[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n# NOTE: editorconfig-core-c has a hardcoded limitation of 50 chars per .ini section name\n\n[*.{cpp,h,hpp,c,asm}]\nindent_style = space\nindent_size = 2\ntrim_trailing_whitespace = true\nend_of_line = lf\ninsert_final_newline = true\ncharset = utf-8\n\n[*.md]\nindent_style = space\ntrim_trailing_whitespace = false\ncharset = utf-8\n\n"
  },
  {
    "path": ".gitattributes",
    "content": "# Set the default behavior, in case people don't have core.autocrlf set.\n* text eol=lf\n\ndistrib/**/*.css linguist-documentation\n\ndistrib/**/*.htm linguist-documentation\ndistrib/**/*.html linguist-documentation\n\n# Denote all files that are truly binary and should not be modified.\n*.bmp binary\n*.dll binary\n*.exe binary\n*.gif binary\n*.ico binary\n*.jpg binary\n*.lib binary\n*.png binary\n*.ps1 binary\n*.svg binary\n"
  },
  {
    "path": ".github/workflows/build.yml",
    "content": "name: Build AviSynth+\n\non: [push]\n\njobs:\n  build:\n    name: ${{ matrix.config.name }}\n    runs-on: ${{ matrix.config.os }}\n    strategy:\n      matrix:\n        config:\n        - {name: \"Windows Latest x64\", os: windows-latest, cmake-parameters: \"-A x64\"}\n        - {name: \"Windows Latest x86\", os: windows-latest, cmake-parameters: \"-A Win32\"}\n        - {name: \"Ubuntu 22.04 x64\", os: ubuntu-22.04}\n        - {name: \"Ubuntu 24.04 x64\", os: ubuntu-24.04}\n        - {name: \"macOS Latest x64\", os: macos-latest}\n\n    steps:\n    - uses: actions/checkout@v3\n      with:\n        submodules: ${{ matrix.config.checkout-submodules }}\n        fetch-depth: 0\n\n    - name: configure\n      run: |\n        cmake -S . -B avisynth-build ${{ matrix.config.cmake-parameters }}\n\n    - name: build\n      run: |\n        cmake --build avisynth-build --config Release -j 2\n"
  },
  {
    "path": ".gitignore",
    "content": "avisynth-build/*\nCMakeCache.txt\nCMakeFiles/*\ndistrib/docs/english/build/\ndistrib/WinInstaller/git_rev.ini\ndistrib/WinInstaller/*.exe\ndistrib/WinInstaller/*.bak\ndistrib/WinInstaller/x86/*\ndistrib/WinInstaller/x64/*\ndistrib/Prerequisites/VC_redist.x64.exe\ndistrib/Prerequisites/VC_redist.x86.exe\ndistrib/Prerequisites/vcredist_x64.exe\ndistrib/Prerequisites/vcredist_x86.exe\ndistrib/Prerequisites/VC_redist_14.27.29114.0.x86.exe\ndistrib/Prerequisites/VC_redist_14.27.29114.0.x64.exe\n\navs_core/CMakeCache.txt\navs_core/CMakeFiles/*\n\n# Intel Profiler\navs_core/VTune Profiler Results/*\nGPUCache/*\n*.db3\n\navs_core/core/version.h\n\nplugins/CMakeCache.txt\nplugins/CMakeFiles/*\n\nplugins/ConvertStacked/CMakeCache.txt\nplugins/ConvertStacked/CMakeFiles/*\nplugins/ConvertStacked/debug/*\nplugins/ConvertStacked/release/*\n\nplugins/DirectShowSource/CMakeCache.txt\nplugins/DirectShowSource/CMakeFiles/*\nplugins/DirectShowSource/debug/*\nplugins/DirectShowSource/release/*\n\nplugins/ImageSeq/CMakeCache.txt\nplugins/ImageSeq/CMakeFiles/*\nplugins/ImageSeq/debug/*\nplugins/ImageSeq/release/*\n\nplugins/Shibatch/CMakeCache.txt\nplugins/Shibatch/CMakeFiles/*\nplugins/Shibatch/debug/*\nplugins/Shibatch/release/*\n\nplugins/Shibatch/PFC/CMakeCache.txt\nplugins/Shibatch/PFC/CMakeFiles/*\nplugins/Shibatch/PFC/debug/*\nplugins/Shibatch/PFC/release/*\n\nplugins/TimeStretch/CMakeCache.txt\nplugins/TimeStretch/CMakeFiles/*\nplugins/TimeStretch/debug/*\nplugins/TimeStretch/release/*\n\nplugins/TimeStretch/SoundTouch/CMakeCache.txt\nplugins/TimeStretch/SoundTouch/CMakeFiles/*\nplugins/TimeStretch/SoundTouch/debug/*\nplugins/TimeStretch/SoundTouch/release/*\n\nplugins/VDubFilter/CMakeCache.txt\nplugins/VDubFilter/CMakeFiles/*\nplugins/VDubFilter/debug/*\nplugins/VDubFilter/release/*\n\nplugins/VFAPIFilter/CMakeCache.txt\nplugins/VFAPIFilter/CMakeFiles/*\nplugins/VFAPIFilter/debug/*\nplugins/VFAPIFilter/release/*\n\n#cmake generated files\n*.sln\n*.slnx\n*.vcxproj\n*.vcxproj.filters\narch.c\navs_core/arch.h\navs_core/avisynth_conf.h\navs_core/version.h\navs_core/avisynth.pc\ncmake_install.cmake\ngenerate.stamp\ngenerate.stamp.depend\n\nout/*\ndebug/*\noutput/*\nrelease/*\nwin32/*\nx64/*\navscore/debug\navscore/release/*\navscore/win32/*\navscore/x64/*\n\n# User-specific files\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]eleases/\n[Rr]elWithDebInfo/\nx64/\nx86/\nbld/\n[Bb]in/\n[Oo]bj/\n[Ll]og/\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opendb\n*.opensdf\n*.sdf\n*.cachefile\n*.VC.db\n*.VC.VC.opendb\n*.VC.db-shm\n*.VC.db-wal\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n*.sap\n\n#Visual Studio other\n.vs/\n\n*.rej\n*.orig\n*_BACKUP_*\n*_BASE_*\n*_LOCAL_*\n*_REMOTE_*\n\n# Assorted build generator files\nMakefile\nbuild.ninja\nrules.ninja\n.ninja_deps\n.ninja_log\ncmake_uninstall.cmake\n*.pc\n*.so\n"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"filesystem\"]\n\tpath = filesystem\n\turl = https://github.com/gulrak/filesystem\n"
  },
  {
    "path": ".readthedocs.yaml",
    "content": "# Read the Docs configuration file for Sphinx projects\n# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details\n\n# Required\nversion: 2\n\n# Set the OS, Python version and other tools you might need\nbuild:\n  os: ubuntu-22.04\n  tools:\n    python: \"3.12\"\n    # You can also specify other tool versions:\n    # nodejs: \"20\"\n    # rust: \"1.70\"\n    # golang: \"1.20\"\n\n# Build documentation in the \"docs/\" directory with Sphinx\nsphinx:\n  configuration: distrib/docs/english/source/conf.py\n  # You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs\n  # builder: \"dirhtml\"\n  # Fail on all warnings to avoid broken references\n  # fail_on_warning: true\n\n# Optionally build your docs in additional formats such as PDF and ePub\nformats: all\n#    - pdf\n#    - epub\n\n# Optional but recommended, declare the Python requirements required\n# to build your documentation\n# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html\n# python:\n#    install:\n#    - requirements: docs/requirements.txt\n"
  },
  {
    "path": "CMakeLists.txt",
    "content": "# Tested generators:\n# Command line makefile generator\n# \"MinGW Makefiles\": MSYS2/Mingw32 GCC 8.3, 10.3 build\n# IDE project file generators\n# \"Visual Studio 15 2017\" optional platform generator Win32 and x64\n# \"Visual Studio 16 2019\" optional platform generator Win32 and x64. optional toolset \"v141_xp\"\n# \"Visual Studio 17 2022\" optional platform generator Win32 and x64. optional toolset \"v141_xp\" or \"clangcl\"\n# \"Visual Studio 18 2026\" optional platform generator Win32 and x64. optional toolset \"v141_xp\" or \"clangcl\"\n\n# Intel C++ Compilers\n# Minimum Cmake version for Intel C++ Compiler 2023: 3.22.3 (Win) 3.20 (Linux)\n# Howto: https://www.intel.com/content/www/us/en/developer/articles/technical/using-oneapi-compilers-with-cmake-in-visual-studio.html\n# \"Intel(R) oneAPI DPC++ Compiler\", two flavours. DPCPP is not compatible with Avisynth.\n# - Intel® NextGen Compiler (in base kit, LLVM based): TOOLSET = \"Intel C++ Compiler 2023\", COMPILER EXE NAME = icx.exe\n# - Intel® Classic Compiler (in extra HPC kit): TOOLSET = \"Intel C++ Compiler 19.2\", COMPILER EXE NAME = icl.exe\n# CMake support files.\n# - Info from: c:\\Program Files (x86)\\Intel\\oneAPI\\compiler\\latest\\windows\\IntelDPCPP\\ReadMe.txt\n# - copy c:\\Program Files (x86)\\Intel\\oneAPI\\compiler\\latest\\windows\\IntelDPCPP\\IntelDPCPPConfig.cmake to c:\\Program Files\\CMake\\share\\cmake-3.20\\Modules\\\n# CMake GUI: \n# - Generator: \"Visual Studio 17 2022\"\n# - Optional toolset to use (-T option): \n#   For LLVM based icx: Intel C++ Compiler 2023 (or earlier 2022, 2021)\n#   For classic icl: Intel C++ Compiler 19.2\n# - Specify native compilers: browse for the appropriate compiler executable path.\n#   icx: C:\\Program Files (x86)\\Intel\\oneAPI\\compiler\\latest\\windows\\bin\\icx.exe\n#   icl: C:\\Program Files (x86)\\Intel\\oneAPI\\compiler\\latest\\windows\\bin\\intel64\\icl.exe\n# If you have errors like \"xilink: : error : Assertion failed (shared/driver/drvutils.c, line 312\" then\n# as a workaround you must copy clang.exe (by default it is located in C:\\Program Files (x86)\\Intel\\oneAPI\\compiler\\latest\\windows\\bin)\n# to the folder beside xilink (for x64 configuration it is in C:\\Program Files (x86)\\Intel\\oneAPI\\compiler\\latest\\windows\\bin\\intel64).\n# Successful log looks like:\n#   The CXX compiler identification is IntelLLVM 2023.0.0 with MSVC-like command-line\n#   Check for working CXX compiler: C:/Program Files (x86)/Intel/oneAPI/compiler/2023.0.0/windows/bin/icx.exe - skipped\n# or\n#   The CXX compiler identification is IntelLLVM 2021.4.0 with MSVC-like command-line\n#   Check for working CXX compiler: C:/Program Files (x86)/Intel/oneAPI/compiler/2021.4.0/windows/bin/icx.exe\n# or\n#   The CXX compiler identification is Intel 2021.4.0.20210910\n#   Check for working CXX compiler: C:/Program Files (x86)/Intel/oneAPI/compiler/2021.4.0/windows/bin/intel64/icl.exe\n#\n# command line:\n#   run \"C:\\Program Files (x86)\\Intel\\oneAPI\\setvars.bat\"   to configure the environment\n#   cmake -T \"Intel C++ Compiler 2023\" -DCMAKE_CXX_COMPILER=\"icx.exe\" ../ \n#   or \n#   cmake -T \"Intel C++ Compiler 19.2\" -DCMAKE_CXX_COMPILER=\"icl.exe\" ../ \n\n# \"Visual Studio 16 2019\" + LLVM 8.0 (clang) optional platform generator Win32 and x64\n\nCMAKE_MINIMUM_REQUIRED( VERSION 3.6.2...3.11 )\n# VS2019: 3.14.1\n# Intel 2023: 3.22.3 (Win) 3.20 (Linux)\n# VS2022: 3.21\n# VS2026: 4.2\n\n# Get PROJECT_VERSION property from 'avs_core/core/version.h.in'\nfile(READ \"avs_core/core/version.h.in\" versioning)\n\nstring(REGEX MATCH \"AVS_MAJOR_VER[ \\\\t]+([0-9]*)\" _ ${versioning})\nset(version_major ${CMAKE_MATCH_1})\nstring(REGEX MATCH \"AVS_MINOR_VER[ \\\\t]+([0-9]*)\" _ ${versioning})\nset(version_minor ${CMAKE_MATCH_1})\nstring(REGEX MATCH \"AVS_BUGFIX_VER[ \\\\t]+([0-9]*)\" _ ${versioning})\nset(version_bugfix ${CMAKE_MATCH_1})\n# Combine version variables for use in the project command\nset(PROJECT_VERSION_STRING \"${version_major}.${version_minor}.${version_bugfix}\")\n\n# Get AVISYNTH_INTERFACE_VERSION from avs_core/include/avisynth.h\nfile(READ \"avs_core/include/avisynth.h\" versioning)\nstring(REGEX MATCH \"AVISYNTH_INTERFACE_VERSION = ([0-9]*)\" _ ${versioning})\nset(AVISYNTH_INTERFACE_VERSION ${CMAKE_MATCH_1})\n\noption(BUILD_SHARED_LIBS \"Build shared libraries instead of static ones.\" ON)\nif(NOT ${BUILD_SHARED_LIBS})\n  message(WARNING \"You must satisfy the conditions of the GPL license when linking against the AviSynth library.\")\nendif()\n\noption(HEADERS_ONLY \"Install only the Headers\" ${INSTALL_ONLY_HEADER})\nif(${INSTALL_ONLY_HEADER})\n  set(INSTALL_ONLY_HEADER OFF)\nendif()\n\nif(NOT HEADERS_ONLY)\n\n  project(\"AviSynth+\" VERSION ${PROJECT_VERSION_STRING} LANGUAGES CXX)\n\n  # message(\"Compiler ID: ${CMAKE_CXX_COMPILER_ID} \") \n\n  include(GNUInstallDirs)\n\n  # Avoid uselessly linking to unused libraries\n  set(CMAKE_STANDARD_LIBRARIES \"\" CACHE STRING \"\" FORCE)\n  set(CMAKE_C_STANDARD_LIBRARIES \"\" CACHE STRING \"\" FORCE)\n  set(CMAKE_CXX_STANDARD_LIBRARIES \"\" CACHE STRING \"\" FORCE)\n\n  # We require C++17 or higher.\n  if(CMAKE_VERSION VERSION_GREATER 3.7)\n    set(CMAKE_CXX_STANDARD 17)\n    set(CMAKE_CXX_STANDARD_REQUIRED TRUE)\n    set(CMAKE_CXX_EXTENSIONS FALSE)\n  endif()\n\n  # Detect Intel processors and turn Intel SIMD on or off automatically.\n  # Detect AArch64 processors and turn AArch64 NEON SIMD on or off automatically.\n  # Old logic relied on the host processor: ${CMAKE_SYSTEM_PROCESSOR}\n\n  set(INTEL_SIMD \"OFF\")\n  set(NEON_SIMD \"OFF\")\n  # Use a list of known Intel-compatible/aarch64 architecture names for the default ON state.\n  set(INTEL_ARCH_NAMES \"win32\" \"x64\" \"x86\" \"i386\" \"amd64\" \"x86_64\" \"i686\")\n  set(ARM_ARCH_NAMES \"arm64\" \"aarch64\")\n\n  # Check the TARGET architecture using the most reliable variables (CMAKE_GENERATOR_PLATFORM and PLATFORMID_LOWER)\n  string(TOLOWER \"${PLATFORMID}\" PLATFORMID_LOWER)\n  string(TOLOWER \"${CMAKE_GENERATOR_PLATFORM}\" GEN_PLATFORM_LOWER) # Often holds x64, ARM64, etc.\n  string(TOLOWER \"${CMAKE_SYSTEM_PROCESSOR}\" HOST_ARCH_LOWER) # ninja with ative aarch64 gcc: probably only this exists\n\n  # --- DEBUG OUTPUT START ---\n  # message(STATUS \"--- SIMD Detection Variables ---\")\n  # message(STATUS \"CMAKE_SYSTEM_PROCESSOR (Host Arch): ${CMAKE_SYSTEM_PROCESSOR}\")\n  # message(STATUS \"Host Arch Lower: ${HOST_ARCH_LOWER}\")\n  # message(STATUS \"PLATFORMID_LOWER (VS Target Platform): ${PLATFORMID_LOWER}\")\n  # message(STATUS \"CMAKE_GENERATOR_PLATFORM (Generator Target): ${CMAKE_GENERATOR_PLATFORM}\")\n  # message(STATUS \"INTEL_ARCH_NAMES: ${INTEL_ARCH_NAMES}\")\n  # message(STATUS \"------------------------------------\")\n  # --- DEBUG OUTPUT END ---\n  # e.g. ARM64 cross-compile on x64 machine:\n  # CMAKE_SYSTEM_PROCESSOR (Host Arch): AMD64\n  # Host Arch Lower: amd64\n  # PLATFORMID_LOWER (VS Target Platform): \n  # CMAKE_GENERATOR_PLATFORM (Generator Target): ARM64  \n\n  # check aarch64 variants\n  list(FIND ARM_ARCH_NAMES \"${HOST_ARCH_LOWER}\" _found_arm_host) # New check\n  list(FIND ARM_ARCH_NAMES \"${PLATFORMID_LOWER}\" _found_arm_platform_id)\n  list(FIND ARM_ARCH_NAMES \"${GEN_PLATFORM_LOWER}\" _found_arm_gen)\n  # check intel variants\n  list(FIND INTEL_ARCH_NAMES \"${HOST_ARCH_LOWER}\" _found_arch)\n  list(FIND INTEL_ARCH_NAMES \"${PLATFORMID_LOWER}\" _found_target_platform_id)\n  list(FIND INTEL_ARCH_NAMES \"${GEN_PLATFORM_LOWER}\" _found_target_gen)\n\n  # 1. Check if the target platform is explicitly known non-Intel (ARM64, AARCH64)\n  if(_found_arm_platform_id GREATER -1 OR _found_arm_gen GREATER -1 OR _found_arm_host GREATER -1)\n      set(INTEL_SIMD \"OFF\")\n      set(NEON_SIMD \"ON\")\n      message(STATUS \"Target is aarch64, turn NEON_SIMD ON.\")\n  else()\n      # 2. Inclusion Check: We are NOT targeting ARM64. \n      \n      # Define a boolean check: Did we find a match in the explicit target variables OR the host architecture?\n      if(_found_target_gen GREATER -1 OR _found_target_platform_id GREATER -1)\n          # Found a match in a generator-set variable (e.g., Win32, x64 when explicitly chosen)\n          set(INTEL_SIMD \"ON\")\n          message(STATUS \"Target architecture is explicitly set and Intel-compatible, INTEL_SIMD set ON.\")\n      elseif(_found_arch GREATER -1 AND \"${GEN_PLATFORM_LOWER}\" STREQUAL \"\")\n          # FALLBACK: Target platform is NOT set (Default Configuration), but the Host is Intel-compatible.\n          # The default target platform for a multi-config generator on a bare x64 host is x64.\n          set(INTEL_SIMD \"ON\")\n          message(STATUS \"Target platform not specified; defaulting to Host (${CMAKE_SYSTEM_PROCESSOR}), INTEL_SIMD set ON.\")\n      endif()\n  endif()\n  # message(STATUS \"Final INTEL_SIMD initial assumption: ${INTEL_SIMD}\")\n  option(ENABLE_INTEL_SIMD \"Enable SIMD intrinsics for Intel processors\" \"${INTEL_SIMD}\")\n  option(ENABLE_NEON_SIMD \"Enable SIMD intrinsics for AArch64 processors\" \"${NEON_SIMD}\")\n\n  option(ENABLE_PLUGINS \"Build set of default external plugins\" ON)\n  set(USER_AVS_PLUGINDIR_LOCATION \".local/lib/avisynth\" CACHE STRING \"Override path for user-local plugins, with $HOME omitted (default: .local/lib/avisynth)\")\n  option(ENABLE_CUDA \"Enable CUDA support\" OFF)\n  set(CORE_PLUGIN_INSTALL_PATH \"${CMAKE_INSTALL_FULL_LIBDIR}\" CACHE STRING \"Set system plugin install parent directory (default: value of CMAKE_INSTALL_FULL_LIBDIR)\")\n\n  if(CMAKE_VERSION VERSION_GREATER 3.9)\n    get_cmake_property(MULTI_CONFIG GENERATOR_IS_MULTI_CONFIG)\n    if(MULTI_CONFIG)\n      if(CMAKE_CONFIGURATION_TYPES)\n        set(CMAKE_CONFIGURATION_TYPES Debug Release RelWithDebInfo)\n        set(CMAKE_CONFIGURATION_TYPES \"${CMAKE_CONFIGURATION_TYPES}\" CACHE STRING \"Reset the configurations to what we need\" FORCE)\n      endif()\n      message(\"-- Build type: Multi-configuration (${CMAKE_CONFIGURATION_TYPES})\")\n    else()\n      # When CMAKE_BUILD_TYPE is not defined, CMake defaults to a simple -O0 configuration, no compiler optimizations\n      # and no debug symbols. For single-configuration generators (Makefiles, Ninja, etc.) we can make Release the\n      # assumed default if it isn't explicitly set by the user. Multi-config generators like Visual Studio ignore\n      # CMAKE_BUILD_TYPE.\n\n      # Unfortunately, this is not visible in CMakeCache, but it can be seen to take effect in build.ninja or running\n      # make with VERBOSE=1 adding the appropriate Release flags.\n      if(NOT CMAKE_BUILD_TYPE)\n        set(CMAKE_BUILD_TYPE \"Release\")\n      endif()\n      message(\"-- Build type: ${CMAKE_BUILD_TYPE}\")\n    endif()\n  endif()\n\n  # Use this one to be safe:\n  # Check for the Visual Studio generator OR the MSVC compiler/toolchain on Windows \n  # (which includes Ninja with cl.exe).\n  # We use the MSVC variable to ensure the configuration block runs when cl.exe is detected.\n  if( CMAKE_GENERATOR MATCHES \"Visual Studio\" OR (MSVC AND WIN32) )\n  ## IF( MSVC ) # Check for Visual Studio\n\n    #1910-1919 = VS 15.0 (v141 toolset) Visual Studio 2017\n    #1920-1929 = VS 16.0 (v142 toolset) Visual Studio 2019\n    #1930-1949 = VS 17.x (v143 toolset) Visual Studio 2022\n    #  ( 1940-1949 = VS v17.10+: Toolset v143 (Still!) | Compiler 19.4x)\n    #1950-1959 = VS 18.0 (v145 toolset) Visual Studio 2026\n    \n    # --- Determine MSVC target platform, Ninja makes a bit more work for us\n    # Since CMAKE_VS_PLATFORM_NAME is empty, only valid for Visual Studio generators.\n\n    # Detect the target platform based on the most reliable variables for MSVC/Ninja:\n    # 1. start with the VS Generator's specific variable. If it's not set, it will be empty.\n    set(TARGET_PLATFORM_TO_CHECK \"${CMAKE_VS_PLATFORM_NAME}\")\n\n    # message(STATUS \"DEBUG: CMAKE_VS_PLATFORM_NAME = '${CMAKE_VS_PLATFORM_NAME}'\")\n    # message(STATUS \"DEBUG: CMAKE_GENERATOR_PLATFORM = '${CMAKE_GENERATOR_PLATFORM}'\")\n    # message(STATUS \"DEBUG: CMAKE_SIZEOF_VOID_P = '${CMAKE_SIZEOF_VOID_P}'\")\n\n    # 2. If CMAKE_VS_PLATFORM_NAME is empty (e.g., Ninja generator), try to infer from pointer size.\n    if(NOT TARGET_PLATFORM_TO_CHECK)\n        # 3. Check the pointer size (most reliable indicator for x64/Win32)\n        if(CMAKE_SIZEOF_VOID_P EQUAL 8)\n            # 64-bit target\n            set(TARGET_PLATFORM_TO_CHECK \"x64\")\n        elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)\n            # 32-bit target\n            set(TARGET_PLATFORM_TO_CHECK \"Win32\")\n        endif()\n    endif()\n\n    # 4. final attempt: If CMAKE_GENERATOR_PLATFORM has a value and TARGET_PLATFORM_TO_CHECK is still empty\n    if(NOT TARGET_PLATFORM_TO_CHECK AND CMAKE_GENERATOR_PLATFORM)\n        set(TARGET_PLATFORM_TO_CHECK \"${CMAKE_GENERATOR_PLATFORM}\")\n    endif()\n    \n    # detect if the target is for x86\n    # PLATFORMID_LOWER is just a lowercase copy of CMAKE_VS_PLATFORM_NAME\n    string(TOLOWER \"${TARGET_PLATFORM_TO_CHECK}\" PLATFORMID_LOWER)\n    # message(\"-- PLATFORMID_LOWER: ${PLATFORMID_LOWER}\")\n \n    if((\"${PLATFORMID_LOWER}\" STREQUAL \"win32\") OR\n       (\"${PLATFORMID_LOWER}\" STREQUAL \"x64\") OR\n       (\"${PLATFORMID_LOWER}\" STREQUAL \"arm64\"))   # allow arm64 targets\n        set(SUPPORTED_MSVC_PLATFORM \"ON\")\n    else()\n        set(SUPPORTED_MSVC_PLATFORM \"OFF\")\n    endif()\n    \n    if(SUPPORTED_MSVC_PLATFORM STREQUAL \"OFF\")\n        message(FATAL_ERROR \"MSVC/ClangCL only supported on Win32, x64, or ARM64 targets. Use MinGW (llvm-mingw or gcc). Unsupported target: ${CMAKE_VS_PLATFORM_NAME}.\")\n    endif()\n\n#[[\n    # check to disable ARM64 by default\n    # PF: re-allowed; VS2026 can build ARM64 even with LLVM\n    if((\"${PLATFORMID_LOWER}\" STREQUAL \"arm64\") AND (NOT DEFINED ENABLE_ARM64_WITH_MSVC_TESTING))\n        # This FATAL_ERROR can be commented out or protected by the ENABLE_ARM64_TESTING cache variable.\n        # To enable the build, define -DENABLE_ARM64_TESTING=ON when running cmake.\n        message(FATAL_ERROR \"MSVC ARM64 platform is currently disabled by default. Define ENABLE_ARM64_WITH_MSVC_TESTING=ON to proceed or use MinGW (llvm-mingw or gcc).\")\n    endif()\n#]]\n\n    IF( MSVC_VERSION VERSION_LESS 1910 )\n      MESSAGE(FATAL_ERROR \"Visual C++ 2017 or newer required.\")\n    ENDIF()\n\n    # Milestones\n    # C++17 COMPLETENESS: Compiler versions 19.10-19.19 (VS 2017) had incomplete C++17 support.\n    # Full C++17 support: starting with compiler version 19.20 (VS 2019 RTM).\n    # C++20 COMPLETENESS: Compiler version 19.29 (VS 2019 v16.10+): full C++20 standard library support.\n    # VS 2022 (v19.30+) is generally recommended for best C++20 stability and language feature compliance.\n    \n    # Damn XP support prevents defining a minimum.\n    # When v141_xp toolset is used, MSVC_VERSION is 1916\n    # So we temporarily inactivate the minimum version check:\n    IF(FALSE)\n        IF( MSVC_VERSION VERSION_LESS 1929 )\n          message(\"--MSVC_VERSION is (${MSVC_VERSION})\")\n          MESSAGE(FATAL_ERROR \"Visual C++ 2019 (v16.10+) or newer is required for C++20 support. Recommended: Visual Studio 2022.\")\n        ENDIF()\n    ENDIF()\n\n    file(MAKE_DIRECTORY \"${CMAKE_BINARY_DIR}/Output/plugins\")\n    file(MAKE_DIRECTORY \"${CMAKE_BINARY_DIR}/Output/system\")\n    file(MAKE_DIRECTORY \"${CMAKE_BINARY_DIR}/Output/c_api\")\n\n    IF(MSVC_IDE)\n      message(\"MSVC_IDE support found, reported CMAKE_GENERATOR_TOOLSET is: ${CMAKE_GENERATOR_TOOLSET}\")\n      string( TOLOWER \"${CMAKE_GENERATOR_TOOLSET}\" cmake_gentoolset_lower)\n\n      IF(cmake_gentoolset_lower STREQUAL \"intel c++ compiler 2021\" OR\n      cmake_gentoolset_lower STREQUAL \"intel c++ compiler 2022\" OR\n      cmake_gentoolset_lower STREQUAL \"intel c++ compiler 2023\" OR\n      cmake_gentoolset_lower STREQUAL \"intel c++ compiler 2024\" OR\n      cmake_gentoolset_lower STREQUAL \"intel c++ compiler 2025\" OR\n      cmake_gentoolset_lower STREQUAL \"intel c++ compiler 2026\"\n      )\n        # IntelLLVM\n        set(IntelLLVM_IN_VS \"1\")\n      ELSEIF(cmake_gentoolset_lower STREQUAL \"intel c++ compiler 19.2\")\n        # Intel Classic\n        set(IntelClassic_IN_VS \"1\")\n      ELSEIF(cmake_gentoolset_lower MATCHES \"intel\")\n        MESSAGE(FATAL_ERROR \"Possibly unknown or unsupported Intel compiler\") # version update needed in the above lines\n      ELSEIF(cmake_gentoolset_lower STREQUAL \"llvm\" OR cmake_gentoolset_lower STREQUAL \"clangcl\")\n        if(${CMAKE_CXX_COMPILER_ID} STREQUAL \"Clang\")  # hope: always\n          message(\"LLVM toolset was specified via -T. Compiler ID is: ${CMAKE_CXX_COMPILER_ID}; CMAKE_CXX_COMPILER_VERSION is: ${CMAKE_CXX_COMPILER_VERSION}\")\n          # Clang; 9.0.0\n          # These are probably not supported when clang is downloaded as a ready-made binary: CLANG_VERSION_MAJOR CLANG_VERSION_MINOR CLANG_VERSION_STRING\n          # string (REGEX REPLACE \".*clang version ([0-9]+\\\\.[0-9]+).*\" \"\\\\1\" CLANG_VERSION_STRING ${clang_full_version_string})\n          if( CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.1 )\n            MESSAGE(FATAL_ERROR \"Clang 7.0.1 or newer required\") # as of November 2021 actually we are using 12.0\n          endif()\n        endif()\n        set(CLANG_IN_VS \"1\")\n      ELSEIF(cmake_gentoolset_lower STREQUAL \"v141_clang_c2\")\n          #1900 is reported\n        message(\"v141_clang_c2 toolset was specified via -T. Reported MSVC_VERSION is: ${MSVC_VERSION}\")\n        message(\"May not work, try clangcl or LLVM\")\n        set(CLANG_IN_VS \"1\")\n        # For LLVM Clang installed separately, specify llvm\n        # Since Visual Studio 2019 v16.4, LLVM 9.0 or newer is integrated, for this use Toolset: clangcl\n      ENDIF()\n\n      option(WINXP_SUPPORT \"Make binaries compatible with Windows XP and Vista\" OFF)\n      if(WINXP_SUPPORT)\n        # We want our project to also run on Windows XP\n        # Not for LLVM: Clang stopped XP support in 2016\n        IF(NOT CLANG_IN_VS STREQUAL \"1\")\n          # Setting CMAKE_GENERATOR_TOOLSET here has no effect, only when passed (-T option) or set directly, so we just check it\n          IF(CMAKE_GENERATOR_TOOLSET STREQUAL \"v141_xp\")\n              # v141_xp is still available in Visual Studio 2022 and 2026.\n              message(\"CMAKE_GENERATOR_TOOLSET is XP compatible: ${CMAKE_GENERATOR_TOOLSET}, extra XP options added\")\n              # https://connect.microsoft.com/VisualStudio/feedback/details/1789709/visual-c-2015-runtime-broken-on-windows-server-2003-c-11-magic-statics\n              # later done: add_definitions(\"/Zc:threadSafeInit-\")\n          ELSE()\n              message(FATAL_ERROR \"For XP you must specify v141_xp toolset with -T option (or 'Optional toolset to use' in CMake GUI)!\")\n          ENDIF()\n        ENDIF()\n      endif()\n    ENDIF()\n\n    if(CMAKE_CXX_COMPILER_ID STREQUAL \"Clang\" AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL \"MSVC\")\n        set(CLANG_IN_VS \"1\")\n    elseif(CMAKE_CXX_COMPILER_ID STREQUAL \"IntelLLVM\" AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL \"MSVC\")\n        set(IntelLLVM_IN_VS \"1\")\n    elseif(CMAKE_CXX_COMPILER_ID STREQUAL \"Intel\" AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL \"MSVC\")\n        set(IntelClassic_IN_VS \"1\")\n    endif()\n\n    IF(IntelClassic_IN_VS STREQUAL \"1\")\n        # Intel C++ Compiler 19.2\n        message(\"Intel Classic chosen, setting additional flags\")\n        set(DELETE_THIS \"/std:c++17\") # if it would co-exist with /Qstd=c++17\n        STRING( REPLACE \"${DELETE_THIS}\" \"\" CMAKE_C_FLAGS \"${CMAKE_C_FLAGS}\")\n        STRING( REPLACE \"${DELETE_THIS}\" \"\" CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS}\")\n        \n        # Workaround as of 19.2: \n        # Statically link with /MT instead of /MD against linker error message\n        # \"unresolved external symbol wmemcmp referenced in function std::filesystem ... lexically_normal\"\n        # Linker bug?\n        set(CompilerFlags\n                CMAKE_CXX_FLAGS\n                CMAKE_CXX_FLAGS_DEBUG\n                CMAKE_CXX_FLAGS_RELEASE\n                CMAKE_CXX_FLAGS_MINSIZEREL\n                CMAKE_CXX_FLAGS_RELWITHDEBINFO\n                CMAKE_C_FLAGS\n                CMAKE_C_FLAGS_DEBUG\n                CMAKE_C_FLAGS_RELEASE\n                CMAKE_C_FLAGS_MINSIZEREL\n                CMAKE_C_FLAGS_RELWITHDEBINFO\n                )\n        foreach(CompilerFlag ${CompilerFlags})\n            string(REPLACE \"/MD\" \"/MT\" ${CompilerFlag} \"${${CompilerFlag}}\")\n            set(${CompilerFlag} \"${${CompilerFlag}}\" CACHE STRING \"msvc compiler flags\" FORCE)\n            message(\"MSVC flags: ${CompilerFlag}:${${CompilerFlag}}\")\n        endforeach()    \n    ELSE()\n        # Plain MSVC branch continues; per-target options are applied later\n    ENDIF()\n\n    # CPU_ARCH can be overridden with the corresponding values when using MSVC:\n    # IA32 (disabled),\n    # SSE (Pentium III and higher, 1999),\n    # SSE2 (Pentium 4 and higher, 2000/2001),\n    # AVX (Sandy Bridge and higher, 2011),\n    # AVX2 (Haswell and higher, 2013)\n    if(CMAKE_SIZEOF_VOID_P EQUAL 4)\n        set(MSVC_CPU_ARCH \"SSE2\" CACHE STRING \"Set MSVC architecture optimization level (default: SSE2)\")\n        # /arch: applied later per-target\n    endif()\n\n  ELSE()\n    # not MS Visual Studio IDE\n    if(WIN32)\n      SET( CMAKE_SHARED_LINKER_FLAGS \"-Wl,--enable-stdcall-fixup\" )\n      # __CRT__NO_INLINE: moved to per-target definitions\n    elseif(APPLE)\n      # macOS uses Clang's linker, doesn't like --no-undefined\n      SET( CMAKE_SHARED_LINKER_FLAGS \"${CMAKE_SHARED_LINKER_FLAGS} -Wl,-undefined,error\" )\n    elseif(CMAKE_CXX_COMPILER_ID STREQUAL \"GNU\")\n      # make sure there are no undefined symbols\n      SET( CMAKE_SHARED_LINKER_FLAGS \"${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined\" )\n    endif()\n\n  ENDIF()\n\n  add_subdirectory(\"avs_core\")\n\n  # Start tracking targets before the plugins subdirectory is processed\n  get_property(_targets_before_plugins GLOBAL PROPERTY BUILT_TARGETS) \n  \n  if(ENABLE_PLUGINS)\n    add_subdirectory(\"plugins\")\n  endif()\n  \n  # End tracking targets and apply fixes here\n  get_property(_targets_after_plugins GLOBAL PROPERTY BUILT_TARGETS)\n  \n  # Calculate targets added in the plugins subdirectory\n  list(REMOVE_ITEM _targets_after_plugins ${_targets_before_plugins})\n  set(NEW_PLUGIN_TARGETS ${_targets_after_plugins})\n  \n  # Combine AvsCore and the newly discovered plugins into one list for fixing\n  set(ALL_AFFECTED_TARGETS)\n  if(TARGET AvsCore)\n      list(APPEND ALL_AFFECTED_TARGETS AvsCore)\n  endif()\n  list(APPEND ALL_AFFECTED_TARGETS ${NEW_PLUGIN_TARGETS})\n  \n  # -----------------------------------------------------------------------\n  # Per-target, modern & safe application of options/defines (CORE and PLUGINS)\n  # -----------------------------------------------------------------------\n  foreach(AFFECTED_TARGET ${ALL_AFFECTED_TARGETS})\n    if(TARGET ${AFFECTED_TARGET})\n      message(STATUS \"Applying compiler fixes to target: ${AFFECTED_TARGET}\")\n\n      # Check if the target is a library or executable (exclude INTERFACE targets)\n      get_target_property(_target_type ${AFFECTED_TARGET} TYPE)\n      if(NOT (\n          ${_target_type} STREQUAL \"SHARED_LIBRARY\" OR \n          ${_target_type} STREQUAL \"STATIC_LIBRARY\" OR\n          ${_target_type} STREQUAL \"MODULE_LIBRARY\"\n      ))\n        # Skip if it's not a compileable target (e.g., if it was an interface target)\n        continue()\n      endif()\n\n      # Use a compound check: If the generator is Visual Studio, or the compiler ID \n      # is MSVC AND we are on Windows, run the MSVC-specific logic.\n      if( CMAKE_GENERATOR MATCHES \"Visual Studio\" OR (MSVC AND WIN32) ) \n      # Using only if(MSVC) will fail with MinGW if the compiler ID is MSVC but the generator is not VS.\n      # This robust check ensures that the MSVC block only runs in an MSVC environment.\n\n        # Handle ARM64 soft intrinsics if requested (for AvsCore logic)\n        # Was experimental, never true\n        if(\"${PLATFORMID}\" STREQUAL \"ARM64\" AND ENABLE_INTEL_SIMD)\n          target_compile_definitions(${AFFECTED_TARGET} PRIVATE USE_SOFT_INTRINSICS)\n        endif()\n        \n        # Needed to properly handle __has_include(<filesystem>) in avs_core/filesystem.h\n        # See note in filesystem/README.md\n        target_compile_options(${AFFECTED_TARGET} PRIVATE /Zc:__cplusplus)\n        \n        # Prevent VC++ secure CRT warnings, and add __SSE2__ flag. (Why?)\n        target_compile_definitions(${AFFECTED_TARGET} PRIVATE\n          _CRT_SECURE_NO_WARNINGS\n          _SECURE_SCL=0\n          _CRTDBG_MAP_ALLOC\n          __SSE2__\n        )\n\n        # INTEL intrinsics master switch (if enabled)\n        if(ENABLE_INTEL_SIMD)\n          target_compile_definitions(${AFFECTED_TARGET} PRIVATE INTEL_INTRINSICS)\n        endif()\n        # NEON intrinsics master switch (if enabled)\n        if(ENABLE_NEON_SIMD)\n          target_compile_definitions(${AFFECTED_TARGET} PRIVATE NEON_INTRINSICS)\n        endif()\n        \n        # FIXME: With Ninja, we can see cl : Command line warning D9025 : overriding '/EHs' with '/EHa'\n        \n        # Compiler-specific options for IntelLLVM / Clang\n        if(CLANG_IN_VS STREQUAL \"1\")\n          target_compile_options(${AFFECTED_TARGET} PRIVATE /EHa -Wno-inconsistent-missing-override)\n          target_compile_options(${AFFECTED_TARGET} PRIVATE -Wno-unused-function -Wno-reorder -Wno-unused-value -Wno-gcc-compat)\n        elseif(IntelLLVM_IN_VS STREQUAL \"1\")\n          target_compile_options(${AFFECTED_TARGET} PRIVATE -Wno-inconsistent-missing-override /EHa /fp:precise)\n          target_compile_options(${AFFECTED_TARGET} PRIVATE -Wno-unused-function -Wno-reorder -Wno-unused-value -Wno-gcc-compat)\n        elseif(IntelClassic_IN_VS STREQUAL \"1\")\n          target_compile_options(${AFFECTED_TARGET} PRIVATE /EHa)\n        else()\n          # Plain MSVC\n          target_compile_options(${AFFECTED_TARGET} PRIVATE /EHa)\n          if (NOT (MSVC_VERSION LESS 1930)) # VS2022+\n            target_compile_options(${AFFECTED_TARGET} PRIVATE /fp:contract)\n          endif()\n        endif()\n        \n        # Enable standards-conformance mode for MSVC compilers that support this\n        # flag (Visual C++ 2017 and later). Default. DirectShowSource will remove if needed.\n        # The headers in the XP-side SDK also have errors if built in conformance mode,\n        # so if we're building for XP, don't turn that on.\n        \n        # Plus check: Skip /permissive- if the target (e.g. DirectShowSource) requests it.\n        # Filled in plugin's CMakeLists.txt\n        get_target_property(_skip_permissive ${AFFECTED_TARGET} SKIP_PERMISSIVE_FLAG)\n\n        if(NOT _skip_permissive) # old DirectShowSource\n          if (NOT WINXP_SUPPORT)\n            if (NOT (MSVC_VERSION LESS 1910))\n              target_compile_options(${AFFECTED_TARGET} PRIVATE /permissive-)\n            endif()\n          endif()\n        endif()\n\n        # Check if XP support is enabled AND if the XP toolset is used (v141_xp)\n        if (WINXP_SUPPORT)\n          if (CMAKE_GENERATOR_TOOLSET STREQUAL \"v141_xp\")\n            # C++11 static initialization fix for XP/Server 2003\n            target_compile_options(${AFFECTED_TARGET} PRIVATE \"/Zc:threadSafeInit-\")\n          endif()\n        endif()\n        \n        # 32-bit arch tuning\n        if(CMAKE_SIZEOF_VOID_P EQUAL 4)\n          target_compile_options(${AFFECTED_TARGET} PRIVATE /arch:${MSVC_CPU_ARCH})\n        endif()\n      else()\n        # CMAKE_CXX_STANDARD doesn't cover the use-case of pre-final C++17 support,\n        # but I'd assume most setups with a new enough version of CMake to use\n        # CMAKE_CXX_STANDARD 17 would also be running a version of GCC/Clang new enough\n        # to not need this. So this will most likely only ever be used by setups running\n        # older versions of CMake; regardless, it shouldn't be necessary to force a\n        # CMAKE_VERSION check on this part unless the mere presence of CMAKE_CXX_STANDARD 17\n        # ends up causing problems for the older compilers here.\n        # Legacy C++17 support for older GCC/Clang\n        if( ((CMAKE_CXX_COMPILER_ID STREQUAL \"GNU\")  AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8)) OR\n            ((CMAKE_CXX_COMPILER_ID STREQUAL \"Clang\") AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5)) )\n            target_compile_options(${AFFECTED_TARGET} PRIVATE -std=c++1z)\n        endif()\n    \n        if(ENABLE_INTEL_SIMD)\n          target_compile_options(${AFFECTED_TARGET} PRIVATE -msse2)\n          target_compile_definitions(${AFFECTED_TARGET} PRIVATE INTEL_INTRINSICS)\n        endif()\n        if(ENABLE_NEON_SIMD)\n          target_compile_definitions(${AFFECTED_TARGET} PRIVATE NEON_INTRINSICS)\n        endif()\n        if(WIN32)\n          target_compile_definitions(${AFFECTED_TARGET} PRIVATE __CRT__NO_INLINE=1)\n        endif()\n      endif()\n    endif()\n  endforeach()\n  \n\nelse()\n  # HEADERS_ONLY is ON\n  project(AviSynth-Headers VERSION ${PROJECT_VERSION_STRING} LANGUAGES CXX)\n  message(STATUS \"Install Only Headers: ON\")\n\n  add_library(${PROJECT_NAME} INTERFACE)\n  target_include_directories(${PROJECT_NAME} INTERFACE \"${CMAKE_CURRENT_SOURCE_DIR}/avs_core/include\")\n  add_library(AviSynth::Headers ALIAS ${PROJECT_NAME})\n\n  # Determine target architecture\n  include(\"${CMAKE_CURRENT_LIST_DIR}/avs_core/TargetArch.cmake\")\n  target_architecture(AVS_ARCH)\n  CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/avs_core/core/arch.h.in ${CMAKE_CURRENT_BINARY_DIR}/arch.h @ONLY)\n\n  # Dynamically generate the sequential version info from Git\n  # Based on the example here: http://www.cmake.org/pipermail/cmake/2010-July/038015.html\n  FIND_PACKAGE(Git)\n  INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})\n  ADD_CUSTOM_TARGET(\n    VersionGen ALL\n    ${CMAKE_COMMAND} -D SRC=${CMAKE_CURRENT_SOURCE_DIR}/avs_core/core/version.h.in\n                      -D DST=${CMAKE_CURRENT_BINARY_DIR}/version.h\n                      -D GIT=${GIT_EXECUTABLE}\n                      -D REPO=${CMAKE_SOURCE_DIR}\n                      -P ${CMAKE_CURRENT_SOURCE_DIR}/avs_core/Version.cmake\n  )\n\n  include(GNUInstallDirs)\n\n  install(\n    FILES ${CMAKE_CURRENT_SOURCE_DIR}/avs_core/include/avisynth.h\n          ${CMAKE_CURRENT_SOURCE_DIR}/avs_core/include/avisynth_c.h\n    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/avisynth\n  )\n\n  install(\n    DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/avs_core/include/avs\n    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/avisynth\n  )\n\n  install(\n    FILES \"${CMAKE_CURRENT_BINARY_DIR}/version.h\"\n          \"${CMAKE_CURRENT_BINARY_DIR}/arch.h\"\n    DESTINATION \"${CMAKE_INSTALL_INCLUDEDIR}/avisynth/avs\"\n  )\n\n\nendif()\n\n# uninstall target\nconfigure_file(\n  \"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in\"\n  \"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake\"\n  IMMEDIATE @ONLY)\n\nadd_custom_target(uninstall\n  COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)"
  },
  {
    "path": "README.md",
    "content": "AviSynth+\n=========\n\n**AviSynth+** is an improved version of the [AviSynth frameserver](http://avisynth.nl/index.php/Main_Page), with improved\nfeatures and developer friendliness.\n\nVisit our [forum thread](http://forum.doom9.org/showthread.php?t=181351) for compilation instructions and support.\n\n\nPlatform availability\n---------------------\n\n| Supported OSes |\n|----------------|\n| Windows        |\n| macOS          |\n| Linux          |\n| *BSD           |\n| Haiku          |\n\n| Supported CPU architectures |\n|-----------------------------|\n| x86(-64)                    | \n| ARM                         |\n| PowerPC                     |\n| SPARC                       |\n| RISC-V                      |\n| MIPS                        |\n| LoongArch                   |\n| z/Architecture              |\n\nNot all OS/CPU combinations possible from either the OS' standpoint or AviSynth+'s.\nMIPS, LoongArch, and z/Architecture enabled by request to allow source compilation to succeed, but not tested on either hardware or VM\n\n\nPackaging status\n----------------\n\n[![Packaging status](https://repology.org/badge/vertical-allrepos/avisynthplus.svg)](https://repology.org/project/avisynthplus/versions)\n\n\nHeaders for applications which dynamically load AviSynth+:\n----------------------------------------------------------\n\nThe expected use-case of AviSynth+ is as a dynamically\nloaded library (using LoadLibrary on Windows or dlopen\neverywhere else).\n\nDue to this, it's not actually necessary to build the\nAviSynth+ library itself in order for applications using\nit this way to find it.\n\nTo facilitate this, we support using CMake to do a\nlimited, headers-only install.\n\n### Using CMake:\n\n#### To install:\n\n> mkdir avisynth-build && cd avisynth-build\n> <br>cmake ../ -DHEADERS_ONLY:bool=on\n> <br>make install\n\n`-DCMAKE_INSTALL_PREFIX` can be used to override the\ninstall location if need be.\n\n#### To uninstall:\n\n>make uninstall\n\n\nBuilding the documentation:\n---------------------------\n(Note: the bundled documentation lags behind the descriptions found in the wiki.\nYou can always check the online documentation at http://avisynth.nl/index.php/Main_Page)\n\nAviSynth+'s documentation can be generated into HTML by using Sphinx.\n\n### Set-up:\n\nMake sure that Sphinx is installed. This requires that Python is already\ninstalled and the pip tool is available.\n\n>pip install sphinx\n\nFor various Linux distributions, a Sphinx package should be available\nin the distro's repositories.  Often under the name 'python-sphinx'\n(as it is in Ubuntu's repositories).\n\n### Building the documentation\n\nOnce Sphinx is installed, we can build the documentation.\n\n> cd distrib/docs/english\n> <br>make html\n\n\n"
  },
  {
    "path": "avs_core/CMakeLists.txt",
    "content": "CMAKE_MINIMUM_REQUIRED( VERSION 3.6.2...3.11 )\n\nif (WIN32)\n  if(BUILD_SHARED_LIBS)\n    set(CoreName \"AviSynth\")\n  else()\n    set(CoreName \"avisynth\")\n  endif()\nelse()\n  set(CoreName \"avisynth\")\nendif()\n\n# Create library\nproject(\"AvsCore\" VERSION \"${PROJECT_VERSION}\" LANGUAGES CXX)\nInclude(\"Files.cmake\")\n\n# Initialize a variable to control INTEL_INTRINSICS_AVX512 definition\n# AVX512 support is only available on Intel architectures and 64-bit builds and specific compilers\nset(DEFINE_AVX512 FALSE)\nif(ENABLE_INTEL_SIMD)\n    if(CMAKE_SIZEOF_VOID_P EQUAL 8) # 64-bit build\n        if(MSVC_IDE AND \n           NOT CLANG_IN_VS AND \n           NOT IntelLLVM_IN_VS AND \n           NOT IntelClassic_IN_VS) # Native MSVC, need to check version\n            string(REGEX MATCH \"^19\\\\.([0-9]+)\\\\.([0-9]+)\" MSVC_VERSION_MATCH \"${CMAKE_CXX_COMPILER_VERSION}\")\n            if(MSVC_VERSION_MATCH)\n                set(MSVC_MAJOR 19)\n                set(MSVC_MINOR ${CMAKE_MATCH_1})\n                set(MSVC_PATCH ${CMAKE_MATCH_2})\n\n                if(MSVC_MAJOR GREATER_EQUAL 19 AND MSVC_MINOR GREATER_EQUAL 22) # MSVC 2019 16.2 (19.22) or newer\n                    set(DEFINE_AVX512 TRUE)\n                else()\n                    # set(DEFINE_AVX512 TRUE) # perhaps compiles but not recommended\n                    message(STATUS \"Disabling AVX-512: MSVC version ${CMAKE_CXX_COMPILER_VERSION} is too old (MSVC 2019 16.2 (19.22) or newer).\")\n                endif()\n            else()\n                message(WARNING \"Could not parse native 64-bit MSVC version. AVX-512 support might be incomplete.\")\n            endif()\n        else() # Not native old MSVC (likely GCC, Clang, or newer MSVC via Clang/IntelLLVM)\n            if(CMAKE_CXX_COMPILER_ID MATCHES \"GNU\")\n                # GCC 9.0 is a reasonable safe minimum for VNNI/VBMI/VBMI2/BITALG\n                if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 9.0)\n                    set(DEFINE_AVX512 TRUE)\n                else()\n                    message(STATUS \"Disabling AVX-512: GCC version ${CMAKE_CXX_COMPILER_VERSION} is too old (requires 9.0+).\")\n                endif()\n            elseif(CMAKE_CXX_COMPILER_ID MATCHES \"Clang\")\n                # Clang 9.0 is a reasonable safe minimum for VNNI/VBMI/VBMI2/BITALG\n                if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 9.0)\n                    set(DEFINE_AVX512 TRUE)\n                else()\n                    message(STATUS \"Disabling AVX-512: Clang version ${CMAKE_CXX_COMPILER_VERSION} is too old (requires 9.0+).\")\n                endif()\n            elseif(CMAKE_CXX_COMPILER_ID MATCHES \"Intel\")\n                # Assume modern Intel compilers (icc, icx) support it\n                set(DEFINE_AVX512 TRUE)\n            else()\n                # Default case for unknown/other compilers (like Clang/Intel in VS)\n                # Since we exclude native MSVC, we assume modern compiler support.\n                set(DEFINE_AVX512 TRUE)\n            endif()\n       endif()\n    endif()\n\n    # Note: AVX512 related source must be guarded with #ifdef INTEL_INTRINSICS_AVX512 within the\n    # already existing #ifdef INTEL_INTRINSICS\n    # Though INTEL_INTRINSICS conditional directive can exist for 32 bit and old compiler versions,\n    # but INTEL_INTRINSICS_AVX512 exists only on x64 platforms for compilers supporting AVX512 features required by Avisynth\nendif()\n\nif(NOT DEFINE_AVX512)\n    # Remove AVX512 specific files if it's a 32-bit build\n    # or not supported compiler version\n    list(FILTER AvsCore_Sources EXCLUDE REGEX \".*_avx512\\\\.(cpp|hpp|h)$\")\n    list(FILTER AvsCore_Sources EXCLUDE REGEX \".*_avx512b\\\\.(cpp|hpp|h)$\")\nendif()\n\nadd_library(\"AvsCore\" ${AvsCore_Sources})\n\nif(DEFINE_AVX512)\n    # dont' use add_definitions(-DINTEL_INTRINSICS_AVX512)\n    target_compile_definitions(\"AvsCore\" PRIVATE INTEL_INTRINSICS_AVX512)\nendif()\n\nset_target_properties(\"AvsCore\" PROPERTIES \"OUTPUT_NAME\" \"${CoreName}\")\nif (NOT WIN32)\n  set_target_properties(\"AvsCore\" PROPERTIES VERSION \"${PROJECT_VERSION}\" SOVERSION \"${AVISYNTH_INTERFACE_VERSION}\")\nendif()\nif (MINGW)\n  if(BUILD_SHARED_LIBS)\n    set_target_properties(\"AvsCore\" PROPERTIES PREFIX \"\")\n    set_target_properties(\"AvsCore\" PROPERTIES IMPORT_PREFIX \"\")\n  endif()\nendif()\n\n# Automatically group source files according to directory structure\nforeach(FILE ${AvsCore_Sources})\n  get_filename_component(PARENT_DIR \"${FILE}\" PATH)\n\n  string(REGEX REPLACE \"(\\\\./)\" \"\" GROUP \"${PARENT_DIR}\")\n  string(REPLACE \"/\" \"\\\\\" GROUP \"${GROUP}\")\n\n  # group into \"Source Files\" and \"Header Files\"\n  if (\"${FILE}\" MATCHES \".*\\\\.cpp\")\n    set(GROUP \"Source Files\\\\${GROUP}\")\n  elseif(\"${FILE}\" MATCHES \".*\\\\.(h|hpp)$\")\n    set(GROUP \"Header Files\\\\${GROUP}\")\n  endif()\n\n  source_group(\"${GROUP}\" FILES \"${FILE}\")\nendforeach()\n\nfunction(handle_arch_flags ARCH_SUFFIX GCC_FLAGS MSVC_FLAGS)\n    string(TOLOWER \"${ARCH_SUFFIX}\" ARCH_SUFFIX_LOWER)\n    file(GLOB_RECURSE SRCS_${ARCH_SUFFIX} \"*_${ARCH_SUFFIX_LOWER}.cpp\")\n    if(SRCS_${ARCH_SUFFIX})\n        # Check for any MSVC-based toolchain (VS IDE or cl.exe with Ninja) on Windows.\n        if (MSVC) # MSVC can do Win32 and ARM64 as well.\n            # not this: if (MSVC_IDE), Ninja leaves MSVC_IDE off\n            # Check for MSVC-frontends that use GCC/Clang-like flags (e.g., ClangCL, IntelLLVM)\n            IF(CLANG_IN_VS STREQUAL \"1\" OR IntelLLVM_IN_VS STREQUAL \"1\" OR IntelClassic_IN_VS STREQUAL \"1\")\n                set_source_files_properties(${SRCS_${ARCH_SUFFIX}} PROPERTIES COMPILE_FLAGS \"${GCC_FLAGS}\")\n            ELSE()\n                # Native MSVC (cl.exe, including when used with Ninja)\n                IF(WIN32)\n                # MSVC gives warning in x64 when SSE2 flag is added, it's just required as a minimum\n                if(NOT (CMAKE_SIZEOF_VOID_P EQUAL 8 AND \"${MSVC_FLAGS}\" STREQUAL \" /arch:SSE2 \"))\n                    set_source_files_properties(${SRCS_${ARCH_SUFFIX}} PROPERTIES COMPILE_FLAGS \"${MSVC_FLAGS}\")\n                endif()\n                endif()\n            ENDIF()\n        else()\n            # Fallback for all non-MSVC compilers (GCC, Clang on Linux/macOS, MinGW)\n            set_source_files_properties(${SRCS_${ARCH_SUFFIX}} PROPERTIES COMPILE_FLAGS \"${GCC_FLAGS}\")\n        endif()\n        list(APPEND AvsCore_Sources ${SRCS_${ARCH_SUFFIX}})\n    endif()\nendfunction()\n\nif(ENABLE_NEON_SIMD)\n    # =========================================================================\n    # AArch64 (ARM64) SIMD Flags\n    # =========================================================================\n    # See: Arch64 SIMD Compilation and Source Code Rules\n    # Files must be located in 'aarch64' subdirectory.\n    \n    # Baseline NEON (ASIMD)\n    # GCC/Clang: Implicit (or -march=armv8-a) MSVC: /arch:armv8.0\n    # asm output debug, leave it here pls.: handle_arch_flags(NEON \" -march=armv8-a -S -g -fverbose-asm -Wa,-adhln \" \" /arch:armv8.0 \")\n    handle_arch_flags(NEON \" -march=armv8-a \" \" /arch:armv8.0 \")\n\n    # Dot Product (FEAT_DotProd / ARMv8.1-A) compulsory from ARMv8.4-A\n    handle_arch_flags(DP \" -march=armv8.1-a+dotprod \" \" /arch:armv8.1 \") \n\n    # Int8 Matrix Multiply (FEAT_I8MM / ARMv8.2-A) Compulsory from ARMv8.6-A\n    # Use the base arch flag to enable the features, relying on modern toolchain support.\n    handle_arch_flags(I8MM \" -march=armv8.2-a+i8mm \" \" /arch:armv8.2 \") \n\n    # SVE2 (Scalable Vector Extension 2) (FEAT_SVE2 / ARMv8.5-A) Compulsory from ARMv9.0-A\n    handle_arch_flags(SVE2 \" -march=armv8.5-a+sve2 \" \" /arch:armv8.5 \") \n\n    # SVE2.1 (FEAT_SVE2p1 / ARMv9.1-A)\n    handle_arch_flags(SVE2_1 \" -march=armv9.1-a+sve2.1 \" \" /arch:armv9.1 \")\n\nelse()\n    # =========================================================================\n    # Intel (x86/x64) SIMD Flags\n    # =========================================================================  \n# gcc/llvm/clang-like flags, MSVC flags\nhandle_arch_flags(SSSE3 \" -mssse3 \" \" /arch:SSE2 \") # no special SSSE3 option in MSVC\nhandle_arch_flags(SSE41 \" -msse4.1 \" \" /arch:SSE2 \") # no special SSE4.1 option in MSVC\nhandle_arch_flags(AVX \" -mavx \" \" /arch:AVX \")\nhandle_arch_flags(AVX2 \" -mavx2 -mfma \" \" /arch:AVX2 \")\n\nif(DEFINE_AVX512)\n        # Similar to AVX2, FMA must be added explicitly for GCC/Clang.\n        # We also enable BMI2, as it is standard since AVX2 and useful for \n        # AVX-512 mask operations like _bzhi_u64/u32.\n        # The core subsets (F, CD, BW, DQ, VL) comprising the CPUF_AVX512_BASE \n        # flag are present on all AVX-512-capable architectures.\n        #\n        # Note: Early Xeon (e.g., Skylake-X/Cascadelake) may exhibit severe \n        # thermal throttling even on a single thread. In AviSynth+, AVX512_BASE \n        # must be manually enabled in-script unless CPUF_AVX512_FAST is also detected.\n        # Functions in *_avx512b.cpp should be dispatched on CPUF_AVX512_BASE.\n        set(AVX512_BASE_GCC_FLAGS\n            \" -mfma -mbmi2 -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl \"\n        )\n\n        # CPUF_AVX512_FAST indicates a modern, low-throttling architecture (ICL/RKL/AVX10.x).\n        # This set represents the intersection of Icelake and AVX10.1 features:\n    # (F, CD, BW, DQ, VL, VNNI, VBMI, VBMI2, BITALG, VPOPCNTDQ).\n        # Functions in *_avx512.cpp should be dispatched on CPUF_AVX512_FAST.\n    set(AVX512_FAST_GCC_FLAGS\n        #\" -march=icelake-client \"  # PF test\n        #\" -march=graniterapids \" # PF test avx10.1\n            \" -mfma -mbmi2 -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl -mavx512vnni -mavx512vbmi -mavx512vbmi2 -mavx512bitalg -mavx512vpopcntdq \"\n    )\n\n        # Note: MSVC's /arch:AVX512 enables the basic subset (F, CD, BW, DQ, VL).\n        # Unlike GCC/Clang, MSVC does not require individual flags for extensions \n        # like VBMI or VNNI; if the intrinsic is used, it is compiled directly. \n        # GCC/Clang require either file-level flags (set here) or function-level \n        # target attributes.\n        # GCC/Clang/Intel compilers will use -mavx512... flags via handle_arch_flags \n        # even when running within the MSVC_IDE.\n        handle_arch_flags(AVX512B \"${AVX512_BASE_GCC_FLAGS}\" \" /arch:AVX512 \") # *_avx512b.cpp\n        handle_arch_flags(AVX512 \"${AVX512_FAST_GCC_FLAGS}\" \" /arch:AVX512 \") # *_avx512.cpp\nendif()\nENDIF()\n\n# Specify include directories\ntarget_include_directories(\"AvsCore\" PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)\n# Specify preprocessor definitions\ntarget_compile_definitions(\"AvsCore\" PRIVATE BUILDING_AVSCORE)\n\nif(NOT ${BUILD_SHARED_LIBS})\n    target_compile_definitions(\"AvsCore\" PRIVATE AVS_STATIC_LIB)\nendif()\n\n# If checked out with compat filesystem submodule, add that to system include directories\nget_filename_component(\n    GHS_FILESYSTEM_INCLUDE_DIR\n    ${CMAKE_CURRENT_SOURCE_DIR}/../filesystem/include\n    ABSOLUTE\n)\nif (EXISTS ${GHS_FILESYSTEM_INCLUDE_DIR})\n    target_include_directories(\"AvsCore\" SYSTEM PRIVATE ${GHS_FILESYSTEM_INCLUDE_DIR})\nendif()\n\nif (CMAKE_SYSTEM_NAME STREQUAL \"Haiku\")\n    set(SYSLIB \"root\")\nelseif(CMAKE_SYSTEM_NAME STREQUAL \"OpenBSD\")\n    set(SYSLIB \"pthread\")\nelseif(MSVC OR MINGW)\n    set(SYSLIB \"uuid\" \"winmm\" \"vfw32\" \"msacm32\" \"gdi32\" \"user32\" \"advapi32\" \"ole32\" \"imagehlp\")\nelse()\n    set(SYSLIB \"pthread\" \"dl\" \"m\")\nendif()\n\nif(MINGW)\n    set(CMAKE_THREAD_PREFER_PTHREAD TRUE)\n    set(THREADS_PREFER_PTHREAD_FLAG TRUE)\n    find_package(Threads REQUIRED)\n\n    list(APPEND SYSLIB \"pthread\")\nendif()\n\nif(CMAKE_CXX_COMPILER_ID STREQUAL \"GNU\")\n    list(APPEND SYSLIB \"stdc++\")\n    # stdc++fs was mainlined into stdc++ in GCC 9, but GCC 8 can build it too\n    if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9)\n        list(APPEND SYSLIB \"stdc++fs\")\n    endif()\nelseif(NOT MSVC AND CMAKE_CXX_COMPILER_ID MATCHES \"Clang\")\n    list(APPEND SYSLIB \"c++\")\nendif()\n\ntarget_link_libraries(\"AvsCore\" ${SYSLIB})\n\nif(ENABLE_CUDA)\n  if(${CMAKE_VERSION} VERSION_LESS \"3.19.5\")\n    # deprecated since 3.10 but works\n    find_package(CUDA)\n    if(CUDA_FOUND)\n      target_include_directories(\"AvsCore\" PRIVATE ${CUDA_INCLUDE_DIRS})\n      #target_link_libraries (\"AvsCore\" ${CUDA_LIBRARIES})\n      target_link_libraries (\"AvsCore\" ${CUDA_cudart_static_LIBRARY})\n      target_compile_definitions(\"AvsCore\" PUBLIC ENABLE_CUDA)\n      list(APPEND SYSLIB \"cudart_static\")\n    endif()\n  else()\n    # Fixed in 3.19.5: https://gitlab.kitware.com/cmake/cmake/-/issues/21740\n    include(FindCUDAToolkit)\n    # FIXME: check supported compiler/platform/CUDA SDK version combinations\n    if(CUDAToolkit_FOUND)\n      target_include_directories(\"AvsCore\" PRIVATE ${CUDAToolkit_INCLUDE_DIRS})\n      target_link_libraries (\"AvsCore\" CUDA::cudart_static)\n      target_compile_definitions(\"AvsCore\" PUBLIC ENABLE_CUDA)\n      list(APPEND SYSLIB \"cudart_static\")\n    endif()\n  endif()\nendif()\n\nif (MSVC_IDE)\n  # Copy output to a common folder for easy deployment\n  add_custom_command(\n    TARGET AvsCore\n    POST_BUILD\n    COMMAND xcopy /Y \\\"$(TargetPath)\\\" \\\"${CMAKE_BINARY_DIR}/Output\\\"\n  )\n  IF(NOT CLANG_IN_VS STREQUAL \"1\" AND\n     NOT IntelLLVM_IN_VS STREQUAL \"1\" AND \n     NOT IntelClassic_IN_VS STREQUAL \"1\")\n    # LLVM does not generate exp or don't know how to do it\n    add_custom_command(\n      TARGET AvsCore\n      POST_BUILD\n      COMMAND xcopy /Y \\\"$(TargetDir)AviSynth.exp\\\" \\\"${CMAKE_BINARY_DIR}/Output/c_api\\\"\n    )\n  ENDIF()\n  add_custom_command(\n    TARGET AvsCore\n    POST_BUILD\n    COMMAND xcopy /Y \\\"$(TargetDir)AviSynth.lib\\\" \\\"${CMAKE_BINARY_DIR}/Output/c_api\\\"\n  )\n  add_custom_command(\n    TARGET AvsCore\n    POST_BUILD\n    COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_BINARY_DIR}/Output/include\n  )\nendif()\n\n# Determine target architecture\ninclude(\"${CMAKE_CURRENT_LIST_DIR}/TargetArch.cmake\")\ntarget_architecture(AVS_ARCH)\nCONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/core/arch.h.in ${CMAKE_CURRENT_BINARY_DIR}/arch.h @ONLY)\n\n# Dynamically generate the sequential version info from Git\n# Based on the example here: http://www.cmake.org/pipermail/cmake/2010-July/038015.html\nFIND_PACKAGE(Git)\nINCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})\nADD_CUSTOM_TARGET(\n    VersionGen\n    ${CMAKE_COMMAND} -D SRC=${CMAKE_CURRENT_SOURCE_DIR}/core/version.h.in\n                     -D DST=${CMAKE_CURRENT_BINARY_DIR}/version.h\n                     -D GIT=${GIT_EXECUTABLE}\n                     -D REPO=${CMAKE_SOURCE_DIR}\n                     -P ${CMAKE_CURRENT_SOURCE_DIR}/Version.cmake\n)\nADD_DEPENDENCIES(\"AvsCore\" VersionGen)\n\nIF(MSVC_IDE)\n  add_custom_command(\n    TARGET AvsCore\n    POST_BUILD\n    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/avs_core/version.h ${CMAKE_BINARY_DIR}/avs_core/arch.h ${CMAKE_BINARY_DIR}/Output/include/avs\n  )\nendif()\n\nif (NOT EXISTS \"${CMAKE_SOURCE_DIR}/.git\" OR NOT GIT_FOUND)\n  set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -DRELEASE_TARBALL\")\nendif()\n\n# Generate pkg-config file\nget_target_property(LIB_NAME AvsCore OUTPUT_NAME)\nset(LIBS \"-l${LIB_NAME}\")\nset(_SYSLIBS_ITEMS ${SYSLIB})\nlist(TRANSFORM _SYSLIBS_ITEMS PREPEND \"-l\")\nlist(JOIN _SYSLIBS_ITEMS \" \" SYSLIBS)\n\nif(MINGW)\nset(SYSLIBS \"${SYSLIBS} -static\")\nendif()\n\nCONFIGURE_FILE(\"avisynth.pc.in\" \"avisynth.pc\" @ONLY)\n\n# Generate avisynth.conf\nCONFIGURE_FILE(\"avisynth_conf.h.in\" \"avisynth_conf.h\" @ONLY)\n\nINSTALL(TARGETS AvsCore\n        RUNTIME DESTINATION \"${CMAKE_INSTALL_BINDIR}\"\n        LIBRARY DESTINATION \"${CMAKE_INSTALL_LIBDIR}\"\n        ARCHIVE DESTINATION \"${CMAKE_INSTALL_LIBDIR}\")\n\nINSTALL(DIRECTORY \"include/\"\n        DESTINATION \"${CMAKE_INSTALL_INCLUDEDIR}/avisynth\")\n\nINSTALL(FILES \"${CMAKE_CURRENT_BINARY_DIR}/version.h\"\n              \"${CMAKE_CURRENT_BINARY_DIR}/arch.h\"\n        DESTINATION \"${CMAKE_INSTALL_INCLUDEDIR}/avisynth/avs\")\n\nINSTALL(FILES \"${CMAKE_CURRENT_BINARY_DIR}/avisynth.pc\"\n        DESTINATION \"${CMAKE_INSTALL_LIBDIR}/pkgconfig\")\n"
  },
  {
    "path": "avs_core/Files.cmake",
    "content": "FILE(GLOB AvsCore_Sources RELATIVE \"${CMAKE_CURRENT_SOURCE_DIR}\"\n  \"*.c\"\n  \"*.cpp\"\n  \"*.h\"\n\n  \"include/*.h\"\n  \"include/avs/*.h\"\n\n  \"convert/*.c\"\n  \"convert/*.cpp\"\n  \"convert/*.h\"\n\n  \"core/*.c\"\n  \"core/*.cpp\"\n  \"core/*.h\"\n\n  \"core/parser/*.c\"\n  \"core/parser/*.cpp\"\n  \"core/parser/*.h\"\n\n  \"core/fonts/*.cpp\"\n  \"core/fonts/*.h\"\n\n  \"filters/*.c\"\n  \"filters/*.cpp\"\n  \"filters/*.h\"\n\n  \"filters/conditional/*.c\"\n  \"filters/conditional/*.cpp\"\n  \"filters/conditional/*.h\"\n\n  \"filters/overlay/*.c\"\n  \"filters/overlay/*.cpp\"\n  \"filters/overlay/*.h\"\n\n  \"filters/exprfilter/*.cpp\"\n  \"filters/exprfilter/*.h\"\n\n)\n\nIF(ENABLE_NEON_SIMD)\n  FILE(GLOB Conditional_Filter_Cpu_Sources RELATIVE \"${CMAKE_CURRENT_SOURCE_DIR}\"\n    \"filters/conditional/aarch64/*.cpp\"\n    \"filters/conditional/aarch64/*.h\")\n  LIST(APPEND AvsCore_Sources \"${Conditional_Filter_Cpu_Sources}\")\n\n  FILE(GLOB Convert_Cpu_Sources RELATIVE \"${CMAKE_CURRENT_SOURCE_DIR}\"\n    \"convert/aarch64/*.cpp\"\n    \"convert/aarch64/*.h\")\n  LIST(APPEND AvsCore_Sources \"${Convert_Cpu_Sources}\")\n\n  FILE(GLOB Filters_Cpu_Sources RELATIVE \"${CMAKE_CURRENT_SOURCE_DIR}\"\n    \"filters/aarch64/*.cpp\"\n    \"filters/aarch64/*.h\")\n  LIST(REMOVE_ITEM AvsCore_Sources \"\")\n\n  LIST(APPEND AvsCore_Sources \"${Filters_Cpu_Sources}\")\n\n  FILE(GLOB Overlay_Cpu_Sources RELATIVE \"${CMAKE_CURRENT_SOURCE_DIR}\"\n    \"filters/overlay/aarch64/*.cpp\"\n    \"filters/overlay/aarch64/*.h\")\n  #not removing yet, unlike for Intel, no SIMD replacement\n  #LIST(REMOVE_ITEM AvsCore_Sources \"filters/overlay/444convert.cpp\"\n  #                                 \"filters/overlay/444convert.h\")\n  LIST(APPEND AvsCore_Sources \"${Overlay_Cpu_Sources}\")\nENDIF()\n\nIF(ENABLE_INTEL_SIMD)\n  FILE(GLOB Conditional_Filter_Cpu_Sources RELATIVE \"${CMAKE_CURRENT_SOURCE_DIR}\"\n    \"filters/conditional/intel/*.cpp\"\n    \"filters/conditional/intel/*.hpp\"\n    \"filters/conditional/intel/*.h\")\n  LIST(APPEND AvsCore_Sources \"${Conditional_Filter_Cpu_Sources}\")\n\n  FILE(GLOB Convert_Cpu_Sources RELATIVE \"${CMAKE_CURRENT_SOURCE_DIR}\"\n    \"convert/intel/*.cpp\"\n    \"convert/intel/*.hpp\"\n    \"convert/intel/*.h\")\n  LIST(APPEND AvsCore_Sources \"${Convert_Cpu_Sources}\")\n\n  FILE(GLOB Filters_Cpu_Sources RELATIVE \"${CMAKE_CURRENT_SOURCE_DIR}\"\n    \"filters/intel/*.cpp\"\n    \"filters/intel/*.hpp\"\n    \"filters/intel/*.h\")\n  LIST(REMOVE_ITEM AvsCore_Sources \"\")\n\n  LIST(APPEND AvsCore_Sources \"${Filters_Cpu_Sources}\")\n\n  FILE(GLOB Overlay_Cpu_Sources RELATIVE \"${CMAKE_CURRENT_SOURCE_DIR}\"\n    \"filters/overlay/intel/*.cpp\"\n    \"filters/overlay/intel/*.hpp\"\n    \"filters/overlay/intel/*.h\")\n  LIST(REMOVE_ITEM AvsCore_Sources \"filters/overlay/444convert.cpp\"\n                                   \"filters/overlay/444convert.h\")\n  LIST(APPEND AvsCore_Sources \"${Overlay_Cpu_Sources}\")\nENDIF()\n\nIF( MSVC OR MINGW )\n# AviSource is Windows-only, because it depends on Video for Windows\n  FILE(GLOB AvsCore_Sources_AviSource RELATIVE \"${CMAKE_CURRENT_SOURCE_DIR}\"\n    \"filters/AviSource/*.c\"\n    \"filters/AviSource/*.cpp\"\n    \"filters/AviSource/*.h\")\n  LIST(APPEND AvsCore_Sources \"${AvsCore_Sources_AviSource}\")\nELSE()\n  LIST(APPEND AvsCore_Sources \"core/parser/os/win32_string_compat.cpp\")\n  LIST(APPEND AvsCore_Sources \"core/parser/os/win32_string_compat.h\")\nENDIF()\n\nIF( MSVC )\n    # Export definitions in general are not needed on x64 and only cause warnings,\n    # unfortunately we still must need a .def file for some COM functions.\n    if(CMAKE_SIZEOF_VOID_P EQUAL 8)\n      LIST(APPEND AvsCore_Sources \"core/avisynth64.def\")\n    else()\n      LIST(APPEND AvsCore_Sources \"core/avisynth.def\")\n    endif()\nENDIF()\n\nIF( MSVC_IDE )\n    # Ninja, unfortunately, seems to have some issues with using rc.exe\n    LIST(APPEND AvsCore_Sources \"core/avisynth.rc\")\nENDIF()\n"
  },
  {
    "path": "avs_core/TargetArch.cmake",
    "content": "# http://stackoverflow.com/questions/11944060/how-to-detect-target-architecture-using-cmake\n# https://github.com/petroules/solar-cmake/blob/master/TargetArch.cmake\n\n# Based on the Qt 5 processor detection code, so should be very accurate\n# https://qt.gitorious.org/qt/qtbase/blobs/master/src/corelib/global/qprocessordetection.h\n# Currently handles arm (v5, v6, v7), x86 (32/64), ia64, and ppc (32/64)\n\n# Regarding POWER/PowerPC, just as is noted in the Qt source,\n# \"There are many more known variants/revisions that we do not handle/detect.\"\n\nset(archdetect_c_code \"\n#if defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM) || defined(_M_ARM64) || defined(__aarch64__) || defined(__ARM64__)\n    #if defined(__ARM64_ARCH_8__) \\\n        || defined(__aarch64__) \\\n        || defined(__ARMv8__) \\\n        || defined(__ARMv8_A__) \\\n        || defined(_M_ARM64)\n        #error cmake_ARCH aarch64\n    #elif defined(__ARM_ARCH_7__) \\\\\n        || defined(__ARM_ARCH_7A__) \\\\\n        || defined(__ARM_ARCH_7R__) \\\\\n        || defined(__ARM_ARCH_7M__) \\\\\n        || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 7)\n        #error cmake_ARCH armv7\n    #elif defined(__ARM_ARCH_6__) \\\\\n        || defined(__ARM_ARCH_6J__) \\\\\n        || defined(__ARM_ARCH_6T2__) \\\\\n        || defined(__ARM_ARCH_6Z__) \\\\\n        || defined(__ARM_ARCH_6K__) \\\\\n        || defined(__ARM_ARCH_6ZK__) \\\\\n        || defined(__ARM_ARCH_6M__) \\\\\n        || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 6)\n        #error cmake_ARCH armv6\n    #elif defined(__ARM_ARCH_5TEJ__) \\\\\n        || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 5)\n        #error cmake_ARCH armv5\n    #else\n        #error cmake_ARCH arm\n    #endif\n#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)\n    #error cmake_ARCH i386\n#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)\n    #error cmake_ARCH x86_64\n#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)\n    #error cmake_ARCH ia64\n#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \\\\\n      || defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC)  \\\\\n      || defined(_M_MPPC) || defined(_M_PPC)\n    #if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__)\n        #error cmake_ARCH ppc64\n    #else\n        #error cmake_ARCH ppc\n    #endif\n#elif defined(__riscv)\n    #error cmake_ARCH riscv\n#elif defined(__sparc_v9__)\n    #error cmake_ARCH sparc\n#elif defined(__mips__)\n    #error cmake_ARCH mips\n#elif defined(__s390x__)\n    #error cmake_ARCH s390x\n#endif\n\n#error cmake_ARCH unknown\n\")\n\n# Set ppc_support to TRUE before including this file or ppc and ppc64\n# will be treated as invalid architectures since they are no longer supported by Apple\n\nfunction(target_architecture output_var)\n    if(APPLE AND CMAKE_OSX_ARCHITECTURES)\n        # On OS X we use CMAKE_OSX_ARCHITECTURES *if* it was set\n        # First let's normalize the order of the values\n\n        # Note that it's not possible to compile PowerPC applications if you are using\n        # the OS X SDK version 10.6 or later - you'll need 10.4/10.5 for that, so we\n        # disable it by default\n        # See this page for more information:\n        # http://stackoverflow.com/questions/5333490/how-can-we-restore-ppc-ppc64-as-well-as-full-10-4-10-5-sdk-support-to-xcode-4\n\n        # Architecture defaults to i386 or ppc on OS X 10.5 and earlier, depending on the CPU type detected at runtime.\n        # On OS X 10.6+ the default is x86_64 if the CPU supports it, i386 otherwise.\n\n        foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES})\n            if(\"${osx_arch}\" STREQUAL \"ppc\" AND ppc_support)\n                set(osx_arch_ppc TRUE)\n            elseif(\"${osx_arch}\" STREQUAL \"i386\")\n                set(osx_arch_i386 TRUE)\n            elseif(\"${osx_arch}\" STREQUAL \"x86_64\")\n                set(osx_arch_x86_64 TRUE)\n            elseif(\"${osx_arch}\" STREQUAL \"ppc64\" AND ppc_support)\n                set(osx_arch_ppc64 TRUE)\n            elseif(\"${osx_arch}\" STREQUAL \"arm64\")\n                set(osx_arch_arm64 TRUE)\n            else()\n                message(FATAL_ERROR \"Invalid OS X arch name: ${osx_arch}\")\n            endif()\n        endforeach()\n\n        # Now add all the architectures in our normalized order\n        if(osx_arch_ppc)\n            list(APPEND ARCH ppc)\n        endif()\n\n        if(osx_arch_i386)\n            list(APPEND ARCH i386)\n        endif()\n\n        if(osx_arch_x86_64)\n            list(APPEND ARCH x86_64)\n        endif()\n\n        if(osx_arch_ppc64)\n            list(APPEND ARCH ppc64)\n        endif()\n\n        if(osx_arch_arm64)\n            list(APPEND ARCH arm64)\n        endif()\n    else()\n        file(WRITE \"${CMAKE_BINARY_DIR}/arch.c\" \"${archdetect_c_code}\")\n\n        enable_language(C)\n\n        # Detect the architecture in a rather creative way...\n        # This compiles a small C program which is a series of ifdefs that selects a\n        # particular #error preprocessor directive whose message string contains the\n        # target architecture. The program will always fail to compile (both because\n        # file is not a valid C program, and obviously because of the presence of the\n        # #error preprocessor directives... but by exploiting the preprocessor in this\n        # way, we can detect the correct target architecture even when cross-compiling,\n        # since the program itself never needs to be run (only the compiler/preprocessor)\n        try_run(\n            run_result_unused\n            compile_result_unused\n            \"${CMAKE_BINARY_DIR}\"\n            \"${CMAKE_BINARY_DIR}/arch.c\"\n            COMPILE_OUTPUT_VARIABLE ARCH\n            CMAKE_FLAGS CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}\n        )\n\n        # Parse the architecture name from the compiler output\n        string(REGEX MATCH \"cmake_ARCH ([a-zA-Z0-9_]+)\" ARCH \"${ARCH}\")\n\n        # Get rid of the value marker leaving just the architecture name\n        string(REPLACE \"cmake_ARCH \" \"\" ARCH \"${ARCH}\")\n\n        # If we are compiling with an unknown architecture this variable should\n        # already be set to \"unknown\" but in the case that it's empty (i.e. due\n        # to a typo in the code), then set it to unknown\n        if (NOT ARCH)\n            set(ARCH unknown)\n        endif()\n    endif()\n\n    set(${output_var} \"${ARCH}\" PARENT_SCOPE)\nendfunction()\n"
  },
  {
    "path": "avs_core/Version.cmake",
    "content": "FIND_PACKAGE(Git)\nif (EXISTS \"${REPO}/.git\" AND GIT_FOUND)\nEXECUTE_PROCESS(\n    COMMAND \"${GIT}\" --git-dir=${REPO}/.git  rev-list --count HEAD\n    OUTPUT_VARIABLE AVS_SEQREV\n    OUTPUT_STRIP_TRAILING_WHITESPACE\n)\nEXECUTE_PROCESS(\n    COMMAND \"${GIT}\" --git-dir=${REPO}/.git  rev-parse --abbrev-ref HEAD\n    OUTPUT_VARIABLE AVS_BRANCH\n    OUTPUT_STRIP_TRAILING_WHITESPACE\n)\n\n# find the newest created tag, which will hopefully only be relevant to\n# release tags (which themselves only apply to the release branches)\nEXECUTE_PROCESS(\n    COMMAND \"${GIT}\" --git-dir=${REPO}/.git  describe --tags --abbrev=0\n    OUTPUT_VARIABLE AVS_NEWEST_TAG\n)\nstring(STRIP ${AVS_NEWEST_TAG} AVS_NEWEST_TAG)\n\n# count the number of commits since the most recently created tag.\n# if an older-than-tag commit has been checked out as HEAD, then this\n# will report '0', which shouldn't be a problem because this is entirely\n# intended for the purposes of current development and not as an\n# arbitrary meter between release tags.\nEXECUTE_PROCESS(\n    COMMAND \"${GIT}\" --git-dir=${REPO}/.git  rev-list --count ${AVS_NEWEST_TAG}..HEAD\n    OUTPUT_VARIABLE AVS_DEVNEXT_REV\n    OUTPUT_STRIP_TRAILING_WHITESPACE\n)\n\n# date of last git commit to branch\nEXECUTE_PROCESS(\n    COMMAND \"${GIT}\" --git-dir=${REPO}/.git  log -1 HEAD --format=%cd --date=unix\n    OUTPUT_VARIABLE AVS_DEV_REVDATE\n    OUTPUT_STRIP_TRAILING_WHITESPACE\n)\nset(ENV{SOURCE_DATE_EPOCH} ${AVS_DEV_REVDATE})\nstring(TIMESTAMP AVS_DEV_REVDATE %Y-%m-%d UTC)\nunset(ENV{SOURCE_DATE_EPOCH})\n\n# abbreviated git commit hash\nEXECUTE_PROCESS(\n    COMMAND \"${GIT}\" --git-dir=${REPO}/.git  describe --tags\n    OUTPUT_VARIABLE AVS_DEV_GITHASH\n    OUTPUT_STRIP_TRAILING_WHITESPACE\n)\nendif()\nCONFIGURE_FILE(${SRC} ${DST} @ONLY)\n"
  },
  {
    "path": "avs_core/avisynth.pc.in",
    "content": "prefix=@CMAKE_INSTALL_PREFIX@\nexec_prefix=@CMAKE_INSTALL_PREFIX@\nlibdir=@CMAKE_INSTALL_FULL_LIBDIR@\nincludedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@/avisynth\n\nName: AviSynth+\nDescription: A powerful nonlinear scripting language for video.\nVersion: @PROJECT_VERSION@\n\nLibs: -L${libdir} @LIBS@\nLibs.private: @SYSLIBS@\nCflags: -I${includedir}\nCflags.private: -DAVS_STATIC_LIB\n"
  },
  {
    "path": "avs_core/avisynth_conf.h.in",
    "content": "#ifndef _AVS_CONF_H_\n#define _AVS_CONF_H_\n\n#include <avs/config.h>\n\n#ifdef AVS_POSIX\n#define user_avs_plugindir_configurable \"@USER_AVS_PLUGINDIR_LOCATION@\"\n#define system_avs_plugindir \"@CORE_PLUGIN_INSTALL_PATH@/avisynth\"\n#endif\n\n#endif // _AVS_CONF_H_\n"
  },
  {
    "path": "avs_core/convert/convert.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002-2009 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include \"convert.h\"\n#include \"convert_matrix.h\"\n#include \"convert_helper.h\"\n#include \"convert_bits.h\"\n#include \"convert_planar.h\"\n#include \"convert_rgb.h\"\n\n#include <avs/alignment.h>\n#include <avs/minmax.h>\n#include <avs/config.h>\n#include <tuple>\n#include <map>\n#include <algorithm>\n#include <cassert>\n\n#ifdef AVS_WINDOWS\n#include <avs/win.h>\n#else\n#include <avs/posix.h>\n#endif\n\n/********************************************************************\n***** Declare index of new filters for Avisynth's filter engine *****\n********************************************************************/\n\nextern const AVSFunction Convert_filters[] = {\n  { \"ConvertToRGB\",   BUILTIN_FUNC_PREFIX, \"c[matrix]s[interlaced]b[ChromaInPlacement]s[chromaresample]s[param1]f[param2]f[param3]f[bits]i[quality]b\", CreateConvertToAdaptivePackedRGB, (void *)0 },\n  { \"ConvertToRGB24\", BUILTIN_FUNC_PREFIX, \"c[matrix]s[interlaced]b[ChromaInPlacement]s[chromaresample]s[param1]f[param2]f[param3]f[bits]i[quality]b\", CreateConvertToPackedRGB, (void *)24 },\n  { \"ConvertToRGB32\", BUILTIN_FUNC_PREFIX, \"c[matrix]s[interlaced]b[ChromaInPlacement]s[chromaresample]s[param1]f[param2]f[param3]f[bits]i[quality]b\", CreateConvertToPackedRGB, (void *)32 },\n  { \"ConvertToRGB48\", BUILTIN_FUNC_PREFIX, \"c[matrix]s[interlaced]b[ChromaInPlacement]s[chromaresample]s[param1]f[param2]f[param3]f[bits]i[quality]b\", CreateConvertToPackedRGB, (void *)48 },\n  { \"ConvertToRGB64\", BUILTIN_FUNC_PREFIX, \"c[matrix]s[interlaced]b[ChromaInPlacement]s[chromaresample]s[param1]f[param2]f[param3]f[bits]i[quality]b\", CreateConvertToPackedRGB, (void *)64 },\n  { \"ConvertToPlanarRGB\",  BUILTIN_FUNC_PREFIX, \"c[matrix]s[interlaced]b[ChromaInPlacement]s[chromaresample]s[param1]f[param2]f[param3]f[bits]i[quality]b\", CreateConvertToRGB, (void *)-1 },\n  { \"ConvertToPlanarRGBA\", BUILTIN_FUNC_PREFIX, \"c[matrix]s[interlaced]b[ChromaInPlacement]s[chromaresample]s[param1]f[param2]f[param3]f[bits]i[quality]b\", CreateConvertToRGB, (void *)-2 },\n  { \"ConvertToY8\",    BUILTIN_FUNC_PREFIX, \"c[matrix]s[bits]i[quality]b\", ConvertToPlanarGeneric::CreateY, (void*)0 }, // user_data == 0 -> only 8 bit sources\n  { \"ConvertToYV12\",  BUILTIN_FUNC_PREFIX, \"c[interlaced]b[matrix]s[ChromaInPlacement]s[chromaresample]s[ChromaOutPlacement]s[param1]f[param2]f[param3]f[bits]i[quality]b\", ConvertToPlanarGeneric::CreateYUV420, (void*)0 },\n  { \"ConvertToYV24\",  BUILTIN_FUNC_PREFIX, \"c[interlaced]b[matrix]s[ChromaInPlacement]s[chromaresample]s[param1]f[param2]f[param3]f[bits]i[quality]b\", ConvertToPlanarGeneric::CreateYUV444, (void*)0},\n  { \"ConvertToYV16\",  BUILTIN_FUNC_PREFIX, \"c[interlaced]b[matrix]s[ChromaInPlacement]s[chromaresample]s[ChromaOutPlacement]s[param1]f[param2]f[param3]f[bits]i[quality]b\", ConvertToPlanarGeneric::CreateYUV422, (void*)0},\n  { \"ConvertToYV411\", BUILTIN_FUNC_PREFIX, \"c[interlaced]b[matrix]s[ChromaInPlacement]s[chromaresample]s[param1]f[param2]f[param3]f[bits]i[quality]b\", ConvertToPlanarGeneric::CreateYV411, (void*)0},\n  { \"ConvertToYUY2\",  BUILTIN_FUNC_PREFIX, \"c[interlaced]b[matrix]s[ChromaInPlacement]s[chromaresample]s[ChromaOutPlacement]s[param1]f[param2]f[param3]f[bits]i[quality]b\", ConvertToPlanarGeneric::CreateConvertToYUY2 },\n  { \"ConvertBackToYUY2\", BUILTIN_FUNC_PREFIX, \"c[matrix]s\", ConvertToPlanarGeneric::CreateConvertBackToYUY2 },\n  { \"ConvertToY\",       BUILTIN_FUNC_PREFIX, \"c[matrix]s[bits]i[quality]b\", ConvertToPlanarGeneric::CreateY, (void*)1 }, // user_data == 1 -> any bit depth sources\n  { \"ConvertToYUV411\", BUILTIN_FUNC_PREFIX, \"c[interlaced]b[matrix]s[ChromaInPlacement]s[chromaresample]s[param1]f[param2]f[param3]f[bits]i[quality]b\", ConvertToPlanarGeneric::CreateYV411, (void*)1}, // alias for ConvertToYV411, 8 bit check later\n  { \"ConvertToYUV420\",  BUILTIN_FUNC_PREFIX, \"c[interlaced]b[matrix]s[ChromaInPlacement]s[chromaresample]s[ChromaOutPlacement]s[param1]f[param2]f[param3]f[bits]i[quality]b\", ConvertToPlanarGeneric::CreateYUV420, (void*)1},\n  { \"ConvertToYUV422\",  BUILTIN_FUNC_PREFIX, \"c[interlaced]b[matrix]s[ChromaInPlacement]s[chromaresample]s[ChromaOutPlacement]s[param1]f[param2]f[param3]f[bits]i[quality]b\", ConvertToPlanarGeneric::CreateYUV422, (void*)1},\n  { \"ConvertToYUV444\",  BUILTIN_FUNC_PREFIX, \"c[interlaced]b[matrix]s[ChromaInPlacement]s[chromaresample]s[param1]f[param2]f[param3]f[bits]i[quality]b\", ConvertToPlanarGeneric::CreateYUV444, (void*)1},\n  { \"ConvertToYUVA420\", BUILTIN_FUNC_PREFIX, \"c[interlaced]b[matrix]s[ChromaInPlacement]s[chromaresample]s[ChromaOutPlacement]s[param1]f[param2]f[param3]f[bits]i[quality]b\", ConvertToPlanarGeneric::CreateYUV420, (void*)2},\n  { \"ConvertToYUVA422\", BUILTIN_FUNC_PREFIX, \"c[interlaced]b[matrix]s[ChromaInPlacement]s[chromaresample]s[ChromaOutPlacement]s[param1]f[param2]f[param3]f[bits]i[quality]b\", ConvertToPlanarGeneric::CreateYUV422, (void*)2},\n  { \"ConvertToYUVA444\", BUILTIN_FUNC_PREFIX, \"c[interlaced]b[matrix]s[ChromaInPlacement]s[chromaresample]s[param1]f[param2]f[param3]f[bits]i[quality]b\", ConvertToPlanarGeneric::CreateYUV444, (void*)2},\n  { \"ConvertTo8bit\",  BUILTIN_FUNC_PREFIX, \"c[bits]i[truerange]b[dither]i[dither_bits]i[fulls]b[fulld]b\", ConvertBits::Create, (void *)8 },\n  { \"ConvertTo16bit\", BUILTIN_FUNC_PREFIX, \"c[bits]i[truerange]b[dither]i[dither_bits]i[fulls]b[fulld]b\", ConvertBits::Create, (void *)16 },\n  { \"ConvertToFloat\", BUILTIN_FUNC_PREFIX, \"c[bits]i[truerange]b[dither]i[dither_bits]i[fulls]b[fulld]b\", ConvertBits::Create, (void *)32 },\n  { \"ConvertBits\",    BUILTIN_FUNC_PREFIX, \"c[bits]i[truerange]b[dither]i[dither_bits]i[fulls]b[fulld]b\", ConvertBits::Create, (void *)0 },\n  { \"AddAlphaPlane\",  BUILTIN_FUNC_PREFIX, \"c[mask].[opacity]f\", AddAlphaPlane::Create},\n  { \"RemoveAlphaPlane\",  BUILTIN_FUNC_PREFIX, \"c\", RemoveAlphaPlane::Create},\n  { 0 }\n};\n\n\n/****************************************\n*******   Convert to RGB / RGBA   ******\n***************************************/\n\n// 0    1         2                 3                  4          5        6        7       8       9\n// c[matrix]s[interlaced]b[ChromaInPlacement]s[chromaresample]s[param1]f[param2]f[param3]f[bits]i[quality]b\n\n// Special syntax: adaptive packed target format: ConvertToRGB\nAVSValue __cdecl CreateConvertToAdaptivePackedRGB(AVSValue args, void* user_data, IScriptEnvironment* env)\n{\n  const PClip clip = args[0].AsClip();\n  const VideoInfo& vi = clip->GetVideoInfo();\n\n  // bits= if given must be 8 or 16 (only valid packed RGB channel depths)\n  int target_bits_per_channel;\n  if (args[8].Defined()) {\n    target_bits_per_channel = args[8].AsInt();\n    if (target_bits_per_channel != 8 && target_bits_per_channel != 16)\n      env->ThrowError(\"ConvertToRGB: bits must be 8 or 16 if specified. \"\n        \"Use ConvertToPlanarRGB for other bit depths.\");\n  }\n  else {\n    const int src_bits = vi.BitsPerComponent();\n    if (src_bits != 8 && src_bits != 16)\n      env->ThrowError(\"ConvertToRGB: source bit depth must be 8 or 16. \"\n        \"Use ConvertToPlanarRGB or ConvertBits(8)/ConvertBits(16) first.\");\n    target_bits_per_channel = src_bits;\n  }\n\n  // Decide target format based on source type and alpha capability (and the optional bits= override):\n  // - YUV/YUY2 source: always alpha-capable (RGB32 or RGB64)\n  // - RGB-like source: preserve alpha capability of source format\n  //     RGB32/RGB64/PlanarRGBA -> RGB32/RGB64 (with alpha)\n  //     RGB24/RGB48/PlanarRGB  -> RGB24/RGB48 (without alpha)\n  const bool hasAlpha = vi.IsYUV() || vi.IsYUVA() // YUV always gets alpha target\n    || vi.IsRGB32() || vi.IsRGB64()\n    || vi.IsPlanarRGBA();\n\n  // 8-bit: RGB24 or RGB32, 16-bit: RGB48 or RGB64\n  const intptr_t target_rgbtype = (target_bits_per_channel == 8)\n    ? (hasAlpha ? 32 : 24)\n    : (hasAlpha ? 64 : 48);\n\n  return CreateConvertToPackedRGB(args, reinterpret_cast<void*>(target_rgbtype), env);\n}\n\n// Registration names with implied fixed bit depth:\n// ConvertToRGB24 -> 24-bit only  (bits must be 24 if specified)\n// ConvertToRGB32 -> 32-bit only  (bits must be 32 if specified)\n// ConvertToRGB48 -> 48-bit only  (bits must be 48 if specified)\n// ConvertToRGB64 -> 64-bit only  (bits must be 64 if specified)\nAVSValue __cdecl CreateConvertToPackedRGB(AVSValue args, void* user_data, IScriptEnvironment* env)\n{\n  const int target_bits = (int)reinterpret_cast<intptr_t>(user_data); // 24, 32, 48, 64\n  const int target_bytes = target_bits / 8; // 3, 4, 6, 8\n  const int bits_per_channel = (target_bytes <= 4) ? 8 : 16; // RGB24/32=8bit, RGB48/64=16bit\n\n  // bits= must match the implied depth if specified\n  if (args[8].Defined() && args[8].AsInt() != bits_per_channel)\n    env->ThrowError(\"ConvertToRGB%d: bits must be %d if specified.\",\n      target_bits, bits_per_channel);\n\n  // Rebuild args with bits forced to the correct value\n  AVSValue new_args[10] = {\n    args[0], args[1], args[2], args[3], args[4],\n    args[5], args[6], args[7],\n    AVSValue(bits_per_channel), // bits forced\n    args[9]  // quality\n  };\n  AVSValue new_args_val(new_args, 10);\n  return CreateConvertToRGB(new_args_val, user_data, env);\n}\n\n// Dispatch hub for all ConvertToRGB variants.\n// Since 3.7.6 YUY2 is pre-converted to YV16 before dispatch, so no class is needed.\n// Called from ConvertToRGB24/32/48/64 and ConvertToPlanarRGB(A) registrations,\n// and from any internal env->Invoke(\"ConvertToRGB\",...) calls.\n// All ToRGB variants has bits and quality parameters, bit the quality=true and on-the-fly bit depth\n// conversion logic is only implemented for YUV->PlanarRGB path.\n\n// Note: when you add new parameters, find all places env->Invoke(\"ConvertToRGB\",...)\n// and check parameter count!\nAVSValue __cdecl CreateConvertToRGB(AVSValue args, void* user_data, IScriptEnvironment* env)\n{\n  PClip clip = args[0].AsClip();\n  VideoInfo vi = clip->GetVideoInfo();\n\n  // Before any conversions, convert YUY2 to YV16\n  if (vi.IsYUY2()) {\n    clip = new ConvertYUY2ToYV16_or_Y(clip, false /*to_y*/, env);\n    vi = clip->GetVideoInfo();\n  }\n\n  const char* const matrix_name = args[1].AsString(0);\n  const bool haveOpts = args[3].Defined() || args[4].Defined();\n\n  // common Create for all CreateRGB24/32/48/64/Planar(RGBP:-1, RGPAP:-2) using user_data\n  int target_rgbtype = (int)reinterpret_cast<intptr_t>(user_data);\n  // can be overridden later\n  // -1,-2: Planar RGB(A)\n  // 24,32,48,64: RGB24/32/48/64\n  const bool original_target_is_packed = target_rgbtype > 0; // 24,32,48,64\n\n  const int target_bits_per_pixel = args[8].AsInt(vi.BitsPerComponent());\n  // for legacy packed formats it's 8 for target_rgbtype==24,32, and 16 for target_rgbtype==48,64\n  // for planar RGB(A) target, it can be any bit depth supported by the source and the conversion logic (8,10,12,14,16,32)\n\n  const bool quality = args[9].AsBool(false); // yuv-planarrgb float workflow\n\n  // planar YUV-like source\n  if (vi.IsPlanar() && (vi.IsYUV() || vi.IsYUVA())) {\n    // here we keep the bit depth, later, the RGB conversion will take target_bits_per_pixel into account\n    AVSValue new_args[10] = { clip, args[2], args[1], args[3], args[4], args[5], args[6], args[7], vi.BitsPerComponent(), quality };\n    // conversion to planar or packed RGB is always from 444\n    // clip, interlaced, matrix, chromainplacement, chromaresample, param1, param2, param3, bits, quality   Check for ConvertToYUV444 param list!!!! Count must match!\n    clip = ConvertToPlanarGeneric::CreateYUV444(AVSValue(new_args, 10), (void*)1, env).AsClip(); // (void *)1: not restricted to 8 bits\n\n    // planar RGB(A) target or packed needing intermediate: set finalBitdepth if conversion needed\n    // also: when quality==true, we need to use the float workflow which requires a planar RGB(A) intermediate\n    if (target_rgbtype > 0) {\n      // packed RGB target: redirect to planar rgb(a) intermediate if bit-depth mismatch or quality mode\n      const bool hasAlpha = (target_rgbtype == 32 || target_rgbtype == 64);\n      if (vi.BitsPerComponent() != target_bits_per_pixel || quality)\n        target_rgbtype = hasAlpha ? -2 : -1;\n    }\n\n    if (target_rgbtype == 48 || target_rgbtype == 64) {\n      // Unlike parameter-less RGB24/32, 16 bit packed format have no direct conversions at all.\n      // 1.) YUV->PlanarRGB first (recursive call),\n      // 2.) then fall through to the planar RGB->packed RGB path below for the final repack\n      // So instead of unoptimized code of YUV(A)444P16->RGB48/64 we convert to PlanarRGB(A) then to RGB48/64\n      // Also: when quality=true or bit-depth conversion is needed, the planar RGB intermediate is required anyway\n      AVSValue new_args2[10] = { clip, args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]/*bits*/, args[9]/*quality*/ };\n\n      const intptr_t target_planar_rgb_type =\n        (target_rgbtype == 24 || target_rgbtype == 48) ? -1 : // no-alpha target: skip alpha even if source has it\n        vi.IsYUVA() ? -2 :  // alpha target + alpha source: preserve it\n        -1;   // alpha target + no alpha source: no alpha to copy\n      // Note: target_rgbtype == 24 is currently never reached here (24/32 use direct conversion path),\n      // but kept for when 24/32-bit packed is also redirected to the planar intermediate path in the future.\n\n      clip = CreateConvertToRGB(AVSValue(new_args2, 10), (void*)target_planar_rgb_type, env).AsClip();\n      vi = clip->GetVideoInfo(); // must update vi for fall-through\n      // Fall through to planar RGB source path below to do the final pack\n      // reuses the same PlanarRGBtoPackedRGB logic.\n    }\n    else {\n      // Direct YUV444->RGB conversion path\n      bool bitdepthConverted = false;\n      const int finalBitdepth = (vi.BitsPerComponent() != target_bits_per_pixel) ?\n        target_bits_per_pixel : -1; // -1 means: no need to convert\n\n      // Optional bit-depth conversion in PackedRGBtoPlanarRGB.\n      // Note: all formats are bit-depth-converted if finalBitdepth != -1\n      // (historically there were cases and bit-depths which were not implemented to have in-line bit-depth conversion)\n      // pass -1 as finalBitdepth, signing that no bit-depth conversion required\n\n      const int rgbtype_param = (target_rgbtype == -1 || target_rgbtype == -2) ? target_rgbtype : // planar RGB(A)\n        target_rgbtype == 24 ? 3 : 4; // RGB24 or RGB32 \"pixel_step\" parameter for legacy direct YUV444->RGB24/32 conversion\n\n      clip = new ConvertYUV444ToRGB(clip, matrix_name, rgbtype_param,\n        finalBitdepth, // -1 if no conversion needed\n        quality, /*ref*/bitdepthConverted, env);\n      vi = clip->GetVideoInfo();\n      // When direct YUV-RGB24/32 conversion happens, the result is not planar!\n\n      const bool needConvertFinalBitdepth = finalBitdepth != -1;\n\n      if (needConvertFinalBitdepth && !bitdepthConverted) {\n        AVSValue new_args[] = { clip, finalBitdepth };\n        clip = env->Invoke(\"ConvertBits\", AVSValue(new_args, 2)).AsClip();\n        vi = clip->GetVideoInfo();\n      }\n\n      // We can still have RGB24/32 here, YV24->24/32 is still valid\n      if (original_target_is_packed && vi.IsPlanar()) {\n        // from any planar rgb(a) -> rgb24/32/48/64\n        // source here is always a 8/16bit planar RGB(A), but we used\n        // planar intermediate.\n        // finally it has to be converted to RGB24/32/48/64\n        clip = new PlanarRGBtoPackedRGB(clip, target_rgbtype == -2);\n        vi = clip->GetVideoInfo();\n      }\n      return clip;\n    }\n  } // end of YUV->RGB path\n  else {\n    if (haveOpts)\n      env->ThrowError(\"ConvertToRGB: ChromaPlacement and ChromaResample options are not supported.\");\n  }\n\n  // This part can fallthrough from the YUV path when target is packed RGB\n\n  // RGB->RGB paths (planar or packed) do not support ChromaPlacement and ChromaResample options, as they are meaningless for RGB formats.\n\n  // Planar RGB(A) source\n  if (vi.IsPlanarRGB() || vi.IsPlanarRGBA())\n  {\n    // Handle alpha channel add/remove for planar-to-planar\n    if (target_rgbtype < 0) {\n      if (vi.IsPlanarRGB() && target_rgbtype == -2)\n        clip = new AddAlphaPlane(clip, nullptr, 0.0f, false, env);\n      else if (vi.IsPlanarRGBA() && target_rgbtype == -1)\n        clip = new RemoveAlphaPlane(clip, env);\n    }\n\n    // Convert bit depth if needed\n    if (vi.BitsPerComponent() != target_bits_per_pixel) {\n      AVSValue args[] = { clip, target_bits_per_pixel };\n      // plain Invoke instead of \"new ConvertBits\", this detects and keeps source and target ranges\n      clip = env->Invoke(\"ConvertBits\", AVSValue(args, 2)).AsClip();\n    }\n\n    // Convert planar to packed\n    if (target_rgbtype >= 0) {\n      bool hasAlpha = (target_rgbtype == 32 || target_rgbtype == 64);\n      clip = new PlanarRGBtoPackedRGB(clip, hasAlpha);\n    }\n\n    return clip;\n  } // Planar RGB(A) source\n\n  // YUV source is done\n  // Planar RGB(A) source is done\n  // Now remains packed RGB source\n  // Conversions from packed RGB\n\n  // Packed to Packed\n  if (target_rgbtype >= 0) {\n    // target bit depth (8-bit for 24/32, 16-bit for 48/64)\n    // target_bits_per_pixel is same as target_rgbtype\n\n    if (vi.BitsPerComponent() != target_bits_per_pixel) {\n      AVSValue args[] = { clip, target_bits_per_pixel };\n      // using Invoke instead of new ConvertBits, this detects and keeps source and target ranges\n      clip = env->Invoke(\"ConvertBits\", AVSValue(args, 2)).AsClip();\n      vi = clip->GetVideoInfo();\n    }\n\n    bool target_has_alpha = (target_rgbtype == 32 || target_rgbtype == 64);\n    bool source_has_alpha = (vi.IsRGB32() || vi.IsRGB64());\n\n    // between packed RGB types, alpha add/remove\n    if (target_has_alpha && !source_has_alpha)\n      return new RGBtoRGBA(clip);\n    if (!target_has_alpha && source_has_alpha)\n      return new RGBAtoRGB(clip);\n\n    return clip;\n  }\n\n  // Packed to Planar\n  // RGB24/32/48/64 ->\n  const bool isSrcRGBA = vi.IsRGB32() || vi.IsRGB64();\n  const bool isTargetRGBA = target_rgbtype == -2; // -2 planar RGBA, -1 planar RGB\n  clip = new PackedRGBtoPlanarRGB(clip, isSrcRGBA, isTargetRGBA);\n  vi = clip->GetVideoInfo(); // new format\n  // no embedded bitdepth conversion in PackedRGBtoPlanarRGB\n  if (target_bits_per_pixel != vi.BitsPerComponent()) {\n    AVSValue new_args[2] = { clip, target_bits_per_pixel };\n    clip = env->Invoke(\"ConvertBits\", AVSValue(new_args, 2)).AsClip();\n    vi = clip->GetVideoInfo(); // new format\n  }\n\n  return clip;\n}\n\n\nAVSValue AddAlphaPlane::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  bool isMaskDefined = args[1].Defined();\n  bool isOpacityDefined = args[2].Defined();\n  bool maskIsClip = false;\n\n  // if mask is not defined and videoformat has Alpha then we return\n  if (isMaskDefined && !args[1].IsClip() && !args[1].IsFloat())\n    env->ThrowError(\"AddAlphaPlane: mask parameter should be clip or number\");\n\n  if (isOpacityDefined && !args[2].IsFloat())\n    env->ThrowError(\"AddAlphaPlane: opacity parameter should be a number\");\n\n  if (isMaskDefined && isOpacityDefined)\n    env->ThrowError(\"AddAlphaPlane: cannot specify both mask and opacity parameters\");\n\n  const VideoInfo& vi = args[0].AsClip()->GetVideoInfo();\n  if (!isMaskDefined && !isOpacityDefined && (vi.IsPlanarRGBA() || vi.IsYUVA() || vi.IsRGB32() || vi.IsRGB64()))\n    return args[0].AsClip();\n\n  PClip alphaClip = nullptr;\n  if (isMaskDefined && args[1].IsClip()) {\n    const VideoInfo& viAlphaClip = args[1].AsClip()->GetVideoInfo();\n    maskIsClip = true;\n    if (viAlphaClip.BitsPerComponent() != vi.BitsPerComponent())\n      env->ThrowError(\"AddAlphaPlane: alpha clip is of different bit depth\");\n    if (viAlphaClip.width != vi.width || viAlphaClip.height != vi.height)\n      env->ThrowError(\"AddAlphaPlane: alpha clip is of different size\");\n    if (viAlphaClip.IsY())\n      alphaClip = args[1].AsClip();\n    else if (viAlphaClip.NumComponents() == 4) {\n      AVSValue new_args[1] = { args[1].AsClip() };\n      alphaClip = env->Invoke(\"ExtractA\", AVSValue(new_args, 1)).AsClip();\n    }\n    else {\n      env->ThrowError(\"AddAlphaPlane: alpha clip should be greyscale or should have alpha plane\");\n    }\n    // alphaClip is always greyscale here\n  }\n\n  float maskAsFloat = -1.0f;\n  if (!maskIsClip) {\n    if (isOpacityDefined) {\n      // Handle opacity parameter (0.0 to 1.0)\n      float opacity = args[2].AsFloatf(1.0f);\n      if (opacity < 0.0f || opacity > 1.0f)\n        env->ThrowError(\"AddAlphaPlane: opacity must be between 0.0 and 1.0\");\n      if (vi.BitsPerComponent() <= 16) {\n        int max_pixel_value = (1 << vi.BitsPerComponent()) - 1;\n        maskAsFloat = opacity * max_pixel_value;\n      }\n      else {\n        maskAsFloat = opacity;\n      }\n    }\n    else {\n      // Handle mask parameter (direct value)\n      maskAsFloat = (float)args[1].AsFloat(-1.0f);\n    }\n  }\n\n  if (vi.IsRGB24()) {\n    AVSValue new_args[1] = { args[0].AsClip() };\n    PClip child = env->Invoke(\"ConvertToRGB32\", AVSValue(new_args, 1)).AsClip();\n    return new AddAlphaPlane(child, alphaClip, maskAsFloat, isMaskDefined || isOpacityDefined, env);\n  }\n  else if (vi.IsRGB48()) {\n    AVSValue new_args[1] = { args[0].AsClip() };\n    PClip child = env->Invoke(\"ConvertToRGB64\", AVSValue(new_args, 1)).AsClip();\n    return new AddAlphaPlane(child, alphaClip, maskAsFloat, isMaskDefined || isOpacityDefined, env);\n  }\n  return new AddAlphaPlane(args[0].AsClip(), alphaClip, maskAsFloat, isMaskDefined || isOpacityDefined, env);\n}\n\nAddAlphaPlane::AddAlphaPlane(PClip _child, PClip _alphaClip, float _mask_f, bool isMaskDefined, IScriptEnvironment* env)\n  : GenericVideoFilter(_child), alphaClip(_alphaClip)\n  , mask(0), mask_f(0.0f), pixelsize(0), bits_per_pixel(0)\n{\n  if(vi.IsYUY2())\n    env->ThrowError(\"AddAlphaPlane: YUY2 is not allowed\");\n  if(vi.IsY())\n    env->ThrowError(\"AddAlphaPlane: greyscale source is not allowed\");\n  if(vi.IsYUV() && !vi.Is420() && !vi.Is422() && !vi.Is444()) // e.g. 410\n    env->ThrowError(\"AddAlphaPlane: YUV format not supported, must be 420, 422 or 444\");\n  if(!vi.IsYUV() && !vi.IsYUVA() && !vi.IsRGB())\n    env->ThrowError(\"AddAlphaPlane: format not supported\");\n\n  pixelsize = vi.ComponentSize();\n  bits_per_pixel = vi.BitsPerComponent();\n\n  if (vi.IsYUV()) {\n    int pixel_type = vi.pixel_type;\n    if (vi.IsYV12())\n      pixel_type = VideoInfo::CS_YV12;\n    int new_pixel_type = (pixel_type & ~VideoInfo::CS_YUV) | VideoInfo::CS_YUVA;\n    vi.pixel_type = new_pixel_type;\n  } else if(vi.IsPlanarRGB()) {\n    int pixel_type = vi.pixel_type;\n    int new_pixel_type = (pixel_type & ~VideoInfo::CS_RGB_TYPE) | VideoInfo::CS_RGBA_TYPE;\n    vi.pixel_type = new_pixel_type;\n  }\n  // RGB24 and RGB48 already converted to 32/64\n  // RGB32, RGB64, YUVA and RGBA: no change\n\n  // mask parameter. If none->max opacity\n\n  if (!alphaClip) {\n    int max_pixel_value = (1 << bits_per_pixel) - 1; // n/a for float\n    if (!isMaskDefined) {\n      mask_f = 1.0f;\n      mask = max_pixel_value;\n    }\n    else {\n      mask_f = _mask_f;\n      mask = (mask_f < 0) ? 0 : (mask_f > max_pixel_value) ? max_pixel_value : (int)(mask_f + 0.5f);\n      mask = clamp(mask, 0, max_pixel_value);\n      // no clamp for float\n    }\n  }\n}\n\nPVideoFrame AddAlphaPlane::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame src = child->GetFrame(n, env);\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n  if(vi.IsPlanar())\n  {\n    int planes_y[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };\n    int planes_r[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A };\n    int *planes = (vi.IsYUV() || vi.IsYUVA()) ? planes_y : planes_r;\n    // copy existing 3 planes\n    for (int p = 0; p < 3; ++p) {\n      const int plane = planes[p];\n      env->BitBlt(dst->GetWritePtr(plane), dst->GetPitch(plane), src->GetReadPtr(plane),\n           src->GetPitch(plane), src->GetRowSize(plane), src->GetHeight(plane));\n    }\n  } else {\n    // Packed RGB, already converted to RGB32 or RGB64\n    env->BitBlt(dst->GetWritePtr(), dst->GetPitch(), src->GetReadPtr(),\n      src->GetPitch(), src->GetRowSize(), src->GetHeight());\n  }\n\n  if (vi.IsPlanarRGBA() || vi.IsYUVA()) {\n    if (alphaClip) {\n      PVideoFrame srcAlpha = alphaClip->GetFrame(n, env);\n      env->BitBlt(dst->GetWritePtr(PLANAR_A), dst->GetPitch(PLANAR_A), srcAlpha->GetReadPtr(PLANAR_Y),\n        srcAlpha->GetPitch(PLANAR_Y), srcAlpha->GetRowSize(PLANAR_Y), srcAlpha->GetHeight(PLANAR_Y));\n    }\n    else {\n      // default constant\n      const int rowsizeA = dst->GetRowSize(PLANAR_A);\n      const int dst_pitchA = dst->GetPitch(PLANAR_A);\n      BYTE* dstp_a = dst->GetWritePtr(PLANAR_A);\n      const int heightA = dst->GetHeight(PLANAR_A);\n\n      switch (vi.ComponentSize())\n      {\n      case 1:\n        fill_plane<BYTE>(dstp_a, heightA, rowsizeA, dst_pitchA, mask);\n        break;\n      case 2:\n        fill_plane<uint16_t>(dstp_a, heightA, rowsizeA, dst_pitchA, mask);\n        break;\n      case 4:\n        fill_plane<float>(dstp_a, heightA, rowsizeA, dst_pitchA, mask_f);\n        break;\n      }\n    }\n    return dst;\n  }\n  // RGB32 and RGB64\n\n  BYTE* pf = dst->GetWritePtr();\n  int pitch = dst->GetPitch();\n  int rowsize = dst->GetRowSize();\n  int height = dst->GetHeight();\n  int width = vi.width;\n\n  if (alphaClip) {\n    // fill by alpha clip already converted to grey-only\n    PVideoFrame srcAlpha = alphaClip->GetFrame(n, env);\n    const BYTE* srcp_a = srcAlpha->GetReadPtr(PLANAR_Y);\n    size_t pitch_a = srcAlpha->GetPitch(PLANAR_Y);\n\n    pf += pitch * (vi.height - 1); // start from bottom: packed RGB is upside down\n\n    if (vi.IsRGB32()) {\n      for (int y = 0; y < height; y++) {\n        for (int x = 0; x < width; x ++) {\n          pf[x*4+3] = srcp_a[x];\n        }\n        pf -= pitch; // packed RGB is upside down\n        srcp_a += pitch_a;\n      }\n    }\n    else if (vi.IsRGB64()) {\n      rowsize /= sizeof(uint16_t);\n      for (int y = 0; y < height; y++) {\n        for (int x = 0; x < width; x ++) {\n          reinterpret_cast<uint16_t *>(pf)[x*4+3] = reinterpret_cast<const uint16_t *>(srcp_a)[x];\n        }\n        pf -= pitch; // packed RGB is upside down\n        srcp_a += pitch_a;\n      }\n    }\n  }\n  else {\n    // fill with constant\n    if (vi.IsRGB32()) {\n      for (int y = 0; y < height; y++) {\n        for (int x = 3; x < rowsize; x += 4) {\n          pf[x] = mask;\n        }\n        pf += pitch;\n      }\n    }\n    else if (vi.IsRGB64()) {\n      rowsize /= sizeof(uint16_t);\n      for (int y = 0; y < height; y++) {\n        for (int x = 3; x < rowsize; x += 4) {\n          reinterpret_cast<uint16_t *>(pf)[x] = mask;\n        }\n        pf += pitch;\n      }\n    }\n  }\n\n  return dst;\n}\n\nAVSValue RemoveAlphaPlane::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  // if videoformat has no Alpha then we return\n  const VideoInfo& vi = args[0].AsClip()->GetVideoInfo();\n  if(vi.IsPlanar() && (vi.IsYUV() || vi.IsPlanarRGB())) // planar and no alpha\n    return args[0].AsClip();\n  if (vi.IsYUY2()) // YUY2: no alpha\n    return args[0].AsClip();\n  if(vi.IsRGB24() || vi.IsRGB48()) // packed RGB and no alpha\n    return args[0].AsClip();\n  if (vi.IsRGB32()) {\n    AVSValue new_args[1] = { args[0].AsClip() };\n    return env->Invoke(\"ConvertToRGB24\", AVSValue(new_args, 1)).AsClip();\n  }\n  if (vi.IsRGB64()) {\n    AVSValue new_args[1] = { args[0].AsClip() };\n    return env->Invoke(\"ConvertToRGB48\", AVSValue(new_args, 1)).AsClip();\n  }\n  return new RemoveAlphaPlane(args[0].AsClip(), env);\n}\n\nRemoveAlphaPlane::RemoveAlphaPlane(PClip _child, IScriptEnvironment* env)\n  : GenericVideoFilter(_child)\n{\n  if(vi.IsYUY2())\n    env->ThrowError(\"RemoveAlphaPlane: YUY2 is not allowed\");\n  if(vi.IsY())\n    env->ThrowError(\"RemoveAlphaPlane: greyscale source is not allowed\");\n\n  if (vi.IsYUVA()) {\n    int pixel_type = vi.pixel_type;\n    int new_pixel_type = (pixel_type & ~VideoInfo::CS_YUVA) | VideoInfo::CS_YUV;\n    vi.pixel_type = new_pixel_type;\n  } else if(vi.IsPlanarRGBA()) {\n    int pixel_type = vi.pixel_type;\n    int new_pixel_type = (pixel_type & ~VideoInfo::CS_RGBA_TYPE) | VideoInfo::CS_RGB_TYPE;\n    vi.pixel_type = new_pixel_type;\n  }\n}\n\nPVideoFrame RemoveAlphaPlane::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame src = child->GetFrame(n, env);\n  // Packed RGB: already handled in ::Create through Invoke 32->24 or 64->48 conversion\n  // only planar here\n  int planes_y[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };\n  int planes_r[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A };\n  int *planes = (vi.IsYUV() || vi.IsYUVA()) ? planes_y : planes_r;\n  // Abuse Subframe to snatch the YUV/GBR planes\n  return env->SubframePlanar(src, 0, src->GetPitch(planes[0]), src->GetRowSize(planes[0]), src->GetHeight(planes[0]), 0, 0, src->GetPitch(planes[1]));\n\n#if 0\n  // BitBlt version. Kept for reference\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n  // copy 3 planes w/o alpha\n  for (int p = 0; p < 3; ++p) {\n    const int plane = planes[p];\n    env->BitBlt(dst->GetWritePtr(plane), dst->GetPitch(plane), src->GetReadPtr(plane),\n      src->GetPitch(plane), src->GetRowSize(plane), src->GetHeight(plane));\n  }\nreturn dst;\n#endif\n}\n\n"
  },
  {
    "path": "avs_core/convert/convert.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Convert_H__\n#define __Convert_H__\n\n#include <avisynth.h>\n\nAVSValue __cdecl CreateConvertToAdaptivePackedRGB(AVSValue args, void* user_data, IScriptEnvironment* env);\nAVSValue __cdecl CreateConvertToPackedRGB(AVSValue args, void* user_data, IScriptEnvironment* env);\nAVSValue __cdecl CreateConvertToRGB(AVSValue args, void* user_data, IScriptEnvironment* env);\n\n#endif  // __Convert_H__\n"
  },
  {
    "path": "avs_core/convert/convert_audio.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// ConvertAudio classes\n// Copyright (c) Klaus Post 2001 - 2004\n// Copyright (c) Ian Brabham 2005\n// Copyright (c) 2020 Xinyue Lu\n// Copyright (c) 2021 pinterf\n\n#include <avisynth.h>\n#include <avs/alignment.h>\n#include \"convert_audio.h\"\n#if defined(AVS_BSD) || defined(AVS_MACOS)\n  #include <stdlib.h>\n#else\n  #include <malloc.h>\n#endif\n\n// There are two type parameters. Acceptable sample types and a prefered sample type.\n// If the current clip is already one of the defined types in sampletype, this will be returned.\n// If not, the current clip will be converted to the prefered type.\nPClip ConvertAudio::Create(PClip clip, int sample_type, int prefered_type) {\n  if ((!clip->GetVideoInfo().HasAudio()) || clip->GetVideoInfo().SampleType() & (sample_type | prefered_type)) {\n    // Sample type is already ok!\n    return clip;\n  } else\n    return new ConvertAudio(clip, prefered_type);\n}\n\nint __stdcall ConvertAudio::SetCacheHints(int cachehints, int frame_range) {\n  // We do pass cache requests upwards, to the next filter.\n  return child->SetCacheHints(cachehints, frame_range);\n}\n\nConvertAudio::ConvertAudio(PClip _clip, int _sample_type)\n    : GenericVideoFilter(_clip) {\n  dst_format = _sample_type;\n  src_format = vi.SampleType();\n  // Set up convertion matrix\n  src_bps = vi.BytesPerChannelSample(); // Store old size\n  vi.sample_type = dst_format;\n  tempbuffer_size = 0;\n\n  #define PAIR(src, dst) ((src << 16) | dst)\n  switch(PAIR(src_format, dst_format)) {\n    case PAIR(SAMPLE_INT32, SAMPLE_INT16): convert_c = convert32To16; break;\n    case PAIR(SAMPLE_INT16, SAMPLE_INT32): convert_c = convert16To32; break;\n    case PAIR(SAMPLE_INT32, SAMPLE_INT8 ): convert_c = convert32To8; break;\n    case PAIR(SAMPLE_INT8 , SAMPLE_INT32): convert_c = convert8To32; break;\n    case PAIR(SAMPLE_INT16, SAMPLE_INT8 ): convert_c = convert16To8; break;\n    case PAIR(SAMPLE_INT8 , SAMPLE_INT16): convert_c = convert8To16; break;\n    case PAIR(SAMPLE_FLOAT, SAMPLE_INT24): two_stage = true; // no-break;\n    case PAIR(SAMPLE_INT32, SAMPLE_INT24): convert_c = convert32To24; break;\n    case PAIR(SAMPLE_INT24, SAMPLE_FLOAT): two_stage = true; // no-break;\n    case PAIR(SAMPLE_INT24, SAMPLE_INT32): convert_c = convert24To32; break;\n    case PAIR(SAMPLE_INT24, SAMPLE_INT16): convert_c = convert24To16; break;\n    case PAIR(SAMPLE_INT16, SAMPLE_INT24): convert_c = convert16To24; break;\n    case PAIR(SAMPLE_INT24, SAMPLE_INT8 ): convert_c = convert24To8; break;\n    case PAIR(SAMPLE_INT8 , SAMPLE_INT24): convert_c = convert8To24; break;\n    case PAIR(SAMPLE_INT8 , SAMPLE_FLOAT): convert_c = convert8ToFLT; break;\n    case PAIR(SAMPLE_FLOAT, SAMPLE_INT8): convert_c = convertFLTTo8; break;\n    case PAIR(SAMPLE_INT16, SAMPLE_FLOAT): convert_c = convert16ToFLT; break;\n    case PAIR(SAMPLE_FLOAT, SAMPLE_INT16): convert_c = convertFLTTo16; break;\n    case PAIR(SAMPLE_INT32, SAMPLE_FLOAT): convert_c = convert32ToFLT; break;\n    case PAIR(SAMPLE_FLOAT, SAMPLE_INT32): convert_c = convertFLTTo32; break;\n  }\n  #ifdef INTEL_INTRINSICS\n    switch(PAIR(src_format, dst_format)) {\n      case PAIR(SAMPLE_INT32, SAMPLE_INT16): convert_sse2  = convert32To16_SSE2;  convert_avx2 = convert32To16_AVX2;  break;\n      case PAIR(SAMPLE_INT16, SAMPLE_INT32): convert_sse2  = convert16To32_SSE2;  convert_avx2 = convert16To32_AVX2;  break;\n      case PAIR(SAMPLE_INT32, SAMPLE_INT8 ): convert_sse2  = convert32To8_SSE2;   break;\n      case PAIR(SAMPLE_INT8 , SAMPLE_INT32): convert_sse2  = convert8To32_SSE2;   break;\n      case PAIR(SAMPLE_INT16, SAMPLE_INT8 ): convert_sse2  = convert16To8_SSE2;   break;\n      case PAIR(SAMPLE_INT8 , SAMPLE_INT16): convert_sse2  = convert8To16_SSE2;   break;\n      case PAIR(SAMPLE_FLOAT, SAMPLE_INT24):\n      case PAIR(SAMPLE_INT32, SAMPLE_INT24): convert_ssse3 = convert32To24_SSSE3; break;\n      case PAIR(SAMPLE_INT24, SAMPLE_FLOAT):\n      case PAIR(SAMPLE_INT24, SAMPLE_INT32): convert_ssse3 = convert24To32_SSSE3; break;\n      case PAIR(SAMPLE_INT24, SAMPLE_INT16): convert_ssse3 = convert24To16_SSSE3; break;\n      case PAIR(SAMPLE_INT16, SAMPLE_INT24): convert_ssse3 = convert16To24_SSSE3; break;\n      case PAIR(SAMPLE_INT24, SAMPLE_INT8 ): convert_ssse3 = convert24To8_SSSE3;  break;\n      case PAIR(SAMPLE_INT8 , SAMPLE_INT24): convert_ssse3 = convert8To24_SSSE3;  break;\n      case PAIR(SAMPLE_INT8 , SAMPLE_FLOAT): convert_sse41 = convert8ToFLT_SSE41; convert_avx2 = convert8ToFLT_AVX2; break;\n      case PAIR(SAMPLE_FLOAT, SAMPLE_INT8) : convert_sse2 = convertFLTTo8_SSE2; convert_avx2 = convertFLTTo8_AVX2; break;\n      case PAIR(SAMPLE_INT16, SAMPLE_FLOAT): convert_sse41 = convert16ToFLT_SSE41; convert_avx2 = convert16ToFLT_AVX2; break;\n      case PAIR(SAMPLE_FLOAT, SAMPLE_INT16): convert_sse2 = convertFLTTo16_SSE2; convert_avx2 = convertFLTTo16_AVX2; break;\n      case PAIR(SAMPLE_INT32, SAMPLE_FLOAT): convert_sse2  = convert32ToFLT_SSE2; convert_avx2 = convert32ToFLT_AVX2; break;\n      case PAIR(SAMPLE_FLOAT, SAMPLE_INT32): convert_sse41 = convertFLTTo32_SSE41; convert_avx2 = convertFLTTo32_AVX2; break;\n    }\n  #endif\n  #undef PAIR\n}\n\nConvertAudio::~ConvertAudio() {\n  if (tempbuffer_size) {\n    avs_free(tempbuffer);\n    tempbuffer_size = 0;\n  }\n}\n\nvoid __stdcall ConvertAudio::GetAudio(void *buf, int64_t start, int64_t count, IScriptEnvironment *env) {\n  if (src_format == dst_format) {\n    // Shouldn't happen, but just in case\n    child->GetAudio(buf, start, count, env);\n    return;\n  }\n\n  int channels = vi.AudioChannels();\n\n  if (tempbuffer_size < count) {\n    if (tempbuffer_size)\n      avs_free(tempbuffer);\n    tempbuffer = (char *)avs_malloc((int)count * src_bps * channels, 16);\n    tempbuffer_size = (int)count;\n  }\n\n  child->GetAudio(tempbuffer, start, count, env);\n\n  if (convert == nullptr) {\n    convert = convert_c;\n    convert_float = src_format == SAMPLE_FLOAT ? convertFLTTo32 : convert32ToFLT; // for two-stage\n    #ifdef INTEL_INTRINSICS\n      int cpu_flags = env->GetCPUFlags();\n      if ((cpu_flags & CPUF_SSE2)) {\n        if (convert_sse2)\n          convert = convert_sse2;\n        if (src_format != SAMPLE_FLOAT)\n          convert_float = convert32ToFLT_SSE2;\n      }\n      if ((cpu_flags & CPUF_SSSE3)) {\n        if (convert_ssse3)\n          convert = convert_ssse3;\n      }\n      if ((cpu_flags & CPUF_SSE4_1)) {\n        if (convert_sse41)\n          convert = convert_sse41;\n        if (src_format == SAMPLE_FLOAT)\n          convert_float = convertFLTTo32_SSE41;\n      }\n      if ((cpu_flags & CPUF_AVX2)) {\n        if (convert_avx2)\n          convert = convert_avx2;\n        convert_float = src_format == SAMPLE_FLOAT ? convertFLTTo32_AVX2 : convert32ToFLT_AVX2;\n      }\n    #endif\n  }\n\n  int sample_count = static_cast<int>(count * channels);\n\n  // Direct conversion cases\n  if (!two_stage) {\n    convert(tempbuffer, buf, sample_count);\n    return;\n  }\n\n  // Floating point cases\n  if (src_format == SAMPLE_FLOAT) {\n    convert_float(tempbuffer, tempbuffer, sample_count);\n    convert(tempbuffer, buf, sample_count);\n    return;\n  }\n\n  if (dst_format == SAMPLE_FLOAT) {\n    convert(tempbuffer, buf, sample_count);\n    convert_float(buf, buf, sample_count);\n    return;\n  }\n}\n"
  },
  {
    "path": "avs_core/convert/convert_audio.h",
    "content": "// Avisynth v2.5.  Copyright 2009 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Convert_Audio_H__\n#define __Convert_Audio_H__\n\n#include <avs/types.h>\n\n\n#define CONVERT_DECLARE(func) void (func)(void *, void *, int);\n\ntypedef CONVERT_DECLARE(*convert_proc);\n\nCONVERT_DECLARE(convert32To16);\nCONVERT_DECLARE(convert16To32);\nCONVERT_DECLARE(convert32To8);\nCONVERT_DECLARE(convert8To32);\nCONVERT_DECLARE(convert16To8);\nCONVERT_DECLARE(convert8To16);\nCONVERT_DECLARE(convert32To24);\nCONVERT_DECLARE(convert24To32);\nCONVERT_DECLARE(convert24To16);\nCONVERT_DECLARE(convert16To24);\nCONVERT_DECLARE(convert24To8);\nCONVERT_DECLARE(convert8To24);\nCONVERT_DECLARE(convert8ToFLT);\nCONVERT_DECLARE(convertFLTTo8);\nCONVERT_DECLARE(convert16ToFLT);\nCONVERT_DECLARE(convertFLTTo16);\nCONVERT_DECLARE(convert32ToFLT);\nCONVERT_DECLARE(convertFLTTo32);\n\n#ifdef INTEL_INTRINSICS\n  CONVERT_DECLARE(convert32To16_SSE2);\n  CONVERT_DECLARE(convert16To32_SSE2);\n  CONVERT_DECLARE(convert32To8_SSE2);\n  CONVERT_DECLARE(convert8To32_SSE2);\n  CONVERT_DECLARE(convert16To8_SSE2);\n  CONVERT_DECLARE(convert8To16_SSE2);\n  CONVERT_DECLARE(convert32To24_SSSE3);\n  CONVERT_DECLARE(convert24To32_SSSE3);\n  CONVERT_DECLARE(convert24To16_SSSE3);\n  CONVERT_DECLARE(convert16To24_SSSE3);\n  CONVERT_DECLARE(convert24To8_SSSE3);\n  CONVERT_DECLARE(convert8To24_SSSE3);\n  CONVERT_DECLARE(convert8ToFLT_SSE41);\n  CONVERT_DECLARE(convertFLTTo8_SSE2);\n  CONVERT_DECLARE(convert16ToFLT_SSE41);\n  CONVERT_DECLARE(convertFLTTo16_SSE2);\n  CONVERT_DECLARE(convert32ToFLT_SSE2);\n  CONVERT_DECLARE(convertFLTTo32_SSE41);\n\n  CONVERT_DECLARE(convert32To16_AVX2);\n  CONVERT_DECLARE(convert16To32_AVX2);\n  CONVERT_DECLARE(convert8ToFLT_AVX2);\n  CONVERT_DECLARE(convertFLTTo8_AVX2);\n  CONVERT_DECLARE(convert16ToFLT_AVX2);\n  CONVERT_DECLARE(convertFLTTo16_AVX2);\n  CONVERT_DECLARE(convert32ToFLT_AVX2);\n  CONVERT_DECLARE(convertFLTTo32_AVX2);\n#endif\n\n#undef CONVERT_DECLARE\n\nclass ConvertAudio : public GenericVideoFilter\n/**\n  * Helper class to convert audio to any format\n **/\n{\npublic:\n  ConvertAudio(PClip _clip, int prefered_format);\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env);\n  int __stdcall SetCacheHints(int cachehints,int frame_range);  // We do pass cache requests upwards, to the cache!\n\n  static PClip Create(PClip clip, int sample_type, int prefered_type);\n  static AVSValue __cdecl Create_float(AVSValue args, void*, IScriptEnvironment*);\n  static AVSValue __cdecl Create_32bit(AVSValue args, void*, IScriptEnvironment*);\n  static AVSValue __cdecl Create_24bit(AVSValue args, void*, IScriptEnvironment*);\n  static AVSValue __cdecl Create_16bit(AVSValue args, void*, IScriptEnvironment*);\n  static AVSValue __cdecl Create_8bit (AVSValue args, void*, IScriptEnvironment*);\n  static AVSValue __cdecl Create_Any  (AVSValue args, void*, IScriptEnvironment*);\n  virtual ~ConvertAudio();\n\nprivate:\n  int src_format;\n  int dst_format;\n  int src_bps;\n  int tempbuffer_size {0};\n  char *tempbuffer {nullptr};\n\n  bool two_stage {false};\n  convert_proc convert {nullptr};\n  convert_proc convert_float {nullptr};\n  convert_proc convert_c {nullptr};\n#ifdef INTEL_INTRINSICS\n  convert_proc convert_sse2 {nullptr};\n  convert_proc convert_ssse3 {nullptr};\n  convert_proc convert_sse41 { nullptr };\n  convert_proc convert_avx2 {nullptr};\n#endif\n\n};\n\n#endif //__Convert_Audio_H__\n"
  },
  {
    "path": "avs_core/convert/convert_audio_c.cpp",
    "content": "// Avisynth+\n// https://avs-plus.net\n//\n// This file is part of Avisynth+ which is released under GPL2+ with exception.\n\n// Convert Audio helper functions (Pure C)\n// Copyright (c) 2020 Xinyue Lu, (c) 2021 pinterf\n\n#include <avs/types.h>\n\n/* Supported fast route conversions:\n *\n * |    From: | U 8 | S16 | S24 | S32 | FLT |\n * | To:      |     |     |     |     |     |\n * |  U 8     |  -  | CS  | CS  | CS  | CSA |\n * |  S16     | CS  |  -  | CS  | CSA | CSA |\n * |  S24     | CS  | CS  |  -  | CS  |     |\n * |  S32     | CS  | CSA | CS  |  -  | CSA |\n * |  FLT     | CSA | CSA |     | CSA |  -  |\n * \n * * C = C, S = SSE2+, A = AVX2\n */\n\n/*\n 8 bit: unsigned (middle point 128)\n 16,24,32 bit: signed\n 32 bit float: -1.0 .. 1.0\n\n Assymetric range considerations.\n\n Android: It is implementation dependent whether the positive maximum of 1.0 is included in the interval\n when converting to integer representation\n \n Method 1 (e.g. Android): smallest number is full scale, 1.0 is clamped to 1.0 minus one LSB\n   -0x8000 - 0x7FFF is valid, nominally +1.0 (top of range) is not part of the range [-1.0..1.0)\n Method 2: largest number is full scale\n   -0x7FFF - 0x7FFF, while -8000 exceeds lower limit. [-1.0..1.0] + smallest value is theoretically invalid\n\n*/\n\n// until 3.6.1: S16 = (S32 + 0x8000) >> 16   (plain round-before shift)\n// Actual: S16 = S32 >> 16\nvoid convert32To16(void *inbuf, void *outbuf, int count) {\n  auto in16 = reinterpret_cast<int16_t *>(inbuf);\n  auto out = reinterpret_cast<int16_t *>(outbuf);\n\n  for (int i = 0; i < count; i++)\n    out[i] = in16[i * 2 + 1];\n}\n\n// until 3.6.1: S32 = (S16 << 16) + (unsigned short)(S16 + 32768)\n//              0x7fff -> 0x7fffffff, 0x8000 -> 0x80000000\n// Actual: S32 = S16 << 16\nvoid convert16To32(void *inbuf, void *outbuf, int count) {\n  auto in = reinterpret_cast<int16_t *>(inbuf);\n  auto out16 = reinterpret_cast<int16_t *>(outbuf);\n\n  for (int i = 0; i < count; i++) {\n    out16[i * 2] = 0;\n    out16[i * 2 + 1] = in[i];\n  }\n}\n\nvoid convert32To8(void* inbuf, void* outbuf, int count) {\n  auto in8 = reinterpret_cast<int8_t*>(inbuf);\n  auto out = reinterpret_cast<uint8_t*>(outbuf);\n\n  for (int i = 0; i < count; i++)\n    out[i] = in8[i * 4 + 3] + 128;\n}\n\nvoid convert8To32(void *inbuf, void *outbuf, int count) {\n  auto in = reinterpret_cast<uint8_t *>(inbuf);\n  auto out8 = reinterpret_cast<int8_t *>(outbuf);\n\n  for (int i = 0; i < count; i++) {\n    out8[i * 4] = 0;\n    out8[i * 4 + 1] = 0;\n    out8[i * 4 + 2] = 0;\n    out8[i * 4 + 3] = in[i] - 128;\n  }\n}\n\nvoid convert16To8(void *inbuf, void *outbuf, int count) {\n  auto in8 = reinterpret_cast<int8_t *>(inbuf);\n  auto out = reinterpret_cast<uint8_t *>(outbuf);\n\n  for (int i = 0; i < count; i++)\n    out[i] = in8[i * 2 + 1] + 128;\n}\n\n// until 3.6.1: S16 = (S8 << 8) + (unsigned short)(S8 + 128)\n//              This make 0x7f(255-128) -> 0x7fff & 0x80(0-128) -> 0x8000\n// Actual: S16 = (U8-128) << 8\nvoid convert8To16(void *inbuf, void *outbuf, int count) {\n  auto in = reinterpret_cast<uint8_t *>(inbuf);\n  auto out8 = reinterpret_cast<int8_t *>(outbuf);\n\n  for (int i = 0; i < count; i++) {\n    out8[i * 2] = 0;\n    out8[i * 2 + 1] = in[i] - 128;\n  }\n}\n\nvoid convert32To24(void *inbuf, void *outbuf, int count) {\n  auto in8 = reinterpret_cast<int8_t *>(inbuf);\n  auto out8 = reinterpret_cast<int8_t *>(outbuf);\n\n  for (int i = 0; i < count; i++) {\n    out8[i * 3 + 0] = in8[i * 4 + 1];\n    out8[i * 3 + 1] = in8[i * 4 + 2];\n    out8[i * 3 + 2] = in8[i * 4 + 3];\n  }\n}\n\nvoid convert24To32(void *inbuf, void *outbuf, int count) {\n  auto in8 = reinterpret_cast<int8_t *>(inbuf);\n  auto out8 = reinterpret_cast<int8_t *>(outbuf);\n\n  for (int i = 0; i < count; i++) {\n    out8[i * 4] = 0;\n    out8[i * 4 + 1] = in8[i * 3 + 0];\n    out8[i * 4 + 2] = in8[i * 3 + 1];\n    out8[i * 4 + 3] = in8[i * 3 + 2];\n  }\n}\n\nvoid convert24To16(void *inbuf, void *outbuf, int count) {\n  auto in8 = reinterpret_cast<int8_t *>(inbuf);\n  auto out8 = reinterpret_cast<int8_t *>(outbuf);\n\n  for (int i = 0; i < count; i++) {\n    out8[i * 2 + 0] = in8[i * 3 + 1];\n    out8[i * 2 + 1] = in8[i * 3 + 2];\n  }\n}\n\nvoid convert16To24(void *inbuf, void *outbuf, int count) {\n  auto in8 = reinterpret_cast<int8_t *>(inbuf);\n  auto out8 = reinterpret_cast<int8_t *>(outbuf);\n\n  for (int i = 0; i < count; i++) {\n    out8[i * 3] = 0;\n    out8[i * 3 + 1] = in8[i * 2 + 0];\n    out8[i * 3 + 2] = in8[i * 2 + 1];\n  }\n}\n\nvoid convert24To8(void *inbuf, void *outbuf, int count) {\n  auto in8 = reinterpret_cast<int8_t *>(inbuf);\n  auto out = reinterpret_cast<uint8_t *>(outbuf);\n\n  for (int i = 0; i < count; i++)\n    out[i] = in8[i * 3 + 2] + 128;\n}\n\nvoid convert8To24(void *inbuf, void *outbuf, int count) {\n  auto in = reinterpret_cast<uint8_t *>(inbuf);\n  auto out8 = reinterpret_cast<int8_t *>(outbuf);\n\n  for (int i = 0; i < count; i++) {\n    out8[i * 3] = 0;\n    out8[i * 3 + 1] = 0;\n    out8[i * 3 + 2] = in[i] - 128;\n  }\n}\n\nvoid convert8ToFLT(void* inbuf, void* outbuf, int count) {\n  auto in = reinterpret_cast<uint8_t*>(inbuf);\n  auto out = reinterpret_cast<SFLOAT*>(outbuf);\n  constexpr float divisor = 1.0f / 128.f; // 1 << 7\n\n  for (int i = 0; i < count; i++)\n    out[i] = (in[i] - 128) * divisor;\n}\n\nvoid convertFLTTo8(void* inbuf, void* outbuf, int count) {\n  auto in = reinterpret_cast<SFLOAT*>(inbuf);\n  auto out = reinterpret_cast<uint8_t*>(outbuf);\n  constexpr float multiplier = 128.f;\n  constexpr float max8 = 127.f;\n  constexpr float min8 = -128.f;\n\n  for (int i = 0; i < count; i++) {\n    float val = in[i] * multiplier;\n    uint8_t result;\n    if (val >= max8) result = 255;\n    else if (val <= min8) result = 0;\n    else result = static_cast<int8_t>(val) + 128;\n    out[i] = result;\n  }\n}\n\nvoid convert16ToFLT(void* inbuf, void* outbuf, int count) {\n  auto in = reinterpret_cast<int16_t*>(inbuf);\n  auto out = reinterpret_cast<SFLOAT*>(outbuf);\n  constexpr float divisor = 1.0f / 32768.f; // 1 << 15\n\n  for (int i = 0; i < count; i++)\n    out[i] = in[i] * divisor;\n}\n\nvoid convertFLTTo16(void* inbuf, void* outbuf, int count) {\n  auto in = reinterpret_cast<SFLOAT*>(inbuf);\n  auto out = reinterpret_cast<int16_t*>(outbuf);\n  constexpr float multiplier = 32768.f;\n  constexpr float max16 = 32767.f;\n  constexpr float min16 = -32768.f;\n\n  for (int i = 0; i < count; i++) {\n    float val = in[i] * multiplier;\n    int16_t result;\n    if (val >= max16) result = 32767;\n    else if (val <= min16) result = (int16_t)-32768;\n    else result = static_cast<int16_t>(val);\n    out[i] = result;\n  }\n}\n\n// not yet used directly, 24 bit has 32 bit 2nd stage\nvoid convert24ToFLT(void* inbuf, void* outbuf, int count) {\n  auto in = reinterpret_cast<uint8_t*>(inbuf);\n  auto out = reinterpret_cast<SFLOAT*>(outbuf);\n  constexpr float divisor = 1.0f / 8388608.f; // 1 << 23\n\n  for (int i = 0; i < count; i++)\n    out[i] = (in[i * 3] | (in[i * 3 + 1] << 8) | (in[i * 3 + 2] << 16)) * divisor;\n}\n\n// not yet used directly, 24 bit has 32 bit 2nd stage\nvoid convertFLTTo24(void* inbuf, void* outbuf, int count) {\n  auto in = reinterpret_cast<SFLOAT*>(inbuf);\n  auto out = reinterpret_cast<uint8_t*>(outbuf);\n  constexpr float multiplier = 8388608.f;\n  constexpr float max24 = 8388607.f;\n  constexpr float min24 = -8388608.f;\n\n  for (int i = 0; i < count; i++) {\n    float val = in[i] * multiplier;\n    int32_t result;\n    if (val >= max24) result = 0x7FFFFF; // 8388607\n    else if (val <= min24) result = 0x800000; // -8388608\n    else result = static_cast<int32_t>(val);\n    out[i * 3 + 0] = result & 0xFF;\n    out[i * 3 + 1] = (result >> 8) & 0xFF;\n    out[i * 3 + 2] = (result >> 16) & 0xFF;\n  }\n}\n\n// note for 32 bit conversions: 32 bit integer cannot be represented in float\n// 2147483647.0f is 2147483648.0f in reality\n\nvoid convert32ToFLT(void *inbuf, void *outbuf, int count) {\n  auto in = reinterpret_cast<int32_t *>(inbuf);\n  auto out = reinterpret_cast<SFLOAT *>(outbuf);\n  constexpr float divisor = 1.0f/2147483648.0f;\n\n  for (int i = 0; i < count; i++)\n    out[i] = in[i] * divisor;\n}\n\nvoid convertFLTTo32(void *inbuf, void *outbuf, int count) {\n  auto in = reinterpret_cast<SFLOAT *>(inbuf);\n  auto out = reinterpret_cast<int32_t *>(outbuf);\n  constexpr float multiplier = 2147483648.0f;\n  constexpr float max32 = 2147483647.0f;\n  constexpr float min32 = -2147483648.0f;\n\n  for (int i = 0; i < count; i++) {\n    float val = in[i] * multiplier;\n    int32_t result;\n    if (val >= max32) result = 0x7FFFFFFF; // 2147483647\n    else if (val <= min32) result = 0x80000000; // -2147483648\n    else result = static_cast<int32_t>(val);\n    out[i] = result;\n  }\n}\n"
  },
  {
    "path": "avs_core/convert/convert_bits.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002-2009 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include \"convert_bits.h\"\n#ifdef INTEL_INTRINSICS\n#include \"intel/convert_bits_sse.h\"\n#include \"intel/convert_bits_avx2.h\"\n#endif\n#include \"convert_helper.h\"\n\n#include <avs/alignment.h>\n#include <avs/minmax.h>\n#include <avs/config.h>\n#include <tuple>\n#include <map>\n#include <algorithm>\n#include <vector>\n\n#ifdef AVS_WINDOWS\n#include <avs/win.h>\n#else\n#include <avs/posix.h>\n#endif\n\n// for odd dither bit differences, we still take even size but\n// correction values are halved (shifted by 1)\n\n// repeated 8x for sse size 16\nconst BYTE dither2x2a_data[4] = {\n  0, 1,\n  1, 0,\n};\n// cycle: 2\nalignas(16) const BYTE dither2x2a_data_sse2[2 * 16] = {\n  0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,\n  1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0\n};\n\n// e.g. 10->8 bits\n// repeated 8x for sse size 16\nconst BYTE dither2x2_data[4] = {\n  0, 2,\n  3, 1,\n};\n// cycle: 2\nalignas(16) const BYTE dither2x2_data_sse2[2 * 16] = {\n  0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2,\n  3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1\n};\n\n// e.g. 8->5 bits\nconst BYTE dither4x4a_data[16] = {\n    0,  4,  1,  5,\n    6,  2,  7,  3,\n    1,  5,  0,  4,\n    7,  3,  6,  2\n};\n// cycle: 4\nalignas(16) const BYTE dither4x4a_data_sse2[4 * 16] = {\n    0,  4,  1,  5,  0,  4,  1,  5,  0,  4,  1,  5,  0,  4,  1,  5,\n    6,  2,  7,  3,  6,  2,  7,  3,  6,  2,  7,  3,  6,  2,  7,  3,\n    1,  5,  0,  4,  1,  5,  0,  4,  1,  5,  0,  4,  1,  5,  0,  4,\n    7,  3,  6,  2,  7,  3,  6,  2,  7,  3,  6,  2,  7,  3,  6,  2,\n};\n\n// e.g. 12->8 bits\nconst BYTE dither4x4_data[16] = {\n    0,  8,  2, 10,\n  12,  4, 14,  6,\n    3, 11,  1,  9,\n  15,  7, 13,  5\n};\n// cycle: 4\nalignas(16) const BYTE dither4x4_data_sse2[4 * 16] = {\n    0,  8,  2, 10,  0,  8,  2, 10,  0,  8,  2, 10,  0,  8,  2, 10,\n  12,  4, 14,  6, 12,  4, 14,  6, 12,  4, 14,  6, 12,  4, 14,  6,\n    3, 11,  1,  9,  3, 11,  1,  9,  3, 11,  1,  9,  3, 11,  1,  9,\n  15,  7, 13,  5, 15,  7, 13,  5, 15,  7, 13,  5, 15,  7, 13,  5\n};\n\n// e.g. 14->9 bits\nextern const BYTE dither8x8a_data[8][8] = {\n  { 0, 16,  4, 20,  1, 17,  5, 21}, /* 8x8 Bayer ordered dithering pattern */\n  {24,  8, 28, 12, 25,  9, 29, 13},\n  { 6, 22,  2, 18,  7, 23,  3, 19},\n  {30, 14, 26, 10, 31, 15, 27, 11},\n  { 1, 17,  5, 21,  0, 16,  4, 20},\n  {25,  9, 29, 13, 24,  8, 28, 12},\n  { 7, 23,  3, 19,  6, 22,  2, 18},\n  {31, 15, 27, 11, 30, 14, 26, 10}\n};\n// cycle: 8\nalignas(16) const BYTE dither8x8a_data_sse2[8][16] = {\n  {  0, 16,  4, 20,  1, 17,  5, 21,  0, 16,  4, 20,  1, 17,  5, 21 },\n  { 24,  8, 28, 12, 25,  9, 29, 13, 24,  8, 28, 12, 25,  9, 29, 13 },\n  {  6, 22,  2, 18,  7, 23,  3, 19,  6, 22,  2, 18,  7, 23,  3, 19 },\n  { 30, 14, 26, 10, 31, 15, 27, 11, 30, 14, 26, 10, 31, 15, 27, 11 },\n  {  1, 17,  5, 21,  0, 16,  4, 20,  1, 17,  5, 21,  0, 16,  4, 20 },\n  { 25,  9, 29, 13, 24,  8, 28, 12, 25,  9, 29, 13, 24,  8, 28, 12 },\n  {  7, 23,  3, 19,  6, 22,  2, 18,  7, 23,  3, 19,  6, 22,  2, 18 },\n  { 31, 15, 27, 11, 30, 14, 26, 10, 31, 15, 27, 11, 30, 14, 26, 10 }\n};\n\n// e.g. 14->8 bits\nextern const BYTE dither8x8_data[8][8] = {\n  { 0, 32,  8, 40,  2, 34, 10, 42},\n  {48, 16, 56, 24, 50, 18, 58, 26},\n  {12, 44,  4, 36, 14, 46,  6, 38},\n  {60, 28, 52, 20, 62, 30, 54, 22},\n  { 3, 35, 11, 43,  1, 33,  9, 41},\n  {51, 19, 59, 27, 49, 17, 57, 25},\n  {15, 47,  7, 39, 13, 45,  5, 37},\n  {63, 31, 55, 23, 61, 29, 53, 21}\n};\n// cycle: 8\nalignas(16) const BYTE dither8x8_data_sse2[8][16] = {\n  {  0, 32,  8, 40,  2, 34, 10, 42,  0, 32,  8, 40,  2, 34, 10, 42 },\n  { 48, 16, 56, 24, 50, 18, 58, 26, 48, 16, 56, 24, 50, 18, 58, 26 },\n  { 12, 44,  4, 36, 14, 46,  6, 38, 12, 44,  4, 36, 14, 46,  6, 38 },\n  { 60, 28, 52, 20, 62, 30, 54, 22, 60, 28, 52, 20, 62, 30, 54, 22 },\n  {  3, 35, 11, 43,  1, 33,  9, 41,  3, 35, 11, 43,  1, 33,  9, 41 },\n  { 51, 19, 59, 27, 49, 17, 57, 25, 51, 19, 59, 27, 49, 17, 57, 25 },\n  { 15, 47,  7, 39, 13, 45,  5, 37, 15, 47,  7, 39, 13, 45,  5, 37 },\n  { 63, 31, 55, 23, 61, 29, 53, 21, 63, 31, 55, 23, 61, 29, 53, 21 }\n};\n\n// e.g. 16->9 or 8->1 bits\n// cycle: 16x. No special 16 byte sse2\nalignas(16) const BYTE dither16x16a_data[16][16] = {\n  {   0, 96, 24,120,  6,102, 30,126,  1, 97, 25,121,  7,103, 31,127 },\n  {  64, 32, 88, 56, 70, 38, 94, 62, 65, 33, 89, 57, 71, 39, 95, 63 },\n  {  16,112,  8,104, 22,118, 14,110, 17,113,  9,105, 23,119, 15,111 },\n  {  80, 48, 72, 40, 86, 54, 78, 46, 81, 49, 73, 41, 87, 55, 79, 47 },\n  {   4,100, 28,124,  2, 98, 26,122,  5,101, 29,125,  3, 99, 27,123 },\n  {  68, 36, 92, 60, 66, 34, 90, 58, 69, 37, 93, 61, 67, 35, 91, 59 },\n  {  20,116, 12,108, 18,114, 10,106, 21,117, 13,109, 19,115, 11,107 },\n  {  84, 52, 76, 44, 82, 50, 74, 42, 85, 53, 77, 45, 83, 51, 75, 43 },\n  {   1, 97, 25,121,  7,103, 31,127,  0, 96, 24,120,  6,102, 30,126 },\n  {  75, 33, 89, 57, 71, 39, 95, 63, 64, 32, 88, 56, 70, 38, 94, 62 },\n  {  17,113,  9,105, 23,119, 15,111, 16,112,  8,104, 22,118, 14,110 },\n  {  81, 49, 73, 41, 87, 55, 79, 47, 80, 48, 72, 40, 86, 54, 78, 46 },\n  {   5,101, 29,125,  3, 99, 27,123,  4,100, 28,124,  2, 98, 26,122 },\n  {  69, 37, 93, 61, 67, 35, 91, 59, 68, 36, 92, 60, 66, 34, 90, 58 },\n  {  21,117, 13,109, 19,115, 11,107, 20,116, 12,108, 18,114, 10,106 },\n  {  85, 53, 77, 45, 83, 51, 75, 43, 84, 52, 76, 44, 82, 50, 74, 42 }\n};\n\n// 16->8\n// cycle: 16x. No special 16 byte sse2\nalignas(16) const BYTE dither16x16_data[16][16] = {\n  {   0,192, 48,240, 12,204, 60,252,  3,195, 51,243, 15,207, 63,255 },\n  { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },\n  {  32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },\n  { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },\n  {   8,200, 56,248,  4,196, 52,244, 11,203, 59,251,  7,199, 55,247 },\n  { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },\n  {  40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },\n  { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },\n  {   2,194, 50,242, 14,206, 62,254,  1,193, 49,241, 13,205, 61,253 },\n  { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },\n  {  34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },\n  { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },\n  {  10,202, 58,250,  6,198, 54,246,  9,201, 57,249,  5,197, 53,245 },\n  { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },\n  {  42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },\n  { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }\n};\n\n\ntemplate<typename pixel_t_s, typename pixel_t_d, bool chroma, bool fulls, bool fulld, bool TEMPLATE_NEED_BACKSCALE, bool TEMPLATE_LOW_DITHER_BITDEPTH>\nstatic void do_convert_ordered_dither_uint_c(const BYTE* srcp8, BYTE* dstp8, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth)\n{\n  const pixel_t_s* srcp = reinterpret_cast<const pixel_t_s*>(srcp8);\n  pixel_t_d* dstp = reinterpret_cast<pixel_t_d*>(dstp8);\n  dst_pitch = dst_pitch / sizeof(pixel_t_d);\n\n  src_pitch = src_pitch / sizeof(pixel_t_s);\n  const int src_width = src_rowsize / sizeof(pixel_t_s);\n\n  // helps compiler optimization\n  if constexpr (sizeof(pixel_t_s) == 1)\n    source_bitdepth = 8;\n  if constexpr (sizeof(pixel_t_d) == 1) {\n    target_bitdepth = 8;\n    if (!TEMPLATE_NEED_BACKSCALE) {\n      dither_target_bitdepth = 8;\n    }\n  }\n\n  const int max_pixel_value_target = (1 << target_bitdepth) - 1;\n  const int max_pixel_value_dithered = (1 << dither_target_bitdepth) - 1;\n  // precheck ensures:\n  // target_bitdepth >= dither_target_bitdepth\n  // source_bitdepth - dither_target_bitdepth <= 8 (max precalculated table is 16x16)\n  const bool odd_diff = (source_bitdepth - dither_target_bitdepth) & 1;\n  const int dither_bit_diff = (source_bitdepth - dither_target_bitdepth);\n  const int dither_order = (dither_bit_diff + 1) / 2;\n  const int dither_mask = (1 << dither_order) - 1; // 9,10=2  11,12=4  13,14=8  15,16=16\n  // 10->8: 0x01 (2x2)\n  // 11->8: 0x03 (4x4)\n  // 12->8: 0x03 (4x4)\n  // 14->8: 0x07 (8x8)\n  // 16->8: 0x0F (16x16)\n  const BYTE* matrix;\n  switch (dither_order) {\n  case 1: matrix = reinterpret_cast<const BYTE*>(odd_diff ? dither2x2a_data : dither2x2_data); break;\n  case 2: matrix = reinterpret_cast<const BYTE*>(odd_diff ? dither4x4a_data : dither4x4_data); break;\n  case 3: matrix = reinterpret_cast<const BYTE*>(odd_diff ? dither8x8a_data : dither8x8_data); break;\n  case 4: matrix = reinterpret_cast<const BYTE*>(odd_diff ? dither16x16a_data : dither16x16_data); break;\n  default: return; // n/a\n  }\n\n  const int bitdiff_between_dither_and_target = target_bitdepth - dither_target_bitdepth;\n  assert(TEMPLATE_NEED_BACKSCALE == (target_bitdepth != dither_target_bitdepth));  // dither to x, target to y\n\n  assert(TEMPLATE_LOW_DITHER_BITDEPTH == (dither_target_bitdepth < 8));\n  // e.g. instead of 0,1 => -0.5,+0.5;  0,1,2,3 => -1.5,-0.5,0.5,1.5\n  const float half_maxcorr_value = ((1 << dither_bit_diff) - 1) / 2.0f;\n\n  const int source_max = (1 << source_bitdepth) - 1;\n  //-----------------------\n  // When calculating src_pixel, src and dst are of the same bit depth\n  bits_conv_constants d;\n  get_bits_conv_constants(d, chroma, fulls, fulld, source_bitdepth, source_bitdepth);\n\n  auto dst_offset_plus_round = d.dst_offset + 0.5f;\n  constexpr auto src_pixel_min = 0;\n  const auto src_pixel_max = source_max;\n  const float mul_factor_backfromlowdither = (float)max_pixel_value_target / max_pixel_value_dithered;\n  //-----------------------\n\n  for (int y = 0; y < src_height; y++)\n  {\n    int _y = (y & dither_mask) << dither_order; // ordered dither\n    for (int x = 0; x < src_width; x++)\n    {\n      const int corr = matrix[_y | (x & dither_mask)];\n\n      int src_pixel = srcp[x];\n\n      if constexpr(fulls != fulld) {\n        const float val = (srcp[x] - d.src_offset_i) * d.mul_factor + dst_offset_plus_round;\n        src_pixel = clamp((int)val, src_pixel_min, src_pixel_max);\n      }\n\n      int new_pixel;\n      if (TEMPLATE_LOW_DITHER_BITDEPTH) {\n        // accurate dither: +/-\n        // accurately positioned to the center\n        const float corr_f = corr - half_maxcorr_value;\n        new_pixel = (int)(src_pixel + corr_f) >> dither_bit_diff;\n      }\n      else\n        new_pixel = ((src_pixel + corr) >> dither_bit_diff);\n\n      // scale back to the required bit depth\n      if constexpr (TEMPLATE_NEED_BACKSCALE) { // dither to x, target to y\n        new_pixel = min(new_pixel, max_pixel_value_dithered);\n        // Interesting problem of dither_bits==1 (or in general at small dither_bits)\n        // After simple slli 0,1 becomes 0,128, we'd expect 0,255 instead. So we make cosmetics.\n        if (TEMPLATE_LOW_DITHER_BITDEPTH) {\n          new_pixel = (int)(new_pixel * mul_factor_backfromlowdither + 0.5f);\n        }\n        else {\n          new_pixel = new_pixel << bitdiff_between_dither_and_target;\n        }\n        // dither_bits\n        // 1            0,1     => 0,128        => 0,255\n        // 2            0,1,2,3 => 0,64,128,192 => 0,?,?,255\n        // 3            0,...,7 => 0,32,...,224 => 0,?,?,255\n        // 4            0,..,15 => 0,16,...,240 => 0,?,?,255\n        // 5            0,..,31 => 0,8,....,248 => 0,?,?,255\n        // 6            0,..,63 => 0,4,....,252 => 0,?,?,255\n        // 7            0,.,127 => 0,2.  ..,254 => 0,?,?,255\n      }\n      dstp[x] = (pixel_t_d)(max(min((int)new_pixel, max_pixel_value_target),0));\n    }\n    dstp += dst_pitch;\n    srcp += src_pitch;\n  }\n}\n\ntemplate<typename pixel_t_s, typename pixel_t_d, bool chroma, bool fulls, bool fulld>\nstatic void convert_ordered_dither_uint_c(const BYTE* srcp8, BYTE* dstp8, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth)\n{\n  const bool need_backscale = target_bitdepth != dither_target_bitdepth; // dither to x, target to y\n  const bool low_dither_bitdepth = dither_target_bitdepth < 8; // 1-7 bits dither targets, need_backscale is always true, since 8 bit format is the minimum\n  if (need_backscale) {\n    if (low_dither_bitdepth)\n      do_convert_ordered_dither_uint_c<pixel_t_s, pixel_t_d, chroma, fulls, fulld, true, true>(srcp8, dstp8, src_rowsize, src_height, src_pitch, dst_pitch, source_bitdepth, target_bitdepth, dither_target_bitdepth);\n    else\n      do_convert_ordered_dither_uint_c<pixel_t_s, pixel_t_d, chroma, fulls, fulld, true, false>(srcp8, dstp8, src_rowsize, src_height, src_pitch, dst_pitch, source_bitdepth, target_bitdepth, dither_target_bitdepth);\n  }\n  else {\n    do_convert_ordered_dither_uint_c<pixel_t_s, pixel_t_d, chroma, fulls, fulld, false, false>(srcp8, dstp8, src_rowsize, src_height, src_pitch, dst_pitch, source_bitdepth, target_bitdepth, dither_target_bitdepth);\n  }\n}\n\n// idea borrowed from fmtConv\n#define FS_OPTIMIZED_SERPENTINE_COEF\n\ntemplate<int direction>\nstatic AVS_FORCEINLINE void diffuse_floyd(int err, int &nextError, int *error_ptr)\n{\n#if defined (FS_OPTIMIZED_SERPENTINE_COEF)\n  const int      e1 = 0;\n  const int      e3 = (err * 4 + 8) >> 4;\n#else\n  const int      e1 = (err + 8) >> 4;\n  const int      e3 = (err * 3 + 8) >> 4;\n#endif\n  const int      e5 = (err * 5 + 8) >> 4;\n  const int      e7 = err - e1 - e3 - e5;\n\n  nextError = error_ptr[direction];\n  error_ptr[-direction] += e3;\n  error_ptr[0] += e5;\n  error_ptr[direction] = e1;\n  nextError += e7;\n}\n\n#if 0\ntemplate<int direction>\nstatic AVS_FORCEINLINE void diffuse_floyd_f(float err, float& nextError, float* error_ptr)\n{\n#if defined (FS_OPTIMIZED_SERPENTINE_COEF)\n  const float    e1 = 0;\n  const float    e3 = err * (4.0f / 16);\n#else\n  const float    e1 = err * (1.0f / 16);\n  const float    e3 = err * (3.0f / 16);\n#endif\n  const float    e5 = err * (5.0f / 16);\n  const float    e7 = err * (7.0f / 16);\n\n  nextError = error_ptr[direction];\n  error_ptr[-direction] += e3;\n  error_ptr[0] += e5;\n  error_ptr[direction] = e1;\n  nextError += e7;\n}\n#endif\n\n// optimization helper: TEMPLATE_DITHER_BIT_DIFF if not <0 then hold value for frequently used differences from 16->8\n// 2nd helper: TEMPLATE_LOW_DITHER_BITDEPTH\n// 3rd helper: source_bitdepth_special\ntemplate<typename pixel_t_s, typename pixel_t_d, bool chroma, bool fulls, bool fulld, int TEMPLATE_DITHER_BIT_DIFF, bool TEMPLATE_LOW_DITHER_BITDEPTH, int SOURCE_BITDEPTH_SPECIAL>\nstatic void do_convert_uint_floyd_c(const BYTE* srcp8, BYTE* dstp8, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth)\n{\n  if constexpr (SOURCE_BITDEPTH_SPECIAL > 0) {\n    // called with >0 values only for special cases like 16 to 8, 16 to 10 and 10 to 8\n    // Hugely helps the optimizers\n    source_bitdepth = SOURCE_BITDEPTH_SPECIAL;\n  }\n  if constexpr (TEMPLATE_DITHER_BIT_DIFF > 0) {\n    assert(TEMPLATE_DITHER_BIT_DIFF == (source_bitdepth - dither_target_bitdepth));\n    assert(target_bitdepth == dither_target_bitdepth);\n    dither_target_bitdepth = source_bitdepth - TEMPLATE_DITHER_BIT_DIFF;\n    target_bitdepth = dither_target_bitdepth;\n    // seems that direct shift with known constant bits is really quicker than shift by 'cl'. \n    // Dithering from 16 to 10 bit: 109 vs 101 fps\n    // PF note: experienced the same with SIMD _mm_srl and _mm_srli in the other bit converter\n  }\n  const int DITHER_BIT_DIFF = TEMPLATE_DITHER_BIT_DIFF > 0 ? TEMPLATE_DITHER_BIT_DIFF : (source_bitdepth - dither_target_bitdepth);\n  assert(TEMPLATE_LOW_DITHER_BITDEPTH == (dither_target_bitdepth < 8)); // must match with dispatcher\n\n  const pixel_t_s* srcp = reinterpret_cast<const pixel_t_s*>(srcp8);\n  src_pitch = src_pitch / sizeof(pixel_t_s);\n  const int src_width = src_rowsize / sizeof(pixel_t_s);\n\n  pixel_t_d* dstp = reinterpret_cast<pixel_t_d*>(dstp8);\n  dst_pitch = dst_pitch / sizeof(pixel_t_d);\n\n  // perhaps helps compiler to optimize\n  if constexpr (sizeof(pixel_t_s) == 1)\n    source_bitdepth = 8;\n  if constexpr (sizeof(pixel_t_d) == 1)\n    target_bitdepth = 8;\n\n  const int max_pixel_value_target = (1 << target_bitdepth) - 1;\n  const int BITDIFF_BETWEEN_DITHER_AND_TARGET = DITHER_BIT_DIFF - (source_bitdepth - target_bitdepth);\n  const int max_pixel_value_dithered = (1 << dither_target_bitdepth) - 1;\n\n  std::vector<int> error_ptr_safe(1 + src_width + 1); // accumulated errors\n  int *error_ptr = &error_ptr_safe[1];\n\n  const int ROUNDER = 1 << (DITHER_BIT_DIFF - 1); // rounding\n  const int source_max = (1 << source_bitdepth) - 1;\n  //-----------------------\n  bits_conv_constants d;\n  get_bits_conv_constants(d, chroma, fulls, fulld, source_bitdepth, source_bitdepth);\n\n  auto dst_offset_plus_round = d.dst_offset + 0.5f;\n  constexpr auto src_pixel_min = 0;\n  const auto src_pixel_max = source_max;\n  const float mul_factor_backfromlowdither = (float)max_pixel_value_target / max_pixel_value_dithered;\n\n  int nextError = 0; // zero\n\n  for (int y = 0; y < src_height; y++)\n  {\n    // serpentine forward\n    if ((y & 1) == 0)\n    {\n      for (int x = 0; x < src_width; x++)\n      {\n        int err = nextError;\n        int src_pixel = srcp[x];\n\n        if constexpr (fulls != fulld) {\n          const float val = (src_pixel - d.src_offset_i) * d.mul_factor + dst_offset_plus_round;\n          src_pixel = clamp((int)val, src_pixel_min, src_pixel_max);\n        }\n\n        if (TEMPLATE_LOW_DITHER_BITDEPTH) {\n          // accurate dither: +/-\n          // accurately positioned to the center\n          err = err - (1 << (DITHER_BIT_DIFF - 1)); // signed\n        }\n        int sum = src_pixel + err;\n\n        int quantized = (sum + ROUNDER) >> (DITHER_BIT_DIFF);\n        err = sum - (quantized << DITHER_BIT_DIFF);\n        // Interesting problem of dither_bits==1 (or in general at small dither_bits)\n        // After simple slli 0,1 becomes 0,128, we'd expect 0,255 instead. So we make cosmetics.\n        if (TEMPLATE_LOW_DITHER_BITDEPTH) {\n          quantized = min(quantized, max_pixel_value_dithered);\n          quantized = (int)(quantized * mul_factor_backfromlowdither + 0.5f);\n        }\n        else {\n          quantized <<= BITDIFF_BETWEEN_DITHER_AND_TARGET;\n        }\n        int pix = max(min(max_pixel_value_target, quantized), 0); // clamp to target bit\n        dstp[x] = (pixel_t_d)pix;\n        diffuse_floyd<1>(err, nextError, &error_ptr[x]);\n      }\n    }\n    else {\n      // serpentine backward\n      for (int x = src_width - 1; x >= 0; --x)\n      {\n        int err = nextError;\n        int src_pixel = srcp[x];\n\n        if constexpr (fulls != fulld) {\n          const float val = (src_pixel - d.src_offset_i) * d.mul_factor + dst_offset_plus_round;\n          src_pixel = clamp((int)val, src_pixel_min, src_pixel_max);\n        }\n\n        if (TEMPLATE_LOW_DITHER_BITDEPTH) {\n          // accurate dither: +/-\n          // accurately positioned to the center\n          err = err - (1 << (DITHER_BIT_DIFF - 1)); // signed\n        }\n        int sum = src_pixel + err;\n\n        int quantized = (sum + ROUNDER) >> (DITHER_BIT_DIFF);\n        err = sum - (quantized << DITHER_BIT_DIFF);\n        // Interesting problem of dither_bits==1 (or in general at small dither_bits)\n        // After simple slli 0,1 becomes 0,128, we'd expect 0,255 instead. So we make cosmetics.\n        if (TEMPLATE_LOW_DITHER_BITDEPTH) {\n          quantized = min(quantized, max_pixel_value_dithered);\n          quantized = (int)(quantized * mul_factor_backfromlowdither + 0.5f);\n        }\n        else {\n          quantized <<= BITDIFF_BETWEEN_DITHER_AND_TARGET;\n        }\n        int pix = max(min(max_pixel_value_target, quantized), 0); // clamp to target bit\n        dstp[x] = (pixel_t_d)pix;\n        diffuse_floyd<-1>(err, nextError, &error_ptr[x]);\n      }\n    }\n    dstp += dst_pitch;\n    srcp += src_pitch;\n  }\n}\n\n\ntemplate<typename pixel_t_s, typename pixel_t_d, bool chroma, bool fulls, bool fulld>\nstatic void convert_uint_floyd_c(const BYTE* srcp8, BYTE* dstp8, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth)\n{\n  const int dither_bit_diff = source_bitdepth - dither_target_bitdepth;\n  const bool low_dither_bitdepth = dither_target_bitdepth < 8;\n  // extra internal template makes it quicker for ordinary non-artistic cases\n  // do not make templates for all 1-16 target bit combinations\n  if (low_dither_bitdepth) {\n    do_convert_uint_floyd_c<pixel_t_s, pixel_t_d, chroma, fulls, fulld, -1, true, -1>(srcp8, dstp8, src_rowsize, src_height, src_pitch, dst_pitch, source_bitdepth, target_bitdepth, dither_target_bitdepth);\n  }\n  else {\n    if (target_bitdepth == dither_target_bitdepth) {\n      // Specifically when source_bitdepth is known as well, it hugely helps optimization\n      // We treat special use cases 10->8, 16->10 and 16->8\n      switch (dither_bit_diff) {\n      case 2: // e.g. 10->8\n        if (source_bitdepth == 10)\n          do_convert_uint_floyd_c<pixel_t_s, pixel_t_d, chroma, fulls, fulld, 2, false, 10>(srcp8, dstp8, src_rowsize, src_height, src_pitch, dst_pitch, source_bitdepth, target_bitdepth, dither_target_bitdepth);\n        else\n          do_convert_uint_floyd_c<pixel_t_s, pixel_t_d, chroma, fulls, fulld, 2, false, -1>(srcp8, dstp8, src_rowsize, src_height, src_pitch, dst_pitch, source_bitdepth, target_bitdepth, dither_target_bitdepth);\n        break;\n      case 4: // e.g. 12->8\n        do_convert_uint_floyd_c<pixel_t_s, pixel_t_d, chroma, fulls, fulld, 4, false, -1>(srcp8, dstp8, src_rowsize, src_height, src_pitch, dst_pitch, source_bitdepth, target_bitdepth, dither_target_bitdepth);\n        break;\n      case 6: // e.g. 16->10, 14->8\n        // prevent invalid templates to generate\n        // like do_convert_uint_floyd_c<unsigned short,unsigned char,0,0,1,6,0,16> which would do 16->8 but dither to 10 bit.\n        if constexpr (sizeof(pixel_t_s) == 2 && sizeof(pixel_t_d) == 2) {\n          if (source_bitdepth == 16)\n            do_convert_uint_floyd_c<pixel_t_s, pixel_t_d, chroma, fulls, fulld, 6, false, 16>(srcp8, dstp8, src_rowsize, src_height, src_pitch, dst_pitch, source_bitdepth, target_bitdepth, dither_target_bitdepth);\n          else\n            do_convert_uint_floyd_c<pixel_t_s, pixel_t_d, chroma, fulls, fulld, 6, false, -1>(srcp8, dstp8, src_rowsize, src_height, src_pitch, dst_pitch, source_bitdepth, target_bitdepth, dither_target_bitdepth);\n        } else\n          do_convert_uint_floyd_c<pixel_t_s, pixel_t_d, chroma, fulls, fulld, 6, false, -1>(srcp8, dstp8, src_rowsize, src_height, src_pitch, dst_pitch, source_bitdepth, target_bitdepth, dither_target_bitdepth);\n        break;\n      case 8: // e.g. 16->8\n        if (sizeof(pixel_t_s) == 2 && source_bitdepth == 16)\n          do_convert_uint_floyd_c<pixel_t_s, pixel_t_d, chroma, fulls, fulld, 8, false, 16>(srcp8, dstp8, src_rowsize, src_height, src_pitch, dst_pitch, source_bitdepth, target_bitdepth, dither_target_bitdepth);\n        else\n          do_convert_uint_floyd_c<pixel_t_s, pixel_t_d, chroma, fulls, fulld, 8, false, -1>(srcp8, dstp8, src_rowsize, src_height, src_pitch, dst_pitch, source_bitdepth, target_bitdepth, dither_target_bitdepth);\n        break;\n      default: // difference is more than 8 or exotic dither to less than 8 bits, we accept 10-15% speed minus\n        do_convert_uint_floyd_c<pixel_t_s, pixel_t_d, chroma, fulls, fulld, -1, false, -1>(srcp8, dstp8, src_rowsize, src_height, src_pitch, dst_pitch, source_bitdepth, target_bitdepth, dither_target_bitdepth);\n      }\n    }\n    else {\n      do_convert_uint_floyd_c<pixel_t_s, pixel_t_d, chroma, fulls, fulld, -1, false, -1>(srcp8, dstp8, src_rowsize, src_height, src_pitch, dst_pitch, source_bitdepth, target_bitdepth, dither_target_bitdepth);\n    }\n  }\n}\n\n// float to 8-16 bits\ntemplate<typename pixel_t, bool chroma, bool fulls, bool fulld>\nstatic void convert_32_to_uintN_c(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth)\n{\n  const float *srcp0 = reinterpret_cast<const float *>(srcp);\n  pixel_t *dstp0 = reinterpret_cast<pixel_t *>(dstp);\n\n  src_pitch = src_pitch / sizeof(float);\n  dst_pitch = dst_pitch / sizeof(pixel_t);\n\n  const int src_width = src_rowsize / sizeof(float);\n\n  //-----------------------\n\n  bits_conv_constants d;\n  get_bits_conv_constants(d, chroma, fulls, fulld, source_bitdepth, target_bitdepth);\n\n  auto dst_offset_plus_round = d.dst_offset + 0.5f;\n  constexpr auto dst_pixel_min = 0;\n  const auto dst_pixel_max = (1 << target_bitdepth) - 1;\n\n  for(int y=0; y<src_height; y++)\n  {\n    for (int x = 0; x < src_width; x++)\n    {\n      const int pixel = (int)((srcp0[x] - d.src_offset) * d.mul_factor + dst_offset_plus_round);\n      dstp0[x] = pixel_t(clamp(pixel, dst_pixel_min, dst_pixel_max));\n    }\n    dstp0 += dst_pitch;\n    srcp0 += src_pitch;\n  }\n}\n\n// YUV: bit shift 8-16 <=> 8-16 bits\n// shift right or left, depending on expandrange\ntemplate<typename pixel_t_s, typename pixel_t_d>\nstatic void convert_uint_limited_c(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth)\n{\n  const pixel_t_s* srcp0 = reinterpret_cast<const pixel_t_s*>(srcp);\n  pixel_t_d* dstp0 = reinterpret_cast<pixel_t_d*>(dstp);\n\n  src_pitch = src_pitch / sizeof(pixel_t_s);\n  dst_pitch = dst_pitch / sizeof(pixel_t_d);\n\n  const int src_width = src_rowsize / sizeof(pixel_t_s);\n\n  if (target_bitdepth > source_bitdepth) // expandrange\n  {\n    const int shift_bits = target_bitdepth - source_bitdepth;\n    for (int y = 0; y < src_height; y++)\n    {\n      for (int x = 0; x < src_width; x++) {\n        dstp0[x] = (pixel_t_d)(srcp0[x]) << shift_bits;  // expand range. No clamp before, source is assumed to have valid range\n      }\n      dstp0 += dst_pitch;\n      srcp0 += src_pitch;\n    }\n  }\n  else\n  {\n    // reduce range\n    const int shift_bits = source_bitdepth - target_bitdepth;\n    const int round = 1 << (shift_bits - 1);\n\n    const int target_max = (1 << target_bitdepth) - 1;\n    constexpr auto target_min = 0;\n\n    for (int y = 0; y < src_height; y++)\n    {\n      for (int x = 0; x < src_width; x++) {\n        dstp0[x] = clamp((srcp0[x] + round) >> shift_bits, target_min, target_max);;  // reduce range\n      }\n      dstp0 += dst_pitch;\n      srcp0 += src_pitch;\n    }\n  }\n}\n\n// chroma is special in full range\ntemplate<typename pixel_t_s, typename pixel_t_d, bool chroma, bool fulls, bool fulld>\nstatic void convert_uint_c(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth)\n{\n  // limited to limited is bitshift, see in other function\n  if constexpr (!fulls && !fulld) {\n    convert_uint_limited_c< pixel_t_s, pixel_t_d>(srcp, dstp, src_rowsize, src_height, src_pitch, dst_pitch, source_bitdepth, target_bitdepth, dither_target_bitdepth);\n    return;\n  }\n\n  const pixel_t_s* srcp0 = reinterpret_cast<const pixel_t_s*>(srcp);\n  pixel_t_d* dstp0 = reinterpret_cast<pixel_t_d*>(dstp);\n\n  src_pitch = src_pitch / sizeof(pixel_t_s);\n  dst_pitch = dst_pitch / sizeof(pixel_t_d);\n\n  const int src_width = src_rowsize / sizeof(pixel_t_s);\n\n  if constexpr (sizeof(pixel_t_s) == 1 && sizeof(pixel_t_d) == 2) {\n    if (fulls && fulld && !chroma && source_bitdepth == 8 && target_bitdepth == 16) {\n      // special case * 65535 / 255 = *257 exactly\n      for (int y = 0; y < src_height; y++)\n      {\n        for (int x = 0; x < src_width; x++)\n        {\n          dstp0[x] = (pixel_t_d)(srcp0[x] * 257);\n        }\n        dstp0 += dst_pitch;\n        srcp0 += src_pitch;\n      }\n      return;\n    }\n  }\n\n  const int target_max = (1 << target_bitdepth) - 1;\n\n  bits_conv_constants d;\n  get_bits_conv_constants(d, chroma, fulls, fulld, source_bitdepth, target_bitdepth);\n\n  auto dst_offset_plus_round = d.dst_offset + 0.5f;\n  constexpr auto target_min = 0;\n\n  for (int y = 0; y < src_height; y++) {\n    for (int x = 0; x < src_width; x++)\n    {\n      const float val = (srcp0[x] - d.src_offset_i) * d.mul_factor + dst_offset_plus_round;\n      dstp0[x] = clamp((int)val, target_min, target_max);\n    }\n\n    dstp0 += dst_pitch;\n    srcp0 += src_pitch;\n  }\n}\n\n\n\n// 8 bit to float, 16/14/12/10 bits to float\ntemplate<typename pixel_t, bool chroma, bool fulls, bool fulld>\nstatic void convert_uintN_to_float_c(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth)\n{\n  const pixel_t *srcp0 = reinterpret_cast<const pixel_t *>(srcp);\n  float *dstp0 = reinterpret_cast<float *>(dstp);\n\n  src_pitch = src_pitch / sizeof(pixel_t);\n  dst_pitch = dst_pitch / sizeof(float);\n\n  const int src_width = src_rowsize / sizeof(pixel_t);\n\n  //-----------------------\n  bits_conv_constants d;\n  get_bits_conv_constants(d, chroma, fulls, fulld, source_bitdepth, target_bitdepth);\n\n  for (int y = 0; y < src_height; y++)\n  {\n    for (int x = 0; x < src_width; x++)\n    {\n      const float pixel = (srcp0[x] - d.src_offset_i) * d.mul_factor + d.dst_offset;\n      dstp0[x] = pixel; // no clamp\n    }\n    dstp0 += dst_pitch;\n    srcp0 += src_pitch;\n  }\n}\n\n// float to float\ntemplate<bool chroma, bool fulls, bool fulld>\nstatic void convert_float_to_float_c(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth)\n{\n  // float is good if always full range. For historical reasons Avisynth has \"limited\" range float,\n  // which is simply a /255.0 reduction of original byte pixels\n  const float* srcp0 = reinterpret_cast<const float*>(srcp);\n  float* dstp0 = reinterpret_cast<float*>(dstp);\n\n  src_pitch = src_pitch / sizeof(float);\n  dst_pitch = dst_pitch / sizeof(float);\n\n  const int src_width = src_rowsize / sizeof(float);\n\n  //-----------------------\n  bits_conv_constants d;\n  get_bits_conv_constants(d, chroma, fulls, fulld, source_bitdepth, target_bitdepth);\n\n  for (int y = 0; y < src_height; y++)\n  {\n    for (int x = 0; x < src_width; x++)\n    {\n      const float pixel = (srcp0[x] - d.src_offset) * d.mul_factor + d.dst_offset;\n      dstp0[x] = pixel; // no clamp\n    }\n    dstp0 += dst_pitch;\n    srcp0 += src_pitch;\n  }\n}\n\nstatic void get_convert_32_to_uintN_functions(int target_bitdepth, bool fulls, bool fulld, \n#ifdef INTEL_INTRINSICS\n  bool sse2, bool sse4, bool avx2,\n#endif\n  BitDepthConvFuncPtr& conv_function, BitDepthConvFuncPtr& conv_function_chroma, BitDepthConvFuncPtr& conv_function_a)\n{\n  // 32bit->8-16bits support fulls fulld\n      // pure C\n#define convert_32_to_uintN_functions(uint_X_t) \\\n      conv_function_a = convert_32_to_uintN_c<uint_X_t, false, true, true>; /* full-full */ \\\n      if (fulls && fulld) { \\\n        conv_function = convert_32_to_uintN_c<uint_X_t, false, true, true>; \\\n        conv_function_chroma = convert_32_to_uintN_c<uint_X_t, true, true, true>; \\\n      } \\\n      else if (fulls && !fulld) { \\\n        conv_function = convert_32_to_uintN_c<uint_X_t, false, true, false>; \\\n        conv_function_chroma = convert_32_to_uintN_c<uint_X_t, true, true, false>; \\\n      } \\\n      else if (!fulls && fulld) { \\\n        conv_function = convert_32_to_uintN_c<uint_X_t, false, false, true>; \\\n        conv_function_chroma = convert_32_to_uintN_c<uint_X_t, true, false, true>; \\\n      } \\\n      else if (!fulls && !fulld) { \\\n        conv_function = convert_32_to_uintN_c<uint_X_t, false, false, false>; \\\n        conv_function_chroma = convert_32_to_uintN_c<uint_X_t, true, false, false>; \\\n      }\n\n#ifdef INTEL_INTRINSICS\n#undef convert_32_to_uintN_functions\n\n#define convert_32_to_uintN_functions(uint_X_t) \\\n      conv_function_a = avx2 ? convert_32_to_uintN_avx2<uint_X_t, false, true, true> : sse4 ? convert_32_to_uintN_sse41<uint_X_t, false, true, true> : convert_32_to_uintN_c<uint_X_t, false, true, true>; /* full-full */ \\\n      if (fulls && fulld) { \\\n        conv_function = avx2 ? convert_32_to_uintN_avx2<uint_X_t, false, true, true> : sse4 ? convert_32_to_uintN_sse41<uint_X_t, false, true, true> : convert_32_to_uintN_c<uint_X_t, false, true, true>; \\\n        conv_function_chroma = avx2 ? convert_32_to_uintN_avx2<uint_X_t, true, true, true> : sse4 ? convert_32_to_uintN_sse41<uint_X_t, true, true, true> : convert_32_to_uintN_c<uint_X_t, true, true, true>; \\\n      } \\\n      else if (fulls && !fulld) { \\\n        conv_function = avx2 ? convert_32_to_uintN_avx2<uint_X_t, false, true, false> : sse4 ? convert_32_to_uintN_sse41<uint_X_t, false, true, false> : convert_32_to_uintN_c<uint_X_t, false, true, false>; \\\n        conv_function_chroma = avx2 ? convert_32_to_uintN_avx2<uint_X_t, true, true, false> : sse4 ? convert_32_to_uintN_sse41<uint_X_t, true, true, false> : convert_32_to_uintN_c<uint_X_t, true, true, false>; \\\n      } \\\n      else if (!fulls && fulld) { \\\n        conv_function = avx2 ? convert_32_to_uintN_avx2<uint_X_t, false, false, true> : sse4 ? convert_32_to_uintN_sse41<uint_X_t, false, false, true> : convert_32_to_uintN_c<uint_X_t, false, false, true>; \\\n        conv_function_chroma = avx2 ? convert_32_to_uintN_avx2<uint_X_t, true, false, true> : sse4 ? convert_32_to_uintN_sse41<uint_X_t, true, false, true> : convert_32_to_uintN_c<uint_X_t, true, false, true>; \\\n      } \\\n      else if (!fulls && !fulld) { \\\n        conv_function = avx2 ? convert_32_to_uintN_avx2<uint_X_t, false, false, false> : sse4 ? convert_32_to_uintN_sse41<uint_X_t, false, false, false> : convert_32_to_uintN_c<uint_X_t, false, false, false>; \\\n        conv_function_chroma = avx2 ? convert_32_to_uintN_avx2<uint_X_t, true, false, false> : sse4 ? convert_32_to_uintN_sse41<uint_X_t, true, false, false> : convert_32_to_uintN_c<uint_X_t, true, false, false>; \\\n      }\n#endif\n\n  switch (target_bitdepth)\n  {\n  case 8:\n    convert_32_to_uintN_functions(uint8_t); // all variations of fulls fulld\n    break;\n  default:\n    // 10-16 bits\n    convert_32_to_uintN_functions(uint16_t); // all variations of fulls fulld\n    break;\n  }\n\n#undef convert_32_to_uintN_functions\n}\n\nstatic void get_convert_float_to_float_functions(bool fulls, bool fulld,\n  BitDepthConvFuncPtr& conv_function, BitDepthConvFuncPtr& conv_function_chroma, BitDepthConvFuncPtr& conv_function_a)\n{\n  // 32bit->32bits support fulls fulld, alpha is always full-full\n  conv_function_a = convert_float_to_float_c<false, true, true>; /* full-full */\n  if (fulls && fulld) {\n    conv_function = convert_float_to_float_c<false, true, true>;\n    conv_function_chroma = convert_float_to_float_c<true, true, true>;\n  }\n  else if (fulls && !fulld) {\n    conv_function = convert_float_to_float_c<false, true, false>;\n    conv_function_chroma = convert_float_to_float_c<true, true, false>;\n  }\n  else if (!fulls && fulld) { \\\n    conv_function = convert_float_to_float_c<false, false, true>;\n    conv_function_chroma = convert_float_to_float_c<true, false, true>;\n  }\n  else if (!fulls && !fulld) {\n    conv_function = convert_float_to_float_c<false, false, false>;\n    conv_function_chroma = convert_float_to_float_c<true, false, false>;\n  }\n}\n\nstatic void get_convert_uintN_to_float_functions(int bits_per_pixel, bool fulls, bool fulld,\n#ifdef INTEL_INTRINSICS\n  bool sse2, bool sse4, bool avx2,\n#endif\n  BitDepthConvFuncPtr& conv_function, BitDepthConvFuncPtr& conv_function_chroma, BitDepthConvFuncPtr& conv_function_a)\n{\n  // 8-16bit->32bits support fulls fulld, alpha is always full-full\n#define convert_uintN_to_float_functions(uint_X_t) \\\n      conv_function_a = convert_uintN_to_float_c<uint_X_t, false, true, true>; /* full-full */ \\\n      if (fulls && fulld) { \\\n        conv_function = convert_uintN_to_float_c<uint_X_t, false, true, true>; \\\n        conv_function_chroma = convert_uintN_to_float_c<uint_X_t, true, true, true>; \\\n      } \\\n      else if (fulls && !fulld) { \\\n        conv_function = convert_uintN_to_float_c<uint_X_t, false, true, false>; \\\n        conv_function_chroma = convert_uintN_to_float_c<uint_X_t, true, true, false>; \\\n      } \\\n      else if (!fulls && fulld) { \\\n        conv_function = convert_uintN_to_float_c<uint_X_t, false, false, true>; \\\n        conv_function_chroma = convert_uintN_to_float_c<uint_X_t, true, false, true>; \\\n      } \\\n      else if (!fulls && !fulld) { \\\n        conv_function = convert_uintN_to_float_c<uint_X_t, false, false, false>; \\\n        conv_function_chroma = convert_uintN_to_float_c<uint_X_t, true, false, false>; \\\n      }\n\n#define convert_uintN_to_float_functions_avx2(uint_X_t) \\\n      conv_function_a = convert_uintN_to_float_avx2<uint_X_t, false, true, true>; /* full-full */ \\\n      if (fulls && fulld) { \\\n        conv_function = convert_uintN_to_float_avx2<uint_X_t, false, true, true>; \\\n        conv_function_chroma = convert_uintN_to_float_avx2<uint_X_t, true, true, true>; \\\n      } \\\n      else if (fulls && !fulld) { \\\n        conv_function = convert_uintN_to_float_avx2<uint_X_t, false, true, false>; \\\n        conv_function_chroma = convert_uintN_to_float_avx2<uint_X_t, true, true, false>; \\\n      } \\\n      else if (!fulls && fulld) { \\\n        conv_function = convert_uintN_to_float_avx2<uint_X_t, false, false, true>; \\\n        conv_function_chroma = convert_uintN_to_float_avx2<uint_X_t, true, false, true>; \\\n      } \\\n      else if (!fulls && !fulld) { \\\n        conv_function = convert_uintN_to_float_avx2<uint_X_t, false, false, false>; \\\n        conv_function_chroma = convert_uintN_to_float_avx2<uint_X_t, true, false, false>; \\\n      }\n\n  switch (bits_per_pixel) {\n  case 8: \n    convert_uintN_to_float_functions(uint8_t);\n    break;\n  default: // 10-16 bits\n    convert_uintN_to_float_functions(uint16_t);\n    break;\n  }\n\n#ifdef INTEL_INTRINSICS\n  if (avx2) {\n    switch (bits_per_pixel) {\n    case 8:\n      convert_uintN_to_float_functions_avx2(uint8_t);\n      break;\n    default: // 10-16 bits\n      convert_uintN_to_float_functions_avx2(uint16_t);\n      break;\n    }\n  }\n#endif \n\n\n#undef convert_uintN_to_float_functions\n}\n\nstatic void get_convert_uintN_to_uintN_ordered_dither_functions(int source_bitdepth, int target_bitdepth, bool fulls, bool fulld,\n#ifdef INTEL_INTRINSICS\n  bool sse2, bool sse4, bool avx2,\n#endif\n  BitDepthConvFuncPtr& conv_function, BitDepthConvFuncPtr& conv_function_chroma)\n{\n// 8-16->8-16 bits support any fulls fulld combination\n// dither has no \"conv_function_a\"\n// pure C\n#define convert_uintN_to_uintN_ordered_dither_functions(uint_X_t, uint_X_dest_t) \\\n      if (fulls && fulld) { \\\n        conv_function = convert_ordered_dither_uint_c<uint_X_t, uint_X_dest_t, false, true, true>; \\\n        conv_function_chroma = convert_ordered_dither_uint_c<uint_X_t, uint_X_dest_t, true, true, true>; \\\n      } \\\n      else if (fulls && !fulld) { \\\n        conv_function = convert_ordered_dither_uint_c<uint_X_t, uint_X_dest_t, false, true, false>; \\\n        conv_function_chroma = convert_ordered_dither_uint_c<uint_X_t, uint_X_dest_t, true, true, false>; \\\n      } \\\n      else if (!fulls && fulld) { \\\n        conv_function = convert_ordered_dither_uint_c<uint_X_t, uint_X_dest_t, false, false, true>; \\\n        conv_function_chroma = convert_ordered_dither_uint_c<uint_X_t, uint_X_dest_t, true, false, true>; \\\n      } \\\n      else if (!fulls && !fulld) { \\\n        conv_function = convert_ordered_dither_uint_c<uint_X_t, uint_X_dest_t, false, false, false>; \\\n        conv_function_chroma = convert_ordered_dither_uint_c<uint_X_t, uint_X_dest_t, true, false, false>; \\\n      }\n\n#ifdef INTEL_INTRINSICS\n#undef convert_uintN_to_uintN_ordered_dither_functions\n// dither has no \"conv_function_a\"\n#define convert_uintN_to_uintN_ordered_dither_functions(uint_X_t, uint_X_dest_t) \\\n      if (fulls && fulld) { \\\n        conv_function = avx2 ? convert_ordered_dither_uint_avx2<uint_X_t, uint_X_dest_t, false, true, true> : sse4 ? convert_ordered_dither_uint_sse41<uint_X_t, uint_X_dest_t, false, true, true> : convert_ordered_dither_uint_c<uint_X_t, uint_X_dest_t, false, true, true>; \\\n        conv_function_chroma = avx2 ? convert_ordered_dither_uint_avx2<uint_X_t, uint_X_dest_t, true, true, true> : sse4 ? convert_ordered_dither_uint_sse41<uint_X_t, uint_X_dest_t, true, true, true> : convert_ordered_dither_uint_c<uint_X_t, uint_X_dest_t, true, true, true>; \\\n      } \\\n      else if (fulls && !fulld) { \\\n        conv_function = avx2 ? convert_ordered_dither_uint_avx2<uint_X_t, uint_X_dest_t, false, true, false> : sse4 ? convert_ordered_dither_uint_sse41<uint_X_t, uint_X_dest_t, false, true, false> : convert_ordered_dither_uint_c<uint_X_t, uint_X_dest_t, false, true, false>; \\\n        conv_function_chroma = avx2 ? convert_ordered_dither_uint_avx2<uint_X_t, uint_X_dest_t, true, true, false> : sse4 ? convert_ordered_dither_uint_sse41<uint_X_t, uint_X_dest_t, true, true, false> : convert_ordered_dither_uint_c<uint_X_t, uint_X_dest_t, true, true, false>; \\\n      } \\\n      else if (!fulls && fulld) { \\\n        conv_function = avx2 ? convert_ordered_dither_uint_avx2<uint_X_t, uint_X_dest_t, false, false, true> : sse4 ? convert_ordered_dither_uint_sse41<uint_X_t, uint_X_dest_t, false, false, true> : convert_ordered_dither_uint_c<uint_X_t, uint_X_dest_t, false, false, true>; \\\n        conv_function_chroma = avx2 ? convert_ordered_dither_uint_avx2<uint_X_t, uint_X_dest_t, true, false, true> : sse4 ? convert_ordered_dither_uint_sse41<uint_X_t, uint_X_dest_t, true, false, true> : convert_ordered_dither_uint_c<uint_X_t, uint_X_dest_t, true, false, true>; \\\n      } \\\n      else if (!fulls && !fulld) { \\\n       conv_function = avx2 ? convert_ordered_dither_uint_avx2<uint_X_t, uint_X_dest_t, false, false, false> : sse4 ? convert_ordered_dither_uint_sse41<uint_X_t, uint_X_dest_t, false, false, false> : convert_ordered_dither_uint_c<uint_X_t, uint_X_dest_t, false, false, false>; \\\n       conv_function_chroma = avx2 ? convert_ordered_dither_uint_avx2<uint_X_t, uint_X_dest_t, true, false, false> : sse4 ? convert_ordered_dither_uint_sse41<uint_X_t, uint_X_dest_t, true, false, false> : convert_ordered_dither_uint_c<uint_X_t, uint_X_dest_t, true, false, false>; \\\n      }\n#endif\n  // all variations of fulls fulld byte/word source/target\n  switch (target_bitdepth)\n  {\n  case 8:\n    if (source_bitdepth == 8) {\n      convert_uintN_to_uintN_ordered_dither_functions(uint8_t, uint8_t);\n    }\n    else {\n      convert_uintN_to_uintN_ordered_dither_functions(uint16_t, uint8_t);\n    }\n    break;\n  default:\n    // uint16_t target is always uint16_t source\n    convert_uintN_to_uintN_ordered_dither_functions(uint16_t, uint16_t);\n    break;\n  }\n\n#undef convert_uintN_to_uintN_ordered_dither_functions\n}\n\nstatic void get_convert_uintN_to_uintN_floyd_dither_functions(int source_bitdepth, int target_bitdepth, bool fulls, bool fulld,\n  BitDepthConvFuncPtr& conv_function, BitDepthConvFuncPtr& conv_function_chroma)\n{\n  // 8-16->8-16 bits support any fulls fulld combination\n  // dither has no \"conv_function_a\"\n  // pure C\n#define convert_uintN_to_uintN_floyd_dither_functions(uint_X_t, uint_X_dest_t) \\\n      if (fulls && fulld) { \\\n        conv_function = convert_uint_floyd_c<uint_X_t, uint_X_dest_t, false, true, true>; \\\n        conv_function_chroma = convert_uint_floyd_c<uint_X_t, uint_X_dest_t, true, true, true>; \\\n      } \\\n      else if (fulls && !fulld) { \\\n        conv_function = convert_uint_floyd_c<uint_X_t, uint_X_dest_t, false, true, false>; \\\n        conv_function_chroma = convert_uint_floyd_c<uint_X_t, uint_X_dest_t, true, true, false>; \\\n      } \\\n      else if (!fulls && fulld) { \\\n        conv_function = convert_uint_floyd_c<uint_X_t, uint_X_dest_t, false, false, true>; \\\n        conv_function_chroma = convert_uint_floyd_c<uint_X_t, uint_X_dest_t, true, false, true>; \\\n      } \\\n      else if (!fulls && !fulld) { \\\n        conv_function = convert_uint_floyd_c<uint_X_t, uint_X_dest_t, false, false, false>; \\\n        conv_function_chroma = convert_uint_floyd_c<uint_X_t, uint_X_dest_t, true, false, false>; \\\n      }\n\n  // all variations of fulls fulld byte/word source/target\n  switch (target_bitdepth)\n  {\n  case 8:\n    if (source_bitdepth == 8) {\n      convert_uintN_to_uintN_floyd_dither_functions(uint8_t, uint8_t);\n    }\n    else {\n      convert_uintN_to_uintN_floyd_dither_functions(uint16_t, uint8_t);\n    }\n    break;\n  default:\n    // uint16_t target is always uint16_t source\n    convert_uintN_to_uintN_floyd_dither_functions(uint16_t, uint16_t);\n    break;\n  }\n\n#undef convert_uintN_to_uintN_floyd_dither_functions\n}\n\n\nstatic void get_convert_uintN_to_uintN_functions(int source_bitdepth, int target_bitdepth, bool fulls, bool fulld,\n#ifdef INTEL_INTRINSICS\n  bool sse2, bool sse4, bool avx2,\n#endif\n  BitDepthConvFuncPtr& conv_function, BitDepthConvFuncPtr& conv_function_chroma, BitDepthConvFuncPtr& conv_function_a)\n{\n  // 8-16->8-16 bits support any fulls fulld combination\n  // pure C\n#define convert_uintN_to_uintN_functions(uint_X_t, uint_X_dest_t) \\\n      conv_function_a = convert_uint_c<uint_X_t, uint_X_dest_t, false, true, true>; /* full-full */ \\\n      if (fulls && fulld) { \\\n        conv_function = convert_uint_c<uint_X_t, uint_X_dest_t, false, true, true>; \\\n        conv_function_chroma = convert_uint_c<uint_X_t, uint_X_dest_t, true, true, true>; \\\n      } \\\n      else if (fulls && !fulld) { \\\n        conv_function = convert_uint_c<uint_X_t, uint_X_dest_t, false, true, false>; \\\n        conv_function_chroma = convert_uint_c<uint_X_t, uint_X_dest_t, true, true, false>; \\\n      } \\\n      else if (!fulls && fulld) { \\\n        conv_function = convert_uint_c<uint_X_t, uint_X_dest_t, false, false, true>; \\\n        conv_function_chroma = convert_uint_c<uint_X_t, uint_X_dest_t, true, false, true>; \\\n      } \\\n      else if (!fulls && !fulld) { \\\n        conv_function = convert_uint_c<uint_X_t, uint_X_dest_t, false, false, false>; \\\n        conv_function_chroma = convert_uint_c<uint_X_t, uint_X_dest_t, true, false, false>; \\\n      }\n\n#ifdef INTEL_INTRINSICS\n#undef convert_uintN_to_uintN_functions\n\n#define convert_uintN_to_uintN_functions(uint_X_t, uint_X_dest_t) \\\n      conv_function_a = avx2 ? convert_uint_avx2<uint_X_t, uint_X_dest_t, false, true, true> : sse4 ? convert_uint_sse41<uint_X_t, uint_X_dest_t, false, true, true> : convert_uint_c<uint_X_t, uint_X_dest_t, false, true, true>; /* full-full */ \\\n      if (fulls && fulld) { \\\n        conv_function = avx2 ? convert_uint_avx2<uint_X_t, uint_X_dest_t, false, true, true> : sse4 ? convert_uint_sse41<uint_X_t, uint_X_dest_t, false, true, true> : convert_uint_c<uint_X_t, uint_X_dest_t, false, true, true>; \\\n        conv_function_chroma = avx2 ? convert_uint_avx2<uint_X_t, uint_X_dest_t, true, true, true> : sse4 ? convert_uint_sse41<uint_X_t, uint_X_dest_t, true, true, true> : convert_uint_c<uint_X_t, uint_X_dest_t, true, true, true>; \\\n      } \\\n      else if (fulls && !fulld) { \\\n        conv_function = avx2 ? convert_uint_avx2<uint_X_t, uint_X_dest_t, false, true, false> : sse4 ? convert_uint_sse41<uint_X_t, uint_X_dest_t, false, true, false> : convert_uint_c<uint_X_t, uint_X_dest_t, false, true, false>; \\\n        conv_function_chroma = avx2 ? convert_uint_avx2<uint_X_t, uint_X_dest_t, true, true, false> : sse4 ? convert_uint_sse41<uint_X_t, uint_X_dest_t, true, true, false> : convert_uint_c<uint_X_t, uint_X_dest_t, true, true, false>; \\\n      } \\\n      else if (!fulls && fulld) { \\\n        conv_function = avx2 ? convert_uint_avx2<uint_X_t, uint_X_dest_t, false, false, true> : sse4 ? convert_uint_sse41<uint_X_t, uint_X_dest_t, false, false, true> : convert_uint_c<uint_X_t, uint_X_dest_t, false, false, true>; \\\n        conv_function_chroma = avx2 ? convert_uint_avx2<uint_X_t, uint_X_dest_t, true, false, true> : sse4 ? convert_uint_sse41<uint_X_t, uint_X_dest_t, true, false, true> : convert_uint_c<uint_X_t, uint_X_dest_t, true, false, true>; \\\n      } \\\n      else if (!fulls && !fulld) { \\\n        conv_function = avx2 ? convert_uint_avx2<uint_X_t, uint_X_dest_t, false, false, false> : sse4 ? convert_uint_sse41<uint_X_t, uint_X_dest_t, false, false, false> : convert_uint_c<uint_X_t, uint_X_dest_t, false, false, false>; \\\n        conv_function_chroma = avx2 ? convert_uint_avx2<uint_X_t, uint_X_dest_t, true, false, false> : sse4 ? convert_uint_sse41<uint_X_t, uint_X_dest_t, true, false, false> : convert_uint_c<uint_X_t, uint_X_dest_t, true, false, false>; \\\n      }\n#endif\n\n   // all variations of fulls fulld byte/word source/target\n  switch (target_bitdepth)\n  {\n  case 8:\n    if (source_bitdepth == 8) {\n      convert_uintN_to_uintN_functions(uint8_t, uint8_t);\n    }\n    else {\n      convert_uintN_to_uintN_functions(uint16_t, uint8_t);\n    }\n    break;\n  default:\n    // 10-16 bits\n    if (source_bitdepth == 8)\n    {\n      convert_uintN_to_uintN_functions(uint8_t, uint16_t);\n    }\n    else {\n      convert_uintN_to_uintN_functions(uint16_t, uint16_t);\n    }\n    break;\n  }\n\n#undef convert_uintN_to_uintN_functions\n}\n\nvoid get_convert_any_bits_functions(int dither_mode, int source_bitdepth, int target_bitdepth, bool fulls, bool fulld,\n#ifdef INTEL_INTRINSICS\n  bool sse2, bool sse4, bool avx2,\n#endif\n  BitDepthConvFuncPtr& conv_function, BitDepthConvFuncPtr& conv_function_chroma, BitDepthConvFuncPtr& conv_function_a)\n{\n\n  if (source_bitdepth <= 16 && target_bitdepth <= 16)\n  {\n    // get basic non-dithered versions\n#ifdef INTEL_INTRINSICS\n    get_convert_uintN_to_uintN_functions(source_bitdepth, target_bitdepth, fulls, fulld, sse2, sse4, avx2, conv_function, conv_function_chroma, conv_function_a);\n#else\n    get_convert_uintN_to_uintN_functions(source_bitdepth, target_bitdepth, fulls, fulld, conv_function, conv_function_chroma, conv_function_a);\n#endif\n    if (target_bitdepth <= source_bitdepth) {\n      // dither is only down\n      if (dither_mode == 0) {\n        // ordered dither\n#ifdef INTEL_INTRINSICS\n        get_convert_uintN_to_uintN_ordered_dither_functions(source_bitdepth, target_bitdepth, fulls, fulld, sse2, sse4, avx2, conv_function, conv_function_chroma);\n#else\n        get_convert_uintN_to_uintN_ordered_dither_functions(source_bitdepth, target_bitdepth, fulls, fulld, conv_function, conv_function_chroma);\n#endif\n      }\n      else if (dither_mode == 1) {\n        // Floyd, no SIMD there\n        get_convert_uintN_to_uintN_floyd_dither_functions(source_bitdepth, target_bitdepth, fulls, fulld, conv_function, conv_function_chroma);\n      }\n    }\n  }\n\n  // 32->8-16 bit\n  if (source_bitdepth == 32 && target_bitdepth <= 16) {\n#ifdef INTEL_INTRINSICS\n    get_convert_32_to_uintN_functions(target_bitdepth, fulls, fulld, sse2, sse4, avx2, conv_function, conv_function_chroma, conv_function_a);\n#else\n    get_convert_32_to_uintN_functions(target_bitdepth, fulls, fulld, conv_function, conv_function_chroma, conv_function_a);\n#endif\n  }\n\n  // 8-32->32\n  if (target_bitdepth == 32) {\n    if (source_bitdepth <= 16) // 8-16->32 bit\n#ifdef INTEL_INTRINSICS\n      get_convert_uintN_to_float_functions(source_bitdepth, fulls, fulld, sse2, sse4, avx2, conv_function, conv_function_chroma, conv_function_a);\n#else\n      get_convert_uintN_to_float_functions(source_bitdepth, fulls, fulld, conv_function, conv_function_chroma, conv_function_a);\n#endif\n    else\n      get_convert_float_to_float_functions(fulls, fulld, conv_function, conv_function_chroma, conv_function_a);\n  }\n}\n\n\nConvertBits::ConvertBits(PClip _child, const int _dither_mode, const int _target_bitdepth, bool _truerange,\n  int _ColorRange_src, int _ColorRange_dest,\n  int _dither_bitdepth, IScriptEnvironment* env) :\n  GenericVideoFilter(_child),\n  conv_function(nullptr), conv_function_chroma(nullptr), conv_function_a(nullptr),\n  target_bitdepth(_target_bitdepth), dither_mode(_dither_mode), dither_bitdepth(_dither_bitdepth),\n  fulls(false), fulld(false), truerange(_truerange)\n{\n\n  pixelsize = vi.ComponentSize();\n  bits_per_pixel = vi.BitsPerComponent();\n  format_change_only = false;\n\n#ifdef INTEL_INTRINSICS\n  const bool sse2 = !!(env->GetCPUFlags() & CPUF_SSE2);\n  const bool sse4 = !!(env->GetCPUFlags() & CPUF_SSE4_1);\n  const bool avx2 = !!(env->GetCPUFlags() & CPUF_AVX2);\n#endif\n\n  // full or limited decision\n  // dest: if undefined, use src\n  if (_ColorRange_dest != ColorRange_Compat_e::AVS_COLORRANGE_LIMITED && _ColorRange_dest != ColorRange_Compat_e::AVS_COLORRANGE_FULL) {\n    _ColorRange_dest = _ColorRange_src;\n  }\n  //\n  fulls = _ColorRange_src == ColorRange_Compat_e::AVS_COLORRANGE_FULL;\n  fulld = _ColorRange_dest == ColorRange_Compat_e::AVS_COLORRANGE_FULL;\n\n  if (!truerange) {\n    if ((target_bitdepth == 8 || target_bitdepth == 32) && pixelsize == 2)\n      bits_per_pixel = 16;\n    if (target_bitdepth > 8 && target_bitdepth <= 16 && (bits_per_pixel == 8 || bits_per_pixel == 32))\n      target_bitdepth = 16;\n    if (target_bitdepth > 8 && target_bitdepth <= 16 && bits_per_pixel > 8 && bits_per_pixel <= 16)\n      format_change_only = true;\n  }\n\n#ifdef INTEL_INTRINSICS\n  get_convert_any_bits_functions(dither_mode, bits_per_pixel, target_bitdepth, fulls, fulld, sse2, sse4, avx2, conv_function, conv_function_chroma, conv_function_a);\n#else\n  get_convert_any_bits_functions(dither_mode, bits_per_pixel, target_bitdepth, fulls, fulld, conv_function, conv_function_chroma, conv_function_a);\n#endif\n\n  // Set VideoInfo\n  if (target_bitdepth == 8) {\n    if (vi.NumComponents() == 1)\n      vi.pixel_type = VideoInfo::CS_Y8;\n    else if (vi.IsYV411())\n      vi.pixel_type = VideoInfo::CS_YV411;\n    else if (vi.Is420() || vi.IsYV12())\n      vi.pixel_type = vi.IsYUVA() ? VideoInfo::CS_YUVA420 : VideoInfo::CS_YV12;\n    else if (vi.Is422())\n      vi.pixel_type = vi.IsYUVA() ? VideoInfo::CS_YUVA422 : VideoInfo::CS_YV16;\n    else if (vi.Is444())\n      vi.pixel_type = vi.IsYUVA() ? VideoInfo::CS_YUVA444 : VideoInfo::CS_YV24;\n    else if (vi.IsRGB48() || vi.IsRGB24())\n      vi.pixel_type = VideoInfo::CS_BGR24;\n    else if (vi.IsRGB64() || vi.IsRGB32())\n      vi.pixel_type = VideoInfo::CS_BGR32;\n    else if (vi.IsPlanarRGB())\n      vi.pixel_type = VideoInfo::CS_RGBP;\n    else if (vi.IsPlanarRGBA())\n      vi.pixel_type = VideoInfo::CS_RGBAP;\n    else\n      env->ThrowError(\"ConvertTo8bit: unsupported color space\");\n\n    return;\n  }\n  else if (target_bitdepth > 8 && target_bitdepth <= 16) {\n    // set output vi format\n    if (vi.IsRGB24() || vi.IsRGB48()) {\n      vi.pixel_type = VideoInfo::CS_BGR48;\n    }\n    else if (vi.IsRGB32() || vi.IsRGB64()) {\n      vi.pixel_type = VideoInfo::CS_BGR64;\n    }\n    else {\n      // Y or YUV(A) or PlanarRGB(A)\n      if (vi.IsYV12()) // YV12 can have an exotic compatibility constant\n        vi.pixel_type = VideoInfo::CS_YV12; // override for known\n      int new_bitdepth_bits;\n      switch (target_bitdepth) {\n      case 8: new_bitdepth_bits = VideoInfo::CS_Sample_Bits_8; break;\n      case 10: new_bitdepth_bits = VideoInfo::CS_Sample_Bits_10; break;\n      case 12: new_bitdepth_bits = VideoInfo::CS_Sample_Bits_12; break;\n      case 14: new_bitdepth_bits = VideoInfo::CS_Sample_Bits_14; break;\n      case 16: new_bitdepth_bits = VideoInfo::CS_Sample_Bits_16; break;\n      case 32: new_bitdepth_bits = VideoInfo::CS_Sample_Bits_32; break;\n      }\n      vi.pixel_type = (vi.pixel_type & ~VideoInfo::CS_Sample_Bits_Mask) | new_bitdepth_bits;\n    }\n    return;\n  }\n  else if (target_bitdepth == 32) {\n    if (vi.NumComponents() == 1)\n      vi.pixel_type = VideoInfo::CS_Y32;\n    else if (vi.Is420())\n      vi.pixel_type = vi.IsYUVA() ? VideoInfo::CS_YUVA420PS : VideoInfo::CS_YUV420PS;\n    else if (vi.Is422())\n      vi.pixel_type = vi.IsYUVA() ? VideoInfo::CS_YUVA422PS : VideoInfo::CS_YUV422PS;\n    else if (vi.Is444())\n      vi.pixel_type = vi.IsYUVA() ? VideoInfo::CS_YUVA444PS : VideoInfo::CS_YUV444PS;\n    else if (vi.IsPlanarRGB())\n      vi.pixel_type = VideoInfo::CS_RGBPS;\n    else if (vi.IsPlanarRGBA())\n      vi.pixel_type = VideoInfo::CS_RGBAPS;\n    else\n      env->ThrowError(\"ConvertToFloat: unsupported color space\");\n\n    return;\n  }\n\n  env->ThrowError(\"ConvertBits: unsupported target bit-depth (%d)\", target_bitdepth);\n\n}\n\nAVSValue __cdecl ConvertBits::Create(AVSValue args, void* user_data, IScriptEnvironment* env) {\n  PClip clip = args[0].AsClip();\n  //0   1        2        3         4         5           6\n  //c[bits]i[truerange]b[dither]i[dither_bits]i[fulls]b[fulld]b\n\n  const VideoInfo &vi = clip->GetVideoInfo();\n\n  int create_param = (int)reinterpret_cast<intptr_t>(user_data);\n\n  // when converting from/true 10-16 bit formats, truerange=false indicates bitdepth of 16 bits regardless of the 10-12-14 bit format\n  // FIXME: stop supporting this parameter (a workaround in the dawn of hbd?)\n  bool assume_truerange = args[2].AsBool(true); // n/a for non planar formats\n\n  int source_bitdepth = vi.BitsPerComponent();\n  // default comes from old legacy To8,To16,ToFloat functions\n  // or the clip's actual bit depth\n  const int default_target_bitdepth = create_param == 0 ? source_bitdepth : create_param;\n  int target_bitdepth = args[1].AsInt(default_target_bitdepth); // \"bits\" parameter\n  int dither_bitdepth = args[4].AsInt(target_bitdepth); // \"dither_bits\" parameter\n\n  if(target_bitdepth!=8 && target_bitdepth!=10 && target_bitdepth!=12 && target_bitdepth!=14 && target_bitdepth!=16 && target_bitdepth!=32)\n    env->ThrowError(\"ConvertBits: invalid bit depth: %d\", target_bitdepth);\n\n  if(create_param == 8 && target_bitdepth !=8)\n    env->ThrowError(\"ConvertTo8Bit: invalid bit depth: %d\", target_bitdepth);\n  if(create_param == 32 && target_bitdepth !=32)\n    env->ThrowError(\"ConvertToFloat: invalid bit depth: %d\", target_bitdepth);\n  if(create_param == 16 && (target_bitdepth == 8 || target_bitdepth ==32))\n    env->ThrowError(\"ConvertTo16bit: invalid bit depth: %d\", target_bitdepth);\n\n  if (args[2].Defined()) {\n    if (!vi.IsPlanar())\n      env->ThrowError(\"ConvertBits: truerange specified for non-planar source\");\n  }\n\n  // retrieve full/limited\n  int ColorRange_src;\n  int ColorRange_dest;\n  if (args[5].Defined())\n    ColorRange_src = args[5].AsBool() ? ColorRange_Compat_e::AVS_COLORRANGE_FULL : ColorRange_Compat_e::AVS_COLORRANGE_LIMITED;\n  else\n    ColorRange_src = -1; // undefined. A frame property may override\n  if (args[6].Defined())\n    ColorRange_dest = args[6].AsBool() ? ColorRange_Compat_e::AVS_COLORRANGE_FULL : ColorRange_Compat_e::AVS_COLORRANGE_LIMITED;\n  else\n    ColorRange_dest = -1; // undefined. A frame property or ColorRange_src may override\n  if (ColorRange_src != ColorRange_Compat_e::AVS_COLORRANGE_LIMITED && ColorRange_src != ColorRange_Compat_e::AVS_COLORRANGE_FULL) {\n    // try getting frame props if parameter is not specified\n    auto frame0 = clip->GetFrame(0, env);\n    const AVSMap* props = env->getFramePropsRO(frame0);\n    if (env->propNumElements(props, \"_ColorRange\") > 0) {\n      ColorRange_src = (int)env->propGetIntSaturated(props, \"_ColorRange\", 0, nullptr);\n    }\n    else {\n      // no param, no frame property -> rgb is full others are limited\n      ColorRange_src = vi.IsRGB() ? ColorRange_Compat_e::AVS_COLORRANGE_FULL : ColorRange_Compat_e::AVS_COLORRANGE_LIMITED;\n    }\n  }\n  // cr_dest = cr_source if not specified\n  if (ColorRange_dest != ColorRange_Compat_e::AVS_COLORRANGE_LIMITED && ColorRange_dest != ColorRange_Compat_e::AVS_COLORRANGE_FULL) {\n    ColorRange_dest = ColorRange_src;\n  }\n  bool fulls = ColorRange_src == ColorRange_Compat_e::AVS_COLORRANGE_FULL;\n  bool fulld = ColorRange_dest == ColorRange_Compat_e::AVS_COLORRANGE_FULL;\n\n\n  int dither_type = args[3].AsInt(-1);\n  bool dither_defined = args[3].Defined();\n  if(dither_defined && dither_type != 1 && dither_type != 0 && dither_type != -1)\n    env->ThrowError(\"ConvertBits: invalid dither type parameter. Only -1 (disabled), 0 (ordered dither) or 1 (Floyd-S) is allowed\");\n\n  if (dither_type >= 0) {\n    if (source_bitdepth < target_bitdepth)\n      env->ThrowError(\"ConvertBits: dithering is allowed only for scale down\");\n    if (dither_bitdepth > target_bitdepth)\n      env->ThrowError(\"ConvertBits: dither_bits must be <= target bitdepth\");\n    if (target_bitdepth == 32)\n      env->ThrowError(\"ConvertBits: dithering is not allowed into 32 bit float target\");\n  }\n\n  // 3.7.1 t25\n  // Unfortunately 32 bit float dithering is not implemented, thus we convert to 16 bit \n  // intermediate clip\n  if (source_bitdepth == 32 && (dither_type == 0 || dither_type == 1)) {\n    // c[bits]i[truerange]b[dither]i[dither_bits]i[fulls]b[fulld]b\n\n    source_bitdepth = 16;\n    // solving ordered dither maximum bit depth difference of 8 problem\n    // by automatic preconversion\n    if (dither_type == 0 && source_bitdepth - dither_bitdepth > 8) {\n      source_bitdepth = dither_bitdepth + 8;\n      if (source_bitdepth % 2)\n        source_bitdepth--; // must be even\n    }\n    \n    AVSValue new_args[7] = { clip, source_bitdepth, true, -1 /* no dither */, AVSValue() /*dither_bits*/, fulls, fulld };\n    clip = env->Invoke(\"ConvertBits\", AVSValue(new_args, 7)).AsClip();\n\n    clip = env->Invoke(\"Cache\", AVSValue(clip)).AsClip();\n    // and now the source range becomes the previous target\n    fulls = fulld;\n    ColorRange_src = ColorRange_dest;\n  }\n\n  // solving ordered dither maximum bit depth difference of 8 problem\n  // by automatic preconversion\n  if (source_bitdepth <= 16 && dither_type == 0 && source_bitdepth - dither_bitdepth > 8) {\n    // c[bits]i[truerange]b[dither]i[dither_bits]i[fulls]b[fulld]b\n    source_bitdepth = dither_bitdepth + 8;\n    if (source_bitdepth % 2)\n      source_bitdepth--; // must be even\n\n    AVSValue new_args[7] = { clip, source_bitdepth, true, -1 /* no dither */, AVSValue() /*dither_bits*/, fulls, fulld };\n    clip = env->Invoke(\"ConvertBits\", AVSValue(new_args, 7)).AsClip();\n\n    clip = env->Invoke(\"Cache\", AVSValue(clip)).AsClip();\n    // and now the source range becomes the previous target\n    fulls = fulld;\n    ColorRange_src = ColorRange_dest;\n  }\n\n  if (source_bitdepth == dither_bitdepth)\n    dither_type = -1; // ignore dithering\n\n  if(dither_type == 0) {\n    if (dither_bitdepth < 1 || dither_bitdepth > 16)\n      env->ThrowError(\"ConvertBits: ordered dither: invalid dither_bits specified (1-16 allowed)\");\n\n    // this error message cannot appear if the automatic bit depth reducing conversions above are done\n    if(source_bitdepth - dither_bitdepth > 8)\n      env->ThrowError(\"ConvertBits: dither_bits cannot differ with more than 8 bits from source\");\n  }\n\n  // floyd\n  if (dither_type == 1) {\n    if (dither_bitdepth < 1 || dither_bitdepth > 16)\n      env->ThrowError(\"ConvertBits: Floyd-S: invalid dither_bits specified (1-16 allowed)\");\n  }\n\n  // no change -> return unmodified if no transform required\n  if (source_bitdepth == target_bitdepth) { // 10->10 .. 16->16\n    if((dither_type < 0 || dither_bitdepth == target_bitdepth) && fulls == fulld)\n      return clip;\n  }\n\n  // YUY2 conversion is limited\n  if (vi.IsYUY2()) {\n    if (target_bitdepth != 8)\n      env->ThrowError(\"ConvertBits: YUY2 input must stay in 8 bits\");\n  }\n\n  if (vi.IsYV411()) {\n    if (target_bitdepth != 8)\n      env->ThrowError(\"ConvertBits: YV411 input must stay in 8 bits\");\n  }\n\n  // packed RGB conversion is limited\n  if (vi.IsRGB() && !vi.IsPlanar()) {\n    if (target_bitdepth != 8 && target_bitdepth != 16)\n      env->ThrowError(\"ConvertBits: invalid bit-depth for packed RGB formats, only 8 or 16 possible\");\n  }\n\n    // remark\n    // source_10_bit.ConvertTo16bit(truerange=true)  : upscale range\n    // source_10_bit.ConvertTo16bit(truerange=false) : leaves data, only format conversion\n    // source_10_bit.ConvertTo16bit(bits=12,truerange=true)  : upscale range from 10 to 12\n    // source_10_bit.ConvertTo16bit(bits=12,truerange=false) : leaves data, only format conversion\n    // source_16_bit.ConvertTo16bit(bits=10, truerange=true)  : downscale range\n    // source_16_bit.ConvertTo16bit(bits=10, truerange=false) : leaves data, only format conversion\n\n  // yuy2 is autoconverted to/from YV16. fulls-fulld and dither to lower bit depths are supported\n  bool need_convert_yuy2 = vi.IsYUY2();\n  // for dither, planar rgb conversion happens\n  bool need_convert_24 = vi.IsRGB24() && dither_type >= 0;\n  bool need_convert_32 = vi.IsRGB32() && dither_type >= 0;\n  bool need_convert_48 = vi.IsRGB48() && dither_type >= 0;\n  bool need_convert_64 = vi.IsRGB64() && dither_type >= 0;\n\n  // convert to planar on the fly if dither was asked\n  if (need_convert_24 || need_convert_48) {\n    AVSValue new_args[1] = { clip };\n    clip = env->Invoke(\"ConvertToPlanarRGB\", AVSValue(new_args, 1)).AsClip();\n  }\n  else if (need_convert_32 || need_convert_64) {\n    AVSValue new_args[1] = { clip };\n    clip = env->Invoke(\"ConvertToPlanarRGBA\", AVSValue(new_args, 1)).AsClip();\n  }\n  else if (need_convert_yuy2) {\n    AVSValue new_args[1] = { clip };\n    clip = env->Invoke(\"ConvertToYV16\", AVSValue(new_args, 1)).AsClip();\n  }\n\n  AVSValue result = new ConvertBits(clip, dither_type, target_bitdepth, assume_truerange, ColorRange_src, ColorRange_dest, dither_bitdepth, env);\n\n  // convert back to packed rgb from planar on the fly\n  if (need_convert_24 || need_convert_48) {\n    AVSValue new_args[1] = { result };\n    if(target_bitdepth == 8)\n      result = env->Invoke(\"ConvertToRGB24\", AVSValue(new_args, 1)).AsClip();\n    else\n      result = env->Invoke(\"ConvertToRGB48\", AVSValue(new_args, 1)).AsClip();\n  } else if (need_convert_32 || need_convert_64) {\n    AVSValue new_args[1] = { result };\n    if (target_bitdepth == 8)\n      result = env->Invoke(\"ConvertToRGB32\", AVSValue(new_args, 1)).AsClip();\n    else\n      result = env->Invoke(\"ConvertToRGB64\", AVSValue(new_args, 1)).AsClip();\n  }\n  else if (need_convert_yuy2) {\n    AVSValue new_args[1] = { result };\n    result = env->Invoke(\"ConvertToYUY2\", AVSValue(new_args, 1)).AsClip();\n  }\n\n  return result;\n}\n\n\nPVideoFrame __stdcall ConvertBits::GetFrame(int n, IScriptEnvironment* env) {\n  PVideoFrame src = child->GetFrame(n, env);\n\n  if (format_change_only)\n  {\n    // for 10-16 bit: simple format override in constructor\n    env->MakeWritable(&src);\n    src->AmendPixelType(vi.pixel_type);\n    return src;\n  }\n\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n\n  auto props = env->getFramePropsRW(dst);\n  update_ColorRange(props, fulld ? ColorRange_Compat_e::AVS_COLORRANGE_FULL : ColorRange_Compat_e::AVS_COLORRANGE_LIMITED, env);\n\n  if(vi.IsPlanar())\n  {\n    int planes_y[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };\n    int planes_r[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A };\n    int *planes = (vi.IsYUV() || vi.IsYUVA()) ? planes_y : planes_r;\n    for (int p = 0; p < vi.NumComponents(); ++p) {\n      const int plane = planes[p];\n      if (plane == PLANAR_A) {\n        if (conv_function_a == nullptr)\n          env->BitBlt(dst->GetWritePtr(plane), dst->GetPitch(plane), src->GetReadPtr(plane), src->GetPitch(plane), src->GetRowSize(plane), src->GetHeight(plane));\n        else\n          conv_function_a(src->GetReadPtr(plane), dst->GetWritePtr(plane),\n            src->GetRowSize(plane), src->GetHeight(plane),\n            src->GetPitch(plane), dst->GetPitch(plane),\n            bits_per_pixel, target_bitdepth, dither_bitdepth\n          );\n      }\n      else if (conv_function == nullptr)\n        env->BitBlt(dst->GetWritePtr(plane), dst->GetPitch(plane), src->GetReadPtr(plane), src->GetPitch(plane), src->GetRowSize(plane), src->GetHeight(plane));\n      else {\n        const bool chroma = (plane == PLANAR_U || plane == PLANAR_V);\n        if (chroma && conv_function_chroma != nullptr)\n          // 32bit float and 8-16 when full-range involved needs separate signed-aware conversion\n          conv_function_chroma(src->GetReadPtr(plane), dst->GetWritePtr(plane),\n            src->GetRowSize(plane), src->GetHeight(plane),\n            src->GetPitch(plane), dst->GetPitch(plane),\n            bits_per_pixel, target_bitdepth, dither_bitdepth);\n        else\n          conv_function(src->GetReadPtr(plane), dst->GetWritePtr(plane),\n            src->GetRowSize(plane), src->GetHeight(plane),\n            src->GetPitch(plane), dst->GetPitch(plane),\n            bits_per_pixel, target_bitdepth, dither_bitdepth);\n      }\n    }\n  }\n  else {\n    // packed RGBs\n    conv_function(src->GetReadPtr(), dst->GetWritePtr(),\n      src->GetRowSize(), src->GetHeight(),\n      src->GetPitch(), dst->GetPitch(),\n      bits_per_pixel, target_bitdepth, dither_bitdepth);\n  }\n  return dst;\n}\n"
  },
  {
    "path": "avs_core/convert/convert_bits.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Convert_bits_H__\n#define __Convert_bits_H__\n\n#include <avisynth.h>\n#include <stdint.h>\n#include \"convert.h\"\n\n\n// in convert_bits.cpp\n// repeated 8x for sse size 16\nextern const BYTE dither2x2a_data[4];\n// cycle: 2\nextern const BYTE dither2x2a_data_sse2[2 * 16];\n// e.g. 10->8 bits\n// repeated 8x for sse size 16\nextern const BYTE dither2x2_data[4];\n// cycle: 2\nextern const BYTE dither2x2_data_sse2[2 * 16];\n// e.g. 8->5 bits\nextern const BYTE dither4x4a_data[16];\n// cycle: 4\nextern const BYTE dither4x4a_data_sse2[4 * 16];\n// e.g. 12->8 bits\nextern const BYTE dither4x4_data[16];\n// cycle: 4\nextern const BYTE dither4x4_data_sse2[4 * 16];\n// e.g. 14->9 bits\nextern const BYTE dither8x8a_data[8][8];\n// cycle: 8\nextern const BYTE dither8x8a_data_sse2[8][16];\n// e.g. 14->8 bits\nextern const BYTE dither8x8_data[8][8];\n// cycle: 8\nextern const BYTE dither8x8_data_sse2[8][16];\n// e.g. 16->9 or 8->1 bits\n// cycle: 16x. No special 16 byte sse2\nextern const BYTE dither16x16a_data[16][16];\n// 16->8\n// cycle: 16x. No special 16 byte sse2\nextern const BYTE dither16x16_data[16][16];\n\ntypedef void (*BitDepthConvFuncPtr)(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\n\nclass ConvertBits : public GenericVideoFilter\n{\npublic:\n  ConvertBits(PClip _child, const int _dither_mode, const int _target_bitdepth, bool _truerange, int _ColorRange_src, int _ColorRange_dest, int _dither_bitdepth, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n,IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\nprivate:\n  BitDepthConvFuncPtr conv_function;\n  BitDepthConvFuncPtr conv_function_chroma; // 32bit float YUV chroma\n  BitDepthConvFuncPtr conv_function_a;\n  int target_bitdepth;\n  int dither_mode;\n  int dither_bitdepth;\n  bool fulls; // source is full range (defaults: rgb=true, yuv=false (bit shift))\n  bool fulld; // destination is full range (defaults: rgb=true, yuv=false (bit shift))\n  bool truerange; // if 16->10 range reducing or e.g. 14->16 bit range expansion needed\n  int pixelsize;\n  int bits_per_pixel;\n  bool format_change_only;\n};\n\nvoid get_convert_any_bits_functions(int dither_mode, int source_bitdepth, int target_bitdepth, bool fulls, bool fulld,\n#ifdef INTEL_INTRINSICS\n  bool sse2, bool sse4, bool avx2,\n#endif\n  BitDepthConvFuncPtr& conv_function, BitDepthConvFuncPtr& conv_function_chroma, BitDepthConvFuncPtr& conv_function_a);\n\n/**********************************\n******  Bitdepth conversions  *****\n**********************************/\n\n#endif // __Convert_bits_H__\n"
  },
  {
    "path": "avs_core/convert/convert_helper.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002-2009 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include <avisynth.h>\n#ifdef AVS_WINDOWS\n#include <avs/win.h>\n#else\n#include <avs/posix.h>\n#endif \n\n#include \"convert_matrix.h\"\n#include \"convert_helper.h\"\n\n#include <unordered_map>\n#include <iostream>\n#include <vector>\n#include <sstream>\n\nconst std::vector<std::pair<const char*, ColorRange_Compat_e>> g_range_table{\n    { \"limited\", AVS_COLORRANGE_LIMITED },\n    { \"full\",    AVS_COLORRANGE_FULL },\n    { \"l\",       AVS_COLORRANGE_LIMITED },\n    { \"f\",       AVS_COLORRANGE_FULL },\n};\n\nconst std::vector<std::pair<const char*, ChromaLocation_e>> g_chromaloc_table{\n    { \"left\",        AVS_CHROMA_LEFT },\n    { \"center\",      AVS_CHROMA_CENTER },\n    { \"top_left\",    AVS_CHROMA_TOP_LEFT },\n    { \"top\",         AVS_CHROMA_TOP }, // not used in Avisynth\n    { \"bottom_left\", AVS_CHROMA_BOTTOM_LEFT }, // not used in Avisynth\n    { \"bottom\",      AVS_CHROMA_BOTTOM }, // not used in Avisynth\n    { \"dv\",          AVS_CHROMA_DV }, // Special to Avisynth\n    // compatibility\n    { \"mpeg1\",       AVS_CHROMA_CENTER },\n    { \"mpeg2\",       AVS_CHROMA_LEFT },\n    { \"jpeg\",        AVS_CHROMA_CENTER },\n};\n\n// unlike Avisynth conventions, the strings do not contain hints on full or limited range\n// e.g. PC.709 or Rec709\nconst std::vector<std::pair<const char*, Matrix_e>> g_matrix_table{\n    { \"rgb\",         AVS_MATRIX_RGB },\n    { \"709\",         AVS_MATRIX_BT709 },\n    { \"unspec\",      AVS_MATRIX_UNSPECIFIED },\n    { \"170m\",        AVS_MATRIX_ST170_M },\n    { \"240m\",        AVS_MATRIX_ST240_M },\n    { \"470bg\",       AVS_MATRIX_BT470_BG },\n    { \"fcc\",         AVS_MATRIX_BT470_M },\n    { \"470m\",        AVS_MATRIX_BT470_M }, // as of 20211111 name is an add-on in Avisynth+\n    { \"ycgco\",       AVS_MATRIX_YCGCO },\n    { \"2020ncl\",     AVS_MATRIX_BT2020_NCL },\n    { \"2020cl\",      AVS_MATRIX_BT2020_CL },\n    { \"chromacl\",    AVS_MATRIX_CHROMATICITY_DERIVED_CL },\n    { \"chromancl\",   AVS_MATRIX_CHROMATICITY_DERIVED_NCL },\n    { \"ictcp\",       AVS_MATRIX_ICTCP },\n    // compatibility\n    { \"601\",         AVS_MATRIX_BT470_BG },\n    { \"2020\",        AVS_MATRIX_BT2020_NCL },\n};\n\n// old Avisynth \"matrix\" parameter strings\nconst std::vector<std::pair<const char*, Old_Avs_Matrix_e>> g_old_avs_matrix_table{\n    { \"rec601\",      AVS_OLD_MATRIX_Rec601 },\n    { \"rec709\",      AVS_OLD_MATRIX_Rec709 },\n    { \"pc.601\",      AVS_OLD_MATRIX_PC_601 },\n    { \"pc.709\",      AVS_OLD_MATRIX_PC_709 },\n    { \"pc601\",       AVS_OLD_MATRIX_PC_601 },\n    { \"pc709\",       AVS_OLD_MATRIX_PC_709 },\n    { \"average\",     AVS_OLD_MATRIX_AVERAGE },\n    { \"rec2020\",     AVS_OLD_MATRIX_Rec2020 },\n    { \"pc.2020\",     AVS_OLD_MATRIX_PC_2020 },\n    { \"pc2020\",      AVS_OLD_MATRIX_PC_2020 }\n};\n\n// not used in Avisynth (yet)\nconst std::vector<std::pair<const char*, Transfer_e>> g_transfer_table{\n    { \"709\",     AVS_TRANSFER_BT709 },\n    { \"unspec\",  AVS_TRANSFER_UNSPECIFIED },\n    { \"601\",     AVS_TRANSFER_BT601 },\n    { \"linear\",  AVS_TRANSFER_LINEAR },\n    { \"2020_10\", AVS_TRANSFER_BT2020_10 },\n    { \"2020_12\", AVS_TRANSFER_BT2020_12 },\n    { \"240m\",    AVS_TRANSFER_ST240_M },\n    { \"470m\",    AVS_TRANSFER_BT470_M },\n    { \"470bg\",   AVS_TRANSFER_BT470_BG },\n    { \"log100\",  AVS_TRANSFER_LOG_100 },\n    { \"log316\",  AVS_TRANSFER_LOG_316 },\n    { \"st2084\",  AVS_TRANSFER_ST2084 },\n    { \"std-b67\", AVS_TRANSFER_ARIB_B67 },\n    { \"srgb\",    AVS_TRANSFER_IEC_61966_2_1 },\n    { \"xvycc\",   AVS_TRANSFER_IEC_61966_2_4 },\n};\n\n// not used in Avisynth (yet)\nconst std::vector<std::pair<const char*, Primaries_e>> g_primaries_table{\n    { \"709\",       AVS_PRIMARIES_BT709 },\n    { \"unspec\",    AVS_PRIMARIES_UNSPECIFIED },\n    { \"170m\",      AVS_PRIMARIES_ST170_M },\n    { \"240m\",      AVS_PRIMARIES_ST240_M },\n    { \"470m\",      AVS_PRIMARIES_BT470_M },\n    { \"470bg\",     AVS_PRIMARIES_BT470_BG },\n    { \"film\",      AVS_PRIMARIES_FILM },\n    { \"2020\",      AVS_PRIMARIES_BT2020 },\n    { \"st428\",     AVS_PRIMARIES_ST428 },\n    { \"xyz\",       AVS_PRIMARIES_ST428 },\n    { \"st431-2\",   AVS_PRIMARIES_ST431_2 },\n    { \"st432-1\",   AVS_PRIMARIES_ST432_1 },\n    { \"ebu3213-e\", AVS_PRIMARIES_EBU3213_E },\n};\n\n// -1: null input or empty string\n// -2: not found\n// table index otherwise\ntemplate<class T>\nauto lookup_table(const std::vector<std::pair<const char *, T>>& table, const char* key) {\n  if (key == nullptr) return -1;\n  if (*key == 0) return -1;\n  auto it = std::find_if(table.begin(), table.end(),\n    [&key](const auto& element) { return !lstrcmpi(element.first, key); });\n  return it != std::end(table) ? it->second : -2;\n}\n\nbool getPrimaries(const char* primaries_name, IScriptEnvironment* env, int& _Primaries) {\n  auto index = lookup_table<Primaries_e>(g_primaries_table, primaries_name);\n  if (index >= 0) {\n    _Primaries = index;\n    return true;\n  }\n\n  if (index == -2) // not found\n    env->ThrowError(\"Convert: Unknown Primaries\");\n\n  // empty\n  return false;\n}\n\nstatic bool getMatrix(const char* matrix_name, IScriptEnvironment* env, int& _Matrix) {\n  auto index = lookup_table<Matrix_e>(g_matrix_table, matrix_name);\n  if (index >= 0) {\n    _Matrix = index;\n    return true;\n  }\n\n  if (index == -2) // not found\n    env->ThrowError(\"Convert: Unknown matrix\");\n\n  // empty\n  return false;\n}\n\nstatic bool getChromaLocation(const char* chromaloc_name, IScriptEnvironment* env, int& _ChromaLocation) {\n  auto index = lookup_table<ChromaLocation_e>(g_chromaloc_table, chromaloc_name);\n  if (index >= 0) {\n    _ChromaLocation = index;\n    return true;\n  }\n\n  if (index == -2) // not found\n    env->ThrowError(\"Unknown chroma placement\");\n\n  // empty\n  return false;\n}\n\nbool getColorRange(const char* color_range_name, IScriptEnvironment* env, int& _ColorRange) {\n  auto color_range_enum = lookup_table<ColorRange_Compat_e>(g_range_table, color_range_name);\n  if (color_range_enum >= 0) {\n    _ColorRange = color_range_enum;\n    return true;\n  }\n\n  if (color_range_enum == -2) // not found\n    env->ThrowError(\"Convert: Unknown color range, must be 'auto', 'full', 'f', 'limited' or 'l'\");\n  \n  // empty\n  return false;\n\n}\n\n// Converts old-style Avisynth matrix to separated _Matrix and _ColorRange values\n// if not found or empty, returns false, does not throw exception.\n// _ColorRange for matrix generation\n// _ColorRange_Out for desired output range, can be set even to nothing for PC.xxx matrices \nstatic bool getOldMatrix(const char* matrix_name, int &_Matrix, int &_ColorRange) {\n  auto old_matrix_enum = lookup_table<Old_Avs_Matrix_e>(g_old_avs_matrix_table, matrix_name);\n  if (old_matrix_enum < 0)\n    return false; // not found or empty\n\n  switch (old_matrix_enum) {\n  case Old_Avs_Matrix_e::AVS_OLD_MATRIX_Rec601:\n    _Matrix = Matrix_e::AVS_MATRIX_ST170_M;\n    _ColorRange = ColorRange_Compat_e::AVS_COLORRANGE_LIMITED;\n    break;\n  case Old_Avs_Matrix_e::AVS_OLD_MATRIX_PC_601:\n    _Matrix = Matrix_e::AVS_MATRIX_ST170_M;\n    _ColorRange = -1; // better no change the range ColorRange_Compat_e::AVS_COLORRANGE_FULL;\n    break;\n  case Old_Avs_Matrix_e::AVS_OLD_MATRIX_Rec709:\n    _Matrix = Matrix_e::AVS_MATRIX_BT709;\n    _ColorRange = ColorRange_Compat_e::AVS_COLORRANGE_LIMITED;\n    break;\n  case Old_Avs_Matrix_e::AVS_OLD_MATRIX_PC_709:\n    _Matrix = Matrix_e::AVS_MATRIX_BT709;\n    _ColorRange = -1; // better no change the range ColorRange_Compat_e::AVS_COLORRANGE_FULL;\n    break;\n  case Old_Avs_Matrix_e::AVS_OLD_MATRIX_Rec2020:\n    _Matrix = Matrix_e::AVS_MATRIX_BT2020_NCL;\n    _ColorRange = ColorRange_Compat_e::AVS_COLORRANGE_LIMITED;\n    break;\n  case Old_Avs_Matrix_e::AVS_OLD_MATRIX_PC_2020:\n    _Matrix = Matrix_e::AVS_MATRIX_BT2020_NCL;\n    _ColorRange = -1; // better no change the range ColorRange_Compat_e::AVS_COLORRANGE_FULL;\n    break;\n  case Old_Avs_Matrix_e::AVS_OLD_MATRIX_AVERAGE:\n    _Matrix = Matrix_e::AVS_MATRIX_AVERAGE; // non-standard!\n    _ColorRange = -1;\n    break;\n  }\n  return true;\n}\n\n\nstatic bool is_paramstring_auto(const std::string &param) {\n  return !lstrcmpi(param.c_str(), \"auto\"); // true is match\n}\n\nstatic bool is_paramstring_same(const std::string& param) {\n  return !lstrcmpi(param.c_str(), \"same\"); // true is match\n}\n\nstatic bool is_paramstring_empty_or_auto(const std::string& param) {\n  return param.empty() || !lstrcmpi(param.c_str(), \"auto\"); // true is match\n}\n\nstatic bool is_paramstring_empty_or_auto(const char* param) {\n  if (!param)\n    return true;\n  return !lstrcmpi(param, \"auto\"); // true is match\n}\n\n// called from yuv <-> rgb and to_greyscale converters\nvoid matrix_parse_merge_with_props_def(bool rgb_in, bool rgb_out, const char* matrix_name, const AVSMap* props, int& _Matrix, int& _ColorRange, int& _ColorRange_Out, int _Matrix_Default, int _ColorRange_Default, IScriptEnvironment* env) {\n  // if once we'd like to use input colorrange when input is rgb (e.g. studio rgb of ColorBars is limited)\n  int _ColorRange_In = rgb_in ? ColorRange_Compat_e::AVS_COLORRANGE_FULL : ColorRange_Compat_e::AVS_COLORRANGE_LIMITED;\n  int _Default_ColorRange_Out = rgb_out ? ColorRange_Compat_e::AVS_COLORRANGE_FULL : ColorRange_Compat_e::AVS_COLORRANGE_LIMITED; // RGB -> YUV or YUV -> RGB\n\n  if (props) {\n    // _ColorRange exists for RGB as well\n    if (env->propNumElements(props, \"_ColorRange\") > 0) {\n      _ColorRange_In = (int)env->propGetIntSaturated(props, \"_ColorRange\", 0, nullptr);\n      _ColorRange_Default = _ColorRange_In;\n      if (rgb_in && rgb_out) // rgb in and out: keep input\n        _Default_ColorRange_Out = _ColorRange_In;\n    }\n    if (!rgb_in) {\n      if (env->propNumElements(props, \"_Matrix\") > 0) {\n        int tmp_matrix = (int)env->propGetIntSaturated(props, \"_Matrix\", 0, nullptr);\n        if (tmp_matrix != Matrix_e::AVS_MATRIX_UNSPECIFIED)\n          _Matrix_Default = tmp_matrix;\n      }\n    }\n  }\n\n  // valid values:\n  // old matrix name, optionally followed by 'auto' e.g. Rec709\n  // matrix name, optionally followed by color range e.g. 709:limited 2020:f 601:full\n  std::vector<std::string> splits;\n  std::string split;\n\n  if (matrix_name) {\n    std::istringstream ss(matrix_name);\n    while (std::getline(ss, split, ':'))\n      splits.push_back(split);\n\n    if (splits.size() > 2)\n      env->ThrowError(\"Invalid matrix specifier, too many parts\");\n  }\n\n  std::string s_matrix_name = splits.size() > 0 ? splits[0] : \"\";\n  std::string s_color_range_name = splits.size() > 1 ? splits[1] : \"\";\n\n  // PC.xxx is like xxx:same (same is not supported though)\n  // recxxx is like xxx:l (limited)\n  if (getOldMatrix(s_matrix_name.c_str(), _Matrix, _ColorRange)) {\n    // old avs syntax: single matrix names\n    if (_ColorRange < 0) {\n      // PC.xx does not suggest neither limited, not full\n      // keep input range\n      _ColorRange = _ColorRange_In; // a default range is set for getting the matrix\n      _ColorRange_Out = _ColorRange_In;\n    } else {\n      // _ColorRange was explicitely set by matrix\n      if (rgb_in) {\n        // RGB -> YUV\n        _ColorRange_Out = _ColorRange;\n        _ColorRange = _ColorRange_In; // a frame prop may override default RGB full input range\n      }\n      else {\n        // YUV -> RGB\n        // _ColorRange; // input range is defined by the matrix\n        _ColorRange_Out = _Default_ColorRange_Out;\n      }\n    }\n    if (!s_color_range_name.empty() && !is_paramstring_auto(s_color_range_name))\n      env->ThrowError(\"Error: this 'old-style' matrix string can only be followed by 'auto' color range\");\n    return;\n  }\n\n  if (is_paramstring_empty_or_auto(s_matrix_name) || !getMatrix(s_matrix_name.c_str(), env, _Matrix)) {\n    _Matrix = _Matrix_Default;\n  }\n  if (_Matrix == Matrix_e::AVS_MATRIX_UNSPECIFIED) {\n    _Matrix = _Matrix_Default;\n  }\n\n  // new in 3.7.3: same range as input's, e.g. \"709:same\" is like \"PC.709\"\n  if (is_paramstring_same(s_color_range_name)) {\n    _ColorRange = _ColorRange_In;\n    _ColorRange_Out = _ColorRange;\n  }\n  else if (is_paramstring_empty_or_auto(s_color_range_name) || !getColorRange(s_color_range_name.c_str(), env, _ColorRange)) {\n    // not specified or auto\n    // RGB -> YUV\n    // YUV -> RGB\n    _ColorRange = _ColorRange_In;\n    _ColorRange_Out = _Default_ColorRange_Out;\n  }\n  else {\n    if (rgb_in) {\n      // RGB -> YUV\n      _ColorRange_Out = _ColorRange;\n      _ColorRange = _ColorRange_In; // a frame prop may override default RGB full input range\n    }\n    else {\n      // YUV -> RGB\n      // _ColorRange; // input range is defined by the matrix\n      _ColorRange_Out = _Default_ColorRange_Out; // unlike RGB->YUV, we have no way to tell output rgb's range, it's always full\n    }\n  }\n}\n\nvoid matrix_parse_merge_with_props(bool rgb_in, bool rgb_out, const char* matrix_name, const AVSMap* props, int& _Matrix, int& _ColorRange, int& ColorRange_Out, IScriptEnvironment * env) {\n  int _Matrix_Default = Matrix_e::AVS_MATRIX_ST170_M; // Rec601 AVS_MATRIX_ST170_M (6-NTSC) and not AVS_MATRIX_BT470_BG (5-PAL)\n  int _ColorRange_Default = ColorRange_Compat_e::AVS_COLORRANGE_LIMITED;\n  matrix_parse_merge_with_props_def(rgb_in, rgb_out, matrix_name, props, _Matrix, _ColorRange, ColorRange_Out, _Matrix_Default, _ColorRange_Default, env);\n}\n\nvoid chromaloc_parse_merge_with_props(VideoInfo& vi, const char* chromaloc_name, const AVSMap* props, int& _ChromaLocation, int _ChromaLocation_Default, IScriptEnvironment* env) {\n  if (props) {\n    if (vi.Is420() || vi.Is422() || vi.IsYV411()) { // yes, YV411 can also have valid _ChromaLocation, if 'left'-ish one is given\n      if (env->propNumElements(props, \"_ChromaLocation\") > 0) {\n        _ChromaLocation_Default = (int)env->propGetIntSaturated(props, \"_ChromaLocation\", 0, nullptr);\n      }\n    }\n    else {\n      // Theoretically RGB and not subsampled formats must not have chroma location\n      if (env->propNumElements(props, \"_ChromaLocation\") > 0) {\n        // Uncommented for a while, just ignore when there is any\n        // env->ThrowError(\"Error: _ChromaLocation property found at a non-subsampled source.\");\n      }\n    }\n  }\n\n  if (is_paramstring_empty_or_auto(chromaloc_name) || !getChromaLocation(chromaloc_name, env, _ChromaLocation)) {\n    _ChromaLocation = _ChromaLocation_Default;\n  }\n}\n\nvoid export_frame_props(VideoInfo& vi, AVSMap* props, int _Matrix, int _ColorRange, IScriptEnvironment* env) {\n  // fixme: what to do with the special \"AVERAGE\" non standard matrix? Solution 1: delete entry\n  if (_Matrix == Matrix_e::AVS_MATRIX_AVERAGE)\n    env->propDeleteKey(props, \"_Matrix\");\n  else if (_Matrix < 0)\n    env->propDeleteKey(props, \"_Matrix\");\n  else\n    env->propSetInt(props, \"_Matrix\", _Matrix, AVSPropAppendMode::PROPAPPENDMODE_REPLACE);\n\n  env->propSetInt(props, \"_ColorRange\", _ColorRange, AVSPropAppendMode::PROPAPPENDMODE_REPLACE);\n}\n\n/*  avsresize:\n    The name of the frame properties that are read and set are: _ChromaLocation, _ColorRange, _Matrix, _Transfer, _Primaries\n    The frame properties read and set the corresponding numerical index of the parameters. For example: matrix \"709\" has numerical index `1` and the frame property have value of `1`.\n    If colorspace_op is not defined and there are frame properties, they are used for default source values.\n    If colorspace_op is not defined and there are no frame properties or they are not supported, default values are used as before (there are default values for matrix, range and chromaloc).\n    If colorspace_op is defined and you want to use the frame property for a source value, use \"auto\".\n    If colorspace_op is defined and you use \"auto\" without frame property, the default value for that argument will be used if exist.\n    If you use \"auto\" for argument with frame property that has value of 2 (unspec) and use anything different than \"same\" for destination, error will be raised.\n    If you use \"auto=>same\" for matrix/transfer/primaries with frame property 2 (unspec) and you want to make colorspace conversion, error will be raised. For example:\n*/\n\nvoid update_Matrix_and_ColorRange(AVSMap* props, int theMatrix, int theColorRange, IScriptEnvironment* env)\n{\n  auto set_int_if_positive = [&](const char* key, int x)\n  {\n    if (x >= 0)\n      env->propSetInt(props, key, x, AVSPropAppendMode::PROPAPPENDMODE_REPLACE);\n    else\n      env->propDeleteKey(props, key);\n  };\n\n  if (theColorRange == ColorRange_Compat_e::AVS_COLORRANGE_FULL || theColorRange == ColorRange_Compat_e::AVS_COLORRANGE_LIMITED)\n    env->propSetInt(props, \"_ColorRange\", theColorRange, AVSPropAppendMode::PROPAPPENDMODE_REPLACE);\n  else\n    env->propDeleteKey(props, \"_ColorRange\");\n\n  set_int_if_positive(\"_Matrix\", theMatrix);\n  //set_int_if_positive(\"_Transfer\", theTransferCharacteristics);\n  //set_int_if_positive(\"_Primaries\", theColorPrimaries);\n}\n\nvoid update_Transfer_and_Primaries(AVSMap* props, int theTransfer, int thePrimaries, IScriptEnvironment* env)\n{\n  auto set_int_if_positive = [&](const char* key, int x)\n    {\n      if (x >= 0)\n        env->propSetInt(props, key, x, AVSPropAppendMode::PROPAPPENDMODE_REPLACE);\n      else\n        env->propDeleteKey(props, key);\n    };\n  set_int_if_positive(\"_Transfer\", theTransfer);\n  set_int_if_positive(\"_Primaries\", thePrimaries);\n}\n\nvoid update_ChromaLocation(AVSMap* props, int theChromaLocation, IScriptEnvironment* env)\n{\n  auto set_int_if_positive = [&](const char* key, int x)\n  {\n    if (x >= 0)\n      env->propSetInt(props, key, x, AVSPropAppendMode::PROPAPPENDMODE_REPLACE);\n    else\n      env->propDeleteKey(props, key);\n  };\n\n  set_int_if_positive(\"_ChromaLocation\", theChromaLocation);\n}\n\nvoid update_ColorRange(AVSMap* props, int theColorRange, IScriptEnvironment* env)\n{\n  if (theColorRange == ColorRange_Compat_e::AVS_COLORRANGE_FULL || theColorRange == ColorRange_Compat_e::AVS_COLORRANGE_LIMITED)\n    env->propSetInt(props, \"_ColorRange\", theColorRange, AVSPropAppendMode::PROPAPPENDMODE_REPLACE);\n  else\n    env->propDeleteKey(props, \"_ColorRange\");\n}\n"
  },
  {
    "path": "avs_core/convert/convert_helper.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Convert_helper_H__\n#define __Convert_helper_H__\n\n#include <avisynth.h>\n#include <string>\n#include <cstring>\n\n// ITU-T H.265 (Table E.1)\ntypedef enum ColorRange_e {\n  AVS_RANGE_LIMITED = 0,  // video_full_range_flag = 0, studio swing, e.g. 16-235 for 8-bit luma\n  AVS_RANGE_FULL = 1,  // video_full_range_flag = 1, full swing, e.g. 0-255 for 8-bit luma\n} ColorRange_e;\n\n// Old constants borrowed from VapourSynth, which transitioned to the ITU-T H.265 standard (Table E.1)\n// Just the opposite as the standard.\ntypedef enum ColorRange_Compat_e {\n  AVS_COLORRANGE_FULL = 0,\n  AVS_COLORRANGE_LIMITED = 1\n} ColorRange_Compat_e;\n\ntypedef enum ChromaLocation_e {\n  AVS_CHROMA_UNUSED = -1,\n  AVS_CHROMA_LEFT = 0,\n  AVS_CHROMA_CENTER = 1,\n  AVS_CHROMA_TOP_LEFT = 2,\n  AVS_CHROMA_TOP = 3,\n  AVS_CHROMA_BOTTOM_LEFT = 4,\n  AVS_CHROMA_BOTTOM = 5,\n  AVS_CHROMA_DV = 6 // Special to Avisynth\n} ChromaLocation_e;\n\ntypedef enum FieldBased_e {\n  AVS_FIELD_PROGRESSIVE = 0,\n  AVS_FIELD_BOTTOM = 1,\n  AVS_FIELD_TOP = 2\n} FieldBased_e;\n\n// https://www.itu.int/rec/T-REC-H.265-202108-I\n/* ITU-T H.265 Table E.5 */\ntypedef enum Matrix_e {\n  AVS_MATRIX_RGB = 0, /* The identity matrix. Typically used for RGB, may also be used for XYZ */\n  AVS_MATRIX_BT709 = 1, /* ITU-R Rec. BT.709-5 */\n  AVS_MATRIX_UNSPECIFIED = 2, /* Image characteristics are unknown or are determined by the application */\n  AVS_MATRIX_BT470_M = 4, // instead of AVS_MATRIX_FCC\n  // FCC Title 47 Code of Federal Regulations (2003) 73.682 (a) (20)\n  // Rec. ITU-R BT.470-6 System M (historical)\n  AVS_MATRIX_BT470_BG = 5, /* Equivalent to 6. */\n  // ITU-R Rec. BT.470-6 System B, G (historical)\n  // Rec. ITU-R BT.601-7 625\n  // Rec. ITU-R BT.1358-0 625 (historical)\n  // Rec. ITU-R BT.1700-0 625 PAL and 625 SECAM\n  AVS_MATRIX_ST170_M = 6,  /* Equivalent to 5. */\n  // Rec. ITU-R BT.601-7 525\n  // Rec. ITU-R BT.1358-1 525 or 625 (historical)\n  // Rec. ITU-R BT.1700-0 NTSC\n  // SMPTE ST 170 (2004)\n  // SMPTE 170M (2004)\n  AVS_MATRIX_ST240_M = 7, // SMPTE ST 240 (1999, historical)\n  AVS_MATRIX_YCGCO = 8,\n  AVS_MATRIX_BT2020_NCL = 9, \n  // Rec. ITU-R BT.2020 non-constant luminance system\n  // Rec. ITU-R BT.2100-2 Y'CbCr\n  AVS_MATRIX_BT2020_CL = 10, /* Rec. ITU-R BT.2020 constant luminance system */\n  AVS_MATRIX_CHROMATICITY_DERIVED_NCL = 12, /* Chromaticity derived non-constant luminance system */\n  AVS_MATRIX_CHROMATICITY_DERIVED_CL = 13, /* Chromaticity derived constant luminance system */\n  AVS_MATRIX_ICTCP = 14, // REC_2100_ICTCP, Rec. ITU-R BT.2100-2 ICTCP\n  AVS_MATRIX_AVERAGE = 9999, // Avisynth compatibility\n} Matrix_e;\n\n// Pre-Avisynth 3.7.1 matrix constants, with implicite PC/limited range\ntypedef enum Old_Avs_Matrix_e {\n  AVS_OLD_MATRIX_Rec601 = 0, \n  AVS_OLD_MATRIX_Rec709 = 1,\n  AVS_OLD_MATRIX_PC_601 = 2,\n  AVS_OLD_MATRIX_PC_709 = 3,\n  AVS_OLD_MATRIX_AVERAGE = 4,\n  AVS_OLD_MATRIX_Rec2020 = 5,\n  AVS_OLD_MATRIX_PC_2020 = 6\n} Old_Avs_Matrix_e;\n\n// transfer characteristics ITU-T H.265 Table E.4\ntypedef enum Transfer_e {\n  AVS_TRANSFER_BT709 = 1,\n  AVS_TRANSFER_UNSPECIFIED = 2,\n  AVS_TRANSFER_BT470_M = 4,\n  AVS_TRANSFER_BT470_BG = 5,\n  AVS_TRANSFER_BT601 = 6,  /* Equivalent to 1. */\n  AVS_TRANSFER_ST240_M = 7,\n  AVS_TRANSFER_LINEAR = 8,\n  AVS_TRANSFER_LOG_100 = 9,\n  AVS_TRANSFER_LOG_316 = 10,\n  AVS_TRANSFER_IEC_61966_2_4 = 11,\n  AVS_TRANSFER_IEC_61966_2_1 = 13,\n  AVS_TRANSFER_BT2020_10 = 14, /* Equivalent to 1. */\n  AVS_TRANSFER_BT2020_12 = 15, /* Equivalent to 1. */\n  AVS_TRANSFER_ST2084 = 16,\n  AVS_TRANSFER_ARIB_B67 = 18\n} Transfer_e;\n\n// color primaries ITU-T H.265 Table E.3\ntypedef enum Primaries_e {\n  AVS_PRIMARIES_BT709 = 1,\n  AVS_PRIMARIES_UNSPECIFIED = 2,\n  AVS_PRIMARIES_BT470_M = 4,\n  AVS_PRIMARIES_BT470_BG = 5,\n  AVS_PRIMARIES_ST170_M = 6,\n  AVS_PRIMARIES_ST240_M = 7,  /* Equivalent to 6. */\n  AVS_PRIMARIES_FILM = 8,\n  AVS_PRIMARIES_BT2020 = 9,\n  AVS_PRIMARIES_ST428 = 10,\n  AVS_PRIMARIES_ST431_2 = 11,\n  AVS_PRIMARIES_ST432_1 = 12,\n  AVS_PRIMARIES_EBU3213_E = 22\n} Primaries_e;\n\nvoid matrix_parse_merge_with_props(bool rgb_in, bool rgb_out, const char* matrix_name, const AVSMap* props, int& _Matrix, int& _ColorRange, int& ColorRange_Out, IScriptEnvironment* env);\nvoid matrix_parse_merge_with_props_def(bool rgb_in, bool rgb_out, const char* matrix_name, const AVSMap* props, int& _Matrix, int& _ColorRange, int& ColorRange_Out, int _Matrix_Default, int _ColorRange_Default, IScriptEnvironment* env);\nvoid chromaloc_parse_merge_with_props(VideoInfo& vi, const char* chromaloc_name, const AVSMap* props, int& _ChromaLocation, int _ChromaLocation_Default, IScriptEnvironment* env);\n\nvoid update_Matrix_and_ColorRange(AVSMap* props, int theMatrix, int theColorRange, IScriptEnvironment* env);\nvoid update_Transfer_and_Primaries(AVSMap* props, int theTransfer, int thePrimaries, IScriptEnvironment* env);\nvoid update_ColorRange(AVSMap* props, int theColorRange, IScriptEnvironment* env);\nvoid update_ChromaLocation(AVSMap* props, int theChromaLocation, IScriptEnvironment* env);\n\ntypedef struct bits_conv_constants {\n  float src_offset = 0.0f;\n  int src_offset_i = 0;\n  float mul_factor = 1.0f;\n  float dst_offset = 0.0f;\n  float src_span = 1.0f;\n  float dst_span = 1.0f;\n} bits_conv_constants;\n\n// universal transform values for any full-limited bit-depth mix\n[[maybe_unused]] static AVS_FORCEINLINE void get_bits_conv_constants(bits_conv_constants& d, bool use_chroma, bool fulls, bool fulld, int srcBitDepth, int dstBitDepth)\n{\n  d.src_offset = 0.0f;\n  d.mul_factor = 1.0f;\n  d.dst_offset = 0.0f;\n  d.src_span = 1.0f;\n  d.dst_span = 1.0f;\n\n  // possible usage places\n  // Expr (autoscale, scalef, scaleb)\n  // convert_bits\n  // ColorYUV\n  // Histogram\n  // YUV->RGB conversions (matrix coefficients depend on full-limited, but also the scaling of the actual pixel values, so this is needed for both matrix and pixel value conversion)\n\n  if (use_chroma) {\n    // decision: 'limited' range float +/-112 is +/-112/255.0. Must be consistent with Expr, ColorYUV etc\n    // 3.7.2: full range chroma: as per ITU Rec H.273 eq.30 p.10: Cb=Clip1_C(Round(((1<<BitDepth_C)-1)*E'_PB)+(1<<(BitDepth_C-1)))\n    // For 8 bit this results in 128 +/-127.5 instead of 128 +/-127\n    // In general the span is ((1 << srcBitDepth) - 1) / 2.0 instead of (1 << (srcBitDepth - 1)) - 1\n\n    // a bit asymmetric but meets mpeg, jpeg, Rec.2020 industry standards:\n    // full range chroma span intentionally not 128 bit 255/2.0, which is virtually 127.5.\n    // This also gives identical results to e.g. zimg when used in full range YUV-RGB conversions, which is good for consistency.\n    d.src_span = (srcBitDepth == 32) ?\n      (fulls ? 0.5f : 112 / 255.0f) :\n      (fulls ? (float)((1 << srcBitDepth) - 1) / 2.0f : (float)(112 << (srcBitDepth - 8)));\n    d.dst_span = (dstBitDepth == 32) ?\n      (fulld ? 0.5f : 112 / 255.0f) :\n      (fulld ? (float)((1 << dstBitDepth) - 1) / 2.0f : (float)(112 << (dstBitDepth - 8)));\n    // chroma use case: go into signed world, factor, then go back to biased range\n    d.src_offset = (srcBitDepth == 32) ? 0.0f : (1 << (srcBitDepth - 1));\n    d.dst_offset = (dstBitDepth == 32) ? 0.0f : (1 << (dstBitDepth - 1));\n\n    /*\n    fulls=fulld=false case:\n    // mul/div by 2^N when between 8-16 bit integer formats\n    // 255*: for consistent float conversion. scale (shift) to/from 8 bit. int-float is always 0..1.0 <-> 0..255\n    // int-float: 10+ bits first downshift to 8 bits then /255.\n    // float-int: 10+ bits first *255 to have 0..255 range, then shift from 8 bits to actual bit depth\n    // Since first we convert to 8 bit 0-255 range and do bit-shift after then to >8 depths, the 1.0 number will show up as 255*256 in 16 bits.\n    // This is normal. Like float32.ConvertBits(8).ConvertBits(16)\n    (srcBitDepth == 32) -> (255 * (float)(1 << (dstBitDepth - 8)) / 1.0\n    (dstBitDepth == 32) -> 1.0 / (255 * (float)(1 << (srcBitDepth - 8)))\n\n    (srcBitDepth == 32) -> ((float)(1 << (dstBitDepth - 8)))) / (1 / 255.0f)\n    (dstBitDepth == 32) -> 1.0 / 255.0f / (float)(1 << (srcBitDepth - 8))))\n    */\n  }\n  else {\n    // luma\n    d.src_span = (srcBitDepth == 32) ?\n      (fulls ? 1.0f : 219 / 255.0f) :\n      (fulls ? ((1 << srcBitDepth) - 1) : (219 << (srcBitDepth - 8))); // 0..255, 16..235\n    d.dst_span = (dstBitDepth == 32) ?\n      (fulld ? 1.0f : 219 / 255.0f) :\n      (fulld ? ((1 << dstBitDepth) - 1) : (219 << (dstBitDepth - 8)));\n    // luma\n    d.src_offset = (srcBitDepth == 32) ?\n      (fulls ? 0 : 16.0f / 255) :\n      (fulls ? 0 : (16 << (srcBitDepth - 8)));\n    d.dst_offset = (dstBitDepth == 32) ?\n      (fulld ? 0 : 16.0f / 255) :\n      (fulld ? 0 : (16 << (dstBitDepth - 8)));\n  }\n\n  d.mul_factor = d.dst_span / d.src_span;\n  d.src_offset_i = (int)d.src_offset; // no rounding, when used, it is integer\n}\n\nenum class ConversionDirection {\n  YUV_TO_RGB,\n  RGB_TO_YUV,\n  YUV_TO_YUV,\n  RGB_TO_RGB,\n  RGB_TO_Y\n};\n\n#endif  // __Convert_helper_H__\n"
  },
  {
    "path": "avs_core/convert/convert_matrix.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002-2009 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include \"convert_matrix.h\"\n#include \"convert_helper.h\"\n#include <avisynth.h>\n#ifdef AVS_WINDOWS\n#include <avs/win.h>\n#else\n#include <avs/posix.h>\n#endif \n#include <cmath>\n\n/**\n * SIMD scaling logic for PMADDWD (16-bit signed multipliers, 32-bit accumulators).\n * RGB->YUV uses 15-bit scale as all coeffs are < 1.0 (max ~0.678, BT.2020 G weight),\n *   fully utilizing 16-bit coefficient precision without overflow.\n * YUV->RGB requires 13-bit scale to accommodate chroma expansion coeffs up to ~1.881\n *   (BT.2020 Cb->B), keeping scaled coefficients within int16 range.\n * Fused YUV->YUV (e.g., 601->2020) needs 14-bit scale; diagonal gain slightly > 1.0\n *   (~1.03 max) rules out 15-bit, but coeffs are well within 13-bit headroom.\n * At 16-bit depth, errors partially average out during 32-bit accumulation before rounding.\n * Avoid unifying all paths to 13-bit: RGB->YUV would degrade from ~±1 to ~±12 LSB worst-case.\n *\n * | Conversion  | Scale  | Max Coeff | LSB Error (16-bit) | Worst-Case Matrix   |\n * |-------------|--------|-----------|--------------------|---------------------|\n * | RGB -> YUV  | 15-bit | ~0.678    | ~±1  (near-exact)  | BT.2020 (G weight)  |\n * | YUV -> RGB  | 13-bit | ~1.881    | ~±8  (practical)   | BT.2020 (Cb -> B)   |\n * | YUV -> YUV  | 14-bit | ~1.030    | ~±2  (low noise)   | 601 <-> 2020 fused  |\n *\n * matrix=\"RGB\" (IDENTITY) exception: If Kr=Kb=0 (Identity), coeffs reach 1.0. (1.0 << 15) = 32768,\n * which overflows int16 (-32768 to 32767). Caller will check it and may diable int16 based SIMD optimization paths.\n */\n\nstatic void BuildMatrix_Rgb2Yuv_core(double Kr, double Kb, int int_arith_shift, bool full_scale_s, bool full_scale_d, int bits_per_pixel, ConversionMatrix& matrix)\n{\n  bits_conv_constants luma, chroma;\n  bits_conv_constants luma_to_32bit;\n\n  // helpers for post-matrix conversion to 32-bit float (for high bit depth sources or targets, e.g. 16-bit to 32-bit float)\n  get_bits_conv_constants(luma_to_32bit, false, full_scale_s, full_scale_d, bits_per_pixel, 32);\n  matrix.target_span_f_32 = luma_to_32bit.dst_span;\n  matrix.offset_out_f_32 = luma_to_32bit.dst_offset;\n\n  // RGB is source, YUV is destination\n  // For RGB source / Y destination (both luma-like):\n  get_bits_conv_constants(luma, false, full_scale_s, full_scale_d, bits_per_pixel, bits_per_pixel);\n  // For UV destination (chroma behavior):\n  // Note: we only need dst_span for UV, so we use full_scale_d for both params\n  get_bits_conv_constants(chroma, true, full_scale_d, full_scale_d, bits_per_pixel, bits_per_pixel);\n\n  double Srgb_f = luma.src_span;      // RGB input range\n  double Sy_f = luma.dst_span;        // Y output range  \n  double Suv_f = chroma.dst_span;     // UV output range\n  double Orgb_f = luma.src_offset;    // RGB input offset\n  double Oy_f = luma.dst_offset;      // Y output offset\n\n  // Derive integer versions (for <= 16 bit paths)\n  int Orgb = (int)Orgb_f;\n  int Oy = (int)Oy_f;\n\n  /*\n    Kr   = {0.299, 0.2126}\n    Kb   = {0.114, 0.0722}\n    Kg   = 1 - Kr - Kb // {0.587, 0.7152}\n    Srgb = 255\n    Sy   = {219, 255}   // { 235-16, 255-0 }\n    Suv  = {112, 127}   // { (240-16)/2, (255-0)/2 }\n    Oy   = {16, 0}\n    Ouv  = 128\n    R = r/Srgb                     // 0..1\n    G = g/Srgb\n    B = b/Srgb\n    Y = Kr*R + Kg*G + Kb*B         // 0..1\n    U = B - (Kr*R + Kg*G)/(1-Kb)   //-1..1\n    V = R - (Kg*G + Kb*B)/(1-Kr)\n    y = Y*Sy  + Oy                 // 16..235, 0..255\n    u = U*Suv + Ouv                // 16..240, 1..255\n    v = V*Suv + Ouv\n  */\n\n  const int mulfac_int = 1 << int_arith_shift;\n  const double mulfac = double(mulfac_int);\n  const double Kg = 1. - Kr - Kb;\n\n  // Symmetric rounding for both positive and negative coefficients\n  auto round_coeff = [](double v) {\n    return (int)(v >= 0 ? (v + 0.5) : (v - 0.5));\n    };\n\n  // Calculate double-precision coefficients\n  double y_b_f = Sy_f * Kb / Srgb_f;\n  double y_g_f = Sy_f * Kg / Srgb_f;\n  double y_r_f = Sy_f * Kr / Srgb_f;\n\n  double u_b_f = Suv_f / Srgb_f;\n  double u_g_f = Suv_f * Kg / (Kb - 1) / Srgb_f;\n  double u_r_f = Suv_f * Kr / (Kb - 1) / Srgb_f;\n\n  double v_b_f = Suv_f * Kb / (Kr - 1) / Srgb_f;\n  double v_g_f = Suv_f * Kg / (Kr - 1) / Srgb_f;\n  double v_r_f = Suv_f / Srgb_f;\n\n  double offset_y_f = Oy_f;\n  double offset_rgb_f = -Orgb_f;  // Negative because addition is used\n\n  // Store float versions\n  matrix.y_b_f = (float)y_b_f;\n  matrix.y_g_f = (float)y_g_f;\n  matrix.y_r_f = (float)y_r_f;\n  matrix.u_b_f = (float)u_b_f;\n  matrix.u_g_f = (float)u_g_f;\n  matrix.u_r_f = (float)u_r_f;\n  matrix.v_b_f = (float)v_b_f;\n  matrix.v_g_f = (float)v_g_f;\n  matrix.v_r_f = (float)v_r_f;\n  matrix.offset_y_f = (float)offset_y_f;\n  matrix.offset_rgb_f = (float)offset_rgb_f;\n\n  if (bits_per_pixel <= 16) {\n    // Derive integer versions from doubles with proper rounding\n    matrix.y_b = round_coeff(mulfac * y_b_f);\n    matrix.y_g = round_coeff(mulfac * y_g_f);\n    matrix.y_r = round_coeff(mulfac * y_r_f);\n\n    matrix.u_b = round_coeff(mulfac * u_b_f);\n    matrix.u_g = round_coeff(mulfac * u_g_f);\n    matrix.u_r = round_coeff(mulfac * u_r_f);\n\n    matrix.v_b = round_coeff(mulfac * v_b_f);\n    matrix.v_g = round_coeff(mulfac * v_g_f);\n    matrix.v_r = round_coeff(mulfac * v_r_f);\n\n    matrix.offset_y = Oy;\n    matrix.offset_rgb = -Orgb;  // negative because addition is used\n\n    // Luma gain check: ensure Y captures 100% of RGB energy\n    // Only applies when destination is full-range (no offset)\n    if (matrix.offset_y == 0) {\n      int y_sum = matrix.y_b + matrix.y_g + matrix.y_r;\n      if (y_sum != mulfac_int) {\n        matrix.y_g += (mulfac_int - y_sum);\n      }\n    }\n\n    // U neutrality check: ensure R=G=B results in U = 0 (before offset)\n    int u_sum = matrix.u_b + matrix.u_g + matrix.u_r;\n    if (u_sum != 0) {\n      matrix.u_g -= u_sum;\n    }\n\n    // V neutrality check: ensure R=G=B results in V = 0 (before offset)\n    int v_sum = matrix.v_b + matrix.v_g + matrix.v_r;\n    if (v_sum != 0) {\n      matrix.v_g -= v_sum;\n    }\n\n  }\n\n  // in: rgb. out: yuv\n  matrix.offset_in = matrix.offset_rgb;\n  matrix.offset_in_f = matrix.offset_rgb_f;\n  matrix.offset_out = matrix.offset_y;\n  matrix.offset_out_f = matrix.offset_y_f;\n}\n\n/*\n * WARNING: int_arith_shift MUST NOT exceed 13 for YUV -> RGB expansion.\n * Example: BT.709 Limited -> Full Range\n * The Blue expansion factor (u_b_f) is ~2.112.\n * - At 14-bit shift: 2.112 * 16384 = 34603 (OVERFLOWS int16_t)\n * - At 13-bit shift: 2.112 * 8192  = 17302 (SAFE)\n * Use 13-bit shift to ensure coefficients fit in int16 for SIMD paths.\n * Additionally, summing up to 3 components (Y, U, V) plus rounding constant must\n * not overflow int32 accumulators in SIMD. (another 2 bits headroom needed)\n*/\nstatic void BuildMatrix_Yuv2Rgb_core(double Kr, double Kb, int int_arith_shift, bool full_scale_s, bool full_scale_d, int bits_per_pixel, ConversionMatrix& matrix)\n{\n  float Sy_f, Suv_f, Oy_f, Orgb_f;\n\n  bits_conv_constants luma, chroma;\n  bits_conv_constants luma_to_32bit;\n\n  // helpers for post-matrix conversion to 32-bit float (for high bit depth sources or targets, e.g. 16-bit to 32-bit float)\n  get_bits_conv_constants(luma_to_32bit, false, full_scale_s, full_scale_d, bits_per_pixel, 32);\n  matrix.target_span_f_32 = luma_to_32bit.dst_span;\n  matrix.offset_out_f_32 = luma_to_32bit.dst_offset;\n\n  // We use dstBitDepth = srcBitDepth because the matrix handles the magnitude \n  // via the mulfac and Srgb calculations. We just need the standardized spans.\n  get_bits_conv_constants(luma, false, full_scale_s, full_scale_d, bits_per_pixel, bits_per_pixel);\n  get_bits_conv_constants(chroma, true, full_scale_s, full_scale_d, bits_per_pixel, bits_per_pixel);\n\n  matrix.target_span_f = luma.dst_span;\n\n  Sy_f = luma.src_span;\n  Suv_f = chroma.src_span;\n  Oy_f = luma.src_offset;\n  Orgb_f = luma.dst_offset;\n\n  /*\n    Kr   = {0.299, 0.2126}\n    Kb   = {0.114, 0.0722}\n    Kg   = 1 - Kr - Kb // {0.587, 0.7152}\n    Srgb = 255\n    Sy   = {219, 255}   // { 235-16, 255-0 }\n    Suv  = {112, 127}   // { (240-16)/2, (255-0)/2 }\n    Oy   = {16, 0}\n    Ouv  = 128\n\n    Y =(y-Oy)  / Sy                         // 0..1\n    U =(u-Ouv) / Suv                        //-1..1\n    V =(v-Ouv) / Suv\n\n    R = Y                  + V*(1-Kr)       // 0..1\n    G = Y - U*(1-Kb)*Kb/Kg - V*(1-Kr)*Kr/Kg\n    B = Y + U*(1-Kb)\n\n    r = R*Srgb                              // 0..255   0..65535\n    g = G*Srgb\n    b = B*Srgb\n  */\n\n\n  const double mulfac = (double)(1 << int_arith_shift); // integer aritmetic precision scale\n\n  const double Kg = 1. - Kr - Kb;\n\n  // The Srgb (destination span) is also just the dst_span (RGB is luma-like)!\n  const float Srgb_f = (float)luma.dst_span;\n\n  // symmetric rounding for both positive and negative coefficients\n  auto round_coeff = [](double v) {\n    return (int)(v >= 0 ? (v + 0.5) : (v - 0.5));\n    };\n\n  double y_b_f = (Srgb_f * 1.000 / Sy_f); //Y\n  double u_b_f = (Srgb_f * (1 - Kb) / Suv_f); //U\n  double v_b_f = (Srgb_f * 0.000 / Suv_f); //V\n  double y_g_f = (Srgb_f * 1.000 / Sy_f);\n  double u_g_f = (Srgb_f * (Kb - 1) * Kb / Kg / Suv_f);\n  double v_g_f = (Srgb_f * (Kr - 1) * Kr / Kg / Suv_f);\n  double y_r_f = (Srgb_f * 1.000 / Sy_f);\n  double u_r_f = (Srgb_f * 0.000 / Suv_f);\n  double v_r_f = (Srgb_f * (1 - Kr) / Suv_f);\n  double offset_y_f = -Oy_f; // negative, it will be added in the conversion, so we store the negative here\n  double offset_rgb_f = Orgb_f;\n\n  matrix.y_b_f = (float)(y_b_f);\n  matrix.u_b_f = (float)(u_b_f);\n  matrix.v_b_f = (float)(v_b_f);\n  matrix.y_g_f = (float)(y_g_f);\n  matrix.u_g_f = (float)(u_g_f);\n  matrix.v_g_f = (float)(v_g_f);\n  matrix.y_r_f = (float)(y_r_f);\n  matrix.u_r_f = (float)(u_r_f);\n  matrix.v_r_f = (float)(v_r_f);\n  matrix.offset_y_f = (float)offset_y_f;\n  matrix.offset_rgb_f = (float)offset_rgb_f;\n\n  matrix.y_b = round_coeff(mulfac * y_b_f);\n  matrix.u_b = round_coeff(mulfac * u_b_f);\n  matrix.v_b = round_coeff(mulfac * v_b_f);\n  matrix.y_g = round_coeff(mulfac * y_g_f);\n  matrix.u_g = round_coeff(mulfac * u_g_f);\n  matrix.v_g = round_coeff(mulfac * v_g_f);\n  matrix.y_r = round_coeff(mulfac * y_r_f);\n  matrix.u_r = round_coeff(mulfac * u_r_f);\n  matrix.v_r = round_coeff(mulfac * v_r_f);\n  matrix.offset_y = round_coeff(offset_y_f);\n  matrix.offset_rgb = round_coeff(offset_rgb_f);\n\n  // in: yuv. out: rgb\n  matrix.offset_in = matrix.offset_y;\n  matrix.offset_in_f = matrix.offset_y_f;\n  matrix.offset_out = matrix.offset_rgb;\n  matrix.offset_out_f = matrix.offset_rgb_f;\n\n}\n\nbool GetKrKb(int matrix, double& Kr, double& Kb)\n{\n  switch (matrix) {\n  case AVS_MATRIX_BT470_BG:\n  case AVS_MATRIX_ST170_M:    Kr = 0.299;  Kb = 0.114;  return true;\n  case AVS_MATRIX_BT709:      Kr = 0.2126; Kb = 0.0722; return true;\n  case AVS_MATRIX_BT2020_NCL:\n  case AVS_MATRIX_BT2020_CL:  Kr = 0.2627; Kb = 0.0593; return true;\n  case AVS_MATRIX_BT470_M:    Kr = 0.3;    Kb = 0.11;   return true;\n  case AVS_MATRIX_ST240_M:    Kr = 0.212;  Kb = 0.087;  return true;\n  case AVS_MATRIX_AVERAGE:    Kr = 1.0 / 3;  Kb = 1.0 / 3;  return true;\n  default: return false;\n  }\n}\n\nbool do_BuildMatrix_Rgb2Yuv(int _Matrix, int _ColorRange, int _ColorRange_Out, int int_arith_shift, int bits_per_pixel, ConversionMatrix& matrix)\n{\n  if (_ColorRange != ColorRange_Compat_e::AVS_COLORRANGE_FULL && _ColorRange != ColorRange_Compat_e::AVS_COLORRANGE_LIMITED)\n    return false;\n  if (_ColorRange_Out != ColorRange_Compat_e::AVS_COLORRANGE_FULL && _ColorRange_Out != ColorRange_Compat_e::AVS_COLORRANGE_LIMITED)\n    return false;\n\n  const bool is_full_s = _ColorRange == ColorRange_Compat_e::AVS_COLORRANGE_FULL;\n  const bool is_full_d = _ColorRange_Out == ColorRange_Compat_e::AVS_COLORRANGE_FULL;\n\n  // Special cases not handled by GetKrKb\n  if (_Matrix == Matrix_e::AVS_MATRIX_RGB) {\n    // copies Green to Y and sets UV to 0\n    BuildMatrix_Rgb2Yuv_core(0.0, 0.0, int_arith_shift, is_full_s, is_full_d, bits_per_pixel, matrix);\n    return true;\n  }\n  if (_Matrix == Matrix_e::AVS_MATRIX_ICTCP || _Matrix == Matrix_e::AVS_MATRIX_YCGCO)\n    return false; // not supported\n\n  double Kr, Kb;\n  if (!GetKrKb(_Matrix, Kr, Kb))\n    return false;\n\n  BuildMatrix_Rgb2Yuv_core(Kr, Kb, int_arith_shift, is_full_s, is_full_d, bits_per_pixel, matrix);\n  return true;\n}\n\nbool do_BuildMatrix_Yuv2Rgb(int _Matrix, int _ColorRange, int _ColorRange_Out, int int_arith_shift, int bits_per_pixel, ConversionMatrix& matrix)\n{\n  if (_ColorRange != ColorRange_Compat_e::AVS_COLORRANGE_FULL && _ColorRange != ColorRange_Compat_e::AVS_COLORRANGE_LIMITED)\n    return false;\n  if (_ColorRange_Out != ColorRange_Compat_e::AVS_COLORRANGE_FULL && _ColorRange_Out != ColorRange_Compat_e::AVS_COLORRANGE_LIMITED)\n    return false;\n\n  const bool is_full_s = _ColorRange == ColorRange_Compat_e::AVS_COLORRANGE_FULL;\n  const bool is_full_d = _ColorRange_Out == ColorRange_Compat_e::AVS_COLORRANGE_FULL;\n\n  // Special cases not handled by GetKrKb\n  if (_Matrix == Matrix_e::AVS_MATRIX_RGB) {\n    BuildMatrix_Yuv2Rgb_core(0.0, 0.0, int_arith_shift, is_full_s, is_full_d, bits_per_pixel, matrix);\n    return true;\n  }\n  if (_Matrix == Matrix_e::AVS_MATRIX_ICTCP || _Matrix == Matrix_e::AVS_MATRIX_YCGCO)\n    return false; // not supported\n\n  double Kr, Kb;\n  if (!GetKrKb(_Matrix, Kr, Kb))\n    return false;\n\n  BuildMatrix_Yuv2Rgb_core(Kr, Kb, int_arith_shift, is_full_s, is_full_d, bits_per_pixel, matrix);\n  return true;\n}\n"
  },
  {
    "path": "avs_core/convert/convert_matrix.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Convert_matrix_H__\n#define __Convert_matrix_H__\n\n#include \"../core/internal.h\"\n\nstruct ConversionMatrix {\n  int y_r, y_g, y_b;\n  // for grayscale conversion these may not needed\n  int u_r, u_g, u_b;\n  int v_r, v_g, v_b;\n\n  float y_r_f, y_g_f, y_b_f;\n  float u_r_f, u_g_f, u_b_f;\n  float v_r_f, v_g_f, v_b_f;\n\n  int offset_y;\n  float offset_y_f;\n  int offset_rgb;\n  float offset_rgb_f;\n\n  // and the w/o the y/rgb suffix, supporting yuv-yuv or rgb-rgb fused matrix calculations.\n  int offset_in;\n  float offset_in_f;\n  int offset_out;\n  float offset_out_f;\n\n  // Helper values for exact 32-bit target for hybric calculations, where\n  // conversion to 32-bits is done after the integer-integer conversion.\n  // E.g. yuv X-bit -> rgb X-bit -> rgb 32-bit\n  float target_span_f;\n  float target_span_f_32;\n  float offset_out_f_32;\n};\n\nbool GetKrKb(int matrix, double& Kr, double& Kb);\nbool do_BuildMatrix_Rgb2Yuv(int _Matrix, int _ColorRange, int _ColorRange_Out, int int_arith_shift, int bits_per_pixel, ConversionMatrix& matrix);\nbool do_BuildMatrix_Yuv2Rgb(int _Matrix, int _ColorRange, int _ColorRange_Out, int int_arith_shift, int bits_per_pixel, ConversionMatrix& matrix);\n\n/*****************************************************\n *******   Colorspace Single-Byte Conversions   ******\n ****************************************************/\n\n// useful to other filters\ninline int RGB2YUV_Rec601(int rgb) // limited range\n{\n  const int cyb = int(0.114*219/255*65536+0.5);\n  const int cyg = int(0.587*219/255*65536+0.5);\n  const int cyr = int(0.299*219/255*65536+0.5);\n\n  // y can't overflow\n  int y = (cyb*(rgb&255) + cyg*((rgb>>8)&255) + cyr*((rgb>>16)&255) + 0x108000) >> 16;\n  int scaled_y = (y - 16) * int(255.0/219.0*65536+0.5);\n  int b_y = ((rgb&255) << 16) - scaled_y;\n  int u = ScaledPixelClip((b_y >> 10) * int(1/2.018*1024+0.5) + 0x800000);\n  int r_y = (rgb & 0xFF0000) - scaled_y;\n  int v = ScaledPixelClip((r_y >> 10) * int(1/1.596*1024+0.5) + 0x800000);\n  return ((y*256+u)*256+v) | (rgb & 0xff000000);\n}\n\n#endif  // __Convert_matrix_H__\n"
  },
  {
    "path": "avs_core/convert/convert_planar.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// ConvertPlanar (c) 2005 by Klaus Post\n\n\n#include \"convert.h\"\n#include \"convert_matrix.h\"\n#include \"convert_helper.h\"\n#include \"convert_planar.h\"\n#ifdef INTEL_INTRINSICS\n#include \"intel/convert_planar_sse.h\"\n#include \"intel/convert_planar_avx2.h\"\n#endif\n#include \"convert_bits.h\"\n#include \"../filters/resample.h\"\n#include \"../filters/planeswap.h\"\n#include \"../filters/field.h\"\n\n#ifdef AVS_WINDOWS\n    #include <avs/win.h>\n#else\n    #include <avs/posix.h>\n#endif\n\n#include <avs/alignment.h>\n#include <algorithm>\n#include <string>\n#include <vector>\n\nDISABLE_WARNING_PUSH\nDISABLE_WARNING_UNREFERENCED_LOCAL_VARIABLE\n\ntemplate <typename pixel_t>\nvoid fill_chroma(uint8_t * dstp_u, uint8_t * dstp_v, int height, int row_size, int pitch, pixel_t val)\n{\n  if (pitch == row_size) {\n    size_t size = height * pitch / sizeof(pixel_t);\n    std::fill_n(reinterpret_cast<pixel_t*>(dstp_u), size, val);\n    std::fill_n(reinterpret_cast<pixel_t*>(dstp_v), size, val);\n  }\n  else {\n    size_t size = row_size / sizeof(pixel_t);\n    for (int i = 0; i < height; i++) {\n      std::fill_n(reinterpret_cast<pixel_t*>(dstp_u), size, val);\n      std::fill_n(reinterpret_cast<pixel_t*>(dstp_v), size, val);\n      dstp_u += pitch;\n      dstp_v += pitch;\n    }\n  }\n}\n\ntemplate <typename pixel_t>\nvoid fill_plane(uint8_t * dstp, int height, int row_size, int pitch, pixel_t val)\n{\n  if (pitch == row_size) {\n    size_t size = height * pitch / sizeof(pixel_t);\n    std::fill_n(reinterpret_cast<pixel_t*>(dstp), size, val);\n  }\n  else {\n    size_t size = row_size / sizeof(pixel_t);\n    for (int i = 0; i < height; i++) {\n      std::fill_n(reinterpret_cast<pixel_t*>(dstp), size, val);\n      dstp += pitch;\n    }\n  }\n}\n\n// specialize it\ntemplate void fill_plane<uint8_t>(uint8_t * dstp, int height, int row_size, int pitch, uint8_t val);\ntemplate void fill_plane<uint16_t>(uint8_t * dstp, int height, int row_size, int pitch, uint16_t val);\ntemplate void fill_plane<float>(uint8_t * dstp, int height, int row_size, int pitch, float val);\ntemplate void fill_chroma<uint8_t>(uint8_t * dstp_u, uint8_t * dstp_v, int height, int row_size, int pitch, uint8_t val);\ntemplate void fill_chroma<uint16_t>(uint8_t * dstp_u, uint8_t * dstp_v, int height, int row_size, int pitch, uint16_t val);\ntemplate void fill_chroma<float>(uint8_t * dstp_u, uint8_t * dstp_v, int height, int row_size, int pitch, float val);\n\n\n// ConvertToY::ConvertToY moved into ConvertPlanarToGeneric, since the conversion logic and parameters overlap with -->444 Conversion, we just need only Y.\n// Legacy formats (packed RGB/YUY2) are handled uniformly inside.\nAVSValue __cdecl ConvertToPlanarGeneric::CreateY(AVSValue args, void* user_data, IScriptEnvironment* env) {\n  bool only_8bit = reinterpret_cast<intptr_t>(user_data) == 0;\n  PClip clip = args[0].AsClip();\n\n  // 0    1       2      3\n  // c[matrix]s[bits]i[quality]b\n  if (only_8bit) {\n    // ConvertToY8() syntax\n    if (args[2].Defined() && args[2].AsInt() != 8)\n      env->ThrowError(\"ConvertToY8: only 8 bit output supported. \"\n        \"Use ConvertToY for higher bit depth.\");\n  }\n\n  // 1.) One single route: planar constructor, where YUY2 is converted to Y8 if needed\n  // 2.) If Y, reason to not return it right now:\n  // - possible bit-depth conversion,\n  // - optional Y-Y future matrix (auto:full->auto:limited) syntax conversion)\n\n  // We use the very same logic as for ConvertToYV24/YUV444, ConvertToYV16/YUV422, ConvertToYV12/YUV420\n  if (only_8bit) {\n    // ConvertToY8() syntax, force 8 bit output}\n    AVSValue new_args[4] = {\n      args[0], args[1], AVSValue(8), args[3]\n    };\n    AVSValue new_args_val(new_args, 4);\n    return Create(new_args_val, \"ConvertToY\", only_8bit, false /*to_yuva*/, env);\n  }\n  else {\n    return Create(args, \"ConvertToY\", only_8bit, false /*to_yuva*/, env);\n  }\n}\n\n/*****************************************************\n * ConvertRGBToYUV444 or simply Y only (when to_y=true)\n ******************************************************/\n\nConvertRGBToYUV444::ConvertRGBToYUV444(PClip src, const char *matrix_name, bool keep_packedrgb_alpha, int _target_bit_depth, bool _quality, bool& bitdepthConverted, bool _to_y, IScriptEnvironment* env)\n  : GenericVideoFilter(src), target_bit_depth(_target_bit_depth), quality(_quality), conv_function(nullptr), conv_function_chroma(nullptr), conv_function_a(nullptr), to_y(_to_y)\n{\n  if (!vi.IsRGB())\n    env->ThrowError(\"ConvertRGBToYV24/YUV444: Only RGB data input accepted\");\n\n  if (vi.IsRGB48() || vi.IsRGB64())\n    env->ThrowError(\"ConvertRGBToYV24/YUV444: internal error: packed 16 bit not supported, must be converted to RGBP(A)16\");\n\n  // ChromaInPlacement parameter exists, (default none/-1) + input frame properties; 'left'-ish _ChromaLocation is allowed, checked later\n  auto frame0 = src->GetFrame(0, env);\n  const AVSMap* props = env->getFramePropsRO(frame0);\n\n  // input _ColorRange frame property can appear for RGB source (studio range limited rgb)\n  matrix_parse_merge_with_props(true /*in rgb*/, false /*out yuv*/, matrix_name, props, theMatrix, theColorRange, theOutColorRange, env);\n\n  const int shift = 15; // internally 15 bits precision, still no overflow in calculations\n  int bits_per_pixel = vi.BitsPerComponent();\n  source_bit_depth = bits_per_pixel;\n\n  if (!do_BuildMatrix_Rgb2Yuv(theMatrix, theColorRange, theOutColorRange, shift, source_bit_depth, /*ref*/matrix))\n    env->ThrowError(\"ConvertRGBToYV24/YUV444: Unknown matrix.\");\n\n  theColorRange = theOutColorRange; // final frame property\n\n  // target_bit_depth == -1: no conversion required\n  const bool need_bitdepth_conversion = (target_bit_depth != -1);\n\n  // get alpha converter, GetFrame is using that if alpha must be depth-converterd and not only copied\n  if (need_bitdepth_conversion)\n  {\n    // supported conversions:\n    // 8-16-bits any range to 8-16, 32 bits any range\n    bitdepthConverted = true;\n\n    if (!to_y) { // single plane Y only has no alpha\n#ifdef INTEL_INTRINSICS\n      const bool sse2 = !!(env->GetCPUFlags() & CPUF_SSE2);\n      const bool sse4 = !!(env->GetCPUFlags() & CPUF_SSE4_1);\n      const bool avx2 = !!(env->GetCPUFlags() & CPUF_AVX2);\n#endif\n      // we really need only alpha conversion function\n      const bool fulls = true; // alpha is always full range\n      const bool fulld = true; // alpha is always full range\n      const int dither_mode = -1;\n#ifdef INTEL_INTRINSICS\n      get_convert_any_bits_functions(dither_mode, source_bit_depth, target_bit_depth, fulls, fulld, sse2, sse4, avx2, conv_function, conv_function_chroma, conv_function_a);\n#else\n      get_convert_any_bits_functions(dither_mode, source_bit_depth, target_bit_depth, fulls, fulld, conv_function, conv_function_chroma, conv_function_a);\n#endif\n    }\n  }\n  else {\n    bitdepthConverted = false;\n    target_bit_depth = source_bit_depth;\n  }\n\n  isPlanarRGBfamily = vi.IsPlanarRGB() || vi.IsPlanarRGBA();\n  targetHasAlpha = vi.IsPlanarRGBA() || (keep_packedrgb_alpha && (vi.IsRGB32() || vi.IsRGB64()));\n  // for packed RGB it depends: ConvertToYUVAxxx() can force YUVA target option\n  if (isPlanarRGBfamily)\n  {\n    if (to_y) {\n      // --> Y\n      pixel_step =  -1;\n      switch (target_bit_depth)\n      {\n      case 8: vi.pixel_type = VideoInfo::CS_Y8; break;\n      case 10: vi.pixel_type = VideoInfo::CS_Y10; break;\n      case 12: vi.pixel_type = VideoInfo::CS_Y12; break;\n      case 14: vi.pixel_type = VideoInfo::CS_Y14; break;\n      case 16: vi.pixel_type = VideoInfo::CS_Y16; break;\n      case 32: vi.pixel_type = VideoInfo::CS_Y32; break;\n      }\n    }\n    else {\n      // --> 444(4)\n      pixel_step = targetHasAlpha ? -2 : -1;\n      switch (target_bit_depth)\n      {\n      case 8: vi.pixel_type = targetHasAlpha ? VideoInfo::CS_YUVA444 : VideoInfo::CS_YV24; break;\n      case 10: vi.pixel_type = targetHasAlpha ? VideoInfo::CS_YUVA444P10 : VideoInfo::CS_YUV444P10; break;\n      case 12: vi.pixel_type = targetHasAlpha ? VideoInfo::CS_YUVA444P12 : VideoInfo::CS_YUV444P12; break;\n      case 14: vi.pixel_type = targetHasAlpha ? VideoInfo::CS_YUVA444P14 : VideoInfo::CS_YUV444P14; break;\n      case 16: vi.pixel_type = targetHasAlpha ? VideoInfo::CS_YUVA444P16 : VideoInfo::CS_YUV444P16; break;\n      case 32: vi.pixel_type = targetHasAlpha ? VideoInfo::CS_YUVA444PS : VideoInfo::CS_YUV444PS; break;\n      }\n    }\n  } else { // packed RGB24/32/48/64\n    // for compatibility reasons ConvertToYUVxxx target is not YUVA even \n    // if original has alpha, such as RGB32.\n    // Unlike ConvertToYUVA which can force keeping RGB32's or RGB64's alpha\n\n    // must be the same, bit depth change is supported only from planar rgb\n    if (bits_per_pixel != target_bit_depth)\n      env->ThrowError(\"ConvertRGBToYV24/YUV444: bit depth change is only supported from planar RGB input\");\n\n    pixel_step = vi.BytesFromPixels(1); // 3,4 for packed 8 bit, 6,8 for\n    switch(vi.ComponentSize())\n    {\n    case 1: vi.pixel_type = targetHasAlpha ? VideoInfo::CS_YUVA444 : VideoInfo::CS_YV24; break;\n    case 2: vi.pixel_type = targetHasAlpha ? VideoInfo::CS_YUVA444P16 : VideoInfo::CS_YUV444P16; break;\n    }\n  }\n\n}\n\n#if 0\n// Kept for reference\ntemplate<int pixel_step, bool copyalpha>\nstatic void convert_rgb24or32_to_yuv444_c(BYTE* dstY, BYTE* dstU, BYTE* dstV, BYTE* dstA, const BYTE* srcp, size_t Ypitch, size_t UVpitch, size_t Apitch, size_t Spitch, size_t width, size_t height, const ConversionMatrix& m)\n{\n  const bool has_offset_rgb = 0 != m.offset_rgb;\n\n  // RGB24 (pixel_step=3)\n  // RGB32 (pixel_step=4) optional copyalpha\n  srcp += Spitch * (height - 1);  // We start at last line\n  const size_t Sstep = Spitch + width * pixel_step;\n  for (size_t y = 0; y < height; y++) {\n    for (size_t x = 0; x < width; x++) {\n      int b = srcp[0];\n      int g = srcp[1];\n      int r = srcp[2];\n      if (has_offset_rgb) {\n        b = b + m.offset_rgb;\n        g = g + m.offset_rgb;\n        r = r + m.offset_rgb;\n      }\n      int Y = m.offset_y + (((int)m.y_b * b + (int)m.y_g * g + (int)m.y_r * r + 16384) >> 15);\n      int U = 128 + (((int)m.u_b * b + (int)m.u_g * g + (int)m.u_r * r + 16384) >> 15);\n      int V = 128 + (((int)m.v_b * b + (int)m.v_g * g + (int)m.v_r * r + 16384) >> 15);\n      dstY[x] = PixelClip(Y);  // All the safety we can wish for.\n      dstU[x] = PixelClip(U);\n      dstV[x] = PixelClip(V);\n      if constexpr (copyalpha) {\n        dstA[x] = srcp[3];\n      }\n      srcp += pixel_step;\n    }\n    srcp -= Sstep; // packed RGBs are upside down\n    dstY += Ypitch;\n    dstU += UVpitch;\n    dstV += UVpitch;\n    if constexpr (copyalpha) {\n      dstA += Apitch;\n    }\n  }\n}\n#endif\n\n\nPVideoFrame __stdcall ConvertRGBToYUV444::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame src = child->GetFrame(n, env);\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n\n  auto props = env->getFramePropsRW(dst);\n  update_Matrix_and_ColorRange(props, theMatrix, theColorRange, env);\n\n  BYTE* dstY = dst->GetWritePtr(PLANAR_Y);\n  BYTE* dstU = to_y ? nullptr : dst->GetWritePtr(PLANAR_U);\n  BYTE* dstV = to_y ? nullptr : dst->GetWritePtr(PLANAR_V);\n\n  const int Ypitch = dst->GetPitch(PLANAR_Y);\n  const int UVpitch = to_y ? 0 : dst->GetPitch(PLANAR_U);\n\n  const bool packedRGBsource = pixel_step > 0;\n\n  if (packedRGBsource) {\n    env->ThrowError(\"Packed RGB is no more allowed here, already preconverted to planar RGB. This is a bug.\");\n  }\n\n  // here we do planar RGB only\n  const int bits_per_pixel = source_bit_depth;\n\n  // copy or fill alpha\n  // Two places, at YUV444toPlanarRGB as well\n  BYTE* dstpA;\n  if (targetHasAlpha) {\n    dstpA = dst->GetWritePtr(PLANAR_A);\n    int heightA = dst->GetHeight(PLANAR_A);\n    int rowsizeA = dst->GetRowSize(PLANAR_A);\n    int dst_pitchA = dst->GetPitch(PLANAR_A);\n    // simple copy\n    if (src->GetRowSize(PLANAR_A)) {\n\n      if (source_bit_depth == target_bit_depth) {\n        // vi.IsYUVA() no-no! vi is already the target video type\n        env->BitBlt(dstpA, dst_pitchA, src->GetReadPtr(PLANAR_A), src->GetPitch(PLANAR_A), src->GetRowSize(PLANAR_A_ALIGNED), src->GetHeight(PLANAR_A));\n      }\n      else {\n        // RGBPA target + different bit-depth\n        // Alpha bit depth conversion needed, normal planes are done in-process.\n        // we need only conv_function_a, proper dispatching from ConvertBits\n        conv_function_a(src->GetReadPtr(PLANAR_A), dstpA, src->GetRowSize(PLANAR_A), heightA, src->GetPitch(PLANAR_A), dst_pitchA, source_bit_depth, target_bit_depth, -1);\n      }\n    }\n    else {\n      // fill default transparency\n      switch (target_bit_depth)\n      {\n      case 1:\n        fill_plane<BYTE>(dstpA, heightA, rowsizeA, dst_pitchA, 255);\n        break;\n      case 2:\n        fill_plane<uint16_t>(dstpA, heightA, rowsizeA, dst_pitchA, (1 << target_bit_depth) - 1);\n        break;\n      case 4:\n        fill_plane<float>(dstpA, heightA, rowsizeA, dst_pitchA, 1.0f);\n        break;\n      }\n    }\n  }\n\n  const BYTE* srcp[3] = { src->GetReadPtr(PLANAR_G), src->GetReadPtr(PLANAR_B), src->GetReadPtr(PLANAR_R) };\n  const int srcPitch[3] = { src->GetPitch(PLANAR_G), src->GetPitch(PLANAR_B), src->GetPitch(PLANAR_R) };\n\n  BYTE* dstp[3] = { dstY, dstU, dstV };\n  int dstPitch[3] = { Ypitch, UVpitch, UVpitch };\n\n  const bool force_float = quality;\n\n  // to Y\n\n  if (to_y) {\n#ifdef INTEL_INTRINSICS\n    if (env->GetCPUFlags() & CPUF_AVX2) {\n      if (bits_per_pixel == 8)\n        convert_yuv_to_planarrgb_avx2<ConversionDirection::RGB_TO_Y, uint8_t, true>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n      else if (bits_per_pixel < 16)\n        convert_yuv_to_planarrgb_avx2<ConversionDirection::RGB_TO_Y, uint16_t, true>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n      else if (bits_per_pixel == 16)\n        convert_yuv_to_planarrgb_avx2<ConversionDirection::RGB_TO_Y, uint16_t, false>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n      else if (bits_per_pixel == 32)\n        convert_yuv_to_planarrgb_avx2<ConversionDirection::RGB_TO_Y, float, false>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n      return dst;\n    }\n\n    if (env->GetCPUFlags() & CPUF_SSE2) {\n      if (bits_per_pixel == 8)\n        convert_yuv_to_planarrgb_sse2<ConversionDirection::RGB_TO_Y, uint8_t, true>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n      else if (bits_per_pixel < 16)\n        convert_yuv_to_planarrgb_sse2<ConversionDirection::RGB_TO_Y, uint16_t, true>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n      else if (bits_per_pixel == 16)\n        convert_yuv_to_planarrgb_sse2<ConversionDirection::RGB_TO_Y, uint16_t, false>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n      else if (bits_per_pixel == 32)\n        convert_yuv_to_planarrgb_sse2<ConversionDirection::RGB_TO_Y, float, false>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n      return dst;\n    }\n\n#endif\n\n    if (bits_per_pixel == 8)\n      convert_yuv_to_planarrgb_c<ConversionDirection::RGB_TO_Y, uint8_t, true>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n    else if (bits_per_pixel < 16)\n      convert_yuv_to_planarrgb_c<ConversionDirection::RGB_TO_Y, uint16_t, true>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n    else if (bits_per_pixel == 16)\n      convert_yuv_to_planarrgb_c<ConversionDirection::RGB_TO_Y, uint16_t, false>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n    else if (bits_per_pixel == 32)\n      convert_yuv_to_planarrgb_c<ConversionDirection::RGB_TO_Y, float, false>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n    return dst;\n  }\n\n  // to YUV\n\n#ifdef INTEL_INTRINSICS\n  if (env->GetCPUFlags() & CPUF_AVX2) {\n    if (bits_per_pixel == 8)\n      convert_yuv_to_planarrgb_avx2<ConversionDirection::RGB_TO_YUV, uint8_t, true>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n    else if (bits_per_pixel < 16)\n      convert_yuv_to_planarrgb_avx2<ConversionDirection::RGB_TO_YUV, uint16_t, true>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n    else if (bits_per_pixel == 16)\n      convert_yuv_to_planarrgb_avx2<ConversionDirection::RGB_TO_YUV, uint16_t, false>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n    else if (bits_per_pixel == 32)\n      convert_yuv_to_planarrgb_avx2<ConversionDirection::RGB_TO_YUV, float, false>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n    return dst;\n  }\n\n  if (env->GetCPUFlags() & CPUF_SSE2) {\n    if (bits_per_pixel == 8)\n      convert_yuv_to_planarrgb_sse2<ConversionDirection::RGB_TO_YUV, uint8_t, true>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n    else if (bits_per_pixel < 16)\n      convert_yuv_to_planarrgb_sse2<ConversionDirection::RGB_TO_YUV, uint16_t, true>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n    else if (bits_per_pixel == 16)\n      convert_yuv_to_planarrgb_sse2<ConversionDirection::RGB_TO_YUV, uint16_t, false>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n    else if (bits_per_pixel == 32)\n      convert_yuv_to_planarrgb_sse2<ConversionDirection::RGB_TO_YUV, float, false>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n    return dst;\n  }\n\n#endif\n\n  if (bits_per_pixel == 8)\n    convert_yuv_to_planarrgb_c<ConversionDirection::RGB_TO_YUV, uint8_t, true>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n  else if (bits_per_pixel < 16)\n    convert_yuv_to_planarrgb_c<ConversionDirection::RGB_TO_YUV, uint16_t, true>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n  else if (bits_per_pixel == 16)\n    convert_yuv_to_planarrgb_c<ConversionDirection::RGB_TO_YUV, uint16_t, false>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n  else if (bits_per_pixel == 32)\n    convert_yuv_to_planarrgb_c<ConversionDirection::RGB_TO_YUV, float, false>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n  return dst;\n\n}\n\n\n\n/*****************************************************\n * ConvertYV24ToRGB\n *\n * (c) Klaus Post, 2005\n * Generic 4:4:4(:4), 16 bit and Planar RGB(A) support 2016 by PF\n ******************************************************/\n\n\nConvertYUV444ToRGB::ConvertYUV444ToRGB(PClip src, const char *matrix_name, int _pixel_step, int _target_bit_depth, bool _quality, bool& bitdepthConverted, IScriptEnvironment* env)\n  : GenericVideoFilter(src), pixel_step(_pixel_step), target_bit_depth(_target_bit_depth), quality(_quality), conv_function(nullptr), conv_function_chroma(nullptr), conv_function_a(nullptr)\n{\n\n  if (!vi.Is444())\n    env->ThrowError(\"ConvertYUV444ToRGB: Only 4:4:4 data input accepted\");\n\n  auto frame0 = child->GetFrame(0, env);\n  const AVSMap* props = env->getFramePropsRO(frame0);\n  matrix_parse_merge_with_props(false /*in yuv*/, true /*out rgb*/, matrix_name, props, theMatrix, theColorRange, theOutColorRange, env);\n  // Good to know:\n  // - When frame property \"_ColorRange\" exists, it overrides the default output RGB color range.\n  // - PC.xxx old-style matrix names leave the color range unchanged, whether they exist or not.\n  // - When using PC.xxx and YUV is limited => output RGB is narrow range (limited)\n  // - Other non PC.xxx old matrix names:\n  //   - input range is defined by the matrix name, even if _ColorRange frame property exists\n  //   - output range is default Full for RGB, unless _ColorRange exists, when its value defines the output RGB range (full or limited/narrow)\n  // - new style matrix definitions: see docs. Preserve what is not set, distinct :f or :l suffixes may tell the color range, not part of matrix name.\n  // - Matrix coefficients still need to know input and output color range (full or limited/narrow) so by this time we have these two.\n\n  const int shift = 13; // for integer arithmetic, over 13 bits would overflow the matrix elements/internal calculation\n  const int bits_per_pixel = vi.BitsPerComponent();\n  source_bit_depth = bits_per_pixel;\n\n  if (!do_BuildMatrix_Yuv2Rgb(theMatrix, theColorRange, theOutColorRange, shift, source_bit_depth, /*ref*/matrix))\n    env->ThrowError(\"ConvertYUV444ToRGB: Unknown matrix.\");\n\n  // Old comment: what is not implemented in-process, we do the conversion with invoked ConvertBits()\n  // Now all source-target combinations are supported.\n\n  // target_bit_depth == -1: no conversion required\n  const bool need_bitdepth_conversion = (target_bit_depth != -1);\n\n  // get alpha converter, GetFrame is using that if alpha must be depth-converterd and not only copied\n  if (need_bitdepth_conversion)\n  {\n    // supported conversions:\n    // 8-16-bits any range to 8-16, 32 bits any range\n    bitdepthConverted = true;\n#ifdef INTEL_INTRINSICS\n    const bool sse2 = !!(env->GetCPUFlags() & CPUF_SSE2);\n    const bool sse4 = !!(env->GetCPUFlags() & CPUF_SSE4_1);\n    const bool avx2 = !!(env->GetCPUFlags() & CPUF_AVX2);\n    // we really need only alpha conversion function\n    const bool fulls = true; // alpha is always full range\n    const bool fulld = true; // alpha is always full range\n    const int dither_mode = -1;\n#ifdef INTEL_INTRINSICS\n    get_convert_any_bits_functions(dither_mode, source_bit_depth, target_bit_depth, fulls, fulld, sse2, sse4, avx2, conv_function, conv_function_chroma, conv_function_a);\n#else\n    get_convert_any_bits_functions(dither_mode, source_bit_depth, target_bit_depth, fulls, fulld, conv_function, conv_function_chroma, conv_function_a);\n#endif\n\n#endif\n\n  }\n  else {\n    bitdepthConverted = false;\n    target_bit_depth = source_bit_depth;\n  }\n\n  theOutMatrix = Matrix_e::AVS_MATRIX_RGB;\n\n  switch (pixel_step)\n  {\n  case -1: case -2: // target is planar RGB(A): all bit depths supported\n    {\n      const bool hasAlpha = (pixel_step == -2);\n      switch (target_bit_depth)\n      {\n      case 8:  vi.pixel_type = hasAlpha ? VideoInfo::CS_RGBAP : VideoInfo::CS_RGBP; break;\n      case 10: vi.pixel_type = hasAlpha ? VideoInfo::CS_RGBAP10 : VideoInfo::CS_RGBP10; break;\n      case 12: vi.pixel_type = hasAlpha ? VideoInfo::CS_RGBAP12 : VideoInfo::CS_RGBP12; break;\n      case 14: vi.pixel_type = hasAlpha ? VideoInfo::CS_RGBAP14 : VideoInfo::CS_RGBP14; break;\n      case 16: vi.pixel_type = hasAlpha ? VideoInfo::CS_RGBAP16 : VideoInfo::CS_RGBP16; break;\n      case 32: vi.pixel_type = hasAlpha ? VideoInfo::CS_RGBAPS : VideoInfo::CS_RGBPS; break;\n      default:\n        env->ThrowError(\"ConvertYUV444ToRGB: invalid vi.BitsPerComponent(): %d\", vi.BitsPerComponent());\n      }\n    }\n    break;\n  case 3: vi.pixel_type = VideoInfo::CS_BGR24; break;\n  case 4: vi.pixel_type = VideoInfo::CS_BGR32; break;\n  case 6: vi.pixel_type = VideoInfo::CS_BGR48; break;\n  case 8: vi.pixel_type = VideoInfo::CS_BGR64; break;\n  default:\n    env->ThrowError(\"ConvertYUV444ToRGB: invalid pixel step: %d\", pixel_step);\n  }\n\n}\n\ntemplate<int pixel_step, bool source_has_alpha>\nstatic void convert_yv24_to_rgb_c(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE* srcV, const BYTE* srcA, int dst_pitch, int src_pitch_y, int src_pitch_uv, int src_pitch_a, int width, int height, const ConversionMatrix& matrix)\n{\n  dstp += dst_pitch * (height - 1);  // We start at last line. Packed RGB is bottom-up.\n  auto round_mask_plus_rgb_offset_i = 4096 + (matrix.offset_rgb << 13);\n  if constexpr (pixel_step == 4) { // RGB32\n    for (int y = 0; y < height; y++) {\n      for (int x = 0; x < width; x++) {\n        int Y = srcY[x] + matrix.offset_y;\n        int U = srcU[x] - 128;\n        int V = srcV[x] - 128;\n        uint8_t a = source_has_alpha ? srcA[x] : 255; // YUVA aware\n        int b = (((int)matrix.y_b * Y + (int)matrix.u_b * U + (int)matrix.v_b * V + round_mask_plus_rgb_offset_i) >> 13);\n        int g = (((int)matrix.y_g * Y + (int)matrix.u_g * U + (int)matrix.v_g * V + round_mask_plus_rgb_offset_i) >> 13);\n        int r = (((int)matrix.y_r * Y + (int)matrix.u_r * U + (int)matrix.v_r * V + round_mask_plus_rgb_offset_i) >> 13);\n        dstp[x * 4 + 0] = PixelClip(b);  // All the safety we can wish for.\n        dstp[x * 4 + 1] = PixelClip(g);  // Probably needed here.\n        dstp[x * 4 + 2] = PixelClip(r);\n        dstp[x * 4 + 3] = a; // alpha\n      }\n      dstp -= dst_pitch;\n      srcY += src_pitch_y;\n      srcU += src_pitch_uv;\n      srcV += src_pitch_uv;\n      srcA += src_pitch_a;\n    }\n  }\n  else if constexpr (pixel_step == 3) { // RGB24\n    const int Dstep = dst_pitch + (width * pixel_step);\n    for (int y = 0; y < height; y++) {\n      for (int x = 0; x < width; x++) {\n        int Y = srcY[x] + matrix.offset_y;\n        int U = srcU[x] - 128;\n        int V = srcV[x] - 128;\n        int b = (((int)matrix.y_b * Y + (int)matrix.u_b * U + (int)matrix.v_b * V + round_mask_plus_rgb_offset_i) >> 13);\n        int g = (((int)matrix.y_g * Y + (int)matrix.u_g * U + (int)matrix.v_g * V + round_mask_plus_rgb_offset_i) >> 13);\n        int r = (((int)matrix.y_r * Y + (int)matrix.u_r * U + (int)matrix.v_r * V + round_mask_plus_rgb_offset_i) >> 13);\n        dstp[0] = PixelClip(b);  // All the safety we can wish for.\n        dstp[1] = PixelClip(g);  // Probably needed here.\n        dstp[2] = PixelClip(r);\n        dstp += pixel_step;\n      }\n      dstp -= Dstep;\n      srcY += src_pitch_y;\n      srcU += src_pitch_uv;\n      srcV += src_pitch_uv;\n    }\n  }\n}\n\n\n// C reference implementation matching AVX2/SSE2 logic with all conversion directions\ntemplate<ConversionDirection direction, typename pixel_t, bool lessthan16bit, bool lessthan16bit_target, typename pixel_t_dst, YuvRgbConversionType conv_type>\nstatic void convert_yuv_to_planarrgb_c_internal(BYTE* dstp[3], int dstPitch[3], const BYTE* srcp[3], const int srcPitch[3], int width, int height, const ConversionMatrix& m,\n  int bits_per_pixel, int bits_per_pixel_target)\n{\n  // int64_t needed for exact 16 bit pixels in integer workflow\n  // float input always uses float workflow\n  typedef typename std::conditional<sizeof(pixel_t) == 1 || lessthan16bit, int, int64_t>::type safe_int_t;\n\n  constexpr int INT_ARITH_SHIFT =\n    (direction == ConversionDirection::YUV_TO_RGB) ? 13 :\n    (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::RGB_TO_Y) ? 15 :\n    (direction == ConversionDirection::YUV_TO_YUV) ? 14 : 13;\n\n  // Validate: float input requires FORCE_FLOAT conversion type\n  static_assert(!(std::is_floating_point<pixel_t>::value && conv_type != YuvRgbConversionType::FORCE_FLOAT),\n    \"FORCE_FLOAT conversion type is required for float input pixel type\");\n\n  constexpr bool force_float = conv_type == YuvRgbConversionType::FORCE_FLOAT;\n  constexpr bool final_is_float = std::is_floating_point<pixel_t_dst>::value;\n  constexpr bool need_int_conversion_narrow_range = conv_type == YuvRgbConversionType::BITCONV_INT_LIMITED;\n  constexpr bool need_int_conversion_full_range = conv_type == YuvRgbConversionType::BITCONV_INT_FULL;\n  constexpr bool need_int_conversion = conv_type == YuvRgbConversionType::BITCONV_INT_FULL ||\n    conv_type == YuvRgbConversionType::BITCONV_INT_LIMITED ||\n    (conv_type == YuvRgbConversionType::FORCE_FLOAT && !final_is_float);\n  const bool float_matrix_workflow = force_float || need_int_conversion_full_range;\n\n  // quasi-constexpr, may help optimizer\n  if constexpr (std::is_same<pixel_t, uint8_t>::value) bits_per_pixel = 8;\n  if constexpr (std::is_same<pixel_t_dst, uint8_t>::value) bits_per_pixel_target = 8;\n  if constexpr (std::is_same<pixel_t, uint16_t>::value && !lessthan16bit) bits_per_pixel = 16;\n  if constexpr (std::is_same<pixel_t_dst, uint16_t>::value && !lessthan16bit_target) bits_per_pixel_target = 16;\n  if constexpr (conv_type == YuvRgbConversionType::NATIVE_INT) bits_per_pixel_target = bits_per_pixel;\n\n  const int bit_diff = need_int_conversion ? bits_per_pixel_target - bits_per_pixel : 0;\n  const int target_shift = need_int_conversion_narrow_range ? INT_ARITH_SHIFT - bit_diff : INT_ARITH_SHIFT;\n  const int ROUNDER = (final_is_float || float_matrix_workflow) ? 0 : (1 << (target_shift - 1));\n\n  const float out_offset_f = m.offset_out_f_32;\n  const int half_pixel_offset = 1 << (bits_per_pixel - 1);\n  const int half_pixel_offset_target = 1 << (bits_per_pixel_target - 1);\n  const int max_pixel_value_target = (1 << bits_per_pixel_target) - 1;\n\n  bits_conv_constants conversion_ranges;\n  const bool full_scale_d = m.offset_out == 0;\n  get_bits_conv_constants(conversion_ranges, false, full_scale_d, full_scale_d, bits_per_pixel, bits_per_pixel_target);\n\n  constexpr int int_arithmetic_shift = 1 << INT_ARITH_SHIFT;\n  float scale_f = conversion_ranges.mul_factor;\n  if (final_is_float && !float_matrix_workflow)\n    scale_f = scale_f / int_arithmetic_shift;\n\n  const int offset_in_scalar = m.offset_in;\n  const int offset_out_scalar = m.offset_out;\n\n  int round_mask_plus_offset_out_i;\n  int round_mask_plus_offset_out_chroma_i;\n\n  if constexpr (!float_matrix_workflow) {\n    round_mask_plus_offset_out_i = final_is_float ? 0 : ROUNDER + (offset_out_scalar << INT_ARITH_SHIFT);\n    round_mask_plus_offset_out_chroma_i = final_is_float ? 0 : ROUNDER + (half_pixel_offset << INT_ARITH_SHIFT);\n  }\n\n  for (int y = 0; y < height; y++) {\n    const pixel_t* src0 = reinterpret_cast<const pixel_t*>(srcp[0]); // Y or G\n    const pixel_t* src1 = reinterpret_cast<const pixel_t*>(srcp[1]); // U or B\n    const pixel_t* src2 = reinterpret_cast<const pixel_t*>(srcp[2]); // V or R\n    pixel_t_dst* d0 = reinterpret_cast<pixel_t_dst*>(dstp[0]); // G or Y\n    pixel_t_dst* d1 = reinterpret_cast<pixel_t_dst*>(dstp[1]); // B or U\n    pixel_t_dst* d2 = reinterpret_cast<pixel_t_dst*>(dstp[2]); // R or V\n\n    for (int x = 0; x < width; x++) {\n      float in0_f, in1_f, in2_f;\n      int in0_i, in1_i, in2_i;\n\n      // Load inputs\n      if constexpr (std::is_floating_point<pixel_t>::value) {\n        in0_f = src0[x];\n        in1_f = src1[x];\n        in2_f = src2[x];\n      }\n      else {\n        in0_i = static_cast<int>(src0[x]);\n        in1_i = static_cast<int>(src1[x]);\n        in2_i = static_cast<int>(src2[x]);\n      }\n\n      float out0_f, out1_f, out2_f;\n      safe_int_t out0_raw, out1_raw, out2_raw; // Keep as int64_t for 16-bit\n\n      if constexpr (float_matrix_workflow) {\n        // Float workflow\n        if constexpr (!std::is_floating_point<pixel_t>::value) {\n          // Convert integer to float and apply input offset\n          if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::YUV_TO_YUV) {\n            // YUV input\n            in0_f = static_cast<float>(in0_i + offset_in_scalar); // Y\n            in1_f = static_cast<float>(in1_i - half_pixel_offset); // U\n            in2_f = static_cast<float>(in2_i - half_pixel_offset); // V\n          }\n          else if constexpr (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::RGB_TO_Y || direction == ConversionDirection::RGB_TO_RGB) {\n            // RGB input\n            in0_f = static_cast<float>(in0_i + offset_in_scalar); // G\n            in1_f = static_cast<float>(in1_i + offset_in_scalar); // B\n            in2_f = static_cast<float>(in2_i + offset_in_scalar); // R\n          }\n        }\n        else {\n          // Float input - apply offset\n          if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::YUV_TO_YUV) {\n            in0_f += m.offset_in_f; // Y only\n          }\n          else {\n            in0_f += m.offset_in_f; // G\n            in1_f += m.offset_in_f; // B\n            in2_f += m.offset_in_f; // R\n          }\n        }\n\n        // Matrix multiply - coefficient order depends on direction\n        if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::YUV_TO_YUV) {\n          // YUV input: in0=Y, in1=U, in2=V\n          out0_f = (m.y_g_f * in0_f + m.u_g_f * in1_f + m.v_g_f * in2_f) * scale_f; // G or Y\n          out1_f = (m.y_b_f * in0_f + m.u_b_f * in1_f + m.v_b_f * in2_f) * scale_f; // B or U\n          out2_f = (m.y_r_f * in0_f + m.u_r_f * in1_f + m.v_r_f * in2_f) * scale_f; // R or V\n        }\n        else if constexpr (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::RGB_TO_RGB) {\n          // RGB input: in0=G, in1=B, in2=R\n          out0_f = (m.y_g_f * in0_f + m.y_b_f * in1_f + m.y_r_f * in2_f) * scale_f; // Y or G\n          out1_f = (m.u_g_f * in0_f + m.u_b_f * in1_f + m.u_r_f * in2_f) * scale_f; // U or B\n          out2_f = (m.v_g_f * in0_f + m.v_b_f * in1_f + m.v_r_f * in2_f) * scale_f; // V or R\n        }\n        else if constexpr (direction == ConversionDirection::RGB_TO_Y) {\n          // RGB input: in0=G, in1=B, in2=R\n          out0_f = (m.y_g_f * in0_f + m.y_b_f * in1_f + m.y_r_f * in2_f) * scale_f; // Y or G\n        }\n\n        // Add output offset\n        if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::RGB_TO_RGB) {\n          // RGB output: same offset for all\n          float rgb_offset_scaled = m.offset_out_f * scale_f;\n          out0_f += rgb_offset_scaled;\n          out1_f += rgb_offset_scaled;\n          out2_f += rgb_offset_scaled;\n        }\n        else if constexpr (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::YUV_TO_YUV) {\n          // YUV output: different offsets\n          float y_offset_scaled = m.offset_out_f * scale_f;\n          float uv_center = final_is_float ? 0.0f : (float)half_pixel_offset_target;\n          out0_f += y_offset_scaled; // Y\n          out1_f += uv_center; // U\n          out2_f += uv_center; // V\n        }\n        else if constexpr (direction == ConversionDirection::RGB_TO_Y) {\n          // Y output: single Y offsets\n          float y_offset_scaled = m.offset_out_f * scale_f;\n          out0_f += y_offset_scaled; // Y\n        }\n\n        if constexpr (final_is_float) {\n          d0[x] = static_cast<pixel_t_dst>(out0_f);\n          if constexpr (direction != ConversionDirection::RGB_TO_Y) {\n            d1[x] = static_cast<pixel_t_dst>(out1_f);\n            d2[x] = static_cast<pixel_t_dst>(out2_f);\n          }\n        }\n        else {\n          // Convert to integer with rounding\n          int out0_i = static_cast<int>(out0_f + 0.5f);\n          out0_i = std::clamp(out0_i, 0, max_pixel_value_target);\n          d0[x] = static_cast<pixel_t_dst>(out0_i);\n\n          if constexpr (direction != ConversionDirection::RGB_TO_Y) {\n            int out1_i = static_cast<int>(out1_f + 0.5f);\n            int out2_i = static_cast<int>(out2_f + 0.5f);\n            out1_i = std::clamp(out1_i, 0, max_pixel_value_target);\n            out2_i = std::clamp(out2_i, 0, max_pixel_value_target);\n            d1[x] = static_cast<pixel_t_dst>(out1_i);\n            d2[x] = static_cast<pixel_t_dst>(out2_i);\n          }\n        }\n      }\n      else {\n        // Integer workflow\n        // Apply input offset and centering\n        if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::YUV_TO_YUV) {\n          // YUV input\n          in0_i = in0_i + offset_in_scalar; // Y\n          in1_i = in1_i - half_pixel_offset; // U (centered)\n          in2_i = in2_i - half_pixel_offset; // V (centered)\n        }\n        else if constexpr (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::RGB_TO_RGB || direction == ConversionDirection::RGB_TO_Y) {\n          // RGB input\n          in0_i = in0_i + offset_in_scalar; // G\n          in1_i = in1_i + offset_in_scalar; // B\n          in2_i = in2_i + offset_in_scalar; // R\n        }\n\n        // Matrix multiply with appropriate rounding/offset\n        int round_and_offset_0, round_and_offset_1, round_and_offset_2;\n\n        if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::RGB_TO_RGB) {\n          // RGB output: same offset for all\n          round_and_offset_0 = round_mask_plus_offset_out_i;\n          round_and_offset_1 = round_mask_plus_offset_out_i;\n          round_and_offset_2 = round_mask_plus_offset_out_i;\n        }\n        else if constexpr (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::YUV_TO_YUV) {\n          // YUV output: different offsets\n          round_and_offset_0 = round_mask_plus_offset_out_i; // Y\n          round_and_offset_1 = round_mask_plus_offset_out_chroma_i; // U\n          round_and_offset_2 = round_mask_plus_offset_out_chroma_i; // V\n        }\n        else if constexpr (direction == ConversionDirection::RGB_TO_Y) {\n          // Y output: single Y offset\n          round_and_offset_0 = round_mask_plus_offset_out_i; // Y\n        }\n\n        if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::YUV_TO_YUV) {\n          // YUV input: in0=Y, in1=U, in2=V\n          out0_raw = (safe_int_t)m.y_g * in0_i + (safe_int_t)m.u_g * in1_i + (safe_int_t)m.v_g * in2_i + round_and_offset_0;\n          out1_raw = (safe_int_t)m.y_b * in0_i + (safe_int_t)m.u_b * in1_i + (safe_int_t)m.v_b * in2_i + round_and_offset_1;\n          out2_raw = (safe_int_t)m.y_r * in0_i + (safe_int_t)m.u_r * in1_i + (safe_int_t)m.v_r * in2_i + round_and_offset_2;\n        }\n        else if constexpr (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::RGB_TO_RGB) {\n          // RGB input: in0=G, in1=B, in2=R\n          out0_raw = (safe_int_t)m.y_g * in0_i + (safe_int_t)m.y_b * in1_i + (safe_int_t)m.y_r * in2_i + round_and_offset_0;\n          out1_raw = (safe_int_t)m.u_g * in0_i + (safe_int_t)m.u_b * in1_i + (safe_int_t)m.u_r * in2_i + round_and_offset_1;\n          out2_raw = (safe_int_t)m.v_g * in0_i + (safe_int_t)m.v_b * in1_i + (safe_int_t)m.v_r * in2_i + round_and_offset_2;\n        }\n        else if constexpr (direction == ConversionDirection::RGB_TO_Y) {\n          // RGB input: in0=G, in1=B, in2=R\n          out0_raw = (safe_int_t)m.y_g * in0_i + (safe_int_t)m.y_b * in1_i + (safe_int_t)m.y_r * in2_i + round_and_offset_0;\n        }\n\n        if constexpr (final_is_float) {\n          // Integer workflow + float output\n          out0_f = static_cast<float>(out0_raw) * scale_f + out_offset_f;\n          if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::RGB_TO_RGB) {\n            // offset for the rest two only RGB output\n            out1_f = static_cast<float>(out1_raw) * scale_f + out_offset_f;\n            out2_f = static_cast<float>(out2_raw) * scale_f + out_offset_f;\n          }\n          else if constexpr (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::YUV_TO_YUV) {\n            // for YUV the U and V float offset is different : 0.0f\n            out1_f = static_cast<float>(out1_raw) * scale_f; // U\n            out2_f = static_cast<float>(out2_raw) * scale_f; // V\n          }\n\n          d0[x] = static_cast<pixel_t_dst>(out0_f);\n          if constexpr (direction != ConversionDirection::RGB_TO_Y) {\n            d1[x] = static_cast<pixel_t_dst>(out1_f);\n            d2[x] = static_cast<pixel_t_dst>(out2_f);\n          }\n        }\n        else {\n          // Integer workflow + integer output\n          int out0_i = static_cast<int>(out0_raw >> target_shift);\n          out0_i = std::clamp(out0_i, 0, max_pixel_value_target);\n          d0[x] = static_cast<pixel_t_dst>(out0_i);\n\n          if constexpr (direction != ConversionDirection::RGB_TO_Y) {\n            int out1_i = static_cast<int>(out1_raw >> target_shift);\n            int out2_i = static_cast<int>(out2_raw >> target_shift);\n\n            // We are in integer domain, no convenient SIMD packus! We cannot spare min-max clamp to constexpr (lessthan16bit_target) {\n            // We need to do it always\n            out1_i = std::clamp(out1_i, 0, max_pixel_value_target);\n            out2_i = std::clamp(out2_i, 0, max_pixel_value_target);\n\n            d1[x] = static_cast<pixel_t_dst>(out1_i);\n            d2[x] = static_cast<pixel_t_dst>(out2_i);\n          }\n        }\n      }\n    }\n\n    dstp[0] += dstPitch[0];\n    if constexpr (direction != ConversionDirection::RGB_TO_Y) {\n      dstp[1] += dstPitch[1];\n      dstp[2] += dstPitch[2];\n    }\n    srcp[0] += srcPitch[0];\n    srcp[1] += srcPitch[1];\n    srcp[2] += srcPitch[2];\n  }\n}\n\n// Dispatcher matching AVX2/SSE2 structure\ntemplate<ConversionDirection direction, typename pixel_t_src, bool lessthan16bit>\nvoid convert_yuv_to_planarrgb_c(BYTE* dstp[3], int dstPitch[3], const BYTE* srcp[3], const int srcPitch[3], int width, int height, const ConversionMatrix& m,\n  int bits_per_pixel, int bits_per_pixel_target, bool force_float)\n{\n  // Handle forced float or float input\n  if (force_float || std::is_floating_point<pixel_t_src>::value) {\n    if (bits_per_pixel_target == 8) {\n      convert_yuv_to_planarrgb_c_internal<direction, pixel_t_src, lessthan16bit, true, uint8_t, YuvRgbConversionType::FORCE_FLOAT>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n    }\n    else if (bits_per_pixel_target < 16) {\n      convert_yuv_to_planarrgb_c_internal<direction, pixel_t_src, lessthan16bit, true, uint16_t, YuvRgbConversionType::FORCE_FLOAT>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n    }\n    else if (bits_per_pixel_target == 16) {\n      convert_yuv_to_planarrgb_c_internal<direction, pixel_t_src, lessthan16bit, false, uint16_t, YuvRgbConversionType::FORCE_FLOAT>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n    }\n    else {\n      convert_yuv_to_planarrgb_c_internal<direction, pixel_t_src, lessthan16bit, false, float, YuvRgbConversionType::FORCE_FLOAT>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n    }\n    return;\n  }\n\n  if constexpr (!std::is_floating_point<pixel_t_src>::value) {\n    const bool need_conversion = bits_per_pixel_target != bits_per_pixel;\n    if (!need_conversion) {\n      convert_yuv_to_planarrgb_c_internal<direction, pixel_t_src, lessthan16bit, lessthan16bit, pixel_t_src, YuvRgbConversionType::NATIVE_INT>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n      return;\n    }\n\n    const bool full_d = m.offset_out == 0;\n    if (bits_per_pixel_target >= 8 && bits_per_pixel <= 16) {\n      if (bits_per_pixel_target == 8) {\n        if (full_d)\n          convert_yuv_to_planarrgb_c_internal<direction, pixel_t_src, lessthan16bit, true, uint8_t, YuvRgbConversionType::BITCONV_INT_FULL>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n        else\n          convert_yuv_to_planarrgb_c_internal<direction, pixel_t_src, lessthan16bit, true, uint8_t, YuvRgbConversionType::BITCONV_INT_LIMITED>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n      }\n      else if (bits_per_pixel_target < 16) {\n        if (full_d)\n          convert_yuv_to_planarrgb_c_internal<direction, pixel_t_src, lessthan16bit, true, uint16_t, YuvRgbConversionType::BITCONV_INT_FULL>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n        else\n          convert_yuv_to_planarrgb_c_internal<direction, pixel_t_src, lessthan16bit, true, uint16_t, YuvRgbConversionType::BITCONV_INT_LIMITED>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n      }\n      else if (bits_per_pixel_target == 16) {\n        if (full_d)\n          convert_yuv_to_planarrgb_c_internal<direction, pixel_t_src, lessthan16bit, false, uint16_t, YuvRgbConversionType::BITCONV_INT_FULL>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n        else\n          convert_yuv_to_planarrgb_c_internal<direction, pixel_t_src, lessthan16bit, false, uint16_t, YuvRgbConversionType::BITCONV_INT_LIMITED>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n      }\n      else {\n        convert_yuv_to_planarrgb_c_internal<direction, pixel_t_src, lessthan16bit, false, float, YuvRgbConversionType::FLOAT_OUTPUT>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n      }\n    }\n  }\n}\n\n// Template instantiations for C version - all 4 directions\n// YUV_TO_RGB\ntemplate void convert_yuv_to_planarrgb_c<ConversionDirection::YUV_TO_RGB, uint8_t, true>(BYTE* dstp[3], int dstPitch[3], const BYTE* srcp[3], const int srcPitch[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_c<ConversionDirection::YUV_TO_RGB, uint16_t, true>(BYTE* dstp[3], int dstPitch[3], const BYTE* srcp[3], const int srcPitch[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_c<ConversionDirection::YUV_TO_RGB, uint16_t, false>(BYTE* dstp[3], int dstPitch[3], const BYTE* srcp[3], const int srcPitch[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_c<ConversionDirection::YUV_TO_RGB, float, false>(BYTE* dstp[3], int dstPitch[3], const BYTE* srcp[3], const int srcPitch[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\n\n// RGB_TO_YUV\ntemplate void convert_yuv_to_planarrgb_c<ConversionDirection::RGB_TO_YUV, uint8_t, true>(BYTE* dstp[3], int dstPitch[3], const BYTE* srcp[3], const int srcPitch[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_c<ConversionDirection::RGB_TO_YUV, uint16_t, true>(BYTE* dstp[3], int dstPitch[3], const BYTE* srcp[3], const int srcPitch[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_c<ConversionDirection::RGB_TO_YUV, uint16_t, false>(BYTE* dstp[3], int dstPitch[3], const BYTE* srcp[3], const int srcPitch[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_c<ConversionDirection::RGB_TO_YUV, float, false>(BYTE* dstp[3], int dstPitch[3], const BYTE* srcp[3], const int srcPitch[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\n\n// RGB_TO_Y\ntemplate void convert_yuv_to_planarrgb_c<ConversionDirection::RGB_TO_Y, uint8_t, true>(BYTE* dstp[3], int dstPitch[3], const BYTE* srcp[3], const int srcPitch[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_c<ConversionDirection::RGB_TO_Y, uint16_t, true>(BYTE* dstp[3], int dstPitch[3], const BYTE* srcp[3], const int srcPitch[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_c<ConversionDirection::RGB_TO_Y, uint16_t, false>(BYTE* dstp[3], int dstPitch[3], const BYTE* srcp[3], const int srcPitch[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_c<ConversionDirection::RGB_TO_Y, float, false>(BYTE* dstp[3], int dstPitch[3], const BYTE* srcp[3], const int srcPitch[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\n\n// YUV_TO_YUV\ntemplate void convert_yuv_to_planarrgb_c<ConversionDirection::YUV_TO_YUV, uint8_t, true>(BYTE* dstp[3], int dstPitch[3], const BYTE* srcp[3], const int srcPitch[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_c<ConversionDirection::YUV_TO_YUV, uint16_t, true>(BYTE* dstp[3], int dstPitch[3], const BYTE* srcp[3], const int srcPitch[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_c<ConversionDirection::YUV_TO_YUV, uint16_t, false>(BYTE* dstp[3], int dstPitch[3], const BYTE* srcp[3], const int srcPitch[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_c<ConversionDirection::YUV_TO_YUV, float, false>(BYTE* dstp[3], int dstPitch[3], const BYTE* srcp[3], const int srcPitch[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\n\nPVideoFrame __stdcall ConvertYUV444ToRGB::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame src = child->GetFrame(n, env);\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n\n  auto props = env->getFramePropsRW(dst);\n  update_Matrix_and_ColorRange(props, theOutMatrix, theOutColorRange, env);\n  update_ChromaLocation(props, -1, env); // RGB target: delete _ChromaLocation\n\n  const BYTE* srcY = src->GetReadPtr(PLANAR_Y);\n  const BYTE* srcU = src->GetReadPtr(PLANAR_U);\n  const BYTE* srcV = src->GetReadPtr(PLANAR_V);\n  const BYTE* srcA = src->GetReadPtr(PLANAR_A);\n\n  BYTE* dstp = dst->GetWritePtr();\n\n  const int src_pitch_y = src->GetPitch(PLANAR_Y);\n  const int src_pitch_uv = src->GetPitch(PLANAR_U);\n  const int src_pitch_a = src->GetPitch(PLANAR_A); // zero if no Alpha\n\n  const int dst_pitch = dst->GetPitch();\n\n  // Legacy direct YV24 -> packed 8 bit RGB24/RGB32\n  // quality=true float-inside or bit-depth changing transformation is handled through planar RGB intermediate.\n\n  if (pixel_step == 3 || pixel_step == 4) {\n#ifdef INTEL_INTRINSICS\n    if (env->GetCPUFlags() & CPUF_AVX2) {\n      if (pixel_step == 4) {\n        // RGB32\n        if (src_pitch_a) // move alpha channel from YUVA\n          convert_yv24_to_rgb_avx2<4, true>(dstp, srcY, srcU, srcV, srcA, dst_pitch, src_pitch_y, src_pitch_uv, src_pitch_a, vi.width, vi.height, matrix);\n        else\n          convert_yv24_to_rgb_avx2<4, false>(dstp, srcY, srcU, srcV, srcA, dst_pitch, src_pitch_y, src_pitch_uv, src_pitch_a, vi.width, vi.height, matrix);\n      }\n      else {\n        // RGB24\n        convert_yv24_to_rgb_avx2<3, false>(dstp, srcY, srcU, srcV, srcA, dst_pitch, src_pitch_y, src_pitch_uv, src_pitch_a, vi.width, vi.height, matrix);\n      }\n      return dst;\n    }\n    else if (env->GetCPUFlags() & CPUF_SSE2) {\n      if (pixel_step == 4) {\n        if (src_pitch_a) // move alpha channel from YUVA\n          convert_yv24_to_rgb_sse2<4, true>(dstp, srcY, srcU, srcV, srcA, dst_pitch, src_pitch_y, src_pitch_uv, src_pitch_a, vi.width, vi.height, matrix);\n        else\n          convert_yv24_to_rgb_sse2<4, false>(dstp, srcY, srcU, srcV, srcA, dst_pitch, src_pitch_y, src_pitch_uv, src_pitch_a, vi.width, vi.height, matrix);\n      }\n      else {\n        if (env->GetCPUFlags() & CPUF_SSSE3) {\n          convert_yv24_to_rgb_ssse3<3, false>(dstp, srcY, srcU, srcV, srcA, dst_pitch, src_pitch_y, src_pitch_uv, src_pitch_a, vi.width, vi.height, matrix);\n        }\n        else {\n          convert_yv24_to_rgb_sse2<3, false>(dstp, srcY, srcU, srcV, srcA, dst_pitch, src_pitch_y, src_pitch_uv, src_pitch_a, vi.width, vi.height, matrix);\n        }\n      }\n      return dst;\n    }\n\n#ifdef X86_32\n    // packed RGB24 and RGB32\n    if ((src_pitch_a == 0) && (env->GetCPUFlags() & CPUF_MMX)) {\n      if (pixel_step == 4) {\n        convert_yv24_to_rgb_mmx<4>(dstp, srcY, srcU, srcV, dst_pitch, src_pitch_y, src_pitch_uv, vi.width, vi.height, matrix);\n      }\n      else {\n        convert_yv24_to_rgb_mmx<3>(dstp, srcY, srcU, srcV, dst_pitch, src_pitch_y, src_pitch_uv, vi.width, vi.height, matrix);\n      }\n      return dst;\n    }\n#endif\n#endif\n\n    // Unoptimized C-code.\n    // rgb24 or rgb32, packed RGB\n    if (pixel_step == 3 || pixel_step == 4) {\n      if (pixel_step == 4) {\n        if (src_pitch_a) // move alpha channel from YUVA\n          convert_yv24_to_rgb_c<4, true>(dstp, srcY, srcU, srcV, srcA, dst_pitch, src_pitch_y, src_pitch_uv, src_pitch_a, vi.width, vi.height, matrix);\n        else\n          convert_yv24_to_rgb_c<4, false>(dstp, srcY, srcU, srcV, srcA, dst_pitch, src_pitch_y, src_pitch_uv, src_pitch_a, vi.width, vi.height, matrix);\n      }\n      else { // 3 RGB24\n        convert_yv24_to_rgb_c<3, false>(dstp, srcY, srcU, srcV, srcA, dst_pitch, src_pitch_y, src_pitch_uv, src_pitch_a, vi.width, vi.height, matrix);\n      }\n      return dst;\n    }\n  } // YV24->RGB24/RGB32\n\n  // rgb48 or rgb64, packed RGB\n  if (pixel_step == 6 || pixel_step == 8) {\n    // cannot happen, handled earlier, RGB48/64 are post converted from RGB(A)P16\n    env->ThrowError(\"ConvertFrom 444: RGB48/64 conversion should have been handled earlier through planar RGB intermediate\");\n  }\n\n  if (pixel_step < 0) {\n    // -1: RGBP  -2:RGBAP\n    // Common task: copy or fill alpha channel\n\n    // YUV444 -> PlanarRGB\n    // YUVA444 -> PlanarRGBA\n    bool targetHasAlpha = pixel_step == -2;\n\n    BYTE *dstpG = dst->GetWritePtr(PLANAR_G);\n    BYTE *dstpB = dst->GetWritePtr(PLANAR_B);\n    BYTE *dstpR = dst->GetWritePtr(PLANAR_R);\n\n    // copy or fill alpha\n    BYTE *dstpA;\n    if (targetHasAlpha) {\n      dstpA = dst->GetWritePtr(PLANAR_A);\n      int heightA = dst->GetHeight(PLANAR_A);\n      int rowsizeA = dst->GetRowSize(PLANAR_A);\n      int dst_pitchA = dst->GetPitch(PLANAR_A);\n        // simple copy\n      if (src->GetRowSize(PLANAR_A)) {\n\n        if (source_bit_depth == target_bit_depth) {\n          // vi.IsYUVA() no-no! vi is already the target video type\n          env->BitBlt(dstpA, dst_pitchA, src->GetReadPtr(PLANAR_A), src->GetPitch(PLANAR_A), src->GetRowSize(PLANAR_A_ALIGNED), src->GetHeight(PLANAR_A));\n        }\n        else {\n          // RGBPA target + different bit-depth\n          // Alpha bit depth conversion needed, normal planes are done in-process.\n          // we need only conv_function_a, proper dispatching from ConvertBits\n          conv_function_a(src->GetReadPtr(PLANAR_A), dstpA, src->GetRowSize(PLANAR_A), heightA, src->GetPitch(PLANAR_A), dst_pitchA, source_bit_depth, target_bit_depth, -1);\n        }\n      }\n      else {\n        // fill default transparency\n        switch (target_bit_depth)\n        {\n        case 1:\n          fill_plane<BYTE>(dstpA, heightA, rowsizeA, dst_pitchA, 255);\n          break;\n        case 2:\n          fill_plane<uint16_t>(dstpA, heightA, rowsizeA, dst_pitchA, (1 << target_bit_depth) - 1);\n          break;\n        case 4:\n          fill_plane<float>(dstpA, heightA, rowsizeA, dst_pitchA, 1.0f);\n          break;\n        }\n      }\n    }\n\n    int dst_pitchG = dst->GetPitch(PLANAR_G);\n    int dst_pitchB = dst->GetPitch(PLANAR_B);\n    int dst_pitchR = dst->GetPitch(PLANAR_R);\n\n    // always start from source bit depth\n    int bits_per_pixel = source_bit_depth;\n\n    const BYTE* srcp[3] = { src->GetReadPtr(PLANAR_Y), src->GetReadPtr(PLANAR_U), src->GetReadPtr(PLANAR_V) };\n    const int srcPitch[3] = { src->GetPitch(PLANAR_Y), src->GetPitch(PLANAR_U), src->GetPitch(PLANAR_V) };\n\n    BYTE* dstp[3] = { dstpG, dstpB, dstpR };\n    int dstPitch[3] = { dst_pitchG, dst_pitchB, dst_pitchR };\n\n    // alpha is already handled above\n\n    const bool force_float = quality;\n\n#ifdef INTEL_INTRINSICS\n\n    if (env->GetCPUFlags() & CPUF_AVX2)\n    {\n      if (bits_per_pixel == 8)\n        convert_yuv_to_planarrgb_avx2<ConversionDirection::YUV_TO_RGB, uint8_t, true>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n      else if (bits_per_pixel < 16)\n        convert_yuv_to_planarrgb_avx2<ConversionDirection::YUV_TO_RGB, uint16_t, true>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n      else if (bits_per_pixel == 16)\n        convert_yuv_to_planarrgb_avx2<ConversionDirection::YUV_TO_RGB, uint16_t, false>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n      else if (bits_per_pixel == 32)\n        convert_yuv_to_planarrgb_avx2<ConversionDirection::YUV_TO_RGB, float, false>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n      return dst;\n    }\n\n    if (env->GetCPUFlags() & CPUF_SSE2)\n    {\n      if (bits_per_pixel == 8)\n        convert_yuv_to_planarrgb_sse2<ConversionDirection::YUV_TO_RGB, uint8_t, true>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n      else if (bits_per_pixel < 16)\n        convert_yuv_to_planarrgb_sse2<ConversionDirection::YUV_TO_RGB, uint16_t, true>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n      else if (bits_per_pixel == 16)\n        convert_yuv_to_planarrgb_sse2<ConversionDirection::YUV_TO_RGB, uint16_t, false>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n      else if (bits_per_pixel == 32)\n        convert_yuv_to_planarrgb_sse2<ConversionDirection::YUV_TO_RGB, float, false>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n      return dst;\n    }\n\n#endif\n\n    if (bits_per_pixel == 8)\n      convert_yuv_to_planarrgb_c<ConversionDirection::YUV_TO_RGB, uint8_t, true>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n    else if (bits_per_pixel < 16)\n      convert_yuv_to_planarrgb_c<ConversionDirection::YUV_TO_RGB, uint16_t, true>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n    else if (bits_per_pixel == 16)\n      convert_yuv_to_planarrgb_c<ConversionDirection::YUV_TO_RGB, uint16_t, false>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n    else if (bits_per_pixel == 32)\n      convert_yuv_to_planarrgb_c<ConversionDirection::YUV_TO_RGB, float, false>(dstp, dstPitch, srcp, srcPitch, vi.width, vi.height, matrix, bits_per_pixel, target_bit_depth, force_float);\n    return dst;\n  }\n  return dst;\n}\n\n/************************************\n * YUY2 to YV16\n ************************************/\n\nConvertYUY2ToYV16_or_Y::ConvertYUY2ToYV16_or_Y(PClip src, bool _to_y, IScriptEnvironment* env) : GenericVideoFilter(src), to_y(_to_y) {\n\n  if (!vi.IsYUY2())\n    env->ThrowError(\"ConvertYUY2ToYV16/Y: Only YUY2 is allowed as input\");\n\n  vi.pixel_type = to_y ? VideoInfo::CS_Y8 : VideoInfo::CS_YV16;\n\n}\n\nstatic void convert_yuy2_to_y8_c(const BYTE* srcp, BYTE* dstp, size_t src_pitch, size_t dst_pitch, size_t width, size_t height)\n{\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < width; x++) {\n      dstp[x] = srcp[x * 2];\n    }\n    srcp += src_pitch;\n    dstp += dst_pitch;\n  }\n}\n\n\nstatic void convert_yuy2_to_yv16_c(const BYTE *srcp, BYTE *dstp_y, BYTE *dstp_u, BYTE *dstp_v, size_t src_pitch, size_t dst_pitch_y, size_t dst_pitch_uv, size_t width, size_t height)\n{\n  width /= 2;\n\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < width; ++x) {\n      dstp_y[x * 2]     = srcp[x * 4 + 0];\n      dstp_y[x * 2 + 1] = srcp[x * 4 + 2];\n      dstp_u[x]         = srcp[x * 4 + 1];\n      dstp_v[x]         = srcp[x * 4 + 3];\n    }\n    srcp += src_pitch;\n    dstp_y += dst_pitch_y;\n    dstp_u += dst_pitch_uv;\n    dstp_v += dst_pitch_uv;\n  }\n}\n\n\nPVideoFrame __stdcall ConvertYUY2ToYV16_or_Y::GetFrame(int n, IScriptEnvironment* env) {\n  PVideoFrame src = child->GetFrame(n, env);\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n\n  const BYTE* srcP = src->GetReadPtr();\n  BYTE* dstY = dst->GetWritePtr(PLANAR_Y);\n\n  if (to_y) {\n    update_ChromaLocation(env->getFramePropsRW(dst), -1, env); // Y8 target: delete _ChromaLocation\n    // YUY2 to Y8, luma only\n#ifdef INTEL_INTRINSICS\n    if (env->GetCPUFlags() & CPUF_SSE2) {\n      convert_yuy2_to_y8_sse2(srcP, dstY, src->GetPitch(), dst->GetPitch(PLANAR_Y), vi.width, vi.height);\n    }\n    else\n#endif\n    {\n      convert_yuy2_to_y8_c(srcP, dstY, src->GetPitch(), dst->GetPitch(PLANAR_Y), vi.width, vi.height);\n    }\n    return dst;\n  }\n  else {\n    BYTE* dstU = dst->GetWritePtr(PLANAR_U);\n    BYTE* dstV = dst->GetWritePtr(PLANAR_V);\n    // YUY2 to YV16, separate luma and chroma\n#ifdef INTEL_INTRINSICS\n    if (env->GetCPUFlags() & CPUF_SSE2) {\n      convert_yuy2_to_yv16_sse2(srcP, dstY, dstU, dstV, src->GetPitch(), dst->GetPitch(PLANAR_Y), dst->GetPitch(PLANAR_U), vi.width, vi.height);\n    }\n    else\n#ifdef X86_32\n      if (env->GetCPUFlags() & CPUF_MMX) {\n        convert_yuy2_to_yv16_mmx(srcP, dstY, dstU, dstV, src->GetPitch(), dst->GetPitch(PLANAR_Y), dst->GetPitch(PLANAR_U), vi.width, vi.height);\n      }\n      else\n#endif\n#endif\n      {\n        convert_yuy2_to_yv16_c(srcP, dstY, dstU, dstV, src->GetPitch(), dst->GetPitch(PLANAR_Y), dst->GetPitch(PLANAR_U), vi.width, vi.height);\n      }\n  }\n\n  return dst;\n}\n\n\nAVSValue __cdecl ConvertYUY2ToYV16_or_Y::Create(AVSValue args, void*, IScriptEnvironment* env) {\n  PClip clip = args[0].AsClip();\n  if (clip->GetVideoInfo().IsYV16())\n    return clip;\n  return new ConvertYUY2ToYV16_or_Y(clip, false /*to_y*/, env);\n}\n\n/************************************\n * YV16 to YUY2\n ************************************/\n\nConvertYV16ToYUY2::ConvertYV16ToYUY2(PClip src, IScriptEnvironment* env) : GenericVideoFilter(src) {\n\n  if (!vi.IsYV16())\n    env->ThrowError(\"ConvertYV16ToYUY2: Only YV16 is allowed as input\");\n\n  vi.pixel_type = VideoInfo::CS_YUY2;\n}\n\nstatic void convert_yv16_to_yuy2_c(const BYTE *srcp_y, const BYTE *srcp_u, const BYTE *srcp_v, BYTE *dstp, size_t src_pitch_y, size_t src_pitch_uv, size_t dst_pitch, size_t width, size_t height) {\n  for (size_t y=0; y < height; y++) {\n    for (size_t x=0; x < width / 2; x++) {\n      dstp[x*4+0] = srcp_y[x*2];\n      dstp[x*4+1] = srcp_u[x];\n      dstp[x*4+2] = srcp_y[x*2+1];\n      dstp[x*4+3] = srcp_v[x];\n    }\n    srcp_y += src_pitch_y;\n    srcp_u += src_pitch_uv;\n    srcp_v += src_pitch_uv;\n    dstp += dst_pitch;\n  }\n}\n\nPVideoFrame __stdcall ConvertYV16ToYUY2::GetFrame(int n, IScriptEnvironment* env) {\n  PVideoFrame src = child->GetFrame(n, env);\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n\n  const BYTE* srcY = src->GetReadPtr(PLANAR_Y);\n  const BYTE* srcU = src->GetReadPtr(PLANAR_U);\n  const BYTE* srcV = src->GetReadPtr(PLANAR_V);\n\n  BYTE* dstp = dst->GetWritePtr();\n\n#ifdef INTEL_INTRINSICS\n  if (env->GetCPUFlags() & CPUF_SSE2) {\n    //U and V don't have to be aligned since we user movq to read from those\n    convert_yv16_to_yuy2_sse2(srcY, srcU, srcV, dstp, src->GetPitch(PLANAR_Y), src->GetPitch(PLANAR_U), dst->GetPitch(), vi.width, vi.height);\n  } else\n#ifdef X86_32\n  if (env->GetCPUFlags() & CPUF_MMX) {\n    convert_yv16_to_yuy2_mmx(srcY, srcU, srcV, dstp, src->GetPitch(PLANAR_Y), src->GetPitch(PLANAR_U), dst->GetPitch(), vi.width, vi.height);\n  } else\n#endif\n#endif\n  {\n    convert_yv16_to_yuy2_c(srcY, srcU, srcV, dstp, src->GetPitch(PLANAR_Y), src->GetPitch(PLANAR_U), dst->GetPitch(), vi.width, vi.height);\n  }\n\n  return dst;\n}\n\n\nAVSValue __cdecl ConvertYV16ToYUY2::Create(AVSValue args, void*, IScriptEnvironment* env) {\n  PClip clip = args[0].AsClip();\n  if (clip->GetVideoInfo().IsYUY2())\n    return clip;\n  return new ConvertYV16ToYUY2(clip, env);\n}\n\n/**********************************************\n * Converter between arbitrary planar formats\n *\n * This uses plane copy for luma, and a custom\n * resizer for chroma\n *\n * (c) Klaus Post, 2005\n * (c) Ian Brabham, 2011\n **********************************************/\n\nConvertToPlanarGeneric::ConvertToPlanarGeneric(\n  PClip src, int dst_space, bool interlaced,\n  int _ChromaLocation_In, \n  const AVSValue& chromaResampler, const AVSValue& param1, const AVSValue& param2, const AVSValue& param3,\n  int _ChromaLocation_Out,\n  IScriptEnvironment* env) : \n  GenericVideoFilter(src), ChromaLocation_In(_ChromaLocation_In), ChromaLocation_Out(_ChromaLocation_Out)\n{\n  Yinput = vi.NumComponents() == 1;\n  pixelsize = vi.ComponentSize();\n\n  if (Yinput) {\n    vi.pixel_type = dst_space;\n    if (vi.ComponentSize() != pixelsize)\n      env->ThrowError(\"Convert: Conversion from %d to %d-byte format not supported.\", pixelsize, vi.ComponentSize());\n    // no more preparation here, GetFrame simply returns Y\n    return;\n  }\n\n  // Y only output from any YUV: no chroma involved, GetFrame will snatch Y plane\n  if (dst_space == VideoInfo::CS_Y8 || dst_space == VideoInfo::CS_Y10 ||\n    dst_space == VideoInfo::CS_Y12 || dst_space == VideoInfo::CS_Y14 || dst_space == VideoInfo::CS_Y16 ||\n    dst_space == VideoInfo::CS_Y32)\n  {\n    vi.pixel_type = dst_space;\n    return;\n  }\n\n  auto Is420 = [](int pix_type) {\n    return pix_type == VideoInfo::CS_YV12 || pix_type == VideoInfo::CS_I420 ||\n      pix_type == VideoInfo::CS_YUV420P10 || pix_type == VideoInfo::CS_YUV420P12 ||\n      pix_type == VideoInfo::CS_YUV420P14 || pix_type == VideoInfo::CS_YUV420P16 ||\n      pix_type == VideoInfo::CS_YUV420PS ||\n        pix_type == VideoInfo::CS_YUVA420 ||\n      pix_type == VideoInfo::CS_YUVA420P10 || pix_type == VideoInfo::CS_YUVA420P12 ||\n      pix_type == VideoInfo::CS_YUVA420P14 || pix_type == VideoInfo::CS_YUVA420P16 ||\n      pix_type == VideoInfo::CS_YUVA420PS;\n  };\n\n  if (!Is420(vi.pixel_type) && !Is420(dst_space))\n    interlaced = false;  // Ignore, if YV12 is not involved.\n  //if (interlaced) env->ThrowError(\"Convert: Interlaced only available with 4:2:0 color spaces.\");\n\n  // Describe input pixel positioning\n  float xdInU = 0.0f, txdInU = 0.0f, bxdInU = 0.0f;\n  float ydInU = 0.0f, tydInU = 0.0f, bydInU = 0.0f;\n  float xdInV = 0.0f, txdInV = 0.0f, bxdInV = 0.0f;\n  float ydInV = 0.0f, tydInV = 0.0f, bydInV = 0.0f;\n\n  /*\n    \"mpeg1\", \"center\"\n      - 1-1 averaging kernel (4:2:0, 4:2:2 (horizontal only))\n    \"mpeg2\", \"left\" (4:2:0, 4:2:2)\n      - top-field samples are sited 1/4 sample below the luma samples (4:2:0)\n      - bottom-field samples are sited 1/4 sample above the luma samples (4:2:0)\n      - horizontal 1-2-1 kernel \n    \"dv\": (4:2:0)\n      Chroma samples are sited on top of luma samples, but CB and CR samples are sited on alternate lines.\n      - top: V\n      - bottom: U\n    \"top_left\" (4:2:0)\n      - horizontal 1-2-1 vertical 1-2-1\n  */\n\n  if (Is420(vi.pixel_type)) {\n    switch (ChromaLocation_In) {\n      case ChromaLocation_e::AVS_CHROMA_DV: // spec. avisynth\n        xdInU = 0.0f; ydInU = 1.0f; txdInU = 0.0f; tydInU = 1.0f; bxdInU = 0.0f; bydInU = 1.0f; // Cb\n        xdInV = 0.0f; ydInV = 0.0f; txdInV = 0.0f; tydInV = 0.0f; bxdInV = 0.0f; bydInV = 0.0f; // Cr\n        break;\n      case ChromaLocation_e::AVS_CHROMA_TOP:\n        xdInU = 0.5f, ydInU = 0.0f; txdInU = 0.5f; tydInU = 0.0f; bxdInU = 0.5f; bydInU = 0.5f;\n        xdInV = 0.5f, ydInV = 0.0f; txdInV = 0.5f; tydInV = 0.0f; bxdInV = 0.5f; bydInV = 0.5f;\n        break;\n      case ChromaLocation_e::AVS_CHROMA_CENTER: // mpeg1, center\n        xdInU = 0.5f, ydInU = 0.5f; txdInU = 0.5f; tydInU = 0.25f; bxdInU = 0.5f; bydInU = 0.75f;\n        xdInV = 0.5f, ydInV = 0.5f; txdInV = 0.5f; tydInV = 0.25f; bxdInV = 0.5f; bydInV = 0.75f;\n        break;\n      case ChromaLocation_e::AVS_CHROMA_BOTTOM:\n        xdInU = 0.5f, ydInU = 1.0f; txdInU = 0.5f; tydInU = 0.5f; bxdInU = 0.5f; bydInU = 1.0f;\n        xdInV = 0.5f, ydInV = 1.0f; txdInV = 0.5f; tydInV = 0.5f; bxdInV = 0.5f; bydInV = 1.0f;\n        break;\n      case ChromaLocation_e::AVS_CHROMA_TOP_LEFT:\n        xdInU = 0.0f; ydInU = 0.0f; txdInU = 0.0f; tydInU = 0.0f; bxdInU = 0.0f; bydInU = 0.5f;\n        xdInV = 0.0f; ydInV = 0.0f; txdInV = 0.0f; tydInV = 0.0f; bxdInV = 0.0f; bydInV = 0.5f;\n        break;\n      case ChromaLocation_e::AVS_CHROMA_LEFT: // left, mpeg2\n        xdInU = 0.0f; ydInU = 0.5f; txdInU = 0.0f; tydInU = 0.25f; bxdInU = 0.0f; bydInU = 0.75f;\n        xdInV = 0.0f; ydInV = 0.5f; txdInV = 0.0f; tydInV = 0.25f; bxdInV = 0.0f; bydInV = 0.75f;\n        break;\n      case ChromaLocation_e::AVS_CHROMA_BOTTOM_LEFT:\n        xdInU = 0.0f; ydInU = 1.0f; txdInU = 0.0f; tydInU = 0.5f; bxdInU = 0.0f; bydInU = 1.0f;\n        xdInV = 0.0f; ydInV = 1.0f; txdInV = 0.0f; tydInV = 0.5f; bxdInV = 0.0f; bydInV = 1.0f;\n        break;\n      default:\n        env->ThrowError(\"Convert: not supported ChromaPlacement for 4:2:0 input.\");\n    }\n  }\n  else if (vi.Is422()) {\n    switch (ChromaLocation_In) {\n    case ChromaLocation_e::AVS_CHROMA_CENTER: // center\n      xdInU = 0.5f, ydInU = 0.0f; txdInU = 0.5f; tydInU = 0.0f; bxdInU = 0.5f; bydInU = 0.0f;\n      xdInV = 0.5f, ydInV = 0.0f; txdInV = 0.5f; tydInV = 0.0f; bxdInV = 0.5f; bydInV = 0.0f;\n      break;\n    case ChromaLocation_e::AVS_CHROMA_TOP_LEFT: // treated as left\n    case ChromaLocation_e::AVS_CHROMA_LEFT: // left, mpeg2\n    case ChromaLocation_e::AVS_CHROMA_BOTTOM_LEFT: // treated as left\n      xdInU = 0.0f; ydInU = 0.0f; txdInU = 0.0f; tydInU = 0.0f; bxdInU = 0.0f; bydInU = 0.0f;\n      xdInV = 0.0f; ydInV = 0.0f; txdInV = 0.0f; tydInV = 0.0f; bxdInV = 0.0f; bydInV = 0.0f;\n      break;\n    default:\n      env->ThrowError(\"Convert: not supported ChromaPlacement for 4:2:2 input.\");\n    }\n  }\n  else if (vi.IsYV411()) {\n    if (ChromaLocation_In >= 0\n      && ChromaLocation_In != ChromaLocation_e::AVS_CHROMA_TOP_LEFT\n      && ChromaLocation_In != ChromaLocation_e::AVS_CHROMA_LEFT\n      && ChromaLocation_In != ChromaLocation_e::AVS_CHROMA_BOTTOM_LEFT\n      )\n    {\n      // if given, only the 'left'-ish versions are accepted, this is how it is treated\n      env->ThrowError(\"Convert: not supported ChromaPlacement for 4:1:1 input. Only 'left'-style is allowed if given.\");\n    }\n  }\n  else if (ChromaLocation_In >= 0)\n    env->ThrowError(\"Convert: Input ChromaPlacement is invalid for this format.\");\n\n  const int xsIn = 1 << vi.GetPlaneWidthSubsampling(PLANAR_U);\n  const int ysIn = 1 << vi.GetPlaneHeightSubsampling(PLANAR_U);\n\n  // change vi to the output format\n  vi.pixel_type = dst_space;\n\n  if (vi.ComponentSize() != pixelsize)\n    env->ThrowError(\"Convert: Conversion from %d to %d-byte format not supported.\", pixelsize, vi.ComponentSize());\n\n  // Describe output pixel positioning\n  float xdOutU = 0.0f, txdOutU = 0.0f, bxdOutU = 0.0f;\n  float ydOutU = 0.0f, tydOutU = 0.0f, bydOutU = 0.0f;\n  float xdOutV = 0.0f, txdOutV = 0.0f, bxdOutV = 0.0f;\n  float ydOutV = 0.0f, tydOutV = 0.0f, bydOutV = 0.0f;\n\n  if (Is420(vi.pixel_type)) {\n    switch (ChromaLocation_Out) {\n    case ChromaLocation_e::AVS_CHROMA_DV:\n      xdOutU = 0.0f; ydOutU = 1.0f; txdOutU = 0.0f; tydOutU = 1.0f; bxdOutU = 0.0f; bydOutU = 1.0f; // Cb\n      xdOutV = 0.0f; ydOutV = 0.0f; txdOutV = 0.0f; tydOutV = 0.0f; bxdOutV = 0.0f; bydOutV = 0.0f; // Cr\n      break;\n    case ChromaLocation_e::AVS_CHROMA_TOP:\n      xdOutU = 0.5f, ydOutU = 0.0f; txdOutU = 0.5f; tydOutU = 0.0f; bxdOutU = 0.5f; bydOutU = 0.5f;\n      xdOutV = 0.5f, ydOutV = 0.0f; txdOutV = 0.5f; tydOutV = 0.0f; bxdOutV = 0.5f; bydOutV = 0.5f;\n      break;\n    case ChromaLocation_e::AVS_CHROMA_CENTER: // mpeg1, center\n      xdOutU = 0.5f, ydOutU = 0.5f; txdOutU = 0.5f; tydOutU = 0.25f; bxdOutU = 0.5f; bydOutU = 0.75f;\n      xdOutV = 0.5f, ydOutV = 0.5f; txdOutV = 0.5f; tydOutV = 0.25f; bxdOutV = 0.5f; bydOutV = 0.75f;\n      break;\n    case ChromaLocation_e::AVS_CHROMA_BOTTOM:\n      xdOutU = 0.5f, ydOutU = 1.0f; txdOutU = 0.5f; tydOutU = 0.5f; bxdOutU = 0.5f; bydOutU = 1.0f;\n      xdOutV = 0.5f, ydOutV = 1.0f; txdOutV = 0.5f; tydOutV = 0.5f; bxdOutV = 0.5f; bydOutV = 1.0f;\n      break;\n    case ChromaLocation_e::AVS_CHROMA_TOP_LEFT:\n      xdOutU = 0.0f; ydOutU = 0.0f; txdOutU = 0.0f; tydOutU = 0.0f; bxdOutU = 0.0f; bydOutU = 0.5f;\n      xdOutV = 0.0f; ydOutV = 0.0f; txdOutV = 0.0f; tydOutV = 0.0f; bxdOutV = 0.0f; bydOutV = 0.5f;\n      break;\n    case ChromaLocation_e::AVS_CHROMA_LEFT: // left, mpeg2\n      xdOutU = 0.0f; ydOutU = 0.5f; txdOutU = 0.0f; tydOutU = 0.25f; bxdOutU = 0.0f; bydOutU = 0.75f;\n      xdOutV = 0.0f; ydOutV = 0.5f; txdOutV = 0.0f; tydOutV = 0.25f; bxdOutV = 0.0f; bydOutV = 0.75f;\n      break;\n    case ChromaLocation_e::AVS_CHROMA_BOTTOM_LEFT:\n      xdOutU = 0.0f; ydOutU = 1.0f; txdOutU = 0.0f; tydOutU = 0.5f; bxdOutU = 0.0f; bydOutU = 1.0f;\n      xdOutV = 0.0f; ydOutV = 1.0f; txdOutV = 0.0f; tydOutV = 0.5f; bxdOutV = 0.0f; bydOutV = 1.0f;\n      break;\n    default:\n      env->ThrowError(\"Convert: not supported ChromaPlacement for 4:2:0 output.\");\n    }\n  }\n  else if (vi.Is422()) {\n    switch (ChromaLocation_Out) {\n    case ChromaLocation_e::AVS_CHROMA_CENTER: // mpeg1, center\n      xdOutU = 0.5f, ydOutU = 0.0f; txdOutU = 0.5f; tydOutU = 0.0f; bxdOutU = 0.5f; bydOutU = 0.0f;\n      xdOutV = 0.5f, ydOutV = 0.0f; txdOutV = 0.5f; tydOutV = 0.0f; bxdOutV = 0.5f; bydOutV = 0.0f;\n      break;\n    case ChromaLocation_e::AVS_CHROMA_TOP_LEFT: // treated as left\n    case ChromaLocation_e::AVS_CHROMA_LEFT: // left, mpeg2\n    case ChromaLocation_e::AVS_CHROMA_BOTTOM_LEFT: // treated as left\n      xdOutU = 0.0f; ydOutU = 0.0f; txdOutU = 0.0f; tydOutU = 0.0f; bxdOutU = 0.0f; bydOutU = 0.0f;\n      xdOutV = 0.0f; ydOutV = 0.0f; txdOutV = 0.0f; tydOutV = 0.0f; bxdOutV = 0.0f; bydOutV = 0.0f;\n      break;\n    default:\n      env->ThrowError(\"Convert: not supported ChromaPlacement for 4:2:2 output.\");\n    }\n  }\n  else if (ChromaLocation_Out >= 0)\n    env->ThrowError(\"Convert: Output ChromaPlacement only available with 4:2:0 or 4:2:2 output.\");\n\n  const int xsOut = 1 << vi.GetPlaneWidthSubsampling(PLANAR_U);\n  const int xmask = xsOut - 1;\n  if (vi.width & xmask)\n    env->ThrowError(\"Convert: Cannot convert if width isn't mod%d!\", xsOut);\n\n  const int ysOut = 1 << vi.GetPlaneHeightSubsampling(PLANAR_U);\n  const int ymask = ysOut - 1;\n  if (vi.height & ymask)\n    env->ThrowError(\"Convert: Cannot convert if height isn't mod%d!\", ysOut);\n\n  int uv_width  = vi.width  >> vi.GetPlaneWidthSubsampling(PLANAR_U);\n  int uv_height = vi.height >> vi.GetPlaneHeightSubsampling(PLANAR_U);\n\n  ResamplingFunction *filter = getResampler(chromaResampler.AsString(\"bicubic\"), param1, param2, param3, true, env);\n\n  bool P = !lstrcmpi(chromaResampler.AsString(\"\"), \"point\");\n\n  auto ChrOffset = [P](int sIn, float dIn, int sOut, float dOut) {\n    //     (1 - sOut/sIn)/2 + (dOut-dIn)/sIn; // Gavino Jan 2011\n    return P ? (dOut - dIn) / sIn : 0.5f + (dOut - dIn - 0.5f*sOut) / sIn;\n  };\n\n  const int force = 0;\n  const bool preserve_center = true;\n  const char *placement_name_notused = nullptr; // n/a\n  const int forced_chroma_placement = -1; // no force\n  // chroma planes are extracted, behave like Y when resized, no chroma planes involved\n\n  if (interlaced) {\n    uv_height /=  2;\n\n    AVSValue tUsubSampling[4] = { ChrOffset(xsIn, txdInU, xsOut, txdOutU), ChrOffset(ysIn, tydInU, ysOut, tydOutU), AVSValue(), AVSValue() };\n    AVSValue bUsubSampling[4] = { ChrOffset(xsIn, bxdInU, xsOut, bxdOutU), ChrOffset(ysIn, bydInU, ysOut, bydOutU), AVSValue(), AVSValue() };\n    AVSValue tVsubSampling[4] = { ChrOffset(xsIn, txdInV, xsOut, txdOutV), ChrOffset(ysIn, tydInV, ysOut, tydOutV), AVSValue(), AVSValue() };\n    AVSValue bVsubSampling[4] = { ChrOffset(xsIn, bxdInV, xsOut, bxdOutV), ChrOffset(ysIn, bydInV, ysOut, bydOutV), AVSValue(), AVSValue() };\n\n    Usource = new SeparateFields(new AssumeParity(new SwapUVToY(child, SwapUVToY::UToY8, env), true), env); // also works for Y16/Y32\n    Vsource = new SeparateFields(new AssumeParity(new SwapUVToY(child, SwapUVToY::VToY8, env), true), env); // also works for Y16/Y32\n\n    std::vector<PClip> tbUsource(2); // Interleave() will take ownership of these\n    std::vector<PClip> tbVsource(2);\n\n    tbUsource[0] = FilteredResize::CreateResize(new SelectEvery(Usource, 2, 0, env), uv_width, uv_height, tUsubSampling, force, filter, preserve_center, placement_name_notused, forced_chroma_placement, env);\n    tbUsource[1] = FilteredResize::CreateResize(new SelectEvery(Usource, 2, 1, env), uv_width, uv_height, bUsubSampling, force, filter, preserve_center, placement_name_notused, forced_chroma_placement, env);\n    tbVsource[0] = FilteredResize::CreateResize(new SelectEvery(Vsource, 2, 0, env), uv_width, uv_height, tVsubSampling, force, filter, preserve_center, placement_name_notused, forced_chroma_placement, env);\n    tbVsource[1] = FilteredResize::CreateResize(new SelectEvery(Vsource, 2, 1, env), uv_width, uv_height, bVsubSampling, force, filter, preserve_center, placement_name_notused, forced_chroma_placement, env);\n\n    Usource = new SelectEvery(new DoubleWeaveFields(new Interleave(std::move(tbUsource), env)), 2, 0, env);\n    Vsource = new SelectEvery(new DoubleWeaveFields(new Interleave(std::move(tbVsource), env)), 2, 0, env);\n  }\n  else {\n    AVSValue UsubSampling[4] = { ChrOffset(xsIn, xdInU, xsOut, xdOutU), ChrOffset(ysIn, ydInU, ysOut, ydOutU), AVSValue(), AVSValue() };\n    AVSValue VsubSampling[4] = { ChrOffset(xsIn, xdInV, xsOut, xdOutV), ChrOffset(ysIn, ydInV, ysOut, ydOutV), AVSValue(), AVSValue() };\n\n    Usource = FilteredResize::CreateResize(new SwapUVToY(child, SwapUVToY::UToY8, env), uv_width, uv_height, UsubSampling, force, filter, preserve_center, placement_name_notused, forced_chroma_placement, env);\n    Vsource = FilteredResize::CreateResize(new SwapUVToY(child, SwapUVToY::VToY8, env), uv_width, uv_height, VsubSampling, force, filter, preserve_center, placement_name_notused, forced_chroma_placement, env);\n  }\n  delete filter;\n}\n\nPVideoFrame __stdcall ConvertToPlanarGeneric::GetFrame(int n, IScriptEnvironment* env) {\n  PVideoFrame src = child->GetFrame(n, env);\n\n\n  if (vi.IsY()) {\n    // Abuse Subframe to snatch the Y plane\n    PVideoFrame dst = env->Subframe(src, 0, src->GetPitch(PLANAR_Y), src->GetRowSize(PLANAR_Y), src->GetHeight(PLANAR_Y));\n    auto props = env->getFramePropsRW(dst);\n    // ChromaLocation_Out is <0 : erased\n    update_ChromaLocation(props, ChromaLocation_Out, env);\n    return dst;\n  }\n\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n  env->BitBlt(dst->GetWritePtr(PLANAR_Y), dst->GetPitch(PLANAR_Y), src->GetReadPtr(PLANAR_Y), src->GetPitch(PLANAR_Y),\n    src->GetRowSize(PLANAR_Y_ALIGNED), src->GetHeight(PLANAR_Y));\n\n  auto props = env->getFramePropsRW(dst);\n  update_ChromaLocation(props, ChromaLocation_Out, env);\n\n  // alpha. if pitch is zero -> no alpha channel\n  const int rowsizeA = dst->GetRowSize(PLANAR_A);\n  const int dst_pitchA = dst->GetPitch(PLANAR_A);\n  BYTE* dstp_a = (dst_pitchA == 0) ? nullptr : dst->GetWritePtr(PLANAR_A);\n  const int heightA = dst->GetHeight(PLANAR_A);\n\n  if (dst_pitchA != 0)\n  {\n    if (src->GetPitch(PLANAR_A) != 0)\n      env->BitBlt(dstp_a, dst_pitchA, src->GetReadPtr(PLANAR_A), src->GetPitch(PLANAR_A),\n        src->GetRowSize(PLANAR_A_ALIGNED), src->GetHeight(PLANAR_A));\n    else {\n      // e.g. ConvertToYUVA() case from Alpha-less formats\n      switch (vi.ComponentSize())\n      {\n      case 1:\n        fill_plane<BYTE>(dstp_a, heightA, rowsizeA, dst_pitchA, 255);\n        break;\n      case 2:\n        fill_plane<uint16_t>(dstp_a, heightA, rowsizeA, dst_pitchA, (1 << vi.BitsPerComponent()) - 1);\n        break;\n      case 4:\n        fill_plane<float>(dstp_a, heightA, rowsizeA, dst_pitchA, 1.0f);\n        break;\n      }\n    }\n  }\n\n  BYTE* dstp_u = dst->GetWritePtr(PLANAR_U);\n  BYTE* dstp_v = dst->GetWritePtr(PLANAR_V);\n  const int height = dst->GetHeight(PLANAR_U);\n  const int rowsizeUV = dst->GetRowSize(PLANAR_U);\n  const int dst_pitch = dst->GetPitch(PLANAR_U);\n\n  if (Yinput) {\n    switch (vi.ComponentSize())\n    {\n      case 1:\n        fill_chroma<BYTE>(dstp_u, dstp_v, height, rowsizeUV, dst_pitch, 0x80);\n        break;\n      case 2:\n        fill_chroma<uint16_t>(dstp_u, dstp_v, height, rowsizeUV, dst_pitch, 1 << (vi.BitsPerComponent() - 1));\n        break;\n      case 4:\n        const float half = 0.0f;\n        fill_chroma<float>(dstp_u, dstp_v, height, rowsizeUV, dst_pitch, half);\n        break;\n    }\n  } else {\n    src = Usource->GetFrame(n, env);\n    env->BitBlt(dstp_u, dst_pitch, src->GetReadPtr(PLANAR_Y), src->GetPitch(PLANAR_Y), src->GetRowSize(PLANAR_Y_ALIGNED), height);\n    src = Vsource->GetFrame(n, env);\n    env->BitBlt(dstp_v, dst_pitch, src->GetReadPtr(PLANAR_Y), src->GetPitch(PLANAR_Y), src->GetRowSize(PLANAR_Y_ALIGNED), height);\n  }\n\n  return dst;\n}\n/*                                           0      1         2             3                  4            5       6         7       8       9\n{ \"ConvertToYUV411\",  BUILTIN_FUNC_PREFIX, \"c[interlaced]b[matrix]s[ChromaInPlacement]s[chromaresample]s[param1]f[param2]f[param3]f[bits]i[quality]b\", ConvertToPlanarGeneric::CreateYV411, (void*)1 }, // alias for ConvertToYV411, 8 bit check later\n{ \"ConvertToYUV444\",  BUILTIN_FUNC_PREFIX, \"c[interlaced]b[matrix]s[ChromaInPlacement]s[chromaresample]s[param1]f[param2]f[param3]f[bits]i[quality]b\", ConvertToPlanarGeneric::CreateYUV444, (void*)1 },\n{ \"ConvertToYUVA444\", BUILTIN_FUNC_PREFIX, \"c[interlaced]b[matrix]s[ChromaInPlacement]s[chromaresample]s[param1]f[param2]f[param3]f[bits]i[quality]b\", ConvertToPlanarGeneric::CreateYUV444, (void*)2 },\n                                             0      1         2             3                   4            5                  6         7          8     9     10\n{ \"ConvertToYUV420\",  BUILTIN_FUNC_PREFIX, \"c[interlaced]b[matrix]s[ChromaInPlacement]s[chromaresample]s[ChromaOutPlacement]s[param1]f[param2]f[param3]f[bits]i[quality]b\", ConvertToPlanarGeneric::CreateYUV420, (void*)1 },\n{ \"ConvertToYUV422\",  BUILTIN_FUNC_PREFIX, \"c[interlaced]b[matrix]s[ChromaInPlacement]s[chromaresample]s[ChromaOutPlacement]s[param1]f[param2]f[param3]f[bits]i[quality]b\", ConvertToPlanarGeneric::CreateYUV422, (void*)1 },\n{ \"ConvertToYUVA420\", BUILTIN_FUNC_PREFIX, \"c[interlaced]b[matrix]s[ChromaInPlacement]s[chromaresample]s[ChromaOutPlacement]s[param1]f[param2]f[param3]f[bits]i[quality]b\", ConvertToPlanarGeneric::CreateYUV420, (void*)2 },\n{ \"ConvertToYUVA422\", BUILTIN_FUNC_PREFIX, \"c[interlaced]b[matrix]s[ChromaInPlacement]s[chromaresample]s[ChromaOutPlacement]s[param1]f[param2]f[param3]f[bits]i[quality]b\", ConvertToPlanarGeneric::CreateYUV422, (void*)2 },\n                                            0   1        2       3 \n{ \"ConvertToY\",       BUILTIN_FUNC_PREFIX, \"c[matrix]s[bits]i[quality]b\", ConvertToPlanarGeneric::CreateConvertToY, (void*)1 }, // user_data == 1 -> any bit depth sources\n\n*/\nAVSValue ConvertToPlanarGeneric::Create(AVSValue& args, const char* filter, bool strip_alpha_legacy_8bit, bool to_yuva, IScriptEnvironment* env) {\n  bool converted = false;\n\n  PClip clip = args[0].AsClip();\n  VideoInfo vi = clip->GetVideoInfo();\n\n  const bool to_y = strcmp(filter, \"ConvertToY\") == 0;\n  const bool to_420 = strcmp(filter, \"ConvertToYUV420\") == 0;\n  const bool to_422 = strcmp(filter, \"ConvertToYUV422\") == 0;\n  const bool to_411 = strcmp(filter, \"ConvertToYV411\") == 0;\n  const bool to_444 = strcmp(filter, \"ConvertToYUV444\") == 0;\n\n  if (vi.IsYUY2()) {\n    // use to_y: no need YV16 extra planes when our target is Y only\n    clip = new ConvertYUY2ToYV16_or_Y(clip, to_y, env);\n    vi = clip->GetVideoInfo();\n  }\n\n  AVSValue bits_arg;\n  AVSValue quality_arg;\n  AVSValue matrix_arg;\n  if (to_y) {\n    matrix_arg = args[1];\n    bits_arg = args[2];\n    quality_arg = args[3];\n  }\n  else if (to_420 || to_422) {\n    matrix_arg = args[2];\n    bits_arg = args[9];\n    quality_arg = args[10];\n  }\n  else {\n    matrix_arg = args[2];\n    bits_arg = args[8];\n    quality_arg = args[9];\n  }\n\n  const int target_bits_per_pixel = bits_arg.AsInt(vi.BitsPerComponent());\n  const bool quality = quality_arg.AsBool(false); // float RGB YUV inside\n\n  int bits_per_pixel = vi.BitsPerComponent();\n\n  /*\n  if (target_bits_per_pixel != bits_per_pixel && !vi.IsRGB()) {\n    env->ThrowError(\"%s: on-thy-fly bit-depth conversion only supported from RGB formats.\", filter);\n  }\n  */\n  bool needConvertFinalBitdepth = false;\n\n  if (target_bits_per_pixel != vi.BitsPerComponent()) {\n    needConvertFinalBitdepth = true;\n  }\n\n  if (vi.IsRGB()) { // packed or planar source\n    const bool keep_packedrgb_alpha = to_yuva && (vi.IsRGB32() || vi.IsRGB64());\n    // 3.7.6: We convert ALL packed RGB formats to planar RGB!\n    // The only case where a RGB32->YV24 is a bit slower is: SSE2-only but no SSSE3 capable CPU.\n    // All other cases are quicker, when converting to planar first and then to YUV444, than doing packed RGB->YUV444 in one step.\n    // On AVX2 capable CPUs using the PlanarRGB-YUV engine, we are +80% quicker\n    // doing RGB32->PlanarRGB->YUV444 than doing RGB32->YUV444 in the old SSSE3 step.\n    if (!vi.IsPlanar()) {\n      // we convert to intermediate PlanarRGB, RGB48/64->YUV444 is slow C, planarRGB  is fast\n      // Default ConvertToPlanarRGB call\n      AVSValue new_args[10] = { clip, AVSValue(), AVSValue(), AVSValue(), AVSValue(), AVSValue(), AVSValue(), AVSValue(), AVSValue(), AVSValue() };\n      // clip, matrix,  interlaced, chromainplacement, chromaresample, param1, param2, param3, bits, quality\n      // convert to planar RGBA only if RGB64 and target is YUVA (need to keep alpha)\n      const intptr_t planar_rgb_type = keep_packedrgb_alpha ? -2 : -1;\n      clip = CreateConvertToRGB(AVSValue(new_args, 10), (void *)planar_rgb_type, env).AsClip();\n      vi = clip->GetVideoInfo();\n    }\n\n    if (target_bits_per_pixel != vi.BitsPerComponent()) {\n      needConvertFinalBitdepth = true;\n    }\n\n    bool bitdepthConverted = false;\n    if (needConvertFinalBitdepth) {\n      // Optional bit-depth conversion in PackedRGBtoPlanarRGB.\n      // int->float full/narrow range, int-int full/narrow supported\n      clip = new ConvertRGBToYUV444(clip, matrix_arg.AsString(0) /* matrix_name */, keep_packedrgb_alpha, target_bits_per_pixel, quality, /*ref*/bitdepthConverted, to_y, env);\n      vi = clip->GetVideoInfo();\n      if (bitdepthConverted) {\n        needConvertFinalBitdepth = false; // done in-process\n      }\n    } else {\n      // pass -1 as finalBitdepth, signing that no bit-depth conversion required\n      // output bitdepthConverted is n/a\n      clip = new ConvertRGBToYUV444(clip, matrix_arg.AsString(0) /* matrix_name */, keep_packedrgb_alpha, -1 /*no bit-depth conversion*/, quality, /*ref*/bitdepthConverted, to_y, env);\n      vi = clip->GetVideoInfo();\n    }\n\n    vi = clip->GetVideoInfo();\n    converted = true;\n  }\n  else if (!vi.IsPlanar())\n    env->ThrowError(\"%s: Can only convert from Planar YUV.\", filter);\n\n  if (needConvertFinalBitdepth) {\n    // plain Invoke and no \"new ConvertBits()\": this detects and keeps source and target ranges\n    // FIXME: use fulls, fulld YUV->YUY (Y->Y where only limited/full is changed)\n    AVSValue new_args[2] = { clip, target_bits_per_pixel };\n    clip = env->Invoke(\"ConvertBits\", AVSValue(new_args, 2)).AsClip();\n    vi = clip->GetVideoInfo();\n  }\n\n  bits_per_pixel = vi.BitsPerComponent(); // rgb conversion or standalone ConvertBits() would alter it.\n\n  int pixel_type = VideoInfo::CS_UNKNOWN;\n  AVSValue outplacement = AVSValue(); // only for ConvertToYUV420 and ConvertToYUV422\n\n  bool hasAlpha = vi.NumComponents() == 4 && !strip_alpha_legacy_8bit;\n  bool shouldStripAlpha = vi.NumComponents() == 4 && strip_alpha_legacy_8bit;\n  bool shouldAddAlpha = vi.NumComponents() != 4 && to_yuva;\n  bool targethasAlpha = hasAlpha || shouldAddAlpha;\n\n  int ChromaLocation_In = -1; // invalid. Chromalocation_e::AVS_CHROMALOCATION_UNUSED\n  int ChromaLocation_Out = -1; // left as invalid for 444, and Y\n\n  if (vi.IsYV411()) {\n    // ChromaInPlacement parameter exists, (default none/-1) + input frame properties; 'left'-ish _ChromaLocation is allowed, checked later\n    auto frame0 = clip->GetFrame(0, env);\n    const AVSMap* props = env->getFramePropsRO(frame0);\n    chromaloc_parse_merge_with_props(vi, args[3].AsString(nullptr), props, /* ref*/ChromaLocation_In, -1 /*default none chromaloc */, env);\n  }\n  else if (vi.Is420() || vi.Is422()) {\n    // ChromaInPlacement parameter is valid + input frame properties\n    auto frame0 = clip->GetFrame(0, env);\n    const AVSMap* props = env->getFramePropsRO(frame0);\n    chromaloc_parse_merge_with_props(vi, args[3].AsString(nullptr), props, /* ref*/ChromaLocation_In, ChromaLocation_e::AVS_CHROMA_LEFT /*default*/, env);\n  }\n\n  AVSValue param1;\n  AVSValue param2;\n  AVSValue param3;\n  if (to_420 || to_422) {\n    // ChromaOutPlacement parameter is valid\n    chromaloc_parse_merge_with_props(vi, args[5].AsString(nullptr), nullptr, /* ref*/ChromaLocation_Out, ChromaLocation_e::AVS_CHROMA_LEFT /*default*/, env);\n    param1 = args[6];\n    param2 = args[7];\n    param3 = args[8];\n  }\n  else if (to_444 || to_411) {\n    // No ChromaOutPlacement parameter, indexes skip back accordingly\n    param1 = args[5];\n    param2 = args[6];\n    param3 = args[7];\n  }\n\n  // FIXME: no-op or almost no-op shortcuts won't exist even at 420-420 conversion if YUV-YUV matrix conversion is added\n\n  if (to_y) {\n    if (vi.IsY()) {\n      // After RGB->Y conversion or input as Y\n      return clip;\n    }\n    // planar YUV original, GetFrame will return Y\n    switch (bits_per_pixel)\n    {\n    case 8: pixel_type =  VideoInfo::CS_Y8; break;\n    case 10: pixel_type = VideoInfo::CS_Y10; break;\n    case 12: pixel_type = VideoInfo::CS_Y12; break;\n    case 14: pixel_type = VideoInfo::CS_Y14; break;\n    case 16: pixel_type = VideoInfo::CS_Y16; break;\n    case 32: pixel_type = VideoInfo::CS_Y32; break;\n    }\n  }\n  else if (to_420) {\n    if (vi.Is420()) {\n      // possible shortcut\n      if (ChromaLocation_In == ChromaLocation_Out)\n      {\n        if (shouldStripAlpha)\n          return new RemoveAlphaPlane(clip, env);\n        if (shouldAddAlpha) {\n          // create with default alpha\n          clip = new AddAlphaPlane(clip, nullptr, 0.0f, false, env);\n          vi = clip->GetVideoInfo();\n        }\n        return clip;\n      }\n    }\n\n    outplacement = args[5];\n    switch (vi.BitsPerComponent())\n    {\n    case 8 : pixel_type = targethasAlpha ? VideoInfo::CS_YUVA420 : VideoInfo::CS_YV12; break;\n    case 10: pixel_type = targethasAlpha ? VideoInfo::CS_YUVA420P10 : VideoInfo::CS_YUV420P10; break;\n    case 12: pixel_type = targethasAlpha ? VideoInfo::CS_YUVA420P12 : VideoInfo::CS_YUV420P12; break;\n    case 14: pixel_type = targethasAlpha ? VideoInfo::CS_YUVA420P14 : VideoInfo::CS_YUV420P14; break;\n    case 16: pixel_type = targethasAlpha ? VideoInfo::CS_YUVA420P16 : VideoInfo::CS_YUV420P16; break;\n    case 32: pixel_type = targethasAlpha ? VideoInfo::CS_YUVA420PS  : VideoInfo::CS_YUV420PS; break;\n    }\n  }\n  else if (to_422) {\n    if (vi.Is422()) {\n      // possible shortcut\n      if (ChromaLocation_In == ChromaLocation_Out)\n      {\n        if (shouldStripAlpha)\n          return new RemoveAlphaPlane(clip, env);\n        if (shouldAddAlpha) {\n          // create with default alpha\n          clip = new AddAlphaPlane(clip, nullptr, 0.0f, false, env);\n          vi = clip->GetVideoInfo();\n        }\n        return clip;\n      }\n    }\n\n    outplacement = args[5];\n    switch (bits_per_pixel)\n    {\n    case 8 : pixel_type = targethasAlpha ? VideoInfo::CS_YUVA422 : VideoInfo::CS_YV16; break;\n    case 10: pixel_type = targethasAlpha ? VideoInfo::CS_YUVA422P10 : VideoInfo::CS_YUV422P10; break;\n    case 12: pixel_type = targethasAlpha ? VideoInfo::CS_YUVA422P12 : VideoInfo::CS_YUV422P12; break;\n    case 14: pixel_type = targethasAlpha ? VideoInfo::CS_YUVA422P14 : VideoInfo::CS_YUV422P14; break;\n    case 16: pixel_type = targethasAlpha ? VideoInfo::CS_YUVA422P16 : VideoInfo::CS_YUV422P16; break;\n    case 32: pixel_type = targethasAlpha ? VideoInfo::CS_YUVA422PS  : VideoInfo::CS_YUV422PS; break;\n    }\n  }\n  else if (to_444) {\n    if (vi.Is444()) {\n      if (shouldStripAlpha)\n        return new RemoveAlphaPlane(clip, env);\n      if (shouldAddAlpha) {\n        // create with default alpha\n        clip = new AddAlphaPlane(clip, nullptr, 0.0f, false, env);\n        vi = clip->GetVideoInfo();\n      }\n      return clip;\n    }\n\n    switch (bits_per_pixel)\n    {\n    case 8 : pixel_type = targethasAlpha ? VideoInfo::CS_YUVA444 : VideoInfo::CS_YV24; break;\n    case 10: pixel_type = targethasAlpha ? VideoInfo::CS_YUVA444P10 : VideoInfo::CS_YUV444P10; break;\n    case 12: pixel_type = targethasAlpha ? VideoInfo::CS_YUVA444P12 : VideoInfo::CS_YUV444P12; break;\n    case 14: pixel_type = targethasAlpha ? VideoInfo::CS_YUVA444P14 : VideoInfo::CS_YUV444P14; break;\n    case 16: pixel_type = targethasAlpha ? VideoInfo::CS_YUVA444P16 : VideoInfo::CS_YUV444P16; break;\n    case 32: pixel_type = targethasAlpha ? VideoInfo::CS_YUVA444PS  : VideoInfo::CS_YUV444PS; break;\n    }\n  }\n  else if (to_411) {\n    if (target_bits_per_pixel != 8)\n      env->ThrowError(\"%s: only bits=8 supported for YV411\", filter);\n    if (vi.IsYV411()) return clip;\n    if(vi.ComponentSize()!=1)\n      env->ThrowError(\"%s: 8 bit input only\", filter);\n\n    pixel_type = VideoInfo::CS_YV411;\n  }\n  else env->ThrowError(\"Convert: unknown filter '%s'.\", filter);\n\n  if (pixel_type == VideoInfo::CS_UNKNOWN)\n    env->ThrowError(\"%s: unsupported bit depth\", filter);\n\n  if (converted)\n    clip = env->Invoke(\"Cache\", AVSValue(clip)).AsClip();\n\n  // ConvertToPlanarGeneric's GetFrame will recognize if alpha copy or fill-with-defaults needed\n  AVSValue dummy_for_to_y;\n\n  return new ConvertToPlanarGeneric(clip, pixel_type,\n    to_y ? false : args[1].AsBool(false), // interlaced\n    ChromaLocation_In, \n    to_y ? dummy_for_to_y : args[4], // chromaresample\n    param1, param2, param3,\n    ChromaLocation_Out,\n    env);\n}\n\nAVSValue __cdecl ConvertToPlanarGeneric::CreateYUV420(AVSValue args, void* user_data, IScriptEnvironment* env) {\n  bool only_8bit = reinterpret_cast<intptr_t>(user_data) == 0;\n  bool to_yuva = reinterpret_cast<intptr_t>(user_data) == 2;\n  if (only_8bit) {\n    // \"ConvertToYV12\" syntax\n    if (args[9].Defined() && args[9].AsInt() != 8)\n      env->ThrowError(\"ConvertToYV12: only 8 bit output supported. \"\n        \"Use ConvertToYUV420 for higher bit depth.\");\n    AVSValue new_args[11] = {\n      args[0], args[1], args[2], args[3], args[4],\n      args[5], args[6], args[7], args[8],\n      AVSValue(8), // bits forced to 8\n      args[10]\n    };\n    AVSValue new_args_val(new_args, 11); // named, lives until end of scope\n    return Create(new_args_val, \"ConvertToYUV420\", only_8bit, to_yuva, env);\n  }\n  return Create(args, \"ConvertToYUV420\", only_8bit, to_yuva, env);\n}\n\nAVSValue __cdecl ConvertToPlanarGeneric::CreateYUV422(AVSValue args, void* user_data, IScriptEnvironment* env) {\n  bool only_8bit = reinterpret_cast<intptr_t>(user_data) == 0;\n  bool to_yuva = reinterpret_cast<intptr_t>(user_data) == 2;\n  if (only_8bit) {\n    // \"ConvertToYV16\" syntax\n    if (args[9].Defined() && args[9].AsInt() != 8)\n      env->ThrowError(\"ConvertToYV16: only 8 bit output supported. \"\n        \"Use ConvertToYUV422 for higher bit depth.\");\n    AVSValue new_args[11] = {\n      args[0], args[1], args[2], args[3], args[4],\n      args[5], args[6], args[7], args[8],\n      AVSValue(8),\n      args[10]\n    };\n    AVSValue new_args_val(new_args, 11);\n    return Create(new_args_val, \"ConvertToYUV422\", only_8bit, to_yuva, env);\n  }\n  return Create(args, \"ConvertToYUV422\", only_8bit, to_yuva, env);\n}\n\nAVSValue __cdecl ConvertToPlanarGeneric::CreateYUV444(AVSValue args, void* user_data, IScriptEnvironment* env) {\n  bool only_8bit = reinterpret_cast<intptr_t>(user_data) == 0;\n  bool to_yuva = reinterpret_cast<intptr_t>(user_data) == 2;\n  if (only_8bit) {\n    // \"ConvertToYV24\" syntax\n    // parameter index skip back by 1 compared to 420/422, no ChromaOutPlacement parameter, bits is at index 8 instead of 9\n    if (args[8].Defined() && args[8].AsInt() != 8)\n      env->ThrowError(\"ConvertToYV24: only 8 bit output supported. \"\n        \"Use ConvertToYUV444 for higher bit depth.\");\n    AVSValue new_args[10] = {\n      args[0], args[1], args[2], args[3], args[4],\n      args[5], args[6], args[7],\n      AVSValue(8),\n      args[9]\n    };\n    AVSValue new_args_val(new_args, 10);\n    return Create(new_args_val, \"ConvertToYUV444\", only_8bit, to_yuva, env);\n  }\n  return Create(args, \"ConvertToYUV444\", only_8bit, to_yuva, env);\n}\n\nAVSValue __cdecl ConvertToPlanarGeneric::CreateYV411(AVSValue args, void* user_data, IScriptEnvironment* env) {\n  bool only_8bit = reinterpret_cast<intptr_t>(user_data) == 0;\n  bool to_yuva = reinterpret_cast<intptr_t>(user_data) == 2;\n  // parameter index skip back by 1 compared to 420/422, no ChromaOutPlacement parameter, bits is at index 8 instead of 9\n  if (args[8].Defined() && args[8].AsInt() != 8)\n    env->ThrowError(\"ConvertToYV411: only 8 bit output supported, \"\n      \"no high bit depth YUV411 format exists.\");\n  AVSValue new_args[10] = {\n    args[0], args[1], args[2], args[3], args[4],\n    args[5], args[6], args[7],\n    AVSValue(8),\n    args[9]\n  };\n  AVSValue new_args_val(new_args, 10);\n  return Create(new_args_val, \"ConvertToYV411\", only_8bit, to_yuva, env);\n}\n\nAVSValue __cdecl ConvertToPlanarGeneric::CreateConvertToYUY2(AVSValue args, void*, IScriptEnvironment* env)\n{\n  PClip clip = args[0].AsClip();\n  VideoInfo vi = clip->GetVideoInfo();\n\n  // Fast no-op: YUY2 source, no parameters at all.\n  // Do not touch frame properties - caller's responsibility.\n  if (vi.IsYUY2()\n    && !args[1].Defined()   // interlaced\n    && !args[2].Defined()   // matrix\n    && !args[3].Defined()   // ChromaInPlacement\n    && !args[4].Defined()   // chromaresample\n    && !args[5].Defined()   // ChromaOutPlacement\n    && !args[6].Defined()   // param1\n    && !args[7].Defined()   // param2\n    && !args[8].Defined()   // param3\n    && !args[9].Defined()   // bits\n    && !args[10].Defined()) // quality\n    return clip;\n\n  // YUY2 is 8-bit only: bits= must be 8 if specified.\n  // We check here to give a proper ConvertToYUY2-specific error message,\n  // rather than letting CreateYUV422 complain about something unrelated.\n  // Source can be any bit depth - the conversion chain will downconvert.\n  if (args[9].Defined() && args[9].AsInt() != 8)\n    env->ThrowError(\"ConvertToYUY2: bits must be 8, YUY2 is an 8-bit format\");\n\n  // Rebuild args with bits=8 forced, so CreateYUV422 sees an explicit\n  // 8-bit target regardless of source bit depth.\n  // This also means the void*1 path in CreateYUV422 won't reject\n  // high bit depth sources - the bits=8 in args drives the downconvert.\n  AVSValue new_args[11] = {\n    args[0],     // clip\n    args[1],     // interlaced\n    args[2],     // matrix\n    args[3],     // ChromaInPlacement\n    args[4],     // chromaresample\n    args[5],     // ChromaOutPlacement\n    args[6],     // param1\n    args[7],     // param2\n    args[8],     // param3\n    AVSValue(8), // bits: always 8 for YUY2, overrides source depth\n    args[10]     // quality\n  };\n\n  // (void*)1: allow any source bit depth, bits=8 in args enforces 8-bit output.\n  // The legacy (void*)0 source-depth check is not appropriate here since\n  // we explicitly want to allow e.g. 10-bit YUV420 → 8-bit YUY2.\n  PClip yv16 = CreateYUV422(AVSValue(new_args, 11), (void*)1, env).AsClip();\n\n  // Lossless repack YV16->YUY2.\n  // Frame properties preserved via NewVideoFrameP in GetFrame.\n  return new ConvertYV16ToYUY2(yv16, env);\n}\n\nAVSValue __cdecl ConvertToPlanarGeneric::CreateConvertBackToYUY2(AVSValue args, void*, IScriptEnvironment* env)\n{\n  // ConvertBackToYUY2 was a pre-2.5 optimization for RGB roundtrip workflows.\n  // It was never interlaced-aware (hardcoded interlaced=false).\n  // Now obsolete - forward to ConvertToYUY2::Create with full parameter array.\n  // ConvertBackToYUY2 signature: c[matrix]s\n  // ConvertToYUY2 signature:     c[interlaced]b[matrix]s[ChromaInPlacement]s\n  //                               [chromaresample]s[ChromaOutPlacement]s\n  //                               [param1]f[param2]f[param3]f[bits]i[quality]b\n  AVSValue new_args[11] = {\n    args[0],        // clip\n    AVSValue(false),// interlaced: was always false in ConvertBackToYUY2\n    args[1],        // matrix: pass through\n    AVSValue(),     // ChromaInPlacement: not defined\n    AVSValue(),     // chromaresample: not defined\n    AVSValue(),     // ChromaOutPlacement: not defined\n    AVSValue(),     // param1: not defined\n    AVSValue(),     // param2: not defined\n    AVSValue(),     // param3: not defined\n    AVSValue(),     // bits: not defined (will be forced to 8 inside)\n    AVSValue()      // quality: not defined\n  };\n  return CreateConvertToYUY2(AVSValue(new_args, 11), nullptr, env);\n}\n\n\n/*\nstatic int getPlacement(const AVSValue& _placement, IScriptEnvironment* env) {\n  const char* placement = _placement.AsString(0);\n\n  if (placement) {\n    if (!lstrcmpi(placement, \"mpeg2\") || !lstrcmpi(placement, \"left\"))\n      return PLACEMENT_MPEG2;\n\n    if (!lstrcmpi(placement, \"mpeg1\") || !lstrcmpi(placement, \"jpeg\") || !lstrcmpi(placement, \"center\"))\n      return PLACEMENT_MPEG1;\n\n    if (!lstrcmpi(placement, \"dv\"))\n      return PLACEMENT_DV;\n\n    if (!lstrcmpi(placement, \"top_left\"))\n      return PLACEMENT_TOP_LEFT;\n\n    env->ThrowError(\"Convert: Unknown chromaplacement\");\n  }\n  return PLACEMENT_MPEG2;\n}\n*/\n\n\nResamplingFunction* getResampler(const char* resampler, AVSValue param1, AVSValue param2, AVSValue param3, bool throw_on_error, IScriptEnvironment* env) {\n  if (resampler) {\n    if (!lstrcmpi(resampler, \"point\"))\n      return new PointFilter();\n    else if (!lstrcmpi(resampler, \"bilinear\"))\n      return new TriangleFilter();\n    else if (!lstrcmpi(resampler, \"bicubic\"))\n      return new MitchellNetravaliFilter(param1.AsDblDef(1.0/3), param2.AsDblDef(1.0/3)); // optional B and C as param1 and param2\n    else if (!lstrcmpi(resampler, \"lanczos\"))\n      return new LanczosFilter((int)param1.AsFloat(3)); // optional Taps as param1\n    else if (!lstrcmpi(resampler, \"lanczos4\"))\n      return new LanczosFilter(4);\n    else if (!lstrcmpi(resampler, \"blackman\"))\n      return new BlackmanFilter((int)param1.AsFloat(4)); // optional Taps as param1\n    else if (!lstrcmpi(resampler, \"spline16\"))\n      return new Spline16Filter();\n    else if (!lstrcmpi(resampler, \"spline36\"))\n      return new Spline36Filter();\n    else if (!lstrcmpi(resampler, \"spline64\"))\n      return new Spline64Filter();\n    else if (!lstrcmpi(resampler, \"gauss\"))\n      return new GaussianFilter(param1.AsDblDef(30.0), param2.AsDblDef(2.0), param3.AsDblDef(4.0)); // optional P, B, S as param1, param2, param3\n    else if (!lstrcmpi(resampler, \"sinc\"))\n      return new SincFilter((int)param1.AsFloat(4)); // optional Taps as param1\n    else if (!lstrcmpi(resampler, \"sinpow\"))\n      return new SinPowerFilter(param1.AsDblDef(2.5)); // optional P as param1\n    else if (!lstrcmpi(resampler, \"sinclin2\"))\n      return new SincLin2Filter((int)param1.AsFloat(15)); // optional Taps= as param1\n    else if (!lstrcmpi(resampler, \"userdefined2\"))\n      return new UserDefined2Filter(param1.AsDblDef(121.0), param2.AsDblDef(19.0), param3.AsDblDef(2.3)); // optional B and C and S as param1, param2, param3\n    else\n      if (throw_on_error)\n        env->ThrowError(\"Convert: Unknown chroma resampler, '%s'\", resampler);\n      else\n        return nullptr; // e.g. from AddBorders\n  }\n  return new MitchellNetravaliFilter(param1.AsDblDef(1.0/3), param2.AsDblDef(1.0/3)); // Default colorspace conversion for AviSynth\n}\n\nDISABLE_WARNING_POP\n"
  },
  {
    "path": "avs_core/convert/convert_planar.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// ConvertPlanar (c) 2005 by Klaus Post\n\n#ifndef __Convert_PLANAR_H__\n#define __Convert_PLANAR_H__\n\n#include <avisynth.h>\n#include <stdint.h>\n#include \"convert.h\"\n#include \"convert_matrix.h\"\n#include \"../filters/resample.h\"\n#include \"convert_helper.h\"\n#include \"convert_bits.h\"\n\nenum YuvRgbConversionType {\n  NATIVE_INT,           // Same bit depth, integer matrix arithmetic, no conversion\n  FORCE_FLOAT,          // Float matrix workflow (required for float input, optional for accuracy)\n  FLOAT_OUTPUT,         // Integer matrix -> float output (for int->float conversions)\n  BITCONV_INT_LIMITED,  // Bit-depth change with limited range (shift-based scaling)\n  BITCONV_INT_FULL      // Bit-depth change with full range (requires float coefficients)\n};\n\n// Dispatcher matching AVX2/SSE2 structure\ntemplate<ConversionDirection direction, typename pixel_t_src, bool lessthan16bit>\nvoid convert_yuv_to_planarrgb_c(BYTE* dstp[3], int dstPitch[3], const BYTE* srcp[3], const int srcPitch[3], int width, int height, const ConversionMatrix& m,\n  int bits_per_pixel, int bits_per_pixel_target, bool force_float);\n\n// useful functions\ntemplate <typename pixel_t>\nvoid fill_chroma(uint8_t * dstp_u, uint8_t * dstp_v, int height, int row_size, int pitch, pixel_t val);\n\ntemplate <typename pixel_t>\nvoid fill_plane(uint8_t * dstp, int height, int row_size, int pitch, pixel_t val);\n\nResamplingFunction* getResampler(const char* resampler, AVSValue param1, AVSValue param2, AVSValue param3, bool throw_on_error, IScriptEnvironment* env);\n\nclass ConvertRGBToYUV444 : public GenericVideoFilter\n{\npublic:\n  ConvertRGBToYUV444(PClip src, const char *matrix_name, bool keep_packedrgb_alpha, int _target_bit_depth, bool _quality, bool& bitdepthConverted, bool _to_y, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\nprivate:\n  int theMatrix;\n  int theColorRange;\n  int theOutColorRange;\n  ConversionMatrix matrix;\n  int pixel_step;\n  bool targetHasAlpha;\n  bool isPlanarRGBfamily;\n  int source_bit_depth;\n  int target_bit_depth;\n  bool quality;\n  bool to_y;\n  // primarily for alpha plane conversion\n  BitDepthConvFuncPtr conv_function;\n  BitDepthConvFuncPtr conv_function_chroma; // 32bit float YUV chroma\n  BitDepthConvFuncPtr conv_function_a;\n};\n\nclass ConvertYUY2ToYV16_or_Y : public GenericVideoFilter\n{\npublic:\n  ConvertYUY2ToYV16_or_Y(PClip src, bool _to_y, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\nprivate:\n  bool to_y;\n};\n\nclass ConvertYUV444ToRGB : public GenericVideoFilter\n{\npublic:\n  ConvertYUV444ToRGB(PClip src, const char* matrix_name, int _pixel_step, int _target_bit_depth, bool quality, bool& bitdepthConverted, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\nprivate:\n  int theMatrix;\n  int theColorRange;\n  // separate out set for rgb target\n  int theOutMatrix;\n  int theOutColorRange;\n  ConversionMatrix matrix;\n  int pixel_step;\n  int source_bit_depth;\n  int target_bit_depth;\n  bool quality; // true: forced float matrix multiplication\n  // primarily for alpha plane conversion\n  BitDepthConvFuncPtr conv_function;\n  BitDepthConvFuncPtr conv_function_chroma; // 32bit float YUV chroma\n  BitDepthConvFuncPtr conv_function_a;\n\n};\n\nclass ConvertYV16ToYUY2 : public GenericVideoFilter\n{\npublic:\n  ConvertYV16ToYUY2(PClip src, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n};\n\nclass ConvertToPlanarGeneric : public GenericVideoFilter\n{\npublic:\n  ConvertToPlanarGeneric(PClip src, int dst_space, bool interlaced,\n                         int _ChromaLocation_In, \n                         const AVSValue& ChromaResampler, const AVSValue& param1, const AVSValue& param2, const AVSValue& param3,\n                         int _ChromaLocation_Out,\n                         IScriptEnvironment* env);\n  ~ConvertToPlanarGeneric() {}\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl CreateY(AVSValue args, void* user_data, IScriptEnvironment* env);\n  static AVSValue __cdecl CreateYV411(AVSValue args, void* user_data, IScriptEnvironment* env);\n  static AVSValue __cdecl CreateYUV420(AVSValue args, void* user_data, IScriptEnvironment* env);\n  static AVSValue __cdecl CreateYUV422(AVSValue args, void* user_data, IScriptEnvironment* env);\n  static AVSValue __cdecl CreateYUV444(AVSValue args, void* user_data, IScriptEnvironment* env);\n  // YUY2 targets: route through YV16, no GetFrame in this class needed.\n  // Placed here as the natural hub for all YUV format conversion routing.\n  static AVSValue __cdecl CreateConvertToYUY2(AVSValue args, void* user_data, IScriptEnvironment* env);\n  static AVSValue __cdecl CreateConvertBackToYUY2(AVSValue args, void* user_data, IScriptEnvironment* env);\n\n\nprivate:\n  static AVSValue Create(AVSValue& args, const char* filter, bool strip_alpha_legacy_8bit, bool to_yuva, IScriptEnvironment* env);\n  bool Yinput;\n  int pixelsize;\n  int ChromaLocation_In;\n  int ChromaLocation_Out; // future _ChromaLocation\n  PClip Usource;\n  PClip Vsource;\n};\n\nclass AddAlphaPlane : public GenericVideoFilter\n{\npublic:\n  AddAlphaPlane(PClip _child, PClip _maskClip, float _mask_f, bool isMaskDefined, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n,IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\nprivate:\n  int mask;\n  float mask_f;\n  PClip alphaClip;\n  int pixelsize;\n  int bits_per_pixel;\n};\n\nclass RemoveAlphaPlane : public GenericVideoFilter\n{\npublic:\n  RemoveAlphaPlane(PClip _child, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n,IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\nprivate:\n};\n\n#endif\n"
  },
  {
    "path": "avs_core/convert/convert_rgb.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include \"convert_rgb.h\"\n#ifdef INTEL_INTRINSICS\n#include \"intel/convert_rgb_sse.h\"\n#include \"intel/convert_rgb_avx2.h\"\n#ifdef INTEL_INTRINSICS_AVX512\n#include \"intel/convert_rgb_avx512.h\"\n#endif\n#endif\n#include <avs/alignment.h>\n\n\n/*************************************\n *******   RGB Helper Classes   ******\n *************************************/\n\nRGBtoRGBA::RGBtoRGBA(PClip src)\n  : GenericVideoFilter(src)\n{\n  vi.pixel_type = src->GetVideoInfo().ComponentSize() == 1 ? VideoInfo::CS_BGR32 : VideoInfo::CS_BGR64;\n}\n\nstatic void convert_rgb24_to_rgb32_c(const BYTE *srcp, BYTE *dstp, size_t src_pitch, size_t dst_pitch, size_t width, size_t height) {\n  for (size_t y = height; y > 0; --y) {\n    for (size_t x = 0; x < width; ++x) {\n      *reinterpret_cast<int*>(dstp + x*4) = *reinterpret_cast<const int*>(srcp+x*3) | 0xFF000000;\n    }\n    srcp += src_pitch;\n    dstp += dst_pitch;\n  }\n}\n\nstatic void convert_rgb48_to_rgb64_c(const BYTE *srcp, BYTE *dstp, size_t src_pitch, size_t dst_pitch, size_t width, size_t height) {\n  for (size_t y = height; y > 0; --y) {\n    for (size_t x = 0; x < width; ++x) {\n      *reinterpret_cast<uint64_t*>(dstp + x*8) = *reinterpret_cast<const uint64_t*>(srcp+x*6) | 0xFFFF000000000000ULL;\n    }\n    srcp += src_pitch;\n    dstp += dst_pitch;\n  }\n}\n\nPVideoFrame __stdcall RGBtoRGBA::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame src = child->GetFrame(n, env);\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n  const BYTE *srcp = src->GetReadPtr();\n  BYTE *dstp = dst->GetWritePtr();\n  const int src_pitch = src->GetPitch();\n  const int dst_pitch = dst->GetPitch();\n\n  int pixelsize = vi.ComponentSize();\n\n  using conv_fn_t = void(*)(const BYTE*, BYTE*, size_t, size_t, size_t, size_t);\n  conv_fn_t fn;\n\n#ifdef INTEL_INTRINSICS\n  if (env->GetCPUFlags() & CPUF_SSSE3)\n    fn = (pixelsize == 1) ? convert_rgb24_to_rgb32_ssse3 : convert_rgb48_to_rgb64_ssse3;\n  else\n#endif\n    fn = (pixelsize == 1) ? convert_rgb24_to_rgb32_c : convert_rgb48_to_rgb64_c;\n\n  fn(srcp, dstp, src_pitch, dst_pitch, vi.width, vi.height);\n  return dst;\n}\n\n\n\n\nRGBAtoRGB::RGBAtoRGB(PClip src)\n: GenericVideoFilter(src)\n{\n  vi.pixel_type = src->GetVideoInfo().ComponentSize() == 1 ? VideoInfo::CS_BGR24 : VideoInfo::CS_BGR48;\n}\n\nstatic void convert_rgb32_to_rgb24_c(const BYTE *srcp, BYTE *dstp, size_t src_pitch, size_t dst_pitch, size_t width, size_t height) {\n  for (size_t y = height; y > 0; --y) {\n    size_t x;\n    for (x = 0; x < width-1; ++x) {\n      *reinterpret_cast<int*>(dstp+x*3) = *reinterpret_cast<const int*>(srcp+x*4);\n    }\n    //last pixel\n    dstp[x*3+0] = srcp[x*4+0];\n    dstp[x*3+1] = srcp[x*4+1];\n    dstp[x*3+2] = srcp[x*4+2];\n\n    srcp += src_pitch;\n    dstp += dst_pitch;\n  }\n}\n\nstatic void convert_rgb64_to_rgb48_c(const BYTE *srcp, BYTE *dstp, size_t src_pitch, size_t dst_pitch, size_t width, size_t height) {\n  for (size_t y = height; y > 0; --y) {\n    size_t x;\n    for (x = 0; x < width-1; ++x) { // width-1 really!\n      *reinterpret_cast<uint64_t*>(dstp+x*6) = *reinterpret_cast<const uint64_t*>(srcp+x*8);\n    }\n    //last pixel\n    reinterpret_cast<uint16_t*>(dstp)[x*3+0] = reinterpret_cast<const uint16_t*>(srcp)[x*4+0];\n    reinterpret_cast<uint16_t*>(dstp)[x*3+1] = reinterpret_cast<const uint16_t*>(srcp)[x*4+1];\n    reinterpret_cast<uint16_t*>(dstp)[x*3+2] = reinterpret_cast<const uint16_t*>(srcp)[x*4+2];\n\n    srcp += src_pitch;\n    dstp += dst_pitch;\n  }\n}\n\nPVideoFrame __stdcall RGBAtoRGB::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame src = child->GetFrame(n, env);\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n  const BYTE *srcp = src->GetReadPtr();\n  BYTE *dstp = dst->GetWritePtr();\n  size_t src_pitch = src->GetPitch();\n  size_t dst_pitch = dst->GetPitch();\n\n  int pixelsize = vi.ComponentSize();\n\n  using conv_fn_t = void(*)(const BYTE*, BYTE*, size_t, size_t, size_t, size_t);\n  conv_fn_t fn = nullptr;\n\n#ifdef INTEL_INTRINSICS\n  if (env->GetCPUFlags() & CPUF_SSSE3)\n    fn = (pixelsize == 1) ? convert_rgb32_to_rgb24_ssse3 : convert_rgb64_to_rgb48_ssse3;\n  else if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_SSE2))\n    fn = convert_rgb32_to_rgb24_sse2;\n  else\n#endif\n    fn = (pixelsize == 1) ? convert_rgb32_to_rgb24_c : convert_rgb64_to_rgb48_c;\n\n  fn(srcp, dstp, src_pitch, dst_pitch, vi.width, vi.height);\n\n  return dst;\n}\n\nPackedRGBtoPlanarRGB::PackedRGBtoPlanarRGB(PClip src, bool _sourceHasAlpha, bool _targetHasAlpha)\n  : GenericVideoFilter(src), sourceHasAlpha(_sourceHasAlpha), targetHasAlpha(_targetHasAlpha)\n{\n  vi.pixel_type = src->GetVideoInfo().ComponentSize() == 1 ?\n    (targetHasAlpha ? VideoInfo::CS_RGBAP : VideoInfo::CS_RGBP) :\n    (targetHasAlpha ? VideoInfo::CS_RGBAP16 : VideoInfo::CS_RGBP16);\n}\n\ntemplate<typename pixel_t, int src_numcomponents, bool targetHasAlpha>\nstatic void convert_rgb_to_rgbp_c(const BYTE* srcp, BYTE* (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height) {\n  constexpr int bits_per_pixel = sizeof(pixel_t) == 1 ? 8 : 16;\n  constexpr int max_pixel_value = (1 << bits_per_pixel) - 1;\n  for (int y = height; y > 0; --y) {\n    int x;\n    for (x = 0; x < width; ++x) {\n      pixel_t B = reinterpret_cast<const pixel_t*>(srcp)[x * src_numcomponents + 0];\n      pixel_t G = reinterpret_cast<const pixel_t*>(srcp)[x * src_numcomponents + 1];\n      pixel_t R = reinterpret_cast<const pixel_t*>(srcp)[x * src_numcomponents + 2];\n      pixel_t A = 0;\n      if constexpr (targetHasAlpha)\n        A = (src_numcomponents == 4) ? reinterpret_cast<const pixel_t*>(srcp)[x * src_numcomponents + 3] : max_pixel_value;\n      reinterpret_cast<pixel_t*>(dstp[0])[x] = G;\n      reinterpret_cast<pixel_t*>(dstp[1])[x] = B;\n      reinterpret_cast<pixel_t*>(dstp[2])[x] = R;\n      if constexpr (targetHasAlpha)\n        reinterpret_cast<pixel_t*>(dstp[3])[x] = A;\n    }\n\n    srcp -= src_pitch; // source packed RGB is upside down\n    dstp[0] += dst_pitch[0];\n    dstp[1] += dst_pitch[1];\n    dstp[2] += dst_pitch[2];\n    if constexpr (targetHasAlpha)\n      dstp[3] += dst_pitch[3];\n  }\n}\n\nPVideoFrame __stdcall PackedRGBtoPlanarRGB::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame src = child->GetFrame(n, env);\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n  int src_pitch = src->GetPitch();\n  const BYTE* srcp = src->GetReadPtr();\n  BYTE* dstp[4] = {\n    dst->GetWritePtr(PLANAR_G), dst->GetWritePtr(PLANAR_B),\n    dst->GetWritePtr(PLANAR_R), dst->GetWritePtr(PLANAR_A)\n  };\n  int dst_pitch[4] = {\n    dst->GetPitch(PLANAR_G), dst->GetPitch(PLANAR_B),\n    dst->GetPitch(PLANAR_R), dst->GetPitch(PLANAR_A)\n  };\n  int pixelsize = vi.ComponentSize();\n  srcp += src_pitch * (vi.height - 1); // start from bottom: packed RGB is upside down\n\n  using conv_fn_t = void(*)(const BYTE*, BYTE* (&)[4], int, int(&)[4], int, int);\n  conv_fn_t fn = nullptr;\n\n  const bool targetHasAlpha = vi.IsPlanarRGBA();\n\n#ifdef INTEL_INTRINSICS\n  auto CPU = env->GetCPUFlagsEx();\n  const bool hasSSE2 = (CPU & CPUF_SSE2) != 0;\n  const bool hasSSSE3 = (CPU & CPUF_SSSE3) != 0;\n  const bool hasAVX2 = (CPU & CPUF_AVX2) != 0;\n#ifdef INTEL_INTRINSICS_AVX512\n  //const bool has_AVX512_base = (CPU & CPUF_AVX512_BASE) == CPUF_AVX512_BASE; // group flag!\n  const bool has_AVX512_fast = (CPU & CPUF_AVX512_FAST) == CPUF_AVX512_FAST; // group flag!\n#endif\n#endif\n\n  // for RGBA there is no width limit, we do full scanlines, Avisynth's 64 byte alignment allows\n  // processing 16 RGB32 pixels or 8 RGB64 pixels at a time\n  // RGB is tricky, remainder handling is needed.\n\n  if (pixelsize == 1) {\n    if (sourceHasAlpha) {\n      // RGB32->\n#ifdef INTEL_INTRINSICS\n#ifdef INTEL_INTRINSICS_AVX512\n      if (has_AVX512_fast)  fn = targetHasAlpha ? convert_rgba_to_rgbp_avx512vbmi<uint8_t, true> : convert_rgba_to_rgbp_avx512vbmi<uint8_t, false>;\n      else\n#endif\n      if (hasAVX2)  fn = targetHasAlpha ? convert_rgba_to_rgbp_avx2<uint8_t, true> : convert_rgba_to_rgbp_avx2<uint8_t, false>;\n      else if (hasSSSE3)  fn = targetHasAlpha ? convert_rgba_to_rgbp_ssse3<uint8_t, true> : convert_rgba_to_rgbp_ssse3<uint8_t, false>;\n      else if (hasSSE2)  fn = targetHasAlpha ? convert_rgba_to_rgbp_sse2 <uint8_t, true> : convert_rgba_to_rgbp_sse2 <uint8_t, false>;\n      else\n#endif\n        fn = targetHasAlpha ? convert_rgb_to_rgbp_c<uint8_t, 4, true> : convert_rgb_to_rgbp_c<uint8_t, 4, false>;\n    }\n    else {\n      // RGB24->\n#ifdef INTEL_INTRINSICS\n      // RGB24->RGB(A)P8, works with 48byte blocks (16xRGB), min width is 16 (SSSE3, 32 (AVX2), width constraint is due to remainder handling, not alignment)\n      if (hasAVX2 && vi.width >= 32) fn = targetHasAlpha ? convert_rgb_to_rgbp_avx2 <uint8_t, true> : convert_rgb_to_rgbp_avx2 <uint8_t, false>;\n      else if (hasSSSE3 && vi.width >= 16) fn = targetHasAlpha ? convert_rgb_to_rgbp_ssse3<uint8_t, true> : convert_rgb_to_rgbp_ssse3<uint8_t, false>;\n      else if (hasSSE2 && vi.width >= 16) fn = targetHasAlpha ? convert_rgb_to_rgbp_sse2 <uint8_t, true> : convert_rgb_to_rgbp_sse2 <uint8_t, false>;\n      else\n#endif\n        fn = targetHasAlpha ? convert_rgb_to_rgbp_c<uint8_t, 3, true> : convert_rgb_to_rgbp_c<uint8_t, 3, false>;\n    }\n  }\n  else { // pixelsize == 2\n    if (sourceHasAlpha) {\n      // RGB64->\n#ifdef INTEL_INTRINSICS\n#ifdef INTEL_INTRINSICS_AVX512\n      if (has_AVX512_fast)  fn = targetHasAlpha ? convert_rgba_to_rgbp_avx512vbmi<uint16_t, true> : convert_rgba_to_rgbp_avx512vbmi<uint16_t, false>;\n      else\n#endif\n      if (hasAVX2)  fn = targetHasAlpha ? convert_rgba_to_rgbp_avx2<uint16_t, true> : convert_rgba_to_rgbp_avx2<uint16_t, false>;\n      else if (hasSSSE3)  fn = targetHasAlpha ? convert_rgba_to_rgbp_ssse3<uint16_t, true> : convert_rgba_to_rgbp_ssse3<uint16_t, false>;\n      else if (hasSSE2)  fn = targetHasAlpha ? convert_rgba_to_rgbp_sse2 <uint16_t, true> : convert_rgba_to_rgbp_sse2 <uint16_t, false>;\n      else\n#endif\n        fn = targetHasAlpha ? convert_rgb_to_rgbp_c<uint16_t, 4, true> : convert_rgb_to_rgbp_c<uint16_t, 4, false>;\n    }\n    else {\n      // RGB48->\n      // width constraint is due to remainder handling, not alignment, AVX2 needs 16 pixels (48 bytes) to process, SSE2/SSSE3 need 8 pixels (48 bytes) to process\n#ifdef INTEL_INTRINSICS\n      if (hasAVX2 && vi.width >= 16) fn = targetHasAlpha ? convert_rgb_to_rgbp_avx2 <uint16_t, true> : convert_rgb_to_rgbp_avx2 <uint16_t, false>;\n      else if (hasSSSE3 && vi.width >= 8)  fn = targetHasAlpha ? convert_rgb_to_rgbp_ssse3<uint16_t, true> : convert_rgb_to_rgbp_ssse3<uint16_t, false>;\n      else if (hasSSE2 && vi.width >= 8)  fn = targetHasAlpha ? convert_rgb_to_rgbp_sse2 <uint16_t, true> : convert_rgb_to_rgbp_sse2 <uint16_t, false>;\n      else\n#endif\n        fn = targetHasAlpha ? convert_rgb_to_rgbp_c<uint16_t, 3, true> : convert_rgb_to_rgbp_c<uint16_t, 3, false>;\n    }\n  }\n\n  fn(srcp, dstp, src_pitch, dst_pitch, vi.width, vi.height);\n  return dst;\n}\n\nPlanarRGBtoPackedRGB::PlanarRGBtoPackedRGB(PClip src, bool _targetHasAlpha)\n  : GenericVideoFilter(src), targetHasAlpha(_targetHasAlpha)\n{\n  vi.pixel_type = src->GetVideoInfo().ComponentSize() == 1 ?\n    (targetHasAlpha ? VideoInfo::CS_BGR32 : VideoInfo::CS_BGR24) : // PlanarRGB(A)->RGB24/32\n    (targetHasAlpha ? VideoInfo::CS_BGR64 : VideoInfo::CS_BGR48);  // PlanarRGB(A)->RGB48/64\n}\n\ntemplate<typename pixel_t, int target_numcomponents, bool hasSrcAlpha>\nstatic void convert_rgbp_to_rgb_c(const BYTE *(&srcp)[4], BYTE * dstp, int (&src_pitch)[4], int dst_pitch, int width, int height) {\n\n  constexpr int bits_per_pixel = sizeof(pixel_t) == 1 ? 8 : 16;\n  constexpr int max_pixel_value = (1 << bits_per_pixel) - 1;\n\n  for (int y = 0; y < height; y++) {\n    int x;\n    for (x = 0; x < width; ++x) {\n      const pixel_t G = reinterpret_cast<const pixel_t *>(srcp[0])[x];\n      const pixel_t B = reinterpret_cast<const pixel_t *>(srcp[1])[x];\n      const pixel_t R = reinterpret_cast<const pixel_t *>(srcp[2])[x];\n      reinterpret_cast<pixel_t *>(dstp)[x*target_numcomponents+0] = B;\n      reinterpret_cast<pixel_t *>(dstp)[x*target_numcomponents+1] = G;\n      reinterpret_cast<pixel_t *>(dstp)[x*target_numcomponents+2] = R;\n      if constexpr (target_numcomponents == 4) { // either from A channel or default transparent constant\n        pixel_t A;\n        if constexpr (hasSrcAlpha)\n          A = reinterpret_cast<const pixel_t*>(srcp[3])[x];\n        else\n          A = max_pixel_value; // 255/65535\n        reinterpret_cast<pixel_t *>(dstp)[x*target_numcomponents + 3] = A;\n      }\n    }\n\n    dstp -= dst_pitch; // source packed RGB is upside down\n    srcp[0] += src_pitch[0];\n    srcp[1] += src_pitch[1];\n    srcp[2] += src_pitch[2];\n    if constexpr (hasSrcAlpha)\n      srcp[3] += src_pitch[3];\n  }\n}\n\nPVideoFrame __stdcall PlanarRGBtoPackedRGB::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame src = child->GetFrame(n, env);\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n  int dst_pitch = dst->GetPitch();\n  BYTE* dstp = dst->GetWritePtr();\n  const BYTE* srcp[4] = { src->GetReadPtr(PLANAR_G), src->GetReadPtr(PLANAR_B),\n                         src->GetReadPtr(PLANAR_R), src->GetReadPtr(PLANAR_A) };\n  int src_pitch[4] = { src->GetPitch(PLANAR_G), src->GetPitch(PLANAR_B),\n                      src->GetPitch(PLANAR_R), src->GetPitch(PLANAR_A) };\n  int pixelsize = vi.ComponentSize();\n  dstp += dst_pitch * (vi.height - 1); // start from bottom: packed RGB is upside down\n\n  const bool hasSrcAlpha = (src_pitch[3] != 0); // planar RGB_A_ source\n  const bool hasTargetAlpha = (vi.NumComponents() == 4); // RGB32 or RGB64 target\n\n  using conv_fn_t = void(*)(const BYTE* (&)[4], BYTE*, int(&)[4], int, int, int);\n  conv_fn_t fn = nullptr;\n\n#ifdef INTEL_INTRINSICS\n  const bool hasSSE2 = (env->GetCPUFlags() & CPUF_SSE2) != 0;\n#endif\n\n  if (pixelsize == 1) {\n    if (!hasTargetAlpha) {  // RGB24 — no SIMD path exists\n      fn = hasSrcAlpha ? convert_rgbp_to_rgb_c<uint8_t, 3, true> : convert_rgbp_to_rgb_c<uint8_t, 3, false>;\n    }\n    else {  // RGBA32\n#ifdef INTEL_INTRINSICS\n      if (hasSSE2)\n        fn = hasSrcAlpha ? convert_rgbp_to_rgba_sse2<uint8_t, true> : convert_rgbp_to_rgba_sse2<uint8_t, false>;\n      else\n#endif\n        fn = hasSrcAlpha ? convert_rgbp_to_rgb_c<uint8_t, 4, true> : convert_rgbp_to_rgb_c<uint8_t, 4, false>;\n    }\n  }\n  else {  // pixelsize == 2\n    if (!hasTargetAlpha) {  // RGB48 — no SIMD path exists\n      fn = hasSrcAlpha ? convert_rgbp_to_rgb_c<uint16_t, 3, true> : convert_rgbp_to_rgb_c<uint16_t, 3, false>;\n    }\n    else {  // RGBA64\n#ifdef INTEL_INTRINSICS\n      if (hasSSE2)\n        fn = hasSrcAlpha ? convert_rgbp_to_rgba_sse2<uint16_t, true> : convert_rgbp_to_rgba_sse2<uint16_t, false>;\n      else\n#endif\n        fn = hasSrcAlpha ? convert_rgbp_to_rgb_c<uint16_t, 4, true> : convert_rgbp_to_rgb_c<uint16_t, 4, false>;\n    }\n  }\n\n  fn(srcp, dstp, src_pitch, dst_pitch, vi.width, vi.height);\n  return dst;\n}\n"
  },
  {
    "path": "avs_core/convert/convert_rgb.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Convert_RGB_H__\n#define __Convert_RGB_H__\n\n#include <avisynth.h>\n\n\nclass RGBtoRGBA : public GenericVideoFilter\n/**\n  * RGB -> RGBA, setting alpha channel to 255/65535\n  */\n{\npublic:\n  RGBtoRGBA(PClip src);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n};\n\n\nclass RGBAtoRGB : public GenericVideoFilter\n/**\n  * Class to strip alpha channel\n  */\n{\npublic:\n  RGBAtoRGB(PClip src);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n};\n\nclass PackedRGBtoPlanarRGB : public GenericVideoFilter\n  /**\n  * RGB(A) -> RGBP(A)\n  */\n{\npublic:\n  PackedRGBtoPlanarRGB(PClip src, bool _sourceHasAlpha, bool _targetHasAlpha);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  const bool sourceHasAlpha;\n  const bool targetHasAlpha;\n};\n\nclass PlanarRGBtoPackedRGB : public GenericVideoFilter\n  /**\n  * RGBP(A) -> RGB(A)\n  */\n{\npublic:\n  PlanarRGBtoPackedRGB(PClip src, bool _targetHasAlpha);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  const bool targetHasAlpha;\n};\n\n#endif  // __Convert_RGB_H__\n"
  },
  {
    "path": "avs_core/convert/intel/convert_audio_avx2.cpp",
    "content": "// Avisynth+\n// https://avs-plus.net\n//\n// This file is part of Avisynth+ which is released under GPL2+ with exception.\n\n// Convert Audio helper functions (AVX2)\n// Copyright (c) 2020 Xinyue Lu, (c) 2021 pinterf\n\n#include <avs/types.h>\n#include <avs/config.h>\n\n// Intrinsics base header + really required extension headers\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n#include <immintrin.h> // AVX2\n\n\n// Easy: 32-16, 16-32\n// Float: 8/16/32-FLT, FLT-8/16/32\n\nvoid convert32To16_AVX2(void *inbuf, void *outbuf, int count) {\n  auto in = reinterpret_cast<int32_t *>(inbuf);\n  auto in16 = reinterpret_cast<int16_t *>(inbuf);\n  auto out = reinterpret_cast<int16_t *>(outbuf);\n\n  const int c_loop = count & ~15;\n\n  for (int i = c_loop; i < count; i++)\n    out[i] = in16[i * 2 + 1];\n\n  for (int i = 0; i < c_loop; i += 16) {\n    __m256i in32a = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(in)); in += 8;\n    __m256i in32b = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(in)); in += 8;\n    __m256i in16a = _mm256_srai_epi32(in32a, 16);\n    __m256i in16b = _mm256_srai_epi32(in32b, 16);\n    __m256i out16 = _mm256_packs_epi32(in16a, in16b);\n    out16 = _mm256_permute4x64_epi64(out16, 216);\n    _mm256_storeu_si256(reinterpret_cast<__m256i *>(out), out16); out += 16;\n  }\n}\n\nvoid convert16To32_AVX2(void *inbuf, void *outbuf, int count) {\n  auto in = reinterpret_cast<int16_t *>(inbuf);\n  auto out = reinterpret_cast<int32_t *>(outbuf);\n  auto out16 = reinterpret_cast<int16_t *>(outbuf);\n\n  const int c_loop = count & ~15;\n\n  for (int i = c_loop; i < count; i++) {\n    out16[i * 2] = 0;\n    out16[i * 2 + 1] = in[i];\n  }\n\n  __m256i zero = _mm256_set1_epi16(0);\n  for (int i = 0; i < c_loop; i += 16) {\n    __m256i in16 = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(in)); in += 16;\n    in16 = _mm256_permute4x64_epi64(in16, 216);\n    __m256i out32a = _mm256_unpacklo_epi16(zero, in16);\n    __m256i out32b = _mm256_unpackhi_epi16(zero, in16);\n    _mm256_storeu_si256(reinterpret_cast<__m256i *>(out), out32a); out += 8;\n    _mm256_storeu_si256(reinterpret_cast<__m256i *>(out), out32b); out += 8;\n  }\n}\n\nvoid convert8ToFLT_AVX2(void* inbuf, void* outbuf, int count) {\n  auto in = reinterpret_cast<uint8_t*>(inbuf);\n  auto out = reinterpret_cast<SFLOAT*>(outbuf);\n  constexpr float divisor = 1.0f / 128.f; // 1 << 7\n\n  const int c_loop = count & ~7;\n\n  for (int i = c_loop; i < count; i++)\n    out[i] = (in[i] - 128) * divisor;\n\n  __m256 divv = _mm256_set1_ps(divisor);\n  for (int i = 0; i < c_loop; i += 8) {\n    __m128i src = _mm_loadl_epi64(reinterpret_cast<__m128i*>(in)); in += 8;\n    __m256i in32 = _mm256_cvtepu8_epi32(src);\n    in32 = _mm256_sub_epi32(in32, _mm256_set1_epi32(128));\n    __m256 infl = _mm256_cvtepi32_ps(in32);\n    __m256 outfl = _mm256_mul_ps(infl, divv);\n    _mm256_storeu_ps(out, outfl); out += 8;\n  }\n}\n\nvoid convertFLTTo8_AVX2(void* inbuf, void* outbuf, int count) {\n  auto in = reinterpret_cast<SFLOAT*>(inbuf);\n  auto out = reinterpret_cast<uint8_t*>(outbuf);\n  constexpr float multiplier = 128.f;\n  constexpr float max8 = 127.f;\n  constexpr float min8 = -128.f;\n\n  const int c_loop = count & ~15;\n\n  for (int i = c_loop; i < count; i++) {\n    float val = in[i] * multiplier;\n    uint8_t result;\n    if (val >= max8) result = 255;\n    else if (val <= min8) result = 0;\n    else result = static_cast<int8_t>(val) + 128;\n    out[i] = result;\n  }\n\n  __m256 mulv = _mm256_set1_ps(multiplier);\n  __m256 maxv = _mm256_set1_ps(max8);\n  __m256 minv = _mm256_set1_ps(min8);\n  for (int i = 0; i < c_loop; i += 16) {\n    __m256 infl_lo = _mm256_loadu_ps(in); in += 8;\n    __m256 infl_hi = _mm256_loadu_ps(in); in += 8;\n    __m256 outfl_lo = _mm256_max_ps(minv, _mm256_min_ps(maxv, _mm256_mul_ps(infl_lo, mulv)));\n    __m256 outfl_hi = _mm256_max_ps(minv, _mm256_min_ps(maxv, _mm256_mul_ps(infl_hi, mulv)));\n    __m256i out32_lo = _mm256_cvttps_epi32(outfl_lo);\n    __m256i out32_hi = _mm256_cvttps_epi32(outfl_hi);\n    __m256i out16 = _mm256_packs_epi32(out32_lo, out32_hi);\n\n    out16 = _mm256_permute4x64_epi64(out16, (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6));\n    __m128i out16_lo = _mm256_castsi256_si128(out16);\n    __m128i out16_hi = _mm256_extractf128_si256(out16, 1);\n    __m128i out8 = _mm_packs_epi16(out16_lo, out16_hi);\n    out8 = _mm_add_epi8(out8, _mm_set1_epi8(-128)); // 128\n    _mm_storeu_si128(reinterpret_cast<__m128i*>(out), out8); out += 16;\n  }\n}\n\nvoid convert16ToFLT_AVX2(void* inbuf, void* outbuf, int count) {\n  auto in = reinterpret_cast<int16_t*>(inbuf);\n  auto out = reinterpret_cast<SFLOAT*>(outbuf);\n  constexpr float divisor = 1.0f / 32768.f; // 1 << 15\n\n  const int c_loop = count & ~7;\n\n  for (int i = c_loop; i < count; i++)\n    out[i] = in[i] * divisor;\n\n  __m256 divv = _mm256_set1_ps(divisor);\n  for (int i = 0; i < c_loop; i += 8) {\n    __m128i src = _mm_loadu_si128(reinterpret_cast<__m128i*>(in)); in += 8;\n    __m256i in32 = _mm256_cvtepi16_epi32(src);\n    __m256 infl = _mm256_cvtepi32_ps(in32);\n    __m256 outfl = _mm256_mul_ps(infl, divv);\n    _mm256_storeu_ps(out, outfl); out += 8;\n  }\n}\n\nvoid convertFLTTo16_AVX2(void* inbuf, void* outbuf, int count) {\n  auto in = reinterpret_cast<SFLOAT*>(inbuf);\n  auto out = reinterpret_cast<int16_t*>(outbuf);\n  constexpr float multiplier = 32768.f;\n  constexpr float max16 = 32767.f;\n  constexpr float min16 = -32768.f;\n\n  const int c_loop = count & ~7;\n\n  for (int i = c_loop; i < count; i++) {\n    float val = in[i] * multiplier;\n    int16_t result;\n    if (val >= max16) result = 32767;\n    else if (val <= min16) result = (int16_t)-32768;\n    else result = static_cast<int16_t>(val);\n    out[i] = result;\n  }\n\n  __m256 mulv = _mm256_set1_ps(multiplier);\n  __m256 maxv = _mm256_set1_ps(max16);\n  __m256 minv = _mm256_set1_ps(min16);\n  for (int i = 0; i < c_loop; i += 8) {\n    __m256 infl = _mm256_loadu_ps(in); in += 8;\n    __m256 outfl = _mm256_max_ps(minv, _mm256_min_ps(maxv, _mm256_mul_ps(infl, mulv)));\n    __m256i out32 = _mm256_cvttps_epi32(outfl);\n    __m256i out16 = _mm256_packs_epi32(out32, out32);\n\n    out16 = _mm256_permute4x64_epi64(out16, (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6));\n\n    _mm_storeu_si128(reinterpret_cast<__m128i*>(out), _mm256_castsi256_si128(out16)); out += 8;\n  }\n}\n\n\n\nvoid convert32ToFLT_AVX2(void *inbuf, void *outbuf, int count) {\n  auto in = reinterpret_cast<int32_t *>(inbuf);\n  auto out = reinterpret_cast<SFLOAT *>(outbuf);\n  const float divisor = 1.0f/2147483648.0f;\n\n  const int c_loop = count & ~7;\n\n  for (int i = c_loop; i < count; i++)\n    out[i] = in[i] * divisor;\n\n  __m256 divv = _mm256_set1_ps(divisor);\n  for (int i = 0; i < c_loop; i += 8) {\n    __m256i in32 = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(in)); in += 8;\n    __m256 infl = _mm256_cvtepi32_ps(in32);\n    __m256 outfl = _mm256_mul_ps(infl, divv);\n    _mm256_storeu_ps(out, outfl); out += 8;\n  }\n}\n\nvoid convertFLTTo32_AVX2(void *inbuf, void *outbuf, int count) {\n  auto in = reinterpret_cast<SFLOAT *>(inbuf);\n  auto out = reinterpret_cast<int32_t *>(outbuf);\n  const float multiplier = 2147483648.0f;\n  const float max32 = 2147483647.0f; // 2147483648.0f in reality\n  const float min32 = -2147483648.0f;\n\n  const int c_loop = count & ~7;\n\n  for (int i = c_loop; i < count; i++) {\n    float val = in[i] * multiplier;\n    int32_t result;\n    if (val >= max32) result = 0x7FFFFFFF; // 2147483647\n    else if (val <= min32) result = 0x80000000; // -2147483648\n    else result = static_cast<int32_t>(val);\n    out[i] = result;\n  }\n\n  __m256 mulv = _mm256_set1_ps(multiplier);\n  __m256 maxv = _mm256_set1_ps(max32);\n  __m256 minv = _mm256_set1_ps(min32);\n  __m256i maxv_i = _mm256_set1_epi32(0x7FFFFFFF); // 2147483647\n  __m256i minv_i = _mm256_set1_epi32(0x80000000); // -2147483648\n  for (int i = 0; i < c_loop; i += 8) {\n    __m256 infl = _mm256_loadu_ps(in); in += 8;\n    __m256 outfl = _mm256_mul_ps(infl, mulv);\n    __m256i cmphigh = _mm256_castps_si256(_mm256_cmp_ps(outfl, maxv, _CMP_GE_OS));\n    __m256i cmplow = _mm256_castps_si256(_mm256_cmp_ps(minv, outfl, _CMP_GE_OS));\n    __m256i out32 = _mm256_cvttps_epi32(outfl);\n    out32 = _mm256_blendv_epi8(out32, maxv_i, cmphigh);\n    out32 = _mm256_blendv_epi8(out32, minv_i, cmplow);\n\n    _mm256_storeu_si256(reinterpret_cast<__m256i *>(out), out32); out += 8;\n  }\n}\n"
  },
  {
    "path": "avs_core/convert/intel/convert_audio_sse.cpp",
    "content": "// Avisynth+\n// https://avs-plus.net\n//\n// This file is part of Avisynth+ which is released under GPL2+ with exception.\n\n// Convert Audio helper functions (SSE2/SSSE3)\n// Copyright (c) 2020 Xinyue Lu, (c) 2021 pinterf\n\n#include <avs/types.h>\n#include <avs/config.h>\n\n// Intrinsics base header + really required extension headers\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n#include <smmintrin.h> // SSE4.1\n\n#if defined(GCC) || defined(CLANG)\n  #define SSE2 __attribute__((__target__(\"sse2\")))\n  #define SSSE3 __attribute__((__target__(\"ssse3\")))\n  #define SSE41 __attribute__((__target__(\"sse4.1\")))\n#else\n  #define SSE2\n  #define SSSE3\n  #define SSE41\n#endif\n\n// Easy: 32-16, 16-32, 32-8, 8-32, 16-8, 8-16\n// Hard: 32-24, 24-32, 24-16, 16-24, 24-8, 8-24\n// Float: 32-FLT, FLT-32\n\nSSE2 void convert32To16_SSE2(void *inbuf, void *outbuf, int count) {\n  auto in = reinterpret_cast<int32_t *>(inbuf);\n  auto in16 = reinterpret_cast<int16_t *>(inbuf);\n  auto out = reinterpret_cast<int16_t *>(outbuf);\n\n  const int c_loop = count & ~7;\n\n  for (int i = c_loop; i < count; i++)\n    out[i] = in16[i * 2 + 1];\n\n  for (int i = 0; i < c_loop; i += 8) {\n    __m128i in32a = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in)); in += 4;\n    __m128i in32b = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in)); in += 4;\n    __m128i in16a = _mm_srai_epi32(in32a, 16);\n    __m128i in16b = _mm_srai_epi32(in32b, 16);\n    __m128i out16 = _mm_packs_epi32(in16a, in16b);\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out), out16); out += 8;\n  }\n}\n\nSSE2 void convert16To32_SSE2(void *inbuf, void *outbuf, int count) {\n  auto in = reinterpret_cast<int16_t *>(inbuf);\n  auto out = reinterpret_cast<int32_t *>(outbuf);\n  auto out16 = reinterpret_cast<int16_t *>(outbuf);\n\n  const int c_loop = count & ~7;\n\n  for (int i = c_loop; i < count; i++) {\n    out16[i * 2] = 0;\n    out16[i * 2 + 1] = in[i];\n  }\n\n  __m128i zero = _mm_set1_epi16(0);\n  for (int i = 0; i < c_loop; i += 8) {\n    __m128i in16 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in)); in += 8;\n    __m128i out32a = _mm_unpacklo_epi16(zero, in16);\n    __m128i out32b = _mm_unpackhi_epi16(zero, in16);\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out), out32a); out += 4;\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out), out32b); out += 4;\n  }\n}\n\nSSE2 void convert32To8_SSE2(void *inbuf, void *outbuf, int count) {\n  auto in = reinterpret_cast<int32_t *>(inbuf);\n  auto in8 = reinterpret_cast<int8_t *>(inbuf);\n  auto out = reinterpret_cast<uint8_t *>(outbuf);\n\n  const int c_loop = count & ~15;\n\n  for (int i = c_loop; i < count; i++)\n    out[i] = in8[i * 4 + 3] + 128;\n\n  for (int i = 0; i < c_loop; i += 16) {\n    __m128i in32a = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in)); in += 4;\n    __m128i in32b = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in)); in += 4;\n    __m128i in32c = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in)); in += 4;\n    __m128i in32d = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in)); in += 4;\n\n    __m128i in8a = _mm_srai_epi32(in32a, 24);\n    __m128i in8b = _mm_srai_epi32(in32b, 24);\n    __m128i in8c = _mm_srai_epi32(in32c, 24);\n    __m128i in8d = _mm_srai_epi32(in32d, 24);\n\n    __m128i out8a = _mm_packs_epi32(in8a, in8b);\n    __m128i out8b = _mm_packs_epi32(in8c, in8d);\n\n    __m128i out8 = _mm_packs_epi16(out8a, out8b);\n\n    out8 = _mm_add_epi8(out8, _mm_set1_epi8(-128));\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out), out8); out += 16;\n  }\n}\n\nSSE2 void convert8To32_SSE2(void *inbuf, void *outbuf, int count) {\n  auto in = reinterpret_cast<uint8_t *>(inbuf);\n  auto out = reinterpret_cast<int32_t *>(outbuf);\n  auto out8 = reinterpret_cast<int8_t *>(outbuf);\n\n  const int c_loop = count & ~15;\n\n  for (int i = c_loop; i < count; i++) {\n    out8[i * 4] = 0;\n    out8[i * 4 + 1] = 0;\n    out8[i * 4 + 2] = 0;\n    out8[i * 4 + 3] = in[i] - 128;\n  }\n\n  __m128i n128 = _mm_set1_epi8(-128);\n  __m128i zero = _mm_set1_epi16(0);\n  for (int i = 0; i < c_loop; i += 16) {\n    __m128i in8 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in)); in += 16;\n    in8 = _mm_add_epi8(in8, n128);\n    __m128i v16a = _mm_unpacklo_epi8(zero, in8);\n    __m128i v16b = _mm_unpackhi_epi8(zero, in8);\n    __m128i out32a = _mm_unpacklo_epi16(zero, v16a);\n    __m128i out32b = _mm_unpackhi_epi16(zero, v16a);\n    __m128i out32c = _mm_unpacklo_epi16(zero, v16b);\n    __m128i out32d = _mm_unpackhi_epi16(zero, v16b);\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out), out32a); out += 4;\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out), out32b); out += 4;\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out), out32c); out += 4;\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out), out32d); out += 4;\n  }\n}\n\nSSE2 void convert16To8_SSE2(void *inbuf, void *outbuf, int count) {\n  auto in = reinterpret_cast<int16_t *>(inbuf);\n  auto in8 = reinterpret_cast<int8_t *>(inbuf);\n  auto out = reinterpret_cast<uint8_t *>(outbuf);\n\n  const int c_loop = count & ~15;\n\n  for (int i = c_loop; i < count; i++)\n    out[i] = in8[i * 2 + 1] + 128;\n\n  for (int i = 0; i < c_loop; i += 16) {\n    __m128i in16a = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in)); in += 8;\n    __m128i in16b = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in)); in += 8;\n    __m128i in8a = _mm_srai_epi16(in16a, 8);\n    __m128i in8b = _mm_srai_epi16(in16b, 8);\n    __m128i out8 = _mm_packs_epi16(in8a, in8b);\n    out8 = _mm_add_epi8(out8, _mm_set1_epi8(-128));\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out), out8); out += 16;\n  }\n}\n\nSSE2 void convert8To16_SSE2(void *inbuf, void *outbuf, int count) {\n  auto in = reinterpret_cast<uint8_t *>(inbuf);\n  auto out = reinterpret_cast<int16_t *>(outbuf);\n  auto out8 = reinterpret_cast<int8_t *>(outbuf);\n\n  const int c_loop = count & ~15;\n\n  for (int i = c_loop; i < count; i++) {\n    out8[i * 2] = 0;\n    out8[i * 2 + 1] = in[i] - 128;\n  }\n\n  __m128i n128 = _mm_set1_epi8(-128);\n  __m128i zero = _mm_set1_epi16(0);\n  for (int i = 0; i < c_loop; i += 16) {\n    __m128i in8 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in)); in += 16;\n    in8 = _mm_add_epi8(in8, n128);\n    __m128i out16a = _mm_unpacklo_epi8(zero, in8);\n    __m128i out16b = _mm_unpackhi_epi8(zero, in8);\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out), out16a); out += 8;\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out), out16b); out += 8;\n  }\n}\n\nSSSE3 void convert32To24_SSSE3(void *inbuf, void *outbuf, int count) {\n  auto in = reinterpret_cast<int32_t *>(inbuf);\n  auto in8 = reinterpret_cast<int8_t *>(inbuf);\n  auto out8 = reinterpret_cast<int8_t *>(outbuf);\n\n  const int c_loop = count & ~15;\n\n  for (int i = c_loop; i < count; i++) {\n    out8[i * 3 + 0] = in8[i * 4 + 1];\n    out8[i * 3 + 1] = in8[i * 4 + 2];\n    out8[i * 3 + 2] = in8[i * 4 + 3];\n  }\n\n  __m128i inv[4], outv[3], mask[6];\n  // clang-format off\n  mask[0] = _mm_set_epi8(\n    -1, -1, -1, -1,\n    15, 14, 13, 11,\n    10,  9,  7,  6,\n     5,  3,  2,  1);\n  mask[1] = _mm_set_epi8(\n     5,  3,  2,  1,\n    -1, -1, -1, -1,\n    -1, -1, -1, -1,\n    -1, -1, -1, -1);\n  mask[2] = _mm_set_epi8(\n    -1, -1, -1, -1,\n    -1, -1, -1, -1,\n    15, 14, 13, 11,\n    10,  9,  7,  6);\n  mask[3] = _mm_set_epi8(\n    10,  9,  7,  6,\n     5,  3,  2,  1,\n    -1, -1, -1, -1,\n    -1, -1, -1, -1);\n  mask[4] = _mm_set_epi8(\n    -1, -1, -1, -1,\n    -1, -1, -1, -1,\n    -1, -1, -1, -1,\n    15, 14, 13, 11);\n  mask[5] = _mm_set_epi8(\n    15, 14, 13, 11,\n    10,  9,  7,  6,\n     5,  3,  2,  1,\n    -1, -1, -1, -1);\n\n  for (int i = 0; i < c_loop; i += 16) {\n    inv[0] = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in)); in += 4;\n    inv[1] = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in)); in += 4;\n    inv[2] = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in)); in += 4;\n    inv[3] = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in)); in += 4;\n\n    outv[0] = _mm_or_si128(\n      _mm_shuffle_epi8(inv[0], mask[0]),\n      _mm_shuffle_epi8(inv[1], mask[1])\n    );\n    outv[1] = _mm_or_si128(\n      _mm_shuffle_epi8(inv[1], mask[2]),\n      _mm_shuffle_epi8(inv[2], mask[3])\n    );\n    outv[2] = _mm_or_si128(\n      _mm_shuffle_epi8(inv[2], mask[4]),\n      _mm_shuffle_epi8(inv[3], mask[5])\n    );\n\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out8), outv[0]); out8 += 16;\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out8), outv[1]); out8 += 16;\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out8), outv[2]); out8 += 16;\n  }\n  // clang-format on\n}\n\nSSSE3 void convert24To32_SSSE3(void *inbuf, void *outbuf, int count) {\n  auto in8 = reinterpret_cast<int8_t *>(inbuf);\n  auto out8 = reinterpret_cast<int8_t *>(outbuf);\n  auto out = reinterpret_cast<int32_t *>(outbuf);\n\n  const int c_loop = count & ~15;\n\n  for (int i = c_loop; i < count; i++) {\n    out8[i * 4] = 0;\n    out8[i * 4 + 1] = in8[i * 3 + 0];\n    out8[i * 4 + 2] = in8[i * 3 + 1];\n    out8[i * 4 + 3] = in8[i * 3 + 2];\n  }\n\n  __m128i inv[3], outv[4], mask[6];\n  // clang-format off\n  mask[0] = _mm_set_epi8(\n    11, 10,  9, -1,\n     8,  7,  6, -1,\n     5,  4,  3, -1,\n     2,  1,  0, -1);\n  mask[1] = _mm_set_epi8(\n    -1, -1, -1, -1,\n    -1, -1, -1, -1,\n    -1, -1, 15, -1,\n    14, 13, 12, -1);\n  mask[2] = _mm_set_epi8(\n     7,  6,  5, -1,\n     4,  3,  2, -1,\n     1,  0, -1, -1,\n    -1, -1, -1, -1);\n  mask[3] = _mm_set_epi8(\n    -1, -1, -1, -1,\n    -1, 15, 14, -1,\n    13, 12, 11, -1,\n    10,  9,  8, -1);\n  mask[4] = _mm_set_epi8(\n     3,  2,  1, -1,\n     0, -1, -1, -1,\n    -1, -1, -1, -1,\n    -1, -1, -1, -1);\n  mask[5] = _mm_set_epi8(\n    15, 14, 13, -1,\n    12, 11, 10, -1,\n     9,  8,  7, -1,\n     6,  5,  4, -1);\n\n  for (int i = 0; i < c_loop; i += 16) {\n    inv[0] = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in8)); in8 += 16;\n    inv[1] = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in8)); in8 += 16;\n    inv[2] = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in8)); in8 += 16;\n\n    outv[0] = _mm_shuffle_epi8(inv[0], mask[0]);\n    outv[1] = _mm_or_si128(\n      _mm_shuffle_epi8(inv[0], mask[1]),\n      _mm_shuffle_epi8(inv[1], mask[2])\n    );\n    outv[2] = _mm_or_si128(\n      _mm_shuffle_epi8(inv[1], mask[3]),\n      _mm_shuffle_epi8(inv[2], mask[4])\n    );\n    outv[3] = _mm_shuffle_epi8(inv[2], mask[5]);\n\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out), outv[0]); out += 4;\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out), outv[1]); out += 4;\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out), outv[2]); out += 4;\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out), outv[3]); out += 4;\n  }\n  // clang-format on\n}\n\nSSSE3 void convert24To16_SSSE3(void *inbuf, void *outbuf, int count) {\n  auto in8 = reinterpret_cast<int8_t *>(inbuf);\n  auto out8 = reinterpret_cast<int8_t *>(outbuf);\n  auto out = reinterpret_cast<int16_t *>(outbuf);\n\n  const int c_loop = count & ~15;\n\n  for (int i = c_loop; i < count; i++) {\n    out8[i * 2 + 0] = in8[i * 3 + 1];\n    out8[i * 2 + 1] = in8[i * 3 + 2];\n  }\n\n  __m128i inv[3], outv[2], mask[4];\n  // clang-format off\n  mask[0] = _mm_set_epi8(\n    -1, -1, -1, -1,\n    -1, -1, 14, 13,\n    11, 10,  8,  7,\n     5,  4,  2,  1);\n  mask[1] = _mm_set_epi8(\n     7,  6,  4,  3,\n     1,  0, -1, -1,\n    -1, -1, -1, -1,\n    -1, -1, -1, -1);\n  mask[2] = _mm_set_epi8(\n    -1, -1, -1, -1,\n    -1, -1, -1, -1,\n    -1, -1, -1, 15,\n    13, 12, 10,  9);\n  mask[3] = _mm_set_epi8(\n    15, 14, 12, 11,\n     9,  8,  6,  5,\n     3,  2,  0, -1,\n    -1, -1, -1, -1);\n\n  for (int i = 0; i < c_loop; i += 16) {\n    inv[0] = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in8)); in8 += 16;\n    inv[1] = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in8)); in8 += 16;\n    inv[2] = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in8)); in8 += 16;\n\n    outv[0] = _mm_or_si128(\n      _mm_shuffle_epi8(inv[0], mask[0]),\n      _mm_shuffle_epi8(inv[1], mask[1])\n    );\n    outv[1] = _mm_or_si128(\n      _mm_shuffle_epi8(inv[1], mask[2]),\n      _mm_shuffle_epi8(inv[2], mask[3])\n    );\n\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out), outv[0]); out += 8;\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out), outv[1]); out += 8;\n  }\n  // clang-format on\n}\n\nSSSE3 void convert16To24_SSSE3(void *inbuf, void *outbuf, int count) {\n  auto in = reinterpret_cast<int16_t *>(inbuf);\n  auto in8 = reinterpret_cast<int8_t *>(inbuf);\n  auto out8 = reinterpret_cast<int8_t *>(outbuf);\n\n  const int c_loop = count & ~15;\n\n  for (int i = c_loop; i < count; i++) {\n    out8[i * 3] = 0;\n    out8[i * 3 + 1] = in8[i * 2 + 0];\n    out8[i * 3 + 2] = in8[i * 2 + 1];\n  }\n\n  __m128i inv[2], outv[3], mask[4];\n  // clang-format off\n  mask[0] = _mm_set_epi8(\n    -1,  9,  8, -1,\n     7,  6, -1,  5,\n     4, -1,  3,  2,\n    -1,  1,  0, -1);\n  mask[1] = _mm_set_epi8(\n    -1, -1, -1, -1,\n    -1, -1, -1, -1,\n    15, 14, -1, 13,\n    12, -1, 11, 10);\n  mask[2] = _mm_set_epi8(\n     4, -1,  3,  2,\n    -1,  1,  0, -1,\n    -1, -1, -1, -1,\n    -1, -1, -1, -1);\n  mask[3] = _mm_set_epi8(\n    15, 14, -1, 13,\n    12, -1, 11, 10,\n    -1,  9,  8, -1,\n     7,  6, -1,  5);\n\n  for (int i = 0; i < c_loop; i += 16) {\n    inv[0] = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in)); in += 8;\n    inv[1] = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in)); in += 8;\n\n    outv[0] = _mm_shuffle_epi8(inv[0], mask[0]);\n    outv[1] = _mm_or_si128(\n      _mm_shuffle_epi8(inv[0], mask[1]),\n      _mm_shuffle_epi8(inv[1], mask[2])\n    );\n    outv[2] = _mm_shuffle_epi8(inv[1], mask[3]);\n\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out8), outv[0]); out8 += 16;\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out8), outv[1]); out8 += 16;\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out8), outv[2]); out8 += 16;\n  }\n  // clang-format on\n}\n\nSSSE3 void convert24To8_SSSE3(void *inbuf, void *outbuf, int count) {\n  auto in8 = reinterpret_cast<int8_t *>(inbuf);\n  auto out = reinterpret_cast<uint8_t *>(outbuf);\n\n  const int c_loop = count & ~15;\n\n  for (int i = c_loop; i < count; i++)\n    out[i] = in8[i * 3 + 2] + 128;\n\n  __m128i inv[3], outv, mask[3];\n  __m128i n128 = _mm_set1_epi8(-128);\n  // clang-format off\n  mask[0] = _mm_set_epi8(\n    -1, -1, -1, -1,\n    -1, -1, -1, -1,\n    -1, -1, -1, 14,\n    11,  8,  5,  2);\n  mask[1] = _mm_set_epi8(\n    -1, -1, -1, -1,\n    -1, -1, 13, 10,\n     7,  4,  1, -1,\n    -1, -1, -1, -1);\n  mask[2] = _mm_set_epi8(\n    15, 12,  9,  6,\n     3,  0, -1, -1,\n    -1, -1, -1, -1,\n    -1, -1, -1, -1);\n\n  for (int i = 0; i < c_loop; i += 16) {\n    inv[0] = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in8)); in8 += 16;\n    inv[1] = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in8)); in8 += 16;\n    inv[2] = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in8)); in8 += 16;\n\n    outv = _mm_or_si128(\n      _mm_shuffle_epi8(inv[0], mask[0]),\n      _mm_shuffle_epi8(inv[1], mask[1])\n    );\n    outv = _mm_or_si128(\n      outv,\n      _mm_shuffle_epi8(inv[2], mask[2])\n    );\n    outv = _mm_add_epi8(outv, n128);\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out), outv); out += 16;\n  }\n  // clang-format on\n}\n\nSSSE3 void convert8To24_SSSE3(void *inbuf, void *outbuf, int count) {\n  auto in = reinterpret_cast<uint8_t *>(inbuf);\n  auto out8 = reinterpret_cast<int8_t *>(outbuf);\n\n  const int c_loop = count & ~15;\n\n  for (int i = c_loop; i < count; i++) {\n    out8[i * 3] = 0;\n    out8[i * 3 + 1] = 0;\n    out8[i * 3 + 2] = in[i] - 128;\n  }\n\n  __m128i inv, outv[3], mask[3];\n  __m128i n128 = _mm_set1_epi8(-128);\n  // clang-format off\n  mask[0] = _mm_set_epi8(\n    -1,  4, -1, -1,\n     3, -1, -1,  2,\n    -1, -1,  1, -1,\n    -1,  0, -1, -1);\n  mask[1] = _mm_set_epi8(\n    -1, -1,  9, -1,\n    -1,  8, -1, -1,\n     7, -1, -1,  6,\n    -1, -1,  5, -1);\n  mask[2] = _mm_set_epi8(\n    15, -1, -1, 14,\n    -1, -1, 13, -1,\n    -1, 12, -1, -1,\n    11, -1, -1, 10);\n\n  for (int i = 0; i < c_loop; i += 16) {\n    inv = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in)); in += 16;\n    inv = _mm_add_epi8(inv, n128);\n\n    outv[0] = _mm_shuffle_epi8(inv, mask[0]);\n    outv[1] = _mm_shuffle_epi8(inv, mask[1]);\n    outv[2] = _mm_shuffle_epi8(inv, mask[2]);\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out8), outv[0]); out8 += 16;\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out8), outv[1]); out8 += 16;\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out8), outv[2]); out8 += 16;\n  }\n  // clang-format on\n}\n\nSSE41 void convert8ToFLT_SSE41(void* inbuf, void* outbuf, int count) {\n  auto in = reinterpret_cast<uint8_t*>(inbuf);\n  auto out = reinterpret_cast<SFLOAT*>(outbuf);\n  constexpr float divisor = 1.0f / 128.f; // 1 << 7\n\n  const int c_loop = count & ~3;\n\n  for (int i = c_loop; i < count; i++)\n    out[i] = (in[i] - 128) * divisor;\n\n  __m128 divv = _mm_set1_ps(divisor);\n  for (int i = 0; i < c_loop; i += 4) {\n    __m128i in32 = _mm_cvtepu8_epi32(_mm_castps_si128(_mm_load_ss(reinterpret_cast<float *>(in)))); in += 4;\n    in32 = _mm_sub_epi32(in32, _mm_set1_epi32(128));\n    __m128 infl = _mm_cvtepi32_ps(in32);\n    __m128 outfl = _mm_mul_ps(infl, divv);\n    _mm_storeu_ps(out, outfl); out += 4;\n  }\n}\n\nSSE2 void convertFLTTo8_SSE2(void* inbuf, void* outbuf, int count) {\n  auto in = reinterpret_cast<SFLOAT*>(inbuf);\n  auto out = reinterpret_cast<uint8_t*>(outbuf);\n  constexpr float multiplier = 128.f;\n  constexpr float max8 = 127.f;\n  constexpr float min8 = -128.f;\n\n  const int c_loop = count & ~3;\n\n  for (int i = c_loop; i < count; i++) {\n    float val = in[i] * multiplier;\n    uint8_t result;\n    if (val >= max8) result = 255;\n    else if (val <= min8) result = 0;\n    else result = static_cast<int8_t>(val) + 128;\n    out[i] = result;\n  }\n\n  __m128 mulv = _mm_set1_ps(multiplier);\n  __m128 maxv = _mm_set1_ps(max8);\n  __m128 minv = _mm_set1_ps(min8);\n  for (int i = 0; i < c_loop; i += 4) {\n    __m128 infl = _mm_loadu_ps(in); in += 4;\n    __m128 outfl = _mm_max_ps(minv, _mm_min_ps(maxv,_mm_mul_ps(infl, mulv)));\n    __m128i out32 = _mm_cvttps_epi32(outfl);\n    __m128i out16 = _mm_packs_epi32(out32, out32);\n    __m128i out8 = _mm_packs_epi16(out16, out16);\n    out8 = _mm_add_epi8(out8, _mm_set1_epi8(-128)); // 128\n    *(uint32_t *)(out) = _mm_cvtsi128_si32(out8); out += 4;\n  }\n}\n\nSSE41 void convert16ToFLT_SSE41(void* inbuf, void* outbuf, int count) {\n  auto in = reinterpret_cast<int16_t*>(inbuf);\n  auto out = reinterpret_cast<SFLOAT*>(outbuf);\n  constexpr float divisor = 1.0f / 32768.f; // 1 << 15\n\n  const int c_loop = count & ~3;\n\n  for (int i = c_loop; i < count; i++)\n    out[i] = in[i] * divisor;\n\n  __m128 divv = _mm_set1_ps(divisor);\n  for (int i = 0; i < c_loop; i += 4) {\n    __m128i in32 = _mm_cvtepi16_epi32(_mm_loadl_epi64(reinterpret_cast<const __m128i*>(in))); in += 4;\n    __m128 infl = _mm_cvtepi32_ps(in32);\n    __m128 outfl = _mm_mul_ps(infl, divv);\n    _mm_storeu_ps(out, outfl); out += 4;\n  }\n}\n\nSSE2 void convertFLTTo16_SSE2(void* inbuf, void* outbuf, int count) {\n  auto in = reinterpret_cast<SFLOAT*>(inbuf);\n  auto out = reinterpret_cast<int16_t*>(outbuf);\n  constexpr float multiplier = 32768.f;\n  constexpr float max16 = 32767.f;\n  constexpr float min16 = -32768.f;\n\n  const int c_loop = count & ~3;\n\n  for (int i = c_loop; i < count; i++) {\n    float val = in[i] * multiplier;\n    int16_t result;\n    if (val >= max16) result = 32767;\n    else if (val <= min16) result = (int16_t)-32768;\n    else result = static_cast<int16_t>(val);\n    out[i] = result;\n  }\n\n  __m128 mulv = _mm_set1_ps(multiplier);\n  __m128 maxv = _mm_set1_ps(max16);\n  __m128 minv = _mm_set1_ps(min16);\n  for (int i = 0; i < c_loop; i += 4) {\n    __m128 infl = _mm_loadu_ps(in); in += 4;\n    __m128 outfl = _mm_max_ps(minv, _mm_min_ps(maxv, _mm_mul_ps(infl, mulv)));\n    __m128i out32 = _mm_cvttps_epi32(outfl);\n    __m128i out16 = _mm_packs_epi32(out32, out32);\n    _mm_storel_epi64(reinterpret_cast<__m128i*>(out), out16); out += 4;\n  }\n}\n\nSSE2 void convert32ToFLT_SSE2(void *inbuf, void *outbuf, int count) {\n  auto in = reinterpret_cast<int32_t *>(inbuf);\n  auto out = reinterpret_cast<SFLOAT *>(outbuf);\n  const float divisor = 1.0f/2147483648.0f;\n\n  const int c_loop = count & ~3;\n\n  for (int i = c_loop; i < count; i++)\n    out[i] = in[i] * divisor;\n\n  __m128 divv = _mm_set1_ps(divisor);\n  for (int i = 0; i < c_loop; i += 4) {\n    __m128i in32 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(in)); in += 4;\n    __m128 infl = _mm_cvtepi32_ps(in32);\n    __m128 outfl = _mm_mul_ps(infl, divv);\n    _mm_storeu_ps(out, outfl); out += 4;\n  }\n}\n\nSSE41 void convertFLTTo32_SSE41(void *inbuf, void *outbuf, int count) {\n  auto in = reinterpret_cast<SFLOAT *>(inbuf);\n  auto out = reinterpret_cast<int32_t *>(outbuf);\n  constexpr float multiplier = 2147483648.0f;\n  constexpr float max32 = 2147483647.0f; // 2147483648.0f in reality\n  constexpr float min32 = -2147483648.0f;\n\n  const int c_loop = count & ~3;\n\n  for (int i = c_loop; i < count; i++) {\n    float val = in[i] * multiplier;\n    int32_t result;\n    if (val >= max32) result = 0x7FFFFFFF; // 2147483647\n    else if (val <= min32) result = 0x80000000; // -2147483648\n    else result = static_cast<int32_t>(val);\n    out[i] = result;\n  }\n\n  __m128 mulv = _mm_set1_ps(multiplier);\n  __m128 maxv = _mm_set1_ps(max32);\n  __m128 minv = _mm_set1_ps(min32);\n  __m128i maxv_i = _mm_set1_epi32(0x7FFFFFFF); // 2147483647\n  __m128i minv_i = _mm_set1_epi32(0x80000000); // -2147483648\n  for (int i = 0; i < c_loop; i += 4) {\n    __m128 infl = _mm_loadu_ps(in); in += 4;\n    __m128 outfl = _mm_mul_ps(infl, mulv);\n    __m128i cmphigh = _mm_castps_si128(_mm_cmpge_ps(outfl, maxv));\n    __m128i cmplow = _mm_castps_si128(_mm_cmpge_ps(minv, outfl));\n    __m128i out32 = _mm_cvttps_epi32(outfl);\n    out32 = _mm_blendv_epi8(out32, maxv_i, cmphigh);\n    out32 = _mm_blendv_epi8(out32, minv_i, cmplow);\n    _mm_storeu_si128(reinterpret_cast<__m128i *>(out), out32); out += 4;\n  }\n}\n"
  },
  {
    "path": "avs_core/convert/intel/convert_bits_avx2.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002-2009 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include <avs/alignment.h>\n#include <avs/minmax.h>\n\n#ifdef _MSC_VER\n    #include <intrin.h>\n#else\n    #include <x86intrin.h>\n#endif\n#include <immintrin.h>\n\n#ifndef _mm256_set_m128i\n#define _mm256_set_m128i(v0, v1) _mm256_insertf128_si256(_mm256_castsi128_si256(v1), (v0), 1)\n#endif\n\n#ifndef _mm256_set_m128\n#define _mm256_set_m128(v0, v1) _mm256_insertf128_ps(_mm256_castps128_ps256(v1), (v0), 1)\n#endif\n\n#include \"convert_bits_avx2.h\"\n#include \"../convert_bits.h\"\n#include \"../convert_helper.h\"\n\n#ifdef _MSC_VER\n#pragma warning(push)\n#pragma warning(disable: 4305)\n#endif\n\ntemplate<typename pixel_t, bool chroma, bool fulls, bool fulld>\nvoid convert_32_to_uintN_avx2(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth)\n{\n  const float* srcp0 = reinterpret_cast<const float*>(srcp);\n  pixel_t* dstp0 = reinterpret_cast<pixel_t*>(dstp);\n\n  src_pitch = src_pitch / sizeof(float);\n  dst_pitch = dst_pitch / sizeof(pixel_t);\n\n  const int src_width = src_rowsize / sizeof(float);\n\n  //-----------------------\n  bits_conv_constants d;\n  get_bits_conv_constants(d, chroma, fulls, fulld, source_bitdepth, target_bitdepth);\n\n  auto dst_offset_plus_round = d.dst_offset + 0.5f;\n  constexpr auto dst_pixel_min = 0;\n  const auto dst_pixel_max = (1 << target_bitdepth) - 1;\n\n  auto src_offset_ps = _mm256_set1_ps(d.src_offset);\n  auto factor_ps = _mm256_set1_ps(d.mul_factor);\n  auto dst_offset_plus_round_ps = _mm256_set1_ps(dst_offset_plus_round);\n  auto dst_pixel_min_ps = _mm256_set1_ps((float)dst_pixel_min);\n  auto dst_pixel_max_ps = _mm256_set1_ps((float)dst_pixel_max);\n\n  for (int y = 0; y < src_height; y++)\n  {\n    for (int x = 0; x < src_width; x += 16) // 16 pixels at a time (64 byte - alignment is OK)\n    {\n      __m256i result;\n      __m256i result_0, result_1;\n      __m256 src_0 = _mm256_load_ps(reinterpret_cast<const float*>(srcp0 + x));\n      __m256 src_1 = _mm256_load_ps(reinterpret_cast<const float*>(srcp0 + x + 8));\n      if constexpr (!chroma && !fulls) {\n        // when offset is different from 0\n        src_0 = _mm256_sub_ps(src_0, src_offset_ps);\n        src_1 = _mm256_sub_ps(src_1, src_offset_ps);\n      }\n\n      src_0 = _mm256_fmadd_ps(src_0, factor_ps, dst_offset_plus_round_ps);\n      src_1 = _mm256_fmadd_ps(src_1, factor_ps, dst_offset_plus_round_ps);\n\n      src_0 = _mm256_max_ps(_mm256_min_ps(src_0, dst_pixel_max_ps), dst_pixel_min_ps);\n      src_1 = _mm256_max_ps(_mm256_min_ps(src_1, dst_pixel_max_ps), dst_pixel_min_ps);\n      result_0 = _mm256_cvttps_epi32(src_0); // truncate\n      result_1 = _mm256_cvttps_epi32(src_1);\n      if constexpr (sizeof(pixel_t) == 2) {\n        result = _mm256_packus_epi32(result_0, result_1);\n        result = _mm256_permute4x64_epi64(result, (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6));\n        _mm256_store_si256(reinterpret_cast<__m256i*>(dstp0 + x), result);\n      }\n      else {\n        result = _mm256_packs_epi32(result_0, result_1);\n        result = _mm256_permute4x64_epi64(result, (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6));\n        __m128i result128_lo = _mm256_castsi256_si128(result);\n        __m128i result128_hi = _mm256_extractf128_si256(result, 1);\n        __m128i result128 = _mm_packus_epi16(result128_lo, result128_hi);\n        _mm_store_si128(reinterpret_cast<__m128i*>(dstp0 + x), result128);\n      }\n\n      // c: \n      //const int pixel = (int)((srcp0[x] - src_offset) * mul_factor + dst_offset_plus_round);\n      //dstp0[x] = pixel_t(clamp(pixel, dst_pixel_min, dst_pixel_max));\n    }\n    dstp0 += dst_pitch;\n    srcp0 += src_pitch;\n  }\n}\n\n#ifdef _MSC_VER\n#pragma warning(pop)\n#endif\n\n#define convert_32_to_uintN_avx2_functions(type) \\\ntemplate void convert_32_to_uintN_avx2<type, false, true, true>(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_32_to_uintN_avx2<type, true, true, true>(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_32_to_uintN_avx2<type, false, true, false>(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_32_to_uintN_avx2<type, true, true, false>(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_32_to_uintN_avx2<type, false, false, true>(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_32_to_uintN_avx2<type, true, false, true>(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_32_to_uintN_avx2<type, false, false, false>(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_32_to_uintN_avx2<type, true, false, false>(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\n\nconvert_32_to_uintN_avx2_functions(uint8_t)\nconvert_32_to_uintN_avx2_functions(uint16_t)\n\n#undef convert_32_to_uintN_avx2_functions\n\n/*\n3.7.1 test26: stop using manual _mm256_zeroupper()\nThis warning is left in Avisynth at one single place.\n1.) compilers do it automatically\n2.) clang is getting mad and produces suboptimal prologue and epilogue, saving and loading all xmm registers!\n** Good (no manual zeroupper) **\n  push\trsi\n  .seh_pushreg rsi\n  push\trdi\n  .seh_pushreg rdi\n  .seh_endprologue \n[...]\n  pop\trdi\n  pop\trsi\n  vzeroupper\n  ret\n\n** Bad, manual _mm256_zeroupper() **\n\n  vmovaps\txmmword ptr [rsp + 144], xmm15  # 16-byte Spill\n  .seh_savexmm xmm15, 144\n  vmovaps\txmmword ptr [rsp + 128], xmm14  # 16-byte Spill\n  .seh_savexmm xmm14, 128\n  vmovaps\txmmword ptr [rsp + 112], xmm13  # 16-byte Spill\n  .seh_savexmm xmm13, 112\n  vmovaps\txmmword ptr [rsp + 96], xmm12   # 16-byte Spill\n  .seh_savexmm xmm12, 96\n  vmovaps\txmmword ptr [rsp + 80], xmm11   # 16-byte Spill\n  .seh_savexmm xmm11, 80\n  vmovaps\txmmword ptr [rsp + 64], xmm10   # 16-byte Spill\n  .seh_savexmm xmm10, 64\n  vmovaps\txmmword ptr [rsp + 48], xmm9    # 16-byte Spill\n  .seh_savexmm xmm9, 48\n  vmovaps\txmmword ptr [rsp + 32], xmm8    # 16-byte Spill\n  .seh_savexmm xmm8, 32\n  vmovaps\txmmword ptr [rsp + 16], xmm7    # 16-byte Spill\n  .seh_savexmm xmm7, 16\n  vmovaps\txmmword ptr [rsp], xmm6         # 16-byte Spill\n  .seh_savexmm xmm6, 0\n  .seh_endprologue \n[...]\n  pop\trdi\n  pop\trsi\n  vzeroupper\n  vmovaps\txmm6, xmmword ptr [rsp]         # 16-byte Reload\n  vmovaps\txmm7, xmmword ptr [rsp + 16]    # 16-byte Reload\n  vmovaps\txmm8, xmmword ptr [rsp + 32]    # 16-byte Reload\n  vmovaps\txmm9, xmmword ptr [rsp + 48]    # 16-byte Reload\n  vmovaps\txmm10, xmmword ptr [rsp + 64]   # 16-byte Reload\n  vmovaps\txmm11, xmmword ptr [rsp + 80]   # 16-byte Reload\n  vmovaps\txmm12, xmmword ptr [rsp + 96]   # 16-byte Reload\n  vmovaps\txmm13, xmmword ptr [rsp + 112]  # 16-byte Reload\n  vmovaps\txmm14, xmmword ptr [rsp + 128]  # 16-byte Reload\n  vmovaps\txmm15, xmmword ptr [rsp + 144]  # 16-byte Reload\n  ret\n*/\n\n// YUV: bit shift 8-16 <=> 8-16 bits\n// shift right or left, depending on expandrange\ntemplate<typename pixel_t_s, typename pixel_t_d>\nstatic void convert_uint_limited_avx2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth)\n{\n  const pixel_t_s* srcp0 = reinterpret_cast<const pixel_t_s*>(srcp);\n  pixel_t_d* dstp0 = reinterpret_cast<pixel_t_d*>(dstp);\n\n  src_pitch = src_pitch / sizeof(pixel_t_s);\n  dst_pitch = dst_pitch / sizeof(pixel_t_d);\n\n  const int src_width = src_rowsize / sizeof(pixel_t_s);\n\n  if (target_bitdepth > source_bitdepth) // expandrange. pixel_t_d is always uint16_t\n  {\n    const int shift_bits = target_bitdepth - source_bitdepth;\n    __m128i shift = _mm_set_epi32(0, 0, 0, shift_bits);\n    for (int y = 0; y < src_height; y++)\n    {\n      for (int x = 0; x < src_width; x += 32)\n      {\n        __m256i src_lo, src_hi;\n        if constexpr (sizeof(pixel_t_s) == 1) {\n          auto src_lo_128 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp0 + x)); // 16* uint8\n          auto src_hi_128 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp0 + x + 16)); // 16* uint8\n          src_lo = _mm256_cvtepu8_epi16(src_lo_128); // 16* uint16\n          src_hi = _mm256_cvtepu8_epi16(src_hi_128); // 16* uint16\n        }\n        else {\n          // 64 bytes per cycle. Ok in avs+\n          src_lo = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp0 + x)); // 16* uint_16\n          src_hi = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp0 + x + 16)); // 16* uint_16\n        }\n        src_lo = _mm256_sll_epi16(src_lo, shift);\n        src_hi = _mm256_sll_epi16(src_hi, shift);\n        if constexpr (sizeof(pixel_t_d) == 1) {\n          // upconvert always to 2 bytes\n          assert(0);\n        }\n        else {\n          _mm256_store_si256(reinterpret_cast<__m256i*>(dstp0 + x), src_lo);\n          _mm256_store_si256(reinterpret_cast<__m256i*>(dstp0 + x + 16), src_hi);\n        }\n      }\n      dstp0 += dst_pitch;\n      srcp0 += src_pitch;\n    }\n  }\n  else\n  {\n    // reduce range\n    const int shift_bits = source_bitdepth - target_bitdepth;\n    const int round = 1 << (shift_bits - 1);\n    __m128i shift = _mm_set_epi32(0, 0, 0, shift_bits);\n    const auto round_simd = _mm256_set1_epi16(round);\n\n    for (int y = 0; y < src_height; y++)\n    {\n      for (int x = 0; x < src_width; x += 32)\n      {\n        if constexpr (sizeof(pixel_t_s) == 1)\n          assert(0);\n        // downconvert always from 2 bytes\n        // 64 bytes per cycle. Ok in avs+\n        auto src_lo = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp0 + x)); // 16* uint_16\n        auto src_hi = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp0 + x + 16)); // 16* uint_16\n        src_lo = _mm256_srl_epi16(_mm256_adds_epu16(src_lo, round_simd), shift);\n        src_hi = _mm256_srl_epi16(_mm256_adds_epu16(src_hi, round_simd), shift);\n        if constexpr (sizeof(pixel_t_d) == 1) {\n          // to 8 bits\n          auto dst = _mm256_packus_epi16(src_lo, src_hi);\n          dst = _mm256_permute4x64_epi64(dst, (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6));\n          _mm256_store_si256(reinterpret_cast<__m256i*>(dstp0 + x), dst);\n        }\n        else {\n          _mm256_store_si256(reinterpret_cast<__m256i*>(dstp0 + x), src_lo);\n          _mm256_store_si256(reinterpret_cast<__m256i*>(dstp0 + x + 16), src_hi);\n        }\n      }\n      dstp0 += dst_pitch;\n      srcp0 += src_pitch;\n    }\n  }\n}\n\ntemplate<typename pixel_t_s, typename pixel_t_d, bool chroma, bool fulls, bool fulld>\nvoid convert_uint_avx2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth)\n{\n  // limited to limited is bitshift, see in other function\n  if constexpr (!fulls && !fulld) {\n    convert_uint_limited_avx2<pixel_t_s, pixel_t_d>(srcp, dstp, src_rowsize, src_height, src_pitch, dst_pitch, source_bitdepth, target_bitdepth, dither_target_bitdepth);\n    return;\n  }\n\n  const pixel_t_s* srcp0 = reinterpret_cast<const pixel_t_s*>(srcp);\n  pixel_t_d* dstp0 = reinterpret_cast<pixel_t_d*>(dstp);\n\n  src_pitch = src_pitch / sizeof(pixel_t_s);\n  dst_pitch = dst_pitch / sizeof(pixel_t_d);\n\n  const int src_width = src_rowsize / sizeof(pixel_t_s);\n  const int wmod32 = (src_width / 32) * 32;\n\n  if constexpr (sizeof(pixel_t_s) == 1 && sizeof(pixel_t_d) == 2) {\n    if (fulls && fulld && !chroma && source_bitdepth == 8 && target_bitdepth == 16) {\n      // special case 8->16 bit full scale: * 65535 / 255 = *257\n      __m256i multiplier = _mm256_set1_epi16(257);\n\n      for (int y = 0; y < src_height; y++)\n      {\n        for (int x = 0; x < src_width; x += 32)\n        {\n          auto src_lo_128 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp0 + x)); // 16* uint8\n          auto src_hi_128 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp0 + x + 16)); // 16* uint8\n          auto src_lo = _mm256_cvtepu8_epi16(src_lo_128); // 16* uint16\n          auto src_hi = _mm256_cvtepu8_epi16(src_hi_128); // 16* uint16\n\n            // *257 mullo is faster than x*257 = (x<<8 + x) add/or solution (i7)\n          auto res_lo = _mm256_mullo_epi16(src_lo, multiplier); // lower 16 bit of multiplication is enough\n          auto res_hi = _mm256_mullo_epi16(src_hi, multiplier);\n          // dstp[x] = srcp0[x] * 257; // RGB: full range 0..255 <-> 0..65535 (257 = 65535 / 255)\n          _mm256_store_si256(reinterpret_cast<__m256i*>(dstp0 + x), res_lo);\n          _mm256_store_si256(reinterpret_cast<__m256i*>(dstp0 + x + 16), res_hi);\n        } // for x\n        // rest\n        for (int x = wmod32; x < src_width; x++)\n        {\n          dstp0[x] = (pixel_t_d)(srcp0[x] * 257);\n        }\n        dstp0 += dst_pitch;\n        srcp0 += src_pitch;\n      } // for y\n      return;\n    }\n  }\n\n  const int target_max = (1 << target_bitdepth) - 1;\n\n  bits_conv_constants d;\n  get_bits_conv_constants(d, chroma, fulls, fulld, source_bitdepth, target_bitdepth);\n\n  auto vect_mul_factor = _mm256_set1_ps(d.mul_factor);\n  auto vect_src_offset = _mm256_set1_epi32(d.src_offset_i);\n  auto dst_offset_plus_round = d.dst_offset + 0.5f;\n  auto vect_dst_offset_plus_round = _mm256_set1_ps(dst_offset_plus_round);\n\n  auto vect_target_max = _mm256_set1_epi16(target_max);\n\n  auto zero = _mm256_setzero_si256();\n\n  for (int y = 0; y < src_height; y++)\n  {\n    for (int x = 0; x < src_width; x += 32)\n    {\n      __m256i src_lo, src_hi;\n      if constexpr (sizeof(pixel_t_s) == 1) {\n        auto src_lo_128 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp0 + x)); // 16* uint8\n        auto src_hi_128 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp0 + x + 16)); // 16* uint8\n        src_lo = _mm256_cvtepu8_epi16(src_lo_128); // 16* uint16\n        src_hi = _mm256_cvtepu8_epi16(src_hi_128); // 16* uint16\n      }\n      else {\n        // 64 bytes per cycle. Ok in avs+\n        src_lo = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp0 + x)); // 8* uint_16\n        src_hi = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp0 + x + 16)); // 8* uint_16\n      }\n\n      __m256i result1, result2;\n      {\n        // src: 8*uint16\n        // convert to int32, bias, to float\n        auto res_lo_i = _mm256_unpacklo_epi16(src_lo, zero);\n        auto res_hi_i = _mm256_unpackhi_epi16(src_lo, zero);\n        if constexpr (chroma || !fulls) {\n          // src_offset is not zero\n          res_lo_i = _mm256_sub_epi32(res_lo_i, vect_src_offset);\n          res_hi_i = _mm256_sub_epi32(res_hi_i, vect_src_offset);\n        }\n        auto res_lo = _mm256_cvtepi32_ps(res_lo_i);\n        auto res_hi = _mm256_cvtepi32_ps(res_hi_i);\n        // multiply, bias back+round\n        // avx2 mode: smart fma instruction inserted even from msvc!\n        res_lo = _mm256_add_ps(_mm256_mul_ps(res_lo, vect_mul_factor), vect_dst_offset_plus_round);\n        res_hi = _mm256_add_ps(_mm256_mul_ps(res_hi, vect_mul_factor), vect_dst_offset_plus_round);\n        // convert back w/ truncate\n        auto result_l = _mm256_cvttps_epi32(res_lo); // no banker's rounding\n        auto result_h = _mm256_cvttps_epi32(res_hi);\n        // 0 min is ensured by packus\n        // back to 16 bit\n        result1 = _mm256_packus_epi32(result_l, result_h); // 8 * 16 bit pixels\n        result1 = _mm256_min_epu16(result1, vect_target_max);\n      }\n\n      // byte target: not yet\n      if constexpr (sizeof(pixel_t_d) == 2)\n        _mm256_store_si256(reinterpret_cast<__m256i*>(dstp0 + x), result1);\n\n      {\n        // src: 8*uint16\n        // convert to int32, bias, to float\n        auto res_lo_i = _mm256_unpacklo_epi16(src_hi, zero);\n        auto res_hi_i = _mm256_unpackhi_epi16(src_hi, zero);\n        if constexpr (chroma || !fulls) {\n          // src_offset is not zero\n          res_lo_i = _mm256_sub_epi32(res_lo_i, vect_src_offset);\n          res_hi_i = _mm256_sub_epi32(res_hi_i, vect_src_offset);\n        }\n        auto res_lo = _mm256_cvtepi32_ps(res_lo_i);\n        auto res_hi = _mm256_cvtepi32_ps(res_hi_i);\n        // multiply, bias back+round\n        res_lo = _mm256_add_ps(_mm256_mul_ps(res_lo, vect_mul_factor), vect_dst_offset_plus_round);\n        res_hi = _mm256_add_ps(_mm256_mul_ps(res_hi, vect_mul_factor), vect_dst_offset_plus_round);\n        // convert back w/ truncate\n        auto result_l = _mm256_cvttps_epi32(res_lo);\n        auto result_h = _mm256_cvttps_epi32(res_hi);\n        // 0 min is ensured by packus\n        // back to 16 bit\n        result2 = _mm256_packus_epi32(result_l, result_h); // 8 * 16 bit pixels\n        result2 = _mm256_min_epu16(result2, vect_target_max);\n      }\n\n      if constexpr (sizeof(pixel_t_d) == 2)\n        _mm256_store_si256(reinterpret_cast<__m256i*>(dstp0 + x + 16), result2);\n      else {\n        // byte target: store both\n        auto result12 = _mm256_packus_epi16(result1, result2);\n        result12 = _mm256_permute4x64_epi64(result12, (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6));\n        _mm256_store_si256(reinterpret_cast<__m256i*>(dstp0 + x), result12);\n      }\n    } // for x\n\n    dstp0 += dst_pitch;\n    srcp0 += src_pitch;\n  }\n}\n\n// instantiate them all\n// template<typename pixel_t_s, typename pixel_t_d, bool chroma, bool fulls, bool fulld>\n// spec: fulld=false, fulls=false\n#define convert_uint_avx2_functions(uint_X_t, uint_X_dest_t) \\\ntemplate void convert_uint_avx2<uint_X_t, uint_X_dest_t, false, false, false>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_uint_avx2<uint_X_t, uint_X_dest_t, false, false, true>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_uint_avx2<uint_X_t, uint_X_dest_t, false, true, false>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_uint_avx2<uint_X_t, uint_X_dest_t, false, true, true>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_uint_avx2<uint_X_t, uint_X_dest_t, true, false, false>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_uint_avx2<uint_X_t, uint_X_dest_t, true, false, true>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_uint_avx2<uint_X_t, uint_X_dest_t, true, true, false>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_uint_avx2<uint_X_t, uint_X_dest_t, true, true, true>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\n\nconvert_uint_avx2_functions(uint8_t, uint8_t)\nconvert_uint_avx2_functions(uint8_t, uint16_t)\nconvert_uint_avx2_functions(uint16_t, uint8_t)\nconvert_uint_avx2_functions(uint16_t, uint16_t)\n\n#undef convert_uint_avx2_functions\n\ntemplate<typename pixel_t_s, typename pixel_t_d, bool chroma, bool fulls, bool fulld, bool TEMPLATE_NEED_BACKSCALE, bool TEMPLATE_LOW_DITHER_BITDEPTH>\nstatic void do_convert_ordered_dither_uint_avx2(const BYTE* srcp8, BYTE* dstp8, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth)\n{\n  const pixel_t_s* srcp = reinterpret_cast<const pixel_t_s*>(srcp8);\n  pixel_t_d* dstp = reinterpret_cast<pixel_t_d*>(dstp8);\n  dst_pitch = dst_pitch / sizeof(pixel_t_d);\n\n  src_pitch = src_pitch / sizeof(pixel_t_s);\n  // we can safely process whole 16 (8 bit src) / 32 byte (16 bit source) chunks, Avisynth ensures at least 32 byte alignment\n  const int src_width = (src_rowsize / sizeof(pixel_t_s) + 15) & ~15;\n\n  // helps compiler optimization\n  if constexpr (sizeof(pixel_t_s) == 1)\n    source_bitdepth = 8;\n  if constexpr (sizeof(pixel_t_d) == 1) {\n    target_bitdepth = 8;\n    if (!TEMPLATE_NEED_BACKSCALE) {\n      dither_target_bitdepth = 8;\n    }\n  }\n\n  const int max_pixel_value_target = (1 << target_bitdepth) - 1;\n  const int max_pixel_value_dithered = (1 << dither_target_bitdepth) - 1;\n  // precheck ensures:\n  // target_bitdepth >= dither_target_bitdepth\n  // source_bitdepth - dither_target_bitdepth <= 8 (max precalculated table is 16x16)\n  const bool odd_diff = (source_bitdepth - dither_target_bitdepth) & 1;\n  const int dither_bit_diff = (source_bitdepth - dither_target_bitdepth);\n  const int dither_order = (dither_bit_diff + 1) / 2;\n  const int dither_mask = (1 << dither_order) - 1; // 9,10=2  11,12=4  13,14=8  15,16=16\n  // 10->8: 0x01 (2x2)\n  // 11->8: 0x03 (4x4)\n  // 12->8: 0x03 (4x4)\n  // 14->8: 0x07 (8x8)\n  // 16->8: 0x0F (16x16)\n  const BYTE* matrix;\n  switch (dither_order) {\n  case 1: matrix = reinterpret_cast<const BYTE*>(odd_diff ? dither2x2a_data_sse2 : dither2x2_data_sse2); break;\n  case 2: matrix = reinterpret_cast<const BYTE*>(odd_diff ? dither4x4a_data_sse2 : dither4x4_data_sse2); break;\n  case 3: matrix = reinterpret_cast<const BYTE*>(odd_diff ? dither8x8a_data_sse2 : dither8x8_data_sse2); break;\n  case 4: matrix = reinterpret_cast<const BYTE*>(odd_diff ? dither16x16a_data : dither16x16_data); break; // no spec sse, already 16 bytes long\n  default: return; // n/a\n  }\n\n  const int bitdiff_between_dither_and_target = target_bitdepth - dither_target_bitdepth;\n  assert(TEMPLATE_NEED_BACKSCALE == (target_bitdepth != dither_target_bitdepth));  // dither to x, target to y\n\n  assert(TEMPLATE_LOW_DITHER_BITDEPTH == (dither_target_bitdepth < 8));\n  // e.g. instead of 0,1 => -0.5,+0.5;  0,1,2,3 => -1.5,-0.5,0.5,1.5\n  const float half_maxcorr_value = ((1 << dither_bit_diff) - 1) / 2.0f;\n\n  const int source_max = (1 << source_bitdepth) - 1;\n  //-----------------------\n  // When calculating src_pixel, src and dst are of the same bit depth\n  bits_conv_constants d;\n  get_bits_conv_constants(d, chroma, fulls, fulld, source_bitdepth, source_bitdepth); // both is src_bitdepth\n\n  auto dst_offset_plus_round = d.dst_offset + 0.5f;\n  //constexpr auto src_pixel_min = 0;\n  const auto src_pixel_max = source_max;\n  const float mul_factor_backfromlowdither = (float)max_pixel_value_target / max_pixel_value_dithered;\n  //-----------------------\n\n  const auto mul_factor_simd = _mm256_set1_ps(d.mul_factor);\n  const auto mul_factor_backfromlowdither_simd = _mm256_set1_ps(mul_factor_backfromlowdither);\n  const auto half_maxcorr_value_simd = _mm256_set1_ps(half_maxcorr_value);\n  const auto zero = _mm256_setzero_si256();\n  const BYTE* matrix_simd16 = matrix;\n  const BYTE* current_matrix_line;\n\n  for (int y = 0; y < src_height; y++)\n  {\n    // int _y = (y & dither_mask) << dither_order; // for C version\n    current_matrix_line = matrix_simd16 + ((y & dither_mask) << 4); // always 16 byte boundary instead of dither order\n    // load and convert corr to 16 bit\n    __m256i corr = _mm256_cvtepu8_epi16(_mm_load_si128(reinterpret_cast<const __m128i*>(current_matrix_line))); // int corr = matrix[_y | (x & dither_mask)];\n\n    for (int x = 0; x < src_width; x += 16)\n    {\n      //const int corr = matrix[_y | (x & dither_mask)];\n\n      //int src_pixel = srcp[x];\n      //__m128i src_lo, src_hi;\n      __m256i src;\n      if constexpr (sizeof(pixel_t_s) == 1) {\n        src = _mm256_cvtepu8_epi16(_mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x))); // 16* uint8->uint16\n      }\n      else {\n        src= _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp + x)); // 16* uint16\n      }\n\n      [[maybe_unused]] __m256i src_lo;\n      [[maybe_unused]] __m256i src_hi;\n      if constexpr (fulls != fulld) {\n        // goint to 32 float\n        // const float val = (srcp[x] - src_offset) * mul_factor + dst_offset_plus_round;\n        const auto src_offset_simd = _mm256_set1_epi32(d.src_offset_i);\n        const auto dst_offset_plus_round_simd = _mm256_set1_ps(dst_offset_plus_round);\n\n        auto src_lo_ps = _mm256_cvtepi32_ps(_mm256_sub_epi32(_mm256_unpacklo_epi16(src, zero), src_offset_simd));\n        auto src_hi_ps = _mm256_cvtepi32_ps(_mm256_sub_epi32(_mm256_unpackhi_epi16(src, zero), src_offset_simd));\n        src_lo_ps = _mm256_add_ps(_mm256_mul_ps(src_lo_ps, mul_factor_simd), dst_offset_plus_round_simd);\n        src_hi_ps = _mm256_add_ps(_mm256_mul_ps(src_hi_ps, mul_factor_simd), dst_offset_plus_round_simd);\n\n        // src_pixel = clamp((int)val, src_pixel_min, src_pixel_max);\n        if constexpr (sizeof(pixel_t_s) == 1 && !TEMPLATE_LOW_DITHER_BITDEPTH) {\n          // Source is 8 bits. This branch is ineffective if we define TEMPLATE_LOW_DITHER_BITDEPTH for all <8 bits, as we do now\n          // We would reach this code for 5-7 bits when lo limit would be e.g. 4 bits\n          // 8 bit source: we can go back from 32 to 16 bit int\n          src = _mm256_packus_epi32(_mm256_cvttps_epi32(src_lo_ps), _mm256_cvttps_epi32(src_hi_ps));\n          // min is 0, which was ensured by packus\n          const auto src_pixel_max_simd = _mm256_set1_epi16(src_pixel_max);\n          src = _mm256_min_epu16(src, src_pixel_max_simd);\n          // tmp result 16 bits in src\n        }\n        else {\n          // go back to int32 only\n          src_lo = _mm256_cvttps_epi32(src_lo_ps);\n          src_hi = _mm256_cvttps_epi32(src_hi_ps);\n          // min is 0, which was ensured by packus\n          const auto src_pixel_max_simd = _mm256_set1_epi32(src_pixel_max);\n          src_lo = _mm256_min_epi32(src_lo, src_pixel_max_simd);\n          src_hi = _mm256_min_epi32(src_hi, src_pixel_max_simd);\n          // tmp result 32 bits in src_lo, src_hi\n        }\n      }\n      else {\n        // 10-16 bits or preshift: go into 32 bit int\n        if constexpr (sizeof(pixel_t_s) == 2 || TEMPLATE_LOW_DITHER_BITDEPTH) {\n          src_lo = _mm256_unpacklo_epi16(src, zero);\n          src_hi = _mm256_unpackhi_epi16(src, zero);\n          // tmp result 32 bits in src_lo, src_hi\n        }\n      }\n\n      __m256i new_pixel;\n\n      // scale down after adding dithering noise\n      // int new_pixel = ((src_pixel + corr) >> dither_bit_diff);\n      if constexpr (sizeof(pixel_t_s) == 1 && !TEMPLATE_LOW_DITHER_BITDEPTH) {\n        // when dither_target_bits is 1, then preshift==1 and dither_bit_diff==(7+1) would not fit in 16 bits\n        new_pixel = _mm256_srai_epi16(_mm256_add_epi16(src, corr), dither_bit_diff);\n        // new_pixel is ready with 16 bit data\n      }\n      else {\n        // source bits: >8.\n        // At 16 bit overflow can happen when 0xFFFF it dithered up. This is why we are at 32 bits int\n        // Theoretically fulls == fulld && <16 bit would allow 16 bit int workflow but we do not specialize for that\n        // source bits: >8 or 8 bit but PRESHIFT\n        // At 16 bit overflow can happen when 0xFFFF it dithered up. This is why we are at 32 bits int\n        // Theoretically fulls == fulld && <16 bit would allow 16 bit int workflow but we do not specialize for that\n        // low dither bitdepth is special as well\n\n        /*\n        int new_pixel;\n        if (TEMPLATE_LOW_DITHER_BITDEPTH) {\n          // accurate dither: +/-\n          const float corr_f = corr - half_maxcorr_value;\n          new_pixel = (int)(src_pixel + corr_f) >> dither_bit_diff;\n        }\n        else\n          new_pixel = ((src_pixel + corr) >> dither_bit_diff);\n        */\n        __m256i new_pixel_lo, new_pixel_hi;\n        auto corr_lo = _mm256_unpacklo_epi16(corr, zero);\n        auto corr_hi = _mm256_unpackhi_epi16(corr, zero);\n        if (TEMPLATE_LOW_DITHER_BITDEPTH) {\n          // accurately positioned to the center\n          auto corr_lo_ps = _mm256_sub_ps(_mm256_cvtepi32_ps(corr_lo), half_maxcorr_value_simd);\n          auto corr_hi_ps = _mm256_sub_ps(_mm256_cvtepi32_ps(corr_hi), half_maxcorr_value_simd);\n          // accurate dither: +/-\n          new_pixel_lo = _mm256_srai_epi32(_mm256_cvttps_epi32(_mm256_add_ps(_mm256_cvtepi32_ps(src_lo), corr_lo_ps)), dither_bit_diff);\n          new_pixel_hi = _mm256_srai_epi32(_mm256_cvttps_epi32(_mm256_add_ps(_mm256_cvtepi32_ps(src_hi), corr_hi_ps)), dither_bit_diff);\n        }\n        else {\n          // Arrgh. If dither_bit_diff would be an immediate constant (e.g. template parameter) then we get 2390 fps vs 1378 even for sse4.1!\n          // for a simple Vide16bit.ConvertBits(8, dither=0, dither_bits=8)\n          // const auto dither_bit_diff = 8;\n          new_pixel_lo = _mm256_srai_epi32(_mm256_add_epi32(src_lo, corr_lo), dither_bit_diff);\n          new_pixel_hi = _mm256_srai_epi32(_mm256_add_epi32(src_hi, corr_hi), dither_bit_diff);\n        }\n        new_pixel = _mm256_packus_epi32(new_pixel_lo, new_pixel_hi);\n        // new_pixel is ready with 16 bit data\n      }\n\n      // scale back to the required bit depth\n       // dither to x, target to y\n      if constexpr (TEMPLATE_NEED_BACKSCALE) {\n        /*\n        new_pixel = min(new_pixel, max_pixel_value_dithered);\n        if (TEMPLATE_LOW_DITHER_BITDEPTH) {\n          new_pixel = (int)(new_pixel * mul_factor_backfromlowdither + 0.5f);\n        }\n        else {\n          new_pixel = new_pixel << bitdiff_between_dither_and_target;\n        }\n        */\n        const auto max_pixel_value_dithered_simd = _mm256_set1_epi16(max_pixel_value_dithered);\n        new_pixel = _mm256_min_epu16(new_pixel, max_pixel_value_dithered_simd);\n        // Interesting problem of dither_bits==1 (or in general at small dither_bits)\n        // After simple slli 0,1 becomes 0,128, we'd expect 0,255 instead. So we make cosmetics.\n        // dither_bits\n        // 1            0,1     => 0,128        => 0,255\n        // 2            0,1,2,3 => 0,64,128,192 => 0,85,170,255\n        // 3            0,...,7 => 0,32,...,224 => 0,....255\n        // 4            0,..,15 => 0,16,...,240 => 0,....255\n        // 5            0,..,31 => 0,8,....,248 => 0,....255\n        // 6            0,..,63 => 0,4,....,252 => 0,....255\n        // 7            0,.,127 => 0,2.  ..,254 => 0,?,?,255\n        if (TEMPLATE_LOW_DITHER_BITDEPTH) {\n          // new_pixel = (int)(new_pixel * mul_factor_backfromlowdither + 0.5f);\n          auto rounder_half_simd = _mm256_set1_ps(0.5f);\n\n          auto new_pixel_lo_ps = _mm256_cvtepi32_ps(_mm256_unpacklo_epi16(new_pixel, zero));\n          auto new_pixel_hi_ps = _mm256_cvtepi32_ps(_mm256_unpackhi_epi16(new_pixel, zero));\n          new_pixel = _mm256_packus_epi32(\n            _mm256_cvttps_epi32(_mm256_add_ps(_mm256_mul_ps(new_pixel_lo_ps, mul_factor_backfromlowdither_simd), rounder_half_simd)),\n            _mm256_cvttps_epi32(_mm256_add_ps(_mm256_mul_ps(new_pixel_hi_ps, mul_factor_backfromlowdither_simd), rounder_half_simd))\n          );\n        }\n        else {\n          new_pixel = _mm256_slli_epi16(new_pixel, bitdiff_between_dither_and_target);\n        }\n      }\n\n      // dstp[x] = (pixel_t_d)(min((int)new_pixel, max_pixel_value_target));\n      if constexpr (sizeof(pixel_t_d) == 1)\n      {\n        // byte target: 16x 2bytes -> 16x 1 bytes like cvtepu16->epu8\n        auto result12 = _mm256_packus_epi16(new_pixel, new_pixel);\n        result12 = _mm256_permute4x64_epi64(result12, (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6));\n        _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x), _mm256_castsi256_si128(result12));\n      }\n      else {\n        const auto max_pixel_value_target_simd = _mm256_set1_epi16(max_pixel_value_target);\n        // max is unnecessary for exact 16 bit pixel type but we are not specialized for that case\n        new_pixel = _mm256_min_epu16(new_pixel, max_pixel_value_target_simd);\n        _mm256_store_si256(reinterpret_cast<__m256i*>(dstp + x), new_pixel);\n      }\n    }\n    dstp += dst_pitch;\n    srcp += src_pitch;\n  }\n}\n\ntemplate<typename pixel_t_s, typename pixel_t_d, bool chroma, bool fulls, bool fulld>\nvoid convert_ordered_dither_uint_avx2(const BYTE* srcp8, BYTE* dstp8, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth)\n{\n  const bool need_backscale = target_bitdepth != dither_target_bitdepth; // dither to x, target to y\n  const bool low_dither_bitdepth = dither_target_bitdepth < 8; // 1-7 bits dither targets, need_backscale is always true, since 8 bit format is the minimum\n  if (need_backscale) {\n    if (low_dither_bitdepth)\n      do_convert_ordered_dither_uint_avx2<pixel_t_s, pixel_t_d, chroma, fulls, fulld, true, true>(srcp8, dstp8, src_rowsize, src_height, src_pitch, dst_pitch, source_bitdepth, target_bitdepth, dither_target_bitdepth);\n    else\n      do_convert_ordered_dither_uint_avx2<pixel_t_s, pixel_t_d, chroma, fulls, fulld, true, false>(srcp8, dstp8, src_rowsize, src_height, src_pitch, dst_pitch, source_bitdepth, target_bitdepth, dither_target_bitdepth);\n  }\n  else {\n    do_convert_ordered_dither_uint_avx2<pixel_t_s, pixel_t_d, chroma, fulls, fulld, false, false>(srcp8, dstp8, src_rowsize, src_height, src_pitch, dst_pitch, source_bitdepth, target_bitdepth, dither_target_bitdepth);\n  }\n}\n\n// instantiate them all\n// template<typename pixel_t_s, typename pixel_t_d, bool chroma, bool fulls, bool fulld>\n// spec: fulld=false, fulls=false\n#define convert_ordered_dither_uint_sse4_functions(uint_X_t, uint_X_dest_t) \\\ntemplate void convert_ordered_dither_uint_avx2<uint_X_t, uint_X_dest_t, false, false, false>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_ordered_dither_uint_avx2<uint_X_t, uint_X_dest_t, false, false, true>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_ordered_dither_uint_avx2<uint_X_t, uint_X_dest_t, false, true, false>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_ordered_dither_uint_avx2<uint_X_t, uint_X_dest_t, false, true, true>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_ordered_dither_uint_avx2<uint_X_t, uint_X_dest_t, true, false, false>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_ordered_dither_uint_avx2<uint_X_t, uint_X_dest_t, true, false, true>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_ordered_dither_uint_avx2<uint_X_t, uint_X_dest_t, true, true, false>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_ordered_dither_uint_avx2<uint_X_t, uint_X_dest_t, true, true, true>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\n\n// dither only same of less bit depth\nconvert_ordered_dither_uint_sse4_functions(uint8_t, uint8_t)\nconvert_ordered_dither_uint_sse4_functions(uint16_t, uint8_t)\nconvert_ordered_dither_uint_sse4_functions(uint16_t, uint16_t)\n\n#undef convert_ordered_dither_uint_sse4_functions\n\ntemplate<typename pixel_t, bool chroma, bool fulls, bool fulld>\nvoid convert_uintN_to_float_avx2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth)\n{\n  const pixel_t* srcp0 = reinterpret_cast<const pixel_t*>(srcp);\n  float* dstp0 = reinterpret_cast<float*>(dstp);\n\n  src_pitch = src_pitch / sizeof(pixel_t);\n  dst_pitch = dst_pitch / sizeof(float);\n\n  const int src_width = src_rowsize / sizeof(pixel_t);\n  // write 32 floats (128 bytes) only if valid, scanline alignment is only 64 bytes (16 floats).\n  // Alignment, write-limited, 16 floats (64 bytes) is guaranteed by AviSynth\n  const int w16 = (src_width + 15) & ~15;\n  //-----------------------\n  bits_conv_constants d;\n  get_bits_conv_constants(d, chroma, fulls, fulld, source_bitdepth, target_bitdepth);\n\n  const __m256i m256_src_offset_epi32 = _mm256_set1_epi32(d.src_offset_i);\n  const __m256 m256_mul_factor = _mm256_set1_ps(d.mul_factor);\n  const __m256 m256_dst_offset = _mm256_set1_ps(d.dst_offset);\n\n  for (int y = 0; y < src_height; y++)\n  {\n    // rows are 64 bytes - 16 float pixels - aligned we have a write constraint\n    int x;\n    for (x = 0; x + 32 <= w16; x += 32)\n    {\n      __m256i src_0_32, src_1_32, src_2_32, src_3_32;\n\n      if constexpr (sizeof(pixel_t) == 1) // uint8_t\n      {\n        __m256i src_32 = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp0 + x));\n        // unpack to 4x64bits\n        src_0_32 = _mm256_cvtepu8_epi32(_mm256_castsi256_si128(src_32)); // bytes 0-7\n\n        __m256i src_1 = _mm256_permute4x64_epi64(src_32, 1);\n        __m256i src_2 = _mm256_permute4x64_epi64(src_32, 2);\n        __m256i src_3 = _mm256_permute4x64_epi64(src_32, 3);\n\n        src_1_32 = _mm256_cvtepu8_epi32(_mm256_castsi256_si128(src_1));\n        src_2_32 = _mm256_cvtepu8_epi32(_mm256_castsi256_si128(src_2));\n        src_3_32 = _mm256_cvtepu8_epi32(_mm256_castsi256_si128(src_3));\n      }\n\n      if constexpr (sizeof(pixel_t) == 2) // uint16_t\n      {\n        __m256i src_16 = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp0 + x));\n        __m256i src_16_2 = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp0 + x + 16));\n        // unpack to 2x128bits  2x8 uint16\n        src_0_32 = _mm256_cvtepu16_epi32(_mm256_castsi256_si128(src_16));\n        src_1_32 = _mm256_cvtepu16_epi32(_mm256_extracti128_si256(src_16, 1));\n        src_2_32 = _mm256_cvtepu16_epi32(_mm256_castsi256_si128(src_16_2));\n        src_3_32 = _mm256_cvtepu16_epi32(_mm256_extracti128_si256(src_16_2, 1));\n      }\n\n      src_0_32 = _mm256_sub_epi32(src_0_32, m256_src_offset_epi32);\n      src_1_32 = _mm256_sub_epi32(src_1_32, m256_src_offset_epi32);\n      src_2_32 = _mm256_sub_epi32(src_2_32, m256_src_offset_epi32);\n      src_3_32 = _mm256_sub_epi32(src_3_32, m256_src_offset_epi32);\n\n      __m256 src_0_ps = _mm256_cvtepi32_ps(src_0_32);\n      __m256 src_1_ps = _mm256_cvtepi32_ps(src_1_32);\n      __m256 src_2_ps = _mm256_cvtepi32_ps(src_2_32);\n      __m256 src_3_ps = _mm256_cvtepi32_ps(src_3_32);\n\n      __m256 out_0_ps = _mm256_fmadd_ps(src_0_ps, m256_mul_factor, m256_dst_offset);\n      __m256 out_1_ps = _mm256_fmadd_ps(src_1_ps, m256_mul_factor, m256_dst_offset);\n      __m256 out_2_ps = _mm256_fmadd_ps(src_2_ps, m256_mul_factor, m256_dst_offset);\n      __m256 out_3_ps = _mm256_fmadd_ps(src_3_ps, m256_mul_factor, m256_dst_offset);\n\n      // process 32 pixels, write 128 bytes\n      _mm256_store_ps((dstp0 + x + 0), out_0_ps);\n      _mm256_store_ps((dstp0 + x + 8), out_1_ps);\n      _mm256_store_ps((dstp0 + x + 16), out_2_ps);\n      _mm256_store_ps((dstp0 + x + 24), out_3_ps);\n\n      //        const float pixel = (srcp0[x] - d.src_offset_i) * d.mul_factor + d.dst_offset;\n      //        dstp0[x] = pixel; // no clamp\n    }\n\n    // second loop: process remaining 1-15 pixels, 16 at a time\n    if (x < w16) {\n      __m256i src_0_32, src_1_32;\n\n      if constexpr (sizeof(pixel_t) == 1) // uint8_t\n      {\n        // _m128 enough, 16 pixels\n        __m128i src_16_bytes = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp0 + x));\n        src_0_32 = _mm256_cvtepu8_epi32(src_16_bytes); // 0-7\n        src_1_32 = _mm256_cvtepu8_epi32(_mm_srli_si128(src_16_bytes, 8)); // 8-15, quick permuteless\n      }\n      else // uint16_t\n      {\n        __m256i src_16 = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp0 + x));\n        src_0_32 = _mm256_cvtepu16_epi32(_mm256_castsi256_si128(src_16));      // 0-7\n        src_1_32 = _mm256_cvtepu16_epi32(_mm256_extracti128_si256(src_16, 1)); // 8-15\n      }\n\n      src_0_32 = _mm256_sub_epi32(src_0_32, m256_src_offset_epi32);\n      src_1_32 = _mm256_sub_epi32(src_1_32, m256_src_offset_epi32);\n\n      __m256 out_0_ps = _mm256_fmadd_ps(_mm256_cvtepi32_ps(src_0_32), m256_mul_factor, m256_dst_offset);\n      __m256 out_1_ps = _mm256_fmadd_ps(_mm256_cvtepi32_ps(src_1_32), m256_mul_factor, m256_dst_offset);\n\n      // 16 floats - 64 bytes always safe\n      _mm256_store_ps((dstp0 + x + 0), out_0_ps);\n      _mm256_store_ps((dstp0 + x + 8), out_1_ps);\n\n      //        const float pixel = (srcp0[x] - d.src_offset_i) * d.mul_factor + d.dst_offset;\n      //        dstp0[x] = pixel; // no clamp\n    }\n    dstp0 += dst_pitch;\n    srcp0 += src_pitch;\n  }\n\n}\n\n// instantinate\ntemplate void convert_uintN_to_float_avx2<uint8_t, false, false, false>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\ntemplate void convert_uintN_to_float_avx2<uint8_t, false, false, true>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\ntemplate void convert_uintN_to_float_avx2<uint8_t, false, true, false>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\ntemplate void convert_uintN_to_float_avx2<uint8_t, false, true, true>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\ntemplate void convert_uintN_to_float_avx2<uint8_t, true, false, false>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\ntemplate void convert_uintN_to_float_avx2<uint8_t, true, false, true>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\ntemplate void convert_uintN_to_float_avx2<uint8_t, true, true, false>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\ntemplate void convert_uintN_to_float_avx2<uint8_t, true, true, true>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\n\ntemplate void convert_uintN_to_float_avx2<uint16_t, false, false, false>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\ntemplate void convert_uintN_to_float_avx2<uint16_t, false, false, true>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\ntemplate void convert_uintN_to_float_avx2<uint16_t, false, true, false>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\ntemplate void convert_uintN_to_float_avx2<uint16_t, false, true, true>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\ntemplate void convert_uintN_to_float_avx2<uint16_t, true, false, false>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\ntemplate void convert_uintN_to_float_avx2<uint16_t, true, false, true>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\ntemplate void convert_uintN_to_float_avx2<uint16_t, true, true, false>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\ntemplate void convert_uintN_to_float_avx2<uint16_t, true, true, true>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\n\n"
  },
  {
    "path": "avs_core/convert/intel/convert_bits_avx2.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Convert_bits_AVX2_H__\n#define __Convert_bits_AVX2_H__\n\n#include <avs/types.h>\n\ntemplate<typename pixel_t, bool chroma, bool fulls, bool fulld>\nvoid convert_32_to_uintN_avx2(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\n\ntemplate<typename pixel_t_s, typename pixel_t_d, bool chroma, bool fulls, bool fulld>\nvoid convert_uint_avx2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\n\ntemplate<typename pixel_t_s, typename pixel_t_d, bool chroma, bool fulls, bool fulld>\nvoid convert_ordered_dither_uint_avx2(const BYTE* srcp8, BYTE* dstp8, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\n\ntemplate<typename pixel_t, bool chroma, bool fulls, bool fulld>\nvoid convert_uintN_to_float_avx2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\n\n#endif  // __Convert_bits_AVX2_H__\n"
  },
  {
    "path": "avs_core/convert/intel/convert_bits_sse.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002-2009 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include \"../convert_bits.h\"\n#include \"convert_bits_sse.h\"\n#include \"../convert_helper.h\"\n\n#include <avs/alignment.h>\n#include <avs/minmax.h>\n#include <avs/config.h>\n#include <tuple>\n#include <map>\n#include <algorithm>\n\n#ifdef AVS_WINDOWS\n#include <avs/win.h>\n#else\n#include <avs/posix.h>\n#endif\n\n// Intrinsics base header + really required extension headers\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n#include <smmintrin.h> // SSE4.1\n\n// float to 8 bit, float to 10/12/14/16 bit\n\n// sse4.1\ntemplate<typename pixel_t, bool chroma, bool fulls, bool fulld>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid convert_32_to_uintN_sse41(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth)\n{\n  const float* srcp0 = reinterpret_cast<const float*>(srcp);\n  pixel_t* dstp0 = reinterpret_cast<pixel_t*>(dstp);\n\n  src_pitch = src_pitch / sizeof(float);\n  dst_pitch = dst_pitch / sizeof(pixel_t);\n\n  const int src_width = src_rowsize / sizeof(float);\n\n  bits_conv_constants d;\n  get_bits_conv_constants(d, chroma, fulls, fulld, source_bitdepth, target_bitdepth);\n\n  auto dst_offset_plus_round = d.dst_offset + 0.5f;\n  constexpr auto dst_pixel_min = 0;\n  const auto dst_pixel_max = (1 << target_bitdepth) - 1;\n\n  auto src_offset_ps = _mm_set1_ps(d.src_offset);\n  auto factor_ps = _mm_set1_ps(d.mul_factor);\n  auto dst_offset_plus_round_ps = _mm_set1_ps(dst_offset_plus_round);\n  auto dst_pixel_min_ps = _mm_set1_ps((float)dst_pixel_min);\n  auto dst_pixel_max_ps = _mm_set1_ps((float)dst_pixel_max);\n\n  for (int y = 0; y < src_height; y++)\n  {\n    for (int x = 0; x < src_width; x += 8) // 8 pixels at a time\n    {\n      __m128i result;\n      __m128i result_0, result_1;\n      __m128 src_0 = _mm_load_ps(reinterpret_cast<const float*>(srcp0 + x));\n      __m128 src_1 = _mm_load_ps(reinterpret_cast<const float*>(srcp0 + x + 4));\n      if constexpr (!chroma && !fulls) {\n        // when offset is different from 0\n        src_0 = _mm_sub_ps(src_0, src_offset_ps);\n        src_1 = _mm_sub_ps(src_1, src_offset_ps);\n      }\n      src_0 = _mm_add_ps(_mm_mul_ps(src_0, factor_ps), dst_offset_plus_round_ps);\n      src_1 = _mm_add_ps(_mm_mul_ps(src_1, factor_ps), dst_offset_plus_round_ps);\n\n      src_0 = _mm_max_ps(_mm_min_ps(src_0, dst_pixel_max_ps), dst_pixel_min_ps);\n      src_1 = _mm_max_ps(_mm_min_ps(src_1, dst_pixel_max_ps), dst_pixel_min_ps);\n      result_0 = _mm_cvttps_epi32(src_0); // truncate\n      result_1 = _mm_cvttps_epi32(src_1);\n      if constexpr (sizeof(pixel_t) == 2) {\n        result = _mm_packus_epi32(result_0, result_1); // sse41\n        _mm_store_si128(reinterpret_cast<__m128i*>(dstp0 + x), result);\n      }\n      else {\n        result = _mm_packs_epi32(result_0, result_1);\n        result = _mm_packus_epi16(result, result); // lo 8 byte\n        _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp0 + x), result);\n      }\n\n      // c: \n      //const int pixel = (int)((srcp0[x] - src_offset) * mul_factor + dst_offset_plus_round);\n      //dstp0[x] = pixel_t(clamp(pixel, dst_pixel_min, dst_pixel_max));\n    }\n    dstp0 += dst_pitch;\n    srcp0 += src_pitch;\n  }\n}\n\n// instantiate them\n//template<typename pixel_t, bool chroma, bool fulls, bool fulld>\n#define DEF_convert_32_to_uintN_functions(uint_X_t) \\\ntemplate void convert_32_to_uintN_sse41<uint_X_t, false, true, true>(const BYTE* srcp8, BYTE* dstp8, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_32_to_uintN_sse41<uint_X_t, true, true, true>(const BYTE* srcp8, BYTE* dstp8, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_32_to_uintN_sse41<uint_X_t, false, true, false>(const BYTE* srcp8, BYTE* dstp8, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_32_to_uintN_sse41<uint_X_t, true, true, false>(const BYTE* srcp8, BYTE* dstp8, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_32_to_uintN_sse41<uint_X_t, false, false, true>(const BYTE* srcp8, BYTE* dstp8, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_32_to_uintN_sse41<uint_X_t, true, false, true>(const BYTE* srcp8, BYTE* dstp8, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_32_to_uintN_sse41<uint_X_t, false, false, false>(const BYTE* srcp8, BYTE* dstp8, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_32_to_uintN_sse41<uint_X_t, true, false, false>(const BYTE* srcp8, BYTE* dstp8, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\n\nDEF_convert_32_to_uintN_functions(uint8_t)\nDEF_convert_32_to_uintN_functions(uint16_t)\n\n#undef DEF_convert_32_to_uintN_functions\n\n// YUV: bit shift 8-16 <=> 8-16 bits\n// shift right or left, depending on expandrange\ntemplate<typename pixel_t_s, typename pixel_t_d>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nstatic void convert_uint_limited_sse41(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth)\n{\n  const pixel_t_s* srcp0 = reinterpret_cast<const pixel_t_s*>(srcp);\n  pixel_t_d* dstp0 = reinterpret_cast<pixel_t_d*>(dstp);\n\n  src_pitch = src_pitch / sizeof(pixel_t_s);\n  dst_pitch = dst_pitch / sizeof(pixel_t_d);\n\n  const int src_width = src_rowsize / sizeof(pixel_t_s);\n\n  if (target_bitdepth > source_bitdepth) // expandrange. pixel_t_d is always uint16_t\n  {\n    const int shift_bits = target_bitdepth - source_bitdepth;\n    __m128i shift = _mm_set_epi32(0, 0, 0, shift_bits);\n    for (int y = 0; y < src_height; y++)\n    {\n      for (int x = 0; x < src_width; x += 16)\n      {\n        __m128i src_lo, src_hi;\n        if constexpr (sizeof(pixel_t_s) == 1) {\n          auto src = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp0 + x)); // 16* uint8\n          src_lo = _mm_cvtepu8_epi16(src);                       // 8* uint16\n          src_hi = _mm_unpackhi_epi8(src, _mm_setzero_si128());  // 8* uint16\n        }\n        else {\n          src_lo = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp0 + x)); // 8* uint_16\n          src_hi = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp0 + x + 8)); // 8* uint_16\n        }\n        src_lo = _mm_sll_epi16(src_lo, shift);\n        src_hi = _mm_sll_epi16(src_hi, shift);\n        if constexpr (sizeof(pixel_t_d) == 1) {\n          // upconvert always to 2 bytes\n          assert(0);\n        }\n        else {\n          _mm_store_si128(reinterpret_cast<__m128i*>(dstp0 + x), src_lo);\n          _mm_store_si128(reinterpret_cast<__m128i*>(dstp0 + x + 8), src_hi);\n        }\n      }\n      dstp0 += dst_pitch;\n      srcp0 += src_pitch;\n    }\n  }\n  else\n  {\n    // reduce range\n    const int shift_bits = source_bitdepth - target_bitdepth;\n    const int round = 1 << (shift_bits - 1);\n    __m128i shift = _mm_set_epi32(0, 0, 0, shift_bits);\n    const auto round_simd = _mm_set1_epi16(round);\n\n    for (int y = 0; y < src_height; y++)\n    {\n      for (int x = 0; x < src_width; x += 16)\n      {\n        if constexpr (sizeof(pixel_t_s) == 1)\n          assert(0);\n        // downconvert always from 2 bytes\n        auto src_lo = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp0 + x)); // 8* uint_16\n        auto src_hi = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp0 + x + 8)); // 8* uint_16\n        src_lo = _mm_srl_epi16(_mm_adds_epu16(src_lo, round_simd), shift);\n        src_hi = _mm_srl_epi16(_mm_adds_epu16(src_hi, round_simd), shift);\n        if constexpr (sizeof(pixel_t_d) == 1) {\n          // to 8 bits\n          auto dst = _mm_packus_epi16(src_lo, src_hi);\n          _mm_store_si128(reinterpret_cast<__m128i*>(dstp0 + x), dst);\n        }\n        else {\n          _mm_store_si128(reinterpret_cast<__m128i*>(dstp0 + x), src_lo);\n          _mm_store_si128(reinterpret_cast<__m128i*>(dstp0 + x + 8), src_hi);\n        }\n      }\n      dstp0 += dst_pitch;\n      srcp0 += src_pitch;\n    }\n  }\n}\n\ntemplate<typename pixel_t_s, typename pixel_t_d, bool chroma, bool fulls, bool fulld>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid convert_uint_sse41(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth)\n{\n  // limited to limited is bitshift, see in other function\n  if constexpr (!fulls && !fulld) {\n    convert_uint_limited_sse41< pixel_t_s, pixel_t_d>(srcp, dstp, src_rowsize, src_height, src_pitch, dst_pitch, source_bitdepth, target_bitdepth, dither_target_bitdepth);\n    return;\n  }\n\n  const pixel_t_s* srcp0 = reinterpret_cast<const pixel_t_s*>(srcp);\n  pixel_t_d* dstp0 = reinterpret_cast<pixel_t_d*>(dstp);\n\n  src_pitch = src_pitch / sizeof(pixel_t_s);\n  dst_pitch = dst_pitch / sizeof(pixel_t_d);\n\n  const int src_width = src_rowsize / sizeof(pixel_t_s);\n\n  if constexpr (sizeof(pixel_t_s) == 1 && sizeof(pixel_t_d) == 2) {\n    if (fulls && fulld && !chroma && source_bitdepth == 8 && target_bitdepth == 16) {\n      // special case 8->16 bit full scale: * 65535 / 255 = *257\n      __m128i zero = _mm_setzero_si128();\n      __m128i multiplier = _mm_set1_epi16(257);\n\n      for (int y = 0; y < src_height; y++)\n      {\n        for (int x = 0; x < src_width; x += 16)\n        {\n          __m128i src = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp0 + x)); // 16* uint8\n          __m128i src_lo = _mm_unpacklo_epi8(src, zero);             // 8* uint16\n          __m128i src_hi = _mm_unpackhi_epi8(src, zero);             // 8* uint16\n            // *257 mullo is faster than x*257 = (x<<8 + x) add/or solution (i7)\n          __m128i res_lo = _mm_mullo_epi16(src_lo, multiplier); // lower 16 bit of multiplication is enough\n          __m128i res_hi = _mm_mullo_epi16(src_hi, multiplier);\n          // dstp[x] = srcp0[x] * 257; // RGB: full range 0..255 <-> 0..65535 (257 = 65535 / 255)\n          _mm_store_si128(reinterpret_cast<__m128i*>(dstp0 + x), res_lo);\n          _mm_store_si128(reinterpret_cast<__m128i*>(dstp0 + x + 8), res_hi);\n        } // for x\n        dstp0 += dst_pitch;\n        srcp0 += src_pitch;\n      } // for y\n      return;\n    }\n  }\n\n  const int target_max = (1 << target_bitdepth) - 1;\n\n  bits_conv_constants d;\n  get_bits_conv_constants(d, chroma, fulls, fulld, source_bitdepth, target_bitdepth);\n\n  auto vect_mul_factor = _mm_set1_ps(d.mul_factor);\n  auto vect_src_offset = _mm_set1_epi32(d.src_offset_i);\n  auto dst_offset_plus_round = d.dst_offset + 0.5f;\n  auto vect_dst_offset_plus_round = _mm_set1_ps(dst_offset_plus_round);\n\n  auto vect_target_max = _mm_set1_epi16(target_max);\n\n  auto zero = _mm_setzero_si128();\n\n  for (int y = 0; y < src_height; y++)\n  {\n    for (int x = 0; x < src_width; x += 16)\n    {\n      __m128i src_lo, src_hi;\n      if constexpr (sizeof(pixel_t_s) == 1) {\n        auto src = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp0 + x)); // 16* uint8\n        src_lo = _mm_cvtepu8_epi16(src);                   // 8* uint16\n        src_hi = _mm_unpackhi_epi8(src, zero);             // 8* uint16\n      }\n      else {\n        src_lo = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp0 + x)); // 8* uint_16\n        src_hi = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp0 + x + 8)); // 8* uint_16\n      }\n\n      __m128i result1, result2;\n      {\n        // src: 8*uint16\n        // convert to int32, bias, to float\n        auto res_lo_i = _mm_cvtepu16_epi32(src_lo);\n        auto res_hi_i = _mm_unpackhi_epi16(src_lo, zero);\n        if constexpr (chroma || !fulls) {\n          // src_offset is not zero\n          res_lo_i = _mm_sub_epi32(res_lo_i, vect_src_offset);\n          res_hi_i = _mm_sub_epi32(res_hi_i, vect_src_offset);\n        }\n        auto res_lo = _mm_cvtepi32_ps(res_lo_i);\n        auto res_hi = _mm_cvtepi32_ps(res_hi_i);\n        // multiply, bias back+round\n        res_lo = _mm_add_ps(_mm_mul_ps(res_lo, vect_mul_factor), vect_dst_offset_plus_round);\n        res_hi = _mm_add_ps(_mm_mul_ps(res_hi, vect_mul_factor), vect_dst_offset_plus_round);\n        // convert back w/ truncate\n        auto result_l = _mm_cvttps_epi32(res_lo); // no banker's rounding\n        auto result_h = _mm_cvttps_epi32(res_hi);\n        // 0 min is ensured by packus\n        // back to 16 bit\n        result1 = _mm_packus_epi32(result_l, result_h); // 8 * 16 bit pixels\n        result1 = _mm_min_epu16(result1, vect_target_max);\n      }\n\n      // byte target: not yet\n      if constexpr (sizeof(pixel_t_d) == 2)\n        _mm_store_si128(reinterpret_cast<__m128i*>(dstp0 + x), result1);\n\n      {\n        // src: 8*uint16\n        // convert to int32, bias, to float\n        auto res_lo_i = _mm_cvtepu16_epi32(src_hi);\n        auto res_hi_i = _mm_unpackhi_epi16(src_hi, zero);\n        if constexpr (chroma || !fulls) {\n          // src_offset is not zero\n          res_lo_i = _mm_sub_epi32(res_lo_i, vect_src_offset);\n          res_hi_i = _mm_sub_epi32(res_hi_i, vect_src_offset);\n        }\n        auto res_lo = _mm_cvtepi32_ps(res_lo_i);\n        auto res_hi = _mm_cvtepi32_ps(res_hi_i);\n        // multiply, bias back+round\n        res_lo = _mm_add_ps(_mm_mul_ps(res_lo, vect_mul_factor), vect_dst_offset_plus_round);\n        res_hi = _mm_add_ps(_mm_mul_ps(res_hi, vect_mul_factor), vect_dst_offset_plus_round);\n        // convert back w/ truncate\n        auto result_l = _mm_cvttps_epi32(res_lo);\n        auto result_h = _mm_cvttps_epi32(res_hi);\n        // 0 min is ensured by packus\n        // back to 16 bit\n        result2 = _mm_packus_epi32(result_l, result_h); // 8 * 16 bit pixels\n        result2 = _mm_min_epu16(result2, vect_target_max);\n      }\n\n      if constexpr (sizeof(pixel_t_d) == 2)\n        _mm_store_si128(reinterpret_cast<__m128i*>(dstp0 + x + 8), result2);\n      else {\n        // byte target: store both\n        auto result12 = _mm_packus_epi16(result1, result2);\n        _mm_store_si128(reinterpret_cast<__m128i*>(dstp0 + x), result12);\n      }\n    } // for x\n\n    dstp0 += dst_pitch;\n    srcp0 += src_pitch;\n  }\n}\n\n// instantiate them all\n// template<typename pixel_t_s, typename pixel_t_d, bool chroma, bool fulls, bool fulld>\n#define convert_uint_sse4_functions(uint_X_t, uint_X_dest_t) \\\ntemplate void convert_uint_sse41<uint_X_t, uint_X_dest_t, false, false, false>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_uint_sse41<uint_X_t, uint_X_dest_t, false, false, true>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_uint_sse41<uint_X_t, uint_X_dest_t, false, true, false>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_uint_sse41<uint_X_t, uint_X_dest_t, false, true, true>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_uint_sse41<uint_X_t, uint_X_dest_t, true, false, false>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_uint_sse41<uint_X_t, uint_X_dest_t, true, false, true>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_uint_sse41<uint_X_t, uint_X_dest_t, true, true, false>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_uint_sse41<uint_X_t, uint_X_dest_t, true, true, true>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\n\nconvert_uint_sse4_functions(uint8_t, uint8_t)\nconvert_uint_sse4_functions(uint8_t, uint16_t)\nconvert_uint_sse4_functions(uint16_t, uint8_t)\nconvert_uint_sse4_functions(uint16_t, uint16_t)\n\n#undef convert_uint_sse4_functions\n\n// for optimization this one has extra template parameters\n// TEMPLATE_NEED_BACKSCALE to support dither_target_bits being lower than target bit depth\ntemplate<typename pixel_t_s, typename pixel_t_d, bool chroma, bool fulls, bool fulld, bool TEMPLATE_NEED_BACKSCALE, bool TEMPLATE_LOW_DITHER_BITDEPTH>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nstatic void do_convert_ordered_dither_uint_sse41(const BYTE* srcp8, BYTE* dstp8, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth)\n{\n  const pixel_t_s* srcp = reinterpret_cast<const pixel_t_s*>(srcp8);\n  pixel_t_d* dstp = reinterpret_cast<pixel_t_d*>(dstp8);\n  dst_pitch = dst_pitch / sizeof(pixel_t_d);\n\n  src_pitch = src_pitch / sizeof(pixel_t_s);\n  // we can safely process whole 16 (8 bit src) / 32 byte (16 bit source) chunks, Avisynth ensures at least 32 byte alignment\n  const int src_width = (src_rowsize / sizeof(pixel_t_s) + 15) & ~15;\n\n  // helps compiler optimization\n  if constexpr (sizeof(pixel_t_s) == 1)\n    source_bitdepth = 8;\n  if constexpr (sizeof(pixel_t_d) == 1) {\n    target_bitdepth = 8;\n    if (!TEMPLATE_NEED_BACKSCALE) {\n      dither_target_bitdepth = 8;\n    }\n  }\n\n  const int max_pixel_value_target = (1 << target_bitdepth) - 1;\n  const int max_pixel_value_dithered = (1 << dither_target_bitdepth) - 1;\n  // precheck ensures:\n  // target_bitdepth >= dither_target_bitdepth\n  // source_bitdepth - dither_target_bitdepth <= 8 (max precalculated table is 16x16)\n  const bool odd_diff = (source_bitdepth - dither_target_bitdepth) & 1;\n  const int dither_bit_diff = (source_bitdepth - dither_target_bitdepth);\n  const int dither_order = (dither_bit_diff + 1) / 2;\n  const int dither_mask = (1 << dither_order) - 1; // 9,10=2  11,12=4  13,14=8  15,16=16\n  // 10->8: 0x01 (2x2)\n  // 11->8: 0x03 (4x4)\n  // 12->8: 0x03 (4x4)\n  // 14->8: 0x07 (8x8)\n  // 16->8: 0x0F (16x16)\n  const BYTE* matrix;\n  switch (dither_order) {\n  case 1: matrix = reinterpret_cast<const BYTE*>(odd_diff ? dither2x2a_data_sse2 : dither2x2_data_sse2); break;\n  case 2: matrix = reinterpret_cast<const BYTE*>(odd_diff ? dither4x4a_data_sse2 : dither4x4_data_sse2); break;\n  case 3: matrix = reinterpret_cast<const BYTE*>(odd_diff ? dither8x8a_data_sse2 : dither8x8_data_sse2); break;\n  case 4: matrix = reinterpret_cast<const BYTE*>(odd_diff ? dither16x16a_data : dither16x16_data); break; // no spec sse, already 16 bytes long\n  default: return; // n/a\n  }\n\n  const int bitdiff_between_dither_and_target = target_bitdepth - dither_target_bitdepth;\n  assert(TEMPLATE_NEED_BACKSCALE == (target_bitdepth != dither_target_bitdepth));  // dither to x, target to y\n\n  assert(TEMPLATE_LOW_DITHER_BITDEPTH == (dither_target_bitdepth < 8));\n  // e.g. instead of 0,1 => -0.5,+0.5;  0,1,2,3 => -1.5,-0.5,0.5,1.5\n  const float half_maxcorr_value = ((1 << dither_bit_diff) - 1) / 2.0f;\n\n  const int source_max = (1 << source_bitdepth) - 1;\n  //-----------------------\n  // When calculating src_pixel, src and dst are of the same bit depth\n  bits_conv_constants d;\n  get_bits_conv_constants(d, chroma, fulls, fulld, source_bitdepth, source_bitdepth); // both is src_bitdepth\n\n  auto dst_offset_plus_round = d.dst_offset + 0.5f;\n  constexpr auto src_pixel_min = 0;\n  const auto src_pixel_max = source_max;\n  const float mul_factor_backfromlowdither = (float)max_pixel_value_target / max_pixel_value_dithered;\n  //-----------------------\n\n  const auto mul_factor_simd = _mm_set1_ps(d.mul_factor);\n  const auto mul_factor_backfromlowdither_simd = _mm_set1_ps(mul_factor_backfromlowdither);\n  const auto half_maxcorr_value_simd = _mm_set1_ps(half_maxcorr_value);\n  const auto zero = _mm_setzero_si128();\n  const BYTE* matrix_simd16 = matrix;\n  const BYTE* current_matrix_line;\n\n  for (int y = 0; y < src_height; y++)\n  {\n   // int _y = (y & dither_mask) << dither_order; // for C version\n    current_matrix_line = matrix_simd16 + ((y & dither_mask) << 4); // always 16 byte boundary instead of dither order\n    __m128i corr = _mm_load_si128(reinterpret_cast<const __m128i*>(current_matrix_line)); // int corr = matrix[_y | (x & dither_mask)];\n    // convert corr to 16 bit\n    __m128i corr_lo = _mm_unpacklo_epi8(corr, zero);\n    __m128i corr_hi = _mm_unpackhi_epi8(corr, zero);\n\n    for (int x = 0; x < src_width; x += 16)\n    {\n      //const int corr = matrix[_y | (x & dither_mask)];\n\n      //int src_pixel = srcp[x];\n      __m128i src_lo, src_hi;\n      if constexpr (sizeof(pixel_t_s) == 1) {\n        auto src = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x)); // 16* uint8\n        src_lo = _mm_unpacklo_epi8(src, zero); // 8* uint16\n        src_hi = _mm_unpackhi_epi8(src, zero); // 8* uint16\n      }\n      else {\n        src_lo = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x)); // 8* uint16\n        src_hi = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x + 8));\n      }\n\n      [[maybe_unused]] __m128i src_lo_lo;\n      [[maybe_unused]] __m128i src_lo_hi;\n      [[maybe_unused]] __m128i src_hi_lo;\n      [[maybe_unused]] __m128i src_hi_hi;\n      if constexpr (fulls != fulld) {\n        // goint to 32 float\n        // const float val = (srcp[x] - src_offset) * mul_factor + dst_offset_plus_round;\n        const auto src_offset_simd = _mm_set1_epi32(d.src_offset_i);\n        const auto dst_offset_plus_round_simd = _mm_set1_ps(dst_offset_plus_round);\n\n        auto src_lo_lo_ps = _mm_cvtepi32_ps(_mm_sub_epi32(_mm_unpacklo_epi16(src_lo, zero), src_offset_simd));\n        auto src_lo_hi_ps = _mm_cvtepi32_ps(_mm_sub_epi32(_mm_unpackhi_epi16(src_lo, zero), src_offset_simd));\n        src_lo_lo_ps = _mm_add_ps(_mm_mul_ps(src_lo_lo_ps, mul_factor_simd), dst_offset_plus_round_simd);\n        src_lo_hi_ps = _mm_add_ps(_mm_mul_ps(src_lo_hi_ps, mul_factor_simd), dst_offset_plus_round_simd);\n\n        auto src_hi_lo_ps = _mm_cvtepi32_ps(_mm_sub_epi32(_mm_unpacklo_epi16(src_hi, zero), src_offset_simd));\n        auto src_hi_hi_ps = _mm_cvtepi32_ps(_mm_sub_epi32(_mm_unpackhi_epi16(src_hi, zero), src_offset_simd));\n        src_hi_lo_ps = _mm_add_ps(_mm_mul_ps(src_hi_lo_ps, mul_factor_simd), dst_offset_plus_round_simd);\n        src_hi_hi_ps = _mm_add_ps(_mm_mul_ps(src_hi_hi_ps, mul_factor_simd), dst_offset_plus_round_simd);\n\n        // src_pixel = clamp((int)val, src_pixel_min, src_pixel_max);\n        if constexpr (sizeof(pixel_t_s) == 1 && !TEMPLATE_LOW_DITHER_BITDEPTH) {\n          // Source is 8 bits. This branch is ineffective if we define TEMPLATE_LOW_DITHER_BITDEPTH for all <8 bits, as we do now\n          // We would reach this code for 5-7 bits when lo limit would be e.g. 4 bits\n          // 8 bit source: we can go back from 32 to 16 bit int\n          src_lo = _mm_packus_epi32(_mm_cvttps_epi32(src_lo_lo_ps), _mm_cvttps_epi32(src_lo_hi_ps));\n          src_hi = _mm_packus_epi32(_mm_cvttps_epi32(src_hi_lo_ps), _mm_cvttps_epi32(src_hi_hi_ps));\n          // 0 min is ensured by packus\n          const auto src_pixel_max_simd = _mm_set1_epi16(src_pixel_max);\n          src_lo = _mm_min_epu16(src_lo, src_pixel_max_simd);\n          src_hi = _mm_min_epu16(src_hi, src_pixel_max_simd);\n          // tmp result 16 bits in src_lo, src_hi\n        }\n        else {\n          // go back to int32 only\n          src_lo_lo = _mm_cvttps_epi32(src_lo_lo_ps);\n          src_lo_hi = _mm_cvttps_epi32(src_lo_hi_ps);\n          src_hi_lo = _mm_cvttps_epi32(src_hi_lo_ps);\n          src_hi_hi = _mm_cvttps_epi32(src_hi_hi_ps);\n\n          // no packus to ensure min 0\n          const auto src_pixel_min_simd = _mm_set1_epi32(src_pixel_min);\n          src_lo_lo = _mm_max_epi32(src_lo_lo, src_pixel_min_simd);\n          src_lo_hi = _mm_max_epi32(src_lo_hi, src_pixel_min_simd);\n          src_hi_lo = _mm_max_epi32(src_hi_lo, src_pixel_min_simd);\n          src_hi_hi = _mm_max_epi32(src_hi_hi, src_pixel_min_simd);\n\n          const auto src_pixel_max_simd = _mm_set1_epi32(src_pixel_max);\n          src_lo_lo = _mm_min_epi32(src_lo_lo, src_pixel_max_simd);\n          src_lo_hi = _mm_min_epi32(src_lo_hi, src_pixel_max_simd);\n          src_hi_lo = _mm_min_epi32(src_hi_lo, src_pixel_max_simd);\n          src_hi_hi = _mm_min_epi32(src_hi_hi, src_pixel_max_simd);\n          // tmp result 32 bits in src_lo_lo, src_lo_hi, src_hi_lo, src_hi_hi\n        }\n      }\n      else {\n        // 10-16 bits: go into 32 bit int\n        if constexpr (sizeof(pixel_t_s) == 2 || TEMPLATE_LOW_DITHER_BITDEPTH) {\n          src_lo_lo = _mm_unpacklo_epi16(src_lo, zero);\n          src_lo_hi = _mm_unpackhi_epi16(src_lo, zero);\n          src_hi_lo = _mm_unpacklo_epi16(src_hi, zero);\n          src_hi_hi = _mm_unpackhi_epi16(src_hi, zero);\n          // tmp result 32 bits in src_lo_lo, src_lo_hi, src_hi_lo, src_hi_hi\n        }\n      }\n\n      __m128i new_pixel_lo, new_pixel_hi;\n\n      // scale down after adding dithering noise\n      // int new_pixel = ((src_pixel + corr) >> dither_bit_diff);\n      if constexpr (sizeof(pixel_t_s) == 1 && !TEMPLATE_LOW_DITHER_BITDEPTH) {\n        new_pixel_lo = _mm_srai_epi16(_mm_add_epi16(src_lo, corr_lo), dither_bit_diff);\n        new_pixel_hi = _mm_srai_epi16(_mm_add_epi16(src_hi, corr_hi), dither_bit_diff);\n        // new_pixel_lo/hi is ready with 16 bit data\n      }\n      else { \n        // source bits: >8 or 8 bit but PRESHIFT\n        // At 16 bit overflow can happen when 0xFFFF it dithered up. This is why we are at 32 bits int\n        // Theoretically fulls == fulld && <16 bit would allow 16 bit int workflow but we do not specialize for that\n        // low dither bitdepth is special as well\n\n        /*\n        int new_pixel;\n        if (TEMPLATE_LOW_DITHER_BITDEPTH) {\n          // accurate dither: +/-\n          const float corr_f = corr - half_maxcorr_value;\n          new_pixel = (int)(src_pixel + corr_f) >> dither_bit_diff;\n        }\n        else\n          new_pixel = ((src_pixel + corr) >> dither_bit_diff);\n        */\n        __m128i new_pixel_lo_lo, new_pixel_lo_hi, new_pixel_hi_lo, new_pixel_hi_hi;\n        auto corr_lo_lo = _mm_unpacklo_epi16(corr_lo, zero);\n        auto corr_lo_hi = _mm_unpackhi_epi16(corr_lo, zero);\n        auto corr_hi_lo = _mm_unpacklo_epi16(corr_hi, zero);\n        auto corr_hi_hi = _mm_unpackhi_epi16(corr_hi, zero);\n        if constexpr(TEMPLATE_LOW_DITHER_BITDEPTH) {\n          // accurately positioned to the center\n          auto corr_lo_lo_ps = _mm_sub_ps(_mm_cvtepi32_ps(corr_lo_lo), half_maxcorr_value_simd);\n          auto corr_lo_hi_ps = _mm_sub_ps(_mm_cvtepi32_ps(corr_lo_hi), half_maxcorr_value_simd);\n          auto corr_hi_lo_ps = _mm_sub_ps(_mm_cvtepi32_ps(corr_hi_lo), half_maxcorr_value_simd);\n          auto corr_hi_hi_ps = _mm_sub_ps(_mm_cvtepi32_ps(corr_hi_hi), half_maxcorr_value_simd);\n          // accurate dither: +/-\n          new_pixel_lo_lo = _mm_srai_epi32(_mm_cvttps_epi32(_mm_add_ps(_mm_cvtepi32_ps(src_lo_lo), corr_lo_lo_ps)), dither_bit_diff);\n          new_pixel_lo_hi = _mm_srai_epi32(_mm_cvttps_epi32(_mm_add_ps(_mm_cvtepi32_ps(src_lo_hi), corr_lo_hi_ps)), dither_bit_diff);\n          new_pixel_hi_lo = _mm_srai_epi32(_mm_cvttps_epi32(_mm_add_ps(_mm_cvtepi32_ps(src_hi_lo), corr_hi_lo_ps)), dither_bit_diff);\n          new_pixel_hi_hi = _mm_srai_epi32(_mm_cvttps_epi32(_mm_add_ps(_mm_cvtepi32_ps(src_hi_hi), corr_hi_hi_ps)), dither_bit_diff);\n        }\n        else {\n          // Arrgh. If dither_bit_diff would be an immediate constant (e.g. template parameter) then we get 2390 fps vs 1378!\n          // for a simple Vide16bit.ConvertBits(8, dither=0, dither_bits=8)\n          // const auto dither_bit_diff = 8;\n          new_pixel_lo_lo = _mm_srai_epi32(_mm_add_epi32(src_lo_lo, corr_lo_lo), dither_bit_diff);\n          new_pixel_lo_hi = _mm_srai_epi32(_mm_add_epi32(src_lo_hi, corr_lo_hi), dither_bit_diff);\n          new_pixel_hi_lo = _mm_srai_epi32(_mm_add_epi32(src_hi_lo, corr_hi_lo), dither_bit_diff);\n          new_pixel_hi_hi = _mm_srai_epi32(_mm_add_epi32(src_hi_hi, corr_hi_hi), dither_bit_diff);\n        }\n        new_pixel_lo = _mm_packus_epi32(new_pixel_lo_lo, new_pixel_lo_hi);\n        new_pixel_hi = _mm_packus_epi32(new_pixel_hi_lo, new_pixel_hi_hi);\n        // new_pixel_lo/hi is ready with 16 bit data\n      }\n\n      // scale back to the required bit depth\n       // dither to x, target to y\n      if constexpr (TEMPLATE_NEED_BACKSCALE) {\n        /*\n        new_pixel = min(new_pixel, max_pixel_value_dithered);\n        if (TEMPLATE_LOW_DITHER_BITDEPTH) {\n          new_pixel = (int)(new_pixel * mul_factor_backfromlowdither + 0.5f);\n        }\n        else {\n          new_pixel = new_pixel << bitdiff_between_dither_and_target;\n        }\n        */\n        const auto max_pixel_value_dithered_simd = _mm_set1_epi16(max_pixel_value_dithered);\n        new_pixel_lo = _mm_min_epu16(new_pixel_lo, max_pixel_value_dithered_simd);\n        new_pixel_hi = _mm_min_epu16(new_pixel_hi, max_pixel_value_dithered_simd);\n        // Interesting problem of dither_bits==1 (or in general at small dither_bits)\n        // After simple slli 0,1 becomes 0,128, we'd expect 0,255 instead. So we make cosmetics.\n        // dither_bits\n        // 1            0,1     => 0,128        => 0,255\n        // 2            0,1,2,3 => 0,64,128,192 => 0,?,?,255\n        // 3            0,...,7 => 0,32,...,224 => 0,?,?,255\n        // 4            0,..,15 => 0,16,...,240 => 0,?,?,255\n        // 5            0,..,31 => 0,8,....,248 => 0,?,?,255\n        // 6            0,..,63 => 0,4,....,252 => 0,?,?,255\n        // 7            0,.,127 => 0,2.  ..,254 => 0,?,?,255\n        if constexpr(TEMPLATE_LOW_DITHER_BITDEPTH) {\n          // new_pixel = (int)(new_pixel * mul_factor_backfromlowdither + 0.5f);\n          auto rounder_half_simd = _mm_set1_ps(0.5f);\n\n          auto new_pixel_lo_lo_ps = _mm_cvtepi32_ps(_mm_unpacklo_epi16(new_pixel_lo, zero));\n          auto new_pixel_lo_hi_ps = _mm_cvtepi32_ps(_mm_unpackhi_epi16(new_pixel_lo, zero));\n          new_pixel_lo = _mm_packus_epi32(\n            _mm_cvttps_epi32(_mm_add_ps(_mm_mul_ps(new_pixel_lo_lo_ps, mul_factor_backfromlowdither_simd), rounder_half_simd)),\n            _mm_cvttps_epi32(_mm_add_ps(_mm_mul_ps(new_pixel_lo_hi_ps, mul_factor_backfromlowdither_simd), rounder_half_simd))\n          );\n          auto new_pixel_hi_lo_ps = _mm_cvtepi32_ps(_mm_unpacklo_epi16(new_pixel_hi, zero));\n          auto new_pixel_hi_hi_ps = _mm_cvtepi32_ps(_mm_unpackhi_epi16(new_pixel_hi, zero));\n          new_pixel_hi = _mm_packus_epi32(\n            _mm_cvttps_epi32(_mm_add_ps(_mm_mul_ps(new_pixel_hi_lo_ps, mul_factor_backfromlowdither_simd), rounder_half_simd)),\n            _mm_cvttps_epi32(_mm_add_ps(_mm_mul_ps(new_pixel_hi_hi_ps, mul_factor_backfromlowdither_simd), rounder_half_simd))\n          );\n        }\n        else {\n          new_pixel_lo = _mm_slli_epi16(new_pixel_lo, bitdiff_between_dither_and_target);\n          new_pixel_hi = _mm_slli_epi16(new_pixel_hi, bitdiff_between_dither_and_target);\n        }\n      }\n\n      // dstp[x] = (pixel_t_d)(min((int)new_pixel, max_pixel_value_target));\n      if constexpr(sizeof(pixel_t_d) == 1)\n      {\n        auto result = _mm_packus_epi16(new_pixel_lo, new_pixel_hi);\n        _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x), result);\n      }\n      else {\n        const auto max_pixel_value_target_simd = _mm_set1_epi16(max_pixel_value_target);\n        // max is unnecessary for exact 16 bit pixel type but we are not specialized for that case\n        new_pixel_lo = _mm_min_epu16(new_pixel_lo, max_pixel_value_target_simd);\n        new_pixel_hi = _mm_min_epu16(new_pixel_hi, max_pixel_value_target_simd);\n        _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x), new_pixel_lo);\n        _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x + 8), new_pixel_hi);\n      }\n    }\n    dstp += dst_pitch;\n    srcp += src_pitch;\n  }\n}\n\ntemplate<typename pixel_t_s, typename pixel_t_d, bool chroma, bool fulls, bool fulld>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid convert_ordered_dither_uint_sse41(const BYTE* srcp8, BYTE* dstp8, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth)\n{\n  const bool need_backscale = target_bitdepth != dither_target_bitdepth; // dither to x, target to y\n  const bool low_dither_bitdepth = dither_target_bitdepth < 8; // 1-7 bits dither targets, need_backscale is always true, since 8 bit format is the minimum\n  if (need_backscale) {\n    if (low_dither_bitdepth)\n      do_convert_ordered_dither_uint_sse41<pixel_t_s, pixel_t_d, chroma, fulls, fulld, true, true>(srcp8, dstp8, src_rowsize, src_height, src_pitch, dst_pitch, source_bitdepth, target_bitdepth, dither_target_bitdepth);\n    else\n    do_convert_ordered_dither_uint_sse41<pixel_t_s, pixel_t_d, chroma, fulls, fulld, true, false>(srcp8, dstp8, src_rowsize, src_height, src_pitch, dst_pitch, source_bitdepth, target_bitdepth, dither_target_bitdepth);\n  }\n  else {\n    do_convert_ordered_dither_uint_sse41<pixel_t_s, pixel_t_d, chroma, fulls, fulld, false, false>(srcp8, dstp8, src_rowsize, src_height, src_pitch, dst_pitch, source_bitdepth, target_bitdepth, dither_target_bitdepth);\n  }\n}\n\n// instantiate them all\n// template<typename pixel_t_s, typename pixel_t_d, bool chroma, bool fulls, bool fulld>\n// spec: fulld=false, fulls=false\n#define convert_ordered_dither_uint_sse4_functions(uint_X_t, uint_X_dest_t) \\\ntemplate void convert_ordered_dither_uint_sse41<uint_X_t, uint_X_dest_t, false, false, false>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_ordered_dither_uint_sse41<uint_X_t, uint_X_dest_t, false, false, true>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_ordered_dither_uint_sse41<uint_X_t, uint_X_dest_t, false, true, false>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_ordered_dither_uint_sse41<uint_X_t, uint_X_dest_t, false, true, true>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_ordered_dither_uint_sse41<uint_X_t, uint_X_dest_t, true, false, false>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_ordered_dither_uint_sse41<uint_X_t, uint_X_dest_t, true, false, true>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_ordered_dither_uint_sse41<uint_X_t, uint_X_dest_t, true, true, false>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth); \\\ntemplate void convert_ordered_dither_uint_sse41<uint_X_t, uint_X_dest_t, true, true, true>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\n\n// dither only same of less bit depth\nconvert_ordered_dither_uint_sse4_functions(uint8_t, uint8_t)\nconvert_ordered_dither_uint_sse4_functions(uint16_t, uint8_t)\nconvert_ordered_dither_uint_sse4_functions(uint16_t, uint16_t)\n\n#undef convert_ordered_dither_uint_sse4_functions\n\n\n"
  },
  {
    "path": "avs_core/convert/intel/convert_bits_sse.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Convert_bits_sse_H__\n#define __Convert_bits_sse_H__\n\n#include <avs/types.h>\n\ntemplate<typename pixel_t, bool chroma, bool fulls, bool fulld>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid convert_32_to_uintN_sse41(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\n\ntemplate<typename pixel_t_s, typename pixel_t_d, bool chroma, bool fulls, bool fulld>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid convert_uint_sse41(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\n\ntemplate<typename pixel_t_s, typename pixel_t_d, bool chroma, bool fulls, bool fulld>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid convert_ordered_dither_uint_sse41(const BYTE* srcp8, BYTE* dstp8, int src_rowsize, int src_height, int src_pitch, int dst_pitch, int source_bitdepth, int target_bitdepth, int dither_target_bitdepth);\n\n#endif  // __Convert_bits_sse_H__\n"
  },
  {
    "path": "avs_core/convert/intel/convert_planar_avx2.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include <avs/alignment.h>\n#ifdef _MSC_VER\n    #include <intrin.h>\n#else\n    #include <x86intrin.h>\n#endif\n#include <immintrin.h>\n\n#include \"convert_planar_avx2.h\"\n#include \"../convert_planar.h\"\n#include \"../convert_helper.h\"\n\n#ifndef _mm256_set_m128i\n#define _mm256_set_m128i(v0, v1) _mm256_insertf128_si256(_mm256_castsi128_si256(v1), (v0), 1)\n#endif\n\nDISABLE_WARNING_PUSH\nDISABLE_WARNING_UNREFERENCED_LOCAL_VARIABLE\n\n// packed rgb helper\nstatic AVS_FORCEINLINE __m256i convert_yuv_to_rgb_avx2_core(const __m256i& px0189, const __m256i& px23AB, const __m256i& px45CD, const __m256i& px67EF, const __m256i& zero, const __m256i& matrix, const __m256i& round_mask_plus_rgb_offset) {\n  //int b = (((int)m[0] * Y + (int)m[1] * U + (int)m[ 2] * V + 4096 + rgb_offset)>>13);\n\n  //px01 - xx xx 00 V1 00 U1 00 Y1 xx xx 00 V0 00 U0 00 Y0\n\n  auto low_lo = _mm256_madd_epi16(px0189, matrix); //xx*0 + v1*m2 | u1*m1 + y1*m0 | xx*0 + v0*m2 | u0*m1 + y0*m0\n  auto low_hi = _mm256_madd_epi16(px23AB, matrix); //xx*0 + v3*m2 | u3*m1 + y3*m0 | xx*0 + v2*m2 | u2*m1 + y2*m0\n  auto high_lo = _mm256_madd_epi16(px45CD, matrix);\n  auto high_hi = _mm256_madd_epi16(px67EF, matrix);\n\n  auto low_v = _mm256_castps_si256(_mm256_shuffle_ps(_mm256_castsi256_ps(low_lo), _mm256_castsi256_ps(low_hi), _MM_SHUFFLE(3, 1, 3, 1))); // v3*m2 | v2*m2 | v1*m2 | v0*m2\n  auto high_v = _mm256_castps_si256(_mm256_shuffle_ps(_mm256_castsi256_ps(high_lo), _mm256_castsi256_ps(high_hi), _MM_SHUFFLE(3, 1, 3, 1)));\n\n  auto low_yu = _mm256_castps_si256(_mm256_shuffle_ps(_mm256_castsi256_ps(low_lo), _mm256_castsi256_ps(low_hi), _MM_SHUFFLE(2, 0, 2, 0))); // u3*m1 + y3*m0 | u2*m1 + y2*m0 | u1*m1 + y1*m0 | u0*m1 + y0*m0\n  auto high_yu = _mm256_castps_si256(_mm256_shuffle_ps(_mm256_castsi256_ps(high_lo), _mm256_castsi256_ps(high_hi), _MM_SHUFFLE(2, 0, 2, 0)));\n\n  auto t_lo = _mm256_add_epi32(low_v, low_yu); // v3*m2 + u3*m1 + y3*m0...\n  auto t_hi = _mm256_add_epi32(high_v, high_yu);\n\n  // v3*m2 + u3*m1 + y3*m0 + 4096 + rgb_offset\n  t_lo = _mm256_add_epi32(t_lo, round_mask_plus_rgb_offset);\n  t_hi = _mm256_add_epi32(t_hi, round_mask_plus_rgb_offset);\n\n  t_lo = _mm256_srai_epi32(t_lo, 13); // (v3*m2 + u3*m1 + y3*m0 + 4096) >> 13...\n  t_hi = _mm256_srai_epi32(t_hi, 13);\n\n  auto result = _mm256_packs_epi32(t_lo, t_hi);\n  result = _mm256_packus_epi16(result, zero); //00 00 00 00 00 00 00 00 b15 b14 b14 b12 b11 b10 b9 b8 00 00 00 00 00 00 00 00 b7 b6 b5 b4 b3 b2 b1 b0\n  return result;\n}\n\ntemplate<int rgb_pixel_step, bool hasAlpha>\nvoid convert_yv24_to_rgb_avx2(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE* srcV, const BYTE* srcA, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t src_pitch_a, size_t width, size_t height, const ConversionMatrix& matrix)\n{\n  dstp += dst_pitch * (height - 1);  // We start at last line\n\n  size_t mod16_width = rgb_pixel_step == 3 ? width / 16 * 16 : width;\n  // for rgb32 target we can process pixels beyond width, but we have 64bit alignment at target 16 pixels to 16*4=64 rgb pixels\n  // if alignment would only be 32 bytes, we'd do the last cycle to process only 8 source pixels\n\n  auto matrix_b = _mm256_set_epi16(0, matrix.v_b, matrix.u_b, matrix.y_b, 0, matrix.v_b, matrix.u_b, matrix.y_b, 0, matrix.v_b, matrix.u_b, matrix.y_b, 0, matrix.v_b, matrix.u_b, matrix.y_b);\n  auto matrix_g = _mm256_set_epi16(0, matrix.v_g, matrix.u_g, matrix.y_g, 0, matrix.v_g, matrix.u_g, matrix.y_g, 0, matrix.v_g, matrix.u_g, matrix.y_g, 0, matrix.v_g, matrix.u_g, matrix.y_g);\n  auto matrix_r = _mm256_set_epi16(0, matrix.v_r, matrix.u_r, matrix.y_r, 0, matrix.v_r, matrix.u_r, matrix.y_r, 0, matrix.v_r, matrix.u_r, matrix.y_r, 0, matrix.v_r, matrix.u_r, matrix.y_r);\n\n  auto zero128 = _mm_setzero_si128();\n  auto zero = _mm256_setzero_si256();\n\n  // .13 bit frac integer arithmetic\n  int round_mask_plus_rgb_offset_i = (1 << 12) + (matrix.offset_rgb << 13);\n  auto round_mask_plus_rgb_offset = _mm256_set1_epi32(round_mask_plus_rgb_offset_i);\n  auto offset = _mm256_set_epi16(0, -128, -128, matrix.offset_y, 0, -128, -128, matrix.offset_y, 0, -128, -128, matrix.offset_y, 0, -128, -128, matrix.offset_y);\n\n  // 16 YUV(A) pixels --> 4x16 RGB quads = 64 bytes. Avisynth's alignment is 64 fortunately.\n\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < mod16_width; x += 16) {\n      __m128i src_y = _mm_load_si128(reinterpret_cast<const __m128i*>(srcY + x)); //Y15 .. Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0\n      __m128i src_u = _mm_load_si128(reinterpret_cast<const __m128i*>(srcU + x)); //U15 .. U7 U6 U5 U4 U3 U2 U1 U0\n      __m128i src_v = _mm_load_si128(reinterpret_cast<const __m128i*>(srcV + x)); //V15 .. V7 V6 V5 V4 V3 V2 V1 V0\n      [[maybe_unused]] __m128i src_a;\n      if constexpr(hasAlpha)\n        src_a = _mm_load_si128(reinterpret_cast<const __m128i*>(srcA + x)); //A15 .. A7 A6 A5 A4 A3 A2 A1 A0\n\n      __m128i t1_lo = _mm_unpacklo_epi8(src_y, src_u); //U7 Y7 U6 Y6 U5 Y5 U4 Y4 U3 Y3 U2 Y2 U1 Y1 U0 Y0\n      __m128i t1_hi = _mm_unpackhi_epi8(src_y, src_u); //U15 Y15 U14 Y14 U13 Y13 U12 Y12 U11 Y11 U10 Y10 U9 Y9 U8 Y8\n      __m128i t2_lo = _mm_unpacklo_epi8(src_v, zero128);  //00 V7 00 V6 00 V5 00 V4 00 V3 00 V2 00 V1 00 V0\n      __m128i t2_hi = _mm_unpackhi_epi8(src_v, zero128);  //00 V15 00 V14 00 V13 00 V12 00 V11 00 V10 00 V9 00 V8\n\n      __m256i t1 = _mm256_set_m128i(t1_hi, t1_lo);\n      __m256i t2 = _mm256_set_m128i(t2_hi, t2_lo);\n      t1 = _mm256_permute4x64_epi64(t1, (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6));\n      t2 = _mm256_permute4x64_epi64(t2, (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6));\n\n      __m256i low = _mm256_unpacklo_epi16(t1, t2); //xx V11 U11 Y11 xx V10 U10 Y10 xx V9 U9 Y9 xx V8 U8 Y8    xx V3 U3 Y3 xx V2 U2 Y2 xx V1 U1 Y1 xx V0 U0 Y0\n      __m256i high = _mm256_unpackhi_epi16(t1, t2); //xx V15 U15 Y15 xx V14 U14 Y14 xx V13 U13 Y13 xx V12 U12 Y12    xx V7 U7 Y7 xx V6 U6 Y6 xx V5 U5 Y5 xx V4 U4 Y4\n\n      __m256i px0189 = _mm256_unpacklo_epi8(low, zero);  //xx xx 00 V1 00 U1 00 Y1 xx xx 00 V0 00 U0 00 Y0\n      __m256i px23AB = _mm256_unpackhi_epi8(low, zero);  //xx xx 00 V3 00 U3 00 Y3 xx xx 00 V2 00 U2 00 Y2\n      __m256i px45CD = _mm256_unpacklo_epi8(high, zero); //xx xx 00 V5 00 U5 00 Y5 xx xx 00 V4 00 U4 00 Y4\n      __m256i px67EF = _mm256_unpackhi_epi8(high, zero); //xx xx 00 V7 00 U7 00 Y7 xx xx 00 V6 00 U6 00 Y6\n\n      px0189 = _mm256_add_epi16(px0189, offset);\n      px23AB = _mm256_add_epi16(px23AB, offset);\n      px45CD = _mm256_add_epi16(px45CD, offset);\n      px67EF = _mm256_add_epi16(px67EF, offset);\n\n      __m256i result_b = convert_yuv_to_rgb_avx2_core(px0189, px23AB, px45CD, px67EF, zero, matrix_b, round_mask_plus_rgb_offset); // b15..0\n      __m256i result_g = convert_yuv_to_rgb_avx2_core(px0189, px23AB, px45CD, px67EF, zero, matrix_g, round_mask_plus_rgb_offset); // g15..0\n      __m256i result_r = convert_yuv_to_rgb_avx2_core(px0189, px23AB, px45CD, px67EF, zero, matrix_r, round_mask_plus_rgb_offset); // r15..0\n\n      __m256i result_bg = _mm256_unpacklo_epi8(result_b, result_g); //g15 b15 g14 b14 g13 b13 g12 b12 g11 b11 g10 b10 g9 b9 g8 b8 | g7 b7 g6 b6 g5 b5 g4 b4 g3 b3 g2 b2 g1 b1 g0 b0\n      __m256i alpha;\n      if constexpr(hasAlpha) {\n        __m128i a_lo = _mm_unpacklo_epi8(src_a, zero128);  //00 A7 00 A6 00 A5 00 A4 00 A3 00 A2 00 A1 00 A0\n        __m128i a_hi = _mm_unpackhi_epi8(src_a, zero128);  //00 A15 00 A14 00 A13 00 A12 00 A11 00 A10 00 A9 00 A8\n        alpha = _mm256_set_m128i(a_hi, a_lo); // a15 .. a0  at low of each m128i part\n        alpha = _mm256_permute4x64_epi64(alpha, (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6));\n      }\n      else\n        alpha = _mm256_cmpeq_epi32(result_r, result_r); // FF FF FF FF ... default alpha transparent\n\n      __m256i result_ra = _mm256_unpacklo_epi8(result_r, alpha);       //a7 r7 a6 r6 a5 r5 a4 r4 a3 r3 a2 r2 a1 r1 a0 r0\n\n      __m256i result_lo = _mm256_unpacklo_epi16(result_bg, result_ra); // a11 r11 g11 b11 | a10 r10 g10 b10 | a9 r9 g9 b9 | a8 r8 g8 b8  |   a3 r3 g3 b3 | a2 r2 g2 b2 | a1 r1 g1 b1 | a0 r0 g0 b0\n      __m256i result_hi = _mm256_unpackhi_epi16(result_bg, result_ra);\n      // note: actual pixel indexes are different from the numbers in comments, they are kept to be follow more easily\n      // Initial _mm256_permute4x64_epi64 ensures that the order here is properly argb7..argb0 and argb15..argb8\n\n      if constexpr (rgb_pixel_step == 4) {\n        //rgb32\n        _mm256_store_si256(reinterpret_cast<__m256i*>(dstp + x * 4), result_lo);\n        _mm256_store_si256(reinterpret_cast<__m256i*>(dstp + x * 4 + 32), result_hi);\n      }\n      else {\n        // rgb24\n        // 16*4 bytes to 16*3 bytes\n        __m256i perm10 = _mm256_set_epi32(0, 0, 6, 5, 4, 2, 1, 0);\n        __m256i shuffle_lo = _mm256_set_epi8(\n            0, 0, 0, 0, 14, 13, 12, 10, 9, 8, 6, 5, 4, 2, 1, 0,\n            0, 0, 0, 0, 14, 13, 12, 10, 9, 8, 6, 5, 4, 2, 1, 0\n        );\n        __m128i shuffle_hi_lo = _mm_set_epi8(9, 8, 6, 5,  4,  2,  1,  0, 0, 0, 0, 0, 0, 0, 0, 0);\n\n        __m128i result_hi_lo = _mm256_extracti128_si256(result_hi, 0); // aBbBgBrB aAbAgArA a9b9g9r9 a8b8g8r8\n        __m128i result_hi_hi = _mm256_extracti128_si256(result_hi, 1); // aFbFgFrF aEbEgErE aDbDgDrD aCbCgCrC\n        \n        __m256i result_lo_reorg = _mm256_shuffle_epi8(result_lo, shuffle_lo);\n        // x  x  x  x  b7g7r7 b6g6r6 b5g5r5 b4g4r4 x  x  x  x  b3g3r3 b2g2r2 b1g1r1 b0g0r0\n        result_lo_reorg = _mm256_permutevar8x32_epi32(result_lo_reorg, perm10);\n        // x  x  x  x  x x x x b7g7r7 b6g6r6 b5g5r5 b4g4r4 b3g3r3 b2g2r2 b1g1r1 b0g0r0\n\n        __m128i result_hi_lo_reorg = _mm_shuffle_epi8(result_hi_lo, shuffle_hi_lo);\n        // gA rA b9 g9 r9 b8 g8 r8 x x x x x x x x\n\n        __m256i dummy_y0 = _mm256_undefined_si256();\n        auto result_hi_lo_reorg_2 = _mm256_inserti128_si256(dummy_y0, result_hi_lo_reorg, 1);\n        //                                                                      \n        // gA rA b9 g9|r9 b8 g8 r8|x x x  x|x x  x x|x  x x x |x x x  x|x x  x x|x  x x x   // result_hi_lo_reorg_2\n        // x  x  x  x  x  x  x  x  b7g7r7 b6g6r6 b5g5r5 b4g4r4 b3g3r3 b2g2r2 b1g1r1 b0g0r0  // result_lo_reorg\n        auto result_0_15 = _mm256_blend_epi32(result_lo_reorg, result_hi_lo_reorg_2, 0xC0); // 11000000\n        _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + x * 3), result_0_15); // not necessarily 32 bytes aligned\n\n        // => x  x  x  x  x  x  x  x  x  x  x  x  bB gB rB bA\n        __m128i shuffle_hi_lo_2 = _mm_set_epi8((char)0x80, (char)0x80, (char)0x80, (char)0x80, (char)0x80, (char)0x80, (char)0x80, (char)0x80, (char)0x80, (char)0x80, (char)0x80, (char)0x80, 14, 13, 12, 10);\n        __m128i xmm4 = _mm_shuffle_epi8(result_hi_lo, shuffle_hi_lo_2);\n\n        // => bF gF rF bE gE rE bD gD rD bC gC rC x  x  x  x\n        __m128i shuffle_hi_hi = _mm_set_epi8(14, 13, 12, 10, 9, 8, 6, 5, 4, 2, 1, 0, (char)0x80, (char)0x80, (char)0x80, (char)0x80);\n        __m128i xmm5 = _mm_shuffle_epi8(result_hi_hi, shuffle_hi_hi);\n\n        // => bF gF rF bE gE rE bD gD rD bC gC rC bB gB rB bA\n        __m128i result_16_23 = _mm_or_si128(xmm4, xmm5);\n        _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x * 3 + 32), result_16_23);\n#if 0\n        // Intel compiler can cope with it 100% optimized. No store, just shuffles and blends as above.\n        alignas(32) BYTE temp[64];\n        _mm256_store_si256(reinterpret_cast<__m256i*>(temp), result_lo);\n        _mm256_store_si256(reinterpret_cast<__m256i*>(temp + 32), result_hi);\n        for (int i = 0; i < 16; ++i) {\n          dstp[(x + i) * 3 + 0] = temp[i * 4 + 0];\n          dstp[(x + i) * 3 + 1] = temp[i * 4 + 1];\n          dstp[(x + i) * 3 + 2] = temp[i * 4 + 2];\n        }\n#endif\n      }\n    }\n\n    if constexpr (rgb_pixel_step == 3) {\n      // for rgb32 (pixel_step == 4) we processed full width and more, including padded bytes\n      for (size_t x = mod16_width; x < width; ++x) {\n        int Y = srcY[x] + matrix.offset_y;\n        int U = srcU[x] - 128;\n        int V = srcV[x] - 128;\n        int b = (((int)matrix.y_b * Y + (int)matrix.u_b * U + (int)matrix.v_b * V + round_mask_plus_rgb_offset_i) >> 13);\n        int g = (((int)matrix.y_g * Y + (int)matrix.u_g * U + (int)matrix.v_g * V + round_mask_plus_rgb_offset_i) >> 13);\n        int r = (((int)matrix.y_r * Y + (int)matrix.u_r * U + (int)matrix.v_r * V + round_mask_plus_rgb_offset_i) >> 13);\n        dstp[x * rgb_pixel_step + 0] = PixelClip(b);\n        dstp[x * rgb_pixel_step + 1] = PixelClip(g);\n        dstp[x * rgb_pixel_step + 2] = PixelClip(r);\n        if constexpr (rgb_pixel_step == 4) { // n/a\n          dstp[x * 4 + 3] = 255;\n        }\n      }\n    }\n    dstp -= dst_pitch;\n    srcY += src_pitch_y;\n    srcU += src_pitch_uv;\n    srcV += src_pitch_uv;\n    if constexpr(hasAlpha)\n      srcA += src_pitch_a;\n  }\n}\n\n//instantiate\n//template<int rgb_pixel_step, bool targetHasAlpha>\ntemplate void convert_yv24_to_rgb_avx2<3, false>(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE* srcV, const BYTE* srcA, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t src_pitch_a, size_t width, size_t height, const ConversionMatrix& matrix);\ntemplate void convert_yv24_to_rgb_avx2<4, false>(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE* srcV, const BYTE* srcA, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t src_pitch_a, size_t width, size_t height, const ConversionMatrix& matrix);\ntemplate void convert_yv24_to_rgb_avx2<3, true>(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE* srcV, const BYTE* srcA, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t src_pitch_a, size_t width, size_t height, const ConversionMatrix& matrix);\ntemplate void convert_yv24_to_rgb_avx2<4, true>(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE* srcV, const BYTE* srcA, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t src_pitch_a, size_t width, size_t height, const ConversionMatrix& matrix);\n\n#define XP_LAMBDA_CAPTURE_FIX(x) (void)(x)\n/*\n================================================================================\nYUV ↔ RGB Color Space Conversion - Unified Implementation\n================================================================================\n\nThis module provides a unified, highly optimized implementation for color space\nconversions between YUV and RGB formats, supporting all bit depths (8-16 bit\ninteger and 32-bit float) with optional bit-depth conversion.\n\nCONVERSION DIRECTIONS:\n  - YUV_TO_RGB: YUV → RGB (e.g., video decode path)\n  - RGB_TO_YUV: RGB → YUV (e.g., video encode path)\n  - YUV_TO_YUV: YUV → YUV (e.g., BT.601 → BT.709 matrix conversion)\n  - RGB_TO_RGB: RGB → RGB (e.g., gamut/color correction)\n\nARITHMETIC PRECISION:\n  - YUV→RGB / RGB→RGB: 13-bit fixed-point (coefficients scaled by 2^13 = 8192)\n  - RGB→YUV: 15-bit fixed-point (coefficients scaled by 2^15 = 32768)\n  - YUV→YUV: 14-bit fixed-point (fused matrix precision)\n\nPLANE MEMORY LAYOUT:\n  - YUV: Plane[0]=Y, Plane[1]=U, Plane[2]=V\n  - RGB: Plane[0]=G, Plane[1]=B, Plane[2]=R (AviSynth convention)\n\n================================================================================\n*/\n\n/**\n * @enum YuvRgbConversionType\n * @brief Defines the conversion workflow type for color space transformations\n *\n * Each conversion type determines:\n * - Whether to use integer or float arithmetic for the matrix multiply\n * - How input/output offsets are applied\n * - Whether bit-depth conversion is integrated into the workflow\n * - Whether 16-bit pivot trick is needed for exact 16-bit integer paths\n *\n * CONVERSION TYPE COMPARISON TABLE:\n * ┌─────────────────────┬────────────┬─────────────┬──────────────┬─────────────┬──────────────┐\n * │ Conversion Type     │ 16-bit     │ Input       │ Matrix       │ Post-Matrix │ Bit-Depth    │\n * │                     │ Pivot?     │ Offset      │ Coefficients │ Rounding    │ Scaling      │\n * ├─────────────────────┼────────────┼─────────────┼──────────────┼─────────────┼──────────────┤\n * │ NATIVE_INT          │ Yes (16)   │ After load  │ Integer      │ Yes (shift) │ None         │\n * │                     │ No (<16)   │ (16-bit add)│ (13/15-bit)  │ Integrated  │              │\n * ├─────────────────────┼────────────┼─────────────┼──────────────┼─────────────┼──────────────┤\n * │ FORCE_FLOAT         │ N/A        │ Pre-matrix  │ Float        │ Float+0.5   │ In scale_f   │\n * │                     │            │ (float add) │ (scaled)     │ (if int out)│              │\n * ├─────────────────────┼────────────┼─────────────┼──────────────┼─────────────┼──────────────┤\n * │ FLOAT_OUTPUT        │ Yes (16)   │ After load  │ Integer      │ No shift    │ Post-matrix  │\n * │                     │ No (<16)   │ (16-bit add)│ (13/15-bit)  │ (int→float) │ (scale_f)    │\n * ├─────────────────────┼────────────┼─────────────┼──────────────┼─────────────┼──────────────┤\n * │ BITCONV_INT_LIMITED │ Yes (16)   │ After load  │ Integer      │ Yes (adj.   │ Integrated   │\n * │                     │ No (<16)   │ (16-bit add)│ (13/15-bit)  │ shift)      │ into shift   │\n * ├─────────────────────┼────────────┼─────────────┼──────────────┼─────────────┼──────────────┤\n * │ BITCONV_INT_FULL    │ N/A        │ Pre-matrix  │ Float        │ Float+0.5   │ In scale_f   │\n * │                     │            │ (float add) │ (scaled)     │ (if int out)│              │\n * └─────────────────────┴────────────┴─────────────┴──────────────┴─────────────┴──────────────┘\n *\n * OFFSET APPLICATION DETAILS:\n * ┌─────────────────────┬─────────────────────────────────────────────────────────────────────┐\n * │ Conversion Type     │ Offset Application Strategy                                         │\n * ├─────────────────────┼─────────────────────────────────────────────────────────────────────┤\n * │ NATIVE_INT          │ • <16-bit: offset_in added as int16 after load                      │\n * │                     │ • 16-bit: offset_in in 32-bit patch after MADD (with pivot)         │\n * │                     │ • Output: offset_out in MADD rounding constant (scaled by 2^13/15)  │\n * ├─────────────────────┼─────────────────────────────────────────────────────────────────────┤\n * │ FORCE_FLOAT         │ • Input: offset_in added as float before matrix multiply            │\n * │                     │ • Output: offset_out added as float in matrix result                │\n * │                     │ • Coefficients pre-scaled by scale_f for bit-depth conversion       │\n * ├─────────────────────┼─────────────────────────────────────────────────────────────────────┤\n * │ FLOAT_OUTPUT        │ • Input: Same as NATIVE_INT (int16 or 32-bit patch)                 │\n * │                     │ • Output: No offset in MADD; added post-conversion in float domain  │\n * │                     │ • Result: int32 → float with scale_f, then + offset_out_f           │\n * ├─────────────────────┼─────────────────────────────────────────────────────────────────────┤\n * │ BITCONV_INT_LIMITED │ • Same as NATIVE_INT but with adjusted shift (13 - bit_diff)        │\n * │                     │ • Chroma offset uses SOURCE bit depth (half_pixel_offset)           │\n * │                     │ • Bit-depth scaling integrated into the right-shift operation       │\n * ├─────────────────────┼─────────────────────────────────────────────────────────────────────┤\n * │ BITCONV_INT_FULL    │ • Same as FORCE_FLOAT (uses float workflow internally)              │\n * │                     │ • Required for full-range bit-depth conversions (e.g., 10→8 full)   │\n * └─────────────────────┴─────────────────────────────────────────────────────────────────────┘\n *\n * 16-BIT PIVOT TECHNIQUE (for integer paths only):\n *   Problem: uint16 range [0, 65535] doesn't fit in signed int16 [-32768, 32767]\n *   Solution: Flip MSB to pivot unsigned to signed: Y_signed = Y XOR 0x8000\n *   - 0 → -32768, 65535 → 32767 (all values fit in int16)\n *   - Correction applied in 32-bit patch: add (32768 + offset_in) × coefficients\n *   - See detailed explanation at top of function\n *\n * CHROMA CENTERING:\n *   YUV Input:  U/V centered around half (e.g., 128 for 8-bit) → subtract half\n *   YUV Output: U/V centered around half → add half after matrix\n *   RGB: No centering (all values have same zero point)\n *\n * PERFORMANCE CHARACTERISTICS:\n *   - AVX2: 32 pixels per iteration (primary target, 2013+ CPUs)\n *   - SSE2: 8 pixels per iteration (legacy compatibility)\n *   - Integer MADD path: ~4000-5400 fps (1920×1080, 8-bit, Ryzen)\n *   - Float workflow: ~3200-3900 fps (10-26% slower, but necessary for some cases)\n *\n * EXAMPLE USE CASES:\n *   YUV→RGB, 10-bit→10-bit, limited range:\n *     → NATIVE_INT (integer MADD, no bit conversion)\n *\n *   YUV→RGB, 10-bit→8-bit, limited→limited:\n *     → BITCONV_INT_LIMITED (integrated bit scaling in shift)\n *\n *   YUV→RGB, 10-bit→8-bit, full→full:\n *     → BITCONV_INT_FULL (uses float workflow internally)\n *\n *   YUV→RGB, 16-bit→32-bit float:\n *     → FORCE_FLOAT (required for float input)\n *\n *   YUV→RGB, 8-bit→32-bit float, limited→full:\n *     → FLOAT_OUTPUT (integer matrix, float output with range expansion)\n *\n *   YUV(BT.601)→YUV(BT.709), 10-bit→10-bit:\n *     → NATIVE_INT with fused conversion matrix (avoids RGB intermediate)\n */\n\n/**\n * @brief Universal color space conversion function (AVX2 optimized)\n *\n * Converts between YUV and RGB color spaces with optional bit-depth conversion.\n * Supports all combinations of 8/10/12/14/16-bit integer and 32-bit float formats.\n *\n * @tparam direction        Conversion direction (YUV_TO_RGB, RGB_TO_YUV, YUV_TO_YUV, RGB_TO_RGB)\n * @tparam pixel_t          Input pixel type (uint8_t, uint16_t, or float)\n * @tparam lessthan16bit    True if input is 8/10/12/14-bit (enables optimizations)\n * @tparam lessthan16bit_target True if output is 8/10/12/14-bit (enables clamping)\n * @tparam pixel_t_dst      Output pixel type (uint8_t, uint16_t, or float)\n * @tparam conv_type        Conversion workflow type (see YuvRgbConversionType)\n *\n * @param dstp              Output plane pointers [3] (G/Y, B/U, R/V)\n * @param dstPitch          Output plane pitches in bytes [3]\n * @param srcp              Input plane pointers [3] (G/Y, B/U, R/V)\n * @param srcPitch          Input plane pitches in bytes [3]\n * @param width             Frame width in pixels\n * @param height            Frame height in pixels\n * @param m                 Conversion matrix with coefficients and offsets\n * @param bits_per_pixel    Input bit depth (8-16)\n * @param bits_per_pixel_target Output bit depth (8-16)\n *\n * @note Matrix coefficients in ConversionMatrix must be pre-scaled:\n *       - Integer coefficients: scaled by 2^13 (YUV↔RGB) or 2^15 (RGB→YUV)\n *       - Float coefficients: unscaled, will be multiplied by scale_f internally\n *\n * @note For 16-bit integer paths, the function uses a pivot trick to work around\n *       signed int16 range limitations. See detailed comment at function start.\n *\n * @note Processes 32 pixels per iteration on AVX2. For float input/output, includes\n *       safety checks to respect 64-byte scanline alignment guarantees.\n */\ntemplate<ConversionDirection direction, typename pixel_t, bool lessthan16bit, bool lessthan16bit_target, typename pixel_t_dst, YuvRgbConversionType conv_type>\nstatic void convert_yuv_to_planarrgb_avx2_internal(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m,\n  int bits_per_pixel, int bits_per_pixel_target)\n{\n\n  constexpr int INT_ARITH_SHIFT =\n    (direction == ConversionDirection::YUV_TO_RGB) ? 13 :\n    (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::RGB_TO_Y) ? 15 :\n    (direction == ConversionDirection::YUV_TO_YUV) ? 14 : 13;\n\n  // 8 bit        uint8_t\n  // 10,12,14 bit uint16_t (signed range)\n  // 16 bit logic:\n  /*\n    1. pivot the pixel:\n      Convert uint16 pixel Y to a signed int16 by flipping the MSB (this is mathematically identical to Y−32768).\n        0 becomes −32768.\n        65535 becomes 32767.\n        All values now fit in int16 without saturation.\n    2. reorganize the formula (offset_in is negative when exists, e.g. -4096):\n       Original: (Y + offset_y) * Cy\n       Substitute\n       Y = (Ysigned​ + 32768)\n       => (Ysigned​ + 32768 + offset_y) * Cy​\n       => (Ysigned​ * Cy​) + (32768 + offset_y) * Cy​)\n    3. correction after the madd section:\n       Add ((32768 + offset_y) * Cy​) to the existing 32-bit rounding/offset_in constant.\n    4. Output rgb offset_in is also added to the precalculated patch.\n  */\n\n  // When input is float (pixel_t), float workflow (FORCE_FLOAT) is compulsory.\n  // But not the opposite: FORCE_FLOAT and not float input is fine\n  // make a static assert\n  static_assert(!(std::is_floating_point<pixel_t>::value && conv_type != YuvRgbConversionType::FORCE_FLOAT), \"FORCE_FLOAT conversion type is required for float input pixel type\");\n\n  constexpr bool force_float = conv_type == YuvRgbConversionType::FORCE_FLOAT; // effectively full-float-inside for int full range conversion, but with the same output rules as other float conversions\n  constexpr bool final_is_float = std::is_floating_point<pixel_t_dst>::value;\n  constexpr bool need_int_conversion_narrow_range = conv_type == YuvRgbConversionType::BITCONV_INT_LIMITED;       // full_d is false\n  constexpr bool need_int_conversion_full_range = conv_type == YuvRgbConversionType::BITCONV_INT_FULL; // full_d is true\n  constexpr bool need_int_conversion = conv_type == YuvRgbConversionType::BITCONV_INT_FULL || conv_type == YuvRgbConversionType::BITCONV_INT_LIMITED ||\n    (conv_type == YuvRgbConversionType::FORCE_FLOAT && !final_is_float);\n\n  const bool float_matrix_workflow = force_float || need_int_conversion_full_range; // effectively full-float-inside for int full range conversion \n\n  // quasi-constexpr, may help optimizer\n  if constexpr (std::is_same<pixel_t, uint8_t>::value) bits_per_pixel = 8;\n  if constexpr (std::is_same<pixel_t_dst, uint8_t>::value) bits_per_pixel_target = 8;\n  if constexpr (std::is_same<pixel_t, uint16_t>::value && !lessthan16bit) bits_per_pixel = 16;\n  if constexpr (std::is_same<pixel_t_dst, uint16_t>::value && !lessthan16bit_target) bits_per_pixel_target = 16;\n  if constexpr (conv_type == YuvRgbConversionType::NATIVE_INT) bits_per_pixel_target = bits_per_pixel;\n\n  const int bit_diff = need_int_conversion ? bits_per_pixel_target - bits_per_pixel : 0;\n  const int target_shift = need_int_conversion_narrow_range ? INT_ARITH_SHIFT - bit_diff : INT_ARITH_SHIFT; // int->int narrow range: integrate the bit depth conversion into the scaling back\n\n  const int ROUNDER = (final_is_float || float_matrix_workflow) ? 0 : (1 << (target_shift - 1)); // 0 when float internal calculation is involved\n\n  // For integer workflow + final is float:\n  const float out_offset_f = m.offset_out_f_32; // for post-32-bit float conversion\n\n  const int half_pixel_offset = 1 << (bits_per_pixel - 1); // YUV -->  // at input is float: n/a\n  const int half_pixel_offset_target = 1 << (bits_per_pixel_target - 1); // For float_matrix_workflow or output is float\n  const int max_pixel_value_target = (1 << bits_per_pixel_target) - 1;\n\n  bits_conv_constants conversion_ranges;\n  const bool full_scale_d = m.offset_out == 0;\n  // matrix is handling only the same-bit-depth factor. Output result must be scaled as if\n  // we further correct it with a post-matrix scaling for bit depth conversion which depends only\n  // on the destination limite/full\n  get_bits_conv_constants(conversion_ranges, false, full_scale_d, full_scale_d, bits_per_pixel, bits_per_pixel_target); // our final scale would be as if work to float\n\n  constexpr int int_arithmetic_shift = 1 << INT_ARITH_SHIFT;\n  float scale_f = conversion_ranges.mul_factor;\n  // Integer matrix workflow + 32 bit final float output extra rules\n  // - no rounding and scaling back INT_ARITH_SHIFT e.g. 13 for YUV-RGB, 15 for RGB-YUV bits\n  // - no clamping to bit depth limits\n  // - the INT_ARITH_SHIFT-bit scaling factor is integrated into the bits_per_pixel shift\n  if (final_is_float && !float_matrix_workflow)\n    scale_f = scale_f / int_arithmetic_shift; // int workflow, float at the end\n\n  __m256i half = _mm256_set1_epi16((short)half_pixel_offset);  // 128\n  __m256i limit = _mm256_set1_epi16((short)max_pixel_value_target); // 255\n\n  // to be able to use it as signed 16 bit in madd; 4096+(16<<13) would not fit into i16\n  // multiplier is 4096 instead of 1:\n  // original   : 1      * 4096\n  // needed     : 1      * (4096 + offset_rgb<<13)  (4096 + 131072 overflows i16)\n  // changed to : 4096   * (1 + offset_rgb>>(13-1)\n  // Except for exact 16 bit, where we do the output offset_in adjustment along with the 16 bit signed-unsigned pivot fix\n  constexpr int ROUND_SCALE = 1 << (INT_ARITH_SHIFT - 1); // 1 << 12, for 13 bit integer arithmetic: \"0.5\"\n  const __m256i m256i_round_scale = _mm256_set1_epi16(ROUND_SCALE);\n\n  int round_mask_plus_offset_out_scaled_i;\n  int round_mask_plus_offset_out_chroma_scaled_i;\n\n  // integer workflow + exact 16 bit path: needs a special handling for the pivot and input offset_in and output rgb offset_out\n  __m256i v_patch_G, v_patch_B, v_patch_R;\n  __m256i sign_flip_mask = _mm256_set1_epi16((short)0x8000); // for 16 bit pivot\n\n  // Full-range is float-workflow inside, so no need to do any of the above adjustments in\n  // integer arithmetic, just do the full float conversion and clamp at the end if needed\n\n  // Input offset_in handling\n  const int offset_in_scalar = m.offset_in;\n  const int offset_out_scalar = m.offset_out;\n\n  __m256i offset_in;\n  __m256 offset_in_f;\n  if constexpr (float_matrix_workflow) {\n    offset_in = _mm256_set1_epi32(offset_in_scalar); // float workflow, integer inputs\n    offset_in_f = _mm256_set1_ps(m.offset_in_f); // float workflow, float inputs\n  }\n  else if constexpr (lessthan16bit) // integer workflow, lessthan16 bit path\n    offset_in = _mm256_set1_epi16((short)offset_in_scalar); // input offset_in correction can happen in 16 bit arithmetic\n  else // n/a, for exact 16 bit integer workflow, the offset_in is handled in the 32-bit patch together with the pivot adjustment\n    offset_in = _mm256_setzero_si256();\n\n  if constexpr (!float_matrix_workflow) {\n    // integer preparations for the madd-based main loop\n    if constexpr (lessthan16bit) {\n      // 8-14 bit\n      // offset of same magnitude as coeffs, also in simd madd\n      round_mask_plus_offset_out_scaled_i = final_is_float ? 0 : (ROUNDER + (offset_out_scalar << INT_ARITH_SHIFT)) / ROUND_SCALE;\n      round_mask_plus_offset_out_chroma_scaled_i = final_is_float ? 0 : (ROUNDER + (half_pixel_offset << INT_ARITH_SHIFT)) / ROUND_SCALE;\n      v_patch_G = v_patch_B = v_patch_R = _mm256_setzero_si256(); // No patch needed, since the signed 16-bit workaround is not needed.\n    }\n    else {\n      // exact 16 bit\n      // keep madd simple: only handle the rounding (ROUND_SCALE * 1)\n      // rgb offset is handled later in the patch, after the madd, added to the same place as the pivot adjustment\n      round_mask_plus_offset_out_scaled_i = ROUNDER / ROUND_SCALE; // effectively 1 or 0 (final_is_float)\n      round_mask_plus_offset_out_chroma_scaled_i = ROUNDER / ROUND_SCALE; // effectively 1 or 0 (final_is_float)\n\n      // move BOTH the pivot and the output offset to the 32-bit patch\n      // Since we have to do the patching anyway, we can combine both adjustments here\n      const int luma_or_rgbin_pivot = 32768 + offset_in_scalar;\n      const int chroma_pivot = 32768;\n      const int offset_out_for_patch = final_is_float ? 0 : (offset_out_scalar << INT_ARITH_SHIFT); // 32-bit post-conversion adds offset in float domain.\n      const int chroma_offset_out_for_patch = final_is_float ? 0 : (half_pixel_offset << INT_ARITH_SHIFT); // 32-bit post-conversion adds offset in float domain.\n\n      if constexpr (direction == ConversionDirection::YUV_TO_RGB) {\n        // for YUV->RGB, the pivot adjustment is needed for all three channels since the luma coeffs are not zero, but pivot only the Y\n        v_patch_G = _mm256_set1_epi32(luma_or_rgbin_pivot * m.y_g + offset_out_for_patch);\n        v_patch_B = _mm256_set1_epi32(luma_or_rgbin_pivot * m.y_b + offset_out_for_patch);\n        v_patch_R = _mm256_set1_epi32(luma_or_rgbin_pivot * m.y_r + offset_out_for_patch);\n      }\n      else if constexpr (direction == ConversionDirection::RGB_TO_RGB) {\n        // for RGB->RGB, the pivot adjustment is needed for all three channels in and aout\n        v_patch_G = _mm256_set1_epi32(luma_or_rgbin_pivot * (m.y_g + m.u_g + m.v_g) + offset_out_for_patch);\n        v_patch_B = _mm256_set1_epi32(luma_or_rgbin_pivot * (m.y_b + m.u_b + m.v_b) + offset_out_for_patch);\n        v_patch_R = _mm256_set1_epi32(luma_or_rgbin_pivot * (m.y_r + m.u_r + m.v_r) + offset_out_for_patch);\n      }\n      else if constexpr (direction == ConversionDirection::RGB_TO_YUV) {\n        // RGB→YUV: All RGB inputs are pivoted, need to account for all three\n        // Out0=Y (luma offset), Out1=U and Out2=V (chroma offset)\n        // Y output = y_r*R + y_g*G + y_b*B\n        v_patch_G = _mm256_set1_epi32(luma_or_rgbin_pivot * (m.y_r + m.y_g + m.y_b) + offset_out_for_patch);\n        // U output = u_r*R + u_g*G + u_b*B\n        v_patch_B = _mm256_set1_epi32(luma_or_rgbin_pivot * (m.u_r + m.u_g + m.u_b) + chroma_offset_out_for_patch);\n        // V output = v_r*R + v_g*G + v_b*B\n        v_patch_R = _mm256_set1_epi32(luma_or_rgbin_pivot * (m.v_r + m.v_g + m.v_b) + chroma_offset_out_for_patch);\n      }\n      else if constexpr (direction == ConversionDirection::RGB_TO_Y) {\n        // RGB→YUV: All RGB inputs are pivoted, need to account for all three\n        // Out0=Y (luma offset), No chroma\n        // Y output = y_r*R + y_g*G + y_b*B\n        v_patch_G = _mm256_set1_epi32(luma_or_rgbin_pivot * (m.y_r + m.y_g + m.y_b) + offset_out_for_patch);\n      }\n      else if constexpr (direction == ConversionDirection::YUV_TO_YUV) {\n        // for YUV->YUV\n        // FIXME: untested, no AviSynth caller yet. Suspect m.y_b/m.y_r should be\n        // m.u_b/m.v_r (chroma diagonal), and offset should be chroma_offset_out_for_patch.\n\n        v_patch_G = _mm256_set1_epi32(luma_or_rgbin_pivot * m.y_g + offset_out_for_patch);\n        v_patch_B = _mm256_set1_epi32(chroma_pivot * m.y_b + offset_out_for_patch);\n        v_patch_R = _mm256_set1_epi32(chroma_pivot * m.y_r + offset_out_for_patch);\n      }\n    }\n  }\n\n  // For integer workflow + final is float\n  const __m256 out_offset_f_avx2 = _mm256_set1_ps(out_offset_f);\n\n  __m256i zero = _mm256_setzero_si256();\n  const __m256 scale_f_avx2 = _mm256_set1_ps(scale_f);\n\n  // For integer workflow\n  __m256i m_uy_G, m_vr_G, m_uy_B, m_vr_B, m_uy_R, m_vr_R; // integer arithmetic, including 32-bit float target when non-float_matrix_workflow\n  // For float_matrix_workflow: define coefficient accessors based on direction\n  __m256 coeff_out0_in0, coeff_out0_in1, coeff_out0_in2;  // First output row\n  __m256 coeff_out1_in0, coeff_out1_in1, coeff_out1_in2;  // Second output row\n  __m256 coeff_out2_in0, coeff_out2_in1, coeff_out2_in2;  // Third output row\n\n  __m256 m_offset_out_y_or_g_f, m_offset_out_u_or_b_f, m_offset_out_v_or_r_f; // three separate offsets, in YUV-RGB they are the same, in RGB-YUV they are different for luma and chroma\n\n  if constexpr (float_matrix_workflow) {\n    __m256 m_y_g_f, m_y_b_f, m_y_r_f, m_u_g_f, m_u_b_f, m_u_r_f, m_v_g_f, m_v_b_f, m_v_r_f;\n    m_y_g_f = _mm256_mul_ps(_mm256_set1_ps(m.y_g_f), scale_f_avx2);\n    m_y_b_f = _mm256_mul_ps(_mm256_set1_ps(m.y_b_f), scale_f_avx2);\n    m_y_r_f = _mm256_mul_ps(_mm256_set1_ps(m.y_r_f), scale_f_avx2);\n    if constexpr (direction != ConversionDirection::RGB_TO_Y) {\n      m_u_g_f = _mm256_mul_ps(_mm256_set1_ps(m.u_g_f), scale_f_avx2);\n      m_u_b_f = _mm256_mul_ps(_mm256_set1_ps(m.u_b_f), scale_f_avx2);\n      m_u_r_f = _mm256_mul_ps(_mm256_set1_ps(m.u_r_f), scale_f_avx2);\n      m_v_g_f = _mm256_mul_ps(_mm256_set1_ps(m.v_g_f), scale_f_avx2);\n      m_v_b_f = _mm256_mul_ps(_mm256_set1_ps(m.v_b_f), scale_f_avx2);\n      m_v_r_f = _mm256_mul_ps(_mm256_set1_ps(m.v_r_f), scale_f_avx2);\n    }\n\n    if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::RGB_TO_RGB) {\n      // RGB output: same offset for all channels\n      float rgb_out_offset_scaled = m.offset_out_f * scale_f;\n      m_offset_out_y_or_g_f = _mm256_set1_ps(rgb_out_offset_scaled);\n      m_offset_out_u_or_b_f = _mm256_set1_ps(rgb_out_offset_scaled);\n      m_offset_out_v_or_r_f = _mm256_set1_ps(rgb_out_offset_scaled);\n    }\n    else if constexpr (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::YUV_TO_YUV) {\n\n      // YUV output\n      float y_out_offset = m.offset_out_f;\n      float y_out_offset_scaled = y_out_offset * scale_f;\n\n      // U/V center offset - should NOT be scaled by scale_f!\n      // The matrix output is already in the target range, just add the center\n      float uv_center_offset = final_is_float ? 0.0f : (float)half_pixel_offset_target;\n\n      m_offset_out_y_or_g_f = _mm256_set1_ps(y_out_offset_scaled);\n      m_offset_out_u_or_b_f = _mm256_set1_ps(uv_center_offset);\n      m_offset_out_v_or_r_f = _mm256_set1_ps(uv_center_offset);\n    }\n    else if constexpr (direction == ConversionDirection::RGB_TO_Y) {\n      // no chroma output\n      float y_out_offset_scaled = m.offset_out_f * scale_f;\n      m_offset_out_y_or_g_f = _mm256_set1_ps(y_out_offset_scaled);\n    }\n\n    if constexpr (direction == ConversionDirection::YUV_TO_RGB) {\n      // YUV→RGB: outputs are RGB (rows G,B,R), inputs are YUV (columns Y,U,V)\n      // Out0=G, Out1=B, Out2=R\n      coeff_out0_in0 = m_y_g_f; coeff_out0_in1 = m_u_g_f; coeff_out0_in2 = m_v_g_f;\n      coeff_out1_in0 = m_y_b_f; coeff_out1_in1 = m_u_b_f; coeff_out1_in2 = m_v_b_f;\n      coeff_out2_in0 = m_y_r_f; coeff_out2_in1 = m_u_r_f; coeff_out2_in2 = m_v_r_f;\n    }\n    else if constexpr (direction == ConversionDirection::RGB_TO_YUV) {\n      // RGB→YUV: outputs are YUV (rows Y,U,V), inputs are RGB in memory order (G, B, R)\n      // Out0=Y, Out1=U, Out2=V\n      // Inputs: in0=G, in1=B, in2=R\n      // Y = y_r*R + y_g*G + y_b*B\n      //   = y_g*in0 + y_b*in1 + y_r*in2\n      coeff_out0_in0 = m_y_g_f; coeff_out0_in1 = m_y_b_f; coeff_out0_in2 = m_y_r_f;\n\n      // U = u_r*R + u_g*G + u_b*B\n      //   = u_g*in0 + u_b*in1 + u_r*in2\n      coeff_out1_in0 = m_u_g_f; coeff_out1_in1 = m_u_b_f; coeff_out1_in2 = m_u_r_f;\n\n      // V = v_r*R + v_g*G + v_b*B\n      //   = v_g*in0 + v_b*in1 + v_r*in2\n      coeff_out2_in0 = m_v_g_f; coeff_out2_in1 = m_v_b_f; coeff_out2_in2 = m_v_r_f;\n    }\n    else if constexpr (direction == ConversionDirection::RGB_TO_Y) {\n      // RGB→YUV: outputs are YUV (rows Y,U,V), inputs are RGB in memory order (G, B, R)\n      // Out0=Y, No chroma output\n      // Inputs: in0=G, in1=B, in2=R\n      // Y = y_r*R + y_g*G + y_b*B\n      //   = y_g*in0 + y_b*in1 + y_r*in2\n      coeff_out0_in0 = m_y_g_f; coeff_out0_in1 = m_y_b_f; coeff_out0_in2 = m_y_r_f;\n    }\n    else if constexpr (direction == ConversionDirection::YUV_TO_YUV) {\n      // YUV→YUV: outputs are YUV (rows Y,U,V), inputs are YUV (columns Y,U,V)\n      // For BT.601→BT.709 conversion, this is a fused matrix\n      // Out0=Y_out, Out1=U_out, Out2=V_out\n      coeff_out0_in0 = m_y_g_f; coeff_out0_in1 = m_u_g_f; coeff_out0_in2 = m_v_g_f;\n      coeff_out1_in0 = m_y_b_f; coeff_out1_in1 = m_u_b_f; coeff_out1_in2 = m_v_b_f;\n      coeff_out2_in0 = m_y_r_f; coeff_out2_in1 = m_u_r_f; coeff_out2_in2 = m_v_r_f;\n    }\n    else if constexpr (direction == ConversionDirection::RGB_TO_RGB) { // RGB_TO_RGB\n      // RGB→RGB: outputs are RGB (rows R,G,B), inputs are RGB (columns R,G,B)\n      // For gamut conversion or color correction\n      // Out0=G_out, Out1=B_out, Out2=R_out\n      coeff_out0_in0 = m_y_g_f; coeff_out0_in1 = m_u_g_f; coeff_out0_in2 = m_v_g_f;\n      coeff_out1_in0 = m_y_b_f; coeff_out1_in1 = m_u_b_f; coeff_out1_in2 = m_v_b_f;\n      coeff_out2_in0 = m_y_r_f; coeff_out2_in1 = m_u_r_f; coeff_out2_in2 = m_v_r_f;\n    }\n  }\n  else {\n    // Integer workflow coefficient setup\n    int round_and_out_offset_y_or_g;\n    int round_and_out_offset_u_or_b;\n    int round_and_out_offset_v_or_r;\n\n    if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::RGB_TO_RGB) {\n      // output RGB: same offset for all channels\n      round_and_out_offset_y_or_g = round_mask_plus_offset_out_scaled_i;\n      round_and_out_offset_u_or_b = round_mask_plus_offset_out_scaled_i;\n      round_and_out_offset_v_or_r = round_mask_plus_offset_out_scaled_i;\n    }\n    else  if constexpr (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::YUV_TO_YUV) {\n      // output YUV: different offsets for Y vs U/V\n      round_and_out_offset_y_or_g = round_mask_plus_offset_out_scaled_i;\n      round_and_out_offset_u_or_b = round_mask_plus_offset_out_chroma_scaled_i;\n      round_and_out_offset_v_or_r = round_mask_plus_offset_out_chroma_scaled_i;\n    }\n    else if constexpr (direction == ConversionDirection::RGB_TO_Y) {\n      // no chroma output\n      round_and_out_offset_y_or_g = round_mask_plus_offset_out_scaled_i;\n    }\n\n    // Pack coefficients based on direction\n    // For MADD packing: [coeff_in1, coeff_in0] and [coeff_in2, round]\n\n    if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::YUV_TO_YUV) {\n      // YUV→RGB: Out0=G, Out1=B, Out2=R\n      // YUV→YUV: Out0=Y, Out1=U, Out2=V\n      // G = y_g*Y + u_g*U + v_g*V\n      // Inputs are: in0=Y, in1=U, in2=V\n      m_uy_G = _mm256_set1_epi32((static_cast<uint16_t>(m.y_g) << 16) | static_cast<uint16_t>(m.u_g));\n      m_vr_G = _mm256_set1_epi32((static_cast<uint16_t>(round_and_out_offset_y_or_g) << 16) | static_cast<uint16_t>(m.v_g));\n\n      // B = y_b*Y + u_b*U + v_b*V\n      m_uy_B = _mm256_set1_epi32((static_cast<uint16_t>(m.y_b) << 16) | static_cast<uint16_t>(m.u_b));\n      m_vr_B = _mm256_set1_epi32((static_cast<uint16_t>(round_and_out_offset_u_or_b) << 16) | static_cast<uint16_t>(m.v_b));\n\n      // R = y_r*Y + u_r*U + v_r*V\n      m_uy_R = _mm256_set1_epi32((static_cast<uint16_t>(m.y_r) << 16) | static_cast<uint16_t>(m.u_r));\n      m_vr_R = _mm256_set1_epi32((static_cast<uint16_t>(round_and_out_offset_v_or_r) << 16) | static_cast<uint16_t>(m.v_r));\n    }\n    else if constexpr (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::RGB_TO_RGB) {\n      // RGB→YUV: Out0=Y, Out1=U, Out2=V\n      // RGB→RGB: Out0=G, Out1=B, Out2=R\n      // Inputs are: in0=G, in1=B, in2=R\n\n      // Y = y_r*R + y_g*G + y_b*B\n      //   = y_g*in0 + y_b*in1 + y_r*in2\n      m_uy_G = _mm256_set1_epi32((static_cast<uint16_t>(m.y_g) << 16) | static_cast<uint16_t>(m.y_b));\n      m_vr_G = _mm256_set1_epi32((static_cast<uint16_t>(round_and_out_offset_y_or_g) << 16) | static_cast<uint16_t>(m.y_r));\n\n      // U = u_r*R + u_g*G + u_b*B\n      //   = u_g*in0 + u_b*in1 + u_r*in2\n      m_uy_B = _mm256_set1_epi32((static_cast<uint16_t>(m.u_g) << 16) | static_cast<uint16_t>(m.u_b));\n      m_vr_B = _mm256_set1_epi32((static_cast<uint16_t>(round_and_out_offset_u_or_b) << 16) | static_cast<uint16_t>(m.u_r));\n\n      // V = v_r*R + v_g*G + v_b*B\n      //   = v_g*in0 + v_b*in1 + v_r*in2\n      m_uy_R = _mm256_set1_epi32((static_cast<uint16_t>(m.v_g) << 16) | static_cast<uint16_t>(m.v_b));\n      m_vr_R = _mm256_set1_epi32((static_cast<uint16_t>(round_and_out_offset_v_or_r) << 16) | static_cast<uint16_t>(m.v_r));\n    }\n    else if constexpr (direction == ConversionDirection::RGB_TO_Y) {\n      // RGB→Y: Out0=Y, No chroma output\n      // Inputs are: in0=G, in1=B, in2=R\n      // Y = y_r*R + y_g*G + y_b*B\n      //   = y_g*in0 + y_b*in1 + y_r*in2\n      m_uy_G = _mm256_set1_epi32((static_cast<uint16_t>(m.y_g) << 16) | static_cast<uint16_t>(m.y_b));\n      m_vr_G = _mm256_set1_epi32((static_cast<uint16_t>(round_and_out_offset_y_or_g) << 16) | static_cast<uint16_t>(m.y_r));\n    }\n  }\n\n  const int rowsize = width * sizeof(pixel_t);\n  const int rowsize_aligned = AlignNumber(rowsize, FRAME_ALIGN); // 64\n  for (int yy = 0; yy < height; yy++) {\n    // 32 pixels per loop: 32 * 8 bit = 32 bytes; 32 * 16 bit = 64 bytes\n    // Note: extra care needed for 32-bit float input or output, since 32xfloat is over\n    // Avisynth+ guaranteed scanline alignment (64 bytes)\n    // Ideally, we have to separate the processing into 32 pixel then 16 pixel chunks.\n    // See ConvertBits to float AVX2 version for reference.\n    // Actually, we only check a pre-calculated limit inside the loop, before the storage. (FIXME)\n    // But I guess, when processing so many pixels at once, it's not that big penalty.\n    // However duplicating the loop body seen below for the two float-problematic cases, that _is_ penalty :)\n\n    for (int x = 0; x < rowsize; x += 32 * sizeof(pixel_t)) {\n\n      // ConversionDirection::YUV_TO_RGB: y, u, v\n      // ConversionDirection::RGB_TO_YUV: g, b, r\n\n      // Regardless of the YUV/RGB source, we ise in0_1, in1_1, in2_1 for the first 16 pixels, and in0_2, in1_2, in2_2 for the second 16 pixels\n      // Layout for 0-1-2: Y-U-V or G-B-R\n\n      // integer input pixels \n      __m256i in0_1, in1_1, in2_1;\n      __m256i in0_2, in1_2, in2_2;\n      // float workflow\n      __m256 in0_1_f_lo, in0_1_f_hi, in0_2_f_lo, in0_2_f_hi;\n      __m256 in1_1_f_lo, in1_1_f_hi, in1_2_f_lo, in1_2_f_hi;\n      __m256 in2_1_f_lo, in2_1_f_hi, in2_2_f_lo, in2_2_f_hi;\n\n      // Avisynth FRAME_ALIGN == 64, so when final_is_float, we cannot process 32 pixels at once at the end of the line\n      // Can I write all 32 pixels (blockA+B+C+D)?\n      // yes: write all 4 blocks (blockA, B, C, D)\n      // no : Write only first 2 blocks (blockA, B), 16 floats are guaranteed safe due to 64-byte alignment\n      bool safe_last_16float_64bytes;\n      if constexpr (final_is_float || sizeof(pixel_t) == 4)\n        safe_last_16float_64bytes = (x + 32 * (int)sizeof(pixel_t)) <= rowsize_aligned;\n      else\n        safe_last_16float_64bytes = false;\n\n      // Note on widening strategy (Y, U, V) for the float internal path, where series of widenings are required:\n      //\n      // We use unpacklo/hi_epi16 for widening Y, U and V from (uint8 to) (u)int16 to int32,\n      // rather than _mm256_extracti128_si256 + (cvtepu8_epi16) + cvtepi16_epi32/cvtepu16_epi32.\n      // For U and V, an additional srai_epi16 generates the sign fill word needed\n      // for correct sign extension of the centered (negative-capable) chroma values.\n      //\n      // Although the extract+cvt approach would produce a sequential lane layout\n      // that avoids the permute2f128 shuffles before the final float store, it is\n      // measurably slower (Possibly port contention).\n\n      // Load pixels, for the integer path, we pivot for exact 16 bit Y later\n      if constexpr (sizeof(pixel_t) == 1) {\n        // Load 32 bytes (32 pixels), unpack to two 16-bit registers\n        __m256i in0_raw = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp[0] + x)); // 0..7 8..15 16..23 24..31 Y or G\n        __m256i in1_raw = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp[1] + x)); // U or B\n        __m256i in2_raw = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp[2] + x)); // V or R\n\n        if constexpr (sizeof(pixel_t_dst) == 2) {\n          // 8->16 bit: pre-shuffle to avoid permutes at the end\n          in0_raw = _mm256_permute4x64_epi64(in0_raw, 0xD8); // (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6)\n          // 0..7, 16..23, 8..15, 24..31\n          in1_raw = _mm256_permute4x64_epi64(in1_raw, 0xD8);\n          in2_raw = _mm256_permute4x64_epi64(in2_raw, 0xD8);\n        }\n        in0_1 = _mm256_unpacklo_epi8(in0_raw, zero); in0_2 = _mm256_unpackhi_epi8(in0_raw, zero);\n        // in0_1: 0..7, 8..15, in0_2: 16..23, 24..31\n        in1_1 = _mm256_unpacklo_epi8(in1_raw, zero); in1_2 = _mm256_unpackhi_epi8(in1_raw, zero);\n        in2_1 = _mm256_unpacklo_epi8(in2_raw, zero); in2_2 = _mm256_unpackhi_epi8(in2_raw, zero);\n      }\n      else if constexpr (sizeof(pixel_t) == 2) {\n        // Load 64 bytes (32 pixels)\n        in0_1 = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp[0] + x));\n        in1_1 = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp[1] + x));\n        in2_1 = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp[2] + x));\n        in0_2 = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp[0] + x + 32));\n        in1_2 = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp[1] + x + 32));\n        in2_2 = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp[2] + x + 32));\n      }\n      else { // if constexpr (sizeof(pixel_t) == 4) {\n        // this also implies full float workflow\n        // Load 128 bytes (32 pixels) // safety! we are well beyond Avisynth's 64 byte alignment\n        in0_1_f_lo = _mm256_load_ps(reinterpret_cast<const float*>(srcp[0] + x));\n        in0_1_f_hi = _mm256_load_ps(reinterpret_cast<const float*>(srcp[0] + x + 32));\n        in1_1_f_lo = _mm256_load_ps(reinterpret_cast<const float*>(srcp[1] + x));\n        in1_1_f_hi = _mm256_load_ps(reinterpret_cast<const float*>(srcp[1] + x + 32));\n        in2_1_f_lo = _mm256_load_ps(reinterpret_cast<const float*>(srcp[2] + x));\n        in2_1_f_hi = _mm256_load_ps(reinterpret_cast<const float*>(srcp[2] + x + 32));\n        if (safe_last_16float_64bytes) {\n          in0_2_f_lo = _mm256_load_ps(reinterpret_cast<const float*>(srcp[0] + x + 64));\n          in0_2_f_hi = _mm256_load_ps(reinterpret_cast<const float*>(srcp[0] + x + 96));\n          in1_2_f_lo = _mm256_load_ps(reinterpret_cast<const float*>(srcp[1] + x + 64));\n          in1_2_f_hi = _mm256_load_ps(reinterpret_cast<const float*>(srcp[1] + x + 96));\n          in2_2_f_lo = _mm256_load_ps(reinterpret_cast<const float*>(srcp[2] + x + 64));\n          in2_2_f_hi = _mm256_load_ps(reinterpret_cast<const float*>(srcp[2] + x + 96));\n        }\n        else {\n          // fill them with something to silence the warning, they won't be stored, either.\n          in0_2_f_lo = in0_2_f_hi = in1_2_f_lo = in1_2_f_hi = in2_2_f_lo = in2_2_f_hi = _mm256_setzero_ps();\n        }\n      }\n\n      if constexpr (float_matrix_workflow) {\n        // complete float workflow, even for integer targets, do matrixes in float math.\n        // Also for maximum accuracy.\n\n        // convert integer pixels to float, only for non-float input\n        if constexpr (sizeof(pixel_t) == 4) {\n          // even float input can be \"limited\" in Avisynth, correct with offset_in as well\n          // YUV chroma is zero centered, no offset correction needed\n          if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::YUV_TO_YUV) {\n            // YUV Source\n            // Y\n            in0_1_f_lo = _mm256_add_ps(in0_1_f_lo, offset_in_f);\n            in0_1_f_hi = _mm256_add_ps(in0_1_f_hi, offset_in_f);\n            in0_2_f_lo = _mm256_add_ps(in0_2_f_lo, offset_in_f);\n            in0_2_f_hi = _mm256_add_ps(in0_2_f_hi, offset_in_f);\n          }\n          else {\n            // RGB source: all channels need offset_in adjustments if studio RGB RGB_TO_RGB, RGB_TO_YUV, RGB_TO_Y\n            in0_1_f_lo = _mm256_add_ps(in0_1_f_lo, offset_in_f);\n            in0_1_f_hi = _mm256_add_ps(in0_1_f_hi, offset_in_f);\n            in0_2_f_lo = _mm256_add_ps(in0_2_f_lo, offset_in_f);\n            in0_2_f_hi = _mm256_add_ps(in0_2_f_hi, offset_in_f);\n            in1_1_f_lo = _mm256_add_ps(in1_1_f_lo, offset_in_f);\n            in1_1_f_hi = _mm256_add_ps(in1_1_f_hi, offset_in_f);\n            in1_2_f_lo = _mm256_add_ps(in1_2_f_lo, offset_in_f);\n            in1_2_f_hi = _mm256_add_ps(in1_2_f_hi, offset_in_f);\n            in2_1_f_lo = _mm256_add_ps(in2_1_f_lo, offset_in_f);\n            in2_1_f_hi = _mm256_add_ps(in2_1_f_hi, offset_in_f);\n            in2_2_f_lo = _mm256_add_ps(in2_2_f_lo, offset_in_f);\n            in2_2_f_hi = _mm256_add_ps(in2_2_f_hi, offset_in_f);\n          }\n\n        }\n        else {\n          // integer input\n\n          // Order: move to int32, and only then adjust offset_in.\n          // Superblacks would yield negative values that can only be sign-extend to int32\n          // with excessive operations, see the U and V workaround.\n\n          // We've already put the input offset_in into each int32. We use add, offset_in is stored as negative.\n\n          // int32->float\n\n          if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::YUV_TO_YUV) {\n            // YUV Source\n            // Y\n            in0_1_f_lo = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpacklo_epi16(in0_1, zero), offset_in));\n            in0_1_f_hi = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpackhi_epi16(in0_1, zero), offset_in));\n            in0_2_f_lo = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpacklo_epi16(in0_2, zero), offset_in));\n            in0_2_f_hi = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpackhi_epi16(in0_2, zero), offset_in));\n\n            // UV to sign extend\n            // Though from SSE4.1 we could use _mm_cvtepi16_epi32 directly but it makes packus lane\n            // crossing correction difficult (and slow). Mayne from avx512 _mm512_cvtepi16_ps (only signed 16 exists)?\n\n            // No lane keeping cvtepi16_epi32 here either.\n            // U,V, make signed, then int16->int32\n\n            // sign-extend int16 chroma to int32, then convert to float\n            // using unpacklo/hi to preserve lane layout compatible with downstream packus\n            auto chroma_to_float = [&](__m256i c, __m256& f_lo, __m256& f_hi) {\n              c = _mm256_sub_epi16(c, half);\n              __m256i sign = _mm256_srai_epi16(c, 15); // 0xFFFF if negative, 0x0000 if positive\n              f_lo = _mm256_cvtepi32_ps(_mm256_unpacklo_epi16(c, sign));\n              f_hi = _mm256_cvtepi32_ps(_mm256_unpackhi_epi16(c, sign));\n              };\n\n            chroma_to_float(in1_1, in1_1_f_lo, in1_1_f_hi); // U1\n            chroma_to_float(in2_1, in2_1_f_lo, in2_1_f_hi); // V1\n            chroma_to_float(in1_2, in1_2_f_lo, in1_2_f_hi); // U2\n            chroma_to_float(in2_2, in2_2_f_lo, in2_2_f_hi); // V2\n          }\n          else {\n            // RGB source: only offset_in adjustment, no centering needed\n            // Green\n            in0_1_f_lo = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpacklo_epi16(in0_1, zero), offset_in));\n            in0_1_f_hi = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpackhi_epi16(in0_1, zero), offset_in));\n            in0_2_f_lo = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpacklo_epi16(in0_2, zero), offset_in));\n            in0_2_f_hi = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpackhi_epi16(in0_2, zero), offset_in));\n            // Blue\n            in1_1_f_lo = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpacklo_epi16(in1_1, zero), offset_in));\n            in1_1_f_hi = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpackhi_epi16(in1_1, zero), offset_in));\n            in1_2_f_lo = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpacklo_epi16(in1_2, zero), offset_in));\n            in1_2_f_hi = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpackhi_epi16(in1_2, zero), offset_in));\n            // Red\n            in2_1_f_lo = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpacklo_epi16(in2_1, zero), offset_in));\n            in2_1_f_hi = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpackhi_epi16(in2_1, zero), offset_in));\n            in2_2_f_lo = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpacklo_epi16(in2_2, zero), offset_in));\n            in2_2_f_hi = _mm256_cvtepi32_ps(_mm256_add_epi32(_mm256_unpackhi_epi16(in2_2, zero), offset_in));\n          }\n        } // end of integer to float conversion and offset_in adjustment\n\n        // COMMON matrix multiply code - works for all 4 directions!\n\n        auto matrix_multiply = [&](\n          __m256 in0_lo, __m256 in0_hi,\n          __m256 in1_lo, __m256 in1_hi,\n          __m256 in2_lo, __m256 in2_hi,\n          __m256& out0_lo, __m256& out0_hi,\n          __m256& out1_lo, __m256& out1_hi,\n          __m256& out2_lo, __m256& out2_hi)\n          {\n            XP_LAMBDA_CAPTURE_FIX(coeff_out0_in0);\n            XP_LAMBDA_CAPTURE_FIX(coeff_out0_in1);\n            XP_LAMBDA_CAPTURE_FIX(coeff_out0_in2);\n            XP_LAMBDA_CAPTURE_FIX(coeff_out1_in0);\n            XP_LAMBDA_CAPTURE_FIX(coeff_out1_in1);\n            XP_LAMBDA_CAPTURE_FIX(coeff_out1_in2);\n            XP_LAMBDA_CAPTURE_FIX(coeff_out2_in0);\n            XP_LAMBDA_CAPTURE_FIX(coeff_out2_in1);\n            XP_LAMBDA_CAPTURE_FIX(coeff_out2_in2);\n            XP_LAMBDA_CAPTURE_FIX(m_offset_out_y_or_g_f);\n            XP_LAMBDA_CAPTURE_FIX(m_offset_out_u_or_b_f);\n            XP_LAMBDA_CAPTURE_FIX(m_offset_out_v_or_r_f);\n\n            out0_lo = _mm256_fmadd_ps(coeff_out0_in2, in2_lo, _mm256_fmadd_ps(coeff_out0_in1, in1_lo, _mm256_fmadd_ps(coeff_out0_in0, in0_lo, m_offset_out_y_or_g_f)));\n            out0_hi = _mm256_fmadd_ps(coeff_out0_in2, in2_hi, _mm256_fmadd_ps(coeff_out0_in1, in1_hi, _mm256_fmadd_ps(coeff_out0_in0, in0_hi, m_offset_out_y_or_g_f)));\n\n            if constexpr (direction != ConversionDirection::RGB_TO_Y) {\n\n              out1_lo = _mm256_fmadd_ps(coeff_out1_in2, in2_lo, _mm256_fmadd_ps(coeff_out1_in1, in1_lo, _mm256_fmadd_ps(coeff_out1_in0, in0_lo, m_offset_out_u_or_b_f)));\n              out1_hi = _mm256_fmadd_ps(coeff_out1_in2, in2_hi, _mm256_fmadd_ps(coeff_out1_in1, in1_hi, _mm256_fmadd_ps(coeff_out1_in0, in0_hi, m_offset_out_u_or_b_f)));\n\n              out2_lo = _mm256_fmadd_ps(coeff_out2_in2, in2_lo, _mm256_fmadd_ps(coeff_out2_in1, in1_lo, _mm256_fmadd_ps(coeff_out2_in0, in0_lo, m_offset_out_v_or_r_f)));\n              out2_hi = _mm256_fmadd_ps(coeff_out2_in2, in2_hi, _mm256_fmadd_ps(coeff_out2_in1, in1_hi, _mm256_fmadd_ps(coeff_out2_in0, in0_hi, m_offset_out_v_or_r_f)));\n            }\n          };\n\n        // output variables\n        __m256 out0_1_f_lo, out0_1_f_hi, out1_1_f_lo, out1_1_f_hi, out2_1_f_lo, out2_1_f_hi;\n        __m256 out0_2_f_lo, out0_2_f_hi, out1_2_f_lo, out1_2_f_hi, out2_2_f_lo, out2_2_f_hi;\n\n        // SET#1: First 16 pixels\n        matrix_multiply(\n          in0_1_f_lo, in0_1_f_hi, in1_1_f_lo, in1_1_f_hi, in2_1_f_lo, in2_1_f_hi, // in0 in1 in2\n          out0_1_f_lo, out0_1_f_hi, out1_1_f_lo, out1_1_f_hi, out2_1_f_lo, out2_1_f_hi // out0 out1 out2: Pixels 0..7 in lo, 8..15 in hi\n        );\n\n        // SET#2: Next 16 pixels\n        matrix_multiply(\n          in0_2_f_lo, in0_2_f_hi, in1_2_f_lo, in1_2_f_hi, in2_2_f_lo, in2_2_f_hi, // in0 in1 in2\n          out0_2_f_lo, out0_2_f_hi, out1_2_f_lo, out1_2_f_hi, out2_2_f_lo, out2_2_f_hi // out0 out1 out2: Pixels 16..23 in lo, 24..31 in hi\n        );\n\n        auto process_from_float_plane_avx2 = [&](BYTE* plane_ptr, __m256 lo_1, __m256 hi_1, __m256 lo_2, __m256 hi_2) {\n          XP_LAMBDA_CAPTURE_FIX(zero);\n          XP_LAMBDA_CAPTURE_FIX(limit);\n\n#ifdef XP_TLS\n          if (final_is_float) {\n#else\n          if constexpr (final_is_float) {\n#endif\n            // float inside path, + 32 bit float output\n            const int pix_idx = x / sizeof(pixel_t);\n            float* f_dst = reinterpret_cast<float*>(plane_ptr) + pix_idx;\n\n            // Define the blocks (8 pixels each) correctly by healing the lanes\n            // Remember: this is still quicker that using lane-preserving cvt's earlier.\n            __m256 blockA, blockB, blockC, blockD;\n\n            if constexpr (sizeof(pixel_t) == 1) {\n              // 8-bit: The lanes were swapped across res1 and res2\n              blockA = _mm256_permute2f128_ps(lo_1, hi_1, 0x20); // Pixels 0-7\n              blockB = _mm256_permute2f128_ps(lo_2, hi_2, 0x20); // Pixels 8-15\n              blockC = _mm256_permute2f128_ps(lo_1, hi_1, 0x31); // Pixels 16-23\n              blockD = _mm256_permute2f128_ps(lo_2, hi_2, 0x31); // Pixels 24-31\n            }\n            else if constexpr (sizeof(pixel_t) == 2) {\n              // 16-bit: res1 is 0-15, res2 is 16-31\n              blockA = _mm256_permute2f128_ps(lo_1, hi_1, 0x20); // Pixels 0-7\n              blockB = _mm256_permute2f128_ps(lo_1, hi_1, 0x31); // Pixels 8-15\n              blockC = _mm256_permute2f128_ps(lo_2, hi_2, 0x20); // Pixels 16-23\n              blockD = _mm256_permute2f128_ps(lo_2, hi_2, 0x31); // Pixels 24-31\n            }\n            else {\n              // 32-bit: no lane swap needed, but we still need to define the blocks for the tail processing\n              blockA = lo_1; // Pixels 0-7\n              blockB = hi_1; // Pixels 8-15\n              blockC = lo_2; // Pixels 16-23\n              blockD = hi_2; // Pixels 24-31\n            }\n\n            _mm256_store_ps(f_dst, blockA);\n            _mm256_store_ps(f_dst + 8, blockB);\n\n            // Safety check: only store the first half of the 32-pixel block if row width allows\n            if (safe_last_16float_64bytes) {\n              _mm256_store_ps(f_dst + 16, blockC);\n              _mm256_store_ps(f_dst + 24, blockD);\n            }\n          }\n          else {\n            // Float workflow + integer output with rounding and clamping\n            // r,g,b = static_cast<int>(r,g,b_f + 0.5f);\n            // back to int32 domain\n            __m256 float_rounder = _mm256_set1_ps(0.5f);\n            __m256i res1_lo = _mm256_cvttps_epi32(_mm256_add_ps(lo_1, float_rounder));\n            __m256i res1_hi = _mm256_cvttps_epi32(_mm256_add_ps(hi_1, float_rounder));\n            __m256i res2_lo = _mm256_cvttps_epi32(_mm256_add_ps(lo_2, float_rounder));\n            __m256i res2_hi = _mm256_cvttps_epi32(_mm256_add_ps(hi_2, float_rounder));\n\n            const int pix_idx = x * sizeof(pixel_t_dst) / sizeof(pixel_t);\n\n            __m256i p1 = _mm256_packus_epi32(res1_lo, res1_hi);\n            __m256i p2 = _mm256_packus_epi32(res2_lo, res2_hi);\n\n            if constexpr (sizeof(pixel_t_dst) == 1) {\n              // X->8 bits\n              __m256i final8 = _mm256_packus_epi16(p1, p2);\n              if constexpr (sizeof(pixel_t) == 4) {\n                // 32->8 bits\n                /*\n                  res1_lo: int32 [ 0  1  2  3 |  4  5  6  7]\n                  res1_hi: int32 [ 8  9 10 11 | 12 13 14 15]\n                  res2_lo: int32 [16 17 18 19 | 20 21 22 23]\n                  res2_hi: int32 [24 25 26 27 | 28 29 30 31]\n                  - after packus_epi32:\n                  p1 = [0..3, 8..11 | 4..7, 12..15]\n                  p2 = [16..19, 24..27 | 20..23, 28..31]\n                  - after packus_epi16 p1, p2: (more lane crossing)\n                  p8 = [0..3, 8..11, 16..19, 24..27 | 4..7, 12..15, 20..23, 28..31]\n\n                  I need final8: 32 bytes [0,1,2..31]\n                */\n                __m256i p1 = _mm256_packus_epi32(res1_lo, res1_hi);\n                __m256i p2 = _mm256_packus_epi32(res2_lo, res2_hi);\n                __m256i p8 = _mm256_packus_epi16(p1, p2);\n                // p8 = [0..3, 8..11, 16..19, 24..27 | 4..7, 12..15, 20..23, 28..31]\n                // as 8x int32: [A, B, C, D, E, F, G, H] where we need [A,E,B,F,C,G,D,H]\n                const __m256i idx = _mm256_set_epi32(7, 3, 6, 2, 5, 1, 4, 0);\n                final8 = _mm256_permutevar8x32_epi32(p8, idx);\n              }\n              else if constexpr (sizeof(pixel_t) == 2) {\n                // 16->8 bits\n                final8 = _mm256_permute4x64_epi64(final8, (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6));\n              }\n              else {\n                // 8->8 bits, no change needed\n              }\n              _mm256_store_si256(reinterpret_cast<__m256i*>(plane_ptr + pix_idx), final8);\n            }\n            else if constexpr (sizeof(pixel_t_dst) == 2) {\n              // x->16 bits\n              if constexpr (lessthan16bit_target) {\n                p1 = _mm256_min_epi16(p1, limit);\n                p2 = _mm256_min_epi16(p2, limit);\n              }\n              if constexpr (sizeof(pixel_t) == 1) {\n                // 8->16 bits:\n                /* If we'd not pre-shuffled the input for 8->16 bit, we would need to do this shuffle at the end to heal the lanes:\n                // p1: 0-7  16-23; p2: 8-15 24-31\n                // two shuffles per R G B plane would be needed, so 6 total, Pre-shuffling Y U V is only 3\n                __m256i temp_p1 = _mm256_permute2x128_si256(p1, p2, 0x20); // 0-7, 8-15\n                __m256i temp_p2 = _mm256_permute2x128_si256(p1, p2, 0x31); // 16-23, 24-31\n                p1 = temp_p1;\n                p2 = temp_p2;\n                */\n              }\n              else if constexpr (sizeof(pixel_t) == 4) {\n                // 32->16 bits\n                p1 = _mm256_permute4x64_epi64(p1, (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6)); // 0xD8\n                p2 = _mm256_permute4x64_epi64(p2, (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6)); // 0xD8\n              }\n\n              _mm256_store_si256(reinterpret_cast<__m256i*>(plane_ptr + pix_idx), p1);\n              _mm256_store_si256(reinterpret_cast<__m256i*>(plane_ptr + pix_idx + 32), p2);\n            }\n          }\n          };\n\n        process_from_float_plane_avx2(dstp[0], out0_1_f_lo, out0_1_f_hi, out0_2_f_lo, out0_2_f_hi);\n        if constexpr (direction != ConversionDirection::RGB_TO_Y) {\n          process_from_float_plane_avx2(dstp[1], out1_1_f_lo, out1_1_f_hi, out1_2_f_lo, out1_2_f_hi);\n          process_from_float_plane_avx2(dstp[2], out2_1_f_lo, out2_1_f_hi, out2_2_f_lo, out2_2_f_hi);\n        }\n        // end of float_matrix_workflow\n      }\n      else {\n        // start of integer matrix arithmetic path, both for integer and float target\n        if constexpr (lessthan16bit) {\n          // offset_in is added, stored as negative\n          if constexpr (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::RGB_TO_RGB || direction == ConversionDirection::RGB_TO_Y) {\n            // RGB sources: same input offset for G, B and R\n            in0_1 = _mm256_adds_epi16(in0_1, offset_in); in0_2 = _mm256_adds_epi16(in0_2, offset_in); // G1 G2\n            in1_1 = _mm256_adds_epi16(in1_1, offset_in); in1_2 = _mm256_adds_epi16(in1_2, offset_in); // B1 B2\n            in2_1 = _mm256_adds_epi16(in2_1, offset_in); in2_2 = _mm256_adds_epi16(in2_2, offset_in); // R1 R2\n          }\n          else {\n            // YUV sources: only luma. add, because offset_in is negative\n            in0_1 = _mm256_adds_epi16(in0_1, offset_in); in0_2 = _mm256_adds_epi16(in0_2, offset_in); // Y1 Y2\n          }\n        }\n        else {\n          // make unsigned to signed by flipping MSB\n          if constexpr (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::RGB_TO_RGB || direction == ConversionDirection::RGB_TO_Y) {\n            // RGB sources: same pivoting offset for G, B and R\n            // pivot the pixel, adjust the offset_in separately, if any, later\n            in0_1 = _mm256_xor_si256(in0_1, sign_flip_mask); in0_2 = _mm256_xor_si256(in0_2, sign_flip_mask); // G1 G2\n            in1_1 = _mm256_xor_si256(in1_1, sign_flip_mask); in1_2 = _mm256_xor_si256(in1_2, sign_flip_mask); // B1 B2\n            in2_1 = _mm256_xor_si256(in2_1, sign_flip_mask); in2_2 = _mm256_xor_si256(in2_2, sign_flip_mask); // R1 R2\n          }\n          else {\n            // YUV sources: only pivot luma, chroma will be pivoted and centered together in the next step\n            in0_1 = _mm256_xor_si256(in0_1, sign_flip_mask); in0_2 = _mm256_xor_si256(in0_2, sign_flip_mask); // Y1 Y2\n          }\n        }\n\n        // YUV source: move to signed UV\n        if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::YUV_TO_YUV) {\n          in1_1 = _mm256_sub_epi16(in1_1, half); in1_2 = _mm256_sub_epi16(in1_2, half); // U1 U2\n          in2_1 = _mm256_sub_epi16(in2_1, half); in2_2 = _mm256_sub_epi16(in2_2, half); // V1 V2\n        }\n\n        // pre-unpack MADD pairs\n        // These are common for all R, G, B planes\n        // Pair 1: [U0 Y0 U1 Y1 ... | U8 Y8 U9 Y9 ...]\n        __m256i uy1_lo = _mm256_unpacklo_epi16(in1_1, in0_1);\n        __m256i uy1_hi = _mm256_unpackhi_epi16(in1_1, in0_1);\n        __m256i uy2_lo = _mm256_unpacklo_epi16(in1_2, in0_2);\n        __m256i uy2_hi = _mm256_unpackhi_epi16(in1_2, in0_2);\n\n        // Pair 2: [V0 Rnd V1 Rnd ... | V8 Rnd V9 Rnd ...]\n        __m256i vr1_lo = _mm256_unpacklo_epi16(in2_1, m256i_round_scale);\n        __m256i vr1_hi = _mm256_unpackhi_epi16(in2_1, m256i_round_scale);\n        __m256i vr2_lo = _mm256_unpacklo_epi16(in2_2, m256i_round_scale);\n        __m256i vr2_hi = _mm256_unpackhi_epi16(in2_2, m256i_round_scale);\n\n        // for 16 bit, the rgb_offset is merged into the post patch adjustment\n        // 13 bit fixed point arithmetic rounder 0.5 is 4096. In general: INT_ARITH_SHIFT\n        // Need1:  (m.y_b   m.u_b )     (m.y_b   m.u_b)     (m.y_b   m.u_b)     (m.y_b   m.u_b)   8x16 bit\n        //         (  y3      u3  )     (  y2      u2 )     (  y1      u1 )     (   y0     u0 )   8x16 bit\n        // res1=  (y_b*y3 + u_b*u3)   ...                                                         4x32 bit\n        // Need2:  (m.v_b   round')     (m.y_b   round')     (m.y_b   round')     (m.y_b   round')\n        //         (  v3     4096 )     (  v2     4096 )     (  v1     4096 )     (  v0     4096 )\n        // res2=  (yv_b*v3 + round' )  ...  round' = round + rgb_offset\n\n        // Processing lambda - checked and benchmarked to be inlined nicely -avoids code bloat\n\n        // For v141_xp compatibility: forces the compiler to capture a const variable\n        // that would otherwise be optimized out of nested lambda scopes.\n\n        // integer matrix arithmetic path, followed by integer-integer shift-scaling or 32-bit float conversion.\n        auto process_plane = [&](BYTE* plane_ptr, __m256i m_uy, __m256i m_vr, __m256i v_patch, auto apply_float_offset_out) {\n          XP_LAMBDA_CAPTURE_FIX(limit);\n          XP_LAMBDA_CAPTURE_FIX(safe_last_16float_64bytes);\n          auto madd_scale = [&](__m256i uy, __m256i vr) {\n            XP_LAMBDA_CAPTURE_FIX(v_patch);\n            XP_LAMBDA_CAPTURE_FIX(target_shift);\n            __m256i sum = _mm256_add_epi32(_mm256_madd_epi16(m_uy, uy), _mm256_madd_epi16(m_vr, vr));\n            // 16-bit adjustment (signed patch, offset_in, output rgb offset_in)\n            if constexpr (!lessthan16bit) sum = _mm256_add_epi32(sum, v_patch);\n#ifdef XP_TLS\n            if (!final_is_float)\n#else\n            if constexpr (!final_is_float)\n#endif\n              sum = _mm256_srai_epi32(sum, target_shift); // INT_ARITH_SHIFT - modified with bit-conversion diff, bit fixed point shift\n            return sum;\n            };\n\n          __m256i res1_lo = madd_scale(uy1_lo, vr1_lo); // Pixels 0-3, 8-11\n          __m256i res1_hi = madd_scale(uy1_hi, vr1_hi); // Pixels 4-7, 12-15\n          __m256i res2_lo = madd_scale(uy2_lo, vr2_lo); // Pixels 16-19, 24-27\n          __m256i res2_hi = madd_scale(uy2_hi, vr2_hi); // Pixels 20-23, 28-31\n\n#ifdef XP_TLS\n          if (final_is_float) {\n#else\n          if constexpr (final_is_float) {\n#endif\n            // when float output is needed, convert after scaling, mimic a post-ConvertBits\n            const int pix_idx = x / sizeof(pixel_t);\n            float* f_dst = reinterpret_cast<float*>(plane_ptr) + pix_idx;\n\n            // Define the blocks (8 pixels each) correctly by healing the lanes\n            __m256i blockA = _mm256_permute2x128_si256(res1_lo, res1_hi, 0x20); // Pixels 0-7\n            __m256i blockB, blockC, blockD;\n\n            if constexpr (sizeof(pixel_t) == 1) {\n              // 8-bit: The lanes were swapped across res1 and res2\n              blockB = _mm256_permute2x128_si256(res2_lo, res2_hi, 0x20); // Pixels 8-15\n              blockC = _mm256_permute2x128_si256(res1_lo, res1_hi, 0x31); // Pixels 16-23\n              blockD = _mm256_permute2x128_si256(res2_lo, res2_hi, 0x31); // Pixels 24-31\n            }\n            else {\n              // 16-bit: res1 is 0-15, res2 is 16-31\n              blockB = _mm256_permute2x128_si256(res1_lo, res1_hi, 0x31); // Pixels 8-15\n              blockC = _mm256_permute2x128_si256(res2_lo, res2_hi, 0x20); // Pixels 16-23\n              blockD = _mm256_permute2x128_si256(res2_lo, res2_hi, 0x31); // Pixels 24-31\n            }\n\n            // Convert and Store\n            auto store_block = [&](float* ptr, __m256i b, auto apply_float_offset_out) {\n              if (apply_float_offset_out)\n                _mm256_store_ps(ptr, _mm256_fmadd_ps(_mm256_cvtepi32_ps(b), scale_f_avx2, out_offset_f_avx2));\n              else // only mul, no add, when offset_out is 0 for non Y,R,G,B channels\n                _mm256_store_ps(ptr, _mm256_mul_ps(_mm256_cvtepi32_ps(b), scale_f_avx2));\n              };\n\n            store_block(f_dst, blockA, apply_float_offset_out);\n            store_block(f_dst + 8, blockB, apply_float_offset_out);\n\n            // Safety check: only store the first half of the 32-pixel block if row width allows\n            if (safe_last_16float_64bytes) {\n              store_block(f_dst + 16, blockC, apply_float_offset_out);\n              store_block(f_dst + 24, blockD, apply_float_offset_out);\n            }\n          }\n          else {\n            const int pix_idx = x * sizeof(pixel_t_dst) / sizeof(pixel_t);\n            // unlike SSE2, AVX2 has packus_epi32\n            __m256i p1 = _mm256_packus_epi32(res1_lo, res1_hi); // Auto-heals lanes, no permute needed\n            __m256i p2 = _mm256_packus_epi32(res2_lo, res2_hi);\n\n            if constexpr (sizeof(pixel_t_dst) == 1) {\n              // X->8 bits\n              __m256i final8 = _mm256_packus_epi16(p1, p2);\n              if constexpr (sizeof(pixel_t) == 2) {\n                // 16->8 extra shuffle\n                final8 = _mm256_permute4x64_epi64(final8, (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6));\n              }\n              _mm256_store_si256(reinterpret_cast<__m256i*>(plane_ptr + pix_idx), final8);\n            }\n            else {\n              // X->16 bits\n              if constexpr (lessthan16bit_target) {\n                p1 = _mm256_min_epi16(p1, limit);\n                p2 = _mm256_min_epi16(p2, limit);\n              }\n              if constexpr (sizeof(pixel_t) == 1) {\n                // 8->16 bits:\n                /* If we'd not pre-shuffled the input for 8->16 bit, we would need to do this shuffle at the end to heal the lanes:\n                // p1: 0-7  16-23; p2: 8-15 24-31\n                // two shuffles per R G B plane would be needed, so 6 total, Pre-shuffling Y U V is only 3\n                __m256i temp_p1 = _mm256_permute2x128_si256(p1, p2, 0x20); // 0-7, 8-15\n                __m256i temp_p2 = _mm256_permute2x128_si256(p1, p2, 0x31); // 16-23, 24-31\n                p1 = temp_p1;\n                p2 = temp_p2;\n                */\n              }\n              _mm256_store_si256(reinterpret_cast<__m256i*>(plane_ptr + pix_idx), p1);\n              _mm256_store_si256(reinterpret_cast<__m256i*>(plane_ptr + pix_idx + 32), p2);\n            }\n          }\n          };\n\n        // Process planes, using pre-packed coefficient, and the 16 bit patch if needed\n        process_plane(dstp[0], m_uy_G, m_vr_G, v_patch_G, true /* apply_float_offset_out */);\n        // only Y,R,G,B needs it uniformly, so for YUV, we call it with false\n        // last param: apply_float_offset_out\n        if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::RGB_TO_RGB) {\n          process_plane(dstp[1], m_uy_B, m_vr_B, v_patch_B, true);\n          process_plane(dstp[2], m_uy_R, m_vr_R, v_patch_R, true);\n        }\n        else if constexpr (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::YUV_TO_YUV) {\n          process_plane(dstp[1], m_uy_B, m_vr_B, v_patch_B, false);\n          process_plane(dstp[2], m_uy_R, m_vr_R, v_patch_R, false);\n        }\n        else if constexpr (direction != ConversionDirection::RGB_TO_Y) {\n          // no other planes\n        }\n      } // if float_matrix_workflow else integer_matrix_arithmetic\n    } // x\n    srcp[0] += srcPitch[0];\n    srcp[1] += srcPitch[1];\n    srcp[2] += srcPitch[2];\n    dstp[0] += dstPitch[0];\n    if constexpr (direction != ConversionDirection::RGB_TO_Y) {\n      dstp[1] += dstPitch[1];\n      dstp[2] += dstPitch[2];\n    }\n  } // y\n}\n\n#undef XP_LAMBDA_CAPTURE_FIX\n\n// Further separating cases inside, dispatcher remains relatively simple\ntemplate<ConversionDirection direction, typename pixel_t_src, bool lessthan16bit>\nvoid convert_yuv_to_planarrgb_avx2(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m,\n  int bits_per_pixel, int bits_per_pixel_target, bool force_float)\n{\n  // Accuracy forever\n  if (force_float || std::is_floating_point<pixel_t_src>::value) {\n    // int->float conversion\n    // limited/full is handled automatically through scaling and offsets\n    // lessthan16bit_target is still important due to clamping\n    if (bits_per_pixel_target == 8) {\n      convert_yuv_to_planarrgb_avx2_internal<direction, pixel_t_src, lessthan16bit, true, uint8_t, YuvRgbConversionType::FORCE_FLOAT>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n    }\n    else if (bits_per_pixel_target < 16) {\n      // lessthan16bit_target is false. Need signed pack and clamping\n      convert_yuv_to_planarrgb_avx2_internal<direction, pixel_t_src, lessthan16bit, true, uint16_t, YuvRgbConversionType::FORCE_FLOAT>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n    }\n    else if (bits_per_pixel_target == 16) { // == 16\n      convert_yuv_to_planarrgb_avx2_internal<direction, pixel_t_src, lessthan16bit, false, uint16_t, YuvRgbConversionType::FORCE_FLOAT>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n    }\n    else { // 32 bit float target\n      // limited/full is handled automatically through scaling and offsets\n      // lessthan16bit_target doesn't matter since float output has no clamping\n      convert_yuv_to_planarrgb_avx2_internal<direction, pixel_t_src, lessthan16bit, false, float, YuvRgbConversionType::FORCE_FLOAT>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n    }\n    return;\n  }\n\n  // this is needed to avoid instantiating the full integer conversion logic when not needed,\n  // it can result static_asssert failure.\n  if constexpr (!std::is_floating_point<pixel_t_src>::value) {\n    const bool need_conversion = bits_per_pixel_target != bits_per_pixel;\n    if (!need_conversion) {\n      // no conversion, just YUV to RGB\n      convert_yuv_to_planarrgb_avx2_internal<direction, pixel_t_src, lessthan16bit, lessthan16bit, pixel_t_src, YuvRgbConversionType::NATIVE_INT>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n      return;\n    }\n\n    const bool full_d = m.offset_rgb == 0;\n\n    if (bits_per_pixel_target >= 8 && bits_per_pixel <= 16) {\n      // int->int conversion with range conversion (limited<->full), or upscale with no range conversion (full->full or limited->limited)\n      if (bits_per_pixel_target == 8) {\n        if (full_d)\n          convert_yuv_to_planarrgb_avx2_internal<direction, pixel_t_src, lessthan16bit, true, uint8_t, YuvRgbConversionType::BITCONV_INT_FULL>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n        else\n          convert_yuv_to_planarrgb_avx2_internal<direction, pixel_t_src, lessthan16bit, true, uint8_t, YuvRgbConversionType::BITCONV_INT_LIMITED>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n      }\n      else if (bits_per_pixel_target < 16) {\n        // lessthan16bit_target is false. Need signed pack and clamping\n        if (full_d)\n          convert_yuv_to_planarrgb_avx2_internal<direction, pixel_t_src, lessthan16bit, true, uint16_t, YuvRgbConversionType::BITCONV_INT_FULL>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n        else\n          convert_yuv_to_planarrgb_avx2_internal<direction, pixel_t_src, lessthan16bit, true, uint16_t, YuvRgbConversionType::BITCONV_INT_LIMITED>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n      }\n      else if (bits_per_pixel_target == 16) { // == 16\n        if (full_d)\n          convert_yuv_to_planarrgb_avx2_internal<direction, pixel_t_src, lessthan16bit, false, uint16_t, YuvRgbConversionType::BITCONV_INT_FULL>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n        else\n          convert_yuv_to_planarrgb_avx2_internal<direction, pixel_t_src, lessthan16bit, false, uint16_t, YuvRgbConversionType::BITCONV_INT_LIMITED>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n      }\n      else { // 32 bit float target\n        // int->float conversion\n        // limited/full is handled automatically through scaling and offsets\n        // lessthan16bit_target doesn't matter since float output has no clamping\n        convert_yuv_to_planarrgb_avx2_internal<direction, pixel_t_src, lessthan16bit, false, float, YuvRgbConversionType::FLOAT_OUTPUT /*n/a*/>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n      }\n    }\n  }\n}\n\n//instantiate\n// YUV_TO_RGB\ntemplate void convert_yuv_to_planarrgb_avx2<ConversionDirection::YUV_TO_RGB, uint8_t, true>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_avx2<ConversionDirection::YUV_TO_RGB, uint16_t, true>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_avx2<ConversionDirection::YUV_TO_RGB, uint16_t, false>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_avx2<ConversionDirection::YUV_TO_RGB, float, false>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\n\n// RGB_TO_YUV\ntemplate void convert_yuv_to_planarrgb_avx2<ConversionDirection::RGB_TO_YUV, uint8_t, true>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_avx2<ConversionDirection::RGB_TO_YUV, uint16_t, true>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_avx2<ConversionDirection::RGB_TO_YUV, uint16_t, false>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_avx2<ConversionDirection::RGB_TO_YUV, float, false>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\n\n// RGB_TO_Y\ntemplate void convert_yuv_to_planarrgb_avx2<ConversionDirection::RGB_TO_Y, uint8_t, true>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_avx2<ConversionDirection::RGB_TO_Y, uint16_t, true>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_avx2<ConversionDirection::RGB_TO_Y, uint16_t, false>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_avx2<ConversionDirection::RGB_TO_Y, float, false>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\n\n// YUV_TO_YUV (for future use - e.g., BT.601 → BT.709)\ntemplate void convert_yuv_to_planarrgb_avx2<ConversionDirection::YUV_TO_YUV, uint8_t, true>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_avx2<ConversionDirection::YUV_TO_YUV, uint16_t, true>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_avx2<ConversionDirection::YUV_TO_YUV, uint16_t, false>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_avx2<ConversionDirection::YUV_TO_YUV, float, false>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\n\nDISABLE_WARNING_POP\n"
  },
  {
    "path": "avs_core/convert/intel/convert_planar_avx2.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Convert_PLANAR_AVX2_H__\n#define __Convert_PLANAR_AVX2_H__\n\n#include <avs/types.h>\n#include \"../convert_matrix.h\"\n#include \"../convert_helper.h\"\n\ntemplate<int rgb_pixel_step, bool hasAlpha>\nvoid convert_yv24_to_rgb_avx2(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE* srcV, const BYTE* srcA, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t src_pitch_a, size_t width, size_t height, const ConversionMatrix& matrix);\n\ntemplate<ConversionDirection direction, typename pixel_t_src, bool lessthan16bit>\nvoid convert_yuv_to_planarrgb_avx2(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m,\n  int bits_per_pixel, int bits_per_pixel_target, bool force_float);\n\n#endif\n"
  },
  {
    "path": "avs_core/convert/intel/convert_planar_sse.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// ConvertPlanar (c) 2005 by Klaus Post\n\n\n#include \"../convert.h\"\n#include \"../convert_matrix.h\"\n#include \"../convert_planar.h\"\n#include \"../convert_helper.h\"\n\n#ifdef AVS_WINDOWS\n    #include <avs/win.h>\n#else\n    #include <avs/posix.h>\n#endif\n\n#include <avs/alignment.h>\n\n// Intrinsics base header + really required extension headers\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n#include <smmintrin.h> // SSE4.1\n\n#include <algorithm>\n#include <string>\n\nDISABLE_WARNING_PUSH\nDISABLE_WARNING_UNREFERENCED_LOCAL_VARIABLE\n\n\nvoid convert_yuy2_to_y8_sse2(const BYTE *srcp, BYTE *dstp, size_t src_pitch, size_t dst_pitch, size_t width, size_t height)\n{\n  __m128i luma_mask = _mm_set1_epi16(0xFF);\n\n  for(size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < width; x += 16) {\n      __m128i src1 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp+x*2));\n      __m128i src2 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp+x*2+16));\n      src1 = _mm_and_si128(src1, luma_mask);\n      src2 = _mm_and_si128(src2, luma_mask);\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp+x), _mm_packus_epi16(src1, src2));\n    }\n\n    dstp += dst_pitch;\n    srcp += src_pitch;\n  }\n}\n\n#if 0\n// Kept for reference\nstatic AVS_FORCEINLINE __m128i convert_rgb_to_y8_sse2_core(const __m128i &pixel01, const __m128i &pixel23, const __m128i &pixel45, const __m128i &pixel67, __m128i& zero, __m128i &matrix, __m128i &round_mask, __m128i &offset) {\n  //int Y = offset_y + ((m0 * srcp[0] + m1 * srcp[1] + m2 * srcp[2] + 16384) >> 15);\n  // in general the algorithm is identical to MMX version, the only different part is getting r and g+b in appropriate registers. We use shuffling instead of unpacking here.\n  __m128i pixel01m = _mm_madd_epi16(pixel01, matrix); //a1*0 + r1*cyr | g1*cyg + b1*cyb | a0*0 + r0*cyr | g0*cyg + b0*cyb\n  __m128i pixel23m = _mm_madd_epi16(pixel23, matrix); //a3*0 + r3*cyr | g3*cyg + b3*cyb | a2*0 + r2*cyr | g2*cyg + b2*cyb\n  __m128i pixel45m = _mm_madd_epi16(pixel45, matrix); //a5*0 + r5*cyr | g5*cyg + b5*cyb | a4*0 + r4*cyr | g4*cyg + b4*cyb\n  __m128i pixel67m = _mm_madd_epi16(pixel67, matrix); //a7*0 + r7*cyr | g7*cyg + b7*cyb | a6*0 + r6*cyr | g6*cyg + b6*cyb\n\n  __m128i pixel_0123_r = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(pixel01m), _mm_castsi128_ps(pixel23m), _MM_SHUFFLE(3, 1, 3, 1))); // r3*cyr | r2*cyr | r1*cyr | r0*cyr\n  __m128i pixel_4567_r = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(pixel45m), _mm_castsi128_ps(pixel67m), _MM_SHUFFLE(3, 1, 3, 1))); // r7*cyr | r6*cyr | r5*cyr | r4*cyr\n\n  __m128i pixel_0123 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(pixel01m), _mm_castsi128_ps(pixel23m), _MM_SHUFFLE(2, 0, 2, 0)));\n  __m128i pixel_4567 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(pixel45m), _mm_castsi128_ps(pixel67m), _MM_SHUFFLE(2, 0, 2, 0)));\n\n  pixel_0123 = _mm_add_epi32(pixel_0123, pixel_0123_r);\n  pixel_4567 = _mm_add_epi32(pixel_4567, pixel_4567_r);\n\n  pixel_0123 = _mm_add_epi32(pixel_0123, round_mask);\n  pixel_4567 = _mm_add_epi32(pixel_4567, round_mask);\n\n  pixel_0123 = _mm_srai_epi32(pixel_0123, 15);\n  pixel_4567 = _mm_srai_epi32(pixel_4567, 15);\n\n  __m128i result = _mm_packs_epi32(pixel_0123, pixel_4567);\n\n  result = _mm_adds_epi16(result, offset);\n  result = _mm_packus_epi16(result, zero);\n\n  return result;\n}\n\nvoid convert_rgb32_to_y8_sse2(const BYTE *srcp, BYTE *dstp, size_t src_pitch, size_t dst_pitch, size_t width, size_t height, const ConversionMatrix &matrix) {\n  __m128i matrix_v = _mm_set_epi16(0, matrix.y_r, matrix.y_g, matrix.y_b, 0, matrix.y_r, matrix.y_g, matrix.y_b);\n  __m128i zero = _mm_setzero_si128();\n  __m128i offset = _mm_set1_epi16(matrix.offset_y);\n  __m128i round_mask = _mm_set1_epi32(16384);\n  __m128i offset_rgb = _mm_set_epi16(0, matrix.offset_rgb, matrix.offset_rgb, matrix.offset_rgb, 0, matrix.offset_rgb, matrix.offset_rgb, matrix.offset_rgb);\n\n  const bool has_offset_rgb = 0 != matrix.offset_rgb;\n\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < width; x+=8) {\n      __m128i src0123 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp+x*4)); //pixels 0, 1, 2 and 3\n      __m128i src4567 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp+x*4+16));//pixels 4, 5, 6 and 7\n\n      __m128i pixel01 = _mm_unpacklo_epi8(src0123, zero);\n      __m128i pixel23 = _mm_unpackhi_epi8(src0123, zero);\n      __m128i pixel45 = _mm_unpacklo_epi8(src4567, zero);\n      __m128i pixel67 = _mm_unpackhi_epi8(src4567, zero);\n      if (has_offset_rgb) {\n        pixel01 = _mm_add_epi16(pixel01, offset_rgb);\n        pixel23 = _mm_add_epi16(pixel23, offset_rgb);\n        pixel45 = _mm_add_epi16(pixel45, offset_rgb);\n        pixel67 = _mm_add_epi16(pixel67, offset_rgb);\n      }\n\n      _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp+x), convert_rgb_to_y8_sse2_core(pixel01, pixel23, pixel45, pixel67, zero, matrix_v, round_mask, offset));\n    }\n\n    srcp -= src_pitch;\n    dstp += dst_pitch;\n  }\n}\n#endif // if 0\n\n#define XP_LAMBDA_CAPTURE_FIX(x) (void)(x)\n\n// SSE2 implementation matching AVX2 logic - processes 8 pixels per iteration\n// Supports all conversion directions, bit depths, and conversion types\ntemplate<ConversionDirection direction, typename pixel_t, bool lessthan16bit, bool lessthan16bit_target, typename pixel_t_dst, YuvRgbConversionType conv_type>\nstatic void convert_yuv_to_planarrgb_sse2_internal(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m,\n  int bits_per_pixel, int bits_per_pixel_target)\n{\n  // SSE2 version: processes 8 pixels at a time (vs 32 for AVX2)\n  constexpr int INT_ARITH_SHIFT =\n    (direction == ConversionDirection::YUV_TO_RGB) ? 13 :\n    (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::RGB_TO_Y) ? 15 :\n    (direction == ConversionDirection::YUV_TO_YUV) ? 14 : 13;\n\n  static_assert(!(std::is_floating_point<pixel_t>::value && conv_type != YuvRgbConversionType::FORCE_FLOAT), \"FORCE_FLOAT conversion type is required for float input pixel type\");\n\n  constexpr bool force_float = conv_type == YuvRgbConversionType::FORCE_FLOAT;\n  constexpr bool final_is_float = std::is_floating_point<pixel_t_dst>::value;\n  constexpr bool need_int_conversion_narrow_range = conv_type == YuvRgbConversionType::BITCONV_INT_LIMITED;\n  constexpr bool need_int_conversion_full_range = conv_type == YuvRgbConversionType::BITCONV_INT_FULL;\n  constexpr bool need_int_conversion = conv_type == YuvRgbConversionType::BITCONV_INT_FULL || conv_type == YuvRgbConversionType::BITCONV_INT_LIMITED ||\n    (conv_type == YuvRgbConversionType::FORCE_FLOAT && !final_is_float);\n  const bool float_matrix_workflow = force_float || need_int_conversion_full_range;\n\n  // quasi-constexpr, may help optimizer\n  if constexpr (std::is_same<pixel_t, uint8_t>::value) bits_per_pixel = 8;\n  if constexpr (std::is_same<pixel_t_dst, uint8_t>::value) bits_per_pixel_target = 8;\n  if constexpr (std::is_same<pixel_t, uint16_t>::value && !lessthan16bit) bits_per_pixel = 16;\n  if constexpr (std::is_same<pixel_t_dst, uint16_t>::value && !lessthan16bit_target) bits_per_pixel_target = 16;\n  if constexpr (conv_type == YuvRgbConversionType::NATIVE_INT) bits_per_pixel_target = bits_per_pixel;\n\n  const int bit_diff = need_int_conversion ? bits_per_pixel_target - bits_per_pixel : 0;\n  const int target_shift = need_int_conversion_narrow_range ? INT_ARITH_SHIFT - bit_diff : INT_ARITH_SHIFT;\n  const int ROUNDER = (final_is_float || float_matrix_workflow) ? 0 : (1 << (target_shift - 1));\n  const float out_offset_f = m.offset_out_f_32;\n  const int half_pixel_offset = 1 << (bits_per_pixel - 1);\n  const int half_pixel_offset_target = 1 << (bits_per_pixel_target - 1);\n  const int max_pixel_value_target = (1 << bits_per_pixel_target) - 1;\n\n  bits_conv_constants conversion_ranges;\n  const bool full_scale_d = m.offset_out == 0;\n  get_bits_conv_constants(conversion_ranges, false, full_scale_d, full_scale_d, bits_per_pixel, bits_per_pixel_target);\n\n  constexpr int int_arithmetic_shift = 1 << INT_ARITH_SHIFT;\n  float scale_f = conversion_ranges.mul_factor;\n  if (final_is_float && !float_matrix_workflow)\n    scale_f = scale_f / int_arithmetic_shift;\n\n  __m128i half = _mm_set1_epi16((short)half_pixel_offset);\n  __m128i limit = _mm_set1_epi16((short)max_pixel_value_target);\n\n  constexpr int ROUND_SCALE = 1 << (INT_ARITH_SHIFT - 1);\n  const __m128i m128i_round_scale = _mm_set1_epi16(ROUND_SCALE);\n\n  int round_mask_plus_offset_out_scaled_i;\n  int round_mask_plus_offset_out_chroma_scaled_i;\n  __m128i v_patch_G, v_patch_B, v_patch_R;\n  __m128i sign_flip_mask = _mm_set1_epi16((short)0x8000);\n\n  const int offset_in_scalar = m.offset_in;\n  const int offset_out_scalar = m.offset_out;\n  __m128i offset_in;\n  __m128 offset_in_f;\n\n  if constexpr (float_matrix_workflow) {\n    offset_in = _mm_set1_epi32(offset_in_scalar);\n    offset_in_f = _mm_set1_ps(m.offset_in_f);\n  }\n  else if constexpr (lessthan16bit)\n    offset_in = _mm_set1_epi16((short)offset_in_scalar);\n  else\n    offset_in = _mm_setzero_si128();\n\n  if constexpr (!float_matrix_workflow) {\n    if constexpr (lessthan16bit) {\n      round_mask_plus_offset_out_scaled_i = final_is_float ? 0 : (ROUNDER + (offset_out_scalar << INT_ARITH_SHIFT)) / ROUND_SCALE;\n      round_mask_plus_offset_out_chroma_scaled_i = final_is_float ? 0 : (ROUNDER + (half_pixel_offset << INT_ARITH_SHIFT)) / ROUND_SCALE;\n      v_patch_G = v_patch_B = v_patch_R = _mm_setzero_si128();\n    }\n    else {\n      round_mask_plus_offset_out_scaled_i = ROUNDER / ROUND_SCALE;\n      round_mask_plus_offset_out_chroma_scaled_i = ROUNDER / ROUND_SCALE;\n      const int luma_or_rgbin_pivot = 32768 + offset_in_scalar;\n      const int chroma_pivot = 32768;\n      const int offset_out_for_patch = final_is_float ? 0 : (offset_out_scalar << INT_ARITH_SHIFT);\n      const int chroma_offset_out_for_patch = final_is_float ? 0 : (half_pixel_offset << INT_ARITH_SHIFT);\n\n      if constexpr (direction == ConversionDirection::YUV_TO_RGB) {\n        v_patch_G = _mm_set1_epi32(luma_or_rgbin_pivot * m.y_g + offset_out_for_patch);\n        v_patch_B = _mm_set1_epi32(luma_or_rgbin_pivot * m.y_b + offset_out_for_patch);\n        v_patch_R = _mm_set1_epi32(luma_or_rgbin_pivot * m.y_r + offset_out_for_patch);\n      }\n      else if constexpr (direction == ConversionDirection::RGB_TO_RGB) {\n        v_patch_G = _mm_set1_epi32(luma_or_rgbin_pivot * (m.y_g + m.u_g + m.v_g) + offset_out_for_patch);\n        v_patch_B = _mm_set1_epi32(luma_or_rgbin_pivot * (m.y_b + m.u_b + m.v_b) + offset_out_for_patch);\n        v_patch_R = _mm_set1_epi32(luma_or_rgbin_pivot * (m.y_r + m.u_r + m.v_r) + offset_out_for_patch);\n      }\n      else if constexpr (direction == ConversionDirection::RGB_TO_YUV) {\n        v_patch_G = _mm_set1_epi32(luma_or_rgbin_pivot * (m.y_r + m.y_g + m.y_b) + offset_out_for_patch);\n        v_patch_B = _mm_set1_epi32(luma_or_rgbin_pivot * (m.u_r + m.u_g + m.u_b) + chroma_offset_out_for_patch);\n        v_patch_R = _mm_set1_epi32(luma_or_rgbin_pivot * (m.v_r + m.v_g + m.v_b) + chroma_offset_out_for_patch);\n      }\n      else if constexpr (direction == ConversionDirection::RGB_TO_Y) {\n        v_patch_G = _mm_set1_epi32(luma_or_rgbin_pivot * (m.y_r + m.y_g + m.y_b) + offset_out_for_patch);\n      }\n      else { // YUV_TO_YUV\n        // FIXME: untested, no AviSynth caller yet. Suspect m.y_b/m.y_r should be\n        // m.u_b/m.v_r (chroma diagonal), and offset should be chroma_offset_out_for_patch.\n        v_patch_G = _mm_set1_epi32(luma_or_rgbin_pivot * m.y_g + offset_out_for_patch);\n        v_patch_B = _mm_set1_epi32(chroma_pivot * m.y_b + offset_out_for_patch);\n        v_patch_R = _mm_set1_epi32(chroma_pivot * m.y_r + offset_out_for_patch);\n      }\n    }\n  }\n\n  const __m128 out_offset_f_sse2 = _mm_set1_ps(out_offset_f);\n  __m128i zero = _mm_setzero_si128();\n  const __m128 scale_f_sse2 = _mm_set1_ps(scale_f);\n\n  __m128i m_uy_G, m_vr_G, m_uy_B, m_vr_B, m_uy_R, m_vr_R;\n  __m128 coeff_out0_in0, coeff_out0_in1, coeff_out0_in2;\n  __m128 coeff_out1_in0, coeff_out1_in1, coeff_out1_in2;\n  __m128 coeff_out2_in0, coeff_out2_in1, coeff_out2_in2;\n  __m128 m_offset_out_y_or_g_f, m_offset_out_u_or_b_f, m_offset_out_v_or_r_f;\n\n  if constexpr (float_matrix_workflow) {\n    __m128 m_y_g_f, m_y_b_f, m_y_r_f, m_u_g_f, m_u_b_f, m_u_r_f, m_v_g_f, m_v_b_f, m_v_r_f;\n    m_y_g_f = _mm_mul_ps(_mm_set1_ps(m.y_g_f), scale_f_sse2);\n    m_y_b_f = _mm_mul_ps(_mm_set1_ps(m.y_b_f), scale_f_sse2);\n    m_y_r_f = _mm_mul_ps(_mm_set1_ps(m.y_r_f), scale_f_sse2);\n    if constexpr (direction != ConversionDirection::RGB_TO_Y) {\n      m_u_g_f = _mm_mul_ps(_mm_set1_ps(m.u_g_f), scale_f_sse2);\n      m_u_b_f = _mm_mul_ps(_mm_set1_ps(m.u_b_f), scale_f_sse2);\n      m_u_r_f = _mm_mul_ps(_mm_set1_ps(m.u_r_f), scale_f_sse2);\n      m_v_g_f = _mm_mul_ps(_mm_set1_ps(m.v_g_f), scale_f_sse2);\n      m_v_b_f = _mm_mul_ps(_mm_set1_ps(m.v_b_f), scale_f_sse2);\n      m_v_r_f = _mm_mul_ps(_mm_set1_ps(m.v_r_f), scale_f_sse2);\n    }\n\n    if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::RGB_TO_RGB) {\n      float rgb_out_offset_scaled = m.offset_out_f * scale_f;\n      m_offset_out_y_or_g_f = _mm_set1_ps(rgb_out_offset_scaled);\n      m_offset_out_u_or_b_f = _mm_set1_ps(rgb_out_offset_scaled);\n      m_offset_out_v_or_r_f = _mm_set1_ps(rgb_out_offset_scaled);\n    }\n    else if constexpr (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::YUV_TO_YUV) {\n      float y_out_offset_scaled = m.offset_out_f * scale_f;\n      float uv_center_offset = final_is_float ? 0.0f : (float)half_pixel_offset_target;\n      m_offset_out_y_or_g_f = _mm_set1_ps(y_out_offset_scaled);\n      m_offset_out_u_or_b_f = _mm_set1_ps(uv_center_offset);\n      m_offset_out_v_or_r_f = _mm_set1_ps(uv_center_offset);\n    }\n    else if constexpr (direction == ConversionDirection::RGB_TO_Y) {\n      float y_out_offset_scaled = m.offset_out_f * scale_f;\n      m_offset_out_y_or_g_f = _mm_set1_ps(y_out_offset_scaled);\n    }\n\n    if constexpr (direction == ConversionDirection::YUV_TO_RGB) {\n      coeff_out0_in0 = m_y_g_f; coeff_out0_in1 = m_u_g_f; coeff_out0_in2 = m_v_g_f;\n      coeff_out1_in0 = m_y_b_f; coeff_out1_in1 = m_u_b_f; coeff_out1_in2 = m_v_b_f;\n      coeff_out2_in0 = m_y_r_f; coeff_out2_in1 = m_u_r_f; coeff_out2_in2 = m_v_r_f;\n    }\n    else if constexpr (direction == ConversionDirection::RGB_TO_YUV) {\n      coeff_out0_in0 = m_y_g_f; coeff_out0_in1 = m_y_b_f; coeff_out0_in2 = m_y_r_f;\n      coeff_out1_in0 = m_u_g_f; coeff_out1_in1 = m_u_b_f; coeff_out1_in2 = m_u_r_f;\n      coeff_out2_in0 = m_v_g_f; coeff_out2_in1 = m_v_b_f; coeff_out2_in2 = m_v_r_f;\n    }\n    else if constexpr (direction == ConversionDirection::RGB_TO_Y) {\n      coeff_out0_in0 = m_y_g_f; coeff_out0_in1 = m_y_b_f; coeff_out0_in2 = m_y_r_f;\n    }\n    else if constexpr (direction == ConversionDirection::YUV_TO_YUV) {\n      coeff_out0_in0 = m_y_g_f; coeff_out0_in1 = m_u_g_f; coeff_out0_in2 = m_v_g_f;\n      coeff_out1_in0 = m_y_b_f; coeff_out1_in1 = m_u_b_f; coeff_out1_in2 = m_v_b_f;\n      coeff_out2_in0 = m_y_r_f; coeff_out2_in1 = m_u_r_f; coeff_out2_in2 = m_v_r_f;\n    }\n    else if constexpr (direction == ConversionDirection::RGB_TO_RGB) {\n      coeff_out0_in0 = m_y_g_f; coeff_out0_in1 = m_u_g_f; coeff_out0_in2 = m_v_g_f;\n      coeff_out1_in0 = m_y_b_f; coeff_out1_in1 = m_u_b_f; coeff_out1_in2 = m_v_b_f;\n      coeff_out2_in0 = m_y_r_f; coeff_out2_in1 = m_u_r_f; coeff_out2_in2 = m_v_r_f;\n    }\n  }\n  else {\n    // Integer workflow coefficient setup\n    int round_and_out_offset_y_or_g;\n    int round_and_out_offset_u_or_b;\n    int round_and_out_offset_v_or_r;\n\n    if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::RGB_TO_RGB) {\n      round_and_out_offset_y_or_g = round_mask_plus_offset_out_scaled_i;\n      round_and_out_offset_u_or_b = round_mask_plus_offset_out_scaled_i;\n      round_and_out_offset_v_or_r = round_mask_plus_offset_out_scaled_i;\n    }\n    else if constexpr (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::YUV_TO_YUV) {\n      round_and_out_offset_y_or_g = round_mask_plus_offset_out_scaled_i;\n      round_and_out_offset_u_or_b = round_mask_plus_offset_out_chroma_scaled_i;\n      round_and_out_offset_v_or_r = round_mask_plus_offset_out_chroma_scaled_i;\n    }\n    else if constexpr (direction == ConversionDirection::RGB_TO_Y) {\n      round_and_out_offset_y_or_g = round_mask_plus_offset_out_scaled_i;\n    }\n\n    if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::YUV_TO_YUV) {\n      m_uy_G = _mm_set1_epi32((static_cast<uint16_t>(m.y_g) << 16) | static_cast<uint16_t>(m.u_g));\n      m_vr_G = _mm_set1_epi32((static_cast<uint16_t>(round_and_out_offset_y_or_g) << 16) | static_cast<uint16_t>(m.v_g));\n      m_uy_B = _mm_set1_epi32((static_cast<uint16_t>(m.y_b) << 16) | static_cast<uint16_t>(m.u_b));\n      m_vr_B = _mm_set1_epi32((static_cast<uint16_t>(round_and_out_offset_u_or_b) << 16) | static_cast<uint16_t>(m.v_b));\n      m_uy_R = _mm_set1_epi32((static_cast<uint16_t>(m.y_r) << 16) | static_cast<uint16_t>(m.u_r));\n      m_vr_R = _mm_set1_epi32((static_cast<uint16_t>(round_and_out_offset_v_or_r) << 16) | static_cast<uint16_t>(m.v_r));\n    }\n    else if constexpr (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::RGB_TO_RGB) {\n      m_uy_G = _mm_set1_epi32((static_cast<uint16_t>(m.y_g) << 16) | static_cast<uint16_t>(m.y_b));\n      m_vr_G = _mm_set1_epi32((static_cast<uint16_t>(round_and_out_offset_y_or_g) << 16) | static_cast<uint16_t>(m.y_r));\n      m_uy_B = _mm_set1_epi32((static_cast<uint16_t>(m.u_g) << 16) | static_cast<uint16_t>(m.u_b));\n      m_vr_B = _mm_set1_epi32((static_cast<uint16_t>(round_and_out_offset_u_or_b) << 16) | static_cast<uint16_t>(m.u_r));\n      m_uy_R = _mm_set1_epi32((static_cast<uint16_t>(m.v_g) << 16) | static_cast<uint16_t>(m.v_b));\n      m_vr_R = _mm_set1_epi32((static_cast<uint16_t>(round_and_out_offset_v_or_r) << 16) | static_cast<uint16_t>(m.v_r));\n    }\n    else if constexpr (direction == ConversionDirection::RGB_TO_Y) {\n      m_uy_G = _mm_set1_epi32((static_cast<uint16_t>(m.y_g) << 16) | static_cast<uint16_t>(m.y_b));\n      m_vr_G = _mm_set1_epi32((static_cast<uint16_t>(round_and_out_offset_y_or_g) << 16) | static_cast<uint16_t>(m.y_r));\n    }\n  }\n\n  const int rowsize = width * sizeof(pixel_t);\n  for (int yy = 0; yy < height; yy++) {\n    // SSE2: 8 pixels per loop (8×1 byte = 8 bytes, 8×2 bytes = 16 bytes, 8×4 bytes = 32 bytes)\n    for (int x = 0; x < rowsize; x += 8 * sizeof(pixel_t)) {\n      __m128i in0, in1, in2;\n      __m128 in0_f_lo, in0_f_hi, in1_f_lo, in1_f_hi, in2_f_lo, in2_f_hi;\n\n      // Load 8 pixels\n      if constexpr (sizeof(pixel_t) == 1) {\n        __m128i in0_raw = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp[0] + x));\n        __m128i in1_raw = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp[1] + x));\n        __m128i in2_raw = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp[2] + x));\n        in0 = _mm_unpacklo_epi8(in0_raw, zero);\n        in1 = _mm_unpacklo_epi8(in1_raw, zero);\n        in2 = _mm_unpacklo_epi8(in2_raw, zero);\n      }\n      else if constexpr (sizeof(pixel_t) == 2) {\n        in0 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp[0] + x));\n        in1 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp[1] + x));\n        in2 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp[2] + x));\n      }\n      else { // sizeof(pixel_t) == 4\n        in0_f_lo = _mm_load_ps(reinterpret_cast<const float*>(srcp[0] + x));\n        in0_f_hi = _mm_load_ps(reinterpret_cast<const float*>(srcp[0] + x + 16));\n        in1_f_lo = _mm_load_ps(reinterpret_cast<const float*>(srcp[1] + x));\n        in1_f_hi = _mm_load_ps(reinterpret_cast<const float*>(srcp[1] + x + 16));\n        in2_f_lo = _mm_load_ps(reinterpret_cast<const float*>(srcp[2] + x));\n        in2_f_hi = _mm_load_ps(reinterpret_cast<const float*>(srcp[2] + x + 16));\n      }\n\n      if constexpr (float_matrix_workflow) {\n        // Float workflow\n        if constexpr (sizeof(pixel_t) == 4) {\n          // Float input - apply offset_in\n          if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::YUV_TO_YUV) {\n            in0_f_lo = _mm_add_ps(in0_f_lo, offset_in_f);\n            in0_f_hi = _mm_add_ps(in0_f_hi, offset_in_f);\n          }\n          else { // RGB source RGB_TO_RGB, RGB_TO_YUV, RGB_TO_Y\n            in0_f_lo = _mm_add_ps(in0_f_lo, offset_in_f);\n            in0_f_hi = _mm_add_ps(in0_f_hi, offset_in_f);\n            in1_f_lo = _mm_add_ps(in1_f_lo, offset_in_f);\n            in1_f_hi = _mm_add_ps(in1_f_hi, offset_in_f);\n            in2_f_lo = _mm_add_ps(in2_f_lo, offset_in_f);\n            in2_f_hi = _mm_add_ps(in2_f_hi, offset_in_f);\n          }\n        }\n        else {\n          // Integer input - convert to float\n          if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::YUV_TO_YUV) {\n            // Y channel\n            __m128i in0_32_lo = _mm_add_epi32(_mm_unpacklo_epi16(in0, zero), offset_in);\n            __m128i in0_32_hi = _mm_add_epi32(_mm_unpackhi_epi16(in0, zero), offset_in);\n            in0_f_lo = _mm_cvtepi32_ps(in0_32_lo);\n            in0_f_hi = _mm_cvtepi32_ps(in0_32_hi);\n            // U,V: sign-extend and convert\n            auto chroma_to_float = [&](__m128i c, __m128& f_lo, __m128& f_hi) {\n              c = _mm_sub_epi16(c, half);\n              __m128i sign = _mm_srai_epi16(c, 15);\n              f_lo = _mm_cvtepi32_ps(_mm_unpacklo_epi16(c, sign));\n              f_hi = _mm_cvtepi32_ps(_mm_unpackhi_epi16(c, sign));\n              };\n            chroma_to_float(in1, in1_f_lo, in1_f_hi);\n            chroma_to_float(in2, in2_f_lo, in2_f_hi);\n          }\n          else { // RGB source\n            in0_f_lo = _mm_cvtepi32_ps(_mm_add_epi32(_mm_unpacklo_epi16(in0, zero), offset_in));\n            in0_f_hi = _mm_cvtepi32_ps(_mm_add_epi32(_mm_unpackhi_epi16(in0, zero), offset_in));\n            in1_f_lo = _mm_cvtepi32_ps(_mm_add_epi32(_mm_unpacklo_epi16(in1, zero), offset_in));\n            in1_f_hi = _mm_cvtepi32_ps(_mm_add_epi32(_mm_unpackhi_epi16(in1, zero), offset_in));\n            in2_f_lo = _mm_cvtepi32_ps(_mm_add_epi32(_mm_unpacklo_epi16(in2, zero), offset_in));\n            in2_f_hi = _mm_cvtepi32_ps(_mm_add_epi32(_mm_unpackhi_epi16(in2, zero), offset_in));\n          }\n        }\n\n        // Matrix multiply (SSE2 doesn't have FMA, use mul+add)\n        auto matrix_multiply = [&](__m128 i0_lo, __m128 i0_hi, __m128 i1_lo, __m128 i1_hi, __m128 i2_lo, __m128 i2_hi,\n          __m128& o0_lo, __m128& o0_hi, __m128& o1_lo, __m128& o1_hi, __m128& o2_lo, __m128& o2_hi) {\n            XP_LAMBDA_CAPTURE_FIX(coeff_out0_in0); XP_LAMBDA_CAPTURE_FIX(coeff_out0_in1); XP_LAMBDA_CAPTURE_FIX(coeff_out0_in2);\n            XP_LAMBDA_CAPTURE_FIX(coeff_out1_in0); XP_LAMBDA_CAPTURE_FIX(coeff_out1_in1); XP_LAMBDA_CAPTURE_FIX(coeff_out1_in2);\n            XP_LAMBDA_CAPTURE_FIX(coeff_out2_in0); XP_LAMBDA_CAPTURE_FIX(coeff_out2_in1); XP_LAMBDA_CAPTURE_FIX(coeff_out2_in2);\n            XP_LAMBDA_CAPTURE_FIX(m_offset_out_y_or_g_f); XP_LAMBDA_CAPTURE_FIX(m_offset_out_u_or_b_f); XP_LAMBDA_CAPTURE_FIX(m_offset_out_v_or_r_f);\n\n            o0_lo = _mm_add_ps(_mm_mul_ps(coeff_out0_in2, i2_lo), _mm_add_ps(_mm_mul_ps(coeff_out0_in1, i1_lo), _mm_add_ps(_mm_mul_ps(coeff_out0_in0, i0_lo), m_offset_out_y_or_g_f)));\n            o0_hi = _mm_add_ps(_mm_mul_ps(coeff_out0_in2, i2_hi), _mm_add_ps(_mm_mul_ps(coeff_out0_in1, i1_hi), _mm_add_ps(_mm_mul_ps(coeff_out0_in0, i0_hi), m_offset_out_y_or_g_f)));\n            if constexpr (direction != ConversionDirection::RGB_TO_Y) {\n              o1_lo = _mm_add_ps(_mm_mul_ps(coeff_out1_in2, i2_lo), _mm_add_ps(_mm_mul_ps(coeff_out1_in1, i1_lo), _mm_add_ps(_mm_mul_ps(coeff_out1_in0, i0_lo), m_offset_out_u_or_b_f)));\n              o1_hi = _mm_add_ps(_mm_mul_ps(coeff_out1_in2, i2_hi), _mm_add_ps(_mm_mul_ps(coeff_out1_in1, i1_hi), _mm_add_ps(_mm_mul_ps(coeff_out1_in0, i0_hi), m_offset_out_u_or_b_f)));\n              o2_lo = _mm_add_ps(_mm_mul_ps(coeff_out2_in2, i2_lo), _mm_add_ps(_mm_mul_ps(coeff_out2_in1, i1_lo), _mm_add_ps(_mm_mul_ps(coeff_out2_in0, i0_lo), m_offset_out_v_or_r_f)));\n              o2_hi = _mm_add_ps(_mm_mul_ps(coeff_out2_in2, i2_hi), _mm_add_ps(_mm_mul_ps(coeff_out2_in1, i1_hi), _mm_add_ps(_mm_mul_ps(coeff_out2_in0, i0_hi), m_offset_out_v_or_r_f)));\n            }\n          };\n\n        __m128 out0_f_lo, out0_f_hi, out1_f_lo, out1_f_hi, out2_f_lo, out2_f_hi;\n        matrix_multiply(in0_f_lo, in0_f_hi, in1_f_lo, in1_f_hi, in2_f_lo, in2_f_hi,\n          out0_f_lo, out0_f_hi, out1_f_lo, out1_f_hi, out2_f_lo, out2_f_hi);\n\n        auto process_from_float_plane_sse2 = [&](BYTE* plane_ptr, __m128 lo, __m128 hi) {\n          XP_LAMBDA_CAPTURE_FIX(zero); XP_LAMBDA_CAPTURE_FIX(limit);\n#ifdef XP_TLS\n          if (final_is_float) {\n#else\n          if constexpr (final_is_float) {\n#endif\n            const int pix_idx = x / sizeof(pixel_t);\n            float* f_dst = reinterpret_cast<float*>(plane_ptr) + pix_idx;\n            _mm_store_ps(f_dst, lo);\n            _mm_store_ps(f_dst + 4, hi);\n          }\n          else {\n            __m128 float_rounder = _mm_set1_ps(0.5f);\n            __m128i res_lo = _mm_cvttps_epi32(_mm_add_ps(lo, float_rounder));\n            __m128i res_hi = _mm_cvttps_epi32(_mm_add_ps(hi, float_rounder));\n            const int pix_idx = x * sizeof(pixel_t_dst) / sizeof(pixel_t);\n\n            if constexpr (sizeof(pixel_t_dst) == 1) {\n              __m128i p = _mm_packs_epi32(res_lo, res_hi);\n              __m128i final8 = _mm_packus_epi16(p, zero);\n              _mm_storel_epi64(reinterpret_cast<__m128i*>(plane_ptr + pix_idx), final8);\n            }\n            else if constexpr (sizeof(pixel_t_dst) == 2) {\n              __m128i p;\n              if constexpr (lessthan16bit_target) {\n                p = _mm_packs_epi32(res_lo, res_hi);\n                p = _mm_max_epi16(_mm_min_epi16(p, limit), zero);\n              }\n              else {\n                p = _MM_PACKUS_EPI32(res_lo, res_hi);\n              }\n              _mm_store_si128(reinterpret_cast<__m128i*>(plane_ptr + pix_idx), p);\n            }\n          }\n          };\n\n        process_from_float_plane_sse2(dstp[0], out0_f_lo, out0_f_hi);\n        if constexpr (direction != ConversionDirection::RGB_TO_Y) {\n          process_from_float_plane_sse2(dstp[1], out1_f_lo, out1_f_hi);\n          process_from_float_plane_sse2(dstp[2], out2_f_lo, out2_f_hi);\n        }\n      }\n      else {\n        // Integer matrix arithmetic\n        if constexpr (lessthan16bit) {\n          if constexpr (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::RGB_TO_RGB || direction == ConversionDirection::RGB_TO_Y) {\n            in0 = _mm_adds_epi16(in0, offset_in);\n            in1 = _mm_adds_epi16(in1, offset_in);\n            in2 = _mm_adds_epi16(in2, offset_in);\n          }\n          else {\n            in0 = _mm_adds_epi16(in0, offset_in);\n          }\n        }\n        else {\n          if constexpr (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::RGB_TO_RGB || direction == ConversionDirection::RGB_TO_Y) {\n            in0 = _mm_xor_si128(in0, sign_flip_mask);\n            in1 = _mm_xor_si128(in1, sign_flip_mask);\n            in2 = _mm_xor_si128(in2, sign_flip_mask);\n          }\n          else {\n            in0 = _mm_xor_si128(in0, sign_flip_mask);\n          }\n        }\n\n        if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::YUV_TO_YUV) {\n          in1 = _mm_sub_epi16(in1, half);\n          in2 = _mm_sub_epi16(in2, half);\n        }\n\n        __m128i uy_lo = _mm_unpacklo_epi16(in1, in0);\n        __m128i uy_hi = _mm_unpackhi_epi16(in1, in0);\n        __m128i vr_lo = _mm_unpacklo_epi16(in2, m128i_round_scale);\n        __m128i vr_hi = _mm_unpackhi_epi16(in2, m128i_round_scale);\n\n        auto process_plane = [&](BYTE* plane_ptr, __m128i m_uy, __m128i m_vr, __m128i v_patch, auto apply_float_offset_out) {\n          XP_LAMBDA_CAPTURE_FIX(limit);\n          auto madd_scale = [&](__m128i uy, __m128i vr) {\n            XP_LAMBDA_CAPTURE_FIX(v_patch); XP_LAMBDA_CAPTURE_FIX(target_shift);\n            __m128i sum = _mm_add_epi32(_mm_madd_epi16(m_uy, uy), _mm_madd_epi16(m_vr, vr));\n            if constexpr (!lessthan16bit) sum = _mm_add_epi32(sum, v_patch);\n#ifdef XP_TLS\n            if (!final_is_float)\n#else\n            if constexpr (!final_is_float)\n#endif\n              sum = _mm_srai_epi32(sum, target_shift);\n            return sum;\n            };\n\n          __m128i res_lo = madd_scale(uy_lo, vr_lo);\n          __m128i res_hi = madd_scale(uy_hi, vr_hi);\n\n#ifdef XP_TLS\n          if (final_is_float) {\n#else\n          if constexpr (final_is_float) {\n#endif\n            const int pix_idx = x / sizeof(pixel_t);\n            float* f_dst = reinterpret_cast<float*>(plane_ptr) + pix_idx;\n            auto store_block = [&](float* ptr, __m128i b, auto apply_float_offset_out) {\n              __m128 result = _mm_mul_ps(_mm_cvtepi32_ps(b), scale_f_sse2);\n              if (apply_float_offset_out)\n                result = _mm_add_ps(result, out_offset_f_sse2);\n              _mm_store_ps(ptr, result);\n              };\n            store_block(f_dst, res_lo, apply_float_offset_out);\n            store_block(f_dst + 4, res_hi, apply_float_offset_out);\n          }\n          else {\n            const int pix_idx = x * sizeof(pixel_t_dst) / sizeof(pixel_t);\n            if constexpr (sizeof(pixel_t_dst) == 1) {\n              __m128i p = _mm_packs_epi32(res_lo, res_hi);\n              __m128i final8 = _mm_packus_epi16(p, zero);\n              _mm_storel_epi64(reinterpret_cast<__m128i*>(plane_ptr + pix_idx), final8);\n            }\n            else {\n              __m128i p;\n              if constexpr (lessthan16bit_target) {\n                p = _mm_packs_epi32(res_lo, res_hi);\n                p = _mm_max_epi16(_mm_min_epi16(p, limit), zero);\n              }\n              else {\n                p = _MM_PACKUS_EPI32(res_lo, res_hi);\n              }\n              _mm_store_si128(reinterpret_cast<__m128i*>(plane_ptr + pix_idx), p);\n            }\n          }\n          };\n\n        // Process planes, using pre-packed coefficient, and the 16 bit patch if needed\n        process_plane(dstp[0], m_uy_G, m_vr_G, v_patch_G, true /* apply_float_offset_out */);\n        // only Y,R,G,B needs it uniformly, so for YUV, we call it with false\n        // last param: apply_float_offset_out\n        if constexpr (direction == ConversionDirection::YUV_TO_RGB || direction == ConversionDirection::RGB_TO_RGB) {\n          process_plane(dstp[1], m_uy_B, m_vr_B, v_patch_B, true);\n          process_plane(dstp[2], m_uy_R, m_vr_R, v_patch_R, true);\n        }\n        else if constexpr (direction == ConversionDirection::RGB_TO_YUV || direction == ConversionDirection::YUV_TO_YUV) {\n          process_plane(dstp[1], m_uy_B, m_vr_B, v_patch_B, false);\n          process_plane(dstp[2], m_uy_R, m_vr_R, v_patch_R, false);\n        }\n        else if constexpr (direction != ConversionDirection::RGB_TO_Y) {\n          // no other planes\n        }\n      }\n    } // x loop\n\n    srcp[0] += srcPitch[0];\n    srcp[1] += srcPitch[1];\n    srcp[2] += srcPitch[2];\n    dstp[0] += dstPitch[0];\n    if constexpr (direction != ConversionDirection::RGB_TO_Y) {\n      dstp[1] += dstPitch[1];\n      dstp[2] += dstPitch[2];\n    }\n  } // y loop\n}\n#undef XP_LAMBDA_CAPTURE_FIX\n\ntemplate<ConversionDirection direction, typename pixel_t_src, bool lessthan16bit>\nvoid convert_yuv_to_planarrgb_sse2(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m,\n  int bits_per_pixel, int bits_per_pixel_target, bool force_float)\n{\n  // Accuracy forever: forced float or float input\n  if (force_float || std::is_floating_point<pixel_t_src>::value) {\n    if (bits_per_pixel_target == 8) {\n      convert_yuv_to_planarrgb_sse2_internal<direction, pixel_t_src, lessthan16bit, true, uint8_t, YuvRgbConversionType::FORCE_FLOAT>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n    }\n    else if (bits_per_pixel_target < 16) {\n      convert_yuv_to_planarrgb_sse2_internal<direction, pixel_t_src, lessthan16bit, true, uint16_t, YuvRgbConversionType::FORCE_FLOAT>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n    }\n    else if (bits_per_pixel_target == 16) {\n      convert_yuv_to_planarrgb_sse2_internal<direction, pixel_t_src, lessthan16bit, false, uint16_t, YuvRgbConversionType::FORCE_FLOAT>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n    }\n    else { // 32 bit float target\n      convert_yuv_to_planarrgb_sse2_internal<direction, pixel_t_src, lessthan16bit, false, float, YuvRgbConversionType::FORCE_FLOAT>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n    }\n    return;\n  }\n\n  // Integer input paths\n  if constexpr (!std::is_floating_point<pixel_t_src>::value) {\n    const bool need_conversion = bits_per_pixel_target != bits_per_pixel;\n    if (!need_conversion) {\n      // No bit-depth conversion, just color space conversion\n      convert_yuv_to_planarrgb_sse2_internal<direction, pixel_t_src, lessthan16bit, lessthan16bit, pixel_t_src, YuvRgbConversionType::NATIVE_INT>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n      return;\n    }\n\n    const bool full_d = m.offset_out == 0;\n    if (bits_per_pixel_target >= 8 && bits_per_pixel <= 16) {\n      if (bits_per_pixel_target == 8) {\n        if (full_d)\n          convert_yuv_to_planarrgb_sse2_internal<direction, pixel_t_src, lessthan16bit, true, uint8_t, YuvRgbConversionType::BITCONV_INT_FULL>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n        else\n          convert_yuv_to_planarrgb_sse2_internal<direction, pixel_t_src, lessthan16bit, true, uint8_t, YuvRgbConversionType::BITCONV_INT_LIMITED>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n      }\n      else if (bits_per_pixel_target < 16) {\n        if (full_d)\n          convert_yuv_to_planarrgb_sse2_internal<direction, pixel_t_src, lessthan16bit, true, uint16_t, YuvRgbConversionType::BITCONV_INT_FULL>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n        else\n          convert_yuv_to_planarrgb_sse2_internal<direction, pixel_t_src, lessthan16bit, true, uint16_t, YuvRgbConversionType::BITCONV_INT_LIMITED>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n      }\n      else if (bits_per_pixel_target == 16) {\n        if (full_d)\n          convert_yuv_to_planarrgb_sse2_internal<direction, pixel_t_src, lessthan16bit, false, uint16_t, YuvRgbConversionType::BITCONV_INT_FULL>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n        else\n          convert_yuv_to_planarrgb_sse2_internal<direction, pixel_t_src, lessthan16bit, false, uint16_t, YuvRgbConversionType::BITCONV_INT_LIMITED>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n      }\n      else { // 32 bit float target\n        convert_yuv_to_planarrgb_sse2_internal<direction, pixel_t_src, lessthan16bit, false, float, YuvRgbConversionType::FLOAT_OUTPUT>(dstp, dstPitch, srcp, srcPitch, width, height, m, bits_per_pixel, bits_per_pixel_target);\n      }\n    }\n  }\n}\n\n// Template instantiations for SSE2\n// YUV_TO_RGB\ntemplate void convert_yuv_to_planarrgb_sse2<ConversionDirection::YUV_TO_RGB, uint8_t, true>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_sse2<ConversionDirection::YUV_TO_RGB, uint16_t, true>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_sse2<ConversionDirection::YUV_TO_RGB, uint16_t, false>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_sse2<ConversionDirection::YUV_TO_RGB, float, false>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\n\n// RGB_TO_YUV\ntemplate void convert_yuv_to_planarrgb_sse2<ConversionDirection::RGB_TO_YUV, uint8_t, true>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_sse2<ConversionDirection::RGB_TO_YUV, uint16_t, true>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_sse2<ConversionDirection::RGB_TO_YUV, uint16_t, false>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_sse2<ConversionDirection::RGB_TO_YUV, float, false>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\n\n// RGB_TO_Y\ntemplate void convert_yuv_to_planarrgb_sse2<ConversionDirection::RGB_TO_Y, uint8_t, true>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_sse2<ConversionDirection::RGB_TO_Y, uint16_t, true>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_sse2<ConversionDirection::RGB_TO_Y, uint16_t, false>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_sse2<ConversionDirection::RGB_TO_Y, float, false>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\n\n// YUV_TO_YUV (for future use)\ntemplate void convert_yuv_to_planarrgb_sse2<ConversionDirection::YUV_TO_YUV, uint8_t, true>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_sse2<ConversionDirection::YUV_TO_YUV, uint16_t, true>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_sse2<ConversionDirection::YUV_TO_YUV, uint16_t, false>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\ntemplate void convert_yuv_to_planarrgb_sse2<ConversionDirection::YUV_TO_YUV, float, false>(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m, int bits_per_pixel, int bits_per_pixel_target, bool force_float);\n\n// kept for reference\n// packed rgb helper\nstatic AVS_FORCEINLINE __m128i convert_yuv_to_rgb_sse2_core(const __m128i &px01, const __m128i &px23, const __m128i &px45, const __m128i &px67, const __m128i& zero, const __m128i &matrix, const __m128i &round_mask_plus_rgb_offset) {\n  //int b = (((int)m[0] * Y + (int)m[1] * U + (int)m[ 2] * V + 4096)>>13);\n\n  //px01 - xx xx 00 V1 00 U1 00 Y1 xx xx 00 V0 00 U0 00 Y0\n\n  __m128i low_lo  = _mm_madd_epi16(px01, matrix); //xx*0 + v1*m2 | u1*m1 + y1*m0 | xx*0 + v0*m2 | u0*m1 + y0*m0\n  __m128i low_hi  = _mm_madd_epi16(px23, matrix); //xx*0 + v3*m2 | u3*m1 + y3*m0 | xx*0 + v2*m2 | u2*m1 + y2*m0\n  __m128i high_lo = _mm_madd_epi16(px45, matrix);\n  __m128i high_hi = _mm_madd_epi16(px67, matrix);\n\n  __m128i low_v  = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(low_lo), _mm_castsi128_ps(low_hi), _MM_SHUFFLE(3, 1, 3, 1))); // v3*m2 | v2*m2 | v1*m2 | v0*m2\n  __m128i high_v = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(high_lo), _mm_castsi128_ps(high_hi), _MM_SHUFFLE(3, 1, 3, 1)));\n\n  __m128i low_yu  = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(low_lo), _mm_castsi128_ps(low_hi), _MM_SHUFFLE(2, 0, 2, 0))); // u3*m1 + y3*m0 | u2*m1 + y2*m0 | u1*m1 + y1*m0 | u0*m1 + y0*m0\n  __m128i high_yu = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(high_lo), _mm_castsi128_ps(high_hi), _MM_SHUFFLE(2, 0, 2, 0)));\n\n  __m128i t_lo = _mm_add_epi32(low_v, low_yu); // v3*m2 + u3*m1 + y3*m0...\n  __m128i t_hi = _mm_add_epi32(high_v, high_yu);\n\n  t_lo = _mm_add_epi32(t_lo, round_mask_plus_rgb_offset); // v3*m2 + u3*m1 + y3*m0 + 4096...\n  t_hi = _mm_add_epi32(t_hi, round_mask_plus_rgb_offset);\n\n  t_lo = _mm_srai_epi32(t_lo, 13); // (v3*m2 + u3*m1 + y3*m0 + 4096) >> 13...\n  t_hi = _mm_srai_epi32(t_hi, 13);\n\n  __m128i result = _mm_packs_epi32(t_lo, t_hi);\n  result = _mm_packus_epi16(result, zero); //00 00 00 00 00 00 00 00 b7 b6 b5 b4 b3 b2 b1 b0\n  return result;\n}\n\ntemplate<int rgb_pixel_step, bool hasAlpha>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nvoid convert_yv24_to_rgb_ssse3(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE*srcV, const BYTE*srcA, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t src_pitch_a, size_t width, size_t height, const ConversionMatrix &matrix)\n{\n  dstp += dst_pitch * (height-1);  // We start at last line\n\n  size_t mod8_width = rgb_pixel_step == 3 ? width / 8 * 8 : width; // for rgb32 target we may process pixels beyond width, but we have at least 32 bytes alignment at target\n\n  __m128i matrix_b = _mm_set_epi16(0, matrix.v_b, matrix.u_b, matrix.y_b, 0, matrix.v_b, matrix.u_b, matrix.y_b);\n  __m128i matrix_g = _mm_set_epi16(0, matrix.v_g, matrix.u_g, matrix.y_g, 0, matrix.v_g, matrix.u_g, matrix.y_g);\n  __m128i matrix_r = _mm_set_epi16(0, matrix.v_r, matrix.u_r, matrix.y_r, 0, matrix.v_r, matrix.u_r, matrix.y_r);\n\n  __m128i zero = _mm_setzero_si128();\n\n  // .13 bit frac integer arithmetic\n  int round_mask_plus_rgb_offset_i = (1 << 12) + (matrix.offset_rgb << 13);\n  __m128i round_mask_plus_rgb_offset = _mm_set1_epi32(round_mask_plus_rgb_offset_i);\n\n  __m128i offset = _mm_set_epi16(0, -128, -128, matrix.offset_y, 0, -128, -128, matrix.offset_y);\n  __m128i pixels0123_mask = _mm_set_epi8(0, 0, 0, 0, 14, 13, 12, 10, 9, 8, 6, 5, 4, 2, 1, 0);\n  __m128i pixels4567_mask = _mm_set_epi8(4, 2, 1, 0, 0, 0, 0, 0, 14, 13, 12, 10, 9, 8, 6, 5);\n  __m128i ssse3_merge_mask = _mm_set_epi32(0xFFFFFFFF, 0, 0, 0);\n\n  // 8 YUV(A) pixels --> 2x16 RGB quads = 32 bytes. Avisynth's alignment is 64 so we are more than safe.\n\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < mod8_width; x+=8) {\n      __m128i src_y = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcY+x)); //0 0 0 0 0 0 0 0 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0\n      __m128i src_u = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcU+x)); //0 0 0 0 0 0 0 0 U7 U6 U5 U4 U3 U2 U1 U0\n      __m128i src_v = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcV+x)); //0 0 0 0 0 0 0 0 V7 V6 V5 V4 V3 V2 V1 V0\n      [[maybe_unused]] __m128i src_a;\n      if constexpr(hasAlpha)\n        src_a = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcA+x)); //0 0 0 0 0 0 0 0 A7 A6 A5 A4 A3 A2 A1 A0\n\n      __m128i t1 = _mm_unpacklo_epi8(src_y, src_u); //U7 Y7 U6 Y6 U5 Y5 U4 Y4 U3 Y3 U2 Y2 U1 Y1 U0 Y0\n      __m128i t2 = _mm_unpacklo_epi8(src_v, zero);  //00 V7 00 V6 00 V5 00 V4 00 V3 00 V2 00 V1 00 V0\n\n      __m128i low  = _mm_unpacklo_epi16(t1, t2); //xx V3 U3 Y3 xx V2 U2 Y2 xx V1 U1 Y1 xx V0 U0 Y0\n      __m128i high = _mm_unpackhi_epi16(t1, t2); //xx V7 U7 Y7 xx V6 U6 Y6 xx V5 U5 Y5 xx V4 U4 Y4\n\n      __m128i px01 = _mm_unpacklo_epi8(low, zero);  //xx xx 00 V1 00 U1 00 Y1 xx xx 00 V0 00 U0 00 Y0\n      __m128i px23 = _mm_unpackhi_epi8(low, zero);  //xx xx 00 V3 00 U3 00 Y3 xx xx 00 V2 00 U2 00 Y2\n      __m128i px45 = _mm_unpacklo_epi8(high, zero); //xx xx 00 V5 00 U5 00 Y5 xx xx 00 V4 00 U4 00 Y4\n      __m128i px67 = _mm_unpackhi_epi8(high, zero); //xx xx 00 V7 00 U7 00 Y7 xx xx 00 V6 00 U6 00 Y6\n\n      px01 = _mm_add_epi16(px01, offset);\n      px23 = _mm_add_epi16(px23, offset);\n      px45 = _mm_add_epi16(px45, offset);\n      px67 = _mm_add_epi16(px67, offset);\n\n      __m128i result_b = convert_yuv_to_rgb_sse2_core(px01, px23, px45, px67, zero, matrix_b, round_mask_plus_rgb_offset); //00 00 00 00 00 00 00 00 b7 b6 b5 b4 b3 b2 b1 b0\n      __m128i result_g = convert_yuv_to_rgb_sse2_core(px01, px23, px45, px67, zero, matrix_g, round_mask_plus_rgb_offset); //00 00 00 00 00 00 00 00 g7 g6 g5 g4 g3 g2 g1 g0\n      __m128i result_r = convert_yuv_to_rgb_sse2_core(px01, px23, px45, px67, zero, matrix_r, round_mask_plus_rgb_offset); //00 00 00 00 00 00 00 00 r7 r6 r5 r4 r3 r2 r1 r0\n\n      __m128i result_bg = _mm_unpacklo_epi8(result_b, result_g); //g7 b7 g6 b6 g5 b5 g4 b4 g3 b3 g2 b2 g1 b1 g0 b0\n      __m128i alpha;\n      if constexpr(hasAlpha)\n        alpha = src_a; // a7 .. a0\n      else\n        alpha = _mm_cmpeq_epi32(result_r, result_r); // FF FF FF FF ... default alpha transparent\n\n      __m128i result_ra = _mm_unpacklo_epi8(result_r, alpha);       //a7 r7 a6 r6 a5 r5 a4 r4 a3 r3 a2 r2 a1 r1 a0 r0\n\n      __m128i result_lo = _mm_unpacklo_epi16(result_bg, result_ra);\n      __m128i result_hi = _mm_unpackhi_epi16(result_bg, result_ra);\n\n      if constexpr(rgb_pixel_step == 4) {\n        //rgb32\n        _mm_store_si128(reinterpret_cast<__m128i*>(dstp+x*4),    result_lo);\n        _mm_store_si128(reinterpret_cast<__m128i*>(dstp+x*4+16), result_hi);\n      }\n      else {\n        //rgb24\n        //\"fast\" SSSE3 version\n        __m128i px0123 = _mm_shuffle_epi8(result_lo, pixels0123_mask); //xxxx xxxx b3g3 r3b2 g2r2 b1g1 r1b0 g0r0\n        __m128i dst567 = _mm_shuffle_epi8(result_hi, pixels4567_mask); //r5b4 g4r4 xxxx xxxx b7g7 r7b6 g6r6 b5g5\n\n        __m128i dst012345 = _mm_or_si128(\n          _mm_andnot_si128(ssse3_merge_mask, px0123),\n          _mm_and_si128(ssse3_merge_mask, dst567)\n        ); //r5b4 g4r4 b3g3 r3b2 g2r2 b1g1 r1b0 g0r0\n\n        _mm_storeu_si128(reinterpret_cast<__m128i*>(dstp + x * 3), dst012345);\n        _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + x * 3 + 16), dst567);\n\n      }\n    }\n\n    if constexpr(rgb_pixel_step == 3) {\n      // for rgb32 (pixel_step == 4) we processed full width and more, including padded 8 bytes\n      for (size_t x = mod8_width; x < width; ++x) {\n        int Y = srcY[x] + matrix.offset_y;\n        int U = srcU[x] - 128;\n        int V = srcV[x] - 128;\n        int b = (((int)matrix.y_b * Y + (int)matrix.u_b * U + (int)matrix.v_b * V + round_mask_plus_rgb_offset_i) >> 13);\n        int g = (((int)matrix.y_g * Y + (int)matrix.u_g * U + (int)matrix.v_g * V + round_mask_plus_rgb_offset_i) >> 13);\n        int r = (((int)matrix.y_r * Y + (int)matrix.u_r * U + (int)matrix.v_r * V + round_mask_plus_rgb_offset_i) >> 13);\n        dstp[x*rgb_pixel_step + 0] = PixelClip(b);\n        dstp[x*rgb_pixel_step + 1] = PixelClip(g);\n        dstp[x*rgb_pixel_step + 2] = PixelClip(r);\n        if constexpr(rgb_pixel_step == 4) { // n/a\n          dstp[x * 4 + 3] = 255;\n        }\n      }\n    }\n    dstp -= dst_pitch;\n    srcY += src_pitch_y;\n    srcU += src_pitch_uv;\n    srcV += src_pitch_uv;\n    if(hasAlpha)\n      srcA += src_pitch_a;\n  }\n}\n\n//instantiate\n//template<int rgb_pixel_step, bool targetHasAlpha>\ntemplate void convert_yv24_to_rgb_ssse3<3, false>(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE*srcV, const BYTE*srcA, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t src_pitch_a, size_t width, size_t height, const ConversionMatrix &matrix);\ntemplate void convert_yv24_to_rgb_ssse3<4, false>(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE*srcV, const BYTE*srcA, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t src_pitch_a, size_t width, size_t height, const ConversionMatrix &matrix);\ntemplate void convert_yv24_to_rgb_ssse3<3, true>(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE*srcV, const BYTE*srcA, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t src_pitch_a, size_t width, size_t height, const ConversionMatrix &matrix);\ntemplate void convert_yv24_to_rgb_ssse3<4, true>(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE*srcV, const BYTE*srcA, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t src_pitch_a, size_t width, size_t height, const ConversionMatrix &matrix);\n\n\ntemplate<int rgb_pixel_step, bool hasAlpha>\nvoid convert_yv24_to_rgb_sse2(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE*srcV, const BYTE*srcA, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t src_pitch_a, size_t width, size_t height, const ConversionMatrix &matrix) {\n  dstp += dst_pitch * (height - 1);  // We start at last line\n\n  size_t mod8_width = rgb_pixel_step == 3 ? width / 8 * 8 : width; // for rgb32 target we may process pixels beyond width, but we have at least 32 bytes alignment at target\n\n  __m128i matrix_b = _mm_set_epi16(0, matrix.v_b, matrix.u_b, matrix.y_b, 0, matrix.v_b, matrix.u_b, matrix.y_b);\n  __m128i matrix_g = _mm_set_epi16(0, matrix.v_g, matrix.u_g, matrix.y_g, 0, matrix.v_g, matrix.u_g, matrix.y_g);\n  __m128i matrix_r = _mm_set_epi16(0, matrix.v_r, matrix.u_r, matrix.y_r, 0, matrix.v_r, matrix.u_r, matrix.y_r);\n\n  __m128i zero = _mm_setzero_si128();\n  // .13 bit frac integer arithmetic\n  int round_mask_plus_rgb_offset_i = (1 << 12) + (matrix.offset_rgb << 13);\n  __m128i round_mask_plus_rgb_offset = _mm_set1_epi32(round_mask_plus_rgb_offset_i);\n  __m128i offset = _mm_set_epi16(0, -128, -128, matrix.offset_y, 0, -128, -128, matrix.offset_y);\n\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < mod8_width; x += 8) {\n      __m128i src_y = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcY + x)); //0 0 0 0 0 0 0 0 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0\n      __m128i src_u = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcU + x)); //0 0 0 0 0 0 0 0 U7 U6 U5 U4 U3 U2 U1 U0\n      __m128i src_v = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcV + x)); //0 0 0 0 0 0 0 0 V7 V6 V5 V4 V3 V2 V1 V0\n      __m128i src_a;\n      if (hasAlpha)\n        src_a = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcA + x)); //0 0 0 0 0 0 0 0 A7 A6 A5 A4 A3 A2 A1 A0\n\n      __m128i t1 = _mm_unpacklo_epi8(src_y, src_u); //U7 Y7 U6 Y6 U5 Y5 U4 Y4 U3 Y3 U2 Y2 U1 Y1 U0 Y0\n      __m128i t2 = _mm_unpacklo_epi8(src_v, zero);  //00 V7 00 V6 00 V5 00 V4 00 V3 00 V2 00 V1 00 V0\n\n      __m128i low = _mm_unpacklo_epi16(t1, t2); //xx V3 U3 Y3 xx V2 U2 Y2 xx V1 U1 Y1 xx V0 U0 Y0\n      __m128i high = _mm_unpackhi_epi16(t1, t2); //xx V7 U7 Y7 xx V6 U6 Y6 xx V5 U5 Y5 xx V4 U4 Y4\n\n      __m128i px01 = _mm_unpacklo_epi8(low, zero);  //xx xx 00 V1 00 U1 00 Y1 xx xx 00 V0 00 U0 00 Y0\n      __m128i px23 = _mm_unpackhi_epi8(low, zero);  //xx xx 00 V3 00 U3 00 Y3 xx xx 00 V2 00 U2 00 Y2\n      __m128i px45 = _mm_unpacklo_epi8(high, zero); //xx xx 00 V5 00 U5 00 Y5 xx xx 00 V4 00 U4 00 Y4\n      __m128i px67 = _mm_unpackhi_epi8(high, zero); //xx xx 00 V7 00 U7 00 Y7 xx xx 00 V6 00 U6 00 Y6\n\n      px01 = _mm_add_epi16(px01, offset);\n      px23 = _mm_add_epi16(px23, offset);\n      px45 = _mm_add_epi16(px45, offset);\n      px67 = _mm_add_epi16(px67, offset);\n\n      __m128i result_b = convert_yuv_to_rgb_sse2_core(px01, px23, px45, px67, zero, matrix_b, round_mask_plus_rgb_offset); //00 00 00 00 00 00 00 00 b7 b6 b5 b4 b3 b2 b1 b0\n      __m128i result_g = convert_yuv_to_rgb_sse2_core(px01, px23, px45, px67, zero, matrix_g, round_mask_plus_rgb_offset); //00 00 00 00 00 00 00 00 g7 g6 g5 g4 g3 g2 g1 g0\n      __m128i result_r = convert_yuv_to_rgb_sse2_core(px01, px23, px45, px67, zero, matrix_r, round_mask_plus_rgb_offset); //00 00 00 00 00 00 00 00 r7 r6 r5 r4 r3 r2 r1 r0\n\n      __m128i result_bg = _mm_unpacklo_epi8(result_b, result_g); //g7 b7 g6 b6 g5 b5 g4 b4 g3 b3 g2 b2 g1 b1 g0 b0\n      __m128i alpha;\n      if (hasAlpha)\n        alpha = src_a; // a7 .. a0\n      else\n        alpha = _mm_cmpeq_epi32(result_r, result_r); // FF FF FF FF ... default alpha transparent\n\n      __m128i result_ra = _mm_unpacklo_epi8(result_r, alpha);       //a7 r7 a6 r6 a5 r5 a4 r4 a3 r3 a2 r2 a1 r1 a0 r0\n\n      __m128i result_lo = _mm_unpacklo_epi16(result_bg, result_ra);\n      __m128i result_hi = _mm_unpackhi_epi16(result_bg, result_ra);\n\n      if constexpr (rgb_pixel_step == 4) {\n        //rgb32\n        _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x * 4), result_lo);\n        _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x * 4 + 16), result_hi);\n      }\n      else {\n        //rgb24\n        alignas(16) BYTE temp[32];\n        //slow SSE2 version\n        _mm_store_si128(reinterpret_cast<__m128i*>(temp), result_lo);\n        _mm_store_si128(reinterpret_cast<__m128i*>(temp + 16), result_hi);\n\n        for (int i = 0; i < 7; ++i) {\n          *reinterpret_cast<int*>(dstp + (x + i) * 3) = *reinterpret_cast<int*>(temp + i * 4);\n        }\n        //last pixel\n        dstp[(x + 7) * 3 + 0] = temp[7 * 4 + 0];\n        dstp[(x + 7) * 3 + 1] = temp[7 * 4 + 1];\n        dstp[(x + 7) * 3 + 2] = temp[7 * 4 + 2];\n      }\n    }\n\n    if constexpr (rgb_pixel_step == 3) {\n      // for rgb32 (pixel_step == 4) we processed full width and more, including padded 8 bytes\n      for (size_t x = mod8_width; x < width; ++x) {\n        int Y = srcY[x] + matrix.offset_y;\n        int U = srcU[x] - 128;\n        int V = srcV[x] - 128;\n        int b = (((int)matrix.y_b * Y + (int)matrix.u_b * U + (int)matrix.v_b * V + round_mask_plus_rgb_offset_i) >> 13);\n        int g = (((int)matrix.y_g * Y + (int)matrix.u_g * U + (int)matrix.v_g * V + round_mask_plus_rgb_offset_i) >> 13);\n        int r = (((int)matrix.y_r * Y + (int)matrix.u_r * U + (int)matrix.v_r * V + round_mask_plus_rgb_offset_i) >> 13);\n        dstp[x*rgb_pixel_step + 0] = PixelClip(b);\n        dstp[x*rgb_pixel_step + 1] = PixelClip(g);\n        dstp[x*rgb_pixel_step + 2] = PixelClip(r);\n        if constexpr (rgb_pixel_step == 4) { // n/a\n          dstp[x * 4 + 3] = 255;\n        }\n      }\n    }\n    dstp -= dst_pitch;\n    srcY += src_pitch_y;\n    srcU += src_pitch_uv;\n    srcV += src_pitch_uv;\n    if (hasAlpha)\n      srcA += src_pitch_a;\n  }\n}\n\n//instantiate\n//template<int rgb_pixel_step, bool targetHasAlpha>\ntemplate void convert_yv24_to_rgb_sse2<3, false>(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE*srcV, const BYTE*srcA, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t src_pitch_a, size_t width, size_t height, const ConversionMatrix &matrix);\ntemplate void convert_yv24_to_rgb_sse2<4, false>(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE*srcV, const BYTE*srcA, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t src_pitch_a, size_t width, size_t height, const ConversionMatrix &matrix);\ntemplate void convert_yv24_to_rgb_sse2<3, true>(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE*srcV, const BYTE*srcA, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t src_pitch_a, size_t width, size_t height, const ConversionMatrix &matrix);\ntemplate void convert_yv24_to_rgb_sse2<4, true>(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE*srcV, const BYTE*srcA, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t src_pitch_a, size_t width, size_t height, const ConversionMatrix &matrix);\n\n\n#ifdef X86_32\n\nstatic AVS_FORCEINLINE __m64 convert_yuv_to_rgb_mmx_core(const __m64 &px0, const __m64 &px1, const __m64 &px2, const __m64 &px3, const __m64& zero, const __m64 &matrix, const __m64 &round_mask_plus_rgb_offset) {\n  //int b = (((int)m[0] * Y + (int)m[1] * U + (int)m[ 2] * V + 4096)>>13);\n\n  //px01 - xx xx 00 V0 00 U0 00 Y0\n\n  __m64 low_lo  = _mm_madd_pi16(px0, matrix); //xx*0 + v1*m2 | u1*m1 + y1*m0 | xx*0 + v0*m2 | u0*m1 + y0*m0\n  __m64 low_hi  = _mm_madd_pi16(px1, matrix); //xx*0 + v3*m2 | u3*m1 + y3*m0 | xx*0 + v2*m2 | u2*m1 + y2*m0\n  __m64 high_lo = _mm_madd_pi16(px2, matrix);\n  __m64 high_hi = _mm_madd_pi16(px3, matrix);\n\n  __m64 low_v = _mm_unpackhi_pi32(low_lo, low_hi); // v1*m2 | v0*m2\n  __m64 high_v = _mm_unpackhi_pi32(high_lo, high_hi);\n\n  __m64 low_yu = _mm_unpacklo_pi32(low_lo, low_hi); // u1*m1 + y1*m0 | u0*m1 + y0*m0\n  __m64 high_yu = _mm_unpacklo_pi32(high_lo, high_hi);\n\n  __m64 t_lo = _mm_add_pi32(low_v, low_yu); // v3*m2 + u3*m1 + y3*m0...\n  __m64 t_hi = _mm_add_pi32(high_v, high_yu);\n\n  t_lo = _mm_add_pi32(t_lo, round_mask_plus_rgb_offset); // v3*m2 + u3*m1 + y3*m0 + 4096...\n  t_hi = _mm_add_pi32(t_hi, round_mask_plus_rgb_offset);\n\n  t_lo = _mm_srai_pi32(t_lo, 13); // (v3*m2 + u3*m1 + y3*m0 + 4096) >> 13...\n  t_hi = _mm_srai_pi32(t_hi, 13);\n\n  __m64 result = _mm_packs_pi32(t_lo, t_hi);\n  result = _mm_packs_pu16(result, zero); //00 00 00 00 b3 b2 b1 b0\n  return result;\n}\n\ntemplate<int rgb_pixel_step>\nvoid convert_yv24_to_rgb_mmx(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE*srcV, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t width, size_t height, const ConversionMatrix &matrix) {\n  dstp += dst_pitch * (height-1);  // We start at last line\n\n  size_t mod4_width = rgb_pixel_step == 3 ? width / 4 * 4 : width;\n\n  __m64 matrix_b = _mm_set_pi16(0, matrix.v_b, matrix.u_b, matrix.y_b);\n  __m64 matrix_g = _mm_set_pi16(0, matrix.v_g, matrix.u_g, matrix.y_g);\n  __m64 matrix_r = _mm_set_pi16(0, matrix.v_r, matrix.u_r, matrix.y_r);\n\n  __m64 zero = _mm_setzero_si64();\n  int round_mask_plus_rgb_offset_i = 4096 + (matrix.offset_rgb << 13);\n  __m64 round_mask_plus_rgb_offset = _mm_set1_pi32(round_mask_plus_rgb_offset_i);\n\n  __m64 ff = _mm_set1_pi32(0xFFFFFFFF);\n  __m64 offset = _mm_set_pi16(0, -128, -128, matrix.offset_y);\n  __m64 low_pixel_mask = _mm_set_pi32(0, 0x00FFFFFF);\n  __m64 high_pixel_mask = _mm_set_pi32(0x00FFFFFF, 0);\n\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < mod4_width; x+=4) {\n      __m64 src_y = _mm_cvtsi32_si64(*reinterpret_cast<const int*>(srcY+x)); //0 0 0 0 Y3 Y2 Y1 Y0\n      __m64 src_u = _mm_cvtsi32_si64(*reinterpret_cast<const int*>(srcU+x)); //0 0 0 0 U3 U2 U1 U0\n      __m64 src_v = _mm_cvtsi32_si64(*reinterpret_cast<const int*>(srcV+x)); //0 0 0 0 V3 V2 V1 V0\n\n      __m64 t1 = _mm_unpacklo_pi8(src_y, src_u); //U3 Y3 U2 Y2 U1 Y1 U0 Y0\n      __m64 t2 = _mm_unpacklo_pi8(src_v, zero);  //00 V3 00 V2 00 V1 00 V0\n\n      __m64 low  = _mm_unpacklo_pi16(t1, t2); //xx V1 U1 Y1 xx V0 U0 Y0\n      __m64 high = _mm_unpackhi_pi16(t1, t2); //xx V3 U3 Y3 xx V2 U2 Y2\n\n      __m64 px0 = _mm_unpacklo_pi8(low, zero);  //xx xx 00 V0 00 U0 00 Y0\n      __m64 px1 = _mm_unpackhi_pi8(low, zero);  //xx xx 00 V1 00 U1 00 Y1\n      __m64 px2 = _mm_unpacklo_pi8(high, zero); //xx xx 00 V2 00 U2 00 Y2\n      __m64 px3 = _mm_unpackhi_pi8(high, zero); //xx xx 00 V3 00 U3 00 Y3\n\n      px0 = _mm_add_pi16(px0, offset);\n      px1 = _mm_add_pi16(px1, offset);\n      px2 = _mm_add_pi16(px2, offset);\n      px3 = _mm_add_pi16(px3, offset);\n\n      __m64 result_b = convert_yuv_to_rgb_mmx_core(px0, px1, px2, px3, zero, matrix_b, round_mask_plus_rgb_offset); //00 00 00 00 b3 b2 b1 b0\n      __m64 result_g = convert_yuv_to_rgb_mmx_core(px0, px1, px2, px3, zero, matrix_g, round_mask_plus_rgb_offset); //00 00 00 00 g3 g2 g1 g0\n      __m64 result_r = convert_yuv_to_rgb_mmx_core(px0, px1, px2, px3, zero, matrix_r, round_mask_plus_rgb_offset); //00 00 00 00 r3 r2 r1 r0\n\n      __m64 result_bg = _mm_unpacklo_pi8(result_b, result_g); //g3 b3 g2 b2 g1 b1 g0 b0\n      __m64 result_ra = _mm_unpacklo_pi8(result_r, ff);       //a3 r3 a2 r2 a1 r1 a0 r0\n\n      __m64 result_lo = _mm_unpacklo_pi16(result_bg, result_ra);\n      __m64 result_hi = _mm_unpackhi_pi16(result_bg, result_ra);\n\n      if (rgb_pixel_step == 4) {\n        //rgb32\n        *reinterpret_cast<__m64*>(dstp+x*4) = result_lo;\n        *reinterpret_cast<__m64*>(dstp+x*4+8) = result_hi;\n      } else {\n        __m64 p0 = _mm_and_si64(result_lo, low_pixel_mask); //0000 0000 00r0 g0b0\n        __m64 p1 = _mm_and_si64(result_lo, high_pixel_mask); //00r1 g1b1 0000 0000\n        __m64 p2 = _mm_and_si64(result_hi, low_pixel_mask); //0000 0000 00r2 g2b2\n        __m64 p3 = _mm_and_si64(result_hi, high_pixel_mask); //00r3 g3b3 0000 0000\n\n        __m64 dst01 = _mm_or_si64(p0, _mm_srli_si64(p1, 8)); //0000 r1g1 b1r0 g0b0\n        p3 = _mm_srli_si64(p3, 24); //0000 0000 r3g3 b300\n\n        __m64 dst012 = _mm_or_si64(dst01, _mm_slli_si64(p2, 48));  //g2b2 r1g1 b1r0 g0b0\n        __m64 dst23 = _mm_or_si64(p3, _mm_srli_si64(p2, 16)); //0000 0000 r3g3 b3r2\n\n        *reinterpret_cast<__m64*>(dstp+x*3) = dst012;\n        *reinterpret_cast<int*>(dstp+x*3+8) = _mm_cvtsi64_si32(dst23);\n      }\n    }\n\n    if (rgb_pixel_step == 3) {\n      for (size_t x = mod4_width; x < width; ++x) {\n        int Y = srcY[x] + matrix.offset_y;\n        int U = srcU[x] - 128;\n        int V = srcV[x] - 128;\n        int b = (((int)matrix.y_b * Y + (int)matrix.u_b * U + (int)matrix.v_b * V + round_mask_plus_rgb_offset_i) >> 13);\n        int g = (((int)matrix.y_g * Y + (int)matrix.u_g * U + (int)matrix.v_g * V + round_mask_plus_rgb_offset_i) >> 13);\n        int r = (((int)matrix.y_r * Y + (int)matrix.u_r * U + (int)matrix.v_r * V + round_mask_plus_rgb_offset_i) >> 13);\n        dstp[x*rgb_pixel_step + 0] = PixelClip(b);\n        dstp[x*rgb_pixel_step + 1] = PixelClip(g);\n        dstp[x*rgb_pixel_step + 2] = PixelClip(r);\n        if (rgb_pixel_step == 4) {\n          dstp[x * 4 + 3] = 255;\n        }\n      }\n    }\n\n    dstp -= dst_pitch;\n    srcY += src_pitch_y;\n    srcU += src_pitch_uv;\n    srcV += src_pitch_uv;\n  }\n  _mm_empty();\n}\n\n//instantiate\n//template<int rgb_pixel_step>\ntemplate void convert_yv24_to_rgb_mmx<3>(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE*srcV, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t width, size_t height, const ConversionMatrix &matrix);\ntemplate void convert_yv24_to_rgb_mmx<4>(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE*srcV, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t width, size_t height, const ConversionMatrix &matrix);\n\n#endif\n\n\nvoid convert_yuy2_to_yv16_sse2(const BYTE *srcp, BYTE *dstp_y, BYTE *dstp_u, BYTE *dstp_v, size_t src_pitch, size_t dst_pitch_y, size_t dst_pitch_uv, size_t width, size_t height)\n{\n  width /= 2;\n\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < width; x += 8) {\n      __m128i p0 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x * 4));      // V3 Y7 U3 Y6 V2 Y5 U2 Y4 V1 Y3 U1 Y2 V0 Y1 U0 Y0\n      __m128i p1 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x * 4 + 16)); // V7 Yf U7 Ye V6 Yd U6 Yc V5 Yb U5 Ya V4 Y9 U4 Y8\n\n      __m128i p2 = _mm_unpacklo_epi8(p0, p1); // V5 V1 Yb Y3 U5 U1 Ya Y2 V4 V0 Y9 Y1 U4 U0 Y8 Y0\n      __m128i p3 = _mm_unpackhi_epi8(p0, p1); // V7 V3 Yf Y7 U7 U3 Ye Y6 V6 V2 Yd Y5 U6 U2 Yc Y4\n\n      p0 = _mm_unpacklo_epi8(p2, p3); // V6 V4 V2 V0 Yd Y9 Y5 Y1 U6 U4 U2 U0 Yc Y8 Y4 Y0\n      p1 = _mm_unpackhi_epi8(p2, p3); // V7 V5 V3 V1 Yf Yb Y7 Y3 U7 U5 U3 U1 Ye Ya Y6 Y2\n\n      p2 = _mm_unpacklo_epi8(p0, p1); // U7 U6 U5 U4 U3 U2 U1 U0 Ye Yc Ya Y8 Y6 Y4 Y2 Y0\n      p3 = _mm_unpackhi_epi8(p0, p1); // V7 V6 V5 V4 V3 V2 V1 V0 Yf Yd Yb Y9 Y7 Y5 Y3 Y1\n\n      _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp_u + x), _mm_srli_si128(p2, 8));\n      _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp_v + x), _mm_srli_si128(p3, 8));\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp_y + x * 2), _mm_unpacklo_epi8(p2, p3));\n    }\n\n    srcp += src_pitch;\n    dstp_y += dst_pitch_y;\n    dstp_u += dst_pitch_uv;\n    dstp_v += dst_pitch_uv;\n  }\n}\n\n\n#ifdef X86_32\n\nvoid convert_yuy2_to_yv16_mmx(const BYTE *srcp, BYTE *dstp_y, BYTE *dstp_u, BYTE *dstp_v, size_t src_pitch, size_t dst_pitch_y, size_t dst_pitch_uv, size_t width, size_t height)\n{\n  width /= 2;\n\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < width; x += 4) {\n      __m64 p0 = *reinterpret_cast<const __m64*>(srcp + x * 4);     // V1 Y3 U1 Y2 V0 Y1 U0 Y0\n      __m64 p1 = *reinterpret_cast<const __m64*>(srcp + x * 4 + 8); // V3 Y7 U3 Y6 V2 Y5 U2 Y4\n\n      __m64 p2 = _mm_unpacklo_pi8(p0, p1); // V2 V0 Y5 Y1 U2 U0 Y4 Y0\n      __m64 p3 = _mm_unpackhi_pi8(p0, p1); // V3 V1 Y7 Y3 U3 U1 Y6 Y2\n\n      p0 = _mm_unpacklo_pi8(p2, p3); // U3 U2 U1 U0 Y6 Y4 Y2 Y0\n      p1 = _mm_unpackhi_pi8(p2, p3); // V3 V2 V1 V0 Y7 Y5 Y3 Y1\n\n      *reinterpret_cast<int*>(dstp_u + x) = _mm_cvtsi64_si32(_mm_srli_si64(p0, 32));\n      *reinterpret_cast<int*>(dstp_v + x) = _mm_cvtsi64_si32(_mm_srli_si64(p1, 32));\n      *reinterpret_cast<__m64*>(dstp_y + x * 2) = _mm_unpacklo_pi8(p0, p1);\n    }\n\n    srcp += src_pitch;\n    dstp_y += dst_pitch_y;\n    dstp_u += dst_pitch_uv;\n    dstp_v += dst_pitch_uv;\n  }\n  _mm_empty();\n}\n\n#endif\n\n\nvoid convert_yv16_to_yuy2_sse2(const BYTE *srcp_y, const BYTE *srcp_u, const BYTE *srcp_v, BYTE *dstp, size_t src_pitch_y, size_t src_pitch_uv, size_t dst_pitch, size_t width, size_t height)\n{\n  width /= 2;\n\n  for (size_t yy=0; yy<height; yy++) {\n    for (size_t x=0; x<width; x+=8) {\n\n      __m128i y = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp_y + x*2));\n      __m128i u = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp_u + x));\n      __m128i v = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp_v + x));\n\n      __m128i uv = _mm_unpacklo_epi8(u, v);\n      __m128i yuv_lo = _mm_unpacklo_epi8(y, uv);\n      __m128i yuv_hi = _mm_unpackhi_epi8(y, uv);\n\n      _mm_stream_si128(reinterpret_cast<__m128i*>(dstp + x*4), yuv_lo);\n      _mm_stream_si128(reinterpret_cast<__m128i*>(dstp + x*4 + 16), yuv_hi);\n    }\n\n    srcp_y += src_pitch_y;\n    srcp_u += src_pitch_uv;\n    srcp_v += src_pitch_uv;\n    dstp += dst_pitch;\n  }\n}\n\n#ifdef X86_32\nvoid convert_yv16_to_yuy2_mmx(const BYTE *srcp_y, const BYTE *srcp_u, const BYTE *srcp_v, BYTE *dstp, size_t src_pitch_y, size_t src_pitch_uv, size_t dst_pitch, size_t width, size_t height)\n{\n  width /= 2;\n\n  for (size_t y=0; y<height; y++) {\n    for (size_t x=0; x<width; x+=4) {\n      __m64 y = *reinterpret_cast<const __m64*>(srcp_y + x*2);\n      __m64 u = *reinterpret_cast<const __m64*>(srcp_u + x);\n      __m64 v = *reinterpret_cast<const __m64*>(srcp_v + x);\n\n      __m64 uv = _mm_unpacklo_pi8(u, v);\n      __m64 yuv_lo = _mm_unpacklo_pi8(y, uv);\n      __m64 yuv_hi = _mm_unpackhi_pi8(y, uv);\n\n      *reinterpret_cast<__m64*>(dstp + x*4) = yuv_lo;\n      *reinterpret_cast<__m64*>(dstp + x*4+8) = yuv_hi;\n    }\n\n    srcp_y += src_pitch_y;\n    srcp_u += src_pitch_uv;\n    srcp_v += src_pitch_uv;\n    dstp += dst_pitch;\n  }\n  _mm_empty();\n}\n#endif\n\nDISABLE_WARNING_POP\n\n\n\n"
  },
  {
    "path": "avs_core/convert/intel/convert_planar_sse.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Convert_PLANAR_sse_H__\n#define __Convert_PLANAR_sse_H__\n\n#include <avs/types.h>\n#include \"../convert_matrix.h\"\n#include \"../convert_helper.h\"\n\nvoid convert_yuy2_to_y8_sse2(const BYTE *srcp, BYTE *dstp, size_t src_pitch, size_t dst_pitch, size_t width, size_t height);\n\n\ntemplate<ConversionDirection direction, typename pixel_t_src, bool lessthan16bit>\nvoid convert_yuv_to_planarrgb_sse2(BYTE* (&dstp)[3], int(&dstPitch)[3], const BYTE* (&srcp)[3], const int(&srcPitch)[3], int width, int height, const ConversionMatrix& m,\n  int bits_per_pixel, int bits_per_pixel_target, bool force_float);\n\ntemplate<int rgb_pixel_step, bool hasAlpha>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nvoid convert_yv24_to_rgb_ssse3(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE*srcV, const BYTE*srcA, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t src_pitch_a, size_t width, size_t height, const ConversionMatrix &matrix);\n\ntemplate<int rgb_pixel_step, bool hasAlpha>\nvoid convert_yv24_to_rgb_sse2(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE*srcV, const BYTE*srcA, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t src_pitch_a, size_t width, size_t height, const ConversionMatrix &matrix);\n\n#ifdef X86_32\ntemplate<int rgb_pixel_step>\nvoid convert_yv24_to_rgb_mmx(BYTE* dstp, const BYTE* srcY, const BYTE* srcU, const BYTE*srcV, size_t dst_pitch, size_t src_pitch_y, size_t src_pitch_uv, size_t width, size_t height, const ConversionMatrix &matrix);\n#endif\n\nvoid convert_yuy2_to_yv16_sse2(const BYTE *srcp, BYTE *dstp_y, BYTE *dstp_u, BYTE *dstp_v, size_t src_pitch, size_t dst_pitch_y, size_t dst_pitch_uv, size_t width, size_t height);\n#ifdef X86_32\nvoid convert_yuy2_to_yv16_mmx(const BYTE *srcp, BYTE *dstp_y, BYTE *dstp_u, BYTE *dstp_v, size_t src_pitch, size_t dst_pitch_y, size_t dst_pitch_uv, size_t width, size_t height);\n#endif\n\nvoid convert_yv16_to_yuy2_sse2(const BYTE *srcp_y, const BYTE *srcp_u, const BYTE *srcp_v, BYTE *dstp, size_t src_pitch_y, size_t src_pitch_uv, size_t dst_pitch, size_t width, size_t height);\n#ifdef X86_32\nvoid convert_yv16_to_yuy2_mmx(const BYTE *srcp_y, const BYTE *srcp_u, const BYTE *srcp_v, BYTE *dstp, size_t src_pitch_y, size_t src_pitch_uv, size_t dst_pitch, size_t width, size_t height);\n#endif\n\n#endif // __Convert_PLANAR_sse_H__\n"
  },
  {
    "path": "avs_core/convert/intel/convert_rgb_avx2.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include <avs/alignment.h>\n#ifdef _MSC_VER\n    #include <intrin.h>\n#else\n    #include <x86intrin.h>\n#endif\n#include <immintrin.h>\n\n#ifndef _mm256_set_m128i\n#define _mm256_set_m128i(v0, v1) _mm256_insertf128_si256(_mm256_castsi128_si256(v1), (v0), 1)\n#endif\n\n#ifndef _mm256_set_m128\n#define _mm256_set_m128(v0, v1) _mm256_insertf128_ps(_mm256_castps128_ps256(v1), (v0), 1)\n#endif\n\n#include \"convert_rgb_avx2.h\"\n\n// minimum width: 48*2 bytes\ntemplate<typename pixel_t, bool targetHasAlpha>\nvoid convert_rgb_to_rgbp_avx2(const BYTE *srcp, BYTE * (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height)\n{\n  // RGB24: 2x3x16 bytes cycle, 2x16*(RGB) 8bit pixels\n  // RGB48: 2x3x16 bytes cycle, 2x8*(RGB) 16bit pixels\n  // 0123456789ABCDEF 0123456789ABCDEF 0123456789ABCDEF\n  // BGRBGRBGRBGRBGRB GRBGRBGRBGRBGRBG RBGRBGRBGRBGRBGR // 8 bit\n  // B G R B G R B G  R B G R B G R B  G R B G R B G R  // 16 bit\n  // 1111111111112222 2222222233333333 3333444444444444\n\n  constexpr int pixels_at_a_time = (sizeof(pixel_t) == 1) ? 32 : 16;\n  const int wmod = (width / pixels_at_a_time) * pixels_at_a_time; // 8 pixels for 8 bit, 4 pixels for 16 bit\n  __m256i mask;\n  if constexpr(sizeof(pixel_t) == 1)\n    mask = _mm256_set_epi8(15, 14, 13, 12, 11, 8, 5, 2, 10, 7, 4, 1, 9, 6, 3, 0,\n      15, 14, 13, 12, 11, 8, 5, 2, 10, 7, 4, 1, 9, 6, 3, 0); // same for both lanes\n  else\n    mask = _mm256_set_epi8(15, 14, 13, 12, 11, 10, 5, 4, 9, 8, 3, 2, 7, 6, 1, 0,\n      15, 14, 13, 12, 11, 10, 5, 4, 9, 8, 3, 2, 7, 6, 1, 0); // same for both lanes\n\n  __m256i max_pixel_value;\n  if constexpr(sizeof(pixel_t) == 1)\n    max_pixel_value = _mm256_set1_epi8((char)0xFF);\n  else\n    max_pixel_value = _mm256_set1_epi16((short)0xFFFF); // bits_per_pixel is 16\n\n// read-optimized\n#define SRC_ADDRESS_ADVANCES\n#ifdef SRC_ADDRESS_ADVANCES\n  srcp -= src_pitch * (height - 1); // source packed RGB is upside down\n  dstp[0] += dst_pitch[0] * (height - 1);\n  dstp[1] += dst_pitch[1] * (height - 1);\n  dstp[2] += dst_pitch[2] * (height - 1);\n  if (targetHasAlpha)\n    dstp[3] += dst_pitch[3] * (height - 1);\n#endif\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wmod; x += pixels_at_a_time) {\n      auto BGRA_1_Lo48 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x * 2 * 48 / pixels_at_a_time));\n      auto BGRA_2_Lo48 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x * 2 * 48 / pixels_at_a_time + 16));\n      auto BGRA_3_Lo48 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x * 2 * 48 / pixels_at_a_time + 32));\n\n      auto BGRA_1_Hi48 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x * 2 * 48 / pixels_at_a_time + 0 + 48));\n      auto BGRA_2_Hi48 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x * 2 * 48 / pixels_at_a_time + 16 + 48));\n      auto BGRA_3_Hi48 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x * 2 * 48 / pixels_at_a_time + 32 + 48));\n\n      auto BGRA_1 = _mm256_set_m128i(BGRA_1_Hi48, BGRA_1_Lo48);\n      auto BGRA_2 = _mm256_set_m128i(BGRA_2_Hi48, BGRA_2_Lo48);\n      auto BGRA_3 = _mm256_set_m128i(BGRA_3_Hi48, BGRA_3_Lo48);\n\n      auto pack_lo = _mm256_shuffle_epi8(BGRA_1, mask); // 111111111111: BBBBGGGGRRRR and rest: BGRB | BBGGRR and rest: BBGG\n      BGRA_1 = _mm256_alignr_epi8(BGRA_2, BGRA_1, 12);\n      auto pack_hi = _mm256_shuffle_epi8(BGRA_1, mask); // 222222222222: BBBBGGGGRRRR | BBGGRR\n      BGRA_2 = _mm256_alignr_epi8(BGRA_3, BGRA_2, 8);\n      auto pack_lo2 = _mm256_shuffle_epi8(BGRA_2, mask); // 333333333333: BBBBGGGGRRRR | BBGGRR\n      BGRA_3 = _mm256_srli_si256(BGRA_3, 4); // to use the same mask\n      auto pack_hi2 = _mm256_shuffle_epi8(BGRA_3, mask); // 444444444444: BBBBGGGGRRRR | BBGGRR\n\n      auto BG1 = _mm256_unpacklo_epi32(pack_lo, pack_hi);  // BBBB_lo BBBB_hi GGGG_lo GGGG_hi\n      auto BG2 = _mm256_unpacklo_epi32(pack_lo2, pack_hi2);  // BBBB_lo BBBB_hi GGGG_lo GGGG_hi\n      auto RA1 = _mm256_unpackhi_epi32(pack_lo, pack_hi);   // RRRR_lo RRRR_hi AAAA_lo AAAA_hi\n      auto RA2 = _mm256_unpackhi_epi32(pack_lo2, pack_hi2);  // RRRR_lo RRRR_hi AAAA_lo AAAA_hi\n      auto B = _mm256_unpacklo_epi64(BG1, BG2);\n      _mm256_stream_si256(reinterpret_cast<__m256i *>(dstp[1] + x * sizeof(pixel_t)), B); // B\n      auto G = _mm256_unpackhi_epi64(BG1, BG2);\n      _mm256_stream_si256(reinterpret_cast<__m256i *>(dstp[0] + x * sizeof(pixel_t)), G); // G\n      auto R = _mm256_unpacklo_epi64(RA1, RA2);\n      _mm256_stream_si256(reinterpret_cast<__m256i *>(dstp[2] + x * sizeof(pixel_t)), R); // R\n      if (targetHasAlpha)\n        _mm256_stream_si256(reinterpret_cast<__m256i *>(dstp[3] + x * sizeof(pixel_t)), max_pixel_value); // A\n    }\n    // rest, unaligned but simd\n    if (wmod != width) {\n      size_t x = (width - pixels_at_a_time);\n      auto BGRA_1_Lo48 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + x * 2 * 48 / pixels_at_a_time));\n      auto BGRA_2_Lo48 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + x * 2 * 48 / pixels_at_a_time + 16));\n      auto BGRA_3_Lo48 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + x * 2 * 48 / pixels_at_a_time + 32));\n\n      auto BGRA_1_Hi48 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + x * 2 * 48 / pixels_at_a_time + 0 + 48));\n      auto BGRA_2_Hi48 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + x * 2 * 48 / pixels_at_a_time + 16 + 48));\n      auto BGRA_3_Hi48 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + x * 2 * 48 / pixels_at_a_time + 32 + 48));\n\n      auto BGRA_1 = _mm256_set_m128i(BGRA_1_Hi48, BGRA_1_Lo48);\n      auto BGRA_2 = _mm256_set_m128i(BGRA_2_Hi48, BGRA_2_Lo48);\n      auto BGRA_3 = _mm256_set_m128i(BGRA_3_Hi48, BGRA_3_Lo48);\n\n      auto pack_lo = _mm256_shuffle_epi8(BGRA_1, mask); // 111111111111: BBBBGGGGRRRR and rest: BGRB | BBGGRR and rest: BBGG\n      BGRA_1 = _mm256_alignr_epi8(BGRA_2, BGRA_1, 12);\n      auto pack_hi = _mm256_shuffle_epi8(BGRA_1, mask); // 222222222222: BBBBGGGGRRRR | BBGGRR\n      BGRA_2 = _mm256_alignr_epi8(BGRA_3, BGRA_2, 8);\n      auto pack_lo2 = _mm256_shuffle_epi8(BGRA_2, mask); // 333333333333: BBBBGGGGRRRR | BBGGRR\n      BGRA_3 = _mm256_srli_si256(BGRA_3, 4); // to use the same mask\n      auto pack_hi2 = _mm256_shuffle_epi8(BGRA_3, mask); // 444444444444: BBBBGGGGRRRR | BBGGRR\n\n      auto BG1 = _mm256_unpacklo_epi32(pack_lo, pack_hi);  // BBBB_lo BBBB_hi GGGG_lo GGGG_hi\n      auto BG2 = _mm256_unpacklo_epi32(pack_lo2, pack_hi2);  // BBBB_lo BBBB_hi GGGG_lo GGGG_hi\n      auto RA1 = _mm256_unpackhi_epi32(pack_lo, pack_hi);   // RRRR_lo RRRR_hi AAAA_lo AAAA_hi\n      auto RA2 = _mm256_unpackhi_epi32(pack_lo2, pack_hi2);  // RRRR_lo RRRR_hi AAAA_lo AAAA_hi\n      auto B = _mm256_unpacklo_epi64(BG1, BG2);\n      _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp[1] + x * sizeof(pixel_t)), B); // B\n      auto G = _mm256_unpackhi_epi64(BG1, BG2);\n      _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp[0] + x * sizeof(pixel_t)), G); // G\n      auto R = _mm256_unpacklo_epi64(RA1, RA2);\n      _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp[2] + x * sizeof(pixel_t)), R); // R\n      if (targetHasAlpha)\n        _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp[3] + x * sizeof(pixel_t)), max_pixel_value); // A\n    }\n#ifdef SRC_ADDRESS_ADVANCES\n    srcp += src_pitch; // source packed RGB is upside down\n    dstp[0] -= dst_pitch[0];\n    dstp[1] -= dst_pitch[1];\n    dstp[2] -= dst_pitch[2];\n    if (targetHasAlpha)\n      dstp[3] -= dst_pitch[3];\n#else\n    srcp -= src_pitch; // source packed RGB is upside down\n    dstp[0] += dst_pitch[0];\n    dstp[1] += dst_pitch[1];\n    dstp[2] += dst_pitch[2];\n    if (targetHasAlpha)\n      dstp[3] += dst_pitch[3];\n#endif\n  }\n#undef SRC_ADDRESS_ADVANCES\n}\n\n// Instantiate them\ntemplate void convert_rgb_to_rgbp_avx2<uint8_t, false>(const BYTE *srcp, BYTE * (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height);\ntemplate void convert_rgb_to_rgbp_avx2<uint8_t, true>(const BYTE *srcp, BYTE * (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height);\ntemplate void convert_rgb_to_rgbp_avx2<uint16_t, false>(const BYTE *srcp, BYTE * (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height);\ntemplate void convert_rgb_to_rgbp_avx2<uint16_t, true>(const BYTE *srcp, BYTE * (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height);\n\ntemplate<typename pixel_t, bool targetHasAlpha>\nvoid convert_rgba_to_rgbp_avx2(const BYTE* srcp, BYTE* (&dstp)[4],\n  int src_pitch, int(&dst_pitch)[4], int width, int height)\n{\n  const int pixels_per_iter = (sizeof(pixel_t) == 1) ? 16 : 8;\n  // 8-bit: process 16 pixels per loop (64 bytes in -> four 16-byte stores out)\n  // 16-bit: process 8 pixels per loop (64 bytes in -> four 16-byte stores out)\n  __m128i mask128;\n  if constexpr (sizeof(pixel_t) == 1)\n    mask128 = _mm_set_epi8(15, 11, 7, 3, 14, 10, 6, 2, 13, 9, 5, 1, 12, 8, 4, 0);\n  else\n    mask128 = _mm_set_epi8(15, 14, 7, 6, 13, 12, 5, 4, 11, 10, 3, 2, 9, 8, 1, 0);\n  __m256i vmask = _mm256_broadcastsi128_si256(mask128);\n  // Avisynth's scanline alignment is 64 bytes, so no remainder hanfling is needed for 16 RGB32 or 8 RGB64 pixels\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; x += pixels_per_iter) {\n      __m256i srcA = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp + x * 4 * sizeof(pixel_t)));\n      __m256i srcB = _mm256_load_si256(reinterpret_cast<const __m256i*>(srcp + (x + pixels_per_iter / 2) * 4 * sizeof(pixel_t)));\n\n      __m256i shufA = _mm256_shuffle_epi8(srcA, vmask);\n      __m256i shufB = _mm256_shuffle_epi8(srcB, vmask);\n\n      __m128i a_lo = _mm256_castsi256_si128(shufA);\n      __m128i a_hi = _mm256_extracti128_si256(shufA, 1);\n      __m128i b_lo = _mm256_castsi256_si128(shufB);\n      __m128i b_hi = _mm256_extracti128_si256(shufB, 1);\n\n      __m128i bg_0 = _mm_unpacklo_epi32(a_lo, a_hi);\n      __m128i ra_0 = _mm_unpackhi_epi32(a_lo, a_hi);\n      __m128i bg_1 = _mm_unpacklo_epi32(b_lo, b_hi);\n      __m128i ra_1 = _mm_unpackhi_epi32(b_lo, b_hi);\n\n      __m128i chB = _mm_unpacklo_epi64(bg_0, bg_1);\n      __m128i chG = _mm_unpackhi_epi64(bg_0, bg_1);\n      __m128i chR = _mm_unpacklo_epi64(ra_0, ra_1);\n      __m128i chA = _mm_unpackhi_epi64(ra_0, ra_1);\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp[1] + x * sizeof(pixel_t)), chB);\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp[0] + x * sizeof(pixel_t)), chG);\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp[2] + x * sizeof(pixel_t)), chR);\n      if constexpr (targetHasAlpha)\n        _mm_store_si128(reinterpret_cast<__m128i*>(dstp[3] + x * sizeof(pixel_t)), chA);\n    }\n\n    srcp -= src_pitch; // source packed RGB is upside down\n    dstp[0] += dst_pitch[0];\n    dstp[1] += dst_pitch[1];\n    dstp[2] += dst_pitch[2];\n    if constexpr (targetHasAlpha)\n      dstp[3] += dst_pitch[3];\n  }\n}\n\n// Instantiate them\ntemplate void convert_rgba_to_rgbp_avx2<uint8_t, false>(const BYTE* srcp, BYTE* (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height);\ntemplate void convert_rgba_to_rgbp_avx2<uint8_t, true>(const BYTE* srcp, BYTE* (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height);\ntemplate void convert_rgba_to_rgbp_avx2<uint16_t, false>(const BYTE* srcp, BYTE* (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height);\ntemplate void convert_rgba_to_rgbp_avx2<uint16_t, true>(const BYTE* srcp, BYTE* (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height);\n"
  },
  {
    "path": "avs_core/convert/intel/convert_rgb_avx2.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Convert_RGB_AVX2_H__\n#define __Convert_RGB_AVX2_H__\n\n#include <avs/types.h>\n\ntemplate<typename pixel_t, bool targetHasAlpha>\nvoid convert_rgb_to_rgbp_avx2(const BYTE *srcp, BYTE * (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height);\n\ntemplate<typename pixel_t, bool targetHasAlpha>\nvoid convert_rgba_to_rgbp_avx2(const BYTE* srcp, BYTE* (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height);\n\n#endif  // __Convert_RGB_AVX2_H__\n"
  },
  {
    "path": "avs_core/convert/intel/convert_rgb_avx512.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include <avs/config.h>\n#include <avs/types.h>\n#include <cstdint>\n\n#include \"../../filters/intel/check_avx512.h\" // compiler avx512 directives check\n#include \"convert_rgb_avx512.h\"\n\n#include <immintrin.h> // Includes AVX-512 intrinsics\n\ntemplate<typename pixel_t, bool targetHasAlpha>\nvoid convert_rgba_to_rgbp_avx512vbmi(const BYTE *srcp, BYTE * (&dstp)[4],\n    int src_pitch, int (&dst_pitch)[4], int width, int height)\n{\n  // 8-bit:  16 BGRA8  pixels = 64 bytes fits in one ZMM\n  // 16-bit:  8 BGRA16 pixels = 64 bytes fits in one ZMM\n  const int pixels_at_a_time = (sizeof(pixel_t) == 1) ? 16 : 8;\n\n  // Build the vpermb index vector, constant, computed once\n  __m512i perm;\n  if constexpr (sizeof(pixel_t) == 1) {\n    // B channel: bytes 0,4,8,...,60  (stride 4, offset 0)\n    // G channel: bytes 1,5,9,...,61  (stride 4, offset 1)\n    // R channel: bytes 2,6,10,...,62 (stride 4, offset 2)\n    // A channel: bytes 3,7,11,...,63 (stride 4, offset 3)\n    alignas(64) uint8_t idx[64];\n    for (int i = 0; i < 16; i++) idx[i]    = i * 4 + 0; // B\n    for (int i = 0; i < 16; i++) idx[16+i] = i * 4 + 1; // G\n    for (int i = 0; i < 16; i++) idx[32+i] = i * 4 + 2; // R\n    for (int i = 0; i < 16; i++) idx[48+i] = i * 4 + 3; // A\n    perm = _mm512_load_si512(reinterpret_cast<const __m512i *>(idx));\n  }\n  else {\n    alignas(64) uint8_t idx[64];\n    for (int i = 0; i < 8; i++) {\n      idx[i * 2 + 0] = (uint8_t)(i * 8 + 0); // B low byte\n      idx[i * 2 + 1] = (uint8_t)(i * 8 + 1); // B high byte\n      idx[16 + i * 2 + 0] = (uint8_t)(i * 8 + 2); // G low byte\n      idx[16 + i * 2 + 1] = (uint8_t)(i * 8 + 3); // G high byte\n      idx[32 + i * 2 + 0] = (uint8_t)(i * 8 + 4); // R low byte\n      idx[32 + i * 2 + 1] = (uint8_t)(i * 8 + 5); // R high byte\n      idx[48 + i * 2 + 0] = (uint8_t)(i * 8 + 6); // A low byte\n      idx[48 + i * 2 + 1] = (uint8_t)(i * 8 + 7); // A high byte\n    }\n    perm = _mm512_load_si512(reinterpret_cast<const __m512i*>(idx));\n  }\n\n  // No remainder: BGRA source is 4 bytes/pixel, 64-byte aligned scanlines guarantee width is a multiple of 16 (8-bit) or 8 (16-bit)\n  for (int y = height; y > 0; --y) {\n    for (int x = 0; x < width; x += pixels_at_a_time) {\n      __m512i src = _mm512_load_si512(\n          reinterpret_cast<const __m512i *>(srcp + x * 4 * sizeof(pixel_t)));\n\n      // 64-byte cross-lane permutation\n      // Result layout:\n      //   bytes  0-15: B0..B15  (8-bit) or B0..B7 as pairs (16-bit)\n      //   bytes 16-31: G channel\n      //   bytes 32-47: R channel\n      //   bytes 48-63: A channel\n      __m512i result = _mm512_permutexvar_epi8(perm, src);\n\n      // Extract each 128-bit quarter and store\n      // _mm512_extracti32x4_epi32: extract 128-bit lane 0,1,2,3\n      __m128i B = _mm512_extracti32x4_epi32(result, 0);\n      __m128i G = _mm512_extracti32x4_epi32(result, 1);\n      __m128i R = _mm512_extracti32x4_epi32(result, 2);\n      __m128i A = _mm512_extracti32x4_epi32(result, 3);\n\n      _mm_store_si128(reinterpret_cast<__m128i *>(dstp[1] + x * sizeof(pixel_t)), B);\n      _mm_store_si128(reinterpret_cast<__m128i *>(dstp[0] + x * sizeof(pixel_t)), G);\n      _mm_store_si128(reinterpret_cast<__m128i *>(dstp[2] + x * sizeof(pixel_t)), R);\n      if constexpr (targetHasAlpha)\n        _mm_store_si128(reinterpret_cast<__m128i *>(dstp[3] + x * sizeof(pixel_t)), A);\n    }\n\n\n    srcp -= src_pitch;\n    dstp[0] += dst_pitch[0];\n    dstp[1] += dst_pitch[1];\n    dstp[2] += dst_pitch[2];\n    if constexpr (targetHasAlpha)\n      dstp[3] += dst_pitch[3];\n  }\n}\n\n// Instantiations\ntemplate void convert_rgba_to_rgbp_avx512vbmi<uint8_t,  false>(const BYTE* srcp, BYTE* (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height);\ntemplate void convert_rgba_to_rgbp_avx512vbmi<uint8_t,  true>(const BYTE* srcp, BYTE* (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height);\ntemplate void convert_rgba_to_rgbp_avx512vbmi<uint16_t, false>(const BYTE* srcp, BYTE* (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height);\ntemplate void convert_rgba_to_rgbp_avx512vbmi<uint16_t, true>(const BYTE* srcp, BYTE* (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height);\n"
  },
  {
    "path": "avs_core/convert/intel/convert_rgb_avx512.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Convert_RGB_AVX512_H__\n#define __Convert_RGB_AVX512_H__\n\n#include <avisynth.h>\n\ntemplate<typename pixel_t, bool targetHasAlpha>\nvoid convert_rgba_to_rgbp_avx512vbmi(const BYTE* srcp, BYTE* (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height);\n\n\n#endif // __Convert_RGB_AVX512_H__\n"
  },
  {
    "path": "avs_core/convert/intel/convert_rgb_sse.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include \"../convert_rgb.h\"\n\n// Intrinsics base header + really required extension headers\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n#include <tmmintrin.h> // SSSE3\n\n#include <avs/alignment.h>\n\n\n\n\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nvoid convert_rgb48_to_rgb64_ssse3(const BYTE *srcp, BYTE *dstp, size_t src_pitch, size_t dst_pitch, size_t width, size_t height)\n{\n  size_t mod16_width = sizeof(uint16_t)*(width & (~size_t(7)));\n  __m128i mask0 = _mm_set_epi8((char)0x80, (char)0x80, 11, 10, 9, 8, 7, 6, (char)0x80, (char)0x80, 5, 4, 3, 2, 1, 0);\n  __m128i mask1 = _mm_set_epi8((char)0x80, (char)0x80, 15, 14, 13, 12, 11, 10, (char)0x80, (char)0x80, 9, 8, 7, 6, 5, 4);\n  __m128i alpha = _mm_set_epi32(0xFFFF0000,0x00000000,0xFFFF0000,0x00000000);\n\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < mod16_width; x+= 16) {\n      __m128i src0 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp+x*3));\n      // 7...       ...0\n      // B G|R B G R B G  #0 #1 (#2)       x*3+0\n      // G R B G|R B G R  (#2) #3 #4 (#5)  x*3+16\n      // R B G R B G|R B  (#5) #6 #7       x*3+32\n      __m128i dst = _mm_or_si128(alpha, _mm_shuffle_epi8(src0, mask0));\n      _mm_stream_si128(reinterpret_cast<__m128i*>(dstp+4*x), dst);\n\n      __m128i src1 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp+x*3+16));\n      __m128i tmp = _mm_alignr_epi8(src1, src0, 12);\n      dst = _mm_or_si128(alpha, _mm_shuffle_epi8(tmp, mask0));\n      _mm_stream_si128(reinterpret_cast<__m128i*>(dstp+x*4+16), dst);\n\n      __m128i src2 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp+x*3+32));\n      tmp = _mm_alignr_epi8(src2, src1, 8);\n      dst = _mm_or_si128(alpha, _mm_shuffle_epi8(tmp, mask0));\n      _mm_stream_si128(reinterpret_cast<__m128i*>(dstp+x*4+32), dst);\n\n      dst = _mm_or_si128(alpha, _mm_shuffle_epi8(src2, mask1));\n      _mm_stream_si128(reinterpret_cast<__m128i*>(dstp+x*4+48), dst);\n    }\n\n    for (size_t x = mod16_width/sizeof(uint16_t); x < width; ++x) {\n      reinterpret_cast<uint16_t *>(dstp)[x*4+0] = reinterpret_cast<const uint16_t *>(srcp)[x*3+0];\n      reinterpret_cast<uint16_t *>(dstp)[x*4+1] = reinterpret_cast<const uint16_t *>(srcp)[x*3+1];\n      reinterpret_cast<uint16_t *>(dstp)[x*4+2] = reinterpret_cast<const uint16_t *>(srcp)[x*3+2];\n      reinterpret_cast<uint16_t *>(dstp)[x*4+3] = 65535;\n    }\n\n    srcp += src_pitch;\n    dstp += dst_pitch;\n  }\n}\n\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nvoid convert_rgb24_to_rgb32_ssse3(const BYTE *srcp, BYTE *dstp, size_t src_pitch, size_t dst_pitch, size_t width, size_t height)\n{\n  size_t mod16_width = (width + 3) & (~size_t(15)); //when the modulo is more than 13, a problem does not happen\n  __m128i mask0 = _mm_set_epi8((char)0x80, 11, 10, 9, (char)0x80, 8, 7, 6, (char)0x80, 5, 4, 3, (char)0x80, 2, 1, 0);\n  __m128i mask1 = _mm_set_epi8((char)0x80, 15, 14, 13, (char)0x80, 12, 11, 10, (char)0x80, 9, 8, 7, (char)0x80, 6, 5, 4);\n  __m128i alpha = _mm_set1_epi32(0xFF000000);\n\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < mod16_width; x+= 16) {\n      __m128i src0 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp+x*3));\n      __m128i dst = _mm_or_si128(alpha, _mm_shuffle_epi8(src0, mask0));\n      _mm_stream_si128(reinterpret_cast<__m128i*>(dstp+4*x), dst);\n\n      __m128i src1 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp+x*3+16));\n      __m128i tmp = _mm_alignr_epi8(src1, src0, 12);\n      dst = _mm_or_si128(alpha, _mm_shuffle_epi8(tmp, mask0));\n      _mm_stream_si128(reinterpret_cast<__m128i*>(dstp+x*4+16), dst);\n\n      __m128i src2 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp+x*3+32));\n      tmp = _mm_alignr_epi8(src2, src1, 8);\n      dst = _mm_or_si128(alpha, _mm_shuffle_epi8(tmp, mask0));\n      _mm_stream_si128(reinterpret_cast<__m128i*>(dstp+x*4+32), dst);\n\n      dst = _mm_or_si128(alpha, _mm_shuffle_epi8(src2, mask1));\n      _mm_stream_si128(reinterpret_cast<__m128i*>(dstp+x*4+48), dst);\n    }\n\n    for (size_t x = mod16_width; x < width; ++x) {\n      dstp[x*4+0] = srcp[x*3+0];\n      dstp[x*4+1] = srcp[x*3+1];\n      dstp[x*4+2] = srcp[x*3+2];\n      dstp[x*4+3] = 255;\n    }\n\n    srcp += src_pitch;\n    dstp += dst_pitch;\n  }\n}\n\n\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nvoid convert_rgb64_to_rgb48_ssse3(const BYTE *srcp, BYTE *dstp, size_t src_pitch, size_t dst_pitch, size_t width, size_t height)\n{\n  size_t mod16_width = sizeof(uint16_t) * ((width) & (~size_t(7))); // perhaps width+2 is still o.k\n  __m128i mask0 = _mm_set_epi8(13, 12, 11, 10, 9, 8, 5, 4, 3, 2, 1, 0, 15, 14, 7, 6); // BBGGRRBBGGRRAAAA\n  __m128i mask1 = _mm_set_epi8(15, 14, 7, 6, 13, 12, 11, 10, 9, 8, 5, 4, 3, 2, 1, 0); // AAAABBGGRRBBGGRR\n\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < mod16_width; x+= 16) {\n      __m128i src0 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp+x*4));    //a1b1 g1r1 a0b0 g0r0\n      __m128i src1 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp+x*4+16)); //a3b3 g3r3 a2b2 g2r2\n      src0 = _mm_shuffle_epi8(src0, mask0);         //b1g1 r1b0 g0r0 a1a0\n      src1 = _mm_shuffle_epi8(src1, mask1);         //a3a2 b3g3 r3b2 g2r2\n      __m128i dst = _mm_alignr_epi8(src1, src0, 4); //g2r2 b1g1 r1b0 g0r0\n      _mm_stream_si128(reinterpret_cast<__m128i*>(dstp+x*3), dst);\n\n      src0 = _mm_slli_si128(src1, 4);       // b3g3 r3b2 g2r2 XXXX\n      src1 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x * 4 + 32)); // a5b5 g5r5 a4b4 g4r4\n      src1 = _mm_shuffle_epi8(src1, mask1); // a5a4 b5g5 r5b4 g4r4\n      dst = _mm_alignr_epi8(src1, src0, 8); // r5b4 g4r4 b3g3 r3b2\n      _mm_stream_si128(reinterpret_cast<__m128i*>(dstp+x*3+16), dst);\n\n      src0 = _mm_slli_si128(src1, 4);        // b5g5 r5b4 g4r4 XXXX\n      src1 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp+x*4+48)); // a7b7 g7r7 a6b6 g6r6\n      src1 = _mm_shuffle_epi8(src1, mask1);  // a7a6 b7g7 r7b6 g6r6\n      dst = _mm_alignr_epi8(src1, src0, 12); // b7g7 r7b6 g6r6 b5g5\n      _mm_stream_si128(reinterpret_cast<__m128i*>(dstp+x*3+32), dst);\n    }\n\n    for (size_t x = mod16_width/sizeof(uint16_t); x < width; ++x) {\n      reinterpret_cast<uint16_t *>(dstp)[x*3+0] = reinterpret_cast<const uint16_t *>(srcp)[x*4+0];\n      reinterpret_cast<uint16_t *>(dstp)[x*3+1] = reinterpret_cast<const uint16_t *>(srcp)[x*4+1];\n      reinterpret_cast<uint16_t *>(dstp)[x*3+2] = reinterpret_cast<const uint16_t *>(srcp)[x*4+2];\n    }\n\n    srcp += src_pitch;\n    dstp += dst_pitch;\n  }\n}\n\n//todo: think how to port to sse2 without tons of shuffles or (un)packs\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nvoid convert_rgb32_to_rgb24_ssse3(const BYTE *srcp, BYTE *dstp, size_t src_pitch, size_t dst_pitch, size_t width, size_t height)\n{\n  size_t mod16_width = (width + 3) & (~size_t(15)); //when the modulo is more than 13, a problem does not happen\n  __m128i mask0 = _mm_set_epi8(14, 13, 12, 10, 9, 8, 6, 5, 4, 2, 1, 0, 15, 11, 7, 3);\n  __m128i mask1 = _mm_set_epi8(15, 11, 7, 3, 14, 13, 12, 10, 9, 8, 6, 5, 4, 2, 1, 0);\n\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < mod16_width; x+= 16) {\n      __m128i src0 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp+x*4));    //a3b3 g3r3 a2b2 g2r2 a1b1 g1r1 a0b0 g0r0\n      __m128i src1 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp+x*4+16)); //a7b7 g7r7 a6b6 g6r6 a5b5 g5r5 a4b4 g4r4\n      src0 = _mm_shuffle_epi8(src0, mask0);         //b3g3 r3b2 g2r2 b1g1 r1b0 g0r0 a3a2 a1a0\n      src1 = _mm_shuffle_epi8(src1, mask1);         //a7a6 a5a4 b7g7 r7b6 g6r6 b5g5 r5b4 g4r4\n      __m128i dst = _mm_alignr_epi8(src1, src0, 4); //r5b4 g4r4 b3g3 r3b2 g2r2 b1g1 r1b0 g0r0\n      _mm_stream_si128(reinterpret_cast<__m128i*>(dstp+x*3), dst);\n\n      src0 = _mm_slli_si128(src1, 4);       //b7g7 r7b6 g6r6 b5g5 r5b4 g4r4 XXXX XXXX\n      src1 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x * 4 + 32)); //aBbB gBrB aAbA gArA a9b9 g9r9 a8b8 g8r8\n      src1 = _mm_shuffle_epi8(src1, mask1); //aBaA a9a8 bBgB rBbA gArA b9g9 r9b8 g8r8\n      dst = _mm_alignr_epi8(src1, src0, 8); //gArA b9g9 r9b8 g8r8 b7g7 r7b6 g6r6 b5g5\n      _mm_stream_si128(reinterpret_cast<__m128i*>(dstp+x*3+16), dst);\n\n      src0 = _mm_slli_si128(src1, 4);        //bBgB rBbA gArA b9g9 r9b8 g8r8 XXXX XXXX\n      src1 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp+x*4+48)); //aFbF gFrF aEbE gErE aDbD gDrD aCbC gCrC\n      src1 = _mm_shuffle_epi8(src1, mask1);  //aFaE aDaC bFgF rFbE gErE bDgD rDbC gCrC\n      dst = _mm_alignr_epi8(src1, src0, 12); //bFgF rFbE gErE bDgD rDbC gCrC bBgB rBbA\n      _mm_stream_si128(reinterpret_cast<__m128i*>(dstp+x*3+32), dst);\n    }\n\n    for (size_t x = mod16_width; x < width; ++x) {\n      dstp[x*3+0] = srcp[x*4+0];\n      dstp[x*3+1] = srcp[x*4+1];\n      dstp[x*3+2] = srcp[x*4+2];\n    }\n\n    srcp += src_pitch;\n    dstp += dst_pitch;\n  }\n}\n\nvoid convert_rgb32_to_rgb24_sse2(const BYTE* srcp, BYTE* dstp, size_t src_pitch, size_t dst_pitch, size_t width, size_t height) {\n  size_t mod4_width = width & (~size_t(3));\n\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < mod4_width; x += 4) {\n      // Load 4 pixels (16 bytes)\n      __m128i src = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + x * 4));\n\n      // Pixel 0 (bytes 0,1,2) and Pixel 1 (bytes 4,5,6)\n      // Goal: [ 00 00 r1 g1 b1 r0 g0 b0 ] in the low 64 bits\n      __m128i p0 = _mm_and_si128(src, _mm_set_epi32(0, 0, 0, 0x00FFFFFF));\n      __m128i p1 = _mm_and_si128(src, _mm_set_epi32(0, 0, 0x00FFFFFF, 0));\n      __m128i dst01 = _mm_or_si128(p0, _mm_srli_si128(p1, 1));\n\n      // Pixel 2 (bytes 8,9,10) and Pixel 3 (bytes 12,13,14)\n      __m128i p2 = _mm_and_si128(src, _mm_set_epi32(0, 0x00FFFFFF, 0, 0));\n      __m128i p3 = _mm_and_si128(src, _mm_set_epi32(0x00FFFFFF, 0, 0, 0));\n\n      // Shift p2 down to byte 6 and p3 down to byte 9\n      __m128i dst23 = _mm_or_si128(_mm_srli_si128(p2, 2), _mm_srli_si128(p3, 3));\n\n      // Combine them\n      __m128i final = _mm_or_si128(dst01, dst23);\n\n      // final now contains: [ B3 G3 R3 | B2 G2 R2 | B1 G1 R1 | B0 G0 R0 ]\n      // In the first 12 bytes. \n      // We store 8 bytes (64-bit) then 4 bytes (32-bit)\n      _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + x * 3), final);\n      *reinterpret_cast<int*>(dstp + x * 3 + 8) = _mm_cvtsi128_si32(_mm_srli_si128(final, 8));\n    }\n\n    // Standard remainder loop\n    for (size_t x = mod4_width; x < width; ++x) {\n      dstp[x * 3 + 0] = srcp[x * 4 + 0];\n      dstp[x * 3 + 1] = srcp[x * 4 + 1];\n      dstp[x * 3 + 2] = srcp[x * 4 + 2];\n    }\n\n    srcp += src_pitch;\n    dstp += dst_pitch;\n  }\n}\n\n\n// ============================================================\n// SSE2 emulation of _mm_alignr_epi8(hi, lo, N)\n// Concatenates [hi:lo] as 32 bytes, returns bytes [N..N+15]\n// ============================================================\ntemplate<int N>\nstatic AVS_FORCEINLINE __m128i sse2_alignr(__m128i hi, __m128i lo) {\n  return _mm_or_si128(_mm_srli_si128(lo, N), _mm_slli_si128(hi, 16 - N));\n}\n\n// ============================================================\n// 8-bit helper: gather B, G, R from 4 BGR8 pixels\n//\n// Input 'grp': low 12 bytes hold 4 BGR8 pixels\n//   byte:  0   1   2   3   4   5   6   7   8   9  10  11\n//   data: B0  G0  R0  B1  G1  R1  B2  G2  R2  B3  G3  R3\n//\n// Output bOut, gOut, rOut: valid bytes in positions 0..3 only\n//   bOut[0..3] = B0 B1 B2 B3\n//   gOut[0..3] = G0 G1 G2 G3\n//   rOut[0..3] = R0 R1 R2 R3\n// ============================================================\nstatic AVS_FORCEINLINE void gather_bgr8_4px(__m128i grp,\n  __m128i& bOut, __m128i& gOut, __m128i& rOut)\n{\n  // B is at bytes 0, 3, 6, 9. We shift them to 0, 1, 2, 3.\n  __m128i b = _mm_and_si128(grp, _mm_set_epi32(0, 0, 0, 0x000000FF)); // B0\n  b = _mm_or_si128(b, _mm_and_si128(_mm_srli_si128(grp, 2), _mm_set_epi32(0, 0, 0, 0x0000FF00))); // B1\n  b = _mm_or_si128(b, _mm_and_si128(_mm_srli_si128(grp, 4), _mm_set_epi32(0, 0, 0, 0x00FF0000))); // B2\n  b = _mm_or_si128(b, _mm_and_si128(_mm_srli_si128(grp, 6), _mm_set_epi32(0, 0, 0, 0xFF000000))); // B3\n  bOut = b;\n\n  // G is at bytes 1, 4, 7, 10.\n  __m128i g = _mm_and_si128(_mm_srli_si128(grp, 1), _mm_set_epi32(0, 0, 0, 0x000000FF)); // G0\n  g = _mm_or_si128(g, _mm_and_si128(_mm_srli_si128(grp, 3), _mm_set_epi32(0, 0, 0, 0x0000FF00))); // G1\n  g = _mm_or_si128(g, _mm_and_si128(_mm_srli_si128(grp, 5), _mm_set_epi32(0, 0, 0, 0x00FF0000))); // G2\n  g = _mm_or_si128(g, _mm_and_si128(_mm_srli_si128(grp, 7), _mm_set_epi32(0, 0, 0, 0xFF000000))); // G3\n  gOut = g;\n\n  // R is at bytes 2, 5, 8, 11.\n  __m128i r = _mm_and_si128(_mm_srli_si128(grp, 2), _mm_set_epi32(0, 0, 0, 0x000000FF)); // R0\n  r = _mm_or_si128(r, _mm_and_si128(_mm_srli_si128(grp, 4), _mm_set_epi32(0, 0, 0, 0x0000FF00))); // R1\n  r = _mm_or_si128(r, _mm_and_si128(_mm_srli_si128(grp, 6), _mm_set_epi32(0, 0, 0, 0x00FF0000))); // R2\n  r = _mm_or_si128(r, _mm_and_si128(_mm_srli_si128(grp, 8), _mm_set_epi32(0, 0, 0, 0xFF000000))); // R3\n  rOut = r;\n}\n\n// ============================================================\n// 8-bit: deinterleave 16 BGR8 pixels from 3 × 16-byte registers\n// into full 16-byte B, G, R output registers\n// ============================================================\nstatic AVS_FORCEINLINE void deinterleave_bgr8_16px(\n  __m128i r0, __m128i r1, __m128i r2,\n  __m128i& B, __m128i& G, __m128i& R)\n{\n  // Split 48-byte stream into 4 groups of 12 bytes (4 pixels each),\n  // each aligned to byte 0 of a 128-bit register:\n  //   group0: r0[0..11]\n  //   group1: r0[12..15] ++ r1[0..7]   = alignr(r1, r0, 12)\n  //   group2: r1[8..15]  ++ r2[0..3]   = alignr(r2, r1,  8)\n  //   group3: r2[4..15]                = srli(r2, 4)\n  __m128i g0 = r0;\n  __m128i g1 = sse2_alignr<12>(r1, r0);\n  __m128i g2 = sse2_alignr<8>(r2, r1);\n  __m128i g3 = _mm_srli_si128(r2, 4);\n\n  // Extract channels from each group (4 valid bytes each in positions 0..3)\n  __m128i B0, G0, R0, B1, G1, R1, B2, G2, R2, B3, G3, R3;\n  gather_bgr8_4px(g0, B0, G0, R0);\n  gather_bgr8_4px(g1, B1, G1, R1);\n  gather_bgr8_4px(g2, B2, G2, R2);\n  gather_bgr8_4px(g3, B3, G3, R3);\n\n  // Combine 4 groups × 4 bytes into one 16-byte register per channel.\n  // Each Bx/Gx/Rx has its 4 bytes in the low dword (bytes 0..3).\n  // unpacklo_epi32 interleaves low dwords of two registers:\n  //   unpacklo_epi32(A, B) = [A.dw0, B.dw0, A.dw1, B.dw1]\n  // unpacklo_epi64 combines low qwords:\n  //   unpacklo_epi64(A, B) = [A.qw0, B.qw0]\n  __m128i B01 = _mm_unpacklo_epi32(B0, B1);  // [B_g0(4B), B_g1(4B), ...]\n  __m128i B23 = _mm_unpacklo_epi32(B2, B3);\n  B = _mm_unpacklo_epi64(B01, B23);           // all 16 B bytes\n\n  __m128i G01 = _mm_unpacklo_epi32(G0, G1);\n  __m128i G23 = _mm_unpacklo_epi32(G2, G3);\n  G = _mm_unpacklo_epi64(G01, G23);\n\n  __m128i R01 = _mm_unpacklo_epi32(R0, R1);\n  __m128i R23 = _mm_unpacklo_epi32(R2, R3);\n  R = _mm_unpacklo_epi64(R01, R23);\n}\n\n// ============================================================\n// 16-bit helper: gather B, G, R from 2 BGR16 pixels\n//\n// Input 'grp': low 12 bytes hold 2 BGR16 pixels\n//   word:  0   1   2   3   4   5\n//   data: B0  G0  R0  B1  G1  R1\n//\n// Output bOut, gOut, rOut: valid words in positions 0..1 only\n//   bOut[0..1] = B0 B1\n//   gOut[0..1] = G0 G1\n//   rOut[0..1] = R0 R1\n// ============================================================\nstatic AVS_FORCEINLINE void gather_bgr16_2px(__m128i grp,\n  __m128i& bOut, __m128i& gOut, __m128i& rOut)\n{\n  // Words in grp: B0 G0 R0 B1 G1 R1 x x\n  // Blue: w0, w3. Use shuffle to bring them to low dword.\n  bOut = _mm_shufflelo_epi16(grp, _MM_SHUFFLE(3, 3, 3, 0));\n  // Green: w1, w4.\n  gOut = _mm_shufflelo_epi16(_mm_srli_si128(grp, 2), _MM_SHUFFLE(3, 3, 3, 0));\n  // Red: w2, w5.\n  rOut = _mm_shufflelo_epi16(_mm_srli_si128(grp, 4), _MM_SHUFFLE(3, 3, 3, 0));\n\n  // Mask out the upper 3 dwords if necessary (though unpacklo handles it)\n  __m128i mask = _mm_set_epi32(0, 0, 0, 0xFFFFFFFF);\n  bOut = _mm_and_si128(bOut, mask);\n  gOut = _mm_and_si128(gOut, mask);\n  rOut = _mm_and_si128(rOut, mask);\n}\n\n// ============================================================\n// 16-bit: deinterleave 8 BGR16 pixels from 3 × 16-byte registers\n// into full 16-byte B, G, R output registers\n// ============================================================\nstatic AVS_FORCEINLINE void deinterleave_bgr16_8px(\n  __m128i r0, __m128i r1, __m128i r2,\n  __m128i& B, __m128i& G, __m128i& R)\n{\n  // Same group extraction as 8-bit case (48 bytes, same offsets)\n  __m128i g0 = r0;\n  __m128i g1 = sse2_alignr<12>(r1, r0);\n  __m128i g2 = sse2_alignr<8>(r2, r1);\n  __m128i g3 = _mm_srli_si128(r2, 4);\n\n  // Each group: 12 bytes = 6 words = 2 BGR16 pixels\n  // Each output xB/xG/xR has 2 valid words (4 bytes) in dword 0\n  __m128i B0, G0, R0, B1, G1, R1, B2, G2, R2, B3, G3, R3;\n  gather_bgr16_2px(g0, B0, G0, R0);\n  gather_bgr16_2px(g1, B1, G1, R1);\n  gather_bgr16_2px(g2, B2, G2, R2);\n  gather_bgr16_2px(g3, B3, G3, R3);\n\n  // Combine: 4 groups × 2 words = 8 words = 16 bytes per channel\n  __m128i B01 = _mm_unpacklo_epi32(B0, B1);\n  __m128i B23 = _mm_unpacklo_epi32(B2, B3);\n  B = _mm_unpacklo_epi64(B01, B23);\n\n  __m128i G01 = _mm_unpacklo_epi32(G0, G1);\n  __m128i G23 = _mm_unpacklo_epi32(G2, G3);\n  G = _mm_unpacklo_epi64(G01, G23);\n\n  __m128i R01 = _mm_unpacklo_epi32(R0, R1);\n  __m128i R23 = _mm_unpacklo_epi32(R2, R3);\n  R = _mm_unpacklo_epi64(R01, R23);\n}\n\n// ============================================================\n// Main conversion function\n// ============================================================\n// RGB24/48 -> RGBP(A)8/16 SSE2 implementation. Ugly and not very quick.\ntemplate<typename pixel_t, bool targetHasAlpha>\nvoid convert_rgb_to_rgbp_sse2(const BYTE* srcp, BYTE* (&dstp)[4],\n  int src_pitch, int(&dst_pitch)[4],\n  int width, int height)\n{\n  const int pixels_at_a_time = (sizeof(pixel_t) == 1) ? 16 : 8;\n  const int wmod = (width / pixels_at_a_time) * pixels_at_a_time;\n\n  __m128i max_pixel_value;\n  if constexpr (sizeof(pixel_t) == 1)\n    max_pixel_value = _mm_set1_epi8((char)0xFF);\n  else\n    max_pixel_value = _mm_set1_epi16((short)0xFFFF);\n\n  for (int y = height; y > 0; --y) {\n\n    for (int x = 0; x < wmod; x += pixels_at_a_time) {\n      const BYTE* src = srcp + x * 3 * sizeof(pixel_t);\n      __m128i r0 = _mm_load_si128(reinterpret_cast<const __m128i*>(src));\n      __m128i r1 = _mm_load_si128(reinterpret_cast<const __m128i*>(src + 16));\n      __m128i r2 = _mm_load_si128(reinterpret_cast<const __m128i*>(src + 32));\n\n      __m128i B, G, R;\n      if constexpr (sizeof(pixel_t) == 1)\n        deinterleave_bgr8_16px(r0, r1, r2, B, G, R);\n      else\n        deinterleave_bgr16_8px(r0, r1, r2, B, G, R);\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp[1] + x * sizeof(pixel_t)), B);\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp[0] + x * sizeof(pixel_t)), G);\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp[2] + x * sizeof(pixel_t)), R);\n      if constexpr (targetHasAlpha)\n        _mm_store_si128(reinterpret_cast<__m128i*>(dstp[3] + x * sizeof(pixel_t)), max_pixel_value);\n    }\n\n    if (wmod != width) {\n      size_t x = width - pixels_at_a_time;\n      const BYTE* src = srcp + x * 3 * sizeof(pixel_t);\n      __m128i r0 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src));\n      __m128i r1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src + 16));\n      __m128i r2 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src + 32));\n\n      __m128i B, G, R;\n      if constexpr (sizeof(pixel_t) == 1)\n        deinterleave_bgr8_16px(r0, r1, r2, B, G, R);\n      else\n        deinterleave_bgr16_8px(r0, r1, r2, B, G, R);\n\n      _mm_storeu_si128(reinterpret_cast<__m128i*>(dstp[1] + x * sizeof(pixel_t)), B);\n      _mm_storeu_si128(reinterpret_cast<__m128i*>(dstp[0] + x * sizeof(pixel_t)), G);\n      _mm_storeu_si128(reinterpret_cast<__m128i*>(dstp[2] + x * sizeof(pixel_t)), R);\n      if constexpr (targetHasAlpha)\n        _mm_storeu_si128(reinterpret_cast<__m128i*>(dstp[3] + x * sizeof(pixel_t)), max_pixel_value);\n    }\n\n    srcp -= src_pitch;\n    dstp[0] += dst_pitch[0];\n    dstp[1] += dst_pitch[1];\n    dstp[2] += dst_pitch[2];\n    if constexpr (targetHasAlpha)\n      dstp[3] += dst_pitch[3];\n  }\n}\n\n// Instantiations\ntemplate void convert_rgb_to_rgbp_sse2<uint8_t, false>(const BYTE*, BYTE* (&)[4], int, int(&)[4], int, int);\ntemplate void convert_rgb_to_rgbp_sse2<uint8_t, true>(const BYTE*, BYTE* (&)[4], int, int(&)[4], int, int);\ntemplate void convert_rgb_to_rgbp_sse2<uint16_t, false>(const BYTE*, BYTE* (&)[4], int, int(&)[4], int, int);\ntemplate void convert_rgb_to_rgbp_sse2<uint16_t, true>(const BYTE*, BYTE* (&)[4], int, int(&)[4], int, int);\n\n// minimum width: 48 bytes\ntemplate<typename pixel_t, bool targetHasAlpha>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nvoid convert_rgb_to_rgbp_ssse3(const BYTE *srcp, BYTE * (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height)\n{\n  // RGB24: 3x16 bytes cycle, 16*(RGB) 8bit pixels\n  // RGB48: 3x16 bytes cycle, 8*(RGB) 16bit pixels\n  // 0123456789ABCDEF 0123456789ABCDEF 0123456789ABCDEF\n  // BGRBGRBGRBGRBGRB GRBGRBGRBGRBGRBG RBGRBGRBGRBGRBGR // 8 bit\n  // B G R B G R B G  R B G R B G R B  G R B G R B G R  // 16 bit\n  // 1111111111112222 2222222233333333 3333444444444444\n\n  const int pixels_at_a_time = (sizeof(pixel_t) == 1) ? 16 : 8;\n  const int wmod = (width / pixels_at_a_time) * pixels_at_a_time; // 8 pixels for 8 bit, 4 pixels for 16 bit\n  __m128i mask;\n  if constexpr(sizeof(pixel_t) == 1)\n    mask = _mm_set_epi8(15, 14, 13, 12, 11, 8, 5, 2, 10, 7, 4, 1, 9, 6, 3, 0);\n  else\n    mask = _mm_set_epi8(15, 14, 13, 12, 11, 10, 5, 4, 9, 8, 3, 2, 7, 6, 1, 0);\n\n  __m128i max_pixel_value;\n  if constexpr(sizeof(pixel_t) == 1)\n    max_pixel_value = _mm_set1_epi8((char)0xFF);\n  else\n    max_pixel_value = _mm_set1_epi16((short)0xFFFF); // bits_per_pixel is 16\n\n  for (int y = height; y > 0; --y) {\n    __m128i BGRA_1, BGRA_2, BGRA_3;\n    for (int x = 0; x < wmod; x += pixels_at_a_time) {\n      BGRA_1 = _mm_load_si128(reinterpret_cast<const __m128i *>(srcp + x * 48 / pixels_at_a_time));\n      BGRA_2 = _mm_load_si128(reinterpret_cast<const __m128i *>(srcp + x * 48 / pixels_at_a_time + 16));\n      BGRA_3 = _mm_load_si128(reinterpret_cast<const __m128i *>(srcp + x * 48 / pixels_at_a_time + 32));\n\n      auto pack_lo = _mm_shuffle_epi8(BGRA_1, mask); // 111111111111: BBBBGGGGRRRR and rest: BGRB | BBGGRR and rest: BBGG\n      BGRA_1 = _mm_alignr_epi8(BGRA_2, BGRA_1, 12);\n      auto pack_hi = _mm_shuffle_epi8(BGRA_1, mask); // 222222222222: BBBBGGGGRRRR | BBGGRR\n      BGRA_2 = _mm_alignr_epi8(BGRA_3, BGRA_2, 8);\n      auto pack_lo2 = _mm_shuffle_epi8(BGRA_2, mask); // 333333333333: BBBBGGGGRRRR | BBGGRR\n      BGRA_3 = _mm_srli_si128(BGRA_3, 4); // to use the same mask\n      auto pack_hi2 = _mm_shuffle_epi8(BGRA_3, mask); // 444444444444: BBBBGGGGRRRR | BBGGRR\n\n      __m128i BG1 = _mm_unpacklo_epi32(pack_lo, pack_hi);  // BBBB_lo BBBB_hi GGGG_lo GGGG_hi\n      __m128i BG2 = _mm_unpacklo_epi32(pack_lo2, pack_hi2);  // BBBB_lo BBBB_hi GGGG_lo GGGG_hi\n      __m128i RA1 = _mm_unpackhi_epi32(pack_lo, pack_hi);   // RRRR_lo RRRR_hi AAAA_lo AAAA_hi\n      __m128i RA2 = _mm_unpackhi_epi32(pack_lo2, pack_hi2);  // RRRR_lo RRRR_hi AAAA_lo AAAA_hi\n      __m128i B = _mm_unpacklo_epi64(BG1, BG2);\n      _mm_store_si128(reinterpret_cast<__m128i *>(dstp[1] + x * sizeof(pixel_t)), B); // B\n      __m128i G = _mm_unpackhi_epi64(BG1, BG2);\n      _mm_store_si128(reinterpret_cast<__m128i *>(dstp[0] + x * sizeof(pixel_t)), G); // G\n      __m128i R = _mm_unpacklo_epi64(RA1, RA2);\n      _mm_store_si128(reinterpret_cast<__m128i *>(dstp[2] + x * sizeof(pixel_t)), R); // R\n      if (targetHasAlpha)\n        _mm_store_si128(reinterpret_cast<__m128i *>(dstp[3] + x * sizeof(pixel_t)), max_pixel_value); // A\n    }\n    // rest, unaligned but simd\n    // RGB24/48 source is 3 bytes/pixel: no power-of-2 stride, 64-byte alignment does not guarantee width is a multiple of 16/8\n    // So we cannot spare the last chunk\n    if (wmod != width) {\n      // width = 17: 0..7 8..15, 16\n      // last_start = 1 (9..16 8 pixels)  width - pixels_at_a_time\n      size_t x = (width - pixels_at_a_time);\n      BGRA_1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(srcp + x * 48 / pixels_at_a_time));\n      BGRA_2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(srcp + x * 48 / pixels_at_a_time + 16));\n      BGRA_3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(srcp + x * 48 / pixels_at_a_time + 32));\n\n      auto pack_lo = _mm_shuffle_epi8(BGRA_1, mask);  // 111111111111: BBBBGGGGRRRR and rest: BGRB | BBGGRR and rest: BBGG\n      BGRA_1 = _mm_alignr_epi8(BGRA_2, BGRA_1, 12);\n      auto pack_hi = _mm_shuffle_epi8(BGRA_1, mask); // 222222222222: BBBBGGGGRRRR | BBGGRR\n      BGRA_2 = _mm_alignr_epi8(BGRA_3, BGRA_2, 8);\n      auto pack_lo2 = _mm_shuffle_epi8(BGRA_2, mask); // 333333333333: BBBBGGGGRRRR | BBGGRR\n      BGRA_3 = _mm_srli_si128(BGRA_3, 4); // to use the same mask\n      auto pack_hi2 = _mm_shuffle_epi8(BGRA_3, mask); // 444444444444: BBBBGGGGRRRR | BBGGRR\n\n      __m128i BG1 = _mm_unpacklo_epi32(pack_lo, pack_hi);  // BBBB_lo BBBB_hi GGGG_lo GGGG_hi\n      __m128i BG2 = _mm_unpacklo_epi32(pack_lo2, pack_hi2);  // BBBB_lo BBBB_hi GGGG_lo GGGG_hi\n      __m128i RA1 = _mm_unpackhi_epi32(pack_lo, pack_hi);   // RRRR_lo RRRR_hi AAAA_lo AAAA_hi\n      __m128i RA2 = _mm_unpackhi_epi32(pack_lo2, pack_hi2);  // RRRR_lo RRRR_hi AAAA_lo AAAA_hi\n      __m128i B = _mm_unpacklo_epi64(BG1, BG2);\n      _mm_storeu_si128(reinterpret_cast<__m128i *>(dstp[1] + x * sizeof(pixel_t)), B); // B\n      __m128i G = _mm_unpackhi_epi64(BG1, BG2);\n      _mm_storeu_si128(reinterpret_cast<__m128i *>(dstp[0] + x * sizeof(pixel_t)), G); // G\n      __m128i R = _mm_unpacklo_epi64(RA1, RA2);\n      _mm_storeu_si128(reinterpret_cast<__m128i *>(dstp[2] + x * sizeof(pixel_t)), R); // R\n      if (targetHasAlpha)\n        _mm_storeu_si128(reinterpret_cast<__m128i *>(dstp[3] + x * sizeof(pixel_t)), max_pixel_value); // A\n    }\n    srcp -= src_pitch; // source packed RGB is upside down\n    dstp[0] += dst_pitch[0];\n    dstp[1] += dst_pitch[1];\n    dstp[2] += dst_pitch[2];\n    if (targetHasAlpha)\n      dstp[3] += dst_pitch[3];\n  }\n}\n\n//instantiate\n//template<typename pixel_t, bool targetHasAlpha>\ntemplate void convert_rgb_to_rgbp_ssse3<uint8_t, false>(const BYTE* srcp, BYTE* (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height);\ntemplate void convert_rgb_to_rgbp_ssse3<uint8_t, true>(const BYTE* srcp, BYTE* (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height);\ntemplate void convert_rgb_to_rgbp_ssse3<uint16_t, false>(const BYTE* srcp, BYTE* (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height);\ntemplate void convert_rgb_to_rgbp_ssse3<uint16_t, true>(const BYTE* srcp, BYTE* (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height);\n\n\n// minimum width: 32 bytes (8 RGBA pixels for 8 bits, 4 RGBA pixels for 16 bits)\n// RGB32/64 -> RGBP(A)8/16 SSE2 implementation. Ugly and not very quick.\ntemplate<typename pixel_t, bool targetHasAlpha>\nvoid convert_rgba_to_rgbp_sse2(const BYTE* srcp, BYTE* (&dstp)[4],\n  int src_pitch, int(&dst_pitch)[4], int width, int height)\n{\n  const int pixels_at_a_time = (sizeof(pixel_t) == 1) ? 8 : 4;\n  __m128i zero = _mm_setzero_si128();\n\n  for (int y = height; y > 0; --y) {\n    // Avisynth's scanline alignment is 64 bytes, so no remainder handling is needed for 8-bit (16 pixels) and 16-bit (8 pixels) formats.\n    for (int x = 0; x < width; x += pixels_at_a_time) {\n      const BYTE* src = srcp + x * 4 * sizeof(pixel_t);\n      __m128i lo = _mm_load_si128(reinterpret_cast<const __m128i*>(src));\n      __m128i hi = _mm_load_si128(reinterpret_cast<const __m128i*>(src + 16));\n      __m128i ch0, ch1;\n\n      if constexpr (sizeof(pixel_t) == 1) {\n        __m128i w0 = _mm_unpacklo_epi8(lo, zero);\n        __m128i w1 = _mm_unpackhi_epi8(lo, zero);\n        __m128i c0 = _mm_unpacklo_epi16(w0, w1);\n        __m128i c1 = _mm_unpackhi_epi16(w0, w1);\n        __m128i lo_bg = _mm_unpacklo_epi16(c0, c1);\n        __m128i lo_ra = _mm_unpackhi_epi16(c0, c1);\n        __m128i w2 = _mm_unpacklo_epi8(hi, zero);\n        __m128i w3 = _mm_unpackhi_epi8(hi, zero);\n        __m128i c2 = _mm_unpacklo_epi16(w2, w3);\n        __m128i c3 = _mm_unpackhi_epi16(w2, w3);\n        __m128i hi_bg = _mm_unpacklo_epi16(c2, c3);\n        __m128i hi_ra = _mm_unpackhi_epi16(c2, c3);\n        ch0 = _mm_shuffle_epi32(_mm_packus_epi16(lo_bg, hi_bg), _MM_SHUFFLE(3, 1, 2, 0));\n        ch1 = _mm_shuffle_epi32(_mm_packus_epi16(lo_ra, hi_ra), _MM_SHUFFLE(3, 1, 2, 0));\n      }\n      else {\n        __m128i t0 = _mm_unpacklo_epi16(lo, hi);\n        __m128i t1 = _mm_unpackhi_epi16(lo, hi);\n        ch0 = _mm_unpacklo_epi16(t0, t1);\n        ch1 = _mm_unpackhi_epi16(t0, t1);\n      }\n      // Stores 8 byte per channel, so we can use storel_epi64. The high 64 bits of ch0/ch1 are ignored.\n      _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp[1] + x * sizeof(pixel_t)), ch0); // B\n      _mm_storeh_pd(reinterpret_cast<double*>(dstp[0] + x * sizeof(pixel_t)),_mm_castsi128_pd(ch0)); // G\n      _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp[2] + x * sizeof(pixel_t)), ch1); // R\n      if constexpr (targetHasAlpha)\n        _mm_storeh_pd(reinterpret_cast<double*>(dstp[3] + x * sizeof(pixel_t)), _mm_castsi128_pd(ch1)); // A\n    }\n\n    srcp -= src_pitch;\n    dstp[0] += dst_pitch[0];\n    dstp[1] += dst_pitch[1];\n    dstp[2] += dst_pitch[2];\n    if constexpr (targetHasAlpha)\n      dstp[3] += dst_pitch[3];\n  }\n}\n\n// Instantiations\ntemplate void convert_rgba_to_rgbp_sse2<uint8_t, false>(const BYTE*, BYTE* (&)[4], int, int(&)[4], int, int);\ntemplate void convert_rgba_to_rgbp_sse2<uint8_t, true>(const BYTE*, BYTE* (&)[4], int, int(&)[4], int, int);\ntemplate void convert_rgba_to_rgbp_sse2<uint16_t, false>(const BYTE*, BYTE* (&)[4], int, int(&)[4], int, int);\ntemplate void convert_rgba_to_rgbp_sse2<uint16_t, true>(const BYTE*, BYTE* (&)[4], int, int(&)[4], int, int);\n\n\ntemplate<typename pixel_t, bool targetHasAlpha>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nvoid convert_rgba_to_rgbp_ssse3(const BYTE* srcp, BYTE* (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height)\n{\n  const int pixels_at_a_time = (sizeof(pixel_t) == 1) ? 8 : 4;\n\n  __m128i mask;\n  if constexpr (sizeof(pixel_t) == 1)\n    mask = _mm_set_epi8(15, 11, 7, 3, 14, 10, 6, 2, 13, 9, 5, 1, 12, 8, 4, 0);\n  else\n    mask = _mm_set_epi8(15, 14, 7, 6, 13, 12, 5, 4, 11, 10, 3, 2, 9, 8, 1, 0);\n\n  for (int y = height; y > 0; --y) {\n    // Avisynth's scanline alignment is 64 bytes, so no remainder handling is needed for 8 RGB32 or 4 RGB64 pixels\n    for (int x = 0; x < width; x += pixels_at_a_time) {\n      __m128i BGRA_lo = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x * 4 * sizeof(pixel_t)));\n      __m128i BGRA_hi = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x * 4 * sizeof(pixel_t) + 16));\n      __m128i pack_lo = _mm_shuffle_epi8(BGRA_lo, mask);\n      __m128i pack_hi = _mm_shuffle_epi8(BGRA_hi, mask);\n      __m128i eightbytes_of_pixels = _mm_unpacklo_epi32(pack_lo, pack_hi);\n      _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp[1] + x * sizeof(pixel_t)), eightbytes_of_pixels); // B\n      _mm_storeh_pd(reinterpret_cast<double*>(dstp[0] + x * sizeof(pixel_t)), _mm_castsi128_pd(eightbytes_of_pixels)); // G\n      eightbytes_of_pixels = _mm_unpackhi_epi32(pack_lo, pack_hi);\n      _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp[2] + x * sizeof(pixel_t)), eightbytes_of_pixels); // R\n      if constexpr (targetHasAlpha)\n        _mm_storeh_pd(reinterpret_cast<double*>(dstp[3] + x * sizeof(pixel_t)), _mm_castsi128_pd(eightbytes_of_pixels)); // A\n    }\n    srcp -= src_pitch;\n    dstp[0] += dst_pitch[0];\n    dstp[1] += dst_pitch[1];\n    dstp[2] += dst_pitch[2];\n    if constexpr (targetHasAlpha)\n      dstp[3] += dst_pitch[3];\n  }\n}\n\n//instantiate\n//template<typename pixel_t, bool targetHasAlpha>\ntemplate void convert_rgba_to_rgbp_ssse3<uint8_t, false>(const BYTE* srcp, BYTE* (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height);\ntemplate void convert_rgba_to_rgbp_ssse3<uint8_t, true>(const BYTE* srcp, BYTE* (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height);\ntemplate void convert_rgba_to_rgbp_ssse3<uint16_t, false>(const BYTE* srcp, BYTE* (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height);\ntemplate void convert_rgba_to_rgbp_ssse3<uint16_t, true>(const BYTE* srcp, BYTE* (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height);\n\ntemplate<typename pixel_t, bool hasSrcAlpha>\nvoid convert_rgbp_to_rgba_sse2(const BYTE* (&srcp)[4], BYTE* dstp, int(&src_pitch)[4], int dst_pitch, int width, int height)\n{\n  const int pixels_at_a_time = 8 / sizeof(pixel_t); // 8x uint8_t, 4x uint16_t\n  const __m128i transparent = _mm_set1_epi8((char)0xFF);\n  // Avisynth's scanline alignment is 64 bytes, so no remainder handling is needed for 8 RGB32 or 4 RGB64 pixels\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < width; x += pixels_at_a_time) {\n      __m128i R, G, B, A;\n      G = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp[0] + x * sizeof(pixel_t)));\n      B = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp[1] + x * sizeof(pixel_t)));\n      R = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp[2] + x * sizeof(pixel_t)));\n      if constexpr (hasSrcAlpha)\n        A = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp[3] + x * sizeof(pixel_t)));\n      else\n        A = transparent;\n\n      if constexpr (sizeof(pixel_t) == 1) {\n        __m128i BG = _mm_unpacklo_epi8(B, G);\n        __m128i RA = _mm_unpacklo_epi8(R, A);\n        _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x * 4), _mm_unpacklo_epi16(BG, RA)); // pixels 0..3\n        _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x * 4 + 16), _mm_unpackhi_epi16(BG, RA)); // pixels 4..7\n      }\n      else {\n        __m128i BG = _mm_unpacklo_epi16(B, G);\n        __m128i RA = _mm_unpacklo_epi16(R, A);\n        _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x * 8), _mm_unpacklo_epi32(BG, RA)); // pixels 0..1\n        _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x * 8 + 16), _mm_unpackhi_epi32(BG, RA)); // pixels 2..3\n      }\n    }\n    dstp -= dst_pitch;\n    srcp[0] += src_pitch[0];\n    srcp[1] += src_pitch[1];\n    srcp[2] += src_pitch[2];\n    if constexpr (hasSrcAlpha)\n      srcp[3] += src_pitch[3];\n  }\n}\n\n//instantiate\n//template<typename pixel_t, bool hasSrcAlpha>\ntemplate void convert_rgbp_to_rgba_sse2<uint8_t, false>(const BYTE* (&srcp)[4], BYTE* dstp, int(&src_pitch)[4], int dst_pitch, int width, int height);\ntemplate void convert_rgbp_to_rgba_sse2<uint8_t, true>(const BYTE* (&srcp)[4], BYTE* dstp, int(&src_pitch)[4], int dst_pitch, int width, int height);\ntemplate void convert_rgbp_to_rgba_sse2<uint16_t, false>(const BYTE* (&srcp)[4], BYTE* dstp, int(&src_pitch)[4], int dst_pitch, int width, int height);\ntemplate void convert_rgbp_to_rgba_sse2<uint16_t, true>(const BYTE* (&srcp)[4], BYTE* dstp, int(&src_pitch)[4], int dst_pitch, int width, int height);\n\n\n"
  },
  {
    "path": "avs_core/convert/intel/convert_rgb_sse.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Convert_RGB_sse_H__\n#define __Convert_RGB_sse_H__\n\n#include <avs/types.h>\n\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nvoid convert_rgb48_to_rgb64_ssse3(const BYTE *srcp, BYTE *dstp, size_t src_pitch, size_t dst_pitch, size_t width, size_t height);\n\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nvoid convert_rgb24_to_rgb32_ssse3(const BYTE *srcp, BYTE *dstp, size_t src_pitch, size_t dst_pitch, size_t width, size_t height);\n\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nvoid convert_rgb64_to_rgb48_ssse3(const BYTE *srcp, BYTE *dstp, size_t src_pitch, size_t dst_pitch, size_t width, size_t height);\n\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nvoid convert_rgb32_to_rgb24_ssse3(const BYTE *srcp, BYTE *dstp, size_t src_pitch, size_t dst_pitch, size_t width, size_t height);\n\nvoid convert_rgb32_to_rgb24_sse2(const BYTE *srcp, BYTE *dstp, size_t src_pitch, size_t dst_pitch, size_t width, size_t height);\n\ntemplate<typename pixel_t, bool targetHasAlpha>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nvoid convert_rgb_to_rgbp_ssse3(const BYTE *srcp, BYTE * (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height);\n\ntemplate<typename pixel_t, bool targetHasAlpha>\nvoid convert_rgb_to_rgbp_sse2(const BYTE* srcp, BYTE* (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height);\n\ntemplate<typename pixel_t, bool targetHasAlpha>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nvoid convert_rgba_to_rgbp_ssse3(const BYTE *srcp, BYTE * (&dstp)[4], int src_pitch, int (&dst_pitch)[4], int width, int height);\n\ntemplate<typename pixel_t, bool targetHasAlpha>\nvoid convert_rgba_to_rgbp_sse2(const BYTE* srcp, BYTE* (&dstp)[4], int src_pitch, int(&dst_pitch)[4], int width, int height);\n\ntemplate<typename pixel_t, bool hasSrcAlpha>\nvoid convert_rgbp_to_rgba_sse2(const BYTE *(&srcp)[4], BYTE * dstp, int (&src_pitch)[4], int dst_pitch, int width, int height);\n\n#endif  // __Convert_RGB_sse_H__\n"
  },
  {
    "path": "avs_core/core/AVSMap.h",
    "content": "#pragma once\n/*\nThis program is free software; you can redistribute it and /or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with this program; if not, write to the Free Software\nFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\nHelper structures for frame properties a.k.a VSMap.\nBased on VapourSynth API4, copyright (c) Fredrik Mellbin\n\n*/\n#include <map>\n#include <mutex>\n#include <string>\n#include \"avisynth.h\"\n#include <atomic>\n#include <vector>\n#include <memory>\n#include <cassert>\n\n// VS node ~ Avisynth clip, VSMap-AVSMap\n// See also in Avisynth.cpp\n\n// INTRUSIVE_PTR_H \n\n#include <algorithm>\n\ntemplate<typename T>\nclass vs_intrusive_ptr {\nprivate:\n  T* obj;\npublic:\n  vs_intrusive_ptr(T* ptr = nullptr, bool add_ref = false) noexcept {\n    obj = ptr;\n    if (add_ref && obj)\n      obj->add_ref();\n  }\n\n  vs_intrusive_ptr(const vs_intrusive_ptr& ptr) noexcept {\n    obj = ptr.obj;\n    if (obj)\n      obj->add_ref();\n  }\n\n  vs_intrusive_ptr(vs_intrusive_ptr&& ptr) noexcept {\n    obj = ptr.obj;\n    ptr.obj = nullptr;\n  }\n\n  ~vs_intrusive_ptr() noexcept {\n    if (obj)\n      obj->release();\n  }\n\n  vs_intrusive_ptr& operator=(vs_intrusive_ptr const& ptr) noexcept {\n    if (obj)\n      obj->release();\n    obj = ptr.obj;\n    if (obj)\n      obj->add_ref();\n    return *this;\n  }\n\n  T* operator->() const noexcept {\n    return obj;\n  }\n\n  T& operator*() const noexcept {\n    return *obj;\n  }\n\n  operator bool() const noexcept {\n    return !!obj;\n  }\n\n  T* get() const noexcept {\n    return obj;\n  }\n\n  void reset() noexcept {\n    if (obj) {\n      obj->release();\n      obj = nullptr;\n    }\n  }\n\n  void swap(vs_intrusive_ptr& ptr) noexcept {\n    std::swap(obj, ptr.obj);\n  }\n};\n\n#define AVS_NOEXCEPT noexcept\n\n// enums for frame property functions\n\n// VS: typedef enum VSPropertyType\ntypedef enum AVSPropertyType {\n  PROPERTYTYPE_UNSET = 0, // ptUnset = 0,\n  PROPERTYTYPE_INT = 1, // ptInt = 1,\n  PROPERTYTYPE_FLOAT = 2, //  ptFloat = 2,\n  PROPERTYTYPE_DATA = 3, // ptData = 3,\n  //  ptFunction = 4, // Avisynth: functions not supported here\n  PROPERTYTYPE_CLIP = 5, // ptVideoNode = 5,\n  //  ptAudioNode = 6, // Avisynth: no special audio clip\n  PROPERTYTYPE_FRAME = 7, //  ptVideoFrame = 7,\n  //  ptAudioFrame = 8 // Avisynth: no special audio frame\n} AVSPropertyType;\n\nclass VSArrayBase {\nprotected:\n  std::atomic<long> refcount;\n  AVSPropertyType ftype;\n  size_t fsize = 0;\n  explicit VSArrayBase(AVSPropertyType type) : refcount(1), ftype(type) {}\n  virtual ~VSArrayBase() {}\npublic:\n  AVSPropertyType type() const {\n    return ftype;\n  }\n\n  size_t size() const {\n    return fsize;\n  }\n\n  bool unique() const noexcept {\n    return (refcount == 1);\n  }\n\n  void add_ref() noexcept {\n    ++refcount;\n  }\n\n  void release() noexcept {\n    assert(refcount > 0);\n    if (--refcount == 0)\n      delete this;\n  }\n\n  virtual VSArrayBase* copy() const noexcept = 0;\n};\n\ntypedef vs_intrusive_ptr<VSArrayBase> PVSArrayBase;\n\ntemplate<typename T, AVSPropertyType propType>\nclass VSArray final : public VSArrayBase {\nprivate:\n  T singleData = {};\n  std::vector<T> data;\npublic:\n  explicit VSArray() noexcept : VSArrayBase(propType) {}\n\n  explicit VSArray(const VSArray& other) noexcept : VSArrayBase(other.ftype) {\n    fsize = other.fsize;\n    if (fsize == 1)\n      singleData = other.singleData;\n    else if (fsize > 1)\n      data = other.data;\n  }\n\n  explicit VSArray(const T* val, size_t count) noexcept : VSArrayBase(propType) { // only enable for POD types\n    fsize = count;\n    if (count == 1) {\n      singleData = *val;\n    }\n    else {\n      data.resize(count);\n      memcpy(data.data(), val, sizeof(T) * count);\n    }\n  }\n\n  virtual VSArrayBase* copy() const noexcept {\n    return new VSArray(*this);\n  }\n\n  const T* getDataPointer() const noexcept { // only enable for POD types\n    if (fsize == 1)\n      return &singleData;\n    else\n      return data.data();\n  }\n\n  void push_back(const T& val) noexcept {\n    if (fsize == 0) {\n      singleData = val;\n    }\n    else if (fsize == 1) {\n      data.reserve(8);\n      data.push_back(std::move(singleData));\n      data.push_back(val);\n    }\n    else {\n      if (data.capacity() == data.size())\n        data.reserve(data.capacity() * 2);\n      data.push_back(val);\n    }\n    fsize++;\n  }\n\n  const T& at(size_t pos) const noexcept {\n    assert(pos < fsize);\n    if (fsize == 1)\n      return singleData;\n    else\n      return data.at(pos);\n  }\n};\n\n// variant types\nclass VSMapData {\npublic:\n  AVSPropDataTypeHint typeHint;\n  std::string data;\n};\n\ntypedef VSArray<int64_t, AVSPropertyType::PROPERTYTYPE_INT> VSIntArray; // ptInt\ntypedef VSArray<double, AVSPropertyType::PROPERTYTYPE_FLOAT> VSFloatArray; // ptFloat\ntypedef VSArray<VSMapData, AVSPropertyType::PROPERTYTYPE_DATA> VSDataArray; // ptData\ntypedef VSArray<PClip, AVSPropertyType::PROPERTYTYPE_CLIP> VSVideoNodeArray; // ptVideoNode\ntypedef VSArray<PVideoFrame, AVSPropertyType::PROPERTYTYPE_FRAME> VSVideoFrameArray; // ptVideoFrame\n//typedef VSArray<PFunction, ptFunction> VSFunctionArray;\n\n\ntypedef std::vector<int64_t> IntList;\ntypedef std::vector<double> FloatList;\ntypedef std::vector<VSMapData> DataList;\ntypedef std::vector<PClip> ClipList;\ntypedef std::vector<PVideoFrame> FrameList;\n//typedef std::vector<PFunction> FuncList;\n\n\nclass VSMapStorage {\nprivate:\n  std::atomic<long> refcount;\npublic:\n  std::map<std::string, PVSArrayBase> data;\n  bool error;\n\n  explicit VSMapStorage() : refcount(1), error(false) {}\n\n  explicit VSMapStorage(const VSMapStorage& s) : refcount(1), data(s.data), error(s.error) {\n  }\n\n  void clear() noexcept {\n    data.clear();\n    error = false;\n  }\n\n  bool unique() noexcept {\n    return (refcount == 1);\n  };\n\n  void add_ref() noexcept {\n    ++refcount;\n  }\n\n  void release() noexcept {\n    assert(refcount > 0);\n    if (--refcount == 0)\n      delete this;\n  }\n};\n\ntypedef vs_intrusive_ptr<VSMapStorage> PVSMapStorage;\n\n// This one is referenced in avisynth.h.\n// For avoiding dual plugin name collisions, renamed VSMap->AVSMap\nstruct AVSMap {\nprivate:\n  PVSMapStorage data;\npublic:\n  AVSMap(const AVSMap* map = nullptr) : data(map ? map->data : new VSMapStorage()) {\n  }\n\n  AVSMap& operator=(const AVSMap& map) {\n    data = map.data;\n    return *this;\n  }\n\n  bool detach() {\n    if (!data->unique()) {\n      data = new VSMapStorage(*data);\n      return true;\n    }\n    return false;\n  }\n\n  VSArrayBase* find(const std::string& key) const {\n    auto it = data->data.find(key);\n    return (it == data->data.end()) ? nullptr : it->second.get();\n  }\n\n  VSArrayBase* detach(const std::string& key) {\n    detach();\n    auto it = data->data.find(key);\n    if (it != data->data.end()) {\n      if (!it->second->unique())\n        it->second = it->second->copy();\n      return it->second.get();\n    }\n    return nullptr;\n  }\n\n  bool erase(const std::string& key) {\n    auto it = data->data.find(key);\n    if (it != data->data.end()) {\n      if (detach())\n        it = data->data.find(key);\n      data->data.erase(it);\n      return true;\n    }\n    return false;\n  }\n\n  void insert(const std::string& key, VSArrayBase* val) {\n    detach();\n    auto it = data->data.find(key);\n    if (it != data->data.end()) {\n      it->second = val;\n    }\n    else {\n      data->data.insert(std::make_pair(key, val));\n    }\n  }\n\n  void copy(const AVSMap* src) {\n    if (src == this)\n      return;\n\n    detach();\n    for (auto& iter : src->data->data)\n      data->data[iter.first] = iter.second;\n  }\n\n  size_t size() const {\n    return data->data.size();\n  }\n\n  void clear() {\n    if (data->unique())\n      data->clear();\n    else\n      data = new VSMapStorage();\n  }\n\n  const char* key(size_t n) const {\n    if (n >= size())\n      return nullptr;\n    auto iter = data->data.cbegin();\n    std::advance(iter, n);\n    return iter->first.c_str();\n  }\n\n  void setError(const std::string& errMsg) {\n    clear();\n    VSDataArray* arr = new VSDataArray();\n    arr->push_back({ AVSPropDataTypeHint::PROPDATATYPEHINT_UTF8, errMsg }); // dtUtf8\n    data->data.insert(std::make_pair(\"_Error\", arr));\n    data->error = true;\n  }\n\n  bool hasError() const {\n    return data->error;\n  }\n\n  const char* getErrorMessage() const {\n    if (data->error) {\n      return reinterpret_cast<VSDataArray*>(data->data.at(\"_Error\").get())->at(0).data.c_str();\n    }\n    else {\n      return nullptr;\n    }\n  }\n\n  //bool isV3Compatible() const noexcept; // VS special\n};\n"
  },
  {
    "path": "avs_core/core/AviHelper.cpp",
    "content": "// Avisynth v2.5.  Copyright 2007 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include <avisynth.h>\n#include \"internal.h\"\n#ifdef INTEL_INTRINSICS\n// Intrinsics base header + really required extension headers\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n#include <smmintrin.h> // SSE4.1\n#endif\n\nint AviHelper_ImageSize(const VideoInfo *vi, bool AVIPadScanlines, bool v210, bool v410, bool r210, bool R10k, bool v308, bool v408, bool Y410) {\n  int image_size;\n  if (vi->pixel_type == VideoInfo::CS_YUV444P16 || vi->pixel_type == VideoInfo::CS_YUVA444P16)\n  { // Y416 packed 4444 U,Y,V,A\n    image_size = vi->width * vi->height * 4 * sizeof(uint16_t);\n  }\n  else if (vi->pixel_type == VideoInfo::CS_RGBP10 && r210)\n  { // 3x10bit packed RGB, 64 aligned\n    image_size = ((vi->width + 63) / 64) * 256 * vi->height; // 4 byte/pixel: 32bits for 3x10 bits\n  }\n  else if (vi->pixel_type == VideoInfo::CS_RGBP10 && R10k)\n  { // 3x10bit packed RGB, no aligment\n    image_size = vi->width * 4 * vi->height; // 4 byte/pixel: 32bits for 3x10 bits\n  }\n  else if (vi->pixel_type == VideoInfo::CS_YV24 && v308)\n  { // v308 packed 444\n    image_size = vi->width * vi->height * 3 * sizeof(uint8_t);\n  }\n  else if (vi->pixel_type == VideoInfo::CS_YUVA444 && v408)\n  { // v408 packed 4444\n    image_size = vi->width * vi->height * 4 * sizeof(uint8_t);\n  }\n  else if (vi->pixel_type == VideoInfo::CS_YUV444P10 && v410)\n  { // v410 packed 444 U,Y,V\n    image_size = vi->width * vi->height * 4; // 4 byte/pixel: 32bits for 3x10 bits\n  }\n  else if ((vi->pixel_type == VideoInfo::CS_YUV444P10 || vi->pixel_type == VideoInfo::CS_YUVA444P10) && Y410)\n  { // Y410 packed 10 bit 444 U,Y,V,A (Alpha is 2 bits)\n    image_size = vi->width * vi->height * 4; // 4 byte/pixel: 32bits for 3x10+2 bits\n  }\n  else if (vi->pixel_type == VideoInfo::CS_YUV422P10 && v210)\n  {\n    image_size = ((16 * ((vi->width + 5) / 6) + 127) & ~127);\n    image_size *= vi->height;\n  }\n  else if ((vi->IsRGB() && !vi->IsPlanar()) || vi->IsYUY2() || vi->IsY() || AVIPadScanlines) {\n    // incl. all packed RGBs\n    image_size = vi->BMPSize();\n  }\n  else { // Packed size\n    if (vi->IsPlanar() && vi->IsRGB()) {\n      image_size = (vi->RowSize(PLANAR_G) * vi->height);\n      if (vi->IsPlanarRGBA()) // not supported yet, but for the sake of completeness\n        image_size *= 4;\n      else\n        image_size *= 3;\n    }\n    else {\n      image_size = vi->RowSize(PLANAR_U);\n      if (image_size) {\n        image_size *= vi->height;\n        image_size >>= vi->GetPlaneHeightSubsampling(PLANAR_U);\n        image_size *= 2;\n      }\n      image_size += vi->RowSize(PLANAR_Y) * vi->height;\n    }\n  }\n  return image_size;\n}\n\n#ifdef INTEL_INTRINSICS\ntemplate<bool hasAlpha>\nvoid ToY416_sse2(uint8_t *outbuf, int out_pitch, const uint8_t *yptr, int ypitch, const uint8_t *uptr, const uint8_t *vptr, int uvpitch, const uint8_t *aptr, int apitch, int width, int height)\n{\n  // out_pitch may not be mod16\n  const int wmod4 = (width / 4) * 4;\n\n  // UYVA\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wmod4; x += 4) {\n      // read 4x4 pixels, store 2x(4x2) pixels\n      auto u = _mm_loadl_epi64(reinterpret_cast<const __m128i *>(uptr + x * sizeof(uint16_t)));\n      auto y = _mm_loadl_epi64(reinterpret_cast<const __m128i *>(yptr + x * sizeof(uint16_t)));\n      auto v = _mm_loadl_epi64(reinterpret_cast<const __m128i *>(vptr + x * sizeof(uint16_t)));\n      __m128i a;\n      if (hasAlpha)\n        a = _mm_loadl_epi64(reinterpret_cast<const __m128i *>(aptr + x * sizeof(uint16_t)));\n      else\n        a = _mm_set1_epi16(-1); // transparent alpha 0xFFFF\n      auto uy = _mm_unpacklo_epi16(u, y);\n      auto va = _mm_unpacklo_epi16(v, a);\n      auto uyva_lo = _mm_unpacklo_epi32(uy, va);\n      _mm_storeu_si128(reinterpret_cast<__m128i *>(outbuf + 4 * sizeof(uint16_t) * x), uyva_lo);\n      auto uyva_hi = _mm_unpackhi_epi32(uy, va);\n      _mm_storeu_si128(reinterpret_cast<__m128i *>(outbuf + 16 + 4 * sizeof(uint16_t) * x), uyva_hi);\n    }\n\n    for (int x = wmod4; x < width; x++) {\n      reinterpret_cast<uint16_t *>(outbuf)[x * 4 + 0] = reinterpret_cast<const uint16_t *>(uptr)[x];\n      reinterpret_cast<uint16_t *>(outbuf)[x * 4 + 1] = reinterpret_cast<const uint16_t *>(yptr)[x];\n      reinterpret_cast<uint16_t *>(outbuf)[x * 4 + 2] = reinterpret_cast<const uint16_t *>(vptr)[x];\n      reinterpret_cast<uint16_t *>(outbuf)[x * 4 + 3] = hasAlpha ? reinterpret_cast<const uint16_t *>(aptr)[x] : 0xFFFF;\n    }\n    outbuf += out_pitch;\n    yptr += ypitch;\n    uptr += uvpitch;\n    vptr += uvpitch;\n    aptr += apitch;\n  }\n}\n\n// instantiate\ntemplate void ToY416_sse2<false>(uint8_t *outbuf, int out_pitch, const uint8_t *yptr, int ypitch, const uint8_t *uptr, const uint8_t *vptr, int uvpitch, const uint8_t *aptr, int apitch, int width, int height);\ntemplate void ToY416_sse2<true>(uint8_t *outbuf, int out_pitch, const uint8_t *yptr, int ypitch, const uint8_t *uptr, const uint8_t *vptr, int uvpitch, const uint8_t *aptr, int apitch, int width, int height);\n#endif\n\ntemplate<bool hasAlpha>\nvoid ToY416_c(uint8_t *outbuf8, int out_pitch, const uint8_t *yptr, int ypitch, const uint8_t *uptr, const uint8_t *vptr, int uvpitch, const uint8_t *aptr, int apitch, int width, int height)\n{\n  uint16_t *outbuf = reinterpret_cast<uint16_t *>(outbuf8);\n  out_pitch /= sizeof(uint16_t);\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < width; x++) {\n      outbuf[x * 4 + 0] = reinterpret_cast<const uint16_t *>(uptr)[x];\n      outbuf[x * 4 + 1] = reinterpret_cast<const uint16_t *>(yptr)[x];\n      outbuf[x * 4 + 2] = reinterpret_cast<const uint16_t *>(vptr)[x];\n      outbuf[x * 4 + 3] = hasAlpha ? reinterpret_cast<const uint16_t *>(aptr)[x] : 0xFFFF;\n    }\n    outbuf += out_pitch;\n    yptr += ypitch;\n    uptr += uvpitch;\n    vptr += uvpitch;\n    aptr += apitch;\n  }\n}\n// instantiate\ntemplate void ToY416_c<false>(uint8_t *outbuf, int out_pitch, const uint8_t *yptr, int ypitch, const uint8_t *uptr, const uint8_t *vptr, int uvpitch, const uint8_t *aptr, int apitch, int width, int height);\ntemplate void ToY416_c<true>(uint8_t *outbuf, int out_pitch, const uint8_t *yptr, int ypitch, const uint8_t *uptr, const uint8_t *vptr, int uvpitch, const uint8_t *aptr, int apitch, int width, int height);\n\ntemplate<bool hasAlpha>\nvoid FromY416_c(uint8_t *yptr, int ypitch, uint8_t *uptr, uint8_t *vptr, int uvpitch, uint8_t *aptr, int apitch,\n  const uint8_t *srcp8, int srcpitch,\n  int width, int height)\n{\n  const uint16_t *srcp = reinterpret_cast<const uint16_t *>(srcp8);\n  srcpitch /= sizeof(uint16_t);\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < width; x++) {\n      reinterpret_cast<uint16_t *>(uptr)[x] = srcp[x * 4 + 0];\n      reinterpret_cast<uint16_t *>(yptr)[x] = srcp[x * 4 + 1];\n      reinterpret_cast<uint16_t *>(vptr)[x] = srcp[x * 4 + 2];\n      if(hasAlpha)\n        reinterpret_cast<uint16_t *>(aptr)[x] = srcp[x * 4 + 3];\n    }\n    srcp += srcpitch;\n    yptr += ypitch;\n    uptr += uvpitch;\n    vptr += uvpitch;\n    aptr += apitch;\n  }\n}\n// instantiate\ntemplate void FromY416_c<false>(uint8_t *yptr, int ypitch, uint8_t *uptr, uint8_t *vptr, int uvpitch, uint8_t *aptr, int apitch, const uint8_t *srcp8, int srcpitch, int width, int height);\ntemplate void FromY416_c<true>(uint8_t *yptr, int ypitch, uint8_t *uptr, uint8_t *vptr, int uvpitch, uint8_t *aptr, int apitch, const uint8_t *srcp8, int srcpitch, int width, int height);\n\ntemplate<bool hasAlpha>\nvoid ToY410_c(uint8_t* outbuf8, int out_pitch, const uint8_t* yptr, int ypitch, const uint8_t* uptr, const uint8_t* vptr, int uvpitch, const uint8_t* aptr, int apitch, int width, int height)\n{\n  uint32_t* outbuf = reinterpret_cast<uint32_t*>(outbuf8);\n  out_pitch /= sizeof(uint32_t);\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < width; x++) {\n      uint32_t uyva =\n        reinterpret_cast<const uint16_t*>(uptr)[x] +\n        (reinterpret_cast<const uint16_t*>(yptr)[x] << 10) +\n        (reinterpret_cast<const uint16_t*>(vptr)[x] << 20);\n      if constexpr(hasAlpha)\n        uyva += (reinterpret_cast<const uint16_t*>(aptr)[x] >> 8) << 30; // 2 bits only\n      else\n        uyva += 0x03 << 30; // 2 bits only\n      outbuf[x] = uyva;\n    }\n    outbuf += out_pitch;\n    yptr += ypitch;\n    uptr += uvpitch;\n    vptr += uvpitch;\n    aptr += apitch;\n  }\n}\n// instantiate\ntemplate void ToY410_c<false>(uint8_t* outbuf, int out_pitch, const uint8_t* yptr, int ypitch, const uint8_t* uptr, const uint8_t* vptr, int uvpitch, const uint8_t* aptr, int apitch, int width, int height);\ntemplate void ToY410_c<true>(uint8_t* outbuf, int out_pitch, const uint8_t* yptr, int ypitch, const uint8_t* uptr, const uint8_t* vptr, int uvpitch, const uint8_t* aptr, int apitch, int width, int height);\n\ntemplate<bool hasAlpha>\nvoid FromY410_c(uint8_t* yptr, int ypitch, uint8_t* uptr, uint8_t* vptr, int uvpitch, uint8_t* aptr, int apitch,\n  const uint8_t* srcp8, int srcpitch,\n  int width, int height)\n{\n  const uint32_t* srcp = reinterpret_cast<const uint32_t*>(srcp8);\n  srcpitch /= sizeof(uint32_t);\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < width; x++) {\n      const uint32_t uyva = srcp[x];\n      reinterpret_cast<uint16_t*>(uptr)[x] = (uyva >> 0) & 0x3FF;\n      reinterpret_cast<uint16_t*>(yptr)[x] = (uyva >> 10) & 0x3FF;\n      reinterpret_cast<uint16_t*>(vptr)[x] = (uyva >> 20) & 0x3FF;\n      if constexpr(hasAlpha) {\n        const int alpha = (uyva >> 30) & 0x3;\n        // keep 03 as 3FF full transparent\n        reinterpret_cast<uint16_t*>(aptr)[x] = alpha == 3 ? 0x3FF : alpha << 8;\n      }\n    }\n    srcp += srcpitch;\n    yptr += ypitch;\n    uptr += uvpitch;\n    vptr += uvpitch;\n    aptr += apitch;\n  }\n}\n// instantiate\ntemplate void FromY410_c<false>(uint8_t* yptr, int ypitch, uint8_t* uptr, uint8_t* vptr, int uvpitch, uint8_t* aptr, int apitch, const uint8_t* srcp8, int srcpitch, int width, int height);\ntemplate void FromY410_c<true>(uint8_t* yptr, int ypitch, uint8_t* uptr, uint8_t* vptr, int uvpitch, uint8_t* aptr, int apitch, const uint8_t* srcp8, int srcpitch, int width, int height);\n\n// Helpers for 10 bit RGB -> Planar RGB\n\nstatic AVS_FORCEINLINE uint32_t avs_swap32(uint32_t x) {\n  x = (x & 0x0000FFFFu) << 16 | (x & 0xFFFF0000u) >> 16;\n  x = (x & 0x00FF00FFu) << 8 | (x & 0xFF00FF00u) >> 8;\n  return x;\n}\n\nvoid From_r210_c(uint8_t *rptr, uint8_t *gptr, uint8_t *bptr, int pitch, uint8_t *srcp8, int srcpitch, int width, int height)\n{\n  // XXrrrrrr rrrrgggg ggggggbb bbbbbbbb\n  // BigEndian\n  const uint32_t *srcp = reinterpret_cast<const uint32_t *>(srcp8);\n  srcpitch /= sizeof(uint32_t);\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < width; x++) {\n      const uint32_t rgb = avs_swap32(srcp[x]);\n      reinterpret_cast<uint16_t *>(bptr)[x] = (rgb >> 0) & 0x3FF;\n      reinterpret_cast<uint16_t *>(gptr)[x] = (rgb >> 10) & 0x3FF;\n      reinterpret_cast<uint16_t *>(rptr)[x] = (rgb >> 20) & 0x3FF;\n    }\n    srcp += srcpitch;\n    gptr += pitch;\n    rptr += pitch;\n    bptr += pitch;\n  }\n}\n\nvoid From_R10k_c(uint8_t *rptr, uint8_t *gptr, uint8_t *bptr, int pitch, uint8_t *srcp8, int srcpitch, int width, int height)\n{\n  // rrrrrrrr rrgggggg ggggbbbb bbbbbbxx\n  // BigEndian\n  const uint32_t *srcp = reinterpret_cast<const uint32_t *>(srcp8);\n  srcpitch /= sizeof(uint32_t);\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < width; x++) {\n      const uint32_t rgb = avs_swap32(srcp[x]);\n      reinterpret_cast<uint16_t *>(bptr)[x] = (rgb >> 2) & 0x3FF;\n      reinterpret_cast<uint16_t *>(gptr)[x] = (rgb >> 12) & 0x3FF;\n      reinterpret_cast<uint16_t *>(rptr)[x] = (rgb >> 22) & 0x3FF;\n    }\n    srcp += srcpitch;\n    gptr += pitch;\n    rptr += pitch;\n    bptr += pitch;\n  }\n}\n\n// Helpers for b64a <-> RGB64\n\nstatic AVS_FORCEINLINE uint64_t avs_swap64(uint64_t x) {\n  x = (x & 0x00000000FFFFFFFFULL) << 32 | (x & 0xFFFFFFFF00000000ULL) >> 32;\n  x = (x & 0x0000FFFF0000FFFFULL) << 16 | (x & 0xFFFF0000FFFF0000ULL) >> 16;\n  x = (x & 0x00FF00FF00FF00FFULL) << 8 | (x & 0xFF00FF00FF00FF00ULL) >> 8;\n  return x;\n}\n\n#ifdef INTEL_INTRINSICS\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nstatic AVS_FORCEINLINE __m128i _mm_bswap_epi64_ssse3(__m128i x)\n{\n  // Reverse order of bytes in each 64-bit word.\n  return _mm_shuffle_epi8(x, _mm_set_epi8(8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7));\n}\n\nstatic AVS_FORCEINLINE __m128i _mm_bswap_epi64_sse2(__m128i x)\n{\n  // Reverse order of bytes in each 64-bit word.\n  // Swap bytes in each 16-bit word:\n  __m128i a = _mm_or_si128(\n    _mm_slli_epi16(x, 8),\n    _mm_srli_epi16(x, 8));\n\n  // Reverse all 16-bit words in 64-bit halves:\n  a = _mm_shufflelo_epi16(a, _MM_SHUFFLE(0, 1, 2, 3));\n  a = _mm_shufflehi_epi16(a, _MM_SHUFFLE(0, 1, 2, 3));\n\n  return a;\n}\n#endif // INTEL_INTRINSICS\n\nstatic AVS_FORCEINLINE uint16_t avs_swap16(uint16_t x) {\n  return (x & 0x00FF) << 8 | (x & 0xFF00) >> 8;\n}\n\n// 3x1\nvoid bgr_to_rgbBE_c(uint8_t* pdst, int dstpitch, const uint8_t *src, int srcpitch, int width, int height)\n{\n  // todo sse2\n  // R G B R G B R G\n  // B R G B R G B R\n  // G B R G B R G B\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < width; x++) {\n      uint16_t r = avs_swap16(reinterpret_cast<const uint16_t *>(src)[x * 3 + 0]);\n      uint16_t g = avs_swap16(reinterpret_cast<const uint16_t *>(src)[x * 3 + 1]);\n      uint16_t b = avs_swap16(reinterpret_cast<const uint16_t *>(src)[x * 3 + 2]);\n      reinterpret_cast<uint16_t*>(pdst)[x * 3 + 0] = b;\n      reinterpret_cast<uint16_t*>(pdst)[x * 3 + 1] = g;\n      reinterpret_cast<uint16_t*>(pdst)[x * 3 + 2] = r;\n    }\n    src += srcpitch;\n    pdst += dstpitch;\n  }\n}\n\n#ifdef INTEL_INTRINSICS\n// 4x16: two-way symmetric\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nvoid bgra_to_argbBE_ssse3(uint8_t* pdst, int dstpitch, const uint8_t *src, int srcpitch, int width, int height)\n{\n  // srcpitch or dstpitch may not be mod16\n  const int wmod2 = (width / 2) * 2; // 2x64bit\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wmod2; x += 2) {\n      __m128i a = _mm_loadu_si128(reinterpret_cast<const __m128i *>(src + 8 * x));\n      a = _mm_bswap_epi64_ssse3(a);\n      _mm_storeu_si128(reinterpret_cast<__m128i *>(pdst + 8 * x), a);\n    }\n    if (wmod2 < width) {\n      __m128i a = _mm_loadl_epi64(reinterpret_cast<const __m128i *>(src + 8 * wmod2));\n      a = _mm_bswap_epi64_ssse3(a);\n      _mm_storel_epi64(reinterpret_cast<__m128i *>(pdst + 8 * wmod2), a);\n    }\n    src += srcpitch;\n    pdst += dstpitch;\n  }\n}\n\nvoid bgra_to_argbBE_sse2(uint8_t* pdst, int dstpitch, const uint8_t *src, int srcpitch, int width, int height)\n{\n  // dstpitch may not be mod16\n  const int wmod2 = (width / 2) * 2; // 2x64bit\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wmod2; x += 2) {\n      __m128i a = _mm_loadu_si128(reinterpret_cast<const __m128i *>(src + 8 * x));\n      a = _mm_bswap_epi64_sse2(a);\n      _mm_storeu_si128(reinterpret_cast<__m128i *>(pdst + 8 * x), a);\n    }\n    if (wmod2 < width) {\n      __m128i a = _mm_loadl_epi64(reinterpret_cast<const __m128i *>(src + 8 * wmod2));\n      a = _mm_bswap_epi64_sse2(a);\n      _mm_storel_epi64(reinterpret_cast<__m128i *>(pdst + 8 * wmod2), a);\n    }\n    src += srcpitch;\n    pdst += dstpitch;\n  }\n}\n#endif // INTEL_INTRINSICS\n\n// 4x16: two-way symmetric\nvoid bgra_to_argbBE_c(uint8_t* pdst, int dstpitch, const uint8_t *src, int srcpitch, int width, int height)\n{\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < width; x++) {\n      uint64_t a = reinterpret_cast<const uint64_t *>(src)[x]; // bgra -> argb+byte swap\n      a = avs_swap64(a);\n      reinterpret_cast<uint64_t*>(pdst)[x] = a;\n    }\n    src += srcpitch;\n    pdst += dstpitch;\n  }\n}\n\n// Helpers for YUV420(422)P10<->P010 and YUV420(422)P16<->P016 conversion\n\ntemplate<bool before>\nstatic void prepare_luma_shift6_c(uint8_t* pdst, int dstpitch, const uint8_t *src, int srcpitch, int width, int height)\n{\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < width; x++) {\n      if (before)\n        reinterpret_cast<uint16_t*>(pdst)[x] = reinterpret_cast<const uint16_t *>(src)[x] << 6;\n      else\n        reinterpret_cast<uint16_t*>(pdst)[x] = reinterpret_cast<const uint16_t *>(src)[x] >> 6;\n    }\n    src += srcpitch;\n    pdst += dstpitch;\n  }\n}\n\n#ifdef INTEL_INTRINSICS\ntemplate<bool before>\nstatic void prepare_luma_shift6_sse2(uint8_t* pdst, int dstpitch, const uint8_t *src, int srcpitch, int width, int height)\n{\n  // srcpitch or dstpitch may not be mod16\n  const int modw = (width / 8) * 8; // 8 uv pairs at a time\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < modw; x += 8) {\n      __m128i y = _mm_loadu_si128(reinterpret_cast<const __m128i *>(reinterpret_cast<const uint16_t *>(src) + x));\n      if (before)\n        y = _mm_slli_epi16(y, 6); // make 10->16 bits\n      else\n        y = _mm_srli_epi16(y, 6); // make 16->10 bits\n      _mm_storeu_si128(reinterpret_cast<__m128i *>(reinterpret_cast<uint16_t *>(pdst) + x), y);\n    }\n\n    for (int x = modw; x < width; x++) {\n      if (before)\n        reinterpret_cast<uint16_t*>(pdst)[x] = reinterpret_cast<const uint16_t *>(src)[x] << 6;\n      else\n        reinterpret_cast<uint16_t*>(pdst)[x] = reinterpret_cast<const uint16_t *>(src)[x] >> 6;\n    }\n    src += srcpitch;\n    pdst += dstpitch;\n  }\n}\n#endif // INTEL_INTRINSICS\n\ntemplate<bool shift6>\nstatic void prepare_to_interleaved_uv_c(uint8_t* pdst, int dstpitch, const uint8_t *srcu, const uint8_t *srcv, int pitchUV, int width, int height)\n{\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < width; x++) {\n      uint16_t u, v;\n      if (shift6) {\n        u = reinterpret_cast<const uint16_t *>(srcu)[x] << 6; // make 10->16 bits\n        v = reinterpret_cast<const uint16_t *>(srcv)[x] << 6; // make 10->16 bits\n      }\n      else {\n        u = reinterpret_cast<const uint16_t *>(srcu)[x];\n        v = reinterpret_cast<const uint16_t *>(srcv)[x];\n      }\n      uint32_t uv = (v << 16) | u;\n      reinterpret_cast<uint32_t*>(pdst)[x] = uv;\n    }\n    srcu += pitchUV;\n    srcv += pitchUV;\n    pdst += dstpitch;\n  }\n}\n\n#ifdef INTEL_INTRINSICS\ntemplate<bool shift6>\nstatic void prepare_to_interleaved_uv_sse2(uint8_t* pdst, int dstpitch, const uint8_t *srcu, const uint8_t *srcv, int pitchUV, int width, int height)\n{\n  // dstpitch may not be mod16\n  const int modw = (width / 8) * 8; // 8 uv pairs at a time\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < modw; x += 8) {\n      __m128i u = _mm_load_si128(reinterpret_cast<const __m128i *>(reinterpret_cast<const uint16_t *>(srcu) + x));\n      __m128i v = _mm_load_si128(reinterpret_cast<const __m128i *>(reinterpret_cast<const uint16_t *>(srcv) + x));\n      if (shift6) {\n        u = _mm_slli_epi16(u, 6); // make 10->16 bits\n        v = _mm_slli_epi16(v, 6);\n      }\n      __m128i uv;\n      uv = _mm_unpacklo_epi16(u, v); // (v << 16) | u;\n      _mm_storeu_si128(reinterpret_cast<__m128i *>(reinterpret_cast<uint32_t *>(pdst) + x), uv);\n      uv = _mm_unpackhi_epi16(u, v); // (v << 16) | u;\n      _mm_storeu_si128(reinterpret_cast<__m128i *>(reinterpret_cast<uint32_t *>(pdst) + x + 4), uv);\n    }\n\n    for (int x = modw; x < width; x++) {\n      uint16_t u, v;\n      if (shift6) {\n        u = reinterpret_cast<const uint16_t *>(srcu)[x] << 6; // make 10->16 bits\n        v = reinterpret_cast<const uint16_t *>(srcv)[x] << 6; // make 10->16 bits\n      }\n      else {\n        u = reinterpret_cast<const uint16_t *>(srcu)[x];\n        v = reinterpret_cast<const uint16_t *>(srcv)[x];\n      }\n      uint32_t uv = (v << 16) | u;\n      reinterpret_cast<uint32_t*>(pdst)[x] = uv;\n    }\n    srcu += pitchUV;\n    srcv += pitchUV;\n    pdst += dstpitch;\n  }\n}\n#endif // INTEL_INTRINSICS\n\ntemplate<bool shift6>\nstatic void prepare_from_interleaved_uv_c(uint8_t* pdstu, uint8_t* pdstv, int pitchUV, const uint8_t *src, int srcpitch, int width, int height)\n{\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < width; x++) {\n      uint32_t uv = reinterpret_cast<const uint32_t*>(src)[x];\n      uint16_t u = uv & 0xFFFF;\n      uint16_t v = uv >> 16;\n      if (shift6) {\n        u >>= 6;\n        v >>= 6;\n      }\n      reinterpret_cast<uint16_t*>(pdstu)[x] = u;\n      reinterpret_cast<uint16_t*>(pdstv)[x] = v;\n    }\n    pdstu += pitchUV;\n    pdstv += pitchUV;\n    src += srcpitch;\n  }\n}\n\n#ifdef INTEL_INTRINSICS\ntemplate<bool shift6>\nstatic void prepare_from_interleaved_uv_sse2(uint8_t* pdstu, uint8_t* pdstv, int pitchUV, const uint8_t *src, int srcpitch, int width, int height)\n{\n  // srcpitch may not be mod16\n  const int modw = (width / 8) * 8;\n  auto mask0000FFFF = _mm_set1_epi32(0x0000FFFF);\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < modw; x += 8) {\n      auto uv_lo = _mm_loadu_si128(reinterpret_cast<const __m128i *>(reinterpret_cast<const uint32_t*>(src) + x));\n      auto uv_hi = _mm_loadu_si128(reinterpret_cast<const __m128i *>(reinterpret_cast<const uint32_t*>(src) + x + 4));\n      if (shift6) {\n        uv_lo = _mm_srli_epi16(uv_lo, 6);\n        uv_hi = _mm_srli_epi16(uv_hi, 6);\n      }\n      auto u_lo = _mm_and_si128(uv_lo, mask0000FFFF);\n      auto u_hi = _mm_and_si128(uv_hi, mask0000FFFF);\n      auto u = shift6 ? _mm_packs_epi32(u_lo, u_hi) : _MM_PACKUS_EPI32(u_lo, u_hi); // sse41 simul\n      _mm_store_si128(reinterpret_cast<__m128i *>(reinterpret_cast<uint16_t*>(pdstu) + x), u);\n\n      auto v_lo = _mm_srli_epi32(uv_lo, 16);\n      auto v_hi = _mm_srli_epi32(uv_hi, 16);\n      auto v = shift6 ? _mm_packs_epi32(v_lo, v_hi) : _MM_PACKUS_EPI32(v_lo, v_hi); // sse41 simul\n      _mm_store_si128(reinterpret_cast<__m128i *>(reinterpret_cast<uint16_t*>(pdstv) + x), v);\n    }\n\n    for (int x = modw; x < width; x++) {\n      uint32_t uv = reinterpret_cast<const uint32_t*>(src)[x];\n      uint16_t u = uv & 0xFFFF;\n      uint16_t v = uv >> 16;\n      if (shift6) {\n        u >>= 6;\n        v >>= 6;\n      }\n      reinterpret_cast<uint16_t*>(pdstu)[x] = u;\n      reinterpret_cast<uint16_t*>(pdstv)[x] = v;\n    }\n\n    pdstu += pitchUV;\n    pdstv += pitchUV;\n    src += srcpitch;\n  }\n}\n\ntemplate<bool shift6>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nstatic void prepare_from_interleaved_uv_sse41(uint8_t* pdstu, uint8_t* pdstv, int pitchUV, const uint8_t *src, int srcpitch, int width, int height)\n{\n  // srcpitch may not be mod16\n  const int modw = (width / 8) * 8;\n  auto mask0000FFFF = _mm_set1_epi32(0x0000FFFF);\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < modw; x += 8) {\n      auto uv_lo = _mm_loadu_si128(reinterpret_cast<const __m128i *>(reinterpret_cast<const uint32_t*>(src) + x));\n      auto uv_hi = _mm_loadu_si128(reinterpret_cast<const __m128i *>(reinterpret_cast<const uint32_t*>(src) + x + 4));\n      if (shift6) {\n        uv_lo = _mm_srli_epi16(uv_lo, 6);\n        uv_hi = _mm_srli_epi16(uv_hi, 6);\n      }\n      auto u_lo = _mm_and_si128(uv_lo, mask0000FFFF);\n      auto u_hi = _mm_and_si128(uv_hi, mask0000FFFF);\n      auto u = shift6 ? _mm_packs_epi32(u_lo, u_hi) : _mm_packus_epi32(u_lo, u_hi); // sse41\n      _mm_store_si128(reinterpret_cast<__m128i *>(reinterpret_cast<uint16_t*>(pdstu) + x), u);\n\n      auto v_lo = _mm_srli_epi32(uv_lo, 16);\n      auto v_hi = _mm_srli_epi32(uv_hi, 16);\n      auto v = shift6 ? _mm_packs_epi32(v_lo, v_hi) : _mm_packus_epi32(v_lo, v_hi); // sse41\n      _mm_store_si128(reinterpret_cast<__m128i *>(reinterpret_cast<uint16_t*>(pdstv) + x), v);\n    }\n\n    for (int x = modw; x < width; x++) {\n      uint32_t uv = reinterpret_cast<const uint32_t*>(src)[x];\n      uint16_t u = uv & 0xFFFF;\n      uint16_t v = uv >> 16;\n      if (shift6) {\n        u >>= 6;\n        v >>= 6;\n      }\n      reinterpret_cast<uint16_t*>(pdstu)[x] = u;\n      reinterpret_cast<uint16_t*>(pdstv)[x] = v;\n    }\n\n    pdstu += pitchUV;\n    pdstv += pitchUV;\n    src += srcpitch;\n  }\n}\n#endif // INTEL_INTRINSICS\n\n\nvoid yuv422p10_to_v210(BYTE *dstp, const BYTE *srcp_y, int srcpitch, const BYTE *srcp_u, const BYTE *srcp_v, int srcpitch_uv, int width, int height)\n{\n  int ppitch_y = srcpitch / sizeof(uint16_t);\n  int ppitch_uv = srcpitch_uv / sizeof(uint16_t);\n  const uint16_t *yptr = (const uint16_t *)srcp_y;\n  const uint16_t *uptr = (const uint16_t *)srcp_u;\n  const uint16_t *vptr = (const uint16_t *)srcp_v;\n  uint32_t *outbuf = (uint32_t *)dstp;\n  const int out_pitch = ((16 * ((width + 5) / 6) + 127) & ~127) / 4;\n  for (int y = 0; y < height; y++) {\n    const uint16_t *yline = yptr;\n    const uint16_t *uline = uptr;\n    const uint16_t *vline = vptr;\n    uint32_t *out_line = outbuf;\n    for (int x = 0; x < width + 5; x += 6) {\n      out_line[0] = (uline[0] | (yline[0] << 10) | (vline[0] << 20));\n      out_line[1] = (yline[1] | (uline[1] << 10) | (yline[2] << 20));\n      out_line[2] = (vline[1] | (yline[3] << 10) | (uline[2] << 20));\n      out_line[3] = (yline[4] | (vline[2] << 10) | (yline[5] << 20));\n      out_line += 4;\n      yline += 6;\n      uline += 3;\n      vline += 3;\n    }\n    outbuf += out_pitch;\n    yptr += ppitch_y;\n    uptr += ppitch_uv;\n    vptr += ppitch_uv;\n  }\n}\n\n\nvoid v210_to_yuv422p10(BYTE *dstp_y, int dstpitch, BYTE *dstp_u, BYTE *dstp_v, int dstpitch_uv, const BYTE *srcp, int width, int height)\n{\n  /*\n  v210: packed YUV 4:2:2 (UYVY) 10 bits per component.\n  Data is stored in blocks of 32 bit values in little-endian.\n  Each such block contains 3 components, one each in bits 0 - 9, 10 - 19 and 20 - 29, the remaining two bits are unused.\n  Six pixels in a pattern that repeats every 4 32-bits blocks:\n\n  block 1, bits  0 -  9: U0-1\n  block 1, bits 10 - 19: Y0\n  block 1, bits 20 - 29: V0-1\n  block 2, bits  0 -  9: Y1\n  block 2, bits 10 - 19: U2-3\n  block 2, bits 20 - 29: Y2\n  block 3, bits  0 -  9: V2-3\n  block 3, bits 10 - 19: Y3\n  block 3, bits 20 - 29: U4-5\n  block 4, bits  0 -  9: Y4\n  block 4, bits 10 - 19: V4-5\n  block 4, bits 20 - 29: Y5\n\n  */\n  int ppitch_y = dstpitch / sizeof(uint16_t);\n  int ppitch_uv = dstpitch_uv / sizeof(uint16_t);\n  uint16_t *yptr = (uint16_t *)dstp_y;\n  uint16_t *uptr = (uint16_t *)dstp_u;\n  uint16_t *vptr = (uint16_t *)dstp_v;\n\n  const int srcpitch = ((16 * ((width + 5) / 6) + 127) & ~127);\n\n  const int width6 = (width / 6) * 6;\n  const int width_rest = width - width6;\n\n  for (int y = 0; y < height; y++) {\n    uint16_t *yline = yptr;\n    uint16_t *uline = uptr;\n    uint16_t *vline = vptr;\n    const uint32_t *srcline = reinterpret_cast<const uint32_t *>(srcp);\n\n    for (int x = 0; x < width6; x += 6) {\n      uint32_t block1 = srcline[0];\n      uint32_t block2 = srcline[1];\n      uint32_t block3 = srcline[2];\n      uint32_t block4 = srcline[3];\n\n      uline[0] = (block1) & 0x3FF;\n      vline[0] = (block1 >> 20) & 0x3FF;\n      yline[0] = (block1 >> 10) & 0x3FF;\n      yline[1] = (block2) & 0x3FF;\n\n      uline[1] = (block2 >> 10) & 0x3FF;\n      vline[1] = (block3) & 0x3FF;\n      yline[2] = (block2 >> 20) & 0x3FF;\n      yline[3] = (block3 >> 10) & 0x3FF;\n\n      uline[2] = (block3 >> 20) & 0x3FF;\n      vline[2] = (block4 >> 10) & 0x3FF;\n      yline[4] = (block4) & 0x3FF;\n      yline[5] = (block4 >> 20) & 0x3FF;\n\n      srcline += 4;\n      yline += 6;\n      uline += 3;\n      vline += 3;\n    }\n    // rest 2 or 4 pixels\n    if (width_rest >= 2) {\n      uint32_t block1 = srcline[0];\n      uint32_t block2 = srcline[1];\n\n      uline[0] = (block1) & 0x3FF;\n      vline[0] = (block1 >> 20) & 0x3FF;\n      yline[0] = (block1 >> 10) & 0x3FF;\n      yline[1] = (block2) & 0x3FF;\n\n      if (width_rest >= 4) {\n        uint32_t block3 = srcline[2];\n\n        uline[1] = (block2 >> 10) & 0x3FF;\n        vline[1] = (block3) & 0x3FF;\n        yline[2] = (block2 >> 20) & 0x3FF;\n        yline[3] = (block3 >> 10) & 0x3FF;\n      }\n    }\n    srcp += srcpitch;\n    yptr += ppitch_y;\n    uptr += ppitch_uv;\n    vptr += ppitch_uv;\n  }\n}\n\nvoid v408_to_yuva444p8(BYTE* dstp_y, int dstpitch, BYTE* dstp_u, BYTE* dstp_v, BYTE* dstp_a, int dstpitch_uv, int dstpitch_a, const BYTE* srcp, int width, int height)\n{\n  int ppitch_y = dstpitch;\n  int ppitch_uv = dstpitch_uv;\n  int ppitch_a = dstpitch_a;\n  uint8_t* yptr = dstp_y;\n  uint8_t* uptr = dstp_u;\n  uint8_t* vptr = dstp_v;\n  uint8_t* aptr = dstp_a;\n\n  const int srcpitch = width * 4;\n\n  for (int y = 0; y < height; y++) {\n    uint8_t* yline = yptr;\n    uint8_t* uline = uptr;\n    uint8_t* vline = vptr;\n    uint8_t* aline = aptr;\n    const uint32_t* srcline = reinterpret_cast<const uint32_t*>(srcp);\n\n    for (int x = 0; x < width; x++) {\n      uint32_t block = srcline[x]; // 4x8 bit\n      uline[x] = (block) & 0xFF;\n      vline[x] = (block >> 16) & 0xFF;\n      yline[x] = (block >> 8) & 0xFF;\n      aline[x] = (block >> 24) & 0xFF;\n    }\n    srcp += srcpitch;\n    yptr += ppitch_y;\n    uptr += ppitch_uv;\n    vptr += ppitch_uv;\n    aptr += ppitch_a;\n  }\n}\n\nvoid v308_to_yuv444p8(BYTE* dstp_y, int dstpitch, BYTE* dstp_u, BYTE* dstp_v, int dstpitch_uv, const BYTE* srcp, int width, int height)\n{\n  int ppitch_y = dstpitch;\n  int ppitch_uv = dstpitch_uv;\n  uint8_t* yptr = dstp_y;\n  uint8_t* uptr = dstp_u;\n  uint8_t* vptr = dstp_v;\n\n  const int srcpitch = width * 3;\n\n  for (int y = 0; y < height; y++) {\n    uint8_t* yline = yptr;\n    uint8_t* uline = uptr;\n    uint8_t* vline = vptr;\n    const uint8_t* srcline = srcp;\n\n    for (int x = 0; x < width; x++) {\n      vline[x] = srcline[x * 3 + 0];\n      yline[x] = srcline[x * 3 + 1];\n      uline[x] = srcline[x * 3 + 2];\n    }\n    srcp += srcpitch;\n    yptr += ppitch_y;\n    uptr += ppitch_uv;\n    vptr += ppitch_uv;\n  }\n}\n\nvoid v410_to_yuv444p10(BYTE* dstp_y, int dstpitch, BYTE* dstp_u, BYTE* dstp_v, int dstpitch_uv, const BYTE* srcp, int width, int height)\n{\n  int ppitch_y = dstpitch / sizeof(uint16_t);\n  int ppitch_uv = dstpitch_uv / sizeof(uint16_t);\n  uint16_t* yptr = (uint16_t*)dstp_y;\n  uint16_t* uptr = (uint16_t*)dstp_u;\n  uint16_t* vptr = (uint16_t*)dstp_v;\n\n  const int srcpitch = width * 4;\n\n  for (int y = 0; y < height; y++) {\n    uint16_t* yline = yptr;\n    uint16_t* uline = uptr;\n    uint16_t* vline = vptr;\n    const uint32_t* srcline = reinterpret_cast<const uint32_t*>(srcp);\n\n    for (int x = 0; x < width; x++) {\n      uint32_t block = srcline[x];\n\n      yline[x] = (block >> 12) & 0x3FF;\n      uline[x] = (block >> 2) & 0x3FF;\n      vline[x] = (block >> 22) & 0x3FF;\n    }\n    srcp += srcpitch;\n    yptr += ppitch_y;\n    uptr += ppitch_uv;\n    vptr += ppitch_uv;\n  }\n}\n\nvoid yuv42xp10_16_to_Px10_16(BYTE *dstp, int dstpitch, const BYTE *srcp_y, int srcpitch,\n  const BYTE *srcp_u, const BYTE *srcp_v, int srcpitch_uv,\n  int width, int height, int cheight, bool semi_packed_p16, IScriptEnvironment *env)\n{\n  // P010/P016/P210/P216 format:\n  // Single buffer\n  // n lines   YYYYYYYYYYYYYY\n  // n/2 lines UVUVUVUVUVUVUV (4:2:0)\n  // or n lines UVUVUVUVUVUVUV (4:2:2)\n  // Pitch is common. P010/P210 is upshifted to 16 bits\n\n#ifdef INTEL_INTRINSICS\n  const bool sse2 = !!(env->GetCPUFlags() & CPUF_SSE2);\n#endif\n\n  // dstpitch may not be mod16\n\n  // luma\n  if (semi_packed_p16) {\n    // no shift, native copy\n    env->BitBlt(dstp, dstpitch, srcp_y, srcpitch, width * sizeof(uint16_t), height);\n  }\n  else {\n    // shift by 6 make 10->16 bits\n#ifdef INTEL_INTRINSICS\n    if (sse2)\n      prepare_luma_shift6_sse2<true>(dstp, dstpitch, srcp_y, srcpitch, width, height); // true: conv to P016\n    else\n#endif // INTEL_INTRINSICS\n      prepare_luma_shift6_c<true>(dstp, dstpitch, srcp_y, srcpitch, width, height); // true: conv to P016\n  }\n\n  dstp += dstpitch * height;\n\n  // Chroma\n  int cwidth = width / 2;\n\n#ifdef INTEL_INTRINSICS\n  if (sse2) {\n    if (semi_packed_p16)\n      prepare_to_interleaved_uv_sse2<false>(dstp, dstpitch, srcp_u, srcp_v, srcpitch_uv, cwidth, cheight);\n    else\n      prepare_to_interleaved_uv_sse2<true>(dstp, dstpitch, srcp_u, srcp_v, srcpitch_uv, cwidth, cheight); // shift6 inside\n  }\n  else {\n#endif // INTEL_INTRINSICS\n    if (semi_packed_p16)\n      prepare_to_interleaved_uv_c<false>(dstp, dstpitch, srcp_u, srcp_v, srcpitch_uv, cwidth, cheight);\n    else\n      prepare_to_interleaved_uv_c<true>(dstp, dstpitch, srcp_u, srcp_v, srcpitch_uv, cwidth, cheight); // shift6 inside\n#ifdef INTEL_INTRINSICS\n  }\n#endif // INTEL_INTRINSICS\n\n}\n\nvoid Px10_16_to_yuv42xp10_16(BYTE *dstp_y, int dstpitch, BYTE *dstp_u, BYTE *dstp_v, int dstpitch_uv,\n  const BYTE *srcp, int srcpitch,\n  int width, int height, int cheight, bool semi_packed_p16, IScriptEnvironment *env)\n{\n#ifdef INTEL_INTRINSICS\n  const bool sse2 = !!(env->GetCPUFlags() & CPUF_SSE2);\n  const bool sse41 = !!(env->GetCPUFlags() & CPUF_SSE4_1);\n#endif\n\n  // srcpitch may not be mod16\n\n  // convert P010, P016, P210 and P216 formats back to Avisynth YUV420P10 and P16 or YUV422P10 and P16 formats\n\n  // Luma\n  if (semi_packed_p16) {\n    env->BitBlt(dstp_y, dstpitch, srcp, srcpitch, width * sizeof(uint16_t), height);\n  }\n  else {\n    // shift by 6 make 10->16 bits\n#ifdef INTEL_INTRINSICS\n    if (sse2)\n      prepare_luma_shift6_sse2<false>(dstp_y, dstpitch, srcp, srcpitch, width, height); // false: after\n    else\n#endif\n      prepare_luma_shift6_c<false>(dstp_y, dstpitch, srcp, srcpitch, width, height); // false: after\n  }\n  srcp += srcpitch * height;\n\n  // Chroma\n  int cwidth = width / 2; // 422 or 420\n#ifdef INTEL_INTRINSICS\n  if (sse41) {\n    if (semi_packed_p16)\n      prepare_from_interleaved_uv_sse41<false>(dstp_u, dstp_v, dstpitch_uv, srcp, srcpitch, cwidth, cheight);\n    else\n      prepare_from_interleaved_uv_sse41<true>(dstp_u, dstp_v, dstpitch_uv, srcp, srcpitch, cwidth, cheight); // true: shift 6\n  }\n  else if (sse2) {\n    if (semi_packed_p16)\n      prepare_from_interleaved_uv_sse2<false>(dstp_u, dstp_v, dstpitch_uv, srcp, srcpitch, cwidth, cheight);\n    else\n      prepare_from_interleaved_uv_sse2<true>(dstp_u, dstp_v, dstpitch_uv, srcp, srcpitch, cwidth, cheight); // true: shift 6\n  }\n  else {\n#endif // INTEL_INTRINSICS\n    if (semi_packed_p16)\n      prepare_from_interleaved_uv_c<false>(dstp_u, dstp_v, dstpitch_uv, srcp, srcpitch, cwidth, cheight);\n    else\n      prepare_from_interleaved_uv_c<true>(dstp_u, dstp_v, dstpitch_uv, srcp, srcpitch, cwidth, cheight); // true: shift 6\n#ifdef INTEL_INTRINSICS\n  }\n#endif\n}\n\n"
  },
  {
    "path": "avs_core/core/AviHelper.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __AviHelper_H__\n#define __AviHelper_H__\n\n#include <avisynth.h>\n#include <stdint.h>\n\nint AviHelper_ImageSize(const VideoInfo *vi, bool AVIPadScanlines, bool v210, bool v410, bool r210, bool R10k, bool v308, bool v408, bool Y410);\n\ntemplate<bool hasAlpha>\nvoid ToY416_sse2(uint8_t *outbuf, int out_pitch, const uint8_t *yptr, int ypitch, const uint8_t *uptr, const uint8_t *vptr, int uvpitch, const uint8_t *aptr, int apitch, int width, int height);\n\ntemplate<bool hasAlpha>\nvoid ToY416_c(uint8_t *outbuf8, int out_pitch, const uint8_t *yptr, int ypitch, const uint8_t *uptr, const uint8_t *vptr, int uvpitch, const uint8_t *aptr, int apitch, int width, int height);\ntemplate<bool hasAlpha>\nvoid FromY416_c(uint8_t *yptr, int ypitch, uint8_t *uptr, uint8_t *vptr, int uvpitch, uint8_t *aptr, int apitch, const uint8_t *srcp8, int srcpitch, int width, int height);\n\ntemplate<bool hasAlpha>\nvoid ToY410_c(uint8_t* outbuf8, int out_pitch, const uint8_t* yptr, int ypitch, const uint8_t* uptr, const uint8_t* vptr, int uvpitch, const uint8_t* aptr, int apitch, int width, int height);\ntemplate<bool hasAlpha>\nvoid FromY410_c(uint8_t* yptr, int ypitch, uint8_t* uptr, uint8_t* vptr, int uvpitch, uint8_t* aptr, int apitch, const uint8_t* srcp8, int srcpitch, int width, int height);\n\nvoid From_r210_c(uint8_t *rptr, uint8_t *gptr, uint8_t *bptr, int pitch, uint8_t *srcp8, int srcpitch, int width, int height);\nvoid From_R10k_c(uint8_t *rptr, uint8_t *gptr, uint8_t *bptr, int pitch, uint8_t *srcp8, int srcpitch, int width, int height);\n\nvoid bgr_to_rgbBE_c(uint8_t* pdst, int dstpitch, const uint8_t *src, int srcpitch, int width, int height);\n\nvoid bgra_to_argbBE_ssse3(uint8_t* pdst, int dstpitch, const uint8_t *src, int srcpitch, int width, int height);\nvoid bgra_to_argbBE_sse2(uint8_t* pdst, int dstpitch, const uint8_t *src, int srcpitch, int width, int height);\n\nvoid bgra_to_argbBE_c(uint8_t* pdst, int dstpitch, const uint8_t *src, int srcpitch, int width, int height);\nvoid v410_to_yuv444p10(BYTE *dstp_y, int dstpitch, BYTE *dstp_u, BYTE *dstp_v, int dstpitch_uv, const BYTE *srcp, int width, int height);\nvoid v210_to_yuv422p10(BYTE *dstp_y, int dstpitch, BYTE *dstp_u, BYTE *dstp_v, int dstpitch_uv, const BYTE *srcp, int width, int height);\nvoid v308_to_yuv444p8(BYTE* dstp_y, int dstpitch, BYTE* dstp_u, BYTE* dstp_v, int dstpitch_uv, const BYTE* srcp, int width, int height);\nvoid v408_to_yuva444p8(BYTE* dstp_y, int dstpitch, BYTE* dstp_u, BYTE* dstp_v, BYTE* dstp_a, int dstpitch_uv, int dstpitch_a, const BYTE* srcp, int width, int height);\nvoid yuv422p10_to_v210(BYTE *dstp, const BYTE *srcp_y, int srcpitch, const BYTE *srcp_u, const BYTE *srcp_v, int srcpitch_uv, int width, int height);\nvoid yuv42xp10_16_to_Px10_16(BYTE *dstp, int dstpitch, const BYTE *srcp_y, int srcpitch,\n  const BYTE *srcp_u, const BYTE *srcp_v, int srcpitch_uv,\n  int width, int height, int cheight, bool semi_packed_p16, IScriptEnvironment *env);\nvoid Px10_16_to_yuv42xp10_16(BYTE *dstp_y, int dstpitch, BYTE *dstp_u, BYTE *dstp_v, int dstpitch_uv,\n  const BYTE *srcp, int srcpitch,\n  int width, int height, int cheight, bool semi_packed_p16, IScriptEnvironment *env);\n\n#endif  // __AviHelper_H__\n"
  },
  {
    "path": "avs_core/core/BufferPool.cpp",
    "content": "#include \"BufferPool.h\"\n#include <map>\n#include <avisynth.h>\n#include <avs/alignment.h>\n#include <avs/minmax.h>\n#include \"InternalEnvironment.h\"\n\n#define BUFFER_GUARD_VALUE  0x55555555\n\nstruct BufferPool::BufferDesc\n{\n  void* ptr;\n  size_t size;\n  size_t alignment;\n  bool in_use;\n};\n\n\nstatic inline void CheckGuards(void* ptr)\n{\n  #ifndef NDEBUG\n  size_t lower_guard = (size_t)(((void**)ptr)[-5]);\n  assert(lower_guard == BUFFER_GUARD_VALUE);\n  size_t upper_guard = (size_t)(((void**)ptr)[-1]);\n  assert(upper_guard == BUFFER_GUARD_VALUE);\n  #endif\n}\n\nstatic inline void* GetUserData(void* ptr)\n{\n  return ((void**)ptr)[-4];\n}\n\nstatic inline size_t GetRealSize(void* ptr)\n{\n  return (size_t)(((void**)ptr)[-3]);\n}\n\nstatic inline void* GetRealPtr(void* ptr)\n{\n  return ((void**)ptr)[-2];\n}\n\nvoid* BufferPool::PrivateAlloc(size_t nBytes, size_t alignment, void* user)\n{\n  /* Number of extra data fields to allocate.\n    * Current field assignment:\n    *  [-1] = upper guard (size_t)\n    *  [-2] = original buffer pointer (void*)\n    *  [-3] = original buffer size (size_t)\n    *  [-4] = user data (void*)\n    *  [-5] = lower guard (size_t)\n    */\n  const int NUM_EXTRA_FIELDS = 5;\n\n  alignment = max(alignment, sizeof(void*));\n  if (!IS_POWER2(alignment))\n    return NULL;\n\n  size_t offset = NUM_EXTRA_FIELDS * sizeof(void*) + alignment - 1;\n  nBytes += offset;\n\n  void *orig = malloc(nBytes);\n  if (orig == NULL)\n    return NULL;\n\n  void **aligned = (void**)(((uintptr_t)orig + (uintptr_t)offset) & (~(uintptr_t)(alignment-1)));\n  aligned[-5] = (void*)BUFFER_GUARD_VALUE;\n  aligned[-4] = user;\n  aligned[-3] = (void*)nBytes;\n  aligned[-2] = orig;\n  aligned[-1] = (void*)BUFFER_GUARD_VALUE;\n\n  Env->AdjustMemoryConsumption(nBytes, false);\n  return aligned;\n}\n\nvoid BufferPool::PrivateFree(void* buffer)\n{\n  CheckGuards(buffer);\n  Env->AdjustMemoryConsumption(GetRealSize(buffer), true);\n  free(GetRealPtr(buffer));\n}\n\n\nBufferPool::BufferPool(InternalEnvironment* env) :\n  Env(env)\n{\n}\n\nBufferPool::~BufferPool()\n{\n  const MapType::iterator end_it = Map.end();\n  for (\n    MapType::iterator it = Map.begin();\n    it != end_it;\n    ++it)\n  {\n      BufferDesc* desc = it->second;\n      PrivateFree(desc->ptr);\n      delete desc;\n  }\n}\n\nvoid* BufferPool::Allocate(size_t nBytes, size_t alignment, bool pool)\n{\n  if (pool)\n  {\n    // First, check if we can return a buffer from the pool\n    const MapType::iterator end_it = Map.end();\n    for (\n      MapType::iterator it = Map.lower_bound(nBytes);\n      it != end_it;\n      ++it)\n    {\n      BufferDesc* desc = it->second;\n      if ( !desc->in_use\n        && (desc->alignment >= alignment)\n      )\n      {\n        desc->in_use = true;\n        return desc->ptr;\n      }\n    }\n\n    // None found, allocate new one\n    BufferDesc* desc = new BufferDesc();\n\n    void* ptr = PrivateAlloc(nBytes, alignment, reinterpret_cast<void*>(desc));\n    if (ptr == NULL)\n    {\n      delete desc;\n      return NULL;\n    }\n\n    desc->alignment = alignment;\n    desc->in_use = true;\n    desc->ptr = ptr;\n    desc->size = nBytes;\n    Map.emplace(nBytes, desc);\n    return ptr;\n  }\n  else\n  {\n    return PrivateAlloc(nBytes, alignment, NULL);\n  }\n}\n\nvoid BufferPool::Free(void* ptr)\n{\n  // Mirroring free()'s semantic requires us to accept NULLs\n  if (ptr == NULL)\n    return;\n\n  CheckGuards(ptr);\n\n  BufferDesc* data = reinterpret_cast<BufferDesc*>(GetUserData(ptr));\n\n  if (data != NULL)\n  { // Getting into this branch means this buffer is pooled\n    data->in_use = false;\n  }\n  else\n  {\n    PrivateFree(ptr);\n  }\n}\n"
  },
  {
    "path": "avs_core/core/BufferPool.h",
    "content": "#ifndef _AVS_BUFFERPOOL_H\n#define _AVS_BUFFERPOOL_H\n\n#include <map>\n#include <avs/types.h>\n\nclass InternalEnvironment;\n\nclass BufferPool\n{\nprivate:\n\n  struct BufferDesc;\n  typedef std::multimap<size_t, BufferDesc*> MapType;\n\n  InternalEnvironment* Env;\n  MapType Map;\n\n  void* PrivateAlloc(size_t nBytes, size_t alignment, void* user);\n  void PrivateFree(void* buffer);\n\npublic:\n\n  BufferPool(InternalEnvironment* env);\n  ~BufferPool();\n\n  void* Allocate(size_t nBytes, size_t alignment, bool pool);\n  void Free(void* ptr);\n\n};\n\n#endif  // _AVS_BUFFERPOOL_H\n"
  },
  {
    "path": "avs_core/core/CompatEnvironment.h",
    "content": "// Avisynth v2.5.  Copyright 2002-2009 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef _AVS_COMPATENVIRONMENT_H_INCLUDED\n#define _AVS_COMPATENVIRONMENT_H_INCLUDED\n\n#include <avisynth.h>\n\n// IScriptEnvironment_Avs25, IScriptEnvironment_AvsPreV11C are used internally.\n// Entries 100% match with IScriptEnvironment to allow typecasting to IScriptEnvironment_Avs25/AvsPreV11.\n// While IScriptEnvironment_Avs25 ends at interface V6 changes, PreV11C version is full copy of IScriptEnvironment.\n// Differences involve three functions:\n// 1. AddFunction25/PreV11C: Marks the added function as originating from \n//    an Avs2.5/PreV11C plugin, see also: arrays-deep-copy, 64-bit params.\n// 2. Invoke25/PreV11C: Argument arrays, which must not be deep-freed, \n//    baked AVSValue code incompatible with deep-array concept and 64 bit data.\n// 3. ManageCache25/PreV11C: Specially returns 1 for key MC_QueryAvs25/PreV11C \n//    to check if called from AVS2.5/PreV11C interface for cache GetFrame/GetAudio.\n\n// See also: InternalEnvironment interface conversion methods comment.\n\n// Compatibility camouflage classes are *passed in place of the original IScriptEnvironment,\n// providing the same function orders to match their VMT tables with the original.\n// Differently named functions appear at specific indexes to perform different compatibility behaviors.\n// *In real they all are static casted from InternalEnvironment, where all these pure virtual methods are implemented.\n\nclass IScriptEnvironment_Avs25 {\npublic:\n  virtual ~IScriptEnvironment_Avs25() {}\n\n  virtual /*static*/ int __stdcall GetCPUFlags() = 0;\n\n  virtual char* __stdcall SaveString(const char* s, int length = -1) = 0;\n  virtual char* Sprintf(const char* fmt, ...) = 0;\n  virtual char* __stdcall VSprintf(const char* fmt, va_list val) = 0;\n\n#ifdef AVS_WINDOWS\n  __declspec(noreturn) virtual void ThrowError(const char* fmt, ...) = 0;\n#else\n  virtual void ThrowError(const char* fmt, ...) = 0;\n#endif\n\n  class NotFound /*exception*/ {};  // thrown by Invoke and GetVar\n\n  typedef AVSValue(__cdecl* ApplyFunc)(AVSValue args, void* user_data, IScriptEnvironment* env);\n\n  virtual void __stdcall AddFunction25(const char* name, const char* params, ApplyFunc apply, void* user_data) = 0;\n  virtual bool __stdcall FunctionExists(const char* name) = 0;\n  virtual AVSValue __stdcall Invoke25(const char* name, const AVSValue args, const char* const* arg_names = 0) = 0;\n\n  virtual AVSValue __stdcall GetVar(const char* name) = 0;\n  virtual bool __stdcall SetVar(const char* name, const AVSValue& val) = 0;\n  virtual bool __stdcall SetGlobalVar(const char* name, const AVSValue& val) = 0;\n\n  virtual void __stdcall PushContext(int level = 0) = 0;\n  virtual void __stdcall PopContext() = 0;\n\n  virtual PVideoFrame __stdcall NewVideoFrame(const VideoInfo& vi, int align = FRAME_ALIGN) = 0;\n\n  virtual bool __stdcall MakeWritable(PVideoFrame* pvf) = 0;\n\n  virtual void __stdcall BitBlt(BYTE* dstp, int dst_pitch, const BYTE* srcp, int src_pitch, int row_size, int height) = 0;\n\n  typedef void(__cdecl* ShutdownFunc)(void* user_data, IScriptEnvironment* env);\n  virtual void __stdcall AtExit(ShutdownFunc function, void* user_data) = 0;\n\n  virtual void __stdcall CheckVersion(int version = AVISYNTH_CLASSIC_INTERFACE_VERSION_25) = 0;\n\n  virtual PVideoFrame __stdcall Subframe(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height) = 0;\n\n  virtual int __stdcall SetMemoryMax(int mem) = 0;\n\n  virtual int __stdcall SetWorkingDir(const char* newdir) = 0;\n\n  // specially returns 1 for key MC_QueryAvs25 to check if called from AVS2.5 interface\n  virtual void* __stdcall ManageCache25(int key, void* data) = 0;\n\n  enum PlanarChromaAlignmentMode {\n    PlanarChromaAlignmentOff,\n    PlanarChromaAlignmentOn,\n    PlanarChromaAlignmentTest\n  };\n\n  virtual bool __stdcall PlanarChromaAlignment(IScriptEnvironment::PlanarChromaAlignmentMode key) = 0;\n\n  virtual PVideoFrame __stdcall SubframePlanar(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size,\n    int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV) = 0;\n\n  // Despite the name, we provide entries up to V6 in case someone requests\n  // a V3 interface and still wants to use V5-V6 functions\n\n  // **** AVISYNTH_INTERFACE_VERSION 5 **** defined since classic Avisynth 2.6 beta\n  virtual void __stdcall DeleteScriptEnvironment() = 0;\n\n  virtual void __stdcall ApplyMessage(PVideoFrame* frame, const VideoInfo& vi, const char* message, int size,\n    int textcolor, int halocolor, int bgcolor) = 0;\n\n  virtual const AVS_Linkage* __stdcall GetAVSLinkage() = 0;\n\n  // **** AVISYNTH_INTERFACE_VERSION 6 **** defined since classic Avisynth 2.6\n  // noThrow version of GetVar\n  virtual AVSValue __stdcall GetVarDef(const char* name, const AVSValue& def = AVSValue()) = 0;\n\n}; // end class IScriptEnvironment_Avs25. Order is important.\n\n\n// Unlike IScriptEnvironment_Avs25 which ends at the V6 changes,\n// IScriptEnvironment_AvsPreV11C is a complete copy of IScriptEnvironment, \n// except the name of the above mentioned three methods.\nclass IScriptEnvironment_AvsPreV11C {\npublic:\n  virtual ~IScriptEnvironment_AvsPreV11C() {}\n\n  virtual int __stdcall GetCPUFlags() = 0;\n\n  virtual char* __stdcall SaveString(const char* s, int length = -1) = 0;\n  virtual char* Sprintf(const char* fmt, ...) = 0;\n  virtual char* __stdcall VSprintf(const char* fmt, va_list val) = 0;\n\n#ifdef AVS_WINDOWS\n  __declspec(noreturn) virtual void ThrowError(const char* fmt, ...) = 0;\n#else\n  virtual void ThrowError(const char* fmt, ...) = 0;\n#endif\n\n  class NotFound /*exception*/ {};  // thrown by Invoke and GetVar\n\n  typedef AVSValue(__cdecl* ApplyFunc)(AVSValue args, void* user_data, IScriptEnvironment* env);\n\n  virtual void __stdcall AddFunctionPreV11C(const char* name, const char* params, ApplyFunc apply, void* user_data) = 0;\n  virtual bool __stdcall FunctionExists(const char* name) = 0;\n  virtual AVSValue __stdcall InvokePreV11C(const char* name, const AVSValue args, const char* const* arg_names = 0) = 0;\n\n  virtual AVSValue __stdcall GetVar(const char* name) = 0;\n  virtual bool __stdcall SetVar(const char* name, const AVSValue& val) = 0;\n  virtual bool __stdcall SetGlobalVar(const char* name, const AVSValue& val) = 0;\n\n  virtual void __stdcall PushContext(int level = 0) = 0;\n  virtual void __stdcall PopContext() = 0;\n\n  virtual PVideoFrame __stdcall NewVideoFrame(const VideoInfo& vi, int align = FRAME_ALIGN) = 0;\n\n  virtual bool __stdcall MakeWritable(PVideoFrame* pvf) = 0;\n\n  virtual void __stdcall BitBlt(BYTE* dstp, int dst_pitch, const BYTE* srcp, int src_pitch, int row_size, int height) = 0;\n\n  typedef void(__cdecl* ShutdownFunc)(void* user_data, IScriptEnvironment* env);\n  virtual void __stdcall AtExit(ShutdownFunc function, void* user_data) = 0;\n\n  virtual void __stdcall CheckVersion(int version = AVISYNTH_CLASSIC_INTERFACE_VERSION_25) = 0;\n\n  virtual PVideoFrame __stdcall Subframe(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height) = 0;\n\n  virtual int __stdcall SetMemoryMax(int mem) = 0;\n\n  virtual int __stdcall SetWorkingDir(const char* newdir) = 0;\n\n  // specially returns 1 for key MC_QueryAvsPreV11C to check if called from C interface\n  virtual void* __stdcall ManageCachePreV11C(int key, void* data) = 0;\n\n  enum PlanarChromaAlignmentMode {\n    PlanarChromaAlignmentOff,\n    PlanarChromaAlignmentOn,\n    PlanarChromaAlignmentTest\n  };\n\n  virtual bool __stdcall PlanarChromaAlignment(IScriptEnvironment::PlanarChromaAlignmentMode key) = 0;\n\n  virtual PVideoFrame __stdcall SubframePlanar(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size,\n    int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV) = 0;\n\n  // **** AVISYNTH_INTERFACE_VERSION 5 **** defined since classic Avisynth 2.6 beta\n  virtual void __stdcall DeleteScriptEnvironment() = 0;\n\n  virtual void __stdcall ApplyMessage(PVideoFrame* frame, const VideoInfo& vi, const char* message, int size,\n    int textcolor, int halocolor, int bgcolor) = 0;\n\n  virtual const AVS_Linkage* __stdcall GetAVSLinkage() = 0;\n\n  // **** AVISYNTH_INTERFACE_VERSION 6 **** defined since classic Avisynth 2.6\n  // noThrow version of GetVar\n  virtual AVSValue __stdcall GetVarDef(const char* name, const AVSValue& def = AVSValue()) = 0;\n\n\n  // **** AVISYNTH_INTERFACE_VERSION 8 **** AviSynth+ 3.6.0-\n  virtual PVideoFrame __stdcall SubframePlanarA(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size,\n    int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV, int rel_offsetA) = 0;\n\n  virtual void __stdcall copyFrameProps(const PVideoFrame& src, PVideoFrame& dst) = 0;\n  virtual const AVSMap* __stdcall getFramePropsRO(const PVideoFrame& frame) = 0;\n  virtual AVSMap* __stdcall getFramePropsRW(PVideoFrame& frame) = 0;\n\n  virtual int __stdcall propNumKeys(const AVSMap* map) = 0;\n\n  virtual const char* __stdcall propGetKey(const AVSMap* map, int index) = 0;\n  virtual int __stdcall propNumElements(const AVSMap* map, const char* key) = 0;\n  virtual char __stdcall propGetType(const AVSMap* map, const char* key) = 0;\n\n  virtual int64_t __stdcall propGetInt(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual double __stdcall propGetFloat(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual const char* __stdcall propGetData(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual int __stdcall propGetDataSize(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual PClip __stdcall propGetClip(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual const PVideoFrame __stdcall propGetFrame(const AVSMap* map, const char* key, int index, int* error) = 0;\n\n  virtual int __stdcall propDeleteKey(AVSMap* map, const char* key) = 0;\n\n  virtual int __stdcall propSetInt(AVSMap* map, const char* key, int64_t i, int append) = 0;\n  virtual int __stdcall propSetFloat(AVSMap* map, const char* key, double d, int append) = 0;\n  virtual int __stdcall propSetData(AVSMap* map, const char* key, const char* d, int length, int append) = 0;\n  virtual int __stdcall propSetClip(AVSMap* map, const char* key, PClip& clip, int append) = 0;\n  virtual int __stdcall propSetFrame(AVSMap* map, const char* key, const PVideoFrame& frame, int append) = 0;\n\n  virtual const int64_t* __stdcall propGetIntArray(const AVSMap* map, const char* key, int* error) = 0;\n  virtual const double* __stdcall propGetFloatArray(const AVSMap* map, const char* key, int* error) = 0;\n  virtual int __stdcall propSetIntArray(AVSMap* map, const char* key, const int64_t* i, int size) = 0;\n  virtual int __stdcall propSetFloatArray(AVSMap* map, const char* key, const double* d, int size) = 0;\n\n  virtual AVSMap* __stdcall createMap() = 0;\n  virtual void __stdcall freeMap(AVSMap* map) = 0;\n  virtual void __stdcall clearMap(AVSMap* map) = 0;\n\n  // NewVideoFrame with frame property source.\n  virtual PVideoFrame __stdcall NewVideoFrameP(const VideoInfo& vi, const PVideoFrame* prop_src, int align = FRAME_ALIGN) = 0;\n\n  // Generic query to ask for various system properties\n  virtual size_t  __stdcall GetEnvProperty(AvsEnvProperty prop) = 0;\n\n  // Support functions\n  virtual void* __stdcall Allocate(size_t nBytes, size_t alignment, AvsAllocType type) = 0;\n  virtual void __stdcall Free(void* ptr) = 0;\n\n  // these GetVar versions (renamed differently) were moved from IScriptEnvironment2\n\n  // Returns TRUE and the requested variable. If the method fails, returns FALSE and does not touch 'val'.\n  virtual bool  __stdcall GetVarTry(const char* name, AVSValue* val) const = 0; // ex virtual bool  __stdcall GetVar(const char* name, AVSValue* val) const = 0;\n  // Return the value of the requested variable.\n  // If the variable was not found or had the wrong type,\n  // return the supplied default value.\n  virtual bool __stdcall GetVarBool(const char* name, bool def) const = 0;\n  virtual int  __stdcall GetVarInt(const char* name, int def) const = 0;\n  virtual double  __stdcall GetVarDouble(const char* name, double def) const = 0;\n  virtual const char* __stdcall GetVarString(const char* name, const char* def) const = 0;\n  // brand new in v8 - v11: real int64 support\n  virtual int64_t __stdcall GetVarLong(const char* name, int64_t def) const = 0;\n\n  // 'Invoke' functions moved here from internal ScriptEnvironments are renamed in order to keep vtable order\n  // Invoke functions with 'Try' will return false instead of throwing NotFound().\n  // ex-IScriptEnvironment2\n  virtual bool __stdcall InvokeTry(AVSValue* result, const char* name, const AVSValue& args, const char* const* arg_names = 0) = 0;\n  // Since V8\n  virtual AVSValue __stdcall Invoke2(const AVSValue& implicit_last, const char* name, const AVSValue args, const char* const* arg_names = 0) = 0;\n  // Ex-INeo\n  virtual bool __stdcall Invoke2Try(AVSValue* result, const AVSValue& implicit_last, const char* name, const AVSValue args, const char* const* arg_names = 0) = 0;\n  virtual AVSValue __stdcall Invoke3(const AVSValue& implicit_last, const PFunction& func, const AVSValue args, const char* const* arg_names = 0) = 0;\n  virtual bool __stdcall Invoke3Try(AVSValue* result, const AVSValue& implicit_last, const PFunction& func, const AVSValue args, const char* const* arg_names = 0) = 0;\n\n  // V9\n  virtual bool __stdcall MakePropertyWritable(PVideoFrame* pvf) = 0;\n\n  // V11\n  virtual int __stdcall propGetIntSaturated(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual float __stdcall propGetFloatSaturated(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual int __stdcall propGetDataTypeHint(const AVSMap* map, const char* key, int index, int* error) = 0; // returns AVSPropDataTypeHint\n  virtual int __stdcall propSetDataH(AVSMap* map, const char* key, const char* d, int length, int type, int append) = 0;\n\n  // V12\n  // New Global Lock API for cross-plugin synchronization.\n  // Plugins must ensure these calls are balanced (acquire followed by release),\n  virtual bool __stdcall AcquireGlobalLock(const char* name) = 0;\n  virtual void __stdcall ReleaseGlobalLock(const char* name) = 0;\n  virtual void __stdcall ApplyMessageEx(PVideoFrame* frame, const VideoInfo& vi, const char* message, int size,\n    int textcolor, int halocolor, int bgcolor, bool utf8) = 0;\n  virtual int64_t __stdcall GetCPUFlagsEx() = 0;\n}; // end class IScriptEnvironment_AvsPreV11C. Order is important.\n\n#endif // _AVS_COMPATENVIRONMENT_H_INCLUDED\n"
  },
  {
    "path": "avs_core/core/DeviceManager.cpp",
    "content": "\n#include \"DeviceManager.h\"\n#include \"internal.h\"\n#include \"InternalEnvironment.h\"\n#include <avs/minmax.h>\n#include <deque>\n#include <map>\n#include <mutex>\n#include <sstream>\n#include \"LruCache.h\"\n#include \"ThreadPool.h\"\n#include \"AVSMap.h\"\n#include \"parser/scriptparser.h\"\n\n#ifndef MINGW_HAS_SECURE_API\n#define sprintf_s sprintf\n#endif\n\n#define ENABLE_CUDA_COMPUTE_STREAM 0\n\n#ifdef ENABLE_CUDA\n\n#include <cuda_runtime_api.h>\n\n#endif // #ifdef ENABLE_CUDA\n\n#define CUDA_CHECK(call) \\\n  do { \\\n    cudaError_t err__ = call; \\\n    if (err__ != cudaSuccess) { \\\n      env->ThrowError(\"[CUDA Error] %d: %s @%d\", err__, cudaGetErrorString(err__), __LINE__); \\\n    } \\\n  } while (0)\n\nint GetDeviceTypes(const PClip& child)\n{\n  if (child->GetVersion() < 5) {\n    return DEV_TYPE_CPU;\n  }\n  int deviceflags = child->SetCacheHints(CACHE_GET_DEV_TYPE, 0);\n  if (deviceflags == 0) {\n    // if not implement CACHE_GET_DEVICE_TYPE, we assume CPU only filter.\n    deviceflags = DEV_TYPE_CPU;\n  }\n  return deviceflags;\n}\n\nint GetTargetDeviceTypes(const PClip& clip)\n{\n  if (clip->GetVersion() < 5) {\n    return DEV_TYPE_CPU;\n  }\n  int deviceflags = clip->SetCacheHints(CACHE_GET_CHILD_DEV_TYPE, 0);\n  if (deviceflags == 0) {\n    deviceflags = clip->SetCacheHints(CACHE_GET_DEV_TYPE, 0);\n    if (deviceflags == 0) {\n      // if not implement CACHE_GET_DEVICE_TYPE, we assume CPU only filter.\n      deviceflags = DEV_TYPE_CPU;\n    }\n  }\n  return deviceflags;\n}\n\nstd::string DeviceTypesString(int devicetypes)\n{\n  std::vector<const char*> typesstr;\n  if (devicetypes & DEV_TYPE_CPU) {\n    typesstr.push_back(\"CPU\");\n  }\n  if (devicetypes & DEV_TYPE_CUDA) {\n    typesstr.push_back(\"CUDA\");\n  }\n  std::ostringstream oss;\n  for (int i = 0; i < (int)typesstr.size(); ++i) {\n    if (i > 0) oss << \",\";\n    oss << typesstr[i];\n  }\n  return oss.str();\n}\n\nstatic void CheckDeviceTypes(const char* name, int devicetypes, const AVSValue& last, const AVSValue& arr, InternalEnvironment* env)\n{\n  for (int i = -1; i < arr.ArraySize(); ++i) {\n    const AVSValue& val = (i == -1) ? last : arr[i];\n    if (val.IsClip()) {\n      int childtypes = GetDeviceTypes(val.AsClip());\n      if ((devicetypes & childtypes) == 0) {\n        std::string parentdevstr = DeviceTypesString(devicetypes);\n        std::string childdevstr = DeviceTypesString(childtypes);\n        // e.g.. Device unmatch: XYfilter[CPU] does not support [CUDA] frame\n        env->ThrowError(\n          \"Device unmatch: %s[%s] does not support [%s] frame\",\n          name, parentdevstr.c_str(), childdevstr.c_str());\n      }\n    }\n    else if (val.IsArray()) {\n      CheckDeviceTypes(name, devicetypes, AVSValue(), val, env);\n    }\n  }\n}\n\nvoid CheckChildDeviceTypes(const PClip& clip, const char* name, const AVSValue& last, const AVSValue& args, const char* const* argnames, InternalEnvironment* env)\n{\n  int deviceflags = GetTargetDeviceTypes(clip);\n  if (args.IsArray()) {\n    CheckDeviceTypes(name, deviceflags, last, args, env);\n  }\n  else {\n    CheckDeviceTypes(name, deviceflags, last, AVSValue(&args, 1), env);\n  }\n}\n\nsize_t GetFrameHead(const PVideoFrame& vf)\n{\n  int head = vf->GetOffset();\n  if (vf->GetPitch(PLANAR_U)) {\n    head = min(head, vf->GetOffset(PLANAR_U));\n  }\n  if (vf->GetPitch(PLANAR_V)) {\n    head = min(head, vf->GetOffset(PLANAR_V));\n  }\n  if (vf->GetPitch(PLANAR_A)) {\n    head = min(head, vf->GetOffset(PLANAR_A));\n  }\n  return head;\n}\n\nsize_t GetFrameTail(const PVideoFrame& vf)\n{\n  int tail = vf->GetOffset() + vf->GetPitch() * vf->GetHeight();\n  if (vf->GetPitch(PLANAR_U)) {\n    tail = max(tail, vf->GetOffset(PLANAR_U) + vf->GetPitch(PLANAR_U) * vf->GetHeight(PLANAR_U));\n  }\n  if (vf->GetPitch(PLANAR_V)) {\n    tail = max(tail, vf->GetOffset(PLANAR_V) + vf->GetPitch(PLANAR_V) * vf->GetHeight(PLANAR_V));\n  }\n  if (vf->GetPitch(PLANAR_A)) {\n    tail = max(tail, vf->GetOffset(PLANAR_A) + vf->GetPitch(PLANAR_A) * vf->GetHeight(PLANAR_A));\n  }\n  return min(tail, vf->GetFrameBuffer()->GetDataSize() + (int)GetFrameHead(vf));\n}\n\nclass CPUDevice : public Device {\npublic:\n  CPUDevice(InternalEnvironment* env)\n    : Device(DEV_TYPE_CPU, 0, 0, env)\n  { }\n\n  virtual int SetMemoryMax(int mem)\n  {\n    // memory_max for CPU device is not implemented here.\n    env->ThrowError(\"Not implemented ...\");\n    return 0;\n  }\n\n  virtual BYTE* Allocate(size_t size, int margin)\n  {\n    size += margin;\n    // Allocate a bit more, so we can safely use a 64 byte (512 bits AVX512) load even from\n    // the last pixel of VideoFrameBuffer. Note: NaN contamination over valid scanlines are still a concern\n    // when using 32-bit float data.\n    // Pre 3.7.6 used only 16 bytes (SSE2)\n    constexpr size_t SIMD_OVERREAD_EXTRA_SAFETY = 64;\n#ifdef _DEBUG\n    BYTE* data = new BYTE[size + SIMD_OVERREAD_EXTRA_SAFETY];\n    // fill extra space with recognizable pattern\n    for (auto i = 0; i < SIMD_OVERREAD_EXTRA_SAFETY / 8; ++i) {\n      ((uint64_t*)(data + size))[i] = 0xDEADBEEFDEADBEEF;\n    }\n    // fill allocated memory with recognizable pattern\n    // AllOCA7ED, uneven 5-byte pattern to catch overruns\n    static const BYTE filler[] = { 0x0A, 0x11, 0x0C, 0xA7, 0xED };\n    BYTE* pByte = data;\n    BYTE* q = pByte + size / 5 * 5;\n    for (; pByte < q; pByte += 5)\n    {\n      pByte[0] = filler[0];\n      pByte[1] = filler[1];\n      pByte[2] = filler[2];\n      pByte[3] = filler[3];\n      pByte[4] = filler[4];\n    }\n    return data;\n#else\n    return new BYTE[size + SIMD_OVERREAD_EXTRA_SAFETY];\n#endif\n  }\n\n  virtual void Free(BYTE* ptr)\n  {\n    if (ptr != nullptr) {\n      delete[] ptr;\n    }\n  }\n\n  virtual const char* GetName() const { return \"CPU\"; }\n\n  virtual void AddCompleteCallback(DeviceCompleteCallbackData cbdata)\n  {\n    // no need to delay, call immediately\n    cbdata.cb(cbdata.user_data);\n  }\n\n  virtual std::unique_ptr<std::vector<DeviceCompleteCallbackData>> GetAndClearCallbacks()\n  {\n    return nullptr;\n  }\n\n  virtual void SetActiveToCurrentThread(InternalEnvironment* env)\n  {\n    // do nothing\n  }\n\n  virtual void* GetComputeStream()\n  {\n    return nullptr;\n  }\n\n  virtual void SetDeviceOpt(DeviceOpt opt, int val, InternalEnvironment* env)\n  {\n    // do nothing\n  }\n\n  virtual void GetAlignmentRequirement(int* memoryAlignment, int* pitchAlignment)\n  {\n    *memoryAlignment = FRAME_ALIGN;\n    *pitchAlignment = FRAME_ALIGN;\n  }\n};\n\n#ifdef ENABLE_CUDA\nclass CUDACPUDevice : public CPUDevice {\n  int num_cuda_devices;\n  bool allocated;\n  bool enable_pinned;\npublic:\n  CUDACPUDevice(InternalEnvironment* env, int num_cuda_devices)\n    : CPUDevice(env)\n    , num_cuda_devices(num_cuda_devices)\n    , allocated()\n    , enable_pinned()\n  { }\n\n  virtual BYTE* Allocate(size_t size, int margin)\n  {\n    allocated = true;\n    if (!enable_pinned) {\n      return CPUDevice::Allocate(size, margin);\n    }\n    //unsigned int flags = (prop.canMapHostMemory && prop.unifiedAddressing)\n    //  ? cudaHostAllocMapped : cudaHostAllocDefault;\n    // Without portable flag, allocated memory is associated with one cuda context,\n    // i.e. one GPU. portable flag is required to use this memory with all GPUs.\n    unsigned int flags = (num_cuda_devices > 1)\n      ? cudaHostAllocPortable : cudaHostAllocDefault;\n    BYTE* data = nullptr;\n    size += margin;\n\n    // FIXME check: is extra safety needed for pinned memory like CPUDevice::Allocate\n    // adds extra 64 bytes for SIMD overread safety instead of 16 bytes?\n\n#ifdef _DEBUG\n    CUDA_CHECK(cudaHostAlloc((void**)&data, size + 16, flags));\n    int *pInt = (int *)(data + size);\n    pInt[0] = 0xDEADBEEF;\n    pInt[1] = 0xDEADBEEF;\n    pInt[2] = 0xDEADBEEF;\n    pInt[3] = 0xDEADBEEF;\n\n    static const BYTE filler[] = { 0x0A, 0x11, 0x0C, 0xA7, 0xED };\n    BYTE* pByte = data;\n    BYTE* q = pByte + size / 5 * 5;\n    for (; pByte < q; pByte += 5)\n    {\n      pByte[0] = filler[0];\n      pByte[1] = filler[1];\n      pByte[2] = filler[2];\n      pByte[3] = filler[3];\n      pByte[4] = filler[4];\n    }\n#else\n    CUDA_CHECK(cudaHostAlloc((void**)&data, size + 16, flags));\n#endif\n    return data;\n  }\n\n  virtual void Free(BYTE* ptr)\n  {\n    if (!enable_pinned) {\n      CPUDevice::Free(ptr);\n    }\n    else {\n      if (ptr != nullptr) {\n        CUDA_CHECK(cudaFreeHost(ptr));\n      }\n    }\n  }\n\n  virtual const char* GetName() const { return \"CPU(CUDAAware)\"; }\n\n  void SetDeviceOpt(DeviceOpt opt, int val, InternalEnvironment* env)\n  {\n    if (opt == DEV_CUDA_PINNED_HOST) {\n      if (!enable_pinned) {\n        if (allocated) {\n          env->ThrowError(\"SetDeviceOpt: Allocation mode change must be done before any frame allocation.\");\n        }\n        enable_pinned = true;\n      }\n    }\n    if (opt == DEV_FREE_THRESHOLD) {\n      free_thresh = val;\n    }\n  }\n\n  virtual void GetAlignmentRequirement(int* memoryAlignment, int* pitchAlignment)\n  {\n    *memoryAlignment = FRAME_ALIGN;\n    *pitchAlignment = FRAME_ALIGN;\n  }\n};\n#endif\n\n#ifdef ENABLE_CUDA\nclass CUDADevice : public Device {\n  class ScopedCUDADevice\n  {\n    int old_device;\n    int tgt_device;\n  public:\n    ScopedCUDADevice(int device_index, IScriptEnvironment* env)\n      : tgt_device(device_index)\n    {\n      CUDA_CHECK(cudaGetDevice(&old_device));\n      if (tgt_device != old_device) {\n        CUDA_CHECK(cudaSetDevice(tgt_device));\n      }\n    }\n    ~ScopedCUDADevice()\n    {\n      if (tgt_device != old_device) {\n        cudaSetDevice(old_device);\n      }\n    }\n  };\n\n  char name[32];\n\n  cudaDeviceProp prop;\n\n  std::mutex mutex;\n  std::vector<DeviceCompleteCallbackData> callbacks;\n\n#if ENABLE_CUDA_COMPUTE_STREAM\n  cudaStream_t computeStream;\n  cudaEvent_t computeEvent;\n#endif\n\npublic:\n  CUDADevice(int id, int n, InternalEnvironment* env) :\n    Device(DEV_TYPE_CUDA, id, n, env)\n  {\n    sprintf_s(name, \"CUDA %d\", n);\n\n    ScopedCUDADevice d(device_index, env);\n\n    CUDA_CHECK(cudaGetDeviceProperties(&prop, device_index));\n\n    SetMemoryMax(768); // start with 768MB\n#if ENABLE_CUDA_COMPUTE_STREAM\n    CUDA_CHECK(cudaStreamCreate(&computeStream));\n    CUDA_CHECK(cudaEventCreate(&computeEvent));\n#endif\n  }\n\n  ~CUDADevice()\n  {\n#if ENABLE_CUDA_COMPUTE_STREAM\n    cudaStreamDestroy(computeStream);\n    cudaEventDestroy(computeEvent);\n#endif\n  }\n\n  virtual int SetMemoryMax(int mem)\n  {\n    if (mem > 0) {\n      uint64_t requested = mem * 1048576ull;\n      uint64_t mem_limit = prop.totalGlobalMem;\n      memory_max = clamp(requested, (uint64_t)(64 * 1024 * 1024ull), (uint64_t)(mem_limit - 128 * 1024 * 1024ull));\n    }\n    return (int)(memory_max / 1048576ull);\n  }\n\n  virtual BYTE* Allocate(size_t size, int margin)\n  {\n    BYTE* data = nullptr;\n    ScopedCUDADevice d(device_index, env);\n    CUDA_CHECK(cudaMalloc((void**)&data, size));\n    return data;\n  }\n\n  virtual void Free(BYTE* ptr)\n  {\n    if (ptr != NULL) {\n      ScopedCUDADevice d(device_index, env);\n      CUDA_CHECK(cudaFree(ptr));\n    }\n  }\n\n  virtual const char* GetName() const { return name; }\n\n  virtual void AddCompleteCallback(DeviceCompleteCallbackData cbdata)\n  {\n    std::lock_guard<std::mutex> lock(mutex);\n\n    callbacks.push_back(cbdata);\n  }\n\n  virtual std::unique_ptr<std::vector<DeviceCompleteCallbackData>> GetAndClearCallbacks()\n  {\n    std::lock_guard<std::mutex> lock(mutex);\n\n    if (callbacks.size() > 0) {\n      auto *ret = new std::vector<DeviceCompleteCallbackData>(std::move(callbacks));\n      callbacks.clear();\n      return std::unique_ptr<std::vector<DeviceCompleteCallbackData>>(ret);\n    }\n\n    return nullptr;\n  }\n\n  virtual void SetActiveToCurrentThread(InternalEnvironment* env)\n  {\n    CUDA_CHECK(cudaSetDevice(device_index));\n  }\n\n  virtual void* GetComputeStream() {\n#if ENABLE_CUDA_COMPUTE_STREAM\n    return computeStream;\n#else\n    return nullptr;\n#endif\n  }\n\n  void MakeStreamWaitCompute(cudaStream_t stream, InternalEnvironment* env)\n  {\n#if ENABLE_CUDA_COMPUTE_STREAM\n    std::lock_guard<std::mutex> lock(mutex);\n\n    CUDA_CHECK(cudaEventRecord(computeEvent, computeStream));\n    CUDA_CHECK(cudaStreamWaitEvent(stream, computeEvent, 0));\n#endif\n  }\n\n  void SetDeviceOpt(DeviceOpt opt, int val, InternalEnvironment* env) {\n    if (opt == DEV_FREE_THRESHOLD) {\n      free_thresh = val;\n    }\n  }\n\n  virtual void GetAlignmentRequirement(int* memoryAlignment, int* pitchAlignment)\n  {\n    *memoryAlignment = (int)prop.textureAlignment;\n    *pitchAlignment = (int)prop.texturePitchAlignment;\n  }\n};\n#endif\n\nDeviceManager::DeviceManager(InternalEnvironment* env) :\n  env(env)\n{\n  // 0 is CPU device, start from 1 for other devices.\n  int next_device_id = 1;\n\n#ifdef ENABLE_CUDA\n  int cuda_device_count = 0;\n  cudaError_t status = cudaGetDeviceCount(&cuda_device_count);\n  if (status == cudaSuccess) {\n    // _RPT0(0, \"cudaGetDeviceCount = %d\\r\\n\", cuda_device_count);\n    for (int i = 0; i < cuda_device_count; ++i) {\n      cudaDevices.emplace_back(new CUDADevice(next_device_id++, i, env));\n    }\n  }\n  else {\n    if (status == cudaErrorInitializationError) {\n      // We probably get this error because of current Nvidia driver version is lower than\n      // the minimum required version by the used CUDA SDK, or a Computing Capability is too low.\n      // Example: GTX460: Latest driver is 391.35, latest supporting CUDA SDK is 9.1.85\n      // Consequence: since SDK 9 is unsupported in VS2019, no GTX460 support\n      // As of Jan.2021 Avisynth+ is is using CUDA Toolkit version 11.2.\n      int version;\n      status = cudaRuntimeGetVersion(&version);\n      if(status == cudaSuccess)\n        _RPT1(0, \"cudaGetDeviceCount: cudaErrorInitializationError!\\r\\nMaybe CUDA Runtime version (%d) does not support old drivers. \\r\\n\", version);\n      else\n        _RPT0(0, \"cudaGetDeviceCount: cudaErrorInitializationError! Runtime version request failed\\r\\n\");\n    }\n    else {\n      _RPT1(0, \"cudaGetDeviceCount failed (%d)\\r\\n\", (int)status);\n    }\n  }\n  // do not modify CUDADevices after this since it causes pointer change\n\n  cpuDevice = std::unique_ptr<Device>((cuda_device_count > 0)\n    ? new CUDACPUDevice(env, cuda_device_count)\n    : new CPUDevice(env));\n#else // ENABLE_CUDA\n  cpuDevice = std::unique_ptr<CPUDevice>(new CPUDevice(env));\n#endif // ENABLE_CUDA\n\n  numDevices = next_device_id;\n}\n\nDevice* DeviceManager::GetDevice(AvsDeviceType device_type, int device_index) const\n{\n  switch (device_type) {\n\n  case DEV_TYPE_CPU:\n    return cpuDevice.get();\n\n  case DEV_TYPE_CUDA:\n#ifdef ENABLE_CUDA\n    if (device_index < 0) {\n      env->ThrowError(\"Invalid device index %d\", device_index);\n    }\n    if (cudaDevices.size() == 0) {\n      env->ThrowError(\"No CUDA devices ...\");\n    }\n    // wrap index\n    device_index %= (int)cudaDevices.size();\n    return cudaDevices[device_index].get();\n#else\n    env->ThrowError(\"This Avisynth does not support memory type %d (CUDA)\", device_type);\n#endif\n\n  default:\n    env->ThrowError(\"Not supported memory type %d\", device_type);\n  }\n  return nullptr;\n}\n\nint DeviceManager::GetNumDevices(AvsDeviceType device_type) const\n{\n  switch (device_type) {\n\n  case DEV_TYPE_CPU:\n    return 1;\n\n  case DEV_TYPE_CUDA:\n    return (int)cudaDevices.size();\n\n  default:\n    env->ThrowError(\"Not supported memory type %d\", device_type);\n  }\n  return 0;\n}\n\nvoid DeviceManager::SetDeviceOpt(DeviceOpt opt, int val, InternalEnvironment* env)\n{\n  cpuDevice->SetDeviceOpt(opt, val, env);\n#ifdef ENABLE_CUDA\n  for (auto& dev : cudaDevices) {\n    dev->SetDeviceOpt(opt, val, env);\n  }\n#endif // #ifdef ENABLE_CUDA\n}\n\nDeviceSetter::DeviceSetter(InternalEnvironment* env, Device* upstreamDevice)\n  : env(env)\n{\n  downstreamDevice = env->SetCurrentDevice(upstreamDevice);\n  if (downstreamDevice == nullptr) {\n    env->ThrowError(\"This thread is not created by AviSynth. It is not allowed to invoke script on this thread ...\");\n  }\n}\n\nDeviceSetter::~DeviceSetter()\n{\n  env->SetCurrentDevice(downstreamDevice);\n}\n\nclass QueuePrefetcher\n{\n  PClip child;\n  VideoInfo vi;\n\n  int prefetchFrames;\n  int numThreads;\n\n  ThreadPool* threadPool;\n  Device* device;\n\n  typedef LruCache<size_t, PVideoFrame> CacheType;\n\n  std::shared_ptr<CacheType> videoCache;\n\n  std::mutex mutex; // do not acceess to videoCache during locked by this mutex\n  std::deque<std::pair<size_t, CacheType::handle>> prefetchQueue;\n  int numWorkers;\n  std::exception_ptr workerException;\n  bool workerExceptionPresent;\n\n  static AVSValue ThreadWorker_(IScriptEnvironment2* env, void* data)\n  {\n    return static_cast<QueuePrefetcher*>(data)->ThreadWorker(\n      static_cast<InternalEnvironment*>(env));\n  }\n\n  AVSValue ThreadWorker(InternalEnvironment* env)\n  {\n    device->SetActiveToCurrentThread(env);\n\n    while (true) {\n      std::pair<size_t, CacheType::handle> work;\n      {\n        std::lock_guard<std::mutex> lock(mutex);\n        if (prefetchQueue.size() == 0) {\n          // there are no prefetch work\n          --numWorkers;\n          break;\n        }\n        work = prefetchQueue.front();\n        prefetchQueue.pop_front();\n      }\n\n      try\n      {\n        work.second.first->value = child->GetFrame((int)work.first, env);\n        videoCache->commit_value(&work.second);\n      }\n      catch (...)\n      {\n        {\n          std::lock_guard<std::mutex> lock(mutex);\n          workerException = std::current_exception();\n          workerExceptionPresent = true;\n        }\n        videoCache->rollback(&work.second);\n      }\n    }\n\n    return AVSValue();\n  }\n\n  void SchedulePrefetch(int currentN, InternalEnvironment* env)\n  {\n    int numQueued = 0;\n    for (int n = currentN + 1;\n      (n < currentN + prefetchFrames) && (n < vi.num_frames);\n      ++n)\n    {\n      PVideoFrame result;\n      CacheType::handle cacheHandle;\n      switch (videoCache->lookup(n, &cacheHandle, false, result))\n      {\n      case LRU_LOOKUP_NOT_FOUND:\n      {\n        std::lock_guard<std::mutex> lock(mutex);\n        prefetchQueue.emplace_back(n, cacheHandle);\n        ++numQueued;\n        break;\n      }\n      case LRU_LOOKUP_FOUND_AND_READY:      // Fall-through intentional\n      case LRU_LOOKUP_NO_CACHE:             // Fall-through intentional\n      case LRU_LOOKUP_FOUND_BUT_NOTAVAIL:\n      {\n        break;\n      }\n      default:\n      {\n        env->ThrowError(\"Invalid Program\");\n        break;\n      }\n      }\n    }\n    // wake up sleeping thread\n    if (numQueued > 0) {\n      std::lock_guard<std::mutex> lock(mutex);\n      for (; numWorkers < numThreads && numQueued > 0; ++numWorkers, --numQueued) {\n        threadPool->QueueJob(ThreadWorker_, this, env, nullptr);\n      }\n    }\n  }\n\npublic:\n  QueuePrefetcher(PClip child, int prefetchFrames, int numThreads, Device* device, InternalEnvironment* env) :\n    child(child),\n    vi(child->GetVideoInfo()),\n    prefetchFrames(prefetchFrames),\n    numThreads(numThreads),\n    threadPool(NULL),\n    device(device),\n    videoCache(NULL),\n    numWorkers(0),\n    workerExceptionPresent(false)\n  {\n    if (numThreads > 0 && prefetchFrames > 0) {\n      threadPool = env->NewThreadPool(numThreads);\n      videoCache = std::shared_ptr<CacheType>(new CacheType(prefetchFrames - 1, CACHE_NO_RESIZE));\n    }\n    else {\n      numThreads = prefetchFrames = 0;\n    }\n  }\n\n  ~QueuePrefetcher()\n  {\n    if (numThreads > 0) {\n      // finish threadpool\n      threadPool->Finish();\n\n      // cancel queue\n      while (prefetchQueue.size() > 0) {\n        videoCache->rollback(&prefetchQueue.front().second);\n        prefetchQueue.pop_front();\n      }\n    }\n  }\n\n  VideoInfo GetVideoInfo() const { return vi; }\n\n  PVideoFrame GetFrame(int n, InternalEnvironment* env)\n  {\n    // do not use thread when invoke running\n    if (prefetchFrames == 0 || env->GetSuppressThreadCount() > 0) {\n      return child->GetFrame(n, env);\n    }\n\n    PVideoFrame result;\n    CacheType::handle cacheHandle;\n    switch (videoCache->lookup(n, &cacheHandle, true, result)) {\n    case LRU_LOOKUP_FOUND_AND_READY:\n      break;\n    case LRU_LOOKUP_NOT_FOUND:\n    {\n      try\n      {\n        {\n          std::lock_guard<std::mutex> lock(mutex);\n          // check error\n          if (workerExceptionPresent)\n          {\n            std::rethrow_exception(workerException);\n          }\n        }\n        cacheHandle.first->value = child->GetFrame(n, env);\n        result = cacheHandle.first->value;\n        videoCache->commit_value(&cacheHandle);\n      }\n      catch (...)\n      {\n        videoCache->rollback(&cacheHandle);\n        throw;\n      }\n      break;\n    }\n    case LRU_LOOKUP_NO_CACHE:\n      result = child->GetFrame(n, env);\n      break;\n    case LRU_LOOKUP_FOUND_BUT_NOTAVAIL:   // Fall-through intentional\n    default:\n      env->ThrowError(\"Invalid Program\");\n      break;\n    }\n\n    SchedulePrefetch(n, env);\n\n    return result;\n  }\n};\n\nclass FrameTransferEngine\n{\npublic:\n  QueuePrefetcher& child;\n  VideoInfo vi;\n\n  Device* upstreamDevice;\n  Device* downstreamDevice;\n\n  FrameTransferEngine(QueuePrefetcher& child, Device* upstreamDevice, Device* downstreamDevice) :\n    child(child),\n    vi(child.GetVideoInfo()),\n    upstreamDevice(upstreamDevice),\n    downstreamDevice(downstreamDevice)\n  { }\n\n  virtual ~FrameTransferEngine() { }\n\n  virtual PVideoFrame GetFrame(int n, InternalEnvironment* env) = 0;\n};\n\n#ifdef ENABLE_CUDA\nclass CUDAFrameTransferEngine : public FrameTransferEngine\n{\n  typedef LruCache<size_t, PVideoFrame> CacheType;\n\n  struct QueueItem {\n    size_t n;\n    PVideoFrame src;\n    CacheType::handle cacheHandle;\n    cudaEvent_t completeEvent;\n    std::unique_ptr<std::vector<DeviceCompleteCallbackData>> completeCallbacks;\n  };\n\n  int prefetchFrames;\n\n  std::shared_ptr<CacheType> videoCache;\n\n  std::mutex mutex;\n  cudaStream_t stream;\n  std::deque<QueueItem> prefetchQueue;\n\n  cudaMemcpyKind GetMemcpyKind()\n  {\n    if (upstreamDevice->device_type == DEV_TYPE_CPU && downstreamDevice->device_type == DEV_TYPE_CUDA) {\n      // Host to Device\n      return cudaMemcpyHostToDevice;\n    }\n    if (upstreamDevice->device_type == DEV_TYPE_CUDA && downstreamDevice->device_type == DEV_TYPE_CPU) {\n      // Device to Host\n      return cudaMemcpyDeviceToHost;\n    }\n    if (upstreamDevice->device_type == DEV_TYPE_CUDA && downstreamDevice->device_type == DEV_TYPE_CUDA) {\n      // Device to Device\n      return cudaMemcpyDeviceToDevice;\n    }\n    _ASSERT(false);\n    return cudaMemcpyDefault;\n  }\n\n  void ExecuteCallbacks(const std::vector<DeviceCompleteCallbackData>* callbacks)\n  {\n    if (callbacks != nullptr) {\n      for (auto cbdata : *callbacks) {\n        cbdata.cb(cbdata.user_data);\n      }\n    }\n  }\n\n  void TransferFrameData(PVideoFrame& dst, PVideoFrame& src, bool async, InternalEnvironment* env)\n  {\n    size_t srchead = GetFrameHead(src);\n    size_t sz = GetFrameTail(src) - srchead;\n    const BYTE* srcptr = src->GetFrameBuffer()->GetReadPtr() + srchead;\n    BYTE* dstptr = dst->GetFrameBuffer()->GetWritePtr() + GetFrameHead(dst);\n    cudaMemcpyKind kind = GetMemcpyKind();\n\n    if (async) {\n      CUDA_CHECK(cudaMemcpyAsync(dstptr, srcptr, sz, kind, stream));\n    }\n    else {\n      CUDA_CHECK(cudaMemcpy(dstptr, srcptr, sz, kind));\n    }\n  }\n\n  PVideoFrame GetFrameImmediate(int n, InternalEnvironment* env)\n  {\n    PVideoFrame src = child.GetFrame(n, env);\n    PVideoFrame dst = env->GetOnDeviceFrame(src, downstreamDevice);\n    TransferFrameData(dst, src, false, env);\n\n#if 1\n    AVSMap* mapv = env->getFramePropsRW(dst);\n    const int numKeys = env->propNumKeys(mapv);\n    for (int i = 0; i < numKeys; i++) {\n      const char* key = env->propGetKey(mapv, i);\n      if (env->propGetType(mapv, key) == AVSPropTypes::PROPTYPE_FRAME) {\n        // isFrame true\n        const int numElements = env->propNumElements(mapv, key);\n\n        std::vector<PVideoFrame> frameset;\n        int error;\n        // avs+: can be more frames in a frame property array\n        for (int index = 0; index < numElements; index++) {\n          const PVideoFrame srcframe = env->propGetFrame(mapv, key, index, &error);\n          frameset.push_back(srcframe);\n        }\n\n        env->propDeleteKey(mapv, key);\n\n        for (int index = 0; index < numElements; index++) {\n          PVideoFrame src = frameset[index];\n          PVideoFrame dst = env->GetOnDeviceFrame(src, downstreamDevice);\n          TransferFrameData(dst, src, false, env);\n          env->propSetFrame(mapv, key, dst, AVSPropAppendMode::PROPAPPENDMODE_APPEND);\n        }\n      }\n    }\n#else\n    // kept for reference from neo fork, a single frame in frame properties. No array of frames here\n    AVSMap* mapv = env->GetAVSMap(dst);\n    for (auto it = mapv->data.begin(), end = mapv->data.end(); it != end; ++it) {\n      if (it->second.IsFrame()) {\n        PVideoFrame src = it->second.GetFrame();\n        PVideoFrame dst = env->GetOnDeviceFrame(src, downstreamDevice);\n        TransferFrameData(dst, src, false, env);\n        it->second = dst;\n      }\n    }\n#endif\n    ExecuteCallbacks(downstreamDevice->GetAndClearCallbacks().get());\n\n    return dst;\n  }\n\n  QueueItem SetupTransfer(int n, CacheType::handle& cacheHandle, InternalEnvironment* env)\n  {\n    QueueItem item = { (size_t)n, child.GetFrame(n, env), cacheHandle, nullptr, nullptr };\n    cacheHandle.first->value = env->GetOnDeviceFrame(item.src, downstreamDevice);\n    CUDA_CHECK(cudaEventCreate(&item.completeEvent));\n\n    item.completeCallbacks = upstreamDevice->GetAndClearCallbacks();\n\n    if (upstreamDevice->device_type == DEV_TYPE_CUDA) {\n      static_cast<CUDADevice*>(upstreamDevice)->MakeStreamWaitCompute(stream, env);\n    }\n\n    TransferFrameData(cacheHandle.first->value, item.src, true, env);\n\n#if 1\n    AVSMap* mapv = env->getFramePropsRW(cacheHandle.first->value);\n    const int numKeys = env->propNumKeys(mapv);\n    for (int i = 0; i < numKeys; i++) {\n      const char* key = env->propGetKey(mapv, i);\n      if (env->propGetType(mapv, key) == AVSPropTypes::PROPTYPE_FRAME) {\n        // isFrame true\n        const int numElements = env->propNumElements(mapv, key);\n\n        std::vector<PVideoFrame> frameset;\n        int error;\n        // avs+: can be more frames in a frame property array\n        for (int index = 0; index < numElements; index++) {\n          const PVideoFrame srcframe = env->propGetFrame(mapv, key, index, &error);\n          frameset.push_back(srcframe);\n        }\n\n        env->propDeleteKey(mapv, key);\n\n        for (int index = 0; index < numElements; index++) {\n          PVideoFrame src = frameset[index];\n          PVideoFrame dst = env->GetOnDeviceFrame(src, downstreamDevice);\n          TransferFrameData(dst, src, true, env);\n          env->propSetFrame(mapv, key, dst, AVSPropAppendMode::PROPAPPENDMODE_APPEND);\n        }\n      }\n    }\n#else\n    // kept for reference from neo fork, a single frame in frame properties. No frame arrays here\n    AVSMap* mapv = env->GetAVSMap(cacheHandle.first->value);\n    for (auto it = mapv->data.begin(), end = mapv->data.end(); it != end; ++it) {\n      if (it->second.IsFrame()) {\n        PVideoFrame src = it->second.GetFrame();\n        PVideoFrame dst = env->GetOnDeviceFrame(src, downstreamDevice);\n        TransferFrameData(dst, src, true, env);\n        it->second = dst;\n      }\n    }\n#endif\n\n    CUDA_CHECK(cudaEventRecord(item.completeEvent, stream));\n\n    return std::move(item);\n  }\n\n  int SchedulePrefetch(int currentN, int prefetchStart, InternalEnvironment* env)\n  {\n    int numQueued = 0;\n    int n = prefetchStart;\n    for (; n < currentN + prefetchFrames && n < vi.num_frames; ++n)\n    {\n      PVideoFrame result;\n      CacheType::handle cacheHandle;\n      switch (videoCache->lookup(n, &cacheHandle, false, result))\n      {\n      case LRU_LOOKUP_NOT_FOUND:\n      {\n        try {\n          prefetchQueue.emplace_back(SetupTransfer(n, cacheHandle, env));\n        }\n        catch (...) {\n          videoCache->rollback(&cacheHandle);\n          throw;\n        }\n        break;\n      }\n      case LRU_LOOKUP_FOUND_AND_READY:      // Fall-through intentional\n      case LRU_LOOKUP_NO_CACHE:             // Fall-through intentional\n      case LRU_LOOKUP_FOUND_BUT_NOTAVAIL:\n      {\n        break;\n      }\n      default:\n      {\n        env->ThrowError(\"Invalid Program\");\n        break;\n      }\n      }\n    }\n    return n;\n  }\n\n  void FinishCompleted(InternalEnvironment* env)\n  {\n    while (prefetchQueue.size() > 0) {\n      QueueItem& item = prefetchQueue.front();\n      cudaError_t err = cudaEventQuery(item.completeEvent);\n      if (err == cudaErrorNotReady) {\n        break;\n      }\n      try {\n        CUDA_CHECK(err);\n\n        // transfer is complete\n        CUDA_CHECK(cudaEventDestroy(item.completeEvent));\n        ExecuteCallbacks(item.completeCallbacks.get());\n\n        videoCache->commit_value(&item.cacheHandle);\n      }\n      catch (...) {\n        videoCache->rollback(&item.cacheHandle);\n        throw;\n      }\n      prefetchQueue.pop_front();\n    }\n  }\n\n  PVideoFrame WaitUntil(int n, InternalEnvironment* env)\n  {\n    while (prefetchQueue.size() > 0) {\n      QueueItem& item = prefetchQueue.front();\n      try {\n        CUDA_CHECK(cudaEventSynchronize(item.completeEvent));\n        CUDA_CHECK(cudaEventDestroy(item.completeEvent));\n        ExecuteCallbacks(item.completeCallbacks.get());\n\n        PVideoFrame frame = item.cacheHandle.first->value; // fill before Commit !!!\n\n        videoCache->commit_value(&item.cacheHandle);\n\n        if (item.n == n) {\n          prefetchQueue.pop_front();\n          return frame;\n        }\n\n        prefetchQueue.pop_front();\n      }\n      catch (...) {\n        videoCache->rollback(&item.cacheHandle);\n        throw;\n      }\n    }\n    env->ThrowError(\"invalid program\");\n    return PVideoFrame();\n  }\n\n  void CheckDevicePair(InternalEnvironment* env)\n  {\n    if (upstreamDevice->device_type == DEV_TYPE_CPU && downstreamDevice->device_type == DEV_TYPE_CUDA) {\n      // Host to Device\n      return;\n    }\n    if (upstreamDevice->device_type == DEV_TYPE_CUDA && downstreamDevice->device_type == DEV_TYPE_CPU) {\n      // Device to Host\n      return;\n    }\n    if (upstreamDevice->device_type == DEV_TYPE_CUDA && downstreamDevice->device_type == DEV_TYPE_CUDA) {\n      // Device to Device\n      return;\n    }\n    env->ThrowError(\"[CUDAFrameTransferEngine] invalid device pair up:%s down:%d\",\n      upstreamDevice->GetName(), downstreamDevice->GetName());\n  }\n\npublic:\n  CUDAFrameTransferEngine(QueuePrefetcher& child, Device* upstreamDevice, Device* downstreamDevice, int prefetchFrames, InternalEnvironment* env) :\n    FrameTransferEngine(child, upstreamDevice, downstreamDevice),\n    prefetchFrames(prefetchFrames),\n    videoCache(new CacheType(std::max(0, prefetchFrames - 1), CACHE_NO_RESIZE)),\n    stream(nullptr)\n  {\n    CheckDevicePair(env);\n\n    // note: stream belongs to a device\n    upstreamDevice->SetActiveToCurrentThread(env);\n    CUDA_CHECK(cudaStreamCreate(&stream));\n  }\n\n  ~CUDAFrameTransferEngine()\n  {\n    for (auto& item : prefetchQueue) {\n      cudaEventSynchronize(item.completeEvent);\n      cudaEventDestroy(item.completeEvent);\n      ExecuteCallbacks(item.completeCallbacks.get());\n      videoCache->commit_value(&item.cacheHandle);\n    }\n    prefetchQueue.clear();\n\n    cudaStreamDestroy(stream);\n  }\n\n  virtual PVideoFrame GetFrame(int n, InternalEnvironment* env)\n  {\n    // Giant lock. This is OK because all transfer is done asynchronously\n    std::lock_guard<std::mutex> lock(mutex);\n\n    // set upstream device\n    upstreamDevice->SetActiveToCurrentThread(env);\n\n    // do not use thread when invoke running\n    if (prefetchFrames == 0 || env->GetSuppressThreadCount() > 0) {\n      return GetFrameImmediate(n, env);\n    }\n\n    FinishCompleted(env);\n\n    SchedulePrefetch(n, n, env);\n\n    // Get requested frame\n    PVideoFrame result;\n    CacheType::handle cacheHandle;\n    // fill result if LRU_LOOKUP_FOUND_AND_READY\n    switch (videoCache->lookup(n, &cacheHandle, false, result))\n    {\n    case LRU_LOOKUP_FOUND_AND_READY:\n    {\n      break;\n    }\n    case LRU_LOOKUP_NO_CACHE:\n    {\n      result = GetFrameImmediate(n, env);\n      break;\n    }\n    case LRU_LOOKUP_FOUND_BUT_NOTAVAIL:\n    {\n      // now transferring, wait until completion\n      result = WaitUntil(n, env);\n      break;\n    }\n    case LRU_LOOKUP_NOT_FOUND:\n    {\n      env->ThrowError(\"Oh.. maybe cache size is too small ...\");\n      break;\n    }\n    default:\n    {\n      env->ThrowError(\"Invalid Program\");\n      break;\n    }\n    }\n\n    // set downstreamdevice\n    downstreamDevice->SetActiveToCurrentThread(env);\n\n    return result;\n  }\n};\n#endif\n\nFrameTransferEngine* CreateTransferEngine(QueuePrefetcher& child,\n  Device* upstreamDevice, Device* downstreamDevice, int prefetchFrames, InternalEnvironment* env)\n{\n#ifdef ENABLE_CUDA\n  if (upstreamDevice->device_type == DEV_TYPE_CPU && downstreamDevice->device_type == DEV_TYPE_CUDA) {\n    // CPU to CUDA\n    return new CUDAFrameTransferEngine(child, upstreamDevice, downstreamDevice, prefetchFrames, env);\n  }\n  if (upstreamDevice->device_type == DEV_TYPE_CUDA && downstreamDevice->device_type == DEV_TYPE_CPU) {\n    // CUDA to CPU\n    return new CUDAFrameTransferEngine(child, upstreamDevice, downstreamDevice, prefetchFrames, env);\n  }\n  if (upstreamDevice->device_type == DEV_TYPE_CUDA && downstreamDevice->device_type == DEV_TYPE_CUDA) {\n    // CUDA to CUDA\n    return new CUDAFrameTransferEngine(child, upstreamDevice, downstreamDevice, prefetchFrames, env);\n  }\n#endif\n  env->ThrowError(\"Not supported frame data transfer. up:%s down:%d\",\n    upstreamDevice->GetName(), downstreamDevice->GetName());\n  return nullptr;\n}\n\nclass OnDevice : public GenericVideoFilter\n{\n  Device* upstreamDevice;\n  int prefetchFrames;\n\n  QueuePrefetcher prefetcher;\n\n  std::mutex mutex;\n  std::map<Device*, std::unique_ptr<FrameTransferEngine>> transferEngines;\n\n  FrameTransferEngine* GetOrCreateTransferEngine(Device* downstreamDevice, InternalEnvironment* env)\n  {\n    std::lock_guard<std::mutex> lock(mutex);\n    auto it = transferEngines.find(downstreamDevice);\n    if (it != transferEngines.end()) {\n      return it->second.get();\n    }\n    int transferPrefetch = (prefetchFrames == 1) ? 2 : prefetchFrames;\n    auto pEngine = CreateTransferEngine(prefetcher, upstreamDevice, downstreamDevice, transferPrefetch, env);\n    transferEngines[downstreamDevice] = std::unique_ptr<FrameTransferEngine>(pEngine);\n    return pEngine;\n  }\n\npublic:\n  OnDevice(PClip child, int prefetchFrames, Device* upstreamDevice, InternalEnvironment* env) :\n    GenericVideoFilter(child),\n    upstreamDevice(upstreamDevice),\n    prefetchFrames(prefetchFrames),\n    prefetcher(child, (prefetchFrames >= 2) ? 2 : 0, (prefetchFrames >= 2) ? 1 : 0, upstreamDevice, env)\n  { }\n\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env_)\n  {\n    InternalEnvironment* env = GetAndRevealCamouflagedEnv(env_);\n    Device* downstreamDevice = env->SetCurrentDevice(upstreamDevice);\n\n    if (downstreamDevice == nullptr) {\n      env->ThrowError(\"This thread is not created by AviSynth. It is not allowed to call GetFrame on this thread ...\");\n    }\n\n    if (downstreamDevice == upstreamDevice) {\n      // shortcut\n      return child->GetFrame(n, env);\n    }\n\n    // Get frame via transfer engine\n    PVideoFrame frame = GetOrCreateTransferEngine(downstreamDevice, env)->GetFrame(n, env);\n\n    env->SetCurrentDevice(downstreamDevice);\n    return frame;\n  }\n\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env_)\n  {\n    InternalEnvironment* env = GetAndRevealCamouflagedEnv(env_);\n    Device* downstreamDevice = env->SetCurrentDevice(upstreamDevice);\n    try {\n      child->GetAudio(buf, start, count, env);\n      env->SetCurrentDevice(downstreamDevice);\n    }\n    catch (...) {\n      env->SetCurrentDevice(downstreamDevice);\n      throw;\n    }\n  }\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range)\n  {\n    if (cachehints == CACHE_GET_MTMODE) {\n      return MT_NICE_FILTER;\n    }\n    if (cachehints == CACHE_GET_DEV_TYPE) {\n      return DEV_TYPE_ANY;\n    }\n    if (cachehints == CACHE_GET_CHILD_DEV_TYPE) {\n      return upstreamDevice->device_type;\n    }\n    return 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void* user_data, IScriptEnvironment* env_)\n  {\n    AvsDeviceType upstreamType = (AvsDeviceType)(size_t)user_data;\n    InternalEnvironment* env = static_cast<InternalEnvironment*>(env_);\n\n    if (args[0].IsClip()) {\n      PClip clip = args[0].AsClip();\n      int numPrefetch = args[1].Defined() ? args[1].AsInt() : 1;\n      int upstreamIndex = (args.ArraySize() >= 3 && args[2].Defined()) ? args[2].AsInt() : 0;\n\n      if (numPrefetch < 0) {\n        numPrefetch = 0;\n      }\n\n      switch (upstreamType) {\n      case DEV_TYPE_CPU:\n        return new OnDevice(clip, numPrefetch, (Device*)(void*)env->GetDevice(DEV_TYPE_CPU, 0), env);\n      case DEV_TYPE_CUDA:\n        return new OnDevice(clip, numPrefetch, (Device*)(void*)env->GetDevice(DEV_TYPE_CUDA, upstreamIndex), env);\n      default:\n        env->ThrowError(\"Not supported device ...\");\n        return AVSValue();\n      }\n\n    }\n    else {\n      assert(args[0].IsFunction());\n      PFunction func = args[0].AsFunction();\n      int upstreamIndex = (args.ArraySize() >= 2 && args[1].Defined()) ? args[1].AsInt() : 0;\n\n      Device* upstreamDevice = nullptr;\n      switch (upstreamType) {\n      case DEV_TYPE_CPU:\n        upstreamDevice = (Device*)(void*)env->GetDevice(DEV_TYPE_CPU, 0);\n        break;\n      case DEV_TYPE_CUDA:\n        upstreamDevice = (Device*)(void*)env->GetDevice(DEV_TYPE_CUDA, upstreamIndex);\n        break;\n      default:\n        env->ThrowError(\"Not supported device ...\");\n        break;\n      }\n\n      DeviceSetter setter(env, upstreamDevice);\n\n      try {\n        AVSValue ret = env->Invoke3(AVSValue(), func, AVSValue(nullptr, 0));\n        return ret;\n      }\n      catch (IScriptEnvironment::NotFound) {\n        const char* name = (upstreamType == DEV_TYPE_CPU) ? \"OnCPU\" : \"OnCUDA\";\n        env->ThrowError(\n          \"%s: Invalid function parameter type '%s'(%s)\\n\"\n          \"Function should have no argument\",\n          name, func->GetDefinition()->param_types, func->ToString(env));\n      }\n\n      return AVSValue();\n    }\n  }\n};\n\nvoid CopyCUDAFrame(const PVideoFrame& dst, const PVideoFrame& src, InternalEnvironment* env, bool sync)\n{\n#ifdef ENABLE_CUDA\n  size_t srchead = GetFrameHead(src);\n  size_t sz = GetFrameTail(src) - srchead;\n  const BYTE* srcptr = src->GetFrameBuffer()->GetReadPtr() + srchead;\n  BYTE* dstptr = dst->GetFrameBuffer()->GetWritePtr() + GetFrameHead(dst);\n\n  AvsDeviceType srcDevice = src->GetDevice()->device_type;\n  AvsDeviceType dstDevice = dst->GetDevice()->device_type;\n  cudaMemcpyKind kind = cudaMemcpyHostToHost;\n\n  if (srcDevice == DEV_TYPE_CPU && dstDevice == DEV_TYPE_CUDA) {\n    kind = cudaMemcpyHostToDevice;\n  }\n  if (srcDevice == DEV_TYPE_CUDA && dstDevice == DEV_TYPE_CPU) {\n    kind = cudaMemcpyDeviceToHost;\n  }\n  if (srcDevice == DEV_TYPE_CUDA && dstDevice == DEV_TYPE_CUDA) {\n    kind = cudaMemcpyDeviceToDevice;\n  }\n\n  if (sync) {\n    CUDA_CHECK(cudaMemcpy(dstptr, srcptr, sz, kind));\n  }\n  else {\n    CUDA_CHECK(cudaMemcpyAsync(dstptr, srcptr, sz, kind));\n  }\n#else\n  env->ThrowError(\"CopyCUDAFrame: CUDA support is disabled ...\");\n#endif\n}\n\nPVideoFrame GetFrameOnDevice(PClip& c, int n, const PDevice& device, InternalEnvironment* env)\n{\n  DeviceSetter setter(env, (Device*)(void*)device);\n  return c->GetFrame(n, env);\n}\n\nextern const AVSFunction Device_filters[] = {\n  { \"OnCPU\", BUILTIN_FUNC_PREFIX, \"c[num_prefetch]i\", OnDevice::Create, (void*)DEV_TYPE_CPU },\n  { \"OnCUDA\", BUILTIN_FUNC_PREFIX, \"c[num_prefetch]i[device_index]i\", OnDevice::Create, (void*)DEV_TYPE_CUDA },\n  { \"OnCPU\", BUILTIN_FUNC_PREFIX, \"n\", OnDevice::Create, (void*)DEV_TYPE_CPU },\n  { \"OnCUDA\", BUILTIN_FUNC_PREFIX, \"n[device_index]i\", OnDevice::Create, (void*)DEV_TYPE_CUDA },\n  { 0 }\n};\n"
  },
  {
    "path": "avs_core/core/DeviceManager.h",
    "content": "#pragma once\n\n#include <avisynth.h>\n#include <vector>\n#include <atomic>\n#include <memory>\n\nclass InternalEnvironment;\nenum DeviceOpt: int; // forward enum w/o underlying types are MS specific\n\nstruct DeviceCompleteCallbackData {\n  void(*cb)(void*);\n  void* user_data;\n};\n\nclass Device {\nprotected:\n    InternalEnvironment* env;\n\npublic:\n    const AvsDeviceType device_type;\n    const int device_id;\n    const int device_index;\n\n    uint64_t memory_max;\n    std::atomic<uint64_t> memory_used;\n\n    int  free_thresh;\n\n    Device(AvsDeviceType type, int id, int index, InternalEnvironment* env) :\n      env(env),\n      device_type(type),\n      device_id(id),\n      device_index(index),\n      memory_max(0),\n      memory_used(0),\n      free_thresh(0)\n    { }\n\n    virtual ~Device() { }\n\n    virtual int SetMemoryMax(int mem) = 0;\n    virtual BYTE* Allocate(size_t sz, int margin) = 0;\n    virtual void Free(BYTE* ptr) = 0;\n    virtual const char* GetName() const = 0;\n    virtual void AddCompleteCallback(DeviceCompleteCallbackData cbdata) = 0;\n    virtual std::unique_ptr<std::vector<DeviceCompleteCallbackData>> GetAndClearCallbacks() = 0;\n    virtual void SetActiveToCurrentThread(InternalEnvironment* env) = 0;\n    virtual void* GetComputeStream() = 0;\n    virtual void SetDeviceOpt(DeviceOpt opt, int val, InternalEnvironment* env) = 0;\n    virtual void GetAlignmentRequirement(int* memoryAlignment, int* pitchAlignment) = 0;\n};\n\nclass DeviceManager {\nprivate:\n  InternalEnvironment *env;\n  std::unique_ptr<Device> cpuDevice;\n  std::vector<std::unique_ptr<Device>> cudaDevices;\n  int numDevices;\n\npublic:\n    DeviceManager(InternalEnvironment* env);\n    ~DeviceManager() { }\n\n    Device* GetDevice(AvsDeviceType device_type, int device_index) const;\n\n    Device* GetCPUDevice() { return GetDevice(DEV_TYPE_CPU, 0); }\n\n    int GetNumDevices() const { return numDevices; }\n    int GetNumDevices(AvsDeviceType device_type) const;\n\n    void SetDeviceOpt(DeviceOpt opt, int val, InternalEnvironment* env);\n};\n\nclass DeviceSetter {\n  InternalEnvironment* env;\n  Device* downstreamDevice;\npublic:\n  DeviceSetter(InternalEnvironment* env, Device* upstreamDevice);\n  ~DeviceSetter();\n};\n\nvoid CheckChildDeviceTypes(const PClip& child, const char* name, const AVSValue& last,\n  const AVSValue& args, const char* const* argnames, InternalEnvironment* env);\n\nvoid CopyCUDAFrame(const PVideoFrame& dst, const PVideoFrame& src, InternalEnvironment* env, bool sync = false);\n"
  },
  {
    "path": "avs_core/core/FilterConstructor.cpp",
    "content": "#include \"FilterConstructor.h\"\n#include \"avisynth.h\"\n\nFilterConstructor::FilterConstructor(IScriptEnvironment2 * env,\n  IScriptEnvironment_Avs25* env25,\n  IScriptEnvironment_AvsPreV11C* envPreV11C,\n  const Function *func, std::vector<AVSValue>* argStorage, std::vector<AVSValue>* ctorArgs) :\n  Env(env),\n  Env25(env25),\n  EnvPreV11C(envPreV11C),\n  Func(func),\n#if 1\n  ArgStorage(std::move(*argStorage)),\n  CtorArgs(std::move(*ctorArgs))\n#else\n  // no need to move, subarrays could not be returned\n  ArgStorage(*argStorage),\n  CtorArgs(*ctorArgs)\n#endif\n{\n}\n\n\nAVSValue FilterConstructor::InstantiateFilter() const\n{\n  // funcArgs is passed to the function as an array.\n  // Calls the plugin's instance creator, which is usually Filter_Create(AVSValue args, void *user_data, IScriptEnvironment *env)\n  // or create_c_filter\n  AVSValue funcArgs;\n\n  // isPluginAvs25 and isPluginPreV11C cannot accept long and double types in\n  // their parameters passed to them.\n  // Such plugins don't recognize 'l' and 'd' 64-bit types due to direct type field checks in AVSValue/AVS_Value.\n  // IsInt/avs_is_int and IsFloat/avs_is_float check the type field directly in the old header, without an interface call.\n  // New avisynth_c.h supports these types, but old plugins don't.\n  // Thus we convert 64-bit types in the parameter list to 32-bit ones.\n  if (Func->isPluginAvs25 || Func->isPluginPreV11C) {\n    std::vector<AVSValue> funcArgs_temp(CtorArgs.size(), AVSValue());\n    for (auto i = 0; i < (int)CtorArgs.size(); i++) {\n      if (CtorArgs[i].GetType() == AvsValueType::VALUE_TYPE_LONG) // long int64 -> 32 bit int\n        funcArgs_temp[i] = CtorArgs[i].AsInt();\n      else if (CtorArgs[i].GetType() == AvsValueType::VALUE_TYPE_DOUBLE) // double -> float\n        funcArgs_temp[i] = CtorArgs[i].AsFloatf();\n      else\n        funcArgs_temp[i] = CtorArgs[i];\n    }\n    funcArgs = AVSValue(funcArgs_temp.data(), (int)funcArgs_temp.size());\n  }\n  else {\n    funcArgs = AVSValue(CtorArgs.data(), (int)CtorArgs.size());\n  }\n\n  AVSValue retval = Func->apply(funcArgs, Func->user_data, \n    Func->isPluginAvs25 ? (IScriptEnvironment *)Env25 : \n    Func->isPluginPreV11C ? (IScriptEnvironment*)EnvPreV11C : \n    Env);\n  // pass back proper ScriptEnvironment, because a 2.5 plugin e.g. GRunT can back-Invoke ScriptClip\n  if (Func->isPluginAvs25)\n  {\n    // After instantiate a v2.5 \"baked code\" function,\n    // manually release Clips or else clip variables get stuck in memory on exit\n    if (funcArgs.IsArray())\n    {\n      for (int i = 0; i < funcArgs.ArraySize(); i++)\n      {\n        if (funcArgs[i].IsClip()) {\n          IClip* rawClip = (IClip*)(void*)funcArgs[i].AsClip(); // de-smart pointering\n          rawClip->Release();\n        }\n      }\n    }\n    // Problem: AVS 2.5 plugins have \"baked code\", their interface contains direct manipulation, refcount, free of AVSValue resources.\n    // So they do not know about array deep copy and deep free mechanism.\n    // Thus array sub-elements of the parameter AVSValue won't be freed up on exiting of such functions.\n    // Example: CtorArgs contains clip(s) with reference count N\n    // Upon creating funcArgs the \"smart\" array creation will copy the subarray as well.\n    // Because of the deep copy the reference count of these PClip values are increased by 1.\n    // Then funcArgs will be passed to the CPP 2.5 function which won't release the Array content, only destroys the\n    // 'holder' array-typed AVSValue, array elements will be untouched.\n    // So if there is a PClip parameters the Clip's reference count remains N+1, causing memory leak.\n    // This is why we have to release them manually, deferencing the Clip by one, instead of the plugin's code.\n    // If this reference count decrease is not done then env->DeleteScriptEnvironment will not free up everything.\n    // ScriptEnvironment destroy is freeing up variables as well.\n    // If a variable contains such a clip (e.g. \"last\"), it will fail to be released, because such Clip will not reached refcount==0.\n    // e.g. VirtualDub consecutively press \"script reload\"s. Memory will leak even 50-80Mbytes so after a while\n    // memory gets full.\n  }\n  return retval;\n}\n"
  },
  {
    "path": "avs_core/core/FilterConstructor.h",
    "content": "#ifndef _AVS_FILTER_CONSTRUCTOR_H\n#define _AVS_FILTER_CONSTRUCTOR_H\n\n#include \"internal.h\"\n#include <vector>\n\nclass FilterConstructor\n{\nprivate:\n  IScriptEnvironment2* const Env;\n  IScriptEnvironment_Avs25* const Env25;\n  IScriptEnvironment_AvsPreV11C* const EnvPreV11C;\n  const Function* const Func;\n  const std::vector<AVSValue> ArgStorage;\n  const std::vector<AVSValue> CtorArgs;\n\npublic:\n  FilterConstructor(IScriptEnvironment2 * env,\n    IScriptEnvironment_Avs25* env25,\n    IScriptEnvironment_AvsPreV11C* envPreV11C,\n    const Function *func, std::vector<AVSValue>* argStorage, std::vector<AVSValue>* ctorArgs);\n  AVSValue InstantiateFilter() const;\n\n  const char* GetFilterName() const\n  {\n    return Func->name;\n  }\n\n  bool IsScriptFunction() const\n  {\n    return AVSFunction::IsScriptFunction(Func);\n  }\n\n  const Function* GetAvsFunction() const\n  {\n      return Func;\n  }\n};\n\n#endif  // _AVS_FILTER_CONSTRUCTOR_H\n"
  },
  {
    "path": "avs_core/core/FilterGraph.cpp",
    "content": "#include \"avs/config.h\"\n#include \"FilterGraph.h\"\n#include \"DeviceManager.h\"\n#include \"InternalEnvironment.h\"\n#include \"strings.h\"\n\n#ifdef AVS_WINDOWS\n  #include <avs/win.h>\n#else\n  #include <avs/posix.h>\n#endif\n\n#include <map>\n#include <iostream>\n#include <string>\n#include <sstream>\n#include <iomanip>\n\n#include <avs/filesystem.h>\n\nstatic AVSValue DeepCopyValue(std::vector<std::unique_ptr<AVSValue[]>>& arrays, const AVSValue& src) {\n  if (src.IsArray()) {\n    AVSValue* copy = new AVSValue[src.ArraySize()];\n    for (int i = 0; i < src.ArraySize(); ++i) {\n      copy[i] = src[i]; // NEW_AVSVALUE is already doing deep copy\n      // copy[i] = DeepCopyValue(arrays, src[i]);\n    }\n    arrays.emplace_back(std::unique_ptr<AVSValue[]>(copy));\n    return AVSValue(copy, src.ArraySize());\n  }\n  return src;\n}\n\nFilterGraphNode::FilterGraphNode(PClip child, const char* name,\n  const AVSValue& last_, const AVSValue& args_, const char* const* argnames_,\n  IScriptEnvironment* env)\n  : Env(env)\n  , child(child)\n  , name(name)\n  , memory(new GraphMemoryNode())\n{\n  if (last_.Defined()) {\n    std::vector<AVSValue> argstmp;\n    argstmp.push_back(last_);\n    if (argnames_) {\n      argnames.push_back(std::string());\n    }\n    for (int i = 0; i < args_.ArraySize(); ++i) {\n      argstmp.push_back(args_[i]);\n    }\n    args = DeepCopyValue(arrays, AVSValue(argstmp.data(), (int)argstmp.size()));\n  }\n  else {\n    args = DeepCopyValue(arrays, args_.IsArray() ? args_ : AVSValue(args_, 1));\n  }\n\n  if (argnames_) {\n    for (int i = 0; i < args_.ArraySize(); ++i) {\n      argnames.push_back(argnames_[i] ? std::string(argnames_[i]) : std::string());\n    }\n  }\n\n  Env->ManageCache(MC_RegisterGraphNode, this);\n}\n\nFilterGraphNode::~FilterGraphNode()\n{\n  Env->ManageCache(MC_UnRegisterGraphNode, this);\n}\n\nstruct ScopedGraphNode {\n  FilterGraphNode*& target;\n  FilterGraphNode* prev;\n  ScopedGraphNode(FilterGraphNode*& target, FilterGraphNode* node) : target(target) {\n    prev = target;\n    target = node;\n  }\n  ~ScopedGraphNode() {\n    target = prev;\n  }\n};\n\nPVideoFrame __stdcall FilterGraphNode::GetFrame(int n, IScriptEnvironment* env_)\n{\n  InternalEnvironment* env = GetAndRevealCamouflagedEnv(env_);\n\n  ScopedGraphNode scope(env->GetCurrentGraphNode(), this);\n  return child->GetFrame(n, env);\n}\n\nvoid GraphMemoryNode::OnAllocate(size_t bytes, Device* dev)\n{\n  auto it = memory.find(dev);\n  if (it == memory.end()) {\n    memory[dev] = MemoryInfo();\n    it = memory.find(dev);\n  }\n  it->second.numAllocation++;\n  it->second.totalBytes += bytes;\n}\n\nvoid GraphMemoryNode::OnFree(size_t bytes, Device* dev)\n{\n  auto it = memory.find(dev);\n  if (it == memory.end()) {\n    printf(\"Unexpected behavior ...\\n\");\n    return;\n  }\n  it->second.numAllocation--;\n  it->second.totalBytes -= bytes;\n}\n\nclass FilterGraph\n{\nprotected:\n  IScriptEnvironment * env;\n\n  struct NodeInfo {\n    bool isFunction;\n    int number;\n    std::string name;\n    std::string args;\n    std::vector<void*> refNodes;\n\n    int cacheSize;\n    int cacheCapacity;\n    std::map<Device*, GraphMemoryNode::MemoryInfo> memory;\n\n    NodeInfo() { }\n    NodeInfo(int number) : number(number) { }\n  };\n\n  std::map<void*, NodeInfo> nodeMap;\n\n  int DoClip(IClip* pclip) {\n    if (nodeMap.find(pclip) == nodeMap.end()) {\n      nodeMap.insert(std::make_pair(pclip, (int)nodeMap.size()));\n      FilterGraphNode* node = dynamic_cast<FilterGraphNode*>(pclip);\n      if (node != nullptr) {\n        NodeInfo& info = nodeMap[node];\n        info.isFunction = false;\n        info.name = node->name;\n        info.args = \"(\" + DoArray(info, nullptr, node->argnames.data(), node->args) + \")\";\n        info.cacheSize = node->SetCacheHints(CACHE_GET_SIZE, 0);\n        info.cacheCapacity = node->SetCacheHints(CACHE_GET_CAPACITY, 0);\n        info.memory = node->memory->memory;\n      }\n      OutClip(nodeMap[node]);\n    }\n    return nodeMap[pclip].number;\n  }\n\n  int DoFunc(IFunction* pfunc) {\n    if (nodeMap.find(pfunc) == nodeMap.end()) {\n      nodeMap.insert(std::make_pair(pfunc, (int)nodeMap.size()));\n      NodeInfo& info = nodeMap[pfunc];\n      info.isFunction = true;\n      auto captures = pfunc->GetCaptures();\n      info.name = pfunc->ToString(env);\n      info.args = \"[\" + DoArray(info, captures.var_names, nullptr, AVSValue(captures.var_data, captures.count)) + \"]\";\n      info.cacheSize = 0;\n      info.cacheCapacity = 0;\n      OutFunc(info);\n    }\n    return nodeMap[pfunc].number;\n  }\n\n  std::string DoArray(NodeInfo& info, const char** argnames_c, std::string* argnames_s, const AVSValue& arr) {\n    std::stringstream ss;\n    int breakpos = 0;\n    int maxlen = 60;\n\n    for (int i = 0; i < arr.ArraySize(); ++i) {\n      if (i != 0) {\n        ss << \",\";\n      }\n      if (argnames_c && argnames_c[i]) {\n        ss << argnames_c[i] << \"=\";\n      }\n      if (argnames_s && argnames_s[i].size() > 0) {\n        ss << argnames_s[i] << \"=\";\n      }\n      const AVSValue& v = arr[i];\n      if (!v.Defined()) {\n        ss << \"default\";\n      }\n      else if (v.IsClip()) {\n        IClip* pclip = (IClip*)(void*)v.AsClip();\n        int clipnum = DoClip(pclip);\n        ss << \"clip\" << (clipnum + 1);\n        info.refNodes.push_back(pclip);\n      }\n      else if (v.IsFunction()) {\n        IFunction* pfunc = (IFunction*)(void*)v.AsFunction();\n        int funcnum = DoFunc(pfunc);\n        ss << \"func\" << (funcnum + 1);\n        info.refNodes.push_back(pfunc);\n      }\n      else if (v.IsArray()) {\n        ss << OutArray(\"(\" + DoArray(info, nullptr, nullptr, v) + \")\");\n      }\n      else if (v.IsBool()) {\n        ss << (v.AsBool() ? \"True\" : \"False\");\n      }\n      else if (v.IsInt()) {\n        ss << v.AsInt();\n      }\n      else if (v.IsFloat()) {\n        ss << std::setprecision(8) << v.AsFloat();\n      }\n      else if (v.IsString()) {\n        ss << \"\\\"\" << v.AsString() << \"\\\"\";\n      }\n      else {\n        ss << \"<error>\";\n      }\n      if ((int)ss.tellp() - breakpos > maxlen) {\n        ss << \"\\n\";\n        breakpos = (int)ss.tellp();\n      }\n    }\n    return ss.str();\n  }\n\n  virtual void OutClip(const NodeInfo& info) = 0;\n  virtual void OutFunc(const NodeInfo& info) = 0;\n  virtual std::string OutArray(const std::string& args) = 0;\n\npublic:\n  int Construct(FilterGraphNode* root, IScriptEnvironment* env_)\n  {\n    env = env_;\n    nodeMap.clear();\n    return DoClip(root);\n  }\n  void Construct(const std::vector<FilterGraphNode*>& roots, IScriptEnvironment* env_)\n  {\n    env = env_;\n    nodeMap.clear();\n    for (auto node : roots) {\n      if (node != nullptr) {\n        DoClip(node);\n      }\n    }\n  }\n};\n\nstatic void ReplaceAll(std::string& str, const std::string& from, const std::string& to) {\n  size_t start_pos = 0;\n  while ((start_pos = str.find(from, start_pos)) != std::string::npos) {\n    str.replace(start_pos, from.length(), to);\n    start_pos += to.length();\n  }\n}\n\nclass AvsScriptFilterGraph : private FilterGraph\n{\n  std::stringstream ss;\n\nprotected:\n  virtual void OutClip(const NodeInfo& info) {\n    int num = info.number + 1;\n    if (info.name.size() == 0) {\n      ss << \"clip\" << num << \": Failed to get information\" << std::endl;\n    }\n    else {\n      auto args = info.args;\n      ReplaceAll(args, \"\\n\", \"\");\n      ss << \"clip\" << num << \" = \" << info.name << args << std::endl;\n    }\n  }\n  virtual void OutFunc(const NodeInfo& info) {\n    int num = info.number + 1;\n    auto args = info.args;\n    ReplaceAll(args, \"\\n\", \"\");\n    ss << \"func\" << num << \" = function\" << args << \"(){ \" << info.name << \" }\" << std::endl;\n  }\n\n  int nextArrayNumber = 0;\n  virtual std::string OutArray(const std::string& args) {\n    std::string name = std::string(\"array\") + std::to_string(++nextArrayNumber);\n    ss << name;\n    ss << \" = ArrayCreate\" << args << std::endl;\n    return name;\n  }\npublic:\n\n  void Construct(FilterGraphNode* root, IScriptEnvironment* env) {\n    int last = FilterGraph::Construct(root, env);\n    ss << \"return clip\" << (last + 1) << std::endl;\n  }\n\n  std::string GetOutput() {\n    return ss.str();\n  }\n};\n\nclass DotFilterGraph : private FilterGraph\n{\n  bool enableArgs;\n  bool enableMemory;\n  std::stringstream ss;\n\nprotected:\n\n  void printfcomma(size_t n) {\n    if (n < 1000) {\n      ss << n;\n      return;\n    }\n    printfcomma(n / 1000);\n    ss << ',' << std::setfill('0') << std::setw(3) << (n % 1000);\n  }\n\n  virtual void OutClip(const NodeInfo& info) {\n    int num = info.number + 1;\n    ss << \"clip\" << num;\n    if (info.name.size() == 0) {\n      ss << \" [label = \\\"...\\\"];\" << std::endl;\n    }\n    else {\n      if (enableArgs) {\n        std::string label = info.name + info.args;\n        ReplaceAll(label, \"\\\\\", \"\\\\\\\\\");\n        ReplaceAll(label, \"\\\"\", \"\\\\\\\"\");\n        ReplaceAll(label, \"\\n\", \"\\\\n\");\n        ss << \" [label = \\\"\" << label << \"\\\"];\" << std::endl;\n      }\n      else {\n        if (info.cacheCapacity != 0) {\n          ss << \" [label = \\\"\" << info.name << \"(caching \" << info.cacheSize << \" frames with capacity \" << info.cacheCapacity << \")\";\n        }\n        else {\n          ss << \" [label = \\\"\" << info.name;\n        }\n        if (enableMemory) {\n          for (auto entry : info.memory) {\n            ss << \"\\\\n\" << entry.first->GetName() << \": \" << entry.second.numAllocation << \" frames, \";\n            printfcomma(entry.second.totalBytes);\n            ss << \" bytes\";\n          }\n        }\n        ss << \"\\\"];\" << std::endl;;\n      }\n    }\n    for (void* pclip : info.refNodes) {\n      auto& node = nodeMap[pclip];\n      int refnum = node.number + 1;\n      if (node.isFunction) {\n        ss << \"func\" << refnum << \" -> \" << \"clip\" << num << \";\" << std::endl;\n      }\n      else {\n        ss << \"clip\" << refnum << \" -> \" << \"clip\" << num << \";\" << std::endl;\n      }\n    }\n  }\n  virtual void OutFunc(const NodeInfo& info) {\n    int num = info.number + 1;\n    ss << \"func\" << num;\n    if (enableArgs) {\n      std::string label = info.name + \"\\n\" + info.args;\n      ReplaceAll(label, \"\\\\\", \"\\\\\\\\\");\n      ReplaceAll(label, \"\\\"\", \"\\\\\\\"\");\n      ReplaceAll(label, \"\\n\", \"\\\\n\");\n      ss << \" [label = \\\"\" << label << \"\\\"];\" << std::endl;\n    }\n    else {\n      ss << \" [label = \\\"\" << info.name << \"\\\"];\" << std::endl;\n    }\n    for (void* pclip : info.refNodes) {\n      auto& node = nodeMap[pclip];\n      int refnum = node.number + 1;\n      if (node.isFunction) {\n        ss << \"func\" << refnum << \" -> \" << \"func\" << num << \";\" << std::endl;\n      }\n      else {\n        ss << \"clip\" << refnum << \" -> \" << \"func\" << num << \";\" << std::endl;\n      }\n    }\n  }\n\n  int nextArrayNumber = 0;\n  virtual std::string OutArray(const std::string& args) {\n    std::string name = std::string(\"array\") + std::to_string(++nextArrayNumber);\n    //ss << name;\n    //ss << \" = ArrayCreate\" << args << std::endl;\n    return name;\n  }\npublic:\n\n  void Construct(FilterGraphNode* root, bool enableArgs, bool enableMemory, IScriptEnvironment* env) {\n    this->enableArgs = enableArgs;\n    this->enableMemory = enableMemory;\n    ss << \"digraph avs_filter_graph {\" << std::endl;\n    ss << \"node [ shape = box ];\" << std::endl;\n    int last = FilterGraph::Construct(root, env);\n    ss << \"GOAL;\" << std::endl;\n    ss << \"clip\" << (last + 1) << \" -> GOAL\" << std::endl;\n    ss << \"}\" << std::endl;\n  }\n\n  void Construct(const std::vector<FilterGraphNode*>& roots, bool enableArgs, bool enableMemory, IScriptEnvironment* env) {\n    this->enableArgs = enableArgs;\n    this->enableMemory = enableMemory;\n    ss << \"digraph avs_filter_graph {\" << std::endl;\n    ss << \"node [ shape = box ];\" << std::endl;\n    FilterGraph::Construct(roots, env);\n    ss << \"}\" << std::endl;\n  }\n\n  std::string GetOutput() {\n    return ss.str();\n  }\n};\n\n// Helper: open a file whose path is encoded as UTF-8.\n// On Windows convert to wide string and use _wfopen; on POSIX just call fopen.\nstatic FILE* OpenFileUtf8(const std::string& path_utf8, const char* mode) {\n#ifdef AVS_WINDOWS\n  if (path_utf8.empty() || mode == nullptr) return nullptr;\n\n  // Convert UTF-8 path to wide string using helper from strings.h\n  std::wstring wpath = Utf8ToWideChar(path_utf8.c_str()).get();\n  if (wpath.empty()) return nullptr;\n\n  // Convert mode to wide string. Mode is usually ASCII but convert via Utf8 helper for consistency.\n  std::wstring wmode = Utf8ToWideChar(mode).get();\n  if (wmode.empty()) return nullptr;\n\n  return _wfopen(wpath.c_str(), wmode.c_str());\n#else\n  return fopen(path_utf8.c_str(), mode);\n#endif\n}\n\nvoid DoDumpGraph(const std::vector<FilterGraphNode*>& roots, const char* path_utf8, IScriptEnvironment* env)\n{\n  DotFilterGraph graph;\n  graph.Construct(roots, true, true, env);\n  std::string ret = graph.GetOutput();\n\n  FILE* fp = OpenFileUtf8(std::string(path_utf8), \"w\");\n  if (fp == nullptr) {\n    env->ThrowError(\"Could not open output file ...\");\n  }\n  fwrite(ret.data(), ret.size(), 1, fp);\n  fclose(fp);\n}\n\nstatic void DoDumpGraph(PClip clip, int mode, const char* path_utf8, IScriptEnvironment* env)\n{\n  FilterGraphNode* root = dynamic_cast<FilterGraphNode*>((IClip*)(void*)clip);\n\n  std::string ret;\n\n  if (mode == 0) {\n    AvsScriptFilterGraph graph;\n    graph.Construct(root, env);\n    ret = graph.GetOutput();\n  }\n  else if (mode == 1 || mode == 2) {\n    DotFilterGraph graph;\n    graph.Construct(root, mode == 1, true, env);\n    ret = graph.GetOutput();\n  }\n  else {\n    env->ThrowError(\"Unknown mode (%d)\", mode);\n  }\n\n  FILE* fp = OpenFileUtf8(std::string(path_utf8), \"w\");\n  if (fp == nullptr) {\n    env->ThrowError(\"Could not open output file ...\");\n  }\n  fwrite(ret.data(), ret.size(), 1, fp);\n  fclose(fp);\n}\n\nclass DelayedDump : public GenericVideoFilter\n{\n  std::string outpath_utf8;\n  int mode;\n  int nframes;\n  bool repeat;\n  std::vector<bool> fired;\npublic:\n  DelayedDump(PClip clip, const std::string& outpath_utf8, int mode, int nframes, bool repeat)\n    : GenericVideoFilter(clip)\n    , outpath_utf8(outpath_utf8)\n    , mode(mode)\n    , nframes(nframes)\n    , repeat(repeat)\n  {\n    if (repeat) {\n      fired.resize((clip->GetVideoInfo().num_frames + nframes - 1) / nframes);\n    }\n    else {\n      fired.resize(1);\n    }\n  }\n\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env)\n  {\n    if (repeat) {\n      int slot = std::max(0, std::min(n / nframes, (int)fired.size() - 1));\n      if (fired[slot] == false) {\n        fired[slot] = true;\n        // Build path by inserting \"-<n>\" before extension (if any), preserve UTF-8\n        std::string basename = outpath_utf8;\n        size_t pos = basename.find_last_of('.');\n        std::string path;\n        if (pos != std::string::npos) {\n          path = basename.substr(0, pos) + \"-\" + std::to_string(n) + basename.substr(pos);\n        } else {\n          path = basename + \"-\" + std::to_string(n);\n        }\n        DoDumpGraph(child, mode, path.c_str(), env);\n      }\n    }\n    else {\n      if (n == nframes && fired[0] == false) {\n        fired[0] = true;\n        DoDumpGraph(child, mode, outpath_utf8.c_str(), env);\n      }\n    }\n    return child->GetFrame(n, env);\n  }\n};\n\nstatic AVSValue DumpFilterGraph(AVSValue args, void* user_data, IScriptEnvironment* env) {\n  PClip clip = args[0].AsClip();\n  FilterGraphNode* root = dynamic_cast<FilterGraphNode*>((IClip*)(void*)clip);\n  if (root == nullptr) {\n    env->ThrowError(\"clip is not a FilterChainNode. Ensure you have enabled the chain analysis by SetGraphAnalysis(true).\");\n  }\n\n  int mode = args[2].AsInt(0);\n  const char* path = args[1].AsString(\"\");\n  int nframes = args[3].AsInt(-1);\n  bool repeat = args[4].AsBool(false);\n\n  const bool utf8 = args[5].AsBool(false);\n  // DumpFiltergraph can also support yet forced UTF-8 mode in ANSI-only processes.\n\n  std::string path_utf8;\n#ifdef AVS_WINDOWS\n  // internally use UTF-8 path\n  if (!utf8)\n    path_utf8 = AnsiToUtf8(path).get();\n  else\n    path_utf8 = path;\n#else\n  path_utf8 = path;\n#endif\n\n  if (nframes >= 0) {\n    return new DelayedDump(clip, GetFullPathNameWrapUtf8(path_utf8), mode, nframes, repeat);\n  }\n\n  // For immediate dumps, normalize and let DoDumpGraph handle UTF-8 aware opening.\n  DoDumpGraph(clip, mode, path_utf8.c_str(), env);\n\n  return clip;\n}\n\nstatic AVSValue __cdecl SetGraphAnalysis(AVSValue args, void* user_data, IScriptEnvironment* env_) {\n  InternalEnvironment* env = GetAndRevealCamouflagedEnv(env_);\n  env->SetGraphAnalysis(args[0].AsBool());\n  return AVSValue();\n}\n\nextern const AVSFunction FilterGraph_filters[] = {\n  { \"SetGraphAnalysis\", BUILTIN_FUNC_PREFIX, \"b\", SetGraphAnalysis, nullptr },\n  { \"DumpFilterGraph\", BUILTIN_FUNC_PREFIX, \"c[outfile]s[mode]i[nframes]i[repeat]b[utf8]b\", DumpFilterGraph, nullptr },\n  { 0 }\n};\n"
  },
  {
    "path": "avs_core/core/FilterGraph.h",
    "content": "#ifndef _AVS_FILTER_GRAPH_H\n#define _AVS_FILTER_GRAPH_H\n\n#include \"internal.h\"\n#include <vector>\n#include <map>\n#include <memory>\n#include <mutex>\n\nclass FilterGraph;\n\nclass Device;\n// no DeviceManager classic avs+\n\nclass GraphMemoryNode {\npublic:\n  struct MemoryInfo {\n    int numAllocation;\n    size_t totalBytes;\n  };\n  std::map<Device*, MemoryInfo> memory;\n  void OnAllocate(size_t bytes, Device* dev);\n  void OnFree(size_t bytes, Device* dev);\nprivate:\n  friend class PGraphMemoryNode;\n  int refcnt;\n  void AddRef() { ++refcnt; }\n  void Release() { if (--refcnt <= 0) delete this; }\n};\n\nclass PGraphMemoryNode\n{\npublic:\n  PGraphMemoryNode() { Init(0); }\n  PGraphMemoryNode(GraphMemoryNode* p) { Init(p); }\n  PGraphMemoryNode(const PGraphMemoryNode& p) { Init(p.e); }\n  PGraphMemoryNode& operator=(GraphMemoryNode* p) { Set(p); return *this; }\n  PGraphMemoryNode& operator=(const PGraphMemoryNode& p) { Set(p.e); return *this; }\n  int operator!() const { return !e; }\n  operator void*() const { return e; }\n  GraphMemoryNode* operator->() const { return e; }\n  ~PGraphMemoryNode() { Release(); }\n\nprivate:\n  GraphMemoryNode* e;\n  void Init(GraphMemoryNode* p) { e = p; if (e) e->AddRef(); }\n  void Set(GraphMemoryNode* p) { if (p) p->AddRef(); if (e) e->Release(); e = p; }\n  void Release() { if (e) e->Release(); }\n};\n\nclass FilterGraphNode : public IClip\n{\n\tIScriptEnvironment* Env;\n  PClip child;\n\n  std::string name;\n  AVSValue args;\n  std::vector<std::unique_ptr<AVSValue[]>> arrays;\n  std::vector<std::string> argnames;\n\n  PGraphMemoryNode memory;\n\n  friend FilterGraph;\npublic:\n  FilterGraphNode(PClip child, const char* name, const AVSValue& last,\n\t\tconst AVSValue& args, const char* const* arg_names, IScriptEnvironment* env);\n\t~FilterGraphNode();\n\n  virtual int __stdcall GetVersion() { return child->GetVersion(); }\n  virtual PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n  virtual bool __stdcall GetParity(int n) { return child->GetParity(n); }\n  virtual void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env)\n  {\n    return child->GetAudio(buf, start, count, env);\n  }\n  virtual int __stdcall SetCacheHints(int cachehints, int frame_range)\n  {\n    return child->SetCacheHints(cachehints, frame_range);\n  }\n  virtual const VideoInfo& __stdcall GetVideoInfo() { return child->GetVideoInfo(); }\n\n  PGraphMemoryNode GetMemoryNode() { return memory; }\n};\n\nvoid DoDumpGraph(const std::vector<FilterGraphNode*>& roots, const char* path, IScriptEnvironment* env);\n\n#endif  // _AVS_FILTER_GRAPH_H\n"
  },
  {
    "path": "avs_core/core/InternalEnvironment.h",
    "content": "#ifndef _AVS_SCRIPTENVIRONMENT_H_INCLUDED\n#define _AVS_SCRIPTENVIRONMENT_H_INCLUDED\n\n#include <avisynth.h>\n#include <algorithm>\n#include <string>\n#include <memory>\n#include \"function.h\"\n#include \"CompatEnvironment.h\"\n\nclass ClipDataStore;\n\ntypedef enum _ELogLevel\n{\n    LOGLEVEL_NONE = 0,\n    LOGLEVEL_ERROR = 1,\n    LOGLEVEL_WARNING = 2,\n    LOGLEVEL_INFO = 3,\n    LOGLEVEL_DEBUG = 4\n} ELogLevel;\n\ntypedef enum _ELogTicketType\n{\n    LOGTICKET_W1000 = 1000, // leaks during shutdown\n    LOGTICKET_W1001 = 1001, // source plugin with no mt-mode\n    LOGTICKET_W1002 = 1002, // buggy SetCacheHints()\n    LOGTICKET_W1003 = 1003, // too stringent memory limit\n    LOGTICKET_W1004 = 1004, // filter completely without mt-mode\n    LOGTICKET_W1005 = 1005, // filter with inconsequent MT-modes\n    LOGTICKET_W1006 = 1006, // filter with redundant MT-modes\n    LOGTICKET_W1007 = 1007, // user should try 64-bit AVS for more memory\n    LOGTICKET_W1008 = 1008, // multiple plugins define the same function\n    LOGTICKET_W1009 = 1009, // a filter is using forced alignment\n    LOGTICKET_W1010 = 1010, // MT-mode specified for script function\n    LOGTICKET_W1100 = 1100, // memory reallocation occurs\n} ELogTicketType;\n\nenum CacheMode {\n\tCACHE_FAST_START,    // start up time and size balanced mode\n\tCACHE_OPTIMAL_SIZE,  // slow start up but optimal speed and cache size\n\tCACHE_NO_RESIZE,     // internal use only\n\n\tCACHE_DEFAULT = CACHE_FAST_START,\n};\n\nenum DeviceOpt: int {\n    DEV_CUDA_PINNED_HOST, // allocate CPU frame with CUDA pinned host memory\n    DEV_FREE_THRESHOLD,   // free request count threshold to free frame\n};\n\nclass OneTimeLogTicket\n{\npublic:\n    ELogTicketType _type;\n    const Function *_function = nullptr;\n    const std::string _string;\n\n    OneTimeLogTicket(ELogTicketType type);\n    OneTimeLogTicket(ELogTicketType type, const Function *func);\n    OneTimeLogTicket(ELogTicketType type, const std::string &str);\n    bool operator==(const OneTimeLogTicket &other) const;\n};\n\nclass Device;\nclass ThreadPool;\nclass ConcurrentVarStringFrame;\nclass FilterGraphNode;\n\nclass ScopedCounter {\n\tint& counter;\npublic:\n\tScopedCounter(int& counter) : counter(counter) {\n\t\t++counter;\n\t}\n\t~ScopedCounter() {\n\t\t--counter;\n\t}\n};\n\n#ifdef ALTERNATIVE_VFB_TIMESTAMP\nclass VideoFrameBuffer;\n\n// Forward declarations - don't expose full classes\nclass ScriptEnvironment;\n\nnamespace VFBHelper {\n  // Wrapper function to call the nested static method\n  void UpdateVFBFreeTimestamp(VideoFrameBuffer* vfb);\n}\n#endif\n\n// Interface transformation hack\nclass InternalEnvironment; // forward\nInternalEnvironment* GetAndRevealCamouflagedEnv(IScriptEnvironment* env);\n\n// Strictly for Avisynth core only.\n// Neither host applications nor plugins should use\n// these interfaces.\nclass InternalEnvironment :\n  public IScriptEnvironment2,\n  public IScriptEnvironment_Avs25,\n  public IScriptEnvironment_AvsPreV11C,\n  public INeoEnv {\nprotected:\n  virtual ~InternalEnvironment() {}\npublic:\n  // define commons to fix ambiguous error\n\n  typedef IScriptEnvironment::NotFound NotFound;\n  typedef IScriptEnvironment::ApplyFunc ApplyFunc;\n\n  // IScriptEnvironment\n  virtual int __stdcall GetCPUFlags() = 0;\n  virtual char* __stdcall SaveString(const char* s, int length = -1) = 0;\n  virtual char* Sprintf(const char* fmt, ...) = 0;\n  virtual char* __stdcall VSprintf(const char* fmt, va_list val) = 0;\n  __declspec(noreturn) virtual void ThrowError(const char* fmt, ...) = 0;\n  virtual void __stdcall AddFunction(const char* name, const char* params, INeoEnv::ApplyFunc apply, void* user_data) = 0;\n  virtual bool __stdcall FunctionExists(const char* name) = 0;\n  virtual AVSValue __stdcall Invoke(const char* name, const AVSValue args, const char* const* arg_names = 0) = 0;\n  virtual AVSValue __stdcall GetVar(const char* name) = 0;\n  virtual bool __stdcall SetVar(const char* name, const AVSValue& val) = 0;\n  virtual bool __stdcall SetGlobalVar(const char* name, const AVSValue& val) = 0;\n  virtual void __stdcall PushContext(int level = 0) = 0;\n  virtual void __stdcall PopContext() = 0;\n  // NewVideoFrame is replaced with new one\n  virtual bool __stdcall MakeWritable(PVideoFrame* pvf) = 0;\n  virtual void __stdcall BitBlt(BYTE* dstp, int dst_pitch, const BYTE* srcp, int src_pitch, int row_size, int height) = 0;\n  virtual void __stdcall AtExit(INeoEnv::ShutdownFunc function, void* user_data) = 0;\n  virtual void __stdcall CheckVersion(int version = AVISYNTH_INTERFACE_VERSION) = 0;\n  virtual PVideoFrame __stdcall Subframe(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height) = 0;\n  virtual int __stdcall SetMemoryMax(int mem) = 0;\n  virtual int __stdcall SetWorkingDir(const char * newdir) = 0;\n  virtual void* __stdcall ManageCache(int key, void* data) = 0;\n  virtual bool __stdcall PlanarChromaAlignment(IScriptEnvironment::PlanarChromaAlignmentMode key) = 0;\n  virtual PVideoFrame __stdcall SubframePlanar(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size,\n    int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV) = 0;\n  // AVISYNTH_INTERFACE_VERSION 5\n  virtual void __stdcall DeleteScriptEnvironment() = 0;\n  virtual void __stdcall ApplyMessage(PVideoFrame* frame, const VideoInfo& vi, const char* message, int size,\n    int textcolor, int halocolor, int bgcolor) = 0;\n  virtual const AVS_Linkage* __stdcall GetAVSLinkage() = 0;\n\n  // AVISYNTH_INTERFACE_VERSION 6\n  virtual AVSValue __stdcall GetVarDef(const char* name, const AVSValue& def = AVSValue()) = 0;\n\n  // AVISYNTH_INTERFACE_VERSION 8\n  virtual PVideoFrame __stdcall SubframePlanarA(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size,\n    int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV, int rel_offsetA) = 0;\n\n  // frame properties support\n  virtual void __stdcall copyFrameProps(const PVideoFrame& src, PVideoFrame& dst) = 0;\n\n  virtual const AVSMap* __stdcall getFramePropsRO(const PVideoFrame& frame) = 0;\n  virtual AVSMap* __stdcall getFramePropsRW(PVideoFrame &frame) = 0;\n\n  virtual int __stdcall propNumKeys(const AVSMap* map) = 0;\n  virtual const char* __stdcall propGetKey(const AVSMap* map, int index) = 0;\n  virtual int __stdcall propDeleteKey(AVSMap* map, const char* key) = 0;\n  virtual int __stdcall propNumElements(const AVSMap* map, const char* key) = 0;\n  virtual char __stdcall propGetType(const AVSMap* map, const char* key) = 0;\n\n  virtual int64_t __stdcall propGetInt(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual double __stdcall propGetFloat(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual const char* __stdcall propGetData(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual int __stdcall propGetDataSize(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual PClip __stdcall propGetClip(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual const PVideoFrame __stdcall propGetFrame(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual int __stdcall propSetInt(AVSMap* map, const char* key, int64_t i, int append) = 0;\n  virtual int __stdcall propSetFloat(AVSMap* map, const char* key, double d, int append) = 0;\n  virtual int __stdcall propSetData(AVSMap* map, const char* key, const char* d, int length, int append) = 0;\n  virtual int __stdcall propSetClip(AVSMap* map, const char* key, PClip& clip, int append) = 0;\n  virtual int __stdcall propSetFrame(AVSMap* map, const char* key, const PVideoFrame& frame, int append) = 0;\n\n  virtual const int64_t* __stdcall propGetIntArray(const AVSMap* map, const char* key, int* error) = 0;\n  virtual const double* __stdcall propGetFloatArray(const AVSMap* map, const char* key, int* error) = 0;\n  virtual int __stdcall propSetIntArray(AVSMap* map, const char* key, const int64_t* i, int size) = 0;\n  virtual int __stdcall propSetFloatArray(AVSMap* map, const char* key, const double* d, int size) = 0;\n\n  virtual AVSMap* __stdcall createMap() = 0;\n  virtual void __stdcall freeMap(AVSMap* map) = 0;\n  virtual void __stdcall clearMap(AVSMap* map) = 0;\n\n  // NewVideoFrame with frame prop source is replaced with new one\n\n  virtual size_t  __stdcall GetEnvProperty(AvsEnvProperty prop) = 0;\n  virtual void* __stdcall Allocate(size_t nBytes, size_t alignment, AvsAllocType type) = 0;\n  virtual void __stdcall Free(void* ptr) = 0;\n\n  // Returns TRUE and the requested variable. If the method fails, returns FALSE and does not touch 'val'.\n  virtual bool __stdcall GetVarTry(const char* name, AVSValue* val) const = 0; // ex virtual bool  __stdcall GetVar(const char* name, AVSValue* val) const = 0;\n  virtual bool __stdcall GetVarBool(const char* name, bool def) const = 0; // ex: virtual bool __stdcall GetVar(const char* name, bool def) const = 0;\n  virtual int __stdcall GetVarInt(const char* name, int def) const = 0; // ex: int  __stdcall GetVar(const char* name, int def) const = 0;\n  virtual double __stdcall GetVarDouble(const char* name, double def) const = 0; // ex: virtual double  __stdcall GetVar(const char* name, double def) const = 0;\n  virtual const char* __stdcall GetVarString(const char* name, const char* def) const = 0; // ex: virtual const char* __stdcall GetVar(const char* name, const char* def) const = 0;\n  virtual int64_t __stdcall GetVarLong(const char* name, int64_t def) const = 0; // brand new in v8 - v11: real int64 support\n\n  // Invoke functions renamed for keeping vtable order in IS\n  // moved from IS2\n  virtual bool __stdcall InvokeTry(AVSValue* result, const char* name, const AVSValue& args, const char* const* arg_names = 0) = 0;\n  // Since V8\n  virtual AVSValue __stdcall Invoke2(const AVSValue& implicit_last, const char* name, const AVSValue args, const char* const* arg_names = 0) = 0;\n  // moved from INeo\n  virtual bool __stdcall Invoke2Try(AVSValue* result, const AVSValue& implicit_last, const char* name, const AVSValue args, const char* const* arg_names = 0) = 0;\n  virtual AVSValue __stdcall Invoke3(const AVSValue& implicit_last, const PFunction& func, const AVSValue args, const char* const* arg_names = 0) = 0;\n  virtual bool __stdcall Invoke3Try(AVSValue* result, const AVSValue& implicit_last, const PFunction& func, const AVSValue args, const char* const* arg_names = 0) = 0;\n\n  // V9\n  virtual bool __stdcall MakePropertyWritable(PVideoFrame* pvf) = 0;\n\n  // V11\n  virtual int __stdcall propGetIntSaturated(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual float __stdcall propGetFloatSaturated(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual int __stdcall propGetDataTypeHint(const AVSMap* map, const char* key, int index, int* error) = 0; /* returns AVSPropDataTypeHint */\n  virtual int __stdcall propSetDataH(AVSMap* map, const char* key, const char* d, int length, int type, int append) = 0;\n\n  // V12\n  virtual bool __stdcall AcquireGlobalLock(const char* name) = 0;\n  virtual void __stdcall ReleaseGlobalLock(const char* name) = 0;\n  virtual void __stdcall ApplyMessageEx(PVideoFrame* frame, const VideoInfo& vi, const char* message, int size,\n    int textcolor, int halocolor, int bgcolor, bool utf8) = 0;\n  virtual int64_t __stdcall GetCPUFlagsEx() = 0;\n\n  // IScriptEnvironment2\n  virtual bool __stdcall LoadPlugin(const char* filePath, bool throwOnError, AVSValue *result) = 0;\n  virtual void __stdcall AddAutoloadDir(const char* dirPath, bool toFront) = 0;\n  virtual void __stdcall ClearAutoloadDirs() = 0;\n  virtual void __stdcall AutoloadPlugins() = 0;\n  virtual void __stdcall AddFunction(const char* name, const char* params, INeoEnv::ApplyFunc apply, void* user_data, const char *exportVar) = 0;\n  virtual bool __stdcall InternalFunctionExists(const char* name) = 0;\n  virtual void __stdcall SetFilterMTMode(const char* filter, MtMode mode, bool force) = 0;\n  virtual IJobCompletion* __stdcall NewCompletion(size_t capacity) = 0;\n  virtual void __stdcall ParallelJob(ThreadWorkerFuncPtr jobFunc, void* jobData, IJobCompletion* completion) = 0;\n\n  // InternalEnvironment\n  virtual char *__stdcall ListAutoloadDirs() = 0;\n  virtual int __stdcall IncrImportDepth() = 0;\n  virtual int __stdcall DecrImportDepth() = 0;\n  virtual void __stdcall AdjustMemoryConsumption(size_t amount, bool minus) = 0;\n  virtual bool __stdcall FilterHasMtMode(const Function* filter) const = 0;\n  virtual MtMode __stdcall GetFilterMTMode(const Function* filter, bool* is_forced) const = 0; // If filter is \"\", gets the default MT mode\n  virtual ClipDataStore* __stdcall ClipData(IClip *clip) = 0;\n  virtual MtMode __stdcall GetDefaultMtMode() const = 0;\n  virtual void __stdcall SetLogParams(const char *target, int level) = 0;\n  virtual void LogMsg(int level, const char* fmt, ...) = 0;\n  virtual void __stdcall LogMsg_valist(int level, const char* fmt, va_list va) = 0;\n  virtual void LogMsgOnce(const OneTimeLogTicket &ticket, int level, const char* fmt, ...) = 0;\n  virtual void __stdcall LogMsgOnce_valist(const OneTimeLogTicket &ticket, int level, const char* fmt, va_list va) = 0;\n  virtual void __stdcall VThrowError(const char* fmt, va_list va) = 0;\n  virtual void __stdcall SetMaxCPU(const char *feature) = 0;\n  virtual void __stdcall SetFilterProp(const char* filter, const char* key, const AVSValue& value, int mode) = 0;\n  virtual void __stdcall SetFilterPropConditional(const char* filter, const char* param_name, const AVSValue& param_match,\n                                                   const char* key, const AVSValue& value, int mode) = 0;\n  virtual const char* __stdcall GetFilterProps() = 0;\n  virtual void __stdcall SetFilterPropPassthrough(const char* filter) = 0;\n\n  /*\n    How casting down works in Avisynth, when passing differently typed \n    IScriptEnvironment variant pointers to plugins.\n\n    We have one big InternalEnvironment (further inherited by ThreadScriptEnvironment).\n    InternalEnvironment inherits all IScriptEnvironment variants, which have strictly \n    identical function order of their pure virtual functions.\n\n    When we pass an IScriptEnvironment variant to a plugin/client (who is just seeing\n    Avisynth's standard IScriptEnvironment), then really we pass the proper VMT table.\n\n    Let's see an example for IScriptEnvironment_Avs25.\n\n    For the static_cast to work correctly, the IScriptEnvironment_Avs25 interface must \n    have the same order of methods as they appear in the InternalEnvironment class.\n    This ensures that the VMT entries align properly, allowing the cast pointer to \n    correctly access the methods defined in IScriptEnvironment_Avs25.\n\n    In C++, the order of methods in the VMT is determined by the order in which they are \n    declared in the class or interface.\n    Therefore, as long as IScriptEnvironment_Avs25 is a base class of InternalEnvironment \n    and the methods are declared in the same order, the static_cast will work as expected.\n\n    When we cast a Derived* to a Base*, e.g. InternalEnvironment*  to IScriptEnvironment2*,\n    the pointer might be adjusted to point to the Base sub-object within Derived.\n    This ensures that the VMT entries for Base methods are correctly aligned.\n\n    If we have multiple base classes with the same pure virtual function names\n    (NewVideoFrame, MakeWritable, etc..), and the derived class (InternalEnvironment) \n    provides the implementation, the VMT entries for all those base classes will point \n    to the same implementation in the derived class.\n\n    The implemented pure virtual function addresses will be written back to all \n    IScriptEnvironmentXXXXX variant's VMT entries. So the same NewVideoFrame address\n    will appear in IScriptEnvironment2 and IScriptEnvironment_Avs25 VMT table.\n\n    Trick:\n    There are differences, that must handle differently for different IScriptEnvironment types.\n    E.g. IScriptEnvironment_Avs25 implements its own AddFunction. Place of AddFunction in VMT table\n    is fixed (VMT index N). In the class definition we use the name AddFunction25 instead \n    of AddFunction. It will appear at VMT index N in IScriptEnvironment_Avs25, since the \n    order is kept similar to IScriptEnvironment's order. \n    Because if was named differently, InternalEnvironment's implementation\n    will put a different address into IScriptEnvironment_Avs25's VMT table.\n    When this pointer is passed to a plugin, (which sees only an IScriptEnvironment*)\n    when it calles AddFunction (that is VMT index N), it hiddenly will call AddFunction25 instead.\n  */\n\n  // interface conversions\n  virtual IScriptEnvironment2* __stdcall GetEnv2() final { return static_cast<IScriptEnvironment2*>(this); }\n  virtual IScriptEnvironment_Avs25* __stdcall GetEnv25() final { return static_cast<IScriptEnvironment_Avs25*>(this); }\n  virtual IScriptEnvironment_AvsPreV11C* __stdcall GetEnvPreV11C() final { return static_cast<IScriptEnvironment_AvsPreV11C*>(this); }\n\n  virtual void __stdcall SetGraphAnalysis(bool enable) = 0;\n\n  virtual Device* __stdcall SetCurrentDevice(Device* device) = 0;\n  virtual Device* __stdcall GetCurrentDevice() const = 0;\n  // replacement of NewVideoFrame\n  virtual PVideoFrame __stdcall NewVideoFrameOnDevice(const VideoInfo& vi, int align, Device* device) = 0;\n  virtual PVideoFrame __stdcall NewVideoFrameOnDevice(const VideoInfo& vi, int align, Device* device, const PVideoFrame *prop_src) = 0;\n  virtual PVideoFrame __stdcall GetOnDeviceFrame(const PVideoFrame& src, Device* device) = 0;\n\n  using INeoEnv::SetMemoryMax;\n  using INeoEnv::Invoke;\n  using INeoEnv::NewVideoFrame;\n  using INeoEnv::SaveString;\n\n  // Nekopanda: support multiple prefetcher //\n  // to allow thread to submit with their env\n  virtual void __stdcall ParallelJob(ThreadWorkerFuncPtr jobFunc, void* jobData, IJobCompletion* completion, InternalEnvironment *env) = 0;\n  virtual ThreadPool* __stdcall NewThreadPool(size_t nThreads) = 0;\n  virtual void __stdcall AddRef() = 0;\n  virtual void __stdcall Release() = 0;\n\n  virtual ConcurrentVarStringFrame* __stdcall GetTopFrame() = 0;\n\n  // Nekopanda: new cache control mechanism\n  virtual void __stdcall SetCacheMode(CacheMode mode) = 0;\n  virtual CacheMode __stdcall GetCacheMode() = 0;\n\tvirtual bool& __stdcall GetSupressCaching() = 0;\n\n  // useful to detect chainedCtor\n  virtual size_t __stdcall GetInvokeStackSize() = 0;\n\n  virtual void __stdcall SetDeviceOpt(DeviceOpt mode, int val) = 0;\n\n  virtual void __stdcall UpdateFunctionExports(const char* funcName, const char* funcParams, const char *exportVar) = 0;\n  virtual bool __stdcall Invoke_(AVSValue *result, const AVSValue& implicit_last,\n    const char* name, const Function *f, const AVSValue& args, const char* const* arg_names) = 0;\n\n  virtual InternalEnvironment* __stdcall NewThreadScriptEnvironment(int thread_id) = 0;\n\n\t// per thread data access\n\tvirtual int __stdcall GetThreadId() = 0;\n\tvirtual int& __stdcall GetFrameRecursiveCount() = 0;\n\tvirtual int& __stdcall GetSuppressThreadCount() = 0;\n\tvirtual FilterGraphNode*& GetCurrentGraphNode() = 0;\n};\n\nstruct InternalEnvironmentDeleter {\n\tvoid operator()(InternalEnvironment* ptr) const {\n\t\tptr->Release();\n\t}\n};\ntypedef std::unique_ptr<InternalEnvironment, InternalEnvironmentDeleter> PInternalEnvironment;\n\n#endif // _AVS_SCRIPTENVIRONMENT_H_INCLUDED\n"
  },
  {
    "path": "avs_core/core/LruCache.h",
    "content": "#ifndef AVS_LRUCACHE_H\n#define AVS_LRUCACHE_H\n\n#include <mutex>\n#include <condition_variable>\n#include <memory>\n#include <cassert>\n#include \"ObjectPool.h\"\n#include \"SimpleLruCache.h\"\n#include \"InternalEnvironment.h\"\n\nenum LruLookupResult\n{\n  LRU_LOOKUP_NOT_FOUND,          // Item has not been found, storage is reserved to be used by caller\n  LRU_LOOKUP_FOUND_AND_READY,    // Item has been found and returned\n  LRU_LOOKUP_FOUND_BUT_NOTAVAIL, // Item has been found, but is waiting for completion and is not yet ready\n  LRU_LOOKUP_NO_CACHE            // Item will not be cached, no storage is returned\n};\n\ntemplate<typename K, typename V>\nclass LruCache : public std::enable_shared_from_this<LruCache<K, V> >\n{\nprivate:\n  enum LruEntryState\n  {\n    LRU_ENTRY_EMPTY,\n    LRU_ENTRY_AVAILABLE,\n    LRU_ENTRY_ROLLED_BACK\n  };\n\n  struct LruGhostEntry\n  {\n    K key;\n    size_t ghosted;\n\n    LruGhostEntry() :\n      key(0), ghosted(0)\n    {\n    }\n\n    LruGhostEntry(K key, size_t ghosted) :\n      key(key), ghosted(ghosted)\n    {\n    }\n  };\n\n  struct LruEntry\n  {\n    K key;\n    V value;\n    size_t locks;      // the number of threads waiting on this entry. used to prevent eviction when readers are waiting on it\n    size_t ghosted;    // the number of times this entry has entered the ghost list\n    std::condition_variable ready_cond;\n    enum LruEntryState state;\n\n    LruEntry(const K& key)\n    {\n      reset(key, V());\n    }\n\n    void reset(const K& k, const V& v)\n    {\n      key = k;\n      value = v;\n      locks = 0;\n      ghosted = 0;\n      state = LRU_ENTRY_EMPTY;\n    }\n\n  private:\n    LruEntry(const LruEntry&);\n    LruEntry& operator=(const LruEntry&);\n  };\n\n  const int GHOSTS_MIN_CAPACITY;\n  typedef LruEntry entry_type;\n  typedef entry_type* entry_ptr;\n  typedef SimpleLruCache<K, entry_ptr> CacheType;\n  typedef SimpleLruCache<K, LruGhostEntry> GhostCacheType;\n\n  typedef size_t  size_type;\n\n  CacheMode mode;\n  CacheType MainCache;\n  GhostCacheType Ghosts;\n  ObjectPool<entry_type> EntryPool;\n  mutable std::mutex mutex;\n\n  static bool MainEvictEvent(CacheType* cache, const typename CacheType::Entry& entry, void* userData)\n  {\n    if (entry.value->locks > 0)\n      return false;\n\n    LruCache* me = reinterpret_cast<LruCache*>(userData);\n\n    bool ghost_found;\n    auto *g = me->Ghosts.lookup(entry.key, &ghost_found);\n    if (!ghost_found)\n    {\n      *g = LruGhostEntry(entry.key, entry.value->ghosted + 1);\n    }\n    else\n    {\n      g->ghosted++;\n    }\n\n    entry.value->reset(0, NULL);\n    me->EntryPool.Destruct(entry.value);\n    return true;\n  }\n\npublic:\n\n  typedef std::pair<entry_ptr, std::shared_ptr<LruCache> > handle;\n\n  LruCache(size_type capacity, CacheMode mode) :\n    GHOSTS_MIN_CAPACITY(50),\n    mode(mode),\n    MainCache(capacity, &MainEvictEvent, reinterpret_cast<void*>(this)),\n    Ghosts(GHOSTS_MIN_CAPACITY, typename GhostCacheType::EvictEventType(), reinterpret_cast<void*>(this))\n  {\n  }\n\n  size_type size() const\n  {\n    return MainCache.size();\n  }\n\n  size_t requested_capacity() const\n  {\n    return MainCache.requested_capacity();\n  }\n\n  size_t capacity() const\n  {\n    return MainCache.capacity();\n  }\n\n  void limits(size_t* min, size_t* max) const\n  {\n    std::unique_lock<std::mutex> global_lock(mutex);\n\n    MainCache.limits(min, max);\n  }\n\n  void set_limits(size_t min, size_t max)\n  {\n    std::unique_lock<std::mutex> global_lock(mutex);\n\n    MainCache.set_limits(min, max);\n  }\n\n  LruLookupResult lookup(const K& key, handle *hndl, bool block_for_completion, V& foundItem, bool* suppressCaching = nullptr)\n  {\n    bool suppress = (suppressCaching != nullptr) && *suppressCaching;\n    hndl->first = nullptr; // clear handle\n\n    std::unique_lock<std::mutex> global_lock(mutex);\n\n    bool found;\n    entry_ptr* entryp = MainCache.lookup(key, &found, suppress);\n\n    if (found)\n    {\n      entry_ptr entry = *entryp;\n\n      if (!block_for_completion && (entry->state != LRU_ENTRY_AVAILABLE))\n      {\n        return LRU_LOOKUP_FOUND_BUT_NOTAVAIL;\n      }\n\n      // wait until data becomes available\n      ++(entry->locks);\n      while (entry->state == LRU_ENTRY_EMPTY)\n      {\n        entry->ready_cond.wait(global_lock);\n\n        switch (entry->state)\n        {\n        case LRU_ENTRY_EMPTY:           // do nothing, spurious wakeup\n          break;\n        case LRU_ENTRY_AVAILABLE:       // finally, data available\n          break;\n        case LRU_ENTRY_ROLLED_BACK:     // whoever we were waiting for decided to step back. we take over his place.\n          entry->state = LRU_ENTRY_EMPTY;\n          *hndl = handle(entry, this->shared_from_this());\n          return LRU_LOOKUP_NOT_FOUND;\n        default:\n          assert(0);\n        }\n      }\n      // copy and return entry->value before releasing lock\n      foundItem = entry->value;\n      --(entry->locks);\n      return LRU_LOOKUP_FOUND_AND_READY;\n    }\n    else if (suppress == false)\n    {\n      // ghost: self-tuning caching algorithm\n      bool ghost_found;\n      auto *g = Ghosts.lookup(key, &ghost_found);\n      assert(g != NULL);\n      if (!ghost_found)\n      {\n        *g = LruGhostEntry(key, 0);\n      }\n      else if (g->ghosted > 1)\n      {\n        // Fix for Issues #270 and #379: require a frame to have been evicted\n        // at least twice (ghosted > 1) before triggering a cache resize.\n        //\n        // With the old condition (ghosted > 0), any single eviction + re-request\n        // caused a +1 resize.  This led to unbounded cache growth in two cases:\n        //\n        // 1. Backward seeking (Issue #379): frames played forward get evicted and\n        //    ghosted=1.  Every backstep hits a ghost (1 > 0 was true) → +1 on each\n        //    step.\n        //\n        // 2. Bob()/SeparateFields access pattern (Issue #270): the n, n/2 pattern\n        //    keeps evicting the same frames with ghosted=1, so every GetFrame call\n        //    triggered a resize.\n        //    Infinite cache growth occured when the requested frame number pattern from \n        //    source filter is something like that:\n        //    0,0, 0,1, 1,2, 1,3, 2,4, 2,5, 3,6, 3,7, 4,8,...\n        // Sample script:\n        //   ConvertToY8()\n        //   org = last\n        //   Bob()\n        //   Merge(last, org)\n        // With ghosted > 1: both cases are suppressed because frames evicted only\n        // once stay at ghosted=1 (1 > 1 is false).  An undersized cache\n        // still grows: frames that keep cycling will be evicted a second time,\n        // pushing ghosted to 2, and growth resumes from that point forward.\n        if (mode != CACHE_NO_RESIZE) {\n#ifdef CACHE_GROWTH_INFINITELY_TEST\n          // When the above (g->ghosted > 1) was (g->ghosted > 0)\n          _RPT1(0, \"Not in cache but in ghost! g->ghosted > 0 => resize! MainCache.capacity()=%d -> += 1\", MainCache.capacity() + 1);\n#endif\n          MainCache.resize(MainCache.capacity() + 1);\n          Ghosts.resize(GHOSTS_MIN_CAPACITY + MainCache.capacity() * 2);\n        }\n\n        // Nekopanda: reduce amount of cache.\n        // when this filter increased the cache, we prevent lower filters increase their cache\n        // because the requests to the lower filters were not needed if this filter cached the frame.\n        if (mode == CACHE_OPTIMAL_SIZE && suppressCaching != nullptr) {\n          *suppressCaching = true;\n        }\n      }\n      else\n      {\n        // This cannot happen\n        //assert(0); LOL maybe it can...\n      }\n\n      if (entryp != NULL)\n      {\n        *entryp = EntryPool.Construct(key);\n        entry_ptr entry = *entryp;\n        *hndl = handle(entry, this->shared_from_this());\n        entry->locks = 1;\n        entry->ghosted = g->ghosted;\n        entry->value = NULL;\n        return LRU_LOOKUP_NOT_FOUND;\n      }\n      else\n      {\n        g->ghosted++;\n        return LRU_LOOKUP_NO_CACHE;\n      }\n    } // if\n    else {\n      assert(entryp == nullptr);\n      return LRU_LOOKUP_NO_CACHE;\n    }\n  }\n\n  void commit_value(handle *hndl)\n  {\n    std::unique_lock<std::mutex> global_lock(mutex);\n\n    // mark data as ready\n    entry_ptr e = hndl->first;\n    e->state = LRU_ENTRY_AVAILABLE;\n    --(e->locks);\n\n    // notify waiters\n    global_lock.unlock();\n    e->ready_cond.notify_all();\n\n    hndl->second.reset();\n  }\n\n  void rollback(handle *hndl)\n  {\n    std::unique_lock<std::mutex> global_lock(mutex);\n\n    entry_ptr e = hndl->first;\n    assert(e->locks > 0);\n\n    if (e->locks == 1)\n    {\n      MainCache.remove(e->key);\n    }\n    else\n    {\n      // others have started waiting for this data, so another one will have to take over\n      --(e->locks);\n      e->state = LRU_ENTRY_ROLLED_BACK;\n\n      // notify one waiter\n      global_lock.unlock();\n      e->ready_cond.notify_one();\n    }\n\n    hndl->second.reset();\n  }\n};\n\n#endif  // AVS_LRUCACHE_H\n"
  },
  {
    "path": "avs_core/core/MTGuard.cpp",
    "content": "// Avisynth v2.6.  Copyright 2002-2009 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include \"MTGuard.h\"\n#include \"cache.h\"\n#include \"internal.h\"\n#include \"FilterConstructor.h\"\n#include \"InternalEnvironment.h\"\n#include <cassert>\n#include <mutex>\n\n#ifdef X86_32\n#include <mmintrin.h>\n#endif\n\nstruct MTGuardChildFilter {\n  PClip filter;\n  std::mutex mutex;\n};\n\n#ifdef AVS_WINDOWS\nMTGuard::MTGuard(PClip firstChild, MtMode mtmode, std::unique_ptr<const FilterConstructor>&& funcCtor, const wchar_t* current_directory, InternalEnvironment* env) :\n#else\nMTGuard::MTGuard(PClip firstChild, MtMode mtmode, std::unique_ptr<const FilterConstructor>&& funcCtor, const char* current_directory, InternalEnvironment* env) :\n#endif\n  Env(env),\n  nThreads(1),\n  mt_enabled(false),\n  FilterCtor(std::move(funcCtor)),\n#ifdef AVS_WINDOWS\n  CurrentDirectory(current_directory ? current_directory : L\"\"),\n#else\n  CurrentDirectory(current_directory ? current_directory : \"\"),\n#endif\n  MTMode(mtmode)\n{\n  assert( ((int)mtmode > (int)MT_INVALID) && ((int)mtmode < (int)MT_MODE_COUNT) );\n\n  ChildFilters = std::unique_ptr<MTGuardChildFilter[]>(new MTGuardChildFilter[1]);\n  ChildFilters[0].filter = firstChild;\n  vi = ChildFilters[0].filter->GetVideoInfo();\n\n  Env->ManageCache(MC_RegisterMTGuard, reinterpret_cast<void*>(this));\n}\n\nMTGuard::~MTGuard()\n{\n  Env->ManageCache(MC_UnRegisterMTGuard, reinterpret_cast<void*>(this));\n}\n\nvoid MTGuard::EnableMT(size_t nThreads)\n{\n  // called for each filter in the chain, starting from the top-level filter\n  // even if their mt_enabled were set by an earlier Prefetch.\n\n  assert(nThreads >= 1);\n\n  if (nThreads > 1)\n  {\n    switch (MTMode)\n    {\n    case MT_NICE_FILTER:\n    {\n      // already created single instance, just set the thread count\n      if (!this->mt_enabled)\n        ChildFilters[0].filter->SetCacheHints(CACHE_INFORM_NUM_THREADS, (int)nThreads);\n      break;\n    }\n    case MT_MULTI_INSTANCE:\n    {\n      // creates the extra filter instances needed for the actual thread count\n      // set only when unset\n      if (!this->mt_enabled) {\n        auto newchilds = std::unique_ptr<MTGuardChildFilter[]>(new MTGuardChildFilter[nThreads]);\n        // copy existing\n        for (size_t i = 0; i < this->nThreads; ++i) {\n          newchilds[i].filter = ChildFilters[i].filter;\n        }\n        if (CurrentDirectory.empty()) {\n          // create the rest\n          for (size_t i = this->nThreads; i < nThreads; ++i) {\n            newchilds[i].filter = FilterCtor->InstantiateFilter().AsClip();\n          }\n        }\n        else {\n          // switch to the original CurrentDirectory to instantiate the threaded filters\n          // in order to their constructor to be able to see the original current directory\n          CWDChanger change_cwd(CurrentDirectory.c_str()); // wstring on Windows, string on Linux\n\n          // create the rest\n          for (size_t i = this->nThreads; i < nThreads; ++i) {\n            newchilds[i].filter = FilterCtor->InstantiateFilter().AsClip();\n          }\n        }\n        // inform all filter instances about the threading\n        for (size_t i = 0; i < nThreads; ++i)\n          newchilds[i].filter->SetCacheHints(CACHE_INFORM_NUM_THREADS, (int)nThreads);\n        ChildFilters = std::move(newchilds);\n      }\n      break;\n    }\n    case MT_SERIALIZED:\n    {\n      // already created single instance, just set the thread count\n      if (!this->mt_enabled)\n        ChildFilters[0].filter->SetCacheHints(CACHE_INFORM_NUM_THREADS, 1);\n      break;\n    }\n    default:\n    {\n      assert(0);\n      break;\n    }\n    }\n  }\n  else if (nThreads == 1) {\n    if (!this->mt_enabled)\n      ChildFilters[0].filter->SetCacheHints(CACHE_INFORM_NUM_THREADS, 1);\n  }\n\n  if (!this->mt_enabled) {\n    this->nThreads = std::max(this->nThreads, nThreads);\n    this->mt_enabled = true;\n  }\n\n  // We don't need the stored parameters any more,\n  // free their memory.\n  //FilterCtor.reset();\n}\n\nPVideoFrame __stdcall MTGuard::GetFrame(int n, IScriptEnvironment* env_)\n{\n  assert(nThreads > 0);\n  /*\n  // We can't call child filter without mutex guards even when nThreads is 1,\n  // because a lately invoked filter may call GetFrame again, see\n  // MT_SERIALIZED considerations below.\n  // Code left here intentionally but commented out.\n  if (nThreads == 1)\n    return ChildFilters[0].filter->GetFrame(n, env);\n  */\n  InternalEnvironment* IEnv = GetAndRevealCamouflagedEnv(env_);\n  IScriptEnvironment* env = static_cast<IScriptEnvironment*>(IEnv);\n\n  PVideoFrame frame = NULL;\n\n  switch (MTMode)\n  {\n  case MT_NICE_FILTER:\n  {\n    frame = ChildFilters[0].filter->GetFrame(n, env);\n    break;\n  }\n  case MT_MULTI_INSTANCE:\n  {\n    // When called from thread pool then thread IDs are one-to-one mapped to ChildFilters array.\n    // 'modulo' method ensures that no over-addressing can happen.\n    // The number of filter instances are created in EnableMT as such.\n    // Thread pool thread IDs are consecutive numbers, starting with 1.\n    // Prefetch threads are consecutive numbers, starting with 0.\n    // Here we cannot differentiate from where was the filter called.\n    // Note: \n    //   when called from Prefetcher (which has 'num_of_logical_processors' threads instead of nThreads)\n    //   the mapping is not ideal. It can be less or more than the actual instance count.\n    //   E.g. when mapping a thread on a CPU with 8 logical cores \n    //   to a instance count of 3 (nThread=3) the mapping is uneven (modulo example): [0,3,6]->[0] [1,4,7]->[1] [2,5]->[2]\n    size_t clipIndex = IEnv->GetThreadId() % nThreads;\n    auto& child = ChildFilters[clipIndex];\n    std::lock_guard<std::mutex> lock(child.mutex);\n    frame = child.filter->GetFrame(n, env);\n    break;\n  }\n  case MT_SERIALIZED:\n  {\n    std::lock_guard<std::mutex> lock(ChildFilters[0].mutex);\n    // Deadlock situation when GetFrame(0) was called from an Invoke\n    // solved in 3.7.2 by separating memory_mutex from invoke_mutex.\n    frame = ChildFilters[0].filter->GetFrame(n, env);\n    break;\n  }\n  default:\n  {\n    assert(0);\n    env->ThrowError(\"Invalid Avisynth logic.\");\n    break;\n  }\n  } // switch\n\n#ifdef X86_32\n  _mm_empty();\n#endif\n\n  return frame;\n}\n\nvoid __stdcall MTGuard::GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env_)\n{\n  assert(nThreads > 0);\n\n  /* commented out, see MTGuard::GetFrame comments for MT_SERIALIZED\n  if (nThreads == 1)\n  {\n    ChildFilters[0].filter->GetAudio(buf, start, count, env);\n    return;\n  }\n  */\n  InternalEnvironment* IEnv = GetAndRevealCamouflagedEnv(env_);\n  IScriptEnvironment* env = static_cast<IScriptEnvironment*>(IEnv);\n\n\n  switch (MTMode)\n  {\n  case MT_NICE_FILTER:\n    {\n      ChildFilters[0].filter->GetAudio(buf, start, count, env);\n      break;\n    }\n  case MT_MULTI_INSTANCE:\n    {\n      size_t clipIndex = IEnv->GetThreadId() % nThreads;\n      auto& child = ChildFilters[clipIndex];\n      std::lock_guard<std::mutex> lock(child.mutex);\n      child.filter->GetAudio(buf, start, count, env);\n      break;\n    }\n  case MT_SERIALIZED:\n    {\n      std::lock_guard<std::mutex> lock(ChildFilters[0].mutex);\n      ChildFilters[0].filter->GetAudio(buf, start, count, env);\n      break;\n    }\n  default:\n    {\n      assert(0);\n      env->ThrowError(\"Invalid Avisynth logic.\");\n      break;\n    }\n  } // switch\n\n#ifdef X86_32\n  _mm_empty();\n#endif\n}\n\nconst VideoInfo& __stdcall MTGuard::GetVideoInfo()\n{\n  return vi;\n}\n\nbool __stdcall MTGuard::GetParity(int n)\n{\n  return ChildFilters[0].filter->GetParity(n);\n}\n\nint __stdcall MTGuard::SetCacheHints(int cachehints, int frame_range)\n{\n  AVS_UNUSED(frame_range);\n  if (CACHE_GET_MTMODE == cachehints) {\n    return MT_NICE_FILTER;\n  }\n  if (CACHE_IS_MTGUARD_REQ == cachehints) {\n    return CACHE_IS_MTGUARD_ANS;\n  }\n  // Filter-MTGuard-CacheGuard(Cache or nothing)\n  // MTGuard is just a helper over real filters, we pass these requests upstream\n  if (CACHE_GET_AUDIO_POLICY == cachehints || CACHE_GET_AUDIO_SIZE == cachehints ||\n    CACHE_GETCHILD_AUDIO_MODE == cachehints || CACHE_GETCHILD_AUDIO_SIZE == cachehints)\n    return (ChildFilters[0].filter->GetVersion() >= 5) ? ChildFilters[0].filter->SetCacheHints(cachehints, 0) : 0;\n  if (CACHE_GET_DEV_TYPE == cachehints || CACHE_GET_CHILD_DEV_TYPE == cachehints) {\n    return (ChildFilters[0].filter->GetVersion() >= 5) ? ChildFilters[0].filter->SetCacheHints(cachehints, 0) : 0;\n  }\n\n  return 0;\n}\n\nbool __stdcall MTGuard::IsMTGuard(const PClip& p)\n{\n  return ((p->GetVersion() >= 5) && (p->SetCacheHints(CACHE_IS_MTGUARD_REQ, 0) == CACHE_IS_MTGUARD_ANS));\n}\n\n#ifdef AVS_WINDOWS\nPClip MTGuard::Create(MtMode mode, PClip filterInstance, std::unique_ptr<const FilterConstructor> funcCtor, const wchar_t* current_directory, InternalEnvironment* env)\n#else\nPClip MTGuard::Create(MtMode mode, PClip filterInstance, std::unique_ptr<const FilterConstructor> funcCtor, const char* current_directory, InternalEnvironment* env)\n#endif\n{\n    switch (mode)\n    {\n    case MT_NICE_FILTER:\n    {\n      // Put a guard even around MT_NICE_FILTER mode filters, in order EnableMT to\n      // be able to inform the filter (CACHE_SET_NUM_OF_THREAD) about the actual (Prefetch) thread count.\n      return new MTGuard(filterInstance, mode, nullptr, nullptr, env);\n    }\n    case MT_MULTI_INSTANCE: // Fall-through intentional\n    {\n        return new MTGuard(filterInstance, mode, std::move(funcCtor), current_directory, env);\n        // args2 and args3 are not valid after this point anymore\n    }\n    case MT_SERIALIZED:\n    {\n      // Put a guard even around MT_SERIALIZED mode filters, in order EnableMT to\n      // be able to inform the filter (CACHE_SET_NUM_OF_THREAD) about the actual\n      // (1) thread count.\n        return new MTGuard(filterInstance, mode, nullptr, nullptr, env);\n        // args2 and args3 are not valid after this point anymore\n    }\n    default:\n        // There are broken plugins out there in the wild that have (GetVersion() >= 5), but still\n        // return garbage for SetCacheHints(). However, this case should be recognized and\n        // handled earlier, so we can never get to this default-branch. If we do, assume the worst.\n        assert(0);\n        return new MTGuard(filterInstance, MT_SERIALIZED, nullptr, nullptr, env);\n    }\n}\n"
  },
  {
    "path": "avs_core/core/MTGuard.h",
    "content": "#ifndef _AVS_MTGUARD_H\n#define _AVS_MTGUARD_H\n\n#include \"internal.h\"\n#include <vector>\n#include <memory>\n#include <mutex>\n\nclass InternalEnvironment;\n\nclass FilterConstructor;\nstruct MTGuardChildFilter;\nclass MTGuard : public IClip\n{\nprivate:\n  IScriptEnvironment2* Env;\n\n\tstd::unique_ptr<MTGuardChildFilter[]> ChildFilters;\n  size_t nThreads;\n  bool mt_enabled;\n  VideoInfo vi;\n\n  std::unique_ptr<const FilterConstructor> FilterCtor;\n\n#ifdef AVS_WINDOWS\n  std::wstring CurrentDirectory;\n#else\n  std::string CurrentDirectory;\n#endif\n\n  const MtMode MTMode;\n\npublic:\n  ~MTGuard();\n#ifdef AVS_WINDOWS\n  MTGuard(PClip firstChild, MtMode mtmode, std::unique_ptr<const FilterConstructor>&& funcCtor, const wchar_t* current_directory, InternalEnvironment* env);\n#else\n  MTGuard(PClip firstChild, MtMode mtmode, std::unique_ptr<const FilterConstructor>&& funcCtor, const char* current_directory, InternalEnvironment* env);\n#endif\n  void EnableMT(size_t nThreads);\n\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env);\n  const VideoInfo& __stdcall GetVideoInfo();\n  bool __stdcall GetParity(int n);\n  int __stdcall SetCacheHints(int cachehints,int frame_range);\n\n\n  static bool __stdcall IsMTGuard(const PClip& p);\n\n#ifdef AVS_WINDOWS\n  static PClip Create(MtMode mode, PClip filterInstance, std::unique_ptr<const FilterConstructor> funcCtor, const wchar_t* current_directory, InternalEnvironment* env);\n#else\n  static PClip Create(MtMode mode, PClip filterInstance, std::unique_ptr<const FilterConstructor> funcCtor, const char* current_directory, InternalEnvironment* env);\n#endif\n};\n\n#endif // _AVS_MTGUARD_H\n"
  },
  {
    "path": "avs_core/core/MappedList.h",
    "content": "#ifndef _AVS_MAPPED_LIST\n#define _AVS_MAPPED_LIST\n\n#include <list>\n#include <unordered_map>\n\ntemplate <typename T>\nclass mapped_list\n{\nprivate:\n\n  typedef std::list<T> ListType;\n  std::list<T> list;\n  std::unordered_map<T, typename ListType::iterator> map;\n\npublic:\n\n  typedef typename ListType::iterator iterator;\n\n  void push_back(const T& elem)\n  {\n    iterator it = list.insert(list.end(), elem);\n    map.emplace(elem, it);\n  }\n\n  void push_front(const T& elem)\n  {\n    iterator it = list.insert(list.begin(), elem);\n    map.emplace(elem, it);\n  }\n\n  bool empty() const\n  {\n    return list.empty();\n  }\n\n  size_t size() const\n  {\n    return list.size();\n  }\n\n  void remove(const T& elem)\n  {\n    auto map_it = map.find(elem);\n    assert(map_it != map.end());\n\n    iterator list_it = map_it->second;\n    map.erase(map_it);\n    list.erase(list_it);\n  }\n\n  void move_to_back(const T& elem)\n  {\n    auto map_it = map.find(elem);\n    assert(map_it != map.end());\n\n    iterator list_it = map_it->second;\n    list.splice(list.end(), list, list_it);\n  }\n\n  iterator begin()\n  {\n    return list.begin();\n  }\n\n  iterator end()\n  {\n    return list.end();\n  }\n};\n\n#endif // _AVS_MAPPED_LIST\n"
  },
  {
    "path": "avs_core/core/ObjectPool.h",
    "content": "#ifndef _AVS_OBJECTPOOL_H\n#define _AVS_OBJECTPOOL_H\n\n#include <list>\n#include <unordered_map>\n#include <new>\n#include <cassert>\n\ntemplate <typename T>\nclass ObjectPool\n{\nprivate:\n\n  typedef std::list<char*> ListType;\n  ListType UseList;\n  ListType FreeList;\n\n  typedef std::unordered_map<char*, typename ListType::iterator> MapType;\n  MapType Map;\n\n  static void DestructList(ListType* list, bool call_dtor)\n  {\n    const ListType::iterator end_it = list->end();\n    if (call_dtor)\n    {\n      for (ListType::iterator it = list->begin(); it != end_it; ++it)\n      {\n        T* obj = (T*)(*it);\n        obj->~T();\n        delete [] (*it);\n      }\n    }\n    else\n    {\n      for (ListType::iterator it = list->begin(); it != end_it; ++it)\n      {\n        delete [] (*it);\n      }\n    }\n  }\n\n  char * Alloc()\n  {\n    char* buff = NULL;\n    if (!FreeList.empty())\n    {\n      buff = FreeList.front();\n      UseList.splice(UseList.begin(), FreeList, FreeList.begin());\n    }\n    else\n    {\n      buff = new(std::nothrow) char[sizeof(T)];\n      if (buff == NULL)\n        return NULL;\n\n      UseList.emplace_front(buff);\n    }\n\n    Map[buff] = UseList.begin();\n    return buff;\n  }\n\n  void Free(char* obj)\n  {\n    MapType::iterator mit = Map.find(obj);\n    assert(mit != Map.end());\n\n    ListType::iterator lit = mit->second;\n    assert(*lit == obj);\n\n    FreeList.splice(FreeList.begin(), UseList, lit);\n\n    // This line is actually not needed, but very cheap and results in a fully consistent map\n    mit->second = FreeList.begin(); // Needed because MSVC violates spec and invalidates old list iterator\n  }\n\npublic:\n\n\n  // For the unfortunate lack of variadic templates in MSVC++2012\n  T* Construct()\n  {\n    char* buff = Alloc();\n    if (buff == NULL)\n      throw std::bad_alloc();\n\n    try\n    {\n      return new(buff) T();\n    }\n    catch(...)\n    {\n      Free(buff);\n      throw;\n    }\n  }\n\n  // For the unfortunate lack of variadic templates in MSVC++2012\n  template<typename K>\n  T* Construct(const K& param0)\n  {\n    char* buff = Alloc();\n    if (buff == NULL)\n      throw std::bad_alloc();\n\n    try\n    {\n      return new(buff) T(param0);\n    }\n    catch(...)\n    {\n      Free(buff);\n      throw;\n    }\n  }\n\n  void Destruct(T* obj)\n  {\n    obj->~T();\n    Free((char*)obj);\n  }\n\n  ~ObjectPool()\n  {\n    DestructList(&FreeList, false);\n    DestructList(&UseList, true);\n  }\n};\n\n#endif // _AVS_OBJECTPOOL_H\n"
  },
  {
    "path": "avs_core/core/PluginManager.cpp",
    "content": "#include \"PluginManager.h\"\n#include <avisynth.h>\n#include <unordered_set>\n#include <avisynth_c.h>\n#include \"strings.h\"\n#include \"InternalEnvironment.h\"\n#include <cassert>\n#include \"function.h\"\n#include <avs/filesystem.h>\n\n#ifdef AVS_WINDOWS\n  #include <avs/win.h>\n#else\n  #include <avs/posix.h>\n#endif\n\n#ifdef AVS_WINDOWS\n    #include <imagehlp.h>\n#endif\n#include \"parser/script.h\"\n#include \"parser/expression.h\" // TODO we only need FunctionInstance from here\n\ntypedef const char* (__stdcall *AvisynthPluginInit3Func)(IScriptEnvironment* env, const AVS_Linkage* const vectors);\ntypedef const char* (__stdcall *AvisynthPluginInit2Func)(IScriptEnvironment_Avs25* env);\ntypedef const char* (AVSC_CC *AvisynthCPluginInitFunc)(AVS_ScriptEnvironment* env);\n\n#ifdef AVS_WINDOWS // only Windows has a registry we care about\n  const char RegAvisynthKey[] = \"Software\\\\Avisynth\";\n  #if defined (AVS_WINDOWS_X86)\n    #if defined (__GNUC__)\n      const char RegPluginDirPlus_GCC[] = \"PluginDir+GCC\";\n      #if defined(X86_32)\n        #define GCC_WIN32\n      #endif // X86_32\n    #endif // __GNUC__\n  #endif // AVS_WINDOWS_X86\n  const char RegPluginDirClassic[] = \"PluginDir2_5\";\n  const char RegPluginDirPlus[] = \"PluginDir+\";\n#endif // AVS_WINDOWS\n\n#ifdef AVS_POSIX\n#include <dlfcn.h>\n// Redifining these is easier than adding several ifdefs.\n#define HMODULE void*\n#define FreeLibrary dlclose\n#if defined(AVS_MACOS) || defined(AVS_BSD)\n#include <sys/syslimits.h>\n#endif\n#endif\n\n#ifdef AVS_MACOS\n#include <mach-o/dyld.h>\n#endif\n\n/*\n---------------------------------------------------------------------------------\n---------------------------------------------------------------------------------\n                                 Static helpers\n---------------------------------------------------------------------------------\n---------------------------------------------------------------------------------\n*/\n\nvoid IFunction::AddRef() {\n  InterlockedIncrement(&refcnt);\n}\n\nvoid IFunction::Release() {\n  if (InterlockedDecrement(&refcnt) <= 0)\n    delete this;\n}\n\n#ifdef AVS_WINDOWS // translate to Linux error handling\n// Translates a Windows error code to a human-readable text message.\nstatic std::string GetLastErrorText(DWORD nErrorCode)\n{\n  wchar_t* msg;\n  // Ask Windows to prepare a standard message for a GetLastError() code:\n  if (0 == FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, nErrorCode, 0, (LPWSTR)&msg, 0, NULL))\n    return(\"Unknown error\");\n  else\n  {\n    auto msg_utf8 = WideCharToUtf8(msg);\n    std::string ret(msg_utf8.get());\n    LocalFree(msg);\n    return ret;\n  }\n}\n\n// utf8 output\nstatic bool GetRegString(HKEY rootKey, const char path[], const char entry[], std::string* result_utf8) {\n  HKEY AvisynthKey;\n\n  // Convert input path/entry (UTF-8/ANSI) to wide char for Unicode registry API\n  auto path_w = Utf8ToWideChar(path);\n  auto entry_w = Utf8ToWideChar(entry);\n\n  if (RegOpenKeyExW(rootKey, path_w.get(), 0, KEY_READ, &AvisynthKey) != ERROR_SUCCESS)\n    return false;\n\n  DWORD type = 0;\n  DWORD sizeBytes = 0;\n  LONG rc = RegQueryValueExW(AvisynthKey, entry_w.get(), NULL, &type, NULL, &sizeBytes);\n  if (rc != ERROR_SUCCESS) {\n    RegCloseKey(AvisynthKey);\n    return false;\n  }\n\n  // Handle empty value\n  if (sizeBytes == 0) {\n    *result_utf8 = std::string();\n    RegCloseKey(AvisynthKey);\n    return true;\n  }\n\n  // If value is stored as wide string, read via wide API and convert to UTF-8\n  if (type == REG_SZ || type == REG_EXPAND_SZ) {\n    // sizeBytes is number of bytes; number of wchar_t elements:\n    size_t wcharCount = (sizeBytes / sizeof(wchar_t));\n    // Ensure space for a terminating wchar_t\n    std::vector<wchar_t> buf(wcharCount + 1);\n    // Initialize to zero for safety\n    buf.assign(wcharCount + 1, L'\\0');\n\n    rc = RegQueryValueExW(AvisynthKey, entry_w.get(), NULL, &type,\n      reinterpret_cast<LPBYTE>(buf.data()), &sizeBytes);\n    if (rc != ERROR_SUCCESS) {\n      RegCloseKey(AvisynthKey);\n      return false;\n    }\n\n    // Ensure null-termination (sizeBytes may include or exclude terminator)\n    size_t charsRead = (sizeBytes / sizeof(wchar_t));\n    if (charsRead == 0)\n      buf[0] = L'\\0';\n    else\n      buf[std::min(charsRead, buf.size() - 1)] = L'\\0';\n\n    auto utf8 = WideCharToUtf8(buf.data());\n    *result_utf8 = std::string(utf8.get());\n\n    RegCloseKey(AvisynthKey);\n    return true;\n  }\n\n  // Fallback: read ANSI data and convert to UTF-8\n  {\n    DWORD sizeA = 0;\n    rc = RegQueryValueExA(AvisynthKey, entry, NULL, NULL, NULL, &sizeA);\n    if (rc != ERROR_SUCCESS) {\n      RegCloseKey(AvisynthKey);\n      return false;\n    }\n\n    std::vector<char> bufA(sizeA + 1);\n    if (sizeA > 0)\n      memset(bufA.data(), 0, sizeA + 1);\n\n    rc = RegQueryValueExA(AvisynthKey, entry, NULL, NULL,\n      reinterpret_cast<LPBYTE>(bufA.data()), &sizeA);\n    if (rc != ERROR_SUCCESS) {\n      RegCloseKey(AvisynthKey);\n      return false;\n    }\n\n    // Ensure null-terminated\n    bufA[std::min<size_t>(sizeA, bufA.size() - 1)] = '\\0';\n\n    // Convert ANSI -> wide (system codepage) -> UTF-8\n    int wideLen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, bufA.data(), -1, NULL, 0);\n    if (wideLen <= 0) {\n      RegCloseKey(AvisynthKey);\n      return false;\n    }\n    std::vector<wchar_t> wbuf(wideLen + 1);\n    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, bufA.data(), -1, wbuf.data(), wideLen);\n    wbuf[wideLen] = L'\\0';\n\n    auto utf8 = WideCharToUtf8(wbuf.data());\n    *result_utf8 = std::string(utf8.get());\n\n    RegCloseKey(AvisynthKey);\n    return true;\n  }\n}\n\n#endif // AVS_WINDOWS\n\n// see also: AVSFunction::TypeMatch\nstatic bool IsParameterTypeSpecifier(char c) {\n  switch (c) {\n  case 'b': case 'i': case 'f': case 's': case 'c': case '.':\n    // case 'd': case 'l':\n    // from v11 f and i will accept 64 bit data as well\n  case 'n':\n  case 'a': // Arrays as function parameters\n      return true;\n    default:\n      return false;\n  }\n}\n\nstatic bool IsParameterTypeModifier(char c) {\n  switch (c) {\n    case '+': case '*':\n      return true;\n    default:\n      return false;\n  }\n}\n\nstatic bool IsValidParameterString(const char* p) {\n  // does not check for logical errors such as\n  // when unnamed untyped array (.+) is followed by additional parameters\n  int state = 0;\n  char c;\n  while ((c = *p++) != '\\0' && state != -1) {\n    switch (state) {\n      case 0:\n        if (IsParameterTypeSpecifier(c)) {\n          state = 1;\n        }\n        else if (c == '[') {\n          state = 2;\n        }\n        else {\n          state = -1;\n        }\n        break;\n\n      case 1:\n        if (IsParameterTypeSpecifier(c)) {\n          // do nothing; stay in the current state\n        }\n        else if (c == '[') {\n          state = 2;\n        }\n        else if (IsParameterTypeModifier(c)) {\n          state = 0;\n        }\n        else {\n          state = -1;\n        }\n        break;\n\n      case 2:\n        if (c == ']') {\n          state = 3;\n        }\n        else {\n          // do nothing; stay in the current state\n        }\n        break;\n\n      case 3:\n        if (IsParameterTypeSpecifier(c)) {\n          state = 1;\n        }\n        else {\n          state = -1;\n        }\n        break;\n    }\n  }\n\n  // states 0, 1 are the only ending states we accept\n  return state == 0 || state == 1;\n}\n\n/*\n---------------------------------------------------------------------------------\n---------------------------------------------------------------------------------\n                                 AVSFunction\n---------------------------------------------------------------------------------\n---------------------------------------------------------------------------------\n*/\n\nAVSFunction::AVSFunction(void*) :\n    AVSFunction(NULL, NULL, NULL, NULL, NULL, NULL, false, false)\n{}\n\nAVSFunction::AVSFunction(const char* _name, const char* _plugin_basename, const char* _param_types, apply_func_t _apply) :\n    AVSFunction(_name, _plugin_basename, _param_types, _apply, NULL, NULL, false, false)\n{}\n\nAVSFunction::AVSFunction(const char* _name, const char* _plugin_basename, const char* _param_types, apply_func_t _apply, void *_user_data) :\n    AVSFunction(_name, _plugin_basename, _param_types, _apply, _user_data, NULL, false, false)\n{}\n\nAVSFunction::AVSFunction(const char* _name, const char* _plugin_basename, const char* _param_types, apply_func_t _apply, void *_user_data, const char* _dll_path, \n  bool _isPluginAvs25, bool _isPluginPreV11C) :\n    Function()\n{\n  apply = _apply;\n  user_data = _user_data;\n  isPluginAvs25 = _isPluginAvs25;\n  isPluginPreV11C = _isPluginPreV11C;\n\n    if (NULL != _dll_path)\n    {\n        size_t len = strlen(_dll_path);\n        auto tmp = new char[len + 1];\n        memcpy(tmp, _dll_path, len);\n        tmp[len] = 0;\n        dll_path = tmp;\n    }\n\n    if (NULL != _name)\n    {\n        size_t len = strlen(_name);\n        auto tmp = new char[len + 1];\n        memcpy(tmp, _name, len);\n        tmp[len] = 0;\n        name = tmp;\n    }\n\n    if ( NULL != _param_types )\n    {\n        size_t len = strlen(_param_types);\n        auto tmp = new char[len+1];\n        memcpy(tmp, _param_types, len);\n        tmp[len] = 0;\n        param_types = tmp;\n    }\n\n    if ( NULL != _name )\n    {\n        std::string cn(NULL != _plugin_basename ? _plugin_basename : \"\");\n        cn.append(\"_\").append(_name);\n        auto tmp = new char[cn.size()+1];\n        memcpy(tmp, cn.c_str(), cn.size());\n        tmp[cn.size()] = 0;\n        canon_name = tmp;\n    }\n}\n\nAVSFunction::~AVSFunction()\n{\n    delete [] canon_name;\n    delete [] name;\n    delete [] param_types;\n    delete [] dll_path;\n}\n\nbool AVSFunction::empty() const\n{\n    return NULL == name;\n}\n\nbool AVSFunction::IsScriptFunction(const Function* func)\n{\n  return ( (func->apply == &(FunctionInstance::Execute_))\n          || (func->apply == &(ScriptFunction::Execute))\n          || (func->apply == &Eval)\n          || (func->apply == &EvalOop)\n          || (func->apply == &Import)\n        );\n}\n\nbool AVSFunction::SingleTypeMatch(char type, const AVSValue& arg, bool strict) {\n  switch (type) {\n    case '.': return true;\n    case 'b': return arg.IsBool();\n    case 'i': return arg.IsInt(); // IsInt is true for long (int64) parameters as well, worst case they will be AsInt-ed, or can use AsLong\n    case 'f': return arg.IsFloat() && (!strict || !arg.IsInt()); // IsFloat is true for 'double' as well\n    case 's': return arg.IsString();\n    case 'c': return arg.IsClip();\n    case 'n': return arg.IsFunction();\n    case 'a': return arg.IsArray(); // PF 161028 AVS+ script arrays\n    default:  return false;\n  }\n}\n\nbool AVSFunction::SingleTypeMatchArray(char type, const AVSValue& arg, bool strict) {\n  if (!arg.IsArray())\n    return false;\n\n  for (int i = 0; i < arg.ArraySize(); i++)\n  {\n    if (!SingleTypeMatch(type, arg[i], strict))\n      return false;\n  }\n\n  return true;\n}\n\n\nbool AVSFunction::TypeMatch(const char* param_types, const AVSValue* args, size_t num_args, bool strict, IScriptEnvironment* env) {\n\n  bool optional = false;\n\n  /* examples\n  { \"StackHorizontal\", BUILTIN_FUNC_PREFIX, \"cc+\", StackHorizontal::Create },\n  { \"Spline\", BUILTIN_FUNC_PREFIX, \"[x]ff+[cubic]b\", Spline },\n  { \"Select\",   BUILTIN_FUNC_PREFIX, \"i.+\", Select },\n  { \"Array\", BUILTIN_FUNC_PREFIX, \".*\", ArrayCreate },\n  { \"IsArray\",   BUILTIN_FUNC_PREFIX, \".\", IsArray },\n  { \"ArrayGet\",  BUILTIN_FUNC_PREFIX, \".s\", ArrayGet },\n  { \"ArrayGet\",  BUILTIN_FUNC_PREFIX, \".i+\", ArrayGet }, // .+i+ syntax is not possible.\n  { \"ArraySize\", BUILTIN_FUNC_PREFIX, \".\", ArraySize },\n  */\n\n  // arguments are provided in a flattened way (flattened=array elements extracted)\n  // e.g.    string array is provided here string,string,string\n\n  // '*' or '+' to indicate \"zero or more\" or \"one or more\"\n  // '.' matches a single argument of any type. To match multiple arguments of any type, use \".*\" or \".+\".\n\n  size_t i = 0;\n  while (i < num_args) {\n\n    if (*param_types == '\\0') {\n      // more args than params\n      return false;\n    }\n\n    if (*param_types == '[') {\n      // named arg: skip over the name\n      param_types = strchr(param_types+1, ']');\n      if (param_types == NULL) {\n        env->ThrowError(\"TypeMatch: unterminated parameter name (bug in filter)\");\n      }\n\n      ++param_types;\n      optional = true;\n\n      if (*param_types == '\\0') {\n        env->ThrowError(\"TypeMatch: no type specified for optional parameter (bug in filter)\");\n      }\n    }\n\n    if (param_types[1] == '*') {\n      // skip over initial test of type for '*' (since zero matches is ok)\n      ++param_types;\n    }\n\n    // see also: IsParameterTypeSpecifier\n    switch (*param_types) {\n      case 'b': case 'i': case 'f': case 's': case 'c':\n      // case 'd': case 'l':\n      // from v11 f and i will accept 64 bit data as well\n      case 'n':\n      case 'a':\n        // PF 2016: 'a' is special letter for script arrays, but if possible we are using .* and .+ (legacy Avisynth style) instead\n        // Note (2021): 'a' is still not used\n        // cons: no z or nz (+ or *) possibility\n        //       no type check (array of int)\n        //       cannot be used in plugins which are intended to work for Avisynth 2.6 Classic. (\"a\" is invalid in function signature -> plugin load error)\n        // pros: clean syntax, accept _only_ arrays when required, no comma-delimited-list-to-array option (like in old Avisynth syntax)\n        // array arguments are not necessarily \"flattened\" when TypeMatch is called.\n        if (param_types[1] == '+' // parameter indicates an array-type args[i]\n          && args[i].IsArray() // allow single e.g. 'c' parameter in place of a 'c+' requirement\n          && *param_types != 'a'\n          )\n        {\n          ++param_types; // will be found in case '+' section\n          break;\n        }\n\n        if (   (!optional || args[i].Defined())\n            && !SingleTypeMatch(*param_types, args[i], strict))\n          return false;\n\n        ++param_types;\n        ++i;\n        break;\n\n      case '.': // any type\n        // This allows even an array in the place of a \".\"\n        // Use cases: IsArray \".\" can be fed with any AvsValue. ArrayGet \".i+\" requires an array in the place of \".\" as well.\n        // Array-ness of such AVSValue parameters can be checked in the function itself.\n        ++param_types;\n        ++i;\n        break;\n      case '+': case '*':\n        // check array content type if required\n        if (args[i].IsArray() && param_types[-1] != '.') {\n          // A script can provide an array argument in an direct array-type variable.\n          // e.g. a user defined script function function Summa(int_array \"x\") will translate to \"[x]i*\"\n          // parameter list. Passing an integer array directly e.g. [1,2,3] will be handled here.\n          // All elements in the array should match with the type character preceding '+' or '*'\n          // (There was another option in legacy AviSynth: the comma separated values e.g. 1,2,3\n          // could be recognized and moved to an unnamed array, this is check later)\n          if (!SingleTypeMatchArray(param_types[-1], args[i], strict))\n            return false;\n          ++param_types;\n          ++i;\n        }\n        else\n        // Legacy Avisynth array check.\n        // Array of arguments of known types last until an argument of another type is found.\n        // This is the reason why an .+ or .* (array of anything) must only appear at the end\n        // of the parameter list since we cannot detect type-change in an any-type argument sequence.\n        if (!SingleTypeMatch(param_types[-1], args[i], strict)) {\n          // we're done with the + or *, parameter type has been changed\n          ++param_types;\n        }\n        else {\n          // parameter type matched, step parameter pointer but leave type pointer\n          ++i;\n        }\n        break;\n      default:\n        env->ThrowError(\"TypeMatch: invalid character in parameter list (bug in filter)\");\n    }\n  }\n\n  // We're out of args.  We have a match if one of the following is true:\n  // (a) we're out of params.\n  // (b) remaining params are named i.e. optional.\n  // (c) we're at a '+' or '*' and any remaining params are optional.\n\n  if (*param_types == '+'  || *param_types == '*')\n    param_types += 1;\n\n  if (*param_types == '\\0' || *param_types == '[')\n    return true;\n\n  while (param_types[1] == '*') {\n    param_types += 2;\n    if (*param_types == '\\0' || *param_types == '[')\n      return true;\n  }\n\n  return false;\n}\n\nbool AVSFunction::ArgNameMatch(const char* param_types, size_t args_names_count, const char* const* arg_names) {\n\n  for (size_t i=0; i<args_names_count; ++i) {\n    if (arg_names[i]) {\n      bool found = false;\n      size_t len = strlen(arg_names[i]);\n      for (const char* p = param_types; *p; ++p) {\n        if (*p == '[') {\n          p += 1;\n          const char* q = strchr(p, ']');\n          if (!q) return false;\n          if (len == q-p && !_strnicmp(arg_names[i], p, q-p)) {\n            found = true;\n            break;\n          }\n          p = q+1;\n        }\n      }\n      if (!found) return false;\n    }\n  }\n  return true;\n}\n\n/*\n---------------------------------------------------------------------------------\n---------------------------------------------------------------------------------\n                                 PluginFile\n---------------------------------------------------------------------------------\n---------------------------------------------------------------------------------\n*/\n\n\nstruct PluginFile\n{\n  std::string FilePath;             // Fully qualified, canonical file path\n  std::string BaseName;             // Only file name, without extension\n  HMODULE Library;                  // LoadLibrary handle\n  bool isPluginAvs25;\n  bool isPluginPreV11C;\n  bool isPluginC; // we register it, but it won't be used\n\n  PluginFile(const std::string &filePath);\n};\n\nPluginFile::PluginFile(const std::string &filePath) :\n  FilePath(GetFullPathNameWrapUtf8(filePath)), BaseName(), Library(NULL),\n  isPluginAvs25(false), isPluginPreV11C(false), isPluginC(false)\n{\n  // Turn all '\\' into '/'\n  replace(FilePath, '\\\\', '/');\n\n  // Find position of dot in extension\n  size_t dot_pos = FilePath.rfind('.');\n\n  // Find position of last directory slash\n  size_t slash_pos = FilePath.rfind('/');\n\n  // Extract basename\n  if ((dot_pos != std::string::npos) && (slash_pos != std::string::npos))\n  {// we have both a slash and a dot\n    if (dot_pos > slash_pos)\n      BaseName = FilePath.substr(slash_pos+1, dot_pos - slash_pos - 1);\n    else\n      BaseName = FilePath.substr(slash_pos+1, std::string::npos);\n  }\n  else if ((dot_pos == std::string::npos) && (slash_pos != std::string::npos))\n  {// we have a slash but no dot\n    // Extract basename\n    BaseName = FilePath.substr(slash_pos+1, std::string::npos);\n  }\n  else\n  {// everything else\n    // Because we have used GetFullPathName, FilePath should contain an absolute path,\n    // meaning that this case should be unreachable, but the devil never sleeps.\n    assert(0);\n    BaseName = FilePath;\n  }\n}\n\n/*\n---------------------------------------------------------------------------------\n---------------------------------------------------------------------------------\n                                 PluginManager\n---------------------------------------------------------------------------------\n---------------------------------------------------------------------------------\n*/\n\nPluginManager::PluginManager(InternalEnvironment* env) :\n  Env(env), PluginInLoad(NULL), AutoloadExecuted(false), Autoloading(false)\n{\n  env->SetGlobalVar(\"$PluginFunctions$\", AVSValue(\"\"));\n}\n\nvoid PluginManager::ClearAutoloadDirs()\n{\n  if (AutoloadExecuted)\n    Env->ThrowError(\"Cannot modify directory list after the autoload procedure has already executed.\");\n\n  AutoloadDirs.clear();\n}\n\nstatic fs::path PathFromUtf8(const std::string& utf8)\n{\n#ifdef AVS_WINDOWS\n  if (utf8.empty()) return fs::path();\n  auto wstr = Utf8ToWideChar(utf8.c_str());\n  return fs::path(wstr.get());\n#else\n  return fs::path(utf8);\n#endif\n}\n\nvoid PluginManager::AddAutoloadDir(const std::string &dirPath_utf8, bool toFront)\n{\n  if (AutoloadExecuted)\n    Env->ThrowError(\"Cannot modify directory list after the autoload procedure has already executed.\");\n\n  std::string dir(dirPath_utf8);\n\n#if !defined(AVS_BSD)\n// Any use of /proc should be avoided on BSD, since\n// most of them have removed it or discourage its use.\n// Thankfully, it actually looks like the need for it\n// is to simply populate the PROGRAMDIR variable for\n// AddAutoloadDirs, but on POSIX systems this variable\n// should probably not be expected to be as flexible\n// as it is on Windows, negating the need for pulling\n// it out programmatically.  Since the macOS and Linux\n// forms of the code still function, leave those alone.\nstd::string ExeFilePath;\n#ifdef AVS_WINDOWS\n  // get folder of our executable as wide char and convert to UTF-8\n  {\n    WCHAR ExeFilePathW[AVS_MAX_PATH];\n    // Ensure buffer is zeroed (older Windows may not null-terminate)\n    // e.g. WinXP does not terminate the result of GetModuleFileName with a zero, so me must zero our buffer\n    memset(ExeFilePathW, 0, sizeof(ExeFilePathW));\n    DWORD len = GetModuleFileNameW(NULL, ExeFilePathW, AVS_MAX_PATH);\n    if (len == 0) {\n      // Fallback to empty string on failure\n      ExeFilePath.clear();\n    }\n    else {\n      // Convert wide-char path to UTF-8 for internal use\n      auto exe_utf8 = WideCharToUtf8(ExeFilePathW);\n      ExeFilePath = exe_utf8.get();\n    }\n  }\n#else // AVS_POSIX\n  char buf[PATH_MAX + 1] {};\n#ifdef AVS_LINUX\n  if (readlink(\"/proc/self/exe\", buf, sizeof(buf) - 1) != -1)\n#elif defined(AVS_MACOS)\n  uint32_t size = sizeof(buf) - 1;\n  if (_NSGetExecutablePath(buf, &size) == 0)\n#endif // AVS_LINUX\n  {\n    ExeFilePath = buf;\n  }\n#endif\n  std::string ExeFileDir(ExeFilePath);\n  replace(ExeFileDir, '\\\\', '/');\n#ifndef AVS_HAIKU\n// Haiku's exe path stuff differs enough from the *nix OSes\n// that it fails spectacularly when loading the library in a client\n// like avs2yuv or FFmpeg.  Try to skip this for now and hope\n// this doesn't cause more errors.\n  ExeFileDir = ExeFileDir.erase(ExeFileDir.rfind('/'), std::string::npos);\n#endif\n#endif // !AVS_BSD\n\n  // variable expansion\n  // now \"dir\" is utf8, so we can use utf8 variants of macros\n  replace_beginning(dir, \"SCRIPTDIR\", Env->GetVarString(\"$ScriptDirUtf8$\", \"\"));\n  replace_beginning(dir, \"MAINSCRIPTDIR\", Env->GetVarString(\"$MainScriptDirUtf8$\", \"\"));\n#if !defined(AVS_BSD)\n  replace_beginning(dir, \"PROGRAMDIR\", ExeFileDir);\n#endif\n\n  // further macro expansions on Windows\n  std::string plugin_dir;\n#ifdef AVS_WINDOWS\n  // folders are read as utf8, can contain non-ansi characters as well\n  // where registry entry does not exist, delete the whole macro string if it contains only that macro\n  #if defined (AVS_WINDOWS_X86)\n    #if defined (__GNUC__)\n      if (GetRegString(HKEY_CURRENT_USER, RegAvisynthKey, RegPluginDirPlus_GCC, &plugin_dir))\n        replace_beginning(dir, \"USER_PLUS_PLUGINS\", plugin_dir);\n      else\n        replace_beginning(dir, \"USER_PLUS_PLUGINS\", \"\");\n      if (GetRegString(HKEY_LOCAL_MACHINE, RegAvisynthKey, RegPluginDirPlus_GCC, &plugin_dir))\n        replace_beginning(dir, \"MACHINE_PLUS_PLUGINS\", plugin_dir);\n      else\n        replace_beginning(dir, \"MACHINE_PLUS_PLUGINS\", \"\");\n    #else\n      // note: if e.g HKCU/PluginDir+ does not exist, USER_PLUS_PLUGINS as a string remain in search path\n      if (GetRegString(HKEY_CURRENT_USER, RegAvisynthKey, RegPluginDirPlus, &plugin_dir))\n        replace_beginning(dir, \"USER_PLUS_PLUGINS\", plugin_dir);\n      else\n        replace_beginning(dir, \"USER_PLUS_PLUGINS\", \"\");\n      if (GetRegString(HKEY_LOCAL_MACHINE, RegAvisynthKey, RegPluginDirPlus, &plugin_dir))\n        replace_beginning(dir, \"MACHINE_PLUS_PLUGINS\", plugin_dir);\n      else\n        replace_beginning(dir, \"MACHINE_PLUS_PLUGINS\", \"\");\n      if (GetRegString(HKEY_CURRENT_USER, RegAvisynthKey, RegPluginDirClassic, &plugin_dir))\n        replace_beginning(dir, \"USER_CLASSIC_PLUGINS\", plugin_dir);\n      else\n        replace_beginning(dir, \"USER_CLASSIC_PLUGINS\", \"\");\n      if (GetRegString(HKEY_LOCAL_MACHINE, RegAvisynthKey, RegPluginDirClassic, &plugin_dir))\n        replace_beginning(dir, \"MACHINE_CLASSIC_PLUGINS\", plugin_dir);\n      else\n        replace_beginning(dir, \"MACHINE_CLASSIC_PLUGINS\", \"\");\n    #endif // _GNUC_\n  #else\n    if (GetRegString(HKEY_CURRENT_USER, RegAvisynthKey, RegPluginDirPlus, &plugin_dir))\n      replace_beginning(dir, \"USER_PLUS_PLUGINS\", plugin_dir);\n    else\n      replace_beginning(dir, \"USER_PLUS_PLUGINS\", \"\");\n    if (GetRegString(HKEY_LOCAL_MACHINE, RegAvisynthKey, RegPluginDirPlus, &plugin_dir))\n      replace_beginning(dir, \"MACHINE_PLUS_PLUGINS\", plugin_dir);\n    else\n      replace_beginning(dir, \"MACHINE_PLUS_PLUGINS\", \"\");\n\n  #endif // AVS_WINDOWS_X86\n#endif // AVS_WINDOWS\n\n  // replace backslashes with forward slashes\n  replace(dir, '\\\\', '/');\n\n  // append terminating slash if needed\n  if (dir.size() > 0 && dir[dir.size()-1] != '/')\n    dir.append(\"/\");\n\n  // remove double slashes\n  while(replace(dir, \"//\", \"/\"));\n\n  if (dir.empty())\n    return;\n  if (toFront)\n    AutoloadDirs.insert(AutoloadDirs.begin(), GetFullPathNameWrapUtf8(dir));\n  else\n    AutoloadDirs.push_back(GetFullPathNameWrapUtf8(dir));\n}\n\nvoid PluginManager::AutoloadPlugins()\n{\n  if (AutoloadExecuted)\n    return;\n\n  AutoloadExecuted = true;\n  Autoloading = true;\n\n  // Load binary plugins\n  // AutoLoadDirs are utf8 on Windows as well\n  for (const std::string& dir : AutoloadDirs)\n  {\n    std::error_code ec;\n\n#ifdef AVS_POSIX\n#ifdef AVS_MACOS\n    const char* binaryFilter = \".dylib\";\n#else\n    const char* binaryFilter = \".so\";\n#endif\n#else\n    const char* binaryFilter = \".dll\";\n#endif\n\n    // Build platform-native path from UTF-8 directory string\n    fs::path dir_path = PathFromUtf8(dir);\n    if (dir_path.empty())\n      continue;\n\n    for (auto& file : fs::directory_iterator(dir_path, fs::directory_options::skip_permission_denied | fs::directory_options::follow_directory_symlink, ec))\n    {\n#ifdef AVS_POSIX\n      const bool extensionsMatch =\n        file.path().extension() == binaryFilter; // case sensitive\n#else\n      auto ext_w = file.path().extension().wstring();\n      auto ext_utf8 = WideCharToUtf8(ext_w.c_str());\n      const bool extensionsMatch =\n        streqi(ext_utf8.get(), binaryFilter);\n#endif\n\n      if (extensionsMatch)\n      {\n        // Convert filename back to UTF-8 for internal handling (plugin expects UTF-8 strings)\n#ifdef AVS_POSIX\n        std::string filename_utf8 = file.path().filename().generic_string();\n#else\n        auto fn_w = file.path().filename().wstring();\n        auto fn_utf8 = WideCharToUtf8(fn_w.c_str());\n        std::string filename_utf8 = fn_utf8.get();\n#endif\n\n        PluginFile p(concat(dir, filename_utf8)); // utf8 handled\n\n        // Search for loaded plugins with the same base name.\n        bool same_found = false;\n        for (size_t i = 0; i < AutoLoadedPlugins.size(); ++i)\n        {\n#ifdef AVS_POSIX\n          if (AutoLoadedPlugins[i].BaseName == p.BaseName) // case insentitive\n#else\n          if (streqi(AutoLoadedPlugins[i].BaseName.c_str(), p.BaseName.c_str()))\n#endif\n          {\n            // Prevent loading a plugin with a basename that is\n            // already loaded (from another autoload folder).\n            same_found = true;\n            break;\n          }\n        }\n\n        if (same_found)\n          continue;\n\n        // Try to load plugin\n        AVSValue dummy;\n        LoadPlugin(p, false, &dummy);\n      }\n    }\n\n    const char* scriptFilter = \".avsi\";\n    // Build platform-native path again (already available as dir_path)\n    for (auto& file : fs::directory_iterator(dir_path, fs::directory_options::skip_permission_denied | fs::directory_options::follow_directory_symlink, ec)) // and not recursive_directory_iterator\n    {\n      const bool extensionsMatch =\n#ifdef AVS_POSIX\n        file.path().extension() == scriptFilter; // case sensitive\n#else\n        // Convert extension to UTF-8 for comparison\n        ([](const fs::path &p, const char *filter)->bool {\n          auto ext_w = p.extension().wstring();\n          auto ext_utf8 = WideCharToUtf8(ext_w.c_str());\n          return streqi(ext_utf8.get(), filter);\n        })(file.path(), scriptFilter);\n#endif\n\n      if (extensionsMatch)\n      {\n        // CWDChanger expects a char*; we keep passing the UTF-8 dir here (as before).\n        CWDChanger cwdchange(dir.c_str());\n\n#ifdef AVS_POSIX\n        std::string filename_utf8 = file.path().filename().generic_string();\n#else\n        auto fn_w = file.path().filename().wstring();\n        auto fn_utf8 = WideCharToUtf8(fn_w.c_str());\n        std::string filename_utf8 = fn_utf8.get();\n#endif\n\n        PluginFile p(concat(dir, filename_utf8));\n\n        // Search for loaded avsi scripts with the same base name.\n        bool same_found = false;\n        for (size_t i = 0; i < AutoLoadedImports.size(); ++i)\n        {\n#ifdef AVS_POSIX\n          if (AutoLoadedImports[i].BaseName == p.BaseName) // case insensitive\n#else\n          if (streqi(AutoLoadedImports[i].BaseName.c_str(), p.BaseName.c_str()))\n#endif\n          {\n            // Prevent loading an avsi script with a basename that is\n            // already loaded (from another autoload folder).\n            same_found = true;\n            break;\n          }\n        }\n\n        if (same_found)\n          continue;\n\n        // Try to load script\n        Env->Invoke(\"Import\", p.FilePath.c_str()); // FIXME: utf8?\n        AutoLoadedImports.push_back(p);\n      }\n    }\n  }\n\n  Autoloading = false;\n}\n\nPluginManager::~PluginManager()\n{\n  // Delete all AVSFunction objects that we created\n  std::unordered_set<const AVSFunction*> function_set;\n  for (const auto& lists : ExternalFunctions)\n  {\n      const FunctionList& funcList = lists.second;\n      for (const auto& func : funcList)\n        function_set.insert(func);\n  }\n  for (const auto& lists : AutoloadedFunctions)\n  {\n      const FunctionList& funcList = lists.second;\n      for (const auto& func : funcList)\n        function_set.insert(func);\n  }\n  for (const auto& func : function_set)\n  {\n      delete func;\n  }\n\n\n  // Unload plugin binaries\n  for (size_t i = 0; i < LoadedPlugins.size(); ++i)\n  {\n    assert(LoadedPlugins[i].Library);\n    FreeLibrary(LoadedPlugins[i].Library);\n    LoadedPlugins[i].Library = NULL;\n  }\n  for (size_t i = 0; i < AutoLoadedPlugins.size(); ++i)\n  {\n    assert(AutoLoadedPlugins[i].Library);\n    FreeLibrary(AutoLoadedPlugins[i].Library);\n    AutoLoadedPlugins[i].Library = NULL;\n  }\n\n  Env = NULL;\n  PluginInLoad = NULL;\n}\n\nvoid PluginManager::UpdateFunctionExports(const char* funcName, const char* funcParams, const char *exportVar)\n{\n  if (exportVar == NULL)\n    exportVar = \"$PluginFunctions$\";\n\n  // Update $PluginFunctions$\n  const char *oldFnList = Env->GetVarString(exportVar, \"\");\n  std::string FnList(oldFnList);\n  if (FnList.size() > 0)    // if the list is not empty...\n    FnList.push_back(' ');  // ...add a delimiting whitespace\n  FnList.append(funcName);\n  Env->SetGlobalVar(exportVar, AVSValue( Env->SaveString(FnList.c_str(), (int)FnList.size()) ));\n\n  // Update $Plugin!...!Param$\n  std::string param_id;\n  param_id.reserve(128);\n  param_id.append(\"$Plugin!\");\n  param_id.append(funcName);\n  param_id.append(\"!Param$\");\n  Env->SetGlobalVar(Env->SaveString(param_id.c_str(), (int)param_id.size()), AVSValue(Env->SaveString(funcParams)));\n}\n\nbool PluginManager::LoadPlugin(const char* path, bool throwOnError, AVSValue *result)\n{\n  auto pf = PluginFile { path };\n  return LoadPlugin(pf, throwOnError, result);\n}\n#ifdef AVS_WINDOWS\nstatic bool Is64BitDLL(std::string sDLL, bool &bIs64BitDLL)\n{\n  bIs64BitDLL = false;\n  LOADED_IMAGE li;\n\n  if (!MapAndLoad((LPSTR)sDLL.c_str(), NULL, &li, TRUE, TRUE))\n  {\n    //error handling (check GetLastError())\n    return false;\n  }\n\n  if (li.FileHeader->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) //64 bit image\n    bIs64BitDLL = true;\n\n  UnMapAndLoad(&li);\n\n  return true;\n}\n#endif //AVS_WINDOWS\nbool PluginManager::LoadPlugin(PluginFile &plugin, bool throwOnError, AVSValue *result)\n{\n  std::vector<PluginFile>& PluginList = Autoloading ? AutoLoadedPlugins : LoadedPlugins;\n\n  for (size_t i = 0; i < PluginList.size(); ++i)\n  {\n    if (streqi(PluginList[i].FilePath.c_str(), plugin.FilePath.c_str()))\n    {\n      // Imitate successful loading if the plugin is already loaded\n      plugin = PluginList[i];\n      return true;\n    }\n  }\n\n  plugin.isPluginAvs25 = false;\n  plugin.isPluginPreV11C = false;\n  plugin.isPluginC = false;\n\n#ifdef AVS_WINDOWS\n  // Search for dependent DLLs in the plugin's directory too\n  size_t slash_pos = plugin.FilePath.rfind('/');\n  std::string plugin_dir = plugin.FilePath.substr(0, slash_pos);;\n  DllDirChanger dllchange(plugin_dir.c_str());\n\n  // Load the dll into memory\n  plugin.Library = LoadLibraryEx(plugin.FilePath.c_str(), 0, LOAD_WITH_ALTERED_SEARCH_PATH);\n  if (plugin.Library == NULL)\n  {\n    DWORD errCode = GetLastError();\n\n    // Bitness mixing always throws an error, regardless of throwOnError state\n    // By this new behaviour even plugin auto-load will fail\n    bool bIs64BitDLL;\n    bool succ = Is64BitDLL(plugin.FilePath, bIs64BitDLL);\n    if (succ) {\n      const bool selfIs32 = sizeof(void *) == 4;\n      if (selfIs32 && bIs64BitDLL)\n        Env->ThrowError(\"Cannot load a 64 bit DLL in 32 bit Avisynth: '%s'.\\n\", plugin.FilePath.c_str());\n      if (!selfIs32 && !bIs64BitDLL)\n        Env->ThrowError(\"Cannot load a 32 bit DLL in 64 bit Avisynth: '%s'.\\n\", plugin.FilePath.c_str());\n    }\n    if (throwOnError)\n    {\n      Env->ThrowError(\"Cannot load file '%s'. Platform returned code %d:\\n%s\", plugin.FilePath.c_str(), errCode, GetLastErrorText(errCode).c_str());\n    }\n    else\n      return false;\n  }\n#else // AVS_POSIX\n  plugin.Library = dlopen(plugin.FilePath.c_str(), RTLD_LAZY);\n  if (plugin.Library == NULL)\n    Env->ThrowError(\"Cannot load file '%s'. Reason: %s\", plugin.FilePath.c_str(), dlerror());\n#endif\n\n  // Try to load various plugin interfaces\n  std::string avsexception26_message;\n  const int avs26res = TryAsAvs26(plugin, result, avsexception26_message);\n  if (avs26res != 0) // 0: OK, plugin had AvisynthPluginInit3Func\n  {\n    if (avs26res != 1) { // 1: AvisynthPluginInit3Func not found \n      // plugin entry point exists but exception was thrown\n      // Bad plugin, we must report the exception immediately regardless of throwOnError\n      // Message could be from plugin author or, e.g., from env->AddFunction()\n      Env->ThrowError(\"'%s' plugin loading error:\\n%s\", plugin.FilePath.c_str(), avsexception26_message.c_str());\n    }\n\n    if (!TryAsAvsC(plugin, result)) // V11: try avisynth_c_plugin_init2, plugin is 64 bit capable\n    {\n      if (!TryAsAvsPreV11C(plugin, result))  // try avisynth_c_plugin_init, plugin is not 64 bit capable, 64 bit data will be casted down to int/float\n      {\n        if (!TryAsAvs25(plugin, result))\n        {\n          FreeLibrary(plugin.Library);\n          plugin.Library = NULL;\n\n          if (throwOnError)\n            Env->ThrowError(\"'%s' cannot be used as a plugin for AviSynth.\", plugin.FilePath.c_str());\n          else\n            return false;\n        }\n      }\n    }\n  }\n\n  PluginList.push_back(plugin);\n  return true;\n}\n\nstd::string PluginManager::ListAutoloadDirs()\n{\n  // lf separated list, no separator after the last one\n  std::string result;\n  if (!AutoloadDirs.empty()) {\n    result = AutoloadDirs[0];\n    for (size_t i = 1; i < AutoloadDirs.size(); ++i) {\n      result += \"\\n\" + AutoloadDirs[i];\n    }\n  }\n  return result;\n}\n\nconst AVSFunction* PluginManager::Lookup(const FunctionMap& map, const char* search_name, const AVSValue* args, size_t num_args,\n                    bool strict, size_t args_names_count, const char* const* arg_names) const\n{\n    FunctionMap::const_iterator list_it = map.find(search_name);\n    if (list_it == map.end())\n      return NULL;\n\n    for ( FunctionList::const_reverse_iterator func_it = list_it->second.rbegin();\n          func_it != list_it->second.rend();\n          ++func_it)\n    {\n      const AVSFunction *func = *func_it;\n      if (AVSFunction::TypeMatch(func->param_types, args, num_args, strict, Env) &&\n          AVSFunction::ArgNameMatch(func->param_types, args_names_count, arg_names)\n         )\n      {\n        return func;\n      }\n    }\n\n    return NULL;\n}\n\nconst AVSFunction* PluginManager::Lookup(const char* search_name, const AVSValue* args, size_t num_args,\n                    bool strict, size_t args_names_count, const char* const* arg_names) const\n{\n  /* Lookup in non-autoloaded functions first, so that they take priority */\n  const AVSFunction* func = Lookup(ExternalFunctions, search_name, args, num_args, strict, args_names_count, arg_names);\n  if (func != NULL)\n    return func;\n\n  /* If not found, look amongst the autoloaded */\n  return Lookup(AutoloadedFunctions, search_name, args, num_args, strict, args_names_count, arg_names);\n}\n\nbool PluginManager::FunctionExists(const char* name) const\n{\n    bool autoloaded = (AutoloadedFunctions.find(name) != AutoloadedFunctions.end());\n    return autoloaded || (ExternalFunctions.find(name) != ExternalFunctions.end());\n}\n\n// A minor helper function\nstatic bool FunctionListHasDll(const FunctionList &list, const char *dll_path)\n{\n    for (const auto &f : list) {\n        if ( (nullptr == f->dll_path) || (nullptr == dll_path) ) {\n            if (f->dll_path == dll_path) {\n                return true;\n            }\n        } else if (streqi(f->dll_path, dll_path)) {\n            return true;\n        }\n    }\n    return false;\n}\n\nvoid PluginManager::AddFunction(const char* name, const char* params, IScriptEnvironment::ApplyFunc apply, void* user_data, const char *exportVar,\n  bool isCalledFromAvs25Interface,\n  bool isCalledFromPreV11CInterface)\n{\n  if (!IsValidParameterString(params))\n    Env->ThrowError(\"%s has an invalid parameter string (bug in filter)\", name);\n\n  FunctionMap& functions = Autoloading ? AutoloadedFunctions : ExternalFunctions;\n\n  AVSFunction *newFunc = NULL;\n  if (PluginInLoad != NULL)\n  {\n    // either called using IScriptEnvironment_Avs25 or we are inside of a CPPv2.5 plugin load\n    const bool isAvs25like = isCalledFromAvs25Interface || PluginInLoad->isPluginAvs25;\n    \n    // During function instantiation the new V11 64 bit 'l'ong/'d'ouble\n    // parameters must be converted to int/float instead.\n    // If 64->32-bit conversion is not done, the pre-V11 C plugin does not detect \n    // AVS_Value type properly, since the type check is not performed through interface calls.\n    // The 'baked code' in avisynth_c.h does not know about 'l'ong or 'd'ouble type: \n    // IsInt() / IsFloat() or avs_is_int() / avs_is_float() would return false on the new 64 bit types.\n\n    // How Avisynth detects that a C plugin 'knows' about 64 bit types?\n    // - the plugin is 64 bit aware plugin, works with regular IScriptEnvironment\n    //   - When avisynth_c_plugin_init2 is available (PluginInLoad->isPluginC is set)\n    //   - When C client called avs_create_script_environment(ver) with ver>=11.\n    // - the plugin is pre-V11 C plugin and we pass IScriptEnvironment_AvsPreV11C\n    //   - when the plugin responded only to avisynth_c_plugin_init;\n    //     (PluginInLoad->isPluginPerV11C is true)\n    //   - C client called avs_create_script_environment(ver) with ver<11\n    //     (isCalledFromPreV11CInterface is true)\n\n    const bool isPrev11Clike = isCalledFromPreV11CInterface || PluginInLoad->isPluginPreV11C;\n    newFunc = new AVSFunction(name, PluginInLoad->BaseName.c_str(), params, apply, user_data, PluginInLoad->FilePath.c_str(),\n      isAvs25like, isPrev11Clike);\n  }\n  else\n  {\n    // Not plugin load case.\n    // AddFunction or avs_add_function was called by a client\n    // (a C client which directly loads avisynth)\n    // or when called from a cpp v2.5 level script environtment. \n    // isCalledFromAvs25Interface: IScriptEnvironment_Avs25->AddFunction\n    newFunc = new AVSFunction(name, NULL, params, apply, user_data, NULL, \n      isCalledFromAvs25Interface, \n      isCalledFromPreV11CInterface\n    );\n  }\n\n  // Warn user if a function with the same name is already registered by another plugin\n  {\n      const auto &it = functions.find(newFunc->name);\n      if ( (functions.end() != it) && !FunctionListHasDll(it->second, newFunc->dll_path) )\n      {\n          OneTimeLogTicket ticket(LOGTICKET_W1008, newFunc->name);\n          Env->LogMsgOnce(ticket, LOGLEVEL_WARNING, \"%s() is defined by multiple plugins. Calls to this filter might be ambiguous and could result in the wrong function being called.\", newFunc->name);\n      }\n  }\n\n  functions[newFunc->name].push_back(newFunc);\n  UpdateFunctionExports(newFunc->name, newFunc->param_types, exportVar);\n\n  if (NULL != newFunc->canon_name)\n  {\n      // Warn user if a function with the same name is already registered by another plugin\n      {\n          const auto &it = functions.find(newFunc->canon_name);\n          if ((functions.end() != it) && !FunctionListHasDll(it->second, newFunc->dll_path))\n          {\n              OneTimeLogTicket ticket(LOGTICKET_W1008, newFunc->canon_name);\n              Env->LogMsgOnce(ticket, LOGLEVEL_WARNING, \"%s() is defined by multiple plugins. Calls to this filter might be ambiguous and could result in the wrong function being called.\", newFunc->name);\n          }\n      }\n\n      functions[newFunc->canon_name].push_back(newFunc);\n      UpdateFunctionExports(newFunc->canon_name, newFunc->param_types, exportVar);\n  }\n}\n\nstd::string PluginManager::PluginLoading() const\n{\n    if (NULL == PluginInLoad)\n        return std::string();\n    else\n        return PluginInLoad->BaseName;\n}\n\n// 0: success\n// 1: no AvisynthPluginInit3Func\n// 2: Avisynth exception\n// 3: other exception\nint PluginManager::TryAsAvs26(PluginFile &plugin, AVSValue *result, std::string &avsexception_message)\n{\n  extern const AVS_Linkage* const AVS_linkage; // In interface.cpp\n#ifdef AVS_POSIX\n  AvisynthPluginInit3Func AvisynthPluginInit3 = (AvisynthPluginInit3Func)dlsym(plugin.Library, \"AvisynthPluginInit3\");\n#elif defined(GCC_WIN32)\n  AvisynthPluginInit3Func AvisynthPluginInit3 = (AvisynthPluginInit3Func)GetProcAddress(plugin.Library, \"_AvisynthPluginInit3\");\n  if (!AvisynthPluginInit3)\n    AvisynthPluginInit3 = (AvisynthPluginInit3Func)GetProcAddress(plugin.Library, \"AvisynthPluginInit3@8\");\n#else\n  AvisynthPluginInit3Func AvisynthPluginInit3 = (AvisynthPluginInit3Func)GetProcAddress(plugin.Library, \"AvisynthPluginInit3\");\n  if (!AvisynthPluginInit3)\n    AvisynthPluginInit3 = (AvisynthPluginInit3Func)GetProcAddress(plugin.Library, \"_AvisynthPluginInit3@8\");\n#endif\n\n  int success = 0; // O.K.\n  avsexception_message = \"\";\n  if (AvisynthPluginInit3 == NULL)\n    return 1; // not found\n  else\n  {\n    PluginInLoad = &plugin;\n    // a bad plugin can kill everything if it uses e.g. an old IScriptEnvironment2\n    try {\n      *result = AvisynthPluginInit3(Env, AVS_linkage);\n    }\n    catch (const AvisynthError& error) {\n      avsexception_message = error.msg;\n      success = 2;\n    }\n    catch (const std::exception& ex) {\n      avsexception_message = ex.what();\n      success = 3;\n    }\n    catch (...) {\n      avsexception_message = \"Unknown exception\";\n      success = 3;\n    }\n    PluginInLoad = NULL;\n  }\n\n  return success;\n}\n\nbool PluginManager::TryAsAvs25(PluginFile &plugin, AVSValue *result)\n{\n#ifdef AVS_POSIX\n  AvisynthPluginInit2Func AvisynthPluginInit2 = (AvisynthPluginInit2Func)dlsym(plugin.Library, \"AvisynthPluginInit2\");\n#elif defined(GCC_WIN32)\n  AvisynthPluginInit2Func AvisynthPluginInit2 = (AvisynthPluginInit2Func)GetProcAddress(plugin.Library, \"_AvisynthPluginInit2\");\n  if (!AvisynthPluginInit2)\n    AvisynthPluginInit2 = (AvisynthPluginInit2Func)GetProcAddress(plugin.Library, \"AvisynthPluginInit2@4\");\n#else\n  AvisynthPluginInit2Func AvisynthPluginInit2 = (AvisynthPluginInit2Func)GetProcAddress(plugin.Library, \"AvisynthPluginInit2\");\n  if (!AvisynthPluginInit2)\n    AvisynthPluginInit2 = (AvisynthPluginInit2Func)GetProcAddress(plugin.Library, \"_AvisynthPluginInit2@4\");\n#endif\n\n  bool success = true;\n  if (AvisynthPluginInit2 == NULL)\n    return false;\n  else\n  {\n    PluginInLoad = &plugin;\n    // in case of a crash in init2\n    try {\n      // Pass the 2.5 variant IScriptEnvironment, which has different Invoke\n      // and AddFunction method to avoid array copy/free problems.\n      // (NEW_AVSVALUE compatibility: \"baked code\" strikes back)\n\n      // set before AddFunction callbacks happen from the AvisynthPluginInit2 called below\n      plugin.isPluginAvs25 = true;\n      *result = AvisynthPluginInit2(Env->GetEnv25());\n    }\n    catch (...)\n    {\n      success = false;\n    }\n    PluginInLoad = NULL;\n  }\n\n  return success;\n}\n\nbool PluginManager::TryAsAvsPreV11C(PluginFile& plugin, AVSValue* result)\n{\n#ifdef AVS_POSIX\n  AvisynthCPluginInitFunc AvisynthCPluginInit = (AvisynthCPluginInitFunc)dlsym(plugin.Library, \"avisynth_c_plugin_init\");\n#else\n#ifdef _WIN64\n  AvisynthCPluginInitFunc AvisynthCPluginInit = (AvisynthCPluginInitFunc)GetProcAddress(plugin.Library, \"avisynth_c_plugin_init\");\n  if (!AvisynthCPluginInit)\n    AvisynthCPluginInit = (AvisynthCPluginInitFunc)GetProcAddress(plugin.Library, \"_avisynth_c_plugin_init@4\");\n#else // _WIN32\n  AvisynthCPluginInitFunc AvisynthCPluginInit = (AvisynthCPluginInitFunc)GetProcAddress(plugin.Library, \"_avisynth_c_plugin_init@4\");\n  if (!AvisynthCPluginInit)\n    AvisynthCPluginInit = (AvisynthCPluginInitFunc)GetProcAddress(plugin.Library, \"avisynth_c_plugin_init@4\");\n  if (!AvisynthCPluginInit)\n    AvisynthCPluginInit = (AvisynthCPluginInitFunc)GetProcAddress(plugin.Library, \"avisynth_c_plugin_init\");\n#endif\n#endif // AVS_POSIX\n\n  if (AvisynthCPluginInit == NULL)\n    return false;\n  else\n  {\n    PluginInLoad = &plugin;\n    // set before AddFunction callbacks happen from the AvisynthCPluginInit called below\n    plugin.isPluginPreV11C = true; // no array deep copy/free when NEW_AVSVALUE\n    {\n      AVS_ScriptEnvironment e;\n      e.env = Env;\n      AVS_ScriptEnvironment* pe;\n      pe = &e;\n      const char* s = NULL;\n#if defined(X86_32) && defined(MSVC)\n      int callok = 1; // (stdcall)\n      __asm // Tritical - Jan 2006\n      {\n        push eax\n        push edx\n\n        push 0x12345678\t\t// Stash a known value\n\n        mov eax, pe\t\t\t// Env pointer\n        push eax\t\t\t// Arg1\n        call AvisynthCPluginInit\t\t\t// avisynth_c_plugin_init\n\n        lea edx, s\t\t\t// return value is in eax\n        mov DWORD PTR[edx], eax\n\n        pop eax\t\t\t\t// Get top of stack\n        cmp eax, 0x12345678\t// Was it our known value?\n        je end\t\t\t\t// Yes! Stack was cleaned up, was a stdcall\n\n        lea edx, callok\n        mov BYTE PTR[edx], 0 // Set callok to 0 (_cdecl)\n\n        pop eax\t\t\t\t// Get 2nd top of stack\n        cmp eax, 0x12345678\t// Was this our known value?\n        je end\t\t\t\t// Yes! Stack is now correctly cleaned up, was a _cdecl\n\n        mov BYTE PTR[edx], 2 // Set callok to 2 (bad stack)\n        end:\n        pop edx\n          pop eax\n      }\n      switch (callok)\n      {\n      case 0:   // cdecl\n#ifdef AVSC_USE_STDCALL\n        Env->ThrowError(\"Avisynth 2 C Plugin '%s' has wrong calling convention! Must be _stdcall.\", plugin.BaseName.c_str());\n#endif\n        break;\n      case 1:   // stdcall\n#ifndef AVSC_USE_STDCALL\n        Env->ThrowError(\"Avisynth 2 C Plugin '%s' has wrong calling convention! Must be _cdecl.\", plugin.BaseName.c_str());\n#endif\n        break;\n      case 2:\n        Env->ThrowError(\"Avisynth 2 C Plugin '%s' has corrupted the stack.\", plugin.BaseName.c_str());\n      }\n#else\n      s = AvisynthCPluginInit(pe);\n#endif\n      //  if (s == 0)\n      //    Env->ThrowError(\"Avisynth 2 C Plugin '%s' returned a NULL pointer.\", plugin.BaseName.c_str());\n\n      *result = AVSValue(s);\n    }\n    PluginInLoad = NULL;\n  }\n\n  return true;\n}\n\n\n// v11 capable: C plugin implements avisynth_c_plugin_init2!\nbool PluginManager::TryAsAvsC(PluginFile& plugin, AVSValue* result)\n{\n#ifdef AVS_POSIX\n  AvisynthCPluginInitFunc AvisynthCPluginInit = (AvisynthCPluginInitFunc)dlsym(plugin.Library, \"avisynth_c_plugin_init2\");\n#else\n#ifdef _WIN64\n  AvisynthCPluginInitFunc AvisynthCPluginInit = (AvisynthCPluginInitFunc)GetProcAddress(plugin.Library, \"avisynth_c_plugin_init2\");\n  if (!AvisynthCPluginInit)\n    AvisynthCPluginInit = (AvisynthCPluginInitFunc)GetProcAddress(plugin.Library, \"_avisynth_c_plugin_init2@4\");\n#else // _WIN32\n  AvisynthCPluginInitFunc AvisynthCPluginInit = (AvisynthCPluginInitFunc)GetProcAddress(plugin.Library, \"_avisynth_c_plugin_init2@4\");\n  if (!AvisynthCPluginInit)\n    AvisynthCPluginInit = (AvisynthCPluginInitFunc)GetProcAddress(plugin.Library, \"avisynth_c_plugin_init2@4\");\n  if (!AvisynthCPluginInit)\n    AvisynthCPluginInit = (AvisynthCPluginInitFunc)GetProcAddress(plugin.Library, \"avisynth_c_plugin_init2\");\n#endif\n#endif // AVS_POSIX\n\n  if (AvisynthCPluginInit == NULL)\n    return false;\n  else\n  {\n    PluginInLoad = &plugin;\n    // set before AddFunction callbacks happen from the AvisynthCPluginInit called below\n    plugin.isPluginC = true; // no array deep copy/free when NEW_AVSVALUE, but 64 bit data capable\n    {\n      AVS_ScriptEnvironment e;\n      e.env = Env;\n      AVS_ScriptEnvironment* pe;\n      pe = &e;\n      const char* s = NULL;\n#if defined(X86_32) && defined(MSVC)\n      int callok = 1; // (stdcall)\n      __asm // Tritical - Jan 2006\n      {\n        push eax\n        push edx\n\n        push 0x12345678\t\t// Stash a known value\n\n        mov eax, pe\t\t\t// Env pointer\n        push eax\t\t\t// Arg1\n        call AvisynthCPluginInit\t\t\t// avisynth_c_plugin_init\n\n        lea edx, s\t\t\t// return value is in eax\n        mov DWORD PTR[edx], eax\n\n        pop eax\t\t\t\t// Get top of stack\n        cmp eax, 0x12345678\t// Was it our known value?\n        je end\t\t\t\t// Yes! Stack was cleaned up, was a stdcall\n\n        lea edx, callok\n        mov BYTE PTR[edx], 0 // Set callok to 0 (_cdecl)\n\n        pop eax\t\t\t\t// Get 2nd top of stack\n        cmp eax, 0x12345678\t// Was this our known value?\n        je end\t\t\t\t// Yes! Stack is now correctly cleaned up, was a _cdecl\n\n        mov BYTE PTR[edx], 2 // Set callok to 2 (bad stack)\n        end:\n        pop edx\n          pop eax\n      }\n      switch (callok)\n      {\n      case 0:   // cdecl\n#ifdef AVSC_USE_STDCALL\n        Env->ThrowError(\"Avisynth C Plugin '%s' has wrong calling convention! Must be _stdcall.\", plugin.BaseName.c_str());\n#endif\n        break;\n      case 1:   // stdcall\n#ifndef AVSC_USE_STDCALL\n        Env->ThrowError(\"Avisynth C Plugin '%s' has wrong calling convention! Must be _cdecl.\", plugin.BaseName.c_str());\n#endif\n        break;\n      case 2:\n        Env->ThrowError(\"Avisynth C Plugin '%s' has corrupted the stack.\", plugin.BaseName.c_str());\n      }\n#else\n      s = AvisynthCPluginInit(pe);\n#endif\n\n      * result = AVSValue(s);\n    }\n    PluginInLoad = NULL;\n  }\n\n  return true;\n}\n\n/*\n---------------------------------------------------------------------------------\n---------------------------------------------------------------------------------\n                                 LoadPlugin\n---------------------------------------------------------------------------------\n---------------------------------------------------------------------------------\n*/\n\nAVSValue LoadPlugin(AVSValue args, void*, IScriptEnvironment* env)\n{\n  IScriptEnvironment2 *env2 = static_cast<IScriptEnvironment2*>(env);\n\n  bool success = true;\n  const bool utf8 = args[1].AsBool(false); // default: false (ANSI on Windows), n/a on other OS\n  for (int i = 0; i < args[0].ArraySize(); ++i)\n  {\n    AVSValue dummy;\n    auto path_utf8 = charToUtf8(args[0][i].AsString(), utf8);\n    success &= env2->LoadPlugin(path_utf8.c_str(), true, &dummy); // accepts only utf8 paths on all OS\n  }\n\n  return AVSValue(success);\n}\n\nextern const AVSFunction Plugin_functions[] = {\n  {\"LoadPlugin\", BUILTIN_FUNC_PREFIX, \"s+[utf8]b\", LoadPlugin},\n  {\"LoadCPlugin\", BUILTIN_FUNC_PREFIX, \"s+[utf8]b\", LoadPlugin },          // for compatibility with older scripts\n  {\"Load_Stdcall_Plugin\", BUILTIN_FUNC_PREFIX, \"s+[utf8]b\", LoadPlugin },  // for compatibility with older scripts\n  { 0 }\n};\n"
  },
  {
    "path": "avs_core/core/PluginManager.h",
    "content": "#ifndef AVSCORE_PLUGINS_H\n#define AVSCORE_PLUGINS_H\n\n#include <string>\n#include <map>\n#include <vector>\n#include \"internal.h\"\n\nclass InternalEnvironment;\nstruct PluginFile;\n\nstruct StdStriComparer\n{\n  bool operator() (const std::string& lhs, const std::string& rhs) const\n  {\n#if defined(MSVC)\n    return (_strcmpi(lhs.c_str(), rhs.c_str()) < 0);\n#else\n    return (strcasecmp(lhs.c_str(), rhs.c_str()) < 0);\n#endif\n  }\n};\n\ntypedef std::vector<const AVSFunction*> FunctionList;\ntypedef std::map<std::string,FunctionList,StdStriComparer> FunctionMap;\nclass PluginManager\n{\nprivate:\n  InternalEnvironment *Env;\n  PluginFile *PluginInLoad;\n  std::vector<std::string> AutoloadDirs;\n  std::vector<PluginFile> AutoLoadedImports;\n  std::vector<PluginFile> AutoLoadedPlugins;\n  std::vector<PluginFile> LoadedPlugins;\n  FunctionMap ExternalFunctions;\n  FunctionMap AutoloadedFunctions;\n  bool AutoloadExecuted;\n  bool Autoloading;\n\n  int TryAsAvs26(PluginFile &plugin, AVSValue *result, std::string& avsexception_message);\n  bool TryAsAvs25(PluginFile &plugin, AVSValue *result);\n  bool TryAsAvsPreV11C(PluginFile& plugin, AVSValue* result);\n  bool TryAsAvsC(PluginFile &plugin, AVSValue *result);\n\n  const AVSFunction* Lookup(const FunctionMap& map,\n    const char* search_name,\n    const AVSValue* args,\n    size_t num_args,\n    bool strict,\n    size_t args_names_count,\n    const char* const* arg_names) const;\n\n\npublic:\n  PluginManager(InternalEnvironment* env);\n  ~PluginManager();\n\n  void ClearAutoloadDirs();\n  void AddAutoloadDir(const std::string &dir_utf8, bool toFront);\n\n  bool LoadPlugin(PluginFile &plugin, bool throwOnError, AVSValue *result);\n  bool LoadPlugin(const char* path, bool throwOnError, AVSValue *result);\n\n  bool HasAutoloadExecuted() const { return AutoloadExecuted; }\n\n  void UpdateFunctionExports(const char* funcName, const char* funcParams, const char *exportVar);\n\n  std::string ListAutoloadDirs();\n\n  bool FunctionExists(const char* name) const;\n  std::string PluginLoading() const;    // Returns the basename of the plugin DLL that is currently being loaded, or NULL if no plugin is being loaded\n  void AutoloadPlugins();\n  void AddFunction(const char* name, const char* params, IScriptEnvironment::ApplyFunc apply, void* user_data, const char *exportVar,\n    bool isCalledFromAvs25Interface,\n    bool isCalledFromPreV11CInterface);\n  const AVSFunction* Lookup(const char* search_name,\n    const AVSValue* args,\n    size_t num_args,\n    bool strict,\n    size_t args_names_count,\n    const char* const* arg_names) const;\n};\n\n#endif  // AVSCORE_PLUGINS_H\n"
  },
  {
    "path": "avs_core/core/Prefetcher.cpp",
    "content": "#include \"Prefetcher.h\"\n\n#include <vector>\n#include <mutex>\n#include <atomic>\n#ifdef INTEL_INTRINSICS\n#include <mmintrin.h>\n#endif\n#include <avisynth.h>\n#include \"ThreadPool.h\"\n#include \"ObjectPool.h\"\n#include \"LruCache.h\"\n#include \"InternalEnvironment.h\"\n#include \"internal.h\"\n\nstruct PrefetcherJobParams\n{\n  int frame;\n  Prefetcher* prefetcher;\n  LruCache<size_t, PVideoFrame>::handle cache_handle;\n};\n\nstruct PrefetcherPimpl\n{\n  PClip child;\n  VideoInfo vi;\n\n  // The number of threads to use for prefetching\n  const int nThreads;\n\n  // Maximum number of frames to prefetch\n  const int nPrefetchFrames;\n\n  ThreadPool* thread_pool;\n\n  ObjectPool<PrefetcherJobParams> JobParamsPool;\n  std::mutex params_pool_mutex;\n\n  // Contains the pattern we are locked on to\n  int LockedPattern;\n\n  // The number of consecutive frames Pattern has repeated itself\n  int PatternHits;\n\n  // The number of consecutive frames LockedPattern was invalid\n  int PatternMisses;\n\n  // The current pattern that we are not locked on to\n  int Pattern;\n\n  // True if we have found a pattern to lock onto\n  bool IsLocked;\n\n  // The frame number that GetFrame() has been called with the last time\n  int LastRequestedFrame;\n\n  std::shared_ptr<LruCache<size_t, PVideoFrame> > VideoCache;\n  std::atomic<int> running_workers;\n  std::mutex worker_exception_mutex;\n  std::exception_ptr worker_exception;\n  bool worker_exception_present;\n  InternalEnvironment *EnvI;\n\n  PrefetcherPimpl(const PClip& _child, int _nThreads, int _nPrefetchFrames, IScriptEnvironment2 *env2) :\n    child(_child),\n    vi(_child->GetVideoInfo()),\n    nThreads(_nThreads),\n    nPrefetchFrames(_nPrefetchFrames),\n    thread_pool(NULL),\n    LockedPattern(1),\n    PatternHits(0),\n    PatternMisses(0),\n    Pattern(1),\n    IsLocked(false),\n    LastRequestedFrame(0),\n    VideoCache(NULL),\n    running_workers(0),\n    worker_exception_present(0),\n    EnvI(static_cast<InternalEnvironment*>(env2))\n  {\n\t\tthread_pool = EnvI->NewThreadPool(nThreads);\n  }\n\n  ~PrefetcherPimpl()\n  {\n\t\tfor (void* data : thread_pool->Finish()) {\n\t\t\tPrefetcherJobParams *ptr = (PrefetcherJobParams*)data;\n\t\t\tVideoCache->rollback(&ptr->cache_handle);\n\t\t}\n  }\n};\n\n\n// The number of intervals a pattern has to repeat itself to become (un)locked\n#define PATTERN_LOCK_LENGTH 3\n\nAVSValue Prefetcher::ThreadWorker(IScriptEnvironment2* env, void* data)\n{\n  PrefetcherJobParams *ptr = (PrefetcherJobParams*)data;\n  Prefetcher *prefetcher = ptr->prefetcher;\n  int n = ptr->frame;\n  LruCache<size_t, PVideoFrame>::handle cache_handle = ptr->cache_handle;\n\n  {\n    std::lock_guard<std::mutex> lock(prefetcher->_pimpl->params_pool_mutex);\n    prefetcher->_pimpl->JobParamsPool.Destruct(ptr);\n  }\n\n  try\n  {\n    cache_handle.first->value = prefetcher->_pimpl->child->GetFrame(n, env);\n#ifdef INTEL_INTRINSICS\n    #ifdef X86_32\n    _mm_empty();\n    #endif\n#endif\n\n    prefetcher->_pimpl->VideoCache->commit_value(&cache_handle);\n    --(prefetcher->_pimpl->running_workers);\n  }\n  catch(...)\n  {\n    prefetcher->_pimpl->VideoCache->rollback(&cache_handle);\n\n    std::lock_guard<std::mutex> lock(prefetcher->_pimpl->worker_exception_mutex);\n    prefetcher->_pimpl->worker_exception = std::current_exception();\n    prefetcher->_pimpl->worker_exception_present = true;\n    --(prefetcher->_pimpl->running_workers);\n  }\n\n  return AVSValue();\n}\n\nPrefetcher::Prefetcher(const PClip& _child, int _nThreads, int _nPrefetchFrames, IScriptEnvironment *env) :\n  _pimpl(NULL)\n{\n  _pimpl = new PrefetcherPimpl(_child, _nThreads, _nPrefetchFrames, static_cast<IScriptEnvironment2*>(env));\n  _pimpl->VideoCache = std::make_shared<LruCache<size_t, PVideoFrame> >(_pimpl->nPrefetchFrames*2, CACHE_NO_RESIZE);\n}\n\nvoid Prefetcher::Destroy()\n{\n  if (_pimpl)\n  {\n    PrefetcherPimpl *pimpl = _pimpl;\n    delete pimpl;\n\t\t_pimpl = nullptr;\n  }\n}\n\nPrefetcher::~Prefetcher()\n{\n  Destroy();\n}\n\nsize_t Prefetcher::NumPrefetchThreads() const\n{\n  return _pimpl->nThreads;\n}\n\nint __stdcall Prefetcher::SchedulePrefetch(int current_n, int prefetch_start, InternalEnvironment* env)\n{\n  int n = prefetch_start;\n  while ((_pimpl->running_workers < _pimpl->nPrefetchFrames) && (std::abs(n - current_n) < _pimpl->nPrefetchFrames) )\n  {\n    n += _pimpl->IsLocked ? _pimpl->LockedPattern : 1;\n    if (n >= _pimpl->vi.num_frames)\n      break;\n\n    PVideoFrame result;\n    LruCache<size_t, PVideoFrame>::handle cache_handle;\n    switch(_pimpl->VideoCache->lookup(n, &cache_handle, false, result))\n    {\n    case LRU_LOOKUP_NOT_FOUND:\n      {\n        PrefetcherJobParams *p = NULL;\n        {\n          std::lock_guard<std::mutex> lock(_pimpl->params_pool_mutex);\n          p = _pimpl->JobParamsPool.Construct();\n        }\n        p->frame = n;\n        p->prefetcher = this;\n        p->cache_handle = cache_handle;\n        ++_pimpl->running_workers;\n        _pimpl->thread_pool->QueueJob(ThreadWorker, p, env, NULL);\n        break;\n      }\n    case LRU_LOOKUP_FOUND_AND_READY:      // Fall-through intentional\n    case LRU_LOOKUP_NO_CACHE:             // Fall-through intentional\n    case LRU_LOOKUP_FOUND_BUT_NOTAVAIL:\n      {\n        break;\n      }\n    default:\n      {\n        assert(0);\n        break;\n      }\n    }\n  } // switch\n\n  return n;\n}\n\nPVideoFrame __stdcall Prefetcher::GetFrame(int n, IScriptEnvironment* env_)\n{\n  InternalEnvironment* IEnv = GetAndRevealCamouflagedEnv(env_);\n  IScriptEnvironment* env = static_cast<IScriptEnvironment*>(IEnv);\n\n  if (IEnv->GetSuppressThreadCount() > 0) {\n    // do not use thread when invoke running\n    return _pimpl->child->GetFrame(n, env);\n  }\n\n  int pattern = n - _pimpl->LastRequestedFrame;\n  _pimpl->LastRequestedFrame = n;\n  if (pattern == 0)\n    pattern = 1;\n\n  if (_pimpl->IsLocked)\n  {\n    if (_pimpl->LockedPattern == pattern)\n    {\n      _pimpl->PatternHits = 0;    // Tracks Pattern\n      _pimpl->PatternMisses = 0;  // Tracks LockedPattern\n    }\n    else if (_pimpl->Pattern == pattern)\n    {\n      _pimpl->PatternHits++;    // Tracks Pattern\n      _pimpl->PatternMisses++;  // Tracks LockedPattern\n    }\n    else\n    {\n      _pimpl->PatternHits = 0;  // Tracks Pattern\n      _pimpl->PatternMisses++;  // Tracks LockedPattern\n    }\n    _pimpl->Pattern = pattern;\n\n    if ((_pimpl->PatternMisses >= PATTERN_LOCK_LENGTH) && (_pimpl->PatternHits >= PATTERN_LOCK_LENGTH))\n    {\n      _pimpl->LockedPattern = _pimpl->Pattern;\n      _pimpl->PatternHits = 0;    // Tracks Pattern\n      _pimpl->PatternMisses = 0;  // Tracks LockedPattern\n    }\n    else if ((_pimpl->PatternMisses >= PATTERN_LOCK_LENGTH) && (_pimpl->PatternHits < PATTERN_LOCK_LENGTH))\n    {\n      _pimpl->IsLocked = false;\n    }\n  }\n  else\n  {\n    if (_pimpl->Pattern == pattern)\n    {\n      _pimpl->PatternHits++;      // Tracks Pattern\n      _pimpl->PatternMisses = 0;  // Tracks Pattern\n    }\n    else\n    {\n      _pimpl->PatternHits = 0;    // Tracks Pattern\n      _pimpl->PatternMisses++;    // Tracks Pattern\n    }\n\n    if (_pimpl->PatternHits >= PATTERN_LOCK_LENGTH)\n    {\n      _pimpl->LockedPattern = pattern;\n      _pimpl->PatternMisses = 0;  // Tracks Pattern\n      _pimpl->IsLocked = true;\n    }\n  }\n\n\n  {\n    std::lock_guard<std::mutex> lock(_pimpl->worker_exception_mutex);\n    if (_pimpl->worker_exception_present)\n    {\n      std::rethrow_exception(_pimpl->worker_exception);\n    }\n  }\n\n\n  // Prefetch 1\n  int prefetch_pos = SchedulePrefetch(n, n, IEnv);\n\n  // Get requested frame\n  PVideoFrame result;\n  LruCache<size_t, PVideoFrame>::handle cache_handle;\n  // fill result if LRU_LOOKUP_FOUND_AND_READY\n  switch(_pimpl->VideoCache->lookup(n, &cache_handle, true, result))\n  {\n  case LRU_LOOKUP_NOT_FOUND:\n    {\n      try\n      {\n        result = _pimpl->child->GetFrame(n, env); // P.F. fill result before Commit!\n        cache_handle.first->value = result;\n        // cache_handle.first->value = _pimpl->child->GetFrame(n, env); // P.F. before Commit!\n#ifdef INTEL_INTRINSICS\n  #ifdef X86_32\n        _mm_empty();\n  #endif\n#endif\n        _pimpl->VideoCache->commit_value(&cache_handle);\n      }\n      catch(...)\n      {\n        _pimpl->VideoCache->rollback(&cache_handle);\n        throw;\n      }\n      break;\n    }\n  case LRU_LOOKUP_FOUND_AND_READY:\n    {\n    //result = cache_handle.first->value; // old method, result is filled already\n    break;\n    }\n  case LRU_LOOKUP_NO_CACHE:\n    {\n      result = _pimpl->child->GetFrame(n, env);\n      break;\n    }\n  case LRU_LOOKUP_FOUND_BUT_NOTAVAIL:    // Fall-through intentional\n  default:\n    {\n      assert(0);\n      break;\n    }\n  }\n\n  // Prefetch 2\n  SchedulePrefetch(n, prefetch_pos, IEnv);\n\n  return result;\n}\n\nbool __stdcall Prefetcher::GetParity(int n)\n{\n  return _pimpl->child->GetParity(n);\n}\n\nvoid __stdcall Prefetcher::GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env_)\n{\n  InternalEnvironment* IEnv = GetAndRevealCamouflagedEnv(env_);\n  IScriptEnvironment* env = static_cast<IScriptEnvironment*>(IEnv);\n\n  _pimpl->child->GetAudio(buf, start, count, env);\n}\n\nint __stdcall Prefetcher::SetCacheHints(int cachehints, int frame_range)\n{\n  AVS_UNUSED(frame_range);\n  if (CACHE_GET_MTMODE == cachehints)\n    return MT_NICE_FILTER;\n\n  if (CACHE_GET_DEV_TYPE == cachehints)\n    return (_pimpl->child->GetVersion() >= 5) ? _pimpl->child->SetCacheHints(CACHE_GET_DEV_TYPE, 0) : 0;\n\n  return 0;\n}\n\nconst VideoInfo& __stdcall Prefetcher::GetVideoInfo()\n{\n  return _pimpl->vi;\n}\n\nAVSValue Prefetcher::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  InternalEnvironment *envi = static_cast<InternalEnvironment*>(env);\n  PClip child = args[0].AsClip();\n\n  int PrefetchThreads = args[1].AsInt((int)envi->GetEnvProperty(AEP_PHYSICAL_CPUS)+1);\n  int PrefetchFrames = args[2].AsInt(PrefetchThreads * 2);\n\n  if (PrefetchThreads > 0 && PrefetchFrames > 0)\n  {\n    return new Prefetcher(child, PrefetchThreads, PrefetchFrames, env);\n  }\n  else\n    return child;\n}\n"
  },
  {
    "path": "avs_core/core/Prefetcher.h",
    "content": "#ifndef _AVS_FILT_PREFETCHER_H\n#define _AVS_FILT_PREFETCHER_H\n\n#include <avisynth.h>\n\nstruct PrefetcherPimpl;\nclass InternalEnvironment;\n\nclass Prefetcher : public IClip\n{\nprivate:\n\n  PrefetcherPimpl * _pimpl;\n\n  static AVSValue ThreadWorker(IScriptEnvironment2* env, void* data);\n  int __stdcall SchedulePrefetch(int current_n, int prefetch_start, InternalEnvironment* env);\n  Prefetcher(const PClip& _child, int _nThreads, int _nPrefetchFrames, IScriptEnvironment *env);\n\npublic:\n  ~Prefetcher();\n  size_t NumPrefetchThreads() const;\n  virtual PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n  virtual bool __stdcall GetParity(int n);\n  virtual void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env);\n  virtual int __stdcall SetCacheHints(int cachehints, int frame_range);\n  virtual const VideoInfo& __stdcall GetVideoInfo();\n\n  void Destroy();\n\n  static AVSValue Create(AVSValue args, void*, IScriptEnvironment* env);\n\n};\n\n#endif // _AVS_FILT_PREFETCHER_H\n"
  },
  {
    "path": "avs_core/core/ScriptEnvironmentTLS.h",
    "content": "#ifndef _ThreadScriptEnvironment_H\n#define _ThreadScriptEnvironment_H\n\n#include <avisynth.h>\n#ifdef AVS_WINDOWS\n#include <avs/win.h>\n#else\n#include <avs/posix.h>\n#endif\n\n#include <cstdarg>\n#include \"vartable.h\"\n#include \"internal.h\"\n#include \"ThreadPool.h\"\n#include \"BufferPool.h\"\n#include \"DeviceManager.h\"\n#include \"InternalEnvironment.h\"\n\n#endif  // _ThreadScriptEnvironment_H\n"
  },
  {
    "path": "avs_core/core/SimpleLruCache.h",
    "content": "#ifndef AVS_SIMPLELRUCACHE_H\n#define AVS_SIMPLELRUCACHE_H\n\n#include <list>\n#include <functional>\n#include <limits>\n#include <avs/minmax.h>\n\ntemplate<typename K, typename V>\nclass SimpleLruCache\n{\npublic:\n  struct Entry\n  {\n    K key;\n    V value;\n\n    Entry(const K& k) :\n      key(k)\n    {}\n  };\n\n  typedef V value_type;\n  typedef K key_type;\n  typedef typename std::list<Entry>::iterator entry_type;\n\n  typedef std::function<bool(SimpleLruCache*, const Entry&, void*)> EvictEventType;\n\nprivate:\n  size_t MinCapacity;\n  size_t MaxCapacity;\n  size_t RequestedCapacity;\n  size_t RealCapacity;\n  std::list<Entry> Cache;\n  std::list<Entry> Pool;\n\n  void* EventUserData;\n  const EvictEventType EvictEvent;\n\npublic:\n  SimpleLruCache(size_t capacity, const EvictEventType&& evict, void* evData) :\n    MinCapacity(0),\n    MaxCapacity(std::numeric_limits<size_t>::max()),\n    RequestedCapacity(capacity),\n    RealCapacity(capacity),\n    EventUserData(evData),\n    EvictEvent(evict)\n  {\n  }\n\n  size_t size() const\n  {\n    return Cache.size();\n  }\n\n  size_t requested_capacity() const\n  {\n    return RequestedCapacity;\n  }\n\n  size_t capacity() const\n  {\n    return RealCapacity;\n  }\n\n  void limits(size_t* min, size_t* max) const\n  {\n    *min = MinCapacity;\n    *max = MaxCapacity;\n  }\n\n  void set_limits(size_t min, size_t max)\n  {\n    MinCapacity = min;\n    MaxCapacity = max;\n    resize(RequestedCapacity);\n  }\n\n  V* lookup(const K& key, bool *found, bool lookuponly = false)\n  {\n    // Look for an existing cache entry,\n    // and return it when found\n    const entry_type it_end =  Cache.end();\n    for (\n      entry_type it = Cache.begin();\n      it != it_end;\n      ++it\n    )\n    {\n      if (it->key == key)\n      {\n        // Move found element to the front of the list\n        if (it != Cache.begin())\n          Cache.splice(Cache.begin(), Cache, it);\n\n        *found = true;\n        return &(Cache.front().value);\n      }\n    }\n\n    // Nothing found\n    *found = false;\n\n\t\tif (lookuponly) {\n\t\t\treturn NULL;\n\t\t}\n\n    // Evict an old element if the cache is full\n    trim();\n\n    if (RealCapacity != 0)\n    {\n      // See if we can take one from our pool\n      if (!Pool.empty())\n      {\n        Cache.splice(Cache.begin(), Pool, Pool.begin());\n        Cache.front().key = key;\n      }\n      else\n      {\n        Cache.emplace_front(key);\n      }\n\n      return &(Cache.front().value);\n    }\n\n    // Return NULL-storage if we cannot store anything\n    return NULL;\n  }\n\n  void remove(const K& key)\n  {\n    const entry_type it_end =  Cache.end();\n    for (\n      entry_type it = Cache.begin();\n      it != it_end;\n      ++it\n    )\n    {\n      if (it->key == key)\n      {\n        Pool.splice(Pool.begin(), Cache, it);\n        break;\n      }\n    }\n  }\n\n  void trim()\n  {\n    if (Cache.size() > RealCapacity)\n    {\n      size_t nItemsToDelete = Cache.size() - RealCapacity;\n      auto it = --Cache.end();\n      for (size_t i = 0; i < nItemsToDelete; ++i)\n      {\n        auto prev_it = it;\n        bool end = (it == Cache.begin());\n        if (!end)\n        {\n          prev_it = it;\n          --prev_it;\n        }\n\n        if (EvictEvent != NULL)\n        {\n          if (EvictEvent(this, *it, EventUserData))\n          {\n            Pool.splice(Pool.begin(), Cache, it);\n          }\n        }\n        else\n        {\n          // TODO: Do we want the consumer to always define EvictItem?\n          Pool.splice(Pool.begin(), Cache, it);\n        }\n\n        if (!end)\n          it = prev_it;\n      }\n    }\n  }\n\n  void resize(size_t new_cap)\n  {\n    RequestedCapacity = new_cap;\n    RealCapacity = clamp(RequestedCapacity, MinCapacity, MaxCapacity);\n    trim();\n  }\n};\n\n#endif // AVS_SIMPLELRUCACHE_H\n"
  },
  {
    "path": "avs_core/core/ThreadPool.cpp",
    "content": "#include \"ThreadPool.h\"\n#include \"internal.h\"\n#include <cassert>\n#include <thread>\n\nstruct ThreadPoolGenericItemData\n{\n  ThreadWorkerFuncPtr Func;\n  void* Params;\n  AVSPromise* Promise;\n  Device* device;\n};\n\n#include \"mpmc_bounded_queue.h\"\ntypedef mpmc_bounded_queue<ThreadPoolGenericItemData> MessageQueue;\n\nclass ThreadPoolPimpl\n{\npublic:\n  std::vector<std::thread> Threads;\n  MessageQueue MsgQueue;\n  std::mutex Mutex;\n  std::condition_variable FinishCond;\n  size_t NumRunning;\n\n  ThreadPoolPimpl(size_t nThreads) :\n    Threads(),\n    MsgQueue(nThreads * 6)\n  {}\n};\n\nvoid ThreadPool::ThreadFunc(size_t thread_id, ThreadPoolPimpl * const _pimpl, InternalEnvironment* env)\n{\n  auto EnvTLS = env->NewThreadScriptEnvironment((int)thread_id);\n  PInternalEnvironment holder = PInternalEnvironment(EnvTLS);\n\n  while (true)\n  {\n    ThreadPoolGenericItemData data;\n    if (_pimpl->MsgQueue.pop_back(&data) == false) {\n      // threadpool is canceled\n      std::unique_lock<std::mutex> lock(_pimpl->Mutex);\n      if (--_pimpl->NumRunning == 0) {\n        _pimpl->FinishCond.notify_all();\n      }\n      return;\n    }\n\n    EnvTLS->SetCurrentDevice(data.device);\n    EnvTLS->GetSupressCaching() = false;\n    if (data.Promise != NULL)\n    {\n      try\n      {\n        data.Promise->set_value(data.Func(EnvTLS, data.Params));\n      }\n      catch (const AvisynthError&)\n      {\n        data.Promise->set_exception(std::current_exception());\n      }\n      catch (const std::exception&)\n      {\n        data.Promise->set_exception(std::current_exception());\n      }\n      catch (...)\n      {\n        data.Promise->set_exception(std::current_exception());\n        //data.Promise->set_value(AVSValue(\"An unknown exception was thrown in the thread pool.\"));\n      }\n    }\n    else\n    {\n      try\n      {\n        data.Func(EnvTLS, data.Params);\n      }\n      catch (...) {}\n    }\n  } //while\n}\n\nThreadPool::ThreadPool(size_t nThreads, size_t nStartId, InternalEnvironment* env) :\n  _pimpl(new ThreadPoolPimpl(nThreads))\n{\n  _pimpl->Threads.reserve(nThreads);\n\n  std::unique_lock<std::mutex> lock(_pimpl->Mutex);\n\n  // i is used as the thread id. Skip id zero because that is reserved for the main thread.\n  // CUDA: thread id is controled by caller\n  for (size_t i = 0; i < nThreads; ++i)\n    _pimpl->Threads.emplace_back(ThreadFunc, i + nStartId, _pimpl, env);\n\n  _pimpl->NumRunning = nThreads;\n}\n\nvoid ThreadPool::QueueJob(ThreadWorkerFuncPtr clb, void* params, InternalEnvironment* env, JobCompletion* tc)\n{\n  ThreadPoolGenericItemData itemData;\n  itemData.Func = clb;\n  itemData.Params = params;\n  itemData.device = env->GetCurrentDevice();\n\n  if (tc != NULL)\n    itemData.Promise = tc->Add();\n  else\n    itemData.Promise = NULL;\n\n  if (_pimpl->MsgQueue.push_front(std::move(itemData)) == false) {\n    throw AvisynthError(\"Threadpool is cancelled\");\n  }\n}\n\nsize_t ThreadPool::NumThreads() const\n{\n  return _pimpl->Threads.size();\n}\n\nstd::vector<void*> ThreadPool::Finish()\n{\n  std::unique_lock<std::mutex> lock(_pimpl->Mutex);\n  if (_pimpl->NumRunning > 0) {\n    _pimpl->MsgQueue.finish();\n    while (_pimpl->NumRunning > 0)\n    {\n      _pimpl->FinishCond.wait(lock);\n    }\n    std::vector<void*> ret;\n    ThreadPoolGenericItemData item;\n    while (_pimpl->MsgQueue.pop_remain(&item)) {\n      ret.push_back(item.Params);\n    }\n    return ret;\n  }\n  return std::vector<void*>();\n}\n\nvoid ThreadPool::Join()\n{\n  if (_pimpl->Threads.size() > 0) {\n    Finish();\n    for (size_t i = 0; i < _pimpl->Threads.size(); ++i)\n    {\n      if (_pimpl->Threads[i].joinable())\n        _pimpl->Threads[i].join();\n    }\n    _pimpl->Threads.clear();\n  }\n}\n\nThreadPool::~ThreadPool()\n{\n  Finish();\n  Join();\n  delete _pimpl;\n}\n"
  },
  {
    "path": "avs_core/core/ThreadPool.h",
    "content": "#ifndef _AVS_THREADPOOL_H\n#define _AVS_THREADPOOL_H\n\n#include <avisynth.h>\n#include <future>\n#include <vector>\n\ntypedef std::future<AVSValue> AVSFuture;\ntypedef std::promise<AVSValue> AVSPromise;\n\nclass InternalEnvironment;\n\nclass JobCompletion : public IJobCompletion\n{\nprivate:\n  const size_t max_jobs;\n  size_t nJobs;\n\npublic:\n  typedef std::pair<AVSPromise, AVSFuture> PromFutPair;\n  PromFutPair *pairs;\n\n  JobCompletion(size_t _max_jobs) :\n    max_jobs(_max_jobs),\n    nJobs(0),\n    pairs(NULL)\n  {\n    pairs = new PromFutPair[max_jobs];\n\n    // Initialize for first use\n    nJobs = max_jobs;\n    Reset();\n  }\n\n  AVSPromise* Add()\n  {\n    if (nJobs == max_jobs)\n      throw AvisynthError(\"The completion object is already full.\");\n\n    AVSPromise* ret = &(pairs[nJobs].first);\n    ++nJobs;\n    return ret;\n  }\n\n  virtual ~JobCompletion()\n  {\n    Wait();\n    delete [] pairs;\n  }\n\n  void __stdcall Wait()\n  {\n    for (size_t i = 0; i < nJobs; ++i)\n      pairs[i].second.wait();\n  }\n  size_t __stdcall Size() const\n  {\n    return nJobs;\n  }\n  size_t __stdcall Capacity() const\n  {\n    return max_jobs;\n  }\n  AVSValue __stdcall Get(size_t i)\n  {\n    return pairs[i].second.get();\n  }\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wpessimizing-move\"\n#elif defined(__GNUC__)\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wpessimizing-move\"\n#elif defined(_MSC_VER)\n  // Add MSVC-specific pragma if needed\n#endif\n  void __stdcall Reset()\n  {\n    for (size_t i = 0; i < nJobs; ++i)\n    {\n      // To be on the safe side, keep std::move to ensure efficient move semantics, \n      // even if copy elision is possible (despite compiler warnings).\n      // AVSValue does not have a move constructor or move assignment operator. \n      // It only has a copy constructor and copy assignment operator. This means that \n      // AVSValue objects will be copied rather than moved, which can be less efficient.\n      pairs[i].first = std::move(AVSPromise());\n      pairs[i].second = std::move(pairs[i].first.get_future());\n    }\n    nJobs = 0;\n  }\n#ifdef __clang__\n#pragma clang diagnostic pop\n#elif defined(__GNUC__)\n#pragma GCC diagnostic pop\n#elif defined(_MSC_VER)\n  // Add MSVC-specific pragma if needed\n#endif\n  void __stdcall Destroy()\n  {\n    delete this;\n  }\n};\n\nclass ThreadPoolPimpl;\nclass ThreadPool\n{\nprivate:\n  ThreadPoolPimpl* const _pimpl;\n\n  static void ThreadFunc(size_t thread_id, ThreadPoolPimpl* const _pimpl, InternalEnvironment* env);\npublic:\n  ThreadPool(size_t nThreads, size_t nStartId, InternalEnvironment* env);\n  ~ThreadPool();\n\n  void QueueJob(ThreadWorkerFuncPtr clb, void* params, InternalEnvironment* env, JobCompletion* tc);\n  size_t NumThreads() const;\n\n  std::vector<void*> Finish();\n  void Join();\n};\n\n\n#endif  // _AVS_THREADPOOL_H\n"
  },
  {
    "path": "avs_core/core/alignplanar.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// Alignplanar\n// Copyright (c) Klaus Post 2001 - 2005\n\n/******************************\n *******   AlignPlanar   ******\n *****************************/\n\n#include \"avisynth.h\"\n#include \"alignplanar.h\"\n\n\nAlignPlanar::AlignPlanar(PClip _clip) : GenericVideoFilter(_clip) {}\n\nPVideoFrame __stdcall AlignPlanar::GetFrame(int n, IScriptEnvironment* env) {\n  int plane = (env->PlanarChromaAlignment(IScriptEnvironment::PlanarChromaAlignmentTest)) ? PLANAR_U_ALIGNED : PLANAR_Y_ALIGNED;\n\n  PVideoFrame src = child->GetFrame(n, env);\n\n  if (!(src->GetRowSize(plane)&(FRAME_ALIGN-1)))\n    return src;\n\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n\n  if ((dst->GetRowSize(PLANAR_Y_ALIGNED)&(FRAME_ALIGN-1)))\n    env->ThrowError(\"AlignPlanar: [internal error] Returned frame was not aligned!\");\n\n  env->BitBlt(dst->GetWritePtr(), dst->GetPitch(), src->GetReadPtr(), src->GetPitch(), src->GetRowSize(), src->GetHeight());\n  env->BitBlt(dst->GetWritePtr(PLANAR_V), dst->GetPitch(PLANAR_V), src->GetReadPtr(PLANAR_V), src->GetPitch(PLANAR_V), src->GetRowSize(PLANAR_V), src->GetHeight(PLANAR_V));\n  env->BitBlt(dst->GetWritePtr(PLANAR_U), dst->GetPitch(PLANAR_U), src->GetReadPtr(PLANAR_U), src->GetPitch(PLANAR_U), src->GetRowSize(PLANAR_U), src->GetHeight(PLANAR_U));\n\n  return dst;\n}\n\n\nPClip AlignPlanar::Create(PClip clip)\n{\n  if (!clip->GetVideoInfo().IsPlanar()) {  // If not planar, already ok.\n    return clip;\n  }\n  else\n    return new AlignPlanar(clip);\n}\n\n"
  },
  {
    "path": "avs_core/core/alignplanar.h",
    "content": "// Avisynth v2.5.  Copyright 2009 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Align_Planar_H__\n#define __Align_Planar_H__\n\n\nclass AlignPlanar : public GenericVideoFilter\n{\npublic:\n  AlignPlanar(PClip _clip);\n  static PClip Create(PClip clip);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n};\n\n\n#endif //__Align_Planar_H__\n"
  },
  {
    "path": "avs_core/core/arch.h.in",
    "content": "#ifndef _AVS_ARCH_H_\n#define _AVS_ARCH_H_\n\n#define       AVS_ARCH          @AVS_ARCH@\t    \t// e.g. i386\n\n#endif  //  _AVS_ARCH_H_"
  },
  {
    "path": "avs_core/core/audio.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include <avisynth.h>\n\n#ifdef AVS_WINDOWS\n    #include <avs/win.h>\n#else\n    #include <avs/posix.h>\n#endif\n\n#include <avs/minmax.h>\n#include \"internal.h\"\n\n#include \"audio.h\"\n#include \"../convert/convert_audio.h\"\n#include <cstdio>\n#include <cstdlib>\n#include <new>\n#include <algorithm>\n\n#define BIGBUFFSIZE (2048*1024) // Use a 2Mb buffer for EnsureVBRMP3Sync seeking & Normalize scanning\n\n#ifndef INT16_MAX\n#define INT16_MAX 32767\n#endif\n#ifndef INT16_MIN\n#define INT16_MIN  (-32768)\n#endif\n#ifndef INT32_MAX\n#define INT32_MAX 2147483647\n#endif\n#ifndef INT32_MIN\n#define INT32_MIN  (-2147483647 - 1)\n#endif\n#ifndef INT64_MAX\n#define INT64_MAX 9223372036854775807LL\n#endif\n#ifndef INT64_MIN\n#define INT64_MIN  (-9223372036854775807LL - 1)\n#endif\n\nstatic int64_t signed_saturated_add64(int64_t x, int64_t y) {\n  // determine the lower or upper bound of the result\n  int64_t ret = (x < 0) ? INT64_MIN : INT64_MAX;\n  // this is always well defined:\n  // if x < 0 this adds a positive value to INT64_MIN\n  // if x > 0 this subtracts a positive value from INT64_MAX\n  int64_t comp = ret - x;\n  // the condition is equivalent to this longer one.\n#ifdef MSVC_PURE\n  // Due to a compiler bug (bad code gen) in VS2022 MSVC 17.12.3 and before,\n  // the short version of the condition cannot be used safely.\n  // Issue is reported: https://developercommunity.visualstudio.com/t/Bad-code-gen-with-inlined-functions-with/10813706\n  // Workaround is presented here, until the fix.\n  // They seem to have it fixed in 17.13.1. Anyway, we keep this code path separated.\n  if ((x < 0 && y > comp) || (x >= 0 && y <= comp))\n#else\n  if ((x < 0) == (y > comp)) // short, quicker one\n#endif\n    ret = x + y;\n  return ret;\n}\n\n// ----------- Channels\n// ffmpeg extras are not handled, only the first 18 bits\n// which is defined in WAVEFORMATEXTENSIBLE and Avisynth.h AvsChannelMask\n\nstruct channel_name_t {\n  const char* name;\n  const char* description;\n};\n\nstatic const struct channel_name_t channel_names[] = {\n    { \"FL\",  \"front left\"            },\n    { \"FR\",  \"front right\"           },\n    { \"FC\",  \"front center\"          },\n    { \"LFE\", \"low frequency\"         },\n    { \"BL\",  \"back left\"             },\n    { \"BR\",  \"back right\"            },\n    { \"FLC\", \"front left-of-center\"  },\n    { \"FRC\", \"front right-of-center\" },\n    { \"BC\",  \"back center\"           },\n    { \"SL\",  \"side left\"             },\n    { \"SR\",  \"side right\"            },\n    { \"TC\",  \"top center\"            },\n    { \"TFL\", \"top front left\"        },\n    { \"TFC\", \"top front center\"      },\n    { \"TFR\", \"top front right\"       },\n    { \"TBL\", \"top back left\"         },\n    { \"TBC\", \"top back center\"       },\n    { \"TBR\", \"top back right\"        }\n};\n\nconstexpr auto channel_names_size = sizeof(channel_names) / sizeof(channel_name_t);\n\nstruct channel_layout_name {\n  const char* name;\n  ChannelLayoutDescriptor_t layout;\n};\n\nstatic const struct channel_layout_name channel_layout_map[] = {\n    { \"mono\",           AVS_CHANNEL_LAYOUT_MASK_MONO                },\n    { \"stereo\",         AVS_CHANNEL_LAYOUT_MASK_STEREO              },\n    { \"2.1\",            AVS_CHANNEL_LAYOUT_MASK_2POINT1             },\n    { \"3.0\",            AVS_CHANNEL_LAYOUT_MASK_SURROUND            },\n    { \"3.0(back)\",      AVS_CHANNEL_LAYOUT_MASK_2_1                 },\n    { \"4.0\",            AVS_CHANNEL_LAYOUT_MASK_4POINT0             },\n    { \"quad\",           AVS_CHANNEL_LAYOUT_MASK_QUAD                },\n    { \"quad(side)\",     AVS_CHANNEL_LAYOUT_MASK_2_2                 },\n    { \"3.1\",            AVS_CHANNEL_LAYOUT_MASK_3POINT1             },\n    { \"5.0\",            AVS_CHANNEL_LAYOUT_MASK_5POINT0_BACK        },\n    { \"5.0(side)\",      AVS_CHANNEL_LAYOUT_MASK_5POINT0             },\n    { \"4.1\",            AVS_CHANNEL_LAYOUT_MASK_4POINT1             },\n    { \"5.1\",            AVS_CHANNEL_LAYOUT_MASK_5POINT1_BACK        },\n    { \"5.1(side)\",      AVS_CHANNEL_LAYOUT_MASK_5POINT1             },\n    { \"6.0\",            AVS_CHANNEL_LAYOUT_MASK_6POINT0             },\n    { \"6.0(front)\",     AVS_CHANNEL_LAYOUT_MASK_6POINT0_FRONT       },\n    { \"hexagonal\",      AVS_CHANNEL_LAYOUT_MASK_HEXAGONAL           },\n    { \"6.1\",            AVS_CHANNEL_LAYOUT_MASK_6POINT1             },\n    { \"6.1(back)\",      AVS_CHANNEL_LAYOUT_MASK_6POINT1_BACK        },\n    { \"6.1(front)\",     AVS_CHANNEL_LAYOUT_MASK_6POINT1_FRONT       },\n    { \"7.0\",            AVS_CHANNEL_LAYOUT_MASK_7POINT0             },\n    { \"7.0(front)\",     AVS_CHANNEL_LAYOUT_MASK_7POINT0_FRONT       },\n    { \"7.1\",            AVS_CHANNEL_LAYOUT_MASK_7POINT1             },\n    { \"7.1(wide)\",      AVS_CHANNEL_LAYOUT_MASK_7POINT1_WIDE_BACK   },\n    { \"7.1(wide-side)\", AVS_CHANNEL_LAYOUT_MASK_7POINT1_WIDE        },\n    { \"7.1(top)\",       AVS_CHANNEL_LAYOUT_MASK_7POINT1_TOP_BACK    },\n    { \"octagonal\",      AVS_CHANNEL_LAYOUT_MASK_OCTAGONAL           },\n    { \"cube\",           AVS_CHANNEL_LAYOUT_MASK_CUBE                },\n    //{ \"hexadecagonal\",  AV_CHANNEL_LAYOUT_HEXADECAGONAL       }\n    //{ \"downmix\",        AV_CHANNEL_LAYOUT_STEREO_DOWNMIX,     },\n    //{ \"22.2\",           AV_CHANNEL_LAYOUT_22POINT2,           },\n};\n\nconstexpr auto channel_layout_map_size = sizeof(channel_layout_map) / sizeof(channel_layout_name);\n\nstatic unsigned int av_get_default_channel_layout(int nb_channels) {\n  for (int i = 0; i < channel_layout_map_size; i++)\n    if (nb_channels == channel_layout_map[i].layout.nb_channels)\n      return channel_layout_map[i].layout.mask;\n  return 0;\n}\n\n// similar to old ffmpeg method\nstatic unsigned int get_channel_layout_single(const char* name, size_t name_len)\n{\n  // combined layout name\n  for (int i = 0; i < channel_layout_map_size; i++) {\n    if (strlen(channel_layout_map[i].name) == name_len &&\n      !memcmp(channel_layout_map[i].name, name, name_len))\n      return channel_layout_map[i].layout.mask;\n  }\n  // individual channel name\n  for (int i = 0; i < channel_names_size; i++)\n    if (channel_names[i].name &&\n      strlen(channel_names[i].name) == name_len &&\n      !memcmp(channel_names[i].name, name, name_len))\n      return (unsigned int)1 << i;\n\n  //get default by number of channels, syntax: number ending with 'c'\n  char* end;\n  errno = 0;\n  long i = std::strtol(name, &end, 10);\n\n  if (!errno && (end + 1 - name == name_len && *end == 'c'))\n    return av_get_default_channel_layout(i);\n\n  // return the directly given mask\n  errno = 0;\n  long long layout = std::strtoll(name, &end, 0);\n  if (!errno && end - name == name_len) {\n    if (layout > std::numeric_limits<unsigned int>::max())\n      return 0;\n    return (unsigned int)std::max(layout, 0LL);\n  }\n  return 0;\n}\n\n// returns layout mask from the layout name or channel name\n// or from their combinations\nunsigned int av_get_channel_layout(const char* name)\n{\n  const char* n, * e;\n  const char* name_end = name + strlen(name);\n  unsigned int layout = 0, layout_single;\n\n  if(!_stricmp(name, \"speaker_all\"))\n    return AvsChannelMask::MASK_SPEAKER_ALL;\n\n  for (n = name; n < name_end; n = e + 1) {\n    for (e = n; e < name_end && *e != '+' && *e != '|'; e++);\n    layout_single = get_channel_layout_single(n, e - n);\n    if (!layout_single)\n      return 0;\n    layout |= layout_single;\n  }\n  return layout;\n}\n\nunsigned int GetDefaultChannelLayout(int nChannels) {\n  if (nChannels < 1 || nChannels > 8)\n    return 0;\n  return av_get_default_channel_layout(nChannels);\n\n  /* old one:\n  // Called from VfW export as well\n  // 3.7.3 changes some defaults to match ffmpeg\n  // 3 channels: Surround to 2.1\n  // 4 channels: Quad to 4.0\n  // 6 channels: 6.1(back) to 6.1\n  const int SpeakerMasks[9] =\n  { 0,\n    //           chnls name      layout                             ffmpeg\n    0x00004,     // 1  mono      -- -- FC                           AV_CH_LAYOUT_MONO              (AV_CH_FRONT_CENTER)\n    0x00003,     // 2  stereo    FL FR                              AV_CH_LAYOUT_STEREO            (AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT)\n    0x0000B,     // 3  2.1       FL FR    LFE                       AV_CH_LAYOUT_2POINT1           (AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY)\n    // 0x00007,  // 3  3.0       FL FR FC                           AV_CH_LAYOUT_SURROUND          (AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER)\n    0x00107,     // 4  4.0       FL FR FC --  -- -- -- -- BC        AV_CH_LAYOUT_4POINT0           (AV_CH_LAYOUT_SURROUND|AV_CH_BACK_CENTER)\n    // 0x00033,  // 4  quad      FL FR -- --  BL BR                 AV_CH_LAYOUT_QUAD              (AV_CH_LAYOUT_STEREO|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT)\n    0x00037,     // 5  5.0       FL FR FC --  BL BR                 AV_CH_LAYOUT_5POINT0_BACK      (AV_CH_LAYOUT_SURROUND|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT)\n    0x0003F,     // 6  5.1       FL FR FC LFE BL BR                 AV_CH_LAYOUT_5POINT1_BACK      (AV_CH_LAYOUT_5POINT0_BACK|AV_CH_LOW_FREQUENCY)\n    0x0070F,     // 7  6.1       FL FR FC LFE -- -- -- -- BC SL SR  AV_CH_LAYOUT_6POINT1           (AV_CH_LAYOUT_5POINT1|AV_CH_BACK_CENTER)\n    // 0x0013F,  // 7  6.1(back) FL FR FC LFE BL BR -- -- BC        AV_CH_LAYOUT_6POINT1_BACK      (AV_CH_LAYOUT_5POINT1_BACK|AV_CH_BACK_CENTER)\n    0x0063F,     // 8  7.1       FL FR FC LFE BL BR -- -- -- SL SR  AV_CH_LAYOUT_7POINT1           (AV_CH_LAYOUT_5POINT1|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT)\n  };\n  return SpeakerMasks[nChannels];\n  */\n}\n\n// popcount\nstatic int channelcount_from_mask(unsigned int mask)\n{\n  unsigned long long y;\n  y = mask * 0x0002000400080010ULL;\n  y = y & 0x1111111111111111ULL;\n  y = y * 0x1111111111111111ULL;\n  y = y >> 60;\n  return (int)y;\n}\n\n// gets the 'idx'th bit=1 from layout_mask and returns its bit index \n// or -1 if not found\n// index can be used to channel_names\nenum AVSChannel av_channel_layout_channel_from_index(const unsigned int channel_layout_mask,\n    unsigned int idx)\n{\n  const int nb_channels = channelcount_from_mask(channel_layout_mask);\n  if ((int)idx >= nb_channels)\n    return AVSChannel::AVS_CHAN_IDX_NONE;\n\n  for (int i = 0; i < 32; i++) { // unsigned int 32 bits\n    if ((1ULL << i) & channel_layout_mask && !idx--)\n      return (enum AVSChannel)i;\n  }\n\n  return AVSChannel::AVS_CHAN_IDX_NONE;\n}\n\nstd::string channel_layout_to_str(const unsigned int channel_layout_mask)\n{\n  // special\n  if (channel_layout_mask == AvsChannelMask::MASK_SPEAKER_ALL)\n    return \"speaker_all\";\n\n  // find direct match\n  for (int i = 0; i < channel_layout_map_size; i++) {\n    if (channel_layout_mask == channel_layout_map[i].layout.mask) {\n      return channel_layout_map[i].name;\n    }\n  }\n\n  // return channel combo:\n  // e.g. \"2 channels (FC+LFE)\"\n\n  const int nb_channels = channelcount_from_mask(channel_layout_mask);\n\n  std::string bp;\n\n  if (nb_channels)\n    bp = std::to_string(nb_channels) + \" channels (\";\n  for (int i = 0; i < nb_channels; i++) {\n    enum AVSChannel ch = av_channel_layout_channel_from_index(channel_layout_mask, i);\n\n    if (i)\n      bp += \"+\";\n\n    if (ch == AVSChannel::AVS_CHAN_IDX_NONE)\n      bp += \"NONE\";\n    else if ((unsigned int)ch < channel_names_size)\n      bp += channel_names[(unsigned int)ch].name;\n  }\n  if (nb_channels) {\n    bp += \")\";\n    return bp;\n  }\n  bp = \"(Error. Mask=\" + std::to_string(channel_layout_mask) + \")\";\n  return bp;\n}\n\n/********************************************************************\n***** Declare index of new filters for Avisynth's filter engine *****\n********************************************************************/\n\nextern const AVSFunction Audio_filters[] = {\n                                { \"DelayAudio\", BUILTIN_FUNC_PREFIX, \"cf\", DelayAudio::Create },\n                                { \"AmplifydB\", BUILTIN_FUNC_PREFIX, \"cf+\", Amplify::Create_dB },\n                                { \"Amplify\", BUILTIN_FUNC_PREFIX, \"cf+\", Amplify::Create },\n                                { \"AssumeSampleRate\", BUILTIN_FUNC_PREFIX, \"ci\", AssumeRate::Create },\n                                { \"Normalize\", BUILTIN_FUNC_PREFIX, \"c[volume]f[show]b\", Normalize::Create },\n                                { \"MixAudio\", BUILTIN_FUNC_PREFIX, \"cc[clip1_factor]f[clip2_factor]f\", MixAudio::Create },\n                                { \"ResampleAudio\", BUILTIN_FUNC_PREFIX, \"ci[]i\", ResampleAudio::Create },\n                                { \"ConvertToMono\", BUILTIN_FUNC_PREFIX, \"c\", ConvertToMono::Create },\n                                { \"EnsureVBRMP3Sync\", BUILTIN_FUNC_PREFIX, \"c\", EnsureVBRMP3Sync::Create },\n                                { \"MergeChannels\", BUILTIN_FUNC_PREFIX, \"c+\", MergeChannels::Create },\n                                { \"MonoToStereo\", BUILTIN_FUNC_PREFIX, \"cc\", MergeChannels::Create },\n                                { \"GetLeftChannel\", BUILTIN_FUNC_PREFIX, \"c\", GetChannel::Create_left },\n                                { \"GetRightChannel\", BUILTIN_FUNC_PREFIX, \"c\", GetChannel::Create_right },\n                                { \"GetChannel\", BUILTIN_FUNC_PREFIX, \"ci+\", GetChannel::Create_n },\n                                { \"GetChannels\", BUILTIN_FUNC_PREFIX, \"ci+\", GetChannel::Create_n },     // Alias to ease use!\n                                { \"KillVideo\", BUILTIN_FUNC_PREFIX, \"c\", KillVideo::Create },\n                                { \"KillAudio\", BUILTIN_FUNC_PREFIX, \"c\", KillAudio::Create },\n                                { \"ConvertAudioTo16bit\", BUILTIN_FUNC_PREFIX, \"c\", ConvertAudio::Create_16bit },   // in convertaudio.cpp\n                                { \"ConvertAudioTo8bit\", BUILTIN_FUNC_PREFIX, \"c\", ConvertAudio::Create_8bit },\n                                { \"ConvertAudioTo24bit\", BUILTIN_FUNC_PREFIX, \"c\", ConvertAudio::Create_24bit },\n                                { \"ConvertAudioTo32bit\", BUILTIN_FUNC_PREFIX, \"c\", ConvertAudio::Create_32bit },\n                                { \"ConvertAudioToFloat\", BUILTIN_FUNC_PREFIX, \"c\", ConvertAudio::Create_float },\n                                { \"ConvertAudio\", BUILTIN_FUNC_PREFIX, \"cii\", ConvertAudio::Create_Any }, // For plugins to Invoke()\n                                { \"SetChannelMask\", BUILTIN_FUNC_PREFIX, \"cbi\", SetChannelMask::Create },\n                                { \"SetChannelMask\", BUILTIN_FUNC_PREFIX, \"cs\", SetChannelMask::Create },\n                                { 0 }\n                              };\n\n// Note - floats should not be clipped - they will be clipped, when they are converted back to ints.\n// Vdub can handle 8/16 bit, and reads 32bit, but cannot play/convert it. Floats doesn't make sense\n// in AVI. So for now convert back to 16 bit always.\n\n// Always! FIXME: Most int64's are often cropped to ints - count is ok to be int, but not start\n\n// For plugins to env->Invoke()\n\nAVSValue __cdecl ConvertAudio::Create_Any(AVSValue args, void*, IScriptEnvironment*) {\n  return Create(args[0].AsClip(), args[1].AsInt(), args[2].AsInt());\n}\n\n// For explicit conversions\n\nAVSValue __cdecl ConvertAudio::Create_16bit(AVSValue args, void*, IScriptEnvironment*) {\n  return Create(args[0].AsClip(), SAMPLE_INT16, SAMPLE_INT16);\n}\n\nAVSValue __cdecl ConvertAudio::Create_8bit(AVSValue args, void*, IScriptEnvironment*) {\n  return Create(args[0].AsClip(), SAMPLE_INT8, SAMPLE_INT8);\n}\n\n\nAVSValue __cdecl ConvertAudio::Create_32bit(AVSValue args, void*, IScriptEnvironment*) {\n  return Create(args[0].AsClip(), SAMPLE_INT32, SAMPLE_INT32);\n}\n\nAVSValue __cdecl ConvertAudio::Create_float(AVSValue args, void*, IScriptEnvironment*) {\n  return Create(args[0].AsClip(), SAMPLE_FLOAT, SAMPLE_FLOAT);\n}\n\nAVSValue __cdecl ConvertAudio::Create_24bit(AVSValue args, void*, IScriptEnvironment*) {\n  return Create(args[0].AsClip(), SAMPLE_INT24, SAMPLE_INT24);\n}\n\n\n#if defined(X86_32) && defined(MSVC) && !defined(__clang__)\nvoid FilterUD_mmx(short *Xp, unsigned Ph, int _inc, int _dhb, short *p_Imp, unsigned End);\n#endif\n\n\n/*************************************\n *******   Assume SampleRate  ********\n *************************************/\n\nAssumeRate::AssumeRate(PClip _clip, int _rate)\n    : NonCachedGenericVideoFilter(_clip) {\n  if (_rate < 0)\n    _rate = 0;\n  if (vi.SamplesPerSecond() == 0)  // Don't add audio if none is present.\n    _rate = 0;\n\n  vi.audio_samples_per_second = _rate;\n}\n\nAVSValue __cdecl AssumeRate::Create(AVSValue args, void*, IScriptEnvironment*) {\n  return new AssumeRate(args[0].AsClip(), args[1].AsInt());\n}\n\n\n\n\n\n/******************************************\n *******   Convert Audio -> Mono     ******\n *******   Supports int16 & float    ******\n *****************************************/\n\nConvertToMono::ConvertToMono(PClip _clip) :\n  GenericVideoFilter(ConvertAudio::Create(_clip, SAMPLE_INT16 | SAMPLE_FLOAT, SAMPLE_FLOAT)),\n  tempbuffer(NULL)\n{\n  channels = vi.AudioChannels();\n  vi.nchannels = 1;\n  vi.SetChannelMask(true, AvsChannelMask::MASK_SPEAKER_FRONT_CENTER);\n  tempbuffer_size = 0;\n}\n\n\nvoid __stdcall ConvertToMono::GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) {\n  if (tempbuffer_size) {\n    if (tempbuffer_size < count) {\n      delete[] tempbuffer;\n      tempbuffer = new char[(unsigned)(count * channels * vi.BytesPerChannelSample())];\n      tempbuffer_size = (int)count;\n    }\n  } else {\n    tempbuffer = new char[(unsigned)(count * channels * vi.BytesPerChannelSample())];\n    tempbuffer_size = (int)count;\n  }\n\n  child->GetAudio(tempbuffer, start, count, env);\n\n  if (vi.IsSampleType(SAMPLE_INT16)) {\n    signed short* samples = (signed short*)buf;\n    signed short* tempsamples = (signed short*)tempbuffer;\n    const int rchannels = 65536 / channels;\n\n    for (int i = 0; i < (int)count; i++) { // Defeat slow default \"(int64_t)i < count\"\n      int tsample = 0;\n      for (int j = 0 ; j < channels; j++)\n        tsample += *tempsamples++; // Accumulate samples\n      samples[i] = (signed short)((tsample * rchannels + 32768) >> 16); // tsample * (1/channels) + 0.5\n    }\n  }\n  else if (vi.IsSampleType(SAMPLE_FLOAT)) {\n    SFLOAT* samples = (SFLOAT*)buf;\n    SFLOAT* tempsamples = (SFLOAT*)tempbuffer;\n    const SFLOAT f_rchannels = SFLOAT(1.0 / channels);\n\n    for (int i = 0; i < (int)count; i++) { // Defeat slow default \"(int64_t)i < count\"\n      SFLOAT tsample = 0.0f;\n      for (int j = 0 ; j < channels; j++)\n        tsample += *tempsamples++; // Accumulate samples\n      samples[i] = (tsample * f_rchannels);\n    }\n  }\n}\n\nint __stdcall ConvertToMono::SetCacheHints(int cachehints, int frame_range) {\n  AVS_UNUSED(frame_range);\n\n  switch (cachehints) {\n  case CACHE_GET_MTMODE:\n    return MT_SERIALIZED;\n  default:\n    break;\n  }\n  return 0;\n}\n\nPClip ConvertToMono::Create(PClip clip) {\n  if (!clip->GetVideoInfo().HasAudio())\n    return clip;\n  if (clip->GetVideoInfo().AudioChannels() == 1)\n    return clip;\n  else\n    return new ConvertToMono(clip);\n}\n\nAVSValue __cdecl ConvertToMono::Create(AVSValue args, void*, IScriptEnvironment*) {\n  return Create(args[0].AsClip());\n}\n\n/******************************************\n *******   Ensure VBR mp3 sync,      ******\n *******    by always reading audio  ******\n *******    sequencial.              ******\n *****************************************/\n\n// EnsureVBRMP3Sync adds a 1MB audio cache and causes a high penalty for any out of order\n// accesses outside the audio cache: a seek to zero plus a linear read up to the new position.\n\nEnsureVBRMP3Sync::EnsureVBRMP3Sync(PClip _clip)\n    : GenericVideoFilter(_clip) {\n  last_end = 0;\n}\n\n\nvoid __stdcall EnsureVBRMP3Sync::GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) {\n\n  if (start != last_end) { // Reread!\n    int64_t bcount = count;\n    int64_t offset = 0;\n    char* samples = (char*)buf;\n    bool bigbuff=false;\n\n    if (start > last_end)\n      offset = last_end; // Skip forward only if the skipped to position is in front of last position.\n\n  if ((count < start-offset) && (vi.BytesFromAudioSamples(count) < BIGBUFFSIZE)) {\n    samples = new(std::nothrow) char[BIGBUFFSIZE];\n    if (samples) {\n      bigbuff=true;\n      bcount = vi.AudioSamplesFromBytes(BIGBUFFSIZE);\n    }\n    else {\n      samples = (char*)buf; // malloc failed just reuse clients buffer\n    }\n  }\n    while (offset + bcount < start) { // Read whole blocks of 'bcount' samples\n      child->GetAudio(samples, offset, bcount, env);\n      offset += bcount;\n    } // Read until 'start'\n    child->GetAudio(samples, offset, start - offset, env);  // Now we're at 'start'\n    offset += start - offset;\n    if (bigbuff) delete[] samples;\n    if (offset != start)\n      env->ThrowError(\"EnsureVBRMP3Sync [Internal error]: Offset should be %i, but is %i\", start, offset);\n  }\n  child->GetAudio(buf, start, count, env);\n  last_end = start + count;\n}\n\n\nint __stdcall EnsureVBRMP3Sync::SetCacheHints(int cachehints, int frame_range) {\n  AVS_UNUSED(frame_range);\n  // Enable CACHE_AUDIO on parent cache and juice it up to 1Mb\n\n  switch (cachehints) {\n    case CACHE_GET_MTMODE:\n      return MT_SERIALIZED;\n\n    case CACHE_GETCHILD_AUDIO_MODE: // Parent Cache asking Child for desired audio cache mode\n      return CACHE_AUDIO;\n\n    case CACHE_GETCHILD_AUDIO_SIZE: // Parent Cache asking Child for desired audio cache size\n      return 1024*1024;\n\n    default:\n      break;\n  }\n  return 0;\n}\n\nAVSValue __cdecl EnsureVBRMP3Sync::Create(AVSValue args, void*, IScriptEnvironment*) {\n  return new EnsureVBRMP3Sync(args[0].AsClip());\n}\n\n\n/*******************************************\n *******   Mux 'N' sources, so the      ****\n *******   total channels is the sum of ****\n *******   the channels in the 'N' clip ****\n *******************************************/\n\nMergeChannels::MergeChannels(PClip _clip, int _num_children, PClip* _child_array, IScriptEnvironment* env) :\n  GenericVideoFilter(_clip), tempbuffer(NULL), child_array(_child_array), num_children(_num_children)\n{\n  clip_channels = new int[num_children];\n  clip_offset = new signed char * [num_children];\n  clip_channels[0] = vi.AudioChannels();\n\n  for (int i = 1;i < num_children;i++) {\n    PClip tclip = child_array[i];\n    child_array[i] = ConvertAudio::Create(tclip, vi.SampleType(), vi.SampleType());  // Clip 2 should now be same type as clip 1.\n    const VideoInfo& vi2 = child_array[i]->GetVideoInfo();\n\n    if (vi.audio_samples_per_second != vi2.audio_samples_per_second) {\n      env->ThrowError(\"MergeChannels: Clips must have same sample rate! Use ResampleAudio()!\");  // Could be removed for fun :)\n    }\n    if (vi.SampleType() != vi2.SampleType())\n      env->ThrowError(\"MergeChannels: Clips must have same sample type! Use ConvertAudio()!\");    // Should never happend!\n    clip_channels[i] = vi2.AudioChannels();\n    vi.nchannels += vi2.AudioChannels();\n  }\n\n  if (vi.AudioChannels() <= 8)\n    vi.SetChannelMask(true, GetDefaultChannelLayout(vi.AudioChannels()));\n  else\n    vi.SetChannelMask(false, 0); // over 8: no guess\n\n  tempbuffer_size = 0;\n}\n\nMergeChannels::~MergeChannels() {\n  if (tempbuffer_size) {\n    delete[] tempbuffer;\n    tempbuffer_size=0;\n  }\n  delete[] clip_channels;\n  delete[] clip_offset;\n  delete[] child_array;\n}\n\n\nvoid __stdcall MergeChannels::GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) {\n  if (tempbuffer_size < count) {\n    if (tempbuffer_size) delete[] tempbuffer;\n    tempbuffer = new signed char[(unsigned)(count * vi.BytesPerAudioSample())];\n    tempbuffer_size = (int)count;\n  }\n  // Get audio:\n  const int channel_offset = (int)count * vi.BytesPerChannelSample();  // Offset per channel\n  int i, c_channel = 0;\n\n  for (i = 0;i < num_children;i++) {\n    child_array[i]->GetAudio(tempbuffer + (c_channel*channel_offset), start, count, env);\n    clip_offset[i] = tempbuffer + (c_channel * channel_offset);\n    c_channel += clip_channels[i];\n  }\n\n  // Interleave channels\n  char* samples = (char*) buf;\n  const int bpcs = vi.BytesPerChannelSample();\n  const int bps = vi.BytesPerAudioSample();\n  int dst_offset = 0;\n  for (i = 0;i < num_children;i++) {\n    signed char* src_buf = clip_offset[i];\n  const int bpcc = bpcs*clip_channels[i];\n\n  switch (bpcc) {\n\n  case 2: { // mono 16 bit\n        for (int l = 0, k=dst_offset; l < count; l++, k+=bps) {\n          *(short*)(samples+k) = ((short*)src_buf)[l];\n        }\n        break;\n      }\n  case 4: { // mono float/32 bit, stereo 16 bit\n        for (int l = 0, k=dst_offset; l < count; l++, k+=bps) {\n          *(int*)(samples+k) = ((int*)src_buf)[l];\n        }\n        break;\n      }\n  case 8: { // stereo float/32 bit\n#ifdef INTEL_INTRINSICS\n#if defined(X86_32) && defined(MSVC)\n    if (env->GetCPUFlags() & CPUF_MMX)\n    {\n      __asm\n      {\n        mov eax,[src_buf]\n        mov edi,[samples]\n        mov ecx,dword ptr[count]\n        add edi,[dst_offset]\n        test ecx,ecx\n        mov edx,[bps]    ; bytes per strip\n        jz done\n        shr ecx,1        ; CF=count&1, count>>=1\n        jnc label        ; count was even\n\n        movq mm1,[eax]    ; do 1 odd quad\n        add eax,8\n        movq [edi],mm1\n        add edi,edx\n        test ecx,ecx\n        jz done\n        align 16\n      label:\n        movq mm0,[eax]    ; do pairs of quads\n        movq mm1,[eax+8]\n        add eax,16\n        movq [edi],mm0\n        movq [edi+edx],mm1\n        lea edi,[edi+edx*2]\n        loop label\n      done:\n        emms\n      }\n    }\n    else\n#endif // X86_32\n#endif\n    {\n      for (int l = 0, k=dst_offset; l < count; l++, k+=bps)\n      {\n        *(int64_t*)(samples+k) = ((int64_t*)src_buf)[l];\n      }\n    }\n        break;\n      }\n  default: { // everything else, 1 byte at a time\n        for (int l = 0; l < count; l++) {\n          for (int k = 0; k < bpcc; k++) {\n            samples[dst_offset + (l*bps) + k] = src_buf[(l*bpcc) + k];\n          }\n        }\n      }\n    }\n    dst_offset += bpcc;\n  }\n}\n\nint __stdcall MergeChannels::SetCacheHints(int cachehints, int frame_range) {\n  AVS_UNUSED(frame_range);\n\n  switch (cachehints) {\n  case CACHE_GET_MTMODE:\n    return MT_SERIALIZED;\n  default:\n    break;\n  }\n  return 0;\n}\n\nAVSValue __cdecl MergeChannels::Create(AVSValue args, void*, IScriptEnvironment* env) {\n  int num_args;\n  PClip* child_array;\n\n  if (args[0].IsArray()) {\n    num_args = args[0].ArraySize();\n    if (num_args == 1)\n      return args[0][0];\n\n    child_array = new PClip[num_args];\n    for (int i = 0; i < num_args; ++i)\n      child_array[i] = args[0][i].AsClip();\n\n    return new MergeChannels(args[0][0].AsClip(), num_args, child_array, env);\n  }\n  // MonoToStereo Case\n  num_args = 2;\n  child_array = new PClip[num_args];\n  child_array[0] = GetChannel::Create_left(args[0].AsClip());\n  child_array[1] = GetChannel::Create_right(args[1].AsClip());\n\n  return new MergeChannels(child_array[0], num_args, child_array, env);\n}\n\n\n/***************************************************\n *******   Get left or right                 *******\n *******    channel from a stereo source     *******\n ***************************************************/\n\n\n\nGetChannel::GetChannel(PClip _clip, int* _channel, int _numchannels) :\n  GenericVideoFilter(_clip), tempbuffer(NULL), channel(_channel), numchannels(_numchannels)\n{\n  cbps = vi.BytesPerChannelSample();\n  src_bps = vi.BytesPerAudioSample();\n  vi.nchannels = numchannels;\n  tempbuffer_size = 0;\n  dst_bps = vi.BytesPerAudioSample();\n\n  if (vi.AudioChannels() <= 8)\n    vi.SetChannelMask(true, GetDefaultChannelLayout(vi.AudioChannels()));\n  else\n    vi.SetChannelMask(false, 0); // over 8: no guess\n}\n\n\nvoid __stdcall GetChannel::GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) {\n  if (tempbuffer_size < count) {\n    if (tempbuffer_size) delete[] tempbuffer;\n    tempbuffer = new char[(unsigned)(count * src_bps)];\n    tempbuffer_size = (int)count;\n  }\n  child->GetAudio(tempbuffer, start, count, env);\n\n  switch (cbps) {\n  case 1: {    // 8 bit\n      char* samples = (char*)buf;\n      char* tbuff = tempbuffer;\n      for (int i = 0; i < count; i++) {\n        for (int k = 0; k < numchannels; k++) {\n          *(samples++) = tbuff[channel[k]];\n        }\n        tbuff += src_bps;\n      }\n    break;\n    }\n  case 2: {    // 16 bit\n      short* samples = (short*)buf;\n      short* tbuff = (short*)tempbuffer;\n      for (int i = 0; i < count; i++) {\n        for (int k = 0; k < numchannels; k++) {\n          *(samples++) = tbuff[channel[k]];\n        }\n        tbuff += src_bps>>1;\n      }\n    break;\n    }\n  case 4: {    // float/32 bit\n      int* samples = (int*)buf;\n      int* tbuff = (int*)tempbuffer;\n      for (int i = 0; i < count; i++) {\n        for (int k = 0; k < numchannels; k++) {\n          *(samples++) = tbuff[channel[k]];\n        }\n        tbuff += src_bps>>2;\n      }\n    break;\n    }\n  default: {  // 24 bit, etc\n      char* samples = (char*)buf;\n      char* tbuff = tempbuffer;\n      for (int i = 0; i < count; i++) {\n        for (int k = 0; k < numchannels; k++) {\n          int src_o = channel[k] * cbps;\n          for (int j = src_o; j < src_o+cbps; j++)\n            *(samples++) = tbuff[j];\n        }\n        tbuff += src_bps;\n      }\n    break;\n    }\n  }\n}\n\nint __stdcall GetChannel::SetCacheHints(int cachehints, int frame_range) {\n  AVS_UNUSED(frame_range);\n\n  switch (cachehints) {\n  case CACHE_GET_MTMODE:\n    return MT_SERIALIZED;\n  default:\n    break;\n  }\n  return 0;\n}\n\nPClip GetChannel::Create_left(PClip clip) {\n\n  if (clip->GetVideoInfo().AudioChannels() != 1) {\n    int* ch = new int[1];\n    ch[0] = 0;\n    clip = new GetChannel(clip, ch, 1);\n  }\n  // do not preserve 'left'ness\n  return new SetChannelMask(clip, true, AvsChannelMask::MASK_SPEAKER_FRONT_CENTER);\n}\n\nPClip GetChannel::Create_right(PClip clip) {\n  if (clip->GetVideoInfo().AudioChannels() != 1)\n  {\n    int* ch = new int[1];\n    ch[0] = 1;\n    clip = new GetChannel(clip, ch, 1);\n  }\n  // do not preserve 'right'ness\n  return new SetChannelMask(clip, true, AvsChannelMask::MASK_SPEAKER_FRONT_CENTER);\n}\n\nPClip GetChannel::Create_n(PClip clip, int* n, int numchannels) {\n  return new GetChannel(clip, n, numchannels);\n}\n\nAVSValue __cdecl GetChannel::Create_left(AVSValue args, void*, IScriptEnvironment*) {\n  return Create_left(args[0].AsClip());\n}\n\nAVSValue __cdecl GetChannel::Create_right(AVSValue args, void*, IScriptEnvironment*) {\n  return Create_right(args[0].AsClip());\n}\n\nAVSValue __cdecl GetChannel::Create_n(AVSValue args, void*, IScriptEnvironment* env) {\n  AVSValue args_c = args[1];\n  const int num_args = args_c.ArraySize();\n  int* child_array = new int[num_args];\n  for (int i = 0; i < num_args; ++i) {\n    child_array[i] = args_c[i].AsInt() - 1;  // Beware: Channel is 0-based in code and 1 based in scripts\n    if (child_array[i] >= args[0].AsClip()->GetVideoInfo().AudioChannels())\n      env->ThrowError(\"GetChannel: Attempted to request a channel that didn't exist!\");\n    if (child_array[i] < 0)\n      env->ThrowError(\"GetChannel: There are no channels below 1! (first channel is 1)\");\n  }\n  return Create_n(args[0].AsClip(), child_array, num_args);\n}\n\n/******************************\n *******   Kill Video  ********\n ******************************/\n\nKillVideo::KillVideo(PClip _clip)\n    : GenericVideoFilter(_clip) {\n  vi.width = 0;\n  vi.height= 0;\n  vi.fps_numerator  = 0;\n  vi.fps_denominator= 0;\n  vi.num_frames = 0;\n  vi.pixel_type = 0;\n  vi.image_type = 0;\n}\n\nAVSValue __cdecl KillVideo::Create(AVSValue args, void*, IScriptEnvironment*) {\n  return new KillVideo(args[0].AsClip());\n}\n\n\n/******************************\n *******   Kill Audio  ********\n ******************************/\n\nKillAudio::KillAudio(PClip _clip)\n    : NonCachedGenericVideoFilter(_clip) {\n  vi.audio_samples_per_second = 0;\n  vi.sample_type = 0;\n  vi.num_audio_samples = 0;\n  vi.nchannels = 0;\n  vi.SetChannelMask(false, 0);\n}\n\nAVSValue __cdecl KillAudio::Create(AVSValue args, void*, IScriptEnvironment*) {\n  return new KillAudio(args[0].AsClip());\n}\n\n/******************************\n ****** Set Channel Mask ******\n ******************************/\n\nSetChannelMask::SetChannelMask(PClip _clip, bool IsChannelMaskKnown, unsigned int dwChannelMask)\n  : NonCachedGenericVideoFilter(_clip) {\n  vi.SetChannelMask(IsChannelMaskKnown, dwChannelMask);\n}\n\nAVSValue __cdecl SetChannelMask::Create(AVSValue args, void*, IScriptEnvironment* env) {\n  if (args[1].IsString()) {\n    const char* channelName = args[1].AsString(\"\");\n    if (*channelName) {\n      unsigned int channelMask = av_get_channel_layout(channelName);\n      if (channelMask == 0)\n        env->ThrowError(\"SetChannelMask: could not find channel descriptor/combo '%s'\\n\", channelName);\n      return new SetChannelMask(args[0].AsClip(), true, channelMask);\n    }\n    // fallthrough, \"\" given -> unknown\n  }\n  else {\n    const bool known = args[1].AsBool(false);\n    if (known)\n      return new SetChannelMask(args[0].AsClip(), true, args[2].AsInt(0));\n  }\n  return new SetChannelMask(args[0].AsClip(), false, 0);\n}\n\n\n/******************************\n *******   Delay Audio   ******\n *****************************/\n\nDelayAudio::DelayAudio(double delay, PClip _child)\n    : GenericVideoFilter(_child), delay_samples(int64_t(delay * vi.audio_samples_per_second + 0.5)) {\n  vi.num_audio_samples += delay_samples;\n}\n\n\nvoid DelayAudio::GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) {\n  child->GetAudio(buf, start - delay_samples, count, env);\n}\n\n\nAVSValue __cdecl DelayAudio::Create(AVSValue args, void*, IScriptEnvironment*) {\n  return new DelayAudio(args[1].AsFloat(), args[0].AsClip());\n}\n\n\n/********************************\n *******   Amplify Audio   ******\n *******************************/\n\n\nAmplify::Amplify(PClip _child, float* _volumes, int* _i_v)\n    : GenericVideoFilter(ConvertAudio::Create(_child, SAMPLE_INT16 | SAMPLE_FLOAT | SAMPLE_INT32, SAMPLE_FLOAT)),\nvolumes(_volumes), i_v(_i_v) { }\n\n\nAmplify::~Amplify()\n{\n    if (volumes) { delete[] (float*)volumes; volumes=0; }\n    if (i_v)     { delete[] (int*)i_v;     i_v=0;     }\n}\n\n\nvoid __stdcall Amplify::GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) {\n  child->GetAudio(buf, start, count, env);\n  int channels = vi.AudioChannels();\n  int countXchannels = (int)count*channels;\n\n  if (vi.SampleType() == SAMPLE_INT16) {\n#if defined(X86_32) && defined(MSVC)\n    const short* endsample = (short*)buf + countXchannels;\n    const int* iv = i_v;\n\n    __asm {\n          mov\t ecx, [iv]\n          mov\t edi, [buf]\n          align  16\niloop0:\n          xor\t esi, esi\t\t\t\t\t; j\njloop0:\n          mov\t eax, DWORD PTR [ecx+esi*4]\t; i_v[j]\n          movsx\t edx, WORD PTR [edi]\t\t; *samples\n          inc\t esi\t\t\t\t\t\t; j++\n          imul\t edx\n          add\t edi, 2\t\t\t\t\t\t; samples++\n          add\t eax, 65536\n          adc\t edx, 0\n\n          cmp\t edx, -1\t\t\t\t\t; if (nh < -1) return MIN_SHORT;\n          jge\t notnegsat0\n          mov\t eax, -32768\n          jmp\t saturate0\nnotnegsat0:\n          test\t edx, edx\t\t\t\t\t; if (nh >  0) return MAX_SHORT;\n          jle\t notpossat0\n          mov\t eax, 32767\n          jmp\t saturate0\nnotpossat0:\n          shrd\t eax, edx, 17\t\t\t\t; n>>17\nsaturate0:\n          mov\t WORD PTR [edi-2], ax\t\t; *samples\n          cmp\t esi, [channels]\t\t\t; j < channels\n          jl\t jloop0\n\n          cmp\t edi, [endsample]\n          jl\t iloop0\n    }\n#else\n  short* samples = (short*)buf;\n  for (int i = 0; i < countXchannels; i+=channels) {\n    for (int j = 0; j < channels; j++) {\n      samples[i + j] = (short)clamp(\n        signed_saturated_add64(Int32x32To64(samples[i + j], i_v[j]), 65536) >> 17,\n        (int64_t)INT16_MIN,\n        (int64_t)INT16_MAX);\n    }\n  }\n#endif // X86_32\n\n    return ;\n  }\n\n  if (vi.SampleType() == SAMPLE_INT32) {\n#if defined(X86_32) && defined(MSVC)\n    const int* endsample = (int*)buf + countXchannels;\n    const int* iv = i_v;\n\n    __asm {\n          mov\t ecx, [iv]\n          mov\t edi, [buf]\n          align  16\niloop1:\n          xor\t esi, esi\t\t\t\t\t; j\njloop1:\n          mov\t eax, DWORD PTR [ecx+esi*4]\t; i_v[j]\n          mov  \t edx, DWORD PTR [edi]\t\t; *samples\n          inc\t esi\t\t\t\t\t\t; j++\n          imul\t edx\n          add\t edi, 4\t\t\t\t\t\t; samples++\n          add\t eax, 65536\n          adc\t edx, 0\n\n          cmp\t edx,0xffff0000\t\t\t\t; if (nh < -65536) return MIN_INT;\n          jge\t notnegsat1\n          mov\t eax, 0x80000000\n          jmp\t saturate1\nnotnegsat1:\n          cmp \t edx,0x0000ffff\t\t\t\t; if (nh >  65535) return MAX_INT;\n          jle\t notpossat1\n          mov\t eax, 0x7fffffff\n          jmp\t saturate1\nnotpossat1:\n          shrd\t eax, edx, 17\t\t\t\t; n>>17\nsaturate1:\n          mov\t DWORD PTR [edi-4], eax\t\t; *samples\n          cmp\t esi, [channels]\t\t\t; j < channels\n          jl\t jloop1\n\n          cmp\t edi, [endsample]\n          jl\t iloop1\n    }\n#else\n  int* samples = (int*)buf;\n  for (int i = 0; i < countXchannels; i+=channels) {\n    for (int j = 0;j < channels;j++) {\n      samples[i + j] = (int)clamp(\n        signed_saturated_add64(Int32x32To64(samples[i + j], i_v[j]), 65536) >> 17,\n        (int64_t)INT32_MIN,\n        (int64_t)INT32_MAX);\n    }\n  }\n#endif // X86_32\n\n    return ;\n  }\n  if (vi.SampleType() == SAMPLE_FLOAT) {\n    SFLOAT* samples = (SFLOAT*)buf;\n    for (int i = 0; i < countXchannels; i+=channels) {\n      for (int j = 0;j < channels;j++) {\t\t\t\t// Does not saturate, as other filters do.\n        samples[i + j] = samples[i + j] * volumes[j];\t// We should saturate only on conversion.\n      }\n    }\n    return ;\n  }\n}\n\n\nAVSValue __cdecl Amplify::Create(AVSValue args, void*, IScriptEnvironment*) {\n  if (!args[0].AsClip()->GetVideoInfo().AudioChannels())\n    return args[0];\n  AVSValue args_c = args[1];\n  const int num_args = args_c.ArraySize();\n  const int ch = args[0].AsClip()->GetVideoInfo().AudioChannels();\n  float* child_array = new float[ch];\n  int* i_child_array = new int[ch];\n  for (int i = 0; i < ch; ++i) {\n    child_array[i] = args_c[min(i, num_args - 1)].AsFloatf();\n    i_child_array[i] = int(child_array[i] * 131072.0f + 0.5f);\n\n  }\n  return new Amplify(args[0].AsClip(), child_array, i_child_array);\n}\n\n\n\nAVSValue __cdecl Amplify::Create_dB(AVSValue args, void*, IScriptEnvironment*) {\n  if (!args[0].AsClip()->GetVideoInfo().AudioChannels())\n    return args[0];\n  AVSValue args_c = args[1];\n  const int num_args = args_c.ArraySize();\n  const int ch = args[0].AsClip()->GetVideoInfo().AudioChannels();\n  float* child_array = new float[ch];\n  int* i_child_array = new int[ch];\n  for (int i = 0; i < ch; ++i) {\n    child_array[i] = dBtoScaleFactorf(args_c[min(i, num_args - 1)].AsFloatf());\n    i_child_array[i] = int(child_array[i] * 131072.0f + 0.5f);\n\n  }\n  return new Amplify(args[0].AsClip(), child_array, i_child_array);\n}\n\n\n/*****************************\n ***** Normalize audio  ******\n ***** Supports int16,float******\n ******************************/\n\nNormalize::Normalize(PClip _child, float _max_factor, bool _showvalues) :\n  GenericVideoFilter(ConvertAudio::Create(_child, SAMPLE_INT16 | SAMPLE_FLOAT, SAMPLE_FLOAT)),\n  max_factor(_max_factor),\n  max_volume(-1.0f),\n  frameno(0),\n  showvalues(_showvalues)\n{\n}\n\n\n\nvoid __stdcall Normalize::GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) {\n  if (max_volume < 0.0f) {\n    // Read samples into buffer and test them\n    if (vi.SampleType() == SAMPLE_INT16) {\n      int64_t bcount = count;\n      short* samples = (short*)buf;\n      bool bigbuff=false;\n\n    if (vi.BytesFromAudioSamples(count) < BIGBUFFSIZE) {\n      samples = new(std::nothrow) short[BIGBUFFSIZE/sizeof(short)];\n      if (samples) {\n        bigbuff=true;\n        bcount = vi.AudioSamplesFromBytes(BIGBUFFSIZE);\n      }\n      else {\n        samples = (short*)buf; // malloc failed just reuse clients buffer\n      }\n    }\n\n      const int64_t passes = vi.num_audio_samples / bcount;\n    int64_t negpeaksampleno=-1, pospeaksampleno=-1;\n      int i_pos_volume = 0;\n      int i_neg_volume = 0;\n      const int chanXbcount = (int)bcount * vi.AudioChannels();\n\n      for (int64_t i = 0; i < passes; i++) {\n        child->GetAudio(samples, bcount*i, bcount, env);\n        for (int j = 0; j < chanXbcount; j++) {\n      const int sample=samples[j];\n          if (sample < i_neg_volume) {\t// Cope with MIN_SHORT\n        i_neg_volume = sample;\n        negpeaksampleno = chanXbcount*i+j;\n      if (sample <= -32767) {\n        i = passes;\n        break;\n      }\n      }\n      else if (sample > i_pos_volume) {\n      i_pos_volume = sample;\n      pospeaksampleno = chanXbcount*i+j;\n      if (sample == 32767) {\n        i = passes;\n        break;\n      }\n      }\n        }\n      }\n    // Remaining samples\n    if ((i_pos_volume != 32767) && (i_neg_volume > -32767)) {\n    const int64_t rem_samples = vi.num_audio_samples % bcount;\n    const int chanXremcount = (int)rem_samples * vi.AudioChannels();\n\n    child->GetAudio(samples, bcount*passes, rem_samples, env);\n    for (int j = 0; j < chanXremcount; j++) {\n      const int sample=samples[j];\n      if (sample < i_neg_volume) {\t// Cope with MIN_SHORT\n      i_neg_volume = sample;\n      negpeaksampleno = chanXbcount*passes+j;\n      }\n      else if (sample > i_pos_volume) {\n      i_pos_volume = sample;\n      pospeaksampleno = chanXbcount*passes+j;\n      }\n    }\n    }\n    if (bigbuff) delete[] samples;\n\n    i_pos_volume = -i_pos_volume; // Remember -ve has 1 more range than +ve, i.e. -32768\n    if (i_neg_volume < i_pos_volume) {\n      i_pos_volume = i_neg_volume;\n      frameno = vi.FramesFromAudioSamples(negpeaksampleno / vi.AudioChannels());\n    }\n    else {\n      frameno = vi.FramesFromAudioSamples(pospeaksampleno / vi.AudioChannels());\n    }\n      max_volume = float(i_pos_volume * (-1.0/32768.0));\n      max_factor = max_factor / max_volume;\n\n    } else if (vi.SampleType() == SAMPLE_FLOAT) {  // Float\n      int64_t bcount = count;\n      SFLOAT* samples = (SFLOAT*)buf;\n      bool bigbuff=false;\n\n    if (vi.BytesFromAudioSamples(count) < BIGBUFFSIZE) {\n      samples = new(std::nothrow) SFLOAT[BIGBUFFSIZE/sizeof(SFLOAT)];\n      if (samples) {\n        bigbuff=true;\n        bcount = vi.AudioSamplesFromBytes(BIGBUFFSIZE);\n      }\n      else {\n        samples = (SFLOAT*)buf; // malloc failed just reuse clients buffer\n      }\n    }\n\n      const int chanXbcount = (int)bcount * vi.AudioChannels();\n      const int64_t passes = vi.num_audio_samples / bcount;\n    int64_t peaksampleno=-1;\n\n      for (int64_t i = 0;i < passes;i++) {\n        child->GetAudio(samples, bcount*i, bcount, env);\n        for (int j = 0;j < chanXbcount;j++) {\n      const SFLOAT sample = fabsf(samples[j]);\n          if (sample > max_volume) {\n        max_volume = sample;\n      peaksampleno = chanXbcount*i+j;\n      }\n        }\n      }\n      // Remaining samples\n      const int64_t rem_samples = vi.num_audio_samples % bcount;\n      const int chanXremcount = (int)rem_samples * vi.AudioChannels();\n\n      child->GetAudio(samples, bcount*passes, rem_samples, env);\n      for (int j = 0;j < chanXremcount;j++) {\n    const SFLOAT sample = fabsf(samples[j]);\n        if (sample > max_volume) {\n      max_volume = sample;\n      peaksampleno = chanXbcount*passes+j;\n    }\n      }\n    if (bigbuff) delete[] samples;\n\n    frameno = vi.FramesFromAudioSamples(peaksampleno / vi.AudioChannels());\n      max_factor = max_factor / max_volume;\n    }\n  }\n\n  const int chanXcount = (int)count * vi.AudioChannels();\n\n  if (vi.SampleType() == SAMPLE_INT16) {\n    const int factor = (int)(max_factor * 131072.0f + 0.5f);\n    child->GetAudio(buf, start, count, env);\n\n#if defined(X86_32) && defined(MSVC)\n    const short* endsample = (short*)buf + chanXcount;\n\n    __asm {\n          mov\t ecx, [factor]\n          mov\t edi, [buf]\n          align  16\niloop2:\n          movsx\t eax, WORD PTR [edi]\t\t; *samples\n          imul\t ecx\n          add\t edi, 2\t\t\t\t\t\t; samples++\n          add\t eax, 65536\n          adc\t edx, 0\n\n          cmp\t edx, -1\t\t\t\t\t; if (nh < -1) return MIN_SHORT;\n          jge\t notnegsat2\n          mov\t eax, -32768\n          jmp\t saturate2\nnotnegsat2:\n          test\t edx, edx\t\t\t\t\t; if (nh >  0) return MAX_SHORT;\n          jle\t notpossat2\n          mov\t eax, 32767\n          jmp\t saturate2\nnotpossat2:\n          shrd\t eax, edx, 17\t\t\t\t; n>>17\nsaturate2:\n          mov\t WORD PTR [edi-2], ax\t\t; *samples\n\n          cmp\t edi, [endsample]\n          jl\t iloop2\n    }\n#else\n    short* samples = (short*)buf;\n    for (int i = 0; i < chanXcount; ++i) {\n      // TODO: This is very slow. Right now, it should just work, we'll optimize later.\n      samples[i] = (short)clamp(\n        signed_saturated_add64(Int32x32To64(samples[i], factor), 65536) >> 17,\n        (int64_t)INT16_MIN,\n        (int64_t)INT16_MAX);\n    }\n#endif // X86_32\n  } else if (vi.SampleType() == SAMPLE_FLOAT) {\n    SFLOAT* samples = (SFLOAT*)buf;\n    child->GetAudio(buf, start, count, env);\n    for (int i = 0; i < chanXcount; ++i) {\n      samples[i] = samples[i] * max_factor;\n    }\n  }\n}\n\nint __stdcall Normalize::SetCacheHints(int cachehints, int frame_range) {\n  AVS_UNUSED(frame_range);\n\n  switch (cachehints) {\n  case CACHE_GET_MTMODE:\n    return MT_SERIALIZED;\n  default:\n    break;\n  }\n  return 0;\n}\n\nPVideoFrame __stdcall Normalize::GetFrame(int n, IScriptEnvironment* env) {\n  if (showvalues) {\n    PVideoFrame src = child->GetFrame(n, env);\n    env->MakeWritable(&src);\n    char text[400];\n\n    if (max_volume < 0) {\n      sprintf(text, \"Normalize: Result not yet calculated!\");\n    } else {\n      double maxdb = 8.685889638 * log(max_factor);\n      // maxdb = (20 * log(factor)) / log(10);\n      sprintf(text, \"Amplify Factor: %8.4f\\nAmplify DB: %8.4f\\nAt Frame: %d\", max_factor, maxdb, frameno);\n    }\n    env->ApplyMessage(&src, vi, text, vi.width / 4, 0xf0f080, 0, 0);\n    return src;\n  }\n  return child->GetFrame(n, env);\n\n}\n\n\nAVSValue __cdecl Normalize::Create(AVSValue args, void*, IScriptEnvironment*) {\n\n  return new Normalize(args[0].AsClip(), args[1].AsFloatf(1.0f), args[2].AsBool(false));}\n\n\n/*****************************\n ***** Mix audio  tracks ******\n ******************************/\n\nMixAudio::MixAudio(PClip _child, PClip _clip, double _track1_factor, double _track2_factor, IScriptEnvironment* env) :\n  GenericVideoFilter(ConvertAudio::Create(_child, SAMPLE_INT16 | SAMPLE_FLOAT, SAMPLE_FLOAT)),\n  tempbuffer(NULL),\n  track1_factor(int(_track1_factor*131072.0 + 0.5)),\n  track2_factor(int(_track2_factor*131072.0 + 0.5)),\n  t1factor(float(_track1_factor)),\n  t2factor(float(_track2_factor))\n{\n  clip = ConvertAudio::Create(_clip, vi.SampleType(), vi.SampleType());  // Clip 2 should now be same type as clip 1.\n  const VideoInfo vi2 = clip->GetVideoInfo();\n\n  if (vi.audio_samples_per_second != vi2.audio_samples_per_second)\n    env->ThrowError(\"MixAudio: Clips must have same sample rate! Use ResampleAudio()!\");  // Could be removed for fun :)\n\n  if (vi.AudioChannels() != vi2.AudioChannels())\n    env->ThrowError(\"MixAudio: Clips must have same number of channels! Use ConvertToMono() or MergeChannels()!\");\n\n  tempbuffer_size = 0;\n}\n\n\nvoid __stdcall MixAudio::GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) {\n  if (tempbuffer_size < count)\n  {\n    if (tempbuffer_size)\n      delete[] tempbuffer;\n\n    tempbuffer = new signed char[(size_t)(count * vi.BytesPerAudioSample())];\n    tempbuffer_size = (int)count;\n  }\n\n  child->GetAudio(buf, start, count, env);\n  clip->GetAudio(tempbuffer, start, count, env);\n  unsigned channels = vi.AudioChannels();\n\n  if (vi.SampleType()&SAMPLE_INT16) {\n#if defined(X86_32) && defined(MSVC)\n    const short* tbuffer = (short*)tempbuffer;\n    const short* endsample = (short*)buf + unsigned(count)*channels;\n    const int t1_factor = track1_factor;\n    const int t2_factor = track2_factor;\n\n    __asm {\n      push   ebx\n          mov\t edi, [buf]\n          mov\t esi, [tbuffer]\n          align  16\niloop3:\n          movsx\t eax, WORD PTR [edi]\t\t; *samples\n          add\t edi, 2\t\t\t\t\t\t; samples++\n          imul\t [t1_factor]\n          mov\t ebx, 65536\n          xor\t ecx, ecx\n      add    ebx, eax\n          movsx\t eax, WORD PTR [esi]\t\t; *clip_samples\n      adc    ecx, edx\n          imul\t [t2_factor]\n          add\t esi, 2\t\t\t\t\t\t; clip_samples++\n          add\t eax, ebx\n          adc\t edx, ecx\n\n          cmp\t edx, -1\t\t\t\t\t; if (nh < -1) return MIN_SHORT;\n          jge\t notnegsat3\n          mov\t eax, -32768\n          jmp\t saturate3\nnotnegsat3:\n          test\t edx, edx\t\t\t\t\t; if (nh >  0) return MAX_SHORT;\n          jle\t notpossat3\n          mov\t eax, 32767\n          jmp\t saturate3\nnotpossat3:\n          shrd\t eax, edx, 17\t\t\t\t; n>>17\nsaturate3:\n          mov\t WORD PTR [edi-2], ax\t\t; *samples\n\n          cmp\t edi, [endsample]\n          jl\t iloop3\n      pop    ebx\n    }\n#else\n    short* samples = (short*)buf;\n    short* clip_samples = (short*)tempbuffer;\n    for (unsigned i = 0; i < unsigned(count)*channels; ++i) {\n      samples[i] = (short)clamp(\n        signed_saturated_add64(signed_saturated_add64(Int32x32To64(samples[i], track1_factor), Int32x32To64(clip_samples[i], track2_factor)), 65536) >> 17,\n        (int64_t)INT16_MIN,\n        (int64_t)INT16_MAX);\n    }\n#endif\n  } else if (vi.SampleType()&SAMPLE_FLOAT) {\n    SFLOAT* samples = (SFLOAT*)buf;\n    const SFLOAT* clip_samples = (SFLOAT*)tempbuffer;\n    for (unsigned i = 0; i < unsigned(count)*channels; ++i) {\n        samples[i] = (samples[i] * t1factor) + (clip_samples[i] * t2factor);\n    }\n  }\n}\n\nint __stdcall MixAudio::SetCacheHints(int cachehints, int frame_range) {\n  AVS_UNUSED(frame_range);\n\n  switch (cachehints) {\n  case CACHE_GET_MTMODE:\n    return MT_SERIALIZED;\n  default:\n    break;\n  }\n  return 0;\n}\n\nAVSValue __cdecl MixAudio::Create(AVSValue args, void*, IScriptEnvironment* env) {\n  double track1_factor = args[2].AsDblDef(0.5);\n  double track2_factor = args[3].AsDblDef(1.0 - track1_factor);\n  return new MixAudio(args[0].AsClip(), args[1].AsClip(), track1_factor, track2_factor, env);\n}\n\n\n\n/********************************\n *******   Resample Audio   ******\n *******************************/\n\nstatic int Amasktab[Amask+1];\nstatic SFLOAT fAmasktab[Amask+1];\n\nResampleAudio::ResampleAudio(PClip _child, int _target_rate_n, int _target_rate_d, IScriptEnvironment*)\n    : GenericVideoFilter(ConvertAudio::Create(_child, SAMPLE_INT16 | SAMPLE_FLOAT, SAMPLE_FLOAT)),\n      factor(_target_rate_n / (double(_target_rate_d) * vi.audio_samples_per_second))\n{\n  srcbuffer  = 0;\n  fsrcbuffer = 0;\n\n  if (vi.audio_samples_per_second == 0) {\n    skip_conversion = true;\n    return ;\n  }\n\n  // To avoid overflow, implement as (A*B+C/2)/C = (A/C)*B + ((A%C)*B+C>>1)/C\n  const int64_t den = Int32x32To64(_target_rate_d, vi.audio_samples_per_second);\n  const int64_t num_audio_samples = (vi.num_audio_samples/den) * _target_rate_n + ((vi.num_audio_samples%den)*_target_rate_n + (den>>1))/den;\n\n  if (vi.num_audio_samples == num_audio_samples) {\n    skip_conversion = true;\n    return ;\n  }\n  skip_conversion = false;\n  vi.num_audio_samples = num_audio_samples;\n  vi.audio_samples_per_second = (_target_rate_n + (_target_rate_d>>1))/_target_rate_d;\n\n  if (vi.IsSampleType(SAMPLE_INT16)) {\n  double dLpScl = 0.0;\n\n  // Load interpolate ratio table\n  for (int i=0; i<=Amask; i++)\n      Amasktab[i] = (i<<16) | (Amask+1-i);   /* a is between 0 and 1 */\n\n  // generate filter coefficients\n  makeFilter(Imp, dLpScl, Nwing, 0.90, 9);\n  Imp[Nwing] = 0; // for \"interpolation\" beyond last coefficient\n\n  /* Account for increased filter gain when using factors less than 1 */\n  if (factor < 1)\n    dLpScl = dLpScl * factor;\n\n  // Attenuate resampler scale factor by 0.95 to reduce probability of clipping\n  LpScl = int(dLpScl * 0.95 + 0.5);\n\n  // Scale guard bits so intermediate result fits in short\n  mNhg   = Nhg;\n  while (dLpScl < 16384.0) {\n    dLpScl *= 2.0;\n    mNhg += 1;\n  }\n  mLpScl = int(dLpScl + 0.5);   // Must be 16384 <= mLpScl <= 32767\n  }\n  else { // SAMPLE_FLOAT\n\n  // Load interpolate ratio table\n  for (int i=0; i<=Amask; i++)\n    fAmasktab[i] = float(i) / (Amask+1);   /* a is between 0 and 1 */\n\n  /* Account for increased filter gain when using factors less than 1 */\n  if (factor < 1)\n    makeFilter(fImp, factor, Nwing, 0.90, 9);  // generate filter coefficients\n  else\n    makeFilter(fImp, 1.0,    Nwing, 0.90, 9);  // generate filter coefficients\n\n  fImp[Nwing] = 0.0; // for \"interpolation\" beyond last coefficient\n\n  }\n\n  /* Calc reach of LP filter wing & give some creeping room */\n  Xoff = int(((Nmult + 1) / 2.0) * max(1.0, 1.0 / factor)) + 10;\n\n  /* The previous algorithm was causing quite a noticable click or pop at the\n   * end of each mouthful due to accumulated creep between pos+N*dtb at the\n   * end of one call to (start/factor*(1<<Np)+0.5) in the next.\n   */\n  double dt = (1 << Np) / factor;              /* Output sampling period          */\n  dtb = int(dt);                               /* Yes! Truncated not rounded      */\n  dt -= dtb;                                   /* 0 <= SamplingPeriodDeficit < 1  */\n  dtbe = unsigned((1 << 31) * dt + 0.5);       /* Prevent creep, bump dtb every (2^31)/dtbe samples */\n\n  double dh = min(double(Npc), factor * Npc);  /* Filter sampling period */\n  dhb = int(dh * (1 << Na) + 0.5);\n}\n\n\nvoid __stdcall ResampleAudio::GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) {\n  if (skip_conversion) {\n    child->GetAudio(buf, start, count, env);\n    return ;\n  }\n  auto src_start = int64_t(((long double)start           / factor) * (1 << Np) + 0.5);\n  auto src_end   = int64_t(((long double)(start + count) / factor) * (1 << Np) + 0.5);\n  const int64_t source_samples = ((src_end - src_start) >> Np) + 2 * Xoff + 1;\n  const int source_bytes = (int)vi.BytesFromAudioSamples(source_samples);\n\n  int64_t pos = (int(src_start & Pmask)) + (Xoff << Np);\n  short ch = (short)vi.AudioChannels();\n  unsigned dtberror = 0;\n\n  if (vi.IsSampleType(SAMPLE_INT16)) {\n\n  if (!srcbuffer || source_bytes > srcbuffer_size) {\n    delete[] srcbuffer;\n    srcbuffer = new short[source_bytes >> 1];\n    srcbuffer_size = source_bytes;\n    last_samples= 0;\n    last_start = 0;\n  }\n\n  const int offset = int((src_start >> Np) - Xoff - last_start);  // Difference from last time\n  last_start = (src_start >> Np) - Xoff;                          // Start for next time\n\n  int overlap = int(last_samples - offset);                       // How many samples already fetched\n  if ((offset < 0) || (overlap <= 0))                             // Is there any overlap?\n    overlap = 0;\n  else if (offset*ch >= 2)  // Assume 32bit separation is okay    // Yes, copy to start of buffer\n    memcpy(srcbuffer, srcbuffer+offset*ch, overlap*ch<<1);  // fast\n  else if (offset > 0)\n    memmove(srcbuffer, srcbuffer+offset*ch, overlap*ch<<1); // slow\n\n  last_samples= max<int64_t>(overlap, source_samples);                     // Samples for next time\n\n    if (source_samples-overlap > 0)                                 // Get the rest of the source samples\n    child->GetAudio(&srcbuffer[overlap*ch], last_start+overlap, source_samples-overlap, env);\n\n  short* dst = (short*)buf;\n\n  short* dst_end = &dst[count * ch];\n\n#ifdef INTEL_INTRINSICS\n#if defined(X86_32) && defined(MSVC_PURE)\n  if (env->GetCPUFlags() & CPUF_MMX)\n  {\n    static const int r_Na     = 1 << (Na-1);\n    static const int r_Nhxn   = 1 << (Nhxn-1);\n    static const int r_NLpScl = 1 << (NLpScl-1);\n    const int inc = ch * sizeof(short);\n    int posNp = int(pos >> Np);\n\n// MM7 - Accumulate the left/right wing inner product of the current sample pair\n// MM6 - Rounding constant 1 << (Na-1),       (64)\n// MM5 - Rounding constant 1 << (Nhxn-1),   (8192)\n// MM4 - Scaled scaling factor, mLpScl\n// MM3 - Rounding constant 1 << (NLpScl-1), (4096)\n// MM2 - Scaled number of guard bits, mNhg\n\n    __asm {\n    movd       mm6, [r_Na]          ; 1 << (Na - 1)\n    movd       mm5, [r_Nhxn]        ; 1 << (Nhxn - 1)\n    punpckldq  mm6, mm6             ; 00000040 00000040\n    mov        eax, this\n    punpckldq  mm5, mm5             ; 00002000 00002000\n    movd       mm4, [eax].mLpScl    ; 00000000 LpScl\n    movd       mm3, [r_NLpScl]      ; 1 << (NLpScl-1)\n    punpckldq  mm4, mm4             ; LpScl | LpScl\n    movd       mm2, [eax].mNhg      ; Number of guard bits\n    punpckldq  mm3, mm3             ; 00001000 00001000\n    }\n\n    while (dst < dst_end) {\n    for (int q = 0; q < ch; q+=2) { // do 2 channels at once\n      bool single = (q+1 >= ch);\n      short* Xp = &srcbuffer[posNp * ch];\n\n      __asm pxor mm7, mm7;  // 2 channel samples are accumulated in MM7\n\n      FilterUD_mmx(Xp + ch + q, (unsigned)(-pos) & Pmask,  inc, dhb, Imp, Nwing);  /* Perform right-wing inner product */\n      FilterUD_mmx(Xp      + q, (unsigned)( pos) & Pmask, -inc, dhb, Imp, Nwing);  /* Perform left-wing inner product */\n\n      __asm {\n        psrad      mm7, mm2              ; scaled Nhg guard bits\n         mov       eax, [dst]\n      pmaddwd    mm7, mm4              ; Normalize for unity filter gain\n       test      byte ptr[single], 1   ; doing 1 sample or 2 samples?\n      paddd      mm7, mm3              ; round\n       jnz       dosingle\n      psrad      mm7, NLpScl           ; strip guard bits\n       add       eax, 4                ; dst+=2\n      packssdw   mm7, mm7              ; pack with signed saturation ready for output\n       mov       [dst], eax\n      movd       [eax-4], mm7          ; deposit 2 output samples\n       jmp       done1\n      align      16\ndosingle:\n      psrad      mm7, NLpScl           ; strip guard bits\n       add       eax, 2                ; dst+=\n      packssdw   mm7, mm7              ; pack with signed saturation ready for output\n       mov       [dst], eax\n      movd       edx, mm7\n      mov        [eax-2], dx           ; deposit 1 output sample\n      align      16\ndone1:\n      }\n    } // for (int q = 0\n    __asm { // Don't be a creep ;-)\n      mov       edx, this\n       mov      eax, dtberror            ; time increment error accumulator\n      mov       ecx, [edx].dtb           ; time increment\n       add      eax, [edx].dtbe          ; add error per cycle\n      mov       edx, dword ptr pos+4\n       cmp      eax, 0x80000000          ; accumulated 1 full error yet?\n       jb       nofix\n      inc       ecx                      ; += 1\n       sub      eax, 0x80000000          ; -= 1 full error\nnofix:\n      add       ecx, dword ptr pos       ; Move to next sample\n       mov      dtberror, eax\n      adc       edx, 0\n       mov      dword ptr pos, ecx\n      shrd      ecx, edx, Np             ; posNp = pos >> Np\n       mov      dword ptr pos+4, edx\n      mov       posNp, ecx\n    }\n    } // while (dst\n    __asm emms;\n  }\n  else\n#endif // X86_32\n#endif\n  {\n    while (dst < dst_end) {\n    for (int q = 0; q < ch; q++) {\n      short* Xp = &srcbuffer[(pos >> Np) * ch];\n#if 1\n      int64_t v64 = FilterUD(Xp + q, (short)(pos & Pmask), - ch);  /* Perform left-wing inner product  */\n      v64 += FilterUD(Xp + ch + q, (short)(( -pos) & Pmask), ch);  /* Perform right-wing inner product */\n          v64 += 1 << (Nh - 1);                                        /* Round only once!                 */\n      int v32 = int(v64 >> Nh);                                    /* Make guard bits once!            */\n      v32 *= LpScl;                                                /* Normalize for unity filter gain  */\n      *dst++ = IntToShort(v32, NLpScl);                            /* strip guard bits, deposit output */\n#else\n      int v = FilterUD(Xp + q, (short)(pos & Pmask), - ch);  /* Perform left-wing inner product */\n      v += FilterUD(Xp + ch + q, (short)(( -pos) & Pmask), ch);  /* Perform right-wing inner product */\n      v >>= Nhg;      /* Make guard bits */\n      v *= LpScl;     /* Normalize for unity filter gain */\n      *dst++ = IntToShort(v, NLpScl);   /* strip guard bits, deposit output */\n#endif\n    }\n    if ((dtberror += dtbe) >= (1u << 31)) { // Don't be a creep ;-)\n      dtberror -= (1u << 31);\n      pos += dtb + 1;   /* Move to next sample by time increment + error adjustment */\n    }\n    else {\n      pos += dtb;       /* Move to next sample by time increment */\n    }\n    }\n  }\n  }\n  else { // SAMPLE_FLOAT\n\n  if (!fsrcbuffer || source_bytes > srcbuffer_size) {\n    delete[] fsrcbuffer;\n    fsrcbuffer = new SFLOAT[source_bytes >> 2];\n    srcbuffer_size = source_bytes;\n    last_samples= 0;\n    last_start = 0;\n  }\n\n  const int offset = int((src_start >> Np) - Xoff - last_start);\n  last_start = (src_start >> Np) - Xoff;\n\n  int overlap = int(last_samples - offset);\n  if ((offset < 0) || (overlap <= 0))\n    overlap = 0;\n  else if (offset > 0)\n    memcpy(fsrcbuffer, fsrcbuffer+offset*ch, overlap*ch<<2);\n  last_samples= max<int64_t>(overlap, source_samples);\n\n    if (source_samples-overlap > 0)\n    child->GetAudio(&fsrcbuffer[overlap*ch], last_start+overlap, source_samples-overlap, env);\n\n  SFLOAT* dst = (SFLOAT*)buf;\n\n  SFLOAT* dst_end = &dst[count * ch];\n\n  while (dst < dst_end) {\n    for (int q = 0; q < ch; q++) {\n    SFLOAT* Xp = &fsrcbuffer[(pos >> Np) * ch];\n    SFLOAT v = FilterUD(Xp +      q, (short)(   pos  & Pmask), - ch);  /* Perform left-wing inner product */\n    v       += FilterUD(Xp + ch + q, (short)(( -pos) & Pmask),   ch);  /* Perform right-wing inner product */\n    *dst++ = v;     /* deposit output */\n    }\n    if ((dtberror += dtbe) >= (1 << 31)) { // Don't be a creep ;-)\n    dtberror -= (1u << 31);\n    pos += dtb + 1;   /* Move to next sample by time increment + error adjustment */\n    }\n    else {\n    pos += dtb;       /* Move to next sample by time increment */\n    }\n  }\n\n  }\n}\n\nint __stdcall ResampleAudio::SetCacheHints(int cachehints, int frame_range) {\n  AVS_UNUSED(frame_range);\n\n  switch (cachehints) {\n  case CACHE_GET_MTMODE:\n    return MT_SERIALIZED;\n  default:\n    break;\n  }\n  return 0;\n}\n\nAVSValue __cdecl ResampleAudio::Create(AVSValue args, void*, IScriptEnvironment* env) {\n  return new ResampleAudio(args[0].AsClip(), args[1].AsInt(), args[2].AsInt(1), env);\n}\n\n\n#ifdef INTEL_INTRINSICS\n#if defined(X86_32) && defined(MSVC_PURE)\n\n// FilterUD MMX SAMPLE_INT16 Version -- approx 3.25 times faster than original (2.4x than new)\n/*\n * MMx registers transfered across calls\n * MM7 - Accumulate the left/right wing inner product of the current sample pair\n * MM6 - Rounding constant 1 << (Na-1),     (64)\n * MM5 - Rounding constant 1 << (Nhxn-1), (8192)\n *\n * Uses MM0, MM1\n */\n#pragma warning( push )\n#pragma warning (disable: 4799)   //function '...' has no EMMS instruction\n\nvoid FilterUD_mmx(short *Xp, unsigned Ph, int _inc, int _dhb, short *p_Imp, unsigned End) {\n\n  unsigned Ho  = (Ph * (unsigned)_dhb) >> Np;\n\n  if (_inc > 0) {   // If doing right wing drop extra coeff, so when Ph is\n    End--;          // 0.5, we don't do one too many mult's\n    if (Ph == 0)    // If the phase is zero then we've already skipped the\n      Ho += _dhb;   // first sample, so we must also skip ahead in Imp[]\n  }\n__asm {\n  mov\t\t\tedi,[Xp]\n  mov\t\t\tesi,[Ho]\n  mov\t\t\tecx,[p_Imp]\n\n  mov\t\t\tedx,esi\t\t; Fold into end for improved pairing\n  mov\t\t\teax,Amask\n  shr\t\t\tedx,Na\t\t\t\t; Ho >> Na\n  and\t\t\teax,esi\t\t\t\t; Ho & Amask\n  cmp\t\t\tedx,[End]\n  movd\t\tmm1,Amasktab[eax*4]\t; 0000 0000 eax 128-eax\n  jae\t\t\tdonone\n\n  align\t\t16\nloop1:\n   movd\t\tmm0,[ecx+edx*2]\t\t; 0000 0000 Imp[Ho>>Na7+1] Imp[Ho>>Na7]\n  add\t\t\tesi,[_dhb]\t\t\t; Ho += dhb\n   pmaddwd\tmm0,mm1\t\t\t\t; 00000000 Imp[h+1]*a + Imp[h]*(128-a)\n  movd\t\tmm1,[edi]\t\t\t; 0000 0000 *(Xp+1) *Xp\n   paddd\t\tmm0,mm6\t\t\t\t; += round\n  add\t\t\tedi,[_inc]\t\t\t; Xp += Inc\n   pslld      mm0,16-Na\t\t\t; <<= 16-Na\n  mov\t\t\teax,Amask\n   psrld\t\tmm0,16\t\t\t\t; 0000 0000 0000 coeff\n  punpcklwd\tmm1,mm1\t\t\t\t; *(Xp+1) *(Xp+1) *Xp *Xp\n   mov \t\tedx,esi\n  punpckldq\tmm0,mm0\t\t\t\t; 0000 coeff 0000 coeff\n   and\t\teax,esi\t\t\t\t; Ho & Amask\n  pmaddwd\t\tmm0,mm1\t\t\t\t; *(Xp+1)*coeff | *Xp*coeff\n   shr\t\tedx,Na\t\t\t\t; Ho >> Na\n  paddd\t\tmm0,mm5\t\t\t\t; += round\n   movd\t\tmm1,Amasktab[eax*4]\t; 0000 0000 eax 128-eax\n  psrad\t\tmm0,Nhxn\t\t\t; >>=Nhxn\n   cmp\t\tedx,[End]\n  paddd\t\tmm7,mm0\t\t\t\t; v += t\n   jb\t\t\tloop1\ndonone:\n  }\n}\n#pragma warning( pop )\n#endif // X86_32\n#endif\n\n\n// FilterUD SAMPLE_INT16 Version\nint64_t ResampleAudio::FilterUD(short *Xp, short Ph, short Inc) {\n  int64_t v = 0;\n  unsigned Ho = (Ph * (unsigned)dhb) >> Np;\n  unsigned End = Nwing;\n\n  if (Inc > 0)          /* If doing right wing...              */\n  {                     /* ...drop extra coeff, so when Ph is  */\n    End--;              /*    0.5, we don't do too many mult's */\n    if (Ph == 0)        /* If the phase is zero...             */\n      Ho += dhb;        /* ...then we've already skipped the   */\n  }                     /*    first sample, so we must also    */\n                        /*    skip ahead in Imp[] and ImpD[]   */\n  while ((Ho >> Na) < End) {\n    int t = Imp[Ho >> Na];                              /* Get IR sample */\n#if 1\n  // It's 37% faster and more accurate to accumulate 64 bits\n  // than stuffing around testing, rounding and shifting\n    const int a = Ho & Amask;                           /* a is logically between 0 and 1 */\n    const int r = 1 << (Na-1);                          /* Round */\n    t += ((int(Imp[(Ho>>Na)+1]) - t) * a + r) >> Na;    /* t is now interp'd filter coeff */\n    t *= *Xp;                                           /* Mult coeff by input sample */\n#else\n    int a = Ho & Amask;   /* a is logically between 0 and 1 */\n    t += ((int(Imp[(Ho >> Na) + 1]) - t) * a) >> Na; /* t is now interp'd filter coeff */\n    t *= *Xp;     /* Mult coeff by input sample */\n    if (t & 1 << (Nhxn - 1))  /* Round, if needed */\n      t += 1 << (Nhxn - 1);\n    t >>= Nhxn;       /* Leave some guard bits, but come back some */\n#endif\n    v += t;           /* The filter output */\n    Ho += dhb;        /* IR step */\n    Xp += Inc;        /* Input signal step. NO CHECK ON BOUNDS */\n  }\n  return (v);\n}\n\n// FilterUD SAMPLE_FLOAT Version  -- Approx same speed as new int16 and SSRC on P4 (40% on P2)\nSFLOAT ResampleAudio::FilterUD(SFLOAT *Xp, short Ph, short Inc) {\n  SFLOAT v = 0;\n  unsigned Ho = (Ph * (unsigned)dhb) >> Np;\n  unsigned End = Nwing;\n  if (Inc > 0)        /* If doing right wing...              */\n  {                   /* ...drop extra coeff, so when Ph is  */\n    End--;            /*    0.5, we don't do too many mult's */\n    if (Ph == 0)      /* If the phase is zero...             */\n      Ho += dhb;      /* ...then we've already skipped the   */\n  }                   /*    first sample, so we must also    */\n                      /*    skip ahead in fImp[]             */\n  while ((Ho >> Na) < End) {\n    SFLOAT t = fImp[Ho >> Na];      /* Get IR sample */\n    t += (fImp[(Ho >> Na) + 1] - t) * fAmasktab[Ho & Amask]; /* t is now interpolated filter coeff */\n    t *= *Xp;         /* Mult coeff by input sample */\n    v += t;           /* The filter output */\n    Ho += dhb;        /* IR step */\n    Xp += Inc;        /* Input signal step. NO CHECK ON BOUNDS */\n  }\n  return (v);\n}\n\n\n\n\n/********************************\n *******   Helper methods *******\n ********************************/\n\ndouble Izero(double x) {\n  double sum, u, halfx, temp;\n  int n;\n\n  sum = u = n = 1;\n  halfx = x / 2.0;\n  do {\n    temp = halfx / (double)n;\n    n += 1;\n    temp *= temp;\n    u *= temp;\n    sum += u;\n  } while (u >= IzeroEPSILON*sum);\n  return (sum);\n}\n\n\nvoid LpFilter(double c[], int N, double frq, double Beta, int Num) {\n  int i;\n\n  /* Calculate ideal lowpass filter impulse response coefficients: */\n  c[0] = 2.0 * frq;\n  const double PIdivNum  = PI / Num;\n  for (i = 1; i < N; i++) {\n    const double temp = PIdivNum * i;\n    c[i] = sin(2.0 * temp * frq) / temp; /* Analog sinc function, cutoff = frq */\n  }\n\n  /*\n   * Calculate and Apply Kaiser window to ideal lowpass filter.\n   * Note: last window value is IBeta which is NOT zero.\n   * You're supposed to really truncate the window here, not ramp\n   * it to zero. This helps reduce the first sidelobe.\n   */\n  const double IBeta = 1.0 / Izero(Beta);\n  const double inm1 = 1.0 / (N - 1);\n  for (i = 1; i < N; i++) {\n    const double temp = i * inm1;\n    c[i] *= Izero(Beta * sqrt(1.0 - temp * temp)) * IBeta;\n  }\n}\n\n\n/* ERROR return codes:\n *    0 - no error\n *    1 - Nwing too large (Nwing is > MAXNWING)\n *    2 - Froll is not in interval [0:1)\n *    3 - Beta is < 1.0\n *\n */\n\n// makeFilter SAMPLE_INT16 Version\nint makeFilter( short Imp[], double &dLpScl, unsigned short Nwing, double Froll, double Beta) {\n  static const int MAXNWING = 8192;\n  static double ImpR[MAXNWING];\n\n  double DCgain, Scl, Maxh;\n  short Dh;\n  int i;\n\n  if (Nwing > MAXNWING)                      /* Check for valid parameters */\n    return (1);\n  if ((Froll <= 0) || (Froll > 1))\n    return (2);\n  if (Beta < 1)\n    return (3);\n\n  /*\n   * Design Kaiser-windowed sinc-function low-pass filter\n   */\n  LpFilter(ImpR, (int)Nwing, 0.5*Froll, Beta, Npc);\n\n  /* Compute the DC gain of the lowpass filter, and its maximum coefficient\n   * magnitude. Scale the coefficients so that the maximum coeffiecient just\n   * fits in Nh-bit fixed-point, and compute LpScl as the NLpScl-bit (signed)\n   * scale factor which when multiplied by the output of the lowpass filter\n   * gives unity gain. */\n  DCgain = 0;\n  Dh = Npc;                       /* Filter sampling period for factors>=1 */\n  for (i = Dh; i < Nwing; i += Dh)\n    DCgain += ImpR[i];\n  DCgain = 2 * DCgain + ImpR[0];    /* DC gain of real coefficients */\n\n  for (Maxh = i = 0; i < Nwing; i++)\n    Maxh = max(Maxh, fabs(ImpR[i]));\n\n  Scl = ((1 << (Nh - 1)) - 1) / Maxh;     /* Map largest coeff to 16-bit maximum */\n  dLpScl = fabs((1 << (NLpScl + Nh)) / (DCgain * Scl));\n\n  /* Scale filter coefficients for Nh bits and convert to integer */\n  if (ImpR[0] < 0)                /* Need pos 1st value for LpScl storage */\n    Scl = -Scl;\n  for (i = 0; i < Nwing; i++)         /* Scale & round them */\n    Imp[i] = short(ImpR[i] * Scl + 0.5);\n\n  return (0);\n}\n\n\n// makeFilter SAMPLE_FLOAT Version\nint makeFilter( SFLOAT fImp[], double dLpScl, unsigned short Nwing, double Froll, double Beta) {\n  static const int MAXNWING = 8192;\n  static double ImpR[MAXNWING];\n\n  double DCgain, Scl;\n  int i;\n\n  if (Nwing > MAXNWING)                      /* Check for valid parameters */\n    return (1);\n  if ((Froll <= 0) || (Froll > 1))\n    return (2);\n  if (Beta < 1)\n    return (3);\n\n  /*\n   * Design Kaiser-windowed sinc-function low-pass filter\n   */\n  LpFilter(ImpR, (int)Nwing, 0.5*Froll, Beta, Npc);\n\n  /* Compute the DC gain of the lowpass filter, and its maximum coefficient\n   * magnitude. Scale the coefficients so that the maximum coeffiecient just\n   * fits in Nh-bit fixed-point, and compute LpScl as the NLpScl-bit (signed)\n   * scale factor which when multiplied by the output of the lowpass filter\n   * gives unity gain. */\n  DCgain = 0;\n  /* Npc is filter sampling period for factors>=1 */\n  for (i = Npc; i < Nwing; i += Npc)\n    DCgain += ImpR[i];\n  DCgain = 2 * DCgain + ImpR[0];    /* DC gain of real coefficients */\n\n  Scl = dLpScl / DCgain;\n\n  /* Scale filter coefficients for unity gain and convert to float */\n  if (ImpR[0] < 0)                /* Need pos 1st value for LpScl storage */\n    Scl = -Scl;\n  for (i = 0; i < Nwing; i++)         /* Scale them */\n    fImp[i] = (SFLOAT)(ImpR[i] * Scl);\n\n  return (0);\n}\n"
  },
  {
    "path": "avs_core/core/audio.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n#ifndef __Audio_H__\n#define __Audio_H__\n\n#include <avisynth.h>\n#include <cmath>\n\n// ------- Channels, only 0..17, SPEAKER_ALL not handled here\nenum AVSChannel {\n  AVS_CHAN_IDX_NONE = -1, // Invalid channel index\n  AVS_CHAN_IDX_FRONT_LEFT,\n  AVS_CHAN_IDX_FRONT_RIGHT,\n  AVS_CHAN_IDX_FRONT_CENTER,\n  AVS_CHAN_IDX_LOW_FREQUENCY,\n  AVS_CHAN_IDX_BACK_LEFT,\n  AVS_CHAN_IDX_BACK_RIGHT,\n  AVS_CHAN_IDX_FRONT_LEFT_OF_CENTER,\n  AVS_CHAN_IDX_FRONT_RIGHT_OF_CENTER,\n  AVS_CHAN_IDX_BACK_CENTER,\n  AVS_CHAN_IDX_SIDE_LEFT,\n  AVS_CHAN_IDX_SIDE_RIGHT,\n  AVS_CHAN_IDX_TOP_CENTER,\n  AVS_CHAN_IDX_TOP_FRONT_LEFT,\n  AVS_CHAN_IDX_TOP_FRONT_CENTER,\n  AVS_CHAN_IDX_TOP_FRONT_RIGHT,\n  AVS_CHAN_IDX_TOP_BACK_LEFT,\n  AVS_CHAN_IDX_TOP_BACK_CENTER,\n  AVS_CHAN_IDX_TOP_BACK_RIGHT\n};\n\n// similarly to ffmpeg\n#define AVS_CHANNEL_LAYOUT_MONO              (AvsChannelMask::MASK_SPEAKER_FRONT_CENTER)\n#define AVS_CHANNEL_LAYOUT_STEREO            (AvsChannelMask::MASK_SPEAKER_FRONT_LEFT|AvsChannelMask::MASK_SPEAKER_FRONT_RIGHT)\n#define AVS_CHANNEL_LAYOUT_2POINT1           (AVS_CHANNEL_LAYOUT_STEREO|AvsChannelMask::MASK_SPEAKER_LOW_FREQUENCY)\n#define AVS_CHANNEL_LAYOUT_2_1               (AVS_CHANNEL_LAYOUT_STEREO|AvsChannelMask::MASK_SPEAKER_BACK_CENTER)\n#define AVS_CHANNEL_LAYOUT_SURROUND          (AVS_CHANNEL_LAYOUT_STEREO|AvsChannelMask::MASK_SPEAKER_FRONT_CENTER)\n#define AVS_CHANNEL_LAYOUT_3POINT1           (AVS_CHANNEL_LAYOUT_SURROUND|AvsChannelMask::MASK_SPEAKER_LOW_FREQUENCY)\n#define AVS_CHANNEL_LAYOUT_4POINT0           (AVS_CHANNEL_LAYOUT_SURROUND|AvsChannelMask::MASK_SPEAKER_BACK_CENTER)\n#define AVS_CHANNEL_LAYOUT_4POINT1           (AVS_CHANNEL_LAYOUT_4POINT0|AvsChannelMask::MASK_SPEAKER_LOW_FREQUENCY)\n#define AVS_CHANNEL_LAYOUT_2_2               (AVS_CHANNEL_LAYOUT_STEREO|AvsChannelMask::MASK_SPEAKER_SIDE_LEFT|AvsChannelMask::MASK_SPEAKER_SIDE_RIGHT)\n#define AVS_CHANNEL_LAYOUT_QUAD              (AVS_CHANNEL_LAYOUT_STEREO|AvsChannelMask::MASK_SPEAKER_BACK_LEFT|AvsChannelMask::MASK_SPEAKER_BACK_RIGHT)\n#define AVS_CHANNEL_LAYOUT_5POINT0           (AVS_CHANNEL_LAYOUT_SURROUND|AvsChannelMask::MASK_SPEAKER_SIDE_LEFT|AvsChannelMask::MASK_SPEAKER_SIDE_RIGHT)\n#define AVS_CHANNEL_LAYOUT_5POINT1           (AVS_CHANNEL_LAYOUT_5POINT0|AvsChannelMask::MASK_SPEAKER_LOW_FREQUENCY)\n#define AVS_CHANNEL_LAYOUT_5POINT0_BACK      (AVS_CHANNEL_LAYOUT_SURROUND|AvsChannelMask::MASK_SPEAKER_BACK_LEFT|AvsChannelMask::MASK_SPEAKER_BACK_RIGHT)\n#define AVS_CHANNEL_LAYOUT_5POINT1_BACK      (AVS_CHANNEL_LAYOUT_5POINT0_BACK|AvsChannelMask::MASK_SPEAKER_LOW_FREQUENCY)\n#define AVS_CHANNEL_LAYOUT_6POINT0           (AVS_CHANNEL_LAYOUT_5POINT0|AvsChannelMask::MASK_SPEAKER_BACK_CENTER)\n#define AVS_CHANNEL_LAYOUT_6POINT0_FRONT     (AVS_CHANNEL_LAYOUT_2_2|AvsChannelMask::MASK_SPEAKER_FRONT_LEFT_OF_CENTER|AvsChannelMask::MASK_SPEAKER_FRONT_RIGHT_OF_CENTER)\n#define AVS_CHANNEL_LAYOUT_HEXAGONAL         (AVS_CHANNEL_LAYOUT_5POINT0_BACK|AvsChannelMask::MASK_SPEAKER_BACK_CENTER)\n#define AVS_CHANNEL_LAYOUT_6POINT1           (AVS_CHANNEL_LAYOUT_5POINT1|AvsChannelMask::MASK_SPEAKER_BACK_CENTER)\n#define AVS_CHANNEL_LAYOUT_6POINT1_BACK      (AVS_CHANNEL_LAYOUT_5POINT1_BACK|AvsChannelMask::MASK_SPEAKER_BACK_CENTER)\n#define AVS_CHANNEL_LAYOUT_6POINT1_FRONT     (AVS_CHANNEL_LAYOUT_6POINT0_FRONT|AvsChannelMask::MASK_SPEAKER_LOW_FREQUENCY)\n#define AVS_CHANNEL_LAYOUT_7POINT0           (AVS_CHANNEL_LAYOUT_5POINT0|AvsChannelMask::MASK_SPEAKER_BACK_LEFT|AvsChannelMask::MASK_SPEAKER_BACK_RIGHT)\n#define AVS_CHANNEL_LAYOUT_7POINT0_FRONT     (AVS_CHANNEL_LAYOUT_5POINT0|AvsChannelMask::MASK_SPEAKER_FRONT_LEFT_OF_CENTER|AvsChannelMask::MASK_SPEAKER_FRONT_RIGHT_OF_CENTER)\n#define AVS_CHANNEL_LAYOUT_7POINT1           (AVS_CHANNEL_LAYOUT_5POINT1|AvsChannelMask::MASK_SPEAKER_BACK_LEFT|AvsChannelMask::MASK_SPEAKER_BACK_RIGHT)\n#define AVS_CHANNEL_LAYOUT_7POINT1_WIDE      (AVS_CHANNEL_LAYOUT_5POINT1|AvsChannelMask::MASK_SPEAKER_FRONT_LEFT_OF_CENTER|AvsChannelMask::MASK_SPEAKER_FRONT_RIGHT_OF_CENTER)\n#define AVS_CHANNEL_LAYOUT_7POINT1_WIDE_BACK (AVS_CHANNEL_LAYOUT_5POINT1_BACK|AvsChannelMask::MASK_SPEAKER_FRONT_LEFT_OF_CENTER|AvsChannelMask::MASK_SPEAKER_FRONT_RIGHT_OF_CENTER)\n#define AVS_CHANNEL_LAYOUT_7POINT1_TOP_BACK  (AVS_CHANNEL_LAYOUT_5POINT1_BACK|AvsChannelMask::MASK_SPEAKER_TOP_FRONT_LEFT|AvsChannelMask::MASK_SPEAKER_TOP_FRONT_RIGHT)\n#define AVS_CHANNEL_LAYOUT_OCTAGONAL         (AVS_CHANNEL_LAYOUT_5POINT0|AvsChannelMask::MASK_SPEAKER_BACK_LEFT|AvsChannelMask::MASK_SPEAKER_BACK_CENTER|AvsChannelMask::MASK_SPEAKER_BACK_RIGHT)\n#define AVS_CHANNEL_LAYOUT_CUBE              (AVS_CHANNEL_LAYOUT_QUAD|AvsChannelMask::MASK_SPEAKER_TOP_FRONT_LEFT|AvsChannelMask::MASK_SPEAKER_TOP_FRONT_RIGHT|AvsChannelMask::MASK_SPEAKER_TOP_BACK_LEFT|AvsChannelMask::MASK_SPEAKER_TOP_BACK_RIGHT)\n//#define AVS_CHANNEL_LAYOUT_HEXADECAGONAL     (AVS_CHANNEL_LAYOUT_OCTAGONAL|AvsChannelMask::MASK_SPEAKER_WIDE_LEFT|AvsChannelMask::MASK_SPEAKER_WIDE_RIGHT|AvsChannelMask::MASK_SPEAKER_TOP_BACK_LEFT|AvsChannelMask::MASK_SPEAKER_TOP_BACK_RIGHT|AvsChannelMask::MASK_SPEAKER_TOP_BACK_CENTER|AvsChannelMask::MASK_SPEAKER_TOP_FRONT_CENTER|AvsChannelMask::MASK_SPEAKER_TOP_FRONT_LEFT|AvsChannelMask::MASK_SPEAKER_TOP_FRONT_RIGHT)\n//#define AVS_CHANNEL_LAYOUT_STEREO_DOWNMIX    (AvsChannelMask::MASK_SPEAKER_STEREO_LEFT|AvsChannelMask::MASK_SPEAKER_STEREO_RIGHT)\n\ntypedef struct ChannelLayoutDescriptor_t {\n  int nb_channels;\n  unsigned int mask;\n} ChannelLayoutDescriptor_t;\n\n#define AVS_CHANNEL_LAYOUT_MASK(nb, m) \\\n     { (nb), (m) }\n\n// Common pre-defined channel layouts\n#define AVS_CHANNEL_LAYOUT_MASK_MONO              AVS_CHANNEL_LAYOUT_MASK(1,  AVS_CHANNEL_LAYOUT_MONO)\n#define AVS_CHANNEL_LAYOUT_MASK_STEREO            AVS_CHANNEL_LAYOUT_MASK(2,  AVS_CHANNEL_LAYOUT_STEREO)\n#define AVS_CHANNEL_LAYOUT_MASK_2POINT1           AVS_CHANNEL_LAYOUT_MASK(3,  AVS_CHANNEL_LAYOUT_2POINT1)\n#define AVS_CHANNEL_LAYOUT_MASK_2_1               AVS_CHANNEL_LAYOUT_MASK(3,  AVS_CHANNEL_LAYOUT_2_1)\n#define AVS_CHANNEL_LAYOUT_MASK_SURROUND          AVS_CHANNEL_LAYOUT_MASK(3,  AVS_CHANNEL_LAYOUT_SURROUND)\n#define AVS_CHANNEL_LAYOUT_MASK_3POINT1           AVS_CHANNEL_LAYOUT_MASK(4,  AVS_CHANNEL_LAYOUT_3POINT1)\n#define AVS_CHANNEL_LAYOUT_MASK_4POINT0           AVS_CHANNEL_LAYOUT_MASK(4,  AVS_CHANNEL_LAYOUT_4POINT0)\n#define AVS_CHANNEL_LAYOUT_MASK_4POINT1           AVS_CHANNEL_LAYOUT_MASK(5,  AVS_CHANNEL_LAYOUT_4POINT1)\n#define AVS_CHANNEL_LAYOUT_MASK_2_2               AVS_CHANNEL_LAYOUT_MASK(4,  AVS_CHANNEL_LAYOUT_2_2)\n#define AVS_CHANNEL_LAYOUT_MASK_QUAD              AVS_CHANNEL_LAYOUT_MASK(4,  AVS_CHANNEL_LAYOUT_QUAD)\n#define AVS_CHANNEL_LAYOUT_MASK_5POINT0           AVS_CHANNEL_LAYOUT_MASK(5,  AVS_CHANNEL_LAYOUT_5POINT0)\n#define AVS_CHANNEL_LAYOUT_MASK_5POINT1           AVS_CHANNEL_LAYOUT_MASK(6,  AVS_CHANNEL_LAYOUT_5POINT1)\n#define AVS_CHANNEL_LAYOUT_MASK_5POINT0_BACK      AVS_CHANNEL_LAYOUT_MASK(5,  AVS_CHANNEL_LAYOUT_5POINT0_BACK)\n#define AVS_CHANNEL_LAYOUT_MASK_5POINT1_BACK      AVS_CHANNEL_LAYOUT_MASK(6,  AVS_CHANNEL_LAYOUT_5POINT1_BACK)\n#define AVS_CHANNEL_LAYOUT_MASK_6POINT0           AVS_CHANNEL_LAYOUT_MASK(6,  AVS_CHANNEL_LAYOUT_6POINT0)\n#define AVS_CHANNEL_LAYOUT_MASK_6POINT0_FRONT     AVS_CHANNEL_LAYOUT_MASK(6,  AVS_CHANNEL_LAYOUT_6POINT0_FRONT)\n#define AVS_CHANNEL_LAYOUT_MASK_HEXAGONAL         AVS_CHANNEL_LAYOUT_MASK(6,  AVS_CHANNEL_LAYOUT_HEXAGONAL)\n#define AVS_CHANNEL_LAYOUT_MASK_6POINT1           AVS_CHANNEL_LAYOUT_MASK(7,  AVS_CHANNEL_LAYOUT_6POINT1)\n#define AVS_CHANNEL_LAYOUT_MASK_6POINT1_BACK      AVS_CHANNEL_LAYOUT_MASK(7,  AVS_CHANNEL_LAYOUT_6POINT1_BACK)\n#define AVS_CHANNEL_LAYOUT_MASK_6POINT1_FRONT     AVS_CHANNEL_LAYOUT_MASK(7,  AVS_CHANNEL_LAYOUT_6POINT1_FRONT)\n#define AVS_CHANNEL_LAYOUT_MASK_7POINT0           AVS_CHANNEL_LAYOUT_MASK(7,  AVS_CHANNEL_LAYOUT_7POINT0)\n#define AVS_CHANNEL_LAYOUT_MASK_7POINT0_FRONT     AVS_CHANNEL_LAYOUT_MASK(7,  AVS_CHANNEL_LAYOUT_7POINT0_FRONT)\n#define AVS_CHANNEL_LAYOUT_MASK_7POINT1           AVS_CHANNEL_LAYOUT_MASK(8,  AVS_CHANNEL_LAYOUT_7POINT1)\n#define AVS_CHANNEL_LAYOUT_MASK_7POINT1_WIDE      AVS_CHANNEL_LAYOUT_MASK(8,  AVS_CHANNEL_LAYOUT_7POINT1_WIDE)\n#define AVS_CHANNEL_LAYOUT_MASK_7POINT1_WIDE_BACK AVS_CHANNEL_LAYOUT_MASK(8,  AVS_CHANNEL_LAYOUT_7POINT1_WIDE_BACK)\n#define AVS_CHANNEL_LAYOUT_MASK_7POINT1_TOP_BACK  AVS_CHANNEL_LAYOUT_MASK(8,  AVS_CHANNEL_LAYOUT_7POINT1_TOP_BACK)\n#define AVS_CHANNEL_LAYOUT_MASK_OCTAGONAL         AVS_CHANNEL_LAYOUT_MASK(8,  AVS_CHANNEL_LAYOUT_OCTAGONAL)\n#define AVS_CHANNEL_LAYOUT_MASK_CUBE              AVS_CHANNEL_LAYOUT_MASK(8,  AVS_CHANNEL_LAYOUT_CUBE)\n//#define AVS_CHANNEL_LAYOUT_MASK_HEXADECAGONAL     AVS_CHANNEL_LAYOUT_MASK(16, AVS_CHANNEL_LAYOUT_HEXADECAGONAL)\n\nunsigned int av_get_channel_layout(const char* name);\nunsigned int GetDefaultChannelLayout(int nChannels);\nstd::string channel_layout_to_str(const unsigned int channel_layout_mask);\n\n/******* Helper stuff *******/\n\n#define MAX_SHORT (32767)\n#define MIN_SHORT (-32768)\n\n\n/* Conversion constants */    // We are using fixed point binary arithmetic here\n#define Nhc       8           // Number of bits for filter points\n#define Na        7           // Number of bits for interpolating between filter points\n#define Np       (Nhc+Na)     // Total number of bits to represent fractional phase\n#define Npc      (1<<Nhc)     // Sampling period binary point scaling factor\n#define Amask    ((1<<Na)-1)  // Interpolation mask\n#define Pmask    ((1<<Np)-1)  // Phase mask\n#define Nh       16           // Number of bits to represent coefficients\n#define Nb       16           // Unused\n#define Nhxn     14           // Number of non-guard bits\n#define Nhg      (Nh-Nhxn)    // Number of guard bits\n#define NLpScl   13           // Number of overflow bits\n\n\n#define IzeroEPSILON 1E-21               /* Max error acceptable in Izero */\n\nstatic constexpr double PI = 3.14159265358979323846;\n\nstatic __inline short IntToShort(int v, const int scl)\n{\n  v += (1<<(scl-1));  /* round */\n  v >>= scl;\n  if (v>MAX_SHORT)\n    return MAX_SHORT;\n  else if (v < MIN_SHORT)\n    return MIN_SHORT;\n  else\n    return (short)v;\n}\n\nstatic double Izero(double x);\nstatic void LpFilter(double c[], int N, double frq, double Beta, int Num);\nstatic int makeFilter(short   Imp[], double &dLpScl, unsigned short Nwing, double Froll, double Beta);\nstatic int makeFilter(SFLOAT fImp[], double  dLpScl, unsigned short Nwing, double Froll, double Beta);\n\n\n/********************************************************************\n********************************************************************/\n\nclass AssumeRate : public NonCachedGenericVideoFilter\n/**\n  * Changes the sample rate of a clip\n **/\n{\npublic:\n  AssumeRate(PClip _clip, int _rate);\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment*);\n};\n\n\n\nclass ConvertToMono : public GenericVideoFilter\n/**\n  * Class to convert audio to mono\n **/\n{\npublic:\n  ConvertToMono(PClip _clip);\n  virtual ~ConvertToMono()\n  {if (tempbuffer_size) {delete[] tempbuffer;tempbuffer_size=0;}}\n\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env);\n  int __stdcall SetCacheHints(int cachehints, int frame_range);\n  static PClip Create(PClip clip);\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment*);\n\nprivate:\n  char *tempbuffer;\n  int tempbuffer_size;\n  int channels;\n};\n\nclass EnsureVBRMP3Sync : public GenericVideoFilter\n/**\n  * Ensure VBR mp3 sync, by always reading audio sequencially.\n **/\n{\npublic:\n  EnsureVBRMP3Sync(PClip _clip);\n\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env);\n  int __stdcall SetCacheHints(int cachehints, int frame_range);\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\nprivate:\n  int64_t last_end;\n};\n\nclass MergeChannels : public GenericVideoFilter\n/**\n  * Class to convert two mono sources to stereo\n **/\n{\npublic:\n  MergeChannels(PClip _clip, int _num_children, PClip* _child_array, IScriptEnvironment* env);\n  ~MergeChannels();\n\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env);\n  int __stdcall SetCacheHints(int cachehints, int frame_range);\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment*);\n\nprivate:\n  int* clip_channels;\n  signed char** clip_offset;\n  signed char *tempbuffer;\n  PClip* child_array;\n  const int num_children;\n  int tempbuffer_size;\n};\n\n\nclass GetChannel : public GenericVideoFilter\n/**\n  * Class to get left or right channel from stereo source\n **/\n{\npublic:\n  GetChannel(PClip _clip, int* _channel, int numchannels);\n  virtual ~GetChannel()\n  {\n    if (tempbuffer_size) {delete[] tempbuffer;tempbuffer_size=0;}\n    if (channel)         {delete[] channel;   channel=0;        }\n  }\n\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env);\n  int __stdcall SetCacheHints(int cachehints, int frame_range);\n  static PClip Create_left(PClip clip);\n  static PClip Create_right(PClip clip);\n  static PClip Create_n(PClip clip, int* n, int numchannels);\n  static AVSValue __cdecl Create_left(AVSValue args, void*, IScriptEnvironment*);\n  static AVSValue __cdecl Create_right(AVSValue args, void*, IScriptEnvironment*);\n  static AVSValue __cdecl Create_n(AVSValue args, void*, IScriptEnvironment* env);\n\nprivate:\n  char *tempbuffer;\n  int* channel;\n  int tempbuffer_size;\n  int numchannels;\n  int cbps;\n  int src_bps;\n  int dst_bps;\n};\n\nclass KillVideo : public GenericVideoFilter\n/**\n  * Removes audio from clip\n **/\n{\npublic:\n  KillVideo(PClip _clip);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment*) { AVS_UNUSED(n); return NULL; };\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment*);\n};\n\n\nclass KillAudio : public NonCachedGenericVideoFilter\n/**\n  * Removes audio from clip\n **/\n{\npublic:\n  KillAudio(PClip _clip);\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) { AVS_UNUSED(buf); AVS_UNUSED(start); AVS_UNUSED(count); AVS_UNUSED(env); };\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment*);\n};\n\nclass SetChannelMask : public NonCachedGenericVideoFilter\n  /**\n    * Sets/remove Audio Channel Mask from VideoInfo\n   **/\n{\npublic:\n  SetChannelMask(PClip _clip, bool IsChannelMaskKnown, unsigned int dwChannelMask);\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment*);\n};\n\nclass DelayAudio : public GenericVideoFilter\n/**\n  * Class to delay audio stream\n **/\n{\npublic:\n  DelayAudio(double delay, PClip _child);\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env);\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\nprivate:\n  const int64_t delay_samples;\n};\n\n\n\nclass Amplify : public GenericVideoFilter\n/**\n  * Amplify a clip's audio track\n **/\n{\npublic:\n  Amplify(PClip _child, float* _volumes, int* _i_v);\n  ~Amplify();\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env);\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n  static AVSValue __cdecl Create_dB(AVSValue args, void*, IScriptEnvironment* env);\n\n\nprivate:\n  const float* volumes;\n  const int* i_v;\n\n static __inline float dBtoScaleFactorf(float dB)\n { return powf(10.0f, dB/20.0f);};\n};\n\n\n\n\n\nclass Normalize : public GenericVideoFilter\n/**\n  * Normalize a clip's audio track\n **/\n{\npublic:\n  Normalize(PClip _child, float _max_factor, bool _showvalues);\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env);\n  int __stdcall SetCacheHints(int cachehints, int frame_range);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\n\nprivate:\n  float max_factor;\n  float max_volume;\n  int   frameno;\n  bool showvalues;\n};\n\nclass MixAudio : public GenericVideoFilter\n/**\n  * Mix audio from one clip into another.\n **/\n{\npublic:\n  MixAudio(PClip _child, PClip _clip, double _track1_factor, double _track2_factor, IScriptEnvironment* env);\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env);\n  int __stdcall SetCacheHints(int cachehints, int frame_range);\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n  virtual ~MixAudio() {if (tempbuffer_size) delete[] tempbuffer;tempbuffer_size=0;}\n\n\nprivate:\n  PClip clip;\n  signed char *tempbuffer;\n  const int track1_factor, track2_factor;\n  const float t1factor, t2factor;\n  int tempbuffer_size;\n};\n\n\nclass ResampleAudio : public GenericVideoFilter\n/**\n  * Class to resample the audio stream\n **/\n{\npublic:\n  ResampleAudio(PClip _child, int _target_rate_n, int _target_rate_d, IScriptEnvironment* env);\n  virtual ~ResampleAudio()\n    { delete[]  srcbuffer;\n      delete[] fsrcbuffer; }\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env);\n  int __stdcall SetCacheHints(int cachehints, int frame_range);\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\n  enum { Nwing = 8192, Nmult = 65 };   // Number of filter points, (Nwing>>Nhc)*2+1\n\nprivate:\n  int64_t FilterUD(short  *Xp, short Ph, short Inc);\n  SFLOAT  FilterUD(SFLOAT *Xp, short Ph, short Inc);\n\n  const double factor;\n  int Xoff, dtb, dhb;\n  unsigned dtbe;\n\n  int LpScl, mLpScl, mNhg;\n\n  short*   srcbuffer;\n  SFLOAT* fsrcbuffer;\n\n  int srcbuffer_size;\n  bool skip_conversion;\n\n  int64_t last_start, last_samples;\n\n  union { // Share storage\n  SFLOAT fImp[Nwing+1];\n  short Imp[Nwing+1];\n  };\n};\n\n\n#endif  // __Audio_H__\n"
  },
  {
    "path": "avs_core/core/avisynth.cpp",
    "content": "// Avisynth v2.6.  Copyright 2002-2009 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include <avisynth.h>\n#include \"../core/internal.h\"\n#include \"InternalEnvironment.h\"\n#include \"./parser/script.h\"\n#include <avs/minmax.h>\n#include <avs/alignment.h>\n#include \"strings.h\"\n#include <avs/cpuid.h>\n#include <unordered_set>\n#include \"bitblt.h\"\n#include \"FilterConstructor.h\"\n#include \"PluginManager.h\"\n#include \"../filters/conditional/conditional_reader.h\"\n#include \"MappedList.h\"\n#include <chrono>\n#include <vector>\n#include <iostream>\n#include <fstream>\n#include <sstream>\n#include <exception>\n\n#define __STDC_FORMAT_MACROS\n#include <inttypes.h>\n\n#ifdef AVS_WINDOWS\n    #include <avs/win.h>\n    #include <objbase.h>\n#else\n    #include \"avisynth_conf.h\"\n#if defined(AVS_MACOS)\n    #include <mach/host_info.h>\n    #include <mach/mach_host.h>\n    #include <mach/mach_init.h>\n    #include <sys/sysctl.h>\n#elif defined(AVS_BSD)\n    #include <sys/sysctl.h>\n#else\n    #include <avs/filesystem.h>\n    #include <set>\n#if defined(AVS_HAIKU)\n    #include <OS.h>\n#else\n    #include <sys/sysinfo.h>\n#endif\n#endif\n    #include <avs/posix.h>\n#endif\n\n#include <string>\n#include <cstdio>\n#include <cstdarg>\n#include <cassert>\n#include \"MTGuard.h\"\n#include \"cache.h\"\n#include <clocale>\n#include <cmath>\n#include <limits>\n#include <set>\n\n#include \"FilterGraph.h\"\n#include \"DeviceManager.h\"\n#include \"AVSMap.h\"\n\n#ifndef YieldProcessor // low power spin idle\n  #define YieldProcessor() __nop(void)\n#endif\n\nclass ScriptEnvironment; // forward\n\n/* Global Lock Manager */\nclass GlobalLockManager\n{\npublic:\n  // Get a named mutex. If it doesn't exist, it's created.\n  static std::mutex& get_mutex(const std::string& name);\n\n  // Track which environments hold which locks for cleanup.\n  static void acquire_lock_for_env(const std::string& name, ScriptEnvironment* env);\n  static void release_lock_for_env(const std::string& name, ScriptEnvironment* env);\n\n  // Called when an IScriptEnvironment is destroyed.\n  static void on_environment_exit(ScriptEnvironment* env);\n\nprivate:\n  GlobalLockManager() = delete;\n  ~GlobalLockManager() = delete;\n\n  static std::map<std::string, std::unique_ptr<std::mutex>> s_namedMutexes;\n  static std::mutex s_mutexMapLock; // Protects s_namedMutexes\n\n  static std::map<ScriptEnvironment*, std::set<std::string>> s_envToHeldLocks;\n  static std::mutex s_envLocksMapLock; // Protects s_envToHeldLocks\n};\n\nstd::map<std::string, std::unique_ptr<std::mutex>> GlobalLockManager::s_namedMutexes;\nstd::mutex GlobalLockManager::s_mutexMapLock;\nstd::map<ScriptEnvironment*, std::set<std::string>> GlobalLockManager::s_envToHeldLocks;\nstd::mutex GlobalLockManager::s_envLocksMapLock;\n\nstd::mutex& GlobalLockManager::get_mutex(const std::string& name)\n{\n  std::lock_guard<std::mutex> lock(s_mutexMapLock);\n  if (s_namedMutexes.find(name) == s_namedMutexes.end())\n  {\n    s_namedMutexes[name] = std::make_unique<std::mutex>();\n  }\n  return *s_namedMutexes[name];\n}\n\nvoid GlobalLockManager::acquire_lock_for_env(const std::string& name, ScriptEnvironment* env)\n{\n  std::lock_guard<std::mutex> envLock(s_envLocksMapLock);\n  s_envToHeldLocks[env].insert(name);\n}\n\nvoid GlobalLockManager::release_lock_for_env(const std::string& name, ScriptEnvironment* env)\n{\n  std::lock_guard<std::mutex> envLock(s_envLocksMapLock);\n  if (s_envToHeldLocks.count(env))\n  {\n    s_envToHeldLocks[env].erase(name);\n    if (s_envToHeldLocks[env].empty())\n    {\n      s_envToHeldLocks.erase(env);\n    }\n  }\n}\n\nvoid GlobalLockManager::on_environment_exit(ScriptEnvironment* env)\n{\n  std::lock_guard<std::mutex> envLock(s_envLocksMapLock);\n  auto it = s_envToHeldLocks.find(env);\n  if (it != s_envToHeldLocks.end())\n  {\n    // Note: The actual mutexes are not unlocked here, only the tracking is cleared.\n    // A truly stuck mutex requires more complex solutions (e.g., timed_mutex with recovery,\n    // or ensuring threads exit gracefully). For Avisynth's use case, clearing the tracking\n    // is important to prevent memory leaks in the map.\n\n    // If it tried to call unlock() on a mutex held by another (potentially crashed) thread,\n    // that would lead to undefined behavior.By simply removing the tracking entry,\n    // we avoid this dangerous operation.\n    s_envToHeldLocks.erase(it);\n  }\n}\n\nextern const AVSFunction Audio_filters[],\n                         Combine_filters[],\n                         Convert_filters[],\n                         Convolution_filters[],\n                         Edit_filters[],\n                         Field_filters[],\n                         Focus_filters[],\n                         Fps_filters[],\n                         Histogram_filters[],\n                         Layer_filters[],\n                         Levels_filters[],\n                         Misc_filters[],\n                         Plugin_functions[],\n                         Resample_filters[],\n                         Resize_filters[],\n                         Script_functions[],\n                         Source_filters[],\n                         Text_filters[],\n                         Transform_filters[],\n                         Merge_filters[],\n                         Color_filters[],\n                         Debug_filters[],\n                         Turn_filters[],\n                         Conditional_filters[],\n                         Conditional_funtions_filters[],\n                         Cache_filters[],\n                         Greyscale_filters[],\n                         Swap_filters[],\n                         Overlay_filters[],\n                         Exprfilter_filters[],\n                         FilterGraph_filters[],\n                         Device_filters[]\n;\n\n\nconst AVSFunction* const builtin_functions[] = {\n                         Audio_filters,\n                         Combine_filters,\n                         Convert_filters,\n                         Convolution_filters,\n                         Edit_filters,\n                         Field_filters,\n                         Focus_filters,\n                         Fps_filters,\n                         Histogram_filters,\n                         Layer_filters,\n                         Levels_filters,\n                         Misc_filters,\n                         Resample_filters,\n                         Resize_filters,\n                         Script_functions,\n                         Source_filters,\n                         Text_filters,\n                         Transform_filters,\n                         Merge_filters,\n                         Color_filters,\n                         Debug_filters,\n                         Turn_filters,\n                         Conditional_filters,\n                         Conditional_funtions_filters,\n                         Plugin_functions,\n                         Cache_filters,\n                         Overlay_filters,\n                         Greyscale_filters,\n                         Swap_filters,\n                         FilterGraph_filters,\n                         Device_filters,\n                         Exprfilter_filters\n};\n\n#if 0\n// Global statistics counters\nstruct {\n  unsigned int CleanUps;\n  unsigned int Losses;\n  unsigned int PlanA1;\n  unsigned int PlanA2;\n  unsigned int PlanB;\n  unsigned int PlanC;\n  unsigned int PlanD;\n  char tag[36];\n} g_Mem_stats = { 0, 0, 0, 0, 0, 0, 0, \"CleanUps, Losses, Plan[A1,A2,B,C,D]\" };\n#endif\n\nconst _PixelClip PixelClip;\n\n\n#ifdef MSVC\n// Helper function to count set bits in the processor mask.\ntemplate<typename T>\nstatic uint32_t CountSetBits(T bitMask)\n{\n  uint32_t LSHIFT = sizeof(T) * 8 - 1;\n  uint32_t bitSetCount = 0;\n  T bitTest = (T)1 << LSHIFT;\n  uint32_t i;\n\n  for (i = 0; i <= LSHIFT; ++i)\n  {\n    bitSetCount += ((bitMask & bitTest) ? 1 : 0);\n    bitTest /= 2;\n  }\n\n  return bitSetCount;\n}\n#endif\n\nstatic size_t GetNumPhysicalCPUs()\n{\n#if defined(AVS_WINDOWS)\n#ifdef MSVC\n  typedef BOOL(WINAPI* LPFN_GLPI)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD);\n  LPFN_GLPI glpi;\n  BOOL done = FALSE;\n  PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL;\n  PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = NULL;\n  DWORD returnLength = 0;\n  [[maybe_unused]] DWORD logicalProcessorCount = 0;\n  [[maybe_unused]] DWORD numaNodeCount = 0;\n  [[maybe_unused]] DWORD processorCoreCount = 0;\n  [[maybe_unused]] DWORD processorL1CacheCount = 0;\n  [[maybe_unused]] DWORD processorL2CacheCount = 0;\n  [[maybe_unused]] DWORD processorL3CacheCount = 0;\n  [[maybe_unused]] DWORD processorPackageCount = 0;\n  DWORD byteOffset = 0;\n  PCACHE_DESCRIPTOR Cache;\n\n  glpi = (LPFN_GLPI)GetProcAddress(\n    GetModuleHandle(TEXT(\"kernel32\")),\n    \"GetLogicalProcessorInformation\");\n  if (NULL == glpi)\n  {\n    //    _tprintf(TEXT(\"\\nGetLogicalProcessorInformation is not supported.\\n\"));\n    return (0);\n  }\n\n  while (!done)\n  {\n    BOOL rc = glpi(buffer, &returnLength);\n\n    if (FALSE == rc)\n    {\n      if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)\n      {\n        if (buffer)\n          free(buffer);\n\n        buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)malloc(\n          returnLength);\n\n        if (NULL == buffer)\n        {\n          //          _tprintf(TEXT(\"\\nError: Allocation failure\\n\"));\n          return (0);\n        }\n      }\n      else\n      {\n        //        _tprintf(TEXT(\"\\nError %d\\n\"), GetLastError());\n        return (0);\n      }\n    }\n    else\n    {\n      done = TRUE;\n    }\n  }\n\n  ptr = buffer;\n\n  while (byteOffset + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= returnLength)\n  {\n    switch (ptr->Relationship)\n    {\n    case RelationNumaNode:\n      // Non-NUMA systems report a single record of this type.\n      numaNodeCount++;\n      break;\n\n    case RelationProcessorCore:\n      processorCoreCount++;\n\n      // A hyperthreaded core supplies more than one logical processor.\n      logicalProcessorCount += CountSetBits<ULONG_PTR>(ptr->ProcessorMask);\n      break;\n\n    case RelationCache:\n      // Cache data is in ptr->Cache, one CACHE_DESCRIPTOR structure for each cache.\n      Cache = &ptr->Cache;\n      if (Cache->Level == 1)\n      {\n        processorL1CacheCount++;\n      }\n      else if (Cache->Level == 2)\n      {\n        processorL2CacheCount++;\n      }\n      else if (Cache->Level == 3)\n      {\n        processorL3CacheCount++;\n      }\n      break;\n\n    case RelationProcessorPackage:\n      // Logical processors share a physical package.\n      processorPackageCount++;\n      break;\n\n    default:\n      //      _tprintf(TEXT(\"\\nError: Unsupported LOGICAL_PROCESSOR_RELATIONSHIP value.\\n\"));\n      return (0);\n    }\n    byteOffset += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);\n    ptr++;\n  }\n\n  /*\n  _tprintf(TEXT(\"\\nGetLogicalProcessorInformation results:\\n\"));\n  _tprintf(TEXT(\"Number of NUMA nodes: %d\\n\"),\n    numaNodeCount);\n  _tprintf(TEXT(\"Number of physical processor packages: %d\\n\"),\n    processorPackageCount);\n  _tprintf(TEXT(\"Number of processor cores: %d\\n\"),\n    processorCoreCount);\n  _tprintf(TEXT(\"Number of logical processors: %d\\n\"),\n    logicalProcessorCount);\n  _tprintf(TEXT(\"Number of processor L1/L2/L3 caches: %d/%d/%d\\n\"),\n    processorL1CacheCount,\n    processorL2CacheCount,\n    processorL3CacheCount);\n  */\n\n  free(buffer);\n\n  return processorCoreCount;\n#else\n  return 4; // TODO: GCC on Windows?\n#endif\n#elif defined(AVS_LINUX)\n  std::set<int> core_ids;\n  for (auto& p : fs::directory_iterator(\"/sys/devices/system/cpu\")) {\n    if (!p.path().filename().string().rfind(\"cpu\", 0)) {\n      std::ifstream ifs(p.path() / \"topology/core_id\");\n      int core_id;\n      if (ifs) {\n        ifs >> core_id;\n        if (ifs)\n          core_ids.insert(core_id);\n      }\n    }\n  }\n  return core_ids.size();\n#elif defined(AVS_MACOS)\n  int cpu_cnt = 0;\n  size_t cpu_cnt_size = sizeof(cpu_cnt);\n  return sysctlbyname(\"hw.physicalcpu\", &cpu_cnt, &cpu_cnt_size, NULL, 0) ? 0 : cpu_cnt;\n#else\n  return 4; // AVS_BSD TODO\n#endif\n}\n\n#ifdef MSVC\nstatic std::string FormatString(const char* fmt, va_list args)\n{\n  va_list args2;\n  va_copy(args2, args);\n  _locale_t locale = _create_locale(LC_NUMERIC, \"C\"); // decimal point: dot\n\n  int count = _vscprintf_l(fmt, locale, args2);\n  // don't use _vsnprintf_l(NULL, 0, fmt, locale, args) here,\n  // it returns -1 instead of the buffer size under Wine (February, 2017)\n  std::vector<char> buf(count + 1);\n  _vsnprintf_l(buf.data(), buf.size(), fmt, locale, args2);\n\n  _free_locale(locale);\n  va_end(args2);\n\n  return std::string(buf.data());\n}\n#else\nstatic std::string FormatString(const char* fmt, va_list args)\n{\n  va_list args2;\n  va_copy(args2, args);\n\n  // There is no locale specific version of vsnprintf under Linux/gcc.\n  // During program startup, the equivalent of setlocale(LC_ALL, \"C\")\n  // is executed before any user code is run. But Avisynth is just a dll/shared object.\n  // If the host program calls std::setlocale(LC_ALL, \"\") - typically in its 'main()'\n  // then it sets current locale by the environment variables.\n  // Unfortunately setlocale is not thread safe and modifies global state which\n  // affects execution of locale-dependent functions, it is undefined behavior to call\n  // it from one thread, while another thread is executing any of such functions (e.g. sprintf)\n  // It can happen that a plugin sets setlocale(LC_ALL, \"\"). The effect is global,\n  // other formatting functions in the same program will start using the new\n  // (environment) setting.\n  // One must set LC_NUMERIC part of the locale to \"C\" before the host executable,\n  // to be sure that after such unsafe setlocale(LC_ALL, \"\") then formatting to dot\n  // remains O.K.\n\n#if 0\n  // Finally we don't do that. Not 100% safe.\n  std::string prev_loc = std::setlocale(LC_NUMERIC, nullptr);\n  setlocale(LC_NUMERIC, \"C\"); // Set C locale for '.' and no thousand sep\n#endif\n\n  int count = vsnprintf(NULL, 0, fmt, args);\n  std::vector<char> buf(count + 1);\n  vsnprintf(buf.data(), buf.size(), fmt, args2);\n\n  va_end(args2);\n\n#if 0\n  std::setlocale(LC_NUMERIC, prev_loc.c_str()); // Restore the previous locale.\n#endif\n\n  return std::string(buf.data());\n}\n#endif\n\nvoid* VideoFrame::operator new(size_t size) {\n  return ::operator new(size);\n}\n\nVideoFrame::VideoFrame(VideoFrameBuffer* _vfb, AVSMap* avsmap, int _offset, int _pitch, int _row_size, int _height, int _pixel_type)\n  : refcount(0), vfb(_vfb), offset(_offset), pitch(_pitch), row_size(_row_size), height(_height),\n  offsetU(_offset), offsetV(_offset), pitchUV(0), row_sizeUV(0), heightUV(0),  // PitchUV=0 so this doesn't take up additional space\n  offsetA(0), pitchA(0), row_sizeA(0),\n  properties(avsmap),\n  pixel_type(_pixel_type)\n{\n  InterlockedIncrement(&vfb->refcount);\n}\n\nVideoFrame::VideoFrame(VideoFrameBuffer* _vfb, AVSMap* avsmap, int _offset, int _pitch, int _row_size, int _height,\n  int _offsetU, int _offsetV, int _pitchUV, int _row_sizeUV, int _heightUV, int _pixel_type)\n  : refcount(0), vfb(_vfb), offset(_offset), pitch(_pitch), row_size(_row_size), height(_height),\n  offsetU(_offsetU), offsetV(_offsetV), pitchUV(_pitchUV), row_sizeUV(_row_sizeUV), heightUV(_heightUV),\n  offsetA(0), pitchA(0), row_sizeA(0),\n  properties(avsmap),\n  pixel_type(_pixel_type)\n{\n  InterlockedIncrement(&vfb->refcount);\n}\n\nVideoFrame::VideoFrame(VideoFrameBuffer* _vfb, AVSMap* avsmap, int _offset, int _pitch, int _row_size, int _height,\n  int _offsetU, int _offsetV, int _pitchUV, int _row_sizeUV, int _heightUV, int _offsetA, int _pixel_type)\n  : refcount(0), vfb(_vfb), offset(_offset), pitch(_pitch), row_size(_row_size), height(_height),\n  offsetU(_offsetU), offsetV(_offsetV), pitchUV(_pitchUV), row_sizeUV(_row_sizeUV), heightUV(_heightUV),\n  offsetA(_offsetA), pitchA(_pitch), row_sizeA(_row_size),\n  properties(avsmap),\n  pixel_type(_pixel_type)\n{\n  InterlockedIncrement(&vfb->refcount);\n}\n// Hack note: Use of Subframe will require an \"InterlockedDecrement(&retval->refcount);\" after\n// assignment to a PVideoFrame, the same as for a \"New VideoFrame\" to keep the refcount consistant.\n// P.F. ?? so far it works automatically\n\nVideoFrame* VideoFrame::Subframe(int rel_offset, int new_pitch, int new_row_size, int new_height) const {\n  // Change planar color formats to Y-only, which is quasi-interleaved\n  int new_pixel_type;\n  if (pixel_type & VideoInfo::CS_PLANAR)\n    new_pixel_type = VideoInfo::CS_GENERIC_Y | (pixel_type & VideoInfo::CS_Sample_Bits_Mask);\n  else\n    new_pixel_type = pixel_type;\n\n  return new VideoFrame(vfb, new AVSMap(), offset + rel_offset, new_pitch, new_row_size, new_height,\n    new_pixel_type);\n}\n\nVideoFrame* VideoFrame::Subframe(int rel_offset, int new_pitch, int new_row_size, int new_height,\n                                 int rel_offsetU, int rel_offsetV, int new_pitchUV) const {\n  // Maintain plane size relationship\n  const int new_row_sizeUV = !row_size ? 0 : MulDiv(new_row_size, row_sizeUV, row_size);\n  const int new_heightUV   = !height   ? 0 : MulDiv(new_height,   heightUV,   height);\n\n  // Remove alpha from color format\n  int new_pixel_type;\n  if (pixel_type & VideoInfo::CS_YUVA)\n    new_pixel_type = (pixel_type & ~VideoInfo::CS_YUVA) | VideoInfo::CS_YUV;\n  else if (pixel_type & VideoInfo::CS_RGBA_TYPE)\n    new_pixel_type = (pixel_type & ~VideoInfo::CS_RGBA_TYPE) | VideoInfo::CS_RGB_TYPE;\n  else\n    new_pixel_type = pixel_type;\n\n  return new VideoFrame(vfb, new AVSMap(), offset + rel_offset, new_pitch, new_row_size, new_height,\n    rel_offsetU + offsetU, rel_offsetV + offsetV, new_pitchUV, new_row_sizeUV, new_heightUV,\n    new_pixel_type);\n}\n\n// alpha support\nVideoFrame* VideoFrame::Subframe(int rel_offset, int new_pitch, int new_row_size, int new_height,\n                                 int rel_offsetU, int rel_offsetV, int new_pitchUV,\n                                 int rel_offsetA) const {\n  // Maintain plane size relationship\n  const int new_row_sizeUV = !row_size ? 0 : MulDiv(new_row_size, row_sizeUV, row_size);\n  const int new_heightUV   = !height   ? 0 : MulDiv(new_height,   heightUV,   height);\n\n  return new VideoFrame(vfb, new AVSMap(), offset + rel_offset, new_pitch, new_row_size, new_height,\n    offsetU + rel_offsetU, offsetV + rel_offsetV, new_pitchUV, new_row_sizeUV, new_heightUV,\n    offsetA + rel_offsetA,\n    pixel_type);\n}\n\nVideoFrameBuffer::VideoFrameBuffer() :\n  data(nullptr),\n  data_size(0),\n  sequence_number(0),\n  refcount(1),\n  device(nullptr)\n{ }\n\n\nVideoFrameBuffer::VideoFrameBuffer(int size, int margin, Device* device) :\n  data(device->Allocate(size, margin)),\n  data_size(size),\n  sequence_number(0),\n  refcount(0),\n  device(device)\n{ }\n\nVideoFrameBuffer::~VideoFrameBuffer() { DESTRUCTOR(); }\nvoid VideoFrameBuffer::DESTRUCTOR() {\n  //  _ASSERTE(refcount == 0);\n  InterlockedIncrement(&sequence_number); // HACK: Notify any children with a pointer, this buffer has changed!!!\n  if (data) device->Free(data);\n  data = nullptr; // and mark it invalid!!\n  data_size = 0;   // and don't forget to set the size to 0 as well!\n  device = nullptr; // no longer related to a device\n}\n\n\nclass AtExiter {\n  struct AtExitRec {\n    const IScriptEnvironment::ShutdownFunc func;\n    void* const user_data;\n    AtExitRec* const next;\n    AtExitRec(IScriptEnvironment::ShutdownFunc _func, void* _user_data, AtExitRec* _next)\n      : func(_func), user_data(_user_data), next(_next) {}\n  };\n  AtExitRec* atexit_list;\n\npublic:\n  AtExiter() {\n    atexit_list = 0;\n  }\n\n  void Add(IScriptEnvironment::ShutdownFunc f, void* d) {\n    atexit_list = new AtExitRec(f, d, atexit_list);\n  }\n\n  void Execute(IScriptEnvironment* env) {\n    while (atexit_list) {\n      AtExitRec* next = atexit_list->next;\n      atexit_list->func(atexit_list->user_data, env);\n      delete atexit_list;\n      atexit_list = next;\n    }\n  }\n};\n\n\nstatic std::string NormalizeString(const std::string& str)\n{\n  // lowercase\n  std::string ret = str;\n  for (size_t i = 0; i < ret.size(); ++i)\n    ret[i] = tolower(ret[i]);\n\n  // trim trailing spaces\n  size_t endpos = ret.find_last_not_of(\" \\t\");\n  if (std::string::npos != endpos)\n    ret = ret.substr(0, endpos + 1);\n\n  // trim leading spaces\n  size_t startpos = ret.find_first_not_of(\" \\t\");\n  if (std::string::npos != startpos)\n    ret = ret.substr(startpos);\n\n  return ret;\n}\n\ntypedef enum class _MtWeight\n{\n  MT_WEIGHT_0_DEFAULT,\n  MT_WEIGHT_1_USERSPEC,\n  MT_WEIGHT_2_USERFORCE,\n  MT_WEIGHT_MAX\n} MtWeight;\n\nclass ClipDataStore\n{\npublic:\n\n  // The clip instance that we hold data for.\n  IClip* Clip = nullptr;\n\n  // Clip was created directly by an Invoke() call\n  bool CreatedByInvoke = false;\n\n  ClipDataStore(IClip* clip) : Clip(clip) {};\n};\n\nclass MtModeEvaluator\n{\npublic:\n  int NumChainedNice = 0;\n  int NumChainedMulti = 0;\n  int NumChainedSerial = 0;\n\n  MtMode GetFinalMode(MtMode topInvokeMode)\n  {\n    if (NumChainedSerial > 0)\n    {\n      return MT_SERIALIZED;\n    }\n    else if (NumChainedMulti > 0)\n    {\n      if (MT_SERIALIZED == topInvokeMode)\n      {\n        return MT_SERIALIZED;\n      }\n      else\n      {\n        return MT_MULTI_INSTANCE;\n      }\n    }\n    else\n    {\n      return topInvokeMode;\n    }\n  }\n\n  void Accumulate(const MtModeEvaluator& other)\n  {\n    NumChainedNice += other.NumChainedNice;\n    NumChainedMulti += other.NumChainedMulti;\n    NumChainedSerial += other.NumChainedSerial;\n  }\n\n  void Accumulate(MtMode mode)\n  {\n    switch (mode)\n    {\n    case MT_NICE_FILTER:\n      ++NumChainedNice;\n      break;\n    case MT_MULTI_INSTANCE:\n      ++NumChainedMulti;\n      break;\n    case MT_SERIALIZED:\n      ++NumChainedSerial;\n      break;\n    default:\n      assert(0);\n      break;\n    }\n  }\n\n  static bool ClipSpecifiesMtMode(const PClip& clip)\n  {\n    int val = clip->SetCacheHints(CACHE_GET_MTMODE, 0);\n    return (clip->GetVersion() >= 5) && (val > MT_INVALID) && (val < MT_MODE_COUNT);\n  }\n\n  static MtMode GetInstanceMode(const PClip& clip, MtMode defaultMode)\n  {\n    return ClipSpecifiesMtMode(clip) ? (MtMode)clip->SetCacheHints(CACHE_GET_MTMODE, 0) : defaultMode;\n  }\n\n  static MtMode GetInstanceMode(const PClip& clip)\n  {\n    return (MtMode)clip->SetCacheHints(CACHE_GET_MTMODE, 0);\n  }\n\n  static MtMode GetMtMode(const PClip& clip, const Function* invokeCall, const InternalEnvironment* env)\n  {\n    bool invokeModeForced;\n\n    MtMode invokeMode = env->GetFilterMTMode(invokeCall, &invokeModeForced);\n    if (invokeModeForced) {\n      return invokeMode;\n    }\n\n    bool hasInstanceMode = ClipSpecifiesMtMode(clip);\n    if (hasInstanceMode) {\n      return GetInstanceMode(clip);\n    }\n    else {\n      return invokeMode;\n    }\n  }\n\n  static bool UsesDefaultMtMode(const PClip& clip, const Function* invokeCall, const InternalEnvironment* env)\n  {\n    return !ClipSpecifiesMtMode(clip) && !env->FilterHasMtMode(invokeCall);\n  }\n\n  void AddChainedFilter(const PClip& clip, MtMode defaultMode)\n  {\n    MtMode mode = GetInstanceMode(clip, defaultMode);\n    Accumulate(mode);\n  }\n};\n\n\nOneTimeLogTicket::OneTimeLogTicket(ELogTicketType type)\n  : _type(type)\n{}\n\nOneTimeLogTicket::OneTimeLogTicket(ELogTicketType type, const Function* func)\n  : _type(type), _function(func)\n{}\n\nOneTimeLogTicket::OneTimeLogTicket(ELogTicketType type, const std::string& str)\n  : _type(type), _string(str)\n{}\n\nbool OneTimeLogTicket::operator==(const OneTimeLogTicket& other) const\n{\n  return (_type == other._type)\n    && (_function == other._function)\n    && (_string.compare(other._string) == 0);\n}\n\nnamespace std\n{\n  template <>\n  struct hash<OneTimeLogTicket>\n  {\n    std::size_t operator()(const OneTimeLogTicket& k) const\n    {\n      // TODO: This is a pretty poor combination function for hashes.\n      // Find something better than a simple XOR.\n      return hash<int>()(k._type)\n        ^ hash<void*>()((void*)k._function)\n        ^ hash<std::string>()((std::string)k._string);\n    }\n  };\n}\n\n#include \"vartable.h\"\n#include \"ThreadPool.h\"\n#include <map>\n#include <unordered_set>\n#include <atomic>\n#include <stack>\n#include \"Prefetcher.h\"\n#include \"BufferPool.h\"\n#include \"ScriptEnvironmentTLS.h\"\n\nclass ThreadScriptEnvironment;\n\n// order is not important, unlike in IScriptEnvironment variants.\nclass ScriptEnvironment {\npublic:\n  ScriptEnvironment();\n  void CheckVersion(int version);\n  int GetCPUFlags();\n  int64_t GetCPUFlagsEx();\n  void AddFunction(const char* name, const char* params, INeoEnv::ApplyFunc apply, void* user_data = 0);\n  void AddFunction25(const char* name, const char* params, INeoEnv::ApplyFunc apply, void* user_data = 0);\n  void AddFunctionPreV11C(const char* name, const char* params, INeoEnv::ApplyFunc apply, void* user_data = 0);\n  bool FunctionExists(const char* name);\n  PVideoFrame NewVideoFrameOnDevice(const VideoInfo& vi, int align, Device* device);\n  PVideoFrame NewVideoFrameOnDevice(int row_size, int height, int align, int pixel_type, Device* device);\n  PVideoFrame NewVideoFrame(const VideoInfo& vi, const PDevice& device);\n  // variant #3, with frame property source\n  PVideoFrame NewVideoFrameOnDevice(const VideoInfo& vi, int align, Device* device, const PVideoFrame *prop_src);\n  // variant #1, with frame property source\n  PVideoFrame NewVideoFrameOnDevice(int row_size, int height, int align, int pixel_type, Device* device, const PVideoFrame* prop_src);\n  // variant #2, with frame property source\n  PVideoFrame NewVideoFrame(const VideoInfo& vi, const PDevice& device, const PVideoFrame* prop_src);\n\n  PVideoFrame NewPlanarVideoFrame(int row_size, int height, int row_sizeUV, int heightUV, int align, bool U_first, int pixel_type, Device* device);\n\n  bool MakeWritable(PVideoFrame* pvf);\n  void BitBlt(BYTE* dstp, int dst_pitch, const BYTE* srcp, int src_pitch, int row_size, int height);\n  void AtExit(IScriptEnvironment::ShutdownFunc function, void* user_data);\n  PVideoFrame Subframe(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height);\n  int SetMemoryMax(int mem);\n  int SetWorkingDir(const char* newdir);\n  bool AcquireGlobalLock(const char* name);\n  void ReleaseGlobalLock(const char* name);\n  AVSC_CC ~ScriptEnvironment();\n  void* ManageCache(int key, void* data);\n  bool PlanarChromaAlignment(IScriptEnvironment::PlanarChromaAlignmentMode key);\n  PVideoFrame SubframePlanar(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV);\n  void DeleteScriptEnvironment();\n  void ApplyMessage(PVideoFrame* frame, const VideoInfo& vi, const char* message, int size, int textcolor, int halocolor, int bgcolor);\n  void ApplyMessageEx(PVideoFrame* frame, const VideoInfo& vi, const char* message, int size, int textcolor, int halocolor, int bgcolor, bool utf8);\n  const AVS_Linkage* GetAVSLinkage();\n\n  // alpha support\n  PVideoFrame NewPlanarVideoFrame(int row_size, int height, int row_sizeUV, int heightUV, int align, bool U_first, bool alpha, int pixel_type, Device* device);\n  PVideoFrame SubframePlanar(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV, int rel_offsetA);\n  PVideoFrame SubframePlanarA(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV, int rel_offsetA);\n\n  void copyFrameProps(const PVideoFrame& src, PVideoFrame& dst);\n  const AVSMap* getFramePropsRO(const PVideoFrame& frame) AVS_NOEXCEPT;\n  AVSMap* getFramePropsRW(PVideoFrame& frame) AVS_NOEXCEPT;\n  int propNumKeys(const AVSMap* map) AVS_NOEXCEPT;\n  const char* propGetKey(const AVSMap* map, int index) AVS_NOEXCEPT;\n  int propNumElements(const AVSMap* map, const char* key) AVS_NOEXCEPT;\n  char propGetType(const AVSMap* map, const char* key) AVS_NOEXCEPT;\n  int propDeleteKey(AVSMap* map, const char* key) AVS_NOEXCEPT;\n  int64_t propGetInt(const AVSMap* map, const char* key, int index, int* error) AVS_NOEXCEPT;\n  int propGetIntSaturated(const AVSMap* map, const char* key, int index, int* error) AVS_NOEXCEPT;\n  double propGetFloat(const AVSMap* map, const char* key, int index, int* error) AVS_NOEXCEPT;\n  float propGetFloatSaturated(const AVSMap* map, const char* key, int index, int* error) AVS_NOEXCEPT;\n  const char* propGetData(const AVSMap* map, const char* key, int index, int* error) AVS_NOEXCEPT;\n  int propGetDataSize(const AVSMap* map, const char* key, int index, int* error) AVS_NOEXCEPT;\n  int propGetDataTypeHint(const AVSMap* map, const char* key, int index, int* error) AVS_NOEXCEPT;\n  PClip propGetClip(const AVSMap* map, const char* key, int index, int* error) AVS_NOEXCEPT;\n  const PVideoFrame propGetFrame(const AVSMap* map, const char* key, int index, int* error) AVS_NOEXCEPT;\n  int propSetInt(AVSMap* map, const char* key, int64_t i, int append) AVS_NOEXCEPT;\n  int propSetFloat(AVSMap* map, const char* key, double d, int append) AVS_NOEXCEPT;\n  int propSetData(AVSMap* map, const char* key, const char* d, int length, int append) AVS_NOEXCEPT;\n  int propSetDataH(AVSMap* map, const char* key, const char* d, int length, int type, int append) AVS_NOEXCEPT;\n  int propSetClip(AVSMap* map, const char* key, PClip& clip, int append) AVS_NOEXCEPT;\n  int propSetFrame(AVSMap* map, const char* key, const PVideoFrame& frame, int append) AVS_NOEXCEPT;\n\n  const int64_t* propGetIntArray(const AVSMap* map, const char* key, int* error) AVS_NOEXCEPT;\n  const double* propGetFloatArray(const AVSMap* map, const char* key, int* error) AVS_NOEXCEPT;\n  int propSetIntArray(AVSMap* map, const char* key, const int64_t* i, int size) AVS_NOEXCEPT;\n  int propSetFloatArray(AVSMap* map, const char* key, const double* d, int size) AVS_NOEXCEPT;\n\n  AVSMap* createMap() AVS_NOEXCEPT;\n  void freeMap(AVSMap* map) AVS_NOEXCEPT;\n  void clearMap(AVSMap* map) AVS_NOEXCEPT;\n  \n  PVideoFrame NewVideoFrame(const VideoInfo& vi, const PVideoFrame* prop_src, int align = FRAME_ALIGN);\n\n  bool MakePropertyWritable(PVideoFrame* pvf); // V9\n\n  /* IScriptEnvironment2 */\n  bool LoadPlugin(const char* filePath, bool throwOnError, AVSValue *result);\n  void AddAutoloadDir(const char* dirPath, bool toFront);\n  void ClearAutoloadDirs();\n  void AutoloadPlugins();\n  void AddFunction(const char* name, const char* params, INeoEnv::ApplyFunc apply, void* user_data, const char *exportVar);\n  bool InternalFunctionExists(const char* name);\n  void AdjustMemoryConsumption(size_t amount, bool minus);\n  void SetFilterMTMode(const char* filter, MtMode mode, bool force);\n  void SetFilterMTMode(const char* filter, MtMode mode, MtWeight weight);\n  void SetFilterProp(const char* filter, const char* key, const AVSValue& value, int mode);\n  void SetFilterPropConditional(const char* filter, const char* param_name, const AVSValue& param_match,\n                                const char* key, const AVSValue& value, int mode);\n  const char* GetFilterProps();\n  void SetFilterPropPassthrough(const char* filter);\n  MtMode GetFilterMTMode(const Function* filter, bool* is_forced) const;\n  void ParallelJob(ThreadWorkerFuncPtr jobFunc, void* jobData, IJobCompletion* completion);\n  IJobCompletion* NewCompletion(size_t capacity);\n  size_t  GetEnvProperty(AvsEnvProperty prop);\n  ClipDataStore* ClipData(IClip* clip);\n  MtMode GetDefaultMtMode() const;\n  bool FilterHasMtMode(const Function* filter) const;\n  void SetLogParams(const char* target, int level);\n  void LogMsg(int level, const char* fmt, ...);\n  void LogMsg_valist(int level, const char* fmt, va_list va);\n  void LogMsgOnce(const OneTimeLogTicket& ticket, int level, const char* fmt, ...);\n  void LogMsgOnce_valist(const OneTimeLogTicket& ticket, int level, const char* fmt, va_list va);\n\n  void SetMaxCPU(const char *features); // fixme: why is here InternalEnvironment?\n\n  /* INeoEnv */\n  bool Invoke_(AVSValue *result, const AVSValue& implicit_last,\n    const char* name, const Function *f, const AVSValue& args, const char* const* arg_names,\n    InternalEnvironment* env_thread, bool is_runtime);\n\n  PDevice GetDevice(AvsDeviceType device_type, int device_index) const;\n  int SetMemoryMax(AvsDeviceType type, int index, int mem);\n\n  PVideoFrame GetOnDeviceFrame(const PVideoFrame& src, Device* device);\n  void ParallelJob(ThreadWorkerFuncPtr jobFunc, void* jobData, IJobCompletion* completion, InternalEnvironment *env);\n  ThreadPool* NewThreadPool(size_t nThreads);\n  void SetGraphAnalysis(bool enable) { graphAnalysisEnable = enable; }\n\n  char* ListAutoloadDirs();\n\n  void IncEnvCount() { InterlockedIncrement(&EnvCount); }\n  void DecEnvCount() { InterlockedDecrement(&EnvCount); }\n\n  ConcurrentVarStringFrame* GetTopFrame() { return &top_frame; }\n  void SetCacheMode(CacheMode mode) { cacheMode = mode; }\n  CacheMode GetCacheMode() { return cacheMode; }\n  void SetDeviceOpt(DeviceOpt opt, int val);\n  size_t GetInvokeStackSize() { return invoke_stack.size(); }\n\n  void UpdateFunctionExports(const char* funcName, const char* funcParams, const char* exportVar);\n\n  // public, AVSMap error should access\n  void ThrowError(const char* fmt, ...);\n\n  ThreadScriptEnvironment* GetMainThreadEnv() { return threadEnv.get(); }\n\n  class VFBStorage : public VideoFrameBuffer {\n  public:\n    std::atomic<int64_t> last_freed_timestamp;\n    int free_count;\n    int margin;\n    PGraphMemoryNode memory_node;\n\n    // Helper to update VFB timestamp from external code\n    static void UpdateVFBFreeTimestamp(VideoFrameBuffer* vfb) {\n      static std::atomic<int64_t> global_free_counter{ 0 };\n      static_cast<VFBStorage*>(vfb)->last_freed_timestamp = ++global_free_counter;\n    }\n\n    VFBStorage()\n      : VideoFrameBuffer(),\n      free_count(0),\n      margin(0)\n    {\n    }\n\n    VFBStorage(int size, int margin, Device* device)\n      : VideoFrameBuffer(size, margin, device),\n      free_count(0),\n      margin(margin)\n    {\n    }\n\n    void Attach(FilterGraphNode* node) {\n      if (memory_node) {\n        memory_node->OnFree(data_size, device);\n        memory_node = nullptr;\n      }\n      if (node != nullptr) {\n        memory_node = node->GetMemoryNode();\n        memory_node->OnAllocate(data_size, device);\n      }\n    }\n\n    ~VFBStorage() {\n      if (memory_node) {\n        memory_node->OnFree(data_size, device);\n        memory_node = nullptr;\n      }\n#ifdef _DEBUG\n      if (data && (device->device_type == DEV_TYPE_CPU)) {\n        // check buffer overrun\n        int* pInt = (int*)(data + margin + data_size);\n        if (pInt[0] != 0xDEADBEEF ||\n          pInt[1] != 0xDEADBEEF ||\n          pInt[2] != 0xDEADBEEF ||\n          pInt[3] != 0xDEADBEEF)\n        {\n          printf(\"Buffer overrun!!!\\n\");\n        }\n      }\n#endif\n    }\n  };\n\nprivate:\n  typedef IScriptEnvironment::NotFound NotFound;\n  typedef IScriptEnvironment::ApplyFunc ApplyFunc;\n\n  // Tritical May 2005\n  // Note order here!!\n  // AtExiter has functions which\n  // rely on StringDump elements.\n  ConcurrentVarStringFrame top_frame;\n  std::unique_ptr<ThreadScriptEnvironment> threadEnv;\n  std::mutex string_mutex;\n\n  AtExiter at_exit;\n  ThreadPool* thread_pool;\n\n  PluginManager* plugin_manager;\n  std::recursive_mutex plugin_mutex;\n\n  long EnvCount; // for ThreadScriptEnvironment leak detection\n\n  void VThrowError(const char* fmt, va_list va);\n\n  const Function* Lookup(const char* search_name, const AVSValue* args, size_t num_args,\n    bool &pstrict, size_t args_names_count, const char* const* arg_names, IScriptEnvironment2* env_thread);\n  bool CheckArguments(const Function* f, const AVSValue* args, size_t num_args,\n    bool &pstrict, size_t args_names_count, const char* const* arg_names);\n  std::unordered_map<IClip*, ClipDataStore> clip_data;\n\n  void ExportBuiltinFilters();\n\n  bool PlanarChromaAlignmentState;\n\n  long hrfromcoinit;\n  uint32_t coinitThreadId;\n\n  struct DebugTimestampedFrame\n  {\n    VideoFrame* frame;\n\n#ifdef _DEBUG\n    std::chrono::time_point<std::chrono::high_resolution_clock> timestamp;\n#endif\n\n    DebugTimestampedFrame(VideoFrame* _frame)\n      : frame(_frame)\n#ifdef _DEBUG\n      , timestamp(std::chrono::high_resolution_clock::now())\n#endif\n    {}\n  };\n\n  typedef std::vector<DebugTimestampedFrame> VideoFrameArrayType;\n  typedef std::map<VideoFrameBuffer *, VideoFrameArrayType> FrameBufferRegistryType;\n  typedef std::map<size_t, FrameBufferRegistryType> FrameRegistryType2; // post r1825 P.F.\n  typedef mapped_list<AvsCache*> CacheRegistryType;\n\n\n  FrameRegistryType2 FrameRegistry2; // P.F.\n#ifdef _DEBUG\n  void ListFrameRegistry(size_t min_size, size_t max_size, bool someframes);\n#endif\n\n  std::unique_ptr<DeviceManager> Devices;\n  CacheRegistryType CacheRegistry;\n  AvsCache* FrontCache;\n  VideoFrame* GetNewFrame(size_t vfb_size, size_t margin, Device* device);\n  VideoFrame* GetFrameFromRegistry(size_t vfb_size, Device* device);\n  void RegisterSubFrameInRegistry(size_t vfb_size, VideoFrameBuffer* vfb, VideoFrame* new_frame);\n  void ShrinkCache(Device* device);\n  VideoFrame* AllocateFrame(size_t vfb_size, size_t margin, Device* device);\n  std::recursive_mutex memory_mutex;\n  std::recursive_mutex invoke_mutex; // 3.7.2\n  // 3.7.2: \n  // Distinct invoke mutex from memory_mutex because a background GetFrame and Invoke would deadlock\n  // when called specially by AvsPMod: Eval, then the resulting clip variable is ConvertToRGB32'd\n  // by using Invoke.\n  // \n  // GetFrame can require accessing FrameRegistry (NewVideoFrame).\n  // When an Clip is obtained from Eval which script has e.g. Prefetch(2) at the end then it runs \n  // worker threads in the background, doing GetFrame calls.\n  // When this AVS Clip is further ConvertToYUV444'd (using Invoke) it calles GetFrame(0) in its\n  // constructor for getting frame properties and prepare the filter upon them. (this is not a real\n  // frame property but rather a clip property which is the same for all frames, we are using frame#0 for\n  // frame property source.\n  // \n  // Two things are running parallel: \n  // - a GetFrame from Invoke which holds a memory_mutex, then locks a MT_SERIALIZED mutex.\n  // - a GetFrame from the prefetcher of the already Eval'd Clip which first holds a\n  //   MT_SERIALIZED mutex then may lock a memory_mutex.\n  // Finally they deadlock on the source filter's ChildFilter MT guard (MtGuard::GetFrame, MT_SERIALIZED).\n  // Serialized access from prefetch \n  // - gets a ChildFilter mutex, calls GetFrame which would require memory_mutex (NewVideoFrame).\n  // Serialized access from Invoke \n  // - _Invoke locks the memory_mutex, then would obtain ChildFilter mutex.\n  // \n  // Under specific timing conditions which surely happens in tenth of seconds we get deadlock.\n  //\n  // Solution: a new invoke_mutex is introduced besides memory_mutex.\n  // Other sub-tasks are already guarded with other mutexes: e.g. plugin_mutex, string_mutex.\n  // Note: An earlier attempt to avoid this problem was introducing\n  //   int ScriptEnvironment::suppressThreadCount; (GetSuppressThreadCount)\n  //   \"Concurrent GetFrame with Invoke causes deadlock.\n  //   Increment this variable when Invoke running\n  //   to prevent submitting job to threadpool\"\n  // But this cannot handle the above mentioned case, because by that time threadpool is already working.\n\n  int frame_align;\n  int plane_align;\n\n  //BufferPool BufferPool;\n\n  typedef std::vector<MTGuard*> MTGuardRegistryType;\n  MTGuardRegistryType MTGuardRegistry;\n\n  std::vector <std::unique_ptr<ThreadPool>> ThreadPoolRegistry;\n  size_t nTotalThreads;\n  size_t nMaxFilterInstances;\n\n  // Members used to reconstruct Association between Invoke() calls and filter instances\n  std::stack<MtModeEvaluator*> invoke_stack;\n\n  // MT mode specifications\n  std::unordered_map<std::string, std::pair<MtMode, MtWeight>> MtMap;\n  MtMode DefaultMtMode = MtMode::MT_MULTI_INSTANCE;\n  static const std::string DEFAULT_MODE_SPECIFIER;\n\n  // Auto filter-property injection\n  struct PropEntry {\n    std::string key;         // frame property key to inject\n    AVSValue value;          // int, float, string, function, or undefined (capture from named arg)\n    int mode;                // AVSPropAppendMode\n    std::string param_name;  // if non-empty: only inject when named call arg 'param_name' == param_match\n    AVSValue param_match;    // the value to compare against (only used when param_name is non-empty)\n  };\n  std::unordered_map<std::string, std::vector<PropEntry>> FilterPropMap;\n  std::unordered_set<std::string> FilterPropPassthroughSet; // filters that need input-prop forwarding\n\n  // Logging-related members\n  int LogLevel;\n  std::string LogTarget;\n  std::ofstream LogFileStream;\n  std::unordered_set<OneTimeLogTicket> LogTickets;\n\n  // filter graph\n  bool graphAnalysisEnable;\n\n  typedef std::vector<FilterGraphNode*> GraphNodeRegistryType;\n  GraphNodeRegistryType GraphNodeRegistry;\n\n  CacheMode cacheMode;\n\n  int64_t cpuFlagsEx; // extended 64 bits CPU flags\n  size_t cache_size_L2;\n\n  void InitMT();\n};\n\n#ifdef ALTERNATIVE_VFB_TIMESTAMP\n// wrapper for VideoFrameBuffer destroy\nnamespace VFBHelper {\n  void UpdateVFBFreeTimestamp(VideoFrameBuffer* vfb) {\n    ScriptEnvironment::VFBStorage::UpdateVFBFreeTimestamp(vfb);\n  }\n}\n#endif\n\nconst std::string ScriptEnvironment::DEFAULT_MODE_SPECIFIER = \"DEFAULT_MT_MODE\";\n\n// Only ThrowError and Sprintf is implemented(Used by destructor)\nclass MinimumScriptEnvironment : public IScriptEnvironment {\n  VarTable var_table;\npublic:\n  MinimumScriptEnvironment(ConcurrentVarStringFrame* top_frame) : var_table(top_frame) { }\n  virtual ~MinimumScriptEnvironment() {}\n  virtual int __stdcall GetCPUFlags() {\n    throw AvisynthError(\"Not Implemented\");\n  }\n  virtual char* __stdcall SaveString(const char* s, int length = -1) {\n    return var_table.SaveString(s, length);\n  }\n  virtual char* Sprintf(const char* fmt, ...) {\n    va_list val;\n    va_start(val, fmt);\n    char* result = VSprintf(fmt, val);\n    va_end(val);\n    return result;\n  }\n  virtual char* __stdcall VSprintf(const char* fmt, va_list val) {\n    try {\n      std::string str = FormatString(fmt, val);\n      return var_table.SaveString(str.c_str(), int(str.size())); // SaveString will add the NULL in len mode.\n    }\n    catch (...) {\n      return NULL;\n    }\n  }\n  __declspec(noreturn) virtual void ThrowError(const char* fmt, ...) {\n    va_list val;\n    va_start(val, fmt);\n    VThrowError(fmt, val);\n    va_end(val);\n    // Compiler doesn't recognize that the function would not return.\n    // With this line we are satisfying the noreturn attribute.\n    // Anyway, this is unreachable code.\n    std::terminate();\n  }\n  void __stdcall VThrowError(const char* fmt, va_list va)\n  {\n    std::string msg;\n    try {\n      msg = FormatString(fmt, va);\n    }\n    catch (...) {\n      msg = \"Exception while processing ScriptEnvironment::ThrowError().\";\n    }\n    // Throw...\n    throw AvisynthError(var_table.SaveString(msg.c_str()));\n  }\n  virtual void __stdcall AddFunction(const char* name, const char* params, ApplyFunc apply, void* user_data) {\n    throw AvisynthError(\"Not Implemented\");\n  }\n  virtual bool __stdcall FunctionExists(const char* name) {\n    throw AvisynthError(\"Not Implemented\");\n  }\n  virtual AVSValue __stdcall Invoke(const char* name, const AVSValue args, const char* const* arg_names = 0) {\n    throw AvisynthError(\"Not Implemented\");\n  }\n  virtual AVSValue __stdcall GetVar(const char* name) {\n    throw AvisynthError(\"Not Implemented\");\n  }\n  virtual bool __stdcall SetVar(const char* name, const AVSValue& val) {\n    throw AvisynthError(\"Not Implemented\");\n  }\n  virtual bool __stdcall SetGlobalVar(const char* name, const AVSValue& val) {\n    throw AvisynthError(\"Not Implemented\");\n  }\n  virtual void __stdcall PushContext(int level = 0) {\n    throw AvisynthError(\"Not Implemented\");\n  }\n  virtual void __stdcall PopContext() {\n    throw AvisynthError(\"Not Implemented\");\n  }\n  virtual PVideoFrame __stdcall NewVideoFrame(const VideoInfo& vi, int align = FRAME_ALIGN) {\n    throw AvisynthError(\"Not Implemented\");\n  }\n  virtual bool __stdcall MakeWritable(PVideoFrame* pvf) {\n    throw AvisynthError(\"Not Implemented\");\n  }\n  virtual void __stdcall BitBlt(BYTE* dstp, int dst_pitch, const BYTE* srcp, int src_pitch, int row_size, int height) {\n    throw AvisynthError(\"Not Implemented\");\n  }\n  virtual void __stdcall AtExit(ShutdownFunc function, void* user_data) {\n    throw AvisynthError(\"Not Implemented\");\n  }\n  virtual void __stdcall CheckVersion(int version = AVISYNTH_INTERFACE_VERSION) {\n    throw AvisynthError(\"Not Implemented\");\n  }\n  virtual PVideoFrame __stdcall Subframe(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height) {\n    throw AvisynthError(\"Not Implemented\");\n  }\n  virtual int __stdcall SetMemoryMax(int mem) {\n    throw AvisynthError(\"Not Implemented\");\n  }\n  virtual int __stdcall SetWorkingDir(const char * newdir) {\n    throw AvisynthError(\"Not Implemented\");\n  }\n  virtual void* __stdcall ManageCache(int key, void* data) {\n    throw AvisynthError(\"Not Implemented\");\n  }\n  virtual bool __stdcall PlanarChromaAlignment(PlanarChromaAlignmentMode key) {\n    throw AvisynthError(\"Not Implemented\");\n  }\n  virtual PVideoFrame __stdcall SubframePlanar(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size,\n    int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV) {\n    throw AvisynthError(\"Not Implemented\");\n  }\n  virtual void __stdcall DeleteScriptEnvironment() {\n    throw AvisynthError(\"Not Implemented\");\n  }\n  virtual void __stdcall ApplyMessage(PVideoFrame* frame, const VideoInfo& vi, const char* message, int size,\n    int textcolor, int halocolor, int bgcolor) {\n    throw AvisynthError(\"Not Implemented\");\n  }\n  virtual const AVS_Linkage* __stdcall GetAVSLinkage() {\n    throw AvisynthError(\"Not Implemented\");\n  }\n  virtual AVSValue __stdcall GetVarDef(const char* name, const AVSValue& def = AVSValue()) {\n    throw AvisynthError(\"Not Implemented\");\n  }\n};\n\n/* ---------------------------------------------------------------------------------\n*  Interface transformation hack\n* ---------------------------------------------------------------------------------\n*/\nInternalEnvironment* GetAndRevealCamouflagedEnv(IScriptEnvironment* env) {\n  InternalEnvironment* IEnv;\n\n  // This function is called from CacheGuard::GetFrame/GetAudio, Prefetcher::GetFrame/GetAudio,\n  // ScriptClip::GetFrame, ConditionalFilter::GetFrame, and other runtime filters.\n  // When GetFrame is called from an AviSynth C++ 2.5 or PreV11C plugin constructor (xx_Create),\n  // or such a plugin is inside a runtime function, then\n  // 'env' is a disguised IScriptEnvironment_Avs25/AvsPreV11C, which we cannot\n  // static_cast to InternalEnvironment directly.\n  // We need to determine whether the environment is v2.5/PreV11C and act accordingly.\n\n  if (env->ManageCache((int)MC_QueryAvs25, nullptr) == (intptr_t*)1) {\n    IEnv = static_cast<InternalEnvironment*>(reinterpret_cast<IScriptEnvironment_Avs25*>(env));\n  }\n  else if (env->ManageCache((int)MC_QueryAvsPreV11C, nullptr) == (intptr_t*)1) {\n    IEnv = static_cast<InternalEnvironment*>(reinterpret_cast<IScriptEnvironment_AvsPreV11C*>(env));\n  }\n  else {\n    IEnv = static_cast<InternalEnvironment*>(env);\n  }\n  return IEnv;\n}\n\n/* ---------------------------------------------------------------------------------\n*  Per thread data\n* ---------------------------------------------------------------------------------\n*/\nstruct ScriptEnvironmentTLS\n{\n  const int thread_id;\n  // PF 161223 why do we need thread-local global variables?\n  // comment remains here until it gets cleared, anyway, I make it of no use\n  VarTable var_table;\n  BufferPool buffer_pool;\n  Device* currentDevice;\n  bool closing;                 // Used to avoid deadlock, if vartable is being accessed while shutting down (Popcontext)\n  bool supressCaching;\n  int ImportDepth;\n  int getFrameRecursiveCount;\n\n  // Concurrent GetFrame with Invoke causes deadlock.\n  // Increment this variable when Invoke running\n  // to prevent submitting job to threadpool\n  int suppressThreadCount;\n\n  FilterGraphNode* currentGraphNode;\n  volatile long refcount;\n\n  ScriptEnvironmentTLS(int thread_id, InternalEnvironment* core)\n    : thread_id(thread_id)\n    , var_table(core->GetTopFrame())\n    , buffer_pool(core)\n    , currentDevice(NULL)\n    , closing(false)\n    , supressCaching(false)\n    , ImportDepth(0)\n    , getFrameRecursiveCount(0)\n    , suppressThreadCount(0)\n    , currentGraphNode(nullptr)\n    , refcount(1)\n  {\n  }\n};\n\n// per thread data is bound to a thread (not ThreadScriptEnvironment)\n// since some filter (e.g. svpflow1) ignores env given for GetFrame, and always use main thread's env.\n// this is a work-around for that.\n#if defined(AVS_WINDOWS) && !defined(__GNUC__)\n#  ifdef XP_TLS\nextern DWORD dwTlsIndex;\n#  else\n// does not work on XP when DLL is dynamic loaded. see dwTlsIndex instead\n__declspec(thread) ScriptEnvironmentTLS* g_TLS = nullptr;\n#  endif\n#else\n__thread ScriptEnvironmentTLS* g_TLS = nullptr;\n#endif\n\nclass ThreadScriptEnvironment : public InternalEnvironment\n{\n  ScriptEnvironment* core;\n  ScriptEnvironmentTLS* coreTLS;\n  ScriptEnvironmentTLS myTLS;\npublic:\n\n  ThreadScriptEnvironment(int thread_id, ScriptEnvironment* core, ScriptEnvironmentTLS* coreTLS)\n    : core(core)\n    , coreTLS(coreTLS)\n    , myTLS(thread_id, this)\n  {\n    if (coreTLS == nullptr) {\n      // when this is main thread TLS\n      this->coreTLS = &myTLS;\n    }\n    if (thread_id != 0) {\n      // thread pool thread\n#ifdef XP_TLS\n      ScriptEnvironmentTLS* g_TLS = (ScriptEnvironmentTLS*)(TlsGetValue(dwTlsIndex));\n#endif\n      if (g_TLS != nullptr) {\n        ThrowError(\"Detected multiple ScriptEnvironmentTLSs for a single thread\");\n      }\n      g_TLS = &myTLS;\n#ifdef XP_TLS\n      if (!TlsSetValue(dwTlsIndex, g_TLS)) {\n        ThrowError(\"Could not store thread local value for ScriptEnvironmentTLS\");\n      }\n#endif\n    }\n    core->IncEnvCount(); // for leak detection\n  }\n\n  ~ThreadScriptEnvironment() {\n    core->DecEnvCount(); // for leak detection\n  }\n\n  ScriptEnvironmentTLS* GetTLS() { return &myTLS; }\n\n#ifdef XP_TLS\n  // a ? : b, evaluate 'a' only once\n#define IFNULL(a, b) ([&](){ auto val = (a); return ((val) == nullptr ? (b) : (val)); }())\n#define DISPATCH(name) IFNULL((ScriptEnvironmentTLS*)(TlsGetValue(dwTlsIndex)), coreTLS)->name\n#else\n#define DISPATCH(name) (g_TLS ? g_TLS : coreTLS)->name\n#endif\n\n\n  AVSValue __stdcall GetVar(const char* name)\n  {\n    if (DISPATCH(closing)) return AVSValue();  // We easily risk  being inside the critical section below, while deleting variables.\n    AVSValue val;\n    if (DISPATCH(var_table).Get(name, &val))\n      return val;\n    else\n      throw IScriptEnvironment::NotFound();\n  }\n\n  bool __stdcall SetVar(const char* name, const AVSValue& val)\n  {\n    if (DISPATCH(closing)) return true;  // We easily risk  being inside the critical section below, while deleting variables.\n    return DISPATCH(var_table).Set(name, val);\n  }\n\n  bool __stdcall SetGlobalVar(const char* name, const AVSValue& val)\n  {\n    if (DISPATCH(closing)) return true;  // We easily risk  being inside the critical section below, while deleting variables.\n    return DISPATCH(var_table).SetGlobal(name, val);\n  }\n\n  void __stdcall PushContext(int level = 0)\n  {\n    DISPATCH(var_table).Push();\n  }\n\n  void __stdcall PopContext()\n  {\n    DISPATCH(var_table).Pop();\n  }\n\n  void __stdcall PushContextGlobal()\n  {\n    DISPATCH(var_table).PushGlobal();\n  }\n\n  void __stdcall PopContextGlobal()\n  {\n    DISPATCH(var_table).PopGlobal();\n  }\n\n  bool __stdcall GetVarTry(const char* name, AVSValue* val) const\n  {\n    if (DISPATCH(closing)) return false;  // We easily risk  being inside the critical section below, while deleting variables.\n    return DISPATCH(var_table).Get(name, val);\n  }\n\n  AVSValue __stdcall GetVarDef(const char* name, const AVSValue& def)\n  {\n    if (DISPATCH(closing)) return def;  // We easily risk  being inside the critical section below, while deleting variables.\n    AVSValue val;\n    if (this->GetVarTry(name, &val))\n      return val;\n    else\n      return def;\n  }\n\n  bool __stdcall GetVarBool(const char* name, bool def) const\n  {\n    if (DISPATCH(closing)) return false;  // We easily risk  being inside the critical section below, while deleting variables.\n    AVSValue val;\n    if (this->GetVarTry(name, &val))\n      return val.AsBool(def);\n    else\n      return def;\n  }\n\n  int __stdcall GetVarInt(const char* name, int def) const\n  {\n    if (DISPATCH(closing)) return def;  // We easily risk  being inside the critical section below, while deleting variables.\n    AVSValue val;\n    if (this->GetVarTry(name, &val))\n      return val.AsInt(def);\n    else\n      return def;\n  }\n\n  double __stdcall GetVarDouble(const char* name, double def) const\n  {\n    if (DISPATCH(closing)) return def;  // We easily risk  being inside the critical section below, while deleting variables.\n    AVSValue val;\n    if (this->GetVarTry(name, &val))\n      return val.AsDblDef(def);\n    else\n      return def;\n  }\n\n  const char* __stdcall GetVarString(const char* name, const char* def) const\n  {\n    if (DISPATCH(closing)) return def;  // We easily risk  being inside the critical section below, while deleting variables.\n    AVSValue val;\n    if (this->GetVarTry(name, &val))\n      return val.AsString(def);\n    else\n      return def;\n  }\n\n#ifdef _MSC_VER\n#pragma warning(push)\n#pragma warning(disable: 4244) // conversion from __int64, possible loss of data\n#endif\n  int64_t __stdcall GetVarLong(const char* name, int64_t def) const\n  {\n    if (DISPATCH(closing)) return def;  // We easily risk  being inside the critical section below, while deleting variables.\n    AVSValue val;\n    if (this->GetVarTry(name, &val))\n      return val.AsLong(def); // v11: real int64 support\n    else\n      return def;\n  }\n#ifdef _MSC_VER\n#pragma warning(pop)\n#endif\n\n  void* __stdcall Allocate(size_t nBytes, size_t alignment, AvsAllocType type)\n  {\n    if ((type != AVS_NORMAL_ALLOC) && (type != AVS_POOLED_ALLOC))\n      return NULL;\n    return DISPATCH(buffer_pool).Allocate(nBytes, alignment, type == AVS_POOLED_ALLOC);\n  }\n\n  void __stdcall Free(void* ptr)\n  {\n    DISPATCH(buffer_pool).Free(ptr);\n  }\n\n  Device* __stdcall GetCurrentDevice() const\n  {\n    return DISPATCH(currentDevice);\n  }\n\n  Device* __stdcall SetCurrentDevice(Device* device)\n  {\n    Device* old = DISPATCH(currentDevice);\n    DISPATCH(currentDevice) = device;\n    return old;\n  }\n\n  PVideoFrame __stdcall NewVideoFrame(const VideoInfo& vi, int align)\n  {\n    return core->NewVideoFrameOnDevice(vi, align, DISPATCH(currentDevice));\n  }\n\n  PVideoFrame __stdcall NewVideoFrameP(const VideoInfo& vi, const PVideoFrame *prop_src, int align)\n  {\n    return core->NewVideoFrameOnDevice(vi, align, DISPATCH(currentDevice), prop_src);\n  }\n    \n  void* __stdcall GetDeviceStream()\n  {\n    return DISPATCH(currentDevice)->GetComputeStream();\n  }\n\n  void __stdcall DeviceAddCallback(void(*cb)(void*), void* user_data)\n  {\n    DeviceCompleteCallbackData cbdata = { cb, user_data };\n    DISPATCH(currentDevice)->AddCompleteCallback(cbdata);\n  }\n\n  PVideoFrame __stdcall GetFrame(PClip c, int n, const PDevice& device)\n  {\n    DeviceSetter setter(this, (Device*)(void*)device);\n    return c->GetFrame(n, this);\n  }\n\n\n  /* ---------------------------------------------------------------------------------\n  *             S T U B S\n  * ---------------------------------------------------------------------------------\n  */\n\n  bool __stdcall InternalFunctionExists(const char* name)\n  {\n    return core->InternalFunctionExists(name);\n  }\n\n  void __stdcall AdjustMemoryConsumption(size_t amount, bool minus)\n  {\n    core->AdjustMemoryConsumption(amount, minus);\n  }\n\n  void __stdcall CheckVersion(int version)\n  {\n    core->CheckVersion(version);\n  }\n\n  int __stdcall GetCPUFlags()\n  {\n    return core->GetCPUFlags();\n  }\n\n  int64_t __stdcall GetCPUFlagsEx()\n  {\n    return core->GetCPUFlagsEx();\n  }\n\n  char* __stdcall SaveString(const char* s, int length = -1)\n  {\n    return DISPATCH(var_table).SaveString(s, length);\n  }\n\n  char* __stdcall SaveString(const char* s, int length, bool escape)\n  {\n    return DISPATCH(var_table).SaveString(s, length, escape);\n  }\n\n  char* Sprintf(const char* fmt, ...)\n  {\n    va_list val;\n    va_start(val, fmt);\n    // do not call core->Sprintf, because cannot pass ... further\n    char* result = VSprintf(fmt, val);\n    va_end(val);\n    return result;\n  }\n\n  char* __stdcall VSprintf(const char* fmt, va_list val)\n  {\n    try {\n      std::string str = FormatString(fmt, val);\n      return DISPATCH(var_table).SaveString(str.c_str(), int(str.size())); // SaveString will add the NULL in len mode.\n    }\n    catch (...) {\n      return NULL;\n    }\n  }\n\n  void ThrowError(const char* fmt, ...)\n  {\n    va_list val;\n    va_start(val, fmt);\n    VThrowError(fmt, val);\n    va_end(val);\n  }\n\n  void __stdcall VThrowError(const char* fmt, va_list va)\n  {\n    std::string msg;\n    try {\n      msg = FormatString(fmt, va);\n    }\n    catch (...) {\n      msg = \"Exception while processing ScriptEnvironment::ThrowError().\";\n    }\n\n    // Also log the error before throwing\n    this->LogMsg(LOGLEVEL_ERROR, msg.c_str());\n\n    // Throw...\n    throw AvisynthError(DISPATCH(var_table).SaveString(msg.c_str()));\n  }\n\n  PVideoFrame __stdcall SubframePlanarA(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV, int rel_offsetA)\n  {\n    return core->SubframePlanarA(src, rel_offset, new_pitch, new_row_size, new_height, rel_offsetU, rel_offsetV, new_pitchUV, rel_offsetA);\n  }\n\n  bool __stdcall MakePropertyWritable(PVideoFrame* pvf)\n  {\n    return core->MakePropertyWritable(pvf);\n  }\n\n  void __stdcall copyFrameProps(const PVideoFrame& src, PVideoFrame& dst)\n  {\n    core->copyFrameProps(src, dst);\n  }\n\n  const AVSMap* __stdcall getFramePropsRO(const PVideoFrame& frame)\n  {\n    return core->getFramePropsRO(frame);\n  }\n  AVSMap* __stdcall getFramePropsRW(PVideoFrame& frame)\n  {\n    return core->getFramePropsRW(frame);\n  }\n  int __stdcall propNumKeys(const AVSMap* map)\n  {\n    return core->propNumKeys(map);\n  }\n  const char* __stdcall propGetKey(const AVSMap* map, int index)\n  {\n    return core->propGetKey(map, index);\n  }\n  int __stdcall propNumElements(const AVSMap* map, const char* key)\n  {\n    return core->propNumElements(map, key);\n  }\n  char __stdcall propGetType(const AVSMap* map, const char* key)\n  {\n    return core->propGetType(map, key);\n  }\n  int __stdcall propDeleteKey(AVSMap* map, const char* key)\n  {\n    return core->propDeleteKey(map, key);\n  }\n  int64_t __stdcall propGetInt(const AVSMap* map, const char* key, int index, int* error)\n  {\n    return core->propGetInt(map, key, index, error);\n  }\n  int __stdcall propGetIntSaturated(const AVSMap* map, const char* key, int index, int* error)\n  {\n    return core->propGetIntSaturated(map, key, index, error);\n  }\n  double __stdcall propGetFloat(const AVSMap* map, const char* key, int index, int* error)\n  {\n    return core->propGetFloat(map, key, index, error);\n  }\n  float __stdcall propGetFloatSaturated(const AVSMap* map, const char* key, int index, int* error)\n  {\n    return core->propGetFloatSaturated(map, key, index, error);\n  }\n  const char* __stdcall propGetData(const AVSMap* map, const char* key, int index, int* error)\n  {\n    return core->propGetData(map, key, index, error);\n  }\n  int __stdcall propGetDataSize(const AVSMap* map, const char* key, int index, int* error)\n  {\n    return core->propGetDataSize(map, key, index, error);\n  }\n  int __stdcall propGetDataTypeHint(const AVSMap* map, const char* key, int index, int* error)\n  {\n    return core->propGetDataTypeHint(map, key, index, error);\n  }\n  PClip __stdcall propGetClip(const AVSMap* map, const char* key, int index, int* error)\n  {\n    return core->propGetClip(map, key, index, error);\n  }\n  const PVideoFrame __stdcall propGetFrame(const AVSMap* map, const char* key, int index, int* error)\n  {\n    return core->propGetFrame(map, key, index, error);\n  }\n  int __stdcall propSetInt(AVSMap* map, const char* key, int64_t i, int append)\n  {\n    return core->propSetInt(map, key, i, append);\n  }\n  int __stdcall propSetFloat(AVSMap* map, const char* key, double d, int append)\n  {\n    return core->propSetFloat(map, key, d, append);\n  }\n  int __stdcall propSetData(AVSMap* map, const char* key, const char* d, int length, int append)\n  {\n    return core->propSetData(map, key, d, length, append);\n  }\n  int __stdcall propSetDataH(AVSMap* map, const char* key, const char* d, int length, int type, int append)\n  {\n    return core->propSetDataH(map, key, d, length, type, append);\n  }\n  int __stdcall propSetClip(AVSMap* map, const char* key, PClip& clip, int append)\n  {\n    return core->propSetClip(map, key, clip, append);\n  }\n  int __stdcall propSetFrame(AVSMap* map, const char* key, const PVideoFrame& frame, int append)\n  {\n    return core->propSetFrame(map, key, frame, append);\n  }\n\n  const int64_t* __stdcall propGetIntArray(const AVSMap* map, const char* key, int* error)\n  {\n    return core->propGetIntArray(map, key, error);\n  }\n\n  const double* __stdcall propGetFloatArray(const AVSMap* map, const char* key, int* error)\n  {\n    return core->propGetFloatArray(map, key, error);\n  }\n\n  int __stdcall propSetIntArray(AVSMap* map, const char* key, const int64_t* i, int size)\n  {\n    return core->propSetIntArray(map, key, i, size);\n  }\n\n  int __stdcall propSetFloatArray(AVSMap* map, const char* key, const double* d, int size)\n  {\n    return core->propSetFloatArray(map, key, d, size);\n  }\n\n  AVSMap* __stdcall createMap()\n  {\n    return core->createMap();\n  }\n\n  void __stdcall freeMap(AVSMap* map)\n  {\n    core->freeMap(map);\n  }\n\n  void __stdcall clearMap(AVSMap* map)\n  {\n    core->clearMap(map);\n  }\n\n  void __stdcall AddFunction(const char* name, const char* params, ApplyFunc apply, void* user_data = 0)\n  {\n    core->AddFunction(name, params, apply, user_data);\n  }\n\n  void __stdcall AddFunction25(const char* name, const char* params, ApplyFunc apply, void* user_data = 0)\n  {\n    core->AddFunction25(name, params, apply, user_data);\n  }\n\n  void __stdcall AddFunctionPreV11C(const char* name, const char* params, ApplyFunc apply, void* user_data = 0)\n  {\n    core->AddFunctionPreV11C(name, params, apply, user_data);\n  }\n\n  bool __stdcall FunctionExists(const char* name)\n  {\n    return core->FunctionExists(name);\n  }\n\n  bool IsRuntime() {\n    // When invoked from GetFrame/GetAudio, skip all cache and mt mecanism\n    bool is_runtime = true;\n\n#ifdef XP_TLS\n    ScriptEnvironmentTLS* g_TLS = (ScriptEnvironmentTLS*)(TlsGetValue(dwTlsIndex));\n#endif\n    if (g_TLS == nullptr) { // not called by thread\n      if (GetFrameRecursiveCount() == 0) { // not called by GetFrame\n        is_runtime = false;\n      }\n    }\n\n    return is_runtime;\n  }\n\n  // thrower Invoke, IScriptEnvironment\n  AVSValue __stdcall Invoke(const char* name,\n    const AVSValue args, const char* const* arg_names)\n  {\n    AVSValue result;\n    if (!core->Invoke_(&result, AVSValue(), name, nullptr, args, arg_names, this, IsRuntime()))\n    {\n      throw NotFound();\n    }\n    return result;\n  }\n\n  // thrower Invoke, IScriptEnvironment_Avs25\n  AVSValue __stdcall Invoke25(const char* name,\n    const AVSValue args, const char* const* arg_names)\n  {\n    AVSValue result;\n    const bool success = core->Invoke_(&result, AVSValue(), name, nullptr, args, arg_names, this, IsRuntime());\n\n    ((AVSValue*)&args)->MarkArrayAsNonDeepCopy();\n    // In Avisynth+, arrays are deep-copied and freed. The 'args' array elements are freed upon Invoke25's exit.\n    // But this call comes from a filter using Avisynth 2.5 header, where the caller would free the elements again, causing a crash.\n    // We assume memory freeing is handled by the cpp 2.5 plugin.\n    // If 'args' is an array, we convert its type to 'void' to prevent AVSValue destructor from freeing the array elements.\n    // Unlike Avisynth+, the passed AVSValue is not a smart deep-copied array; it was allocated by the client and filled manually.\n\n    if (!success)\n      throw NotFound();\n\n    // 2.5 plugins don't know about long and double types.\n    if (result.GetType() == AvsValueType::VALUE_TYPE_LONG) // real 64 bit integer\n      result = result.AsInt();\n    else if (result.GetType() == AvsValueType::VALUE_TYPE_DOUBLE) // real 64 bit double\n      result = result.AsFloatf();\n\n    return result;\n  }\n\n  // thrower Invoke, IScriptEnvironment_AvsPreV11C\n  AVSValue __stdcall InvokePreV11C(const char* name,\n    const AVSValue args, const char* const* arg_names)\n  {\n    AVSValue result;\n\n    const bool success = core->Invoke_(&result, AVSValue(), name, nullptr, args, arg_names, this, IsRuntime());\n\n    if (!success)\n      throw NotFound();\n\n    // PreV11C plugins don't know about 'l'ong and 'd'ouble basic types.\n    // Convert them to 'i'nt and 'f'loat respectively.\n    // A preV11C interface plugin (no avisynth_c_plugin_init2) can call avs_invoke\n    // which would (if unchanged) result in a 64 bit type, like Pi() returns double.\n    // Example call: \n    // AVS_Value ver = avs_invoke(Env, \"Pi\", avs_new_value_array(NULL, 0), NULL);\n    // We convert only basic types, and not handling array type return values here,\n    // to look into whether it contains 64 bit elements accidentally.\n    // Neither is an old C plugin expected to handle array return values.\n    // Anyway, proper dyn array support comes only from v11 on C API.\n    if (result.GetType() == AvsValueType::VALUE_TYPE_LONG) // real 64 bit integer\n      result = result.AsInt(); // to 32 bit integer\n    else if (result.GetType() == AvsValueType::VALUE_TYPE_DOUBLE) // real 64 bit double\n      result = result.AsFloatf(); // to 32 bit float\n\n    return result;\n  }\n\n  //  no-throw Invoke, IScriptEnvironment, Ex-IS2\n  bool __stdcall InvokeTry(AVSValue* result,\n    const char* name, const AVSValue& args, const char* const* arg_names)\n  {\n    return core->Invoke_(result, AVSValue(), name, nullptr, args, arg_names, this, IsRuntime());\n  }\n\n  // thrower Invoke + implicit last, since IS V8\n  // created to have throw and non-throw (xxxxTry) versions from all Invokes\n  AVSValue __stdcall Invoke2(const AVSValue& implicit_last,\n    const char* name, const AVSValue args, const char* const* arg_names)\n  {\n    AVSValue result;\n    if (!core->Invoke_(&result, implicit_last,\n      name, nullptr, args, arg_names, this, IsRuntime()))\n    {\n      throw NotFound();\n    }\n    return result;\n  }\n\n  // no-throw Invoke + implicit last, Ex-INeo\n  bool __stdcall Invoke2Try(AVSValue* result, const AVSValue& implicit_last,\n    const char* name, const AVSValue args, const char* const* arg_names)\n  {\n    return core->Invoke_(result, implicit_last,\n      name, nullptr, args, arg_names, this, IsRuntime());\n  }\n\n  // thrower Invoke + implicit last + PFunction\n  AVSValue __stdcall Invoke3(const AVSValue& implicit_last,\n    const PFunction& func, const AVSValue args, const char* const* arg_names)\n  {\n    AVSValue result;\n    if (!core->Invoke_(&result, implicit_last,\n      func->GetLegacyName(), func->GetDefinition(), args, arg_names, this, IsRuntime()))\n    {\n      throw NotFound();\n    }\n    return result;\n  }\n\n  // no-throw Invoke + implicit last + PFunction\n  bool __stdcall Invoke3Try(AVSValue *result, const AVSValue& implicit_last,\n    const PFunction& func, const AVSValue args, const char* const* arg_names)\n  {\n    return core->Invoke_(result, implicit_last,\n      func->GetLegacyName(), func->GetDefinition(), args, arg_names, this, IsRuntime());\n  }\n\n  // King of all Invoke versions: no-throw Invoke + implicit last + funtion name + function definition\n  bool __stdcall Invoke_(AVSValue *result, const AVSValue& implicit_last,\n    const char* name, const Function *f, const AVSValue& args, const char* const* arg_names)\n  {\n    return core->Invoke_(result, implicit_last, name, f, args, arg_names, this, IsRuntime());\n  }\n\n  bool __stdcall MakeWritable(PVideoFrame* pvf)\n  {\n    return core->MakeWritable(pvf);\n  }\n\n  void __stdcall BitBlt(BYTE* dstp, int dst_pitch, const BYTE* srcp, int src_pitch, int row_size, int height)\n  {\n    core->BitBlt(dstp, dst_pitch, srcp, src_pitch, row_size, height);\n  }\n\n  void __stdcall AtExit(IScriptEnvironment::ShutdownFunc function, void* user_data)\n  {\n    core->AtExit(function, user_data);\n  }\n\n  PVideoFrame __stdcall Subframe(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height)\n  {\n    return core->Subframe(src, rel_offset, new_pitch, new_row_size, new_height);\n  }\n\n  int __stdcall SetMemoryMax(int mem)\n  {\n    return core->SetMemoryMax(mem);\n  }\n\n  int __stdcall SetWorkingDir(const char* newdir)\n  {\n    return core->SetWorkingDir(newdir);\n  }\n\n  bool __stdcall AcquireGlobalLock(const char* name) {\n    return core->AcquireGlobalLock(name);\n  }\n\n  void __stdcall ReleaseGlobalLock(const char* name) {\n    core->ReleaseGlobalLock(name);\n  }\n\n  void* __stdcall ManageCache(int key, void* data)\n  {\n    if (\n      (MANAGE_CACHE_KEYS)key == MC_QueryAvs25 ||\n      (MANAGE_CACHE_KEYS)key == MC_QueryAvsPreV11C\n      )\n      return (intptr_t*)0;\n    return core->ManageCache(key, data);\n  }\n\n  void* __stdcall ManageCache25(int key, void* data)\n  {\n    // We use a v2.5-special ManageCache call with special key to query if\n    // env ptr is v2.5 even if casted to IScriptEnvironment \n    if ((MANAGE_CACHE_KEYS)key == MC_QueryAvs25)\n      return (intptr_t *)1;\n    return ManageCache(key, data);\n  }\n\n  void* __stdcall ManageCachePreV11C(int key, void* data)\n  {\n    // We use a preV11C-special ManageCache call with special key to query if\n    // env ptr is preV11C even if casted to IScriptEnvironment \n    if ((MANAGE_CACHE_KEYS)key == MC_QueryAvsPreV11C)\n      return (intptr_t*)1;\n    return ManageCache(key, data);\n  }\n\n  bool __stdcall PlanarChromaAlignment(IScriptEnvironment::PlanarChromaAlignmentMode key)\n  {\n    return core->PlanarChromaAlignment(key);\n  }\n\n  PVideoFrame __stdcall SubframePlanar(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV)\n  {\n    return core->SubframePlanar(src, rel_offset, new_pitch, new_row_size, new_height, rel_offsetU, rel_offsetV, new_pitchUV);\n  }\n\n  void __stdcall DeleteScriptEnvironment()\n  {\n#ifdef XP_TLS\n    ScriptEnvironmentTLS* g_TLS = (ScriptEnvironmentTLS*)(TlsGetValue(dwTlsIndex));\n#endif\n    if (g_TLS != nullptr) {\n      ThrowError(\"Cannot delete environment from a TLS proxy.\");\n    }\n    core->DeleteScriptEnvironment();\n  }\n\n  void __stdcall ApplyMessage(PVideoFrame* frame, const VideoInfo& vi, const char* message, int size, int textcolor, int halocolor, int bgcolor)\n  {\n    core->ApplyMessage(frame, vi, message, size, textcolor, halocolor, bgcolor);\n  }\n\n  void __stdcall ApplyMessageEx(PVideoFrame* frame, const VideoInfo& vi, const char* message, int size, int textcolor, int halocolor, int bgcolor, bool utf8)\n  {\n    core->ApplyMessageEx(frame, vi, message, size, textcolor, halocolor, bgcolor, utf8);\n  }\n\n  const AVS_Linkage* __stdcall GetAVSLinkage()\n  {\n    return core->GetAVSLinkage();\n  }\n\n  /* IScriptEnvironment2 */\n  bool __stdcall LoadPlugin(const char* filePath, bool throwOnError, AVSValue* result)\n  {\n    return core->LoadPlugin(filePath, throwOnError, result);\n  }\n\n  void __stdcall AddAutoloadDir(const char* dirPath, bool toFront)\n  {\n    core->AddAutoloadDir(dirPath, toFront);\n  }\n\n  void __stdcall ClearAutoloadDirs()\n  {\n    core->ClearAutoloadDirs();\n  }\n\n  void __stdcall AutoloadPlugins()\n  {\n    core->AutoloadPlugins();\n  }\n\n  void __stdcall AddFunction(const char* name, const char* params, ApplyFunc apply, void* user_data, const char* exportVar)\n  {\n    core->AddFunction(name, params, apply, user_data, exportVar);\n  }\n\n  char* __stdcall ListAutoloadDirs()\n  {\n    return core->ListAutoloadDirs();\n  }\n\n  void __stdcall SetFilterProp(const char* filter, const char* key, const AVSValue& value, int mode)\n  {\n    core->SetFilterProp(filter, key, value, mode);\n  }\n\n  void __stdcall SetFilterPropConditional(const char* filter, const char* param_name, const AVSValue& param_match,\n                                          const char* key, const AVSValue& value, int mode)\n  {\n    core->SetFilterPropConditional(filter, param_name, param_match, key, value, mode);\n  }\n\n  const char* __stdcall GetFilterProps()\n  {\n    return core->GetFilterProps();\n  }\n\n  void __stdcall SetFilterPropPassthrough(const char* filter)\n  {\n    core->SetFilterPropPassthrough(filter);\n  }\n\n  int __stdcall IncrImportDepth()\n  {\n    return ++DISPATCH(ImportDepth);\n  }\n\n  int __stdcall DecrImportDepth()\n  {\n    return --DISPATCH(ImportDepth);\n  }\n\n  size_t  __stdcall GetEnvProperty(AvsEnvProperty prop)\n  {\n    switch (prop)\n    {\n    case AEP_THREAD_ID:\n      return DISPATCH(thread_id);\n    case AEP_SUPPRESS_THREAD:\n      return DISPATCH(suppressThreadCount);\n    case AEP_GETFRAME_RECURSIVE:\n      return DISPATCH(getFrameRecursiveCount);\n    default:\n      return core->GetEnvProperty(prop);\n    }\n  }\n\n  void __stdcall SetFilterMTMode(const char* filter, MtMode mode, bool force)\n  {\n    core->SetFilterMTMode(filter, mode, force);\n  }\n\n  MtMode __stdcall GetFilterMTMode(const Function* filter, bool* is_forced) const\n  {\n    return core->GetFilterMTMode(filter, is_forced);\n  }\n\n  bool __stdcall FilterHasMtMode(const Function* filter) const\n  {\n    return core->FilterHasMtMode(filter);\n  }\n\n  IJobCompletion* __stdcall NewCompletion(size_t capacity)\n  {\n    return core->NewCompletion(capacity);\n  }\n\n  void __stdcall ParallelJob(ThreadWorkerFuncPtr jobFunc, void* jobData, IJobCompletion* completion)\n  {\n    core->ParallelJob(jobFunc, jobData, completion, this);\n  }\n\n  void __stdcall ParallelJob(ThreadWorkerFuncPtr jobFunc, void* jobData, IJobCompletion* completion, InternalEnvironment* env)\n  {\n    core->ParallelJob(jobFunc, jobData, completion, env);\n  }\n\n  ClipDataStore* __stdcall ClipData(IClip* clip)\n  {\n    return core->ClipData(clip);\n  }\n\n  MtMode __stdcall GetDefaultMtMode() const\n  {\n    return core->GetDefaultMtMode();\n  }\n\n  void __stdcall SetLogParams(const char* target, int level)\n  {\n    core->SetLogParams(target, level);\n  }\n\n  // stdcall calling convention is not supported on variadic function\n  void LogMsg(int level, const char* fmt, ...)\n  {\n    va_list val;\n    va_start(val, fmt);\n    core->LogMsg_valist(level, fmt, val);\n    va_end(val);\n  }\n\n  void __stdcall LogMsg_valist(int level, const char* fmt, va_list va)\n  {\n    core->LogMsg_valist(level, fmt, va);\n  }\n\n  // stdcall calling convention is not supported on variadic function\n  void LogMsgOnce(const OneTimeLogTicket& ticket, int level, const char* fmt, ...)\n  {\n    va_list val;\n    va_start(val, fmt);\n    core->LogMsgOnce_valist(ticket, level, fmt, val);\n    va_end(val);\n  }\n\n  void __stdcall LogMsgOnce_valist(const OneTimeLogTicket& ticket, int level, const char* fmt, va_list va)\n  {\n    core->LogMsgOnce_valist(ticket, level, fmt, va);\n  }\n\n  void __stdcall SetMaxCPU(const char *features)\n  {\n    core->SetMaxCPU(features);\n  }\n\n  void __stdcall SetGraphAnalysis(bool enable)\n  {\n    core->SetGraphAnalysis(enable);\n  }\n\n  int __stdcall SetMemoryMax(AvsDeviceType type, int index, int mem)\n  {\n    return core->SetMemoryMax(type, index, mem);\n  }\n\n  PDevice __stdcall GetDevice(AvsDeviceType device_type, int device_index) const\n  {\n    return core->GetDevice(device_type, device_index);\n  }\n\n  PDevice __stdcall GetDevice() const\n  {\n    return DISPATCH(currentDevice);\n  }\n\n  AvsDeviceType __stdcall GetDeviceType() const\n  {\n    return DISPATCH(currentDevice)->device_type;\n  }\n\n  int __stdcall GetDeviceId() const\n  {\n    return DISPATCH(currentDevice)->device_id;\n  }\n\n  int __stdcall GetDeviceIndex() const\n  {\n    return DISPATCH(currentDevice)->device_index;\n  }\n\n  void* __stdcall GetDeviceStream() const\n  {\n    return DISPATCH(currentDevice)->GetComputeStream();;\n  }\n\n  PVideoFrame __stdcall NewVideoFrameOnDevice(const VideoInfo& vi, int align, Device* device)\n  {\n    return core->NewVideoFrameOnDevice(vi, align, device);\n  }\n\n  // shortcut to the above\n  PVideoFrame __stdcall NewVideoFrame(const VideoInfo& vi)\n  {\n    return NewVideoFrameOnDevice(vi, FRAME_ALIGN, DISPATCH(currentDevice));\n  }\n\n  // shortcut to the above\n  PVideoFrame __stdcall NewVideoFrame(const VideoInfo& vi, const PDevice& device)\n  {\n    return NewVideoFrameOnDevice(vi, FRAME_ALIGN, (Device*)(void*)device);\n  }\n\n  // variants with frame property source\n  PVideoFrame __stdcall NewVideoFrameOnDevice(const VideoInfo& vi, int align, Device* device, const PVideoFrame *prop_src)\n  {\n    return core->NewVideoFrameOnDevice(vi, align, device, prop_src);\n  }\n\n  // shortcut to the above\n  PVideoFrame __stdcall NewVideoFrame(const VideoInfo& vi, const PVideoFrame* prop_src)\n  {\n    return NewVideoFrameOnDevice(vi, FRAME_ALIGN, DISPATCH(currentDevice), prop_src);\n  }\n\n  // shortcut to the above\n  PVideoFrame __stdcall NewVideoFrame(const VideoInfo& vi, const PDevice& device, const PVideoFrame* prop_src)\n  {\n    return NewVideoFrameOnDevice(vi, FRAME_ALIGN, (Device*)(void*)device, prop_src);\n  }\n\n  PVideoFrame __stdcall GetOnDeviceFrame(const PVideoFrame& src, Device* device)\n  {\n    return core->GetOnDeviceFrame(src, device);\n  }\n\n\n  ThreadPool* __stdcall NewThreadPool(size_t nThreads)\n  {\n    return core->NewThreadPool(nThreads);\n  }\n\n\n  void __stdcall AddRef() {\n    InterlockedIncrement(&DISPATCH(refcount));\n  }\n\n  void __stdcall Release() {\n    if (InterlockedDecrement(&DISPATCH(refcount)) == 0) {\n      delete this;\n    }\n  }\n\n  void __stdcall IncEnvCount() {\n    core->IncEnvCount();\n  }\n\n  void __stdcall DecEnvCount() {\n    core->DecEnvCount();\n  }\n\n  ConcurrentVarStringFrame* __stdcall GetTopFrame()\n  {\n    return core->GetTopFrame();\n  }\n\n  void __stdcall SetCacheMode(CacheMode mode)\n  {\n    core->SetCacheMode(mode);\n  }\n\n  CacheMode __stdcall GetCacheMode()\n  {\n    return core->GetCacheMode();\n  }\n\n  bool& __stdcall GetSupressCaching()\n  {\n    return DISPATCH(supressCaching);\n  }\n\n  size_t __stdcall GetInvokeStackSize()\n  {\n    return core->GetInvokeStackSize();\n  }\n\n  void __stdcall SetDeviceOpt(DeviceOpt opt, int val)\n  {\n    core->SetDeviceOpt(opt, val);\n  }\n\n  void __stdcall UpdateFunctionExports(const char* funcName, const char* funcParams, const char *exportVar)\n  {\n    if (GetThreadId() != 0 || GetFrameRecursiveCount() != 0) {\n      // no need to export function at runtime\n      return;\n    }\n    core->UpdateFunctionExports(funcName, funcParams, exportVar);\n  }\n\n\n  InternalEnvironment* __stdcall NewThreadScriptEnvironment(int thread_id)\n  {\n    return new ThreadScriptEnvironment(thread_id, core, coreTLS);\n  }\n\n  int __stdcall GetThreadId() {\n    return DISPATCH(thread_id);\n  }\n\n  int& __stdcall GetFrameRecursiveCount() {\n    return DISPATCH(getFrameRecursiveCount);\n  }\n\n  int& __stdcall GetSuppressThreadCount() {\n    return DISPATCH(suppressThreadCount);\n  }\n\n  FilterGraphNode*& GetCurrentGraphNode() {\n    return DISPATCH(currentGraphNode);\n  }\n\n#undef DISPATCH\n#undef IFNULL\n};\n\n#ifdef AVS_POSIX\nstatic uint64_t posix_get_physical_memory() {\n  uint64_t ullTotalPhys;\n#if defined(AVS_MACOS)\n  size_t len;\n  sysctlbyname(\"hw.memsize\", nullptr, &len, nullptr, 0);\n  int64_t memsize;\n  sysctlbyname(\"hw.memsize\", (void*)&memsize, &len, nullptr, 0);\n  ullTotalPhys = memsize;\n#elif defined(AVS_BSD)\n  size_t len;\n  int64_t memsize;\n#if !defined(__OpenBSD__)\n// OpenBSD doesn't have sysctlbyname at all, so this needs to be\n// ported to plain sysctl.\n  sysctlbyname(\"hw.physmem\", nullptr, &len, nullptr, 0);\n  sysctlbyname(\"hw.physmem\", (void*)&memsize, &len, nullptr, 0);\n#else\n  sysctl((const int *)HW_PHYSMEM, 4, nullptr, &len, nullptr, 0);\n  sysctl((const int *)HW_PHYSMEM, 4, (void*)&memsize, &len, nullptr, 0);\n#endif\n  ullTotalPhys = memsize;\n#elif defined(AVS_HAIKU)\n  system_info sysinf;\n  get_system_info(&sysinf);\n  ullTotalPhys = PAGESIZE * sysinf.max_pages;\n#else\n  // linux\n  struct sysinfo info;\n  if (sysinfo(&info) != 0) {\n    throw AvisynthError(\"sysinfo: error reading system statistics\");\n  }\n  ullTotalPhys = (uint64_t)info.totalram * info.mem_unit;\n#endif\n  return ullTotalPhys;\n}\n\nstatic int64_t posix_get_available_memory() {\n  int64_t memory;\n\n  long nPageSize = sysconf(_SC_PAGE_SIZE);\n  int64_t nAvailablePhysicalPages;\n\n#if defined(AVS_MACOS)\n  vm_statistics64_data_t vmstats;\n  mach_msg_type_number_t vmstatsz = HOST_VM_INFO64_COUNT;\n  host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info_t)&vmstats, &vmstatsz);\n  nAvailablePhysicalPages = vmstats.free_count;\n#elif defined(AVS_BSD)\n#if !defined(__OpenBSD__)\n// OpenBSD does not have sysctlbyname\n  size_t nAvailablePhysicalPagesLen = sizeof(nAvailablePhysicalPages);\n  sysctlbyname(\"vm.stats.vm.v_free_count\", &nAvailablePhysicalPages, &nAvailablePhysicalPagesLen, NULL, 0);\n#endif\n#elif defined(AVS_HAIKU)\n  system_info sysinf;\n  get_system_info(&sysinf);\n  nAvailablePhysicalPages = sysinf.free_memory;\n#else // Linux\n  nAvailablePhysicalPages = sysconf(_SC_AVPHYS_PAGES);\n#endif\n\n  memory = nPageSize * nAvailablePhysicalPages;\n\n  return memory;\n}\n#endif\n\nstatic uint64_t ConstrainMemoryRequest(uint64_t requested)\n{\n  // Get system memory information\n#ifdef AVS_WINDOWS // needs linux alternative\n  MEMORYSTATUSEX memstatus;\n  memstatus.dwLength = sizeof(memstatus);\n  GlobalMemoryStatusEx(&memstatus);\n\n  // mem_limit is the largest amount of memory that makes sense to use.\n  // We don't want to use more than the virtual address space,\n  // and we also don't want to start paging to disk.\n  uint64_t mem_limit = min(memstatus.ullTotalVirtual, memstatus.ullTotalPhys);\n\n  uint64_t mem_sysreserve = 0;\n  if (memstatus.ullTotalPhys > memstatus.ullTotalVirtual)\n  {\n    // We are probably running on a 32bit OS system where the virtual space is capped to\n    // much less than what the system can use, so it is enough to reserve only a small amount.\n    mem_sysreserve = 128 * 1024 * 1024ull;\n  }\n  else\n  {\n    // We could probably use up all the RAM in our single application,\n    // so reserve more to leave some RAM for other apps and the OS too.\n    mem_sysreserve = 1024 * 1024 * 1024ull;\n  }\n\n  // Cap memory_max to at most mem_sysreserve less than total, but at least to 64MB.\n  return clamp(requested, (uint64_t)64 * 1024 * 1024, mem_limit - mem_sysreserve);\n#else\n  // copied over from AvxSynth, check against current code!!!\n\n  // Check#1\n  // AvxSynth returned simply the actual total_available memory\n  // this part is trying to fine tune it, considering that\n  // - total_available may contain swap area which we do not want to use FIXME: check it!\n  // - leave some memory for other processes (1 GB for x64, 128MB for 32 bit)\n\n  uint64_t physical_memory = posix_get_physical_memory();\n  uint64_t total_available = posix_get_available_memory();\n  // We don't want to use more than the virtual address space,\n  // and we also don't want to start paging to disk.\n  uint64_t mem_limit = min(total_available, physical_memory);\n\n  // We could probably use up all the RAM in our single application,\n  // so reserve more to leave some RAM for other apps and the OS too.\n  const bool isX64 = sizeof(void*) == 8;\n  uint64_t mem_sysreserve = isX64 ? (uint64_t)1024 * 1024 * 1024 : (uint64_t)128 * 1024 * 1024;\n\n  // Cap memory_max to at most mem_sysreserve less than total, but at least to 64MB.\n  uint64_t allowed_memory = clamp(requested, (uint64_t)64 * 1024 * 1024, mem_limit - mem_sysreserve);\n#if 0\n  const int DIV = 1024 * 1024;\n  fprintf(stdout, \"requested= %\" PRIu64 \" MB\\r\\n\", requested / DIV);\n  fprintf(stdout, \"physical_memory= %\" PRIu64 \" MB\\r\\n\", physical_memory / DIV);\n  fprintf(stdout, \"total_available= %\" PRIu64 \" MB\\r\\n\", total_available / DIV);\n  fprintf(stdout, \"mem_limit= %\" PRIu64 \" MB\\r\\n\", mem_limit / DIV);\n  fprintf(stdout, \"mem_sysreserve= %\" PRIu64 \" MB\\r\\n\", mem_sysreserve / DIV);\n  fprintf(stdout, \"allowed_memory= %\" PRIu64 \" MB\\r\\n\", allowed_memory / DIV);\n  /*For a computer with 16GB RAM, 64 bit OS\n    No SetMemoryMax, where default max request is 4GB on x64\n      requested= 4072 MB\n      physical_memory= 16291 MB\n      total_available= 7640 MB\n      mem_limit= 7640 MB\n      mem_sysreserve= 1024 MB\n      allowed_memory= 4072 MB\n    Using SetmemoryMax(10000)\n      requested= 10000 MB\n      physical_memory= 16291 MB\n      total_available= 7667 MB\n      mem_limit= 7667 MB\n      mem_sysreserve= 1024 MB\n      allowed_memory= 6643 MB\n  */\n#endif\n  return allowed_memory;\n#endif\n\n}\n\nIJobCompletion* ScriptEnvironment::NewCompletion(size_t capacity)\n{\n  return new JobCompletion(capacity);\n}\n\nScriptEnvironment::ScriptEnvironment()\n  : threadEnv(),\n  at_exit(),\n  thread_pool(NULL),\n  plugin_manager(NULL),\n  EnvCount(0),\n  PlanarChromaAlignmentState(true),   // Change to \"true\" for 2.5.7\n  hrfromcoinit(E_FAIL), coinitThreadId(0),\n  Devices(),\n  FrontCache(NULL),\n  nTotalThreads(1),\n  nMaxFilterInstances(1),\n  LogLevel(LOGLEVEL_NONE),\n  graphAnalysisEnable(false),\n  cacheMode(CACHE_DEFAULT)\n{\n#ifdef XP_TLS\n  if(dwTlsIndex == 0)\n    throw(\"ScriptEnvironment: TlsAlloc failed on DLL load\");\n#endif\n\n  cpuFlagsEx = ::GetCPUFlagsEx();\n  cache_size_L2 = ::GetL2CacheSize();\n\n  try {\n#ifdef AVS_WINDOWS\n    // Make sure COM is initialised\n    hrfromcoinit = CoInitialize(NULL);\n    // If it was already init'd then decrement\n    // the use count and leave it alone!\n    if (hrfromcoinit == S_FALSE) {\n      hrfromcoinit = E_FAIL;\n      CoUninitialize();\n    }\n    // Remember our threadId.\n    coinitThreadId = GetCurrentThreadId();\n#endif\n\n    threadEnv = std::unique_ptr<ThreadScriptEnvironment>(new ThreadScriptEnvironment(0, this, nullptr));\n    Devices = std::unique_ptr<DeviceManager>(new DeviceManager(threadEnv.get()));\n\n    // calc frame align\n    frame_align = plane_align = FRAME_ALIGN;\n#ifdef ENABLE_CUDA\n    for (int i = 0, end = Devices->GetNumDevices(DEV_TYPE_CUDA); i < end; ++i) {\n      int align, pitchAlign;\n      Devices->GetDevice(DEV_TYPE_CUDA, i)->GetAlignmentRequirement(&align, &pitchAlign);\n      frame_align = max(frame_align, pitchAlign);\n      plane_align = max(plane_align, align);\n    }\n#endif\n\n    auto cpuDevice = Devices->GetCPUDevice();\n    threadEnv->GetTLS()->currentDevice = cpuDevice;\n\n#ifdef AVS_WINDOWS\n    MEMORYSTATUSEX memstatus;\n    memstatus.dwLength = sizeof(memstatus);\n    GlobalMemoryStatusEx(&memstatus);\n    cpuDevice->memory_max = ConstrainMemoryRequest(memstatus.ullTotalPhys / 4);\n#endif\n#ifdef AVS_POSIX\n    uint64_t ullTotalPhys = posix_get_physical_memory();\n    cpuDevice->memory_max = ConstrainMemoryRequest(ullTotalPhys / 4);\n    // fprintf(stdout, \"Total physical memory= %\" PRIu64 \", after constraint=%\" PRIu64 \"\\r\\n\", ullTotalPhys, memory_max);\n    // Total physical memory = 17083355136, after constraint = 7274700800\n#endif\n    const bool isX64 = sizeof(void*) == 8;\n    cpuDevice->memory_max = min(cpuDevice->memory_max, (uint64_t)((isX64 ? 4096 : 1024) * (1024 * 1024ull)));  // at start, cap memory usage to 1GB(x86)/4GB (x64)\n    cpuDevice->memory_used = 0ull;\n\n    top_frame.Set(\"true\", true);\n    top_frame.Set(\"false\", false);\n    top_frame.Set(\"yes\", true);\n    top_frame.Set(\"no\", false);\n    top_frame.Set(\"last\", AVSValue());\n\n    top_frame.Set(\"$ScriptName$\", AVSValue());\n    top_frame.Set(\"$ScriptFile$\", AVSValue());\n    top_frame.Set(\"$ScriptDir$\", AVSValue());\n    top_frame.Set(\"$ScriptNameUtf8$\", AVSValue());\n    top_frame.Set(\"$ScriptFileUtf8$\", AVSValue());\n    top_frame.Set(\"$ScriptDirUtf8$\", AVSValue());\n\n    plugin_manager = new PluginManager(threadEnv.get());\n#ifdef AVS_WINDOWS\n    plugin_manager->AddAutoloadDir(\"USER_PLUS_PLUGINS\", false);\n    plugin_manager->AddAutoloadDir(\"MACHINE_PLUS_PLUGINS\", false);\n    plugin_manager->AddAutoloadDir(\"USER_CLASSIC_PLUGINS\", false);\n    plugin_manager->AddAutoloadDir(\"MACHINE_CLASSIC_PLUGINS\", false);\n#else\n    // system_avs_plugindir relies on install path, it and user_avs_plugindir_configurable get\n    // defined in avisynth_conf.h.in when configuring.\n\n    if(std::getenv(\"HOME\")) {\n        std::string user_avs_plugindir = std::getenv(\"HOME\");\n        std::string user_avs_plugindir_local = std::getenv(\"HOME\");\n        std::string user_avs_dirname = \"/.avisynth\";\n\n        user_avs_plugindir.append(user_avs_dirname);\n\n        user_avs_plugindir_local.append(\"/\").append(user_avs_plugindir_configurable);\n\n        plugin_manager->AddAutoloadDir(user_avs_plugindir, false);\n        plugin_manager->AddAutoloadDir(user_avs_plugindir_local, false);\n    }\n\n    if (std::getenv(\"LD_LIBRARY_PATH\")) {\n        std::string ldrel_avs_plugindir, ldrel_stor;\n        ldrel_avs_plugindir.append(std::getenv(\"LD_LIBRARY_PATH\"));\n\n        std::istringstream ldrelin(ldrel_avs_plugindir);\n\n        while(getline(ldrelin, ldrel_stor, ':')) {\n            ldrel_stor.append(\"/avisynth\");\n            plugin_manager->AddAutoloadDir(ldrel_stor, false);\n        }\n    }\n\n    plugin_manager->AddAutoloadDir(system_avs_plugindir, false);\n#endif\n\n    top_frame.Set(\"LOG_ERROR\", (int)LOGLEVEL_ERROR);\n    top_frame.Set(\"LOG_WARNING\", (int)LOGLEVEL_WARNING);\n    top_frame.Set(\"LOG_INFO\",    (int)LOGLEVEL_INFO);\n    top_frame.Set(\"LOG_DEBUG\",   (int)LOGLEVEL_DEBUG);\n\n    top_frame.Set(\"DEV_TYPE_CPU\", (int)DEV_TYPE_CPU);\n    top_frame.Set(\"DEV_TYPE_CUDA\", (int)DEV_TYPE_CUDA);\n\n    top_frame.Set(\"CACHE_FAST_START\", (int)CACHE_FAST_START);\n    top_frame.Set(\"CACHE_OPTIMAL_SIZE\", (int)CACHE_OPTIMAL_SIZE);\n    top_frame.Set(\"DEV_CUDA_PINNED_HOST\", (int)DEV_CUDA_PINNED_HOST);\n    top_frame.Set(\"DEV_FREE_THRESHOLD\", (int)DEV_FREE_THRESHOLD);\n\n    InitMT();\n    thread_pool = new ThreadPool(std::thread::hardware_concurrency(), 1, threadEnv.get());\n\n    ExportBuiltinFilters();\n\n    clip_data.max_load_factor(0.8f);\n    LogTickets.max_load_factor(0.8f);\n  }\n  catch (const AvisynthError& err) {\n#ifdef AVS_WINDOWS\n    if (SUCCEEDED(hrfromcoinit)) {\n      hrfromcoinit = E_FAIL;\n      CoUninitialize();\n    }\n#endif\n    // Needs must, to not loose the text we\n    // must leak a little memory.\n    throw AvisynthError(_strdup(err.msg));\n  }\n}\n\nMtMode ScriptEnvironment::GetDefaultMtMode() const\n{\n  return DefaultMtMode;\n}\n\nvoid ScriptEnvironment::InitMT()\n{\n  top_frame.Set(\"MT_NICE_FILTER\", (int)MT_NICE_FILTER);\n  top_frame.Set(\"MT_MULTI_INSTANCE\", (int)MT_MULTI_INSTANCE);\n  top_frame.Set(\"MT_SERIALIZED\", (int)MT_SERIALIZED);\n  top_frame.Set(\"MT_SPECIAL_MT\", (int)MT_SPECIAL_MT);\n}\n\nScriptEnvironment::~ScriptEnvironment() {\n\n  _RPT0(0, \"~ScriptEnvironment() called.\\n\");\n\n  auto tls = threadEnv->GetTLS();\n  tls->closing = true;\n\n  // Before we start to pull the world apart\n  // give every one their last wish.\n  at_exit.Execute(threadEnv.get());\n\n  GlobalLockManager::on_environment_exit(this); // V12\n\n  delete thread_pool;\n\n  tls->var_table.Clear();\n  top_frame.Clear();\n\n  // There can be a circular reference between the Prefetcher and the\n  // TLS PopContext() variables of the threads started by it. Normally\n  // this doesn't happen, but it can for example when somebody\n  // sets 'last' in a TLS (see ScriptClip for a specific example).\n  // This circular reference causes leaks, so we call\n  // Destroy() on the prefetcher, which will in turn terminate all\n  // its TLS stuff and break the chain.\n  for (auto& pool : ThreadPoolRegistry) {\n    pool->Join();\n  }\n  ThreadPoolRegistry.clear();\n\n  // delete ThreadScriptEnvironment\n  threadEnv = nullptr;\n\n  // check ThreadScriptEnvironment leaks\n  if (EnvCount > 0) {\n    LogMsg(LOGLEVEL_WARNING, \"ThreadScriptEnvironment leaks.\");\n  }\n\n#if 0\n  // check clip leaks DoDumpGraph\n  if (std::find_if(GraphNodeRegistry.begin(), GraphNodeRegistry.end(),\n    [](FilterGraphNode* node) { return node != nullptr; }) != GraphNodeRegistry.end())\n  {\n    // This is dangerous operation because thread's string is destroyed\n    // and may be there are dangling string pointer which results in access violation.\n    MinimumScriptEnvironment env(&top_frame);\n    DoDumpGraph(GraphNodeRegistry, \"clip_leaks.txt\", &env);\n  }\n#endif\n\n\n#ifdef _DEBUG\n  // LogMsg(LOGLEVEL_DEBUG, \"We are before FrameRegistryCleanup\");\n  // ListFrameRegistry(0,10000000000000ull, true, device); // list all\n#endif\n  // and deleting the frame buffer from FrameRegistry2 as well\n  bool somethingLeaks = false;\n  for (auto &it: FrameRegistry2)\n  {\n    for (auto &it2: it.second)\n  {\n      VFBStorage *vfb = static_cast<VFBStorage*>(it2.first);\n      delete vfb;\n      // iterate through frames belonging to this vfb\n      for (auto &it3: it2.second)\n      {\n        VideoFrame *frame = it3.frame;\n\n        frame->vfb = 0;\n\n        //assert(0 == frame->refcount);\n        if (0 == frame->refcount)\n        {\n          delete frame;\n        }\n        else\n        {\n          somethingLeaks = true;\n        }\n      } // it3\n    } // it2\n  } // it\n\n  if (somethingLeaks) {\n    LogMsg(LOGLEVEL_WARNING, \"A plugin or the host application might be causing memory leaks.\");\n  }\n\n  delete plugin_manager;\n\n#ifdef AVS_WINDOWS // COM is Win32-specific\n  // If we init'd COM and this is the right thread then release it\n  // If it's the wrong threadId then tuff, nothing we can do.\n  if (SUCCEEDED(hrfromcoinit) && (coinitThreadId == GetCurrentThreadId())) {\n    hrfromcoinit = E_FAIL;\n    CoUninitialize();\n  }\n#endif\n\n}\n\nvoid ScriptEnvironment::SetLogParams(const char* target, int level)\n{\n  if (nullptr == target) {\n    target = \"stderr\";\n  }\n\n  if (-1 == level) {\n    level = LOGLEVEL_INFO;\n  }\n\n  if (LogFileStream.is_open()) {\n    LogFileStream.close();\n  }\n\n  LogLevel = LOGLEVEL_NONE;\n\n  if (!streqi(target, \"stderr\") && !streqi(target, \"stdout\")) {\n    LogFileStream.open(target, std::ofstream::out | std::ofstream::app);\n    if (LogFileStream.fail()) {\n      this->ThrowError(\"SetLogParams: Could not open file \\\"%s\\\" for writing.\", target);\n      return;\n    }\n  }\n\n  LogLevel = level;\n  LogTarget = target;\n}\n\nvoid ScriptEnvironment::LogMsg(int level, const char* fmt, ...)\n{\n  va_list val;\n  va_start(val, fmt);\n  LogMsg_valist(level, fmt, val);\n  va_end(val);\n}\n\nvoid ScriptEnvironment::LogMsg_valist(int level, const char* fmt, va_list va)\n{\n  // Don't output message if our logging level is not high enough\n  if (level > LogLevel) {\n    return;\n  }\n\n  // Setup string prefixes for output messages\n  const char* levelStr = nullptr;\n  uint16_t levelAttr;\n  switch (level)\n  {\n  case LOGLEVEL_ERROR:\n    levelStr = \"ERROR: \";\n#ifdef AVS_WINDOWS // FOREGROUND_* is Windows-specific\n    levelAttr = FOREGROUND_INTENSITY | FOREGROUND_RED;\n#endif\n    break;\n  case LOGLEVEL_WARNING:\n    levelStr = \"WARNING: \";\n#ifdef AVS_WINDOWS // FOREGROUND_* is Windows-specific\n    levelAttr = FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED;\n#endif\n    break;\n  case LOGLEVEL_INFO:\n    levelStr = \"INFO: \";\n#ifdef AVS_WINDOWS // FOREGROUND_* is Windows-specific\n    levelAttr = FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE;\n#endif\n    break;\n  case LOGLEVEL_DEBUG:\n    levelStr = \"DEBUG: \";\n#ifdef AVS_WINDOWS // FOREGROUND_* is Windows-specific\n    levelAttr = FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_RED;\n#endif\n    break;\n  default:\n    this->ThrowError(\"LogMsg: level argument must be between 1 and 4.\");\n    break;\n  }\n\n  // Prepare message output target\n  std::ostream* targetStream = nullptr;\n#ifdef AVS_WINDOWS\n  void* hConsole = GetStdHandle(STD_ERROR_HANDLE);\n#else\n  void* hConsole = stderr;\n#endif\n\n  if (streqi(\"stderr\", LogTarget.c_str()))\n  {\n#ifdef AVS_WINDOWS\n    hConsole = GetStdHandle(STD_ERROR_HANDLE);\n#else\n    hConsole = stderr;\n#endif\n    targetStream = &std::cerr;\n  }\n  else if (streqi(\"stdout\", LogTarget.c_str()))\n  {\n#ifdef AVS_WINDOWS // linux alternative?\n    hConsole = GetStdHandle(STD_OUTPUT_HANDLE);\n#else\n    hConsole = stdout;\n#endif\n    targetStream = &std::cout;\n  }\n  else if (LogFileStream.is_open())\n  {\n    targetStream = &LogFileStream;\n  }\n  else\n  {\n    // Logging not yet set up (SetLogParams() not yet called).\n    // Do nothing.\n    return;\n  }\n\n  // Format our message string\n  std::string msg = FormatString(fmt, va);\n\n#ifdef AVS_WINDOWS\n  // Save current console attributes so that we can restore them later\n  CONSOLE_SCREEN_BUFFER_INFO Info;\n  GetConsoleScreenBufferInfo(hConsole, &Info);\n#endif\n\n  // Do the output\n  std::lock_guard<std::mutex> lock(string_mutex);\n  *targetStream << \"---------------------------------------------------------------------\" << std::endl;\n#ifdef AVS_WINDOWS\n  SetConsoleTextAttribute(hConsole, levelAttr);\n#endif\n  *targetStream << levelStr;\n#ifdef AVS_WINDOWS\n  SetConsoleTextAttribute(hConsole, Info.wAttributes);\n#endif\n  *targetStream << msg << std::endl;\n  targetStream->flush();\n}\n\nvoid ScriptEnvironment::LogMsgOnce(const OneTimeLogTicket& ticket, int level, const char* fmt, ...)\n{\n  va_list val;\n  va_start(val, fmt);\n  LogMsgOnce_valist(ticket, level, fmt, val);\n  va_end(val);\n}\n\nvoid ScriptEnvironment::LogMsgOnce_valist(const OneTimeLogTicket& ticket, int level, const char* fmt, va_list va)\n{\n  if (LogTickets.end() == LogTickets.find(ticket))\n  {\n    LogMsg_valist(level, fmt, va);\n    LogTickets.insert(ticket);\n  }\n}\n\nvoid ScriptEnvironment::SetMaxCPU(const char* features)\n{\n#if defined(ARM64)\n  enum CPUlevel {\n    CL_NONE,\n    CL_NEON,\n    CL_DOTPROD,\n    CL_SVE2,\n    CL_I8MM,\n    CL_SVE2_1\n  };\n#elif defined(X86_32) || defined(X86_64)\n  enum CPUlevel {\n    CL_NONE,\n    CL_MMX,\n    CL_SSE,\n    CL_SSE2,\n    CL_SSE3,\n    CL_SSSE3,\n    CL_SSE4_1,\n    CL_SSE4_2,\n    CL_AVX,\n    CL_AVX2,\n    CL_AVX512_BASE,\n    CL_AVX512_FAST\n  };\n#else\n  enum CPUlevel {\n    CL_NONE\n  };\n#endif\n\n  std::string s;\n  const int len = (int)strlen(features);\n  s.resize(len);\n  for (int i = 0; i < len; i++)\n    s[i] = tolower(features[i]);\n\n  int64_t cpu_flags = GetCPUFlagsEx();\n\n  std::vector<std::string> tokens;\n  std::size_t start = 0, end = 0;\n  while ((end = s.find(',', start)) != std::string::npos) {\n    if (end != start) {\n      tokens.push_back(s.substr(start, end - start));\n    }\n    start = end + 1;\n  }\n  if (end != start) {\n    tokens.push_back(s.substr(start));\n  }\n\n  for (auto token : tokens)\n  {\n    token = trim(token);\n    if (token.empty()) continue;\n\n    int mode = 0; // limit\n\n    char ch = token[token.size() - 1];\n    if (ch == '-') mode = -1; // remove\n    else if (ch == '+') mode = 1; // add\n\n    if (mode != 0)\n      token.resize(token.size() - 1);\n\n    CPUlevel cpulevel = CL_NONE;\n\n    const char* t = token.c_str();\n\n    if (streqi(t, \"\") || streqi(t, \"none\")) cpulevel = CL_NONE;\n#if defined(ARM64)\n    else if (streqi(t, \"neon\")) cpulevel = CL_NEON;\n    else if (streqi(t, \"dotprod\")) cpulevel = CL_DOTPROD;\n    else if (streqi(t, \"sve2\")) cpulevel = CL_SVE2;\n    else if (streqi(t, \"i8mm\")) cpulevel = CL_I8MM;\n    else if (streqi(t, \"sve2.1\")) cpulevel = CL_SVE2_1;\n    // i8mm is just an optional level may not dependent on sve2 and vice versa\n    else ThrowError(\"SetMaxCPU error: cpu level must be empty or none, neon, dotprod or sve2 (%s)\", t);\n#elif defined(X86_32) || defined(X86_64)\n    else if (streqi(t, \"mmx\")) cpulevel = CL_MMX;\n    else if (streqi(t, \"sse\")) cpulevel = CL_SSE;\n    else if (streqi(t, \"sse2\")) cpulevel = CL_SSE2;\n    else if (streqi(t, \"sse3\")) cpulevel = CL_SSE3;\n    else if (streqi(t, \"ssse3\")) cpulevel = CL_SSSE3;\n    else if (streqi(t, \"sse4\") || streqi(t, \"sse4.1\")) cpulevel = CL_SSE4_1;\n    else if (streqi(t, \"sse4.2\")) cpulevel = CL_SSE4_2;\n    else if (streqi(t, \"avx\")) cpulevel = CL_AVX;\n    else if (streqi(t, \"avx2\")) cpulevel = CL_AVX2;\n    else if (streqi(t, \"avx512base\")) cpulevel = CL_AVX512_BASE;\n    else if (streqi(t, \"avx512fast\")) cpulevel = CL_AVX512_FAST;\n    else ThrowError(\"SetMaxCPU error: cpu level must be empty or none, mmx, sse, sse2, sse3, ssse3, sse4 or sse4.1, sse4.2, avx, avx2, avx512base or avx512fast (%s)\", t);\n#else\n    else ThrowError(\"SetMaxCPU error: cpu level must be empty or none (%s)\", t);\n#endif\n\n    if (0 == mode) { // limit\n      // always switch off the more advanced features compared to previous check if limiting\n#if defined(ARM64)\n      if (cpulevel <= CL_SVE2_1) {\n        // already max level, nothing to do\n      }\n      if (cpulevel <= CL_SVE2) {\n        cpu_flags &= ~CPUF_ARM_SVE2_1;\n      }\n      if (cpulevel <= CL_DOTPROD) {\n        cpu_flags &= ~CPUF_ARM_SVE2;\n      }\n      if (cpulevel <= CL_NEON) {\n        cpu_flags &= ~CPUF_ARM_DOTPROD;\n      }\n      if (cpulevel <= CL_NONE) {\n        cpu_flags &= ~CPUF_ARM_NEON; // switch off the most minimal feature\n      }\n\n#elif defined(X86_32) || defined(X86_64)\n      // group feature\n      if (cpulevel <= CL_AVX512_FAST) {\n        // disable all avx512, re-enable the whole mask up to \"fast\"\n        cpu_flags &= ~CPUF_AVX512_MASK;\n        cpu_flags |= CPUF_AVX512_FAST_ALL;\n      }\n      // group feature\n      if (cpulevel <= CL_AVX512_BASE) {\n        // disable all avx512, re-enable the whole mask up to \"base\"\n        cpu_flags &= ~CPUF_AVX512_MASK;\n        cpu_flags |= CPUF_AVX512_BASE_ALL;\n      }\n      // individual features\n      if (cpulevel <= CL_AVX2) // just disable all avx512\n        cpu_flags &= ~CPUF_AVX512_MASK;\n      if (cpulevel <= CL_AVX)\n        cpu_flags &= ~(CPUF_AVX2 | CPUF_FMA3 | CPUF_FMA4 | CPUF_F16C);\n      if (cpulevel <= CL_SSE4_2)\n        cpu_flags &= ~(CPUF_AVX); // switch off AVX, when max is sse4.2, other features already off\n      if (cpulevel <= CL_SSE4_1)\n        cpu_flags &= ~(CPUF_SSE4_2);\n      if (cpulevel <= CL_SSSE3)\n        cpu_flags &= ~(CPUF_SSE4_1);\n      if (cpulevel <= CL_SSE3)\n        cpu_flags &= ~(CPUF_SSSE3);\n      if (cpulevel <= CL_SSE2)\n        cpu_flags &= ~(CPUF_SSE3);\n      if (cpulevel <= CL_SSE)\n        cpu_flags &= ~(CPUF_SSE2);\n      if (cpulevel <= CL_MMX)\n        cpu_flags &= ~(CPUF_SSE | CPUF_INTEGER_SSE); // ?\n      if (cpulevel <= CL_NONE)\n        cpu_flags &= ~(CPUF_MMX);\n#else\n      // nothing to do, only \"none\" exists\n#endif\n    }\n    else {\n      int64_t current_flag;\n      switch (cpulevel) {\n#if defined(ARM64)\n      case CL_SVE2_1: current_flag = CPUF_ARM_SVE2_1; break;\n      case CL_I8MM: current_flag = CPUF_ARM_I8MM; break;\n      case CL_SVE2: current_flag = CPUF_ARM_SVE2; break;\n      case CL_DOTPROD: current_flag = CPUF_ARM_DOTPROD; break;\n      case CL_NEON: current_flag = CPUF_ARM_NEON; break;\n#elif defined(X86_32) || defined(X86_64)\n      case CL_AVX512_FAST: current_flag = CPUF_AVX512_FAST_ALL; break;\n      case CL_AVX512_BASE: current_flag = CPUF_AVX512_BASE_ALL; break;\n      case CL_AVX2: current_flag = CPUF_AVX2 | CPUF_FMA3; break;\n      case CL_AVX: current_flag = CPUF_AVX; break;\n      case CL_SSE4_2: current_flag = CPUF_SSE4_2; break;\n      case CL_SSE4_1: current_flag = CPUF_SSE4_1; break;\n      case CL_SSSE3: current_flag = CPUF_SSSE3; break;\n      case CL_SSE3: current_flag = CPUF_SSE3; break;\n      case CL_SSE2: current_flag = CPUF_SSE2; break;\n      case CL_SSE: current_flag = CPUF_SSE; break;\n      case CL_MMX: current_flag = CPUF_MMX; break;\n#else\n        // nothing to do, only \"none\" exists\n#endif\n      default:\n        current_flag = 0;\n      }\n      if (mode < 0) {\n        if (0 != current_flag)\n          cpu_flags &= ~current_flag; // sse2-: removes sse2\n      }\n      else\n        cpu_flags |= current_flag; // avx2+: adds avx2 and fma3\n      // limit to sse2 and avx2: \"sse2,avx2+\"\n    }\n  }\n\n  cpuFlagsEx = cpu_flags;\n}\n\nClipDataStore* ScriptEnvironment::ClipData(IClip *clip)\n{\n#if ( !defined(_MSC_VER) || (_MSC_VER < 1900) )\n  return &(clip_data.emplace(clip, clip).first->second);\n#else\n  return &(clip_data.try_emplace(clip, clip).first->second);\n#endif\n}\n\nvoid ScriptEnvironment::AdjustMemoryConsumption(size_t amount, bool minus)\n{\n  if (minus)\n    Devices->GetCPUDevice()->memory_used -= amount;\n  else\n    Devices->GetCPUDevice()->memory_used += amount;\n}\n\nvoid ScriptEnvironment::ParallelJob(ThreadWorkerFuncPtr jobFunc, void* jobData, IJobCompletion* completion)\n{\n  thread_pool->QueueJob(jobFunc, jobData, threadEnv.get(), static_cast<JobCompletion*>(completion));\n}\n\nvoid ScriptEnvironment::ParallelJob(ThreadWorkerFuncPtr jobFunc, void* jobData, IJobCompletion* completion, InternalEnvironment* env)\n{\n  thread_pool->QueueJob(jobFunc, jobData, env, static_cast<JobCompletion*>(completion));\n}\n\nvoid ScriptEnvironment::SetFilterMTMode(const char* filter, MtMode mode, bool force)\n{\n  this->SetFilterMTMode(filter, mode, force ? MtWeight::MT_WEIGHT_2_USERFORCE : MtWeight::MT_WEIGHT_1_USERSPEC);\n}\n\nvoid ScriptEnvironment::SetFilterMTMode(const char* filter, MtMode mode, MtWeight weight)\n{\n  assert(NULL != filter);\n  assert(strcmp(\"\", filter) != 0);\n\n  if (((int)mode <= (int)MT_INVALID)\n    || ((int)mode >= (int)MT_MODE_COUNT))\n  {\n    throw AvisynthError(\"Invalid MT mode specified.\");\n  }\n\n  if (streqi(filter, DEFAULT_MODE_SPECIFIER.c_str()))\n  {\n    DefaultMtMode = mode;\n    return;\n  }\n\n  std::string name_to_register;\n  std::string loading;\n  {\n    std::unique_lock<std::recursive_mutex> env_lock(plugin_mutex);\n    loading = plugin_manager->PluginLoading();\n  }\n  if (loading.empty())\n    name_to_register = filter;\n  else\n    name_to_register = loading.append(\"_\").append(filter);\n\n  name_to_register = NormalizeString(name_to_register);\n\n  auto it = MtMap.find(name_to_register);\n  if (it != MtMap.end())\n  {\n    if ((int)weight >= (int)(it->second.second))\n    {\n      it->second.first = mode;\n      it->second.second = weight;\n    }\n  }\n  else\n  {\n    MtMap.emplace(name_to_register, std::make_pair(mode, weight));\n  }\n}\n\nbool ScriptEnvironment::FilterHasMtMode(const Function* filter) const\n{\n  if (filter->name == nullptr) { // no named function\n    return false;\n  }\n  const auto& end = MtMap.end();\n  return (end != MtMap.find(NormalizeString(filter->canon_name)))\n    || (end != MtMap.find(NormalizeString(filter->name)));\n}\n\nstatic bool isValidVSMapKey(const std::string& s); // forward\n\nvoid ScriptEnvironment::SetFilterProp(const char* filter, const char* key, const AVSValue& value, int mode)\n{\n  assert(filter != nullptr && *filter != '\\0');\n  assert(key != nullptr);\n\n  if (!isValidVSMapKey(std::string(key)))\n    ThrowError(\"SetFilterProp: invalid property key '%s'. Must start with a letter or underscore, \"\n               \"followed only by letters, digits and underscores.\", key);\n\n  if (mode != AVSPropAppendMode::PROPAPPENDMODE_REPLACE\n    && mode != AVSPropAppendMode::PROPAPPENDMODE_APPEND\n    && mode != AVSPropAppendMode::PROPAPPENDMODE_TOUCH)\n    ThrowError(\"SetFilterProp: invalid mode %d for filter '%s', key '%s'.\", mode, filter, key);\n\n  std::string name_to_register;\n  std::string loading;\n  {\n    std::unique_lock<std::recursive_mutex> env_lock(plugin_mutex);\n    loading = plugin_manager->PluginLoading();\n  }\n  if (loading.empty())\n    name_to_register = filter;\n  else\n    name_to_register = loading + \"_\" + filter;\n\n  name_to_register = NormalizeString(name_to_register);\n\n  FilterPropMap[name_to_register].push_back(PropEntry{ std::string(key), value, mode, {}, AVSValue() });\n}\n\nvoid ScriptEnvironment::SetFilterPropConditional(const char* filter, const char* param_name,\n  const AVSValue& param_match, const char* key, const AVSValue& value, int mode)\n{\n  assert(filter != nullptr && *filter != '\\0');\n  assert(param_name != nullptr && *param_name != '\\0');\n  assert(key != nullptr);\n\n  if (!isValidVSMapKey(std::string(key)))\n    ThrowError(\"SetFilterProp: invalid property key '%s'. Must start with a letter or underscore, \"\n               \"followed only by letters, digits and underscores.\", key);\n\n  if (mode != AVSPropAppendMode::PROPAPPENDMODE_REPLACE\n    && mode != AVSPropAppendMode::PROPAPPENDMODE_APPEND\n    && mode != AVSPropAppendMode::PROPAPPENDMODE_TOUCH)\n    ThrowError(\"SetFilterProp: invalid mode %d for filter '%s', key '%s'.\", mode, filter, key);\n\n  std::string name_to_register;\n  std::string loading;\n  {\n    std::unique_lock<std::recursive_mutex> env_lock(plugin_mutex);\n    loading = plugin_manager->PluginLoading();\n  }\n  if (loading.empty())\n    name_to_register = filter;\n  else\n    name_to_register = loading + \"_\" + filter;\n\n  name_to_register = NormalizeString(name_to_register);\n\n  FilterPropMap[name_to_register].push_back(PropEntry{ std::string(key), value, mode,\n                                                        std::string(param_name), param_match });\n}\n\nvoid ScriptEnvironment::SetFilterPropPassthrough(const char* filter)\n{\n  assert(filter != nullptr && *filter != '\\0');\n\n  std::string name_to_register;\n  std::string loading;\n  {\n    std::unique_lock<std::recursive_mutex> env_lock(plugin_mutex);\n    loading = plugin_manager->PluginLoading();\n  }\n  if (loading.empty())\n    name_to_register = filter;\n  else\n    name_to_register = loading + \"_\" + filter;\n\n  FilterPropPassthroughSet.insert(NormalizeString(name_to_register));\n}\n\nconst char* ScriptEnvironment::GetFilterProps()\n{\n  std::string json = \"[\\n\";\n  bool first = true;\n  for (const auto& kv : FilterPropMap) {\n    for (const auto& entry : kv.second) {\n      if (!first) json += \",\\n\";\n      first = false;\n      json += \"  {\\\"filter\\\":\\\"\" + kv.first + \"\\\",\\\"key\\\":\\\"\" + entry.key + \"\\\"\";\n      if (!entry.param_name.empty()) {\n        json += \",\\\"when_param\\\":\\\"\" + entry.param_name + \"\\\",\\\"when_value\\\":\";\n        // param_match can be a scalar or an alias array\n        auto serializeScalar = [&](const AVSValue& v) -> std::string {\n          if (v.IsString()) return \"\\\"\" + std::string(v.AsString()) + \"\\\"\";\n          if (v.IsInt())    return std::to_string(v.AsLong());\n          if (v.IsFloat())  return double_to_string(v.AsFloat());\n          if (v.IsBool())   return v.AsBool() ? \"true\" : \"false\";\n          return \"null\";\n        };\n        if (entry.param_match.IsArray()) {\n          json += \"[\";\n          for (int j = 0; j < entry.param_match.ArraySize(); ++j) {\n            if (j > 0) json += \",\";\n            json += serializeScalar(entry.param_match[j]);\n          }\n          json += \"]\";\n        } else {\n          json += serializeScalar(entry.param_match);\n        }\n      }\n      json += \",\";\n      if (entry.value.IsFunction()) {\n        json += \"\\\"type\\\":\\\"function\\\",\\\"value\\\":null\";\n      } else if (entry.value.IsInt()) {\n        json += \"\\\"type\\\":\\\"int\\\",\\\"value\\\":\" + std::to_string(entry.value.AsLong());\n      } else if (entry.value.IsBool()) {\n        // bool values are converted to int at registration; this branch is a safety net\n        json += \"\\\"type\\\":\\\"int\\\",\\\"value\\\":\" + std::to_string(entry.value.AsBool() ? 1 : 0);\n      } else if (entry.value.IsFloat()) {\n        json += \"\\\"type\\\":\\\"float\\\",\\\"value\\\":\" + double_to_string(entry.value.AsFloat());\n      } else if (entry.value.IsString()) {\n        std::string escaped;\n        for (unsigned char c : std::string(entry.value.AsString())) {\n          if      (c == '\"')  escaped += \"\\\\\\\"\";\n          else if (c == '\\\\') escaped += \"\\\\\\\\\";\n          else if (c == '\\n') escaped += \"\\\\n\";\n          else if (c == '\\r') escaped += \"\\\\r\";\n          else                escaped += c;\n        }\n        json += \"\\\"type\\\":\\\"string\\\",\\\"value\\\":\\\"\" + escaped + \"\\\"\";\n      } else if (!entry.value.Defined()) {\n        json += \"\\\"type\\\":\\\"capture\\\",\\\"value\\\":null\"; // undefined(): capture from named call arg\n      } else {\n        json += \"\\\"type\\\":\\\"unknown\\\",\\\"value\\\":null\";\n      }\n      json += \",\\\"mode\\\":\" + std::to_string(entry.mode) + \"}\";\n    }\n  }\n  json += \"\\n]\";\n  return threadEnv->SaveString(json.c_str(), (int)json.size());\n}\n\nMtMode ScriptEnvironment::GetFilterMTMode(const Function* filter, bool* is_forced) const\n{\n  assert(NULL != filter);\n  if (filter->name == nullptr) { // no named function\n    *is_forced = false;\n    return DefaultMtMode;\n  }\n\n  assert(NULL != filter->name);\n  assert(NULL != filter->canon_name);\n\n  auto it = MtMap.find(NormalizeString(filter->canon_name));\n  if (it != MtMap.end())\n  {\n    *is_forced = it->second.second == MtWeight::MT_WEIGHT_2_USERFORCE;\n    return it->second.first;\n  }\n\n  it = MtMap.find(NormalizeString(filter->name));\n  if (it != MtMap.end())\n  {\n    *is_forced = it->second.second == MtWeight::MT_WEIGHT_2_USERFORCE;\n    return it->second.first;\n  }\n\n  *is_forced = false;\n  return DefaultMtMode;\n}\n\n/* This function adds information about builtin functions into global variables.\n * External utilities (like AvsPmod) can parse these variables and use them\n * to learn about supported functions and their syntax.\n */\nvoid ScriptEnvironment::ExportBuiltinFilters()\n{\n  std::string FunctionList;\n  FunctionList.reserve(512);\n  const size_t NumFunctionArrays = sizeof(builtin_functions) / sizeof(builtin_functions[0]);\n  for (size_t i = 0; i < NumFunctionArrays; ++i)\n  {\n    for (const AVSFunction* f = builtin_functions[i]; !f->empty(); ++f)\n    {\n      // This builds the $InternalFunctions$ variable, which is a list of space-delimited\n      // function names. Utilities can learn the names of the builtin function from this.\n      FunctionList.append(f->name);\n      FunctionList.push_back(' ');\n\n      // For each supported function, a global variable is added with <param_var_name> as the name,\n      // and the list of parameters to that function as the value.\n      std::string param_var_name;\n      param_var_name.reserve(128);\n      param_var_name.append(\"$Plugin!\");\n      param_var_name.append(f->name);\n      param_var_name.append(\"!Param$\");\n      threadEnv->SetGlobalVar(threadEnv->SaveString(param_var_name.c_str(), (int)param_var_name.size()), AVSValue(f->param_types));\n    }\n  }\n\n  // Save $InternalFunctions$\n  threadEnv->SetGlobalVar(\"$InternalFunctions$\", AVSValue(threadEnv->SaveString(FunctionList.c_str(), (int)FunctionList.size())));\n}\n\nsize_t  ScriptEnvironment::GetEnvProperty(AvsEnvProperty prop)\n{\n  switch (prop)\n  {\n  case AEP_NUM_DEVICES:\n    return Devices->GetNumDevices();\n  case AEP_FRAME_ALIGN:\n    return frame_align;\n  case AEP_PLANE_ALIGN:\n    return plane_align;\n  case AEP_FILTERCHAIN_THREADS:\n    return nMaxFilterInstances;\n  case AEP_PHYSICAL_CPUS:\n    return GetNumPhysicalCPUs();\n  case AEP_CACHESIZE_L2:\n    return cache_size_L2;\n  case AEP_LOGICAL_CPUS:\n    return std::thread::hardware_concurrency();\n  case AEP_THREAD_ID:\n    return 0;\n  case AEP_THREADPOOL_THREADS:\n    return thread_pool->NumThreads();\n  case AEP_VERSION:\n#ifdef RELEASE_TARBALL\n    return 0;\n#else\n    return AVS_SEQREV;\n#endif\n  case AEP_HOST_SYSTEM_ENDIANNESS:\n    return (uintptr_t)AVS_ENDIANNESS;\n  case AEP_INTERFACE_VERSION:\n    return AVISYNTH_INTERFACE_VERSION;\n  case AEP_INTERFACE_BUGFIX:\n    return AVISYNTHPLUS_INTERFACE_BUGFIX_VERSION;\n  default:\n    this->ThrowError(\"Invalid property request.\");\n    return std::numeric_limits<size_t>::max();\n  }\n\n  assert(0);\n}\n\nbool ScriptEnvironment::LoadPlugin(const char* filePath, bool throwOnError, AVSValue *result)\n{\n  // Autoload needed to ensure that manual LoadPlugin() calls always override autoloaded plugins.\n  // For that, autoloading must happen before any LoadPlugin(), so we force an\n  // autoload operation before any LoadPlugin().\n  std::unique_lock<std::recursive_mutex> env_lock(plugin_mutex);\n\n  this->AutoloadPlugins();\n  return plugin_manager->LoadPlugin(filePath, throwOnError, result);\n}\n\nvoid ScriptEnvironment::AddAutoloadDir(const char* dirPath, bool toFront)\n{\n  std::unique_lock<std::recursive_mutex> env_lock(plugin_mutex);\n  plugin_manager->AddAutoloadDir(dirPath, toFront);\n}\n\nvoid ScriptEnvironment::ClearAutoloadDirs()\n{\n  std::unique_lock<std::recursive_mutex> env_lock(plugin_mutex);\n  plugin_manager->ClearAutoloadDirs();\n}\n\nchar* ScriptEnvironment::ListAutoloadDirs()\n{\n  std::unique_lock<std::recursive_mutex> env_lock(plugin_mutex);\n\n  std::string str = plugin_manager->ListAutoloadDirs();\n  return threadEnv->SaveString(str.c_str(), (int)str.size());\n}\n\nvoid ScriptEnvironment::AutoloadPlugins()\n{\n  std::unique_lock<std::recursive_mutex> env_lock(plugin_mutex);\n  plugin_manager->AutoloadPlugins();\n}\n\nint ScriptEnvironment::SetMemoryMax(int mem) {\n\n  Device* cpuDevice = Devices->GetCPUDevice();\n  if (mem > 0)  /* If mem is zero, we should just return current setting */\n    cpuDevice->memory_max = ConstrainMemoryRequest(mem * 1048576ull);\n\n  return (int)(cpuDevice->memory_max / 1048576ull);\n}\n\nint ScriptEnvironment::SetWorkingDir(const char* newdir) {\n  return SetCurrentDirectory(newdir) ? 0 : 1;\n}\n\nvoid ScriptEnvironment::CheckVersion(int version) {\n  if (version > AVISYNTH_INTERFACE_VERSION)\n    ThrowError(\"Plugin was designed for a later version of Avisynth (%d)\", version);\n}\n\nint ScriptEnvironment::GetCPUFlags() { return cpuFlagsEx & 0xFFFFFFFF; }\nint64_t ScriptEnvironment::GetCPUFlagsEx() { return cpuFlagsEx; }\n\nvoid ScriptEnvironment::AddFunction(const char* name, const char* params, ApplyFunc apply, void* user_data) {\n  this->AddFunction(name, params, apply, user_data, NULL);\n}\n\n// called from IScriptEnvironment_Avs25\nvoid ScriptEnvironment::AddFunction25(const char* name, const char* params, ApplyFunc apply, void* user_data) {\n  std::unique_lock<std::recursive_mutex> env_lock(plugin_mutex);\n  plugin_manager->AddFunction(name, params, apply, user_data, NULL, true, false);\n}\n\n// called from IScriptEnvironment_AvsPreV11C\nvoid ScriptEnvironment::AddFunctionPreV11C(const char* name, const char* params, ApplyFunc apply, void* user_data) {\n  std::unique_lock<std::recursive_mutex> env_lock(plugin_mutex);\n  plugin_manager->AddFunction(name, params, apply, user_data, NULL, false, true);\n}\n\nvoid ScriptEnvironment::AddFunction(const char* name, const char* params, ApplyFunc apply, void* user_data, const char *exportVar) {\n  std::unique_lock<std::recursive_mutex> env_lock(plugin_mutex);\n  plugin_manager->AddFunction(name, params, apply, user_data, exportVar, false, false);\n}\n\nVideoFrame* ScriptEnvironment::AllocateFrame(size_t vfb_size, size_t margin, Device* device)\n{\n  if (vfb_size > (size_t)std::numeric_limits<int>::max())\n  {\n    throw AvisynthError(threadEnv->Sprintf(\"Requested buffer size of %zu is too large\", vfb_size));\n  }\n\n  VFBStorage* vfb = NULL;\n  try\n  {\n    vfb = new VFBStorage((int)vfb_size, (int)margin, device);\n  }\n  catch(const std::bad_alloc&)\n  {\n    return NULL;\n  }\n\n  VideoFrame *new_frame = NULL;\n  try\n  {\n    new_frame = new VideoFrame(vfb, new AVSMap(), 0, 0, 0, 0, VideoInfo::CS_UNKNOWN);\n  }\n  catch(const std::bad_alloc&)\n  {\n    delete vfb;\n    return NULL;\n  }\n\n  device->memory_used += vfb_size;\n  vfb->Attach(threadEnv->GetCurrentGraphNode());\n\n  // automatically inserts keys if they not exist!\n  // no locking here, calling method have done it already\n  FrameRegistry2[vfb_size][vfb].push_back(DebugTimestampedFrame(new_frame));\n\n  //_RPT1(0, \"ScriptEnvironment::AllocateFrame %zu frame=%p vfb=%p %\" PRIu64 \"\\n\", vfb_size, newFrame, newFrame->vfb, memory_used);\n\n  return new_frame;\n}\n\n#ifdef _DEBUG\n\nstatic void DebugOut(char* s)\n{\n#ifdef AVS_POSIX\n  LogMsg(LOGLEVEL_DEBUG, s);\n#else\n  _RPT0(0, s);\n#endif\n}\n\nvoid ScriptEnvironment::ListFrameRegistry(size_t min_size, size_t max_size, bool someframes)\n{\n  char buf[1024];\n  //#define FULL_LIST_OF_VFBs\n  //#define LIST_ALSO_SOME_FRAMES\n  int size1 = 0;\n  int size2 = 0;\n  int size3 = 0;\n  snprintf(buf, 1023, \"******** %p <= FrameRegistry2 Address. Buffer list for size between %7zu and %7zu\\n\", &FrameRegistry2, min_size, max_size);\n  DebugOut(buf);\n  snprintf(buf, 1023, \">> IterateLevel #1: Different vfb sizes: FrameRegistry2.size=%zu \\n\", FrameRegistry2.size());\n  DebugOut(buf);\n  size_t total_vfb_size = 0;\n  auto t_end = std::chrono::high_resolution_clock::now();\n\n  // list to debugview: all frames up-to vfb_size size\n  for (FrameRegistryType2::iterator it = FrameRegistry2.lower_bound(min_size), end_it = FrameRegistry2.upper_bound(max_size);\n    it != end_it;\n    ++it)\n  {\n    size1++;\n    _RPT3(0, \">>>> IterateLevel #2 [%3d]: Vfb count for size %7zu is %7zu\\n\", size1, it->first, it->second.size());\n    for (auto &it2: it->second)\n    {\n      size2++;\n      VFBStorage* vfb = static_cast<VFBStorage*>(it2.first);\n      total_vfb_size += vfb->GetDataSize();\n      size_t inner_frame_count_size = it2.second.size();\n#ifdef ALTERNATIVE_VFB_TIMESTAMP\n      snprintf(buf, 1023, \">>>> IterateLevel #3 %5zu frames in [%3d,%5d] --> vfb=%p vfb_refcount=%3ld vfb_timestamp=%\" PRId64 \" seqNum=%d\\n\", inner_frame_count_size, size1, size2, vfb, vfb->refcount, vfb->last_freed_timestamp.load(), vfb->GetSequenceNumber());\n#else\n      snprintf(buf, 1023, \">>>> IterateLevel #3 %5zu frames in [%3d,%5d] --> vfb=%p vfb_refcount=%3ld seqNum=%d\\n\", inner_frame_count_size, size1, size2, vfb, vfb->refcount, vfb->GetSequenceNumber());\n#endif\n      DebugOut(buf);\n      // iterate the frame list of this vfb\n      int inner_frame_count = 0;\n      int inner_frame_count_for_frame_refcount_nonzero = 0;\n      for (auto &it3: it2.second)\n      {\n        size3++;\n        inner_frame_count++;\n#ifdef _DEBUG\n        VideoFrame* frame = it3.frame;\n        std::chrono::time_point<std::chrono::high_resolution_clock> frame_entry_timestamp = it3.timestamp;\n#else\n        VideoFrame* frame = it3;\n#endif\n        if (0 != frame->refcount)\n          inner_frame_count_for_frame_refcount_nonzero++;\n        if (someframes)\n        {\n          std::chrono::duration<double> elapsed_seconds = t_end - frame_entry_timestamp;\n          if (inner_frame_count <= 4) // list only the first 2. There can be even many thousand of frames!\n          {\n            // log only if frame creation timestamp is too old!\n            // e.g. 100 secs, it must be a stuck frame (but can also be a valid static frame from ColorBars)\n            // if (elapsed_seconds.count() > 100.0f && frame->refcount > 0)\n            //if (frame->refcount > 0)\n            {\n              snprintf(buf, 1023, \"  >> Frame#%6d: vfb=%p frame=%p frame_refcount=%3ld T=%f ago\\n\", inner_frame_count, vfb, frame, frame->refcount, elapsed_seconds.count());\n              DebugOut(buf);\n            }\n          }\n          else if (inner_frame_count == inner_frame_count_size - 1)\n          {\n            // log the last one\n            if (frame->refcount > 0)\n            {\n              snprintf(buf, 1023, \"  ...Frame#%6d: vfb=%p frame=%p frame_refcount=%3ld \\n\", inner_frame_count, vfb, frame, frame->refcount);\n              DebugOut(buf);\n            }\n            _RPT2(0, \"  == TOTAL of %d frames. Number of nonzero refcount=%d \\n\", inner_frame_count, inner_frame_count_for_frame_refcount_nonzero);\n          }\n          if (0 == vfb->refcount && 0 != frame->refcount)\n          {\n            snprintf(buf, 1023, \"  ########## VFB=0 FRAME!=0 ####### VFB: %p Frame:%p frame_refcount=%3ld \\n\", vfb, frame, frame->refcount);\n            DebugOut(buf);\n          }\n        }\n      }\n      // After the inner loop, always print summary:\n      snprintf(buf, 1023, \"  == TOTAL of %d frames. nonzero refcount=%d \\n\",\n        inner_frame_count, inner_frame_count_for_frame_refcount_nonzero);\n      DebugOut(buf);\n    }\n  }\n  snprintf(buf, 1023, \">> >> >> array sizes %d %d %d Total VFB size=%zu\\n\", size1, size2, size3, total_vfb_size);\n  DebugOut(buf);\n  snprintf(buf, 1023, \"  ----------------------------\\n\");\n  DebugOut(buf);\n}\n#endif\n\n#ifndef ALTERNATIVE_VFB_TIMESTAMP\nVideoFrame* ScriptEnvironment::GetFrameFromRegistry(size_t vfb_size, Device* device)\n{\n#ifdef _DEBUG\n  std::chrono::time_point<std::chrono::high_resolution_clock> t_start, t_end; // std::chrono::time_point<std::chrono::system_clock> t_start, t_end;\n  t_start = std::chrono::high_resolution_clock::now();\n#endif\n\n  // FrameRegistry2 is like: map<key1, map<key2, vector<VideoFrame *>> >\n  // typedef std::vector<VideoFrame*> VideoFrameArrayType;\n  // typedef std::map<VideoFrameBuffer *, VideoFrameArrayType> FrameBufferRegistryType;\n  // typedef std::map<size_t, FrameBufferRegistryType> FrameRegistryType2;\n  // [vfb_size = 10000][vfb = 0x111111111] [frame = 0x129837192(,timestamp=xxx)]\n  //                                       [frame = 0x012312122(,timestamp=xxx)]\n  //                                       [frame = 0x232323232(,timestamp=xxx)]\n  //                   [vfb = 0x222222222] [frame = 0x333333333(,timestamp=xxx)]\n  //                                       [frame = 0x444444444(,timestamp=xxx)]\n  // Which is better?\n  // - found exact vfb_size or\n  // - allow reusing existing vfb's with size up to size_to_find*1.5 THIS ONE!\n  // - allow to occupy any buffer that is bigger than the requested size\n  //for (FrameRegistryType2::iterator it = FrameRegistry2.lower_bound(vfb_size), end_it = FrameRegistry2.upper_bound(vfb_size); // exact! no-go. special service clips can fragment it\n  //for (FrameRegistryType2::iterator it = FrameRegistry2.lower_bound(vfb_size), end_it = FrameRegistry2.end(); // vfb_size or bigger, so a 100K size would claim a 1.5M space.\n  for (FrameRegistryType2::iterator it = FrameRegistry2.lower_bound(vfb_size), end_it = FrameRegistry2.upper_bound(vfb_size * 3 / 2); // vfb_size or at most 1.5* bigger\n    it != end_it;\n    ++it)\n  {\n    for (auto &it2: it->second)\n    {\n      VFBStorage *vfb = static_cast<VFBStorage*>(it2.first); // same for all map content, the key is vfb pointer\n      if (device == vfb->device && 0 == vfb->refcount) // vfb device and refcount check\n      {\n        size_t videoFrameListSize = it2.second.size();\n        // size is more than one if SubFrame was used to create a new frame\n        VideoFrame *frame_found;\n        bool found = false;\n        for (VideoFrameArrayType::iterator it3 = it2.second.begin(), end_it3 = it2.second.end();\n          it3 != end_it3;\n          /* ++it3 not here, because of the delete */)\n        {\n          VideoFrame *frame = it3->frame;\n\n          // sanity check if its refcount is zero\n          // because when a vfb is free (refcount==0) then all its parent frames should also be free\n          assert(0 == frame->refcount);\n\n          // Note: Release() does not free 'properties'; FrameRegistry is the sole owner.\n          // An Avisynth 2.5 filter (\"baked code\" in ancient avisynth.h) can set refcount\n          // to zero without freeing extra frame data, so nullptr is not guaranteed here.\n          // Clear content now to promptly free any large strings/arrays.\n          if (frame->properties != nullptr)\n            frame->properties->clear();\n\n          if (!found)\n          {\n            InterlockedIncrement(&(frame->vfb->refcount)); // same as &(vfb->refcount)\n            vfb->free_count = 0; // reset free count\n            vfb->Attach(threadEnv->GetCurrentGraphNode());\n#ifdef _DEBUG\n            char buf[256];\n            t_end = std::chrono::high_resolution_clock::now();\n            std::chrono::duration<double> elapsed_seconds = t_end - t_start;\n            snprintf(buf, 255, \"ScriptEnvironment::GetNewFrame NEW METHOD EXACT hit! VideoFrameListSize=%7zu GotSize=%7zu FrReg.Size=%6zu vfb=%p frame=%p SeekTime:%f\\n\", videoFrameListSize, vfb_size, FrameRegistry2.size(), vfb, frame, elapsed_seconds.count());\n            _RPT0(0, buf);\n            _RPT5(0, \"                                          frame %p RowSize=%d Height=%d Pitch=%d Offset=%d\\n\", frame, frame->GetRowSize(), frame->GetHeight(), frame->GetPitch(), frame->GetOffset());\n#endif\n            // properties was cleared above; create the AVSMap shell only if somehow null\n            if (frame->properties == nullptr)\n              frame->properties = new AVSMap();\n            // only 1 frame in list -> no delete\n            if (videoFrameListSize <= 1)\n            {\n              _RPT1(0, \"ScriptEnvironment::GetNewFrame returning frame. VideoFrameListSize was 1\\n\", videoFrameListSize);\n#ifdef _DEBUG\n              it3->timestamp = std::chrono::high_resolution_clock::now(); // refresh timestamp!\n#endif\n              return frame; // return immediately\n            }\n            // more than X: just registered the frame found, and erase all other frames from list plus delete frame objects also\n            frame_found = frame;\n            found = true;\n            ++it3;\n          }\n          else {\n            // if the first frame to this vfb was already found, then we free all others and delete it from the list\n            // Benefit: no 4-5k frame list count per a single vfb.\n            //_RPT4(0, \"ScriptEnvironment::GetNewFrame Delete one frame %p RowSize=%d Height=%d Pitch=%d Offset=%d\\n\", frame, frame->GetRowSize(), frame->GetHeight(), frame->GetPitch(), frame->GetOffset());\n            delete frame;\n            ++it3;\n          }\n        } // for it3\n        if (found)\n        {\n          _RPT1(0, \"ScriptEnvironment::GetNewFrame returning frame_found. clearing frames. List count: it2->second.size(): %7zu \\n\", it2.second.size());\n          it2.second.clear();\n          it2.second.reserve(16); // initial capacity set to 16, avoid reallocation when 1st, 2nd, etc.. elements pushed later (possible speedup)\n          it2.second.push_back(DebugTimestampedFrame(frame_found)); // keep only the first\n#ifdef _DEBUG\n          //ListFrameRegistry(vfb_size, vfb_size, true); // for chasing stuck frames\n          //ListFrameRegistry(0, vfb_size, true); // for chasing stuck frames\n#endif\n          return frame_found;\n        }\n      }\n    } // for it2\n  } // for it\n  _RPT3(0, \"ScriptEnvironment::GetNewFrame, no free entry in FrameRegistry. Requested vfb size=%zu memused=%\" PRIu64 \" memmax=%\" PRIu64 \"\\n\", vfb_size, device->memory_used.load(), device->memory_max);\n\n#ifdef _DEBUG\n  //ListFrameRegistry(vfb_size, vfb_size, true); // for chasing stuck frames\n  //ListFrameRegistry(0, vfb_size, true); // for chasing stuck frames\n#endif\n\n  return NULL;\n}\n#else\n\n// A newer method which returns the most recently freed vfb\nVideoFrame* ScriptEnvironment::GetFrameFromRegistry(size_t vfb_size, Device* device)\n{\n#ifdef _DEBUG\n  std::chrono::time_point<std::chrono::high_resolution_clock> t_start, t_end;\n  t_start = std::chrono::high_resolution_clock::now();\n#endif\n\n  for (FrameRegistryType2::iterator it = FrameRegistry2.lower_bound(vfb_size), end_it = FrameRegistry2.upper_bound(vfb_size * 3 / 2);\n    it != end_it;\n    ++it)\n  {\n    // Find VFB with _highest_ last_freed_timestamp (most recently freed)\n    VFBStorage* best_vfb = nullptr;\n    int64_t best_timestamp = -1;\n    FrameBufferRegistryType::iterator best_it2 = it->second.end();\n\n    // FIXME: size of frame registry? - Here we do always full scan.\n    // Unlike the old method which returns first free.\n    for (auto it2 = it->second.begin(); it2 != it->second.end(); ++it2)\n    {\n      VFBStorage* vfb = static_cast<VFBStorage*>(it2->first);\n      if (device == vfb->device && 0 == vfb->refcount)\n      {\n        int64_t timestamp = vfb->last_freed_timestamp.load();\n        if (timestamp > best_timestamp)\n        {\n          best_timestamp = timestamp;\n          best_vfb = vfb;\n          best_it2 = it2;\n        }\n      }\n\n    }\n\n    if (best_vfb != nullptr)\n    {\n      auto& it2 = best_it2;\n      VFBStorage* vfb = best_vfb;\n\n      // Process the most recently freed VFB (LRU strategy for better cache locality)\n      // This new version is likely better because it prefers recently-used memory\n      // (better cache performance), while the old version just grabs the first available match.\n      size_t videoFrameListSize = it2->second.size();\n      VideoFrame* frame_found = nullptr;\n      bool found = false;\n\n      for (VideoFrameArrayType::iterator it3 = it2->second.begin(), end_it3 = it2->second.end();\n        it3 != end_it3;\n        /* ++it3 not here, because of the delete */)\n      {\n        VideoFrame* frame = it3->frame;\n        assert(0 == frame->refcount);\n\n        // Clear content now to promptly free any large strings/arrays.\n        if (frame->properties != nullptr)\n          frame->properties->clear();\n\n        if (!found)\n        {\n          InterlockedIncrement(&(frame->vfb->refcount));\n          vfb->free_count = 0;\n          vfb->Attach(threadEnv->GetCurrentGraphNode());\n\n#ifdef _DEBUG\n          char buf[256];\n          t_end = std::chrono::high_resolution_clock::now();\n          std::chrono::duration<double> elapsed_seconds = t_end - t_start;\n          snprintf(buf, 255, \"ScriptEnvironment::GetNewFrame NEW METHOD EXACT hit! VideoFrameListSize=%7zu GotSize=%7zu FrReg.Size=%6zu vfb=%p frame=%p timestamp=%\" PRId64 \" SeqNum=%d SeekTime:%f\\n\", videoFrameListSize, vfb_size, FrameRegistry2.size(), vfb, frame, vfb->last_freed_timestamp.load(), vfb->GetSequenceNumber(), elapsed_seconds.count());\n          _RPT0(0, buf);\n#endif\n\n          // properties was cleared above; create the AVSMap shell only if somehow null\n          if (frame->properties == nullptr)\n            frame->properties = new AVSMap();\n          frame_found = frame;\n          found = true;\n\n#ifdef _DEBUG\n          it3->timestamp = std::chrono::high_resolution_clock::now();\n#endif\n          ++it3;\n        }\n        else {\n          delete frame; // ~VideoFrame()/DESTRUCTOR() deletes frame->properties\n          ++it3;\n        }\n      } // for it3\n\n      if (found)\n      {\n        _RPT2(0, \"ScriptEnvironment::GetNewFrame returning frame_found. clearing frames. List count: %7zu timestamp=%\" PRId64 \" SeqNum=%d\\n\", it2->second.size(), vfb->last_freed_timestamp.load(), vfb->GetSequenceNumber());\n        it2->second.clear();\n        it2->second.reserve(16);\n        it2->second.push_back(DebugTimestampedFrame(frame_found));\n\n#ifdef _DEBUG\n        ListFrameRegistry(vfb_size, vfb_size, true);\n        ListFrameRegistry(0, vfb_size, true);\n#endif\n        return frame_found;\n      }\n    }\n  } // for it\n\n  _RPT3(0, \"ScriptEnvironment::GetNewFrame, no free entry in FrameRegistry. Requested vfb size=%zu memused=%\" PRIu64 \" memmax=%\" PRIu64 \"\\n\", vfb_size, device->memory_used.load(), device->memory_max);\n#ifdef _DEBUG\n  ListFrameRegistry(vfb_size, vfb_size, true);\n  ListFrameRegistry(0, vfb_size, true);\n#endif\n  return NULL;\n}\n#endif\n\nVideoFrame* ScriptEnvironment::GetNewFrame(size_t vfb_size, size_t margin, Device* device)\n{\n  std::unique_lock<std::recursive_mutex> env_lock(memory_mutex);\n\n  // prevent fragmentation of vfb buffer list many different small-sized vfb's\n  if (vfb_size < 64) vfb_size = 64;\n  else if (vfb_size < 256) vfb_size = 256;\n  else if (vfb_size < 512) vfb_size = 512;\n  else if (vfb_size < 1024) vfb_size = 1024;\n  else if (vfb_size < 2048) vfb_size = 2048;\n  else if (vfb_size < 4096) vfb_size = 4096;\n\n  /* -----------------------------------------------------------\n   *   Try to return an unused but already allocated instance\n   * -----------------------------------------------------------\n   */\n  VideoFrame* frame = GetFrameFromRegistry(vfb_size, device);\n  if (frame != NULL)\n    return frame;\n\n  /* -----------------------------------------------------------\n     *   No unused instance was found, try to allocate a new one\n   * -----------------------------------------------------------\n   */\n   // We reserve 15% for unaccounted stuff\n  if (device->memory_used + vfb_size < device->memory_max * 0.85f) {\n    frame = AllocateFrame(vfb_size, margin, device);\n  }\n  if (frame != NULL)\n    return frame;\n\n#ifdef _DEBUG\n  // #define LIST_CACHES\n  // list all cache_entries\n#ifdef LIST_CACHES\n  int cache_counter = 0;\n  for (auto &cit: CacheRegistry)\n  {\n    cache_counter++;\n    AvsCache* cache = cit;\n    int cache_size = cache->SetCacheHints(CACHE_GET_SIZE, 0);\n    _RPT4(0, \"  cache#%d cache_ptr=%p cache_size=%d \\n\", cache_counter, (void*)cache, cache_size); // let's see what's in the cache\n  }\n#endif\n#endif\n\n  /* -----------------------------------------------------------\n  * Couldn't allocate, shrink cache and get more unused frames\n  * -----------------------------------------------------------\n  */\n  ShrinkCache(device);\n\n  /* -----------------------------------------------------------\n  *   Try to return an unused frame again\n  * -----------------------------------------------------------\n  */\n  frame = GetFrameFromRegistry(vfb_size, device);\n  if (frame != NULL)\n    return frame;\n\n  /* -----------------------------------------------------------\n  *   Try to allocate again\n  * -----------------------------------------------------------\n  */\n  frame = AllocateFrame(vfb_size, margin, device);\n  if (frame != NULL)\n    return frame;\n\n  OneTimeLogTicket ticket(LOGTICKET_W1100);\n  LogMsgOnce(ticket, LOGLEVEL_WARNING, \"Memory reallocation occurs. This will probably degrade performance. You can try increasing the limit using SetMemoryMax().\");\n\n  /* -----------------------------------------------------------\n   * No frame found, free all the unused frames!!!\n   * -----------------------------------------------------------\n   */\n  _RPT1(0, \"Allocate failed. GC start memory_used=%\" PRIu64 \"\\n\", device->memory_used.load());\n  // unfortunately if we reach here, only 0 or 1 vfbs or frames can be freed, from lower vfb sizes\n  // usually it's not enough\n  // yet it is true that it's meaningful only to free up smaller vfb sizes here\n  for (FrameRegistryType2::iterator it = FrameRegistry2.begin(), end_it = FrameRegistry2.upper_bound(vfb_size);\n    it != end_it;\n    ++it)\n  {\n    for (FrameBufferRegistryType::iterator it2 = (it->second).begin(), end_it2 = (it->second).end();\n      it2 != end_it2;\n      /*++it2: not here: may delete iterator position */)\n    {\n      VFBStorage *vfb = static_cast<VFBStorage*>(it2->first);\n      if (device == vfb->device && 0 == vfb->refcount) // vfb refcount check\n      {\n        vfb->device->memory_used -= vfb->GetDataSize(); // frame->vfb->GetDataSize();\n        delete vfb;\n        for (auto &it3: it2->second)\n        {\n          VideoFrame *currentframe = it3.frame;\n          assert(0 == currentframe->refcount);\n          delete currentframe;\n        }\n        // delete array belonging to this vfb in one step\n        it2->second.clear(); // clear frame list\n        it2 = (it->second).erase(it2); // clear current vfb\n      }\n      else ++it2;\n    }\n  }\n  _RPT1(0, \"End of garbage collection A memused=%\" PRIu64 \"\\n\", device->memory_used.load());\n#if 0\n  static int counter = 0;\n  char buf[200]; sprintf(buf, \"Re allocation %d\\r\\n\", counter++);\n  OutputDebugStringA(buf);\n#endif\n  /* -----------------------------------------------------------\n   *   Try to allocate again\n   * -----------------------------------------------------------\n   */\n  frame = AllocateFrame(vfb_size, margin, device);\n  if ( frame != NULL)\n    return frame;\n\n\n  /* -----------------------------------------------------------\n   *   Oh boy...\n   * -----------------------------------------------------------\n   */\n\n   // See if we could benefit from 64-bit Avisynth\n  if (sizeof(void*) == 4 && device == Devices->GetCPUDevice())\n  {\n#ifdef AVS_WINDOWS\n    // Get system memory information\n    MEMORYSTATUSEX memstatus;\n    memstatus.dwLength = sizeof(memstatus);\n    GlobalMemoryStatusEx(&memstatus);\n\n    BOOL using_wow64;\n    if (IsWow64Process(GetCurrentProcess(), &using_wow64)     // if running 32-bits on a 64-bit OS\n      && (memstatus.ullAvailPhys > 1024ull * 1024 * 1024))    // if at least 1GB of system memory is still free\n    {\n      OneTimeLogTicket ticket(LOGTICKET_W1007);\n      LogMsgOnce(ticket, LOGLEVEL_INFO, \"We have run out of memory, but your system still has some free RAM left. You might benefit from a 64-bit build of Avisynth+.\");\n    }\n#endif\n  }\n\n  ThrowError(\"Could not allocate video frame. Out of memory. memory_max = %\" PRIu64 \", memory_used = %\" PRIu64 \" Request=%zu\", device->memory_max, device->memory_used.load(), vfb_size);\n  return NULL;\n}\n\nvoid ScriptEnvironment::ShrinkCache(Device *device)\n{\n  /* -----------------------------------------------------------\n  *   Shrink cache to keep memory limit\n  * -----------------------------------------------------------\n  */\n  int shrinkcount = 0;\n\n  for (auto &cit: CacheRegistry)\n  {\n    // Oh darn. We'd need more memory than we are allowed to use.\n    // Let's reduce the amount of caching.\n\n    // We try to shrink least recently used caches first.\n\n    AvsCache* cache = cit;\n    if (cache->GetDevice() != device) {\n      continue;\n    }\n    int cache_size = cache->SetCacheHints(CACHE_GET_SIZE, 0);\n    if (cache_size != 0)\n    {\n      _RPT2(0, \"ScriptEnvironment::EnsureMemoryLimit shrink cache. cache=%p new size=%d\\n\", (void*)cache, cache_size - 1);\n      cache->SetCacheHints(CACHE_SET_MAX_CAPACITY, cache_size - 1);\n      shrinkcount++;\n    } // if\n  } // for cit\n\n  if (shrinkcount != 0)\n  {\n    OneTimeLogTicket ticket(LOGTICKET_W1003);\n    LogMsgOnce(ticket, LOGLEVEL_WARNING, \"Caches have been shrunk due to low memory limit. This will probably degrade performance. You can try increasing the limit using SetMemoryMax().\");\n  }\n\n  /* -----------------------------------------------------------\n  * Count up free_count and free if it exceeds the threshold\n  * -----------------------------------------------------------\n  */\n  // Free up in one pass in FrameRegistry2\n  if (shrinkcount)\n  {\n    _RPT1(0, \"EnsureMemoryLimit GC start: memused=%\" PRIu64 \"\\n\", device->memory_used.load());\n    [[maybe_unused]] int freed_vfb_count = 0;\n    [[maybe_unused]] int freed_frame_count = 0;\n    [[maybe_unused]] int unfreed_frame_count = 0;\n    for (auto &it: FrameRegistry2)\n    {\n      for (FrameBufferRegistryType::iterator it2 = (it.second).begin(), end_it2 = (it.second).end();\n        it2 != end_it2;\n        /*++it2: not here: may delete iterator position */)\n      {\n        VFBStorage *vfb = static_cast<VFBStorage*>(it2->first);\n        // vfb device and refcount check and free count exceeds the threshold\n        if (device == vfb->device && 0 == vfb->refcount && vfb->free_count++ >= device->free_thresh)\n        {\n#if 0\n          static int counter = 0;\n          char buf[200]; sprintf(buf, \"Free frame !!! %d\\r\\n\", counter++);\n          OutputDebugStringA(buf);\n#endif\n          device->memory_used -= vfb->GetDataSize();\n#ifdef _DEBUG\n          VFBStorage *_vfb = vfb;\n#endif\n          delete vfb;\n          ++freed_vfb_count;\n          for (auto &it3: it2->second)\n          {\n            VideoFrame *frame = it3.frame;\n            assert(0 == frame->refcount);\n            if (0 == frame->refcount)\n            {\n              delete frame;\n              ++freed_frame_count;\n            }\n            else {\n              // there should not be such case: vfb.refcount=0 and frame.refcount!=0\n              ++unfreed_frame_count;\n#ifdef _DEBUG\n              _RPT3(0, \"  ?????? frame refcount error!!! _vfb=%p frame=%p framerefcount=%d \\n\", _vfb, frame, frame->refcount);\n#endif\n            }\n          }\n          // delete array belonging to this vfb in one step\n          it2->second.clear(); // clear frame list\n          it2 = (it.second).erase(it2); // clear vfb entry\n        }\n        else ++it2;\n      }\n    }\n    _RPT4(0, \"End of garbage collection B: freed_vfb=%d frame=%d unfreed=%d memused=%\" PRIu64 \"\\n\", freed_vfb_count, freed_frame_count, unfreed_frame_count, device->memory_used.load());\n  }\n}\n\n// no alpha\nPVideoFrame ScriptEnvironment::NewPlanarVideoFrame(int row_size, int height, int row_sizeUV, int heightUV, int align, bool U_first, int pixel_type, Device* device)\n{\n  return NewPlanarVideoFrame(row_size, height, row_sizeUV, heightUV, align, U_first, false /* no alpha */, pixel_type, device);\n}\n\n// with alpha support\nPVideoFrame ScriptEnvironment::NewPlanarVideoFrame(int row_size, int height, int row_sizeUV, int heightUV, int align, bool U_first, bool alpha, int pixel_type, Device* device)\n{\n  if (align < 0)\n  {\n    align = -align;\n    OneTimeLogTicket ticket(LOGTICKET_W1009);\n    LogMsgOnce(ticket, LOGLEVEL_WARNING, \"A filter is using forced frame alignment, a feature that is deprecated and disabled. The filter will likely behave erroneously.\");\n  }\n  align = max(align, frame_align);\n\n  int pitchUV;\n  const int pitchY = AlignNumber(row_size, align);\n  if (!PlanarChromaAlignmentState && (row_size == row_sizeUV*2) && (height == heightUV*2)) { // Meet old 2.5 series API expectations for YV12\n    // Legacy alignment - pack Y as specified, pack UV half that\n    pitchUV = (pitchY+1)>>1;  // UV plane, width = 1/2 byte per pixel - don't align UV planes seperately.\n  }\n  else {\n    // Align planes separately\n    pitchUV = AlignNumber(row_sizeUV, align);\n  }\n\n  size_t sizeY = AlignNumber(pitchY * height, plane_align);\n  size_t sizeUV = AlignNumber(pitchUV * heightUV, plane_align);\n  size_t size = sizeY + 2 * sizeUV + (alpha ? sizeY : 0);\n\n  VideoFrame *res = GetNewFrame(size, align - 1, device);\n\n  int  offsetU, offsetV, offsetA;\n  const int offsetY = (int)(AlignPointer(res->vfb->GetWritePtr(), align) - res->vfb->GetWritePtr()); // first line offset for proper alignment\n  if (U_first) {\n    offsetU = offsetY + (int)sizeY;\n    offsetV = offsetY + (int)sizeY + (int)sizeUV;\n    offsetA = alpha ? offsetV + (int)sizeUV : 0;\n  } else {\n    offsetV = offsetY + (int)sizeY;\n    offsetU = offsetY + (int)sizeY + (int)sizeUV;\n    offsetA = alpha ? offsetU + (int)sizeUV : 0;\n  }\n\n  res->offset = offsetY;\n  res->pitch = pitchY;\n  res->row_size = row_size;\n  res->height = height;\n\n  res->offsetU = offsetU;\n  res->offsetV = offsetV;\n  res->pitchUV = pitchUV;\n  res->row_sizeUV = row_sizeUV;\n  res->heightUV = heightUV;\n\n  // alpha support\n  res->offsetA = offsetA;\n  res->row_sizeA = alpha ? row_size : 0;\n  res->pitchA = alpha ? pitchY : 0;\n\n  res->pixel_type = pixel_type;\n\n  return PVideoFrame(res);\n}\n\n// Variant #1.no frame property source\nPVideoFrame ScriptEnvironment::NewVideoFrameOnDevice(int row_size, int height, int align, int pixel_type, Device* device)\n{\n  if (align < 0)\n  {\n    align = -align;\n    OneTimeLogTicket ticket(LOGTICKET_W1009);\n    this->LogMsgOnce(ticket, LOGLEVEL_WARNING, \"A filter is using forced frame alignment, a feature that is deprecated and disabled. The filter will likely behave erroneously.\");\n  }\n  align = max(align, frame_align);\n\n  const int pitch = AlignNumber(row_size, align);\n  size_t size = pitch * height;\n\n  VideoFrame *res = GetNewFrame(size, align - 1, device);\n\n  const int offset = (int)(AlignPointer(res->vfb->GetWritePtr(), align) - res->vfb->GetWritePtr()); // first line offset for proper alignment\n\n  res->offset = offset;\n  res->pitch = pitch;\n  res->row_size = row_size;\n  res->height = height;\n\n  res->offsetU = offset;\n  res->offsetV = offset;\n  res->pitchUV = 0;\n  res->row_sizeUV = 0;\n  res->heightUV = 0;\n\n  // alpha support\n  res->offsetA = 0;\n  res->row_sizeA = 0;\n  res->pitchA = 0;\n\n  res->pixel_type = pixel_type;\n\n  return PVideoFrame(res);\n}\n\n// Variant #1. with frame property source\nPVideoFrame ScriptEnvironment::NewVideoFrameOnDevice(int row_size, int height, int align, int pixel_type, Device* device, const PVideoFrame* prop_src)\n{\n  PVideoFrame result = NewVideoFrameOnDevice(row_size, height, align, pixel_type, device);\n\n  if (prop_src)\n    copyFrameProps(*prop_src, result);\n\n  return result;\n}\n\n// Variant #2. without frame property source\nPVideoFrame ScriptEnvironment::NewVideoFrame(const VideoInfo& vi, const PDevice& device) {\n  return NewVideoFrameOnDevice(vi, frame_align, (Device*)(void*)device);\n}\n\n// Variant #2. with frame property source\nPVideoFrame ScriptEnvironment::NewVideoFrame(const VideoInfo& vi, const PDevice& device, const PVideoFrame* prop_src)\n{\n  PVideoFrame result = NewVideoFrame(vi, device);\n\n  if (prop_src)\n    copyFrameProps(*prop_src, result);\n\n  return result;\n}\n\n// Variant #3. without frame property source\nPVideoFrame ScriptEnvironment::NewVideoFrameOnDevice(const VideoInfo& vi, int align, Device* device) {\n  // todo: high bit-depth: we have too many types now. Do we need really check?\n  // Check requested pixel_type:\n  switch (vi.pixel_type) {\n    case VideoInfo::CS_BGR24:\n    case VideoInfo::CS_BGR32:\n    case VideoInfo::CS_YUY2:\n    case VideoInfo::CS_Y8:\n    case VideoInfo::CS_YV12:\n    case VideoInfo::CS_YV16:\n    case VideoInfo::CS_YV24:\n    case VideoInfo::CS_YV411:\n    case VideoInfo::CS_I420:\n    // AVS16 do not reject when a filter requests it\n        // planar YUV 10-32 bit\n    case VideoInfo::CS_YUV420P10:\n    case VideoInfo::CS_YUV422P10:\n    case VideoInfo::CS_YUV444P10:\n    case VideoInfo::CS_Y10:\n    case VideoInfo::CS_YUV420P12:\n    case VideoInfo::CS_YUV422P12:\n    case VideoInfo::CS_YUV444P12:\n    case VideoInfo::CS_Y12:\n    case VideoInfo::CS_YUV420P14:\n    case VideoInfo::CS_YUV422P14:\n    case VideoInfo::CS_YUV444P14:\n    case VideoInfo::CS_Y14:\n    case VideoInfo::CS_YUV420P16:\n    case VideoInfo::CS_YUV422P16:\n    case VideoInfo::CS_YUV444P16:\n    case VideoInfo::CS_Y16:\n    case VideoInfo::CS_YUV420PS:\n    case VideoInfo::CS_YUV422PS:\n    case VideoInfo::CS_YUV444PS:\n    case VideoInfo::CS_Y32:\n        // 16 bit/sample packed RGB\n    case VideoInfo::CS_BGR48:\n    case VideoInfo::CS_BGR64:\n        // planar RGB\n    case VideoInfo::CS_RGBP:\n    case VideoInfo::CS_RGBP10:\n    case VideoInfo::CS_RGBP12:\n    case VideoInfo::CS_RGBP14:\n    case VideoInfo::CS_RGBP16:\n    case VideoInfo::CS_RGBPS:\n        // planar RGBA\n    case VideoInfo::CS_RGBAP:\n    case VideoInfo::CS_RGBAP10:\n    case VideoInfo::CS_RGBAP12:\n    case VideoInfo::CS_RGBAP14:\n    case VideoInfo::CS_RGBAP16:\n    case VideoInfo::CS_RGBAPS:\n        // planar YUVA 8-32 bit\n    case VideoInfo::CS_YUVA420:\n    case VideoInfo::CS_YUVA422:\n    case VideoInfo::CS_YUVA444:\n    case VideoInfo::CS_YUVA420P10:\n    case VideoInfo::CS_YUVA422P10:\n    case VideoInfo::CS_YUVA444P10:\n    case VideoInfo::CS_YUVA420P12:\n    case VideoInfo::CS_YUVA422P12:\n    case VideoInfo::CS_YUVA444P12:\n    case VideoInfo::CS_YUVA420P14:\n    case VideoInfo::CS_YUVA422P14:\n    case VideoInfo::CS_YUVA444P14:\n    case VideoInfo::CS_YUVA420P16:\n    case VideoInfo::CS_YUVA422P16:\n    case VideoInfo::CS_YUVA444P16:\n    case VideoInfo::CS_YUVA420PS:\n    case VideoInfo::CS_YUVA422PS:\n    case VideoInfo::CS_YUVA444PS:\n        break;\n    default:\n      ThrowError(\"Filter Error: Filter attempted to create VideoFrame with invalid pixel_type.\");\n  }\n\n  PVideoFrame retval;\n\n  if (vi.IsPlanar() && (vi.NumComponents() > 1)) {\n    if (vi.IsYUV() || vi.IsYUVA()) {\n      // Planar requires different math ;)\n      const int xmod  = 1 << vi.GetPlaneWidthSubsampling(PLANAR_U);\n      const int xmask = xmod - 1;\n      if (vi.width & xmask)\n        ThrowError(\"Filter Error: Attempted to request a planar frame that wasn't mod%d in width!\", xmod);\n\n      const int ymod  = 1 << vi.GetPlaneHeightSubsampling(PLANAR_U);\n      const int ymask = ymod - 1;\n      if (vi.height & ymask)\n        ThrowError(\"Filter Error: Attempted to request a planar frame that wasn't mod%d in height!\", ymod);\n\n      const int heightUV = vi.height >> vi.GetPlaneHeightSubsampling(PLANAR_U);\n\n      retval = NewPlanarVideoFrame(vi.RowSize(PLANAR_Y), vi.height, vi.RowSize(PLANAR_U), heightUV, align, !vi.IsVPlaneFirst(), vi.IsYUVA(), vi.pixel_type, device);\n    } else {\n      // plane order: G,B,R\n      retval = NewPlanarVideoFrame(vi.RowSize(PLANAR_G), vi.height, vi.RowSize(PLANAR_G), vi.height, align, !vi.IsVPlaneFirst(), vi.IsPlanarRGBA(), vi.pixel_type, device);\n    }\n  }\n  else {\n    if ((vi.width&1)&&(vi.IsYUY2()))\n      ThrowError(\"Filter Error: Attempted to request an YUY2 frame that wasn't mod2 in width.\");\n\n    retval= NewVideoFrameOnDevice(vi.RowSize(), vi.height, align, vi.pixel_type, device);\n  }\n\n  return retval;\n}\n\n\n// Variant #3. with frame property source\nPVideoFrame ScriptEnvironment::NewVideoFrameOnDevice(const VideoInfo& vi, int align, Device* device, const PVideoFrame* prop_src)\n{\n  PVideoFrame result = NewVideoFrameOnDevice(vi, align, device);\n\n  if (prop_src)\n    copyFrameProps(*prop_src, result);\n\n  return result;\n}\n\n\nbool ScriptEnvironment::MakeWritable(PVideoFrame* pvf) {\n  const PVideoFrame& vf = *pvf;\n\n  // If the frame is already writable, do nothing.\n  if (vf->IsWritable())\n    return false;\n\n  // Otherwise, allocate a new frame (using NewVideoFrame) and\n  // copy the data into it.  Then modify the passed PVideoFrame\n  // to point to the new buffer.\n  Device* device = vf->GetFrameBuffer()->device;\n  PVideoFrame dst;\n\n#ifdef ENABLE_CUDA\n  if (device->device_type == DEV_TYPE_CUDA) {\n    // copy whole frame\n    dst = GetOnDeviceFrame(vf, device);\n    CopyCUDAFrame(dst, vf, threadEnv.get());\n  }\n  else\n#endif\n  {\n    const int row_size = vf->GetRowSize();\n    const int height = vf->GetHeight();\n\n    bool alpha = 0 != vf->GetPitch(PLANAR_A);\n    if (vf->GetPitch(PLANAR_U)) {  // we have no videoinfo, so we assume that it is Planar if it has a U plane.\n      const int row_sizeUV = vf->GetRowSize(PLANAR_U); // for Planar RGB this returns row_sizeUV which is the same for all planes\n      const int heightUV = vf->GetHeight(PLANAR_U);\n      dst = NewPlanarVideoFrame(row_size, height, row_sizeUV, heightUV, frame_align, false /* always V first on internal images */, alpha, vf->pixel_type, device);\n    }\n    else {\n      dst = NewVideoFrameOnDevice(row_size, height, frame_align, vf->pixel_type, device);\n    }\n\n    BitBlt(dst->GetWritePtr(), dst->GetPitch(), vf->GetReadPtr(), vf->GetPitch(), row_size, height);\n    // Blit More planes (pitch, rowsize and height should be 0, if none is present)\n    BitBlt(dst->GetWritePtr(PLANAR_V), dst->GetPitch(PLANAR_V), vf->GetReadPtr(PLANAR_V),\n      vf->GetPitch(PLANAR_V), vf->GetRowSize(PLANAR_V), vf->GetHeight(PLANAR_V));\n    BitBlt(dst->GetWritePtr(PLANAR_U), dst->GetPitch(PLANAR_U), vf->GetReadPtr(PLANAR_U),\n      vf->GetPitch(PLANAR_U), vf->GetRowSize(PLANAR_U), vf->GetHeight(PLANAR_U));\n    if (alpha)\n      BitBlt(dst->GetWritePtr(PLANAR_A), dst->GetPitch(PLANAR_A), vf->GetReadPtr(PLANAR_A),\n        vf->GetPitch(PLANAR_A), vf->GetRowSize(PLANAR_A), vf->GetHeight(PLANAR_A));\n  }\n\n  copyFrameProps(vf, dst);\n\n  *pvf = dst;\n  return true;\n}\n\n\nvoid ScriptEnvironment::AtExit(IScriptEnvironment::ShutdownFunc function, void* user_data) {\n  at_exit.Add(function, user_data);\n}\n\n// Registers a new VideoFrame (which shares an existing VFB via Subframe) into\n// FrameRegistry2, with eager pruning of dead entries.\n//\n// Why subframe registration is needed:\n// Even though the new subframe shares the source VFB, it must be registered so\n// that GetFrameFromRegistry cannot wrongly reassign the VFB while any subframe\n// still references it. The VFB refcount guards against reuse, but the registry\n// is the mechanism by which VideoFrame objects are tracked and eventually recycled.\n//\n// Why pruning is needed:\n// The naive approach (bare push_back) causes a memory leak when the source VFB\n// belongs to a static-frame clip such as ColorBars() or BlankClip(). Those clips\n// serve the same VFB for every GetFrame() call; its refcount never reaches 0.\n// GetFrameFromRegistry only cleans up dead VideoFrame objects when it finds\n// vfb->refcount == 0, so it never visits the static VFB's bucket. Each call to\n// Subframe/SubframePlanar/MakePropertyWritable pushes a new entry; the subframe\n// is used briefly, released (refcount drops to 0), but the dead VideoFrame object\n// is never deleted. Over a long sequence (e.g. 107000 frames) this accumulates\n// ~10 MB of dead VideoFrame objects.\n//\n// The fix:\n// Before pushing, scan the bucket and delete all entries with refcount == 0,\n// mirroring what GetFrameFromRegistry does during normal VFB recycling, but\n// eagerly, for buckets it will never visit.\n// For static-clip VFBs the vector stabilizes at exactly 2 entries:\n//   [0] the original live frame  (refcount >= 2, untouched)\n//   [1] the single current subframe (refcount == 0 by next call, pruned then)\n// For normal (non-static) clips the VFB is recycled normally by\n// GetFrameFromRegistry; the prune loop finds nothing and is a no-op.\n//\n// NOTE 1: AllocateFrame is intentionally excluded. It always creates a brand-new\n// VFB with a fresh, empty bucket, so there are never stale entries to prune there.\n//\n// NOTE 2: Caller must hold memory_mutex before calling this function.\n// All four call sites (AllocateFrame excluded) acquire memory_mutex\n// via std::unique_lock<std::recursive_mutex> env_lock(memory_mutex)\n// before reaching this point.\nvoid ScriptEnvironment::RegisterSubFrameInRegistry(size_t vfb_size, VideoFrameBuffer* vfb, VideoFrame* new_frame)\n{\n  // caller must already hold memory_mutex\n  auto& vec = FrameRegistry2[vfb_size][vfb];\n  for (auto it = vec.begin(); it != vec.end(); ) {\n    VideoFrame* f = it->frame;\n    if (f->refcount == 0) {\n      delete f; // ~VideoFrame()/DESTRUCTOR() deletes f->properties\n      it = vec.erase(it);\n    }\n    else {\n      ++it;\n    }\n  }\n  vec.push_back(DebugTimestampedFrame(new_frame));\n#ifdef _DEBUG\n  // ListFrameRegistry(vfb_size, vfb_size, true);\n#endif\n\n}\n\nPVideoFrame ScriptEnvironment::Subframe(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height) {\n\n  if (src->GetFrameBuffer()->device->device_type == DEV_TYPE_CPU)\n    if ((new_pitch | rel_offset) & (frame_align - 1))\n      ThrowError(\"Filter Error: Filter attempted to break alignment of VideoFrame.\");\n\n  VideoFrame* subframe = src->Subframe(rel_offset, new_pitch, new_row_size, new_height);\n\n  const AVSMap &avsmap = src->getConstProperties();\n  if (propNumKeys(&avsmap) > 0)\n    subframe->setProperties(avsmap);\n\n  size_t vfb_size = src->GetFrameBuffer()->GetDataSize();\n\n  // vector and maps needs locking\n  std::unique_lock<std::recursive_mutex> env_lock(memory_mutex);\n  assert(NULL != subframe);\n\n  RegisterSubFrameInRegistry(vfb_size, src->GetFrameBuffer(), subframe);\n\n  return subframe;\n}\n\nPVideoFrame ScriptEnvironment::SubframePlanar(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size,\n  int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV) {\n  if(src->GetFrameBuffer()->device->device_type == DEV_TYPE_CPU)\n    if ((rel_offset | new_pitch | rel_offsetU | rel_offsetV | new_pitchUV) & (frame_align - 1))\n      ThrowError(\"Filter Error: Filter attempted to break alignment of VideoFrame.\");\n\n  VideoFrame *subframe = src->Subframe(rel_offset, new_pitch, new_row_size, new_height, rel_offsetU, rel_offsetV, new_pitchUV);\n\n  const AVSMap& avsmap = src->getConstProperties();\n  if (propNumKeys(&avsmap) > 0)\n    subframe->setProperties(avsmap);\n\n  size_t vfb_size = src->GetFrameBuffer()->GetDataSize();\n\n  // vector and maps needs locking\n  std::unique_lock<std::recursive_mutex> env_lock(memory_mutex); // vector needs locking!\n  assert(subframe != NULL);\n\n  RegisterSubFrameInRegistry(vfb_size, src->GetFrameBuffer(), subframe);\n\n  return subframe;\n}\n\n// alpha aware version\nPVideoFrame ScriptEnvironment::SubframePlanar(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size,\n  int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV, int rel_offsetA) {\n  if (src->GetFrameBuffer()->device->device_type == DEV_TYPE_CPU)\n    if ((rel_offset | new_pitch | rel_offsetU | rel_offsetV | new_pitchUV | rel_offsetA) & (frame_align - 1))\n      ThrowError(\"Filter Error: Filter attempted to break alignment of VideoFrame.\");\n  VideoFrame* subframe;\n  subframe = src->Subframe(rel_offset, new_pitch, new_row_size, new_height, rel_offsetU, rel_offsetV, new_pitchUV, rel_offsetA);\n\n  const AVSMap& avsmap = src->getConstProperties();\n  if (propNumKeys(&avsmap) > 0)\n    subframe->setProperties(avsmap);\n\n  size_t vfb_size = src->GetFrameBuffer()->GetDataSize();\n\n  // vector and maps needs locking\n  std::unique_lock<std::recursive_mutex> env_lock(memory_mutex);\n  assert(subframe != NULL);\n\n  RegisterSubFrameInRegistry(vfb_size, src->GetFrameBuffer(), subframe);\n\n  return subframe;\n}\n\nvoid* ScriptEnvironment::ManageCache(int key, void* data) {\n// An extensible interface for providing system or user access to the\n// ScriptEnvironment class without extending the IScriptEnvironment\n// definition.\n\n  std::lock_guard<std::recursive_mutex> env_lock(memory_mutex);\n  switch ((MANAGE_CACHE_KEYS)key)\n  {\n    // Called by Cache instances upon creation\n  case MC_RegisterCache:\n  {\n    AvsCache* cache = reinterpret_cast<AvsCache*>(data);\n    if (FrontCache != NULL)\n      CacheRegistry.push_back(FrontCache);\n    FrontCache = cache;\n    break;\n  }\n  // Called by Cache instances upon destruction\n  case MC_UnRegisterCache:\n  {\n    AvsCache* cache = reinterpret_cast<AvsCache*>(data);\n    if (FrontCache == cache)\n      FrontCache = NULL;\n    else\n      CacheRegistry.remove(cache);\n    break;\n  }\n  // Called by Cache instances when they want to expand their limit\n  case MC_NodAndExpandCache:\n  {\n    AvsCache* cache = reinterpret_cast<AvsCache*>(data);\n\n    // Nod\n    if (cache != FrontCache)\n    {\n      CacheRegistry.move_to_back(cache);\n    }\n\n    // Given that we are within our memory limits,\n    // try to expand the limit of those caches that\n    // need it.\n    // We try to expand most recently used caches first.\n\n    int cache_cap = cache->SetCacheHints(CACHE_GET_CAPACITY, 0);\n    int cache_reqcap = cache->SetCacheHints(CACHE_GET_REQUESTED_CAP, 0);\n    if (cache_reqcap <= cache_cap)\n      return 0;\n\n    Device* device = cache->GetDevice();\n    if ((device->memory_used > device->memory_max) || (device->memory_max - device->memory_used < device->memory_max*0.1f))\n    {\n      // If we don't have enough free reserves, take away a cache slot from\n      // a cache instance that hasn't been used since long.\n\n      for (AvsCache* old_cache : CacheRegistry)\n      {\n        if (old_cache->GetDevice() != device) {\n          continue;\n        }\n        int osize = cache->SetCacheHints(CACHE_GET_SIZE, 0);\n        if (osize != 0)\n        {\n          old_cache->SetCacheHints(CACHE_SET_MAX_CAPACITY, osize - 1);\n          break;\n        }\n      } // for cit\n    }\n#ifdef _DEBUG\n    _RPT2(0, \"ScriptEnvironment::ManageCache increase capacity to %d cache_id=%s\\n\", cache_cap + 1, cache->FuncName.c_str());\n#endif\n    cache->SetCacheHints(CACHE_SET_MAX_CAPACITY, cache_cap + 1);\n\n    break;\n  }\n  // Called by Cache instances when they are accessed\n  case MC_NodCache:\n  {\n    AvsCache* cache = reinterpret_cast<AvsCache*>(data);\n    if (cache == FrontCache) {\n      return 0;\n    }\n\n    CacheRegistry.move_to_back(cache);\n    break;\n  } // case\n  case MC_RegisterMTGuard:\n  {\n    MTGuard* guard = reinterpret_cast<MTGuard*>(data);\n\n    MTGuardRegistry.push_back(guard);\n\n    break;\n  }\n  case MC_UnRegisterMTGuard:\n  {\n    MTGuard* guard = reinterpret_cast<MTGuard*>(data);\n    for (auto& item : MTGuardRegistry)\n    {\n      if (item == guard)\n      {\n        item = NULL;\n        break;\n      }\n    }\n    break;\n  }\n  case MC_RegisterGraphNode:\n  {\n    FilterGraphNode* node = reinterpret_cast<FilterGraphNode*>(data);\n    GraphNodeRegistry.push_back(node);\n    break;\n  }\n  case MC_UnRegisterGraphNode:\n  {\n    FilterGraphNode* node = reinterpret_cast<FilterGraphNode*>(data);\n    for (auto& item : GraphNodeRegistry)\n    {\n      if (item == node)\n      {\n        item = NULL;\n        break;\n      }\n    }\n    break;\n  }\n  case MC_QueryAvs25:\n  case MC_QueryAvsPreV11C:\n  {\n    break; // not cache related\n  }\n  } // switch\n  return 0;\n}\n\n\nbool ScriptEnvironment::PlanarChromaAlignment(IScriptEnvironment::PlanarChromaAlignmentMode key){\n  bool oldPlanarChromaAlignmentState = PlanarChromaAlignmentState;\n\n  switch (key)\n  {\n  case IScriptEnvironment::PlanarChromaAlignmentOff:\n  {\n    PlanarChromaAlignmentState = false;\n    break;\n  }\n  case IScriptEnvironment::PlanarChromaAlignmentOn:\n  {\n    PlanarChromaAlignmentState = true;\n    break;\n  }\n  default:\n    break;\n  }\n  return oldPlanarChromaAlignmentState;\n}\n\n/* A helper for Invoke.\n   Copy a nested array of 'src' into a flat array 'dst'.\n   Returns the number of elements that have been written to 'dst'.\n   If 'dst' is NULL, will still return the number of elements\n   that would have been written to 'dst', but will not actually write to 'dst'.\n*/\nstatic size_t Flatten(const AVSValue& src, AVSValue* dst, size_t index, int level, const char* const* arg_names = NULL) {\n  // level is starting from zero\n  if (src.IsArray()\n    && level == 0\n    ) { // flatten for the first arg level\n    const int array_size = src.ArraySize();\n    for (int i=0; i<array_size; ++i) {\n      if (!arg_names || arg_names[i] == 0)\n        index = Flatten(src[i], dst, index, level+1);\n    }\n  } else {\n    if (dst != NULL)\n      dst[index] = src;\n    ++index;\n  }\n  return index;\n}\n\nconst Function* ScriptEnvironment::Lookup(const char* search_name, const AVSValue* args, size_t num_args,\n  bool& pstrict, size_t args_names_count, const char* const* arg_names, IScriptEnvironment2* ctx)\n{\n  AVSValue avsv;\n  if (ctx->GetVarTry(search_name, &avsv) && avsv.IsFunction()) {\n    //auto& funcv = avsv.AsFunction(); // c++ strict conformance: cannot Convert PFunction to PFunction&\n    const PFunction& funcv = avsv.AsFunction();\n    const char* name = funcv->GetLegacyName();\n    const Function* func = funcv->GetDefinition();\n    if (name != nullptr) {\n      // wrapped function\n      search_name = name;\n    }\n    else if (AVSFunction::TypeMatch(func->param_types, args, num_args, false, threadEnv.get()) &&\n      AVSFunction::ArgNameMatch(func->param_types, args_names_count, arg_names))\n    {\n      pstrict = AVSFunction::TypeMatch(func->param_types, args, num_args, true, threadEnv.get());\n      return func;\n    }\n  }\n\n  std::unique_lock<std::recursive_mutex> env_lock(plugin_mutex);\n\n  const Function *result = NULL;\n\n  auto orig_args_names_count = args_names_count;\n\n  size_t oanc;\n  do {\n    // if args_names_count>0 then a 2x2 loop, strict yes/no, with or without args name matching\n    // if =0, 2x loop strict yes/no,without args name matching\n    for (int strict = 1; strict >= 0; --strict) {\n      pstrict = strict & 1;\n      // first, look in loaded plugins or user defined functions\n      result = plugin_manager->Lookup(search_name, args, num_args, pstrict, args_names_count, arg_names);\n      if (result)\n        return result;\n\n      // then, look for a built-in function\n      for (int i = 0; i < sizeof(builtin_functions)/sizeof(builtin_functions[0]); ++i)\n        for (const AVSFunction* j = builtin_functions[i]; !j->empty(); ++j)\n        {\n          if (streqi(j->name, search_name)) {\n            if (AVSFunction::TypeMatch(j->param_types, args, num_args, pstrict, ctx) &&\n              AVSFunction::ArgNameMatch(j->param_types, args_names_count, arg_names))\n              return j;\n          }\n        }\n    }\n    // Try again without arg name matching\n    oanc = args_names_count;\n    args_names_count = 0;\n  } while (oanc);\n\n  // If we got here it means the function has not been found.\n  // If we haven't done so yet, load the plugins in the autoload folders\n  // and try again.\n  if (!plugin_manager->HasAutoloadExecuted())\n  {\n    plugin_manager->AutoloadPlugins();\n    args_names_count = orig_args_names_count;\n    return Lookup(search_name, args, num_args, pstrict, args_names_count, arg_names, ctx);\n  }\n\n  return NULL;\n}\n\nbool ScriptEnvironment::CheckArguments(const Function* func, const AVSValue* args, size_t num_args,\n  bool &pstrict, size_t args_names_count, const char* const* arg_names)\n{\n  if (AVSFunction::TypeMatch(func->param_types, args, num_args, false, threadEnv.get()) &&\n    AVSFunction::ArgNameMatch(func->param_types, args_names_count, arg_names))\n  {\n    pstrict = AVSFunction::TypeMatch(func->param_types, args, num_args, true, threadEnv.get());\n    return true;\n  }\n  return false;\n}\n\n#ifdef LISTARGUMENTS\n// debug\nstatic void ListArguments(const char *name, const AVSValue& args, int &level, bool flattened) {\n  if (!strcmp(name, \"Import\"))\n    return;\n  if (!strcmp(name, \"Eval\"))\n    return;\n  if (level == 0)\n    fprintf(stdout, \"------- %s (%s)\\r\\n\", name, flattened ? \"flattened\" : \"orig\");\n  level++;\n  if (args.IsArray()) {\n    const int as = args.ArraySize();\n    fprintf(stdout, \"Array, size=%d {\\r\\n\", as);\n    for (int i = 0; i < as; i++) {\n      fprintf(stdout, \"Element#%d\\r\\n\", i);\n      ListArguments(name, args[i], level, flattened);\n    }\n    fprintf(stdout, \"}\\r\\n\");\n  }\n  else {\n    if (!args.Defined())\n      fprintf(stdout, \"Undefined\\r\\n\");\n    else if (args.IsBool())\n      fprintf(stdout, \"Bool %s\\r\\n\", args.AsBool() ? \"true\" : \"false\");\n    else if (args.GetType() == AvsValueType::VALUE_TYPE_LONG) // before IsInt() !\n      fprintf(stdout, \"Long %\" PRId64 \"\\r\\n\", args.AsLong());\n    else if (args.IsInt())\n      fprintf(stdout, \"Int %d\\r\\n\", args.AsInt());\n    else if (args.IsString())\n      fprintf(stdout, \"String %s\\r\\n\", args.AsString());\n    else if (args.GetType() == AvsValueType::VALUE_TYPE_FLOAT) // before IsFloat() !\n      fprintf(stdout, \"Float %f\\r\\n\", args.AsFloatf());\n    else if (args.IsFloat())\n      fprintf(stdout, \"Float/Double %lf\\r\\n\", args.AsFloat());\n    else if (args.IsFunction())\n      fprintf(stdout, \"Function\\r\\n\");\n    else if (args.IsClip())\n      fprintf(stdout, \"Clip\\r\\n\");\n    else\n      fprintf(stdout, \"Unknown type\\r\\n\");\n  }\n  level--;\n}\n\nstatic void ListArguments2(const char* name, const AVSValue* args, int& level, bool flattened, int len) {\n  if (!strcmp(name, \"Import\"))\n    return;\n  if (!strcmp(name, \"Eval\"))\n    return;\n  fprintf(stdout, \"------- %s (%s)\\r\\n\", name, flattened ? \"flattened\" : \"orig\");\n  level++;\n  for (int i = 0; i < len; i++) {\n    ListArguments(name, *(args +i), level, flattened);\n  }\n}\n#endif\n\nbool ScriptEnvironment::Invoke_(AVSValue *result, const AVSValue& implicit_last,\n  const char* name, const Function *f, const AVSValue& args, const char* const* arg_names,\n  InternalEnvironment* env_thread, bool is_runtime)\n{\n\n  const int args_names_count = (arg_names && args.IsArray()) ? args.ArraySize() : 0;\n\n  if (name == nullptr) {\n    // for debug printing\n    name = \"<anonymous function>\";\n  }\n\n  // Step #1: Flattening\n  // arrays received in the place of unnamed parameters are flattened back\n  // to have them as a list again, in order to be compatible with Avisynth's \"array elements as comma\n  // delimited parameters\" definition style.\n\n  // get how many args we will need to store\n  size_t args2_count = Flatten(args, NULL, 0, 0, arg_names);\n  if (args2_count > ScriptParser::max_args)\n    ThrowError(\"Too many arguments passed to function (max. is %d)\", ScriptParser::max_args);\n\n  // flatten unnamed args\n  std::vector<AVSValue> args2(args2_count + 1, AVSValue());\n  args2[0] = implicit_last;\n  Flatten(args, args2.data() + 1, 0, 0, arg_names);\n\n#ifdef LISTARGUMENTS\n  // debug list of Invoke arguments before-after flattening\n  int level = 0;\n  ListArguments(name, args, level, false); // unflattened remark\n  ListArguments2(name, args2.data()+1, level, true, args2_count); // flattened remark\n#endif\n\n  // Step #2: Arguments check and function detection by matching signature.\n\n  bool strict = false;\n  int argbase = 1;\n  if (f != nullptr) {\n    // check arguments\n    if (!this->CheckArguments(f, args2.data() + 1, args2_count, strict, args_names_count, arg_names)) {\n      if (!implicit_last.Defined() ||\n        !this->CheckArguments(f, args2.data(), args2_count + 1, strict, args_names_count, arg_names))\n        return false;\n      argbase = 0;\n      args2_count += 1;\n    }\n  }\n  else {\n    // Because only one level is flattened, for 2+ Dimension arrays result are\n    // at least two parameters which are still arrays)\n    // [3,4,5] is flattened as 3,4,5\n    // clip, [[2,3], [3,4,5]] is flattened as clip, [2,3], [3,4,5]\n\n    // find matching function\n    f = this->Lookup(name, args2.data() + 1, args2_count, strict, args_names_count, arg_names, env_thread);\n    if (!f)\n    {\n      if (!implicit_last.Defined())\n        return false;\n      // search function definitions with implicite \"last\" given\n      f = this->Lookup(name, args2.data(), args2_count + 1, strict, args_names_count, arg_names, env_thread);\n      if (!f)\n        return false;\n      argbase = 0;\n      args2_count += 1;\n    }\n  }\n\n  // Problem: Animate has parameter signature both \"iis.*\" and \"ciis.*\"\n  //   ColorBars()\n  //   Animate(0, 100, \"blur\", 0.1, 1.5)\n  // Here we find \"iis.*\" but it turns out that its given function parameter \"Blur\" requires a clip\n  // Thus we got an exception later during the filter instantiation (really it is \"Blur\" who throws the exception)\n  // (see comment Issue20200818 later).\n  // Expression evaluator would catch NotFound and reissue _Invoke with a forced implicit_last in args.\n\n  // Step #3: Unnamed arguments\n\n  // combine unnamed args into arrays\n  size_t src_index = 0;\n  const char* p = f->param_types;\n\n  std::vector<AVSValue> args3;\n  std::vector<bool> args3_really_filled;\n\n  bool last_was_named = false;\n  while (*p) {\n    if (*p == '[') {\n      // named parameter check: between brackets (no name validity check, empty is valid as well)\n      const char* pstart = p + 1;\n      p = strchr(pstart, ']');\n      if (!p) break;\n      last_was_named = true;\n      p++; // skip closing bracket\n    }\n    else if (((p[1] == '*') || (p[1] == '+'))) {\n      // Case of unnamed arrays or named arrays\n      // Special named array: [] with no real name\n      // Pre 3.6: filling up named arrays with names from script level was not possible.\n      // Memo: array function signature types: * means \"zero or more\". + means \"one or more\"\n      // Example fake-named array: the first clip array parameter of BlankClip \"[]c*[length]i etc.\n      // Some functions with array signatures:\n      //   Select i.+\n      //   SelectEvery: cii*\n      //   Format: s.*\n      //   MPP_SharedMemoryServer: csi[aux_clips]c*[max_cache_frames]i\n      //   BlankClip []c*[length]i (fake named array)\n      //   ArrayGet .i+\n      //   ArraySize .\n      //   Array/ArrayCreate .*: [[2,3,4], [1,2]] -> [2,3,4], [1,2]\n      //   user_script_function(clip, int_array) c[]i*\n      // Pre v3.6 script-level array definition: autodetect comma separated list elements\n      // The parser detects the end of array: the next argument type is different.\n      // Since the end of free-typed (\".+\" or \".*\") arrays cannot be recognized, they are allowed to appear\n      // only at the very end of the parameter signature\n      // Option since 3.6: bracket-style array definition syntax\n      size_t start = src_index;\n      const char arg_type = *p;\n\n\n      if (src_index < args2_count &&\n        args2[argbase + src_index].IsArray() \n        // After flattening this only happens when an explicite array was passed.\n        // typed array recognition is easy and unambigous\n        && arg_type != '.' // to avoid .+ case when one can pass array of arrays like [[1,2,3],[4,5]] flattened to [1,2,3],[4,5]\n        )\n      {\n        if (arg_type != '.') {\n          if (!AVSFunction::SingleTypeMatchArray(arg_type, args2[argbase + src_index], strict))\n            ThrowError(\"Array elements do not match with the specified type in function %s\", name);\n        }\n\n        if(p[1] == '+' && args2[argbase + src_index].ArraySize() == 0) // one or more\n          ThrowError(\"An array with zero element size was given to function %s which expects a 'one-or-more' style array argument\", name);\n        args3.push_back(args2[argbase + src_index]); // can't delete args2 early because of this\n        args3_really_filled.push_back(true); // valid array content\n        src_index++;\n      }\n      else\n      {\n        // Collect consecutive similary-typed parameters into an array by automatic detection of its end:\n        // The end of a simple-typed array:\n        // - when the comma separated parameter list is changing type\n        // - no more parameters (list ends)\n        // E.g. collect values into an integer array (i*) until values in the list are still integers.\n        // The array collection in parameter sequence 1, 2, 3, \"hello1\", \"hello2\" will stop before \"hello1\"\n        // because type is changed from i to s.\n        // This is why the end of an 'any-type' array (.*) cannot be detected from a comma delimited list:\n        // no stopping condition (no type), only the end of list can stop collecting.\n        while ((src_index < args2_count)) {\n          const bool match = AVSFunction::SingleTypeMatch(arg_type, args2[argbase + src_index], strict);\n          if (!match)\n            break;\n          src_index++;\n        }\n        size_t size = src_index - start; // so we have size number of items detected. Put them back into an array.\n        assert(args2_count >= size);\n\n        // Even if the AVSValue below is an array of zero size, we can't skip adding it to args3,\n        // because filters like BlankClip []c* or MPP_SharedMemoryServer might still be expecting it.\n        // 3.7.1.: This statement is no longer true. BlankClip was modified to handle Undefined AVSValue instead of array[] properly\n\n/*\n  Considerations on resolving parameter handling for \"array of anything\" parameter when array(s) would be passed directly.\n  Memo:\n  - Avisynth signature: .* or .+\n  - Script function specifier val_array or val_array_nz\n\n  When parameter signature is array of anything (.* or .+) and the\n  parameter is passed unnamed (even if it is a named parameter) then\n  there is an ambiguos situation which \n\n  Giving a parameter list of 1,2,3 will be detected as [1,2,3] (compatibility: list is grouped together into an array internally).\n  E.g. 1 will be detected as [1]\n  Passing nothing from an Avisynth script in the place of the parameter will be detected as [] (array size is zero, value is defined)\n  initially, then later in the named parameter processing procedure it can be overridden directly by a named value.\n  \n  This rule means that a directly given script array e.g. [1,2,3] will be detected as [[1,2,3]], because unnamed and untyped parameters are\n  put together into an array, which has the size of the list. This is a list of 1 element which happens to be an array.\n  Avisynth cannot 'guess' whether we want to define a single array directly or this array is the only one part of the list.\n  So an unnamedly passed [1,2,3] will appear as [ [1,2,3] ] in the unnamed \"array of anything\" parameter value.\n\n  Syntax hint:\n  When someone would like to pass a directly specified array (e.g. [1,2,3] instead of 1,2,3) to a .+ or .* parameter\n  the parameter must be passed by name to avoid ambiguity!\n\n  Example script function definition:\n    function foo(val_array \"n\")\n\n  Value seen inside the function body:\n      Call                          Value of n\n      foo()                         Undefined\n      foo(1)                        [1] (*)\n      foo(1,2,3)                    [1,2,3] (*)\n      foo([1,2,3])            !     [[1,2,3]] (*)\n      foo([1,2,3],[4,5])      !     [[1,2,3],[4,5]] (*)\n      foo(n=[1,2,3])                [1,2,3]\n      foo(n=[[1,2,3],[4,5]])        [[1,2,3],[4,5]]\n      foo(n=[])                     []\n      foo(n=1)                      [1] (**)\n      foo(n=\"hello\")                [\"hello\"]  (**)\n\n    *  compatible Avisynth way: comma delimited consecutive values form an array\n    ** simple-type value passed to a named array parameter will be created as a 1-element real array\n\n      // unnamed signature\n    function foo(val_array n)\n      Call                          n\n      foo()                         [] (defined and array size is zero) Avisynth compatible behaviour\n*/\n\n        if (size == 0 && p[1] == '+') // '+': one or more\n        {\n          if(!last_was_named)\n            ThrowError(\"A zero-sized array (or empty parameter list) appeared in the place of an unnamed parameter to function %s which expects a 'one-or-more' style array argument\", name);\n          args3.push_back(AVSValue()); // push undefined\n          args3_really_filled.push_back(false); // zero sized (not found) array can be specified later with argname\n        }\n        else {\n          if (size == 0) {\n            if (last_was_named)\n              args3.push_back(AVSValue());\n            // Named array is left Undefined here. In a later section it can be overridden with named argument\n            // This ensures that passing empty [] is different than not passing anything (Defined() vs. Undefined())\n            // because of this (undefined instead of zero-sized array) BlankClip was changed to handle to allow the parameter as undefined.\n            else {\n              args3.push_back(AVSValue(NULL, 0));\n              // Unnamed parameter: array of zero size.\n              // Fixme cosmetics: Maybe this one even cannot be reached, because an unnamed compulsory parameter cannot be 'zero or more' array\n            }\n          }\n          else\n            // create a proper array from the list of elements\n            args3.push_back(AVSValue(args2.data() + argbase + start, (int)size)); // can't delete args2 early because of this\n\n          if (last_was_named && size > 0)\n            args3_really_filled.push_back(true); // valid array content\n          else\n            args3_really_filled.push_back(false); // zero sized (not found) array can be specified later with argname\n        }\n      }\n\n      p += 2; // skip type-char and '*' or '+'\n      last_was_named = false;\n    }\n    else {\n      if (src_index < args2_count) {\n        // At this point we could still have an array in AVSValue because a directly given (e.g. [1,2,3]) array is accepted at the place of a \".\" (any) type\n        // The signature checker recognizes and reports a signature match in AVSFunction::TypeMatch\n        // Example call: fn([1,2,3]) where fn has a signature of \"c[n].\"\n        // Allowing it does not do any harm\n        // FIXME, When removed, we'd better remove the limitation in (look for: QWERTZUIOP)\n#ifdef DISABLE_ARRAYS_WHEN_DOT_ALONE\n        if (args2[argbase + src_index].IsArray() && p[0] != 'a') {\n          ThrowError((std::string(\"An array is passed to a non-array parameter type in function \") + std::string(name)).c_str());\n        }\n        else \n#endif\n        {\n          args3.push_back(args2[argbase + src_index]);\n        }\n        args3_really_filled.push_back(true);\n      }\n      else {\n        args3.push_back(AVSValue());\n        args3_really_filled.push_back(false);\n      }\n      src_index++;\n      p++;\n      // Skip possible array marker for named arrays like [colors]f+\n      // Note: this declaration style is recognized only for versions >= 3.5.3\n      // so plugins using this syntax won't load/work with older AviSynth versions\n      // Older versions without this check will report various errors like \"named parameter was given more than once\"\n      // but only when given with names. Providing a named parameter as unnamed was possible from \n      // direct plugin use formerly as well.\n      if ((p[0] == '*') || (p[0] == '+'))\n        p++;\n\n      last_was_named = false;\n    }\n  }\n  if (src_index < args2_count)\n    ThrowError(\"Too many arguments to function %s\", name);\n\n  // Step #4: Named arguments\n\n  // copy named args\n  for (int i = 0; i<args_names_count; ++i) {\n    if (arg_names[i]) {\n      size_t named_arg_index = 0;\n      for (const char* p = f->param_types; *p; ++p) {\n        if (*p == '*' || *p == '+') {\n          continue;   // without incrementing named_arg_index\n        }\n        else if (*p == '[') {\n          p += 1;\n          const char* q = strchr(p, ']');\n          if (!q) break;\n          if (strlen(arg_names[i]) == size_t(q - p) && !_strnicmp(arg_names[i], p, q - p)) {\n            // we have a match\n            if (args3[named_arg_index].Defined() && args3_really_filled[named_arg_index]) {\n              // when a parameter like named array was filled as an empty array\n              // from the unnamed section we don't throw error for the first time\n              ThrowError(\"Script error: the named argument \\\"%s\\\" was passed more than once (twice as named or first unnamed then named) to %s\", arg_names[i], name);\n            }\n            else if (args[i].Defined() && args[i].IsArray() && ((q[2] == '*' || q[2] == '+')) && !AVSFunction::SingleTypeMatchArray(q[1], args[i], false))\n            {\n              // e.g. passing colors=[235, 128, \"Hello\"] to [colors]f+\n              ThrowError(\"Script error: the named array argument \\\"%s\\\" to %s had a wrong element type\", arg_names[i], name);\n            }\n            else if (args[i].Defined() && !args[i].IsArray() && !AVSFunction::SingleTypeMatch(q[1], args[i], false))\n            {\n              ThrowError(\"Script error: the named argument \\\"%s\\\" to %s had the wrong type (passed '%c')\", arg_names[i], name, args[i].GetType(), q[1]);\n            }\n            else {\n              if (args[i].Defined() && args[i].IsArray()) {\n                // e.g. foo(sigma=[1.0, 1.1]) to [sigma]f is invalid \n                if (!(q[2] == '*' || q[2] == '+') && q[1] != '.' && q[1] != 'a')\n                  ThrowError(\"Script error: the named argument \\\"%s\\\" to %s had the wrong type (passed an array to a non-array and not-any parameter)\", arg_names[i], name);\n                if (q[2] == '+' && args[i].ArraySize() == 0)\n                  ThrowError(\"Script error: the named argument \\\"%s\\\" to %s is a 'one-or-more' element style array but had zero element count.\", arg_names[i], name);\n              }\n              // Note (after having array type parameters in script functions)\n              // When passing a simple value to an array parameter, we should really make an array of it\n              // or else script function parameters of array types won't see this parameter as an array inside the function body.\n              // Note: Unlike AVS scripts a real plugin - through Avisynth interface - is \n              // - allowed to index an AVSValue which is not even an array. Index 0 returns the simple-type value itself.\n              // - calling AVSValue ArraySize() returns 1\n              // But an AVS script syntax indexing and ArraySize() requires a real array, simple base type is not allowed there.\n              if(args[i].Defined() && !args[i].IsArray() && (q[2] == '*' || q[2] == '+' || q[1] == 'a'))\n                args3[named_arg_index] = AVSValue(&args[i],1); // really create an array with one element\n              else\n                args3[named_arg_index] = args[i];\n              args3_really_filled[named_arg_index] = true;\n              goto success;\n            }\n          }\n          else {\n            p = q + 1;\n          }\n        }\n        named_arg_index++;\n      }\n      // failure\n      ThrowError(\"Script error: %s does not have a named argument \\\"%s\\\"\", name, arg_names[i]);\n    success:;\n    }\n  }\n\n  std::vector<AVSValue>(args3).shrink_to_fit();\n\n  // end of parameter matching and parsing\n\n  if(is_runtime) {\n    // Invoked by a thread or GetFrame\n    AVSValue funcArgs(args3.data(), (int)args3.size());\n\n    if (f->isPluginAvs25) // like GRunT's AverageLuma wrapper\n      *result = f->apply(funcArgs, f->user_data, (IScriptEnvironment*)((IScriptEnvironment_Avs25*)env_thread));\n    else if (f->isPluginPreV11C)\n      *result = f->apply(funcArgs, f->user_data, (IScriptEnvironment*)((IScriptEnvironment_AvsPreV11C*)env_thread));\n    else\n      *result = f->apply(funcArgs, f->user_data, env_thread);\n    return true;\n  }\n\n  // 3.7.2: changed memory_mutex to invoke_mutex\n  // Concurrent GetFrame with Invoke causes deadlock.\n  // Healing mode #2\n  std::lock_guard<std::recursive_mutex> env_lock(invoke_mutex);\n\n  // Concurrent GetFrame with Invoke causes deadlock.\n  // Increment this variable when Invoke running\n  // to prevent submitting job to threadpool\n  // Healing mode #1 from Neo\n  ScopedCounter suppressThreadCount_(threadEnv->GetSuppressThreadCount());\n\n  // chainedCtor is true if we are being constructed inside/by the\n  // constructor of another filter. In that case we want MT protections\n  // applied not here, but by the Invoke() call of that filter.\n  const bool chainedCtor = invoke_stack.size() > 0;\n\n  MtModeEvaluator mthelper;\n\n  // Save clips whether one of them is returned unaltered after Invoke\n  std::vector<IClip*> clip_parameters_raw;\n\n  bool foundClipArgument = false;\n  for (int i = argbase; i < (int)args2.size(); ++i)\n  {\n    auto& argx = args2[i];\n    // todo PF 161112 new arrays: recursive look into arrays whether they contain clips\n    if (argx.IsClip())\n    {\n      foundClipArgument = true;\n\n      const PClip &clip = argx.AsClip();\n      IClip *clip_raw = (IClip*)((void*)clip);\n      ClipDataStore *data = this->ClipData(clip_raw);\n      // Save clips whether one of them is returned unaltered after Invoke\n      clip_parameters_raw.push_back(clip_raw);\n\n      if (!data->CreatedByInvoke)\n      {\n#ifdef _DEBUG\n        _RPT3(0, \"ScriptEnvironment::Invoke.AddChainedFilter %s thread %d this->DefaultMtMode=%d\\n\", name, GetCurrentThreadId(), (int)this->DefaultMtMode);\n#endif\n        mthelper.AddChainedFilter(clip, this->DefaultMtMode);\n      }\n    }\n  }\n  bool isSourceFilter = !foundClipArgument;\n\n  // Capture call-time parameter values for filter-prop injection.\n  // Must run before funcCtor (which moves args3) so we can read args3 here.\n  // Using args3 (by now it is fully resolved) lets us match both positional and named call args.\n  // For 99.9% of filters (not in FilterPropMap) this is just one fast O(1) map lookup.\n  // Memo: f->param_types is the full function parameter signature.\n  const std::vector<PropEntry>* prop_entries_to_inject = nullptr;\n  std::vector<PropEntry> captured_entries;\n  if (f->name != nullptr) {\n    const std::string fname_for_prop = NormalizeString(f->canon_name ? f->canon_name : f->name);\n    auto prop_it = FilterPropMap.find(fname_for_prop);\n    if (prop_it == FilterPropMap.end() && f->canon_name != nullptr)\n      prop_it = FilterPropMap.find(NormalizeString(f->name));\n    if (prop_it != FilterPropMap.end()) {\n      bool needs_capture = false;\n      for (const auto& e : prop_it->second)\n        if (!e.value.Defined() || !e.param_name.empty()) { needs_capture = true; break; }\n      if (needs_capture) {\n        // Scan f->param_types for a [name]type parameter, return its args3 index or -1.\n        // Works for both positional and named call args because args3 is fully resolved.\n        auto findParamIdx = [&](const char* pname) -> int {\n          int idx = 0;\n          for (const char* p = f->param_types; *p; ++p) {\n            if (*p == '*' || *p == '+') continue; // modifier, doesn't add a new slot\n            if (*p == '[') {\n              ++p;\n              const char* q = strchr(p, ']');\n              if (!q) break;\n              if (!_strnicmp(pname, p, q - p) && strlen(pname) == size_t(q - p))\n                return idx; // found: args3[idx] holds this param's value\n              p = q + 1;    // advance to type char, outer ++p moves past it\n            }\n            idx++;\n          }\n          return -1;\n        };\n        auto scalarMatch = [](const AVSValue& actual, const AVSValue& candidate) -> bool {\n          if (actual.IsString() && candidate.IsString())\n            return _stricmp(actual.AsString(), candidate.AsString()) == 0;\n          // bool and int are interchangeable: true==1, false==0\n          if ((actual.IsInt() || actual.IsBool()) && (candidate.IsInt() || candidate.IsBool())) {\n            int64_t a = actual.IsInt()    ? actual.AsLong()             : (actual.AsBool()    ? 1LL : 0LL);\n            int64_t c = candidate.IsInt() ? candidate.AsLong()          : (candidate.AsBool() ? 1LL : 0LL);\n            return a == c;\n          }\n          return (actual.IsFloat() && candidate.IsFloat() &&\n                  actual.AsFloat() == candidate.AsFloat());\n        };\n        captured_entries = prop_it->second; // copy to resolve\n        for (auto& entry : captured_entries) {\n          if (!entry.param_name.empty()) {\n            // Conditional: find formal param 'param_name' in args3 and compare to param_match.\n            // param_match may be a scalar or an alias array (any element satisfies).\n            // Works for positional and named call sites alike.\n            int idx = findParamIdx(entry.param_name.c_str());\n            if (idx < 0 || idx >= (int)args3.size() || !args3[idx].Defined()) {\n              entry.key.clear(); // param not in signature or not provided: skip\n            } else {\n              const AVSValue& actual = args3[idx];\n              bool matched = false;\n              if (entry.param_match.IsArray()) {\n                for (int j = 0; j < entry.param_match.ArraySize() && !matched; ++j)\n                  matched = scalarMatch(actual, entry.param_match[j]);\n              } else {\n                matched = scalarMatch(actual, entry.param_match);\n              }\n              if (!matched)\n                entry.key.clear(); // condition not met: skip\n            }\n          } else if (!entry.value.Defined()) {\n            // Unconditional capture: find formal param named entry.key in args3.\n            int idx = findParamIdx(entry.key.c_str());\n            if (idx >= 0 && idx < (int)args3.size() && args3[idx].Defined())\n              entry.value = args3[idx];\n            // Still undefined: param not found or not passed; skipped at injection\n          }\n        }\n        prop_entries_to_inject = &captured_entries;\n      } else {\n        prop_entries_to_inject = &(prop_it->second); // all entries have static values\n      }\n    }\n  }\n\n  // Capture passthrough source clip before funcCtor moves args3.\n  // Only set when the filter is registered in FilterPropPassthroughSet AND args3[0] is a clip.\n  PClip prop_passthrough_src;\n  if (f->name != nullptr) {\n    const std::string fname_pt = NormalizeString(f->canon_name ? f->canon_name : f->name);\n    bool in_set = FilterPropPassthroughSet.count(fname_pt) > 0;\n    if (!in_set && f->canon_name != nullptr)\n      in_set = FilterPropPassthroughSet.count(NormalizeString(f->name)) > 0;\n    if (in_set && !args3.empty() && args3[0].IsClip())\n      prop_passthrough_src = args3[0].AsClip();\n  }\n\n  auto call_env = f->isPluginAvs25 || f->isPluginPreV11C ? nullptr : threadEnv.get();\n  auto call_env25 = f->isPluginAvs25 ? threadEnv.get()->GetEnv25() : nullptr;\n  auto call_envPreV11C = f->isPluginPreV11C ? threadEnv.get()->GetEnvPreV11C() : nullptr;\n  // ... and we're finally ready to make the call\n  std::unique_ptr<const FilterConstructor> funcCtor =\n    std::make_unique<const FilterConstructor>(call_env, call_env25, call_envPreV11C, f, &args2, &args3);\n  _RPT1(0, \"ScriptEnvironment::Invoke after funcCtor make unique %s\\r\\n\", name);\n\n  // args2 and args3 are not valid after this point anymore\n\n  bool is_mtmode_forced;\n  bool filterHasSpecialMT = this->GetFilterMTMode(f, &is_mtmode_forced) == MT_SPECIAL_MT;\n\n  bool instantiated_clip_unaltered = false;\n#ifdef _DEBUG\n  bool cache_guard_called = false;\n#endif\n\n  if (filterHasSpecialMT) // pre-avs 3.6 workaround for MP_Pipeline\n  {\n    *result = funcCtor->InstantiateFilter();\n#ifdef _DEBUG\n    _RPT1(0, \"ScriptEnvironment::Invoke done funcCtor->InstantiateFilter %s\\r\\n\", name);\n#endif\n    if ((*result).IsClip()) {\n      // PropPassthrough: forward input frame properties for old filters that drop them.\n      // Inserted before SetFilterProp entries so specific injections override inherited props.\n      if (prop_passthrough_src)\n        *result = new PropPassthrough((*result).AsClip(), prop_passthrough_src, threadEnv.get());\n      // property injection\n      if (prop_entries_to_inject != nullptr) {\n        for (const auto& entry : *prop_entries_to_inject) {\n          if (entry.key.empty()) continue;\n          if (!entry.value.Defined()) continue;\n          const char* saved_key = threadEnv->SaveString(entry.key.c_str());\n          AVSValue prop_args[4] = { *result, AVSValue(saved_key), entry.value, AVSValue(entry.mode) };\n          *result = SetProperty::Create(AVSValue(prop_args, 4), (void*)0, threadEnv.get());\n        }\n      }\n    }\n  }\n  else if (funcCtor->IsScriptFunction())\n  {\n    // Eval, EvalOop, Import and user defined script functions\n    // Warn user if he set an MT-mode for a script function\n    if (this->FilterHasMtMode(f))\n    {\n      OneTimeLogTicket ticket(LOGTICKET_W1010, f);\n      LogMsgOnce(ticket, LOGLEVEL_WARNING, \"An MT-mode is set for %s() but it is a script function. You can only set the MT-mode for binary filters, for scripted functions it will be ignored.\", f->name);\n    }\n\n    *result = funcCtor->InstantiateFilter();\n#ifdef _DEBUG\n    _RPT1(0, \"ScriptEnvironment::Invoke done funcCtor->InstantiateFilter %s\\r\\n\", name);\n#endif\n    if ((*result).IsClip()) {\n      if (prop_passthrough_src)\n        *result = new PropPassthrough((*result).AsClip(), prop_passthrough_src, threadEnv.get());\n      if (prop_entries_to_inject != nullptr) {\n        for (const auto& entry : *prop_entries_to_inject) {\n          if (entry.key.empty()) continue;\n          if (!entry.value.Defined()) continue;\n          const char* saved_key = threadEnv->SaveString(entry.key.c_str());\n          AVSValue prop_args[4] = { *result, AVSValue(saved_key), entry.value, AVSValue(entry.mode) };\n          *result = SetProperty::Create(AVSValue(prop_args, 4), (void*)0, threadEnv.get());\n        }\n      }\n    }\n  }\n  else\n  {\n#ifdef _DEBUG\n    AvsCache *PrevFrontCache = FrontCache;\n#endif\n\n    AVSValue fret;\n\n    invoke_stack.push(&mthelper);\n    try\n    {\n      fret = funcCtor->InstantiateFilter();\n\n      // Detect whether one of the parameter clip was returned unaltered.\n      // Introduce bool instantiated_clip_unaltered.\n      if (fret.IsClip()) {\n        const PClip& clip = fret.AsClip();\n        IClip* clip_raw = (IClip*)((void*)clip);\n        for (auto comparewith : clip_parameters_raw) {\n          if (comparewith == clip_raw) {\n            _RPT1(0, \"ScriptEnvironment::Invoke funcCtor->InstantiateFilter %s returned the very same clip unaltered that was in a parameter\\r\\n\", name);\n            instantiated_clip_unaltered = true;\n            break;\n          }\n        }\n      }\n\n      invoke_stack.pop();\n    }\n    catch (...)\n    {\n      // comment: Issue20200818\n      invoke_stack.pop();\n      throw;\n    }\n\n    // Determine MT-mode, as if this instance had not called Invoke()\n    // in its constructor. Note that this is not necessary the final\n    // MT-mode.\n    // PF 161012 hack(?) don't call if prefetch. If effective mt mode is MT_MULTI, then\n    // Prefetch create gets called again\n    // Prefetch is activated above in: fret = funcCtor->InstantiateFilter();\n    if (fret.IsClip() && (f->name == nullptr || strcmp(f->name, \"Prefetch\")))\n    {\n      const PClip &clip = fret.AsClip();\n\n      bool is_mtmode_forced;\n      this->GetFilterMTMode(f, &is_mtmode_forced);\n      MtMode mtmode = MtModeEvaluator::GetMtMode(clip, f, threadEnv.get());\n\n      if (chainedCtor)\n      {\n        // Propagate information about our children's MT-safety\n          // to our parent.\n        invoke_stack.top()->Accumulate(mthelper);\n\n        // Add our own MT-mode's information to the parent.\n        invoke_stack.top()->Accumulate(mtmode);\n\n        *result = fret;\n      }\n      else\n      {\n        if (!is_mtmode_forced) {\n          mtmode = mthelper.GetFinalMode(mtmode);\n        }\n\n        // Special handling for source filters\n        if (isSourceFilter\n          && MtModeEvaluator::UsesDefaultMtMode(clip, f, threadEnv.get())\n          && (MT_SERIALIZED != mtmode))\n        {\n          mtmode = MT_SERIALIZED;\n          OneTimeLogTicket ticket(LOGTICKET_W1001, f);\n          LogMsgOnce(ticket, LOGLEVEL_INFO, \"%s() does not have any MT-mode specification. Because it is a source filter, it will use MT_SERIALIZED instead of the default MT mode.\", f->canon_name);\n        }\n\n        // pass current directory as well, in order to remember it when a MT_MULTI_INSTANCE filter is populated to threads during Prefetch\n        auto current_directory = CWDChanger::GetCurrentWorkingDirectory(); // wstring on Windows, string on POSIX\n\n        // Do dot create MTGuard on an already existing clip\n        if (!instantiated_clip_unaltered) {\n          *result = MTGuard::Create(mtmode, clip, std::move(funcCtor), current_directory.c_str(), threadEnv.get());\n\n          IClip *clip_raw = (IClip*)((void*)clip);\n          ClipDataStore *data = this->ClipData(clip_raw);\n          data->CreatedByInvoke = true;\n        }\n        else {\n          *result = clip;\n        }\n      } // if (chainedCtor)\n\n      // Nekopanda: moved here from above.\n      // some filters invoke complex filters in its constructor, and they need cache.\n      // pf: Do not introduce (another) cache on an existing PClip\n      if (!instantiated_clip_unaltered) {\n        AVSValue args_cacheguard[2]{ *result, f->name };\n        *result = CacheGuard::Create(AVSValue(args_cacheguard, 2), NULL, threadEnv.get());\n#ifdef _DEBUG\n        cache_guard_called = true;\n#endif\n\n        // Check that the filter returns zero for unknown queries in SetCacheHints().\n        // This is actually something we rely upon.\n        if ((clip->GetVersion() >= 5) && (0 != clip->SetCacheHints(CACHE_USER_CONSTANTS, 0)))\n        {\n          OneTimeLogTicket ticket(LOGTICKET_W1002, f);\n          LogMsgOnce(ticket, LOGLEVEL_WARNING, \"%s() violates semantic contracts and may cause undefined behavior. Please inform the author of the plugin.\", f->canon_name);\n        }\n\n        // Warn user if the MT-mode of this filter is unknown\n        if (MtModeEvaluator::UsesDefaultMtMode(clip, f, threadEnv.get()) && !isSourceFilter)\n        {\n          OneTimeLogTicket ticket(LOGTICKET_W1004, f);\n          LogMsgOnce(ticket, LOGLEVEL_WARNING, \"%s() has no MT-mode set and will use the default MT-mode. This might be dangerous.\", f->canon_name);\n        }\n\n        // Warn user if he forced an MT-mode that differs from the one specified by the filter itself\n        if (is_mtmode_forced\n          && MtModeEvaluator::ClipSpecifiesMtMode(clip)\n          && MtModeEvaluator::GetInstanceMode(clip) != mtmode)\n        {\n          OneTimeLogTicket ticket(LOGTICKET_W1005, f);\n          LogMsgOnce(ticket, LOGLEVEL_WARNING, \"%s() specifies an MT-mode for itself, but a script forced a different one. Either the plugin or the script is erronous.\", f->canon_name);\n        }\n\n        // Inform user if a script unnecessarily specifies an MT-mode for this filter\n        if (!is_mtmode_forced\n          && this->FilterHasMtMode(f)\n          && MtModeEvaluator::ClipSpecifiesMtMode(clip))\n        {\n          OneTimeLogTicket ticket(LOGTICKET_W1006, f);\n          LogMsgOnce(ticket, LOGLEVEL_INFO, \"Ignoring unnecessary MT-mode specification for %s() by script.\", f->canon_name);\n        }\n      }\n\n      // Auto-inject registered frame properties for this filter, outside !instantiated_clip_unaltered:\n      // rules apply even when the filter returned a parameter clip unaltered.\n      // PropPassthrough wraps first so specific SetFilterProp entries override inherited props.\n      if ((*result).IsClip()) {\n        if (prop_passthrough_src)\n          *result = new PropPassthrough((*result).AsClip(), prop_passthrough_src, threadEnv.get());\n        // prop_entries_to_inject was resolved before InstantiateFilter(); undefined entries are\n        // ones where capture-from-param failed (no matching named arg) and are skipped here.\n        if (prop_entries_to_inject != nullptr) {\n          for (const auto& entry : *prop_entries_to_inject) {\n            if (entry.key.empty()) continue;        // conditional entry: param did not match\n            if (!entry.value.Defined()) continue;   // capture-from-param: no named arg matched\n            const char* saved_key = threadEnv->SaveString(entry.key.c_str());\n            AVSValue prop_args[4] = { *result, AVSValue(saved_key), entry.value, AVSValue(entry.mode) };\n            *result = SetProperty::Create(AVSValue(prop_args, 4), (void*)0, threadEnv.get());\n          }\n        }\n      }\n\n    } // if (fret.IsClip())\n    else\n    {\n      *result = fret;\n    }\n\n    // static device check\n    // this is not enough to check all dependencies but much helpful to users\n    if ((*result).IsClip()) {\n      auto last = (argbase == 0) ? implicit_last : AVSValue();\n      CheckChildDeviceTypes((*result).AsClip(), name, last, args, arg_names, threadEnv.get());\n    }\n\n    // filter graph\n    if (graphAnalysisEnable && (*result).IsClip()) {\n      auto last = (argbase == 0) ? implicit_last : AVSValue();\n      *result = new FilterGraphNode((*result).AsClip(), f->name, last, args, arg_names, threadEnv.get());\n    }\n\n#ifdef _DEBUG\n    if (PrevFrontCache != FrontCache && FrontCache != NULL) // cache registering swaps frontcache to the current\n    {\n      std::string real_function_name = name;\n      if (!cache_guard_called) {\n        real_function_name = \"Unknow_Function_Invoked_By_No-Op_\" + real_function_name + \"_Create\";\n        _RPT2(0, \"ScriptEnvironment::Invoke nearEnd: FrontCache altered, (but no direct AvsCache call) FuncName=%s  cache_id=%p\\r\\n\", real_function_name.c_str(), (void*)FrontCache);\n      }\n      else {\n        _RPT2(0, \"ScriptEnvironment::Invoke nearEnd: FrontCache altered. FuncName=%s  cache_id=%p\\r\\n\", real_function_name.c_str(), (void*)FrontCache);\n      }\n      FrontCache->FuncName = real_function_name; // helps debugging. See also in cache.cpp\n    }\n    _RPT1(0, \"ScriptEnvironment::Invoke done %s\\r\\n\", name);\n#endif\n  }\n\n  return true;\n}\n\n\nbool ScriptEnvironment::FunctionExists(const char* name)\n{\n  std::unique_lock<std::recursive_mutex> env_lock(plugin_mutex);\n\n  // Look among variable table\n  AVSValue result;\n  if (threadEnv->GetVarTry(name, &result)) {\n    if (result.IsFunction()) {\n      return true;\n    }\n  }\n\n  // Look among internal functions\n  if (InternalFunctionExists(name))\n    return true;\n\n  // Look among plugin functions\n  if (plugin_manager->FunctionExists(name))\n    return true;\n\n  // Uhh... maybe if we load the plugins we'll have the function\n  if (!plugin_manager->HasAutoloadExecuted())\n  {\n    plugin_manager->AutoloadPlugins();\n    return this->FunctionExists(name);\n  }\n\n  return false;\n}\n\nbool ScriptEnvironment::InternalFunctionExists(const char* name)\n{\n  for (int i = 0; i < sizeof(builtin_functions)/sizeof(builtin_functions[0]); ++i)\n    for (const AVSFunction* j = builtin_functions[i]; !j->empty(); ++j)\n      if (streqi(j->name, name))\n        return true;\n\n  return false;\n}\n\nvoid ScriptEnvironment::BitBlt(BYTE* dstp, int dst_pitch, const BYTE* srcp, int src_pitch, int row_size, int height) {\n  if (height<0)\n    ThrowError(\"Filter Error: Attempting to blit an image with negative height.\");\n  if (row_size<0)\n    ThrowError(\"Filter Error: Attempting to blit an image with negative row size.\");\n  ::BitBlt(dstp, dst_pitch, srcp, src_pitch, row_size, height);\n}\n\nvoid ScriptEnvironment::ThrowError(const char* fmt, ...)\n{\n  va_list val;\n  va_start(val, fmt);\n  threadEnv->VThrowError(fmt, val);\n  va_end(val);\n}\n\nvoid ScriptEnvironment::VThrowError(const char* fmt, va_list va)\n{\n  threadEnv->VThrowError(fmt, va);\n}\n\n// since IF V8 it moved from IScriptEnvironment2 to IScriptEnvironment\nPVideoFrame ScriptEnvironment::SubframePlanarA(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV, int rel_offsetA)\n{\n  return SubframePlanar(src, rel_offset, new_pitch, new_row_size, new_height, rel_offsetU, rel_offsetV, new_pitchUV, rel_offsetA);\n}\n\nbool ScriptEnvironment::MakePropertyWritable(PVideoFrame* pvf)\n{\n  const PVideoFrame& vf = *pvf;\n\n  // If the frame is already writable, do nothing.\n  if (vf->IsPropertyWritable())\n    return false;\n\n  // Otherwise, allocate a new frame (using Subframe)\n  // Thus we avoid the frame-content copy overhead and still get a new frame with its unique frameprop\n  VideoFrame *dst;\n  if (vf->GetPitch(PLANAR_A)) {\n    // planar + alpha\n    dst = vf->Subframe(0, vf->GetPitch(), vf->GetRowSize(), vf->GetHeight(), 0, 0, vf->GetPitch(PLANAR_U), 0);\n  }\n  else if (vf->GetPitch(PLANAR_U)) {\n    // planar\n    dst = vf->Subframe(0, vf->GetPitch(), vf->GetRowSize(), vf->GetHeight(), 0, 0, vf->GetPitch(PLANAR_U));\n  }\n  else {\n    // single plane\n    dst = vf->Subframe(0, vf->GetPitch(), vf->GetRowSize(), vf->GetHeight());\n  }\n\n  const AVSMap& avsmap = vf->getConstProperties();\n  if (propNumKeys(&avsmap) > 0)\n    dst->setProperties(avsmap);\n\n  size_t vfb_size = vf->GetFrameBuffer()->GetDataSize();\n\n  // vector and maps needs locking!\n  std::unique_lock<std::recursive_mutex> env_lock(memory_mutex);\n  assert(dst != NULL);\n\n  RegisterSubFrameInRegistry(vfb_size, vf->GetFrameBuffer(), dst);\n\n  *pvf = dst;\n  return true;\n}\n\n// since IF V8 frame property helpers are part of IScriptEnvironment\nvoid ScriptEnvironment::copyFrameProps(const PVideoFrame& src, PVideoFrame& dst)\n{\n  dst->setProperties(src->getProperties());\n}\n\n// frame properties support\n// core imported from VapourSynth\n// from vsapi.cpp\nconst AVSMap* ScriptEnvironment::getFramePropsRO(const PVideoFrame& frame) AVS_NOEXCEPT {\n  assert(frame);\n  return &(frame->getConstProperties());\n}\n\nAVSMap* ScriptEnvironment::getFramePropsRW(PVideoFrame &frame) AVS_NOEXCEPT {\n  assert(frame);\n  return &(frame->getProperties());\n}\n\nint ScriptEnvironment::propNumKeys(const AVSMap* map) AVS_NOEXCEPT {\n  assert(map);\n  return static_cast<int>(map->size());\n}\n\nconst char* ScriptEnvironment::propGetKey(const AVSMap* map, int index) AVS_NOEXCEPT {\n  assert(map);\n  if (index < 0 || static_cast<size_t>(index) >= map->size())\n    ThrowError((\"propGetKey: Out of bounds index \" + std::to_string(index) + \" passed. Valid range: [0,\" + std::to_string(map->size() - 1) + \"]\").c_str());\n\n  return map->key(index);\n}\n\nint ScriptEnvironment::propNumElements(const AVSMap* map, const char* key) AVS_NOEXCEPT {\n  assert(map && key);\n  VSArrayBase* val = map->find(key);\n  return val ? static_cast<int>(val->size()) : -1;\n}\n\nchar ScriptEnvironment::propGetType(const AVSMap* map, const char* key) AVS_NOEXCEPT {\n  assert(map && key);\n  const char a[] = { 'u', 'i', 'f', 's', 'm', 'c', '?', 'v', '?' };\n  /*\n    u PROPERTYTYPE_UNSET = 0, // ptUnset = 0,\n    i PROPERTYTYPE_INT = 1, // ptInt = 1,\n    f PROPERTYTYPE_FLOAT = 2, //  ptFloat = 2,\n    s PROPERTYTYPE_DATA = 3, // ptData = 3,\n    m //  ptFunction = 4,\n    c PROPERTYTYPE_CLIP = 5, // ptVideoNode = 5,\n    ? //  ptAudioNode = 6,\n    v PROPERTYTYPE_FRAME = 7, //  ptVideoFrame = 7,\n    ? //  ptAudioFrame = 8\n  */\n  VSArrayBase* val = map->find(key);\n  return val ? a[val->type()] : 'u';\n}\n\nint ScriptEnvironment::propDeleteKey(AVSMap* map, const char* key) AVS_NOEXCEPT {\n  assert(map && key);\n  return map->erase(key);\n}\n\nstatic VSArrayBase* propGetShared(const AVSMap* map, const char* key, int index, int* error, AVSPropertyType propType, ScriptEnvironment *env) noexcept {\n  assert(map && key && index >= 0);\n\n  if (error)\n    *error = AVSGetPropErrors::GETPROPERROR_SUCCESS; // peSuccess;\n\n  if (map->hasError()) {\n    if (error)\n      *error = AVSGetPropErrors::GETPROPERROR_ERROR; // peError;\n    else\n      env->ThrowError((\"Property read unsuccessful on map with error set but no error output: \" + std::string(key)).c_str());\n    return nullptr;\n  }\n\n  VSArrayBase* arr = map->find(key);\n\n  if (!arr) {\n    if (error)\n      *error = AVSGetPropErrors::GETPROPERROR_UNSET; // peUnset;\n    else\n      env->ThrowError((\"Property read unsuccessful due to missing key but no error output: \" + std::string(key)).c_str());\n    return nullptr;\n  }\n\n  if (index < 0 || index >= static_cast<int>(arr->size())) {\n    if (error)\n      *error = AVSGetPropErrors::GETPROPERROR_INDEX; // peIndex;\n    else\n      env->ThrowError((\"Property read unsuccessful due to out of bounds index but no error output: \" + std::string(key)).c_str());\n    return nullptr;\n  }\n\n  if (arr->type() != propType) {\n    if (error)\n      *error = AVSGetPropErrors::GETPROPERROR_TYPE; // peType;\n    else\n      env->ThrowError((\"Property read unsuccessful due to wrong type but no error output: \" + std::string(key)).c_str());\n    return nullptr;\n  }\n\n  return arr;\n}\n\nint64_t ScriptEnvironment::propGetInt(const AVSMap* map, const char* key, int index, int* error) AVS_NOEXCEPT {\n  VSArrayBase* arr = propGetShared(map, key, index, error, AVSPropertyType::PROPERTYTYPE_INT, this); //  ptInt\n  if (arr)\n    return reinterpret_cast<const VSIntArray*>(arr)->at(index);\n  else\n    return 0;\n}\n\nint ScriptEnvironment::propGetIntSaturated(const AVSMap* map, const char* key, int index, int* error) AVS_NOEXCEPT {\n  int internalError = 0;\n  int64_t value = propGetInt(map, key, index, &internalError);\n\n  if (error) {\n    *error = internalError;\n  }\n\n  if (internalError == 0) {\n    if (value > std::numeric_limits<int>::max()) {\n      return std::numeric_limits<int>::max();\n    }\n    if (value < std::numeric_limits<int>::min()) {\n      return std::numeric_limits<int>::min();\n    }\n  }\n\n  return static_cast<int>(value);\n}\n\ndouble ScriptEnvironment::propGetFloat(const AVSMap* map, const char* key, int index, int* error) AVS_NOEXCEPT {\n  VSArrayBase* arr = propGetShared(map, key, index, error, AVSPropertyType::PROPERTYTYPE_FLOAT, this); // ptFloat\n  if (arr)\n    return reinterpret_cast<const VSFloatArray*>(arr)->at(index);\n  else\n    return 0;\n}\n\nfloat ScriptEnvironment::propGetFloatSaturated(const AVSMap* map, const char* key, int index, int* error) AVS_NOEXCEPT {\n  int internalError = 0;\n  double value = propGetFloat(map, key, index, &internalError);\n\n  if (error) {\n    *error = internalError;\n  }\n\n  if (internalError == 0) {\n    if (std::isnan(value)) {\n      return std::numeric_limits<float>::quiet_NaN();\n    }\n    if (value > std::numeric_limits<float>::max()) {\n      return std::numeric_limits<float>::max();\n    }\n    if (value < -std::numeric_limits<float>::max()) {\n      return -std::numeric_limits<float>::max();\n    }\n  }\n\n  return static_cast<float>(value);\n}\n\nconst char* ScriptEnvironment::propGetData(const AVSMap* map, const char* key, int index, int* error) AVS_NOEXCEPT {\n  VSArrayBase* arr = propGetShared(map, key, index, error, AVSPropertyType::PROPERTYTYPE_DATA, this); // ptData\n  if (arr)\n    return reinterpret_cast<const VSDataArray*>(arr)->at(index).data.c_str();\n  else\n    return nullptr;\n}\n\nint ScriptEnvironment::propGetDataSize(const AVSMap* map, const char* key, int index, int* error) AVS_NOEXCEPT {\n  VSArrayBase* arr = propGetShared(map, key, index, error, AVSPropertyType::PROPERTYTYPE_DATA, this); // ptData\n  if (arr)\n    return static_cast<int>(reinterpret_cast<const VSDataArray*>(arr)->at(index).data.size());\n  else\n    return -1;\n}\n\nint ScriptEnvironment::propGetDataTypeHint(const AVSMap* map, const char* key, int index, int* error) AVS_NOEXCEPT {\n  VSArrayBase* arr = propGetShared(map, key, index, error, AVSPropertyType::PROPERTYTYPE_DATA, this); // ptData\n  if (arr)\n    return reinterpret_cast<const VSDataArray*>(arr)->at(index).typeHint;\n  else\n    return AVSPropDataTypeHint::PROPDATATYPEHINT_UNKNOWN; // dtUnknown;\n}\n\nPClip ScriptEnvironment::propGetClip(const AVSMap* map, const char* key, int index, int* error) AVS_NOEXCEPT {\n  int dummyError;\n  VSArrayBase* arr = propGetShared(map, key, index, &dummyError, AVSPropertyType::PROPERTYTYPE_CLIP, this); // ptVideoNode\n  if (arr) {\n    // PClip itself is reference counted\n    PClip ref = reinterpret_cast<VSVideoNodeArray*>(arr)->at(index);\n    return ref;\n  }\n  else {\n    // no separate audio node in AVS\n    return nullptr;\n  }\n}\n\nconst PVideoFrame ScriptEnvironment::propGetFrame(const AVSMap* map, const char* key, int index, int* error) AVS_NOEXCEPT {\n  // PVideoFrame itself is reference counted\n  int dummyError;\n  VSArrayBase* arr = propGetShared(map, key, index, &dummyError, AVSPropertyType::PROPERTYTYPE_FRAME, this); //  ptVideoFrame\n  if (arr) {\n    PVideoFrame ref = reinterpret_cast<VSVideoFrameArray*>(arr)->at(index);\n    return ref;\n  }\n  else {\n    // no separate audio frame in AVS\n    return nullptr;\n  }\n}\n\nstatic inline bool isAlphaUnderscore(char c) {\n  return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';\n}\n\nstatic inline bool isAlphaNumUnderscore(char c) {\n  return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';\n}\n\nstatic bool isValidVSMapKey(const std::string& s) {\n  size_t len = s.length();\n  if (!len)\n    return false;\n\n  if (!isAlphaUnderscore(s[0]))\n    return false;\n  for (size_t i = 1; i < len; i++)\n    if (!isAlphaNumUnderscore(s[i]))\n      return false;\n  return true;\n}\n\nstatic int mapSetEmpty(AVSMap* map, const char* key, int type) AVS_NOEXCEPT {\n  assert(map && key);\n  if (!isValidVSMapKey(key))\n    return 1;\n\n  std::string skey = key;\n  if (map->find(skey))\n    return 1;\n\n  switch (type) {\n  case AVSPropertyType::PROPERTYTYPE_INT: // ptInt:\n    map->insert(key, new VSIntArray);\n    break;\n  case AVSPropertyType::PROPERTYTYPE_FLOAT: // ptFloat:\n    map->insert(key, new VSFloatArray);\n    break;\n  case AVSPropertyType::PROPERTYTYPE_DATA: // ptData:\n    map->insert(key, new VSDataArray);\n    break;\n  case AVSPropertyType::PROPERTYTYPE_CLIP: // ptVideoNode:\n    map->insert(key, new VSVideoNodeArray);\n    break;\n  /*\n  case ptAudioNode:\n    map->insert(key, new VSAudioNodeArray);\n    break;\n  */\n  case AVSPropertyType::PROPERTYTYPE_FRAME: // ptVideoFrame:\n    map->insert(key, new VSVideoFrameArray);\n    break;\n  /*\n  case ptAudioFrame:\n    map->insert(key, new VSAudioFrameArray);\n    break;\n  */\n  /*\n  case AVSPropertyType::PROPERTYTYPE_FUNCTION: // ptFunction:\n    map->insert(key, new VSFunctionArray);\n    break;\n  */\n  default:\n    return 1;\n  }\n  return 0;\n}\n\ntemplate<typename T, AVSPropertyType propType>\nbool propSetShared(AVSMap* map, const char* key, const T& val, int append, ScriptEnvironment *env) {\n  assert(map && key);\n  if (append != AVSPropAppendMode::PROPAPPENDMODE_REPLACE && \n      append != AVSPropAppendMode::PROPAPPENDMODE_APPEND && \n      append != AVSPropAppendMode::PROPAPPENDMODE_TOUCH) // in VS4 this mode was dropped\n    env->ThrowError(\"Invalid prop append mode given when setting key '%s'\", key);\n\n  if (!isValidVSMapKey(key))\n    return false;\n  std::string skey = key;\n\n  if (append == AVSPropAppendMode::PROPAPPENDMODE_REPLACE) {\n    VSArray<T, propType>* v = new VSArray<T, propType>();\n    v->push_back(val);\n    map->insert(key, v);\n    return true;\n  }\n  else if (append == AVSPropAppendMode::PROPAPPENDMODE_APPEND) {\n    VSArrayBase* arr = map->find(skey);\n    if (arr && arr->type() == propType) {\n      arr = map->detach(skey);\n      reinterpret_cast<VSArray<T, propType>*>(arr)->push_back(val);\n      return true;\n    }\n    else if (arr) {\n      return false;\n    }\n    else {\n      VSArray<T, propType>* v = new VSArray<T, propType>();\n      v->push_back(val);\n      map->insert(key, v);\n      return true;\n    }\n  }\n  else /* if (append == vs3::paTouch) */ {\n    return !mapSetEmpty(map, key, propType);\n  }\n}\n\n\nint ScriptEnvironment::propSetInt(AVSMap* map, const char* key, int64_t i, int append) AVS_NOEXCEPT {\n  return !propSetShared<int64_t, AVSPropertyType::PROPERTYTYPE_INT>(map, key, i, append, this); // ptInt\n}\n\nint ScriptEnvironment::propSetFloat(AVSMap* map, const char* key, double d, int append) AVS_NOEXCEPT {\n  return !propSetShared<double, AVSPropertyType::PROPERTYTYPE_FLOAT>(map, key, d, append, this); // ptFloat\n}\n\n// Unlike VS API4, Avisynth must maintain old function name, and introduce propSetDataH\nint ScriptEnvironment::propSetData(AVSMap* map, const char* key, const char* d, int length, int append) AVS_NOEXCEPT {\n  return propSetDataH(map, key, d, length, AVSPropDataTypeHint::PROPDATATYPEHINT_UNKNOWN, append); // dtUnknown\n}\n\n// v11\nint ScriptEnvironment::propSetDataH(AVSMap* map, const char* key, const char* d, int length, int type, int append) AVS_NOEXCEPT {\n  return !propSetShared<VSMapData, AVSPropertyType::PROPERTYTYPE_DATA>(map, key, { static_cast<AVSPropDataTypeHint>(type), (length >= 0) ? std::string(d, length) : std::string(d) }, append, this);\n}\n\nint ScriptEnvironment::propSetClip(AVSMap* map, const char* key, PClip& clip, int append) AVS_NOEXCEPT {\n  return !propSetShared<PClip, AVSPropertyType::PROPERTYTYPE_CLIP>(map, key, clip, append, this); // ptVideoNode\n}\n\nint ScriptEnvironment::propSetFrame(AVSMap* map, const char* key, const PVideoFrame &frame, int append) AVS_NOEXCEPT {\n  return !propSetShared<PVideoFrame, AVSPropertyType::PROPERTYTYPE_FRAME>(map, key, frame, append, this); // ptVideoFrame\n}\n\nconst int64_t* ScriptEnvironment::propGetIntArray(const AVSMap* map, const char* key, int* error) AVS_NOEXCEPT {\n  const VSArrayBase* arr = propGetShared(map, key, 0, error, AVSPropertyType::PROPERTYTYPE_INT, this);\n  if (arr) {\n    return reinterpret_cast<const VSIntArray*>(arr)->getDataPointer();\n  }\n  else {\n    return nullptr;\n  }\n}\n\nconst double* ScriptEnvironment::propGetFloatArray(const AVSMap* map, const char* key, int* error) AVS_NOEXCEPT {\n  const VSArrayBase* arr = propGetShared(map, key, 0, error, AVSPropertyType::PROPERTYTYPE_FLOAT, this);\n  if (arr) {\n    return reinterpret_cast<const VSFloatArray*>(arr)->getDataPointer();\n  }\n  else {\n    return nullptr;\n  }\n}\n\nint ScriptEnvironment::propSetIntArray(AVSMap* map, const char* key, const int64_t* i, int size) AVS_NOEXCEPT {\n  assert(map && key && size >= 0);\n  if (size < 0)\n    return 1;\n  if (!isValidVSMapKey(key))\n    return 1;\n  map->insert(key, new VSIntArray(i, size));\n  return 0;\n}\n\n int ScriptEnvironment::propSetFloatArray(AVSMap* map, const char* key, const double* d, int size) AVS_NOEXCEPT {\n   assert(map && key && size >= 0);\n   if (size < 0)\n     return 1;\n   if (!isValidVSMapKey(key))\n     return 1;\n   map->insert(key, new VSFloatArray(d, size));\n   return 0;\n }\n\nAVSMap* ScriptEnvironment::createMap() AVS_NOEXCEPT {\n  return new AVSMap();\n}\n\nvoid ScriptEnvironment::freeMap(AVSMap* map) AVS_NOEXCEPT {\n  delete map;\n}\n\nvoid ScriptEnvironment::clearMap(AVSMap* map) AVS_NOEXCEPT {\n  assert(map);\n  map->clear();\n}\n// end of frame prop support functions\n\nPDevice ScriptEnvironment::GetDevice(AvsDeviceType device_type, int device_index) const\n{\n  return Devices->GetDevice(device_type, device_index);\n}\n\nint ScriptEnvironment::SetMemoryMax(AvsDeviceType type, int index, int mem)\n{\n  return Devices->GetDevice(type, index)->SetMemoryMax(mem);\n}\n\nbool ScriptEnvironment::AcquireGlobalLock(const char* name)\n{\n  if (!name) return false;\n  std::string lock_name(name);\n  std::mutex& mtx = GlobalLockManager::get_mutex(lock_name);\n  mtx.lock(); // Blocks until lock is acquired.\n  GlobalLockManager::acquire_lock_for_env(lock_name, this); // Track for cleanup.\n  return true;\n}\n\nvoid ScriptEnvironment::ReleaseGlobalLock(const char* name)\n{\n  if (!name) return;\n  std::string lock_name(name);\n  std::mutex& mtx = GlobalLockManager::get_mutex(lock_name);\n  GlobalLockManager::release_lock_for_env(lock_name, this); // Untrack.\n  mtx.unlock();\n}\n\nPVideoFrame ScriptEnvironment::GetOnDeviceFrame(const PVideoFrame& src, Device* device)\n{\n  typedef int diff_t;\n\n  size_t srchead = GetFrameHead(src);\n\n  // make space for alignment\n  size_t size = GetFrameTail(src) - srchead;\n\n  VideoFrame *res = GetNewFrame(size, frame_align - 1, device);\n\n  const diff_t offset = (diff_t)(AlignPointer(res->vfb->GetWritePtr(), frame_align) - res->vfb->GetWritePtr()); // first line offset for proper alignment\n  const diff_t diff = offset - (diff_t)srchead;\n\n  res->offset = src->offset + diff;\n  res->pitch = src->pitch;\n  res->row_size = src->row_size;\n  res->height = src->height;\n\n  res->offsetU = src->pitchUV ? (src->offsetU + diff) : res->offset;\n  res->offsetV = src->pitchUV ? (src->offsetV + diff) : res->offset;\n  res->pitchUV = src->pitchUV;\n  res->row_sizeUV = src->row_sizeUV;\n  res->heightUV = src->heightUV;\n\n  res->offsetA = src->pitchA ? (src->offsetA + diff) : 0;\n  res->pitchA = src->pitchA;\n  res->row_sizeA = src->row_sizeA;\n\n  res->pixel_type = src->pixel_type;\n\n  *res->properties = *src->properties;\n\n  return PVideoFrame(res);\n}\n\n\nThreadPool* ScriptEnvironment::NewThreadPool(size_t nThreads)\n{\n  // Creates threads with threadIDs (which envI->GetThreadId() is returning) starting from \n  // (nTotalThreads+0) to (nTotalThreads+nThreads-1)\n  ThreadPool* pool = new ThreadPool(nThreads, nTotalThreads, threadEnv.get());\n  ThreadPoolRegistry.emplace_back(pool);\n\n  nTotalThreads += nThreads;\n\n  // TotalThreads: 1\n  //*Prefetch(3)\n  // added threads are 3, threadids: 1+0,1+1,1+2 (1,2,3)\n  // TotalThreads = 4 from now\n  // MaxFilterInstances -> 3->rounded up to 4 (next power of two). Number of instantiations\n  // ChildFilter[0..3] (size = MaxFilterInstances)\n  // GetThreadID & (4-1) = GetThreadID & 3\n  // ThreadID 1,2,3 will map to ChildFilter[x] where x is 1,2,3\n\n  // TotalThreads: 4\n  //*Prefetch(6)\n  // added threads are 6, threadids: 4+0,4+1,4+2,4+3,4+4,4+5 (4,5,6,7,8,9)\n  // TotalThreads = 10 from now\n  // MaxFilterInstances -> 6->rounded up to 8 (next power of two). Number of instantiations\n  // ChildFilter[0..7] (size = MaxFilterInstances)\n  // GetThreadID & (8-1) = GetThreadID & 7\n  // ThreadID 4,5,6,7,8,9 will map to ChildFilter[x] where x is 4,5,6,7,0,1\n\n  // TotalThreads: 10\n  //*Prefetch(3)\n  // added threads are 3, threadids: 10+0,10+1,10+2  (10,11,12)\n  // TotalThreads = 13 from now\n  // MaxFilterInstances -> 3->rounded up to 4 (next power of two). Number of instantiations\n  // ChildFilter[0..3] (size = MaxFilterInstances)\n  // GetThreadID & (4-1) = GetThreadID & 3\n  // ThreadID 10,11,12 will map to ChildFilter[x] where x is 2,3,0\n\n  // PF remark: this is not too memory friendly, because the excessive numbers of MT_MULTI_INSTANCE filters\n  // Prefetch(3) will create 4 instances\n  // Prefetch(4) will create 8 instances\n  // Prefetch(9) will still create 16 instances, of which 7 is not accessed at all\n\n  nMaxFilterInstances = nThreads; // really n/a\n  // AEP_FILTERCHAIN_THREADS environment property ID returns this value. Unlikely if someone used it\n  // for meaningful purposes.\n  // Avisynth does not use that internally, and called from a filter preceesing another Prefetch,\n  // only the last Prefetch's value is effectively returned, belonging to the actual 'env'.\n\n  // Since this method basically enables MT operation,\n  // upgrade all MTGuards to MT-mode.\n  // iterates through all filters in the chain, even is an earlier Prefetch has set the MT threads earlier\n  for (MTGuard* guard : MTGuardRegistry)\n  {\n    if (guard != NULL)\n      guard->EnableMT(nThreads);\n  }\n\n  return pool;\n}\n\nvoid ScriptEnvironment::SetDeviceOpt(DeviceOpt opt, int val)\n{\n  Devices->SetDeviceOpt(opt, val, threadEnv.get());\n}\n\nvoid ScriptEnvironment::UpdateFunctionExports(const char* funcName, const char* funcParams, const char *exportVar)\n{\n  std::unique_lock<std::recursive_mutex> env_lock(plugin_mutex);\n  plugin_manager->UpdateFunctionExports(funcName, funcParams, exportVar);\n}\n\nextern void ApplyMessage(PVideoFrame* frame, const VideoInfo& vi,\n  const char* message, int size, int textcolor, int halocolor, int bgcolor,\n  IScriptEnvironment* env);\n\nextern void ApplyMessageEx(PVideoFrame* frame, const VideoInfo& vi,\n  const char* message, int size, int textcolor, int halocolor, int bgcolor, bool utf8,\n  IScriptEnvironment* env);\n\nconst AVS_Linkage* ScriptEnvironment::GetAVSLinkage() {\n  extern const AVS_Linkage* const AVS_linkage; // In interface.cpp\n\n  return AVS_linkage;\n}\n\nvoid ScriptEnvironment::ApplyMessageEx(PVideoFrame* frame, const VideoInfo& vi, const char* message, int size, int textcolor, int halocolor, int bgcolor, bool utf8)\n{\n#ifdef ENABLE_CUDA\n  if ((*frame)->GetDevice()->device_type == DEV_TYPE_CUDA) {\n    // if frame is CUDA frame, copy to CPU and apply\n    PVideoFrame copy = GetOnDeviceFrame(*frame, Devices->GetCPUDevice());\n    CopyCUDAFrame(copy, *frame, threadEnv.get(), true);\n    ::ApplyMessageEx(&copy, vi, message, size, textcolor, halocolor, bgcolor, utf8, threadEnv.get());\n    CopyCUDAFrame(*frame, copy, threadEnv.get(), true);\n  }\n  else\n#endif\n  {\n    ::ApplyMessageEx(frame, vi, message, size, textcolor, halocolor, bgcolor, utf8, threadEnv.get());\n  }\n}\n\nvoid ScriptEnvironment::ApplyMessage(PVideoFrame* frame, const VideoInfo& vi, const char* message, int size, int textcolor, int halocolor, int bgcolor)\n{\n  ApplyMessageEx(frame, vi, message, size, textcolor, halocolor, bgcolor, false /* utf8 */);\n}\n\nvoid ScriptEnvironment::DeleteScriptEnvironment() {\n  // Provide a method to delete this ScriptEnvironment in\n  // the same malloc context in which it was created below.\n  delete this;\n}\n\n\nAVSC_API(IScriptEnvironment*, CreateScriptEnvironment)(int version) {\n  return CreateScriptEnvironment2(version);\n}\n\n// Can be called from C interface create_script_environment with specially marking the C interface source\nIScriptEnvironment2* CreateScriptEnvironment2_internal(int version, bool fromAvs25, bool fromC)\n{\n  /* Some plugins use OpenMP. But OMP threads do not exit immediately\n  * after all work is exhausted, and keep spinning for a small amount\n  * of time waiting for new jobs. If we unload the OMP DLL (indirectly\n  * by unloading its plugin that started it) while its threads are\n  * running, the sky comes crashing down. This results in crashes\n  * from OMP plugins if the IScriptEnvironment is destructed shortly\n  * after a GetFrame() call.\n  *\n  * OMP_WAIT_POLICY=passive changes the behavior of OMP thread pools\n  * to shut down immediately instead of continuing to spin.\n  * This solves our problem at the cost of some performance.\n  */\n#ifdef AVS_WINDOWS\n  _putenv(\"OMP_WAIT_POLICY=passive\");\n#endif\n\n  // When a CPP plugin explicitely requests avs2.5 interface\n  if (fromAvs25) {\n    auto IEnv25 = (new ScriptEnvironment())->GetMainThreadEnv()->GetEnv25();\n    // return a disguised IScriptEnvironment_Avs25\n    return reinterpret_cast<IScriptEnvironment2*>(IEnv25);\n  }\n  else if (fromC && version < 11) {\n    // V11 supports 64 bit data types; no difference in IScriptEnvironment\n    auto IEnvPreV11C = (new ScriptEnvironment())->GetMainThreadEnv()->GetEnvPreV11C();\n    // return a disguised IScriptEnvironment_AvsC\n    return reinterpret_cast<IScriptEnvironment2*>(IEnvPreV11C);\n  }\n  else if (version <= AVISYNTH_INTERFACE_VERSION)\n    return (new ScriptEnvironment())->GetMainThreadEnv();\n  else\n    return NULL;\n}\n\nAVSC_API(IScriptEnvironment2*, CreateScriptEnvironment2)(int version)\n{\n  if (version <= AVISYNTH_CLASSIC_INTERFACE_VERSION_25)\n    return CreateScriptEnvironment2_internal(version, true, false); // avs 2.5, non-C\n  else if (version <= AVISYNTH_INTERFACE_VERSION)\n    return CreateScriptEnvironment2_internal(version, false, false); // modern avs, non-C\n\n  return nullptr;\n\n}\n\n///////////////\n\n"
  },
  {
    "path": "avs_core/core/avisynth.def",
    "content": "LIBRARY AviSynth.dll\nEXPORTS\n  DllGetClassObject PRIVATE\n  DllCanUnloadNow PRIVATE\n  CreateScriptEnvironment = _CreateScriptEnvironment@4\n  CreateScriptEnvironment2 = _CreateScriptEnvironment2@4\n  avs_add_function = _avs_add_function@20\n  avs_at_exit = _avs_at_exit@12\n  avs_bit_blt = _avs_bit_blt@28\n  avs_check_version = _avs_check_version@8\n  avs_clip_get_error = _avs_clip_get_error@4\n  avs_copy_clip = _avs_copy_clip@4\n  avs_copy_value = _avs_copy_value@12\n  avs_copy_video_frame = _avs_copy_video_frame@4\n  avs_create_script_environment = _avs_create_script_environment@4\n  avs_function_exists = _avs_function_exists@8\n  avs_get_audio = _avs_get_audio@24\n  avs_get_cpu_flags = _avs_get_cpu_flags@4\n  avs_get_frame = _avs_get_frame@8\n  avs_get_parity = _avs_get_parity@8\n  avs_get_var = _avs_get_var@8\n  avs_get_version = _avs_get_version@4\n  avs_get_video_info = _avs_get_video_info@4\n  avs_invoke = _avs_invoke@20\n  avs_make_writable = _avs_make_writable@8\n  avs_new_c_filter = _avs_new_c_filter@20\n  avs_new_video_frame_a = _avs_new_video_frame_a@12\n  avs_release_clip = _avs_release_clip@4\n  avs_release_value = _avs_release_value@8\n  avs_release_video_frame = _avs_release_video_frame@4\n  avs_save_string = _avs_save_string@12\n  avs_set_cache_hints = _avs_set_cache_hints@12\n  avs_set_global_var = _avs_set_global_var@16\n  avs_set_memory_max = _avs_set_memory_max@8\n  avs_set_to_clip = _avs_set_to_clip@8\n  avs_set_var = _avs_set_var@16\n  avs_set_working_dir = _avs_set_working_dir@8\n  avs_subframe = _avs_subframe@24\n  avs_take_clip = _avs_take_clip@12\n  avs_vsprintf = _avs_vsprintf@12\n  avs_sprintf\n  avs_delete_script_environment = _avs_delete_script_environment@4\n  avs_subframe_planar = _avs_subframe_planar@36\n  avs_get_error = _avs_get_error@4\n  avs_is_yv24 = _avs_is_yv24@4\n  avs_is_yv16 = _avs_is_yv16@4\n  avs_is_yv12 = _avs_is_yv12@4\n  avs_is_yv411 = _avs_is_yv411@4\n  avs_is_y8 = _avs_is_y8@4\n  avs_is_color_space = _avs_is_color_space@8\n  avs_get_plane_width_subsampling = _avs_get_plane_width_subsampling@8\n  avs_get_plane_height_subsampling = _avs_get_plane_height_subsampling@8\n  avs_bits_per_pixel = _avs_bits_per_pixel@4\n  avs_bytes_from_pixels = _avs_bytes_from_pixels@8\n  avs_row_size = _avs_row_size@8\n  avs_bmp_size = _avs_bmp_size@4\n  avs_get_pitch_p = _avs_get_pitch_p@8\n  avs_get_row_size_p = _avs_get_row_size_p@8\n  avs_get_height_p = _avs_get_height_p@8\n  avs_get_read_ptr_p = _avs_get_read_ptr_p@8\n  avs_is_writable = _avs_is_writable@4\n  avs_get_write_ptr_p = _avs_get_write_ptr_p@8\n  avs_is_yuv444p16 = _avs_is_yuv444p16@4\n  avs_is_yuv422p16 = _avs_is_yuv422p16@4\n  avs_is_yuv420p16 = _avs_is_yuv420p16@4\n  avs_is_y16 = _avs_is_y16@4\n  avs_is_yuv444ps = _avs_is_yuv444ps@4\n  avs_is_yuv422ps = _avs_is_yuv422ps@4\n  avs_is_yuv420ps = _avs_is_yuv420ps@4\n  avs_is_y32 = _avs_is_y32@4\n  avs_num_components = _avs_num_components@4\n  avs_component_size = _avs_component_size@4\n  avs_bits_per_component = _avs_bits_per_component@4\n  avs_is_444 = _avs_is_444@4\n  avs_is_422 = _avs_is_422@4\n  avs_is_420 = _avs_is_420@4\n  avs_is_y = _avs_is_y@4\n  avs_is_yuva = _avs_is_yuva@4\n  avs_is_planar_rgb = _avs_is_planar_rgb@4\n  avs_is_planar_rgba = _avs_is_planar_rgba@4\n  avs_is_rgb48 = _avs_is_rgb48@4\n  avs_is_rgb64 = _avs_is_rgb64@4\n  avs_subframe_planar_a = _avs_subframe_planar_a@40\n  avs_copy_frame_props = _avs_copy_frame_props@12\n  avs_get_frame_props_ro = _avs_get_frame_props_ro@8\n  avs_get_frame_props_rw = _avs_get_frame_props_rw@8\n  avs_prop_num_keys = _avs_prop_num_keys@8\n  avs_prop_get_key = _avs_prop_get_key@12\n  avs_prop_num_elements = _avs_prop_num_elements@12\n  avs_prop_get_type = _avs_prop_get_type@12\n  avs_prop_get_int = _avs_prop_get_int@20\n  avs_prop_get_float = _avs_prop_get_float@20\n  avs_prop_get_data = _avs_prop_get_data@20\n  avs_prop_get_data_size = _avs_prop_get_data_size@20\n  avs_prop_get_clip = _avs_prop_get_clip@20\n  avs_prop_get_frame = _avs_prop_get_frame@20\n  avs_prop_delete_key = _avs_prop_delete_key@12\n  avs_prop_set_int = _avs_prop_set_int@24\n  avs_prop_set_float = _avs_prop_set_float@24\n  avs_prop_set_data = _avs_prop_set_data@24\n  avs_prop_set_clip = _avs_prop_set_clip@20\n  avs_prop_set_frame = _avs_prop_set_frame@20\n  avs_prop_get_int_array = _avs_prop_get_int_array@16\n  avs_prop_get_float_array = _avs_prop_get_float_array@16\n  avs_prop_set_int_array = _avs_prop_set_int_array@20\n  avs_prop_set_float_array = _avs_prop_set_float_array@20\n  avs_clear_map = _avs_clear_map@8\n  avs_new_video_frame_p = _avs_new_video_frame_p@12\n  avs_new_video_frame_p_a = _avs_new_video_frame_p_a@16\n  avs_get_env_property = _avs_get_env_property@8\n  avs_pool_allocate = _avs_pool_allocate@16\n  avs_pool_free = _avs_pool_free@8\n  avs_get_var_try = _avs_get_var_try@12\n  avs_get_var_bool = _avs_get_var_bool@12\n  avs_get_var_int = _avs_get_var_int@12\n  avs_get_var_double = _avs_get_var_double@16\n  avs_get_var_string = _avs_get_var_string@12\n  avs_get_var_long = _avs_get_var_long@16\n  avs_is_property_writable = _avs_is_property_writable@4\n  avs_make_property_writable = _avs_make_property_writable@8\n\n  avs_video_frame_get_pixel_type = _avs_video_frame_get_pixel_type@4\n  avs_video_frame_amend_pixel_type = _avs_video_frame_amend_pixel_type@8\n\n  avs_is_channel_mask_known = _avs_is_channel_mask_known@4\n  avs_set_channel_mask = _avs_set_channel_mask@12\n  avs_get_channel_mask = _avs_get_channel_mask@4\n\n  avs_set_to_error = _avs_set_to_error@8\n  avs_set_to_bool = _avs_set_to_bool@8\n  avs_set_to_int = _avs_set_to_int@8\n  avs_set_to_string = _avs_set_to_string@8\n  avs_set_to_float = _avs_set_to_float@8\n  avs_set_to_double = _avs_set_to_double@12\n  avs_set_to_long = _avs_set_to_long@12\n  avs_set_to_array = _avs_set_to_array@12\n  avs_set_to_void = _avs_set_to_void@4\n\n  avs_get_as_bool = _avs_get_as_bool@8\n  avs_get_as_clip = _avs_get_as_clip@12\n  avs_get_as_int = _avs_get_as_int@8\n  avs_get_as_long = _avs_get_as_long@8\n  avs_get_as_string = _avs_get_as_string@8\n  avs_get_as_float = _avs_get_as_float@8\n  avs_get_as_error = _avs_get_as_error@8\n  avs_get_as_array = _avs_get_as_array@8\n  avs_get_array_elt = _avs_get_array_elt@12\n  avs_get_array_size = _avs_get_array_size@8\n\n  avs_prop_get_int_saturated = _avs_prop_get_int_saturated@20\n  avs_prop_get_float_saturated = _avs_prop_get_float_saturated@20\n  avs_prop_get_data_type_hint = _avs_prop_get_data_type_hint@20\n  avs_prop_set_data_h = _avs_prop_set_data_h@28\n\n  avs_add_function_r = _avs_add_function_r@20\n\n  avs_val_defined = _avs_val_defined@8\n  avs_val_is_clip = _avs_val_is_clip@8\n  avs_val_is_bool = _avs_val_is_bool@8\n  avs_val_is_int = _avs_val_is_int@8\n  avs_val_is_long_strict = _avs_val_is_long_strict@8\n  avs_val_is_float = _avs_val_is_float@8\n  avs_val_is_floatf_strict = _avs_val_is_floatf_strict@8\n  avs_val_is_string = _avs_val_is_string@8\n  avs_val_is_array = _avs_val_is_array@8\n  avs_val_is_error = _avs_val_is_error@8\n\n  avs_acquire_global_lock = _avs_acquire_global_lock@8\n  avs_release_global_lock = _avs_release_global_lock@8\n\n  avs_get_cpu_flags_ex = _avs_get_cpu_flags_ex@4\n"
  },
  {
    "path": "avs_core/core/avisynth.rc",
    "content": "#include <windows.h>\n#include \"version.h\"\n\n#define VER_FILEVERSION             AVS_MAJOR_VER,AVS_MINOR_VER,AVS_BUGFIX_VER\n#define VER_PRODUCTVERSION          AVS_MAJOR_VER,AVS_MINOR_VER,AVS_BUGFIX_VER\n#define VER_COMPANYNAME_STR         \"The Public\\0\"\n#define VER_FILEDESCRIPTION_STR     \"AviSynth video processing scripting language\\0\"\n#define VER_FILEVERSION_STR         AVS_PPSTR(AVS_MAJOR_VER) \", \" AVS_PPSTR(AVS_MINOR_VER) \", \" AVS_PPSTR(AVS_BUGFIX_VER) \"\\0\"\n#define VER_INTERNALNAME_STR        AVS_FULLVERSION \"\\0\"\n#define VER_LEGALCOPYRIGHT_STR      \" 2000-2026 Ben Rudiak-Gould and others\\0\"\n#define VER_ORIGINALFILENAME_STR    \"avisynth.dll\\0\"\n#define VER_PRODUCTNAME_STR         AVS_FULLVERSION \"\\0\"\n#define VER_PRODUCTVERSION_STR      VER_FILEVERSION_STR\n#define VER_COMMENTS_STR            \"Homepage: http://avisynth.nl\\0\"\n\n#ifndef _DEBUG\n#define VER_DEBUG                   0\n#else\n#define VER_DEBUG                   VS_FF_DEBUG\n#endif\n\n#define AVS_ICON                    0\n#define AVSI_ICON                   1\n\n\nVS_VERSION_INFO VERSIONINFO\nFILEVERSION    \tVER_FILEVERSION\nPRODUCTVERSION \tVER_PRODUCTVERSION\nFILEFLAGSMASK  \tVS_FFI_FILEFLAGSMASK\nFILEFLAGS      \t(VS_FF_PRERELEASE|VER_DEBUG)\nFILEOS         \tVOS__WINDOWS32\nFILETYPE       \tVFT_DLL\nFILESUBTYPE    \tVFT2_UNKNOWN\nBEGIN\n    BLOCK \"StringFileInfo\"\n    BEGIN\n        BLOCK \"040904E4\"\n        BEGIN\n            VALUE \"CompanyName\",      VER_COMPANYNAME_STR\n            VALUE \"FileDescription\",  VER_FILEDESCRIPTION_STR\n            VALUE \"FileVersion\",      VER_FILEVERSION_STR\n            VALUE \"InternalName\",     VER_INTERNALNAME_STR\n            VALUE \"LegalCopyright\",   VER_LEGALCOPYRIGHT_STR\n//            VALUE \"LegalTrademarks1\", VER_LEGALTRADEMARKS1_STR\n//            VALUE \"LegalTrademarks2\", VER_LEGALTRADEMARKS2_STR\n            VALUE \"OriginalFilename\", VER_ORIGINALFILENAME_STR\n            VALUE \"ProductName\",      VER_PRODUCTNAME_STR\n            VALUE \"ProductVersion\",   VER_PRODUCTVERSION_STR\n            VALUE \"Comments\",         VER_COMMENTS_STR\n        END\n    END\n\n    BLOCK \"VarFileInfo\"\n    BEGIN\n        /* The following line should only be modified for localized versions.     */\n        /* It consists of any number of WORD,WORD pairs, with each pair           */\n        /* describing a language,codepage combination supported by the file.      */\n        /*                                                                        */\n        /* For example, a file might have values \"0x409,1252\" indicating that it  */\n        /* supports English language (0x409) in the Windows ANSI codepage (1252). */\n\n        VALUE \"Translation\", 0x409, 1252\n\n    END\nEND\n\n\nLANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT\nAVS_ICON   ICON  \"../../distrib/Icons/Ico/AvsDocWindows.ico\"\nAVSI_ICON  ICON  \"../../distrib/Icons/Ico/AvsiDocWindows.ico\"\n"
  },
  {
    "path": "avs_core/core/avisynth64.def",
    "content": "LIBRARY AviSynth.dll\nEXPORTS\n  DllGetClassObject PRIVATE\n  DllCanUnloadNow PRIVATE\n"
  },
  {
    "path": "avs_core/core/avisynth_c.cpp",
    "content": "// Avisynth C Interface\n// Based on Copyright 2003 Kevin Atkinson\n//\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n\n#include <avisynth.h>\n#include <avisynth_c.h>\n#include \"AVSMap.h\"\n#include \"internal.h\"\n\n#ifdef AVS_WINDOWS\n#include <avs/win.h>\n#else\n#include <avs/posix.h>\n#endif\n\n#include <algorithm>\n#include <cstdarg>\n\n\nstruct AVS_Clip\n{\n  PClip clip;\n  IScriptEnvironment* env;\n  const char* error;\n  AVS_Clip() : env(0), error(0) {}\n};\n\nclass C_VideoFilter : public IClip {\npublic: // but don't use\n  AVS_Clip child;\n  AVS_ScriptEnvironment env;\n  AVS_FilterInfo d;\npublic:\n  C_VideoFilter() { memset(&d, 0, sizeof(d)); }\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env);\n  const VideoInfo& __stdcall GetVideoInfo();\n  bool __stdcall GetParity(int n);\n  int __stdcall SetCacheHints(int cachehints, int frame_range);\n  AVSC_CC ~C_VideoFilter();\n};\n\n/////////////////////////////////////////////////////////////////////\n//\n//\n//\n\nextern \"C\"\nint AVSC_CC avs_is_rgb48(const AVS_VideoInfo * p)\n{\n  return ((p->pixel_type & AVS_CS_BGR24) == AVS_CS_BGR24) && ((p->pixel_type & AVS_CS_SAMPLE_BITS_MASK) == AVS_CS_SAMPLE_BITS_16);\n}\n\nextern \"C\"\nint AVSC_CC avs_is_rgb64(const AVS_VideoInfo * p)\n{\n  return ((p->pixel_type & AVS_CS_BGR32) == AVS_CS_BGR32) && ((p->pixel_type & AVS_CS_SAMPLE_BITS_MASK) == AVS_CS_SAMPLE_BITS_16);\n}\n\nextern \"C\"\nint AVSC_CC avs_is_yv24(const AVS_VideoInfo * p)\n{\n  return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_YV24 & AVS_CS_PLANAR_FILTER);\n}\n\nextern \"C\"\nint AVSC_CC avs_is_yv16(const AVS_VideoInfo * p)\n{\n  return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_YV16 & AVS_CS_PLANAR_FILTER);\n}\n\nextern \"C\"\nint AVSC_CC avs_is_yv12(const AVS_VideoInfo * p)\n{\n  return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_YV12 & AVS_CS_PLANAR_FILTER);\n}\n\nextern \"C\"\nint AVSC_CC avs_is_yv411(const AVS_VideoInfo * p)\n{\n  return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_YV411 & AVS_CS_PLANAR_FILTER);\n}\n\nextern \"C\"\nint AVSC_CC avs_is_y8(const AVS_VideoInfo * p)\n{\n  return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_Y8 & AVS_CS_PLANAR_FILTER);\n}\n\nextern \"C\"\nint AVSC_CC avs_is_yuv444p16(const AVS_VideoInfo * p)\n{\n  return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_YUV444P16 & AVS_CS_PLANAR_FILTER);\n}\n\nextern \"C\"\nint AVSC_CC avs_is_yuv422p16(const AVS_VideoInfo * p)\n{\n  return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_YUV422P16 & AVS_CS_PLANAR_FILTER);\n}\n\nextern \"C\"\nint AVSC_CC avs_is_yuv420p16(const AVS_VideoInfo * p)\n{\n  return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_YUV420P16 & AVS_CS_PLANAR_FILTER);\n}\n\nextern \"C\"\nint AVSC_CC avs_is_y16(const AVS_VideoInfo * p)\n{\n  return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_Y16 & AVS_CS_PLANAR_FILTER);\n}\n\nextern \"C\"\nint AVSC_CC avs_is_yuv444ps(const AVS_VideoInfo * p)\n{\n  return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_YUV444PS & AVS_CS_PLANAR_FILTER);\n}\n\nextern \"C\"\nint AVSC_CC avs_is_yuv422ps(const AVS_VideoInfo * p)\n{\n  return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_YUV422PS & AVS_CS_PLANAR_FILTER);\n}\n\nextern \"C\"\nint AVSC_CC avs_is_yuv420ps(const AVS_VideoInfo * p)\n{\n  return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_YUV420PS & AVS_CS_PLANAR_FILTER);\n}\n\nextern \"C\"\nint AVSC_CC avs_is_y32(const AVS_VideoInfo * p)\n{\n  return (p->pixel_type & AVS_CS_PLANAR_MASK) == (AVS_CS_Y32 & AVS_CS_PLANAR_FILTER);\n}\n\nextern \"C\"\nint AVSC_CC avs_is_444(const AVS_VideoInfo * p)\n{\n  return ((p->pixel_type & AVS_CS_PLANAR_MASK & ~AVS_CS_SAMPLE_BITS_MASK) == (AVS_CS_GENERIC_YUV444 & AVS_CS_PLANAR_FILTER)) ||\n    ((p->pixel_type & AVS_CS_PLANAR_MASK & ~AVS_CS_SAMPLE_BITS_MASK) == (AVS_CS_GENERIC_YUVA444 & AVS_CS_PLANAR_FILTER));\n}\n\nextern \"C\"\nint AVSC_CC avs_is_422(const AVS_VideoInfo * p)\n{\n  return ((p->pixel_type & AVS_CS_PLANAR_MASK & ~AVS_CS_SAMPLE_BITS_MASK) == (AVS_CS_GENERIC_YUV422 & AVS_CS_PLANAR_FILTER)) ||\n    ((p->pixel_type & AVS_CS_PLANAR_MASK & ~AVS_CS_SAMPLE_BITS_MASK) == (AVS_CS_GENERIC_YUVA422 & AVS_CS_PLANAR_FILTER));\n}\n\nextern \"C\"\nint AVSC_CC avs_is_420(const AVS_VideoInfo * p)\n{\n  return ((p->pixel_type & AVS_CS_PLANAR_MASK & ~AVS_CS_SAMPLE_BITS_MASK) == (AVS_CS_GENERIC_YUV420 & AVS_CS_PLANAR_FILTER)) ||\n    ((p->pixel_type & AVS_CS_PLANAR_MASK & ~AVS_CS_SAMPLE_BITS_MASK) == (AVS_CS_GENERIC_YUVA420 & AVS_CS_PLANAR_FILTER));\n}\n\nextern \"C\"\nint AVSC_CC avs_is_y(const AVS_VideoInfo * p)\n{\n  return (p->pixel_type & AVS_CS_PLANAR_MASK & ~AVS_CS_SAMPLE_BITS_MASK) == (AVS_CS_GENERIC_Y & AVS_CS_PLANAR_FILTER);\n}\n\nextern \"C\"\nint AVSC_CC avs_is_color_space(const AVS_VideoInfo * p, int c_space)\n{\n  return avs_is_planar(p) ?\n    ((p->pixel_type & AVS_CS_PLANAR_MASK) == (c_space & AVS_CS_PLANAR_FILTER))\n    :\n    (((p->pixel_type & ~AVS_CS_SAMPLE_BITS_MASK & c_space) == (c_space & ~AVS_CS_SAMPLE_BITS_MASK)) && // RGB got sample bits\n      ((p->pixel_type & AVS_CS_SAMPLE_BITS_MASK) == (c_space & AVS_CS_SAMPLE_BITS_MASK)));\n}\n\nextern \"C\"\nint AVSC_CC avs_is_yuva(const AVS_VideoInfo * p)\n{\n  return !!(p->pixel_type & AVS_CS_YUVA);\n}\n\nextern \"C\"\nint AVSC_CC avs_is_planar_rgb(const AVS_VideoInfo * p)\n{\n  return !!(p->pixel_type & AVS_CS_PLANAR) && !!(p->pixel_type & AVS_CS_BGR) && !!(p->pixel_type & AVS_CS_RGB_TYPE);\n}\n\nextern \"C\"\nint AVSC_CC avs_is_planar_rgba(const AVS_VideoInfo * p)\n{\n  return !!(p->pixel_type & AVS_CS_PLANAR) && !!(p->pixel_type & AVS_CS_BGR) && !!(p->pixel_type & AVS_CS_RGBA_TYPE);\n}\n\nextern \"C\"\nint AVSC_CC avs_get_plane_width_subsampling(const AVS_VideoInfo * p, int plane)\n{\n  try {\n    return ((VideoInfo*)p)->GetPlaneWidthSubsampling(plane);\n  }\n  catch (const AvisynthError& err) {\n    (void)err;  // silence warning about unused variable; variable is kept for debugging\n    return -1;\n  }\n}\n\nextern \"C\"\nint AVSC_CC avs_get_plane_height_subsampling(const AVS_VideoInfo * p, int plane)\n{\n  try {\n    return ((VideoInfo*)p)->GetPlaneHeightSubsampling(plane);\n  }\n  catch (const AvisynthError& err) {\n    (void)err;  // silence warning about unused variable; variable is kept for debugging\n    return -1;\n  }\n}\n\nextern \"C\"\nint AVSC_CC avs_bits_per_pixel(const AVS_VideoInfo * p)\n{\n  return ((VideoInfo*)p)->BitsPerPixel();\n}\n\nextern \"C\"\nint AVSC_CC avs_bytes_from_pixels(const AVS_VideoInfo * p, int pixels)\n{\n  return ((VideoInfo*)p)->BytesFromPixels(pixels);\n}\n\n// This method should be called avs_row_size_p,\n// but we won't change it anymore to avoid breaking\n// the interface.\nextern \"C\"\nint AVSC_CC avs_row_size(const AVS_VideoInfo * p, int plane)\n{\n  return ((VideoInfo*)p)->RowSize(plane);\n}\n\nextern \"C\"\nint AVSC_CC avs_bmp_size(const AVS_VideoInfo * vi)\n{\n  return ((VideoInfo*)vi)->BMPSize();\n}\n\n\n/////////////////////////////////////////////////////////////////////\n//\n//\n//\n\nextern \"C\"\nint AVSC_CC avs_get_pitch_p(const AVS_VideoFrame * p, int plane)\n{\n  // Memo: the lines in class PVideoFrame:\n  //   VideoFrame* p;\n  //   VideoFrame* operator->() const { return p; }\n  // help when you use the arrow operator on a PVideoFrame object, it will return \n  // the \"VideoFrame* p\" pointer, allowing you to access members of the \n  // VideoFrame class directly.\n  return (*(const PVideoFrame*)&p)->GetPitch(plane);\n}\n\nextern \"C\"\nint AVSC_CC avs_get_row_size_p(const AVS_VideoFrame * p, int plane)\n{\n  return (*(const PVideoFrame*)&p)->GetRowSize(plane);\n}\n\nextern \"C\"\nint AVSC_CC avs_get_height_p(const AVS_VideoFrame * p, int plane)\n{\n  return (*(const PVideoFrame*)&p)->GetHeight(plane);\n}\n\nextern \"C\"\nconst BYTE * AVSC_CC avs_get_read_ptr_p(const AVS_VideoFrame * p, int plane)\n{\n  return (*(const PVideoFrame*)&p)->GetReadPtr(plane);\n}\n\nextern \"C\"\nint AVSC_CC avs_is_writable(const AVS_VideoFrame * p)\n{\n  return (*(const PVideoFrame*)&p)->IsWritable() ? 1 : 0;\n}\n\n// V9\nextern \"C\"\nint AVSC_CC avs_is_property_writable(const AVS_VideoFrame * p)\n{\n  return (*(const PVideoFrame*)&p)->IsPropertyWritable() ? 1 : 0;\n}\n\n// V10\nextern \"C\"\nint AVSC_CC avs_video_frame_get_pixel_type(const AVS_VideoFrame * p)\n{\n  return (*(const PVideoFrame*)&p)->GetPixelType();\n}\n\n// V10\nvoid AVSC_CC avs_video_frame_amend_pixel_type(AVS_VideoFrame* p, int new_pixel_type)\n{\n  (*(PVideoFrame*)&p)->AmendPixelType(new_pixel_type);\n}\n\nextern \"C\"\nBYTE * AVSC_CC avs_get_write_ptr_p(const AVS_VideoFrame * p, int plane)\n{\n  return (*(const PVideoFrame*)&p)->GetWritePtr(plane);\n}\n\nextern \"C\"\nvoid AVSC_CC avs_release_video_frame(AVS_VideoFrame * f)\n{\n  ((PVideoFrame*)&f)->~PVideoFrame();\n}\n\nextern \"C\"\nAVS_VideoFrame * AVSC_CC avs_copy_video_frame(AVS_VideoFrame * f)\n{\n  AVS_VideoFrame* fnew;\n  new ((PVideoFrame*)&fnew) PVideoFrame(*(PVideoFrame*)&f);\n  return fnew;\n}\n\n\nextern \"C\"\nint AVSC_CC avs_num_components(const AVS_VideoInfo * p)\n{\n  return ((VideoInfo*)p)->NumComponents();\n}\n\nextern \"C\"\nint AVSC_CC avs_component_size(const AVS_VideoInfo * p)\n{\n  return ((VideoInfo*)p)->ComponentSize();\n}\n\nextern \"C\"\nint AVSC_CC avs_bits_per_component(const AVS_VideoInfo * p)\n{\n  return ((VideoInfo*)p)->BitsPerComponent();\n}\n\n// V10.1\nextern \"C\"\nbool AVSC_CC avs_is_channel_mask_known(const AVS_VideoInfo * p)\n{\n  return ((VideoInfo*)p)->IsChannelMaskKnown();\n}\n\nextern \"C\"\nvoid AVSC_CC avs_set_channel_mask(const AVS_VideoInfo * p, bool isChannelMaskKnown, unsigned int dwChannelMask)\n{\n  ((VideoInfo*)p)->SetChannelMask(isChannelMaskKnown, dwChannelMask);\n}\n\nextern \"C\"\nunsigned int AVSC_CC avs_get_channel_mask(const AVS_VideoInfo * p)\n{\n  return ((VideoInfo*)p)->GetChannelMask();\n}\n\n//////////////////////////////////////////////////////////\n//\n// frame properties\n//\nextern \"C\"\nvoid AVSC_CC avs_copy_frame_props(AVS_ScriptEnvironment * p, const AVS_VideoFrame * src, AVS_VideoFrame * dst)\n{\n  p->error = 0;\n  try {\n    p->env->copyFrameProps(*(const PVideoFrame*)&src, *(PVideoFrame*)&dst);\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n  }\n}\n\nextern \"C\"\nconst AVS_Map * AVSC_CC avs_get_frame_props_ro(AVS_ScriptEnvironment * p, const AVS_VideoFrame * frame)\n{\n  p->error = 0;\n  try {\n    return (const AVS_Map*)(p->env->getFramePropsRO(*(const PVideoFrame*)&frame));\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nAVS_Map * AVSC_CC avs_get_frame_props_rw(AVS_ScriptEnvironment * p, AVS_VideoFrame * frame)\n{\n  p->error = 0;\n  try {\n    return (AVS_Map*)(p->env->getFramePropsRW(*(PVideoFrame*)&frame));\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nint AVSC_CC avs_prop_num_keys(AVS_ScriptEnvironment * p, const AVS_Map * map)\n{\n  p->error = 0;\n  try {\n    return (p->env->propNumKeys((const AVSMap*)map));\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nconst char* AVSC_CC avs_prop_get_key(AVS_ScriptEnvironment * p, const AVS_Map * map, int index)\n{\n  p->error = 0;\n  try {\n    const char* key = (p->env->propGetKey((const AVSMap*)map, index));\n    return p->env->SaveString(key);\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nint AVSC_CC avs_prop_num_elements(AVS_ScriptEnvironment * p, const AVS_Map * map, const char* key)\n{\n  p->error = 0;\n  try {\n    return (p->env->propNumElements((const AVSMap*)map, key));\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nchar AVSC_CC avs_prop_get_type(AVS_ScriptEnvironment * p, const AVS_Map * map, const char* key)\n{\n  p->error = 0;\n  try {\n    return (p->env->propGetType((const AVSMap*)map, key));\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nint AVSC_CC avs_prop_delete_key(AVS_ScriptEnvironment * p, AVS_Map * map, const char* key)\n{\n  p->error = 0;\n  try {\n    return (p->env->propDeleteKey((AVSMap*)map, key));\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nint64_t AVSC_CC avs_prop_get_int(AVS_ScriptEnvironment * p, const AVS_Map * map, const char* key, int index, int* error)\n{\n  p->error = 0;\n  try {\n    return (p->env->propGetInt((const AVSMap*)map, key, index, error));\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nint AVSC_CC avs_prop_get_int_saturated(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error)\n{\n  p->error = 0;\n  try {\n    return (p->env->propGetIntSaturated((const AVSMap*)map, key, index, error));\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\ndouble AVSC_CC avs_prop_get_float(AVS_ScriptEnvironment * p, const AVS_Map * map, const char* key, int index, int* error)\n{\n  p->error = 0;\n  try {\n    return (p->env->propGetFloat((const AVSMap*)map, key, index, error));\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\n// v11\nextern \"C\"\nfloat AVSC_CC avs_prop_get_float_saturated(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error)\n{\n  p->error = 0;\n  try {\n    return (p->env->propGetFloatSaturated((const AVSMap*)map, key, index, error));\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nconst char* AVSC_CC avs_prop_get_data(AVS_ScriptEnvironment * p, const AVS_Map * map, const char* key, int index, int* error)\n{\n  p->error = 0;\n  try {\n    const char* data = p->env->propGetData((const AVSMap*)map, key, index, error);\n    if (!data)\n      return nullptr;\n    else\n      return data;\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nint AVSC_CC avs_prop_get_data_size(AVS_ScriptEnvironment * p, const AVS_Map * map, const char* key, int index, int* error)\n{\n  p->error = 0;\n  try {\n    return (p->env->propGetDataSize((const AVSMap*)map, key, index, error));\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nint AVSC_CC avs_prop_get_data_type_hint(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error)\n{\n  p->error = 0;\n  try {\n    return (p->env->propGetDataTypeHint((const AVSMap*)map, key, index, error));\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nAVS_Clip* AVSC_CC avs_prop_get_clip(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error)\n{\n  p->error = 0;\n  try {\n    PClip c0 = p->env->propGetClip((const AVSMap*)map, key, index, error);\n    AVS_Clip* c;\n    new((PClip*)&c) PClip(c0);\n    return c;\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nconst AVS_VideoFrame * AVSC_CC avs_prop_get_frame(AVS_ScriptEnvironment * p, const AVS_Map * map, const char* key, int index, int* error)\n{\n  p->error = 0;\n  try {\n    const PVideoFrame f0 = p->env->propGetFrame((const AVSMap*)map, key, index, error);\n    AVS_VideoFrame* f;\n    new((PVideoFrame*)&f) PVideoFrame(f0);\n    return f;\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nint AVSC_CC avs_prop_set_int(AVS_ScriptEnvironment * p, AVS_Map * map, const char* key, int64_t i, int append)\n{\n  p->error = 0;\n  try {\n    return (p->env->propSetInt((AVSMap*)map, key, i, append));\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nint AVSC_CC avs_prop_set_float(AVS_ScriptEnvironment * p, AVS_Map * map, const char* key, double d, int append)\n{\n  p->error = 0;\n  try {\n    return (p->env->propSetFloat((AVSMap*)map, key, d, append));\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nint AVSC_CC avs_prop_set_data(AVS_ScriptEnvironment * p, AVS_Map * map, const char* key, const char* d, int length, int append)\n{\n  // length = -1 -> auto strlen\n  p->error = 0;\n  try {\n    return (p->env->propSetData((AVSMap*)map, key, d, length, append));\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nint AVSC_CC avs_prop_set_data_h(AVS_ScriptEnvironment* p, AVS_Map* map, const char* key, const char* d, int length, int type, int append)\n{\n  // length = -1 -> auto strlen\n  p->error = 0;\n  try {\n    return (p->env->propSetDataH((AVSMap*)map, key, d, length, type, append));\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nint AVSC_CC avs_prop_set_clip(AVS_ScriptEnvironment * p, AVS_Map * map, const char* key, AVS_Clip * clip, int append)\n{\n   p->error = 0;\n  try {\n    return (p->env->propSetClip((AVSMap*)map, key, *(PClip*)clip, append));\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nint AVSC_CC avs_prop_set_frame(AVS_ScriptEnvironment * p, AVS_Map * map, const char* key, const AVS_VideoFrame * frame, int append)\n{\n  p->error = 0;\n  try {\n    return (p->env->propSetFrame((AVSMap*)map, key, *(PVideoFrame*)&frame, append));\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\n\nextern \"C\"\nconst int64_t * AVSC_CC avs_prop_get_int_array(AVS_ScriptEnvironment * p, const AVS_Map * map, const char* key, int* error)\n{\n  p->error = 0;\n  try {\n    return p->env->propGetIntArray((const AVSMap*)map, key, error);\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nconst double* AVSC_CC avs_prop_get_float_array(AVS_ScriptEnvironment * p, const AVS_Map * map, const char* key, int* error)\n{\n  p->error = 0;\n  try {\n    return p->env->propGetFloatArray((const AVSMap*)map, key, error);\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nint AVSC_CC avs_prop_set_int_array(AVS_ScriptEnvironment * p, AVS_Map * map, const char* key, const int64_t * i, int size)\n{\n  p->error = 0;\n  try {\n    return (p->env->propSetIntArray((AVSMap*)map, key, i, size));\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nint AVSC_CC avs_prop_set_float_array(AVS_ScriptEnvironment * p, AVS_Map * map, const char* key, const double* d, int size)\n{\n  p->error = 0;\n  try {\n    return (p->env->propSetFloatArray((AVSMap*)map, key, d, size));\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nvoid AVSC_CC avs_clear_map(AVS_ScriptEnvironment * p, AVS_Map * map)\n{\n  p->error = 0;\n  try {\n    p->env->clearMap((AVSMap*)map);\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n  }\n}\n\n\n\n/////////////////////////////////////////////////////////////////////\n//\n// C_VideoFilter\n//\n\nPVideoFrame C_VideoFilter::GetFrame(int n, IScriptEnvironment* env)\n{\n  if (d.get_frame) {\n    d.error = 0;\n    AVS_VideoFrame* f = d.get_frame(&d, n);\n    if (d.error)\n      throw AvisynthError(d.error);\n    if (d.child != NULL && d.child->error)\n      throw AvisynthError(d.child->error);\n    PVideoFrame fr((VideoFrame*)f);\n    ((PVideoFrame*)&f)->~PVideoFrame();\n    return fr;\n  }\n  else {\n    return d.child->clip->GetFrame(n, env);\n  }\n}\n\nvoid __stdcall C_VideoFilter::GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env)\n{\n  if (d.get_audio) {\n    d.error = 0;\n    d.get_audio(&d, buf, start, count);\n    if (d.error)\n      throw AvisynthError(d.error);\n  }\n  else {\n    d.child->clip->GetAudio(buf, start, count, env);\n  }\n}\n\nconst VideoInfo& __stdcall C_VideoFilter::GetVideoInfo()\n{\n  return *(VideoInfo*)&d.vi;\n}\n\nbool __stdcall C_VideoFilter::GetParity(int n)\n{\n  if (d.get_parity) {\n    d.error = 0;\n    int res = d.get_parity(&d, n);\n    if (d.error)\n      throw AvisynthError(d.error);\n    return !!res;\n  }\n  else {\n    return d.child->clip->GetParity(n);\n  }\n}\n\nint __stdcall C_VideoFilter::SetCacheHints(int cachehints, int frame_range)\n{\n  if (d.set_cache_hints) {\n    d.error = 0;\n    int res = d.set_cache_hints(&d, cachehints, frame_range);\n    if (d.error)\n      throw AvisynthError(d.error);\n    return res;\n  }\n  // We do not pass cache requests upwards, only to the hosted filter.\n  return 0;\n}\n\nC_VideoFilter::~C_VideoFilter()\n{\n  if (d.free_filter)\n    d.free_filter(&d);\n}\n\n/////////////////////////////////////////////////////////////////////\n//\n// AVS_Clip\n//\n\nextern \"C\"\nvoid AVSC_CC avs_release_clip(AVS_Clip * p)\n{\n  delete p;\n}\n\nAVS_Clip* AVSC_CC avs_copy_clip(AVS_Clip* p)\n{\n  return new AVS_Clip(*p);\n}\n\nextern \"C\"\nconst char* AVSC_CC avs_clip_get_error(AVS_Clip * p) // return 0 if no error\n{\n  return p->error;\n}\n\nextern \"C\"\nint AVSC_CC avs_get_version(AVS_Clip * p)\n{\n  return p->clip->GetVersion();\n}\n\nextern \"C\"\nconst AVS_VideoInfo * AVSC_CC avs_get_video_info(AVS_Clip * p)\n{\n  return  (const AVS_VideoInfo*)&p->clip->GetVideoInfo();\n}\n\n\nextern \"C\"\nAVS_VideoFrame * AVSC_CC avs_get_frame(AVS_Clip * p, int n)\n{\n  p->error = 0;\n  try {\n    PVideoFrame f0 = p->clip->GetFrame(n, p->env);\n    AVS_VideoFrame* f;\n    new((PVideoFrame*)&f) PVideoFrame(f0);\n    return f;\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nint AVSC_CC avs_get_parity(AVS_Clip * p, int n) // return field parity if field_based, else parity of first field in frame\n{\n  try {\n    p->error = 0;\n    return p->clip->GetParity(n);\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return -1;\n  }\n}\n\nextern \"C\"\nint AVSC_CC avs_get_audio(AVS_Clip * p, void* buf, int64_t start, int64_t count) // start and count are in samples\n{\n  try {\n    p->error = 0;\n    p->clip->GetAudio(buf, start, count, p->env);\n    return 0;\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return -1;\n  }\n}\n\nextern \"C\"\nint AVSC_CC avs_set_cache_hints(AVS_Clip * p, int cachehints, int frame_range)  // We do not pass cache requests upwards, only to the next filter.\n{\n  try {\n    p->error = 0;\n    return p->clip->SetCacheHints(cachehints, frame_range);\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return -1;\n  }\n}\n\n//////////////////////////////////////////////////////////////////\n//\n//\n//\nextern \"C\"\nAVS_Clip * AVSC_CC avs_take_clip(AVS_Value v, AVS_ScriptEnvironment * env)\n{\n  AVS_Clip* c = new AVS_Clip;\n  c->env = env->env;\n  c->clip = (IClip*)v.d.clip;\n  return c;\n}\n\n// v11 API AVS_Value type checkers.\nextern \"C\"\nint AVSC_CC avs_val_defined(AVS_Value v) { return ((const AVSValue*)(&v))->Defined() ? 1 : 0; }\nextern \"C\"\nint AVSC_CC avs_val_is_clip(AVS_Value v) { return ((const AVSValue*)(&v))->IsClip() ? 1 : 0; }\nextern \"C\"\nint AVSC_CC avs_val_is_bool(AVS_Value v) { return ((const AVSValue*)(&v))->IsBool() ? 1 : 0; }\nextern \"C\"\nint AVSC_CC avs_val_is_int(AVS_Value v) { return ((const AVSValue*)(&v))->IsInt() ? 1 : 0; }\nextern \"C\"\nint AVSC_CC avs_val_is_long_strict(AVS_Value v) { return ((const AVSValue*)(&v))->IsLongStrict() ? 1 : 0; }\nextern \"C\"\nint AVSC_CC avs_val_is_float(AVS_Value v) { return ((const AVSValue*)(&v))->IsFloat() ? 1 : 0; }\nextern \"C\"\nint AVSC_CC avs_val_is_floatf_strict(AVS_Value v) { return ((const AVSValue*)(&v))->IsFloatfStrict() ? 1 : 0; }\nextern \"C\"\nint AVSC_CC avs_val_is_string(AVS_Value v) { return ((const AVSValue*)(&v))->IsString() ? 1 : 0; }\nextern \"C\"\nint AVSC_CC avs_val_is_array(AVS_Value v) { return ((const AVSValue*)(&v))->IsArray() ? 1 : 0; }\nextern \"C\"\nint AVSC_CC avs_val_is_error(AVS_Value v) { return v.type == 'e' ? 1 : 0; }\n\n\n// v11 API AVS_Value setters\nextern \"C\"\nvoid AVSC_CC avs_set_to_error(AVS_Value* v, const char* v0) { new(v) AVSValue(v0); /*string->error*/ v->type = 'e'; }\nextern \"C\"\nvoid AVSC_CC avs_set_to_bool(AVS_Value* v, int v0) { new(v) AVSValue(v0 != 0); }\nextern \"C\"\nvoid AVSC_CC avs_set_to_int(AVS_Value* v, int v0) { new(v) AVSValue(v0); }\nextern \"C\"\nvoid AVSC_CC avs_set_to_float(AVS_Value* v, float v0) { new(v) AVSValue(v0); }\nextern \"C\"\nvoid AVSC_CC avs_set_to_string(AVS_Value* v, const char* v0) { new(v) AVSValue(v0); }\nextern \"C\"\nvoid AVSC_CC avs_set_to_double(AVS_Value* v, double d) { new(v) AVSValue(d); }\nextern \"C\"\nvoid AVSC_CC avs_set_to_long(AVS_Value* v, int64_t l) { new(v) AVSValue(l); }\nextern \"C\"\nvoid AVSC_CC avs_set_to_array(AVS_Value* v, AVS_Value* src, int size) { new(v) AVSValue((AVSValue *)src, size); }\nextern \"C\"\nvoid AVSC_CC avs_set_to_void(AVS_Value* v) { new(v) AVSValue(); }\n// existed pre V11\nextern \"C\"\nvoid AVSC_CC avs_set_to_clip(AVS_Value* v, AVS_Clip* c) { new(v) AVSValue(c->clip); }\n\nextern \"C\"\nvoid AVSC_CC avs_copy_value(AVS_Value * dest, AVS_Value src)\n{\n#if 0\n  // no need to guard multidim arrays. avs_release_value will release properly.\n  // true: don't copy array elements recursively\n  new(dest) AVSValue(*(const AVSValue*)&src, true);\n#endif\n  // CONSTRUCTOR9-->Assign(&v, init=true) ensures that the original content\n  // is simply overwritten and will not be freed.\n  new(dest) AVSValue(*(const AVSValue*)&src);\n}\n\n// Releases/free resources contained in an AVS_Value\n// Such types are: \n// - clip\n// - function (not supported on C interface)\n// - double and long on 32 bit architects\n// - Avisynth+ arrays\n// Since AVS_Value is just a struct passed by value, nothing else happens.\n// If AVS_Value has no extra resource to free up, nothing is done.\n// release is mandatory for results of:\n// - avs_invoke \n// - avs_copy_value \n// - avs_set_to_double (x86)\n// - avs_set_to_long (x86)\n// - avs_set_to_array, avs_set_to_clip\n// - in general: all avs_set_xxx values\n\n// Note:\n// Unlike dynamic arrays, which have a full create-copy-modify-release cycle,\n// C plugins/clients can use in-source arrays, typically for assembling function\n// parameters (\"args\"). Do not call avs_release_value on such arrays, as it causes\n// a crash since the array itself and the elements are not maintained by the \n// Avisynth core.However, it is good practice to release the array content\n// with avs_release_value one-by-one for the resource-allocated types mentioned above.\n\nextern \"C\"\nvoid AVSC_CC avs_release_value(AVS_Value v)\n{\n#if 0\n  // This would prevent crashes when a C client calls it for an array.\n  // However, since Avisynth+ arrays can be returned by avs_invoke, avs_copy_value,\n  // and avs_set_to_array, this exemption is no longer valid.\n  // This rule was not explicitly written earlier and must be enforced in clients/plugins,\n  // see the Python wrapper issue in AvsPmod, which was fixed.\n  if (((AVSValue*)&v)->IsArray()) {\n    // signing for destructor: don't free array elements\n    ((AVSValue*)&v)->MarkArrayAsNonDeepCopy();\n  }\n#endif  \n  ((AVSValue*)&v)->~AVSValue();\n}\n\n// API AVS_Value getters, like INLINE versions\nextern \"C\"\nint AVSC_CC avs_get_as_bool(AVS_Value v) { return ((AVSValue*)&v)->AsBool() ? 1 : 0; }\n\nextern \"C\"\nAVS_Clip* AVSC_CC avs_get_as_clip(AVS_Value v, AVS_ScriptEnvironment* env) {\n  // like the existing avs_take_clip, to fit in the avs_get_as_xxxx line\n  AVS_Clip* c = new AVS_Clip;\n  c->env = env->env;\n  c->clip = (IClip*)(v.d.clip);\n  return c;\n}\n\nextern \"C\"\nint AVSC_CC avs_get_as_int(AVS_Value v) { return ((AVSValue*)&v)->AsInt(); }\nextern \"C\"\nint64_t AVSC_CC avs_get_as_long(AVS_Value v) { return ((AVSValue*)&v)->AsLong(); }\nextern \"C\"\nconst char* AVSC_CC avs_get_as_string(AVS_Value v) { return ((AVSValue*)&v)->AsString(); }\nextern \"C\"\ndouble AVSC_CC avs_get_as_float(AVS_Value v) { return ((AVSValue*)&v)->AsFloat(); }\nextern \"C\"\nconst char* AVSC_CC avs_get_as_error(AVS_Value v) {\n  if (v.type == 'e') {\n    v.type = 's'; // 'e'rror is unknown in c++ api\n    return ((AVSValue*)&v)->AsString();\n  }\n  return nullptr;\n}\nextern \"C\"\nconst AVS_Value * AVSC_CC avs_get_as_array(AVS_Value v) { return v.d.array; }\nextern \"C\"\nAVS_Value AVSC_CC avs_get_array_elt(AVS_Value v, int index) \n{ // just a dumb data copy, no ref counting, no resource handling\n  return avs_is_array(v) ? v.d.array[index] : v;\n}\nextern \"C\"\nint AVSC_CC avs_get_array_size(AVS_Value v) { return ((AVSValue*)&v)->ArraySize(); }\n\n\n//////////////////////////////////////////////////////////////////\n//\n//\n//\n\nextern \"C\"\nAVS_Clip * AVSC_CC avs_new_c_filter(AVS_ScriptEnvironment * e,\n  AVS_FilterInfo * *fi,\n  AVS_Value child, int store_child)\n{\n  C_VideoFilter* f = new C_VideoFilter();\n  AVS_Clip* ff = new AVS_Clip();\n  ff->clip = f; // IClip descendant\n  ff->env = e->env;\n  f->env.env = e->env;\n  f->d.env = &f->env;\n  if (store_child) {\n    _ASSERTE(child.type == 'c');\n    f->child.clip = (IClip*)child.d.clip;\n    f->child.env = e->env;\n    f->d.child = &f->child;\n  }\n  *fi = &f->d;\n  // (*fi)->free_filter will be set later by the plugin.\n  // It is used in ~C_VideoFilter, which is called when the clip's \n  // reference count reaches zero and it is released. This serves \n  // as the filter destructor in C.\n  if (child.type == 'c')\n    f->d.vi = *(const AVS_VideoInfo*)(&((IClip*)child.d.clip)->GetVideoInfo());\n  return ff;\n}\n\n/////////////////////////////////////////////////////////////////////\n//\n// AVS_ScriptEnvironment::add_function\n//\n\nstruct C_VideoFilter_UserData {\n  void* user_data;\n  AVS_ApplyFunc func;\n  AVS_ApplyFuncR func_r;\n};\n\nAVSValue __cdecl create_c_video_filter(AVSValue args, void* user_data,\n  IScriptEnvironment* e0)\n{\n  C_VideoFilter_UserData* d = (C_VideoFilter_UserData*)user_data;\n  AVS_ScriptEnvironment env;\n  env.env = e0;\n  env.error = NULL;\n\n  AVS_Value res;\n  if(d->func)\n    res = (d->func)(&env, *(AVS_Value*)&args, d->user_data);\n  else\n    (d->func_r)(&env, (AVS_Value*)&res, *(AVS_Value*)&args, d->user_data); // new in v11: byref\n  if (res.type == 'e') {\n    throw AvisynthError(res.d.string);\n  }\n  else {\n    AVSValue val;\n    val = (*(const AVSValue*)&res);\n    ((AVSValue*)&res)->~AVSValue();\n    return val;\n  }\n}\n\nextern \"C\"\nint AVSC_CC\navs_add_function(AVS_ScriptEnvironment * p, const char* name, const char* params,\n  AVS_ApplyFunc applyf, void* user_data)\n{\n  C_VideoFilter_UserData* dd, * d = new C_VideoFilter_UserData;\n  p->error = 0;\n  d->func = applyf; // return value struct\n  d->func_r = nullptr;\n  d->user_data = user_data;\n  dd = (C_VideoFilter_UserData*)p->env->SaveString((const char*)d, sizeof(C_VideoFilter_UserData));\n  delete d;\n  try {\n    p->env->AddFunction(name, params, create_c_video_filter, dd);\n  }\n  catch (AvisynthError& err) {\n    p->error = err.msg;\n    return -1;\n  }\n  return 0;\n}\n\n// v11\nextern \"C\"\nint AVSC_CC\navs_add_function_r(AVS_ScriptEnvironment* p, const char* name, const char* params,\n  AVS_ApplyFuncR applyf, void* user_data)\n{\n  C_VideoFilter_UserData* dd, * d = new C_VideoFilter_UserData;\n  p->error = 0;\n  d->func = nullptr;\n  d->func_r = applyf;  // return value among parameters byref struct (Python cref callbacks like it better)\n  d->user_data = user_data;\n  dd = (C_VideoFilter_UserData*)p->env->SaveString((const char*)d, sizeof(C_VideoFilter_UserData));\n  delete d;\n  try {\n    p->env->AddFunction(name, params, create_c_video_filter, dd);\n  }\n  catch (AvisynthError& err) {\n    p->error = err.msg;\n    return -1;\n  }\n  return 0;\n}\n\n/////////////////////////////////////////////////////////////////////\n//\n// AVS_ScriptEnvironment\n//\n\nextern \"C\"\nconst char* AVSC_CC avs_get_error(AVS_ScriptEnvironment * p) // return 0 if no error\n{\n  return p->error;\n}\n\nextern \"C\"\nint AVSC_CC avs_get_cpu_flags(AVS_ScriptEnvironment * p)\n{\n  p->error = 0;\n  return p->env->GetCPUFlags();\n}\n\nextern \"C\"\nint64_t AVSC_CC avs_get_cpu_flags_ex(AVS_ScriptEnvironment* p)\n{\n  p->error = 0;\n  return p->env->GetCPUFlagsEx();\n}\n\nextern \"C\"\nchar* AVSC_CC avs_save_string(AVS_ScriptEnvironment * p, const char* s, int length)\n{\n  p->error = 0;\n  return p->env->SaveString(s, length);\n}\n\nextern \"C\"\nchar* AVSC_CC avs_sprintf(AVS_ScriptEnvironment * p, const char* fmt, ...)\n{\n  p->error = 0;\n  va_list vl;\n  va_start(vl, fmt);\n  char* v = p->env->VSprintf(fmt, vl);\n  va_end(vl);\n  return v;\n}\n\n// note: val is really a va_list; I hope everyone typedefs va_list to a pointer\nextern \"C\"\nchar* AVSC_CC avs_vsprintf(AVS_ScriptEnvironment * p, const char* fmt, va_list val)\n{\n  p->error = 0;\n  return p->env->VSprintf(fmt, val);\n}\n\nextern \"C\"\nint AVSC_CC avs_function_exists(AVS_ScriptEnvironment * p, const char* name)\n{\n  p->error = 0;\n  return p->env->FunctionExists(name);\n}\n\nextern \"C\"\nAVS_Value AVSC_CC avs_invoke(AVS_ScriptEnvironment* p, const char* name, AVS_Value args, const char** arg_names)\n{\n  AVS_Value v = { 0,0 };\n  p->error = 0;\n  try {\n    // AVSValue(*(AVSValue*)&args) is deep-copying input array\n\n    // Invoke has a special InvokePreV11C variant if pre V11 C interface \n    // detected, which converts a possible 64 bit result to 32 bit one for\n    // compatibility. double->float, long->int. Nothing should be done here.\n    AVSValue v0 = p->env->Invoke(name, *(AVSValue*)&args, arg_names);\n    new ((AVSValue*)&v) AVSValue(v0);\n  }\n  catch (const IScriptEnvironment::NotFound&) {\n    p->error = \"Function Not Found\";\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n  }\n  if (p->error)\n    v = avs_new_value_error(p->error);\n  return v;\n}\n\nextern \"C\"\nAVS_Value AVSC_CC avs_get_var(AVS_ScriptEnvironment * p, const char* name)\n{\n  AVS_Value v = { 0,0 };\n  p->error = 0;\n  try {\n    AVSValue v0 = p->env->GetVar(name);\n    new ((AVSValue*)&v) AVSValue(v0);\n  }\n  catch (const IScriptEnvironment::NotFound&) {}\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    v = avs_new_value_error(p->error);\n  }\n  return v;\n}\n\nextern \"C\"\nint AVSC_CC avs_set_var(AVS_ScriptEnvironment * p, const char* name, AVS_Value val)\n{\n  p->error = 0;\n  try {\n    return p->env->SetVar(p->env->SaveString(name), *(const AVSValue*)(&val));\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return -1;\n  }\n}\n\nextern \"C\"\nint AVSC_CC avs_set_global_var(AVS_ScriptEnvironment * p, const char* name, AVS_Value val)\n{\n  p->error = 0;\n  try {\n    return p->env->SetGlobalVar(p->env->SaveString(name), *(const AVSValue*)(&val));\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return -1;\n  }\n}\n\nextern \"C\"\nAVS_VideoFrame * AVSC_CC avs_new_video_frame_a(AVS_ScriptEnvironment * p, const AVS_VideoInfo * vi, int align)\n{\n  p->error = 0;\n  try {\n    PVideoFrame f0 = p->env->NewVideoFrame(*(const VideoInfo*)vi, align);\n    AVS_VideoFrame* f;\n    new((PVideoFrame*)&f) PVideoFrame(f0);\n    return f;\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n  }\n  return 0;\n}\n\n// with frame properties, and alignment\n// note: in general there is no need for alignment specificationm use avs_new_video_frame_p\nextern \"C\"\nAVS_VideoFrame * AVSC_CC avs_new_video_frame_p_a(AVS_ScriptEnvironment * p, const AVS_VideoInfo * vi, const AVS_VideoFrame * prop_src, int align)\n{\n  p->error = 0;\n  try {\n    PVideoFrame f0 = p->env->NewVideoFrameP(*(const VideoInfo*)vi, (const PVideoFrame*)&prop_src, align);\n    AVS_VideoFrame* f;\n    new((PVideoFrame*)&f) PVideoFrame(f0);\n    return f;\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n  }\n  return 0;\n}\n\n// with frame properties, no extra alignment requirement\nextern \"C\"\nAVS_VideoFrame * AVSC_CC avs_new_video_frame_p(AVS_ScriptEnvironment * p, const AVS_VideoInfo * vi, const AVS_VideoFrame * prop_src)\n{\n  p->error = 0;\n  try {\n    PVideoFrame f0 = p->env->NewVideoFrameP(*(const VideoInfo*)vi, (const PVideoFrame*)&prop_src, AVS_FRAME_ALIGN);\n    AVS_VideoFrame* f;\n    new((PVideoFrame*)&f) PVideoFrame(f0);\n    return f;\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n  }\n  return 0;\n}\n\n\nextern \"C\"\nint AVSC_CC avs_make_writable(AVS_ScriptEnvironment * p, AVS_VideoFrame * *pvf)\n{\n  p->error = 0;\n  try {\n    return p->env->MakeWritable((PVideoFrame*)(pvf));\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n  }\n  return -1;\n}\n\n// Since V9\nextern \"C\"\nint AVSC_CC avs_make_property_writable(AVS_ScriptEnvironment * p, AVS_VideoFrame * *pvf)\n{\n  p->error = 0;\n  try {\n    return p->env->MakePropertyWritable((PVideoFrame*)(pvf));\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n  }\n  return -1;\n}\n\nextern \"C\"\nvoid AVSC_CC avs_bit_blt(AVS_ScriptEnvironment * p, BYTE * dstp, int dst_pitch, const BYTE * srcp, int src_pitch, int row_size, int height)\n{\n  p->error = 0;\n  try {\n    p->env->BitBlt(dstp, dst_pitch, srcp, src_pitch, row_size, height);\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n  }\n}\n\nstruct ShutdownFuncData\n{\n  AVS_ShutdownFunc func;\n  void* user_data;\n};\n\nvoid __cdecl shutdown_func_bridge(void* user_data, IScriptEnvironment* env)\n{\n  ShutdownFuncData* d = (ShutdownFuncData*)user_data;\n  AVS_ScriptEnvironment e;\n  e.env = env;\n  e.error = NULL;\n  d->func(d->user_data, &e);\n}\n\nextern \"C\"\nvoid AVSC_CC avs_at_exit(AVS_ScriptEnvironment * p,\n  AVS_ShutdownFunc function, void* user_data)\n{\n  p->error = 0;\n  ShutdownFuncData* dd, * d = new ShutdownFuncData;\n  d->func = function;\n  d->user_data = user_data;\n  dd = (ShutdownFuncData*)p->env->SaveString((const char*)d, sizeof(ShutdownFuncData));\n  delete d;\n  p->env->AtExit(shutdown_func_bridge, dd);\n}\n\nextern \"C\"\nint AVSC_CC avs_check_version(AVS_ScriptEnvironment * p, int version)\n{\n  p->error = 0;\n  try {\n    p->env->CheckVersion(version);\n    return 0;\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return -1;\n  }\n}\n\nextern \"C\"\nAVS_VideoFrame * AVSC_CC avs_subframe(AVS_ScriptEnvironment * p, AVS_VideoFrame * src0,\n  int rel_offset, int new_pitch, int new_row_size, int new_height)\n{\n  p->error = 0;\n  try {\n    PVideoFrame f0 = p->env->Subframe((VideoFrame*)src0, rel_offset, new_pitch, new_row_size, new_height);\n    AVS_VideoFrame* f;\n    new((PVideoFrame*)&f) PVideoFrame(f0);\n    return f;\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nAVS_VideoFrame * AVSC_CC avs_subframe_planar(AVS_ScriptEnvironment * p, AVS_VideoFrame * src0,\n  int rel_offset, int new_pitch, int new_row_size, int new_height,\n  int rel_offsetU, int rel_offsetV, int new_pitchUV)\n{\n  p->error = 0;\n  try {\n    PVideoFrame f0 = p->env->SubframePlanar((VideoFrame*)src0, rel_offset, new_pitch, new_row_size,\n      new_height, rel_offsetU, rel_offsetV, new_pitchUV);\n    AVS_VideoFrame* f;\n    new((PVideoFrame*)&f) PVideoFrame(f0);\n    return f;\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\n// Interface V8\nextern \"C\"\nAVS_VideoFrame * AVSC_CC avs_subframe_planar_a(AVS_ScriptEnvironment * p, AVS_VideoFrame * src0,\n  int rel_offset, int new_pitch, int new_row_size, int new_height,\n  int rel_offsetU, int rel_offsetV, int new_pitchUV, int rel_offsetA)\n{\n  p->error = 0;\n  try {\n    PVideoFrame f0 = p->env->SubframePlanarA((VideoFrame*)src0, rel_offset, new_pitch, new_row_size,\n      new_height, rel_offsetU, rel_offsetV, new_pitchUV, rel_offsetA);\n    AVS_VideoFrame* f;\n    new((PVideoFrame*)&f) PVideoFrame(f0);\n    return f;\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nint AVSC_CC avs_set_memory_max(AVS_ScriptEnvironment * p, int mem)\n{\n  p->error = 0;\n  try {\n    return p->env->SetMemoryMax(mem);\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return -1;\n  }\n}\n\nextern \"C\"\nint AVSC_CC avs_set_working_dir(AVS_ScriptEnvironment * p, const char* newdir)\n{\n  p->error = 0;\n  try {\n    return p->env->SetWorkingDir(newdir);\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return -1;\n  }\n}\n\n// V12\nextern \"C\"\nint AVSC_CC avs_acquire_global_lock(AVS_ScriptEnvironment* p, const char* name)\n{\n  p->error = 0;\n  try {\n    return p->env->AcquireGlobalLock(name) ? 1 : 0;\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\n// V12\nextern \"C\"\nvoid AVSC_CC avs_release_global_lock(AVS_ScriptEnvironment* p, const char* name)\n{\n  p->error = 0;\n  try {\n    p->env->ReleaseGlobalLock(name);\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n  }\n}\n\n// Interface V8. See AVS_AEP_xxx enums\nextern \"C\"\nsize_t AVSC_CC avs_get_env_property(AVS_ScriptEnvironment * p, int avs_aep_prop)\n{\n  p->error = 0;\n  try {\n    return p->env->GetEnvProperty((AvsEnvProperty)avs_aep_prop);\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\n// Interface V8, buffer pool, Support functions\n// see AVS_ALLOCTYPE_xxx enum\nextern \"C\"\nvoid * AVSC_CC avs_pool_allocate(AVS_ScriptEnvironment * p, size_t nBytes, size_t alignment, int avs_alloc_type)\n{\n  p->error = 0;\n  try {\n    return p->env->Allocate(nBytes, alignment, (AvsAllocType)avs_alloc_type);\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n    return 0;\n  }\n}\n\nextern \"C\"\nvoid AVSC_CC avs_pool_free(AVS_ScriptEnvironment * p, void* ptr)\n{\n  p->error = 0;\n  try {\n    return p->env->Free(ptr);\n  }\n  catch (const AvisynthError& err) {\n    p->error = err.msg;\n  }\n}\n\n// Returns TRUE (1) and the requested variable. If the method fails, returns 0 (FALSE) and does not touch 'val'.\n// The returned AVS_Value *val value must be be released with avs_release_value only on success\n// AVS_Value *val is not caller allocated\nextern \"C\"\nint AVSC_CC avs_get_var_try(AVS_ScriptEnvironment * p, const char* name, AVS_Value *val)\n{\n  p->error = 0;\n  AVSValue v0;\n  const bool success = p->env->GetVarTry(name, &v0);\n  if (success) {\n    new ((AVSValue*)val) AVSValue(v0);\n    return 1;\n  }\n  return 0;\n}\n\n// Return the value of the requested variable.\n// If the variable was not found or had the wrong type,\n// return the supplied default value.\nextern \"C\"\nint AVSC_CC avs_get_var_bool(AVS_ScriptEnvironment * p, const char* name, int def)\n{\n  p->error = 0;\n  return (int)(p->env->GetVarBool(name, (bool)def));\n}\n\nextern \"C\"\nint AVSC_CC avs_get_var_int(AVS_ScriptEnvironment * p, const char* name, int def)\n{\n  p->error = 0;\n  return p->env->GetVarInt(name, def);\n}\n\nextern \"C\"\ndouble AVSC_CC avs_get_var_double(AVS_ScriptEnvironment * p, const char* name, double def)\n{\n  p->error = 0;\n  return p->env->GetVarDouble(name, def);\n}\n\nextern \"C\"\nconst char * AVSC_CC avs_get_var_string(AVS_ScriptEnvironment * p, const char* name, const char* def)\n{\n  p->error = 0;\n  return p->env->GetVarString(name, def);\n}\n\nextern \"C\"\nint64_t AVSC_CC avs_get_var_long(AVS_ScriptEnvironment * p, const char* name, int64_t def)\n{\n  p->error = 0;\n  return p->env->GetVarLong(name, def);\n}\n\n/////////////////////////////////////////////////////////////////////\n//\n//\n//\n\n// prototype from avisynth.cpp\nIScriptEnvironment2* CreateScriptEnvironment2_internal(int version, bool fromAvs25, bool fromC);\n\nextern \"C\"\nAVS_ScriptEnvironment * AVSC_CC avs_create_script_environment(int version)\n{\n  AVS_ScriptEnvironment* e = new AVS_ScriptEnvironment;\n  try {\n    if (version < AVISYNTH_CLASSIC_INTERFACE_VERSION)\n      version = AVISYNTH_CLASSIC_INTERFACE_VERSION; // always request a more modern ScriptEnvironment.\n    e->env = CreateScriptEnvironment2_internal(version, false, true); // flag: from C\n    e->error = NULL;\n  }\n  catch (const AvisynthError& err) {\n    e->error = err.msg;\n    e->env = 0;\n  }\n  return e;\n}\n\n\n/////////////////////////////////////////////////////////////////////\n//\n//\n//\n\nextern \"C\"\nvoid AVSC_CC avs_delete_script_environment(AVS_ScriptEnvironment * e)\n{\n  if (e) {\n    if (e->env) {\n      try {\n        e->env->DeleteScriptEnvironment();\n      }\n      catch (const AvisynthError& err) {\n        (void)err;  // silence warning about unused variable; variable is kept for debugging\n      }\n      e->env = 0;\n    }\n    delete e;\n  }\n}\n"
  },
  {
    "path": "avs_core/core/avs_simd_c.h",
    "content": "// AviSynth+.  Copyright 2025 AviSynth+ Project\n// https://avs-plus.net\n// http://avisynth.nl\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// SIMD-like C++ classes (C)2025 Ferenc Pintér\n\n#ifndef __AVS_SIMD_C_H__\n#define __AVS_SIMD_C_H__\n// Auto-vectorization friendly types for smart compilers\n// Some helper static functions, marked with c++ 17 [[maybe_unused]] attribute\n\n#include <avs/config.h> // force inline variants\n#include <algorithm>\n#include <cstdint>\n#include <cstring>\n#include <iostream>\n#include <type_traits>\n#include <stdexcept>\n\n#if defined(_MSC_VER) && !defined(__clang__) && defined(INTEL_INTRINSICS)\n#include <immintrin.h>  // covers SSE2 through AVX2 for MSVC\n#endif\n\n// Determine if we can use vector attribute\n\n// As of 2025 clang (llvm) supports vector attributes and also produces fast code\n// gcc can use it but may produce slower code with than without vector attributes.\n// (gcc 12.2 on aarch64 Raspberry Pi 5 is slow)\n// We still keep it here, maybe non-arm platforms can benefit with gcc as well.\n// Note: llvm defines __clang__ as well\n#if defined(__GNUC__) || defined(__clang__)\n#define HAS_VECTOR_ATTRIBUTE 1\n#else\n#define HAS_VECTOR_ATTRIBUTE 0\n#endif\n\n// Vector type definitions\n#if HAS_VECTOR_ATTRIBUTE\n    // GCC/Clang supports vector attribute\nusing uint8_vec32_t = uint8_t __attribute__((vector_size(32)));  // 256-bit (32 bytes)\nusing uint8_vec16_t = uint8_t __attribute__((vector_size(16)));  // 128-bit (16 bytes)\nusing uint8_vec8_t  = uint8_t __attribute__((vector_size(8)));   // 64-bit  (8 bytes)\nusing uint8_vec4_t  = uint8_t __attribute__((vector_size(4)));   // 32-bit  (4 bytes)\n\nusing int16_vec16_t = int16_t __attribute__((vector_size(32)));  // 256-bit (32 bytes)\nusing int16_vec8_t  = int16_t __attribute__((vector_size(16)));  // 128-bit (16 bytes)\nusing int16_vec4_t  = int16_t __attribute__((vector_size(8)));   // 64-bit  (8 bytes)\n\nusing uint16_vec16_t = uint16_t __attribute__((vector_size(32))); // 256-bit (32 bytes)\nusing uint16_vec8_t  = uint16_t __attribute__((vector_size(16))); // 128-bit (16 bytes)\nusing uint16_vec4_t  = uint16_t __attribute__((vector_size(8)));  // 64-bit  (8 bytes)\n\nusing int32_vec8_t  = int32_t __attribute__((vector_size(32)));  // 256-bit (32 bytes)\nusing int32_vec4_t  = int32_t __attribute__((vector_size(16)));  // 128-bit (16 bytes)\nusing int32_vec2_t  = int32_t __attribute__((vector_size(8)));   // 64-bit  (8 bytes)\n\nusing float_vec8_t  = float __attribute__((vector_size(32)));    // 256-bit (32 bytes)\nusing float_vec4_t  = float __attribute__((vector_size(16)));    // 128-bit (16 bytes)\nusing float_vec2_t  = float __attribute__((vector_size(8)));     // 64-bit  (8 bytes)\n\n#else\n\n// For MSVC: use __declspec(align) + plain array in a struct, may help optimizer\ntemplate<typename T, size_t N>\nstruct alignas(N * sizeof(T)) Avs_SimdArray {\n  T v[N];\n\n  AVS_FORCEINLINE T& operator[](size_t i) { return v[i]; }\n  AVS_FORCEINLINE const T& operator[](size_t i) const { return v[i]; }\n\n  // Trivial fill\n  AVS_FORCEINLINE void fill(T val) {\n    if constexpr (sizeof(T) == 1) {\n      memset(v, val, N);  // intrinsic, single rep stosd or movdqu\n    }\n    else {\n      // Seemingly MSVC (as of in 2026) will not vectorize a loop here, but will inline these\n      for (size_t i = 0; i < N; ++i) v[i] = val;\n    }\n  }\n\n  // Iterators for compatibility\n  AVS_FORCEINLINE T* begin() { return v; }\n  AVS_FORCEINLINE T* end() { return v + N; }\n  AVS_FORCEINLINE const T* begin() const { return v; }\n  AVS_FORCEINLINE const T* end()   const { return v + N; }\n\n  static constexpr size_t size() { return N; }\n};\n\nusing uint8_vec32_t = Avs_SimdArray<uint8_t, 32>;\nusing uint8_vec16_t = Avs_SimdArray<uint8_t, 16>;\nusing uint8_vec8_t = Avs_SimdArray<uint8_t, 8>;\nusing uint8_vec4_t = Avs_SimdArray<uint8_t, 4>;\n\nusing int16_vec16_t = Avs_SimdArray<int16_t, 16>;\nusing int16_vec8_t = Avs_SimdArray<int16_t, 8>;\nusing int16_vec4_t = Avs_SimdArray<int16_t, 4>;\n\nusing uint16_vec16_t = Avs_SimdArray<uint16_t, 16>;\nusing uint16_vec8_t = Avs_SimdArray<uint16_t, 8>;\nusing uint16_vec4_t = Avs_SimdArray<uint16_t, 4>;\n\nusing int32_vec8_t = Avs_SimdArray<int32_t, 8>;\nusing int32_vec4_t = Avs_SimdArray<int32_t, 4>;\nusing int32_vec2_t = Avs_SimdArray<int32_t, 2>;\nusing float_vec8_t = Avs_SimdArray<float, 8>;\nusing float_vec4_t = Avs_SimdArray<float, 4>;\nusing float_vec2_t = Avs_SimdArray<float, 2>;\n\n#endif // HAS_VECTOR_ATTRIBUTE\n\n// Type traits for vector elements\ntemplate <typename T>\nstruct vector_traits {};\n\n\n#define DEFINE_VECTOR_TRAITS(VecType, ElemType, Size) \\\n    template <> struct vector_traits<VecType> { \\\n        using element_type = ElemType; \\\n        static constexpr size_t size = Size; \\\n    };\n\n// Covering 8 to 32 bytes long vectors.\n// No int64_t or double, they are not relevant in AviSynth\nDEFINE_VECTOR_TRAITS(uint8_vec32_t, uint8_t, 32)\nDEFINE_VECTOR_TRAITS(uint8_vec16_t, uint8_t, 16)\nDEFINE_VECTOR_TRAITS(uint8_vec8_t, uint8_t, 8)\nDEFINE_VECTOR_TRAITS(uint8_vec4_t, uint8_t, 4)\nDEFINE_VECTOR_TRAITS(int16_vec16_t, int16_t, 16)\nDEFINE_VECTOR_TRAITS(int16_vec8_t, int16_t, 8)\nDEFINE_VECTOR_TRAITS(int16_vec4_t, int16_t, 4)\nDEFINE_VECTOR_TRAITS(uint16_vec16_t, uint16_t, 16)\nDEFINE_VECTOR_TRAITS(uint16_vec8_t, uint16_t, 8)\nDEFINE_VECTOR_TRAITS(uint16_vec4_t, uint16_t, 4)\nDEFINE_VECTOR_TRAITS(int32_vec8_t, int32_t, 8)\nDEFINE_VECTOR_TRAITS(int32_vec4_t, int32_t, 4)\nDEFINE_VECTOR_TRAITS(int32_vec2_t, int32_t, 2)\nDEFINE_VECTOR_TRAITS(float_vec8_t, float, 8)\nDEFINE_VECTOR_TRAITS(float_vec4_t, float, 4)\nDEFINE_VECTOR_TRAITS(float_vec2_t, float, 2)\n\n// Specialization for array-based vector operations\n#if !HAS_VECTOR_ATTRIBUTE\ntemplate <typename VecType, typename ScalarType = typename vector_traits<VecType>::element_type>\nclass VectorOps {\npublic:\n  static AVS_FORCEINLINE VecType add(const VecType& a, const VecType& b) {\n    VecType result;\n#if defined(_MSC_VER) && !defined(__clang__) && defined(INTEL_INTRINSICS) && defined(__AVX__)\n    if constexpr (sizeof(VecType) == 32) {\n      // Force the use of YMM\n      __m256 va = _mm256_loadu_ps(reinterpret_cast<const float*>(&a));\n      __m256 vb = _mm256_loadu_ps(reinterpret_cast<const float*>(&b));\n      __m256 vr = _mm256_add_ps(va, vb);\n      _mm256_storeu_ps(reinterpret_cast<float*>(&result), vr);\n      return result;\n    }\n#endif\n    for (size_t i = 0; i < vector_traits<VecType>::size; ++i) {\n      result[i] = a[i] + b[i];\n    }\n    return result;\n  }\n\n  static AVS_FORCEINLINE VecType subtract(const VecType& a, const VecType& b) {\n    VecType result;\n    for (size_t i = 0; i < vector_traits<VecType>::size; ++i) {\n      result[i] = a[i] - b[i];\n    }\n    return result;\n  }\n\n  static AVS_FORCEINLINE VecType multiply(const VecType& a, const VecType& b) {\n    VecType result;\n    for (size_t i = 0; i < vector_traits<VecType>::size; ++i) {\n      result[i] = a[i] * b[i];\n    }\n    return result;\n  }\n\n  static AVS_FORCEINLINE VecType scalar_multiply(const VecType& a, ScalarType scalar) {\n    VecType result;\n#if defined(_MSC_VER) && !defined(__clang__) && defined(INTEL_INTRINSICS) && defined(__AVX__)\n    if constexpr (sizeof(VecType) == 32 && std::is_same_v<ScalarType, float>) {\n      if constexpr (sizeof(VecType) == 32) {\n        // Use 'set1' which the compiler usually optimizes to a broadcast\n        __m256 v_a = _mm256_loadu_ps((const float*)&a);\n        __m256 v_res = _mm256_mul_ps(v_a, _mm256_set1_ps(scalar));\n        _mm256_storeu_ps((float*)&result, v_res);\n        return result;\n      }\n    }\n#endif\n    for (size_t i = 0; i < vector_traits<VecType>::size; ++i) {\n      result[i] = a[i] * scalar;\n    }\n    return result;\n  }\n\n  static AVS_FORCEINLINE VecType left_shift(const VecType& a, int shift) {\n    VecType result;\n    for (size_t i = 0; i < vector_traits<VecType>::size; ++i) {\n      result[i] = a[i] << shift;\n    }\n    return result;\n  }\n\n  static AVS_FORCEINLINE VecType right_shift(const VecType& a, int shift) {\n    VecType result;\n    for (size_t i = 0; i < vector_traits<VecType>::size; ++i) {\n      result[i] = a[i] >> shift;\n    }\n    return result;\n  }\n};\n#endif\n\n// Template for vector class wrapper\n// Passing \"Derived\" allows syntax for assigning a wrapper class to a derived class.\ntemplate <typename Derived, typename VecType>\nclass VectorWrapper {\nprivate:\n  using ElementType = typename vector_traits<VecType>::element_type;\n  static constexpr size_t N = vector_traits<VecType>::size;\n  VecType data;\n\npublic:\n\n  // Default constructor\n  AVS_FORCEINLINE VectorWrapper() {\n#if HAS_VECTOR_ATTRIBUTE\n    data = VecType{};  // empty initializer\n#else\n    data.fill(ElementType{});\n#endif\n  }\n\n  // Constructor from scalar\n  AVS_FORCEINLINE explicit VectorWrapper(ElementType val) {\n#if HAS_VECTOR_ATTRIBUTE\n    data = VecType{};\n    for (size_t i = 0; i < N; ++i) {\n      data[i] = val;\n    }\n#else\n#if defined(_MSC_VER) && !defined(__clang__) && defined(INTEL_INTRINSICS)\n    if constexpr (sizeof(VecType) == 32 && std::is_same_v<ElementType, float>) {\n#if defined(__AVX__)\n      if (val == 0.0f) {\n        __m256 zero = _mm256_setzero_ps();\n        _mm256_storeu_ps((float*)&data, zero);\n        return;\n      }\n      __m256 v = _mm256_set1_ps(val);\n      _mm256_storeu_ps((float*)&data, v);\n      return;\n#else\n      // __m128 path\n      if (val == 0.0f) {\n        __m128 zero = _mm_setzero_ps();\n        _mm_storeu_ps((float*)&data, zero); // 2x128 = 32 bytes, so we can store 16 bytes at a time with\n        _mm_storeu_ps((float*)((char*)&data + 16), zero);\n        return;\n      }\n      __m128 v = _mm_set1_ps(val); // possibly optimized to a broadcast\n      _mm_storeu_ps((float*)&data, v);\n      _mm_storeu_ps((float*)((char*)&data + 16), v);\n      return;\n#endif\n    } // 32 bytes\n    if constexpr (sizeof(VecType) == 16 && std::is_same_v<ElementType, float>) {\n      if (val == 0.0f) {\n        __m128 zero = _mm_setzero_ps();\n        _mm_storeu_ps((float*)&data, zero);\n        return;\n      }\n      __m128 v = _mm_set1_ps(val); // possibly optimized to a broadcast\n      _mm_storeu_ps((float*)&data, v);\n      return;\n    } // 16 bytes\n#endif\n    data.fill(val);\n#endif\n  }\n\n  // Constructor from raw vector type\n  AVS_FORCEINLINE explicit VectorWrapper(const VecType& vec) {\n#if HAS_VECTOR_ATTRIBUTE\n    data = vec;  // native vector assign, optimal\n#else\n    memcpy(&data, &vec, sizeof(data));  // fixed-size, MSVC inlines to movq/movdqu\n#endif\n  }\n  // Conversion operator, allowing implicit conversion to the derived type.\n  // Supporting syntax like: Int32x4 = src * coeff; where the right side is a VectorWrapper<Int32x4, int32_vec4_t>\n  AVS_FORCEINLINE operator Derived() const {\n    return static_cast<const Derived>(data);\n  }\n\n  // Copy constructor\n  // Note: There is no need to define assignment operators for move or copy, as the underlying 'data' type \n  // (either array or vector attribute) already provides support for these operations.\n  // 2026: but yes, we need! For MSVC optimizer's sake at least.\n#ifdef HAS_VECTOR_ATTRIBUTE   \n  AVS_FORCEINLINE VectorWrapper(const VectorWrapper& other) : data(other.data) {}\n#else\n  AVS_FORCEINLINE VectorWrapper(const VectorWrapper& other) {\n    memcpy(&data, &other.data, sizeof(data));\n  }\n  AVS_FORCEINLINE VectorWrapper& operator=(const VectorWrapper& other) {\n    memcpy(&data, &other.data, sizeof(data));\n    return *this;\n  }\n#endif\n\n  // Constructors from initializer list, e.g. x = {32768, 0, 0, 0};\n\n  // Constexpr variadic template constructor for compile-time initialization.Thx AI :)\n  template <typename... Args,\n    typename = std::enable_if_t<sizeof...(Args) + 1 == N>>\n    AVS_FORCEINLINE constexpr VectorWrapper(ElementType arg, Args... args) {\n    static_assert(sizeof...(args) + 1 == N, \"Initializer list must have exactly N elements.\");\n    ElementType values[] = { arg, static_cast<ElementType>(args)... };\n    for (size_t i = 0; i < N; ++i) {\n      data[i] = values[i];\n    }\n  }\n\n  // std::initializer_list constructor for runtime initialization\n  AVS_FORCEINLINE VectorWrapper(std::initializer_list<ElementType> values) {\n    if (values.size() != N) {\n      throw std::logic_error(\"Initializer list must have exactly N elements\");\n    }\n    size_t i = 0;\n    for (auto val : values) {\n      data[i++] = val;\n    }\n  }\n\n  // Load only the lower half of the vector (e.g., 8 bytes for a 16-byte vector)\n  AVS_FORCEINLINE void load_lo(const ElementType* ptr) {\n#if HAS_VECTOR_ATTRIBUTE\n    for (size_t i = 0; i < N / 2; ++i) {\n      data[i] = ptr[i];\n    }\n    for (size_t i = N / 2; i < N; ++i) {\n      data[i] = ElementType{}; // Zero out the upper half\n    }\n#else\n    memcpy(data.v, ptr, sizeof(data.v) / 2); // avoid std::copy!!!at least for MSVC\n    memset(data.v + N / 2, 0, sizeof(data.v) / 2); // zero upper half\n#endif\n  }\n\n  // Conversions from other types as long as their size matches\n  // Full and half size\n\n  // Full: Widening or narrowing without range checks, e.g., no saturation when converting down.\n  // This one  must be used as src=Int32x4::convert_from(src16) and NOT as src32.convert_from(src16).\n  template <typename OtherDerived, typename OtherVecType>\n  AVS_FORCEINLINE static VectorWrapper convert_from(const VectorWrapper<OtherDerived, OtherVecType>& other) {\n    static_assert(vector_traits<VecType>::size == vector_traits<OtherVecType>::size,\n      \"Vector sizes must match for convert_from.\");\n#if HAS_VECTOR_ATTRIBUTE\n    VecType result_vec;\n    result_vec = __builtin_convertvector(other.raw(), VecType);\n    return VectorWrapper(result_vec);\n#else\n    VecType result;\n    for (size_t i = 0; i < vector_traits<VecType>::size; ++i) {\n      result[i] = static_cast<typename vector_traits<VecType>::element_type>(other[i]);\n    }\n    return VectorWrapper(result);\n#endif\n\n  }\n\n  // Static factory: Widening or narrowing the lower half of a larger vector\n  template <typename OtherDerived, typename OtherVecType>\n  AVS_FORCEINLINE static VectorWrapper convert_from_lo(const VectorWrapper<OtherDerived, OtherVecType>& other) {\n    static_assert(vector_traits<VecType>::size == vector_traits<OtherVecType>::size / 2,\n      \"Source vector must have twice the elements of target for convert_from_lo.\");\n\n    VectorWrapper result;\n    for (size_t i = 0; i < vector_traits<VecType>::size; ++i) {\n      // Access via operator[] which is public\n      result.raw()[i] = static_cast<ElementType>(other[i]);\n    }\n    return result;\n  }\n\n  // Static factory: Widening or narrowing the upper half of a larger vector\n  template <typename OtherDerived, typename OtherVecType>\n  AVS_FORCEINLINE static VectorWrapper convert_from_hi(const VectorWrapper<OtherDerived, OtherVecType>& other) {\n    static_assert(vector_traits<VecType>::size == vector_traits<OtherVecType>::size / 2,\n      \"Source vector must have twice the elements of target for convert_from_hi.\");\n\n    constexpr auto half_size = vector_traits<OtherVecType>::size / 2;\n    VectorWrapper result;\n    for (size_t i = 0; i < vector_traits<VecType>::size; ++i) {\n      result.raw()[i] = static_cast<ElementType>(other[half_size + i]);\n    }\n    return result;\n  }\n\n  // Fill an integer vector/array from integer pointer source.\n  // Versions for uint8_t, int16_t (short), uint16_t and int32_t\n\n  AVS_FORCEINLINE void load_from_any_intptr(const uint8_t* ptr) {\n    static_assert(\n      std::is_same_v<typename vector_traits<VecType>::element_type, int32_t> ||\n      std::is_same_v<typename vector_traits<VecType>::element_type, int16_t> ||\n      std::is_same_v<typename vector_traits<VecType>::element_type, uint16_t> ||\n      std::is_same_v<typename vector_traits<VecType>::element_type, uint8_t>,\n      \"load_from_any_intptr is only valid for int32_t, int16_t, uint16_t or uint8_t target element types.\"\n      );\n\n    for (size_t i = 0; i < vector_traits<VecType>::size; ++i) {\n      data[i] = static_cast<typename vector_traits<VecType>::element_type>(ptr[i]);\n    }\n  }\n\n  AVS_FORCEINLINE void load_from_any_intptr(const short* ptr) {\n    static_assert(\n      std::is_same_v<typename vector_traits<VecType>::element_type, int32_t> ||\n      std::is_same_v<typename vector_traits<VecType>::element_type, int16_t> ||\n      std::is_same_v<typename vector_traits<VecType>::element_type, uint16_t> ||\n      std::is_same_v<typename vector_traits<VecType>::element_type, uint8_t>,\n      \"load_from_any_intptr is only valid for int32_t, int16_t, uint16_t or uint8_t target element types.\"\n      );\n\n    for (size_t i = 0; i < vector_traits<VecType>::size; ++i) {\n      data[i] = static_cast<typename vector_traits<VecType>::element_type>(ptr[i]);\n    }\n  }\n\n  AVS_FORCEINLINE void load_from_any_intptr(const uint16_t* ptr) {\n    static_assert(\n      std::is_same_v<typename vector_traits<VecType>::element_type, int32_t> ||\n      std::is_same_v<typename vector_traits<VecType>::element_type, int16_t> ||\n      std::is_same_v<typename vector_traits<VecType>::element_type, uint16_t> ||\n      std::is_same_v<typename vector_traits<VecType>::element_type, uint8_t>,\n      \"load_from_any_intptr is only valid for int32_t, int16_t, uint16_t or uint8_t target element types.\"\n      );\n\n    for (size_t i = 0; i < vector_traits<VecType>::size; ++i) {\n      data[i] = static_cast<typename vector_traits<VecType>::element_type>(ptr[i]);\n    }\n  }\n\n  AVS_FORCEINLINE void load_from_any_intptr(const int32_t* ptr) {\n    static_assert(\n      std::is_same_v<typename vector_traits<VecType>::element_type, int32_t> ||\n      std::is_same_v<typename vector_traits<VecType>::element_type, int16_t> ||\n      std::is_same_v<typename vector_traits<VecType>::element_type, uint16_t> ||\n      std::is_same_v<typename vector_traits<VecType>::element_type, uint8_t>,\n      \"load_from_any_intptr is only valid for int32_t, int16_t, uint16_t or uint8_t target element types.\"\n      );\n\n    for (size_t i = 0; i < vector_traits<VecType>::size; ++i) {\n      data[i] = static_cast<typename vector_traits<VecType>::element_type>(ptr[i]);\n    }\n  }\n\n  // Syntax: variable.load(myPointer);\n  // Load from pointer (potentially unaligned)\n  AVS_FORCEINLINE void load(const ElementType* ptr) {\n#if HAS_VECTOR_ATTRIBUTE\n    for (size_t i = 0; i < N; ++i) {\n      data[i] = ptr[i];\n    }\n#else\n    memcpy(data.v, ptr, sizeof(data.v)); // avoid std::copy!!! At least for MSVC\n#endif\n  }\n\n  // Syntax: variable = VecType::from_ptr(myPointer);\n  // Static factory method\n  AVS_FORCEINLINE static VectorWrapper from_ptr(const ElementType* ptr) {\n    VectorWrapper result;\n#if HAS_VECTOR_ATTRIBUTE\n    result.load(ptr);  // Reuse the instance method\n#else\n    constexpr size_t byte_size = sizeof(result.data);\n\n    // Use _MSC_VER (one underscore) and check for actual size\n#if defined(_MSC_VER) && !defined(__clang__) && defined(INTEL_INTRINSICS)\n    if constexpr (byte_size == 4) {\n      __m128i tmp = _mm_setzero_si128();\n      memcpy(&tmp, ptr, 4); // Coax MSVC into MOVD\n      memcpy(&result.data, &tmp, 4);\n    }\n    else if constexpr (byte_size == 8) {\n      __m128i tmp = _mm_setzero_si128();\n      memcpy(&tmp, ptr, 8); // Coax MSVC into MOVQ\n      memcpy(&result.data, &tmp, 8);\n    }\n    else if constexpr (byte_size == 16) {\n      __m128i tmp = _mm_loadu_si128(reinterpret_cast<const __m128i*>(ptr));\n      memcpy(&result.data, &tmp, 16);\n    }\n    else if constexpr (byte_size == 32) {\n#if defined(__AVX__)\n      // Use a single 256-bit load. This stops the XMM-to-stack-back-to-YMM MSVC habit.\n      _mm256_storeu_ps((float*)&result.raw(), _mm256_loadu_ps(ptr));\n#else\n      __m128i tmp1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(ptr));\n      __m128i tmp1next16 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(ptr + 16));\n      memcpy(&result.data, &tmp1, 16);\n      memcpy(reinterpret_cast<char*>(&result.data) + 16, &tmp1next16, 16);\n#endif\n    }\n    else {\n      // Fallback for 32+ byte or unusual sizes\n      memcpy(&result.data, ptr, byte_size);\n    }\n#else\n    memcpy(&result.data, ptr, byte_size);\n#endif\n#endif\n    return result;\n  }\n\n  // Syntax: variable = VecType::from_ptr_lo(myPointer);\n  // Loads the lower half of the vector and zeros the upper half.\n  AVS_FORCEINLINE static VectorWrapper from_ptr_lo(const ElementType* ptr) {\n    VectorWrapper result;\n#if HAS_VECTOR_ATTRIBUTE\n    // Standard attribute-based load\n    result.load_lo(ptr);\n#else\n    constexpr size_t total_bytes = sizeof(result.data);\n\n#if defined(_MSC_VER) && !defined(__clang__) && defined(INTEL_INTRINSICS)\n    if constexpr (total_bytes == 16) {\n      // Int16x8 or Int32x4 case: Load 8 bytes, zero top 8.\n      // _mm_loadl_epi64 generates MOVQ (XMM load 64-bit).\n      __m128i tmp = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(ptr));\n      memcpy(&result.data, &tmp, 16);\n    }\n    else if constexpr (total_bytes == 32) {\n#if defined(__AVX__)\n      __m128i tmp = _mm_loadu_si128(reinterpret_cast<const __m128i*>(ptr)); // Load 16 bytes into low half, zero top 16.\n      __m256i tmp256 = _mm256_setzero_si256();\n      tmp256 = _mm256_insertf128_si256(tmp256, tmp, 0);\n      memcpy(&result.data, &tmp256, 32);\n#else\n      // 256-bit case: Load 16 bytes into low half, zero top 16.\n      __m128i lo = _mm_loadu_si128(reinterpret_cast<const __m128i*>(ptr));\n      memcpy(&result.data, &lo, 16);\n      // clear high 16 bytes\n      memset(reinterpret_cast<char*>(&result.data) + 16, 0, 16);\n#endif\n    }\n    else {\n      result.load_lo(ptr);\n    }\n#else\n    result.load_lo(ptr);\n#endif\n#endif\n    return result;\n  }\n\n  // Store to pointer (potentially unaligned)\n  AVS_FORCEINLINE void store(ElementType* ptr) const {\n#if HAS_VECTOR_ATTRIBUTE\n    for (size_t i = 0; i < N; ++i) {\n      ptr[i] = data[i];\n    }\n#else\n    memcpy(ptr, data.v, sizeof(data.v));  // with Avs_SimdArray; or &data[0] with std::array\n#endif\n  }\n\n  // Addition operator (+)\n  AVS_FORCEINLINE VectorWrapper operator+(const VectorWrapper& other) const {\n#if HAS_VECTOR_ATTRIBUTE\n    return VectorWrapper(data + other.data);\n#else\n    return VectorWrapper(VectorOps<VecType>::add(data, other.data));\n#endif\n  }\n\n  // Subtraction operator (-)\n  AVS_FORCEINLINE VectorWrapper operator-(const VectorWrapper& other) const {\n#if HAS_VECTOR_ATTRIBUTE\n    return VectorWrapper(data - other.data);\n#else\n    return VectorWrapper(VectorOps<VecType>::subtract(data, other.data));\n#endif\n  }\n\n  // Multiplication operator (*)\n  AVS_FORCEINLINE VectorWrapper operator*(const VectorWrapper& other) const {\n#if HAS_VECTOR_ATTRIBUTE\n    return VectorWrapper(data * other.data);\n#else\n    return VectorWrapper(VectorOps<VecType>::multiply(data, other.data));\n#endif\n  }\n\n  // Scalar multiplication (*val)\n  AVS_FORCEINLINE VectorWrapper operator*(ElementType scalar) const {\n#if HAS_VECTOR_ATTRIBUTE\n    return VectorWrapper(data * scalar);\n#else\n    return VectorWrapper(VectorOps<VecType>::scalar_multiply(data, scalar));\n#endif\n  }\n\n  // Left shift operator (<<)\n  VectorWrapper operator<<(int shift) const {\n#if HAS_VECTOR_ATTRIBUTE\n    return VectorWrapper(data << shift);\n#else\n    return VectorWrapper(VectorOps<VecType>::left_shift(data, shift));\n#endif\n  }\n\n  // Right shift operator (arithmetic) (>>)\n  AVS_FORCEINLINE VectorWrapper operator>>(int shift) const {\n#if HAS_VECTOR_ATTRIBUTE\n    return VectorWrapper(data >> shift);\n#else\n    return VectorWrapper(VectorOps<VecType>::right_shift(data, shift));\n#endif\n  }\n\n  // We do not define special operators for logical shift, but provide a function.\n  AVS_FORCEINLINE VectorWrapper shift_right_logical(int shift) const {\n    // Cast to unsigned type for logical shift\n    using UnsignedVecType = std::make_unsigned_t<typename vector_traits<VecType>::element_type>;\n    VecType result;\n    for (size_t i = 0; i < vector_traits<VecType>::size; ++i) {\n      result[i] = static_cast<UnsignedVecType>(data[i]) >> shift;\n    }\n    return VectorWrapper(result);\n  }\n\n  // Addition assignment operator (+=)\n  AVS_FORCEINLINE VectorWrapper& operator+=(const VectorWrapper& other) {\n#if HAS_VECTOR_ATTRIBUTE\n    data += other.data;\n#else\n    data = VectorOps<VecType>::add(data, other.data);\n#endif\n    return *this;\n  }\n\n  // Subtract assignment operator (-=)\n  AVS_FORCEINLINE VectorWrapper& operator-=(const VectorWrapper& other) {\n#if HAS_VECTOR_ATTRIBUTE\n    data -= other.data;\n#else\n    data = VectorOps<VecType>::sub(data, other.data);\n#endif\n    return *this;\n  }\n\n  // Multiplication assignment operator (*=) \n  AVS_FORCEINLINE VectorWrapper& operator*=(const VectorWrapper& other) {\n#if HAS_VECTOR_ATTRIBUTE\n    data *= other.data;\n#else\n    data = VectorOps<VecType>::mul(data, other.data);\n#endif\n    return *this;\n  }\n\n  // right shift assignment operator (>>=)\n  AVS_FORCEINLINE VectorWrapper& operator>>=(int shift) {\n#if HAS_VECTOR_ATTRIBUTE\n    data >>= shift;\n#else\n    data = VectorOps<VecType>::right_shift(data, shift);\n#endif\n    return *this;\n  }\n\n  // left shift assignment operator (<<=)\n  AVS_FORCEINLINE VectorWrapper& operator<<=(int shift) {\n#if HAS_VECTOR_ATTRIBUTE\n    data <<= shift;\n#else\n    data = VectorOps<VecType>::left_shift(data, shift);\n#endif\n    return *this;\n  }\n\n  // Minimum operation: z = x.min(scalar)\n  AVS_FORCEINLINE VectorWrapper min(ElementType scalar) const {\n#if HAS_VECTOR_ATTRIBUTE\n    VecType result;\n    for (size_t i = 0; i < N; ++i) {\n      result[i] = data[i] < scalar ? data[i] : scalar;\n    }\n    return VectorWrapper(result);\n#else\n    VecType result;\n    for (size_t i = 0; i < N; ++i) {\n      result[i] = std::min(data[i], scalar);\n    }\n    return VectorWrapper(result);\n#endif\n  }\n\n  // Maximum operation: z = x.max(scalar)\n  AVS_FORCEINLINE VectorWrapper max(ElementType scalar) const {\n#if HAS_VECTOR_ATTRIBUTE\n    VecType result;\n    for (size_t i = 0; i < N; ++i) {\n      result[i] = data[i] > scalar ? data[i] : scalar;\n    }\n    return VectorWrapper(result);\n#else\n    VecType result;\n    for (size_t i = 0; i < N; ++i) {\n      result[i] = std::max(data[i], scalar);\n    }\n    return VectorWrapper(result);\n#endif\n  }\n\n  // Minimum operation (element-wise): z = x.min(y)\n  AVS_FORCEINLINE VectorWrapper min(const VectorWrapper& other) const {\n#if HAS_VECTOR_ATTRIBUTE\n    // Use a ternary operator with a comparison to simulate min operation\n    VecType result;\n    for (size_t i = 0; i < N; ++i) {\n      result[i] = data[i] < other.data[i] ? data[i] : other.data[i];\n    }\n    return VectorWrapper(result);\n#else\n    VecType result;\n    for (size_t i = 0; i < N; ++i) {\n      result[i] = std::min(data[i], other.data[i]);\n    }\n    return VectorWrapper(result);\n#endif\n  }\n\n  // Maximum operation (element-wise) : z = x.max(y)\n  AVS_FORCEINLINE VectorWrapper max(const VectorWrapper& other) const {\n#if HAS_VECTOR_ATTRIBUTE\n    // Use a ternary operator with a comparison to simulate max operation\n    VecType result;\n    for (size_t i = 0; i < N; ++i) {\n      result[i] = data[i] > other.data[i] ? data[i] : other.data[i];\n    }\n    return VectorWrapper(result);\n#else\n    VecType result;\n    for (size_t i = 0; i < N; ++i) {\n      result[i] = std::max(data[i], other.data[i]);\n    }\n    return VectorWrapper(result);\n#endif\n  }\n\n  // Static min functions similar to SIMD intrinsics: z = min(x, y)\n  AVS_FORCEINLINE static VectorWrapper min(const VectorWrapper& a, const VectorWrapper& b) {\n    return a.min(b);\n  }\n\n  // Static max function similar to SIMD intrinsics: z = max(x, y)\n  AVS_FORCEINLINE static VectorWrapper max(const VectorWrapper& a, const VectorWrapper& b) {\n    return a.max(b);\n  }\n\n  // Accessor for raw data\n  AVS_FORCEINLINE const VecType& raw() const { return data; }\n  AVS_FORCEINLINE VecType& raw() { return data; }\n\n  // Element access (const and non-const versions)\n  AVS_FORCEINLINE ElementType operator[](size_t idx) const {\n    return data[idx];\n  }\n\n  // a set method instead of non-const operator[]\n  // use: x.set(index, value) instead of x[index] = value\n  AVS_FORCEINLINE void set(size_t idx, ElementType value) {\n    data[idx] = value;\n  }\n\n  AVS_FORCEINLINE int32_t horiz_add_int32() const {\n#if defined(_MSC_VER) && !defined(__clang__) && defined(INTEL_INTRINSICS)\n    static_assert(N * sizeof(ElementType) <= 16, \"horiz_add_int32: vector too large for XMM\");\n    __m128i v = _mm_setzero_si128();  // zero upper lanes for sub-16-byte vectors\n    memcpy(&v, &data, N * sizeof(ElementType));\n\n    // SSE2 only, hadd simulation with shuffles and adds\n    if constexpr (N * sizeof(ElementType) <= 4) {\n      return _mm_cvtsi128_si32(v);\n    }\n    else if constexpr (N * sizeof(ElementType) <= 8) {\n      __m128i hi32 = _mm_shuffle_epi32(v, _MM_SHUFFLE(1, 1, 1, 1));\n      return _mm_cvtsi128_si32(_mm_add_epi32(v, hi32));\n    }\n    else {\n      // 4x int32\n      // v = [D, C, B, A]\n      __m128i hi64 = _mm_unpackhi_epi64(v, v); // [B, A, D, C]\n      v = _mm_add_epi32(v, hi64); // [D+B, C+A, B+D, A+C]\n      __m128i hi32 = _mm_shuffle_epi32(v, _MM_SHUFFLE(1, 1, 1, 1)); // [C+A, C+A, C+A, C+A]\n      v = _mm_add_epi32(v, hi32); // [..., ..., ..., A+C+B+D]\n      return _mm_cvtsi128_si32(v);\n    }\n#else\n    int32_t sum = 0;\n    for (size_t i = 0; i < N; ++i)\n#if HAS_VECTOR_ATTRIBUTE\n      sum += data[i];\n#else\n      sum += data.v[i];\n#endif\n    return sum;\n#endif\n  }\n\n  AVS_FORCEINLINE float horiz_add_float() const {\n#if defined(_MSC_VER) && !defined(__clang__) && defined(INTEL_INTRINSICS)\n    static_assert(N * sizeof(ElementType) <= 16, \"horiz_add_float: vector too large for XMM\");\n    __m128 v = _mm_setzero_ps();\n    memcpy(&v, &data, N * sizeof(ElementType));\n    // SSE2 only, not haddps, only quick shuffles and adds\n    if constexpr (N <= 1) {\n      return _mm_cvtss_f32(v);\n    }\n    else if constexpr (N <= 2) {\n      __m128 hi32 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1));\n      return _mm_cvtss_f32(_mm_add_ss(v, hi32));\n    }\n    else {\n      // v = [D, C, B, A]\n      __m128 hi64 = _mm_movehl_ps(v, v); // [B, A, D, C]\n      v = _mm_add_ps(v, hi64); // [D+B, C+A, B+D, A+C]\n      __m128 hi32 = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1)); // [C+A, C+A, C+A, C+A]\n      v = _mm_add_ss(v, hi32); // [..., ..., ..., A+C+B+D]\n      return _mm_cvtss_f32(v);\n    }\n#else\n    float sum = 0.0f;\n    for (size_t i = 0; i < N; ++i)\n#if HAS_VECTOR_ATTRIBUTE\n      sum += static_cast<float>(data[i]);\n#else\n      sum += static_cast<float>(data.v[i]);\n#endif\n    return sum;\n#endif\n  }\n\n  static constexpr size_t size() { return N; }\n};\n\n// Scalar multiplication (scalar on left)\ntemplate <typename Derived, typename VecType>\nAVS_FORCEINLINE VectorWrapper<Derived, VecType> operator*(\n  typename vector_traits<VecType>::element_type scalar,\n  const VectorWrapper<Derived, VecType>& vec) {\n  return vec * scalar;\n}\n\n// Stream output operator\ntemplate <typename Derived, typename VecType>\nstd::ostream& operator<<(std::ostream& os, const VectorWrapper<Derived, VecType>& vec) {\n  os << \"[\";\n  for (size_t i = 0; i < vector_traits<VecType>::size; ++i) {\n    os << vec[i];\n    if (i < vector_traits<VecType>::size - 1) os << \", \";\n  }\n  os << \"]\";\n  return os;\n}\n\n// Concrete class definitions for 8, 16 and 32 bytes vectors\nclass Uint8x32 : public VectorWrapper<Uint8x32, uint8_vec32_t> {\npublic:\n  using Base = VectorWrapper<Uint8x32, uint8_vec32_t>;\n  using Base::Base;\n  using Base::operator=;\n};\n\nclass Uint8x16 : public VectorWrapper<Uint8x16, uint8_vec16_t> {\npublic:\n  using Base = VectorWrapper<Uint8x16, uint8_vec16_t>;\n  using Base::Base;\n  using Base::operator=;\n};\n\nclass Uint8x8 : public VectorWrapper<Uint8x8, uint8_vec8_t> {\npublic:\n  using Base = VectorWrapper<Uint8x8, uint8_vec8_t>;\n  using Base::Base;\n  using Base::operator=;\n};\n\nclass Uint8x4 : public VectorWrapper<Uint8x4, uint8_vec4_t> {\npublic:\n  using Base = VectorWrapper<Uint8x4, uint8_vec4_t>;\n  using Base::Base;\n  using Base::operator=;\n};\n\nclass Int16x16 : public VectorWrapper<Int16x16, int16_vec16_t> {\npublic:\n  using Base = VectorWrapper<Int16x16, int16_vec16_t>;\n  using Base::Base;\n  using Base::operator=;\n};\n\nclass Int16x8 : public VectorWrapper<Int16x8, int16_vec8_t> {\npublic:\n  using Base = VectorWrapper<Int16x8, int16_vec8_t>;\n  using Base::Base;\n  using Base::operator=;\n};\n\nclass Int16x4 : public VectorWrapper<Int16x4, int16_vec4_t> {\npublic:\n  using Base = VectorWrapper<Int16x4, int16_vec4_t>;\n  using Base::Base;\n  using Base::operator=;\n};\n\nclass Uint16x16 : public VectorWrapper<Uint16x16, uint16_vec16_t> {\npublic:\n  using Base = VectorWrapper<Uint16x16, uint16_vec16_t>;\n  using Base::Base;\n  using Base::operator=;\n};\n\nclass Uint16x8 : public VectorWrapper<Uint16x8, uint16_vec8_t> {\npublic:\n  using Base = VectorWrapper<Uint16x8, uint16_vec8_t>;\n  using Base::Base;\n  using Base::operator=;\n};\n\nclass Uint16x4 : public VectorWrapper<Uint16x4, uint16_vec4_t> {\npublic:\n  using Base = VectorWrapper<Uint16x4, uint16_vec4_t>;\n  using Base::Base;\n  using Base::operator=;\n};\n\nclass Int32x8 : public VectorWrapper<Int32x8, int32_vec8_t> {\npublic:\n  using Base = VectorWrapper<Int32x8, int32_vec8_t>;\n  using Base::Base;\n  using Base::operator=;\n};\n\nclass Int32x4 : public VectorWrapper<Int32x4, int32_vec4_t> {\npublic:\n  using Base = VectorWrapper<Int32x4, int32_vec4_t>;\n  using Base::Base;\n  using Base::operator=;\n};\n\nclass Int32x2 : public VectorWrapper<Int32x2, int32_vec2_t> {\npublic:\n  using Base = VectorWrapper<Int32x2, int32_vec2_t>;\n  using Base::Base;\n  using Base::operator=;\n};\n\nclass Float8 : public VectorWrapper<Float8, float_vec8_t> {\npublic:\n  using Base = VectorWrapper<Float8, float_vec8_t>;\n  using Base::Base;\n  using Base::operator=;\n};\n\nclass Float4 : public VectorWrapper<Float4, float_vec4_t> {\npublic:\n  using Base = VectorWrapper<Float4, float_vec4_t>;\n  using Base::Base;\n  using Base::operator=;\n};\n\nclass Float2 : public VectorWrapper<Float2, float_vec2_t> {\npublic:\n  using Base = VectorWrapper<Float2, float_vec2_t>;\n  using Base::Base;\n  using Base::operator=;\n};\n\n// Saturated narrowing integer conversion functions.\n\n// 8x int32_t -> 8x uint8_t\n// Guaranteed to stay in XMM/YMM registers\n[[maybe_unused]] static AVS_FORCEINLINE void convert_and_saturate_int32x8_to_uint8x8(const Int32x8& src1, Uint8x8& result) {\n#if defined(_MSC_VER) && !defined(__clang__) && defined(INTEL_INTRINSICS)\n  // Assuming Int32x8 is composed of two __m128i (low/high) or one __m256i\n  // If using 128-bit wrappers:\n  __m128i src1_lo;\n  __m128i src1_hi;\n  memcpy(&src1_lo, &src1, 16); // first 4 ints\n  memcpy(&src1_hi, reinterpret_cast<const char*>(&src1) + 16, 16); // second 4 ints\n\n  // Step 1: Pack 32-bit to 16-bit (Signed Saturation)\n  __m128i v16 = _mm_packs_epi32(src1_lo, src1_hi);\n\n  // Step 2: Pack 16-bit to 8-bit (Unsigned Saturation)\n  // We use v16 twice because pack instructions always process 128-bits into 128-bits\n  __m128i v8 = _mm_packus_epi16(v16, v16);\n\n  // Step 3: Store only the low 8 bytes (64-bits)\n  _mm_storel_epi64(reinterpret_cast<__m128i*>(&result), v8);\n#else\n  // Fallback for LLVM (which handles the loop perfectly)\n  for (size_t i = 0; i < 8; ++i) {\n    result.set(i, static_cast<uint8_t>(std::min(std::max(src1[i], 0), 255)));\n  }\n#endif\n}\n\n\n// 4x int32_t -> 4x uint8_t\n// Prevents the \"Extract-to-GPR\" penalty seen in your assembly\n[[maybe_unused]] static AVS_FORCEINLINE void convert_and_saturate_int32x4_to_uint8x4(const Int32x4& src1, Uint8x4& result) {\n#if defined(_MSC_VER) && !defined(__clang__) && defined(INTEL_INTRINSICS)\n  __m128i a;\n  memcpy(&a, &src1, 16);\n\n  // Step 1: 32-bit signed -> 16-bit signed saturation\n  // [i32, i32, i32, i32] -> [i16, i16, i16, i16, i16, i16, i16, i16]\n  // We duplicate 'a' to fill the 128-bit output\n  __m128i v16 = _mm_packs_epi32(a, a);\n\n  // Step 2: 16-bit signed -> 8-bit unsigned saturation\n  // This clamps everything to [0, 255]\n  __m128i v8 = _mm_packus_epi16(v16, v16);\n\n  // Step 3: Store only the low 32 bits (4 bytes)\n  // This replaces those 4 'mov byte ptr' instructions with one 'movd'\n  int packed_pixels = _mm_cvtsi128_si32(v8);\n  memcpy(&result, &packed_pixels, 4);\n#else\n  // LLVM/Clang handles the loop fine, as you noted\n  for (size_t i = 0; i < 4; ++i) {\n    result.set(i, static_cast<uint8_t>(std::min(std::max(src1[i], 0), 255)));\n  }\n#endif\n}\n\n// 8x int32_t -> 8x uint16_t\n[[maybe_unused]] static AVS_FORCEINLINE void convert_and_saturate_int32x8_to_uint16x8(const Int32x8& src1, Uint16x8& result) {\n  for (size_t i = 0; i < 8; ++i) {\n    result.set(i, static_cast<uint16_t>(std::min(std::max(src1[i], 0), 65535)));\n  }\n}\n\n\n// 4x int32_t -> 4x uint16_t with 0 <= x <= limit\n[[maybe_unused]] static AVS_FORCEINLINE void convert_and_saturate_int32x4_to_uint16x4_limit(const Int32x4& src1, Uint16x4& result, const uint16_t limit) {\n#if defined(_MSC_VER) && !defined(__clang__) && defined(INTEL_INTRINSICS)\n  __m128i a;\n  memcpy(&a, &src1, 16);\n\n#if defined(__AVX__) || defined(__SSE4_1__)\n  __m128i packed = _mm_packus_epi32(a, a);\n  __m128i vlimit = _mm_set1_epi16(static_cast<short>(limit));\n  __m128i clamped = _mm_min_epu16(packed, vlimit);\n  _mm_storel_epi64(reinterpret_cast<__m128i*>(&result), clamped);\n#else\n  // SSE2 Fallback: Bias trick + manual unsigned min\n  const __m128i bias = _mm_set1_epi32(32768);\n  const __m128i bias16 = _mm_set1_epi16(-32768);\n  __m128i biased = _mm_sub_epi32(a, bias);\n  __m128i packed = _mm_packs_epi32(biased, biased);\n  __m128i unbiased = _mm_sub_epi16(packed, bias16);\n\n  __m128i vlimit = _mm_set1_epi16(static_cast<short>(limit));\n  const __m128i sign_bias = _mm_set1_epi16(-32768);\n  __m128i u_shifted = _mm_add_epi16(unbiased, sign_bias);\n  __m128i l_shifted = _mm_add_epi16(vlimit, sign_bias);\n  __m128i mask = _mm_cmpgt_epi16(u_shifted, l_shifted);\n  __m128i final = _mm_or_si128(_mm_and_si128(mask, vlimit), _mm_andnot_si128(mask, unbiased));\n  _mm_storel_epi64(reinterpret_cast<__m128i*>(&result), final);\n#endif\n\n#else\n  for (size_t i = 0; i < 4; ++i) {\n    result.set(i, static_cast<uint16_t>(std::min(std::max(src1[i], 0), (int)limit)));\n  }\n#endif\n}\n\n\n// 4x int32_t -> 4x uint16_t\n[[maybe_unused]] static AVS_FORCEINLINE void convert_and_saturate_int32x4_to_uint16x4(const Int32x4& src1, Uint16x4& result) {\n#if defined(_MSC_VER) && !defined(__clang__) && defined(INTEL_INTRINSICS)\n  __m128i a;\n  memcpy(&a, &src1, 16);\n\n#if defined(__AVX__) || defined(__SSE4_1__)\n  // Packs 4+4 lanes into 8 lanes of uint16. We use 'a' twice.\n  __m128i packed = _mm_packus_epi32(a, a);\n  // Store only the low 64 bits (4x uint16)\n  _mm_storel_epi64(reinterpret_cast<__m128i*>(&result), packed);\n#else\n  // SSE2 Fallback: The Bias Trick\n  const __m128i bias = _mm_set1_epi32(32768);\n  const __m128i bias16 = _mm_set1_epi16(-32768);\n  __m128i biased = _mm_sub_epi32(a, bias);\n  __m128i packed = _mm_packs_epi32(biased, biased);\n  __m128i final = _mm_sub_epi16(packed, bias16);\n  _mm_storel_epi64(reinterpret_cast<__m128i*>(&result), final);\n#endif\n\n#else\n  for (size_t i = 0; i < 4; ++i) {\n    result.set(i, static_cast<uint16_t>(std::min(std::max(src1[i], 0), 65535)));\n  }\n#endif\n}\n\n// Combined horizontal add of 4 Int32x4 vectors into one Int32x4 of sums\n[[maybe_unused]]\nAVS_FORCEINLINE Int32x4 make_from_horiz_sums(\n  const Int32x4& r0, const Int32x4& r1,\n  const Int32x4& r2, const Int32x4& r3) {\n#if defined(_MSC_VER) && !defined(__clang__) && defined(INTEL_INTRINSICS)\n  __m128i a, b, c, d;\n  memcpy(&a, &r0, 16); memcpy(&b, &r1, 16);\n  memcpy(&c, &r2, 16); memcpy(&d, &r3, 16);\n\n  // 1. Interleave to pair up elements (SSE2)\n  __m128i t0 = _mm_unpacklo_epi32(a, b); // [a0, b0, a1, b1]\n  __m128i t1 = _mm_unpackhi_epi32(a, b); // [a2, b2, a3, b3]\n  __m128i t2 = _mm_unpacklo_epi32(c, d); // [c0, d0, c1, d1]\n  __m128i t3 = _mm_unpackhi_epi32(c, d); // [c2, d2, c3, d3]\n\n  // 2. First vertical add (Partial sums)\n  __m128i sum_ab = _mm_add_epi32(t0, t1); // [a0+a2, b0+b2, a1+a3, b1+b3]\n  __m128i sum_cd = _mm_add_epi32(t2, t3); // [c0+c2, d0+d2, c1+c3, d1+d3]\n\n  // 3. Final pairing using 64-bit unpacks (SSE2)\n  __m128i res_lo = _mm_unpacklo_epi64(sum_ab, sum_cd); // [a0+a2, b0+b2, c0+c2, d0+d2]\n  __m128i res_hi = _mm_unpackhi_epi64(sum_ab, sum_cd); // [a1+a3, b1+b3, c1+c3, d1+d3]\n\n  // 4. Final vertical add\n  __m128i res = _mm_add_epi32(res_lo, res_hi); // [sumA, sumB, sumC, sumD]\n\n  Int32x4 out;\n  memcpy(&out, &res, 16);\n  return out;\n#else\n  Int32x4 out;\n  out.set(0, r0.horiz_add_int32());\n  out.set(1, r1.horiz_add_int32());\n  out.set(2, r2.horiz_add_int32());\n  out.set(3, r3.horiz_add_int32());\n  return out;\n#endif\n}\n\n// two 4x int32_t -> 8x uint16_t\n// like an _mm_packus_epi32\n[[maybe_unused]]\nstatic AVS_FORCEINLINE void convert_and_saturate_int32x4x2_to_uint16x8(const Int32x4& src1, const Int32x4& src2, Uint16x8& result) {\n#if defined(_MSC_VER) && !defined(__clang__) && defined(INTEL_INTRINSICS)\n  __m128i a, b;\n  memcpy(&a, &src1, 16);\n  memcpy(&b, &src2, 16);\n  // Though MSVC does not have sse4.1 arch granularity\n#if defined(__AVX__) || defined(__SSE4_1__)\n  // SSE4.1+: direct unsigned pack\n  __m128i packed = _mm_packus_epi32(a, b);\n  memcpy(&result, &packed, 16);\n#else\n  // SSE2 fallback: bias trick\n  // _mm_packs_epi32 does signed saturation, so bias into signed range first\n  // subtract 32768, pack as signed, then the result is offset by 32768\n  const __m128i bias = _mm_set1_epi32(32768);\n  const __m128i bias16 = _mm_set1_epi16(-32768); // same bit pattern, adds back\n  __m128i a_biased = _mm_sub_epi32(a, bias);\n  __m128i b_biased = _mm_sub_epi32(b, bias);\n  __m128i packed = _mm_packs_epi32(a_biased, b_biased); // signed sat to int16\n  __m128i unbiased = _mm_sub_epi16(packed, bias16);       // restore: wraps correctly\n  memcpy(&result, &unbiased, 16);\n#endif\n#else\n  for (size_t i = 0; i < 4; ++i) {\n    result.set(i, static_cast<uint16_t>(std::min(std::max(src1[i], 0), 65535)));\n    result.set(i + 4, static_cast<uint16_t>(std::min(std::max(src2[i], 0), 65535)));\n  }\n#endif\n}\n\n// two 4x int32_t -> 8x uint16_t\n// like a _mm_packus_epi32 followed by a max(x,limit)\n[[maybe_unused]]\nstatic AVS_FORCEINLINE void convert_and_saturate_int32x4x2_to_uint16x8_limit(const Int32x4& src1, const Int32x4& src2, Uint16x8& result, const uint16_t limit) {\n#if defined(_MSC_VER) && !defined(__clang__) && defined(INTEL_INTRINSICS)\n  __m128i a, b;\n  memcpy(&a, &src1, 16);\n  memcpy(&b, &src2, 16);\n#if defined(__AVX__) || defined(__SSE4_1__)\n  __m128i packed = _mm_packus_epi32(a, b);\n  __m128i vlimit = _mm_set1_epi16(static_cast<short>(limit));\n  __m128i clamped = _mm_min_epu16(packed, vlimit);\n  memcpy(&result, &clamped, 16);\n#else\n  // SSE2: same bias trick for pack, then scalar min (limit path is rare/short)\n  const __m128i bias = _mm_set1_epi32(32768);\n  const __m128i bias16 = _mm_set1_epi16(-32768);\n  __m128i a_biased = _mm_sub_epi32(a, bias);\n  __m128i b_biased = _mm_sub_epi32(b, bias);\n  __m128i packed = _mm_packs_epi32(a_biased, b_biased);\n  __m128i unbiased = _mm_sub_epi16(packed, bias16);\n  // SSE2 has no _mm_min_epu16, emulate with signed comparison bias\n  __m128i vlimit = _mm_set1_epi16(static_cast<short>(limit));\n  // unsigned min: a < b unsigned  <=>  (a - 32768) < (b - 32768) signed\n  const __m128i sign_bias = _mm_set1_epi16(-32768);\n  __m128i u_shifted = _mm_add_epi16(unbiased, sign_bias);\n  __m128i l_shifted = _mm_add_epi16(vlimit, sign_bias);\n  __m128i mask = _mm_cmpgt_epi16(u_shifted, l_shifted); // 0xFFFF where unbiased > limit\n  __m128i clamped = _mm_or_si128(_mm_and_si128(mask, vlimit),\n    _mm_andnot_si128(mask, unbiased));\n  memcpy(&result, &clamped, 16);\n#endif\n#else\n  for (size_t i = 0; i < 4; ++i) {\n    result.set(i, static_cast<uint16_t>(std::min(std::max(src1[i], 0), (int)limit)));\n    result.set(i + 4, static_cast<uint16_t>(std::min(std::max(src2[i], 0), (int)limit)));\n  }\n#endif\n}\n\n// two 4x int32_t -> 8x uint8_t\n// like an _mm_packs_epi32 followed by _mm_packus_epi16\n[[maybe_unused]]\nstatic AVS_FORCEINLINE void convert_and_saturate_int32x4x2_to_uint8x8(const Int32x4& src1, const Int32x4& src2, Uint8x8& result) {\n#if defined(_MSC_VER) && !defined(__clang__) && defined(INTEL_INTRINSICS)\n  __m128i a, b;\n  memcpy(&a, &src1, 16);\n  memcpy(&b, &src2, 16);\n  __m128i packed16 = _mm_packs_epi32(a, b);        // [s1_0..s1_3, s2_0..s2_3] as int16 with signed sat\n  __m128i packed8 = _mm_packus_epi16(packed16, packed16); // uint8 with unsigned sat, result in low 8 bytes\n  memcpy(&result, &packed8, 8);                    // movq equivalent\n#else\n  for (size_t i = 0; i < 4; ++i) {\n    result.set(i, static_cast<uint8_t>(std::min(std::max(src1[i], 0), 255)));\n    result.set(i + 4, static_cast<uint8_t>(std::min(std::max(src2[i], 0), 255)));\n  }\n  // This one is optimized with LLVM, but not with gcc or MSVC\n  /* bravo LLVM x86-64 icx 2025.1.0, using return Int32x4\n\n        movdqu  xmm0, xmmword ptr [rdi]\n        packssdw        xmm0, xmm0\n        packuswb        xmm0, xmm0\n        movdqu  xmm1, xmmword ptr [rsi + 16]\n        packssdw        xmm1, xmm1\n        packuswb        xmm1, xmm1\n        movd    eax, xmm0\n        movd    ecx, xmm1\n        shl     rcx, 32\n        or      rax, rcx\n        ret\n    */\n#endif\n}\n\n// int16 * int16->int32 with partial result addition.\n// Simulates the _mm_madd_epi16 x86 SIMD intrinsic function.\n// returns [a0*b0 + a1*b1, a2*b2 + a3*b3, a4*b4 + a5*b5, a6*b6 + a7*b7]\n// When the pre-addition order is not important use the reduce_add version,\n// which may be easier to optimize on non-x86 architectures.\n// (only LLVM was able to optimize the x86 version and compile into real madd)\n[[maybe_unused]]\nstatic AVS_FORCEINLINE Int32x4 simul_madd_epi16(const Int16x8& a, const Int16x8& b) {\n  Int32x4 result;\n\n  // pairwise multiplication and horizontal addition\n  // Yes, I know c++ integer promotion rules, but maybe the compiler\n  // will see our forced static_casting the already short type.\n  // Otherwise, yes, it makes no sense.\n  for (size_t i = 0; i < 4; ++i) {\n    size_t idx = i * 2;\n    int32_t sum =\n      static_cast<short>(a[idx]) * static_cast<short>(b[idx]) +\n      static_cast<short>(a[idx + 1]) * static_cast<short>(b[idx + 1]);\n\n    result.set(i, sum);\n  }\n  return result;\n}\n\n\n// int16 * int16 -> int32 with partial result addition.\n// Unlike the classic x86 SIMD madd_epi16, the sum of multiplications \n// is not horizontally adjacent, instead, the lanes are added together.\n// returns [a0*b0 + a4*b4, a1*b1 + a5*b5, a2*b2 + a6*b6, a3*b3 + a7*b7]\n// However, since the order is not always important, this approach is\n// beneficial for non-x64 processor architectures when the compiler\n// recognizes the widening multiplication pattern.\n[[maybe_unused]]\nstatic AVS_FORCEINLINE Int32x4 mul16x16_reduce_to_Int32x4(const Int16x8 &a, const Int16x8 &b) {\n  Int32x4 result_lo, result_hi;\n\n  for (size_t i = 0; i < 4; ++i) {\n    result_lo.set(i, static_cast<short>(a[i]) * static_cast<short>(b[i]));\n  }\n  for (size_t i = 0; i < 4; ++i) {\n    result_hi.set(i, static_cast<short>(a[i + 4]) * static_cast<short>(b[i + 4]));\n  }\n  Int32x4 result = result_lo + result_hi;\n  return result;\n}\n\n[[maybe_unused]]\nstatic AVS_FORCEINLINE Int32x4 mul16x16_to_Int32x4(const Int16x4& a, const Int16x4& b) {\n  Int32x4 result;\n\n  for (size_t i = 0; i < 4; ++i) {\n    result.set(i, static_cast<short>(a[i]) * static_cast<short>(b[i]));\n  }\n  return result;\n}\n\n#endif  // __AVS_SIMD_C_H__\n"
  },
  {
    "path": "avs_core/core/bitblt.cpp",
    "content": "// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include \"bitblt.h\"\n#include <avs/config.h>\n#include \"memcpy_amd.h\"\n#include <avs/cpuid.h>\n#include <cstring>\n#include <cassert>\n\n#ifdef INTEL_INTRINSICS\n#if defined(X86_32) && defined(MSVC_PURE)\n\n// Assembler bitblit by Steady\nstatic void asm_BitBlt_ISSE(BYTE* dstp, int dst_pitch, const BYTE* srcp, int src_pitch, int row_size, int height) {\n\n  // Warning! : If you modify this routine, check the generated assembler to make sure\n  //            the stupid compiler is saving the ebx register in the entry prologue.\n  //            And don't just add an extra push/pop ebx pair around the code, try to\n  //            convince the compiler to do the right thing, it's not hard, usually a\n  //            slight shuffle or a well placed \"__asm mov ebx,ebx\" does the trick.\n\n  if(row_size==0 || height==0) return; //abort on goofs\n  //move backwards for easier looping and to disable hardware prefetch\n  const BYTE* srcStart=srcp+src_pitch*(height-1);\n  BYTE* dstStart=dstp+dst_pitch*(height-1);\n\n  if(row_size < 64) {\n    _asm {\n      mov   esi,srcStart  //move rows from bottom up\n      mov   edi,dstStart\n      mov   edx,row_size\n      dec   edx\n      mov   ebx,height\n      align 16\nmemoptS_rowloop:\n      mov   ecx,edx\n//      rep movsb\nmemoptS_byteloop:\n      mov   AL,[esi+ecx]\n      mov   [edi+ecx],AL\n      sub   ecx,1\n      jnc   memoptS_byteloop\n      sub   esi,src_pitch\n      sub   edi,dst_pitch\n      dec   ebx\n      jne   memoptS_rowloop\n    };\n    return;\n  }//end small version\n\n  else if( (int(dstp) | row_size | src_pitch | dst_pitch) & 7) {//not QW aligned\n    //unaligned version makes no assumptions on alignment\n\n    _asm {\n//****** initialize\n      mov   esi,srcStart  //bottom row\n      mov   AL,[esi]\n      mov   edi,dstStart\n      mov   edx,row_size\n      mov   ebx,height\n\n//********** loop starts here ***********\n\n      align 16\nmemoptU_rowloop:\n      mov   ecx,edx     //row_size\n      dec   ecx         //offset to last byte in row\n      add   ecx,esi     //ecx= ptr last byte in row\n      and   ecx,~63     //align to first byte in cache line\nmemoptU_prefetchloop:\n      mov   AX,[ecx]    //tried AL,AX,EAX, AX a tiny bit faster\n      sub   ecx,64\n      cmp   ecx,esi\n      jae   memoptU_prefetchloop\n\n//************ write *************\n\n      movq    mm6,[esi]     //move the first unaligned bytes\n      movntq  [edi],mm6\n//************************\n      mov   eax,edi\n      neg   eax\n      mov   ecx,eax\n      and   eax,63      //eax=bytes from [edi] to start of next 64 byte cache line\n      and   ecx,7       //ecx=bytes from [edi] to next QW\n      align 16\nmemoptU_prewrite8loop:        //write out odd QW's so 64 bit write is cache line aligned\n      cmp   ecx,eax           //start of cache line ?\n      jz    memoptU_pre8done  //if not, write single QW\n      movq    mm7,[esi+ecx]\n      movntq  [edi+ecx],mm7\n      add   ecx,8\n      jmp   memoptU_prewrite8loop\n\n      align 16\nmemoptU_write64loop:\n      movntq  [edi+ecx-64],mm0\n      movntq  [edi+ecx-56],mm1\n      movntq  [edi+ecx-48],mm2\n      movntq  [edi+ecx-40],mm3\n      movntq  [edi+ecx-32],mm4\n      movntq  [edi+ecx-24],mm5\n      movntq  [edi+ecx-16],mm6\n      movntq  [edi+ecx- 8],mm7\nmemoptU_pre8done:\n      add   ecx,64\n      cmp   ecx,edx         //while(offset <= row_size) do {...\n      ja    memoptU_done64\n      movq    mm0,[esi+ecx-64]\n      movq    mm1,[esi+ecx-56]\n      movq    mm2,[esi+ecx-48]\n      movq    mm3,[esi+ecx-40]\n      movq    mm4,[esi+ecx-32]\n      movq    mm5,[esi+ecx-24]\n      movq    mm6,[esi+ecx-16]\n      movq    mm7,[esi+ecx- 8]\n      jmp   memoptU_write64loop\nmemoptU_done64:\n\n      sub     ecx,64    //went to far\n      align 16\nmemoptU_write8loop:\n      add     ecx,8           //next QW\n      cmp     ecx,edx         //any QW's left in row ?\n      ja      memoptU_done8\n      movq    mm0,[esi+ecx-8]\n      movntq  [edi+ecx-8],mm0\n      jmp   memoptU_write8loop\nmemoptU_done8:\n\n      movq    mm1,[esi+edx-8] //write the last unaligned bytes\n      movntq  [edi+edx-8],mm1\n      sub   esi,src_pitch\n      sub   edi,dst_pitch\n      dec   ebx               //row counter (=height at start)\n      jne   memoptU_rowloop\n\n      sfence\n      emms\n    };\n    return;\n  }//end unaligned version\n\n  else {//QW aligned version (fastest)\n  //else dstp and row_size QW aligned - hope for the best from srcp\n  //QW aligned version should generally be true when copying full rows\n    _asm {\n      mov   esi,srcStart  //start of bottom row\n      mov   edi,dstStart\n      mov   ebx,height\n      mov   edx,row_size\n      align 16\nmemoptA_rowloop:\n      mov   ecx,edx //row_size\n      dec   ecx     //offset to last byte in row\n\n//********forward routine\n      add   ecx,esi\n      and   ecx,~63   //align prefetch to first byte in cache line(~3-4% faster)\n      align 16\nmemoptA_prefetchloop:\n      mov   AX,[ecx]\n      sub   ecx,64\n      cmp   ecx,esi\n      jae   memoptA_prefetchloop\n\n      mov   eax,edi\n      xor   ecx,ecx\n      neg   eax\n      and   eax,63            //eax=bytes from edi to start of cache line\n      align 16\nmemoptA_prewrite8loop:        //write out odd QW's so 64bit write is cache line aligned\n      cmp   ecx,eax           //start of cache line ?\n      jz    memoptA_pre8done  //if not, write single QW\n      movq    mm7,[esi+ecx]\n      movntq  [edi+ecx],mm7\n      add   ecx,8\n      jmp   memoptA_prewrite8loop\n\n      align 16\nmemoptA_write64loop:\n      movntq  [edi+ecx-64],mm0\n      movntq  [edi+ecx-56],mm1\n      movntq  [edi+ecx-48],mm2\n      movntq  [edi+ecx-40],mm3\n      movntq  [edi+ecx-32],mm4\n      movntq  [edi+ecx-24],mm5\n      movntq  [edi+ecx-16],mm6\n      movntq  [edi+ecx- 8],mm7\nmemoptA_pre8done:\n      add   ecx,64\n      cmp   ecx,edx\n      ja    memoptA_done64    //less than 64 bytes left\n      movq    mm0,[esi+ecx-64]\n      movq    mm1,[esi+ecx-56]\n      movq    mm2,[esi+ecx-48]\n      movq    mm3,[esi+ecx-40]\n      movq    mm4,[esi+ecx-32]\n      movq    mm5,[esi+ecx-24]\n      movq    mm6,[esi+ecx-16]\n      movq    mm7,[esi+ecx- 8]\n      jmp   memoptA_write64loop\n\nmemoptA_done64:\n      sub   ecx,64\n\n      align 16\nmemoptA_write8loop:           //less than 8 QW's left\n      add   ecx,8\n      cmp   ecx,edx\n      ja    memoptA_done8     //no QW's left\n      movq    mm7,[esi+ecx-8]\n      movntq  [edi+ecx-8],mm7\n      jmp   memoptA_write8loop\n\nmemoptA_done8:\n      sub   esi,src_pitch\n      sub   edi,dst_pitch\n      dec   ebx               //row counter (height)\n      jne   memoptA_rowloop\n\n      sfence\n      emms\n    };\n    return;\n  }//end aligned version\n}//end BitBlt_memopt()\n\n#endif //X86_32\n#endif // INTEL_INTRINSICS\n\nvoid BitBlt(BYTE* dstp, int dst_pitch, const BYTE* srcp, int src_pitch, int row_size, int height)\n{\n  if ( (!height) || (!row_size) ) return;\n\n#ifdef INTEL_INTRINSICS\n#if defined(X86_32) && defined(MSVC_PURE)\n  const int cpuf = GetCPUFlags();\n  if ((cpuf & CPUF_INTEGER_SSE) && !(cpuf & CPUF_AVX))\n  {\n    if (height == 1 || (src_pitch == dst_pitch && dst_pitch == row_size)) {\n      memcpy_amd(dstp, srcp, row_size*height);\n    } else {\n      asm_BitBlt_ISSE(dstp,dst_pitch,srcp,src_pitch,row_size,height);\n    }\n    return;\n  }\n#endif\n#endif // INTEL_INTRINSICS\n\n  if (height == 1 || (dst_pitch == src_pitch && src_pitch == row_size)) {\n    memcpy(dstp, srcp, row_size*height);\n  } else {\n    for (int y = height; y > 0; --y) {\n      memcpy(dstp, srcp, row_size);\n      dstp += dst_pitch;\n      srcp += src_pitch;\n    }\n  }\n}\n"
  },
  {
    "path": "avs_core/core/bitblt.h",
    "content": "// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef AVSCORE_BITBLT_H\n#define AVSCORE_BITBLT_H\n\ntypedef unsigned char BYTE;\n\nvoid BitBlt(BYTE* dstp, int dst_pitch, const BYTE* srcp, int src_pitch, int row_size, int height);\n\n#endif // AVSCORE_BITBLT_H\n"
  },
  {
    "path": "avs_core/core/cache.cpp",
    "content": "// Avisynth v2.6.  Copyright 2002-2009 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include \"cache.h\"\n#include \"internal.h\"\n#include \"LruCache.h\"\n#include \"InternalEnvironment.h\"\n#include \"DeviceManager.h\"\n#include <cassert>\n#include <chrono>\n#include <cstdio>\n\n#ifdef X86_32\n#include <mmintrin.h>\n#endif\n\n#include <avs/config.h>\n#ifdef AVS_WINDOWS\n#include <avs/win.h>\n#else\n#include <avs/posix.h>\n#endif\n\n\nextern const AVSFunction Cache_filters[] = {\n  { \"Cache\", BUILTIN_FUNC_PREFIX, \"c[name]s\", CacheGuard::Create },\n  { \"InternalCache\", BUILTIN_FUNC_PREFIX, \"c[name]s\", CacheGuard::Create },\n  { 0 }\n};\n\nclass CacheStack\n{\n  InternalEnvironment* env;\n  bool retSupressCaching;\npublic:\n  CacheStack(InternalEnvironment* env)\n    : env(env)\n    , retSupressCaching(env->GetSupressCaching())\n  { }\n  ~CacheStack() {\n    env->GetSupressCaching() = retSupressCaching;\n  }\n};\n\nstruct CachePimpl\n{\n  PClip child;\n  VideoInfo vi;\n\n  // Video cache\n  std::shared_ptr<LruCache<size_t, PVideoFrame> > VideoCache;\n\n  // Audio cache\n  CachePolicyHint AudioPolicy;\n  char* AudioCache;\n  int SampleSize;\n  int64_t MaxSampleCount;\n  int64_t AudioCacheStart;\n  int64_t CacheCount;\n  int64_t ac_expected_next;\n  int ac_too_small_count;\n  long ac_currentscore;\n\n  CachePimpl(const PClip& _child, CacheMode mode) :\n    child(_child),\n    vi(_child->GetVideoInfo()),\n    VideoCache(std::make_shared<LruCache<size_t, PVideoFrame> >(0, mode)),\n    AudioPolicy(vi.HasAudio() ? CACHE_AUDIO_AUTO_START_OFF : CACHE_AUDIO_NOTHING),  // Don't cache audio per default, auto mode.\n    AudioCache(NULL),\n    SampleSize(0),\n    MaxSampleCount(0),\n    AudioCacheStart(0),\n    CacheCount(0),\n    ac_expected_next(0),\n    ac_too_small_count(0),\n    ac_currentscore(20)\n  {\n    SampleSize = vi.BytesPerAudioSample();\n  }\n  ~CachePimpl()\n  {\n    if (AudioCache)\n      free(AudioCache);\n    AudioCache = NULL;\n  }\n};\n\n\nAvsCache::AvsCache(const PClip& _child, Device* device, std::mutex& CacheGuardMutex, InternalEnvironment* env) :\n  Env(env),\n  _pimpl(NULL),\n  device(device),\n  CacheGuardMutex(CacheGuardMutex)\n{\n  _pimpl = new CachePimpl(_child, env->GetCacheMode());\n  env->ManageCache(MC_RegisterCache, reinterpret_cast<void*>(this));\n  _RPT5(0, \"AvsCache::AvsCache registered. cache_id=%p child=%p w=%d h=%d VideoCacheSize=%Iu\\n\", (void*)this, (void*)_child, _pimpl->vi.width, _pimpl->vi.height, _pimpl->VideoCache->size());\n\n  const int dummy = 0;\n  // child is usually MTGuard, which forwards this request to its child filter - the real one\n  const bool overAvs25 = (_child->GetVersion() >= 5);\n  CachePolicyHint childAudioPolicy = (CachePolicyHint)(overAvs25 ? _child->SetCacheHints(CACHE_GETCHILD_AUDIO_MODE, dummy) : 0);\n  // if not set by the plugin, get default (set in CachePimpl ctor)\n  if (childAudioPolicy == 0)\n    childAudioPolicy = (CachePolicyHint)this->SetCacheHints(CACHE_GET_AUDIO_POLICY, dummy);\n  switch (childAudioPolicy) {\n  case CachePolicyHint(0): break; // n/a\n  case CACHE_AUDIO:          // Explicitly do cache audio, X byte cache.\n  case CACHE_AUDIO_NOTHING:  // Explicitly do not cache audio.\n  case CACHE_AUDIO_AUTO_START_OFF: // Audio cache off (auto mode), X byte initial cache.\n  case CACHE_AUDIO_AUTO_START_ON:  // Audio cache on (auto mode), X byte initial cache.\n    // ask child for desired audio cache size\n    // e.g. EnsureVBRMP3Sync explicitely requests CACHE_AUDIO and 1024*1024\n    // This will create cache only if clip has audio\n    this->SetCacheHints(childAudioPolicy, overAvs25 ? _child->SetCacheHints(CACHE_GETCHILD_AUDIO_SIZE, dummy) : 0); // if size=0 remains the default\n    break;\n  default:\n    env->ThrowError(\"Cache: Filter returned invalid response to CACHE_GETCHILD_AUDIO_MODE. %d\", childAudioPolicy);\n  }\n}\n\nAvsCache::~AvsCache()\n{\n  _RPT5(0, \"AvsCache::AvsCache unregister. cache_id=%p child=%p w=%d h=%d VideoCacheSize=%Iu\\n\", (void *)this, (void *)_pimpl->child, _pimpl->vi.width, _pimpl->vi.height, _pimpl->VideoCache->size()); // P.F.\n  Env->ManageCache(MC_UnRegisterCache, reinterpret_cast<void*>(this));\n  delete _pimpl;\n}\n\nPVideoFrame __stdcall AvsCache::GetFrame(int n, IScriptEnvironment* env_)\n{\n#ifdef _DEBUG\n  constexpr auto BUFSIZE = 255;\n  std::unique_ptr<char[]> buf(new char[BUFSIZE+1]);\n\n#endif\n  InternalEnvironment* env = GetAndRevealCamouflagedEnv(env_);\n\n  // Protect plugins that cannot handle out-of-bounds frame indices\n  n = clamp(n, 0, GetVideoInfo().num_frames-1);\n\n  if (_pimpl->VideoCache->requested_capacity() > _pimpl->VideoCache->capacity())\n    env->ManageCache(MC_NodAndExpandCache, reinterpret_cast<void*>(this));\n  else\n    env->ManageCache(MC_NodCache, reinterpret_cast<void*>(this));\n\n  PVideoFrame result;\n  LruCache<size_t, PVideoFrame>::handle cache_handle;\n\n  CacheStack cache_stack(env);\n\n#ifdef _DEBUG\n  std::chrono::time_point<std::chrono::high_resolution_clock> t_start, t_end;\n  t_start = std::chrono::high_resolution_clock::now(); // t_start starts in the constructor. Used in logging\n\n  LruLookupResult LruLookupRes = _pimpl->VideoCache->lookup(n, &cache_handle, true, result, &env->GetSupressCaching());\n  /*\n  std::string name = FuncName;\n  snprintf(buf.get(), BUFSIZE, \"AvsCache::GetFrame lookup follows: [%s] n=%6d Thread=%zu\", name.c_str(), n, env->GetEnvProperty(AEP_THREAD_ID));\n  _RPT0(0, buf.get());\n\n  snprintf(buf.get(), BUFSIZE, \"AvsCache::GetFrame lookup ready: [%s] n=%6d Thread=%zu res=%d\", name.c_str(), n, env->GetEnvProperty(AEP_THREAD_ID), (int)LruLookupRes);\n  _RPT0(0, buf.get());\n  */\n\n#ifdef _DEBUG\n  std::string name = FuncName;\n#endif\n\n  switch (LruLookupRes)\n#else\n  // fill result in lookup before releasing cache handle lock\n  switch(_pimpl->VideoCache->lookup(n, &cache_handle, true, result, &env->GetSupressCaching()))\n#endif\n  {\n  case LRU_LOOKUP_NOT_FOUND:\n    {\n      try\n      {\n#ifdef _DEBUG\n        snprintf(buf.get(), BUFSIZE, \"AvsCache::GetFrame LRU_LOOKUP_NOT_FOUND Start: [%s] n=%6d child=%p\\n\", name.c_str(), n, (void*)_pimpl->child); // P.F.\n        _RPT0(0, buf.get());\n#endif\n        //cache_handle.first->value = _pimpl->child->GetFrame(n, env);\n        result = _pimpl->child->GetFrame(n, env); // P.F. fill result immediately\n\n        // check device\n        if (result->GetFrameBuffer()->device != device) {\n            const char* error_msg = env->Sprintf(\"Frame device mismatch: Assumed: %s Actual: %s\",\n                device->GetName(), result->GetFrameBuffer()->device->GetName());\n            result = env->NewVideoFrame(_pimpl->vi);\n            env->ApplyMessage(&result, _pimpl->vi, error_msg, _pimpl->vi.width / 5, 0xa0a0a0, 0, 0);\n        }\n\n        cache_handle.first->value = result; // not after commit!\n  #ifdef X86_32\n        _mm_empty();\n  #endif\n        _pimpl->VideoCache->commit_value(&cache_handle);\n      }\n      catch (...)\n      {\n        _pimpl->VideoCache->rollback(&cache_handle);\n        throw;\n      }\n#ifdef _DEBUG\n      t_end = std::chrono::high_resolution_clock::now();\n      std::chrono::duration<double> elapsed_seconds = t_end - t_start;\n      std::string name = FuncName;\n      if (NULL == cache_handle.first->value) {\n          snprintf(buf.get(), BUFSIZE, \"AvsCache::GetFrame LRU_LOOKUP_NOT_FOUND   End: HEY! got nulled! [%s] n=%6d child=%p frame=%p framebefore=%p SeekTimeWithGetFrame:%f\\n\", name.c_str(), n, (void *)_pimpl->child, (void *)cache_handle.first->value, (void *)result, elapsed_seconds.count()); // P.F.\n          _RPT0(0, buf.get());\n      } else {\n          snprintf(buf.get(), BUFSIZE, \"AvsCache::GetFrame LRU_LOOKUP_NOT_FOUND   End: [%s] n=%6d child=%p frame=%p framebefore=%p videoCacheSize=%zu SeekTimeWithGetFrame:%f\\n\", name.c_str(), n, (void *)_pimpl->child, (void *)cache_handle.first->value, (void *)result, _pimpl->VideoCache->size(), elapsed_seconds.count()); // P.F.\n          _RPT0(0, buf.get());\n      }\n#endif\n      // result = cache_handle.first->value; not here!\n      // its content may change after commit when the last lock is released\n      // (cache is being restructured by other threads, new frames, etc...)\n      break;\n    }\n  case LRU_LOOKUP_FOUND_AND_READY:\n    {\n      // theoretically cache_handle here may point to wrong entry,\n      // because the lock in lookup is released before this readout\n      // solution:\n      // when LRU_LOOKUP_FOUND_AND_READY, the cache_handle.first->value is copied and returned in result itself\n      // result =  cache_handle.first->value; // old method not needed, result is filled already by lookup\n#ifdef _DEBUG\n      t_end = std::chrono::high_resolution_clock::now();\n      std::chrono::duration<double> elapsed_seconds = t_end - t_start;\n      std::string name = FuncName;\n      snprintf(buf.get(), BUFSIZE, \"AvsCache::GetFrame LRU_LOOKUP_FOUND_AND_READY: [%s] n=%6d child=%p frame=%p vfb=%p videoCacheSize=%zu SeekTime            :%f\\n\", name.c_str(), n, (void *)_pimpl->child, (void *)result, (void *)result->GetFrameBuffer(), _pimpl->VideoCache->size(), elapsed_seconds.count());\n      _RPT0(0, buf.get());\n      assert(result != NULL);\n#endif\n      break;\n    }\n  case LRU_LOOKUP_NO_CACHE:\n    {\n#ifdef _DEBUG\n    snprintf(buf.get(), BUFSIZE, \"AvsCache::GetFrame <Before GetFrame> LRU_LOOKUP_NO_CACHE: [%s] n=%6d child=%p\\n\", name.c_str(), n, (void*)_pimpl->child); // P.F.\n    _RPT0(0, buf.get());\n#endif\n    result = _pimpl->child->GetFrame(n, env);\n#ifdef _DEBUG\n      t_end = std::chrono::high_resolution_clock::now();\n      std::chrono::duration<double> elapsed_seconds = t_end - t_start;\n      snprintf(buf.get(), BUFSIZE, \"AvsCache::GetFrame <After GetFrame> LRU_LOOKUP_NO_CACHE: [%s] n=%6d child=%p frame=%p vfb=%p videoCacheSize=%zu SeekTime            :%f\\n\", name.c_str(), n, (void *)_pimpl->child, (void *)result, (void *)result->GetFrameBuffer(), _pimpl->VideoCache->size(), elapsed_seconds.count()); // P.F.\n      _RPT0(0, buf.get());\n#endif\n      break;\n    }\n  case LRU_LOOKUP_FOUND_BUT_NOTAVAIL:    // Fall-through intentional\n  default:\n    {\n      assert(0);\n      break;\n    }\n  }\n\n  return result;\n}\n\nvoid AvsCache::FillAudioZeros(void* buf, size_t start_offset, size_t count) {\n    const int bps = _pimpl->vi.BytesPerAudioSample();\n    unsigned char* byte_buf = (unsigned char*)buf;\n    memset(byte_buf + start_offset * bps, 0, count * bps);\n}\n\nvoid __stdcall AvsCache::GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env)\n{\n  if (count <= 0)\n    return;\n  if (count > 0 && static_cast<uint64_t>(count) > std::numeric_limits<size_t>::max())\n    env->ThrowError(\"GetAudio error: Count exceeds platform maximum buffer size limit.\");\n\n  // -----------------------------------------------------------\n  //          Enforce audio bounds\n  // -----------------------------------------------------------\n\n  VideoInfo * vi = &(_pimpl->vi);\n\n  if ((!vi->HasAudio()) || (start + count <= 0) || (start >= vi->num_audio_samples)) {\n    // Completely skip.\n    FillAudioZeros(buf, 0, (size_t)count);\n    count = 0;\n    return;\n  }\n\n  if (start < 0) {  // Partial initial skip\n    FillAudioZeros(buf, 0, static_cast<size_t>(-start));  // Fill all samples before 0 with silence.\n    count += start;  // Subtract start bytes from count.\n    buf = ((BYTE*)buf) - start * vi->BytesPerAudioSample();\n    start = 0;\n  }\n\n  if (start + count > vi->num_audio_samples) {  // Partial ending skip\n    FillAudioZeros(buf, (size_t)(vi->num_audio_samples - start), (size_t)(count - (vi->num_audio_samples - start)));  // Fill end samples\n    count = (vi->num_audio_samples - start);\n  }\n\n  // -----------------------------------------------------------\n  //          Caching\n  // -----------------------------------------------------------\n\n  long _cs = _pimpl->ac_currentscore;\n  if (start < _pimpl->ac_expected_next)\n    _cs = InterlockedExchangeAdd(&_pimpl->ac_currentscore, -5) - 5;  // revisiting old ground - a cache could help\n  else if (start > _pimpl->ac_expected_next)\n    _cs = InterlockedDecrement(&_pimpl->ac_currentscore);            // skipping chunks - a cache might not help\n  else // (start == ac_expected_next)\n    _cs = InterlockedIncrement(&_pimpl->ac_currentscore);            // strict linear reading - why bother with a cache\n\n  if (_cs < -2000000)\n    _pimpl->ac_currentscore = -2000000;\n  else if (_cs > 90)\n    _pimpl->ac_currentscore = 90;\n\n  // Change from AUTO_OFF to AUTO_ON\n  if (_pimpl->AudioPolicy == CACHE_AUDIO_AUTO_START_OFF && _pimpl->ac_currentscore <= 0) {\n    // align size to 8192 byte boundary\n    int64_t new_size = (_pimpl->vi.BytesFromAudioSamples(count) + 8191) & -8192;\n    new_size = min((int64_t)4096 * 1024, new_size);\n    _RPT2(0, \"CA:%x: Automatically adding %d byte audiocache!\\n\", this, (int)new_size);\n    SetCacheHints(CACHE_AUDIO_AUTO_START_ON, (int)new_size);\n  }\n\n  // Change from AUTO_ON to AUTO_OFF\n  if (_pimpl->AudioPolicy == CACHE_AUDIO_AUTO_START_ON && (_pimpl->ac_currentscore > 80)) {\n    _RPT1(0, \"CA:%x: Automatically deleting cache!\\n\", this);\n    SetCacheHints(CACHE_AUDIO_AUTO_START_OFF, 0);\n  }\n\n  _pimpl->ac_expected_next = start + count;\n\n  if (_pimpl->AudioPolicy == CACHE_AUDIO_AUTO_START_OFF || _pimpl->AudioPolicy == CACHE_AUDIO_NOTHING) {\n    _pimpl->child->GetAudio(buf, start, count, env);\n    return;  // We are ok to return now!\n  }\n\n  std::unique_lock<std::mutex> global_lock(CacheGuardMutex);\n\n  while (count > _pimpl->MaxSampleCount) {    //is cache big enough?\n    _RPT1(0, \"CA:%x:Cache too small->caching last audio\\n\", this);\n    _pimpl->ac_too_small_count++;\n\n    // But the current cache might have 99% of what was requested??\n\n    if (_pimpl->ac_too_small_count > 2 && _pimpl->MaxSampleCount < _pimpl->vi.AudioSamplesFromBytes(8192 * 1024)) {  // Max size = 8MB!\n      //automatically upsize cache!\n      int64_t new_size = (_pimpl->vi.BytesFromAudioSamples(std::max(count, _pimpl->AudioCacheStart + _pimpl->CacheCount - start)) + 8192) & -8192; // Yes +1 to +8192 bytes\n      new_size = std::min((int64_t)8192 * 1024, new_size);\n      _RPT2(0, \"CA:%x: Autoupsizing buffer to %d bytes!\\n\", this, (int)new_size);\n      SetCacheHints(_pimpl->AudioPolicy, (int)new_size); // updates maxsamplecount!!\n      _pimpl->ac_too_small_count = 0;\n    }\n    else {\n      global_lock.unlock();\n      _pimpl->child->GetAudio(buf, start, count, env);\n      global_lock.lock();\n\n      _pimpl->CacheCount = std::min(count, _pimpl->MaxSampleCount); // Remember maxsamplecount gets updated\n      _pimpl->AudioCacheStart = start + count - _pimpl->CacheCount;\n      BYTE* buff = (BYTE*)buf;\n      buff += _pimpl->vi.BytesFromAudioSamples(_pimpl->AudioCacheStart - start);\n      memcpy(_pimpl->AudioCache, buff, (size_t)_pimpl->vi.BytesFromAudioSamples(_pimpl->CacheCount));\n\n      global_lock.unlock();\n\n      return;\n    }\n  }\n\n  if ((start < _pimpl->AudioCacheStart) || (start > _pimpl->AudioCacheStart + _pimpl->MaxSampleCount)) { //first sample is before cache or beyond linear reach -> restart cache\n    _RPT1(0, \"CA:%x: Restart\\n\", this);\n\n    _pimpl->CacheCount = std::min(count, _pimpl->MaxSampleCount);\n    _pimpl->AudioCacheStart = start;\n    _pimpl->child->GetAudio(_pimpl->AudioCache, _pimpl->AudioCacheStart, _pimpl->CacheCount, env);\n  }\n  else {\n    if (start + count > _pimpl->AudioCacheStart + _pimpl->CacheCount) { // Does the cache fail to cover the request?\n      if (start + count > _pimpl->AudioCacheStart + _pimpl->MaxSampleCount) {  // Is cache shifting necessary?\n        int shiftsamples = (int)((start + count) - (_pimpl->AudioCacheStart + _pimpl->MaxSampleCount)); // Align end of cache with end of request\n\n        if ((start - _pimpl->AudioCacheStart) / 2 > shiftsamples) {  //shift half cache if possible\n          shiftsamples = (int)((start - _pimpl->AudioCacheStart) / 2);\n        }\n        if (shiftsamples >= (int)_pimpl->CacheCount) { // Can we save any existing data\n          _pimpl->AudioCacheStart = start + count - _pimpl->MaxSampleCount; // Maximise linear access\n          _pimpl->CacheCount = 0;\n        }\n        else {\n          memmove(_pimpl->AudioCache, _pimpl->AudioCache + shiftsamples * _pimpl->SampleSize, (size_t)((_pimpl->CacheCount - shiftsamples) * _pimpl->SampleSize));\n          _pimpl->AudioCacheStart = _pimpl->AudioCacheStart + shiftsamples;\n          _pimpl->CacheCount = _pimpl->CacheCount - shiftsamples;\n        }\n      }\n      // Read just enough to complete the current request, append it to the cache\n      _pimpl->child->GetAudio(_pimpl->AudioCache + _pimpl->CacheCount * _pimpl->SampleSize, _pimpl->AudioCacheStart + _pimpl->CacheCount, start + count - (_pimpl->AudioCacheStart + _pimpl->CacheCount), env);\n      _pimpl->CacheCount += (size_t)(start + count - (_pimpl->AudioCacheStart + _pimpl->CacheCount));\n    }\n  }\n\n  //copy cache to buf\n  memcpy(buf, _pimpl->AudioCache + (size_t)(start - _pimpl->AudioCacheStart) * _pimpl->SampleSize, (size_t)(count * _pimpl->SampleSize));\n\n}\n\nconst VideoInfo& __stdcall AvsCache::GetVideoInfo()\n{\n  return _pimpl->vi;\n}\n\nbool __stdcall AvsCache::GetParity(int n)\n{\n  return _pimpl->child->GetParity(n);\n}\n\nint __stdcall AvsCache::SetCacheHints(int cachehints, int frame_range)\n{\n  // _RPT3(0, \"AvsCache::SetCacheHints called. cache=%p hint=%d frame_range=%d\\n\", (void *)this, cachehints, frame_range);\n  switch(cachehints)\n  {\n    /*********************************************\n        MISC\n    *********************************************/\n\n    // By returning IS_CACHE_ANS to IS_CACHE_REQ, we tell the caller we are a cache\n    case CACHE_IS_CACHE_REQ:\n      return CACHE_IS_CACHE_ANS;\n\n    case CACHE_GET_POLICY: // Get the current policy.\n      return CACHE_GENERIC;\n\n    case CACHE_DONT_CACHE_ME:\n      return 1;\n\n    case CACHE_GET_MTMODE:\n      return MT_NICE_FILTER;\n\n    /*********************************************\n        VIDEO\n    *********************************************/\n\n    case CACHE_SET_MIN_CAPACITY:\n    { // This is not atomic, but frankly, we don't care\n      size_t min, max;\n      _pimpl->VideoCache->limits(&min, &max);\n      min = frame_range;\n      _pimpl->VideoCache->set_limits(min, max);\n      break;\n    }\n\n    case CACHE_SET_MAX_CAPACITY:\n    { // This is not atomic, but frankly, we don't care\n      size_t min, max;\n      _pimpl->VideoCache->limits(&min, &max);\n      max = frame_range;\n      _pimpl->VideoCache->set_limits(min, max);\n      _RPT3(0, \"AvsCache::SetCacheHints CACHE_SET_MAX_CAPACITY cache=%p hint=%d frame_range=%d\\n\", (void *)this, cachehints, frame_range);\n      break;\n    }\n\n    case CACHE_GET_MIN_CAPACITY:\n    {\n      size_t min, max;\n      _pimpl->VideoCache->limits(&min, &max);\n      return (int)min;\n    }\n\n    case CACHE_GET_MAX_CAPACITY:\n    {\n      size_t min, max;\n      _pimpl->VideoCache->limits(&min, &max);\n      return (int)max;\n    }\n\n    case CACHE_GET_SIZE:\n      return (int)_pimpl->VideoCache->size();\n\n    case CACHE_GET_REQUESTED_CAP:\n      return (int)_pimpl->VideoCache->requested_capacity();\n\n    case CACHE_GET_CAPACITY:\n      return (int)_pimpl->VideoCache->capacity();\n\n    case CACHE_GET_WINDOW: // Get the current window h_span.\n    case CACHE_GET_RANGE: // Get the current generic frame range.\n      return 2;\n      break;\n\n    case CACHE_GENERIC:\n    case CACHE_FORCE_GENERIC:\n    case CACHE_NOTHING:\n    case CACHE_WINDOW:\n    case CACHE_PREFETCH_FRAME:          // Queue request to prefetch frame N.\n    case CACHE_PREFETCH_GO:             // Action video prefetches.\n      break;\n\n    /*********************************************\n        AUDIO\n    *********************************************/\n\n    case CACHE_AUDIO:\n    case CACHE_AUDIO_AUTO_START_ON:\n      if (!_pimpl->vi.HasAudio())\n        break;\n\n      // Range means for audio.\n      // 0 == Create a default buffer (256kb).\n      // Positive. Allocate X bytes for cache.\n      if (frame_range == 0) {\n        if (_pimpl->AudioPolicy != CACHE_AUDIO_AUTO_START_OFF)   // We already have a policy - no need for a default one.\n          break;\n\n        frame_range = 256 * 1024;\n      }\n\n      if (frame_range/_pimpl->SampleSize > _pimpl->MaxSampleCount) { // Only make bigger\n        const bool audio_cache_existed = _pimpl->AudioCache != nullptr;\n        // keep content, newly added bytes are undefined on increase\n        // but CacheCount keeps track on that fact\n        char * NewAudioCache = (char*)realloc(_pimpl->AudioCache, frame_range);\n        if (NewAudioCache == NULL)\n        {\n          throw std::bad_alloc();\n        }\n        _pimpl->AudioCache = NewAudioCache;\n\n        _pimpl->MaxSampleCount = frame_range/_pimpl->SampleSize;\n        if(audio_cache_existed)\n          _pimpl->CacheCount = std::min(_pimpl->CacheCount, _pimpl->MaxSampleCount);\n        else {\n          _pimpl->AudioCacheStart = 0;\n          _pimpl->CacheCount = 0;\n        }\n      }\n\n      _pimpl->AudioPolicy = (CachePolicyHint)cachehints;\n      break;\n\n    case CACHE_AUDIO_AUTO_START_OFF:\n    case CACHE_AUDIO_NOTHING:\n      free(_pimpl->AudioCache);\n      _pimpl->AudioCache = NULL;\n      _pimpl->MaxSampleCount = 0;\n      _pimpl->AudioCacheStart = 0;\n      _pimpl->CacheCount = 0;\n      _pimpl->AudioPolicy = (CachePolicyHint)cachehints;\n      break;\n\n    case CACHE_GET_AUDIO_POLICY: // Get the current audio policy.\n      return _pimpl->AudioPolicy;\n\n    case CACHE_GET_AUDIO_SIZE: // Get the current audio cache size.\n      return (int)(_pimpl->SampleSize * _pimpl->MaxSampleCount);\n\n    // n/a ignore them, not implemented even in 2.6\n    case CACHE_PREFETCH_AUDIO_BEGIN:    // Begin queue request to prefetch audio (take critical section).\n    case CACHE_PREFETCH_AUDIO_STARTLO:  // Set low 32 bits of start.\n    case CACHE_PREFETCH_AUDIO_STARTHI:  // Set high 32 bits of start.\n    case CACHE_PREFETCH_AUDIO_COUNT:    // Set low 32 bits of length.\n    case CACHE_PREFETCH_AUDIO_COMMIT:   // Enqueue request transaction to prefetch audio (release critical section).\n    case CACHE_PREFETCH_AUDIO_GO:       // Action audio prefetch\n      break;\n\n    default:\n      return 0;\n  }\n\n  return 0;\n}\n\nCacheGuard::CacheGuard(const PClip& child, const char *name, IScriptEnvironment* env) :\n    child(child),\n    vi(child->GetVideoInfo()),\n    globalEnv(env)\n{\n  if (name)\n    this->name = name;\n\n  // other fields are set OK already\n  hints.AudioPolicy = vi.HasAudio() ? CACHE_AUDIO_AUTO_START_OFF : CACHE_AUDIO_NOTHING;\n  hints.default_AudioPolicy = hints.AudioPolicy;\n\n}\n\nCacheGuard::~CacheGuard()\n{ }\n\nPClip CacheGuard::GetCache(IScriptEnvironment* env_, bool use_child_if_notfound)\n{\n  std::unique_lock<std::mutex> global_lock(mutex);\n\n  InternalEnvironment* env = GetAndRevealCamouflagedEnv(env_);\n\n  Device* device = env->GetCurrentDevice();\n\n  for (auto entry : deviceCaches) {\n    if (entry.first == device) {\n      return entry.second;\n    }\n  }\n\n  // not found for current device, creation may not be good (e.g. GetFrame(0) from an Invoke)\n  if (use_child_if_notfound)\n    return child;\n\n  // not found for current device, create it\n  AvsCache* cache = new AvsCache(child, device, /*ref*/mutex, static_cast<InternalEnvironment*>(globalEnv));\n\n  // apply cache hints if it is changed\n  if (hints.min != hints.default_min)\n    cache->SetCacheHints(CACHE_SET_MIN_CAPACITY, (int)hints.min);\n  if (hints.max != hints.default_max)\n    cache->SetCacheHints(CACHE_SET_MAX_CAPACITY, (int)hints.max);\n\n  if (hints.AudioPolicy != hints.default_AudioPolicy || hints.AudioSize != hints.default_AudioSize)\n    cache->SetCacheHints(hints.AudioPolicy, hints.AudioSize);\n\n  deviceCaches.emplace_back(device, cache);\n  return deviceCaches.back().second;\n}\n\nvoid CacheGuard::ApplyHints(int cachehints, int frame_range)\n{\n  std::unique_lock<std::mutex> global_lock(mutex);\n  for (auto entry : deviceCaches) {\n    entry.second->SetCacheHints(cachehints, frame_range);\n  }\n}\n\nint CacheGuard::GetOrDefault(int cachehints, int frame_range, int def)\n{\n  std::unique_lock<std::mutex> global_lock(mutex);\n  for (auto entry : deviceCaches) {\n    return entry.second->SetCacheHints(cachehints, frame_range);\n  }\n  return def;\n}\n\nPVideoFrame __stdcall CacheGuard::GetFrame(int n, IScriptEnvironment* env_)\n{\n  InternalEnvironment* IEnv = GetAndRevealCamouflagedEnv(env_);\n  IScriptEnvironment* env = static_cast<IScriptEnvironment*>(IEnv);\n\n  ScopedCounter getframe_counter(IEnv->GetFrameRecursiveCount());\n  /*\n  if (!name.empty())\n    _RPT2(0, \"CacheGuard::GetFrame call further GetFrame: %s %d\\n\", name.c_str(), n);\n  */\n\n  // do not create cache from inside Invoke (e.g. when calling GetFrame(0) from constructor during instantation)\n  //const bool chainedCtor = IEnv->GetInvokeStackSize() > 0;\n  const bool chainedCtor = false;\n \n  return GetCache(env, chainedCtor)->GetFrame(n, env);\n}\n\nvoid __stdcall CacheGuard::GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env_)\n{\n  InternalEnvironment* IEnv = GetAndRevealCamouflagedEnv(env_);\n  IScriptEnvironment* env = static_cast<IScriptEnvironment*>(IEnv);\n\n  ScopedCounter getframe_counter(IEnv->GetFrameRecursiveCount());\n\n  // do not create cache from inside Invoke (e.g. when calling GetFrame(0) from constructor during instantation)\n  //const bool chainedCtor = IEnv->GetInvokeStackSize() > 0;\n  const bool chainedCtor = false;\n\n  return GetCache(env, chainedCtor)->GetAudio(buf, start, count, env);\n}\n\nconst VideoInfo& __stdcall CacheGuard::GetVideoInfo()\n{\n    return vi;\n}\n\nbool __stdcall CacheGuard::GetParity(int n)\n{\n    return child->GetParity(n);\n}\n\nint __stdcall CacheGuard::SetCacheHints(int cachehints, int frame_range)\n{\n\n#ifdef _DEBUG\n  std::string hintname;\n  switch (cachehints) {\n  case CACHE_DONT_CACHE_ME: hintname = \"CACHE_DONT_CACHE_ME\"; break;\n  case CACHE_SET_MIN_CAPACITY: hintname = \"CACHE_SET_MIN_CAPACITY\"; break;\n  case CACHE_SET_MAX_CAPACITY: hintname = \"CACHE_SET_MAX_CAPACITY\"; break;\n  case CACHE_GET_MIN_CAPACITY: hintname = \"CACHE_GET_MIN_CAPACITY\"; break;\n  case CACHE_GET_MAX_CAPACITY: hintname = \"CACHE_GET_MAX_CAPACITY\"; break;\n  case CACHE_GET_SIZE: hintname = \"CACHE_GET_SIZE\"; break;\n  case CACHE_GET_REQUESTED_CAP: hintname = \"CACHE_GET_REQUESTED_CAP\"; break;\n  case CACHE_GET_CAPACITY: hintname = \"CACHE_GET_CAPACITY\"; break;\n  case CACHE_GET_MTMODE: hintname = \"CACHE_GET_MTMODE\"; break;\n  case CACHE_IS_CACHE_REQ: hintname = \"CACHE_IS_CACHE_REQ\"; break;\n  case CACHE_IS_CACHE_ANS: hintname = \"CACHE_IS_CACHE_ANS\"; break;\n  case CACHE_IS_MTGUARD_REQ: hintname = \"CACHE_IS_MTGUARD_REQ\"; break;\n  case CACHE_IS_MTGUARD_ANS: hintname = \"CACHE_IS_MTGUARD_ANS\"; break;\n  case CACHE_INFORM_NUM_THREADS: hintname = \"CACHE_INFORM_NUM_THREADS\"; break;\n  case CACHE_GET_DEV_TYPE: hintname = \"CACHE_GET_DEV_TYPE\"; break;\n  case CACHE_GET_CHILD_DEV_TYPE: hintname = \"CACHE_GET_CHILD_DEV_TYPE\"; break;\n  }\n  if (cachehints != CACHE_GET_DEV_TYPE && cachehints != CACHE_GET_CHILD_DEV_TYPE) {\n    // dont't care for the above\n    if (hintname == \"\")\n      _RPT3(0, \"CacheGuard::SetCacheHints called. cache=%p hint=%d frame_range=%d\\n\", (void*)this, cachehints, frame_range); // P.F.\n    else\n      _RPT4(0, \"CacheGuard::SetCacheHints called. cache=%p hint=%d (%s) frame_range=%d\\n\", (void*)this, cachehints, hintname.c_str(), frame_range); // P.F.\n  }\n#endif\n  switch (cachehints)\n  {\n    /*********************************************\n    MISC\n    *********************************************/\n\n    // By returning IS_CACHE_ANS to IS_CACHE_REQ, we tell the caller we are a cache\n  case CACHE_IS_CACHE_REQ:\n    return CACHE_IS_CACHE_ANS;\n\n  case CACHE_GET_POLICY: // Get the current policy.\n    return CACHE_GENERIC;\n\n  case CACHE_DONT_CACHE_ME:\n    return 1;\n\n  case CACHE_GET_MTMODE:\n    return MT_NICE_FILTER;\n\n    /*********************************************\n    AVS 2.5 TRANSLATION\n    *********************************************/\n\n    // Ignore 2.5 CACHE_NOTHING requests\n  case CACHE_25_NOTHING:\n    break;\n\n    // Map 2.5 CACHE_RANGE calls to CACHE_WINDOW\n    // force minimum range to 2\n  case CACHE_25_RANGE:\n    if (frame_range < 2) frame_range = 2;\n    SetCacheHints(CACHE_WINDOW, frame_range);\n    break;\n\n    // Map 2.5 CACHE_ALL calls to CACHE_GENERIC\n  case CACHE_25_ALL:\n    SetCacheHints(CACHE_GENERIC, frame_range);\n    break;\n\n    // Map 2.5 CACHE_AUDIO calls to CACHE_AUDIO\n  case CACHE_25_AUDIO:\n    SetCacheHints(CACHE_AUDIO, frame_range);\n    break;\n\n    // Map 2.5 CACHE_AUDIO_NONE calls to CACHE_AUDIO_NONE\n  case CACHE_25_AUDIO_NONE:\n    SetCacheHints(CACHE_AUDIO_NONE, 0);\n    break;\n\n    // Map 2.5 CACHE_AUDIO_AUTO calls to CACHE_AUDIO_AUTO\n  case CACHE_25_AUDIO_AUTO:\n    SetCacheHints(CACHE_AUDIO_AUTO, frame_range);\n    break;\n\n    /*********************************************\n    VIDEO\n    *********************************************/\n\n  case CACHE_SET_MIN_CAPACITY:\n    hints.min = frame_range;\n    ApplyHints(cachehints, frame_range);\n    break;\n\n  case CACHE_SET_MAX_CAPACITY:\n    hints.max = frame_range;\n    ApplyHints(cachehints, frame_range);\n    break;\n\n  case CACHE_GET_MIN_CAPACITY:\n    return (int)hints.min;\n\n  case CACHE_GET_MAX_CAPACITY:\n    return (int)hints.max;\n\n  case CACHE_GET_SIZE:\n  case CACHE_GET_REQUESTED_CAP:\n  case CACHE_GET_CAPACITY:\n    return GetOrDefault(cachehints, frame_range, 0);\n\n  case CACHE_GET_WINDOW: // Get the current window h_span.\n  case CACHE_GET_RANGE: // Get the current generic frame range.\n    return 2;\n    break;\n\n  case CACHE_GENERIC:\n  case CACHE_FORCE_GENERIC:\n  case CACHE_NOTHING:\n  case CACHE_WINDOW:\n  case CACHE_PREFETCH_FRAME:          // Queue request to prefetch frame N.\n  case CACHE_PREFETCH_GO:             // Action video prefetches.\n    break;\n\n    /*********************************************\n    AUDIO\n    *********************************************/\n  case CACHE_GETCHILD_AUDIO_MODE:\n  case CACHE_GETCHILD_AUDIO_SIZE:\n    return (child->GetVersion() >= 5) ? child->SetCacheHints(cachehints, 0) : 0;\n\n  case CACHE_AUDIO:\n  case CACHE_AUDIO_AUTO_START_ON: // auto mode, initially cache\n  case CACHE_AUDIO_AUTO_START_OFF: // auto mode, initially don't cache\n  case CACHE_AUDIO_NOTHING:\n    hints.AudioPolicy = (CachePolicyHint)cachehints;\n    hints.AudioSize = frame_range;\n    ApplyHints(cachehints, frame_range);\n    break;\n\n  case CACHE_GET_AUDIO_POLICY: // Get the current audio policy.\n    return hints.AudioPolicy;\n\n  case CACHE_GET_AUDIO_SIZE: // Get the current audio cache size.\n    return (child->GetVersion() >= 5) ? GetOrDefault(cachehints, frame_range, 0) : 0;\n\n  case CACHE_PREFETCH_AUDIO_BEGIN:    // Begin queue request to prefetch audio (take critical section).\n  case CACHE_PREFETCH_AUDIO_STARTLO:  // Set low 32 bits of start.\n  case CACHE_PREFETCH_AUDIO_STARTHI:  // Set high 32 bits of start.\n  case CACHE_PREFETCH_AUDIO_COUNT:    // Set low 32 bits of length.\n  case CACHE_PREFETCH_AUDIO_COMMIT:   // Enqueue request transaction to prefetch audio (release critical section).\n  case CACHE_PREFETCH_AUDIO_GO:       // Action audio prefetch\n    break;\n\n  case CACHE_GET_DEV_TYPE:\n  case CACHE_GET_CHILD_DEV_TYPE:\n    return (child->GetVersion() >= 5) ? child->SetCacheHints(cachehints, 0) : 0;\n\n\n  /*****************************************************\n  Passes actual number of threads after a Prefetch call\n  *****************************************************/\n  case CACHE_INFORM_NUM_THREADS:\n    // pass the request to the child\n    return (child->GetVersion() >= 5) ? child->SetCacheHints(cachehints, frame_range) : 0;\n\n  default:\n    return 0;\n  }\n\n  return 0;\n}\n\nAVSValue __cdecl CacheGuard::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  PClip p = 0;\n  if (args.IsClip())\n  {\n    p = args.AsClip();\n  }\n  else if (args.IsArray() && args[0].IsClip())\n  {\n    p = args[0].AsClip();\n  }\n  const char* name = nullptr;\n  if (args.IsArray() && args.ArraySize() >= 2 && args[1].IsString())\n    name = args[1].AsString();\n\n  if (p)  // If the child is a clip\n  {\n    if ( (p->GetVersion() >= 5)\n      && (p->SetCacheHints(CACHE_DONT_CACHE_ME, 0) != 0) )\n    {\n      // Don't create cache instance if the child doesn't want to be cached\n      // DONT_CACHE_ME is disabling audio cache as well, even if filter\n      // would specify it by CACHE_GETCHILD_AUDIO_MODE\n      return p; /* This is op, not args! */\n    }\n    else\n    {\n      return new CacheGuard(p, name, env);\n    }\n  }\n  else\n  {\n    return args;\n  }\n}\n\nbool __stdcall CacheGuard::IsCache(const PClip& p)\n{\n  return ((p->GetVersion() >= 5) && (p->SetCacheHints(CACHE_IS_CACHE_REQ, 0) == CACHE_IS_CACHE_ANS));\n}\n"
  },
  {
    "path": "avs_core/core/cache.h",
    "content": "// Avisynth v2.6.  Copyright 2002-2009 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Cache_H__\n#define __Cache_H__\n\n#include <avisynth.h>\n#include <mutex>\n#include <vector>\n#include <string>\n\nstruct CachePimpl;\nclass InternalEnvironment;\n\nclass AvsCache : public IClip\n{\nprivate:\n\n  IScriptEnvironment* Env;\n  CachePimpl* _pimpl;\n  Device* device;\n  std::mutex& CacheGuardMutex; // just reference!\n\n  void FillAudioZeros(void* buf, size_t start_offset, size_t count);\n\npublic:\n#ifdef _DEBUG\n  std::string FuncName = \"\"; // P.F. Invoked function's name whose queue owns the cache object\n#endif\n  AvsCache(const PClip& child, Device* device, std::mutex &CacheGuardMutex, InternalEnvironment* env);\n  ~AvsCache();\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env);\n  const VideoInfo& __stdcall GetVideoInfo();\n  bool __stdcall GetParity(int n);\n  int __stdcall SetCacheHints(int cachehints,int frame_range);\n\n  Device* GetDevice() const { return device; }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n  static bool __stdcall IsCache(const PClip& c);\n\n};\n\nclass CacheGuard : public IClip\n{\nprivate:\n  struct CacheHints {\n    size_t min, max;\n    size_t default_min, default_max;\n    CachePolicyHint AudioPolicy, default_AudioPolicy;\n    int AudioSize, default_AudioSize;\n\n    CacheHints() :\n      min(0), max(std::numeric_limits<size_t>::max()),\n      default_min(min), default_max(max),\n      AudioPolicy(CACHE_AUDIO), default_AudioPolicy(AudioPolicy),\n      AudioSize(0), default_AudioSize(AudioSize)\n    { }\n  };\n\n  PClip child;\n  VideoInfo vi;\n  IScriptEnvironment* globalEnv;\n\n  std::vector<std::pair<Device*, PClip>> deviceCaches;\n  CacheHints hints;\n  mutable std::mutex mutex;\n\n  PClip GetCache(IScriptEnvironment* env_, bool use_child_if_notfound);\n\n  void ApplyHints(int cachehints, int frame_range);\n\n  int GetOrDefault(int cachehints, int frame_range, int def);\n\npublic:\n  CacheGuard(const PClip& child, const char *name, IScriptEnvironment* env);\n  ~CacheGuard();\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env);\n  const VideoInfo& __stdcall GetVideoInfo();\n  bool __stdcall GetParity(int n);\n  int __stdcall SetCacheHints(int cachehints, int frame_range);\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n  static bool __stdcall IsCache(const PClip& c);\n\nprivate:\n  std::string name;\n  enum {\n    // Old 2.5 poorly defined cache hints.\n    // Reserve values used by 2.5 API\n    // Do not use in new filters\n    CACHE_25_NOTHING=0,\n    CACHE_25_RANGE=1,\n    CACHE_25_ALL=2,\n    CACHE_25_AUDIO=3,\n    CACHE_25_AUDIO_NONE=4,\n    CACHE_25_AUDIO_AUTO=5,\n  };\n};\n\n#endif  // __Cache_H__\n"
  },
  {
    "path": "avs_core/core/clip_info.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __CLIP_INFO_H__\n#define __CLIP_INFO_H__\n\n\nextern \"C\" const GUID CLSID_CAVIFileSynth;   // {E6D6B700-124D-11D4-86F3-DB80AFD98778}\n\nextern \"C\" const GUID IID_IAvisynthClipInfo;   // {E6D6B708-124D-11D4-86F3-DB80AFD98778}\n\nstruct IAvisynthClipInfo : IUnknown {\n  virtual int __stdcall GetError(const char** ppszMessage) = 0;\n  virtual bool __stdcall GetParity(int n) = 0;\n  virtual bool __stdcall IsFieldBased() = 0;\n};\n\n\n#endif"
  },
  {
    "path": "avs_core/core/cpuid.cpp",
    "content": "// Avisynth v1.0 beta.  Copyright 2000 Ben Rudiak-Gould.\n// http://www.math.berkeley.edu/~benrg/avisynth.html\n\n//\tVirtualDub - Video processing and capture application\n//\tCopyright (C) 1998-2000 Avery Lee\n//\n//\tThis program is free software; you can redistribute it and/or modify\n//\tit under the terms of the GNU General Public License as published by\n//\tthe Free Software Foundation; either version 2 of the License, or\n//\t(at your option) any later version.\n//\n//\tThis program is distributed in the hope that it will be useful,\n//\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n//\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//\tGNU General Public License for more details.\n//\n//\tYou should have received a copy of the GNU General Public License\n//\talong with this program; if not, write to the Free Software\n//\tFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n#include <avs/cpuid.h>\n#include <avs/config.h>\n#include <cstdint>\n#include <cstddef>\n\n// needed for linux and bsd l2cache size query\n#if defined(AVS_LINUX) || defined(AVS_BSD)\n#include <cstring>\n#include <cstdio>\n#include <cstdlib>\n#endif\n\n// Neon/Dotprod request in WinAPI ...\n#if defined(ARM64) && defined(AVS_WINDOWS)\n#include <windows.h>\n#include <processthreadsapi.h>\n#endif\n\n// --- Platform-specific headers for x86/x64 ---\n#if defined(X86_32) || defined(X86_64)\n\n#ifdef AVS_WINDOWS\n#include <intrin.h> // MSVC/Clang-CL\n#else\n// Non-Windows (GCC, Clang-GNU, etc.)\n#include <x86intrin.h>\n#include <cpuid.h>\n#undef __cpuid\n\nstatic inline void __cpuid(int cpuinfo[4], int leaf) {\n  unsigned int eax, ebx, ecx, edx;\n  // for deeper leaves __get_cpuid is not enough\n  __get_cpuid_count(leaf, 0, &eax, &ebx, &ecx, &edx);\n  cpuinfo[0] = eax;\n  cpuinfo[1] = ebx;\n  cpuinfo[2] = ecx;\n  cpuinfo[3] = edx;\n}\n#endif // AVS_WINDOWS\n\n#endif // defined(X86_32) || defined(X86_64)\n\n// --- Platform-specific headers for ARM64 ---\n#if defined(ARM64)\n#if defined(AVS_LINUX) || defined(AVS_BSD)\n// HWCAP values are needed for Linux/BSD\n#include <sys/auxv.h>\n// Note: <asm/hwcap.h> may be required on some systems, \n// but AT_HWCAP and values like HWCAP_DOTPROD are often found in sys/auxv.h or defined by toolchain.\n// We assume standard GNU/Clang behavior where flags like HWCAP_DOTPROD are available.\n#include <asm/hwcap.h>\n#elif defined(AVS_MACOS)\n// macOS/Apple Silicon uses sysctl for features\n#include <sys/types.h>\n#include <sys/sysctl.h>\n#endif\n#endif\n\n#define IS_BIT_SET(bitfield, bit) ((bitfield) & (1<<(bit)) ? true : false)\n\n#if defined(X86_32) || defined(X86_64)\nstatic uint32_t get_xcr0()\n{\n    uint32_t xcr0;\n    // _XCR_XFEATURE_ENABLED_MASK: 0\n#if defined(GCC) || defined(CLANG)\n    __asm__(\"xgetbv\" : \"=a\" (xcr0) : \"c\" (0) : \"%edx\");\n#else\n    xcr0 = (uint32_t)_xgetbv(0);\n#endif\n    return xcr0;\n}\n\n// --- Helper for __cpuid_count/ex (required for Leaf 4 sub-leaves) ---\nstatic void __cpuid_count_wrapper(int info[4], int leaf, int subleaf) {\n#ifdef AVS_WINDOWS\n  // MSVC uses __cpuidex\n  __cpuidex(info, leaf, subleaf);\n#elif defined(GCC) || defined(CLANG)\n  // GCC/Clang uses __cpuid_count\n  __cpuid_count(leaf, subleaf, info[0], info[1], info[2], info[3]);\n#else\n  // Fallback or error if no intrinsic is available\n  info[0] = info[1] = info[2] = info[3] = 0;\n#endif\n}\n\n// Helper function to determine the AVX10 version (e.g., 10.2)\n// Returns the minor version (0 for none, 1 for 10.1, 2 for 10.2, etc.)\nstatic int get_avx10_minor_version() {\n  int info[4];\n  int max_sub_leaf_7;\n\n  // 1. Check max CPUID Leaf 7 sub-leaf to ensure Sub-leaf 1 is available.\n  // Call Leaf 7, Sub-leaf 0. Max Sub-leaf is returned in EAX.\n  __cpuid_count_wrapper(info, 7, 0);\n  max_sub_leaf_7 = info[0]; // EAX holds the Max Sub-leaf\n\n  // If max sub-leaf is less than 1, we cannot query the AVX10 version.\n  if (max_sub_leaf_7 < 1) {\n    return 0; // AVX10 version not supported or enumerable\n  }\n\n  // 2. Query CPUID Leaf 7, Sub-leaf 1 for the AVX10 Version (Major/Minor)\n  __cpuid_count_wrapper(info, 7, 1);\n\n  // EAX[31:24] = Major Version\n  int major_version = (info[0] >> 24) & 0xFF;\n\n  // EAX[23:16] = Minor Version\n  int minor_version = (info[0] >> 16) & 0xFF;\n\n  // AVX10 has a major version of 10.\n  // This check confirms the version returned is for AVX10.\n  if (major_version == 10) {\n    return minor_version;\n  }\n\n  return 0; // Not an AVX10 major version\n}\n#endif // defined(X86_32) || defined(X86_64)\n\n// ------------------------------------------------------------------\n// Core aarch64 (ARMv8/v9) Feature Detection Function\n// ------------------------------------------------------------------\n#if defined(ARM64)\nstatic int64_t ARMCheckForExtensions()\n{\n  int64_t result = 0;\n\n  // Tier 1: CPUF_ARM_NEON (Mandatory for AArch64)\n  // We can assume NEON for any successful ARM64 build.\n  result |= CPUF_ARM_NEON;\n\n#if defined(AVS_LINUX) || defined(AVS_BSD)\n\n  // Linux/BSD HWCAP detection (uses AT_HWCAP/AT_HWCAP2)\n  // aarch64 implies -march=armv8-a\n  // HWCAP_NEON (Basic NEON) is covered by the assumption above.\n  unsigned long hwcap = getauxval(AT_HWCAP);\n  unsigned long hwcap2 = getauxval(AT_HWCAP2);\n\n  // When DOTPROD exists, we have at least Armv8.1-a\n  // optional in v8.1-a, mandatory in v8.4-a\n  // Safe gcc/clang flags: -march=armv8.1-a+dotprod\n  if ((hwcap & HWCAP_ASIMDDP)) {\n    result |= CPUF_ARM_DOTPROD;\n  }\n\n  // SVE2 (Scalable Vector Extension version 2) optional in v8.5-a, mandatory in v9.0-a\n  // Safe flags: -march=armv8.5-a+sve2\n  if (hwcap2 & HWCAP2_SVE2) {\n    result |= CPUF_ARM_SVE2;\n  }\n\n\n  // CPUF_ARM_SVE2_1 (incremental SVE2 part 1)\n  // optional in v9.1-a, mandatory in v9.2-a\n  #ifdef HWCAP2_SVE2P1\n  #ifdef CPUF_ARM_SVE2_1\n  if (hwcap2 & HWCAP2_SVE2P1) {\n    result |= CPUF_ARM_SVE2_1;\n  }\n  #endif\n  #endif\n\n  // CPUF_ARM_I8MM (AdvSIMD Int8 matrix multiply, Armv8.2-I8MM)\n  // optional in v8.2-a, mandatory in v8.6-a\n  // Safe flags: -march=armv8.2-a+i8mm\n  if (hwcap2 & HWCAP2_I8MM) {\n    result |= CPUF_ARM_I8MM;\n  }\n\n\n#elif defined(AVS_MACOS)\n\n  // macOS (Apple Silicon) detection via sysctlbyname.\n  // https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics\n  int value = 0;\n  size_t len = sizeof(value);\n\n  // Check for the DOTPROD feature, which is guaranteed on modern Apple Silicon.\n  // All Apple Silicon devices (M1, M2, M3, etc.) are based on ARMv8.6-a or later.\n  // The sysctl function returns 0 on success and populates 'value'.\n  if (sysctlbyname(\"hw.optional.arm.FEAT_DotProd\", &value, &len, NULL, 0) == 0 && value) {\n    result |= CPUF_ARM_DOTPROD;\n  }\n  if (sysctlbyname(\"hw.optional.arm.FEAT_I8MM\", &value, &len, NULL, 0) == 0 && value) {\n    result |= CPUF_ARM_I8MM;\n  }\n\n  // SVE2 is mandatory for general ARMv9.0-a compliance, Apple has chosen not to\n  // implement SVE or SVE2 in its M-series CPUs to date (2025).\n  // No check required here as the hardware does not support it.\n\n#elif defined(AVS_WINDOWS)\n\n  // Windows ARM64 detection using IsProcessorFeaturePresent\n  // Windows ARM SVE/SVE2 features via WinAPI flags are available since SDK 26100 (Windows 11 24H2).\n\n  // CPUF_ARM_DOTPROD (Dot Product)\n#if defined(PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE)\n  if (IsProcessorFeaturePresent(PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE)) {\n    result |= CPUF_ARM_DOTPROD;\n  }\n#endif\n\n#if defined(PF_ARM_V8_DOTPROD_INSTRUCTIONS_AVAILABLE)\n  if (IsProcessorFeaturePresent(PF_ARM_V8_DOTPROD_INSTRUCTIONS_AVAILABLE)) {\n    result |= CPUF_ARM_DOTPROD;\n  }\n#endif\n\n#if defined(PF_ARM_SVE2_INSTRUCTIONS_AVAILABLE)\n  if (IsProcessorFeaturePresent(PF_ARM_SVE2_INSTRUCTIONS_AVAILABLE)) {\n    result |= CPUF_ARM_SVE2;\n  }\n#endif\n\n#if defined(PF_ARM_V82_I8MM_INSTRUCTIONS_AVAILABLE)\n  if (IsProcessorFeaturePresent(PF_ARM_V82_I8MM_INSTRUCTIONS_AVAILABLE)) {\n    result |= CPUF_ARM_I8MM;\n  }\n#endif\n\n#if defined(PF_ARM_SVE2_1_INSTRUCTIONS_AVAILABLE)\n  if (IsProcessorFeaturePresent(PF_ARM_SVE2_1_INSTRUCTIONS_AVAILABLE)) {\n    result |= CPUF_ARM_SVE2_1;\n  }\n#endif\n\n#endif // Platform-specific ARM64 feature detection\n\n  return result;\n}\n#endif // defined(ARM64)\n\n\n// ------------------------------------------------------------------\n// Core x86/x64 Feature Detection Function\n// (Refactored for cleaner architecture switch)\n// ------------------------------------------------------------------\n#if defined(X86_32) || defined(X86_64)\nstatic int64_t X86CheckForExtensions()\n{\n  int64_t result = 0;\n  int cpuinfo[4];\n\n#if defined(X86_32) || defined(X86_64)\n  // Check CPUID Leaf 1\n  __cpuid(cpuinfo, 1);\n  if (IS_BIT_SET(cpuinfo[3], 0))\n    result |= CPUF_FPU;\n  if (IS_BIT_SET(cpuinfo[3], 23))\n    result |= CPUF_MMX;\n  if (IS_BIT_SET(cpuinfo[3], 25))\n    result |= CPUF_SSE | CPUF_INTEGER_SSE;\n  if (IS_BIT_SET(cpuinfo[3], 26))\n    result |= CPUF_SSE2;\n  if (IS_BIT_SET(cpuinfo[2], 0))\n    result |= CPUF_SSE3;\n  if (IS_BIT_SET(cpuinfo[2], 9))\n    result |= CPUF_SSSE3;\n  if (IS_BIT_SET(cpuinfo[2], 19))\n    result |= CPUF_SSE4_1;\n  if (IS_BIT_SET(cpuinfo[2], 20))\n    result |= CPUF_SSE4_2;\n  if (IS_BIT_SET(cpuinfo[2], 22))\n    result |= CPUF_MOVBE;\n  if (IS_BIT_SET(cpuinfo[2], 23))\n    result |= CPUF_POPCNT;\n  if (IS_BIT_SET(cpuinfo[2], 25))\n    result |= CPUF_AES;\n  if (IS_BIT_SET(cpuinfo[2], 29))\n    result |= CPUF_F16C;\n\n  // AVX and XCR0 Check (Needed for AVX2 and AVX-512)\n  bool xgetbv_supported = IS_BIT_SET(cpuinfo[2], 27);\n  bool avx_supported = IS_BIT_SET(cpuinfo[2], 28);\n  if (xgetbv_supported && avx_supported)\n  {\n    uint32_t xgetbv0_32 = get_xcr0();\n\n    // Check OS support for AVX (XMM and YMM state)\n    if ((xgetbv0_32 & 0x6u) == 0x6u) {\n      result |= CPUF_AVX;\n      if (IS_BIT_SET(cpuinfo[2], 12)) result |= CPUF_FMA3;\n\n      __cpuid_count_wrapper(cpuinfo, 7, 0);\n      if (IS_BIT_SET(cpuinfo[1], 5)) result |= CPUF_AVX2;\n    }\n\n    // Check OS support for AVX-512 (OPMASK, ZMM0-ZMM15, ZMM16-ZMM31 states)\n    if ((xgetbv0_32 & (0x7u << 5)) && (xgetbv0_32 & (0x3u << 1)))\n    {\n      // Leaf 7, Sub-leaf 0 results are already in cpuinfo (from AVX2 check)\n\n      // --- EBX: Core Base Features & Specialized Features ---\n      if (IS_BIT_SET(cpuinfo[1], 16)) result |= CPUF_AVX512F;\n      if (IS_BIT_SET(cpuinfo[1], 17)) result |= CPUF_AVX512DQ;\n      if (IS_BIT_SET(cpuinfo[1], 21)) result |= CPUF_AVX512IFMA;\n      if (IS_BIT_SET(cpuinfo[1], 26)) result |= CPUF_AVX512PF;\n      if (IS_BIT_SET(cpuinfo[1], 27)) result |= CPUF_AVX512ER;\n      if (IS_BIT_SET(cpuinfo[1], 28)) result |= CPUF_AVX512CD;\n      if (IS_BIT_SET(cpuinfo[1], 30)) result |= CPUF_AVX512BW;\n      if (IS_BIT_SET(cpuinfo[1], 31)) result |= CPUF_AVX512VL;\n\n      // --- ECX: ICL/RKL Features (VBMI, VNNI, Cryptography) ---\n      if (IS_BIT_SET(cpuinfo[2], 1)) result |= CPUF_AVX512VBMI;\n      if (IS_BIT_SET(cpuinfo[2], 6)) result |= CPUF_AVX512VBMI2;\n\n      /* Deprecated:\n       * AVX-512 Vector Pair to Two Intersect (VP2INTERSECT) instruction set\n       * has been found to be slower than alternative implementations using\n       * existing instructions. Newer CPUs may not implement this feature.\n      if (IS_BIT_SET(cpuinfo[2], 2)) result |= CPUF_AVX512VP2INTERSECT;\n       */\n\n      const bool has_avx512_crypto =\n        IS_BIT_SET(cpuinfo[2], 7) ||\n        IS_BIT_SET(cpuinfo[2], 8) ||\n        IS_BIT_SET(cpuinfo[2], 9);\n      /* Avisynth don't use crypto features.\n      if (IS_BIT_SET(cpuinfo[2], 8)) result |= CPUF_AVX512GFNI;\n      if (IS_BIT_SET(cpuinfo[2], 9)) result |= CPUF_AVX512VAES;\n      if (IS_BIT_SET(cpuinfo[2], 10)) result |= CPUF_AVX512VPCLMULQDQ;\n      */\n      if (IS_BIT_SET(cpuinfo[2], 11)) result |= CPUF_AVX512VNNI;\n      if (IS_BIT_SET(cpuinfo[2], 12)) result |= CPUF_AVX512BITALG;\n      if (IS_BIT_SET(cpuinfo[2], 14)) result |= CPUF_AVX512VPOPCNTDQ;\n\n      // --- AVX-512 (Leaf 7, Sub-leaf 1) ---\n      __cpuid_count_wrapper(cpuinfo, 7, 1);\n\n      // EAX:\n\n      /* Deprecated:\n       * AVX-512 4-way VNNI with Word Granularity (4VNNIW) and\n       * AVX-512 4-way Fused Multiply-Add Single precision (4FMAPS)\n       * have been deprecated and replaced by more versatile instructions\n       * in AVX10. Newer CPUs may not implement these features.\n      if (IS_BIT_SET(cpuinfo[0], 4)) result |= CPUF_AVX5124VNNIW;\n      if (IS_BIT_SET(cpuinfo[0], 5)) result |= CPUF_AVX5124FMAPS;\n      */\n\n      // EDX:\n      if (IS_BIT_SET(cpuinfo[3], 16)) result |= CPUF_AVX512FP16;\n      if (IS_BIT_SET(cpuinfo[3], 17)) result |= CPUF_AVX512BF16;\n\n      int avx10_minor = get_avx10_minor_version(); // 0 if no AVX10\n\n      // --- Composite Feature Flags and AVX10 ---\n\n      constexpr int64_t avx512_base_mask =\n        CPUF_AVX512F |\n        CPUF_AVX512CD |\n        CPUF_AVX512BW |\n        CPUF_AVX512DQ |\n        CPUF_AVX512VL;\n\n      constexpr int64_t avx512_fast_core_mask =\n        CPUF_AVX512VBMI |\n        CPUF_AVX512VNNI |\n        CPUF_AVX512VBMI2 |\n        CPUF_AVX512BITALG |\n        CPUF_AVX512VPOPCNTDQ;\n\n      // 1. Check for Base AVX-512\n      if ((result & avx512_base_mask) == avx512_base_mask) {\n\n        // Check for AVX512_FAST (Pre-AVX10 minimum Ice Lake)\n        // Base + Core ICL + Crypto (to distinguish from older server CPUs)\n        const bool has_avx512_fast =\n          ((result & avx512_fast_core_mask) == avx512_fast_core_mask) && has_avx512_crypto;\n\n        const bool has_avx10 = (avx10_minor >= 1);\n\n        // The \"Base\" group feature flag is set only if FAST is present!\n        // Since only-Base means a very old throttling CPU, we disable AVX512 group flag by default.\n        // User can later re-enable it via SetMaxCPU(\"AVX512base+\")\n        if (has_avx512_fast || has_avx10) {\n          result |= CPUF_AVX512_BASE; // fulfilling base mask is not enough\n          result |= CPUF_AVX512_FAST;\n        }\n\n        // Check for AVX10, no AVS flags atm.\n        if (has_avx10) {\n          //result |= CPUF_AVX10; // not yet, RFU\n        }\n      }\n\n      // GCC/clang compiler flags for matching CPUF_AVX512_BASE\n      // \" -mfma -mbmi2 -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl \"\n      // for matching CPUF_AVX512_FAST:\n      //\" -mfma -mbmi2 -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl -mavx512vnni -mavx512vbmi -mavx512vbmi2 -mavx512bitalg -mavx512vpopcntdq \"\n    }\n  }\n#else\n  result |= CPUF_FORCE;\n\n  return result;\n#endif\n\n#if defined(X86_32) || defined(X86_64)\n  // Check CPUID Extended Leaf 0x80000001 (for 3DNow! and FMA4)\n  __cpuid(cpuinfo, 0x80000000);\n  if (cpuinfo[0] >= 0x80000001)\n  {\n    __cpuid(cpuinfo, 0x80000001);\n\n    if (IS_BIT_SET(cpuinfo[3], 31))\n      result |= CPUF_3DNOW;\n\n    if (IS_BIT_SET(cpuinfo[3], 30))\n      result |= CPUF_3DNOW_EXT;\n\n    if (IS_BIT_SET(cpuinfo[3], 22))\n      result |= CPUF_INTEGER_SSE;\n\n    if (result & CPUF_AVX) {\n      if (IS_BIT_SET(cpuinfo[2], 16))\n        result |= CPUF_FMA4;\n    }\n  }\n#endif\n\n  return result;\n}\n#endif // defined(X86_32) || defined(X86_64)\n\n// ------------------------------------------------------------------\n// Master Feature Detection Function (Dispatcher)\n// ------------------------------------------------------------------\nstatic int64_t CPUCheckForExtensions()\n{\n  int64_t result = 0;\n\n#if defined(X86_32) || defined(X86_64)\n  result |= X86CheckForExtensions();\n#elif defined(ARM64)\n  result |= ARMCheckForExtensions();\n#else\n  // Fallback for architectures without specific detection implemented\n#endif\n\n  return result;\n}\n\n#if defined(ARM64) && (defined(AVS_LINUX) || defined(AVS_BSD))\nstatic size_t parse_sysfs_size_string(const char* size_str) {\n  if (size_str == nullptr) {\n    return 0;\n  }\n\n  char* endptr;\n  long value = strtol(size_str, &endptr, 10);\n  if (value <= 0) {\n    return 0;\n  }\n\n  if (*endptr == 'K' || *endptr == 'k') {\n    return (size_t)value * 1024;\n  }\n  else if (*endptr == 'M' || *endptr == 'm') {\n    return (size_t)value * 1024 * 1024;\n  }\n  else if (*endptr == 'G' || *endptr == 'g') {\n    return (size_t)value * 1024 * 1024 * 1024;\n  }\n  return (size_t)value;\n}\n#endif // defined(ARM64) && (defined(AVS_LINUX) || defined(AVS_BSD))\n\n// ------------------------------------------------------------------\n// Core L2 Cache Detection Function\n// ------------------------------------------------------------------\nstatic size_t DetectL2CacheSize()\n{\n#if defined(X86_32) || defined(X86_64)\n  int info[4];\n\n  // -------------------------------------------------------\n  // 1. PRIMARY METHOD: Deterministic Cache Parameters (Leaf 4)\n  //    (Modern, cross-vendor, and supports topology)\n  // -------------------------------------------------------\n  for (int i = 0; ; ++i) {\n    // We use the helper that supports sub-leaves (i)\n    __cpuid_count_wrapper(info, 0x4, i);\n\n    // EAX[4:0] = Cache Type: 1=Data, 2=Instruction, 3=Unified\n    int cache_type = info[0] & 0x1F;\n\n    // EAX[7:5] = Cache Level: 1=L1, 2=L2, 3=L3, ...\n    int cache_level = (info[0] >> 5) & 0b111;\n\n    // Check for end of list (type 0)\n    if (cache_type == 0) {\n      break;\n    }\n\n    // We look for Cache Level 2, regardless of whether it's reported as Unified (3) or Instruction (2).\n    if (cache_level == 2) {\n      // Cache Size (Bytes) = (Ways + 1) * (Partitions + 1) * (Line Size + 1) * (Sets + 1)\n\n      size_t line_size = (info[1] & 0xFFF) + 1;           // EBX[11:0]\n      size_t partitions = ((info[1] >> 12) & 0x3FF) + 1;   // EBX[21:12]\n      size_t ways = ((info[1] >> 22) & 0x3FF) + 1;   // EBX[31:22]\n      size_t sets = (size_t)info[2] + 1;             // ECX[31:0]\n\n      return ways * partitions * line_size * sets;\n    }\n  }\n\n  // -------------------------------------------------------\n  // 2. FALLBACK METHOD: AMD Extended Cache (Leaf 80000006)\n  //    (Legacy method, but reliable for older AMD CPUs)\n  // -------------------------------------------------------\n  __cpuid(info, 0x80000000);\n  // Check if the CPU supports extended leaf 80000006\n  if (info[0] >= 0x80000006) {\n    __cpuid(info, 0x80000006);\n    // ECX[31:16] is L2 cache size in KB. Convert to bytes.\n    return (size_t)(info[2] >> 16) * 1024;\n  }\n\n  // 3. If neither method worked, return 0.\n  return 0;\n#elif defined(ARM64)\n  // Cache detection on ARM is highly vendor/OS-specific.\n// --- Linux/BSD Implementation (e.g., Raspberry Pi 5) ---\n#if defined(AVS_LINUX) || defined(AVS_BSD)\n  // Detection via /sys filesystem (standard on Linux/BSD for cache info).\n  // The path targets the L2 cache size for cpu0 (per core L2 on RPi5/Cortex-A76).\n  // e.g. cat /sys/devices/system/cpu/cpu0/cache/index2/size returns 512K on RPi5\n  static constexpr const char* ARM_L2_CACHE_SYSFS_PATH = \"/sys/devices/system/cpu/cpu0/cache/index2/size\";\n  FILE* file = fopen(ARM_L2_CACHE_SYSFS_PATH, \"r\");\n  if (file) {\n    char size_str[32] = { 0 };\n    if (fgets(size_str, sizeof(size_str) - 1, file) != NULL) {\n      // Remove trailing newline character\n      size_t str_len = strlen(size_str);\n      if (str_len > 0 && size_str[str_len - 1] == '\\n') {\n        size_str[str_len - 1] = '\\0';\n      }\n\n      // Parse the string (e.g., \"512K\") and return in bytes.\n      size_t l2_cache_bytes = parse_sysfs_size_string(size_str);\n      fclose(file);\n      return l2_cache_bytes;\n    }\n    fclose(file);\n  }\n#elif defined(AVS_MACOS)\n  // macOS/Apple Silicon detection via sysctlbyname.\n  // https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_system_capabilities\n  // The generic 'hw.l2cachesize' is for the least performant core (E-cores).\n  // For performance optimization, we target the L2 cache of the high-performance (P) cores.\n  // These are typically designated as perflevel0.\n  // Note: sysctl returns the cache size in bytes.\n\n  int l2_cache_bytes = 0;\n  size_t len = sizeof(l2_cache_bytes);\n\n  // Check for the L2 cache size of the high-performance cores (P-cores), \n  // which is the largest and most relevant for optimization.\n  if (sysctlbyname(\"hw.perflevel0.l2cachesize\", &l2_cache_bytes, &len, NULL, 0) == 0 && l2_cache_bytes > 0) {\n    // Return size in bytes.\n    return static_cast<size_t>(l2_cache_bytes);\n  }\n\n  // Fallback to the generic L2 key (typically the E-core cache size).\n  if (sysctlbyname(\"hw.l2cachesize\", &l2_cache_bytes, &len, NULL, 0) == 0 && l2_cache_bytes > 0) {\n    // Return size in bytes.\n    return static_cast<size_t>(l2_cache_bytes);\n  }\n#endif\n\n\n  // Returning 0 is a safe default for a portable cross-platform implementation.\n  return 0;\n#else\n  return 0;\n#endif\n}\n\nclass _CPUFlags\n{\nprivate:\n  size_t L2CacheSize; // in bytes\n  int64_t lCPUExtensionsAvailable;\n  _CPUFlags() {\n    lCPUExtensionsAvailable = CPUCheckForExtensions();\n    L2CacheSize = DetectL2CacheSize();\n  }\n\npublic:\n  static _CPUFlags& getInstance() {\n    static _CPUFlags theInstance;\n    return theInstance;\n  }\n\n  int GetCPUFlags() {\n    return lCPUExtensionsAvailable & 0xFFFFFFFF;\n  }\n\n  int64_t GetCPUFlagsEx() {\n    return lCPUExtensionsAvailable;\n  }\n\n  void SetCPUFlags(int64_t new_flags) {\n    lCPUExtensionsAvailable = new_flags;\n  }\n\n  size_t GetL2CacheSize() {\n    return L2CacheSize;\n  }\n};\n\nint GetCPUFlags() {\n  return _CPUFlags::getInstance().GetCPUFlags();\n}\n\nint64_t GetCPUFlagsEx() {\n  return _CPUFlags::getInstance().GetCPUFlagsEx();\n}\n\nsize_t GetL2CacheSize() {\n  return _CPUFlags::getInstance().GetL2CacheSize();\n}\n"
  },
  {
    "path": "avs_core/core/exception.cpp",
    "content": "// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n/* First cut for breaking out system exceptions from the evil and most\n * unhelpful \"Unrecognized exception!\".\n *\n * This initial version just decodes the exception code, latter if one\n * is so inclined the info structure could be pulled apart and the\n * state of the machine presented. So far just knowing \"Integer Divide\n * by Zero\" was happening has been a real boon.\n */\n\n#include \"exception.h\"\n\n#ifdef AVS_WINDOWS\n    #include <avs/win.h>\n#else\n    #include <avs/posix.h>\n#endif\n\n#include <cassert>\n\n#ifdef AVS_WINDOWS\nstatic const char * StringSystemError(const unsigned code)\n{\n  switch (code) {\n  case STATUS_GUARD_PAGE_VIOLATION:      // 0x80000001\n    return \"System exception - Guard Page Violation\";\n  case STATUS_DATATYPE_MISALIGNMENT:     // 0x80000002\n    return \"System exception - Datatype Misalignment\";\n  case STATUS_BREAKPOINT:                // 0x80000003\n    return \"System exception - Breakpoint\";\n  case STATUS_SINGLE_STEP:               // 0x80000004\n    return \"System exception - Single Step\";\n//------------------------------------------------------------------------------\n  case STATUS_ACCESS_VIOLATION:          // 0xc0000005\n    return \"System exception - Access Violation\";\n  case STATUS_IN_PAGE_ERROR:             // 0xc0000006\n    return \" System exception - In Page Error\";\n  case STATUS_INVALID_HANDLE:            // 0xc0000008\n    return \"System exception - Invalid Handle\";\n  case STATUS_NO_MEMORY:                 // 0xc0000017\n    return \"System exception - No Memory\";\n  case STATUS_ILLEGAL_INSTRUCTION:       // 0xc000001d\n    return \"System exception - Illegal Instruction\";\n  case STATUS_NONCONTINUABLE_EXCEPTION:  // 0xc0000025\n    return \"System exception - Noncontinuable Exception\";\n  case STATUS_INVALID_DISPOSITION:       // 0xc0000026\n    return \"System exception - Invalid Disposition\";\n  case STATUS_ARRAY_BOUNDS_EXCEEDED:     // 0xc000008c\n    return \"System exception - Array Bounds Exceeded\";\n  case STATUS_FLOAT_DENORMAL_OPERAND:    // 0xc000008d\n    return \"System exception - Float Denormal Operand\";\n  case STATUS_FLOAT_DIVIDE_BY_ZERO:      // 0xc000008e\n    return \"System exception - Float Divide by Zero\";\n  case STATUS_FLOAT_INEXACT_RESULT:      // 0xc000008f\n    return \"System exception - Float Inexact Result\";\n  case STATUS_FLOAT_INVALID_OPERATION:   // 0xc0000090\n    return \"System exception - Float Invalid Operation\";\n  case STATUS_FLOAT_OVERFLOW:            // 0xc0000091\n    return \"System exception - Float Overflow\";\n  case STATUS_FLOAT_STACK_CHECK:         // 0xc0000092\n    return \"System exception - Float Stack Check\";\n  case STATUS_FLOAT_UNDERFLOW:           // 0xc0000093\n    return \"System exception - Float Underflow\";\n  case STATUS_INTEGER_DIVIDE_BY_ZERO:    // 0xc0000094\n    return \"System exception - Integer Divide by Zero\";\n  case STATUS_INTEGER_OVERFLOW:          // 0xc0000095\n    return \"System exception - Integer Overflow\";\n  case STATUS_PRIVILEGED_INSTRUCTION:    // 0xc0000096\n    return \"System exception - Privileged Instruction\";\n  case STATUS_STACK_OVERFLOW:            // 0xc00000fd\n    return \"System exception - Stack Overflow\";\n//------------------------------------------------------------------------------\n  case 0xC0000135:                       // 0xc0000135\n    return \"DLL Not Found\";\n  case 0xC0000142:                       // 0xc0000142\n    return \"DLL Initialization Failed\";\n  case 0xC06d007E:                       // 0xc06d007e\n    return \"Delay-load Module Not Found\";\n  case 0xC06d007F:                       // 0xc06d007e\n    return \"Delay-load Proceedure Not Found\";\n//------------------------------------------------------------------------------\n  default:\n    assert(0);\n    return \"Unrecognized system exception!\";\n  }\n\n  // Should never-ever get here\n  assert(0);\n}\n\n// Seh is Windows-only, right?\nvoid SehTranslatorFunction(unsigned int code, struct _EXCEPTION_POINTERS *record)\n{\n  throw SehException(code, record->ExceptionRecord->ExceptionAddress, StringSystemError(code));\n}\n#endif\n"
  },
  {
    "path": "avs_core/core/exception.h",
    "content": "// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef AVSCORE_EXCEPTION_H\n#define AVSCORE_EXCEPTION_H\n\n#include <avs/config.h>\n\n#if defined(MSVC)\n\n// IMPORTANT: Project must be compiled with /EHa\n#include <eh.h>\n\nextern void SehTranslatorFunction(unsigned int, struct _EXCEPTION_POINTERS*);\n\nclass SehGuard\n{\npublic:\n    SehGuard()\n    {\n        m_prev = _set_se_translator(SehTranslatorFunction);\n    }\n\n    ~SehGuard()\n    {\n        _set_se_translator(m_prev);\n    }\n\nprivate:\n    _se_translator_function m_prev;\n};\n#else\n\n// TODO: port to unix signals\nclass SehGuard\n{\npublic:\n    SehGuard() { }\n\n    ~SehGuard() { }\n};\n\n#endif\n\nclass SehException\n{\npublic:\n  SehException(unsigned int code, const void* addr, const char* msg) : m_msg(msg), m_addr(addr), m_code(code) { }\n  const char* m_msg;\n  const void* m_addr;\n  unsigned int m_code;\n};\n\n#endif // AVSCORE_EXCEPTION_H\n"
  },
  {
    "path": "avs_core/core/findfirst.h",
    "content": "/*\n * Copyright (C) 2011 Mathieu Turcotte (mathieuturcotte.ca)\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see http://www.gnu.org/licenses/.\n */\n\n#ifndef FINDFIRST_H_\n#define FINDFIRST_H_\n\n#include <sys/types.h>\n#include <stdint.h>\n#include <time.h>\n\n/* http://en.wikipedia.org/wiki/Attrib */\n#define _A_NORMAL   0x00    /* Normal file.     */\n#define _A_RDONLY   0x01    /* Read only file.  */\n#define _A_HIDDEN   0x02    /* Hidden file.     */\n#define _A_SYSTEM   0x04    /* System file.     */\n#define _A_SUBDIR   0x10    /* Subdirectory.    */\n#define _A_ARCH     0x20    /* Archive file.    */\n\nstruct _finddata_t {\n    unsigned attrib;\n    time_t time_create;\n    time_t time_access;\n    time_t time_write;\n    off_t size;\n    char name[260];\n};\n\n/*\n * Returns a unique search handle identifying the file or group of\n * files matching the filespec specification, which can be used in\n * a subsequent call to findnext or to findclose. Otherwise, findfirst\n * returns NULL and sets errno to EINVAL if filespec or fileinfo\n * was NULL or if the operating system returned an unexpected error\n * and ENOENT if the file specification could not be matched.\n */\nintptr_t _findfirst(const char* filespec, struct _finddata_t* fileinfo);\n\n/*\n * Find the next entry, if any, that matches the filespec argument\n * of a previous call to findfirst, and then alter the fileinfo\n * structure contents accordingly. If successful, returns 0. Otherwise,\n * returns -1 and sets errno to EINVAL if handle or fileinfo was NULL\n * or if the operating system returned an unexpected error and ENOENT\n * if no more matching files could be found.\n */\nint _findnext(intptr_t handle, struct _finddata_t* fileinfo);\n\n/*\n * Closes the specified search handle and releases associated\n * resources. If successful, findclose returns 0. Otherwise, it\n * returns -1 and sets errno to ENOENT, indicating that no more\n * matching files could be found.\n */\nint _findclose(intptr_t handle);\n\n#endif /* FINDFIRST_H_ */\n"
  },
  {
    "path": "avs_core/core/fonts/fixedfonts.cpp",
    "content": "/*\nFont set #1\n-----------\nCopyright (c) 2019 Dimitar Toshkov Zhekov,\nwith Reserved Font Name \"Terminus Font\".\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttp://scripts.sil.org/OFL\n\nBased on http://terminus-font.sourceforge.net/ v4.48\nSizes: 6x12, 8x14, 8x16, 10x18, 10x20, 11x22, 12x24, 14x28 and 16x32.\nWeights: normal and bold (except for 6x12, where bold=normal)\n\nTerminus Font 4.48, Copyright(C) 2019 Dimitar Toshkov Zhekov.\nReport bugs to <dimitar.zhekov@gmail.com>\n\nFont set #2\n-----------\n10x20 info_h font from old avisynth info.h + 4 extra characters by pinterf\n\nAvisynth+ source code integration by pinterf\n\n*/\n\n#include \"fixedfonts.h\"\n#include <cstring>\n#include <cstdint>\n#include <sstream>\n#include <unordered_map>\n#include <array>\n\n// The font definitions in this file were autogenerated\n// by special functions for reading BDF file and exporting it as cpp source\n\nnamespace fixed_font_12n {\n  // -- start of autogenerated text ---\n  // definition section for font: ter-u12n.bdf\n  constexpr int CHARCOUNT = 1354;\n  constexpr int WIDTH = 6;\n  constexpr int HEIGHT = 12;\n  constexpr int OFFSET_X = 0;\n  constexpr int OFFSET_Y = 0;\n  constexpr FixedFont_info_t fixedfont_info = {\n    \"Terminus\", // font name\n    \"ter-u12n.bdf\", // font name internal\n    CHARCOUNT, // num of chars\n    WIDTH, HEIGHT, OFFSET_X, OFFSET_Y,\n    false // bold\n  };\n  // font bitmap definitions\n  constexpr std::array<uint16_t, CHARCOUNT * HEIGHT> fixedfont_bitmap = {\n  0x0000,0x0000,0xd800,0x8800,0x0000,0x8800,0x8800,0x0000,0x8800,0xd800,0x0000,0x0000, // u0000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0020\n  0x0000,0x0000,0x2000,0x2000,0x2000,0x2000,0x2000,0x0000,0x2000,0x2000,0x0000,0x0000, // u0021\n  0x0000,0x5000,0x5000,0x5000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0022\n  0x0000,0x0000,0x5000,0x5000,0xf800,0x5000,0x5000,0xf800,0x5000,0x5000,0x0000,0x0000, // u0023\n  0x0000,0x0000,0x2000,0x7000,0xa800,0xa000,0x7000,0x2800,0xa800,0x7000,0x2000,0x0000, // u0024\n  0x0000,0x0000,0x4800,0xa800,0x5000,0x1000,0x2000,0x2800,0x5400,0x4800,0x0000,0x0000, // u0025\n  0x0000,0x0000,0x2000,0x5000,0x5000,0x2000,0x6800,0x9000,0x9000,0x6800,0x0000,0x0000, // u0026\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0027\n  0x0000,0x0000,0x1000,0x2000,0x4000,0x4000,0x4000,0x4000,0x2000,0x1000,0x0000,0x0000, // u0028\n  0x0000,0x0000,0x4000,0x2000,0x1000,0x1000,0x1000,0x1000,0x2000,0x4000,0x0000,0x0000, // u0029\n  0x0000,0x0000,0x0000,0x0000,0x5000,0x2000,0xf800,0x2000,0x5000,0x0000,0x0000,0x0000, // u002a\n  0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0xf800,0x2000,0x2000,0x0000,0x0000,0x0000, // u002b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x4000,0x0000, // u002c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000, // u002d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000, // u002e\n  0x0000,0x0000,0x0800,0x0800,0x1000,0x1000,0x2000,0x2000,0x4000,0x4000,0x0000,0x0000, // u002f\n  0x0000,0x0000,0x7000,0x8800,0x9800,0xa800,0xc800,0x8800,0x8800,0x7000,0x0000,0x0000, // u0030\n  0x0000,0x0000,0x2000,0x6000,0x2000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u0031\n  0x0000,0x0000,0x7000,0x8800,0x8800,0x0800,0x1000,0x2000,0x4000,0xf800,0x0000,0x0000, // u0032\n  0x0000,0x0000,0x7000,0x8800,0x0800,0x3000,0x0800,0x0800,0x8800,0x7000,0x0000,0x0000, // u0033\n  0x0000,0x0000,0x0800,0x1800,0x2800,0x4800,0x8800,0xf800,0x0800,0x0800,0x0000,0x0000, // u0034\n  0x0000,0x0000,0xf800,0x8000,0x8000,0xf000,0x0800,0x0800,0x8800,0x7000,0x0000,0x0000, // u0035\n  0x0000,0x0000,0x7000,0x8000,0x8000,0xf000,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u0036\n  0x0000,0x0000,0xf800,0x0800,0x0800,0x1000,0x1000,0x2000,0x2000,0x2000,0x0000,0x0000, // u0037\n  0x0000,0x0000,0x7000,0x8800,0x8800,0x7000,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u0038\n  0x0000,0x0000,0x7000,0x8800,0x8800,0x8800,0x7800,0x0800,0x0800,0x7000,0x0000,0x0000, // u0039\n  0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000, // u003a\n  0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x4000,0x0000, // u003b\n  0x0000,0x0000,0x0000,0x0800,0x1000,0x2000,0x4000,0x2000,0x1000,0x0800,0x0000,0x0000, // u003c\n  0x0000,0x0000,0x0000,0x0000,0xf800,0x0000,0x0000,0xf800,0x0000,0x0000,0x0000,0x0000, // u003d\n  0x0000,0x0000,0x0000,0x4000,0x2000,0x1000,0x0800,0x1000,0x2000,0x4000,0x0000,0x0000, // u003e\n  0x0000,0x0000,0x7000,0x8800,0x8800,0x1000,0x2000,0x0000,0x2000,0x2000,0x0000,0x0000, // u003f\n  0x0000,0x0000,0x7000,0x8800,0x9800,0xa800,0xa800,0x9800,0x8000,0x7800,0x0000,0x0000, // u0040\n  0x0000,0x0000,0x7000,0x8800,0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x0000,0x0000, // u0041\n  0x0000,0x0000,0xf000,0x8800,0x8800,0xf000,0x8800,0x8800,0x8800,0xf000,0x0000,0x0000, // u0042\n  0x0000,0x0000,0x7000,0x8800,0x8000,0x8000,0x8000,0x8000,0x8800,0x7000,0x0000,0x0000, // u0043\n  0x0000,0x0000,0xe000,0x9000,0x8800,0x8800,0x8800,0x8800,0x9000,0xe000,0x0000,0x0000, // u0044\n  0x0000,0x0000,0xf800,0x8000,0x8000,0xf000,0x8000,0x8000,0x8000,0xf800,0x0000,0x0000, // u0045\n  0x0000,0x0000,0xf800,0x8000,0x8000,0xf000,0x8000,0x8000,0x8000,0x8000,0x0000,0x0000, // u0046\n  0x0000,0x0000,0x7000,0x8800,0x8000,0x8000,0xb800,0x8800,0x8800,0x7000,0x0000,0x0000, // u0047\n  0x0000,0x0000,0x8800,0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u0048\n  0x0000,0x0000,0x7000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u0049\n  0x0000,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x9000,0x9000,0x6000,0x0000,0x0000, // u004a\n  0x0000,0x0000,0x8800,0x9000,0xa000,0xc000,0xc000,0xa000,0x9000,0x8800,0x0000,0x0000, // u004b\n  0x0000,0x0000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0xf800,0x0000,0x0000, // u004c\n  0x0000,0x0000,0x8800,0xd800,0xa800,0xa800,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u004d\n  0x0000,0x0000,0x8800,0x8800,0xc800,0xa800,0x9800,0x8800,0x8800,0x8800,0x0000,0x0000, // u004e\n  0x0000,0x0000,0x7000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u004f\n  0x0000,0x0000,0xf000,0x8800,0x8800,0x8800,0xf000,0x8000,0x8000,0x8000,0x0000,0x0000, // u0050\n  0x0000,0x0000,0x7000,0x8800,0x8800,0x8800,0x8800,0x8800,0xa800,0x7000,0x0800,0x0000, // u0051\n  0x0000,0x0000,0xf000,0x8800,0x8800,0x8800,0xf000,0xa000,0x9000,0x8800,0x0000,0x0000, // u0052\n  0x0000,0x0000,0x7000,0x8800,0x8000,0x7000,0x0800,0x0800,0x8800,0x7000,0x0000,0x0000, // u0053\n  0x0000,0x0000,0xf800,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000, // u0054\n  0x0000,0x0000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u0055\n  0x0000,0x0000,0x8800,0x8800,0x8800,0x5000,0x5000,0x5000,0x2000,0x2000,0x0000,0x0000, // u0056\n  0x0000,0x0000,0x8800,0x8800,0x8800,0x8800,0xa800,0xa800,0xd800,0x8800,0x0000,0x0000, // u0057\n  0x0000,0x0000,0x8800,0x8800,0x5000,0x2000,0x2000,0x5000,0x8800,0x8800,0x0000,0x0000, // u0058\n  0x0000,0x0000,0x8800,0x8800,0x5000,0x5000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000, // u0059\n  0x0000,0x0000,0xf800,0x0800,0x1000,0x2000,0x4000,0x8000,0x8000,0xf800,0x0000,0x0000, // u005a\n  0x0000,0x0000,0x7000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7000,0x0000,0x0000, // u005b\n  0x0000,0x0000,0x4000,0x4000,0x2000,0x2000,0x1000,0x1000,0x0800,0x0800,0x0000,0x0000, // u005c\n  0x0000,0x0000,0x7000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x7000,0x0000,0x0000, // u005d\n  0x0000,0x2000,0x5000,0x8800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0x0000, // u005f\n  0x4000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0060\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x0800,0x7800,0x8800,0x8800,0x7800,0x0000,0x0000, // u0061\n  0x0000,0x0000,0x8000,0x8000,0xf000,0x8800,0x8800,0x8800,0x8800,0xf000,0x0000,0x0000, // u0062\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0x8000,0x8000,0x8800,0x7000,0x0000,0x0000, // u0063\n  0x0000,0x0000,0x0800,0x0800,0x7800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0000,0x0000, // u0064\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0xf800,0x8000,0x8000,0x7800,0x0000,0x0000, // u0065\n  0x0000,0x0000,0x1800,0x2000,0x7000,0x2000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000, // u0066\n  0x0000,0x0000,0x0000,0x0000,0x7800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x7000, // u0067\n  0x0000,0x0000,0x8000,0x8000,0xf000,0x8800,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u0068\n  0x0000,0x2000,0x2000,0x0000,0x6000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u0069\n  0x0000,0x0800,0x0800,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x4800,0x3000, // u006a\n  0x0000,0x0000,0x4000,0x4000,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x0000,0x0000, // u006b\n  0x0000,0x0000,0x6000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u006c\n  0x0000,0x0000,0x0000,0x0000,0xf000,0xa800,0xa800,0xa800,0xa800,0xa800,0x0000,0x0000, // u006d\n  0x0000,0x0000,0x0000,0x0000,0xf000,0x8800,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u006e\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u006f\n  0x0000,0x0000,0x0000,0x0000,0xf000,0x8800,0x8800,0x8800,0x8800,0xf000,0x8000,0x8000, // u0070\n  0x0000,0x0000,0x0000,0x0000,0x7800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x0800, // u0071\n  0x0000,0x0000,0x0000,0x0000,0xb800,0xc000,0x8000,0x8000,0x8000,0x8000,0x0000,0x0000, // u0072\n  0x0000,0x0000,0x0000,0x0000,0x7800,0x8000,0x7000,0x0800,0x0800,0xf000,0x0000,0x0000, // u0073\n  0x0000,0x0000,0x2000,0x2000,0x7000,0x2000,0x2000,0x2000,0x2000,0x1800,0x0000,0x0000, // u0074\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0000,0x0000, // u0075\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0x5000,0x5000,0x2000,0x2000,0x0000,0x0000, // u0076\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0xa800,0xa800,0xa800,0x7000,0x0000,0x0000, // u0077\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x5000,0x2000,0x2000,0x5000,0x8800,0x0000,0x0000, // u0078\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x7000, // u0079\n  0x0000,0x0000,0x0000,0x0000,0xf800,0x1000,0x2000,0x4000,0x8000,0xf800,0x0000,0x0000, // u007a\n  0x0000,0x0000,0x1800,0x2000,0x2000,0x4000,0x2000,0x2000,0x2000,0x1800,0x0000,0x0000, // u007b\n  0x0000,0x0000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000, // u007c\n  0x0000,0x0000,0x6000,0x1000,0x1000,0x0800,0x1000,0x1000,0x1000,0x6000,0x0000,0x0000, // u007d\n  0x0000,0x4800,0xa800,0x9000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a0\n  0x0000,0x0000,0x2000,0x2000,0x0000,0x2000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000, // u00a1\n  0x0000,0x0000,0x0000,0x2000,0x7000,0xa800,0xa000,0xa000,0xa800,0x7000,0x2000,0x0000, // u00a2\n  0x0000,0x0000,0x3000,0x4800,0x4000,0xf000,0x4000,0x4000,0x4800,0xf800,0x0000,0x0000, // u00a3\n  0x0000,0x0000,0x0000,0x4800,0x3000,0x4800,0x4800,0x3000,0x4800,0x0000,0x0000,0x0000, // u00a4\n  0x0000,0x0000,0x8800,0x8800,0x5000,0x2000,0x7000,0x2000,0x7000,0x2000,0x0000,0x0000, // u00a5\n  0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u00a6\n  0x0000,0x3000,0x4800,0x2000,0x5000,0x4800,0x2800,0x1000,0x4800,0x3000,0x0000,0x0000, // u00a7\n  0x5000,0x5000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a8\n  0x0000,0x0000,0x7800,0x8400,0xb400,0xa400,0xa400,0xb400,0x8400,0x7800,0x0000,0x0000, // u00a9\n  0x3000,0x0800,0x3800,0x4800,0x3800,0x0000,0x7800,0x0000,0x0000,0x0000,0x0000,0x0000, // u00aa\n  0x0000,0x0000,0x0000,0x1400,0x2800,0x5000,0xa000,0x5000,0x2800,0x1400,0x0000,0x0000, // u00ab\n  0x0000,0x0000,0x0000,0x0000,0xf800,0x0800,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000, // u00ac\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7800,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ad\n  0x0000,0x0000,0x7800,0x8400,0xb400,0xac00,0xb400,0xac00,0x8400,0x7800,0x0000,0x0000, // u00ae\n  0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00af\n  0x0000,0x2000,0x5000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b0\n  0x0000,0x0000,0x0000,0x2000,0x2000,0xf800,0x2000,0x2000,0x0000,0xf800,0x0000,0x0000, // u00b1\n  0x0000,0x3000,0x4800,0x1000,0x2000,0x7800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b2\n  0x0000,0x7000,0x0800,0x3000,0x0800,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b3\n  0x1000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b4\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0x8800,0x8800,0x9800,0xe800,0x8000,0x8000, // u00b5\n  0x0000,0x0000,0x7800,0xa800,0xa800,0xa800,0x6800,0x2800,0x2800,0x2800,0x0000,0x0000, // u00b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x4000, // u00b8\n  0x0000,0x1000,0x3000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b9\n  0x3000,0x4800,0x4800,0x4800,0x3000,0x0000,0x7800,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ba\n  0x0000,0x0000,0x0000,0xa000,0x5000,0x2800,0x1400,0x2800,0x5000,0xa000,0x0000,0x0000, // u00bb\n  0x4000,0xc000,0x4400,0x4800,0x5000,0x2000,0x4800,0x9800,0x2800,0x7800,0x0800,0x0800, // u00bc\n  0x4000,0xc000,0x4400,0x4800,0x5000,0x2000,0x4000,0x9800,0x2400,0x0800,0x1000,0x3c00, // u00bd\n  0xe000,0x1000,0x6000,0x1400,0xe800,0x1000,0x2400,0x4c00,0x9400,0x3c00,0x0400,0x0400, // u00be\n  0x0000,0x0000,0x2000,0x2000,0x0000,0x2000,0x4000,0x8800,0x8800,0x7000,0x0000,0x0000, // u00bf\n  0x4000,0x2000,0x7000,0x8800,0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x0000,0x0000, // u00c0\n  0x1000,0x2000,0x7000,0x8800,0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x0000,0x0000, // u00c1\n  0x2000,0x5000,0x7000,0x8800,0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x0000,0x0000, // u00c2\n  0x2800,0x5000,0x7000,0x8800,0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x0000,0x0000, // u00c3\n  0x5000,0x5000,0x7000,0x8800,0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x0000,0x0000, // u00c4\n  0x2000,0x5000,0x7000,0x8800,0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x0000,0x0000, // u00c5\n  0x0000,0x0000,0x7c00,0x9000,0x9000,0xfc00,0x9000,0x9000,0x9000,0x9c00,0x0000,0x0000, // u00c6\n  0x0000,0x0000,0x7000,0x8800,0x8000,0x8000,0x8000,0x8000,0x8800,0x7000,0x2000,0x4000, // u00c7\n  0x4000,0x2000,0xf800,0x8000,0x8000,0xf000,0x8000,0x8000,0x8000,0xf800,0x0000,0x0000, // u00c8\n  0x1000,0x2000,0xf800,0x8000,0x8000,0xf000,0x8000,0x8000,0x8000,0xf800,0x0000,0x0000, // u00c9\n  0x2000,0x5000,0xf800,0x8000,0x8000,0xf000,0x8000,0x8000,0x8000,0xf800,0x0000,0x0000, // u00ca\n  0x5000,0x5000,0xf800,0x8000,0x8000,0xf000,0x8000,0x8000,0x8000,0xf800,0x0000,0x0000, // u00cb\n  0x4000,0x2000,0x7000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u00cc\n  0x1000,0x2000,0x7000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u00cd\n  0x2000,0x5000,0x7000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u00ce\n  0x5000,0x5000,0x7000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u00cf\n  0x0000,0x0000,0xe000,0x9000,0x8800,0xe800,0x8800,0x8800,0x9000,0xe000,0x0000,0x0000, // u00d0\n  0x2800,0x5000,0x8800,0x8800,0xc800,0xa800,0x9800,0x8800,0x8800,0x8800,0x0000,0x0000, // u00d1\n  0x4000,0x2000,0x7000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u00d2\n  0x1000,0x2000,0x7000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u00d3\n  0x2000,0x5000,0x7000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u00d4\n  0x2800,0x5000,0x7000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u00d5\n  0x5000,0x5000,0x7000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u00d6\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x5000,0x2000,0x5000,0x8800,0x0000,0x0000,0x0000, // u00d7\n  0x0000,0x0000,0x7400,0x8800,0x9800,0xa800,0xc800,0x8800,0x8800,0x7000,0x0000,0x0000, // u00d8\n  0x4000,0x2000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u00d9\n  0x1000,0x2000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u00da\n  0x2000,0x5000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u00db\n  0x5000,0x5000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u00dc\n  0x1000,0x2000,0x8800,0x8800,0x5000,0x5000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000, // u00dd\n  0x0000,0x0000,0x8000,0xf000,0x8800,0x8800,0x8800,0xf000,0x8000,0x8000,0x0000,0x0000, // u00de\n  0x0000,0x0000,0xe000,0x9000,0x9000,0xf000,0x8800,0x8800,0xc800,0xb000,0x0000,0x0000, // u00df\n  0x0000,0x0000,0x4000,0x2000,0x7000,0x0800,0x7800,0x8800,0x8800,0x7800,0x0000,0x0000, // u00e0\n  0x0000,0x0000,0x1000,0x2000,0x7000,0x0800,0x7800,0x8800,0x8800,0x7800,0x0000,0x0000, // u00e1\n  0x0000,0x0000,0x2000,0x5000,0x7000,0x0800,0x7800,0x8800,0x8800,0x7800,0x0000,0x0000, // u00e2\n  0x0000,0x0000,0x2800,0x5000,0x7000,0x0800,0x7800,0x8800,0x8800,0x7800,0x0000,0x0000, // u00e3\n  0x0000,0x0000,0x5000,0x5000,0x7000,0x0800,0x7800,0x8800,0x8800,0x7800,0x0000,0x0000, // u00e4\n  0x0000,0x0000,0x2000,0x5000,0x7000,0x0800,0x7800,0x8800,0x8800,0x7800,0x0000,0x0000, // u00e5\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x2800,0x6800,0xb000,0xa000,0x7800,0x0000,0x0000, // u00e6\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0x8000,0x8000,0x8800,0x7000,0x2000,0x4000, // u00e7\n  0x0000,0x0000,0x4000,0x2000,0x7000,0x8800,0xf800,0x8000,0x8000,0x7800,0x0000,0x0000, // u00e8\n  0x0000,0x0000,0x1000,0x2000,0x7000,0x8800,0xf800,0x8000,0x8000,0x7800,0x0000,0x0000, // u00e9\n  0x0000,0x0000,0x2000,0x5000,0x7000,0x8800,0xf800,0x8000,0x8000,0x7800,0x0000,0x0000, // u00ea\n  0x0000,0x0000,0x5000,0x5000,0x7000,0x8800,0xf800,0x8000,0x8000,0x7800,0x0000,0x0000, // u00eb\n  0x0000,0x0000,0x4000,0x2000,0x6000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u00ec\n  0x0000,0x0000,0x1000,0x2000,0x6000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u00ed\n  0x0000,0x0000,0x2000,0x5000,0x6000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u00ee\n  0x0000,0x0000,0x5000,0x5000,0x6000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u00ef\n  0x0000,0xa000,0x4000,0xa000,0x7000,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u00f0\n  0x0000,0x0000,0x2800,0x5000,0xf000,0x8800,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u00f1\n  0x0000,0x0000,0x4000,0x2000,0x7000,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u00f2\n  0x0000,0x0000,0x1000,0x2000,0x7000,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u00f3\n  0x0000,0x0000,0x2000,0x5000,0x7000,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u00f4\n  0x0000,0x0000,0x2800,0x5000,0x7000,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u00f5\n  0x0000,0x0000,0x5000,0x5000,0x7000,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u00f6\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0xf800,0x0000,0x2000,0x2000,0x0000,0x0000, // u00f7\n  0x0000,0x0000,0x0000,0x0000,0x7400,0x9800,0xa800,0xc800,0x8800,0x7000,0x0000,0x0000, // u00f8\n  0x0000,0x0000,0x4000,0x2000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0000,0x0000, // u00f9\n  0x0000,0x0000,0x1000,0x2000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0000,0x0000, // u00fa\n  0x0000,0x0000,0x2000,0x5000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0000,0x0000, // u00fb\n  0x0000,0x0000,0x5000,0x5000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0000,0x0000, // u00fc\n  0x0000,0x0000,0x1000,0x2000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x7000, // u00fd\n  0x0000,0x0000,0x8000,0x8000,0xf000,0x8800,0x8800,0x8800,0x8800,0xf000,0x8000,0x8000, // u00fe\n  0x0000,0x0000,0x5000,0x5000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x7000, // u00ff\n  0x7000,0x0000,0x7000,0x8800,0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x0000,0x0000, // u0100\n  0x0000,0x0000,0x7000,0x0000,0x7000,0x0800,0x7800,0x8800,0x8800,0x7800,0x0000,0x0000, // u0101\n  0x5000,0x2000,0x7000,0x8800,0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x0000,0x0000, // u0102\n  0x0000,0x0000,0x5000,0x2000,0x7000,0x0800,0x7800,0x8800,0x8800,0x7800,0x0000,0x0000, // u0103\n  0x0000,0x0000,0x7000,0x8800,0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x1000,0x0c00, // u0104\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x0800,0x7800,0x8800,0x8800,0x7800,0x1000,0x0c00, // u0105\n  0x1000,0x2000,0x7000,0x8800,0x8000,0x8000,0x8000,0x8000,0x8800,0x7000,0x0000,0x0000, // u0106\n  0x0000,0x0000,0x1000,0x2000,0x7000,0x8800,0x8000,0x8000,0x8800,0x7000,0x0000,0x0000, // u0107\n  0x2000,0x5000,0x7000,0x8800,0x8000,0x8000,0x8000,0x8000,0x8800,0x7000,0x0000,0x0000, // u0108\n  0x0000,0x0000,0x2000,0x5000,0x7000,0x8800,0x8000,0x8000,0x8800,0x7000,0x0000,0x0000, // u0109\n  0x2000,0x2000,0x7000,0x8800,0x8000,0x8000,0x8000,0x8000,0x8800,0x7000,0x0000,0x0000, // u010a\n  0x0000,0x0000,0x2000,0x2000,0x7000,0x8800,0x8000,0x8000,0x8800,0x7000,0x0000,0x0000, // u010b\n  0x5000,0x2000,0x7000,0x8800,0x8000,0x8000,0x8000,0x8000,0x8800,0x7000,0x0000,0x0000, // u010c\n  0x0000,0x0000,0x5000,0x2000,0x7000,0x8800,0x8000,0x8000,0x8800,0x7000,0x0000,0x0000, // u010d\n  0xa000,0x4000,0xe000,0x9000,0x8800,0x8800,0x8800,0x8800,0x9000,0xe000,0x0000,0x0000, // u010e\n  0x5000,0x2000,0x0800,0x0800,0x7800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0000,0x0000, // u010f\n  0x0000,0x0000,0xe000,0x9000,0x8800,0xe800,0x8800,0x8800,0x9000,0xe000,0x0000,0x0000, // u0110\n  0x0000,0x0000,0x0800,0x3c00,0x0800,0x7800,0x8800,0x8800,0x8800,0x7800,0x0000,0x0000, // u0111\n  0x7000,0x0000,0xf800,0x8000,0x8000,0xf000,0x8000,0x8000,0x8000,0xf800,0x0000,0x0000, // u0112\n  0x0000,0x0000,0x7000,0x0000,0x7000,0x8800,0xf800,0x8000,0x8000,0x7800,0x0000,0x0000, // u0113\n  0x5000,0x2000,0xf800,0x8000,0x8000,0xf000,0x8000,0x8000,0x8000,0xf800,0x0000,0x0000, // u0114\n  0x0000,0x0000,0x5000,0x2000,0x7000,0x8800,0xf800,0x8000,0x8000,0x7800,0x0000,0x0000, // u0115\n  0x2000,0x2000,0xf800,0x8000,0x8000,0xf000,0x8000,0x8000,0x8000,0xf800,0x0000,0x0000, // u0116\n  0x0000,0x0000,0x2000,0x2000,0x7000,0x8800,0xf800,0x8000,0x8000,0x7800,0x0000,0x0000, // u0117\n  0x0000,0x0000,0xf800,0x8000,0x8000,0xf000,0x8000,0x8000,0x8000,0xf800,0x1000,0x0c00, // u0118\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0xf800,0x8000,0x8000,0x7800,0x2000,0x1800, // u0119\n  0x5000,0x2000,0xf800,0x8000,0x8000,0xf000,0x8000,0x8000,0x8000,0xf800,0x0000,0x0000, // u011a\n  0x0000,0x0000,0x5000,0x2000,0x7000,0x8800,0xf800,0x8000,0x8000,0x7800,0x0000,0x0000, // u011b\n  0x2000,0x5000,0x7000,0x8800,0x8000,0x8000,0xb800,0x8800,0x8800,0x7000,0x0000,0x0000, // u011c\n  0x0000,0x0000,0x2000,0x5000,0x7800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x7000, // u011d\n  0x5000,0x2000,0x7000,0x8800,0x8000,0x8000,0xb800,0x8800,0x8800,0x7000,0x0000,0x0000, // u011e\n  0x0000,0x0000,0x5000,0x2000,0x7800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x7000, // u011f\n  0x2000,0x2000,0x7000,0x8800,0x8000,0x8000,0xb800,0x8800,0x8800,0x7000,0x0000,0x0000, // u0120\n  0x0000,0x0000,0x2000,0x2000,0x7800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x7000, // u0121\n  0x0000,0x0000,0x7000,0x8800,0x8000,0x8000,0xb800,0x8800,0x8800,0x7000,0x2000,0x4000, // u0122\n  0x0000,0x0000,0x1000,0x2000,0x7800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x7000, // u0123\n  0x2000,0x5000,0x8800,0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u0124\n  0x2000,0x5000,0x8000,0x8000,0xf000,0x8800,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u0125\n  0x0000,0x0000,0x4800,0xfc00,0x4800,0x7800,0x4800,0x4800,0x4800,0x4800,0x0000,0x0000, // u0126\n  0x0000,0x0000,0x4000,0xf000,0x4000,0x7000,0x4800,0x4800,0x4800,0x4800,0x0000,0x0000, // u0127\n  0x2800,0x5000,0x7000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u0128\n  0x0000,0x0000,0x2800,0x5000,0x6000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u0129\n  0x7000,0x0000,0x7000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u012a\n  0x0000,0x0000,0x7000,0x0000,0x6000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u012b\n  0x5000,0x2000,0x7000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u012c\n  0x0000,0x0000,0x5000,0x2000,0x6000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u012d\n  0x0000,0x0000,0x7000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x7000,0x2000,0x1800, // u012e\n  0x0000,0x2000,0x2000,0x0000,0x6000,0x2000,0x2000,0x2000,0x2000,0x7000,0x2000,0x1800, // u012f\n  0x2000,0x2000,0x7000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u0130\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u0131\n  0x0000,0x0000,0x8800,0x8800,0x8800,0x8800,0x8800,0xa800,0xa800,0x9000,0x0000,0x0000, // u0132\n  0x0000,0x8800,0x8800,0x0000,0x9800,0x8800,0x8800,0x8800,0x8800,0x8800,0x2800,0x1000, // u0133\n  0x1000,0x2800,0x3800,0x1000,0x1000,0x1000,0x1000,0x9000,0x9000,0x6000,0x0000,0x0000, // u0134\n  0x0000,0x0000,0x0800,0x1400,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x4800,0x3000, // u0135\n  0x0000,0x0000,0x8800,0x9000,0xa000,0xc000,0xc000,0xa000,0x9000,0xa800,0x2000,0x4000, // u0136\n  0x0000,0x0000,0x4000,0x4000,0x4800,0x5000,0x6000,0x6000,0x5000,0x6800,0x2000,0x4000, // u0137\n  0x0000,0x0000,0x0000,0x0000,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x0000,0x0000, // u0138\n  0x2000,0x4000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0xf800,0x0000,0x0000, // u0139\n  0x1000,0x2000,0x6000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u013a\n  0x0000,0x0000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0xf800,0x2000,0x4000, // u013b\n  0x0000,0x0000,0x6000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x7000,0x2000,0x4000, // u013c\n  0x5000,0x2000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0xf800,0x0000,0x0000, // u013d\n  0x5000,0x2000,0x6000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u013e\n  0x0000,0x0000,0x8000,0x8000,0x8000,0x9000,0x9000,0x8000,0x8000,0xf800,0x0000,0x0000, // u013f\n  0x0000,0x0000,0x6000,0x2000,0x2000,0x2400,0x2400,0x2000,0x2000,0x7000,0x0000,0x0000, // u0140\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x6000,0xc000,0x4000,0x4000,0x7c00,0x0000,0x0000, // u0141\n  0x0000,0x0000,0x6000,0x2000,0x2000,0x3000,0x6000,0x2000,0x2000,0x7000,0x0000,0x0000, // u0142\n  0x1000,0x2000,0x8800,0x8800,0xc800,0xa800,0x9800,0x8800,0x8800,0x8800,0x0000,0x0000, // u0143\n  0x0000,0x0000,0x1000,0x2000,0xf000,0x8800,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u0144\n  0x0000,0x0000,0x8800,0x8800,0xc800,0xa800,0x9800,0x8800,0x8800,0xa800,0x2000,0x4000, // u0145\n  0x0000,0x0000,0x0000,0x0000,0xf000,0x8800,0x8800,0x8800,0x8800,0xa800,0x2000,0x4000, // u0146\n  0x5000,0x2000,0x8800,0x8800,0xc800,0xa800,0x9800,0x8800,0x8800,0x8800,0x0000,0x0000, // u0147\n  0x0000,0x0000,0x5000,0x2000,0xf000,0x8800,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u0148\n  0x0000,0x4000,0x4000,0x8000,0xf000,0x8800,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u0149\n  0x0000,0x0000,0x8800,0x8800,0xc800,0xa800,0x9800,0x8800,0x8800,0x8800,0x0800,0x1000, // u014a\n  0x0000,0x0000,0x0000,0x0000,0xf000,0x8800,0x8800,0x8800,0x8800,0x8800,0x0800,0x1000, // u014b\n  0x7000,0x0000,0x7000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u014c\n  0x0000,0x0000,0x7000,0x0000,0x7000,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u014d\n  0x5000,0x2000,0x7000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u014e\n  0x0000,0x0000,0x5000,0x2000,0x7000,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u014f\n  0x2800,0x5000,0x7000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u0150\n  0x0000,0x0000,0x2800,0x5000,0x7000,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u0151\n  0x0000,0x0000,0x7c00,0x9000,0x9000,0x9c00,0x9000,0x9000,0x9000,0x7c00,0x0000,0x0000, // u0152\n  0x0000,0x0000,0x0000,0x0000,0x7000,0xa800,0xa800,0xb000,0xa000,0x7800,0x0000,0x0000, // u0153\n  0x1000,0x2000,0xf000,0x8800,0x8800,0x8800,0xf000,0xa000,0x9000,0x8800,0x0000,0x0000, // u0154\n  0x0000,0x0000,0x1000,0x2000,0xb800,0xc000,0x8000,0x8000,0x8000,0x8000,0x0000,0x0000, // u0155\n  0x0000,0x0000,0xf000,0x8800,0x8800,0x8800,0xf000,0xa000,0x9000,0xa800,0x2000,0x4000, // u0156\n  0x0000,0x0000,0x0000,0x0000,0xb800,0xc000,0x8000,0x8000,0x8000,0xc000,0x4000,0x8000, // u0157\n  0x5000,0x2000,0xf000,0x8800,0x8800,0x8800,0xf000,0xa000,0x9000,0x8800,0x0000,0x0000, // u0158\n  0x0000,0x0000,0x5000,0x2000,0xb800,0xc000,0x8000,0x8000,0x8000,0x8000,0x0000,0x0000, // u0159\n  0x1000,0x2000,0x7000,0x8800,0x8000,0x7000,0x0800,0x0800,0x8800,0x7000,0x0000,0x0000, // u015a\n  0x0000,0x0000,0x1000,0x2000,0x7800,0x8000,0x7000,0x0800,0x0800,0xf000,0x0000,0x0000, // u015b\n  0x2000,0x5000,0x7000,0x8800,0x8000,0x7000,0x0800,0x0800,0x8800,0x7000,0x0000,0x0000, // u015c\n  0x0000,0x0000,0x2000,0x5000,0x7800,0x8000,0x7000,0x0800,0x0800,0xf000,0x0000,0x0000, // u015d\n  0x0000,0x0000,0x7000,0x8800,0x8000,0x7000,0x0800,0x0800,0x8800,0x7000,0x2000,0x4000, // u015e\n  0x0000,0x0000,0x0000,0x0000,0x7800,0x8000,0x7000,0x0800,0x0800,0xf000,0x2000,0x4000, // u015f\n  0x5000,0x2000,0x7000,0x8800,0x8000,0x7000,0x0800,0x0800,0x8800,0x7000,0x0000,0x0000, // u0160\n  0x0000,0x0000,0x5000,0x2000,0x7800,0x8000,0x7000,0x0800,0x0800,0xf000,0x0000,0x0000, // u0161\n  0x0000,0x0000,0xf800,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x3000,0x1000,0x2000, // u0162\n  0x0000,0x0000,0x2000,0x2000,0x7000,0x2000,0x2000,0x2000,0x2000,0x1800,0x1000,0x2000, // u0163\n  0x5000,0x2000,0xf800,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000, // u0164\n  0x5000,0x2000,0x2000,0x2000,0x7000,0x2000,0x2000,0x2000,0x2000,0x1800,0x0000,0x0000, // u0165\n  0x0000,0x0000,0xf800,0x2000,0x2000,0x7000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000, // u0166\n  0x0000,0x0000,0x2000,0x2000,0x7000,0x2000,0x7000,0x2000,0x2000,0x1800,0x0000,0x0000, // u0167\n  0x2800,0x5000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u0168\n  0x0000,0x0000,0x2800,0x5000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0000,0x0000, // u0169\n  0x7000,0x0000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u016a\n  0x0000,0x0000,0x7000,0x0000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0000,0x0000, // u016b\n  0x5000,0x2000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u016c\n  0x0000,0x0000,0x5000,0x2000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0000,0x0000, // u016d\n  0x2000,0x5000,0xa800,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u016e\n  0x0000,0x0000,0x2000,0x5000,0xa800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0000,0x0000, // u016f\n  0x2800,0x5000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u0170\n  0x0000,0x0000,0x2800,0x5000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0000,0x0000, // u0171\n  0x0000,0x0000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x2000,0x1800, // u0172\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x1000,0x0c00, // u0173\n  0x2000,0x5000,0x8800,0x8800,0x8800,0x8800,0xa800,0xa800,0xd800,0x8800,0x0000,0x0000, // u0174\n  0x0000,0x0000,0x2000,0x5000,0x8800,0x8800,0xa800,0xa800,0xa800,0x7000,0x0000,0x0000, // u0175\n  0x2000,0x5000,0x8800,0x8800,0x5000,0x5000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000, // u0176\n  0x0000,0x0000,0x2000,0x5000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x7000, // u0177\n  0x5000,0x5000,0x8800,0x8800,0x5000,0x5000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000, // u0178\n  0x1000,0x2000,0xf800,0x0800,0x1000,0x2000,0x4000,0x8000,0x8000,0xf800,0x0000,0x0000, // u0179\n  0x0000,0x0000,0x1000,0x2000,0xf800,0x1000,0x2000,0x4000,0x8000,0xf800,0x0000,0x0000, // u017a\n  0x2000,0x2000,0xf800,0x0800,0x1000,0x2000,0x4000,0x8000,0x8000,0xf800,0x0000,0x0000, // u017b\n  0x0000,0x0000,0x2000,0x2000,0xf800,0x1000,0x2000,0x4000,0x8000,0xf800,0x0000,0x0000, // u017c\n  0x5000,0x2000,0xf800,0x0800,0x1000,0x2000,0x4000,0x8000,0x8000,0xf800,0x0000,0x0000, // u017d\n  0x0000,0x0000,0x5000,0x2000,0xf800,0x1000,0x2000,0x4000,0x8000,0xf800,0x0000,0x0000, // u017e\n  0x0000,0x0000,0x1800,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000, // u017f\n  0x0000,0x0000,0x7000,0x8800,0x0800,0x0800,0x0800,0x0800,0x8800,0x7000,0x0000,0x0000, // u0186\n  0x0000,0x0000,0xf800,0x0800,0x0800,0x7800,0x0800,0x0800,0x0800,0xf800,0x0000,0x0000, // u018e\n  0x0000,0x0000,0x7000,0x8800,0x0800,0x0800,0xf800,0x8800,0x8800,0x7000,0x0000,0x0000, // u018f\n  0x0000,0x0000,0x7000,0x8800,0x8000,0x6000,0x8000,0x8000,0x8800,0x7000,0x0000,0x0000, // u0190\n  0x0000,0x0000,0x1000,0x2800,0x2000,0x7000,0x2000,0x2000,0x2000,0x2000,0xa000,0x4000, // u0192\n  0x0000,0x0000,0x8800,0x8800,0xc800,0xa800,0x9800,0x8800,0x8800,0xc800,0x4000,0x8000, // u019d\n  0x0000,0x0000,0x0000,0x0000,0xf000,0x8800,0x8800,0x8800,0x8800,0x8800,0x0800,0x0800, // u019e\n  0x0000,0x0000,0xf800,0x0800,0x1000,0xf800,0x2000,0x4000,0x8000,0xf800,0x0000,0x0000, // u01b5\n  0x0000,0x0000,0x0000,0x0000,0xf800,0x1000,0x7800,0x2000,0x4000,0xf800,0x0000,0x0000, // u01b6\n  0x0000,0x0000,0xf800,0x0800,0x1000,0x3000,0x0800,0x0800,0x8800,0x7000,0x0000,0x0000, // u01b7\n  0x5000,0x2000,0x7000,0x8800,0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x0000,0x0000, // u01cd\n  0x0000,0x0000,0x5000,0x2000,0x7000,0x0800,0x7800,0x8800,0x8800,0x7800,0x0000,0x0000, // u01ce\n  0x5000,0x2000,0x7000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u01cf\n  0x0000,0x0000,0x5000,0x2000,0x6000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u01d0\n  0x5000,0x2000,0x7000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u01d1\n  0x0000,0x0000,0x5000,0x2000,0x7000,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u01d2\n  0x5000,0x2000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u01d3\n  0x0000,0x0000,0x5000,0x2000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0000,0x0000, // u01d4\n  0x7800,0x0000,0x7c00,0x9000,0x9000,0xfc00,0x9000,0x9000,0x9000,0x9c00,0x0000,0x0000, // u01e2\n  0x0000,0x0000,0x7000,0x0000,0x7000,0x2800,0x6800,0xb000,0xa000,0x7800,0x0000,0x0000, // u01e3\n  0x0000,0x0000,0x7800,0x8000,0x8000,0xb800,0x8800,0x9c00,0x8800,0x7000,0x0000,0x0000, // u01e4\n  0x0000,0x0000,0x0000,0x0000,0x7800,0x8800,0x9c00,0x8800,0x8800,0x7800,0x0800,0x7000, // u01e5\n  0x5000,0x2000,0x7000,0x8800,0x8000,0x8000,0xb800,0x8800,0x8800,0x7000,0x0000,0x0000, // u01e6\n  0x0000,0x0000,0x5000,0x2000,0x7800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x7000, // u01e7\n  0x5000,0x2000,0x8800,0x9000,0xa000,0xc000,0xc000,0xa000,0x9000,0x8800,0x0000,0x0000, // u01e8\n  0x5000,0x2000,0x4000,0x4000,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x0000,0x0000, // u01e9\n  0x0000,0x0000,0x7000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x2000,0x1800, // u01ea\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0x8800,0x8800,0x8800,0x7000,0x2000,0x1800, // u01eb\n  0x7000,0x0000,0x7000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x2000,0x1800, // u01ec\n  0x0000,0x0000,0x7000,0x0000,0x7000,0x8800,0x8800,0x8800,0x8800,0x7000,0x2000,0x1800, // u01ed\n  0x5000,0x2000,0xf800,0x0800,0x1000,0x3000,0x0800,0x0800,0x8800,0x7000,0x0000,0x0000, // u01ee\n  0x0000,0x0000,0x5000,0x2000,0xf800,0x0800,0x1000,0x3000,0x0800,0x0800,0x8800,0x7000, // u01ef\n  0x0000,0x0000,0x1400,0x0800,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x4800,0x3000, // u01f0\n  0x1000,0x2000,0x7000,0x8800,0x8000,0x8000,0xb800,0x8800,0x8800,0x7000,0x0000,0x0000, // u01f4\n  0x0000,0x0000,0x1000,0x2000,0x7800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x7000, // u01f5\n  0x0800,0x1000,0x7c00,0x9000,0x9000,0xfc00,0x9000,0x9000,0x9000,0x9c00,0x0000,0x0000, // u01fc\n  0x0000,0x0000,0x1000,0x2000,0x7000,0x2800,0x6800,0xb000,0xa000,0x7800,0x0000,0x0000, // u01fd\n  0x1000,0x2000,0x7400,0x8800,0x9800,0xa800,0xc800,0x8800,0x8800,0x7000,0x0000,0x0000, // u01fe\n  0x0000,0x0000,0x1000,0x2000,0x7400,0x9800,0xa800,0xc800,0x8800,0x7000,0x0000,0x0000, // u01ff\n  0x0000,0x0000,0x7000,0x8800,0x8000,0x7000,0x0800,0x0800,0x8800,0x7000,0x2000,0x4000, // u0218\n  0x0000,0x0000,0x0000,0x0000,0x7800,0x8000,0x7000,0x0800,0x0800,0xf000,0x2000,0x4000, // u0219\n  0x0000,0x0000,0xf800,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x3000,0x1000,0x2000, // u021a\n  0x0000,0x0000,0x2000,0x2000,0x7000,0x2000,0x2000,0x2000,0x2000,0x1800,0x0800,0x1000, // u021b\n  0x7000,0x0000,0x8800,0x8800,0x5000,0x5000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000, // u0232\n  0x0000,0x0000,0x7000,0x0000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x7000, // u0233\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x4800,0x3000, // u0237\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0x0800,0x0800,0x8800,0x7000,0x0000,0x0000, // u0254\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0xf800,0x0800,0x8800,0x7000,0x0000,0x0000, // u0258\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0x0800,0xf800,0x8800,0x7000,0x0000,0x0000, // u0259\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0x6000,0x8000,0x8800,0x7000,0x0000,0x0000, // u025b\n  0x0000,0x0000,0x0000,0x0000,0xf000,0x8800,0x8800,0x8800,0x8800,0xc800,0x4000,0x8000, // u0272\n  0x0000,0x0000,0x0000,0x0000,0xf800,0x0800,0x1000,0x3000,0x0800,0x0800,0x8800,0x7000, // u0292\n  0x1000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bb\n  0x1000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bc\n  0x2000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bd\n  0x2000,0x5000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02c6\n  0x5000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02c7\n  0x5000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02d8\n  0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02d9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x2000,0x1800, // u02db\n  0x2800,0x5000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02dc\n  0x2800,0x5000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02dd\n  0x4000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0300\n  0x1000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0301\n  0x2000,0x5000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0302\n  0x2800,0x5000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0303\n  0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0304\n  0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0305\n  0x5000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0306\n  0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0307\n  0x5000,0x5000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0308\n  0x2000,0x5000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030a\n  0x2800,0x5000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030b\n  0x5000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000, // u0329\n  0x4000,0x8000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0384\n  0x1000,0x2000,0x5000,0x5000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0385\n  0x4000,0x8000,0x7000,0x8800,0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x0000,0x0000, // u0386\n  0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0387\n  0x4000,0x8000,0xf800,0x8000,0x8000,0xf000,0x8000,0x8000,0x8000,0xf800,0x0000,0x0000, // u0388\n  0x4000,0x8000,0x8800,0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u0389\n  0x4000,0x8000,0x7000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u038a\n  0x4000,0x8000,0x7000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u038c\n  0x4000,0x8000,0x8800,0x8800,0x5000,0x5000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000, // u038e\n  0x4000,0x8000,0x7000,0x8800,0x8800,0x8800,0x8800,0x8800,0x5000,0xd800,0x0000,0x0000, // u038f\n  0x1000,0x2000,0x5000,0x5000,0x6000,0x2000,0x2000,0x2000,0x2000,0x1800,0x0000,0x0000, // u0390\n  0x0000,0x0000,0x7000,0x8800,0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x0000,0x0000, // u0391\n  0x0000,0x0000,0xf000,0x8800,0x8800,0xf000,0x8800,0x8800,0x8800,0xf000,0x0000,0x0000, // u0392\n  0x0000,0x0000,0xf800,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x0000,0x0000, // u0393\n  0x0000,0x0000,0x2000,0x2000,0x5000,0x5000,0x8800,0x8800,0x8800,0xf800,0x0000,0x0000, // u0394\n  0x0000,0x0000,0xf800,0x8000,0x8000,0xf000,0x8000,0x8000,0x8000,0xf800,0x0000,0x0000, // u0395\n  0x0000,0x0000,0xf800,0x0800,0x1000,0x2000,0x4000,0x8000,0x8000,0xf800,0x0000,0x0000, // u0396\n  0x0000,0x0000,0x8800,0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u0397\n  0x0000,0x0000,0x7000,0x8800,0x8800,0xa800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u0398\n  0x0000,0x0000,0x7000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u0399\n  0x0000,0x0000,0x8800,0x9000,0xa000,0xc000,0xc000,0xa000,0x9000,0x8800,0x0000,0x0000, // u039a\n  0x0000,0x0000,0x2000,0x2000,0x5000,0x5000,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u039b\n  0x0000,0x0000,0x8800,0xd800,0xa800,0xa800,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u039c\n  0x0000,0x0000,0x8800,0x8800,0xc800,0xa800,0x9800,0x8800,0x8800,0x8800,0x0000,0x0000, // u039d\n  0x0000,0x0000,0xf800,0x0000,0x0000,0x7000,0x0000,0x0000,0x0000,0xf800,0x0000,0x0000, // u039e\n  0x0000,0x0000,0x7000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u039f\n  0x0000,0x0000,0xf800,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u03a0\n  0x0000,0x0000,0xf000,0x8800,0x8800,0x8800,0xf000,0x8000,0x8000,0x8000,0x0000,0x0000, // u03a1\n  0x0000,0x0000,0xf800,0x4000,0x2000,0x1000,0x1000,0x2000,0x4000,0xf800,0x0000,0x0000, // u03a3\n  0x0000,0x0000,0xf800,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000, // u03a4\n  0x0000,0x0000,0x8800,0x8800,0x5000,0x5000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000, // u03a5\n  0x0000,0x0000,0x2000,0x7000,0xa800,0xa800,0xa800,0xa800,0x7000,0x2000,0x0000,0x0000, // u03a6\n  0x0000,0x0000,0x8800,0x8800,0x5000,0x2000,0x2000,0x5000,0x8800,0x8800,0x0000,0x0000, // u03a7\n  0x0000,0x0000,0xa800,0xa800,0xa800,0xa800,0xa800,0x7000,0x2000,0x2000,0x0000,0x0000, // u03a8\n  0x0000,0x0000,0x7000,0x8800,0x8800,0x8800,0x8800,0x8800,0x5000,0xd800,0x0000,0x0000, // u03a9\n  0x5000,0x5000,0x7000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u03aa\n  0x5000,0x5000,0x8800,0x8800,0x5000,0x5000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000, // u03ab\n  0x0000,0x0000,0x1000,0x2000,0x6800,0x9000,0x9000,0x9000,0x9000,0x6800,0x0000,0x0000, // u03ac\n  0x0000,0x0000,0x1000,0x2000,0x7000,0x8800,0x6000,0x8000,0x8800,0x7000,0x0000,0x0000, // u03ad\n  0x0000,0x0000,0x1000,0x2000,0xf000,0x8800,0x8800,0x8800,0x8800,0x8800,0x0800,0x0800, // u03ae\n  0x0000,0x0000,0x1000,0x2000,0x6000,0x2000,0x2000,0x2000,0x2000,0x1800,0x0000,0x0000, // u03af\n  0x1000,0x2000,0x5000,0x5000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u03b0\n  0x0000,0x0000,0x0000,0x0000,0x6800,0x9000,0x9000,0x9000,0x9000,0x6800,0x0000,0x0000, // u03b1\n  0x0000,0x0000,0xe000,0x9000,0x9000,0xf000,0x8800,0x8800,0x8800,0xf000,0x8000,0x8000, // u03b2\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0x8800,0x5000,0x5000,0x2000,0x2000,0x2000, // u03b3\n  0x0000,0x0000,0xf000,0x4000,0x2000,0x7000,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u03b4\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0x6000,0x8000,0x8800,0x7000,0x0000,0x0000, // u03b5\n  0x0000,0x0000,0xf800,0x1000,0x2000,0x4000,0x8000,0x8000,0x8000,0x7000,0x0800,0x1000, // u03b6\n  0x0000,0x0000,0x0000,0x0000,0xf000,0x8800,0x8800,0x8800,0x8800,0x8800,0x0800,0x0800, // u03b7\n  0x0000,0x0000,0x3000,0x4800,0x4800,0x7800,0x4800,0x4800,0x4800,0x3000,0x0000,0x0000, // u03b8\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x2000,0x2000,0x2000,0x2000,0x1800,0x0000,0x0000, // u03b9\n  0x0000,0x0000,0x0000,0x0000,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x0000,0x0000, // u03ba\n  0x0000,0x0000,0x4000,0x4000,0x2000,0x2000,0x5000,0x5000,0x8800,0x8800,0x0000,0x0000, // u03bb\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0x8800,0x8800,0x9800,0xe800,0x8000,0x8000, // u03bc\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0x5000,0x5000,0x2000,0x2000,0x0000,0x0000, // u03bd\n  0x0000,0x0000,0x7800,0x8000,0x8000,0x7000,0x8000,0x8000,0x8000,0x7000,0x0800,0x1000, // u03be\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u03bf\n  0x0000,0x0000,0x0000,0x0000,0xf800,0x8800,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u03c0\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0x8800,0x8800,0x8800,0xf000,0x8000,0x8000, // u03c1\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0x8000,0x8000,0x8000,0x7000,0x0800,0x1000, // u03c2\n  0x0000,0x0000,0x0000,0x0000,0x7800,0x9000,0x9000,0x9000,0x9000,0x6000,0x0000,0x0000, // u03c3\n  0x0000,0x0000,0x0000,0x0000,0xf800,0x2000,0x2000,0x2000,0x2000,0x1000,0x0000,0x0000, // u03c4\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u03c5\n  0x0000,0x0000,0x0000,0x0000,0x9000,0xa800,0xa800,0xa800,0xa800,0x7000,0x2000,0x2000, // u03c6\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0x5000,0x2000,0x2000,0x5000,0x8800,0x8800, // u03c7\n  0x0000,0x0000,0x0000,0x0000,0xa800,0xa800,0xa800,0xa800,0xa800,0x7000,0x2000,0x2000, // u03c8\n  0x0000,0x0000,0x0000,0x0000,0x5000,0x8800,0xa800,0xa800,0xa800,0x5000,0x0000,0x0000, // u03c9\n  0x0000,0x0000,0x5000,0x5000,0x6000,0x2000,0x2000,0x2000,0x2000,0x1800,0x0000,0x0000, // u03ca\n  0x0000,0x0000,0x5000,0x5000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u03cb\n  0x0000,0x0000,0x1000,0x2000,0x7000,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u03cc\n  0x0000,0x0000,0x1000,0x2000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u03cd\n  0x0000,0x0000,0x1000,0x2000,0x5000,0x8800,0xa800,0xa800,0xa800,0x5000,0x0000,0x0000, // u03ce\n  0x0000,0x0000,0x3000,0x4800,0x4800,0x3c00,0x0800,0xc800,0x4800,0x3000,0x0000,0x0000, // u03d1\n  0x0000,0x0000,0x0000,0x2000,0x7000,0xa800,0xa800,0xa800,0xa800,0x7000,0x2000,0x0000, // u03d5\n  0x0000,0x0000,0x0000,0x0000,0xc400,0x2800,0x1000,0x2000,0x5000,0x8c00,0x0000,0x0000, // u03f0\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0x8800,0x8800,0x8800,0xf000,0x8000,0x7000, // u03f1\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0x8000,0x8000,0x8800,0x7000,0x0000,0x0000, // u03f2\n  0x0000,0x0800,0x0800,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x4800,0x3000, // u03f3\n  0x0000,0x0000,0x7000,0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u03f4\n  0x0000,0x0000,0x0000,0x0000,0x7800,0x8000,0xf000,0x8000,0x8000,0x7800,0x0000,0x0000, // u03f5\n  0x0000,0x0000,0x0000,0x0000,0xf000,0x0800,0x7800,0x0800,0x0800,0xf000,0x0000,0x0000, // u03f6\n  0x4000,0x2000,0xf800,0x8000,0x8000,0xf000,0x8000,0x8000,0x8000,0xf800,0x0000,0x0000, // u0400\n  0x5000,0x5000,0xf800,0x8000,0x8000,0xf000,0x8000,0x8000,0x8000,0xf800,0x0000,0x0000, // u0401\n  0x0000,0x0000,0xe000,0x4000,0x4000,0x7000,0x4800,0x4800,0x4800,0x4800,0x0800,0x1000, // u0402\n  0x1000,0x2000,0xf800,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x0000,0x0000, // u0403\n  0x0000,0x0000,0x7000,0x8800,0x8000,0xf000,0x8000,0x8000,0x8800,0x7000,0x0000,0x0000, // u0404\n  0x0000,0x0000,0x7000,0x8800,0x8000,0x7000,0x0800,0x0800,0x8800,0x7000,0x0000,0x0000, // u0405\n  0x0000,0x0000,0x7000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u0406\n  0x5000,0x5000,0x7000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u0407\n  0x0000,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x9000,0x9000,0x6000,0x0000,0x0000, // u0408\n  0x0000,0x0000,0x6000,0xa000,0xb000,0xa800,0xa800,0xa800,0xa800,0xb000,0x0000,0x0000, // u0409\n  0x0000,0x0000,0xa000,0xa000,0xb000,0xe800,0xa800,0xa800,0xa800,0xb000,0x0000,0x0000, // u040a\n  0x0000,0x0000,0xe000,0x4000,0x4000,0x7000,0x4800,0x4800,0x4800,0x4800,0x0000,0x0000, // u040b\n  0x1000,0x2000,0x8800,0x9000,0xa000,0xc000,0xc000,0xa000,0x9000,0x8800,0x0000,0x0000, // u040c\n  0x4000,0x2000,0x8800,0x8800,0x9800,0xa800,0xc800,0x8800,0x8800,0x8800,0x0000,0x0000, // u040d\n  0x5000,0x2000,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x0800,0x7000,0x0000,0x0000, // u040e\n  0x0000,0x0000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0xf800,0x2000,0x2000, // u040f\n  0x0000,0x0000,0x7000,0x8800,0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x0000,0x0000, // u0410\n  0x0000,0x0000,0xf000,0x8000,0x8000,0xf000,0x8800,0x8800,0x8800,0xf000,0x0000,0x0000, // u0411\n  0x0000,0x0000,0xf000,0x8800,0x8800,0xf000,0x8800,0x8800,0x8800,0xf000,0x0000,0x0000, // u0412\n  0x0000,0x0000,0xf800,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x0000,0x0000, // u0413\n  0x0000,0x0000,0x3800,0x4800,0x4800,0x4800,0x4800,0x4800,0x4800,0xfc00,0x8400,0x0000, // u0414\n  0x0000,0x0000,0xf800,0x8000,0x8000,0xf000,0x8000,0x8000,0x8000,0xf800,0x0000,0x0000, // u0415\n  0x0000,0x0000,0xa800,0xa800,0xa800,0x7000,0x7000,0xa800,0xa800,0xa800,0x0000,0x0000, // u0416\n  0x0000,0x0000,0x7000,0x8800,0x0800,0x3000,0x0800,0x0800,0x8800,0x7000,0x0000,0x0000, // u0417\n  0x0000,0x0000,0x8800,0x8800,0x9800,0xa800,0xc800,0x8800,0x8800,0x8800,0x0000,0x0000, // u0418\n  0x5000,0x2000,0x8800,0x8800,0x9800,0xa800,0xc800,0x8800,0x8800,0x8800,0x0000,0x0000, // u0419\n  0x0000,0x0000,0x8800,0x9000,0xa000,0xc000,0xc000,0xa000,0x9000,0x8800,0x0000,0x0000, // u041a\n  0x0000,0x0000,0x3800,0x4800,0x4800,0x4800,0x4800,0x4800,0x4800,0x8800,0x0000,0x0000, // u041b\n  0x0000,0x0000,0x8800,0xd800,0xa800,0xa800,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u041c\n  0x0000,0x0000,0x8800,0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u041d\n  0x0000,0x0000,0x7000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u041e\n  0x0000,0x0000,0xf800,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u041f\n  0x0000,0x0000,0xf000,0x8800,0x8800,0x8800,0xf000,0x8000,0x8000,0x8000,0x0000,0x0000, // u0420\n  0x0000,0x0000,0x7000,0x8800,0x8000,0x8000,0x8000,0x8000,0x8800,0x7000,0x0000,0x0000, // u0421\n  0x0000,0x0000,0xf800,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000, // u0422\n  0x0000,0x0000,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x0800,0x7000,0x0000,0x0000, // u0423\n  0x0000,0x2000,0x7000,0xa800,0xa800,0xa800,0xa800,0xa800,0xa800,0x7000,0x2000,0x0000, // u0424\n  0x0000,0x0000,0x8800,0x8800,0x5000,0x2000,0x2000,0x5000,0x8800,0x8800,0x0000,0x0000, // u0425\n  0x0000,0x0000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7c00,0x0400,0x0400, // u0426\n  0x0000,0x0000,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x0800,0x0800,0x0000,0x0000, // u0427\n  0x0000,0x0000,0xa800,0xa800,0xa800,0xa800,0xa800,0xa800,0xa800,0x7800,0x0000,0x0000, // u0428\n  0x0000,0x0000,0xa800,0xa800,0xa800,0xa800,0xa800,0xa800,0xa800,0x7c00,0x0400,0x0400, // u0429\n  0x0000,0x0000,0xc000,0x4000,0x7000,0x4800,0x4800,0x4800,0x4800,0x7000,0x0000,0x0000, // u042a\n  0x0000,0x0000,0x8800,0x8800,0xc800,0xa800,0xa800,0xa800,0xa800,0xc800,0x0000,0x0000, // u042b\n  0x0000,0x0000,0x4000,0x4000,0x7000,0x4800,0x4800,0x4800,0x4800,0x7000,0x0000,0x0000, // u042c\n  0x0000,0x0000,0x7000,0x8800,0x0800,0x3800,0x0800,0x0800,0x8800,0x7000,0x0000,0x0000, // u042d\n  0x0000,0x0000,0x9000,0xa800,0xa800,0xa800,0xe800,0xa800,0xa800,0x9000,0x0000,0x0000, // u042e\n  0x0000,0x0000,0x7800,0x8800,0x8800,0x8800,0x7800,0x2800,0x4800,0x8800,0x0000,0x0000, // u042f\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x0800,0x7800,0x8800,0x8800,0x7800,0x0000,0x0000, // u0430\n  0x0000,0x0000,0x7000,0x8000,0xf000,0x8800,0x8800,0x8800,0x8800,0xf000,0x0000,0x0000, // u0431\n  0x0000,0x0000,0xe000,0x9000,0x9000,0xf000,0x8800,0x8800,0x8800,0xf000,0x0000,0x0000, // u0432\n  0x0000,0x0000,0x0000,0x0000,0xf800,0x8000,0x8000,0x8000,0x8000,0x8000,0x0000,0x0000, // u0433\n  0x0000,0x0000,0x0000,0x0000,0x7800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x7000, // u0434\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0xf800,0x8000,0x8000,0x7800,0x0000,0x0000, // u0435\n  0x0000,0x0000,0x0000,0x0000,0xa800,0xa800,0x7000,0xa800,0xa800,0xa800,0x0000,0x0000, // u0436\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0x3000,0x0800,0x8800,0x7000,0x0000,0x0000, // u0437\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0000,0x0000, // u0438\n  0x0000,0x0000,0x5000,0x2000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0000,0x0000, // u0439\n  0x0000,0x0000,0x0000,0x0000,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x0000,0x0000, // u043a\n  0x0000,0x0000,0x0000,0x0000,0x3800,0x4800,0x4800,0x4800,0x4800,0x8800,0x0000,0x0000, // u043b\n  0x0000,0x0000,0x0000,0x0000,0x8800,0xd800,0xa800,0x8800,0x8800,0x8800,0x0000,0x0000, // u043c\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x0000,0x0000, // u043d\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u043e\n  0x0000,0x0000,0x0000,0x0000,0xf800,0x8800,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u043f\n  0x0000,0x0000,0x0000,0x0000,0xf000,0x8800,0x8800,0x8800,0x8800,0xf000,0x8000,0x8000, // u0440\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0x8000,0x8000,0x8800,0x7000,0x0000,0x0000, // u0441\n  0x0000,0x0000,0x0000,0x0000,0xf800,0x2000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000, // u0442\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x7000, // u0443\n  0x0000,0x0000,0x0000,0x2000,0x7000,0xa800,0xa800,0xa800,0xa800,0x7000,0x2000,0x0000, // u0444\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x5000,0x2000,0x2000,0x5000,0x8800,0x0000,0x0000, // u0445\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7c00,0x0400,0x0400, // u0446\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0x8800,0x7800,0x0800,0x0800,0x0000,0x0000, // u0447\n  0x0000,0x0000,0x0000,0x0000,0xa800,0xa800,0xa800,0xa800,0xa800,0x7800,0x0000,0x0000, // u0448\n  0x0000,0x0000,0x0000,0x0000,0xa800,0xa800,0xa800,0xa800,0xa800,0x7c00,0x0400,0x0400, // u0449\n  0x0000,0x0000,0x0000,0x0000,0xc000,0x4000,0x7000,0x4800,0x4800,0x7000,0x0000,0x0000, // u044a\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0xc800,0xa800,0xa800,0xc800,0x0000,0x0000, // u044b\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x7000,0x4800,0x4800,0x7000,0x0000,0x0000, // u044c\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0x3800,0x0800,0x8800,0x7000,0x0000,0x0000, // u044d\n  0x0000,0x0000,0x0000,0x0000,0x9000,0xa800,0xa800,0xe800,0xa800,0x9000,0x0000,0x0000, // u044e\n  0x0000,0x0000,0x0000,0x0000,0x7800,0x8800,0x8800,0x7800,0x2800,0x4800,0x0000,0x0000, // u044f\n  0x0000,0x0000,0x4000,0x2000,0x7000,0x8800,0xf800,0x8000,0x8000,0x7800,0x0000,0x0000, // u0450\n  0x0000,0x0000,0x5000,0x5000,0x7000,0x8800,0xf800,0x8000,0x8000,0x7800,0x0000,0x0000, // u0451\n  0x0000,0x0000,0x4000,0xf000,0x4000,0x7000,0x4800,0x4800,0x4800,0x4800,0x0800,0x1000, // u0452\n  0x0000,0x0000,0x1000,0x2000,0xf800,0x8000,0x8000,0x8000,0x8000,0x8000,0x0000,0x0000, // u0453\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0xe000,0x8000,0x8800,0x7000,0x0000,0x0000, // u0454\n  0x0000,0x0000,0x0000,0x0000,0x7800,0x8000,0x7000,0x0800,0x0800,0xf000,0x0000,0x0000, // u0455\n  0x0000,0x2000,0x2000,0x0000,0x6000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u0456\n  0x0000,0x0000,0x5000,0x5000,0x6000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u0457\n  0x0000,0x0800,0x0800,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x4800,0x3000, // u0458\n  0x0000,0x0000,0x0000,0x0000,0x6000,0xa000,0xb000,0xa800,0xa800,0xb000,0x0000,0x0000, // u0459\n  0x0000,0x0000,0x0000,0x0000,0xa000,0xa000,0xf000,0xa800,0xa800,0xb000,0x0000,0x0000, // u045a\n  0x0000,0x0000,0x4000,0xf000,0x4000,0x7000,0x4800,0x4800,0x4800,0x4800,0x0000,0x0000, // u045b\n  0x0000,0x0000,0x0800,0x1000,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x0000,0x0000, // u045c\n  0x0000,0x0000,0x4000,0x2000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0000,0x0000, // u045d\n  0x0000,0x0000,0x5000,0x2000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x7000, // u045e\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0x8800,0x8800,0x8800,0xf800,0x2000,0x2000, // u045f\n  0x0000,0x0000,0x4000,0xf000,0x4000,0x7000,0x4800,0x4800,0x4800,0x7000,0x0000,0x0000, // u0462\n  0x0000,0x0000,0x4000,0x4000,0xe000,0x4000,0x7000,0x4800,0x4800,0x7000,0x0000,0x0000, // u0463\n  0x0000,0x0000,0xf800,0x8800,0x5000,0x2000,0x7000,0xa800,0xa800,0xa800,0x0000,0x0000, // u046a\n  0x0000,0x0000,0x0000,0x0000,0xf800,0x5000,0x2000,0x7000,0xa800,0xa800,0x0000,0x0000, // u046b\n  0x0800,0x0800,0xf800,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x0000,0x0000, // u0490\n  0x0000,0x0000,0x0800,0x0800,0xf800,0x8000,0x8000,0x8000,0x8000,0x8000,0x0000,0x0000, // u0491\n  0x0000,0x0000,0x7c00,0x4000,0x4000,0x4000,0xf000,0x4000,0x4000,0x4000,0x0000,0x0000, // u0492\n  0x0000,0x0000,0x0000,0x0000,0x7800,0x4000,0x4000,0xf000,0x4000,0x4000,0x0000,0x0000, // u0493\n  0x0000,0x0000,0xf800,0x8000,0x8000,0x8000,0xf000,0x8800,0x8800,0x8800,0x0800,0x1000, // u0494\n  0x0000,0x0000,0x0000,0x0000,0xf800,0x8000,0x8000,0xe000,0x9000,0x9000,0x1000,0x2000, // u0495\n  0x0000,0x0000,0xa800,0xa800,0xa800,0x7000,0x7000,0xa800,0xa800,0xac00,0x0400,0x0400, // u0496\n  0x0000,0x0000,0x0000,0x0000,0xa800,0xa800,0x7000,0xa800,0xa800,0xac00,0x0400,0x0400, // u0497\n  0x0000,0x0000,0x7000,0x8800,0x0800,0x3000,0x0800,0x0800,0x8800,0x7000,0x2000,0x2000, // u0498\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0x3000,0x0800,0x8800,0x7000,0x2000,0x2000, // u0499\n  0x0000,0x0000,0x8800,0x9000,0xa000,0xc000,0xc000,0xa000,0x9000,0x8c00,0x0400,0x0400, // u049a\n  0x0000,0x0000,0x0000,0x0000,0x4800,0x5000,0x6000,0x6000,0x5000,0x4c00,0x0400,0x0400, // u049b\n  0x0000,0x0000,0x8400,0xa800,0xb000,0xe000,0xe000,0xb000,0xa800,0x8400,0x0000,0x0000, // u049c\n  0x0000,0x0000,0x0000,0x0000,0xa800,0xb000,0xe000,0xe000,0xb000,0xa800,0x0000,0x0000, // u049d\n  0x0000,0x0000,0xc400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x0000,0x0000, // u04a0\n  0x0000,0x0000,0x0000,0x0000,0xc800,0x5000,0x6000,0x6000,0x5000,0x4800,0x0000,0x0000, // u04a1\n  0x0000,0x0000,0x8800,0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x8c00,0x0400,0x0400, // u04a2\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0xf800,0x8800,0x8800,0x8c00,0x0400,0x0400, // u04a3\n  0x0000,0x0000,0x9c00,0x9000,0x9000,0xf000,0x9000,0x9000,0x9000,0x9000,0x0000,0x0000, // u04a4\n  0x0000,0x0000,0x0000,0x0000,0x9c00,0x9000,0xf000,0x9000,0x9000,0x9000,0x0000,0x0000, // u04a5\n  0x0000,0x0000,0x7000,0x8800,0x8000,0x8000,0x8000,0x8000,0x8800,0x7000,0x2000,0x2000, // u04aa\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0x8000,0x8000,0x8800,0x7000,0x2000,0x2000, // u04ab\n  0x0000,0x0000,0x8800,0x8800,0x5000,0x5000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000, // u04ae\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0x8800,0x5000,0x5000,0x2000,0x2000,0x2000, // u04af\n  0x0000,0x0000,0x8800,0x8800,0x5000,0x5000,0x2000,0x7000,0x2000,0x2000,0x0000,0x0000, // u04b0\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0x8800,0x5000,0x5000,0x2000,0x7000,0x2000, // u04b1\n  0x0000,0x0000,0x8800,0x8800,0x5000,0x2000,0x2000,0x5000,0x8800,0x8c00,0x0400,0x0400, // u04b2\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x5000,0x2000,0x2000,0x5000,0x8c00,0x0400,0x0400, // u04b3\n  0x0000,0x0000,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x0800,0x0c00,0x0400,0x0400, // u04b6\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0x8800,0x7800,0x0800,0x0c00,0x0400,0x0400, // u04b7\n  0x0000,0x0000,0x8800,0x8800,0xa800,0xa800,0x7800,0x2800,0x2800,0x0800,0x0000,0x0000, // u04b8\n  0x0000,0x0000,0x0000,0x0000,0x8800,0xa800,0xa800,0x7800,0x2800,0x0800,0x0000,0x0000, // u04b9\n  0x0000,0x0000,0x8000,0x8000,0x8000,0xf000,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u04ba\n  0x0000,0x0000,0x0000,0x0000,0x8000,0x8000,0xf000,0x8800,0x8800,0x8800,0x0000,0x0000, // u04bb\n  0x0000,0x0000,0x7000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u04c0\n  0x5000,0x2000,0xa800,0xa800,0xa800,0x7000,0x7000,0xa800,0xa800,0xa800,0x0000,0x0000, // u04c1\n  0x0000,0x0000,0x5000,0x2000,0xa800,0xa800,0x7000,0xa800,0xa800,0xa800,0x0000,0x0000, // u04c2\n  0x0000,0x0000,0x6000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u04cf\n  0x5000,0x2000,0x7000,0x8800,0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x0000,0x0000, // u04d0\n  0x0000,0x0000,0x5000,0x2000,0x7000,0x0800,0x7800,0x8800,0x8800,0x7800,0x0000,0x0000, // u04d1\n  0x5000,0x5000,0x7000,0x8800,0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x0000,0x0000, // u04d2\n  0x0000,0x0000,0x5000,0x5000,0x7000,0x0800,0x7800,0x8800,0x8800,0x7800,0x0000,0x0000, // u04d3\n  0x0000,0x0000,0x7c00,0x9000,0x9000,0xfc00,0x9000,0x9000,0x9000,0x9c00,0x0000,0x0000, // u04d4\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x2800,0x6800,0xb000,0xa000,0x7800,0x0000,0x0000, // u04d5\n  0x5000,0x2000,0xf800,0x8000,0x8000,0xf000,0x8000,0x8000,0x8000,0xf800,0x0000,0x0000, // u04d6\n  0x0000,0x0000,0x5000,0x2000,0x7000,0x8800,0xf800,0x8000,0x8000,0x7800,0x0000,0x0000, // u04d7\n  0x0000,0x0000,0x7000,0x8800,0x0800,0x0800,0xf800,0x8800,0x8800,0x7000,0x0000,0x0000, // u04d8\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0x0800,0xf800,0x8800,0x7000,0x0000,0x0000, // u04d9\n  0x5000,0x5000,0x7000,0x8800,0x0800,0x0800,0xf800,0x8800,0x8800,0x7000,0x0000,0x0000, // u04da\n  0x0000,0x0000,0x5000,0x5000,0x7000,0x8800,0x0800,0xf800,0x8800,0x7000,0x0000,0x0000, // u04db\n  0x5000,0x5000,0xa800,0xa800,0xa800,0x7000,0x7000,0xa800,0xa800,0xa800,0x0000,0x0000, // u04dc\n  0x0000,0x0000,0x5000,0x5000,0xa800,0xa800,0x7000,0xa800,0xa800,0xa800,0x0000,0x0000, // u04dd\n  0x5000,0x5000,0x7000,0x8800,0x0800,0x3000,0x0800,0x0800,0x8800,0x7000,0x0000,0x0000, // u04de\n  0x0000,0x0000,0x5000,0x5000,0x7000,0x8800,0x3000,0x0800,0x8800,0x7000,0x0000,0x0000, // u04df\n  0x7000,0x0000,0x8800,0x8800,0x9800,0xa800,0xc800,0x8800,0x8800,0x8800,0x0000,0x0000, // u04e2\n  0x0000,0x0000,0x7000,0x0000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0000,0x0000, // u04e3\n  0x5000,0x5000,0x8800,0x8800,0x9800,0xa800,0xc800,0x8800,0x8800,0x8800,0x0000,0x0000, // u04e4\n  0x0000,0x0000,0x5000,0x5000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0000,0x0000, // u04e5\n  0x5000,0x5000,0x7000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u04e6\n  0x0000,0x0000,0x5000,0x5000,0x7000,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u04e7\n  0x0000,0x0000,0x7000,0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u04e8\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0xf800,0x8800,0x8800,0x7000,0x0000,0x0000, // u04e9\n  0x5000,0x5000,0x7000,0x8800,0x8800,0x8800,0xf800,0x8800,0x8800,0x7000,0x0000,0x0000, // u04ea\n  0x0000,0x0000,0x5000,0x5000,0x7000,0x8800,0xf800,0x8800,0x8800,0x7000,0x0000,0x0000, // u04eb\n  0x5000,0x5000,0x7000,0x8800,0x0800,0x3800,0x0800,0x0800,0x8800,0x7000,0x0000,0x0000, // u04ec\n  0x0000,0x0000,0x5000,0x5000,0x7000,0x8800,0x3800,0x0800,0x8800,0x7000,0x0000,0x0000, // u04ed\n  0x7000,0x0000,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x0800,0x7000,0x0000,0x0000, // u04ee\n  0x0000,0x0000,0x7000,0x0000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x7000, // u04ef\n  0x5000,0x5000,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x0800,0x7000,0x0000,0x0000, // u04f0\n  0x0000,0x0000,0x5000,0x5000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x7000, // u04f1\n  0x2800,0x5000,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x0800,0x7000,0x0000,0x0000, // u04f2\n  0x0000,0x0000,0x2800,0x5000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x7000, // u04f3\n  0x5000,0x5000,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x0800,0x0800,0x0000,0x0000, // u04f4\n  0x0000,0x0000,0x5000,0x5000,0x8800,0x8800,0x8800,0x7800,0x0800,0x0800,0x0000,0x0000, // u04f5\n  0x5000,0x5000,0x8800,0x8800,0xc800,0xa800,0xa800,0xa800,0xa800,0xc800,0x0000,0x0000, // u04f8\n  0x0000,0x0000,0x5000,0x5000,0x8800,0x8800,0xc800,0xa800,0xa800,0xc800,0x0000,0x0000, // u04f9\n  0x0000,0x0000,0x8800,0x8800,0x5000,0x2000,0x5000,0x9000,0x8800,0x8800,0x0000,0x0000, // u05d0\n  0x0000,0x0000,0xf000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xfc00,0x0000,0x0000, // u05d1\n  0x0000,0x0000,0x6000,0x1000,0x1000,0x1000,0x1000,0x3000,0x4800,0x8800,0x0000,0x0000, // u05d2\n  0x0000,0x0000,0xfc00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,0x0000, // u05d3\n  0x0000,0x0000,0xf000,0x0800,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u05d4\n  0x0000,0x0000,0xc000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000, // u05d5\n  0x0000,0x0000,0x7800,0x1000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000, // u05d6\n  0x0000,0x0000,0xf000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u05d7\n  0x0000,0x0000,0x9000,0x9800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u05d8\n  0x0000,0x0000,0xc000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d9\n  0x0000,0x0000,0xf000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800, // u05da\n  0x0000,0x0000,0xf000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xf000,0x0000,0x0000, // u05db\n  0x8000,0x8000,0xf800,0x0800,0x0800,0x0800,0x1000,0x2000,0x2000,0x2000,0x0000,0x0000, // u05dc\n  0x0000,0x0000,0xf000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0xf800,0x0000,0x0000, // u05dd\n  0x0000,0x0000,0xb000,0xc800,0x8800,0x8800,0x8800,0x8800,0x8800,0x9800,0x0000,0x0000, // u05de\n  0x0000,0x0000,0xc000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u05df\n  0x0000,0x0000,0x6000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x7000,0x0000,0x0000, // u05e0\n  0x0000,0x0000,0xf000,0x4800,0x4800,0x4800,0x4800,0x4800,0x4800,0x3000,0x0000,0x0000, // u05e1\n  0x0000,0x0000,0x8800,0x8800,0x8800,0x4800,0x4800,0x4800,0x3000,0xc000,0x0000,0x0000, // u05e2\n  0x0000,0x0000,0xf000,0x8800,0x8800,0x4800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800, // u05e3\n  0x0000,0x0000,0xf000,0x8800,0x8800,0x4800,0x0800,0x0800,0x0800,0xf000,0x0000,0x0000, // u05e4\n  0x0000,0x0000,0x8800,0x8800,0x4800,0x5000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u05e5\n  0x0000,0x0000,0x8800,0x8800,0x4800,0x5000,0x2000,0x2000,0x1000,0xf000,0x0000,0x0000, // u05e6\n  0x0000,0x0000,0xf800,0x0800,0x8800,0x8800,0x9000,0xa000,0xa000,0xa000,0x8000,0x8000, // u05e7\n  0x0000,0x0000,0xf000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,0x0000, // u05e8\n  0x0000,0x0000,0xa800,0xa800,0xa800,0xa800,0xc800,0x8800,0x8800,0xf000,0x0000,0x0000, // u05e9\n  0x0000,0x0000,0xf000,0x4800,0x4800,0x4800,0x4800,0x4800,0x4800,0x8800,0x0000,0x0000, // u05ea\n  0x0000,0x0000,0xe000,0x9000,0x8800,0x8800,0x8800,0x8800,0x9000,0xe000,0x2000,0x2000, // u1e0c\n  0x0000,0x0000,0x0800,0x0800,0x7800,0x8800,0x8800,0x8800,0x8800,0x7800,0x2000,0x2000, // u1e0d\n  0x0000,0x0000,0x8800,0x9000,0xa000,0xc000,0xc000,0xa000,0x9000,0x8800,0x0000,0x7000, // u1e34\n  0x0000,0x0000,0x4000,0x4000,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x0000,0x7000, // u1e35\n  0x0000,0x0000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0xf800,0x2000,0x2000, // u1e36\n  0x0000,0x0000,0x6000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x7000,0x2000,0x2000, // u1e37\n  0x2000,0x2000,0x8800,0xd800,0xa800,0xa800,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u1e40\n  0x0000,0x0000,0x2000,0x2000,0xf000,0xa800,0xa800,0xa800,0xa800,0xa800,0x0000,0x0000, // u1e41\n  0x0000,0x0000,0x8800,0xd800,0xa800,0xa800,0x8800,0x8800,0x8800,0x8800,0x2000,0x2000, // u1e42\n  0x0000,0x0000,0x0000,0x0000,0xf000,0xa800,0xa800,0xa800,0xa800,0xa800,0x1000,0x1000, // u1e43\n  0x2000,0x2000,0x8800,0x8800,0xc800,0xa800,0x9800,0x8800,0x8800,0x8800,0x0000,0x0000, // u1e44\n  0x0000,0x0000,0x2000,0x2000,0xf000,0x8800,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u1e45\n  0x0000,0x0000,0x8800,0x8800,0xc800,0xa800,0x9800,0x8800,0x8800,0x8800,0x2000,0x2000, // u1e46\n  0x0000,0x0000,0x0000,0x0000,0xf000,0x8800,0x8800,0x8800,0x8800,0x8800,0x2000,0x2000, // u1e47\n  0x0000,0x0000,0xf800,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x1000,0x1000, // u1e6c\n  0x0000,0x0000,0x2000,0x2000,0x7000,0x2000,0x2000,0x2000,0x2000,0x1800,0x1000,0x1000, // u1e6d\n  0x0000,0x0000,0xf800,0x8000,0x8000,0xf000,0x8000,0x8000,0x8000,0xf800,0x2000,0x2000, // u1eb8\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0xf800,0x8000,0x8000,0x7800,0x2000,0x2000, // u1eb9\n  0x2800,0x5000,0xf800,0x8000,0x8000,0xf000,0x8000,0x8000,0x8000,0xf800,0x0000,0x0000, // u1ebc\n  0x0000,0x0000,0x2800,0x5000,0x7000,0x8800,0xf800,0x8000,0x8000,0x7800,0x0000,0x0000, // u1ebd\n  0x0000,0x0000,0x7000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x7000,0x2000,0x2000, // u1eca\n  0x0000,0x2000,0x2000,0x0000,0x6000,0x2000,0x2000,0x2000,0x2000,0x7000,0x2000,0x2000, // u1ecb\n  0x0000,0x0000,0x7000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x2000,0x2000, // u1ecc\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0x8800,0x8800,0x8800,0x7000,0x2000,0x2000, // u1ecd\n  0x0000,0x0000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x2000,0x2000, // u1ee4\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x2000,0x2000, // u1ee5\n  0x2800,0x5000,0x8800,0x8800,0x5000,0x5000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000, // u1ef8\n  0x0000,0x0000,0x2800,0x5000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7800,0x0800,0x7000, // u1ef9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2001\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2002\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2003\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2004\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2005\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2006\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2007\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2008\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2009\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7800,0x0000,0x0000,0x0000,0x0000,0x0000, // u2010\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7800,0x0000,0x0000,0x0000,0x0000,0x0000, // u2011\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000, // u2012\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000, // u2013\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000, // u2014\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000, // u2015\n  0x0000,0x0000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x0000,0x0000, // u2016\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0x0000,0xf800, // u2017\n  0x0000,0x1000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2018\n  0x0000,0x2000,0x2000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2019\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x4000,0x0000, // u201a\n  0x0000,0x2000,0x2000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201b\n  0x0000,0x2800,0x5000,0x5000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201c\n  0x0000,0x2800,0x2800,0x5000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x5000,0x5000,0xa000,0x0000, // u201e\n  0x0000,0xa000,0xa000,0x5000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201f\n  0x0000,0x0000,0x2000,0x7000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2020\n  0x0000,0x0000,0x2000,0x7000,0x2000,0x2000,0x2000,0x2000,0x7000,0x2000,0x0000,0x0000, // u2021\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x7800,0x7800,0x3000,0x0000,0x0000,0x0000,0x0000, // u2022\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xa800,0xa800,0x0000,0x0000, // u2026\n  0x0000,0x0000,0x4400,0xa800,0x5000,0x2000,0x4000,0xa800,0x5400,0x2800,0x0000,0x0000, // u2030\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2032\n  0x0000,0x5000,0x5000,0x5000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2033\n  0x0000,0x0000,0x0000,0x0800,0x1000,0x2000,0x4000,0x2000,0x1000,0x0800,0x0000,0x0000, // u2039\n  0x0000,0x0000,0x0000,0x4000,0x2000,0x1000,0x0800,0x1000,0x2000,0x4000,0x0000,0x0000, // u203a\n  0x0000,0x0000,0x5000,0x5000,0x5000,0x5000,0x5000,0x0000,0x5000,0x5000,0x0000,0x0000, // u203c\n  0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u203e\n  0x0000,0x3000,0x4800,0x4800,0x4800,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2070\n  0x2000,0x0000,0x6000,0x2000,0x2000,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2071\n  0x0000,0x0800,0x1800,0x2800,0x7800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2074\n  0x0000,0x7000,0x4000,0x7000,0x0800,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2075\n  0x0000,0x3000,0x4000,0x7000,0x4800,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2076\n  0x0000,0x7800,0x0800,0x1000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2077\n  0x0000,0x3000,0x4800,0x3000,0x4800,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2078\n  0x0000,0x3000,0x4800,0x3800,0x0800,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2079\n  0x0000,0x2000,0x2000,0xf800,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207a\n  0x0000,0x0000,0x0000,0x7800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207b\n  0x0000,0x0000,0x7800,0x0000,0x7800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207c\n  0x0000,0x1000,0x2000,0x2000,0x2000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207d\n  0x0000,0x2000,0x1000,0x1000,0x1000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207e\n  0x0000,0x7000,0x4800,0x4800,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x4800,0x4800,0x4800,0x3000,0x0000,0x0000, // u2080\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x3000,0x1000,0x1000,0x3800,0x0000,0x0000, // u2081\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x4800,0x1000,0x2000,0x7800,0x0000,0x0000, // u2082\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x0800,0x3000,0x0800,0x7000,0x0000,0x0000, // u2083\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x1800,0x2800,0x7800,0x0800,0x0000,0x0000, // u2084\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x4000,0x7000,0x0800,0x7000,0x0000,0x0000, // u2085\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x4000,0x7000,0x4800,0x3000,0x0000,0x0000, // u2086\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7800,0x0800,0x1000,0x2000,0x2000,0x0000,0x0000, // u2087\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x4800,0x3000,0x4800,0x3000,0x0000,0x0000, // u2088\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x4800,0x3800,0x0800,0x3000,0x0000,0x0000, // u2089\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0xf800,0x2000,0x2000,0x0000,0x0000, // u208a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7800,0x0000,0x0000,0x0000,0x0000, // u208b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7800,0x0000,0x7800,0x0000,0x0000,0x0000, // u208c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x2000,0x2000,0x2000,0x1000,0x0000,0x0000, // u208d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x1000,0x1000,0x1000,0x2000,0x0000,0x0000, // u208e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x0800,0x3800,0x4800,0x3800,0x0000,0x0000, // u2090\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x4800,0x7800,0x4000,0x3800,0x0000,0x0000, // u2091\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x4800,0x4800,0x4800,0x3000,0x0000,0x0000, // u2092\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x8800,0x5000,0x2000,0x5000,0x8800,0x0000,0x0000, // u2093\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x0800,0x7800,0x4800,0x3000,0x0000,0x0000, // u2094\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x7000,0x4800,0x4800,0x4800,0x4800,0x0000,0x0000, // u2095\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4800,0x5000,0x6000,0x5000,0x4800,0x0000,0x0000, // u2096\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x2000,0x2000,0x2000,0x2000,0x7000,0x0000,0x0000, // u2097\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xf000,0xa800,0xa800,0xa800,0xa800,0x0000,0x0000, // u2098\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x4800,0x4800,0x4800,0x7000,0x4000,0x4000, // u209a\n  0x0000,0x0000,0xc000,0xa000,0xa000,0xc800,0x9c00,0x8800,0x8800,0x8400,0x0000,0x0000, // u20a7\n  0x0000,0x0000,0xc800,0xa800,0xa800,0x8800,0x8800,0xa800,0xa800,0xb000,0x0000,0x0000, // u20aa\n  0x0000,0x0000,0x0000,0x3800,0x4400,0xf000,0x4000,0xf000,0x4400,0x3800,0x0000,0x0000, // u20ac\n  0x0000,0x0000,0xf800,0x2000,0x3000,0x6000,0x3000,0x6000,0x2000,0x2000,0x0000,0x0000, // u20ae\n  0x0000,0x0000,0x7000,0xa800,0xa000,0xa000,0xa000,0xa000,0xa800,0x7000,0x0000,0x0000, // u2102\n  0x0000,0x0000,0x8000,0x8000,0xf000,0x8800,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u210e\n  0x0000,0x0000,0x4000,0xf000,0x4000,0x7000,0x4800,0x4800,0x4800,0x4800,0x0000,0x0000, // u210f\n  0x0000,0x0000,0x8800,0xc800,0xa800,0xd800,0xa800,0x9800,0x8800,0x8800,0x0000,0x0000, // u2115\n  0x0000,0x0000,0x9400,0x9400,0xd000,0xf000,0xf000,0xb400,0x9000,0x9400,0x0000,0x0000, // u2116\n  0x0000,0x0000,0x7000,0xc800,0xa800,0xa800,0xa800,0xa800,0xa800,0x7000,0x1800,0x0000, // u211a\n  0x0000,0x0000,0xf000,0xa800,0xa800,0xa800,0xb000,0xb000,0xa800,0xe400,0x0000,0x0000, // u211d\n  0x0000,0x0000,0xf400,0x5c00,0x5400,0x5400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2122\n  0x0000,0x0000,0xf800,0x1800,0x2800,0x5000,0xa000,0xc000,0x8000,0xf800,0x0000,0x0000, // u2124\n  0x0000,0x0000,0x7000,0x8800,0x8800,0x8800,0x8800,0x8800,0x5000,0xd800,0x0000,0x0000, // u2126\n  0x0000,0x0000,0x4800,0x4800,0x2400,0x6800,0x9000,0x9000,0x8800,0x4800,0x0000,0x0000, // u2135\n  0x0000,0x0000,0x0000,0x2000,0x6000,0xfc00,0x6000,0x2000,0x0000,0x0000,0x0000,0x0000, // u2190\n  0x0000,0x0000,0x2000,0x7000,0xf800,0x2000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2191\n  0x0000,0x0000,0x0000,0x1000,0x1800,0xfc00,0x1800,0x1000,0x0000,0x0000,0x0000,0x0000, // u2192\n  0x0000,0x0000,0x2000,0x2000,0x2000,0x2000,0x2000,0xf800,0x7000,0x2000,0x0000,0x0000, // u2193\n  0x0000,0x0000,0x0000,0x4800,0xcc00,0xfc00,0xcc00,0x4800,0x0000,0x0000,0x0000,0x0000, // u2194\n  0x0000,0x0000,0x2000,0x7000,0xf800,0x2000,0x2000,0xf800,0x7000,0x2000,0x0000,0x0000, // u2195\n  0x0000,0x0000,0x0000,0x2400,0x6400,0xfc00,0x6400,0x2400,0x0000,0x0000,0x0000,0x0000, // u21a4\n  0x0000,0x0000,0x0000,0x9000,0x9800,0xfc00,0x9800,0x9000,0x0000,0x0000,0x0000,0x0000, // u21a6\n  0x0000,0x0000,0x2000,0x7000,0xf800,0x2000,0xf800,0x7000,0x2000,0xf800,0x0000,0x0000, // u21a8\n  0x0000,0x0000,0x0800,0x0800,0x0800,0x2800,0x6800,0xf800,0x6000,0x2000,0x0000,0x0000, // u21b5\n  0x0000,0x0000,0xf000,0x3000,0x5000,0x9400,0x8400,0x8400,0x8400,0x7800,0x0000,0x0000, // u21bb\n  0x0000,0x0000,0x2000,0x4000,0xfc00,0x0000,0xfc00,0x0800,0x1000,0x0000,0x0000,0x0000, // u21cb\n  0x0000,0x0000,0x1000,0x0800,0xfc00,0x0000,0xfc00,0x4000,0x2000,0x0000,0x0000,0x0000, // u21cc\n  0x0000,0x0000,0x0000,0x2000,0x7c00,0xe000,0x7c00,0x2000,0x0000,0x0000,0x0000,0x0000, // u21d0\n  0x0000,0x0000,0x2000,0x7000,0xf800,0x5000,0x5000,0x5000,0x5000,0x5000,0x0000,0x0000, // u21d1\n  0x0000,0x0000,0x0000,0x1000,0xf800,0x1c00,0xf800,0x1000,0x0000,0x0000,0x0000,0x0000, // u21d2\n  0x0000,0x0000,0x5000,0x5000,0x5000,0x5000,0x5000,0xf800,0x7000,0x2000,0x0000,0x0000, // u21d3\n  0x0000,0x0000,0x0000,0x4800,0xfc00,0xcc00,0xfc00,0x4800,0x0000,0x0000,0x0000,0x0000, // u21d4\n  0x0000,0x0000,0x2000,0x7000,0xf800,0x5000,0x5000,0xf800,0x7000,0x2000,0x0000,0x0000, // u21d5\n  0x0000,0x0000,0x8800,0x8800,0xf800,0x5000,0x5000,0x5000,0x2000,0x2000,0x0000,0x0000, // u2200\n  0x0000,0x0000,0x0000,0xf800,0x0800,0x0800,0xf800,0x0800,0x0800,0xf800,0x0000,0x0000, // u2203\n  0x0000,0x0000,0x1000,0xf800,0x2800,0x2800,0xf800,0x4800,0x4800,0xf800,0x8000,0x0000, // u2204\n  0x0000,0x0000,0x0800,0x7000,0x9800,0xa800,0xa800,0xc800,0x7000,0x8000,0x0000,0x0000, // u2205\n  0x0000,0x0000,0x2000,0x2000,0x5000,0x5000,0x8800,0x8800,0x8800,0xf800,0x0000,0x0000, // u2206\n  0x0000,0x0000,0xf800,0x8800,0x8800,0x8800,0x5000,0x5000,0x2000,0x2000,0x0000,0x0000, // u2207\n  0x0000,0x0000,0x0000,0x3800,0x4000,0x8000,0xf800,0x8000,0x4000,0x3800,0x0000,0x0000, // u2208\n  0x0000,0x0000,0x0800,0x3800,0x5000,0x9000,0xf800,0xa000,0x6000,0x7800,0x4000,0x0000, // u2209\n  0x0000,0x0000,0x0000,0x0000,0x7800,0x8000,0xf800,0x8000,0x7800,0x0000,0x0000,0x0000, // u220a\n  0x0000,0x0000,0x0000,0xe000,0x1000,0x0800,0xf800,0x0800,0x1000,0xe000,0x0000,0x0000, // u220b\n  0x0000,0x0000,0x8000,0xe000,0x5000,0x4800,0xf800,0x2800,0x3000,0xf000,0x1000,0x0000, // u220c\n  0x0000,0x0000,0x0000,0x0000,0xf000,0x0800,0xf800,0x0800,0xf000,0x0000,0x0000,0x0000, // u220d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000, // u2212\n  0x0000,0x0000,0x0000,0xf800,0x0000,0x2000,0x2000,0xf800,0x2000,0x2000,0x0000,0x0000, // u2213\n  0x0000,0x0000,0x2000,0x2000,0x0000,0x2000,0x2000,0xf800,0x2000,0x2000,0x0000,0x0000, // u2214\n  0x0000,0x0000,0x0000,0x0000,0x0800,0x1000,0x2000,0x4000,0x8000,0x0000,0x0000,0x0000, // u2215\n  0x0000,0x0000,0x0000,0x0000,0x8000,0x4000,0x2000,0x1000,0x0800,0x0000,0x0000,0x0000, // u2216\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x7800,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2219\n  0x0000,0x0c00,0x0800,0x0800,0x0800,0x8800,0x8800,0x4800,0x2800,0x1800,0x0000,0x0000, // u221a\n  0x0000,0x0000,0x0000,0x5000,0xa800,0xa800,0xa800,0x5000,0x0000,0x0000,0x0000,0x0000, // u221e\n  0x0000,0x0000,0x0000,0x8000,0x8000,0x8000,0x8000,0xf800,0x0000,0x0000,0x0000,0x0000, // u221f\n  0x0000,0x0000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x0000,0x0000, // u2225\n  0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x5000,0x5000,0x8800,0x8800,0x0000,0x0000, // u2227\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0x5000,0x5000,0x2000,0x2000,0x0000,0x0000, // u2228\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x8800,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u2229\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u222a\n  0x0000,0x0000,0x0000,0x0000,0x6800,0xb000,0x0000,0x6800,0xb000,0x0000,0x0000,0x0000, // u2248\n  0x0000,0x0000,0x0000,0x0800,0xf800,0x2000,0x4000,0xf800,0x8000,0x0000,0x0000,0x0000, // u2260\n  0x0000,0x0000,0x0000,0x0000,0xf800,0x0000,0xf800,0x0000,0xf800,0x0000,0x0000,0x0000, // u2261\n  0x0000,0x1000,0x2000,0x4000,0x8000,0x4000,0x2000,0x1000,0x0000,0xf800,0x0000,0x0000, // u2264\n  0x0000,0x4000,0x2000,0x1000,0x0800,0x1000,0x2000,0x4000,0x0000,0xf800,0x0000,0x0000, // u2265\n  0x0000,0x0000,0x0000,0x1400,0x2800,0x5000,0xa000,0x5000,0x2800,0x1400,0x0000,0x0000, // u226a\n  0x0000,0x0000,0x0000,0xa000,0x5000,0x2800,0x1400,0x2800,0x5000,0xa000,0x0000,0x0000, // u226b\n  0x0000,0x0000,0x0000,0x7800,0x8000,0x8000,0x8000,0x8000,0x7800,0x0000,0x0000,0x0000, // u2282\n  0x0000,0x0000,0x0000,0xf000,0x0800,0x0800,0x0800,0x0800,0xf000,0x0000,0x0000,0x0000, // u2283\n  0x0000,0x0000,0x7800,0x8000,0x8000,0x8000,0x8000,0x7800,0x0000,0xf800,0x0000,0x0000, // u2286\n  0x0000,0x0000,0xf000,0x0800,0x0800,0x0800,0x0800,0xf000,0x0000,0xf800,0x0000,0x0000, // u2287\n  0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x2000,0x2000,0xf800,0x0000,0x0000, // u22a5\n  0x0000,0x0000,0x7000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x0000,0x0000, // u22c2\n  0x0000,0x0000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u22c3\n  0x0000,0x0000,0x0800,0x7000,0x9800,0xa800,0xa800,0xc800,0x7000,0x8000,0x0000,0x0000, // u2300\n  0x0000,0x0000,0x0000,0x0000,0x2000,0x5000,0x8800,0x8800,0x8800,0xf800,0x0000,0x0000, // u2302\n  0x0000,0x0000,0x7000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000, // u2308\n  0x0000,0x0000,0x7000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000, // u2309\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7000,0x0000,0x0000, // u230a\n  0x0000,0x0000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x7000,0x0000,0x0000, // u230b\n  0x0000,0x0000,0x0000,0x0000,0xf800,0x8000,0x8000,0x8000,0x0000,0x0000,0x0000,0x0000, // u2310\n  0x0000,0x0000,0x0000,0x0000,0x8000,0x8000,0x8000,0xf800,0x0000,0x0000,0x0000,0x0000, // u2319\n  0x0000,0x0000,0x1000,0x2800,0x2800,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u2320\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0xa000,0xa000,0x4000,0x0000,0x0000, // u2321\n  0x0800,0x1000,0x1000,0x2000,0x2000,0x2000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000, // u239b\n  0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000, // u239c\n  0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x2000,0x2000,0x2000,0x1000,0x1000,0x0800, // u239d\n  0x4000,0x2000,0x2000,0x1000,0x1000,0x1000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800, // u239e\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800, // u239f\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1000,0x1000,0x1000,0x2000,0x2000,0x4000, // u23a0\n  0x7800,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000, // u23a1\n  0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000, // u23a2\n  0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7800, // u23a3\n  0x7800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800, // u23a4\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800, // u23a5\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x7800, // u23a6\n  0x0c00,0x1000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u23a7\n  0x2000,0x2000,0x2000,0x2000,0x2000,0xc000,0xc000,0x2000,0x2000,0x2000,0x2000,0x2000, // u23a8\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x1000,0x0c00, // u23a9\n  0xc000,0x2000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u23ab\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x0c00,0x0c00,0x1000,0x1000,0x1000,0x1000,0x1000, // u23ac\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x2000,0xc000, // u23ad\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u23ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23af\n  0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23ba\n  0x0000,0x0000,0x0000,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x0000,0x0000,0x0000, // u23bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00, // u23bd\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u23d0\n  0x9000,0x9000,0xf000,0x9000,0x9000,0x0000,0x7c00,0x1000,0x1000,0x1000,0x1000,0x0000, // u2409\n  0x8000,0x8000,0x8000,0x8000,0xf000,0x0000,0x3c00,0x2000,0x3800,0x2000,0x2000,0x0000, // u240a\n  0x8800,0x8800,0x8800,0x5000,0x2000,0x0000,0x7c00,0x1000,0x1000,0x1000,0x1000,0x0000, // u240b\n  0xf000,0x8000,0xe000,0x8000,0x8000,0x0000,0x3c00,0x2000,0x3800,0x2000,0x2000,0x0000, // u240c\n  0x6000,0x9000,0x8000,0x9000,0x6000,0x0000,0x3800,0x2400,0x3800,0x2800,0x2400,0x0000, // u240d\n  0x9000,0xd000,0xb000,0x9000,0x9000,0x0000,0x2000,0x2000,0x2000,0x2000,0x3c00,0x0000, // u2424\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2500\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2501\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u2502\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000, // u2503\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xa800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2508\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xa800,0xa800,0x0000,0x0000,0x0000,0x0000,0x0000, // u2509\n  0x2000,0x2000,0x0000,0x2000,0x2000,0x0000,0x2000,0x2000,0x0000,0x2000,0x2000,0x0000, // u250a\n  0x3000,0x3000,0x0000,0x3000,0x3000,0x0000,0x3000,0x3000,0x0000,0x3000,0x3000,0x0000, // u250b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u250c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x3c00,0x2000,0x2000,0x2000,0x2000,0x2000, // u250d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000, // u250e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x3c00,0x3000,0x3000,0x3000,0x3000,0x3000, // u250f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xe000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u2510\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xe000,0xe000,0x2000,0x2000,0x2000,0x2000,0x2000, // u2511\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xf000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000, // u2512\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xf000,0xf000,0x3000,0x3000,0x3000,0x3000,0x3000, // u2513\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2514\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x3c00,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2515\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2516\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3c00,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2517\n  0x2000,0x2000,0x2000,0x2000,0x2000,0xe000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2518\n  0x2000,0x2000,0x2000,0x2000,0x2000,0xe000,0xe000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2519\n  0x3000,0x3000,0x3000,0x3000,0x3000,0xf000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u251a\n  0x3000,0x3000,0x3000,0x3000,0x3000,0xf000,0xf000,0x0000,0x0000,0x0000,0x0000,0x0000, // u251b\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x3c00,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u251c\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x3c00,0x3c00,0x2000,0x2000,0x2000,0x2000,0x2000, // u251d\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3c00,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u251e\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x3c00,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000, // u251f\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3c00,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000, // u2520\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3c00,0x3c00,0x2000,0x2000,0x2000,0x2000,0x2000, // u2521\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x3c00,0x3c00,0x3000,0x3000,0x3000,0x3000,0x3000, // u2522\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3c00,0x3c00,0x3000,0x3000,0x3000,0x3000,0x3000, // u2523\n  0x2000,0x2000,0x2000,0x2000,0x2000,0xe000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u2524\n  0x2000,0x2000,0x2000,0x2000,0x2000,0xe000,0xe000,0x2000,0x2000,0x2000,0x2000,0x2000, // u2525\n  0x3000,0x3000,0x3000,0x3000,0x3000,0xf000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u2526\n  0x2000,0x2000,0x2000,0x2000,0x2000,0xf000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000, // u2527\n  0x3000,0x3000,0x3000,0x3000,0x3000,0xf000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000, // u2528\n  0x3000,0x3000,0x3000,0x3000,0x3000,0xf000,0xf000,0x2000,0x2000,0x2000,0x2000,0x2000, // u2529\n  0x2000,0x2000,0x2000,0x2000,0x2000,0xf000,0xf000,0x3000,0x3000,0x3000,0x3000,0x3000, // u252a\n  0x3000,0x3000,0x3000,0x3000,0x3000,0xf000,0xf000,0x3000,0x3000,0x3000,0x3000,0x3000, // u252b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u252c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xe000,0x2000,0x2000,0x2000,0x2000,0x2000, // u252d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x3c00,0x2000,0x2000,0x2000,0x2000,0x2000, // u252e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x2000,0x2000,0x2000,0x2000,0x2000, // u252f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000, // u2530\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xf000,0x3000,0x3000,0x3000,0x3000,0x3000, // u2531\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x3c00,0x3000,0x3000,0x3000,0x3000,0x3000, // u2532\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x3000,0x3000,0x3000,0x3000,0x3000, // u2533\n  0x2000,0x2000,0x2000,0x2000,0x2000,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2534\n  0x2000,0x2000,0x2000,0x2000,0x2000,0xfc00,0xe000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2535\n  0x2000,0x2000,0x2000,0x2000,0x2000,0xfc00,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2536\n  0x2000,0x2000,0x2000,0x2000,0x2000,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2537\n  0x3000,0x3000,0x3000,0x3000,0x3000,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2538\n  0x3000,0x3000,0x3000,0x3000,0x3000,0xfc00,0xf000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2539\n  0x3000,0x3000,0x3000,0x3000,0x3000,0xfc00,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u253a\n  0x3000,0x3000,0x3000,0x3000,0x3000,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000, // u253b\n  0x2000,0x2000,0x2000,0x2000,0x2000,0xfc00,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u253c\n  0x2000,0x2000,0x2000,0x2000,0x2000,0xfc00,0xe000,0x2000,0x2000,0x2000,0x2000,0x2000, // u253d\n  0x2000,0x2000,0x2000,0x2000,0x2000,0xfc00,0x3c00,0x2000,0x2000,0x2000,0x2000,0x2000, // u253e\n  0x2000,0x2000,0x2000,0x2000,0x2000,0xfc00,0xfc00,0x2000,0x2000,0x2000,0x2000,0x2000, // u253f\n  0x3000,0x3000,0x3000,0x3000,0x3000,0xfc00,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u2540\n  0x2000,0x2000,0x2000,0x2000,0x2000,0xfc00,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000, // u2541\n  0x3000,0x3000,0x3000,0x3000,0x3000,0xfc00,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000, // u2542\n  0x3000,0x3000,0x3000,0x3000,0x3000,0xfc00,0xe000,0x2000,0x2000,0x2000,0x2000,0x2000, // u2543\n  0x3000,0x3000,0x3000,0x3000,0x3000,0xfc00,0x3c00,0x2000,0x2000,0x2000,0x2000,0x2000, // u2544\n  0x2000,0x2000,0x2000,0x2000,0x2000,0xfc00,0xf000,0x3000,0x3000,0x3000,0x3000,0x3000, // u2545\n  0x2000,0x2000,0x2000,0x2000,0x2000,0xfc00,0x3c00,0x3000,0x3000,0x3000,0x3000,0x3000, // u2546\n  0x3000,0x3000,0x3000,0x3000,0x3000,0xfc00,0xfc00,0x2000,0x2000,0x2000,0x2000,0x2000, // u2547\n  0x2000,0x2000,0x2000,0x2000,0x2000,0xfc00,0xfc00,0x3000,0x3000,0x3000,0x3000,0x3000, // u2548\n  0x3000,0x3000,0x3000,0x3000,0x3000,0xfc00,0xf000,0x3000,0x3000,0x3000,0x3000,0x3000, // u2549\n  0x3000,0x3000,0x3000,0x3000,0x3000,0xfc00,0x3c00,0x3000,0x3000,0x3000,0x3000,0x3000, // u254a\n  0x3000,0x3000,0x3000,0x3000,0x3000,0xfc00,0xfc00,0x3000,0x3000,0x3000,0x3000,0x3000, // u254b\n  0x0000,0x0000,0x0000,0x0000,0xfc00,0x0000,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2550\n  0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000, // u2551\n  0x0000,0x0000,0x0000,0x0000,0x3c00,0x2000,0x3c00,0x2000,0x2000,0x2000,0x2000,0x2000, // u2552\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000, // u2553\n  0x0000,0x0000,0x0000,0x0000,0x7c00,0x4000,0x5c00,0x5000,0x5000,0x5000,0x5000,0x5000, // u2554\n  0x0000,0x0000,0x0000,0x0000,0xe000,0x2000,0xe000,0x2000,0x2000,0x2000,0x2000,0x2000, // u2555\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xf000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000, // u2556\n  0x0000,0x0000,0x0000,0x0000,0xf000,0x1000,0xd000,0x5000,0x5000,0x5000,0x5000,0x5000, // u2557\n  0x2000,0x2000,0x2000,0x2000,0x3c00,0x2000,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2558\n  0x5000,0x5000,0x5000,0x5000,0x5000,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2559\n  0x5000,0x5000,0x5000,0x5000,0x5c00,0x4000,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u255a\n  0x2000,0x2000,0x2000,0x2000,0xe000,0x2000,0xe000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255b\n  0x5000,0x5000,0x5000,0x5000,0x5000,0xf000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255c\n  0x5000,0x5000,0x5000,0x5000,0xd000,0x1000,0xf000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255d\n  0x2000,0x2000,0x2000,0x2000,0x3c00,0x2000,0x3c00,0x2000,0x2000,0x2000,0x2000,0x2000, // u255e\n  0x5000,0x5000,0x5000,0x5000,0x5000,0x5c00,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000, // u255f\n  0x5000,0x5000,0x5000,0x5000,0x5c00,0x4000,0x5c00,0x5000,0x5000,0x5000,0x5000,0x5000, // u2560\n  0x2000,0x2000,0x2000,0x2000,0xe000,0x2000,0xe000,0x2000,0x2000,0x2000,0x2000,0x2000, // u2561\n  0x5000,0x5000,0x5000,0x5000,0x5000,0xd000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000, // u2562\n  0x5000,0x5000,0x5000,0x5000,0xd000,0x1000,0xd000,0x5000,0x5000,0x5000,0x5000,0x5000, // u2563\n  0x0000,0x0000,0x0000,0x0000,0xfc00,0x0000,0xfc00,0x2000,0x2000,0x2000,0x2000,0x2000, // u2564\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000, // u2565\n  0x0000,0x0000,0x0000,0x0000,0xfc00,0x0000,0xdc00,0x5000,0x5000,0x5000,0x5000,0x5000, // u2566\n  0x2000,0x2000,0x2000,0x2000,0xfc00,0x0000,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2567\n  0x5000,0x5000,0x5000,0x5000,0x5000,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2568\n  0x5000,0x5000,0x5000,0x5000,0xdc00,0x0000,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2569\n  0x2000,0x2000,0x2000,0x2000,0xfc00,0x2000,0xfc00,0x2000,0x2000,0x2000,0x2000,0x2000, // u256a\n  0x5000,0x5000,0x5000,0x5000,0x5000,0xfc00,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000, // u256b\n  0x5000,0x5000,0x5000,0x5000,0xdc00,0x0000,0xdc00,0x5000,0x5000,0x5000,0x5000,0x5000, // u256c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x1000,0x2000,0x2000,0x2000,0x2000,0x2000, // u256d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x8000,0x4000,0x2000,0x2000,0x2000,0x2000,0x2000, // u256e\n  0x2000,0x2000,0x2000,0x2000,0x4000,0x8000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u256f\n  0x2000,0x2000,0x2000,0x2000,0x1000,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2570\n  0x0400,0x0400,0x0800,0x0800,0x1000,0x1000,0x2000,0x2000,0x4000,0x4000,0x8000,0x8000, // u2571\n  0x8000,0x8000,0x4000,0x4000,0x2000,0x2000,0x1000,0x1000,0x0800,0x0800,0x0400,0x0400, // u2572\n  0x8400,0x8400,0x4800,0x4800,0x3000,0x3000,0x3000,0x3000,0x4800,0x4800,0x8400,0x8400, // u2573\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xe000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2574\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2575\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2576\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u2577\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xe000,0xe000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2578\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2579\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u257a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000, // u257b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u257c\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000, // u257d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xe000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257e\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u257f\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2580\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00, // u2581\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0xfc00, // u2582\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0xfc00,0xfc00, // u2583\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00, // u2584\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00, // u2585\n  0x0000,0x0000,0x0000,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00, // u2586\n  0x0000,0x0000,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00, // u2587\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00, // u2588\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800, // u2589\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000, // u258a\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000, // u258b\n  0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000, // u258c\n  0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000, // u258d\n  0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000, // u258e\n  0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000, // u258f\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00, // u2590\n  0x9000,0x2400,0x9000,0x2400,0x9000,0x2400,0x9000,0x2400,0x9000,0x2400,0x9000,0x2400, // u2591\n  0xa800,0x5400,0xa800,0x5400,0xa800,0x5400,0xa800,0x5400,0xa800,0x5400,0xa800,0x5400, // u2592\n  0xd800,0xb400,0xd800,0xb400,0xd800,0xb400,0xd800,0xb400,0xd800,0xb400,0xd800,0xb400, // u2593\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000, // u2596\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00, // u2597\n  0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2598\n  0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00, // u2599\n  0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00, // u259a\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000, // u259b\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00, // u259c\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u259d\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000, // u259e\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00, // u259f\n  0x0000,0x0000,0x0000,0x7800,0x7800,0x7800,0x7800,0x7800,0x0000,0x0000,0x0000,0x0000, // u25a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0xf800,0x0000,0x0000, // u25ac\n  0x0000,0x0000,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0x0000,0x0000, // u25ae\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x7800,0x7800,0xfc00,0xfc00,0x0000,0x0000,0x0000, // u25b2\n  0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xfc00,0xf000,0xc000,0x0000,0x0000,0x0000, // u25b6\n  0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xfc00,0xf000,0xc000,0x0000,0x0000,0x0000, // u25ba\n  0x0000,0x0000,0x0000,0xfc00,0xfc00,0x7800,0x7800,0x3000,0x3000,0x0000,0x0000,0x0000, // u25bc\n  0x0000,0x0000,0x0000,0x0c00,0x3c00,0xfc00,0xfc00,0x3c00,0x0c00,0x0000,0x0000,0x0000, // u25c0\n  0x0000,0x0000,0x0000,0x0c00,0x3c00,0xfc00,0xfc00,0x3c00,0x0c00,0x0000,0x0000,0x0000, // u25c4\n  0x0000,0x0000,0x0000,0x2000,0x7000,0xf800,0x7000,0x2000,0x0000,0x0000,0x0000,0x0000, // u25c6\n  0x0000,0x0000,0x0000,0x2000,0x5000,0x8800,0x5000,0x2000,0x0000,0x0000,0x0000,0x0000, // u25ca\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x4800,0x4800,0x3000,0x0000,0x0000,0x0000,0x0000, // u25cb\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x7800,0x7800,0x3000,0x0000,0x0000,0x0000,0x0000, // u25cf\n  0xfc00,0xfc00,0xfc00,0xfc00,0xcc00,0x8400,0x8400,0xcc00,0xfc00,0xfc00,0xfc00,0xfc00, // u25d8\n  0xfc00,0xfc00,0xfc00,0xfc00,0xcc00,0xb400,0xb400,0xcc00,0xfc00,0xfc00,0xfc00,0xfc00, // u25d9\n  0x0000,0x0000,0x7800,0x8400,0xcc00,0x8400,0xb400,0xb400,0x8400,0x7800,0x0000,0x0000, // u263a\n  0x0000,0x0000,0x7800,0xfc00,0xb400,0xfc00,0x8400,0xcc00,0xfc00,0x7800,0x0000,0x0000, // u263b\n  0x0000,0x0000,0x0000,0x2000,0xa800,0x7000,0xd800,0x7000,0xa800,0x2000,0x0000,0x0000, // u263c\n  0x0000,0x0000,0x7000,0x8800,0x8800,0x8800,0x7000,0x2000,0xf800,0x2000,0x0000,0x0000, // u2640\n  0x0000,0x0000,0x3c00,0x0c00,0x1400,0x7000,0x8800,0x8800,0x8800,0x7000,0x0000,0x0000, // u2642\n  0x0000,0x0000,0x2000,0x2000,0x7000,0xf800,0xf800,0x7000,0x2000,0x7000,0x0000,0x0000, // u2660\n  0x0000,0x0000,0x2000,0x7000,0x2000,0xa800,0xf800,0xa800,0x2000,0x7000,0x0000,0x0000, // u2663\n  0x0000,0x0000,0x0000,0x5000,0xf800,0xf800,0xf800,0x7000,0x7000,0x2000,0x0000,0x0000, // u2665\n  0x0000,0x0000,0x0000,0x2000,0x7000,0xf800,0x7000,0x2000,0x0000,0x0000,0x0000,0x0000, // u2666\n  0x0000,0x0000,0x7800,0x4800,0x7800,0x4000,0x4000,0x4000,0x4000,0x8000,0x0000,0x0000, // u266a\n  0x0000,0x0000,0x7800,0x4800,0x7800,0x4800,0x4800,0x4800,0x4800,0x5000,0x8000,0x0000, // u266b\n  0x0000,0x0000,0x0400,0x0400,0x0800,0x8800,0x9000,0x5000,0x2000,0x2000,0x0000,0x0000, // u2713\n  0x0000,0x0000,0x0c00,0x0c00,0x1800,0xd800,0xf000,0x7000,0x6000,0x6000,0x0000,0x0000, // u2714\n  0x0000,0x0000,0x4800,0x2800,0x1000,0x1000,0x2800,0x2400,0x4000,0x4000,0x0000,0x0000, // u2717\n  0x0000,0x0000,0x1800,0xd800,0x7000,0x3000,0x7800,0x6c00,0xc000,0xc000,0x0000,0x0000, // u2718\n  0x0000,0x1000,0x1000,0x2000,0x2000,0x4000,0x2000,0x2000,0x1000,0x1000,0x0000,0x0000, // u27e8\n  0x0000,0x4000,0x4000,0x2000,0x2000,0x1000,0x2000,0x2000,0x4000,0x4000,0x0000,0x0000, // u27e9\n  0x0000,0x2800,0x2800,0x5000,0x5000,0xa000,0x5000,0x5000,0x2800,0x2800,0x0000,0x0000, // u27ea\n  0x0000,0xa000,0xa000,0x5000,0x5000,0x2800,0x5000,0x5000,0xa000,0xa000,0x0000,0x0000, // u27eb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2800\n  0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2801\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2802\n  0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2803\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u2804\n  0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u2805\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u2806\n  0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u2807\n  0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2808\n  0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2809\n  0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280a\n  0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280b\n  0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u280c\n  0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u280d\n  0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u280e\n  0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u280f\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2810\n  0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2811\n  0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2812\n  0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2813\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u2814\n  0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u2815\n  0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u2816\n  0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u2817\n  0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2818\n  0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2819\n  0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281a\n  0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281b\n  0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u281c\n  0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u281d\n  0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u281e\n  0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u281f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000, // u2820\n  0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000, // u2821\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000, // u2822\n  0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000, // u2823\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000, // u2824\n  0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000, // u2825\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000, // u2826\n  0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000, // u2827\n  0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000, // u2828\n  0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000, // u2829\n  0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000, // u282a\n  0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000, // u282b\n  0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000, // u282c\n  0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000, // u282d\n  0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000, // u282e\n  0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000, // u282f\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000, // u2830\n  0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000, // u2831\n  0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000, // u2832\n  0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000, // u2833\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000, // u2834\n  0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000, // u2835\n  0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000, // u2836\n  0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000, // u2837\n  0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000, // u2838\n  0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000, // u2839\n  0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000, // u283a\n  0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000, // u283b\n  0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000, // u283c\n  0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000, // u283d\n  0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000, // u283e\n  0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000, // u283f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2840\n  0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2841\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2842\n  0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2843\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u2844\n  0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u2845\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u2846\n  0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u2847\n  0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2848\n  0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2849\n  0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u284a\n  0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u284b\n  0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u284c\n  0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u284d\n  0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u284e\n  0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u284f\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2850\n  0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2851\n  0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2852\n  0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2853\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u2854\n  0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u2855\n  0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u2856\n  0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u2857\n  0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2858\n  0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2859\n  0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u285a\n  0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u285b\n  0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u285c\n  0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u285d\n  0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u285e\n  0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u285f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000, // u2860\n  0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000, // u2861\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000, // u2862\n  0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000, // u2863\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000, // u2864\n  0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000, // u2865\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000, // u2866\n  0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000, // u2867\n  0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000, // u2868\n  0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000, // u2869\n  0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000, // u286a\n  0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000, // u286b\n  0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000, // u286c\n  0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000, // u286d\n  0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000, // u286e\n  0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000, // u286f\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000, // u2870\n  0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000, // u2871\n  0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000, // u2872\n  0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000, // u2873\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000, // u2874\n  0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000, // u2875\n  0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000, // u2876\n  0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000, // u2877\n  0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000, // u2878\n  0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000, // u2879\n  0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000, // u287a\n  0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000, // u287b\n  0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000, // u287c\n  0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000, // u287d\n  0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000, // u287e\n  0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000, // u287f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000, // u2880\n  0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000, // u2881\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000, // u2882\n  0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000, // u2883\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000, // u2884\n  0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000, // u2885\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000, // u2886\n  0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000, // u2887\n  0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000, // u2888\n  0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000, // u2889\n  0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000, // u288a\n  0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000, // u288b\n  0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000, // u288c\n  0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000, // u288d\n  0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000, // u288e\n  0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000, // u288f\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000, // u2890\n  0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000, // u2891\n  0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000, // u2892\n  0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000, // u2893\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000, // u2894\n  0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000, // u2895\n  0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000, // u2896\n  0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000, // u2897\n  0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000, // u2898\n  0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000, // u2899\n  0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000, // u289a\n  0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000, // u289b\n  0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000, // u289c\n  0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000, // u289d\n  0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000, // u289e\n  0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000, // u289f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000, // u28a0\n  0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000, // u28a1\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000, // u28a2\n  0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000, // u28a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000, // u28a4\n  0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000, // u28a5\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000, // u28a6\n  0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000, // u28a7\n  0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000, // u28a8\n  0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000, // u28a9\n  0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000, // u28aa\n  0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000, // u28ab\n  0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000, // u28ac\n  0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000, // u28ad\n  0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000, // u28ae\n  0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000, // u28af\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000, // u28b0\n  0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000, // u28b1\n  0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000, // u28b2\n  0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000, // u28b3\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000, // u28b4\n  0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000, // u28b5\n  0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000, // u28b6\n  0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000, // u28b7\n  0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000, // u28b8\n  0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000, // u28b9\n  0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000, // u28ba\n  0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000, // u28bb\n  0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000, // u28bc\n  0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000, // u28bd\n  0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000, // u28be\n  0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000, // u28bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000, // u28c0\n  0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000, // u28c1\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000, // u28c2\n  0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000, // u28c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000, // u28c4\n  0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000, // u28c5\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000, // u28c6\n  0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000, // u28c7\n  0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000, // u28c8\n  0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000, // u28c9\n  0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000, // u28ca\n  0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000, // u28cb\n  0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000, // u28cc\n  0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000, // u28cd\n  0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000, // u28ce\n  0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000, // u28cf\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000, // u28d0\n  0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000, // u28d1\n  0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000, // u28d2\n  0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000, // u28d3\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000, // u28d4\n  0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000, // u28d5\n  0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000, // u28d6\n  0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000, // u28d7\n  0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000, // u28d8\n  0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000, // u28d9\n  0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000, // u28da\n  0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000, // u28db\n  0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000, // u28dc\n  0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000, // u28dd\n  0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000, // u28de\n  0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000, // u28df\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000, // u28e0\n  0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000, // u28e1\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000, // u28e2\n  0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000, // u28e3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000, // u28e4\n  0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000, // u28e5\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000, // u28e6\n  0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000, // u28e7\n  0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000, // u28e8\n  0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000, // u28e9\n  0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000, // u28ea\n  0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000, // u28eb\n  0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000, // u28ec\n  0x4800,0x4800,0x0000,0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000, // u28ed\n  0x0800,0x0800,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000, // u28ee\n  0x4800,0x4800,0x0000,0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000, // u28ef\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000, // u28f0\n  0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000, // u28f1\n  0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000, // u28f2\n  0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000, // u28f3\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000, // u28f4\n  0x4000,0x4000,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000, // u28f5\n  0x0000,0x0000,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000, // u28f6\n  0x4000,0x4000,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000, // u28f7\n  0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000, // u28f8\n  0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000, // u28f9\n  0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000, // u28fa\n  0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000, // u28fb\n  0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000, // u28fc\n  0x4800,0x4800,0x0000,0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000, // u28fd\n  0x0800,0x0800,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000, // u28fe\n  0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000,0x4800,0x4800,0x0000, // u28ff\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0x0000,0x0000,0x8800,0x8800,0x0000,0x0000, // u2e2c\n  0x8000,0x9000,0xb800,0x9000,0x9000,0x9000,0x2000,0x4000,0x8000,0x8000,0x8000,0x8000, // ue0a0\n  0x8000,0x8000,0x8000,0x8000,0xf000,0x0000,0x2400,0x3400,0x2c00,0x2400,0x2400,0x0000, // ue0a1\n  0x0000,0x3000,0x4800,0x4800,0x4800,0xfc00,0xfc00,0xcc00,0xcc00,0xfc00,0xfc00,0x0000, // ue0a2\n  0x8000,0xc000,0xe000,0xf000,0xf800,0xfc00,0xfc00,0xf800,0xf000,0xe000,0xc000,0x8000, // ue0b0\n  0x8000,0x4000,0x2000,0x1000,0x0800,0x0400,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000, // ue0b1\n  0x0400,0x0c00,0x1c00,0x3c00,0x7c00,0xfc00,0xfc00,0x7c00,0x3c00,0x1c00,0x0c00,0x0400, // ue0b2\n  0x0400,0x0800,0x1000,0x2000,0x4000,0x8000,0x8000,0x4000,0x2000,0x1000,0x0800,0x0400, // ue0b3\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x4800,0x3000, // uf6be\n  0x0000,0x0000,0xf800,0x8800,0x8800,0x8800,0x8800,0x8800,0x8800,0xf800,0x0000,0x0000 // ufffd\n  };\n  // codepoints array\n  constexpr std::array<uint16_t, CHARCOUNT> fixedfont_codepoints = {\n  0x0000,0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,\n  0x002f,0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,\n  0x003f,0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,\n  0x004f,0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,\n  0x005f,0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,\n  0x006f,0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,\n  0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af,\n  0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf,\n  0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf,\n  0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df,\n  0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef,\n  0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff,\n  0x0100,0x0101,0x0102,0x0103,0x0104,0x0105,0x0106,0x0107,0x0108,0x0109,0x010a,0x010b,0x010c,0x010d,0x010e,0x010f,\n  0x0110,0x0111,0x0112,0x0113,0x0114,0x0115,0x0116,0x0117,0x0118,0x0119,0x011a,0x011b,0x011c,0x011d,0x011e,0x011f,\n  0x0120,0x0121,0x0122,0x0123,0x0124,0x0125,0x0126,0x0127,0x0128,0x0129,0x012a,0x012b,0x012c,0x012d,0x012e,0x012f,\n  0x0130,0x0131,0x0132,0x0133,0x0134,0x0135,0x0136,0x0137,0x0138,0x0139,0x013a,0x013b,0x013c,0x013d,0x013e,0x013f,\n  0x0140,0x0141,0x0142,0x0143,0x0144,0x0145,0x0146,0x0147,0x0148,0x0149,0x014a,0x014b,0x014c,0x014d,0x014e,0x014f,\n  0x0150,0x0151,0x0152,0x0153,0x0154,0x0155,0x0156,0x0157,0x0158,0x0159,0x015a,0x015b,0x015c,0x015d,0x015e,0x015f,\n  0x0160,0x0161,0x0162,0x0163,0x0164,0x0165,0x0166,0x0167,0x0168,0x0169,0x016a,0x016b,0x016c,0x016d,0x016e,0x016f,\n  0x0170,0x0171,0x0172,0x0173,0x0174,0x0175,0x0176,0x0177,0x0178,0x0179,0x017a,0x017b,0x017c,0x017d,0x017e,0x017f,\n  0x0186,0x018e,0x018f,0x0190,0x0192,0x019d,0x019e,0x01b5,0x01b6,0x01b7,0x01cd,0x01ce,0x01cf,0x01d0,0x01d1,0x01d2,\n  0x01d3,0x01d4,0x01e2,0x01e3,0x01e4,0x01e5,0x01e6,0x01e7,0x01e8,0x01e9,0x01ea,0x01eb,0x01ec,0x01ed,0x01ee,0x01ef,\n  0x01f0,0x01f4,0x01f5,0x01fc,0x01fd,0x01fe,0x01ff,0x0218,0x0219,0x021a,0x021b,0x0232,0x0233,0x0237,0x0254,0x0258,\n  0x0259,0x025b,0x0272,0x0292,0x02bb,0x02bc,0x02bd,0x02c6,0x02c7,0x02d8,0x02d9,0x02db,0x02dc,0x02dd,0x0300,0x0301,\n  0x0302,0x0303,0x0304,0x0305,0x0306,0x0307,0x0308,0x030a,0x030b,0x030c,0x0329,0x0384,0x0385,0x0386,0x0387,0x0388,\n  0x0389,0x038a,0x038c,0x038e,0x038f,0x0390,0x0391,0x0392,0x0393,0x0394,0x0395,0x0396,0x0397,0x0398,0x0399,0x039a,\n  0x039b,0x039c,0x039d,0x039e,0x039f,0x03a0,0x03a1,0x03a3,0x03a4,0x03a5,0x03a6,0x03a7,0x03a8,0x03a9,0x03aa,0x03ab,\n  0x03ac,0x03ad,0x03ae,0x03af,0x03b0,0x03b1,0x03b2,0x03b3,0x03b4,0x03b5,0x03b6,0x03b7,0x03b8,0x03b9,0x03ba,0x03bb,\n  0x03bc,0x03bd,0x03be,0x03bf,0x03c0,0x03c1,0x03c2,0x03c3,0x03c4,0x03c5,0x03c6,0x03c7,0x03c8,0x03c9,0x03ca,0x03cb,\n  0x03cc,0x03cd,0x03ce,0x03d1,0x03d5,0x03f0,0x03f1,0x03f2,0x03f3,0x03f4,0x03f5,0x03f6,0x0400,0x0401,0x0402,0x0403,\n  0x0404,0x0405,0x0406,0x0407,0x0408,0x0409,0x040a,0x040b,0x040c,0x040d,0x040e,0x040f,0x0410,0x0411,0x0412,0x0413,\n  0x0414,0x0415,0x0416,0x0417,0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e,0x041f,0x0420,0x0421,0x0422,0x0423,\n  0x0424,0x0425,0x0426,0x0427,0x0428,0x0429,0x042a,0x042b,0x042c,0x042d,0x042e,0x042f,0x0430,0x0431,0x0432,0x0433,\n  0x0434,0x0435,0x0436,0x0437,0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e,0x043f,0x0440,0x0441,0x0442,0x0443,\n  0x0444,0x0445,0x0446,0x0447,0x0448,0x0449,0x044a,0x044b,0x044c,0x044d,0x044e,0x044f,0x0450,0x0451,0x0452,0x0453,\n  0x0454,0x0455,0x0456,0x0457,0x0458,0x0459,0x045a,0x045b,0x045c,0x045d,0x045e,0x045f,0x0462,0x0463,0x046a,0x046b,\n  0x0490,0x0491,0x0492,0x0493,0x0494,0x0495,0x0496,0x0497,0x0498,0x0499,0x049a,0x049b,0x049c,0x049d,0x04a0,0x04a1,\n  0x04a2,0x04a3,0x04a4,0x04a5,0x04aa,0x04ab,0x04ae,0x04af,0x04b0,0x04b1,0x04b2,0x04b3,0x04b6,0x04b7,0x04b8,0x04b9,\n  0x04ba,0x04bb,0x04c0,0x04c1,0x04c2,0x04cf,0x04d0,0x04d1,0x04d2,0x04d3,0x04d4,0x04d5,0x04d6,0x04d7,0x04d8,0x04d9,\n  0x04da,0x04db,0x04dc,0x04dd,0x04de,0x04df,0x04e2,0x04e3,0x04e4,0x04e5,0x04e6,0x04e7,0x04e8,0x04e9,0x04ea,0x04eb,\n  0x04ec,0x04ed,0x04ee,0x04ef,0x04f0,0x04f1,0x04f2,0x04f3,0x04f4,0x04f5,0x04f8,0x04f9,0x05d0,0x05d1,0x05d2,0x05d3,\n  0x05d4,0x05d5,0x05d6,0x05d7,0x05d8,0x05d9,0x05da,0x05db,0x05dc,0x05dd,0x05de,0x05df,0x05e0,0x05e1,0x05e2,0x05e3,\n  0x05e4,0x05e5,0x05e6,0x05e7,0x05e8,0x05e9,0x05ea,0x1e0c,0x1e0d,0x1e34,0x1e35,0x1e36,0x1e37,0x1e40,0x1e41,0x1e42,\n  0x1e43,0x1e44,0x1e45,0x1e46,0x1e47,0x1e6c,0x1e6d,0x1eb8,0x1eb9,0x1ebc,0x1ebd,0x1eca,0x1ecb,0x1ecc,0x1ecd,0x1ee4,\n  0x1ee5,0x1ef8,0x1ef9,0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007,0x2008,0x2009,0x200a,0x200b,0x200c,\n  0x200d,0x200e,0x200f,0x2010,0x2011,0x2012,0x2013,0x2014,0x2015,0x2016,0x2017,0x2018,0x2019,0x201a,0x201b,0x201c,\n  0x201d,0x201e,0x201f,0x2020,0x2021,0x2022,0x2026,0x2030,0x2032,0x2033,0x2039,0x203a,0x203c,0x203e,0x2070,0x2071,\n  0x2074,0x2075,0x2076,0x2077,0x2078,0x2079,0x207a,0x207b,0x207c,0x207d,0x207e,0x207f,0x2080,0x2081,0x2082,0x2083,\n  0x2084,0x2085,0x2086,0x2087,0x2088,0x2089,0x208a,0x208b,0x208c,0x208d,0x208e,0x2090,0x2091,0x2092,0x2093,0x2094,\n  0x2095,0x2096,0x2097,0x2098,0x209a,0x20a7,0x20aa,0x20ac,0x20ae,0x2102,0x210e,0x210f,0x2115,0x2116,0x211a,0x211d,\n  0x2122,0x2124,0x2126,0x2135,0x2190,0x2191,0x2192,0x2193,0x2194,0x2195,0x21a4,0x21a6,0x21a8,0x21b5,0x21bb,0x21cb,\n  0x21cc,0x21d0,0x21d1,0x21d2,0x21d3,0x21d4,0x21d5,0x2200,0x2203,0x2204,0x2205,0x2206,0x2207,0x2208,0x2209,0x220a,\n  0x220b,0x220c,0x220d,0x2212,0x2213,0x2214,0x2215,0x2216,0x2219,0x221a,0x221e,0x221f,0x2225,0x2227,0x2228,0x2229,\n  0x222a,0x2248,0x2260,0x2261,0x2264,0x2265,0x226a,0x226b,0x2282,0x2283,0x2286,0x2287,0x22a5,0x22c2,0x22c3,0x2300,\n  0x2302,0x2308,0x2309,0x230a,0x230b,0x2310,0x2319,0x2320,0x2321,0x239b,0x239c,0x239d,0x239e,0x239f,0x23a0,0x23a1,\n  0x23a2,0x23a3,0x23a4,0x23a5,0x23a6,0x23a7,0x23a8,0x23a9,0x23ab,0x23ac,0x23ad,0x23ae,0x23af,0x23ba,0x23bb,0x23bc,\n  0x23bd,0x23d0,0x2409,0x240a,0x240b,0x240c,0x240d,0x2424,0x2500,0x2501,0x2502,0x2503,0x2508,0x2509,0x250a,0x250b,\n  0x250c,0x250d,0x250e,0x250f,0x2510,0x2511,0x2512,0x2513,0x2514,0x2515,0x2516,0x2517,0x2518,0x2519,0x251a,0x251b,\n  0x251c,0x251d,0x251e,0x251f,0x2520,0x2521,0x2522,0x2523,0x2524,0x2525,0x2526,0x2527,0x2528,0x2529,0x252a,0x252b,\n  0x252c,0x252d,0x252e,0x252f,0x2530,0x2531,0x2532,0x2533,0x2534,0x2535,0x2536,0x2537,0x2538,0x2539,0x253a,0x253b,\n  0x253c,0x253d,0x253e,0x253f,0x2540,0x2541,0x2542,0x2543,0x2544,0x2545,0x2546,0x2547,0x2548,0x2549,0x254a,0x254b,\n  0x2550,0x2551,0x2552,0x2553,0x2554,0x2555,0x2556,0x2557,0x2558,0x2559,0x255a,0x255b,0x255c,0x255d,0x255e,0x255f,\n  0x2560,0x2561,0x2562,0x2563,0x2564,0x2565,0x2566,0x2567,0x2568,0x2569,0x256a,0x256b,0x256c,0x256d,0x256e,0x256f,\n  0x2570,0x2571,0x2572,0x2573,0x2574,0x2575,0x2576,0x2577,0x2578,0x2579,0x257a,0x257b,0x257c,0x257d,0x257e,0x257f,\n  0x2580,0x2581,0x2582,0x2583,0x2584,0x2585,0x2586,0x2587,0x2588,0x2589,0x258a,0x258b,0x258c,0x258d,0x258e,0x258f,\n  0x2590,0x2591,0x2592,0x2593,0x2596,0x2597,0x2598,0x2599,0x259a,0x259b,0x259c,0x259d,0x259e,0x259f,0x25a0,0x25ac,\n  0x25ae,0x25b2,0x25b6,0x25ba,0x25bc,0x25c0,0x25c4,0x25c6,0x25ca,0x25cb,0x25cf,0x25d8,0x25d9,0x263a,0x263b,0x263c,\n  0x2640,0x2642,0x2660,0x2663,0x2665,0x2666,0x266a,0x266b,0x2713,0x2714,0x2717,0x2718,0x27e8,0x27e9,0x27ea,0x27eb,\n  0x2800,0x2801,0x2802,0x2803,0x2804,0x2805,0x2806,0x2807,0x2808,0x2809,0x280a,0x280b,0x280c,0x280d,0x280e,0x280f,\n  0x2810,0x2811,0x2812,0x2813,0x2814,0x2815,0x2816,0x2817,0x2818,0x2819,0x281a,0x281b,0x281c,0x281d,0x281e,0x281f,\n  0x2820,0x2821,0x2822,0x2823,0x2824,0x2825,0x2826,0x2827,0x2828,0x2829,0x282a,0x282b,0x282c,0x282d,0x282e,0x282f,\n  0x2830,0x2831,0x2832,0x2833,0x2834,0x2835,0x2836,0x2837,0x2838,0x2839,0x283a,0x283b,0x283c,0x283d,0x283e,0x283f,\n  0x2840,0x2841,0x2842,0x2843,0x2844,0x2845,0x2846,0x2847,0x2848,0x2849,0x284a,0x284b,0x284c,0x284d,0x284e,0x284f,\n  0x2850,0x2851,0x2852,0x2853,0x2854,0x2855,0x2856,0x2857,0x2858,0x2859,0x285a,0x285b,0x285c,0x285d,0x285e,0x285f,\n  0x2860,0x2861,0x2862,0x2863,0x2864,0x2865,0x2866,0x2867,0x2868,0x2869,0x286a,0x286b,0x286c,0x286d,0x286e,0x286f,\n  0x2870,0x2871,0x2872,0x2873,0x2874,0x2875,0x2876,0x2877,0x2878,0x2879,0x287a,0x287b,0x287c,0x287d,0x287e,0x287f,\n  0x2880,0x2881,0x2882,0x2883,0x2884,0x2885,0x2886,0x2887,0x2888,0x2889,0x288a,0x288b,0x288c,0x288d,0x288e,0x288f,\n  0x2890,0x2891,0x2892,0x2893,0x2894,0x2895,0x2896,0x2897,0x2898,0x2899,0x289a,0x289b,0x289c,0x289d,0x289e,0x289f,\n  0x28a0,0x28a1,0x28a2,0x28a3,0x28a4,0x28a5,0x28a6,0x28a7,0x28a8,0x28a9,0x28aa,0x28ab,0x28ac,0x28ad,0x28ae,0x28af,\n  0x28b0,0x28b1,0x28b2,0x28b3,0x28b4,0x28b5,0x28b6,0x28b7,0x28b8,0x28b9,0x28ba,0x28bb,0x28bc,0x28bd,0x28be,0x28bf,\n  0x28c0,0x28c1,0x28c2,0x28c3,0x28c4,0x28c5,0x28c6,0x28c7,0x28c8,0x28c9,0x28ca,0x28cb,0x28cc,0x28cd,0x28ce,0x28cf,\n  0x28d0,0x28d1,0x28d2,0x28d3,0x28d4,0x28d5,0x28d6,0x28d7,0x28d8,0x28d9,0x28da,0x28db,0x28dc,0x28dd,0x28de,0x28df,\n  0x28e0,0x28e1,0x28e2,0x28e3,0x28e4,0x28e5,0x28e6,0x28e7,0x28e8,0x28e9,0x28ea,0x28eb,0x28ec,0x28ed,0x28ee,0x28ef,\n  0x28f0,0x28f1,0x28f2,0x28f3,0x28f4,0x28f5,0x28f6,0x28f7,0x28f8,0x28f9,0x28fa,0x28fb,0x28fc,0x28fd,0x28fe,0x28ff,\n  0x2e2c,0xe0a0,0xe0a1,0xe0a2,0xe0b0,0xe0b1,0xe0b2,0xe0b3,0xf6be,0xfffd };\n} // namespace\n// -- end of autogenerated text ---\n\nnamespace fixed_font_12b {\n  // -- start of autogenerated text ---\n  // definition section for font: ter-u12b.bdf\n  constexpr int CHARCOUNT = 1354;\n  constexpr int WIDTH = 6;\n  constexpr int HEIGHT = 12;\n  constexpr int OFFSET_X = 0;\n  constexpr int OFFSET_Y = 0;\n  constexpr FixedFont_info_t fixedfont_info = {\n    \"Terminus\", // font name\n    \"ter-u12b.bdf\", // font name internal\n    CHARCOUNT, // num of chars\n    WIDTH, HEIGHT, OFFSET_X, OFFSET_Y,\n    true // bold\n  };\n  // font bitmap definitions\n  // same as 12n!\n  // codepoints array\n  // same as 12n!\n} // namespace\n// -- end of autogenerated text ---\n\nnamespace fixed_font_14n {\n  // -- start of autogenerated text ---\n  // definition section for font: ter-u14n.bdf\n  constexpr int CHARCOUNT = 1354;\n  constexpr int WIDTH = 8;\n  constexpr int HEIGHT = 14;\n  constexpr int OFFSET_X = 0;\n  constexpr int OFFSET_Y = 0;\n  constexpr FixedFont_info_t fixedfont_info = {\n    \"Terminus\", // font name\n    \"ter-u14n.bdf\", // font name internal\n    CHARCOUNT, // num of chars\n    WIDTH, HEIGHT, OFFSET_X, OFFSET_Y,\n    false // bold\n  };\n  // font bitmap definitions\n  constexpr std::array<uint16_t, CHARCOUNT * HEIGHT> fixedfont_bitmap = {\n  0x0000,0x0000,0x6600,0x4200,0x0000,0x4200,0x4200,0x4200,0x0000,0x4200,0x4200,0x6600,0x0000,0x0000, // u0000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0020\n  0x0000,0x0000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x1000,0x1000,0x0000,0x0000, // u0021\n  0x0000,0x2400,0x2400,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0022\n  0x0000,0x0000,0x2400,0x2400,0x2400,0x7e00,0x2400,0x2400,0x7e00,0x2400,0x2400,0x2400,0x0000,0x0000, // u0023\n  0x0000,0x1000,0x1000,0x7c00,0x9200,0x9000,0x9000,0x7c00,0x1200,0x1200,0x9200,0x7c00,0x1000,0x1000, // u0024\n  0x0000,0x0000,0x6400,0x9400,0x6800,0x0800,0x1000,0x1000,0x2000,0x2c00,0x5200,0x4c00,0x0000,0x0000, // u0025\n  0x0000,0x0000,0x1800,0x2400,0x2400,0x1800,0x3000,0x4a00,0x4400,0x4400,0x4400,0x3a00,0x0000,0x0000, // u0026\n  0x0000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0027\n  0x0000,0x0000,0x0800,0x1000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x1000,0x0800,0x0000,0x0000, // u0028\n  0x0000,0x0000,0x2000,0x1000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1000,0x2000,0x0000,0x0000, // u0029\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2400,0x1800,0x7e00,0x1800,0x2400,0x0000,0x0000,0x0000,0x0000, // u002a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u002b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x2000,0x0000, // u002c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x0000,0x0000, // u002e\n  0x0000,0x0000,0x0400,0x0400,0x0800,0x0800,0x1000,0x1000,0x2000,0x2000,0x4000,0x4000,0x0000,0x0000, // u002f\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4600,0x4a00,0x5200,0x6200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u0030\n  0x0000,0x0000,0x0800,0x1800,0x2800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x3e00,0x0000,0x0000, // u0031\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x7e00,0x0000,0x0000, // u0032\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x0200,0x1c00,0x0200,0x0200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u0033\n  0x0000,0x0000,0x0200,0x0600,0x0a00,0x1200,0x2200,0x4200,0x7e00,0x0200,0x0200,0x0200,0x0000,0x0000, // u0034\n  0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7c00,0x0200,0x0200,0x0200,0x4200,0x3c00,0x0000,0x0000, // u0035\n  0x0000,0x0000,0x1c00,0x2000,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u0036\n  0x0000,0x0000,0x7e00,0x0200,0x0200,0x0400,0x0400,0x0800,0x0800,0x1000,0x1000,0x1000,0x0000,0x0000, // u0037\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x3c00,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u0038\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x0400,0x3800,0x0000,0x0000, // u0039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x0000,0x0000,0x0000,0x1000,0x1000,0x0000,0x0000, // u003a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x0000,0x0000,0x0000,0x1000,0x1000,0x2000,0x0000, // u003b\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x1000,0x2000,0x4000,0x2000,0x1000,0x0800,0x0400,0x0000,0x0000, // u003c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0000,0x0000,0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u003d\n  0x0000,0x0000,0x0000,0x4000,0x2000,0x1000,0x0800,0x0400,0x0800,0x1000,0x2000,0x4000,0x0000,0x0000, // u003e\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x0400,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x0000, // u003f\n  0x0000,0x0000,0x7c00,0x8200,0x9e00,0xa200,0xa200,0xa200,0xa600,0x9a00,0x8000,0x7e00,0x0000,0x0000, // u0040\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u0041\n  0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x7c00,0x4200,0x4200,0x4200,0x4200,0x7c00,0x0000,0x0000, // u0042\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4000,0x4000,0x4000,0x4000,0x4200,0x4200,0x3c00,0x0000,0x0000, // u0043\n  0x0000,0x0000,0x7800,0x4400,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4400,0x7800,0x0000,0x0000, // u0044\n  0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u0045\n  0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000, // u0046\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4000,0x4000,0x4e00,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u0047\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u0048\n  0x0000,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u0049\n  0x0000,0x0000,0x0e00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x4400,0x4400,0x3800,0x0000,0x0000, // u004a\n  0x0000,0x0000,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x0000,0x0000, // u004b\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u004c\n  0x0000,0x0000,0x8200,0xc600,0xaa00,0x9200,0x9200,0x8200,0x8200,0x8200,0x8200,0x8200,0x0000,0x0000, // u004d\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x6200,0x5200,0x4a00,0x4600,0x4200,0x4200,0x4200,0x0000,0x0000, // u004e\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u004f\n  0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x7c00,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000, // u0050\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4a00,0x3c00,0x0200,0x0000, // u0051\n  0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x7c00,0x5000,0x4800,0x4400,0x4200,0x0000,0x0000, // u0052\n  0x0000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x3c00,0x0200,0x0200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u0053\n  0x0000,0x0000,0xfe00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000, // u0054\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u0055\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x2400,0x2400,0x2400,0x1800,0x1800,0x0000,0x0000, // u0056\n  0x0000,0x0000,0x8200,0x8200,0x8200,0x8200,0x8200,0x9200,0x9200,0xaa00,0xc600,0x8200,0x0000,0x0000, // u0057\n  0x0000,0x0000,0x4200,0x4200,0x2400,0x2400,0x1800,0x1800,0x2400,0x2400,0x4200,0x4200,0x0000,0x0000, // u0058\n  0x0000,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000, // u0059\n  0x0000,0x0000,0x7e00,0x0200,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u005a\n  0x0000,0x0000,0x3800,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x3800,0x0000,0x0000, // u005b\n  0x0000,0x0000,0x4000,0x4000,0x2000,0x2000,0x1000,0x1000,0x0800,0x0800,0x0400,0x0400,0x0000,0x0000, // u005c\n  0x0000,0x0000,0x3800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x3800,0x0000,0x0000, // u005d\n  0x0000,0x1000,0x2800,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0000, // u005f\n  0x1000,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0060\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u0061\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x7c00,0x0000,0x0000, // u0062\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4000,0x4200,0x3c00,0x0000,0x0000, // u0063\n  0x0000,0x0000,0x0200,0x0200,0x0200,0x3e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u0064\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000, // u0065\n  0x0000,0x0000,0x0e00,0x1000,0x1000,0x7c00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000, // u0066\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x3c00, // u0067\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u0068\n  0x0000,0x0000,0x1000,0x1000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u0069\n  0x0000,0x0000,0x0400,0x0400,0x0000,0x0c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x4400,0x4400,0x3800, // u006a\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x0000,0x0000, // u006b\n  0x0000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u006c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x0000,0x0000, // u006d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u006e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u006f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x7c00,0x4000,0x4000, // u0070\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200, // u0071\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x5e00,0x6000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000, // u0072\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4000,0x4000,0x3c00,0x0200,0x0200,0x7c00,0x0000,0x0000, // u0073\n  0x0000,0x0000,0x1000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x1000,0x1000,0x1000,0x0e00,0x0000,0x0000, // u0074\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u0075\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x2400,0x2400,0x1800,0x1800,0x0000,0x0000, // u0076\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x8200,0x8200,0x9200,0x9200,0x9200,0x9200,0x7c00,0x0000,0x0000, // u0077\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x2400,0x1800,0x2400,0x4200,0x4200,0x0000,0x0000, // u0078\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x3c00, // u0079\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0400,0x0800,0x1000,0x2000,0x4000,0x7e00,0x0000,0x0000, // u007a\n  0x0000,0x0000,0x0c00,0x1000,0x1000,0x1000,0x2000,0x1000,0x1000,0x1000,0x1000,0x0c00,0x0000,0x0000, // u007b\n  0x0000,0x0000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000, // u007c\n  0x0000,0x0000,0x3000,0x0800,0x0800,0x0800,0x0400,0x0800,0x0800,0x0800,0x0800,0x3000,0x0000,0x0000, // u007d\n  0x0000,0x6200,0x9200,0x8c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a0\n  0x0000,0x0000,0x1000,0x1000,0x0000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000, // u00a1\n  0x0000,0x0000,0x0000,0x1000,0x1000,0x7c00,0x9200,0x9000,0x9000,0x9000,0x9200,0x7c00,0x1000,0x1000, // u00a2\n  0x0000,0x0000,0x1800,0x2400,0x2000,0x2000,0x7800,0x2000,0x2000,0x2000,0x2200,0x7e00,0x0000,0x0000, // u00a3\n  0x0000,0x0000,0x0000,0x0000,0x4400,0x3800,0x4400,0x4400,0x4400,0x3800,0x4400,0x0000,0x0000,0x0000, // u00a4\n  0x0000,0x0000,0x8200,0x8200,0x4400,0x2800,0x1000,0x7c00,0x1000,0x7c00,0x1000,0x1000,0x0000,0x0000, // u00a5\n  0x0000,0x0000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000, // u00a6\n  0x0000,0x3800,0x4400,0x4000,0x3000,0x4800,0x4400,0x4400,0x2400,0x1800,0x0400,0x4400,0x3800,0x0000, // u00a7\n  0x2400,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a8\n  0x0000,0x0000,0x0000,0x7e00,0x8100,0x9900,0xa500,0xa100,0xa500,0x9900,0x8100,0x7e00,0x0000,0x0000, // u00a9\n  0x0000,0x3800,0x0400,0x3c00,0x4400,0x3c00,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1200,0x2400,0x4800,0x9000,0x4800,0x2400,0x1200,0x0000,0x0000, // u00ab\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0200,0x0200,0x0200,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ac\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ad\n  0x0000,0x0000,0x0000,0x7e00,0x8100,0xb900,0xa500,0xb900,0xa900,0xa500,0x8100,0x7e00,0x0000,0x0000, // u00ae\n  0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00af\n  0x0000,0x1800,0x2400,0x2400,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x0000,0x7c00,0x0000,0x0000, // u00b1\n  0x0000,0x1800,0x2400,0x0400,0x0800,0x1000,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b2\n  0x0000,0x3800,0x0400,0x1800,0x0400,0x0400,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b3\n  0x0800,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4600,0x7a00,0x4000,0x4000, // u00b5\n  0x0000,0x0000,0x7e00,0x9200,0x9200,0x9200,0x9200,0x7200,0x1200,0x1200,0x1200,0x1200,0x0000,0x0000, // u00b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x2000, // u00b8\n  0x0000,0x1000,0x3000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b9\n  0x0000,0x3800,0x4400,0x4400,0x4400,0x3800,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x9000,0x4800,0x2400,0x1200,0x2400,0x4800,0x9000,0x0000,0x0000, // u00bb\n  0x2000,0x6000,0x2000,0x2200,0x2400,0x0800,0x1000,0x2200,0x4600,0x8a00,0x1e00,0x0200,0x0200,0x0000, // u00bc\n  0x2000,0x6000,0x2000,0x2200,0x2400,0x0800,0x1000,0x2000,0x4c00,0x9200,0x0400,0x0800,0x1e00,0x0000, // u00bd\n  0xe000,0x1000,0x6000,0x1200,0xe400,0x0800,0x1000,0x2200,0x4600,0x8a00,0x1e00,0x0200,0x0200,0x0000, // u00be\n  0x0000,0x0000,0x1000,0x1000,0x0000,0x1000,0x1000,0x2000,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u00bf\n  0x1000,0x0800,0x0000,0x3c00,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u00c0\n  0x0800,0x1000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u00c1\n  0x1800,0x2400,0x0000,0x3c00,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u00c2\n  0x3200,0x4c00,0x0000,0x3c00,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u00c3\n  0x2400,0x2400,0x0000,0x3c00,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u00c4\n  0x1800,0x2400,0x1800,0x3c00,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u00c5\n  0x0000,0x0000,0x7e00,0x9000,0x9000,0x9000,0xfc00,0x9000,0x9000,0x9000,0x9000,0x9e00,0x0000,0x0000, // u00c6\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4000,0x4000,0x4000,0x4000,0x4200,0x4200,0x3c00,0x1000,0x2000, // u00c7\n  0x1000,0x0800,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u00c8\n  0x0800,0x1000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u00c9\n  0x1800,0x2400,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u00ca\n  0x2400,0x2400,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u00cb\n  0x2000,0x1000,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u00cc\n  0x0800,0x1000,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u00cd\n  0x1800,0x2400,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u00ce\n  0x4400,0x4400,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u00cf\n  0x0000,0x0000,0x7800,0x4400,0x4200,0x4200,0xf200,0x4200,0x4200,0x4200,0x4400,0x7800,0x0000,0x0000, // u00d0\n  0x3200,0x4c00,0x0000,0x4200,0x4200,0x6200,0x5200,0x4a00,0x4600,0x4200,0x4200,0x4200,0x0000,0x0000, // u00d1\n  0x1000,0x0800,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u00d2\n  0x0800,0x1000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u00d3\n  0x1800,0x2400,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u00d4\n  0x3200,0x4c00,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u00d5\n  0x2400,0x2400,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u00d6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x2400,0x1800,0x1800,0x2400,0x4200,0x0000,0x0000,0x0000, // u00d7\n  0x0000,0x0000,0x3c00,0x4300,0x4200,0x4600,0x4a00,0x5200,0x6200,0x4200,0xc200,0x3c00,0x0000,0x0000, // u00d8\n  0x1000,0x0800,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u00d9\n  0x0800,0x1000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u00da\n  0x1800,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u00db\n  0x2400,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u00dc\n  0x0800,0x1000,0x8200,0x8200,0x4400,0x4400,0x2800,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000, // u00dd\n  0x0000,0x0000,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x7c00,0x4000,0x4000,0x0000,0x0000, // u00de\n  0x0000,0x0000,0x3800,0x4400,0x4400,0x4800,0x7c00,0x4200,0x4200,0x4200,0x6200,0x5c00,0x0000,0x0000, // u00df\n  0x0000,0x0000,0x1000,0x0800,0x0000,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u00e0\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u00e1\n  0x0000,0x0000,0x1800,0x2400,0x0000,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u00e2\n  0x0000,0x0000,0x3200,0x4c00,0x0000,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u00e3\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u00e4\n  0x0000,0x0000,0x1800,0x2400,0x1800,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u00e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6c00,0x1200,0x7200,0x9e00,0x9000,0x9000,0x6c00,0x0000,0x0000, // u00e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4000,0x4200,0x3c00,0x1000,0x2000, // u00e7\n  0x0000,0x0000,0x1000,0x0800,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000, // u00e8\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000, // u00e9\n  0x0000,0x0000,0x1800,0x2400,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000, // u00ea\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000, // u00eb\n  0x0000,0x0000,0x2000,0x1000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u00ec\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u00ed\n  0x0000,0x0000,0x3000,0x4800,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u00ee\n  0x0000,0x0000,0x4800,0x4800,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u00ef\n  0x0000,0x0000,0x2800,0x1000,0x2800,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u00f0\n  0x0000,0x0000,0x3200,0x4c00,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u00f1\n  0x0000,0x0000,0x1000,0x0800,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u00f2\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u00f3\n  0x0000,0x0000,0x1800,0x2400,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u00f4\n  0x0000,0x0000,0x3200,0x4c00,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u00f5\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u00f6\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x0000,0x7c00,0x0000,0x1000,0x1000,0x0000,0x0000,0x0000, // u00f7\n  0x0000,0x0000,0x0000,0x0000,0x0200,0x3c00,0x4600,0x4a00,0x5200,0x6200,0x4200,0xbc00,0x0000,0x0000, // u00f8\n  0x0000,0x0000,0x1000,0x0800,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u00f9\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u00fa\n  0x0000,0x0000,0x1800,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u00fb\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u00fc\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x3c00, // u00fd\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x7c00,0x4000,0x4000, // u00fe\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x3c00, // u00ff\n  0x3c00,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u0100\n  0x0000,0x0000,0x0000,0x3c00,0x0000,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u0101\n  0x2400,0x1800,0x0000,0x3c00,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u0102\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u0103\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0400,0x0300, // u0104\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0400,0x0300, // u0105\n  0x0800,0x1000,0x0000,0x3c00,0x4200,0x4200,0x4000,0x4000,0x4000,0x4200,0x4200,0x3c00,0x0000,0x0000, // u0106\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4000,0x4200,0x3c00,0x0000,0x0000, // u0107\n  0x1800,0x2400,0x0000,0x3c00,0x4200,0x4200,0x4000,0x4000,0x4000,0x4200,0x4200,0x3c00,0x0000,0x0000, // u0108\n  0x0000,0x0000,0x1800,0x2400,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4000,0x4200,0x3c00,0x0000,0x0000, // u0109\n  0x1000,0x1000,0x0000,0x3c00,0x4200,0x4200,0x4000,0x4000,0x4000,0x4200,0x4200,0x3c00,0x0000,0x0000, // u010a\n  0x0000,0x0000,0x1000,0x1000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4000,0x4200,0x3c00,0x0000,0x0000, // u010b\n  0x2400,0x1800,0x0000,0x3c00,0x4200,0x4200,0x4000,0x4000,0x4000,0x4200,0x4200,0x3c00,0x0000,0x0000, // u010c\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4000,0x4200,0x3c00,0x0000,0x0000, // u010d\n  0x2400,0x1800,0x0000,0x7800,0x4400,0x4200,0x4200,0x4200,0x4200,0x4200,0x4400,0x7800,0x0000,0x0000, // u010e\n  0x2400,0x1800,0x0200,0x0200,0x0200,0x3e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u010f\n  0x0000,0x0000,0x7800,0x4400,0x4200,0x4200,0xf200,0x4200,0x4200,0x4200,0x4400,0x7800,0x0000,0x0000, // u0110\n  0x0000,0x0000,0x0200,0x0f00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u0111\n  0x3c00,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u0112\n  0x0000,0x0000,0x0000,0x3c00,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000, // u0113\n  0x2400,0x1800,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u0114\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000, // u0115\n  0x1000,0x1000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u0116\n  0x0000,0x0000,0x1000,0x1000,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000, // u0117\n  0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0400,0x0300, // u0118\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0800,0x0600, // u0119\n  0x2400,0x1800,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u011a\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000, // u011b\n  0x1800,0x2400,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4e00,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u011c\n  0x0000,0x0000,0x1800,0x2400,0x0000,0x3e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x3c00, // u011d\n  0x2400,0x1800,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4e00,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u011e\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x3e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x3c00, // u011f\n  0x1000,0x1000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4e00,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u0120\n  0x0000,0x0000,0x0800,0x0800,0x0000,0x3e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x3c00, // u0121\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4000,0x4000,0x4e00,0x4200,0x4200,0x4200,0x3c00,0x1000,0x2000, // u0122\n  0x0000,0x0400,0x0800,0x0800,0x0000,0x3e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x3c00, // u0123\n  0x1800,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u0124\n  0x0c00,0x1200,0x4000,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u0125\n  0x0000,0x0000,0x4200,0xff00,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u0126\n  0x0000,0x0000,0x4000,0xf000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u0127\n  0x3200,0x4c00,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u0128\n  0x0000,0x0000,0x3400,0x5800,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u0129\n  0x7c00,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u012a\n  0x0000,0x0000,0x0000,0x7800,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u012b\n  0x2400,0x1800,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u012c\n  0x0000,0x0000,0x4800,0x3000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u012d\n  0x0000,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x1000,0x0c00, // u012e\n  0x0000,0x0000,0x1000,0x1000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x1000,0x0c00, // u012f\n  0x1000,0x1000,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u0130\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u0131\n  0x0000,0x0000,0xe700,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x5200,0x5200,0xec00,0x0000,0x0000, // u0132\n  0x0000,0x0000,0x4200,0x4200,0x0000,0xc600,0x4200,0x4200,0x4200,0x4200,0x4200,0xf200,0x1200,0x0c00, // u0133\n  0x0c00,0x1200,0x0000,0x0e00,0x0400,0x0400,0x0400,0x0400,0x0400,0x4400,0x4400,0x3800,0x0000,0x0000, // u0134\n  0x0000,0x0000,0x0c00,0x1200,0x0000,0x0c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x4400,0x4400,0x3800, // u0135\n  0x0000,0x0000,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x5200,0x1000,0x2000, // u0136\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x5200,0x1000,0x2000, // u0137\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x0000,0x0000, // u0138\n  0x2000,0x4000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u0139\n  0x0800,0x1000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u013a\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x1000,0x2000, // u013b\n  0x0000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x1000,0x2000, // u013c\n  0x2400,0x1800,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u013d\n  0x4800,0x3000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u013e\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4400,0x4400,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u013f\n  0x0000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1100,0x1100,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u0140\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x6000,0xc000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u0141\n  0x0000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1800,0x3000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u0142\n  0x0800,0x1000,0x4200,0x4200,0x4200,0x6200,0x5200,0x4a00,0x4600,0x4200,0x4200,0x4200,0x0000,0x0000, // u0143\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u0144\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x6200,0x5200,0x4a00,0x4600,0x4200,0x4200,0x5200,0x1000,0x2000, // u0145\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x5200,0x1000,0x2000, // u0146\n  0x2400,0x1800,0x4200,0x4200,0x4200,0x6200,0x5200,0x4a00,0x4600,0x4200,0x4200,0x4200,0x0000,0x0000, // u0147\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u0148\n  0x0000,0x4000,0x4000,0x8000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u0149\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x6200,0x5200,0x4a00,0x4600,0x4200,0x4200,0x4200,0x0200,0x0c00, // u014a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0200,0x0c00, // u014b\n  0x3c00,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u014c\n  0x0000,0x0000,0x0000,0x3c00,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u014d\n  0x2400,0x1800,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u014e\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u014f\n  0x1200,0x2400,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u0150\n  0x0000,0x0000,0x1200,0x2400,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u0151\n  0x0000,0x0000,0x7e00,0x9000,0x9000,0x9000,0x9c00,0x9000,0x9000,0x9000,0x9000,0x7e00,0x0000,0x0000, // u0152\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x9200,0x9200,0x9e00,0x9000,0x9000,0x7c00,0x0000,0x0000, // u0153\n  0x0800,0x1000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x7c00,0x5000,0x4800,0x4400,0x4200,0x0000,0x0000, // u0154\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x5e00,0x6000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000, // u0155\n  0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x7c00,0x5000,0x4800,0x4400,0x5200,0x1000,0x2000, // u0156\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x5e00,0x6000,0x4000,0x4000,0x4000,0x4000,0x6000,0x2000,0x4000, // u0157\n  0x2400,0x1800,0x0000,0x7c00,0x4200,0x4200,0x4200,0x7c00,0x5000,0x4800,0x4400,0x4200,0x0000,0x0000, // u0158\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x5e00,0x6000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000, // u0159\n  0x0800,0x1000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x3c00,0x0200,0x0200,0x4200,0x3c00,0x0000,0x0000, // u015a\n  0x0000,0x0000,0x0400,0x0800,0x0000,0x3e00,0x4000,0x4000,0x3c00,0x0200,0x0200,0x7c00,0x0000,0x0000, // u015b\n  0x1800,0x2400,0x0000,0x3c00,0x4200,0x4000,0x4000,0x3c00,0x0200,0x0200,0x4200,0x3c00,0x0000,0x0000, // u015c\n  0x0000,0x0000,0x1800,0x2400,0x0000,0x3e00,0x4000,0x4000,0x3c00,0x0200,0x0200,0x7c00,0x0000,0x0000, // u015d\n  0x0000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x3c00,0x0200,0x0200,0x4200,0x4200,0x3c00,0x1000,0x2000, // u015e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4000,0x4000,0x3c00,0x0200,0x0200,0x7c00,0x1000,0x2000, // u015f\n  0x2400,0x1800,0x0000,0x3c00,0x4200,0x4000,0x4000,0x3c00,0x0200,0x0200,0x4200,0x3c00,0x0000,0x0000, // u0160\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x3e00,0x4000,0x4000,0x3c00,0x0200,0x0200,0x7c00,0x0000,0x0000, // u0161\n  0x0000,0x0000,0xfe00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1800,0x0800,0x1000, // u0162\n  0x0000,0x0000,0x1000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x1000,0x1000,0x1000,0x0e00,0x0400,0x0800, // u0163\n  0x2400,0x1800,0x0000,0xfe00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000, // u0164\n  0x2400,0x1800,0x0000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x1000,0x1000,0x1000,0x0e00,0x0000,0x0000, // u0165\n  0x0000,0x0000,0xfe00,0x1000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000, // u0166\n  0x0000,0x0000,0x1000,0x1000,0x1000,0x7c00,0x1000,0x3800,0x1000,0x1000,0x1000,0x0e00,0x0000,0x0000, // u0167\n  0x3200,0x4c00,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u0168\n  0x0000,0x0000,0x3200,0x4c00,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u0169\n  0x3c00,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u016a\n  0x0000,0x0000,0x0000,0x3c00,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u016b\n  0x2400,0x1800,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u016c\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u016d\n  0x1800,0x2400,0x1800,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u016e\n  0x0000,0x0000,0x1800,0x2400,0x1800,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u016f\n  0x1200,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u0170\n  0x0000,0x0000,0x1200,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u0171\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0800,0x0600, // u0172\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0400,0x0300, // u0173\n  0x1800,0x2400,0x0000,0x8200,0x8200,0x8200,0x8200,0x9200,0x9200,0xaa00,0xc600,0x8200,0x0000,0x0000, // u0174\n  0x0000,0x0000,0x1800,0x2400,0x0000,0x8200,0x8200,0x9200,0x9200,0x9200,0x9200,0x7c00,0x0000,0x0000, // u0175\n  0x1800,0x2400,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000, // u0176\n  0x0000,0x0000,0x1800,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x3c00, // u0177\n  0x4400,0x4400,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000, // u0178\n  0x0800,0x1000,0x0000,0x7e00,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u0179\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x7e00,0x0400,0x0800,0x1000,0x2000,0x4000,0x7e00,0x0000,0x0000, // u017a\n  0x1000,0x1000,0x0000,0x7e00,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u017b\n  0x0000,0x0000,0x1000,0x1000,0x0000,0x7e00,0x0400,0x0800,0x1000,0x2000,0x4000,0x7e00,0x0000,0x0000, // u017c\n  0x2400,0x1800,0x0000,0x7e00,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u017d\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x7e00,0x0400,0x0800,0x1000,0x2000,0x4000,0x7e00,0x0000,0x0000, // u017e\n  0x0000,0x0000,0x0e00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000, // u017f\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x0200,0x0200,0x0200,0x0200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u0186\n  0x0000,0x0000,0x7e00,0x0200,0x0200,0x0200,0x1e00,0x0200,0x0200,0x0200,0x0200,0x7e00,0x0000,0x0000, // u018e\n  0x0000,0x0000,0x3c00,0x4200,0x0200,0x0200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u018f\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4000,0x3800,0x4000,0x4000,0x4200,0x4200,0x3c00,0x0000,0x0000, // u0190\n  0x0000,0x0000,0x0c00,0x1200,0x1000,0x1000,0x7c00,0x1000,0x1000,0x1000,0x1000,0x1000,0x9000,0x6000, // u0192\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x6200,0x5200,0x4a00,0x4600,0x4200,0x4200,0x4200,0x4000,0x8000, // u019d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0200,0x0200, // u019e\n  0x0000,0x0000,0x7e00,0x0200,0x0400,0x0800,0x7e00,0x1000,0x2000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u01b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0400,0x0800,0x7c00,0x1000,0x2000,0x7e00,0x0000,0x0000, // u01b6\n  0x0000,0x0000,0x7e00,0x0200,0x0400,0x0800,0x1c00,0x0200,0x0200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u01b7\n  0x2400,0x1800,0x0000,0x3c00,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u01cd\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u01ce\n  0x2400,0x1800,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u01cf\n  0x0000,0x0000,0x4800,0x3000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u01d0\n  0x2400,0x1800,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u01d1\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u01d2\n  0x2400,0x1800,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u01d3\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u01d4\n  0x7c00,0x0000,0x7e00,0x9000,0x9000,0x9000,0xfc00,0x9000,0x9000,0x9000,0x9000,0x9e00,0x0000,0x0000, // u01e2\n  0x0000,0x0000,0x0000,0x7c00,0x0000,0x6c00,0x1200,0x7200,0x9e00,0x9000,0x9000,0x6c00,0x0000,0x0000, // u01e3\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4000,0x4000,0x4e00,0x4200,0x4f00,0x4200,0x3c00,0x0000,0x0000, // u01e4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4200,0x4200,0x4f00,0x4200,0x4200,0x3e00,0x0200,0x3c00, // u01e5\n  0x2400,0x1800,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4e00,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u01e6\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x3e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x3c00, // u01e7\n  0x2400,0x1800,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x0000,0x0000, // u01e8\n  0x2400,0x1800,0x4000,0x4000,0x4000,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x0000,0x0000, // u01e9\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0800,0x0600, // u01ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0800,0x0600, // u01eb\n  0x3c00,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0800,0x0600, // u01ec\n  0x0000,0x0000,0x0000,0x3c00,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0800,0x0600, // u01ed\n  0x2400,0x1800,0x0000,0x7e00,0x0400,0x0800,0x1c00,0x0200,0x0200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u01ee\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x7e00,0x0200,0x0400,0x0800,0x1c00,0x0200,0x0200,0x4200,0x3c00, // u01ef\n  0x0000,0x0000,0x1200,0x0c00,0x0000,0x0c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x4400,0x4400,0x3800, // u01f0\n  0x0800,0x1000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4e00,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u01f4\n  0x0000,0x0000,0x0400,0x0800,0x0000,0x3e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x3c00, // u01f5\n  0x0800,0x1000,0x0000,0x7e00,0x9000,0x9000,0x9000,0xfc00,0x9000,0x9000,0x9000,0x9e00,0x0000,0x0000, // u01fc\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x6c00,0x1200,0x7200,0x9e00,0x9000,0x9000,0x6c00,0x0000,0x0000, // u01fd\n  0x0800,0x1000,0x0000,0x3d00,0x4200,0x4600,0x4a00,0x5200,0x6200,0x4200,0xc200,0x3c00,0x0000,0x0000, // u01fe\n  0x0000,0x0000,0x0800,0x1000,0x0200,0x3c00,0x4600,0x4a00,0x5200,0x6200,0x4200,0xbc00,0x0000,0x0000, // u01ff\n  0x0000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x3c00,0x0200,0x0200,0x4200,0x4200,0x3c00,0x1000,0x2000, // u0218\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4000,0x4000,0x3c00,0x0200,0x0200,0x7c00,0x1000,0x2000, // u0219\n  0x0000,0x0000,0xfe00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1800,0x0800,0x1000, // u021a\n  0x0000,0x0000,0x1000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x1000,0x1000,0x1000,0x0e00,0x0200,0x0400, // u021b\n  0x7c00,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000, // u0232\n  0x0000,0x0000,0x0000,0x3c00,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x3c00, // u0233\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x4400,0x4400,0x3800, // u0237\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x0200,0x0200,0x0200,0x4200,0x3c00,0x0000,0x0000, // u0254\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x0200,0x0200,0x3c00,0x0000,0x0000, // u0258\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x0200,0x0200,0x7e00,0x4200,0x4200,0x3c00,0x0000,0x0000, // u0259\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4000,0x3800,0x4000,0x4200,0x3c00,0x0000,0x0000, // u025b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4000,0x8000, // u0272\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0200,0x0400,0x0800,0x1c00,0x0200,0x0200,0x4200,0x3c00, // u0292\n  0x0800,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bb\n  0x0800,0x0800,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bc\n  0x1000,0x1000,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bd\n  0x1800,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02c6\n  0x2400,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02c7\n  0x2400,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02d8\n  0x1000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02d9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x0600, // u02db\n  0x3200,0x4c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02dc\n  0x1200,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02dd\n  0x1000,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0300\n  0x0800,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0301\n  0x1800,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0302\n  0x3200,0x4c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0303\n  0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0304\n  0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0305\n  0x2400,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0306\n  0x1000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0307\n  0x2400,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0308\n  0x1800,0x2400,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030a\n  0x1200,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030b\n  0x2400,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x1000, // u0329\n  0x4000,0x8000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0384\n  0x0800,0x1000,0x0000,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0385\n  0x4000,0x8000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u0386\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0387\n  0x4000,0x8000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u0388\n  0x4000,0x8000,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u0389\n  0x4000,0x8000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u038a\n  0x4000,0x8000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u038c\n  0x4000,0x8000,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000, // u038e\n  0x4000,0x8000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x2400,0x2400,0x6600,0x0000,0x0000, // u038f\n  0x0800,0x1000,0x4800,0x4800,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0c00,0x0000,0x0000, // u0390\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u0391\n  0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x7c00,0x4200,0x4200,0x4200,0x4200,0x7c00,0x0000,0x0000, // u0392\n  0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000, // u0393\n  0x0000,0x0000,0x1000,0x1000,0x2800,0x2800,0x4400,0x4400,0x4400,0x8200,0x8200,0xfe00,0x0000,0x0000, // u0394\n  0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u0395\n  0x0000,0x0000,0x7e00,0x0200,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u0396\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u0397\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x5a00,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u0398\n  0x0000,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u0399\n  0x0000,0x0000,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x0000,0x0000, // u039a\n  0x0000,0x0000,0x1000,0x1000,0x2800,0x2800,0x4400,0x4400,0x4400,0x8200,0x8200,0x8200,0x0000,0x0000, // u039b\n  0x0000,0x0000,0x8200,0xc600,0xaa00,0x9200,0x9200,0x8200,0x8200,0x8200,0x8200,0x8200,0x0000,0x0000, // u039c\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x6200,0x5200,0x4a00,0x4600,0x4200,0x4200,0x4200,0x0000,0x0000, // u039d\n  0x0000,0x0000,0x7e00,0x0000,0x0000,0x0000,0x3c00,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0000,0x0000, // u039e\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u039f\n  0x0000,0x0000,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u03a0\n  0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x7c00,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000, // u03a1\n  0x0000,0x0000,0x7e00,0x4000,0x2000,0x1000,0x0800,0x0800,0x1000,0x2000,0x4000,0x7e00,0x0000,0x0000, // u03a3\n  0x0000,0x0000,0xfe00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000, // u03a4\n  0x0000,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000, // u03a5\n  0x0000,0x0000,0x1000,0x7c00,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x7c00,0x1000,0x0000,0x0000, // u03a6\n  0x0000,0x0000,0x4200,0x4200,0x2400,0x2400,0x1800,0x1800,0x2400,0x2400,0x4200,0x4200,0x0000,0x0000, // u03a7\n  0x0000,0x0000,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x7c00,0x1000,0x1000,0x0000,0x0000, // u03a8\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x2400,0x2400,0x6600,0x0000,0x0000, // u03a9\n  0x4400,0x4400,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u03aa\n  0x4400,0x4400,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000, // u03ab\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x3a00,0x4600,0x4400,0x4400,0x4400,0x4600,0x3a00,0x0000,0x0000, // u03ac\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x3c00,0x4200,0x4000,0x3800,0x4000,0x4200,0x3c00,0x0000,0x0000, // u03ad\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0200,0x0200, // u03ae\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0c00,0x0000,0x0000, // u03af\n  0x0800,0x1000,0x0000,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u03b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3a00,0x4600,0x4400,0x4400,0x4400,0x4600,0x3a00,0x0000,0x0000, // u03b1\n  0x0000,0x0000,0x3800,0x4400,0x4400,0x4800,0x7c00,0x4200,0x4200,0x4200,0x4200,0x7c00,0x4000,0x4000, // u03b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x2800,0x1000,0x1000,0x1000, // u03b3\n  0x0000,0x0000,0x3e00,0x1000,0x0800,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u03b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4000,0x3800,0x4000,0x4200,0x3c00,0x0000,0x0000, // u03b5\n  0x0000,0x0000,0x7e00,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x4000,0x4000,0x3c00,0x0200,0x0400, // u03b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0200,0x0200, // u03b7\n  0x0000,0x0000,0x3800,0x4400,0x4400,0x4400,0x7c00,0x4400,0x4400,0x4400,0x4400,0x3800,0x0000,0x0000, // u03b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0c00,0x0000,0x0000, // u03b9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x0000,0x0000, // u03ba\n  0x0000,0x0000,0x2000,0x2000,0x1000,0x1000,0x2800,0x2800,0x4400,0x4400,0x8200,0x8200,0x0000,0x0000, // u03bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4600,0x7a00,0x4000,0x4000, // u03bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x2400,0x2400,0x1800,0x1800,0x0000,0x0000, // u03bd\n  0x0000,0x0000,0x3e00,0x4000,0x4000,0x4000,0x3c00,0x4000,0x4000,0x4000,0x4000,0x3c00,0x0200,0x0400, // u03be\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u03bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u03c0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x7c00,0x4000,0x4000, // u03c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4000,0x4000,0x3c00,0x0200,0x0400, // u03c2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4400,0x4400,0x4400,0x4400,0x4400,0x3800,0x0000,0x0000, // u03c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x1000,0x1000,0x1000,0x1000,0x1000,0x0c00,0x0000,0x0000, // u03c4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u03c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4c00,0x9200,0x9200,0x9200,0x9200,0x9200,0x7c00,0x1000,0x1000, // u03c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x2400,0x2400,0x1800,0x2400,0x2400,0x4200,0x4200, // u03c7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x7c00,0x1000,0x1000, // u03c8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x8200,0x9200,0x9200,0x9200,0x9200,0x6c00,0x0000,0x0000, // u03c9\n  0x0000,0x0000,0x4800,0x4800,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0c00,0x0000,0x0000, // u03ca\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u03cb\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u03cc\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u03cd\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x4400,0x8200,0x9200,0x9200,0x9200,0x9200,0x6c00,0x0000,0x0000, // u03ce\n  0x0000,0x0000,0x3800,0x4400,0x4400,0x4400,0x3e00,0x0400,0xc400,0x4400,0x4400,0x3800,0x0000,0x0000, // u03d1\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x7c00,0x9200,0x9200,0x9200,0x9200,0x9200,0x7c00,0x1000,0x0000, // u03d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc200,0x2400,0x1800,0x1000,0x3000,0x4800,0x8600,0x0000,0x0000, // u03f0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x7c00,0x4000,0x3c00, // u03f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4000,0x4200,0x3c00,0x0000,0x0000, // u03f2\n  0x0000,0x0000,0x0400,0x0400,0x0000,0x0c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x4400,0x4400,0x3800, // u03f3\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u03f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2000,0x4000,0x7c00,0x4000,0x2000,0x1e00,0x0000,0x0000, // u03f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7800,0x0400,0x0200,0x3e00,0x0200,0x0400,0x7800,0x0000,0x0000, // u03f6\n  0x1000,0x0800,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u0400\n  0x2400,0x2400,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u0401\n  0x0000,0x0000,0xf800,0x2000,0x2000,0x3c00,0x2200,0x2200,0x2200,0x2200,0x2200,0x2400,0x0000,0x0000, // u0402\n  0x0800,0x1000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000, // u0403\n  0x0000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x4200,0x3c00,0x0000,0x0000, // u0404\n  0x0000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x3c00,0x0200,0x0200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u0405\n  0x0000,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u0406\n  0x4400,0x4400,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u0407\n  0x0000,0x0000,0x0e00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x4400,0x4400,0x3800,0x0000,0x0000, // u0408\n  0x0000,0x0000,0x3000,0x5000,0x9000,0x9c00,0x9200,0x9200,0x9200,0x9200,0x9200,0x9c00,0x0000,0x0000, // u0409\n  0x0000,0x0000,0x9000,0x9000,0x9000,0x9c00,0xf200,0x9200,0x9200,0x9200,0x9200,0x9c00,0x0000,0x0000, // u040a\n  0x0000,0x0000,0xf800,0x2000,0x2000,0x3c00,0x2200,0x2200,0x2200,0x2200,0x2200,0x2200,0x0000,0x0000, // u040b\n  0x0800,0x1000,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x0000,0x0000, // u040c\n  0x1000,0x0800,0x4200,0x4200,0x4200,0x4600,0x4a00,0x5200,0x6200,0x4200,0x4200,0x4200,0x0000,0x0000, // u040d\n  0x2400,0x1800,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x0200,0x3c00,0x0000,0x0000, // u040e\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x7e00,0x1800,0x1800, // u040f\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u0410\n  0x0000,0x0000,0x7c00,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x7c00,0x0000,0x0000, // u0411\n  0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x7c00,0x4200,0x4200,0x4200,0x4200,0x7c00,0x0000,0x0000, // u0412\n  0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000, // u0413\n  0x0000,0x0000,0x3c00,0x4400,0x4400,0x4400,0x4400,0x4400,0x4400,0x4400,0x4400,0xfe00,0x8200,0x0000, // u0414\n  0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u0415\n  0x0000,0x0000,0x9200,0x9200,0x9200,0x5400,0x3800,0x5400,0x9200,0x9200,0x9200,0x9200,0x0000,0x0000, // u0416\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x0200,0x1c00,0x0200,0x0200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u0417\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4600,0x4a00,0x5200,0x6200,0x4200,0x4200,0x4200,0x0000,0x0000, // u0418\n  0x2400,0x1800,0x4200,0x4200,0x4200,0x4600,0x4a00,0x5200,0x6200,0x4200,0x4200,0x4200,0x0000,0x0000, // u0419\n  0x0000,0x0000,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x0000,0x0000, // u041a\n  0x0000,0x0000,0x0e00,0x1200,0x2200,0x2200,0x2200,0x2200,0x2200,0x2200,0x2200,0x4200,0x0000,0x0000, // u041b\n  0x0000,0x0000,0x8200,0xc600,0xaa00,0x9200,0x9200,0x8200,0x8200,0x8200,0x8200,0x8200,0x0000,0x0000, // u041c\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u041d\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u041e\n  0x0000,0x0000,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u041f\n  0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x7c00,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000, // u0420\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4000,0x4000,0x4000,0x4000,0x4200,0x4200,0x3c00,0x0000,0x0000, // u0421\n  0x0000,0x0000,0xfe00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000, // u0422\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x0200,0x3c00,0x0000,0x0000, // u0423\n  0x0000,0x1000,0x7c00,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x7c00,0x1000,0x0000, // u0424\n  0x0000,0x0000,0x4200,0x4200,0x2400,0x2400,0x1800,0x1800,0x2400,0x2400,0x4200,0x4200,0x0000,0x0000, // u0425\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3f00,0x0100,0x0100, // u0426\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x0200,0x0200,0x0000,0x0000, // u0427\n  0x0000,0x0000,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x7e00,0x0000,0x0000, // u0428\n  0x0000,0x0000,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x7f00,0x0100,0x0100, // u0429\n  0x0000,0x0000,0xc000,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x7c00,0x0000,0x0000, // u042a\n  0x0000,0x0000,0x8200,0x8200,0x8200,0xf200,0x8a00,0x8a00,0x8a00,0x8a00,0x8a00,0xf200,0x0000,0x0000, // u042b\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x7c00,0x0000,0x0000, // u042c\n  0x0000,0x0000,0x3c00,0x4200,0x0200,0x0200,0x1e00,0x0200,0x0200,0x0200,0x4200,0x3c00,0x0000,0x0000, // u042d\n  0x0000,0x0000,0x8c00,0x9200,0x9200,0x9200,0x9200,0xf200,0x9200,0x9200,0x9200,0x8c00,0x0000,0x0000, // u042e\n  0x0000,0x0000,0x3e00,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0a00,0x1200,0x2200,0x4200,0x0000,0x0000, // u042f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u0430\n  0x0000,0x0000,0x3c00,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x7c00,0x0000,0x0000, // u0431\n  0x0000,0x0000,0x3800,0x4400,0x4400,0x4800,0x7c00,0x4200,0x4200,0x4200,0x4200,0x7c00,0x0000,0x0000, // u0432\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000, // u0433\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x3c00, // u0434\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000, // u0435\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x9200,0x9200,0x5400,0x3800,0x5400,0x9200,0x9200,0x0000,0x0000, // u0436\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x0200,0x1c00,0x0200,0x4200,0x3c00,0x0000,0x0000, // u0437\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u0438\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u0439\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x0000,0x0000, // u043a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2200,0x2200,0x2200,0x2200,0x2200,0x4200,0x0000,0x0000, // u043b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x8200,0xc600,0xaa00,0x9200,0x8200,0x8200,0x8200,0x0000,0x0000, // u043c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x0000,0x0000, // u043d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u043e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u043f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x7c00,0x4000,0x4000, // u0440\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4000,0x4200,0x3c00,0x0000,0x0000, // u0441\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000, // u0442\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x3c00, // u0443\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x7c00,0x9200,0x9200,0x9200,0x9200,0x9200,0x7c00,0x1000,0x0000, // u0444\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x2400,0x1800,0x2400,0x4200,0x4200,0x0000,0x0000, // u0445\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3f00,0x0100,0x0100, // u0446\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x0200,0x0000,0x0000, // u0447\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x7e00,0x0000,0x0000, // u0448\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x7f00,0x0100,0x0100, // u0449\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x2000,0x3c00,0x2200,0x2200,0x2200,0x3c00,0x0000,0x0000, // u044a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x8200,0x8200,0xf200,0x8a00,0x8a00,0x8a00,0xf200,0x0000,0x0000, // u044b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x7800,0x4400,0x4400,0x4400,0x7800,0x0000,0x0000, // u044c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x0200,0x1e00,0x0200,0x4200,0x3c00,0x0000,0x0000, // u044d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x8c00,0x9200,0x9200,0xf200,0x9200,0x9200,0x8c00,0x0000,0x0000, // u044e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4200,0x4200,0x3e00,0x1200,0x2200,0x4200,0x0000,0x0000, // u044f\n  0x0000,0x0000,0x1000,0x0800,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000, // u0450\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000, // u0451\n  0x0000,0x0000,0x4000,0xf000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0200,0x0c00, // u0452\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000, // u0453\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4000,0x7800,0x4000,0x4200,0x3c00,0x0000,0x0000, // u0454\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4000,0x4000,0x3c00,0x0200,0x0200,0x7c00,0x0000,0x0000, // u0455\n  0x0000,0x0000,0x1000,0x1000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u0456\n  0x0000,0x0000,0x4800,0x4800,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u0457\n  0x0000,0x0000,0x0400,0x0400,0x0000,0x0c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x4400,0x4400,0x3800, // u0458\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x9000,0x9c00,0x9200,0x9200,0x9200,0x9c00,0x0000,0x0000, // u0459\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x9000,0x9000,0x9c00,0xf200,0x9200,0x9200,0x9c00,0x0000,0x0000, // u045a\n  0x0000,0x0000,0x4000,0xf000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u045b\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x0000,0x0000, // u045c\n  0x0000,0x0000,0x1000,0x0800,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u045d\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x3c00, // u045e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x7e00,0x1800,0x1800, // u045f\n  0x0000,0x0000,0x4000,0xf000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x7c00,0x0000,0x0000, // u0462\n  0x0000,0x0000,0x2000,0x2000,0x7800,0x2000,0x2000,0x3c00,0x2200,0x2200,0x2200,0x3c00,0x0000,0x0000, // u0463\n  0x0000,0x0000,0xfe00,0x8200,0x4400,0x2800,0x3800,0x5400,0x9200,0x9200,0x9200,0x9200,0x0000,0x0000, // u046a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x4400,0x2800,0x3800,0x5400,0x9200,0x9200,0x0000,0x0000, // u046b\n  0x0200,0x0200,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000, // u0490\n  0x0000,0x0000,0x0000,0x0200,0x0200,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000, // u0491\n  0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0xf800,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000, // u0492\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4000,0x4000,0xf800,0x4000,0x4000,0x4000,0x0000,0x0000, // u0493\n  0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x0200,0x0400, // u0494\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4000,0x4000,0x7800,0x4400,0x4400,0x4400,0x0400,0x0800, // u0495\n  0x0000,0x0000,0x9200,0x9200,0x9200,0x5400,0x3800,0x5400,0x9200,0x9200,0x9200,0x9300,0x0100,0x0100, // u0496\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x9200,0x9200,0x5400,0x3800,0x5400,0x9200,0x9300,0x0100,0x0100, // u0497\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x0200,0x1c00,0x0200,0x0200,0x4200,0x4200,0x3c00,0x1000,0x1000, // u0498\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x0200,0x1c00,0x0200,0x4200,0x3c00,0x1000,0x1000, // u0499\n  0x0000,0x0000,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4300,0x0100,0x0100, // u049a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4300,0x0100,0x0100, // u049b\n  0x0000,0x0000,0x4200,0x4200,0x5400,0x5800,0x7000,0x7000,0x5800,0x5400,0x4200,0x4200,0x0000,0x0000, // u049c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x5400,0x5800,0x7000,0x5800,0x5400,0x4200,0x0000,0x0000, // u049d\n  0x0000,0x0000,0xc200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x0000,0x0000, // u04a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x0000,0x0000, // u04a1\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4300,0x0100,0x0100, // u04a2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4300,0x0100,0x0100, // u04a3\n  0x0000,0x0000,0x4700,0x4400,0x4400,0x4400,0x7c00,0x4400,0x4400,0x4400,0x4400,0x4400,0x0000,0x0000, // u04a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4700,0x4400,0x4400,0x7c00,0x4400,0x4400,0x4400,0x0000,0x0000, // u04a5\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4000,0x4000,0x4000,0x4000,0x4200,0x4200,0x3c00,0x1000,0x1000, // u04aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4000,0x4200,0x3c00,0x1000,0x1000, // u04ab\n  0x0000,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000, // u04ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x2800,0x1000,0x1000,0x1000, // u04af\n  0x0000,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x1000,0x7c00,0x1000,0x1000,0x1000,0x0000,0x0000, // u04b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x2800,0x1000,0x7c00,0x1000, // u04b1\n  0x0000,0x0000,0x4200,0x4200,0x2400,0x2400,0x1800,0x1800,0x2400,0x2400,0x4200,0x4300,0x0100,0x0100, // u04b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x2400,0x1800,0x2400,0x4200,0x4300,0x0100,0x0100, // u04b3\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x0200,0x0300,0x0100,0x0100, // u04b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x0300,0x0100,0x0100, // u04b7\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4a00,0x4a00,0x3e00,0x0a00,0x0a00,0x0200,0x0200,0x0000,0x0000, // u04b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4a00,0x4a00,0x3e00,0x0a00,0x0200,0x0200,0x0000,0x0000, // u04b9\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u04ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u04bb\n  0x0000,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u04c0\n  0x2400,0x1800,0x0000,0x9200,0x9200,0x9200,0x5400,0x3800,0x5400,0x9200,0x9200,0x9200,0x0000,0x0000, // u04c1\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x9200,0x9200,0x5400,0x3800,0x5400,0x9200,0x9200,0x0000,0x0000, // u04c2\n  0x0000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u04cf\n  0x2400,0x1800,0x0000,0x3c00,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u04d0\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u04d1\n  0x2400,0x2400,0x0000,0x3c00,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u04d2\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u04d3\n  0x0000,0x0000,0x7e00,0x9000,0x9000,0x9000,0xfc00,0x9000,0x9000,0x9000,0x9000,0x9e00,0x0000,0x0000, // u04d4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6c00,0x1200,0x7200,0x9e00,0x9000,0x9000,0x6c00,0x0000,0x0000, // u04d5\n  0x2400,0x1800,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u04d6\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000, // u04d7\n  0x0000,0x0000,0x3c00,0x4200,0x0200,0x0200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u04d8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x0200,0x0200,0x7e00,0x4200,0x4200,0x3c00,0x0000,0x0000, // u04d9\n  0x2400,0x2400,0x0000,0x3c00,0x4200,0x0200,0x0200,0x7e00,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u04da\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x3c00,0x0200,0x0200,0x7e00,0x4200,0x4200,0x3c00,0x0000,0x0000, // u04db\n  0x4400,0x4400,0x0000,0x9200,0x9200,0x9200,0x5400,0x3800,0x5400,0x9200,0x9200,0x9200,0x0000,0x0000, // u04dc\n  0x0000,0x0000,0x4400,0x4400,0x0000,0x9200,0x9200,0x5400,0x3800,0x5400,0x9200,0x9200,0x0000,0x0000, // u04dd\n  0x2400,0x2400,0x0000,0x3c00,0x4200,0x4200,0x0200,0x1c00,0x0200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u04de\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x3c00,0x4200,0x0200,0x1c00,0x0200,0x4200,0x3c00,0x0000,0x0000, // u04df\n  0x3c00,0x0000,0x4200,0x4200,0x4200,0x4600,0x4a00,0x5200,0x6200,0x4200,0x4200,0x4200,0x0000,0x0000, // u04e2\n  0x0000,0x0000,0x0000,0x3c00,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u04e3\n  0x2400,0x2400,0x0000,0x4200,0x4200,0x4200,0x4600,0x4a00,0x5200,0x6200,0x4200,0x4200,0x0000,0x0000, // u04e4\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000, // u04e5\n  0x2400,0x2400,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u04e6\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u04e7\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u04e8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4200,0x4200,0x3c00,0x0000,0x0000, // u04e9\n  0x2400,0x2400,0x0000,0x3c00,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u04ea\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4200,0x4200,0x3c00,0x0000,0x0000, // u04eb\n  0x2400,0x2400,0x0000,0x3c00,0x4200,0x0200,0x0200,0x1e00,0x0200,0x0200,0x4200,0x3c00,0x0000,0x0000, // u04ec\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x3c00,0x4200,0x0200,0x1e00,0x0200,0x4200,0x3c00,0x0000,0x0000, // u04ed\n  0x3c00,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x0200,0x3c00,0x0000,0x0000, // u04ee\n  0x0000,0x0000,0x0000,0x3c00,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x3c00, // u04ef\n  0x2400,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x0200,0x3c00,0x0000,0x0000, // u04f0\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x3c00, // u04f1\n  0x1200,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x0200,0x3c00,0x0000,0x0000, // u04f2\n  0x0000,0x0000,0x1200,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x3c00, // u04f3\n  0x2400,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x0200,0x0200,0x0000,0x0000, // u04f4\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x0200,0x0000,0x0000, // u04f5\n  0x4800,0x4800,0x0000,0x8200,0x8200,0x8200,0xf200,0x8a00,0x8a00,0x8a00,0x8a00,0xf200,0x0000,0x0000, // u04f8\n  0x0000,0x0000,0x4800,0x4800,0x0000,0x8200,0x8200,0xf200,0x8a00,0x8a00,0x8a00,0xf200,0x0000,0x0000, // u04f9\n  0x0000,0x0000,0x4200,0x4200,0x2200,0x2200,0x1400,0x2800,0x4400,0x4400,0x4200,0x4200,0x0000,0x0000, // u05d0\n  0x0000,0x0000,0x7c00,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x7f00,0x0000,0x0000, // u05d1\n  0x0000,0x0000,0x7000,0x0800,0x0800,0x0800,0x0800,0x0800,0x1400,0x2400,0x4200,0x8200,0x0000,0x0000, // u05d2\n  0x0000,0x0000,0x7f00,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0000,0x0000, // u05d3\n  0x0000,0x0000,0x7c00,0x0200,0x0200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u05d4\n  0x0000,0x0000,0x3000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,0x0000, // u05d5\n  0x0000,0x0000,0x7c00,0x0800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000, // u05d6\n  0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u05d7\n  0x0000,0x0000,0x4c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u05d8\n  0x0000,0x0000,0x3000,0x0800,0x0800,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d9\n  0x0000,0x0000,0x7c00,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200, // u05da\n  0x0000,0x0000,0x7c00,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x7c00,0x0000,0x0000, // u05db\n  0x4000,0x4000,0x7e00,0x0200,0x0200,0x0200,0x0200,0x0400,0x0800,0x1000,0x1000,0x1000,0x0000,0x0000, // u05dc\n  0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x7e00,0x0000,0x0000, // u05dd\n  0x0000,0x0000,0xdc00,0x6200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4e00,0x0000,0x0000, // u05de\n  0x0000,0x0000,0x7000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,0x0000, // u05df\n  0x0000,0x0000,0x3800,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x3c00,0x0000,0x0000, // u05e0\n  0x0000,0x0000,0xfc00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u05e1\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x2200,0x2200,0x2200,0x1400,0x1400,0x1800,0x6000,0x0000,0x0000, // u05e2\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x3200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200, // u05e3\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x3200,0x0200,0x0200,0x0200,0x0200,0x7c00,0x0000,0x0000, // u05e4\n  0x0000,0x0000,0x4200,0x4200,0x2200,0x2400,0x1800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u05e5\n  0x0000,0x0000,0x4200,0x4200,0x2200,0x2400,0x1800,0x1000,0x0800,0x0800,0x0400,0x7c00,0x0000,0x0000, // u05e6\n  0x0000,0x0000,0x7e00,0x0200,0x0200,0x4200,0x4200,0x4400,0x4800,0x4800,0x4800,0x4800,0x4000,0x4000, // u05e7\n  0x0000,0x0000,0x7c00,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0000,0x0000, // u05e8\n  0x0000,0x0000,0x9200,0x9200,0x9200,0x9200,0x9200,0xa200,0xc200,0x8200,0x8400,0xf800,0x0000,0x0000, // u05e9\n  0x0000,0x0000,0xfc00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x8200,0x0000,0x0000, // u05ea\n  0x0000,0x0000,0x7800,0x4400,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4400,0x7800,0x1000,0x1000, // u1e0c\n  0x0000,0x0000,0x0200,0x0200,0x0200,0x3e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0800,0x0800, // u1e0d\n  0x0000,0x0000,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x0000,0x3c00, // u1e34\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x0000,0x3c00, // u1e35\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x1000,0x1000, // u1e36\n  0x0000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x1000,0x1000, // u1e37\n  0x1000,0x1000,0x8200,0xc600,0xaa00,0x9200,0x9200,0x8200,0x8200,0x8200,0x8200,0x8200,0x0000,0x0000, // u1e40\n  0x0000,0x0000,0x1000,0x1000,0x0000,0xfc00,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x0000,0x0000, // u1e41\n  0x0000,0x0000,0x8200,0xc600,0xaa00,0x9200,0x9200,0x8200,0x8200,0x8200,0x8200,0x8200,0x1000,0x1000, // u1e42\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x0800,0x0800, // u1e43\n  0x1000,0x1000,0x4200,0x4200,0x4200,0x6200,0x5200,0x4a00,0x4600,0x4200,0x4200,0x4200,0x0000,0x0000, // u1e44\n  0x0000,0x0000,0x1000,0x1000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u1e45\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x6200,0x5200,0x4a00,0x4600,0x4200,0x4200,0x4200,0x1000,0x1000, // u1e46\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x1000,0x1000, // u1e47\n  0x0000,0x0000,0xfe00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0800,0x0800, // u1e6c\n  0x0000,0x0000,0x1000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x1000,0x1000,0x1000,0x0e00,0x0400,0x0400, // u1e6d\n  0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x4000,0x7e00,0x1000,0x1000, // u1eb8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x1000,0x1000, // u1eb9\n  0x3200,0x4c00,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000, // u1ebc\n  0x0000,0x0000,0x3200,0x4c00,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000, // u1ebd\n  0x0000,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x1000,0x1000, // u1eca\n  0x0000,0x0000,0x1000,0x1000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x1000,0x1000, // u1ecb\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x1000,0x1000, // u1ecc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x1000,0x1000, // u1ecd\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x1000,0x1000, // u1ee4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0800,0x0800, // u1ee5\n  0x6400,0x9800,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000, // u1ef8\n  0x0000,0x0000,0x3200,0x4c00,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x3c00, // u1ef9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2001\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2002\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2003\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2004\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2005\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2006\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2007\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2008\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2009\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2010\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2011\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2012\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2013\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2014\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2015\n  0x0000,0x0000,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x0000,0x0000, // u2016\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0000,0x7e00, // u2017\n  0x0000,0x0800,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2018\n  0x0000,0x0800,0x0800,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2019\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x1000,0x0000, // u201a\n  0x0000,0x1000,0x1000,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201b\n  0x0000,0x1200,0x2400,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201c\n  0x0000,0x1200,0x1200,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2400,0x2400,0x4800,0x0000, // u201e\n  0x0000,0x4800,0x4800,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201f\n  0x0000,0x0000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000, // u2020\n  0x0000,0x0000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x0000,0x0000, // u2021\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x3c00,0x3c00,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000, // u2022\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x9200,0x9200,0x0000,0x0000, // u2026\n  0x0000,0x0000,0x4800,0xa800,0x5000,0x1000,0x2000,0x2000,0x4000,0x5400,0xaa00,0x9400,0x0000,0x0000, // u2030\n  0x0000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2032\n  0x0000,0x2400,0x2400,0x2400,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2033\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x1000,0x2000,0x1000,0x0800,0x0400,0x0000,0x0000, // u2039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x1000,0x0800,0x0400,0x0800,0x1000,0x2000,0x0000,0x0000, // u203a\n  0x0000,0x0000,0x2400,0x2400,0x2400,0x2400,0x2400,0x2400,0x2400,0x0000,0x2400,0x2400,0x0000,0x0000, // u203c\n  0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u203e\n  0x0000,0x1800,0x2400,0x2400,0x2400,0x2400,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2070\n  0x1000,0x0000,0x3000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2071\n  0x0000,0x0400,0x0c00,0x1400,0x3e00,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2074\n  0x0000,0x3800,0x2000,0x3800,0x0400,0x0400,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2075\n  0x0000,0x1800,0x2000,0x3800,0x2400,0x2400,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2076\n  0x0000,0x3c00,0x0400,0x0800,0x0800,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2077\n  0x0000,0x1800,0x2400,0x1800,0x2400,0x2400,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2078\n  0x0000,0x1800,0x2400,0x2400,0x1c00,0x0400,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2079\n  0x0000,0x0000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207a\n  0x0000,0x0000,0x0000,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207b\n  0x0000,0x0000,0x0000,0x7c00,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207c\n  0x0000,0x0800,0x1000,0x1000,0x1000,0x1000,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207d\n  0x0000,0x1000,0x0800,0x0800,0x0800,0x0800,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207e\n  0x0000,0x0000,0x3800,0x2400,0x2400,0x2400,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x2400,0x2400,0x2400,0x2400,0x1800,0x0000,0x0000, // u2080\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x3000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u2081\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x2400,0x0400,0x0800,0x1000,0x3c00,0x0000,0x0000, // u2082\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x0400,0x1800,0x0400,0x0400,0x3800,0x0000,0x0000, // u2083\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0c00,0x1400,0x3e00,0x0400,0x0400,0x0000,0x0000, // u2084\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x2000,0x3800,0x0400,0x0400,0x3800,0x0000,0x0000, // u2085\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x2000,0x3800,0x2400,0x2400,0x1800,0x0000,0x0000, // u2086\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x0400,0x0800,0x0800,0x1000,0x1000,0x0000,0x0000, // u2087\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x2400,0x1800,0x2400,0x2400,0x1800,0x0000,0x0000, // u2088\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x2400,0x2400,0x1c00,0x0400,0x1800,0x0000,0x0000, // u2089\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x0000,0x0000, // u208a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000, // u208b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0000,0x7c00,0x0000,0x0000,0x0000, // u208c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x1000,0x1000,0x1000,0x1000,0x0800,0x0000,0x0000, // u208d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x0800,0x0800,0x0800,0x0800,0x1000,0x0000,0x0000, // u208e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x0400,0x1c00,0x2400,0x1c00,0x0000,0x0000, // u2090\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x2400,0x3c00,0x2000,0x1c00,0x0000,0x0000, // u2091\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x2400,0x2400,0x2400,0x1800,0x0000,0x0000, // u2092\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x2800,0x1000,0x2800,0x4400,0x0000,0x0000, // u2093\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x0400,0x3c00,0x2400,0x1800,0x0000,0x0000, // u2094\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x3800,0x2400,0x2400,0x2400,0x2400,0x0000,0x0000, // u2095\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2400,0x2800,0x3000,0x2800,0x2400,0x0000,0x0000, // u2096\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000, // u2097\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7800,0x5400,0x5400,0x5400,0x5400,0x0000,0x0000, // u2098\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x2400,0x2400,0x2400,0x3800,0x2000,0x2000, // u209a\n  0x0000,0x0000,0xf000,0x8800,0x8800,0x8800,0xf400,0x8400,0x8e00,0x8400,0x8400,0x8200,0x0000,0x0000, // u20a7\n  0x0000,0x0000,0xf200,0x8a00,0x8a00,0xaa00,0xaa00,0xaa00,0xaa00,0xa200,0xa200,0xbc00,0x0000,0x0000, // u20aa\n  0x0000,0x0000,0x0000,0x1c00,0x2200,0x4000,0xf800,0x4000,0xf800,0x4000,0x2200,0x1c00,0x0000,0x0000, // u20ac\n  0x0000,0x0000,0xfe00,0x1000,0x1000,0x1c00,0x7000,0x1c00,0x7000,0x1000,0x1000,0x1000,0x0000,0x0000, // u20ae\n  0x0000,0x0000,0x3c00,0x5200,0x5200,0x5000,0x5000,0x5000,0x5000,0x5200,0x5200,0x3c00,0x0000,0x0000, // u2102\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u210e\n  0x0000,0x0000,0x4000,0xf000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u210f\n  0x0000,0x0000,0x4200,0x4200,0x6200,0x5200,0x6a00,0x5600,0x4a00,0x4600,0x4200,0x4200,0x0000,0x0000, // u2115\n  0x0000,0x0000,0x9600,0x9600,0x9600,0xd000,0xf000,0xf000,0xb000,0x9600,0x9000,0x9600,0x0000,0x0000, // u2116\n  0x0000,0x0000,0x3c00,0x5200,0x5200,0x5200,0x5200,0x5200,0x5200,0x5200,0x5a00,0x3c00,0x0600,0x0000, // u211a\n  0x0000,0x0000,0xf800,0xa400,0xa400,0xa400,0xa400,0xb800,0xa800,0xb400,0xaa00,0xe600,0x0000,0x0000, // u211d\n  0x0000,0x0000,0xfb00,0x5500,0x5500,0x5100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2122\n  0x0000,0x0000,0x7e00,0x0200,0x0600,0x0a00,0x1400,0x2800,0x5000,0x6000,0x4000,0x7e00,0x0000,0x0000, // u2124\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x2400,0x2400,0x6600,0x0000,0x0000, // u2126\n  0x0000,0x0000,0x4400,0x4400,0x2200,0x2200,0x3400,0x5800,0x8800,0x8800,0x8400,0x4400,0x0000,0x0000, // u2135\n  0x0000,0x0000,0x0000,0x0000,0x2000,0x4000,0xfe00,0x4000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2190\n  0x0000,0x0000,0x1000,0x3800,0x5400,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000, // u2191\n  0x0000,0x0000,0x0000,0x0000,0x0800,0x0400,0xfe00,0x0400,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000, // u2192\n  0x0000,0x0000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x5400,0x3800,0x1000,0x0000,0x0000, // u2193\n  0x0000,0x0000,0x0000,0x0000,0x2400,0x4200,0xff00,0x4200,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2194\n  0x0000,0x0000,0x1000,0x3800,0x5400,0x1000,0x1000,0x1000,0x1000,0x5400,0x3800,0x1000,0x0000,0x0000, // u2195\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x4200,0xfe00,0x4200,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a4\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8400,0xfe00,0x8400,0x8800,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a6\n  0x0000,0x0000,0x1000,0x3800,0x5400,0x1000,0x1000,0x1000,0x5400,0x3800,0x1000,0x7c00,0x0000,0x0000, // u21a8\n  0x0000,0x0000,0x0200,0x0200,0x0200,0x0200,0x0200,0x2200,0x4200,0xfe00,0x4000,0x2000,0x0000,0x0000, // u21b5\n  0x0000,0x0000,0x0000,0xf000,0x3000,0x5000,0x9200,0x8200,0x8200,0x4400,0x3800,0x0000,0x0000,0x0000, // u21bb\n  0x0000,0x0000,0x0000,0x2000,0x4000,0xfe00,0x0000,0xfe00,0x0400,0x0800,0x0000,0x0000,0x0000,0x0000, // u21cb\n  0x0000,0x0000,0x0000,0x0800,0x0400,0xfe00,0x0000,0xfe00,0x4000,0x2000,0x0000,0x0000,0x0000,0x0000, // u21cc\n  0x0000,0x0000,0x0000,0x0000,0x2000,0x7e00,0xc000,0x7e00,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d0\n  0x0000,0x0000,0x1000,0x3800,0x6c00,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x0000,0x0000, // u21d1\n  0x0000,0x0000,0x0000,0x0000,0x0800,0xfc00,0x0600,0xfc00,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d2\n  0x0000,0x0000,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x6c00,0x3800,0x1000,0x0000,0x0000, // u21d3\n  0x0000,0x0000,0x0000,0x0000,0x2400,0x7e00,0xc300,0x7e00,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d4\n  0x0000,0x0000,0x1000,0x3800,0x6c00,0x2800,0x2800,0x2800,0x2800,0x6c00,0x3800,0x1000,0x0000,0x0000, // u21d5\n  0x0000,0x0000,0x8200,0x8200,0x8200,0x7c00,0x4400,0x4400,0x2800,0x2800,0x1000,0x1000,0x0000,0x0000, // u2200\n  0x0000,0x0000,0x0000,0x7e00,0x0200,0x0200,0x0200,0x7e00,0x0200,0x0200,0x0200,0x7e00,0x0000,0x0000, // u2203\n  0x0000,0x0000,0x0400,0x7e00,0x0a00,0x0a00,0x1200,0x7e00,0x1200,0x2200,0x2200,0x7e00,0x4000,0x0000, // u2204\n  0x0000,0x0000,0x0200,0x0400,0x7c00,0x8a00,0x9200,0x9200,0xa200,0x7c00,0x4000,0x8000,0x0000,0x0000, // u2205\n  0x0000,0x0000,0x1000,0x1000,0x2800,0x2800,0x4400,0x4400,0x4400,0x8200,0x8200,0xfe00,0x0000,0x0000, // u2206\n  0x0000,0x0000,0xfe00,0x8200,0x8200,0x4400,0x4400,0x4400,0x2800,0x2800,0x1000,0x1000,0x0000,0x0000, // u2207\n  0x0000,0x0000,0x0000,0x1e00,0x2000,0x4000,0x4000,0x7e00,0x4000,0x4000,0x2000,0x1e00,0x0000,0x0000, // u2208\n  0x0000,0x0000,0x0200,0x1e00,0x2400,0x4400,0x4800,0x7e00,0x4800,0x5000,0x3000,0x3e00,0x2000,0x0000, // u2209\n  0x0000,0x0000,0x0000,0x0000,0x1e00,0x2000,0x4000,0x7e00,0x4000,0x2000,0x1e00,0x0000,0x0000,0x0000, // u220a\n  0x0000,0x0000,0x0000,0x7800,0x0400,0x0200,0x0200,0x7e00,0x0200,0x0200,0x0400,0x7800,0x0000,0x0000, // u220b\n  0x0000,0x0000,0x4000,0x7800,0x2400,0x2200,0x1200,0x7e00,0x1200,0x0a00,0x0c00,0x7c00,0x0400,0x0000, // u220c\n  0x0000,0x0000,0x0000,0x0000,0x7800,0x0400,0x0200,0x7e00,0x0200,0x0400,0x7800,0x0000,0x0000,0x0000, // u220d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2212\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x0000,0x0000, // u2213\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x0000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x0000,0x0000, // u2214\n  0x0000,0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000,0x0000,0x0000,0x0000, // u2215\n  0x0000,0x0000,0x0000,0x0000,0x8000,0x4000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0000,0x0000,0x0000, // u2216\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2219\n  0x0000,0x0600,0x0400,0x0400,0x0400,0x0400,0x4400,0x4400,0x4400,0x2400,0x1400,0x0c00,0x0000,0x0000, // u221a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x9200,0x9200,0x9200,0x7c00,0x0000,0x0000,0x0000,0x0000, // u221e\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u221f\n  0x0000,0x0000,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x0000,0x0000, // u2225\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x2800,0x2800,0x4400,0x4400,0x8200,0x8200,0x0000,0x0000, // u2227\n  0x0000,0x0000,0x0000,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x2800,0x1000,0x1000,0x0000,0x0000, // u2228\n  0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u2229\n  0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u222a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3200,0x4c00,0x0000,0x3200,0x4c00,0x0000,0x0000,0x0000,0x0000, // u2248\n  0x0000,0x0000,0x0000,0x0000,0x0200,0x7e00,0x0800,0x1000,0x7e00,0x4000,0x0000,0x0000,0x0000,0x0000, // u2260\n  0x0000,0x0000,0x0000,0x0000,0x7e00,0x0000,0x0000,0x7e00,0x0000,0x0000,0x7e00,0x0000,0x0000,0x0000, // u2261\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x1000,0x2000,0x1000,0x0800,0x0400,0x0000,0x3e00,0x0000,0x0000, // u2264\n  0x0000,0x0000,0x0000,0x2000,0x1000,0x0800,0x0400,0x0800,0x1000,0x2000,0x0000,0x7c00,0x0000,0x0000, // u2265\n  0x0000,0x0000,0x0000,0x0900,0x1200,0x2400,0x4800,0x9000,0x4800,0x2400,0x1200,0x0900,0x0000,0x0000, // u226a\n  0x0000,0x0000,0x0000,0x9000,0x4800,0x2400,0x1200,0x0900,0x1200,0x2400,0x4800,0x9000,0x0000,0x0000, // u226b\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x3e00,0x0000,0x0000,0x0000, // u2282\n  0x0000,0x0000,0x0000,0x0000,0x7c00,0x0200,0x0200,0x0200,0x0200,0x0200,0x7c00,0x0000,0x0000,0x0000, // u2283\n  0x0000,0x0000,0x0000,0x3e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x3e00,0x0000,0x7e00,0x0000,0x0000, // u2286\n  0x0000,0x0000,0x0000,0x7c00,0x0200,0x0200,0x0200,0x0200,0x0200,0x7c00,0x0000,0x7e00,0x0000,0x0000, // u2287\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xfe00,0x0000,0x0000, // u22a5\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000, // u22c2\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000, // u22c3\n  0x0000,0x0000,0x0200,0x0400,0x7c00,0x8a00,0x9200,0x9200,0xa200,0x7c00,0x4000,0x8000,0x0000,0x0000, // u2300\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x2800,0x4400,0x8200,0x8200,0x8200,0x8200,0xfe00,0x0000,0x0000, // u2302\n  0x0000,0x0000,0x3800,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2308\n  0x0000,0x0000,0x3800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,0x0000, // u2309\n  0x0000,0x0000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x3800,0x0000,0x0000, // u230a\n  0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x3800,0x0000,0x0000, // u230b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2310\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2319\n  0x0000,0x0000,0x0c00,0x1200,0x1200,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2320\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x9000,0x9000,0x6000,0x0000,0x0000, // u2321\n  0x0400,0x0800,0x1000,0x1000,0x2000,0x2000,0x2000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000, // u239b\n  0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000, // u239c\n  0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x2000,0x2000,0x2000,0x1000,0x1000,0x0800,0x0400, // u239d\n  0x4000,0x2000,0x1000,0x1000,0x0800,0x0800,0x0800,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u239e\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u239f\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0800,0x0800,0x0800,0x1000,0x1000,0x2000,0x4000, // u23a0\n  0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000, // u23a1\n  0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000, // u23a2\n  0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00, // u23a3\n  0x7c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u23a4\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u23a5\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x7c00, // u23a6\n  0x0e00,0x1000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u23a7\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0xc000,0xc000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u23a8\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x1000,0x0e00, // u23a9\n  0xe000,0x1000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800, // u23ab\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0600,0x0600,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800, // u23ac\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1000,0xe000, // u23ad\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u23ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23af\n  0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23ba\n  0x0000,0x0000,0x0000,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x0000,0x0000,0x0000, // u23bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00, // u23bd\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u23d0\n  0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0000, // u2409\n  0x8000,0x8000,0x8000,0x8000,0x8000,0xf800,0x0000,0x1f00,0x1000,0x1c00,0x1000,0x1000,0x1000,0x0000, // u240a\n  0x8800,0x8800,0x5000,0x5000,0x2000,0x2000,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0000, // u240b\n  0xf800,0x8000,0xe000,0x8000,0x8000,0x8000,0x0000,0x1f00,0x1000,0x1c00,0x1000,0x1000,0x1000,0x0000, // u240c\n  0x7000,0x8800,0x8000,0x8000,0x8800,0x7000,0x0000,0x1e00,0x1100,0x1100,0x1e00,0x1200,0x1100,0x0000, // u240d\n  0x8800,0xc800,0xa800,0x9800,0x8800,0x8800,0x0000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1f00,0x0000, // u2424\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2500\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2501\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2502\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2503\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xaa00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2508\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xaa00,0xaa00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2509\n  0x1000,0x1000,0x1000,0x0000,0x1000,0x1000,0x0000,0x1000,0x1000,0x1000,0x0000,0x1000,0x1000,0x0000, // u250a\n  0x1800,0x1800,0x1800,0x0000,0x1800,0x1800,0x0000,0x1800,0x1800,0x1800,0x0000,0x1800,0x1800,0x0000, // u250b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u250c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x1f00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u250d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u250e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u250f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2510\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf000,0xf000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2511\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2512\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2513\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2514\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1f00,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2515\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2516\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2517\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xf000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2518\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xf000,0xf000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2519\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u251a\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u251b\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1f00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u251c\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1f00,0x1f00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u251d\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u251e\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u251f\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2520\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0x1f00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2521\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1f00,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2522\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2523\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xf000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2524\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xf000,0xf000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2525\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2526\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2527\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2528\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0xf800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2529\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xf800,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u252a\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u252b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u252c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xf000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u252d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x1f00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u252e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u252f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2530\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2531\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2532\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2533\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2534\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0xf000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2535\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2536\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2537\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2538\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2539\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u253a\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u253b\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u253c\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0xf000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u253d\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0x1f00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u253e\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0xff00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u253f\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2540\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2541\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2542\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0xf000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2543\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0x1f00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2544\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2545\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2546\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0xff00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2547\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2548\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2549\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u254a\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u254b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x0000,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2550\n  0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800, // u2551\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x1000,0x1f00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2552\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800, // u2553\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x2000,0x2f00,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800, // u2554\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xf000,0x1000,0xf000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2555\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800, // u2556\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0x0800,0xe800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800, // u2557\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1f00,0x1000,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2558\n  0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2559\n  0x2800,0x2800,0x2800,0x2800,0x2800,0x2f00,0x2000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255a\n  0x1000,0x1000,0x1000,0x1000,0x1000,0xf000,0x1000,0xf000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255b\n  0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255c\n  0x2800,0x2800,0x2800,0x2800,0x2800,0xe800,0x0800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255d\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1f00,0x1000,0x1f00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u255e\n  0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2f00,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800, // u255f\n  0x2800,0x2800,0x2800,0x2800,0x2800,0x2f00,0x2000,0x2f00,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800, // u2560\n  0x1000,0x1000,0x1000,0x1000,0x1000,0xf000,0x1000,0xf000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2561\n  0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0xe800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800, // u2562\n  0x2800,0x2800,0x2800,0x2800,0x2800,0xe800,0x0800,0xe800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800, // u2563\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x0000,0xff00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2564\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800, // u2565\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x0000,0xef00,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800, // u2566\n  0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0x0000,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2567\n  0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2568\n  0x2800,0x2800,0x2800,0x2800,0x2800,0xef00,0x0000,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2569\n  0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0x1000,0xff00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u256a\n  0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0xff00,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800, // u256b\n  0x2800,0x2800,0x2800,0x2800,0x2800,0xef00,0x0000,0xef00,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800, // u256c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u256d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0x2000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u256e\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x2000,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u256f\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x0800,0x0700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2570\n  0x0100,0x0200,0x0200,0x0400,0x0400,0x0800,0x0800,0x1000,0x1000,0x2000,0x2000,0x4000,0x4000,0x8000, // u2571\n  0x8000,0x4000,0x4000,0x2000,0x2000,0x1000,0x1000,0x0800,0x0800,0x0400,0x0400,0x0200,0x0200,0x0100, // u2572\n  0x8100,0x4200,0x4200,0x2400,0x2400,0x1800,0x1800,0x1800,0x1800,0x2400,0x2400,0x4200,0x4200,0x8100, // u2573\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2574\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2575\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2576\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2577\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf000,0xf000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2578\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2579\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u257b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257c\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u257d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xf000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257e\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u257f\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2580\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00, // u2581\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00, // u2582\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0xff00,0xff00, // u2583\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2584\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2585\n  0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2586\n  0x0000,0x0000,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2587\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2588\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00, // u2589\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00, // u258a\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800, // u258b\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000, // u258c\n  0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000, // u258d\n  0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000, // u258e\n  0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000, // u258f\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u2590\n  0x8800,0x2200,0x8800,0x2200,0x8800,0x2200,0x8800,0x2200,0x8800,0x2200,0x8800,0x2200,0x8800,0x2200, // u2591\n  0xaa00,0x5500,0xaa00,0x5500,0xaa00,0x5500,0xaa00,0x5500,0xaa00,0x5500,0xaa00,0x5500,0xaa00,0x5500, // u2592\n  0xee00,0xbb00,0xee00,0xbb00,0xee00,0xbb00,0xee00,0xbb00,0xee00,0xbb00,0xee00,0xbb00,0xee00,0xbb00, // u2593\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000, // u2596\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u2597\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2598\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2599\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u259a\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000, // u259b\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u259c\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u259d\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000, // u259e\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u259f\n  0x0000,0x0000,0x0000,0x0000,0x3c00,0x3c00,0x3c00,0x3c00,0x3c00,0x3c00,0x0000,0x0000,0x0000,0x0000, // u25a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x7e00,0x7e00,0x7e00,0x0000,0x0000, // u25ac\n  0x0000,0x0000,0x7e00,0x7e00,0x7e00,0x7e00,0x7e00,0x7e00,0x7e00,0x7e00,0x7e00,0x7e00,0x0000,0x0000, // u25ae\n  0x0000,0x0000,0x0000,0x1000,0x1000,0x3800,0x3800,0x7c00,0x7c00,0xfe00,0xfe00,0x0000,0x0000,0x0000, // u25b2\n  0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xfc00,0xf000,0xc000,0x0000,0x0000,0x0000,0x0000, // u25b6\n  0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xfc00,0xf000,0xc000,0x0000,0x0000,0x0000,0x0000, // u25ba\n  0x0000,0x0000,0x0000,0xfe00,0xfe00,0x7c00,0x7c00,0x3800,0x3800,0x1000,0x1000,0x0000,0x0000,0x0000, // u25bc\n  0x0000,0x0000,0x0000,0x0300,0x0f00,0x3f00,0xff00,0x3f00,0x0f00,0x0300,0x0000,0x0000,0x0000,0x0000, // u25c0\n  0x0000,0x0000,0x0000,0x0300,0x0f00,0x3f00,0xff00,0x3f00,0x0f00,0x0300,0x0000,0x0000,0x0000,0x0000, // u25c4\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x3800,0x7c00,0xfe00,0x7c00,0x3800,0x1000,0x0000,0x0000,0x0000, // u25c6\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x2800,0x4400,0x8200,0x4400,0x2800,0x1000,0x0000,0x0000,0x0000, // u25ca\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x2400,0x2400,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000, // u25cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x3c00,0x3c00,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000, // u25cf\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xe700,0xc300,0xc300,0xe700,0xff00,0xff00,0xff00,0xff00,0xff00, // u25d8\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xe700,0xdb00,0xdb00,0xe700,0xff00,0xff00,0xff00,0xff00,0xff00, // u25d9\n  0x0000,0x0000,0x7c00,0x8200,0xaa00,0x8200,0x8200,0xba00,0x9200,0x8200,0x8200,0x7c00,0x0000,0x0000, // u263a\n  0x0000,0x0000,0x7c00,0xfe00,0xd600,0xfe00,0xfe00,0xc600,0xee00,0xfe00,0xfe00,0x7c00,0x0000,0x0000, // u263b\n  0x0000,0x0000,0x0000,0x1000,0x9200,0x5400,0x3800,0xee00,0x3800,0x5400,0x9200,0x1000,0x0000,0x0000, // u263c\n  0x0000,0x0000,0x3800,0x4400,0x4400,0x4400,0x4400,0x3800,0x1000,0x7c00,0x1000,0x1000,0x0000,0x0000, // u2640\n  0x0000,0x0000,0x1e00,0x0600,0x0a00,0x1200,0x3800,0x4400,0x4400,0x4400,0x4400,0x3800,0x0000,0x0000, // u2642\n  0x0000,0x0000,0x1000,0x1000,0x3800,0x7c00,0xfe00,0xfe00,0x7c00,0x1000,0x1000,0x3800,0x0000,0x0000, // u2660\n  0x0000,0x0000,0x1000,0x3800,0x3800,0x1000,0x5400,0xfe00,0xfe00,0x5400,0x1000,0x3800,0x0000,0x0000, // u2663\n  0x0000,0x0000,0x0000,0x6c00,0xfe00,0xfe00,0xfe00,0xfe00,0x7c00,0x3800,0x1000,0x0000,0x0000,0x0000, // u2665\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x3800,0x7c00,0xfe00,0x7c00,0x3800,0x1000,0x0000,0x0000,0x0000, // u2666\n  0x0000,0x0000,0x3e00,0x2200,0x3e00,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0xc000,0x0000,0x0000, // u266a\n  0x0000,0x0000,0x7e00,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4400,0x8000,0x0000, // u266b\n  0x0000,0x0000,0x0200,0x0200,0x0400,0x0400,0x8800,0x8800,0x5000,0x5000,0x2000,0x2000,0x0000,0x0000, // u2713\n  0x0000,0x0000,0x0300,0x0300,0x0600,0x0600,0xcc00,0xcc00,0x7800,0x7800,0x3000,0x3000,0x0000,0x0000, // u2714\n  0x0000,0x0000,0x0400,0x4400,0x2800,0x1800,0x1800,0x1400,0x2200,0x2000,0x4000,0x4000,0x0000,0x0000, // u2717\n  0x0000,0x0000,0x0c00,0xcc00,0x7800,0x3800,0x3800,0x3c00,0x6600,0x6000,0xc000,0xc000,0x0000,0x0000, // u2718\n  0x0000,0x0000,0x0800,0x0800,0x1000,0x1000,0x2000,0x2000,0x1000,0x1000,0x0800,0x0800,0x0000,0x0000, // u27e8\n  0x0000,0x0000,0x2000,0x2000,0x1000,0x1000,0x0800,0x0800,0x1000,0x1000,0x2000,0x2000,0x0000,0x0000, // u27e9\n  0x0000,0x0000,0x1200,0x1200,0x2400,0x2400,0x4800,0x4800,0x2400,0x2400,0x1200,0x1200,0x0000,0x0000, // u27ea\n  0x0000,0x0000,0x4800,0x4800,0x2400,0x2400,0x1200,0x1200,0x2400,0x2400,0x4800,0x4800,0x0000,0x0000, // u27eb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2800\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2801\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2802\n  0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2803\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u2804\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u2805\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u2806\n  0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u2807\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2808\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2809\n  0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280a\n  0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280b\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u280c\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u280d\n  0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u280e\n  0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u280f\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2810\n  0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2811\n  0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2812\n  0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2813\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u2814\n  0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u2815\n  0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u2816\n  0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u2817\n  0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2818\n  0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2819\n  0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281a\n  0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281b\n  0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u281c\n  0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u281d\n  0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u281e\n  0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u281f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000, // u2820\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000, // u2821\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000, // u2822\n  0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000, // u2823\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000, // u2824\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000, // u2825\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000, // u2826\n  0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000, // u2827\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000, // u2828\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000, // u2829\n  0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000, // u282a\n  0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000, // u282b\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000, // u282c\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000, // u282d\n  0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000, // u282e\n  0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000, // u282f\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000, // u2830\n  0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000, // u2831\n  0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000, // u2832\n  0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000, // u2833\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000, // u2834\n  0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000, // u2835\n  0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000, // u2836\n  0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000, // u2837\n  0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000, // u2838\n  0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000, // u2839\n  0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000, // u283a\n  0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000, // u283b\n  0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000, // u283c\n  0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000, // u283d\n  0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000, // u283e\n  0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000, // u283f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2840\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2841\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2842\n  0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2843\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u2844\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u2845\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u2846\n  0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u2847\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2848\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2849\n  0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u284a\n  0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u284b\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u284c\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u284d\n  0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u284e\n  0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u284f\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2850\n  0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2851\n  0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2852\n  0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2853\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u2854\n  0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u2855\n  0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u2856\n  0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u2857\n  0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2858\n  0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2859\n  0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u285a\n  0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u285b\n  0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u285c\n  0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u285d\n  0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u285e\n  0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000, // u285f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000, // u2860\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000, // u2861\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000, // u2862\n  0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000, // u2863\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000, // u2864\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000, // u2865\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000, // u2866\n  0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000, // u2867\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000, // u2868\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000, // u2869\n  0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000, // u286a\n  0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000, // u286b\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000, // u286c\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000, // u286d\n  0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000, // u286e\n  0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000, // u286f\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000, // u2870\n  0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000, // u2871\n  0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000, // u2872\n  0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000, // u2873\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000, // u2874\n  0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000, // u2875\n  0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000, // u2876\n  0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000, // u2877\n  0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000, // u2878\n  0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000, // u2879\n  0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000, // u287a\n  0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000, // u287b\n  0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000, // u287c\n  0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000, // u287d\n  0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000, // u287e\n  0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000, // u287f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2880\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2881\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2882\n  0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2883\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000, // u2884\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000, // u2885\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000, // u2886\n  0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000, // u2887\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2888\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2889\n  0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u288a\n  0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u288b\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000, // u288c\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000, // u288d\n  0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000, // u288e\n  0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000, // u288f\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2890\n  0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2891\n  0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2892\n  0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2893\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000, // u2894\n  0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000, // u2895\n  0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000, // u2896\n  0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000, // u2897\n  0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2898\n  0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2899\n  0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u289a\n  0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u289b\n  0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000, // u289c\n  0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000, // u289d\n  0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000, // u289e\n  0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000, // u289f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000, // u28a0\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000, // u28a1\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000, // u28a2\n  0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000, // u28a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000, // u28a4\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000, // u28a5\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000, // u28a6\n  0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000, // u28a7\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000, // u28a8\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000, // u28a9\n  0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000, // u28aa\n  0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000, // u28ab\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000, // u28ac\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000, // u28ad\n  0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000, // u28ae\n  0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000, // u28af\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000, // u28b0\n  0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000, // u28b1\n  0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000, // u28b2\n  0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000, // u28b3\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000, // u28b4\n  0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000, // u28b5\n  0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000, // u28b6\n  0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000, // u28b7\n  0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000, // u28b8\n  0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000, // u28b9\n  0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000, // u28ba\n  0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000, // u28bb\n  0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000, // u28bc\n  0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000, // u28bd\n  0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000, // u28be\n  0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000, // u28bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28c0\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28c1\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28c2\n  0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000, // u28c4\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000, // u28c5\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000, // u28c6\n  0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000, // u28c7\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28c8\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28c9\n  0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28ca\n  0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28cb\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000, // u28cc\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000, // u28cd\n  0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000, // u28ce\n  0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000, // u28cf\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28d0\n  0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28d1\n  0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28d2\n  0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28d3\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000, // u28d4\n  0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000, // u28d5\n  0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000, // u28d6\n  0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000, // u28d7\n  0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28d8\n  0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28d9\n  0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28da\n  0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28db\n  0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000, // u28dc\n  0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000, // u28dd\n  0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000, // u28de\n  0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000, // u28df\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000, // u28e0\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000, // u28e1\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000, // u28e2\n  0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000, // u28e3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000, // u28e4\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000, // u28e5\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000, // u28e6\n  0x0000,0x4000,0x4000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000, // u28e7\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000, // u28e8\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000, // u28e9\n  0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000, // u28ea\n  0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000, // u28eb\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000, // u28ec\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000, // u28ed\n  0x0000,0x0400,0x0400,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000, // u28ee\n  0x0000,0x4400,0x4400,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000, // u28ef\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000, // u28f0\n  0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000, // u28f1\n  0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000, // u28f2\n  0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000, // u28f3\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000, // u28f4\n  0x0000,0x4000,0x4000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000, // u28f5\n  0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000, // u28f6\n  0x0000,0x4000,0x4000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000, // u28f7\n  0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000, // u28f8\n  0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000, // u28f9\n  0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000, // u28fa\n  0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000, // u28fb\n  0x0000,0x0400,0x0400,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000, // u28fc\n  0x0000,0x4400,0x4400,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000, // u28fd\n  0x0000,0x0400,0x0400,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000, // u28fe\n  0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x4400,0x4400,0x0000, // u28ff\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x0000,0x0000,0x0000,0x4200,0x4200,0x0000,0x0000, // u2e2c\n  0x8000,0x8800,0x9c00,0xaa00,0x8800,0x8800,0x8800,0x1000,0x2000,0x4000,0x8000,0x8000,0x8000,0x8000, // ue0a0\n  0x8000,0x8000,0x8000,0x8000,0x8000,0xf800,0x0000,0x1100,0x1900,0x1500,0x1300,0x1100,0x1100,0x0000, // ue0a1\n  0x3800,0x4400,0x4400,0x4400,0x4400,0xfe00,0xfe00,0xee00,0xc600,0xee00,0xfe00,0xfe00,0xfe00,0x0000, // ue0a2\n  0x8000,0xc000,0xe000,0xf000,0xf800,0xfc00,0xfe00,0xfe00,0xfc00,0xf800,0xf000,0xe000,0xc000,0x8000, // ue0b0\n  0x8000,0x4000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000, // ue0b1\n  0x0100,0x0300,0x0700,0x0f00,0x1f00,0x3f00,0x7f00,0x7f00,0x3f00,0x1f00,0x0f00,0x0700,0x0300,0x0100, // ue0b2\n  0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100, // ue0b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x4400,0x4400,0x3800, // uf6be\n  0x0000,0x0000,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x7e00,0x0000,0x0000 // ufffd\n  };\n  // codepoints array\n  constexpr std::array<uint16_t, CHARCOUNT> fixedfont_codepoints = {\n  0x0000,0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,\n  0x002f,0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,\n  0x003f,0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,\n  0x004f,0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,\n  0x005f,0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,\n  0x006f,0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,\n  0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af,\n  0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf,\n  0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf,\n  0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df,\n  0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef,\n  0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff,\n  0x0100,0x0101,0x0102,0x0103,0x0104,0x0105,0x0106,0x0107,0x0108,0x0109,0x010a,0x010b,0x010c,0x010d,0x010e,0x010f,\n  0x0110,0x0111,0x0112,0x0113,0x0114,0x0115,0x0116,0x0117,0x0118,0x0119,0x011a,0x011b,0x011c,0x011d,0x011e,0x011f,\n  0x0120,0x0121,0x0122,0x0123,0x0124,0x0125,0x0126,0x0127,0x0128,0x0129,0x012a,0x012b,0x012c,0x012d,0x012e,0x012f,\n  0x0130,0x0131,0x0132,0x0133,0x0134,0x0135,0x0136,0x0137,0x0138,0x0139,0x013a,0x013b,0x013c,0x013d,0x013e,0x013f,\n  0x0140,0x0141,0x0142,0x0143,0x0144,0x0145,0x0146,0x0147,0x0148,0x0149,0x014a,0x014b,0x014c,0x014d,0x014e,0x014f,\n  0x0150,0x0151,0x0152,0x0153,0x0154,0x0155,0x0156,0x0157,0x0158,0x0159,0x015a,0x015b,0x015c,0x015d,0x015e,0x015f,\n  0x0160,0x0161,0x0162,0x0163,0x0164,0x0165,0x0166,0x0167,0x0168,0x0169,0x016a,0x016b,0x016c,0x016d,0x016e,0x016f,\n  0x0170,0x0171,0x0172,0x0173,0x0174,0x0175,0x0176,0x0177,0x0178,0x0179,0x017a,0x017b,0x017c,0x017d,0x017e,0x017f,\n  0x0186,0x018e,0x018f,0x0190,0x0192,0x019d,0x019e,0x01b5,0x01b6,0x01b7,0x01cd,0x01ce,0x01cf,0x01d0,0x01d1,0x01d2,\n  0x01d3,0x01d4,0x01e2,0x01e3,0x01e4,0x01e5,0x01e6,0x01e7,0x01e8,0x01e9,0x01ea,0x01eb,0x01ec,0x01ed,0x01ee,0x01ef,\n  0x01f0,0x01f4,0x01f5,0x01fc,0x01fd,0x01fe,0x01ff,0x0218,0x0219,0x021a,0x021b,0x0232,0x0233,0x0237,0x0254,0x0258,\n  0x0259,0x025b,0x0272,0x0292,0x02bb,0x02bc,0x02bd,0x02c6,0x02c7,0x02d8,0x02d9,0x02db,0x02dc,0x02dd,0x0300,0x0301,\n  0x0302,0x0303,0x0304,0x0305,0x0306,0x0307,0x0308,0x030a,0x030b,0x030c,0x0329,0x0384,0x0385,0x0386,0x0387,0x0388,\n  0x0389,0x038a,0x038c,0x038e,0x038f,0x0390,0x0391,0x0392,0x0393,0x0394,0x0395,0x0396,0x0397,0x0398,0x0399,0x039a,\n  0x039b,0x039c,0x039d,0x039e,0x039f,0x03a0,0x03a1,0x03a3,0x03a4,0x03a5,0x03a6,0x03a7,0x03a8,0x03a9,0x03aa,0x03ab,\n  0x03ac,0x03ad,0x03ae,0x03af,0x03b0,0x03b1,0x03b2,0x03b3,0x03b4,0x03b5,0x03b6,0x03b7,0x03b8,0x03b9,0x03ba,0x03bb,\n  0x03bc,0x03bd,0x03be,0x03bf,0x03c0,0x03c1,0x03c2,0x03c3,0x03c4,0x03c5,0x03c6,0x03c7,0x03c8,0x03c9,0x03ca,0x03cb,\n  0x03cc,0x03cd,0x03ce,0x03d1,0x03d5,0x03f0,0x03f1,0x03f2,0x03f3,0x03f4,0x03f5,0x03f6,0x0400,0x0401,0x0402,0x0403,\n  0x0404,0x0405,0x0406,0x0407,0x0408,0x0409,0x040a,0x040b,0x040c,0x040d,0x040e,0x040f,0x0410,0x0411,0x0412,0x0413,\n  0x0414,0x0415,0x0416,0x0417,0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e,0x041f,0x0420,0x0421,0x0422,0x0423,\n  0x0424,0x0425,0x0426,0x0427,0x0428,0x0429,0x042a,0x042b,0x042c,0x042d,0x042e,0x042f,0x0430,0x0431,0x0432,0x0433,\n  0x0434,0x0435,0x0436,0x0437,0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e,0x043f,0x0440,0x0441,0x0442,0x0443,\n  0x0444,0x0445,0x0446,0x0447,0x0448,0x0449,0x044a,0x044b,0x044c,0x044d,0x044e,0x044f,0x0450,0x0451,0x0452,0x0453,\n  0x0454,0x0455,0x0456,0x0457,0x0458,0x0459,0x045a,0x045b,0x045c,0x045d,0x045e,0x045f,0x0462,0x0463,0x046a,0x046b,\n  0x0490,0x0491,0x0492,0x0493,0x0494,0x0495,0x0496,0x0497,0x0498,0x0499,0x049a,0x049b,0x049c,0x049d,0x04a0,0x04a1,\n  0x04a2,0x04a3,0x04a4,0x04a5,0x04aa,0x04ab,0x04ae,0x04af,0x04b0,0x04b1,0x04b2,0x04b3,0x04b6,0x04b7,0x04b8,0x04b9,\n  0x04ba,0x04bb,0x04c0,0x04c1,0x04c2,0x04cf,0x04d0,0x04d1,0x04d2,0x04d3,0x04d4,0x04d5,0x04d6,0x04d7,0x04d8,0x04d9,\n  0x04da,0x04db,0x04dc,0x04dd,0x04de,0x04df,0x04e2,0x04e3,0x04e4,0x04e5,0x04e6,0x04e7,0x04e8,0x04e9,0x04ea,0x04eb,\n  0x04ec,0x04ed,0x04ee,0x04ef,0x04f0,0x04f1,0x04f2,0x04f3,0x04f4,0x04f5,0x04f8,0x04f9,0x05d0,0x05d1,0x05d2,0x05d3,\n  0x05d4,0x05d5,0x05d6,0x05d7,0x05d8,0x05d9,0x05da,0x05db,0x05dc,0x05dd,0x05de,0x05df,0x05e0,0x05e1,0x05e2,0x05e3,\n  0x05e4,0x05e5,0x05e6,0x05e7,0x05e8,0x05e9,0x05ea,0x1e0c,0x1e0d,0x1e34,0x1e35,0x1e36,0x1e37,0x1e40,0x1e41,0x1e42,\n  0x1e43,0x1e44,0x1e45,0x1e46,0x1e47,0x1e6c,0x1e6d,0x1eb8,0x1eb9,0x1ebc,0x1ebd,0x1eca,0x1ecb,0x1ecc,0x1ecd,0x1ee4,\n  0x1ee5,0x1ef8,0x1ef9,0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007,0x2008,0x2009,0x200a,0x200b,0x200c,\n  0x200d,0x200e,0x200f,0x2010,0x2011,0x2012,0x2013,0x2014,0x2015,0x2016,0x2017,0x2018,0x2019,0x201a,0x201b,0x201c,\n  0x201d,0x201e,0x201f,0x2020,0x2021,0x2022,0x2026,0x2030,0x2032,0x2033,0x2039,0x203a,0x203c,0x203e,0x2070,0x2071,\n  0x2074,0x2075,0x2076,0x2077,0x2078,0x2079,0x207a,0x207b,0x207c,0x207d,0x207e,0x207f,0x2080,0x2081,0x2082,0x2083,\n  0x2084,0x2085,0x2086,0x2087,0x2088,0x2089,0x208a,0x208b,0x208c,0x208d,0x208e,0x2090,0x2091,0x2092,0x2093,0x2094,\n  0x2095,0x2096,0x2097,0x2098,0x209a,0x20a7,0x20aa,0x20ac,0x20ae,0x2102,0x210e,0x210f,0x2115,0x2116,0x211a,0x211d,\n  0x2122,0x2124,0x2126,0x2135,0x2190,0x2191,0x2192,0x2193,0x2194,0x2195,0x21a4,0x21a6,0x21a8,0x21b5,0x21bb,0x21cb,\n  0x21cc,0x21d0,0x21d1,0x21d2,0x21d3,0x21d4,0x21d5,0x2200,0x2203,0x2204,0x2205,0x2206,0x2207,0x2208,0x2209,0x220a,\n  0x220b,0x220c,0x220d,0x2212,0x2213,0x2214,0x2215,0x2216,0x2219,0x221a,0x221e,0x221f,0x2225,0x2227,0x2228,0x2229,\n  0x222a,0x2248,0x2260,0x2261,0x2264,0x2265,0x226a,0x226b,0x2282,0x2283,0x2286,0x2287,0x22a5,0x22c2,0x22c3,0x2300,\n  0x2302,0x2308,0x2309,0x230a,0x230b,0x2310,0x2319,0x2320,0x2321,0x239b,0x239c,0x239d,0x239e,0x239f,0x23a0,0x23a1,\n  0x23a2,0x23a3,0x23a4,0x23a5,0x23a6,0x23a7,0x23a8,0x23a9,0x23ab,0x23ac,0x23ad,0x23ae,0x23af,0x23ba,0x23bb,0x23bc,\n  0x23bd,0x23d0,0x2409,0x240a,0x240b,0x240c,0x240d,0x2424,0x2500,0x2501,0x2502,0x2503,0x2508,0x2509,0x250a,0x250b,\n  0x250c,0x250d,0x250e,0x250f,0x2510,0x2511,0x2512,0x2513,0x2514,0x2515,0x2516,0x2517,0x2518,0x2519,0x251a,0x251b,\n  0x251c,0x251d,0x251e,0x251f,0x2520,0x2521,0x2522,0x2523,0x2524,0x2525,0x2526,0x2527,0x2528,0x2529,0x252a,0x252b,\n  0x252c,0x252d,0x252e,0x252f,0x2530,0x2531,0x2532,0x2533,0x2534,0x2535,0x2536,0x2537,0x2538,0x2539,0x253a,0x253b,\n  0x253c,0x253d,0x253e,0x253f,0x2540,0x2541,0x2542,0x2543,0x2544,0x2545,0x2546,0x2547,0x2548,0x2549,0x254a,0x254b,\n  0x2550,0x2551,0x2552,0x2553,0x2554,0x2555,0x2556,0x2557,0x2558,0x2559,0x255a,0x255b,0x255c,0x255d,0x255e,0x255f,\n  0x2560,0x2561,0x2562,0x2563,0x2564,0x2565,0x2566,0x2567,0x2568,0x2569,0x256a,0x256b,0x256c,0x256d,0x256e,0x256f,\n  0x2570,0x2571,0x2572,0x2573,0x2574,0x2575,0x2576,0x2577,0x2578,0x2579,0x257a,0x257b,0x257c,0x257d,0x257e,0x257f,\n  0x2580,0x2581,0x2582,0x2583,0x2584,0x2585,0x2586,0x2587,0x2588,0x2589,0x258a,0x258b,0x258c,0x258d,0x258e,0x258f,\n  0x2590,0x2591,0x2592,0x2593,0x2596,0x2597,0x2598,0x2599,0x259a,0x259b,0x259c,0x259d,0x259e,0x259f,0x25a0,0x25ac,\n  0x25ae,0x25b2,0x25b6,0x25ba,0x25bc,0x25c0,0x25c4,0x25c6,0x25ca,0x25cb,0x25cf,0x25d8,0x25d9,0x263a,0x263b,0x263c,\n  0x2640,0x2642,0x2660,0x2663,0x2665,0x2666,0x266a,0x266b,0x2713,0x2714,0x2717,0x2718,0x27e8,0x27e9,0x27ea,0x27eb,\n  0x2800,0x2801,0x2802,0x2803,0x2804,0x2805,0x2806,0x2807,0x2808,0x2809,0x280a,0x280b,0x280c,0x280d,0x280e,0x280f,\n  0x2810,0x2811,0x2812,0x2813,0x2814,0x2815,0x2816,0x2817,0x2818,0x2819,0x281a,0x281b,0x281c,0x281d,0x281e,0x281f,\n  0x2820,0x2821,0x2822,0x2823,0x2824,0x2825,0x2826,0x2827,0x2828,0x2829,0x282a,0x282b,0x282c,0x282d,0x282e,0x282f,\n  0x2830,0x2831,0x2832,0x2833,0x2834,0x2835,0x2836,0x2837,0x2838,0x2839,0x283a,0x283b,0x283c,0x283d,0x283e,0x283f,\n  0x2840,0x2841,0x2842,0x2843,0x2844,0x2845,0x2846,0x2847,0x2848,0x2849,0x284a,0x284b,0x284c,0x284d,0x284e,0x284f,\n  0x2850,0x2851,0x2852,0x2853,0x2854,0x2855,0x2856,0x2857,0x2858,0x2859,0x285a,0x285b,0x285c,0x285d,0x285e,0x285f,\n  0x2860,0x2861,0x2862,0x2863,0x2864,0x2865,0x2866,0x2867,0x2868,0x2869,0x286a,0x286b,0x286c,0x286d,0x286e,0x286f,\n  0x2870,0x2871,0x2872,0x2873,0x2874,0x2875,0x2876,0x2877,0x2878,0x2879,0x287a,0x287b,0x287c,0x287d,0x287e,0x287f,\n  0x2880,0x2881,0x2882,0x2883,0x2884,0x2885,0x2886,0x2887,0x2888,0x2889,0x288a,0x288b,0x288c,0x288d,0x288e,0x288f,\n  0x2890,0x2891,0x2892,0x2893,0x2894,0x2895,0x2896,0x2897,0x2898,0x2899,0x289a,0x289b,0x289c,0x289d,0x289e,0x289f,\n  0x28a0,0x28a1,0x28a2,0x28a3,0x28a4,0x28a5,0x28a6,0x28a7,0x28a8,0x28a9,0x28aa,0x28ab,0x28ac,0x28ad,0x28ae,0x28af,\n  0x28b0,0x28b1,0x28b2,0x28b3,0x28b4,0x28b5,0x28b6,0x28b7,0x28b8,0x28b9,0x28ba,0x28bb,0x28bc,0x28bd,0x28be,0x28bf,\n  0x28c0,0x28c1,0x28c2,0x28c3,0x28c4,0x28c5,0x28c6,0x28c7,0x28c8,0x28c9,0x28ca,0x28cb,0x28cc,0x28cd,0x28ce,0x28cf,\n  0x28d0,0x28d1,0x28d2,0x28d3,0x28d4,0x28d5,0x28d6,0x28d7,0x28d8,0x28d9,0x28da,0x28db,0x28dc,0x28dd,0x28de,0x28df,\n  0x28e0,0x28e1,0x28e2,0x28e3,0x28e4,0x28e5,0x28e6,0x28e7,0x28e8,0x28e9,0x28ea,0x28eb,0x28ec,0x28ed,0x28ee,0x28ef,\n  0x28f0,0x28f1,0x28f2,0x28f3,0x28f4,0x28f5,0x28f6,0x28f7,0x28f8,0x28f9,0x28fa,0x28fb,0x28fc,0x28fd,0x28fe,0x28ff,\n  0x2e2c,0xe0a0,0xe0a1,0xe0a2,0xe0b0,0xe0b1,0xe0b2,0xe0b3,0xf6be,0xfffd };\n} // namespace\n// -- end of autogenerated text ---\n\nnamespace fixed_font_14b {\n  // -- start of autogenerated text ---\n  // definition section for font: ter-u14b.bdf\n  constexpr int CHARCOUNT = 1354;\n  constexpr int WIDTH = 8;\n  constexpr int HEIGHT = 14;\n  constexpr int OFFSET_X = 0;\n  constexpr int OFFSET_Y = 0;\n  constexpr FixedFont_info_t fixedfont_info = {\n    \"Terminus\", // font name\n    \"ter-u14b.bdf\", // font name internal\n    CHARCOUNT, // num of chars\n    WIDTH, HEIGHT, OFFSET_X, OFFSET_Y,\n    true // bold\n  };\n  // font bitmap definitions\n  constexpr std::array<uint16_t, CHARCOUNT * HEIGHT> fixedfont_bitmap = {\n  0x0000,0x0000,0xee00,0xc600,0x0000,0xc600,0xc600,0xc600,0x0000,0xc600,0xc600,0xee00,0x0000,0x0000, // u0000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0020\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x1800,0x1800,0x0000,0x0000, // u0021\n  0x0000,0x6600,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0022\n  0x0000,0x0000,0x6c00,0x6c00,0x6c00,0xfe00,0x6c00,0x6c00,0xfe00,0x6c00,0x6c00,0x6c00,0x0000,0x0000, // u0023\n  0x0000,0x1000,0x1000,0x7c00,0xd600,0xd000,0xd000,0x7c00,0x1600,0x1600,0xd600,0x7c00,0x1000,0x1000, // u0024\n  0x0000,0x0000,0x6600,0xd600,0x6c00,0x0c00,0x1800,0x1800,0x3000,0x3600,0x6b00,0x6600,0x0000,0x0000, // u0025\n  0x0000,0x0000,0x3800,0x6c00,0x6c00,0x3800,0x7600,0xdc00,0xcc00,0xcc00,0xdc00,0x7600,0x0000,0x0000, // u0026\n  0x0000,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0027\n  0x0000,0x0000,0x0c00,0x1800,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x1800,0x0c00,0x0000,0x0000, // u0028\n  0x0000,0x0000,0x3000,0x1800,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1800,0x3000,0x0000,0x0000, // u0029\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6c00,0x3800,0xfe00,0x3800,0x6c00,0x0000,0x0000,0x0000,0x0000, // u002a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x7e00,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u002b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x3000,0x0000, // u002c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x0000,0x0000, // u002e\n  0x0000,0x0000,0x0600,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x6000,0x6000,0x0000,0x0000, // u002f\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xce00,0xde00,0xf600,0xe600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u0030\n  0x0000,0x0000,0x1800,0x3800,0x7800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x7e00,0x0000,0x0000, // u0031\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0xfe00,0x0000,0x0000, // u0032\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0x0600,0x3c00,0x0600,0x0600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u0033\n  0x0000,0x0000,0x0600,0x0e00,0x1e00,0x3600,0x6600,0xc600,0xfe00,0x0600,0x0600,0x0600,0x0000,0x0000, // u0034\n  0x0000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xfc00,0x0600,0x0600,0x0600,0xc600,0x7c00,0x0000,0x0000, // u0035\n  0x0000,0x0000,0x3c00,0x6000,0xc000,0xc000,0xfc00,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u0036\n  0x0000,0x0000,0xfe00,0x0600,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x3000,0x0000,0x0000, // u0037\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0x7c00,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u0038\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x0c00,0x7800,0x0000,0x0000, // u0039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x0000,0x0000,0x0000,0x1800,0x1800,0x0000,0x0000, // u003a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x0000,0x0000,0x0000,0x1800,0x1800,0x3000,0x0000, // u003b\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x1800,0x3000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0000,0x0000, // u003c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0000,0x0000,0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000, // u003d\n  0x0000,0x0000,0x0000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0c00,0x1800,0x3000,0x6000,0x0000,0x0000, // u003e\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0x0c00,0x1800,0x1800,0x0000,0x1800,0x1800,0x0000,0x0000, // u003f\n  0x0000,0x0000,0x7c00,0xc600,0xce00,0xd600,0xd600,0xd600,0xd600,0xce00,0xc000,0x7e00,0x0000,0x0000, // u0040\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u0041\n  0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xfc00,0xc600,0xc600,0xc600,0xc600,0xfc00,0x0000,0x0000, // u0042\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc000,0xc000,0xc000,0xc000,0xc600,0xc600,0x7c00,0x0000,0x0000, // u0043\n  0x0000,0x0000,0xf800,0xcc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xcc00,0xf800,0x0000,0x0000, // u0044\n  0x0000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000, // u0045\n  0x0000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000, // u0046\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc000,0xc000,0xde00,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u0047\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u0048\n  0x0000,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u0049\n  0x0000,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xcc00,0xcc00,0x7800,0x0000,0x0000, // u004a\n  0x0000,0x0000,0xc600,0xc600,0xcc00,0xd800,0xf000,0xf000,0xd800,0xcc00,0xc600,0xc600,0x0000,0x0000, // u004b\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000, // u004c\n  0x0000,0x0000,0x8200,0xc600,0xee00,0xfe00,0xd600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u004d\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xe600,0xf600,0xde00,0xce00,0xc600,0xc600,0xc600,0x0000,0x0000, // u004e\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u004f\n  0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xfc00,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000, // u0050\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xde00,0x7c00,0x0600,0x0000, // u0051\n  0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xfc00,0xf000,0xd800,0xcc00,0xc600,0x0000,0x0000, // u0052\n  0x0000,0x0000,0x7c00,0xc600,0xc000,0xc000,0x7c00,0x0600,0x0600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u0053\n  0x0000,0x0000,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u0054\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u0055\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0x6c00,0x6c00,0x6c00,0x3800,0x3800,0x0000,0x0000, // u0056\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xd600,0xfe00,0xee00,0xc600,0x8200,0x0000,0x0000, // u0057\n  0x0000,0x0000,0xc600,0xc600,0x6c00,0x6c00,0x3800,0x3800,0x6c00,0x6c00,0xc600,0xc600,0x0000,0x0000, // u0058\n  0x0000,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u0059\n  0x0000,0x0000,0xfe00,0x0600,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0xc000,0xfe00,0x0000,0x0000, // u005a\n  0x0000,0x0000,0x3c00,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3c00,0x0000,0x0000, // u005b\n  0x0000,0x0000,0x6000,0x6000,0x3000,0x3000,0x1800,0x1800,0x0c00,0x0c00,0x0600,0x0600,0x0000,0x0000, // u005c\n  0x0000,0x0000,0x3c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x3c00,0x0000,0x0000, // u005d\n  0x0000,0x1800,0x3c00,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0000, // u005f\n  0x3000,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0060\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u0061\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xfc00,0x0000,0x0000, // u0062\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc000,0xc000,0xc000,0xc600,0x7c00,0x0000,0x0000, // u0063\n  0x0000,0x0000,0x0600,0x0600,0x0600,0x7e00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u0064\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000, // u0065\n  0x0000,0x0000,0x1e00,0x3000,0x3000,0xfc00,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u0066\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x7c00, // u0067\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u0068\n  0x0000,0x0000,0x1800,0x1800,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u0069\n  0x0000,0x0000,0x0600,0x0600,0x0000,0x0e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x6600,0x6600,0x3c00, // u006a\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xc600,0xcc00,0xd800,0xf000,0xd800,0xcc00,0xc600,0x0000,0x0000, // u006b\n  0x0000,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u006c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0x0000,0x0000, // u006d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u006e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u006f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xfc00,0xc000,0xc000, // u0070\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600, // u0071\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xde00,0xf000,0xe000,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000, // u0072\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0xc000,0xc000,0x7c00,0x0600,0x0600,0xfc00,0x0000,0x0000, // u0073\n  0x0000,0x0000,0x3000,0x3000,0x3000,0xfc00,0x3000,0x3000,0x3000,0x3000,0x3000,0x1e00,0x0000,0x0000, // u0074\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u0075\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0x6c00,0x6c00,0x3800,0x3800,0x0000,0x0000, // u0076\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xd600,0xd600,0xd600,0xd600,0x7c00,0x0000,0x0000, // u0077\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0x6c00,0x3800,0x6c00,0xc600,0xc600,0x0000,0x0000, // u0078\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x7c00, // u0079\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0c00,0x1800,0x3000,0x6000,0xc000,0xfe00,0x0000,0x0000, // u007a\n  0x0000,0x0000,0x1c00,0x3000,0x3000,0x3000,0x6000,0x3000,0x3000,0x3000,0x3000,0x1c00,0x0000,0x0000, // u007b\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u007c\n  0x0000,0x0000,0x7000,0x1800,0x1800,0x1800,0x0c00,0x1800,0x1800,0x1800,0x1800,0x7000,0x0000,0x0000, // u007d\n  0x0000,0x7300,0xdb00,0xce00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a0\n  0x0000,0x0000,0x1800,0x1800,0x0000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u00a1\n  0x0000,0x0000,0x0000,0x1000,0x1000,0x7c00,0xd600,0xd000,0xd000,0xd000,0xd600,0x7c00,0x1000,0x1000, // u00a2\n  0x0000,0x0000,0x3800,0x6c00,0x6000,0x6000,0xf800,0x6000,0x6000,0x6000,0x6600,0xfe00,0x0000,0x0000, // u00a3\n  0x0000,0x0000,0x0000,0x0000,0x6600,0x3c00,0x6600,0x6600,0x6600,0x3c00,0x6600,0x0000,0x0000,0x0000, // u00a4\n  0x0000,0x0000,0xc300,0xc300,0x6600,0x3c00,0x1800,0x7e00,0x1800,0x7e00,0x1800,0x1800,0x0000,0x0000, // u00a5\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u00a6\n  0x0000,0x3c00,0x6600,0x6000,0x3800,0x6c00,0x6600,0x6600,0x3600,0x1c00,0x0600,0x6600,0x3c00,0x0000, // u00a7\n  0x6c00,0x6c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a8\n  0x0000,0x0000,0x0000,0x7e00,0x8100,0x9900,0xa500,0xa100,0xa500,0x9900,0x8100,0x7e00,0x0000,0x0000, // u00a9\n  0x0000,0x3c00,0x0600,0x3e00,0x6600,0x3e00,0x0000,0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1b00,0x3600,0x6c00,0xd800,0x6c00,0x3600,0x1b00,0x0000,0x0000, // u00ab\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ac\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ad\n  0x0000,0x0000,0x0000,0x7e00,0x8100,0xb900,0xa500,0xb900,0xa900,0xa500,0x8100,0x7e00,0x0000,0x0000, // u00ae\n  0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00af\n  0x0000,0x3800,0x6c00,0x6c00,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x7e00,0x1800,0x1800,0x0000,0x7e00,0x0000,0x0000, // u00b1\n  0x0000,0x3800,0x6c00,0x0c00,0x1800,0x3000,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b2\n  0x0000,0x7800,0x0c00,0x3800,0x0c00,0x0c00,0x7800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b3\n  0x1800,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xce00,0xf600,0xc000,0xc000, // u00b5\n  0x0000,0x0000,0x7e00,0xd600,0xd600,0xd600,0xd600,0x7600,0x1600,0x1600,0x1600,0x1600,0x0000,0x0000, // u00b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x6000, // u00b8\n  0x0000,0x1800,0x3800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b9\n  0x0000,0x3c00,0x6600,0x6600,0x6600,0x3c00,0x0000,0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xd800,0x6c00,0x3600,0x1b00,0x3600,0x6c00,0xd800,0x0000,0x0000, // u00bb\n  0x6000,0xe000,0x6200,0x6600,0x6c00,0x1800,0x3000,0x6600,0xce00,0x9a00,0x3e00,0x0600,0x0600,0x0000, // u00bc\n  0x6000,0xe000,0x6200,0x6600,0x6c00,0x1800,0x3000,0x6000,0xdc00,0xb600,0x0c00,0x1800,0x3e00,0x0000, // u00bd\n  0xe000,0x3000,0x6200,0x3600,0xec00,0x1800,0x3000,0x6600,0xce00,0x9a00,0x3e00,0x0600,0x0600,0x0000, // u00be\n  0x0000,0x0000,0x3000,0x3000,0x0000,0x3000,0x3000,0x6000,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u00bf\n  0x3000,0x1800,0x0000,0x7c00,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u00c0\n  0x1800,0x3000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u00c1\n  0x3800,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u00c2\n  0x7600,0xdc00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u00c3\n  0x6c00,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u00c4\n  0x3800,0x6c00,0x3800,0x7c00,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u00c5\n  0x0000,0x0000,0x7e00,0xd800,0xd800,0xd800,0xfe00,0xd800,0xd800,0xd800,0xd800,0xde00,0x0000,0x0000, // u00c6\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc000,0xc000,0xc000,0xc000,0xc600,0xc600,0x7c00,0x3000,0x6000, // u00c7\n  0x3000,0x1800,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000, // u00c8\n  0x1800,0x3000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000, // u00c9\n  0x3800,0x6c00,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000, // u00ca\n  0x6c00,0x6c00,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000, // u00cb\n  0x3000,0x1800,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u00cc\n  0x0c00,0x1800,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u00cd\n  0x3800,0x6c00,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u00ce\n  0x6600,0x6600,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u00cf\n  0x0000,0x0000,0x7800,0x6c00,0x6600,0x6600,0xf600,0x6600,0x6600,0x6600,0x6c00,0x7800,0x0000,0x0000, // u00d0\n  0x7600,0xdc00,0x0000,0xc600,0xc600,0xe600,0xf600,0xde00,0xce00,0xc600,0xc600,0xc600,0x0000,0x0000, // u00d1\n  0x3000,0x1800,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u00d2\n  0x1800,0x3000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u00d3\n  0x3800,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u00d4\n  0x7600,0xdc00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u00d5\n  0x6c00,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u00d6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0x6c00,0x3800,0x3800,0x6c00,0xc600,0x0000,0x0000,0x0000, // u00d7\n  0x0000,0x0000,0x7c00,0xc700,0xc600,0xce00,0xde00,0xf600,0xe600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u00d8\n  0x3000,0x1800,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u00d9\n  0x1800,0x3000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u00da\n  0x3800,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u00db\n  0x6c00,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u00dc\n  0x0c00,0x1800,0xc300,0xc300,0x6600,0x6600,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u00dd\n  0x0000,0x0000,0xc000,0xc000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xfc00,0xc000,0xc000,0x0000,0x0000, // u00de\n  0x0000,0x0000,0x7800,0xcc00,0xcc00,0xc800,0xfc00,0xc600,0xc600,0xc600,0xe600,0xdc00,0x0000,0x0000, // u00df\n  0x0000,0x0000,0x3000,0x1800,0x0000,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u00e0\n  0x0000,0x0000,0x1800,0x3000,0x0000,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u00e1\n  0x0000,0x0000,0x3800,0x6c00,0x0000,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u00e2\n  0x0000,0x0000,0x7600,0xdc00,0x0000,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u00e3\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u00e4\n  0x0000,0x0000,0x3800,0x6c00,0x3800,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u00e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6c00,0x1600,0x1600,0x7e00,0xd000,0xd000,0x6c00,0x0000,0x0000, // u00e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc000,0xc000,0xc000,0xc600,0x7c00,0x3000,0x6000, // u00e7\n  0x0000,0x0000,0x3000,0x1800,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000, // u00e8\n  0x0000,0x0000,0x1800,0x3000,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000, // u00e9\n  0x0000,0x0000,0x3800,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000, // u00ea\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000, // u00eb\n  0x0000,0x0000,0x3000,0x1800,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u00ec\n  0x0000,0x0000,0x0c00,0x1800,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u00ed\n  0x0000,0x0000,0x3800,0x6c00,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u00ee\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u00ef\n  0x0000,0x0000,0x6800,0x3000,0x5800,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u00f0\n  0x0000,0x0000,0x7600,0xdc00,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u00f1\n  0x0000,0x0000,0x3000,0x1800,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u00f2\n  0x0000,0x0000,0x1800,0x3000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u00f3\n  0x0000,0x0000,0x3800,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u00f4\n  0x0000,0x0000,0x7600,0xdc00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u00f5\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u00f6\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x0000,0x7e00,0x0000,0x1800,0x1800,0x0000,0x0000,0x0000, // u00f7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3d00,0x6700,0x6e00,0x7e00,0x7600,0xe600,0xbc00,0x0000,0x0000, // u00f8\n  0x0000,0x0000,0x3000,0x1800,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u00f9\n  0x0000,0x0000,0x1800,0x3000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u00fa\n  0x0000,0x0000,0x3800,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u00fb\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u00fc\n  0x0000,0x0000,0x1800,0x3000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x7c00, // u00fd\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xfc00,0xc000,0xc000, // u00fe\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x7c00, // u00ff\n  0x7c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u0100\n  0x0000,0x0000,0x0000,0x7c00,0x0000,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u0101\n  0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u0102\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u0103\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0c00,0x0700, // u0104\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0c00,0x0700, // u0105\n  0x1800,0x3000,0x0000,0x7c00,0xc600,0xc600,0xc000,0xc000,0xc000,0xc600,0xc600,0x7c00,0x0000,0x0000, // u0106\n  0x0000,0x0000,0x1800,0x3000,0x0000,0x7c00,0xc600,0xc000,0xc000,0xc000,0xc600,0x7c00,0x0000,0x0000, // u0107\n  0x3800,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xc000,0xc000,0xc000,0xc600,0xc600,0x7c00,0x0000,0x0000, // u0108\n  0x0000,0x0000,0x3800,0x6c00,0x0000,0x7c00,0xc600,0xc000,0xc000,0xc000,0xc600,0x7c00,0x0000,0x0000, // u0109\n  0x1800,0x1800,0x0000,0x7c00,0xc600,0xc600,0xc000,0xc000,0xc000,0xc600,0xc600,0x7c00,0x0000,0x0000, // u010a\n  0x0000,0x0000,0x1800,0x1800,0x0000,0x7c00,0xc600,0xc000,0xc000,0xc000,0xc600,0x7c00,0x0000,0x0000, // u010b\n  0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc600,0xc000,0xc000,0xc000,0xc600,0xc600,0x7c00,0x0000,0x0000, // u010c\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc000,0xc000,0xc000,0xc600,0x7c00,0x0000,0x0000, // u010d\n  0x6c00,0x3800,0x0000,0xf800,0xcc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xcc00,0xf800,0x0000,0x0000, // u010e\n  0x6c00,0x3800,0x0600,0x0600,0x0600,0x7e00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u010f\n  0x0000,0x0000,0x7800,0x6c00,0x6600,0x6600,0xf600,0x6600,0x6600,0x6600,0x6c00,0x7800,0x0000,0x0000, // u0110\n  0x0000,0x0000,0x0600,0x1f00,0x0600,0x7e00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u0111\n  0x7c00,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000, // u0112\n  0x0000,0x0000,0x0000,0x7c00,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000, // u0113\n  0x6c00,0x3800,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000, // u0114\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000, // u0115\n  0x1800,0x1800,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000, // u0116\n  0x0000,0x0000,0x1800,0x1800,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000, // u0117\n  0x0000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xc000,0xfe00,0x0c00,0x0700, // u0118\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x1800,0x0e00, // u0119\n  0x6c00,0x3800,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000, // u011a\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000, // u011b\n  0x3800,0x6c00,0x0000,0x7c00,0xc600,0xc000,0xc000,0xde00,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u011c\n  0x0000,0x0000,0x3800,0x6c00,0x0000,0x7e00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x7c00, // u011d\n  0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc000,0xc000,0xde00,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u011e\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x7e00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x7c00, // u011f\n  0x1800,0x1800,0x0000,0x7c00,0xc600,0xc000,0xc000,0xde00,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u0120\n  0x0000,0x0000,0x1800,0x1800,0x0000,0x7e00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x7c00, // u0121\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc000,0xc000,0xde00,0xc600,0xc600,0xc600,0x7c00,0x3000,0x6000, // u0122\n  0x0000,0x0c00,0x1800,0x1800,0x0000,0x7e00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x7c00, // u0123\n  0x3800,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u0124\n  0x1c00,0x3600,0xc000,0xc000,0xc000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u0125\n  0x0000,0x0000,0x6600,0xff00,0x6600,0x6600,0x7e00,0x6600,0x6600,0x6600,0x6600,0x6600,0x0000,0x0000, // u0126\n  0x0000,0x0000,0x6000,0xf800,0x6000,0x7c00,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x0000,0x0000, // u0127\n  0x7600,0xdc00,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u0128\n  0x0000,0x0000,0x7600,0xdc00,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u0129\n  0x7e00,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u012a\n  0x0000,0x0000,0x0000,0x7c00,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u012b\n  0x6c00,0x3800,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u012c\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u012d\n  0x0000,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x1800,0x0e00, // u012e\n  0x0000,0x0000,0x1800,0x1800,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x1800,0x0e00, // u012f\n  0x1800,0x1800,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u0130\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u0131\n  0x0000,0x0000,0xcf00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xf600,0xf600,0xdc00,0x0000,0x0000, // u0132\n  0x0000,0x0000,0xc600,0xc600,0x0000,0xce00,0xc600,0xc600,0xc600,0xc600,0xc600,0xf600,0x3600,0x1c00, // u0133\n  0x1c00,0x3600,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xcc00,0xcc00,0x7800,0x0000,0x0000, // u0134\n  0x0000,0x0000,0x0e00,0x1b00,0x0000,0x0e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x6600,0x6600,0x3c00, // u0135\n  0x0000,0x0000,0xc600,0xc600,0xcc00,0xd800,0xf000,0xf000,0xd800,0xcc00,0xc600,0xf600,0x3000,0x6000, // u0136\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xc600,0xcc00,0xd800,0xf000,0xd800,0xcc00,0xf600,0x3000,0x6000, // u0137\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xcc00,0xd800,0xf000,0xd800,0xcc00,0xc600,0x0000,0x0000, // u0138\n  0x6000,0xc000,0x0000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000, // u0139\n  0x0c00,0x1800,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u013a\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xfe00,0x3000,0x6000, // u013b\n  0x0000,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x1800,0x3000, // u013c\n  0x6c00,0x3800,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000, // u013d\n  0x6c00,0x3800,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u013e\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xc000,0xcc00,0xcc00,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000, // u013f\n  0x0000,0x0000,0x3800,0x1800,0x1800,0x1800,0x1b00,0x1b00,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u0140\n  0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x7000,0xe000,0x6000,0x6000,0x6000,0x7f00,0x0000,0x0000, // u0141\n  0x0000,0x0000,0x3800,0x1800,0x1800,0x1800,0x1c00,0x3800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u0142\n  0x1800,0x3000,0xc600,0xc600,0xc600,0xe600,0xf600,0xde00,0xce00,0xc600,0xc600,0xc600,0x0000,0x0000, // u0143\n  0x0000,0x0000,0x1800,0x3000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u0144\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xe600,0xf600,0xde00,0xce00,0xc600,0xc600,0xf600,0x3000,0x6000, // u0145\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xf600,0x3000,0x6000, // u0146\n  0x6c00,0x3800,0xc600,0xc600,0xc600,0xe600,0xf600,0xde00,0xce00,0xc600,0xc600,0xc600,0x0000,0x0000, // u0147\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u0148\n  0x0000,0x6000,0x6000,0xc000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u0149\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xe600,0xf600,0xde00,0xce00,0xc600,0xc600,0xc600,0x0600,0x1c00, // u014a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0600,0x1c00, // u014b\n  0x7c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u014c\n  0x0000,0x0000,0x0000,0x7c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u014d\n  0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u014e\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u014f\n  0x3600,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u0150\n  0x0000,0x0000,0x3600,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u0151\n  0x0000,0x0000,0x7e00,0xd800,0xd800,0xd800,0xde00,0xd800,0xd800,0xd800,0xd800,0x7e00,0x0000,0x0000, // u0152\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xd600,0xd600,0xde00,0xd000,0xd000,0x7c00,0x0000,0x0000, // u0153\n  0x1800,0x3000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xfc00,0xf000,0xd800,0xcc00,0xc600,0x0000,0x0000, // u0154\n  0x0000,0x0000,0x1800,0x3000,0x0000,0xde00,0xf000,0xe000,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000, // u0155\n  0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xfc00,0xf000,0xd800,0xcc00,0xf600,0x3000,0x6000, // u0156\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xde00,0xf000,0xe000,0xc000,0xc000,0xc000,0xe000,0x6000,0xc000, // u0157\n  0x6c00,0x3800,0x0000,0xfc00,0xc600,0xc600,0xc600,0xfc00,0xf000,0xd800,0xcc00,0xc600,0x0000,0x0000, // u0158\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0xde00,0xf000,0xe000,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000, // u0159\n  0x1800,0x3000,0x0000,0x7c00,0xc600,0xc000,0xc000,0x7c00,0x0600,0x0600,0xc600,0x7c00,0x0000,0x0000, // u015a\n  0x0000,0x0000,0x0c00,0x1800,0x0000,0x7e00,0xc000,0xc000,0x7c00,0x0600,0x0600,0xfc00,0x0000,0x0000, // u015b\n  0x3800,0x6c00,0x0000,0x7c00,0xc600,0xc000,0xc000,0x7c00,0x0600,0x0600,0xc600,0x7c00,0x0000,0x0000, // u015c\n  0x0000,0x0000,0x3800,0x6c00,0x0000,0x7e00,0xc000,0xc000,0x7c00,0x0600,0x0600,0xfc00,0x0000,0x0000, // u015d\n  0x0000,0x0000,0x7c00,0xc600,0xc000,0xc000,0x7c00,0x0600,0x0600,0xc600,0xc600,0x7c00,0x3000,0x6000, // u015e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0xc000,0xc000,0x7c00,0x0600,0x0600,0xfc00,0x3000,0x6000, // u015f\n  0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc000,0xc000,0x7c00,0x0600,0x0600,0xc600,0x7c00,0x0000,0x0000, // u0160\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x7e00,0xc000,0xc000,0x7c00,0x0600,0x0600,0xfc00,0x0000,0x0000, // u0161\n  0x0000,0x0000,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1c00,0x0c00,0x1800, // u0162\n  0x0000,0x0000,0x3000,0x3000,0x3000,0xfc00,0x3000,0x3000,0x3000,0x3000,0x3000,0x1e00,0x0c00,0x1800, // u0163\n  0x6c00,0x3800,0x0000,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u0164\n  0x6c00,0x3800,0x0000,0x3000,0x3000,0xfc00,0x3000,0x3000,0x3000,0x3000,0x3000,0x1e00,0x0000,0x0000, // u0165\n  0x0000,0x0000,0xff00,0x1800,0x1800,0x1800,0x7e00,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u0166\n  0x0000,0x0000,0x3000,0x3000,0x3000,0xfc00,0x3000,0x7800,0x3000,0x3000,0x3000,0x1e00,0x0000,0x0000, // u0167\n  0x7600,0xdc00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u0168\n  0x0000,0x0000,0x7600,0xdc00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u0169\n  0x7c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u016a\n  0x0000,0x0000,0x0000,0x7c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u016b\n  0x6c00,0x3800,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u016c\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u016d\n  0x3800,0x6c00,0x3800,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u016e\n  0x0000,0x0000,0x3800,0x6c00,0x3800,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u016f\n  0x3600,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u0170\n  0x0000,0x0000,0x3600,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u0171\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x1800,0x0e00, // u0172\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0c00,0x0700, // u0173\n  0x3800,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xd600,0xfe00,0xee00,0xc600,0x8200,0x0000,0x0000, // u0174\n  0x0000,0x0000,0x3800,0x6c00,0x0000,0xc600,0xc600,0xd600,0xd600,0xd600,0xd600,0x7c00,0x0000,0x0000, // u0175\n  0x3800,0x6c00,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u0176\n  0x0000,0x0000,0x3800,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x7c00, // u0177\n  0x6600,0x6600,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u0178\n  0x1800,0x3000,0x0000,0xfe00,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0xc000,0xfe00,0x0000,0x0000, // u0179\n  0x0000,0x0000,0x1800,0x3000,0x0000,0xfe00,0x0c00,0x1800,0x3000,0x6000,0xc000,0xfe00,0x0000,0x0000, // u017a\n  0x1800,0x1800,0x0000,0xfe00,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0xc000,0xfe00,0x0000,0x0000, // u017b\n  0x0000,0x0000,0x1800,0x1800,0x0000,0xfe00,0x0c00,0x1800,0x3000,0x6000,0xc000,0xfe00,0x0000,0x0000, // u017c\n  0x6c00,0x3800,0x0000,0xfe00,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0xc000,0xfe00,0x0000,0x0000, // u017d\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0xfe00,0x0c00,0x1800,0x3000,0x6000,0xc000,0xfe00,0x0000,0x0000, // u017e\n  0x0000,0x0000,0x1e00,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u017f\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0x0600,0x0600,0x0600,0x0600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u0186\n  0x0000,0x0000,0xfe00,0x0600,0x0600,0x0600,0x3e00,0x0600,0x0600,0x0600,0x0600,0xfe00,0x0000,0x0000, // u018e\n  0x0000,0x0000,0x7c00,0xc600,0x0600,0x0600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u018f\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc000,0x7800,0xc000,0xc000,0xc600,0xc600,0x7c00,0x0000,0x0000, // u0190\n  0x0000,0x0000,0x0e00,0x1b00,0x1800,0x1800,0x7e00,0x1800,0x1800,0x1800,0x1800,0x1800,0xd800,0x7000, // u0192\n  0x0000,0x0000,0x6600,0x6600,0x6600,0x7600,0x7e00,0x6e00,0x6600,0x6600,0x6600,0x6600,0x6000,0xc000, // u019d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0600,0x0600, // u019e\n  0x0000,0x0000,0xfe00,0x0600,0x0c00,0x1800,0xfe00,0x3000,0x6000,0xc000,0xc000,0xfe00,0x0000,0x0000, // u01b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0c00,0x1800,0xfc00,0x3000,0x6000,0xfe00,0x0000,0x0000, // u01b6\n  0x0000,0x0000,0xfe00,0x0600,0x0c00,0x1800,0x3c00,0x0600,0x0600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u01b7\n  0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u01cd\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u01ce\n  0x6c00,0x3800,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u01cf\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u01d0\n  0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u01d1\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u01d2\n  0x6c00,0x3800,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u01d3\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u01d4\n  0x7c00,0x0000,0x7e00,0xd800,0xd800,0xd800,0xfe00,0xd800,0xd800,0xd800,0xd800,0xde00,0x0000,0x0000, // u01e2\n  0x0000,0x0000,0x0000,0x7c00,0x0000,0x6c00,0x1600,0x1600,0x7e00,0xd000,0xd000,0x6c00,0x0000,0x0000, // u01e3\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc000,0xc000,0xde00,0xc600,0xdf00,0xc600,0x7c00,0x0000,0x0000, // u01e4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0xc600,0xc600,0xdf00,0xc600,0xc600,0x7e00,0x0600,0x7c00, // u01e5\n  0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc000,0xc000,0xde00,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u01e6\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x7e00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x7c00, // u01e7\n  0x6c00,0x3800,0xc600,0xc600,0xcc00,0xd800,0xf000,0xf000,0xd800,0xcc00,0xc600,0xc600,0x0000,0x0000, // u01e8\n  0x6c00,0x3800,0xc000,0xc000,0xc000,0xc600,0xcc00,0xd800,0xf000,0xd800,0xcc00,0xc600,0x0000,0x0000, // u01e9\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x1800,0x0e00, // u01ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x1800,0x0e00, // u01eb\n  0x7c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x1800,0x0e00, // u01ec\n  0x0000,0x0000,0x0000,0x7c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x1800,0x0e00, // u01ed\n  0x6c00,0x3800,0x0000,0xfe00,0x0c00,0x1800,0x3c00,0x0600,0x0600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u01ee\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0xfe00,0x0600,0x0c00,0x1800,0x3c00,0x0600,0x0600,0xc600,0x7c00, // u01ef\n  0x0000,0x0000,0x1b00,0x0e00,0x0000,0x0e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x6600,0x6600,0x3c00, // u01f0\n  0x1800,0x3000,0x0000,0x7c00,0xc600,0xc000,0xc000,0xde00,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u01f4\n  0x0000,0x0000,0x0c00,0x1800,0x0000,0x7e00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x7c00, // u01f5\n  0x0c00,0x1800,0x0000,0x7e00,0xd800,0xd800,0xd800,0xfe00,0xd800,0xd800,0xd800,0xde00,0x0000,0x0000, // u01fc\n  0x0000,0x0000,0x0c00,0x1800,0x0000,0x6c00,0x1600,0x1600,0x7e00,0xd000,0xd000,0x6c00,0x0000,0x0000, // u01fd\n  0x1800,0x3000,0x0000,0x7c00,0xc700,0xc600,0xce00,0xde00,0xf600,0xe600,0xc600,0x7c00,0x0000,0x0000, // u01fe\n  0x0000,0x0000,0x1800,0x3000,0x0000,0x3d00,0x6700,0x6e00,0x7e00,0x7600,0xe600,0xbc00,0x0000,0x0000, // u01ff\n  0x0000,0x0000,0x7c00,0xc600,0xc000,0xc000,0x7c00,0x0600,0x0600,0xc600,0xc600,0x7c00,0x3000,0x6000, // u0218\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0xc000,0xc000,0x7c00,0x0600,0x0600,0xfc00,0x3000,0x6000, // u0219\n  0x0000,0x0000,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1c00,0x0c00,0x1800, // u021a\n  0x0000,0x0000,0x3000,0x3000,0x3000,0xfc00,0x3000,0x3000,0x3000,0x3000,0x3000,0x1e00,0x0600,0x0c00, // u021b\n  0x7e00,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u0232\n  0x0000,0x0000,0x0000,0x7c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x7c00, // u0233\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x6600,0x6600,0x3c00, // u0237\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0x0600,0x0600,0x0600,0xc600,0x7c00,0x0000,0x0000, // u0254\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xfe00,0x0600,0x0600,0x7c00,0x0000,0x0000, // u0258\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0600,0x0600,0xfe00,0xc600,0xc600,0x7c00,0x0000,0x0000, // u0259\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc000,0x7800,0xc000,0xc600,0x7c00,0x0000,0x0000, // u025b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6000,0xc000, // u0272\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0600,0x0c00,0x1800,0x3c00,0x0600,0x0600,0xc600,0x7c00, // u0292\n  0x1800,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bb\n  0x1800,0x1800,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bc\n  0x3000,0x3000,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bd\n  0x3800,0x6c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02c6\n  0x6c00,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02c7\n  0x6c00,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02d8\n  0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02d9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x1800,0x0e00, // u02db\n  0x7600,0xdc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02dc\n  0x3600,0x6c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02dd\n  0x3000,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0300\n  0x1800,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0301\n  0x3800,0x6c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0302\n  0x7600,0xdc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0303\n  0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0304\n  0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0305\n  0x6c00,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0306\n  0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0307\n  0x6c00,0x6c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0308\n  0x3800,0x6c00,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030a\n  0x3600,0x6c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030b\n  0x6c00,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800, // u0329\n  0x6000,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0384\n  0x1800,0x3000,0x0000,0x6c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0385\n  0x6000,0xc000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u0386\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0387\n  0x6000,0xc000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000, // u0388\n  0x6000,0xc000,0x0000,0xc600,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u0389\n  0x6000,0xc000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u038a\n  0x6000,0xc000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u038c\n  0x6000,0xc000,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u038e\n  0x6000,0xc000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x6c00,0x6c00,0xee00,0x0000,0x0000, // u038f\n  0x1800,0x3000,0xd800,0xd800,0x0000,0x7000,0x3000,0x3000,0x3000,0x3000,0x3000,0x1c00,0x0000,0x0000, // u0390\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u0391\n  0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xfc00,0xc600,0xc600,0xc600,0xc600,0xfc00,0x0000,0x0000, // u0392\n  0x0000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000, // u0393\n  0x0000,0x0000,0x1000,0x1000,0x3800,0x3800,0x6c00,0x6c00,0x6c00,0xc600,0xc600,0xfe00,0x0000,0x0000, // u0394\n  0x0000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000, // u0395\n  0x0000,0x0000,0xfe00,0x0600,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0xc000,0xfe00,0x0000,0x0000, // u0396\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u0397\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xd600,0xd600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u0398\n  0x0000,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u0399\n  0x0000,0x0000,0xc600,0xc600,0xcc00,0xd800,0xf000,0xf000,0xd800,0xcc00,0xc600,0xc600,0x0000,0x0000, // u039a\n  0x0000,0x0000,0x1000,0x1000,0x3800,0x3800,0x6c00,0x6c00,0x6c00,0xc600,0xc600,0xc600,0x0000,0x0000, // u039b\n  0x0000,0x0000,0x8200,0xc600,0xee00,0xfe00,0xd600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u039c\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xe600,0xf600,0xde00,0xce00,0xc600,0xc600,0xc600,0x0000,0x0000, // u039d\n  0x0000,0x0000,0xfe00,0x0000,0x0000,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0000,0x0000, // u039e\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u039f\n  0x0000,0x0000,0xfe00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u03a0\n  0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xfc00,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000, // u03a1\n  0x0000,0x0000,0xfe00,0xc000,0x6000,0x3000,0x1800,0x1800,0x3000,0x6000,0xc000,0xfe00,0x0000,0x0000, // u03a3\n  0x0000,0x0000,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u03a4\n  0x0000,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u03a5\n  0x0000,0x0000,0x1000,0x7c00,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0x7c00,0x1000,0x0000,0x0000, // u03a6\n  0x0000,0x0000,0xc600,0xc600,0x6c00,0x6c00,0x3800,0x3800,0x6c00,0x6c00,0xc600,0xc600,0x0000,0x0000, // u03a7\n  0x0000,0x0000,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0x7c00,0x1000,0x1000,0x0000,0x0000, // u03a8\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x6c00,0x6c00,0xee00,0x0000,0x0000, // u03a9\n  0x6600,0x6600,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u03aa\n  0x6600,0x6600,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u03ab\n  0x0000,0x0000,0x1800,0x3000,0x0000,0x7a00,0xce00,0xcc00,0xcc00,0xcc00,0xce00,0x7a00,0x0000,0x0000, // u03ac\n  0x0000,0x0000,0x1800,0x3000,0x0000,0x7c00,0xc600,0xc000,0x7800,0xc000,0xc600,0x7c00,0x0000,0x0000, // u03ad\n  0x0000,0x0000,0x1800,0x3000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0600,0x0600, // u03ae\n  0x0000,0x0000,0x1800,0x3000,0x0000,0x7000,0x3000,0x3000,0x3000,0x3000,0x3000,0x1c00,0x0000,0x0000, // u03af\n  0x1800,0x3000,0x0000,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u03b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7a00,0xce00,0xcc00,0xcc00,0xcc00,0xce00,0x7a00,0x0000,0x0000, // u03b1\n  0x0000,0x0000,0x7800,0xcc00,0xcc00,0xc800,0xfc00,0xc600,0xc600,0xc600,0xc600,0xfc00,0xc000,0xc000, // u03b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x3c00,0x1800,0x1800,0x1800, // u03b3\n  0x0000,0x0000,0x7e00,0x3000,0x1800,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u03b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc000,0x7800,0xc000,0xc600,0x7c00,0x0000,0x0000, // u03b5\n  0x0000,0x0000,0xfe00,0x0c00,0x1800,0x3000,0x6000,0xc000,0xc000,0xc000,0xc000,0x7c00,0x0600,0x0c00, // u03b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0600,0x0600, // u03b7\n  0x0000,0x0000,0x3c00,0x6600,0x6600,0x6600,0x7e00,0x6600,0x6600,0x6600,0x6600,0x3c00,0x0000,0x0000, // u03b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x3000,0x3000,0x3000,0x3000,0x3000,0x1c00,0x0000,0x0000, // u03b9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xcc00,0xd800,0xf000,0xd800,0xcc00,0xc600,0x0000,0x0000, // u03ba\n  0x0000,0x0000,0x3000,0x3000,0x1800,0x1800,0x3c00,0x3c00,0x6600,0x6600,0xc300,0xc300,0x0000,0x0000, // u03bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xce00,0xf600,0xc000,0xc000, // u03bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0x6c00,0x6c00,0x3800,0x3800,0x0000,0x0000, // u03bd\n  0x0000,0x0000,0x7e00,0xc000,0xc000,0xc000,0x7c00,0xc000,0xc000,0xc000,0xc000,0x7c00,0x0600,0x0c00, // u03be\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u03bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u03c0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xfc00,0xc000,0xc000, // u03c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc000,0xc000,0xc000,0xc000,0x7c00,0x0600,0x0c00, // u03c2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6600,0x6600,0x6600,0x6600,0x6600,0x3c00,0x0000,0x0000, // u03c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x0e00,0x0000,0x0000, // u03c4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u03c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4c00,0xd600,0xd600,0xd600,0xd600,0xd600,0x7c00,0x1000,0x1000, // u03c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0x6c00,0x6c00,0x3800,0x6c00,0x6c00,0xc600,0xc600, // u03c7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0x7c00,0x1000,0x1000, // u03c8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0xc600,0xd600,0xd600,0xd600,0xfe00,0x6c00,0x0000,0x0000, // u03c9\n  0x0000,0x0000,0xd800,0xd800,0x0000,0x7000,0x3000,0x3000,0x3000,0x3000,0x3000,0x1c00,0x0000,0x0000, // u03ca\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u03cb\n  0x0000,0x0000,0x1800,0x3000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u03cc\n  0x0000,0x0000,0x1800,0x3000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u03cd\n  0x0000,0x0000,0x1800,0x3000,0x0000,0x4400,0xc600,0xd600,0xd600,0xd600,0xfe00,0x6c00,0x0000,0x0000, // u03ce\n  0x0000,0x0000,0x3c00,0x6600,0x6600,0x6600,0x3f00,0x0600,0xe600,0x6600,0x6600,0x3c00,0x0000,0x0000, // u03d1\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x7c00,0xd600,0xd600,0xd600,0xd600,0xd600,0x7c00,0x1000,0x0000, // u03d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xe300,0x3600,0x1c00,0x1800,0x3800,0x6c00,0xc700,0x0000,0x0000, // u03f0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xfc00,0xc000,0x7c00, // u03f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc000,0xc000,0xc000,0xc600,0x7c00,0x0000,0x0000, // u03f2\n  0x0000,0x0000,0x0600,0x0600,0x0000,0x0e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x6600,0x6600,0x3c00, // u03f3\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u03f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x6000,0xc000,0xfc00,0xc000,0x6000,0x3e00,0x0000,0x0000, // u03f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0x0c00,0x0600,0x7e00,0x0600,0x0c00,0xf800,0x0000,0x0000, // u03f6\n  0x3000,0x1800,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000, // u0400\n  0x6c00,0x6c00,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000, // u0401\n  0x0000,0x0000,0xf000,0x6000,0x6000,0x7c00,0x6600,0x6600,0x6600,0x6600,0x6600,0x6c00,0x0000,0x0000, // u0402\n  0x1800,0x3000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000, // u0403\n  0x0000,0x0000,0x7c00,0xc600,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xc600,0x7c00,0x0000,0x0000, // u0404\n  0x0000,0x0000,0x7c00,0xc600,0xc000,0xc000,0x7c00,0x0600,0x0600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u0405\n  0x0000,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u0406\n  0x6600,0x6600,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u0407\n  0x0000,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xcc00,0xcc00,0x7800,0x0000,0x0000, // u0408\n  0x0000,0x0000,0x3000,0x7000,0xd000,0xdc00,0xd600,0xd600,0xd600,0xd600,0xd600,0x9c00,0x0000,0x0000, // u0409\n  0x0000,0x0000,0xd000,0xd000,0xd000,0xdc00,0xf600,0xd600,0xd600,0xd600,0xd600,0xdc00,0x0000,0x0000, // u040a\n  0x0000,0x0000,0xf000,0x6000,0x6000,0x7c00,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x0000,0x0000, // u040b\n  0x1800,0x3000,0xc600,0xc600,0xcc00,0xd800,0xf000,0xf000,0xd800,0xcc00,0xc600,0xc600,0x0000,0x0000, // u040c\n  0x3000,0x1800,0xc600,0xc600,0xc600,0xce00,0xde00,0xf600,0xe600,0xc600,0xc600,0xc600,0x0000,0x0000, // u040d\n  0x6c00,0x3800,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x0600,0x7c00,0x0000,0x0000, // u040e\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xfe00,0x3800,0x3800, // u040f\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u0410\n  0x0000,0x0000,0xfc00,0xc000,0xc000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xfc00,0x0000,0x0000, // u0411\n  0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xfc00,0xc600,0xc600,0xc600,0xc600,0xfc00,0x0000,0x0000, // u0412\n  0x0000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000, // u0413\n  0x0000,0x0000,0x3e00,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0xff00,0xc300,0x0000, // u0414\n  0x0000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000, // u0415\n  0x0000,0x0000,0xd600,0xd600,0xd600,0x7c00,0x3800,0x7c00,0xd600,0xd600,0xd600,0xd600,0x0000,0x0000, // u0416\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0x0600,0x3c00,0x0600,0x0600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u0417\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xce00,0xde00,0xf600,0xe600,0xc600,0xc600,0xc600,0x0000,0x0000, // u0418\n  0x6c00,0x3800,0xc600,0xc600,0xc600,0xce00,0xde00,0xf600,0xe600,0xc600,0xc600,0xc600,0x0000,0x0000, // u0419\n  0x0000,0x0000,0xc600,0xc600,0xcc00,0xd800,0xf000,0xf000,0xd800,0xcc00,0xc600,0xc600,0x0000,0x0000, // u041a\n  0x0000,0x0000,0x1e00,0x3600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0xc600,0x0000,0x0000, // u041b\n  0x0000,0x0000,0x8200,0xc600,0xee00,0xfe00,0xd600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u041c\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u041d\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u041e\n  0x0000,0x0000,0xfe00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u041f\n  0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xfc00,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000, // u0420\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc000,0xc000,0xc000,0xc000,0xc600,0xc600,0x7c00,0x0000,0x0000, // u0421\n  0x0000,0x0000,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u0422\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x0600,0x7c00,0x0000,0x0000, // u0423\n  0x0000,0x1000,0x7c00,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0x7c00,0x1000,0x0000, // u0424\n  0x0000,0x0000,0xc600,0xc600,0x6c00,0x6c00,0x3800,0x3800,0x6c00,0x6c00,0xc600,0xc600,0x0000,0x0000, // u0425\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7f00,0x0300,0x0300, // u0426\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x0600,0x0600,0x0000,0x0000, // u0427\n  0x0000,0x0000,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0x7e00,0x0000,0x0000, // u0428\n  0x0000,0x0000,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0x7f00,0x0300,0x0300, // u0429\n  0x0000,0x0000,0xe000,0x6000,0x6000,0x7c00,0x6600,0x6600,0x6600,0x6600,0x6600,0x7c00,0x0000,0x0000, // u042a\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xe600,0xd600,0xd600,0xd600,0xd600,0xd600,0xe600,0x0000,0x0000, // u042b\n  0x0000,0x0000,0x6000,0x6000,0x6000,0x7c00,0x6600,0x6600,0x6600,0x6600,0x6600,0x7c00,0x0000,0x0000, // u042c\n  0x0000,0x0000,0x7c00,0xc600,0x0600,0x0600,0x3e00,0x0600,0x0600,0x0600,0xc600,0x7c00,0x0000,0x0000, // u042d\n  0x0000,0x0000,0xcc00,0xd600,0xd600,0xd600,0xd600,0xf600,0xd600,0xd600,0xd600,0xcc00,0x0000,0x0000, // u042e\n  0x0000,0x0000,0x7e00,0xc600,0xc600,0xc600,0xc600,0x7e00,0x1e00,0x3600,0x6600,0xc600,0x0000,0x0000, // u042f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u0430\n  0x0000,0x0000,0x7c00,0xc000,0xc000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xfc00,0x0000,0x0000, // u0431\n  0x0000,0x0000,0x7800,0xcc00,0xcc00,0xc800,0xfc00,0xc600,0xc600,0xc600,0xc600,0xfc00,0x0000,0x0000, // u0432\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000, // u0433\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x7c00, // u0434\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000, // u0435\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xd600,0xd600,0x7c00,0x3800,0x7c00,0xd600,0xd600,0x0000,0x0000, // u0436\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0x0600,0x3c00,0x0600,0xc600,0x7c00,0x0000,0x0000, // u0437\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u0438\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u0439\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xcc00,0xd800,0xf000,0xd800,0xcc00,0xc600,0x0000,0x0000, // u043a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x6600,0x6600,0x6600,0x6600,0x6600,0xc600,0x0000,0x0000, // u043b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xee00,0xfe00,0xd600,0xc600,0xc600,0xc600,0x0000,0x0000, // u043c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0x0000,0x0000, // u043d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u043e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u043f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xfc00,0xc000,0xc000, // u0440\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc000,0xc000,0xc000,0xc600,0x7c00,0x0000,0x0000, // u0441\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u0442\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x7c00, // u0443\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x7c00,0xd600,0xd600,0xd600,0xd600,0xd600,0x7c00,0x1000,0x0000, // u0444\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0x6c00,0x3800,0x6c00,0xc600,0xc600,0x0000,0x0000, // u0445\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7f00,0x0300,0x0300, // u0446\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x0600,0x0000,0x0000, // u0447\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0x7e00,0x0000,0x0000, // u0448\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0x7f00,0x0300,0x0300, // u0449\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xe000,0x6000,0x7c00,0x6600,0x6600,0x6600,0x7c00,0x0000,0x0000, // u044a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xe600,0xd600,0xd600,0xd600,0xe600,0x0000,0x0000, // u044b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x7c00,0x6600,0x6600,0x6600,0x7c00,0x0000,0x0000, // u044c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0x0600,0x3e00,0x0600,0xc600,0x7c00,0x0000,0x0000, // u044d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xcc00,0xd600,0xd600,0xf600,0xd600,0xd600,0xcc00,0x0000,0x0000, // u044e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0xc600,0xc600,0x7e00,0x3600,0x6600,0xc600,0x0000,0x0000, // u044f\n  0x0000,0x0000,0x3000,0x1800,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000, // u0450\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000, // u0451\n  0x0000,0x0000,0x6000,0xf800,0x6000,0x7c00,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x0600,0x1c00, // u0452\n  0x0000,0x0000,0x1800,0x3000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000, // u0453\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc000,0xf800,0xc000,0xc600,0x7c00,0x0000,0x0000, // u0454\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0xc000,0xc000,0x7c00,0x0600,0x0600,0xfc00,0x0000,0x0000, // u0455\n  0x0000,0x0000,0x1800,0x1800,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u0456\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u0457\n  0x0000,0x0000,0x0600,0x0600,0x0000,0x0e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x6600,0x6600,0x3c00, // u0458\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0xd000,0xdc00,0xd600,0xd600,0xd600,0x9c00,0x0000,0x0000, // u0459\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xd000,0xd000,0xdc00,0xf600,0xd600,0xd600,0xdc00,0x0000,0x0000, // u045a\n  0x0000,0x0000,0x6000,0xf800,0x6000,0x7c00,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x0000,0x0000, // u045b\n  0x0000,0x0000,0x1800,0x3000,0x0000,0xc600,0xcc00,0xd800,0xf000,0xd800,0xcc00,0xc600,0x0000,0x0000, // u045c\n  0x0000,0x0000,0x3000,0x1800,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u045d\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x7c00, // u045e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xfe00,0x3800,0x3800, // u045f\n  0x0000,0x0000,0x6000,0xf800,0x6000,0x7c00,0x6600,0x6600,0x6600,0x6600,0x6600,0x7c00,0x0000,0x0000, // u0462\n  0x0000,0x0000,0x6000,0x6000,0xf800,0x6000,0x6000,0x7c00,0x6600,0x6600,0x6600,0x7c00,0x0000,0x0000, // u0463\n  0x0000,0x0000,0xfe00,0xc600,0x6c00,0x6c00,0x3800,0x7c00,0xd600,0xd600,0xd600,0xd600,0x0000,0x0000, // u046a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x6c00,0x2800,0x3800,0x7c00,0xd600,0xd600,0x0000,0x0000, // u046b\n  0x0600,0x0600,0xfe00,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000, // u0490\n  0x0000,0x0000,0x0000,0x0600,0x0600,0xfe00,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000, // u0491\n  0x0000,0x0000,0x7f00,0x6000,0x6000,0x6000,0xfc00,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000, // u0492\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6000,0x6000,0xfc00,0x6000,0x6000,0x6000,0x0000,0x0000, // u0493\n  0x0000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xc000,0xfc00,0xc600,0xc600,0xc600,0xc600,0x0600,0x0c00, // u0494\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xc000,0xc000,0xf800,0xcc00,0xcc00,0xcc00,0x0c00,0x1800, // u0495\n  0x0000,0x0000,0xd600,0xd600,0xd600,0x7c00,0x3800,0x7c00,0xd600,0xd600,0xd600,0xd700,0x0300,0x0300, // u0496\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xd600,0xd600,0x7c00,0x3800,0x7c00,0xd600,0xd700,0x0300,0x0300, // u0497\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0x0600,0x3c00,0x0600,0x0600,0xc600,0xc600,0x7c00,0x3000,0x3000, // u0498\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0x0600,0x3c00,0x0600,0xc600,0x7c00,0x3000,0x3000, // u0499\n  0x0000,0x0000,0xc600,0xc600,0xcc00,0xd800,0xf000,0xf000,0xd800,0xcc00,0xc600,0xc700,0x0300,0x0300, // u049a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xcc00,0xd800,0xf000,0xd800,0xcc00,0xc700,0x0300,0x0300, // u049b\n  0x0000,0x0000,0xc600,0xc600,0xd600,0xdc00,0xf800,0xf800,0xdc00,0xd600,0xc600,0xc600,0x0000,0x0000, // u049c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xd600,0xdc00,0xf800,0xdc00,0xd600,0xc600,0x0000,0x0000, // u049d\n  0x0000,0x0000,0xe300,0xe300,0x6600,0x6c00,0x7800,0x7800,0x6c00,0x6600,0x6300,0x6300,0x0000,0x0000, // u04a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xe300,0x6600,0x6c00,0x7800,0x6c00,0x6600,0x6300,0x0000,0x0000, // u04a1\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0xc700,0x0300,0x0300, // u04a2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc700,0x0300,0x0300, // u04a3\n  0x0000,0x0000,0xcf00,0xcc00,0xcc00,0xcc00,0xfc00,0xcc00,0xcc00,0xcc00,0xcc00,0xcc00,0x0000,0x0000, // u04a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xcf00,0xcc00,0xcc00,0xfc00,0xcc00,0xcc00,0xcc00,0x0000,0x0000, // u04a5\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc000,0xc000,0xc000,0xc000,0xc600,0xc600,0x7c00,0x3000,0x3000, // u04aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc000,0xc000,0xc000,0xc600,0x7c00,0x3000,0x3000, // u04ab\n  0x0000,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u04ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x3c00,0x1800,0x1800,0x1800, // u04af\n  0x0000,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x1800,0x7e00,0x1800,0x1800,0x1800,0x0000,0x0000, // u04b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x3c00,0x1800,0x7e00,0x1800, // u04b1\n  0x0000,0x0000,0xc600,0xc600,0x6c00,0x6c00,0x3800,0x3800,0x6c00,0x6c00,0xc600,0xc700,0x0300,0x0300, // u04b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0x6c00,0x3800,0x6c00,0xc600,0xc700,0x0300,0x0300, // u04b3\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x0600,0x0700,0x0300,0x0300, // u04b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x0700,0x0300,0x0300, // u04b7\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xd600,0xd600,0x7e00,0x1600,0x1600,0x0600,0x0600,0x0000,0x0000, // u04b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xd600,0xd600,0x7e00,0x1600,0x0600,0x0600,0x0000,0x0000, // u04b9\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xc000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u04ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0xc000,0xfc00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u04bb\n  0x0000,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u04c0\n  0x6c00,0x3800,0x0000,0xd600,0xd600,0xd600,0x7c00,0x3800,0x7c00,0xd600,0xd600,0xd600,0x0000,0x0000, // u04c1\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0xd600,0xd600,0x7c00,0x3800,0x7c00,0xd600,0xd600,0x0000,0x0000, // u04c2\n  0x0000,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u04cf\n  0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u04d0\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u04d1\n  0x6c00,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u04d2\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u04d3\n  0x0000,0x0000,0x7e00,0xd800,0xd800,0xd800,0xfe00,0xd800,0xd800,0xd800,0xd800,0xde00,0x0000,0x0000, // u04d4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6c00,0x1600,0x1600,0x7e00,0xd000,0xd000,0x6c00,0x0000,0x0000, // u04d5\n  0x6c00,0x3800,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000, // u04d6\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000, // u04d7\n  0x0000,0x0000,0x7c00,0xc600,0x0600,0x0600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u04d8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0600,0x0600,0xfe00,0xc600,0xc600,0x7c00,0x0000,0x0000, // u04d9\n  0x6c00,0x6c00,0x0000,0x7c00,0xc600,0x0600,0x0600,0xfe00,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u04da\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0x7c00,0x0600,0x0600,0xfe00,0xc600,0xc600,0x7c00,0x0000,0x0000, // u04db\n  0x6c00,0x6c00,0x0000,0xd600,0xd600,0xd600,0x7c00,0x3800,0x7c00,0xd600,0xd600,0xd600,0x0000,0x0000, // u04dc\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0xd600,0xd600,0x7c00,0x3800,0x7c00,0xd600,0xd600,0x0000,0x0000, // u04dd\n  0x6c00,0x6c00,0x0000,0x7c00,0xc600,0xc600,0x0600,0x3c00,0x0600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u04de\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0x7c00,0xc600,0x0600,0x3c00,0x0600,0xc600,0x7c00,0x0000,0x0000, // u04df\n  0x7c00,0x0000,0xc600,0xc600,0xc600,0xce00,0xde00,0xf600,0xe600,0xc600,0xc600,0xc600,0x0000,0x0000, // u04e2\n  0x0000,0x0000,0x0000,0x7c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u04e3\n  0x6c00,0x6c00,0x0000,0xc600,0xc600,0xc600,0xce00,0xde00,0xf600,0xe600,0xc600,0xc600,0x0000,0x0000, // u04e4\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000, // u04e5\n  0x6c00,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u04e6\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u04e7\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u04e8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc600,0xc600,0x7c00,0x0000,0x0000, // u04e9\n  0x6c00,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u04ea\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc600,0xc600,0x7c00,0x0000,0x0000, // u04eb\n  0x6c00,0x6c00,0x0000,0x7c00,0xc600,0x0600,0x0600,0x3e00,0x0600,0x0600,0xc600,0x7c00,0x0000,0x0000, // u04ec\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0x7c00,0xc600,0x0600,0x3e00,0x0600,0xc600,0x7c00,0x0000,0x0000, // u04ed\n  0x7c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x0600,0x7c00,0x0000,0x0000, // u04ee\n  0x0000,0x0000,0x0000,0x7c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x7c00, // u04ef\n  0x6c00,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x0600,0x7c00,0x0000,0x0000, // u04f0\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x7c00, // u04f1\n  0x3600,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x0600,0x7c00,0x0000,0x0000, // u04f2\n  0x0000,0x0000,0x3600,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x7c00, // u04f3\n  0x6c00,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x0600,0x0600,0x0000,0x0000, // u04f4\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x0600,0x0000,0x0000, // u04f5\n  0x6c00,0x6c00,0x0000,0xc600,0xc600,0xc600,0xe600,0xd600,0xd600,0xd600,0xd600,0xe600,0x0000,0x0000, // u04f8\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0xc600,0xc600,0xe600,0xd600,0xd600,0xd600,0xe600,0x0000,0x0000, // u04f9\n  0x0000,0x0000,0xc600,0xc600,0x6600,0x6600,0x3c00,0x7800,0xcc00,0xcc00,0xc600,0xc600,0x0000,0x0000, // u05d0\n  0x0000,0x0000,0xfc00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xff00,0x0000,0x0000, // u05d1\n  0x0000,0x0000,0x7800,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x3600,0x6300,0xc300,0x0000,0x0000, // u05d2\n  0x0000,0x0000,0xff00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000,0x0000, // u05d3\n  0x0000,0x0000,0xfc00,0x0600,0x0600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u05d4\n  0x0000,0x0000,0x7000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u05d5\n  0x0000,0x0000,0x7e00,0x0c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u05d6\n  0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u05d7\n  0x0000,0x0000,0xcc00,0xce00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u05d8\n  0x0000,0x0000,0x7000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d9\n  0x0000,0x0000,0xfc00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u05da\n  0x0000,0x0000,0xfc00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfc00,0x0000,0x0000, // u05db\n  0xc000,0xc000,0xfe00,0x0600,0x0600,0x0600,0x0600,0x0c00,0x1800,0x3000,0x3000,0x3000,0x0000,0x0000, // u05dc\n  0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xfe00,0x0000,0x0000, // u05dd\n  0x0000,0x0000,0xdc00,0x7600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6e00,0x0000,0x0000, // u05de\n  0x0000,0x0000,0xf000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u05df\n  0x0000,0x0000,0x7800,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x7c00,0x0000,0x0000, // u05e0\n  0x0000,0x0000,0xfc00,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x3c00,0x0000,0x0000, // u05e1\n  0x0000,0x0000,0xc600,0xc600,0xc600,0x6600,0x6600,0x3600,0x3600,0x1c00,0x3800,0xe000,0x0000,0x0000, // u05e2\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0x6600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u05e3\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0x6600,0x0600,0x0600,0x0600,0x0600,0xfc00,0x0000,0x0000, // u05e4\n  0x0000,0x0000,0xc600,0xc600,0x6600,0x6c00,0x3800,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000, // u05e5\n  0x0000,0x0000,0xc600,0xc600,0x6600,0x6c00,0x3800,0x3000,0x1800,0x1800,0x0c00,0xfc00,0x0000,0x0000, // u05e6\n  0x0000,0x0000,0xfe00,0x0600,0x0600,0xc600,0xc600,0xcc00,0xd800,0xd800,0xd800,0xd800,0xc000,0xc000, // u05e7\n  0x0000,0x0000,0xfc00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000,0x0000, // u05e8\n  0x0000,0x0000,0xd600,0xd600,0xd600,0xd600,0xd600,0xe600,0xc600,0xc600,0xcc00,0xf800,0x0000,0x0000, // u05e9\n  0x0000,0x0000,0xfc00,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0xc600,0x0000,0x0000, // u05ea\n  0x0000,0x0000,0xf800,0xcc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xcc00,0xf800,0x3000,0x3000, // u1e0c\n  0x0000,0x0000,0x0600,0x0600,0x0600,0x7e00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x1800,0x1800, // u1e0d\n  0x0000,0x0000,0xc600,0xc600,0xcc00,0xd800,0xf000,0xf000,0xd800,0xcc00,0xc600,0xc600,0x0000,0x7c00, // u1e34\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xc600,0xcc00,0xd800,0xf000,0xd800,0xcc00,0xc600,0x0000,0x7c00, // u1e35\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xfe00,0x1800,0x1800, // u1e36\n  0x0000,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x1800,0x1800, // u1e37\n  0x1800,0x1800,0x8200,0xc600,0xee00,0xfe00,0xd600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u1e40\n  0x0000,0x0000,0x3000,0x3000,0x0000,0xfc00,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0x0000,0x0000, // u1e41\n  0x0000,0x0000,0x8200,0xc600,0xee00,0xfe00,0xd600,0xc600,0xc600,0xc600,0xc600,0xc600,0x1800,0x1800, // u1e42\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0x1800,0x1800, // u1e43\n  0x1800,0x1800,0xc600,0xc600,0xc600,0xe600,0xf600,0xde00,0xce00,0xc600,0xc600,0xc600,0x0000,0x0000, // u1e44\n  0x0000,0x0000,0x3000,0x3000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u1e45\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xe600,0xf600,0xde00,0xce00,0xc600,0xc600,0xc600,0x1800,0x1800, // u1e46\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x1800,0x1800, // u1e47\n  0x0000,0x0000,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0c00,0x0c00, // u1e6c\n  0x0000,0x0000,0x3000,0x3000,0x3000,0xfc00,0x3000,0x3000,0x3000,0x3000,0x3000,0x1e00,0x0c00,0x0c00, // u1e6d\n  0x0000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xc000,0xfe00,0x1800,0x1800, // u1eb8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x1800,0x1800, // u1eb9\n  0x7600,0xdc00,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000, // u1ebc\n  0x0000,0x0000,0x7600,0xdc00,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000, // u1ebd\n  0x0000,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x1800,0x1800, // u1eca\n  0x0000,0x0000,0x1800,0x1800,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x1800,0x1800, // u1ecb\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x1800,0x1800, // u1ecc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x1800,0x1800, // u1ecd\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x1800,0x1800, // u1ee4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x1800,0x1800, // u1ee5\n  0x7600,0xdc00,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u1ef8\n  0x0000,0x0000,0x7600,0xdc00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x7c00, // u1ef9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2001\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2002\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2003\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2004\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2005\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2006\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2007\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2008\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2009\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2010\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2011\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2012\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2013\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2014\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2015\n  0x0000,0x0000,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x0000,0x0000, // u2016\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0000,0xfe00, // u2017\n  0x0000,0x1800,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2018\n  0x0000,0x1800,0x1800,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2019\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x3000,0x0000, // u201a\n  0x0000,0x3000,0x3000,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201b\n  0x0000,0x6600,0xcc00,0xcc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201c\n  0x0000,0x3300,0x3300,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0xcc00,0x0000, // u201e\n  0x0000,0xcc00,0xcc00,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201f\n  0x0000,0x0000,0x1800,0x1800,0x7e00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2020\n  0x0000,0x0000,0x1800,0x1800,0x7e00,0x1800,0x1800,0x1800,0x1800,0x7e00,0x1800,0x1800,0x0000,0x0000, // u2021\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x3c00,0x3c00,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000, // u2022\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xdb00,0xdb00,0x0000,0x0000, // u2026\n  0x0000,0x0000,0xec00,0xac00,0xf800,0x1800,0x3000,0x3000,0x6000,0x7f00,0xd500,0xdf00,0x0000,0x0000, // u2030\n  0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2032\n  0x0000,0x6600,0x6600,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2033\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x1800,0x3000,0x6000,0x3000,0x1800,0x0c00,0x0000,0x0000, // u2039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x3000,0x1800,0x0c00,0x1800,0x3000,0x6000,0x0000,0x0000, // u203a\n  0x0000,0x0000,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000,0x0000, // u203c\n  0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u203e\n  0x0000,0x3800,0x6c00,0x6c00,0x6c00,0x6c00,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2070\n  0x1800,0x0000,0x3800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2071\n  0x0000,0x0c00,0x1c00,0x3400,0x7e00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2074\n  0x0000,0x7800,0x6000,0x7800,0x0c00,0x0c00,0x7800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2075\n  0x0000,0x3800,0x6000,0x7800,0x6c00,0x6c00,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2076\n  0x0000,0x7c00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2077\n  0x0000,0x3800,0x6c00,0x3800,0x6c00,0x6c00,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2078\n  0x0000,0x3800,0x6c00,0x6c00,0x3c00,0x0c00,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2079\n  0x0000,0x0000,0x1800,0x1800,0x7e00,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207a\n  0x0000,0x0000,0x0000,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207b\n  0x0000,0x0000,0x0000,0x7c00,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207c\n  0x0000,0x1800,0x3000,0x3000,0x3000,0x3000,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207d\n  0x0000,0x3000,0x1800,0x1800,0x1800,0x1800,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207e\n  0x0000,0x0000,0x7800,0x6c00,0x6c00,0x6c00,0x6c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x6c00,0x6c00,0x6c00,0x6c00,0x3800,0x0000,0x0000, // u2080\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x3800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u2081\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x6c00,0x0c00,0x1800,0x3000,0x7c00,0x0000,0x0000, // u2082\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7800,0x0c00,0x3800,0x0c00,0x0c00,0x7800,0x0000,0x0000, // u2083\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x1c00,0x3400,0x7e00,0x0c00,0x0c00,0x0000,0x0000, // u2084\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7800,0x6000,0x7800,0x0c00,0x0c00,0x7800,0x0000,0x0000, // u2085\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x6000,0x7800,0x6c00,0x6c00,0x3800,0x0000,0x0000, // u2086\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x0000,0x0000, // u2087\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x6c00,0x3800,0x6c00,0x6c00,0x3800,0x0000,0x0000, // u2088\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x6c00,0x6c00,0x3c00,0x0c00,0x3800,0x0000,0x0000, // u2089\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x7e00,0x1800,0x1800,0x0000,0x0000, // u208a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000, // u208b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0000,0x7c00,0x0000,0x0000,0x0000, // u208c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x3000,0x3000,0x3000,0x3000,0x1800,0x0000,0x0000, // u208d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x1800,0x1800,0x1800,0x1800,0x3000,0x0000,0x0000, // u208e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x0c00,0x3c00,0x6c00,0x3c00,0x0000,0x0000, // u2090\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x6c00,0x7c00,0x6000,0x3c00,0x0000,0x0000, // u2091\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x6c00,0x6c00,0x6c00,0x3800,0x0000,0x0000, // u2092\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x3c00,0x1800,0x3c00,0x6600,0x0000,0x0000, // u2093\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7800,0x0c00,0x7c00,0x6c00,0x3800,0x0000,0x0000, // u2094\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x7800,0x6c00,0x6c00,0x6c00,0x6c00,0x0000,0x0000, // u2095\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6600,0x6c00,0x7800,0x6c00,0x6600,0x0000,0x0000, // u2096\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000, // u2097\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xd600,0xd600,0xd600,0xd600,0x0000,0x0000, // u2098\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7800,0x6c00,0x6c00,0x6c00,0x7800,0x6000,0x6000, // u209a\n  0x0000,0x0000,0xf800,0xcc00,0xcc00,0xcc00,0xfa00,0xc600,0xcf00,0xc600,0xc600,0xc300,0x0000,0x0000, // u20a7\n  0x0000,0x0000,0xf200,0x8a00,0x8a00,0xaa00,0xaa00,0xaa00,0xaa00,0xa200,0xa200,0xbc00,0x0000,0x0000, // u20aa\n  0x0000,0x0000,0x0000,0x1e00,0x3300,0x6000,0xfc00,0x6000,0xfc00,0x6000,0x3300,0x1e00,0x0000,0x0000, // u20ac\n  0x0000,0x0000,0xff00,0x1800,0x1800,0x1e00,0x7800,0x1e00,0x7800,0x1800,0x1800,0x1800,0x0000,0x0000, // u20ae\n  0x0000,0x0000,0x3c00,0x5200,0x5200,0x5000,0x5000,0x5000,0x5000,0x5200,0x5200,0x3c00,0x0000,0x0000, // u2102\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u210e\n  0x0000,0x0000,0x6000,0xf800,0x6000,0x7c00,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x0000,0x0000, // u210f\n  0x0000,0x0000,0x4200,0x4200,0x6200,0x5200,0x6a00,0x5600,0x4a00,0x4600,0x4200,0x4200,0x0000,0x0000, // u2115\n  0x0000,0x0000,0x9600,0x9600,0x9600,0xd000,0xf000,0xf000,0xb000,0x9600,0x9000,0x9600,0x0000,0x0000, // u2116\n  0x0000,0x0000,0x3c00,0x5200,0x5200,0x5200,0x5200,0x5200,0x5200,0x5200,0x5a00,0x3c00,0x0600,0x0000, // u211a\n  0x0000,0x0000,0xf800,0xa400,0xa400,0xa400,0xa400,0xb800,0xa800,0xb400,0xaa00,0xe600,0x0000,0x0000, // u211d\n  0x0000,0x0000,0xfb00,0x5500,0x5500,0x5100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2122\n  0x0000,0x0000,0x7e00,0x0200,0x0600,0x0a00,0x1400,0x2800,0x5000,0x6000,0x4000,0x7e00,0x0000,0x0000, // u2124\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x6c00,0x6c00,0xee00,0x0000,0x0000, // u2126\n  0x0000,0x0000,0x6600,0x6600,0x3300,0x3300,0x3e00,0x7c00,0xcc00,0xcc00,0xc600,0x6600,0x0000,0x0000, // u2135\n  0x0000,0x0000,0x0000,0x0000,0x2000,0x6000,0xfe00,0xfe00,0x6000,0x2000,0x0000,0x0000,0x0000,0x0000, // u2190\n  0x0000,0x0000,0x1800,0x3c00,0x7e00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2191\n  0x0000,0x0000,0x0000,0x0000,0x0800,0x0c00,0xfe00,0xfe00,0x0c00,0x0800,0x0000,0x0000,0x0000,0x0000, // u2192\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x7e00,0x3c00,0x1800,0x0000,0x0000, // u2193\n  0x0000,0x0000,0x0000,0x0000,0x2400,0x6600,0xff00,0xff00,0x6600,0x2400,0x0000,0x0000,0x0000,0x0000, // u2194\n  0x0000,0x0000,0x1800,0x3c00,0x7e00,0x1800,0x1800,0x1800,0x1800,0x7e00,0x3c00,0x1800,0x0000,0x0000, // u2195\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x6200,0xfe00,0xfe00,0x6200,0x2200,0x0000,0x0000,0x0000,0x0000, // u21a4\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x8c00,0xfe00,0xfe00,0x8c00,0x8800,0x0000,0x0000,0x0000,0x0000, // u21a6\n  0x0000,0x0000,0x1800,0x3c00,0x7e00,0x1800,0x1800,0x1800,0x7e00,0x3c00,0x1800,0x7e00,0x0000,0x0000, // u21a8\n  0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x2600,0x6600,0xfe00,0xfe00,0x6000,0x2000,0x0000,0x0000, // u21b5\n  0x0000,0x0000,0x0000,0xf800,0x3800,0x6800,0xcb00,0xc300,0xc300,0x6600,0x3c00,0x0000,0x0000,0x0000, // u21bb\n  0x0000,0x0000,0x2000,0x6000,0xfe00,0xfe00,0x0000,0xfe00,0xfe00,0x0c00,0x0800,0x0000,0x0000,0x0000, // u21cb\n  0x0000,0x0000,0x0800,0x0c00,0xfe00,0xfe00,0x0000,0xfe00,0xfe00,0x6000,0x2000,0x0000,0x0000,0x0000, // u21cc\n  0x0000,0x0000,0x0000,0x1000,0x3e00,0x7e00,0xe000,0x7e00,0x3e00,0x1000,0x0000,0x0000,0x0000,0x0000, // u21d0\n  0x0000,0x0000,0x1000,0x3800,0x7c00,0xee00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x0000,0x0000, // u21d1\n  0x0000,0x0000,0x0000,0x1000,0xf800,0xfc00,0x0e00,0xfc00,0xf800,0x1000,0x0000,0x0000,0x0000,0x0000, // u21d2\n  0x0000,0x0000,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0xee00,0x7c00,0x3800,0x1000,0x0000,0x0000, // u21d3\n  0x0000,0x0000,0x0000,0x2400,0x7e00,0xff00,0xc300,0xff00,0x7e00,0x2400,0x0000,0x0000,0x0000,0x0000, // u21d4\n  0x0000,0x0000,0x1000,0x3800,0x7c00,0xee00,0x6c00,0x6c00,0xee00,0x7c00,0x3800,0x1000,0x0000,0x0000, // u21d5\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xfe00,0x6c00,0x6c00,0x6c00,0x3800,0x3800,0x3800,0x0000,0x0000, // u2200\n  0x0000,0x0000,0x0000,0xfe00,0x0600,0x0600,0x0600,0xfe00,0x0600,0x0600,0x0600,0xfe00,0x0000,0x0000, // u2203\n  0x0000,0x0000,0x0c00,0xfe00,0x1e00,0x1600,0x3600,0xfe00,0x3600,0x6600,0x6600,0xfe00,0xc000,0x0000, // u2204\n  0x0000,0x0000,0x0600,0x0c00,0x7c00,0xce00,0xde00,0xf600,0xe600,0x7c00,0x6000,0xc000,0x0000,0x0000, // u2205\n  0x0000,0x0000,0x1000,0x1000,0x3800,0x3800,0x6c00,0x6c00,0x6c00,0xc600,0xc600,0xfe00,0x0000,0x0000, // u2206\n  0x0000,0x0000,0xfe00,0xc600,0xc600,0x6c00,0x6c00,0x6c00,0x3800,0x3800,0x1000,0x1000,0x0000,0x0000, // u2207\n  0x0000,0x0000,0x0000,0x3e00,0x6000,0xc000,0xc000,0xfe00,0xc000,0xc000,0x6000,0x3e00,0x0000,0x0000, // u2208\n  0x0000,0x0000,0x0600,0x3e00,0x6c00,0xcc00,0xd800,0xfe00,0xd800,0xf000,0x7000,0x7e00,0x6000,0x0000, // u2209\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x6000,0xc000,0xfe00,0xc000,0x6000,0x3e00,0x0000,0x0000,0x0000, // u220a\n  0x0000,0x0000,0x0000,0xf800,0x0c00,0x0600,0x0600,0xfe00,0x0600,0x0600,0x0c00,0xf800,0x0000,0x0000, // u220b\n  0x0000,0x0000,0xc000,0xf800,0x6c00,0x6600,0x3600,0xfe00,0x3600,0x1e00,0x1c00,0xfc00,0x0c00,0x0000, // u220c\n  0x0000,0x0000,0x0000,0x0000,0xf800,0x0c00,0x0600,0xfe00,0x0600,0x0c00,0xf800,0x0000,0x0000,0x0000, // u220d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2212\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0000,0x1800,0x1800,0x7e00,0x1800,0x1800,0x0000,0x0000, // u2213\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x0000,0x1800,0x1800,0x7e00,0x1800,0x1800,0x0000,0x0000, // u2214\n  0x0000,0x0000,0x0000,0x0000,0x0200,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0x8000,0x0000,0x0000, // u2215\n  0x0000,0x0000,0x0000,0x0000,0x8000,0xc000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0200,0x0000,0x0000, // u2216\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000, // u2219\n  0x0000,0x0e00,0x0c00,0x0c00,0x0c00,0x0c00,0xcc00,0xcc00,0xcc00,0x6c00,0x3c00,0x1c00,0x0000,0x0000, // u221a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xd600,0xd600,0xd600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u221e\n  0x0000,0x0000,0x0000,0x0000,0xc000,0xc000,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u221f\n  0x0000,0x0000,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x0000,0x0000, // u2225\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x3c00,0x3c00,0x6600,0x6600,0xc300,0xc300,0x0000,0x0000, // u2227\n  0x0000,0x0000,0x0000,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x3c00,0x1800,0x1800,0x0000,0x0000, // u2228\n  0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u2229\n  0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u222a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7600,0xdc00,0x0000,0x7600,0xdc00,0x0000,0x0000,0x0000,0x0000, // u2248\n  0x0000,0x0000,0x0000,0x0000,0x0600,0xfe00,0x1800,0x3000,0xfe00,0xc000,0x0000,0x0000,0x0000,0x0000, // u2260\n  0x0000,0x0000,0x0000,0x0000,0xfe00,0x0000,0x0000,0xfe00,0x0000,0x0000,0xfe00,0x0000,0x0000,0x0000, // u2261\n  0x0000,0x0000,0x0000,0x0c00,0x1800,0x3000,0x6000,0x3000,0x1800,0x0c00,0x0000,0x7e00,0x0000,0x0000, // u2264\n  0x0000,0x0000,0x0000,0x3000,0x1800,0x0c00,0x0600,0x0c00,0x1800,0x3000,0x0000,0x7e00,0x0000,0x0000, // u2265\n  0x0000,0x0000,0x0000,0x0900,0x1b00,0x3600,0x6c00,0xd800,0x6c00,0x3600,0x1b00,0x0900,0x0000,0x0000, // u226a\n  0x0000,0x0000,0x0000,0x9000,0xd800,0x6c00,0x3600,0x1b00,0x3600,0x6c00,0xd800,0x9000,0x0000,0x0000, // u226b\n  0x0000,0x0000,0x0000,0x0000,0x7e00,0xc000,0xc000,0xc000,0xc000,0xc000,0x7e00,0x0000,0x0000,0x0000, // u2282\n  0x0000,0x0000,0x0000,0x0000,0xfc00,0x0600,0x0600,0x0600,0x0600,0x0600,0xfc00,0x0000,0x0000,0x0000, // u2283\n  0x0000,0x0000,0x0000,0x7e00,0xc000,0xc000,0xc000,0xc000,0xc000,0x7e00,0x0000,0xfe00,0x0000,0x0000, // u2286\n  0x0000,0x0000,0x0000,0xfc00,0x0600,0x0600,0x0600,0x0600,0x0600,0xfc00,0x0000,0xfe00,0x0000,0x0000, // u2287\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0x0000,0x0000, // u22a5\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000, // u22c2\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000, // u22c3\n  0x0000,0x0000,0x0600,0x0c00,0x7c00,0xce00,0xde00,0xf600,0xe600,0x7c00,0x6000,0xc000,0x0000,0x0000, // u2300\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x3800,0x6c00,0xc600,0xc600,0xc600,0xc600,0xfe00,0x0000,0x0000, // u2302\n  0x0000,0x0000,0x3c00,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2308\n  0x0000,0x0000,0x3c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000, // u2309\n  0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3c00,0x0000,0x0000, // u230a\n  0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x3c00,0x0000,0x0000, // u230b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xc000,0xc000,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2310\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2319\n  0x0000,0x0000,0x0e00,0x1b00,0x1b00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2320\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xd800,0xd800,0x7000,0x0000,0x0000, // u2321\n  0x0600,0x0c00,0x1800,0x1800,0x3000,0x3000,0x3000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000, // u239b\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000, // u239c\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x3000,0x3000,0x3000,0x1800,0x1800,0x0c00,0x0600, // u239d\n  0x6000,0x3000,0x1800,0x1800,0x0c00,0x0c00,0x0c00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u239e\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u239f\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0c00,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x6000, // u23a0\n  0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000, // u23a1\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000, // u23a2\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7e00, // u23a3\n  0x7e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u23a4\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u23a5\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x7e00, // u23a6\n  0x0f00,0x1800,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000, // u23a7\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0xe000,0xe000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000, // u23a8\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x1800,0x0f00, // u23a9\n  0xf000,0x1800,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u23ab\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0700,0x0700,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u23ac\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1800,0xf000, // u23ad\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u23ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23af\n  0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23ba\n  0x0000,0x0000,0x0000,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x0000,0x0000,0x0000, // u23bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00, // u23bd\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u23d0\n  0xcc00,0xcc00,0xfc00,0xcc00,0xcc00,0xcc00,0x0000,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000, // u2409\n  0xc000,0xc000,0xc000,0xc000,0xc000,0xf800,0x0000,0x3f00,0x3000,0x3c00,0x3000,0x3000,0x3000,0x0000, // u240a\n  0xcc00,0xcc00,0xcc00,0xcc00,0x7800,0x3000,0x0000,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000, // u240b\n  0xfc00,0xc000,0xf000,0xc000,0xc000,0xc000,0x0000,0x3f00,0x3000,0x3c00,0x3000,0x3000,0x3000,0x0000, // u240c\n  0x7800,0xcc00,0xc000,0xc000,0xcc00,0x7800,0x0000,0x3e00,0x3300,0x3300,0x3e00,0x3600,0x3300,0x0000, // u240d\n  0xcc00,0xec00,0xfc00,0xdc00,0xcc00,0xcc00,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3f00,0x0000, // u2424\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2500\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2501\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2502\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2503\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xaa00,0xaa00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2508\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xaa00,0xaa00,0xaa00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2509\n  0x1800,0x1800,0x1800,0x0000,0x1800,0x1800,0x0000,0x1800,0x1800,0x1800,0x0000,0x1800,0x1800,0x0000, // u250a\n  0x3800,0x3800,0x3800,0x0000,0x3800,0x3800,0x0000,0x3800,0x3800,0x3800,0x0000,0x3800,0x3800,0x0000, // u250b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u250c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x1f00,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u250d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x3f00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u250e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x3f00,0x3f00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u250f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2510\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2511\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2512\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0xf800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2513\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2514\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0x1f00,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2515\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3f00,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2516\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3f00,0x3f00,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2517\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2518\n  0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2519\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u251a\n  0x3800,0x3800,0x3800,0x3800,0x3800,0xf800,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u251b\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u251c\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0x1f00,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u251d\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3f00,0x3f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u251e\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3f00,0x3f00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u251f\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3f00,0x3f00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2520\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3f00,0x3f00,0x3f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2521\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x3f00,0x3f00,0x3f00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2522\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3f00,0x3f00,0x3f00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2523\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2524\n  0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0xf800,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2525\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0xf800,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2526\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0xf800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2527\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0xf800,0xf800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2528\n  0x3800,0x3800,0x3800,0x3800,0x3800,0xf800,0xf800,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2529\n  0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0xf800,0xf800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u252a\n  0x3800,0x3800,0x3800,0x3800,0x3800,0xf800,0xf800,0xf800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u252b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u252c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u252d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u252e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u252f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2530\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xff00,0xff00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2531\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0xff00,0xff00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2532\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2533\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2534\n  0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2535\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2536\n  0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2537\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2538\n  0x3800,0x3800,0x3800,0x3800,0x3800,0xf800,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2539\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3f00,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u253a\n  0x3800,0x3800,0x3800,0x3800,0x3800,0xff00,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u253b\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u253c\n  0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u253d\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u253e\n  0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u253f\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2540\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0xff00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2541\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0xff00,0xff00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2542\n  0x3800,0x3800,0x3800,0x3800,0x3800,0xf800,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2543\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3f00,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2544\n  0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0xff00,0xff00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2545\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0xff00,0xff00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2546\n  0x3800,0x3800,0x3800,0x3800,0x3800,0xff00,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2547\n  0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0xff00,0xff00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2548\n  0x3800,0x3800,0x3800,0x3800,0x3800,0xf800,0xff00,0xff00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2549\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3f00,0xff00,0xff00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u254a\n  0x3800,0x3800,0x3800,0x3800,0x3800,0xff00,0xff00,0xff00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u254b\n  0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x0000,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2550\n  0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00, // u2551\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x1f00,0x1800,0x1f00,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800, // u2552\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x7f00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00, // u2553\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x7f00,0x6000,0x6f00,0x6f00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00, // u2554\n  0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0x1800,0xf800,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2555\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00, // u2556\n  0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x0c00,0xec00,0xec00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00, // u2557\n  0x1800,0x1800,0x1800,0x1800,0x1f00,0x1f00,0x1800,0x1f00,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2558\n  0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x7f00,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2559\n  0x6c00,0x6c00,0x6c00,0x6c00,0x6f00,0x6f00,0x6000,0x7f00,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u255a\n  0x1800,0x1800,0x1800,0x1800,0xf800,0xf800,0x1800,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000, // u255b\n  0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255c\n  0x6c00,0x6c00,0x6c00,0x6c00,0xec00,0xec00,0x0c00,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000, // u255d\n  0x1800,0x1800,0x1800,0x1800,0x1f00,0x1f00,0x1800,0x1f00,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800, // u255e\n  0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6f00,0x6f00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00, // u255f\n  0x6c00,0x6c00,0x6c00,0x6c00,0x6f00,0x6f00,0x6000,0x6f00,0x6f00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00, // u2560\n  0x1800,0x1800,0x1800,0x1800,0xf800,0xf800,0x1800,0xf800,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2561\n  0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0xec00,0xec00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00, // u2562\n  0x6c00,0x6c00,0x6c00,0x6c00,0xec00,0xec00,0x0c00,0xec00,0xec00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00, // u2563\n  0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x0000,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800, // u2564\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00, // u2565\n  0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x0000,0xef00,0xef00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00, // u2566\n  0x1800,0x1800,0x1800,0x1800,0xff00,0xff00,0x0000,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2567\n  0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2568\n  0x6c00,0x6c00,0x6c00,0x6c00,0xef00,0xef00,0x0000,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2569\n  0x1800,0x1800,0x1800,0x1800,0xff00,0xff00,0x1800,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800, // u256a\n  0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0xff00,0xff00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00, // u256b\n  0x6c00,0x6c00,0x6c00,0x6c00,0xef00,0xef00,0x0000,0xef00,0xef00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00, // u256c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0f00,0x1c00,0x1800,0x1800,0x1800,0x1800,0x1800, // u256d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xe000,0xf000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800, // u256e\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x3800,0xf000,0xe000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u256f\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1c00,0x0f00,0x0700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2570\n  0x0100,0x0300,0x0200,0x0600,0x0400,0x0c00,0x0800,0x1800,0x1000,0x3000,0x2000,0x6000,0x4000,0xc000, // u2571\n  0xc000,0x4000,0x6000,0x2000,0x3000,0x1000,0x1800,0x0800,0x0c00,0x0400,0x0600,0x0200,0x0300,0x0100, // u2572\n  0xc100,0x4300,0x6200,0x2600,0x3400,0x1c00,0x1800,0x1800,0x1c00,0x3400,0x2600,0x6200,0x4300,0xc100, // u2573\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2574\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2575\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2576\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2577\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2578\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2579\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x1f00,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u257b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257c\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u257d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257e\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u257f\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2580\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00, // u2581\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0xff00, // u2582\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0xff00,0xff00, // u2583\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2584\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2585\n  0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2586\n  0x0000,0x0000,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2587\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2588\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00, // u2589\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00, // u258a\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800, // u258b\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000, // u258c\n  0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000, // u258d\n  0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000, // u258e\n  0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000, // u258f\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u2590\n  0x8800,0x2200,0x8800,0x2200,0x8800,0x2200,0x8800,0x2200,0x8800,0x2200,0x8800,0x2200,0x8800,0x2200, // u2591\n  0xaa00,0x5500,0xaa00,0x5500,0xaa00,0x5500,0xaa00,0x5500,0xaa00,0x5500,0xaa00,0x5500,0xaa00,0x5500, // u2592\n  0xee00,0xbb00,0xee00,0xbb00,0xee00,0xbb00,0xee00,0xbb00,0xee00,0xbb00,0xee00,0xbb00,0xee00,0xbb00, // u2593\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000, // u2596\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u2597\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2598\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2599\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u259a\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000, // u259b\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u259c\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u259d\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000, // u259e\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u259f\n  0x0000,0x0000,0x0000,0x0000,0x7c00,0x7c00,0x7c00,0x7c00,0x7c00,0x7c00,0x0000,0x0000,0x0000,0x0000, // u25a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xfe00,0xfe00,0xfe00,0x0000,0x0000, // u25ac\n  0x0000,0x0000,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0x0000,0x0000, // u25ae\n  0x0000,0x0000,0x0000,0x1800,0x1800,0x3c00,0x3c00,0x7e00,0x7e00,0xff00,0xff00,0x0000,0x0000,0x0000, // u25b2\n  0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xff00,0xfc00,0xf000,0xc000,0x0000,0x0000,0x0000, // u25b6\n  0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xff00,0xfc00,0xf000,0xc000,0x0000,0x0000,0x0000, // u25ba\n  0x0000,0x0000,0x0000,0xff00,0xff00,0x7e00,0x7e00,0x3c00,0x3c00,0x1800,0x1800,0x0000,0x0000,0x0000, // u25bc\n  0x0000,0x0000,0x0000,0x0300,0x0f00,0x3f00,0xff00,0xff00,0x3f00,0x0f00,0x0300,0x0000,0x0000,0x0000, // u25c0\n  0x0000,0x0000,0x0000,0x0300,0x0f00,0x3f00,0xff00,0xff00,0x3f00,0x0f00,0x0300,0x0000,0x0000,0x0000, // u25c4\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x3c00,0x7e00,0xff00,0x7e00,0x3c00,0x1800,0x0000,0x0000,0x0000, // u25c6\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x3c00,0x6600,0xc300,0x6600,0x3c00,0x1800,0x0000,0x0000,0x0000, // u25ca\n  0x0000,0x0000,0x0000,0x0000,0x3c00,0x6600,0x4200,0x4200,0x6600,0x3c00,0x0000,0x0000,0x0000,0x0000, // u25cb\n  0x0000,0x0000,0x0000,0x0000,0x3c00,0x7e00,0x7e00,0x7e00,0x7e00,0x3c00,0x0000,0x0000,0x0000,0x0000, // u25cf\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xe700,0xc300,0xc300,0xe700,0xff00,0xff00,0xff00,0xff00,0xff00, // u25d8\n  0xff00,0xff00,0xff00,0xff00,0xc300,0x9900,0xbd00,0xbd00,0x9900,0xc300,0xff00,0xff00,0xff00,0xff00, // u25d9\n  0x0000,0x0000,0x7c00,0x8200,0xaa00,0x8200,0x8200,0xba00,0x9200,0x8200,0x8200,0x7c00,0x0000,0x0000, // u263a\n  0x0000,0x0000,0x7c00,0xfe00,0xd600,0xfe00,0xfe00,0xc600,0xee00,0xfe00,0xfe00,0x7c00,0x0000,0x0000, // u263b\n  0x0000,0x0000,0x0000,0x1800,0xdb00,0x7e00,0x3c00,0xe700,0x3c00,0x7e00,0xdb00,0x1800,0x0000,0x0000, // u263c\n  0x0000,0x0000,0x3c00,0x6600,0x6600,0x6600,0x6600,0x3c00,0x1800,0x7e00,0x1800,0x1800,0x0000,0x0000, // u2640\n  0x0000,0x0000,0x3e00,0x0e00,0x1a00,0x3200,0x7800,0xcc00,0xcc00,0xcc00,0xcc00,0x7800,0x0000,0x0000, // u2642\n  0x0000,0x0000,0x1800,0x1800,0x3c00,0x7e00,0xff00,0xff00,0x7e00,0x1800,0x1800,0x3c00,0x0000,0x0000, // u2660\n  0x0000,0x0000,0x1800,0x3c00,0x3c00,0x1800,0x5a00,0xff00,0xff00,0x5a00,0x1800,0x3c00,0x0000,0x0000, // u2663\n  0x0000,0x0000,0x0000,0x6c00,0xfe00,0xfe00,0xfe00,0xfe00,0x7c00,0x3800,0x1000,0x0000,0x0000,0x0000, // u2665\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x3c00,0x7e00,0xff00,0x7e00,0x3c00,0x1800,0x0000,0x0000,0x0000, // u2666\n  0x0000,0x0000,0x7e00,0x6600,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0xe000,0xc000,0x0000,0x0000, // u266a\n  0x0000,0x0000,0x7e00,0x6600,0x7e00,0x6600,0x6600,0x6600,0x6600,0x6600,0x6e00,0xec00,0xc000,0x0000, // u266b\n  0x0000,0x0000,0x0300,0x0300,0x0600,0x0600,0xcc00,0xcc00,0x7800,0x7800,0x3000,0x3000,0x0000,0x0000, // u2713\n  0x0000,0x0000,0x0700,0x0700,0x0e00,0x0e00,0xdc00,0xfc00,0x7800,0x7800,0x3000,0x3000,0x0000,0x0000, // u2714\n  0x0000,0x0000,0x0c00,0xcc00,0x7800,0x3800,0x3800,0x3c00,0x6600,0x6000,0xc000,0xc000,0x0000,0x0000, // u2717\n  0x0000,0x0000,0x0e00,0xee00,0x7c00,0x3c00,0x3c00,0x3e00,0x7700,0x7300,0xe000,0xe000,0x0000,0x0000, // u2718\n  0x0000,0x0000,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x1800,0x1800,0x0c00,0x0c00,0x0000,0x0000, // u27e8\n  0x0000,0x0000,0x3000,0x3000,0x1800,0x1800,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x0000,0x0000, // u27e9\n  0x0000,0x0000,0x3600,0x3600,0x6c00,0x6c00,0xd800,0xd800,0x6c00,0x6c00,0x3600,0x3600,0x0000,0x0000, // u27ea\n  0x0000,0x0000,0xd800,0xd800,0x6c00,0x6c00,0x3600,0x3600,0x6c00,0x6c00,0xd800,0xd800,0x0000,0x0000, // u27eb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2800\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2801\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2802\n  0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2803\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000, // u2804\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000, // u2805\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000, // u2806\n  0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000, // u2807\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2808\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2809\n  0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280a\n  0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280b\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000, // u280c\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000, // u280d\n  0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000, // u280e\n  0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000, // u280f\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2810\n  0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2811\n  0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2812\n  0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2813\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000, // u2814\n  0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000, // u2815\n  0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000, // u2816\n  0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000, // u2817\n  0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2818\n  0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2819\n  0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281a\n  0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281b\n  0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000, // u281c\n  0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000, // u281d\n  0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000, // u281e\n  0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000, // u281f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u2820\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u2821\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u2822\n  0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u2823\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000, // u2824\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000, // u2825\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000, // u2826\n  0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000, // u2827\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u2828\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u2829\n  0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u282a\n  0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u282b\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000, // u282c\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000, // u282d\n  0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000, // u282e\n  0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000, // u282f\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u2830\n  0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u2831\n  0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u2832\n  0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u2833\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000, // u2834\n  0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000, // u2835\n  0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000, // u2836\n  0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000, // u2837\n  0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u2838\n  0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u2839\n  0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u283a\n  0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u283b\n  0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000, // u283c\n  0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000, // u283d\n  0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000, // u283e\n  0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000, // u283f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2840\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2841\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2842\n  0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2843\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000, // u2844\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000, // u2845\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000, // u2846\n  0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000, // u2847\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2848\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2849\n  0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u284a\n  0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u284b\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000, // u284c\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000, // u284d\n  0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000, // u284e\n  0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000, // u284f\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2850\n  0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2851\n  0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2852\n  0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2853\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000, // u2854\n  0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000, // u2855\n  0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000, // u2856\n  0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000, // u2857\n  0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2858\n  0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2859\n  0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u285a\n  0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u285b\n  0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000, // u285c\n  0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000, // u285d\n  0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000, // u285e\n  0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000, // u285f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000, // u2860\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000, // u2861\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000, // u2862\n  0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000, // u2863\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000, // u2864\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000, // u2865\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000, // u2866\n  0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000, // u2867\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000, // u2868\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000, // u2869\n  0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000, // u286a\n  0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000, // u286b\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000, // u286c\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000, // u286d\n  0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000, // u286e\n  0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000, // u286f\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000, // u2870\n  0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000, // u2871\n  0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000, // u2872\n  0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000, // u2873\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000, // u2874\n  0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000, // u2875\n  0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000, // u2876\n  0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000, // u2877\n  0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000, // u2878\n  0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000, // u2879\n  0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000, // u287a\n  0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000, // u287b\n  0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000, // u287c\n  0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000, // u287d\n  0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000, // u287e\n  0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000, // u287f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2880\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2881\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2882\n  0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2883\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000, // u2884\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000, // u2885\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000, // u2886\n  0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000, // u2887\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2888\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2889\n  0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u288a\n  0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u288b\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000, // u288c\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000, // u288d\n  0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000, // u288e\n  0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000, // u288f\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2890\n  0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2891\n  0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2892\n  0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2893\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000, // u2894\n  0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000, // u2895\n  0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000, // u2896\n  0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000, // u2897\n  0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2898\n  0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2899\n  0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u289a\n  0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u289b\n  0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000, // u289c\n  0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000, // u289d\n  0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000, // u289e\n  0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000, // u289f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000, // u28a0\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000, // u28a1\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000, // u28a2\n  0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000, // u28a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000, // u28a4\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000, // u28a5\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000, // u28a6\n  0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000, // u28a7\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000, // u28a8\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000, // u28a9\n  0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000, // u28aa\n  0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000, // u28ab\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000, // u28ac\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000, // u28ad\n  0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000, // u28ae\n  0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000, // u28af\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000, // u28b0\n  0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000, // u28b1\n  0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000, // u28b2\n  0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000, // u28b3\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000, // u28b4\n  0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000, // u28b5\n  0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000, // u28b6\n  0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000, // u28b7\n  0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000, // u28b8\n  0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000, // u28b9\n  0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000, // u28ba\n  0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000, // u28bb\n  0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000, // u28bc\n  0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000, // u28bd\n  0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000, // u28be\n  0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000, // u28bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28c0\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28c1\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28c2\n  0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000, // u28c4\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000, // u28c5\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000, // u28c6\n  0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000, // u28c7\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28c8\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28c9\n  0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28ca\n  0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28cb\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000, // u28cc\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000, // u28cd\n  0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000, // u28ce\n  0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000, // u28cf\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28d0\n  0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28d1\n  0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28d2\n  0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28d3\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000, // u28d4\n  0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000, // u28d5\n  0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000, // u28d6\n  0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000, // u28d7\n  0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28d8\n  0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28d9\n  0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28da\n  0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28db\n  0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000, // u28dc\n  0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000, // u28dd\n  0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000, // u28de\n  0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000, // u28df\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000, // u28e0\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000, // u28e1\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000, // u28e2\n  0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000, // u28e3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000, // u28e4\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000, // u28e5\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000, // u28e6\n  0x0000,0x6000,0x6000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000, // u28e7\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000, // u28e8\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000, // u28e9\n  0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000, // u28ea\n  0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000, // u28eb\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000, // u28ec\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000, // u28ed\n  0x0000,0x0600,0x0600,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000, // u28ee\n  0x0000,0x6600,0x6600,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000, // u28ef\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000, // u28f0\n  0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000, // u28f1\n  0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000, // u28f2\n  0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000, // u28f3\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000, // u28f4\n  0x0000,0x6000,0x6000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000, // u28f5\n  0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000, // u28f6\n  0x0000,0x6000,0x6000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000, // u28f7\n  0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000, // u28f8\n  0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000, // u28f9\n  0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000, // u28fa\n  0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000, // u28fb\n  0x0000,0x0600,0x0600,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000, // u28fc\n  0x0000,0x6600,0x6600,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000, // u28fd\n  0x0000,0x0600,0x0600,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000, // u28fe\n  0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000, // u28ff\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0x0000,0x0000,0x0000,0xc600,0xc600,0x0000,0x0000, // u2e2c\n  0xc000,0xcc00,0xde00,0xff00,0xcc00,0xcc00,0xcc00,0x9800,0x3000,0x6000,0xc000,0xc000,0xc000,0xc000, // ue0a0\n  0xc000,0xc000,0xc000,0xc000,0xc000,0xfc00,0x0000,0x3300,0x3b00,0x3f00,0x3700,0x3300,0x3300,0x0000, // ue0a1\n  0x3c00,0x6600,0x6600,0x6600,0x6600,0xff00,0xff00,0xe700,0xc300,0xe700,0xff00,0xff00,0xff00,0x0000, // ue0a2\n  0x8000,0xc000,0xe000,0xf000,0xf800,0xfc00,0xfe00,0xfe00,0xfc00,0xf800,0xf000,0xe000,0xc000,0x8000, // ue0b0\n  0x8000,0xc000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0x8000, // ue0b1\n  0x0100,0x0300,0x0700,0x0f00,0x1f00,0x3f00,0x7f00,0x7f00,0x3f00,0x1f00,0x0f00,0x0700,0x0300,0x0100, // ue0b2\n  0x0100,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0100, // ue0b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x6600,0x6600,0x3c00, // uf6be\n  0x0000,0x0000,0xfe00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xfe00,0x0000,0x0000 // ufffd\n  };\n  // codepoints array\n  constexpr std::array<uint16_t, CHARCOUNT> fixedfont_codepoints = {\n  0x0000,0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,\n  0x002f,0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,\n  0x003f,0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,\n  0x004f,0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,\n  0x005f,0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,\n  0x006f,0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,\n  0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af,\n  0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf,\n  0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf,\n  0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df,\n  0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef,\n  0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff,\n  0x0100,0x0101,0x0102,0x0103,0x0104,0x0105,0x0106,0x0107,0x0108,0x0109,0x010a,0x010b,0x010c,0x010d,0x010e,0x010f,\n  0x0110,0x0111,0x0112,0x0113,0x0114,0x0115,0x0116,0x0117,0x0118,0x0119,0x011a,0x011b,0x011c,0x011d,0x011e,0x011f,\n  0x0120,0x0121,0x0122,0x0123,0x0124,0x0125,0x0126,0x0127,0x0128,0x0129,0x012a,0x012b,0x012c,0x012d,0x012e,0x012f,\n  0x0130,0x0131,0x0132,0x0133,0x0134,0x0135,0x0136,0x0137,0x0138,0x0139,0x013a,0x013b,0x013c,0x013d,0x013e,0x013f,\n  0x0140,0x0141,0x0142,0x0143,0x0144,0x0145,0x0146,0x0147,0x0148,0x0149,0x014a,0x014b,0x014c,0x014d,0x014e,0x014f,\n  0x0150,0x0151,0x0152,0x0153,0x0154,0x0155,0x0156,0x0157,0x0158,0x0159,0x015a,0x015b,0x015c,0x015d,0x015e,0x015f,\n  0x0160,0x0161,0x0162,0x0163,0x0164,0x0165,0x0166,0x0167,0x0168,0x0169,0x016a,0x016b,0x016c,0x016d,0x016e,0x016f,\n  0x0170,0x0171,0x0172,0x0173,0x0174,0x0175,0x0176,0x0177,0x0178,0x0179,0x017a,0x017b,0x017c,0x017d,0x017e,0x017f,\n  0x0186,0x018e,0x018f,0x0190,0x0192,0x019d,0x019e,0x01b5,0x01b6,0x01b7,0x01cd,0x01ce,0x01cf,0x01d0,0x01d1,0x01d2,\n  0x01d3,0x01d4,0x01e2,0x01e3,0x01e4,0x01e5,0x01e6,0x01e7,0x01e8,0x01e9,0x01ea,0x01eb,0x01ec,0x01ed,0x01ee,0x01ef,\n  0x01f0,0x01f4,0x01f5,0x01fc,0x01fd,0x01fe,0x01ff,0x0218,0x0219,0x021a,0x021b,0x0232,0x0233,0x0237,0x0254,0x0258,\n  0x0259,0x025b,0x0272,0x0292,0x02bb,0x02bc,0x02bd,0x02c6,0x02c7,0x02d8,0x02d9,0x02db,0x02dc,0x02dd,0x0300,0x0301,\n  0x0302,0x0303,0x0304,0x0305,0x0306,0x0307,0x0308,0x030a,0x030b,0x030c,0x0329,0x0384,0x0385,0x0386,0x0387,0x0388,\n  0x0389,0x038a,0x038c,0x038e,0x038f,0x0390,0x0391,0x0392,0x0393,0x0394,0x0395,0x0396,0x0397,0x0398,0x0399,0x039a,\n  0x039b,0x039c,0x039d,0x039e,0x039f,0x03a0,0x03a1,0x03a3,0x03a4,0x03a5,0x03a6,0x03a7,0x03a8,0x03a9,0x03aa,0x03ab,\n  0x03ac,0x03ad,0x03ae,0x03af,0x03b0,0x03b1,0x03b2,0x03b3,0x03b4,0x03b5,0x03b6,0x03b7,0x03b8,0x03b9,0x03ba,0x03bb,\n  0x03bc,0x03bd,0x03be,0x03bf,0x03c0,0x03c1,0x03c2,0x03c3,0x03c4,0x03c5,0x03c6,0x03c7,0x03c8,0x03c9,0x03ca,0x03cb,\n  0x03cc,0x03cd,0x03ce,0x03d1,0x03d5,0x03f0,0x03f1,0x03f2,0x03f3,0x03f4,0x03f5,0x03f6,0x0400,0x0401,0x0402,0x0403,\n  0x0404,0x0405,0x0406,0x0407,0x0408,0x0409,0x040a,0x040b,0x040c,0x040d,0x040e,0x040f,0x0410,0x0411,0x0412,0x0413,\n  0x0414,0x0415,0x0416,0x0417,0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e,0x041f,0x0420,0x0421,0x0422,0x0423,\n  0x0424,0x0425,0x0426,0x0427,0x0428,0x0429,0x042a,0x042b,0x042c,0x042d,0x042e,0x042f,0x0430,0x0431,0x0432,0x0433,\n  0x0434,0x0435,0x0436,0x0437,0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e,0x043f,0x0440,0x0441,0x0442,0x0443,\n  0x0444,0x0445,0x0446,0x0447,0x0448,0x0449,0x044a,0x044b,0x044c,0x044d,0x044e,0x044f,0x0450,0x0451,0x0452,0x0453,\n  0x0454,0x0455,0x0456,0x0457,0x0458,0x0459,0x045a,0x045b,0x045c,0x045d,0x045e,0x045f,0x0462,0x0463,0x046a,0x046b,\n  0x0490,0x0491,0x0492,0x0493,0x0494,0x0495,0x0496,0x0497,0x0498,0x0499,0x049a,0x049b,0x049c,0x049d,0x04a0,0x04a1,\n  0x04a2,0x04a3,0x04a4,0x04a5,0x04aa,0x04ab,0x04ae,0x04af,0x04b0,0x04b1,0x04b2,0x04b3,0x04b6,0x04b7,0x04b8,0x04b9,\n  0x04ba,0x04bb,0x04c0,0x04c1,0x04c2,0x04cf,0x04d0,0x04d1,0x04d2,0x04d3,0x04d4,0x04d5,0x04d6,0x04d7,0x04d8,0x04d9,\n  0x04da,0x04db,0x04dc,0x04dd,0x04de,0x04df,0x04e2,0x04e3,0x04e4,0x04e5,0x04e6,0x04e7,0x04e8,0x04e9,0x04ea,0x04eb,\n  0x04ec,0x04ed,0x04ee,0x04ef,0x04f0,0x04f1,0x04f2,0x04f3,0x04f4,0x04f5,0x04f8,0x04f9,0x05d0,0x05d1,0x05d2,0x05d3,\n  0x05d4,0x05d5,0x05d6,0x05d7,0x05d8,0x05d9,0x05da,0x05db,0x05dc,0x05dd,0x05de,0x05df,0x05e0,0x05e1,0x05e2,0x05e3,\n  0x05e4,0x05e5,0x05e6,0x05e7,0x05e8,0x05e9,0x05ea,0x1e0c,0x1e0d,0x1e34,0x1e35,0x1e36,0x1e37,0x1e40,0x1e41,0x1e42,\n  0x1e43,0x1e44,0x1e45,0x1e46,0x1e47,0x1e6c,0x1e6d,0x1eb8,0x1eb9,0x1ebc,0x1ebd,0x1eca,0x1ecb,0x1ecc,0x1ecd,0x1ee4,\n  0x1ee5,0x1ef8,0x1ef9,0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007,0x2008,0x2009,0x200a,0x200b,0x200c,\n  0x200d,0x200e,0x200f,0x2010,0x2011,0x2012,0x2013,0x2014,0x2015,0x2016,0x2017,0x2018,0x2019,0x201a,0x201b,0x201c,\n  0x201d,0x201e,0x201f,0x2020,0x2021,0x2022,0x2026,0x2030,0x2032,0x2033,0x2039,0x203a,0x203c,0x203e,0x2070,0x2071,\n  0x2074,0x2075,0x2076,0x2077,0x2078,0x2079,0x207a,0x207b,0x207c,0x207d,0x207e,0x207f,0x2080,0x2081,0x2082,0x2083,\n  0x2084,0x2085,0x2086,0x2087,0x2088,0x2089,0x208a,0x208b,0x208c,0x208d,0x208e,0x2090,0x2091,0x2092,0x2093,0x2094,\n  0x2095,0x2096,0x2097,0x2098,0x209a,0x20a7,0x20aa,0x20ac,0x20ae,0x2102,0x210e,0x210f,0x2115,0x2116,0x211a,0x211d,\n  0x2122,0x2124,0x2126,0x2135,0x2190,0x2191,0x2192,0x2193,0x2194,0x2195,0x21a4,0x21a6,0x21a8,0x21b5,0x21bb,0x21cb,\n  0x21cc,0x21d0,0x21d1,0x21d2,0x21d3,0x21d4,0x21d5,0x2200,0x2203,0x2204,0x2205,0x2206,0x2207,0x2208,0x2209,0x220a,\n  0x220b,0x220c,0x220d,0x2212,0x2213,0x2214,0x2215,0x2216,0x2219,0x221a,0x221e,0x221f,0x2225,0x2227,0x2228,0x2229,\n  0x222a,0x2248,0x2260,0x2261,0x2264,0x2265,0x226a,0x226b,0x2282,0x2283,0x2286,0x2287,0x22a5,0x22c2,0x22c3,0x2300,\n  0x2302,0x2308,0x2309,0x230a,0x230b,0x2310,0x2319,0x2320,0x2321,0x239b,0x239c,0x239d,0x239e,0x239f,0x23a0,0x23a1,\n  0x23a2,0x23a3,0x23a4,0x23a5,0x23a6,0x23a7,0x23a8,0x23a9,0x23ab,0x23ac,0x23ad,0x23ae,0x23af,0x23ba,0x23bb,0x23bc,\n  0x23bd,0x23d0,0x2409,0x240a,0x240b,0x240c,0x240d,0x2424,0x2500,0x2501,0x2502,0x2503,0x2508,0x2509,0x250a,0x250b,\n  0x250c,0x250d,0x250e,0x250f,0x2510,0x2511,0x2512,0x2513,0x2514,0x2515,0x2516,0x2517,0x2518,0x2519,0x251a,0x251b,\n  0x251c,0x251d,0x251e,0x251f,0x2520,0x2521,0x2522,0x2523,0x2524,0x2525,0x2526,0x2527,0x2528,0x2529,0x252a,0x252b,\n  0x252c,0x252d,0x252e,0x252f,0x2530,0x2531,0x2532,0x2533,0x2534,0x2535,0x2536,0x2537,0x2538,0x2539,0x253a,0x253b,\n  0x253c,0x253d,0x253e,0x253f,0x2540,0x2541,0x2542,0x2543,0x2544,0x2545,0x2546,0x2547,0x2548,0x2549,0x254a,0x254b,\n  0x2550,0x2551,0x2552,0x2553,0x2554,0x2555,0x2556,0x2557,0x2558,0x2559,0x255a,0x255b,0x255c,0x255d,0x255e,0x255f,\n  0x2560,0x2561,0x2562,0x2563,0x2564,0x2565,0x2566,0x2567,0x2568,0x2569,0x256a,0x256b,0x256c,0x256d,0x256e,0x256f,\n  0x2570,0x2571,0x2572,0x2573,0x2574,0x2575,0x2576,0x2577,0x2578,0x2579,0x257a,0x257b,0x257c,0x257d,0x257e,0x257f,\n  0x2580,0x2581,0x2582,0x2583,0x2584,0x2585,0x2586,0x2587,0x2588,0x2589,0x258a,0x258b,0x258c,0x258d,0x258e,0x258f,\n  0x2590,0x2591,0x2592,0x2593,0x2596,0x2597,0x2598,0x2599,0x259a,0x259b,0x259c,0x259d,0x259e,0x259f,0x25a0,0x25ac,\n  0x25ae,0x25b2,0x25b6,0x25ba,0x25bc,0x25c0,0x25c4,0x25c6,0x25ca,0x25cb,0x25cf,0x25d8,0x25d9,0x263a,0x263b,0x263c,\n  0x2640,0x2642,0x2660,0x2663,0x2665,0x2666,0x266a,0x266b,0x2713,0x2714,0x2717,0x2718,0x27e8,0x27e9,0x27ea,0x27eb,\n  0x2800,0x2801,0x2802,0x2803,0x2804,0x2805,0x2806,0x2807,0x2808,0x2809,0x280a,0x280b,0x280c,0x280d,0x280e,0x280f,\n  0x2810,0x2811,0x2812,0x2813,0x2814,0x2815,0x2816,0x2817,0x2818,0x2819,0x281a,0x281b,0x281c,0x281d,0x281e,0x281f,\n  0x2820,0x2821,0x2822,0x2823,0x2824,0x2825,0x2826,0x2827,0x2828,0x2829,0x282a,0x282b,0x282c,0x282d,0x282e,0x282f,\n  0x2830,0x2831,0x2832,0x2833,0x2834,0x2835,0x2836,0x2837,0x2838,0x2839,0x283a,0x283b,0x283c,0x283d,0x283e,0x283f,\n  0x2840,0x2841,0x2842,0x2843,0x2844,0x2845,0x2846,0x2847,0x2848,0x2849,0x284a,0x284b,0x284c,0x284d,0x284e,0x284f,\n  0x2850,0x2851,0x2852,0x2853,0x2854,0x2855,0x2856,0x2857,0x2858,0x2859,0x285a,0x285b,0x285c,0x285d,0x285e,0x285f,\n  0x2860,0x2861,0x2862,0x2863,0x2864,0x2865,0x2866,0x2867,0x2868,0x2869,0x286a,0x286b,0x286c,0x286d,0x286e,0x286f,\n  0x2870,0x2871,0x2872,0x2873,0x2874,0x2875,0x2876,0x2877,0x2878,0x2879,0x287a,0x287b,0x287c,0x287d,0x287e,0x287f,\n  0x2880,0x2881,0x2882,0x2883,0x2884,0x2885,0x2886,0x2887,0x2888,0x2889,0x288a,0x288b,0x288c,0x288d,0x288e,0x288f,\n  0x2890,0x2891,0x2892,0x2893,0x2894,0x2895,0x2896,0x2897,0x2898,0x2899,0x289a,0x289b,0x289c,0x289d,0x289e,0x289f,\n  0x28a0,0x28a1,0x28a2,0x28a3,0x28a4,0x28a5,0x28a6,0x28a7,0x28a8,0x28a9,0x28aa,0x28ab,0x28ac,0x28ad,0x28ae,0x28af,\n  0x28b0,0x28b1,0x28b2,0x28b3,0x28b4,0x28b5,0x28b6,0x28b7,0x28b8,0x28b9,0x28ba,0x28bb,0x28bc,0x28bd,0x28be,0x28bf,\n  0x28c0,0x28c1,0x28c2,0x28c3,0x28c4,0x28c5,0x28c6,0x28c7,0x28c8,0x28c9,0x28ca,0x28cb,0x28cc,0x28cd,0x28ce,0x28cf,\n  0x28d0,0x28d1,0x28d2,0x28d3,0x28d4,0x28d5,0x28d6,0x28d7,0x28d8,0x28d9,0x28da,0x28db,0x28dc,0x28dd,0x28de,0x28df,\n  0x28e0,0x28e1,0x28e2,0x28e3,0x28e4,0x28e5,0x28e6,0x28e7,0x28e8,0x28e9,0x28ea,0x28eb,0x28ec,0x28ed,0x28ee,0x28ef,\n  0x28f0,0x28f1,0x28f2,0x28f3,0x28f4,0x28f5,0x28f6,0x28f7,0x28f8,0x28f9,0x28fa,0x28fb,0x28fc,0x28fd,0x28fe,0x28ff,\n  0x2e2c,0xe0a0,0xe0a1,0xe0a2,0xe0b0,0xe0b1,0xe0b2,0xe0b3,0xf6be,0xfffd };\n} // namespace\n// -- end of autogenerated text ---\n\nnamespace fixed_font_16n {\n  // -- start of autogenerated text ---\n  // definition section for font: ter-u16n.bdf\n  constexpr int CHARCOUNT = 1354;\n  constexpr int WIDTH = 8;\n  constexpr int HEIGHT = 16;\n  constexpr int OFFSET_X = 0;\n  constexpr int OFFSET_Y = 0;\n  constexpr FixedFont_info_t fixedfont_info = {\n    \"Terminus\", // font name\n    \"ter-u16n.bdf\", // font name internal\n    CHARCOUNT, // num of chars\n    WIDTH, HEIGHT, OFFSET_X, OFFSET_Y,\n    false // bold\n  };\n  // font bitmap definitions\n  constexpr std::array<uint16_t, CHARCOUNT * HEIGHT> fixedfont_bitmap = {\n  0x0000,0x0000,0x6600,0x4200,0x0000,0x4200,0x4200,0x4200,0x0000,0x4200,0x4200,0x6600,0x0000,0x0000,0x0000,0x0000, // u0000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0020\n  0x0000,0x0000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u0021\n  0x0000,0x2400,0x2400,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0022\n  0x0000,0x0000,0x2400,0x2400,0x2400,0x7e00,0x2400,0x2400,0x7e00,0x2400,0x2400,0x2400,0x0000,0x0000,0x0000,0x0000, // u0023\n  0x0000,0x1000,0x1000,0x7c00,0x9200,0x9000,0x9000,0x7c00,0x1200,0x1200,0x9200,0x7c00,0x1000,0x1000,0x0000,0x0000, // u0024\n  0x0000,0x0000,0x6400,0x9400,0x6800,0x0800,0x1000,0x1000,0x2000,0x2c00,0x5200,0x4c00,0x0000,0x0000,0x0000,0x0000, // u0025\n  0x0000,0x0000,0x1800,0x2400,0x2400,0x1800,0x3000,0x4a00,0x4400,0x4400,0x4400,0x3a00,0x0000,0x0000,0x0000,0x0000, // u0026\n  0x0000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0027\n  0x0000,0x0000,0x0800,0x1000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x1000,0x0800,0x0000,0x0000,0x0000,0x0000, // u0028\n  0x0000,0x0000,0x2000,0x1000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1000,0x2000,0x0000,0x0000,0x0000,0x0000, // u0029\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2400,0x1800,0x7e00,0x1800,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x2000,0x0000,0x0000,0x0000, // u002c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u002e\n  0x0000,0x0000,0x0400,0x0400,0x0800,0x0800,0x1000,0x1000,0x2000,0x2000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u002f\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4600,0x4a00,0x5200,0x6200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0030\n  0x0000,0x0000,0x0800,0x1800,0x2800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x3e00,0x0000,0x0000,0x0000,0x0000, // u0031\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0032\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x0200,0x1c00,0x0200,0x0200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0033\n  0x0000,0x0000,0x0200,0x0600,0x0a00,0x1200,0x2200,0x4200,0x7e00,0x0200,0x0200,0x0200,0x0000,0x0000,0x0000,0x0000, // u0034\n  0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7c00,0x0200,0x0200,0x0200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0035\n  0x0000,0x0000,0x1c00,0x2000,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0036\n  0x0000,0x0000,0x7e00,0x0200,0x0200,0x0400,0x0400,0x0800,0x0800,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u0037\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x3c00,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0038\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x0400,0x3800,0x0000,0x0000,0x0000,0x0000, // u0039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x0000,0x0000,0x0000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u003a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x0000,0x0000,0x0000,0x1000,0x1000,0x2000,0x0000,0x0000,0x0000, // u003b\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x1000,0x2000,0x4000,0x2000,0x1000,0x0800,0x0400,0x0000,0x0000,0x0000,0x0000, // u003c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0000,0x0000,0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003d\n  0x0000,0x0000,0x0000,0x4000,0x2000,0x1000,0x0800,0x0400,0x0800,0x1000,0x2000,0x4000,0x0000,0x0000,0x0000,0x0000, // u003e\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x0400,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000, // u003f\n  0x0000,0x0000,0x7c00,0x8200,0x9e00,0xa200,0xa200,0xa200,0xa600,0x9a00,0x8000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0040\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u0041\n  0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x7c00,0x4200,0x4200,0x4200,0x4200,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0042\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4000,0x4000,0x4000,0x4000,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0043\n  0x0000,0x0000,0x7800,0x4400,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4400,0x7800,0x0000,0x0000,0x0000,0x0000, // u0044\n  0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0045\n  0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u0046\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4000,0x4000,0x4e00,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0047\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u0048\n  0x0000,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u0049\n  0x0000,0x0000,0x0e00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x4400,0x4400,0x3800,0x0000,0x0000,0x0000,0x0000, // u004a\n  0x0000,0x0000,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x0000,0x0000,0x0000,0x0000, // u004b\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u004c\n  0x0000,0x0000,0x8200,0xc600,0xaa00,0x9200,0x9200,0x8200,0x8200,0x8200,0x8200,0x8200,0x0000,0x0000,0x0000,0x0000, // u004d\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x6200,0x5200,0x4a00,0x4600,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u004e\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u004f\n  0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x7c00,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u0050\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4a00,0x3c00,0x0200,0x0000,0x0000,0x0000, // u0051\n  0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x7c00,0x5000,0x4800,0x4400,0x4200,0x0000,0x0000,0x0000,0x0000, // u0052\n  0x0000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x3c00,0x0200,0x0200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0053\n  0x0000,0x0000,0xfe00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u0054\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0055\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x2400,0x2400,0x2400,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u0056\n  0x0000,0x0000,0x8200,0x8200,0x8200,0x8200,0x8200,0x9200,0x9200,0xaa00,0xc600,0x8200,0x0000,0x0000,0x0000,0x0000, // u0057\n  0x0000,0x0000,0x4200,0x4200,0x2400,0x2400,0x1800,0x1800,0x2400,0x2400,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u0058\n  0x0000,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u0059\n  0x0000,0x0000,0x7e00,0x0200,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u005a\n  0x0000,0x0000,0x3800,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x3800,0x0000,0x0000,0x0000,0x0000, // u005b\n  0x0000,0x0000,0x4000,0x4000,0x2000,0x2000,0x1000,0x1000,0x0800,0x0800,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000, // u005c\n  0x0000,0x0000,0x3800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x3800,0x0000,0x0000,0x0000,0x0000, // u005d\n  0x0000,0x1000,0x2800,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0000,0x0000, // u005f\n  0x1000,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0060\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u0061\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0062\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4000,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0063\n  0x0000,0x0000,0x0200,0x0200,0x0200,0x3e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u0064\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0065\n  0x0000,0x0000,0x0e00,0x1000,0x1000,0x7c00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u0066\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x3c00,0x0000, // u0067\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u0068\n  0x0000,0x0000,0x1000,0x1000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u0069\n  0x0000,0x0000,0x0400,0x0400,0x0000,0x0c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x4400,0x4400,0x3800,0x0000, // u006a\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x0000,0x0000,0x0000,0x0000, // u006b\n  0x0000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u006c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x0000,0x0000,0x0000,0x0000, // u006d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u006e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u006f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x7c00,0x4000,0x4000,0x4000,0x0000, // u0070\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x0200,0x0000, // u0071\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x5e00,0x6000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u0072\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4000,0x4000,0x3c00,0x0200,0x0200,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0073\n  0x0000,0x0000,0x1000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x1000,0x1000,0x1000,0x0e00,0x0000,0x0000,0x0000,0x0000, // u0074\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u0075\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x2400,0x2400,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u0076\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x8200,0x8200,0x9200,0x9200,0x9200,0x9200,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0077\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x2400,0x1800,0x2400,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u0078\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x3c00,0x0000, // u0079\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0400,0x0800,0x1000,0x2000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u007a\n  0x0000,0x0000,0x0c00,0x1000,0x1000,0x1000,0x2000,0x1000,0x1000,0x1000,0x1000,0x0c00,0x0000,0x0000,0x0000,0x0000, // u007b\n  0x0000,0x0000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u007c\n  0x0000,0x0000,0x3000,0x0800,0x0800,0x0800,0x0400,0x0800,0x0800,0x0800,0x0800,0x3000,0x0000,0x0000,0x0000,0x0000, // u007d\n  0x0000,0x6200,0x9200,0x8c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a0\n  0x0000,0x0000,0x1000,0x1000,0x0000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u00a1\n  0x0000,0x0000,0x0000,0x1000,0x1000,0x7c00,0x9200,0x9000,0x9000,0x9000,0x9200,0x7c00,0x1000,0x1000,0x0000,0x0000, // u00a2\n  0x0000,0x0000,0x1800,0x2400,0x2000,0x2000,0x7800,0x2000,0x2000,0x2000,0x2200,0x7e00,0x0000,0x0000,0x0000,0x0000, // u00a3\n  0x0000,0x0000,0x0000,0x0000,0x4400,0x3800,0x4400,0x4400,0x4400,0x3800,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a4\n  0x0000,0x0000,0x8200,0x8200,0x4400,0x2800,0x1000,0x7c00,0x1000,0x7c00,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u00a5\n  0x0000,0x0000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u00a6\n  0x0000,0x3800,0x4400,0x4000,0x3000,0x4800,0x4400,0x4400,0x2400,0x1800,0x0400,0x4400,0x3800,0x0000,0x0000,0x0000, // u00a7\n  0x2400,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a8\n  0x0000,0x0000,0x0000,0x7e00,0x8100,0x9900,0xa500,0xa100,0xa500,0x9900,0x8100,0x7e00,0x0000,0x0000,0x0000,0x0000, // u00a9\n  0x0000,0x3800,0x0400,0x3c00,0x4400,0x3c00,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1200,0x2400,0x4800,0x9000,0x4800,0x2400,0x1200,0x0000,0x0000,0x0000,0x0000, // u00ab\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0200,0x0200,0x0200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ac\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ad\n  0x0000,0x0000,0x0000,0x7e00,0x8100,0xb900,0xa500,0xb900,0xa900,0xa500,0x8100,0x7e00,0x0000,0x0000,0x0000,0x0000, // u00ae\n  0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00af\n  0x0000,0x1800,0x2400,0x2400,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000, // u00b1\n  0x0000,0x1800,0x2400,0x0400,0x0800,0x1000,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b2\n  0x0000,0x3800,0x0400,0x1800,0x0400,0x0400,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b3\n  0x0800,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4600,0x7a00,0x4000,0x4000,0x4000,0x0000, // u00b5\n  0x0000,0x0000,0x7e00,0x9200,0x9200,0x9200,0x9200,0x7200,0x1200,0x1200,0x1200,0x1200,0x0000,0x0000,0x0000,0x0000, // u00b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x2000,0x0000, // u00b8\n  0x0000,0x1000,0x3000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b9\n  0x0000,0x3800,0x4400,0x4400,0x4400,0x3800,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x9000,0x4800,0x2400,0x1200,0x2400,0x4800,0x9000,0x0000,0x0000,0x0000,0x0000, // u00bb\n  0x0000,0x2000,0x6000,0x2000,0x2200,0x2400,0x0800,0x1000,0x2200,0x4600,0x8a00,0x1e00,0x0200,0x0200,0x0000,0x0000, // u00bc\n  0x0000,0x2000,0x6000,0x2000,0x2200,0x2400,0x0800,0x1000,0x2000,0x4c00,0x9200,0x0400,0x0800,0x1e00,0x0000,0x0000, // u00bd\n  0x0000,0xe000,0x1000,0x6000,0x1200,0xe400,0x0800,0x1000,0x2200,0x4600,0x8a00,0x1e00,0x0200,0x0200,0x0000,0x0000, // u00be\n  0x0000,0x0000,0x1000,0x1000,0x0000,0x1000,0x1000,0x2000,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00bf\n  0x1000,0x0800,0x0000,0x3c00,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u00c0\n  0x0800,0x1000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u00c1\n  0x1800,0x2400,0x0000,0x3c00,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u00c2\n  0x3200,0x4c00,0x0000,0x3c00,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u00c3\n  0x2400,0x2400,0x0000,0x3c00,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u00c4\n  0x1800,0x2400,0x1800,0x3c00,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u00c5\n  0x0000,0x0000,0x7e00,0x9000,0x9000,0x9000,0xfc00,0x9000,0x9000,0x9000,0x9000,0x9e00,0x0000,0x0000,0x0000,0x0000, // u00c6\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4000,0x4000,0x4000,0x4000,0x4200,0x4200,0x3c00,0x1000,0x1000,0x2000,0x0000, // u00c7\n  0x1000,0x0800,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u00c8\n  0x0800,0x1000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u00c9\n  0x1800,0x2400,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u00ca\n  0x2400,0x2400,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u00cb\n  0x2000,0x1000,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u00cc\n  0x0800,0x1000,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u00cd\n  0x1800,0x2400,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u00ce\n  0x4400,0x4400,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u00cf\n  0x0000,0x0000,0x7800,0x4400,0x4200,0x4200,0xf200,0x4200,0x4200,0x4200,0x4400,0x7800,0x0000,0x0000,0x0000,0x0000, // u00d0\n  0x3200,0x4c00,0x0000,0x4200,0x4200,0x6200,0x5200,0x4a00,0x4600,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u00d1\n  0x1000,0x0800,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00d2\n  0x0800,0x1000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00d3\n  0x1800,0x2400,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00d4\n  0x3200,0x4c00,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00d5\n  0x2400,0x2400,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00d6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x2400,0x1800,0x1800,0x2400,0x4200,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d7\n  0x0000,0x0000,0x3c00,0x4300,0x4200,0x4600,0x4a00,0x5200,0x6200,0x4200,0xc200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00d8\n  0x1000,0x0800,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00d9\n  0x0800,0x1000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00da\n  0x1800,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00db\n  0x2400,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00dc\n  0x0800,0x1000,0x8200,0x8200,0x4400,0x4400,0x2800,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u00dd\n  0x0000,0x0000,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x7c00,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u00de\n  0x0000,0x0000,0x3800,0x4400,0x4400,0x4800,0x7c00,0x4200,0x4200,0x4200,0x6200,0x5c00,0x0000,0x0000,0x0000,0x0000, // u00df\n  0x0000,0x0000,0x1000,0x0800,0x0000,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u00e0\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u00e1\n  0x0000,0x0000,0x1800,0x2400,0x0000,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u00e2\n  0x0000,0x0000,0x3200,0x4c00,0x0000,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u00e3\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u00e4\n  0x0000,0x0000,0x1800,0x2400,0x1800,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u00e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6c00,0x1200,0x7200,0x9e00,0x9000,0x9000,0x6c00,0x0000,0x0000,0x0000,0x0000, // u00e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4000,0x4200,0x3c00,0x1000,0x1000,0x2000,0x0000, // u00e7\n  0x0000,0x0000,0x1000,0x0800,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00e8\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00e9\n  0x0000,0x0000,0x1800,0x2400,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00ea\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00eb\n  0x0000,0x0000,0x2000,0x1000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u00ec\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u00ed\n  0x0000,0x0000,0x3000,0x4800,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u00ee\n  0x0000,0x0000,0x4800,0x4800,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u00ef\n  0x0000,0x0000,0x2800,0x1000,0x2800,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00f0\n  0x0000,0x0000,0x3200,0x4c00,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u00f1\n  0x0000,0x0000,0x1000,0x0800,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00f2\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00f3\n  0x0000,0x0000,0x1800,0x2400,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00f4\n  0x0000,0x0000,0x3200,0x4c00,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00f5\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00f6\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x0000,0x7c00,0x0000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f7\n  0x0000,0x0000,0x0000,0x0000,0x0200,0x3c00,0x4600,0x4a00,0x5200,0x6200,0x4200,0xbc00,0x0000,0x0000,0x0000,0x0000, // u00f8\n  0x0000,0x0000,0x1000,0x0800,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u00f9\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u00fa\n  0x0000,0x0000,0x1800,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u00fb\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u00fc\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x3c00,0x0000, // u00fd\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x7c00,0x4000,0x4000,0x4000,0x0000, // u00fe\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x3c00,0x0000, // u00ff\n  0x3c00,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u0100\n  0x0000,0x0000,0x0000,0x3c00,0x0000,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u0101\n  0x2400,0x1800,0x0000,0x3c00,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u0102\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u0103\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0200,0x0400,0x0300,0x0000, // u0104\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0400,0x0300,0x0000, // u0105\n  0x0800,0x1000,0x0000,0x3c00,0x4200,0x4200,0x4000,0x4000,0x4000,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0106\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4000,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0107\n  0x1800,0x2400,0x0000,0x3c00,0x4200,0x4200,0x4000,0x4000,0x4000,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0108\n  0x0000,0x0000,0x1800,0x2400,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4000,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0109\n  0x1000,0x1000,0x0000,0x3c00,0x4200,0x4200,0x4000,0x4000,0x4000,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u010a\n  0x0000,0x0000,0x1000,0x1000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4000,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u010b\n  0x2400,0x1800,0x0000,0x3c00,0x4200,0x4200,0x4000,0x4000,0x4000,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u010c\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4000,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u010d\n  0x2400,0x1800,0x0000,0x7800,0x4400,0x4200,0x4200,0x4200,0x4200,0x4200,0x4400,0x7800,0x0000,0x0000,0x0000,0x0000, // u010e\n  0x2400,0x1800,0x0200,0x0200,0x0200,0x3e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u010f\n  0x0000,0x0000,0x7800,0x4400,0x4200,0x4200,0xf200,0x4200,0x4200,0x4200,0x4400,0x7800,0x0000,0x0000,0x0000,0x0000, // u0110\n  0x0000,0x0000,0x0200,0x0f00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u0111\n  0x3c00,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0112\n  0x0000,0x0000,0x0000,0x3c00,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0113\n  0x2400,0x1800,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0114\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0115\n  0x1000,0x1000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0116\n  0x0000,0x0000,0x1000,0x1000,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0117\n  0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0200,0x0400,0x0300,0x0000, // u0118\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0800,0x1000,0x0c00,0x0000, // u0119\n  0x2400,0x1800,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u011a\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000,0x0000,0x0000, // u011b\n  0x1800,0x2400,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4e00,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u011c\n  0x0000,0x0000,0x1800,0x2400,0x0000,0x3e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x3c00,0x0000, // u011d\n  0x2400,0x1800,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4e00,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u011e\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x3e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x3c00,0x0000, // u011f\n  0x1000,0x1000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4e00,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0120\n  0x0000,0x0000,0x0800,0x0800,0x0000,0x3e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x3c00,0x0000, // u0121\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4000,0x4000,0x4e00,0x4200,0x4200,0x4200,0x3c00,0x0000,0x1000,0x1000,0x2000, // u0122\n  0x0000,0x0400,0x0800,0x0800,0x0000,0x3e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x3c00,0x0000, // u0123\n  0x1800,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u0124\n  0x0c00,0x1200,0x4000,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u0125\n  0x0000,0x0000,0x4200,0xff00,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u0126\n  0x0000,0x0000,0x4000,0xf000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u0127\n  0x3200,0x4c00,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u0128\n  0x0000,0x0000,0x3400,0x5800,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u0129\n  0x7c00,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u012a\n  0x0000,0x0000,0x0000,0x7800,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u012b\n  0x2400,0x1800,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u012c\n  0x0000,0x0000,0x4800,0x3000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u012d\n  0x0000,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x1000,0x2000,0x1800,0x0000, // u012e\n  0x0000,0x0000,0x1000,0x1000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x1000,0x2000,0x1800,0x0000, // u012f\n  0x1000,0x1000,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u0130\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u0131\n  0x0000,0x0000,0xe700,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x5200,0x5200,0xec00,0x0000,0x0000,0x0000,0x0000, // u0132\n  0x0000,0x0000,0x4200,0x4200,0x0000,0xc600,0x4200,0x4200,0x4200,0x4200,0x4200,0xe200,0x1200,0x1200,0x0c00,0x0000, // u0133\n  0x0c00,0x1200,0x0000,0x0e00,0x0400,0x0400,0x0400,0x0400,0x0400,0x4400,0x4400,0x3800,0x0000,0x0000,0x0000,0x0000, // u0134\n  0x0000,0x0000,0x0c00,0x1200,0x0000,0x0c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x4400,0x4400,0x3800,0x0000, // u0135\n  0x0000,0x0000,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x0000,0x1000,0x1000,0x2000, // u0136\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x0000,0x1000,0x1000,0x2000, // u0137\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x0000,0x0000,0x0000,0x0000, // u0138\n  0x2000,0x4000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0139\n  0x0800,0x1000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u013a\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x1000,0x1000,0x2000, // u013b\n  0x0000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x1000,0x1000,0x2000, // u013c\n  0x2400,0x1800,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u013d\n  0x4800,0x3000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u013e\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4400,0x4400,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u013f\n  0x0000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1100,0x1100,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u0140\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x6000,0xc000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0141\n  0x0000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1800,0x3000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u0142\n  0x0800,0x1000,0x4200,0x4200,0x4200,0x6200,0x5200,0x4a00,0x4600,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u0143\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u0144\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x6200,0x5200,0x4a00,0x4600,0x4200,0x4200,0x4200,0x0000,0x1000,0x1000,0x2000, // u0145\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x1000,0x1000,0x2000, // u0146\n  0x2400,0x1800,0x4200,0x4200,0x4200,0x6200,0x5200,0x4a00,0x4600,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u0147\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u0148\n  0x0000,0x4000,0x4000,0x8000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u0149\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x6200,0x5200,0x4a00,0x4600,0x4200,0x4200,0x4200,0x0200,0x0200,0x0c00,0x0000, // u014a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0200,0x0200,0x0c00,0x0000, // u014b\n  0x3c00,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u014c\n  0x0000,0x0000,0x0000,0x3c00,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u014d\n  0x2400,0x1800,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u014e\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u014f\n  0x1200,0x2400,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0150\n  0x0000,0x0000,0x1200,0x2400,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0151\n  0x0000,0x0000,0x7e00,0x9000,0x9000,0x9000,0x9c00,0x9000,0x9000,0x9000,0x9000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0152\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x9200,0x9200,0x9e00,0x9000,0x9000,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0153\n  0x0800,0x1000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x7c00,0x5000,0x4800,0x4400,0x4200,0x0000,0x0000,0x0000,0x0000, // u0154\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x5e00,0x6000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u0155\n  0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x7c00,0x5000,0x4800,0x4400,0x4200,0x0000,0x1000,0x1000,0x2000, // u0156\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x5e00,0x6000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,0x4000,0x4000,0x8000, // u0157\n  0x2400,0x1800,0x0000,0x7c00,0x4200,0x4200,0x4200,0x7c00,0x5000,0x4800,0x4400,0x4200,0x0000,0x0000,0x0000,0x0000, // u0158\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x5e00,0x6000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u0159\n  0x0800,0x1000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x3c00,0x0200,0x0200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u015a\n  0x0000,0x0000,0x0400,0x0800,0x0000,0x3e00,0x4000,0x4000,0x3c00,0x0200,0x0200,0x7c00,0x0000,0x0000,0x0000,0x0000, // u015b\n  0x1800,0x2400,0x0000,0x3c00,0x4200,0x4000,0x4000,0x3c00,0x0200,0x0200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u015c\n  0x0000,0x0000,0x1800,0x2400,0x0000,0x3e00,0x4000,0x4000,0x3c00,0x0200,0x0200,0x7c00,0x0000,0x0000,0x0000,0x0000, // u015d\n  0x0000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x3c00,0x0200,0x0200,0x4200,0x4200,0x3c00,0x1000,0x1000,0x2000,0x0000, // u015e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4000,0x4000,0x3c00,0x0200,0x0200,0x7c00,0x1000,0x1000,0x2000,0x0000, // u015f\n  0x2400,0x1800,0x0000,0x3c00,0x4200,0x4000,0x4000,0x3c00,0x0200,0x0200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0160\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x3e00,0x4000,0x4000,0x3c00,0x0200,0x0200,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0161\n  0x0000,0x0000,0xfe00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0800,0x0800,0x1000,0x0000, // u0162\n  0x0000,0x0000,0x1000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x1000,0x1000,0x1000,0x0e00,0x0400,0x0400,0x0800,0x0000, // u0163\n  0x2400,0x1800,0x0000,0xfe00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u0164\n  0x2400,0x1800,0x0000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x1000,0x1000,0x1000,0x0e00,0x0000,0x0000,0x0000,0x0000, // u0165\n  0x0000,0x0000,0xfe00,0x1000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u0166\n  0x0000,0x0000,0x1000,0x1000,0x1000,0x7c00,0x1000,0x3800,0x1000,0x1000,0x1000,0x0e00,0x0000,0x0000,0x0000,0x0000, // u0167\n  0x3200,0x4c00,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0168\n  0x0000,0x0000,0x3200,0x4c00,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u0169\n  0x3c00,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u016a\n  0x0000,0x0000,0x0000,0x3c00,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u016b\n  0x2400,0x1800,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u016c\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u016d\n  0x1800,0x2400,0x1800,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u016e\n  0x0000,0x0000,0x1800,0x2400,0x1800,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u016f\n  0x1200,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0170\n  0x0000,0x0000,0x1200,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u0171\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0800,0x1000,0x0c00,0x0000, // u0172\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0400,0x0300,0x0000, // u0173\n  0x1800,0x2400,0x0000,0x8200,0x8200,0x8200,0x8200,0x9200,0x9200,0xaa00,0xc600,0x8200,0x0000,0x0000,0x0000,0x0000, // u0174\n  0x0000,0x0000,0x1800,0x2400,0x0000,0x8200,0x8200,0x9200,0x9200,0x9200,0x9200,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0175\n  0x1800,0x2400,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u0176\n  0x0000,0x0000,0x1800,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x3c00,0x0000, // u0177\n  0x4400,0x4400,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u0178\n  0x0800,0x1000,0x0000,0x7e00,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0179\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x7e00,0x0400,0x0800,0x1000,0x2000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u017a\n  0x1000,0x1000,0x0000,0x7e00,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u017b\n  0x0000,0x0000,0x1000,0x1000,0x0000,0x7e00,0x0400,0x0800,0x1000,0x2000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u017c\n  0x2400,0x1800,0x0000,0x7e00,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u017d\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x7e00,0x0400,0x0800,0x1000,0x2000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u017e\n  0x0000,0x0000,0x0e00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u017f\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x0200,0x0200,0x0200,0x0200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0186\n  0x0000,0x0000,0x7e00,0x0200,0x0200,0x0200,0x1e00,0x0200,0x0200,0x0200,0x0200,0x7e00,0x0000,0x0000,0x0000,0x0000, // u018e\n  0x0000,0x0000,0x3c00,0x4200,0x0200,0x0200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u018f\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4000,0x3800,0x4000,0x4000,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0190\n  0x0000,0x0000,0x0c00,0x1200,0x1000,0x1000,0x7c00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x9000,0x6000,0x0000, // u0192\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x6200,0x5200,0x4a00,0x4600,0x4200,0x4200,0x4200,0x4000,0x4000,0x8000,0x0000, // u019d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0200,0x0200,0x0200,0x0000, // u019e\n  0x0000,0x0000,0x7e00,0x0200,0x0400,0x0800,0x7e00,0x1000,0x2000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u01b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0400,0x0800,0x7c00,0x1000,0x2000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u01b6\n  0x0000,0x0000,0x7e00,0x0200,0x0400,0x0800,0x1c00,0x0200,0x0200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u01b7\n  0x2400,0x1800,0x0000,0x3c00,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u01cd\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u01ce\n  0x2400,0x1800,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u01cf\n  0x0000,0x0000,0x4800,0x3000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u01d0\n  0x2400,0x1800,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u01d1\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u01d2\n  0x2400,0x1800,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u01d3\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u01d4\n  0x7c00,0x0000,0x7e00,0x9000,0x9000,0x9000,0xfc00,0x9000,0x9000,0x9000,0x9000,0x9e00,0x0000,0x0000,0x0000,0x0000, // u01e2\n  0x0000,0x0000,0x0000,0x7c00,0x0000,0x6c00,0x1200,0x7200,0x9e00,0x9000,0x9000,0x6c00,0x0000,0x0000,0x0000,0x0000, // u01e3\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4000,0x4000,0x4e00,0x4200,0x4f00,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u01e4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4200,0x4200,0x4f00,0x4200,0x4200,0x3e00,0x0200,0x0200,0x3c00,0x0000, // u01e5\n  0x2400,0x1800,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4e00,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u01e6\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x3e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x3c00,0x0000, // u01e7\n  0x2400,0x1800,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x0000,0x0000,0x0000,0x0000, // u01e8\n  0x2400,0x1800,0x4000,0x4000,0x4000,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x0000,0x0000,0x0000,0x0000, // u01e9\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0800,0x1000,0x0c00,0x0000, // u01ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0800,0x1000,0x0c00,0x0000, // u01eb\n  0x3c00,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0800,0x1000,0x0c00,0x0000, // u01ec\n  0x0000,0x0000,0x0000,0x3c00,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0800,0x1000,0x0c00,0x0000, // u01ed\n  0x2400,0x1800,0x0000,0x7e00,0x0400,0x0800,0x1c00,0x0200,0x0200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u01ee\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x7e00,0x0200,0x0400,0x0800,0x1c00,0x0200,0x0200,0x4200,0x4200,0x3c00,0x0000, // u01ef\n  0x0000,0x0000,0x1200,0x0c00,0x0000,0x0c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x4400,0x4400,0x3800,0x0000, // u01f0\n  0x0800,0x1000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4e00,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u01f4\n  0x0000,0x0000,0x0400,0x0800,0x0000,0x3e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x3c00,0x0000, // u01f5\n  0x0800,0x1000,0x0000,0x7e00,0x9000,0x9000,0x9000,0xfc00,0x9000,0x9000,0x9000,0x9e00,0x0000,0x0000,0x0000,0x0000, // u01fc\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x6c00,0x1200,0x7200,0x9e00,0x9000,0x9000,0x6c00,0x0000,0x0000,0x0000,0x0000, // u01fd\n  0x0800,0x1000,0x0000,0x3d00,0x4200,0x4600,0x4a00,0x5200,0x6200,0x4200,0xc200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u01fe\n  0x0000,0x0000,0x0800,0x1000,0x0200,0x3c00,0x4600,0x4a00,0x5200,0x6200,0x4200,0xbc00,0x0000,0x0000,0x0000,0x0000, // u01ff\n  0x0000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x3c00,0x0200,0x0200,0x4200,0x4200,0x3c00,0x0000,0x1000,0x1000,0x2000, // u0218\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4000,0x4000,0x3c00,0x0200,0x0200,0x7c00,0x0000,0x1000,0x1000,0x2000, // u0219\n  0x0000,0x0000,0xfe00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x1000,0x1000,0x2000, // u021a\n  0x0000,0x0000,0x1000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x1000,0x1000,0x1000,0x0e00,0x0000,0x0400,0x0400,0x0800, // u021b\n  0x7c00,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u0232\n  0x0000,0x0000,0x0000,0x3c00,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x3c00,0x0000, // u0233\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x4400,0x4400,0x3800,0x0000, // u0237\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x0200,0x0200,0x0200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0254\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x0200,0x0200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0258\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x0200,0x0200,0x7e00,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0259\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4000,0x3800,0x4000,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u025b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4000,0x4000,0x8000,0x0000, // u0272\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0200,0x0400,0x0800,0x1c00,0x0200,0x0200,0x4200,0x4200,0x3c00,0x0000, // u0292\n  0x0800,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bb\n  0x0800,0x0800,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bc\n  0x1000,0x1000,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bd\n  0x1800,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02c6\n  0x2400,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02c7\n  0x2400,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02d8\n  0x1000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02d9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x1000,0x0c00,0x0000, // u02db\n  0x3200,0x4c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02dc\n  0x1200,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02dd\n  0x1000,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0300\n  0x0800,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0301\n  0x1800,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0302\n  0x3200,0x4c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0303\n  0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0304\n  0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0305\n  0x2400,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0306\n  0x1000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0307\n  0x2400,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0308\n  0x1800,0x2400,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030a\n  0x1200,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030b\n  0x2400,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x0000, // u0329\n  0x4000,0x8000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0384\n  0x0800,0x1000,0x0000,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0385\n  0x4000,0x8000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u0386\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0387\n  0x4000,0x8000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0388\n  0x4000,0x8000,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u0389\n  0x4000,0x8000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u038a\n  0x4000,0x8000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u038c\n  0x4000,0x8000,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u038e\n  0x4000,0x8000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x2400,0x2400,0x6600,0x0000,0x0000,0x0000,0x0000, // u038f\n  0x0800,0x1000,0x4800,0x4800,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0c00,0x0000,0x0000,0x0000,0x0000, // u0390\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u0391\n  0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x7c00,0x4200,0x4200,0x4200,0x4200,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0392\n  0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u0393\n  0x0000,0x0000,0x1000,0x1000,0x2800,0x2800,0x4400,0x4400,0x4400,0x8200,0x8200,0xfe00,0x0000,0x0000,0x0000,0x0000, // u0394\n  0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0395\n  0x0000,0x0000,0x7e00,0x0200,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0396\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u0397\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x5a00,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0398\n  0x0000,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u0399\n  0x0000,0x0000,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x0000,0x0000,0x0000,0x0000, // u039a\n  0x0000,0x0000,0x1000,0x1000,0x2800,0x2800,0x4400,0x4400,0x4400,0x8200,0x8200,0x8200,0x0000,0x0000,0x0000,0x0000, // u039b\n  0x0000,0x0000,0x8200,0xc600,0xaa00,0x9200,0x9200,0x8200,0x8200,0x8200,0x8200,0x8200,0x0000,0x0000,0x0000,0x0000, // u039c\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x6200,0x5200,0x4a00,0x4600,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u039d\n  0x0000,0x0000,0x7e00,0x0000,0x0000,0x0000,0x3c00,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u039e\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u039f\n  0x0000,0x0000,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u03a0\n  0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x7c00,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u03a1\n  0x0000,0x0000,0x7e00,0x4000,0x2000,0x1000,0x0800,0x0800,0x1000,0x2000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u03a3\n  0x0000,0x0000,0xfe00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u03a4\n  0x0000,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u03a5\n  0x0000,0x0000,0x1000,0x7c00,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x7c00,0x1000,0x0000,0x0000,0x0000,0x0000, // u03a6\n  0x0000,0x0000,0x4200,0x4200,0x2400,0x2400,0x1800,0x1800,0x2400,0x2400,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u03a7\n  0x0000,0x0000,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x7c00,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u03a8\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x2400,0x2400,0x6600,0x0000,0x0000,0x0000,0x0000, // u03a9\n  0x4400,0x4400,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u03aa\n  0x4400,0x4400,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u03ab\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x3a00,0x4600,0x4400,0x4400,0x4400,0x4600,0x3a00,0x0000,0x0000,0x0000,0x0000, // u03ac\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x3c00,0x4200,0x4000,0x3800,0x4000,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u03ad\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0200,0x0200,0x0200,0x0000, // u03ae\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0c00,0x0000,0x0000,0x0000,0x0000, // u03af\n  0x0800,0x1000,0x0000,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u03b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3a00,0x4600,0x4400,0x4400,0x4400,0x4600,0x3a00,0x0000,0x0000,0x0000,0x0000, // u03b1\n  0x0000,0x0000,0x3800,0x4400,0x4400,0x4800,0x7c00,0x4200,0x4200,0x4200,0x4200,0x7c00,0x4000,0x4000,0x4000,0x0000, // u03b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x2800,0x1000,0x1000,0x1000,0x1000,0x0000, // u03b3\n  0x0000,0x0000,0x3e00,0x1000,0x0800,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u03b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4000,0x3800,0x4000,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u03b5\n  0x0000,0x0000,0x7e00,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x4000,0x4000,0x3c00,0x0200,0x0200,0x0400,0x0000, // u03b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0200,0x0200,0x0200,0x0000, // u03b7\n  0x0000,0x0000,0x3800,0x4400,0x4400,0x4400,0x7c00,0x4400,0x4400,0x4400,0x4400,0x3800,0x0000,0x0000,0x0000,0x0000, // u03b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0c00,0x0000,0x0000,0x0000,0x0000, // u03b9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x0000,0x0000,0x0000,0x0000, // u03ba\n  0x0000,0x0000,0x2000,0x2000,0x1000,0x1000,0x2800,0x2800,0x4400,0x4400,0x8200,0x8200,0x0000,0x0000,0x0000,0x0000, // u03bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4600,0x7a00,0x4000,0x4000,0x4000,0x0000, // u03bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x2400,0x2400,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u03bd\n  0x0000,0x0000,0x3e00,0x4000,0x4000,0x4000,0x3c00,0x4000,0x4000,0x4000,0x4000,0x3c00,0x0200,0x0200,0x0400,0x0000, // u03be\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u03bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u03c0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x7c00,0x4000,0x4000,0x4000,0x0000, // u03c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4000,0x4000,0x3c00,0x0200,0x0200,0x0400,0x0000, // u03c2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4400,0x4400,0x4400,0x4400,0x4400,0x3800,0x0000,0x0000,0x0000,0x0000, // u03c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x1000,0x1000,0x1000,0x1000,0x1000,0x0c00,0x0000,0x0000,0x0000,0x0000, // u03c4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u03c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4c00,0x9200,0x9200,0x9200,0x9200,0x9200,0x7c00,0x1000,0x1000,0x1000,0x0000, // u03c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x2400,0x2400,0x1800,0x1800,0x2400,0x2400,0x4200,0x4200,0x0000, // u03c7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x7c00,0x1000,0x1000,0x1000,0x0000, // u03c8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x8200,0x9200,0x9200,0x9200,0x9200,0x6c00,0x0000,0x0000,0x0000,0x0000, // u03c9\n  0x0000,0x0000,0x4800,0x4800,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0c00,0x0000,0x0000,0x0000,0x0000, // u03ca\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u03cb\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u03cc\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u03cd\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x4400,0x8200,0x9200,0x9200,0x9200,0x9200,0x6c00,0x0000,0x0000,0x0000,0x0000, // u03ce\n  0x0000,0x0000,0x3800,0x4400,0x4400,0x4400,0x3e00,0x0400,0xc400,0x4400,0x4400,0x3800,0x0000,0x0000,0x0000,0x0000, // u03d1\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x7c00,0x9200,0x9200,0x9200,0x9200,0x9200,0x7c00,0x1000,0x0000,0x0000,0x0000, // u03d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc200,0x2400,0x1800,0x1000,0x3000,0x4800,0x8600,0x0000,0x0000,0x0000,0x0000, // u03f0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x7c00,0x4000,0x4000,0x3c00,0x0000, // u03f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4000,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u03f2\n  0x0000,0x0000,0x0400,0x0400,0x0000,0x0c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x4400,0x4400,0x3800,0x0000, // u03f3\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u03f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2000,0x4000,0x7c00,0x4000,0x2000,0x1e00,0x0000,0x0000,0x0000,0x0000, // u03f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7800,0x0400,0x0200,0x3e00,0x0200,0x0400,0x7800,0x0000,0x0000,0x0000,0x0000, // u03f6\n  0x1000,0x0800,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0400\n  0x2400,0x2400,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0401\n  0x0000,0x0000,0xf800,0x2000,0x2000,0x3c00,0x2200,0x2200,0x2200,0x2200,0x2200,0x2400,0x0000,0x0000,0x0000,0x0000, // u0402\n  0x0800,0x1000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u0403\n  0x0000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0404\n  0x0000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x3c00,0x0200,0x0200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0405\n  0x0000,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u0406\n  0x4400,0x4400,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u0407\n  0x0000,0x0000,0x0e00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x4400,0x4400,0x3800,0x0000,0x0000,0x0000,0x0000, // u0408\n  0x0000,0x0000,0x3000,0x5000,0x9000,0x9c00,0x9200,0x9200,0x9200,0x9200,0x9200,0x9c00,0x0000,0x0000,0x0000,0x0000, // u0409\n  0x0000,0x0000,0x9000,0x9000,0x9000,0x9c00,0xf200,0x9200,0x9200,0x9200,0x9200,0x9c00,0x0000,0x0000,0x0000,0x0000, // u040a\n  0x0000,0x0000,0xf800,0x2000,0x2000,0x3c00,0x2200,0x2200,0x2200,0x2200,0x2200,0x2200,0x0000,0x0000,0x0000,0x0000, // u040b\n  0x0800,0x1000,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x0000,0x0000,0x0000,0x0000, // u040c\n  0x1000,0x0800,0x4200,0x4200,0x4200,0x4600,0x4a00,0x5200,0x6200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u040d\n  0x2400,0x1800,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x0200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u040e\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x7e00,0x1800,0x1800,0x0000,0x0000, // u040f\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u0410\n  0x0000,0x0000,0x7c00,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0411\n  0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x7c00,0x4200,0x4200,0x4200,0x4200,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0412\n  0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u0413\n  0x0000,0x0000,0x3c00,0x4400,0x4400,0x4400,0x4400,0x4400,0x4400,0x4400,0x4400,0xfe00,0x8200,0x0000,0x0000,0x0000, // u0414\n  0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0415\n  0x0000,0x0000,0x9200,0x9200,0x9200,0x5400,0x3800,0x5400,0x9200,0x9200,0x9200,0x9200,0x0000,0x0000,0x0000,0x0000, // u0416\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x0200,0x1c00,0x0200,0x0200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0417\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4600,0x4a00,0x5200,0x6200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u0418\n  0x2400,0x1800,0x4200,0x4200,0x4200,0x4600,0x4a00,0x5200,0x6200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u0419\n  0x0000,0x0000,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x0000,0x0000,0x0000,0x0000, // u041a\n  0x0000,0x0000,0x0e00,0x1200,0x2200,0x2200,0x2200,0x2200,0x2200,0x2200,0x2200,0x4200,0x0000,0x0000,0x0000,0x0000, // u041b\n  0x0000,0x0000,0x8200,0xc600,0xaa00,0x9200,0x9200,0x8200,0x8200,0x8200,0x8200,0x8200,0x0000,0x0000,0x0000,0x0000, // u041c\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u041d\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u041e\n  0x0000,0x0000,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u041f\n  0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x7c00,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u0420\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4000,0x4000,0x4000,0x4000,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0421\n  0x0000,0x0000,0xfe00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u0422\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x0200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0423\n  0x0000,0x1000,0x7c00,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x7c00,0x1000,0x0000,0x0000,0x0000, // u0424\n  0x0000,0x0000,0x4200,0x4200,0x2400,0x2400,0x1800,0x1800,0x2400,0x2400,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u0425\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3f00,0x0100,0x0100,0x0000,0x0000, // u0426\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x0200,0x0200,0x0000,0x0000,0x0000,0x0000, // u0427\n  0x0000,0x0000,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0428\n  0x0000,0x0000,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x7f00,0x0100,0x0100,0x0000,0x0000, // u0429\n  0x0000,0x0000,0xc000,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x7c00,0x0000,0x0000,0x0000,0x0000, // u042a\n  0x0000,0x0000,0x8200,0x8200,0x8200,0xf200,0x8a00,0x8a00,0x8a00,0x8a00,0x8a00,0xf200,0x0000,0x0000,0x0000,0x0000, // u042b\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x7c00,0x0000,0x0000,0x0000,0x0000, // u042c\n  0x0000,0x0000,0x3c00,0x4200,0x0200,0x0200,0x1e00,0x0200,0x0200,0x0200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u042d\n  0x0000,0x0000,0x8c00,0x9200,0x9200,0x9200,0x9200,0xf200,0x9200,0x9200,0x9200,0x8c00,0x0000,0x0000,0x0000,0x0000, // u042e\n  0x0000,0x0000,0x3e00,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0a00,0x1200,0x2200,0x4200,0x0000,0x0000,0x0000,0x0000, // u042f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u0430\n  0x0000,0x0000,0x3c00,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0431\n  0x0000,0x0000,0x3800,0x4400,0x4400,0x4800,0x7c00,0x4200,0x4200,0x4200,0x4200,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0432\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u0433\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x3c00,0x0000, // u0434\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0435\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x9200,0x9200,0x5400,0x3800,0x5400,0x9200,0x9200,0x0000,0x0000,0x0000,0x0000, // u0436\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x0200,0x1c00,0x0200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0437\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u0438\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u0439\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x0000,0x0000,0x0000,0x0000, // u043a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2200,0x2200,0x2200,0x2200,0x2200,0x4200,0x0000,0x0000,0x0000,0x0000, // u043b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x8200,0xc600,0xaa00,0x9200,0x8200,0x8200,0x8200,0x0000,0x0000,0x0000,0x0000, // u043c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u043d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u043e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u043f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x7c00,0x4000,0x4000,0x4000,0x0000, // u0440\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4000,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0441\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u0442\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x3c00,0x0000, // u0443\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x7c00,0x9200,0x9200,0x9200,0x9200,0x9200,0x7c00,0x1000,0x0000,0x0000,0x0000, // u0444\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x2400,0x1800,0x2400,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u0445\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3f00,0x0100,0x0100,0x0000,0x0000, // u0446\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x0200,0x0000,0x0000,0x0000,0x0000, // u0447\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0448\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x7f00,0x0100,0x0100,0x0000,0x0000, // u0449\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x2000,0x3c00,0x2200,0x2200,0x2200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u044a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x8200,0x8200,0xf200,0x8a00,0x8a00,0x8a00,0xf200,0x0000,0x0000,0x0000,0x0000, // u044b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x7800,0x4400,0x4400,0x4400,0x7800,0x0000,0x0000,0x0000,0x0000, // u044c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x0200,0x1e00,0x0200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u044d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x8c00,0x9200,0x9200,0xf200,0x9200,0x9200,0x8c00,0x0000,0x0000,0x0000,0x0000, // u044e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4200,0x4200,0x3e00,0x1200,0x2200,0x4200,0x0000,0x0000,0x0000,0x0000, // u044f\n  0x0000,0x0000,0x1000,0x0800,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0450\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0451\n  0x0000,0x0000,0x4000,0xf000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0200,0x0200,0x0c00,0x0000, // u0452\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u0453\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4000,0x7800,0x4000,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0454\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4000,0x4000,0x3c00,0x0200,0x0200,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0455\n  0x0000,0x0000,0x1000,0x1000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u0456\n  0x0000,0x0000,0x4800,0x4800,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u0457\n  0x0000,0x0000,0x0400,0x0400,0x0000,0x0c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x4400,0x4400,0x3800,0x0000, // u0458\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x9000,0x9c00,0x9200,0x9200,0x9200,0x9c00,0x0000,0x0000,0x0000,0x0000, // u0459\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x9000,0x9000,0x9c00,0xf200,0x9200,0x9200,0x9c00,0x0000,0x0000,0x0000,0x0000, // u045a\n  0x0000,0x0000,0x4000,0xf000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u045b\n  0x0000,0x0000,0x0800,0x1000,0x0000,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x0000,0x0000,0x0000,0x0000, // u045c\n  0x0000,0x0000,0x1000,0x0800,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u045d\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x3c00,0x0000, // u045e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x7e00,0x1800,0x1800,0x0000,0x0000, // u045f\n  0x0000,0x0000,0x4000,0xf000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0462\n  0x0000,0x0000,0x2000,0x2000,0x7800,0x2000,0x2000,0x3c00,0x2200,0x2200,0x2200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0463\n  0x0000,0x0000,0xfe00,0x8200,0x4400,0x2800,0x3800,0x5400,0x9200,0x9200,0x9200,0x9200,0x0000,0x0000,0x0000,0x0000, // u046a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x4400,0x2800,0x3800,0x5400,0x9200,0x9200,0x0000,0x0000,0x0000,0x0000, // u046b\n  0x0200,0x0200,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u0490\n  0x0000,0x0000,0x0000,0x0200,0x0200,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u0491\n  0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0xf800,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u0492\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4000,0x4000,0xf800,0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u0493\n  0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x0200,0x0400,0x0000,0x0000, // u0494\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4000,0x4000,0x7800,0x4400,0x4400,0x4400,0x0400,0x0800,0x0000,0x0000, // u0495\n  0x0000,0x0000,0x9200,0x9200,0x9200,0x5400,0x3800,0x5400,0x9200,0x9200,0x9200,0x9300,0x0100,0x0100,0x0000,0x0000, // u0496\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x9200,0x9200,0x5400,0x3800,0x5400,0x9200,0x9300,0x0100,0x0100,0x0000,0x0000, // u0497\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x0200,0x1c00,0x0200,0x0200,0x4200,0x4200,0x3c00,0x1000,0x1000,0x1000,0x0000, // u0498\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x0200,0x1c00,0x0200,0x4200,0x3c00,0x1000,0x1000,0x1000,0x0000, // u0499\n  0x0000,0x0000,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4300,0x0100,0x0100,0x0000,0x0000, // u049a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4300,0x0100,0x0100,0x0000,0x0000, // u049b\n  0x0000,0x0000,0x4200,0x4200,0x5400,0x5800,0x7000,0x7000,0x5800,0x5400,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u049c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x5400,0x5800,0x7000,0x5800,0x5400,0x4200,0x0000,0x0000,0x0000,0x0000, // u049d\n  0x0000,0x0000,0xc200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x0000,0x0000,0x0000,0x0000, // u04a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x0000,0x0000,0x0000,0x0000, // u04a1\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4300,0x0100,0x0100,0x0000,0x0000, // u04a2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4300,0x0100,0x0100,0x0000,0x0000, // u04a3\n  0x0000,0x0000,0x4700,0x4400,0x4400,0x4400,0x7c00,0x4400,0x4400,0x4400,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000, // u04a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4700,0x4400,0x4400,0x7c00,0x4400,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000, // u04a5\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4000,0x4000,0x4000,0x4000,0x4200,0x4200,0x3c00,0x1000,0x1000,0x1000,0x0000, // u04aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4000,0x4000,0x4000,0x4200,0x3c00,0x1000,0x1000,0x1000,0x0000, // u04ab\n  0x0000,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u04ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x2800,0x1000,0x1000,0x1000,0x1000,0x0000, // u04af\n  0x0000,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x1000,0x7c00,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u04b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x2800,0x1000,0x7c00,0x1000,0x1000,0x0000, // u04b1\n  0x0000,0x0000,0x4200,0x4200,0x2400,0x2400,0x1800,0x1800,0x2400,0x2400,0x4200,0x4300,0x0100,0x0100,0x0000,0x0000, // u04b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x2400,0x1800,0x2400,0x4200,0x4300,0x0100,0x0100,0x0000,0x0000, // u04b3\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x0200,0x0300,0x0100,0x0100,0x0000,0x0000, // u04b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x0300,0x0100,0x0100,0x0000,0x0000, // u04b7\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4a00,0x4a00,0x3e00,0x0a00,0x0a00,0x0200,0x0200,0x0000,0x0000,0x0000,0x0000, // u04b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4a00,0x4a00,0x3e00,0x0a00,0x0200,0x0200,0x0000,0x0000,0x0000,0x0000, // u04b9\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u04ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u04bb\n  0x0000,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u04c0\n  0x2400,0x1800,0x0000,0x9200,0x9200,0x9200,0x5400,0x3800,0x5400,0x9200,0x9200,0x9200,0x0000,0x0000,0x0000,0x0000, // u04c1\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x9200,0x9200,0x5400,0x3800,0x5400,0x9200,0x9200,0x0000,0x0000,0x0000,0x0000, // u04c2\n  0x0000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u04cf\n  0x2400,0x1800,0x0000,0x3c00,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u04d0\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u04d1\n  0x2400,0x2400,0x0000,0x3c00,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u04d2\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x3c00,0x0200,0x3e00,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u04d3\n  0x0000,0x0000,0x7e00,0x9000,0x9000,0x9000,0xfc00,0x9000,0x9000,0x9000,0x9000,0x9e00,0x0000,0x0000,0x0000,0x0000, // u04d4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6c00,0x1200,0x7200,0x9e00,0x9000,0x9000,0x6c00,0x0000,0x0000,0x0000,0x0000, // u04d5\n  0x2400,0x1800,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u04d6\n  0x0000,0x0000,0x2400,0x1800,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000,0x0000,0x0000, // u04d7\n  0x0000,0x0000,0x3c00,0x4200,0x0200,0x0200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u04d8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x0200,0x0200,0x7e00,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u04d9\n  0x2400,0x2400,0x0000,0x3c00,0x4200,0x0200,0x0200,0x7e00,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u04da\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x3c00,0x0200,0x0200,0x7e00,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u04db\n  0x4400,0x4400,0x0000,0x9200,0x9200,0x9200,0x5400,0x3800,0x5400,0x9200,0x9200,0x9200,0x0000,0x0000,0x0000,0x0000, // u04dc\n  0x0000,0x0000,0x4400,0x4400,0x0000,0x9200,0x9200,0x5400,0x3800,0x5400,0x9200,0x9200,0x0000,0x0000,0x0000,0x0000, // u04dd\n  0x2400,0x2400,0x0000,0x3c00,0x4200,0x4200,0x0200,0x1c00,0x0200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u04de\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x3c00,0x4200,0x0200,0x1c00,0x0200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u04df\n  0x3c00,0x0000,0x4200,0x4200,0x4200,0x4600,0x4a00,0x5200,0x6200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u04e2\n  0x0000,0x0000,0x0000,0x3c00,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u04e3\n  0x2400,0x2400,0x0000,0x4200,0x4200,0x4200,0x4600,0x4a00,0x5200,0x6200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u04e4\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0000,0x0000,0x0000, // u04e5\n  0x2400,0x2400,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u04e6\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u04e7\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u04e8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u04e9\n  0x2400,0x2400,0x0000,0x3c00,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u04ea\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u04eb\n  0x2400,0x2400,0x0000,0x3c00,0x4200,0x0200,0x0200,0x1e00,0x0200,0x0200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u04ec\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x3c00,0x4200,0x0200,0x1e00,0x0200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u04ed\n  0x3c00,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x0200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u04ee\n  0x0000,0x0000,0x0000,0x3c00,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x3c00,0x0000, // u04ef\n  0x2400,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x0200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u04f0\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x3c00,0x0000, // u04f1\n  0x1200,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x0200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u04f2\n  0x0000,0x0000,0x1200,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x3c00,0x0000, // u04f3\n  0x2400,0x2400,0x0000,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x0200,0x0200,0x0000,0x0000,0x0000,0x0000, // u04f4\n  0x0000,0x0000,0x2400,0x2400,0x0000,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x0200,0x0000,0x0000,0x0000,0x0000, // u04f5\n  0x4800,0x4800,0x0000,0x8200,0x8200,0x8200,0xf200,0x8a00,0x8a00,0x8a00,0x8a00,0xf200,0x0000,0x0000,0x0000,0x0000, // u04f8\n  0x0000,0x0000,0x4800,0x4800,0x0000,0x8200,0x8200,0xf200,0x8a00,0x8a00,0x8a00,0xf200,0x0000,0x0000,0x0000,0x0000, // u04f9\n  0x0000,0x0000,0x4200,0x4200,0x2200,0x2200,0x1400,0x2800,0x4400,0x4400,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u05d0\n  0x0000,0x0000,0x7c00,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x7f00,0x0000,0x0000,0x0000,0x0000, // u05d1\n  0x0000,0x0000,0x7000,0x0800,0x0800,0x0800,0x0800,0x0800,0x1400,0x2400,0x4200,0x8200,0x0000,0x0000,0x0000,0x0000, // u05d2\n  0x0000,0x0000,0x7f00,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0000,0x0000,0x0000,0x0000, // u05d3\n  0x0000,0x0000,0x7c00,0x0200,0x0200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u05d4\n  0x0000,0x0000,0x3000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000, // u05d5\n  0x0000,0x0000,0x7c00,0x0800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u05d6\n  0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u05d7\n  0x0000,0x0000,0x4c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u05d8\n  0x0000,0x0000,0x3000,0x0800,0x0800,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d9\n  0x0000,0x0000,0x7c00,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0000, // u05da\n  0x0000,0x0000,0x7c00,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x7c00,0x0000,0x0000,0x0000,0x0000, // u05db\n  0x4000,0x4000,0x7e00,0x0200,0x0200,0x0200,0x0200,0x0400,0x0800,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u05dc\n  0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x7e00,0x0000,0x0000,0x0000,0x0000, // u05dd\n  0x0000,0x0000,0xdc00,0x6200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4e00,0x0000,0x0000,0x0000,0x0000, // u05de\n  0x0000,0x0000,0x7000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000, // u05df\n  0x0000,0x0000,0x3800,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x3c00,0x0000,0x0000,0x0000,0x0000, // u05e0\n  0x0000,0x0000,0xfc00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u05e1\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x2200,0x2200,0x2200,0x1400,0x1400,0x1800,0x6000,0x0000,0x0000,0x0000,0x0000, // u05e2\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x3200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0000, // u05e3\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x3200,0x0200,0x0200,0x0200,0x0200,0x7c00,0x0000,0x0000,0x0000,0x0000, // u05e4\n  0x0000,0x0000,0x4200,0x4200,0x2200,0x2400,0x1800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000, // u05e5\n  0x0000,0x0000,0x4200,0x4200,0x2200,0x2400,0x1800,0x1000,0x0800,0x0800,0x0400,0x7c00,0x0000,0x0000,0x0000,0x0000, // u05e6\n  0x0000,0x0000,0x7e00,0x0200,0x0200,0x4200,0x4200,0x4400,0x4800,0x4800,0x4800,0x4800,0x4000,0x4000,0x4000,0x0000, // u05e7\n  0x0000,0x0000,0x7c00,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0000,0x0000,0x0000,0x0000, // u05e8\n  0x0000,0x0000,0x9200,0x9200,0x9200,0x9200,0x9200,0xa200,0xc200,0x8200,0x8400,0xf800,0x0000,0x0000,0x0000,0x0000, // u05e9\n  0x0000,0x0000,0xfc00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x8200,0x0000,0x0000,0x0000,0x0000, // u05ea\n  0x0000,0x0000,0x7800,0x4400,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4400,0x7800,0x0000,0x1000,0x1000,0x0000, // u1e0c\n  0x0000,0x0000,0x0200,0x0200,0x0200,0x3e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0800,0x0800,0x0000, // u1e0d\n  0x0000,0x0000,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x0000,0x3c00,0x0000,0x0000, // u1e34\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x0000,0x3c00,0x0000,0x0000, // u1e35\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x1000,0x1000,0x0000, // u1e36\n  0x0000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x1000,0x1000,0x0000, // u1e37\n  0x1000,0x1000,0x8200,0xc600,0xaa00,0x9200,0x9200,0x8200,0x8200,0x8200,0x8200,0x8200,0x0000,0x0000,0x0000,0x0000, // u1e40\n  0x0000,0x0000,0x1000,0x1000,0x0000,0xfc00,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x0000,0x0000,0x0000,0x0000, // u1e41\n  0x0000,0x0000,0x8200,0xc600,0xaa00,0x9200,0x9200,0x8200,0x8200,0x8200,0x8200,0x8200,0x0000,0x1000,0x1000,0x0000, // u1e42\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x9200,0x9200,0x9200,0x9200,0x9200,0x9200,0x0000,0x1000,0x1000,0x0000, // u1e43\n  0x1000,0x1000,0x4200,0x4200,0x4200,0x6200,0x5200,0x4a00,0x4600,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u1e44\n  0x0000,0x0000,0x1000,0x1000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u1e45\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x6200,0x5200,0x4a00,0x4600,0x4200,0x4200,0x4200,0x0000,0x1000,0x1000,0x0000, // u1e46\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x1000,0x1000,0x0000, // u1e47\n  0x0000,0x0000,0xfe00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x1000,0x1000,0x0000, // u1e6c\n  0x0000,0x0000,0x1000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x1000,0x1000,0x1000,0x0e00,0x0000,0x0400,0x0400,0x0000, // u1e6d\n  0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x1000,0x1000,0x0000, // u1eb8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x1000,0x1000,0x0000, // u1eb9\n  0x3200,0x4c00,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7800,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u1ebc\n  0x0000,0x0000,0x3200,0x4c00,0x0000,0x3c00,0x4200,0x4200,0x7e00,0x4000,0x4000,0x3c00,0x0000,0x0000,0x0000,0x0000, // u1ebd\n  0x0000,0x0000,0x3800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x1000,0x1000,0x0000, // u1eca\n  0x0000,0x0000,0x1000,0x1000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x1000,0x1000,0x0000, // u1ecb\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x1000,0x1000,0x0000, // u1ecc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x1000,0x1000,0x0000, // u1ecd\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x1000,0x1000,0x0000, // u1ee4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0000,0x0800,0x0800,0x0000, // u1ee5\n  0x6400,0x9800,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u1ef8\n  0x0000,0x0000,0x3200,0x4c00,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3e00,0x0200,0x0200,0x3c00,0x0000, // u1ef9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2001\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2002\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2003\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2004\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2005\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2006\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2007\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2008\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2009\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2010\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2011\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2012\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2013\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2014\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2015\n  0x0000,0x0000,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x0000,0x0000,0x0000,0x0000, // u2016\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0000,0x7e00, // u2017\n  0x0000,0x0800,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2018\n  0x0000,0x0800,0x0800,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2019\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x1000,0x0000,0x0000,0x0000, // u201a\n  0x0000,0x1000,0x1000,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201b\n  0x0000,0x1200,0x2400,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201c\n  0x0000,0x1200,0x1200,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2400,0x2400,0x4800,0x0000,0x0000,0x0000, // u201e\n  0x0000,0x4800,0x4800,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201f\n  0x0000,0x0000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u2020\n  0x0000,0x0000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u2021\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x3c00,0x3c00,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2022\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x9200,0x9200,0x0000,0x0000,0x0000,0x0000, // u2026\n  0x0000,0x0000,0x4800,0xa800,0x5000,0x1000,0x2000,0x2000,0x4000,0x5400,0xaa00,0x9400,0x0000,0x0000,0x0000,0x0000, // u2030\n  0x0000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2032\n  0x0000,0x2400,0x2400,0x2400,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2033\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x1000,0x2000,0x1000,0x0800,0x0400,0x0000,0x0000,0x0000,0x0000, // u2039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x1000,0x0800,0x0400,0x0800,0x1000,0x2000,0x0000,0x0000,0x0000,0x0000, // u203a\n  0x0000,0x0000,0x2400,0x2400,0x2400,0x2400,0x2400,0x2400,0x2400,0x0000,0x2400,0x2400,0x0000,0x0000,0x0000,0x0000, // u203c\n  0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u203e\n  0x0000,0x1800,0x2400,0x2400,0x2400,0x2400,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2070\n  0x1000,0x0000,0x3000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2071\n  0x0000,0x0400,0x0c00,0x1400,0x3e00,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2074\n  0x0000,0x3800,0x2000,0x3800,0x0400,0x0400,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2075\n  0x0000,0x1800,0x2000,0x3800,0x2400,0x2400,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2076\n  0x0000,0x3c00,0x0400,0x0800,0x0800,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2077\n  0x0000,0x1800,0x2400,0x1800,0x2400,0x2400,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2078\n  0x0000,0x1800,0x2400,0x2400,0x1c00,0x0400,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2079\n  0x0000,0x0000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207a\n  0x0000,0x0000,0x0000,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207b\n  0x0000,0x0000,0x0000,0x7c00,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207c\n  0x0000,0x0800,0x1000,0x1000,0x1000,0x1000,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207d\n  0x0000,0x1000,0x0800,0x0800,0x0800,0x0800,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207e\n  0x0000,0x0000,0x3800,0x2400,0x2400,0x2400,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x2400,0x2400,0x2400,0x2400,0x1800,0x0000,0x0000,0x0000, // u2080\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x3000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000, // u2081\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x2400,0x0400,0x0800,0x1000,0x3c00,0x0000,0x0000,0x0000, // u2082\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x0400,0x1800,0x0400,0x0400,0x3800,0x0000,0x0000,0x0000, // u2083\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0c00,0x1400,0x3e00,0x0400,0x0400,0x0000,0x0000,0x0000, // u2084\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x2000,0x3800,0x0400,0x0400,0x3800,0x0000,0x0000,0x0000, // u2085\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x2000,0x3800,0x2400,0x2400,0x1800,0x0000,0x0000,0x0000, // u2086\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x0400,0x0800,0x0800,0x1000,0x1000,0x0000,0x0000,0x0000, // u2087\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x2400,0x1800,0x2400,0x2400,0x1800,0x0000,0x0000,0x0000, // u2088\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x2400,0x2400,0x1c00,0x0400,0x1800,0x0000,0x0000,0x0000, // u2089\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x0000,0x0000,0x0000, // u208a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u208b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000, // u208c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x1000,0x1000,0x1000,0x1000,0x0800,0x0000,0x0000,0x0000, // u208d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x0800,0x0800,0x0800,0x0800,0x1000,0x0000,0x0000,0x0000, // u208e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x0400,0x1c00,0x2400,0x1c00,0x0000,0x0000,0x0000, // u2090\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x2400,0x3c00,0x2000,0x1c00,0x0000,0x0000,0x0000, // u2091\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x2400,0x2400,0x2400,0x1800,0x0000,0x0000,0x0000, // u2092\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x2800,0x1000,0x2800,0x4400,0x0000,0x0000,0x0000, // u2093\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x0400,0x3c00,0x2400,0x1800,0x0000,0x0000,0x0000, // u2094\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x3800,0x2400,0x2400,0x2400,0x2400,0x0000,0x0000,0x0000, // u2095\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2400,0x2800,0x3000,0x2800,0x2400,0x0000,0x0000,0x0000, // u2096\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x1000,0x1000,0x1000,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000, // u2097\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7800,0x5400,0x5400,0x5400,0x5400,0x0000,0x0000,0x0000, // u2098\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x2400,0x2400,0x2400,0x3800,0x2000,0x2000,0x0000, // u209a\n  0x0000,0x0000,0xf000,0x8800,0x8800,0x8800,0xf400,0x8400,0x8e00,0x8400,0x8400,0x8200,0x0000,0x0000,0x0000,0x0000, // u20a7\n  0x0000,0x0000,0xf200,0x8a00,0x8a00,0xaa00,0xaa00,0xaa00,0xaa00,0xa200,0xa200,0xbc00,0x0000,0x0000,0x0000,0x0000, // u20aa\n  0x0000,0x0000,0x0000,0x1c00,0x2200,0x4000,0xf800,0x4000,0xf800,0x4000,0x2200,0x1c00,0x0000,0x0000,0x0000,0x0000, // u20ac\n  0x0000,0x0000,0xfe00,0x1000,0x1000,0x1c00,0x7000,0x1c00,0x7000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u20ae\n  0x0000,0x0000,0x3c00,0x5200,0x5200,0x5000,0x5000,0x5000,0x5000,0x5200,0x5200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u2102\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u210e\n  0x0000,0x0000,0x4000,0xf000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u210f\n  0x0000,0x0000,0x4200,0x4200,0x6200,0x5200,0x6a00,0x5600,0x4a00,0x4600,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u2115\n  0x0000,0x0000,0x9600,0x9600,0x9600,0xd000,0xf000,0xf000,0xb000,0x9600,0x9000,0x9600,0x0000,0x0000,0x0000,0x0000, // u2116\n  0x0000,0x0000,0x3c00,0x5200,0x5200,0x5200,0x5200,0x5200,0x5200,0x5200,0x5a00,0x3c00,0x0600,0x0000,0x0000,0x0000, // u211a\n  0x0000,0x0000,0xf800,0xa400,0xa400,0xa400,0xa400,0xb800,0xa800,0xb400,0xaa00,0xe600,0x0000,0x0000,0x0000,0x0000, // u211d\n  0x0000,0x0000,0xfb00,0x5500,0x5500,0x5100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2122\n  0x0000,0x0000,0x7e00,0x0200,0x0600,0x0a00,0x1400,0x2800,0x5000,0x6000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u2124\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x2400,0x2400,0x6600,0x0000,0x0000,0x0000,0x0000, // u2126\n  0x0000,0x0000,0x4400,0x4400,0x2200,0x2200,0x3400,0x5800,0x8800,0x8800,0x8400,0x4400,0x0000,0x0000,0x0000,0x0000, // u2135\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x4000,0xfe00,0x4000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2190\n  0x0000,0x0000,0x1000,0x3800,0x5400,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u2191\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0400,0xfe00,0x0400,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2192\n  0x0000,0x0000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x5400,0x3800,0x1000,0x0000,0x0000,0x0000,0x0000, // u2193\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2400,0x4200,0xff00,0x4200,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2194\n  0x0000,0x0000,0x1000,0x3800,0x5400,0x1000,0x1000,0x1000,0x1000,0x5400,0x3800,0x1000,0x0000,0x0000,0x0000,0x0000, // u2195\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2200,0x4200,0xfe00,0x4200,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x8800,0x8400,0xfe00,0x8400,0x8800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a6\n  0x0000,0x0000,0x1000,0x3800,0x5400,0x1000,0x1000,0x1000,0x5400,0x3800,0x1000,0x7c00,0x0000,0x0000,0x0000,0x0000, // u21a8\n  0x0000,0x0000,0x0200,0x0200,0x0200,0x0200,0x0200,0x2200,0x4200,0xfe00,0x4000,0x2000,0x0000,0x0000,0x0000,0x0000, // u21b5\n  0x0000,0x0000,0x0000,0xf000,0x3000,0x5000,0x9200,0x8200,0x8200,0x4400,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000, // u21bb\n  0x0000,0x0000,0x0000,0x0000,0x2000,0x4000,0xfe00,0x0000,0xfe00,0x0400,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000, // u21cb\n  0x0000,0x0000,0x0000,0x0000,0x0800,0x0400,0xfe00,0x0000,0xfe00,0x4000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21cc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x7e00,0xc000,0x7e00,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d0\n  0x0000,0x0000,0x1000,0x3800,0x6c00,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x0000,0x0000,0x0000,0x0000, // u21d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0xfc00,0x0600,0xfc00,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d2\n  0x0000,0x0000,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x6c00,0x3800,0x1000,0x0000,0x0000,0x0000,0x0000, // u21d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2400,0x7e00,0xc300,0x7e00,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d4\n  0x0000,0x0000,0x1000,0x3800,0x6c00,0x2800,0x2800,0x2800,0x2800,0x6c00,0x3800,0x1000,0x0000,0x0000,0x0000,0x0000, // u21d5\n  0x0000,0x0000,0x8200,0x8200,0x8200,0x7c00,0x4400,0x4400,0x2800,0x2800,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u2200\n  0x0000,0x0000,0x0000,0x7e00,0x0200,0x0200,0x0200,0x7e00,0x0200,0x0200,0x0200,0x7e00,0x0000,0x0000,0x0000,0x0000, // u2203\n  0x0000,0x0000,0x0400,0x7e00,0x0a00,0x0a00,0x1200,0x7e00,0x1200,0x2200,0x2200,0x7e00,0x4000,0x0000,0x0000,0x0000, // u2204\n  0x0000,0x0000,0x0200,0x0400,0x7c00,0x8a00,0x9200,0x9200,0xa200,0x7c00,0x4000,0x8000,0x0000,0x0000,0x0000,0x0000, // u2205\n  0x0000,0x0000,0x1000,0x1000,0x2800,0x2800,0x4400,0x4400,0x4400,0x8200,0x8200,0xfe00,0x0000,0x0000,0x0000,0x0000, // u2206\n  0x0000,0x0000,0xfe00,0x8200,0x8200,0x4400,0x4400,0x4400,0x2800,0x2800,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u2207\n  0x0000,0x0000,0x0000,0x1e00,0x2000,0x4000,0x4000,0x7e00,0x4000,0x4000,0x2000,0x1e00,0x0000,0x0000,0x0000,0x0000, // u2208\n  0x0000,0x0000,0x0200,0x1e00,0x2400,0x4400,0x4800,0x7e00,0x4800,0x5000,0x3000,0x3e00,0x2000,0x0000,0x0000,0x0000, // u2209\n  0x0000,0x0000,0x0000,0x0000,0x1e00,0x2000,0x4000,0x7e00,0x4000,0x2000,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u220a\n  0x0000,0x0000,0x0000,0x7800,0x0400,0x0200,0x0200,0x7e00,0x0200,0x0200,0x0400,0x7800,0x0000,0x0000,0x0000,0x0000, // u220b\n  0x0000,0x0000,0x4000,0x7800,0x2400,0x2200,0x1200,0x7e00,0x1200,0x0a00,0x0c00,0x7c00,0x0400,0x0000,0x0000,0x0000, // u220c\n  0x0000,0x0000,0x0000,0x0000,0x7800,0x0400,0x0200,0x7e00,0x0200,0x0400,0x7800,0x0000,0x0000,0x0000,0x0000,0x0000, // u220d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2212\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u2213\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x0000,0x1000,0x1000,0x7c00,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u2214\n  0x0000,0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2215\n  0x0000,0x0000,0x0000,0x0000,0x8000,0x4000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0000,0x0000,0x0000,0x0000,0x0000, // u2216\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2219\n  0x0000,0x0600,0x0400,0x0400,0x0400,0x0400,0x4400,0x4400,0x4400,0x2400,0x1400,0x0c00,0x0000,0x0000,0x0000,0x0000, // u221a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x9200,0x9200,0x9200,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u221e\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u221f\n  0x0000,0x0000,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x0000,0x0000,0x0000,0x0000, // u2225\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x2800,0x2800,0x4400,0x4400,0x8200,0x8200,0x0000,0x0000,0x0000,0x0000, // u2227\n  0x0000,0x0000,0x0000,0x0000,0x8200,0x8200,0x4400,0x4400,0x2800,0x2800,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u2228\n  0x0000,0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u2229\n  0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u222a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3200,0x4c00,0x0000,0x3200,0x4c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2248\n  0x0000,0x0000,0x0000,0x0000,0x0200,0x7e00,0x0800,0x1000,0x7e00,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2260\n  0x0000,0x0000,0x0000,0x0000,0x7e00,0x0000,0x0000,0x7e00,0x0000,0x0000,0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2261\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x1000,0x2000,0x1000,0x0800,0x0400,0x0000,0x3e00,0x0000,0x0000,0x0000,0x0000, // u2264\n  0x0000,0x0000,0x0000,0x2000,0x1000,0x0800,0x0400,0x0800,0x1000,0x2000,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000, // u2265\n  0x0000,0x0000,0x0000,0x0900,0x1200,0x2400,0x4800,0x9000,0x4800,0x2400,0x1200,0x0900,0x0000,0x0000,0x0000,0x0000, // u226a\n  0x0000,0x0000,0x0000,0x9000,0x4800,0x2400,0x1200,0x0900,0x1200,0x2400,0x4800,0x9000,0x0000,0x0000,0x0000,0x0000, // u226b\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2282\n  0x0000,0x0000,0x0000,0x0000,0x7c00,0x0200,0x0200,0x0200,0x0200,0x0200,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2283\n  0x0000,0x0000,0x0000,0x3e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x3e00,0x0000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u2286\n  0x0000,0x0000,0x0000,0x7c00,0x0200,0x0200,0x0200,0x0200,0x0200,0x7c00,0x0000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u2287\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u22a5\n  0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u22c2\n  0x0000,0x0000,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u22c3\n  0x0000,0x0000,0x0200,0x0400,0x7c00,0x8a00,0x9200,0x9200,0xa200,0x7c00,0x4000,0x8000,0x0000,0x0000,0x0000,0x0000, // u2300\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x2800,0x4400,0x8200,0x8200,0x8200,0x8200,0xfe00,0x0000,0x0000,0x0000,0x0000, // u2302\n  0x0000,0x0000,0x3800,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000, // u2308\n  0x0000,0x0000,0x3800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000, // u2309\n  0x0000,0x0000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x3800,0x0000,0x0000,0x0000,0x0000, // u230a\n  0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x3800,0x0000,0x0000,0x0000,0x0000, // u230b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2310\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2319\n  0x0000,0x0000,0x0c00,0x1200,0x1200,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2320\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x9000,0x9000,0x6000,0x0000,0x0000,0x0000,0x0000, // u2321\n  0x0400,0x0800,0x1000,0x1000,0x2000,0x2000,0x2000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000, // u239b\n  0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000, // u239c\n  0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x2000,0x2000,0x2000,0x1000,0x1000,0x0800,0x0400, // u239d\n  0x4000,0x2000,0x1000,0x1000,0x0800,0x0800,0x0800,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u239e\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u239f\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0800,0x0800,0x0800,0x1000,0x1000,0x2000,0x4000, // u23a0\n  0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000, // u23a1\n  0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000, // u23a2\n  0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00, // u23a3\n  0x7c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u23a4\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u23a5\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x7c00, // u23a6\n  0x0e00,0x1000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u23a7\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0xc000,0xc000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u23a8\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x1000,0x0e00, // u23a9\n  0xe000,0x1000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800, // u23ab\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0600,0x0600,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800, // u23ac\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1000,0xe000, // u23ad\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u23ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23af\n  0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23ba\n  0x0000,0x0000,0x0000,0x0000,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x0000,0x0000,0x0000,0x0000, // u23bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00, // u23bd\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u23d0\n  0x0000,0x8800,0x8800,0xf800,0x8800,0x8800,0x8800,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0000,0x0000, // u2409\n  0x0000,0x8000,0x8000,0x8000,0x8000,0x8000,0xf800,0x0000,0x1f00,0x1000,0x1c00,0x1000,0x1000,0x1000,0x0000,0x0000, // u240a\n  0x0000,0x8800,0x8800,0x5000,0x5000,0x2000,0x2000,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0000,0x0000, // u240b\n  0x0000,0xf800,0x8000,0xe000,0x8000,0x8000,0x8000,0x0000,0x1f00,0x1000,0x1c00,0x1000,0x1000,0x1000,0x0000,0x0000, // u240c\n  0x0000,0x7000,0x8800,0x8000,0x8000,0x8800,0x7000,0x0000,0x1e00,0x1100,0x1100,0x1e00,0x1200,0x1100,0x0000,0x0000, // u240d\n  0x0000,0x8800,0xc800,0xa800,0x9800,0x8800,0x8800,0x0000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1f00,0x0000,0x0000, // u2424\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2500\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2501\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2502\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2503\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xaa00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2508\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xaa00,0xaa00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2509\n  0x1000,0x1000,0x1000,0x0000,0x1000,0x1000,0x1000,0x0000,0x1000,0x1000,0x1000,0x0000,0x1000,0x1000,0x1000,0x0000, // u250a\n  0x1800,0x1800,0x1800,0x0000,0x1800,0x1800,0x1800,0x0000,0x1800,0x1800,0x1800,0x0000,0x1800,0x1800,0x1800,0x0000, // u250b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u250c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x1f00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u250d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u250e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u250f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2510\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf000,0xf000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2511\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2512\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2513\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2514\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1f00,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2515\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2516\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2517\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xf000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2518\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xf000,0xf000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2519\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u251a\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u251b\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1f00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u251c\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1f00,0x1f00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u251d\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u251e\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u251f\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2520\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0x1f00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2521\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1f00,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2522\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2523\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xf000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2524\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xf000,0xf000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2525\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2526\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2527\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2528\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0xf800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2529\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xf800,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u252a\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u252b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u252c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xf000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u252d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x1f00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u252e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u252f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2530\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2531\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2532\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2533\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2534\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0xf000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2535\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2536\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2537\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2538\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2539\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u253a\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u253b\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u253c\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0xf000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u253d\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0x1f00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u253e\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0xff00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u253f\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2540\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2541\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2542\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0xf000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2543\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0x1f00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2544\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2545\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2546\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0xff00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2547\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2548\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2549\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u254a\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u254b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x0000,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2550\n  0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800, // u2551\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x1000,0x1f00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2552\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800, // u2553\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x2000,0x2f00,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800, // u2554\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf000,0x1000,0xf000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2555\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800, // u2556\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0x0800,0xe800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800, // u2557\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1f00,0x1000,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2558\n  0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2559\n  0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2f00,0x2000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255a\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xf000,0x1000,0xf000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255b\n  0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255c\n  0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0xe800,0x0800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255d\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1f00,0x1000,0x1f00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u255e\n  0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2f00,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800, // u255f\n  0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2f00,0x2000,0x2f00,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800, // u2560\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xf000,0x1000,0xf000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2561\n  0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0xe800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800, // u2562\n  0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0xe800,0x0800,0xe800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800, // u2563\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x0000,0xff00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2564\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800, // u2565\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x0000,0xef00,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800, // u2566\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0x0000,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2567\n  0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2568\n  0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0xef00,0x0000,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2569\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xff00,0x1000,0xff00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u256a\n  0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0xff00,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800, // u256b\n  0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0xef00,0x0000,0xef00,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800,0x2800, // u256c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u256d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0x2000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u256e\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x2000,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u256f\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0800,0x0700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2570\n  0x0100,0x0100,0x0200,0x0200,0x0400,0x0400,0x0800,0x0800,0x1000,0x1000,0x2000,0x2000,0x4000,0x4000,0x8000,0x8000, // u2571\n  0x8000,0x8000,0x4000,0x4000,0x2000,0x2000,0x1000,0x1000,0x0800,0x0800,0x0400,0x0400,0x0200,0x0200,0x0100,0x0100, // u2572\n  0x8100,0x8100,0x4200,0x4200,0x2400,0x2400,0x1800,0x1800,0x1800,0x1800,0x2400,0x2400,0x4200,0x4200,0x8100,0x8100, // u2573\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2574\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2575\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2576\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u2577\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf000,0xf000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2578\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2579\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u257b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257c\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u257d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xf000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257e\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000, // u257f\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2580\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00, // u2581\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0xff00, // u2582\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2583\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2584\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2585\n  0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2586\n  0x0000,0x0000,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2587\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2588\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00, // u2589\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00, // u258a\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800, // u258b\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000, // u258c\n  0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000, // u258d\n  0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000, // u258e\n  0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000, // u258f\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u2590\n  0x8800,0x2200,0x8800,0x2200,0x8800,0x2200,0x8800,0x2200,0x8800,0x2200,0x8800,0x2200,0x8800,0x2200,0x8800,0x2200, // u2591\n  0xaa00,0x5500,0xaa00,0x5500,0xaa00,0x5500,0xaa00,0x5500,0xaa00,0x5500,0xaa00,0x5500,0xaa00,0x5500,0xaa00,0x5500, // u2592\n  0xee00,0xbb00,0xee00,0xbb00,0xee00,0xbb00,0xee00,0xbb00,0xee00,0xbb00,0xee00,0xbb00,0xee00,0xbb00,0xee00,0xbb00, // u2593\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000, // u2596\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u2597\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2598\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2599\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u259a\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000, // u259b\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u259c\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u259d\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000, // u259e\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u259f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x3c00,0x3c00,0x3c00,0x3c00,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u25a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x7e00,0x7e00,0x7e00,0x0000,0x0000,0x0000,0x0000, // u25ac\n  0x0000,0x0000,0x7e00,0x7e00,0x7e00,0x7e00,0x7e00,0x7e00,0x7e00,0x7e00,0x7e00,0x7e00,0x0000,0x0000,0x0000,0x0000, // u25ae\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x3800,0x3800,0x7c00,0x7c00,0xfe00,0xfe00,0x0000,0x0000,0x0000,0x0000, // u25b2\n  0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xfc00,0xf000,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25b6\n  0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xfc00,0xf000,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ba\n  0x0000,0x0000,0x0000,0x0000,0xfe00,0xfe00,0x7c00,0x7c00,0x3800,0x3800,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u25bc\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0f00,0x3f00,0xff00,0x3f00,0x0f00,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c0\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0f00,0x3f00,0xff00,0x3f00,0x0f00,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c4\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x3800,0x7c00,0xfe00,0x7c00,0x3800,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c6\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x2800,0x4400,0x8200,0x4400,0x2800,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ca\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x2400,0x2400,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x3c00,0x3c00,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25cf\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xe700,0xc300,0xc300,0xe700,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u25d8\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xe700,0xdb00,0xdb00,0xe700,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u25d9\n  0x0000,0x0000,0x7c00,0x8200,0xaa00,0x8200,0x8200,0xba00,0x9200,0x8200,0x8200,0x7c00,0x0000,0x0000,0x0000,0x0000, // u263a\n  0x0000,0x0000,0x7c00,0xfe00,0xd600,0xfe00,0xfe00,0xc600,0xee00,0xfe00,0xfe00,0x7c00,0x0000,0x0000,0x0000,0x0000, // u263b\n  0x0000,0x0000,0x0000,0x1000,0x9200,0x5400,0x3800,0xee00,0x3800,0x5400,0x9200,0x1000,0x0000,0x0000,0x0000,0x0000, // u263c\n  0x0000,0x0000,0x3800,0x4400,0x4400,0x4400,0x4400,0x3800,0x1000,0x7c00,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u2640\n  0x0000,0x0000,0x1e00,0x0600,0x0a00,0x1200,0x3800,0x4400,0x4400,0x4400,0x4400,0x3800,0x0000,0x0000,0x0000,0x0000, // u2642\n  0x0000,0x0000,0x1000,0x1000,0x3800,0x7c00,0xfe00,0xfe00,0x7c00,0x1000,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u2660\n  0x0000,0x0000,0x1000,0x3800,0x3800,0x1000,0x5400,0xfe00,0xfe00,0x5400,0x1000,0x3800,0x0000,0x0000,0x0000,0x0000, // u2663\n  0x0000,0x0000,0x0000,0x0000,0x6c00,0xfe00,0xfe00,0xfe00,0xfe00,0x7c00,0x3800,0x1000,0x0000,0x0000,0x0000,0x0000, // u2665\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x3800,0x7c00,0xfe00,0x7c00,0x3800,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2666\n  0x0000,0x0000,0x3e00,0x2200,0x3e00,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0xc000,0x0000,0x0000,0x0000,0x0000, // u266a\n  0x0000,0x0000,0x7e00,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4400,0x8000,0x0000,0x0000,0x0000, // u266b\n  0x0000,0x0000,0x0200,0x0200,0x0400,0x0400,0x8800,0x8800,0x5000,0x5000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000, // u2713\n  0x0000,0x0000,0x0300,0x0300,0x0600,0x0600,0xcc00,0xcc00,0x7800,0x7800,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000, // u2714\n  0x0000,0x0000,0x0400,0x4400,0x2800,0x1800,0x1800,0x1400,0x2200,0x2000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000, // u2717\n  0x0000,0x0000,0x0c00,0xcc00,0x7800,0x3800,0x3800,0x3c00,0x6600,0x6000,0xc000,0xc000,0x0000,0x0000,0x0000,0x0000, // u2718\n  0x0000,0x0000,0x0800,0x0800,0x1000,0x1000,0x2000,0x2000,0x1000,0x1000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000, // u27e8\n  0x0000,0x0000,0x2000,0x2000,0x1000,0x1000,0x0800,0x0800,0x1000,0x1000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000, // u27e9\n  0x0000,0x0000,0x1200,0x1200,0x2400,0x2400,0x4800,0x4800,0x2400,0x2400,0x1200,0x1200,0x0000,0x0000,0x0000,0x0000, // u27ea\n  0x0000,0x0000,0x4800,0x4800,0x2400,0x2400,0x1200,0x1200,0x2400,0x2400,0x4800,0x4800,0x0000,0x0000,0x0000,0x0000, // u27eb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2800\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2801\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2802\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2803\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2804\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2805\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2806\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2807\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2808\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2809\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280a\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280b\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280c\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280d\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280e\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2810\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2811\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2812\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2813\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2814\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2815\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2816\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2817\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2818\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2819\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281a\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281b\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281c\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281d\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281e\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2820\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2821\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2822\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2823\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2824\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2825\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2826\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2827\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2828\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2829\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u282a\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u282b\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000, // u282c\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000, // u282d\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000, // u282e\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000, // u282f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2830\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2831\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2832\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2833\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2834\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2835\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2836\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2837\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2838\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2839\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u283a\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u283b\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000, // u283c\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000, // u283d\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000, // u283e\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000, // u283f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2840\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2841\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2842\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2843\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2844\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2845\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2846\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2847\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2848\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2849\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u284a\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u284b\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000, // u284c\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000, // u284d\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000, // u284e\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000, // u284f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2850\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2851\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2852\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2853\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2854\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2855\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2856\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2857\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2858\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u2859\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u285a\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000, // u285b\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000, // u285c\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000, // u285d\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000, // u285e\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000, // u285f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000, // u2860\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000, // u2861\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000, // u2862\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000, // u2863\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000, // u2864\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000, // u2865\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000, // u2866\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000, // u2867\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000, // u2868\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000, // u2869\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000, // u286a\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000, // u286b\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000, // u286c\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000, // u286d\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000, // u286e\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000, // u286f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000, // u2870\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000, // u2871\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000, // u2872\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000, // u2873\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000, // u2874\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000, // u2875\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000, // u2876\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000, // u2877\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000, // u2878\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000, // u2879\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000, // u287a\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000, // u287b\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000, // u287c\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000, // u287d\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000, // u287e\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000, // u287f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2880\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2881\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2882\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2883\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2884\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2885\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2886\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2887\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2888\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2889\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u288a\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u288b\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000, // u288c\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000, // u288d\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000, // u288e\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000, // u288f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2890\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2891\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2892\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2893\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2894\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2895\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2896\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2897\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2898\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u2899\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u289a\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000, // u289b\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000, // u289c\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000, // u289d\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000, // u289e\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000, // u289f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28a0\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28a2\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28a4\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28a5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28a6\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28a7\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28a8\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28a9\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28aa\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28ab\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28ac\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28ad\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28ae\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28af\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28b0\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28b1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28b2\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28b4\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28b6\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28b7\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28b8\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28b9\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28ba\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28bb\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28bc\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28bd\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28be\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000, // u28bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28c0\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28c2\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28c4\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28c6\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28c7\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28c8\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28c9\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28ca\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28cb\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28cc\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28cd\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28ce\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28cf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28d0\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28d2\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28d4\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28d6\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28d7\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28d8\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28d9\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28da\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28db\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28dc\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28dd\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28de\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000, // u28df\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28e0\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28e1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28e2\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28e3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28e4\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28e6\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28e7\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28e8\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28e9\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28ea\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28eb\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28ec\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28ed\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28ee\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28ef\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28f0\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28f2\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28f3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28f4\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28f6\n  0x0000,0x4000,0x4000,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28f7\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28f8\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28f9\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28fa\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28fb\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28fc\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28fd\n  0x0000,0x0400,0x0400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28fe\n  0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000,0x0000,0x4400,0x4400,0x0000, // u28ff\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x0000,0x0000,0x0000,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u2e2c\n  0x8000,0x8000,0x8800,0x9c00,0xaa00,0x8800,0x8800,0x8800,0x1000,0x2000,0x4000,0x8000,0x8000,0x8000,0x8000,0x8000, // ue0a0\n  0x0000,0x8000,0x8000,0x8000,0x8000,0x8000,0xf800,0x0000,0x1100,0x1900,0x1500,0x1300,0x1100,0x1100,0x0000,0x0000, // ue0a1\n  0x0000,0x3800,0x4400,0x4400,0x4400,0x4400,0xfe00,0xfe00,0xee00,0xc600,0xee00,0xfe00,0xfe00,0xfe00,0x0000,0x0000, // ue0a2\n  0x8000,0xc000,0xe000,0xf000,0xf800,0xfc00,0xfe00,0xff00,0xff00,0xfe00,0xfc00,0xf800,0xf000,0xe000,0xc000,0x8000, // ue0b0\n  0x8000,0x4000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000, // ue0b1\n  0x0100,0x0300,0x0700,0x0f00,0x1f00,0x3f00,0x7f00,0xff00,0xff00,0x7f00,0x3f00,0x1f00,0x0f00,0x0700,0x0300,0x0100, // ue0b2\n  0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000,0x8000,0x4000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100, // ue0b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x4400,0x4400,0x3800,0x0000, // uf6be\n  0x0000,0x0000,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x7e00,0x0000,0x0000,0x0000,0x0000 // ufffd\n  };\n  // codepoints array\n  constexpr std::array<uint16_t, CHARCOUNT> fixedfont_codepoints = {\n  0x0000,0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,\n  0x002f,0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,\n  0x003f,0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,\n  0x004f,0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,\n  0x005f,0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,\n  0x006f,0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,\n  0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af,\n  0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf,\n  0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf,\n  0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df,\n  0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef,\n  0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff,\n  0x0100,0x0101,0x0102,0x0103,0x0104,0x0105,0x0106,0x0107,0x0108,0x0109,0x010a,0x010b,0x010c,0x010d,0x010e,0x010f,\n  0x0110,0x0111,0x0112,0x0113,0x0114,0x0115,0x0116,0x0117,0x0118,0x0119,0x011a,0x011b,0x011c,0x011d,0x011e,0x011f,\n  0x0120,0x0121,0x0122,0x0123,0x0124,0x0125,0x0126,0x0127,0x0128,0x0129,0x012a,0x012b,0x012c,0x012d,0x012e,0x012f,\n  0x0130,0x0131,0x0132,0x0133,0x0134,0x0135,0x0136,0x0137,0x0138,0x0139,0x013a,0x013b,0x013c,0x013d,0x013e,0x013f,\n  0x0140,0x0141,0x0142,0x0143,0x0144,0x0145,0x0146,0x0147,0x0148,0x0149,0x014a,0x014b,0x014c,0x014d,0x014e,0x014f,\n  0x0150,0x0151,0x0152,0x0153,0x0154,0x0155,0x0156,0x0157,0x0158,0x0159,0x015a,0x015b,0x015c,0x015d,0x015e,0x015f,\n  0x0160,0x0161,0x0162,0x0163,0x0164,0x0165,0x0166,0x0167,0x0168,0x0169,0x016a,0x016b,0x016c,0x016d,0x016e,0x016f,\n  0x0170,0x0171,0x0172,0x0173,0x0174,0x0175,0x0176,0x0177,0x0178,0x0179,0x017a,0x017b,0x017c,0x017d,0x017e,0x017f,\n  0x0186,0x018e,0x018f,0x0190,0x0192,0x019d,0x019e,0x01b5,0x01b6,0x01b7,0x01cd,0x01ce,0x01cf,0x01d0,0x01d1,0x01d2,\n  0x01d3,0x01d4,0x01e2,0x01e3,0x01e4,0x01e5,0x01e6,0x01e7,0x01e8,0x01e9,0x01ea,0x01eb,0x01ec,0x01ed,0x01ee,0x01ef,\n  0x01f0,0x01f4,0x01f5,0x01fc,0x01fd,0x01fe,0x01ff,0x0218,0x0219,0x021a,0x021b,0x0232,0x0233,0x0237,0x0254,0x0258,\n  0x0259,0x025b,0x0272,0x0292,0x02bb,0x02bc,0x02bd,0x02c6,0x02c7,0x02d8,0x02d9,0x02db,0x02dc,0x02dd,0x0300,0x0301,\n  0x0302,0x0303,0x0304,0x0305,0x0306,0x0307,0x0308,0x030a,0x030b,0x030c,0x0329,0x0384,0x0385,0x0386,0x0387,0x0388,\n  0x0389,0x038a,0x038c,0x038e,0x038f,0x0390,0x0391,0x0392,0x0393,0x0394,0x0395,0x0396,0x0397,0x0398,0x0399,0x039a,\n  0x039b,0x039c,0x039d,0x039e,0x039f,0x03a0,0x03a1,0x03a3,0x03a4,0x03a5,0x03a6,0x03a7,0x03a8,0x03a9,0x03aa,0x03ab,\n  0x03ac,0x03ad,0x03ae,0x03af,0x03b0,0x03b1,0x03b2,0x03b3,0x03b4,0x03b5,0x03b6,0x03b7,0x03b8,0x03b9,0x03ba,0x03bb,\n  0x03bc,0x03bd,0x03be,0x03bf,0x03c0,0x03c1,0x03c2,0x03c3,0x03c4,0x03c5,0x03c6,0x03c7,0x03c8,0x03c9,0x03ca,0x03cb,\n  0x03cc,0x03cd,0x03ce,0x03d1,0x03d5,0x03f0,0x03f1,0x03f2,0x03f3,0x03f4,0x03f5,0x03f6,0x0400,0x0401,0x0402,0x0403,\n  0x0404,0x0405,0x0406,0x0407,0x0408,0x0409,0x040a,0x040b,0x040c,0x040d,0x040e,0x040f,0x0410,0x0411,0x0412,0x0413,\n  0x0414,0x0415,0x0416,0x0417,0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e,0x041f,0x0420,0x0421,0x0422,0x0423,\n  0x0424,0x0425,0x0426,0x0427,0x0428,0x0429,0x042a,0x042b,0x042c,0x042d,0x042e,0x042f,0x0430,0x0431,0x0432,0x0433,\n  0x0434,0x0435,0x0436,0x0437,0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e,0x043f,0x0440,0x0441,0x0442,0x0443,\n  0x0444,0x0445,0x0446,0x0447,0x0448,0x0449,0x044a,0x044b,0x044c,0x044d,0x044e,0x044f,0x0450,0x0451,0x0452,0x0453,\n  0x0454,0x0455,0x0456,0x0457,0x0458,0x0459,0x045a,0x045b,0x045c,0x045d,0x045e,0x045f,0x0462,0x0463,0x046a,0x046b,\n  0x0490,0x0491,0x0492,0x0493,0x0494,0x0495,0x0496,0x0497,0x0498,0x0499,0x049a,0x049b,0x049c,0x049d,0x04a0,0x04a1,\n  0x04a2,0x04a3,0x04a4,0x04a5,0x04aa,0x04ab,0x04ae,0x04af,0x04b0,0x04b1,0x04b2,0x04b3,0x04b6,0x04b7,0x04b8,0x04b9,\n  0x04ba,0x04bb,0x04c0,0x04c1,0x04c2,0x04cf,0x04d0,0x04d1,0x04d2,0x04d3,0x04d4,0x04d5,0x04d6,0x04d7,0x04d8,0x04d9,\n  0x04da,0x04db,0x04dc,0x04dd,0x04de,0x04df,0x04e2,0x04e3,0x04e4,0x04e5,0x04e6,0x04e7,0x04e8,0x04e9,0x04ea,0x04eb,\n  0x04ec,0x04ed,0x04ee,0x04ef,0x04f0,0x04f1,0x04f2,0x04f3,0x04f4,0x04f5,0x04f8,0x04f9,0x05d0,0x05d1,0x05d2,0x05d3,\n  0x05d4,0x05d5,0x05d6,0x05d7,0x05d8,0x05d9,0x05da,0x05db,0x05dc,0x05dd,0x05de,0x05df,0x05e0,0x05e1,0x05e2,0x05e3,\n  0x05e4,0x05e5,0x05e6,0x05e7,0x05e8,0x05e9,0x05ea,0x1e0c,0x1e0d,0x1e34,0x1e35,0x1e36,0x1e37,0x1e40,0x1e41,0x1e42,\n  0x1e43,0x1e44,0x1e45,0x1e46,0x1e47,0x1e6c,0x1e6d,0x1eb8,0x1eb9,0x1ebc,0x1ebd,0x1eca,0x1ecb,0x1ecc,0x1ecd,0x1ee4,\n  0x1ee5,0x1ef8,0x1ef9,0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007,0x2008,0x2009,0x200a,0x200b,0x200c,\n  0x200d,0x200e,0x200f,0x2010,0x2011,0x2012,0x2013,0x2014,0x2015,0x2016,0x2017,0x2018,0x2019,0x201a,0x201b,0x201c,\n  0x201d,0x201e,0x201f,0x2020,0x2021,0x2022,0x2026,0x2030,0x2032,0x2033,0x2039,0x203a,0x203c,0x203e,0x2070,0x2071,\n  0x2074,0x2075,0x2076,0x2077,0x2078,0x2079,0x207a,0x207b,0x207c,0x207d,0x207e,0x207f,0x2080,0x2081,0x2082,0x2083,\n  0x2084,0x2085,0x2086,0x2087,0x2088,0x2089,0x208a,0x208b,0x208c,0x208d,0x208e,0x2090,0x2091,0x2092,0x2093,0x2094,\n  0x2095,0x2096,0x2097,0x2098,0x209a,0x20a7,0x20aa,0x20ac,0x20ae,0x2102,0x210e,0x210f,0x2115,0x2116,0x211a,0x211d,\n  0x2122,0x2124,0x2126,0x2135,0x2190,0x2191,0x2192,0x2193,0x2194,0x2195,0x21a4,0x21a6,0x21a8,0x21b5,0x21bb,0x21cb,\n  0x21cc,0x21d0,0x21d1,0x21d2,0x21d3,0x21d4,0x21d5,0x2200,0x2203,0x2204,0x2205,0x2206,0x2207,0x2208,0x2209,0x220a,\n  0x220b,0x220c,0x220d,0x2212,0x2213,0x2214,0x2215,0x2216,0x2219,0x221a,0x221e,0x221f,0x2225,0x2227,0x2228,0x2229,\n  0x222a,0x2248,0x2260,0x2261,0x2264,0x2265,0x226a,0x226b,0x2282,0x2283,0x2286,0x2287,0x22a5,0x22c2,0x22c3,0x2300,\n  0x2302,0x2308,0x2309,0x230a,0x230b,0x2310,0x2319,0x2320,0x2321,0x239b,0x239c,0x239d,0x239e,0x239f,0x23a0,0x23a1,\n  0x23a2,0x23a3,0x23a4,0x23a5,0x23a6,0x23a7,0x23a8,0x23a9,0x23ab,0x23ac,0x23ad,0x23ae,0x23af,0x23ba,0x23bb,0x23bc,\n  0x23bd,0x23d0,0x2409,0x240a,0x240b,0x240c,0x240d,0x2424,0x2500,0x2501,0x2502,0x2503,0x2508,0x2509,0x250a,0x250b,\n  0x250c,0x250d,0x250e,0x250f,0x2510,0x2511,0x2512,0x2513,0x2514,0x2515,0x2516,0x2517,0x2518,0x2519,0x251a,0x251b,\n  0x251c,0x251d,0x251e,0x251f,0x2520,0x2521,0x2522,0x2523,0x2524,0x2525,0x2526,0x2527,0x2528,0x2529,0x252a,0x252b,\n  0x252c,0x252d,0x252e,0x252f,0x2530,0x2531,0x2532,0x2533,0x2534,0x2535,0x2536,0x2537,0x2538,0x2539,0x253a,0x253b,\n  0x253c,0x253d,0x253e,0x253f,0x2540,0x2541,0x2542,0x2543,0x2544,0x2545,0x2546,0x2547,0x2548,0x2549,0x254a,0x254b,\n  0x2550,0x2551,0x2552,0x2553,0x2554,0x2555,0x2556,0x2557,0x2558,0x2559,0x255a,0x255b,0x255c,0x255d,0x255e,0x255f,\n  0x2560,0x2561,0x2562,0x2563,0x2564,0x2565,0x2566,0x2567,0x2568,0x2569,0x256a,0x256b,0x256c,0x256d,0x256e,0x256f,\n  0x2570,0x2571,0x2572,0x2573,0x2574,0x2575,0x2576,0x2577,0x2578,0x2579,0x257a,0x257b,0x257c,0x257d,0x257e,0x257f,\n  0x2580,0x2581,0x2582,0x2583,0x2584,0x2585,0x2586,0x2587,0x2588,0x2589,0x258a,0x258b,0x258c,0x258d,0x258e,0x258f,\n  0x2590,0x2591,0x2592,0x2593,0x2596,0x2597,0x2598,0x2599,0x259a,0x259b,0x259c,0x259d,0x259e,0x259f,0x25a0,0x25ac,\n  0x25ae,0x25b2,0x25b6,0x25ba,0x25bc,0x25c0,0x25c4,0x25c6,0x25ca,0x25cb,0x25cf,0x25d8,0x25d9,0x263a,0x263b,0x263c,\n  0x2640,0x2642,0x2660,0x2663,0x2665,0x2666,0x266a,0x266b,0x2713,0x2714,0x2717,0x2718,0x27e8,0x27e9,0x27ea,0x27eb,\n  0x2800,0x2801,0x2802,0x2803,0x2804,0x2805,0x2806,0x2807,0x2808,0x2809,0x280a,0x280b,0x280c,0x280d,0x280e,0x280f,\n  0x2810,0x2811,0x2812,0x2813,0x2814,0x2815,0x2816,0x2817,0x2818,0x2819,0x281a,0x281b,0x281c,0x281d,0x281e,0x281f,\n  0x2820,0x2821,0x2822,0x2823,0x2824,0x2825,0x2826,0x2827,0x2828,0x2829,0x282a,0x282b,0x282c,0x282d,0x282e,0x282f,\n  0x2830,0x2831,0x2832,0x2833,0x2834,0x2835,0x2836,0x2837,0x2838,0x2839,0x283a,0x283b,0x283c,0x283d,0x283e,0x283f,\n  0x2840,0x2841,0x2842,0x2843,0x2844,0x2845,0x2846,0x2847,0x2848,0x2849,0x284a,0x284b,0x284c,0x284d,0x284e,0x284f,\n  0x2850,0x2851,0x2852,0x2853,0x2854,0x2855,0x2856,0x2857,0x2858,0x2859,0x285a,0x285b,0x285c,0x285d,0x285e,0x285f,\n  0x2860,0x2861,0x2862,0x2863,0x2864,0x2865,0x2866,0x2867,0x2868,0x2869,0x286a,0x286b,0x286c,0x286d,0x286e,0x286f,\n  0x2870,0x2871,0x2872,0x2873,0x2874,0x2875,0x2876,0x2877,0x2878,0x2879,0x287a,0x287b,0x287c,0x287d,0x287e,0x287f,\n  0x2880,0x2881,0x2882,0x2883,0x2884,0x2885,0x2886,0x2887,0x2888,0x2889,0x288a,0x288b,0x288c,0x288d,0x288e,0x288f,\n  0x2890,0x2891,0x2892,0x2893,0x2894,0x2895,0x2896,0x2897,0x2898,0x2899,0x289a,0x289b,0x289c,0x289d,0x289e,0x289f,\n  0x28a0,0x28a1,0x28a2,0x28a3,0x28a4,0x28a5,0x28a6,0x28a7,0x28a8,0x28a9,0x28aa,0x28ab,0x28ac,0x28ad,0x28ae,0x28af,\n  0x28b0,0x28b1,0x28b2,0x28b3,0x28b4,0x28b5,0x28b6,0x28b7,0x28b8,0x28b9,0x28ba,0x28bb,0x28bc,0x28bd,0x28be,0x28bf,\n  0x28c0,0x28c1,0x28c2,0x28c3,0x28c4,0x28c5,0x28c6,0x28c7,0x28c8,0x28c9,0x28ca,0x28cb,0x28cc,0x28cd,0x28ce,0x28cf,\n  0x28d0,0x28d1,0x28d2,0x28d3,0x28d4,0x28d5,0x28d6,0x28d7,0x28d8,0x28d9,0x28da,0x28db,0x28dc,0x28dd,0x28de,0x28df,\n  0x28e0,0x28e1,0x28e2,0x28e3,0x28e4,0x28e5,0x28e6,0x28e7,0x28e8,0x28e9,0x28ea,0x28eb,0x28ec,0x28ed,0x28ee,0x28ef,\n  0x28f0,0x28f1,0x28f2,0x28f3,0x28f4,0x28f5,0x28f6,0x28f7,0x28f8,0x28f9,0x28fa,0x28fb,0x28fc,0x28fd,0x28fe,0x28ff,\n  0x2e2c,0xe0a0,0xe0a1,0xe0a2,0xe0b0,0xe0b1,0xe0b2,0xe0b3,0xf6be,0xfffd };\n} // namespace\n// -- end of autogenerated text ---\n\nnamespace fixed_font_16b {\n  // -- start of autogenerated text ---\n  // definition section for font: ter-u16b.bdf\n  constexpr int CHARCOUNT = 1354;\n  constexpr int WIDTH = 8;\n  constexpr int HEIGHT = 16;\n  constexpr int OFFSET_X = 0;\n  constexpr int OFFSET_Y = 0;\n  constexpr FixedFont_info_t fixedfont_info = {\n    \"Terminus\", // font name\n    \"ter-u16b.bdf\", // font name internal\n    CHARCOUNT, // num of chars\n    WIDTH, HEIGHT, OFFSET_X, OFFSET_Y,\n    true // bold\n  };\n  // font bitmap definitions\n  constexpr std::array<uint16_t, CHARCOUNT * HEIGHT> fixedfont_bitmap = {\n  0x0000,0x0000,0xee00,0xc600,0x0000,0xc600,0xc600,0xc600,0x0000,0xc600,0xc600,0xee00,0x0000,0x0000,0x0000,0x0000, // u0000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0020\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u0021\n  0x0000,0x6600,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0022\n  0x0000,0x0000,0x6c00,0x6c00,0x6c00,0xfe00,0x6c00,0x6c00,0xfe00,0x6c00,0x6c00,0x6c00,0x0000,0x0000,0x0000,0x0000, // u0023\n  0x0000,0x1000,0x1000,0x7c00,0xd600,0xd000,0xd000,0x7c00,0x1600,0x1600,0xd600,0x7c00,0x1000,0x1000,0x0000,0x0000, // u0024\n  0x0000,0x0000,0x6600,0xd600,0x6c00,0x0c00,0x1800,0x1800,0x3000,0x3600,0x6b00,0x6600,0x0000,0x0000,0x0000,0x0000, // u0025\n  0x0000,0x0000,0x3800,0x6c00,0x6c00,0x3800,0x7600,0xdc00,0xcc00,0xcc00,0xdc00,0x7600,0x0000,0x0000,0x0000,0x0000, // u0026\n  0x0000,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0027\n  0x0000,0x0000,0x0c00,0x1800,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x1800,0x0c00,0x0000,0x0000,0x0000,0x0000, // u0028\n  0x0000,0x0000,0x3000,0x1800,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1800,0x3000,0x0000,0x0000,0x0000,0x0000, // u0029\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6c00,0x3800,0xfe00,0x3800,0x6c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x7e00,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x3000,0x0000,0x0000,0x0000, // u002c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u002e\n  0x0000,0x0000,0x0600,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000, // u002f\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xce00,0xde00,0xf600,0xe600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0030\n  0x0000,0x0000,0x1800,0x3800,0x7800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0031\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u0032\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0x0600,0x3c00,0x0600,0x0600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0033\n  0x0000,0x0000,0x0600,0x0e00,0x1e00,0x3600,0x6600,0xc600,0xfe00,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u0034\n  0x0000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xfc00,0x0600,0x0600,0x0600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0035\n  0x0000,0x0000,0x3c00,0x6000,0xc000,0xc000,0xfc00,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0036\n  0x0000,0x0000,0xfe00,0x0600,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000, // u0037\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0x7c00,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0038\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x0c00,0x7800,0x0000,0x0000,0x0000,0x0000, // u0039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x0000,0x0000,0x0000,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u003a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x0000,0x0000,0x0000,0x1800,0x1800,0x3000,0x0000,0x0000,0x0000, // u003b\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x1800,0x3000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0000,0x0000,0x0000,0x0000, // u003c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0000,0x0000,0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003d\n  0x0000,0x0000,0x0000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0c00,0x1800,0x3000,0x6000,0x0000,0x0000,0x0000,0x0000, // u003e\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0x0c00,0x1800,0x1800,0x0000,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u003f\n  0x0000,0x0000,0x7c00,0xc600,0xce00,0xd600,0xd600,0xd600,0xd600,0xce00,0xc000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0040\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u0041\n  0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xfc00,0xc600,0xc600,0xc600,0xc600,0xfc00,0x0000,0x0000,0x0000,0x0000, // u0042\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc000,0xc000,0xc000,0xc000,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0043\n  0x0000,0x0000,0xf800,0xcc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xcc00,0xf800,0x0000,0x0000,0x0000,0x0000, // u0044\n  0x0000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u0045\n  0x0000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000,0x0000,0x0000, // u0046\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc000,0xc000,0xde00,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0047\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u0048\n  0x0000,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0049\n  0x0000,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xcc00,0xcc00,0x7800,0x0000,0x0000,0x0000,0x0000, // u004a\n  0x0000,0x0000,0xc600,0xc600,0xcc00,0xd800,0xf000,0xf000,0xd800,0xcc00,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u004b\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u004c\n  0x0000,0x0000,0x8200,0xc600,0xee00,0xfe00,0xd600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u004d\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xe600,0xf600,0xde00,0xce00,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u004e\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u004f\n  0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xfc00,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000,0x0000,0x0000, // u0050\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xde00,0x7c00,0x0600,0x0000,0x0000,0x0000, // u0051\n  0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xfc00,0xf000,0xd800,0xcc00,0xc600,0x0000,0x0000,0x0000,0x0000, // u0052\n  0x0000,0x0000,0x7c00,0xc600,0xc000,0xc000,0x7c00,0x0600,0x0600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0053\n  0x0000,0x0000,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u0054\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0055\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0x6c00,0x6c00,0x6c00,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000, // u0056\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xd600,0xfe00,0xee00,0xc600,0x8200,0x0000,0x0000,0x0000,0x0000, // u0057\n  0x0000,0x0000,0xc600,0xc600,0x6c00,0x6c00,0x3800,0x3800,0x6c00,0x6c00,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u0058\n  0x0000,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u0059\n  0x0000,0x0000,0xfe00,0x0600,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u005a\n  0x0000,0x0000,0x3c00,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3c00,0x0000,0x0000,0x0000,0x0000, // u005b\n  0x0000,0x0000,0x6000,0x6000,0x3000,0x3000,0x1800,0x1800,0x0c00,0x0c00,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u005c\n  0x0000,0x0000,0x3c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x3c00,0x0000,0x0000,0x0000,0x0000, // u005d\n  0x0000,0x1800,0x3c00,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0000,0x0000, // u005f\n  0x3000,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0060\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0061\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xfc00,0x0000,0x0000,0x0000,0x0000, // u0062\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc000,0xc000,0xc000,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0063\n  0x0000,0x0000,0x0600,0x0600,0x0600,0x7e00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0064\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0065\n  0x0000,0x0000,0x1e00,0x3000,0x3000,0xfc00,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000, // u0066\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x7c00,0x0000, // u0067\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u0068\n  0x0000,0x0000,0x1800,0x1800,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0069\n  0x0000,0x0000,0x0600,0x0600,0x0000,0x0e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x6600,0x6600,0x3c00,0x0000, // u006a\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xc600,0xcc00,0xd800,0xf000,0xd800,0xcc00,0xc600,0x0000,0x0000,0x0000,0x0000, // u006b\n  0x0000,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u006c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0x0000,0x0000,0x0000,0x0000, // u006d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u006e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u006f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xfc00,0xc000,0xc000,0xc000,0x0000, // u0070\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x0600,0x0000, // u0071\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xde00,0xf000,0xe000,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000,0x0000,0x0000, // u0072\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0xc000,0xc000,0x7c00,0x0600,0x0600,0xfc00,0x0000,0x0000,0x0000,0x0000, // u0073\n  0x0000,0x0000,0x3000,0x3000,0x3000,0xfc00,0x3000,0x3000,0x3000,0x3000,0x3000,0x1e00,0x0000,0x0000,0x0000,0x0000, // u0074\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0075\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0x6c00,0x6c00,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000, // u0076\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xd600,0xd600,0xd600,0xd600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0077\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0x6c00,0x3800,0x6c00,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u0078\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x7c00,0x0000, // u0079\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0c00,0x1800,0x3000,0x6000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u007a\n  0x0000,0x0000,0x1c00,0x3000,0x3000,0x3000,0x6000,0x3000,0x3000,0x3000,0x3000,0x1c00,0x0000,0x0000,0x0000,0x0000, // u007b\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u007c\n  0x0000,0x0000,0x7000,0x1800,0x1800,0x1800,0x0c00,0x1800,0x1800,0x1800,0x1800,0x7000,0x0000,0x0000,0x0000,0x0000, // u007d\n  0x0000,0x7300,0xdb00,0xce00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a0\n  0x0000,0x0000,0x1800,0x1800,0x0000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u00a1\n  0x0000,0x0000,0x0000,0x1000,0x1000,0x7c00,0xd600,0xd000,0xd000,0xd000,0xd600,0x7c00,0x1000,0x1000,0x0000,0x0000, // u00a2\n  0x0000,0x0000,0x3800,0x6c00,0x6000,0x6000,0xf800,0x6000,0x6000,0x6000,0x6600,0xfe00,0x0000,0x0000,0x0000,0x0000, // u00a3\n  0x0000,0x0000,0x0000,0x0000,0x6600,0x3c00,0x6600,0x6600,0x6600,0x3c00,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a4\n  0x0000,0x0000,0xc300,0xc300,0x6600,0x3c00,0x1800,0x7e00,0x1800,0x7e00,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u00a5\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u00a6\n  0x0000,0x3c00,0x6600,0x6000,0x3800,0x6c00,0x6600,0x6600,0x3600,0x1c00,0x0600,0x6600,0x3c00,0x0000,0x0000,0x0000, // u00a7\n  0x6c00,0x6c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a8\n  0x0000,0x0000,0x0000,0x7e00,0x8100,0x9900,0xa500,0xa100,0xa500,0x9900,0x8100,0x7e00,0x0000,0x0000,0x0000,0x0000, // u00a9\n  0x0000,0x3c00,0x0600,0x3e00,0x6600,0x3e00,0x0000,0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1b00,0x3600,0x6c00,0xd800,0x6c00,0x3600,0x1b00,0x0000,0x0000,0x0000,0x0000, // u00ab\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ac\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ad\n  0x0000,0x0000,0x0000,0x7e00,0x8100,0xb900,0xa500,0xb900,0xa900,0xa500,0x8100,0x7e00,0x0000,0x0000,0x0000,0x0000, // u00ae\n  0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00af\n  0x0000,0x3800,0x6c00,0x6c00,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x7e00,0x1800,0x1800,0x0000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u00b1\n  0x0000,0x3800,0x6c00,0x0c00,0x1800,0x3000,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b2\n  0x0000,0x7800,0x0c00,0x3800,0x0c00,0x0c00,0x7800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b3\n  0x1800,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xce00,0xf600,0xc000,0xc000,0xc000,0x0000, // u00b5\n  0x0000,0x0000,0x7e00,0xd600,0xd600,0xd600,0xd600,0x7600,0x1600,0x1600,0x1600,0x1600,0x0000,0x0000,0x0000,0x0000, // u00b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x6000,0x0000, // u00b8\n  0x0000,0x1800,0x3800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b9\n  0x0000,0x3c00,0x6600,0x6600,0x6600,0x3c00,0x0000,0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xd800,0x6c00,0x3600,0x1b00,0x3600,0x6c00,0xd800,0x0000,0x0000,0x0000,0x0000, // u00bb\n  0x0000,0x6000,0xe000,0x6200,0x6600,0x6c00,0x1800,0x3000,0x6600,0xce00,0x9a00,0x3e00,0x0600,0x0600,0x0000,0x0000, // u00bc\n  0x0000,0x6000,0xe000,0x6200,0x6600,0x6c00,0x1800,0x3000,0x6000,0xdc00,0xb600,0x0c00,0x1800,0x3e00,0x0000,0x0000, // u00bd\n  0x0000,0xe000,0x3000,0x6200,0x3600,0xec00,0x1800,0x3000,0x6600,0xce00,0x9a00,0x3e00,0x0600,0x0600,0x0000,0x0000, // u00be\n  0x0000,0x0000,0x3000,0x3000,0x0000,0x3000,0x3000,0x6000,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u00bf\n  0x3000,0x1800,0x0000,0x7c00,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u00c0\n  0x1800,0x3000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u00c1\n  0x3800,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u00c2\n  0x7600,0xdc00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u00c3\n  0x6c00,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u00c4\n  0x3800,0x6c00,0x3800,0x7c00,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u00c5\n  0x0000,0x0000,0x7e00,0xd800,0xd800,0xd800,0xfe00,0xd800,0xd800,0xd800,0xd800,0xde00,0x0000,0x0000,0x0000,0x0000, // u00c6\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc000,0xc000,0xc000,0xc000,0xc600,0xc600,0x7c00,0x3000,0x3000,0x6000,0x0000, // u00c7\n  0x3000,0x1800,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u00c8\n  0x1800,0x3000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u00c9\n  0x3800,0x6c00,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u00ca\n  0x6c00,0x6c00,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u00cb\n  0x3000,0x1800,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00cc\n  0x0c00,0x1800,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00cd\n  0x3800,0x6c00,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00ce\n  0x6600,0x6600,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00cf\n  0x0000,0x0000,0x7800,0x6c00,0x6600,0x6600,0xf600,0x6600,0x6600,0x6600,0x6c00,0x7800,0x0000,0x0000,0x0000,0x0000, // u00d0\n  0x7600,0xdc00,0x0000,0xc600,0xc600,0xe600,0xf600,0xde00,0xce00,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u00d1\n  0x3000,0x1800,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u00d2\n  0x1800,0x3000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u00d3\n  0x3800,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u00d4\n  0x7600,0xdc00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u00d5\n  0x6c00,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u00d6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0x6c00,0x3800,0x3800,0x6c00,0xc600,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d7\n  0x0000,0x0000,0x7c00,0xc700,0xc600,0xce00,0xde00,0xf600,0xe600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u00d8\n  0x3000,0x1800,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u00d9\n  0x1800,0x3000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u00da\n  0x3800,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u00db\n  0x6c00,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u00dc\n  0x0c00,0x1800,0xc300,0xc300,0x6600,0x6600,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u00dd\n  0x0000,0x0000,0xc000,0xc000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xfc00,0xc000,0xc000,0x0000,0x0000,0x0000,0x0000, // u00de\n  0x0000,0x0000,0x7800,0xcc00,0xcc00,0xc800,0xfc00,0xc600,0xc600,0xc600,0xe600,0xdc00,0x0000,0x0000,0x0000,0x0000, // u00df\n  0x0000,0x0000,0x3000,0x1800,0x0000,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u00e0\n  0x0000,0x0000,0x1800,0x3000,0x0000,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u00e1\n  0x0000,0x0000,0x3800,0x6c00,0x0000,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u00e2\n  0x0000,0x0000,0x7600,0xdc00,0x0000,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u00e3\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u00e4\n  0x0000,0x0000,0x3800,0x6c00,0x3800,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u00e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6c00,0x1600,0x1600,0x7e00,0xd000,0xd000,0x6c00,0x0000,0x0000,0x0000,0x0000, // u00e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc000,0xc000,0xc000,0xc600,0x7c00,0x3000,0x3000,0x6000,0x0000, // u00e7\n  0x0000,0x0000,0x3000,0x1800,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000,0x0000,0x0000, // u00e8\n  0x0000,0x0000,0x1800,0x3000,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000,0x0000,0x0000, // u00e9\n  0x0000,0x0000,0x3800,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000,0x0000,0x0000, // u00ea\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000,0x0000,0x0000, // u00eb\n  0x0000,0x0000,0x3000,0x1800,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00ec\n  0x0000,0x0000,0x0c00,0x1800,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00ed\n  0x0000,0x0000,0x3800,0x6c00,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00ee\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u00ef\n  0x0000,0x0000,0x6800,0x3000,0x5800,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u00f0\n  0x0000,0x0000,0x7600,0xdc00,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u00f1\n  0x0000,0x0000,0x3000,0x1800,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u00f2\n  0x0000,0x0000,0x1800,0x3000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u00f3\n  0x0000,0x0000,0x3800,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u00f4\n  0x0000,0x0000,0x7600,0xdc00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u00f5\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u00f6\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x0000,0x7e00,0x0000,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3d00,0x6700,0x6e00,0x7e00,0x7600,0xe600,0xbc00,0x0000,0x0000,0x0000,0x0000, // u00f8\n  0x0000,0x0000,0x3000,0x1800,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u00f9\n  0x0000,0x0000,0x1800,0x3000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u00fa\n  0x0000,0x0000,0x3800,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u00fb\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u00fc\n  0x0000,0x0000,0x1800,0x3000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x7c00,0x0000, // u00fd\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xfc00,0xc000,0xc000,0xc000,0x0000, // u00fe\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x7c00,0x0000, // u00ff\n  0x7c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u0100\n  0x0000,0x0000,0x0000,0x7c00,0x0000,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0101\n  0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u0102\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0103\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0600,0x0c00,0x0700,0x0000, // u0104\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0c00,0x0700,0x0000, // u0105\n  0x1800,0x3000,0x0000,0x7c00,0xc600,0xc600,0xc000,0xc000,0xc000,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0106\n  0x0000,0x0000,0x1800,0x3000,0x0000,0x7c00,0xc600,0xc000,0xc000,0xc000,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0107\n  0x3800,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xc000,0xc000,0xc000,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0108\n  0x0000,0x0000,0x3800,0x6c00,0x0000,0x7c00,0xc600,0xc000,0xc000,0xc000,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0109\n  0x1800,0x1800,0x0000,0x7c00,0xc600,0xc600,0xc000,0xc000,0xc000,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u010a\n  0x0000,0x0000,0x1800,0x1800,0x0000,0x7c00,0xc600,0xc000,0xc000,0xc000,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u010b\n  0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc600,0xc000,0xc000,0xc000,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u010c\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc000,0xc000,0xc000,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u010d\n  0x6c00,0x3800,0x0000,0xf800,0xcc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xcc00,0xf800,0x0000,0x0000,0x0000,0x0000, // u010e\n  0x6c00,0x3800,0x0600,0x0600,0x0600,0x7e00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u010f\n  0x0000,0x0000,0x7800,0x6c00,0x6600,0x6600,0xf600,0x6600,0x6600,0x6600,0x6c00,0x7800,0x0000,0x0000,0x0000,0x0000, // u0110\n  0x0000,0x0000,0x0600,0x1f00,0x0600,0x7e00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0111\n  0x7c00,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u0112\n  0x0000,0x0000,0x0000,0x7c00,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0113\n  0x6c00,0x3800,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u0114\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0115\n  0x1800,0x1800,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u0116\n  0x0000,0x0000,0x1800,0x1800,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0117\n  0x0000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xc000,0xfe00,0x0600,0x0c00,0x0700,0x0000, // u0118\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x1800,0x3000,0x1c00,0x0000, // u0119\n  0x6c00,0x3800,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u011a\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000,0x0000,0x0000, // u011b\n  0x3800,0x6c00,0x0000,0x7c00,0xc600,0xc000,0xc000,0xde00,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u011c\n  0x0000,0x0000,0x3800,0x6c00,0x0000,0x7e00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x7c00,0x0000, // u011d\n  0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc000,0xc000,0xde00,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u011e\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x7e00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x7c00,0x0000, // u011f\n  0x1800,0x1800,0x0000,0x7c00,0xc600,0xc000,0xc000,0xde00,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0120\n  0x0000,0x0000,0x1800,0x1800,0x0000,0x7e00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x7c00,0x0000, // u0121\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc000,0xc000,0xde00,0xc600,0xc600,0xc600,0x7c00,0x0000,0x3000,0x3000,0x6000, // u0122\n  0x0000,0x0c00,0x1800,0x1800,0x0000,0x7e00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x7c00,0x0000, // u0123\n  0x3800,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u0124\n  0x1c00,0x3600,0xc000,0xc000,0xc000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u0125\n  0x0000,0x0000,0x6600,0xff00,0x6600,0x6600,0x7e00,0x6600,0x6600,0x6600,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000, // u0126\n  0x0000,0x0000,0x6000,0xf800,0x6000,0x7c00,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000, // u0127\n  0x7600,0xdc00,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0128\n  0x0000,0x0000,0x7600,0xdc00,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0129\n  0x7e00,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u012a\n  0x0000,0x0000,0x0000,0x7c00,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u012b\n  0x6c00,0x3800,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u012c\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u012d\n  0x0000,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x1800,0x3000,0x1c00,0x0000, // u012e\n  0x0000,0x0000,0x1800,0x1800,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x1800,0x3000,0x1c00,0x0000, // u012f\n  0x1800,0x1800,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0130\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0131\n  0x0000,0x0000,0xcf00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xf600,0xf600,0xdc00,0x0000,0x0000,0x0000,0x0000, // u0132\n  0x0000,0x0000,0xc600,0xc600,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x3600,0x3600,0x1c00,0x0000, // u0133\n  0x1c00,0x3600,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xcc00,0xcc00,0x7800,0x0000,0x0000,0x0000,0x0000, // u0134\n  0x0000,0x0000,0x0e00,0x1b00,0x0000,0x0e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x6600,0x6600,0x3c00,0x0000, // u0135\n  0x0000,0x0000,0xc600,0xc600,0xcc00,0xd800,0xf000,0xf000,0xd800,0xcc00,0xc600,0xc600,0x0000,0x3000,0x3000,0x6000, // u0136\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xc600,0xcc00,0xd800,0xf000,0xd800,0xcc00,0xc600,0x0000,0x3000,0x3000,0x6000, // u0137\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xcc00,0xd800,0xf000,0xd800,0xcc00,0xc600,0x0000,0x0000,0x0000,0x0000, // u0138\n  0x6000,0xc000,0x0000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u0139\n  0x0c00,0x1800,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u013a\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xfe00,0x0000,0x3000,0x3000,0x6000, // u013b\n  0x0000,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x1800,0x1800,0x3000, // u013c\n  0x6c00,0x3800,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u013d\n  0x6c00,0x3800,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u013e\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xc000,0xcc00,0xcc00,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u013f\n  0x0000,0x0000,0x3800,0x1800,0x1800,0x1800,0x1b00,0x1b00,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0140\n  0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x7000,0xe000,0x6000,0x6000,0x6000,0x7f00,0x0000,0x0000,0x0000,0x0000, // u0141\n  0x0000,0x0000,0x3800,0x1800,0x1800,0x1800,0x1c00,0x3800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0142\n  0x1800,0x3000,0xc600,0xc600,0xc600,0xe600,0xf600,0xde00,0xce00,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u0143\n  0x0000,0x0000,0x1800,0x3000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u0144\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xe600,0xf600,0xde00,0xce00,0xc600,0xc600,0xc600,0x0000,0x3000,0x3000,0x6000, // u0145\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x3000,0x3000,0x6000, // u0146\n  0x6c00,0x3800,0xc600,0xc600,0xc600,0xe600,0xf600,0xde00,0xce00,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u0147\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u0148\n  0x0000,0x6000,0x6000,0xc000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u0149\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xe600,0xf600,0xde00,0xce00,0xc600,0xc600,0xc600,0x0600,0x0600,0x1c00,0x0000, // u014a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0600,0x0600,0x1c00,0x0000, // u014b\n  0x7c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u014c\n  0x0000,0x0000,0x0000,0x7c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u014d\n  0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u014e\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u014f\n  0x3600,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0150\n  0x0000,0x0000,0x3600,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0151\n  0x0000,0x0000,0x7e00,0xd800,0xd800,0xd800,0xde00,0xd800,0xd800,0xd800,0xd800,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0152\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xd600,0xd600,0xde00,0xd000,0xd000,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0153\n  0x1800,0x3000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xfc00,0xf000,0xd800,0xcc00,0xc600,0x0000,0x0000,0x0000,0x0000, // u0154\n  0x0000,0x0000,0x1800,0x3000,0x0000,0xde00,0xf000,0xe000,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000,0x0000,0x0000, // u0155\n  0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xfc00,0xf000,0xd800,0xcc00,0xc600,0x0000,0x3000,0x3000,0x6000, // u0156\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6f00,0x7800,0x7000,0x6000,0x6000,0x6000,0x6000,0x0000,0x6000,0x6000,0xc000, // u0157\n  0x6c00,0x3800,0x0000,0xfc00,0xc600,0xc600,0xc600,0xfc00,0xf000,0xd800,0xcc00,0xc600,0x0000,0x0000,0x0000,0x0000, // u0158\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0xde00,0xf000,0xe000,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000,0x0000,0x0000, // u0159\n  0x1800,0x3000,0x0000,0x7c00,0xc600,0xc000,0xc000,0x7c00,0x0600,0x0600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u015a\n  0x0000,0x0000,0x0c00,0x1800,0x0000,0x7e00,0xc000,0xc000,0x7c00,0x0600,0x0600,0xfc00,0x0000,0x0000,0x0000,0x0000, // u015b\n  0x3800,0x6c00,0x0000,0x7c00,0xc600,0xc000,0xc000,0x7c00,0x0600,0x0600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u015c\n  0x0000,0x0000,0x3800,0x6c00,0x0000,0x7e00,0xc000,0xc000,0x7c00,0x0600,0x0600,0xfc00,0x0000,0x0000,0x0000,0x0000, // u015d\n  0x0000,0x0000,0x7c00,0xc600,0xc000,0xc000,0x7c00,0x0600,0x0600,0xc600,0xc600,0x7c00,0x3000,0x3000,0x6000,0x0000, // u015e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0xc000,0xc000,0x7c00,0x0600,0x0600,0xfc00,0x3000,0x3000,0x6000,0x0000, // u015f\n  0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc000,0xc000,0x7c00,0x0600,0x0600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0160\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x7e00,0xc000,0xc000,0x7c00,0x0600,0x0600,0xfc00,0x0000,0x0000,0x0000,0x0000, // u0161\n  0x0000,0x0000,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0c00,0x0c00,0x1800,0x0000, // u0162\n  0x0000,0x0000,0x3000,0x3000,0x3000,0xfc00,0x3000,0x3000,0x3000,0x3000,0x3000,0x1e00,0x0c00,0x0c00,0x1800,0x0000, // u0163\n  0x6c00,0x3800,0x0000,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u0164\n  0x6c00,0x3800,0x0000,0x3000,0x3000,0xfc00,0x3000,0x3000,0x3000,0x3000,0x3000,0x1e00,0x0000,0x0000,0x0000,0x0000, // u0165\n  0x0000,0x0000,0xff00,0x1800,0x1800,0x1800,0x7e00,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u0166\n  0x0000,0x0000,0x3000,0x3000,0x3000,0xfc00,0x3000,0x7800,0x3000,0x3000,0x3000,0x1e00,0x0000,0x0000,0x0000,0x0000, // u0167\n  0x7600,0xdc00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0168\n  0x0000,0x0000,0x7600,0xdc00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0169\n  0x7c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u016a\n  0x0000,0x0000,0x0000,0x7c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u016b\n  0x6c00,0x3800,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u016c\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u016d\n  0x3800,0x6c00,0x3800,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u016e\n  0x0000,0x0000,0x3800,0x6c00,0x3800,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u016f\n  0x3600,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0170\n  0x0000,0x0000,0x3600,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0171\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x1800,0x3000,0x1c00,0x0000, // u0172\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0c00,0x0700,0x0000, // u0173\n  0x3800,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xd600,0xfe00,0xee00,0xc600,0x8200,0x0000,0x0000,0x0000,0x0000, // u0174\n  0x0000,0x0000,0x3800,0x6c00,0x0000,0xc600,0xc600,0xd600,0xd600,0xd600,0xd600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0175\n  0x3800,0x6c00,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u0176\n  0x0000,0x0000,0x3800,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x7c00,0x0000, // u0177\n  0x6600,0x6600,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u0178\n  0x1800,0x3000,0x0000,0xfe00,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u0179\n  0x0000,0x0000,0x1800,0x3000,0x0000,0xfe00,0x0c00,0x1800,0x3000,0x6000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u017a\n  0x1800,0x1800,0x0000,0xfe00,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u017b\n  0x0000,0x0000,0x1800,0x1800,0x0000,0xfe00,0x0c00,0x1800,0x3000,0x6000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u017c\n  0x6c00,0x3800,0x0000,0xfe00,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u017d\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0xfe00,0x0c00,0x1800,0x3000,0x6000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u017e\n  0x0000,0x0000,0x1e00,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000, // u017f\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0x0600,0x0600,0x0600,0x0600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0186\n  0x0000,0x0000,0xfe00,0x0600,0x0600,0x0600,0x3e00,0x0600,0x0600,0x0600,0x0600,0xfe00,0x0000,0x0000,0x0000,0x0000, // u018e\n  0x0000,0x0000,0x7c00,0xc600,0x0600,0x0600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u018f\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc000,0x7800,0xc000,0xc000,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0190\n  0x0000,0x0000,0x0e00,0x1b00,0x1800,0x1800,0x7e00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xd800,0x7000,0x0000, // u0192\n  0x0000,0x0000,0x6600,0x6600,0x6600,0x7600,0x7e00,0x6e00,0x6600,0x6600,0x6600,0x6600,0x6000,0x6000,0xc000,0x0000, // u019d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0600,0x0600,0x0600,0x0000, // u019e\n  0x0000,0x0000,0xfe00,0x0600,0x0c00,0x1800,0xfe00,0x3000,0x6000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u01b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0c00,0x1800,0xfc00,0x3000,0x6000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u01b6\n  0x0000,0x0000,0xfe00,0x0600,0x0c00,0x1800,0x3c00,0x0600,0x0600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u01b7\n  0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u01cd\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u01ce\n  0x6c00,0x3800,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u01cf\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u01d0\n  0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u01d1\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u01d2\n  0x6c00,0x3800,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u01d3\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u01d4\n  0x7c00,0x0000,0x7e00,0xd800,0xd800,0xd800,0xfe00,0xd800,0xd800,0xd800,0xd800,0xde00,0x0000,0x0000,0x0000,0x0000, // u01e2\n  0x0000,0x0000,0x0000,0x7c00,0x0000,0x6c00,0x1600,0x1600,0x7e00,0xd000,0xd000,0x6c00,0x0000,0x0000,0x0000,0x0000, // u01e3\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc000,0xc000,0xde00,0xc600,0xdf00,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u01e4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0xc600,0xc600,0xdf00,0xc600,0xc600,0x7e00,0x0600,0x0600,0x7c00,0x0000, // u01e5\n  0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc000,0xc000,0xde00,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u01e6\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x7e00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x7c00,0x0000, // u01e7\n  0x6c00,0x3800,0xc600,0xc600,0xcc00,0xd800,0xf000,0xf000,0xd800,0xcc00,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u01e8\n  0x6c00,0x3800,0xc000,0xc000,0xc000,0xc600,0xcc00,0xd800,0xf000,0xd800,0xcc00,0xc600,0x0000,0x0000,0x0000,0x0000, // u01e9\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x1800,0x3000,0x1c00,0x0000, // u01ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x1800,0x3000,0x1c00,0x0000, // u01eb\n  0x7c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x1800,0x3000,0x1c00,0x0000, // u01ec\n  0x0000,0x0000,0x0000,0x7c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x1800,0x3000,0x1c00,0x0000, // u01ed\n  0x6c00,0x3800,0x0000,0xfe00,0x0c00,0x1800,0x3c00,0x0600,0x0600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u01ee\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0xfe00,0x0600,0x0c00,0x1800,0x3c00,0x0600,0x0600,0xc600,0xc600,0x7c00,0x0000, // u01ef\n  0x0000,0x0000,0x1b00,0x0e00,0x0000,0x0e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x6600,0x6600,0x3c00,0x0000, // u01f0\n  0x1800,0x3000,0x0000,0x7c00,0xc600,0xc000,0xc000,0xde00,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u01f4\n  0x0000,0x0000,0x0c00,0x1800,0x0000,0x7e00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x7c00,0x0000, // u01f5\n  0x0c00,0x1800,0x0000,0x7e00,0xd800,0xd800,0xd800,0xfe00,0xd800,0xd800,0xd800,0xde00,0x0000,0x0000,0x0000,0x0000, // u01fc\n  0x0000,0x0000,0x0c00,0x1800,0x0000,0x6c00,0x1600,0x1600,0x7e00,0xd000,0xd000,0x6c00,0x0000,0x0000,0x0000,0x0000, // u01fd\n  0x1800,0x3000,0x0000,0x7c00,0xc700,0xc600,0xce00,0xde00,0xf600,0xe600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u01fe\n  0x0000,0x0000,0x1800,0x3000,0x0000,0x3d00,0x6700,0x6e00,0x7e00,0x7600,0xe600,0xbc00,0x0000,0x0000,0x0000,0x0000, // u01ff\n  0x0000,0x0000,0x7c00,0xc600,0xc000,0xc000,0x7c00,0x0600,0x0600,0xc600,0xc600,0x7c00,0x0000,0x3000,0x3000,0x6000, // u0218\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0xc000,0xc000,0x7c00,0x0600,0x0600,0xfc00,0x0000,0x3000,0x3000,0x6000, // u0219\n  0x0000,0x0000,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x1800,0x1800,0x3000, // u021a\n  0x0000,0x0000,0x3000,0x3000,0x3000,0xfc00,0x3000,0x3000,0x3000,0x3000,0x3000,0x1e00,0x0000,0x0c00,0x0c00,0x1800, // u021b\n  0x7e00,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u0232\n  0x0000,0x0000,0x0000,0x7c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x7c00,0x0000, // u0233\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x6600,0x6600,0x3c00,0x0000, // u0237\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0x0600,0x0600,0x0600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0254\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xfe00,0x0600,0x0600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0258\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0600,0x0600,0xfe00,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0259\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc000,0x7800,0xc000,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u025b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6000,0x6000,0xc000,0x0000, // u0272\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0600,0x0c00,0x1800,0x3c00,0x0600,0x0600,0xc600,0xc600,0x7c00,0x0000, // u0292\n  0x1800,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bb\n  0x1800,0x1800,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bc\n  0x3000,0x3000,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bd\n  0x3800,0x6c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02c6\n  0x6c00,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02c7\n  0x6c00,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02d8\n  0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02d9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x3000,0x1c00,0x0000, // u02db\n  0x7600,0xdc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02dc\n  0x3600,0x6c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02dd\n  0x3000,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0300\n  0x1800,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0301\n  0x3800,0x6c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0302\n  0x7600,0xdc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0303\n  0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0304\n  0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0305\n  0x6c00,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0306\n  0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0307\n  0x6c00,0x6c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0308\n  0x3800,0x6c00,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030a\n  0x3600,0x6c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030b\n  0x6c00,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x0000, // u0329\n  0x6000,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0384\n  0x1800,0x3000,0x0000,0x6c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0385\n  0x6000,0xc000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u0386\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0387\n  0x6000,0xc000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u0388\n  0x6000,0xc000,0x0000,0xc600,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u0389\n  0x6000,0xc000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u038a\n  0x6000,0xc000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u038c\n  0x6000,0xc000,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u038e\n  0x6000,0xc000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x6c00,0x6c00,0xee00,0x0000,0x0000,0x0000,0x0000, // u038f\n  0x1800,0x3000,0xd800,0xd800,0x0000,0x7000,0x3000,0x3000,0x3000,0x3000,0x3000,0x1c00,0x0000,0x0000,0x0000,0x0000, // u0390\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u0391\n  0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xfc00,0xc600,0xc600,0xc600,0xc600,0xfc00,0x0000,0x0000,0x0000,0x0000, // u0392\n  0x0000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000,0x0000,0x0000, // u0393\n  0x0000,0x0000,0x1000,0x1000,0x3800,0x3800,0x6c00,0x6c00,0x6c00,0xc600,0xc600,0xfe00,0x0000,0x0000,0x0000,0x0000, // u0394\n  0x0000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u0395\n  0x0000,0x0000,0xfe00,0x0600,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u0396\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u0397\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xd600,0xd600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0398\n  0x0000,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0399\n  0x0000,0x0000,0xc600,0xc600,0xcc00,0xd800,0xf000,0xf000,0xd800,0xcc00,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u039a\n  0x0000,0x0000,0x1000,0x1000,0x3800,0x3800,0x6c00,0x6c00,0x6c00,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u039b\n  0x0000,0x0000,0x8200,0xc600,0xee00,0xfe00,0xd600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u039c\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xe600,0xf600,0xde00,0xce00,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u039d\n  0x0000,0x0000,0xfe00,0x0000,0x0000,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u039e\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u039f\n  0x0000,0x0000,0xfe00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u03a0\n  0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xfc00,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000,0x0000,0x0000, // u03a1\n  0x0000,0x0000,0xfe00,0xc000,0x6000,0x3000,0x1800,0x1800,0x3000,0x6000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u03a3\n  0x0000,0x0000,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u03a4\n  0x0000,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u03a5\n  0x0000,0x0000,0x1000,0x7c00,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0x7c00,0x1000,0x0000,0x0000,0x0000,0x0000, // u03a6\n  0x0000,0x0000,0xc600,0xc600,0x6c00,0x6c00,0x3800,0x3800,0x6c00,0x6c00,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u03a7\n  0x0000,0x0000,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0x7c00,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u03a8\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x6c00,0x6c00,0xee00,0x0000,0x0000,0x0000,0x0000, // u03a9\n  0x6600,0x6600,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u03aa\n  0x6600,0x6600,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u03ab\n  0x0000,0x0000,0x1800,0x3000,0x0000,0x7a00,0xce00,0xcc00,0xcc00,0xcc00,0xce00,0x7a00,0x0000,0x0000,0x0000,0x0000, // u03ac\n  0x0000,0x0000,0x1800,0x3000,0x0000,0x7c00,0xc600,0xc000,0x7800,0xc000,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u03ad\n  0x0000,0x0000,0x1800,0x3000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0600,0x0600,0x0600,0x0000, // u03ae\n  0x0000,0x0000,0x1800,0x3000,0x0000,0x7000,0x3000,0x3000,0x3000,0x3000,0x3000,0x1c00,0x0000,0x0000,0x0000,0x0000, // u03af\n  0x1800,0x3000,0x0000,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u03b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7a00,0xce00,0xcc00,0xcc00,0xcc00,0xce00,0x7a00,0x0000,0x0000,0x0000,0x0000, // u03b1\n  0x0000,0x0000,0x7800,0xcc00,0xcc00,0xc800,0xfc00,0xc600,0xc600,0xc600,0xc600,0xfc00,0xc000,0xc000,0xc000,0x0000, // u03b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x3c00,0x1800,0x1800,0x1800,0x1800,0x0000, // u03b3\n  0x0000,0x0000,0x7e00,0x3000,0x1800,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u03b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc000,0x7800,0xc000,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u03b5\n  0x0000,0x0000,0xfe00,0x0c00,0x1800,0x3000,0x6000,0xc000,0xc000,0xc000,0xc000,0x7c00,0x0600,0x0600,0x0c00,0x0000, // u03b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0600,0x0600,0x0600,0x0000, // u03b7\n  0x0000,0x0000,0x3c00,0x6600,0x6600,0x6600,0x7e00,0x6600,0x6600,0x6600,0x6600,0x3c00,0x0000,0x0000,0x0000,0x0000, // u03b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x3000,0x3000,0x3000,0x3000,0x3000,0x1c00,0x0000,0x0000,0x0000,0x0000, // u03b9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xcc00,0xd800,0xf000,0xd800,0xcc00,0xc600,0x0000,0x0000,0x0000,0x0000, // u03ba\n  0x0000,0x0000,0x3000,0x3000,0x1800,0x1800,0x3c00,0x3c00,0x6600,0x6600,0xc300,0xc300,0x0000,0x0000,0x0000,0x0000, // u03bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xce00,0xf600,0xc000,0xc000,0xc000,0x0000, // u03bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0x6c00,0x6c00,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000, // u03bd\n  0x0000,0x0000,0x7e00,0xc000,0xc000,0xc000,0x7c00,0xc000,0xc000,0xc000,0xc000,0x7c00,0x0600,0x0600,0x0c00,0x0000, // u03be\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u03bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u03c0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xfc00,0xc000,0xc000,0xc000,0x0000, // u03c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc000,0xc000,0xc000,0xc000,0x7c00,0x0600,0x0600,0x0c00,0x0000, // u03c2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6600,0x6600,0x6600,0x6600,0x6600,0x3c00,0x0000,0x0000,0x0000,0x0000, // u03c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x0e00,0x0000,0x0000,0x0000,0x0000, // u03c4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u03c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4c00,0xd600,0xd600,0xd600,0xd600,0xd600,0x7c00,0x1000,0x1000,0x1000,0x0000, // u03c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0x6c00,0x6c00,0x3800,0x3800,0x6c00,0x6c00,0xc600,0xc600,0x0000, // u03c7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0x7c00,0x1000,0x1000,0x1000,0x0000, // u03c8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0xc600,0xd600,0xd600,0xd600,0xfe00,0x6c00,0x0000,0x0000,0x0000,0x0000, // u03c9\n  0x0000,0x0000,0xd800,0xd800,0x0000,0x7000,0x3000,0x3000,0x3000,0x3000,0x3000,0x1c00,0x0000,0x0000,0x0000,0x0000, // u03ca\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u03cb\n  0x0000,0x0000,0x1800,0x3000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u03cc\n  0x0000,0x0000,0x1800,0x3000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u03cd\n  0x0000,0x0000,0x1800,0x3000,0x0000,0x4400,0xc600,0xd600,0xd600,0xd600,0xfe00,0x6c00,0x0000,0x0000,0x0000,0x0000, // u03ce\n  0x0000,0x0000,0x3c00,0x6600,0x6600,0x6600,0x3f00,0x0600,0xe600,0x6600,0x6600,0x3c00,0x0000,0x0000,0x0000,0x0000, // u03d1\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x7c00,0xd600,0xd600,0xd600,0xd600,0xd600,0x7c00,0x1000,0x0000,0x0000,0x0000, // u03d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xe300,0x3600,0x1c00,0x1800,0x3800,0x6c00,0xc700,0x0000,0x0000,0x0000,0x0000, // u03f0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xfc00,0xc000,0xc000,0x7c00,0x0000, // u03f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc000,0xc000,0xc000,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u03f2\n  0x0000,0x0000,0x0600,0x0600,0x0000,0x0e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x6600,0x6600,0x3c00,0x0000, // u03f3\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u03f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x6000,0xc000,0xfc00,0xc000,0x6000,0x3e00,0x0000,0x0000,0x0000,0x0000, // u03f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0x0c00,0x0600,0x7e00,0x0600,0x0c00,0xf800,0x0000,0x0000,0x0000,0x0000, // u03f6\n  0x3000,0x1800,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u0400\n  0x6c00,0x6c00,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u0401\n  0x0000,0x0000,0xf000,0x6000,0x6000,0x7c00,0x6600,0x6600,0x6600,0x6600,0x6600,0x6c00,0x0000,0x0000,0x0000,0x0000, // u0402\n  0x1800,0x3000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000,0x0000,0x0000, // u0403\n  0x0000,0x0000,0x7c00,0xc600,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0404\n  0x0000,0x0000,0x7c00,0xc600,0xc000,0xc000,0x7c00,0x0600,0x0600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0405\n  0x0000,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0406\n  0x6600,0x6600,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0407\n  0x0000,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xcc00,0xcc00,0x7800,0x0000,0x0000,0x0000,0x0000, // u0408\n  0x0000,0x0000,0x3000,0x7000,0xd000,0xdc00,0xd600,0xd600,0xd600,0xd600,0xd600,0x9c00,0x0000,0x0000,0x0000,0x0000, // u0409\n  0x0000,0x0000,0xd000,0xd000,0xd000,0xdc00,0xf600,0xd600,0xd600,0xd600,0xd600,0xdc00,0x0000,0x0000,0x0000,0x0000, // u040a\n  0x0000,0x0000,0xf000,0x6000,0x6000,0x7c00,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000, // u040b\n  0x1800,0x3000,0xc600,0xc600,0xcc00,0xd800,0xf000,0xf000,0xd800,0xcc00,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u040c\n  0x3000,0x1800,0xc600,0xc600,0xc600,0xce00,0xde00,0xf600,0xe600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u040d\n  0x6c00,0x3800,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x0600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u040e\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xfe00,0x3800,0x3800,0x0000,0x0000, // u040f\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u0410\n  0x0000,0x0000,0xfc00,0xc000,0xc000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xfc00,0x0000,0x0000,0x0000,0x0000, // u0411\n  0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xfc00,0xc600,0xc600,0xc600,0xc600,0xfc00,0x0000,0x0000,0x0000,0x0000, // u0412\n  0x0000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000,0x0000,0x0000, // u0413\n  0x0000,0x0000,0x3e00,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0xff00,0xc300,0x0000,0x0000,0x0000, // u0414\n  0x0000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u0415\n  0x0000,0x0000,0xd600,0xd600,0xd600,0x7c00,0x3800,0x7c00,0xd600,0xd600,0xd600,0xd600,0x0000,0x0000,0x0000,0x0000, // u0416\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0x0600,0x3c00,0x0600,0x0600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0417\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xce00,0xde00,0xf600,0xe600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u0418\n  0x6c00,0x3800,0xc600,0xc600,0xc600,0xce00,0xde00,0xf600,0xe600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u0419\n  0x0000,0x0000,0xc600,0xc600,0xcc00,0xd800,0xf000,0xf000,0xd800,0xcc00,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u041a\n  0x0000,0x0000,0x1e00,0x3600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0xc600,0x0000,0x0000,0x0000,0x0000, // u041b\n  0x0000,0x0000,0x8200,0xc600,0xee00,0xfe00,0xd600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u041c\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u041d\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u041e\n  0x0000,0x0000,0xfe00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u041f\n  0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xfc00,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000,0x0000,0x0000, // u0420\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc000,0xc000,0xc000,0xc000,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0421\n  0x0000,0x0000,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u0422\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x0600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0423\n  0x0000,0x1000,0x7c00,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0x7c00,0x1000,0x0000,0x0000,0x0000, // u0424\n  0x0000,0x0000,0xc600,0xc600,0x6c00,0x6c00,0x3800,0x3800,0x6c00,0x6c00,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u0425\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7f00,0x0300,0x0300,0x0000,0x0000, // u0426\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u0427\n  0x0000,0x0000,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0428\n  0x0000,0x0000,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0x7f00,0x0300,0x0300,0x0000,0x0000, // u0429\n  0x0000,0x0000,0xe000,0x6000,0x6000,0x7c00,0x6600,0x6600,0x6600,0x6600,0x6600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u042a\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xe600,0xd600,0xd600,0xd600,0xd600,0xd600,0xe600,0x0000,0x0000,0x0000,0x0000, // u042b\n  0x0000,0x0000,0x6000,0x6000,0x6000,0x7c00,0x6600,0x6600,0x6600,0x6600,0x6600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u042c\n  0x0000,0x0000,0x7c00,0xc600,0x0600,0x0600,0x3e00,0x0600,0x0600,0x0600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u042d\n  0x0000,0x0000,0xcc00,0xd600,0xd600,0xd600,0xd600,0xf600,0xd600,0xd600,0xd600,0xcc00,0x0000,0x0000,0x0000,0x0000, // u042e\n  0x0000,0x0000,0x7e00,0xc600,0xc600,0xc600,0xc600,0x7e00,0x1e00,0x3600,0x6600,0xc600,0x0000,0x0000,0x0000,0x0000, // u042f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0430\n  0x0000,0x0000,0x7c00,0xc000,0xc000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xfc00,0x0000,0x0000,0x0000,0x0000, // u0431\n  0x0000,0x0000,0x7800,0xcc00,0xcc00,0xc800,0xfc00,0xc600,0xc600,0xc600,0xc600,0xfc00,0x0000,0x0000,0x0000,0x0000, // u0432\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000,0x0000,0x0000, // u0433\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x7c00,0x0000, // u0434\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0435\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xd600,0xd600,0x7c00,0x3800,0x7c00,0xd600,0xd600,0x0000,0x0000,0x0000,0x0000, // u0436\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0x0600,0x3c00,0x0600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0437\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0438\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0439\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xcc00,0xd800,0xf000,0xd800,0xcc00,0xc600,0x0000,0x0000,0x0000,0x0000, // u043a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x6600,0x6600,0x6600,0x6600,0x6600,0xc600,0x0000,0x0000,0x0000,0x0000, // u043b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xee00,0xfe00,0xd600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u043c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u043d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u043e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u043f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xfc00,0xc000,0xc000,0xc000,0x0000, // u0440\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc000,0xc000,0xc000,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0441\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u0442\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x7c00,0x0000, // u0443\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x7c00,0xd600,0xd600,0xd600,0xd600,0xd600,0x7c00,0x1000,0x0000,0x0000,0x0000, // u0444\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0x6c00,0x3800,0x6c00,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u0445\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7f00,0x0300,0x0300,0x0000,0x0000, // u0446\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u0447\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u0448\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0x7f00,0x0300,0x0300,0x0000,0x0000, // u0449\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xe000,0x6000,0x7c00,0x6600,0x6600,0x6600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u044a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xe600,0xd600,0xd600,0xd600,0xe600,0x0000,0x0000,0x0000,0x0000, // u044b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x7c00,0x6600,0x6600,0x6600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u044c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0x0600,0x3e00,0x0600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u044d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xcc00,0xd600,0xd600,0xf600,0xd600,0xd600,0xcc00,0x0000,0x0000,0x0000,0x0000, // u044e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0xc600,0xc600,0x7e00,0x3600,0x6600,0xc600,0x0000,0x0000,0x0000,0x0000, // u044f\n  0x0000,0x0000,0x3000,0x1800,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0450\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0451\n  0x0000,0x0000,0x6000,0xf800,0x6000,0x7c00,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x0600,0x0600,0x1c00,0x0000, // u0452\n  0x0000,0x0000,0x1800,0x3000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000,0x0000,0x0000, // u0453\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc000,0xf800,0xc000,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0454\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0xc000,0xc000,0x7c00,0x0600,0x0600,0xfc00,0x0000,0x0000,0x0000,0x0000, // u0455\n  0x0000,0x0000,0x1800,0x1800,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0456\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u0457\n  0x0000,0x0000,0x0600,0x0600,0x0000,0x0e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x6600,0x6600,0x3c00,0x0000, // u0458\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0xd000,0xdc00,0xd600,0xd600,0xd600,0x9c00,0x0000,0x0000,0x0000,0x0000, // u0459\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xd000,0xd000,0xdc00,0xf600,0xd600,0xd600,0xdc00,0x0000,0x0000,0x0000,0x0000, // u045a\n  0x0000,0x0000,0x6000,0xf800,0x6000,0x7c00,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000, // u045b\n  0x0000,0x0000,0x1800,0x3000,0x0000,0xc600,0xcc00,0xd800,0xf000,0xd800,0xcc00,0xc600,0x0000,0x0000,0x0000,0x0000, // u045c\n  0x0000,0x0000,0x3000,0x1800,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u045d\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x7c00,0x0000, // u045e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xfe00,0x3800,0x3800,0x0000,0x0000, // u045f\n  0x0000,0x0000,0x6000,0xf800,0x6000,0x7c00,0x6600,0x6600,0x6600,0x6600,0x6600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0462\n  0x0000,0x0000,0x6000,0x6000,0xf800,0x6000,0x6000,0x7c00,0x6600,0x6600,0x6600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u0463\n  0x0000,0x0000,0xfe00,0xc600,0x6c00,0x6c00,0x3800,0x7c00,0xd600,0xd600,0xd600,0xd600,0x0000,0x0000,0x0000,0x0000, // u046a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x6c00,0x2800,0x3800,0x7c00,0xd600,0xd600,0x0000,0x0000,0x0000,0x0000, // u046b\n  0x0600,0x0600,0xfe00,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000,0x0000,0x0000, // u0490\n  0x0000,0x0000,0x0000,0x0600,0x0600,0xfe00,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0x0000,0x0000,0x0000,0x0000, // u0491\n  0x0000,0x0000,0x7f00,0x6000,0x6000,0x6000,0xfc00,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000, // u0492\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6000,0x6000,0xfc00,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000, // u0493\n  0x0000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xc000,0xfc00,0xc600,0xc600,0xc600,0xc600,0x0600,0x0c00,0x0000,0x0000, // u0494\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xc000,0xc000,0xf800,0xcc00,0xcc00,0xcc00,0x0c00,0x1800,0x0000,0x0000, // u0495\n  0x0000,0x0000,0xd600,0xd600,0xd600,0x7c00,0x3800,0x7c00,0xd600,0xd600,0xd600,0xd700,0x0300,0x0300,0x0000,0x0000, // u0496\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xd600,0xd600,0x7c00,0x3800,0x7c00,0xd600,0xd700,0x0300,0x0300,0x0000,0x0000, // u0497\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0x0600,0x3c00,0x0600,0x0600,0xc600,0xc600,0x7c00,0x3000,0x3000,0x3000,0x0000, // u0498\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0x0600,0x3c00,0x0600,0xc600,0x7c00,0x3000,0x3000,0x3000,0x0000, // u0499\n  0x0000,0x0000,0xc600,0xc600,0xcc00,0xd800,0xf000,0xf000,0xd800,0xcc00,0xc600,0xc700,0x0300,0x0300,0x0000,0x0000, // u049a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xcc00,0xd800,0xf000,0xd800,0xcc00,0xc700,0x0300,0x0300,0x0000,0x0000, // u049b\n  0x0000,0x0000,0xc600,0xc600,0xd600,0xdc00,0xf800,0xf800,0xdc00,0xd600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u049c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xd600,0xdc00,0xf800,0xdc00,0xd600,0xc600,0x0000,0x0000,0x0000,0x0000, // u049d\n  0x0000,0x0000,0xe300,0xe300,0x6600,0x6c00,0x7800,0x7800,0x6c00,0x6600,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000, // u04a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xe300,0x6600,0x6c00,0x7800,0x6c00,0x6600,0x6300,0x0000,0x0000,0x0000,0x0000, // u04a1\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0xc700,0x0300,0x0300,0x0000,0x0000, // u04a2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc700,0x0300,0x0300,0x0000,0x0000, // u04a3\n  0x0000,0x0000,0xcf00,0xcc00,0xcc00,0xcc00,0xfc00,0xcc00,0xcc00,0xcc00,0xcc00,0xcc00,0x0000,0x0000,0x0000,0x0000, // u04a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xcf00,0xcc00,0xcc00,0xfc00,0xcc00,0xcc00,0xcc00,0x0000,0x0000,0x0000,0x0000, // u04a5\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc000,0xc000,0xc000,0xc000,0xc600,0xc600,0x7c00,0x3000,0x3000,0x3000,0x0000, // u04aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc000,0xc000,0xc000,0xc600,0x7c00,0x3000,0x3000,0x3000,0x0000, // u04ab\n  0x0000,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u04ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x3c00,0x1800,0x1800,0x1800,0x1800,0x0000, // u04af\n  0x0000,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x1800,0x7e00,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u04b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x3c00,0x1800,0x7e00,0x1800,0x1800,0x0000, // u04b1\n  0x0000,0x0000,0xc600,0xc600,0x6c00,0x6c00,0x3800,0x3800,0x6c00,0x6c00,0xc600,0xc700,0x0300,0x0300,0x0000,0x0000, // u04b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0x6c00,0x3800,0x6c00,0xc600,0xc700,0x0300,0x0300,0x0000,0x0000, // u04b3\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x0600,0x0700,0x0300,0x0300,0x0000,0x0000, // u04b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x0700,0x0300,0x0300,0x0000,0x0000, // u04b7\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xd600,0xd600,0x7e00,0x1600,0x1600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u04b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xd600,0xd600,0x7e00,0x1600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u04b9\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xc000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u04ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0xc000,0xfc00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u04bb\n  0x0000,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u04c0\n  0x6c00,0x3800,0x0000,0xd600,0xd600,0xd600,0x7c00,0x3800,0x7c00,0xd600,0xd600,0xd600,0x0000,0x0000,0x0000,0x0000, // u04c1\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0xd600,0xd600,0x7c00,0x3800,0x7c00,0xd600,0xd600,0x0000,0x0000,0x0000,0x0000, // u04c2\n  0x0000,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u04cf\n  0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u04d0\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u04d1\n  0x6c00,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u04d2\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0x7c00,0x0600,0x7e00,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u04d3\n  0x0000,0x0000,0x7e00,0xd800,0xd800,0xd800,0xfe00,0xd800,0xd800,0xd800,0xd800,0xde00,0x0000,0x0000,0x0000,0x0000, // u04d4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6c00,0x1600,0x1600,0x7e00,0xd000,0xd000,0x6c00,0x0000,0x0000,0x0000,0x0000, // u04d5\n  0x6c00,0x3800,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u04d6\n  0x0000,0x0000,0x6c00,0x3800,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000,0x0000,0x0000, // u04d7\n  0x0000,0x0000,0x7c00,0xc600,0x0600,0x0600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u04d8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0600,0x0600,0xfe00,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u04d9\n  0x6c00,0x6c00,0x0000,0x7c00,0xc600,0x0600,0x0600,0xfe00,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u04da\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0x7c00,0x0600,0x0600,0xfe00,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u04db\n  0x6c00,0x6c00,0x0000,0xd600,0xd600,0xd600,0x7c00,0x3800,0x7c00,0xd600,0xd600,0xd600,0x0000,0x0000,0x0000,0x0000, // u04dc\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0xd600,0xd600,0x7c00,0x3800,0x7c00,0xd600,0xd600,0x0000,0x0000,0x0000,0x0000, // u04dd\n  0x6c00,0x6c00,0x0000,0x7c00,0xc600,0xc600,0x0600,0x3c00,0x0600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u04de\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0x7c00,0xc600,0x0600,0x3c00,0x0600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u04df\n  0x7c00,0x0000,0xc600,0xc600,0xc600,0xce00,0xde00,0xf600,0xe600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u04e2\n  0x0000,0x0000,0x0000,0x7c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u04e3\n  0x6c00,0x6c00,0x0000,0xc600,0xc600,0xc600,0xce00,0xde00,0xf600,0xe600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u04e4\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x0000,0x0000,0x0000, // u04e5\n  0x6c00,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u04e6\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u04e7\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u04e8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u04e9\n  0x6c00,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u04ea\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u04eb\n  0x6c00,0x6c00,0x0000,0x7c00,0xc600,0x0600,0x0600,0x3e00,0x0600,0x0600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u04ec\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0x7c00,0xc600,0x0600,0x3e00,0x0600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u04ed\n  0x7c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x0600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u04ee\n  0x0000,0x0000,0x0000,0x7c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x7c00,0x0000, // u04ef\n  0x6c00,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x0600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u04f0\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x7c00,0x0000, // u04f1\n  0x3600,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x0600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u04f2\n  0x0000,0x0000,0x3600,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x7c00,0x0000, // u04f3\n  0x6c00,0x6c00,0x0000,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u04f4\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u04f5\n  0x6c00,0x6c00,0x0000,0xc600,0xc600,0xc600,0xe600,0xd600,0xd600,0xd600,0xd600,0xe600,0x0000,0x0000,0x0000,0x0000, // u04f8\n  0x0000,0x0000,0x6c00,0x6c00,0x0000,0xc600,0xc600,0xe600,0xd600,0xd600,0xd600,0xe600,0x0000,0x0000,0x0000,0x0000, // u04f9\n  0x0000,0x0000,0xc600,0xc600,0x6600,0x6600,0x3c00,0x7800,0xcc00,0xcc00,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u05d0\n  0x0000,0x0000,0xfc00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xff00,0x0000,0x0000,0x0000,0x0000, // u05d1\n  0x0000,0x0000,0x7800,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x3600,0x6300,0xc300,0x0000,0x0000,0x0000,0x0000, // u05d2\n  0x0000,0x0000,0xff00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u05d3\n  0x0000,0x0000,0xfc00,0x0600,0x0600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u05d4\n  0x0000,0x0000,0x7000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u05d5\n  0x0000,0x0000,0x7e00,0x0c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u05d6\n  0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u05d7\n  0x0000,0x0000,0xcc00,0xce00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u05d8\n  0x0000,0x0000,0x7000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d9\n  0x0000,0x0000,0xfc00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000, // u05da\n  0x0000,0x0000,0xfc00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfc00,0x0000,0x0000,0x0000,0x0000, // u05db\n  0xc000,0xc000,0xfe00,0x0600,0x0600,0x0600,0x0600,0x0c00,0x1800,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000, // u05dc\n  0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xfe00,0x0000,0x0000,0x0000,0x0000, // u05dd\n  0x0000,0x0000,0xdc00,0x7600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6e00,0x0000,0x0000,0x0000,0x0000, // u05de\n  0x0000,0x0000,0xf000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u05df\n  0x0000,0x0000,0x7800,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x7c00,0x0000,0x0000,0x0000,0x0000, // u05e0\n  0x0000,0x0000,0xfc00,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x3c00,0x0000,0x0000,0x0000,0x0000, // u05e1\n  0x0000,0x0000,0xc600,0xc600,0xc600,0x6600,0x6600,0x3600,0x3600,0x1c00,0x3800,0xe000,0x0000,0x0000,0x0000,0x0000, // u05e2\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0x6600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000, // u05e3\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0x6600,0x0600,0x0600,0x0600,0x0600,0xfc00,0x0000,0x0000,0x0000,0x0000, // u05e4\n  0x0000,0x0000,0x6300,0x6300,0x3300,0x3600,0x1c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000, // u05e5\n  0x0000,0x0000,0xc600,0xc600,0x6600,0x6c00,0x3800,0x3000,0x1800,0x1800,0x0c00,0xfc00,0x0000,0x0000,0x0000,0x0000, // u05e6\n  0x0000,0x0000,0xfe00,0x0600,0x0600,0xc600,0xc600,0xcc00,0xd800,0xd800,0xd800,0xd800,0xc000,0xc000,0xc000,0x0000, // u05e7\n  0x0000,0x0000,0xfc00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u05e8\n  0x0000,0x0000,0xd600,0xd600,0xd600,0xd600,0xd600,0xe600,0xc600,0xc600,0xcc00,0xf800,0x0000,0x0000,0x0000,0x0000, // u05e9\n  0x0000,0x0000,0xfc00,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0xc600,0x0000,0x0000,0x0000,0x0000, // u05ea\n  0x0000,0x0000,0xf800,0xcc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xcc00,0xf800,0x0000,0x3000,0x3000,0x0000, // u1e0c\n  0x0000,0x0000,0x0600,0x0600,0x0600,0x7e00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x1800,0x1800,0x0000, // u1e0d\n  0x0000,0x0000,0xc600,0xc600,0xcc00,0xd800,0xf000,0xf000,0xd800,0xcc00,0xc600,0xc600,0x0000,0x7c00,0x0000,0x0000, // u1e34\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xc600,0xcc00,0xd800,0xf000,0xd800,0xcc00,0xc600,0x0000,0x7c00,0x0000,0x0000, // u1e35\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xfe00,0x0000,0x1800,0x1800,0x0000, // u1e36\n  0x0000,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x1800,0x1800,0x0000, // u1e37\n  0x1800,0x1800,0x8200,0xc600,0xee00,0xfe00,0xd600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u1e40\n  0x0000,0x0000,0x3000,0x3000,0x0000,0xfc00,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0x0000,0x0000,0x0000,0x0000, // u1e41\n  0x0000,0x0000,0x8200,0xc600,0xee00,0xfe00,0xd600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x1800,0x1800,0x0000, // u1e42\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xd600,0xd600,0xd600,0xd600,0xd600,0xd600,0x0000,0x1800,0x1800,0x0000, // u1e43\n  0x1800,0x1800,0xc600,0xc600,0xc600,0xe600,0xf600,0xde00,0xce00,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u1e44\n  0x0000,0x0000,0x3000,0x3000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u1e45\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xe600,0xf600,0xde00,0xce00,0xc600,0xc600,0xc600,0x0000,0x1800,0x1800,0x0000, // u1e46\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x1800,0x1800,0x0000, // u1e47\n  0x0000,0x0000,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x1800,0x1800,0x0000, // u1e6c\n  0x0000,0x0000,0x3000,0x3000,0x3000,0xfc00,0x3000,0x3000,0x3000,0x3000,0x3000,0x1e00,0x0000,0x0c00,0x0c00,0x0000, // u1e6d\n  0x0000,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xc000,0xfe00,0x0000,0x1800,0x1800,0x0000, // u1eb8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x1800,0x1800,0x0000, // u1eb9\n  0x7600,0xdc00,0x0000,0xfe00,0xc000,0xc000,0xc000,0xf800,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u1ebc\n  0x0000,0x0000,0x7600,0xdc00,0x0000,0x7c00,0xc600,0xc600,0xfe00,0xc000,0xc000,0x7c00,0x0000,0x0000,0x0000,0x0000, // u1ebd\n  0x0000,0x0000,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x1800,0x1800,0x0000, // u1eca\n  0x0000,0x0000,0x1800,0x1800,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x1800,0x1800,0x0000, // u1ecb\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x1800,0x1800,0x0000, // u1ecc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x1800,0x1800,0x0000, // u1ecd\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x1800,0x1800,0x0000, // u1ee4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0000,0x1800,0x1800,0x0000, // u1ee5\n  0x7600,0xdc00,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u1ef8\n  0x0000,0x0000,0x7600,0xdc00,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7e00,0x0600,0x0600,0x7c00,0x0000, // u1ef9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2001\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2002\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2003\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2004\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2005\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2006\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2007\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2008\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2009\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2010\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2011\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2012\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2013\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2014\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2015\n  0x0000,0x0000,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x0000,0x0000,0x0000,0x0000, // u2016\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0000,0xfe00, // u2017\n  0x0000,0x1800,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2018\n  0x0000,0x1800,0x1800,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2019\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x3000,0x0000,0x0000,0x0000, // u201a\n  0x0000,0x3000,0x3000,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201b\n  0x0000,0x6600,0xcc00,0xcc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201c\n  0x0000,0x3300,0x3300,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0xcc00,0x0000,0x0000,0x0000, // u201e\n  0x0000,0xcc00,0xcc00,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201f\n  0x0000,0x0000,0x1800,0x1800,0x7e00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u2020\n  0x0000,0x0000,0x1800,0x1800,0x7e00,0x1800,0x1800,0x1800,0x1800,0x7e00,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u2021\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x3c00,0x3c00,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2022\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xdb00,0xdb00,0x0000,0x0000,0x0000,0x0000, // u2026\n  0x0000,0x0000,0xec00,0xac00,0xf800,0x1800,0x3000,0x3000,0x6000,0x7f00,0xd500,0xdf00,0x0000,0x0000,0x0000,0x0000, // u2030\n  0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2032\n  0x0000,0x6600,0x6600,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2033\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x1800,0x3000,0x6000,0x3000,0x1800,0x0c00,0x0000,0x0000,0x0000,0x0000, // u2039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x3000,0x1800,0x0c00,0x1800,0x3000,0x6000,0x0000,0x0000,0x0000,0x0000, // u203a\n  0x0000,0x0000,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000, // u203c\n  0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u203e\n  0x0000,0x3800,0x6c00,0x6c00,0x6c00,0x6c00,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2070\n  0x1800,0x0000,0x3800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2071\n  0x0000,0x0c00,0x1c00,0x3400,0x7e00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2074\n  0x0000,0x7800,0x6000,0x7800,0x0c00,0x0c00,0x7800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2075\n  0x0000,0x3800,0x6000,0x7800,0x6c00,0x6c00,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2076\n  0x0000,0x7c00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2077\n  0x0000,0x3800,0x6c00,0x3800,0x6c00,0x6c00,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2078\n  0x0000,0x3800,0x6c00,0x6c00,0x3c00,0x0c00,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2079\n  0x0000,0x0000,0x1800,0x1800,0x7e00,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207a\n  0x0000,0x0000,0x0000,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207b\n  0x0000,0x0000,0x0000,0x7c00,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207c\n  0x0000,0x1800,0x3000,0x3000,0x3000,0x3000,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207d\n  0x0000,0x3000,0x1800,0x1800,0x1800,0x1800,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207e\n  0x0000,0x0000,0x7800,0x6c00,0x6c00,0x6c00,0x6c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x6c00,0x6c00,0x6c00,0x6c00,0x3800,0x0000,0x0000,0x0000, // u2080\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x3800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000, // u2081\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x6c00,0x0c00,0x1800,0x3000,0x7c00,0x0000,0x0000,0x0000, // u2082\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7800,0x0c00,0x3800,0x0c00,0x0c00,0x7800,0x0000,0x0000,0x0000, // u2083\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x1c00,0x3400,0x7e00,0x0c00,0x0c00,0x0000,0x0000,0x0000, // u2084\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7800,0x6000,0x7800,0x0c00,0x0c00,0x7800,0x0000,0x0000,0x0000, // u2085\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x6000,0x7800,0x6c00,0x6c00,0x3800,0x0000,0x0000,0x0000, // u2086\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x0000,0x0000,0x0000, // u2087\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x6c00,0x3800,0x6c00,0x6c00,0x3800,0x0000,0x0000,0x0000, // u2088\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x6c00,0x6c00,0x3c00,0x0c00,0x3800,0x0000,0x0000,0x0000, // u2089\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x7e00,0x1800,0x1800,0x0000,0x0000,0x0000, // u208a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u208b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0000,0x7c00,0x0000,0x0000,0x0000,0x0000, // u208c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x3000,0x3000,0x3000,0x3000,0x1800,0x0000,0x0000,0x0000, // u208d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x1800,0x1800,0x1800,0x1800,0x3000,0x0000,0x0000,0x0000, // u208e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x0c00,0x3c00,0x6c00,0x3c00,0x0000,0x0000,0x0000, // u2090\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x6c00,0x7c00,0x6000,0x3c00,0x0000,0x0000,0x0000, // u2091\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x6c00,0x6c00,0x6c00,0x3800,0x0000,0x0000,0x0000, // u2092\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x3c00,0x1800,0x3c00,0x6600,0x0000,0x0000,0x0000, // u2093\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7800,0x0c00,0x7c00,0x6c00,0x3800,0x0000,0x0000,0x0000, // u2094\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x7800,0x6c00,0x6c00,0x6c00,0x6c00,0x0000,0x0000,0x0000, // u2095\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6600,0x6c00,0x7800,0x6c00,0x6600,0x0000,0x0000,0x0000, // u2096\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000, // u2097\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xd600,0xd600,0xd600,0xd600,0x0000,0x0000,0x0000, // u2098\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7800,0x6c00,0x6c00,0x6c00,0x7800,0x6000,0x6000,0x0000, // u209a\n  0x0000,0x0000,0xf800,0xcc00,0xcc00,0xcc00,0xfa00,0xc600,0xcf00,0xc600,0xc600,0xc300,0x0000,0x0000,0x0000,0x0000, // u20a7\n  0x0000,0x0000,0xf200,0x8a00,0x8a00,0xaa00,0xaa00,0xaa00,0xaa00,0xa200,0xa200,0xbc00,0x0000,0x0000,0x0000,0x0000, // u20aa\n  0x0000,0x0000,0x0000,0x1e00,0x3300,0x6000,0xfc00,0x6000,0xfc00,0x6000,0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000, // u20ac\n  0x0000,0x0000,0xff00,0x1800,0x1800,0x1e00,0x7800,0x1e00,0x7800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u20ae\n  0x0000,0x0000,0x3c00,0x5200,0x5200,0x5000,0x5000,0x5000,0x5000,0x5200,0x5200,0x3c00,0x0000,0x0000,0x0000,0x0000, // u2102\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xfc00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u210e\n  0x0000,0x0000,0x6000,0xf800,0x6000,0x7c00,0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000, // u210f\n  0x0000,0x0000,0x4200,0x4200,0x6200,0x5200,0x6a00,0x5600,0x4a00,0x4600,0x4200,0x4200,0x0000,0x0000,0x0000,0x0000, // u2115\n  0x0000,0x0000,0x9600,0x9600,0x9600,0xd000,0xf000,0xf000,0xb000,0x9600,0x9000,0x9600,0x0000,0x0000,0x0000,0x0000, // u2116\n  0x0000,0x0000,0x3c00,0x5200,0x5200,0x5200,0x5200,0x5200,0x5200,0x5200,0x5a00,0x3c00,0x0600,0x0000,0x0000,0x0000, // u211a\n  0x0000,0x0000,0xf800,0xa400,0xa400,0xa400,0xa400,0xb800,0xa800,0xb400,0xaa00,0xe600,0x0000,0x0000,0x0000,0x0000, // u211d\n  0x0000,0x0000,0xfb00,0x5500,0x5500,0x5100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2122\n  0x0000,0x0000,0x7e00,0x0200,0x0600,0x0a00,0x1400,0x2800,0x5000,0x6000,0x4000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u2124\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x6c00,0x6c00,0xee00,0x0000,0x0000,0x0000,0x0000, // u2126\n  0x0000,0x0000,0x6600,0x6600,0x3300,0x3300,0x3e00,0x7c00,0xcc00,0xcc00,0xc600,0x6600,0x0000,0x0000,0x0000,0x0000, // u2135\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x6000,0xfe00,0xfe00,0x6000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2190\n  0x0000,0x0000,0x1800,0x3c00,0x7e00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u2191\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0c00,0xfe00,0xfe00,0x0c00,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000, // u2192\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x7e00,0x3c00,0x1800,0x0000,0x0000,0x0000,0x0000, // u2193\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2400,0x6600,0xff00,0xff00,0x6600,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2194\n  0x0000,0x0000,0x1800,0x3c00,0x7e00,0x1800,0x1800,0x1800,0x1800,0x7e00,0x3c00,0x1800,0x0000,0x0000,0x0000,0x0000, // u2195\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2200,0x6200,0xfe00,0xfe00,0x6200,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x8800,0x8c00,0xfe00,0xfe00,0x8c00,0x8800,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a6\n  0x0000,0x0000,0x1800,0x3c00,0x7e00,0x1800,0x1800,0x1800,0x7e00,0x3c00,0x1800,0x7e00,0x0000,0x0000,0x0000,0x0000, // u21a8\n  0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x2600,0x6600,0xfe00,0xfe00,0x6000,0x2000,0x0000,0x0000,0x0000,0x0000, // u21b5\n  0x0000,0x0000,0x0000,0xf800,0x3800,0x6800,0xcb00,0xc300,0xc300,0x6600,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u21bb\n  0x0000,0x0000,0x0000,0x2000,0x6000,0xfe00,0xfe00,0x0000,0xfe00,0xfe00,0x0c00,0x0800,0x0000,0x0000,0x0000,0x0000, // u21cb\n  0x0000,0x0000,0x0000,0x0800,0x0c00,0xfe00,0xfe00,0x0000,0xfe00,0xfe00,0x6000,0x2000,0x0000,0x0000,0x0000,0x0000, // u21cc\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x3e00,0x7e00,0xe000,0x7e00,0x3e00,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d0\n  0x0000,0x0000,0x1000,0x3800,0x7c00,0xee00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x0000,0x0000,0x0000,0x0000, // u21d1\n  0x0000,0x0000,0x0000,0x0000,0x1000,0xf800,0xfc00,0x0e00,0xfc00,0xf800,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d2\n  0x0000,0x0000,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0xee00,0x7c00,0x3800,0x1000,0x0000,0x0000,0x0000,0x0000, // u21d3\n  0x0000,0x0000,0x0000,0x0000,0x2400,0x7e00,0xff00,0xc300,0xff00,0x7e00,0x2400,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d4\n  0x0000,0x0000,0x1000,0x3800,0x7c00,0xee00,0x6c00,0x6c00,0xee00,0x7c00,0x3800,0x1000,0x0000,0x0000,0x0000,0x0000, // u21d5\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xfe00,0x6c00,0x6c00,0x6c00,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000, // u2200\n  0x0000,0x0000,0x0000,0xfe00,0x0600,0x0600,0x0600,0xfe00,0x0600,0x0600,0x0600,0xfe00,0x0000,0x0000,0x0000,0x0000, // u2203\n  0x0000,0x0000,0x0c00,0xfe00,0x1e00,0x1600,0x3600,0xfe00,0x3600,0x6600,0x6600,0xfe00,0xc000,0x0000,0x0000,0x0000, // u2204\n  0x0000,0x0000,0x0600,0x0c00,0x7c00,0xce00,0xde00,0xf600,0xe600,0x7c00,0x6000,0xc000,0x0000,0x0000,0x0000,0x0000, // u2205\n  0x0000,0x0000,0x1000,0x1000,0x3800,0x3800,0x6c00,0x6c00,0x6c00,0xc600,0xc600,0xfe00,0x0000,0x0000,0x0000,0x0000, // u2206\n  0x0000,0x0000,0xfe00,0xc600,0xc600,0x6c00,0x6c00,0x6c00,0x3800,0x3800,0x1000,0x1000,0x0000,0x0000,0x0000,0x0000, // u2207\n  0x0000,0x0000,0x0000,0x3e00,0x6000,0xc000,0xc000,0xfe00,0xc000,0xc000,0x6000,0x3e00,0x0000,0x0000,0x0000,0x0000, // u2208\n  0x0000,0x0000,0x0600,0x3e00,0x6c00,0xcc00,0xd800,0xfe00,0xd800,0xf000,0x7000,0x7e00,0x6000,0x0000,0x0000,0x0000, // u2209\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x6000,0xc000,0xfe00,0xc000,0x6000,0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u220a\n  0x0000,0x0000,0x0000,0xf800,0x0c00,0x0600,0x0600,0xfe00,0x0600,0x0600,0x0c00,0xf800,0x0000,0x0000,0x0000,0x0000, // u220b\n  0x0000,0x0000,0xc000,0xf800,0x6c00,0x6600,0x3600,0xfe00,0x3600,0x1e00,0x1c00,0xfc00,0x0c00,0x0000,0x0000,0x0000, // u220c\n  0x0000,0x0000,0x0000,0x0000,0xf800,0x0c00,0x0600,0xfe00,0x0600,0x0c00,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000, // u220d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2212\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0000,0x1800,0x1800,0x7e00,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u2213\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x0000,0x1800,0x1800,0x7e00,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u2214\n  0x0000,0x0000,0x0000,0x0000,0x0200,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0x8000,0x0000,0x0000,0x0000,0x0000, // u2215\n  0x0000,0x0000,0x0000,0x0000,0x8000,0xc000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0200,0x0000,0x0000,0x0000,0x0000, // u2216\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2219\n  0x0000,0x0e00,0x0c00,0x0c00,0x0c00,0x0c00,0xcc00,0xcc00,0xcc00,0x6c00,0x3c00,0x1c00,0x0000,0x0000,0x0000,0x0000, // u221a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0xd600,0xd600,0xd600,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u221e\n  0x0000,0x0000,0x0000,0x0000,0xc000,0xc000,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u221f\n  0x0000,0x0000,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x0000,0x0000,0x0000,0x0000, // u2225\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x3c00,0x3c00,0x6600,0x6600,0xc300,0xc300,0x0000,0x0000,0x0000,0x0000, // u2227\n  0x0000,0x0000,0x0000,0x0000,0xc300,0xc300,0x6600,0x6600,0x3c00,0x3c00,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u2228\n  0x0000,0x0000,0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u2229\n  0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u222a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7600,0xdc00,0x0000,0x7600,0xdc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2248\n  0x0000,0x0000,0x0000,0x0000,0x0600,0xfe00,0x1800,0x3000,0xfe00,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2260\n  0x0000,0x0000,0x0000,0x0000,0xfe00,0x0000,0x0000,0xfe00,0x0000,0x0000,0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2261\n  0x0000,0x0000,0x0000,0x0c00,0x1800,0x3000,0x6000,0x3000,0x1800,0x0c00,0x0000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u2264\n  0x0000,0x0000,0x0000,0x3000,0x1800,0x0c00,0x0600,0x0c00,0x1800,0x3000,0x0000,0x7e00,0x0000,0x0000,0x0000,0x0000, // u2265\n  0x0000,0x0000,0x0000,0x0900,0x1b00,0x3600,0x6c00,0xd800,0x6c00,0x3600,0x1b00,0x0900,0x0000,0x0000,0x0000,0x0000, // u226a\n  0x0000,0x0000,0x0000,0x9000,0xd800,0x6c00,0x3600,0x1b00,0x3600,0x6c00,0xd800,0x9000,0x0000,0x0000,0x0000,0x0000, // u226b\n  0x0000,0x0000,0x0000,0x0000,0x7e00,0xc000,0xc000,0xc000,0xc000,0xc000,0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2282\n  0x0000,0x0000,0x0000,0x0000,0xfc00,0x0600,0x0600,0x0600,0x0600,0x0600,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2283\n  0x0000,0x0000,0x0000,0x7e00,0xc000,0xc000,0xc000,0xc000,0xc000,0x7e00,0x0000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u2286\n  0x0000,0x0000,0x0000,0xfc00,0x0600,0x0600,0x0600,0x0600,0x0600,0xfc00,0x0000,0xfe00,0x0000,0x0000,0x0000,0x0000, // u2287\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0x0000,0x0000,0x0000,0x0000, // u22a5\n  0x0000,0x0000,0x7c00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u22c2\n  0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x7c00,0x0000,0x0000,0x0000,0x0000, // u22c3\n  0x0000,0x0000,0x0600,0x0c00,0x7c00,0xce00,0xde00,0xf600,0xe600,0x7c00,0x6000,0xc000,0x0000,0x0000,0x0000,0x0000, // u2300\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x3800,0x6c00,0xc600,0xc600,0xc600,0xc600,0xfe00,0x0000,0x0000,0x0000,0x0000, // u2302\n  0x0000,0x0000,0x3c00,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000, // u2308\n  0x0000,0x0000,0x3c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000, // u2309\n  0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3c00,0x0000,0x0000,0x0000,0x0000, // u230a\n  0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x3c00,0x0000,0x0000,0x0000,0x0000, // u230b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xc000,0xc000,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2310\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2319\n  0x0000,0x0000,0x0e00,0x1b00,0x1b00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2320\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xd800,0xd800,0x7000,0x0000,0x0000,0x0000,0x0000, // u2321\n  0x0600,0x0c00,0x1800,0x1800,0x3000,0x3000,0x3000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000, // u239b\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000, // u239c\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x3000,0x3000,0x3000,0x1800,0x1800,0x0c00,0x0600, // u239d\n  0x6000,0x3000,0x1800,0x1800,0x0c00,0x0c00,0x0c00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u239e\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u239f\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0c00,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x6000, // u23a0\n  0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000, // u23a1\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000, // u23a2\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7e00, // u23a3\n  0x7e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u23a4\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u23a5\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x7e00, // u23a6\n  0x0f00,0x1800,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000, // u23a7\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0xe000,0xe000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000, // u23a8\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x1800,0x0f00, // u23a9\n  0xf000,0x1800,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u23ab\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0700,0x0700,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u23ac\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1800,0xf000, // u23ad\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u23ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23af\n  0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23ba\n  0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000, // u23bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00, // u23bd\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u23d0\n  0x0000,0xcc00,0xcc00,0xfc00,0xcc00,0xcc00,0xcc00,0x0000,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000, // u2409\n  0x0000,0xc000,0xc000,0xc000,0xc000,0xc000,0xf800,0x0000,0x3f00,0x3000,0x3c00,0x3000,0x3000,0x3000,0x0000,0x0000, // u240a\n  0x0000,0xcc00,0xcc00,0xcc00,0xcc00,0x7800,0x3000,0x0000,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000, // u240b\n  0x0000,0xfc00,0xc000,0xf000,0xc000,0xc000,0xc000,0x0000,0x3f00,0x3000,0x3c00,0x3000,0x3000,0x3000,0x0000,0x0000, // u240c\n  0x0000,0x7800,0xcc00,0xc000,0xc000,0xcc00,0x7800,0x0000,0x3e00,0x3300,0x3300,0x3e00,0x3600,0x3300,0x0000,0x0000, // u240d\n  0x0000,0xcc00,0xec00,0xfc00,0xdc00,0xcc00,0xcc00,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3f00,0x0000,0x0000, // u2424\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2500\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2501\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2502\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2503\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xaa00,0xaa00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2508\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xaa00,0xaa00,0xaa00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2509\n  0x1800,0x1800,0x1800,0x0000,0x1800,0x1800,0x1800,0x0000,0x1800,0x1800,0x1800,0x0000,0x1800,0x1800,0x1800,0x0000, // u250a\n  0x3800,0x3800,0x3800,0x0000,0x3800,0x3800,0x3800,0x0000,0x3800,0x3800,0x3800,0x0000,0x3800,0x3800,0x3800,0x0000, // u250b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u250c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x1f00,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u250d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x3f00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u250e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x3f00,0x3f00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u250f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2510\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2511\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2512\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0xf800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2513\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2514\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0x1f00,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2515\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3f00,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2516\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3f00,0x3f00,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2517\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2518\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2519\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u251a\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0xf800,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u251b\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u251c\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0x1f00,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u251d\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3f00,0x3f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u251e\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3f00,0x3f00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u251f\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3f00,0x3f00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2520\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3f00,0x3f00,0x3f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2521\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3f00,0x3f00,0x3f00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2522\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3f00,0x3f00,0x3f00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2523\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2524\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0xf800,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2525\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0xf800,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2526\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0xf800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2527\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0xf800,0xf800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2528\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0xf800,0xf800,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2529\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0xf800,0xf800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u252a\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0xf800,0xf800,0xf800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u252b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u252c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u252d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u252e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u252f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2530\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xff00,0xff00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2531\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0xff00,0xff00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2532\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2533\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2534\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2535\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2536\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2537\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2538\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0xf800,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2539\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3f00,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u253a\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0xff00,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u253b\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u253c\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u253d\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u253e\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u253f\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2540\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0xff00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2541\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0xff00,0xff00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2542\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0xf800,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2543\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3f00,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2544\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0xff00,0xff00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2545\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0xff00,0xff00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2546\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0xff00,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2547\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0xff00,0xff00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2548\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0xf800,0xff00,0xff00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u2549\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3f00,0xff00,0xff00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u254a\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0xff00,0xff00,0xff00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u254b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x0000,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2550\n  0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00, // u2551\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x1f00,0x1800,0x1f00,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2552\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x7f00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00, // u2553\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x7f00,0x6000,0x6f00,0x6f00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00, // u2554\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0x1800,0xf800,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2555\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00, // u2556\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x0c00,0xec00,0xec00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00, // u2557\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0x1f00,0x1800,0x1f00,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2558\n  0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x7f00,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2559\n  0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6f00,0x6f00,0x6000,0x7f00,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255a\n  0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0xf800,0x1800,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255b\n  0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255c\n  0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0xec00,0xec00,0x0c00,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255d\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1f00,0x1f00,0x1800,0x1f00,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u255e\n  0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6f00,0x6f00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00, // u255f\n  0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6f00,0x6f00,0x6000,0x6f00,0x6f00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00, // u2560\n  0x1800,0x1800,0x1800,0x1800,0x1800,0xf800,0xf800,0x1800,0xf800,0xf800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2561\n  0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0xec00,0xec00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00, // u2562\n  0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0xec00,0xec00,0x0c00,0xec00,0xec00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00, // u2563\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x0000,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2564\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00, // u2565\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x0000,0xef00,0xef00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00, // u2566\n  0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0xff00,0x0000,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2567\n  0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2568\n  0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0xef00,0xef00,0x0000,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2569\n  0x1800,0x1800,0x1800,0x1800,0x1800,0xff00,0xff00,0x1800,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u256a\n  0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0xff00,0xff00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00, // u256b\n  0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0xef00,0xef00,0x0000,0xef00,0xef00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00, // u256c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0f00,0x1c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u256d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xe000,0xf000,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u256e\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3800,0xf000,0xe000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u256f\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1c00,0x0f00,0x0700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2570\n  0x0100,0x0100,0x0300,0x0200,0x0600,0x0400,0x0c00,0x0800,0x1800,0x1000,0x3000,0x2000,0x6000,0x4000,0xc000,0x8000, // u2571\n  0x8000,0xc000,0x4000,0x6000,0x2000,0x3000,0x1000,0x1800,0x0800,0x0c00,0x0400,0x0600,0x0200,0x0300,0x0100,0x0100, // u2572\n  0x8100,0xc100,0x4300,0x6200,0x2600,0x3400,0x1c00,0x1800,0x1800,0x1c00,0x3400,0x2600,0x6200,0x4300,0xc100,0x8100, // u2573\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2574\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2575\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2576\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u2577\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2578\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2579\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x1f00,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u257b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257c\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u257d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257e\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u257f\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2580\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00, // u2581\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0xff00, // u2582\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2583\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2584\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2585\n  0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2586\n  0x0000,0x0000,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2587\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2588\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00, // u2589\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00, // u258a\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800, // u258b\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000, // u258c\n  0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000, // u258d\n  0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000, // u258e\n  0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000, // u258f\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u2590\n  0x8800,0x2200,0x8800,0x2200,0x8800,0x2200,0x8800,0x2200,0x8800,0x2200,0x8800,0x2200,0x8800,0x2200,0x8800,0x2200, // u2591\n  0xaa00,0x5500,0xaa00,0x5500,0xaa00,0x5500,0xaa00,0x5500,0xaa00,0x5500,0xaa00,0x5500,0xaa00,0x5500,0xaa00,0x5500, // u2592\n  0xee00,0xbb00,0xee00,0xbb00,0xee00,0xbb00,0xee00,0xbb00,0xee00,0xbb00,0xee00,0xbb00,0xee00,0xbb00,0xee00,0xbb00, // u2593\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000, // u2596\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u2597\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2598\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2599\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u259a\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000, // u259b\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u259c\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u259d\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000, // u259e\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u259f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x7c00,0x7c00,0x7c00,0x7c00,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u25a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xfe00,0xfe00,0xfe00,0x0000,0x0000,0x0000,0x0000, // u25ac\n  0x0000,0x0000,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0x0000,0x0000,0x0000,0x0000, // u25ae\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x3c00,0x3c00,0x7e00,0x7e00,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000, // u25b2\n  0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xff00,0xfc00,0xf000,0xc000,0x0000,0x0000,0x0000,0x0000, // u25b6\n  0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xff00,0xfc00,0xf000,0xc000,0x0000,0x0000,0x0000,0x0000, // u25ba\n  0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x7e00,0x7e00,0x3c00,0x3c00,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u25bc\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0f00,0x3f00,0xff00,0xff00,0x3f00,0x0f00,0x0300,0x0000,0x0000,0x0000,0x0000, // u25c0\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0f00,0x3f00,0xff00,0xff00,0x3f00,0x0f00,0x0300,0x0000,0x0000,0x0000,0x0000, // u25c4\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x3c00,0x7e00,0xff00,0x7e00,0x3c00,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c6\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x3c00,0x6600,0xc300,0x6600,0x3c00,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ca\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x6600,0x4200,0x4200,0x6600,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u25cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x7e00,0x7e00,0x7e00,0x7e00,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u25cf\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xe700,0xc300,0xc300,0xe700,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u25d8\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xc300,0x9900,0xbd00,0xbd00,0x9900,0xc300,0xff00,0xff00,0xff00,0xff00,0xff00, // u25d9\n  0x0000,0x0000,0x7c00,0x8200,0xaa00,0x8200,0x8200,0xba00,0x9200,0x8200,0x8200,0x7c00,0x0000,0x0000,0x0000,0x0000, // u263a\n  0x0000,0x0000,0x7c00,0xfe00,0xd600,0xfe00,0xfe00,0xc600,0xee00,0xfe00,0xfe00,0x7c00,0x0000,0x0000,0x0000,0x0000, // u263b\n  0x0000,0x0000,0x0000,0x1800,0xdb00,0x7e00,0x3c00,0xe700,0x3c00,0x7e00,0xdb00,0x1800,0x0000,0x0000,0x0000,0x0000, // u263c\n  0x0000,0x0000,0x3c00,0x6600,0x6600,0x6600,0x6600,0x3c00,0x1800,0x7e00,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000, // u2640\n  0x0000,0x0000,0x3e00,0x0e00,0x1a00,0x3200,0x7800,0xcc00,0xcc00,0xcc00,0xcc00,0x7800,0x0000,0x0000,0x0000,0x0000, // u2642\n  0x0000,0x0000,0x1800,0x1800,0x3c00,0x7e00,0xff00,0xff00,0x7e00,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u2660\n  0x0000,0x0000,0x1800,0x3c00,0x3c00,0x1800,0x5a00,0xff00,0xff00,0x5a00,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000, // u2663\n  0x0000,0x0000,0x0000,0x0000,0x6c00,0xfe00,0xfe00,0xfe00,0xfe00,0x7c00,0x3800,0x1000,0x0000,0x0000,0x0000,0x0000, // u2665\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x3c00,0x7e00,0xff00,0x7e00,0x3c00,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000, // u2666\n  0x0000,0x0000,0x7e00,0x6600,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0xe000,0xc000,0x0000,0x0000,0x0000,0x0000, // u266a\n  0x0000,0x0000,0x7e00,0x6600,0x7e00,0x6600,0x6600,0x6600,0x6600,0x6600,0x6e00,0xec00,0xc000,0x0000,0x0000,0x0000, // u266b\n  0x0000,0x0000,0x0300,0x0300,0x0600,0x0600,0xcc00,0xcc00,0x7800,0x7800,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000, // u2713\n  0x0000,0x0000,0x0700,0x0700,0x0e00,0x0e00,0xdc00,0xfc00,0x7800,0x7800,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000, // u2714\n  0x0000,0x0000,0x0c00,0xcc00,0x7800,0x3800,0x3800,0x3c00,0x6600,0x6000,0xc000,0xc000,0x0000,0x0000,0x0000,0x0000, // u2717\n  0x0000,0x0000,0x0e00,0xee00,0x7c00,0x3c00,0x3c00,0x3e00,0x7700,0x7300,0xe000,0xe000,0x0000,0x0000,0x0000,0x0000, // u2718\n  0x0000,0x0000,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x1800,0x1800,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000, // u27e8\n  0x0000,0x0000,0x3000,0x3000,0x1800,0x1800,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000, // u27e9\n  0x0000,0x0000,0x3600,0x3600,0x6c00,0x6c00,0xd800,0xd800,0x6c00,0x6c00,0x3600,0x3600,0x0000,0x0000,0x0000,0x0000, // u27ea\n  0x0000,0x0000,0xd800,0xd800,0x6c00,0x6c00,0x3600,0x3600,0x6c00,0x6c00,0xd800,0xd800,0x0000,0x0000,0x0000,0x0000, // u27eb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2800\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2801\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2802\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2803\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2804\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2805\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2806\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2807\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2808\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2809\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280a\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280b\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280c\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280d\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280e\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2810\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2811\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2812\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2813\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2814\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2815\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2816\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2817\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2818\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2819\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281a\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281b\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281c\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281d\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281e\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2820\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2821\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2822\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2823\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2824\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2825\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2826\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2827\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2828\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2829\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u282a\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u282b\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000, // u282c\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000, // u282d\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000, // u282e\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000, // u282f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2830\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2831\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2832\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2833\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2834\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2835\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2836\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2837\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2838\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2839\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u283a\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u283b\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000, // u283c\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000, // u283d\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000, // u283e\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000, // u283f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2840\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2841\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2842\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2843\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2844\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2845\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2846\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2847\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2848\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2849\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u284a\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u284b\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000, // u284c\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000, // u284d\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000, // u284e\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000, // u284f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2850\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2851\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2852\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2853\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2854\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2855\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2856\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2857\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2858\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u2859\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u285a\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000, // u285b\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000, // u285c\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000, // u285d\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000, // u285e\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000, // u285f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000, // u2860\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000, // u2861\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000, // u2862\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000, // u2863\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000, // u2864\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000, // u2865\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000, // u2866\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000, // u2867\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000, // u2868\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000, // u2869\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000, // u286a\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000, // u286b\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000, // u286c\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000, // u286d\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000, // u286e\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000, // u286f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000, // u2870\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000, // u2871\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000, // u2872\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000, // u2873\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000, // u2874\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000, // u2875\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000, // u2876\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000, // u2877\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000, // u2878\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000, // u2879\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000, // u287a\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000, // u287b\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000, // u287c\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000, // u287d\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000, // u287e\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000, // u287f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2880\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2881\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2882\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2883\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2884\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2885\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2886\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2887\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2888\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2889\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u288a\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u288b\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000, // u288c\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000, // u288d\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000, // u288e\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000, // u288f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2890\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2891\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2892\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2893\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2894\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2895\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2896\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2897\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2898\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u2899\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u289a\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000, // u289b\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000, // u289c\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000, // u289d\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000, // u289e\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000, // u289f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28a0\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28a2\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28a4\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28a5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28a6\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28a7\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28a8\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28a9\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28aa\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28ab\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28ac\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28ad\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28ae\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28af\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28b0\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28b1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28b2\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28b4\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28b6\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28b7\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28b8\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28b9\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28ba\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28bb\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28bc\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28bd\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28be\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000, // u28bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28c0\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28c2\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28c4\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28c6\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28c7\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28c8\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28c9\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28ca\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28cb\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28cc\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28cd\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28ce\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28cf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28d0\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28d2\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28d4\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28d6\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28d7\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28d8\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28d9\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28da\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28db\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28dc\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28dd\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28de\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000, // u28df\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28e0\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28e1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28e2\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28e3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28e4\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28e6\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28e7\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28e8\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28e9\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28ea\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28eb\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28ec\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28ed\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28ee\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28ef\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28f0\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28f2\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28f3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28f4\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28f6\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28f7\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28f8\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28f9\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28fa\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28fb\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28fc\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28fd\n  0x0000,0x0600,0x0600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28fe\n  0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000,0x0000,0x6600,0x6600,0x0000, // u28ff\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0x0000,0x0000,0x0000,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000, // u2e2c\n  0xc000,0xc000,0xcc00,0xde00,0xff00,0xcc00,0xcc00,0xcc00,0x9800,0x3000,0x6000,0xc000,0xc000,0xc000,0xc000,0xc000, // ue0a0\n  0x0000,0xc000,0xc000,0xc000,0xc000,0xc000,0xfc00,0x0000,0x3300,0x3b00,0x3f00,0x3700,0x3300,0x3300,0x0000,0x0000, // ue0a1\n  0x0000,0x3c00,0x6600,0x6600,0x6600,0x6600,0xff00,0xff00,0xe700,0xc300,0xe700,0xff00,0xff00,0xff00,0x0000,0x0000, // ue0a2\n  0x8000,0xc000,0xe000,0xf000,0xf800,0xfc00,0xfe00,0xff00,0xff00,0xfe00,0xfc00,0xf800,0xf000,0xe000,0xc000,0x8000, // ue0b0\n  0x8000,0xc000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0x8000, // ue0b1\n  0x0100,0x0300,0x0700,0x0f00,0x1f00,0x3f00,0x7f00,0xff00,0xff00,0x7f00,0x3f00,0x1f00,0x0f00,0x0700,0x0300,0x0100, // ue0b2\n  0x0100,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0xc000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0100, // ue0b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x6600,0x6600,0x3c00,0x0000, // uf6be\n  0x0000,0x0000,0xfe00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xfe00,0x0000,0x0000,0x0000,0x0000 // ufffd\n  };\n  // codepoints array\n  constexpr std::array<uint16_t, CHARCOUNT> fixedfont_codepoints = {\n  0x0000,0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,\n  0x002f,0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,\n  0x003f,0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,\n  0x004f,0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,\n  0x005f,0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,\n  0x006f,0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,\n  0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af,\n  0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf,\n  0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf,\n  0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df,\n  0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef,\n  0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff,\n  0x0100,0x0101,0x0102,0x0103,0x0104,0x0105,0x0106,0x0107,0x0108,0x0109,0x010a,0x010b,0x010c,0x010d,0x010e,0x010f,\n  0x0110,0x0111,0x0112,0x0113,0x0114,0x0115,0x0116,0x0117,0x0118,0x0119,0x011a,0x011b,0x011c,0x011d,0x011e,0x011f,\n  0x0120,0x0121,0x0122,0x0123,0x0124,0x0125,0x0126,0x0127,0x0128,0x0129,0x012a,0x012b,0x012c,0x012d,0x012e,0x012f,\n  0x0130,0x0131,0x0132,0x0133,0x0134,0x0135,0x0136,0x0137,0x0138,0x0139,0x013a,0x013b,0x013c,0x013d,0x013e,0x013f,\n  0x0140,0x0141,0x0142,0x0143,0x0144,0x0145,0x0146,0x0147,0x0148,0x0149,0x014a,0x014b,0x014c,0x014d,0x014e,0x014f,\n  0x0150,0x0151,0x0152,0x0153,0x0154,0x0155,0x0156,0x0157,0x0158,0x0159,0x015a,0x015b,0x015c,0x015d,0x015e,0x015f,\n  0x0160,0x0161,0x0162,0x0163,0x0164,0x0165,0x0166,0x0167,0x0168,0x0169,0x016a,0x016b,0x016c,0x016d,0x016e,0x016f,\n  0x0170,0x0171,0x0172,0x0173,0x0174,0x0175,0x0176,0x0177,0x0178,0x0179,0x017a,0x017b,0x017c,0x017d,0x017e,0x017f,\n  0x0186,0x018e,0x018f,0x0190,0x0192,0x019d,0x019e,0x01b5,0x01b6,0x01b7,0x01cd,0x01ce,0x01cf,0x01d0,0x01d1,0x01d2,\n  0x01d3,0x01d4,0x01e2,0x01e3,0x01e4,0x01e5,0x01e6,0x01e7,0x01e8,0x01e9,0x01ea,0x01eb,0x01ec,0x01ed,0x01ee,0x01ef,\n  0x01f0,0x01f4,0x01f5,0x01fc,0x01fd,0x01fe,0x01ff,0x0218,0x0219,0x021a,0x021b,0x0232,0x0233,0x0237,0x0254,0x0258,\n  0x0259,0x025b,0x0272,0x0292,0x02bb,0x02bc,0x02bd,0x02c6,0x02c7,0x02d8,0x02d9,0x02db,0x02dc,0x02dd,0x0300,0x0301,\n  0x0302,0x0303,0x0304,0x0305,0x0306,0x0307,0x0308,0x030a,0x030b,0x030c,0x0329,0x0384,0x0385,0x0386,0x0387,0x0388,\n  0x0389,0x038a,0x038c,0x038e,0x038f,0x0390,0x0391,0x0392,0x0393,0x0394,0x0395,0x0396,0x0397,0x0398,0x0399,0x039a,\n  0x039b,0x039c,0x039d,0x039e,0x039f,0x03a0,0x03a1,0x03a3,0x03a4,0x03a5,0x03a6,0x03a7,0x03a8,0x03a9,0x03aa,0x03ab,\n  0x03ac,0x03ad,0x03ae,0x03af,0x03b0,0x03b1,0x03b2,0x03b3,0x03b4,0x03b5,0x03b6,0x03b7,0x03b8,0x03b9,0x03ba,0x03bb,\n  0x03bc,0x03bd,0x03be,0x03bf,0x03c0,0x03c1,0x03c2,0x03c3,0x03c4,0x03c5,0x03c6,0x03c7,0x03c8,0x03c9,0x03ca,0x03cb,\n  0x03cc,0x03cd,0x03ce,0x03d1,0x03d5,0x03f0,0x03f1,0x03f2,0x03f3,0x03f4,0x03f5,0x03f6,0x0400,0x0401,0x0402,0x0403,\n  0x0404,0x0405,0x0406,0x0407,0x0408,0x0409,0x040a,0x040b,0x040c,0x040d,0x040e,0x040f,0x0410,0x0411,0x0412,0x0413,\n  0x0414,0x0415,0x0416,0x0417,0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e,0x041f,0x0420,0x0421,0x0422,0x0423,\n  0x0424,0x0425,0x0426,0x0427,0x0428,0x0429,0x042a,0x042b,0x042c,0x042d,0x042e,0x042f,0x0430,0x0431,0x0432,0x0433,\n  0x0434,0x0435,0x0436,0x0437,0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e,0x043f,0x0440,0x0441,0x0442,0x0443,\n  0x0444,0x0445,0x0446,0x0447,0x0448,0x0449,0x044a,0x044b,0x044c,0x044d,0x044e,0x044f,0x0450,0x0451,0x0452,0x0453,\n  0x0454,0x0455,0x0456,0x0457,0x0458,0x0459,0x045a,0x045b,0x045c,0x045d,0x045e,0x045f,0x0462,0x0463,0x046a,0x046b,\n  0x0490,0x0491,0x0492,0x0493,0x0494,0x0495,0x0496,0x0497,0x0498,0x0499,0x049a,0x049b,0x049c,0x049d,0x04a0,0x04a1,\n  0x04a2,0x04a3,0x04a4,0x04a5,0x04aa,0x04ab,0x04ae,0x04af,0x04b0,0x04b1,0x04b2,0x04b3,0x04b6,0x04b7,0x04b8,0x04b9,\n  0x04ba,0x04bb,0x04c0,0x04c1,0x04c2,0x04cf,0x04d0,0x04d1,0x04d2,0x04d3,0x04d4,0x04d5,0x04d6,0x04d7,0x04d8,0x04d9,\n  0x04da,0x04db,0x04dc,0x04dd,0x04de,0x04df,0x04e2,0x04e3,0x04e4,0x04e5,0x04e6,0x04e7,0x04e8,0x04e9,0x04ea,0x04eb,\n  0x04ec,0x04ed,0x04ee,0x04ef,0x04f0,0x04f1,0x04f2,0x04f3,0x04f4,0x04f5,0x04f8,0x04f9,0x05d0,0x05d1,0x05d2,0x05d3,\n  0x05d4,0x05d5,0x05d6,0x05d7,0x05d8,0x05d9,0x05da,0x05db,0x05dc,0x05dd,0x05de,0x05df,0x05e0,0x05e1,0x05e2,0x05e3,\n  0x05e4,0x05e5,0x05e6,0x05e7,0x05e8,0x05e9,0x05ea,0x1e0c,0x1e0d,0x1e34,0x1e35,0x1e36,0x1e37,0x1e40,0x1e41,0x1e42,\n  0x1e43,0x1e44,0x1e45,0x1e46,0x1e47,0x1e6c,0x1e6d,0x1eb8,0x1eb9,0x1ebc,0x1ebd,0x1eca,0x1ecb,0x1ecc,0x1ecd,0x1ee4,\n  0x1ee5,0x1ef8,0x1ef9,0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007,0x2008,0x2009,0x200a,0x200b,0x200c,\n  0x200d,0x200e,0x200f,0x2010,0x2011,0x2012,0x2013,0x2014,0x2015,0x2016,0x2017,0x2018,0x2019,0x201a,0x201b,0x201c,\n  0x201d,0x201e,0x201f,0x2020,0x2021,0x2022,0x2026,0x2030,0x2032,0x2033,0x2039,0x203a,0x203c,0x203e,0x2070,0x2071,\n  0x2074,0x2075,0x2076,0x2077,0x2078,0x2079,0x207a,0x207b,0x207c,0x207d,0x207e,0x207f,0x2080,0x2081,0x2082,0x2083,\n  0x2084,0x2085,0x2086,0x2087,0x2088,0x2089,0x208a,0x208b,0x208c,0x208d,0x208e,0x2090,0x2091,0x2092,0x2093,0x2094,\n  0x2095,0x2096,0x2097,0x2098,0x209a,0x20a7,0x20aa,0x20ac,0x20ae,0x2102,0x210e,0x210f,0x2115,0x2116,0x211a,0x211d,\n  0x2122,0x2124,0x2126,0x2135,0x2190,0x2191,0x2192,0x2193,0x2194,0x2195,0x21a4,0x21a6,0x21a8,0x21b5,0x21bb,0x21cb,\n  0x21cc,0x21d0,0x21d1,0x21d2,0x21d3,0x21d4,0x21d5,0x2200,0x2203,0x2204,0x2205,0x2206,0x2207,0x2208,0x2209,0x220a,\n  0x220b,0x220c,0x220d,0x2212,0x2213,0x2214,0x2215,0x2216,0x2219,0x221a,0x221e,0x221f,0x2225,0x2227,0x2228,0x2229,\n  0x222a,0x2248,0x2260,0x2261,0x2264,0x2265,0x226a,0x226b,0x2282,0x2283,0x2286,0x2287,0x22a5,0x22c2,0x22c3,0x2300,\n  0x2302,0x2308,0x2309,0x230a,0x230b,0x2310,0x2319,0x2320,0x2321,0x239b,0x239c,0x239d,0x239e,0x239f,0x23a0,0x23a1,\n  0x23a2,0x23a3,0x23a4,0x23a5,0x23a6,0x23a7,0x23a8,0x23a9,0x23ab,0x23ac,0x23ad,0x23ae,0x23af,0x23ba,0x23bb,0x23bc,\n  0x23bd,0x23d0,0x2409,0x240a,0x240b,0x240c,0x240d,0x2424,0x2500,0x2501,0x2502,0x2503,0x2508,0x2509,0x250a,0x250b,\n  0x250c,0x250d,0x250e,0x250f,0x2510,0x2511,0x2512,0x2513,0x2514,0x2515,0x2516,0x2517,0x2518,0x2519,0x251a,0x251b,\n  0x251c,0x251d,0x251e,0x251f,0x2520,0x2521,0x2522,0x2523,0x2524,0x2525,0x2526,0x2527,0x2528,0x2529,0x252a,0x252b,\n  0x252c,0x252d,0x252e,0x252f,0x2530,0x2531,0x2532,0x2533,0x2534,0x2535,0x2536,0x2537,0x2538,0x2539,0x253a,0x253b,\n  0x253c,0x253d,0x253e,0x253f,0x2540,0x2541,0x2542,0x2543,0x2544,0x2545,0x2546,0x2547,0x2548,0x2549,0x254a,0x254b,\n  0x2550,0x2551,0x2552,0x2553,0x2554,0x2555,0x2556,0x2557,0x2558,0x2559,0x255a,0x255b,0x255c,0x255d,0x255e,0x255f,\n  0x2560,0x2561,0x2562,0x2563,0x2564,0x2565,0x2566,0x2567,0x2568,0x2569,0x256a,0x256b,0x256c,0x256d,0x256e,0x256f,\n  0x2570,0x2571,0x2572,0x2573,0x2574,0x2575,0x2576,0x2577,0x2578,0x2579,0x257a,0x257b,0x257c,0x257d,0x257e,0x257f,\n  0x2580,0x2581,0x2582,0x2583,0x2584,0x2585,0x2586,0x2587,0x2588,0x2589,0x258a,0x258b,0x258c,0x258d,0x258e,0x258f,\n  0x2590,0x2591,0x2592,0x2593,0x2596,0x2597,0x2598,0x2599,0x259a,0x259b,0x259c,0x259d,0x259e,0x259f,0x25a0,0x25ac,\n  0x25ae,0x25b2,0x25b6,0x25ba,0x25bc,0x25c0,0x25c4,0x25c6,0x25ca,0x25cb,0x25cf,0x25d8,0x25d9,0x263a,0x263b,0x263c,\n  0x2640,0x2642,0x2660,0x2663,0x2665,0x2666,0x266a,0x266b,0x2713,0x2714,0x2717,0x2718,0x27e8,0x27e9,0x27ea,0x27eb,\n  0x2800,0x2801,0x2802,0x2803,0x2804,0x2805,0x2806,0x2807,0x2808,0x2809,0x280a,0x280b,0x280c,0x280d,0x280e,0x280f,\n  0x2810,0x2811,0x2812,0x2813,0x2814,0x2815,0x2816,0x2817,0x2818,0x2819,0x281a,0x281b,0x281c,0x281d,0x281e,0x281f,\n  0x2820,0x2821,0x2822,0x2823,0x2824,0x2825,0x2826,0x2827,0x2828,0x2829,0x282a,0x282b,0x282c,0x282d,0x282e,0x282f,\n  0x2830,0x2831,0x2832,0x2833,0x2834,0x2835,0x2836,0x2837,0x2838,0x2839,0x283a,0x283b,0x283c,0x283d,0x283e,0x283f,\n  0x2840,0x2841,0x2842,0x2843,0x2844,0x2845,0x2846,0x2847,0x2848,0x2849,0x284a,0x284b,0x284c,0x284d,0x284e,0x284f,\n  0x2850,0x2851,0x2852,0x2853,0x2854,0x2855,0x2856,0x2857,0x2858,0x2859,0x285a,0x285b,0x285c,0x285d,0x285e,0x285f,\n  0x2860,0x2861,0x2862,0x2863,0x2864,0x2865,0x2866,0x2867,0x2868,0x2869,0x286a,0x286b,0x286c,0x286d,0x286e,0x286f,\n  0x2870,0x2871,0x2872,0x2873,0x2874,0x2875,0x2876,0x2877,0x2878,0x2879,0x287a,0x287b,0x287c,0x287d,0x287e,0x287f,\n  0x2880,0x2881,0x2882,0x2883,0x2884,0x2885,0x2886,0x2887,0x2888,0x2889,0x288a,0x288b,0x288c,0x288d,0x288e,0x288f,\n  0x2890,0x2891,0x2892,0x2893,0x2894,0x2895,0x2896,0x2897,0x2898,0x2899,0x289a,0x289b,0x289c,0x289d,0x289e,0x289f,\n  0x28a0,0x28a1,0x28a2,0x28a3,0x28a4,0x28a5,0x28a6,0x28a7,0x28a8,0x28a9,0x28aa,0x28ab,0x28ac,0x28ad,0x28ae,0x28af,\n  0x28b0,0x28b1,0x28b2,0x28b3,0x28b4,0x28b5,0x28b6,0x28b7,0x28b8,0x28b9,0x28ba,0x28bb,0x28bc,0x28bd,0x28be,0x28bf,\n  0x28c0,0x28c1,0x28c2,0x28c3,0x28c4,0x28c5,0x28c6,0x28c7,0x28c8,0x28c9,0x28ca,0x28cb,0x28cc,0x28cd,0x28ce,0x28cf,\n  0x28d0,0x28d1,0x28d2,0x28d3,0x28d4,0x28d5,0x28d6,0x28d7,0x28d8,0x28d9,0x28da,0x28db,0x28dc,0x28dd,0x28de,0x28df,\n  0x28e0,0x28e1,0x28e2,0x28e3,0x28e4,0x28e5,0x28e6,0x28e7,0x28e8,0x28e9,0x28ea,0x28eb,0x28ec,0x28ed,0x28ee,0x28ef,\n  0x28f0,0x28f1,0x28f2,0x28f3,0x28f4,0x28f5,0x28f6,0x28f7,0x28f8,0x28f9,0x28fa,0x28fb,0x28fc,0x28fd,0x28fe,0x28ff,\n  0x2e2c,0xe0a0,0xe0a1,0xe0a2,0xe0b0,0xe0b1,0xe0b2,0xe0b3,0xf6be,0xfffd };\n} // namespace\n// -- end of autogenerated text ---\n\nnamespace fixed_font_18n {\n  // -- start of autogenerated text ---\n  // definition section for font: ter-u18n.bdf\n  constexpr int CHARCOUNT = 1354;\n  constexpr int WIDTH = 10;\n  constexpr int HEIGHT = 18;\n  constexpr int OFFSET_X = 0;\n  constexpr int OFFSET_Y = 0;\n  constexpr FixedFont_info_t fixedfont_info = {\n    \"Terminus\", // font name\n    \"ter-u18n.bdf\", // font name internal\n    CHARCOUNT, // num of chars\n    WIDTH, HEIGHT, OFFSET_X, OFFSET_Y,\n    false // bold\n  };\n  // font bitmap definitions\n  constexpr std::array<uint16_t, CHARCOUNT * HEIGHT> fixedfont_bitmap = {\n  0x0000,0x0000,0x0000,0x7700,0x4100,0x4100,0x0000,0x4100,0x4100,0x4100,0x4100,0x0000,0x4100,0x4100,0x7700,0x0000,\n  0x0000,0x0000, // u0000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0020\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,0x0000,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u0021\n  0x0000,0x2200,0x2200,0x2200,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0022\n  0x0000,0x0000,0x0000,0x2200,0x2200,0x2200,0x7f00,0x2200,0x2200,0x2200,0x2200,0x7f00,0x2200,0x2200,0x2200,0x0000,\n  0x0000,0x0000, // u0023\n  0x0000,0x0000,0x0800,0x0800,0x3e00,0x4900,0x4800,0x4800,0x4800,0x3e00,0x0900,0x0900,0x0900,0x4900,0x3e00,0x0800,\n  0x0800,0x0000, // u0024\n  0x0000,0x0000,0x0000,0x7100,0x5100,0x7200,0x0200,0x0400,0x0400,0x0800,0x0800,0x1000,0x1380,0x2280,0x2380,0x0000,\n  0x0000,0x0000, // u0025\n  0x0000,0x0000,0x0000,0x1c00,0x2200,0x2200,0x2200,0x1400,0x1880,0x2480,0x4300,0x4100,0x4100,0x2280,0x1c80,0x0000,\n  0x0000,0x0000, // u0026\n  0x0000,0x0800,0x0800,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0027\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0800,0x0800,0x0400,0x0000,\n  0x0000,0x0000, // u0028\n  0x0000,0x0000,0x0000,0x1000,0x0800,0x0800,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0800,0x0800,0x1000,0x0000,\n  0x0000,0x0000, // u0029\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2200,0x1400,0x0800,0x7f00,0x0800,0x1400,0x2200,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u002a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x7f00,0x0800,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u002b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x1000,\n  0x0000,0x0000, // u002c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u002d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u002e\n  0x0000,0x0000,0x0000,0x0100,0x0100,0x0200,0x0200,0x0400,0x0400,0x0800,0x0800,0x1000,0x1000,0x2000,0x2000,0x0000,\n  0x0000,0x0000, // u002f\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4300,0x4500,0x4900,0x5100,0x6100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0030\n  0x0000,0x0000,0x0000,0x0800,0x1800,0x2800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x3e00,0x0000,\n  0x0000,0x0000, // u0031\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u0032\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x0100,0x0100,0x1e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0033\n  0x0000,0x0000,0x0000,0x0100,0x0300,0x0500,0x0900,0x1100,0x2100,0x4100,0x4100,0x7f00,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0000, // u0034\n  0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0035\n  0x0000,0x0000,0x0000,0x1e00,0x2000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0036\n  0x0000,0x0000,0x0000,0x7f00,0x4100,0x4100,0x0100,0x0200,0x0200,0x0400,0x0400,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u0037\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0038\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,0x0100,0x0100,0x0200,0x3c00,0x0000,\n  0x0000,0x0000, // u0039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,\n  0x0000,0x0000, // u003a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x1000,\n  0x0000,0x0000, // u003b\n  0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,0x0000,\n  0x0000,0x0000, // u003c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0000,0x0000,0x0000,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u003d\n  0x0000,0x0000,0x0000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x0000,\n  0x0000,0x0000, // u003e\n  0x0000,0x0000,0x0000,0x1c00,0x2200,0x4100,0x4100,0x0100,0x0200,0x0400,0x0800,0x0800,0x0000,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u003f\n  0x0000,0x0000,0x0000,0x3f00,0x4080,0x4080,0x4780,0x4880,0x4880,0x4880,0x4980,0x4680,0x4000,0x4000,0x3f80,0x0000,\n  0x0000,0x0000, // u0040\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u0041\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x0000,\n  0x0000,0x0000, // u0042\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0043\n  0x0000,0x0000,0x0000,0x7c00,0x4200,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4200,0x7c00,0x0000,\n  0x0000,0x0000, // u0044\n  0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u0045\n  0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,\n  0x0000,0x0000, // u0046\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4f00,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0047\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u0048\n  0x0000,0x0000,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u0049\n  0x0000,0x0000,0x0000,0x0380,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x2100,0x2100,0x2100,0x1e00,0x0000,\n  0x0000,0x0000, // u004a\n  0x0000,0x0000,0x0000,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,0x0000,\n  0x0000,0x0000, // u004b\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u004c\n  0x0000,0x0000,0x0000,0x4080,0x6180,0x5280,0x5280,0x4c80,0x4c80,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x0000,\n  0x0000,0x0000, // u004d\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x6100,0x5100,0x4900,0x4500,0x4300,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u004e\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u004f\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,\n  0x0000,0x0000, // u0050\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4900,0x3e00,0x0200,\n  0x0100,0x0000, // u0051\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x5000,0x4800,0x4400,0x4200,0x4100,0x0000,\n  0x0000,0x0000, // u0052\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x3e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0053\n  0x0000,0x0000,0x0000,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u0054\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0055\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x2200,0x2200,0x2200,0x1400,0x1400,0x1400,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u0056\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4c80,0x4c80,0x5280,0x5280,0x6180,0x4080,0x0000,\n  0x0000,0x0000, // u0057\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x0800,0x0800,0x1400,0x2200,0x2200,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u0058\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u0059\n  0x0000,0x0000,0x0000,0x7f00,0x0100,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u005a\n  0x0000,0x0000,0x0000,0x1c00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1c00,0x0000,\n  0x0000,0x0000, // u005b\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x1000,0x1000,0x0800,0x0800,0x0400,0x0400,0x0200,0x0200,0x0100,0x0100,0x0000,\n  0x0000,0x0000, // u005c\n  0x0000,0x0000,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x1c00,0x0000,\n  0x0000,0x0000, // u005d\n  0x0000,0x0800,0x1400,0x2200,0x4100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u005e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x7f00,0x0000, // u005f\n  0x1000,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0060\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u0061\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x0000,\n  0x0000,0x0000, // u0062\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0063\n  0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u0064\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0065\n  0x0000,0x0000,0x0000,0x0700,0x0800,0x0800,0x3e00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u0066\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,\n  0x0100,0x3e00, // u0067\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u0068\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u0069\n  0x0000,0x0000,0x0000,0x0200,0x0200,0x0000,0x0600,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x2200,\n  0x2200,0x1c00, // u006a\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4100,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x4100,0x0000,\n  0x0000,0x0000, // u006b\n  0x0000,0x0000,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u006c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x0000,\n  0x0000,0x0000, // u006d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u006e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u006f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x4000,\n  0x4000,0x4000, // u0070\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,\n  0x0100,0x0100, // u0071\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4f00,0x5000,0x6000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,\n  0x0000,0x0000, // u0072\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4000,0x4000,0x3e00,0x0100,0x0100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0073\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x3e00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0700,0x0000,\n  0x0000,0x0000, // u0074\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u0075\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u0076\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4900,0x4900,0x4900,0x4900,0x4900,0x3e00,0x0000,\n  0x0000,0x0000, // u0077\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x1400,0x0800,0x1400,0x2200,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u0078\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,\n  0x0100,0x3e00, // u0079\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u007a\n  0x0000,0x0000,0x0000,0x0600,0x0800,0x0800,0x0800,0x0800,0x3000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0600,0x0000,\n  0x0000,0x0000, // u007b\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u007c\n  0x0000,0x0000,0x0000,0x3000,0x0800,0x0800,0x0800,0x0800,0x0600,0x0800,0x0800,0x0800,0x0800,0x0800,0x3000,0x0000,\n  0x0000,0x0000, // u007d\n  0x0000,0x3100,0x4900,0x4900,0x4600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u007e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00a0\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u00a1\n  0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x3e00,0x4900,0x4800,0x4800,0x4800,0x4800,0x4800,0x4900,0x3e00,0x0800,\n  0x0800,0x0000, // u00a2\n  0x0000,0x0000,0x0000,0x1c00,0x2200,0x2000,0x2000,0x2000,0x7c00,0x2000,0x2000,0x2000,0x2000,0x2100,0x7f00,0x0000,\n  0x0000,0x0000, // u00a3\n  0x0000,0x0000,0x0000,0x0000,0x4080,0x2100,0x1e00,0x2100,0x2100,0x2100,0x2100,0x1e00,0x2100,0x4080,0x0000,0x0000,\n  0x0000,0x0000, // u00a4\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x0800,0x0800,0x3e00,0x0800,0x3e00,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u00a5\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u00a6\n  0x0000,0x0000,0x1c00,0x2200,0x2000,0x1800,0x2400,0x2200,0x2200,0x2200,0x1200,0x0c00,0x0200,0x2200,0x1c00,0x0000,\n  0x0000,0x0000, // u00a7\n  0x2200,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00a8\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x9c80,0xa280,0xa080,0xa080,0xa280,0x9c80,0x4100,0x3e00,0x0000,0x0000,\n  0x0000,0x0000, // u00a9\n  0x0000,0x1e00,0x0100,0x1f00,0x2100,0x2100,0x1f00,0x0000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0880,0x1100,0x2200,0x4400,0x8800,0x4400,0x2200,0x1100,0x0880,0x0000,\n  0x0000,0x0000, // u00ab\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0100,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00ac\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00ad\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0xbc80,0xa280,0xa280,0xbc80,0xa480,0xa280,0x4100,0x3e00,0x0000,0x0000,\n  0x0000,0x0000, // u00ae\n  0x0000,0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00af\n  0x0000,0x1c00,0x2200,0x2200,0x2200,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x7f00,0x0800,0x0800,0x0800,0x0000,0x0000,0x7f00,0x0000,\n  0x0000,0x0000, // u00b1\n  0x0000,0x1c00,0x2200,0x2200,0x0400,0x0800,0x1000,0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00b2\n  0x0000,0x1c00,0x2200,0x0200,0x0c00,0x0200,0x2200,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00b3\n  0x0400,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4300,0x7d00,0x4000,\n  0x4000,0x4000, // u00b5\n  0x0000,0x0000,0x0000,0x3f00,0x4900,0x4900,0x4900,0x4900,0x4900,0x3900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0000,\n  0x0000,0x0000, // u00b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00b7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,\n  0x0800,0x1000, // u00b8\n  0x0000,0x0800,0x1800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00b9\n  0x0000,0x1e00,0x2100,0x2100,0x2100,0x2100,0x1e00,0x0000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x8800,0x4400,0x2200,0x1100,0x0880,0x1100,0x2200,0x4400,0x8800,0x0000,\n  0x0000,0x0000, // u00bb\n  0x0000,0x0000,0x2000,0x6000,0x2080,0x2100,0x2200,0x2400,0x0800,0x1100,0x2300,0x4500,0x8900,0x0f00,0x0100,0x0100,\n  0x0000,0x0000, // u00bc\n  0x0000,0x0000,0x2000,0x6000,0x2080,0x2100,0x2200,0x2400,0x0800,0x1000,0x2600,0x4900,0x8100,0x0200,0x0400,0x0f00,\n  0x0000,0x0000, // u00bd\n  0x0000,0x0000,0xe000,0x1000,0x6080,0x1100,0x1200,0xe400,0x0800,0x1100,0x2300,0x4500,0x8900,0x0f00,0x0100,0x0100,\n  0x0000,0x0000, // u00be\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0800,0x0800,0x1000,0x2000,0x4000,0x4100,0x4100,0x2200,0x1c00,0x0000,\n  0x0000,0x0000, // u00bf\n  0x1000,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u00c0\n  0x0400,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u00c1\n  0x1c00,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u00c2\n  0x3300,0x4c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u00c3\n  0x2200,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u00c4\n  0x1c00,0x2200,0x1c00,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u00c5\n  0x0000,0x0000,0x0000,0x7f80,0x8800,0x8800,0x8800,0x8800,0xff00,0x8800,0x8800,0x8800,0x8800,0x8800,0x8f80,0x0000,\n  0x0000,0x0000, // u00c6\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x4100,0x3e00,0x0800,\n  0x0800,0x1000, // u00c7\n  0x1000,0x0800,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u00c8\n  0x0400,0x0800,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u00c9\n  0x1c00,0x2200,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u00ca\n  0x2200,0x2200,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u00cb\n  0x1000,0x0800,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u00cc\n  0x0400,0x0800,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u00cd\n  0x1c00,0x2200,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u00ce\n  0x2200,0x2200,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u00cf\n  0x0000,0x0000,0x0000,0x7c00,0x4200,0x4100,0x4100,0x4100,0xf900,0x4100,0x4100,0x4100,0x4100,0x4200,0x7c00,0x0000,\n  0x0000,0x0000, // u00d0\n  0x3300,0x4c00,0x0000,0x4100,0x4100,0x4100,0x6100,0x5100,0x4900,0x4500,0x4300,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u00d1\n  0x1000,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u00d2\n  0x0400,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u00d3\n  0x1c00,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u00d4\n  0x3300,0x4c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u00d5\n  0x2200,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u00d6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x2200,0x1400,0x0800,0x1400,0x2200,0x4100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00d7\n  0x0000,0x0000,0x0000,0x3e00,0x4180,0x4100,0x4300,0x4500,0x4900,0x5100,0x6100,0x4100,0xc100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u00d8\n  0x1000,0x0800,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u00d9\n  0x0400,0x0800,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u00da\n  0x1c00,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u00db\n  0x2200,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u00dc\n  0x0400,0x0800,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u00dd\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x4000,0x4000,0x4000,0x0000,\n  0x0000,0x0000, // u00de\n  0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4400,0x7e00,0x4100,0x4100,0x4100,0x4100,0x6100,0x5e00,0x0000,\n  0x0000,0x0000, // u00df\n  0x0000,0x0000,0x0000,0x1000,0x0800,0x0000,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u00e0\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u00e1\n  0x0000,0x0000,0x0000,0x1c00,0x2200,0x0000,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u00e2\n  0x0000,0x0000,0x0000,0x3300,0x4c00,0x0000,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u00e3\n  0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u00e4\n  0x0000,0x0000,0x0000,0x1c00,0x2200,0x1c00,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u00e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7700,0x0880,0x0880,0x7880,0x8f80,0x8800,0x8800,0x8880,0x7700,0x0000,\n  0x0000,0x0000, // u00e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x3e00,0x0800,\n  0x0800,0x1000, // u00e7\n  0x0000,0x0000,0x0000,0x1000,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u00e8\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u00e9\n  0x0000,0x0000,0x0000,0x1c00,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u00ea\n  0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u00eb\n  0x0000,0x0000,0x0000,0x1000,0x0800,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u00ec\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u00ed\n  0x0000,0x0000,0x0000,0x1c00,0x2200,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u00ee\n  0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u00ef\n  0x0000,0x0000,0x0000,0x2c00,0x1000,0x6800,0x0400,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u00f0\n  0x0000,0x0000,0x0000,0x3300,0x4c00,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u00f1\n  0x0000,0x0000,0x0000,0x1000,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u00f2\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u00f3\n  0x0000,0x0000,0x0000,0x1c00,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u00f4\n  0x0000,0x0000,0x0000,0x3300,0x4c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u00f5\n  0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u00f6\n  0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x7f00,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00f7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e80,0x4100,0x4300,0x4500,0x4900,0x5100,0x6100,0x4100,0xbe00,0x0000,\n  0x0000,0x0000, // u00f8\n  0x0000,0x0000,0x0000,0x1000,0x0800,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u00f9\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u00fa\n  0x0000,0x0000,0x0000,0x1c00,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u00fb\n  0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u00fc\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,\n  0x0100,0x3e00, // u00fd\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x4000,\n  0x4000,0x4000, // u00fe\n  0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,\n  0x0100,0x3e00, // u00ff\n  0x0000,0x3e00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u0100\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u0101\n  0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u0102\n  0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u0103\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x0100,\n  0x0200,0x0180, // u0104\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,\n  0x0200,0x0180, // u0105\n  0x0400,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0106\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x3e00,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0107\n  0x1c00,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0108\n  0x0000,0x0000,0x0000,0x1c00,0x2200,0x0000,0x3e00,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0109\n  0x0800,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u010a\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x3e00,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u010b\n  0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u010c\n  0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u010d\n  0x2200,0x1c00,0x0000,0x7c00,0x4200,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4200,0x7c00,0x0000,\n  0x0000,0x0000, // u010e\n  0x2200,0x1c00,0x0000,0x0100,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u010f\n  0x0000,0x0000,0x0000,0x7c00,0x4200,0x4100,0x4100,0x4100,0xf900,0x4100,0x4100,0x4100,0x4100,0x4200,0x7c00,0x0000,\n  0x0000,0x0000, // u0110\n  0x0000,0x0000,0x0000,0x0100,0x0f80,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u0111\n  0x0000,0x3e00,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u0112\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0113\n  0x2200,0x1c00,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u0114\n  0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0115\n  0x0800,0x0800,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u0116\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0117\n  0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0100,\n  0x0200,0x0180, // u0118\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,0x0800,\n  0x1000,0x0c00, // u0119\n  0x2200,0x1c00,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u011a\n  0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u011b\n  0x1c00,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4f00,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u011c\n  0x0000,0x0000,0x0000,0x1c00,0x2200,0x0000,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,\n  0x0100,0x3e00, // u011d\n  0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4f00,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u011e\n  0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,\n  0x0100,0x3e00, // u011f\n  0x0800,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4f00,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0120\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,\n  0x0100,0x3e00, // u0121\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4f00,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0800,\n  0x0800,0x1000, // u0122\n  0x0000,0x0000,0x0400,0x0800,0x0800,0x0000,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,\n  0x0100,0x3e00, // u0123\n  0x1c00,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u0124\n  0x1c00,0x2200,0x0000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u0125\n  0x0000,0x0000,0x0000,0x4100,0x4100,0xff80,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u0126\n  0x0000,0x0000,0x0000,0x4000,0xf800,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u0127\n  0x3300,0x4c00,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u0128\n  0x0000,0x0000,0x0000,0x3300,0x4c00,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u0129\n  0x0000,0x3e00,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u012a\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u012b\n  0x2200,0x1c00,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u012c\n  0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u012d\n  0x0000,0x0000,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0800,\n  0x1000,0x0c00, // u012e\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0800,\n  0x1000,0x0c00, // u012f\n  0x0800,0x0800,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u0130\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u0131\n  0x0000,0x0000,0x0000,0xe380,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4900,0x4900,0x4900,0xe600,0x0000,\n  0x0000,0x0000, // u0132\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x0000,0x6180,0x2080,0x2080,0x2080,0x2080,0x2080,0x2080,0x2080,0x7080,0x0480,\n  0x0480,0x0300, // u0133\n  0x0700,0x0880,0x0000,0x0700,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x4200,0x4200,0x4200,0x3c00,0x0000,\n  0x0000,0x0000, // u0134\n  0x0000,0x0000,0x0000,0x0700,0x0880,0x0000,0x0600,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x2200,\n  0x2200,0x1c00, // u0135\n  0x0000,0x0000,0x0000,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,0x0800,\n  0x0800,0x1000, // u0136\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4100,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x4100,0x0800,\n  0x0800,0x1000, // u0137\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x4100,0x0000,\n  0x0000,0x0000, // u0138\n  0x2000,0x4000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u0139\n  0x0400,0x0800,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u013a\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0800,\n  0x0800,0x1000, // u013b\n  0x0000,0x0000,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0800,\n  0x0800,0x1000, // u013c\n  0x2200,0x1c00,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u013d\n  0x2200,0x1c00,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u013e\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4200,0x4200,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u013f\n  0x0000,0x0000,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0840,0x0840,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u0140\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x2800,0x3000,0x2000,0x6000,0xa000,0x2000,0x2000,0x2000,0x3f80,0x0000,\n  0x0000,0x0000, // u0141\n  0x0000,0x0000,0x0000,0x1800,0x0800,0x0800,0x0a00,0x0c00,0x0800,0x1800,0x2800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u0142\n  0x0400,0x0800,0x0000,0x4100,0x4100,0x4100,0x6100,0x5100,0x4900,0x4500,0x4300,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u0143\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u0144\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x6100,0x5100,0x4900,0x4500,0x4300,0x4100,0x4100,0x4100,0x4100,0x0800,\n  0x0800,0x1000, // u0145\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0800,\n  0x0800,0x1000, // u0146\n  0x2200,0x1c00,0x0000,0x4100,0x4100,0x4100,0x6100,0x5100,0x4900,0x4500,0x4300,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u0147\n  0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u0148\n  0x0000,0x4000,0x4000,0x4000,0x8000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u0149\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x6100,0x5100,0x4900,0x4500,0x4300,0x4100,0x4100,0x4100,0x4100,0x0100,\n  0x0100,0x0600, // u014a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0100,\n  0x0100,0x0600, // u014b\n  0x0000,0x3e00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u014c\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u014d\n  0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u014e\n  0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u014f\n  0x1100,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0150\n  0x0000,0x0000,0x0000,0x1100,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0151\n  0x0000,0x0000,0x0000,0x7f80,0x8800,0x8800,0x8800,0x8800,0x8f00,0x8800,0x8800,0x8800,0x8800,0x8800,0x7f80,0x0000,\n  0x0000,0x0000, // u0152\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x8880,0x8880,0x8880,0x8f80,0x8800,0x8800,0x8880,0x7f00,0x0000,\n  0x0000,0x0000, // u0153\n  0x0400,0x0800,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x5000,0x4800,0x4400,0x4200,0x4100,0x0000,\n  0x0000,0x0000, // u0154\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x4f00,0x5000,0x6000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,\n  0x0000,0x0000, // u0155\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x5000,0x4800,0x4400,0x4200,0x4100,0x0800,\n  0x0800,0x1000, // u0156\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4f00,0x5000,0x6000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x2000,\n  0x2000,0x4000, // u0157\n  0x2200,0x1c00,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x5000,0x4800,0x4400,0x4200,0x4100,0x0000,\n  0x0000,0x0000, // u0158\n  0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x4f00,0x5000,0x6000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,\n  0x0000,0x0000, // u0159\n  0x0400,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x3e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u015a\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x3e00,0x4100,0x4000,0x4000,0x3e00,0x0100,0x0100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u015b\n  0x1c00,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x3e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u015c\n  0x0000,0x0000,0x0000,0x1c00,0x2200,0x0000,0x3e00,0x4100,0x4000,0x4000,0x3e00,0x0100,0x0100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u015d\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x3e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,0x0800,\n  0x0800,0x1000, // u015e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4000,0x4000,0x3e00,0x0100,0x0100,0x4100,0x3e00,0x0800,\n  0x0800,0x1000, // u015f\n  0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x3e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0160\n  0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4000,0x4000,0x3e00,0x0100,0x0100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0161\n  0x0000,0x0000,0x0000,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0400,\n  0x0400,0x0800, // u0162\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x3e00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0700,0x0200,\n  0x0200,0x0400, // u0163\n  0x2200,0x1c00,0x0000,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u0164\n  0x2200,0x1c00,0x0000,0x0800,0x0800,0x0800,0x3e00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0700,0x0000,\n  0x0000,0x0000, // u0165\n  0x0000,0x0000,0x0000,0x7f00,0x0800,0x0800,0x0800,0x0800,0x3e00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u0166\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x3e00,0x0800,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0700,0x0000,\n  0x0000,0x0000, // u0167\n  0x3300,0x4c00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0168\n  0x0000,0x0000,0x0000,0x3300,0x4c00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u0169\n  0x0000,0x3e00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u016a\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u016b\n  0x2200,0x1c00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u016c\n  0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u016d\n  0x1c00,0x2200,0x1c00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u016e\n  0x0000,0x0000,0x0000,0x1c00,0x2200,0x1c00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u016f\n  0x1100,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0170\n  0x0000,0x0000,0x0000,0x1100,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u0171\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0800,\n  0x1000,0x0c00, // u0172\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,\n  0x0200,0x0180, // u0173\n  0x1c00,0x2200,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4c80,0x4c80,0x5280,0x5280,0x6180,0x4080,0x0000,\n  0x0000,0x0000, // u0174\n  0x0000,0x0000,0x0000,0x1c00,0x2200,0x0000,0x4100,0x4100,0x4100,0x4900,0x4900,0x4900,0x4900,0x4900,0x3e00,0x0000,\n  0x0000,0x0000, // u0175\n  0x1c00,0x2200,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u0176\n  0x0000,0x0000,0x0000,0x1c00,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,\n  0x0100,0x3e00, // u0177\n  0x2200,0x2200,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u0178\n  0x0400,0x0800,0x0000,0x7f00,0x0100,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u0179\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x7f00,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u017a\n  0x0800,0x0800,0x0000,0x7f00,0x0100,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u017b\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x7f00,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u017c\n  0x2200,0x1c00,0x0000,0x7f00,0x0100,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u017d\n  0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x7f00,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u017e\n  0x0000,0x0000,0x0000,0x0700,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u017f\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0186\n  0x0000,0x0000,0x0000,0x7f00,0x0100,0x0100,0x0100,0x0100,0x1f00,0x0100,0x0100,0x0100,0x0100,0x0100,0x7f00,0x0000,\n  0x0000,0x0000, // u018e\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x0100,0x0100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u018f\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x3c00,0x4000,0x4000,0x4000,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0190\n  0x0000,0x0000,0x0000,0x0600,0x0900,0x0900,0x0800,0x0800,0x3e00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x4800,\n  0x4800,0x3000, // u0192\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x6100,0x5100,0x4900,0x4500,0x4300,0x4100,0x4100,0x4100,0x4100,0x4000,\n  0x4000,0x8000, // u019d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0100,\n  0x0100,0x0100, // u019e\n  0x0000,0x0000,0x0000,0x7f00,0x0100,0x0100,0x0200,0x0400,0x7f00,0x0800,0x1000,0x2000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u01b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0100,0x0200,0x0400,0x7f00,0x1000,0x2000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u01b6\n  0x0000,0x0000,0x0000,0x7f00,0x0100,0x0200,0x0400,0x0800,0x1e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u01b7\n  0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u01cd\n  0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u01ce\n  0x2200,0x1c00,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u01cf\n  0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u01d0\n  0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u01d1\n  0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u01d2\n  0x2200,0x1c00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u01d3\n  0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u01d4\n  0x0000,0x3f00,0x0000,0x7f80,0x8800,0x8800,0x8800,0x8800,0xff00,0x8800,0x8800,0x8800,0x8800,0x8800,0x8f80,0x0000,\n  0x0000,0x0000, // u01e2\n  0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x7700,0x0880,0x0880,0x7880,0x8f80,0x8800,0x8800,0x8880,0x7700,0x0000,\n  0x0000,0x0000, // u01e3\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4f00,0x4100,0x4780,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u01e4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x4100,0x4100,0x4100,0x4780,0x4100,0x4100,0x4100,0x3f00,0x0100,\n  0x0100,0x3e00, // u01e5\n  0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4f00,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u01e6\n  0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,\n  0x0100,0x3e00, // u01e7\n  0x2200,0x1c00,0x0000,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,0x0000,\n  0x0000,0x0000, // u01e8\n  0x2200,0x1c00,0x0000,0x4000,0x4000,0x4000,0x4100,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x4100,0x0000,\n  0x0000,0x0000, // u01e9\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0800,\n  0x1000,0x0c00, // u01ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0800,\n  0x1000,0x0c00, // u01eb\n  0x0000,0x3e00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0800,\n  0x1000,0x0c00, // u01ec\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0800,\n  0x1000,0x0c00, // u01ed\n  0x2200,0x1c00,0x0000,0x7f00,0x0100,0x0200,0x0400,0x0800,0x1e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u01ee\n  0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x7f00,0x0100,0x0200,0x0400,0x0800,0x1e00,0x0100,0x0100,0x0100,0x4100,\n  0x4100,0x3e00, // u01ef\n  0x0000,0x0000,0x0000,0x0880,0x0700,0x0000,0x0600,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x2200,\n  0x2200,0x1c00, // u01f0\n  0x0400,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4f00,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u01f4\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,\n  0x0100,0x3e00, // u01f5\n  0x0400,0x0800,0x0000,0x7f80,0x8800,0x8800,0x8800,0x8800,0xff00,0x8800,0x8800,0x8800,0x8800,0x8800,0x8f80,0x0000,\n  0x0000,0x0000, // u01fc\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x7700,0x0880,0x0880,0x7880,0x8f80,0x8800,0x8800,0x8880,0x7700,0x0000,\n  0x0000,0x0000, // u01fd\n  0x0400,0x0800,0x0000,0x3e00,0x4180,0x4100,0x4300,0x4500,0x4900,0x5100,0x6100,0x4100,0xc100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u01fe\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x3e80,0x4100,0x4300,0x4500,0x4900,0x5100,0x6100,0x4100,0xbe00,0x0000,\n  0x0000,0x0000, // u01ff\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x3e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,0x0800,\n  0x0800,0x1000, // u0218\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4000,0x4000,0x3e00,0x0100,0x0100,0x4100,0x3e00,0x0800,\n  0x0800,0x1000, // u0219\n  0x0000,0x0000,0x0000,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0400,\n  0x0400,0x0800, // u021a\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x3e00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0700,0x0100,\n  0x0100,0x0200, // u021b\n  0x0000,0x3e00,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u0232\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,\n  0x0100,0x3e00, // u0233\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x2200,\n  0x2200,0x1c00, // u0237\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x0100,0x0100,0x0100,0x0100,0x0100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0254\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x0100,0x0100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0258\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x0100,0x0100,0x7f00,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0259\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4000,0x4000,0x3c00,0x4000,0x4000,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u025b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4000,\n  0x4000,0x8000, // u0272\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0100,0x0200,0x0400,0x0800,0x1e00,0x0100,0x0100,0x0100,0x4100,\n  0x4100,0x3e00, // u0292\n  0x0400,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u02bb\n  0x0800,0x0800,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u02bc\n  0x0800,0x0800,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u02bd\n  0x1c00,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u02c6\n  0x2200,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u02c7\n  0x2200,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u02d8\n  0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u02d9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,\n  0x1000,0x0c00, // u02db\n  0x3300,0x4c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u02dc\n  0x1100,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u02dd\n  0x1000,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0300\n  0x0400,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0301\n  0x1c00,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0302\n  0x3300,0x4c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0303\n  0x0000,0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0304\n  0x0000,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0305\n  0x2200,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0306\n  0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0307\n  0x2200,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0308\n  0x1c00,0x2200,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u030a\n  0x1100,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u030b\n  0x2200,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u030c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0800,0x0800, // u0329\n  0x0000,0x4000,0x8000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0384\n  0x0400,0x0800,0x0000,0x2200,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0385\n  0x0000,0x4000,0x8000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u0386\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0387\n  0x0000,0x4000,0x8000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u0388\n  0x0000,0x4000,0x8000,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u0389\n  0x0000,0x4000,0x8000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u038a\n  0x0000,0x4000,0x8000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u038c\n  0x0000,0x4000,0x8000,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0a00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0000,\n  0x0000,0x0000, // u038e\n  0x0000,0x4000,0x8000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x2200,0x1400,0x1400,0x7700,0x0000,\n  0x0000,0x0000, // u038f\n  0x0400,0x0800,0x0000,0x2200,0x2200,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0600,0x0000,\n  0x0000,0x0000, // u0390\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u0391\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x0000,\n  0x0000,0x0000, // u0392\n  0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,\n  0x0000,0x0000, // u0393\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x1400,0x1400,0x1400,0x2200,0x2200,0x2200,0x4100,0x4100,0x7f00,0x0000,\n  0x0000,0x0000, // u0394\n  0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u0395\n  0x0000,0x0000,0x0000,0x7f00,0x0100,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u0396\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u0397\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x5d00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0398\n  0x0000,0x0000,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u0399\n  0x0000,0x0000,0x0000,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,0x0000,\n  0x0000,0x0000, // u039a\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x1400,0x1400,0x1400,0x2200,0x2200,0x2200,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u039b\n  0x0000,0x0000,0x0000,0x4080,0x6180,0x5280,0x5280,0x4c80,0x4c80,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x0000,\n  0x0000,0x0000, // u039c\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x6100,0x5100,0x4900,0x4500,0x4300,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u039d\n  0x0000,0x0000,0x0000,0x7f00,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0000,\n  0x0000,0x0000, // u039e\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u039f\n  0x0000,0x0000,0x0000,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u03a0\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,\n  0x0000,0x0000, // u03a1\n  0x0000,0x0000,0x0000,0x7f00,0x4000,0x2000,0x1000,0x0800,0x0400,0x0400,0x0800,0x1000,0x2000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u03a3\n  0x0000,0x0000,0x0000,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u03a4\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u03a5\n  0x0000,0x0000,0x0000,0x0800,0x3e00,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x3e00,0x0800,0x0000,\n  0x0000,0x0000, // u03a6\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x0800,0x0800,0x1400,0x2200,0x2200,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u03a7\n  0x0000,0x0000,0x0000,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x3e00,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u03a8\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x2200,0x1400,0x1400,0x7700,0x0000,\n  0x0000,0x0000, // u03a9\n  0x2200,0x2200,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u03aa\n  0x2200,0x2200,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u03ab\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x3d80,0x4300,0x4200,0x4200,0x4200,0x4200,0x4200,0x4300,0x3d80,0x0000,\n  0x0000,0x0000, // u03ac\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x3e00,0x4100,0x4000,0x4000,0x3c00,0x4000,0x4000,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u03ad\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0100,\n  0x0100,0x0100, // u03ae\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0600,0x0000,\n  0x0000,0x0000, // u03af\n  0x0400,0x0800,0x0000,0x2200,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u03b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3d80,0x4300,0x4200,0x4200,0x4200,0x4200,0x4200,0x4300,0x3d80,0x0000,\n  0x0000,0x0000, // u03b1\n  0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4400,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x4000,\n  0x4000,0x4000, // u03b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x2200,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,\n  0x0800,0x0800, // u03b3\n  0x0000,0x0000,0x0000,0x3e00,0x1000,0x0800,0x1c00,0x2200,0x4100,0x4100,0x4100,0x4100,0x4100,0x2200,0x1c00,0x0000,\n  0x0000,0x0000, // u03b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4000,0x4000,0x3c00,0x4000,0x4000,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u03b5\n  0x0000,0x0000,0x0000,0x7f00,0x0200,0x0400,0x0800,0x1000,0x2000,0x2000,0x4000,0x4000,0x4000,0x4000,0x3e00,0x0100,\n  0x0100,0x0200, // u03b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0100,\n  0x0100,0x0100, // u03b7\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x2100,0x2100,0x2100,0x3f00,0x2100,0x2100,0x2100,0x2100,0x2100,0x1e00,0x0000,\n  0x0000,0x0000, // u03b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0600,0x0000,\n  0x0000,0x0000, // u03b9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x4100,0x0000,\n  0x0000,0x0000, // u03ba\n  0x0000,0x0000,0x0000,0x1000,0x1000,0x0800,0x0800,0x1400,0x1400,0x2200,0x2200,0x2200,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u03bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4300,0x7d00,0x4000,\n  0x4000,0x4000, // u03bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u03bd\n  0x0000,0x0000,0x0000,0x3f00,0x4000,0x4000,0x4000,0x4000,0x3e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x3e00,0x0100,\n  0x0100,0x0200, // u03be\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u03bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u03c0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x4000,\n  0x4000,0x4000, // u03c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x3e00,0x0100,\n  0x0100,0x0200, // u03c2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x2200,0x4100,0x4100,0x4100,0x4100,0x4100,0x2200,0x1c00,0x0000,\n  0x0000,0x0000, // u03c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0600,0x0000,\n  0x0000,0x0000, // u03c4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u03c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2600,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x3e00,0x0800,\n  0x0800,0x0800, // u03c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x0800,0x0800,0x1400,0x2200,0x2200,\n  0x4100,0x4100, // u03c7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x3e00,0x0800,\n  0x0800,0x0800, // u03c8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2200,0x4100,0x4100,0x4900,0x4900,0x4900,0x4900,0x4900,0x3600,0x0000,\n  0x0000,0x0000, // u03c9\n  0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0600,0x0000,\n  0x0000,0x0000, // u03ca\n  0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u03cb\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u03cc\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u03cd\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x2200,0x4100,0x4100,0x4900,0x4900,0x4900,0x4900,0x4900,0x3600,0x0000,\n  0x0000,0x0000, // u03ce\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x2100,0x2100,0x1f80,0x0100,0x0100,0x6100,0x2100,0x2100,0x2100,0x1e00,0x0000,\n  0x0000,0x0000, // u03d1\n  0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x3e00,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x3e00,0x0800,\n  0x0800,0x0000, // u03d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xe080,0x1100,0x0a00,0x0c00,0x0800,0x1800,0x2800,0x4400,0x8380,0x0000,\n  0x0000,0x0000, // u03f0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x4000,\n  0x4000,0x3e00, // u03f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u03f2\n  0x0000,0x0000,0x0000,0x0200,0x0200,0x0000,0x0600,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x2200,\n  0x2200,0x1c00, // u03f3\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u03f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2000,0x4000,0x4000,0x7e00,0x4000,0x4000,0x2000,0x1f00,0x0000,\n  0x0000,0x0000, // u03f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0200,0x0100,0x0100,0x3f00,0x0100,0x0100,0x0200,0x7c00,0x0000,\n  0x0000,0x0000, // u03f6\n  0x1000,0x0800,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u0400\n  0x2200,0x2200,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u0401\n  0x0000,0x0000,0x0000,0xf800,0x2000,0x2000,0x3e00,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2600,0x0000,\n  0x0000,0x0000, // u0402\n  0x0400,0x0800,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,\n  0x0000,0x0000, // u0403\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0404\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x3e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0405\n  0x0000,0x0000,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u0406\n  0x2200,0x2200,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u0407\n  0x0000,0x0000,0x0000,0x0380,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x2100,0x2100,0x2100,0x1e00,0x0000,\n  0x0000,0x0000, // u0408\n  0x0000,0x0000,0x0000,0x3800,0x4800,0x8800,0x8800,0x8f00,0x8880,0x8880,0x8880,0x8880,0x8880,0x8880,0x8f00,0x0000,\n  0x0000,0x0000, // u0409\n  0x0000,0x0000,0x0000,0x8800,0x8800,0x8800,0x8800,0x8f00,0xf880,0x8880,0x8880,0x8880,0x8880,0x8880,0x8f00,0x0000,\n  0x0000,0x0000, // u040a\n  0x0000,0x0000,0x0000,0xf800,0x2000,0x2000,0x3e00,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0000, // u040b\n  0x0400,0x0800,0x0000,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,0x0000,\n  0x0000,0x0000, // u040c\n  0x1000,0x0800,0x0000,0x4100,0x4100,0x4100,0x4300,0x4500,0x4900,0x5100,0x6100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u040d\n  0x2200,0x1c00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,0x0100,0x0100,0x0100,0x3e00,0x0000,\n  0x0000,0x0000, // u040e\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x0800,\n  0x0800,0x0000, // u040f\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u0410\n  0x0000,0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x0000,\n  0x0000,0x0000, // u0411\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x0000,\n  0x0000,0x0000, // u0412\n  0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,\n  0x0000,0x0000, // u0413\n  0x0000,0x0000,0x0000,0x0f00,0x1100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x7f80,0x4080,\n  0x4080,0x0000, // u0414\n  0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u0415\n  0x0000,0x0000,0x0000,0x4900,0x4900,0x4900,0x4900,0x2a00,0x1c00,0x2a00,0x4900,0x4900,0x4900,0x4900,0x4900,0x0000,\n  0x0000,0x0000, // u0416\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x0100,0x0100,0x1e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0417\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4300,0x4500,0x4900,0x5100,0x6100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u0418\n  0x2200,0x1c00,0x0000,0x4100,0x4100,0x4100,0x4300,0x4500,0x4900,0x5100,0x6100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u0419\n  0x0000,0x0000,0x0000,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,0x0000,\n  0x0000,0x0000, // u041a\n  0x0000,0x0000,0x0000,0x0f00,0x1100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x4100,0x0000,\n  0x0000,0x0000, // u041b\n  0x0000,0x0000,0x0000,0x4080,0x6180,0x5280,0x5280,0x4c80,0x4c80,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x0000,\n  0x0000,0x0000, // u041c\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u041d\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u041e\n  0x0000,0x0000,0x0000,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u041f\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,\n  0x0000,0x0000, // u0420\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0421\n  0x0000,0x0000,0x0000,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u0422\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,0x0100,0x0100,0x0100,0x3e00,0x0000,\n  0x0000,0x0000, // u0423\n  0x0000,0x0000,0x0800,0x3e00,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x3e00,0x0800,\n  0x0000,0x0000, // u0424\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x0800,0x0800,0x1400,0x2200,0x2200,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u0425\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f80,0x0080,\n  0x0080,0x0000, // u0426\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,0x0100,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0000, // u0427\n  0x0000,0x0000,0x0000,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x3f00,0x0000,\n  0x0000,0x0000, // u0428\n  0x0000,0x0000,0x0000,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x3f80,0x0080,\n  0x0080,0x0000, // u0429\n  0x0000,0x0000,0x0000,0xc000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x0000,\n  0x0000,0x0000, // u042a\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x7880,0x4480,0x4480,0x4480,0x4480,0x4480,0x4480,0x7880,0x0000,\n  0x0000,0x0000, // u042b\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x0000,\n  0x0000,0x0000, // u042c\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x0100,0x0100,0x1f00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u042d\n  0x0000,0x0000,0x0000,0x4700,0x4880,0x4880,0x4880,0x4880,0x7880,0x4880,0x4880,0x4880,0x4880,0x4880,0x4700,0x0000,\n  0x0000,0x0000, // u042e\n  0x0000,0x0000,0x0000,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0500,0x0900,0x1100,0x2100,0x4100,0x0000,\n  0x0000,0x0000, // u042f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u0430\n  0x0000,0x0000,0x0000,0x3e00,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x0000,\n  0x0000,0x0000, // u0431\n  0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4400,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x0000,\n  0x0000,0x0000, // u0432\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,\n  0x0000,0x0000, // u0433\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,\n  0x0100,0x3e00, // u0434\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0435\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4900,0x4900,0x4900,0x2a00,0x1c00,0x2a00,0x4900,0x4900,0x4900,0x0000,\n  0x0000,0x0000, // u0436\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x0100,0x0100,0x1e00,0x0100,0x0100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0437\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u0438\n  0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u0439\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x4100,0x0000,\n  0x0000,0x0000, // u043a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x1100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x4100,0x0000,\n  0x0000,0x0000, // u043b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x6300,0x5500,0x4900,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u043c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u043d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u043e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u043f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x4000,\n  0x4000,0x4000, // u0440\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0441\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u0442\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,\n  0x0100,0x3e00, // u0443\n  0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x3e00,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x3e00,0x0800,\n  0x0800,0x0000, // u0444\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x1400,0x0800,0x1400,0x2200,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u0445\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f80,0x0080,\n  0x0080,0x0000, // u0446\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0000, // u0447\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x3f00,0x0000,\n  0x0000,0x0000, // u0448\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x3f80,0x0080,\n  0x0080,0x0000, // u0449\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x2000,0x2000,0x3e00,0x2100,0x2100,0x2100,0x2100,0x3e00,0x0000,\n  0x0000,0x0000, // u044a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x7880,0x4480,0x4480,0x4480,0x4480,0x7880,0x0000,\n  0x0000,0x0000, // u044b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x3e00,0x2100,0x2100,0x2100,0x2100,0x3e00,0x0000,\n  0x0000,0x0000, // u044c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x0100,0x0100,0x1f00,0x0100,0x0100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u044d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4700,0x4880,0x4880,0x4880,0x7880,0x4880,0x4880,0x4880,0x4700,0x0000,\n  0x0000,0x0000, // u044e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x4100,0x4100,0x4100,0x3f00,0x0500,0x0900,0x1100,0x2100,0x0000,\n  0x0000,0x0000, // u044f\n  0x0000,0x0000,0x0000,0x1000,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0450\n  0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0451\n  0x0000,0x0000,0x0000,0x4000,0xf800,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0100,\n  0x0100,0x0600, // u0452\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,\n  0x0000,0x0000, // u0453\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0454\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4000,0x4000,0x3e00,0x0100,0x0100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u0455\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u0456\n  0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u0457\n  0x0000,0x0000,0x0000,0x0200,0x0200,0x0000,0x0600,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x2200,\n  0x2200,0x1c00, // u0458\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x4800,0x8800,0x8f00,0x8880,0x8880,0x8880,0x8880,0x8f00,0x0000,\n  0x0000,0x0000, // u0459\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0x8800,0x8f00,0xf880,0x8880,0x8880,0x8880,0x8f00,0x0000,\n  0x0000,0x0000, // u045a\n  0x0000,0x0000,0x0000,0x4000,0xf800,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u045b\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x4100,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x4100,0x0000,\n  0x0000,0x0000, // u045c\n  0x0000,0x0000,0x0000,0x1000,0x0800,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u045d\n  0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,\n  0x0100,0x3e00, // u045e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x0800,\n  0x0800,0x0000, // u045f\n  0x0000,0x0000,0x0000,0x4000,0xf800,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x0000,\n  0x0000,0x0000, // u0462\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0xf800,0x2000,0x2000,0x3e00,0x2100,0x2100,0x2100,0x2100,0x3e00,0x0000,\n  0x0000,0x0000, // u0463\n  0x0000,0x0000,0x0000,0x7f00,0x4100,0x2200,0x2200,0x1400,0x0800,0x1c00,0x2a00,0x4900,0x4900,0x4900,0x4900,0x0000,\n  0x0000,0x0000, // u046a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4100,0x2200,0x1400,0x1c00,0x2a00,0x4900,0x4900,0x4900,0x0000,\n  0x0000,0x0000, // u046b\n  0x0000,0x0100,0x0100,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,\n  0x0000,0x0000, // u0490\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,\n  0x0000,0x0000, // u0491\n  0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0xf800,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,\n  0x0000,0x0000, // u0492\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0xf800,0x4000,0x4000,0x4000,0x4000,0x0000,\n  0x0000,0x0000, // u0493\n  0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x0100,\n  0x0200,0x0000, // u0494\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,0x0200,\n  0x0400,0x0000, // u0495\n  0x0000,0x0000,0x0000,0x4900,0x4900,0x4900,0x4900,0x2a00,0x1c00,0x2a00,0x4900,0x4900,0x4900,0x4900,0x4980,0x0080,\n  0x0080,0x0000, // u0496\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4900,0x4900,0x4900,0x2a00,0x1c00,0x2a00,0x4900,0x4900,0x4980,0x0080,\n  0x0080,0x0000, // u0497\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x0100,0x0100,0x1e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,0x0800,\n  0x0800,0x0800, // u0498\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x0100,0x0100,0x1e00,0x0100,0x0100,0x4100,0x3e00,0x0800,\n  0x0800,0x0800, // u0499\n  0x0000,0x0000,0x0000,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4180,0x0080,\n  0x0080,0x0000, // u049a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x4180,0x0080,\n  0x0080,0x0000, // u049b\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4200,0x5400,0x5800,0x7000,0x7000,0x5800,0x5400,0x4200,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u049c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x5200,0x5400,0x5800,0x7000,0x5800,0x5400,0x5200,0x4100,0x0000,\n  0x0000,0x0000, // u049d\n  0x0000,0x0000,0x0000,0xc100,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,0x0000,\n  0x0000,0x0000, // u04a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc100,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x4100,0x0000,\n  0x0000,0x0000, // u04a1\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4180,0x0080,\n  0x0080,0x0000, // u04a2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4180,0x0080,\n  0x0080,0x0000, // u04a3\n  0x0000,0x0000,0x0000,0x43c0,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x0000,\n  0x0000,0x0000, // u04a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x43c0,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x0000,\n  0x0000,0x0000, // u04a5\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x4100,0x3e00,0x0800,\n  0x0800,0x0800, // u04aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x3e00,0x0800,\n  0x0800,0x0800, // u04ab\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u04ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x2200,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,\n  0x0800,0x0800, // u04af\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x3e00,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u04b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x2200,0x2200,0x2200,0x1400,0x1400,0x0800,0x3e00,\n  0x0800,0x0800, // u04b1\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x0800,0x0800,0x1400,0x2200,0x2200,0x4100,0x4180,0x0080,\n  0x0080,0x0000, // u04b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x1400,0x0800,0x1400,0x2200,0x4100,0x4180,0x0080,\n  0x0080,0x0000, // u04b3\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,0x0100,0x0100,0x0100,0x0180,0x0080,\n  0x0080,0x0000, // u04b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,0x0100,0x0100,0x0180,0x0080,\n  0x0080,0x0000, // u04b7\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4900,0x4900,0x4900,0x3f00,0x0900,0x0900,0x0900,0x0100,0x0100,0x0000,\n  0x0000,0x0000, // u04b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4900,0x4900,0x3f00,0x0900,0x0900,0x0100,0x0100,0x0000,\n  0x0000,0x0000, // u04b9\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u04ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u04bb\n  0x0000,0x0000,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u04c0\n  0x2200,0x1c00,0x0000,0x4900,0x4900,0x4900,0x4900,0x2a00,0x1c00,0x2a00,0x4900,0x4900,0x4900,0x4900,0x4900,0x0000,\n  0x0000,0x0000, // u04c1\n  0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x4900,0x4900,0x4900,0x2a00,0x1c00,0x2a00,0x4900,0x4900,0x4900,0x0000,\n  0x0000,0x0000, // u04c2\n  0x0000,0x0000,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0000,0x0000, // u04cf\n  0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u04d0\n  0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u04d1\n  0x2200,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u04d2\n  0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u04d3\n  0x0000,0x0000,0x0000,0x7f80,0x8800,0x8800,0x8800,0x8800,0xff00,0x8800,0x8800,0x8800,0x8800,0x8800,0x8f80,0x0000,\n  0x0000,0x0000, // u04d4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7700,0x0880,0x0880,0x7880,0x8f80,0x8800,0x8800,0x8880,0x7700,0x0000,\n  0x0000,0x0000, // u04d5\n  0x2200,0x1c00,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u04d6\n  0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u04d7\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x0100,0x0100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u04d8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x0100,0x0100,0x7f00,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u04d9\n  0x2200,0x2200,0x0000,0x3e00,0x4100,0x4100,0x0100,0x0100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u04da\n  0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x3e00,0x4100,0x0100,0x0100,0x7f00,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u04db\n  0x2200,0x2200,0x0000,0x4900,0x4900,0x4900,0x4900,0x2a00,0x1c00,0x2a00,0x4900,0x4900,0x4900,0x4900,0x4900,0x0000,\n  0x0000,0x0000, // u04dc\n  0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x4900,0x4900,0x4900,0x2a00,0x1c00,0x2a00,0x4900,0x4900,0x4900,0x0000,\n  0x0000,0x0000, // u04dd\n  0x2200,0x2200,0x0000,0x3e00,0x4100,0x4100,0x0100,0x0100,0x1e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u04de\n  0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x3e00,0x4100,0x0100,0x0100,0x1e00,0x0100,0x0100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u04df\n  0x0000,0x3e00,0x0000,0x4100,0x4100,0x4100,0x4300,0x4500,0x4900,0x5100,0x6100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u04e2\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u04e3\n  0x2200,0x2200,0x0000,0x4100,0x4100,0x4100,0x4300,0x4500,0x4900,0x5100,0x6100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u04e4\n  0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0000,0x0000, // u04e5\n  0x2200,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u04e6\n  0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u04e7\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u04e8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u04e9\n  0x2200,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u04ea\n  0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u04eb\n  0x2200,0x2200,0x0000,0x3e00,0x4100,0x4100,0x0100,0x0100,0x1f00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u04ec\n  0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x3e00,0x4100,0x0100,0x0100,0x1f00,0x0100,0x0100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u04ed\n  0x0000,0x3e00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,0x0100,0x0100,0x0100,0x3e00,0x0000,\n  0x0000,0x0000, // u04ee\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,\n  0x0100,0x3e00, // u04ef\n  0x2200,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,0x0100,0x0100,0x0100,0x3e00,0x0000,\n  0x0000,0x0000, // u04f0\n  0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,\n  0x0100,0x3e00, // u04f1\n  0x1100,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,0x0100,0x0100,0x0100,0x3e00,0x0000,\n  0x0000,0x0000, // u04f2\n  0x0000,0x0000,0x0000,0x1100,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,\n  0x0100,0x3e00, // u04f3\n  0x2200,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,0x0100,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0000, // u04f4\n  0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0000, // u04f5\n  0x2200,0x2200,0x0000,0x4080,0x4080,0x4080,0x4080,0x7880,0x4480,0x4480,0x4480,0x4480,0x4480,0x4480,0x7880,0x0000,\n  0x0000,0x0000, // u04f8\n  0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x4080,0x4080,0x4080,0x7880,0x4480,0x4480,0x4480,0x4480,0x7880,0x0000,\n  0x0000,0x0000, // u04f9\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x1080,0x1080,0x0880,0x1900,0x2600,0x4400,0x4200,0x4200,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u05d0\n  0x0000,0x0000,0x0000,0x7e00,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x7f80,0x0000,\n  0x0000,0x0000, // u05d1\n  0x0000,0x0000,0x0000,0x3c00,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0600,0x0900,0x1100,0x2080,0x4080,0x0000,\n  0x0000,0x0000, // u05d2\n  0x0000,0x0000,0x0000,0x7f80,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0000, // u05d3\n  0x0000,0x0000,0x0000,0x7e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u05d4\n  0x0000,0x0000,0x0000,0x3000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u05d5\n  0x0000,0x0000,0x0000,0x3f00,0x0200,0x0400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u05d6\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u05d7\n  0x0000,0x0000,0x0000,0x4600,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u05d8\n  0x0000,0x0000,0x0000,0x3000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u05d9\n  0x0000,0x0000,0x0000,0x7e00,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0100,0x0100, // u05da\n  0x0000,0x0000,0x0000,0x7e00,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x7e00,0x0000,\n  0x0000,0x0000, // u05db\n  0x0000,0x4000,0x4000,0x7f00,0x0100,0x0100,0x0100,0x0100,0x0200,0x0400,0x0800,0x1000,0x1000,0x1000,0x1000,0x0000,\n  0x0000,0x0000, // u05dc\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x0000,\n  0x0000,0x0000, // u05dd\n  0x0000,0x0000,0x0000,0xdc00,0x6200,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4700,0x0000,\n  0x0000,0x0000, // u05de\n  0x0000,0x0000,0x0000,0x7800,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400, // u05df\n  0x0000,0x0000,0x0000,0x3c00,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x3e00,0x0000,\n  0x0000,0x0000, // u05e0\n  0x0000,0x0000,0x0000,0xfe00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u05e1\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x2100,0x2100,0x2100,0x1100,0x1200,0x1200,0x0c00,0x1800,0x6000,0x0000,\n  0x0000,0x0000, // u05e2\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x3100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0100,0x0100, // u05e3\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x3100,0x0100,0x0100,0x0100,0x0100,0x0100,0x7e00,0x0000,\n  0x0000,0x0000, // u05e4\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x2100,0x2100,0x1200,0x1400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u05e5\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x2100,0x2100,0x1200,0x1400,0x0800,0x0800,0x0400,0x0400,0x0200,0x7e00,0x0000,\n  0x0000,0x0000, // u05e6\n  0x0000,0x0000,0x0000,0x7f00,0x0100,0x0100,0x0100,0x4100,0x4100,0x4200,0x4400,0x4800,0x4800,0x4800,0x4800,0x4000,\n  0x4000,0x4000, // u05e7\n  0x0000,0x0000,0x0000,0x7e00,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0000, // u05e8\n  0x0000,0x0000,0x0000,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x5100,0x6100,0x4100,0x4100,0x4200,0x7c00,0x0000,\n  0x0000,0x0000, // u05e9\n  0x0000,0x0000,0x0000,0xfe00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x8100,0x0000,\n  0x0000,0x0000, // u05ea\n  0x0000,0x0000,0x0000,0x7c00,0x4200,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4200,0x7c00,0x0000,\n  0x1000,0x1000, // u1e0c\n  0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0800,0x0800, // u1e0d\n  0x0000,0x0000,0x0000,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,0x0000,\n  0x3e00,0x0000, // u1e34\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4100,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x4100,0x0000,\n  0x3e00,0x0000, // u1e35\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0800,0x0800, // u1e36\n  0x0000,0x0000,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0800,0x0800, // u1e37\n  0x0800,0x0800,0x0000,0x4080,0x6180,0x5280,0x5280,0x4c80,0x4c80,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x0000,\n  0x0000,0x0000, // u1e40\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x7e00,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x0000,\n  0x0000,0x0000, // u1e41\n  0x0000,0x0000,0x0000,0x4080,0x6180,0x5280,0x5280,0x4c80,0x4c80,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x0000,\n  0x0800,0x0800, // u1e42\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x0000,\n  0x0800,0x0800, // u1e43\n  0x0800,0x0800,0x0000,0x4100,0x4100,0x4100,0x6100,0x5100,0x4900,0x4500,0x4300,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u1e44\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u1e45\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x6100,0x5100,0x4900,0x4500,0x4300,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0800,0x0800, // u1e46\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0800,0x0800, // u1e47\n  0x0000,0x0000,0x0000,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0800,0x0800, // u1e6c\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x3e00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0700,0x0200,\n  0x0200,0x0000, // u1e6d\n  0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0800,0x0800, // u1eb8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,0x0000,\n  0x0800,0x0800, // u1eb9\n  0x3300,0x4c00,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u1ebc\n  0x0000,0x0000,0x0000,0x3300,0x4c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,0x0000,\n  0x0000,0x0000, // u1ebd\n  0x0000,0x0000,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0800,0x0800, // u1eca\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,\n  0x0800,0x0800, // u1ecb\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0800,0x0800, // u1ecc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0800,0x0800, // u1ecd\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0000,\n  0x0800,0x0800, // u1ee4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0000,\n  0x0800,0x0800, // u1ee5\n  0x3300,0x4c00,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u1ef8\n  0x0000,0x0000,0x0000,0x3300,0x4c00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,\n  0x0100,0x3e00, // u1ef9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2001\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2002\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2003\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2004\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2005\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2006\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2007\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2008\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2009\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u200a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u200b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u200c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u200d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u200e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u200f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2010\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2011\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2012\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2013\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2014\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2015\n  0x0000,0x0000,0x0000,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x0000,\n  0x0000,0x0000, // u2016\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,\n  0x0000,0x7f00, // u2017\n  0x0000,0x0400,0x0800,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2018\n  0x0000,0x0800,0x0800,0x0800,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2019\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x1000,\n  0x0000,0x0000, // u201a\n  0x0000,0x1000,0x1000,0x1000,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u201b\n  0x0000,0x1100,0x2200,0x2200,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u201c\n  0x0000,0x1100,0x1100,0x1100,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u201d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2200,0x2200,0x2200,0x4400,\n  0x0000,0x0000, // u201e\n  0x0000,0x4400,0x4400,0x4400,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u201f\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u2020\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x7f00,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u2021\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x1e00,0x1e00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2022\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4900,0x4900,0x0000,\n  0x0000,0x0000, // u2026\n  0x0000,0x0000,0x0000,0xe400,0xa400,0xe800,0x0800,0x1000,0x1000,0x2000,0x2000,0x4000,0x5dc0,0x9540,0x9dc0,0x0000,\n  0x0000,0x0000, // u2030\n  0x0000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2032\n  0x0000,0x2200,0x2200,0x2200,0x2200,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2033\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x1000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0000,\n  0x0000,0x0000, // u2039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0400,0x0800,0x1000,0x2000,0x0000,\n  0x0000,0x0000, // u203a\n  0x0000,0x0000,0x0000,0x2200,0x2200,0x2200,0x2200,0x2200,0x2200,0x2200,0x2200,0x0000,0x0000,0x2200,0x2200,0x0000,\n  0x0000,0x0000, // u203c\n  0x0000,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u203e\n  0x0000,0x1c00,0x2200,0x2200,0x2200,0x2200,0x2200,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2070\n  0x0800,0x0800,0x0000,0x1800,0x0800,0x0800,0x0800,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2071\n  0x0000,0x0200,0x0600,0x0a00,0x1200,0x3f00,0x0200,0x0200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2074\n  0x0000,0x3c00,0x2000,0x2000,0x3c00,0x0200,0x0200,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2075\n  0x0000,0x1c00,0x2000,0x2000,0x3c00,0x2200,0x2200,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2076\n  0x0000,0x3e00,0x0200,0x0400,0x0400,0x0800,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2077\n  0x0000,0x1c00,0x2200,0x2200,0x1c00,0x2200,0x2200,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2078\n  0x0000,0x1c00,0x2200,0x2200,0x1e00,0x0200,0x0200,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2079\n  0x0000,0x0000,0x0800,0x0800,0x3e00,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u207a\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u207b\n  0x0000,0x0000,0x0000,0x3e00,0x0000,0x0000,0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u207c\n  0x0000,0x0400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u207d\n  0x0000,0x0800,0x0400,0x0400,0x0400,0x0400,0x0400,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u207e\n  0x0000,0x0000,0x3c00,0x2200,0x2200,0x2200,0x2200,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u207f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x2200,0x2200,0x2200,0x2200,0x1c00,\n  0x0000,0x0000, // u2080\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x1800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000, // u2081\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x2200,0x0400,0x0800,0x1000,0x3e00,\n  0x0000,0x0000, // u2082\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x0200,0x0c00,0x0200,0x2200,0x1c00,\n  0x0000,0x0000, // u2083\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0200,0x0600,0x0a00,0x1200,0x3f00,0x0200,0x0200,\n  0x0000,0x0000, // u2084\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x2000,0x2000,0x3c00,0x0200,0x0200,0x3c00,\n  0x0000,0x0000, // u2085\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x2000,0x2000,0x3c00,0x2200,0x2200,0x1c00,\n  0x0000,0x0000, // u2086\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0200,0x0400,0x0400,0x0800,0x0800,0x0800,\n  0x0000,0x0000, // u2087\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x2200,0x1c00,0x2200,0x2200,0x1c00,\n  0x0000,0x0000, // u2088\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x2200,0x1e00,0x0200,0x0200,0x1c00,\n  0x0000,0x0000, // u2089\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x3e00,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u208a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u208b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x0000,0x3e00,0x0000,0x0000,\n  0x0000,0x0000, // u208c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0400,\n  0x0000,0x0000, // u208d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0400,0x0400,0x0400,0x0400,0x0400,0x0800,\n  0x0000,0x0000, // u208e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0200,0x1e00,0x2200,0x2200,0x1e00,\n  0x0000,0x0000, // u2090\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x3e00,0x2000,0x2000,0x1e00,\n  0x0000,0x0000, // u2091\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x2200,0x2200,0x2200,0x1c00,\n  0x0000,0x0000, // u2092\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2200,0x1400,0x0800,0x0800,0x1400,0x2200,\n  0x0000,0x0000, // u2093\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x0200,0x0200,0x3e00,0x2200,0x1c00,\n  0x0000,0x0000, // u2094\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x3c00,0x2200,0x2200,0x2200,0x2200,0x2200,\n  0x0000,0x0000, // u2095\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2200,0x2400,0x2800,0x3800,0x2400,0x2200,\n  0x0000,0x0000, // u2096\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000, // u2097\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4900,0x4900,0x4900,0x4900,0x4900,\n  0x0000,0x0000, // u2098\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x2200,0x2200,0x2200,0x2200,0x3c00,\n  0x2000,0x2000, // u209a\n  0x0000,0x0000,0x0000,0x7800,0x4400,0x4400,0x4400,0x4400,0x7a00,0x4200,0x4700,0x4200,0x4200,0x4200,0x4100,0x0000,\n  0x0000,0x0000, // u20a7\n  0x0000,0x0000,0x0000,0x7900,0x4500,0x4500,0x5500,0x5500,0x5500,0x5500,0x5500,0x5500,0x5100,0x5100,0x5e00,0x0000,\n  0x0000,0x0000, // u20aa\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4000,0xfc00,0x4000,0x4000,0xfc00,0x4000,0x4080,0x2100,0x1e00,0x0000,\n  0x0000,0x0000, // u20ac\n  0x0000,0x0000,0x0000,0x7f00,0x0800,0x0800,0x0800,0x0e00,0x3800,0x0e00,0x3800,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u20ae\n  0x0000,0x0000,0x0000,0x3e00,0x5100,0x5100,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5100,0x5100,0x3e00,0x0000,\n  0x0000,0x0000, // u2102\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u210e\n  0x0000,0x0000,0x0000,0x4000,0xf800,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u210f\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x6100,0x5100,0x6900,0x5500,0x4b00,0x4500,0x4300,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u2115\n  0x0000,0x0000,0x0000,0x8400,0x8480,0xc540,0xc540,0xa480,0xa400,0x9400,0x9400,0x8dc0,0x8c00,0x85c0,0x8400,0x0000,\n  0x0000,0x0000, // u2116\n  0x0000,0x0000,0x0000,0x3e00,0x5100,0x5100,0x5100,0x5100,0x5100,0x5100,0x5100,0x5100,0x5100,0x5500,0x3e00,0x0100,\n  0x0080,0x0000, // u211a\n  0x0000,0x0000,0x0000,0x7e00,0x5100,0x5100,0x5100,0x5100,0x5100,0x5e00,0x5400,0x5a00,0x5500,0x5280,0x7180,0x0000,\n  0x0000,0x0000, // u211d\n  0x0000,0x0000,0x0000,0xe880,0x4d80,0x4a80,0x4880,0x4880,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2122\n  0x0000,0x0000,0x0000,0x7f00,0x0100,0x0300,0x0500,0x0a00,0x1400,0x2800,0x5000,0x6000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u2124\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x2200,0x1400,0x1400,0x7700,0x0000,\n  0x0000,0x0000, // u2126\n  0x0000,0x0000,0x0000,0x4200,0x4200,0x2100,0x2100,0x1080,0x3100,0x4a00,0x8c00,0x8400,0x8400,0x8200,0x4200,0x0000,\n  0x0000,0x0000, // u2135\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x2000,0x4000,0xff80,0x4000,0x2000,0x1000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2190\n  0x0000,0x0000,0x0000,0x0800,0x1c00,0x2a00,0x4900,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u2191\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0200,0x0100,0xff80,0x0100,0x0200,0x0400,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2192\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x4900,0x2a00,0x1c00,0x0800,0x0000,\n  0x0000,0x0000, // u2193\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1200,0x2100,0x4080,0xffc0,0x4080,0x2100,0x1200,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2194\n  0x0000,0x0000,0x0000,0x0800,0x1c00,0x2a00,0x4900,0x0800,0x0800,0x0800,0x0800,0x4900,0x2a00,0x1c00,0x0800,0x0000,\n  0x0000,0x0000, // u2195\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1080,0x2080,0x4080,0xff80,0x4080,0x2080,0x1080,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u21a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x8400,0x8200,0x8100,0xff80,0x8100,0x8200,0x8400,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u21a6\n  0x0000,0x0000,0x0000,0x0800,0x1c00,0x2a00,0x4900,0x0800,0x0800,0x0800,0x4900,0x2a00,0x1c00,0x0800,0x7f00,0x0000,\n  0x0000,0x0000, // u21a8\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0080,0x0080,0x1080,0x2080,0x4080,0xff80,0x4000,0x2000,0x1000,0x0000,\n  0x0000,0x0000, // u21b5\n  0x0000,0x0000,0x0000,0x0000,0x7800,0x1800,0x2800,0x4880,0x4080,0x4080,0x4080,0x2100,0x1e00,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u21bb\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x2000,0x4000,0xff80,0x0000,0xff80,0x0100,0x0200,0x0400,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u21cb\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0200,0x0100,0xff80,0x0000,0xff80,0x4000,0x2000,0x1000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u21cc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x2000,0x7f80,0xc000,0x7f80,0x2000,0x1000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u21d0\n  0x0000,0x0000,0x0000,0x0800,0x1c00,0x3600,0x5500,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x0000,\n  0x0000,0x0000, // u21d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0200,0xff00,0x0180,0xff00,0x0200,0x0400,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u21d2\n  0x0000,0x0000,0x0000,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x5500,0x3600,0x1c00,0x0800,0x0000,\n  0x0000,0x0000, // u21d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1200,0x2100,0x7f80,0xc0c0,0x7f80,0x2100,0x1200,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u21d4\n  0x0000,0x0000,0x0000,0x0800,0x1c00,0x3600,0x5500,0x1400,0x1400,0x1400,0x1400,0x5500,0x3600,0x1c00,0x0800,0x0000,\n  0x0000,0x0000, // u21d5\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x7f00,0x2200,0x2200,0x2200,0x1400,0x1400,0x1400,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u2200\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x0100,0x0100,0x0100,0x0100,0x7f00,0x0100,0x0100,0x0100,0x0100,0x7f00,0x0000,\n  0x0000,0x0000, // u2203\n  0x0000,0x0000,0x0000,0x0200,0x7f00,0x0500,0x0500,0x0900,0x0900,0x7f00,0x1100,0x1100,0x2100,0x2100,0x7f00,0x4000,\n  0x0000,0x0000, // u2204\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x3e00,0x4500,0x4500,0x4900,0x5100,0x5100,0x3e00,0x2000,0x4000,0x0000,\n  0x0000,0x0000, // u2205\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x1400,0x1400,0x1400,0x2200,0x2200,0x2200,0x4100,0x4100,0x7f00,0x0000,\n  0x0000,0x0000, // u2206\n  0x0000,0x0000,0x0000,0x7f00,0x4100,0x4100,0x2200,0x2200,0x2200,0x1400,0x1400,0x1400,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u2207\n  0x0000,0x0000,0x0000,0x0000,0x0f00,0x1000,0x2000,0x4000,0x4000,0x7f00,0x4000,0x4000,0x2000,0x1000,0x0f00,0x0000,\n  0x0000,0x0000, // u2208\n  0x0000,0x0000,0x0000,0x0100,0x0f00,0x1200,0x2200,0x4400,0x4400,0x7f00,0x4800,0x4800,0x3000,0x1000,0x2f00,0x2000,\n  0x0000,0x0000, // u2209\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2000,0x4000,0x4000,0x7f00,0x4000,0x4000,0x2000,0x1f00,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u220a\n  0x0000,0x0000,0x0000,0x0000,0x7800,0x0400,0x0200,0x0100,0x0100,0x7f00,0x0100,0x0100,0x0200,0x0400,0x7800,0x0000,\n  0x0000,0x0000, // u220b\n  0x0000,0x0000,0x0000,0x4000,0x7800,0x2400,0x2200,0x1100,0x1100,0x7f00,0x0900,0x0900,0x0600,0x0400,0x7a00,0x0200,\n  0x0000,0x0000, // u220c\n  0x0000,0x0000,0x0000,0x0000,0x7c00,0x0200,0x0100,0x0100,0x7f00,0x0100,0x0100,0x0200,0x7c00,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u220d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2212\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0000,0x0000,0x0800,0x0800,0x0800,0x7f00,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u2213\n  0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0800,0x0800,0x0800,0x7f00,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u2214\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2215\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,0x0080,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2216\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2219\n  0x0000,0x0380,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x4200,0x4200,0x4200,0x2200,0x1200,0x0a00,0x0600,0x0000,\n  0x0000,0x0000, // u221a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3600,0x4900,0x4900,0x4900,0x4900,0x3600,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u221e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u221f\n  0x0000,0x0000,0x0000,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x0000,\n  0x0000,0x0000, // u2225\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x1400,0x1400,0x2200,0x2200,0x2200,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u2227\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u2228\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u2229\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x2200,0x1c00,0x0000,\n  0x0000,0x0000, // u222a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3100,0x4900,0x4600,0x0000,0x3100,0x4900,0x4600,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2248\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x7f00,0x0400,0x0800,0x1000,0x7f00,0x4000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2260\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x0000,0x0000,0x0000,0x7f00,0x0000,0x0000,0x0000,0x7f00,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2261\n  0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x1000,0x2000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0000,0x7f00,0x0000,\n  0x0000,0x0000, // u2264\n  0x0000,0x0000,0x0000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0200,0x0400,0x0800,0x1000,0x2000,0x0000,0x7f00,0x0000,\n  0x0000,0x0000, // u2265\n  0x0000,0x0000,0x0000,0x0000,0x0440,0x0880,0x1100,0x2200,0x4400,0x8800,0x4400,0x2200,0x1100,0x0880,0x0440,0x0000,\n  0x0000,0x0000, // u226a\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x4400,0x2200,0x1100,0x0880,0x0440,0x0880,0x1100,0x2200,0x4400,0x8800,0x0000,\n  0x0000,0x0000, // u226b\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2000,0x4000,0x4000,0x4000,0x4000,0x4000,0x2000,0x1f00,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2282\n  0x0000,0x0000,0x0000,0x0000,0x7c00,0x0200,0x0100,0x0100,0x0100,0x0100,0x0100,0x0200,0x7c00,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2283\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2000,0x4000,0x4000,0x4000,0x4000,0x4000,0x2000,0x1f00,0x0000,0x7f00,0x0000,\n  0x0000,0x0000, // u2286\n  0x0000,0x0000,0x0000,0x0000,0x7c00,0x0200,0x0100,0x0100,0x0100,0x0100,0x0100,0x0200,0x7c00,0x0000,0x7f00,0x0000,\n  0x0000,0x0000, // u2287\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x7f00,0x0000,\n  0x0000,0x0000, // u22a5\n  0x0000,0x0000,0x0000,0x1c00,0x2200,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u22c2\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x2200,0x1c00,0x0000,\n  0x0000,0x0000, // u22c3\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x3e00,0x4500,0x4500,0x4900,0x5100,0x5100,0x3e00,0x2000,0x4000,0x0000,\n  0x0000,0x0000, // u2300\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x1400,0x2200,0x4100,0x8080,0x8080,0x8080,0x8080,0x8080,0xff80,0x0000,\n  0x0000,0x0000, // u2302\n  0x0000,0x0000,0x0000,0x1c00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0000,\n  0x0000,0x0000, // u2308\n  0x0000,0x0000,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0000,\n  0x0000,0x0000, // u2309\n  0x0000,0x0000,0x0000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1c00,0x0000,\n  0x0000,0x0000, // u230a\n  0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x1c00,0x0000,\n  0x0000,0x0000, // u230b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2310\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2319\n  0x0000,0x0000,0x0000,0x0600,0x0900,0x0900,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u2320\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x4800,0x4800,0x3000,0x0000,\n  0x0000,0x0000, // u2321\n  0x0100,0x0200,0x0400,0x0400,0x0800,0x0800,0x0800,0x1000,0x1000,0x1000,0x1000,0x2000,0x2000,0x2000,0x2000,0x2000,\n  0x2000,0x2000, // u239b\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,\n  0x2000,0x2000, // u239c\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x1000,0x1000,0x1000,0x1000,0x0800,0x0800,0x0800,0x0400,0x0400,\n  0x0200,0x0100, // u239d\n  0x2000,0x1000,0x0800,0x0800,0x0400,0x0400,0x0400,0x0200,0x0200,0x0200,0x0200,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0100,0x0100, // u239e\n  0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0100,0x0100, // u239f\n  0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0200,0x0200,0x0200,0x0200,0x0400,0x0400,0x0400,0x0800,0x0800,\n  0x1000,0x2000, // u23a0\n  0x3f00,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,\n  0x2000,0x2000, // u23a1\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,\n  0x2000,0x2000, // u23a2\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,\n  0x2000,0x3f00, // u23a3\n  0x3f00,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0100,0x0100, // u23a4\n  0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0100,0x0100, // u23a5\n  0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0100,0x3f00, // u23a6\n  0x0380,0x0c00,0x0800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,\n  0x1000,0x1000, // u23a7\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x2000,0xc000,0xc000,0x2000,0x1000,0x1000,0x1000,0x1000,0x1000,\n  0x1000,0x1000, // u23a8\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0800,\n  0x0c00,0x0380, // u23a9\n  0xe000,0x1800,0x0800,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400, // u23ab\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0200,0x0180,0x0180,0x0200,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400, // u23ac\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0800,\n  0x1800,0xe000, // u23ad\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u23ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u23af\n  0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u23ba\n  0x0000,0x0000,0x0000,0x0000,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u23bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0000,0x0000,\n  0x0000,0x0000, // u23bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0xffc0, // u23bd\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u23d0\n  0x0000,0x0000,0x4400,0x4400,0x7c00,0x4400,0x4400,0x4400,0x0000,0x0f80,0x0200,0x0200,0x0200,0x0200,0x0200,0x0000,\n  0x0000,0x0000, // u2409\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x0000,0x0f80,0x0800,0x0e00,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u240a\n  0x0000,0x0000,0x4400,0x4400,0x2800,0x2800,0x1000,0x1000,0x0000,0x0000,0x0f80,0x0200,0x0200,0x0200,0x0200,0x0200,\n  0x0000,0x0000, // u240b\n  0x0000,0x0000,0x7c00,0x4000,0x7000,0x4000,0x4000,0x4000,0x0000,0x0f80,0x0800,0x0e00,0x0800,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u240c\n  0x0000,0x0000,0x3800,0x4400,0x4000,0x4000,0x4400,0x3800,0x0000,0x0f00,0x0880,0x0880,0x0f00,0x0900,0x0880,0x0000,\n  0x0000,0x0000, // u240d\n  0x0000,0x0000,0x4400,0x6400,0x5400,0x4c00,0x4400,0x4400,0x0000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0f80,0x0000,\n  0x0000,0x0000, // u2424\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2500\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2501\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u2502\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2503\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xd680,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2508\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xd680,0xd680,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2509\n  0x0800,0x0800,0x0800,0x0800,0x0000,0x0800,0x0800,0x0800,0x0000,0x0800,0x0800,0x0800,0x0800,0x0000,0x0800,0x0800,\n  0x0800,0x0000, // u250a\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0c00,0x0c00,0x0c00,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0c00,0x0c00,\n  0x0c00,0x0000, // u250b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u250c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fc0,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u250d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u250e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u250f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u2510\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u2511\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2512\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2513\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2514\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2515\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2516\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2517\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2518\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2519\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u251a\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u251b\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0fc0,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u251c\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0fc0,0x0fc0,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u251d\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u251e\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u251f\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2520\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0fc0,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u2521\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0fc0,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2522\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2523\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xf800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u2524\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xf800,0xf800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u2525\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u2526\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2527\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2528\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u2529\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u252a\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u252b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u252c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xf800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u252d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0fc0,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u252e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u252f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2530\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2531\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2532\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2533\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2534\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2535\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2536\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2537\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2538\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2539\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u253a\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u253b\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u253c\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0xf800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u253d\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0x0fc0,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u253e\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0xffc0,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u253f\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u2540\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2541\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2542\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xf800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u2543\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0x0fc0,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u2544\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2545\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2546\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xffc0,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u2547\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2548\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2549\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u254a\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u254b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0000,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2550\n  0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x1400,0x1400, // u2551\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0800,0x0fc0,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u2552\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x1400,0x1400, // u2553\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x1000,0x17c0,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x1400,0x1400, // u2554\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0x0800,0xf800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u2555\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x1400,0x1400, // u2556\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x0400,0xf400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x1400,0x1400, // u2557\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0fc0,0x0800,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2558\n  0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2559\n  0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x17c0,0x1000,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u255a\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xf800,0x0800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u255b\n  0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u255c\n  0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0xf400,0x0400,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u255d\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0fc0,0x0800,0x0fc0,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u255e\n  0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x17c0,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x1400,0x1400, // u255f\n  0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x17c0,0x1000,0x17c0,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x1400,0x1400, // u2560\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xf800,0x0800,0xf800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u2561\n  0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0xf400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x1400,0x1400, // u2562\n  0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0xf400,0x0400,0xf400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x1400,0x1400, // u2563\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0000,0xffc0,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u2564\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x1400,0x1400, // u2565\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0000,0xf7c0,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x1400,0x1400, // u2566\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0x0000,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2567\n  0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2568\n  0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0xf7c0,0x0000,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2569\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0x0800,0xffc0,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u256a\n  0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0xffc0,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x1400,0x1400, // u256b\n  0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0xf7c0,0x0000,0xf7c0,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x1400,0x1400, // u256c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x0200,0x0400,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u256d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0x2000,0x1000,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u256e\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1000,0x2000,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u256f\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0400,0x0200,0x01c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2570\n  0x0040,0x0080,0x0080,0x0100,0x0100,0x0200,0x0200,0x0400,0x0400,0x0800,0x0800,0x1000,0x1000,0x2000,0x2000,0x4000,\n  0x4000,0x8000, // u2571\n  0x8000,0x4000,0x4000,0x2000,0x2000,0x1000,0x1000,0x0800,0x0800,0x0400,0x0400,0x0200,0x0200,0x0100,0x0100,0x0080,\n  0x0080,0x0040, // u2572\n  0x8040,0x4080,0x4080,0x2100,0x2100,0x1200,0x1200,0x0c00,0x0c00,0x0c00,0x0c00,0x1200,0x1200,0x2100,0x2100,0x4080,\n  0x4080,0x8040, // u2573\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2574\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2575\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2576\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u2577\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2578\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2579\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u257a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u257b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u257c\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u257d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u257e\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800, // u257f\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2580\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0xffc0,0xffc0, // u2581\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,\n  0xffc0,0xffc0, // u2582\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0, // u2583\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0, // u2584\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0, // u2585\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0, // u2586\n  0x0000,0x0000,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0, // u2587\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0, // u2588\n  0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,\n  0xff80,0xff80, // u2589\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,\n  0xfe00,0xfe00, // u258a\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,\n  0xfc00,0xfc00, // u258b\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800, // u258c\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,\n  0xf000,0xf000, // u258d\n  0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,\n  0xc000,0xc000, // u258e\n  0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,\n  0x8000,0x8000, // u258f\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,\n  0x07c0,0x07c0, // u2590\n  0xaa80,0x0000,0xaa80,0x0000,0xaa80,0x0000,0xaa80,0x0000,0xaa80,0x0000,0xaa80,0x0000,0xaa80,0x0000,0xaa80,0x0000,\n  0xaa80,0x0000, // u2591\n  0xaa80,0x5540,0xaa80,0x5540,0xaa80,0x5540,0xaa80,0x5540,0xaa80,0x5540,0xaa80,0x5540,0xaa80,0x5540,0xaa80,0x5540,\n  0xaa80,0x5540, // u2592\n  0xffc0,0xaa80,0xffc0,0xaa80,0xffc0,0xaa80,0xffc0,0xaa80,0xffc0,0xaa80,0xffc0,0xaa80,0xffc0,0xaa80,0xffc0,0xaa80,\n  0xffc0,0xaa80, // u2593\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800, // u2596\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,\n  0x07c0,0x07c0, // u2597\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2598\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0, // u2599\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,\n  0x07c0,0x07c0, // u259a\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800, // u259b\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,\n  0x07c0,0x07c0, // u259c\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u259d\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800, // u259e\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0, // u259f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x3e00,0x3e00,0x3e00,0x3e00,0x3e00,0x3e00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u25a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,0x0000,\n  0x0000,0x0000, // u25ac\n  0x0000,0x0000,0x0000,0x7f00,0x7f00,0x7f00,0x7f00,0x7f00,0x7f00,0x7f00,0x7f00,0x7f00,0x7f00,0x7f00,0x7f00,0x0000,\n  0x0000,0x0000, // u25ae\n  0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x1c00,0x1c00,0x3e00,0x3e00,0x7f00,0x7f00,0xff80,0xff80,0x0000,0x0000,\n  0x0000,0x0000, // u25b2\n  0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xffc0,0xff00,0xfc00,0xf000,0xc000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u25b6\n  0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xffc0,0xff00,0xfc00,0xf000,0xc000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u25ba\n  0x0000,0x0000,0x0000,0x0000,0xff80,0xff80,0x7f00,0x7f00,0x3e00,0x3e00,0x1c00,0x1c00,0x0800,0x0800,0x0000,0x0000,\n  0x0000,0x0000, // u25bc\n  0x0000,0x0000,0x0000,0x0000,0x00c0,0x03c0,0x0fc0,0x3fc0,0xffc0,0x3fc0,0x0fc0,0x03c0,0x00c0,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u25c0\n  0x0000,0x0000,0x0000,0x0000,0x00c0,0x03c0,0x0fc0,0x3fc0,0xffc0,0x3fc0,0x0fc0,0x03c0,0x00c0,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u25c4\n  0x0000,0x0000,0x0000,0x0000,0x0800,0x1c00,0x3e00,0x7f00,0xff80,0x7f00,0x3e00,0x1c00,0x0800,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u25c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x1400,0x2200,0x4100,0x8080,0x4100,0x2200,0x1400,0x0800,0x0000,0x0000,\n  0x0000,0x0000, // u25ca\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x2100,0x2100,0x2100,0x1e00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u25cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3f00,0x3f00,0x3f00,0x3f00,0x1e00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u25cf\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xf3c0,0xe1c0,0xe1c0,0xf3c0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0, // u25d8\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xe1c0,0xdec0,0xdec0,0xdec0,0xdec0,0xe1c0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0, // u25d9\n  0x0000,0x0000,0x0000,0x7f00,0x8080,0x8080,0xb680,0xb680,0x8080,0x8080,0xbe80,0x9c80,0x8080,0x8080,0x7f00,0x0000,\n  0x0000,0x0000, // u263a\n  0x0000,0x0000,0x0000,0x7f00,0xff80,0xff80,0xc980,0xc980,0xff80,0xff80,0xc180,0xe380,0xff80,0xff80,0x7f00,0x0000,\n  0x0000,0x0000, // u263b\n  0x0000,0x0000,0x0000,0x0800,0x8880,0x4900,0x2a00,0x1c00,0xf780,0x1c00,0x2a00,0x4900,0x8880,0x0800,0x0000,0x0000,\n  0x0000,0x0000, // u263c\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0800,0x0800,0x7f00,0x0800,0x0800,0x0000,\n  0x0000,0x0000, // u2640\n  0x0000,0x0000,0x0000,0x0f00,0x0300,0x0500,0x0900,0x3c00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,0x3c00,0x0000,\n  0x0000,0x0000, // u2642\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x1c00,0x3e00,0x7f00,0xff80,0xff80,0xff80,0x6b00,0x0800,0x0800,0x3e00,0x0000,\n  0x0000,0x0000, // u2660\n  0x0000,0x0000,0x0000,0x1c00,0x3e00,0x3e00,0x1c00,0x0800,0x6b00,0xff80,0xff80,0xff80,0x6b00,0x0800,0x3e00,0x0000,\n  0x0000,0x0000, // u2663\n  0x0000,0x0000,0x0000,0x0000,0x6300,0xf780,0xff80,0xff80,0xff80,0xff80,0x7f00,0x3e00,0x1c00,0x0800,0x0000,0x0000,\n  0x0000,0x0000, // u2665\n  0x0000,0x0000,0x0000,0x0000,0x0800,0x1c00,0x3e00,0x7f00,0xff80,0x7f00,0x3e00,0x1c00,0x0800,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2666\n  0x0000,0x0000,0x0000,0x1f80,0x1080,0x1080,0x1f80,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xe000,0x0000,\n  0x0000,0x0000, // u266a\n  0x0000,0x0000,0x0000,0x7f00,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4200,0x8000,0x0000,\n  0x0000,0x0000, // u266b\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0100,0x0100,0x8200,0x8200,0x4400,0x4400,0x2800,0x2800,0x1000,0x1000,0x0000,\n  0x0000,0x0000, // u2713\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x0180,0x0180,0xc300,0xc300,0x6600,0x6600,0x3c00,0x3c00,0x1800,0x1800,0x0000,\n  0x0000,0x0000, // u2714\n  0x0000,0x0000,0x0000,0x0200,0x4200,0x2400,0x1400,0x0800,0x0c00,0x1200,0x1100,0x2000,0x2000,0x4000,0x4000,0x0000,\n  0x0000,0x0000, // u2717\n  0x0000,0x0000,0x0000,0x0300,0x6300,0x3600,0x1e00,0x0c00,0x0e00,0x1b00,0x1980,0x3000,0x3000,0x6000,0x6000,0x0000,\n  0x0000,0x0000, // u2718\n  0x0000,0x0000,0x0200,0x0200,0x0400,0x0400,0x0800,0x0800,0x1000,0x0800,0x0800,0x0400,0x0400,0x0200,0x0200,0x0000,\n  0x0000,0x0000, // u27e8\n  0x0000,0x0000,0x1000,0x1000,0x0800,0x0800,0x0400,0x0400,0x0200,0x0400,0x0400,0x0800,0x0800,0x1000,0x1000,0x0000,\n  0x0000,0x0000, // u27e9\n  0x0000,0x0000,0x0880,0x0880,0x1100,0x1100,0x2200,0x2200,0x4400,0x2200,0x2200,0x1100,0x1100,0x0880,0x0880,0x0000,\n  0x0000,0x0000, // u27ea\n  0x0000,0x0000,0x4400,0x4400,0x2200,0x2200,0x1100,0x1100,0x0880,0x1100,0x1100,0x2200,0x2200,0x4400,0x4400,0x0000,\n  0x0000,0x0000, // u27eb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2800\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2801\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2802\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2803\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2804\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2805\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2806\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2807\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2808\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2809\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u280a\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u280b\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u280c\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u280d\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u280e\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u280f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2810\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2811\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2812\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2813\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2814\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2815\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2816\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2817\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2818\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2819\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u281a\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u281b\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u281c\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u281d\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u281e\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u281f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2820\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2821\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2822\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2823\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2824\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2825\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2826\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2827\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2828\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2829\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u282a\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u282b\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u282c\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u282d\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u282e\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u282f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2830\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2831\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2832\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2833\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2834\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2835\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2836\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2837\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2838\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2839\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u283a\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u283b\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u283c\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u283d\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u283e\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u283f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2840\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2841\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2842\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2843\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2844\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2845\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2846\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2847\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2848\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2849\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u284a\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u284b\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u284c\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u284d\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u284e\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u284f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2850\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2851\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2852\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2853\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2854\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2855\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2856\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2857\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2858\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2859\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u285a\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u285b\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u285c\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u285d\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u285e\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u285f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2860\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2861\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2862\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2863\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2864\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2865\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2866\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2867\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2868\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2869\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u286a\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u286b\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u286c\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u286d\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u286e\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u286f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2870\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2871\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2872\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2873\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2874\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2875\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2876\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2877\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2878\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u2879\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u287a\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u287b\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u287c\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u287d\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u287e\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,\n  0x0000,0x0000, // u287f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u2880\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u2881\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u2882\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u2883\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u2884\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u2885\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u2886\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u2887\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u2888\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u2889\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u288a\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u288b\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u288c\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u288d\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u288e\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u288f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u2890\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u2891\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u2892\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u2893\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u2894\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u2895\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u2896\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u2897\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u2898\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u2899\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u289a\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u289b\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u289c\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u289d\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u289e\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u289f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28a0\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28a2\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28a4\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28a5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28a6\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28a7\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28a8\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28a9\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28aa\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28ab\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28ac\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28ad\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28ae\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28af\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28b0\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28b1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28b2\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28b4\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28b6\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28b7\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28b8\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28b9\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28ba\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28bb\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28bc\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28bd\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28be\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,\n  0x0000,0x0000, // u28bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28c0\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28c2\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28c4\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28c6\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28c7\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28c8\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28c9\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28ca\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28cb\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28cc\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28cd\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28ce\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28cf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28d0\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28d2\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28d4\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28d6\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28d7\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28d8\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28d9\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28da\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28db\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28dc\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28dd\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28de\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28df\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28e0\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28e1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28e2\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28e3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28e4\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28e6\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28e7\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28e8\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28e9\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28ea\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28eb\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28ec\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28ed\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28ee\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28ef\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28f0\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28f2\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28f3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28f4\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28f6\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28f7\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28f8\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28f9\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28fa\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28fb\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28fc\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28fd\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28fe\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,\n  0x0000,0x0000, // u28ff\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x0000,0x0000,\n  0x0000,0x0000, // u2e2c\n  0x8000,0x8000,0x8400,0x8e00,0x9500,0xa480,0x8400,0x8400,0x8400,0x8800,0x1000,0x2000,0x4000,0x8000,0x8000,0x8000,\n  0x8000,0x8000, // ue0a0\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x0000,0x0880,0x0c80,0x0a80,0x0980,0x0880,0x0880,0x0000,\n  0x0000,0x0000, // ue0a1\n  0x0000,0x0000,0x1e00,0x2100,0x2100,0x2100,0x2100,0x2100,0x7f80,0x7f80,0x7380,0x6180,0x7380,0x7f80,0x7f80,0x7f80,\n  0x0000,0x0000, // ue0a2\n  0x8000,0xc000,0xe000,0xf000,0xf800,0xfc00,0xfe00,0xff00,0xff80,0xff80,0xff00,0xfe00,0xfc00,0xf800,0xf000,0xe000,\n  0xc000,0x8000, // ue0b0\n  0x8000,0x4000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,0x0080,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,\n  0x4000,0x8000, // ue0b1\n  0x0040,0x00c0,0x01c0,0x03c0,0x07c0,0x0fc0,0x1fc0,0x3fc0,0x7fc0,0x7fc0,0x3fc0,0x1fc0,0x0fc0,0x07c0,0x03c0,0x01c0,\n  0x00c0,0x0040, // ue0b2\n  0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,\n  0x0080,0x0040, // ue0b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x2200,\n  0x2200,0x1c00, // uf6be\n  0x0000,0x0000,0x0000,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x0000,\n  0x0000,0x0000 // ufffd\n  };\n  // codepoints array\n  constexpr std::array<uint16_t, CHARCOUNT> fixedfont_codepoints = {\n  0x0000,0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,\n  0x002f,0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,\n  0x003f,0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,\n  0x004f,0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,\n  0x005f,0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,\n  0x006f,0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,\n  0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af,\n  0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf,\n  0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf,\n  0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df,\n  0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef,\n  0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff,\n  0x0100,0x0101,0x0102,0x0103,0x0104,0x0105,0x0106,0x0107,0x0108,0x0109,0x010a,0x010b,0x010c,0x010d,0x010e,0x010f,\n  0x0110,0x0111,0x0112,0x0113,0x0114,0x0115,0x0116,0x0117,0x0118,0x0119,0x011a,0x011b,0x011c,0x011d,0x011e,0x011f,\n  0x0120,0x0121,0x0122,0x0123,0x0124,0x0125,0x0126,0x0127,0x0128,0x0129,0x012a,0x012b,0x012c,0x012d,0x012e,0x012f,\n  0x0130,0x0131,0x0132,0x0133,0x0134,0x0135,0x0136,0x0137,0x0138,0x0139,0x013a,0x013b,0x013c,0x013d,0x013e,0x013f,\n  0x0140,0x0141,0x0142,0x0143,0x0144,0x0145,0x0146,0x0147,0x0148,0x0149,0x014a,0x014b,0x014c,0x014d,0x014e,0x014f,\n  0x0150,0x0151,0x0152,0x0153,0x0154,0x0155,0x0156,0x0157,0x0158,0x0159,0x015a,0x015b,0x015c,0x015d,0x015e,0x015f,\n  0x0160,0x0161,0x0162,0x0163,0x0164,0x0165,0x0166,0x0167,0x0168,0x0169,0x016a,0x016b,0x016c,0x016d,0x016e,0x016f,\n  0x0170,0x0171,0x0172,0x0173,0x0174,0x0175,0x0176,0x0177,0x0178,0x0179,0x017a,0x017b,0x017c,0x017d,0x017e,0x017f,\n  0x0186,0x018e,0x018f,0x0190,0x0192,0x019d,0x019e,0x01b5,0x01b6,0x01b7,0x01cd,0x01ce,0x01cf,0x01d0,0x01d1,0x01d2,\n  0x01d3,0x01d4,0x01e2,0x01e3,0x01e4,0x01e5,0x01e6,0x01e7,0x01e8,0x01e9,0x01ea,0x01eb,0x01ec,0x01ed,0x01ee,0x01ef,\n  0x01f0,0x01f4,0x01f5,0x01fc,0x01fd,0x01fe,0x01ff,0x0218,0x0219,0x021a,0x021b,0x0232,0x0233,0x0237,0x0254,0x0258,\n  0x0259,0x025b,0x0272,0x0292,0x02bb,0x02bc,0x02bd,0x02c6,0x02c7,0x02d8,0x02d9,0x02db,0x02dc,0x02dd,0x0300,0x0301,\n  0x0302,0x0303,0x0304,0x0305,0x0306,0x0307,0x0308,0x030a,0x030b,0x030c,0x0329,0x0384,0x0385,0x0386,0x0387,0x0388,\n  0x0389,0x038a,0x038c,0x038e,0x038f,0x0390,0x0391,0x0392,0x0393,0x0394,0x0395,0x0396,0x0397,0x0398,0x0399,0x039a,\n  0x039b,0x039c,0x039d,0x039e,0x039f,0x03a0,0x03a1,0x03a3,0x03a4,0x03a5,0x03a6,0x03a7,0x03a8,0x03a9,0x03aa,0x03ab,\n  0x03ac,0x03ad,0x03ae,0x03af,0x03b0,0x03b1,0x03b2,0x03b3,0x03b4,0x03b5,0x03b6,0x03b7,0x03b8,0x03b9,0x03ba,0x03bb,\n  0x03bc,0x03bd,0x03be,0x03bf,0x03c0,0x03c1,0x03c2,0x03c3,0x03c4,0x03c5,0x03c6,0x03c7,0x03c8,0x03c9,0x03ca,0x03cb,\n  0x03cc,0x03cd,0x03ce,0x03d1,0x03d5,0x03f0,0x03f1,0x03f2,0x03f3,0x03f4,0x03f5,0x03f6,0x0400,0x0401,0x0402,0x0403,\n  0x0404,0x0405,0x0406,0x0407,0x0408,0x0409,0x040a,0x040b,0x040c,0x040d,0x040e,0x040f,0x0410,0x0411,0x0412,0x0413,\n  0x0414,0x0415,0x0416,0x0417,0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e,0x041f,0x0420,0x0421,0x0422,0x0423,\n  0x0424,0x0425,0x0426,0x0427,0x0428,0x0429,0x042a,0x042b,0x042c,0x042d,0x042e,0x042f,0x0430,0x0431,0x0432,0x0433,\n  0x0434,0x0435,0x0436,0x0437,0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e,0x043f,0x0440,0x0441,0x0442,0x0443,\n  0x0444,0x0445,0x0446,0x0447,0x0448,0x0449,0x044a,0x044b,0x044c,0x044d,0x044e,0x044f,0x0450,0x0451,0x0452,0x0453,\n  0x0454,0x0455,0x0456,0x0457,0x0458,0x0459,0x045a,0x045b,0x045c,0x045d,0x045e,0x045f,0x0462,0x0463,0x046a,0x046b,\n  0x0490,0x0491,0x0492,0x0493,0x0494,0x0495,0x0496,0x0497,0x0498,0x0499,0x049a,0x049b,0x049c,0x049d,0x04a0,0x04a1,\n  0x04a2,0x04a3,0x04a4,0x04a5,0x04aa,0x04ab,0x04ae,0x04af,0x04b0,0x04b1,0x04b2,0x04b3,0x04b6,0x04b7,0x04b8,0x04b9,\n  0x04ba,0x04bb,0x04c0,0x04c1,0x04c2,0x04cf,0x04d0,0x04d1,0x04d2,0x04d3,0x04d4,0x04d5,0x04d6,0x04d7,0x04d8,0x04d9,\n  0x04da,0x04db,0x04dc,0x04dd,0x04de,0x04df,0x04e2,0x04e3,0x04e4,0x04e5,0x04e6,0x04e7,0x04e8,0x04e9,0x04ea,0x04eb,\n  0x04ec,0x04ed,0x04ee,0x04ef,0x04f0,0x04f1,0x04f2,0x04f3,0x04f4,0x04f5,0x04f8,0x04f9,0x05d0,0x05d1,0x05d2,0x05d3,\n  0x05d4,0x05d5,0x05d6,0x05d7,0x05d8,0x05d9,0x05da,0x05db,0x05dc,0x05dd,0x05de,0x05df,0x05e0,0x05e1,0x05e2,0x05e3,\n  0x05e4,0x05e5,0x05e6,0x05e7,0x05e8,0x05e9,0x05ea,0x1e0c,0x1e0d,0x1e34,0x1e35,0x1e36,0x1e37,0x1e40,0x1e41,0x1e42,\n  0x1e43,0x1e44,0x1e45,0x1e46,0x1e47,0x1e6c,0x1e6d,0x1eb8,0x1eb9,0x1ebc,0x1ebd,0x1eca,0x1ecb,0x1ecc,0x1ecd,0x1ee4,\n  0x1ee5,0x1ef8,0x1ef9,0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007,0x2008,0x2009,0x200a,0x200b,0x200c,\n  0x200d,0x200e,0x200f,0x2010,0x2011,0x2012,0x2013,0x2014,0x2015,0x2016,0x2017,0x2018,0x2019,0x201a,0x201b,0x201c,\n  0x201d,0x201e,0x201f,0x2020,0x2021,0x2022,0x2026,0x2030,0x2032,0x2033,0x2039,0x203a,0x203c,0x203e,0x2070,0x2071,\n  0x2074,0x2075,0x2076,0x2077,0x2078,0x2079,0x207a,0x207b,0x207c,0x207d,0x207e,0x207f,0x2080,0x2081,0x2082,0x2083,\n  0x2084,0x2085,0x2086,0x2087,0x2088,0x2089,0x208a,0x208b,0x208c,0x208d,0x208e,0x2090,0x2091,0x2092,0x2093,0x2094,\n  0x2095,0x2096,0x2097,0x2098,0x209a,0x20a7,0x20aa,0x20ac,0x20ae,0x2102,0x210e,0x210f,0x2115,0x2116,0x211a,0x211d,\n  0x2122,0x2124,0x2126,0x2135,0x2190,0x2191,0x2192,0x2193,0x2194,0x2195,0x21a4,0x21a6,0x21a8,0x21b5,0x21bb,0x21cb,\n  0x21cc,0x21d0,0x21d1,0x21d2,0x21d3,0x21d4,0x21d5,0x2200,0x2203,0x2204,0x2205,0x2206,0x2207,0x2208,0x2209,0x220a,\n  0x220b,0x220c,0x220d,0x2212,0x2213,0x2214,0x2215,0x2216,0x2219,0x221a,0x221e,0x221f,0x2225,0x2227,0x2228,0x2229,\n  0x222a,0x2248,0x2260,0x2261,0x2264,0x2265,0x226a,0x226b,0x2282,0x2283,0x2286,0x2287,0x22a5,0x22c2,0x22c3,0x2300,\n  0x2302,0x2308,0x2309,0x230a,0x230b,0x2310,0x2319,0x2320,0x2321,0x239b,0x239c,0x239d,0x239e,0x239f,0x23a0,0x23a1,\n  0x23a2,0x23a3,0x23a4,0x23a5,0x23a6,0x23a7,0x23a8,0x23a9,0x23ab,0x23ac,0x23ad,0x23ae,0x23af,0x23ba,0x23bb,0x23bc,\n  0x23bd,0x23d0,0x2409,0x240a,0x240b,0x240c,0x240d,0x2424,0x2500,0x2501,0x2502,0x2503,0x2508,0x2509,0x250a,0x250b,\n  0x250c,0x250d,0x250e,0x250f,0x2510,0x2511,0x2512,0x2513,0x2514,0x2515,0x2516,0x2517,0x2518,0x2519,0x251a,0x251b,\n  0x251c,0x251d,0x251e,0x251f,0x2520,0x2521,0x2522,0x2523,0x2524,0x2525,0x2526,0x2527,0x2528,0x2529,0x252a,0x252b,\n  0x252c,0x252d,0x252e,0x252f,0x2530,0x2531,0x2532,0x2533,0x2534,0x2535,0x2536,0x2537,0x2538,0x2539,0x253a,0x253b,\n  0x253c,0x253d,0x253e,0x253f,0x2540,0x2541,0x2542,0x2543,0x2544,0x2545,0x2546,0x2547,0x2548,0x2549,0x254a,0x254b,\n  0x2550,0x2551,0x2552,0x2553,0x2554,0x2555,0x2556,0x2557,0x2558,0x2559,0x255a,0x255b,0x255c,0x255d,0x255e,0x255f,\n  0x2560,0x2561,0x2562,0x2563,0x2564,0x2565,0x2566,0x2567,0x2568,0x2569,0x256a,0x256b,0x256c,0x256d,0x256e,0x256f,\n  0x2570,0x2571,0x2572,0x2573,0x2574,0x2575,0x2576,0x2577,0x2578,0x2579,0x257a,0x257b,0x257c,0x257d,0x257e,0x257f,\n  0x2580,0x2581,0x2582,0x2583,0x2584,0x2585,0x2586,0x2587,0x2588,0x2589,0x258a,0x258b,0x258c,0x258d,0x258e,0x258f,\n  0x2590,0x2591,0x2592,0x2593,0x2596,0x2597,0x2598,0x2599,0x259a,0x259b,0x259c,0x259d,0x259e,0x259f,0x25a0,0x25ac,\n  0x25ae,0x25b2,0x25b6,0x25ba,0x25bc,0x25c0,0x25c4,0x25c6,0x25ca,0x25cb,0x25cf,0x25d8,0x25d9,0x263a,0x263b,0x263c,\n  0x2640,0x2642,0x2660,0x2663,0x2665,0x2666,0x266a,0x266b,0x2713,0x2714,0x2717,0x2718,0x27e8,0x27e9,0x27ea,0x27eb,\n  0x2800,0x2801,0x2802,0x2803,0x2804,0x2805,0x2806,0x2807,0x2808,0x2809,0x280a,0x280b,0x280c,0x280d,0x280e,0x280f,\n  0x2810,0x2811,0x2812,0x2813,0x2814,0x2815,0x2816,0x2817,0x2818,0x2819,0x281a,0x281b,0x281c,0x281d,0x281e,0x281f,\n  0x2820,0x2821,0x2822,0x2823,0x2824,0x2825,0x2826,0x2827,0x2828,0x2829,0x282a,0x282b,0x282c,0x282d,0x282e,0x282f,\n  0x2830,0x2831,0x2832,0x2833,0x2834,0x2835,0x2836,0x2837,0x2838,0x2839,0x283a,0x283b,0x283c,0x283d,0x283e,0x283f,\n  0x2840,0x2841,0x2842,0x2843,0x2844,0x2845,0x2846,0x2847,0x2848,0x2849,0x284a,0x284b,0x284c,0x284d,0x284e,0x284f,\n  0x2850,0x2851,0x2852,0x2853,0x2854,0x2855,0x2856,0x2857,0x2858,0x2859,0x285a,0x285b,0x285c,0x285d,0x285e,0x285f,\n  0x2860,0x2861,0x2862,0x2863,0x2864,0x2865,0x2866,0x2867,0x2868,0x2869,0x286a,0x286b,0x286c,0x286d,0x286e,0x286f,\n  0x2870,0x2871,0x2872,0x2873,0x2874,0x2875,0x2876,0x2877,0x2878,0x2879,0x287a,0x287b,0x287c,0x287d,0x287e,0x287f,\n  0x2880,0x2881,0x2882,0x2883,0x2884,0x2885,0x2886,0x2887,0x2888,0x2889,0x288a,0x288b,0x288c,0x288d,0x288e,0x288f,\n  0x2890,0x2891,0x2892,0x2893,0x2894,0x2895,0x2896,0x2897,0x2898,0x2899,0x289a,0x289b,0x289c,0x289d,0x289e,0x289f,\n  0x28a0,0x28a1,0x28a2,0x28a3,0x28a4,0x28a5,0x28a6,0x28a7,0x28a8,0x28a9,0x28aa,0x28ab,0x28ac,0x28ad,0x28ae,0x28af,\n  0x28b0,0x28b1,0x28b2,0x28b3,0x28b4,0x28b5,0x28b6,0x28b7,0x28b8,0x28b9,0x28ba,0x28bb,0x28bc,0x28bd,0x28be,0x28bf,\n  0x28c0,0x28c1,0x28c2,0x28c3,0x28c4,0x28c5,0x28c6,0x28c7,0x28c8,0x28c9,0x28ca,0x28cb,0x28cc,0x28cd,0x28ce,0x28cf,\n  0x28d0,0x28d1,0x28d2,0x28d3,0x28d4,0x28d5,0x28d6,0x28d7,0x28d8,0x28d9,0x28da,0x28db,0x28dc,0x28dd,0x28de,0x28df,\n  0x28e0,0x28e1,0x28e2,0x28e3,0x28e4,0x28e5,0x28e6,0x28e7,0x28e8,0x28e9,0x28ea,0x28eb,0x28ec,0x28ed,0x28ee,0x28ef,\n  0x28f0,0x28f1,0x28f2,0x28f3,0x28f4,0x28f5,0x28f6,0x28f7,0x28f8,0x28f9,0x28fa,0x28fb,0x28fc,0x28fd,0x28fe,0x28ff,\n  0x2e2c,0xe0a0,0xe0a1,0xe0a2,0xe0b0,0xe0b1,0xe0b2,0xe0b3,0xf6be,0xfffd };\n} // namespace\n// -- end of autogenerated text ---\n\nnamespace fixed_font_18b {\n  // -- start of autogenerated text ---\n  // definition section for font: ter-u18b.bdf\n  constexpr int CHARCOUNT = 1354;\n  constexpr int WIDTH = 10;\n  constexpr int HEIGHT = 18;\n  constexpr int OFFSET_X = 0;\n  constexpr int OFFSET_Y = 0;\n  constexpr FixedFont_info_t fixedfont_info = {\n    \"Terminus\", // font name\n    \"ter-u18b.bdf\", // font name internal\n    CHARCOUNT, // num of chars\n    WIDTH, HEIGHT, OFFSET_X, OFFSET_Y,\n    true // bold\n  };\n  // font bitmap definitions\n  constexpr std::array<uint16_t, CHARCOUNT * HEIGHT> fixedfont_bitmap = {\n  0x0000,0x0000,0x0000,0x7380,0x6180,0x6180,0x0000,0x6180,0x6180,0x6180,0x6180,0x0000,0x6180,0x6180,0x7380,0x0000,\n  0x0000,0x0000, // u0000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0020\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u0021\n  0x0000,0x3300,0x3300,0x3300,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0022\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x3300,0x7f80,0x3300,0x3300,0x3300,0x3300,0x7f80,0x3300,0x3300,0x3300,0x0000,\n  0x0000,0x0000, // u0023\n  0x0000,0x0000,0x0c00,0x0c00,0x3f00,0x6d80,0x6c00,0x6c00,0x6c00,0x3f00,0x0d80,0x0d80,0x0d80,0x6d80,0x3f00,0x0c00,\n  0x0c00,0x0000, // u0024\n  0x0000,0x0000,0x0000,0x7300,0x5300,0x7600,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x3700,0x6500,0x6700,0x0000,\n  0x0000,0x0000, // u0025\n  0x0000,0x0000,0x0000,0x3c00,0x6600,0x6600,0x6600,0x3c00,0x3980,0x6d80,0xc700,0xc300,0xc300,0x6780,0x3d80,0x0000,\n  0x0000,0x0000, // u0026\n  0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0027\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0c00,0x0c00,0x0600,0x0000,\n  0x0000,0x0000, // u0028\n  0x0000,0x0000,0x0000,0x1800,0x0c00,0x0c00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0c00,0x0c00,0x1800,0x0000,\n  0x0000,0x0000, // u0029\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x3600,0x1c00,0xff80,0x1c00,0x3600,0x6300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u002a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u002b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x1800,\n  0x0000,0x0000, // u002c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u002d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u002e\n  0x0000,0x0000,0x0000,0x0300,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x6000,0x6000,0x0000,\n  0x0000,0x0000, // u002f\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6380,0x6780,0x6d80,0x7980,0x7180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0030\n  0x0000,0x0000,0x0000,0x0c00,0x1c00,0x3c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x3f00,0x0000,\n  0x0000,0x0000, // u0031\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u0032\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x0180,0x0180,0x1f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0033\n  0x0000,0x0000,0x0000,0x0180,0x0380,0x0780,0x0d80,0x1980,0x3180,0x6180,0x6180,0x7f80,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0000, // u0034\n  0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x7f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0035\n  0x0000,0x0000,0x0000,0x1f00,0x3000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0036\n  0x0000,0x0000,0x0000,0x7f80,0x6180,0x6180,0x0180,0x0300,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u0037\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0038\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,0x0180,0x0180,0x0300,0x3e00,0x0000,\n  0x0000,0x0000, // u0039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0000,\n  0x0000,0x0000, // u003a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x1800,\n  0x0000,0x0000, // u003b\n  0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0000,\n  0x0000,0x0000, // u003c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u003d\n  0x0000,0x0000,0x0000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x0000,\n  0x0000,0x0000, // u003e\n  0x0000,0x0000,0x0000,0x1e00,0x3300,0x6180,0x6180,0x0180,0x0300,0x0600,0x0c00,0x0c00,0x0000,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u003f\n  0x0000,0x0000,0x0000,0x7f00,0xc180,0xc180,0xcf80,0xd980,0xd980,0xd980,0xd980,0xcf80,0xc000,0xc000,0x7f80,0x0000,\n  0x0000,0x0000, // u0040\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u0041\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x0000,\n  0x0000,0x0000, // u0042\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0043\n  0x0000,0x0000,0x0000,0x7e00,0x6300,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6300,0x7e00,0x0000,\n  0x0000,0x0000, // u0044\n  0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u0045\n  0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,\n  0x0000,0x0000, // u0046\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6780,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0047\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u0048\n  0x0000,0x0000,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u0049\n  0x0000,0x0000,0x0000,0x0780,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x6300,0x6300,0x6300,0x3e00,0x0000,\n  0x0000,0x0000, // u004a\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7800,0x6c00,0x6600,0x6300,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u004b\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u004c\n  0x0000,0x0000,0x0000,0x8080,0xc180,0xe380,0xf780,0xdd80,0xc980,0xc180,0xc180,0xc180,0xc180,0xc180,0xc180,0x0000,\n  0x0000,0x0000, // u004d\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x7180,0x7980,0x6d80,0x6780,0x6380,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u004e\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u004f\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,\n  0x0000,0x0000, // u0050\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6780,0x3f00,0x0300,\n  0x0180,0x0000, // u0051\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x7800,0x6c00,0x6600,0x6300,0x6180,0x0000,\n  0x0000,0x0000, // u0052\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x3f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0053\n  0x0000,0x0000,0x0000,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u0054\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0055\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x3300,0x3300,0x3300,0x3300,0x1e00,0x1e00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u0056\n  0x0000,0x0000,0x0000,0xc180,0xc180,0xc180,0xc180,0xc180,0xc180,0xc980,0xdd80,0xf780,0xe380,0xc180,0x8080,0x0000,\n  0x0000,0x0000, // u0057\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x1e00,0x3300,0x3300,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u0058\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u0059\n  0x0000,0x0000,0x0000,0x7f80,0x0180,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u005a\n  0x0000,0x0000,0x0000,0x1e00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1e00,0x0000,\n  0x0000,0x0000, // u005b\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x3000,0x3000,0x1800,0x1800,0x0c00,0x0c00,0x0600,0x0600,0x0300,0x0300,0x0000,\n  0x0000,0x0000, // u005c\n  0x0000,0x0000,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x1e00,0x0000,\n  0x0000,0x0000, // u005d\n  0x0000,0x0c00,0x1e00,0x3300,0x6180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u005e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x7f80,0x0000, // u005f\n  0x1800,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0060\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u0061\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x0000,\n  0x0000,0x0000, // u0062\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0063\n  0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u0064\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0065\n  0x0000,0x0000,0x0000,0x0780,0x0c00,0x0c00,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u0066\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,\n  0x0180,0x3f00, // u0067\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u0068\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u0069\n  0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0700,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x3300,\n  0x3300,0x1e00, // u006a\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6180,0x6300,0x6600,0x6c00,0x7800,0x6c00,0x6600,0x6300,0x6180,0x0000,\n  0x0000,0x0000, // u006b\n  0x0000,0x0000,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u006c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x0000,\n  0x0000,0x0000, // u006d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u006e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u006f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x6000,\n  0x6000,0x6000, // u0070\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,\n  0x0180,0x0180, // u0071\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6f80,0x7800,0x7000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,\n  0x0000,0x0000, // u0072\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x6000,0x3f00,0x0180,0x0180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0073\n  0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x7e00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0f00,0x0000,\n  0x0000,0x0000, // u0074\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u0075\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u0076\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,0x0000,\n  0x0000,0x0000, // u0077\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x3300,0x1e00,0x0c00,0x1e00,0x3300,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u0078\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,\n  0x0180,0x3f00, // u0079\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u007a\n  0x0000,0x0000,0x0000,0x0700,0x0c00,0x0c00,0x0c00,0x0c00,0x3800,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0700,0x0000,\n  0x0000,0x0000, // u007b\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u007c\n  0x0000,0x0000,0x0000,0x3800,0x0c00,0x0c00,0x0c00,0x0c00,0x0700,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x3800,0x0000,\n  0x0000,0x0000, // u007d\n  0x0000,0x3980,0x6d80,0x6d80,0x6700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u007e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00a0\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u00a1\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x3f00,0x6d80,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6d80,0x3f00,0x0c00,\n  0x0c00,0x0000, // u00a2\n  0x0000,0x0000,0x0000,0x1e00,0x3300,0x3000,0x3000,0x3000,0x7e00,0x3000,0x3000,0x3000,0x3000,0x3180,0x7f80,0x0000,\n  0x0000,0x0000, // u00a3\n  0x0000,0x0000,0x0000,0x0000,0xc180,0x6300,0x3e00,0x6300,0x6300,0x6300,0x6300,0x3e00,0x6300,0xc180,0x0000,0x0000,\n  0x0000,0x0000, // u00a4\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x3300,0x3300,0x1e00,0x1e00,0x0c00,0x3f00,0x0c00,0x3f00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u00a5\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u00a6\n  0x0000,0x0000,0x1e00,0x3300,0x3000,0x1c00,0x3600,0x3300,0x3300,0x3300,0x1b00,0x0e00,0x0300,0x3300,0x1e00,0x0000,\n  0x0000,0x0000, // u00a7\n  0x3300,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00a8\n  0x0000,0x0000,0x0000,0x0000,0x3f00,0x4080,0x9e40,0xb340,0xb040,0xb040,0xb340,0x9e40,0x4080,0x3f00,0x0000,0x0000,\n  0x0000,0x0000, // u00a9\n  0x0000,0x3e00,0x0300,0x3f00,0x6300,0x6300,0x3f00,0x0000,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0cc0,0x1980,0x3300,0x6600,0xcc00,0x6600,0x3300,0x1980,0x0cc0,0x0000,\n  0x0000,0x0000, // u00ab\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00ac\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00ad\n  0x0000,0x0000,0x0000,0x0000,0x3f00,0x4080,0xbe40,0xb340,0xb340,0xbe40,0xb640,0xb340,0x4080,0x3f00,0x0000,0x0000,\n  0x0000,0x0000, // u00ae\n  0x0000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00af\n  0x0000,0x1e00,0x3300,0x3300,0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x7f80,0x0000,\n  0x0000,0x0000, // u00b1\n  0x0000,0x1e00,0x3300,0x3300,0x0600,0x0c00,0x1800,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00b2\n  0x0000,0x1e00,0x3300,0x0300,0x0e00,0x0300,0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00b3\n  0x0600,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6380,0x7d80,0x6000,\n  0x6000,0x6000, // u00b5\n  0x0000,0x0000,0x0000,0x3f80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3d80,0x0d80,0x0d80,0x0d80,0x0d80,0x0d80,0x0000,\n  0x0000,0x0000, // u00b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00b7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,\n  0x0c00,0x1800, // u00b8\n  0x0000,0x0c00,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00b9\n  0x0000,0x3e00,0x6300,0x6300,0x6300,0x6300,0x3e00,0x0000,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xcc00,0x6600,0x3300,0x1980,0x0cc0,0x1980,0x3300,0x6600,0xcc00,0x0000,\n  0x0000,0x0000, // u00bb\n  0x0000,0x0000,0x3000,0x7000,0x3080,0x3180,0x3300,0x3600,0x0c00,0x1980,0x3380,0x6780,0xcd80,0x8f80,0x0180,0x0180,\n  0x0000,0x0000, // u00bc\n  0x0000,0x0000,0x3000,0x7000,0x3080,0x3180,0x3300,0x3600,0x0c00,0x1800,0x3700,0x6d80,0xc180,0x8300,0x0600,0x0f80,\n  0x0000,0x0000, // u00bd\n  0x0000,0x0000,0xf000,0x1800,0x7080,0x1980,0x1b00,0xf600,0x0c00,0x1980,0x3380,0x6780,0xcd80,0x8f80,0x0180,0x0180,\n  0x0000,0x0000, // u00be\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0c00,0x0c00,0x1800,0x3000,0x6000,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000, // u00bf\n  0x1800,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u00c0\n  0x0600,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u00c1\n  0x1e00,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u00c2\n  0x3b80,0x6e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u00c3\n  0x3300,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u00c4\n  0x1e00,0x3300,0x1e00,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u00c5\n  0x0000,0x0000,0x0000,0x7fc0,0xc600,0xc600,0xc600,0xc600,0xffc0,0xc600,0xc600,0xc600,0xc600,0xc600,0xc7c0,0x0000,\n  0x0000,0x0000, // u00c6\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x6180,0x3f00,0x0c00,\n  0x0c00,0x1800, // u00c7\n  0x1800,0x0c00,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u00c8\n  0x0600,0x0c00,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u00c9\n  0x1e00,0x3300,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u00ca\n  0x3300,0x3300,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u00cb\n  0x1800,0x0c00,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u00cc\n  0x0600,0x0c00,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u00cd\n  0x1e00,0x3300,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u00ce\n  0x3300,0x3300,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u00cf\n  0x0000,0x0000,0x0000,0x7e00,0x6300,0x6180,0x6180,0x6180,0xfd80,0x6180,0x6180,0x6180,0x6180,0x6300,0x7e00,0x0000,\n  0x0000,0x0000, // u00d0\n  0x3b80,0x6e00,0x0000,0x6180,0x6180,0x6180,0x7180,0x7980,0x6d80,0x6780,0x6380,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u00d1\n  0x1800,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u00d2\n  0x0600,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u00d3\n  0x1e00,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u00d4\n  0x3b80,0x6e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u00d5\n  0x3300,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u00d6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x3300,0x1e00,0x0c00,0x1e00,0x3300,0x6180,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00d7\n  0x0000,0x0000,0x0000,0x3f00,0x61c0,0x6180,0x6380,0x6780,0x6d80,0x7980,0x7180,0x6180,0xe180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u00d8\n  0x1800,0x0c00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u00d9\n  0x0600,0x0c00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u00da\n  0x1e00,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u00db\n  0x3300,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u00dc\n  0x0600,0x0c00,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u00dd\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x6000,0x6000,0x6000,0x0000,\n  0x0000,0x0000, // u00de\n  0x0000,0x0000,0x0000,0x3e00,0x6300,0x6300,0x6300,0x6200,0x7f00,0x6180,0x6180,0x6180,0x6180,0x7180,0x6f00,0x0000,\n  0x0000,0x0000, // u00df\n  0x0000,0x0000,0x0000,0x1800,0x0c00,0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u00e0\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u00e1\n  0x0000,0x0000,0x0000,0x1e00,0x3300,0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u00e2\n  0x0000,0x0000,0x0000,0x3b80,0x6e00,0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u00e3\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u00e4\n  0x0000,0x0000,0x0000,0x1e00,0x3300,0x1e00,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u00e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7b80,0x0cc0,0x0cc0,0x7cc0,0xcfc0,0xcc00,0xcc00,0xccc0,0x7780,0x0000,\n  0x0000,0x0000, // u00e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x3f00,0x0c00,\n  0x0c00,0x1800, // u00e7\n  0x0000,0x0000,0x0000,0x1800,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u00e8\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u00e9\n  0x0000,0x0000,0x0000,0x1e00,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u00ea\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u00eb\n  0x0000,0x0000,0x0000,0x1800,0x0c00,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u00ec\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u00ed\n  0x0000,0x0000,0x0000,0x1e00,0x3300,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u00ee\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u00ef\n  0x0000,0x0000,0x0000,0x3600,0x3c00,0x6c00,0x0600,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u00f0\n  0x0000,0x0000,0x0000,0x3b80,0x6e00,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u00f1\n  0x0000,0x0000,0x0000,0x1800,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u00f2\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u00f3\n  0x0000,0x0000,0x0000,0x1e00,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u00f4\n  0x0000,0x0000,0x0000,0x3b80,0x6e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u00f5\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u00f6\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u00f7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f40,0x6180,0x6380,0x6780,0x6d80,0x7980,0x7180,0x6180,0xbf00,0x0000,\n  0x0000,0x0000, // u00f8\n  0x0000,0x0000,0x0000,0x1800,0x0c00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u00f9\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u00fa\n  0x0000,0x0000,0x0000,0x1e00,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u00fb\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u00fc\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,\n  0x0180,0x3f00, // u00fd\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x6000,\n  0x6000,0x6000, // u00fe\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,\n  0x0180,0x3f00, // u00ff\n  0x0000,0x3f00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u0100\n  0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u0101\n  0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u0102\n  0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u0103\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x0180,\n  0x0300,0x01c0, // u0104\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,\n  0x0300,0x01c0, // u0105\n  0x0600,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0106\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x3f00,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0107\n  0x1e00,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0108\n  0x0000,0x0000,0x0000,0x1e00,0x3300,0x0000,0x3f00,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0109\n  0x0c00,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u010a\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x3f00,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u010b\n  0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u010c\n  0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u010d\n  0x3300,0x1e00,0x0000,0x7e00,0x6300,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6300,0x7e00,0x0000,\n  0x0000,0x0000, // u010e\n  0x3300,0x1e00,0x0000,0x0180,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u010f\n  0x0000,0x0000,0x0000,0x7e00,0x6300,0x6180,0x6180,0x6180,0xfd80,0x6180,0x6180,0x6180,0x6180,0x6300,0x7e00,0x0000,\n  0x0000,0x0000, // u0110\n  0x0000,0x0000,0x0000,0x0180,0x0fc0,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u0111\n  0x0000,0x3f00,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u0112\n  0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0113\n  0x3300,0x1e00,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u0114\n  0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0115\n  0x0c00,0x0c00,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u0116\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0117\n  0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0180,\n  0x0300,0x01c0, // u0118\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,0x0c00,\n  0x1800,0x0e00, // u0119\n  0x3300,0x1e00,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u011a\n  0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u011b\n  0x1e00,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6780,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u011c\n  0x0000,0x0000,0x0000,0x1e00,0x3300,0x0000,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,\n  0x0180,0x3f00, // u011d\n  0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6780,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u011e\n  0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,\n  0x0180,0x3f00, // u011f\n  0x0c00,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6780,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0120\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,\n  0x0180,0x3f00, // u0121\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6780,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0c00,\n  0x0c00,0x1800, // u0122\n  0x0000,0x0000,0x0600,0x0c00,0x0c00,0x0000,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,\n  0x0180,0x3f00, // u0123\n  0x1e00,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u0124\n  0x1e00,0x3300,0x0000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u0125\n  0x0000,0x0000,0x0000,0x6180,0x6180,0xffc0,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u0126\n  0x0000,0x0000,0x0000,0x6000,0xfc00,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u0127\n  0x3b80,0x6e00,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u0128\n  0x0000,0x0000,0x0000,0x3b80,0x6e00,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u0129\n  0x0000,0x3f00,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u012a\n  0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u012b\n  0x3300,0x1e00,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u012c\n  0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u012d\n  0x0000,0x0000,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0c00,\n  0x1800,0x0e00, // u012e\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0c00,\n  0x1800,0x0e00, // u012f\n  0x0c00,0x0c00,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u0130\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u0131\n  0x0000,0x0000,0x0000,0xf3c0,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6d80,0x6d80,0x6d80,0xf700,0x0000,\n  0x0000,0x0000, // u0132\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x0000,0xe380,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0xf180,0x0d80,\n  0x0d80,0x0700, // u0133\n  0x0780,0x0cc0,0x0000,0x0780,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x6300,0x6300,0x6300,0x3e00,0x0000,\n  0x0000,0x0000, // u0134\n  0x0000,0x0000,0x0000,0x0780,0x0cc0,0x0000,0x0700,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x3300,\n  0x3300,0x1e00, // u0135\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7800,0x6c00,0x6600,0x6300,0x6180,0x6180,0x0c00,\n  0x0c00,0x1800, // u0136\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6180,0x6300,0x6600,0x6c00,0x7800,0x6c00,0x6600,0x6300,0x6180,0x0c00,\n  0x0c00,0x1800, // u0137\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6300,0x6600,0x6c00,0x7800,0x6c00,0x6600,0x6300,0x6180,0x0000,\n  0x0000,0x0000, // u0138\n  0x3000,0x6000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u0139\n  0x0600,0x0c00,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u013a\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0c00,\n  0x0c00,0x1800, // u013b\n  0x0000,0x0000,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0c00,\n  0x0c00,0x1800, // u013c\n  0x3300,0x1e00,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u013d\n  0x3300,0x1e00,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u013e\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6300,0x6300,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u013f\n  0x0000,0x0000,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0cc0,0x0cc0,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u0140\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3c00,0x3800,0x3000,0x7000,0xf000,0x3000,0x3000,0x3000,0x3fc0,0x0000,\n  0x0000,0x0000, // u0141\n  0x0000,0x0000,0x0000,0x1c00,0x0c00,0x0c00,0x0f00,0x0e00,0x0c00,0x1c00,0x3c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u0142\n  0x0600,0x0c00,0x0000,0x6180,0x6180,0x6180,0x7180,0x7980,0x6d80,0x6780,0x6380,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u0143\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u0144\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x7180,0x7980,0x6d80,0x6780,0x6380,0x6180,0x6180,0x6180,0x6180,0x0c00,\n  0x0c00,0x1800, // u0145\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0c00,\n  0x0c00,0x1800, // u0146\n  0x3300,0x1e00,0x0000,0x6180,0x6180,0x6180,0x7180,0x7980,0x6d80,0x6780,0x6380,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u0147\n  0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u0148\n  0x0000,0x6000,0x6000,0x6000,0xc000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u0149\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x7180,0x7980,0x6d80,0x6780,0x6380,0x6180,0x6180,0x6180,0x6180,0x0180,\n  0x0180,0x0700, // u014a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0180,\n  0x0180,0x0700, // u014b\n  0x0000,0x3f00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u014c\n  0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u014d\n  0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u014e\n  0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u014f\n  0x1980,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0150\n  0x0000,0x0000,0x0000,0x1980,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0151\n  0x0000,0x0000,0x0000,0x7fc0,0xc600,0xc600,0xc600,0xc600,0xc7c0,0xc600,0xc600,0xc600,0xc600,0xc600,0x7fc0,0x0000,\n  0x0000,0x0000, // u0152\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0xccc0,0xccc0,0xccc0,0xcfc0,0xcc00,0xcc00,0xccc0,0x7f80,0x0000,\n  0x0000,0x0000, // u0153\n  0x0600,0x0c00,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x7800,0x6c00,0x6600,0x6300,0x6180,0x0000,\n  0x0000,0x0000, // u0154\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x6f80,0x7800,0x7000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,\n  0x0000,0x0000, // u0155\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x7800,0x6c00,0x6600,0x6300,0x6180,0x0c00,\n  0x0c00,0x1800, // u0156\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6f80,0x7800,0x7000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x3000,\n  0x3000,0x6000, // u0157\n  0x3300,0x1e00,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x7800,0x6c00,0x6600,0x6300,0x6180,0x0000,\n  0x0000,0x0000, // u0158\n  0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x6f80,0x7800,0x7000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,\n  0x0000,0x0000, // u0159\n  0x0600,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x3f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u015a\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x3f00,0x6180,0x6000,0x6000,0x3f00,0x0180,0x0180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u015b\n  0x1e00,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x3f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u015c\n  0x0000,0x0000,0x0000,0x1e00,0x3300,0x0000,0x3f00,0x6180,0x6000,0x6000,0x3f00,0x0180,0x0180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u015d\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x3f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,0x0c00,\n  0x0c00,0x1800, // u015e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x6000,0x3f00,0x0180,0x0180,0x6180,0x3f00,0x0c00,\n  0x0c00,0x1800, // u015f\n  0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x3f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0160\n  0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6000,0x6000,0x3f00,0x0180,0x0180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0161\n  0x0000,0x0000,0x0000,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0600,\n  0x0600,0x0c00, // u0162\n  0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x7e00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0f00,0x0600,\n  0x0600,0x0c00, // u0163\n  0x3300,0x1e00,0x0000,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u0164\n  0x6600,0x3c00,0x0000,0x1800,0x1800,0x1800,0x7e00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0f00,0x0000,\n  0x0000,0x0000, // u0165\n  0x0000,0x0000,0x0000,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u0166\n  0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x7e00,0x1800,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x0f00,0x0000,\n  0x0000,0x0000, // u0167\n  0x3b80,0x6e00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0168\n  0x0000,0x0000,0x0000,0x3b80,0x6e00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u0169\n  0x0000,0x3f00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u016a\n  0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u016b\n  0x3300,0x1e00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u016c\n  0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u016d\n  0x1e00,0x3300,0x1e00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u016e\n  0x0000,0x0000,0x0000,0x1e00,0x3300,0x1e00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u016f\n  0x1980,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0170\n  0x0000,0x0000,0x0000,0x1980,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u0171\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0c00,\n  0x1800,0x0e00, // u0172\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,\n  0x0300,0x01c0, // u0173\n  0x1e00,0x3300,0x0000,0xc180,0xc180,0xc180,0xc180,0xc180,0xc180,0xc980,0xdd80,0xf780,0xe380,0xc180,0x8080,0x0000,\n  0x0000,0x0000, // u0174\n  0x0000,0x0000,0x0000,0x1e00,0x3300,0x0000,0x6180,0x6180,0x6180,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,0x0000,\n  0x0000,0x0000, // u0175\n  0x1e00,0x3300,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u0176\n  0x0000,0x0000,0x0000,0x1e00,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,\n  0x0180,0x3f00, // u0177\n  0x3300,0x3300,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u0178\n  0x0600,0x0c00,0x0000,0x7f80,0x0180,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u0179\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x7f80,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u017a\n  0x0c00,0x0c00,0x0000,0x7f80,0x0180,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u017b\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x7f80,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u017c\n  0x3300,0x1e00,0x0000,0x7f80,0x0180,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u017d\n  0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x7f80,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u017e\n  0x0000,0x0000,0x0000,0x0780,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u017f\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0186\n  0x0000,0x0000,0x0000,0x7f80,0x0180,0x0180,0x0180,0x0180,0x1f80,0x0180,0x0180,0x0180,0x0180,0x0180,0x7f80,0x0000,\n  0x0000,0x0000, // u018e\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x0180,0x0180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u018f\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x3e00,0x6000,0x6000,0x6000,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0190\n  0x0000,0x0000,0x0000,0x0700,0x0d80,0x0d80,0x0c00,0x0c00,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x6c00,\n  0x6c00,0x3800, // u0192\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x7180,0x7980,0x6d80,0x6780,0x6380,0x6180,0x6180,0x6180,0x6180,0x6000,\n  0x6000,0xc000, // u019d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0180,\n  0x0180,0x0180, // u019e\n  0x0000,0x0000,0x0000,0x7f80,0x0180,0x0180,0x0300,0x0600,0x7f80,0x0c00,0x1800,0x3000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u01b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0180,0x0300,0x0600,0x7f80,0x1800,0x3000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u01b6\n  0x0000,0x0000,0x0000,0x7f80,0x0180,0x0300,0x0600,0x0c00,0x1f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u01b7\n  0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u01cd\n  0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u01ce\n  0x3300,0x1e00,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u01cf\n  0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u01d0\n  0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u01d1\n  0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u01d2\n  0x3300,0x1e00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u01d3\n  0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u01d4\n  0x0000,0x3f80,0x0000,0x7fc0,0xc600,0xc600,0xc600,0xc600,0xffc0,0xc600,0xc600,0xc600,0xc600,0xc600,0xc7c0,0x0000,\n  0x0000,0x0000, // u01e2\n  0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x7b80,0x0cc0,0x0cc0,0x7cc0,0xcfc0,0xcc00,0xcc00,0xccc0,0x7780,0x0000,\n  0x0000,0x0000, // u01e3\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6780,0x6180,0x67c0,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u01e4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x6180,0x6180,0x6180,0x67c0,0x6180,0x6180,0x6180,0x3f80,0x0180,\n  0x0180,0x3f00, // u01e5\n  0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6780,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u01e6\n  0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,\n  0x0180,0x3f00, // u01e7\n  0x3300,0x1e00,0x0000,0x6180,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7800,0x6c00,0x6600,0x6300,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u01e8\n  0x3300,0x1e00,0x0000,0x6000,0x6000,0x6000,0x6180,0x6300,0x6600,0x6c00,0x7800,0x6c00,0x6600,0x6300,0x6180,0x0000,\n  0x0000,0x0000, // u01e9\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0c00,\n  0x1800,0x0e00, // u01ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0c00,\n  0x1800,0x0e00, // u01eb\n  0x0000,0x3f00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0c00,\n  0x1800,0x0e00, // u01ec\n  0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0c00,\n  0x1800,0x0e00, // u01ed\n  0x3300,0x1e00,0x0000,0x7f80,0x0180,0x0300,0x0600,0x0c00,0x1f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u01ee\n  0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x7f80,0x0180,0x0300,0x0600,0x0c00,0x1f00,0x0180,0x0180,0x0180,0x6180,\n  0x6180,0x3f00, // u01ef\n  0x0000,0x0000,0x0000,0x0cc0,0x0780,0x0000,0x0700,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x3300,\n  0x3300,0x1e00, // u01f0\n  0x0600,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6780,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u01f4\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,\n  0x0180,0x3f00, // u01f5\n  0x0600,0x0c00,0x0000,0x7fc0,0xc600,0xc600,0xc600,0xc600,0xffc0,0xc600,0xc600,0xc600,0xc600,0xc600,0xc7c0,0x0000,\n  0x0000,0x0000, // u01fc\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x7b80,0x0cc0,0x0cc0,0x7cc0,0xcfc0,0xcc00,0xcc00,0xccc0,0x7780,0x0000,\n  0x0000,0x0000, // u01fd\n  0x0600,0x0c00,0x0000,0x3f00,0x61c0,0x6180,0x6380,0x6780,0x6d80,0x7980,0x7180,0x6180,0xe180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u01fe\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x3f40,0x6180,0x6380,0x6780,0x6d80,0x7980,0x7180,0x6180,0xbf00,0x0000,\n  0x0000,0x0000, // u01ff\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x3f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,0x0c00,\n  0x0c00,0x1800, // u0218\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x6000,0x3f00,0x0180,0x0180,0x6180,0x3f00,0x0c00,\n  0x0c00,0x1800, // u0219\n  0x0000,0x0000,0x0000,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0600,\n  0x0600,0x0c00, // u021a\n  0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x7e00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0f00,0x0300,\n  0x0300,0x0600, // u021b\n  0x0000,0x3f00,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u0232\n  0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,\n  0x0180,0x3f00, // u0233\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x3300,\n  0x3300,0x1e00, // u0237\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x0180,0x0180,0x0180,0x0180,0x0180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0254\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x0180,0x0180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0258\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x0180,0x0180,0x7f80,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0259\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x6000,0x3e00,0x6000,0x6000,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u025b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6000,\n  0x6000,0xc000, // u0272\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0180,0x0300,0x0600,0x0c00,0x1f00,0x0180,0x0180,0x0180,0x6180,\n  0x6180,0x3f00, // u0292\n  0x0600,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u02bb\n  0x0c00,0x0c00,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u02bc\n  0x0c00,0x0c00,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u02bd\n  0x1e00,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u02c6\n  0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u02c7\n  0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u02d8\n  0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u02d9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,\n  0x1800,0x0e00, // u02db\n  0x3b80,0x6e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u02dc\n  0x1980,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u02dd\n  0x1800,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0300\n  0x0600,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0301\n  0x1e00,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0302\n  0x3b80,0x6e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0303\n  0x0000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0304\n  0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0305\n  0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0306\n  0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0307\n  0x3300,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0308\n  0x1e00,0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u030a\n  0x1980,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u030b\n  0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u030c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0c00,0x0c00, // u0329\n  0x0000,0x6000,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0384\n  0x0600,0x0c00,0x0000,0x3300,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0385\n  0x0000,0x6000,0xc000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u0386\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u0387\n  0x0000,0x6000,0xc000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u0388\n  0x0000,0x6000,0xc000,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u0389\n  0x0000,0x6000,0xc000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u038a\n  0x0000,0x6000,0xc000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u038c\n  0x0000,0x6000,0xc000,0x30c0,0x30c0,0x30c0,0x1980,0x1980,0x0f00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000,\n  0x0000,0x0000, // u038e\n  0x0000,0x6000,0xc000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x3300,0x7380,0x0000,\n  0x0000,0x0000, // u038f\n  0x0600,0x0c00,0x0000,0x3300,0x3300,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0700,0x0000,\n  0x0000,0x0000, // u0390\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u0391\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x0000,\n  0x0000,0x0000, // u0392\n  0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,\n  0x0000,0x0000, // u0393\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x1e00,0x1e00,0x3300,0x3300,0x3300,0x6180,0x6180,0x6180,0x7f80,0x0000,\n  0x0000,0x0000, // u0394\n  0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u0395\n  0x0000,0x0000,0x0000,0x7f80,0x0180,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u0396\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u0397\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6d80,0x6d80,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0398\n  0x0000,0x0000,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u0399\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7800,0x6c00,0x6600,0x6300,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u039a\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x1e00,0x1e00,0x1e00,0x3300,0x3300,0x3300,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u039b\n  0x0000,0x0000,0x0000,0x8080,0xc180,0xe380,0xf780,0xdd80,0xc980,0xc180,0xc180,0xc180,0xc180,0xc180,0xc180,0x0000,\n  0x0000,0x0000, // u039c\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x7180,0x7980,0x6d80,0x6780,0x6380,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u039d\n  0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,\n  0x0000,0x0000, // u039e\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u039f\n  0x0000,0x0000,0x0000,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u03a0\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,\n  0x0000,0x0000, // u03a1\n  0x0000,0x0000,0x0000,0x7f80,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0600,0x0c00,0x1800,0x3000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u03a3\n  0x0000,0x0000,0x0000,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u03a4\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u03a5\n  0x0000,0x0000,0x0000,0x0c00,0x3f00,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,0x0c00,0x0000,\n  0x0000,0x0000, // u03a6\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x1e00,0x3300,0x3300,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u03a7\n  0x0000,0x0000,0x0000,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u03a8\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x3300,0x7380,0x0000,\n  0x0000,0x0000, // u03a9\n  0x3300,0x3300,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u03aa\n  0x3300,0x3300,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u03ab\n  0x0000,0x0000,0x0000,0x0c00,0x1800,0x0000,0x7d80,0xc700,0xc600,0xc600,0xc600,0xc600,0xc600,0xc700,0x7d80,0x0000,\n  0x0000,0x0000, // u03ac\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x3f00,0x6180,0x6000,0x6000,0x3e00,0x6000,0x6000,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u03ad\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0180,\n  0x0180,0x0180, // u03ae\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0700,0x0000,\n  0x0000,0x0000, // u03af\n  0x0600,0x0c00,0x0000,0x3300,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u03b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7d80,0xc700,0xc600,0xc600,0xc600,0xc600,0xc600,0xc700,0x7d80,0x0000,\n  0x0000,0x0000, // u03b1\n  0x0000,0x0000,0x0000,0x3e00,0x6300,0x6300,0x6300,0x6200,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x6000,\n  0x6000,0x6000, // u03b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x1e00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u03b3\n  0x0000,0x0000,0x0000,0x3f00,0x1800,0x0c00,0x1e00,0x3300,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000, // u03b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x6000,0x3e00,0x6000,0x6000,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u03b5\n  0x0000,0x0000,0x0000,0x7f80,0x0300,0x0600,0x0c00,0x1800,0x3000,0x3000,0x6000,0x6000,0x6000,0x6000,0x3f00,0x0180,\n  0x0180,0x0300, // u03b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0180,\n  0x0180,0x0180, // u03b7\n  0x0000,0x0000,0x0000,0x3e00,0x6300,0x6300,0x6300,0x6300,0x7f00,0x6300,0x6300,0x6300,0x6300,0x6300,0x3e00,0x0000,\n  0x0000,0x0000, // u03b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0700,0x0000,\n  0x0000,0x0000, // u03b9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6300,0x6600,0x6c00,0x7800,0x6c00,0x6600,0x6300,0x6180,0x0000,\n  0x0000,0x0000, // u03ba\n  0x0000,0x0000,0x0000,0x1800,0x1800,0x0c00,0x0c00,0x1e00,0x1e00,0x3300,0x3300,0x3300,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u03bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6380,0x7d80,0x6000,\n  0x6000,0x6000, // u03bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u03bd\n  0x0000,0x0000,0x0000,0x3f80,0x6000,0x6000,0x6000,0x6000,0x3f00,0x6000,0x6000,0x6000,0x6000,0x6000,0x3f00,0x0180,\n  0x0180,0x0300, // u03be\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u03bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u03c0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x6000,\n  0x6000,0x6000, // u03c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x3f00,0x0180,\n  0x0180,0x0300, // u03c2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3300,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000, // u03c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0700,0x0000,\n  0x0000,0x0000, // u03c4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u03c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2700,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,0x0c00,\n  0x0c00,0x0c00, // u03c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x1e00,0x3300,0x3300,\n  0x6180,0x6180, // u03c7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,0x0c00,\n  0x0c00,0x0c00, // u03c8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3300,0x6180,0x6180,0x6d80,0x6d80,0x6d80,0x6d80,0x7f80,0x3300,0x0000,\n  0x0000,0x0000, // u03c9\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0700,0x0000,\n  0x0000,0x0000, // u03ca\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u03cb\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u03cc\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u03cd\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x3300,0x6180,0x6180,0x6d80,0x6d80,0x6d80,0x6d80,0x7f80,0x3300,0x0000,\n  0x0000,0x0000, // u03ce\n  0x0000,0x0000,0x0000,0x3e00,0x6300,0x6300,0x6300,0x3f80,0x0300,0x0300,0xe300,0x6300,0x6300,0x6300,0x3e00,0x0000,\n  0x0000,0x0000, // u03d1\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x3f00,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,0x0c00,\n  0x0c00,0x0000, // u03d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf0c0,0x1980,0x0b00,0x0e00,0x0c00,0x1c00,0x3400,0x6600,0xc3c0,0x0000,\n  0x0000,0x0000, // u03f0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x6000,\n  0x6000,0x3f00, // u03f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u03f2\n  0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0700,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x3300,\n  0x3300,0x1e00, // u03f3\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u03f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6000,0xc000,0xc000,0xfe00,0xc000,0xc000,0x6000,0x3f00,0x0000,\n  0x0000,0x0000, // u03f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x0600,0x0300,0x0300,0x7f00,0x0300,0x0300,0x0600,0xfc00,0x0000,\n  0x0000,0x0000, // u03f6\n  0x1800,0x0c00,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u0400\n  0x3300,0x3300,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u0401\n  0x0000,0x0000,0x0000,0xfc00,0x3000,0x3000,0x3f00,0x3180,0x3180,0x3180,0x3180,0x3180,0x3180,0x3180,0x3300,0x0000,\n  0x0000,0x0000, // u0402\n  0x0600,0x0c00,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,\n  0x0000,0x0000, // u0403\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0404\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x3f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0405\n  0x0000,0x0000,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u0406\n  0x3300,0x3300,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u0407\n  0x0000,0x0000,0x0000,0x0780,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x6300,0x6300,0x6300,0x3e00,0x0000,\n  0x0000,0x0000, // u0408\n  0x0000,0x0000,0x0000,0x3c00,0x6c00,0xcc00,0xcc00,0xcf80,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0x8f80,0x0000,\n  0x0000,0x0000, // u0409\n  0x0000,0x0000,0x0000,0xcc00,0xcc00,0xcc00,0xcc00,0xcf80,0xfcc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xcf80,0x0000,\n  0x0000,0x0000, // u040a\n  0x0000,0x0000,0x0000,0xfc00,0x3000,0x3000,0x3f00,0x3180,0x3180,0x3180,0x3180,0x3180,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0000, // u040b\n  0x0600,0x0c00,0x0000,0x6180,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7800,0x6c00,0x6600,0x6300,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u040c\n  0x1800,0x0c00,0x0000,0x6180,0x6180,0x6180,0x6380,0x6780,0x6d80,0x7980,0x7180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u040d\n  0x3300,0x1e00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,0x0180,0x0180,0x0180,0x3f00,0x0000,\n  0x0000,0x0000, // u040e\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x0c00,\n  0x0c00,0x0000, // u040f\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u0410\n  0x0000,0x0000,0x0000,0x7f00,0x6000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x0000,\n  0x0000,0x0000, // u0411\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x0000,\n  0x0000,0x0000, // u0412\n  0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,\n  0x0000,0x0000, // u0413\n  0x0000,0x0000,0x0000,0x1f00,0x3300,0x6300,0x6300,0x6300,0x6300,0x6300,0x6300,0x6300,0x6300,0x6300,0xff80,0xc180,\n  0xc180,0x0000, // u0414\n  0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u0415\n  0x0000,0x0000,0x0000,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,0x1e00,0x3f00,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x0000,\n  0x0000,0x0000, // u0416\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x0180,0x0180,0x1f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0417\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6380,0x6780,0x6d80,0x7980,0x7180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u0418\n  0x3300,0x1e00,0x0000,0x6180,0x6180,0x6180,0x6380,0x6780,0x6d80,0x7980,0x7180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u0419\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7800,0x6c00,0x6600,0x6300,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u041a\n  0x0000,0x0000,0x0000,0x0f80,0x1980,0x3180,0x3180,0x3180,0x3180,0x3180,0x3180,0x3180,0x3180,0x3180,0x6180,0x0000,\n  0x0000,0x0000, // u041b\n  0x0000,0x0000,0x0000,0x8080,0xc180,0xe380,0xf780,0xdd80,0xc980,0xc180,0xc180,0xc180,0xc180,0xc180,0xc180,0x0000,\n  0x0000,0x0000, // u041c\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u041d\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u041e\n  0x0000,0x0000,0x0000,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u041f\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,\n  0x0000,0x0000, // u0420\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0421\n  0x0000,0x0000,0x0000,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u0422\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,0x0180,0x0180,0x0180,0x3f00,0x0000,\n  0x0000,0x0000, // u0423\n  0x0000,0x0000,0x0c00,0x3f00,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,0x0c00,\n  0x0000,0x0000, // u0424\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x1e00,0x3300,0x3300,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u0425\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3fc0,0x00c0,\n  0x00c0,0x0000, // u0426\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0000, // u0427\n  0x0000,0x0000,0x0000,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3f80,0x0000,\n  0x0000,0x0000, // u0428\n  0x0000,0x0000,0x0000,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3fc0,0x00c0,\n  0x00c0,0x0000, // u0429\n  0x0000,0x0000,0x0000,0xe000,0xe000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x0000,\n  0x0000,0x0000, // u042a\n  0x0000,0x0000,0x0000,0xc180,0xc180,0xc180,0xc180,0xf980,0xcd80,0xcd80,0xcd80,0xcd80,0xcd80,0xcd80,0xf980,0x0000,\n  0x0000,0x0000, // u042b\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x0000,\n  0x0000,0x0000, // u042c\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x0180,0x0180,0x1f80,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u042d\n  0x0000,0x0000,0x0000,0xcf00,0xd980,0xd980,0xd980,0xd980,0xf980,0xd980,0xd980,0xd980,0xd980,0xd980,0xcf00,0x0000,\n  0x0000,0x0000, // u042e\n  0x0000,0x0000,0x0000,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0780,0x0d80,0x1980,0x3180,0x6180,0x0000,\n  0x0000,0x0000, // u042f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u0430\n  0x0000,0x0000,0x0000,0x3e00,0x6000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x0000,\n  0x0000,0x0000, // u0431\n  0x0000,0x0000,0x0000,0x3e00,0x6300,0x6300,0x6300,0x6200,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x0000,\n  0x0000,0x0000, // u0432\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,\n  0x0000,0x0000, // u0433\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,\n  0x0180,0x3f00, // u0434\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0435\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6d80,0x6d80,0x6d80,0x3f00,0x1e00,0x3f00,0x6d80,0x6d80,0x6d80,0x0000,\n  0x0000,0x0000, // u0436\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x0180,0x0180,0x1f00,0x0180,0x0180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0437\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u0438\n  0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u0439\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6300,0x6600,0x6c00,0x7800,0x6c00,0x6600,0x6300,0x6180,0x0000,\n  0x0000,0x0000, // u043a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f80,0x1980,0x3180,0x3180,0x3180,0x3180,0x3180,0x3180,0x6180,0x0000,\n  0x0000,0x0000, // u043b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x6180,0x7380,0x7f80,0x6d80,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u043c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u043d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u043e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u043f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x6000,\n  0x6000,0x6000, // u0440\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0441\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u0442\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,\n  0x0180,0x3f00, // u0443\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x3f00,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,0x0c00,\n  0x0c00,0x0000, // u0444\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x3300,0x1e00,0x0c00,0x1e00,0x3300,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u0445\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3fc0,0x00c0,\n  0x00c0,0x0000, // u0446\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0000, // u0447\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3f80,0x0000,\n  0x0000,0x0000, // u0448\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3fc0,0x00c0,\n  0x00c0,0x0000, // u0449\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x3000,0x3000,0x3f00,0x3180,0x3180,0x3180,0x3180,0x3f00,0x0000,\n  0x0000,0x0000, // u044a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc180,0xc180,0xc180,0xf980,0xcd80,0xcd80,0xcd80,0xcd80,0xf980,0x0000,\n  0x0000,0x0000, // u044b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x7e00,0x6300,0x6300,0x6300,0x6300,0x7e00,0x0000,\n  0x0000,0x0000, // u044c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x0180,0x0180,0x1f80,0x0180,0x0180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u044d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xcf00,0xd980,0xd980,0xd980,0xf980,0xd980,0xd980,0xd980,0xcf00,0x0000,\n  0x0000,0x0000, // u044e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x6180,0x6180,0x6180,0x3f80,0x0d80,0x1980,0x3180,0x6180,0x0000,\n  0x0000,0x0000, // u044f\n  0x0000,0x0000,0x0000,0x1800,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0450\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0451\n  0x0000,0x0000,0x0000,0x6000,0xfc00,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0180,\n  0x0180,0x0700, // u0452\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,\n  0x0000,0x0000, // u0453\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0454\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x6000,0x3f00,0x0180,0x0180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u0455\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u0456\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u0457\n  0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0700,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x3300,\n  0x3300,0x1e00, // u0458\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x6c00,0xcc00,0xcf80,0xccc0,0xccc0,0xccc0,0xccc0,0x8f80,0x0000,\n  0x0000,0x0000, // u0459\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xcc00,0xcc00,0xcc00,0xcf80,0xfcc0,0xccc0,0xccc0,0xccc0,0xcf80,0x0000,\n  0x0000,0x0000, // u045a\n  0x0000,0x0000,0x0000,0x6000,0xfc00,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u045b\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x6180,0x6300,0x6600,0x6c00,0x7800,0x6c00,0x6600,0x6300,0x6180,0x0000,\n  0x0000,0x0000, // u045c\n  0x0000,0x0000,0x0000,0x1800,0x0c00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u045d\n  0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,\n  0x0180,0x3f00, // u045e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x0c00,\n  0x0c00,0x0000, // u045f\n  0x0000,0x0000,0x0000,0x6000,0xfc00,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x0000,\n  0x0000,0x0000, // u0462\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0xfc00,0x3000,0x3000,0x3f00,0x3180,0x3180,0x3180,0x3180,0x3f00,0x0000,\n  0x0000,0x0000, // u0463\n  0x0000,0x0000,0x0000,0x7f80,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x1e00,0x3f00,0x6d80,0x6d80,0x6d80,0x6d80,0x0000,\n  0x0000,0x0000, // u046a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x6180,0x3300,0x1e00,0x1e00,0x3f00,0x6d80,0x6d80,0x6d80,0x0000,\n  0x0000,0x0000, // u046b\n  0x0000,0x0180,0x0180,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,\n  0x0000,0x0000, // u0490\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,\n  0x0000,0x0000, // u0491\n  0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0xfc00,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,\n  0x0000,0x0000, // u0492\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0xfc00,0x6000,0x6000,0x6000,0x6000,0x0000,\n  0x0000,0x0000, // u0493\n  0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x0180,\n  0x0300,0x0000, // u0494\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x7e00,0x6300,0x6300,0x6300,0x6300,0x0300,\n  0x0600,0x0000, // u0495\n  0x0000,0x0000,0x0000,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,0x1e00,0x3f00,0x6d80,0x6d80,0x6d80,0x6d80,0x6dc0,0x00c0,\n  0x00c0,0x0000, // u0496\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6d80,0x6d80,0x6d80,0x3f00,0x1e00,0x3f00,0x6d80,0x6d80,0x6dc0,0x00c0,\n  0x00c0,0x0000, // u0497\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x0180,0x0180,0x1f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,0x0c00,\n  0x0c00,0x0c00, // u0498\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x0180,0x0180,0x1f00,0x0180,0x0180,0x6180,0x3f00,0x0c00,\n  0x0c00,0x0c00, // u0499\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7800,0x6c00,0x6600,0x6300,0x6180,0x61c0,0x00c0,\n  0x00c0,0x0000, // u049a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6300,0x6600,0x6c00,0x7800,0x6c00,0x6600,0x6300,0x61c0,0x00c0,\n  0x00c0,0x0000, // u049b\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6b00,0x6e00,0x7c00,0x7c00,0x6e00,0x6b00,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u049c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6b00,0x6e00,0x6c00,0x7800,0x6c00,0x6e00,0x6b00,0x6180,0x0000,\n  0x0000,0x0000, // u049d\n  0x0000,0x0000,0x0000,0xe180,0xe180,0x6300,0x6600,0x6c00,0x7800,0x7800,0x6c00,0x6600,0x6300,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u04a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xe180,0x6300,0x6600,0x6c00,0x7800,0x6c00,0x6600,0x6300,0x6180,0x0000,\n  0x0000,0x0000, // u04a1\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x61c0,0x00c0,\n  0x00c0,0x0000, // u04a2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x61c0,0x00c0,\n  0x00c0,0x0000, // u04a3\n  0x0000,0x0000,0x0000,0xc7c0,0xc600,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0x0000,\n  0x0000,0x0000, // u04a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc7c0,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0x0000,\n  0x0000,0x0000, // u04a5\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x6180,0x3f00,0x0c00,\n  0x0c00,0x0c00, // u04aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x3f00,0x0c00,\n  0x0c00,0x0c00, // u04ab\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u04ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x1e00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u04af\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u04b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x1e00,0x0c00,0x3f00,\n  0x0c00,0x0c00, // u04b1\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x1e00,0x3300,0x3300,0x6180,0x61c0,0x00c0,\n  0x00c0,0x0000, // u04b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x3300,0x1e00,0x0c00,0x1e00,0x3300,0x6180,0x61c0,0x00c0,\n  0x00c0,0x0000, // u04b3\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,0x0180,0x0180,0x0180,0x01c0,0x00c0,\n  0x00c0,0x0000, // u04b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,0x0180,0x0180,0x01c0,0x00c0,\n  0x00c0,0x0000, // u04b7\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6d80,0x6d80,0x6d80,0x3f80,0x0d80,0x0d80,0x0d80,0x0180,0x0180,0x0000,\n  0x0000,0x0000, // u04b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6d80,0x6d80,0x3f80,0x0d80,0x0d80,0x0180,0x0180,0x0000,\n  0x0000,0x0000, // u04b9\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u04ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u04bb\n  0x0000,0x0000,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u04c0\n  0x3300,0x1e00,0x0000,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,0x1e00,0x3f00,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x0000,\n  0x0000,0x0000, // u04c1\n  0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x6d80,0x6d80,0x6d80,0x3f00,0x1e00,0x3f00,0x6d80,0x6d80,0x6d80,0x0000,\n  0x0000,0x0000, // u04c2\n  0x0000,0x0000,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0000,0x0000, // u04cf\n  0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u04d0\n  0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u04d1\n  0x3300,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u04d2\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u04d3\n  0x0000,0x0000,0x0000,0x7fc0,0xc600,0xc600,0xc600,0xc600,0xffc0,0xc600,0xc600,0xc600,0xc600,0xc600,0xc7c0,0x0000,\n  0x0000,0x0000, // u04d4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7b80,0x0cc0,0x0cc0,0x7cc0,0xcfc0,0xcc00,0xcc00,0xccc0,0x7780,0x0000,\n  0x0000,0x0000, // u04d5\n  0x3300,0x1e00,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u04d6\n  0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u04d7\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x0180,0x0180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u04d8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x0180,0x0180,0x7f80,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u04d9\n  0x3300,0x3300,0x0000,0x3f00,0x6180,0x6180,0x0180,0x0180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u04da\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x3f00,0x6180,0x0180,0x0180,0x7f80,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u04db\n  0x3300,0x3300,0x0000,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,0x1e00,0x3f00,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x0000,\n  0x0000,0x0000, // u04dc\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x6d80,0x6d80,0x6d80,0x3f00,0x1e00,0x3f00,0x6d80,0x6d80,0x6d80,0x0000,\n  0x0000,0x0000, // u04dd\n  0x3300,0x3300,0x0000,0x3f00,0x6180,0x6180,0x0180,0x0180,0x1f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u04de\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x3f00,0x6180,0x0180,0x0180,0x1f00,0x0180,0x0180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u04df\n  0x0000,0x3f00,0x0000,0x6180,0x6180,0x6180,0x6380,0x6780,0x6d80,0x7980,0x7180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u04e2\n  0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u04e3\n  0x3300,0x3300,0x0000,0x6180,0x6180,0x6180,0x6380,0x6780,0x6d80,0x7980,0x7180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u04e4\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0000,0x0000, // u04e5\n  0x3300,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u04e6\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u04e7\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u04e8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u04e9\n  0x3300,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u04ea\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u04eb\n  0x3300,0x3300,0x0000,0x3f00,0x6180,0x6180,0x0180,0x0180,0x1f80,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u04ec\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x3f00,0x6180,0x0180,0x0180,0x1f80,0x0180,0x0180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u04ed\n  0x0000,0x3f00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,0x0180,0x0180,0x0180,0x3f00,0x0000,\n  0x0000,0x0000, // u04ee\n  0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,\n  0x0180,0x3f00, // u04ef\n  0x3300,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,0x0180,0x0180,0x0180,0x3f00,0x0000,\n  0x0000,0x0000, // u04f0\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,\n  0x0180,0x3f00, // u04f1\n  0x1980,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,0x0180,0x0180,0x0180,0x3f00,0x0000,\n  0x0000,0x0000, // u04f2\n  0x0000,0x0000,0x0000,0x1980,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,\n  0x0180,0x3f00, // u04f3\n  0x3300,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0000, // u04f4\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0000, // u04f5\n  0x6600,0x6600,0x0000,0xc180,0xc180,0xc180,0xc180,0xf980,0xcd80,0xcd80,0xcd80,0xcd80,0xcd80,0xcd80,0xf980,0x0000,\n  0x0000,0x0000, // u04f8\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0xc180,0xc180,0xc180,0xf980,0xcd80,0xcd80,0xcd80,0xcd80,0xf980,0x0000,\n  0x0000,0x0000, // u04f9\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x3180,0x3180,0x1980,0x3b00,0x6e00,0xcc00,0xc600,0xc600,0xc300,0xc300,0x0000,\n  0x0000,0x0000, // u05d0\n  0x0000,0x0000,0x0000,0x7f00,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x7fc0,0x0000,\n  0x0000,0x0000, // u05d1\n  0x0000,0x0000,0x0000,0x7c00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0e00,0x1b00,0x3300,0x6180,0xc180,0x0000,\n  0x0000,0x0000, // u05d2\n  0x0000,0x0000,0x0000,0x7fc0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0000, // u05d3\n  0x0000,0x0000,0x0000,0x7f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u05d4\n  0x0000,0x0000,0x0000,0x3800,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u05d5\n  0x0000,0x0000,0x0000,0x3f00,0x0300,0x0600,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u05d6\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u05d7\n  0x0000,0x0000,0x0000,0x6700,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u05d8\n  0x0000,0x0000,0x0000,0x3800,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u05d9\n  0x0000,0x0000,0x0000,0x7f00,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180, // u05da\n  0x0000,0x0000,0x0000,0x7f00,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x7f00,0x0000,\n  0x0000,0x0000, // u05db\n  0x0000,0x6000,0x6000,0x7f80,0x0180,0x0180,0x0180,0x0180,0x0300,0x0600,0x0c00,0x1800,0x1800,0x1800,0x1800,0x0000,\n  0x0000,0x0000, // u05dc\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x0000,\n  0x0000,0x0000, // u05dd\n  0x0000,0x0000,0x0000,0xde00,0x7300,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6780,0x0000,\n  0x0000,0x0000, // u05de\n  0x0000,0x0000,0x0000,0x7c00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600, // u05df\n  0x0000,0x0000,0x0000,0x3e00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x3f00,0x0000,\n  0x0000,0x0000, // u05e0\n  0x0000,0x0000,0x0000,0xff00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u05e1\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x3180,0x3180,0x3180,0x1980,0x1b00,0x1b00,0x0e00,0x1c00,0x7000,0x0000,\n  0x0000,0x0000, // u05e2\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x3980,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180, // u05e3\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x3980,0x0180,0x0180,0x0180,0x0180,0x0180,0x7f00,0x0000,\n  0x0000,0x0000, // u05e4\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x3180,0x3180,0x1b00,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u05e5\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x3180,0x3180,0x1b00,0x1e00,0x0c00,0x0c00,0x0600,0x0600,0x0300,0x7f00,0x0000,\n  0x0000,0x0000, // u05e6\n  0x0000,0x0000,0x0000,0x7f80,0x0180,0x0180,0x0180,0x6180,0x6180,0x6300,0x6600,0x6c00,0x6c00,0x6c00,0x6c00,0x6000,\n  0x6000,0x6000, // u05e7\n  0x0000,0x0000,0x0000,0x7f00,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0000, // u05e8\n  0x0000,0x0000,0x0000,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x7980,0x7180,0x6180,0x6180,0x6300,0x7e00,0x0000,\n  0x0000,0x0000, // u05e9\n  0x0000,0x0000,0x0000,0xff00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0xc180,0x0000,\n  0x0000,0x0000, // u05ea\n  0x0000,0x0000,0x0000,0x7e00,0x6300,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6300,0x7e00,0x0000,\n  0x1800,0x1800, // u1e0c\n  0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0c00,0x0c00, // u1e0d\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7800,0x6c00,0x6600,0x6300,0x6180,0x6180,0x0000,\n  0x3f00,0x0000, // u1e34\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6180,0x6300,0x6600,0x6c00,0x7800,0x6c00,0x6600,0x6300,0x6180,0x0000,\n  0x3f00,0x0000, // u1e35\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0c00,0x0c00, // u1e36\n  0x0000,0x0000,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0c00,0x0c00, // u1e37\n  0x0c00,0x0c00,0x0000,0x8080,0xc180,0xe380,0xf780,0xdd80,0xc980,0xc180,0xc180,0xc180,0xc180,0xc180,0xc180,0x0000,\n  0x0000,0x0000, // u1e40\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x7f00,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x0000,\n  0x0000,0x0000, // u1e41\n  0x0000,0x0000,0x0000,0x8080,0xc180,0xe380,0xf780,0xdd80,0xc980,0xc180,0xc180,0xc180,0xc180,0xc180,0xc180,0x0000,\n  0x0c00,0x0c00, // u1e42\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x0000,\n  0x0c00,0x0c00, // u1e43\n  0x0c00,0x0c00,0x0000,0x6180,0x6180,0x6180,0x7180,0x7980,0x6d80,0x6780,0x6380,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u1e44\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u1e45\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x7180,0x7980,0x6d80,0x6780,0x6380,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0c00,0x0c00, // u1e46\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0c00,0x0c00, // u1e47\n  0x0000,0x0000,0x0000,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0c00,0x0c00, // u1e6c\n  0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x7e00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0f00,0x0600,\n  0x0600,0x0000, // u1e6d\n  0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0c00,0x0c00, // u1eb8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,0x0000,\n  0x0c00,0x0c00, // u1eb9\n  0x3b80,0x6e00,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000, // u1ebc\n  0x0000,0x0000,0x0000,0x3b80,0x6e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,0x0000,\n  0x0000,0x0000, // u1ebd\n  0x0000,0x0000,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0c00,0x0c00, // u1eca\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,\n  0x0c00,0x0c00, // u1ecb\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0c00,0x0c00, // u1ecc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0c00,0x0c00, // u1ecd\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,\n  0x0c00,0x0c00, // u1ee4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0000,\n  0x0c00,0x0c00, // u1ee5\n  0x3b80,0x6e00,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u1ef8\n  0x0000,0x0000,0x0000,0x3b80,0x6e00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,\n  0x0180,0x3f00, // u1ef9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2001\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2002\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2003\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2004\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2005\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2006\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2007\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2008\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2009\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u200a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u200b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u200c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u200d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u200e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u200f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2010\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2011\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2012\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2013\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2014\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2015\n  0x0000,0x0000,0x0000,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x0000,\n  0x0000,0x0000, // u2016\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,\n  0x0000,0x7f80, // u2017\n  0x0000,0x0600,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2018\n  0x0000,0x0c00,0x0c00,0x0c00,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2019\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x1800,\n  0x0000,0x0000, // u201a\n  0x0000,0x1800,0x1800,0x1800,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u201b\n  0x0000,0x1980,0x3300,0x3300,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u201c\n  0x0000,0x1980,0x1980,0x1980,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u201d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3300,0x3300,0x3300,0x6600,\n  0x0000,0x0000, // u201e\n  0x0000,0x6600,0x6600,0x6600,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u201f\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u2020\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u2021\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x1e00,0x1e00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2022\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6d80,0x6d80,0x0000,\n  0x0000,0x0000, // u2026\n  0x0000,0x0000,0x0000,0xe600,0xa600,0xec00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x6000,0x6fc0,0xcb40,0xcfc0,0x0000,\n  0x0000,0x0000, // u2030\n  0x0000,0x0c00,0x0c00,0x0c00,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2032\n  0x0000,0x3300,0x3300,0x3300,0x2200,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2033\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x1800,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0000,\n  0x0000,0x0000, // u2039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0600,0x0c00,0x1800,0x3000,0x0000,\n  0x0000,0x0000, // u203a\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x3300,0x3300,0x3300,0x3300,0x3300,0x3300,0x0000,0x0000,0x3300,0x3300,0x0000,\n  0x0000,0x0000, // u203c\n  0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u203e\n  0x0000,0x1e00,0x3300,0x3300,0x3300,0x3300,0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2070\n  0x0c00,0x0c00,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2071\n  0x0000,0x0300,0x0700,0x0f00,0x1b00,0x3f80,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2074\n  0x0000,0x3e00,0x3000,0x3000,0x3e00,0x0300,0x0300,0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2075\n  0x0000,0x1e00,0x3000,0x3000,0x3e00,0x3300,0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2076\n  0x0000,0x3f00,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2077\n  0x0000,0x1e00,0x3300,0x3300,0x1e00,0x3300,0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2078\n  0x0000,0x1e00,0x3300,0x3300,0x1f00,0x0300,0x0300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2079\n  0x0000,0x0000,0x0c00,0x0c00,0x3f00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u207a\n  0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u207b\n  0x0000,0x0000,0x0000,0x3f00,0x0000,0x0000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u207c\n  0x0000,0x0600,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u207d\n  0x0000,0x0c00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u207e\n  0x0000,0x0000,0x3e00,0x3300,0x3300,0x3300,0x3300,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u207f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x3300,0x3300,0x3300,0x3300,0x1e00,\n  0x0000,0x0000, // u2080\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000, // u2081\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x3300,0x0600,0x0c00,0x1800,0x3f00,\n  0x0000,0x0000, // u2082\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x0300,0x0e00,0x0300,0x3300,0x1e00,\n  0x0000,0x0000, // u2083\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0700,0x0f00,0x1b00,0x3f80,0x0300,0x0300,\n  0x0000,0x0000, // u2084\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x3000,0x3000,0x3e00,0x0300,0x0300,0x3e00,\n  0x0000,0x0000, // u2085\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3000,0x3000,0x3e00,0x3300,0x3300,0x1e00,\n  0x0000,0x0000, // u2086\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000, // u2087\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x3300,0x1e00,0x3300,0x3300,0x1e00,\n  0x0000,0x0000, // u2088\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x3300,0x1f00,0x0300,0x0300,0x1e00,\n  0x0000,0x0000, // u2089\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x3f00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u208a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u208b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x0000,0x3f00,0x0000,0x0000,\n  0x0000,0x0000, // u208c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0600,\n  0x0000,0x0000, // u208d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0c00,\n  0x0000,0x0000, // u208e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x0300,0x1f00,0x3300,0x3300,0x1f00,\n  0x0000,0x0000, // u2090\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x3f00,0x3000,0x3000,0x1f00,\n  0x0000,0x0000, // u2091\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x3300,0x3300,0x3300,0x1e00,\n  0x0000,0x0000, // u2092\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3300,0x1e00,0x0c00,0x0c00,0x1e00,0x3300,\n  0x0000,0x0000, // u2093\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0300,0x0300,0x3f00,0x3300,0x1e00,\n  0x0000,0x0000, // u2094\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3e00,0x3300,0x3300,0x3300,0x3300,0x3300,\n  0x0000,0x0000, // u2095\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3300,0x3600,0x3c00,0x3c00,0x3600,0x3300,\n  0x0000,0x0000, // u2096\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000, // u2097\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,\n  0x0000,0x0000, // u2098\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x3300,0x3300,0x3300,0x3300,0x3e00,\n  0x3000,0x3000, // u209a\n  0x0000,0x0000,0x0000,0xf800,0xcc00,0xcc00,0xcc00,0xcc00,0xfb00,0xc300,0xc780,0xc300,0xc300,0xc300,0xc180,0x0000,\n  0x0000,0x0000, // u20a7\n  0x0000,0x0000,0x0000,0xf880,0x8480,0x8480,0x9480,0x9480,0x9480,0x9480,0x9480,0x9480,0x9080,0x9080,0x9f00,0x0000,\n  0x0000,0x0000, // u20aa\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x6000,0xfe00,0x6000,0x6000,0xfe00,0x6000,0x60c0,0x3180,0x1f00,0x0000,\n  0x0000,0x0000, // u20ac\n  0x0000,0x0000,0x0000,0x7f80,0x0c00,0x0c00,0x0c00,0x0f00,0x3c00,0x0f00,0x3c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u20ae\n  0x0000,0x0000,0x0000,0x3e00,0x5100,0x5100,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5100,0x5100,0x3e00,0x0000,\n  0x0000,0x0000, // u2102\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u210e\n  0x0000,0x0000,0x0000,0x6000,0xfc00,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u210f\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x6100,0x5100,0x6900,0x5500,0x4b00,0x4500,0x4300,0x4100,0x4100,0x4100,0x0000,\n  0x0000,0x0000, // u2115\n  0x0000,0x0000,0x0000,0xcc00,0xcdc0,0xcd40,0xed40,0xedc0,0xfc00,0xfc00,0xddc0,0xddc0,0xcc00,0xcdc0,0xcdc0,0x0000,\n  0x0000,0x0000, // u2116\n  0x0000,0x0000,0x0000,0x3e00,0x5100,0x5100,0x5100,0x5100,0x5100,0x5100,0x5100,0x5100,0x5100,0x5500,0x3e00,0x0100,\n  0x0080,0x0000, // u211a\n  0x0000,0x0000,0x0000,0x7e00,0x5100,0x5100,0x5100,0x5100,0x5100,0x5e00,0x5400,0x5a00,0x5500,0x5280,0x7180,0x0000,\n  0x0000,0x0000, // u211d\n  0x0000,0x0000,0x0000,0xf440,0x66c0,0x67c0,0x66c0,0x66c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2122\n  0x0000,0x0000,0x0000,0x7f00,0x0100,0x0300,0x0500,0x0a00,0x1400,0x2800,0x5000,0x6000,0x4000,0x4000,0x7f00,0x0000,\n  0x0000,0x0000, // u2124\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x3300,0x7380,0x0000,\n  0x0000,0x0000, // u2126\n  0x0000,0x0000,0x0000,0x6300,0x6300,0x3180,0x3180,0x18c0,0x3980,0x6f00,0xce00,0xc600,0xc600,0xc300,0x6300,0x0000,\n  0x0000,0x0000, // u2135\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x3000,0x6000,0xff80,0xff80,0x6000,0x3000,0x1000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2190\n  0x0000,0x0000,0x0000,0x0c00,0x1e00,0x3f00,0x6d80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u2191\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0600,0x0300,0xff80,0xff80,0x0300,0x0600,0x0400,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2192\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x6d80,0x3f00,0x1e00,0x0c00,0x0000,\n  0x0000,0x0000, // u2193\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1200,0x3300,0x6180,0xffc0,0xffc0,0x6180,0x3300,0x1200,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2194\n  0x0000,0x0000,0x0000,0x0c00,0x1e00,0x3f00,0x6d80,0x0c00,0x0c00,0x0c00,0x0c00,0x6d80,0x3f00,0x1e00,0x0c00,0x0000,\n  0x0000,0x0000, // u2195\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1180,0x3180,0x6180,0xff80,0xff80,0x6180,0x3180,0x1180,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u21a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc400,0xc600,0xc300,0xff80,0xff80,0xc300,0xc600,0xc400,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u21a6\n  0x0000,0x0000,0x0000,0x0c00,0x1e00,0x3f00,0x6d80,0x0c00,0x0c00,0x0c00,0x6d80,0x3f00,0x1e00,0x0c00,0x7f80,0x0000,\n  0x0000,0x0000, // u21a8\n  0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x1180,0x3180,0x6180,0xff80,0xff80,0x6000,0x3000,0x1000,0x0000,\n  0x0000,0x0000, // u21b5\n  0x0000,0x0000,0x0000,0x0000,0xf800,0x3800,0x6800,0xc980,0xc180,0xc180,0xc180,0x6300,0x3e00,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u21bb\n  0x0000,0x0000,0x0000,0x1000,0x3000,0x6000,0xff80,0xff80,0x0000,0xff80,0xff80,0x0300,0x0600,0x0400,0x0000,0x0000,\n  0x0000,0x0000, // u21cb\n  0x0000,0x0000,0x0000,0x0400,0x0600,0x0300,0xff80,0xff80,0x0000,0xff80,0xff80,0x6000,0x3000,0x1000,0x0000,0x0000,\n  0x0000,0x0000, // u21cc\n  0x0000,0x0000,0x0000,0x0000,0x0800,0x1800,0x3f80,0x7f80,0xe000,0x7f80,0x3f80,0x1800,0x0800,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u21d0\n  0x0000,0x0000,0x0000,0x0800,0x1c00,0x3e00,0x7700,0xf780,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x0000,\n  0x0000,0x0000, // u21d1\n  0x0000,0x0000,0x0000,0x0000,0x0800,0x0c00,0xfe00,0xff00,0x0380,0xff00,0xfe00,0x0c00,0x0800,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u21d2\n  0x0000,0x0000,0x0000,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0xf780,0x7700,0x3e00,0x1c00,0x0800,0x0000,\n  0x0000,0x0000, // u21d3\n  0x0000,0x0000,0x0000,0x0000,0x1200,0x3300,0x7f80,0xffc0,0xc0c0,0xffc0,0x7f80,0x3300,0x1200,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u21d4\n  0x0000,0x0000,0x0000,0x0800,0x1c00,0x3e00,0x7700,0xf780,0x3600,0x3600,0xf780,0x7700,0x3e00,0x1c00,0x0800,0x0000,\n  0x0000,0x0000, // u21d5\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x7f80,0x3300,0x3300,0x3300,0x1200,0x1e00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u2200\n  0x0000,0x0000,0x0000,0x0000,0x7f80,0x0180,0x0180,0x0180,0x0180,0x7f80,0x0180,0x0180,0x0180,0x0180,0x7f80,0x0000,\n  0x0000,0x0000, // u2203\n  0x0000,0x0000,0x0000,0x0300,0x7f80,0x0780,0x0580,0x0d80,0x0d80,0x7f80,0x1980,0x1980,0x3180,0x3180,0x7f80,0x6000,\n  0x0000,0x0000, // u2204\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x3f00,0x6780,0x6d80,0x6d80,0x6d80,0x7980,0x3f00,0x3000,0x6000,0x0000,\n  0x0000,0x0000, // u2205\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x1e00,0x1e00,0x3300,0x3300,0x3300,0x6180,0x6180,0x6180,0x7f80,0x0000,\n  0x0000,0x0000, // u2206\n  0x0000,0x0000,0x0000,0x7f80,0x6180,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x1e00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u2207\n  0x0000,0x0000,0x0000,0x0000,0x0f80,0x1800,0x3000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x3000,0x1800,0x0f80,0x0000,\n  0x0000,0x0000, // u2208\n  0x0000,0x0000,0x0000,0x0180,0x0f80,0x1b00,0x3300,0x6600,0x6600,0x7f80,0x6c00,0x6c00,0x3800,0x1800,0x3f80,0x3000,\n  0x0000,0x0000, // u2209\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x3000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x3000,0x1f80,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u220a\n  0x0000,0x0000,0x0000,0x0000,0x7c00,0x0600,0x0300,0x0180,0x0180,0x7f80,0x0180,0x0180,0x0300,0x0600,0x7c00,0x0000,\n  0x0000,0x0000, // u220b\n  0x0000,0x0000,0x0000,0x6000,0x7c00,0x3600,0x3300,0x1980,0x1980,0x7f80,0x0d80,0x0d80,0x0700,0x0600,0x7f00,0x0300,\n  0x0000,0x0000, // u220c\n  0x0000,0x0000,0x0000,0x0000,0x7e00,0x0300,0x0180,0x0180,0x7f80,0x0180,0x0180,0x0300,0x7e00,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u220d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2212\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u2213\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u2214\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2215\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2216\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x1c00,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2219\n  0x0000,0x0380,0x0380,0x0300,0x0300,0x0300,0x0300,0x0300,0x6300,0x6300,0x6300,0x3300,0x1b00,0x0f00,0x0700,0x0000,\n  0x0000,0x0000, // u221a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u221e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u221f\n  0x0000,0x0000,0x0000,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x0000,\n  0x0000,0x0000, // u2225\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x1e00,0x1e00,0x3300,0x3300,0x3300,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u2227\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x1e00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u2228\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u2229\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000, // u222a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3980,0x6d80,0x6700,0x0000,0x3980,0x6d80,0x6700,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2248\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x7f80,0x0600,0x0c00,0x1800,0x7f80,0x6000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2260\n  0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2261\n  0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x1800,0x3000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0000,0x7f80,0x0000,\n  0x0000,0x0000, // u2264\n  0x0000,0x0000,0x0000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0300,0x0600,0x0c00,0x1800,0x3000,0x0000,0x7f80,0x0000,\n  0x0000,0x0000, // u2265\n  0x0000,0x0000,0x0000,0x0000,0x0440,0x0cc0,0x1980,0x3300,0x6600,0xcc00,0x6600,0x3300,0x1980,0x0cc0,0x0440,0x0000,\n  0x0000,0x0000, // u226a\n  0x0000,0x0000,0x0000,0x0000,0x8800,0xcc00,0x6600,0x3300,0x1980,0x0cc0,0x1980,0x3300,0x6600,0xcc00,0x8800,0x0000,\n  0x0000,0x0000, // u226b\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x3000,0x6000,0x6000,0x6000,0x6000,0x6000,0x3000,0x1f80,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2282\n  0x0000,0x0000,0x0000,0x0000,0x7e00,0x0300,0x0180,0x0180,0x0180,0x0180,0x0180,0x0300,0x7e00,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2283\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x3000,0x6000,0x6000,0x6000,0x6000,0x6000,0x3000,0x1f80,0x0000,0x7f80,0x0000,\n  0x0000,0x0000, // u2286\n  0x0000,0x0000,0x0000,0x0000,0x7e00,0x0300,0x0180,0x0180,0x0180,0x0180,0x0180,0x0300,0x7e00,0x0000,0x7f80,0x0000,\n  0x0000,0x0000, // u2287\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x7f80,0x0000,\n  0x0000,0x0000, // u22a5\n  0x0000,0x0000,0x0000,0x1e00,0x3300,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000, // u22c2\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000, // u22c3\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x3f00,0x6780,0x6d80,0x6d80,0x6d80,0x7980,0x3f00,0x3000,0x6000,0x0000,\n  0x0000,0x0000, // u2300\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x1c00,0x3600,0x6300,0xc180,0xc180,0xc180,0xc180,0xc180,0xff80,0x0000,\n  0x0000,0x0000, // u2302\n  0x0000,0x0000,0x0000,0x1e00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,\n  0x0000,0x0000, // u2308\n  0x0000,0x0000,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000,\n  0x0000,0x0000, // u2309\n  0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1e00,0x0000,\n  0x0000,0x0000, // u230a\n  0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x1e00,0x0000,\n  0x0000,0x0000, // u230b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2310\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2319\n  0x0000,0x0000,0x0000,0x0700,0x0d80,0x0d80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2320\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x6c00,0x6c00,0x3800,0x0000,\n  0x0000,0x0000, // u2321\n  0x0300,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x1800,0x3000,0x3000,0x3000,0x3000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000, // u239b\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000, // u239c\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x3000,0x3000,0x3000,0x3000,0x1800,0x1800,0x1800,0x0c00,0x0c00,\n  0x0600,0x0300, // u239d\n  0x6000,0x3000,0x1800,0x1800,0x0c00,0x0c00,0x0c00,0x0600,0x0600,0x0600,0x0600,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300, // u239e\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300, // u239f\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0600,0x0600,0x0600,0x0600,0x0c00,0x0c00,0x0c00,0x1800,0x1800,\n  0x3000,0x6000, // u23a0\n  0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000, // u23a1\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000, // u23a2\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x7f00, // u23a3\n  0x7f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300, // u23a4\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300, // u23a5\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x7f00, // u23a6\n  0x03c0,0x0e00,0x0c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,\n  0x1800,0x1800, // u23a7\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3000,0xe000,0xe000,0x3000,0x1800,0x1800,0x1800,0x1800,0x1800,\n  0x1800,0x1800, // u23a8\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0c00,\n  0x0e00,0x03c0, // u23a9\n  0xf000,0x1c00,0x0c00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600, // u23ab\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0300,0x01c0,0x01c0,0x0300,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600, // u23ac\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0c00,\n  0x1c00,0xf000, // u23ad\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u23ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u23af\n  0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u23ba\n  0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u23bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x0000,0x0000,\n  0x0000,0x0000, // u23bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0xffc0,0xffc0, // u23bd\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u23d0\n  0x0000,0x0000,0xcc00,0xcc00,0xfc00,0xcc00,0xcc00,0xcc00,0x0000,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000,\n  0x0000,0x0000, // u2409\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xc000,0xc000,0xfc00,0x0000,0x1f80,0x1800,0x1e00,0x1800,0x1800,0x1800,0x0000,\n  0x0000,0x0000, // u240a\n  0x0000,0x0000,0xcc00,0xcc00,0xcc00,0xcc00,0x7800,0x3000,0x0000,0x0000,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0000,0x0000, // u240b\n  0x0000,0x0000,0xfc00,0xc000,0xf000,0xc000,0xc000,0xc000,0x0000,0x1f80,0x1800,0x1e00,0x1800,0x1800,0x1800,0x0000,\n  0x0000,0x0000, // u240c\n  0x0000,0x0000,0x7800,0xcc00,0xc000,0xc000,0xcc00,0x7800,0x0000,0x1f00,0x1980,0x1980,0x1f00,0x1b00,0x1980,0x0000,\n  0x0000,0x0000, // u240d\n  0x0000,0x0000,0xcc00,0xec00,0xfc00,0xdc00,0xcc00,0xcc00,0x0000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1f80,0x0000,\n  0x0000,0x0000, // u2424\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2500\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2501\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2502\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u2503\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xd680,0xd680,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2508\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xd680,0xd680,0xd680,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2509\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0c00,0x0c00,0x0c00,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0c00,0x0c00,\n  0x0c00,0x0000, // u250a\n  0x1c00,0x1c00,0x1c00,0x1c00,0x0000,0x1c00,0x1c00,0x1c00,0x0000,0x1c00,0x1c00,0x1c00,0x1c00,0x0000,0x1c00,0x1c00,\n  0x1c00,0x0000, // u250b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u250c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fc0,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u250d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x1fc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u250e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x1fc0,0x1fc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u250f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2510\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2511\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u2512\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0xfc00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u2513\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2514\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2515\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1fc0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2516\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1fc0,0x1fc0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2517\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2518\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2519\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u251a\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xfc00,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u251b\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u251c\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0fc0,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u251d\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1fc0,0x1fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u251e\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1fc0,0x1fc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u251f\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1fc0,0x1fc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u2520\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1fc0,0x1fc0,0x1fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2521\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1fc0,0x1fc0,0x1fc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u2522\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1fc0,0x1fc0,0x1fc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u2523\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2524\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2525\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2526\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u2527\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xfc00,0xfc00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u2528\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xfc00,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2529\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0xfc00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u252a\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xfc00,0xfc00,0xfc00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u252b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u252c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u252d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u252e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u252f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u2530\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xffc0,0xffc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u2531\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0xffc0,0xffc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u2532\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0xffc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u2533\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2534\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2535\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2536\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2537\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2538\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xfc00,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2539\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1fc0,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u253a\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xffc0,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u253b\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u253c\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u253d\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u253e\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u253f\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2540\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xffc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u2541\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xffc0,0xffc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u2542\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xfc00,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2543\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1fc0,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2544\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xffc0,0xffc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u2545\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0xffc0,0xffc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u2546\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xffc0,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2547\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xffc0,0xffc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u2548\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xfc00,0xffc0,0xffc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u2549\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1fc0,0xffc0,0xffc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u254a\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xffc0,0xffc0,0xffc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u254b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x0000,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2550\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600, // u2551\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fc0,0x0c00,0x0fc0,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2552\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x3fc0,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600, // u2553\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x3fc0,0x3000,0x37c0,0x37c0,0x3600,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600, // u2554\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x0c00,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2555\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xfe00,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600, // u2556\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xfe00,0x0600,0xf600,0xf600,0x3600,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600, // u2557\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0fc0,0x0c00,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2558\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3fc0,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2559\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x37c0,0x37c0,0x3000,0x3fc0,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u255a\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0x0c00,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u255b\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0xfe00,0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u255c\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0xf600,0xf600,0x0600,0xfe00,0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u255d\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0fc0,0x0c00,0x0fc0,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u255e\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x37c0,0x37c0,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600, // u255f\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x37c0,0x37c0,0x3000,0x37c0,0x37c0,0x3600,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600, // u2560\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0x0c00,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2561\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0xf600,0xf600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600, // u2562\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0xf600,0xf600,0x0600,0xf600,0xf600,0x3600,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600, // u2563\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x0000,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2564\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600, // u2565\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x0000,0xf7c0,0xf7c0,0x3600,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600, // u2566\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xffc0,0x0000,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2567\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2568\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0xf7c0,0xf7c0,0x0000,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2569\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xffc0,0x0c00,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u256a\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0xffc0,0xffc0,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600, // u256b\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0xf7c0,0xf7c0,0x0000,0xf7c0,0xf7c0,0x3600,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600, // u256c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x03c0,0x0700,0x0e00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u256d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xe000,0xf000,0x3800,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u256e\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1c00,0x3800,0xf000,0xe000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u256f\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0e00,0x0700,0x03c0,0x01c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2570\n  0x0040,0x00c0,0x0080,0x0180,0x0100,0x0300,0x0200,0x0600,0x0400,0x0c00,0x0800,0x1800,0x1000,0x3000,0x2000,0x6000,\n  0x4000,0xc000, // u2571\n  0xc000,0x4000,0x6000,0x2000,0x3000,0x1000,0x1800,0x0800,0x0c00,0x0400,0x0600,0x0200,0x0300,0x0100,0x0180,0x0080,\n  0x00c0,0x0040, // u2572\n  0xc040,0x40c0,0x6080,0x2180,0x3100,0x1300,0x1a00,0x0e00,0x0c00,0x0c00,0x0e00,0x1a00,0x1300,0x3100,0x2180,0x6080,\n  0x40c0,0xc040, // u2573\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2574\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2575\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2576\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u2577\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2578\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2579\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u257a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u257b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u257c\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00, // u257d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u257e\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00, // u257f\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2580\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0xffc0,0xffc0, // u2581\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0, // u2582\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0, // u2583\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0, // u2584\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0, // u2585\n  0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0, // u2586\n  0x0000,0x0000,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0, // u2587\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0, // u2588\n  0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,\n  0xff80,0xff80, // u2589\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,\n  0xff00,0xff00, // u258a\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,\n  0xfc00,0xfc00, // u258b\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800, // u258c\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,\n  0xf000,0xf000, // u258d\n  0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,\n  0xe000,0xe000, // u258e\n  0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,\n  0x8000,0x8000, // u258f\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,\n  0x07c0,0x07c0, // u2590\n  0xaa80,0x0000,0xaa80,0x0000,0xaa80,0x0000,0xaa80,0x0000,0xaa80,0x0000,0xaa80,0x0000,0xaa80,0x0000,0xaa80,0x0000,\n  0xaa80,0x0000, // u2591\n  0xaa80,0x5540,0xaa80,0x5540,0xaa80,0x5540,0xaa80,0x5540,0xaa80,0x5540,0xaa80,0x5540,0xaa80,0x5540,0xaa80,0x5540,\n  0xaa80,0x5540, // u2592\n  0xffc0,0xaa80,0xffc0,0xaa80,0xffc0,0xaa80,0xffc0,0xaa80,0xffc0,0xaa80,0xffc0,0xaa80,0xffc0,0xaa80,0xffc0,0xaa80,\n  0xffc0,0xaa80, // u2593\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800, // u2596\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,\n  0x07c0,0x07c0, // u2597\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2598\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0, // u2599\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,\n  0x07c0,0x07c0, // u259a\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800, // u259b\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,\n  0x07c0,0x07c0, // u259c\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u259d\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800, // u259e\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0, // u259f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x3f00,0x3f00,0x3f00,0x3f00,0x3f00,0x3f00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u25a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,0xff80,0xff80,0xff80,0xff80,0x0000,\n  0x0000,0x0000, // u25ac\n  0x0000,0x0000,0x0000,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,0x0000,\n  0x0000,0x0000, // u25ae\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x1e00,0x1e00,0x3f00,0x3f00,0x7f80,0x7f80,0xffc0,0xffc0,0x0000,0x0000,\n  0x0000,0x0000, // u25b2\n  0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xffc0,0xffc0,0xff00,0xfc00,0xf000,0xc000,0x0000,0x0000,\n  0x0000,0x0000, // u25b6\n  0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xffc0,0xffc0,0xff00,0xfc00,0xf000,0xc000,0x0000,0x0000,\n  0x0000,0x0000, // u25ba\n  0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x7f80,0x7f80,0x3f00,0x3f00,0x1e00,0x1e00,0x0c00,0x0c00,0x0000,0x0000,\n  0x0000,0x0000, // u25bc\n  0x0000,0x0000,0x0000,0x0000,0x00c0,0x03c0,0x0fc0,0x3fc0,0xffc0,0xffc0,0x3fc0,0x0fc0,0x03c0,0x00c0,0x0000,0x0000,\n  0x0000,0x0000, // u25c0\n  0x0000,0x0000,0x0000,0x0000,0x00c0,0x03c0,0x0fc0,0x3fc0,0xffc0,0xffc0,0x3fc0,0x0fc0,0x03c0,0x00c0,0x0000,0x0000,\n  0x0000,0x0000, // u25c4\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x1e00,0x3f00,0x7f80,0xffc0,0xffc0,0x7f80,0x3f00,0x1e00,0x0c00,0x0000,0x0000,\n  0x0000,0x0000, // u25c6\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x1e00,0x3300,0x6180,0xc0c0,0xc0c0,0x6180,0x3300,0x1e00,0x0c00,0x0000,0x0000,\n  0x0000,0x0000, // u25ca\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x2100,0x2100,0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u25cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3f00,0x3f00,0x3f00,0x3f00,0x1e00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u25cf\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xf3c0,0xe1c0,0xe1c0,0xf3c0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0, // u25d8\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xe1c0,0xccc0,0xdec0,0xdec0,0xccc0,0xe1c0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0, // u25d9\n  0x0000,0x0000,0x0000,0x7f80,0x8040,0x8040,0xb340,0xb340,0x8040,0x8040,0xbf40,0x9e40,0x8040,0x8040,0x7f80,0x0000,\n  0x0000,0x0000, // u263a\n  0x0000,0x0000,0x0000,0x7f80,0xffc0,0xffc0,0xccc0,0xccc0,0xffc0,0xffc0,0xc0c0,0xe1c0,0xffc0,0xffc0,0x7f80,0x0000,\n  0x0000,0x0000, // u263b\n  0x0000,0x0000,0x0000,0x0c00,0xccc0,0x6d80,0x3f00,0x1e00,0xf3c0,0x1e00,0x3f00,0x6d80,0xccc0,0x0c00,0x0000,0x0000,\n  0x0000,0x0000, // u263c\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000, // u2640\n  0x0000,0x0000,0x0000,0x0f80,0x0380,0x0680,0x0c80,0x3e00,0x6300,0x6300,0x6300,0x6300,0x6300,0x6300,0x3e00,0x0000,\n  0x0000,0x0000, // u2642\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x1e00,0x3f00,0x7f80,0xffc0,0xffc0,0xffc0,0x6d80,0x0c00,0x0c00,0x3f00,0x0000,\n  0x0000,0x0000, // u2660\n  0x0000,0x0000,0x0000,0x1e00,0x3f00,0x3f00,0x1e00,0x0c00,0x6d80,0xffc0,0xffc0,0xffc0,0x6d80,0x0c00,0x3f00,0x0000,\n  0x0000,0x0000, // u2663\n  0x0000,0x0000,0x0000,0x0000,0x7380,0xf3c0,0xffc0,0xffc0,0xffc0,0xffc0,0x7f80,0x3f00,0x1e00,0x0c00,0x0000,0x0000,\n  0x0000,0x0000, // u2665\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x1e00,0x3f00,0x7f80,0xffc0,0xffc0,0x7f80,0x3f00,0x1e00,0x0c00,0x0000,0x0000,\n  0x0000,0x0000, // u2666\n  0x0000,0x0000,0x0000,0x3f80,0x3180,0x3180,0x3f80,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0xf000,0xe000,0x0000,\n  0x0000,0x0000, // u266a\n  0x0000,0x0000,0x0000,0x7f80,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6380,0xe300,0xc000,0x0000,\n  0x0000,0x0000, // u266b\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x0180,0x0180,0xc300,0xc300,0x6600,0x6600,0x3c00,0x3c00,0x1800,0x1800,0x0000,\n  0x0000,0x0000, // u2713\n  0x0000,0x0000,0x0000,0x01c0,0x01c0,0x0380,0x0380,0xe700,0xe700,0x7e00,0x7e00,0x3c00,0x3c00,0x1800,0x1800,0x0000,\n  0x0000,0x0000, // u2714\n  0x0000,0x0000,0x0000,0x0300,0x6300,0x3600,0x1e00,0x0c00,0x0e00,0x1b00,0x1980,0x3000,0x3000,0x6000,0x6000,0x0000,\n  0x0000,0x0000, // u2717\n  0x0000,0x0000,0x0000,0x0700,0xe700,0x7e00,0x3e00,0x1c00,0x1e00,0x3f00,0x3b80,0x7180,0x7000,0xe000,0xe000,0x0000,\n  0x0000,0x0000, // u2718\n  0x0000,0x0000,0x0600,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x1800,0x1800,0x0c00,0x0c00,0x0600,0x0600,0x0000,\n  0x0000,0x0000, // u27e8\n  0x0000,0x0000,0x3000,0x3000,0x1800,0x1800,0x0c00,0x0c00,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x0000,\n  0x0000,0x0000, // u27e9\n  0x0000,0x0000,0x1980,0x1980,0x3300,0x3300,0x6600,0x6600,0xcc00,0x6600,0x6600,0x3300,0x3300,0x1980,0x1980,0x0000,\n  0x0000,0x0000, // u27ea\n  0x0000,0x0000,0xcc00,0xcc00,0x6600,0x6600,0x3300,0x3300,0x1980,0x3300,0x3300,0x6600,0x6600,0xcc00,0xcc00,0x0000,\n  0x0000,0x0000, // u27eb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2800\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2801\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2802\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2803\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2804\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2805\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2806\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2807\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2808\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2809\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u280a\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u280b\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u280c\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u280d\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u280e\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u280f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2810\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2811\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2812\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2813\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2814\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2815\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2816\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2817\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2818\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2819\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u281a\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u281b\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u281c\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u281d\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u281e\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u281f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2820\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2821\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2822\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2823\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2824\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2825\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2826\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2827\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2828\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2829\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u282a\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u282b\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u282c\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u282d\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u282e\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u282f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2830\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2831\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2832\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2833\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2834\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2835\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2836\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2837\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2838\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u2839\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u283a\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u283b\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u283c\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u283d\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u283e\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000, // u283f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2840\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2841\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2842\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2843\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2844\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2845\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2846\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2847\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2848\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2849\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u284a\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u284b\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u284c\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u284d\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u284e\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u284f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2850\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2851\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2852\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2853\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2854\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2855\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2856\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2857\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2858\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2859\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u285a\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u285b\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u285c\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u285d\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u285e\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u285f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2860\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2861\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2862\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2863\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2864\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2865\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2866\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2867\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2868\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2869\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u286a\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u286b\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u286c\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u286d\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u286e\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u286f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2870\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2871\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2872\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2873\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2874\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2875\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2876\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2877\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2878\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u2879\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u287a\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u287b\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u287c\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u287d\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u287e\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,\n  0x0000,0x0000, // u287f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u2880\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u2881\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u2882\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u2883\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u2884\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u2885\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u2886\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u2887\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u2888\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u2889\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u288a\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u288b\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u288c\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u288d\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u288e\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u288f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u2890\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u2891\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u2892\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u2893\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u2894\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u2895\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u2896\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u2897\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u2898\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u2899\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u289a\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u289b\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u289c\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u289d\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u289e\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u289f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28a0\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28a2\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28a4\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28a5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28a6\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28a7\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28a8\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28a9\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28aa\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28ab\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28ac\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28ad\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28ae\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28af\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28b0\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28b1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28b2\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28b4\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28b6\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28b7\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28b8\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28b9\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28ba\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28bb\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28bc\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28bd\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28be\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,\n  0x0000,0x0000, // u28bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28c0\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28c2\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28c4\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28c6\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28c7\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28c8\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28c9\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28ca\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28cb\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28cc\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28cd\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28ce\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28cf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28d0\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28d2\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28d4\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28d6\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28d7\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28d8\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28d9\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28da\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28db\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28dc\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28dd\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28de\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28df\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28e0\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28e1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28e2\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28e3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28e4\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28e6\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28e7\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28e8\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28e9\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28ea\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28eb\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28ec\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28ed\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28ee\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28ef\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28f0\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28f2\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28f3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28f4\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28f6\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28f7\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28f8\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28f9\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28fa\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28fb\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28fc\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28fd\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28fe\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x6300,0x6300,\n  0x0000,0x0000, // u28ff\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x0000,0x0000,\n  0x0000,0x0000, // u2e2c\n  0xc000,0xc000,0xc600,0xcf00,0xdf80,0xf6c0,0xc600,0xc600,0xc600,0x8c00,0x1800,0x3000,0x6000,0xc000,0xc000,0xc000,\n  0xc000,0xc000, // ue0a0\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xc000,0xc000,0xfc00,0x0000,0x1980,0x1d80,0x1f80,0x1b80,0x1980,0x1980,0x0000,\n  0x0000,0x0000, // ue0a1\n  0x0000,0x0000,0x3e00,0x6300,0x6300,0x6300,0x6300,0x6300,0xff80,0xff80,0xf780,0xe380,0xe380,0xf780,0xff80,0xff80,\n  0x0000,0x0000, // ue0a2\n  0x8000,0xc000,0xe000,0xf000,0xf800,0xfc00,0xfe00,0xff00,0xff80,0xff80,0xff00,0xfe00,0xfc00,0xf800,0xf000,0xe000,\n  0xc000,0x8000, // ue0b0\n  0x8000,0xc000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,\n  0xc000,0x8000, // ue0b1\n  0x0040,0x00c0,0x01c0,0x03c0,0x07c0,0x0fc0,0x1fc0,0x3fc0,0x7fc0,0x7fc0,0x3fc0,0x1fc0,0x0fc0,0x07c0,0x03c0,0x01c0,\n  0x00c0,0x0040, // ue0b2\n  0x0040,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,\n  0x00c0,0x0040, // ue0b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x3300,\n  0x3300,0x1e00, // uf6be\n  0x0000,0x0000,0x0000,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x0000,\n  0x0000,0x0000 // ufffd\n  };\n  // codepoints array\n  constexpr std::array<uint16_t, CHARCOUNT> fixedfont_codepoints = {\n  0x0000,0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,\n  0x002f,0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,\n  0x003f,0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,\n  0x004f,0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,\n  0x005f,0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,\n  0x006f,0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,\n  0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af,\n  0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf,\n  0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf,\n  0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df,\n  0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef,\n  0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff,\n  0x0100,0x0101,0x0102,0x0103,0x0104,0x0105,0x0106,0x0107,0x0108,0x0109,0x010a,0x010b,0x010c,0x010d,0x010e,0x010f,\n  0x0110,0x0111,0x0112,0x0113,0x0114,0x0115,0x0116,0x0117,0x0118,0x0119,0x011a,0x011b,0x011c,0x011d,0x011e,0x011f,\n  0x0120,0x0121,0x0122,0x0123,0x0124,0x0125,0x0126,0x0127,0x0128,0x0129,0x012a,0x012b,0x012c,0x012d,0x012e,0x012f,\n  0x0130,0x0131,0x0132,0x0133,0x0134,0x0135,0x0136,0x0137,0x0138,0x0139,0x013a,0x013b,0x013c,0x013d,0x013e,0x013f,\n  0x0140,0x0141,0x0142,0x0143,0x0144,0x0145,0x0146,0x0147,0x0148,0x0149,0x014a,0x014b,0x014c,0x014d,0x014e,0x014f,\n  0x0150,0x0151,0x0152,0x0153,0x0154,0x0155,0x0156,0x0157,0x0158,0x0159,0x015a,0x015b,0x015c,0x015d,0x015e,0x015f,\n  0x0160,0x0161,0x0162,0x0163,0x0164,0x0165,0x0166,0x0167,0x0168,0x0169,0x016a,0x016b,0x016c,0x016d,0x016e,0x016f,\n  0x0170,0x0171,0x0172,0x0173,0x0174,0x0175,0x0176,0x0177,0x0178,0x0179,0x017a,0x017b,0x017c,0x017d,0x017e,0x017f,\n  0x0186,0x018e,0x018f,0x0190,0x0192,0x019d,0x019e,0x01b5,0x01b6,0x01b7,0x01cd,0x01ce,0x01cf,0x01d0,0x01d1,0x01d2,\n  0x01d3,0x01d4,0x01e2,0x01e3,0x01e4,0x01e5,0x01e6,0x01e7,0x01e8,0x01e9,0x01ea,0x01eb,0x01ec,0x01ed,0x01ee,0x01ef,\n  0x01f0,0x01f4,0x01f5,0x01fc,0x01fd,0x01fe,0x01ff,0x0218,0x0219,0x021a,0x021b,0x0232,0x0233,0x0237,0x0254,0x0258,\n  0x0259,0x025b,0x0272,0x0292,0x02bb,0x02bc,0x02bd,0x02c6,0x02c7,0x02d8,0x02d9,0x02db,0x02dc,0x02dd,0x0300,0x0301,\n  0x0302,0x0303,0x0304,0x0305,0x0306,0x0307,0x0308,0x030a,0x030b,0x030c,0x0329,0x0384,0x0385,0x0386,0x0387,0x0388,\n  0x0389,0x038a,0x038c,0x038e,0x038f,0x0390,0x0391,0x0392,0x0393,0x0394,0x0395,0x0396,0x0397,0x0398,0x0399,0x039a,\n  0x039b,0x039c,0x039d,0x039e,0x039f,0x03a0,0x03a1,0x03a3,0x03a4,0x03a5,0x03a6,0x03a7,0x03a8,0x03a9,0x03aa,0x03ab,\n  0x03ac,0x03ad,0x03ae,0x03af,0x03b0,0x03b1,0x03b2,0x03b3,0x03b4,0x03b5,0x03b6,0x03b7,0x03b8,0x03b9,0x03ba,0x03bb,\n  0x03bc,0x03bd,0x03be,0x03bf,0x03c0,0x03c1,0x03c2,0x03c3,0x03c4,0x03c5,0x03c6,0x03c7,0x03c8,0x03c9,0x03ca,0x03cb,\n  0x03cc,0x03cd,0x03ce,0x03d1,0x03d5,0x03f0,0x03f1,0x03f2,0x03f3,0x03f4,0x03f5,0x03f6,0x0400,0x0401,0x0402,0x0403,\n  0x0404,0x0405,0x0406,0x0407,0x0408,0x0409,0x040a,0x040b,0x040c,0x040d,0x040e,0x040f,0x0410,0x0411,0x0412,0x0413,\n  0x0414,0x0415,0x0416,0x0417,0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e,0x041f,0x0420,0x0421,0x0422,0x0423,\n  0x0424,0x0425,0x0426,0x0427,0x0428,0x0429,0x042a,0x042b,0x042c,0x042d,0x042e,0x042f,0x0430,0x0431,0x0432,0x0433,\n  0x0434,0x0435,0x0436,0x0437,0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e,0x043f,0x0440,0x0441,0x0442,0x0443,\n  0x0444,0x0445,0x0446,0x0447,0x0448,0x0449,0x044a,0x044b,0x044c,0x044d,0x044e,0x044f,0x0450,0x0451,0x0452,0x0453,\n  0x0454,0x0455,0x0456,0x0457,0x0458,0x0459,0x045a,0x045b,0x045c,0x045d,0x045e,0x045f,0x0462,0x0463,0x046a,0x046b,\n  0x0490,0x0491,0x0492,0x0493,0x0494,0x0495,0x0496,0x0497,0x0498,0x0499,0x049a,0x049b,0x049c,0x049d,0x04a0,0x04a1,\n  0x04a2,0x04a3,0x04a4,0x04a5,0x04aa,0x04ab,0x04ae,0x04af,0x04b0,0x04b1,0x04b2,0x04b3,0x04b6,0x04b7,0x04b8,0x04b9,\n  0x04ba,0x04bb,0x04c0,0x04c1,0x04c2,0x04cf,0x04d0,0x04d1,0x04d2,0x04d3,0x04d4,0x04d5,0x04d6,0x04d7,0x04d8,0x04d9,\n  0x04da,0x04db,0x04dc,0x04dd,0x04de,0x04df,0x04e2,0x04e3,0x04e4,0x04e5,0x04e6,0x04e7,0x04e8,0x04e9,0x04ea,0x04eb,\n  0x04ec,0x04ed,0x04ee,0x04ef,0x04f0,0x04f1,0x04f2,0x04f3,0x04f4,0x04f5,0x04f8,0x04f9,0x05d0,0x05d1,0x05d2,0x05d3,\n  0x05d4,0x05d5,0x05d6,0x05d7,0x05d8,0x05d9,0x05da,0x05db,0x05dc,0x05dd,0x05de,0x05df,0x05e0,0x05e1,0x05e2,0x05e3,\n  0x05e4,0x05e5,0x05e6,0x05e7,0x05e8,0x05e9,0x05ea,0x1e0c,0x1e0d,0x1e34,0x1e35,0x1e36,0x1e37,0x1e40,0x1e41,0x1e42,\n  0x1e43,0x1e44,0x1e45,0x1e46,0x1e47,0x1e6c,0x1e6d,0x1eb8,0x1eb9,0x1ebc,0x1ebd,0x1eca,0x1ecb,0x1ecc,0x1ecd,0x1ee4,\n  0x1ee5,0x1ef8,0x1ef9,0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007,0x2008,0x2009,0x200a,0x200b,0x200c,\n  0x200d,0x200e,0x200f,0x2010,0x2011,0x2012,0x2013,0x2014,0x2015,0x2016,0x2017,0x2018,0x2019,0x201a,0x201b,0x201c,\n  0x201d,0x201e,0x201f,0x2020,0x2021,0x2022,0x2026,0x2030,0x2032,0x2033,0x2039,0x203a,0x203c,0x203e,0x2070,0x2071,\n  0x2074,0x2075,0x2076,0x2077,0x2078,0x2079,0x207a,0x207b,0x207c,0x207d,0x207e,0x207f,0x2080,0x2081,0x2082,0x2083,\n  0x2084,0x2085,0x2086,0x2087,0x2088,0x2089,0x208a,0x208b,0x208c,0x208d,0x208e,0x2090,0x2091,0x2092,0x2093,0x2094,\n  0x2095,0x2096,0x2097,0x2098,0x209a,0x20a7,0x20aa,0x20ac,0x20ae,0x2102,0x210e,0x210f,0x2115,0x2116,0x211a,0x211d,\n  0x2122,0x2124,0x2126,0x2135,0x2190,0x2191,0x2192,0x2193,0x2194,0x2195,0x21a4,0x21a6,0x21a8,0x21b5,0x21bb,0x21cb,\n  0x21cc,0x21d0,0x21d1,0x21d2,0x21d3,0x21d4,0x21d5,0x2200,0x2203,0x2204,0x2205,0x2206,0x2207,0x2208,0x2209,0x220a,\n  0x220b,0x220c,0x220d,0x2212,0x2213,0x2214,0x2215,0x2216,0x2219,0x221a,0x221e,0x221f,0x2225,0x2227,0x2228,0x2229,\n  0x222a,0x2248,0x2260,0x2261,0x2264,0x2265,0x226a,0x226b,0x2282,0x2283,0x2286,0x2287,0x22a5,0x22c2,0x22c3,0x2300,\n  0x2302,0x2308,0x2309,0x230a,0x230b,0x2310,0x2319,0x2320,0x2321,0x239b,0x239c,0x239d,0x239e,0x239f,0x23a0,0x23a1,\n  0x23a2,0x23a3,0x23a4,0x23a5,0x23a6,0x23a7,0x23a8,0x23a9,0x23ab,0x23ac,0x23ad,0x23ae,0x23af,0x23ba,0x23bb,0x23bc,\n  0x23bd,0x23d0,0x2409,0x240a,0x240b,0x240c,0x240d,0x2424,0x2500,0x2501,0x2502,0x2503,0x2508,0x2509,0x250a,0x250b,\n  0x250c,0x250d,0x250e,0x250f,0x2510,0x2511,0x2512,0x2513,0x2514,0x2515,0x2516,0x2517,0x2518,0x2519,0x251a,0x251b,\n  0x251c,0x251d,0x251e,0x251f,0x2520,0x2521,0x2522,0x2523,0x2524,0x2525,0x2526,0x2527,0x2528,0x2529,0x252a,0x252b,\n  0x252c,0x252d,0x252e,0x252f,0x2530,0x2531,0x2532,0x2533,0x2534,0x2535,0x2536,0x2537,0x2538,0x2539,0x253a,0x253b,\n  0x253c,0x253d,0x253e,0x253f,0x2540,0x2541,0x2542,0x2543,0x2544,0x2545,0x2546,0x2547,0x2548,0x2549,0x254a,0x254b,\n  0x2550,0x2551,0x2552,0x2553,0x2554,0x2555,0x2556,0x2557,0x2558,0x2559,0x255a,0x255b,0x255c,0x255d,0x255e,0x255f,\n  0x2560,0x2561,0x2562,0x2563,0x2564,0x2565,0x2566,0x2567,0x2568,0x2569,0x256a,0x256b,0x256c,0x256d,0x256e,0x256f,\n  0x2570,0x2571,0x2572,0x2573,0x2574,0x2575,0x2576,0x2577,0x2578,0x2579,0x257a,0x257b,0x257c,0x257d,0x257e,0x257f,\n  0x2580,0x2581,0x2582,0x2583,0x2584,0x2585,0x2586,0x2587,0x2588,0x2589,0x258a,0x258b,0x258c,0x258d,0x258e,0x258f,\n  0x2590,0x2591,0x2592,0x2593,0x2596,0x2597,0x2598,0x2599,0x259a,0x259b,0x259c,0x259d,0x259e,0x259f,0x25a0,0x25ac,\n  0x25ae,0x25b2,0x25b6,0x25ba,0x25bc,0x25c0,0x25c4,0x25c6,0x25ca,0x25cb,0x25cf,0x25d8,0x25d9,0x263a,0x263b,0x263c,\n  0x2640,0x2642,0x2660,0x2663,0x2665,0x2666,0x266a,0x266b,0x2713,0x2714,0x2717,0x2718,0x27e8,0x27e9,0x27ea,0x27eb,\n  0x2800,0x2801,0x2802,0x2803,0x2804,0x2805,0x2806,0x2807,0x2808,0x2809,0x280a,0x280b,0x280c,0x280d,0x280e,0x280f,\n  0x2810,0x2811,0x2812,0x2813,0x2814,0x2815,0x2816,0x2817,0x2818,0x2819,0x281a,0x281b,0x281c,0x281d,0x281e,0x281f,\n  0x2820,0x2821,0x2822,0x2823,0x2824,0x2825,0x2826,0x2827,0x2828,0x2829,0x282a,0x282b,0x282c,0x282d,0x282e,0x282f,\n  0x2830,0x2831,0x2832,0x2833,0x2834,0x2835,0x2836,0x2837,0x2838,0x2839,0x283a,0x283b,0x283c,0x283d,0x283e,0x283f,\n  0x2840,0x2841,0x2842,0x2843,0x2844,0x2845,0x2846,0x2847,0x2848,0x2849,0x284a,0x284b,0x284c,0x284d,0x284e,0x284f,\n  0x2850,0x2851,0x2852,0x2853,0x2854,0x2855,0x2856,0x2857,0x2858,0x2859,0x285a,0x285b,0x285c,0x285d,0x285e,0x285f,\n  0x2860,0x2861,0x2862,0x2863,0x2864,0x2865,0x2866,0x2867,0x2868,0x2869,0x286a,0x286b,0x286c,0x286d,0x286e,0x286f,\n  0x2870,0x2871,0x2872,0x2873,0x2874,0x2875,0x2876,0x2877,0x2878,0x2879,0x287a,0x287b,0x287c,0x287d,0x287e,0x287f,\n  0x2880,0x2881,0x2882,0x2883,0x2884,0x2885,0x2886,0x2887,0x2888,0x2889,0x288a,0x288b,0x288c,0x288d,0x288e,0x288f,\n  0x2890,0x2891,0x2892,0x2893,0x2894,0x2895,0x2896,0x2897,0x2898,0x2899,0x289a,0x289b,0x289c,0x289d,0x289e,0x289f,\n  0x28a0,0x28a1,0x28a2,0x28a3,0x28a4,0x28a5,0x28a6,0x28a7,0x28a8,0x28a9,0x28aa,0x28ab,0x28ac,0x28ad,0x28ae,0x28af,\n  0x28b0,0x28b1,0x28b2,0x28b3,0x28b4,0x28b5,0x28b6,0x28b7,0x28b8,0x28b9,0x28ba,0x28bb,0x28bc,0x28bd,0x28be,0x28bf,\n  0x28c0,0x28c1,0x28c2,0x28c3,0x28c4,0x28c5,0x28c6,0x28c7,0x28c8,0x28c9,0x28ca,0x28cb,0x28cc,0x28cd,0x28ce,0x28cf,\n  0x28d0,0x28d1,0x28d2,0x28d3,0x28d4,0x28d5,0x28d6,0x28d7,0x28d8,0x28d9,0x28da,0x28db,0x28dc,0x28dd,0x28de,0x28df,\n  0x28e0,0x28e1,0x28e2,0x28e3,0x28e4,0x28e5,0x28e6,0x28e7,0x28e8,0x28e9,0x28ea,0x28eb,0x28ec,0x28ed,0x28ee,0x28ef,\n  0x28f0,0x28f1,0x28f2,0x28f3,0x28f4,0x28f5,0x28f6,0x28f7,0x28f8,0x28f9,0x28fa,0x28fb,0x28fc,0x28fd,0x28fe,0x28ff,\n  0x2e2c,0xe0a0,0xe0a1,0xe0a2,0xe0b0,0xe0b1,0xe0b2,0xe0b3,0xf6be,0xfffd };\n} // namespace\n// -- end of autogenerated text ---\n\nnamespace fixed_font_20n {\n  // -- start of autogenerated text ---\n  // definition section for font: ter-u20n.bdf\n  constexpr int CHARCOUNT = 1354;\n  constexpr int WIDTH = 10;\n  constexpr int HEIGHT = 20;\n  constexpr int OFFSET_X = 0;\n  constexpr int OFFSET_Y = 0;\n  constexpr FixedFont_info_t fixedfont_info = {\n    \"Terminus\", // font name\n    \"ter-u20n.bdf\", // font name internal\n    CHARCOUNT, // num of chars\n    WIDTH, HEIGHT, OFFSET_X, OFFSET_Y,\n    false // bold\n  };\n  // font bitmap definitions\n  constexpr std::array<uint16_t, CHARCOUNT * HEIGHT> fixedfont_bitmap = {\n  0x0000,0x0000,0x0000,0x6300,0x4100,0x4100,0x0000,0x0000,0x4100,0x4100,0x4100,0x0000,0x0000,0x4100,0x4100,0x6300,\n  0x0000,0x0000,0x0000,0x0000, // u0000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0020\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,0x0000,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u0021\n  0x0000,0x2200,0x2200,0x2200,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0022\n  0x0000,0x0000,0x0000,0x2200,0x2200,0x2200,0x2200,0x7f00,0x2200,0x2200,0x2200,0x7f00,0x2200,0x2200,0x2200,0x2200,\n  0x0000,0x0000,0x0000,0x0000, // u0023\n  0x0000,0x0000,0x0800,0x0800,0x3e00,0x4900,0x4800,0x4800,0x4800,0x3e00,0x0900,0x0900,0x0900,0x4900,0x3e00,0x0800,\n  0x0800,0x0000,0x0000,0x0000, // u0024\n  0x0000,0x0000,0x0000,0x0000,0x7100,0x5100,0x7200,0x0200,0x0400,0x0400,0x0800,0x0800,0x1000,0x1380,0x2280,0x2380,\n  0x0000,0x0000,0x0000,0x0000, // u0025\n  0x0000,0x0000,0x0000,0x1c00,0x2200,0x2200,0x2200,0x1400,0x0800,0x1480,0x2280,0x4100,0x4100,0x4100,0x2280,0x1c80,\n  0x0000,0x0000,0x0000,0x0000, // u0026\n  0x0000,0x0800,0x0800,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0027\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0800,0x0800,0x0400,\n  0x0000,0x0000,0x0000,0x0000, // u0028\n  0x0000,0x0000,0x0000,0x1000,0x0800,0x0800,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0800,0x0800,0x1000,\n  0x0000,0x0000,0x0000,0x0000, // u0029\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2200,0x1400,0x0800,0x7f00,0x0800,0x1400,0x2200,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u002a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x7f00,0x0800,0x0800,0x0800,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u002b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,\n  0x1000,0x0000,0x0000,0x0000, // u002c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u002d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u002e\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0200,0x0200,0x0400,0x0400,0x0800,0x0800,0x1000,0x1000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0000, // u002f\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4300,0x4500,0x4900,0x5100,0x6100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0030\n  0x0000,0x0000,0x0000,0x0800,0x1800,0x2800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0031\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x0100,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u0032\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x0100,0x0100,0x0100,0x1e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0033\n  0x0000,0x0000,0x0000,0x0100,0x0300,0x0500,0x0900,0x1100,0x2100,0x4100,0x4100,0x4100,0x7f00,0x0100,0x0100,0x0100,\n  0x0000,0x0000,0x0000,0x0000, // u0034\n  0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0100,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0035\n  0x0000,0x0000,0x0000,0x1e00,0x2000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0036\n  0x0000,0x0000,0x0000,0x7f00,0x4100,0x4100,0x0100,0x0200,0x0200,0x0400,0x0400,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u0037\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0038\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,0x0100,0x0100,0x0200,0x3c00,\n  0x0000,0x0000,0x0000,0x0000, // u0039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u003a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,\n  0x1000,0x0000,0x0000,0x0000, // u003b\n  0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,\n  0x0000,0x0000,0x0000,0x0000, // u003c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0000,0x0000,0x0000,0x7f00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u003d\n  0x0000,0x0000,0x0000,0x4000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,\n  0x0000,0x0000,0x0000,0x0000, // u003e\n  0x0000,0x0000,0x0000,0x1c00,0x2200,0x4100,0x4100,0x0100,0x0200,0x0400,0x0800,0x0800,0x0000,0x0000,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u003f\n  0x0000,0x0000,0x0000,0x3f00,0x4080,0x4080,0x4780,0x4880,0x4880,0x4880,0x4880,0x4980,0x4680,0x4000,0x4000,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u0040\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0041\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,\n  0x0000,0x0000,0x0000,0x0000, // u0042\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0043\n  0x0000,0x0000,0x0000,0x7c00,0x4200,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4200,0x7c00,\n  0x0000,0x0000,0x0000,0x0000, // u0044\n  0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u0045\n  0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x0000,0x0000,0x0000,0x0000, // u0046\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0047\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0048\n  0x0000,0x0000,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u0049\n  0x0000,0x0000,0x0000,0x0380,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x2100,0x2100,0x2100,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u004a\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u004b\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u004c\n  0x0000,0x0000,0x0000,0x4080,0x6180,0x5280,0x5280,0x4c80,0x4c80,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x0000,0x0000,0x0000,0x0000, // u004d\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x6100,0x5100,0x4900,0x4500,0x4300,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u004e\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u004f\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x0000,0x0000,0x0000,0x0000, // u0050\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4900,0x3e00,\n  0x0200,0x0100,0x0000,0x0000, // u0051\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0052\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x3e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0053\n  0x0000,0x0000,0x0000,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u0054\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0055\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x2200,0x2200,0x2200,0x2200,0x1400,0x1400,0x1400,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u0056\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4c80,0x4c80,0x5280,0x5280,0x6180,0x4080,\n  0x0000,0x0000,0x0000,0x0000, // u0057\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x1400,0x1400,0x2200,0x2200,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0058\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u0059\n  0x0000,0x0000,0x0000,0x7f00,0x0100,0x0100,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u005a\n  0x0000,0x0000,0x0000,0x1c00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u005b\n  0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x1000,0x1000,0x0800,0x0800,0x0400,0x0400,0x0200,0x0200,0x0100,0x0100,\n  0x0000,0x0000,0x0000,0x0000, // u005c\n  0x0000,0x0000,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u005d\n  0x0000,0x0800,0x1400,0x2200,0x4100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u005e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x7f00,0x0000,0x0000, // u005f\n  0x1000,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0060\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0061\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,\n  0x0000,0x0000,0x0000,0x0000, // u0062\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0063\n  0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0064\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0065\n  0x0000,0x0000,0x0000,0x0700,0x0800,0x0800,0x0800,0x3e00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u0066\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0100,0x0100,0x3e00,0x0000, // u0067\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0068\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u0069\n  0x0000,0x0000,0x0000,0x0200,0x0200,0x0000,0x0000,0x0600,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,\n  0x2200,0x2200,0x1c00,0x0000, // u006a\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4100,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u006b\n  0x0000,0x0000,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u006c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,\n  0x0000,0x0000,0x0000,0x0000, // u006d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u006e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u006f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,\n  0x4000,0x4000,0x4000,0x0000, // u0070\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0100,0x0100,0x0100,0x0000, // u0071\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4f00,0x5000,0x6000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x0000,0x0000,0x0000,0x0000, // u0072\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4000,0x4000,0x3e00,0x0100,0x0100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0073\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x3e00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0700,\n  0x0000,0x0000,0x0000,0x0000, // u0074\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0075\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u0076\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4900,0x4900,0x4900,0x4900,0x4900,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0077\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x1400,0x0800,0x1400,0x2200,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0078\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0100,0x0100,0x3e00,0x0000, // u0079\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u007a\n  0x0000,0x0000,0x0000,0x0600,0x0800,0x0800,0x0800,0x0800,0x0800,0x3000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0600,\n  0x0000,0x0000,0x0000,0x0000, // u007b\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u007c\n  0x0000,0x0000,0x0000,0x3000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0600,0x0800,0x0800,0x0800,0x0800,0x0800,0x3000,\n  0x0000,0x0000,0x0000,0x0000, // u007d\n  0x0000,0x3100,0x4900,0x4900,0x4600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u007e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00a0\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u00a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x3e00,0x4900,0x4800,0x4800,0x4800,0x4800,0x4800,0x4900,0x3e00,\n  0x0800,0x0800,0x0000,0x0000, // u00a2\n  0x0000,0x0000,0x0000,0x1c00,0x2200,0x2000,0x2000,0x2000,0x2000,0x7c00,0x2000,0x2000,0x2000,0x2000,0x2100,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u00a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x2100,0x1e00,0x2100,0x2100,0x2100,0x2100,0x1e00,0x2100,0x4080,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00a4\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,0x3e00,0x0800,0x3e00,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u00a5\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u00a6\n  0x0000,0x0000,0x1c00,0x2200,0x2000,0x2000,0x1800,0x2400,0x2200,0x2200,0x2200,0x1200,0x0c00,0x0200,0x0200,0x2200,\n  0x1c00,0x0000,0x0000,0x0000, // u00a7\n  0x2200,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00a8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x9c80,0xa280,0xa080,0xa080,0xa280,0x9c80,0x4100,0x3e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00a9\n  0x0000,0x1e00,0x0100,0x1f00,0x2100,0x2100,0x2100,0x1f00,0x0000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0880,0x1100,0x2200,0x4400,0x8800,0x4400,0x2200,0x1100,0x0880,\n  0x0000,0x0000,0x0000,0x0000, // u00ab\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0100,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00ac\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00ad\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0xbc80,0xa280,0xa280,0xbc80,0xa480,0xa280,0x4100,0x3e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00ae\n  0x0000,0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00af\n  0x0000,0x1c00,0x2200,0x2200,0x2200,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x7f00,0x0800,0x0800,0x0800,0x0000,0x0000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u00b1\n  0x0000,0x1c00,0x2200,0x2200,0x0400,0x0800,0x1000,0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00b2\n  0x0000,0x1c00,0x2200,0x0200,0x0c00,0x0200,0x2200,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00b3\n  0x0400,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4300,0x7d00,\n  0x4000,0x4000,0x4000,0x0000, // u00b5\n  0x0000,0x0000,0x0000,0x3f00,0x4900,0x4900,0x4900,0x4900,0x4900,0x3900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,\n  0x0000,0x0000,0x0000,0x0000, // u00b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00b7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0800,0x0800,0x1000,0x0000, // u00b8\n  0x0000,0x0800,0x1800,0x0800,0x0800,0x0800,0x0800,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00b9\n  0x0000,0x1e00,0x2100,0x2100,0x2100,0x2100,0x2100,0x1e00,0x0000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x8800,0x4400,0x2200,0x1100,0x0880,0x1100,0x2200,0x4400,0x8800,\n  0x0000,0x0000,0x0000,0x0000, // u00bb\n  0x0000,0x0000,0x1000,0x3000,0x1000,0x1080,0x1100,0x1200,0x0400,0x0800,0x1100,0x2300,0x4500,0x8900,0x0f00,0x0100,\n  0x0100,0x0000,0x0000,0x0000, // u00bc\n  0x0000,0x0000,0x1000,0x3000,0x1000,0x1080,0x1100,0x1200,0x0400,0x0800,0x1000,0x2600,0x4900,0x8100,0x0200,0x0400,\n  0x0f00,0x0000,0x0000,0x0000, // u00bd\n  0x0000,0x0000,0x7000,0x0800,0x3000,0x0880,0x0900,0x7200,0x0400,0x0800,0x1100,0x2300,0x4500,0x8900,0x0f00,0x0100,\n  0x0100,0x0000,0x0000,0x0000, // u00be\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0800,0x0800,0x1000,0x2000,0x4000,0x4100,0x4100,0x2200,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u00bf\n  0x1000,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u00c0\n  0x0400,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u00c1\n  0x1c00,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u00c2\n  0x3300,0x4c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u00c3\n  0x2200,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u00c4\n  0x1c00,0x2200,0x1c00,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u00c5\n  0x0000,0x0000,0x0000,0x7f80,0x8800,0x8800,0x8800,0x8800,0x8800,0xff00,0x8800,0x8800,0x8800,0x8800,0x8800,0x8f80,\n  0x0000,0x0000,0x0000,0x0000, // u00c6\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x4100,0x3e00,\n  0x0800,0x0800,0x1000,0x0000, // u00c7\n  0x1000,0x0800,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u00c8\n  0x0400,0x0800,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u00c9\n  0x1c00,0x2200,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u00ca\n  0x2200,0x2200,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u00cb\n  0x1000,0x0800,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u00cc\n  0x0400,0x0800,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u00cd\n  0x1c00,0x2200,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u00ce\n  0x2200,0x2200,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u00cf\n  0x0000,0x0000,0x0000,0x7c00,0x4200,0x4100,0x4100,0x4100,0x4100,0xf900,0x4100,0x4100,0x4100,0x4100,0x4200,0x7c00,\n  0x0000,0x0000,0x0000,0x0000, // u00d0\n  0x3300,0x4c00,0x0000,0x4100,0x4100,0x4100,0x4100,0x6100,0x5100,0x4900,0x4500,0x4300,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u00d1\n  0x1000,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u00d2\n  0x0400,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u00d3\n  0x1c00,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u00d4\n  0x3300,0x4c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u00d5\n  0x2200,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u00d6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x2200,0x1400,0x0800,0x1400,0x2200,0x4100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00d7\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4180,0x4100,0x4300,0x4500,0x4900,0x5100,0x6100,0x4100,0xc100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u00d8\n  0x1000,0x0800,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u00d9\n  0x0400,0x0800,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u00da\n  0x1c00,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u00db\n  0x2200,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u00dc\n  0x0400,0x0800,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u00dd\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x4000,0x4000,0x4000,\n  0x0000,0x0000,0x0000,0x0000, // u00de\n  0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4400,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x6100,0x5e00,\n  0x0000,0x0000,0x0000,0x0000, // u00df\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x0800,0x0000,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00e0\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00e1\n  0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x0000,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00e2\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x4c00,0x0000,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00e3\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00e4\n  0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x1c00,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7700,0x0880,0x0880,0x7880,0x8f80,0x8800,0x8800,0x8880,0x7700,\n  0x0000,0x0000,0x0000,0x0000, // u00e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x3e00,\n  0x0800,0x0800,0x1000,0x0000, // u00e7\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u00e8\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u00e9\n  0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u00ea\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u00eb\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x0800,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u00ec\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u00ed\n  0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u00ee\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u00ef\n  0x0000,0x0000,0x0000,0x2c00,0x1000,0x6800,0x0400,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u00f0\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x4c00,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u00f1\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u00f2\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u00f3\n  0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u00f4\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x4c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u00f5\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u00f6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x7f00,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00f7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e80,0x4100,0x4300,0x4500,0x4900,0x5100,0x6100,0x4100,0xbe00,\n  0x0000,0x0000,0x0000,0x0000, // u00f8\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x0800,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00f9\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00fa\n  0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00fb\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00fc\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0100,0x0100,0x3e00,0x0000, // u00fd\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,\n  0x4000,0x4000,0x4000,0x0000, // u00fe\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0100,0x0100,0x3e00,0x0000, // u00ff\n  0x0000,0x3e00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0100\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0101\n  0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0102\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0103\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0100,0x0200,0x0180,0x0000, // u0104\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0100,0x0200,0x0180,0x0000, // u0105\n  0x0400,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0106\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x3e00,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0107\n  0x1c00,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0108\n  0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x0000,0x3e00,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0109\n  0x0800,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u010a\n  0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x3e00,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u010b\n  0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u010c\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u010d\n  0x2200,0x1c00,0x0000,0x7c00,0x4200,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4200,0x7c00,\n  0x0000,0x0000,0x0000,0x0000, // u010e\n  0x2200,0x1c00,0x0000,0x0100,0x0100,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u010f\n  0x0000,0x0000,0x0000,0x7c00,0x4200,0x4100,0x4100,0x4100,0x4100,0xf900,0x4100,0x4100,0x4100,0x4100,0x4200,0x7c00,\n  0x0000,0x0000,0x0000,0x0000, // u0110\n  0x0000,0x0000,0x0000,0x0100,0x0f80,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0111\n  0x0000,0x3e00,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u0112\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0113\n  0x2200,0x1c00,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u0114\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0115\n  0x0800,0x0800,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u0116\n  0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0117\n  0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,\n  0x0100,0x0200,0x0180,0x0000, // u0118\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,\n  0x0800,0x1000,0x0c00,0x0000, // u0119\n  0x2200,0x1c00,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u011a\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u011b\n  0x1c00,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u011c\n  0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x0000,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0100,0x0100,0x3e00,0x0000, // u011d\n  0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u011e\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0100,0x0100,0x3e00,0x0000, // u011f\n  0x0800,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0120\n  0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0100,0x0100,0x3e00,0x0000, // u0121\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0800,0x0800,0x1000, // u0122\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0800,0x0000,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0100,0x0100,0x3e00,0x0000, // u0123\n  0x1c00,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0124\n  0x1c00,0x2200,0x0000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0125\n  0x0000,0x0000,0x0000,0x4100,0x4100,0xff80,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0126\n  0x0000,0x0000,0x0000,0x4000,0xf800,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0127\n  0x3300,0x4c00,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u0128\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x4c00,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u0129\n  0x0000,0x3e00,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u012a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u012b\n  0x2200,0x1c00,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u012c\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u012d\n  0x0000,0x0000,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0800,0x1000,0x0c00,0x0000, // u012e\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0800,0x1000,0x0c00,0x0000, // u012f\n  0x0800,0x0800,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u0130\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u0131\n  0x0000,0x0000,0x0000,0xe380,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4900,0x4900,0x4900,0xe600,\n  0x0000,0x0000,0x0000,0x0000, // u0132\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x0000,0x0000,0x6180,0x2080,0x2080,0x2080,0x2080,0x2080,0x2080,0x2080,0x7080,\n  0x0480,0x0480,0x0300,0x0000, // u0133\n  0x0700,0x0880,0x0000,0x0700,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x4200,0x4200,0x4200,0x3c00,\n  0x0000,0x0000,0x0000,0x0000, // u0134\n  0x0000,0x0000,0x0000,0x0000,0x0700,0x0880,0x0000,0x0600,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,\n  0x2200,0x2200,0x1c00,0x0000, // u0135\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,0x4100,\n  0x0000,0x0800,0x0800,0x1000, // u0136\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4100,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x4100,\n  0x0000,0x0800,0x0800,0x1000, // u0137\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0138\n  0x2000,0x4000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u0139\n  0x0400,0x0800,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u013a\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0800,0x0800,0x1000, // u013b\n  0x0000,0x0000,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0800,0x0800,0x1000, // u013c\n  0x2200,0x1c00,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u013d\n  0x2200,0x1c00,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u013e\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4200,0x4200,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u013f\n  0x0000,0x0000,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0840,0x0840,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u0140\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x2000,0x2800,0x3000,0x2000,0x6000,0xa000,0x2000,0x2000,0x2000,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u0141\n  0x0000,0x0000,0x0000,0x1800,0x0800,0x0800,0x0800,0x0a00,0x0c00,0x0800,0x1800,0x2800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u0142\n  0x0400,0x0800,0x0000,0x4100,0x4100,0x4100,0x4100,0x6100,0x5100,0x4900,0x4500,0x4300,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0143\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0144\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x6100,0x5100,0x4900,0x4500,0x4300,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0800,0x0800,0x1000, // u0145\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0800,0x0800,0x1000, // u0146\n  0x2200,0x1c00,0x0000,0x4100,0x4100,0x4100,0x4100,0x6100,0x5100,0x4900,0x4500,0x4300,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0147\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0148\n  0x0000,0x4000,0x4000,0x4000,0x8000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0149\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x6100,0x5100,0x4900,0x4500,0x4300,0x4100,0x4100,0x4100,0x4100,\n  0x0100,0x0100,0x0600,0x0000, // u014a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0100,0x0100,0x0600,0x0000, // u014b\n  0x0000,0x3e00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u014c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u014d\n  0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u014e\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u014f\n  0x1100,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0150\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0151\n  0x0000,0x0000,0x0000,0x7f80,0x8800,0x8800,0x8800,0x8800,0x8800,0x8f00,0x8800,0x8800,0x8800,0x8800,0x8800,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u0152\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x8880,0x8880,0x8880,0x8f80,0x8800,0x8800,0x8880,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u0153\n  0x0400,0x0800,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0154\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x4f00,0x5000,0x6000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x0000,0x0000,0x0000,0x0000, // u0155\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,\n  0x0000,0x0800,0x0800,0x1000, // u0156\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4f00,0x5000,0x6000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x0000,0x4000,0x4000,0x8000, // u0157\n  0x2200,0x1c00,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0158\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x4f00,0x5000,0x6000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x0000,0x0000,0x0000,0x0000, // u0159\n  0x0400,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x3e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u015a\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x3e00,0x4100,0x4000,0x4000,0x3e00,0x0100,0x0100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u015b\n  0x1c00,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x3e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u015c\n  0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x0000,0x3e00,0x4100,0x4000,0x4000,0x3e00,0x0100,0x0100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u015d\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x3e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,\n  0x0800,0x0800,0x1000,0x0000, // u015e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4000,0x4000,0x3e00,0x0100,0x0100,0x4100,0x3e00,\n  0x0800,0x0800,0x1000,0x0000, // u015f\n  0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x3e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0160\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4000,0x4000,0x3e00,0x0100,0x0100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0161\n  0x0000,0x0000,0x0000,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0400,0x0400,0x0800,0x0000, // u0162\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x3e00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0700,\n  0x0200,0x0200,0x0400,0x0000, // u0163\n  0x2200,0x1c00,0x0000,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u0164\n  0x2200,0x1c00,0x0000,0x0800,0x0800,0x0800,0x0800,0x3e00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0700,\n  0x0000,0x0000,0x0000,0x0000, // u0165\n  0x0000,0x0000,0x0000,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x3e00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u0166\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x3e00,0x0800,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0700,\n  0x0000,0x0000,0x0000,0x0000, // u0167\n  0x3300,0x4c00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0168\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x4c00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0169\n  0x0000,0x3e00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u016a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u016b\n  0x2200,0x1c00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u016c\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u016d\n  0x1c00,0x2200,0x1c00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u016e\n  0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x1c00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u016f\n  0x1100,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0170\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0171\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0800,0x1000,0x0c00,0x0000, // u0172\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0100,0x0200,0x0180,0x0000, // u0173\n  0x1c00,0x2200,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4c80,0x4c80,0x5280,0x5280,0x6180,0x4080,\n  0x0000,0x0000,0x0000,0x0000, // u0174\n  0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x0000,0x4100,0x4100,0x4100,0x4900,0x4900,0x4900,0x4900,0x4900,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0175\n  0x1c00,0x2200,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u0176\n  0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0100,0x0100,0x3e00,0x0000, // u0177\n  0x2200,0x2200,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u0178\n  0x0400,0x0800,0x0000,0x7f00,0x0100,0x0100,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u0179\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x7f00,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u017a\n  0x0800,0x0800,0x0000,0x7f00,0x0100,0x0100,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u017b\n  0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x7f00,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u017c\n  0x2200,0x1c00,0x0000,0x7f00,0x0100,0x0100,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u017d\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x7f00,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u017e\n  0x0000,0x0000,0x0000,0x0700,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u017f\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0186\n  0x0000,0x0000,0x0000,0x7f00,0x0100,0x0100,0x0100,0x0100,0x0100,0x1f00,0x0100,0x0100,0x0100,0x0100,0x0100,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u018e\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x0100,0x0100,0x0100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u018f\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x3c00,0x4000,0x4000,0x4000,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0190\n  0x0000,0x0000,0x0000,0x0600,0x0900,0x0900,0x0800,0x0800,0x3e00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x4800,0x4800,0x3000,0x0000, // u0192\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x6100,0x5100,0x4900,0x4500,0x4300,0x4100,0x4100,0x4100,0x4100,\n  0x4000,0x4000,0x8000,0x0000, // u019d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0100,0x0100,0x0100,0x0000, // u019e\n  0x0000,0x0000,0x0000,0x7f00,0x0100,0x0100,0x0100,0x0200,0x0400,0x7f00,0x0800,0x1000,0x2000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u01b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0100,0x0200,0x0400,0x7f00,0x1000,0x2000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u01b6\n  0x0000,0x0000,0x0000,0x7f00,0x0100,0x0200,0x0400,0x0800,0x1e00,0x0100,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u01b7\n  0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u01cd\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u01ce\n  0x2200,0x1c00,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u01cf\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u01d0\n  0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u01d1\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u01d2\n  0x2200,0x1c00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u01d3\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u01d4\n  0x0000,0x3f00,0x0000,0x7f80,0x8800,0x8800,0x8800,0x8800,0x8800,0xff00,0x8800,0x8800,0x8800,0x8800,0x8800,0x8f80,\n  0x0000,0x0000,0x0000,0x0000, // u01e2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x7700,0x0880,0x0880,0x7880,0x8f80,0x8800,0x8800,0x8880,0x7700,\n  0x0000,0x0000,0x0000,0x0000, // u01e3\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4f00,0x4100,0x4100,0x4780,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u01e4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x4100,0x4100,0x4100,0x4780,0x4100,0x4100,0x4100,0x3f00,\n  0x0100,0x0100,0x3e00,0x0000, // u01e5\n  0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u01e6\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0100,0x0100,0x3e00,0x0000, // u01e7\n  0x2200,0x1c00,0x0000,0x4100,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u01e8\n  0x2200,0x1c00,0x0000,0x4000,0x4000,0x4000,0x4000,0x4100,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u01e9\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0800,0x1000,0x0c00,0x0000, // u01ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0800,0x1000,0x0c00,0x0000, // u01eb\n  0x0000,0x3e00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0800,0x1000,0x0c00,0x0000, // u01ec\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0800,0x1000,0x0c00,0x0000, // u01ed\n  0x2200,0x1c00,0x0000,0x7f00,0x0100,0x0200,0x0400,0x0800,0x1e00,0x0100,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u01ee\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x7f00,0x0100,0x0200,0x0400,0x0800,0x1e00,0x0100,0x0100,0x0100,\n  0x4100,0x4100,0x3e00,0x0000, // u01ef\n  0x0000,0x0000,0x0000,0x0000,0x0880,0x0700,0x0000,0x0600,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,\n  0x2200,0x2200,0x1c00,0x0000, // u01f0\n  0x0400,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u01f4\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0100,0x0100,0x3e00,0x0000, // u01f5\n  0x0400,0x0800,0x0000,0x7f80,0x8800,0x8800,0x8800,0x8800,0x8800,0xff00,0x8800,0x8800,0x8800,0x8800,0x8800,0x8f80,\n  0x0000,0x0000,0x0000,0x0000, // u01fc\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x7700,0x0880,0x0880,0x7880,0x8f80,0x8800,0x8800,0x8880,0x7700,\n  0x0000,0x0000,0x0000,0x0000, // u01fd\n  0x0400,0x0800,0x0000,0x3e00,0x4100,0x4180,0x4100,0x4300,0x4500,0x4900,0x5100,0x6100,0x4100,0xc100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u01fe\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x3e80,0x4100,0x4300,0x4500,0x4900,0x5100,0x6100,0x4100,0xbe00,\n  0x0000,0x0000,0x0000,0x0000, // u01ff\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x3e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,\n  0x0000,0x0800,0x0800,0x1000, // u0218\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4000,0x4000,0x3e00,0x0100,0x0100,0x4100,0x3e00,\n  0x0000,0x0800,0x0800,0x1000, // u0219\n  0x0000,0x0000,0x0000,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0800,0x0800,0x1000, // u021a\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x3e00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0700,\n  0x0000,0x0200,0x0200,0x0400, // u021b\n  0x0000,0x3e00,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u0232\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0100,0x0100,0x3e00,0x0000, // u0233\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,\n  0x2200,0x2200,0x1c00,0x0000, // u0237\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x0100,0x0100,0x0100,0x0100,0x0100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0254\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x0100,0x0100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0258\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x0100,0x0100,0x7f00,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0259\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4000,0x4000,0x3c00,0x4000,0x4000,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u025b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x4000,0x4000,0x8000,0x0000, // u0272\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0100,0x0200,0x0400,0x0800,0x1e00,0x0100,0x0100,0x0100,\n  0x4100,0x4100,0x3e00,0x0000, // u0292\n  0x0400,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u02bb\n  0x0800,0x0800,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u02bc\n  0x0800,0x0800,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u02bd\n  0x1c00,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u02c6\n  0x2200,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u02c7\n  0x2200,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u02d8\n  0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u02d9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0800,0x1000,0x0c00,0x0000, // u02db\n  0x3300,0x4c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u02dc\n  0x1100,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u02dd\n  0x1000,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0300\n  0x0400,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0301\n  0x1c00,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0302\n  0x3300,0x4c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0303\n  0x0000,0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0304\n  0x0000,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0305\n  0x2200,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0306\n  0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0307\n  0x2200,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0308\n  0x1c00,0x2200,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u030a\n  0x1100,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u030b\n  0x2200,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u030c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0800,0x0800,0x0000, // u0329\n  0x0000,0x4000,0x8000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0384\n  0x0000,0x0400,0x0800,0x0000,0x2200,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0385\n  0x0000,0x4000,0x8000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0386\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0387\n  0x0000,0x4000,0x8000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u0388\n  0x0000,0x4000,0x8000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0389\n  0x0000,0x4000,0x8000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u038a\n  0x0000,0x4000,0x8000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u038c\n  0x0000,0x4000,0x8000,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0a00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0000,0x0000,0x0000,0x0000, // u038e\n  0x0000,0x4000,0x8000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x2200,0x1400,0x1400,0x7700,\n  0x0000,0x0000,0x0000,0x0000, // u038f\n  0x0000,0x0400,0x0800,0x0000,0x2200,0x2200,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0600,\n  0x0000,0x0000,0x0000,0x0000, // u0390\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0391\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,\n  0x0000,0x0000,0x0000,0x0000, // u0392\n  0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x0000,0x0000,0x0000,0x0000, // u0393\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x1400,0x1400,0x1400,0x2200,0x2200,0x2200,0x4100,0x4100,0x4100,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u0394\n  0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u0395\n  0x0000,0x0000,0x0000,0x7f00,0x0100,0x0100,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u0396\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0397\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x5d00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0398\n  0x0000,0x0000,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u0399\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u039a\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x1400,0x1400,0x1400,0x2200,0x2200,0x2200,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u039b\n  0x0000,0x0000,0x0000,0x4080,0x6180,0x5280,0x5280,0x4c80,0x4c80,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x0000,0x0000,0x0000,0x0000, // u039c\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x6100,0x5100,0x4900,0x4500,0x4300,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u039d\n  0x0000,0x0000,0x0000,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u039e\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u039f\n  0x0000,0x0000,0x0000,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u03a0\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x0000,0x0000,0x0000,0x0000, // u03a1\n  0x0000,0x0000,0x0000,0x7f00,0x4000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u03a3\n  0x0000,0x0000,0x0000,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u03a4\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u03a5\n  0x0000,0x0000,0x0000,0x0800,0x3e00,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x3e00,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u03a6\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x1400,0x1400,0x2200,0x2200,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u03a7\n  0x0000,0x0000,0x0000,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x3e00,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u03a8\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x2200,0x1400,0x1400,0x7700,\n  0x0000,0x0000,0x0000,0x0000, // u03a9\n  0x2200,0x2200,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u03aa\n  0x2200,0x2200,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u03ab\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x3d80,0x4300,0x4200,0x4200,0x4200,0x4200,0x4200,0x4300,0x3d80,\n  0x0000,0x0000,0x0000,0x0000, // u03ac\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x3e00,0x4100,0x4000,0x4000,0x3c00,0x4000,0x4000,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u03ad\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0100,0x0100,0x0100,0x0000, // u03ae\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0600,\n  0x0000,0x0000,0x0000,0x0000, // u03af\n  0x0000,0x0400,0x0800,0x0000,0x2200,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u03b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3d80,0x4300,0x4200,0x4200,0x4200,0x4200,0x4200,0x4300,0x3d80,\n  0x0000,0x0000,0x0000,0x0000, // u03b1\n  0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4400,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,\n  0x4000,0x4000,0x4000,0x0000, // u03b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x2200,0x2200,0x2200,0x1400,0x1400,0x0800,\n  0x0800,0x0800,0x0800,0x0000, // u03b3\n  0x0000,0x0000,0x0000,0x3e00,0x1000,0x0800,0x0400,0x1e00,0x2300,0x4100,0x4100,0x4100,0x4100,0x4100,0x2200,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u03b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4000,0x4000,0x3c00,0x4000,0x4000,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u03b5\n  0x0000,0x0000,0x0000,0x7f00,0x0200,0x0400,0x0800,0x1000,0x2000,0x2000,0x4000,0x4000,0x4000,0x4000,0x4000,0x3e00,\n  0x0100,0x0100,0x0200,0x0000, // u03b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0100,0x0100,0x0100,0x0000, // u03b7\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x2100,0x2100,0x2100,0x2100,0x3f00,0x2100,0x2100,0x2100,0x2100,0x2100,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u03b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0600,\n  0x0000,0x0000,0x0000,0x0000, // u03b9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u03ba\n  0x0000,0x0000,0x0000,0x1000,0x1000,0x0800,0x0800,0x0800,0x1400,0x1400,0x2200,0x2200,0x2200,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u03bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4300,0x7d00,\n  0x4000,0x4000,0x4000,0x0000, // u03bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u03bd\n  0x0000,0x0000,0x0000,0x3f00,0x4000,0x4000,0x4000,0x4000,0x3e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x3e00,\n  0x0100,0x0100,0x0200,0x0000, // u03be\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u03bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u03c0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,\n  0x4000,0x4000,0x4000,0x0000, // u03c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x3e00,\n  0x0100,0x0100,0x0200,0x0000, // u03c2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x2200,0x4100,0x4100,0x4100,0x4100,0x4100,0x2200,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u03c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0600,\n  0x0000,0x0000,0x0000,0x0000, // u03c4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u03c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2600,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x3e00,\n  0x0800,0x0800,0x0800,0x0000, // u03c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x0800,0x0800,0x1400,0x2200,\n  0x2200,0x4100,0x4100,0x0000, // u03c7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x3e00,\n  0x0800,0x0800,0x0800,0x0000, // u03c8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2200,0x4100,0x4100,0x4900,0x4900,0x4900,0x4900,0x4900,0x3600,\n  0x0000,0x0000,0x0000,0x0000, // u03c9\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0600,\n  0x0000,0x0000,0x0000,0x0000, // u03ca\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u03cb\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u03cc\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u03cd\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x2200,0x4100,0x4100,0x4900,0x4900,0x4900,0x4900,0x4900,0x3600,\n  0x0000,0x0000,0x0000,0x0000, // u03ce\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x2100,0x2100,0x2100,0x1f80,0x0100,0x0100,0x6100,0x2100,0x2100,0x2100,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u03d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x3e00,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x3e00,\n  0x0800,0x0800,0x0000,0x0000, // u03d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xe080,0x1100,0x0a00,0x0c00,0x0800,0x1800,0x2800,0x4400,0x8380,\n  0x0000,0x0000,0x0000,0x0000, // u03f0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,\n  0x4000,0x4000,0x3e00,0x0000, // u03f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u03f2\n  0x0000,0x0000,0x0000,0x0200,0x0200,0x0000,0x0000,0x0600,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,\n  0x2200,0x2200,0x1c00,0x0000, // u03f3\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u03f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2000,0x4000,0x4000,0x7e00,0x4000,0x4000,0x2000,0x1f00,\n  0x0000,0x0000,0x0000,0x0000, // u03f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0200,0x0100,0x0100,0x3f00,0x0100,0x0100,0x0200,0x7c00,\n  0x0000,0x0000,0x0000,0x0000, // u03f6\n  0x1000,0x0800,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u0400\n  0x2200,0x2200,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u0401\n  0x0000,0x0000,0x0000,0xf800,0x2000,0x2000,0x2000,0x3e00,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2600,\n  0x0000,0x0000,0x0000,0x0000, // u0402\n  0x0400,0x0800,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x0000,0x0000,0x0000,0x0000, // u0403\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0404\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x3e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0405\n  0x0000,0x0000,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u0406\n  0x2200,0x2200,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u0407\n  0x0000,0x0000,0x0000,0x0380,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x2100,0x2100,0x2100,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u0408\n  0x0000,0x0000,0x0000,0x3800,0x4800,0x8800,0x8800,0x8800,0x8f00,0x8880,0x8880,0x8880,0x8880,0x8880,0x8880,0x8f00,\n  0x0000,0x0000,0x0000,0x0000, // u0409\n  0x0000,0x0000,0x0000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8f00,0xf880,0x8880,0x8880,0x8880,0x8880,0x8880,0x8f00,\n  0x0000,0x0000,0x0000,0x0000, // u040a\n  0x0000,0x0000,0x0000,0xf800,0x2000,0x2000,0x2000,0x3e00,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,\n  0x0000,0x0000,0x0000,0x0000, // u040b\n  0x0400,0x0800,0x0000,0x4100,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u040c\n  0x1000,0x0800,0x0000,0x4100,0x4100,0x4100,0x4100,0x4300,0x4500,0x4900,0x5100,0x6100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u040d\n  0x2200,0x1c00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,0x0100,0x0100,0x0100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u040e\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,\n  0x0800,0x0800,0x0000,0x0000, // u040f\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0410\n  0x0000,0x0000,0x0000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,\n  0x0000,0x0000,0x0000,0x0000, // u0411\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,\n  0x0000,0x0000,0x0000,0x0000, // u0412\n  0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x0000,0x0000,0x0000,0x0000, // u0413\n  0x0000,0x0000,0x0000,0x0f00,0x1100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x7f80,\n  0x4080,0x4080,0x0000,0x0000, // u0414\n  0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u0415\n  0x0000,0x0000,0x0000,0x4900,0x4900,0x4900,0x4900,0x4900,0x2a00,0x1c00,0x2a00,0x4900,0x4900,0x4900,0x4900,0x4900,\n  0x0000,0x0000,0x0000,0x0000, // u0416\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x0100,0x0100,0x0100,0x1e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0417\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4300,0x4500,0x4900,0x5100,0x6100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0418\n  0x2200,0x1c00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4300,0x4500,0x4900,0x5100,0x6100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0419\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u041a\n  0x0000,0x0000,0x0000,0x0f00,0x1100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u041b\n  0x0000,0x0000,0x0000,0x4080,0x6180,0x5280,0x5280,0x4c80,0x4c80,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x0000,0x0000,0x0000,0x0000, // u041c\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u041d\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u041e\n  0x0000,0x0000,0x0000,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u041f\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x0000,0x0000,0x0000,0x0000, // u0420\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0421\n  0x0000,0x0000,0x0000,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u0422\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,0x0100,0x0100,0x0100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0423\n  0x0000,0x0000,0x0800,0x3e00,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x3e00,\n  0x0800,0x0000,0x0000,0x0000, // u0424\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x1400,0x1400,0x2200,0x2200,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0425\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f80,\n  0x0080,0x0080,0x0000,0x0000, // u0426\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0000,0x0000,0x0000,0x0000, // u0427\n  0x0000,0x0000,0x0000,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0428\n  0x0000,0x0000,0x0000,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x3f80,\n  0x0080,0x0080,0x0000,0x0000, // u0429\n  0x0000,0x0000,0x0000,0xc000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,\n  0x0000,0x0000,0x0000,0x0000, // u042a\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x7880,0x4480,0x4480,0x4480,0x4480,0x4480,0x4480,0x4480,0x7880,\n  0x0000,0x0000,0x0000,0x0000, // u042b\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,\n  0x0000,0x0000,0x0000,0x0000, // u042c\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x0100,0x0100,0x0100,0x1f00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u042d\n  0x0000,0x0000,0x0000,0x4700,0x4880,0x4880,0x4880,0x4880,0x4880,0x7880,0x4880,0x4880,0x4880,0x4880,0x4880,0x4700,\n  0x0000,0x0000,0x0000,0x0000, // u042e\n  0x0000,0x0000,0x0000,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0300,0x0500,0x0900,0x1100,0x2100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u042f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0430\n  0x0000,0x0000,0x0000,0x3e00,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,\n  0x0000,0x0000,0x0000,0x0000, // u0431\n  0x0000,0x0000,0x0000,0x3c00,0x4200,0x4200,0x4200,0x4400,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,\n  0x0000,0x0000,0x0000,0x0000, // u0432\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x0000,0x0000,0x0000,0x0000, // u0433\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0100,0x0100,0x3e00,0x0000, // u0434\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0435\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4900,0x4900,0x4900,0x2a00,0x1c00,0x2a00,0x4900,0x4900,0x4900,\n  0x0000,0x0000,0x0000,0x0000, // u0436\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x0100,0x0100,0x1e00,0x0100,0x0100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0437\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0438\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0439\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u043a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x1100,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u043b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x6300,0x5500,0x4900,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u043c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u043d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u043e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u043f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,\n  0x4000,0x4000,0x4000,0x0000, // u0440\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0441\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u0442\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0100,0x0100,0x3e00,0x0000, // u0443\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x3e00,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x3e00,\n  0x0800,0x0800,0x0000,0x0000, // u0444\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x1400,0x0800,0x1400,0x2200,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u0445\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f80,\n  0x0080,0x0080,0x0000,0x0000, // u0446\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,0x0100,0x0100,0x0100,\n  0x0000,0x0000,0x0000,0x0000, // u0447\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0448\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x3f80,\n  0x0080,0x0080,0x0000,0x0000, // u0449\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x2000,0x2000,0x3e00,0x2100,0x2100,0x2100,0x2100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u044a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x7880,0x4480,0x4480,0x4480,0x4480,0x7880,\n  0x0000,0x0000,0x0000,0x0000, // u044b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x3e00,0x2100,0x2100,0x2100,0x2100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u044c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x0100,0x0100,0x1f00,0x0100,0x0100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u044d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4700,0x4880,0x4880,0x4880,0x7880,0x4880,0x4880,0x4880,0x4700,\n  0x0000,0x0000,0x0000,0x0000, // u044e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x4100,0x4100,0x4100,0x3f00,0x0500,0x0900,0x1100,0x2100,\n  0x0000,0x0000,0x0000,0x0000, // u044f\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x0800,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0450\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0451\n  0x0000,0x0000,0x0000,0x4000,0xf800,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0100,0x0100,0x0600,0x0000, // u0452\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x0000,0x0000,0x0000,0x0000, // u0453\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0454\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4000,0x4000,0x3e00,0x0100,0x0100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0455\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u0456\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u0457\n  0x0000,0x0000,0x0000,0x0200,0x0200,0x0000,0x0000,0x0600,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,\n  0x2200,0x2200,0x1c00,0x0000, // u0458\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x4800,0x8800,0x8f00,0x8880,0x8880,0x8880,0x8880,0x8f00,\n  0x0000,0x0000,0x0000,0x0000, // u0459\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0x8800,0x8f00,0xf880,0x8880,0x8880,0x8880,0x8f00,\n  0x0000,0x0000,0x0000,0x0000, // u045a\n  0x0000,0x0000,0x0000,0x4000,0xf800,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u045b\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x0000,0x4100,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u045c\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x0800,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u045d\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0100,0x0100,0x3e00,0x0000, // u045e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,\n  0x0800,0x0800,0x0000,0x0000, // u045f\n  0x0000,0x0000,0x0000,0x4000,0xf800,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7e00,\n  0x0000,0x0000,0x0000,0x0000, // u0462\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0xf800,0x2000,0x2000,0x2000,0x3e00,0x2100,0x2100,0x2100,0x2100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0463\n  0x0000,0x0000,0x0000,0x7f00,0x4100,0x2200,0x2200,0x1400,0x0800,0x1c00,0x2a00,0x4900,0x4900,0x4900,0x4900,0x4900,\n  0x0000,0x0000,0x0000,0x0000, // u046a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4100,0x2200,0x1400,0x1c00,0x2a00,0x4900,0x4900,0x4900,\n  0x0000,0x0000,0x0000,0x0000, // u046b\n  0x0000,0x0100,0x0100,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x0000,0x0000,0x0000,0x0000, // u0490\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x0000,0x0000,0x0000,0x0000, // u0491\n  0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0xf800,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x0000,0x0000,0x0000,0x0000, // u0492\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0xf800,0x4000,0x4000,0x4000,0x4000,\n  0x0000,0x0000,0x0000,0x0000, // u0493\n  0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0100,0x0200,0x0000,0x0000, // u0494\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x7c00,0x4200,0x4200,0x4200,0x4200,\n  0x0200,0x0400,0x0000,0x0000, // u0495\n  0x0000,0x0000,0x0000,0x4900,0x4900,0x4900,0x4900,0x4900,0x2a00,0x1c00,0x2a00,0x4900,0x4900,0x4900,0x4900,0x4980,\n  0x0080,0x0080,0x0000,0x0000, // u0496\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4900,0x4900,0x4900,0x2a00,0x1c00,0x2a00,0x4900,0x4900,0x4980,\n  0x0080,0x0080,0x0000,0x0000, // u0497\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x0100,0x0100,0x0100,0x1e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,\n  0x0800,0x0800,0x0800,0x0000, // u0498\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x0100,0x0100,0x1e00,0x0100,0x0100,0x4100,0x3e00,\n  0x0800,0x0800,0x0800,0x0000, // u0499\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,0x4180,\n  0x0080,0x0080,0x0000,0x0000, // u049a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x4180,\n  0x0080,0x0080,0x0000,0x0000, // u049b\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x5200,0x5400,0x5800,0x7000,0x5800,0x5400,0x5200,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u049c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x5200,0x5400,0x5800,0x7000,0x5800,0x5400,0x5200,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u049d\n  0x0000,0x0000,0x0000,0xc100,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u04a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc100,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u04a1\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4180,\n  0x0080,0x0080,0x0000,0x0000, // u04a2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4180,\n  0x0080,0x0080,0x0000,0x0000, // u04a3\n  0x0000,0x0000,0x0000,0x43c0,0x4200,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,\n  0x0000,0x0000,0x0000,0x0000, // u04a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x43c0,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,\n  0x0000,0x0000,0x0000,0x0000, // u04a5\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x4100,0x3e00,\n  0x0800,0x0800,0x0800,0x0000, // u04aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x3e00,\n  0x0800,0x0800,0x0800,0x0000, // u04ab\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u04ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x2200,0x2200,0x2200,0x1400,0x1400,0x0800,\n  0x0800,0x0800,0x0800,0x0000, // u04af\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,0x3e00,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u04b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x2200,0x2200,0x2200,0x1400,0x1400,0x0800,\n  0x3e00,0x0800,0x0800,0x0000, // u04b1\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x1400,0x1400,0x2200,0x2200,0x4100,0x4180,\n  0x0080,0x0080,0x0000,0x0000, // u04b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x1400,0x0800,0x1400,0x2200,0x4100,0x4180,\n  0x0080,0x0080,0x0000,0x0000, // u04b3\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,0x0100,0x0100,0x0100,0x0100,0x0180,\n  0x0080,0x0080,0x0000,0x0000, // u04b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,0x0100,0x0100,0x0180,\n  0x0080,0x0080,0x0000,0x0000, // u04b7\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4900,0x4900,0x4900,0x3f00,0x0900,0x0900,0x0900,0x0100,0x0100,0x0100,\n  0x0000,0x0000,0x0000,0x0000, // u04b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4900,0x4900,0x3f00,0x0900,0x0900,0x0100,0x0100,\n  0x0000,0x0000,0x0000,0x0000, // u04b9\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u04ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u04bb\n  0x0000,0x0000,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u04c0\n  0x2200,0x1c00,0x0000,0x4900,0x4900,0x4900,0x4900,0x4900,0x2a00,0x1c00,0x2a00,0x4900,0x4900,0x4900,0x4900,0x4900,\n  0x0000,0x0000,0x0000,0x0000, // u04c1\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x4900,0x4900,0x4900,0x2a00,0x1c00,0x2a00,0x4900,0x4900,0x4900,\n  0x0000,0x0000,0x0000,0x0000, // u04c2\n  0x0000,0x0000,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u04cf\n  0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u04d0\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u04d1\n  0x2200,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u04d2\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x3e00,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u04d3\n  0x0000,0x0000,0x0000,0x7f80,0x8800,0x8800,0x8800,0x8800,0x8800,0xff00,0x8800,0x8800,0x8800,0x8800,0x8800,0x8f80,\n  0x0000,0x0000,0x0000,0x0000, // u04d4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7700,0x0880,0x0880,0x7880,0x8f80,0x8800,0x8800,0x8880,0x7700,\n  0x0000,0x0000,0x0000,0x0000, // u04d5\n  0x2200,0x1c00,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u04d6\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x1c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u04d7\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x0100,0x0100,0x0100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u04d8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x0100,0x0100,0x7f00,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u04d9\n  0x2200,0x2200,0x0000,0x3e00,0x4100,0x4100,0x0100,0x0100,0x0100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u04da\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x3e00,0x4100,0x0100,0x0100,0x7f00,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u04db\n  0x2200,0x2200,0x0000,0x4900,0x4900,0x4900,0x4900,0x4900,0x2a00,0x1c00,0x2a00,0x4900,0x4900,0x4900,0x4900,0x4900,\n  0x0000,0x0000,0x0000,0x0000, // u04dc\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x4900,0x4900,0x4900,0x2a00,0x1c00,0x2a00,0x4900,0x4900,0x4900,\n  0x0000,0x0000,0x0000,0x0000, // u04dd\n  0x2200,0x2200,0x0000,0x3e00,0x4100,0x4100,0x0100,0x0100,0x0100,0x1e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u04de\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x3e00,0x4100,0x0100,0x0100,0x1e00,0x0100,0x0100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u04df\n  0x0000,0x3e00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4300,0x4500,0x4900,0x5100,0x6100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u04e2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u04e3\n  0x2200,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4300,0x4500,0x4900,0x5100,0x6100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u04e4\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u04e5\n  0x2200,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u04e6\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u04e7\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u04e8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u04e9\n  0x2200,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u04ea\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u04eb\n  0x2200,0x2200,0x0000,0x3e00,0x4100,0x4100,0x0100,0x0100,0x0100,0x1f00,0x0100,0x0100,0x0100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u04ec\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x3e00,0x4100,0x0100,0x0100,0x1f00,0x0100,0x0100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u04ed\n  0x0000,0x3e00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,0x0100,0x0100,0x0100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u04ee\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0100,0x0100,0x3e00,0x0000, // u04ef\n  0x2200,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,0x0100,0x0100,0x0100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u04f0\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0100,0x0100,0x3e00,0x0000, // u04f1\n  0x1100,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,0x0100,0x0100,0x0100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u04f2\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0100,0x0100,0x3e00,0x0000, // u04f3\n  0x2200,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0000,0x0000,0x0000,0x0000, // u04f4\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x4100,0x4100,0x4100,0x4100,0x3f00,0x0100,0x0100,0x0100,0x0100,\n  0x0000,0x0000,0x0000,0x0000, // u04f5\n  0x2200,0x2200,0x0000,0x4080,0x4080,0x4080,0x4080,0x7880,0x4480,0x4480,0x4480,0x4480,0x4480,0x4480,0x4480,0x7880,\n  0x0000,0x0000,0x0000,0x0000, // u04f8\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x2200,0x0000,0x4080,0x4080,0x4080,0x7880,0x4480,0x4480,0x4480,0x4480,0x7880,\n  0x0000,0x0000,0x0000,0x0000, // u04f9\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x1080,0x1080,0x0880,0x0900,0x1600,0x2400,0x4400,0x4200,0x4200,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u05d0\n  0x0000,0x0000,0x0000,0x7e00,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u05d1\n  0x0000,0x0000,0x0000,0x3c00,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0600,0x0900,0x1100,0x2080,0x4080,\n  0x0000,0x0000,0x0000,0x0000, // u05d2\n  0x0000,0x0000,0x0000,0x7f80,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0000,0x0000,0x0000,0x0000, // u05d3\n  0x0000,0x0000,0x0000,0x7e00,0x0100,0x0100,0x0100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u05d4\n  0x0000,0x0000,0x0000,0x3000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u05d5\n  0x0000,0x0000,0x0000,0x0000,0x3f00,0x0200,0x0400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u05d6\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u05d7\n  0x0000,0x0000,0x0000,0x4600,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u05d8\n  0x0000,0x0000,0x0000,0x3000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u05d9\n  0x0000,0x0000,0x0000,0x7e00,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0100,0x0100,0x0100,0x0000, // u05da\n  0x0000,0x0000,0x0000,0x7e00,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x7e00,\n  0x0000,0x0000,0x0000,0x0000, // u05db\n  0x0000,0x4000,0x4000,0x7f00,0x0100,0x0100,0x0100,0x0100,0x0100,0x0200,0x0400,0x0800,0x1000,0x1000,0x1000,0x1000,\n  0x0000,0x0000,0x0000,0x0000, // u05dc\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u05dd\n  0x0000,0x0000,0x0000,0x0000,0xdc00,0x6200,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4700,\n  0x0000,0x0000,0x0000,0x0000, // u05de\n  0x0000,0x0000,0x0000,0x7800,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000, // u05df\n  0x0000,0x0000,0x0000,0x3c00,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u05e0\n  0x0000,0x0000,0x0000,0xfe00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u05e1\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x2100,0x2100,0x2100,0x1100,0x1100,0x0a00,0x0a00,0x0c00,0x1800,0x6000,\n  0x0000,0x0000,0x0000,0x0000, // u05e2\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0100,0x0100,0x0100,0x0000, // u05e3\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x3100,0x0100,0x0100,0x0100,0x0100,0x0100,0x7e00,\n  0x0000,0x0000,0x0000,0x0000, // u05e4\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x2100,0x2100,0x1100,0x1200,0x0c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0000, // u05e5\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x2100,0x2100,0x1100,0x1200,0x0c00,0x0800,0x0400,0x0400,0x0200,0x0200,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u05e6\n  0x0000,0x0000,0x0000,0x7f00,0x0100,0x0100,0x0100,0x4100,0x4100,0x4200,0x4400,0x4800,0x4800,0x4800,0x4800,0x4800,\n  0x4000,0x4000,0x4000,0x0000, // u05e7\n  0x0000,0x0000,0x0000,0x7e00,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0000,0x0000,0x0000,0x0000, // u05e8\n  0x0000,0x0000,0x0000,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x5100,0x6100,0x4100,0x4100,0x4100,0x4200,0x7c00,\n  0x0000,0x0000,0x0000,0x0000, // u05e9\n  0x0000,0x0000,0x0000,0xfe00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x8100,\n  0x0000,0x0000,0x0000,0x0000, // u05ea\n  0x0000,0x0000,0x0000,0x7c00,0x4200,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4200,0x7c00,\n  0x0000,0x1000,0x1000,0x0000, // u1e0c\n  0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0100,0x3f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0800,0x0800,0x0000, // u1e0d\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,0x4100,\n  0x0000,0x3e00,0x0000,0x0000, // u1e34\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4100,0x4200,0x4400,0x4800,0x7000,0x4800,0x4400,0x4200,0x4100,\n  0x0000,0x3e00,0x0000,0x0000, // u1e35\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0800,0x0800,0x0000, // u1e36\n  0x0000,0x0000,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0800,0x0800,0x0000, // u1e37\n  0x0800,0x0800,0x0000,0x4080,0x6180,0x5280,0x5280,0x4c80,0x4c80,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x0000,0x0000,0x0000,0x0000, // u1e40\n  0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x7e00,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,\n  0x0000,0x0000,0x0000,0x0000, // u1e41\n  0x0000,0x0000,0x0000,0x4080,0x6180,0x5280,0x5280,0x4c80,0x4c80,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x0000,0x0800,0x0800,0x0000, // u1e42\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,0x4900,\n  0x0000,0x0800,0x0800,0x0000, // u1e43\n  0x0800,0x0800,0x0000,0x4100,0x4100,0x4100,0x4100,0x6100,0x5100,0x4900,0x4500,0x4300,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u1e44\n  0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u1e45\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x6100,0x5100,0x4900,0x4500,0x4300,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0800,0x0800,0x0000, // u1e46\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0800,0x0800,0x0000, // u1e47\n  0x0000,0x0000,0x0000,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0800,0x0800,0x0000, // u1e6c\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x3e00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0700,\n  0x0000,0x0200,0x0200,0x0000, // u1e6d\n  0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0800,0x0800,0x0000, // u1eb8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,\n  0x0000,0x0800,0x0800,0x0000, // u1eb9\n  0x3300,0x4c00,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u1ebc\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x4c00,0x0000,0x3e00,0x4100,0x4100,0x4100,0x7f00,0x4000,0x4000,0x4100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u1ebd\n  0x0000,0x0000,0x0000,0x1c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0800,0x0800,0x0000, // u1eca\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1c00,\n  0x0000,0x0800,0x0800,0x0000, // u1ecb\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0800,0x0800,0x0000, // u1ecc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0800,0x0800,0x0000, // u1ecd\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,\n  0x0000,0x0800,0x0800,0x0000, // u1ee4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0000,0x0800,0x0800,0x0000, // u1ee5\n  0x3300,0x4c00,0x0000,0x4100,0x4100,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u1ef8\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x4c00,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3f00,\n  0x0100,0x0100,0x3e00,0x0000, // u1ef9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2001\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2002\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2003\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2004\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2005\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2006\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2007\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2008\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2009\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u200a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u200b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u200c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u200d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u200e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u200f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2010\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2011\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2012\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2013\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2014\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2015\n  0x0000,0x0000,0x0000,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x0000,0x0000,0x0000,0x0000, // u2016\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x7f00,0x0000,0x7f00, // u2017\n  0x0000,0x0400,0x0800,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2018\n  0x0000,0x0800,0x0800,0x0800,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2019\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,\n  0x1000,0x0000,0x0000,0x0000, // u201a\n  0x0000,0x1000,0x1000,0x1000,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u201b\n  0x0000,0x1100,0x2200,0x2200,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u201c\n  0x0000,0x1100,0x1100,0x1100,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u201d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2200,0x2200,0x2200,\n  0x4400,0x0000,0x0000,0x0000, // u201e\n  0x0000,0x4400,0x4400,0x4400,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u201f\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u2020\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x7f00,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u2021\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x1e00,0x1e00,0x0c00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2022\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4900,0x4900,\n  0x0000,0x0000,0x0000,0x0000, // u2026\n  0x0000,0x0000,0x0000,0x0000,0xe400,0xa400,0xe800,0x0800,0x1000,0x1000,0x2000,0x2000,0x4000,0x5dc0,0x9540,0x9dc0,\n  0x0000,0x0000,0x0000,0x0000, // u2030\n  0x0000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2032\n  0x0000,0x2200,0x2200,0x2200,0x2200,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2033\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x1000,0x2000,0x1000,0x0800,0x0400,0x0200,\n  0x0000,0x0000,0x0000,0x0000, // u2039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0400,0x0800,0x1000,0x2000,\n  0x0000,0x0000,0x0000,0x0000, // u203a\n  0x0000,0x0000,0x0000,0x2200,0x2200,0x2200,0x2200,0x2200,0x2200,0x2200,0x2200,0x2200,0x0000,0x0000,0x2200,0x2200,\n  0x0000,0x0000,0x0000,0x0000, // u203c\n  0x0000,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u203e\n  0x0000,0x1c00,0x2200,0x2200,0x2200,0x2200,0x2200,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2070\n  0x0800,0x0800,0x0000,0x1800,0x0800,0x0800,0x0800,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2071\n  0x0000,0x0200,0x0600,0x0a00,0x1200,0x3f00,0x0200,0x0200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2074\n  0x0000,0x3c00,0x2000,0x2000,0x3c00,0x0200,0x0200,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2075\n  0x0000,0x1c00,0x2000,0x2000,0x3c00,0x2200,0x2200,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2076\n  0x0000,0x3e00,0x0200,0x0400,0x0400,0x0800,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2077\n  0x0000,0x1c00,0x2200,0x2200,0x1c00,0x2200,0x2200,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2078\n  0x0000,0x1c00,0x2200,0x2200,0x1e00,0x0200,0x0200,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2079\n  0x0000,0x0000,0x0800,0x0800,0x3e00,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u207a\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u207b\n  0x0000,0x0000,0x0000,0x3e00,0x0000,0x0000,0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u207c\n  0x0000,0x0400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u207d\n  0x0000,0x0800,0x0400,0x0400,0x0400,0x0400,0x0400,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u207e\n  0x0000,0x0000,0x3c00,0x2200,0x2200,0x2200,0x2200,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u207f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x2200,0x2200,0x2200,0x2200,\n  0x1c00,0x0000,0x0000,0x0000, // u2080\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x1800,0x0800,0x0800,0x0800,0x0800,\n  0x1c00,0x0000,0x0000,0x0000, // u2081\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x2200,0x0400,0x0800,0x1000,\n  0x3e00,0x0000,0x0000,0x0000, // u2082\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x0200,0x0c00,0x0200,0x2200,\n  0x1c00,0x0000,0x0000,0x0000, // u2083\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0200,0x0600,0x0a00,0x1200,0x3f00,0x0200,\n  0x0200,0x0000,0x0000,0x0000, // u2084\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x2000,0x2000,0x3c00,0x0200,0x0200,\n  0x3c00,0x0000,0x0000,0x0000, // u2085\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x2000,0x2000,0x3c00,0x2200,0x2200,\n  0x1c00,0x0000,0x0000,0x0000, // u2086\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0200,0x0400,0x0400,0x0800,0x0800,\n  0x0800,0x0000,0x0000,0x0000, // u2087\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x2200,0x1c00,0x2200,0x2200,\n  0x1c00,0x0000,0x0000,0x0000, // u2088\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x2200,0x1e00,0x0200,0x0200,\n  0x1c00,0x0000,0x0000,0x0000, // u2089\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x3e00,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u208a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u208b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0000,0x0000,0x3e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u208c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0400,0x0000,0x0000,0x0000, // u208d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0800,0x0000,0x0000,0x0000, // u208e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0200,0x1e00,0x2200,0x2200,\n  0x1e00,0x0000,0x0000,0x0000, // u2090\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x3e00,0x2000,0x2000,\n  0x1e00,0x0000,0x0000,0x0000, // u2091\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x2200,0x2200,0x2200,\n  0x1c00,0x0000,0x0000,0x0000, // u2092\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2200,0x1400,0x0800,0x0800,0x1400,\n  0x2200,0x0000,0x0000,0x0000, // u2093\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x0200,0x0200,0x3e00,0x2200,\n  0x1c00,0x0000,0x0000,0x0000, // u2094\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x3c00,0x2200,0x2200,0x2200,0x2200,\n  0x2200,0x0000,0x0000,0x0000, // u2095\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2200,0x2400,0x2800,0x3800,0x2400,\n  0x2200,0x0000,0x0000,0x0000, // u2096\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x1c00,0x0000,0x0000,0x0000, // u2097\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4900,0x4900,0x4900,0x4900,\n  0x4900,0x0000,0x0000,0x0000, // u2098\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x2200,0x2200,0x2200,0x2200,\n  0x3c00,0x2000,0x2000,0x0000, // u209a\n  0x0000,0x0000,0x0000,0x7800,0x4400,0x4400,0x4400,0x4400,0x4400,0x7a00,0x4200,0x4700,0x4200,0x4200,0x4200,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u20a7\n  0x0000,0x0000,0x0000,0x7900,0x4500,0x4500,0x4500,0x5500,0x5500,0x5500,0x5500,0x5500,0x5100,0x5100,0x5100,0x5e00,\n  0x0000,0x0000,0x0000,0x0000, // u20aa\n  0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4000,0xfc00,0x4000,0x4000,0xfc00,0x4000,0x4080,0x2100,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u20ac\n  0x0000,0x0000,0x0000,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0e00,0x3800,0x0e00,0x3800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u20ae\n  0x0000,0x0000,0x0000,0x3e00,0x5100,0x5100,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5100,0x5100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u2102\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u210e\n  0x0000,0x0000,0x0000,0x4000,0xf800,0x4000,0x4000,0x7e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u210f\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x6100,0x5100,0x6900,0x5500,0x4b00,0x4500,0x4300,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u2115\n  0x0000,0x0000,0x0000,0x8400,0x8480,0xc540,0xc540,0xa480,0xa400,0x9400,0x9400,0x8dc0,0x8c00,0x85c0,0x8400,0x8400,\n  0x0000,0x0000,0x0000,0x0000, // u2116\n  0x0000,0x0000,0x0000,0x3e00,0x5100,0x5100,0x5100,0x5100,0x5100,0x5100,0x5100,0x5100,0x5100,0x5100,0x5500,0x3e00,\n  0x0100,0x0080,0x0000,0x0000, // u211a\n  0x0000,0x0000,0x0000,0x7e00,0x5100,0x5100,0x5100,0x5100,0x5100,0x5e00,0x5800,0x5400,0x5a00,0x5500,0x5280,0x7180,\n  0x0000,0x0000,0x0000,0x0000, // u211d\n  0x0000,0x0000,0x0000,0xe880,0x4d80,0x4a80,0x4880,0x4880,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2122\n  0x0000,0x0000,0x0000,0x7f00,0x0100,0x0100,0x0300,0x0500,0x0a00,0x1400,0x2800,0x5000,0x6000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u2124\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x2200,0x1400,0x1400,0x7700,\n  0x0000,0x0000,0x0000,0x0000, // u2126\n  0x0000,0x0000,0x0000,0x0000,0x4200,0x4200,0x2100,0x2100,0x1080,0x3100,0x4a00,0x8c00,0x8400,0x8400,0x8200,0x4200,\n  0x0000,0x0000,0x0000,0x0000, // u2135\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x2000,0x4000,0xff80,0x4000,0x2000,0x1000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2190\n  0x0000,0x0000,0x0000,0x0800,0x1c00,0x2a00,0x4900,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u2191\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0200,0x0100,0xff80,0x0100,0x0200,0x0400,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2192\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x4900,0x2a00,0x1c00,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u2193\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1200,0x2100,0x4080,0xffc0,0x4080,0x2100,0x1200,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2194\n  0x0000,0x0000,0x0000,0x0800,0x1c00,0x2a00,0x4900,0x0800,0x0800,0x0800,0x0800,0x0800,0x4900,0x2a00,0x1c00,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u2195\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1080,0x2080,0x4080,0xff80,0x4080,0x2080,0x1080,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u21a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x8400,0x8200,0x8100,0xff80,0x8100,0x8200,0x8400,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u21a6\n  0x0000,0x0000,0x0000,0x0800,0x1c00,0x2a00,0x4900,0x0800,0x0800,0x0800,0x0800,0x4900,0x2a00,0x1c00,0x0800,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u21a8\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x1080,0x2080,0x4080,0xff80,0x4000,0x2000,0x1000,\n  0x0000,0x0000,0x0000,0x0000, // u21b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7800,0x1800,0x2800,0x4880,0x4080,0x4080,0x4080,0x2100,0x1e00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u21bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x2000,0x4000,0xff80,0x0000,0xff80,0x0100,0x0200,0x0400,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u21cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0200,0x0100,0xff80,0x0000,0xff80,0x4000,0x2000,0x1000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u21cc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x2000,0x7f80,0xc000,0x7f80,0x2000,0x1000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u21d0\n  0x0000,0x0000,0x0000,0x0800,0x1c00,0x3600,0x5500,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x0000,0x0000,0x0000,0x0000, // u21d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0200,0xff00,0x0180,0xff00,0x0200,0x0400,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u21d2\n  0x0000,0x0000,0x0000,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x5500,0x3600,0x1c00,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u21d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1200,0x2100,0x7f80,0xc0c0,0x7f80,0x2100,0x1200,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u21d4\n  0x0000,0x0000,0x0000,0x0800,0x1c00,0x3600,0x5500,0x1400,0x1400,0x1400,0x1400,0x1400,0x5500,0x3600,0x1c00,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u21d5\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x7f00,0x2200,0x2200,0x2200,0x1400,0x1400,0x1400,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u2200\n  0x0000,0x0000,0x0000,0x7f00,0x0100,0x0100,0x0100,0x0100,0x0100,0x7f00,0x0100,0x0100,0x0100,0x0100,0x0100,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u2203\n  0x0000,0x0100,0x0100,0x7f00,0x0300,0x0500,0x0500,0x0900,0x0900,0x7f00,0x1100,0x1100,0x2100,0x2100,0x4100,0x7f00,\n  0x8000,0x8000,0x0000,0x0000, // u2204\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x3e00,0x4500,0x4500,0x4900,0x5100,0x5100,0x3e00,0x2000,0x4000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2205\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x1400,0x1400,0x1400,0x2200,0x2200,0x2200,0x4100,0x4100,0x4100,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u2206\n  0x0000,0x0000,0x0000,0x7f00,0x4100,0x4100,0x4100,0x2200,0x2200,0x2200,0x1400,0x1400,0x1400,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u2207\n  0x0000,0x0000,0x0000,0x0f00,0x1000,0x2000,0x4000,0x4000,0x4000,0x7f00,0x4000,0x4000,0x4000,0x2000,0x1000,0x0f00,\n  0x0000,0x0000,0x0000,0x0000, // u2208\n  0x0000,0x0080,0x0080,0x0f00,0x1100,0x2200,0x4200,0x4400,0x4400,0x7f00,0x4800,0x4800,0x5000,0x3000,0x3000,0x2f00,\n  0x4000,0x4000,0x0000,0x0000, // u2209\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2000,0x4000,0x4000,0x7f00,0x4000,0x4000,0x2000,0x1f00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u220a\n  0x0000,0x0000,0x0000,0x7800,0x0400,0x0200,0x0100,0x0100,0x0100,0x7f00,0x0100,0x0100,0x0100,0x0200,0x0400,0x7800,\n  0x0000,0x0000,0x0000,0x0000, // u220b\n  0x0000,0x4000,0x4000,0x3c00,0x2200,0x1100,0x1080,0x0880,0x0880,0x3f80,0x0480,0x0480,0x0280,0x0300,0x0300,0x3d00,\n  0x0080,0x0080,0x0000,0x0000, // u220c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0200,0x0100,0x0100,0x7f00,0x0100,0x0100,0x0200,0x7c00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u220d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2212\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0000,0x0000,0x0800,0x0800,0x0800,0x7f00,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u2213\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0000,0x0000,0x0800,0x0800,0x0800,0x7f00,0x0800,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u2214\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2215\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,0x0080,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2216\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2219\n  0x0000,0x0380,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x4200,0x4200,0x4200,0x2200,0x1200,0x0a00,0x0600,\n  0x0000,0x0000,0x0000,0x0000, // u221a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3600,0x4900,0x4900,0x4900,0x4900,0x3600,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u221e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u221f\n  0x0000,0x0000,0x0000,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x0000,0x0000,0x0000,0x0000, // u2225\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x1400,0x1400,0x2200,0x2200,0x2200,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u2227\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x2200,0x2200,0x2200,0x1400,0x1400,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u2228\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x2200,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u2229\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x2200,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u222a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3100,0x4900,0x4600,0x0000,0x3100,0x4900,0x4600,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2248\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x7f00,0x0400,0x0800,0x1000,0x7f00,0x4000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2260\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0000,0x0000,0x0000,0x7f00,0x0000,0x0000,0x0000,0x7f00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2261\n  0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u2264\n  0x0000,0x0000,0x0000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x0000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u2265\n  0x0000,0x0000,0x0000,0x0000,0x0440,0x0880,0x1100,0x2200,0x4400,0x8800,0x4400,0x2200,0x1100,0x0880,0x0440,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u226a\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x4400,0x2200,0x1100,0x0880,0x0440,0x0880,0x1100,0x2200,0x4400,0x8800,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u226b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2000,0x4000,0x4000,0x4000,0x4000,0x4000,0x2000,0x1f00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2282\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x0200,0x0100,0x0100,0x0100,0x0100,0x0100,0x0200,0x7c00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2283\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2000,0x4000,0x4000,0x4000,0x4000,0x4000,0x2000,0x1f00,0x0000,0x7f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2286\n  0x0000,0x0000,0x0000,0x0000,0x7c00,0x0200,0x0100,0x0100,0x0100,0x0100,0x0100,0x0200,0x7c00,0x0000,0x7f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2287\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u22a5\n  0x0000,0x0000,0x0000,0x1c00,0x2200,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u22c2\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x2200,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u22c3\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x3e00,0x4500,0x4500,0x4900,0x5100,0x5100,0x3e00,0x2000,0x4000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2300\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x1400,0x2200,0x4100,0x8080,0x8080,0x8080,0x8080,0x8080,0xff80,\n  0x0000,0x0000,0x0000,0x0000, // u2302\n  0x0000,0x0000,0x0000,0x1c00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,\n  0x0000,0x0000,0x0000,0x0000, // u2308\n  0x0000,0x0000,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0000,0x0000,0x0000,0x0000, // u2309\n  0x0000,0x0000,0x0000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u230a\n  0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x1c00,\n  0x0000,0x0000,0x0000,0x0000, // u230b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2310\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2319\n  0x0000,0x0000,0x0000,0x0600,0x0900,0x0900,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u2320\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x4800,0x4800,0x3000,\n  0x0000,0x0000,0x0000,0x0000, // u2321\n  0x0100,0x0200,0x0400,0x0400,0x0800,0x0800,0x0800,0x1000,0x1000,0x1000,0x1000,0x2000,0x2000,0x2000,0x2000,0x2000,\n  0x2000,0x2000,0x2000,0x2000, // u239b\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,\n  0x2000,0x2000,0x2000,0x2000, // u239c\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x1000,0x1000,0x1000,0x1000,0x0800,0x0800,0x0800,\n  0x0400,0x0400,0x0200,0x0100, // u239d\n  0x2000,0x1000,0x0800,0x0800,0x0400,0x0400,0x0400,0x0200,0x0200,0x0200,0x0200,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0100,0x0100,0x0100,0x0100, // u239e\n  0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0100,0x0100,0x0100,0x0100, // u239f\n  0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0200,0x0200,0x0200,0x0200,0x0400,0x0400,0x0400,\n  0x0800,0x0800,0x1000,0x2000, // u23a0\n  0x3f00,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,\n  0x2000,0x2000,0x2000,0x2000, // u23a1\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,\n  0x2000,0x2000,0x2000,0x2000, // u23a2\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,\n  0x2000,0x2000,0x2000,0x3f00, // u23a3\n  0x3f00,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0100,0x0100,0x0100,0x0100, // u23a4\n  0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0100,0x0100,0x0100,0x0100, // u23a5\n  0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0100,0x0100,0x0100,0x3f00, // u23a6\n  0x0380,0x0c00,0x0800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,\n  0x1000,0x1000,0x1000,0x1000, // u23a7\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x2000,0xc000,0xc000,0x2000,0x1000,0x1000,0x1000,0x1000,\n  0x1000,0x1000,0x1000,0x1000, // u23a8\n  0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,\n  0x1000,0x0800,0x0c00,0x0380, // u23a9\n  0xe000,0x1800,0x0800,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400, // u23ab\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0200,0x0180,0x0180,0x0200,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400, // u23ac\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0800,0x1800,0xe000, // u23ad\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u23ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u23af\n  0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u23ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u23bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u23bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0xffc0, // u23bd\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u23d0\n  0x0000,0x0000,0x4400,0x4400,0x4400,0x7c00,0x4400,0x4400,0x4400,0x0000,0x0f80,0x0200,0x0200,0x0200,0x0200,0x0200,\n  0x0200,0x0000,0x0000,0x0000, // u2409\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x0000,0x0f80,0x0800,0x0800,0x0e00,0x0800,0x0800,\n  0x0800,0x0000,0x0000,0x0000, // u240a\n  0x0000,0x0000,0x4400,0x4400,0x4400,0x2800,0x2800,0x1000,0x1000,0x0000,0x0f80,0x0200,0x0200,0x0200,0x0200,0x0200,\n  0x0200,0x0000,0x0000,0x0000, // u240b\n  0x0000,0x0000,0x7c00,0x4000,0x4000,0x7000,0x4000,0x4000,0x4000,0x0000,0x0f80,0x0800,0x0800,0x0e00,0x0800,0x0800,\n  0x0800,0x0000,0x0000,0x0000, // u240c\n  0x0000,0x0000,0x3800,0x4400,0x4000,0x4000,0x4000,0x4400,0x3800,0x0000,0x0f00,0x0880,0x0880,0x0f00,0x0a00,0x0900,\n  0x0880,0x0000,0x0000,0x0000, // u240d\n  0x0000,0x0000,0x4400,0x4400,0x6400,0x5400,0x4c00,0x4400,0x4400,0x0000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0f80,0x0000,0x0000,0x0000, // u2424\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2500\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2501\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u2502\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2503\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xd680,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2508\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xd680,0xd680,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2509\n  0x0800,0x0800,0x0800,0x0800,0x0000,0x0800,0x0800,0x0800,0x0800,0x0000,0x0800,0x0800,0x0800,0x0800,0x0000,0x0800,\n  0x0800,0x0800,0x0800,0x0000, // u250a\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0000, // u250b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u250c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fc0,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u250d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u250e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u250f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u2510\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u2511\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2512\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2513\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2514\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2515\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2516\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2517\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2518\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2519\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u251a\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u251b\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0fc0,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u251c\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0fc0,0x0fc0,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u251d\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u251e\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u251f\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2520\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0fc0,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u2521\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0fc0,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2522\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2523\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xf800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u2524\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xf800,0xf800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u2525\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u2526\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2527\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2528\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u2529\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u252a\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u252b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u252c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xf800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u252d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0fc0,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u252e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u252f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2530\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2531\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2532\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2533\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2534\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2535\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2536\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2537\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2538\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2539\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u253a\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u253b\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u253c\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0xf800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u253d\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0x0fc0,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u253e\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0xffc0,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u253f\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u2540\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2541\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2542\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xf800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u2543\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0x0fc0,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u2544\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2545\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2546\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xffc0,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u2547\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2548\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2549\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u254a\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u254b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0000,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2550\n  0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x1400,0x1400,0x1400,0x1400, // u2551\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0800,0x0fc0,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u2552\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x1400,0x1400,0x1400,0x1400, // u2553\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x1000,0x17c0,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x1400,0x1400,0x1400,0x1400, // u2554\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0x0800,0xf800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u2555\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x1400,0x1400,0x1400,0x1400, // u2556\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x0400,0xf400,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x1400,0x1400,0x1400,0x1400, // u2557\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0fc0,0x0800,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2558\n  0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2559\n  0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x17c0,0x1000,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u255a\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xf800,0x0800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u255b\n  0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u255c\n  0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0xf400,0x0400,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u255d\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0fc0,0x0800,0x0fc0,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u255e\n  0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x17c0,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x1400,0x1400,0x1400,0x1400, // u255f\n  0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x17c0,0x1000,0x17c0,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x1400,0x1400,0x1400,0x1400, // u2560\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xf800,0x0800,0xf800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u2561\n  0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0xf400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x1400,0x1400,0x1400,0x1400, // u2562\n  0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0xf400,0x0400,0xf400,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x1400,0x1400,0x1400,0x1400, // u2563\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0000,0xffc0,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u2564\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x1400,0x1400,0x1400,0x1400, // u2565\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0000,0xf7c0,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x1400,0x1400,0x1400,0x1400, // u2566\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0x0000,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2567\n  0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2568\n  0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0xf7c0,0x0000,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2569\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0xffc0,0x0800,0xffc0,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u256a\n  0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0xffc0,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x1400,0x1400,0x1400,0x1400, // u256b\n  0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0x1400,0xf7c0,0x0000,0xf7c0,0x1400,0x1400,0x1400,0x1400,0x1400,\n  0x1400,0x1400,0x1400,0x1400, // u256c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x0200,0x0400,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u256d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0x2000,0x1000,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u256e\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1000,0x2000,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u256f\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0400,0x0200,0x01c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2570\n  0x0040,0x0040,0x0080,0x0080,0x0100,0x0100,0x0200,0x0200,0x0400,0x0400,0x0800,0x0800,0x1000,0x1000,0x2000,0x2000,\n  0x4000,0x4000,0x8000,0x8000, // u2571\n  0x8000,0x8000,0x4000,0x4000,0x2000,0x2000,0x1000,0x1000,0x0800,0x0800,0x0400,0x0400,0x0200,0x0200,0x0100,0x0100,\n  0x0080,0x0080,0x0040,0x0040, // u2572\n  0x8040,0x8040,0x4080,0x4080,0x2100,0x2100,0x1200,0x1200,0x0c00,0x0c00,0x0c00,0x0c00,0x1200,0x1200,0x2100,0x2100,\n  0x4080,0x4080,0x8040,0x8040, // u2573\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2574\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2575\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2576\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u2577\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2578\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2579\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u257a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u257b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u257c\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u257d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u257e\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800, // u257f\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2580\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0xffc0,0xffc0, // u2581\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0, // u2582\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0, // u2583\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0, // u2584\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0, // u2585\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0, // u2586\n  0x0000,0x0000,0x0000,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0, // u2587\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0, // u2588\n  0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,\n  0xff80,0xff80,0xff80,0xff80, // u2589\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,\n  0xfe00,0xfe00,0xfe00,0xfe00, // u258a\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,\n  0xfc00,0xfc00,0xfc00,0xfc00, // u258b\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800,0xf800,0xf800, // u258c\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,\n  0xf000,0xf000,0xf000,0xf000, // u258d\n  0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,\n  0xc000,0xc000,0xc000,0xc000, // u258e\n  0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,\n  0x8000,0x8000,0x8000,0x8000, // u258f\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,\n  0x07c0,0x07c0,0x07c0,0x07c0, // u2590\n  0xaa80,0x0000,0xaa80,0x0000,0xaa80,0x0000,0xaa80,0x0000,0xaa80,0x0000,0xaa80,0x0000,0xaa80,0x0000,0xaa80,0x0000,\n  0xaa80,0x0000,0xaa80,0x0000, // u2591\n  0xaa80,0x5540,0xaa80,0x5540,0xaa80,0x5540,0xaa80,0x5540,0xaa80,0x5540,0xaa80,0x5540,0xaa80,0x5540,0xaa80,0x5540,\n  0xaa80,0x5540,0xaa80,0x5540, // u2592\n  0xffc0,0xaa80,0xffc0,0xaa80,0xffc0,0xaa80,0xffc0,0xaa80,0xffc0,0xaa80,0xffc0,0xaa80,0xffc0,0xaa80,0xffc0,0xaa80,\n  0xffc0,0xaa80,0xffc0,0xaa80, // u2593\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800,0xf800,0xf800, // u2596\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,\n  0x07c0,0x07c0,0x07c0,0x07c0, // u2597\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2598\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0, // u2599\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,\n  0x07c0,0x07c0,0x07c0,0x07c0, // u259a\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800,0xf800,0xf800, // u259b\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,\n  0x07c0,0x07c0,0x07c0,0x07c0, // u259c\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u259d\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800,0xf800,0xf800, // u259e\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0, // u259f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x3e00,0x3e00,0x3e00,0x3e00,0x3e00,0x3e00,0x3e00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u25a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u25ac\n  0x0000,0x0000,0x0000,0x7f00,0x7f00,0x7f00,0x7f00,0x7f00,0x7f00,0x7f00,0x7f00,0x7f00,0x7f00,0x7f00,0x7f00,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u25ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x1c00,0x1c00,0x3e00,0x3e00,0x7f00,0x7f00,0xff80,0xff80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u25b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xffc0,0xff00,0xfc00,0xf000,0xc000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u25b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xffc0,0xff00,0xfc00,0xf000,0xc000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u25ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,0xff80,0x7f00,0x7f00,0x3e00,0x3e00,0x1c00,0x1c00,0x0800,0x0800,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u25bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x03c0,0x0fc0,0x3fc0,0xffc0,0x3fc0,0x0fc0,0x03c0,0x00c0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u25c0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x03c0,0x0fc0,0x3fc0,0xffc0,0x3fc0,0x0fc0,0x03c0,0x00c0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u25c4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x1c00,0x3e00,0x7f00,0xff80,0x7f00,0x3e00,0x1c00,0x0800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u25c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x1400,0x2200,0x4100,0x8080,0x4100,0x2200,0x1400,0x0800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u25ca\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x2100,0x2100,0x2100,0x1e00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u25cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3f00,0x3f00,0x3f00,0x3f00,0x1e00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u25cf\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xf3c0,0xe1c0,0xe1c0,0xf3c0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0, // u25d8\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xe1c0,0xdec0,0xdec0,0xdec0,0xdec0,0xe1c0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0, // u25d9\n  0x0000,0x0000,0x0000,0x7f00,0x8080,0x8080,0xb680,0xb680,0x8080,0x8080,0xbe80,0x9c80,0x8080,0x8080,0x8080,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u263a\n  0x0000,0x0000,0x0000,0x7f00,0xff80,0xff80,0xc980,0xc980,0xff80,0xff80,0xc180,0xe380,0xff80,0xff80,0xff80,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u263b\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x8880,0x4900,0x2a00,0x1c00,0xf780,0x1c00,0x2a00,0x4900,0x8880,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u263c\n  0x0000,0x0000,0x0000,0x3e00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x3e00,0x0800,0x0800,0x7f00,0x0800,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u2640\n  0x0000,0x0000,0x0000,0x0f80,0x0180,0x0280,0x0480,0x0880,0x7c00,0x8200,0x8200,0x8200,0x8200,0x8200,0x8200,0x7c00,\n  0x0000,0x0000,0x0000,0x0000, // u2642\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x1c00,0x3e00,0x7f00,0xff80,0xff80,0xff80,0xff80,0x6b00,0x0800,0x0800,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u2660\n  0x0000,0x0000,0x0000,0x1c00,0x3e00,0x3e00,0x1c00,0x0800,0x6b00,0xff80,0xff80,0xff80,0x6b00,0x0800,0x0800,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u2663\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0xf780,0xff80,0xff80,0xff80,0xff80,0x7f00,0x3e00,0x1c00,0x0800,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2665\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x1c00,0x3e00,0x7f00,0xff80,0x7f00,0x3e00,0x1c00,0x0800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2666\n  0x0000,0x0000,0x0000,0x1f80,0x1080,0x1080,0x1f80,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0xe000,\n  0x0000,0x0000,0x0000,0x0000, // u266a\n  0x0000,0x0000,0x0000,0x7f00,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4200,0x8000,\n  0x0000,0x0000,0x0000,0x0000, // u266b\n  0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0100,0x0100,0x8200,0x8200,0x4400,0x4400,0x2800,0x2800,0x1000,0x1000,\n  0x0000,0x0000,0x0000,0x0000, // u2713\n  0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x0180,0x0180,0xc300,0xc300,0x6600,0x6600,0x3c00,0x3c00,0x1800,0x1800,\n  0x0000,0x0000,0x0000,0x0000, // u2714\n  0x0000,0x0000,0x0000,0x0000,0x0200,0x4200,0x2400,0x1400,0x0800,0x0c00,0x1200,0x1100,0x2000,0x2000,0x4000,0x4000,\n  0x0000,0x0000,0x0000,0x0000, // u2717\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x6300,0x3600,0x1e00,0x0c00,0x0e00,0x1b00,0x1980,0x3000,0x3000,0x6000,0x6000,\n  0x0000,0x0000,0x0000,0x0000, // u2718\n  0x0000,0x0000,0x0000,0x0200,0x0200,0x0400,0x0400,0x0800,0x0800,0x1000,0x0800,0x0800,0x0400,0x0400,0x0200,0x0200,\n  0x0000,0x0000,0x0000,0x0000, // u27e8\n  0x0000,0x0000,0x0000,0x1000,0x1000,0x0800,0x0800,0x0400,0x0400,0x0200,0x0400,0x0400,0x0800,0x0800,0x1000,0x1000,\n  0x0000,0x0000,0x0000,0x0000, // u27e9\n  0x0000,0x0000,0x0000,0x0880,0x0880,0x1100,0x1100,0x2200,0x2200,0x4400,0x2200,0x2200,0x1100,0x1100,0x0880,0x0880,\n  0x0000,0x0000,0x0000,0x0000, // u27ea\n  0x0000,0x0000,0x0000,0x4400,0x4400,0x2200,0x2200,0x1100,0x1100,0x0880,0x1100,0x1100,0x2200,0x2200,0x4400,0x4400,\n  0x0000,0x0000,0x0000,0x0000, // u27eb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2800\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2801\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2802\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2803\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2804\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2805\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2806\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2807\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2808\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2809\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u280a\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u280b\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u280c\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u280d\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u280e\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u280f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2810\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2811\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2812\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2813\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2814\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2815\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2816\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2817\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2818\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2819\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u281a\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u281b\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u281c\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u281d\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u281e\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u281f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2820\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2821\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2822\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2823\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2824\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2825\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2826\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2827\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2828\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2829\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u282a\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u282b\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u282c\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u282d\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u282e\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u282f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2830\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2831\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2832\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2833\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2834\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2835\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2836\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2837\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2838\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2839\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u283a\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u283b\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u283c\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u283d\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u283e\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u283f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2840\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2841\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2842\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2843\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2844\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2845\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2846\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2847\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2848\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2849\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u284a\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u284b\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u284c\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u284d\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u284e\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u284f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2850\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2851\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2852\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2853\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2854\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2855\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2856\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2857\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2858\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2859\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u285a\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u285b\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u285c\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u285d\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u285e\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u285f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2860\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2861\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2862\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2863\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2864\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2865\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2866\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2867\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2868\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2869\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u286a\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u286b\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u286c\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u286d\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u286e\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u286f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2870\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2871\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2872\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2873\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2874\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2875\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2876\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2877\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2878\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u2879\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u287a\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u287b\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u287c\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u287d\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u287e\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2000,0x2000,0x0000,0x0000, // u287f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u2880\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u2881\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u2882\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u2883\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u2884\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u2885\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u2886\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u2887\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u2888\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u2889\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u288a\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u288b\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u288c\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u288d\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u288e\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u288f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u2890\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u2891\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u2892\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u2893\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u2894\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u2895\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u2896\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u2897\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u2898\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u2899\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u289a\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u289b\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u289c\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u289d\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u289e\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u289f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28a0\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28a2\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28a4\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28a5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28a6\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28a7\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28a8\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28a9\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28aa\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28ab\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28ac\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28ad\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28ae\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28af\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28b0\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28b1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28b2\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28b4\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28b6\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28b7\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28b8\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28b9\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28ba\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28bb\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28bc\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28bd\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28be\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x0100,0x0100,0x0000,0x0000, // u28bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28c0\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28c2\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28c4\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28c6\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28c7\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28c8\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28c9\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28ca\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28cb\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28cc\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28cd\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28ce\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28cf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28d0\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28d2\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28d4\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28d6\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28d7\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28d8\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28d9\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28da\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28db\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28dc\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28dd\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28de\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28df\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28e0\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28e1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28e2\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28e3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28e4\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28e6\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28e7\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28e8\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28e9\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28ea\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28eb\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28ec\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28ed\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28ee\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28ef\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28f0\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28f2\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28f3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28f4\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28f6\n  0x0000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28f7\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28f8\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28f9\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28fa\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28fb\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28fc\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28fd\n  0x0000,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28fe\n  0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x0000,0x0000,0x0000,\n  0x2100,0x2100,0x0000,0x0000, // u28ff\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x0000,0x0000,0x0000,0x0000,0x4100,0x4100,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2e2c\n  0x8000,0x8000,0x8400,0x8e00,0x9500,0xa480,0x8400,0x8400,0x8400,0x8400,0x8800,0x1000,0x2000,0x4000,0x8000,0x8000,\n  0x8000,0x8000,0x8000,0x8000, // ue0a0\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x0000,0x0880,0x0880,0x0c80,0x0a80,0x0980,0x0880,\n  0x0880,0x0000,0x0000,0x0000, // ue0a1\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x2100,0x2100,0x2100,0x2100,0x7f80,0x7f80,0x7380,0x6180,0x7380,0x7f80,0x7f80,\n  0x7f80,0x0000,0x0000,0x0000, // ue0a2\n  0x8000,0xc000,0xe000,0xf000,0xf800,0xfc00,0xfe00,0xff00,0xff80,0xffc0,0xffc0,0xff80,0xff00,0xfe00,0xfc00,0xf800,\n  0xf000,0xe000,0xc000,0x8000, // ue0b0\n  0x8000,0x4000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,0x0080,0x0040,0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,\n  0x1000,0x2000,0x4000,0x8000, // ue0b1\n  0x0040,0x00c0,0x01c0,0x03c0,0x07c0,0x0fc0,0x1fc0,0x3fc0,0x7fc0,0xffc0,0xffc0,0x7fc0,0x3fc0,0x1fc0,0x0fc0,0x07c0,\n  0x03c0,0x01c0,0x00c0,0x0040, // ue0b2\n  0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000,0x8000,0x4000,0x2000,0x1000,0x0800,0x0400,\n  0x0200,0x0100,0x0080,0x0040, // ue0b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,\n  0x2200,0x2200,0x1c00,0x0000, // uf6be\n  0x0000,0x0000,0x0000,0x7f00,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,\n  0x0000,0x0000,0x0000,0x0000 // ufffd\n  };\n  // codepoints array\n  constexpr std::array<uint16_t, CHARCOUNT> fixedfont_codepoints = {\n  0x0000,0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,\n  0x002f,0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,\n  0x003f,0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,\n  0x004f,0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,\n  0x005f,0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,\n  0x006f,0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,\n  0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af,\n  0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf,\n  0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf,\n  0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df,\n  0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef,\n  0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff,\n  0x0100,0x0101,0x0102,0x0103,0x0104,0x0105,0x0106,0x0107,0x0108,0x0109,0x010a,0x010b,0x010c,0x010d,0x010e,0x010f,\n  0x0110,0x0111,0x0112,0x0113,0x0114,0x0115,0x0116,0x0117,0x0118,0x0119,0x011a,0x011b,0x011c,0x011d,0x011e,0x011f,\n  0x0120,0x0121,0x0122,0x0123,0x0124,0x0125,0x0126,0x0127,0x0128,0x0129,0x012a,0x012b,0x012c,0x012d,0x012e,0x012f,\n  0x0130,0x0131,0x0132,0x0133,0x0134,0x0135,0x0136,0x0137,0x0138,0x0139,0x013a,0x013b,0x013c,0x013d,0x013e,0x013f,\n  0x0140,0x0141,0x0142,0x0143,0x0144,0x0145,0x0146,0x0147,0x0148,0x0149,0x014a,0x014b,0x014c,0x014d,0x014e,0x014f,\n  0x0150,0x0151,0x0152,0x0153,0x0154,0x0155,0x0156,0x0157,0x0158,0x0159,0x015a,0x015b,0x015c,0x015d,0x015e,0x015f,\n  0x0160,0x0161,0x0162,0x0163,0x0164,0x0165,0x0166,0x0167,0x0168,0x0169,0x016a,0x016b,0x016c,0x016d,0x016e,0x016f,\n  0x0170,0x0171,0x0172,0x0173,0x0174,0x0175,0x0176,0x0177,0x0178,0x0179,0x017a,0x017b,0x017c,0x017d,0x017e,0x017f,\n  0x0186,0x018e,0x018f,0x0190,0x0192,0x019d,0x019e,0x01b5,0x01b6,0x01b7,0x01cd,0x01ce,0x01cf,0x01d0,0x01d1,0x01d2,\n  0x01d3,0x01d4,0x01e2,0x01e3,0x01e4,0x01e5,0x01e6,0x01e7,0x01e8,0x01e9,0x01ea,0x01eb,0x01ec,0x01ed,0x01ee,0x01ef,\n  0x01f0,0x01f4,0x01f5,0x01fc,0x01fd,0x01fe,0x01ff,0x0218,0x0219,0x021a,0x021b,0x0232,0x0233,0x0237,0x0254,0x0258,\n  0x0259,0x025b,0x0272,0x0292,0x02bb,0x02bc,0x02bd,0x02c6,0x02c7,0x02d8,0x02d9,0x02db,0x02dc,0x02dd,0x0300,0x0301,\n  0x0302,0x0303,0x0304,0x0305,0x0306,0x0307,0x0308,0x030a,0x030b,0x030c,0x0329,0x0384,0x0385,0x0386,0x0387,0x0388,\n  0x0389,0x038a,0x038c,0x038e,0x038f,0x0390,0x0391,0x0392,0x0393,0x0394,0x0395,0x0396,0x0397,0x0398,0x0399,0x039a,\n  0x039b,0x039c,0x039d,0x039e,0x039f,0x03a0,0x03a1,0x03a3,0x03a4,0x03a5,0x03a6,0x03a7,0x03a8,0x03a9,0x03aa,0x03ab,\n  0x03ac,0x03ad,0x03ae,0x03af,0x03b0,0x03b1,0x03b2,0x03b3,0x03b4,0x03b5,0x03b6,0x03b7,0x03b8,0x03b9,0x03ba,0x03bb,\n  0x03bc,0x03bd,0x03be,0x03bf,0x03c0,0x03c1,0x03c2,0x03c3,0x03c4,0x03c5,0x03c6,0x03c7,0x03c8,0x03c9,0x03ca,0x03cb,\n  0x03cc,0x03cd,0x03ce,0x03d1,0x03d5,0x03f0,0x03f1,0x03f2,0x03f3,0x03f4,0x03f5,0x03f6,0x0400,0x0401,0x0402,0x0403,\n  0x0404,0x0405,0x0406,0x0407,0x0408,0x0409,0x040a,0x040b,0x040c,0x040d,0x040e,0x040f,0x0410,0x0411,0x0412,0x0413,\n  0x0414,0x0415,0x0416,0x0417,0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e,0x041f,0x0420,0x0421,0x0422,0x0423,\n  0x0424,0x0425,0x0426,0x0427,0x0428,0x0429,0x042a,0x042b,0x042c,0x042d,0x042e,0x042f,0x0430,0x0431,0x0432,0x0433,\n  0x0434,0x0435,0x0436,0x0437,0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e,0x043f,0x0440,0x0441,0x0442,0x0443,\n  0x0444,0x0445,0x0446,0x0447,0x0448,0x0449,0x044a,0x044b,0x044c,0x044d,0x044e,0x044f,0x0450,0x0451,0x0452,0x0453,\n  0x0454,0x0455,0x0456,0x0457,0x0458,0x0459,0x045a,0x045b,0x045c,0x045d,0x045e,0x045f,0x0462,0x0463,0x046a,0x046b,\n  0x0490,0x0491,0x0492,0x0493,0x0494,0x0495,0x0496,0x0497,0x0498,0x0499,0x049a,0x049b,0x049c,0x049d,0x04a0,0x04a1,\n  0x04a2,0x04a3,0x04a4,0x04a5,0x04aa,0x04ab,0x04ae,0x04af,0x04b0,0x04b1,0x04b2,0x04b3,0x04b6,0x04b7,0x04b8,0x04b9,\n  0x04ba,0x04bb,0x04c0,0x04c1,0x04c2,0x04cf,0x04d0,0x04d1,0x04d2,0x04d3,0x04d4,0x04d5,0x04d6,0x04d7,0x04d8,0x04d9,\n  0x04da,0x04db,0x04dc,0x04dd,0x04de,0x04df,0x04e2,0x04e3,0x04e4,0x04e5,0x04e6,0x04e7,0x04e8,0x04e9,0x04ea,0x04eb,\n  0x04ec,0x04ed,0x04ee,0x04ef,0x04f0,0x04f1,0x04f2,0x04f3,0x04f4,0x04f5,0x04f8,0x04f9,0x05d0,0x05d1,0x05d2,0x05d3,\n  0x05d4,0x05d5,0x05d6,0x05d7,0x05d8,0x05d9,0x05da,0x05db,0x05dc,0x05dd,0x05de,0x05df,0x05e0,0x05e1,0x05e2,0x05e3,\n  0x05e4,0x05e5,0x05e6,0x05e7,0x05e8,0x05e9,0x05ea,0x1e0c,0x1e0d,0x1e34,0x1e35,0x1e36,0x1e37,0x1e40,0x1e41,0x1e42,\n  0x1e43,0x1e44,0x1e45,0x1e46,0x1e47,0x1e6c,0x1e6d,0x1eb8,0x1eb9,0x1ebc,0x1ebd,0x1eca,0x1ecb,0x1ecc,0x1ecd,0x1ee4,\n  0x1ee5,0x1ef8,0x1ef9,0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007,0x2008,0x2009,0x200a,0x200b,0x200c,\n  0x200d,0x200e,0x200f,0x2010,0x2011,0x2012,0x2013,0x2014,0x2015,0x2016,0x2017,0x2018,0x2019,0x201a,0x201b,0x201c,\n  0x201d,0x201e,0x201f,0x2020,0x2021,0x2022,0x2026,0x2030,0x2032,0x2033,0x2039,0x203a,0x203c,0x203e,0x2070,0x2071,\n  0x2074,0x2075,0x2076,0x2077,0x2078,0x2079,0x207a,0x207b,0x207c,0x207d,0x207e,0x207f,0x2080,0x2081,0x2082,0x2083,\n  0x2084,0x2085,0x2086,0x2087,0x2088,0x2089,0x208a,0x208b,0x208c,0x208d,0x208e,0x2090,0x2091,0x2092,0x2093,0x2094,\n  0x2095,0x2096,0x2097,0x2098,0x209a,0x20a7,0x20aa,0x20ac,0x20ae,0x2102,0x210e,0x210f,0x2115,0x2116,0x211a,0x211d,\n  0x2122,0x2124,0x2126,0x2135,0x2190,0x2191,0x2192,0x2193,0x2194,0x2195,0x21a4,0x21a6,0x21a8,0x21b5,0x21bb,0x21cb,\n  0x21cc,0x21d0,0x21d1,0x21d2,0x21d3,0x21d4,0x21d5,0x2200,0x2203,0x2204,0x2205,0x2206,0x2207,0x2208,0x2209,0x220a,\n  0x220b,0x220c,0x220d,0x2212,0x2213,0x2214,0x2215,0x2216,0x2219,0x221a,0x221e,0x221f,0x2225,0x2227,0x2228,0x2229,\n  0x222a,0x2248,0x2260,0x2261,0x2264,0x2265,0x226a,0x226b,0x2282,0x2283,0x2286,0x2287,0x22a5,0x22c2,0x22c3,0x2300,\n  0x2302,0x2308,0x2309,0x230a,0x230b,0x2310,0x2319,0x2320,0x2321,0x239b,0x239c,0x239d,0x239e,0x239f,0x23a0,0x23a1,\n  0x23a2,0x23a3,0x23a4,0x23a5,0x23a6,0x23a7,0x23a8,0x23a9,0x23ab,0x23ac,0x23ad,0x23ae,0x23af,0x23ba,0x23bb,0x23bc,\n  0x23bd,0x23d0,0x2409,0x240a,0x240b,0x240c,0x240d,0x2424,0x2500,0x2501,0x2502,0x2503,0x2508,0x2509,0x250a,0x250b,\n  0x250c,0x250d,0x250e,0x250f,0x2510,0x2511,0x2512,0x2513,0x2514,0x2515,0x2516,0x2517,0x2518,0x2519,0x251a,0x251b,\n  0x251c,0x251d,0x251e,0x251f,0x2520,0x2521,0x2522,0x2523,0x2524,0x2525,0x2526,0x2527,0x2528,0x2529,0x252a,0x252b,\n  0x252c,0x252d,0x252e,0x252f,0x2530,0x2531,0x2532,0x2533,0x2534,0x2535,0x2536,0x2537,0x2538,0x2539,0x253a,0x253b,\n  0x253c,0x253d,0x253e,0x253f,0x2540,0x2541,0x2542,0x2543,0x2544,0x2545,0x2546,0x2547,0x2548,0x2549,0x254a,0x254b,\n  0x2550,0x2551,0x2552,0x2553,0x2554,0x2555,0x2556,0x2557,0x2558,0x2559,0x255a,0x255b,0x255c,0x255d,0x255e,0x255f,\n  0x2560,0x2561,0x2562,0x2563,0x2564,0x2565,0x2566,0x2567,0x2568,0x2569,0x256a,0x256b,0x256c,0x256d,0x256e,0x256f,\n  0x2570,0x2571,0x2572,0x2573,0x2574,0x2575,0x2576,0x2577,0x2578,0x2579,0x257a,0x257b,0x257c,0x257d,0x257e,0x257f,\n  0x2580,0x2581,0x2582,0x2583,0x2584,0x2585,0x2586,0x2587,0x2588,0x2589,0x258a,0x258b,0x258c,0x258d,0x258e,0x258f,\n  0x2590,0x2591,0x2592,0x2593,0x2596,0x2597,0x2598,0x2599,0x259a,0x259b,0x259c,0x259d,0x259e,0x259f,0x25a0,0x25ac,\n  0x25ae,0x25b2,0x25b6,0x25ba,0x25bc,0x25c0,0x25c4,0x25c6,0x25ca,0x25cb,0x25cf,0x25d8,0x25d9,0x263a,0x263b,0x263c,\n  0x2640,0x2642,0x2660,0x2663,0x2665,0x2666,0x266a,0x266b,0x2713,0x2714,0x2717,0x2718,0x27e8,0x27e9,0x27ea,0x27eb,\n  0x2800,0x2801,0x2802,0x2803,0x2804,0x2805,0x2806,0x2807,0x2808,0x2809,0x280a,0x280b,0x280c,0x280d,0x280e,0x280f,\n  0x2810,0x2811,0x2812,0x2813,0x2814,0x2815,0x2816,0x2817,0x2818,0x2819,0x281a,0x281b,0x281c,0x281d,0x281e,0x281f,\n  0x2820,0x2821,0x2822,0x2823,0x2824,0x2825,0x2826,0x2827,0x2828,0x2829,0x282a,0x282b,0x282c,0x282d,0x282e,0x282f,\n  0x2830,0x2831,0x2832,0x2833,0x2834,0x2835,0x2836,0x2837,0x2838,0x2839,0x283a,0x283b,0x283c,0x283d,0x283e,0x283f,\n  0x2840,0x2841,0x2842,0x2843,0x2844,0x2845,0x2846,0x2847,0x2848,0x2849,0x284a,0x284b,0x284c,0x284d,0x284e,0x284f,\n  0x2850,0x2851,0x2852,0x2853,0x2854,0x2855,0x2856,0x2857,0x2858,0x2859,0x285a,0x285b,0x285c,0x285d,0x285e,0x285f,\n  0x2860,0x2861,0x2862,0x2863,0x2864,0x2865,0x2866,0x2867,0x2868,0x2869,0x286a,0x286b,0x286c,0x286d,0x286e,0x286f,\n  0x2870,0x2871,0x2872,0x2873,0x2874,0x2875,0x2876,0x2877,0x2878,0x2879,0x287a,0x287b,0x287c,0x287d,0x287e,0x287f,\n  0x2880,0x2881,0x2882,0x2883,0x2884,0x2885,0x2886,0x2887,0x2888,0x2889,0x288a,0x288b,0x288c,0x288d,0x288e,0x288f,\n  0x2890,0x2891,0x2892,0x2893,0x2894,0x2895,0x2896,0x2897,0x2898,0x2899,0x289a,0x289b,0x289c,0x289d,0x289e,0x289f,\n  0x28a0,0x28a1,0x28a2,0x28a3,0x28a4,0x28a5,0x28a6,0x28a7,0x28a8,0x28a9,0x28aa,0x28ab,0x28ac,0x28ad,0x28ae,0x28af,\n  0x28b0,0x28b1,0x28b2,0x28b3,0x28b4,0x28b5,0x28b6,0x28b7,0x28b8,0x28b9,0x28ba,0x28bb,0x28bc,0x28bd,0x28be,0x28bf,\n  0x28c0,0x28c1,0x28c2,0x28c3,0x28c4,0x28c5,0x28c6,0x28c7,0x28c8,0x28c9,0x28ca,0x28cb,0x28cc,0x28cd,0x28ce,0x28cf,\n  0x28d0,0x28d1,0x28d2,0x28d3,0x28d4,0x28d5,0x28d6,0x28d7,0x28d8,0x28d9,0x28da,0x28db,0x28dc,0x28dd,0x28de,0x28df,\n  0x28e0,0x28e1,0x28e2,0x28e3,0x28e4,0x28e5,0x28e6,0x28e7,0x28e8,0x28e9,0x28ea,0x28eb,0x28ec,0x28ed,0x28ee,0x28ef,\n  0x28f0,0x28f1,0x28f2,0x28f3,0x28f4,0x28f5,0x28f6,0x28f7,0x28f8,0x28f9,0x28fa,0x28fb,0x28fc,0x28fd,0x28fe,0x28ff,\n  0x2e2c,0xe0a0,0xe0a1,0xe0a2,0xe0b0,0xe0b1,0xe0b2,0xe0b3,0xf6be,0xfffd };\n} // namespace\n// -- end of autogenerated text ---\n\nnamespace fixed_font_20b {\n  // -- start of autogenerated text ---\n  // definition section for font: ter-u20b.bdf\n  constexpr int CHARCOUNT = 1354;\n  constexpr int WIDTH = 10;\n  constexpr int HEIGHT = 20;\n  constexpr int OFFSET_X = 0;\n  constexpr int OFFSET_Y = 0;\n  constexpr FixedFont_info_t fixedfont_info = {\n    \"Terminus\", // font name\n    \"ter-u20b.bdf\", // font name internal\n    CHARCOUNT, // num of chars\n    WIDTH, HEIGHT, OFFSET_X, OFFSET_Y,\n    true // bold\n  };\n  // font bitmap definitions\n  constexpr std::array<uint16_t, CHARCOUNT * HEIGHT> fixedfont_bitmap = {\n  0x0000,0x0000,0x0000,0x7380,0x6180,0x6180,0x0000,0x0000,0x6180,0x6180,0x6180,0x0000,0x0000,0x6180,0x6180,0x7380,\n  0x0000,0x0000,0x0000,0x0000, // u0000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0020\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u0021\n  0x0000,0x3300,0x3300,0x3300,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0022\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x3300,0x3300,0x7f80,0x3300,0x3300,0x3300,0x7f80,0x3300,0x3300,0x3300,0x3300,\n  0x0000,0x0000,0x0000,0x0000, // u0023\n  0x0000,0x0000,0x0c00,0x0c00,0x3f00,0x6d80,0x6c00,0x6c00,0x6c00,0x3f00,0x0d80,0x0d80,0x0d80,0x6d80,0x3f00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000, // u0024\n  0x0000,0x0000,0x0000,0x0000,0x7300,0x5300,0x7600,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x3700,0x6500,0x6700,\n  0x0000,0x0000,0x0000,0x0000, // u0025\n  0x0000,0x0000,0x0000,0x3c00,0x6600,0x6600,0x6600,0x3c00,0x1800,0x3980,0x6d80,0xc700,0xc300,0xc300,0x6780,0x3d80,\n  0x0000,0x0000,0x0000,0x0000, // u0026\n  0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0027\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0c00,0x0c00,0x0600,\n  0x0000,0x0000,0x0000,0x0000, // u0028\n  0x0000,0x0000,0x0000,0x1800,0x0c00,0x0c00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0c00,0x0c00,0x1800,\n  0x0000,0x0000,0x0000,0x0000, // u0029\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x3600,0x1c00,0xff80,0x1c00,0x3600,0x6300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u002a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u002b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,\n  0x1800,0x0000,0x0000,0x0000, // u002c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u002d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u002e\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x6000,0x6000,\n  0x0000,0x0000,0x0000,0x0000, // u002f\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6380,0x6780,0x6d80,0x7980,0x7180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0030\n  0x0000,0x0000,0x0000,0x0c00,0x1c00,0x3c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0031\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x0180,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u0032\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x0180,0x0180,0x0180,0x1f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0033\n  0x0000,0x0000,0x0000,0x0180,0x0380,0x0780,0x0d80,0x1980,0x3180,0x6180,0x6180,0x6180,0x7f80,0x0180,0x0180,0x0180,\n  0x0000,0x0000,0x0000,0x0000, // u0034\n  0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x7f00,0x0180,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0035\n  0x0000,0x0000,0x0000,0x1f00,0x3000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0036\n  0x0000,0x0000,0x0000,0x7f80,0x6180,0x6180,0x0180,0x0300,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u0037\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0038\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,0x0180,0x0180,0x0300,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u003a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,\n  0x1800,0x0000,0x0000,0x0000, // u003b\n  0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,\n  0x0000,0x0000,0x0000,0x0000, // u003c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u003d\n  0x0000,0x0000,0x0000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,\n  0x0000,0x0000,0x0000,0x0000, // u003e\n  0x0000,0x0000,0x0000,0x1e00,0x3300,0x6180,0x6180,0x0180,0x0300,0x0600,0x0c00,0x0c00,0x0000,0x0000,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u003f\n  0x0000,0x0000,0x0000,0x7f00,0xc180,0xc180,0xcf80,0xd980,0xd980,0xd980,0xd980,0xd980,0xcf80,0xc000,0xc000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u0040\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0041\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u0042\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0043\n  0x0000,0x0000,0x0000,0x7e00,0x6300,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6300,0x7e00,\n  0x0000,0x0000,0x0000,0x0000, // u0044\n  0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u0045\n  0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x0000,0x0000,0x0000,0x0000, // u0046\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6780,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0047\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0048\n  0x0000,0x0000,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u0049\n  0x0000,0x0000,0x0000,0x0780,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x6300,0x6300,0x6300,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u004a\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7000,0x7800,0x6c00,0x6600,0x6300,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u004b\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u004c\n  0x0000,0x0000,0x0000,0x8080,0xc180,0xe380,0xf780,0xdd80,0xc980,0xc180,0xc180,0xc180,0xc180,0xc180,0xc180,0xc180,\n  0x0000,0x0000,0x0000,0x0000, // u004d\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x7180,0x7980,0x6d80,0x6780,0x6380,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u004e\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u004f\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x0000,0x0000,0x0000,0x0000, // u0050\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6780,0x3f00,\n  0x0300,0x0180,0x0000,0x0000, // u0051\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x7800,0x6c00,0x6600,0x6300,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0052\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x3f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0053\n  0x0000,0x0000,0x0000,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u0054\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0055\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x3300,0x3300,0x3300,0x1e00,0x1e00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u0056\n  0x0000,0x0000,0x0000,0xc180,0xc180,0xc180,0xc180,0xc180,0xc180,0xc180,0xc980,0xdd80,0xf780,0xe380,0xc180,0x8080,\n  0x0000,0x0000,0x0000,0x0000, // u0057\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x1e00,0x3300,0x3300,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0058\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u0059\n  0x0000,0x0000,0x0000,0x7f80,0x0180,0x0180,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u005a\n  0x0000,0x0000,0x0000,0x1e00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u005b\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x3000,0x3000,0x1800,0x1800,0x0c00,0x0c00,0x0600,0x0600,0x0300,0x0300,\n  0x0000,0x0000,0x0000,0x0000, // u005c\n  0x0000,0x0000,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u005d\n  0x0000,0x0c00,0x1e00,0x3300,0x6180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u005e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x7f80,0x0000,0x0000, // u005f\n  0x1800,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0060\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u0061\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u0062\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0063\n  0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u0064\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0065\n  0x0000,0x0000,0x0000,0x0780,0x0c00,0x0c00,0x0c00,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u0066\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0180,0x0180,0x3f00,0x0000, // u0067\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0068\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u0069\n  0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0700,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x3300,0x3300,0x1e00,0x0000, // u006a\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6180,0x6300,0x6600,0x6c00,0x7800,0x6c00,0x6600,0x6300,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u006b\n  0x0000,0x0000,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u006c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,\n  0x0000,0x0000,0x0000,0x0000, // u006d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u006e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u006f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,\n  0x6000,0x6000,0x6000,0x0000, // u0070\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0180,0x0180,0x0180,0x0000, // u0071\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6f80,0x7800,0x7000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x0000,0x0000,0x0000,0x0000, // u0072\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x6000,0x3f00,0x0180,0x0180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0073\n  0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x7e00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0f00,\n  0x0000,0x0000,0x0000,0x0000, // u0074\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u0075\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u0076\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0077\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x3300,0x1e00,0x0c00,0x1e00,0x3300,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0078\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0180,0x0180,0x3f00,0x0000, // u0079\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u007a\n  0x0000,0x0000,0x0000,0x0700,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x3800,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0700,\n  0x0000,0x0000,0x0000,0x0000, // u007b\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u007c\n  0x0000,0x0000,0x0000,0x3800,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0700,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x3800,\n  0x0000,0x0000,0x0000,0x0000, // u007d\n  0x0000,0x3980,0x6d80,0x6d80,0x6700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u007e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00a0\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u00a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x3f00,0x6d80,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6d80,0x3f00,\n  0x0c00,0x0c00,0x0000,0x0000, // u00a2\n  0x0000,0x0000,0x0000,0x1e00,0x3300,0x3000,0x3000,0x3000,0x3000,0x7e00,0x3000,0x3000,0x3000,0x3000,0x3180,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u00a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc180,0x6300,0x3e00,0x6300,0x6300,0x6300,0x6300,0x3e00,0x6300,0xc180,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00a4\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x1e00,0x0c00,0x3f00,0x0c00,0x3f00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u00a5\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u00a6\n  0x0000,0x0000,0x1e00,0x3300,0x3000,0x3000,0x1c00,0x3600,0x3300,0x3300,0x3300,0x1b00,0x0e00,0x0300,0x0300,0x3300,\n  0x1e00,0x0000,0x0000,0x0000, // u00a7\n  0x3300,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00a8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x4080,0x9e40,0xb340,0xb040,0xb040,0xb340,0x9e40,0x4080,0x3f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00a9\n  0x0000,0x3e00,0x0300,0x3f00,0x6300,0x6300,0x6300,0x3f00,0x0000,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0cc0,0x1980,0x3300,0x6600,0xcc00,0x6600,0x3300,0x1980,0x0cc0,\n  0x0000,0x0000,0x0000,0x0000, // u00ab\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00ac\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00ad\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x4080,0xbe40,0xb340,0xb340,0xbe40,0xb640,0xb340,0x4080,0x3f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00ae\n  0x0000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00af\n  0x0000,0x1e00,0x3300,0x3300,0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u00b1\n  0x0000,0x1e00,0x3300,0x3300,0x0600,0x0c00,0x1800,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00b2\n  0x0000,0x1e00,0x3300,0x0300,0x0e00,0x0300,0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00b3\n  0x0600,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6380,0x7d80,\n  0x6000,0x6000,0x6000,0x0000, // u00b5\n  0x0000,0x0000,0x0000,0x3f80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3d80,0x0d80,0x0d80,0x0d80,0x0d80,0x0d80,0x0d80,\n  0x0000,0x0000,0x0000,0x0000, // u00b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00b7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0c00,0x0c00,0x1800,0x0000, // u00b8\n  0x0000,0x0c00,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00b9\n  0x0000,0x3e00,0x6300,0x6300,0x6300,0x6300,0x6300,0x3e00,0x0000,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xcc00,0x6600,0x3300,0x1980,0x0cc0,0x1980,0x3300,0x6600,0xcc00,\n  0x0000,0x0000,0x0000,0x0000, // u00bb\n  0x0000,0x0000,0x3000,0x7000,0x3000,0x3080,0x3180,0x3300,0x0600,0x0c00,0x1980,0x3380,0x6780,0xcd80,0x8f80,0x0180,\n  0x0180,0x0000,0x0000,0x0000, // u00bc\n  0x0000,0x0000,0x3000,0x7000,0x3000,0x3080,0x3180,0x3300,0x0600,0x0c00,0x1800,0x3700,0x6d80,0xc180,0x8300,0x0600,\n  0x0f80,0x0000,0x0000,0x0000, // u00bd\n  0x0000,0x0000,0xf000,0x1800,0x7000,0x1880,0x1980,0xf300,0x0600,0x0c00,0x1980,0x3380,0x6780,0xcd80,0x8f80,0x0180,\n  0x0180,0x0000,0x0000,0x0000, // u00be\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0000,0x0c00,0x0c00,0x1800,0x3000,0x6000,0x6180,0x6180,0x3300,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u00bf\n  0x1800,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u00c0\n  0x0600,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u00c1\n  0x1e00,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u00c2\n  0x3b80,0x6e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u00c3\n  0x3300,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u00c4\n  0x1e00,0x3300,0x1e00,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u00c5\n  0x0000,0x0000,0x0000,0x7fc0,0xc600,0xc600,0xc600,0xc600,0xc600,0xffc0,0xc600,0xc600,0xc600,0xc600,0xc600,0xc7c0,\n  0x0000,0x0000,0x0000,0x0000, // u00c6\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x6180,0x3f00,\n  0x0c00,0x0c00,0x1800,0x0000, // u00c7\n  0x1800,0x0c00,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u00c8\n  0x0600,0x0c00,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u00c9\n  0x1e00,0x3300,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u00ca\n  0x3300,0x3300,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u00cb\n  0x1800,0x0c00,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u00cc\n  0x0600,0x0c00,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u00cd\n  0x1e00,0x3300,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u00ce\n  0x3300,0x3300,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u00cf\n  0x0000,0x0000,0x0000,0x7e00,0x6300,0x6180,0x6180,0x6180,0x6180,0xfd80,0x6180,0x6180,0x6180,0x6180,0x6300,0x7e00,\n  0x0000,0x0000,0x0000,0x0000, // u00d0\n  0x3b80,0x6e00,0x0000,0x6180,0x6180,0x6180,0x6180,0x7180,0x7980,0x6d80,0x6780,0x6380,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u00d1\n  0x1800,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00d2\n  0x0600,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00d3\n  0x1e00,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00d4\n  0x3b80,0x6e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00d5\n  0x3300,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00d6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x3300,0x1e00,0x0c00,0x1e00,0x3300,0x6180,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00d7\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x61c0,0x6180,0x6380,0x6780,0x6d80,0x7980,0x7180,0x6180,0xe180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00d8\n  0x1800,0x0c00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00d9\n  0x0600,0x0c00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00da\n  0x1e00,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00db\n  0x3300,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00dc\n  0x0600,0x0c00,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u00dd\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x6000,0x6000,0x6000,\n  0x0000,0x0000,0x0000,0x0000, // u00de\n  0x0000,0x0000,0x0000,0x3e00,0x6300,0x6300,0x6300,0x6200,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7180,0x6f00,\n  0x0000,0x0000,0x0000,0x0000, // u00df\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x0c00,0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u00e0\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u00e1\n  0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u00e2\n  0x0000,0x0000,0x0000,0x0000,0x3b80,0x6e00,0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u00e3\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u00e4\n  0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x1e00,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u00e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7b80,0x0cc0,0x0cc0,0x7cc0,0xcfc0,0xcc00,0xcc00,0xccc0,0x7780,\n  0x0000,0x0000,0x0000,0x0000, // u00e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x3f00,\n  0x0c00,0x0c00,0x1800,0x0000, // u00e7\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00e8\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00e9\n  0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00ea\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00eb\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x0c00,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u00ec\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u00ed\n  0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u00ee\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u00ef\n  0x0000,0x0000,0x0000,0x3600,0x3c00,0x6c00,0x0600,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00f0\n  0x0000,0x0000,0x0000,0x0000,0x3b80,0x6e00,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u00f1\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00f2\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00f3\n  0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00f4\n  0x0000,0x0000,0x0000,0x0000,0x3b80,0x6e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00f5\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u00f6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00f7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f40,0x6180,0x6380,0x6780,0x6d80,0x7980,0x7180,0x6180,0xbf00,\n  0x0000,0x0000,0x0000,0x0000, // u00f8\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x0c00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u00f9\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u00fa\n  0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u00fb\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u00fc\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0180,0x0180,0x3f00,0x0000, // u00fd\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,\n  0x6000,0x6000,0x6000,0x0000, // u00fe\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0180,0x0180,0x3f00,0x0000, // u00ff\n  0x0000,0x3f00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0100\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u0101\n  0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0102\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u0103\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0180,0x0300,0x01c0,0x0000, // u0104\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0180,0x0300,0x01c0,0x0000, // u0105\n  0x0600,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0106\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x3f00,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0107\n  0x1e00,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0108\n  0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x0000,0x3f00,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0109\n  0x0c00,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u010a\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x3f00,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u010b\n  0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u010c\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u010d\n  0x3300,0x1e00,0x0000,0x7e00,0x6300,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6300,0x7e00,\n  0x0000,0x0000,0x0000,0x0000, // u010e\n  0x3300,0x1e00,0x0000,0x0180,0x0180,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u010f\n  0x0000,0x0000,0x0000,0x7e00,0x6300,0x6180,0x6180,0x6180,0x6180,0xfd80,0x6180,0x6180,0x6180,0x6180,0x6300,0x7e00,\n  0x0000,0x0000,0x0000,0x0000, // u0110\n  0x0000,0x0000,0x0000,0x0180,0x0fc0,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u0111\n  0x0000,0x3f00,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u0112\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0113\n  0x3300,0x1e00,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u0114\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0115\n  0x0c00,0x0c00,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u0116\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0117\n  0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,\n  0x0180,0x0300,0x01c0,0x0000, // u0118\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,\n  0x0c00,0x1800,0x0e00,0x0000, // u0119\n  0x3300,0x1e00,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u011a\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u011b\n  0x1e00,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6780,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u011c\n  0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x0000,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0180,0x0180,0x3f00,0x0000, // u011d\n  0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6780,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u011e\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0180,0x0180,0x3f00,0x0000, // u011f\n  0x0c00,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6780,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0120\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0180,0x0180,0x3f00,0x0000, // u0121\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6780,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0c00,0x0c00,0x1800, // u0122\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x0c00,0x0000,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0180,0x0180,0x3f00,0x0000, // u0123\n  0x1e00,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0124\n  0x1e00,0x3300,0x0000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0125\n  0x0000,0x0000,0x0000,0x6180,0x6180,0xffc0,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0126\n  0x0000,0x0000,0x0000,0x6000,0xfc00,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0127\n  0x3b80,0x6e00,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u0128\n  0x0000,0x0000,0x0000,0x0000,0x3b80,0x6e00,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u0129\n  0x0000,0x3f00,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u012a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u012b\n  0x3300,0x1e00,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u012c\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u012d\n  0x0000,0x0000,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0c00,0x1800,0x0e00,0x0000, // u012e\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0c00,0x1800,0x0e00,0x0000, // u012f\n  0x0c00,0x0c00,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u0130\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u0131\n  0x0000,0x0000,0x0000,0xf3c0,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6d80,0x6d80,0x6d80,0xf700,\n  0x0000,0x0000,0x0000,0x0000, // u0132\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x0000,0x0000,0xe380,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0xf180,\n  0x0d80,0x0d80,0x0700,0x0000, // u0133\n  0x0780,0x0cc0,0x0000,0x0780,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x6300,0x6300,0x6300,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0134\n  0x0000,0x0000,0x0000,0x0000,0x0780,0x0cc0,0x0000,0x0700,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x3300,0x3300,0x1e00,0x0000, // u0135\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7000,0x7800,0x6c00,0x6600,0x6300,0x6180,0x6180,\n  0x0000,0x0c00,0x0c00,0x1800, // u0136\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6180,0x6300,0x6600,0x6c00,0x7800,0x6c00,0x6600,0x6300,0x6180,\n  0x0000,0x0c00,0x0c00,0x1800, // u0137\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6300,0x6600,0x6c00,0x7800,0x6c00,0x6600,0x6300,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0138\n  0x3000,0x6000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u0139\n  0x0600,0x0c00,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u013a\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0c00,0x0c00,0x1800, // u013b\n  0x0000,0x0000,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0c00,0x0c00,0x1800, // u013c\n  0x3300,0x1e00,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u013d\n  0x3300,0x1e00,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u013e\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6300,0x6300,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u013f\n  0x0000,0x0000,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0cc0,0x0cc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u0140\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3c00,0x3800,0x3000,0x7000,0xf000,0x3000,0x3000,0x3000,0x3fc0,\n  0x0000,0x0000,0x0000,0x0000, // u0141\n  0x0000,0x0000,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0f00,0x0e00,0x0c00,0x1c00,0x3c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u0142\n  0x0600,0x0c00,0x0000,0x6180,0x6180,0x6180,0x6180,0x7180,0x7980,0x6d80,0x6780,0x6380,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0143\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0144\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x7180,0x7980,0x6d80,0x6780,0x6380,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0c00,0x0c00,0x1800, // u0145\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0c00,0x0c00,0x1800, // u0146\n  0x3300,0x1e00,0x0000,0x6180,0x6180,0x6180,0x6180,0x7180,0x7980,0x6d80,0x6780,0x6380,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0147\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0148\n  0x0000,0x6000,0x6000,0x6000,0xc000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0149\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x7180,0x7980,0x6d80,0x6780,0x6380,0x6180,0x6180,0x6180,0x6180,\n  0x0180,0x0180,0x0700,0x0000, // u014a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0180,0x0180,0x0700,0x0000, // u014b\n  0x0000,0x3f00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u014c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u014d\n  0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u014e\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u014f\n  0x1980,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0150\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0151\n  0x0000,0x0000,0x0000,0x7fc0,0xc600,0xc600,0xc600,0xc600,0xc600,0xc7c0,0xc600,0xc600,0xc600,0xc600,0xc600,0x7fc0,\n  0x0000,0x0000,0x0000,0x0000, // u0152\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0xccc0,0xccc0,0xccc0,0xcfc0,0xcc00,0xcc00,0xccc0,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u0153\n  0x0600,0x0c00,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x7800,0x6c00,0x6600,0x6300,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0154\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x6f80,0x7800,0x7000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x0000,0x0000,0x0000,0x0000, // u0155\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x7800,0x6c00,0x6600,0x6300,0x6180,0x6180,\n  0x0000,0x0c00,0x0c00,0x1800, // u0156\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6f80,0x7800,0x7000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x0000,0x6000,0x6000,0xc000, // u0157\n  0x3300,0x1e00,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x7800,0x6c00,0x6600,0x6300,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0158\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x6f80,0x7800,0x7000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x0000,0x0000,0x0000,0x0000, // u0159\n  0x0600,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x3f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u015a\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x3f00,0x6180,0x6000,0x6000,0x3f00,0x0180,0x0180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u015b\n  0x1e00,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x3f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u015c\n  0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x0000,0x3f00,0x6180,0x6000,0x6000,0x3f00,0x0180,0x0180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u015d\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x3f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,\n  0x0c00,0x0c00,0x1800,0x0000, // u015e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x6000,0x3f00,0x0180,0x0180,0x6180,0x3f00,\n  0x0c00,0x0c00,0x1800,0x0000, // u015f\n  0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x3f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0160\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6000,0x6000,0x3f00,0x0180,0x0180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0161\n  0x0000,0x0000,0x0000,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0600,0x0600,0x0c00,0x0000, // u0162\n  0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x7e00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0f00,\n  0x0600,0x0600,0x0c00,0x0000, // u0163\n  0x3300,0x1e00,0x0000,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u0164\n  0x6600,0x3c00,0x0000,0x1800,0x1800,0x1800,0x1800,0x7e00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0f00,\n  0x0000,0x0000,0x0000,0x0000, // u0165\n  0x0000,0x0000,0x0000,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u0166\n  0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x7e00,0x1800,0x3c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x0f00,\n  0x0000,0x0000,0x0000,0x0000, // u0167\n  0x3b80,0x6e00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0168\n  0x0000,0x0000,0x0000,0x0000,0x3b80,0x6e00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u0169\n  0x0000,0x3f00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u016a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u016b\n  0x3300,0x1e00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u016c\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u016d\n  0x1e00,0x3300,0x1e00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u016e\n  0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x1e00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u016f\n  0x1980,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0170\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u0171\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0c00,0x1800,0x0e00,0x0000, // u0172\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0180,0x0300,0x01c0,0x0000, // u0173\n  0x1e00,0x3300,0x0000,0xc180,0xc180,0xc180,0xc180,0xc180,0xc180,0xc180,0xc980,0xdd80,0xf780,0xe380,0xc180,0x8080,\n  0x0000,0x0000,0x0000,0x0000, // u0174\n  0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x0000,0x6180,0x6180,0x6180,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0175\n  0x1e00,0x3300,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u0176\n  0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0180,0x0180,0x3f00,0x0000, // u0177\n  0x3300,0x3300,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u0178\n  0x0600,0x0c00,0x0000,0x7f80,0x0180,0x0180,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u0179\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x7f80,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u017a\n  0x0c00,0x0c00,0x0000,0x7f80,0x0180,0x0180,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u017b\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x7f80,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u017c\n  0x3300,0x1e00,0x0000,0x7f80,0x0180,0x0180,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u017d\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x7f80,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u017e\n  0x0000,0x0000,0x0000,0x0780,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u017f\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0186\n  0x0000,0x0000,0x0000,0x7f80,0x0180,0x0180,0x0180,0x0180,0x0180,0x1f80,0x0180,0x0180,0x0180,0x0180,0x0180,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u018e\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x0180,0x0180,0x0180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u018f\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x3e00,0x6000,0x6000,0x6000,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0190\n  0x0000,0x0000,0x0000,0x0700,0x0d80,0x0d80,0x0c00,0x0c00,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x6c00,0x6c00,0x3800,0x0000, // u0192\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x7180,0x7980,0x6d80,0x6780,0x6380,0x6180,0x6180,0x6180,0x6180,\n  0x6000,0x6000,0xc000,0x0000, // u019d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0180,0x0180,0x0180,0x0000, // u019e\n  0x0000,0x0000,0x0000,0x7f80,0x0180,0x0180,0x0180,0x0300,0x0600,0x7f80,0x0c00,0x1800,0x3000,0x6000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u01b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0180,0x0300,0x0600,0x7f80,0x1800,0x3000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u01b6\n  0x0000,0x0000,0x0000,0x7f80,0x0180,0x0300,0x0600,0x0c00,0x1f00,0x0180,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u01b7\n  0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u01cd\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u01ce\n  0x3300,0x1e00,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u01cf\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u01d0\n  0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u01d1\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u01d2\n  0x3300,0x1e00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u01d3\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u01d4\n  0x0000,0x3f80,0x0000,0x7fc0,0xc600,0xc600,0xc600,0xc600,0xc600,0xffc0,0xc600,0xc600,0xc600,0xc600,0xc600,0xc7c0,\n  0x0000,0x0000,0x0000,0x0000, // u01e2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x7b80,0x0cc0,0x0cc0,0x7cc0,0xcfc0,0xcc00,0xcc00,0xccc0,0x7780,\n  0x0000,0x0000,0x0000,0x0000, // u01e3\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6780,0x6180,0x6180,0x67c0,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u01e4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x6180,0x6180,0x6180,0x67c0,0x6180,0x6180,0x6180,0x3f80,\n  0x0180,0x0180,0x3f00,0x0000, // u01e5\n  0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6780,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u01e6\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0180,0x0180,0x3f00,0x0000, // u01e7\n  0x3300,0x1e00,0x0000,0x6180,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7000,0x7800,0x6c00,0x6600,0x6300,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u01e8\n  0x3300,0x1e00,0x0000,0x6000,0x6000,0x6000,0x6000,0x6180,0x6300,0x6600,0x6c00,0x7800,0x6c00,0x6600,0x6300,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u01e9\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0c00,0x1800,0x0e00,0x0000, // u01ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0c00,0x1800,0x0e00,0x0000, // u01eb\n  0x0000,0x3f00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0c00,0x1800,0x0e00,0x0000, // u01ec\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0c00,0x1800,0x0e00,0x0000, // u01ed\n  0x3300,0x1e00,0x0000,0x7f80,0x0180,0x0300,0x0600,0x0c00,0x1f00,0x0180,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u01ee\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x7f80,0x0180,0x0300,0x0600,0x0c00,0x1f00,0x0180,0x0180,0x0180,\n  0x6180,0x6180,0x3f00,0x0000, // u01ef\n  0x0000,0x0000,0x0000,0x0000,0x0cc0,0x0780,0x0000,0x0700,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x3300,0x3300,0x1e00,0x0000, // u01f0\n  0x0600,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6780,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u01f4\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0180,0x0180,0x3f00,0x0000, // u01f5\n  0x0600,0x0c00,0x0000,0x7fc0,0xc600,0xc600,0xc600,0xc600,0xc600,0xffc0,0xc600,0xc600,0xc600,0xc600,0xc600,0xc7c0,\n  0x0000,0x0000,0x0000,0x0000, // u01fc\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x7b80,0x0cc0,0x0cc0,0x7cc0,0xcfc0,0xcc00,0xcc00,0xccc0,0x7780,\n  0x0000,0x0000,0x0000,0x0000, // u01fd\n  0x0600,0x0c00,0x0000,0x3f00,0x6180,0x61c0,0x6180,0x6380,0x6780,0x6d80,0x7980,0x7180,0x6180,0xe180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u01fe\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x3f40,0x6180,0x6380,0x6780,0x6d80,0x7980,0x7180,0x6180,0xbf00,\n  0x0000,0x0000,0x0000,0x0000, // u01ff\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x3f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,\n  0x0000,0x0c00,0x0c00,0x1800, // u0218\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x6000,0x3f00,0x0180,0x0180,0x6180,0x3f00,\n  0x0000,0x0c00,0x0c00,0x1800, // u0219\n  0x0000,0x0000,0x0000,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0c00,0x0c00,0x1800, // u021a\n  0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x7e00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0f00,\n  0x0000,0x0600,0x0600,0x0c00, // u021b\n  0x0000,0x3f00,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u0232\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0180,0x0180,0x3f00,0x0000, // u0233\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x3300,0x3300,0x1e00,0x0000, // u0237\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x0180,0x0180,0x0180,0x0180,0x0180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0254\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x0180,0x0180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0258\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x0180,0x0180,0x7f80,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0259\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x6000,0x3e00,0x6000,0x6000,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u025b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x6000,0x6000,0xc000,0x0000, // u0272\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0180,0x0300,0x0600,0x0c00,0x1f00,0x0180,0x0180,0x0180,\n  0x6180,0x6180,0x3f00,0x0000, // u0292\n  0x0600,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u02bb\n  0x0c00,0x0c00,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u02bc\n  0x0c00,0x0c00,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u02bd\n  0x1e00,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u02c6\n  0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u02c7\n  0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u02d8\n  0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u02d9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0c00,0x1800,0x0e00,0x0000, // u02db\n  0x3b80,0x6e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u02dc\n  0x1980,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u02dd\n  0x1800,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0300\n  0x0600,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0301\n  0x1e00,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0302\n  0x3b80,0x6e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0303\n  0x0000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0304\n  0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0305\n  0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0306\n  0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0307\n  0x3300,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0308\n  0x1e00,0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u030a\n  0x1980,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u030b\n  0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u030c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0c00,0x0c00,0x0000, // u0329\n  0x0000,0x6000,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0384\n  0x0000,0x0600,0x0c00,0x0000,0x3300,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0385\n  0x0000,0x6000,0xc000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0386\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0387\n  0x0000,0x6000,0xc000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u0388\n  0x0000,0x6000,0xc000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0389\n  0x0000,0x6000,0xc000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u038a\n  0x0000,0x6000,0xc000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u038c\n  0x0000,0x6000,0xc000,0x30c0,0x30c0,0x30c0,0x1980,0x1980,0x1980,0x0f00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0000,0x0000,0x0000,0x0000, // u038e\n  0x0000,0x6000,0xc000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x3300,0x7380,\n  0x0000,0x0000,0x0000,0x0000, // u038f\n  0x0000,0x0600,0x0c00,0x0000,0x3300,0x3300,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0700,\n  0x0000,0x0000,0x0000,0x0000, // u0390\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0391\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u0392\n  0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x0000,0x0000,0x0000,0x0000, // u0393\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x1e00,0x1e00,0x1e00,0x3300,0x3300,0x3300,0x6180,0x6180,0x6180,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u0394\n  0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u0395\n  0x0000,0x0000,0x0000,0x7f80,0x0180,0x0180,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u0396\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0397\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6d80,0x6d80,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0398\n  0x0000,0x0000,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u0399\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7000,0x7800,0x6c00,0x6600,0x6300,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u039a\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x1e00,0x1e00,0x1e00,0x3300,0x3300,0x3300,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u039b\n  0x0000,0x0000,0x0000,0x8080,0xc180,0xe380,0xf780,0xdd80,0xc980,0xc180,0xc180,0xc180,0xc180,0xc180,0xc180,0xc180,\n  0x0000,0x0000,0x0000,0x0000, // u039c\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x7180,0x7980,0x6d80,0x6780,0x6380,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u039d\n  0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u039e\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u039f\n  0x0000,0x0000,0x0000,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u03a0\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x0000,0x0000,0x0000,0x0000, // u03a1\n  0x0000,0x0000,0x0000,0x7f80,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u03a3\n  0x0000,0x0000,0x0000,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u03a4\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u03a5\n  0x0000,0x0000,0x0000,0x0c00,0x3f00,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u03a6\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x1e00,0x3300,0x3300,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u03a7\n  0x0000,0x0000,0x0000,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u03a8\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x3300,0x7380,\n  0x0000,0x0000,0x0000,0x0000, // u03a9\n  0x3300,0x3300,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u03aa\n  0x3300,0x3300,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u03ab\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x1800,0x0000,0x7d80,0xc700,0xc600,0xc600,0xc600,0xc600,0xc600,0xc700,0x7d80,\n  0x0000,0x0000,0x0000,0x0000, // u03ac\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x3f00,0x6180,0x6000,0x6000,0x3e00,0x6000,0x6000,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u03ad\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0180,0x0180,0x0180,0x0000, // u03ae\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0700,\n  0x0000,0x0000,0x0000,0x0000, // u03af\n  0x0000,0x0600,0x0c00,0x0000,0x3300,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u03b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7d80,0xc700,0xc600,0xc600,0xc600,0xc600,0xc600,0xc700,0x7d80,\n  0x0000,0x0000,0x0000,0x0000, // u03b1\n  0x0000,0x0000,0x0000,0x3e00,0x6300,0x6300,0x6300,0x6200,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,\n  0x6000,0x6000,0x6000,0x0000, // u03b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x1e00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0000, // u03b3\n  0x0000,0x0000,0x0000,0x3f00,0x1800,0x0c00,0x0600,0x1f00,0x3380,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u03b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x6000,0x3e00,0x6000,0x6000,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u03b5\n  0x0000,0x0000,0x0000,0x7f80,0x0300,0x0600,0x0c00,0x1800,0x3000,0x3000,0x6000,0x6000,0x6000,0x6000,0x6000,0x3f00,\n  0x0180,0x0180,0x0300,0x0000, // u03b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0180,0x0180,0x0180,0x0000, // u03b7\n  0x0000,0x0000,0x0000,0x3e00,0x6300,0x6300,0x6300,0x6300,0x6300,0x7f00,0x6300,0x6300,0x6300,0x6300,0x6300,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u03b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0700,\n  0x0000,0x0000,0x0000,0x0000, // u03b9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6300,0x6600,0x6c00,0x7800,0x6c00,0x6600,0x6300,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u03ba\n  0x0000,0x0000,0x0000,0x1800,0x1800,0x0c00,0x0c00,0x0c00,0x1e00,0x1e00,0x3300,0x3300,0x3300,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u03bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6380,0x7d80,\n  0x6000,0x6000,0x6000,0x0000, // u03bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u03bd\n  0x0000,0x0000,0x0000,0x3f80,0x6000,0x6000,0x6000,0x6000,0x3f00,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x3f00,\n  0x0180,0x0180,0x0300,0x0000, // u03be\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u03bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u03c0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,\n  0x6000,0x6000,0x6000,0x0000, // u03c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x3f00,\n  0x0180,0x0180,0x0300,0x0000, // u03c2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3300,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u03c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0700,\n  0x0000,0x0000,0x0000,0x0000, // u03c4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u03c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2700,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,\n  0x0c00,0x0c00,0x0c00,0x0000, // u03c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x1e00,0x3300,\n  0x3300,0x6180,0x6180,0x0000, // u03c7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,\n  0x0c00,0x0c00,0x0c00,0x0000, // u03c8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3300,0x6180,0x6180,0x6d80,0x6d80,0x6d80,0x6d80,0x7f80,0x3300,\n  0x0000,0x0000,0x0000,0x0000, // u03c9\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0700,\n  0x0000,0x0000,0x0000,0x0000, // u03ca\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u03cb\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u03cc\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u03cd\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x3300,0x6180,0x6180,0x6d80,0x6d80,0x6d80,0x6d80,0x7f80,0x3300,\n  0x0000,0x0000,0x0000,0x0000, // u03ce\n  0x0000,0x0000,0x0000,0x3e00,0x6300,0x6300,0x6300,0x6300,0x3f80,0x0300,0x0300,0xe300,0x6300,0x6300,0x6300,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u03d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x3f00,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,\n  0x0c00,0x0c00,0x0000,0x0000, // u03d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf0c0,0x1980,0x0b00,0x0e00,0x0c00,0x1c00,0x3400,0x6600,0xc3c0,\n  0x0000,0x0000,0x0000,0x0000, // u03f0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,\n  0x6000,0x6000,0x3f00,0x0000, // u03f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u03f2\n  0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0700,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x3300,0x3300,0x1e00,0x0000, // u03f3\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u03f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6000,0xc000,0xc000,0xfe00,0xc000,0xc000,0x6000,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u03f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x0600,0x0300,0x0300,0x7f00,0x0300,0x0300,0x0600,0xfc00,\n  0x0000,0x0000,0x0000,0x0000, // u03f6\n  0x1800,0x0c00,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u0400\n  0x3300,0x3300,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u0401\n  0x0000,0x0000,0x0000,0xfc00,0x3000,0x3000,0x3000,0x3f00,0x3180,0x3180,0x3180,0x3180,0x3180,0x3180,0x3180,0x3300,\n  0x0000,0x0000,0x0000,0x0000, // u0402\n  0x0600,0x0c00,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x0000,0x0000,0x0000,0x0000, // u0403\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0404\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x3f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0405\n  0x0000,0x0000,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u0406\n  0x3300,0x3300,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u0407\n  0x0000,0x0000,0x0000,0x0780,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x6300,0x6300,0x6300,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u0408\n  0x0000,0x0000,0x0000,0x3c00,0x6c00,0xcc00,0xcc00,0xcc00,0xcf80,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0x8f80,\n  0x0000,0x0000,0x0000,0x0000, // u0409\n  0x0000,0x0000,0x0000,0xcc00,0xcc00,0xcc00,0xcc00,0xcc00,0xcf80,0xfcc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xcf80,\n  0x0000,0x0000,0x0000,0x0000, // u040a\n  0x0000,0x0000,0x0000,0xfc00,0x3000,0x3000,0x3000,0x3f00,0x3180,0x3180,0x3180,0x3180,0x3180,0x3180,0x3180,0x3180,\n  0x0000,0x0000,0x0000,0x0000, // u040b\n  0x0600,0x0c00,0x0000,0x6180,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7000,0x7800,0x6c00,0x6600,0x6300,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u040c\n  0x1800,0x0c00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6380,0x6780,0x6d80,0x7980,0x7180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u040d\n  0x3300,0x1e00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,0x0180,0x0180,0x0180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u040e\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,\n  0x0c00,0x0c00,0x0000,0x0000, // u040f\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0410\n  0x0000,0x0000,0x0000,0x7f00,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u0411\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u0412\n  0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x0000,0x0000,0x0000,0x0000, // u0413\n  0x0000,0x0000,0x0000,0x1f00,0x3300,0x6300,0x6300,0x6300,0x6300,0x6300,0x6300,0x6300,0x6300,0x6300,0x6300,0xff80,\n  0xc180,0xc180,0x0000,0x0000, // u0414\n  0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u0415\n  0x0000,0x0000,0x0000,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,0x1e00,0x3f00,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,\n  0x0000,0x0000,0x0000,0x0000, // u0416\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x0180,0x0180,0x0180,0x1f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0417\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6380,0x6780,0x6d80,0x7980,0x7180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0418\n  0x3300,0x1e00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6380,0x6780,0x6d80,0x7980,0x7180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0419\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7000,0x7800,0x6c00,0x6600,0x6300,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u041a\n  0x0000,0x0000,0x0000,0x0f80,0x1980,0x3180,0x3180,0x3180,0x3180,0x3180,0x3180,0x3180,0x3180,0x3180,0x3180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u041b\n  0x0000,0x0000,0x0000,0x8080,0xc180,0xe380,0xf780,0xdd80,0xc980,0xc180,0xc180,0xc180,0xc180,0xc180,0xc180,0xc180,\n  0x0000,0x0000,0x0000,0x0000, // u041c\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u041d\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u041e\n  0x0000,0x0000,0x0000,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u041f\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x0000,0x0000,0x0000,0x0000, // u0420\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0421\n  0x0000,0x0000,0x0000,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u0422\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,0x0180,0x0180,0x0180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0423\n  0x0000,0x0000,0x0c00,0x3f00,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,\n  0x0c00,0x0000,0x0000,0x0000, // u0424\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x1e00,0x3300,0x3300,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0425\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3fc0,\n  0x00c0,0x00c0,0x0000,0x0000, // u0426\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0000,0x0000,0x0000,0x0000, // u0427\n  0x0000,0x0000,0x0000,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u0428\n  0x0000,0x0000,0x0000,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3fc0,\n  0x00c0,0x00c0,0x0000,0x0000, // u0429\n  0x0000,0x0000,0x0000,0xe000,0xe000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u042a\n  0x0000,0x0000,0x0000,0xc180,0xc180,0xc180,0xc180,0xf980,0xcd80,0xcd80,0xcd80,0xcd80,0xcd80,0xcd80,0xcd80,0xf980,\n  0x0000,0x0000,0x0000,0x0000, // u042b\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u042c\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x0180,0x0180,0x0180,0x1f80,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u042d\n  0x0000,0x0000,0x0000,0xcf00,0xd980,0xd980,0xd980,0xd980,0xd980,0xf980,0xd980,0xd980,0xd980,0xd980,0xd980,0xcf00,\n  0x0000,0x0000,0x0000,0x0000, // u042e\n  0x0000,0x0000,0x0000,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0780,0x0d80,0x1980,0x3180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u042f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u0430\n  0x0000,0x0000,0x0000,0x3e00,0x6000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u0431\n  0x0000,0x0000,0x0000,0x3e00,0x6300,0x6300,0x6300,0x6200,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u0432\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x0000,0x0000,0x0000,0x0000, // u0433\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0180,0x0180,0x3f00,0x0000, // u0434\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0435\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6d80,0x6d80,0x6d80,0x3f00,0x1e00,0x3f00,0x6d80,0x6d80,0x6d80,\n  0x0000,0x0000,0x0000,0x0000, // u0436\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x0180,0x0180,0x1f00,0x0180,0x0180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0437\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u0438\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u0439\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6300,0x6600,0x6c00,0x7800,0x6c00,0x6600,0x6300,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u043a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f80,0x1980,0x3180,0x3180,0x3180,0x3180,0x3180,0x3180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u043b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x6180,0x7380,0x7f80,0x6d80,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u043c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u043d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u043e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u043f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,\n  0x6000,0x6000,0x6000,0x0000, // u0440\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0441\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u0442\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0180,0x0180,0x3f00,0x0000, // u0443\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x3f00,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,\n  0x0c00,0x0c00,0x0000,0x0000, // u0444\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x3300,0x1e00,0x0c00,0x1e00,0x3300,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u0445\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3fc0,\n  0x00c0,0x00c0,0x0000,0x0000, // u0446\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,0x0180,0x0180,0x0180,\n  0x0000,0x0000,0x0000,0x0000, // u0447\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u0448\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3fc0,\n  0x00c0,0x00c0,0x0000,0x0000, // u0449\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x3000,0x3000,0x3f00,0x3180,0x3180,0x3180,0x3180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u044a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc180,0xc180,0xc180,0xf980,0xcd80,0xcd80,0xcd80,0xcd80,0xf980,\n  0x0000,0x0000,0x0000,0x0000, // u044b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x7e00,0x6300,0x6300,0x6300,0x6300,0x7e00,\n  0x0000,0x0000,0x0000,0x0000, // u044c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x0180,0x0180,0x1f80,0x0180,0x0180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u044d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xcf00,0xd980,0xd980,0xd980,0xf980,0xd980,0xd980,0xd980,0xcf00,\n  0x0000,0x0000,0x0000,0x0000, // u044e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x6180,0x6180,0x6180,0x3f80,0x0d80,0x1980,0x3180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u044f\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x0c00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0450\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0451\n  0x0000,0x0000,0x0000,0x6000,0xfc00,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0180,0x0180,0x0700,0x0000, // u0452\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x0000,0x0000,0x0000,0x0000, // u0453\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0454\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x6000,0x3f00,0x0180,0x0180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0455\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u0456\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u0457\n  0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0700,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x3300,0x3300,0x1e00,0x0000, // u0458\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x6c00,0xcc00,0xcf80,0xccc0,0xccc0,0xccc0,0xccc0,0x8f80,\n  0x0000,0x0000,0x0000,0x0000, // u0459\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xcc00,0xcc00,0xcc00,0xcf80,0xfcc0,0xccc0,0xccc0,0xccc0,0xcf80,\n  0x0000,0x0000,0x0000,0x0000, // u045a\n  0x0000,0x0000,0x0000,0x6000,0xfc00,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u045b\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0c00,0x0000,0x6180,0x6300,0x6600,0x6c00,0x7800,0x6c00,0x6600,0x6300,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u045c\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x0c00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u045d\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0180,0x0180,0x3f00,0x0000, // u045e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,\n  0x0c00,0x0c00,0x0000,0x0000, // u045f\n  0x0000,0x0000,0x0000,0x6000,0xfc00,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u0462\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0xfc00,0x3000,0x3000,0x3000,0x3f00,0x3180,0x3180,0x3180,0x3180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u0463\n  0x0000,0x0000,0x0000,0x7f80,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x1e00,0x3f00,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,\n  0x0000,0x0000,0x0000,0x0000, // u046a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x6180,0x3300,0x1e00,0x1e00,0x3f00,0x6d80,0x6d80,0x6d80,\n  0x0000,0x0000,0x0000,0x0000, // u046b\n  0x0000,0x0180,0x0180,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x0000,0x0000,0x0000,0x0000, // u0490\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x0000,0x0000,0x0000,0x0000, // u0491\n  0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0xfc00,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x0000,0x0000,0x0000,0x0000, // u0492\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0xfc00,0x6000,0x6000,0x6000,0x6000,\n  0x0000,0x0000,0x0000,0x0000, // u0493\n  0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0180,0x0300,0x0000,0x0000, // u0494\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x7e00,0x6300,0x6300,0x6300,0x6300,\n  0x0300,0x0600,0x0000,0x0000, // u0495\n  0x0000,0x0000,0x0000,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,0x1e00,0x3f00,0x6d80,0x6d80,0x6d80,0x6d80,0x6dc0,\n  0x00c0,0x00c0,0x0000,0x0000, // u0496\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6d80,0x6d80,0x6d80,0x3f00,0x1e00,0x3f00,0x6d80,0x6d80,0x6dc0,\n  0x00c0,0x00c0,0x0000,0x0000, // u0497\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x0180,0x0180,0x0180,0x1f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,\n  0x0c00,0x0c00,0x0c00,0x0000, // u0498\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x0180,0x0180,0x1f00,0x0180,0x0180,0x6180,0x3f00,\n  0x0c00,0x0c00,0x0c00,0x0000, // u0499\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7000,0x7800,0x6c00,0x6600,0x6300,0x6180,0x61c0,\n  0x00c0,0x00c0,0x0000,0x0000, // u049a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6300,0x6600,0x6c00,0x7800,0x6c00,0x6600,0x6300,0x61c0,\n  0x00c0,0x00c0,0x0000,0x0000, // u049b\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6b00,0x6e00,0x7c00,0x7800,0x7c00,0x6e00,0x6b00,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u049c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6b00,0x6e00,0x6c00,0x7800,0x6c00,0x6e00,0x6b00,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u049d\n  0x0000,0x0000,0x0000,0xe180,0xe180,0x6300,0x6600,0x6c00,0x7800,0x7000,0x7800,0x6c00,0x6600,0x6300,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u04a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xe180,0x6300,0x6600,0x6c00,0x7800,0x6c00,0x6600,0x6300,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u04a1\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x61c0,\n  0x00c0,0x00c0,0x0000,0x0000, // u04a2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x61c0,\n  0x00c0,0x00c0,0x0000,0x0000, // u04a3\n  0x0000,0x0000,0x0000,0xc7c0,0xc600,0xc600,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,\n  0x0000,0x0000,0x0000,0x0000, // u04a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc7c0,0xc600,0xc600,0xc600,0xfe00,0xc600,0xc600,0xc600,0xc600,\n  0x0000,0x0000,0x0000,0x0000, // u04a5\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x6180,0x3f00,\n  0x0c00,0x0c00,0x0c00,0x0000, // u04aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x3f00,\n  0x0c00,0x0c00,0x0c00,0x0000, // u04ab\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u04ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x1e00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0000, // u04af\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x0c00,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u04b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x1e00,0x0c00,\n  0x3f00,0x0c00,0x0c00,0x0000, // u04b1\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x1e00,0x3300,0x3300,0x6180,0x6180,0x61c0,\n  0x00c0,0x00c0,0x0000,0x0000, // u04b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x3300,0x1e00,0x0c00,0x1e00,0x3300,0x6180,0x61c0,\n  0x00c0,0x00c0,0x0000,0x0000, // u04b3\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,0x0180,0x0180,0x0180,0x0180,0x01c0,\n  0x00c0,0x00c0,0x0000,0x0000, // u04b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,0x0180,0x0180,0x01c0,\n  0x00c0,0x00c0,0x0000,0x0000, // u04b7\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6d80,0x6d80,0x6d80,0x3f80,0x0d80,0x0d80,0x0d80,0x0180,0x0180,0x0180,\n  0x0000,0x0000,0x0000,0x0000, // u04b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6d80,0x6d80,0x3f80,0x0d80,0x0d80,0x0180,0x0180,\n  0x0000,0x0000,0x0000,0x0000, // u04b9\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u04ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u04bb\n  0x0000,0x0000,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u04c0\n  0x3300,0x1e00,0x0000,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,0x1e00,0x3f00,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,\n  0x0000,0x0000,0x0000,0x0000, // u04c1\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x6d80,0x6d80,0x6d80,0x3f00,0x1e00,0x3f00,0x6d80,0x6d80,0x6d80,\n  0x0000,0x0000,0x0000,0x0000, // u04c2\n  0x0000,0x0000,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u04cf\n  0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u04d0\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u04d1\n  0x3300,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u04d2\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u04d3\n  0x0000,0x0000,0x0000,0x7fc0,0xc600,0xc600,0xc600,0xc600,0xc600,0xffc0,0xc600,0xc600,0xc600,0xc600,0xc600,0xc7c0,\n  0x0000,0x0000,0x0000,0x0000, // u04d4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7b80,0x0cc0,0x0cc0,0x7cc0,0xcfc0,0xcc00,0xcc00,0xccc0,0x7780,\n  0x0000,0x0000,0x0000,0x0000, // u04d5\n  0x3300,0x1e00,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u04d6\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x1e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u04d7\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x0180,0x0180,0x0180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u04d8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x0180,0x0180,0x7f80,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u04d9\n  0x3300,0x3300,0x0000,0x3f00,0x6180,0x6180,0x0180,0x0180,0x0180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u04da\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x3f00,0x6180,0x0180,0x0180,0x7f80,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u04db\n  0x3300,0x3300,0x0000,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,0x1e00,0x3f00,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,\n  0x0000,0x0000,0x0000,0x0000, // u04dc\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x6d80,0x6d80,0x6d80,0x3f00,0x1e00,0x3f00,0x6d80,0x6d80,0x6d80,\n  0x0000,0x0000,0x0000,0x0000, // u04dd\n  0x3300,0x3300,0x0000,0x3f00,0x6180,0x6180,0x0180,0x0180,0x0180,0x1f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u04de\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x3f00,0x6180,0x0180,0x0180,0x1f00,0x0180,0x0180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u04df\n  0x0000,0x3f00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6380,0x6780,0x6d80,0x7980,0x7180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u04e2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u04e3\n  0x3300,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6380,0x6780,0x6d80,0x7980,0x7180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u04e4\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0000,0x0000,0x0000, // u04e5\n  0x3300,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u04e6\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u04e7\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u04e8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u04e9\n  0x3300,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u04ea\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u04eb\n  0x3300,0x3300,0x0000,0x3f00,0x6180,0x6180,0x0180,0x0180,0x0180,0x1f80,0x0180,0x0180,0x0180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u04ec\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x3f00,0x6180,0x0180,0x0180,0x1f80,0x0180,0x0180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u04ed\n  0x0000,0x3f00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,0x0180,0x0180,0x0180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u04ee\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0180,0x0180,0x3f00,0x0000, // u04ef\n  0x3300,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,0x0180,0x0180,0x0180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u04f0\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0180,0x0180,0x3f00,0x0000, // u04f1\n  0x1980,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,0x0180,0x0180,0x0180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u04f2\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0180,0x0180,0x3f00,0x0000, // u04f3\n  0x3300,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0000,0x0000,0x0000,0x0000, // u04f4\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x3f80,0x0180,0x0180,0x0180,0x0180,\n  0x0000,0x0000,0x0000,0x0000, // u04f5\n  0x6600,0x6600,0x0000,0xc180,0xc180,0xc180,0xc180,0xf980,0xcd80,0xcd80,0xcd80,0xcd80,0xcd80,0xcd80,0xcd80,0xf980,\n  0x0000,0x0000,0x0000,0x0000, // u04f8\n  0x0000,0x0000,0x0000,0x0000,0x3300,0x3300,0x0000,0xc180,0xc180,0xc180,0xf980,0xcd80,0xcd80,0xcd80,0xcd80,0xf980,\n  0x0000,0x0000,0x0000,0x0000, // u04f9\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x3180,0x3180,0x1980,0x1b00,0x3e00,0x6c00,0xcc00,0xc600,0xc600,0xc300,0xc300,\n  0x0000,0x0000,0x0000,0x0000, // u05d0\n  0x0000,0x0000,0x0000,0x7f00,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x7fc0,\n  0x0000,0x0000,0x0000,0x0000, // u05d1\n  0x0000,0x0000,0x0000,0x7c00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0e00,0x1b00,0x3300,0x6180,0xc180,\n  0x0000,0x0000,0x0000,0x0000, // u05d2\n  0x0000,0x0000,0x0000,0x7fc0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0000,0x0000,0x0000,0x0000, // u05d3\n  0x0000,0x0000,0x0000,0x7f00,0x0180,0x0180,0x0180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u05d4\n  0x0000,0x0000,0x0000,0x3800,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u05d5\n  0x0000,0x0000,0x0000,0x0000,0x3f00,0x0300,0x0600,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u05d6\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u05d7\n  0x0000,0x0000,0x0000,0x6700,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u05d8\n  0x0000,0x0000,0x0000,0x3800,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u05d9\n  0x0000,0x0000,0x0000,0x7f00,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0000, // u05da\n  0x0000,0x0000,0x0000,0x7f00,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u05db\n  0x0000,0x6000,0x6000,0x7f80,0x0180,0x0180,0x0180,0x0180,0x0180,0x0300,0x0600,0x0c00,0x1800,0x1800,0x1800,0x1800,\n  0x0000,0x0000,0x0000,0x0000, // u05dc\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u05dd\n  0x0000,0x0000,0x0000,0x0000,0xde00,0x7300,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6780,\n  0x0000,0x0000,0x0000,0x0000, // u05de\n  0x0000,0x0000,0x0000,0x7c00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000, // u05df\n  0x0000,0x0000,0x0000,0x3e00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u05e0\n  0x0000,0x0000,0x0000,0xff00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u05e1\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x3180,0x3180,0x3180,0x1980,0x1980,0x1b00,0x0f00,0x0e00,0x1c00,0x7000,\n  0x0000,0x0000,0x0000,0x0000, // u05e2\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x3980,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0000, // u05e3\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x3980,0x0180,0x0180,0x0180,0x0180,0x0180,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u05e4\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x3180,0x3180,0x1980,0x1b00,0x0e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0000, // u05e5\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x3180,0x3180,0x1980,0x1b00,0x0e00,0x0c00,0x0600,0x0600,0x0300,0x0300,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u05e6\n  0x0000,0x0000,0x0000,0x7f80,0x0180,0x0180,0x0180,0x6180,0x6180,0x6300,0x6600,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,\n  0x6000,0x6000,0x6000,0x0000, // u05e7\n  0x0000,0x0000,0x0000,0x7f00,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0000,0x0000,0x0000,0x0000, // u05e8\n  0x0000,0x0000,0x0000,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x7980,0x7180,0x6180,0x6180,0x6180,0x6300,0x7e00,\n  0x0000,0x0000,0x0000,0x0000, // u05e9\n  0x0000,0x0000,0x0000,0xff00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0xc180,\n  0x0000,0x0000,0x0000,0x0000, // u05ea\n  0x0000,0x0000,0x0000,0x7e00,0x6300,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6300,0x7e00,\n  0x0000,0x1800,0x1800,0x0000, // u1e0c\n  0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0c00,0x0c00,0x0000, // u1e0d\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7000,0x7800,0x6c00,0x6600,0x6300,0x6180,0x6180,\n  0x0000,0x3f00,0x0000,0x0000, // u1e34\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6180,0x6300,0x6600,0x6c00,0x7800,0x6c00,0x6600,0x6300,0x6180,\n  0x0000,0x3f00,0x0000,0x0000, // u1e35\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0c00,0x0c00,0x0000, // u1e36\n  0x0000,0x0000,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0c00,0x0c00,0x0000, // u1e37\n  0x0c00,0x0c00,0x0000,0x8080,0xc180,0xe380,0xf780,0xdd80,0xc980,0xc180,0xc180,0xc180,0xc180,0xc180,0xc180,0xc180,\n  0x0000,0x0000,0x0000,0x0000, // u1e40\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x7f00,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,\n  0x0000,0x0000,0x0000,0x0000, // u1e41\n  0x0000,0x0000,0x0000,0x8080,0xc180,0xe380,0xf780,0xdd80,0xc980,0xc180,0xc180,0xc180,0xc180,0xc180,0xc180,0xc180,\n  0x0000,0x0c00,0x0c00,0x0000, // u1e42\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,\n  0x0000,0x0c00,0x0c00,0x0000, // u1e43\n  0x0c00,0x0c00,0x0000,0x6180,0x6180,0x6180,0x6180,0x7180,0x7980,0x6d80,0x6780,0x6380,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u1e44\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u1e45\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x7180,0x7980,0x6d80,0x6780,0x6380,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0c00,0x0c00,0x0000, // u1e46\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0c00,0x0c00,0x0000, // u1e47\n  0x0000,0x0000,0x0000,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0c00,0x0c00,0x0000, // u1e6c\n  0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x7e00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0f00,\n  0x0000,0x0600,0x0600,0x0000, // u1e6d\n  0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0c00,0x0c00,0x0000, // u1eb8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,\n  0x0000,0x0c00,0x0c00,0x0000, // u1eb9\n  0x3b80,0x6e00,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u1ebc\n  0x0000,0x0000,0x0000,0x0000,0x3b80,0x6e00,0x0000,0x3f00,0x6180,0x6180,0x6180,0x7f80,0x6000,0x6000,0x6180,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u1ebd\n  0x0000,0x0000,0x0000,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0c00,0x0c00,0x0000, // u1eca\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,\n  0x0000,0x0c00,0x0c00,0x0000, // u1ecb\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0c00,0x0c00,0x0000, // u1ecc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0c00,0x0c00,0x0000, // u1ecd\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,\n  0x0000,0x0c00,0x0c00,0x0000, // u1ee4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0000,0x0c00,0x0c00,0x0000, // u1ee5\n  0x3b80,0x6e00,0x0000,0x6180,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u1ef8\n  0x0000,0x0000,0x0000,0x0000,0x3b80,0x6e00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f80,\n  0x0180,0x0180,0x3f00,0x0000, // u1ef9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2001\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2002\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2003\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2004\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2005\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2006\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2007\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2008\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2009\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u200a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u200b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u200c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u200d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u200e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u200f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2010\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2011\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2012\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2013\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2014\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2015\n  0x0000,0x0000,0x0000,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,\n  0x0000,0x0000,0x0000,0x0000, // u2016\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x7f80,0x0000,0x7f80, // u2017\n  0x0000,0x0600,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2018\n  0x0000,0x0c00,0x0c00,0x0c00,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2019\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,\n  0x1800,0x0000,0x0000,0x0000, // u201a\n  0x0000,0x1800,0x1800,0x1800,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u201b\n  0x0000,0x1980,0x3300,0x3300,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u201c\n  0x0000,0x1980,0x1980,0x1980,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u201d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3300,0x3300,0x3300,\n  0x6600,0x0000,0x0000,0x0000, // u201e\n  0x0000,0x6600,0x6600,0x6600,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u201f\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u2020\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u2021\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x1e00,0x1e00,0x0c00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2022\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6d80,0x6d80,\n  0x0000,0x0000,0x0000,0x0000, // u2026\n  0x0000,0x0000,0x0000,0x0000,0xe600,0xa600,0xec00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x6000,0x6fc0,0xcb40,0xcfc0,\n  0x0000,0x0000,0x0000,0x0000, // u2030\n  0x0000,0x0c00,0x0c00,0x0c00,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2032\n  0x0000,0x3300,0x3300,0x3300,0x2200,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2033\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x1800,0x3000,0x1800,0x0c00,0x0600,0x0300,\n  0x0000,0x0000,0x0000,0x0000, // u2039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0600,0x0c00,0x1800,0x3000,\n  0x0000,0x0000,0x0000,0x0000, // u203a\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x3300,0x3300,0x3300,0x3300,0x3300,0x3300,0x3300,0x0000,0x0000,0x3300,0x3300,\n  0x0000,0x0000,0x0000,0x0000, // u203c\n  0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u203e\n  0x0000,0x1e00,0x3300,0x3300,0x3300,0x3300,0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2070\n  0x0c00,0x0c00,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2071\n  0x0000,0x0300,0x0700,0x0f00,0x1b00,0x3f80,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2074\n  0x0000,0x3e00,0x3000,0x3000,0x3e00,0x0300,0x0300,0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2075\n  0x0000,0x1e00,0x3000,0x3000,0x3e00,0x3300,0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2076\n  0x0000,0x3f00,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2077\n  0x0000,0x1e00,0x3300,0x3300,0x1e00,0x3300,0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2078\n  0x0000,0x1e00,0x3300,0x3300,0x1f00,0x0300,0x0300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2079\n  0x0000,0x0000,0x0c00,0x0c00,0x3f00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u207a\n  0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u207b\n  0x0000,0x0000,0x0000,0x3f00,0x0000,0x0000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u207c\n  0x0000,0x0600,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u207d\n  0x0000,0x0c00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u207e\n  0x0000,0x0000,0x3e00,0x3300,0x3300,0x3300,0x3300,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u207f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x3300,0x3300,0x3300,0x3300,\n  0x1e00,0x0000,0x0000,0x0000, // u2080\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x1e00,0x0000,0x0000,0x0000, // u2081\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x3300,0x0600,0x0c00,0x1800,\n  0x3f00,0x0000,0x0000,0x0000, // u2082\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x0300,0x0e00,0x0300,0x3300,\n  0x1e00,0x0000,0x0000,0x0000, // u2083\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0700,0x0f00,0x1b00,0x3f80,0x0300,\n  0x0300,0x0000,0x0000,0x0000, // u2084\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x3000,0x3000,0x3e00,0x0300,0x0300,\n  0x3e00,0x0000,0x0000,0x0000, // u2085\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3000,0x3000,0x3e00,0x3300,0x3300,\n  0x1e00,0x0000,0x0000,0x0000, // u2086\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0300,0x0600,0x0600,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000, // u2087\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x3300,0x1e00,0x3300,0x3300,\n  0x1e00,0x0000,0x0000,0x0000, // u2088\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x3300,0x1f00,0x0300,0x0300,\n  0x1e00,0x0000,0x0000,0x0000, // u2089\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x3f00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u208a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u208b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x0000,0x3f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u208c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0600,0x0000,0x0000,0x0000, // u208d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0c00,0x0000,0x0000,0x0000, // u208e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x0300,0x1f00,0x3300,0x3300,\n  0x1f00,0x0000,0x0000,0x0000, // u2090\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x3f00,0x3000,0x3000,\n  0x1f00,0x0000,0x0000,0x0000, // u2091\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x3300,0x3300,0x3300,\n  0x1e00,0x0000,0x0000,0x0000, // u2092\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3300,0x1e00,0x0c00,0x0c00,0x1e00,\n  0x3300,0x0000,0x0000,0x0000, // u2093\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0300,0x0300,0x3f00,0x3300,\n  0x1e00,0x0000,0x0000,0x0000, // u2094\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3e00,0x3300,0x3300,0x3300,0x3300,\n  0x3300,0x0000,0x0000,0x0000, // u2095\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3300,0x3600,0x3c00,0x3c00,0x3600,\n  0x3300,0x0000,0x0000,0x0000, // u2096\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x1e00,0x0000,0x0000,0x0000, // u2097\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6d80,0x6d80,0x6d80,0x6d80,\n  0x6d80,0x0000,0x0000,0x0000, // u2098\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x3300,0x3300,0x3300,0x3300,\n  0x3e00,0x3000,0x3000,0x0000, // u209a\n  0x0000,0x0000,0x0000,0xf800,0xcc00,0xcc00,0xcc00,0xcc00,0xcc00,0xfb00,0xc300,0xc780,0xc300,0xc300,0xc300,0xc180,\n  0x0000,0x0000,0x0000,0x0000, // u20a7\n  0x0000,0x0000,0x0000,0xf880,0x8480,0x8480,0x8480,0x9480,0x9480,0x9480,0x9480,0x9480,0x9080,0x9080,0x9080,0x9f00,\n  0x0000,0x0000,0x0000,0x0000, // u20aa\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x6000,0xfe00,0x6000,0x6000,0xfe00,0x6000,0x60c0,0x3180,0x1f00,\n  0x0000,0x0000,0x0000,0x0000, // u20ac\n  0x0000,0x0000,0x0000,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0f00,0x3c00,0x0f00,0x3c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u20ae\n  0x0000,0x0000,0x0000,0x3e00,0x5100,0x5100,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5100,0x5100,0x3e00,\n  0x0000,0x0000,0x0000,0x0000, // u2102\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u210e\n  0x0000,0x0000,0x0000,0x6000,0xfc00,0x6000,0x6000,0x7f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u210f\n  0x0000,0x0000,0x0000,0x4100,0x4100,0x4100,0x6100,0x5100,0x6900,0x5500,0x4b00,0x4500,0x4300,0x4100,0x4100,0x4100,\n  0x0000,0x0000,0x0000,0x0000, // u2115\n  0x0000,0x0000,0x0000,0xcc00,0xcdc0,0xcd40,0xed40,0xedc0,0xfc00,0xfc00,0xfdc0,0xddc0,0xdc00,0xcdc0,0xcdc0,0xcc00,\n  0x0000,0x0000,0x0000,0x0000, // u2116\n  0x0000,0x0000,0x0000,0x3e00,0x5100,0x5100,0x5100,0x5100,0x5100,0x5100,0x5100,0x5100,0x5100,0x5100,0x5500,0x3e00,\n  0x0100,0x0080,0x0000,0x0000, // u211a\n  0x0000,0x0000,0x0000,0x7e00,0x5100,0x5100,0x5100,0x5100,0x5100,0x5e00,0x5800,0x5400,0x5a00,0x5500,0x5280,0x7180,\n  0x0000,0x0000,0x0000,0x0000, // u211d\n  0x0000,0x0000,0x0000,0xf440,0x66c0,0x67c0,0x66c0,0x66c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2122\n  0x0000,0x0000,0x0000,0x7f00,0x0100,0x0100,0x0300,0x0500,0x0a00,0x1400,0x2800,0x5000,0x6000,0x4000,0x4000,0x7f00,\n  0x0000,0x0000,0x0000,0x0000, // u2124\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x3300,0x7380,\n  0x0000,0x0000,0x0000,0x0000, // u2126\n  0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x3180,0x3180,0x18c0,0x3980,0x6f00,0xce00,0xc600,0xc600,0xc300,0x6300,\n  0x0000,0x0000,0x0000,0x0000, // u2135\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x3000,0x6000,0xff80,0xff80,0x6000,0x3000,0x1000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2190\n  0x0000,0x0000,0x0000,0x0c00,0x1e00,0x3f00,0x6d80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u2191\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0600,0x0300,0xff80,0xff80,0x0300,0x0600,0x0400,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2192\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x6d80,0x3f00,0x1e00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u2193\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1200,0x3300,0x6180,0xffc0,0xffc0,0x6180,0x3300,0x1200,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2194\n  0x0000,0x0000,0x0000,0x0c00,0x1e00,0x3f00,0x6d80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x6d80,0x3f00,0x1e00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u2195\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1180,0x3180,0x6180,0xff80,0xff80,0x6180,0x3180,0x1180,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u21a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc400,0xc600,0xc300,0xff80,0xff80,0xc300,0xc600,0xc400,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u21a6\n  0x0000,0x0000,0x0000,0x0c00,0x1e00,0x3f00,0x6d80,0x0c00,0x0c00,0x0c00,0x0c00,0x6d80,0x3f00,0x1e00,0x0c00,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u21a8\n  0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0180,0x1180,0x3180,0x6180,0xff80,0xff80,0x6000,0x3000,0x1000,\n  0x0000,0x0000,0x0000,0x0000, // u21b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0x3800,0x6800,0xc980,0xc180,0xc180,0xc180,0x6300,0x3e00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u21bb\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x3000,0x6000,0xff80,0xff80,0x0000,0xff80,0xff80,0x0300,0x0600,0x0400,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u21cb\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0600,0x0300,0xff80,0xff80,0x0000,0xff80,0xff80,0x6000,0x3000,0x1000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u21cc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x1800,0x3f80,0x7f80,0xe000,0x7f80,0x3f80,0x1800,0x0800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u21d0\n  0x0000,0x0000,0x0000,0x0800,0x1c00,0x3e00,0x7700,0xf780,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,\n  0x0000,0x0000,0x0000,0x0000, // u21d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0c00,0xfe00,0xff00,0x0380,0xff00,0xfe00,0x0c00,0x0800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u21d2\n  0x0000,0x0000,0x0000,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0xf780,0x7700,0x3e00,0x1c00,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u21d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1200,0x3300,0x7f80,0xffc0,0xc0c0,0xffc0,0x7f80,0x3300,0x1200,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u21d4\n  0x0000,0x0000,0x0000,0x0800,0x1c00,0x3e00,0x7700,0xf780,0x3600,0x3600,0x3600,0xf780,0x7700,0x3e00,0x1c00,0x0800,\n  0x0000,0x0000,0x0000,0x0000, // u21d5\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x7f80,0x3300,0x3300,0x3300,0x1200,0x1e00,0x1e00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u2200\n  0x0000,0x0000,0x0000,0x7f80,0x0180,0x0180,0x0180,0x0180,0x0180,0x7f80,0x0180,0x0180,0x0180,0x0180,0x0180,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u2203\n  0x0000,0x0180,0x0180,0x7f80,0x0380,0x0780,0x0780,0x0d80,0x0d80,0x7f80,0x1980,0x1980,0x3180,0x3180,0x6180,0x7f80,\n  0xc000,0xc000,0x0000,0x0000, // u2204\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x3f00,0x6780,0x6d80,0x6d80,0x6d80,0x7980,0x3f00,0x3000,0x6000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2205\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x1e00,0x1e00,0x1e00,0x3300,0x3300,0x3300,0x6180,0x6180,0x6180,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u2206\n  0x0000,0x0000,0x0000,0x7f80,0x6180,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x1e00,0x1e00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u2207\n  0x0000,0x0000,0x0000,0x0f80,0x1800,0x3000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,0x3000,0x1800,0x0f80,\n  0x0000,0x0000,0x0000,0x0000, // u2208\n  0x0000,0x00c0,0x00c0,0x0f80,0x1980,0x3300,0x6300,0x6600,0x6600,0x7f80,0x6c00,0x6c00,0x7800,0x3800,0x3800,0x3f80,\n  0x6000,0x6000,0x0000,0x0000, // u2209\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x3000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x3000,0x1f80,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u220a\n  0x0000,0x0000,0x0000,0x7c00,0x0600,0x0300,0x0180,0x0180,0x0180,0x7f80,0x0180,0x0180,0x0180,0x0300,0x0600,0x7c00,\n  0x0000,0x0000,0x0000,0x0000, // u220b\n  0x0000,0x6000,0x6000,0x3e00,0x3300,0x1980,0x18c0,0x0cc0,0x0cc0,0x3fc0,0x06c0,0x06c0,0x03c0,0x0380,0x0380,0x3f80,\n  0x00c0,0x00c0,0x0000,0x0000, // u220c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0300,0x0180,0x0180,0x7f80,0x0180,0x0180,0x0300,0x7e00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u220d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2212\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u2213\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u2214\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2215\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2216\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x1c00,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2219\n  0x0000,0x0380,0x0380,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x6300,0x6300,0x6300,0x3300,0x1b00,0x0f00,0x0700,\n  0x0000,0x0000,0x0000,0x0000, // u221a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6d80,0x6d80,0x6d80,0x6d80,0x3f00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u221e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u221f\n  0x0000,0x0000,0x0000,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,\n  0x0000,0x0000,0x0000,0x0000, // u2225\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x1e00,0x1e00,0x3300,0x3300,0x3300,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u2227\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x1e00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u2228\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u2229\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u222a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3980,0x6d80,0x6700,0x0000,0x3980,0x6d80,0x6700,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2248\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x7f80,0x0600,0x0c00,0x1800,0x7f80,0x6000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2260\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2261\n  0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u2264\n  0x0000,0x0000,0x0000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x0000,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u2265\n  0x0000,0x0000,0x0000,0x0000,0x0440,0x0cc0,0x1980,0x3300,0x6600,0xcc00,0x6600,0x3300,0x1980,0x0cc0,0x0440,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u226a\n  0x0000,0x0000,0x0000,0x0000,0x8800,0xcc00,0x6600,0x3300,0x1980,0x0cc0,0x1980,0x3300,0x6600,0xcc00,0x8800,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u226b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x3000,0x6000,0x6000,0x6000,0x6000,0x6000,0x3000,0x1f80,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2282\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0300,0x0180,0x0180,0x0180,0x0180,0x0180,0x0300,0x7e00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2283\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x3000,0x6000,0x6000,0x6000,0x6000,0x6000,0x3000,0x1f80,0x0000,0x7f80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2286\n  0x0000,0x0000,0x0000,0x0000,0x7e00,0x0300,0x0180,0x0180,0x0180,0x0180,0x0180,0x0300,0x7e00,0x0000,0x7f80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2287\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u22a5\n  0x0000,0x0000,0x0000,0x1e00,0x3300,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,\n  0x0000,0x0000,0x0000,0x0000, // u22c2\n  0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u22c3\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x3f00,0x6780,0x6d80,0x6d80,0x6d80,0x7980,0x3f00,0x3000,0x6000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2300\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x1c00,0x3600,0x6300,0xc180,0xc180,0xc180,0xc180,0xc180,0xff80,\n  0x0000,0x0000,0x0000,0x0000, // u2302\n  0x0000,0x0000,0x0000,0x1e00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,\n  0x0000,0x0000,0x0000,0x0000, // u2308\n  0x0000,0x0000,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0000,0x0000,0x0000,0x0000, // u2309\n  0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u230a\n  0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x1e00,\n  0x0000,0x0000,0x0000,0x0000, // u230b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2310\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2319\n  0x0000,0x0000,0x0000,0x0700,0x0d80,0x0d80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2320\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x6c00,0x6c00,0x3800,\n  0x0000,0x0000,0x0000,0x0000, // u2321\n  0x0300,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x1800,0x3000,0x3000,0x3000,0x3000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000, // u239b\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000, // u239c\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x3000,0x3000,0x3000,0x3000,0x1800,0x1800,0x1800,\n  0x0c00,0x0c00,0x0600,0x0300, // u239d\n  0x6000,0x3000,0x1800,0x1800,0x0c00,0x0c00,0x0c00,0x0600,0x0600,0x0600,0x0600,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300, // u239e\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300, // u239f\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0600,0x0600,0x0600,0x0600,0x0c00,0x0c00,0x0c00,\n  0x1800,0x1800,0x3000,0x6000, // u23a0\n  0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000, // u23a1\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000, // u23a2\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x7f00, // u23a3\n  0x7f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300, // u23a4\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300, // u23a5\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x7f00, // u23a6\n  0x03c0,0x0e00,0x0c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,\n  0x1800,0x1800,0x1800,0x1800, // u23a7\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3000,0xe000,0xe000,0x3000,0x1800,0x1800,0x1800,0x1800,\n  0x1800,0x1800,0x1800,0x1800, // u23a8\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,\n  0x1800,0x0c00,0x0e00,0x03c0, // u23a9\n  0xf000,0x1c00,0x0c00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600, // u23ab\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0300,0x01c0,0x01c0,0x0300,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600, // u23ac\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0c00,0x1c00,0xf000, // u23ad\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u23ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u23af\n  0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u23ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u23bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u23bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0xffc0,0xffc0, // u23bd\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u23d0\n  0x0000,0x0000,0xcc00,0xcc00,0xcc00,0xfc00,0xcc00,0xcc00,0xcc00,0x0000,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0000,0x0000,0x0000, // u2409\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xfc00,0x0000,0x1f80,0x1800,0x1800,0x1e00,0x1800,0x1800,\n  0x1800,0x0000,0x0000,0x0000, // u240a\n  0x0000,0x0000,0xcc00,0xcc00,0xcc00,0xcc00,0xcc00,0x7800,0x3000,0x0000,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0000,0x0000,0x0000, // u240b\n  0x0000,0x0000,0xfc00,0xc000,0xc000,0xf000,0xc000,0xc000,0xc000,0x0000,0x1f80,0x1800,0x1800,0x1e00,0x1800,0x1800,\n  0x1800,0x0000,0x0000,0x0000, // u240c\n  0x0000,0x0000,0x7800,0xcc00,0xc000,0xc000,0xc000,0xcc00,0x7800,0x0000,0x1f00,0x1980,0x1980,0x1f00,0x1e00,0x1b00,\n  0x1980,0x0000,0x0000,0x0000, // u240d\n  0x0000,0x0000,0xcc00,0xcc00,0xec00,0xfc00,0xdc00,0xcc00,0xcc00,0x0000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,\n  0x1f80,0x0000,0x0000,0x0000, // u2424\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2500\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2501\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2502\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u2503\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xd680,0xd680,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2508\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xd680,0xd680,0xd680,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2509\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0000, // u250a\n  0x1c00,0x1c00,0x1c00,0x1c00,0x0000,0x1c00,0x1c00,0x1c00,0x1c00,0x0000,0x1c00,0x1c00,0x1c00,0x1c00,0x0000,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x0000, // u250b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u250c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fc0,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u250d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x1fc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u250e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x1fc0,0x1fc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u250f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2510\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2511\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u2512\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0xfc00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u2513\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2514\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2515\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1fc0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2516\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1fc0,0x1fc0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2517\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2518\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2519\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u251a\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xfc00,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u251b\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u251c\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0fc0,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u251d\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1fc0,0x1fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u251e\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1fc0,0x1fc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u251f\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1fc0,0x1fc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u2520\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1fc0,0x1fc0,0x1fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2521\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1fc0,0x1fc0,0x1fc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u2522\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1fc0,0x1fc0,0x1fc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u2523\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2524\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2525\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2526\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u2527\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xfc00,0xfc00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u2528\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xfc00,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2529\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0xfc00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u252a\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xfc00,0xfc00,0xfc00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u252b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u252c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u252d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u252e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u252f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u2530\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xffc0,0xffc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u2531\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0xffc0,0xffc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u2532\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0xffc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u2533\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2534\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2535\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2536\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2537\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2538\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xfc00,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2539\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1fc0,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u253a\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xffc0,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u253b\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u253c\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u253d\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u253e\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u253f\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2540\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xffc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u2541\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xffc0,0xffc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u2542\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xfc00,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2543\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1fc0,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2544\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xffc0,0xffc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u2545\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0xffc0,0xffc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u2546\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xffc0,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2547\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xffc0,0xffc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u2548\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xfc00,0xffc0,0xffc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u2549\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1fc0,0xffc0,0xffc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u254a\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0xffc0,0xffc0,0xffc0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u254b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x0000,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2550\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600,0x3600,0x3600, // u2551\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fc0,0x0c00,0x0fc0,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2552\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x3fc0,0x3600,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600,0x3600,0x3600, // u2553\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x3fc0,0x3000,0x37c0,0x37c0,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600,0x3600,0x3600, // u2554\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x0c00,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2555\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xfe00,0x3600,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600,0x3600,0x3600, // u2556\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xfe00,0x0600,0xf600,0xf600,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600,0x3600,0x3600, // u2557\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0fc0,0x0c00,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2558\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3fc0,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2559\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x37c0,0x37c0,0x3000,0x3fc0,0x3fc0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u255a\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0x0c00,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u255b\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0xfe00,0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u255c\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0xf600,0xf600,0x0600,0xfe00,0xfe00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u255d\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0fc0,0x0c00,0x0fc0,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u255e\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x37c0,0x37c0,0x3600,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600,0x3600,0x3600, // u255f\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x37c0,0x37c0,0x3000,0x37c0,0x37c0,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600,0x3600,0x3600, // u2560\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0x0c00,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2561\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0xf600,0xf600,0x3600,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600,0x3600,0x3600, // u2562\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0xf600,0xf600,0x0600,0xf600,0xf600,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600,0x3600,0x3600, // u2563\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x0000,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2564\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x3600,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600,0x3600,0x3600, // u2565\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x0000,0xf7c0,0xf7c0,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600,0x3600,0x3600, // u2566\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xffc0,0x0000,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2567\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2568\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0xf7c0,0xf7c0,0x0000,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2569\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0xffc0,0x0c00,0xffc0,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u256a\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0xffc0,0xffc0,0x3600,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600,0x3600,0x3600, // u256b\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0x3600,0xf7c0,0xf7c0,0x0000,0xf7c0,0xf7c0,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600,0x3600,0x3600, // u256c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x03c0,0x0700,0x0e00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u256d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xe000,0xf000,0x3800,0x1c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u256e\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1c00,0x3800,0xf000,0xe000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u256f\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0e00,0x0700,0x03c0,0x01c0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2570\n  0x0040,0x0040,0x00c0,0x0080,0x0180,0x0100,0x0300,0x0200,0x0600,0x0400,0x0c00,0x0800,0x1800,0x1000,0x3000,0x2000,\n  0x6000,0x4000,0xc000,0x8000, // u2571\n  0x8000,0xc000,0x4000,0x6000,0x2000,0x3000,0x1000,0x1800,0x0800,0x0c00,0x0400,0x0600,0x0200,0x0300,0x0100,0x0180,\n  0x0080,0x00c0,0x0040,0x0040, // u2572\n  0x8040,0xc040,0x40c0,0x6080,0x2180,0x3100,0x1300,0x1a00,0x0e00,0x0c00,0x0c00,0x0e00,0x1a00,0x1300,0x3100,0x2180,\n  0x6080,0x40c0,0xc040,0x8040, // u2573\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2574\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2575\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2576\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u2577\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2578\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2579\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u257a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u257b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u257c\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c00, // u257d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u257e\n  0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00, // u257f\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2580\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0xffc0,0xffc0,0xffc0, // u2581\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0, // u2582\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0, // u2583\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0, // u2584\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0, // u2585\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0, // u2586\n  0x0000,0x0000,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0, // u2587\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0, // u2588\n  0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,\n  0xff80,0xff80,0xff80,0xff80, // u2589\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,\n  0xff00,0xff00,0xff00,0xff00, // u258a\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,\n  0xfc00,0xfc00,0xfc00,0xfc00, // u258b\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800,0xf800,0xf800, // u258c\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,\n  0xf000,0xf000,0xf000,0xf000, // u258d\n  0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,\n  0xe000,0xe000,0xe000,0xe000, // u258e\n  0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,\n  0x8000,0x8000,0x8000,0x8000, // u258f\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,\n  0x07c0,0x07c0,0x07c0,0x07c0, // u2590\n  0xaa80,0x0000,0xaa80,0x0000,0xaa80,0x0000,0xaa80,0x0000,0xaa80,0x0000,0xaa80,0x0000,0xaa80,0x0000,0xaa80,0x0000,\n  0xaa80,0x0000,0xaa80,0x0000, // u2591\n  0xaa80,0x5540,0xaa80,0x5540,0xaa80,0x5540,0xaa80,0x5540,0xaa80,0x5540,0xaa80,0x5540,0xaa80,0x5540,0xaa80,0x5540,\n  0xaa80,0x5540,0xaa80,0x5540, // u2592\n  0xffc0,0xaa80,0xffc0,0xaa80,0xffc0,0xaa80,0xffc0,0xaa80,0xffc0,0xaa80,0xffc0,0xaa80,0xffc0,0xaa80,0xffc0,0xaa80,\n  0xffc0,0xaa80,0xffc0,0xaa80, // u2593\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800,0xf800,0xf800, // u2596\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,\n  0x07c0,0x07c0,0x07c0,0x07c0, // u2597\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2598\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0, // u2599\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,\n  0x07c0,0x07c0,0x07c0,0x07c0, // u259a\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800,0xf800,0xf800, // u259b\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,\n  0x07c0,0x07c0,0x07c0,0x07c0, // u259c\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u259d\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800,0xf800,0xf800, // u259e\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0, // u259f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x3f00,0x3f00,0x3f00,0x3f00,0x3f00,0x3f00,0x3f00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u25a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,0xff80,0xff80,0xff80,0xff80,\n  0x0000,0x0000,0x0000,0x0000, // u25ac\n  0x0000,0x0000,0x0000,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u25ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x1e00,0x1e00,0x3f00,0x3f00,0x7f80,0x7f80,0xffc0,0xffc0,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u25b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xffc0,0xffc0,0xff00,0xfc00,0xf000,0xc000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u25b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xffc0,0xffc0,0xff00,0xfc00,0xf000,0xc000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u25ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x7f80,0x7f80,0x3f00,0x3f00,0x1e00,0x1e00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u25bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x03c0,0x0fc0,0x3fc0,0xffc0,0xffc0,0x3fc0,0x0fc0,0x03c0,0x00c0,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u25c0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x03c0,0x0fc0,0x3fc0,0xffc0,0xffc0,0x3fc0,0x0fc0,0x03c0,0x00c0,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u25c4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x1e00,0x3f00,0x7f80,0xffc0,0xffc0,0x7f80,0x3f00,0x1e00,0x0c00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u25c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x1e00,0x3300,0x6180,0xc0c0,0xc0c0,0x6180,0x3300,0x1e00,0x0c00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u25ca\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x2100,0x2100,0x3300,0x1e00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u25cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3f00,0x3f00,0x3f00,0x3f00,0x1e00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u25cf\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xf3c0,0xe1c0,0xe1c0,0xf3c0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0, // u25d8\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xe1c0,0xccc0,0xdec0,0xdec0,0xccc0,0xe1c0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0, // u25d9\n  0x0000,0x0000,0x0000,0x7f80,0x8040,0x8040,0xb340,0xb340,0x8040,0x8040,0xbf40,0x9e40,0x8040,0x8040,0x8040,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u263a\n  0x0000,0x0000,0x0000,0x7f80,0xffc0,0xffc0,0xccc0,0xccc0,0xffc0,0xffc0,0xc0c0,0xe1c0,0xffc0,0xffc0,0xffc0,0x7f80,\n  0x0000,0x0000,0x0000,0x0000, // u263b\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0xccc0,0x6d80,0x3f00,0x1e00,0xf3c0,0x1e00,0x3f00,0x6d80,0xccc0,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u263c\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000, // u2640\n  0x0000,0x0000,0x0000,0x0f80,0x0380,0x0680,0x0c80,0x1880,0x7e00,0xc300,0xc300,0xc300,0xc300,0xc300,0xc300,0x7e00,\n  0x0000,0x0000,0x0000,0x0000, // u2642\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x1e00,0x3f00,0x7f80,0xffc0,0xffc0,0xffc0,0xffc0,0x6d80,0x0c00,0x0c00,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u2660\n  0x0000,0x0000,0x0000,0x1e00,0x3f00,0x3f00,0x1e00,0x0c00,0x6d80,0xffc0,0xffc0,0xffc0,0xffc0,0x6d80,0x0c00,0x3f00,\n  0x0000,0x0000,0x0000,0x0000, // u2663\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7380,0xf3c0,0xffc0,0xffc0,0xffc0,0xffc0,0x7f80,0x3f00,0x1e00,0x0c00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2665\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x1e00,0x3f00,0x7f80,0xffc0,0xffc0,0x7f80,0x3f00,0x1e00,0x0c00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2666\n  0x0000,0x0000,0x0000,0x3f80,0x3180,0x3180,0x3f80,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0xf000,0xe000,\n  0x0000,0x0000,0x0000,0x0000, // u266a\n  0x0000,0x0000,0x0000,0x7f80,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6380,0xe300,0xc000,\n  0x0000,0x0000,0x0000,0x0000, // u266b\n  0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x0180,0x0180,0xc300,0xc300,0x6600,0x6600,0x3c00,0x3c00,0x1800,0x1800,\n  0x0000,0x0000,0x0000,0x0000, // u2713\n  0x0000,0x0000,0x0000,0x0000,0x01c0,0x01c0,0x0380,0x0380,0xe700,0xe700,0x7e00,0x7e00,0x3c00,0x3c00,0x1800,0x1800,\n  0x0000,0x0000,0x0000,0x0000, // u2714\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x6300,0x3600,0x1e00,0x0c00,0x0e00,0x1b00,0x1980,0x3000,0x3000,0x6000,0x6000,\n  0x0000,0x0000,0x0000,0x0000, // u2717\n  0x0000,0x0000,0x0000,0x0000,0x0700,0xe700,0x7e00,0x3e00,0x1c00,0x1e00,0x3f00,0x3b80,0x7180,0x7000,0xe000,0xe000,\n  0x0000,0x0000,0x0000,0x0000, // u2718\n  0x0000,0x0000,0x0000,0x0600,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x1800,0x1800,0x0c00,0x0c00,0x0600,0x0600,\n  0x0000,0x0000,0x0000,0x0000, // u27e8\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x1800,0x1800,0x0c00,0x0c00,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x0000, // u27e9\n  0x0000,0x0000,0x0000,0x1980,0x1980,0x3300,0x3300,0x6600,0x6600,0xcc00,0x6600,0x6600,0x3300,0x3300,0x1980,0x1980,\n  0x0000,0x0000,0x0000,0x0000, // u27ea\n  0x0000,0x0000,0x0000,0xcc00,0xcc00,0x6600,0x6600,0x3300,0x3300,0x1980,0x3300,0x3300,0x6600,0x6600,0xcc00,0xcc00,\n  0x0000,0x0000,0x0000,0x0000, // u27eb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2800\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2801\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2802\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2803\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2804\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2805\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2806\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2807\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2808\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2809\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u280a\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u280b\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u280c\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u280d\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u280e\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u280f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2810\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2811\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2812\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2813\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2814\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2815\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2816\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2817\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2818\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2819\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u281a\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u281b\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u281c\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u281d\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u281e\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u281f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2820\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2821\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2822\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2823\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2824\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2825\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2826\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2827\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2828\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2829\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u282a\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u282b\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u282c\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u282d\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u282e\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u282f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2830\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2831\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2832\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2833\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2834\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2835\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2836\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2837\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2838\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2839\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u283a\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u283b\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u283c\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u283d\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u283e\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u283f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2840\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2841\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2842\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2843\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2844\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2845\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2846\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2847\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2848\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2849\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u284a\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u284b\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u284c\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u284d\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u284e\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u284f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2850\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2851\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2852\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2853\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2854\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2855\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2856\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2857\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2858\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2859\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u285a\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u285b\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u285c\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u285d\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u285e\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u285f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2860\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2861\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2862\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2863\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2864\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2865\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2866\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2867\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2868\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2869\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u286a\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u286b\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u286c\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u286d\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u286e\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u286f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2870\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2871\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2872\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2873\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2874\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2875\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2876\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2877\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2878\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u2879\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u287a\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u287b\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u287c\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u287d\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u287e\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6000,0x6000,0x0000,0x0000, // u287f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u2880\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u2881\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u2882\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u2883\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u2884\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u2885\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u2886\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u2887\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u2888\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u2889\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u288a\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u288b\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u288c\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u288d\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u288e\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u288f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u2890\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u2891\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u2892\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u2893\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u2894\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u2895\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u2896\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u2897\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u2898\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u2899\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u289a\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u289b\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u289c\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u289d\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u289e\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u289f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28a0\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28a2\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28a4\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28a5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28a6\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28a7\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28a8\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28a9\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28aa\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28ab\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28ac\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28ad\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28ae\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28af\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28b0\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28b1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28b2\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28b4\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28b6\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28b7\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28b8\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28b9\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28ba\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28bb\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28bc\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28bd\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28be\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0000,0x0000, // u28bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28c0\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28c2\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28c4\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28c6\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28c7\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28c8\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28c9\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28ca\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28cb\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28cc\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28cd\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28ce\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28cf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28d0\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28d2\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28d4\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28d6\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28d7\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28d8\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28d9\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28da\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28db\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28dc\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28dd\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28de\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28df\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28e0\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28e1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28e2\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28e3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28e4\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28e6\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28e7\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28e8\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28e9\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28ea\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28eb\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28ec\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28ed\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28ee\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28ef\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28f0\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28f2\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28f3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28f4\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28f6\n  0x0000,0x6000,0x6000,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28f7\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28f8\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28f9\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28fa\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28fb\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28fc\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28fd\n  0x0000,0x0300,0x0300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28fe\n  0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,0x6300,0x6300,0x0000,0x0000,0x0000,\n  0x6300,0x6300,0x0000,0x0000, // u28ff\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u2e2c\n  0xc000,0xc000,0xc600,0xcf00,0xdf80,0xf6c0,0xc600,0xc600,0xc600,0xc600,0x8c00,0x1800,0x3000,0x6000,0xc000,0xc000,\n  0xc000,0xc000,0xc000,0xc000, // ue0a0\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xfc00,0x0000,0x1980,0x1980,0x1d80,0x1f80,0x1b80,0x1980,\n  0x1980,0x0000,0x0000,0x0000, // ue0a1\n  0x0000,0x0000,0x0000,0x3e00,0x6300,0x6300,0x6300,0x6300,0x6300,0xff80,0xff80,0xf780,0xe380,0xe380,0xf780,0xff80,\n  0xff80,0x0000,0x0000,0x0000, // ue0a2\n  0x8000,0xc000,0xe000,0xf000,0xf800,0xfc00,0xfe00,0xff00,0xff80,0xffc0,0xffc0,0xff80,0xff00,0xfe00,0xfc00,0xf800,\n  0xf000,0xe000,0xc000,0x8000, // ue0b0\n  0x8000,0xc000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x00c0,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,\n  0x3000,0x6000,0xc000,0x8000, // ue0b1\n  0x0040,0x00c0,0x01c0,0x03c0,0x07c0,0x0fc0,0x1fc0,0x3fc0,0x7fc0,0xffc0,0xffc0,0x7fc0,0x3fc0,0x1fc0,0x0fc0,0x07c0,\n  0x03c0,0x01c0,0x00c0,0x0040, // ue0b2\n  0x0040,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0xc000,0x6000,0x3000,0x1800,0x0c00,0x0600,\n  0x0300,0x0180,0x00c0,0x0040, // ue0b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x3300,0x3300,0x1e00,0x0000, // uf6be\n  0x0000,0x0000,0x0000,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,\n  0x0000,0x0000,0x0000,0x0000 // ufffd\n  };\n  // codepoints array\n  constexpr std::array<uint16_t, CHARCOUNT> fixedfont_codepoints = {\n  0x0000,0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,\n  0x002f,0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,\n  0x003f,0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,\n  0x004f,0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,\n  0x005f,0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,\n  0x006f,0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,\n  0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af,\n  0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf,\n  0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf,\n  0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df,\n  0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef,\n  0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff,\n  0x0100,0x0101,0x0102,0x0103,0x0104,0x0105,0x0106,0x0107,0x0108,0x0109,0x010a,0x010b,0x010c,0x010d,0x010e,0x010f,\n  0x0110,0x0111,0x0112,0x0113,0x0114,0x0115,0x0116,0x0117,0x0118,0x0119,0x011a,0x011b,0x011c,0x011d,0x011e,0x011f,\n  0x0120,0x0121,0x0122,0x0123,0x0124,0x0125,0x0126,0x0127,0x0128,0x0129,0x012a,0x012b,0x012c,0x012d,0x012e,0x012f,\n  0x0130,0x0131,0x0132,0x0133,0x0134,0x0135,0x0136,0x0137,0x0138,0x0139,0x013a,0x013b,0x013c,0x013d,0x013e,0x013f,\n  0x0140,0x0141,0x0142,0x0143,0x0144,0x0145,0x0146,0x0147,0x0148,0x0149,0x014a,0x014b,0x014c,0x014d,0x014e,0x014f,\n  0x0150,0x0151,0x0152,0x0153,0x0154,0x0155,0x0156,0x0157,0x0158,0x0159,0x015a,0x015b,0x015c,0x015d,0x015e,0x015f,\n  0x0160,0x0161,0x0162,0x0163,0x0164,0x0165,0x0166,0x0167,0x0168,0x0169,0x016a,0x016b,0x016c,0x016d,0x016e,0x016f,\n  0x0170,0x0171,0x0172,0x0173,0x0174,0x0175,0x0176,0x0177,0x0178,0x0179,0x017a,0x017b,0x017c,0x017d,0x017e,0x017f,\n  0x0186,0x018e,0x018f,0x0190,0x0192,0x019d,0x019e,0x01b5,0x01b6,0x01b7,0x01cd,0x01ce,0x01cf,0x01d0,0x01d1,0x01d2,\n  0x01d3,0x01d4,0x01e2,0x01e3,0x01e4,0x01e5,0x01e6,0x01e7,0x01e8,0x01e9,0x01ea,0x01eb,0x01ec,0x01ed,0x01ee,0x01ef,\n  0x01f0,0x01f4,0x01f5,0x01fc,0x01fd,0x01fe,0x01ff,0x0218,0x0219,0x021a,0x021b,0x0232,0x0233,0x0237,0x0254,0x0258,\n  0x0259,0x025b,0x0272,0x0292,0x02bb,0x02bc,0x02bd,0x02c6,0x02c7,0x02d8,0x02d9,0x02db,0x02dc,0x02dd,0x0300,0x0301,\n  0x0302,0x0303,0x0304,0x0305,0x0306,0x0307,0x0308,0x030a,0x030b,0x030c,0x0329,0x0384,0x0385,0x0386,0x0387,0x0388,\n  0x0389,0x038a,0x038c,0x038e,0x038f,0x0390,0x0391,0x0392,0x0393,0x0394,0x0395,0x0396,0x0397,0x0398,0x0399,0x039a,\n  0x039b,0x039c,0x039d,0x039e,0x039f,0x03a0,0x03a1,0x03a3,0x03a4,0x03a5,0x03a6,0x03a7,0x03a8,0x03a9,0x03aa,0x03ab,\n  0x03ac,0x03ad,0x03ae,0x03af,0x03b0,0x03b1,0x03b2,0x03b3,0x03b4,0x03b5,0x03b6,0x03b7,0x03b8,0x03b9,0x03ba,0x03bb,\n  0x03bc,0x03bd,0x03be,0x03bf,0x03c0,0x03c1,0x03c2,0x03c3,0x03c4,0x03c5,0x03c6,0x03c7,0x03c8,0x03c9,0x03ca,0x03cb,\n  0x03cc,0x03cd,0x03ce,0x03d1,0x03d5,0x03f0,0x03f1,0x03f2,0x03f3,0x03f4,0x03f5,0x03f6,0x0400,0x0401,0x0402,0x0403,\n  0x0404,0x0405,0x0406,0x0407,0x0408,0x0409,0x040a,0x040b,0x040c,0x040d,0x040e,0x040f,0x0410,0x0411,0x0412,0x0413,\n  0x0414,0x0415,0x0416,0x0417,0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e,0x041f,0x0420,0x0421,0x0422,0x0423,\n  0x0424,0x0425,0x0426,0x0427,0x0428,0x0429,0x042a,0x042b,0x042c,0x042d,0x042e,0x042f,0x0430,0x0431,0x0432,0x0433,\n  0x0434,0x0435,0x0436,0x0437,0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e,0x043f,0x0440,0x0441,0x0442,0x0443,\n  0x0444,0x0445,0x0446,0x0447,0x0448,0x0449,0x044a,0x044b,0x044c,0x044d,0x044e,0x044f,0x0450,0x0451,0x0452,0x0453,\n  0x0454,0x0455,0x0456,0x0457,0x0458,0x0459,0x045a,0x045b,0x045c,0x045d,0x045e,0x045f,0x0462,0x0463,0x046a,0x046b,\n  0x0490,0x0491,0x0492,0x0493,0x0494,0x0495,0x0496,0x0497,0x0498,0x0499,0x049a,0x049b,0x049c,0x049d,0x04a0,0x04a1,\n  0x04a2,0x04a3,0x04a4,0x04a5,0x04aa,0x04ab,0x04ae,0x04af,0x04b0,0x04b1,0x04b2,0x04b3,0x04b6,0x04b7,0x04b8,0x04b9,\n  0x04ba,0x04bb,0x04c0,0x04c1,0x04c2,0x04cf,0x04d0,0x04d1,0x04d2,0x04d3,0x04d4,0x04d5,0x04d6,0x04d7,0x04d8,0x04d9,\n  0x04da,0x04db,0x04dc,0x04dd,0x04de,0x04df,0x04e2,0x04e3,0x04e4,0x04e5,0x04e6,0x04e7,0x04e8,0x04e9,0x04ea,0x04eb,\n  0x04ec,0x04ed,0x04ee,0x04ef,0x04f0,0x04f1,0x04f2,0x04f3,0x04f4,0x04f5,0x04f8,0x04f9,0x05d0,0x05d1,0x05d2,0x05d3,\n  0x05d4,0x05d5,0x05d6,0x05d7,0x05d8,0x05d9,0x05da,0x05db,0x05dc,0x05dd,0x05de,0x05df,0x05e0,0x05e1,0x05e2,0x05e3,\n  0x05e4,0x05e5,0x05e6,0x05e7,0x05e8,0x05e9,0x05ea,0x1e0c,0x1e0d,0x1e34,0x1e35,0x1e36,0x1e37,0x1e40,0x1e41,0x1e42,\n  0x1e43,0x1e44,0x1e45,0x1e46,0x1e47,0x1e6c,0x1e6d,0x1eb8,0x1eb9,0x1ebc,0x1ebd,0x1eca,0x1ecb,0x1ecc,0x1ecd,0x1ee4,\n  0x1ee5,0x1ef8,0x1ef9,0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007,0x2008,0x2009,0x200a,0x200b,0x200c,\n  0x200d,0x200e,0x200f,0x2010,0x2011,0x2012,0x2013,0x2014,0x2015,0x2016,0x2017,0x2018,0x2019,0x201a,0x201b,0x201c,\n  0x201d,0x201e,0x201f,0x2020,0x2021,0x2022,0x2026,0x2030,0x2032,0x2033,0x2039,0x203a,0x203c,0x203e,0x2070,0x2071,\n  0x2074,0x2075,0x2076,0x2077,0x2078,0x2079,0x207a,0x207b,0x207c,0x207d,0x207e,0x207f,0x2080,0x2081,0x2082,0x2083,\n  0x2084,0x2085,0x2086,0x2087,0x2088,0x2089,0x208a,0x208b,0x208c,0x208d,0x208e,0x2090,0x2091,0x2092,0x2093,0x2094,\n  0x2095,0x2096,0x2097,0x2098,0x209a,0x20a7,0x20aa,0x20ac,0x20ae,0x2102,0x210e,0x210f,0x2115,0x2116,0x211a,0x211d,\n  0x2122,0x2124,0x2126,0x2135,0x2190,0x2191,0x2192,0x2193,0x2194,0x2195,0x21a4,0x21a6,0x21a8,0x21b5,0x21bb,0x21cb,\n  0x21cc,0x21d0,0x21d1,0x21d2,0x21d3,0x21d4,0x21d5,0x2200,0x2203,0x2204,0x2205,0x2206,0x2207,0x2208,0x2209,0x220a,\n  0x220b,0x220c,0x220d,0x2212,0x2213,0x2214,0x2215,0x2216,0x2219,0x221a,0x221e,0x221f,0x2225,0x2227,0x2228,0x2229,\n  0x222a,0x2248,0x2260,0x2261,0x2264,0x2265,0x226a,0x226b,0x2282,0x2283,0x2286,0x2287,0x22a5,0x22c2,0x22c3,0x2300,\n  0x2302,0x2308,0x2309,0x230a,0x230b,0x2310,0x2319,0x2320,0x2321,0x239b,0x239c,0x239d,0x239e,0x239f,0x23a0,0x23a1,\n  0x23a2,0x23a3,0x23a4,0x23a5,0x23a6,0x23a7,0x23a8,0x23a9,0x23ab,0x23ac,0x23ad,0x23ae,0x23af,0x23ba,0x23bb,0x23bc,\n  0x23bd,0x23d0,0x2409,0x240a,0x240b,0x240c,0x240d,0x2424,0x2500,0x2501,0x2502,0x2503,0x2508,0x2509,0x250a,0x250b,\n  0x250c,0x250d,0x250e,0x250f,0x2510,0x2511,0x2512,0x2513,0x2514,0x2515,0x2516,0x2517,0x2518,0x2519,0x251a,0x251b,\n  0x251c,0x251d,0x251e,0x251f,0x2520,0x2521,0x2522,0x2523,0x2524,0x2525,0x2526,0x2527,0x2528,0x2529,0x252a,0x252b,\n  0x252c,0x252d,0x252e,0x252f,0x2530,0x2531,0x2532,0x2533,0x2534,0x2535,0x2536,0x2537,0x2538,0x2539,0x253a,0x253b,\n  0x253c,0x253d,0x253e,0x253f,0x2540,0x2541,0x2542,0x2543,0x2544,0x2545,0x2546,0x2547,0x2548,0x2549,0x254a,0x254b,\n  0x2550,0x2551,0x2552,0x2553,0x2554,0x2555,0x2556,0x2557,0x2558,0x2559,0x255a,0x255b,0x255c,0x255d,0x255e,0x255f,\n  0x2560,0x2561,0x2562,0x2563,0x2564,0x2565,0x2566,0x2567,0x2568,0x2569,0x256a,0x256b,0x256c,0x256d,0x256e,0x256f,\n  0x2570,0x2571,0x2572,0x2573,0x2574,0x2575,0x2576,0x2577,0x2578,0x2579,0x257a,0x257b,0x257c,0x257d,0x257e,0x257f,\n  0x2580,0x2581,0x2582,0x2583,0x2584,0x2585,0x2586,0x2587,0x2588,0x2589,0x258a,0x258b,0x258c,0x258d,0x258e,0x258f,\n  0x2590,0x2591,0x2592,0x2593,0x2596,0x2597,0x2598,0x2599,0x259a,0x259b,0x259c,0x259d,0x259e,0x259f,0x25a0,0x25ac,\n  0x25ae,0x25b2,0x25b6,0x25ba,0x25bc,0x25c0,0x25c4,0x25c6,0x25ca,0x25cb,0x25cf,0x25d8,0x25d9,0x263a,0x263b,0x263c,\n  0x2640,0x2642,0x2660,0x2663,0x2665,0x2666,0x266a,0x266b,0x2713,0x2714,0x2717,0x2718,0x27e8,0x27e9,0x27ea,0x27eb,\n  0x2800,0x2801,0x2802,0x2803,0x2804,0x2805,0x2806,0x2807,0x2808,0x2809,0x280a,0x280b,0x280c,0x280d,0x280e,0x280f,\n  0x2810,0x2811,0x2812,0x2813,0x2814,0x2815,0x2816,0x2817,0x2818,0x2819,0x281a,0x281b,0x281c,0x281d,0x281e,0x281f,\n  0x2820,0x2821,0x2822,0x2823,0x2824,0x2825,0x2826,0x2827,0x2828,0x2829,0x282a,0x282b,0x282c,0x282d,0x282e,0x282f,\n  0x2830,0x2831,0x2832,0x2833,0x2834,0x2835,0x2836,0x2837,0x2838,0x2839,0x283a,0x283b,0x283c,0x283d,0x283e,0x283f,\n  0x2840,0x2841,0x2842,0x2843,0x2844,0x2845,0x2846,0x2847,0x2848,0x2849,0x284a,0x284b,0x284c,0x284d,0x284e,0x284f,\n  0x2850,0x2851,0x2852,0x2853,0x2854,0x2855,0x2856,0x2857,0x2858,0x2859,0x285a,0x285b,0x285c,0x285d,0x285e,0x285f,\n  0x2860,0x2861,0x2862,0x2863,0x2864,0x2865,0x2866,0x2867,0x2868,0x2869,0x286a,0x286b,0x286c,0x286d,0x286e,0x286f,\n  0x2870,0x2871,0x2872,0x2873,0x2874,0x2875,0x2876,0x2877,0x2878,0x2879,0x287a,0x287b,0x287c,0x287d,0x287e,0x287f,\n  0x2880,0x2881,0x2882,0x2883,0x2884,0x2885,0x2886,0x2887,0x2888,0x2889,0x288a,0x288b,0x288c,0x288d,0x288e,0x288f,\n  0x2890,0x2891,0x2892,0x2893,0x2894,0x2895,0x2896,0x2897,0x2898,0x2899,0x289a,0x289b,0x289c,0x289d,0x289e,0x289f,\n  0x28a0,0x28a1,0x28a2,0x28a3,0x28a4,0x28a5,0x28a6,0x28a7,0x28a8,0x28a9,0x28aa,0x28ab,0x28ac,0x28ad,0x28ae,0x28af,\n  0x28b0,0x28b1,0x28b2,0x28b3,0x28b4,0x28b5,0x28b6,0x28b7,0x28b8,0x28b9,0x28ba,0x28bb,0x28bc,0x28bd,0x28be,0x28bf,\n  0x28c0,0x28c1,0x28c2,0x28c3,0x28c4,0x28c5,0x28c6,0x28c7,0x28c8,0x28c9,0x28ca,0x28cb,0x28cc,0x28cd,0x28ce,0x28cf,\n  0x28d0,0x28d1,0x28d2,0x28d3,0x28d4,0x28d5,0x28d6,0x28d7,0x28d8,0x28d9,0x28da,0x28db,0x28dc,0x28dd,0x28de,0x28df,\n  0x28e0,0x28e1,0x28e2,0x28e3,0x28e4,0x28e5,0x28e6,0x28e7,0x28e8,0x28e9,0x28ea,0x28eb,0x28ec,0x28ed,0x28ee,0x28ef,\n  0x28f0,0x28f1,0x28f2,0x28f3,0x28f4,0x28f5,0x28f6,0x28f7,0x28f8,0x28f9,0x28fa,0x28fb,0x28fc,0x28fd,0x28fe,0x28ff,\n  0x2e2c,0xe0a0,0xe0a1,0xe0a2,0xe0b0,0xe0b1,0xe0b2,0xe0b3,0xf6be,0xfffd };\n} // namespace\n// -- end of autogenerated text ---\n\nnamespace fixed_font_22n {\n  // -- start of autogenerated text ---\n  // definition section for font: ter-u22n.bdf\n  constexpr int CHARCOUNT = 1354;\n  constexpr int WIDTH = 11;\n  constexpr int HEIGHT = 22;\n  constexpr int OFFSET_X = 0;\n  constexpr int OFFSET_Y = 0;\n  constexpr FixedFont_info_t fixedfont_info = {\n    \"Terminus\", // font name\n    \"ter-u22n.bdf\", // font name internal\n    CHARCOUNT, // num of chars\n    WIDTH, HEIGHT, OFFSET_X, OFFSET_Y,\n    false // bold\n  };\n  // font bitmap definitions\n  constexpr std::array<uint16_t, CHARCOUNT * HEIGHT> fixedfont_bitmap = {\n  0x0000,0x0000,0x0000,0x7380,0x4080,0x4080,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x0000,0x0000,0x4080,0x4080,\n  0x7380,0x0000,0x0000,0x0000,0x0000,0x0000, // u0000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0020\n  0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u0021\n  0x0000,0x1100,0x1100,0x1100,0x1100,0x1100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0022\n  0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,0x1100,0x7fc0,0x1100,0x1100,0x1100,0x1100,0x7fc0,0x1100,0x1100,0x1100,\n  0x1100,0x0000,0x0000,0x0000,0x0000,0x0000, // u0023\n  0x0000,0x0000,0x0400,0x0400,0x1f00,0x2480,0x4440,0x4400,0x4400,0x2400,0x1f00,0x0480,0x0440,0x0440,0x4440,0x2480,\n  0x1f00,0x0400,0x0400,0x0000,0x0000,0x0000, // u0024\n  0x0000,0x0000,0x0000,0x3080,0x4880,0x4900,0x3100,0x0200,0x0200,0x0400,0x0400,0x0800,0x0800,0x1180,0x1240,0x2240,\n  0x2180,0x0000,0x0000,0x0000,0x0000,0x0000, // u0025\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x2100,0x2100,0x1200,0x0c00,0x1400,0x2240,0x4140,0x4080,0x4080,0x4080,0x2140,\n  0x1e40,0x0000,0x0000,0x0000,0x0000,0x0000, // u0026\n  0x0000,0x0400,0x0400,0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0027\n  0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x0800,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x0800,0x0800,0x0400,\n  0x0200,0x0000,0x0000,0x0000,0x0000,0x0000, // u0028\n  0x0000,0x0000,0x0000,0x1000,0x0800,0x0400,0x0400,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0400,0x0400,0x0800,\n  0x1000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0029\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x1100,0x0a00,0x0400,0x7fc0,0x0400,0x0a00,0x1100,0x2080,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x7fc0,0x0400,0x0400,0x0400,0x0400,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,\n  0x0400,0x0800,0x0000,0x0000,0x0000,0x0000, // u002c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u002e\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0100,0x0100,0x0200,0x0200,0x0400,0x0400,0x0800,0x0800,0x1000,0x1000,0x2000,\n  0x2000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002f\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4180,0x4280,0x4480,0x4880,0x5080,0x6080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0030\n  0x0000,0x0000,0x0000,0x0400,0x0c00,0x1400,0x2400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0031\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0032\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x0080,0x0080,0x0100,0x1e00,0x0100,0x0080,0x0080,0x0080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0033\n  0x0000,0x0000,0x0000,0x0080,0x0180,0x0280,0x0480,0x0880,0x1080,0x2080,0x4080,0x4080,0x4080,0x7f80,0x0080,0x0080,\n  0x0080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0034\n  0x0000,0x0000,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0100,0x0080,0x0080,0x0080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0035\n  0x0000,0x0000,0x0000,0x1f00,0x2000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0036\n  0x0000,0x0000,0x0000,0x7f80,0x4080,0x4080,0x0080,0x0100,0x0100,0x0200,0x0200,0x0400,0x0400,0x0800,0x0800,0x0800,\n  0x0800,0x0000,0x0000,0x0000,0x0000,0x0000, // u0037\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x2100,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0038\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,0x1f80,0x0080,0x0080,0x0080,0x0100,\n  0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,\n  0x0400,0x0800,0x0000,0x0000,0x0000,0x0000, // u003b\n  0x0000,0x0000,0x0000,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,\n  0x0080,0x0000,0x0000,0x0000,0x0000,0x0000, // u003c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003d\n  0x0000,0x0000,0x0000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,0x0080,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,\n  0x2000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003e\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x0080,0x0100,0x0200,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u003f\n  0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x43c0,0x4440,0x4840,0x4840,0x4840,0x4840,0x4440,0x43c0,0x4000,0x2000,\n  0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0040\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0041\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4100,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4100,\n  0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0042\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0043\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4100,\n  0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0044\n  0x0000,0x0000,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0045\n  0x0000,0x0000,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0046\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4000,0x4000,0x4000,0x4780,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0047\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0048\n  0x0000,0x0000,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0049\n  0x0000,0x0000,0x0000,0x07c0,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x4100,0x4100,0x4100,0x2200,\n  0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u004a\n  0x0000,0x0000,0x0000,0x4080,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u004b\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u004c\n  0x0000,0x0000,0x0000,0x4040,0x60c0,0x5140,0x5140,0x4a40,0x4440,0x4440,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u004d\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x6080,0x5080,0x4880,0x4480,0x4280,0x4180,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u004e\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u004f\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4100,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0050\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4880,0x2500,\n  0x1e00,0x0100,0x0080,0x0000,0x0000,0x0000, // u0051\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4100,0x7e00,0x5000,0x4800,0x4400,0x4200,0x4100,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0052\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4000,0x4000,0x2000,0x1e00,0x0100,0x0080,0x0080,0x0080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0053\n  0x0000,0x0000,0x0000,0x7fc0,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u0054\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0055\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,0x2100,0x2100,0x2100,0x1200,0x1200,0x1200,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0056\n  0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4440,0x4440,0x4a40,0x5140,0x5140,0x60c0,\n  0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0057\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x2100,0x2100,0x1200,0x1200,0x0c00,0x0c00,0x1200,0x1200,0x2100,0x2100,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0058\n  0x0000,0x0000,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0a00,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u0059\n  0x0000,0x0000,0x0000,0x7f80,0x0080,0x0080,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u005a\n  0x0000,0x0000,0x0000,0x1e00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u005b\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x1000,0x1000,0x0800,0x0800,0x0400,0x0400,0x0200,0x0200,0x0100,0x0100,0x0080,\n  0x0080,0x0000,0x0000,0x0000,0x0000,0x0000, // u005c\n  0x0000,0x0000,0x0000,0x1e00,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u005d\n  0x0000,0x0400,0x0a00,0x1100,0x2080,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000, // u005f\n  0x1000,0x0800,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0060\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0100,0x0080,0x0080,0x3f80,0x4080,0x4080,0x4080,0x4080,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0061\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4100,\n  0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0062\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4000,0x4000,0x4000,0x4000,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0063\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0080,0x1f80,0x2080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0064\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x7f80,0x4000,0x4000,0x4000,0x2080,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0065\n  0x0000,0x0000,0x0000,0x0780,0x0800,0x0800,0x0800,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0000,0x0000,0x0000,0x0000,0x0000, // u0066\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x2080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0080,0x0080,0x0100,0x3e00,0x0000, // u0067\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0068\n  0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0069\n  0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0700,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0100,0x2100,0x2100,0x2100,0x1e00,0x0000, // u006a\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x2000,0x2080,0x2100,0x2200,0x2400,0x3800,0x3800,0x2400,0x2200,0x2100,\n  0x2080,0x0000,0x0000,0x0000,0x0000,0x0000, // u006b\n  0x0000,0x0000,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u006c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4480,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,\n  0x4440,0x0000,0x0000,0x0000,0x0000,0x0000, // u006d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u006e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u006f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4100,\n  0x7e00,0x4000,0x4000,0x4000,0x4000,0x0000, // u0070\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x2080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0080,0x0080,0x0080,0x0080,0x0000, // u0071\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4f80,0x5000,0x6000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0072\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x4080,0x4000,0x4000,0x3f00,0x0080,0x0080,0x0080,0x4080,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0073\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0780,0x0000,0x0000,0x0000,0x0000,0x0000, // u0074\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0075\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x2100,0x2100,0x2100,0x1200,0x1200,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0076\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0077\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x2100,0x1200,0x0c00,0x0c00,0x1200,0x2100,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0078\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0080,0x0080,0x0100,0x3e00,0x0000, // u0079\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u007a\n  0x0000,0x0000,0x0000,0x0300,0x0400,0x0800,0x0800,0x0800,0x0800,0x3000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0400,\n  0x0300,0x0000,0x0000,0x0000,0x0000,0x0000, // u007b\n  0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u007c\n  0x0000,0x0000,0x0000,0x3000,0x0800,0x0400,0x0400,0x0400,0x0400,0x0300,0x0400,0x0400,0x0400,0x0400,0x0400,0x0800,\n  0x3000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007d\n  0x0000,0x3080,0x4880,0x4480,0x4300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a0\n  0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x1f00,0x2480,0x4440,0x4400,0x4400,0x4400,0x4400,0x4440,0x2480,\n  0x1f00,0x0400,0x0400,0x0000,0x0000,0x0000, // u00a2\n  0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x2100,0x2000,0x2000,0x2000,0x7c00,0x2000,0x2000,0x2000,0x2000,0x2080,\n  0x2080,0x7f80,0x0000,0x0000,0x0000,0x0000, // u00a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x2080,0x1f00,0x2080,0x2080,0x2080,0x2080,0x2080,0x1f00,0x2080,0x4040,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a4\n  0x0000,0x0000,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0400,0x3f80,0x0400,0x0400,0x3f80,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a5\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a6\n  0x0000,0x0000,0x1e00,0x2100,0x2000,0x2000,0x1c00,0x2200,0x2100,0x2100,0x2100,0x2100,0x1100,0x0e00,0x0100,0x0100,\n  0x2100,0x1e00,0x0000,0x0000,0x0000,0x0000, // u00a7\n  0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4e40,0x5140,0x5040,0x5040,0x5040,0x5140,0x4e40,0x2080,0x1f00,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a9\n  0x0000,0x1f00,0x0080,0x0080,0x1f80,0x2080,0x2080,0x2080,0x1f80,0x0000,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0440,0x0880,0x1100,0x2200,0x4400,0x4400,0x2200,0x1100,0x0880,\n  0x0440,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ab\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0080,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ac\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ad\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x5e40,0x5140,0x5140,0x5e40,0x5440,0x5240,0x5140,0x2080,0x1f00,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ae\n  0x0000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00af\n  0x0000,0x0e00,0x1100,0x1100,0x1100,0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x7fc0,0x0400,0x0400,0x0400,0x0400,0x0000,0x0000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b1\n  0x0000,0x0e00,0x1100,0x1100,0x0100,0x0200,0x0400,0x0800,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b2\n  0x0000,0x0e00,0x1100,0x0100,0x0600,0x0100,0x0100,0x1100,0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b3\n  0x0200,0x0400,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4180,0x4280,\n  0x7c80,0x4000,0x4000,0x4000,0x4000,0x0000, // u00b5\n  0x0000,0x0000,0x0000,0x3fc0,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x3c40,0x0440,0x0440,0x0440,0x0440,0x0440,\n  0x0440,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0400,0x0400,0x0400,0x0800,0x0000, // u00b8\n  0x0000,0x0400,0x0c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b9\n  0x0000,0x1f00,0x2080,0x2080,0x2080,0x2080,0x2080,0x2080,0x1f00,0x0000,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x2200,0x1100,0x0880,0x0440,0x0440,0x0880,0x1100,0x2200,\n  0x4400,0x0000,0x0000,0x0000,0x0000,0x0000, // u00bb\n  0x0000,0x0000,0x1000,0x3000,0x5000,0x1040,0x1080,0x1100,0x1200,0x0400,0x0880,0x1180,0x2280,0x4480,0x0880,0x0f80,\n  0x0080,0x0080,0x0000,0x0000,0x0000,0x0000, // u00bc\n  0x0000,0x0000,0x1000,0x3000,0x5000,0x1040,0x1080,0x1100,0x1200,0x0400,0x0800,0x1380,0x2440,0x4440,0x0080,0x0100,\n  0x0200,0x07c0,0x0000,0x0000,0x0000,0x0000, // u00bd\n  0x0000,0x0000,0x3800,0x4400,0x0400,0x1800,0x0440,0x4480,0x3900,0x0200,0x0480,0x0980,0x1280,0x2480,0x4880,0x0f80,\n  0x0080,0x0080,0x0000,0x0000,0x0000,0x0000, // u00be\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0000,0x0000,0x0800,0x0800,0x1000,0x2000,0x4000,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00bf\n  0x1000,0x0800,0x0400,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c0\n  0x0200,0x0400,0x0800,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c1\n  0x0c00,0x1200,0x2100,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c2\n  0x1880,0x2480,0x2300,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c3\n  0x2100,0x2100,0x2100,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c4\n  0x0c00,0x1200,0x1200,0x0c00,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c5\n  0x0000,0x0000,0x0000,0x3fc0,0x4400,0x8400,0x8400,0x8400,0x8400,0xffc0,0x8400,0x8400,0x8400,0x8400,0x8400,0x8400,\n  0x87c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c6\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4080,0x4080,0x2100,\n  0x1e00,0x0400,0x0400,0x0400,0x0800,0x0000, // u00c7\n  0x1000,0x0800,0x0400,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c8\n  0x0200,0x0400,0x0800,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c9\n  0x0c00,0x1200,0x2100,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ca\n  0x2100,0x2100,0x2100,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cb\n  0x1000,0x0800,0x0400,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cc\n  0x0100,0x0200,0x0400,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cd\n  0x0c00,0x1200,0x2100,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ce\n  0x2100,0x2100,0x2100,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cf\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0xf880,0x4080,0x4080,0x4080,0x4080,0x4080,0x4100,\n  0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d0\n  0x1880,0x2480,0x2300,0x0000,0x4080,0x4080,0x4080,0x6080,0x5080,0x4880,0x4480,0x4280,0x4180,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d1\n  0x1000,0x0800,0x0400,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d2\n  0x0200,0x0400,0x0800,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d3\n  0x0c00,0x1200,0x2100,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d4\n  0x1880,0x2480,0x2300,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d5\n  0x2100,0x2100,0x2100,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x2100,0x1200,0x0c00,0x0c00,0x1200,0x2100,0x4080,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d7\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x40c0,0x4080,0x4180,0x4280,0x4480,0x4880,0x5080,0x6080,0x4080,0xc080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d8\n  0x1000,0x0800,0x0400,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d9\n  0x0200,0x0400,0x0800,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00da\n  0x0c00,0x1200,0x2100,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00db\n  0x2100,0x2100,0x2100,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00dc\n  0x0100,0x0200,0x0400,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0a00,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u00dd\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4100,\n  0x7e00,0x4000,0x4000,0x4000,0x4000,0x0000, // u00de\n  0x0000,0x0000,0x0000,0x3c00,0x4200,0x4100,0x4100,0x4100,0x4200,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x6100,\n  0x5e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00df\n  0x0000,0x0000,0x0000,0x1000,0x0800,0x0400,0x0000,0x3e00,0x0100,0x0080,0x0080,0x3f80,0x4080,0x4080,0x4080,0x4080,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e0\n  0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x0000,0x3e00,0x0100,0x0080,0x0080,0x3f80,0x4080,0x4080,0x4080,0x4080,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e1\n  0x0000,0x0000,0x0000,0x0c00,0x1200,0x2100,0x0000,0x3e00,0x0100,0x0080,0x0080,0x3f80,0x4080,0x4080,0x4080,0x4080,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e2\n  0x0000,0x0000,0x0000,0x1880,0x2480,0x2300,0x0000,0x3e00,0x0100,0x0080,0x0080,0x3f80,0x4080,0x4080,0x4080,0x4080,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e3\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x3e00,0x0100,0x0080,0x0080,0x3f80,0x4080,0x4080,0x4080,0x4080,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e4\n  0x0000,0x0000,0x0000,0x0c00,0x1200,0x1200,0x0c00,0x3e00,0x0100,0x0080,0x0080,0x3f80,0x4080,0x4080,0x4080,0x4080,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3b80,0x0440,0x0440,0x0440,0x3fc0,0x4400,0x4400,0x4400,0x4440,\n  0x3b80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4000,0x4000,0x4000,0x4000,0x4080,0x2100,\n  0x1e00,0x0400,0x0400,0x0400,0x0800,0x0000, // u00e7\n  0x0000,0x0000,0x0000,0x1000,0x0800,0x0400,0x0000,0x1e00,0x2100,0x4080,0x4080,0x7f80,0x4000,0x4000,0x4000,0x2080,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e8\n  0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x0000,0x1e00,0x2100,0x4080,0x4080,0x7f80,0x4000,0x4000,0x4000,0x2080,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e9\n  0x0000,0x0000,0x0000,0x0c00,0x1200,0x2100,0x0000,0x1e00,0x2100,0x4080,0x4080,0x7f80,0x4000,0x4000,0x4000,0x2080,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ea\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x1e00,0x2100,0x4080,0x4080,0x7f80,0x4000,0x4000,0x4000,0x2080,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00eb\n  0x0000,0x0000,0x0000,0x1000,0x0800,0x0400,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ec\n  0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ed\n  0x0000,0x0000,0x0000,0x0c00,0x1200,0x2100,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ee\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ef\n  0x0000,0x0000,0x0000,0x2c00,0x1000,0x6800,0x0400,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f0\n  0x0000,0x0000,0x0000,0x3100,0x4900,0x4600,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f1\n  0x0000,0x0000,0x0000,0x1000,0x0800,0x0400,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f2\n  0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f3\n  0x0000,0x0000,0x0000,0x0c00,0x1200,0x2100,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f4\n  0x0000,0x0000,0x0000,0x1880,0x2480,0x2300,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f5\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0400,0x0400,0x0400,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e40,0x2180,0x4180,0x4280,0x4480,0x4880,0x5080,0x6080,0x6100,\n  0x9e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f8\n  0x0000,0x0000,0x0000,0x1000,0x0800,0x0400,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f9\n  0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00fa\n  0x0000,0x0000,0x0000,0x0c00,0x1200,0x2100,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00fb\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00fc\n  0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0080,0x0080,0x0100,0x3e00,0x0000, // u00fd\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4100,\n  0x7e00,0x4000,0x4000,0x4000,0x4000,0x0000, // u00fe\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0080,0x0080,0x0100,0x3e00,0x0000, // u00ff\n  0x0000,0x3f00,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0100\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x3e00,0x0100,0x0080,0x0080,0x3f80,0x4080,0x4080,0x4080,0x4080,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0101\n  0x2100,0x2100,0x1e00,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0102\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x1e00,0x0000,0x3e00,0x0100,0x0080,0x0080,0x3f80,0x4080,0x4080,0x4080,0x4080,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0103\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0100,0x0200,0x0200,0x01c0,0x0000, // u0104\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0100,0x0080,0x0080,0x3f80,0x4080,0x4080,0x4080,0x4080,\n  0x3f80,0x0100,0x0200,0x0200,0x01c0,0x0000, // u0105\n  0x0200,0x0400,0x0800,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4000,0x4000,0x4000,0x4000,0x4000,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0106\n  0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x0000,0x1e00,0x2100,0x4080,0x4000,0x4000,0x4000,0x4000,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0107\n  0x0c00,0x1200,0x2100,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4000,0x4000,0x4000,0x4000,0x4000,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0108\n  0x0000,0x0000,0x0000,0x0c00,0x1200,0x2100,0x0000,0x1e00,0x2100,0x4080,0x4000,0x4000,0x4000,0x4000,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0109\n  0x0400,0x0400,0x0400,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4000,0x4000,0x4000,0x4000,0x4000,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u010a\n  0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x1e00,0x2100,0x4080,0x4000,0x4000,0x4000,0x4000,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u010b\n  0x2100,0x1200,0x0c00,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4000,0x4000,0x4000,0x4000,0x4000,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u010c\n  0x0000,0x0000,0x0000,0x2100,0x1200,0x0c00,0x0000,0x1e00,0x2100,0x4080,0x4000,0x4000,0x4000,0x4000,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u010d\n  0x2100,0x1200,0x0c00,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4100,\n  0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u010e\n  0x2100,0x1200,0x0c00,0x0080,0x0080,0x0080,0x0080,0x1f80,0x2080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u010f\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0xf880,0x4080,0x4080,0x4080,0x4080,0x4080,0x4100,\n  0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0110\n  0x0000,0x0000,0x0000,0x0080,0x0fc0,0x0080,0x0080,0x1f80,0x2080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0111\n  0x0000,0x3f00,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0112\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x1e00,0x2100,0x4080,0x4080,0x7f80,0x4000,0x4000,0x4000,0x2080,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0113\n  0x2100,0x2100,0x1e00,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0114\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x1e00,0x0000,0x1e00,0x2100,0x4080,0x4080,0x7f80,0x4000,0x4000,0x4000,0x2080,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0115\n  0x0400,0x0400,0x0400,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0116\n  0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x1e00,0x2100,0x4080,0x4080,0x7f80,0x4000,0x4000,0x4000,0x2080,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0117\n  0x0000,0x0000,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x7f80,0x0100,0x0200,0x0200,0x01c0,0x0000, // u0118\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x7f80,0x4000,0x4000,0x4000,0x2080,\n  0x1f00,0x0400,0x0800,0x0800,0x0700,0x0000, // u0119\n  0x2100,0x1200,0x0c00,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u011a\n  0x0000,0x0000,0x0000,0x2100,0x1200,0x0c00,0x0000,0x1e00,0x2100,0x4080,0x4080,0x7f80,0x4000,0x4000,0x4000,0x2080,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u011b\n  0x0c00,0x1200,0x2100,0x0000,0x1e00,0x2100,0x4180,0x4000,0x4000,0x4000,0x4780,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u011c\n  0x0000,0x0000,0x0000,0x0c00,0x1200,0x2100,0x0000,0x1f80,0x2080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0080,0x0080,0x0100,0x3e00,0x0000, // u011d\n  0x2100,0x2100,0x1e00,0x0000,0x1e00,0x2100,0x4180,0x4000,0x4000,0x4000,0x4780,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u011e\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x1e00,0x0000,0x1f80,0x2080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0080,0x0080,0x0100,0x3e00,0x0000, // u011f\n  0x0400,0x0400,0x0400,0x0000,0x1e00,0x2100,0x4180,0x4000,0x4000,0x4000,0x4780,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0120\n  0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x1f80,0x2080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0080,0x0080,0x0100,0x3e00,0x0000, // u0121\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4000,0x4000,0x4000,0x4780,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0400,0x0400,0x0400,0x0800, // u0122\n  0x0000,0x0000,0x0200,0x0400,0x0400,0x0400,0x0000,0x1f80,0x2080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0080,0x0080,0x0100,0x3e00,0x0000, // u0123\n  0x0c00,0x1200,0x2100,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0124\n  0x0600,0x0900,0x1080,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0125\n  0x0000,0x0000,0x0000,0x4080,0x4080,0xffc0,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0126\n  0x0000,0x0000,0x0000,0x4000,0xfc00,0x4000,0x4000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0127\n  0x1880,0x2480,0x2300,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0128\n  0x0000,0x0000,0x0000,0x1880,0x2480,0x2300,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0129\n  0x0000,0x3f00,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u012a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u012b\n  0x2100,0x2100,0x1e00,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u012c\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x1e00,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u012d\n  0x0000,0x0000,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0400,0x0800,0x0800,0x0700,0x0000, // u012e\n  0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0400,0x0800,0x0800,0x0700,0x0000, // u012f\n  0x0400,0x0400,0x0400,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0130\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0131\n  0x0000,0x0000,0x0000,0xe1c0,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4880,0x4880,0x4880,0x4880,\n  0xe700,0x0000,0x0000,0x0000,0x0000,0x0000, // u0132\n  0x0000,0x0000,0x0000,0x2040,0x2040,0x2040,0x0000,0x60c0,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,\n  0x7040,0x0440,0x0440,0x0440,0x0380,0x0000, // u0133\n  0x0300,0x0480,0x0840,0x0000,0x07c0,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x4100,0x4100,0x4100,0x2200,\n  0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0134\n  0x0000,0x0000,0x0000,0x0300,0x0480,0x0840,0x0000,0x0700,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0100,0x2100,0x2100,0x2100,0x1e00,0x0000, // u0135\n  0x0000,0x0000,0x0000,0x4080,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,\n  0x4080,0x0000,0x0400,0x0400,0x0400,0x0800, // u0136\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x2000,0x2080,0x2100,0x2200,0x2400,0x3800,0x3800,0x2400,0x2200,0x2100,\n  0x2080,0x0000,0x0400,0x0400,0x0400,0x0800, // u0137\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2100,0x2200,0x2400,0x3800,0x3800,0x2400,0x2200,0x2100,\n  0x2080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0138\n  0x1000,0x2000,0x4000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0139\n  0x0100,0x0200,0x0400,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u013a\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0400,0x0400,0x0400,0x0800, // u013b\n  0x0000,0x0000,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0400,0x0400,0x0400,0x0800, // u013c\n  0x2100,0x1200,0x0c00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u013d\n  0x2100,0x1200,0x0c00,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u013e\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4200,0x4200,0x4200,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u013f\n  0x0000,0x0000,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0420,0x0420,0x0420,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0140\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x2000,0x2800,0x3000,0x2000,0x6000,0xa000,0x2000,0x2000,0x2000,0x2000,\n  0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0141\n  0x0000,0x0000,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0500,0x0600,0x0400,0x0c00,0x1400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0142\n  0x0200,0x0400,0x0800,0x4080,0x4080,0x4080,0x4080,0x6080,0x5080,0x4880,0x4480,0x4280,0x4180,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0143\n  0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0144\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x6080,0x5080,0x4880,0x4480,0x4280,0x4180,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0400,0x0400,0x0400,0x0800, // u0145\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0400,0x0400,0x0400,0x0800, // u0146\n  0x2100,0x1200,0x0c00,0x4080,0x4080,0x4080,0x4080,0x6080,0x5080,0x4880,0x4480,0x4280,0x4180,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0147\n  0x0000,0x0000,0x0000,0x2100,0x1200,0x0c00,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0148\n  0x0000,0x4000,0x4000,0x4000,0x4000,0x8000,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0149\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x6080,0x5080,0x4880,0x4480,0x4280,0x4180,0x4080,0x4080,0x4080,\n  0x4080,0x0080,0x0080,0x0100,0x0600,0x0000, // u014a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0080,0x0080,0x0100,0x0600,0x0000, // u014b\n  0x0000,0x3f00,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u014c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u014d\n  0x2100,0x2100,0x1e00,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u014e\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x1e00,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u014f\n  0x0440,0x0880,0x1100,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0150\n  0x0000,0x0000,0x0000,0x0440,0x0880,0x1100,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0151\n  0x0000,0x0000,0x0000,0x3fc0,0x4400,0x8400,0x8400,0x8400,0x8400,0x87c0,0x8400,0x8400,0x8400,0x8400,0x8400,0x4400,\n  0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0152\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x4440,0x4440,0x4440,0x47c0,0x4400,0x4400,0x4400,0x4440,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0153\n  0x0200,0x0400,0x0800,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4100,0x7e00,0x5000,0x4800,0x4400,0x4200,0x4100,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0154\n  0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x0000,0x4f80,0x5000,0x6000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0155\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4100,0x7e00,0x5000,0x4800,0x4400,0x4200,0x4100,\n  0x4080,0x0000,0x0400,0x0400,0x0400,0x0800, // u0156\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4f80,0x5000,0x6000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x0000,0x4000,0x4000,0x4000,0x8000, // u0157\n  0x2100,0x1200,0x0c00,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4100,0x7e00,0x5000,0x4800,0x4400,0x4200,0x4100,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0158\n  0x0000,0x0000,0x0000,0x2100,0x1200,0x0c00,0x0000,0x4f80,0x5000,0x6000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0159\n  0x0200,0x0400,0x0800,0x0000,0x1e00,0x2100,0x4080,0x4000,0x4000,0x2000,0x1e00,0x0100,0x0080,0x0080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u015a\n  0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x0000,0x3f00,0x4080,0x4000,0x4000,0x3f00,0x0080,0x0080,0x0080,0x4080,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u015b\n  0x0c00,0x1200,0x2100,0x0000,0x1e00,0x2100,0x4080,0x4000,0x4000,0x2000,0x1e00,0x0100,0x0080,0x0080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u015c\n  0x0000,0x0000,0x0000,0x0c00,0x1200,0x2100,0x0000,0x3f00,0x4080,0x4000,0x4000,0x3f00,0x0080,0x0080,0x0080,0x4080,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u015d\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4000,0x4000,0x2000,0x1e00,0x0100,0x0080,0x0080,0x0080,0x4080,0x2100,\n  0x1e00,0x0400,0x0400,0x0400,0x0800,0x0000, // u015e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x4080,0x4000,0x4000,0x3f00,0x0080,0x0080,0x0080,0x4080,\n  0x3f00,0x0400,0x0400,0x0400,0x0800,0x0000, // u015f\n  0x2100,0x1200,0x0c00,0x0000,0x1e00,0x2100,0x4080,0x4000,0x4000,0x2000,0x1e00,0x0100,0x0080,0x0080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0160\n  0x0000,0x0000,0x0000,0x2100,0x1200,0x0c00,0x0000,0x3f00,0x4080,0x4000,0x4000,0x3f00,0x0080,0x0080,0x0080,0x4080,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0161\n  0x0000,0x0000,0x0000,0x7fc0,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0200,0x0200,0x0200,0x0400,0x0000, // u0162\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0780,0x0200,0x0200,0x0200,0x0400,0x0000, // u0163\n  0x2100,0x1200,0x0c00,0x0000,0x7fc0,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u0164\n  0x2200,0x1400,0x0800,0x0000,0x0800,0x0800,0x0800,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0780,0x0000,0x0000,0x0000,0x0000,0x0000, // u0165\n  0x0000,0x0000,0x0000,0x7fc0,0x0400,0x0400,0x0400,0x0400,0x0400,0x3f80,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u0166\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x7f00,0x0800,0x0800,0x3e00,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0780,0x0000,0x0000,0x0000,0x0000,0x0000, // u0167\n  0x1880,0x2480,0x2300,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0168\n  0x0000,0x0000,0x0000,0x1880,0x2480,0x2300,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0169\n  0x0000,0x3f00,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u016a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u016b\n  0x2100,0x2100,0x1e00,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u016c\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x1e00,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u016d\n  0x0c00,0x1200,0x1200,0x0c00,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u016e\n  0x0000,0x0000,0x0000,0x0c00,0x1200,0x1200,0x0c00,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u016f\n  0x0440,0x0880,0x1100,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0170\n  0x0000,0x0000,0x0000,0x0440,0x0880,0x1100,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0171\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0400,0x0800,0x0800,0x0700,0x0000, // u0172\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0100,0x0200,0x0200,0x01c0,0x0000, // u0173\n  0x0c00,0x1200,0x2100,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4440,0x4a40,0x5140,0x60c0,\n  0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0174\n  0x0000,0x0000,0x0000,0x0c00,0x1200,0x2100,0x0000,0x4040,0x4040,0x4040,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0175\n  0x0c00,0x1200,0x2100,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u0176\n  0x0000,0x0000,0x0000,0x0c00,0x1200,0x2100,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0080,0x0080,0x0100,0x3e00,0x0000, // u0177\n  0x2100,0x2100,0x2100,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u0178\n  0x0200,0x0400,0x0800,0x0000,0x7f80,0x0080,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0179\n  0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x0000,0x7f80,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u017a\n  0x0400,0x0400,0x0400,0x0000,0x7f80,0x0080,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u017b\n  0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x7f80,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u017c\n  0x2100,0x1200,0x0c00,0x0000,0x7f80,0x0080,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u017d\n  0x0000,0x0000,0x0000,0x2100,0x1200,0x0c00,0x0000,0x7f80,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u017e\n  0x0000,0x0000,0x0000,0x0780,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0000,0x0000,0x0000,0x0000,0x0000, // u017f\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0186\n  0x0000,0x0000,0x0000,0x7f80,0x0080,0x0080,0x0080,0x0080,0x0080,0x1f80,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u018e\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x0080,0x0080,0x0080,0x7f80,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u018f\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4000,0x4000,0x2000,0x1e00,0x2000,0x4000,0x4000,0x4000,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0190\n  0x0000,0x0000,0x0000,0x0380,0x0440,0x0440,0x0400,0x0400,0x0400,0x3f80,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x4400,0x4400,0x3800,0x0000, // u0192\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x6080,0x5080,0x4880,0x4480,0x4280,0x4180,0x4080,0x4080,0x4080,\n  0x4080,0x4000,0x4000,0x4000,0x8000,0x0000, // u019d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0080,0x0080,0x0080,0x0080,0x0000, // u019e\n  0x0000,0x0000,0x0000,0x7f80,0x0080,0x0080,0x0100,0x0200,0x0400,0x7f80,0x0800,0x1000,0x2000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u01b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0100,0x0200,0x0400,0x7f80,0x0800,0x1000,0x2000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u01b6\n  0x0000,0x0000,0x0000,0x7f80,0x0100,0x0200,0x0400,0x0800,0x1e00,0x0100,0x0080,0x0080,0x0080,0x0080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01b7\n  0x2100,0x1200,0x0c00,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u01cd\n  0x0000,0x0000,0x0000,0x2100,0x1200,0x0c00,0x0000,0x3e00,0x0100,0x0080,0x0080,0x3f80,0x4080,0x4080,0x4080,0x4080,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u01ce\n  0x2100,0x1200,0x0c00,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01cf\n  0x0000,0x0000,0x0000,0x2100,0x1200,0x0c00,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d0\n  0x2100,0x1200,0x0c00,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d1\n  0x0000,0x0000,0x0000,0x2100,0x1200,0x0c00,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d2\n  0x2100,0x1200,0x0c00,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d3\n  0x0000,0x0000,0x0000,0x2100,0x1200,0x0c00,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d4\n  0x0000,0x3f80,0x0000,0x3fc0,0x4400,0x8400,0x8400,0x8400,0x8400,0xffc0,0x8400,0x8400,0x8400,0x8400,0x8400,0x8400,\n  0x87c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x3b80,0x0440,0x0440,0x0440,0x3fc0,0x4400,0x4400,0x4400,0x4440,\n  0x3b80,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e3\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4000,0x4000,0x4000,0x4780,0x4080,0x4080,0x47c0,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x2080,0x4080,0x4080,0x47c0,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0080,0x0080,0x0100,0x3e00,0x0000, // u01e5\n  0x2100,0x1200,0x0c00,0x0000,0x1e00,0x2100,0x4180,0x4000,0x4000,0x4000,0x4780,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e6\n  0x0000,0x0000,0x0000,0x2100,0x1200,0x0c00,0x0000,0x1f80,0x2080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0080,0x0080,0x0100,0x3e00,0x0000, // u01e7\n  0x2100,0x1200,0x0c00,0x4080,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e8\n  0x1080,0x0900,0x0600,0x2000,0x2000,0x2000,0x2000,0x2080,0x2100,0x2200,0x2400,0x3800,0x3800,0x2400,0x2200,0x2100,\n  0x2080,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e9\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0400,0x0800,0x0800,0x0700,0x0000, // u01ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0400,0x0800,0x0800,0x0700,0x0000, // u01eb\n  0x0000,0x3f00,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0400,0x0800,0x0800,0x0700,0x0000, // u01ec\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0400,0x0800,0x0800,0x0700,0x0000, // u01ed\n  0x2100,0x1200,0x0c00,0x0000,0x7f80,0x0100,0x0200,0x0400,0x0800,0x1e00,0x0100,0x0080,0x0080,0x0080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01ee\n  0x0000,0x0000,0x0000,0x2100,0x1200,0x0c00,0x0000,0x7f80,0x0100,0x0200,0x0400,0x0800,0x1e00,0x0100,0x0080,0x0080,\n  0x0080,0x0080,0x4080,0x2100,0x1e00,0x0000, // u01ef\n  0x0000,0x0000,0x0000,0x0840,0x0480,0x0300,0x0000,0x0700,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0100,0x2100,0x2100,0x2100,0x1e00,0x0000, // u01f0\n  0x0200,0x0400,0x0800,0x0000,0x1e00,0x2100,0x4180,0x4000,0x4000,0x4000,0x4780,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01f4\n  0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x1f80,0x2080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0080,0x0080,0x0100,0x3e00,0x0000, // u01f5\n  0x0100,0x0200,0x0400,0x0000,0x3fc0,0x4400,0x8400,0x8400,0x8400,0x8400,0xffc0,0x8400,0x8400,0x8400,0x8400,0x8400,\n  0x87c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01fc\n  0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x3b80,0x0440,0x0440,0x0440,0x3fc0,0x4400,0x4400,0x4400,0x4440,\n  0x3b80,0x0000,0x0000,0x0000,0x0000,0x0000, // u01fd\n  0x0200,0x0400,0x0800,0x0000,0x1e00,0x2140,0x4080,0x4180,0x4280,0x4480,0x4880,0x5080,0x6080,0x4080,0xc080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01fe\n  0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x0000,0x1e40,0x2180,0x4180,0x4280,0x4480,0x4880,0x5080,0x6080,0x6100,\n  0x9e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01ff\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4000,0x4000,0x2000,0x1e00,0x0100,0x0080,0x0080,0x0080,0x4080,0x2100,\n  0x1e00,0x0000,0x0400,0x0400,0x0400,0x0800, // u0218\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x4080,0x4000,0x4000,0x3f00,0x0080,0x0080,0x0080,0x4080,\n  0x3f00,0x0000,0x0400,0x0400,0x0400,0x0800, // u0219\n  0x0000,0x0000,0x0000,0x7fc0,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0400,0x0400,0x0400,0x0800, // u021a\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0780,0x0000,0x0200,0x0200,0x0200,0x0400, // u021b\n  0x0000,0x3f00,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0a00,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u0232\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0080,0x0080,0x0100,0x3e00,0x0000, // u0233\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0100,0x2100,0x2100,0x2100,0x1e00,0x0000, // u0237\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x0080,0x0080,0x0080,0x0080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0254\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x7f80,0x0080,0x0080,0x0080,0x4100,\n  0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0258\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x0080,0x0080,0x0080,0x7f80,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0259\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x4080,0x4000,0x4000,0x3c00,0x4000,0x4000,0x4000,0x4080,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u025b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x4000,0x4000,0x4000,0x8000,0x0000, // u0272\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0100,0x0200,0x0400,0x0800,0x1e00,0x0100,0x0080,0x0080,\n  0x0080,0x0080,0x4080,0x2100,0x1e00,0x0000, // u0292\n  0x0200,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bb\n  0x0400,0x0400,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bc\n  0x0400,0x0400,0x0200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bd\n  0x0c00,0x1200,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02c6\n  0x2100,0x1200,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02c7\n  0x2100,0x2100,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02d8\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02d9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0400,0x0800,0x0800,0x0700,0x0000, // u02db\n  0x1880,0x2480,0x2300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02dc\n  0x0440,0x0880,0x1100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02dd\n  0x1000,0x0800,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0300\n  0x0200,0x0400,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0301\n  0x0c00,0x1200,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0302\n  0x1880,0x2480,0x2300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0303\n  0x0000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0304\n  0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0305\n  0x2100,0x2100,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0306\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0307\n  0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0308\n  0x0c00,0x1200,0x1200,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030a\n  0x0440,0x0880,0x1100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030b\n  0x2100,0x1200,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0400,0x0400,0x0400,0x0000, // u0329\n  0x2000,0x4000,0x8000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0384\n  0x0200,0x0400,0x0800,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0385\n  0x2000,0x4000,0x8000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0386\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0387\n  0x2000,0x4000,0x8000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0388\n  0x2000,0x4000,0x8000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0389\n  0x2000,0x4000,0x8000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u038a\n  0x2000,0x4000,0x8000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u038c\n  0x2000,0x4000,0x8000,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u038e\n  0x2000,0x4000,0x8000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,0x1200,0x1200,\n  0x7380,0x0000,0x0000,0x0000,0x0000,0x0000, // u038f\n  0x0200,0x0400,0x0800,0x4200,0x4200,0x4200,0x0000,0x3800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0700,0x0000,0x0000,0x0000,0x0000,0x0000, // u0390\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0391\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4100,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4100,\n  0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0392\n  0x0000,0x0000,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0393\n  0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0a00,0x0a00,0x1100,0x1100,0x1100,0x2080,0x2080,0x2080,0x4040,0x4040,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0394\n  0x0000,0x0000,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0395\n  0x0000,0x0000,0x0000,0x7f80,0x0080,0x0080,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0396\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0397\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x5e80,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0398\n  0x0000,0x0000,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0399\n  0x0000,0x0000,0x0000,0x4080,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u039a\n  0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0a00,0x0a00,0x1100,0x1100,0x1100,0x2080,0x2080,0x2080,0x4040,0x4040,\n  0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u039b\n  0x0000,0x0000,0x0000,0x4040,0x60c0,0x5140,0x5140,0x4a40,0x4440,0x4440,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u039c\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x6080,0x5080,0x4880,0x4480,0x4280,0x4180,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u039d\n  0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u039e\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u039f\n  0x0000,0x0000,0x0000,0x7f80,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a0\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4100,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a1\n  0x0000,0x0000,0x0000,0x7f80,0x4000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a3\n  0x0000,0x0000,0x0000,0x7fc0,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a4\n  0x0000,0x0000,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0a00,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a5\n  0x0000,0x0000,0x0000,0x0400,0x1f00,0x2480,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x2480,0x1f00,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a6\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x2100,0x2100,0x1200,0x1200,0x0c00,0x0c00,0x1200,0x1200,0x2100,0x2100,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a7\n  0x0000,0x0000,0x0000,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x2480,0x1f00,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a8\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,0x1200,0x1200,\n  0x7380,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a9\n  0x2100,0x2100,0x2100,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03aa\n  0x2100,0x2100,0x2100,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ab\n  0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x0000,0x1cc0,0x2380,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x2380,\n  0x1cc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ac\n  0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x0000,0x3f00,0x4080,0x4000,0x4000,0x3c00,0x4000,0x4000,0x4000,0x4080,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ad\n  0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0080,0x0080,0x0080,0x0080,0x0000, // u03ae\n  0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x0000,0x3800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0700,0x0000,0x0000,0x0000,0x0000,0x0000, // u03af\n  0x0200,0x0400,0x0800,0x2100,0x2100,0x2100,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1cc0,0x2380,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x2380,\n  0x1cc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b1\n  0x0000,0x0000,0x0000,0x3c00,0x4200,0x4100,0x4100,0x4100,0x4200,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4100,\n  0x7e00,0x4000,0x4000,0x4000,0x4000,0x0000, // u03b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0a00,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0000, // u03b3\n  0x0000,0x0000,0x0000,0x3f00,0x1000,0x0800,0x0400,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x4080,0x4000,0x4000,0x3c00,0x4000,0x4000,0x4000,0x4080,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b5\n  0x0000,0x0000,0x0000,0x7f80,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x2000,0x4000,0x4000,0x4000,0x4000,0x2000,\n  0x1f00,0x0080,0x0080,0x0080,0x0300,0x0000, // u03b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0080,0x0080,0x0080,0x0080,0x0000, // u03b7\n  0x0000,0x0000,0x0000,0x0e00,0x1100,0x2080,0x2080,0x2080,0x2080,0x3f80,0x2080,0x2080,0x2080,0x2080,0x2080,0x1100,\n  0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0700,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2100,0x2200,0x2400,0x3800,0x3800,0x2400,0x2200,0x2100,\n  0x2080,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ba\n  0x0000,0x0000,0x0000,0x1000,0x1000,0x0800,0x0800,0x0c00,0x0c00,0x1200,0x1200,0x2100,0x2100,0x2100,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u03bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4180,0x4280,\n  0x7c80,0x4000,0x4000,0x4000,0x4000,0x0000, // u03bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x2100,0x2100,0x2100,0x1200,0x1200,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03bd\n  0x0000,0x0000,0x0000,0x1f80,0x2000,0x4000,0x4000,0x4000,0x2000,0x1f00,0x2000,0x4000,0x4000,0x4000,0x4000,0x2000,\n  0x1f00,0x0080,0x0080,0x0080,0x0300,0x0000, // u03be\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4100,\n  0x7e00,0x4000,0x4000,0x4000,0x4000,0x0000, // u03c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4000,0x4000,0x4000,0x4000,0x4000,0x2000,\n  0x1f00,0x0080,0x0080,0x0080,0x0300,0x0000, // u03c2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x2200,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0380,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2380,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x2480,\n  0x1f00,0x0400,0x0400,0x0400,0x0400,0x0000, // u03c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x2100,0x2100,0x1200,0x1200,0x0c00,0x0c00,0x1200,\n  0x1200,0x2100,0x2100,0x4080,0x4080,0x0000, // u03c7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x2480,\n  0x1f00,0x0400,0x0400,0x0400,0x0400,0x0000, // u03c8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x4040,0x4040,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,\n  0x3b80,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c9\n  0x0000,0x0000,0x0000,0x4200,0x4200,0x4200,0x0000,0x3800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0700,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ca\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03cb\n  0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03cc\n  0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03cd\n  0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x2080,0x4040,0x4040,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,\n  0x3b80,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ce\n  0x0000,0x0000,0x0000,0x0e00,0x1100,0x2080,0x2080,0x2080,0x1080,0x0fc0,0x0080,0x6080,0x2080,0x2080,0x2080,0x1100,\n  0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x1f00,0x2480,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x2480,\n  0x1f00,0x0400,0x0400,0x0000,0x0000,0x0000, // u03d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xe040,0x1080,0x0900,0x0a00,0x0c00,0x0c00,0x1400,0x2400,0x4200,\n  0x81c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4100,\n  0x7e00,0x4000,0x4000,0x2000,0x1f00,0x0000, // u03f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4000,0x4000,0x4000,0x4000,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f2\n  0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0700,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0100,0x2100,0x2100,0x2100,0x1e00,0x0000, // u03f3\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x2000,0x4000,0x4000,0x7e00,0x4000,0x4000,0x4000,0x2000,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0100,0x0080,0x0080,0x1f80,0x0080,0x0080,0x0080,0x0100,\n  0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f6\n  0x1000,0x0800,0x0400,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0400\n  0x2100,0x2100,0x2100,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0401\n  0x0000,0x0000,0x0000,0xf800,0x2000,0x2000,0x2000,0x3e00,0x2100,0x2080,0x2080,0x2080,0x2080,0x2080,0x2080,0x2100,\n  0x2200,0x0000,0x0000,0x0000,0x0000,0x0000, // u0402\n  0x0200,0x0400,0x0800,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0403\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4000,0x4000,0x4000,0x7c00,0x4000,0x4000,0x4000,0x4000,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0404\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4000,0x4000,0x2000,0x1e00,0x0100,0x0080,0x0080,0x0080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0405\n  0x0000,0x0000,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0406\n  0x2100,0x2100,0x2100,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0407\n  0x0000,0x0000,0x0000,0x07c0,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x4100,0x4100,0x4100,0x2200,\n  0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0408\n  0x0000,0x0000,0x0000,0x3800,0x4800,0x8800,0x8800,0x8800,0x8f00,0x8880,0x8840,0x8840,0x8840,0x8840,0x8840,0x8880,\n  0x8f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0409\n  0x0000,0x0000,0x0000,0x8800,0x8800,0x8800,0x8800,0x8800,0x8f00,0xf880,0x8840,0x8840,0x8840,0x8840,0x8840,0x8880,\n  0x8f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u040a\n  0x0000,0x0000,0x0000,0xf800,0x2000,0x2000,0x2000,0x3e00,0x2100,0x2080,0x2080,0x2080,0x2080,0x2080,0x2080,0x2080,\n  0x2080,0x0000,0x0000,0x0000,0x0000,0x0000, // u040b\n  0x0200,0x0400,0x0800,0x4080,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u040c\n  0x1000,0x0800,0x0400,0x4080,0x4080,0x4080,0x4080,0x4180,0x4280,0x4480,0x4880,0x5080,0x6080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u040d\n  0x2100,0x2100,0x1e00,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,0x1f80,0x0080,0x0080,0x0080,0x0080,0x0100,\n  0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u040e\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x7f80,0x0c00,0x0c00,0x0c00,0x0000,0x0000, // u040f\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0410\n  0x0000,0x0000,0x0000,0x7f00,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4100,\n  0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0411\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4100,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4100,\n  0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0412\n  0x0000,0x0000,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0413\n  0x0000,0x0000,0x0000,0x0f80,0x1080,0x2080,0x2080,0x2080,0x2080,0x2080,0x2080,0x2080,0x2080,0x2080,0x2080,0x4080,\n  0xffc0,0x8040,0x8040,0x0000,0x0000,0x0000, // u0414\n  0x0000,0x0000,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0415\n  0x0000,0x0000,0x0000,0x4440,0x4440,0x4440,0x4440,0x2480,0x1500,0x0e00,0x1500,0x2480,0x4440,0x4440,0x4440,0x4440,\n  0x4440,0x0000,0x0000,0x0000,0x0000,0x0000, // u0416\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x0080,0x0080,0x0100,0x1e00,0x0100,0x0080,0x0080,0x0080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0417\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4180,0x4280,0x4480,0x4880,0x5080,0x6080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0418\n  0x2100,0x2100,0x1e00,0x4080,0x4080,0x4080,0x4080,0x4180,0x4280,0x4480,0x4880,0x5080,0x6080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0419\n  0x0000,0x0000,0x0000,0x4080,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u041a\n  0x0000,0x0000,0x0000,0x0f80,0x1080,0x2080,0x2080,0x2080,0x2080,0x2080,0x2080,0x2080,0x2080,0x2080,0x2080,0x4080,\n  0x8080,0x0000,0x0000,0x0000,0x0000,0x0000, // u041b\n  0x0000,0x0000,0x0000,0x4040,0x60c0,0x5140,0x5140,0x4a40,0x4440,0x4440,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u041c\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u041d\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u041e\n  0x0000,0x0000,0x0000,0x7f80,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u041f\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4100,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0420\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0421\n  0x0000,0x0000,0x0000,0x7fc0,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u0422\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,0x1f80,0x0080,0x0080,0x0080,0x0080,0x0100,\n  0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0423\n  0x0000,0x0000,0x0400,0x1f00,0x2480,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x2480,\n  0x1f00,0x0400,0x0000,0x0000,0x0000,0x0000, // u0424\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x2100,0x2100,0x1200,0x1200,0x0c00,0x0c00,0x1200,0x1200,0x2100,0x2100,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0425\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1fc0,0x0040,0x0040,0x0040,0x0000,0x0000, // u0426\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,0x1f80,0x0080,0x0080,0x0080,0x0080,0x0080,\n  0x0080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0427\n  0x0000,0x0000,0x0000,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x2440,\n  0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0428\n  0x0000,0x0000,0x0000,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x2440,\n  0x1fe0,0x0020,0x0020,0x0020,0x0000,0x0000, // u0429\n  0x0000,0x0000,0x0000,0xc000,0xc000,0x4000,0x4000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4100,\n  0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u042a\n  0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x7840,0x4440,0x4240,0x4240,0x4240,0x4240,0x4240,0x4240,0x4440,\n  0x7840,0x0000,0x0000,0x0000,0x0000,0x0000, // u042b\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4100,\n  0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u042c\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x0080,0x0080,0x0080,0x0f80,0x0080,0x0080,0x0080,0x0080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u042d\n  0x0000,0x0000,0x0000,0x4780,0x4840,0x4840,0x4840,0x4840,0x4840,0x7840,0x4840,0x4840,0x4840,0x4840,0x4840,0x4840,\n  0x4780,0x0000,0x0000,0x0000,0x0000,0x0000, // u042e\n  0x0000,0x0000,0x0000,0x1f80,0x2080,0x4080,0x4080,0x4080,0x4080,0x2080,0x1f80,0x0280,0x0480,0x0880,0x1080,0x2080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u042f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x0100,0x0080,0x0080,0x3f80,0x4080,0x4080,0x4080,0x4080,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0430\n  0x0000,0x0000,0x0000,0x1f00,0x2000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4100,\n  0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0431\n  0x0000,0x0000,0x0000,0x3c00,0x4200,0x4100,0x4100,0x4100,0x4200,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4100,\n  0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0432\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0433\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x2080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0080,0x0080,0x0100,0x3e00,0x0000, // u0434\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x7f80,0x4000,0x4000,0x4000,0x2080,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0435\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4440,0x4440,0x2480,0x1500,0x0e00,0x1500,0x2480,0x4440,0x4440,\n  0x4440,0x0000,0x0000,0x0000,0x0000,0x0000, // u0436\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x4080,0x0080,0x0080,0x0f00,0x0080,0x0080,0x0080,0x4080,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0437\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0438\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x1e00,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0439\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2100,0x2200,0x2400,0x3800,0x3800,0x2400,0x2200,0x2100,\n  0x2080,0x0000,0x0000,0x0000,0x0000,0x0000, // u043a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f80,0x1080,0x2080,0x2080,0x2080,0x2080,0x2080,0x2080,0x2080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u043b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x60c0,0x5140,0x4a40,0x4440,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u043c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u043d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u043e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u043f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4100,\n  0x7e00,0x4000,0x4000,0x4000,0x4000,0x0000, // u0440\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4000,0x4000,0x4000,0x4000,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0441\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u0442\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0080,0x0080,0x0100,0x3e00,0x0000, // u0443\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x1f00,0x2480,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x2480,\n  0x1f00,0x0400,0x0400,0x0000,0x0000,0x0000, // u0444\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x2100,0x1200,0x0c00,0x0c00,0x1200,0x2100,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0445\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1fc0,0x0040,0x0040,0x0040,0x0000,0x0000, // u0446\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x2080,0x1f80,0x0080,0x0080,0x0080,\n  0x0080,0x0000,0x0000,0x0000,0x0000,0x0000, // u0447\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x2440,\n  0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0448\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x2440,\n  0x1fe0,0x0020,0x0020,0x0020,0x0000,0x0000, // u0449\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xe000,0x2000,0x2000,0x3e00,0x2100,0x2080,0x2080,0x2080,0x2100,\n  0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u044a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x7840,0x4440,0x4240,0x4240,0x4240,0x4440,\n  0x7840,0x0000,0x0000,0x0000,0x0000,0x0000, // u044b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x3e00,0x2100,0x2080,0x2080,0x2080,0x2100,\n  0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u044c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x0080,0x0f80,0x0080,0x0080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u044d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4780,0x4840,0x4840,0x4840,0x7840,0x4840,0x4840,0x4840,0x4840,\n  0x4780,0x0000,0x0000,0x0000,0x0000,0x0000, // u044e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x4080,0x4080,0x4080,0x4080,0x3f80,0x0480,0x0880,0x1080,\n  0x2080,0x0000,0x0000,0x0000,0x0000,0x0000, // u044f\n  0x0000,0x0000,0x0000,0x1000,0x0800,0x0400,0x0000,0x1e00,0x2100,0x4080,0x4080,0x7f80,0x4000,0x4000,0x4000,0x2080,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0450\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x1e00,0x2100,0x4080,0x4080,0x7f80,0x4000,0x4000,0x4000,0x2080,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0451\n  0x0000,0x0000,0x0000,0x4000,0xfc00,0x4000,0x4000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0080,0x0080,0x0100,0x0600,0x0000, // u0452\n  0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0453\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4000,0x7c00,0x4000,0x4000,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0454\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x4080,0x4000,0x4000,0x3f00,0x0080,0x0080,0x0080,0x4080,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0455\n  0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0456\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0457\n  0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0700,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0100,0x2100,0x2100,0x2100,0x1e00,0x0000, // u0458\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x4800,0x8800,0x8f00,0x8880,0x8840,0x8840,0x8840,0x8880,\n  0x8f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0459\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x8800,0x8800,0x8800,0x8f00,0xf880,0x8840,0x8840,0x8840,0x8880,\n  0x8f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u045a\n  0x0000,0x0000,0x0000,0x4000,0xfc00,0x4000,0x4000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u045b\n  0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x2080,0x2100,0x2200,0x2400,0x3800,0x3800,0x2400,0x2200,0x2100,\n  0x2080,0x0000,0x0000,0x0000,0x0000,0x0000, // u045c\n  0x0000,0x0000,0x0000,0x1000,0x0800,0x0400,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u045d\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x1e00,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0080,0x0080,0x0100,0x3e00,0x0000, // u045e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x7f80,0x0c00,0x0c00,0x0c00,0x0000,0x0000, // u045f\n  0x0000,0x0000,0x0000,0x4000,0x4000,0xfc00,0x4000,0x4000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4100,\n  0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0462\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0xfc00,0x2000,0x2000,0x2000,0x3e00,0x2100,0x2080,0x2080,0x2080,0x2100,\n  0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0463\n  0x0000,0x0000,0x0000,0x7fc0,0x4040,0x2080,0x2080,0x1100,0x1100,0x0e00,0x1500,0x2480,0x4440,0x4440,0x4440,0x4440,\n  0x4440,0x0000,0x0000,0x0000,0x0000,0x0000, // u046a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4040,0x2080,0x1100,0x0e00,0x1500,0x2480,0x4440,0x4440,\n  0x4440,0x0000,0x0000,0x0000,0x0000,0x0000, // u046b\n  0x0080,0x0080,0x0080,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0490\n  0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0491\n  0x0000,0x0000,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0xfc00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0492\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0xfc00,0x4000,0x4000,0x4000,\n  0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0493\n  0x0000,0x0000,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0080,0x0100,0x0200,0x0000,0x0000, // u0494\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x7c00,0x4200,0x4100,0x4100,\n  0x4100,0x0100,0x0200,0x0400,0x0000,0x0000, // u0495\n  0x0000,0x0000,0x0000,0x4440,0x4440,0x4440,0x4440,0x2480,0x1500,0x0e00,0x1500,0x2480,0x4440,0x4440,0x4440,0x4440,\n  0x4460,0x0020,0x0020,0x0020,0x0000,0x0000, // u0496\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4440,0x4440,0x2480,0x1500,0x0e00,0x1500,0x2480,0x4440,0x4440,\n  0x4460,0x0020,0x0020,0x0020,0x0000,0x0000, // u0497\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x0080,0x0080,0x0100,0x1e00,0x0100,0x0080,0x0080,0x0080,0x4080,0x2100,\n  0x1e00,0x0400,0x0400,0x0400,0x0400,0x0000, // u0498\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x4080,0x0080,0x0080,0x0f00,0x0080,0x0080,0x0080,0x4080,\n  0x3f00,0x0400,0x0400,0x0400,0x0400,0x0000, // u0499\n  0x0000,0x0000,0x0000,0x4080,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,\n  0x40c0,0x0040,0x0040,0x0040,0x0000,0x0000, // u049a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2100,0x2200,0x2400,0x3800,0x3800,0x2400,0x2200,0x2100,\n  0x20c0,0x0040,0x0040,0x0040,0x0000,0x0000, // u049b\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4100,0x5200,0x5400,0x5800,0x7000,0x7000,0x5800,0x5400,0x5200,0x4100,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u049c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2900,0x2a00,0x2c00,0x3800,0x3800,0x2c00,0x2a00,0x2900,\n  0x2080,0x0000,0x0000,0x0000,0x0000,0x0000, // u049d\n  0x0000,0x0000,0x0000,0xc080,0xc100,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xe080,0x2100,0x2200,0x2400,0x3800,0x3800,0x2400,0x2200,0x2100,\n  0x2080,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a1\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x40c0,0x0040,0x0040,0x0040,0x0000,0x0000, // u04a2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,\n  0x40c0,0x0040,0x0040,0x0040,0x0000,0x0000, // u04a3\n  0x0000,0x0000,0x0000,0x43c0,0x4200,0x4200,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,0x4200,0x4200,\n  0x4200,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x43c0,0x4200,0x4200,0x4200,0x7e00,0x4200,0x4200,0x4200,0x4200,\n  0x4200,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a5\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4080,0x4080,0x2100,\n  0x1e00,0x0400,0x0400,0x0400,0x0400,0x0000, // u04aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4000,0x4000,0x4000,0x4000,0x4080,0x2100,\n  0x1e00,0x0400,0x0400,0x0400,0x0400,0x0000, // u04ab\n  0x0000,0x0000,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0a00,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0a00,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0000, // u04af\n  0x0000,0x0000,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0a00,0x0400,0x3f80,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u04b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0a00,\n  0x0400,0x3f80,0x0400,0x0400,0x0400,0x0000, // u04b1\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x2100,0x2100,0x1200,0x1200,0x0c00,0x0c00,0x1200,0x1200,0x2100,0x2100,0x4080,\n  0x40c0,0x0040,0x0040,0x0040,0x0000,0x0000, // u04b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x2100,0x1200,0x0c00,0x0c00,0x1200,0x2100,0x4080,\n  0x40c0,0x0040,0x0040,0x0040,0x0000,0x0000, // u04b3\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,0x1f80,0x0080,0x0080,0x0080,0x0080,0x0080,\n  0x00c0,0x0040,0x0040,0x0040,0x0000,0x0000, // u04b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x2080,0x1f80,0x0080,0x0080,0x0080,\n  0x00c0,0x0040,0x0040,0x0040,0x0000,0x0000, // u04b7\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4480,0x4480,0x2480,0x1f80,0x0480,0x0480,0x0480,0x0080,0x0080,\n  0x0080,0x0000,0x0000,0x0000,0x0000,0x0000, // u04b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x4480,0x4480,0x2480,0x1f80,0x0480,0x0480,0x0080,\n  0x0080,0x0000,0x0000,0x0000,0x0000,0x0000, // u04b9\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u04bb\n  0x0000,0x0000,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04c0\n  0x2100,0x2100,0x1e00,0x0000,0x4440,0x4440,0x4440,0x4440,0x2480,0x1500,0x0e00,0x1500,0x2480,0x4440,0x4440,0x4440,\n  0x4440,0x0000,0x0000,0x0000,0x0000,0x0000, // u04c1\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x1e00,0x0000,0x4440,0x4440,0x2480,0x1500,0x0e00,0x1500,0x2480,0x4440,0x4440,\n  0x4440,0x0000,0x0000,0x0000,0x0000,0x0000, // u04c2\n  0x0000,0x0000,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04cf\n  0x2100,0x2100,0x1e00,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d0\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x1e00,0x0000,0x3e00,0x0100,0x0080,0x0080,0x3f80,0x4080,0x4080,0x4080,0x4080,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d1\n  0x2100,0x2100,0x2100,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d2\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x3e00,0x0100,0x0080,0x0080,0x3f80,0x4080,0x4080,0x4080,0x4080,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d3\n  0x0000,0x0000,0x0000,0x3fc0,0x4400,0x8400,0x8400,0x8400,0x8400,0xffc0,0x8400,0x8400,0x8400,0x8400,0x8400,0x8400,\n  0x87c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3b80,0x0440,0x0440,0x0440,0x3fc0,0x4400,0x4400,0x4400,0x4440,\n  0x3b80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d5\n  0x2100,0x2100,0x1e00,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d6\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x1e00,0x0000,0x1e00,0x2100,0x4080,0x4080,0x7f80,0x4000,0x4000,0x4000,0x2080,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d7\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x0080,0x0080,0x0080,0x7f80,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x0080,0x0080,0x0080,0x7f80,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d9\n  0x2100,0x2100,0x2100,0x0000,0x1e00,0x2100,0x4080,0x0080,0x0080,0x0080,0x7f80,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04da\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x3e00,0x4100,0x0080,0x0080,0x0080,0x7f80,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04db\n  0x1100,0x1100,0x1100,0x0000,0x4440,0x4440,0x4440,0x4440,0x2480,0x1500,0x0e00,0x1500,0x2480,0x4440,0x4440,0x4440,\n  0x4440,0x0000,0x0000,0x0000,0x0000,0x0000, // u04dc\n  0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,0x0000,0x4440,0x4440,0x2480,0x1500,0x0e00,0x1500,0x2480,0x4440,0x4440,\n  0x4440,0x0000,0x0000,0x0000,0x0000,0x0000, // u04dd\n  0x2100,0x2100,0x2100,0x0000,0x1e00,0x2100,0x4080,0x0080,0x0080,0x0100,0x1e00,0x0100,0x0080,0x0080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04de\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x3f00,0x4080,0x0080,0x0080,0x0f00,0x0080,0x0080,0x0080,0x4080,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04df\n  0x0000,0x3f00,0x0000,0x4080,0x4080,0x4080,0x4080,0x4180,0x4280,0x4480,0x4880,0x5080,0x6080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e3\n  0x2100,0x2100,0x2100,0x0000,0x4080,0x4080,0x4080,0x4180,0x4280,0x4480,0x4880,0x5080,0x6080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e4\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e5\n  0x2100,0x2100,0x2100,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e6\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e7\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e9\n  0x2100,0x2100,0x2100,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ea\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x1e00,0x2100,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04eb\n  0x2100,0x2100,0x2100,0x0000,0x1e00,0x2100,0x4080,0x0080,0x0080,0x0080,0x0f80,0x0080,0x0080,0x0080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ec\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x1e00,0x2100,0x4080,0x0080,0x0f80,0x0080,0x0080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ed\n  0x0000,0x3f00,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,0x1f80,0x0080,0x0080,0x0080,0x0080,0x0100,\n  0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ee\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0080,0x0080,0x0100,0x3e00,0x0000, // u04ef\n  0x2100,0x2100,0x2100,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,0x1f80,0x0080,0x0080,0x0080,0x0100,\n  0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f0\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0080,0x0080,0x0100,0x3e00,0x0000, // u04f1\n  0x0440,0x0880,0x1100,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,0x1f80,0x0080,0x0080,0x0080,0x0100,\n  0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f2\n  0x0000,0x0000,0x0000,0x0440,0x0880,0x1100,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0080,0x0080,0x0100,0x3e00,0x0000, // u04f3\n  0x2100,0x2100,0x2100,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,0x1f80,0x0080,0x0080,0x0080,0x0080,0x0080,\n  0x0080,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f4\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x4080,0x4080,0x4080,0x4080,0x2080,0x1f80,0x0080,0x0080,0x0080,\n  0x0080,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f5\n  0x2100,0x2100,0x2100,0x0000,0x4040,0x4040,0x4040,0x4040,0x7840,0x4440,0x4240,0x4240,0x4240,0x4240,0x4240,0x4440,\n  0x7840,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f8\n  0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x4040,0x4040,0x4040,0x7840,0x4440,0x4240,0x4240,0x4240,0x4440,\n  0x7840,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f9\n  0x0000,0x0000,0x0000,0x2040,0x2040,0x1040,0x1040,0x0840,0x0840,0x1480,0x2500,0x4200,0x4200,0x4100,0x4100,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d0\n  0x0000,0x0000,0x0000,0xfc00,0x0200,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d1\n  0x0000,0x0000,0x0000,0x7800,0x0400,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0600,0x0a00,0x1100,0x2100,0x4080,\n  0x8080,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d2\n  0x0000,0x0000,0x0000,0xffc0,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0100,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d3\n  0x0000,0x0000,0x0000,0x7e00,0x0100,0x0080,0x0080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d4\n  0x0000,0x0000,0x0000,0x3000,0x0800,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d5\n  0x0000,0x0000,0x0000,0x3f80,0x0100,0x0200,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d6\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d7\n  0x0000,0x0000,0x0000,0x4600,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d8\n  0x0000,0x0000,0x0000,0x3000,0x0800,0x0400,0x0400,0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d9\n  0x0000,0x0000,0x0000,0x7e00,0x0100,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,\n  0x0080,0x0080,0x0080,0x0080,0x0080,0x0000, // u05da\n  0x0000,0x0000,0x0000,0x7e00,0x0100,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0100,\n  0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u05db\n  0x4000,0x4000,0x4000,0x7f80,0x0080,0x0080,0x0080,0x0080,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x1000,0x1000,\n  0x1000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05dc\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u05dd\n  0x0000,0x0000,0x0000,0xef00,0x3080,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,\n  0x23c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u05de\n  0x0000,0x0000,0x0000,0x7800,0x0400,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,\n  0x0200,0x0200,0x0200,0x0200,0x0200,0x0000, // u05df\n  0x0000,0x0000,0x0000,0x3c00,0x0200,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e0\n  0x0000,0x0000,0x0000,0xff00,0x2080,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,0x1080,\n  0x0f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e1\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x2080,0x2080,0x2080,0x1080,0x1100,0x0900,0x0900,0x0600,0x0c00,0x1800,\n  0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e2\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x2080,0x1880,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,\n  0x0080,0x0080,0x0080,0x0080,0x0080,0x0000, // u05e3\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x2080,0x1880,0x0080,0x0080,0x0080,0x0080,0x0080,0x0100,\n  0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e4\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x2080,0x2080,0x1100,0x1200,0x0c00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0000, // u05e5\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x2080,0x2080,0x1100,0x1200,0x0c00,0x0800,0x0400,0x0400,0x0200,0x0200,0x0100,\n  0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e6\n  0x0000,0x0000,0x0000,0x7f80,0x0080,0x0080,0x0080,0x4080,0x4080,0x4100,0x4200,0x4400,0x4800,0x4800,0x4800,0x4800,\n  0x4800,0x4000,0x4000,0x4000,0x4000,0x0000, // u05e7\n  0x0000,0x0000,0x0000,0x7e00,0x0100,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,\n  0x0080,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e8\n  0x0000,0x0000,0x0000,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4840,0x7040,0x4040,0x4040,0x4040,0x4080,\n  0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e9\n  0x0000,0x0000,0x0000,0xff00,0x2080,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,\n  0xc040,0x0000,0x0000,0x0000,0x0000,0x0000, // u05ea\n  0x0000,0x0000,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4100,\n  0x7e00,0x0000,0x0800,0x0800,0x0800,0x0000, // u1e0c\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0080,0x1f80,0x2080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0000,0x0400,0x0400,0x0400,0x0000, // u1e0d\n  0x0000,0x0000,0x0000,0x4080,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x6000,0x5000,0x4800,0x4400,0x4200,0x4100,\n  0x4080,0x0000,0x3f00,0x0000,0x0000,0x0000, // u1e34\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x2000,0x2080,0x2100,0x2200,0x2400,0x3800,0x3800,0x2400,0x2200,0x2100,\n  0x2080,0x0000,0x1f00,0x0000,0x0000,0x0000, // u1e35\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0400,0x0400,0x0400,0x0000, // u1e36\n  0x0000,0x0000,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0400,0x0400,0x0400,0x0000, // u1e37\n  0x0400,0x0400,0x0400,0x4040,0x60c0,0x5140,0x5140,0x4a40,0x4440,0x4440,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e40\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0000,0x7f00,0x4480,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,\n  0x4440,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e41\n  0x0000,0x0000,0x0000,0x4040,0x60c0,0x5140,0x5140,0x4a40,0x4440,0x4440,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x0000,0x0400,0x0400,0x0400,0x0000, // u1e42\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4480,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,\n  0x4440,0x0000,0x0400,0x0400,0x0400,0x0000, // u1e43\n  0x0400,0x0400,0x0400,0x4080,0x4080,0x4080,0x4080,0x6080,0x5080,0x4880,0x4480,0x4280,0x4180,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e44\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e45\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x6080,0x5080,0x4880,0x4480,0x4280,0x4180,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0400,0x0400,0x0400,0x0000, // u1e46\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0400,0x0400,0x0400,0x0000, // u1e47\n  0x0000,0x0000,0x0000,0x7fc0,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0400,0x0400,0x0400,0x0000, // u1e6c\n  0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x7f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0780,0x0000,0x0200,0x0200,0x0200,0x0000, // u1e6d\n  0x0000,0x0000,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0400,0x0400,0x0400,0x0000, // u1eb8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x7f80,0x4000,0x4000,0x4000,0x2080,\n  0x1f00,0x0000,0x0400,0x0400,0x0400,0x0000, // u1eb9\n  0x1880,0x2480,0x2300,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u1ebc\n  0x0000,0x0000,0x0000,0x1880,0x2480,0x2300,0x0000,0x1e00,0x2100,0x4080,0x4080,0x7f80,0x4000,0x4000,0x4000,0x2080,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u1ebd\n  0x0000,0x0000,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0400,0x0400,0x0400,0x0000, // u1eca\n  0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x1f00,0x0000,0x0400,0x0400,0x0400,0x0000, // u1ecb\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0400,0x0400,0x0400,0x0000, // u1ecc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0400,0x0400,0x0400,0x0000, // u1ecd\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0400,0x0400,0x0400,0x0000, // u1ee4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0000,0x0400,0x0400,0x0400,0x0000, // u1ee5\n  0x1880,0x2480,0x2300,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u1ef8\n  0x0000,0x0000,0x0000,0x1880,0x2480,0x2300,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2080,\n  0x1f80,0x0080,0x0080,0x0100,0x3e00,0x0000, // u1ef9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2001\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2002\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2003\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2004\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2005\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2006\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2007\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2008\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2009\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2010\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2011\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2012\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2013\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2014\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2015\n  0x0000,0x0000,0x0000,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,\n  0x1200,0x0000,0x0000,0x0000,0x0000,0x0000, // u2016\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x7f80,0x0000,0x0000,0x7f80, // u2017\n  0x0000,0x0200,0x0400,0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2018\n  0x0000,0x0400,0x0400,0x0400,0x0400,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2019\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,\n  0x0400,0x0800,0x0000,0x0000,0x0000,0x0000, // u201a\n  0x0000,0x0400,0x0400,0x0400,0x0400,0x0200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201b\n  0x0000,0x0880,0x1100,0x1100,0x1100,0x1100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201c\n  0x0000,0x1100,0x1100,0x1100,0x1100,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,\n  0x1100,0x2200,0x0000,0x0000,0x0000,0x0000, // u201e\n  0x0000,0x2200,0x2200,0x2200,0x2200,0x1100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201f\n  0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x3f80,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2020\n  0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x3f80,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x3f80,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2021\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x1f00,0x1f00,0x1f00,0x0e00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2022\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4440,0x4440,\n  0x4440,0x0000,0x0000,0x0000,0x0000,0x0000, // u2026\n  0x0000,0x0000,0x0000,0x6200,0x9200,0x9400,0x6400,0x0800,0x0800,0x1000,0x1000,0x2000,0x2000,0x4d80,0x5240,0x9240,\n  0x8d80,0x0000,0x0000,0x0000,0x0000,0x0000, // u2030\n  0x0000,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2032\n  0x0000,0x1100,0x1100,0x1100,0x1100,0x1100,0x1100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2033\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0800,0x1000,0x1000,0x0800,0x0400,0x0200,\n  0x0100,0x0000,0x0000,0x0000,0x0000,0x0000, // u2039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x0800,0x0400,0x0200,0x0100,0x0100,0x0200,0x0400,0x0800,\n  0x1000,0x0000,0x0000,0x0000,0x0000,0x0000, // u203a\n  0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,0x1100,0x1100,0x1100,0x1100,0x1100,0x1100,0x0000,0x0000,0x1100,0x1100,\n  0x1100,0x0000,0x0000,0x0000,0x0000,0x0000, // u203c\n  0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u203e\n  0x0000,0x0e00,0x1100,0x1100,0x1100,0x1100,0x1100,0x1100,0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2070\n  0x0400,0x0400,0x0000,0x0c00,0x0400,0x0400,0x0400,0x0400,0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2071\n  0x0000,0x0100,0x0300,0x0500,0x0900,0x1100,0x1f00,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2074\n  0x0000,0x1f00,0x1000,0x1000,0x1e00,0x0100,0x0100,0x1100,0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2075\n  0x0000,0x0e00,0x1000,0x1000,0x1e00,0x1100,0x1100,0x1100,0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2076\n  0x0000,0x1f00,0x0100,0x0100,0x0200,0x0200,0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2077\n  0x0000,0x0e00,0x1100,0x1100,0x0e00,0x1100,0x1100,0x1100,0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2078\n  0x0000,0x0e00,0x1100,0x1100,0x1100,0x0f00,0x0100,0x0100,0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2079\n  0x0000,0x0000,0x0400,0x0400,0x0400,0x3f80,0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207b\n  0x0000,0x0000,0x0000,0x3f00,0x0000,0x0000,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207c\n  0x0000,0x0200,0x0400,0x0800,0x0800,0x0800,0x0800,0x0400,0x0200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207d\n  0x0000,0x0800,0x0400,0x0200,0x0200,0x0200,0x0200,0x0400,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207e\n  0x0000,0x0000,0x3e00,0x2100,0x2100,0x2100,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x1100,0x1100,0x1100,0x1100,\n  0x1100,0x1100,0x0e00,0x0000,0x0000,0x0000, // u2080\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0c00,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0e00,0x0000,0x0000,0x0000, // u2081\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x1100,0x1100,0x0100,0x0200,\n  0x0400,0x0800,0x1f00,0x0000,0x0000,0x0000, // u2082\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x1100,0x0100,0x0600,0x0100,\n  0x0100,0x1100,0x0e00,0x0000,0x0000,0x0000, // u2083\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0300,0x0500,0x0900,0x1100,\n  0x1f00,0x0100,0x0100,0x0000,0x0000,0x0000, // u2084\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x1000,0x1000,0x1e00,0x0100,\n  0x0100,0x1100,0x0e00,0x0000,0x0000,0x0000, // u2085\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x1000,0x1000,0x1e00,0x1100,\n  0x1100,0x1100,0x0e00,0x0000,0x0000,0x0000, // u2086\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x0100,0x0100,0x0200,0x0200,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000, // u2087\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x1100,0x1100,0x0e00,0x1100,\n  0x1100,0x1100,0x0e00,0x0000,0x0000,0x0000, // u2088\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x1100,0x1100,0x1100,0x0f00,\n  0x0100,0x0100,0x0e00,0x0000,0x0000,0x0000, // u2089\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x3f80,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000, // u208a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u208b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0000,0x0000,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u208c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x0800,0x0800,\n  0x0800,0x0400,0x0200,0x0000,0x0000,0x0000, // u208d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0400,0x0200,0x0200,0x0200,\n  0x0200,0x0400,0x0800,0x0000,0x0000,0x0000, // u208e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x0100,0x1f00,0x2100,\n  0x2100,0x2100,0x1f00,0x0000,0x0000,0x0000, // u2090\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x2100,0x3f00,\n  0x2000,0x2000,0x1e00,0x0000,0x0000,0x0000, // u2091\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x2100,0x2100,\n  0x2100,0x2100,0x1e00,0x0000,0x0000,0x0000, // u2092\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x1200,0x0c00,\n  0x1200,0x2100,0x2100,0x0000,0x0000,0x0000, // u2093\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x0100,0x0100,0x3f00,\n  0x2100,0x2100,0x1e00,0x0000,0x0000,0x0000, // u2094\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x3e00,0x2100,0x2100,0x2100,\n  0x2100,0x2100,0x2100,0x0000,0x0000,0x0000, // u2095\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x2100,0x2200,0x2400,0x3800,\n  0x2400,0x2200,0x2100,0x0000,0x0000,0x0000, // u2096\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0e00,0x0000,0x0000,0x0000, // u2097\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x2480,0x2480,0x2480,\n  0x2480,0x2480,0x2480,0x0000,0x0000,0x0000, // u2098\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x2100,0x2100,0x2100,\n  0x2100,0x2100,0x3e00,0x2000,0x2000,0x2000, // u209a\n  0x0000,0x0000,0x0000,0x7800,0x4400,0x4200,0x4200,0x4200,0x4200,0x4400,0x7900,0x4100,0x47c0,0x4100,0x4100,0x4100,\n  0x40c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u20a7\n  0x0000,0x0000,0x0000,0x7840,0x4440,0x4240,0x4240,0x4a40,0x4a40,0x4a40,0x4a40,0x4a40,0x4a40,0x4840,0x4840,0x4880,\n  0x4f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u20aa\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4000,0x4000,0xfc00,0x4000,0x4000,0xfc00,0x4000,0x4000,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u20ac\n  0x0000,0x0000,0x0000,0x7fc0,0x0400,0x0400,0x0400,0x0580,0x0600,0x0c00,0x3580,0x0600,0x0c00,0x3400,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u20ae\n  0x0000,0x0000,0x0000,0x1e00,0x3100,0x5080,0x5080,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5080,0x5080,0x3100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2102\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u210e\n  0x0000,0x0000,0x0000,0x4000,0xfc00,0x4000,0x4000,0x7e00,0x4100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u210f\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x6080,0x5080,0x6880,0x5480,0x4a80,0x4580,0x4280,0x4180,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u2115\n  0x0000,0x0000,0x0000,0x8400,0x84c0,0x8520,0xc520,0xc4c0,0xa400,0xa400,0x9400,0x95e0,0x8c00,0x8c00,0x85e0,0x8400,\n  0x8400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2116\n  0x0000,0x0000,0x0000,0x1e00,0x3100,0x5080,0x5080,0x5080,0x5080,0x5080,0x5080,0x5080,0x5080,0x5080,0x5480,0x3300,\n  0x1f00,0x0080,0x0040,0x0000,0x0000,0x0000, // u211a\n  0x0000,0x0000,0x0000,0x7e00,0x5100,0x5080,0x5080,0x5080,0x5080,0x5100,0x5e00,0x5400,0x5a00,0x5500,0x5280,0x5140,\n  0x70c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u211d\n  0x0000,0x0000,0x0000,0xfc40,0x26c0,0x2540,0x2440,0x2440,0x2440,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2122\n  0x0000,0x0000,0x0000,0x7f80,0x0080,0x0080,0x0180,0x0280,0x0500,0x0a00,0x1400,0x2800,0x5000,0x6000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u2124\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,0x1200,0x1200,\n  0x7380,0x0000,0x0000,0x0000,0x0000,0x0000, // u2126\n  0x0000,0x0000,0x0000,0x4200,0x4200,0x2100,0x2100,0x1080,0x1040,0x2880,0x4900,0x8600,0x8400,0x8200,0x8200,0x4100,\n  0x2100,0x0000,0x0000,0x0000,0x0000,0x0000, // u2135\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x2000,0x4000,0xffc0,0x4000,0x2000,0x1000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2190\n  0x0000,0x0000,0x0000,0x0400,0x0e00,0x1500,0x2480,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2191\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0200,0x0100,0x0080,0xffc0,0x0080,0x0100,0x0200,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2192\n  0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x2480,0x1500,0x0e00,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2193\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1100,0x2080,0x4040,0xffe0,0x4040,0x2080,0x1100,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2194\n  0x0000,0x0000,0x0000,0x0400,0x0e00,0x1500,0x2480,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x2480,0x1500,0x0e00,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2195\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1040,0x2040,0x4040,0xffc0,0x4040,0x2040,0x1040,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x8200,0x8100,0x8080,0xffc0,0x8080,0x8100,0x8200,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a6\n  0x0000,0x0000,0x0000,0x0400,0x0e00,0x1500,0x2480,0x0400,0x0400,0x0400,0x0400,0x0400,0x2480,0x1500,0x0e00,0x0400,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a8\n  0x0000,0x0000,0x0000,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x1040,0x2040,0x4040,0xffc0,0x4000,0x2000,\n  0x1000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7800,0x1800,0x2880,0x4840,0x4040,0x4040,0x4040,0x4040,0x2080,0x1f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x2000,0x4000,0xffc0,0x0000,0x0000,0xffc0,0x0080,0x0100,0x0200,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0200,0x0100,0x0080,0xffc0,0x0000,0x0000,0xffc0,0x4000,0x2000,0x1000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21cc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x2000,0x7fc0,0xc000,0xc000,0x7fc0,0x2000,0x1000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d0\n  0x0000,0x0000,0x0000,0x0c00,0x1e00,0x3300,0x5280,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,\n  0x1200,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0200,0x0100,0xff80,0x00c0,0x00c0,0xff80,0x0100,0x0200,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d2\n  0x0000,0x0000,0x0000,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x5280,0x3300,0x1e00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1100,0x2080,0x7fc0,0xc060,0xc060,0x7fc0,0x2080,0x1100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d4\n  0x0000,0x0000,0x0000,0x0c00,0x1e00,0x3300,0x5280,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x5280,0x3300,0x1e00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d5\n  0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x2080,0x3f80,0x2080,0x1100,0x1100,0x1100,0x0a00,0x0a00,0x0a00,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2200\n  0x0000,0x0000,0x0000,0x0000,0x7f80,0x0080,0x0080,0x0080,0x0080,0x0080,0x7f80,0x0080,0x0080,0x0080,0x0080,0x0080,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u2203\n  0x0000,0x0000,0x0080,0x0080,0x7f80,0x0180,0x0280,0x0280,0x0480,0x0480,0x7f80,0x0880,0x0880,0x1080,0x1080,0x2080,\n  0x7f80,0x4000,0x4000,0x0000,0x0000,0x0000, // u2204\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0040,0x1e80,0x2100,0x4280,0x4480,0x4880,0x5080,0x2100,0x5e00,0x8000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2205\n  0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0a00,0x0a00,0x1100,0x1100,0x1100,0x2080,0x2080,0x2080,0x4040,0x4040,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2206\n  0x0000,0x0000,0x0000,0x7fc0,0x4040,0x4040,0x2080,0x2080,0x2080,0x1100,0x1100,0x1100,0x0a00,0x0a00,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2207\n  0x0000,0x0000,0x0000,0x0000,0x0f80,0x1000,0x2000,0x4000,0x4000,0x4000,0x7f80,0x4000,0x4000,0x4000,0x2000,0x1000,\n  0x0f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u2208\n  0x0000,0x0000,0x0080,0x0080,0x0f80,0x1100,0x2100,0x4200,0x4200,0x4400,0x7f80,0x4400,0x4800,0x4800,0x3000,0x1000,\n  0x2f80,0x2000,0x2000,0x0000,0x0000,0x0000, // u2209\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x2000,0x4000,0x4000,0x7f80,0x4000,0x4000,0x2000,0x1f80,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u220a\n  0x0000,0x0000,0x0000,0x0000,0x7c00,0x0200,0x0100,0x0080,0x0080,0x0080,0x7f80,0x0080,0x0080,0x0080,0x0100,0x0200,\n  0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u220b\n  0x0000,0x0000,0x4000,0x4000,0x7c00,0x2200,0x2100,0x1080,0x1080,0x0880,0x7f80,0x0880,0x0480,0x0480,0x0300,0x0200,\n  0x7d00,0x0100,0x0100,0x0000,0x0000,0x0000, // u220c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0100,0x0080,0x0080,0x7f80,0x0080,0x0080,0x0100,0x7e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u220d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2212\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x7fc0,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2213\n  0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x7fc0,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2214\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2215\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,0x0080,0x0040,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2216\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x0e00,0x0e00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2219\n  0x0000,0x01c0,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x4100,0x4100,0x4100,0x2100,0x1100,0x0900,0x0500,\n  0x0300,0x0000,0x0000,0x0000,0x0000,0x0000, // u221a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3b80,0x4440,0x4440,0x4440,0x4440,0x4440,0x3b80,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u221e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f80,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u221f\n  0x0000,0x0000,0x0000,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,\n  0x1200,0x0000,0x0000,0x0000,0x0000,0x0000, // u2225\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0a00,0x0a00,0x1100,0x1100,0x2080,0x2080,0x4040,\n  0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u2227\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0a00,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2228\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u2229\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u222a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3080,0x4c80,0x4300,0x0000,0x3080,0x4c80,0x4300,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2248\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x7f80,0x0200,0x0400,0x0800,0x1000,0x7f80,0x4000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2260\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x7f80,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2261\n  0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,0x0000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u2264\n  0x0000,0x0000,0x0000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x0000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u2265\n  0x0000,0x0000,0x0000,0x0000,0x0440,0x0880,0x1100,0x2200,0x4400,0x8800,0x8800,0x4400,0x2200,0x1100,0x0880,0x0440,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u226a\n  0x0000,0x0000,0x0000,0x0000,0x8800,0x4400,0x2200,0x1100,0x0880,0x0440,0x0440,0x0880,0x1100,0x2200,0x4400,0x8800,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u226b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x1000,0x2000,0x4000,0x4000,0x4000,0x4000,0x2000,0x1000,0x0fc0,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2282\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0100,0x0080,0x0040,0x0040,0x0040,0x0040,0x0080,0x0100,0x7e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2283\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x1000,0x2000,0x4000,0x4000,0x4000,0x4000,0x2000,0x1000,0x0fc0,0x0000,0x0000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2286\n  0x0000,0x0000,0x0000,0x0000,0x7e00,0x0100,0x0080,0x0040,0x0040,0x0040,0x0040,0x0080,0x0100,0x7e00,0x0000,0x0000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2287\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u22a5\n  0x0000,0x0000,0x0000,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u22c2\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u22c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0040,0x1e80,0x2100,0x4280,0x4480,0x4880,0x5080,0x2100,0x5e00,0x8000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2300\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x1200,0x2100,0x4080,0x8040,0x8040,0x8040,0x8040,0x8040,0x8040,\n  0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2302\n  0x0000,0x0000,0x0000,0x1e00,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,\n  0x1000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2308\n  0x0000,0x0000,0x0000,0x1e00,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,\n  0x0200,0x0000,0x0000,0x0000,0x0000,0x0000, // u2309\n  0x0000,0x0000,0x0000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u230a\n  0x0000,0x0000,0x0000,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u230b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2310\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x7f80,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2319\n  0x0000,0x0000,0x0000,0x0380,0x0440,0x0440,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2320\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x4400,0x4400,\n  0x3800,0x0000,0x0000,0x0000,0x0000,0x0000, // u2321\n  0x0080,0x0100,0x0200,0x0400,0x0400,0x0800,0x0800,0x0800,0x1000,0x1000,0x1000,0x1000,0x2000,0x2000,0x2000,0x2000,\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u239b\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u239c\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x1000,0x1000,0x1000,0x1000,0x0800,0x0800,\n  0x0800,0x0400,0x0400,0x0200,0x0100,0x0080, // u239d\n  0x2000,0x1000,0x0800,0x0400,0x0400,0x0200,0x0200,0x0200,0x0100,0x0100,0x0100,0x0100,0x0080,0x0080,0x0080,0x0080,\n  0x0080,0x0080,0x0080,0x0080,0x0080,0x0080, // u239e\n  0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,\n  0x0080,0x0080,0x0080,0x0080,0x0080,0x0080, // u239f\n  0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0100,0x0100,0x0100,0x0100,0x0200,0x0200,\n  0x0200,0x0400,0x0400,0x0800,0x1000,0x2000, // u23a0\n  0x3f80,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u23a1\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u23a2\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x3f80, // u23a3\n  0x3f80,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,\n  0x0080,0x0080,0x0080,0x0080,0x0080,0x0080, // u23a4\n  0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,\n  0x0080,0x0080,0x0080,0x0080,0x0080,0x0080, // u23a5\n  0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,\n  0x0080,0x0080,0x0080,0x0080,0x0080,0x3f80, // u23a6\n  0x01c0,0x0600,0x0400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800, // u23a7\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1000,0x6000,0x6000,0x1000,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800, // u23a8\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0400,0x0600,0x01c0, // u23a9\n  0x7000,0x0c00,0x0400,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,\n  0x0200,0x0200,0x0200,0x0200,0x0200,0x0200, // u23ab\n  0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0100,0x00c0,0x00c0,0x0100,0x0200,0x0200,0x0200,\n  0x0200,0x0200,0x0200,0x0200,0x0200,0x0200, // u23ac\n  0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,\n  0x0200,0x0200,0x0200,0x0400,0x0c00,0x7000, // u23ad\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u23ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23af\n  0xffe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0xffe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u23bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0, // u23bd\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u23d0\n  0x0000,0x0000,0x4400,0x4400,0x4400,0x7c00,0x4400,0x4400,0x4400,0x0000,0x0f80,0x0200,0x0200,0x0200,0x0200,0x0200,\n  0x0200,0x0000,0x0000,0x0000,0x0000,0x0000, // u2409\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x0000,0x0f80,0x0800,0x0800,0x0e00,0x0800,0x0800,\n  0x0800,0x0000,0x0000,0x0000,0x0000,0x0000, // u240a\n  0x0000,0x0000,0x4400,0x4400,0x4400,0x2800,0x2800,0x1000,0x1000,0x0000,0x0f80,0x0200,0x0200,0x0200,0x0200,0x0200,\n  0x0200,0x0000,0x0000,0x0000,0x0000,0x0000, // u240b\n  0x0000,0x0000,0x7c00,0x4000,0x4000,0x7000,0x4000,0x4000,0x4000,0x0000,0x0f80,0x0800,0x0800,0x0e00,0x0800,0x0800,\n  0x0800,0x0000,0x0000,0x0000,0x0000,0x0000, // u240c\n  0x0000,0x0000,0x3800,0x4400,0x4000,0x4000,0x4000,0x4400,0x3800,0x0000,0x0f00,0x0880,0x0880,0x0f00,0x0a00,0x0900,\n  0x0880,0x0000,0x0000,0x0000,0x0000,0x0000, // u240d\n  0x0000,0x0000,0x4400,0x4400,0x6400,0x5400,0x4c00,0x4400,0x4400,0x0000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u2424\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2500\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2501\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2502\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2503\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xd6c0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2508\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xd6c0,0xd6c0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2509\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0000,0x0400,0x0400,0x0400,0x0400,0x0000,0x0400,0x0400,0x0400,0x0400,0x0000,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0000, // u250a\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0000, // u250b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07e0,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u250c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07e0,0x07e0,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u250d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u250e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x0fe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u250f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2510\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2511\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2512\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2513\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2514\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2515\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2516\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2517\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2518\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2519\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u251a\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u251b\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x07e0,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u251c\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x07e0,0x07e0,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u251d\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fe0,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u251e\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0fe0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u251f\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fe0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2520\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fe0,0x0fe0,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2521\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0fe0,0x0fe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2522\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fe0,0x0fe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2523\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfc00,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2524\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfc00,0xfc00,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2525\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2526\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2527\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2528\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2529\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u252a\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u252b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u252c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xfc00,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u252d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0x07e0,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u252e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u252f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2530\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2531\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0x0fe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2532\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2533\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xffe0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2534\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xffe0,0xfc00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2535\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xffe0,0x07e0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2536\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xffe0,0xffe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2537\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffe0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2538\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffe0,0xfc00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2539\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u253a\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffe0,0xffe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u253b\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xffe0,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u253c\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xffe0,0xfc00,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u253d\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xffe0,0x07e0,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u253e\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xffe0,0xffe0,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u253f\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffe0,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2540\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xffe0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2541\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffe0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2542\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffe0,0xfc00,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2543\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffe0,0x07e0,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2544\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xffe0,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2545\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xffe0,0x0fe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2546\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffe0,0xffe0,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2547\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xffe0,0xffe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2548\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffe0,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2549\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffe0,0x0fe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u254a\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffe0,0xffe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u254b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0x0000,0x0000,0xffe0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2550\n  0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,\n  0x1200,0x1200,0x1200,0x1200,0x1200,0x1200, // u2551\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07e0,0x0400,0x0400,0x07e0,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2552\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fe0,0x1200,0x1200,0x1200,0x1200,0x1200,\n  0x1200,0x1200,0x1200,0x1200,0x1200,0x1200, // u2553\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fe0,0x1000,0x1000,0x13e0,0x1200,0x1200,0x1200,\n  0x1200,0x1200,0x1200,0x1200,0x1200,0x1200, // u2554\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x0400,0x0400,0xfc00,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2555\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x1200,0x1200,0x1200,0x1200,0x1200,\n  0x1200,0x1200,0x1200,0x1200,0x1200,0x1200, // u2556\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0200,0x0200,0xf200,0x1200,0x1200,0x1200,\n  0x1200,0x1200,0x1200,0x1200,0x1200,0x1200, // u2557\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x07e0,0x0400,0x0400,0x07e0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2558\n  0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2559\n  0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x13e0,0x1000,0x1000,0x1fe0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255a\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfc00,0x0400,0x0400,0xfc00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255b\n  0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0xfe00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255c\n  0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0xf200,0x0200,0x0200,0xfe00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255d\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x07e0,0x0400,0x0400,0x07e0,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u255e\n  0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1fe0,0x1200,0x1200,0x1200,0x1200,0x1200,\n  0x1200,0x1200,0x1200,0x1200,0x1200,0x1200, // u255f\n  0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x13e0,0x1000,0x1000,0x13e0,0x1200,0x1200,0x1200,\n  0x1200,0x1200,0x1200,0x1200,0x1200,0x1200, // u2560\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfc00,0x0400,0x0400,0xfc00,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2561\n  0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0xfe00,0x1200,0x1200,0x1200,0x1200,0x1200,\n  0x1200,0x1200,0x1200,0x1200,0x1200,0x1200, // u2562\n  0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0xf200,0x0200,0x0200,0xf200,0x1200,0x1200,0x1200,\n  0x1200,0x1200,0x1200,0x1200,0x1200,0x1200, // u2563\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0x0000,0x0000,0xffe0,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2564\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0x1200,0x1200,0x1200,0x1200,0x1200,\n  0x1200,0x1200,0x1200,0x1200,0x1200,0x1200, // u2565\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0x0000,0x0000,0xf3e0,0x1200,0x1200,0x1200,\n  0x1200,0x1200,0x1200,0x1200,0x1200,0x1200, // u2566\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xffe0,0x0000,0x0000,0xffe0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2567\n  0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0xffe0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2568\n  0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0xf3e0,0x0000,0x0000,0xffe0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2569\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xffe0,0x0400,0x0400,0xffe0,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u256a\n  0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0xffe0,0x1200,0x1200,0x1200,0x1200,0x1200,\n  0x1200,0x1200,0x1200,0x1200,0x1200,0x1200, // u256b\n  0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0x1200,0xf3e0,0x0000,0x0000,0xf3e0,0x1200,0x1200,0x1200,\n  0x1200,0x1200,0x1200,0x1200,0x1200,0x1200, // u256c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0180,0x0200,0x0200,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u256d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0x3000,0x0800,0x0800,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u256e\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0800,0x0800,0x3000,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u256f\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0200,0x0200,0x0180,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2570\n  0x0020,0x0020,0x0040,0x0040,0x0080,0x0080,0x0100,0x0100,0x0200,0x0200,0x0400,0x0400,0x0800,0x0800,0x1000,0x1000,\n  0x2000,0x2000,0x4000,0x4000,0x8000,0x8000, // u2571\n  0x8000,0x8000,0x4000,0x4000,0x2000,0x2000,0x1000,0x1000,0x0800,0x0800,0x0400,0x0400,0x0200,0x0200,0x0100,0x0100,\n  0x0080,0x0080,0x0040,0x0040,0x0020,0x0020, // u2572\n  0x8020,0x8020,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0a00,0x0400,0x0400,0x0a00,0x0a00,0x1100,0x1100,\n  0x2080,0x2080,0x4040,0x4040,0x8020,0x8020, // u2573\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2574\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2575\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2576\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2577\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2578\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2579\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u257b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0x07e0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257c\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u257d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xfc00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257e\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u257f\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2580\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0xffe0,0xffe0,0xffe0, // u2581\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0, // u2582\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0, // u2583\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0, // u2584\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0, // u2585\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0, // u2586\n  0x0000,0x0000,0x0000,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0, // u2587\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0, // u2588\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0, // u2589\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u258a\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00, // u258b\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800, // u258c\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000, // u258d\n  0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,\n  0xe000,0xe000,0xe000,0xe000,0xe000,0xe000, // u258e\n  0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,\n  0x8000,0x8000,0x8000,0x8000,0x8000,0x8000, // u258f\n  0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,\n  0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0, // u2590\n  0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000,\n  0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000, // u2591\n  0xaaa0,0x5540,0xaaa0,0x5540,0xaaa0,0x5540,0xaaa0,0x5540,0xaaa0,0x5540,0xaaa0,0x5540,0xaaa0,0x5540,0xaaa0,0x5540,\n  0xaaa0,0x5540,0xaaa0,0x5540,0xaaa0,0x5540, // u2592\n  0xffe0,0xaaa0,0xffe0,0xaaa0,0xffe0,0xaaa0,0xffe0,0xaaa0,0xffe0,0xaaa0,0xffe0,0xaaa0,0xffe0,0xaaa0,0xffe0,0xaaa0,\n  0xffe0,0xaaa0,0xffe0,0xaaa0,0xffe0,0xaaa0, // u2593\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800, // u2596\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,\n  0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0, // u2597\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2598\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0, // u2599\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,\n  0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0, // u259a\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800, // u259b\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,\n  0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0, // u259c\n  0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u259d\n  0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800, // u259e\n  0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0, // u259f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x3f00,0x3f00,0x3f00,0x3f00,0x3f00,0x3f00,0x3f00,0x3f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fc0,0x7fc0,0x7fc0,0x7fc0,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ac\n  0x0000,0x0000,0x0000,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,0x7f80,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x1e00,0x1e00,0x3f00,0x3f00,0x7f80,0x7f80,0xffc0,0xffc0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xffc0,0xffc0,0xff00,0xfc00,0xf000,0xc000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xffc0,0xffc0,0xff00,0xfc00,0xf000,0xc000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x7f80,0x7f80,0x3f00,0x3f00,0x1e00,0x1e00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x01e0,0x07e0,0x1fe0,0x7fe0,0x7fe0,0x1fe0,0x07e0,0x01e0,0x0060,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x01e0,0x07e0,0x1fe0,0x7fe0,0x7fe0,0x1fe0,0x07e0,0x01e0,0x0060,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0e00,0x1f00,0x3f80,0x7fc0,0x3f80,0x1f00,0x0e00,0x0400,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0a00,0x1100,0x2080,0x4040,0x2080,0x1100,0x0a00,0x0400,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ca\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x1100,0x1100,0x1100,0x0e00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x1f00,0x1f00,0x1f00,0x0e00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25cf\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xf1e0,0xe0e0,0xe0e0,0xe0e0,0xf1e0,0xffe0,0xffe0,0xffe0,\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0, // u25d8\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xf1e0,0xeee0,0xeee0,0xeee0,0xf1e0,0xffe0,0xffe0,0xffe0,\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0, // u25d9\n  0x0000,0x0000,0x0000,0x3f00,0x4080,0x8040,0xb340,0xb340,0x8040,0x8040,0x8040,0xbf40,0x9e40,0x8040,0x8040,0x4080,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u263a\n  0x0000,0x0000,0x0000,0x3f00,0x7f80,0xffc0,0xccc0,0xccc0,0xffc0,0xffc0,0xffc0,0xc0c0,0xe1c0,0xffc0,0xffc0,0x7f80,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u263b\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x4440,0x2480,0x1500,0x0e00,0x7bc0,0x0e00,0x1500,0x2480,0x4440,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u263c\n  0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x2080,0x1f00,0x0400,0x0400,0x7fc0,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2640\n  0x0000,0x0000,0x0000,0x07c0,0x00c0,0x0140,0x0240,0x0440,0x1e00,0x2100,0x4080,0x4080,0x4080,0x4080,0x4080,0x2100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2642\n  0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0e00,0x1f00,0x3f80,0x7fc0,0x7fc0,0x7fc0,0x7fc0,0x3580,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2660\n  0x0000,0x0000,0x0000,0x0e00,0x1f00,0x1f00,0x0e00,0x0400,0x0400,0x3580,0x7fc0,0x7fc0,0x7fc0,0x3580,0x0400,0x0400,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2663\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x7bc0,0x7fc0,0x7fc0,0x7fc0,0x7fc0,0x7fc0,0x3f80,0x1f00,0x0e00,0x0400,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2665\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0e00,0x1f00,0x3f80,0x7fc0,0x3f80,0x1f00,0x0e00,0x0400,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2666\n  0x0000,0x0000,0x0000,0x1fc0,0x1040,0x1040,0x1040,0x1fc0,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,\n  0xe000,0x0000,0x0000,0x0000,0x0000,0x0000, // u266a\n  0x0000,0x0000,0x0000,0x7f80,0x4080,0x4080,0x4080,0x7f80,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4100,\n  0x8000,0x0000,0x0000,0x0000,0x0000,0x0000, // u266b\n  0x0000,0x0000,0x0000,0x0040,0x0040,0x0080,0x0080,0x0100,0x0100,0x8200,0x8200,0x4400,0x4400,0x2800,0x2800,0x1000,\n  0x1000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2713\n  0x0000,0x0000,0x0000,0x0060,0x0060,0x00c0,0x00c0,0x0180,0x0180,0xc300,0xc300,0x6600,0x6600,0x3c00,0x3c00,0x1800,\n  0x1800,0x0000,0x0000,0x0000,0x0000,0x0000, // u2714\n  0x0000,0x0000,0x0000,0x0100,0x0100,0x4200,0x2200,0x1400,0x0c00,0x0c00,0x0a00,0x1100,0x1080,0x2000,0x2000,0x4000,\n  0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2717\n  0x0000,0x0000,0x0000,0x0180,0x0180,0x6300,0x3300,0x1e00,0x0e00,0x0e00,0x0f00,0x1980,0x18c0,0x3000,0x3000,0x6000,\n  0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2718\n  0x0000,0x0000,0x0000,0x0200,0x0200,0x0400,0x0400,0x0800,0x0800,0x1000,0x1000,0x0800,0x0800,0x0400,0x0400,0x0200,\n  0x0200,0x0000,0x0000,0x0000,0x0000,0x0000, // u27e8\n  0x0000,0x0000,0x0000,0x1000,0x1000,0x0800,0x0800,0x0400,0x0400,0x0200,0x0200,0x0400,0x0400,0x0800,0x0800,0x1000,\n  0x1000,0x0000,0x0000,0x0000,0x0000,0x0000, // u27e9\n  0x0000,0x0000,0x0000,0x0880,0x0880,0x1100,0x1100,0x2200,0x2200,0x4400,0x4400,0x2200,0x2200,0x1100,0x1100,0x0880,\n  0x0880,0x0000,0x0000,0x0000,0x0000,0x0000, // u27ea\n  0x0000,0x0000,0x0000,0x4400,0x4400,0x2200,0x2200,0x1100,0x1100,0x0880,0x0880,0x1100,0x1100,0x2200,0x2200,0x4400,\n  0x4400,0x0000,0x0000,0x0000,0x0000,0x0000, // u27eb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2800\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2801\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2802\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2803\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2804\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2805\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2806\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2807\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2808\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2809\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280a\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280b\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280c\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280d\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280e\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2810\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2811\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2812\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2813\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2814\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2815\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2816\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2817\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2818\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2819\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281a\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281b\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281c\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281d\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281e\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2820\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2821\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2822\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2823\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2824\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2825\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2826\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2827\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2828\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2829\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282a\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282b\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282c\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282d\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282e\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2830\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2831\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2832\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2833\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2834\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2835\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2836\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2837\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2838\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2839\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283a\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283b\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283c\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283d\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283e\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2840\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2841\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2842\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2843\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2844\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2845\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2846\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2847\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2848\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2849\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u284a\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u284b\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u284c\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u284d\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u284e\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u284f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2850\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2851\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2852\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2853\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2854\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2855\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2856\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2857\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2858\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2859\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u285a\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u285b\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u285c\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u285d\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u285e\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u285f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2860\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2861\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2862\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2863\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2864\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2865\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2866\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2867\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2868\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2869\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u286a\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u286b\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u286c\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u286d\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u286e\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u286f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2870\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2871\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2872\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2873\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2874\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2875\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2876\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2877\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2878\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2879\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u287a\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u287b\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u287c\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u287d\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u287e\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u287f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u2880\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u2881\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u2882\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u2883\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u2884\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u2885\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u2886\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u2887\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u2888\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u2889\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u288a\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u288b\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u288c\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u288d\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u288e\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u288f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u2890\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u2891\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u2892\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u2893\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u2894\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u2895\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u2896\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u2897\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u2898\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u2899\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u289a\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u289b\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u289c\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u289d\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u289e\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u289f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28a0\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28a2\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28a4\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28a5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28a6\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28a7\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28a8\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28a9\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28aa\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28ab\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28ac\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28ad\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28ae\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28af\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28b0\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28b1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28b2\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28b4\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28b6\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28b7\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28b8\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28b9\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28ba\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28bb\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28bc\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28bd\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28be\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000, // u28bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28c0\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28c2\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28c4\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28c6\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28c7\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28c8\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28c9\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28ca\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28cb\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28cc\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28cd\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28ce\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28cf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28d0\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28d2\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28d4\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28d6\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28d7\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28d8\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28d9\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28da\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28db\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28dc\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28dd\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28de\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28df\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28e0\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28e1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28e2\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28e3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28e4\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28e6\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28e7\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28e8\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28e9\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28ea\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28eb\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28ec\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28ed\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28ee\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28ef\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28f0\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28f2\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28f3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28f4\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28f6\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28f7\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28f8\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28f9\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28fa\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28fb\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28fc\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28fd\n  0x0000,0x0100,0x0100,0x0100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28fe\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,0x0000,0x0000,0x2100,0x2100,0x2100,0x0000,\n  0x0000,0x2100,0x2100,0x2100,0x0000,0x0000, // u28ff\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x0000,0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2e2c\n  0x8000,0x8000,0x8200,0x8700,0x8a80,0x9240,0x8200,0x8200,0x8200,0x8200,0x8400,0x0800,0x1000,0x2000,0x4000,0x8000,\n  0x8000,0x8000,0x8000,0x8000,0x8000,0x8000, // ue0a0\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0840,0x0840,0x0c40,0x0a40,\n  0x0940,0x08c0,0x0840,0x0840,0x0000,0x0000, // ue0a1\n  0x0000,0x0000,0x1f00,0x2080,0x2080,0x2080,0x2080,0x2080,0x2080,0x7fc0,0x7fc0,0x7fc0,0x7bc0,0x71c0,0x71c0,0x7bc0,\n  0x7fc0,0x7fc0,0x7fc0,0x0000,0x0000,0x0000, // ue0a2\n  0x8000,0xc000,0xe000,0xf000,0xf800,0xfc00,0xfe00,0xff00,0xff80,0xffc0,0xffe0,0xffe0,0xffc0,0xff80,0xff00,0xfe00,\n  0xfc00,0xf800,0xf000,0xe000,0xc000,0x8000, // ue0b0\n  0x8000,0x4000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,0x0080,0x0040,0x0020,0x0020,0x0040,0x0080,0x0100,0x0200,\n  0x0400,0x0800,0x1000,0x2000,0x4000,0x8000, // ue0b1\n  0x0020,0x0060,0x00e0,0x01e0,0x03e0,0x07e0,0x0fe0,0x1fe0,0x3fe0,0x7fe0,0xffe0,0xffe0,0x7fe0,0x3fe0,0x1fe0,0x0fe0,\n  0x07e0,0x03e0,0x01e0,0x00e0,0x0060,0x0020, // ue0b2\n  0x0020,0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000,0x8000,0x4000,0x2000,0x1000,0x0800,\n  0x0400,0x0200,0x0100,0x0080,0x0040,0x0020, // ue0b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0100,0x2100,0x2100,0x2100,0x1e00,0x0000, // uf6be\n  0x0000,0x0000,0x0000,0x7f80,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000 // ufffd\n  };\n  // codepoints array\n  constexpr std::array<uint16_t, CHARCOUNT> fixedfont_codepoints = {\n  0x0000,0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,\n  0x002f,0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,\n  0x003f,0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,\n  0x004f,0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,\n  0x005f,0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,\n  0x006f,0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,\n  0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af,\n  0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf,\n  0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf,\n  0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df,\n  0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef,\n  0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff,\n  0x0100,0x0101,0x0102,0x0103,0x0104,0x0105,0x0106,0x0107,0x0108,0x0109,0x010a,0x010b,0x010c,0x010d,0x010e,0x010f,\n  0x0110,0x0111,0x0112,0x0113,0x0114,0x0115,0x0116,0x0117,0x0118,0x0119,0x011a,0x011b,0x011c,0x011d,0x011e,0x011f,\n  0x0120,0x0121,0x0122,0x0123,0x0124,0x0125,0x0126,0x0127,0x0128,0x0129,0x012a,0x012b,0x012c,0x012d,0x012e,0x012f,\n  0x0130,0x0131,0x0132,0x0133,0x0134,0x0135,0x0136,0x0137,0x0138,0x0139,0x013a,0x013b,0x013c,0x013d,0x013e,0x013f,\n  0x0140,0x0141,0x0142,0x0143,0x0144,0x0145,0x0146,0x0147,0x0148,0x0149,0x014a,0x014b,0x014c,0x014d,0x014e,0x014f,\n  0x0150,0x0151,0x0152,0x0153,0x0154,0x0155,0x0156,0x0157,0x0158,0x0159,0x015a,0x015b,0x015c,0x015d,0x015e,0x015f,\n  0x0160,0x0161,0x0162,0x0163,0x0164,0x0165,0x0166,0x0167,0x0168,0x0169,0x016a,0x016b,0x016c,0x016d,0x016e,0x016f,\n  0x0170,0x0171,0x0172,0x0173,0x0174,0x0175,0x0176,0x0177,0x0178,0x0179,0x017a,0x017b,0x017c,0x017d,0x017e,0x017f,\n  0x0186,0x018e,0x018f,0x0190,0x0192,0x019d,0x019e,0x01b5,0x01b6,0x01b7,0x01cd,0x01ce,0x01cf,0x01d0,0x01d1,0x01d2,\n  0x01d3,0x01d4,0x01e2,0x01e3,0x01e4,0x01e5,0x01e6,0x01e7,0x01e8,0x01e9,0x01ea,0x01eb,0x01ec,0x01ed,0x01ee,0x01ef,\n  0x01f0,0x01f4,0x01f5,0x01fc,0x01fd,0x01fe,0x01ff,0x0218,0x0219,0x021a,0x021b,0x0232,0x0233,0x0237,0x0254,0x0258,\n  0x0259,0x025b,0x0272,0x0292,0x02bb,0x02bc,0x02bd,0x02c6,0x02c7,0x02d8,0x02d9,0x02db,0x02dc,0x02dd,0x0300,0x0301,\n  0x0302,0x0303,0x0304,0x0305,0x0306,0x0307,0x0308,0x030a,0x030b,0x030c,0x0329,0x0384,0x0385,0x0386,0x0387,0x0388,\n  0x0389,0x038a,0x038c,0x038e,0x038f,0x0390,0x0391,0x0392,0x0393,0x0394,0x0395,0x0396,0x0397,0x0398,0x0399,0x039a,\n  0x039b,0x039c,0x039d,0x039e,0x039f,0x03a0,0x03a1,0x03a3,0x03a4,0x03a5,0x03a6,0x03a7,0x03a8,0x03a9,0x03aa,0x03ab,\n  0x03ac,0x03ad,0x03ae,0x03af,0x03b0,0x03b1,0x03b2,0x03b3,0x03b4,0x03b5,0x03b6,0x03b7,0x03b8,0x03b9,0x03ba,0x03bb,\n  0x03bc,0x03bd,0x03be,0x03bf,0x03c0,0x03c1,0x03c2,0x03c3,0x03c4,0x03c5,0x03c6,0x03c7,0x03c8,0x03c9,0x03ca,0x03cb,\n  0x03cc,0x03cd,0x03ce,0x03d1,0x03d5,0x03f0,0x03f1,0x03f2,0x03f3,0x03f4,0x03f5,0x03f6,0x0400,0x0401,0x0402,0x0403,\n  0x0404,0x0405,0x0406,0x0407,0x0408,0x0409,0x040a,0x040b,0x040c,0x040d,0x040e,0x040f,0x0410,0x0411,0x0412,0x0413,\n  0x0414,0x0415,0x0416,0x0417,0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e,0x041f,0x0420,0x0421,0x0422,0x0423,\n  0x0424,0x0425,0x0426,0x0427,0x0428,0x0429,0x042a,0x042b,0x042c,0x042d,0x042e,0x042f,0x0430,0x0431,0x0432,0x0433,\n  0x0434,0x0435,0x0436,0x0437,0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e,0x043f,0x0440,0x0441,0x0442,0x0443,\n  0x0444,0x0445,0x0446,0x0447,0x0448,0x0449,0x044a,0x044b,0x044c,0x044d,0x044e,0x044f,0x0450,0x0451,0x0452,0x0453,\n  0x0454,0x0455,0x0456,0x0457,0x0458,0x0459,0x045a,0x045b,0x045c,0x045d,0x045e,0x045f,0x0462,0x0463,0x046a,0x046b,\n  0x0490,0x0491,0x0492,0x0493,0x0494,0x0495,0x0496,0x0497,0x0498,0x0499,0x049a,0x049b,0x049c,0x049d,0x04a0,0x04a1,\n  0x04a2,0x04a3,0x04a4,0x04a5,0x04aa,0x04ab,0x04ae,0x04af,0x04b0,0x04b1,0x04b2,0x04b3,0x04b6,0x04b7,0x04b8,0x04b9,\n  0x04ba,0x04bb,0x04c0,0x04c1,0x04c2,0x04cf,0x04d0,0x04d1,0x04d2,0x04d3,0x04d4,0x04d5,0x04d6,0x04d7,0x04d8,0x04d9,\n  0x04da,0x04db,0x04dc,0x04dd,0x04de,0x04df,0x04e2,0x04e3,0x04e4,0x04e5,0x04e6,0x04e7,0x04e8,0x04e9,0x04ea,0x04eb,\n  0x04ec,0x04ed,0x04ee,0x04ef,0x04f0,0x04f1,0x04f2,0x04f3,0x04f4,0x04f5,0x04f8,0x04f9,0x05d0,0x05d1,0x05d2,0x05d3,\n  0x05d4,0x05d5,0x05d6,0x05d7,0x05d8,0x05d9,0x05da,0x05db,0x05dc,0x05dd,0x05de,0x05df,0x05e0,0x05e1,0x05e2,0x05e3,\n  0x05e4,0x05e5,0x05e6,0x05e7,0x05e8,0x05e9,0x05ea,0x1e0c,0x1e0d,0x1e34,0x1e35,0x1e36,0x1e37,0x1e40,0x1e41,0x1e42,\n  0x1e43,0x1e44,0x1e45,0x1e46,0x1e47,0x1e6c,0x1e6d,0x1eb8,0x1eb9,0x1ebc,0x1ebd,0x1eca,0x1ecb,0x1ecc,0x1ecd,0x1ee4,\n  0x1ee5,0x1ef8,0x1ef9,0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007,0x2008,0x2009,0x200a,0x200b,0x200c,\n  0x200d,0x200e,0x200f,0x2010,0x2011,0x2012,0x2013,0x2014,0x2015,0x2016,0x2017,0x2018,0x2019,0x201a,0x201b,0x201c,\n  0x201d,0x201e,0x201f,0x2020,0x2021,0x2022,0x2026,0x2030,0x2032,0x2033,0x2039,0x203a,0x203c,0x203e,0x2070,0x2071,\n  0x2074,0x2075,0x2076,0x2077,0x2078,0x2079,0x207a,0x207b,0x207c,0x207d,0x207e,0x207f,0x2080,0x2081,0x2082,0x2083,\n  0x2084,0x2085,0x2086,0x2087,0x2088,0x2089,0x208a,0x208b,0x208c,0x208d,0x208e,0x2090,0x2091,0x2092,0x2093,0x2094,\n  0x2095,0x2096,0x2097,0x2098,0x209a,0x20a7,0x20aa,0x20ac,0x20ae,0x2102,0x210e,0x210f,0x2115,0x2116,0x211a,0x211d,\n  0x2122,0x2124,0x2126,0x2135,0x2190,0x2191,0x2192,0x2193,0x2194,0x2195,0x21a4,0x21a6,0x21a8,0x21b5,0x21bb,0x21cb,\n  0x21cc,0x21d0,0x21d1,0x21d2,0x21d3,0x21d4,0x21d5,0x2200,0x2203,0x2204,0x2205,0x2206,0x2207,0x2208,0x2209,0x220a,\n  0x220b,0x220c,0x220d,0x2212,0x2213,0x2214,0x2215,0x2216,0x2219,0x221a,0x221e,0x221f,0x2225,0x2227,0x2228,0x2229,\n  0x222a,0x2248,0x2260,0x2261,0x2264,0x2265,0x226a,0x226b,0x2282,0x2283,0x2286,0x2287,0x22a5,0x22c2,0x22c3,0x2300,\n  0x2302,0x2308,0x2309,0x230a,0x230b,0x2310,0x2319,0x2320,0x2321,0x239b,0x239c,0x239d,0x239e,0x239f,0x23a0,0x23a1,\n  0x23a2,0x23a3,0x23a4,0x23a5,0x23a6,0x23a7,0x23a8,0x23a9,0x23ab,0x23ac,0x23ad,0x23ae,0x23af,0x23ba,0x23bb,0x23bc,\n  0x23bd,0x23d0,0x2409,0x240a,0x240b,0x240c,0x240d,0x2424,0x2500,0x2501,0x2502,0x2503,0x2508,0x2509,0x250a,0x250b,\n  0x250c,0x250d,0x250e,0x250f,0x2510,0x2511,0x2512,0x2513,0x2514,0x2515,0x2516,0x2517,0x2518,0x2519,0x251a,0x251b,\n  0x251c,0x251d,0x251e,0x251f,0x2520,0x2521,0x2522,0x2523,0x2524,0x2525,0x2526,0x2527,0x2528,0x2529,0x252a,0x252b,\n  0x252c,0x252d,0x252e,0x252f,0x2530,0x2531,0x2532,0x2533,0x2534,0x2535,0x2536,0x2537,0x2538,0x2539,0x253a,0x253b,\n  0x253c,0x253d,0x253e,0x253f,0x2540,0x2541,0x2542,0x2543,0x2544,0x2545,0x2546,0x2547,0x2548,0x2549,0x254a,0x254b,\n  0x2550,0x2551,0x2552,0x2553,0x2554,0x2555,0x2556,0x2557,0x2558,0x2559,0x255a,0x255b,0x255c,0x255d,0x255e,0x255f,\n  0x2560,0x2561,0x2562,0x2563,0x2564,0x2565,0x2566,0x2567,0x2568,0x2569,0x256a,0x256b,0x256c,0x256d,0x256e,0x256f,\n  0x2570,0x2571,0x2572,0x2573,0x2574,0x2575,0x2576,0x2577,0x2578,0x2579,0x257a,0x257b,0x257c,0x257d,0x257e,0x257f,\n  0x2580,0x2581,0x2582,0x2583,0x2584,0x2585,0x2586,0x2587,0x2588,0x2589,0x258a,0x258b,0x258c,0x258d,0x258e,0x258f,\n  0x2590,0x2591,0x2592,0x2593,0x2596,0x2597,0x2598,0x2599,0x259a,0x259b,0x259c,0x259d,0x259e,0x259f,0x25a0,0x25ac,\n  0x25ae,0x25b2,0x25b6,0x25ba,0x25bc,0x25c0,0x25c4,0x25c6,0x25ca,0x25cb,0x25cf,0x25d8,0x25d9,0x263a,0x263b,0x263c,\n  0x2640,0x2642,0x2660,0x2663,0x2665,0x2666,0x266a,0x266b,0x2713,0x2714,0x2717,0x2718,0x27e8,0x27e9,0x27ea,0x27eb,\n  0x2800,0x2801,0x2802,0x2803,0x2804,0x2805,0x2806,0x2807,0x2808,0x2809,0x280a,0x280b,0x280c,0x280d,0x280e,0x280f,\n  0x2810,0x2811,0x2812,0x2813,0x2814,0x2815,0x2816,0x2817,0x2818,0x2819,0x281a,0x281b,0x281c,0x281d,0x281e,0x281f,\n  0x2820,0x2821,0x2822,0x2823,0x2824,0x2825,0x2826,0x2827,0x2828,0x2829,0x282a,0x282b,0x282c,0x282d,0x282e,0x282f,\n  0x2830,0x2831,0x2832,0x2833,0x2834,0x2835,0x2836,0x2837,0x2838,0x2839,0x283a,0x283b,0x283c,0x283d,0x283e,0x283f,\n  0x2840,0x2841,0x2842,0x2843,0x2844,0x2845,0x2846,0x2847,0x2848,0x2849,0x284a,0x284b,0x284c,0x284d,0x284e,0x284f,\n  0x2850,0x2851,0x2852,0x2853,0x2854,0x2855,0x2856,0x2857,0x2858,0x2859,0x285a,0x285b,0x285c,0x285d,0x285e,0x285f,\n  0x2860,0x2861,0x2862,0x2863,0x2864,0x2865,0x2866,0x2867,0x2868,0x2869,0x286a,0x286b,0x286c,0x286d,0x286e,0x286f,\n  0x2870,0x2871,0x2872,0x2873,0x2874,0x2875,0x2876,0x2877,0x2878,0x2879,0x287a,0x287b,0x287c,0x287d,0x287e,0x287f,\n  0x2880,0x2881,0x2882,0x2883,0x2884,0x2885,0x2886,0x2887,0x2888,0x2889,0x288a,0x288b,0x288c,0x288d,0x288e,0x288f,\n  0x2890,0x2891,0x2892,0x2893,0x2894,0x2895,0x2896,0x2897,0x2898,0x2899,0x289a,0x289b,0x289c,0x289d,0x289e,0x289f,\n  0x28a0,0x28a1,0x28a2,0x28a3,0x28a4,0x28a5,0x28a6,0x28a7,0x28a8,0x28a9,0x28aa,0x28ab,0x28ac,0x28ad,0x28ae,0x28af,\n  0x28b0,0x28b1,0x28b2,0x28b3,0x28b4,0x28b5,0x28b6,0x28b7,0x28b8,0x28b9,0x28ba,0x28bb,0x28bc,0x28bd,0x28be,0x28bf,\n  0x28c0,0x28c1,0x28c2,0x28c3,0x28c4,0x28c5,0x28c6,0x28c7,0x28c8,0x28c9,0x28ca,0x28cb,0x28cc,0x28cd,0x28ce,0x28cf,\n  0x28d0,0x28d1,0x28d2,0x28d3,0x28d4,0x28d5,0x28d6,0x28d7,0x28d8,0x28d9,0x28da,0x28db,0x28dc,0x28dd,0x28de,0x28df,\n  0x28e0,0x28e1,0x28e2,0x28e3,0x28e4,0x28e5,0x28e6,0x28e7,0x28e8,0x28e9,0x28ea,0x28eb,0x28ec,0x28ed,0x28ee,0x28ef,\n  0x28f0,0x28f1,0x28f2,0x28f3,0x28f4,0x28f5,0x28f6,0x28f7,0x28f8,0x28f9,0x28fa,0x28fb,0x28fc,0x28fd,0x28fe,0x28ff,\n  0x2e2c,0xe0a0,0xe0a1,0xe0a2,0xe0b0,0xe0b1,0xe0b2,0xe0b3,0xf6be,0xfffd };\n} // namespace\n// -- end of autogenerated text ---\n\nnamespace fixed_font_22b {\n  // -- start of autogenerated text ---\n  // definition section for font: ter-u22b.bdf\n  constexpr int CHARCOUNT = 1354;\n  constexpr int WIDTH = 11;\n  constexpr int HEIGHT = 22;\n  constexpr int OFFSET_X = 0;\n  constexpr int OFFSET_Y = 0;\n  constexpr FixedFont_info_t fixedfont_info = {\n    \"Terminus\", // font name\n    \"ter-u22b.bdf\", // font name internal\n    CHARCOUNT, // num of chars\n    WIDTH, HEIGHT, OFFSET_X, OFFSET_Y,\n    true // bold\n  };\n  // font bitmap definitions\n  constexpr std::array<uint16_t, CHARCOUNT * HEIGHT> fixedfont_bitmap = {\n  0x0000,0x0000,0x0000,0x7bc0,0x60c0,0x60c0,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x0000,0x0000,0x60c0,0x60c0,\n  0x7bc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0020\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0021\n  0x0000,0x3300,0x3300,0x3300,0x3300,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0022\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x3300,0x3300,0xffc0,0x3300,0x3300,0x3300,0x3300,0xffc0,0x3300,0x3300,0x3300,\n  0x3300,0x0000,0x0000,0x0000,0x0000,0x0000, // u0023\n  0x0000,0x0000,0x0c00,0x0c00,0x3f00,0x6d80,0xccc0,0xcc00,0xcc00,0x6c00,0x3f00,0x0d80,0x0cc0,0x0cc0,0xccc0,0x6d80,\n  0x3f00,0x0c00,0x0c00,0x0000,0x0000,0x0000, // u0024\n  0x0000,0x0000,0x0000,0x7180,0xd980,0xdb00,0x7300,0x0600,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x3380,0x36c0,0x66c0,\n  0x6380,0x0000,0x0000,0x0000,0x0000,0x0000, // u0025\n  0x0000,0x0000,0x0000,0x3e00,0x6300,0x6300,0x6300,0x3600,0x1c00,0x3c00,0x66c0,0xc3c0,0xc180,0xc180,0xc180,0x63c0,\n  0x3ec0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0026\n  0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0027\n  0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0c00,0x0c00,0x0600,\n  0x0300,0x0000,0x0000,0x0000,0x0000,0x0000, // u0028\n  0x0000,0x0000,0x0000,0x1800,0x0c00,0x0600,0x0600,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0600,0x0600,0x0c00,\n  0x1800,0x0000,0x0000,0x0000,0x0000,0x0000, // u0029\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x3300,0x1e00,0x0c00,0xffc0,0x0c00,0x1e00,0x3300,0x6180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x1800,0x0000,0x0000,0x0000,0x0000, // u002c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u002e\n  0x0000,0x0000,0x0000,0x0180,0x0180,0x0300,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x6000,\n  0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002f\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x61c0,0x63c0,0x66c0,0x6cc0,0x78c0,0x70c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0030\n  0x0000,0x0000,0x0000,0x0600,0x0e00,0x1e00,0x3600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0031\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0032\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x00c0,0x00c0,0x0180,0x0f00,0x0180,0x00c0,0x00c0,0x00c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0033\n  0x0000,0x0000,0x0000,0x00c0,0x01c0,0x03c0,0x06c0,0x0cc0,0x18c0,0x30c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x00c0,0x00c0,\n  0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0034\n  0x0000,0x0000,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x7f00,0x0180,0x00c0,0x00c0,0x00c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0035\n  0x0000,0x0000,0x0000,0x1f80,0x3000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0036\n  0x0000,0x0000,0x0000,0x7fc0,0x60c0,0x60c0,0x00c0,0x0180,0x0180,0x0300,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0037\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x3180,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0038\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,0x1fc0,0x00c0,0x00c0,0x00c0,0x0180,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x1800,0x0000,0x0000,0x0000,0x0000, // u003b\n  0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,\n  0x0180,0x0000,0x0000,0x0000,0x0000,0x0000, // u003c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003d\n  0x0000,0x0000,0x0000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,\n  0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003e\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x00c0,0x0180,0x0300,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,\n  0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u003f\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0xc0c0,0xc7c0,0xccc0,0xd8c0,0xd8c0,0xd8c0,0xd8c0,0xccc0,0xc7c0,0xc000,0x6000,\n  0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0040\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0041\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x6180,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,\n  0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0042\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0043\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,\n  0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0044\n  0x0000,0x0000,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0045\n  0x0000,0x0000,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0046\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x6000,0x6000,0x6000,0x67c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0047\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0048\n  0x0000,0x0000,0x0000,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0049\n  0x0000,0x0000,0x0000,0x07e0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x6180,0x6180,0x6180,0x3300,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u004a\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7800,0x6c00,0x6600,0x6300,0x6180,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u004b\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u004c\n  0x0000,0x0000,0x0000,0x8040,0xc0c0,0xe1c0,0xf3c0,0xdec0,0xccc0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,\n  0xc0c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u004d\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x70c0,0x78c0,0x6cc0,0x66c0,0x63c0,0x61c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u004e\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u004f\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0050\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3780,\n  0x1f00,0x0180,0x00c0,0x0000,0x0000,0x0000, // u0051\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,0x7f00,0x7800,0x6c00,0x6600,0x6300,0x6180,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0052\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x6000,0x6000,0x3000,0x1f00,0x0180,0x00c0,0x00c0,0x00c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0053\n  0x0000,0x0000,0x0000,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0054\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0055\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,0x3180,0x3180,0x3180,0x1b00,0x1b00,0x0e00,0x0e00,\n  0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0056\n  0x0000,0x0000,0x0000,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xccc0,0xccc0,0xdec0,0xf3c0,0xe1c0,0xc0c0,\n  0x8040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0057\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x3180,0x3180,0x1b00,0x1b00,0x0e00,0x0e00,0x1b00,0x1b00,0x3180,0x3180,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0058\n  0x0000,0x0000,0x0000,0xc0c0,0xc0c0,0x6180,0x6180,0x3300,0x3300,0x1e00,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0059\n  0x0000,0x0000,0x0000,0x7fc0,0x00c0,0x00c0,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u005a\n  0x0000,0x0000,0x0000,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u005b\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x3000,0x3000,0x1800,0x1800,0x0c00,0x0c00,0x0600,0x0600,0x0300,0x0300,0x0180,\n  0x0180,0x0000,0x0000,0x0000,0x0000,0x0000, // u005c\n  0x0000,0x0000,0x0000,0x1f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u005d\n  0x0000,0x0400,0x0e00,0x1b00,0x3180,0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0000, // u005f\n  0x1800,0x0c00,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0060\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0180,0x00c0,0x00c0,0x3fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0061\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,\n  0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0062\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x6000,0x6000,0x6000,0x6000,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0063\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x00c0,0x1fc0,0x30c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0064\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x7fc0,0x6000,0x6000,0x6000,0x30c0,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0065\n  0x0000,0x0000,0x0000,0x07c0,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0066\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x30c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x00c0,0x00c0,0x0180,0x3f00,0x0000, // u0067\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0068\n  0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0069\n  0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0780,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x3180,0x3180,0x3180,0x1f00,0x0000, // u006a\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x30c0,0x3180,0x3300,0x3600,0x3c00,0x3c00,0x3600,0x3300,0x3180,\n  0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u006b\n  0x0000,0x0000,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u006c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xcd80,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,\n  0xccc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u006d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u006e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u006f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,\n  0x7f00,0x6000,0x6000,0x6000,0x6000,0x0000, // u0070\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x30c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x00c0,0x00c0,0x00c0,0x00c0,0x0000, // u0071\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x67c0,0x6c00,0x7800,0x7000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0072\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x60c0,0x6000,0x6000,0x3f80,0x00c0,0x00c0,0x00c0,0x60c0,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0073\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x07c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0074\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0075\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x3180,0x3180,0x3180,0x1b00,0x1b00,0x0e00,\n  0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0076\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc0c0,0xc0c0,0xc0c0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0077\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x3180,0x1b00,0x0e00,0x0e00,0x1b00,0x3180,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0078\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x00c0,0x00c0,0x0180,0x3f00,0x0000, // u0079\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u007a\n  0x0000,0x0000,0x0000,0x0380,0x0600,0x0c00,0x0c00,0x0c00,0x0c00,0x3800,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0600,\n  0x0380,0x0000,0x0000,0x0000,0x0000,0x0000, // u007b\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u007c\n  0x0000,0x0000,0x0000,0x3800,0x0c00,0x0600,0x0600,0x0600,0x0600,0x0380,0x0600,0x0600,0x0600,0x0600,0x0600,0x0c00,\n  0x3800,0x0000,0x0000,0x0000,0x0000,0x0000, // u007d\n  0x0000,0x38c0,0x6cc0,0x66c0,0x6380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a0\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x3f00,0x6d80,0xccc0,0xcc00,0xcc00,0xcc00,0xcc00,0xccc0,0x6d80,\n  0x3f00,0x0c00,0x0c00,0x0000,0x0000,0x0000, // u00a2\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x3180,0x3000,0x3000,0x3000,0x7e00,0x3000,0x3000,0x3000,0x3000,0x30c0,\n  0x30c0,0x7fc0,0x0000,0x0000,0x0000,0x0000, // u00a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc0c0,0x6180,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x6180,0xc0c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a4\n  0x0000,0x0000,0x0000,0xc0c0,0xc0c0,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x7f80,0x0c00,0x0c00,0x7f80,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a5\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a6\n  0x0000,0x0000,0x1f00,0x3180,0x3000,0x3000,0x1e00,0x3300,0x3180,0x3180,0x3180,0x3180,0x1980,0x0f00,0x0180,0x0180,\n  0x3180,0x1f00,0x0000,0x0000,0x0000,0x0000, // u00a7\n  0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x4080,0x9e40,0xb340,0xb040,0xb040,0xb040,0xb340,0x9e40,0x4080,0x3f00,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a9\n  0x0000,0x3f00,0x0180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x3f80,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0cc0,0x1980,0x3300,0x6600,0xcc00,0xcc00,0x6600,0x3300,0x1980,\n  0x0cc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ab\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x00c0,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ac\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ad\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x4080,0xbe40,0xb340,0xb340,0xbe40,0xbc40,0xb640,0xb340,0x4080,0x3f00,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ae\n  0x0000,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00af\n  0x0000,0x1e00,0x3300,0x3300,0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000,\n  0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b1\n  0x0000,0x1e00,0x3300,0x3300,0x0300,0x0600,0x0c00,0x1800,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b2\n  0x0000,0x1e00,0x3300,0x0300,0x0e00,0x0300,0x0300,0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b3\n  0x0300,0x0600,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x61c0,0x63c0,\n  0x7ec0,0x6000,0x6000,0x6000,0x6000,0x0000, // u00b5\n  0x0000,0x0000,0x0000,0x7fc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0x7cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,\n  0x0cc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0600,0x0600,0x0600,0x0c00,0x0000, // u00b8\n  0x0000,0x0c00,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b9\n  0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3f00,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xcc00,0x6600,0x3300,0x1980,0x0cc0,0x0cc0,0x1980,0x3300,0x6600,\n  0xcc00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00bb\n  0x0000,0x0000,0x3000,0x7000,0xf000,0x3040,0x30c0,0x3180,0x3300,0x0600,0x0cc0,0x19c0,0x33c0,0x66c0,0x4cc0,0x0fc0,\n  0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000, // u00bc\n  0x0000,0x0000,0x3000,0x7000,0xf040,0x30c0,0x3180,0x3300,0x3600,0x0c00,0x1800,0x3780,0x6cc0,0x4cc0,0x0180,0x0300,\n  0x0600,0x0fc0,0x0000,0x0000,0x0000,0x0000, // u00bd\n  0x0000,0x0000,0x7800,0xcc00,0x0c00,0x3840,0x0cc0,0xcd80,0x7b00,0x0600,0x0cc0,0x19c0,0x33c0,0x66c0,0x4cc0,0x0fc0,\n  0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000, // u00be\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0c00,0x0c00,0x1800,0x3000,0x6000,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00bf\n  0x1800,0x0c00,0x0600,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c0\n  0x0300,0x0600,0x0c00,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c1\n  0x0e00,0x1b00,0x3180,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c2\n  0x1cc0,0x36c0,0x3380,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c3\n  0x3180,0x3180,0x3180,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c4\n  0x0e00,0x1b00,0x1b00,0x0e00,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c5\n  0x0000,0x0000,0x0000,0x3fe0,0x6600,0xc600,0xc600,0xc600,0xc600,0xffe0,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,\n  0xc7e0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c6\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0600,0x0600,0x0600,0x0c00,0x0000, // u00c7\n  0x1800,0x0c00,0x0600,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c8\n  0x0300,0x0600,0x0c00,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c9\n  0x0e00,0x1b00,0x3180,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ca\n  0x3180,0x3180,0x3180,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cb\n  0x3000,0x1800,0x0c00,0x0000,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cc\n  0x0300,0x0600,0x0c00,0x0000,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cd\n  0x0e00,0x1b00,0x3180,0x0000,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ce\n  0x3180,0x3180,0x3180,0x0000,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cf\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0xfcc0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,\n  0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d0\n  0x1cc0,0x36c0,0x3380,0x0000,0x60c0,0x60c0,0x60c0,0x70c0,0x78c0,0x6cc0,0x66c0,0x63c0,0x61c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d1\n  0x1800,0x0c00,0x0600,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d2\n  0x0300,0x0600,0x0c00,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d3\n  0x0e00,0x1b00,0x3180,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d4\n  0x1cc0,0x36c0,0x3380,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d5\n  0x3180,0x3180,0x3180,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x3180,0x1b00,0x0e00,0x0e00,0x1b00,0x3180,0x60c0,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d7\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60e0,0x60c0,0x61c0,0x63c0,0x66c0,0x6cc0,0x78c0,0x70c0,0x60c0,0xe0c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d8\n  0x1800,0x0c00,0x0600,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d9\n  0x0300,0x0600,0x0c00,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00da\n  0x0e00,0x1b00,0x3180,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00db\n  0x3180,0x3180,0x3180,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00dc\n  0x0300,0x0600,0x0c00,0xc0c0,0xc0c0,0x6180,0x6180,0x3300,0x3300,0x1e00,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00dd\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,\n  0x7f00,0x6000,0x6000,0x6000,0x6000,0x0000, // u00de\n  0x0000,0x0000,0x0000,0x3e00,0x6300,0x6180,0x6180,0x6180,0x6300,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x7180,\n  0x6f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00df\n  0x0000,0x0000,0x0000,0x1800,0x0c00,0x0600,0x0000,0x3f00,0x0180,0x00c0,0x00c0,0x3fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e0\n  0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x0000,0x3f00,0x0180,0x00c0,0x00c0,0x3fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e1\n  0x0000,0x0000,0x0000,0x0e00,0x1b00,0x3180,0x0000,0x3f00,0x0180,0x00c0,0x00c0,0x3fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e2\n  0x0000,0x0000,0x0000,0x1cc0,0x36c0,0x3380,0x0000,0x3f00,0x0180,0x00c0,0x00c0,0x3fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e3\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x3f00,0x0180,0x00c0,0x00c0,0x3fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e4\n  0x0000,0x0000,0x0000,0x0e00,0x1b00,0x1b00,0x0e00,0x3f00,0x0180,0x00c0,0x00c0,0x3fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7b80,0x0cc0,0x0cc0,0x0cc0,0x7fc0,0xcc00,0xcc00,0xcc00,0xccc0,\n  0x7780,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x6000,0x6000,0x6000,0x6000,0x60c0,0x3180,\n  0x1f00,0x0600,0x0600,0x0600,0x0c00,0x0000, // u00e7\n  0x0000,0x0000,0x0000,0x1800,0x0c00,0x0600,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x7fc0,0x6000,0x6000,0x6000,0x30c0,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e8\n  0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x7fc0,0x6000,0x6000,0x6000,0x30c0,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e9\n  0x0000,0x0000,0x0000,0x0e00,0x1b00,0x3180,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x7fc0,0x6000,0x6000,0x6000,0x30c0,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ea\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x7fc0,0x6000,0x6000,0x6000,0x30c0,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00eb\n  0x0000,0x0000,0x0000,0x1800,0x0c00,0x0600,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ec\n  0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ed\n  0x0000,0x0000,0x0000,0x0e00,0x1b00,0x3180,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ee\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ef\n  0x0000,0x0000,0x0000,0x3600,0x1800,0x6c00,0x0600,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f0\n  0x0000,0x0000,0x0000,0x3980,0x6d80,0x6700,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f1\n  0x0000,0x0000,0x0000,0x1800,0x0c00,0x0600,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f2\n  0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f3\n  0x0000,0x0000,0x0000,0x0e00,0x1b00,0x3180,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f4\n  0x0000,0x0000,0x0000,0x1cc0,0x36c0,0x3380,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f5\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0xffc0,0x0000,0x0000,0x0c00,0x0c00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f60,0x31c0,0x61c0,0x63c0,0x66c0,0x6cc0,0x78c0,0x70c0,0x7180,\n  0xdf00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f8\n  0x0000,0x0000,0x0000,0x1800,0x0c00,0x0600,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f9\n  0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00fa\n  0x0000,0x0000,0x0000,0x0e00,0x1b00,0x3180,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00fb\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00fc\n  0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x00c0,0x00c0,0x0180,0x3f00,0x0000, // u00fd\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,\n  0x7f00,0x6000,0x6000,0x6000,0x6000,0x0000, // u00fe\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x00c0,0x00c0,0x0180,0x3f00,0x0000, // u00ff\n  0x0000,0x3f80,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0100\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x3f00,0x0180,0x00c0,0x00c0,0x3fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0101\n  0x3180,0x3180,0x1f00,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0102\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x1f00,0x0000,0x3f00,0x0180,0x00c0,0x00c0,0x3fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0103\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0180,0x0300,0x0300,0x01e0,0x0000, // u0104\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0180,0x00c0,0x00c0,0x3fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x3fc0,0x0180,0x0300,0x0300,0x01e0,0x0000, // u0105\n  0x0300,0x0600,0x0c00,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x6000,0x6000,0x6000,0x6000,0x6000,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0106\n  0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x0000,0x1f00,0x3180,0x60c0,0x6000,0x6000,0x6000,0x6000,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0107\n  0x0e00,0x1b00,0x3180,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x6000,0x6000,0x6000,0x6000,0x6000,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0108\n  0x0000,0x0000,0x0000,0x0e00,0x1b00,0x3180,0x0000,0x1f00,0x3180,0x60c0,0x6000,0x6000,0x6000,0x6000,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0109\n  0x0c00,0x0c00,0x0c00,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x6000,0x6000,0x6000,0x6000,0x6000,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u010a\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0000,0x1f00,0x3180,0x60c0,0x6000,0x6000,0x6000,0x6000,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u010b\n  0x3180,0x1b00,0x0e00,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x6000,0x6000,0x6000,0x6000,0x6000,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u010c\n  0x0000,0x0000,0x0000,0x3180,0x1b00,0x0e00,0x0000,0x1f00,0x3180,0x60c0,0x6000,0x6000,0x6000,0x6000,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u010d\n  0x3180,0x1b00,0x0e00,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,\n  0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u010e\n  0x3180,0x1b00,0x0e00,0x00c0,0x00c0,0x00c0,0x00c0,0x1fc0,0x30c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u010f\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0xfcc0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,\n  0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0110\n  0x0000,0x0000,0x0000,0x00c0,0x0fe0,0x00c0,0x00c0,0x1fc0,0x30c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0111\n  0x0000,0x3f80,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0112\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x7fc0,0x6000,0x6000,0x6000,0x30c0,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0113\n  0x3180,0x3180,0x1f00,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0114\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x1f00,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x7fc0,0x6000,0x6000,0x6000,0x30c0,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0115\n  0x0c00,0x0c00,0x0c00,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0116\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x7fc0,0x6000,0x6000,0x6000,0x30c0,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0117\n  0x0000,0x0000,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0180,0x0300,0x0300,0x01e0,0x0000, // u0118\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x7fc0,0x6000,0x6000,0x6000,0x30c0,\n  0x1f80,0x0600,0x0c00,0x0c00,0x0780,0x0000, // u0119\n  0x3180,0x1b00,0x0e00,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u011a\n  0x0000,0x0000,0x0000,0x3180,0x1b00,0x0e00,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x7fc0,0x6000,0x6000,0x6000,0x30c0,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u011b\n  0x0e00,0x1b00,0x3180,0x0000,0x1f00,0x3180,0x61c0,0x6000,0x6000,0x6000,0x67c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u011c\n  0x0000,0x0000,0x0000,0x0e00,0x1b00,0x3180,0x0000,0x1fc0,0x30c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x00c0,0x00c0,0x0180,0x3f00,0x0000, // u011d\n  0x3180,0x3180,0x1f00,0x0000,0x1f00,0x3180,0x61c0,0x6000,0x6000,0x6000,0x67c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u011e\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x1f00,0x0000,0x1fc0,0x30c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x00c0,0x00c0,0x0180,0x3f00,0x0000, // u011f\n  0x0c00,0x0c00,0x0c00,0x0000,0x1f00,0x3180,0x61c0,0x6000,0x6000,0x6000,0x67c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0120\n  0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0000,0x1fc0,0x30c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x00c0,0x00c0,0x0180,0x3f00,0x0000, // u0121\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x6000,0x6000,0x6000,0x67c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0600,0x0600,0x0600,0x0c00, // u0122\n  0x0000,0x0000,0x0300,0x0600,0x0600,0x0600,0x0000,0x1fc0,0x30c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x00c0,0x00c0,0x0180,0x3f00,0x0000, // u0123\n  0x0e00,0x1b00,0x3180,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0124\n  0x0700,0x0d80,0x18c0,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0125\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0xffe0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0126\n  0x0000,0x0000,0x0000,0x6000,0xfe00,0x6000,0x6000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0127\n  0x1cc0,0x36c0,0x3380,0x0000,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0128\n  0x0000,0x0000,0x0000,0x1cc0,0x36c0,0x3380,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0129\n  0x0000,0x3f80,0x0000,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u012a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u012b\n  0x3180,0x3180,0x1f00,0x0000,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u012c\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x1f00,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u012d\n  0x0000,0x0000,0x0000,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x3f00,0x0c00,0x1800,0x1800,0x0f00,0x0000, // u012e\n  0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x1f80,0x0600,0x0c00,0x0c00,0x0780,0x0000, // u012f\n  0x0c00,0x0c00,0x0c00,0x0000,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0130\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0131\n  0x0000,0x0000,0x0000,0xf1e0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x6cc0,0x6cc0,0x6cc0,0x6cc0,\n  0xf780,0x0000,0x0000,0x0000,0x0000,0x0000, // u0132\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x0000,0xe1c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0xf0c0,0x0cc0,0x0cc0,0x0cc0,0x0780,0x0000, // u0133\n  0x0380,0x06c0,0x0c60,0x0000,0x07e0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x6180,0x6180,0x6180,0x3300,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0134\n  0x0000,0x0000,0x0000,0x0380,0x06c0,0x0c60,0x0000,0x0780,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x3180,0x3180,0x3180,0x1f00,0x0000, // u0135\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7800,0x6c00,0x6600,0x6300,0x6180,0x60c0,\n  0x60c0,0x0000,0x0600,0x0600,0x0600,0x0c00, // u0136\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x30c0,0x3180,0x3300,0x3600,0x3c00,0x3c00,0x3600,0x3300,0x3180,\n  0x30c0,0x0000,0x0600,0x0600,0x0600,0x0c00, // u0137\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x3180,0x3300,0x3600,0x3c00,0x3c00,0x3600,0x3300,0x3180,\n  0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0138\n  0x1800,0x3000,0x6000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0139\n  0x0180,0x0300,0x0600,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u013a\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0600,0x0600,0x0600,0x0c00, // u013b\n  0x0000,0x0000,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x1f80,0x0000,0x0600,0x0600,0x0600,0x0c00, // u013c\n  0x3180,0x1b00,0x0e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u013d\n  0x3180,0x1b00,0x0e00,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u013e\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6300,0x6300,0x6300,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u013f\n  0x0000,0x0000,0x0000,0x3c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c60,0x0c60,0x0c60,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0140\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3c00,0x3800,0x3000,0x7000,0xf000,0x3000,0x3000,0x3000,0x3000,\n  0x3fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0141\n  0x0000,0x0000,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0780,0x0700,0x0600,0x0e00,0x1e00,0x0600,0x0600,0x0600,0x0600,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0142\n  0x0300,0x0600,0x0c00,0x60c0,0x60c0,0x60c0,0x60c0,0x70c0,0x78c0,0x6cc0,0x66c0,0x63c0,0x61c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0143\n  0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0144\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x70c0,0x78c0,0x6cc0,0x66c0,0x63c0,0x61c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0600,0x0600,0x0600,0x0c00, // u0145\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0600,0x0600,0x0600,0x0c00, // u0146\n  0x3180,0x1b00,0x0e00,0x60c0,0x60c0,0x60c0,0x60c0,0x70c0,0x78c0,0x6cc0,0x66c0,0x63c0,0x61c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0147\n  0x0000,0x0000,0x0000,0x3180,0x1b00,0x0e00,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0148\n  0x0000,0x6000,0x6000,0x6000,0x6000,0xc000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0149\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x70c0,0x78c0,0x6cc0,0x66c0,0x63c0,0x61c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x00c0,0x00c0,0x0180,0x0700,0x0000, // u014a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x00c0,0x00c0,0x0180,0x0700,0x0000, // u014b\n  0x0000,0x3f80,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u014c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u014d\n  0x3180,0x3180,0x1f00,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u014e\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x1f00,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u014f\n  0x0660,0x0cc0,0x1980,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0150\n  0x0000,0x0000,0x0000,0x0660,0x0cc0,0x1980,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0151\n  0x0000,0x0000,0x0000,0x3fe0,0x6600,0xc600,0xc600,0xc600,0xc600,0xc7e0,0xc600,0xc600,0xc600,0xc600,0xc600,0x6600,\n  0x3fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0152\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0xccc0,0xccc0,0xccc0,0xcfc0,0xcc00,0xcc00,0xcc00,0xccc0,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0153\n  0x0300,0x0600,0x0c00,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x6180,0x7f00,0x7800,0x6c00,0x6600,0x6300,0x6180,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0154\n  0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x0000,0x67c0,0x6c00,0x7800,0x7000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0155\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,0x7f00,0x7800,0x6c00,0x6600,0x6300,0x6180,\n  0x60c0,0x0000,0x0600,0x0600,0x0600,0x0c00, // u0156\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x67c0,0x6c00,0x7800,0x7000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x0000,0x6000,0x6000,0x6000,0xc000, // u0157\n  0x3180,0x1b00,0x0e00,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x6180,0x7f00,0x7800,0x6c00,0x6600,0x6300,0x6180,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0158\n  0x0000,0x0000,0x0000,0x3180,0x1b00,0x0e00,0x0000,0x67c0,0x6c00,0x7800,0x7000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0159\n  0x0300,0x0600,0x0c00,0x0000,0x1f00,0x3180,0x60c0,0x6000,0x6000,0x3000,0x1f00,0x0180,0x00c0,0x00c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u015a\n  0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x0000,0x3f80,0x60c0,0x6000,0x6000,0x3f80,0x00c0,0x00c0,0x00c0,0x60c0,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u015b\n  0x0e00,0x1b00,0x3180,0x0000,0x1f00,0x3180,0x60c0,0x6000,0x6000,0x3000,0x1f00,0x0180,0x00c0,0x00c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u015c\n  0x0000,0x0000,0x0000,0x0e00,0x1b00,0x3180,0x0000,0x3f80,0x60c0,0x6000,0x6000,0x3f80,0x00c0,0x00c0,0x00c0,0x60c0,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u015d\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x6000,0x6000,0x3000,0x1f00,0x0180,0x00c0,0x00c0,0x00c0,0x60c0,0x3180,\n  0x1f00,0x0600,0x0600,0x0600,0x0c00,0x0000, // u015e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x60c0,0x6000,0x6000,0x3f80,0x00c0,0x00c0,0x00c0,0x60c0,\n  0x3f80,0x0600,0x0600,0x0600,0x0c00,0x0000, // u015f\n  0x3180,0x1b00,0x0e00,0x0000,0x1f00,0x3180,0x60c0,0x6000,0x6000,0x3000,0x1f00,0x0180,0x00c0,0x00c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0160\n  0x0000,0x0000,0x0000,0x3180,0x1b00,0x0e00,0x0000,0x3f80,0x60c0,0x6000,0x6000,0x3f80,0x00c0,0x00c0,0x00c0,0x60c0,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0161\n  0x0000,0x0000,0x0000,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0600,0x0600,0x0600,0x0c00,0x0000, // u0162\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x07c0,0x0300,0x0300,0x0300,0x0600,0x0000, // u0163\n  0x3180,0x1b00,0x0e00,0x0000,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0164\n  0x3300,0x1e00,0x0c00,0x0000,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x07c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0165\n  0x0000,0x0000,0x0000,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0166\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x07c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0167\n  0x1cc0,0x36c0,0x3380,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0168\n  0x0000,0x0000,0x0000,0x1cc0,0x36c0,0x3380,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0169\n  0x0000,0x3f80,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u016a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u016b\n  0x3180,0x3180,0x1f00,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u016c\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x1f00,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u016d\n  0x0e00,0x1b00,0x1b00,0x0e00,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u016e\n  0x0000,0x0000,0x0000,0x0e00,0x1b00,0x1b00,0x0e00,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u016f\n  0x0660,0x0cc0,0x1980,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0170\n  0x0000,0x0000,0x0000,0x0660,0x0cc0,0x1980,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0171\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0600,0x0c00,0x0c00,0x0780,0x0000, // u0172\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x0180,0x0300,0x0300,0x01e0,0x0000, // u0173\n  0x0e00,0x1b00,0x3180,0x0000,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xccc0,0xdec0,0xf3c0,0xe1c0,0xc0c0,\n  0x8040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0174\n  0x0000,0x0000,0x0000,0x0e00,0x1b00,0x3180,0x0000,0xc0c0,0xc0c0,0xc0c0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0175\n  0x0e00,0x1b00,0x3180,0x0000,0xc0c0,0xc0c0,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0176\n  0x0000,0x0000,0x0000,0x0e00,0x1b00,0x3180,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x00c0,0x00c0,0x0180,0x3f00,0x0000, // u0177\n  0x3180,0x3180,0x3180,0x0000,0xc0c0,0xc0c0,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0178\n  0x0300,0x0600,0x0c00,0x0000,0x7fc0,0x00c0,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0179\n  0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x0000,0x7fc0,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u017a\n  0x0c00,0x0c00,0x0c00,0x0000,0x7fc0,0x00c0,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u017b\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0000,0x7fc0,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u017c\n  0x3180,0x1b00,0x0e00,0x0000,0x7fc0,0x00c0,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u017d\n  0x0000,0x0000,0x0000,0x3180,0x1b00,0x0e00,0x0000,0x7fc0,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u017e\n  0x0000,0x0000,0x0000,0x07c0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u017f\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0186\n  0x0000,0x0000,0x0000,0x7fc0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x1fc0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u018e\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x00c0,0x00c0,0x00c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u018f\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x6000,0x6000,0x3000,0x1e00,0x3000,0x6000,0x6000,0x6000,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0190\n  0x0000,0x0000,0x0000,0x0780,0x0cc0,0x0cc0,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0xcc00,0xcc00,0x7800,0x0000, // u0192\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x70c0,0x78c0,0x6cc0,0x66c0,0x63c0,0x61c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x6000,0x6000,0x6000,0xc000,0x0000, // u019d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x00c0,0x00c0,0x00c0,0x00c0,0x0000, // u019e\n  0x0000,0x0000,0x0000,0x7fc0,0x00c0,0x00c0,0x0180,0x0300,0x0600,0x7fc0,0x0c00,0x1800,0x3000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0180,0x0300,0x0600,0x7fc0,0x0c00,0x1800,0x3000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01b6\n  0x0000,0x0000,0x0000,0x7fc0,0x00c0,0x0180,0x0300,0x0600,0x0f00,0x0180,0x00c0,0x00c0,0x00c0,0x00c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01b7\n  0x3180,0x1b00,0x0e00,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01cd\n  0x0000,0x0000,0x0000,0x3180,0x1b00,0x0e00,0x0000,0x3f00,0x0180,0x00c0,0x00c0,0x3fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01ce\n  0x3180,0x1b00,0x0e00,0x0000,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01cf\n  0x0000,0x0000,0x0000,0x3180,0x1b00,0x0e00,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d0\n  0x3180,0x1b00,0x0e00,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d1\n  0x0000,0x0000,0x0000,0x3180,0x1b00,0x0e00,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d2\n  0x3180,0x1b00,0x0e00,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d3\n  0x0000,0x0000,0x0000,0x3180,0x1b00,0x0e00,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d4\n  0x0000,0x3fc0,0x0000,0x3fe0,0x6600,0xc600,0xc600,0xc600,0xc600,0xffe0,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,\n  0xc7e0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x7b80,0x0cc0,0x0cc0,0x0cc0,0x7fc0,0xcc00,0xcc00,0xcc00,0xccc0,\n  0x7780,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e3\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x6000,0x6000,0x6000,0x67c0,0x60c0,0x60c0,0x67e0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x30c0,0x60c0,0x60c0,0x67e0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x00c0,0x00c0,0x0180,0x3f00,0x0000, // u01e5\n  0x3180,0x1b00,0x0e00,0x0000,0x1f00,0x3180,0x61c0,0x6000,0x6000,0x6000,0x67c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e6\n  0x0000,0x0000,0x0000,0x3180,0x1b00,0x0e00,0x0000,0x1fc0,0x30c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x00c0,0x00c0,0x0180,0x3f00,0x0000, // u01e7\n  0x3180,0x1b00,0x0e00,0x60c0,0x60c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7800,0x6c00,0x6600,0x6300,0x6180,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e8\n  0x18c0,0x0d80,0x0700,0x3000,0x3000,0x3000,0x3000,0x30c0,0x3180,0x3300,0x3600,0x3c00,0x3c00,0x3600,0x3300,0x3180,\n  0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e9\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0600,0x0c00,0x0c00,0x0780,0x0000, // u01ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0600,0x0c00,0x0c00,0x0780,0x0000, // u01eb\n  0x0000,0x3f80,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0600,0x0c00,0x0c00,0x0780,0x0000, // u01ec\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0600,0x0c00,0x0c00,0x0780,0x0000, // u01ed\n  0x3180,0x1b00,0x0e00,0x0000,0x7fc0,0x00c0,0x0180,0x0300,0x0600,0x0f00,0x0180,0x00c0,0x00c0,0x00c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01ee\n  0x0000,0x0000,0x0000,0x3180,0x1b00,0x0e00,0x0000,0x7fc0,0x00c0,0x0180,0x0300,0x0600,0x0f00,0x0180,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x60c0,0x3180,0x1f00,0x0000, // u01ef\n  0x0000,0x0000,0x0000,0x0c60,0x06c0,0x0380,0x0000,0x0780,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x3180,0x3180,0x3180,0x1f00,0x0000, // u01f0\n  0x0300,0x0600,0x0c00,0x0000,0x1f00,0x3180,0x61c0,0x6000,0x6000,0x6000,0x67c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01f4\n  0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x1fc0,0x30c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x00c0,0x00c0,0x0180,0x3f00,0x0000, // u01f5\n  0x0180,0x0300,0x0600,0x0000,0x3fe0,0x6600,0xc600,0xc600,0xc600,0xc600,0xffe0,0xc600,0xc600,0xc600,0xc600,0xc600,\n  0xc7e0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01fc\n  0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x0000,0x7b80,0x0cc0,0x0cc0,0x0cc0,0x7fc0,0xcc00,0xcc00,0xcc00,0xccc0,\n  0x7780,0x0000,0x0000,0x0000,0x0000,0x0000, // u01fd\n  0x0300,0x0600,0x0c00,0x0000,0x1f00,0x3180,0x60e0,0x61c0,0x63c0,0x66c0,0x6cc0,0x78c0,0x70c0,0x60c0,0xe0c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01fe\n  0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x0000,0x1f60,0x31c0,0x61c0,0x63c0,0x66c0,0x6cc0,0x78c0,0x70c0,0x7180,\n  0xdf00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01ff\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x6000,0x6000,0x3000,0x1f00,0x0180,0x00c0,0x00c0,0x00c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0600,0x0600,0x0600,0x0c00, // u0218\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x60c0,0x6000,0x6000,0x3f80,0x00c0,0x00c0,0x00c0,0x60c0,\n  0x3f80,0x0000,0x0600,0x0600,0x0600,0x0c00, // u0219\n  0x0000,0x0000,0x0000,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0c00,0x0c00,0x0c00,0x1800, // u021a\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x07c0,0x0000,0x0300,0x0300,0x0300,0x0600, // u021b\n  0x0000,0x3f80,0x0000,0xc0c0,0xc0c0,0x6180,0x6180,0x3300,0x3300,0x1e00,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0232\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x00c0,0x00c0,0x0180,0x3f00,0x0000, // u0233\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0780,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x3180,0x3180,0x3180,0x1f00,0x0000, // u0237\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x00c0,0x00c0,0x00c0,0x00c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0254\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x7fc0,0x00c0,0x00c0,0x00c0,0x6180,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0258\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x00c0,0x00c0,0x00c0,0x7fc0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0259\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x60c0,0x6000,0x6000,0x3e00,0x6000,0x6000,0x6000,0x60c0,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u025b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x6000,0x6000,0x6000,0xc000,0x0000, // u0272\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x00c0,0x0180,0x0300,0x0600,0x0f00,0x0180,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x60c0,0x3180,0x1f00,0x0000, // u0292\n  0x0600,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bb\n  0x0c00,0x0c00,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bc\n  0x0c00,0x0c00,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bd\n  0x0e00,0x1b00,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02c6\n  0x3180,0x1b00,0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02c7\n  0x3180,0x3180,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02d8\n  0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02d9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0600,0x0c00,0x0c00,0x0780,0x0000, // u02db\n  0x1cc0,0x36c0,0x3380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02dc\n  0x0660,0x0cc0,0x1980,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02dd\n  0x1800,0x0c00,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0300\n  0x0300,0x0600,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0301\n  0x0e00,0x1b00,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0302\n  0x1cc0,0x36c0,0x3380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0303\n  0x0000,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0304\n  0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0305\n  0x3180,0x3180,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0306\n  0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0307\n  0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0308\n  0x0e00,0x1b00,0x1b00,0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030a\n  0x0660,0x0cc0,0x1980,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030b\n  0x3180,0x1b00,0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0000, // u0329\n  0x3000,0x6000,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0384\n  0x0300,0x0600,0x0c00,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0385\n  0x3000,0x6000,0xc000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0386\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0387\n  0x3000,0x6000,0xc000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0388\n  0x3000,0x6000,0xc000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0389\n  0x3000,0x6000,0xc000,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u038a\n  0x3000,0x6000,0xc000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u038c\n  0x3000,0x6000,0xc000,0x0000,0xc0c0,0xc0c0,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u038e\n  0x3000,0x6000,0xc000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,0x1b00,0x1b00,\n  0x7bc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u038f\n  0x0300,0x0600,0x0c00,0x6300,0x6300,0x6300,0x0000,0x3c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0780,0x0000,0x0000,0x0000,0x0000,0x0000, // u0390\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0391\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x6180,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,\n  0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0392\n  0x0000,0x0000,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0393\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x1e00,0x1e00,0x3300,0x3300,0x3300,0x6180,0x6180,0x6180,0xc0c0,0xc0c0,\n  0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0394\n  0x0000,0x0000,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0395\n  0x0000,0x0000,0x0000,0x7fc0,0x00c0,0x00c0,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0396\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0397\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x6ec0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0398\n  0x0000,0x0000,0x0000,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0399\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7800,0x6c00,0x6600,0x6300,0x6180,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u039a\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x1e00,0x1e00,0x3300,0x3300,0x3300,0x6180,0x6180,0x6180,0xc0c0,0xc0c0,\n  0xc0c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u039b\n  0x0000,0x0000,0x0000,0x8040,0xc0c0,0xe1c0,0xf3c0,0xdec0,0xccc0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,\n  0xc0c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u039c\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x70c0,0x78c0,0x6cc0,0x66c0,0x63c0,0x61c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u039d\n  0x0000,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u039e\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u039f\n  0x0000,0x0000,0x0000,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a0\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a1\n  0x0000,0x0000,0x0000,0x7fc0,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a3\n  0x0000,0x0000,0x0000,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a4\n  0x0000,0x0000,0x0000,0xc0c0,0xc0c0,0x6180,0x6180,0x3300,0x3300,0x1e00,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a5\n  0x0000,0x0000,0x0000,0x0c00,0x3f00,0x6d80,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0x6d80,0x3f00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a6\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x3180,0x3180,0x1b00,0x1b00,0x0e00,0x0e00,0x1b00,0x1b00,0x3180,0x3180,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a7\n  0x0000,0x0000,0x0000,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0x6d80,0x3f00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a8\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,0x1b00,0x1b00,\n  0x7bc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a9\n  0x3180,0x3180,0x3180,0x0000,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03aa\n  0x3180,0x3180,0x3180,0x0000,0xc0c0,0xc0c0,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ab\n  0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x0000,0x3cc0,0x6780,0xc300,0xc300,0xc300,0xc300,0xc300,0xc300,0x6780,\n  0x3cc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ac\n  0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x0000,0x3f80,0x60c0,0x6000,0x6000,0x3e00,0x6000,0x6000,0x6000,0x60c0,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ad\n  0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x00c0,0x00c0,0x00c0,0x00c0,0x0000, // u03ae\n  0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x0000,0x3c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0780,0x0000,0x0000,0x0000,0x0000,0x0000, // u03af\n  0x0300,0x0600,0x0c00,0x3180,0x3180,0x3180,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3cc0,0x6780,0xc300,0xc300,0xc300,0xc300,0xc300,0xc300,0x6780,\n  0x3cc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b1\n  0x0000,0x0000,0x0000,0x3e00,0x6300,0x6180,0x6180,0x6180,0x6300,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,\n  0x7f00,0x6000,0x6000,0x6000,0x6000,0x0000, // u03b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc0c0,0xc0c0,0xc0c0,0x6180,0x6180,0x3300,0x3300,0x1e00,0x1e00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000, // u03b3\n  0x0000,0x0000,0x0000,0x3f80,0x1800,0x0c00,0x0600,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x60c0,0x6000,0x6000,0x3e00,0x6000,0x6000,0x6000,0x60c0,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b5\n  0x0000,0x0000,0x0000,0x7fc0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x3000,0x6000,0x6000,0x6000,0x6000,0x3000,\n  0x1f80,0x00c0,0x00c0,0x00c0,0x0380,0x0000, // u03b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x00c0,0x00c0,0x00c0,0x00c0,0x0000, // u03b7\n  0x0000,0x0000,0x0000,0x1e00,0x3300,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0780,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x3180,0x3300,0x3600,0x3c00,0x3c00,0x3600,0x3300,0x3180,\n  0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ba\n  0x0000,0x0000,0x0000,0x1800,0x1800,0x0c00,0x0c00,0x0e00,0x0e00,0x1b00,0x1b00,0x3180,0x3180,0x3180,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x61c0,0x63c0,\n  0x7ec0,0x6000,0x6000,0x6000,0x6000,0x0000, // u03bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x3180,0x3180,0x3180,0x1b00,0x1b00,0x0e00,\n  0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03bd\n  0x0000,0x0000,0x0000,0x1fc0,0x3000,0x6000,0x6000,0x6000,0x3000,0x1f80,0x3000,0x6000,0x6000,0x6000,0x6000,0x3000,\n  0x1f80,0x00c0,0x00c0,0x00c0,0x0380,0x0000, // u03be\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,\n  0x7f00,0x6000,0x6000,0x6000,0x6000,0x0000, // u03c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x6000,0x6000,0x6000,0x6000,0x6000,0x3000,\n  0x1f80,0x00c0,0x00c0,0x00c0,0x0380,0x0000, // u03c2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fe0,0x3300,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0780,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6780,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0x6d80,\n  0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000, // u03c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x3180,0x3180,0x1b00,0x1b00,0x0e00,0x0e00,0x1b00,\n  0x1b00,0x3180,0x3180,0x60c0,0x60c0,0x0000, // u03c7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0x6d80,\n  0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000, // u03c8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0xc0c0,0xc0c0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xdec0,\n  0x7380,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c9\n  0x0000,0x0000,0x0000,0x6300,0x6300,0x6300,0x0000,0x3c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0780,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ca\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03cb\n  0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03cc\n  0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03cd\n  0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x0000,0x6180,0xc0c0,0xc0c0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xdec0,\n  0x7380,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ce\n  0x0000,0x0000,0x0000,0x0f00,0x1980,0x30c0,0x30c0,0x30c0,0x18c0,0x0fe0,0x00c0,0x70c0,0x30c0,0x30c0,0x30c0,0x1980,\n  0x0f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x3f00,0x6d80,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0x6d80,\n  0x3f00,0x0c00,0x0c00,0x0000,0x0000,0x0000, // u03d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf0c0,0x1980,0x0b00,0x0e00,0x0c00,0x0c00,0x1c00,0x3400,0x6600,\n  0xc3c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,\n  0x7f00,0x6000,0x6000,0x3000,0x1f80,0x0000, // u03f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x6000,0x6000,0x6000,0x6000,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f2\n  0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0780,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x3180,0x3180,0x3180,0x1f00,0x0000, // u03f3\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3000,0x6000,0x6000,0x7f00,0x6000,0x6000,0x6000,0x3000,\n  0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0180,0x00c0,0x00c0,0x1fc0,0x00c0,0x00c0,0x00c0,0x0180,\n  0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f6\n  0x1800,0x0c00,0x0600,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0400\n  0x3180,0x3180,0x3180,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0401\n  0x0000,0x0000,0x0000,0xfc00,0x3000,0x3000,0x3000,0x3f00,0x3180,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,0x3180,\n  0x3300,0x0000,0x0000,0x0000,0x0000,0x0000, // u0402\n  0x0300,0x0600,0x0c00,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0403\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0404\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x6000,0x6000,0x3000,0x1f00,0x0180,0x00c0,0x00c0,0x00c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0405\n  0x0000,0x0000,0x0000,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0406\n  0x3180,0x3180,0x3180,0x0000,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0407\n  0x0000,0x0000,0x0000,0x07e0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x6180,0x6180,0x6180,0x3300,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0408\n  0x0000,0x0000,0x0000,0x3c00,0x6c00,0xcc00,0xcc00,0xcc00,0xcf80,0xccc0,0xcc60,0xcc60,0xcc60,0xcc60,0xcc60,0xccc0,\n  0xcf80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0409\n  0x0000,0x0000,0x0000,0xcc00,0xcc00,0xcc00,0xcc00,0xcc00,0xcf80,0xfcc0,0xcc60,0xcc60,0xcc60,0xcc60,0xcc60,0xccc0,\n  0xcf80,0x0000,0x0000,0x0000,0x0000,0x0000, // u040a\n  0x0000,0x0000,0x0000,0xfc00,0x3000,0x3000,0x3000,0x3f00,0x3180,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,\n  0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u040b\n  0x0300,0x0600,0x0c00,0x60c0,0x60c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7800,0x6c00,0x6600,0x6300,0x6180,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u040c\n  0x1800,0x0c00,0x0600,0x60c0,0x60c0,0x60c0,0x60c0,0x61c0,0x63c0,0x66c0,0x6cc0,0x78c0,0x70c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u040d\n  0x3180,0x3180,0x1f00,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,0x1fc0,0x00c0,0x00c0,0x00c0,0x00c0,0x0180,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u040e\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x7fc0,0x0e00,0x0e00,0x0e00,0x0000,0x0000, // u040f\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0410\n  0x0000,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,\n  0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0411\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x6180,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,\n  0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0412\n  0x0000,0x0000,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0413\n  0x0000,0x0000,0x0000,0x0fc0,0x18c0,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,0x60c0,\n  0xffe0,0xc060,0xc060,0x0000,0x0000,0x0000, // u0414\n  0x0000,0x0000,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0415\n  0x0000,0x0000,0x0000,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0x6d80,0x3f00,0x3f00,0x6d80,0xccc0,0xccc0,0xccc0,0xccc0,\n  0xccc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0416\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x00c0,0x00c0,0x0180,0x0f00,0x0180,0x00c0,0x00c0,0x00c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0417\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x61c0,0x63c0,0x66c0,0x6cc0,0x78c0,0x70c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0418\n  0x3180,0x3180,0x1f00,0x60c0,0x60c0,0x60c0,0x60c0,0x61c0,0x63c0,0x66c0,0x6cc0,0x78c0,0x70c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0419\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7800,0x6c00,0x6600,0x6300,0x6180,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u041a\n  0x0000,0x0000,0x0000,0x0fc0,0x18c0,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,0x60c0,\n  0xc0c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u041b\n  0x0000,0x0000,0x0000,0x8040,0xc0c0,0xe1c0,0xf3c0,0xdec0,0xccc0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,\n  0xc0c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u041c\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u041d\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u041e\n  0x0000,0x0000,0x0000,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u041f\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0420\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0421\n  0x0000,0x0000,0x0000,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0422\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,0x1fc0,0x00c0,0x00c0,0x00c0,0x00c0,0x0180,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0423\n  0x0000,0x0000,0x0c00,0x3f00,0x6d80,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0x6d80,\n  0x3f00,0x0c00,0x0000,0x0000,0x0000,0x0000, // u0424\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x3180,0x3180,0x1b00,0x1b00,0x0e00,0x0e00,0x1b00,0x1b00,0x3180,0x3180,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0425\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fe0,0x0060,0x0060,0x0060,0x0000,0x0000, // u0426\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,0x1fc0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0427\n  0x0000,0x0000,0x0000,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0x6cc0,\n  0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0428\n  0x0000,0x0000,0x0000,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0x6cc0,\n  0x3fe0,0x0060,0x0060,0x0060,0x0000,0x0000, // u0429\n  0x0000,0x0000,0x0000,0xe000,0xe000,0x6000,0x6000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,\n  0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u042a\n  0x0000,0x0000,0x0000,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xf8c0,0xccc0,0xc6c0,0xc6c0,0xc6c0,0xc6c0,0xc6c0,0xc6c0,0xccc0,\n  0xf8c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u042b\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,\n  0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u042c\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x00c0,0x00c0,0x00c0,0x0fc0,0x00c0,0x00c0,0x00c0,0x00c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u042d\n  0x0000,0x0000,0x0000,0xc780,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xfcc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,\n  0xc780,0x0000,0x0000,0x0000,0x0000,0x0000, // u042e\n  0x0000,0x0000,0x0000,0x1fc0,0x30c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,0x1fc0,0x03c0,0x06c0,0x0cc0,0x18c0,0x30c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u042f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0180,0x00c0,0x00c0,0x3fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0430\n  0x0000,0x0000,0x0000,0x1f80,0x3000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,\n  0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0431\n  0x0000,0x0000,0x0000,0x3e00,0x6300,0x6180,0x6180,0x6180,0x6300,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,\n  0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0432\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0433\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x30c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x00c0,0x00c0,0x0180,0x3f00,0x0000, // u0434\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x7fc0,0x6000,0x6000,0x6000,0x30c0,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0435\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xccc0,0xccc0,0xccc0,0x6d80,0x3f00,0x3f00,0x6d80,0xccc0,0xccc0,\n  0xccc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0436\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x60c0,0x00c0,0x00c0,0x0f80,0x00c0,0x00c0,0x00c0,0x60c0,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0437\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0438\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x1f00,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0439\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x3180,0x3300,0x3600,0x3c00,0x3c00,0x3600,0x3300,0x3180,\n  0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u043a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x18c0,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u043b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x8040,0xc0c0,0xe1c0,0xf3c0,0xdec0,0xccc0,0xc0c0,0xc0c0,0xc0c0,\n  0xc0c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u043c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u043d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u043e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u043f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,\n  0x7f00,0x6000,0x6000,0x6000,0x6000,0x0000, // u0440\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x6000,0x6000,0x6000,0x6000,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0441\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0442\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x00c0,0x00c0,0x0180,0x3f00,0x0000, // u0443\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x3f00,0x6d80,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0x6d80,\n  0x3f00,0x0c00,0x0c00,0x0000,0x0000,0x0000, // u0444\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x3180,0x1b00,0x0e00,0x0e00,0x1b00,0x3180,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0445\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fe0,0x0060,0x0060,0x0060,0x0000,0x0000, // u0446\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,0x1fc0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0447\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0x6cc0,\n  0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0448\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0x6cc0,\n  0x3fe0,0x0060,0x0060,0x0060,0x0000,0x0000, // u0449\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x7000,0x3000,0x3f00,0x3180,0x30c0,0x30c0,0x30c0,0x3180,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u044a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc0c0,0xc0c0,0xc0c0,0xf8c0,0xccc0,0xc6c0,0xc6c0,0xc6c0,0xccc0,\n  0xf8c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u044b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3f00,0x3180,0x30c0,0x30c0,0x30c0,0x3180,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u044c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x00c0,0x0fc0,0x00c0,0x00c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u044d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc780,0xccc0,0xccc0,0xccc0,0xfcc0,0xccc0,0xccc0,0xccc0,0xccc0,\n  0xc780,0x0000,0x0000,0x0000,0x0000,0x0000, // u044e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x3fc0,0x06c0,0x0cc0,0x18c0,\n  0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u044f\n  0x0000,0x0000,0x0000,0x1800,0x0c00,0x0600,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x7fc0,0x6000,0x6000,0x6000,0x30c0,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0450\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x7fc0,0x6000,0x6000,0x6000,0x30c0,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0451\n  0x0000,0x0000,0x0000,0x6000,0xfe00,0x6000,0x6000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x00c0,0x00c0,0x0180,0x0700,0x0000, // u0452\n  0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0453\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x6000,0x7e00,0x6000,0x6000,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0454\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x60c0,0x6000,0x6000,0x3f80,0x00c0,0x00c0,0x00c0,0x60c0,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0455\n  0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0456\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0457\n  0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0780,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x3180,0x3180,0x3180,0x1f00,0x0000, // u0458\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x6c00,0xcc00,0xcf80,0xccc0,0xcc60,0xcc60,0xcc60,0xccc0,\n  0xcf80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0459\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xcc00,0xcc00,0xcc00,0xcf80,0xfcc0,0xcc60,0xcc60,0xcc60,0xccc0,\n  0xcf80,0x0000,0x0000,0x0000,0x0000,0x0000, // u045a\n  0x0000,0x0000,0x0000,0x6000,0xfe00,0x6000,0x6000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u045b\n  0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x30c0,0x3180,0x3300,0x3600,0x3c00,0x3c00,0x3600,0x3300,0x3180,\n  0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u045c\n  0x0000,0x0000,0x0000,0x1800,0x0c00,0x0600,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u045d\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x1f00,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x00c0,0x00c0,0x0180,0x3f00,0x0000, // u045e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x7fc0,0x0e00,0x0e00,0x0e00,0x0000,0x0000, // u045f\n  0x0000,0x0000,0x0000,0x6000,0x6000,0xfe00,0x6000,0x6000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,\n  0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0462\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0xfe00,0x3000,0x3000,0x3000,0x3f00,0x3180,0x30c0,0x30c0,0x30c0,0x3180,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0463\n  0x0000,0x0000,0x0000,0xffc0,0xc0c0,0x6180,0x6180,0x3300,0x3300,0x1e00,0x3f00,0x6d80,0xccc0,0xccc0,0xccc0,0xccc0,\n  0xccc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u046a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xc0c0,0x6180,0x3300,0x1e00,0x3f00,0x6d80,0xccc0,0xccc0,\n  0xccc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u046b\n  0x00c0,0x00c0,0x00c0,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0490\n  0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0491\n  0x0000,0x0000,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0xfe00,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0492\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0xfe00,0x6000,0x6000,0x6000,\n  0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0493\n  0x0000,0x0000,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x00c0,0x0180,0x0300,0x0000,0x0000, // u0494\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6300,0x6180,0x6180,\n  0x6180,0x0180,0x0300,0x0600,0x0000,0x0000, // u0495\n  0x0000,0x0000,0x0000,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0x6d80,0x3f00,0x3f00,0x6d80,0xccc0,0xccc0,0xccc0,0xccc0,\n  0xcce0,0x0060,0x0060,0x0060,0x0000,0x0000, // u0496\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xccc0,0xccc0,0xccc0,0x6d80,0x3f00,0x3f00,0x6d80,0xccc0,0xccc0,\n  0xcce0,0x0060,0x0060,0x0060,0x0000,0x0000, // u0497\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x00c0,0x00c0,0x0180,0x0f00,0x0180,0x00c0,0x00c0,0x00c0,0x60c0,0x3180,\n  0x1f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000, // u0498\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x60c0,0x00c0,0x00c0,0x0f80,0x00c0,0x00c0,0x00c0,0x60c0,\n  0x3f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0000, // u0499\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7800,0x6c00,0x6600,0x6300,0x6180,0x60c0,\n  0x60e0,0x0060,0x0060,0x0060,0x0000,0x0000, // u049a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x3180,0x3300,0x3600,0x3c00,0x3c00,0x3600,0x3300,0x3180,\n  0x30e0,0x0060,0x0060,0x0060,0x0000,0x0000, // u049b\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x6180,0x6b00,0x6e00,0x6c00,0x7800,0x7800,0x6c00,0x6e00,0x6b00,0x6180,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u049c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x3580,0x3700,0x3600,0x3c00,0x3c00,0x3600,0x3700,0x3580,\n  0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u049d\n  0x0000,0x0000,0x0000,0xe0c0,0xe0c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7800,0x6c00,0x6600,0x6300,0x6180,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x70c0,0x7180,0x3300,0x3600,0x3c00,0x3c00,0x3600,0x3300,0x3180,\n  0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a1\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60e0,0x0060,0x0060,0x0060,0x0000,0x0000, // u04a2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60e0,0x0060,0x0060,0x0060,0x0000,0x0000, // u04a3\n  0x0000,0x0000,0x0000,0x63e0,0x6300,0x6300,0x6300,0x6300,0x6300,0x7f00,0x6300,0x6300,0x6300,0x6300,0x6300,0x6300,\n  0x6300,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x63e0,0x6300,0x6300,0x6300,0x7f00,0x6300,0x6300,0x6300,0x6300,\n  0x6300,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a5\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000, // u04aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x6000,0x6000,0x6000,0x6000,0x60c0,0x3180,\n  0x1f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000, // u04ab\n  0x0000,0x0000,0x0000,0xc0c0,0xc0c0,0x6180,0x6180,0x3300,0x3300,0x1e00,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc0c0,0xc0c0,0xc0c0,0x6180,0x6180,0x3300,0x3300,0x1e00,0x1e00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000, // u04af\n  0x0000,0x0000,0x0000,0xc0c0,0xc0c0,0x6180,0x6180,0x3300,0x3300,0x1e00,0x1e00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc0c0,0xc0c0,0xc0c0,0x6180,0x6180,0x3300,0x3300,0x1e00,0x1e00,\n  0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0000, // u04b1\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x3180,0x3180,0x1b00,0x1b00,0x0e00,0x0e00,0x1b00,0x1b00,0x3180,0x3180,0x60c0,\n  0x60e0,0x0060,0x0060,0x0060,0x0000,0x0000, // u04b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x3180,0x1b00,0x0e00,0x0e00,0x1b00,0x3180,0x60c0,\n  0x60e0,0x0060,0x0060,0x0060,0x0000,0x0000, // u04b3\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,0x1fc0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00e0,0x0060,0x0060,0x0060,0x0000,0x0000, // u04b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,0x1fc0,0x00c0,0x00c0,0x00c0,\n  0x00e0,0x0060,0x0060,0x0060,0x0000,0x0000, // u04b7\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x66c0,0x66c0,0x36c0,0x1fc0,0x06c0,0x06c0,0x06c0,0x00c0,0x00c0,\n  0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x66c0,0x66c0,0x36c0,0x1fc0,0x06c0,0x06c0,0x00c0,\n  0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04b9\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04bb\n  0x0000,0x0000,0x0000,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04c0\n  0x3180,0x3180,0x1f00,0x0000,0xccc0,0xccc0,0xccc0,0xccc0,0x6d80,0x3f00,0x3f00,0x6d80,0xccc0,0xccc0,0xccc0,0xccc0,\n  0xccc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04c1\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x1f00,0x0000,0xccc0,0xccc0,0xccc0,0x6d80,0x3f00,0x3f00,0x6d80,0xccc0,0xccc0,\n  0xccc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04c2\n  0x0000,0x0000,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04cf\n  0x3180,0x3180,0x1f00,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d0\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x1f00,0x0000,0x3f00,0x0180,0x00c0,0x00c0,0x3fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d1\n  0x3180,0x3180,0x3180,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d2\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x3f00,0x0180,0x00c0,0x00c0,0x3fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d3\n  0x0000,0x0000,0x0000,0x3fe0,0x6600,0xc600,0xc600,0xc600,0xc600,0xffe0,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,\n  0xc7e0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7b80,0x0cc0,0x0cc0,0x0cc0,0x7fc0,0xcc00,0xcc00,0xcc00,0xccc0,\n  0x7780,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d5\n  0x3180,0x3180,0x1f00,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d6\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x1f00,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x7fc0,0x6000,0x6000,0x6000,0x30c0,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d7\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x00c0,0x00c0,0x00c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x00c0,0x00c0,0x00c0,0x7fc0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d9\n  0x3180,0x3180,0x3180,0x0000,0x1f00,0x3180,0x60c0,0x00c0,0x00c0,0x00c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04da\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x3f00,0x6180,0x00c0,0x00c0,0x00c0,0x7fc0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04db\n  0x3180,0x3180,0x3180,0x0000,0xccc0,0xccc0,0xccc0,0xccc0,0x6d80,0x3f00,0x3f00,0x6d80,0xccc0,0xccc0,0xccc0,0xccc0,\n  0xccc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04dc\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0xccc0,0xccc0,0xccc0,0x6d80,0x3f00,0x3f00,0x6d80,0xccc0,0xccc0,\n  0xccc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04dd\n  0x3180,0x3180,0x3180,0x0000,0x1f00,0x3180,0x60c0,0x00c0,0x00c0,0x0180,0x0f00,0x0180,0x00c0,0x00c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04de\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x3f80,0x60c0,0x00c0,0x00c0,0x0f80,0x00c0,0x00c0,0x00c0,0x60c0,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04df\n  0x0000,0x3f80,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x61c0,0x63c0,0x66c0,0x6cc0,0x78c0,0x70c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e3\n  0x3180,0x3180,0x3180,0x0000,0x60c0,0x60c0,0x60c0,0x61c0,0x63c0,0x66c0,0x6cc0,0x78c0,0x70c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e4\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e5\n  0x3180,0x3180,0x3180,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e6\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e7\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e9\n  0x3180,0x3180,0x3180,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ea\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04eb\n  0x3180,0x3180,0x3180,0x0000,0x1f00,0x3180,0x60c0,0x00c0,0x00c0,0x00c0,0x0fc0,0x00c0,0x00c0,0x00c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ec\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x1f00,0x3180,0x60c0,0x00c0,0x0fc0,0x00c0,0x00c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ed\n  0x0000,0x3f80,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,0x1fc0,0x00c0,0x00c0,0x00c0,0x00c0,0x0180,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ee\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x00c0,0x00c0,0x0180,0x3f00,0x0000, // u04ef\n  0x3180,0x3180,0x3180,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,0x1fc0,0x00c0,0x00c0,0x00c0,0x0180,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f0\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x00c0,0x00c0,0x0180,0x3f00,0x0000, // u04f1\n  0x0660,0x0cc0,0x1980,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,0x1fc0,0x00c0,0x00c0,0x00c0,0x0180,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f2\n  0x0000,0x0000,0x0000,0x0660,0x0cc0,0x1980,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x00c0,0x00c0,0x0180,0x3f00,0x0000, // u04f3\n  0x3180,0x3180,0x3180,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,0x1fc0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f4\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,0x1fc0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f5\n  0x6300,0x6300,0x6300,0x0000,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xf8c0,0xccc0,0xc6c0,0xc6c0,0xc6c0,0xc6c0,0xc6c0,0xccc0,\n  0xf8c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f8\n  0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0xc0c0,0xc0c0,0xc0c0,0xf8c0,0xccc0,0xc6c0,0xc6c0,0xc6c0,0xccc0,\n  0xf8c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f9\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x30c0,0x30c0,0x18c0,0x18c0,0x3d80,0x6f00,0xc600,0xc600,0xc300,0xc300,0xc180,\n  0xc180,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d0\n  0x0000,0x0000,0x0000,0xfe00,0x0300,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0xffe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d1\n  0x0000,0x0000,0x0000,0x7c00,0x0600,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0700,0x0f00,0x1980,0x3180,0x60c0,\n  0xc0c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d2\n  0x0000,0x0000,0x0000,0xffe0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d3\n  0x0000,0x0000,0x0000,0x7f00,0x0180,0x00c0,0x00c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d4\n  0x0000,0x0000,0x0000,0x3800,0x0c00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d5\n  0x0000,0x0000,0x0000,0x7f80,0x0300,0x0600,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d6\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d7\n  0x0000,0x0000,0x0000,0x6700,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d8\n  0x0000,0x0000,0x0000,0x3800,0x0c00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d9\n  0x0000,0x0000,0x0000,0x7f00,0x0180,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x0000, // u05da\n  0x0000,0x0000,0x0000,0x7f00,0x0180,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x0180,\n  0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u05db\n  0x6000,0x6000,0x6000,0x7fc0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x1800,0x1800,\n  0x1800,0x0000,0x0000,0x0000,0x0000,0x0000, // u05dc\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u05dd\n  0x0000,0x0000,0x0000,0xdf00,0xf180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x63c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u05de\n  0x0000,0x0000,0x0000,0x7c00,0x0600,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0000, // u05df\n  0x0000,0x0000,0x0000,0x3e00,0x0300,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e0\n  0x0000,0x0000,0x0000,0xff00,0xc180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e1\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x30c0,0x30c0,0x30c0,0x18c0,0x1980,0x0d80,0x0d80,0x0700,0x0e00,0x1c00,\n  0x7000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e2\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x30c0,0x1cc0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x0000, // u05e3\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x30c0,0x1cc0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x0180,\n  0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e4\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x30c0,0x30c0,0x1980,0x1b00,0x0e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000, // u05e5\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x30c0,0x30c0,0x1980,0x1b00,0x0e00,0x0c00,0x0600,0x0600,0x0300,0x0300,0x0180,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e6\n  0x0000,0x0000,0x0000,0x7fc0,0x00c0,0x00c0,0x00c0,0x60c0,0x60c0,0x6180,0x6300,0x6600,0x6600,0x6600,0x6600,0x6600,\n  0x6600,0x6000,0x6000,0x6000,0x6000,0x0000, // u05e7\n  0x0000,0x0000,0x0000,0x7f00,0x0180,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e8\n  0x0000,0x0000,0x0000,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6c60,0x7860,0x6060,0x6060,0x6060,0x60c0,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e9\n  0x0000,0x0000,0x0000,0xff00,0xc180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0xe0c0,\n  0xc0c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u05ea\n  0x0000,0x0000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,\n  0x7f00,0x0000,0x0c00,0x0c00,0x0c00,0x0000, // u1e0c\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x00c0,0x1fc0,0x30c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x0000,0x0600,0x0600,0x0600,0x0000, // u1e0d\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7800,0x6c00,0x6600,0x6300,0x6180,0x60c0,\n  0x60c0,0x0000,0x3f80,0x0000,0x0000,0x0000, // u1e34\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x30c0,0x3180,0x3300,0x3600,0x3c00,0x3c00,0x3600,0x3300,0x3180,\n  0x30c0,0x0000,0x1f80,0x0000,0x0000,0x0000, // u1e35\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0c00,0x0c00,0x0c00,0x0000, // u1e36\n  0x0000,0x0000,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x1f80,0x0000,0x0c00,0x0c00,0x0c00,0x0000, // u1e37\n  0x0c00,0x0c00,0x0c00,0x8040,0xc0c0,0xe1c0,0xf3c0,0xdec0,0xccc0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,\n  0xc0c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e40\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0000,0xff00,0xcd80,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,\n  0xccc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e41\n  0x0000,0x0000,0x0000,0x8040,0xc0c0,0xe1c0,0xf3c0,0xdec0,0xccc0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,\n  0xc0c0,0x0000,0x0c00,0x0c00,0x0c00,0x0000, // u1e42\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xcd80,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,\n  0xccc0,0x0000,0x0c00,0x0c00,0x0c00,0x0000, // u1e43\n  0x0c00,0x0c00,0x0c00,0x60c0,0x60c0,0x60c0,0x60c0,0x70c0,0x78c0,0x6cc0,0x66c0,0x63c0,0x61c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e44\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e45\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x70c0,0x78c0,0x6cc0,0x66c0,0x63c0,0x61c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0c00,0x0c00,0x0c00,0x0000, // u1e46\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0c00,0x0c00,0x0c00,0x0000, // u1e47\n  0x0000,0x0000,0x0000,0xffc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0c00,0x0c00,0x0c00,0x0000, // u1e6c\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x07c0,0x0000,0x0300,0x0300,0x0300,0x0000, // u1e6d\n  0x0000,0x0000,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0c00,0x0c00,0x0c00,0x0000, // u1eb8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x7fc0,0x6000,0x6000,0x6000,0x30c0,\n  0x1f80,0x0000,0x0c00,0x0c00,0x0c00,0x0000, // u1eb9\n  0x1cc0,0x36c0,0x3380,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u1ebc\n  0x0000,0x0000,0x0000,0x1cc0,0x36c0,0x3380,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x7fc0,0x6000,0x6000,0x6000,0x30c0,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u1ebd\n  0x0000,0x0000,0x0000,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x3f00,0x0000,0x0c00,0x0c00,0x0c00,0x0000, // u1eca\n  0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x1f80,0x0000,0x0600,0x0600,0x0600,0x0000, // u1ecb\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0c00,0x0c00,0x0c00,0x0000, // u1ecc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0c00,0x0c00,0x0c00,0x0000, // u1ecd\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0c00,0x0c00,0x0c00,0x0000, // u1ee4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x0000,0x0600,0x0600,0x0600,0x0000, // u1ee5\n  0x3980,0x6d80,0x6700,0x0000,0xc0c0,0xc0c0,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u1ef8\n  0x0000,0x0000,0x0000,0x1cc0,0x36c0,0x3380,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x30c0,\n  0x1fc0,0x00c0,0x00c0,0x0180,0x3f00,0x0000, // u1ef9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2001\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2002\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2003\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2004\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2005\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2006\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2007\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2008\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2009\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2010\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2011\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2012\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2013\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2014\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2015\n  0x0000,0x0000,0x0000,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,\n  0x1b00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2016\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x7fc0,0x0000,0x0000,0x7fc0, // u2017\n  0x0000,0x0300,0x0600,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2018\n  0x0000,0x0600,0x0600,0x0600,0x0600,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2019\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x1800,0x0000,0x0000,0x0000,0x0000, // u201a\n  0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201b\n  0x0000,0x0cc0,0x1980,0x1980,0x1980,0x1980,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201c\n  0x0000,0x1980,0x1980,0x1980,0x1980,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,\n  0x1980,0x3300,0x0000,0x0000,0x0000,0x0000, // u201e\n  0x0000,0x3300,0x3300,0x3300,0x3300,0x1980,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201f\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2020\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2021\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x1f00,0x1f00,0x1f00,0x0e00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2022\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xccc0,0xccc0,\n  0xccc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2026\n  0x0000,0x0000,0x0000,0x7300,0xdb00,0xde00,0x7600,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x7dc0,0x7760,0xf760,\n  0xddc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2030\n  0x0000,0x0600,0x0600,0x0600,0x0600,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2032\n  0x0000,0x1980,0x1980,0x1980,0x1980,0x1100,0x1100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2033\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x1800,0x3000,0x3000,0x1800,0x0c00,0x0600,\n  0x0300,0x0000,0x0000,0x0000,0x0000,0x0000, // u2039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0300,0x0600,0x0c00,0x1800,\n  0x3000,0x0000,0x0000,0x0000,0x0000,0x0000, // u203a\n  0x0000,0x0000,0x0000,0x3300,0x3300,0x3300,0x3300,0x3300,0x3300,0x3300,0x3300,0x3300,0x0000,0x0000,0x3300,0x3300,\n  0x3300,0x0000,0x0000,0x0000,0x0000,0x0000, // u203c\n  0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u203e\n  0x0000,0x1e00,0x3300,0x3300,0x3300,0x3300,0x3300,0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2070\n  0x0c00,0x0c00,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2071\n  0x0000,0x0300,0x0700,0x0f00,0x1b00,0x3300,0x3f00,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2074\n  0x0000,0x3f00,0x3000,0x3000,0x3e00,0x0300,0x0300,0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2075\n  0x0000,0x1e00,0x3000,0x3000,0x3e00,0x3300,0x3300,0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2076\n  0x0000,0x3f00,0x0300,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2077\n  0x0000,0x1e00,0x3300,0x3300,0x1e00,0x3300,0x3300,0x3300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2078\n  0x0000,0x1e00,0x3300,0x3300,0x3300,0x1f00,0x0300,0x0300,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2079\n  0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207b\n  0x0000,0x0000,0x0000,0x3f80,0x0000,0x0000,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207c\n  0x0000,0x0600,0x0c00,0x1800,0x1800,0x1800,0x1800,0x0c00,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207d\n  0x0000,0x1800,0x0c00,0x0600,0x0600,0x0600,0x0600,0x0c00,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207e\n  0x0000,0x0000,0x3f00,0x3180,0x3180,0x3180,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x3300,0x3300,0x3300,\n  0x3300,0x3300,0x1e00,0x0000,0x0000,0x0000, // u2080\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x1c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x1e00,0x0000,0x0000,0x0000, // u2081\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x3300,0x0300,0x0600,\n  0x0c00,0x1800,0x3f00,0x0000,0x0000,0x0000, // u2082\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x0300,0x0e00,0x0300,\n  0x0300,0x3300,0x1e00,0x0000,0x0000,0x0000, // u2083\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0700,0x0f00,0x1b00,0x3300,\n  0x3f00,0x0300,0x0300,0x0000,0x0000,0x0000, // u2084\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x3000,0x3000,0x3e00,0x0300,\n  0x0300,0x3300,0x1e00,0x0000,0x0000,0x0000, // u2085\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3000,0x3000,0x3e00,0x3300,\n  0x3300,0x3300,0x1e00,0x0000,0x0000,0x0000, // u2086\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0300,0x0300,0x0600,0x0600,\n  0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000, // u2087\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x3300,0x1e00,0x3300,\n  0x3300,0x3300,0x1e00,0x0000,0x0000,0x0000, // u2088\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x3300,0x3300,0x1f00,\n  0x0300,0x0300,0x1e00,0x0000,0x0000,0x0000, // u2089\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x7f80,\n  0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000, // u208a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u208b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x0000,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u208c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0c00,0x1800,0x1800,0x1800,\n  0x1800,0x0c00,0x0600,0x0000,0x0000,0x0000, // u208d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x0c00,0x0600,0x0600,0x0600,\n  0x0600,0x0c00,0x1800,0x0000,0x0000,0x0000, // u208e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x0180,0x1f80,0x3180,\n  0x3180,0x3180,0x1f80,0x0000,0x0000,0x0000, // u2090\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x3180,0x3f80,\n  0x3000,0x3000,0x1f00,0x0000,0x0000,0x0000, // u2091\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x3180,0x3180,\n  0x3180,0x3180,0x1f00,0x0000,0x0000,0x0000, // u2092\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x1b00,0x0e00,\n  0x1b00,0x3180,0x3180,0x0000,0x0000,0x0000, // u2093\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x0180,0x0180,0x3f80,\n  0x3180,0x3180,0x1f00,0x0000,0x0000,0x0000, // u2094\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3f00,0x3180,0x3180,0x3180,\n  0x3180,0x3180,0x3180,0x0000,0x0000,0x0000, // u2095\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3180,0x3300,0x3600,0x3c00,\n  0x3600,0x3300,0x3180,0x0000,0x0000,0x0000, // u2096\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x1e00,0x0000,0x0000,0x0000, // u2097\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x6d80,0x6d80,0x6d80,\n  0x6d80,0x6d80,0x6d80,0x0000,0x0000,0x0000, // u2098\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x3180,0x3180,0x3180,\n  0x3180,0x3180,0x3f00,0x3000,0x3000,0x3000, // u209a\n  0x0000,0x0000,0x0000,0xf800,0xcc00,0xc600,0xc600,0xc600,0xc600,0xcc00,0xfb00,0xc300,0xcfc0,0xc300,0xc300,0xc300,\n  0xc1c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u20a7\n  0x0000,0x0000,0x0000,0xf840,0x8440,0x8240,0x8240,0x9240,0x9240,0x9240,0x9240,0x9240,0x9240,0x9040,0x9040,0x9080,\n  0x9f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u20aa\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x6000,0x6000,0xfe00,0x6000,0x6000,0xfe00,0x6000,0x6000,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u20ac\n  0x0000,0x0000,0x0000,0xffc0,0x0c00,0x0c00,0x0c00,0x0f80,0x0e00,0x1c00,0x7f80,0x0e00,0x1c00,0x7c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u20ae\n  0x0000,0x0000,0x0000,0x1e00,0x3100,0x5080,0x5080,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5080,0x5080,0x3100,\n  0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2102\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u210e\n  0x0000,0x0000,0x0000,0x6000,0xfe00,0x6000,0x6000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u210f\n  0x0000,0x0000,0x0000,0x4080,0x4080,0x4080,0x6080,0x5080,0x6880,0x5480,0x4a80,0x4580,0x4280,0x4180,0x4080,0x4080,\n  0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u2115\n  0x0000,0x0000,0x0000,0xcc00,0xccc0,0xcd20,0xcd20,0xecc0,0xec00,0xfc00,0xfc00,0xdc00,0xdde0,0xcc00,0xcde0,0xcc00,\n  0xcc00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2116\n  0x0000,0x0000,0x0000,0x1e00,0x3100,0x5080,0x5080,0x5080,0x5080,0x5080,0x5080,0x5080,0x5080,0x5080,0x5480,0x3300,\n  0x1f00,0x0080,0x0040,0x0000,0x0000,0x0000, // u211a\n  0x0000,0x0000,0x0000,0x7e00,0x5100,0x5080,0x5080,0x5080,0x5080,0x5100,0x5e00,0x5400,0x5a00,0x5500,0x5280,0x5140,\n  0x70c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u211d\n  0x0000,0x0000,0x0000,0xfe20,0x3360,0x33e0,0x3360,0x3360,0x3360,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2122\n  0x0000,0x0000,0x0000,0x7f80,0x0080,0x0080,0x0180,0x0280,0x0500,0x0a00,0x1400,0x2800,0x5000,0x6000,0x4000,0x4000,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u2124\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,0x1b00,0x1b00,\n  0x7bc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2126\n  0x0000,0x0000,0x0000,0x6300,0x6300,0x3180,0x3180,0x18c0,0x1860,0x3cc0,0x6d80,0xc700,0xc600,0xc300,0xc300,0x6180,\n  0x3180,0x0000,0x0000,0x0000,0x0000,0x0000, // u2135\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x3000,0x6000,0xffc0,0xffc0,0x6000,0x3000,0x1000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2190\n  0x0000,0x0000,0x0000,0x0c00,0x1e00,0x3f00,0x6d80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2191\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0200,0x0300,0x0180,0xffc0,0xffc0,0x0180,0x0300,0x0200,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2192\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x6d80,0x3f00,0x1e00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2193\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1100,0x3180,0x60c0,0xffe0,0xffe0,0x60c0,0x3180,0x1100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2194\n  0x0000,0x0000,0x0000,0x0c00,0x1e00,0x3f00,0x6d80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x6d80,0x3f00,0x1e00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2195\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x10c0,0x30c0,0x60c0,0xffc0,0xffc0,0x60c0,0x30c0,0x10c0,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc200,0xc300,0xc180,0xffc0,0xffc0,0xc180,0xc300,0xc200,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a6\n  0x0000,0x0000,0x0000,0x0c00,0x1e00,0x3f00,0x6d80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x6d80,0x3f00,0x1e00,0x0c00,\n  0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a8\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x10c0,0x30c0,0x60c0,0xffc0,0xffc0,0x6000,0x3000,\n  0x1000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0x3800,0x6880,0xc8c0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0x6180,0x3f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x3000,0x6000,0xffc0,0xffc0,0x0000,0xffc0,0xffc0,0x0180,0x0300,0x0200,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0200,0x0300,0x0180,0xffc0,0xffc0,0x0000,0xffc0,0xffc0,0x6000,0x3000,0x1000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21cc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x1800,0x3fc0,0x7fc0,0xe000,0x7fc0,0x3fc0,0x1800,0x0800,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d0\n  0x0000,0x0000,0x0000,0x0400,0x0e00,0x1f00,0x3b80,0x7bc0,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,\n  0x1b00,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0600,0xff00,0xff80,0x01c0,0xff80,0xff00,0x0600,0x0400,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d2\n  0x0000,0x0000,0x0000,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x7bc0,0x3b80,0x1f00,0x0e00,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1100,0x3180,0x7fc0,0xffe0,0xe0e0,0xffe0,0x7fc0,0x3180,0x1100,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d4\n  0x0000,0x0000,0x0000,0x0400,0x0e00,0x1f00,0x3b80,0x7bc0,0x1b00,0x1b00,0x1b00,0x1b00,0x7bc0,0x3b80,0x1f00,0x0e00,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d5\n  0x0000,0x0000,0x0000,0xc0c0,0xc0c0,0xc0c0,0x6180,0x7f80,0x6180,0x3300,0x3300,0x3300,0x1200,0x1e00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2200\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x7fc0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2203\n  0x0000,0x0000,0x00c0,0x00c0,0x7fc0,0x01c0,0x03c0,0x03c0,0x06c0,0x06c0,0x7fc0,0x0cc0,0x0cc0,0x18c0,0x18c0,0x30c0,\n  0x7fc0,0x6000,0x6000,0x0000,0x0000,0x0000, // u2204\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x0180,0x1f00,0x3380,0x66c0,0x66c0,0x6cc0,0x6cc0,0x3980,0x1f00,0x3000,\n  0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2205\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x1e00,0x1e00,0x3300,0x3300,0x3300,0x6180,0x6180,0x6180,0xc0c0,0xc0c0,\n  0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2206\n  0x0000,0x0000,0x0000,0xffc0,0xc0c0,0xc0c0,0x6180,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x1e00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2207\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x1800,0x3000,0x6000,0x6000,0x6000,0x7fc0,0x6000,0x6000,0x6000,0x3000,0x1800,\n  0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2208\n  0x0000,0x0000,0x00c0,0x00c0,0x0fc0,0x1980,0x3180,0x6300,0x6300,0x6600,0x7fc0,0x6600,0x6c00,0x6c00,0x3800,0x1800,\n  0x3fc0,0x3000,0x3000,0x0000,0x0000,0x0000, // u2209\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3000,0x6000,0x6000,0x7fc0,0x6000,0x6000,0x3000,0x1fc0,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u220a\n  0x0000,0x0000,0x0000,0x0000,0x7e00,0x0300,0x0180,0x00c0,0x00c0,0x00c0,0x7fc0,0x00c0,0x00c0,0x00c0,0x0180,0x0300,\n  0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u220b\n  0x0000,0x0000,0x6000,0x6000,0x7e00,0x3300,0x3180,0x18c0,0x18c0,0x0cc0,0x7fc0,0x0cc0,0x06c0,0x06c0,0x0380,0x0300,\n  0x7f80,0x0180,0x0180,0x0000,0x0000,0x0000, // u220c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0180,0x00c0,0x00c0,0x7fc0,0x00c0,0x00c0,0x0180,0x7f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u220d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2212\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2213\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0xffc0,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2214\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2215\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x00c0,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2216\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x1e00,0x1e00,0x0c00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2219\n  0x0000,0x01c0,0x01c0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x6180,0x6180,0x6180,0x3180,0x1980,0x0d80,0x0780,\n  0x0380,0x0000,0x0000,0x0000,0x0000,0x0000, // u221a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0xccc0,0xccc0,0xccc0,0xccc0,0xccc0,0x7f80,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u221e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u221f\n  0x0000,0x0000,0x0000,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,\n  0x1b00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2225\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x1e00,0x1e00,0x3300,0x3300,0x6180,0x6180,0xc0c0,\n  0xc0c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2227\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc0c0,0xc0c0,0x6180,0x6180,0x3300,0x3300,0x1e00,0x1e00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2228\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2229\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u222a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x38c0,0x6ec0,0x6380,0x0000,0x38c0,0x6ec0,0x6380,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2248\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x7fc0,0x0300,0x0600,0x0c00,0x1800,0x7fc0,0x6000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2260\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x7fc0,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2261\n  0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x0000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2264\n  0x0000,0x0000,0x0000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x0000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2265\n  0x0000,0x0000,0x0000,0x0000,0x0660,0x0cc0,0x1980,0x3300,0x6600,0xcc00,0xcc00,0x6600,0x3300,0x1980,0x0cc0,0x0660,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u226a\n  0x0000,0x0000,0x0000,0x0000,0xcc00,0x6600,0x3300,0x1980,0x0cc0,0x0660,0x0660,0x0cc0,0x1980,0x3300,0x6600,0xcc00,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u226b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3000,0x6000,0xc000,0xc000,0xc000,0xc000,0x6000,0x3000,0x1fc0,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2282\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0300,0x0180,0x00c0,0x00c0,0x00c0,0x00c0,0x0180,0x0300,0xfe00,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2283\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3000,0x6000,0xc000,0xc000,0xc000,0xc000,0x6000,0x3000,0x1fc0,0x0000,0x0000,\n  0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2286\n  0x0000,0x0000,0x0000,0x0000,0xfe00,0x0300,0x0180,0x00c0,0x00c0,0x00c0,0x00c0,0x0180,0x0300,0xfe00,0x0000,0x0000,\n  0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2287\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u22a5\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u22c2\n  0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u22c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x0180,0x1f00,0x3380,0x66c0,0x66c0,0x6cc0,0x6cc0,0x3980,0x1f00,0x3000,\n  0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2300\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x1e00,0x3300,0x6180,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,\n  0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2302\n  0x0000,0x0000,0x0000,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,\n  0x1800,0x0000,0x0000,0x0000,0x0000,0x0000, // u2308\n  0x0000,0x0000,0x0000,0x1f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0000,0x0000,0x0000,0x0000,0x0000, // u2309\n  0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u230a\n  0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u230b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2310\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2319\n  0x0000,0x0000,0x0000,0x0780,0x0cc0,0x0cc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2320\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xcc00,0xcc00,\n  0x7800,0x0000,0x0000,0x0000,0x0000,0x0000, // u2321\n  0x0180,0x0300,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x1800,0x3000,0x3000,0x3000,0x3000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000, // u239b\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000, // u239c\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x3000,0x3000,0x3000,0x3000,0x1800,0x1800,\n  0x1800,0x0c00,0x0c00,0x0600,0x0300,0x0180, // u239d\n  0x6000,0x3000,0x1800,0x0c00,0x0c00,0x0600,0x0600,0x0600,0x0300,0x0300,0x0300,0x0300,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u239e\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u239f\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0300,0x0300,0x0300,0x0300,0x0600,0x0600,\n  0x0600,0x0c00,0x0c00,0x1800,0x3000,0x6000, // u23a0\n  0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000, // u23a1\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000, // u23a2\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80, // u23a3\n  0x7f80,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u23a4\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u23a5\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x7f80, // u23a6\n  0x03c0,0x0e00,0x0c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u23a7\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x3000,0xe000,0xe000,0x3000,0x1800,0x1800,0x1800,\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u23a8\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,\n  0x1800,0x1800,0x1800,0x0c00,0x0e00,0x03c0, // u23a9\n  0xf000,0x1c00,0x0c00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u23ab\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0300,0x01c0,0x01c0,0x0300,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u23ac\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0c00,0x1c00,0xf000, // u23ad\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u23ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23af\n  0xffe0,0xffe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,\n  0xffe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u23bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0, // u23bd\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u23d0\n  0x0000,0x0000,0x6600,0x6600,0x6600,0x7e00,0x6600,0x6600,0x6600,0x0000,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0000,0x0000,0x0000,0x0000,0x0000, // u2409\n  0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7e00,0x0000,0x0fc0,0x0c00,0x0c00,0x0f00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u240a\n  0x0000,0x0000,0xcc00,0xcc00,0xcc00,0xcc00,0xcc00,0x7800,0x3000,0x0000,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u240b\n  0x0000,0x0000,0x7e00,0x6000,0x6000,0x7800,0x6000,0x6000,0x6000,0x0000,0x0fc0,0x0c00,0x0c00,0x0f00,0x0c00,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u240c\n  0x0000,0x0000,0x3c00,0x6600,0x6000,0x6000,0x6000,0x6600,0x3c00,0x0000,0x0f80,0x0cc0,0x0cc0,0x0f80,0x0f00,0x0d80,\n  0x0cc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u240d\n  0x0000,0x0000,0x6600,0x6600,0x7600,0x7e00,0x6e00,0x6600,0x6600,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2424\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2500\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,0xffe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2501\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2502\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u2503\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xd6c0,0xd6c0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2508\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xd6c0,0xd6c0,0xd6c0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2509\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000, // u250a\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0000,0x0e00,0x0e00,0x0e00,0x0e00,0x0000,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0000,0x0e00,0x0e00,0x0e00,0x0e00,0x0000, // u250b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x0fe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u250c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x0fe0,0x0fe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u250d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x0fe0,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u250e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x0fe0,0x0fe0,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u250f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2510\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2511\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xfe00,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u2512\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xfe00,0xfe00,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u2513\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2514\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fe0,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2515\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2516\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0fe0,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2517\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2518\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2519\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0xfe00,0xfe00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u251a\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0xfe00,0xfe00,0xfe00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u251b\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fe0,0x0fe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u251c\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fe0,0x0fe0,0x0fe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u251d\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0fe0,0x0fe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u251e\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fe0,0x0fe0,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u251f\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0fe0,0x0fe0,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u2520\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0fe0,0x0fe0,0x0fe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2521\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fe0,0x0fe0,0x0fe0,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u2522\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0fe0,0x0fe0,0x0fe0,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u2523\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2524\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2525\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0xfe00,0xfe00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2526\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfe00,0xfe00,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u2527\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0xfe00,0xfe00,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u2528\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0xfe00,0xfe00,0xfe00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2529\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfe00,0xfe00,0xfe00,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u252a\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0xfe00,0xfe00,0xfe00,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u252b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u252c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xffe0,0xffe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u252d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0xffe0,0xffe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u252e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,0xffe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u252f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u2530\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xffe0,0xffe0,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u2531\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0xffe0,0xffe0,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u2532\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,0xffe0,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u2533\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffe0,0xffe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2534\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xffe0,0xffe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2535\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fe0,0xffe0,0xffe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2536\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffe0,0xffe0,0xffe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2537\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0xffe0,0xffe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2538\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0xfe00,0xffe0,0xffe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2539\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0fe0,0xffe0,0xffe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u253a\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0xffe0,0xffe0,0xffe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u253b\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffe0,0xffe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u253c\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xffe0,0xffe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u253d\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fe0,0xffe0,0xffe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u253e\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffe0,0xffe0,0xffe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u253f\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0xffe0,0xffe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2540\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffe0,0xffe0,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u2541\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0xffe0,0xffe0,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u2542\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0xfe00,0xffe0,0xffe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2543\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0fe0,0xffe0,0xffe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2544\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xffe0,0xffe0,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u2545\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fe0,0xffe0,0xffe0,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u2546\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0xffe0,0xffe0,0xffe0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2547\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffe0,0xffe0,0xffe0,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u2548\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0xfe00,0xffe0,0xffe0,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u2549\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0fe0,0xffe0,0xffe0,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u254a\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0xffe0,0xffe0,0xffe0,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u254b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,0x0000,0xffe0,0xffe0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2550\n  0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,\n  0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00, // u2551\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x0fe0,0x0c00,0x0fe0,0x0fe0,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2552\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fe0,0x1fe0,0x1b00,0x1b00,0x1b00,0x1b00,\n  0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00, // u2553\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fe0,0x1fe0,0x1800,0x1be0,0x1be0,0x1b00,0x1b00,0x1b00,\n  0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00, // u2554\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x0c00,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2555\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x1b00,0x1b00,0x1b00,0x1b00,\n  0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00, // u2556\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x0300,0xfb00,0xfb00,0x1b00,0x1b00,0x1b00,\n  0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00, // u2557\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fe0,0x0fe0,0x0c00,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2558\n  0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1fe0,0x1fe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2559\n  0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1be0,0x1be0,0x1800,0x1fe0,0x1fe0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255a\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0x0400,0xfc00,0xfc00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255b\n  0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0xff00,0xff00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255c\n  0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0xfb00,0xfb00,0x0300,0xff00,0xff00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255d\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fe0,0x0fe0,0x0c00,0x0fe0,0x0fe0,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u255e\n  0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1fe0,0x1fe0,0x1b00,0x1b00,0x1b00,0x1b00,\n  0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00, // u255f\n  0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1be0,0x1be0,0x1800,0x1be0,0x1be0,0x1b00,0x1b00,0x1b00,\n  0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00, // u2560\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xfc00,0xfc00,0x0c00,0xfc00,0xfc00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2561\n  0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0xff00,0xff00,0x1b00,0x1b00,0x1b00,0x1b00,\n  0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00, // u2562\n  0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0xfb00,0xfb00,0x0300,0xfb00,0xfb00,0x1b00,0x1b00,0x1b00,\n  0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00, // u2563\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,0x0000,0xffe0,0xffe0,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2564\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,0x1b00,0x1b00,0x1b00,0x1b00,\n  0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00, // u2565\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,0x0000,0xfbe0,0xfbe0,0x1b00,0x1b00,0x1b00,\n  0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00, // u2566\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffe0,0xffe0,0x0000,0xffe0,0xffe0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2567\n  0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0xffe0,0xffe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2568\n  0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0xfbe0,0xfbe0,0x0000,0xffe0,0xffe0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2569\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0xffe0,0xffe0,0x0c00,0xffe0,0xffe0,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u256a\n  0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0xffe0,0xffe0,0x1b00,0x1b00,0x1b00,0x1b00,\n  0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00, // u256b\n  0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0xfbe0,0xfbe0,0x0000,0xfbe0,0xfbe0,0x1b00,0x1b00,0x1b00,\n  0x1b00,0x1b00,0x1b00,0x1b00,0x1b00,0x1b00, // u256c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00e0,0x03e0,0x0700,0x0600,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u256d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0x3800,0x1800,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u256e\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1800,0x3800,0xf000,0xc000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u256f\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0600,0x0700,0x03e0,0x00e0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2570\n  0x0020,0x0020,0x0060,0x0040,0x00c0,0x0080,0x0180,0x0100,0x0300,0x0200,0x0600,0x0400,0x0c00,0x0800,0x1800,0x1000,\n  0x3000,0x2000,0x6000,0x4000,0xc000,0x8000, // u2571\n  0x8000,0xc000,0x4000,0x6000,0x2000,0x3000,0x1000,0x1800,0x0800,0x0c00,0x0400,0x0600,0x0200,0x0300,0x0100,0x0180,\n  0x0080,0x00c0,0x0040,0x0060,0x0020,0x0020, // u2572\n  0x8020,0xc020,0x4060,0x6040,0x20c0,0x3080,0x1180,0x1900,0x0b00,0x0e00,0x0600,0x0600,0x0e00,0x0b00,0x1900,0x1180,\n  0x3080,0x20c0,0x6040,0x4060,0xc020,0x8020, // u2573\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2574\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2575\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2576\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u2577\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2578\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2579\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u257b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0xffe0,0xffe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257c\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00, // u257d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xffe0,0xffe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257e\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u257f\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2580\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0xffe0,0xffe0,0xffe0, // u2581\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0, // u2582\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0, // u2583\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0, // u2584\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0, // u2585\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0, // u2586\n  0x0000,0x0000,0x0000,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0, // u2587\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0, // u2588\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0, // u2589\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u258a\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00, // u258b\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800, // u258c\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000, // u258d\n  0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,\n  0xe000,0xe000,0xe000,0xe000,0xe000,0xe000, // u258e\n  0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,\n  0x8000,0x8000,0x8000,0x8000,0x8000,0x8000, // u258f\n  0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,\n  0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0, // u2590\n  0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000,\n  0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000, // u2591\n  0xaaa0,0x5540,0xaaa0,0x5540,0xaaa0,0x5540,0xaaa0,0x5540,0xaaa0,0x5540,0xaaa0,0x5540,0xaaa0,0x5540,0xaaa0,0x5540,\n  0xaaa0,0x5540,0xaaa0,0x5540,0xaaa0,0x5540, // u2592\n  0xffe0,0xaaa0,0xffe0,0xaaa0,0xffe0,0xaaa0,0xffe0,0xaaa0,0xffe0,0xaaa0,0xffe0,0xaaa0,0xffe0,0xaaa0,0xffe0,0xaaa0,\n  0xffe0,0xaaa0,0xffe0,0xaaa0,0xffe0,0xaaa0, // u2593\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800, // u2596\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,\n  0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0, // u2597\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2598\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0, // u2599\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,\n  0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0, // u259a\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800, // u259b\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,\n  0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0, // u259c\n  0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u259d\n  0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800, // u259e\n  0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0, // u259f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x3f80,0x3f80,0x3f80,0x3f80,0x3f80,0x3f80,0x3f80,0x3f80,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ac\n  0x0000,0x0000,0x0000,0x7fc0,0x7fc0,0x7fc0,0x7fc0,0x7fc0,0x7fc0,0x7fc0,0x7fc0,0x7fc0,0x7fc0,0x7fc0,0x7fc0,0x7fc0,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0e00,0x0e00,0x1f00,0x1f00,0x3f80,0x3f80,0x7fc0,0x7fc0,0xffe0,0xffe0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xffc0,0xffe0,0xffc0,0xff00,0xfc00,0xf000,0xc000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xffc0,0xffe0,0xffc0,0xff00,0xfc00,0xf000,0xc000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,0x7fc0,0x7fc0,0x3f80,0x3f80,0x1f00,0x1f00,0x0e00,0x0e00,0x0400,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x01e0,0x07e0,0x1fe0,0x7fe0,0xffe0,0x7fe0,0x1fe0,0x07e0,0x01e0,0x0060,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x01e0,0x07e0,0x1fe0,0x7fe0,0xffe0,0x7fe0,0x1fe0,0x07e0,0x01e0,0x0060,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x1e00,0x3f00,0x7f80,0xffc0,0xffc0,0x7f80,0x3f00,0x1e00,0x0c00,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x1e00,0x3300,0x6180,0xc0c0,0xc0c0,0x6180,0x3300,0x1e00,0x0c00,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ca\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x1b00,0x1100,0x1b00,0x0e00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x1f00,0x1f00,0x1f00,0x0e00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25cf\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xf1e0,0xe0e0,0xe0e0,0xe0e0,0xf1e0,0xffe0,0xffe0,0xffe0,\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0, // u25d8\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xf1e0,0xe4e0,0xeee0,0xe4e0,0xf1e0,0xffe0,0xffe0,0xffe0,\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0, // u25d9\n  0x0000,0x0000,0x0000,0x3f80,0x60c0,0xc060,0xdb60,0xdb60,0xc060,0xc060,0xc060,0xdf60,0xce60,0xc060,0xc060,0x60c0,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u263a\n  0x0000,0x0000,0x0000,0x3f80,0x7fc0,0xffe0,0xe4e0,0xe4e0,0xffe0,0xffe0,0xffe0,0xe0e0,0xf1e0,0xffe0,0xffe0,0x7fc0,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u263b\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0xccc0,0x6d80,0x3f00,0x1e00,0xf3c0,0x1e00,0x3f00,0x6d80,0xccc0,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u263c\n  0x0000,0x0000,0x0000,0x3f00,0x6180,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0xc0c0,0x6180,0x3f00,0x0c00,0x0c00,0xffc0,0x0c00,\n  0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2640\n  0x0000,0x0000,0x0000,0x0fc0,0x01c0,0x0340,0x0640,0x0c40,0x3e00,0x6300,0xc180,0xc180,0xc180,0xc180,0xc180,0x6300,\n  0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2642\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x1e00,0x3f00,0x7f80,0xffc0,0xffc0,0xffc0,0xffc0,0x6d80,0x0c00,0x0c00,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2660\n  0x0000,0x0000,0x0000,0x1e00,0x3f00,0x3f00,0x1e00,0x0c00,0x0c00,0x6d80,0xffc0,0xffc0,0xffc0,0x6d80,0x0c00,0x0c00,\n  0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2663\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7380,0xf3c0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0x7f80,0x3f00,0x1e00,0x0c00,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2665\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x1e00,0x3f00,0x7f80,0xffc0,0xffc0,0x7f80,0x3f00,0x1e00,0x0c00,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2666\n  0x0000,0x0000,0x0000,0x3fc0,0x30c0,0x30c0,0x30c0,0x3fc0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0xf000,\n  0xe000,0x0000,0x0000,0x0000,0x0000,0x0000, // u266a\n  0x0000,0x0000,0x0000,0x7fc0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,\n  0xc000,0x0000,0x0000,0x0000,0x0000,0x0000, // u266b\n  0x0000,0x0000,0x0000,0x0060,0x0060,0x00c0,0x00c0,0x0180,0x0180,0xc300,0xc300,0x6600,0x6600,0x3c00,0x3c00,0x1800,\n  0x1800,0x0000,0x0000,0x0000,0x0000,0x0000, // u2713\n  0x0000,0x0000,0x0000,0x00e0,0x00e0,0x01c0,0x01c0,0x0380,0x0380,0xe700,0xe700,0x7e00,0x7e00,0x3c00,0x3c00,0x1800,\n  0x1800,0x0000,0x0000,0x0000,0x0000,0x0000, // u2714\n  0x0000,0x0000,0x0000,0x0180,0x0180,0x6300,0x3300,0x1e00,0x0e00,0x0e00,0x0f00,0x1980,0x18c0,0x3000,0x3000,0x6000,\n  0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2717\n  0x0000,0x0000,0x0000,0x0380,0xe380,0x7700,0x3f00,0x1e00,0x0e00,0x1f00,0x1f80,0x39c0,0x38c0,0x7000,0x7000,0xe000,\n  0xe000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2718\n  0x0000,0x0000,0x0000,0x0300,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x0c00,0x0c00,0x0600,0x0600,0x0300,\n  0x0300,0x0000,0x0000,0x0000,0x0000,0x0000, // u27e8\n  0x0000,0x0000,0x0000,0x1800,0x1800,0x0c00,0x0c00,0x0600,0x0600,0x0300,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x1800,\n  0x1800,0x0000,0x0000,0x0000,0x0000,0x0000, // u27e9\n  0x0000,0x0000,0x0000,0x0cc0,0x0cc0,0x1980,0x1980,0x3300,0x3300,0x6600,0x6600,0x3300,0x3300,0x1980,0x1980,0x0cc0,\n  0x0cc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u27ea\n  0x0000,0x0000,0x0000,0x6600,0x6600,0x3300,0x3300,0x1980,0x1980,0x0cc0,0x0cc0,0x1980,0x1980,0x3300,0x3300,0x6600,\n  0x6600,0x0000,0x0000,0x0000,0x0000,0x0000, // u27eb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2800\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2801\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2802\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2803\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2804\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2805\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2806\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2807\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2808\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2809\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280a\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280b\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280c\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280d\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280e\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2810\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2811\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2812\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2813\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2814\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2815\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2816\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2817\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2818\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2819\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281a\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281b\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281c\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281d\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281e\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2820\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2821\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2822\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2823\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2824\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2825\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2826\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2827\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2828\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2829\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282a\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282b\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282c\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282d\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282e\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2830\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2831\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2832\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2833\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2834\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2835\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2836\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2837\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2838\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2839\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283a\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283b\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283c\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283d\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283e\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2840\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2841\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2842\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2843\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2844\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2845\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2846\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2847\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2848\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2849\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u284a\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u284b\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u284c\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u284d\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u284e\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u284f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2850\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2851\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2852\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2853\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2854\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2855\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2856\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2857\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2858\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2859\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u285a\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u285b\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u285c\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u285d\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u285e\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u285f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2860\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2861\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2862\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2863\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2864\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2865\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2866\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2867\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2868\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2869\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u286a\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u286b\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u286c\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u286d\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u286e\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u286f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2870\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2871\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2872\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2873\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2874\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2875\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2876\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2877\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2878\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2879\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u287a\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u287b\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u287c\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u287d\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u287e\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u287f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u2880\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u2881\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u2882\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u2883\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u2884\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u2885\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u2886\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u2887\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u2888\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u2889\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u288a\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u288b\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u288c\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u288d\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u288e\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u288f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u2890\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u2891\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u2892\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u2893\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u2894\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u2895\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u2896\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u2897\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u2898\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u2899\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u289a\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u289b\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u289c\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u289d\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u289e\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u289f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28a0\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28a2\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28a4\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28a5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28a6\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28a7\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28a8\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28a9\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28aa\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28ab\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28ac\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28ad\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28ae\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28af\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28b0\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28b1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28b2\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28b4\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28b6\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28b7\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28b8\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28b9\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28ba\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28bb\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28bc\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28bd\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28be\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u28bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28c0\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28c2\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28c4\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28c6\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28c7\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28c8\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28c9\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28ca\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28cb\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28cc\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28cd\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28ce\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28cf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28d0\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28d2\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28d4\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28d6\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28d7\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28d8\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28d9\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28da\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28db\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28dc\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28dd\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28de\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28df\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28e0\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28e1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28e2\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28e3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28e4\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28e6\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28e7\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28e8\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28e9\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28ea\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28eb\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28ec\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28ed\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28ee\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28ef\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28f0\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28f2\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28f3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28f4\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28f6\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28f7\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28f8\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28f9\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28fa\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28fb\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28fc\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28fd\n  0x0000,0x0180,0x0180,0x0180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28fe\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,\n  0x0000,0x3180,0x3180,0x3180,0x0000,0x0000, // u28ff\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x60c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2e2c\n  0xc000,0xc000,0xc300,0xc780,0xcfc0,0xdb60,0xc300,0xc300,0xc300,0xc300,0xc600,0x8c00,0x1800,0x3000,0x6000,0xc000,\n  0xc000,0xc000,0xc000,0xc000,0xc000,0xc000, // ue0a0\n  0x0000,0x0000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xfe00,0x0000,0x0000,0x18c0,0x18c0,0x1cc0,0x1ec0,\n  0x1bc0,0x19c0,0x18c0,0x18c0,0x0000,0x0000, // ue0a1\n  0x0000,0x0000,0x3f00,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0xffc0,0xffc0,0xffc0,0xf3c0,0xe1c0,0xe1c0,0xf3c0,\n  0xffc0,0xffc0,0xffc0,0x0000,0x0000,0x0000, // ue0a2\n  0x8000,0xc000,0xe000,0xf000,0xf800,0xfc00,0xfe00,0xff00,0xff80,0xffc0,0xffe0,0xffe0,0xffc0,0xff80,0xff00,0xfe00,\n  0xfc00,0xf800,0xf000,0xe000,0xc000,0x8000, // ue0b0\n  0x8000,0xc000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x00c0,0x0060,0x0060,0x00c0,0x0180,0x0300,0x0600,\n  0x0c00,0x1800,0x3000,0x6000,0xc000,0x8000, // ue0b1\n  0x0020,0x0060,0x00e0,0x01e0,0x03e0,0x07e0,0x0fe0,0x1fe0,0x3fe0,0x7fe0,0xffe0,0xffe0,0x7fe0,0x3fe0,0x1fe0,0x0fe0,\n  0x07e0,0x03e0,0x01e0,0x00e0,0x0060,0x0020, // ue0b2\n  0x0020,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0xc000,0x6000,0x3000,0x1800,0x0c00,\n  0x0600,0x0300,0x0180,0x00c0,0x0060,0x0020, // ue0b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0780,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x3180,0x3180,0x3180,0x1f00,0x0000, // uf6be\n  0x0000,0x0000,0x0000,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000 // ufffd\n  };\n  // codepoints array\n  constexpr std::array<uint16_t, CHARCOUNT> fixedfont_codepoints = {\n  0x0000,0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,\n  0x002f,0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,\n  0x003f,0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,\n  0x004f,0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,\n  0x005f,0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,\n  0x006f,0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,\n  0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af,\n  0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf,\n  0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf,\n  0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df,\n  0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef,\n  0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff,\n  0x0100,0x0101,0x0102,0x0103,0x0104,0x0105,0x0106,0x0107,0x0108,0x0109,0x010a,0x010b,0x010c,0x010d,0x010e,0x010f,\n  0x0110,0x0111,0x0112,0x0113,0x0114,0x0115,0x0116,0x0117,0x0118,0x0119,0x011a,0x011b,0x011c,0x011d,0x011e,0x011f,\n  0x0120,0x0121,0x0122,0x0123,0x0124,0x0125,0x0126,0x0127,0x0128,0x0129,0x012a,0x012b,0x012c,0x012d,0x012e,0x012f,\n  0x0130,0x0131,0x0132,0x0133,0x0134,0x0135,0x0136,0x0137,0x0138,0x0139,0x013a,0x013b,0x013c,0x013d,0x013e,0x013f,\n  0x0140,0x0141,0x0142,0x0143,0x0144,0x0145,0x0146,0x0147,0x0148,0x0149,0x014a,0x014b,0x014c,0x014d,0x014e,0x014f,\n  0x0150,0x0151,0x0152,0x0153,0x0154,0x0155,0x0156,0x0157,0x0158,0x0159,0x015a,0x015b,0x015c,0x015d,0x015e,0x015f,\n  0x0160,0x0161,0x0162,0x0163,0x0164,0x0165,0x0166,0x0167,0x0168,0x0169,0x016a,0x016b,0x016c,0x016d,0x016e,0x016f,\n  0x0170,0x0171,0x0172,0x0173,0x0174,0x0175,0x0176,0x0177,0x0178,0x0179,0x017a,0x017b,0x017c,0x017d,0x017e,0x017f,\n  0x0186,0x018e,0x018f,0x0190,0x0192,0x019d,0x019e,0x01b5,0x01b6,0x01b7,0x01cd,0x01ce,0x01cf,0x01d0,0x01d1,0x01d2,\n  0x01d3,0x01d4,0x01e2,0x01e3,0x01e4,0x01e5,0x01e6,0x01e7,0x01e8,0x01e9,0x01ea,0x01eb,0x01ec,0x01ed,0x01ee,0x01ef,\n  0x01f0,0x01f4,0x01f5,0x01fc,0x01fd,0x01fe,0x01ff,0x0218,0x0219,0x021a,0x021b,0x0232,0x0233,0x0237,0x0254,0x0258,\n  0x0259,0x025b,0x0272,0x0292,0x02bb,0x02bc,0x02bd,0x02c6,0x02c7,0x02d8,0x02d9,0x02db,0x02dc,0x02dd,0x0300,0x0301,\n  0x0302,0x0303,0x0304,0x0305,0x0306,0x0307,0x0308,0x030a,0x030b,0x030c,0x0329,0x0384,0x0385,0x0386,0x0387,0x0388,\n  0x0389,0x038a,0x038c,0x038e,0x038f,0x0390,0x0391,0x0392,0x0393,0x0394,0x0395,0x0396,0x0397,0x0398,0x0399,0x039a,\n  0x039b,0x039c,0x039d,0x039e,0x039f,0x03a0,0x03a1,0x03a3,0x03a4,0x03a5,0x03a6,0x03a7,0x03a8,0x03a9,0x03aa,0x03ab,\n  0x03ac,0x03ad,0x03ae,0x03af,0x03b0,0x03b1,0x03b2,0x03b3,0x03b4,0x03b5,0x03b6,0x03b7,0x03b8,0x03b9,0x03ba,0x03bb,\n  0x03bc,0x03bd,0x03be,0x03bf,0x03c0,0x03c1,0x03c2,0x03c3,0x03c4,0x03c5,0x03c6,0x03c7,0x03c8,0x03c9,0x03ca,0x03cb,\n  0x03cc,0x03cd,0x03ce,0x03d1,0x03d5,0x03f0,0x03f1,0x03f2,0x03f3,0x03f4,0x03f5,0x03f6,0x0400,0x0401,0x0402,0x0403,\n  0x0404,0x0405,0x0406,0x0407,0x0408,0x0409,0x040a,0x040b,0x040c,0x040d,0x040e,0x040f,0x0410,0x0411,0x0412,0x0413,\n  0x0414,0x0415,0x0416,0x0417,0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e,0x041f,0x0420,0x0421,0x0422,0x0423,\n  0x0424,0x0425,0x0426,0x0427,0x0428,0x0429,0x042a,0x042b,0x042c,0x042d,0x042e,0x042f,0x0430,0x0431,0x0432,0x0433,\n  0x0434,0x0435,0x0436,0x0437,0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e,0x043f,0x0440,0x0441,0x0442,0x0443,\n  0x0444,0x0445,0x0446,0x0447,0x0448,0x0449,0x044a,0x044b,0x044c,0x044d,0x044e,0x044f,0x0450,0x0451,0x0452,0x0453,\n  0x0454,0x0455,0x0456,0x0457,0x0458,0x0459,0x045a,0x045b,0x045c,0x045d,0x045e,0x045f,0x0462,0x0463,0x046a,0x046b,\n  0x0490,0x0491,0x0492,0x0493,0x0494,0x0495,0x0496,0x0497,0x0498,0x0499,0x049a,0x049b,0x049c,0x049d,0x04a0,0x04a1,\n  0x04a2,0x04a3,0x04a4,0x04a5,0x04aa,0x04ab,0x04ae,0x04af,0x04b0,0x04b1,0x04b2,0x04b3,0x04b6,0x04b7,0x04b8,0x04b9,\n  0x04ba,0x04bb,0x04c0,0x04c1,0x04c2,0x04cf,0x04d0,0x04d1,0x04d2,0x04d3,0x04d4,0x04d5,0x04d6,0x04d7,0x04d8,0x04d9,\n  0x04da,0x04db,0x04dc,0x04dd,0x04de,0x04df,0x04e2,0x04e3,0x04e4,0x04e5,0x04e6,0x04e7,0x04e8,0x04e9,0x04ea,0x04eb,\n  0x04ec,0x04ed,0x04ee,0x04ef,0x04f0,0x04f1,0x04f2,0x04f3,0x04f4,0x04f5,0x04f8,0x04f9,0x05d0,0x05d1,0x05d2,0x05d3,\n  0x05d4,0x05d5,0x05d6,0x05d7,0x05d8,0x05d9,0x05da,0x05db,0x05dc,0x05dd,0x05de,0x05df,0x05e0,0x05e1,0x05e2,0x05e3,\n  0x05e4,0x05e5,0x05e6,0x05e7,0x05e8,0x05e9,0x05ea,0x1e0c,0x1e0d,0x1e34,0x1e35,0x1e36,0x1e37,0x1e40,0x1e41,0x1e42,\n  0x1e43,0x1e44,0x1e45,0x1e46,0x1e47,0x1e6c,0x1e6d,0x1eb8,0x1eb9,0x1ebc,0x1ebd,0x1eca,0x1ecb,0x1ecc,0x1ecd,0x1ee4,\n  0x1ee5,0x1ef8,0x1ef9,0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007,0x2008,0x2009,0x200a,0x200b,0x200c,\n  0x200d,0x200e,0x200f,0x2010,0x2011,0x2012,0x2013,0x2014,0x2015,0x2016,0x2017,0x2018,0x2019,0x201a,0x201b,0x201c,\n  0x201d,0x201e,0x201f,0x2020,0x2021,0x2022,0x2026,0x2030,0x2032,0x2033,0x2039,0x203a,0x203c,0x203e,0x2070,0x2071,\n  0x2074,0x2075,0x2076,0x2077,0x2078,0x2079,0x207a,0x207b,0x207c,0x207d,0x207e,0x207f,0x2080,0x2081,0x2082,0x2083,\n  0x2084,0x2085,0x2086,0x2087,0x2088,0x2089,0x208a,0x208b,0x208c,0x208d,0x208e,0x2090,0x2091,0x2092,0x2093,0x2094,\n  0x2095,0x2096,0x2097,0x2098,0x209a,0x20a7,0x20aa,0x20ac,0x20ae,0x2102,0x210e,0x210f,0x2115,0x2116,0x211a,0x211d,\n  0x2122,0x2124,0x2126,0x2135,0x2190,0x2191,0x2192,0x2193,0x2194,0x2195,0x21a4,0x21a6,0x21a8,0x21b5,0x21bb,0x21cb,\n  0x21cc,0x21d0,0x21d1,0x21d2,0x21d3,0x21d4,0x21d5,0x2200,0x2203,0x2204,0x2205,0x2206,0x2207,0x2208,0x2209,0x220a,\n  0x220b,0x220c,0x220d,0x2212,0x2213,0x2214,0x2215,0x2216,0x2219,0x221a,0x221e,0x221f,0x2225,0x2227,0x2228,0x2229,\n  0x222a,0x2248,0x2260,0x2261,0x2264,0x2265,0x226a,0x226b,0x2282,0x2283,0x2286,0x2287,0x22a5,0x22c2,0x22c3,0x2300,\n  0x2302,0x2308,0x2309,0x230a,0x230b,0x2310,0x2319,0x2320,0x2321,0x239b,0x239c,0x239d,0x239e,0x239f,0x23a0,0x23a1,\n  0x23a2,0x23a3,0x23a4,0x23a5,0x23a6,0x23a7,0x23a8,0x23a9,0x23ab,0x23ac,0x23ad,0x23ae,0x23af,0x23ba,0x23bb,0x23bc,\n  0x23bd,0x23d0,0x2409,0x240a,0x240b,0x240c,0x240d,0x2424,0x2500,0x2501,0x2502,0x2503,0x2508,0x2509,0x250a,0x250b,\n  0x250c,0x250d,0x250e,0x250f,0x2510,0x2511,0x2512,0x2513,0x2514,0x2515,0x2516,0x2517,0x2518,0x2519,0x251a,0x251b,\n  0x251c,0x251d,0x251e,0x251f,0x2520,0x2521,0x2522,0x2523,0x2524,0x2525,0x2526,0x2527,0x2528,0x2529,0x252a,0x252b,\n  0x252c,0x252d,0x252e,0x252f,0x2530,0x2531,0x2532,0x2533,0x2534,0x2535,0x2536,0x2537,0x2538,0x2539,0x253a,0x253b,\n  0x253c,0x253d,0x253e,0x253f,0x2540,0x2541,0x2542,0x2543,0x2544,0x2545,0x2546,0x2547,0x2548,0x2549,0x254a,0x254b,\n  0x2550,0x2551,0x2552,0x2553,0x2554,0x2555,0x2556,0x2557,0x2558,0x2559,0x255a,0x255b,0x255c,0x255d,0x255e,0x255f,\n  0x2560,0x2561,0x2562,0x2563,0x2564,0x2565,0x2566,0x2567,0x2568,0x2569,0x256a,0x256b,0x256c,0x256d,0x256e,0x256f,\n  0x2570,0x2571,0x2572,0x2573,0x2574,0x2575,0x2576,0x2577,0x2578,0x2579,0x257a,0x257b,0x257c,0x257d,0x257e,0x257f,\n  0x2580,0x2581,0x2582,0x2583,0x2584,0x2585,0x2586,0x2587,0x2588,0x2589,0x258a,0x258b,0x258c,0x258d,0x258e,0x258f,\n  0x2590,0x2591,0x2592,0x2593,0x2596,0x2597,0x2598,0x2599,0x259a,0x259b,0x259c,0x259d,0x259e,0x259f,0x25a0,0x25ac,\n  0x25ae,0x25b2,0x25b6,0x25ba,0x25bc,0x25c0,0x25c4,0x25c6,0x25ca,0x25cb,0x25cf,0x25d8,0x25d9,0x263a,0x263b,0x263c,\n  0x2640,0x2642,0x2660,0x2663,0x2665,0x2666,0x266a,0x266b,0x2713,0x2714,0x2717,0x2718,0x27e8,0x27e9,0x27ea,0x27eb,\n  0x2800,0x2801,0x2802,0x2803,0x2804,0x2805,0x2806,0x2807,0x2808,0x2809,0x280a,0x280b,0x280c,0x280d,0x280e,0x280f,\n  0x2810,0x2811,0x2812,0x2813,0x2814,0x2815,0x2816,0x2817,0x2818,0x2819,0x281a,0x281b,0x281c,0x281d,0x281e,0x281f,\n  0x2820,0x2821,0x2822,0x2823,0x2824,0x2825,0x2826,0x2827,0x2828,0x2829,0x282a,0x282b,0x282c,0x282d,0x282e,0x282f,\n  0x2830,0x2831,0x2832,0x2833,0x2834,0x2835,0x2836,0x2837,0x2838,0x2839,0x283a,0x283b,0x283c,0x283d,0x283e,0x283f,\n  0x2840,0x2841,0x2842,0x2843,0x2844,0x2845,0x2846,0x2847,0x2848,0x2849,0x284a,0x284b,0x284c,0x284d,0x284e,0x284f,\n  0x2850,0x2851,0x2852,0x2853,0x2854,0x2855,0x2856,0x2857,0x2858,0x2859,0x285a,0x285b,0x285c,0x285d,0x285e,0x285f,\n  0x2860,0x2861,0x2862,0x2863,0x2864,0x2865,0x2866,0x2867,0x2868,0x2869,0x286a,0x286b,0x286c,0x286d,0x286e,0x286f,\n  0x2870,0x2871,0x2872,0x2873,0x2874,0x2875,0x2876,0x2877,0x2878,0x2879,0x287a,0x287b,0x287c,0x287d,0x287e,0x287f,\n  0x2880,0x2881,0x2882,0x2883,0x2884,0x2885,0x2886,0x2887,0x2888,0x2889,0x288a,0x288b,0x288c,0x288d,0x288e,0x288f,\n  0x2890,0x2891,0x2892,0x2893,0x2894,0x2895,0x2896,0x2897,0x2898,0x2899,0x289a,0x289b,0x289c,0x289d,0x289e,0x289f,\n  0x28a0,0x28a1,0x28a2,0x28a3,0x28a4,0x28a5,0x28a6,0x28a7,0x28a8,0x28a9,0x28aa,0x28ab,0x28ac,0x28ad,0x28ae,0x28af,\n  0x28b0,0x28b1,0x28b2,0x28b3,0x28b4,0x28b5,0x28b6,0x28b7,0x28b8,0x28b9,0x28ba,0x28bb,0x28bc,0x28bd,0x28be,0x28bf,\n  0x28c0,0x28c1,0x28c2,0x28c3,0x28c4,0x28c5,0x28c6,0x28c7,0x28c8,0x28c9,0x28ca,0x28cb,0x28cc,0x28cd,0x28ce,0x28cf,\n  0x28d0,0x28d1,0x28d2,0x28d3,0x28d4,0x28d5,0x28d6,0x28d7,0x28d8,0x28d9,0x28da,0x28db,0x28dc,0x28dd,0x28de,0x28df,\n  0x28e0,0x28e1,0x28e2,0x28e3,0x28e4,0x28e5,0x28e6,0x28e7,0x28e8,0x28e9,0x28ea,0x28eb,0x28ec,0x28ed,0x28ee,0x28ef,\n  0x28f0,0x28f1,0x28f2,0x28f3,0x28f4,0x28f5,0x28f6,0x28f7,0x28f8,0x28f9,0x28fa,0x28fb,0x28fc,0x28fd,0x28fe,0x28ff,\n  0x2e2c,0xe0a0,0xe0a1,0xe0a2,0xe0b0,0xe0b1,0xe0b2,0xe0b3,0xf6be,0xfffd };\n} // namespace\n// -- end of autogenerated text ---\n\nnamespace fixed_font_24n {\n  // -- start of autogenerated text ---\n  // definition section for font: ter-u24n.bdf\n  constexpr int CHARCOUNT = 1354;\n  constexpr int WIDTH = 12;\n  constexpr int HEIGHT = 24;\n  constexpr int OFFSET_X = 0;\n  constexpr int OFFSET_Y = 0;\n  constexpr FixedFont_info_t fixedfont_info = {\n    \"Terminus\", // font name\n    \"ter-u24n.bdf\", // font name internal\n    CHARCOUNT, // num of chars\n    WIDTH, HEIGHT, OFFSET_X, OFFSET_Y,\n    false // bold\n  };\n  // font bitmap definitions\n  constexpr std::array<uint16_t, CHARCOUNT * HEIGHT> fixedfont_bitmap = {\n  0x0000,0x0000,0x0000,0x0000,0x71c0,0x4040,0x4040,0x4040,0x0000,0x0000,0x4040,0x4040,0x4040,0x0000,0x0000,0x4040,\n  0x4040,0x4040,0x71c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0020\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0000,0x0000,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u0021\n  0x0000,0x0000,0x1100,0x1100,0x1100,0x1100,0x1100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0022\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,0x1100,0x7fc0,0x1100,0x1100,0x1100,0x1100,0x1100,0x7fc0,0x1100,\n  0x1100,0x1100,0x1100,0x0000,0x0000,0x0000,0x0000,0x0000, // u0023\n  0x0000,0x0000,0x0000,0x0400,0x0400,0x1f00,0x2480,0x4440,0x4400,0x4400,0x2400,0x1f00,0x0480,0x0440,0x0440,0x4440,\n  0x2480,0x1f00,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000, // u0024\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3080,0x4880,0x4900,0x3100,0x0200,0x0200,0x0400,0x0400,0x0800,0x0800,0x1180,\n  0x1240,0x2240,0x2180,0x0000,0x0000,0x0000,0x0000,0x0000, // u0025\n  0x0000,0x0000,0x0000,0x0000,0x1e00,0x2100,0x2100,0x2100,0x2100,0x1200,0x0c00,0x1400,0x2240,0x4140,0x4080,0x4080,\n  0x4080,0x2140,0x1e40,0x0000,0x0000,0x0000,0x0000,0x0000, // u0026\n  0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0027\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0400,\n  0x0400,0x0200,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000, // u0028\n  0x0000,0x0000,0x0000,0x0000,0x0800,0x0400,0x0200,0x0200,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0200,\n  0x0200,0x0400,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000, // u0029\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x1100,0x0a00,0x0400,0x7fc0,0x0400,0x0a00,0x1100,0x2080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x7fc0,0x0400,0x0400,0x0400,0x0400,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,\n  0x0400,0x0400,0x0400,0x0800,0x0000,0x0000,0x0000,0x0000, // u002c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u002e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0100,0x0100,0x0200,0x0200,0x0400,0x0400,0x0800,0x0800,0x1000,\n  0x1000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002f\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x40c0,0x4140,0x4240,0x4440,0x4840,0x5040,0x6040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0030\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0c00,0x1400,0x2400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0031\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,\n  0x2000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0032\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x0040,0x0040,0x0040,0x0080,0x0f00,0x0080,0x0040,0x0040,0x0040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0033\n  0x0000,0x0000,0x0000,0x0000,0x0040,0x00c0,0x0140,0x0240,0x0440,0x0840,0x1040,0x2040,0x4040,0x4040,0x4040,0x7fc0,\n  0x0040,0x0040,0x0040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0034\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x0080,0x0040,0x0040,0x0040,0x0040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0035\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x2000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0036\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4040,0x4040,0x0040,0x0080,0x0080,0x0100,0x0100,0x0200,0x0200,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u0037\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x2080,0x1f00,0x2080,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0038\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x2040,0x1fc0,0x0040,0x0040,0x0040,\n  0x0040,0x0080,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0400,\n  0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0400,\n  0x0400,0x0400,0x0400,0x0800,0x0000,0x0000,0x0000,0x0000, // u003b\n  0x0000,0x0000,0x0000,0x0000,0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x1000,0x0800,0x0400,0x0200,\n  0x0100,0x0080,0x0040,0x0000,0x0000,0x0000,0x0000,0x0000, // u003c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003d\n  0x0000,0x0000,0x0000,0x0000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,0x0080,0x0040,0x0080,0x0100,0x0200,0x0400,\n  0x0800,0x1000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003e\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x0080,0x0100,0x0200,0x0400,0x0400,0x0000,0x0000,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u003f\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x2040,0x4020,0x43e0,0x4420,0x4820,0x4820,0x4820,0x4820,0x4820,0x4460,0x43a0,\n  0x4000,0x2000,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0040\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0041\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4080,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4080,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0042\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0043\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4080,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0044\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0045\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0046\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4000,0x4000,0x4000,0x47c0,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0047\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0048\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0049\n  0x0000,0x0000,0x0000,0x0000,0x03e0,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x4080,0x4080,\n  0x4080,0x2100,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u004a\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4080,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x5000,0x4800,0x4400,0x4200,\n  0x4100,0x4080,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u004b\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u004c\n  0x0000,0x0000,0x0000,0x0000,0x4020,0x6060,0x50a0,0x50a0,0x4920,0x4620,0x4620,0x4020,0x4020,0x4020,0x4020,0x4020,\n  0x4020,0x4020,0x4020,0x0000,0x0000,0x0000,0x0000,0x0000, // u004d\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x6040,0x5040,0x4840,0x4440,0x4240,0x4140,0x40c0,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u004e\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u004f\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4080,0x7f00,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0050\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4440,0x2280,0x1f00,0x0080,0x0040,0x0000,0x0000,0x0000, // u0051\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4080,0x7f00,0x5000,0x4800,0x4400,0x4200,\n  0x4100,0x4080,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0052\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4000,0x4000,0x4000,0x2000,0x1f00,0x0080,0x0040,0x0040,0x0040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0053\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u0054\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0055\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x2080,0x2080,0x2080,0x1100,0x1100,0x1100,0x0a00,0x0a00,\n  0x0a00,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u0056\n  0x0000,0x0000,0x0000,0x0000,0x4020,0x4020,0x4020,0x4020,0x4020,0x4020,0x4020,0x4020,0x4620,0x4620,0x4920,0x50a0,\n  0x50a0,0x6060,0x4020,0x0000,0x0000,0x0000,0x0000,0x0000, // u0057\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0400,0x0a00,0x1100,0x1100,0x2080,\n  0x2080,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0058\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0a00,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u0059\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0040,0x0040,0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u005a\n  0x0000,0x0000,0x0000,0x0000,0x0f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u005b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x1000,0x1000,0x0800,0x0800,0x0400,0x0400,0x0200,0x0200,0x0100,\n  0x0100,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000, // u005c\n  0x0000,0x0000,0x0000,0x0000,0x0f00,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0100,0x0100,0x0f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u005d\n  0x0000,0x0000,0x0400,0x0a00,0x1100,0x2080,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0000, // u005f\n  0x1000,0x0800,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0060\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0080,0x0040,0x0040,0x1fc0,0x2040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0061\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4080,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0062\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0063\n  0x0000,0x0000,0x0000,0x0000,0x0040,0x0040,0x0040,0x0040,0x1fc0,0x2040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0064\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x7fc0,0x4000,0x4000,\n  0x4000,0x2040,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0065\n  0x0000,0x0000,0x0000,0x0000,0x03c0,0x0400,0x0400,0x0400,0x3f80,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u0066\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x2040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x20c0,0x1f40,0x0040,0x0040,0x0080,0x3f00,0x0000, // u0067\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0068\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0069\n  0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0380,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,\n  0x0080,0x0080,0x0080,0x2080,0x2080,0x1100,0x0e00,0x0000, // u006a\n  0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x2000,0x2040,0x2080,0x2100,0x2200,0x2400,0x3800,0x2400,0x2200,\n  0x2100,0x2080,0x2040,0x0000,0x0000,0x0000,0x0000,0x0000, // u006b\n  0x0000,0x0000,0x0000,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u006c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4480,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,\n  0x4440,0x4440,0x4440,0x0000,0x0000,0x0000,0x0000,0x0000, // u006d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u006e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u006f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4080,0x7f00,0x4000,0x4000,0x4000,0x4000,0x0000, // u0070\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x2040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0040,0x0040,0x0040,0x0040,0x0000, // u0071\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x47c0,0x4800,0x5000,0x6000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0072\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x4040,0x4000,0x4000,0x4000,0x3f80,0x0040,0x0040,\n  0x0040,0x4040,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0073\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x3f80,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0074\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0075\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,\n  0x0a00,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u0076\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4440,0x4440,0x4440,0x4440,\n  0x4440,0x4440,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0077\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x2080,0x1100,0x0a00,0x0400,0x0a00,0x1100,\n  0x2080,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0078\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x20c0,0x1f40,0x0040,0x0040,0x0080,0x3f00,0x0000, // u0079\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,\n  0x2000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u007a\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0200,0x0400,0x0400,0x0400,0x0400,0x0400,0x1800,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0200,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000, // u007b\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u007c\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x0400,0x0200,0x0200,0x0200,0x0200,0x0200,0x0180,0x0200,0x0200,0x0200,0x0200,\n  0x0200,0x0400,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000, // u007d\n  0x0000,0x0000,0x3840,0x4440,0x4440,0x4380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a0\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x1f00,0x2480,0x4440,0x4400,0x4400,0x4400,0x4400,0x4400,\n  0x4440,0x2480,0x1f00,0x0400,0x0400,0x0000,0x0000,0x0000, // u00a2\n  0x0000,0x0000,0x0000,0x0000,0x0e00,0x1100,0x2080,0x2000,0x2000,0x2000,0x2000,0x7e00,0x2000,0x2000,0x2000,0x2000,\n  0x2040,0x2040,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4020,0x2040,0x1f80,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,0x1f80,\n  0x2040,0x4020,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a4\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0400,0x0400,0x3f80,0x0400,0x0400,\n  0x3f80,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a5\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a6\n  0x0000,0x0000,0x0000,0x0f00,0x1080,0x1000,0x1000,0x0e00,0x1100,0x1080,0x1080,0x1080,0x1080,0x0880,0x0700,0x0080,\n  0x0080,0x1080,0x0f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a7\n  0x1100,0x1100,0x1100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x2040,0x4f20,0x50a0,0x50a0,0x5020,0x5020,0x50a0,0x50a0,0x4f20,\n  0x2040,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a9\n  0x0000,0x1f80,0x0040,0x0040,0x1fc0,0x2040,0x2040,0x2040,0x2040,0x1fc0,0x0000,0x3fc0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0220,0x0440,0x0880,0x1100,0x2200,0x4400,0x2200,0x1100,\n  0x0880,0x0440,0x0220,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ab\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0040,0x0040,0x0040,0x0040,0x0040,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ac\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ad\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x2040,0x5f20,0x50a0,0x50a0,0x50a0,0x5f20,0x5220,0x5120,0x50a0,\n  0x2040,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ae\n  0x0000,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00af\n  0x0000,0x0000,0x0f00,0x1080,0x1080,0x1080,0x1080,0x0f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x7fc0,0x0400,0x0400,0x0400,0x0400,\n  0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b1\n  0x0000,0x0000,0x0f00,0x1080,0x1080,0x0080,0x0100,0x0200,0x0400,0x0800,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b2\n  0x0000,0x0000,0x0f00,0x1080,0x0080,0x0080,0x0700,0x0080,0x0080,0x1080,0x0f00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b3\n  0x0100,0x0200,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x40c0,0x4140,0x7e40,0x4000,0x4000,0x4000,0x4000,0x0000, // u00b5\n  0x0000,0x0000,0x0000,0x0000,0x3fc0,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x3c40,0x0440,0x0440,0x0440,0x0440,\n  0x0440,0x0440,0x0440,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0800,0x0000, // u00b8\n  0x0000,0x0000,0x0400,0x0c00,0x1400,0x0400,0x0400,0x0400,0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b9\n  0x0000,0x0f00,0x1080,0x2040,0x2040,0x2040,0x2040,0x2040,0x1080,0x0f00,0x0000,0x3fc0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4400,0x2200,0x1100,0x0880,0x0440,0x0220,0x0440,0x0880,\n  0x1100,0x2200,0x4400,0x0000,0x0000,0x0000,0x0000,0x0000, // u00bb\n  0x0000,0x0000,0x0000,0x0800,0x1800,0x2800,0x0800,0x0840,0x0880,0x0900,0x0200,0x0400,0x0880,0x1180,0x2280,0x4480,\n  0x0880,0x0f80,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000, // u00bc\n  0x0000,0x0000,0x0000,0x0800,0x1800,0x2800,0x0800,0x0840,0x0880,0x0900,0x0200,0x0400,0x0800,0x1380,0x2440,0x4440,\n  0x0080,0x0100,0x0200,0x07c0,0x0000,0x0000,0x0000,0x0000, // u00bd\n  0x0000,0x0000,0x0000,0x1c00,0x2200,0x0200,0x0c00,0x0200,0x2240,0x1c80,0x0100,0x0200,0x0480,0x0980,0x1280,0x2480,\n  0x4880,0x0f80,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000, // u00be\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0800,0x1000,0x2000,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00bf\n  0x1000,0x0800,0x0400,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c0\n  0x0100,0x0200,0x0400,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c1\n  0x0400,0x0a00,0x1100,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c2\n  0x1880,0x2480,0x2300,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c3\n  0x1100,0x1100,0x1100,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c4\n  0x0e00,0x1100,0x1100,0x0e00,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c5\n  0x0000,0x0000,0x0000,0x0000,0x3fe0,0x4400,0x8400,0x8400,0x8400,0x8400,0x8400,0xffc0,0x8400,0x8400,0x8400,0x8400,\n  0x8400,0x8400,0x87e0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c6\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4040,\n  0x4040,0x2080,0x1f00,0x0400,0x0400,0x0400,0x0800,0x0000, // u00c7\n  0x1000,0x0800,0x0400,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c8\n  0x0100,0x0200,0x0400,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c9\n  0x0400,0x0a00,0x1100,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ca\n  0x1100,0x1100,0x1100,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cb\n  0x1000,0x0800,0x0400,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cc\n  0x0100,0x0200,0x0400,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cd\n  0x0400,0x0a00,0x1100,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ce\n  0x1100,0x1100,0x1100,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cf\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0xfc40,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4080,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d0\n  0x1880,0x2480,0x2300,0x0000,0x4040,0x4040,0x4040,0x4040,0x6040,0x5040,0x4840,0x4440,0x4240,0x4140,0x40c0,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d1\n  0x1000,0x0800,0x0400,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d2\n  0x0100,0x0200,0x0400,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d3\n  0x0400,0x0a00,0x1100,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d4\n  0x1880,0x2480,0x2300,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d5\n  0x1100,0x1100,0x1100,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x2080,0x1100,0x0a00,0x0400,0x0a00,0x1100,0x2080,0x4040,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d7\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4060,0x4040,0x40c0,0x4140,0x4240,0x4440,0x4840,0x5040,0x6040,0x4040,\n  0xc040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d8\n  0x1000,0x0800,0x0400,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d9\n  0x0100,0x0200,0x0400,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00da\n  0x0400,0x0a00,0x1100,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00db\n  0x1100,0x1100,0x1100,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00dc\n  0x0100,0x0200,0x0400,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0a00,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u00dd\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4080,0x7f00,0x4000,\n  0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00de\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4080,0x4080,0x4080,0x4100,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,\n  0x6040,0x5080,0x4f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00df\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x0800,0x0400,0x0000,0x3f00,0x0080,0x0040,0x0040,0x1fc0,0x2040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e0\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x3f00,0x0080,0x0040,0x0040,0x1fc0,0x2040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e1\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0a00,0x1100,0x0000,0x3f00,0x0080,0x0040,0x0040,0x1fc0,0x2040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e2\n  0x0000,0x0000,0x0000,0x0000,0x1880,0x2480,0x2300,0x0000,0x3f00,0x0080,0x0040,0x0040,0x1fc0,0x2040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e3\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,0x0000,0x3f00,0x0080,0x0040,0x0040,0x1fc0,0x2040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e4\n  0x0000,0x0000,0x0000,0x0000,0x0e00,0x1100,0x1100,0x0e00,0x3f00,0x0080,0x0040,0x0040,0x1fc0,0x2040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7bc0,0x0420,0x0420,0x0420,0x7c20,0x87e0,0x8400,0x8400,\n  0x8400,0x8420,0x7bc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4040,0x2080,0x1f00,0x0400,0x0400,0x0400,0x0800,0x0000, // u00e7\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x0800,0x0400,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x7fc0,0x4000,0x4000,\n  0x4000,0x2040,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e8\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x7fc0,0x4000,0x4000,\n  0x4000,0x2040,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e9\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0a00,0x1100,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x7fc0,0x4000,0x4000,\n  0x4000,0x2040,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ea\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x7fc0,0x4000,0x4000,\n  0x4000,0x2040,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00eb\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x0800,0x0400,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ec\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ed\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0a00,0x1100,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ee\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ef\n  0x0000,0x0000,0x0000,0x0000,0x1600,0x0800,0x3400,0x0200,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f0\n  0x0000,0x0000,0x0000,0x0000,0x1880,0x2480,0x2300,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f1\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x0800,0x0400,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f2\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f3\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0a00,0x1100,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f4\n  0x0000,0x0000,0x0000,0x0000,0x1880,0x2480,0x2300,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f5\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0400,0x0400,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f20,0x20c0,0x40c0,0x4140,0x4240,0x4440,0x4840,0x5040,\n  0x6040,0x6080,0x9f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f8\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x0800,0x0400,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f9\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00fa\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0a00,0x1100,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00fb\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00fc\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x20c0,0x1f40,0x0040,0x0040,0x0080,0x3f00,0x0000, // u00fd\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4080,0x7f00,0x4000,0x4000,0x4000,0x4000,0x0000, // u00fe\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x20c0,0x1f40,0x0040,0x0040,0x0080,0x3f00,0x0000, // u00ff\n  0x0000,0x3f80,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0100\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x0000,0x3f00,0x0080,0x0040,0x0040,0x1fc0,0x2040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0101\n  0x2080,0x2080,0x1f00,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0102\n  0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x1f00,0x0000,0x3f00,0x0080,0x0040,0x0040,0x1fc0,0x2040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0103\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0080,0x0100,0x0100,0x00e0,0x0000, // u0104\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0080,0x0040,0x0040,0x1fc0,0x2040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0080,0x0100,0x0100,0x00e0,0x0000, // u0105\n  0x0100,0x0200,0x0400,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0106\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x1f00,0x2080,0x4040,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0107\n  0x0400,0x0a00,0x1100,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0108\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0a00,0x1100,0x0000,0x1f00,0x2080,0x4040,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0109\n  0x0400,0x0400,0x0400,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u010a\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x1f00,0x2080,0x4040,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u010b\n  0x1100,0x0a00,0x0400,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u010c\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x0a00,0x0400,0x0000,0x1f00,0x2080,0x4040,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u010d\n  0x1100,0x0a00,0x0400,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4080,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u010e\n  0x1100,0x0a00,0x0400,0x0000,0x0040,0x0040,0x0040,0x0040,0x1fc0,0x2040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u010f\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0xfc40,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4080,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0110\n  0x0000,0x0000,0x0000,0x0000,0x0040,0x07e0,0x0040,0x0040,0x1fc0,0x2040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0111\n  0x0000,0x3f80,0x0000,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0112\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x7fc0,0x4000,0x4000,\n  0x4000,0x2040,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0113\n  0x2080,0x2080,0x1f00,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0114\n  0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x1f00,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x7fc0,0x4000,0x4000,\n  0x4000,0x2040,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0115\n  0x0400,0x0400,0x0400,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0116\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x7fc0,0x4000,0x4000,\n  0x4000,0x2040,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0117\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0080,0x0100,0x0100,0x00e0,0x0000, // u0118\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x7fc0,0x4000,0x4000,\n  0x4000,0x2040,0x1f80,0x0200,0x0400,0x0400,0x0380,0x0000, // u0119\n  0x1100,0x0a00,0x0400,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u011a\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x0a00,0x0400,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x7fc0,0x4000,0x4000,\n  0x4000,0x2040,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u011b\n  0x0400,0x0a00,0x1100,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4000,0x4000,0x4000,0x47c0,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u011c\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0a00,0x1100,0x0000,0x1fc0,0x2040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x20c0,0x1f40,0x0040,0x0040,0x0080,0x3f00,0x0000, // u011d\n  0x2080,0x2080,0x1f00,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4000,0x4000,0x4000,0x47c0,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u011e\n  0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x1f00,0x0000,0x1fc0,0x2040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x20c0,0x1f40,0x0040,0x0040,0x0080,0x3f00,0x0000, // u011f\n  0x0400,0x0400,0x0400,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4000,0x4000,0x4000,0x47c0,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0120\n  0x0000,0x0000,0x0000,0x0000,0x0200,0x0200,0x0200,0x0000,0x1fc0,0x2040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x20c0,0x1f40,0x0040,0x0040,0x0080,0x3f00,0x0000, // u0121\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4000,0x4000,0x4000,0x47c0,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0400,0x0400,0x0400,0x0800, // u0122\n  0x0000,0x0000,0x0000,0x0100,0x0200,0x0200,0x0200,0x0000,0x1fc0,0x2040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x20c0,0x1f40,0x0040,0x0040,0x0080,0x3f00,0x0000, // u0123\n  0x0400,0x0a00,0x1100,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0124\n  0x0400,0x0a00,0x1100,0x0000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0125\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0xffe0,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0126\n  0x0000,0x0000,0x0000,0x0000,0x4000,0xfc00,0x4000,0x4000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0127\n  0x1880,0x2480,0x2300,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0128\n  0x0000,0x0000,0x0000,0x0000,0x1880,0x2480,0x2300,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0129\n  0x0000,0x3f80,0x0000,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u012a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u012b\n  0x2080,0x2080,0x1f00,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u012c\n  0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x1f00,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u012d\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0400,0x0800,0x0800,0x0700,0x0000, // u012e\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0400,0x0800,0x0800,0x0700,0x0000, // u012f\n  0x0400,0x0400,0x0400,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0130\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0131\n  0x0000,0x0000,0x0000,0x0000,0xe0e0,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4840,0x4840,\n  0x4840,0x4840,0xe780,0x0000,0x0000,0x0000,0x0000,0x0000, // u0132\n  0x0000,0x0000,0x0000,0x0000,0x2020,0x2020,0x2020,0x0000,0x6060,0x2020,0x2020,0x2020,0x2020,0x2020,0x2020,0x2020,\n  0x2020,0x2020,0x7020,0x0420,0x0420,0x0420,0x03c0,0x0000, // u0133\n  0x0080,0x0140,0x0220,0x0000,0x03e0,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x4080,0x4080,\n  0x4080,0x2100,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0134\n  0x0000,0x0000,0x0000,0x0000,0x0080,0x0140,0x0220,0x0000,0x0380,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,\n  0x0080,0x0080,0x0080,0x2080,0x2080,0x1100,0x0e00,0x0000, // u0135\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4080,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x5000,0x4800,0x4400,0x4200,\n  0x4100,0x4080,0x4040,0x0000,0x0400,0x0400,0x0400,0x0800, // u0136\n  0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x2000,0x2040,0x2080,0x2100,0x2200,0x2400,0x3800,0x2400,0x2200,\n  0x2100,0x2080,0x2040,0x0000,0x0400,0x0400,0x0400,0x0800, // u0137\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2040,0x2080,0x2100,0x2200,0x2400,0x3800,0x2400,0x2200,\n  0x2100,0x2080,0x2040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0138\n  0x1000,0x2000,0x4000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0139\n  0x0100,0x0200,0x0400,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u013a\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0400,0x0400,0x0400,0x0800, // u013b\n  0x0000,0x0000,0x0000,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0400,0x0400,0x0400,0x0800, // u013c\n  0x1100,0x0a00,0x0400,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u013d\n  0x1100,0x0a00,0x0400,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u013e\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4100,0x4100,0x4100,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u013f\n  0x0000,0x0000,0x0000,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0410,0x0410,0x0410,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0140\n  0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2800,0x3000,0x2000,0x6000,0xa000,0x2000,0x2000,\n  0x2000,0x2000,0x3fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0141\n  0x0000,0x0000,0x0000,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0500,0x0600,0x0400,0x0c00,0x1400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0142\n  0x0100,0x0200,0x0400,0x0000,0x4040,0x4040,0x4040,0x4040,0x6040,0x5040,0x4840,0x4440,0x4240,0x4140,0x40c0,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0143\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0144\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x6040,0x5040,0x4840,0x4440,0x4240,0x4140,0x40c0,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0400,0x0400,0x0400,0x0800, // u0145\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0400,0x0400,0x0400,0x0800, // u0146\n  0x1100,0x0a00,0x0400,0x0000,0x4040,0x4040,0x4040,0x4040,0x6040,0x5040,0x4840,0x4440,0x4240,0x4140,0x40c0,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0147\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x0a00,0x0400,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0148\n  0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x8000,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0149\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x6040,0x5040,0x4840,0x4440,0x4240,0x4140,0x40c0,0x4040,\n  0x4040,0x4040,0x4040,0x0040,0x0040,0x0080,0x0300,0x0000, // u014a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0040,0x0040,0x0080,0x0300,0x0000, // u014b\n  0x0000,0x3f80,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u014c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u014d\n  0x2080,0x2080,0x1f00,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u014e\n  0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x1f00,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u014f\n  0x0440,0x0880,0x1100,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0150\n  0x0000,0x0000,0x0000,0x0000,0x0440,0x0880,0x1100,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0151\n  0x0000,0x0000,0x0000,0x0000,0x3fe0,0x4400,0x8400,0x8400,0x8400,0x8400,0x8400,0x87c0,0x8400,0x8400,0x8400,0x8400,\n  0x8400,0x4400,0x3fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0152\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x4440,0x8420,0x8420,0x8420,0x87e0,0x8400,0x8400,\n  0x8400,0x4420,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0153\n  0x0100,0x0200,0x0400,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4080,0x7f00,0x5000,0x4800,0x4400,0x4200,\n  0x4100,0x4080,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0154\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x47c0,0x4800,0x5000,0x6000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0155\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4080,0x7f00,0x5000,0x4800,0x4400,0x4200,\n  0x4100,0x4080,0x4040,0x0000,0x0400,0x0400,0x0400,0x0800, // u0156\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x47c0,0x4800,0x5000,0x6000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x4000,0x0000,0x4000,0x4000,0x4000,0x8000, // u0157\n  0x1100,0x0a00,0x0400,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4080,0x7f00,0x5000,0x4800,0x4400,0x4200,\n  0x4100,0x4080,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0158\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x0a00,0x0400,0x0000,0x47c0,0x4800,0x5000,0x6000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0159\n  0x0100,0x0200,0x0400,0x0000,0x1f00,0x2080,0x4040,0x4000,0x4000,0x4000,0x2000,0x1f00,0x0080,0x0040,0x0040,0x0040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u015a\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x3f80,0x4040,0x4000,0x4000,0x4000,0x3f80,0x0040,0x0040,\n  0x0040,0x4040,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u015b\n  0x0400,0x0a00,0x1100,0x0000,0x1f00,0x2080,0x4040,0x4000,0x4000,0x4000,0x2000,0x1f00,0x0080,0x0040,0x0040,0x0040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u015c\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0a00,0x1100,0x0000,0x3f80,0x4040,0x4000,0x4000,0x4000,0x3f80,0x0040,0x0040,\n  0x0040,0x4040,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u015d\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4000,0x4000,0x4000,0x2000,0x1f00,0x0080,0x0040,0x0040,0x0040,\n  0x4040,0x2080,0x1f00,0x0400,0x0400,0x0400,0x0800,0x0000, // u015e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x4040,0x4000,0x4000,0x4000,0x3f80,0x0040,0x0040,\n  0x0040,0x4040,0x3f80,0x0400,0x0400,0x0400,0x0800,0x0000, // u015f\n  0x1100,0x0a00,0x0400,0x0000,0x1f00,0x2080,0x4040,0x4000,0x4000,0x4000,0x2000,0x1f00,0x0080,0x0040,0x0040,0x0040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0160\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x0a00,0x0400,0x0000,0x3f80,0x4040,0x4000,0x4000,0x4000,0x3f80,0x0040,0x0040,\n  0x0040,0x4040,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0161\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0200,0x0200,0x0200,0x0400,0x0000, // u0162\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x3f80,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x03c0,0x0100,0x0100,0x0100,0x0200,0x0000, // u0163\n  0x1100,0x0a00,0x0400,0x0000,0x7fc0,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u0164\n  0x1100,0x0a00,0x0400,0x0000,0x0400,0x0400,0x0400,0x0400,0x3f80,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0165\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x3f80,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u0166\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x3f80,0x0400,0x0400,0x1f00,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0167\n  0x1880,0x2480,0x2300,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0168\n  0x0000,0x0000,0x0000,0x0000,0x1880,0x2480,0x2300,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0169\n  0x0000,0x3f80,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u016a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u016b\n  0x2080,0x2080,0x1f00,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u016c\n  0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x1f00,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u016d\n  0x0e00,0x1100,0x1100,0x0e00,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u016e\n  0x0000,0x0000,0x0000,0x0000,0x0e00,0x1100,0x1100,0x0e00,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u016f\n  0x0440,0x0880,0x1100,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0170\n  0x0000,0x0000,0x0000,0x0000,0x0440,0x0880,0x1100,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0171\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0400,0x0800,0x0800,0x0700,0x0000, // u0172\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0080,0x0100,0x0100,0x00e0,0x0000, // u0173\n  0x0400,0x0a00,0x1100,0x0000,0x4020,0x4020,0x4020,0x4020,0x4020,0x4020,0x4020,0x4020,0x4620,0x4620,0x4920,0x50a0,\n  0x50a0,0x6060,0x4020,0x0000,0x0000,0x0000,0x0000,0x0000, // u0174\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0a00,0x1100,0x0000,0x4040,0x4040,0x4040,0x4040,0x4440,0x4440,0x4440,0x4440,\n  0x4440,0x4440,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0175\n  0x0400,0x0a00,0x1100,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0a00,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u0176\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0a00,0x1100,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x20c0,0x1f40,0x0040,0x0040,0x0080,0x3f00,0x0000, // u0177\n  0x1100,0x1100,0x1100,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0a00,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u0178\n  0x0100,0x0200,0x0400,0x0000,0x7fc0,0x0040,0x0040,0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0179\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x7fc0,0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,\n  0x2000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u017a\n  0x0400,0x0400,0x0400,0x0000,0x7fc0,0x0040,0x0040,0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u017b\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x7fc0,0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,\n  0x2000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u017c\n  0x1100,0x0a00,0x0400,0x0000,0x7fc0,0x0040,0x0040,0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u017d\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x0a00,0x0400,0x0000,0x7fc0,0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,\n  0x2000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u017e\n  0x0000,0x0000,0x0000,0x0000,0x03c0,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u017f\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0186\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x1fc0,0x0040,0x0040,0x0040,0x0040,\n  0x0040,0x0040,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u018e\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x0040,0x0040,0x0040,0x0040,0x7fc0,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u018f\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4000,0x4000,0x4000,0x2000,0x1e00,0x2000,0x4000,0x4000,0x4000,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0190\n  0x0000,0x0000,0x0000,0x0000,0x0380,0x0440,0x0440,0x0400,0x0400,0x0400,0x3f80,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x4400,0x4400,0x3800,0x0000, // u0192\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x6040,0x5040,0x4840,0x4440,0x4240,0x4140,0x40c0,0x4040,\n  0x4040,0x4040,0x4040,0x4000,0x4000,0x4000,0x8000,0x0000, // u019d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0040,0x0040,0x0040,0x0040,0x0000, // u019e\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0040,0x0040,0x0040,0x0080,0x0100,0x0200,0x7fc0,0x0400,0x0800,0x1000,0x2000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0040,0x0080,0x0100,0x0200,0x7fc0,0x0800,0x1000,\n  0x2000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01b6\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0040,0x0080,0x0100,0x0200,0x0400,0x0f00,0x0080,0x0040,0x0040,0x0040,0x0040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01b7\n  0x1100,0x0a00,0x0400,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u01cd\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x0a00,0x0400,0x0000,0x3f00,0x0080,0x0040,0x0040,0x1fc0,0x2040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01ce\n  0x1100,0x0a00,0x0400,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01cf\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x0a00,0x0400,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d0\n  0x1100,0x0a00,0x0400,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d1\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x0a00,0x0400,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d2\n  0x1100,0x0a00,0x0400,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d3\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x0a00,0x0400,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d4\n  0x0000,0x3fc0,0x0000,0x0000,0x3fe0,0x4400,0x8400,0x8400,0x8400,0x8400,0x8400,0xffc0,0x8400,0x8400,0x8400,0x8400,\n  0x8400,0x8400,0x87e0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x0000,0x0000,0x7bc0,0x0420,0x0420,0x0420,0x7c20,0x87e0,0x8400,0x8400,\n  0x8400,0x8420,0x7bc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e3\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4000,0x4000,0x4000,0x47c0,0x4040,0x4040,0x43e0,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x2040,0x4040,0x4040,0x4040,0x43e0,0x4040,0x4040,\n  0x4040,0x20c0,0x1f40,0x0040,0x0040,0x0080,0x3f00,0x0000, // u01e5\n  0x1100,0x0a00,0x0400,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4000,0x4000,0x4000,0x47c0,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e6\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x0a00,0x0400,0x0000,0x1fc0,0x2040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x20c0,0x1f40,0x0040,0x0040,0x0080,0x3f00,0x0000, // u01e7\n  0x1100,0x0a00,0x0400,0x0000,0x4040,0x4080,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x5000,0x4800,0x4400,0x4200,\n  0x4100,0x4080,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e8\n  0x1100,0x0a00,0x0400,0x0000,0x2000,0x2000,0x2000,0x2000,0x2040,0x2080,0x2100,0x2200,0x2400,0x3800,0x2400,0x2200,\n  0x2100,0x2080,0x2040,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e9\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0400,0x0800,0x0800,0x0700,0x0000, // u01ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0400,0x0800,0x0800,0x0700,0x0000, // u01eb\n  0x0000,0x3f80,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0400,0x0800,0x0800,0x0700,0x0000, // u01ec\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0400,0x0800,0x0800,0x0700,0x0000, // u01ed\n  0x1100,0x0a00,0x0400,0x0000,0x7fc0,0x0040,0x0080,0x0100,0x0200,0x0400,0x0f00,0x0080,0x0040,0x0040,0x0040,0x0040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01ee\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x0a00,0x0400,0x0000,0x7fc0,0x0040,0x0080,0x0100,0x0200,0x0400,0x0f00,0x0080,\n  0x0040,0x0040,0x0040,0x0040,0x4040,0x2080,0x1f00,0x0000, // u01ef\n  0x0000,0x0000,0x0000,0x0000,0x0220,0x0140,0x0080,0x0000,0x0380,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,\n  0x0080,0x0080,0x0080,0x2080,0x2080,0x1100,0x0e00,0x0000, // u01f0\n  0x0100,0x0200,0x0400,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4000,0x4000,0x4000,0x47c0,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01f4\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x1fc0,0x2040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x20c0,0x1f40,0x0040,0x0040,0x0080,0x3f00,0x0000, // u01f5\n  0x0100,0x0200,0x0400,0x0000,0x3fe0,0x4400,0x8400,0x8400,0x8400,0x8400,0x8400,0xffc0,0x8400,0x8400,0x8400,0x8400,\n  0x8400,0x8400,0x87e0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01fc\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x7bc0,0x0420,0x0420,0x0420,0x7c20,0x87e0,0x8400,0x8400,\n  0x8400,0x8420,0x7bc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01fd\n  0x0100,0x0200,0x0400,0x0000,0x1f00,0x2080,0x4060,0x4040,0x40c0,0x4140,0x4240,0x4440,0x4840,0x5040,0x6040,0x4040,\n  0xc040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01fe\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x1f20,0x20c0,0x40c0,0x4140,0x4240,0x4440,0x4840,0x5040,\n  0x6040,0x6080,0x9f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u01ff\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4000,0x4000,0x4000,0x2000,0x1f00,0x0080,0x0040,0x0040,0x0040,\n  0x4040,0x2080,0x1f00,0x0000,0x0400,0x0400,0x0400,0x0800, // u0218\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x4040,0x4000,0x4000,0x4000,0x3f80,0x0040,0x0040,\n  0x0040,0x4040,0x3f80,0x0000,0x0400,0x0400,0x0400,0x0800, // u0219\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0400,0x0400,0x0400,0x0800, // u021a\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x3f80,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x03c0,0x0000,0x0100,0x0100,0x0100,0x0200, // u021b\n  0x0000,0x3f80,0x0000,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0a00,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u0232\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x20c0,0x1f40,0x0040,0x0040,0x0080,0x3f00,0x0000, // u0233\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,\n  0x0080,0x0080,0x0080,0x2080,0x2080,0x1100,0x0e00,0x0000, // u0237\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x0040,0x0040,0x0040,0x0040,0x0040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0254\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x7fc0,0x0040,0x0040,\n  0x0040,0x4080,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0258\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x4080,0x0040,0x0040,0x0040,0x7fc0,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0259\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x4040,0x4000,0x4000,0x4000,0x3e00,0x4000,0x4000,\n  0x4000,0x4040,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u025b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x4000,0x4000,0x4000,0x8000,0x0000, // u0272\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0040,0x0080,0x0100,0x0200,0x0400,0x0f00,0x0080,\n  0x0040,0x0040,0x0040,0x0040,0x4040,0x2080,0x1f00,0x0000, // u0292\n  0x0200,0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bb\n  0x0400,0x0400,0x0400,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bc\n  0x0400,0x0400,0x0400,0x0200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bd\n  0x0400,0x0a00,0x1100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02c6\n  0x1100,0x0a00,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02c7\n  0x2080,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02d8\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02d9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0400,0x0800,0x0800,0x0700,0x0000, // u02db\n  0x1880,0x2480,0x2300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02dc\n  0x0440,0x0880,0x1100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02dd\n  0x1000,0x0800,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0300\n  0x0100,0x0200,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0301\n  0x0400,0x0a00,0x1100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0302\n  0x1880,0x2480,0x2300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0303\n  0x0000,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0304\n  0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0305\n  0x2080,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0306\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0307\n  0x1100,0x1100,0x1100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0308\n  0x0e00,0x1100,0x1100,0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030a\n  0x0440,0x0880,0x1100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030b\n  0x1100,0x0a00,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000, // u0329\n  0x0000,0x2000,0x4000,0x8000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0384\n  0x0100,0x0200,0x0400,0x0000,0x1100,0x1100,0x1100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0385\n  0x0000,0x2000,0x4000,0x8000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0386\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0387\n  0x0000,0x2000,0x4000,0x8000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0388\n  0x0000,0x2000,0x4000,0x8000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0389\n  0x0000,0x2000,0x4000,0x8000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u038a\n  0x0000,0x2000,0x4000,0x8000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u038c\n  0x0000,0x2000,0x4000,0x8000,0x2020,0x2020,0x1040,0x1040,0x0880,0x0880,0x0500,0x0500,0x0200,0x0200,0x0200,0x0200,\n  0x0200,0x0200,0x0200,0x0000,0x0000,0x0000,0x0000,0x0000, // u038e\n  0x0000,0x2000,0x4000,0x8000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x2080,\n  0x1100,0x1100,0x71c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u038f\n  0x0100,0x0200,0x0400,0x0000,0x1100,0x1100,0x1100,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000, // u0390\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0391\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4080,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4080,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0392\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0393\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0a00,0x0a00,0x0a00,0x1100,0x1100,0x1100,0x2080,0x2080,0x2080,\n  0x4040,0x4040,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0394\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0395\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0040,0x0040,0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0396\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0397\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x5f40,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0398\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0399\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4080,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x5000,0x4800,0x4400,0x4200,\n  0x4100,0x4080,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u039a\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0a00,0x0a00,0x0a00,0x1100,0x1100,0x1100,0x2080,0x2080,0x2080,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u039b\n  0x0000,0x0000,0x0000,0x0000,0x4020,0x6060,0x50a0,0x50a0,0x4920,0x4620,0x4620,0x4020,0x4020,0x4020,0x4020,0x4020,\n  0x4020,0x4020,0x4020,0x0000,0x0000,0x0000,0x0000,0x0000, // u039c\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x6040,0x5040,0x4840,0x4440,0x4240,0x4140,0x40c0,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u039d\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u039e\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u039f\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a0\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4080,0x7f00,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a1\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,0x0200,0x0400,0x0800,0x1000,\n  0x2000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a3\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a4\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0a00,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a5\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x1f00,0x2480,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,\n  0x2480,0x1f00,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a6\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0400,0x0a00,0x1100,0x1100,0x2080,\n  0x2080,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a7\n  0x0000,0x0000,0x0000,0x0000,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x2480,0x1f00,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a8\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x2080,\n  0x1100,0x1100,0x71c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a9\n  0x1100,0x1100,0x1100,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03aa\n  0x1100,0x1100,0x1100,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0a00,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ab\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x1e60,0x21c0,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x21c0,0x1e60,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ac\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x3f80,0x4040,0x4000,0x4000,0x4000,0x3e00,0x4000,0x4000,\n  0x4000,0x4040,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ad\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0040,0x0040,0x0040,0x0040,0x0000, // u03ae\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000, // u03af\n  0x0100,0x0200,0x0400,0x0000,0x1100,0x1100,0x1100,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e60,0x21c0,0x4080,0x4080,0x4080,0x4080,0x4080,0x4080,\n  0x4080,0x21c0,0x1e60,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b1\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4080,0x4080,0x4080,0x4100,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4080,0x7f00,0x4000,0x4000,0x4000,0x4000,0x0000, // u03b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x2080,0x2080,0x2080,0x1100,0x1100,\n  0x0a00,0x0a00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0000, // u03b3\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x0800,0x0400,0x0200,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x4040,0x4000,0x4000,0x4000,0x3e00,0x4000,0x4000,\n  0x4000,0x4040,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b5\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x2000,0x4000,0x4000,0x4000,\n  0x4000,0x2000,0x1f80,0x0040,0x0040,0x0040,0x0180,0x0000, // u03b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0040,0x0040,0x0040,0x0040,0x0000, // u03b7\n  0x0000,0x0000,0x0000,0x0000,0x0f00,0x1080,0x2040,0x2040,0x2040,0x2040,0x2040,0x3fc0,0x2040,0x2040,0x2040,0x2040,\n  0x2040,0x1080,0x0f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2040,0x2080,0x2100,0x2200,0x2400,0x3800,0x2400,0x2200,\n  0x2100,0x2080,0x2040,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ba\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x0800,0x0800,0x0400,0x0400,0x0a00,0x0a00,0x1100,0x1100,0x2080,0x2080,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u03bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x40c0,0x4140,0x7e40,0x4000,0x4000,0x4000,0x4000,0x0000, // u03bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,\n  0x0a00,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u03bd\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x2000,0x4000,0x4000,0x4000,0x2000,0x1f80,0x2000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x2000,0x1f80,0x0040,0x0040,0x0040,0x0180,0x0000, // u03be\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x6080,0x5f00,0x4000,0x4000,0x4000,0x4000,0x0000, // u03c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x2000,0x1f80,0x0040,0x0040,0x0040,0x0180,0x0000, // u03c2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fe0,0x2100,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2380,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,\n  0x4440,0x2480,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0000, // u03c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0400,\n  0x0a00,0x1100,0x1100,0x2080,0x2080,0x4040,0x4040,0x0000, // u03c7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,\n  0x4440,0x2480,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0000, // u03c8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x4040,0x4040,0x4040,0x4440,0x4440,0x4440,0x4440,\n  0x4440,0x4440,0x3b80,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c9\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ca\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03cb\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03cc\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03cd\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x2080,0x4040,0x4040,0x4040,0x4440,0x4440,0x4440,0x4440,\n  0x4440,0x4440,0x3b80,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ce\n  0x0000,0x0000,0x0000,0x0000,0x0f00,0x1080,0x2040,0x2040,0x2040,0x1040,0x0fe0,0x0040,0x0040,0xe040,0x2040,0x2040,\n  0x2040,0x1080,0x0f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x1f00,0x2480,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,\n  0x4440,0x2480,0x1f00,0x0400,0x0400,0x0000,0x0000,0x0000, // u03d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7020,0x0840,0x0480,0x0500,0x0200,0x0600,0x0400,0x0a00,\n  0x1200,0x2100,0x40e0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x6080,0x5f00,0x4000,0x4000,0x2000,0x1f80,0x0000, // u03f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f2\n  0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0380,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,\n  0x0080,0x0080,0x0080,0x2080,0x2080,0x1100,0x0e00,0x0000, // u03f3\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x1000,0x2000,0x4000,0x4000,0x7f00,0x4000,0x4000,\n  0x2000,0x1000,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0100,0x0080,0x0040,0x0040,0x1fc0,0x0040,0x0040,\n  0x0080,0x0100,0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f6\n  0x1000,0x0800,0x0400,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0400\n  0x1100,0x1100,0x1100,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0401\n  0x0000,0x0000,0x0000,0x0000,0xf800,0x2000,0x2000,0x2000,0x2000,0x3f00,0x2080,0x2040,0x2040,0x2040,0x2040,0x2040,\n  0x2040,0x2080,0x2300,0x0000,0x0000,0x0000,0x0000,0x0000, // u0402\n  0x0100,0x0200,0x0400,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0403\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4000,0x4000,0x4000,0x4000,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0404\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4000,0x4000,0x4000,0x2000,0x1f00,0x0080,0x0040,0x0040,0x0040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0405\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0406\n  0x1100,0x1100,0x1100,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0407\n  0x0000,0x0000,0x0000,0x0000,0x03e0,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x4080,0x4080,\n  0x4080,0x2100,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0408\n  0x0000,0x0000,0x0000,0x0000,0x3c00,0x4400,0x8400,0x8400,0x8400,0x8400,0x8780,0x8440,0x8420,0x8420,0x8420,0x8420,\n  0x8420,0x8440,0x8780,0x0000,0x0000,0x0000,0x0000,0x0000, // u0409\n  0x0000,0x0000,0x0000,0x0000,0x8400,0x8400,0x8400,0x8400,0x8400,0x8400,0x8780,0xfc40,0x8420,0x8420,0x8420,0x8420,\n  0x8420,0x8440,0x8780,0x0000,0x0000,0x0000,0x0000,0x0000, // u040a\n  0x0000,0x0000,0x0000,0x0000,0xf800,0x2000,0x2000,0x2000,0x2000,0x3f00,0x2080,0x2040,0x2040,0x2040,0x2040,0x2040,\n  0x2040,0x2040,0x2040,0x0000,0x0000,0x0000,0x0000,0x0000, // u040b\n  0x0100,0x0200,0x0400,0x0000,0x4040,0x4080,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x5000,0x4800,0x4400,0x4200,\n  0x4100,0x4080,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u040c\n  0x1000,0x0800,0x0400,0x0000,0x4040,0x4040,0x4040,0x4040,0x40c0,0x4140,0x4240,0x4440,0x4840,0x5040,0x6040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u040d\n  0x2080,0x2080,0x1f00,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x2040,0x1fc0,0x0040,0x0040,0x0040,\n  0x0040,0x0080,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u040e\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x7fc0,0x0400,0x0400,0x0400,0x0000,0x0000, // u040f\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0410\n  0x0000,0x0000,0x0000,0x0000,0x7f80,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4080,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0411\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4080,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4080,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0412\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0413\n  0x0000,0x0000,0x0000,0x0000,0x07c0,0x0840,0x1040,0x1040,0x1040,0x1040,0x1040,0x1040,0x1040,0x1040,0x1040,0x1040,\n  0x1040,0x2040,0x7fe0,0x4020,0x4020,0x4020,0x0000,0x0000, // u0414\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0415\n  0x0000,0x0000,0x0000,0x0000,0x4440,0x4440,0x4440,0x4440,0x4440,0x2480,0x1500,0x0e00,0x1500,0x2480,0x4440,0x4440,\n  0x4440,0x4440,0x4440,0x0000,0x0000,0x0000,0x0000,0x0000, // u0416\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x0040,0x0040,0x0040,0x0080,0x0f00,0x0080,0x0040,0x0040,0x0040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0417\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x40c0,0x4140,0x4240,0x4440,0x4840,0x5040,0x6040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0418\n  0x2080,0x2080,0x1f00,0x0000,0x4040,0x4040,0x4040,0x4040,0x40c0,0x4140,0x4240,0x4440,0x4840,0x5040,0x6040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0419\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4080,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x5000,0x4800,0x4400,0x4200,\n  0x4100,0x4080,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u041a\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x1040,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,\n  0x2040,0x4040,0x8040,0x0000,0x0000,0x0000,0x0000,0x0000, // u041b\n  0x0000,0x0000,0x0000,0x0000,0x4020,0x6060,0x50a0,0x50a0,0x4920,0x4620,0x4620,0x4020,0x4020,0x4020,0x4020,0x4020,\n  0x4020,0x4020,0x4020,0x0000,0x0000,0x0000,0x0000,0x0000, // u041c\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u041d\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u041e\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u041f\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4080,0x7f00,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0420\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0421\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u0422\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x2040,0x1fc0,0x0040,0x0040,0x0040,\n  0x0040,0x0080,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0423\n  0x0000,0x0000,0x0000,0x0400,0x1f00,0x2480,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,\n  0x4440,0x2480,0x1f00,0x0400,0x0000,0x0000,0x0000,0x0000, // u0424\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0400,0x0a00,0x1100,0x1100,0x2080,\n  0x2080,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0425\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2040,0x1fe0,0x0020,0x0020,0x0020,0x0000,0x0000, // u0426\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x2040,0x1fc0,0x0040,0x0040,0x0040,0x0040,\n  0x0040,0x0040,0x0040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0427\n  0x0000,0x0000,0x0000,0x0000,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,\n  0x4440,0x2440,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0428\n  0x0000,0x0000,0x0000,0x0000,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,\n  0x4440,0x2440,0x1fe0,0x0020,0x0020,0x0020,0x0000,0x0000, // u0429\n  0x0000,0x0000,0x0000,0x0000,0xc000,0xc000,0x4000,0x4000,0x4000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4080,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u042a\n  0x0000,0x0000,0x0000,0x0000,0x4020,0x4020,0x4020,0x4020,0x4020,0x7c20,0x4220,0x4120,0x4120,0x4120,0x4120,0x4120,\n  0x4120,0x4220,0x7c20,0x0000,0x0000,0x0000,0x0000,0x0000, // u042b\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4080,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u042c\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x0040,0x0040,0x0040,0x0040,0x0fc0,0x0040,0x0040,0x0040,0x0040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u042d\n  0x0000,0x0000,0x0000,0x0000,0x43c0,0x4420,0x4420,0x4420,0x4420,0x4420,0x4420,0x7c20,0x4420,0x4420,0x4420,0x4420,\n  0x4420,0x4420,0x43c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u042e\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x2040,0x4040,0x4040,0x4040,0x4040,0x2040,0x1fc0,0x0140,0x0240,0x0440,0x0840,\n  0x1040,0x2040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u042f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x0080,0x0040,0x0040,0x1fc0,0x2040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0430\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x2000,0x4000,0x4000,0x4000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4080,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0431\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x4100,0x4080,0x4080,0x4080,0x4100,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4080,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0432\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0433\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x2040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x20c0,0x1f40,0x0040,0x0040,0x0080,0x3f00,0x0000, // u0434\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x7fc0,0x4000,0x4000,\n  0x4000,0x2040,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0435\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4440,0x4440,0x4440,0x2480,0x1500,0x0e00,0x1500,0x2480,\n  0x4440,0x4440,0x4440,0x0000,0x0000,0x0000,0x0000,0x0000, // u0436\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x4040,0x0040,0x0040,0x0040,0x0f80,0x0040,0x0040,\n  0x0040,0x4040,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0437\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0438\n  0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x1f00,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0439\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2040,0x2080,0x2100,0x2200,0x2400,0x3800,0x2400,0x2200,\n  0x2100,0x2080,0x2040,0x0000,0x0000,0x0000,0x0000,0x0000, // u043a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x1040,0x2040,0x2040,0x2040,0x2040,0x2040,0x2040,\n  0x2040,0x2040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u043b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x60c0,0x5140,0x4a40,0x4440,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u043c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u043d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u043e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u043f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4080,0x7f00,0x4000,0x4000,0x4000,0x4000,0x0000, // u0440\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0441\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u0442\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x20c0,0x1f40,0x0040,0x0040,0x0080,0x3f00,0x0000, // u0443\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x1f00,0x2480,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,\n  0x4440,0x2480,0x1f00,0x0400,0x0400,0x0000,0x0000,0x0000, // u0444\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x2080,0x1100,0x0a00,0x0400,0x0a00,0x1100,\n  0x2080,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0445\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2040,0x1fe0,0x0020,0x0020,0x0020,0x0000,0x0000, // u0446\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x2040,0x1fc0,0x0040,0x0040,\n  0x0040,0x0040,0x0040,0x0000,0x0000,0x0000,0x0000,0x0000, // u0447\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,\n  0x4440,0x2440,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0448\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,\n  0x4440,0x2440,0x1fe0,0x0020,0x0020,0x0020,0x0000,0x0000, // u0449\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xe000,0x2000,0x2000,0x3f00,0x2080,0x2040,0x2040,0x2040,\n  0x2040,0x2080,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u044a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x7840,0x4440,0x4240,0x4240,0x4240,\n  0x4240,0x4440,0x7840,0x0000,0x0000,0x0000,0x0000,0x0000, // u044b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x3f00,0x2080,0x2040,0x2040,0x2040,\n  0x2040,0x2080,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u044c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x0040,0x0040,0x0fc0,0x0040,0x0040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u044d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x43c0,0x4420,0x4420,0x4420,0x4420,0x7c20,0x4420,0x4420,\n  0x4420,0x4420,0x43c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u044e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x4040,0x4040,0x4040,0x4040,0x3fc0,0x0240,0x0440,\n  0x0840,0x1040,0x2040,0x0000,0x0000,0x0000,0x0000,0x0000, // u044f\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x0800,0x0400,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x7fc0,0x4000,0x4000,\n  0x4000,0x2040,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0450\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x7fc0,0x4000,0x4000,\n  0x4000,0x2040,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0451\n  0x0000,0x0000,0x0000,0x0000,0x4000,0xfc00,0x4000,0x4000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0040,0x0040,0x0080,0x0300,0x0000, // u0452\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0453\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4000,0x4000,0x7e00,0x4000,0x4000,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0454\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x4040,0x4000,0x4000,0x4000,0x3f80,0x0040,0x0040,\n  0x0040,0x4040,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0455\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0456\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0457\n  0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0380,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,\n  0x0080,0x0080,0x0080,0x2080,0x2080,0x1100,0x0e00,0x0000, // u0458\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x4400,0x8400,0x8780,0x8440,0x8420,0x8420,0x8420,\n  0x8420,0x8440,0x8780,0x0000,0x0000,0x0000,0x0000,0x0000, // u0459\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x8400,0x8400,0x8400,0x8400,0x8780,0xfc40,0x8420,0x8420,\n  0x8420,0x8440,0x8780,0x0000,0x0000,0x0000,0x0000,0x0000, // u045a\n  0x0000,0x0000,0x0000,0x0000,0x4000,0xfc00,0x4000,0x4000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u045b\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0200,0x0400,0x0000,0x2040,0x2080,0x2100,0x2200,0x2400,0x3800,0x2400,0x2200,\n  0x2100,0x2080,0x2040,0x0000,0x0000,0x0000,0x0000,0x0000, // u045c\n  0x0000,0x0000,0x0000,0x0000,0x1000,0x0800,0x0400,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u045d\n  0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x1f00,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x20c0,0x1f40,0x0040,0x0040,0x0080,0x3f00,0x0000, // u045e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x7fc0,0x0400,0x0400,0x0400,0x0000,0x0000, // u045f\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0xfc00,0x4000,0x4000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4080,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0462\n  0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0xfc00,0x2000,0x2000,0x2000,0x3f00,0x2080,0x2040,0x2040,0x2040,\n  0x2040,0x2080,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0463\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0e00,0x1500,0x2480,0x4440,0x4440,\n  0x4440,0x4440,0x4440,0x0000,0x0000,0x0000,0x0000,0x0000, // u046a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4040,0x2080,0x1100,0x0a00,0x0e00,0x1500,0x2480,\n  0x4440,0x4440,0x4440,0x0000,0x0000,0x0000,0x0000,0x0000, // u046b\n  0x0000,0x0040,0x0040,0x0040,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0490\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0040,0x0040,0x0040,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0491\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0xfc00,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0492\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0xfc00,0x4000,0x4000,\n  0x4000,0x4000,0x4000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0493\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4080,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0040,0x0080,0x0100,0x0000,0x0000, // u0494\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x7e00,0x4100,0x4080,\n  0x4080,0x4080,0x4080,0x0080,0x0100,0x0200,0x0000,0x0000, // u0495\n  0x0000,0x0000,0x0000,0x0000,0x4440,0x4440,0x4440,0x4440,0x4440,0x2480,0x1500,0x0e00,0x1500,0x2480,0x4440,0x4440,\n  0x4440,0x4440,0x4460,0x0020,0x0020,0x0020,0x0000,0x0000, // u0496\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4440,0x4440,0x4440,0x2480,0x1500,0x0e00,0x1500,0x2480,\n  0x4440,0x4440,0x4460,0x0020,0x0020,0x0020,0x0000,0x0000, // u0497\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x0040,0x0040,0x0040,0x0080,0x0f00,0x0080,0x0040,0x0040,0x0040,\n  0x4040,0x2080,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0000, // u0498\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x4040,0x0040,0x0040,0x0040,0x0f80,0x0040,0x0040,\n  0x0040,0x4040,0x3f80,0x0400,0x0400,0x0400,0x0400,0x0000, // u0499\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4080,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x5000,0x4800,0x4400,0x4200,\n  0x4100,0x4080,0x4060,0x0020,0x0020,0x0020,0x0000,0x0000, // u049a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2040,0x2080,0x2100,0x2200,0x2400,0x3800,0x2400,0x2200,\n  0x2100,0x2080,0x2060,0x0020,0x0020,0x0020,0x0000,0x0000, // u049b\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4080,0x4100,0x5200,0x5400,0x5800,0x7000,0x5800,0x5400,0x5200,0x4100,\n  0x4080,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u049c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4080,0x5100,0x5200,0x5400,0x7800,0x5400,0x5200,\n  0x5100,0x4080,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u049d\n  0x0000,0x0000,0x0000,0x0000,0xc040,0xc080,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x5000,0x4800,0x4400,0x4200,\n  0x4100,0x4080,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xe040,0x2080,0x2100,0x2200,0x2400,0x3800,0x2400,0x2200,\n  0x2100,0x2080,0x2040,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a1\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4060,0x0020,0x0020,0x0020,0x0000,0x0000, // u04a2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,\n  0x4040,0x4040,0x4060,0x0020,0x0020,0x0020,0x0000,0x0000, // u04a3\n  0x0000,0x0000,0x0000,0x0000,0x41f0,0x4100,0x4100,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,0x4100,0x4100,\n  0x4100,0x4100,0x4100,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x41f0,0x4100,0x4100,0x4100,0x4100,0x7f00,0x4100,0x4100,\n  0x4100,0x4100,0x4100,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a5\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4040,\n  0x4040,0x2080,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0000, // u04aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4040,0x2080,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0000, // u04ab\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0a00,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x2080,0x2080,0x2080,0x1100,0x1100,\n  0x0a00,0x0a00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0000, // u04af\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0a00,0x0400,0x3f80,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u04b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x2080,0x2080,0x2080,0x1100,0x1100,\n  0x0a00,0x0a00,0x0400,0x3f80,0x0400,0x0400,0x0400,0x0000, // u04b1\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0400,0x0a00,0x1100,0x1100,0x2080,\n  0x2080,0x4040,0x4060,0x0020,0x0020,0x0020,0x0000,0x0000, // u04b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x2080,0x1100,0x0a00,0x0400,0x0a00,0x1100,\n  0x2080,0x4040,0x4060,0x0020,0x0020,0x0020,0x0000,0x0000, // u04b3\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x2040,0x1fc0,0x0040,0x0040,0x0040,0x0040,\n  0x0040,0x0040,0x0060,0x0020,0x0020,0x0020,0x0000,0x0000, // u04b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x2040,0x1fc0,0x0040,0x0040,\n  0x0040,0x0040,0x0060,0x0020,0x0020,0x0020,0x0000,0x0000, // u04b7\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4440,0x4440,0x2440,0x1fc0,0x0440,0x0440,0x0440,0x0040,\n  0x0040,0x0040,0x0040,0x0000,0x0000,0x0000,0x0000,0x0000, // u04b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4440,0x4440,0x2440,0x1fc0,0x0440,0x0440,\n  0x0440,0x0040,0x0040,0x0000,0x0000,0x0000,0x0000,0x0000, // u04b9\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4080,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u04bb\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04c0\n  0x2080,0x2080,0x1f00,0x0000,0x4440,0x4440,0x4440,0x4440,0x4440,0x2480,0x1500,0x0e00,0x1500,0x2480,0x4440,0x4440,\n  0x4440,0x4440,0x4440,0x0000,0x0000,0x0000,0x0000,0x0000, // u04c1\n  0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x1f00,0x0000,0x4440,0x4440,0x4440,0x2480,0x1500,0x0e00,0x1500,0x2480,\n  0x4440,0x4440,0x4440,0x0000,0x0000,0x0000,0x0000,0x0000, // u04c2\n  0x0000,0x0000,0x0000,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04cf\n  0x2080,0x2080,0x1f00,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d0\n  0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x1f00,0x0000,0x3f00,0x0080,0x0040,0x0040,0x1fc0,0x2040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d1\n  0x1100,0x1100,0x1100,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d2\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,0x0000,0x3f00,0x0080,0x0040,0x0040,0x1fc0,0x2040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d3\n  0x0000,0x0000,0x0000,0x0000,0x3fe0,0x4400,0x8400,0x8400,0x8400,0x8400,0x8400,0xffc0,0x8400,0x8400,0x8400,0x8400,\n  0x8400,0x8400,0x87e0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7bc0,0x0420,0x0420,0x0420,0x7c20,0x87e0,0x8400,0x8400,\n  0x8400,0x8420,0x7bc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d5\n  0x2080,0x2080,0x1f00,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d6\n  0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x1f00,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x7fc0,0x4000,0x4000,\n  0x4000,0x2040,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d7\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x0040,0x0040,0x0040,0x0040,0x7fc0,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x4080,0x0040,0x0040,0x0040,0x7fc0,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d9\n  0x1100,0x1100,0x1100,0x0000,0x1f00,0x2080,0x4040,0x0040,0x0040,0x0040,0x0040,0x7fc0,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04da\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,0x0000,0x3f00,0x4080,0x0040,0x0040,0x0040,0x7fc0,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04db\n  0x1100,0x1100,0x1100,0x0000,0x4440,0x4440,0x4440,0x4440,0x4440,0x2480,0x1500,0x0e00,0x1500,0x2480,0x4440,0x4440,\n  0x4440,0x4440,0x4440,0x0000,0x0000,0x0000,0x0000,0x0000, // u04dc\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,0x0000,0x4440,0x4440,0x4440,0x2480,0x1500,0x0e00,0x1500,0x2480,\n  0x4440,0x4440,0x4440,0x0000,0x0000,0x0000,0x0000,0x0000, // u04dd\n  0x1100,0x1100,0x1100,0x0000,0x1f00,0x2080,0x4040,0x0040,0x0040,0x0040,0x0080,0x0f00,0x0080,0x0040,0x0040,0x0040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04de\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,0x0000,0x3f80,0x4040,0x0040,0x0040,0x0040,0x0f80,0x0040,0x0040,\n  0x0040,0x4040,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04df\n  0x0000,0x3f80,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x40c0,0x4140,0x4240,0x4440,0x4840,0x5040,0x6040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e3\n  0x1100,0x1100,0x1100,0x0000,0x4040,0x4040,0x4040,0x4040,0x40c0,0x4140,0x4240,0x4440,0x4840,0x5040,0x6040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e4\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e5\n  0x1100,0x1100,0x1100,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e6\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e7\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e9\n  0x1100,0x1100,0x1100,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ea\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04eb\n  0x1100,0x1100,0x1100,0x0000,0x1f00,0x2080,0x4040,0x0040,0x0040,0x0040,0x0040,0x0fc0,0x0040,0x0040,0x0040,0x0040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ec\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,0x0000,0x1f00,0x2080,0x4040,0x0040,0x0040,0x0fc0,0x0040,0x0040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ed\n  0x0000,0x3f80,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x2040,0x1fc0,0x0040,0x0040,0x0040,\n  0x0040,0x0080,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ee\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x20c0,0x1f40,0x0040,0x0040,0x0080,0x3f00,0x0000, // u04ef\n  0x1100,0x1100,0x1100,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x2040,0x1fc0,0x0040,0x0040,0x0040,\n  0x0040,0x0080,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f0\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x20c0,0x1f40,0x0040,0x0040,0x0080,0x3f00,0x0000, // u04f1\n  0x0440,0x0880,0x1100,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x2040,0x1fc0,0x0040,0x0040,0x0040,\n  0x0040,0x0080,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f2\n  0x0000,0x0000,0x0000,0x0000,0x0440,0x0880,0x1100,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x20c0,0x1f40,0x0040,0x0040,0x0080,0x3f00,0x0000, // u04f3\n  0x1100,0x1100,0x1100,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x2040,0x1fc0,0x0040,0x0040,0x0040,0x0040,\n  0x0040,0x0040,0x0040,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f4\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,0x0000,0x4040,0x4040,0x4040,0x4040,0x2040,0x1fc0,0x0040,0x0040,\n  0x0040,0x0040,0x0040,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f5\n  0x1100,0x1100,0x1100,0x0000,0x4020,0x4020,0x4020,0x4020,0x4020,0x7c20,0x4220,0x4120,0x4120,0x4120,0x4120,0x4120,\n  0x4120,0x4220,0x7c20,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f8\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,0x0000,0x4040,0x4040,0x4040,0x7840,0x4440,0x4240,0x4240,0x4240,\n  0x4240,0x4440,0x7840,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f9\n  0x0000,0x0000,0x0000,0x0000,0x2040,0x2040,0x1040,0x1040,0x0840,0x0840,0x1440,0x2480,0x4500,0x4200,0x4200,0x4100,\n  0x4100,0x4080,0x4080,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d0\n  0x0000,0x0000,0x0000,0x0000,0xfe00,0x0100,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,\n  0x0080,0x0080,0xffe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d1\n  0x0000,0x0000,0x0000,0x0000,0x3c00,0x0200,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0300,0x0500,0x0880,\n  0x1080,0x2040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d2\n  0x0000,0x0000,0x0000,0x0000,0xffe0,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,\n  0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d3\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x0080,0x0040,0x0040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d4\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x0800,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d5\n  0x0000,0x0000,0x0000,0x0000,0x3f80,0x0100,0x0200,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d6\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d7\n  0x0000,0x0000,0x0000,0x0000,0x4300,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d8\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x0800,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d9\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x0080,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,\n  0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0000, // u05da\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x0080,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,\n  0x0040,0x0080,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u05db\n  0x0000,0x4000,0x4000,0x4000,0x7fc0,0x0040,0x0040,0x0040,0x0040,0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000, // u05dc\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u05dd\n  0x0000,0x0000,0x0000,0x0000,0xc780,0x2840,0x3020,0x2020,0x2020,0x2020,0x2020,0x2020,0x2020,0x2020,0x2020,0x2020,\n  0x2020,0x2020,0x21e0,0x0000,0x0000,0x0000,0x0000,0x0000, // u05de\n  0x0000,0x0000,0x0000,0x0000,0x7800,0x0400,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,\n  0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0000, // u05df\n  0x0000,0x0000,0x0000,0x0000,0x3c00,0x0200,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0100,0x0100,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e0\n  0x0000,0x0000,0x0000,0x0000,0xff80,0x2040,0x2020,0x2020,0x2020,0x2020,0x2020,0x2020,0x2020,0x2020,0x2020,0x2020,\n  0x2020,0x1040,0x0f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e1\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x2040,0x2040,0x2040,0x1040,0x1080,0x1080,0x0900,0x0900,0x0600,\n  0x0c00,0x1800,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e2\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x2040,0x1840,0x0040,0x0040,0x0040,0x0040,\n  0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0000, // u05e3\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x2040,0x1840,0x0040,0x0040,0x0040,0x0040,\n  0x0040,0x0080,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e4\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x2040,0x2040,0x1040,0x1080,0x0900,0x0a00,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0000, // u05e5\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x2040,0x2040,0x1040,0x1080,0x0900,0x0a00,0x0400,0x0200,0x0200,0x0100,\n  0x0100,0x0080,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e6\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0040,0x0040,0x0040,0x4040,0x4040,0x4080,0x4100,0x4200,0x4400,0x4800,0x4800,\n  0x4800,0x4800,0x4800,0x4000,0x4000,0x4000,0x4000,0x0000, // u05e7\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x0080,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,\n  0x0040,0x0040,0x0040,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e8\n  0x0000,0x0000,0x0000,0x0000,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,0x4840,0x7040,0x4040,0x4040,0x4040,\n  0x4040,0x4080,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e9\n  0x0000,0x0000,0x0000,0x0000,0xff80,0x2040,0x2020,0x2020,0x2020,0x2020,0x2020,0x2020,0x2020,0x2020,0x2020,0x2020,\n  0x2020,0x2020,0xc020,0x0000,0x0000,0x0000,0x0000,0x0000, // u05ea\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4080,0x7f00,0x0000,0x0800,0x0800,0x0800,0x0000, // u1e0c\n  0x0000,0x0000,0x0000,0x0000,0x0040,0x0040,0x0040,0x0040,0x1fc0,0x2040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0200,0x0200,0x0200,0x0000, // u1e0d\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4080,0x4100,0x4200,0x4400,0x4800,0x5000,0x6000,0x5000,0x4800,0x4400,0x4200,\n  0x4100,0x4080,0x4040,0x0000,0x0000,0x3f80,0x0000,0x0000, // u1e34\n  0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x2000,0x2040,0x2080,0x2100,0x2200,0x2400,0x3800,0x2400,0x2200,\n  0x2100,0x2080,0x2040,0x0000,0x0000,0x1f80,0x0000,0x0000, // u1e35\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0400,0x0400,0x0400,0x0000, // u1e36\n  0x0000,0x0000,0x0000,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0400,0x0400,0x0400,0x0000, // u1e37\n  0x0400,0x0400,0x0400,0x0000,0x4020,0x6060,0x50a0,0x50a0,0x4920,0x4620,0x4620,0x4020,0x4020,0x4020,0x4020,0x4020,\n  0x4020,0x4020,0x4020,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e40\n  0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0000,0x7f00,0x4480,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,\n  0x4440,0x4440,0x4440,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e41\n  0x0000,0x0000,0x0000,0x0000,0x4020,0x6060,0x50a0,0x50a0,0x4920,0x4620,0x4620,0x4020,0x4020,0x4020,0x4020,0x4020,\n  0x4020,0x4020,0x4020,0x0000,0x0400,0x0400,0x0400,0x0000, // u1e42\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4480,0x4440,0x4440,0x4440,0x4440,0x4440,0x4440,\n  0x4440,0x4440,0x4440,0x0000,0x0400,0x0400,0x0400,0x0000, // u1e43\n  0x0400,0x0400,0x0400,0x0000,0x4040,0x4040,0x4040,0x4040,0x6040,0x5040,0x4840,0x4440,0x4240,0x4140,0x40c0,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e44\n  0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e45\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x6040,0x5040,0x4840,0x4440,0x4240,0x4140,0x40c0,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0400,0x0400,0x0400,0x0000, // u1e46\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0400,0x0400,0x0400,0x0000, // u1e47\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0400,0x0400,0x0400,0x0000, // u1e6c\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x3f80,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x03c0,0x0000,0x0100,0x0100,0x0100,0x0000, // u1e6d\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0400,0x0400,0x0400,0x0000, // u1eb8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x7fc0,0x4000,0x4000,\n  0x4000,0x2040,0x1f80,0x0000,0x0400,0x0400,0x0400,0x0000, // u1eb9\n  0x1880,0x2480,0x2300,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4000,0x4000,0x4000,0x4000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u1ebc\n  0x0000,0x0000,0x0000,0x0000,0x1880,0x2480,0x2300,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x7fc0,0x4000,0x4000,\n  0x4000,0x2040,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u1ebd\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0400,0x0400,0x0400,0x0000, // u1eca\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x1c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0400,0x0400,0x0400,0x0000, // u1ecb\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0400,0x0400,0x0400,0x0000, // u1ecc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0400,0x0400,0x0400,0x0000, // u1ecd\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0400,0x0400,0x0400,0x0000, // u1ee4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2040,0x1fc0,0x0000,0x0200,0x0200,0x0200,0x0000, // u1ee5\n  0x1880,0x2480,0x2300,0x0000,0x4040,0x4040,0x2080,0x2080,0x1100,0x1100,0x0a00,0x0a00,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u1ef8\n  0x0000,0x0000,0x0000,0x0000,0x1880,0x2480,0x2300,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x20c0,0x1f40,0x0040,0x0040,0x0080,0x3f00,0x0000, // u1ef9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2001\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2002\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2003\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2004\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2005\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2006\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2007\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2008\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2009\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2010\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2011\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2012\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2013\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2014\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2015\n  0x0000,0x0000,0x0000,0x0000,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,\n  0x0900,0x0900,0x0900,0x0000,0x0000,0x0000,0x0000,0x0000, // u2016\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x7fc0, // u2017\n  0x0000,0x0000,0x0200,0x0400,0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2018\n  0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2019\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,\n  0x0400,0x0400,0x0400,0x0800,0x0000,0x0000,0x0000,0x0000, // u201a\n  0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x0200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201b\n  0x0000,0x0000,0x0440,0x0880,0x0880,0x0880,0x0880,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201c\n  0x0000,0x0000,0x1100,0x1100,0x1100,0x1100,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0880,\n  0x0880,0x0880,0x0880,0x1100,0x0000,0x0000,0x0000,0x0000, // u201e\n  0x0000,0x0000,0x1100,0x1100,0x1100,0x1100,0x0880,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201f\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x7fc0,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2020\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x7fc0,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x7fc0,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2021\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x1f80,0x1f80,0x1f80,0x1f80,0x0f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2022\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x4440,0x4440,0x4440,0x0000,0x0000,0x0000,0x0000,0x0000, // u2026\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3100,0x4900,0x4a00,0x3200,0x0400,0x0400,0x0800,0x0800,0x1000,0x1000,0x26c0,\n  0x2920,0x4920,0x46c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2030\n  0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2032\n  0x0000,0x0000,0x1100,0x1100,0x1100,0x1100,0x1100,0x1100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2033\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x0800,0x0400,\n  0x0200,0x0100,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000, // u2039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x0800,0x0400,0x0200,0x0100,0x0080,0x0100,0x0200,\n  0x0400,0x0800,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000, // u203a\n  0x0000,0x0000,0x0000,0x0000,0x1100,0x1100,0x1100,0x1100,0x1100,0x1100,0x1100,0x1100,0x1100,0x1100,0x0000,0x0000,\n  0x1100,0x1100,0x1100,0x0000,0x0000,0x0000,0x0000,0x0000, // u203c\n  0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u203e\n  0x0000,0x0000,0x0f00,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x0f00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2070\n  0x0000,0x0400,0x0400,0x0000,0x0c00,0x0400,0x0400,0x0400,0x0400,0x0400,0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2071\n  0x0000,0x0000,0x0080,0x0180,0x0280,0x0480,0x0880,0x1080,0x1f80,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2074\n  0x0000,0x0000,0x1f00,0x1000,0x1000,0x1000,0x1f00,0x0080,0x0080,0x0080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2075\n  0x0000,0x0000,0x0f00,0x1000,0x1000,0x1000,0x1f00,0x1080,0x1080,0x1080,0x0f00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2076\n  0x0000,0x0000,0x1f80,0x1080,0x0080,0x0100,0x0100,0x0200,0x0200,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2077\n  0x0000,0x0000,0x0f00,0x1080,0x1080,0x1080,0x0f00,0x1080,0x1080,0x1080,0x0f00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2078\n  0x0000,0x0000,0x0f00,0x1080,0x1080,0x1080,0x0f80,0x0080,0x0080,0x0080,0x0f00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2079\n  0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x3f80,0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207b\n  0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,0x0000,0x0000,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207c\n  0x0000,0x0000,0x0200,0x0400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0400,0x0200,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207d\n  0x0000,0x0000,0x0800,0x0400,0x0200,0x0200,0x0200,0x0200,0x0200,0x0400,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207e\n  0x0000,0x0000,0x0000,0x1f00,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x1080,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x1080,0x1080,0x1080,\n  0x1080,0x1080,0x1080,0x1080,0x0f00,0x0000,0x0000,0x0000, // u2080\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0c00,0x1400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000, // u2081\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x1080,0x1080,0x0080,\n  0x0100,0x0200,0x0400,0x0800,0x1f80,0x0000,0x0000,0x0000, // u2082\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x1080,0x0080,0x0080,\n  0x0700,0x0080,0x0080,0x1080,0x0f00,0x0000,0x0000,0x0000, // u2083\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0180,0x0280,0x0480,\n  0x0880,0x1080,0x1f80,0x0080,0x0080,0x0000,0x0000,0x0000, // u2084\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x1000,0x1000,0x1000,\n  0x1f00,0x0080,0x0080,0x0080,0x1f00,0x0000,0x0000,0x0000, // u2085\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x1000,0x1000,0x1000,\n  0x1f00,0x1080,0x1080,0x1080,0x0f00,0x0000,0x0000,0x0000, // u2086\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x1080,0x0080,0x0100,\n  0x0100,0x0200,0x0200,0x0400,0x0400,0x0000,0x0000,0x0000, // u2087\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x1080,0x1080,0x1080,\n  0x0f00,0x1080,0x1080,0x1080,0x0f00,0x0000,0x0000,0x0000, // u2088\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x1080,0x1080,0x1080,\n  0x0f80,0x0080,0x0080,0x0080,0x0f00,0x0000,0x0000,0x0000, // u2089\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,\n  0x3f80,0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000, // u208a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u208b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0000,\n  0x0000,0x0000,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u208c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0200,0x0400,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0400,0x0200,0x0000,0x0000,0x0000, // u208d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x0400,0x0200,0x0200,\n  0x0200,0x0200,0x0200,0x0400,0x0800,0x0000,0x0000,0x0000, // u208e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x0080,0x0080,\n  0x0f80,0x1080,0x1080,0x1080,0x0f80,0x0000,0x0000,0x0000, // u2090\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x1080,0x1080,\n  0x1f80,0x1000,0x1000,0x1080,0x0f00,0x0000,0x0000,0x0000, // u2091\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x1080,0x1080,\n  0x1080,0x1080,0x1080,0x1080,0x0f00,0x0000,0x0000,0x0000, // u2092\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1080,0x1080,0x0900,\n  0x0600,0x0600,0x0900,0x1080,0x1080,0x0000,0x0000,0x0000, // u2093\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x1080,0x0080,\n  0x0080,0x1f80,0x1080,0x1080,0x0f00,0x0000,0x0000,0x0000, // u2094\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x1000,0x1f00,0x1080,0x1080,\n  0x1080,0x1080,0x1080,0x1080,0x1080,0x0000,0x0000,0x0000, // u2095\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x1000,0x1000,0x1080,0x1100,0x1200,\n  0x1400,0x1c00,0x1200,0x1100,0x1080,0x0000,0x0000,0x0000, // u2096\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0e00,0x0000,0x0000,0x0000, // u2097\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x4440,0x4440,\n  0x4440,0x4440,0x4440,0x4440,0x4440,0x0000,0x0000,0x0000, // u2098\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x1080,0x1080,\n  0x1080,0x1080,0x1080,0x1080,0x1f00,0x1000,0x1000,0x1000, // u209a\n  0x0000,0x0000,0x0000,0x0000,0x7c00,0x4200,0x4100,0x4100,0x4100,0x4100,0x4200,0x7c80,0x4080,0x43e0,0x4080,0x4080,\n  0x4080,0x4080,0x4060,0x0000,0x0000,0x0000,0x0000,0x0000, // u20a7\n  0x0000,0x0000,0x0000,0x0000,0x7c20,0x4220,0x4120,0x4120,0x4920,0x4920,0x4920,0x4920,0x4920,0x4920,0x4920,0x4820,\n  0x4820,0x4840,0x4f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u20aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x1080,0x2040,0x4000,0x4000,0xfe00,0x4000,0x4000,0xfe00,0x4000,0x4000,\n  0x2040,0x1080,0x0f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u20ac\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0400,0x0400,0x0400,0x0580,0x0600,0x0c00,0x3580,0x0600,0x0c00,0x3400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u20ae\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x3080,0x5040,0x5040,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5040,\n  0x5040,0x3080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2102\n  0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u210e\n  0x0000,0x0000,0x0000,0x0000,0x4000,0xfc00,0x4000,0x4000,0x7f00,0x4080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u210f\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x6040,0x5040,0x6840,0x5440,0x4a40,0x4540,0x42c0,0x4140,0x40c0,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u2115\n  0x0000,0x0000,0x0000,0x0000,0x8200,0x8260,0xc290,0xc290,0xa260,0xa200,0x9200,0x9200,0x8a00,0x8af0,0x8600,0x8600,\n  0x82f0,0x8200,0x8200,0x0000,0x0000,0x0000,0x0000,0x0000, // u2116\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x3080,0x5040,0x5040,0x5040,0x5040,0x5040,0x5040,0x5040,0x5040,0x5040,0x5040,\n  0x5440,0x3280,0x1f00,0x0080,0x0040,0x0000,0x0000,0x0000, // u211a\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x5080,0x5040,0x5040,0x5040,0x5040,0x5080,0x5f00,0x5400,0x5a00,0x5500,0x5280,\n  0x5140,0x50a0,0x7060,0x0000,0x0000,0x0000,0x0000,0x0000, // u211d\n  0x0000,0x0000,0x0000,0x0000,0xfa20,0x2360,0x22a0,0x2220,0x2220,0x2220,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2122\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0040,0x0040,0x00c0,0x0140,0x0280,0x0500,0x0a00,0x1400,0x2800,0x5000,0x6000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2124\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x2080,\n  0x1100,0x1100,0x71c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2126\n  0x0000,0x0000,0x0000,0x0000,0x2100,0x2100,0x1080,0x1080,0x0840,0x0820,0x1440,0x2480,0x4500,0x4200,0x4200,0x4100,\n  0x4100,0x2080,0x1080,0x0000,0x0000,0x0000,0x0000,0x0000, // u2135\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x1000,0x2000,0x4000,0xffe0,0x4000,0x2000,0x1000,0x0800,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2190\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0e00,0x1500,0x2480,0x4440,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2191\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0200,0x0100,0x0080,0x0040,0xffe0,0x0040,0x0080,0x0100,0x0200,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2192\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x4440,0x2480,\n  0x1500,0x0e00,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2193\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0900,0x1080,0x2040,0x4020,0xfff0,0x4020,0x2040,0x1080,0x0900,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2194\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0e00,0x1500,0x2480,0x4440,0x0400,0x0400,0x0400,0x0400,0x0400,0x4440,0x2480,\n  0x1500,0x0e00,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2195\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0820,0x1020,0x2020,0x4020,0xffe0,0x4020,0x2020,0x1020,0x0820,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x8200,0x8100,0x8080,0x8040,0xffe0,0x8040,0x8080,0x8100,0x8200,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a6\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0e00,0x1500,0x2480,0x4440,0x0400,0x0400,0x0400,0x0400,0x4440,0x2480,0x1500,\n  0x0e00,0x0400,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a8\n  0x0000,0x0000,0x0000,0x0000,0x0020,0x0020,0x0020,0x0020,0x0020,0x0020,0x0820,0x1020,0x2020,0x4020,0xffe0,0x4000,\n  0x2000,0x1000,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000, // u21b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7800,0x1800,0x2880,0x4840,0x4840,0x4040,0x4040,0x4040,0x4040,0x2080,\n  0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x2000,0x4000,0xffe0,0x0000,0x0000,0xffe0,0x0040,0x0080,\n  0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0080,0x0040,0xffe0,0x0000,0x0000,0xffe0,0x4000,0x2000,\n  0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21cc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x1000,0x2000,0x7fe0,0xc000,0xc000,0x7fe0,0x2000,0x1000,\n  0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d0\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0f00,0x1980,0x2940,0x4920,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,\n  0x0900,0x0900,0x0900,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0200,0x0100,0x0080,0xffc0,0x0060,0x0060,0xffc0,0x0080,0x0100,\n  0x0200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d2\n  0x0000,0x0000,0x0000,0x0000,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x4920,0x2940,\n  0x1980,0x0f00,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0900,0x1080,0x2040,0x7fe0,0xc030,0xc030,0x7fe0,0x2040,0x1080,\n  0x0900,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d4\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0f00,0x1980,0x2940,0x4920,0x0900,0x0900,0x0900,0x0900,0x0900,0x4920,0x2940,\n  0x1980,0x0f00,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d5\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x2080,0x3f80,0x2080,0x1100,0x1100,0x1100,0x0a00,0x0a00,0x0a00,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2200\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x7fc0,0x0040,0x0040,0x0040,0x0040,\n  0x0040,0x0040,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2203\n  0x0000,0x0000,0x0040,0x0040,0x7fc0,0x00c0,0x0140,0x0140,0x0240,0x0240,0x0440,0x7fc0,0x0440,0x0840,0x0840,0x1040,\n  0x1040,0x2040,0x7fc0,0x4000,0x4000,0x0000,0x0000,0x0000, // u2204\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0020,0x1f40,0x2080,0x4140,0x4240,0x4440,0x4840,0x5040,0x2080,0x5f00,\n  0x8000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2205\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0a00,0x0a00,0x0a00,0x1100,0x1100,0x1100,0x2080,0x2080,0x2080,\n  0x4040,0x4040,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2206\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4040,0x4040,0x2080,0x2080,0x2080,0x1100,0x1100,0x1100,0x0a00,0x0a00,0x0a00,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2207\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x1000,0x2000,0x4000,0x4000,0x4000,0x4000,0x7fc0,0x4000,0x4000,0x4000,0x4000,\n  0x2000,0x1000,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2208\n  0x0000,0x0000,0x0020,0x0020,0x0fc0,0x1040,0x2080,0x4080,0x4100,0x4100,0x4200,0x7fc0,0x4400,0x4800,0x4800,0x5000,\n  0x3000,0x3000,0x2fc0,0x4000,0x4000,0x0000,0x0000,0x0000, // u2209\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x1000,0x2000,0x4000,0x4000,0x7fc0,0x4000,0x4000,0x2000,0x1000,\n  0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u220a\n  0x0000,0x0000,0x0000,0x0000,0x7e00,0x0100,0x0080,0x0040,0x0040,0x0040,0x0040,0x7fc0,0x0040,0x0040,0x0040,0x0040,\n  0x0080,0x0100,0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000, // u220b\n  0x0000,0x0000,0x4000,0x4000,0x3f00,0x2080,0x1040,0x1020,0x0820,0x0820,0x0420,0x3fe0,0x0220,0x0120,0x0120,0x00a0,\n  0x00c0,0x00c0,0x3f40,0x0020,0x0020,0x0000,0x0000,0x0000, // u220c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0100,0x0080,0x0040,0x0040,0x7fc0,0x0040,0x0040,0x0080,0x0100,\n  0x7e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u220d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2212\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x7fc0,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2213\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x7fc0,0x0400,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2214\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2215\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,0x0080,0x0040,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2216\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0f00,0x0f00,0x0600,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2219\n  0x0000,0x0000,0x00e0,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x4080,0x4080,0x4080,0x2080,0x1080,0x0880,\n  0x0480,0x0280,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000, // u221a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3b80,0x4440,0x4440,0x4440,0x4440,0x4440,0x3b80,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u221e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7fc0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u221f\n  0x0000,0x0000,0x0000,0x0000,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,\n  0x0900,0x0900,0x0900,0x0000,0x0000,0x0000,0x0000,0x0000, // u2225\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0a00,0x0a00,0x1100,0x1100,0x2080,0x2080,\n  0x2080,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u2227\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x2080,0x2080,0x2080,0x1100,0x1100,0x0a00,\n  0x0a00,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2228\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u2229\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u222a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3840,0x4440,0x4380,0x0000,0x3840,0x4440,0x4380,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2248\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0040,0x7fc0,0x0100,0x0200,0x0400,0x0800,0x1000,0x7fc0,0x4000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2260\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,\n  0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2261\n  0x0000,0x0000,0x0000,0x0000,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,\n  0x0080,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2264\n  0x0000,0x0000,0x0000,0x0000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,\n  0x2000,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2265\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0220,0x0440,0x0880,0x1100,0x2200,0x4400,0x8800,0x4400,0x2200,0x1100,0x0880,\n  0x0440,0x0220,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u226a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x8800,0x4400,0x2200,0x1100,0x0880,0x0440,0x0220,0x0440,0x0880,0x1100,0x2200,\n  0x4400,0x8800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u226b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x1000,0x2000,0x4000,0x4000,0x4000,0x4000,0x4000,0x2000,0x1000,\n  0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2282\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0080,0x0040,0x0020,0x0020,0x0020,0x0020,0x0020,0x0040,0x0080,\n  0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2283\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x1000,0x2000,0x4000,0x4000,0x4000,0x4000,0x4000,0x2000,0x1000,0x0fe0,\n  0x0000,0x0000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2286\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0080,0x0040,0x0020,0x0020,0x0020,0x0020,0x0020,0x0040,0x0080,0x7f00,\n  0x0000,0x0000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2287\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u22a5\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u22c2\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u22c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0020,0x1f40,0x2080,0x4140,0x4240,0x4440,0x4840,0x5040,0x2080,0x5f00,\n  0x8000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2300\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0900,0x1080,0x2040,0x4020,0x4020,0x4020,0x4020,0x4020,\n  0x4020,0x4020,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2302\n  0x0000,0x0000,0x0000,0x0000,0x0f00,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000, // u2308\n  0x0000,0x0000,0x0000,0x0000,0x0f00,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000, // u2309\n  0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u230a\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,0x0100,\n  0x0100,0x0100,0x0f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u230b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4000,0x4000,0x4000,0x4000,0x4000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2310\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7fc0,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2319\n  0x0000,0x0000,0x0000,0x0000,0x0380,0x0440,0x0440,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2320\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x4400,0x4400,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000, // u2321\n  0x0040,0x0080,0x0100,0x0200,0x0200,0x0400,0x0400,0x0800,0x0800,0x0800,0x1000,0x1000,0x1000,0x1000,0x2000,0x2000,\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u239b\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u239c\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x1000,0x1000,0x1000,0x1000,0x0800,0x0800,\n  0x0800,0x0400,0x0400,0x0200,0x0200,0x0100,0x0080,0x0040, // u239d\n  0x2000,0x1000,0x0800,0x0400,0x0400,0x0200,0x0200,0x0100,0x0100,0x0100,0x0080,0x0080,0x0080,0x0080,0x0040,0x0040,\n  0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040, // u239e\n  0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,\n  0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040, // u239f\n  0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0080,0x0080,0x0080,0x0080,0x0100,0x0100,\n  0x0100,0x0200,0x0200,0x0400,0x0400,0x0800,0x1000,0x2000, // u23a0\n  0x3fc0,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u23a1\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000, // u23a2\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,\n  0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x2000,0x3fc0, // u23a3\n  0x3fc0,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,\n  0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040, // u23a4\n  0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,\n  0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040, // u23a5\n  0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,\n  0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x0040,0x3fc0, // u23a6\n  0x01e0,0x0600,0x0400,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800, // u23a7\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x1000,0xe000,0xe000,0x1000,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800, // u23a8\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,0x0800,\n  0x0800,0x0800,0x0800,0x0800,0x0800,0x0400,0x0600,0x01e0, // u23a9\n  0xf000,0x0c00,0x0400,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,\n  0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200, // u23ab\n  0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0100,0x00e0,0x00e0,0x0100,0x0200,0x0200,\n  0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200, // u23ac\n  0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,0x0200,\n  0x0200,0x0200,0x0200,0x0200,0x0200,0x0400,0x0c00,0xf000, // u23ad\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u23ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23af\n  0xfff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0xfff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0, // u23bd\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u23d0\n  0x0000,0x0000,0x0000,0x4400,0x4400,0x4400,0x7c00,0x4400,0x4400,0x4400,0x0000,0x0000,0x07c0,0x0100,0x0100,0x0100,\n  0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000, // u2409\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7c00,0x0000,0x0000,0x07c0,0x0400,0x0400,0x0700,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u240a\n  0x0000,0x0000,0x0000,0x4400,0x4400,0x4400,0x2800,0x2800,0x1000,0x1000,0x0000,0x0000,0x07c0,0x0100,0x0100,0x0100,\n  0x0100,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000, // u240b\n  0x0000,0x0000,0x0000,0x7c00,0x4000,0x4000,0x7000,0x4000,0x4000,0x4000,0x0000,0x0000,0x07c0,0x0400,0x0400,0x0700,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u240c\n  0x0000,0x0000,0x0000,0x3800,0x4400,0x4000,0x4000,0x4000,0x4400,0x3800,0x0000,0x0000,0x0780,0x0440,0x0440,0x0780,\n  0x0500,0x0480,0x0440,0x0000,0x0000,0x0000,0x0000,0x0000, // u240d\n  0x0000,0x0000,0x0000,0x4400,0x4400,0x6400,0x5400,0x4c00,0x4400,0x4400,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x07c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2424\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2500\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2501\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2502\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2503\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xdb60,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2508\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xdb60,0xdb60,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2509\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0000,0x0400,0x0400,0x0400,0x0400,0x0400,0x0000,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0000,0x0400,0x0400,0x0400,0x0400,0x0400,0x0000, // u250a\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000, // u250b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07f0,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u250c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07f0,0x07f0,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u250d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07f0,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u250e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07f0,0x07f0,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u250f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2510\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2511\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2512\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xfe00,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2513\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x07f0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2514\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x07f0,0x07f0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2515\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x07f0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2516\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x07f0,0x07f0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2517\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfc00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2518\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfc00,0xfc00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2519\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfe00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u251a\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfe00,0xfe00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u251b\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x07f0,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u251c\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x07f0,0x07f0,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u251d\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x07f0,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u251e\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x07f0,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u251f\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x07f0,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2520\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x07f0,0x07f0,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2521\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x07f0,0x07f0,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2522\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x07f0,0x07f0,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2523\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfc00,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2524\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfc00,0xfc00,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2525\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfe00,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2526\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfe00,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2527\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfe00,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2528\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfe00,0xfe00,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2529\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfe00,0xfe00,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u252a\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfe00,0xfe00,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u252b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u252c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfc00,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u252d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0x07f0,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u252e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u252f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2530\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfe00,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2531\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0x07f0,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2532\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2533\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfff0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2534\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfff0,0xfc00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2535\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfff0,0x07f0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2536\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfff0,0xfff0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2537\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfff0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2538\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfff0,0xfe00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2539\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfff0,0x07f0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u253a\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfff0,0xfff0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u253b\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfff0,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u253c\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfff0,0xfc00,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u253d\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfff0,0x07f0,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u253e\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfff0,0xfff0,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u253f\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfff0,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2540\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfff0,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2541\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfff0,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2542\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfff0,0xfc00,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2543\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfff0,0x07f0,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2544\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfff0,0xfe00,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2545\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfff0,0x07f0,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2546\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfff0,0xfff0,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2547\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfff0,0xfff0,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2548\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfff0,0xfe00,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2549\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfff0,0x07f0,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u254a\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfff0,0xfff0,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u254b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0x0000,0x0000,0xfff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2550\n  0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,\n  0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900, // u2551\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07f0,0x0400,0x0400,0x07f0,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2552\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x0900,0x0900,0x0900,0x0900,\n  0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900, // u2553\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x0800,0x0800,0x09f0,0x0900,0x0900,\n  0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900, // u2554\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x0400,0x0400,0xfc00,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2555\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x0900,0x0900,0x0900,0x0900,\n  0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900, // u2556\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x0100,0x0100,0xf900,0x0900,0x0900,\n  0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900, // u2557\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x07f0,0x0400,0x0400,0x07f0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2558\n  0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0ff0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2559\n  0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x09f0,0x0800,0x0800,0x0ff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255a\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfc00,0x0400,0x0400,0xfc00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255b\n  0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0xff00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255c\n  0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0xf900,0x0100,0x0100,0xff00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255d\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x07f0,0x0400,0x0400,0x07f0,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u255e\n  0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x09f0,0x0900,0x0900,0x0900,0x0900,\n  0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900, // u255f\n  0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x09f0,0x0800,0x0800,0x09f0,0x0900,0x0900,\n  0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900, // u2560\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfc00,0x0400,0x0400,0xfc00,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2561\n  0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0xf900,0x0900,0x0900,0x0900,0x0900,\n  0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900, // u2562\n  0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0xf900,0x0100,0x0100,0xf900,0x0900,0x0900,\n  0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900, // u2563\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0x0000,0x0000,0xfff0,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2564\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0x0900,0x0900,0x0900,0x0900,\n  0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900, // u2565\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0x0000,0x0000,0xf9f0,0x0900,0x0900,\n  0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900, // u2566\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfff0,0x0000,0x0000,0xfff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2567\n  0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0xfff0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2568\n  0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0xf9f0,0x0000,0x0000,0xfff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2569\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0xfff0,0x0400,0x0400,0xfff0,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u256a\n  0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0xfff0,0x0900,0x0900,0x0900,0x0900,\n  0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900, // u256b\n  0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0xf9f0,0x0000,0x0000,0xf9f0,0x0900,0x0900,\n  0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900,0x0900, // u256c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x0180,0x0200,0x0200,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u256d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0x3000,0x0800,0x0800,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u256e\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0800,0x0800,0x3000,0xc000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u256f\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0200,0x0200,0x0180,0x0070,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2570\n  0x0010,0x0010,0x0020,0x0020,0x0040,0x0040,0x0080,0x0080,0x0100,0x0100,0x0200,0x0200,0x0400,0x0400,0x0800,0x0800,\n  0x1000,0x1000,0x2000,0x2000,0x4000,0x4000,0x8000,0x8000, // u2571\n  0x8000,0x8000,0x4000,0x4000,0x2000,0x2000,0x1000,0x1000,0x0800,0x0800,0x0400,0x0400,0x0200,0x0200,0x0100,0x0100,\n  0x0080,0x0080,0x0040,0x0040,0x0020,0x0020,0x0010,0x0010, // u2572\n  0x8010,0x8010,0x4020,0x4020,0x2040,0x2040,0x1080,0x1080,0x0900,0x0900,0x0600,0x0600,0x0600,0x0600,0x0900,0x0900,\n  0x1080,0x1080,0x2040,0x2040,0x4020,0x4020,0x8010,0x8010, // u2573\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2574\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2575\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07f0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2576\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u2577\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2578\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2579\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07f0,0x07f0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u257b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0x07f0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257c\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u257d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfc00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257e\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0400,0x0400,0x0400,0x0400,\n  0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400,0x0400, // u257f\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2580\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0,0xfff0, // u2581\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0, // u2582\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0, // u2583\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0,0xfff0,0xfff0,\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0, // u2584\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0, // u2585\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0, // u2586\n  0x0000,0x0000,0x0000,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0, // u2587\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0, // u2588\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0, // u2589\n  0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,\n  0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80, // u258a\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00, // u258b\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00, // u258c\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000, // u258d\n  0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,\n  0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000, // u258e\n  0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,\n  0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000,0x8000, // u258f\n  0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,\n  0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0, // u2590\n  0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000,\n  0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000, // u2591\n  0xaaa0,0x5550,0xaaa0,0x5550,0xaaa0,0x5550,0xaaa0,0x5550,0xaaa0,0x5550,0xaaa0,0x5550,0xaaa0,0x5550,0xaaa0,0x5550,\n  0xaaa0,0x5550,0xaaa0,0x5550,0xaaa0,0x5550,0xaaa0,0x5550, // u2592\n  0xfff0,0xaaa0,0xfff0,0xaaa0,0xfff0,0xaaa0,0xfff0,0xaaa0,0xfff0,0xaaa0,0xfff0,0xaaa0,0xfff0,0xaaa0,0xfff0,0xaaa0,\n  0xfff0,0xaaa0,0xfff0,0xaaa0,0xfff0,0xaaa0,0xfff0,0xaaa0, // u2593\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0xfc00,0xfc00,\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00, // u2596\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03f0,0x03f0,0x03f0,0x03f0,\n  0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0, // u2597\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2598\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfff0,0xfff0,0xfff0,0xfff0,\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0, // u2599\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0x03f0,0x03f0,0x03f0,0x03f0,\n  0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0, // u259a\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfc00,0xfc00,0xfc00,0xfc00,\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00, // u259b\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0x03f0,0x03f0,0x03f0,0x03f0,\n  0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0, // u259c\n  0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u259d\n  0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0xfc00,0xfc00,0xfc00,0xfc00,\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00, // u259e\n  0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0xfff0,0xfff0,0xfff0,0xfff0,\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0, // u259f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x3f80,0x3f80,0x3f80,0x3f80,0x3f80,0x3f80,0x3f80,0x3f80,\n  0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x7fe0,0x7fe0,\n  0x7fe0,0x7fe0,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ac\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fc0,0x7fc0,0x7fc0,0x7fc0,0x7fc0,0x7fc0,0x7fc0,0x7fc0,0x7fc0,0x7fc0,0x7fc0,\n  0x7fc0,0x7fc0,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0e00,0x0e00,0x1f00,0x1f00,0x3f80,0x3f80,0x7fc0,0x7fc0,\n  0xffe0,0xffe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xffc0,0xfff0,0xffc0,0xff00,0xfc00,0xf000,\n  0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xffc0,0xfff0,0xffc0,0xff00,0xfc00,0xf000,\n  0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,0x7fc0,0x7fc0,0x3f80,0x3f80,0x1f00,0x1f00,0x0e00,0x0e00,\n  0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0030,0x00f0,0x03f0,0x0ff0,0x3ff0,0xfff0,0x3ff0,0x0ff0,0x03f0,0x00f0,\n  0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0030,0x00f0,0x03f0,0x0ff0,0x3ff0,0xfff0,0x3ff0,0x0ff0,0x03f0,0x00f0,\n  0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0e00,0x1f00,0x3f80,0x7fc0,0xffe0,0x7fc0,0x3f80,0x1f00,0x0e00,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0a00,0x1100,0x2080,0x4040,0x8020,0x4040,0x2080,0x1100,0x0a00,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ca\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x1080,0x1080,0x1080,0x1080,0x0f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x1f80,0x1f80,0x1f80,0x1f80,0x0f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25cf\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xf0f0,0xe070,0xe070,0xe070,0xe070,0xf0f0,0xfff0,\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0, // u25d8\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xf0f0,0xef70,0xef70,0xef70,0xef70,0xf0f0,0xfff0,\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0, // u25d9\n  0x0000,0x0000,0x0000,0x0000,0x3f80,0x4040,0x8020,0x8020,0x9b20,0x9b20,0x8020,0x8020,0x8020,0x9f20,0x8e20,0x8020,\n  0x8020,0x4040,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u263a\n  0x0000,0x0000,0x0000,0x0000,0x3f80,0x7fc0,0xffe0,0xffe0,0xe4e0,0xe4e0,0xffe0,0xffe0,0xffe0,0xe0e0,0xf1e0,0xffe0,\n  0xffe0,0x7fc0,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u263b\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x8420,0x4440,0x2480,0x1500,0x0e00,0xfbe0,0x0e00,0x1500,0x2480,0x4440,\n  0x8420,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u263c\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,0x4040,0x2080,0x1f00,0x0400,0x0400,0x7fc0,\n  0x0400,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000, // u2640\n  0x0000,0x0000,0x0000,0x0000,0x07e0,0x0060,0x00a0,0x0120,0x0220,0x0420,0x1f00,0x2080,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x2080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2642\n  0x0000,0x0000,0x0000,0x0000,0x0400,0x0400,0x0e00,0x1f00,0x3f80,0x7fc0,0x7fc0,0x7fc0,0x7fc0,0x7fc0,0x3580,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2660\n  0x0000,0x0000,0x0000,0x0000,0x0e00,0x1f00,0x1f00,0x0e00,0x0400,0x0400,0x75c0,0xffe0,0xffe0,0xffe0,0x75c0,0x0400,\n  0x0400,0x0400,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2663\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x7bc0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0x7fc0,0x3f80,0x1f00,\n  0x0e00,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2665\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0e00,0x1f00,0x3f80,0x7fc0,0xffe0,0x7fc0,0x3f80,0x1f00,0x0e00,\n  0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2666\n  0x0000,0x0000,0x0000,0x0000,0x1fe0,0x1020,0x1020,0x1020,0x1fe0,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,0x1000,\n  0x1000,0x1000,0xe000,0x0000,0x0000,0x0000,0x0000,0x0000, // u266a\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4040,0x4040,0x4040,0x7fc0,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4080,0x8000,0x0000,0x0000,0x0000,0x0000,0x0000, // u266b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0020,0x0020,0x0040,0x0040,0x0080,0x0080,0x4100,0x4100,0x2200,0x2200,0x1400,\n  0x1400,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000, // u2713\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x00c0,0x00c0,0x0180,0x0180,0xc300,0xc300,0x6600,0x6600,0x3c00,\n  0x3c00,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000, // u2714\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x2100,0x1100,0x0a00,0x0600,0x0600,0x0500,0x0880,0x0840,0x1000,\n  0x1000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2717\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x6300,0x3300,0x1e00,0x0e00,0x0e00,0x0f00,0x1980,0x18c0,0x3000,\n  0x3000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2718\n  0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0200,0x0200,0x0400,0x0400,0x0800,0x0800,0x0800,0x0400,0x0400,0x0200,\n  0x0200,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000, // u27e8\n  0x0000,0x0000,0x0000,0x0000,0x0800,0x0800,0x0400,0x0400,0x0200,0x0200,0x0100,0x0100,0x0100,0x0200,0x0200,0x0400,\n  0x0400,0x0800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000, // u27e9\n  0x0000,0x0000,0x0000,0x0000,0x0440,0x0440,0x0880,0x0880,0x1100,0x1100,0x2200,0x2200,0x2200,0x1100,0x1100,0x0880,\n  0x0880,0x0440,0x0440,0x0000,0x0000,0x0000,0x0000,0x0000, // u27ea\n  0x0000,0x0000,0x0000,0x0000,0x2200,0x2200,0x1100,0x1100,0x0880,0x0880,0x0440,0x0440,0x0440,0x0880,0x0880,0x1100,\n  0x1100,0x2200,0x2200,0x0000,0x0000,0x0000,0x0000,0x0000, // u27eb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2800\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2801\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2802\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2803\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2804\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2805\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2806\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2807\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2808\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2809\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280a\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280b\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280c\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280d\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280e\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2810\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2811\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2812\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2813\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2814\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2815\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2816\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2817\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2818\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2819\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281a\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281b\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281c\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281d\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281e\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2820\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2821\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2822\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2823\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2824\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2825\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2826\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2827\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2828\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2829\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282a\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282b\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282c\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282d\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282e\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2830\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2831\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2832\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2833\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2834\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2835\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2836\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2837\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2838\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2839\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283a\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283b\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283c\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283d\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283e\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2840\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2841\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2842\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2843\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2844\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2845\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2846\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2847\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2848\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2849\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u284a\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u284b\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u284c\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u284d\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u284e\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u284f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2850\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2851\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2852\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2853\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2854\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2855\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2856\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2857\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2858\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2859\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u285a\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u285b\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u285c\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u285d\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u285e\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u285f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2860\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2861\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2862\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2863\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2864\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2865\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2866\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2867\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2868\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2869\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u286a\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u286b\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u286c\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u286d\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u286e\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u286f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2870\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2871\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2872\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2873\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2874\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2875\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2876\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2877\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2878\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u2879\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u287a\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u287b\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u287c\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u287d\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u287e\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000, // u287f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u2880\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u2881\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u2882\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u2883\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u2884\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u2885\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u2886\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u2887\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u2888\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u2889\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u288a\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u288b\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u288c\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u288d\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u288e\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u288f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u2890\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u2891\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u2892\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u2893\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u2894\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u2895\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u2896\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u2897\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u2898\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u2899\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u289a\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u289b\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u289c\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u289d\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u289e\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u289f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28a0\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28a2\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28a4\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28a5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28a6\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28a7\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28a8\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28a9\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28aa\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28ab\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28ac\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28ad\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28ae\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28af\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28b0\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28b1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28b2\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28b4\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28b6\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28b7\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28b8\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28b9\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28ba\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28bb\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28bc\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28bd\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28be\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000, // u28bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28c0\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28c2\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28c4\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28c6\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28c7\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28c8\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28c9\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28ca\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28cb\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28cc\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28cd\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28ce\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28cf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28d0\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28d2\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28d4\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28d6\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28d7\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28d8\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28d9\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28da\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28db\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28dc\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28dd\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28de\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28df\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28e0\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28e1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28e2\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28e3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28e4\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28e6\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28e7\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28e8\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28e9\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28ea\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28eb\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28ec\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28ed\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28ee\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28ef\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28f0\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28f2\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28f3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28f4\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28f6\n  0x0000,0x2000,0x2000,0x2000,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28f7\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28f8\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28f9\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28fa\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28fb\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28fc\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28fd\n  0x0000,0x0080,0x0080,0x0080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28fe\n  0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,\n  0x0000,0x0000,0x0000,0x2080,0x2080,0x2080,0x0000,0x0000, // u28ff\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x4040,\n  0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2e2c\n  0x4000,0x4000,0x4100,0x4380,0x4540,0x4920,0x4100,0x4100,0x4100,0x4100,0x4100,0x4200,0x0400,0x0800,0x1000,0x2000,\n  0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000, // ue0a0\n  0x0000,0x0000,0x0000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x7e00,0x0000,0x0000,0x0840,0x0840,0x0c40,\n  0x0a40,0x0940,0x08c0,0x0840,0x0840,0x0000,0x0000,0x0000, // ue0a1\n  0x0000,0x0000,0x0000,0x1f00,0x2080,0x2080,0x2080,0x2080,0x2080,0x2080,0x7fc0,0xffe0,0xffe0,0xf1e0,0xe0e0,0xe0e0,\n  0xf1e0,0xffe0,0xffe0,0xffe0,0x0000,0x0000,0x0000,0x0000, // ue0a2\n  0x8000,0xc000,0xe000,0xf000,0xf800,0xfc00,0xfe00,0xff00,0xff80,0xffc0,0xffe0,0xfff0,0xfff0,0xffe0,0xffc0,0xff80,\n  0xff00,0xfe00,0xfc00,0xf800,0xf000,0xe000,0xc000,0x8000, // ue0b0\n  0x8000,0x4000,0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,0x0080,0x0040,0x0020,0x0010,0x0010,0x0020,0x0040,0x0080,\n  0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000, // ue0b1\n  0x0010,0x0030,0x0070,0x00f0,0x01f0,0x03f0,0x07f0,0x0ff0,0x1ff0,0x3ff0,0x7ff0,0xfff0,0xfff0,0x7ff0,0x3ff0,0x1ff0,\n  0x0ff0,0x07f0,0x03f0,0x01f0,0x00f0,0x0070,0x0030,0x0010, // ue0b2\n  0x0010,0x0020,0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000,0x8000,0x4000,0x2000,0x1000,\n  0x0800,0x0400,0x0200,0x0100,0x0080,0x0040,0x0020,0x0010, // ue0b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,0x0080,\n  0x0080,0x0080,0x0080,0x2080,0x2080,0x1100,0x0e00,0x0000, // uf6be\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,0x4040,\n  0x4040,0x4040,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000 // ufffd\n  };\n  // codepoints array\n  constexpr std::array<uint16_t, CHARCOUNT> fixedfont_codepoints = {\n  0x0000,0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,\n  0x002f,0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,\n  0x003f,0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,\n  0x004f,0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,\n  0x005f,0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,\n  0x006f,0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,\n  0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af,\n  0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf,\n  0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf,\n  0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df,\n  0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef,\n  0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff,\n  0x0100,0x0101,0x0102,0x0103,0x0104,0x0105,0x0106,0x0107,0x0108,0x0109,0x010a,0x010b,0x010c,0x010d,0x010e,0x010f,\n  0x0110,0x0111,0x0112,0x0113,0x0114,0x0115,0x0116,0x0117,0x0118,0x0119,0x011a,0x011b,0x011c,0x011d,0x011e,0x011f,\n  0x0120,0x0121,0x0122,0x0123,0x0124,0x0125,0x0126,0x0127,0x0128,0x0129,0x012a,0x012b,0x012c,0x012d,0x012e,0x012f,\n  0x0130,0x0131,0x0132,0x0133,0x0134,0x0135,0x0136,0x0137,0x0138,0x0139,0x013a,0x013b,0x013c,0x013d,0x013e,0x013f,\n  0x0140,0x0141,0x0142,0x0143,0x0144,0x0145,0x0146,0x0147,0x0148,0x0149,0x014a,0x014b,0x014c,0x014d,0x014e,0x014f,\n  0x0150,0x0151,0x0152,0x0153,0x0154,0x0155,0x0156,0x0157,0x0158,0x0159,0x015a,0x015b,0x015c,0x015d,0x015e,0x015f,\n  0x0160,0x0161,0x0162,0x0163,0x0164,0x0165,0x0166,0x0167,0x0168,0x0169,0x016a,0x016b,0x016c,0x016d,0x016e,0x016f,\n  0x0170,0x0171,0x0172,0x0173,0x0174,0x0175,0x0176,0x0177,0x0178,0x0179,0x017a,0x017b,0x017c,0x017d,0x017e,0x017f,\n  0x0186,0x018e,0x018f,0x0190,0x0192,0x019d,0x019e,0x01b5,0x01b6,0x01b7,0x01cd,0x01ce,0x01cf,0x01d0,0x01d1,0x01d2,\n  0x01d3,0x01d4,0x01e2,0x01e3,0x01e4,0x01e5,0x01e6,0x01e7,0x01e8,0x01e9,0x01ea,0x01eb,0x01ec,0x01ed,0x01ee,0x01ef,\n  0x01f0,0x01f4,0x01f5,0x01fc,0x01fd,0x01fe,0x01ff,0x0218,0x0219,0x021a,0x021b,0x0232,0x0233,0x0237,0x0254,0x0258,\n  0x0259,0x025b,0x0272,0x0292,0x02bb,0x02bc,0x02bd,0x02c6,0x02c7,0x02d8,0x02d9,0x02db,0x02dc,0x02dd,0x0300,0x0301,\n  0x0302,0x0303,0x0304,0x0305,0x0306,0x0307,0x0308,0x030a,0x030b,0x030c,0x0329,0x0384,0x0385,0x0386,0x0387,0x0388,\n  0x0389,0x038a,0x038c,0x038e,0x038f,0x0390,0x0391,0x0392,0x0393,0x0394,0x0395,0x0396,0x0397,0x0398,0x0399,0x039a,\n  0x039b,0x039c,0x039d,0x039e,0x039f,0x03a0,0x03a1,0x03a3,0x03a4,0x03a5,0x03a6,0x03a7,0x03a8,0x03a9,0x03aa,0x03ab,\n  0x03ac,0x03ad,0x03ae,0x03af,0x03b0,0x03b1,0x03b2,0x03b3,0x03b4,0x03b5,0x03b6,0x03b7,0x03b8,0x03b9,0x03ba,0x03bb,\n  0x03bc,0x03bd,0x03be,0x03bf,0x03c0,0x03c1,0x03c2,0x03c3,0x03c4,0x03c5,0x03c6,0x03c7,0x03c8,0x03c9,0x03ca,0x03cb,\n  0x03cc,0x03cd,0x03ce,0x03d1,0x03d5,0x03f0,0x03f1,0x03f2,0x03f3,0x03f4,0x03f5,0x03f6,0x0400,0x0401,0x0402,0x0403,\n  0x0404,0x0405,0x0406,0x0407,0x0408,0x0409,0x040a,0x040b,0x040c,0x040d,0x040e,0x040f,0x0410,0x0411,0x0412,0x0413,\n  0x0414,0x0415,0x0416,0x0417,0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e,0x041f,0x0420,0x0421,0x0422,0x0423,\n  0x0424,0x0425,0x0426,0x0427,0x0428,0x0429,0x042a,0x042b,0x042c,0x042d,0x042e,0x042f,0x0430,0x0431,0x0432,0x0433,\n  0x0434,0x0435,0x0436,0x0437,0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e,0x043f,0x0440,0x0441,0x0442,0x0443,\n  0x0444,0x0445,0x0446,0x0447,0x0448,0x0449,0x044a,0x044b,0x044c,0x044d,0x044e,0x044f,0x0450,0x0451,0x0452,0x0453,\n  0x0454,0x0455,0x0456,0x0457,0x0458,0x0459,0x045a,0x045b,0x045c,0x045d,0x045e,0x045f,0x0462,0x0463,0x046a,0x046b,\n  0x0490,0x0491,0x0492,0x0493,0x0494,0x0495,0x0496,0x0497,0x0498,0x0499,0x049a,0x049b,0x049c,0x049d,0x04a0,0x04a1,\n  0x04a2,0x04a3,0x04a4,0x04a5,0x04aa,0x04ab,0x04ae,0x04af,0x04b0,0x04b1,0x04b2,0x04b3,0x04b6,0x04b7,0x04b8,0x04b9,\n  0x04ba,0x04bb,0x04c0,0x04c1,0x04c2,0x04cf,0x04d0,0x04d1,0x04d2,0x04d3,0x04d4,0x04d5,0x04d6,0x04d7,0x04d8,0x04d9,\n  0x04da,0x04db,0x04dc,0x04dd,0x04de,0x04df,0x04e2,0x04e3,0x04e4,0x04e5,0x04e6,0x04e7,0x04e8,0x04e9,0x04ea,0x04eb,\n  0x04ec,0x04ed,0x04ee,0x04ef,0x04f0,0x04f1,0x04f2,0x04f3,0x04f4,0x04f5,0x04f8,0x04f9,0x05d0,0x05d1,0x05d2,0x05d3,\n  0x05d4,0x05d5,0x05d6,0x05d7,0x05d8,0x05d9,0x05da,0x05db,0x05dc,0x05dd,0x05de,0x05df,0x05e0,0x05e1,0x05e2,0x05e3,\n  0x05e4,0x05e5,0x05e6,0x05e7,0x05e8,0x05e9,0x05ea,0x1e0c,0x1e0d,0x1e34,0x1e35,0x1e36,0x1e37,0x1e40,0x1e41,0x1e42,\n  0x1e43,0x1e44,0x1e45,0x1e46,0x1e47,0x1e6c,0x1e6d,0x1eb8,0x1eb9,0x1ebc,0x1ebd,0x1eca,0x1ecb,0x1ecc,0x1ecd,0x1ee4,\n  0x1ee5,0x1ef8,0x1ef9,0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007,0x2008,0x2009,0x200a,0x200b,0x200c,\n  0x200d,0x200e,0x200f,0x2010,0x2011,0x2012,0x2013,0x2014,0x2015,0x2016,0x2017,0x2018,0x2019,0x201a,0x201b,0x201c,\n  0x201d,0x201e,0x201f,0x2020,0x2021,0x2022,0x2026,0x2030,0x2032,0x2033,0x2039,0x203a,0x203c,0x203e,0x2070,0x2071,\n  0x2074,0x2075,0x2076,0x2077,0x2078,0x2079,0x207a,0x207b,0x207c,0x207d,0x207e,0x207f,0x2080,0x2081,0x2082,0x2083,\n  0x2084,0x2085,0x2086,0x2087,0x2088,0x2089,0x208a,0x208b,0x208c,0x208d,0x208e,0x2090,0x2091,0x2092,0x2093,0x2094,\n  0x2095,0x2096,0x2097,0x2098,0x209a,0x20a7,0x20aa,0x20ac,0x20ae,0x2102,0x210e,0x210f,0x2115,0x2116,0x211a,0x211d,\n  0x2122,0x2124,0x2126,0x2135,0x2190,0x2191,0x2192,0x2193,0x2194,0x2195,0x21a4,0x21a6,0x21a8,0x21b5,0x21bb,0x21cb,\n  0x21cc,0x21d0,0x21d1,0x21d2,0x21d3,0x21d4,0x21d5,0x2200,0x2203,0x2204,0x2205,0x2206,0x2207,0x2208,0x2209,0x220a,\n  0x220b,0x220c,0x220d,0x2212,0x2213,0x2214,0x2215,0x2216,0x2219,0x221a,0x221e,0x221f,0x2225,0x2227,0x2228,0x2229,\n  0x222a,0x2248,0x2260,0x2261,0x2264,0x2265,0x226a,0x226b,0x2282,0x2283,0x2286,0x2287,0x22a5,0x22c2,0x22c3,0x2300,\n  0x2302,0x2308,0x2309,0x230a,0x230b,0x2310,0x2319,0x2320,0x2321,0x239b,0x239c,0x239d,0x239e,0x239f,0x23a0,0x23a1,\n  0x23a2,0x23a3,0x23a4,0x23a5,0x23a6,0x23a7,0x23a8,0x23a9,0x23ab,0x23ac,0x23ad,0x23ae,0x23af,0x23ba,0x23bb,0x23bc,\n  0x23bd,0x23d0,0x2409,0x240a,0x240b,0x240c,0x240d,0x2424,0x2500,0x2501,0x2502,0x2503,0x2508,0x2509,0x250a,0x250b,\n  0x250c,0x250d,0x250e,0x250f,0x2510,0x2511,0x2512,0x2513,0x2514,0x2515,0x2516,0x2517,0x2518,0x2519,0x251a,0x251b,\n  0x251c,0x251d,0x251e,0x251f,0x2520,0x2521,0x2522,0x2523,0x2524,0x2525,0x2526,0x2527,0x2528,0x2529,0x252a,0x252b,\n  0x252c,0x252d,0x252e,0x252f,0x2530,0x2531,0x2532,0x2533,0x2534,0x2535,0x2536,0x2537,0x2538,0x2539,0x253a,0x253b,\n  0x253c,0x253d,0x253e,0x253f,0x2540,0x2541,0x2542,0x2543,0x2544,0x2545,0x2546,0x2547,0x2548,0x2549,0x254a,0x254b,\n  0x2550,0x2551,0x2552,0x2553,0x2554,0x2555,0x2556,0x2557,0x2558,0x2559,0x255a,0x255b,0x255c,0x255d,0x255e,0x255f,\n  0x2560,0x2561,0x2562,0x2563,0x2564,0x2565,0x2566,0x2567,0x2568,0x2569,0x256a,0x256b,0x256c,0x256d,0x256e,0x256f,\n  0x2570,0x2571,0x2572,0x2573,0x2574,0x2575,0x2576,0x2577,0x2578,0x2579,0x257a,0x257b,0x257c,0x257d,0x257e,0x257f,\n  0x2580,0x2581,0x2582,0x2583,0x2584,0x2585,0x2586,0x2587,0x2588,0x2589,0x258a,0x258b,0x258c,0x258d,0x258e,0x258f,\n  0x2590,0x2591,0x2592,0x2593,0x2596,0x2597,0x2598,0x2599,0x259a,0x259b,0x259c,0x259d,0x259e,0x259f,0x25a0,0x25ac,\n  0x25ae,0x25b2,0x25b6,0x25ba,0x25bc,0x25c0,0x25c4,0x25c6,0x25ca,0x25cb,0x25cf,0x25d8,0x25d9,0x263a,0x263b,0x263c,\n  0x2640,0x2642,0x2660,0x2663,0x2665,0x2666,0x266a,0x266b,0x2713,0x2714,0x2717,0x2718,0x27e8,0x27e9,0x27ea,0x27eb,\n  0x2800,0x2801,0x2802,0x2803,0x2804,0x2805,0x2806,0x2807,0x2808,0x2809,0x280a,0x280b,0x280c,0x280d,0x280e,0x280f,\n  0x2810,0x2811,0x2812,0x2813,0x2814,0x2815,0x2816,0x2817,0x2818,0x2819,0x281a,0x281b,0x281c,0x281d,0x281e,0x281f,\n  0x2820,0x2821,0x2822,0x2823,0x2824,0x2825,0x2826,0x2827,0x2828,0x2829,0x282a,0x282b,0x282c,0x282d,0x282e,0x282f,\n  0x2830,0x2831,0x2832,0x2833,0x2834,0x2835,0x2836,0x2837,0x2838,0x2839,0x283a,0x283b,0x283c,0x283d,0x283e,0x283f,\n  0x2840,0x2841,0x2842,0x2843,0x2844,0x2845,0x2846,0x2847,0x2848,0x2849,0x284a,0x284b,0x284c,0x284d,0x284e,0x284f,\n  0x2850,0x2851,0x2852,0x2853,0x2854,0x2855,0x2856,0x2857,0x2858,0x2859,0x285a,0x285b,0x285c,0x285d,0x285e,0x285f,\n  0x2860,0x2861,0x2862,0x2863,0x2864,0x2865,0x2866,0x2867,0x2868,0x2869,0x286a,0x286b,0x286c,0x286d,0x286e,0x286f,\n  0x2870,0x2871,0x2872,0x2873,0x2874,0x2875,0x2876,0x2877,0x2878,0x2879,0x287a,0x287b,0x287c,0x287d,0x287e,0x287f,\n  0x2880,0x2881,0x2882,0x2883,0x2884,0x2885,0x2886,0x2887,0x2888,0x2889,0x288a,0x288b,0x288c,0x288d,0x288e,0x288f,\n  0x2890,0x2891,0x2892,0x2893,0x2894,0x2895,0x2896,0x2897,0x2898,0x2899,0x289a,0x289b,0x289c,0x289d,0x289e,0x289f,\n  0x28a0,0x28a1,0x28a2,0x28a3,0x28a4,0x28a5,0x28a6,0x28a7,0x28a8,0x28a9,0x28aa,0x28ab,0x28ac,0x28ad,0x28ae,0x28af,\n  0x28b0,0x28b1,0x28b2,0x28b3,0x28b4,0x28b5,0x28b6,0x28b7,0x28b8,0x28b9,0x28ba,0x28bb,0x28bc,0x28bd,0x28be,0x28bf,\n  0x28c0,0x28c1,0x28c2,0x28c3,0x28c4,0x28c5,0x28c6,0x28c7,0x28c8,0x28c9,0x28ca,0x28cb,0x28cc,0x28cd,0x28ce,0x28cf,\n  0x28d0,0x28d1,0x28d2,0x28d3,0x28d4,0x28d5,0x28d6,0x28d7,0x28d8,0x28d9,0x28da,0x28db,0x28dc,0x28dd,0x28de,0x28df,\n  0x28e0,0x28e1,0x28e2,0x28e3,0x28e4,0x28e5,0x28e6,0x28e7,0x28e8,0x28e9,0x28ea,0x28eb,0x28ec,0x28ed,0x28ee,0x28ef,\n  0x28f0,0x28f1,0x28f2,0x28f3,0x28f4,0x28f5,0x28f6,0x28f7,0x28f8,0x28f9,0x28fa,0x28fb,0x28fc,0x28fd,0x28fe,0x28ff,\n  0x2e2c,0xe0a0,0xe0a1,0xe0a2,0xe0b0,0xe0b1,0xe0b2,0xe0b3,0xf6be,0xfffd };\n} // namespace\n// -- end of autogenerated text ---\n\nnamespace fixed_font_24b {\n  // -- start of autogenerated text ---\n  // definition section for font: ter-u24b.bdf\n  constexpr int CHARCOUNT = 1354;\n  constexpr int WIDTH = 12;\n  constexpr int HEIGHT = 24;\n  constexpr int OFFSET_X = 0;\n  constexpr int OFFSET_Y = 0;\n  constexpr FixedFont_info_t fixedfont_info = {\n    \"Terminus\", // font name\n    \"ter-u24b.bdf\", // font name internal\n    CHARCOUNT, // num of chars\n    WIDTH, HEIGHT, OFFSET_X, OFFSET_Y,\n    true // bold\n  };\n  // font bitmap definitions\n  constexpr std::array<uint16_t, CHARCOUNT * HEIGHT> fixedfont_bitmap = {\n  0x0000,0x0000,0x0000,0x0000,0x79e0,0x6060,0x6060,0x6060,0x0000,0x0000,0x6060,0x6060,0x6060,0x0000,0x0000,0x6060,\n  0x6060,0x6060,0x79e0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0020\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000,0x0000,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u0021\n  0x0000,0x0000,0x1980,0x1980,0x1980,0x1980,0x1980,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0022\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,0x1980,0x7fe0,0x1980,0x1980,0x1980,0x1980,0x1980,0x7fe0,0x1980,\n  0x1980,0x1980,0x1980,0x0000,0x0000,0x0000,0x0000,0x0000, // u0023\n  0x0000,0x0000,0x0000,0x0600,0x0600,0x1f80,0x36c0,0x6660,0x6600,0x6600,0x3600,0x1f80,0x06c0,0x0660,0x0660,0x6660,\n  0x36c0,0x1f80,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u0024\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x38c0,0x6cc0,0x6d80,0x3980,0x0300,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x19c0,\n  0x1b60,0x3360,0x31c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0025\n  0x0000,0x0000,0x0000,0x0000,0x0e00,0x1b00,0x3180,0x3180,0x3180,0x1b00,0x0e00,0x1e60,0x3360,0x61c0,0x60c0,0x60c0,\n  0x61c0,0x3360,0x1e60,0x0000,0x0000,0x0000,0x0000,0x0000, // u0026\n  0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0027\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x0c00,\n  0x0c00,0x0600,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000, // u0028\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x0c00,0x0600,0x0600,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0600,\n  0x0600,0x0c00,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000, // u0029\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x3180,0x1b00,0x0e00,0xffe0,0x0e00,0x1b00,0x3180,0x60c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x7fe0,0x0600,0x0600,0x0600,0x0600,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,\n  0x0600,0x0600,0x0600,0x0c00,0x0000,0x0000,0x0000,0x0000, // u002c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u002e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x0180,0x0180,0x0300,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x1800,\n  0x1800,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002f\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x60e0,0x61e0,0x6360,0x6660,0x6c60,0x7860,0x7060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0030\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0e00,0x1e00,0x3600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0031\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,\n  0x3000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0032\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x0060,0x0060,0x0060,0x00c0,0x0f80,0x00c0,0x0060,0x0060,0x0060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0033\n  0x0000,0x0000,0x0000,0x0000,0x0060,0x00e0,0x01e0,0x0360,0x0660,0x0c60,0x1860,0x3060,0x6060,0x6060,0x6060,0x7fe0,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0034\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x00c0,0x0060,0x0060,0x0060,0x0060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0035\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0036\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6060,0x6060,0x0060,0x00c0,0x00c0,0x0180,0x0180,0x0300,0x0300,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u0037\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x30c0,0x1f80,0x30c0,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0038\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x3060,0x1fe0,0x0060,0x0060,0x0060,\n  0x0060,0x00c0,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0600,\n  0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0600,\n  0x0600,0x0600,0x0600,0x0c00,0x0000,0x0000,0x0000,0x0000, // u003b\n  0x0000,0x0000,0x0000,0x0000,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x3000,0x1800,0x0c00,0x0600,\n  0x0300,0x0180,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u003c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003d\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x00c0,0x0180,0x0300,0x0600,0x0c00,\n  0x1800,0x3000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003e\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x00c0,0x0180,0x0300,0x0600,0x0600,0x0000,0x0000,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u003f\n  0x0000,0x0000,0x0000,0x0000,0x3f80,0x60c0,0xc060,0xc3e0,0xc660,0xcc60,0xcc60,0xcc60,0xcc60,0xcc60,0xc660,0xc3e0,\n  0xc000,0x6000,0x3fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0040\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0041\n  0x0000,0x0000,0x0000,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x60c0,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x60c0,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0042\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0043\n  0x0000,0x0000,0x0000,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x60c0,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0044\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0045\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0046\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6000,0x6000,0x6000,0x63e0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0047\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0048\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0049\n  0x0000,0x0000,0x0000,0x0000,0x03f0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x60c0,0x60c0,\n  0x60c0,0x3180,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u004a\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x60c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7000,0x7800,0x6c00,0x6600,0x6300,\n  0x6180,0x60c0,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u004b\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u004c\n  0x0000,0x0000,0x0000,0x0000,0x8020,0xc060,0xe0e0,0xf1e0,0xdb60,0xce60,0xc460,0xc060,0xc060,0xc060,0xc060,0xc060,\n  0xc060,0xc060,0xc060,0x0000,0x0000,0x0000,0x0000,0x0000, // u004d\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x7060,0x7860,0x6c60,0x6660,0x6360,0x61e0,0x60e0,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u004e\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u004f\n  0x0000,0x0000,0x0000,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x60c0,0x7f80,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0050\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6660,0x33c0,0x1f80,0x00c0,0x0060,0x0000,0x0000,0x0000, // u0051\n  0x0000,0x0000,0x0000,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x60c0,0x7f80,0x7800,0x6c00,0x6600,0x6300,\n  0x6180,0x60c0,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0052\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6000,0x6000,0x6000,0x3000,0x1f80,0x00c0,0x0060,0x0060,0x0060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0053\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u0054\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0055\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x30c0,0x30c0,0x30c0,0x30c0,0x1980,0x1980,0x1980,0x0f00,\n  0x0f00,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u0056\n  0x0000,0x0000,0x0000,0x0000,0xc060,0xc060,0xc060,0xc060,0xc060,0xc060,0xc060,0xc060,0xc460,0xce60,0xdb60,0xf1e0,\n  0xe0e0,0xc060,0x8020,0x0000,0x0000,0x0000,0x0000,0x0000, // u0057\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x30c0,0x30c0,0x1980,0x1980,0x0f00,0x0600,0x0f00,0x1980,0x1980,0x30c0,\n  0x30c0,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0058\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x30c0,0x30c0,0x1980,0x1980,0x0f00,0x0f00,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u0059\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0060,0x0060,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u005a\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,\n  0x1800,0x1800,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u005b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x1800,0x1800,0x0c00,0x0c00,0x0600,0x0600,0x0300,0x0300,0x0180,\n  0x0180,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u005c\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u005d\n  0x0000,0x0000,0x0600,0x0f00,0x1980,0x30c0,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0000,0x0000,0x0000, // u005f\n  0x1800,0x0c00,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0060\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x00c0,0x0060,0x0060,0x1fe0,0x3060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0061\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x60c0,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0062\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0063\n  0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x1fe0,0x3060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0064\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x7fe0,0x6000,0x6000,\n  0x6000,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0065\n  0x0000,0x0000,0x0000,0x0000,0x03e0,0x0600,0x0600,0x0600,0x3fc0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u0066\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fe0,0x3060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30e0,0x1fe0,0x0060,0x0060,0x00c0,0x3f80,0x0000, // u0067\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0068\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0069\n  0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x03c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x30c0,0x30c0,0x1980,0x0f00,0x0000, // u006a\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3060,0x30c0,0x3180,0x3300,0x3600,0x3c00,0x3600,0x3300,\n  0x3180,0x30c0,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000, // u006b\n  0x0000,0x0000,0x0000,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u006c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x66c0,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,\n  0x6660,0x6660,0x6660,0x0000,0x0000,0x0000,0x0000,0x0000, // u006d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u006e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u006f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x60c0,0x7f80,0x6000,0x6000,0x6000,0x6000,0x0000, // u0070\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fe0,0x3060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0060,0x0060,0x0060,0x0060,0x0000, // u0071\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x67e0,0x6c00,0x7800,0x7000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0072\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x6060,0x6000,0x6000,0x6000,0x3fc0,0x0060,0x0060,\n  0x0060,0x6060,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0073\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x07c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0074\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0075\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x30c0,0x30c0,0x1980,0x1980,0x0f00,\n  0x0f00,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u0076\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6660,0x6660,0x6660,0x6660,\n  0x6660,0x6660,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0077\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x30c0,0x1980,0x0f00,0x0600,0x0f00,0x1980,\n  0x30c0,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0078\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30e0,0x1fe0,0x0060,0x0060,0x00c0,0x3f80,0x0000, // u0079\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,\n  0x3000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u007a\n  0x0000,0x0000,0x0000,0x0000,0x0380,0x0600,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x3800,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0600,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000, // u007b\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u007c\n  0x0000,0x0000,0x0000,0x0000,0x3800,0x0c00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0380,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0c00,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000, // u007d\n  0x0000,0x0000,0x3c60,0x6660,0x6660,0x63c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a0\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x1f80,0x36c0,0x6660,0x6600,0x6600,0x6600,0x6600,0x6600,\n  0x6660,0x36c0,0x1f80,0x0600,0x0600,0x0000,0x0000,0x0000, // u00a2\n  0x0000,0x0000,0x0000,0x0000,0x0f00,0x1980,0x30c0,0x3000,0x3000,0x3000,0x3000,0x7f00,0x3000,0x3000,0x3000,0x3000,\n  0x3060,0x3060,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc060,0x60c0,0x3f80,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3f80,\n  0x60c0,0xc060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a4\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x30c0,0x30c0,0x1980,0x1980,0x0f00,0x0600,0x0600,0x3fc0,0x0600,0x0600,\n  0x3fc0,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a5\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a6\n  0x0000,0x0000,0x0000,0x1f00,0x3180,0x3000,0x3000,0x1e00,0x3300,0x3180,0x3180,0x3180,0x3180,0x1980,0x0f00,0x0180,\n  0x0180,0x3180,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a7\n  0x1980,0x1980,0x1980,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x4040,0x9f20,0xb1a0,0xb1a0,0xb020,0xb020,0xb1a0,0xb1a0,0x9f20,\n  0x4040,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a9\n  0x0000,0x3f80,0x00c0,0x00c0,0x3fc0,0x60c0,0x60c0,0x60c0,0x60c0,0x3fc0,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0660,0x0cc0,0x1980,0x3300,0x6600,0xcc00,0x6600,0x3300,\n  0x1980,0x0cc0,0x0660,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ab\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0060,0x0060,0x0060,0x0060,0x0060,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ac\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ad\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x4040,0xbf20,0xb1a0,0xb1a0,0xb1a0,0xbf20,0xb620,0xb320,0xb1a0,\n  0x4040,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ae\n  0x0000,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00af\n  0x0000,0x0000,0x1f00,0x3180,0x3180,0x3180,0x3180,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x7fe0,0x0600,0x0600,0x0600,0x0600,\n  0x0000,0x0000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b1\n  0x0000,0x0000,0x1f00,0x3180,0x3180,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b2\n  0x0000,0x0000,0x1f00,0x3180,0x0180,0x0180,0x0f00,0x0180,0x0180,0x3180,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b3\n  0x0180,0x0300,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x60e0,0x61e0,0x7f60,0x6000,0x6000,0x6000,0x6000,0x0000, // u00b5\n  0x0000,0x0000,0x0000,0x0000,0x3fe0,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x3e60,0x0660,0x0660,0x0660,0x0660,\n  0x0660,0x0660,0x0660,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0c00,0x0000, // u00b8\n  0x0000,0x0000,0x0600,0x0e00,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b9\n  0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x3180,0x1f00,0x0000,0x7fc0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xcc00,0x6600,0x3300,0x1980,0x0cc0,0x0660,0x0cc0,0x1980,\n  0x3300,0x6600,0xcc00,0x0000,0x0000,0x0000,0x0000,0x0000, // u00bb\n  0x0000,0x0000,0x0000,0x0c00,0x1c00,0x3c00,0x0c00,0x0c20,0x0c60,0x0cc0,0x0180,0x0300,0x0660,0x0ce0,0x19e0,0x3360,\n  0x6660,0x47e0,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000, // u00bc\n  0x0000,0x0000,0x0000,0x0c00,0x1c00,0x3c00,0x0c20,0x0c60,0x0cc0,0x0d80,0x0300,0x0600,0x0c00,0x1bc0,0x3660,0x6660,\n  0x40c0,0x0180,0x0300,0x07e0,0x0000,0x0000,0x0000,0x0000, // u00bd\n  0x0000,0x0000,0x0000,0x3c00,0x6600,0x0600,0x1c00,0x0620,0x6660,0x3cc0,0x0180,0x0300,0x0660,0x0ce0,0x19e0,0x3360,\n  0x6660,0x47e0,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000, // u00be\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0c00,0x1800,0x3000,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00bf\n  0x1800,0x0c00,0x0600,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c0\n  0x0180,0x0300,0x0600,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c1\n  0x0600,0x0f00,0x1980,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c2\n  0x1cc0,0x36c0,0x3380,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c3\n  0x1980,0x1980,0x1980,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c4\n  0x0f00,0x1980,0x1980,0x0f00,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c5\n  0x0000,0x0000,0x0000,0x0000,0x3ff0,0x6300,0xc300,0xc300,0xc300,0xc300,0xc300,0xfff0,0xc300,0xc300,0xc300,0xc300,\n  0xc300,0xc300,0xc3f0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c6\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6060,\n  0x6060,0x30c0,0x1f80,0x0600,0x0600,0x0600,0x0c00,0x0000, // u00c7\n  0x1800,0x0c00,0x0600,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c8\n  0x0180,0x0300,0x0600,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c9\n  0x0600,0x0f00,0x1980,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ca\n  0x1980,0x1980,0x1980,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cb\n  0x1800,0x0c00,0x0600,0x0000,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cc\n  0x0180,0x0300,0x0600,0x0000,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cd\n  0x0600,0x0f00,0x1980,0x0000,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ce\n  0x1980,0x1980,0x1980,0x0000,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cf\n  0x0000,0x0000,0x0000,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0xfe60,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x60c0,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d0\n  0x1cc0,0x36c0,0x3380,0x0000,0x6060,0x6060,0x6060,0x6060,0x7060,0x7860,0x6c60,0x6660,0x6360,0x61e0,0x60e0,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d1\n  0x1800,0x0c00,0x0600,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d2\n  0x0180,0x0300,0x0600,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d3\n  0x0600,0x0f00,0x1980,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d4\n  0x1cc0,0x36c0,0x3380,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d5\n  0x1980,0x1980,0x1980,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x30c0,0x1980,0x0f00,0x0600,0x0f00,0x1980,0x30c0,0x6060,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d7\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6070,0x6060,0x60e0,0x61e0,0x6360,0x6660,0x6c60,0x7860,0x7060,0x6060,\n  0xe060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d8\n  0x1800,0x0c00,0x0600,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d9\n  0x0180,0x0300,0x0600,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00da\n  0x0600,0x0f00,0x1980,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00db\n  0x1980,0x1980,0x1980,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00dc\n  0x0180,0x0300,0x0600,0x0000,0x6060,0x6060,0x30c0,0x30c0,0x1980,0x1980,0x0f00,0x0f00,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u00dd\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x60c0,0x7f80,0x6000,\n  0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00de\n  0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x60c0,0x60c0,0x60c0,0x6180,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,\n  0x7060,0x68c0,0x6f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00df\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x0c00,0x0600,0x0000,0x3f80,0x00c0,0x0060,0x0060,0x1fe0,0x3060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e0\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x3f80,0x00c0,0x0060,0x0060,0x1fe0,0x3060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e1\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0f00,0x1980,0x0000,0x3f80,0x00c0,0x0060,0x0060,0x1fe0,0x3060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e2\n  0x0000,0x0000,0x0000,0x0000,0x1cc0,0x36c0,0x3380,0x0000,0x3f80,0x00c0,0x0060,0x0060,0x1fe0,0x3060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e3\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,0x0000,0x3f80,0x00c0,0x0060,0x0060,0x1fe0,0x3060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e4\n  0x0000,0x0000,0x0000,0x0000,0x0f00,0x1980,0x1980,0x0f00,0x3f80,0x00c0,0x0060,0x0060,0x1fe0,0x3060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7be0,0x0e30,0x0630,0x0630,0x7e30,0xc7f0,0xc600,0xc600,\n  0xc600,0xc730,0x7de0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6060,0x30c0,0x1f80,0x0600,0x0600,0x0600,0x0c00,0x0000, // u00e7\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x0c00,0x0600,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x7fe0,0x6000,0x6000,\n  0x6000,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e8\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x7fe0,0x6000,0x6000,\n  0x6000,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e9\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0f00,0x1980,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x7fe0,0x6000,0x6000,\n  0x6000,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ea\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x7fe0,0x6000,0x6000,\n  0x6000,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00eb\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x0c00,0x0600,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ec\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ed\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0f00,0x1980,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ee\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ef\n  0x0000,0x0000,0x0000,0x0000,0x3600,0x1c00,0x3600,0x0300,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f0\n  0x0000,0x0000,0x0000,0x0000,0x1cc0,0x36c0,0x3380,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f1\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x0c00,0x0600,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f2\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f3\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0f00,0x1980,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f4\n  0x0000,0x0000,0x0000,0x0000,0x1cc0,0x36c0,0x3380,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f5\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0000,0x0000,0x7fe0,0x0000,0x0000,0x0600,0x0600,\n  0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fa0,0x30c0,0x60e0,0x61e0,0x6360,0x6660,0x6c60,0x7860,\n  0x7060,0x30c0,0x5f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f8\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x0c00,0x0600,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f9\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00fa\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0f00,0x1980,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00fb\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00fc\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30e0,0x1fe0,0x0060,0x0060,0x00c0,0x3f80,0x0000, // u00fd\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x60c0,0x7f80,0x6000,0x6000,0x6000,0x6000,0x0000, // u00fe\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30e0,0x1fe0,0x0060,0x0060,0x00c0,0x3f80,0x0000, // u00ff\n  0x0000,0x3fc0,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0100\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x0000,0x0000,0x3f80,0x00c0,0x0060,0x0060,0x1fe0,0x3060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0101\n  0x30c0,0x30c0,0x1f80,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0102\n  0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x1f80,0x0000,0x3f80,0x00c0,0x0060,0x0060,0x1fe0,0x3060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0103\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x00c0,0x0180,0x0180,0x00f0,0x0000, // u0104\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x00c0,0x0060,0x0060,0x1fe0,0x3060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x00c0,0x0180,0x0180,0x00f0,0x0000, // u0105\n  0x0180,0x0300,0x0600,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0106\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x1f80,0x30c0,0x6060,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0107\n  0x0600,0x0f00,0x1980,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0108\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0f00,0x1980,0x0000,0x1f80,0x30c0,0x6060,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0109\n  0x0600,0x0600,0x0600,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u010a\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0000,0x1f80,0x30c0,0x6060,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u010b\n  0x1980,0x0f00,0x0600,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u010c\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x0f00,0x0600,0x0000,0x1f80,0x30c0,0x6060,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u010d\n  0x1980,0x0f00,0x0600,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x60c0,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u010e\n  0x1980,0x0f00,0x0600,0x0000,0x0060,0x0060,0x0060,0x0060,0x1fe0,0x3060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u010f\n  0x0000,0x0000,0x0000,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0xfe60,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x60c0,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0110\n  0x0000,0x0000,0x0000,0x0000,0x0060,0x07f0,0x0060,0x0060,0x1fe0,0x3060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0111\n  0x0000,0x3fc0,0x0000,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0112\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x7fe0,0x6000,0x6000,\n  0x6000,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0113\n  0x30c0,0x30c0,0x1f80,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0114\n  0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x1f80,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x7fe0,0x6000,0x6000,\n  0x6000,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0115\n  0x0600,0x0600,0x0600,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0116\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x7fe0,0x6000,0x6000,\n  0x6000,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0117\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x7fe0,0x00c0,0x0180,0x0180,0x00f0,0x0000, // u0118\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x7fe0,0x6000,0x6000,\n  0x6000,0x3060,0x1fc0,0x0300,0x0600,0x0600,0x03c0,0x0000, // u0119\n  0x1980,0x0f00,0x0600,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u011a\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x0f00,0x0600,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x7fe0,0x6000,0x6000,\n  0x6000,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u011b\n  0x0600,0x0f00,0x1980,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6000,0x6000,0x6000,0x63e0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u011c\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0f00,0x1980,0x0000,0x1fe0,0x3060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30e0,0x1fe0,0x0060,0x0060,0x00c0,0x3f80,0x0000, // u011d\n  0x30c0,0x30c0,0x1f80,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6000,0x6000,0x6000,0x63e0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u011e\n  0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x1f80,0x0000,0x1fe0,0x3060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30e0,0x1fe0,0x0060,0x0060,0x00c0,0x3f80,0x0000, // u011f\n  0x0600,0x0600,0x0600,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6000,0x6000,0x6000,0x63e0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0120\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0000,0x1fe0,0x3060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30e0,0x1fe0,0x0060,0x0060,0x00c0,0x3f80,0x0000, // u0121\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6000,0x6000,0x6000,0x63e0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0600,0x0600,0x0600,0x0c00, // u0122\n  0x0000,0x0000,0x0000,0x0180,0x0300,0x0300,0x0300,0x0000,0x1fe0,0x3060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30e0,0x1fe0,0x0060,0x0060,0x00c0,0x3f80,0x0000, // u0123\n  0x0600,0x0f00,0x1980,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0124\n  0x0600,0x0f00,0x1980,0x0000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0125\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0xfff0,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0126\n  0x0000,0x0000,0x0000,0x0000,0x6000,0xfe00,0x6000,0x6000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0127\n  0x1cc0,0x36c0,0x3380,0x0000,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0128\n  0x0000,0x0000,0x0000,0x0000,0x1cc0,0x36c0,0x3380,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0129\n  0x0000,0x3fc0,0x0000,0x0000,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u012a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x0000,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u012b\n  0x30c0,0x30c0,0x1f80,0x0000,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u012c\n  0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x1f80,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u012d\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0600,0x0c00,0x0c00,0x0780,0x0000, // u012e\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0600,0x0c00,0x0c00,0x0780,0x0000, // u012f\n  0x0600,0x0600,0x0600,0x0000,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0130\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0131\n  0x0000,0x0000,0x0000,0x0000,0xf0f0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6c60,0x6c60,\n  0x6c60,0x6c60,0xf7c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0132\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x0000,0xe0e0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0xf060,0x0c60,0x0c60,0x0c60,0x07c0,0x0000, // u0133\n  0x00c0,0x01e0,0x0330,0x0000,0x03f0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x60c0,0x60c0,\n  0x60c0,0x3180,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0134\n  0x0000,0x0000,0x0000,0x0000,0x00c0,0x01e0,0x0330,0x0000,0x03c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x30c0,0x30c0,0x1980,0x0f00,0x0000, // u0135\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x60c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7000,0x7800,0x6c00,0x6600,0x6300,\n  0x6180,0x60c0,0x6060,0x0000,0x0600,0x0600,0x0600,0x0c00, // u0136\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3060,0x30c0,0x3180,0x3300,0x3600,0x3c00,0x3600,0x3300,\n  0x3180,0x30c0,0x3060,0x0000,0x0600,0x0600,0x0600,0x0c00, // u0137\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x30c0,0x3180,0x3300,0x3600,0x3c00,0x3600,0x3300,\n  0x3180,0x30c0,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0138\n  0x1800,0x3000,0x6000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0139\n  0x0180,0x0300,0x0600,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u013a\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0600,0x0600,0x0600,0x0c00, // u013b\n  0x0000,0x0000,0x0000,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0600,0x0600,0x0600,0x0c00, // u013c\n  0x1980,0x0f00,0x0600,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u013d\n  0x1980,0x0f00,0x0600,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u013e\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x6180,0x6180,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u013f\n  0x0000,0x0000,0x0000,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0630,0x0630,0x0630,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0140\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3c00,0x3800,0x3000,0x7000,0xf000,0x3000,0x3000,\n  0x3000,0x3000,0x3ff0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0141\n  0x0000,0x0000,0x0000,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0780,0x0700,0x0600,0x0e00,0x1e00,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0142\n  0x0180,0x0300,0x0600,0x0000,0x6060,0x6060,0x6060,0x6060,0x7060,0x7860,0x6c60,0x6660,0x6360,0x61e0,0x60e0,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0143\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0144\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x7060,0x7860,0x6c60,0x6660,0x6360,0x61e0,0x60e0,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0600,0x0600,0x0600,0x0c00, // u0145\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0600,0x0600,0x0600,0x0c00, // u0146\n  0x1980,0x0f00,0x0600,0x0000,0x6060,0x6060,0x6060,0x6060,0x7060,0x7860,0x6c60,0x6660,0x6360,0x61e0,0x60e0,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0147\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x0f00,0x0600,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0148\n  0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0xc000,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0149\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x7060,0x7860,0x6c60,0x6660,0x6360,0x61e0,0x60e0,0x6060,\n  0x6060,0x6060,0x6060,0x0060,0x0060,0x00c0,0x0380,0x0000, // u014a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0060,0x0060,0x00c0,0x0380,0x0000, // u014b\n  0x0000,0x3fc0,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u014c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u014d\n  0x30c0,0x30c0,0x1f80,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u014e\n  0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x1f80,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u014f\n  0x0660,0x0cc0,0x1980,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0150\n  0x0000,0x0000,0x0000,0x0000,0x0660,0x0cc0,0x1980,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0151\n  0x0000,0x0000,0x0000,0x0000,0x3ff0,0x6300,0xc300,0xc300,0xc300,0xc300,0xc300,0xc3f0,0xc300,0xc300,0xc300,0xc300,\n  0xc300,0x6300,0x3ff0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0152\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x6660,0xc630,0xc630,0xc630,0xc7f0,0xc600,0xc600,\n  0xc600,0x6630,0x3fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0153\n  0x0180,0x0300,0x0600,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x60c0,0x7f80,0x7800,0x6c00,0x6600,0x6300,\n  0x6180,0x60c0,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0154\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x67e0,0x6c00,0x7800,0x7000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0155\n  0x0000,0x0000,0x0000,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x60c0,0x7f80,0x7800,0x6c00,0x6600,0x6300,\n  0x6180,0x60c0,0x6060,0x0000,0x0600,0x0600,0x0600,0x0c00, // u0156\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x67e0,0x6c00,0x7800,0x7000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x0000,0x6000,0x6000,0x6000,0xc000, // u0157\n  0x1980,0x0f00,0x0600,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x60c0,0x7f80,0x7800,0x6c00,0x6600,0x6300,\n  0x6180,0x60c0,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0158\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x0f00,0x0600,0x0000,0x67e0,0x6c00,0x7800,0x7000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0159\n  0x0180,0x0300,0x0600,0x0000,0x1f80,0x30c0,0x6060,0x6000,0x6000,0x6000,0x3000,0x1f80,0x00c0,0x0060,0x0060,0x0060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u015a\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x3fc0,0x6060,0x6000,0x6000,0x6000,0x3fc0,0x0060,0x0060,\n  0x0060,0x6060,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u015b\n  0x0600,0x0f00,0x1980,0x0000,0x1f80,0x30c0,0x6060,0x6000,0x6000,0x6000,0x3000,0x1f80,0x00c0,0x0060,0x0060,0x0060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u015c\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0f00,0x1980,0x0000,0x3fc0,0x6060,0x6000,0x6000,0x6000,0x3fc0,0x0060,0x0060,\n  0x0060,0x6060,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u015d\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6000,0x6000,0x6000,0x3000,0x1f80,0x00c0,0x0060,0x0060,0x0060,\n  0x6060,0x30c0,0x1f80,0x0600,0x0600,0x0600,0x0c00,0x0000, // u015e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x6060,0x6000,0x6000,0x6000,0x3fc0,0x0060,0x0060,\n  0x0060,0x6060,0x3fc0,0x0600,0x0600,0x0600,0x0c00,0x0000, // u015f\n  0x1980,0x0f00,0x0600,0x0000,0x1f80,0x30c0,0x6060,0x6000,0x6000,0x6000,0x3000,0x1f80,0x00c0,0x0060,0x0060,0x0060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0160\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x0f00,0x0600,0x0000,0x3fc0,0x6060,0x6000,0x6000,0x6000,0x3fc0,0x0060,0x0060,\n  0x0060,0x6060,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0161\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0300,0x0300,0x0300,0x0600,0x0000, // u0162\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x07c0,0x0300,0x0300,0x0300,0x0600,0x0000, // u0163\n  0x1980,0x0f00,0x0600,0x0000,0x7fe0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u0164\n  0x3300,0x1e00,0x0c00,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x07c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0165\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x3fc0,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u0166\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x07c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0167\n  0x1cc0,0x36c0,0x3380,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0168\n  0x0000,0x0000,0x0000,0x0000,0x1cc0,0x36c0,0x3380,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0169\n  0x0000,0x3fc0,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u016a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u016b\n  0x30c0,0x30c0,0x1f80,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u016c\n  0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x1f80,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u016d\n  0x0f00,0x1980,0x1980,0x0f00,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u016e\n  0x0000,0x0000,0x0000,0x0000,0x0f00,0x1980,0x1980,0x0f00,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u016f\n  0x0660,0x0cc0,0x1980,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0170\n  0x0000,0x0000,0x0000,0x0000,0x0660,0x0cc0,0x1980,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0171\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0600,0x0c00,0x0c00,0x0780,0x0000, // u0172\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x00c0,0x0180,0x0180,0x00f0,0x0000, // u0173\n  0x0600,0x0f00,0x1980,0x0000,0xc060,0xc060,0xc060,0xc060,0xc060,0xc060,0xc060,0xc060,0xc460,0xce60,0xdb60,0xf1e0,\n  0xe0e0,0xc060,0x8020,0x0000,0x0000,0x0000,0x0000,0x0000, // u0174\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0f00,0x1980,0x0000,0x6060,0x6060,0x6060,0x6060,0x6660,0x6660,0x6660,0x6660,\n  0x6660,0x6660,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0175\n  0x0600,0x0f00,0x1980,0x0000,0x6060,0x6060,0x30c0,0x30c0,0x1980,0x1980,0x0f00,0x0f00,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u0176\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0f00,0x1980,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30e0,0x1fe0,0x0060,0x0060,0x00c0,0x3f80,0x0000, // u0177\n  0x1980,0x1980,0x1980,0x0000,0x6060,0x6060,0x30c0,0x30c0,0x1980,0x1980,0x0f00,0x0f00,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u0178\n  0x0180,0x0300,0x0600,0x0000,0x7fe0,0x0060,0x0060,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0179\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x7fe0,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,\n  0x3000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u017a\n  0x0600,0x0600,0x0600,0x0000,0x7fe0,0x0060,0x0060,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u017b\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0000,0x7fe0,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,\n  0x3000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u017c\n  0x1980,0x0f00,0x0600,0x0000,0x7fe0,0x0060,0x0060,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u017d\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x0f00,0x0600,0x0000,0x7fe0,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,\n  0x3000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u017e\n  0x0000,0x0000,0x0000,0x0000,0x03e0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u017f\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0186\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x1fe0,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u018e\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x0060,0x0060,0x0060,0x0060,0x7fe0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u018f\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6000,0x6000,0x6000,0x3000,0x1f00,0x3000,0x6000,0x6000,0x6000,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0190\n  0x0000,0x0000,0x0000,0x0000,0x03c0,0x0660,0x0660,0x0600,0x0600,0x0600,0x3fc0,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x6600,0x6600,0x3c00,0x0000, // u0192\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x7060,0x7860,0x6c60,0x6660,0x6360,0x61e0,0x60e0,0x6060,\n  0x6060,0x6060,0x6060,0x6000,0x6000,0x6000,0xc000,0x0000, // u019d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0060,0x0060,0x0060,0x0060,0x0000, // u019e\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0060,0x0060,0x0060,0x00c0,0x0180,0x0300,0x7fe0,0x0600,0x0c00,0x1800,0x3000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0060,0x00c0,0x0180,0x0300,0x7fe0,0x0c00,0x1800,\n  0x3000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01b6\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0f80,0x00c0,0x0060,0x0060,0x0060,0x0060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u01b7\n  0x1980,0x0f00,0x0600,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u01cd\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x0f00,0x0600,0x0000,0x3f80,0x00c0,0x0060,0x0060,0x1fe0,0x3060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01ce\n  0x1980,0x0f00,0x0600,0x0000,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u01cf\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x0f00,0x0600,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d0\n  0x1980,0x0f00,0x0600,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d1\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x0f00,0x0600,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d2\n  0x1980,0x0f00,0x0600,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d3\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x0f00,0x0600,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d4\n  0x0000,0x3fe0,0x0000,0x0000,0x3ff0,0x6300,0xc300,0xc300,0xc300,0xc300,0xc300,0xfff0,0xc300,0xc300,0xc300,0xc300,\n  0xc300,0xc300,0xc3f0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3fe0,0x0000,0x0000,0x7be0,0x0e30,0x0630,0x0630,0x7e30,0xc7f0,0xc600,0xc600,\n  0xc600,0xc730,0x7de0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e3\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6000,0x6000,0x6000,0x63e0,0x6060,0x6060,0x63f0,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fe0,0x3060,0x6060,0x6060,0x6060,0x63f0,0x6060,0x6060,\n  0x6060,0x30e0,0x1fe0,0x0060,0x0060,0x00c0,0x3f80,0x0000, // u01e5\n  0x1980,0x0f00,0x0600,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6000,0x6000,0x6000,0x63e0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e6\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x0f00,0x0600,0x0000,0x1fe0,0x3060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30e0,0x1fe0,0x0060,0x0060,0x00c0,0x3f80,0x0000, // u01e7\n  0x1980,0x0f00,0x0600,0x0000,0x6060,0x60c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7000,0x7800,0x6c00,0x6600,0x6300,\n  0x6180,0x60c0,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e8\n  0x1980,0x0f00,0x0600,0x0000,0x3000,0x3000,0x3000,0x3000,0x3060,0x30c0,0x3180,0x3300,0x3600,0x3c00,0x3600,0x3300,\n  0x3180,0x30c0,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e9\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0600,0x0c00,0x0c00,0x0780,0x0000, // u01ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0600,0x0c00,0x0c00,0x0780,0x0000, // u01eb\n  0x0000,0x3fc0,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0600,0x0c00,0x0c00,0x0780,0x0000, // u01ec\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0600,0x0c00,0x0c00,0x0780,0x0000, // u01ed\n  0x1980,0x0f00,0x0600,0x0000,0x7fe0,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0f80,0x00c0,0x0060,0x0060,0x0060,0x0060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u01ee\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x0f00,0x0600,0x0000,0x7fe0,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0f80,0x00c0,\n  0x0060,0x0060,0x0060,0x0060,0x6060,0x30c0,0x1f80,0x0000, // u01ef\n  0x0000,0x0000,0x0000,0x0000,0x0330,0x01e0,0x00c0,0x0000,0x03c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x30c0,0x30c0,0x1980,0x0f00,0x0000, // u01f0\n  0x0180,0x0300,0x0600,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6000,0x6000,0x6000,0x63e0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u01f4\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x1fe0,0x3060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30e0,0x1fe0,0x0060,0x0060,0x00c0,0x3f80,0x0000, // u01f5\n  0x0180,0x0300,0x0600,0x0000,0x3ff0,0x6300,0xc300,0xc300,0xc300,0xc300,0xc300,0xfff0,0xc300,0xc300,0xc300,0xc300,\n  0xc300,0xc300,0xc3f0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01fc\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x7be0,0x0e30,0x0630,0x0630,0x7e30,0xc7f0,0xc600,0xc600,\n  0xc600,0xc730,0x7de0,0x0000,0x0000,0x0000,0x0000,0x0000, // u01fd\n  0x0180,0x0300,0x0600,0x0000,0x1f80,0x30c0,0x6070,0x6060,0x60e0,0x61e0,0x6360,0x6660,0x6c60,0x7860,0x7060,0x6060,\n  0xe060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u01fe\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x1fa0,0x30c0,0x60e0,0x61e0,0x6360,0x6660,0x6c60,0x7860,\n  0x7060,0x30c0,0x5f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u01ff\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6000,0x6000,0x6000,0x3000,0x1f80,0x00c0,0x0060,0x0060,0x0060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0600,0x0600,0x0600,0x0c00, // u0218\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x6060,0x6000,0x6000,0x6000,0x3fc0,0x0060,0x0060,\n  0x0060,0x6060,0x3fc0,0x0000,0x0600,0x0600,0x0600,0x0c00, // u0219\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0600,0x0600,0x0600,0x0c00, // u021a\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x07c0,0x0000,0x0300,0x0300,0x0300,0x0600, // u021b\n  0x0000,0x3fc0,0x0000,0x0000,0x6060,0x6060,0x30c0,0x30c0,0x1980,0x1980,0x0f00,0x0f00,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u0232\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30e0,0x1fe0,0x0060,0x0060,0x00c0,0x3f80,0x0000, // u0233\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x30c0,0x30c0,0x1980,0x0f00,0x0000, // u0237\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0254\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x7fe0,0x0060,0x0060,\n  0x0060,0x60c0,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0258\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x60c0,0x0060,0x0060,0x0060,0x7fe0,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0259\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x6060,0x6000,0x6000,0x6000,0x3f00,0x6000,0x6000,\n  0x6000,0x6060,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u025b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x6000,0x6000,0x6000,0xc000,0x0000, // u0272\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0f80,0x00c0,\n  0x0060,0x0060,0x0060,0x0060,0x6060,0x30c0,0x1f80,0x0000, // u0292\n  0x0300,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bb\n  0x0600,0x0600,0x0600,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bc\n  0x0600,0x0600,0x0600,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bd\n  0x0600,0x0f00,0x1980,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02c6\n  0x1980,0x0f00,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02c7\n  0x30c0,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02d8\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02d9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0600,0x0c00,0x0c00,0x0780,0x0000, // u02db\n  0x1cc0,0x36c0,0x3380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02dc\n  0x0660,0x0cc0,0x1980,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02dd\n  0x1800,0x0c00,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0300\n  0x0180,0x0300,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0301\n  0x0600,0x0f00,0x1980,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0302\n  0x1cc0,0x36c0,0x3380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0303\n  0x0000,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0304\n  0x0000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0305\n  0x30c0,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0306\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0307\n  0x1980,0x1980,0x1980,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0308\n  0x0f00,0x1980,0x1980,0x0f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030a\n  0x0660,0x0cc0,0x1980,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030b\n  0x1980,0x0f00,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0000, // u0329\n  0x0000,0x3000,0x6000,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0384\n  0x0180,0x0300,0x0600,0x0000,0x1980,0x1980,0x1980,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0385\n  0x0000,0x3000,0x6000,0xc000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0386\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0387\n  0x0000,0x3000,0x6000,0xc000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0388\n  0x0000,0x3000,0x6000,0xc000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0389\n  0x0000,0x3000,0x6000,0xc000,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u038a\n  0x0000,0x3000,0x6000,0xc000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u038c\n  0x0000,0x3000,0x6000,0xc000,0x3030,0x3030,0x1860,0x1860,0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000, // u038e\n  0x0000,0x3000,0x6000,0xc000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x30c0,\n  0x1980,0x1980,0x79e0,0x0000,0x0000,0x0000,0x0000,0x0000, // u038f\n  0x0180,0x0300,0x0600,0x0000,0x1980,0x1980,0x1980,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0390\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0391\n  0x0000,0x0000,0x0000,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x60c0,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x60c0,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0392\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0393\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0f00,0x0f00,0x0f00,0x1980,0x1980,0x1980,0x30c0,0x30c0,0x30c0,\n  0x6060,0x6060,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0394\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0395\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0060,0x0060,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0396\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0397\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6f60,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0398\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0399\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x60c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7000,0x7800,0x6c00,0x6600,0x6300,\n  0x6180,0x60c0,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u039a\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0f00,0x0f00,0x0f00,0x1980,0x1980,0x1980,0x30c0,0x30c0,0x30c0,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u039b\n  0x0000,0x0000,0x0000,0x0000,0x8020,0xc060,0xe0e0,0xf1e0,0xdb60,0xce60,0xc460,0xc060,0xc060,0xc060,0xc060,0xc060,\n  0xc060,0xc060,0xc060,0x0000,0x0000,0x0000,0x0000,0x0000, // u039c\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x7060,0x7860,0x6c60,0x6660,0x6360,0x61e0,0x60e0,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u039d\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u039e\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u039f\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a0\n  0x0000,0x0000,0x0000,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x60c0,0x7f80,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a1\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x0300,0x0600,0x0c00,0x1800,\n  0x3000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a3\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a4\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x30c0,0x30c0,0x1980,0x1980,0x0f00,0x0f00,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a5\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x1f80,0x36c0,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,\n  0x36c0,0x1f80,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a6\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x30c0,0x30c0,0x1980,0x1980,0x0f00,0x0600,0x0f00,0x1980,0x1980,0x30c0,\n  0x30c0,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a7\n  0x0000,0x0000,0x0000,0x0000,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x36c0,0x1f80,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a8\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x30c0,\n  0x1980,0x1980,0x79e0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a9\n  0x1980,0x1980,0x1980,0x0000,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u03aa\n  0x1980,0x1980,0x1980,0x0000,0x6060,0x6060,0x30c0,0x30c0,0x1980,0x1980,0x0f00,0x0f00,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ab\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x0000,0x3e60,0x63c0,0xc180,0xc180,0xc180,0xc180,0xc180,0xc180,\n  0xc180,0x63c0,0x3e60,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ac\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x3fc0,0x6060,0x6000,0x6000,0x6000,0x3f00,0x6000,0x6000,\n  0x6000,0x6060,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ad\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0060,0x0060,0x0060,0x0060,0x0000, // u03ae\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03af\n  0x0180,0x0300,0x0600,0x0000,0x1980,0x1980,0x1980,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e60,0x63c0,0xc180,0xc180,0xc180,0xc180,0xc180,0xc180,\n  0xc180,0x63c0,0x3e60,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b1\n  0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x60c0,0x60c0,0x60c0,0x6180,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x60c0,0x7f80,0x6000,0x6000,0x6000,0x6000,0x0000, // u03b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x30c0,0x30c0,0x30c0,0x1980,0x1980,\n  0x0f00,0x0f00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000, // u03b3\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x0c00,0x0600,0x0300,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x6060,0x6000,0x6000,0x6000,0x3f00,0x6000,0x6000,\n  0x6000,0x6060,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b5\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x3000,0x6000,0x6000,0x6000,\n  0x6000,0x3000,0x1fc0,0x0060,0x0060,0x0060,0x01c0,0x0000, // u03b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0060,0x0060,0x0060,0x0060,0x0000, // u03b7\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x3180,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x30c0,0x3180,0x3300,0x3600,0x3c00,0x3600,0x3300,\n  0x3180,0x30c0,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ba\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x0c00,0x0c00,0x0600,0x0600,0x0f00,0x0f00,0x1980,0x1980,0x30c0,0x30c0,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u03bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x60e0,0x61e0,0x7f60,0x6000,0x6000,0x6000,0x6000,0x0000, // u03bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x30c0,0x30c0,0x1980,0x1980,0x0f00,\n  0x0f00,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u03bd\n  0x0000,0x0000,0x0000,0x0000,0x1fe0,0x3000,0x6000,0x6000,0x6000,0x3000,0x1fc0,0x3000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x3000,0x1fc0,0x0060,0x0060,0x0060,0x01c0,0x0000, // u03be\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u03bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x70c0,0x7f80,0x6000,0x6000,0x6000,0x6000,0x0000, // u03c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x3000,0x1fc0,0x0060,0x0060,0x0060,0x01c0,0x0000, // u03c2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3180,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x33c0,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,\n  0x6660,0x36c0,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0000, // u03c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x30c0,0x30c0,0x1980,0x1980,0x0f00,0x0600,\n  0x0f00,0x1980,0x1980,0x30c0,0x30c0,0x6060,0x6060,0x0000, // u03c7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,\n  0x6660,0x36c0,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0000, // u03c8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x6060,0x6060,0x6060,0x6660,0x6660,0x6660,0x6660,\n  0x6660,0x6f60,0x39c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c9\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ca\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u03cb\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u03cc\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u03cd\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x30c0,0x6060,0x6060,0x6060,0x6660,0x6660,0x6660,0x6660,\n  0x6660,0x6f60,0x39c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ce\n  0x0000,0x0000,0x0000,0x0000,0x0f80,0x18c0,0x3060,0x3060,0x3060,0x1860,0x0ff0,0x0060,0x0060,0xf060,0x3060,0x3060,\n  0x3060,0x18c0,0x0f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u03d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x1f80,0x36c0,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,\n  0x6660,0x36c0,0x1f80,0x0600,0x0600,0x0000,0x0000,0x0000, // u03d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7030,0x1860,0x0cc0,0x0580,0x0700,0x0600,0x0e00,0x1a00,\n  0x3300,0x6180,0xc0e0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x70c0,0x7f80,0x6000,0x6000,0x3000,0x1fc0,0x0000, // u03f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f2\n  0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x03c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x30c0,0x30c0,0x1980,0x0f00,0x0000, // u03f3\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x1800,0x3000,0x6000,0x6000,0x7f80,0x6000,0x6000,\n  0x3000,0x1800,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0180,0x00c0,0x0060,0x0060,0x1fe0,0x0060,0x0060,\n  0x00c0,0x0180,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f6\n  0x1800,0x0c00,0x0600,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0400\n  0x1980,0x1980,0x1980,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0401\n  0x0000,0x0000,0x0000,0x0000,0xfc00,0x3000,0x3000,0x3000,0x3000,0x3f80,0x30c0,0x3060,0x3060,0x3060,0x3060,0x3060,\n  0x3060,0x30c0,0x3380,0x0000,0x0000,0x0000,0x0000,0x0000, // u0402\n  0x0180,0x0300,0x0600,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0403\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6000,0x6000,0x6000,0x6000,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0404\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6000,0x6000,0x6000,0x3000,0x1f80,0x00c0,0x0060,0x0060,0x0060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0405\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0406\n  0x1980,0x1980,0x1980,0x0000,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0407\n  0x0000,0x0000,0x0000,0x0000,0x03f0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x60c0,0x60c0,\n  0x60c0,0x3180,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u0408\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x6600,0xc600,0xc600,0xc600,0xc600,0xc7c0,0xc660,0xc630,0xc630,0xc630,0xc630,\n  0xc630,0xc660,0x87c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0409\n  0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc600,0xc600,0xc7c0,0xfe60,0xc630,0xc630,0xc630,0xc630,\n  0xc630,0xc660,0xc7c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u040a\n  0x0000,0x0000,0x0000,0x0000,0xfc00,0x3000,0x3000,0x3000,0x3000,0x3f80,0x30c0,0x3060,0x3060,0x3060,0x3060,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000, // u040b\n  0x0180,0x0300,0x0600,0x0000,0x6060,0x60c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7000,0x7800,0x6c00,0x6600,0x6300,\n  0x6180,0x60c0,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u040c\n  0x1800,0x0c00,0x0600,0x0000,0x6060,0x6060,0x6060,0x6060,0x60e0,0x61e0,0x6360,0x6660,0x6c60,0x7860,0x7060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u040d\n  0x30c0,0x30c0,0x1f80,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x3060,0x1fe0,0x0060,0x0060,0x0060,\n  0x0060,0x00c0,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u040e\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x7fe0,0x0600,0x0600,0x0600,0x0000,0x0000, // u040f\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0410\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x60c0,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0411\n  0x0000,0x0000,0x0000,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x60c0,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x60c0,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0412\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0413\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x18c0,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,\n  0x30c0,0x70c0,0xffe0,0xc060,0xc060,0xc060,0x0000,0x0000, // u0414\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0415\n  0x0000,0x0000,0x0000,0x0000,0x6660,0x6660,0x6660,0x6660,0x6660,0x36c0,0x1f80,0x0f00,0x1f80,0x36c0,0x6660,0x6660,\n  0x6660,0x6660,0x6660,0x0000,0x0000,0x0000,0x0000,0x0000, // u0416\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x0060,0x0060,0x0060,0x00c0,0x0f80,0x00c0,0x0060,0x0060,0x0060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0417\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x60e0,0x61e0,0x6360,0x6660,0x6c60,0x7860,0x7060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0418\n  0x30c0,0x30c0,0x1f80,0x0000,0x6060,0x6060,0x6060,0x6060,0x60e0,0x61e0,0x6360,0x6660,0x6c60,0x7860,0x7060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0419\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x60c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7000,0x7800,0x6c00,0x6600,0x6300,\n  0x6180,0x60c0,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u041a\n  0x0000,0x0000,0x0000,0x0000,0x0fe0,0x1860,0x3060,0x3060,0x3060,0x3060,0x3060,0x3060,0x3060,0x3060,0x3060,0x3060,\n  0x3060,0x6060,0xc060,0x0000,0x0000,0x0000,0x0000,0x0000, // u041b\n  0x0000,0x0000,0x0000,0x0000,0x8020,0xc060,0xe0e0,0xf1e0,0xdb60,0xce60,0xc460,0xc060,0xc060,0xc060,0xc060,0xc060,\n  0xc060,0xc060,0xc060,0x0000,0x0000,0x0000,0x0000,0x0000, // u041c\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u041d\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u041e\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u041f\n  0x0000,0x0000,0x0000,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x60c0,0x7f80,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0420\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0421\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u0422\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x3060,0x1fe0,0x0060,0x0060,0x0060,\n  0x0060,0x00c0,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0423\n  0x0000,0x0000,0x0000,0x0600,0x1f80,0x36c0,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,\n  0x6660,0x36c0,0x1f80,0x0600,0x0000,0x0000,0x0000,0x0000, // u0424\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x30c0,0x30c0,0x1980,0x1980,0x0f00,0x0600,0x0f00,0x1980,0x1980,0x30c0,\n  0x30c0,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0425\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x3060,0x1ff0,0x0030,0x0030,0x0030,0x0000,0x0000, // u0426\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x3060,0x1fe0,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0427\n  0x0000,0x0000,0x0000,0x0000,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,\n  0x6660,0x3660,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0428\n  0x0000,0x0000,0x0000,0x0000,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,\n  0x6660,0x3660,0x1ff0,0x0030,0x0030,0x0030,0x0000,0x0000, // u0429\n  0x0000,0x0000,0x0000,0x0000,0xe000,0xe000,0x6000,0x6000,0x6000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x60c0,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u042a\n  0x0000,0x0000,0x0000,0x0000,0xc060,0xc060,0xc060,0xc060,0xc060,0xfc60,0xc660,0xc360,0xc360,0xc360,0xc360,0xc360,\n  0xc360,0xc660,0xfc60,0x0000,0x0000,0x0000,0x0000,0x0000, // u042b\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x60c0,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u042c\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x0060,0x0060,0x0060,0x0060,0x0fe0,0x0060,0x0060,0x0060,0x0060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u042d\n  0x0000,0x0000,0x0000,0x0000,0xc7c0,0xcc60,0xcc60,0xcc60,0xcc60,0xcc60,0xcc60,0xfc60,0xcc60,0xcc60,0xcc60,0xcc60,\n  0xcc60,0xcc60,0xc7c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u042e\n  0x0000,0x0000,0x0000,0x0000,0x1fe0,0x3060,0x6060,0x6060,0x6060,0x6060,0x3060,0x1fe0,0x01e0,0x0360,0x0660,0x0c60,\n  0x1860,0x3060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u042f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x00c0,0x0060,0x0060,0x1fe0,0x3060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0430\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3000,0x6000,0x6000,0x6000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x60c0,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0431\n  0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x60c0,0x60c0,0x60c0,0x6180,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x60c0,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0432\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0433\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fe0,0x3060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30e0,0x1fe0,0x0060,0x0060,0x00c0,0x3f80,0x0000, // u0434\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x7fe0,0x6000,0x6000,\n  0x6000,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0435\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6660,0x6660,0x6660,0x36c0,0x1f80,0x0f00,0x1f80,0x36c0,\n  0x6660,0x6660,0x6660,0x0000,0x0000,0x0000,0x0000,0x0000, // u0436\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x6060,0x0060,0x0060,0x0060,0x0fc0,0x0060,0x0060,\n  0x0060,0x6060,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0437\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0438\n  0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x1f80,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0439\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x30c0,0x3180,0x3300,0x3600,0x3c00,0x3600,0x3300,\n  0x3180,0x30c0,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000, // u043a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x1860,0x3060,0x3060,0x3060,0x3060,0x3060,0x3060,\n  0x3060,0x3060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u043b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4020,0x6060,0x70e0,0x79e0,0x6f60,0x6660,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u043c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u043d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u043e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u043f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x60c0,0x7f80,0x6000,0x6000,0x6000,0x6000,0x0000, // u0440\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0441\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u0442\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30e0,0x1fe0,0x0060,0x0060,0x00c0,0x3f80,0x0000, // u0443\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x1f80,0x36c0,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,\n  0x6660,0x36c0,0x1f80,0x0600,0x0600,0x0000,0x0000,0x0000, // u0444\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x30c0,0x1980,0x0f00,0x0600,0x0f00,0x1980,\n  0x30c0,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0445\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x3060,0x1ff0,0x0030,0x0030,0x0030,0x0000,0x0000, // u0446\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x3060,0x1fe0,0x0060,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000, // u0447\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,\n  0x6660,0x3660,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0448\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,\n  0x6660,0x3660,0x1ff0,0x0030,0x0030,0x0030,0x0000,0x0000, // u0449\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x7000,0x3000,0x3f80,0x30c0,0x3060,0x3060,0x3060,\n  0x3060,0x30c0,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u044a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x7c60,0x6660,0x6360,0x6360,0x6360,\n  0x6360,0x6660,0x7c60,0x0000,0x0000,0x0000,0x0000,0x0000, // u044b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x6180,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u044c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x0060,0x0060,0x0fe0,0x0060,0x0060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u044d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc7c0,0xcc60,0xcc60,0xcc60,0xcc60,0xfc60,0xcc60,0xcc60,\n  0xcc60,0xcc60,0xc7c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u044e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fe0,0x6060,0x6060,0x6060,0x6060,0x3fe0,0x0360,0x0660,\n  0x0c60,0x1860,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000, // u044f\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x0c00,0x0600,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x7fe0,0x6000,0x6000,\n  0x6000,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0450\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x7fe0,0x6000,0x6000,\n  0x6000,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0451\n  0x0000,0x0000,0x0000,0x0000,0x6000,0xfe00,0x6000,0x6000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0060,0x0060,0x00c0,0x0380,0x0000, // u0452\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0453\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6000,0x6000,0x7f00,0x6000,0x6000,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0454\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x6060,0x6000,0x6000,0x6000,0x3fc0,0x0060,0x0060,\n  0x0060,0x6060,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0455\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0456\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0457\n  0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x03c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x30c0,0x30c0,0x1980,0x0f00,0x0000, // u0458\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x6600,0xc600,0xc7c0,0xc660,0xc630,0xc630,0xc630,\n  0xc630,0xc660,0x87c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u0459\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xc600,0xc600,0xc600,0xc7c0,0xfe60,0xc630,0xc630,\n  0xc630,0xc660,0xc7c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u045a\n  0x0000,0x0000,0x0000,0x0000,0x6000,0xfe00,0x6000,0x6000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u045b\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x3060,0x30c0,0x3180,0x3300,0x3600,0x3c00,0x3600,0x3300,\n  0x3180,0x30c0,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000, // u045c\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x0c00,0x0600,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u045d\n  0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x1f80,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30e0,0x1fe0,0x0060,0x0060,0x00c0,0x3f80,0x0000, // u045e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x7fe0,0x0600,0x0600,0x0600,0x0000,0x0000, // u045f\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0xfe00,0x6000,0x6000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x60c0,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0462\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0xfe00,0x3000,0x3000,0x3000,0x3f80,0x30c0,0x3060,0x3060,0x3060,\n  0x3060,0x30c0,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u0463\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6060,0x30c0,0x30c0,0x1980,0x1980,0x0f00,0x0f00,0x1f80,0x36c0,0x6660,0x6660,\n  0x6660,0x6660,0x6660,0x0000,0x0000,0x0000,0x0000,0x0000, // u046a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6060,0x30c0,0x1980,0x0f00,0x0f00,0x1f80,0x36c0,\n  0x6660,0x6660,0x6660,0x0000,0x0000,0x0000,0x0000,0x0000, // u046b\n  0x0000,0x0060,0x0060,0x0060,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0490\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0491\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0xfe00,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0492\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0xfe00,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0493\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x60c0,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0060,0x00c0,0x0180,0x0000,0x0000, // u0494\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x7f00,0x6180,0x60c0,\n  0x60c0,0x60c0,0x60c0,0x00c0,0x0180,0x0300,0x0000,0x0000, // u0495\n  0x0000,0x0000,0x0000,0x0000,0x6660,0x6660,0x6660,0x6660,0x6660,0x36c0,0x1f80,0x0f00,0x1f80,0x36c0,0x6660,0x6660,\n  0x6660,0x6660,0x6670,0x0030,0x0030,0x0030,0x0000,0x0000, // u0496\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6660,0x6660,0x6660,0x36c0,0x1f80,0x0f00,0x1f80,0x36c0,\n  0x6660,0x6660,0x6670,0x0030,0x0030,0x0030,0x0000,0x0000, // u0497\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x0060,0x0060,0x0060,0x00c0,0x0f80,0x00c0,0x0060,0x0060,0x0060,\n  0x6060,0x30c0,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0000, // u0498\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x6060,0x0060,0x0060,0x0060,0x0fc0,0x0060,0x0060,\n  0x0060,0x6060,0x3fc0,0x0600,0x0600,0x0600,0x0600,0x0000, // u0499\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x60c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7000,0x7800,0x6c00,0x6600,0x6300,\n  0x6180,0x60c0,0x6070,0x0030,0x0030,0x0030,0x0000,0x0000, // u049a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x6c00,0x6600,\n  0x6300,0x6180,0x60e0,0x0060,0x0060,0x0060,0x0000,0x0000, // u049b\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x60c0,0x6180,0x6b00,0x6e00,0x6c00,0x7800,0x6c00,0x6e00,0x6b00,0x6180,\n  0x60c0,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u049c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x60c0,0x6980,0x6b00,0x6e00,0x7c00,0x6e00,0x6b00,\n  0x6980,0x60c0,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u049d\n  0x0000,0x0000,0x0000,0x0000,0xe060,0xe0c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7000,0x7800,0x6c00,0x6600,0x6300,\n  0x6180,0x60c0,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7060,0x70c0,0x3180,0x3300,0x3600,0x3c00,0x3600,0x3300,\n  0x3180,0x30c0,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a1\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6070,0x0030,0x0030,0x0030,0x0000,0x0000, // u04a2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,\n  0x6060,0x6060,0x6070,0x0030,0x0030,0x0030,0x0000,0x0000, // u04a3\n  0x0000,0x0000,0x0000,0x0000,0x61f0,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,\n  0x6180,0x6180,0x6180,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x61f0,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,\n  0x6180,0x6180,0x6180,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a5\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6060,\n  0x6060,0x30c0,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0000, // u04aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6060,0x30c0,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0000, // u04ab\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x30c0,0x30c0,0x1980,0x1980,0x0f00,0x0f00,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x30c0,0x30c0,0x30c0,0x1980,0x1980,\n  0x0f00,0x0f00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000, // u04af\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x30c0,0x30c0,0x1980,0x1980,0x0f00,0x0f00,0x0600,0x3fc0,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u04b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x30c0,0x30c0,0x30c0,0x1980,0x1980,\n  0x0f00,0x0f00,0x0600,0x3fc0,0x0600,0x0600,0x0600,0x0000, // u04b1\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x30c0,0x30c0,0x1980,0x1980,0x0f00,0x0600,0x0f00,0x1980,0x1980,0x30c0,\n  0x30c0,0x6060,0x6070,0x0030,0x0030,0x0030,0x0000,0x0000, // u04b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x30c0,0x1980,0x0f00,0x0600,0x0f00,0x1980,\n  0x30c0,0x6060,0x6070,0x0030,0x0030,0x0030,0x0000,0x0000, // u04b3\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x3060,0x1fe0,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x0070,0x0030,0x0030,0x0030,0x0000,0x0000, // u04b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x3060,0x1fe0,0x0060,0x0060,\n  0x0060,0x0060,0x0070,0x0030,0x0030,0x0030,0x0000,0x0000, // u04b7\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6660,0x6660,0x3660,0x1fe0,0x0660,0x0660,0x0660,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000, // u04b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6660,0x6660,0x3660,0x1fe0,0x0660,0x0660,\n  0x0660,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000, // u04b9\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x60c0,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u04bb\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04c0\n  0x30c0,0x30c0,0x1f80,0x0000,0x6660,0x6660,0x6660,0x6660,0x6660,0x36c0,0x1f80,0x0f00,0x1f80,0x36c0,0x6660,0x6660,\n  0x6660,0x6660,0x6660,0x0000,0x0000,0x0000,0x0000,0x0000, // u04c1\n  0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x1f80,0x0000,0x6660,0x6660,0x6660,0x36c0,0x1f80,0x0f00,0x1f80,0x36c0,\n  0x6660,0x6660,0x6660,0x0000,0x0000,0x0000,0x0000,0x0000, // u04c2\n  0x0000,0x0000,0x0000,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04cf\n  0x30c0,0x30c0,0x1f80,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d0\n  0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x1f80,0x0000,0x3f80,0x00c0,0x0060,0x0060,0x1fe0,0x3060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d1\n  0x1980,0x1980,0x1980,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d2\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,0x0000,0x3f80,0x00c0,0x0060,0x0060,0x1fe0,0x3060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d3\n  0x0000,0x0000,0x0000,0x0000,0x3ff0,0x6300,0xc300,0xc300,0xc300,0xc300,0xc300,0xfff0,0xc300,0xc300,0xc300,0xc300,\n  0xc300,0xc300,0xc3f0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7be0,0x0e30,0x0630,0x0630,0x7e30,0xc7f0,0xc600,0xc600,\n  0xc600,0xc730,0x7de0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d5\n  0x30c0,0x30c0,0x1f80,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d6\n  0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x1f80,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x7fe0,0x6000,0x6000,\n  0x6000,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d7\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x0060,0x0060,0x0060,0x0060,0x7fe0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x60c0,0x0060,0x0060,0x0060,0x7fe0,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d9\n  0x1980,0x1980,0x1980,0x0000,0x1f80,0x30c0,0x6060,0x0060,0x0060,0x0060,0x0060,0x7fe0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04da\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,0x0000,0x3f80,0x60c0,0x0060,0x0060,0x0060,0x7fe0,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04db\n  0x1980,0x1980,0x1980,0x0000,0x6660,0x6660,0x6660,0x6660,0x6660,0x36c0,0x1f80,0x0f00,0x1f80,0x36c0,0x6660,0x6660,\n  0x6660,0x6660,0x6660,0x0000,0x0000,0x0000,0x0000,0x0000, // u04dc\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,0x0000,0x6660,0x6660,0x6660,0x36c0,0x1f80,0x0f00,0x1f80,0x36c0,\n  0x6660,0x6660,0x6660,0x0000,0x0000,0x0000,0x0000,0x0000, // u04dd\n  0x1980,0x1980,0x1980,0x0000,0x1f80,0x30c0,0x6060,0x0060,0x0060,0x0060,0x00c0,0x0f80,0x00c0,0x0060,0x0060,0x0060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04de\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,0x0000,0x3fc0,0x6060,0x0060,0x0060,0x0060,0x0fc0,0x0060,0x0060,\n  0x0060,0x6060,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04df\n  0x0000,0x3fc0,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x60e0,0x61e0,0x6360,0x6660,0x6c60,0x7860,0x7060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e3\n  0x1980,0x1980,0x1980,0x0000,0x6060,0x6060,0x6060,0x6060,0x60e0,0x61e0,0x6360,0x6660,0x6c60,0x7860,0x7060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e4\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e5\n  0x1980,0x1980,0x1980,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e6\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e7\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e9\n  0x1980,0x1980,0x1980,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ea\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04eb\n  0x1980,0x1980,0x1980,0x0000,0x1f80,0x30c0,0x6060,0x0060,0x0060,0x0060,0x0060,0x0fe0,0x0060,0x0060,0x0060,0x0060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ec\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,0x0000,0x1f80,0x30c0,0x6060,0x0060,0x0060,0x0fe0,0x0060,0x0060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ed\n  0x0000,0x3fc0,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x3060,0x1fe0,0x0060,0x0060,0x0060,\n  0x0060,0x00c0,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ee\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30e0,0x1fe0,0x0060,0x0060,0x00c0,0x3f80,0x0000, // u04ef\n  0x1980,0x1980,0x1980,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x3060,0x1fe0,0x0060,0x0060,0x0060,\n  0x0060,0x00c0,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f0\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30e0,0x1fe0,0x0060,0x0060,0x00c0,0x3f80,0x0000, // u04f1\n  0x0660,0x0cc0,0x1980,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x3060,0x1fe0,0x0060,0x0060,0x0060,\n  0x0060,0x00c0,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f2\n  0x0000,0x0000,0x0000,0x0000,0x0660,0x0cc0,0x1980,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30e0,0x1fe0,0x0060,0x0060,0x00c0,0x3f80,0x0000, // u04f3\n  0x1980,0x1980,0x1980,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x3060,0x1fe0,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f4\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,0x0000,0x6060,0x6060,0x6060,0x6060,0x3060,0x1fe0,0x0060,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f5\n  0x3300,0x3300,0x3300,0x0000,0xc060,0xc060,0xc060,0xc060,0xc060,0xfc60,0xc660,0xc360,0xc360,0xc360,0xc360,0xc360,\n  0xc360,0xc660,0xfc60,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f8\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,0x0000,0x6060,0x6060,0x6060,0x7c60,0x6660,0x6360,0x6360,0x6360,\n  0x6360,0x6660,0x7c60,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f9\n  0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x1860,0x1860,0x0c60,0x0c60,0x1e60,0x36c0,0x6780,0x6300,0x6300,0x6180,\n  0x6180,0x60c0,0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d0\n  0x0000,0x0000,0x0000,0x0000,0xff00,0x0180,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0xfff0,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d1\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x0300,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0380,0x0780,0x0cc0,\n  0x18c0,0x3060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d2\n  0x0000,0x0000,0x0000,0x0000,0xfff0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d3\n  0x0000,0x0000,0x0000,0x0000,0x7f80,0x00c0,0x0060,0x0060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d4\n  0x0000,0x0000,0x0000,0x0000,0x3800,0x0c00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d5\n  0x0000,0x0000,0x0000,0x0000,0x7f80,0x0300,0x0600,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d6\n  0x0000,0x0000,0x0000,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d7\n  0x0000,0x0000,0x0000,0x0000,0x6380,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d8\n  0x0000,0x0000,0x0000,0x0000,0x3800,0x0c00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d9\n  0x0000,0x0000,0x0000,0x0000,0x7f80,0x00c0,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0000, // u05da\n  0x0000,0x0000,0x0000,0x0000,0x7f80,0x00c0,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x00c0,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u05db\n  0x0000,0x6000,0x6000,0x6000,0x7fe0,0x0060,0x0060,0x0060,0x0060,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u05dc\n  0x0000,0x0000,0x0000,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u05dd\n  0x0000,0x0000,0x0000,0x0000,0xcf80,0xf8c0,0x7060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x63e0,0x0000,0x0000,0x0000,0x0000,0x0000, // u05de\n  0x0000,0x0000,0x0000,0x0000,0x7c00,0x0600,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000, // u05df\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x0300,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e0\n  0x0000,0x0000,0x0000,0x0000,0xff80,0xc0c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e1\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x3060,0x3060,0x3060,0x1860,0x18c0,0x18c0,0x0d80,0x0d80,0x0700,\n  0x0e00,0x1c00,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e2\n  0x0000,0x0000,0x0000,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x3060,0x1c60,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0000, // u05e3\n  0x0000,0x0000,0x0000,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x3060,0x1c60,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x00c0,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e4\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x3060,0x3060,0x1860,0x18c0,0x0d80,0x0f00,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000, // u05e5\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x3060,0x3060,0x1860,0x18c0,0x0d80,0x0f00,0x0600,0x0300,0x0300,0x0180,\n  0x0180,0x00c0,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e6\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0060,0x0060,0x0060,0x6060,0x6060,0x6060,0x60c0,0x6180,0x6300,0x6600,0x6600,\n  0x6600,0x6600,0x6600,0x6000,0x6000,0x6000,0x6000,0x0000, // u05e7\n  0x0000,0x0000,0x0000,0x0000,0x7f80,0x00c0,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e8\n  0x0000,0x0000,0x0000,0x0000,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,0x6c60,0x7860,0x6060,0x6060,0x6060,\n  0x6060,0x60c0,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e9\n  0x0000,0x0000,0x0000,0x0000,0xff80,0xc0c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0xc060,0x0000,0x0000,0x0000,0x0000,0x0000, // u05ea\n  0x0000,0x0000,0x0000,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x60c0,0x7f80,0x0000,0x0c00,0x0c00,0x0c00,0x0000, // u1e0c\n  0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x1fe0,0x3060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0300,0x0300,0x0300,0x0000, // u1e0d\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x60c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7000,0x7800,0x6c00,0x6600,0x6300,\n  0x6180,0x60c0,0x6060,0x0000,0x0000,0x3fc0,0x0000,0x0000, // u1e34\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3060,0x30c0,0x3180,0x3300,0x3600,0x3c00,0x3600,0x3300,\n  0x3180,0x30c0,0x3060,0x0000,0x0000,0x1fc0,0x0000,0x0000, // u1e35\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0600,0x0600,0x0600,0x0000, // u1e36\n  0x0000,0x0000,0x0000,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0600,0x0600,0x0600,0x0000, // u1e37\n  0x0600,0x0600,0x0600,0x0000,0x8020,0xc060,0xe0e0,0xf1e0,0xdb60,0xce60,0xc460,0xc060,0xc060,0xc060,0xc060,0xc060,\n  0xc060,0xc060,0xc060,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e40\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0000,0x7f80,0x66c0,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,\n  0x6660,0x6660,0x6660,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e41\n  0x0000,0x0000,0x0000,0x0000,0x8020,0xc060,0xe0e0,0xf1e0,0xdb60,0xce60,0xc460,0xc060,0xc060,0xc060,0xc060,0xc060,\n  0xc060,0xc060,0xc060,0x0000,0x0600,0x0600,0x0600,0x0000, // u1e42\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x66c0,0x6660,0x6660,0x6660,0x6660,0x6660,0x6660,\n  0x6660,0x6660,0x6660,0x0000,0x0600,0x0600,0x0600,0x0000, // u1e43\n  0x0600,0x0600,0x0600,0x0000,0x6060,0x6060,0x6060,0x6060,0x7060,0x7860,0x6c60,0x6660,0x6360,0x61e0,0x60e0,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e44\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e45\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x7060,0x7860,0x6c60,0x6660,0x6360,0x61e0,0x60e0,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0600,0x0600,0x0600,0x0000, // u1e46\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0600,0x0600,0x0600,0x0000, // u1e47\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0600,0x0600,0x0600,0x0000, // u1e6c\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x07c0,0x0000,0x0300,0x0300,0x0300,0x0000, // u1e6d\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0600,0x0600,0x0600,0x0000, // u1eb8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x7fe0,0x6000,0x6000,\n  0x6000,0x3060,0x1fc0,0x0000,0x0600,0x0600,0x0600,0x0000, // u1eb9\n  0x1cc0,0x36c0,0x3380,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u1ebc\n  0x0000,0x0000,0x0000,0x0000,0x1cc0,0x36c0,0x3380,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x7fe0,0x6000,0x6000,\n  0x6000,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u1ebd\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0600,0x0600,0x0600,0x0000, // u1eca\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0600,0x0600,0x0600,0x0000, // u1ecb\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0600,0x0600,0x0600,0x0000, // u1ecc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0600,0x0600,0x0600,0x0000, // u1ecd\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0600,0x0600,0x0600,0x0000, // u1ee4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x3060,0x1fe0,0x0000,0x0300,0x0300,0x0300,0x0000, // u1ee5\n  0x1cc0,0x36c0,0x3380,0x0000,0x6060,0x6060,0x30c0,0x30c0,0x1980,0x1980,0x0f00,0x0f00,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u1ef8\n  0x0000,0x0000,0x0000,0x0000,0x1cc0,0x36c0,0x3380,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30e0,0x1fe0,0x0060,0x0060,0x00c0,0x3f80,0x0000, // u1ef9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2001\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2002\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2003\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2004\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2005\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2006\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2007\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2008\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2009\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2010\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2011\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2012\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2013\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2014\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2015\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,\n  0x1980,0x1980,0x1980,0x0000,0x0000,0x0000,0x0000,0x0000, // u2016\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0000,0x0000,0x7fe0, // u2017\n  0x0000,0x0000,0x0300,0x0600,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2018\n  0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2019\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,\n  0x0600,0x0600,0x0600,0x0c00,0x0000,0x0000,0x0000,0x0000, // u201a\n  0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201b\n  0x0000,0x0000,0x0660,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201c\n  0x0000,0x0000,0x1980,0x1980,0x1980,0x1980,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0cc0,\n  0x0cc0,0x0cc0,0x0cc0,0x1980,0x0000,0x0000,0x0000,0x0000, // u201e\n  0x0000,0x0000,0x1980,0x1980,0x1980,0x1980,0x0cc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201f\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x7fe0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2020\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x7fe0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x7fe0,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2021\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x1f80,0x1f80,0x1f80,0x1f80,0x0f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2022\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x6660,0x6660,0x6660,0x0000,0x0000,0x0000,0x0000,0x0000, // u2026\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7300,0xdb00,0xde00,0x7600,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x6ee0,\n  0x7bb0,0xdbb0,0xcee0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2030\n  0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0400,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2032\n  0x0000,0x0000,0x1980,0x1980,0x1980,0x1980,0x1100,0x1100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2033\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x1800,0x0c00,\n  0x0600,0x0300,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000, // u2039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x0300,0x0600,\n  0x0c00,0x1800,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000, // u203a\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x0000,0x0000,\n  0x1980,0x1980,0x1980,0x0000,0x0000,0x0000,0x0000,0x0000, // u203c\n  0x0000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u203e\n  0x0000,0x0000,0x1f00,0x3180,0x3180,0x3180,0x3180,0x3180,0x3180,0x3180,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2070\n  0x0000,0x0600,0x0600,0x0000,0x0e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0f00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2071\n  0x0000,0x0000,0x0180,0x0380,0x0780,0x0d80,0x1980,0x3180,0x3f80,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2074\n  0x0000,0x0000,0x3f00,0x3000,0x3000,0x3000,0x3f00,0x0180,0x0180,0x0180,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2075\n  0x0000,0x0000,0x1f00,0x3000,0x3000,0x3000,0x3f00,0x3180,0x3180,0x3180,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2076\n  0x0000,0x0000,0x3f80,0x3180,0x0180,0x0300,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2077\n  0x0000,0x0000,0x1f00,0x3180,0x3180,0x3180,0x1f00,0x3180,0x3180,0x3180,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2078\n  0x0000,0x0000,0x1f00,0x3180,0x3180,0x3180,0x1f80,0x0180,0x0180,0x0180,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2079\n  0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x3fc0,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207b\n  0x0000,0x0000,0x0000,0x0000,0x3fc0,0x0000,0x0000,0x0000,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207c\n  0x0000,0x0000,0x0300,0x0600,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0600,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207d\n  0x0000,0x0000,0x1800,0x0c00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0c00,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207e\n  0x0000,0x0000,0x0000,0x1f80,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x3180,0x3180,\n  0x3180,0x3180,0x3180,0x3180,0x1f00,0x0000,0x0000,0x0000, // u2080\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0e00,0x1e00,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000, // u2081\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x3180,0x0180,\n  0x0300,0x0600,0x0c00,0x1800,0x3f80,0x0000,0x0000,0x0000, // u2082\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x0180,0x0180,\n  0x0f00,0x0180,0x0180,0x3180,0x1f00,0x0000,0x0000,0x0000, // u2083\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0380,0x0780,0x0d80,\n  0x1980,0x3180,0x3f80,0x0180,0x0180,0x0000,0x0000,0x0000, // u2084\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x3000,0x3000,0x3000,\n  0x3f00,0x0180,0x0180,0x0180,0x3f00,0x0000,0x0000,0x0000, // u2085\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3000,0x3000,0x3000,\n  0x3f00,0x3180,0x3180,0x3180,0x1f00,0x0000,0x0000,0x0000, // u2086\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x3180,0x0180,0x0300,\n  0x0300,0x0600,0x0600,0x0c00,0x0c00,0x0000,0x0000,0x0000, // u2087\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x3180,0x3180,\n  0x1f00,0x3180,0x3180,0x3180,0x1f00,0x0000,0x0000,0x0000, // u2088\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x3180,0x3180,\n  0x1f80,0x0180,0x0180,0x0180,0x1f00,0x0000,0x0000,0x0000, // u2089\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,\n  0x3fc0,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u208a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u208b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x0000,\n  0x0000,0x0000,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u208c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0600,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0600,0x0300,0x0000,0x0000,0x0000, // u208d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x0c00,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0c00,0x1800,0x0000,0x0000,0x0000, // u208e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x0180,0x0180,\n  0x1f80,0x3180,0x3180,0x3180,0x1f80,0x0000,0x0000,0x0000, // u2090\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x3180,\n  0x3f80,0x3000,0x3000,0x3180,0x1f00,0x0000,0x0000,0x0000, // u2091\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x3180,\n  0x3180,0x3180,0x3180,0x3180,0x1f00,0x0000,0x0000,0x0000, // u2092\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x1b00,\n  0x0e00,0x0e00,0x1b00,0x3180,0x3180,0x0000,0x0000,0x0000, // u2093\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x0180,\n  0x0180,0x3f80,0x3180,0x3180,0x1f00,0x0000,0x0000,0x0000, // u2094\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3f00,0x3180,0x3180,\n  0x3180,0x3180,0x3180,0x3180,0x3180,0x0000,0x0000,0x0000, // u2095\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3180,0x3300,0x3600,\n  0x3c00,0x3c00,0x3600,0x3300,0x3180,0x0000,0x0000,0x0000, // u2096\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0f00,0x0000,0x0000,0x0000, // u2097\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6660,0x6660,\n  0x6660,0x6660,0x6660,0x6660,0x6660,0x0000,0x0000,0x0000, // u2098\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x3180,0x3180,\n  0x3180,0x3180,0x3180,0x3180,0x3f00,0x3000,0x3000,0x3000, // u209a\n  0x0000,0x0000,0x0000,0x0000,0xfc00,0xc600,0xc300,0xc300,0xc300,0xc300,0xc600,0xfd80,0xc180,0xc7e0,0xc180,0xc180,\n  0xc180,0xc180,0xc0e0,0x0000,0x0000,0x0000,0x0000,0x0000, // u20a7\n  0x0000,0x0000,0x0000,0x0000,0xfc60,0xc660,0xc360,0xc360,0xdb60,0xdb60,0xdb60,0xdb60,0xdb60,0xdb60,0xdb60,0xd860,\n  0xd860,0xd8c0,0xdf80,0x0000,0x0000,0x0000,0x0000,0x0000, // u20aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0f80,0x18c0,0x3060,0x6000,0x6000,0xff00,0x6000,0x6000,0xff00,0x6000,0x6000,\n  0x3060,0x18c0,0x0f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u20ac\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0600,0x0600,0x0600,0x07c0,0x0700,0x0e00,0x3fc0,0x0700,0x0e00,0x3e00,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u20ae\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x3080,0x5040,0x5040,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5000,0x5040,\n  0x5040,0x3080,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2102\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u210e\n  0x0000,0x0000,0x0000,0x0000,0x6000,0xfe00,0x6000,0x6000,0x7f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u210f\n  0x0000,0x0000,0x0000,0x0000,0x4040,0x4040,0x4040,0x6040,0x5040,0x6840,0x5440,0x4a40,0x4540,0x42c0,0x4140,0x40c0,\n  0x4040,0x4040,0x4040,0x0000,0x0000,0x0000,0x0000,0x0000, // u2115\n  0x0000,0x0000,0x0000,0x0000,0xc600,0xc660,0xc690,0xe690,0xe660,0xf600,0xf600,0xde00,0xde00,0xcef0,0xce00,0xc600,\n  0xc6f0,0xc600,0xc600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2116\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x3080,0x5040,0x5040,0x5040,0x5040,0x5040,0x5040,0x5040,0x5040,0x5040,0x5040,\n  0x5440,0x3280,0x1f00,0x0080,0x0040,0x0000,0x0000,0x0000, // u211a\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x5080,0x5040,0x5040,0x5040,0x5040,0x5080,0x5f00,0x5400,0x5a00,0x5500,0x5280,\n  0x5140,0x50a0,0x7060,0x0000,0x0000,0x0000,0x0000,0x0000, // u211d\n  0x0000,0x0000,0x0000,0x0000,0xfd10,0x31b0,0x31f0,0x31b0,0x31b0,0x31b0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2122\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0040,0x0040,0x00c0,0x0140,0x0280,0x0500,0x0a00,0x1400,0x2800,0x5000,0x6000,\n  0x4000,0x4000,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2124\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x30c0,\n  0x1980,0x1980,0x79e0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2126\n  0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x18c0,0x18c0,0x0c60,0x0c30,0x1e60,0x36c0,0x6780,0x6300,0x6300,0x6180,\n  0x6180,0x30c0,0x18c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2135\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x1800,0x3000,0x6000,0xffe0,0xffe0,0x6000,0x3000,0x1800,\n  0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2190\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0f00,0x1f80,0x36c0,0x6660,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2191\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0200,0x0300,0x0180,0x00c0,0xffe0,0xffe0,0x00c0,0x0180,0x0300,\n  0x0200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2192\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x6660,0x36c0,\n  0x1f80,0x0f00,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2193\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0900,0x1980,0x30c0,0x6060,0xfff0,0xfff0,0x6060,0x30c0,0x1980,\n  0x0900,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2194\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0f00,0x1f80,0x36c0,0x6660,0x0600,0x0600,0x0600,0x0600,0x0600,0x6660,0x36c0,\n  0x1f80,0x0f00,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2195\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0860,0x1860,0x3060,0x6060,0xffe0,0xffe0,0x6060,0x3060,0x1860,\n  0x0860,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc200,0xc300,0xc180,0xc0c0,0xffe0,0xffe0,0xc0c0,0xc180,0xc300,\n  0xc200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a6\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0f00,0x1f80,0x36c0,0x6660,0x0600,0x0600,0x0600,0x0600,0x6660,0x36c0,0x1f80,\n  0x0f00,0x0600,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a8\n  0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0060,0x0860,0x1860,0x3060,0x6060,0xffe0,0xffe0,0x6000,\n  0x3000,0x1800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000, // u21b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x1c00,0x3440,0x6460,0x6460,0x6060,0x6060,0x6060,0x6060,0x30c0,\n  0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1000,0x3000,0x6000,0xffe0,0xffe0,0x0000,0x0000,0xffe0,0xffe0,0x00c0,\n  0x0180,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0180,0x00c0,0xffe0,0xffe0,0x0000,0x0000,0xffe0,0xffe0,0x6000,\n  0x3000,0x1000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21cc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x1800,0x3fe0,0x7fe0,0xe000,0xe000,0x7fe0,0x3fe0,0x1800,\n  0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d0\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0f00,0x1f80,0x39c0,0x79e0,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,\n  0x1980,0x1980,0x1980,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0200,0x0300,0xff80,0xffc0,0x00e0,0x00e0,0xffc0,0xff80,0x0300,\n  0x0200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d2\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x79e0,0x39c0,\n  0x1f80,0x0f00,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0900,0x1980,0x3fc0,0x7fe0,0xe070,0xe070,0x7fe0,0x3fc0,0x1980,\n  0x0900,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d4\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0f00,0x1f80,0x39c0,0x79e0,0x1980,0x1980,0x1980,0x1980,0x1980,0x79e0,0x39c0,\n  0x1f80,0x0f00,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d5\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x30c0,0x3fc0,0x30c0,0x1980,0x1980,0x1980,0x0f00,0x0f00,0x0f00,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2200\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x7fe0,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2203\n  0x0000,0x0000,0x0060,0x0060,0x7fe0,0x00e0,0x01e0,0x01e0,0x0360,0x0360,0x0660,0x7fe0,0x0660,0x0c60,0x0c60,0x1860,\n  0x1860,0x3060,0x7fe0,0x6000,0x6000,0x0000,0x0000,0x0000, // u2204\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x00c0,0x1f80,0x31c0,0x6360,0x6360,0x6660,0x6c60,0x6c60,0x38c0,0x1f80,\n  0x3000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2205\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0f00,0x0f00,0x0f00,0x1980,0x1980,0x1980,0x30c0,0x30c0,0x30c0,\n  0x6060,0x6060,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2206\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6060,0x6060,0x30c0,0x30c0,0x30c0,0x1980,0x1980,0x1980,0x0f00,0x0f00,0x0f00,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2207\n  0x0000,0x0000,0x0000,0x0000,0x0fe0,0x1800,0x3000,0x6000,0x6000,0x6000,0x6000,0x7fe0,0x6000,0x6000,0x6000,0x6000,\n  0x3000,0x1800,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2208\n  0x0000,0x0000,0x0030,0x0030,0x0fe0,0x1860,0x30c0,0x60c0,0x6180,0x6180,0x6300,0x7fe0,0x6600,0x6c00,0x6c00,0x7800,\n  0x3800,0x3800,0x3fe0,0x6000,0x6000,0x0000,0x0000,0x0000, // u2209\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x1800,0x3000,0x6000,0x6000,0x7fe0,0x6000,0x6000,0x3000,0x1800,\n  0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u220a\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x0180,0x00c0,0x0060,0x0060,0x0060,0x0060,0x7fe0,0x0060,0x0060,0x0060,0x0060,\n  0x00c0,0x0180,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u220b\n  0x0000,0x0000,0x6000,0x6000,0x3f80,0x30c0,0x1860,0x1830,0x0c30,0x0c30,0x0630,0x3ff0,0x0330,0x01b0,0x01b0,0x00f0,\n  0x00e0,0x00e0,0x3fe0,0x0030,0x0030,0x0000,0x0000,0x0000, // u220c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x0180,0x00c0,0x0060,0x0060,0x7fe0,0x0060,0x0060,0x00c0,0x0180,\n  0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u220d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2212\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x7fe0,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2213\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x7fe0,0x0600,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2214\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2215\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x00c0,0x0060,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2216\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x1f00,0x1f00,0x1f00,0x0e00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2219\n  0x0000,0x0000,0x00e0,0x00e0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x60c0,0x60c0,0x60c0,0x30c0,0x18c0,0x0cc0,\n  0x06c0,0x03c0,0x01c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u221a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x6660,0x6660,0x6660,0x6660,0x6660,0x3fc0,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u221e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fe0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u221f\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,\n  0x1980,0x1980,0x1980,0x0000,0x0000,0x0000,0x0000,0x0000, // u2225\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0f00,0x0f00,0x1980,0x1980,0x30c0,0x30c0,\n  0x30c0,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u2227\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x30c0,0x30c0,0x30c0,0x1980,0x1980,0x0f00,\n  0x0f00,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2228\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u2229\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u222a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3c60,0x6660,0x63c0,0x0000,0x3c60,0x6660,0x63c0,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2248\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x7fe0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x7fe0,0x6000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2260\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x0000,0x0000,0x0000,0x0000,\n  0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2261\n  0x0000,0x0000,0x0000,0x0000,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,\n  0x00c0,0x0000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2264\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,\n  0x3000,0x0000,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2265\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0330,0x0660,0x0cc0,0x1980,0x3300,0x6600,0xcc00,0x6600,0x3300,0x1980,0x0cc0,\n  0x0660,0x0330,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u226a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xcc00,0x6600,0x3300,0x1980,0x0cc0,0x0660,0x0330,0x0660,0x0cc0,0x1980,0x3300,\n  0x6600,0xcc00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u226b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fe0,0x3000,0x6000,0xc000,0xc000,0xc000,0xc000,0xc000,0x6000,0x3000,\n  0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2282\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x0180,0x00c0,0x0060,0x0060,0x0060,0x0060,0x0060,0x00c0,0x0180,\n  0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2283\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1fe0,0x3000,0x6000,0xc000,0xc000,0xc000,0xc000,0xc000,0x6000,0x3000,0x1fe0,\n  0x0000,0x0000,0xffe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2286\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0x0180,0x00c0,0x0060,0x0060,0x0060,0x0060,0x0060,0x00c0,0x0180,0xff00,\n  0x0000,0x0000,0xffe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2287\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u22a5\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000, // u22c2\n  0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u22c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x00c0,0x1f80,0x31c0,0x6360,0x6360,0x6660,0x6c60,0x6c60,0x38c0,0x1f80,\n  0x3000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2300\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0f00,0x1980,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2302\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,\n  0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000, // u2308\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000, // u2309\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,\n  0x1800,0x1800,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u230a\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u230b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2310\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fe0,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2319\n  0x0000,0x0000,0x0000,0x0000,0x03c0,0x0660,0x0660,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2320\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x6600,0x6600,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2321\n  0x00c0,0x0180,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x1800,0x3000,0x3000,0x3000,0x3000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000, // u239b\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000, // u239c\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x3000,0x3000,0x3000,0x3000,0x1800,0x1800,\n  0x1800,0x0c00,0x0c00,0x0600,0x0600,0x0300,0x0180,0x00c0, // u239d\n  0x6000,0x3000,0x1800,0x0c00,0x0c00,0x0600,0x0600,0x0300,0x0300,0x0300,0x0180,0x0180,0x0180,0x0180,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0, // u239e\n  0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0, // u239f\n  0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x0180,0x0180,0x0180,0x0180,0x0300,0x0300,\n  0x0300,0x0600,0x0600,0x0c00,0x0c00,0x1800,0x3000,0x6000, // u23a0\n  0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000, // u23a1\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000, // u23a2\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fc0, // u23a3\n  0x7fc0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0, // u23a4\n  0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0, // u23a5\n  0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x7fc0, // u23a6\n  0x01f0,0x0700,0x0600,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u23a7\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1800,0xf000,0xf000,0x1800,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u23a8\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0600,0x0700,0x01f0, // u23a9\n  0xf800,0x0e00,0x0600,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u23ab\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0180,0x00f0,0x00f0,0x0180,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u23ac\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0600,0x0e00,0xf800, // u23ad\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u23ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23af\n  0xfff0,0xfff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0xfff0,0xfff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0, // u23bd\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u23d0\n  0x0000,0x0000,0x0000,0x6600,0x6600,0x6600,0x7e00,0x6600,0x6600,0x6600,0x0000,0x0000,0x07e0,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000, // u2409\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7e00,0x0000,0x0000,0x07e0,0x0600,0x0600,0x0780,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u240a\n  0x0000,0x0000,0x0000,0x6600,0x6600,0x6600,0x6600,0x6600,0x3c00,0x1800,0x0000,0x0000,0x07e0,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000, // u240b\n  0x0000,0x0000,0x0000,0x7e00,0x6000,0x6000,0x7800,0x6000,0x6000,0x6000,0x0000,0x0000,0x07e0,0x0600,0x0600,0x0780,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u240c\n  0x0000,0x0000,0x0000,0x3c00,0x6600,0x6000,0x6000,0x6000,0x6600,0x3c00,0x0000,0x0000,0x07c0,0x0660,0x0660,0x07c0,\n  0x0780,0x06c0,0x0660,0x0000,0x0000,0x0000,0x0000,0x0000, // u240d\n  0x0000,0x0000,0x0000,0x6600,0x6600,0x7600,0x7e00,0x6e00,0x6600,0x6600,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000, // u2424\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2500\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0,0xfff0,0xfff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2501\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2502\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u2503\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xdb60,0xdb60,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2508\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xdb60,0xdb60,0xdb60,0xdb60,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2509\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000, // u250a\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0000,0x0000,0x0f00,0x0f00,0x0f00,0x0f00,0x0000,0x0000,0x0f00,0x0f00,0x0f00,0x0f00,\n  0x0000,0x0000,0x0f00,0x0f00,0x0f00,0x0f00,0x0000,0x0000, // u250b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07f0,0x07f0,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u250c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07f0,0x07f0,0x07f0,0x07f0,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u250d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x0ff0,0x0f00,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u250e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x0ff0,0x0ff0,0x0ff0,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u250f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xfe00,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2510\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xfe00,0xfe00,0xfe00,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2511\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x0f00,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u2512\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0xff00,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u2513\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x07f0,0x07f0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2514\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x07f0,0x07f0,0x07f0,0x07f0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2515\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0ff0,0x0ff0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2516\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0ff0,0x0ff0,0x0ff0,0x0ff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2517\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfe00,0xfe00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2518\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfe00,0xfe00,0xfe00,0xfe00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2519\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0xff00,0xff00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u251a\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0xff00,0xff00,0xff00,0xff00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u251b\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x07f0,0x07f0,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u251c\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x07f0,0x07f0,0x07f0,0x07f0,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u251d\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0ff0,0x0ff0,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u251e\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0ff0,0x0ff0,0x0f00,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u251f\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0ff0,0x0ff0,0x0f00,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u2520\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0ff0,0x0ff0,0x0ff0,0x0ff0,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2521\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0ff0,0x0ff0,0x0ff0,0x0ff0,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u2522\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0ff0,0x0ff0,0x0ff0,0x0ff0,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u2523\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfe00,0xfe00,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2524\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfe00,0xfe00,0xfe00,0xfe00,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2525\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0xff00,0xff00,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2526\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xff00,0xff00,0x0f00,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u2527\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0xff00,0xff00,0x0f00,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u2528\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0xff00,0xff00,0xff00,0xff00,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2529\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xff00,0xff00,0xff00,0xff00,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u252a\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0xff00,0xff00,0xff00,0xff00,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u252b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u252c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xfff0,0xfff0,0xfe00,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u252d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07f0,0xfff0,0xfff0,0x07f0,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u252e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0,0xfff0,0xfff0,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u252f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0,0x0f00,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u2530\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xfff0,0xfff0,0xff00,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u2531\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0xfff0,0xfff0,0x0ff0,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u2532\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0,0xfff0,0xfff0,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u2533\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfff0,0xfff0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2534\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfe00,0xfff0,0xfff0,0xfe00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2535\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x07f0,0xfff0,0xfff0,0x07f0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2536\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfff0,0xfff0,0xfff0,0xfff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2537\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0xfff0,0xfff0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2538\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0xff00,0xfff0,0xfff0,0xff00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2539\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0ff0,0xfff0,0xfff0,0x0ff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u253a\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0xfff0,0xfff0,0xfff0,0xfff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u253b\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfff0,0xfff0,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u253c\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfe00,0xfff0,0xfff0,0xfe00,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u253d\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x07f0,0xfff0,0xfff0,0x07f0,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u253e\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfff0,0xfff0,0xfff0,0xfff0,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u253f\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0xfff0,0xfff0,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2540\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfff0,0xfff0,0x0f00,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u2541\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0xfff0,0xfff0,0x0f00,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u2542\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0xff00,0xfff0,0xfff0,0xfe00,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2543\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0ff0,0xfff0,0xfff0,0x07f0,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2544\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfe00,0xfff0,0xfff0,0xff00,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u2545\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x07f0,0xfff0,0xfff0,0x0ff0,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u2546\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0xfff0,0xfff0,0xfff0,0xfff0,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2547\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfff0,0xfff0,0xfff0,0xfff0,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u2548\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0xff00,0xfff0,0xfff0,0xff00,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u2549\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0ff0,0xfff0,0xfff0,0x0ff0,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u254a\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0xfff0,0xfff0,0xfff0,0xfff0,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u254b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0,0x0000,0x0000,0xfff0,0xfff0,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2550\n  0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,\n  0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980, // u2551\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07f0,0x07f0,0x0600,0x0600,0x07f0,0x07f0,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2552\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x1ff0,0x1980,0x1980,0x1980,\n  0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980, // u2553\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x1ff0,0x1800,0x1800,0x19f0,0x19f0,0x1980,\n  0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980, // u2554\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xfe00,0x0600,0x0600,0xfe00,0xfe00,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2555\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,0xff80,0x1980,0x1980,0x1980,\n  0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980, // u2556\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,0xff80,0x0180,0x0180,0xf980,0xf980,0x1980,\n  0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980, // u2557\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x07f0,0x07f0,0x0600,0x0600,0x07f0,0x07f0,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2558\n  0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1ff0,0x1ff0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2559\n  0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x19f0,0x19f0,0x1800,0x1800,0x1ff0,0x1ff0,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255a\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfe00,0xfe00,0x0600,0x0600,0xfe00,0xfe00,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255b\n  0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0xff80,0xff80,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255c\n  0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0xf980,0xf980,0x0180,0x0180,0xff80,0xff80,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255d\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x07f0,0x07f0,0x0600,0x0600,0x07f0,0x07f0,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u255e\n  0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x19f0,0x19f0,0x1980,0x1980,0x1980,\n  0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980, // u255f\n  0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x19f0,0x19f0,0x1800,0x1800,0x19f0,0x19f0,0x1980,\n  0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980, // u2560\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfe00,0xfe00,0x0600,0x0600,0xfe00,0xfe00,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2561\n  0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0xf980,0xf980,0x1980,0x1980,0x1980,\n  0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980, // u2562\n  0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0xf980,0xf980,0x0180,0x0180,0xf980,0xf980,0x1980,\n  0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980, // u2563\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0,0x0000,0x0000,0xfff0,0xfff0,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2564\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0,0x1980,0x1980,0x1980,\n  0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980, // u2565\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0,0x0000,0x0000,0xf9f0,0xf9f0,0x1980,\n  0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980, // u2566\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfff0,0xfff0,0x0000,0x0000,0xfff0,0xfff0,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2567\n  0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0xfff0,0xfff0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2568\n  0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0xf9f0,0xf9f0,0x0000,0x0000,0xfff0,0xfff0,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2569\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0xfff0,0xfff0,0x0600,0x0600,0xfff0,0xfff0,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u256a\n  0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0xfff0,0xfff0,0x1980,0x1980,0x1980,\n  0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980, // u256b\n  0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0xf9f0,0xf9f0,0x0000,0x0000,0xf9f0,0xf9f0,0x1980,\n  0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980,0x1980, // u256c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x01f0,0x0380,0x0300,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u256d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xe000,0xf800,0x1c00,0x0c00,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u256e\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0c00,0x1c00,0xf800,0xe000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u256f\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0300,0x0380,0x01f0,0x0070,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2570\n  0x0010,0x0010,0x0030,0x0020,0x0060,0x0040,0x00c0,0x0080,0x0180,0x0100,0x0300,0x0200,0x0600,0x0400,0x0c00,0x0800,\n  0x1800,0x1000,0x3000,0x2000,0x6000,0x4000,0xc000,0x8000, // u2571\n  0x8000,0xc000,0x4000,0x6000,0x2000,0x3000,0x1000,0x1800,0x0800,0x0c00,0x0400,0x0600,0x0200,0x0300,0x0100,0x0180,\n  0x0080,0x00c0,0x0040,0x0060,0x0020,0x0030,0x0010,0x0010, // u2572\n  0x8010,0xc010,0x4030,0x6020,0x2060,0x3040,0x10c0,0x1880,0x0980,0x0d00,0x0700,0x0600,0x0600,0x0700,0x0d00,0x0980,\n  0x1880,0x10c0,0x3040,0x2060,0x6020,0x4030,0xc010,0x8010, // u2573\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xfe00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2574\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2575\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07f0,0x07f0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2576\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u2577\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xfe00,0xfe00,0xfe00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2578\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2579\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07f0,0x07f0,0x07f0,0x07f0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u257b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07f0,0xfff0,0xfff0,0x07f0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257c\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00, // u257d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xfff0,0xfff0,0xfe00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257e\n  0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0f00,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u257f\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2580\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0,0xfff0, // u2581\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0, // u2582\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0, // u2583\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0,0xfff0,0xfff0,\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0, // u2584\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0, // u2585\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0, // u2586\n  0x0000,0x0000,0x0000,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0, // u2587\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0, // u2588\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0, // u2589\n  0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,\n  0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80, // u258a\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u258b\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00, // u258c\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800, // u258d\n  0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,\n  0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000, // u258e\n  0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,\n  0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000, // u258f\n  0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,\n  0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0, // u2590\n  0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000,\n  0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000,0xaaa0,0x0000, // u2591\n  0xaaa0,0x5550,0xaaa0,0x5550,0xaaa0,0x5550,0xaaa0,0x5550,0xaaa0,0x5550,0xaaa0,0x5550,0xaaa0,0x5550,0xaaa0,0x5550,\n  0xaaa0,0x5550,0xaaa0,0x5550,0xaaa0,0x5550,0xaaa0,0x5550, // u2592\n  0xfff0,0xaaa0,0xfff0,0xaaa0,0xfff0,0xaaa0,0xfff0,0xaaa0,0xfff0,0xaaa0,0xfff0,0xaaa0,0xfff0,0xaaa0,0xfff0,0xaaa0,\n  0xfff0,0xaaa0,0xfff0,0xaaa0,0xfff0,0xaaa0,0xfff0,0xaaa0, // u2593\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0xfc00,0xfc00,\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00, // u2596\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03f0,0x03f0,0x03f0,0x03f0,\n  0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0, // u2597\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2598\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfff0,0xfff0,0xfff0,0xfff0,\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0, // u2599\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0x03f0,0x03f0,0x03f0,0x03f0,\n  0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0, // u259a\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfc00,0xfc00,0xfc00,0xfc00,\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00, // u259b\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0x03f0,0x03f0,0x03f0,0x03f0,\n  0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0, // u259c\n  0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u259d\n  0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0xfc00,0xfc00,0xfc00,0xfc00,\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00, // u259e\n  0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0x03f0,0xfff0,0xfff0,0xfff0,0xfff0,\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0, // u259f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x3fc0,0x3fc0,0x3fc0,0x3fc0,0x3fc0,0x3fc0,0x3fc0,0x3fc0,\n  0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,0xffe0,\n  0xffe0,0xffe0,0xffe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ac\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x7fe0,0x7fe0,0x7fe0,0x7fe0,0x7fe0,0x7fe0,0x7fe0,0x7fe0,0x7fe0,0x7fe0,0x7fe0,\n  0x7fe0,0x7fe0,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0f00,0x0f00,0x1f80,0x1f80,0x3fc0,0x3fc0,0x7fe0,0x7fe0,\n  0xfff0,0xfff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xffc0,0xfff0,0xfff0,0xffc0,0xff00,0xfc00,\n  0xf000,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xffc0,0xfff0,0xfff0,0xffc0,0xff00,0xfc00,\n  0xf000,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0,0x7fe0,0x7fe0,0x3fc0,0x3fc0,0x1f80,0x1f80,0x0f00,0x0f00,\n  0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0030,0x00f0,0x03f0,0x0ff0,0x3ff0,0xfff0,0xfff0,0x3ff0,0x0ff0,0x03f0,\n  0x00f0,0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0030,0x00f0,0x03f0,0x0ff0,0x3ff0,0xfff0,0xfff0,0x3ff0,0x0ff0,0x03f0,\n  0x00f0,0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0f00,0x1f80,0x3fc0,0x7fe0,0xfff0,0xfff0,0x7fe0,0x3fc0,0x1f80,\n  0x0f00,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0f00,0x1980,0x30c0,0x6060,0xc030,0xc030,0x6060,0x30c0,0x1980,\n  0x0f00,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ca\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x1980,0x1080,0x1080,0x1980,0x0f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x1f80,0x1f80,0x1f80,0x1f80,0x0f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25cf\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xf0f0,0xe070,0xe070,0xe070,0xe070,0xf0f0,0xfff0,\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0, // u25d8\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xf0f0,0xe670,0xef70,0xef70,0xe670,0xf0f0,0xfff0,\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0, // u25d9\n  0x0000,0x0000,0x0000,0x0000,0x3fc0,0x6060,0xc030,0xc030,0xd9b0,0xd9b0,0xc030,0xc030,0xc030,0xdfb0,0xcf30,0xc030,\n  0xc030,0x6060,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u263a\n  0x0000,0x0000,0x0000,0x0000,0x3fc0,0x7fe0,0xfff0,0xfff0,0xe670,0xe670,0xfff0,0xfff0,0xfff0,0xe070,0xf0f0,0xfff0,\n  0xfff0,0x7fe0,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u263b\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0xc630,0x6660,0x36c0,0x1f80,0x0f00,0xf9f0,0x0f00,0x1f80,0x36c0,0x6660,\n  0xc630,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u263c\n  0x0000,0x0000,0x0000,0x0000,0x1f80,0x30c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x30c0,0x1f80,0x0600,0x0600,0x7fe0,\n  0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000, // u2640\n  0x0000,0x0000,0x0000,0x0000,0x0fe0,0x00e0,0x01a0,0x0320,0x0620,0x0c20,0x3f00,0x6180,0xc0c0,0xc0c0,0xc0c0,0xc0c0,\n  0xc0c0,0x6180,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2642\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0f00,0x1f80,0x3fc0,0x7fe0,0x7fe0,0x7fe0,0x7fe0,0x7fe0,0x36c0,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u2660\n  0x0000,0x0000,0x0000,0x0000,0x0f00,0x1f80,0x1f80,0x0f00,0x0600,0x0600,0x76e0,0xfff0,0xfff0,0xfff0,0x76e0,0x0600,\n  0x0600,0x0600,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000, // u2663\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x39c0,0x79e0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0x7fe0,0x3fc0,0x1f80,\n  0x0f00,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2665\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0f00,0x1f80,0x3fc0,0x7fe0,0xfff0,0xfff0,0x7fe0,0x3fc0,0x1f80,\n  0x0f00,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2666\n  0x0000,0x0000,0x0000,0x0000,0x3fe0,0x3060,0x3060,0x3060,0x3fe0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0xf000,0xe000,0x0000,0x0000,0x0000,0x0000,0x0000, // u266a\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6060,0x6060,0x6060,0x7fe0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x60c0,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000, // u266b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x00c0,0x00c0,0x0180,0x0180,0xc300,0xc300,0x6600,0x6600,0x3c00,\n  0x3c00,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000, // u2713\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x0070,0x00e0,0x00e0,0x01c0,0x01c0,0xe380,0xe380,0x7700,0x7700,0x3e00,\n  0x3e00,0x1c00,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000, // u2714\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x6300,0x3300,0x1e00,0x0e00,0x0e00,0x0f00,0x1980,0x18c0,0x3000,\n  0x3000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2717\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x71c0,0x3b80,0x1f80,0x0f00,0x0700,0x0f80,0x0fc0,0x1ce0,0x1c60,0x3800,\n  0x3800,0x7000,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2718\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x1800,0x0c00,0x0c00,0x0600,\n  0x0600,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000, // u27e8\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x0c00,0x0c00,0x0600,0x0600,0x0300,0x0300,0x0300,0x0600,0x0600,0x0c00,\n  0x0c00,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000, // u27e9\n  0x0000,0x0000,0x0000,0x0000,0x0cc0,0x0cc0,0x1980,0x1980,0x3300,0x3300,0x6600,0x6600,0x6600,0x3300,0x3300,0x1980,\n  0x1980,0x0cc0,0x0cc0,0x0000,0x0000,0x0000,0x0000,0x0000, // u27ea\n  0x0000,0x0000,0x0000,0x0000,0x6600,0x6600,0x3300,0x3300,0x1980,0x1980,0x0cc0,0x0cc0,0x0cc0,0x1980,0x1980,0x3300,\n  0x3300,0x6600,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000, // u27eb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2800\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2801\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2802\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2803\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2804\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2805\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2806\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2807\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2808\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2809\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280a\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280b\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280c\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280d\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280e\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2810\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2811\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2812\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2813\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2814\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2815\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2816\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2817\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2818\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2819\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281a\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281b\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281c\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281d\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281e\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2820\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2821\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2822\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2823\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2824\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2825\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2826\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2827\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2828\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2829\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282a\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282b\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282c\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282d\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282e\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2830\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2831\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2832\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2833\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2834\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2835\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2836\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2837\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2838\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2839\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283a\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283b\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283c\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283d\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283e\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2840\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2841\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2842\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2843\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2844\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2845\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2846\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2847\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2848\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2849\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u284a\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u284b\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u284c\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u284d\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u284e\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u284f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2850\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2851\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2852\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2853\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2854\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2855\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2856\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2857\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2858\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2859\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u285a\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u285b\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u285c\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u285d\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u285e\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u285f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2860\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2861\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2862\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2863\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2864\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2865\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2866\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2867\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2868\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2869\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u286a\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u286b\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u286c\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u286d\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u286e\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u286f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2870\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2871\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2872\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2873\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2874\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2875\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2876\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2877\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2878\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2879\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u287a\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u287b\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u287c\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u287d\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u287e\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000, // u287f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u2880\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u2881\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u2882\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u2883\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u2884\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u2885\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u2886\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u2887\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u2888\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u2889\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u288a\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u288b\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u288c\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u288d\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u288e\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u288f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u2890\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u2891\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u2892\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u2893\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u2894\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u2895\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u2896\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u2897\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u2898\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u2899\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u289a\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u289b\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u289c\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u289d\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u289e\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u289f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28a0\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28a2\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28a4\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28a5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28a6\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28a7\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28a8\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28a9\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28aa\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28ab\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28ac\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28ad\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28ae\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28af\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28b0\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28b1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28b2\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28b4\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28b6\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28b7\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28b8\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28b9\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28ba\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28bb\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28bc\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28bd\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28be\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u28bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28c0\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28c2\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28c4\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28c6\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28c7\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28c8\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28c9\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28ca\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28cb\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28cc\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28cd\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28ce\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28cf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28d0\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28d2\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28d4\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28d6\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28d7\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28d8\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28d9\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28da\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28db\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28dc\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28dd\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28de\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28df\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28e0\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28e1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28e2\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28e3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28e4\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28e6\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28e7\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28e8\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28e9\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28ea\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28eb\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28ec\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28ed\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28ee\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28ef\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28f0\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28f2\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28f3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28f4\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28f6\n  0x0000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28f7\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28f8\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28f9\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28fa\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28fb\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28fc\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28fd\n  0x0000,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28fe\n  0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,\n  0x0000,0x0000,0x0000,0x30c0,0x30c0,0x30c0,0x0000,0x0000, // u28ff\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x6060,\n  0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2e2c\n  0xc000,0xc000,0xc300,0xc780,0xcfc0,0xdb60,0xc300,0xc300,0xc300,0xc300,0xc300,0xc600,0x8c00,0x1800,0x3000,0x6000,\n  0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000, // ue0a0\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x0000,0x0000,0x0c60,0x0c60,0x0e60,\n  0x0f60,0x0de0,0x0ce0,0x0c60,0x0c60,0x0000,0x0000,0x0000, // ue0a1\n  0x0000,0x0000,0x0000,0x1f80,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,0x30c0,0x7fe0,0xfff0,0xfff0,0xf9f0,0xf0f0,0xf0f0,\n  0xf0f0,0xf9f0,0xfff0,0xfff0,0xfff0,0x0000,0x0000,0x0000, // ue0a2\n  0x8000,0xc000,0xe000,0xf000,0xf800,0xfc00,0xfe00,0xff00,0xff80,0xffc0,0xffe0,0xfff0,0xfff0,0xffe0,0xffc0,0xff80,\n  0xff00,0xfe00,0xfc00,0xf800,0xf000,0xe000,0xc000,0x8000, // ue0b0\n  0x8000,0xc000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x00c0,0x0060,0x0030,0x0030,0x0060,0x00c0,0x0180,\n  0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0x8000, // ue0b1\n  0x0010,0x0030,0x0070,0x00f0,0x01f0,0x03f0,0x07f0,0x0ff0,0x1ff0,0x3ff0,0x7ff0,0xfff0,0xfff0,0x7ff0,0x3ff0,0x1ff0,\n  0x0ff0,0x07f0,0x03f0,0x01f0,0x00f0,0x0070,0x0030,0x0010, // ue0b2\n  0x0010,0x0030,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0xc000,0x6000,0x3000,0x1800,\n  0x0c00,0x0600,0x0300,0x0180,0x00c0,0x0060,0x0030,0x0010, // ue0b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x30c0,0x30c0,0x1980,0x0f00,0x0000, // uf6be\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000 // ufffd\n  };\n  // codepoints array\n  constexpr std::array<uint16_t, CHARCOUNT> fixedfont_codepoints = {\n  0x0000,0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,\n  0x002f,0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,\n  0x003f,0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,\n  0x004f,0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,\n  0x005f,0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,\n  0x006f,0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,\n  0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af,\n  0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf,\n  0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf,\n  0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df,\n  0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef,\n  0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff,\n  0x0100,0x0101,0x0102,0x0103,0x0104,0x0105,0x0106,0x0107,0x0108,0x0109,0x010a,0x010b,0x010c,0x010d,0x010e,0x010f,\n  0x0110,0x0111,0x0112,0x0113,0x0114,0x0115,0x0116,0x0117,0x0118,0x0119,0x011a,0x011b,0x011c,0x011d,0x011e,0x011f,\n  0x0120,0x0121,0x0122,0x0123,0x0124,0x0125,0x0126,0x0127,0x0128,0x0129,0x012a,0x012b,0x012c,0x012d,0x012e,0x012f,\n  0x0130,0x0131,0x0132,0x0133,0x0134,0x0135,0x0136,0x0137,0x0138,0x0139,0x013a,0x013b,0x013c,0x013d,0x013e,0x013f,\n  0x0140,0x0141,0x0142,0x0143,0x0144,0x0145,0x0146,0x0147,0x0148,0x0149,0x014a,0x014b,0x014c,0x014d,0x014e,0x014f,\n  0x0150,0x0151,0x0152,0x0153,0x0154,0x0155,0x0156,0x0157,0x0158,0x0159,0x015a,0x015b,0x015c,0x015d,0x015e,0x015f,\n  0x0160,0x0161,0x0162,0x0163,0x0164,0x0165,0x0166,0x0167,0x0168,0x0169,0x016a,0x016b,0x016c,0x016d,0x016e,0x016f,\n  0x0170,0x0171,0x0172,0x0173,0x0174,0x0175,0x0176,0x0177,0x0178,0x0179,0x017a,0x017b,0x017c,0x017d,0x017e,0x017f,\n  0x0186,0x018e,0x018f,0x0190,0x0192,0x019d,0x019e,0x01b5,0x01b6,0x01b7,0x01cd,0x01ce,0x01cf,0x01d0,0x01d1,0x01d2,\n  0x01d3,0x01d4,0x01e2,0x01e3,0x01e4,0x01e5,0x01e6,0x01e7,0x01e8,0x01e9,0x01ea,0x01eb,0x01ec,0x01ed,0x01ee,0x01ef,\n  0x01f0,0x01f4,0x01f5,0x01fc,0x01fd,0x01fe,0x01ff,0x0218,0x0219,0x021a,0x021b,0x0232,0x0233,0x0237,0x0254,0x0258,\n  0x0259,0x025b,0x0272,0x0292,0x02bb,0x02bc,0x02bd,0x02c6,0x02c7,0x02d8,0x02d9,0x02db,0x02dc,0x02dd,0x0300,0x0301,\n  0x0302,0x0303,0x0304,0x0305,0x0306,0x0307,0x0308,0x030a,0x030b,0x030c,0x0329,0x0384,0x0385,0x0386,0x0387,0x0388,\n  0x0389,0x038a,0x038c,0x038e,0x038f,0x0390,0x0391,0x0392,0x0393,0x0394,0x0395,0x0396,0x0397,0x0398,0x0399,0x039a,\n  0x039b,0x039c,0x039d,0x039e,0x039f,0x03a0,0x03a1,0x03a3,0x03a4,0x03a5,0x03a6,0x03a7,0x03a8,0x03a9,0x03aa,0x03ab,\n  0x03ac,0x03ad,0x03ae,0x03af,0x03b0,0x03b1,0x03b2,0x03b3,0x03b4,0x03b5,0x03b6,0x03b7,0x03b8,0x03b9,0x03ba,0x03bb,\n  0x03bc,0x03bd,0x03be,0x03bf,0x03c0,0x03c1,0x03c2,0x03c3,0x03c4,0x03c5,0x03c6,0x03c7,0x03c8,0x03c9,0x03ca,0x03cb,\n  0x03cc,0x03cd,0x03ce,0x03d1,0x03d5,0x03f0,0x03f1,0x03f2,0x03f3,0x03f4,0x03f5,0x03f6,0x0400,0x0401,0x0402,0x0403,\n  0x0404,0x0405,0x0406,0x0407,0x0408,0x0409,0x040a,0x040b,0x040c,0x040d,0x040e,0x040f,0x0410,0x0411,0x0412,0x0413,\n  0x0414,0x0415,0x0416,0x0417,0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e,0x041f,0x0420,0x0421,0x0422,0x0423,\n  0x0424,0x0425,0x0426,0x0427,0x0428,0x0429,0x042a,0x042b,0x042c,0x042d,0x042e,0x042f,0x0430,0x0431,0x0432,0x0433,\n  0x0434,0x0435,0x0436,0x0437,0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e,0x043f,0x0440,0x0441,0x0442,0x0443,\n  0x0444,0x0445,0x0446,0x0447,0x0448,0x0449,0x044a,0x044b,0x044c,0x044d,0x044e,0x044f,0x0450,0x0451,0x0452,0x0453,\n  0x0454,0x0455,0x0456,0x0457,0x0458,0x0459,0x045a,0x045b,0x045c,0x045d,0x045e,0x045f,0x0462,0x0463,0x046a,0x046b,\n  0x0490,0x0491,0x0492,0x0493,0x0494,0x0495,0x0496,0x0497,0x0498,0x0499,0x049a,0x049b,0x049c,0x049d,0x04a0,0x04a1,\n  0x04a2,0x04a3,0x04a4,0x04a5,0x04aa,0x04ab,0x04ae,0x04af,0x04b0,0x04b1,0x04b2,0x04b3,0x04b6,0x04b7,0x04b8,0x04b9,\n  0x04ba,0x04bb,0x04c0,0x04c1,0x04c2,0x04cf,0x04d0,0x04d1,0x04d2,0x04d3,0x04d4,0x04d5,0x04d6,0x04d7,0x04d8,0x04d9,\n  0x04da,0x04db,0x04dc,0x04dd,0x04de,0x04df,0x04e2,0x04e3,0x04e4,0x04e5,0x04e6,0x04e7,0x04e8,0x04e9,0x04ea,0x04eb,\n  0x04ec,0x04ed,0x04ee,0x04ef,0x04f0,0x04f1,0x04f2,0x04f3,0x04f4,0x04f5,0x04f8,0x04f9,0x05d0,0x05d1,0x05d2,0x05d3,\n  0x05d4,0x05d5,0x05d6,0x05d7,0x05d8,0x05d9,0x05da,0x05db,0x05dc,0x05dd,0x05de,0x05df,0x05e0,0x05e1,0x05e2,0x05e3,\n  0x05e4,0x05e5,0x05e6,0x05e7,0x05e8,0x05e9,0x05ea,0x1e0c,0x1e0d,0x1e34,0x1e35,0x1e36,0x1e37,0x1e40,0x1e41,0x1e42,\n  0x1e43,0x1e44,0x1e45,0x1e46,0x1e47,0x1e6c,0x1e6d,0x1eb8,0x1eb9,0x1ebc,0x1ebd,0x1eca,0x1ecb,0x1ecc,0x1ecd,0x1ee4,\n  0x1ee5,0x1ef8,0x1ef9,0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007,0x2008,0x2009,0x200a,0x200b,0x200c,\n  0x200d,0x200e,0x200f,0x2010,0x2011,0x2012,0x2013,0x2014,0x2015,0x2016,0x2017,0x2018,0x2019,0x201a,0x201b,0x201c,\n  0x201d,0x201e,0x201f,0x2020,0x2021,0x2022,0x2026,0x2030,0x2032,0x2033,0x2039,0x203a,0x203c,0x203e,0x2070,0x2071,\n  0x2074,0x2075,0x2076,0x2077,0x2078,0x2079,0x207a,0x207b,0x207c,0x207d,0x207e,0x207f,0x2080,0x2081,0x2082,0x2083,\n  0x2084,0x2085,0x2086,0x2087,0x2088,0x2089,0x208a,0x208b,0x208c,0x208d,0x208e,0x2090,0x2091,0x2092,0x2093,0x2094,\n  0x2095,0x2096,0x2097,0x2098,0x209a,0x20a7,0x20aa,0x20ac,0x20ae,0x2102,0x210e,0x210f,0x2115,0x2116,0x211a,0x211d,\n  0x2122,0x2124,0x2126,0x2135,0x2190,0x2191,0x2192,0x2193,0x2194,0x2195,0x21a4,0x21a6,0x21a8,0x21b5,0x21bb,0x21cb,\n  0x21cc,0x21d0,0x21d1,0x21d2,0x21d3,0x21d4,0x21d5,0x2200,0x2203,0x2204,0x2205,0x2206,0x2207,0x2208,0x2209,0x220a,\n  0x220b,0x220c,0x220d,0x2212,0x2213,0x2214,0x2215,0x2216,0x2219,0x221a,0x221e,0x221f,0x2225,0x2227,0x2228,0x2229,\n  0x222a,0x2248,0x2260,0x2261,0x2264,0x2265,0x226a,0x226b,0x2282,0x2283,0x2286,0x2287,0x22a5,0x22c2,0x22c3,0x2300,\n  0x2302,0x2308,0x2309,0x230a,0x230b,0x2310,0x2319,0x2320,0x2321,0x239b,0x239c,0x239d,0x239e,0x239f,0x23a0,0x23a1,\n  0x23a2,0x23a3,0x23a4,0x23a5,0x23a6,0x23a7,0x23a8,0x23a9,0x23ab,0x23ac,0x23ad,0x23ae,0x23af,0x23ba,0x23bb,0x23bc,\n  0x23bd,0x23d0,0x2409,0x240a,0x240b,0x240c,0x240d,0x2424,0x2500,0x2501,0x2502,0x2503,0x2508,0x2509,0x250a,0x250b,\n  0x250c,0x250d,0x250e,0x250f,0x2510,0x2511,0x2512,0x2513,0x2514,0x2515,0x2516,0x2517,0x2518,0x2519,0x251a,0x251b,\n  0x251c,0x251d,0x251e,0x251f,0x2520,0x2521,0x2522,0x2523,0x2524,0x2525,0x2526,0x2527,0x2528,0x2529,0x252a,0x252b,\n  0x252c,0x252d,0x252e,0x252f,0x2530,0x2531,0x2532,0x2533,0x2534,0x2535,0x2536,0x2537,0x2538,0x2539,0x253a,0x253b,\n  0x253c,0x253d,0x253e,0x253f,0x2540,0x2541,0x2542,0x2543,0x2544,0x2545,0x2546,0x2547,0x2548,0x2549,0x254a,0x254b,\n  0x2550,0x2551,0x2552,0x2553,0x2554,0x2555,0x2556,0x2557,0x2558,0x2559,0x255a,0x255b,0x255c,0x255d,0x255e,0x255f,\n  0x2560,0x2561,0x2562,0x2563,0x2564,0x2565,0x2566,0x2567,0x2568,0x2569,0x256a,0x256b,0x256c,0x256d,0x256e,0x256f,\n  0x2570,0x2571,0x2572,0x2573,0x2574,0x2575,0x2576,0x2577,0x2578,0x2579,0x257a,0x257b,0x257c,0x257d,0x257e,0x257f,\n  0x2580,0x2581,0x2582,0x2583,0x2584,0x2585,0x2586,0x2587,0x2588,0x2589,0x258a,0x258b,0x258c,0x258d,0x258e,0x258f,\n  0x2590,0x2591,0x2592,0x2593,0x2596,0x2597,0x2598,0x2599,0x259a,0x259b,0x259c,0x259d,0x259e,0x259f,0x25a0,0x25ac,\n  0x25ae,0x25b2,0x25b6,0x25ba,0x25bc,0x25c0,0x25c4,0x25c6,0x25ca,0x25cb,0x25cf,0x25d8,0x25d9,0x263a,0x263b,0x263c,\n  0x2640,0x2642,0x2660,0x2663,0x2665,0x2666,0x266a,0x266b,0x2713,0x2714,0x2717,0x2718,0x27e8,0x27e9,0x27ea,0x27eb,\n  0x2800,0x2801,0x2802,0x2803,0x2804,0x2805,0x2806,0x2807,0x2808,0x2809,0x280a,0x280b,0x280c,0x280d,0x280e,0x280f,\n  0x2810,0x2811,0x2812,0x2813,0x2814,0x2815,0x2816,0x2817,0x2818,0x2819,0x281a,0x281b,0x281c,0x281d,0x281e,0x281f,\n  0x2820,0x2821,0x2822,0x2823,0x2824,0x2825,0x2826,0x2827,0x2828,0x2829,0x282a,0x282b,0x282c,0x282d,0x282e,0x282f,\n  0x2830,0x2831,0x2832,0x2833,0x2834,0x2835,0x2836,0x2837,0x2838,0x2839,0x283a,0x283b,0x283c,0x283d,0x283e,0x283f,\n  0x2840,0x2841,0x2842,0x2843,0x2844,0x2845,0x2846,0x2847,0x2848,0x2849,0x284a,0x284b,0x284c,0x284d,0x284e,0x284f,\n  0x2850,0x2851,0x2852,0x2853,0x2854,0x2855,0x2856,0x2857,0x2858,0x2859,0x285a,0x285b,0x285c,0x285d,0x285e,0x285f,\n  0x2860,0x2861,0x2862,0x2863,0x2864,0x2865,0x2866,0x2867,0x2868,0x2869,0x286a,0x286b,0x286c,0x286d,0x286e,0x286f,\n  0x2870,0x2871,0x2872,0x2873,0x2874,0x2875,0x2876,0x2877,0x2878,0x2879,0x287a,0x287b,0x287c,0x287d,0x287e,0x287f,\n  0x2880,0x2881,0x2882,0x2883,0x2884,0x2885,0x2886,0x2887,0x2888,0x2889,0x288a,0x288b,0x288c,0x288d,0x288e,0x288f,\n  0x2890,0x2891,0x2892,0x2893,0x2894,0x2895,0x2896,0x2897,0x2898,0x2899,0x289a,0x289b,0x289c,0x289d,0x289e,0x289f,\n  0x28a0,0x28a1,0x28a2,0x28a3,0x28a4,0x28a5,0x28a6,0x28a7,0x28a8,0x28a9,0x28aa,0x28ab,0x28ac,0x28ad,0x28ae,0x28af,\n  0x28b0,0x28b1,0x28b2,0x28b3,0x28b4,0x28b5,0x28b6,0x28b7,0x28b8,0x28b9,0x28ba,0x28bb,0x28bc,0x28bd,0x28be,0x28bf,\n  0x28c0,0x28c1,0x28c2,0x28c3,0x28c4,0x28c5,0x28c6,0x28c7,0x28c8,0x28c9,0x28ca,0x28cb,0x28cc,0x28cd,0x28ce,0x28cf,\n  0x28d0,0x28d1,0x28d2,0x28d3,0x28d4,0x28d5,0x28d6,0x28d7,0x28d8,0x28d9,0x28da,0x28db,0x28dc,0x28dd,0x28de,0x28df,\n  0x28e0,0x28e1,0x28e2,0x28e3,0x28e4,0x28e5,0x28e6,0x28e7,0x28e8,0x28e9,0x28ea,0x28eb,0x28ec,0x28ed,0x28ee,0x28ef,\n  0x28f0,0x28f1,0x28f2,0x28f3,0x28f4,0x28f5,0x28f6,0x28f7,0x28f8,0x28f9,0x28fa,0x28fb,0x28fc,0x28fd,0x28fe,0x28ff,\n  0x2e2c,0xe0a0,0xe0a1,0xe0a2,0xe0b0,0xe0b1,0xe0b2,0xe0b3,0xf6be,0xfffd };\n} // namespace\n// -- end of autogenerated text ---\n\nnamespace fixed_font_28n {\n  // -- start of autogenerated text ---\n  // definition section for font: ter-u28n.bdf\n  constexpr int CHARCOUNT = 1354;\n  constexpr int WIDTH = 14;\n  constexpr int HEIGHT = 28;\n  constexpr int OFFSET_X = 0;\n  constexpr int OFFSET_Y = 0;\n  constexpr FixedFont_info_t fixedfont_info = {\n    \"Terminus\", // font name\n    \"ter-u28n.bdf\", // font name internal\n    CHARCOUNT, // num of chars\n    WIDTH, HEIGHT, OFFSET_X, OFFSET_Y,\n    false // bold\n  };\n  // font bitmap definitions\n  constexpr std::array<uint16_t, CHARCOUNT * HEIGHT> fixedfont_bitmap = {\n  0x0000,0x0000,0x0000,0x0000,0x78f0,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x0000,\n  0x0000,0x0000,0x6030,0x6030,0x6030,0x78f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0020\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0021\n  0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0022\n  0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x7ff0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,\n  0x7ff0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0023\n  0x0000,0x0000,0x0300,0x0300,0x0300,0x1fe0,0x3330,0x6318,0x6300,0x6300,0x6300,0x6300,0x3300,0x1fe0,0x0330,0x0318,\n  0x0318,0x0318,0x0318,0x6318,0x3330,0x1fe0,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000, // u0024\n  0x0000,0x0000,0x0000,0x0000,0x3c30,0x6630,0x6660,0x6660,0x3cc0,0x00c0,0x0180,0x0180,0x0300,0x0300,0x0600,0x0600,\n  0x0c00,0x0cf0,0x1998,0x1998,0x3198,0x30f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0025\n  0x0000,0x0000,0x0000,0x0000,0x0f00,0x1980,0x30c0,0x30c0,0x30c0,0x30c0,0x1980,0x0f00,0x0e00,0x1b18,0x3198,0x60f0,\n  0x6060,0x6060,0x6060,0x60f0,0x3198,0x1f18,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0026\n  0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0027\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0600,0x0600,0x0300,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0028\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0600,0x0300,0x0300,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0300,0x0300,0x0600,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0029\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3030,0x1860,0x0cc0,0x0780,0x0300,0x7ff8,0x0300,0x0780,\n  0x0cc0,0x1860,0x3030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x7ff8,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0600,0x0c00,0x0000,0x0000,0x0000,0x0000, // u002c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002e\n  0x0000,0x0000,0x0000,0x0000,0x0030,0x0030,0x0060,0x0060,0x00c0,0x00c0,0x0180,0x0180,0x0300,0x0300,0x0600,0x0600,\n  0x0c00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002f\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6070,0x60f0,0x61b0,0x6330,0x6630,0x6c30,0x7830,\n  0x7030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0030\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0700,0x0f00,0x1b00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0031\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x0030,0x0060,0x00c0,0x0180,0x0300,0x0600,\n  0x0c00,0x1800,0x3000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0032\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x0030,0x0030,0x0030,0x0030,0x0060,0x0fc0,0x0060,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0033\n  0x0000,0x0000,0x0000,0x0000,0x0030,0x0070,0x00f0,0x01b0,0x0330,0x0630,0x0c30,0x1830,0x3030,0x6030,0x6030,0x6030,\n  0x6030,0x7ff0,0x0030,0x0030,0x0030,0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0034\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x0060,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0035\n  0x0000,0x0000,0x0000,0x0000,0x1fe0,0x3000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x6060,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0036\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x6030,0x6030,0x6030,0x6030,0x0060,0x0060,0x00c0,0x00c0,0x0180,0x0180,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0037\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x3060,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0038\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0060,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0600,0x0c00,0x0000,0x0000,0x0000,0x0000, // u003b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0030,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x1800,0x0c00,\n  0x0600,0x0300,0x0180,0x00c0,0x0060,0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x00c0,0x0060,0x0030,0x0060,0x00c0,\n  0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003e\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x0060,0x00c0,0x0180,0x0300,0x0300,0x0300,\n  0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003f\n  0x0000,0x0000,0x0000,0x0000,0x1fe0,0x3030,0x6018,0x6018,0x61f8,0x6318,0x6618,0x6618,0x6618,0x6618,0x6618,0x6618,\n  0x6318,0x61e8,0x6000,0x6000,0x3000,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0040\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0041\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x6060,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0042\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0043\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x61c0,0x6060,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6060,0x6060,0x61c0,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0044\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0045\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0046\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6000,0x6000,0x6000,0x6000,0x63f0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0047\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0048\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0049\n  0x0000,0x0000,0x0000,0x0000,0x01f8,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x6060,0x6060,0x6060,0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u004a\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6060,0x60c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7000,0x7000,0x7800,0x6c00,\n  0x6600,0x6300,0x6180,0x60c0,0x6060,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u004b\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u004c\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x7038,0x7878,0x6cd8,0x6cd8,0x6798,0x6318,0x6318,0x6018,0x6018,0x6018,\n  0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u004d\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x7030,0x7830,0x6c30,0x6630,0x6330,0x61b0,0x60f0,\n  0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u004e\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u004f\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0050\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6330,0x31e0,0x1fc0,0x0060,0x0030,0x0000,0x0000,0x0000,0x0000, // u0051\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x7800,0x6c00,\n  0x6600,0x6300,0x6180,0x60c0,0x6060,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0052\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6000,0x6000,0x6000,0x3000,0x1fc0,0x0060,0x0030,0x0030,\n  0x0030,0x0030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0053\n  0x0000,0x0000,0x0000,0x0000,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0054\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0055\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x3060,0x3060,0x3060,0x3060,0x18c0,0x18c0,0x18c0,0x18c0,\n  0x0d80,0x0d80,0x0d80,0x0700,0x0700,0x0700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0056\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6318,0x6318,0x6798,\n  0x6cd8,0x6cd8,0x7878,0x7038,0x6018,0x6018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0057\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x3060,0x3060,0x18c0,0x18c0,0x0d80,0x0d80,0x0700,0x0700,0x0d80,0x0d80,\n  0x18c0,0x18c0,0x3060,0x3060,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0058\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0059\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x0030,0x0030,0x0030,0x0030,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,\n  0x3000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005a\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005b\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x1800,0x1800,0x0c00,0x0c00,0x0600,0x0600,0x0300,0x0300,0x0180,0x0180,\n  0x00c0,0x00c0,0x0060,0x0060,0x0030,0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005c\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005d\n  0x0000,0x0000,0x0200,0x0700,0x0d80,0x18c0,0x3060,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x0000,0x0000,0x0000, // u005f\n  0x0c00,0x0600,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0060\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x0060,0x0030,0x0030,0x1ff0,0x3030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0061\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0062\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0063\n  0x0000,0x0000,0x0000,0x0000,0x0030,0x0030,0x0030,0x0030,0x0030,0x1ff0,0x3030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0064\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x7ff0,\n  0x6000,0x6000,0x6000,0x6000,0x3030,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0065\n  0x0000,0x0000,0x0000,0x0000,0x03f0,0x0600,0x0600,0x0600,0x0600,0x3fc0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0066\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,0x0030,0x0030,0x0060,0x3fc0,0x0000, // u0067\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0068\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0069\n  0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0000,0x0000,0x01e0,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x3060,0x3060,0x3060,0x18c0,0x0f80,0x0000, // u006a\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3030,0x3060,0x30c0,0x3180,0x3300,0x3600,0x3c00,\n  0x3600,0x3300,0x3180,0x30c0,0x3060,0x3030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u006b\n  0x0000,0x0000,0x0000,0x0000,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u006c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6330,0x6318,0x6318,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u006d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u006e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u006f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000, // u0070\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,0x0030,0x0030,0x0030,0x0030,0x0000, // u0071\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x67f0,0x6c00,0x7800,0x7000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0072\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6000,0x6000,0x3000,0x1fc0,\n  0x0060,0x0030,0x0030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0073\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,0x3fc0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x03e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0074\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0075\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x3060,0x3060,0x3060,0x18c0,\n  0x18c0,0x18c0,0x0d80,0x0d80,0x0700,0x0700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0076\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x6018,0x6018,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x3330,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0077\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x3060,0x18c0,0x0d80,0x0700,0x0700,\n  0x0700,0x0d80,0x18c0,0x3060,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0078\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,0x0030,0x0030,0x0060,0x3fc0,0x0000, // u0079\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x0030,0x0060,0x00c0,0x0180,0x0300,0x0600,\n  0x0c00,0x1800,0x3000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007a\n  0x0000,0x0000,0x0000,0x0000,0x01c0,0x0300,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x1c00,0x1c00,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0300,0x01c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007b\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007c\n  0x0000,0x0000,0x0000,0x0000,0x1c00,0x0600,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x01c0,0x01c0,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0600,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007d\n  0x0000,0x0000,0x3c30,0x6630,0x6330,0x6330,0x61e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a0\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0fc0,0x1b60,0x3330,0x3300,0x3300,0x3300,0x3300,\n  0x3300,0x3300,0x3300,0x3330,0x1b60,0x0fc0,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000, // u00a2\n  0x0000,0x0000,0x0000,0x0000,0x0780,0x0cc0,0x1860,0x1800,0x1800,0x1800,0x1800,0x1800,0x3f80,0x1800,0x1800,0x1800,\n  0x1800,0x1800,0x1800,0x1830,0x3830,0x3ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6018,0x3030,0x1fe0,0x3030,0x3030,0x3030,0x3030,0x3030,0x3030,\n  0x3030,0x1fe0,0x3030,0x6018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a4\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,0x0cc0,0x0cc0,0x0780,0x0300,0x0300,0x3ff0,\n  0x0300,0x0300,0x3ff0,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a5\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a6\n  0x0000,0x0000,0x0000,0x0780,0x0cc0,0x1860,0x1800,0x1c00,0x0f00,0x0d80,0x18c0,0x1860,0x1860,0x1860,0x1860,0x0c60,\n  0x06c0,0x03c0,0x00e0,0x0060,0x1860,0x0cc0,0x0780,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a7\n  0x18c0,0x18c0,0x18c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fe0,0x6030,0xcf98,0xd8d8,0xd8d8,0xd818,0xd818,0xd818,0xd818,\n  0xd8d8,0xd8d8,0xcf98,0x6030,0x3fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a9\n  0x0000,0x1fc0,0x0060,0x0030,0x0ff0,0x1830,0x3030,0x3030,0x3030,0x1830,0x0ff0,0x0000,0x0000,0x3ff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0198,0x0330,0x0660,0x0cc0,0x1980,0x3300,0x6600,\n  0x3300,0x1980,0x0cc0,0x0660,0x0330,0x0198,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ab\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x0030,0x0030,0x0030,0x0030,0x0030,\n  0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ac\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ad\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fe0,0x6030,0xdf98,0xd8d8,0xd8d8,0xd8d8,0xd8d8,0xdf98,0xde18,\n  0xdb18,0xd998,0xd8d8,0x6030,0x3fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ae\n  0x0000,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00af\n  0x0000,0x0000,0x0f80,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x0f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x7ff8,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0000,0x0000,0x0000,0x7ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b1\n  0x0000,0x0000,0x0f80,0x18c0,0x18c0,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x1fc0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b2\n  0x0000,0x0000,0x0f80,0x18c0,0x00c0,0x00c0,0x0780,0x00c0,0x00c0,0x00c0,0x18c0,0x0f80,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b3\n  0x0180,0x0300,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6070,0x60f0,0x61b0,0x7f30,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000, // u00b5\n  0x0000,0x0000,0x0000,0x0000,0x3ff8,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x3f18,0x0318,0x0318,\n  0x0318,0x0318,0x0318,0x0318,0x0318,0x0318,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0c00,0x1800,0x0000, // u00b8\n  0x0000,0x0000,0x0300,0x0700,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b9\n  0x0000,0x0fc0,0x1860,0x3030,0x3030,0x3030,0x3030,0x3030,0x3030,0x1860,0x0fc0,0x0000,0x0000,0x3ff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6600,0x3300,0x1980,0x0cc0,0x0660,0x0330,0x0198,\n  0x0330,0x0660,0x0cc0,0x1980,0x3300,0x6600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00bb\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x1c00,0x3c00,0x0c00,0x0c10,0x0c30,0x0c60,0x0cc0,0x0180,0x0330,0x0670,0x0cf0,\n  0x19b0,0x3330,0x6630,0x47f0,0x0030,0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00bc\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x3800,0x7810,0x1830,0x1860,0x18c0,0x1980,0x1b00,0x0600,0x0c00,0x1be0,0x3630,\n  0x6630,0x4060,0x00c0,0x0180,0x0300,0x07f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00bd\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x6300,0x0300,0x1e00,0x0308,0x0318,0x6330,0x3e60,0x00c0,0x0198,0x0338,0x0678,\n  0x0cd8,0x1998,0x3318,0x63f8,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00be\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0600,0x0c00,0x1800,0x3000,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00bf\n  0x0c00,0x0600,0x0300,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c0\n  0x0180,0x0300,0x0600,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c1\n  0x0700,0x0d80,0x18c0,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c2\n  0x1c60,0x3760,0x31c0,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c3\n  0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c4\n  0x0780,0x0cc0,0x0cc0,0x0780,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c5\n  0x0000,0x0000,0x0000,0x0000,0x3ff8,0x6300,0xc300,0xc300,0xc300,0xc300,0xc300,0xc300,0xfff0,0xc300,0xc300,0xc300,\n  0xc300,0xc300,0xc300,0xc300,0xc300,0xc3f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c6\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0600,0x0600,0x0600,0x0c00,0x1800,0x0000, // u00c7\n  0x0c00,0x0600,0x0300,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c8\n  0x0180,0x0300,0x0600,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c9\n  0x0700,0x0d80,0x18c0,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ca\n  0x18c0,0x18c0,0x18c0,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cb\n  0x0c00,0x0600,0x0300,0x0000,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cc\n  0x00c0,0x0180,0x0300,0x0000,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cd\n  0x0700,0x0d80,0x18c0,0x0000,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ce\n  0x18c0,0x18c0,0x18c0,0x0000,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cf\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x61c0,0x6060,0x6060,0x6030,0x6030,0x6030,0x6030,0xfe30,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6060,0x6060,0x61c0,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d0\n  0x1c60,0x3760,0x31c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x7030,0x7830,0x6c30,0x6630,0x6330,0x61b0,0x60f0,\n  0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d1\n  0x0c00,0x0600,0x0300,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d2\n  0x0180,0x0300,0x0600,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d3\n  0x0700,0x0d80,0x18c0,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d4\n  0x1c60,0x3760,0x31c0,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d5\n  0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6018,0x3030,0x1860,0x0cc0,0x0780,0x0300,0x0780,0x0cc0,\n  0x1860,0x3030,0x6018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d7\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6038,0x6030,0x6070,0x60f0,0x61b0,0x6330,0x6630,0x6c30,0x7830,\n  0x7030,0x6030,0xe030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d8\n  0x0c00,0x0600,0x0300,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d9\n  0x0180,0x0300,0x0600,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00da\n  0x0700,0x0d80,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00db\n  0x18c0,0x18c0,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00dc\n  0x00c0,0x0180,0x0300,0x0000,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00dd\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6060,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00de\n  0x0000,0x0000,0x0000,0x0000,0x3f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x60c0,0x7fc0,0x6060,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x6c60,0x67c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00df\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0600,0x0300,0x0000,0x1fc0,0x0060,0x0030,0x0030,0x1ff0,0x3030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x1fc0,0x0060,0x0030,0x0030,0x1ff0,0x3030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0d80,0x18c0,0x0000,0x1fc0,0x0060,0x0030,0x0030,0x1ff0,0x3030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1c60,0x3760,0x31c0,0x0000,0x1fc0,0x0060,0x0030,0x0030,0x1ff0,0x3030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x0060,0x0030,0x0030,0x1ff0,0x3030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0780,0x0cc0,0x0cc0,0x0780,0x1fc0,0x0060,0x0030,0x0030,0x1ff0,0x3030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7de0,0x0730,0x0318,0x0318,0x0318,0x3f18,0x63f8,\n  0xc300,0xc300,0xc300,0xc300,0x6398,0x3ef0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6030,0x3060,0x1fc0,0x0600,0x0600,0x0600,0x0c00,0x1800,0x0000, // u00e7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0600,0x0300,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x7ff0,\n  0x6000,0x6000,0x6000,0x6000,0x3030,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x7ff0,\n  0x6000,0x6000,0x6000,0x6000,0x3030,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0d80,0x18c0,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x7ff0,\n  0x6000,0x6000,0x6000,0x6000,0x3030,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x7ff0,\n  0x6000,0x6000,0x6000,0x6000,0x3030,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00eb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0600,0x0300,0x0000,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ec\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x0180,0x0300,0x0000,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ed\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0d80,0x18c0,0x0000,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ee\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ef\n  0x0000,0x0000,0x0000,0x0000,0x1980,0x0f00,0x1e00,0x3300,0x0180,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c60,0x6660,0x63c0,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0600,0x0300,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0d80,0x18c0,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1c60,0x3760,0x31c0,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x7ff8,0x0000,0x0000,\n  0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fd8,0x3078,0x6070,0x60f0,0x61b0,0x6330,0x6630,\n  0x6c30,0x7830,0x7030,0x6030,0xf060,0xdfc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0600,0x0300,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00fa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0d80,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00fb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00fc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,0x0030,0x0030,0x0060,0x3fc0,0x0000, // u00fd\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000, // u00fe\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,0x0030,0x0030,0x0060,0x3fc0,0x0000, // u00ff\n  0x0000,0x1fc0,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0100\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x0000,0x0000,0x1fc0,0x0060,0x0030,0x0030,0x1ff0,0x3030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0101\n  0x18c0,0x18c0,0x0f80,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0102\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x0f80,0x0000,0x1fc0,0x0060,0x0030,0x0030,0x1ff0,0x3030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0103\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0060,0x00c0,0x00c0,0x00c0,0x0078,0x0000, // u0104\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x0060,0x0030,0x0030,0x1ff0,0x3030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0060,0x00c0,0x00c0,0x00c0,0x0078,0x0000, // u0105\n  0x0180,0x0300,0x0600,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0106\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x1fc0,0x3060,0x6030,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0107\n  0x0700,0x0d80,0x18c0,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0108\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0d80,0x18c0,0x0000,0x1fc0,0x3060,0x6030,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0109\n  0x0300,0x0300,0x0300,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u010a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0000,0x1fc0,0x3060,0x6030,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u010b\n  0x18c0,0x0d80,0x0700,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u010c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x0d80,0x0700,0x0000,0x1fc0,0x3060,0x6030,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u010d\n  0x18c0,0x0d80,0x0700,0x0000,0x7f00,0x61c0,0x6060,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6060,0x6060,0x61c0,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u010e\n  0x18c0,0x0d80,0x0700,0x0000,0x0030,0x0030,0x0030,0x0030,0x0030,0x1ff0,0x3030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u010f\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x61c0,0x6060,0x6060,0x6030,0x6030,0x6030,0x6030,0xfe30,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6060,0x6060,0x61c0,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0110\n  0x0000,0x0000,0x0000,0x0000,0x0030,0x0030,0x07f8,0x0030,0x0030,0x1ff0,0x3030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0111\n  0x0000,0x1fc0,0x0000,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0112\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x7ff0,\n  0x6000,0x6000,0x6000,0x6000,0x3030,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0113\n  0x18c0,0x18c0,0x0f80,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0114\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x0f80,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x7ff0,\n  0x6000,0x6000,0x6000,0x6000,0x3030,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0115\n  0x0300,0x0300,0x0300,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0116\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x7ff0,\n  0x6000,0x6000,0x6000,0x6000,0x3030,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0117\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0060,0x00c0,0x00c0,0x00c0,0x0078,0x0000, // u0118\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x7ff0,\n  0x6000,0x6000,0x6000,0x6000,0x3030,0x1fe0,0x0380,0x0600,0x0600,0x0600,0x03c0,0x0000, // u0119\n  0x18c0,0x0d80,0x0700,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u011a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x0d80,0x0700,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x7ff0,\n  0x6000,0x6000,0x6000,0x6000,0x3030,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u011b\n  0x0700,0x0d80,0x18c0,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6000,0x6000,0x6000,0x6000,0x63f0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u011c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0d80,0x18c0,0x0000,0x1ff0,0x3030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,0x0030,0x0030,0x0060,0x3fc0,0x0000, // u011d\n  0x18c0,0x18c0,0x0f80,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6000,0x6000,0x6000,0x6000,0x63f0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u011e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x0f80,0x0000,0x1ff0,0x3030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,0x0030,0x0030,0x0060,0x3fc0,0x0000, // u011f\n  0x0300,0x0300,0x0300,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6000,0x6000,0x6000,0x6000,0x63f0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0120\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0000,0x1ff0,0x3030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,0x0030,0x0030,0x0060,0x3fc0,0x0000, // u0121\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6000,0x6000,0x6000,0x6000,0x63f0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0600,0x0600,0x0600,0x0c00,0x1800, // u0122\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0300,0x0300,0x0000,0x1ff0,0x3030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,0x0030,0x0030,0x0060,0x3fc0,0x0000, // u0123\n  0x0700,0x0d80,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0124\n  0x0700,0x0d80,0x18c0,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0125\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0xfff8,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0126\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0xff00,0x6000,0x6000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0127\n  0x1c60,0x3760,0x31c0,0x0000,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0128\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1c60,0x3760,0x31c0,0x0000,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0129\n  0x0000,0x1fc0,0x0000,0x0000,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u012a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x0000,0x0000,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u012b\n  0x18c0,0x18c0,0x0f80,0x0000,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u012c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x0f80,0x0000,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u012d\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0300,0x0600,0x0600,0x0600,0x03c0,0x0000, // u012e\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0300,0x0600,0x0600,0x0600,0x03c0,0x0000, // u012f\n  0x0300,0x0300,0x0300,0x0000,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0130\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0131\n  0x0000,0x0000,0x0000,0x0000,0xf078,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6630,0x6630,0x6630,0x6630,0x6630,0xf3e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0132\n  0x0000,0x0000,0x0000,0x0000,0x3018,0x3018,0x3018,0x0000,0x0000,0x7038,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,\n  0x3018,0x3018,0x3018,0x3018,0x3018,0x7818,0x0018,0x0318,0x0318,0x0318,0x01f0,0x0000, // u0133\n  0x00e0,0x01b0,0x0318,0x0000,0x01f8,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x6060,0x6060,0x6060,0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0134\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x00e0,0x01b0,0x0318,0x0000,0x01e0,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x3060,0x3060,0x3060,0x18c0,0x0f80,0x0000, // u0135\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6060,0x60c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7000,0x7000,0x7800,0x6c00,\n  0x6600,0x6300,0x6180,0x60c0,0x6060,0x6030,0x0000,0x0600,0x0600,0x0600,0x0c00,0x1800, // u0136\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3030,0x3060,0x30c0,0x3180,0x3300,0x3600,0x3c00,\n  0x3600,0x3300,0x3180,0x30c0,0x3060,0x3030,0x0000,0x0600,0x0600,0x0600,0x0c00,0x1800, // u0137\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3030,0x3060,0x30c0,0x3180,0x3300,0x3600,0x3c00,\n  0x3600,0x3300,0x3180,0x30c0,0x3060,0x3030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0138\n  0x1800,0x3000,0x6000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0139\n  0x00c0,0x0180,0x0300,0x0000,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u013a\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0600,0x0600,0x0600,0x0c00,0x1800, // u013b\n  0x0000,0x0000,0x0000,0x0000,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0300,0x0300,0x0300,0x0600,0x0c00, // u013c\n  0x18c0,0x0d80,0x0700,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u013d\n  0x18c0,0x0d80,0x0700,0x0000,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u013e\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x60c0,0x60c0,0x60c0,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u013f\n  0x0000,0x0000,0x0000,0x0000,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x030c,0x030c,0x030c,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0140\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3300,0x3600,0x3c00,0x3800,0x3000,0x7000,0xf000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0141\n  0x0000,0x0000,0x0000,0x0000,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0360,0x03c0,0x0380,0x0300,0x0700,0x0f00,0x1b00,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0142\n  0x0180,0x0300,0x0600,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x7030,0x7830,0x6c30,0x6630,0x6330,0x61b0,0x60f0,\n  0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0143\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0144\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x7030,0x7830,0x6c30,0x6630,0x6330,0x61b0,0x60f0,\n  0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0600,0x0600,0x0600,0x0c00,0x1800, // u0145\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0600,0x0600,0x0600,0x0c00,0x1800, // u0146\n  0x18c0,0x0d80,0x0700,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x7030,0x7830,0x6c30,0x6630,0x6330,0x61b0,0x60f0,\n  0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0147\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x0d80,0x0700,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0148\n  0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0xc000,0xc000,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0149\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x7030,0x7830,0x6c30,0x6630,0x6330,0x61b0,0x60f0,\n  0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x0030,0x0030,0x0030,0x0060,0x03c0,0x0000, // u014a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0030,0x0030,0x0030,0x0060,0x03c0,0x0000, // u014b\n  0x0000,0x1fc0,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u014c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u014d\n  0x18c0,0x18c0,0x0f80,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u014e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x0f80,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u014f\n  0x0630,0x0c60,0x18c0,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0150\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0630,0x0c60,0x18c0,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0151\n  0x0000,0x0000,0x0000,0x0000,0x3ff8,0x6300,0xc300,0xc300,0xc300,0xc300,0xc300,0xc300,0xc3f0,0xc300,0xc300,0xc300,\n  0xc300,0xc300,0xc300,0xc300,0x6300,0x3ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0152\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fe0,0x6330,0xc318,0xc318,0xc318,0xc318,0xc3f8,\n  0xc300,0xc300,0xc300,0xc300,0x6318,0x3ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0153\n  0x0180,0x0300,0x0600,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x7800,0x6c00,\n  0x6600,0x6300,0x6180,0x60c0,0x6060,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0154\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x67f0,0x6c00,0x7800,0x7000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0155\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x7800,0x6c00,\n  0x6600,0x6300,0x6180,0x60c0,0x6060,0x6030,0x0000,0x0600,0x0600,0x0600,0x0c00,0x1800, // u0156\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x33f8,0x3600,0x3c00,0x3800,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,0x3000,0x3000,0x3000,0x6000,0xc000, // u0157\n  0x18c0,0x0d80,0x0700,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x7800,0x6c00,\n  0x6600,0x6300,0x6180,0x60c0,0x6060,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0158\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x0d80,0x0700,0x0000,0x67f0,0x6c00,0x7800,0x7000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0159\n  0x0180,0x0300,0x0600,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6000,0x6000,0x6000,0x3000,0x1fc0,0x0060,0x0030,0x0030,\n  0x0030,0x0030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u015a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x1fc0,0x3060,0x6030,0x6000,0x6000,0x3000,0x1fc0,\n  0x0060,0x0030,0x0030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u015b\n  0x0700,0x0d80,0x18c0,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6000,0x6000,0x6000,0x3000,0x1fc0,0x0060,0x0030,0x0030,\n  0x0030,0x0030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u015c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0d80,0x18c0,0x0000,0x1fc0,0x3060,0x6030,0x6000,0x6000,0x3000,0x1fc0,\n  0x0060,0x0030,0x0030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u015d\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6000,0x6000,0x6000,0x3000,0x1fc0,0x0060,0x0030,0x0030,\n  0x0030,0x0030,0x6030,0x6030,0x3060,0x1fc0,0x0600,0x0600,0x0600,0x0c00,0x1800,0x0000, // u015e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6000,0x6000,0x3000,0x1fc0,\n  0x0060,0x0030,0x0030,0x6030,0x3060,0x1fc0,0x0600,0x0600,0x0600,0x0c00,0x1800,0x0000, // u015f\n  0x18c0,0x0d80,0x0700,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6000,0x6000,0x6000,0x3000,0x1fc0,0x0060,0x0030,0x0030,\n  0x0030,0x0030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0160\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x0d80,0x0700,0x0000,0x1fc0,0x3060,0x6030,0x6000,0x6000,0x3000,0x1fc0,\n  0x0060,0x0030,0x0030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0161\n  0x0000,0x0000,0x0000,0x0000,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0180,0x0180,0x0180,0x0300,0x0600,0x0000, // u0162\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,0x3fc0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x03e0,0x0180,0x0180,0x0180,0x0300,0x0600,0x0000, // u0163\n  0x18c0,0x0d80,0x0700,0x0000,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0164\n  0x3180,0x1b00,0x0e00,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,0x3fc0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x03e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0165\n  0x0000,0x0000,0x0000,0x0000,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x1fe0,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0166\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,0x3fc0,0x0600,0x0600,0x1f80,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x03e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0167\n  0x1c60,0x3760,0x31c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0168\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1c60,0x3760,0x31c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0169\n  0x0000,0x1fc0,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u016a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u016b\n  0x18c0,0x18c0,0x0f80,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u016c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x0f80,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u016d\n  0x0780,0x0cc0,0x0cc0,0x0780,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u016e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0780,0x0cc0,0x0cc0,0x0780,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u016f\n  0x0630,0x0c60,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0170\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0630,0x0c60,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0171\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0380,0x0600,0x0600,0x0600,0x03c0,0x0000, // u0172\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0060,0x00c0,0x00c0,0x00c0,0x0078,0x0000, // u0173\n  0x0700,0x0d80,0x18c0,0x0000,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6318,0x6318,0x6798,\n  0x6cd8,0x6cd8,0x7878,0x7038,0x6018,0x6018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0174\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0d80,0x18c0,0x0000,0x6018,0x6018,0x6018,0x6018,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x3330,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0175\n  0x0700,0x0d80,0x18c0,0x0000,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0176\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0d80,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,0x0030,0x0030,0x0060,0x3fc0,0x0000, // u0177\n  0x18c0,0x18c0,0x18c0,0x0000,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0178\n  0x0180,0x0300,0x0600,0x0000,0x7ff0,0x0030,0x0030,0x0030,0x0030,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,\n  0x3000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0179\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x7ff0,0x0030,0x0060,0x00c0,0x0180,0x0300,0x0600,\n  0x0c00,0x1800,0x3000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u017a\n  0x0300,0x0300,0x0300,0x0000,0x7ff0,0x0030,0x0030,0x0030,0x0030,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,\n  0x3000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u017b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0000,0x7ff0,0x0030,0x0060,0x00c0,0x0180,0x0300,0x0600,\n  0x0c00,0x1800,0x3000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u017c\n  0x18c0,0x0d80,0x0700,0x0000,0x7ff0,0x0030,0x0030,0x0030,0x0030,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,\n  0x3000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u017d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x0d80,0x0700,0x0000,0x7ff0,0x0030,0x0060,0x00c0,0x0180,0x0300,0x0600,\n  0x0c00,0x1800,0x3000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u017e\n  0x0000,0x0000,0x0000,0x0000,0x03f0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u017f\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,\n  0x0030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0186\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0ff0,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u018e\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x0030,0x0030,0x0030,0x0030,0x0030,0x7ff0,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u018f\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6000,0x6000,0x6000,0x6000,0x3000,0x1f80,0x3000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0190\n  0x0000,0x0000,0x0000,0x0000,0x01e0,0x0330,0x0330,0x0300,0x0300,0x0300,0x0300,0x1fe0,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x3300,0x3300,0x1e00,0x0000,0x0000, // u0192\n  0x0000,0x0000,0x0000,0x0000,0x3018,0x3018,0x3018,0x3018,0x3018,0x3818,0x3c18,0x3618,0x3318,0x3198,0x30d8,0x3078,\n  0x3038,0x3018,0x3018,0x3018,0x3018,0x3018,0x3000,0x3000,0x3000,0x3000,0xe000,0x0000, // u019d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0000, // u019e\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x0030,0x0030,0x0030,0x0060,0x00c0,0x0180,0x0300,0x7ff0,0x0600,0x0c00,0x1800,\n  0x3000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x0030,0x0060,0x00c0,0x0180,0x0300,0x7ff0,\n  0x0600,0x0c00,0x1800,0x3000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01b6\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x0030,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0fc0,0x0060,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01b7\n  0x18c0,0x0d80,0x0700,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01cd\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x0d80,0x0700,0x0000,0x1fc0,0x0060,0x0030,0x0030,0x1ff0,0x3030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01ce\n  0x18c0,0x0d80,0x0700,0x0000,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01cf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x0d80,0x0700,0x0000,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d0\n  0x18c0,0x0d80,0x0700,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x0d80,0x0700,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d2\n  0x18c0,0x0d80,0x0700,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x0d80,0x0700,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d4\n  0x0000,0x3ff0,0x0000,0x0000,0x3ff8,0x6300,0xc300,0xc300,0xc300,0xc300,0xc300,0xc300,0xfff0,0xc300,0xc300,0xc300,\n  0xc300,0xc300,0xc300,0xc300,0xc300,0xc3f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fe0,0x0000,0x0000,0x7de0,0x0730,0x0318,0x0318,0x0318,0x3f18,0x63f8,\n  0xc300,0xc300,0xc300,0xc300,0x6398,0x3ef0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e3\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6000,0x6000,0x6000,0x6000,0x63f0,0x6030,0x6030,\n  0x61fc,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3030,0x6030,0x6030,0x6030,0x6030,0x61fc,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,0x0030,0x0030,0x0060,0x3fc0,0x0000, // u01e5\n  0x18c0,0x0d80,0x0700,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6000,0x6000,0x6000,0x6000,0x63f0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x0d80,0x0700,0x0000,0x1ff0,0x3030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,0x0030,0x0030,0x0060,0x3fc0,0x0000, // u01e7\n  0x18c0,0x0d80,0x0700,0x0000,0x6030,0x6060,0x60c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7000,0x7000,0x7800,0x6c00,\n  0x6600,0x6300,0x6180,0x60c0,0x6060,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e8\n  0x18c0,0x0d80,0x0700,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3030,0x3060,0x30c0,0x3180,0x3300,0x3600,0x3c00,\n  0x3600,0x3300,0x3180,0x30c0,0x3060,0x3030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e9\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0380,0x0600,0x0600,0x0600,0x03c0,0x0000, // u01ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0380,0x0600,0x0600,0x0600,0x03c0,0x0000, // u01eb\n  0x0000,0x1fc0,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0380,0x0600,0x0600,0x0600,0x03c0,0x0000, // u01ec\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0380,0x0600,0x0600,0x0600,0x03c0,0x0000, // u01ed\n  0x18c0,0x0d80,0x0700,0x0000,0x7ff0,0x0030,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0fc0,0x0060,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01ee\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x0d80,0x0700,0x0000,0x7ff0,0x0030,0x0060,0x00c0,0x0180,0x0300,0x0600,\n  0x0fc0,0x0060,0x0030,0x0030,0x0030,0x0030,0x0030,0x6030,0x6030,0x3060,0x1fc0,0x0000, // u01ef\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0318,0x01b0,0x00e0,0x0000,0x01e0,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x3060,0x3060,0x3060,0x18c0,0x0f80,0x0000, // u01f0\n  0x0180,0x0300,0x0600,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6000,0x6000,0x6000,0x6000,0x63f0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x0180,0x0300,0x0000,0x1ff0,0x3030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,0x0030,0x0030,0x0060,0x3fc0,0x0000, // u01f5\n  0x00c0,0x0180,0x0300,0x0000,0x3ff8,0x6300,0xc300,0xc300,0xc300,0xc300,0xc300,0xc300,0xfff0,0xc300,0xc300,0xc300,\n  0xc300,0xc300,0xc300,0xc300,0xc300,0xc3f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01fc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x0180,0x0300,0x0000,0x7de0,0x0730,0x0318,0x0318,0x0318,0x3f18,0x63f8,\n  0xc300,0xc300,0xc300,0xc300,0x6398,0x3ef0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01fd\n  0x0180,0x0300,0x0600,0x0000,0x1fc0,0x3060,0x6030,0x6038,0x6030,0x6070,0x60f0,0x61b0,0x6330,0x6630,0x6c30,0x7830,\n  0x7030,0x6030,0xe030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01fe\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x1fd8,0x3078,0x6070,0x60f0,0x61b0,0x6330,0x6630,\n  0x6c30,0x7830,0x7030,0x6030,0xf060,0xdfc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01ff\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6000,0x6000,0x6000,0x3000,0x1fc0,0x0060,0x0030,0x0030,\n  0x0030,0x0030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0600,0x0600,0x0600,0x0c00,0x1800, // u0218\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6000,0x6000,0x3000,0x1fc0,\n  0x0060,0x0030,0x0030,0x6030,0x3060,0x1fc0,0x0000,0x0600,0x0600,0x0600,0x0c00,0x1800, // u0219\n  0x0000,0x0000,0x0000,0x0000,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0300,0x0300,0x0300,0x0600,0x0c00, // u021a\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,0x3fc0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x03e0,0x0000,0x0180,0x0180,0x0180,0x0300,0x0600, // u021b\n  0x0000,0x1fc0,0x0000,0x0000,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0232\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,0x0030,0x0030,0x0060,0x3fc0,0x0000, // u0233\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01e0,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x3060,0x3060,0x3060,0x18c0,0x0f80,0x0000, // u0237\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x0030,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0254\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x7ff0,\n  0x0030,0x0030,0x0030,0x0030,0x6060,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0258\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x6060,0x0030,0x0030,0x0030,0x0030,0x7ff0,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0259\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6000,0x6000,0x3000,0x1f80,\n  0x3000,0x6000,0x6000,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u025b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fe0,0x3030,0x3018,0x3018,0x3018,0x3018,0x3018,\n  0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3000,0x3000,0x3000,0x3000,0xe000,0x0000, // u0272\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x0030,0x0060,0x00c0,0x0180,0x0300,0x0600,\n  0x0fc0,0x0060,0x0030,0x0030,0x0030,0x0030,0x0030,0x6030,0x6030,0x3060,0x1fc0,0x0000, // u0292\n  0x0300,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bb\n  0x0300,0x0300,0x0300,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bc\n  0x0600,0x0600,0x0600,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bd\n  0x0700,0x0d80,0x18c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02c6\n  0x18c0,0x0d80,0x0700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02c7\n  0x18c0,0x18c0,0x0f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02d8\n  0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02d9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0600,0x0600,0x0600,0x03c0,0x0000, // u02db\n  0x1c60,0x3760,0x31c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02dc\n  0x0630,0x0c60,0x18c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02dd\n  0x0c00,0x0600,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0300\n  0x0180,0x0300,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0301\n  0x0700,0x0d80,0x18c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0302\n  0x1c60,0x3760,0x31c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0303\n  0x0000,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0304\n  0x0000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0305\n  0x18c0,0x18c0,0x0f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0306\n  0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0307\n  0x18c0,0x18c0,0x18c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0308\n  0x0780,0x0cc0,0x0cc0,0x0780,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030a\n  0x0630,0x0c60,0x18c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030b\n  0x18c0,0x0d80,0x0700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u0329\n  0x0000,0x3000,0x6000,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0384\n  0x0180,0x0300,0x0600,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0385\n  0x0000,0x3000,0x6000,0xc000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0386\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0387\n  0x0000,0x3000,0x6000,0xc000,0x3ff8,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3fc0,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0388\n  0x0000,0x3000,0x6000,0xc000,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3ff8,0x3018,0x3018,0x3018,\n  0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0389\n  0x0000,0x3000,0x6000,0xc000,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u038a\n  0x0000,0x3000,0x6000,0xc000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u038c\n  0x0000,0x3000,0x6000,0xc000,0x300c,0x300c,0x1818,0x1818,0x0c30,0x0c30,0x0660,0x0660,0x03c0,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u038e\n  0x0000,0x3000,0x6000,0xc000,0x1fe0,0x3030,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,\n  0x3030,0x1860,0x0cc0,0x0cc0,0x0cc0,0x7cf8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u038f\n  0x0180,0x0300,0x0600,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0390\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0391\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x6060,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0392\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0393\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0780,0x0780,0x0780,0x0cc0,0x0cc0,0x0cc0,0x1860,0x1860,0x1860,\n  0x3030,0x3030,0x3030,0x6018,0x6018,0x7ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0394\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0395\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x0030,0x0030,0x0030,0x0030,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,\n  0x3000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0396\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0397\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6fb0,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0398\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0399\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6060,0x60c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7000,0x7000,0x7800,0x6c00,\n  0x6600,0x6300,0x6180,0x60c0,0x6060,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u039a\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0780,0x0780,0x0780,0x0cc0,0x0cc0,0x0cc0,0x1860,0x1860,0x1860,\n  0x3030,0x3030,0x3030,0x6018,0x6018,0x6018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u039b\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x7038,0x7878,0x6cd8,0x6cd8,0x6798,0x6318,0x6318,0x6018,0x6018,0x6018,\n  0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u039c\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x7030,0x7830,0x6c30,0x6630,0x6330,0x61b0,0x60f0,\n  0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u039d\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u039e\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u039f\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a0\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a1\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x00c0,0x00c0,0x0180,0x0300,\n  0x0600,0x0c00,0x1800,0x3000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a3\n  0x0000,0x0000,0x0000,0x0000,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a4\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a5\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x1fe0,0x3330,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x3330,0x1fe0,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a6\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x3060,0x3060,0x18c0,0x18c0,0x0d80,0x0d80,0x0700,0x0700,0x0d80,0x0d80,\n  0x18c0,0x18c0,0x3060,0x3060,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a7\n  0x0000,0x0000,0x0000,0x0000,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,\n  0x3330,0x1fe0,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a8\n  0x0000,0x0000,0x0000,0x0000,0x1fe0,0x3030,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,\n  0x3030,0x1860,0x0cc0,0x0cc0,0x0cc0,0x7cf8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a9\n  0x18c0,0x18c0,0x18c0,0x0000,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03aa\n  0x18c0,0x18c0,0x18c0,0x0000,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ab\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x1f98,0x30f0,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x6060,0x30f0,0x1f98,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ac\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x1fc0,0x3060,0x6030,0x6000,0x6000,0x3000,0x1f80,\n  0x3000,0x6000,0x6000,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ad\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0000, // u03ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03af\n  0x0180,0x0300,0x0600,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f98,0x30f0,0x6060,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x6060,0x30f0,0x1f98,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b1\n  0x0000,0x0000,0x0000,0x0000,0x3f80,0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x60c0,0x7fc0,0x6060,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000, // u03b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,\n  0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000, // u03b3\n  0x0000,0x0000,0x0000,0x0000,0x1fe0,0x0c00,0x0600,0x0300,0x0180,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6000,0x6000,0x3000,0x1f80,\n  0x3000,0x6000,0x6000,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b5\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x3000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x3000,0x1fc0,0x0060,0x0030,0x0030,0x0030,0x00e0,0x0000, // u03b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0000, // u03b7\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x1860,0x3030,0x3030,0x3030,0x3030,0x3030,0x3030,0x3ff0,0x3030,0x3030,0x3030,\n  0x3030,0x3030,0x3030,0x3030,0x1860,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3030,0x3060,0x30c0,0x3180,0x3300,0x3600,0x3c00,\n  0x3600,0x3300,0x3180,0x30c0,0x3060,0x3030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ba\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x0c00,0x0c00,0x0600,0x0600,0x0700,0x0700,0x0d80,0x0d80,0x18c0,0x18c0,\n  0x3060,0x3060,0x3060,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6070,0x60f0,0x61b0,0x7f30,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000, // u03bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x3060,0x3060,0x3060,0x18c0,\n  0x18c0,0x18c0,0x0d80,0x0d80,0x0700,0x0700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03bd\n  0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3000,0x6000,0x6000,0x6000,0x6000,0x6000,0x3000,0x1fc0,0x3000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x3000,0x1fc0,0x0060,0x0030,0x0030,0x0030,0x00e0,0x0000, // u03be\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000, // u03c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x3000,0x1fc0,0x0060,0x0030,0x0030,0x0030,0x00e0,0x0000, // u03c2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff8,0x30c0,0x6060,0x6060,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x01e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x19e0,0x3330,0x6318,0x6318,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x3330,0x1fe0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000, // u03c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x3060,0x3060,0x18c0,0x18c0,0x0d80,\n  0x0d80,0x0700,0x0700,0x0d80,0x0d80,0x18c0,0x18c0,0x3060,0x3060,0x6030,0x6030,0x0000, // u03c7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x3330,0x1fe0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000, // u03c8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1860,0x3030,0x6018,0x6018,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x37b0,0x1ce0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ca\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03cc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03cd\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x0180,0x0300,0x0000,0x1860,0x3030,0x6018,0x6018,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x37b0,0x1ce0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ce\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x1860,0x3030,0x3030,0x3030,0x3030,0x1830,0x0ff8,0x0030,0x0030,0xf030,0x3030,\n  0x3030,0x3030,0x3030,0x3030,0x1860,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x1fe0,0x3330,0x6318,0x6318,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x3330,0x1fe0,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000, // u03d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7818,0x0c30,0x0660,0x06c0,0x0380,0x0300,0x0300,\n  0x0300,0x0700,0x0d80,0x1980,0x30c0,0x6078,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x6000,0x6000,0x6000,0x3000,0x1fe0,0x0000, // u03f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f2\n  0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0000,0x0000,0x01e0,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x3060,0x3060,0x3060,0x18c0,0x0f80,0x0000, // u03f3\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1800,0x3000,0x6000,0x6000,0x6000,0x7fc0,\n  0x6000,0x6000,0x6000,0x3000,0x1800,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x00c0,0x0060,0x0030,0x0030,0x0030,0x1ff0,\n  0x0030,0x0030,0x0030,0x0060,0x00c0,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f6\n  0x0c00,0x0600,0x0300,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0400\n  0x18c0,0x18c0,0x18c0,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0401\n  0x0000,0x0000,0x0000,0x0000,0xfc00,0x3000,0x3000,0x3000,0x3000,0x3000,0x3fc0,0x3060,0x3030,0x3030,0x3030,0x3030,\n  0x3030,0x3030,0x3030,0x3030,0x3060,0x31c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0402\n  0x0180,0x0300,0x0600,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0403\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0404\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6000,0x6000,0x6000,0x3000,0x1fc0,0x0060,0x0030,0x0030,\n  0x0030,0x0030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0405\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0406\n  0x18c0,0x18c0,0x18c0,0x0000,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0407\n  0x0000,0x0000,0x0000,0x0000,0x01f8,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x6060,0x6060,0x6060,0x6060,0x30c0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0408\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x3300,0x6300,0x6300,0x6300,0x6300,0x6300,0x63e0,0x6330,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x6330,0xc3e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0409\n  0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x6300,0x6300,0x6300,0x6300,0x6300,0x63e0,0x7f30,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x6330,0x63e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u040a\n  0x0000,0x0000,0x0000,0x0000,0xfc00,0x3000,0x3000,0x3000,0x3000,0x3000,0x3fc0,0x3060,0x3030,0x3030,0x3030,0x3030,\n  0x3030,0x3030,0x3030,0x3030,0x3030,0x3030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u040b\n  0x0180,0x0300,0x0600,0x0000,0x6030,0x6060,0x60c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7000,0x7000,0x7800,0x6c00,\n  0x6600,0x6300,0x6180,0x60c0,0x6060,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u040c\n  0x0c00,0x0600,0x0300,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6070,0x60f0,0x61b0,0x6330,0x6630,0x6c30,0x7830,\n  0x7030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u040d\n  0x18c0,0x18c0,0x0f80,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0060,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u040e\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,\n  0x6018,0x6018,0x6018,0x6018,0x6018,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000, // u040f\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0410\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x6060,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0411\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x6060,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0412\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0413\n  0x0000,0x0000,0x0000,0x0000,0x07f0,0x0c30,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,\n  0x1830,0x1830,0x1830,0x1830,0x1830,0x7ff8,0x6018,0x6018,0x6018,0x0000,0x0000,0x0000, // u0414\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0415\n  0x0000,0x0000,0x0000,0x0000,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x3330,0x1b60,0x0fc0,0x1b60,0x3330,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0416\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x0030,0x0030,0x0030,0x0030,0x0060,0x0fc0,0x0060,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0417\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6070,0x60f0,0x61b0,0x6330,0x6630,0x6c30,0x7830,\n  0x7030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0418\n  0x18c0,0x18c0,0x0f80,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6070,0x60f0,0x61b0,0x6330,0x6630,0x6c30,0x7830,\n  0x7030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0419\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6060,0x60c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7000,0x7000,0x7800,0x6c00,\n  0x6600,0x6300,0x6180,0x60c0,0x6060,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u041a\n  0x0000,0x0000,0x0000,0x0000,0x07f0,0x0c30,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,\n  0x1830,0x1830,0x1830,0x1830,0x3030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u041b\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x7038,0x7878,0x6cd8,0x6cd8,0x6798,0x6318,0x6318,0x6018,0x6018,0x6018,\n  0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u041c\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u041d\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u041e\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u041f\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0420\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0421\n  0x0000,0x0000,0x0000,0x0000,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0422\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0060,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0423\n  0x0000,0x0000,0x0300,0x0300,0x1fe0,0x3330,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x3330,0x1fe0,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000, // u0424\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x3060,0x3060,0x18c0,0x18c0,0x0d80,0x0d80,0x0700,0x0700,0x0d80,0x0d80,\n  0x18c0,0x18c0,0x3060,0x3060,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0425\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff8,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u0426\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0427\n  0x0000,0x0000,0x0000,0x0000,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x3318,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0428\n  0x0000,0x0000,0x0000,0x0000,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x3318,0x1ffc,0x000c,0x000c,0x000c,0x000c,0x0000,0x0000, // u0429\n  0x0000,0x0000,0x0000,0x0000,0xf000,0xf000,0x3000,0x3000,0x3000,0x3000,0x3fe0,0x3030,0x3018,0x3018,0x3018,0x3018,\n  0x3018,0x3018,0x3018,0x3018,0x3030,0x3fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u042a\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x7f18,0x6198,0x60d8,0x60d8,0x60d8,0x60d8,\n  0x60d8,0x60d8,0x60d8,0x60d8,0x6198,0x7f18,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u042b\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u042c\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0ff0,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u042d\n  0x0000,0x0000,0x0000,0x0000,0x61e0,0x6330,0x6618,0x6618,0x6618,0x6618,0x6618,0x6618,0x6618,0x7e18,0x6618,0x6618,\n  0x6618,0x6618,0x6618,0x6618,0x6330,0x61e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u042e\n  0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x00f0,0x01b0,\n  0x0330,0x0630,0x0c30,0x1830,0x3030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u042f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x0060,0x0030,0x0030,0x1ff0,0x3030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0430\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0431\n  0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,0x7fc0,0x6060,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0432\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0433\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,0x0030,0x0030,0x0060,0x3fc0,0x0000, // u0434\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x7ff0,\n  0x6000,0x6000,0x6000,0x6000,0x3030,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0435\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6318,0x6318,0x6318,0x6318,0x3330,0x1b60,0x0fc0,\n  0x1b60,0x3330,0x6318,0x6318,0x6318,0x6318,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0436\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x0030,0x0030,0x0060,0x0fc0,\n  0x0060,0x0030,0x0030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0437\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0438\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x0f80,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0439\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3030,0x3060,0x30c0,0x3180,0x3300,0x3600,0x3c00,\n  0x3600,0x3300,0x3180,0x30c0,0x3060,0x3030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u043a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07f0,0x0c30,0x1830,0x1830,0x1830,0x1830,0x1830,\n  0x1830,0x1830,0x1830,0x1830,0x3030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u043b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x7038,0x7878,0x6cd8,0x6cd8,0x6798,\n  0x6318,0x6318,0x6018,0x6018,0x6018,0x6018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u043c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u043d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u043e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u043f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000, // u0440\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0441\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0442\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,0x0030,0x0030,0x0060,0x3fc0,0x0000, // u0443\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x1fe0,0x3330,0x6318,0x6318,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x3330,0x1fe0,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000, // u0444\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x3060,0x18c0,0x0d80,0x0700,0x0700,\n  0x0700,0x0d80,0x18c0,0x3060,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0445\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff8,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u0446\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0447\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x3318,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0448\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x3318,0x1ffc,0x000c,0x000c,0x000c,0x000c,0x0000,0x0000, // u0449\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf000,0xf000,0x3000,0x3000,0x3fc0,0x3060,0x3030,\n  0x3030,0x3030,0x3030,0x3030,0x3060,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u044a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x6018,0x6018,0x7f18,0x6198,0x60d8,\n  0x60d8,0x60d8,0x60d8,0x60d8,0x6198,0x7f18,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u044b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3fc0,0x3060,0x3030,\n  0x3030,0x3030,0x3030,0x3030,0x3060,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u044c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x0030,0x0030,0x0030,0x0ff0,\n  0x0030,0x0030,0x0030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u044d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x61e0,0x6330,0x6618,0x6618,0x6618,0x6618,0x7e18,\n  0x6618,0x6618,0x6618,0x6618,0x6330,0x61e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u044e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3030,0x6030,0x6030,0x6030,0x3030,0x1ff0,\n  0x01b0,0x0330,0x0630,0x0c30,0x1830,0x3030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u044f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0600,0x0300,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x7ff0,\n  0x6000,0x6000,0x6000,0x6000,0x3030,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0450\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x7ff0,\n  0x6000,0x6000,0x6000,0x6000,0x3030,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0451\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0xff00,0x6000,0x6000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0030,0x0030,0x0030,0x0060,0x03c0,0x0000, // u0452\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0453\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6000,0x6000,0x6000,0x7f80,\n  0x6000,0x6000,0x6000,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0454\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6000,0x6000,0x3000,0x1fc0,\n  0x0060,0x0030,0x0030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0455\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0456\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0457\n  0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0000,0x0000,0x01e0,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x3060,0x3060,0x3060,0x18c0,0x0f80,0x0000, // u0458\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3300,0x6300,0x6300,0x63e0,0x6330,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x6330,0xc3e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0459\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x6300,0x6300,0x63e0,0x6330,0x7f18,\n  0x6318,0x6318,0x6318,0x6318,0x6330,0x63e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u045a\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0xff00,0x6000,0x6000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u045b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x0180,0x0300,0x0000,0x3030,0x3060,0x30c0,0x3180,0x3300,0x3600,0x3c00,\n  0x3600,0x3300,0x3180,0x30c0,0x3060,0x3030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u045c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0600,0x0300,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u045d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x0f80,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,0x0030,0x0030,0x0060,0x3fc0,0x0000, // u045e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,\n  0x6018,0x6018,0x6018,0x6018,0x6018,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000, // u045f\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0xff00,0x3000,0x3000,0x3000,0x3fe0,0x3030,0x3018,0x3018,0x3018,0x3018,\n  0x3018,0x3018,0x3018,0x3018,0x3030,0x3fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0462\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0xff00,0x3000,0x3000,0x3000,0x3000,0x3fc0,0x3060,0x3030,\n  0x3030,0x3030,0x3030,0x3030,0x3060,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0463\n  0x0000,0x0000,0x0000,0x0000,0x7ff8,0x6018,0x3030,0x3030,0x1860,0x0cc0,0x0cc0,0x0780,0x0fc0,0x1b60,0x3330,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u046a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff8,0x6018,0x3030,0x1860,0x0cc0,0x0780,0x0fc0,\n  0x1b60,0x3330,0x6318,0x6318,0x6318,0x6318,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u046b\n  0x0000,0x0030,0x0030,0x0030,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0490\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0030,0x0030,0x0030,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0491\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0xff00,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0492\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0xff00,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0493\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x6060,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0030,0x0060,0x00c0,0x0000,0x0000,0x0000, // u0494\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,\n  0x60c0,0x6060,0x6060,0x6060,0x6060,0x6060,0x0060,0x00c0,0x0180,0x0000,0x0000,0x0000, // u0495\n  0x0000,0x0000,0x0000,0x0000,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x3330,0x1b60,0x0fc0,0x1b60,0x3330,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x6318,0x631c,0x000c,0x000c,0x000c,0x000c,0x0000,0x0000, // u0496\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6318,0x6318,0x6318,0x6318,0x3330,0x1b60,0x0fc0,\n  0x1b60,0x3330,0x6318,0x6318,0x6318,0x631c,0x000c,0x000c,0x000c,0x000c,0x0000,0x0000, // u0497\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x0030,0x0030,0x0030,0x0030,0x0060,0x0fc0,0x0060,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x6030,0x3060,0x1fc0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000, // u0498\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x0030,0x0030,0x0060,0x0fc0,\n  0x0060,0x0030,0x0030,0x6030,0x3060,0x1fc0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000, // u0499\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6060,0x60c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7000,0x7000,0x7800,0x6c00,\n  0x6600,0x6300,0x6180,0x60c0,0x6060,0x6030,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u049a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3030,0x3060,0x30c0,0x3180,0x3300,0x3600,0x3c00,\n  0x3600,0x3300,0x3180,0x30c0,0x3060,0x3030,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u049b\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x6030,0x6060,0x6cc0,0x6d80,0x6f00,0x6e00,0x7c00,0x7c00,0x6e00,0x6f00,\n  0x6d80,0x6cc0,0x6060,0x6030,0x6018,0x6018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u049c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6018,0x6030,0x6c60,0x6cc0,0x6d80,0x6f00,0x7e00,\n  0x6f00,0x6d80,0x6cc0,0x6c60,0x6030,0x6018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u049d\n  0x0000,0x0000,0x0000,0x0000,0xf018,0xf030,0x3060,0x30c0,0x3180,0x3300,0x3600,0x3c00,0x3800,0x3800,0x3c00,0x3600,\n  0x3300,0x3180,0x30c0,0x3060,0x3030,0x3018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf030,0xf060,0x30c0,0x3180,0x3300,0x3600,0x3c00,\n  0x3600,0x3300,0x3180,0x30c0,0x3060,0x3030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a1\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6038,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u04a2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6038,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u04a3\n  0x0000,0x0000,0x0000,0x0000,0x60fc,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x60c0,0x60c0,0x60c0,\n  0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60fc,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,\n  0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a5\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000, // u04aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6030,0x3060,0x1fc0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000, // u04ab\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,\n  0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000, // u04af\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x3ff0,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,\n  0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,0x3ff0,0x0300,0x0300,0x0300,0x0300,0x0000, // u04b1\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x3060,0x3060,0x18c0,0x18c0,0x0d80,0x0d80,0x0700,0x0700,0x0d80,0x0d80,\n  0x18c0,0x18c0,0x3060,0x3060,0x6030,0x6038,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u04b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x3060,0x18c0,0x0d80,0x0700,0x0700,\n  0x0700,0x0d80,0x18c0,0x3060,0x6030,0x6038,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u04b3\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0038,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u04b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0038,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u04b7\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6330,0x6330,0x6330,0x3330,0x1ff0,0x0330,0x0330,\n  0x0330,0x0330,0x0030,0x0030,0x0030,0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6330,0x6330,0x3330,0x1ff0,\n  0x0330,0x0330,0x0330,0x0030,0x0030,0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04b9\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x6060,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x6060,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04bb\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04c0\n  0x18c0,0x18c0,0x0f80,0x0000,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x3330,0x1b60,0x0fc0,0x1b60,0x3330,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x0f80,0x0000,0x6318,0x6318,0x6318,0x6318,0x3330,0x1b60,0x0fc0,\n  0x1b60,0x3330,0x6318,0x6318,0x6318,0x6318,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04c2\n  0x0000,0x0000,0x0000,0x0000,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04cf\n  0x18c0,0x18c0,0x0f80,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x0f80,0x0000,0x1fc0,0x0060,0x0030,0x0030,0x1ff0,0x3030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d1\n  0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x0060,0x0030,0x0030,0x1ff0,0x3030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d3\n  0x0000,0x0000,0x0000,0x0000,0x3ff8,0x6300,0xc300,0xc300,0xc300,0xc300,0xc300,0xc300,0xfff0,0xc300,0xc300,0xc300,\n  0xc300,0xc300,0xc300,0xc300,0xc300,0xc3f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7de0,0x0730,0x0318,0x0318,0x0318,0x3f18,0x63f8,\n  0xc300,0xc300,0xc300,0xc300,0x6398,0x3ef0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d5\n  0x18c0,0x18c0,0x0f80,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x0f80,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x7ff0,\n  0x6000,0x6000,0x6000,0x6000,0x3030,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d7\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x0030,0x0030,0x0030,0x0030,0x0030,0x7ff0,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x6060,0x0030,0x0030,0x0030,0x0030,0x7ff0,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d9\n  0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3060,0x6030,0x0030,0x0030,0x0030,0x0030,0x0030,0x7ff0,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04da\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x3fc0,0x6060,0x0030,0x0030,0x0030,0x0030,0x7ff0,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04db\n  0x1860,0x1860,0x1860,0x0000,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x3330,0x1b60,0x0fc0,0x1b60,0x3330,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04dc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1860,0x1860,0x1860,0x0000,0x6318,0x6318,0x6318,0x6318,0x3330,0x1b60,0x0fc0,\n  0x1b60,0x3330,0x6318,0x6318,0x6318,0x6318,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04dd\n  0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3060,0x6030,0x0030,0x0030,0x0030,0x0030,0x0060,0x0fc0,0x0060,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04de\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3060,0x6030,0x0030,0x0030,0x0060,0x0fc0,\n  0x0060,0x0030,0x0030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04df\n  0x0000,0x1fc0,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6070,0x60f0,0x61b0,0x6330,0x6630,0x6c30,0x7830,\n  0x7030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e3\n  0x18c0,0x18c0,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6070,0x60f0,0x61b0,0x6330,0x6630,0x6c30,0x7830,\n  0x7030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e5\n  0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e7\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x7ff0,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e9\n  0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x7ff0,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04eb\n  0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3060,0x6030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0ff0,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ec\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3060,0x6030,0x0030,0x0030,0x0030,0x0ff0,\n  0x0030,0x0030,0x0030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ed\n  0x0000,0x1fc0,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0060,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ee\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,0x0030,0x0030,0x0060,0x3fc0,0x0000, // u04ef\n  0x18c0,0x18c0,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0060,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,0x0030,0x0030,0x0060,0x3fc0,0x0000, // u04f1\n  0x0630,0x0c60,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0060,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0630,0x0c60,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,0x0030,0x0030,0x0060,0x3fc0,0x0000, // u04f3\n  0x18c0,0x18c0,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f5\n  0x18c0,0x18c0,0x18c0,0x0000,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x7f18,0x6198,0x60d8,0x60d8,0x60d8,0x60d8,\n  0x60d8,0x60d8,0x60d8,0x60d8,0x6198,0x7f18,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x6018,0x6018,0x6018,0x6018,0x7f18,0x6198,0x60d8,\n  0x60d8,0x60d8,0x60d8,0x60d8,0x6198,0x7f18,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f9\n  0x0000,0x0000,0x0000,0x0000,0x3018,0x3018,0x1818,0x1818,0x0c18,0x0c18,0x0618,0x0e30,0x1b60,0x33c0,0x6180,0x6180,\n  0x60c0,0x60c0,0x6060,0x6060,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d0\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0060,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d1\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x0300,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0380,\n  0x06c0,0x0cc0,0x1860,0x3060,0x6030,0xc030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d2\n  0x0000,0x0000,0x0000,0x0000,0x7ffc,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d3\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0060,0x0030,0x0030,0x0030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d4\n  0x0000,0x0000,0x0000,0x0000,0x3c00,0x0600,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d5\n  0x0000,0x0000,0x0000,0x0000,0x1ff0,0x0060,0x00c0,0x0180,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d6\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d7\n  0x0000,0x0000,0x0000,0x0000,0x63c0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d8\n  0x0000,0x0000,0x0000,0x0000,0x3c00,0x0600,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d9\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0060,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0000,0x0000, // u05da\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0060,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0060,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05db\n  0x0000,0x6000,0x6000,0x6000,0x7ff0,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0060,0x00c0,0x0180,0x0300,0x0600,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05dc\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05dd\n  0x0000,0x0000,0x0000,0x0000,0xe780,0xfce0,0x3830,0x3030,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,\n  0x3018,0x3018,0x3018,0x3018,0x3018,0x30f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05de\n  0x0000,0x0000,0x0000,0x0000,0x3f00,0x0180,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u05df\n  0x0000,0x0000,0x0000,0x0000,0x3f00,0x0180,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e0\n  0x0000,0x0000,0x0000,0x0000,0xffe0,0x3030,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,\n  0x3018,0x3018,0x3018,0x3018,0x1830,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e1\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x3030,0x3030,0x3030,0x1830,0x1830,0x1860,0x0c60,0x0c60,0x0cc0,\n  0x06c0,0x06c0,0x0380,0x0700,0x0e00,0x7800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e2\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,0x3030,0x1e30,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0000,0x0000, // u05e3\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,0x3030,0x1e30,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0060,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e4\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x3018,0x3018,0x1818,0x1830,0x0c60,0x0cc0,0x0780,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000, // u05e5\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x3018,0x3018,0x1818,0x1830,0x0c60,0x0cc0,0x0780,0x0300,0x0300,0x0180,\n  0x0180,0x00c0,0x00c0,0x0060,0x0060,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e6\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x0030,0x0030,0x0030,0x0030,0x6030,0x6030,0x6030,0x6060,0x60c0,0x6180,0x6300,\n  0x6600,0x6600,0x6600,0x6600,0x6600,0x6600,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000, // u05e7\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0060,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e8\n  0x0000,0x0000,0x0000,0x0000,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6618,0x7c18,0x6018,\n  0x6018,0x6018,0x6018,0x6018,0x6030,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e9\n  0x0000,0x0000,0x0000,0x0000,0xffe0,0x3030,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,\n  0x3018,0x3018,0x3018,0x3018,0x3018,0xe018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05ea\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x61c0,0x6060,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6060,0x6060,0x61c0,0x7f00,0x0000,0x0600,0x0600,0x0600,0x0000,0x0000, // u1e0c\n  0x0000,0x0000,0x0000,0x0000,0x0030,0x0030,0x0030,0x0030,0x0030,0x1ff0,0x3030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1e0d\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6060,0x60c0,0x6180,0x6300,0x6600,0x6c00,0x7800,0x7000,0x7000,0x7800,0x6c00,\n  0x6600,0x6300,0x6180,0x60c0,0x6060,0x6030,0x0000,0x0000,0x3fe0,0x0000,0x0000,0x0000, // u1e34\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3030,0x3060,0x30c0,0x3180,0x3300,0x3600,0x3c00,\n  0x3600,0x3300,0x3180,0x30c0,0x3060,0x3030,0x0000,0x0000,0x1fe0,0x0000,0x0000,0x0000, // u1e35\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1e36\n  0x0000,0x0000,0x0000,0x0000,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1e37\n  0x0300,0x0300,0x0300,0x0000,0x6018,0x6018,0x7038,0x7878,0x6cd8,0x6cd8,0x6798,0x6318,0x6318,0x6018,0x6018,0x6018,\n  0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e40\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0000,0x7fe0,0x6330,0x6318,0x6318,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e41\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x7038,0x7878,0x6cd8,0x6cd8,0x6798,0x6318,0x6318,0x6018,0x6018,0x6018,\n  0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1e42\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x6330,0x6318,0x6318,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1e43\n  0x0300,0x0300,0x0300,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x7030,0x7830,0x6c30,0x6630,0x6330,0x61b0,0x60f0,\n  0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e44\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e45\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x7030,0x7830,0x6c30,0x6630,0x6330,0x61b0,0x60f0,\n  0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1e46\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1e47\n  0x0000,0x0000,0x0000,0x0000,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1e6c\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,0x3fc0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x03e0,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u1e6d\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1eb8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x7ff0,\n  0x6000,0x6000,0x6000,0x6000,0x3030,0x1fe0,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1eb9\n  0x1c60,0x3760,0x31c0,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1ebc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1c60,0x3760,0x31c0,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x7ff0,\n  0x6000,0x6000,0x6000,0x6000,0x3030,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1ebd\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1eca\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1ecb\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1ecc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1ecd\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3060,0x1fc0,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1ee4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1ee5\n  0x1c60,0x3760,0x31c0,0x0000,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1ef8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1c60,0x3760,0x31c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x3030,0x1ff0,0x0030,0x0030,0x0030,0x0060,0x3fc0,0x0000, // u1ef9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2001\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2002\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2003\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2004\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2005\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2006\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2007\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2008\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2009\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2010\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2011\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2012\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2013\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff8,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2014\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff8,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2015\n  0x0000,0x0000,0x0000,0x0000,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2016\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x0000,0x0000,0x7ff0, // u2017\n  0x0000,0x0000,0x0300,0x0300,0x0600,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2018\n  0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2019\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u201a\n  0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201b\n  0x0000,0x0000,0x0c60,0x0c60,0x18c0,0x18c0,0x18c0,0x18c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201c\n  0x0000,0x0000,0x0c60,0x0c60,0x0c60,0x0c60,0x18c0,0x18c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x18c0,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000, // u201e\n  0x0000,0x0000,0x3180,0x3180,0x3180,0x3180,0x18c0,0x18c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201f\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x3ff0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2020\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x3ff0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x3ff0,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2021\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0780,0x0fc0,0x0fc0,0x0fc0,0x0fc0,\n  0x0780,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2022\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x6318,0x6318,0x6318,0x6318,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2026\n  0x0000,0x0000,0x0000,0x0000,0x38c0,0x6cc0,0x6d80,0x6d80,0x3b00,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x1800,0x1800,\n  0x3000,0x3770,0x6dd8,0x6dd8,0xcdd8,0xc770,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2030\n  0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0200,0x0200,0x0200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2032\n  0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x18c0,0x1080,0x1080,0x1080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2033\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,\n  0x0c00,0x0600,0x0300,0x0180,0x00c0,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x00c0,0x0060,\n  0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u203a\n  0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,\n  0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x18c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u203c\n  0x0000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u203e\n  0x0000,0x0000,0x0f80,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x0f80,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2070\n  0x0300,0x0300,0x0000,0x0000,0x0700,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0780,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2071\n  0x0000,0x0000,0x00c0,0x01c0,0x03c0,0x06c0,0x0cc0,0x18c0,0x1fc0,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2074\n  0x0000,0x0000,0x1fc0,0x1800,0x1800,0x1800,0x1f80,0x00c0,0x00c0,0x00c0,0x18c0,0x0f80,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2075\n  0x0000,0x0000,0x0780,0x0c00,0x1800,0x1800,0x1f80,0x18c0,0x18c0,0x18c0,0x18c0,0x0f80,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2076\n  0x0000,0x0000,0x1fc0,0x18c0,0x00c0,0x0180,0x0180,0x0300,0x0300,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2077\n  0x0000,0x0000,0x0f80,0x18c0,0x18c0,0x18c0,0x0f80,0x18c0,0x18c0,0x18c0,0x18c0,0x0f80,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2078\n  0x0000,0x0000,0x0f80,0x18c0,0x18c0,0x18c0,0x18c0,0x0fc0,0x00c0,0x00c0,0x0180,0x0f00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2079\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x1fe0,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1fe0,0x0000,0x0000,0x0000,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207c\n  0x0000,0x0000,0x0180,0x0300,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0300,0x0180,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207d\n  0x0000,0x0000,0x0600,0x0300,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0300,0x0600,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207e\n  0x0000,0x0000,0x0000,0x1fc0,0x1860,0x1860,0x1860,0x1860,0x1860,0x1860,0x1860,0x1860,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f80,0x18c0,\n  0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x0f80,0x0000,0x0000,0x0000,0x0000, // u2080\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0700,\n  0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000, // u2081\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f80,0x18c0,\n  0x18c0,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x1fc0,0x0000,0x0000,0x0000,0x0000, // u2082\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f80,0x18c0,\n  0x00c0,0x00c0,0x0780,0x00c0,0x00c0,0x00c0,0x18c0,0x0f80,0x0000,0x0000,0x0000,0x0000, // u2083\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x01c0,\n  0x03c0,0x06c0,0x0cc0,0x18c0,0x1fc0,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000, // u2084\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x1800,\n  0x1800,0x1800,0x1f80,0x00c0,0x00c0,0x00c0,0x18c0,0x0f80,0x0000,0x0000,0x0000,0x0000, // u2085\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0780,0x0c00,\n  0x1800,0x1800,0x1f80,0x18c0,0x18c0,0x18c0,0x18c0,0x0f80,0x0000,0x0000,0x0000,0x0000, // u2086\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x18c0,\n  0x00c0,0x0180,0x0180,0x0300,0x0300,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u2087\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f80,0x18c0,\n  0x18c0,0x18c0,0x0f80,0x18c0,0x18c0,0x18c0,0x18c0,0x0f80,0x0000,0x0000,0x0000,0x0000, // u2088\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f80,0x18c0,\n  0x18c0,0x18c0,0x18c0,0x0fc0,0x00c0,0x00c0,0x0180,0x0f00,0x0000,0x0000,0x0000,0x0000, // u2089\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0300,0x0300,0x0300,0x1fe0,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000, // u208a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u208b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x1fe0,0x0000,0x0000,0x0000,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u208c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0300,0x0180,0x0000,0x0000,0x0000,0x0000, // u208d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0300,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0300,0x0600,0x0000,0x0000,0x0000,0x0000, // u208e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,\n  0x0060,0x0060,0x0fe0,0x1860,0x1860,0x1860,0x1860,0x0fe0,0x0000,0x0000,0x0000,0x0000, // u2090\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,\n  0x1860,0x1860,0x1860,0x1fe0,0x1800,0x1800,0x1860,0x0fc0,0x0000,0x0000,0x0000,0x0000, // u2091\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,\n  0x1860,0x1860,0x1860,0x1860,0x1860,0x1860,0x1860,0x0fc0,0x0000,0x0000,0x0000,0x0000, // u2092\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1860,\n  0x1860,0x0cc0,0x0780,0x0300,0x0780,0x0cc0,0x1860,0x1860,0x0000,0x0000,0x0000,0x0000, // u2093\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,\n  0x1860,0x0060,0x0060,0x1fe0,0x1860,0x1860,0x1860,0x0fc0,0x0000,0x0000,0x0000,0x0000, // u2094\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x1fc0,\n  0x1860,0x1860,0x1860,0x1860,0x1860,0x1860,0x1860,0x1860,0x0000,0x0000,0x0000,0x0000, // u2095\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x1860,\n  0x18c0,0x1980,0x1b00,0x1e00,0x1b00,0x1980,0x18c0,0x1860,0x0000,0x0000,0x0000,0x0000, // u2096\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0780,0x0000,0x0000,0x0000,0x0000, // u2097\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fe0,\n  0x3330,0x3330,0x3330,0x3330,0x3330,0x3330,0x3330,0x3330,0x0000,0x0000,0x0000,0x0000, // u2098\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,\n  0x1860,0x1860,0x1860,0x1860,0x1860,0x1860,0x1860,0x1fc0,0x1800,0x1800,0x1800,0x0000, // u209a\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x6180,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x6180,0x7f60,0x6060,0x61f8,\n  0x6060,0x6060,0x6060,0x6060,0x6060,0x6038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u20a7\n  0x0000,0x0000,0x0000,0x0000,0xfe18,0xc318,0xc198,0xc198,0xc198,0xcd98,0xcd98,0xcd98,0xcd98,0xcd98,0xcd98,0xcd98,\n  0xcd98,0xcc18,0xcc18,0xcc18,0xcc30,0xcfe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u20aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x1860,0x3030,0x6000,0x6000,0x6000,0xff80,0x6000,0x6000,0x6000,0xff80,\n  0x6000,0x6000,0x6000,0x3030,0x1860,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u20ac\n  0x0000,0x0000,0x0000,0x0000,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0300,0x0370,0x03c0,0x0f00,0x3b70,0x03c0,0x0f00,\n  0x3b00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u20ae\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3c60,0x6c30,0x6c30,0x6c30,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,\n  0x6c00,0x6c30,0x6c30,0x6c30,0x3c60,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2102\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u210e\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0xff00,0x6000,0x6000,0x7fc0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u210f\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x7030,0x7830,0x6c30,0x7630,0x7b30,0x6db0,0x66f0,0x6370,0x61b0,\n  0x60f0,0x6070,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2115\n  0x0000,0x0000,0x0000,0x0000,0xc300,0xc338,0xc36c,0xc36c,0xe36c,0xe338,0xf300,0xf300,0xdb00,0xdb00,0xcf00,0xcf00,\n  0xc77c,0xc700,0xc300,0xc37c,0xc300,0xc300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2116\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3c60,0x6c30,0x6c30,0x6c30,0x6c30,0x6c30,0x6c30,0x6c30,0x6c30,0x6c30,0x6c30,\n  0x6c30,0x6c30,0x6c30,0x6db0,0x3de0,0x1fc0,0x0060,0x0030,0x0000,0x0000,0x0000,0x0000, // u211a\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6c60,0x6c30,0x6c30,0x6c30,0x6c30,0x6c30,0x6c30,0x6c60,0x6fc0,0x6f00,0x6d80,\n  0x6ec0,0x6f60,0x6db0,0x6cd8,0x6c68,0x7c38,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u211d\n  0x0000,0x0000,0x0000,0x0000,0xfd04,0x318c,0x31fc,0x31ac,0x318c,0x318c,0x318c,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2122\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x0030,0x0030,0x0070,0x00f0,0x01b0,0x0360,0x06c0,0x0d80,0x1b00,0x3600,0x6c00,\n  0x7800,0x7000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2124\n  0x0000,0x0000,0x0000,0x0000,0x1fe0,0x3030,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,\n  0x3030,0x1860,0x0cc0,0x0cc0,0x0cc0,0x7cf8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2126\n  0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x3060,0x3060,0x1830,0x1830,0x0c18,0x1c30,0x3660,0x66c0,0xc380,0xc300,\n  0xc180,0xc180,0xc0c0,0xc0c0,0x6060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2135\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0c00,0x1800,0x3000,0x6000,0xfff8,0xfff8,0x6000,\n  0x3000,0x1800,0x0c00,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2190\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0780,0x0fc0,0x1b60,0x3330,0x6318,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2191\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0180,0x00c0,0x0060,0x0030,0xfff8,0xfff8,0x0030,\n  0x0060,0x00c0,0x0180,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2192\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x6318,0x3330,0x1b60,0x0fc0,0x0780,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2193\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0480,0x0cc0,0x1860,0x3030,0x6018,0xfffc,0xfffc,0x6018,\n  0x3030,0x1860,0x0cc0,0x0480,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2194\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0780,0x0fc0,0x1b60,0x3330,0x6318,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x6318,0x3330,0x1b60,0x0fc0,0x0780,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2195\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0418,0x0c18,0x1818,0x3018,0x6018,0xfff8,0xfff8,0x6018,\n  0x3018,0x1818,0x0c18,0x0418,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc100,0xc180,0xc0c0,0xc060,0xc030,0xfff8,0xfff8,0xc030,\n  0xc060,0xc0c0,0xc180,0xc100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a6\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0780,0x0fc0,0x1b60,0x3330,0x6318,0x0300,0x0300,0x0300,0x0300,0x0300,0x6318,\n  0x3330,0x1b60,0x0fc0,0x0780,0x0300,0x7ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a8\n  0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0418,0x0c18,0x1818,0x3018,0x6018,0xfff8,\n  0xfff8,0x6000,0x3000,0x1800,0x0c00,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x0e00,0x1e20,0x3630,0x6618,0x6018,0x6018,0x6018,0x6018,\n  0x3030,0x1860,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x1800,0x3000,0x6000,0xfff8,0xfff8,0x0000,0x0000,0xfff8,\n  0xfff8,0x0030,0x0060,0x00c0,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x00c0,0x0060,0x0030,0xfff8,0xfff8,0x0000,0x0000,0xfff8,\n  0xfff8,0x6000,0x3000,0x1800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21cc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0c00,0x1800,0x3ff8,0x7ff8,0xe000,0xe000,0x7ff8,\n  0x3ff8,0x1800,0x0c00,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d0\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0780,0x0fc0,0x1ce0,0x3cf0,0x6cd8,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0180,0x00c0,0xffe0,0xfff0,0x0038,0x0038,0xfff0,\n  0xffe0,0x00c0,0x0180,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d2\n  0x0000,0x0000,0x0000,0x0000,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,\n  0x6cd8,0x3cf0,0x1ce0,0x0fc0,0x0780,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0480,0x0cc0,0x1860,0x3ff0,0x7ff8,0xe01c,0xe01c,0x7ff8,\n  0x3ff0,0x1860,0x0cc0,0x0480,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d4\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0780,0x0fc0,0x1ce0,0x3cf0,0x6cd8,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,\n  0x6cd8,0x3cf0,0x1ce0,0x0fc0,0x0780,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d5\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x3060,0x3060,0x3fe0,0x3060,0x18c0,0x18c0,0x18c0,0x18c0,\n  0x0d80,0x0d80,0x0d80,0x0700,0x0700,0x0700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2200\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x7ff0,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2203\n  0x0000,0x0000,0x0000,0x0030,0x0030,0x7ff0,0x0070,0x00f0,0x00f0,0x01b0,0x01b0,0x0330,0x0330,0x7ff0,0x0630,0x0630,\n  0x0c30,0x0c30,0x1830,0x1830,0x3030,0x7ff0,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000, // u2204\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0030,0x0060,0x1fc0,0x30e0,0x61b0,0x61b0,0x6330,0x6330,0x6630,0x6630,0x6c30,\n  0x6c30,0x3860,0x1fc0,0x3000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2205\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0780,0x0780,0x0780,0x0cc0,0x0cc0,0x0cc0,0x1860,0x1860,0x1860,\n  0x3030,0x3030,0x3030,0x6018,0x6018,0x7ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2206\n  0x0000,0x0000,0x0000,0x0000,0x7ff8,0x6018,0x6018,0x3030,0x3030,0x3030,0x1860,0x1860,0x1860,0x0cc0,0x0cc0,0x0cc0,\n  0x0780,0x0780,0x0780,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2207\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x07f0,0x1c00,0x3000,0x3000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x6000,0x6000,\n  0x6000,0x6000,0x3000,0x3000,0x1c00,0x07f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2208\n  0x0000,0x0000,0x0000,0x0018,0x0018,0x07f0,0x1c30,0x3060,0x3060,0x60c0,0x60c0,0x6180,0x6180,0x7ff0,0x6300,0x6300,\n  0x6600,0x6600,0x2c00,0x3c00,0x1800,0x1ff0,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000, // u2209\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1800,0x3000,0x6000,0x6000,0x6000,0x7ff0,0x6000,0x6000,\n  0x6000,0x3000,0x1800,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u220a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x01c0,0x0060,0x0060,0x0030,0x0030,0x0030,0x0030,0x7ff0,0x0030,0x0030,\n  0x0030,0x0030,0x0060,0x0060,0x01c0,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u220b\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x3f80,0x30e0,0x1830,0x1830,0x0c18,0x0c18,0x0618,0x0618,0x3ff8,0x0318,0x0318,\n  0x0198,0x0198,0x00d0,0x00f0,0x0060,0x3fe0,0x0030,0x0030,0x0000,0x0000,0x0000,0x0000, // u220c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x00c0,0x0060,0x0030,0x0030,0x0030,0x7ff0,0x0030,0x0030,\n  0x0030,0x0060,0x00c0,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u220d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2212\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff8,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2213\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2214\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0030,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,\n  0x1800,0x3000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2215\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x00c0,\n  0x0060,0x0030,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2216\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0f80,0x0f80,0x0f80,0x0700,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2219\n  0x0000,0x0000,0x0078,0x0078,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x6060,0x6060,0x6060,0x3060,\n  0x1860,0x0c60,0x0660,0x0360,0x01e0,0x00e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u221a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ce0,0x37b0,0x6318,0x6318,0x6318,0x6318,0x6318,\n  0x37b0,0x1ce0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u221e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u221f\n  0x0000,0x0000,0x0000,0x0000,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2225\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0780,0x0780,0x0cc0,0x0cc0,0x1860,\n  0x1860,0x1860,0x3030,0x3030,0x6018,0x6018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2227\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,0x1860,\n  0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2228\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f80,0x18c0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2229\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x3060,0x18c0,0x0f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u222a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c30,0x3630,0x6360,0x61c0,0x0000,0x1c30,0x3630,\n  0x6360,0x61c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2248\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0030,0x7ff8,0x00c0,0x0180,0x0300,0x0600,0x0c00,\n  0x7ff8,0x3000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2260\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2261\n  0x0000,0x0000,0x0000,0x0000,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x1800,0x0c00,0x0600,0x0300,\n  0x0180,0x00c0,0x0060,0x0000,0x0000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2264\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x00c0,0x0060,0x00c0,0x0180,0x0300,0x0600,\n  0x0c00,0x1800,0x3000,0x0000,0x0000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2265\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x018c,0x0318,0x0630,0x0c60,0x18c0,0x3180,0x6300,0xc600,0xc600,0x6300,0x3180,\n  0x18c0,0x0c60,0x0630,0x0318,0x018c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u226a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0x6300,0x3180,0x18c0,0x0c60,0x0630,0x0318,0x018c,0x018c,0x0318,0x0630,\n  0x0c60,0x18c0,0x3180,0x6300,0xc600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u226b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff8,0x1800,0x3000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x3000,0x1800,0x0ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2282\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0060,0x0030,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,\n  0x0030,0x0060,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2283\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff8,0x1800,0x3000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x3000,\n  0x1800,0x0ff8,0x0000,0x0000,0x7ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2286\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x0060,0x0030,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0030,\n  0x0060,0x7fc0,0x0000,0x0000,0x7ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2287\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x7ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u22a5\n  0x0000,0x0000,0x0000,0x0000,0x0f80,0x18c0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u22c2\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x3060,0x18c0,0x0f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u22c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0030,0x0060,0x1fc0,0x30e0,0x61b0,0x61b0,0x6330,0x6330,0x6630,0x6630,0x6c30,\n  0x6c30,0x3860,0x1fc0,0x3000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2300\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0780,0x0cc0,0x1860,0x3030,0x6018,0x6018,0x6018,\n  0x6018,0x6018,0x6018,0x6018,0x6018,0x7ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2302\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2308\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2309\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u230a\n  0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u230b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2310\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2319\n  0x0000,0x0000,0x0000,0x0000,0x01f0,0x0318,0x0318,0x0318,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2320\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x6300,0x6300,0x6300,0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2321\n  0x0030,0x0060,0x00c0,0x0180,0x0300,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x0c00,0x1800,0x1800,0x1800,0x1800,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000, // u239b\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000, // u239c\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x1800,0x1800,0x1800,\n  0x1800,0x0c00,0x0c00,0x0c00,0x0600,0x0600,0x0300,0x0300,0x0180,0x00c0,0x0060,0x0030, // u239d\n  0x3000,0x1800,0x0c00,0x0600,0x0300,0x0300,0x0180,0x0180,0x00c0,0x00c0,0x00c0,0x0060,0x0060,0x0060,0x0060,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030, // u239e\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030, // u239f\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0060,0x0060,0x0060,\n  0x0060,0x00c0,0x00c0,0x00c0,0x0180,0x0180,0x0300,0x0300,0x0600,0x0c00,0x1800,0x3000, // u23a0\n  0x3ff0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000, // u23a1\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000, // u23a2\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ff0, // u23a3\n  0x3ff0,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030, // u23a4\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030, // u23a5\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x3ff0, // u23a6\n  0x00f8,0x0380,0x0600,0x0600,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u23a7\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1800,0xf000,0xf000,0x1800,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u23a8\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0600,0x0600,0x0380,0x00f8, // u23a9\n  0xf800,0x0e00,0x0300,0x0300,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u23ab\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x00c0,0x0078,0x0078,0x00c0,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u23ac\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0300,0x0300,0x0e00,0xf800, // u23ad\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u23ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23af\n  0xfffc,0xfffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0xfffc,0xfffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc, // u23bd\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u23d0\n  0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x6300,0x7f00,0x6300,0x6300,0x6300,0x6300,0x0000,0x0000,0x07f8,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2409\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x0000,0x0000,0x03f8,0x0300,\n  0x0300,0x03e0,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u240a\n  0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x6300,0x6300,0x6300,0x3600,0x1c00,0x0800,0x0000,0x0000,0x07f8,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u240b\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x6000,0x6000,0x7c00,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x03f8,0x0300,\n  0x0300,0x03e0,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u240c\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x6300,0x6000,0x6000,0x6000,0x6000,0x6300,0x3e00,0x0000,0x0000,0x03f0,0x0318,\n  0x0318,0x03f0,0x03c0,0x0360,0x0330,0x0318,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u240d\n  0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x7300,0x7b00,0x6f00,0x6700,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x03f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2424\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2500\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0xfffc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2501\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2502\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u2503\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xedd8,0xedd8,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2508\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xedd8,0xedd8,0xedd8,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2509\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000, // u250a\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0000,0x0000,0x0700,0x0700,0x0700,0x0700,0x0700,0x0000,0x0000,0x0700,0x0700,\n  0x0700,0x0700,0x0700,0x0000,0x0000,0x0700,0x0700,0x0700,0x0700,0x0700,0x0000,0x0000, // u250b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03fc,0x03fc,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u250c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03fc,0x03fc,0x03fc,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u250d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07fc,0x07fc,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u250e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07fc,0x07fc,0x07fc,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u250f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2510\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2511\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u2512\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u2513\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x03fc,0x03fc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2514\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x03fc,0x03fc,0x03fc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2515\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x07fc,0x07fc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2516\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x07fc,0x07fc,0x07fc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2517\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xff00,0xff00,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2518\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xff00,0xff00,0xff00,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2519\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0xff00,0xff00,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u251a\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0xff00,0xff00,0xff00,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u251b\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x03fc,0x03fc,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u251c\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x03fc,0x03fc,0x03fc,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u251d\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x07fc,0x07fc,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u251e\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x07fc,0x07fc,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u251f\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x07fc,0x07fc,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u2520\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x07fc,0x07fc,0x07fc,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2521\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x07fc,0x07fc,0x07fc,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u2522\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x07fc,0x07fc,0x07fc,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u2523\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xff00,0xff00,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2524\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xff00,0xff00,0xff00,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2525\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0xff00,0xff00,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2526\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xff00,0xff00,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u2527\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0xff00,0xff00,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u2528\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0xff00,0xff00,0xff00,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2529\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xff00,0xff00,0xff00,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u252a\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0xff00,0xff00,0xff00,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u252b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u252c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xfffc,0xfffc,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u252d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03fc,0xfffc,0xfffc,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u252e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0xfffc,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u252f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u2530\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xfffc,0xfffc,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u2531\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07fc,0xfffc,0xfffc,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u2532\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0xfffc,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u2533\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xfffc,0xfffc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2534\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xff00,0xfffc,0xfffc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2535\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x03fc,0xfffc,0xfffc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2536\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xfffc,0xfffc,0xfffc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2537\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0xfffc,0xfffc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2538\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0xff00,0xfffc,0xfffc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2539\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x07fc,0xfffc,0xfffc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u253a\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0xfffc,0xfffc,0xfffc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u253b\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xfffc,0xfffc,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u253c\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xff00,0xfffc,0xfffc,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u253d\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x03fc,0xfffc,0xfffc,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u253e\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xfffc,0xfffc,0xfffc,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u253f\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0xfffc,0xfffc,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2540\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xfffc,0xfffc,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u2541\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0xfffc,0xfffc,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u2542\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0xff00,0xfffc,0xfffc,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2543\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x07fc,0xfffc,0xfffc,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2544\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xff00,0xfffc,0xfffc,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u2545\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x03fc,0xfffc,0xfffc,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u2546\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0xfffc,0xfffc,0xfffc,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2547\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xfffc,0xfffc,0xfffc,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u2548\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0xff00,0xfffc,0xfffc,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u2549\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x07fc,0xfffc,0xfffc,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u254a\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0xfffc,0xfffc,0xfffc,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u254b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0x0000,0x0000,0xfffc,\n  0xfffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2550\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0, // u2551\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03fc,0x03fc,0x0300,0x0300,0x03fc,\n  0x03fc,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2552\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ffc,0x0ffc,0x0cc0,\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0, // u2553\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ffc,0x0ffc,0x0c00,0x0c00,0x0cfc,\n  0x0cfc,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0, // u2554\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x0300,0x0300,0xff00,\n  0xff00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2555\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x0cc0,\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0, // u2556\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x00c0,0x00c0,0xfcc0,\n  0xfcc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0, // u2557\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x03fc,0x03fc,0x0300,0x0300,0x03fc,\n  0x03fc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2558\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0ffc,0x0ffc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2559\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cfc,0x0cfc,0x0c00,0x0c00,0x0ffc,\n  0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255a\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xff00,0xff00,0x0300,0x0300,0xff00,\n  0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255b\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0xffc0,0xffc0,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255c\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0xfcc0,0xfcc0,0x00c0,0x00c0,0xffc0,\n  0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255d\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x03fc,0x03fc,0x0300,0x0300,0x03fc,\n  0x03fc,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u255e\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cfc,0x0cfc,0x0cc0,\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0, // u255f\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cfc,0x0cfc,0x0c00,0x0c00,0x0cfc,\n  0x0cfc,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0, // u2560\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xff00,0xff00,0x0300,0x0300,0xff00,\n  0xff00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2561\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0xfcc0,0xfcc0,0x0cc0,\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0, // u2562\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0xfcc0,0xfcc0,0x00c0,0x00c0,0xfcc0,\n  0xfcc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0, // u2563\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0x0000,0x0000,0xfffc,\n  0xfffc,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2564\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0x0cc0,\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0, // u2565\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0x0000,0x0000,0xfcfc,\n  0xfcfc,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0, // u2566\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xfffc,0xfffc,0x0000,0x0000,0xfffc,\n  0xfffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2567\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0xfffc,0xfffc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2568\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0xfcfc,0xfcfc,0x0000,0x0000,0xfffc,\n  0xfffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2569\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xfffc,0xfffc,0x0300,0x0300,0xfffc,\n  0xfffc,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u256a\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0xfffc,0xfffc,0x0cc0,\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0, // u256b\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0xfcfc,0xfcfc,0x0000,0x0000,0xfcfc,\n  0xfcfc,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0, // u256c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x001c,0x007c,0x00e0,\n  0x01c0,0x0180,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u256d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xe000,0xf800,0x1c00,\n  0x0e00,0x0600,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u256e\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0600,0x0e00,0x1c00,0xf800,0xe000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u256f\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0180,0x01c0,0x00e0,0x007c,0x001c,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2570\n  0x0004,0x0004,0x000c,0x0008,0x0018,0x0010,0x0030,0x0020,0x0060,0x0040,0x00c0,0x0080,0x0180,0x0100,0x0300,0x0200,\n  0x0600,0x0400,0x0c00,0x0800,0x1800,0x1000,0x3000,0x2000,0x6000,0x4000,0xc000,0x8000, // u2571\n  0x8000,0xc000,0x4000,0x6000,0x2000,0x3000,0x1000,0x1800,0x0800,0x0c00,0x0400,0x0600,0x0200,0x0300,0x0100,0x0180,\n  0x0080,0x00c0,0x0040,0x0060,0x0020,0x0030,0x0010,0x0018,0x0008,0x000c,0x0004,0x0004, // u2572\n  0x8004,0xc004,0x400c,0x6008,0x2018,0x3010,0x1030,0x1820,0x0860,0x0c40,0x04c0,0x0680,0x0380,0x0300,0x0300,0x0380,\n  0x0680,0x04c0,0x0c40,0x0860,0x1820,0x1030,0x3010,0x2018,0x6008,0x400c,0xc004,0x8004, // u2573\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2574\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2575\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03fc,0x03fc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2576\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2577\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2578\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2579\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03fc,0x03fc,0x03fc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0700,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u257b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03fc,0xfffc,0xfffc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257c\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0700,0x0700,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u257d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xfffc,0xfffc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257e\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u257f\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2580\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0xfffc, // u2581\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc, // u2582\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc, // u2583\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc, // u2584\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc, // u2585\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc, // u2586\n  0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc, // u2587\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc, // u2588\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0, // u2589\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0, // u258a\n  0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,\n  0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80, // u258b\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00, // u258c\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800, // u258d\n  0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,\n  0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000, // u258e\n  0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,\n  0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000, // u258f\n  0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,\n  0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc, // u2590\n  0xaaa8,0x0000,0xaaa8,0x0000,0xaaa8,0x0000,0xaaa8,0x0000,0xaaa8,0x0000,0xaaa8,0x0000,0xaaa8,0x0000,0xaaa8,0x0000,\n  0xaaa8,0x0000,0xaaa8,0x0000,0xaaa8,0x0000,0xaaa8,0x0000,0xaaa8,0x0000,0xaaa8,0x0000, // u2591\n  0xaaa8,0x5554,0xaaa8,0x5554,0xaaa8,0x5554,0xaaa8,0x5554,0xaaa8,0x5554,0xaaa8,0x5554,0xaaa8,0x5554,0xaaa8,0x5554,\n  0xaaa8,0x5554,0xaaa8,0x5554,0xaaa8,0x5554,0xaaa8,0x5554,0xaaa8,0x5554,0xaaa8,0x5554, // u2592\n  0xfffc,0xaaa8,0xfffc,0xaaa8,0xfffc,0xaaa8,0xfffc,0xaaa8,0xfffc,0xaaa8,0xfffc,0xaaa8,0xfffc,0xaaa8,0xfffc,0xaaa8,\n  0xfffc,0xaaa8,0xfffc,0xaaa8,0xfffc,0xaaa8,0xfffc,0xaaa8,0xfffc,0xaaa8,0xfffc,0xaaa8, // u2593\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xfe00,\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00, // u2596\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01fc,0x01fc,\n  0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc, // u2597\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2598\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfffc,0xfffc,\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc, // u2599\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0x01fc,0x01fc,\n  0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc, // u259a\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfe00,0xfe00,\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00, // u259b\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0x01fc,0x01fc,\n  0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc, // u259c\n  0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u259d\n  0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0xfe00,0xfe00,\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00, // u259e\n  0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0xfffc,0xfffc,\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc, // u259f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fe0,0x3fe0,0x3fe0,0x3fe0,0x3fe0,0x3fe0,0x3fe0,0x3fe0,\n  0x3fe0,0x3fe0,0x3fe0,0x3fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff8,\n  0x7ff8,0x7ff8,0x7ff8,0x7ff8,0x7ff8,0x7ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ac\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x7ff0,0x7ff0,0x7ff0,0x7ff0,0x7ff0,0x7ff0,0x7ff0,0x7ff0,0x7ff0,0x7ff0,\n  0x7ff0,0x7ff0,0x7ff0,0x7ff0,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0780,0x0780,0x0fc0,0x0fc0,0x1fe0,0x1fe0,0x3ff0,\n  0x3ff0,0x7ff8,0x7ff8,0xfffc,0xfffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xffc0,0xfff0,0xfffc,0xfffc,0xfff0,\n  0xffc0,0xff00,0xfc00,0xf000,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xffc0,0xfff0,0xfffc,0xfffc,0xfff0,\n  0xffc0,0xff00,0xfc00,0xf000,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0x7ff8,0x7ff8,0x3ff0,0x3ff0,0x1fe0,0x1fe0,0x0fc0,\n  0x0fc0,0x0780,0x0780,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000c,0x003c,0x00fc,0x03fc,0x0ffc,0x3ffc,0xfffc,0xfffc,0x3ffc,\n  0x0ffc,0x03fc,0x00fc,0x003c,0x000c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000c,0x003c,0x00fc,0x03fc,0x0ffc,0x3ffc,0xfffc,0xfffc,0x3ffc,\n  0x0ffc,0x03fc,0x00fc,0x003c,0x000c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0200,0x0700,0x0f80,0x1fc0,0x3fe0,0x7ff0,0xfff8,0xfff8,0x7ff0,\n  0x3fe0,0x1fc0,0x0f80,0x0700,0x0200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0200,0x0700,0x0d80,0x18c0,0x3060,0x6030,0xc018,0xc018,0x6030,\n  0x3060,0x18c0,0x0d80,0x0700,0x0200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ca\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0780,0x0cc0,0x0840,0x0840,0x0cc0,\n  0x0780,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0780,0x0fc0,0x0fc0,0x0fc0,0x0fc0,\n  0x0780,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25cf\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xf87c,0xf03c,0xf03c,0xf03c,0xf03c,\n  0xf87c,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc, // u25d8\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xf87c,0xf33c,0xf7bc,0xf7bc,0xf33c,\n  0xf87c,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc, // u25d9\n  0x0000,0x0000,0x0000,0x0000,0x3fe0,0x6030,0xc018,0xc018,0xc018,0xddd8,0xddd8,0xc018,0xc018,0xc018,0xc018,0xdfd8,\n  0xcf98,0xc018,0xc018,0xc018,0x6030,0x3fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u263a\n  0x0000,0x0000,0x0000,0x0000,0x3fe0,0x7ff0,0xfff8,0xfff8,0xfff8,0xc718,0xc718,0xfff8,0xfff8,0xfff8,0xfff8,0xc018,\n  0xe038,0xfff8,0xfff8,0xfff8,0x7ff0,0x3fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u263b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x6318,0x3330,0x1b60,0x0fc0,0x0780,0x7cf8,0x0780,0x0fc0,\n  0x1b60,0x3330,0x6318,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u263c\n  0x0000,0x0000,0x0000,0x0000,0x1fe0,0x3030,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x3030,0x1fe0,0x0300,0x0300,\n  0x0300,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2640\n  0x0000,0x0000,0x0000,0x0000,0x03f8,0x0038,0x0078,0x00d8,0x0198,0x0318,0x0618,0x3f80,0x60c0,0xc060,0xc060,0xc060,\n  0xc060,0xc060,0xc060,0xc060,0x60c0,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2642\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0780,0x0fc0,0x1fe0,0x3ff0,0x3ff0,0x7ff8,0x7ff8,0x7ff8,0x7ff8,0x7ff8,\n  0x7b78,0x3b70,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2660\n  0x0000,0x0000,0x0000,0x0000,0x0780,0x0fc0,0x0fc0,0x0fc0,0x0fc0,0x0780,0x0300,0x3b70,0x7ff8,0x7ff8,0x7ff8,0x7ff8,\n  0x7ff8,0x3b70,0x0300,0x0300,0x0300,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2663\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x78f0,0xfdf8,0xfdf8,0xfff8,0xfff8,0xfff8,0xfff8,0x7ff0,0x7ff0,\n  0x3fe0,0x1fc0,0x0f80,0x0700,0x0200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2665\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0200,0x0700,0x0f80,0x1fc0,0x3fe0,0x7ff0,0xfff8,0xfff8,0x7ff0,\n  0x3fe0,0x1fc0,0x0f80,0x0700,0x0200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2666\n  0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3030,0x3030,0x3030,0x3030,0x3ff0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0xf000,0xe000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u266a\n  0x0000,0x0000,0x0000,0x0000,0x7ff8,0x6018,0x6018,0x6018,0x6018,0x7ff8,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,\n  0x6018,0x6018,0x6018,0x6078,0xe070,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u266b\n  0x0000,0x0000,0x0000,0x0000,0x000c,0x000c,0x0018,0x0018,0x0030,0x0030,0x0060,0x0060,0xc0c0,0xc0c0,0x6180,0x6180,\n  0x3300,0x3300,0x1e00,0x1e00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2713\n  0x0000,0x0000,0x0000,0x0000,0x001c,0x001c,0x0038,0x0038,0x0070,0x0070,0x00e0,0x00e0,0xc1c0,0xc1c0,0xe380,0xe380,\n  0x7700,0x7700,0x3e00,0x3e00,0x1c00,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2714\n  0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x00c0,0x60c0,0x3180,0x1980,0x0f00,0x0700,0x0700,0x0780,0x0cc0,0x0c60,\n  0x1830,0x1800,0x3000,0x3000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2717\n  0x0000,0x0000,0x0000,0x0000,0x00e0,0x00e0,0xe1c0,0x71c0,0x3b80,0x1f80,0x0f00,0x0700,0x0f80,0x0fc0,0x1ce0,0x1c70,\n  0x3830,0x3800,0x7000,0x7000,0xe000,0xe000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2718\n  0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x0180,0x0180,0x0300,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x0600,0x0600,\n  0x0300,0x0300,0x0180,0x0180,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u27e8\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0600,0x0600,0x0300,0x0300,0x0180,0x0180,0x00c0,0x00c0,0x0180,0x0180,\n  0x0300,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u27e9\n  0x0000,0x0000,0x0000,0x0000,0x0630,0x0630,0x0c60,0x0c60,0x18c0,0x18c0,0x3180,0x3180,0x6300,0x6300,0x3180,0x3180,\n  0x18c0,0x18c0,0x0c60,0x0c60,0x0630,0x0630,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u27ea\n  0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x3180,0x3180,0x18c0,0x18c0,0x0c60,0x0c60,0x0630,0x0630,0x0c60,0x0c60,\n  0x18c0,0x18c0,0x3180,0x3180,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u27eb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2800\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2801\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2802\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2803\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2804\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2805\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2806\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2807\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2808\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2809\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280a\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280b\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280c\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280d\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280e\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2810\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2811\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2812\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2813\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2814\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2815\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2816\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2817\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2818\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2819\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281a\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281b\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281c\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281d\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281e\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2820\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2821\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2822\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2823\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2824\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2825\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2826\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2827\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2828\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2829\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282a\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282b\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282c\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282d\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282e\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2830\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2831\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2832\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2833\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2834\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2835\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2836\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2837\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2838\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2839\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283a\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283b\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283c\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283d\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283e\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2840\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2841\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2842\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2843\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2844\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2845\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2846\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2847\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2848\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2849\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u284a\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u284b\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u284c\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u284d\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u284e\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u284f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2850\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2851\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2852\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2853\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2854\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2855\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2856\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2857\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2858\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2859\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u285a\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u285b\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u285c\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u285d\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u285e\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u285f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2860\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2861\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2862\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2863\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2864\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2865\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2866\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2867\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2868\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2869\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u286a\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u286b\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u286c\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u286d\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u286e\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u286f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2870\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2871\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2872\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2873\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2874\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2875\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2876\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2877\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2878\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2879\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u287a\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u287b\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u287c\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u287d\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u287e\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u287f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2880\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2881\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2882\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2883\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2884\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2885\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2886\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2887\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2888\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2889\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u288a\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u288b\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u288c\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u288d\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u288e\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u288f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2890\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2891\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2892\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2893\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2894\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2895\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2896\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2897\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2898\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2899\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u289a\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u289b\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u289c\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u289d\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u289e\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u289f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28a0\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28a2\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28a4\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28a5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28a6\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28a7\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28a8\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28a9\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28aa\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28ab\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28ac\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28ad\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28ae\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28af\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28b0\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28b1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28b2\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28b4\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28b6\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28b7\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28b8\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28b9\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28ba\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28bb\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28bc\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28bd\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28be\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28c0\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28c2\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28c4\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28c6\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28c7\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28c8\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28c9\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28ca\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28cb\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28cc\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28cd\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28ce\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28cf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28d0\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28d2\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28d4\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28d6\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28d7\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28d8\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28d9\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28da\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28db\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28dc\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28dd\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28de\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28df\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28e0\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28e1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28e2\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28e3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28e4\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28e6\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28e7\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28e8\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28e9\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28ea\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28eb\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28ec\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28ed\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28ee\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28ef\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28f0\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28f2\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28f3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28f4\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28f6\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28f7\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28f8\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28f9\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28fa\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28fb\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28fc\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28fd\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28fe\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28ff\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2e2c\n  0xc000,0xc000,0xc000,0xc180,0xc3c0,0xc7e0,0xcdb0,0xd998,0xc180,0xc180,0xc180,0xc180,0xc180,0xc300,0x8600,0x0c00,\n  0x1800,0x3000,0x6000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000, // ue0a0\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,0x0000,0x0618,\n  0x0618,0x0718,0x0798,0x06d8,0x0678,0x0638,0x0618,0x0618,0x0618,0x0000,0x0000,0x0000, // ue0a1\n  0x0000,0x0000,0x0000,0x0f80,0x18c0,0x3060,0x3060,0x3060,0x3060,0x3060,0x3060,0x3060,0x7ff0,0xfff8,0xfff8,0xfff8,\n  0xf8f8,0xf078,0xf078,0xf078,0xf8f8,0xfff8,0xfff8,0xfff8,0xfff8,0x0000,0x0000,0x0000, // ue0a2\n  0x8000,0xc000,0xe000,0xf000,0xf800,0xfc00,0xfe00,0xff00,0xff80,0xffc0,0xffe0,0xfff0,0xfff8,0xfffc,0xfffc,0xfff8,\n  0xfff0,0xffe0,0xffc0,0xff80,0xff00,0xfe00,0xfc00,0xf800,0xf000,0xe000,0xc000,0x8000, // ue0b0\n  0x8000,0xc000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x00c0,0x0060,0x0030,0x0018,0x000c,0x000c,0x0018,\n  0x0030,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0x8000, // ue0b1\n  0x0004,0x000c,0x001c,0x003c,0x007c,0x00fc,0x01fc,0x03fc,0x07fc,0x0ffc,0x1ffc,0x3ffc,0x7ffc,0xfffc,0xfffc,0x7ffc,\n  0x3ffc,0x1ffc,0x0ffc,0x07fc,0x03fc,0x01fc,0x00fc,0x007c,0x003c,0x001c,0x000c,0x0004, // ue0b2\n  0x0004,0x000c,0x0018,0x0030,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0xc000,0x6000,\n  0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x00c0,0x0060,0x0030,0x0018,0x000c,0x0004, // ue0b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01e0,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x3060,0x3060,0x3060,0x18c0,0x0f80,0x0000, // uf6be\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 // ufffd\n  };\n  // codepoints array\n  constexpr std::array<uint16_t, CHARCOUNT> fixedfont_codepoints = {\n  0x0000,0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,\n  0x002f,0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,\n  0x003f,0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,\n  0x004f,0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,\n  0x005f,0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,\n  0x006f,0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,\n  0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af,\n  0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf,\n  0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf,\n  0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df,\n  0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef,\n  0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff,\n  0x0100,0x0101,0x0102,0x0103,0x0104,0x0105,0x0106,0x0107,0x0108,0x0109,0x010a,0x010b,0x010c,0x010d,0x010e,0x010f,\n  0x0110,0x0111,0x0112,0x0113,0x0114,0x0115,0x0116,0x0117,0x0118,0x0119,0x011a,0x011b,0x011c,0x011d,0x011e,0x011f,\n  0x0120,0x0121,0x0122,0x0123,0x0124,0x0125,0x0126,0x0127,0x0128,0x0129,0x012a,0x012b,0x012c,0x012d,0x012e,0x012f,\n  0x0130,0x0131,0x0132,0x0133,0x0134,0x0135,0x0136,0x0137,0x0138,0x0139,0x013a,0x013b,0x013c,0x013d,0x013e,0x013f,\n  0x0140,0x0141,0x0142,0x0143,0x0144,0x0145,0x0146,0x0147,0x0148,0x0149,0x014a,0x014b,0x014c,0x014d,0x014e,0x014f,\n  0x0150,0x0151,0x0152,0x0153,0x0154,0x0155,0x0156,0x0157,0x0158,0x0159,0x015a,0x015b,0x015c,0x015d,0x015e,0x015f,\n  0x0160,0x0161,0x0162,0x0163,0x0164,0x0165,0x0166,0x0167,0x0168,0x0169,0x016a,0x016b,0x016c,0x016d,0x016e,0x016f,\n  0x0170,0x0171,0x0172,0x0173,0x0174,0x0175,0x0176,0x0177,0x0178,0x0179,0x017a,0x017b,0x017c,0x017d,0x017e,0x017f,\n  0x0186,0x018e,0x018f,0x0190,0x0192,0x019d,0x019e,0x01b5,0x01b6,0x01b7,0x01cd,0x01ce,0x01cf,0x01d0,0x01d1,0x01d2,\n  0x01d3,0x01d4,0x01e2,0x01e3,0x01e4,0x01e5,0x01e6,0x01e7,0x01e8,0x01e9,0x01ea,0x01eb,0x01ec,0x01ed,0x01ee,0x01ef,\n  0x01f0,0x01f4,0x01f5,0x01fc,0x01fd,0x01fe,0x01ff,0x0218,0x0219,0x021a,0x021b,0x0232,0x0233,0x0237,0x0254,0x0258,\n  0x0259,0x025b,0x0272,0x0292,0x02bb,0x02bc,0x02bd,0x02c6,0x02c7,0x02d8,0x02d9,0x02db,0x02dc,0x02dd,0x0300,0x0301,\n  0x0302,0x0303,0x0304,0x0305,0x0306,0x0307,0x0308,0x030a,0x030b,0x030c,0x0329,0x0384,0x0385,0x0386,0x0387,0x0388,\n  0x0389,0x038a,0x038c,0x038e,0x038f,0x0390,0x0391,0x0392,0x0393,0x0394,0x0395,0x0396,0x0397,0x0398,0x0399,0x039a,\n  0x039b,0x039c,0x039d,0x039e,0x039f,0x03a0,0x03a1,0x03a3,0x03a4,0x03a5,0x03a6,0x03a7,0x03a8,0x03a9,0x03aa,0x03ab,\n  0x03ac,0x03ad,0x03ae,0x03af,0x03b0,0x03b1,0x03b2,0x03b3,0x03b4,0x03b5,0x03b6,0x03b7,0x03b8,0x03b9,0x03ba,0x03bb,\n  0x03bc,0x03bd,0x03be,0x03bf,0x03c0,0x03c1,0x03c2,0x03c3,0x03c4,0x03c5,0x03c6,0x03c7,0x03c8,0x03c9,0x03ca,0x03cb,\n  0x03cc,0x03cd,0x03ce,0x03d1,0x03d5,0x03f0,0x03f1,0x03f2,0x03f3,0x03f4,0x03f5,0x03f6,0x0400,0x0401,0x0402,0x0403,\n  0x0404,0x0405,0x0406,0x0407,0x0408,0x0409,0x040a,0x040b,0x040c,0x040d,0x040e,0x040f,0x0410,0x0411,0x0412,0x0413,\n  0x0414,0x0415,0x0416,0x0417,0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e,0x041f,0x0420,0x0421,0x0422,0x0423,\n  0x0424,0x0425,0x0426,0x0427,0x0428,0x0429,0x042a,0x042b,0x042c,0x042d,0x042e,0x042f,0x0430,0x0431,0x0432,0x0433,\n  0x0434,0x0435,0x0436,0x0437,0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e,0x043f,0x0440,0x0441,0x0442,0x0443,\n  0x0444,0x0445,0x0446,0x0447,0x0448,0x0449,0x044a,0x044b,0x044c,0x044d,0x044e,0x044f,0x0450,0x0451,0x0452,0x0453,\n  0x0454,0x0455,0x0456,0x0457,0x0458,0x0459,0x045a,0x045b,0x045c,0x045d,0x045e,0x045f,0x0462,0x0463,0x046a,0x046b,\n  0x0490,0x0491,0x0492,0x0493,0x0494,0x0495,0x0496,0x0497,0x0498,0x0499,0x049a,0x049b,0x049c,0x049d,0x04a0,0x04a1,\n  0x04a2,0x04a3,0x04a4,0x04a5,0x04aa,0x04ab,0x04ae,0x04af,0x04b0,0x04b1,0x04b2,0x04b3,0x04b6,0x04b7,0x04b8,0x04b9,\n  0x04ba,0x04bb,0x04c0,0x04c1,0x04c2,0x04cf,0x04d0,0x04d1,0x04d2,0x04d3,0x04d4,0x04d5,0x04d6,0x04d7,0x04d8,0x04d9,\n  0x04da,0x04db,0x04dc,0x04dd,0x04de,0x04df,0x04e2,0x04e3,0x04e4,0x04e5,0x04e6,0x04e7,0x04e8,0x04e9,0x04ea,0x04eb,\n  0x04ec,0x04ed,0x04ee,0x04ef,0x04f0,0x04f1,0x04f2,0x04f3,0x04f4,0x04f5,0x04f8,0x04f9,0x05d0,0x05d1,0x05d2,0x05d3,\n  0x05d4,0x05d5,0x05d6,0x05d7,0x05d8,0x05d9,0x05da,0x05db,0x05dc,0x05dd,0x05de,0x05df,0x05e0,0x05e1,0x05e2,0x05e3,\n  0x05e4,0x05e5,0x05e6,0x05e7,0x05e8,0x05e9,0x05ea,0x1e0c,0x1e0d,0x1e34,0x1e35,0x1e36,0x1e37,0x1e40,0x1e41,0x1e42,\n  0x1e43,0x1e44,0x1e45,0x1e46,0x1e47,0x1e6c,0x1e6d,0x1eb8,0x1eb9,0x1ebc,0x1ebd,0x1eca,0x1ecb,0x1ecc,0x1ecd,0x1ee4,\n  0x1ee5,0x1ef8,0x1ef9,0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007,0x2008,0x2009,0x200a,0x200b,0x200c,\n  0x200d,0x200e,0x200f,0x2010,0x2011,0x2012,0x2013,0x2014,0x2015,0x2016,0x2017,0x2018,0x2019,0x201a,0x201b,0x201c,\n  0x201d,0x201e,0x201f,0x2020,0x2021,0x2022,0x2026,0x2030,0x2032,0x2033,0x2039,0x203a,0x203c,0x203e,0x2070,0x2071,\n  0x2074,0x2075,0x2076,0x2077,0x2078,0x2079,0x207a,0x207b,0x207c,0x207d,0x207e,0x207f,0x2080,0x2081,0x2082,0x2083,\n  0x2084,0x2085,0x2086,0x2087,0x2088,0x2089,0x208a,0x208b,0x208c,0x208d,0x208e,0x2090,0x2091,0x2092,0x2093,0x2094,\n  0x2095,0x2096,0x2097,0x2098,0x209a,0x20a7,0x20aa,0x20ac,0x20ae,0x2102,0x210e,0x210f,0x2115,0x2116,0x211a,0x211d,\n  0x2122,0x2124,0x2126,0x2135,0x2190,0x2191,0x2192,0x2193,0x2194,0x2195,0x21a4,0x21a6,0x21a8,0x21b5,0x21bb,0x21cb,\n  0x21cc,0x21d0,0x21d1,0x21d2,0x21d3,0x21d4,0x21d5,0x2200,0x2203,0x2204,0x2205,0x2206,0x2207,0x2208,0x2209,0x220a,\n  0x220b,0x220c,0x220d,0x2212,0x2213,0x2214,0x2215,0x2216,0x2219,0x221a,0x221e,0x221f,0x2225,0x2227,0x2228,0x2229,\n  0x222a,0x2248,0x2260,0x2261,0x2264,0x2265,0x226a,0x226b,0x2282,0x2283,0x2286,0x2287,0x22a5,0x22c2,0x22c3,0x2300,\n  0x2302,0x2308,0x2309,0x230a,0x230b,0x2310,0x2319,0x2320,0x2321,0x239b,0x239c,0x239d,0x239e,0x239f,0x23a0,0x23a1,\n  0x23a2,0x23a3,0x23a4,0x23a5,0x23a6,0x23a7,0x23a8,0x23a9,0x23ab,0x23ac,0x23ad,0x23ae,0x23af,0x23ba,0x23bb,0x23bc,\n  0x23bd,0x23d0,0x2409,0x240a,0x240b,0x240c,0x240d,0x2424,0x2500,0x2501,0x2502,0x2503,0x2508,0x2509,0x250a,0x250b,\n  0x250c,0x250d,0x250e,0x250f,0x2510,0x2511,0x2512,0x2513,0x2514,0x2515,0x2516,0x2517,0x2518,0x2519,0x251a,0x251b,\n  0x251c,0x251d,0x251e,0x251f,0x2520,0x2521,0x2522,0x2523,0x2524,0x2525,0x2526,0x2527,0x2528,0x2529,0x252a,0x252b,\n  0x252c,0x252d,0x252e,0x252f,0x2530,0x2531,0x2532,0x2533,0x2534,0x2535,0x2536,0x2537,0x2538,0x2539,0x253a,0x253b,\n  0x253c,0x253d,0x253e,0x253f,0x2540,0x2541,0x2542,0x2543,0x2544,0x2545,0x2546,0x2547,0x2548,0x2549,0x254a,0x254b,\n  0x2550,0x2551,0x2552,0x2553,0x2554,0x2555,0x2556,0x2557,0x2558,0x2559,0x255a,0x255b,0x255c,0x255d,0x255e,0x255f,\n  0x2560,0x2561,0x2562,0x2563,0x2564,0x2565,0x2566,0x2567,0x2568,0x2569,0x256a,0x256b,0x256c,0x256d,0x256e,0x256f,\n  0x2570,0x2571,0x2572,0x2573,0x2574,0x2575,0x2576,0x2577,0x2578,0x2579,0x257a,0x257b,0x257c,0x257d,0x257e,0x257f,\n  0x2580,0x2581,0x2582,0x2583,0x2584,0x2585,0x2586,0x2587,0x2588,0x2589,0x258a,0x258b,0x258c,0x258d,0x258e,0x258f,\n  0x2590,0x2591,0x2592,0x2593,0x2596,0x2597,0x2598,0x2599,0x259a,0x259b,0x259c,0x259d,0x259e,0x259f,0x25a0,0x25ac,\n  0x25ae,0x25b2,0x25b6,0x25ba,0x25bc,0x25c0,0x25c4,0x25c6,0x25ca,0x25cb,0x25cf,0x25d8,0x25d9,0x263a,0x263b,0x263c,\n  0x2640,0x2642,0x2660,0x2663,0x2665,0x2666,0x266a,0x266b,0x2713,0x2714,0x2717,0x2718,0x27e8,0x27e9,0x27ea,0x27eb,\n  0x2800,0x2801,0x2802,0x2803,0x2804,0x2805,0x2806,0x2807,0x2808,0x2809,0x280a,0x280b,0x280c,0x280d,0x280e,0x280f,\n  0x2810,0x2811,0x2812,0x2813,0x2814,0x2815,0x2816,0x2817,0x2818,0x2819,0x281a,0x281b,0x281c,0x281d,0x281e,0x281f,\n  0x2820,0x2821,0x2822,0x2823,0x2824,0x2825,0x2826,0x2827,0x2828,0x2829,0x282a,0x282b,0x282c,0x282d,0x282e,0x282f,\n  0x2830,0x2831,0x2832,0x2833,0x2834,0x2835,0x2836,0x2837,0x2838,0x2839,0x283a,0x283b,0x283c,0x283d,0x283e,0x283f,\n  0x2840,0x2841,0x2842,0x2843,0x2844,0x2845,0x2846,0x2847,0x2848,0x2849,0x284a,0x284b,0x284c,0x284d,0x284e,0x284f,\n  0x2850,0x2851,0x2852,0x2853,0x2854,0x2855,0x2856,0x2857,0x2858,0x2859,0x285a,0x285b,0x285c,0x285d,0x285e,0x285f,\n  0x2860,0x2861,0x2862,0x2863,0x2864,0x2865,0x2866,0x2867,0x2868,0x2869,0x286a,0x286b,0x286c,0x286d,0x286e,0x286f,\n  0x2870,0x2871,0x2872,0x2873,0x2874,0x2875,0x2876,0x2877,0x2878,0x2879,0x287a,0x287b,0x287c,0x287d,0x287e,0x287f,\n  0x2880,0x2881,0x2882,0x2883,0x2884,0x2885,0x2886,0x2887,0x2888,0x2889,0x288a,0x288b,0x288c,0x288d,0x288e,0x288f,\n  0x2890,0x2891,0x2892,0x2893,0x2894,0x2895,0x2896,0x2897,0x2898,0x2899,0x289a,0x289b,0x289c,0x289d,0x289e,0x289f,\n  0x28a0,0x28a1,0x28a2,0x28a3,0x28a4,0x28a5,0x28a6,0x28a7,0x28a8,0x28a9,0x28aa,0x28ab,0x28ac,0x28ad,0x28ae,0x28af,\n  0x28b0,0x28b1,0x28b2,0x28b3,0x28b4,0x28b5,0x28b6,0x28b7,0x28b8,0x28b9,0x28ba,0x28bb,0x28bc,0x28bd,0x28be,0x28bf,\n  0x28c0,0x28c1,0x28c2,0x28c3,0x28c4,0x28c5,0x28c6,0x28c7,0x28c8,0x28c9,0x28ca,0x28cb,0x28cc,0x28cd,0x28ce,0x28cf,\n  0x28d0,0x28d1,0x28d2,0x28d3,0x28d4,0x28d5,0x28d6,0x28d7,0x28d8,0x28d9,0x28da,0x28db,0x28dc,0x28dd,0x28de,0x28df,\n  0x28e0,0x28e1,0x28e2,0x28e3,0x28e4,0x28e5,0x28e6,0x28e7,0x28e8,0x28e9,0x28ea,0x28eb,0x28ec,0x28ed,0x28ee,0x28ef,\n  0x28f0,0x28f1,0x28f2,0x28f3,0x28f4,0x28f5,0x28f6,0x28f7,0x28f8,0x28f9,0x28fa,0x28fb,0x28fc,0x28fd,0x28fe,0x28ff,\n  0x2e2c,0xe0a0,0xe0a1,0xe0a2,0xe0b0,0xe0b1,0xe0b2,0xe0b3,0xf6be,0xfffd };\n} // namespace\n// -- end of autogenerated text ---\n\nnamespace fixed_font_28b {\n  // -- start of autogenerated text ---\n  // definition section for font: ter-u28b.bdf\n  constexpr int CHARCOUNT = 1354;\n  constexpr int WIDTH = 14;\n  constexpr int HEIGHT = 28;\n  constexpr int OFFSET_X = 0;\n  constexpr int OFFSET_Y = 0;\n  constexpr FixedFont_info_t fixedfont_info = {\n    \"Terminus\", // font name\n    \"ter-u28b.bdf\", // font name internal\n    CHARCOUNT, // num of chars\n    WIDTH, HEIGHT, OFFSET_X, OFFSET_Y,\n    true // bold\n  };\n  // font bitmap definitions\n  constexpr std::array<uint16_t, CHARCOUNT * HEIGHT> fixedfont_bitmap = {\n  0x0000,0x0000,0x0000,0x0000,0x78f0,0x78f0,0x6030,0x6030,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x0000,\n  0x0000,0x0000,0x6030,0x6030,0x78f0,0x78f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0020\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0021\n  0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0022\n  0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x18c0,0x7ff0,0x7ff0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,\n  0x7ff0,0x7ff0,0x18c0,0x18c0,0x18c0,0x18c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0023\n  0x0000,0x0000,0x0300,0x0300,0x0300,0x1fe0,0x3ff0,0x7338,0x6318,0x6300,0x6300,0x7300,0x3fe0,0x1ff0,0x0338,0x0318,\n  0x0318,0x6318,0x7338,0x3ff0,0x1fe0,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000, // u0024\n  0x0000,0x0000,0x0000,0x0000,0x3c30,0x7e30,0x6660,0x7e60,0x3cc0,0x00c0,0x0180,0x0180,0x0300,0x0300,0x0600,0x0600,\n  0x0c00,0x0cf0,0x19f8,0x1998,0x31f8,0x30f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0025\n  0x0000,0x0000,0x0000,0x0000,0x0f00,0x1f80,0x39c0,0x30c0,0x30c0,0x39c0,0x1f80,0x0f00,0x0e00,0x1f18,0x3bb8,0x71f0,\n  0x60e0,0x60e0,0x60e0,0x71f0,0x3fb8,0x1f18,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0026\n  0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0027\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0600,0x0600,0x0300,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0028\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0600,0x0300,0x0300,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0300,0x0300,0x0600,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0029\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x38e0,0x1dc0,0x0f80,0x0700,0x7ff0,0x7ff0,0x0700,0x0f80,\n  0x1dc0,0x38e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x7ff8,0x7ff8,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0600,0x0c00,0x0000,0x0000,0x0000,0x0000, // u002c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002e\n  0x0000,0x0000,0x0000,0x0000,0x0030,0x0030,0x0060,0x0060,0x00c0,0x00c0,0x0180,0x0180,0x0300,0x0300,0x0600,0x0600,\n  0x0c00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002f\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6070,0x60f0,0x61f0,0x63b0,0x6730,0x6e30,0x7c30,0x7830,\n  0x7030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0030\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0700,0x0f00,0x1f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x1fe0,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0031\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x0030,0x0070,0x00e0,0x01c0,0x0380,0x0700,\n  0x0e00,0x1c00,0x3800,0x7000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0032\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x0030,0x0030,0x0030,0x0070,0x0fe0,0x0fe0,0x0070,0x0030,\n  0x0030,0x0030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0033\n  0x0000,0x0000,0x0000,0x0000,0x0030,0x0070,0x00f0,0x01f0,0x03b0,0x0730,0x0e30,0x1c30,0x3830,0x7030,0x6030,0x6030,\n  0x7ff0,0x7ff0,0x0030,0x0030,0x0030,0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0034\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x7fe0,0x0070,0x0030,0x0030,\n  0x0030,0x0030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0035\n  0x0000,0x0000,0x0000,0x0000,0x1fe0,0x3fe0,0x7000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0036\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x6030,0x6030,0x6030,0x0060,0x0060,0x00c0,0x00c0,0x0180,0x0180,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0037\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x7070,0x3fe0,0x3fe0,0x7070,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0038\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,\n  0x0030,0x0030,0x0030,0x0070,0x3fe0,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0600,0x0c00,0x0000,0x0000,0x0000,0x0000, // u003b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,0x7000,0x3800,0x1c00,\n  0x0e00,0x0700,0x0380,0x01c0,0x00e0,0x0070,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x7ff0,\n  0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x3800,0x1c00,0x0e00,0x0700,0x0380,0x01c0,0x00e0,0x0070,0x00e0,0x01c0,\n  0x0380,0x0700,0x0e00,0x1c00,0x3800,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003e\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x0070,0x00e0,0x01c0,0x0380,0x0300,0x0300,\n  0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003f\n  0x0000,0x0000,0x0000,0x0000,0x1fe0,0x3ff0,0x7038,0x6018,0x61f8,0x63f8,0x6718,0x6618,0x6618,0x6618,0x6618,0x6718,\n  0x63f8,0x61e8,0x6000,0x7000,0x3ff8,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0040\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0041\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x7fc0,0x6060,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6070,0x7fe0,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0042\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0043\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x7fc0,0x60e0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6060,0x60e0,0x7fc0,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0044\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x7f80,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0045\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x7f80,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0046\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6000,0x6000,0x6000,0x63f0,0x63f0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0047\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0048\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0049\n  0x0000,0x0000,0x0000,0x0000,0x01f8,0x01f8,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x6060,0x6060,0x6060,0x70e0,0x3fc0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u004a\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6070,0x60e0,0x61c0,0x6380,0x6700,0x6e00,0x7c00,0x7800,0x7800,0x7c00,0x6e00,\n  0x6700,0x6380,0x61c0,0x60e0,0x6070,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u004b\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u004c\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x7038,0x7878,0x7cf8,0x6fd8,0x6798,0x6318,0x6018,0x6018,0x6018,0x6018,\n  0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u004d\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x7030,0x7830,0x7c30,0x6e30,0x6730,0x63b0,0x61f0,0x60f0,\n  0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u004e\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u004f\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6070,0x7fe0,0x7fc0,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0050\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x63b0,0x71f0,0x3fe0,0x1fe0,0x0070,0x0038,0x0000,0x0000,0x0000,0x0000, // u0051\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6070,0x7fe0,0x7fc0,0x7c00,\n  0x6e00,0x6700,0x6380,0x61c0,0x60e0,0x6070,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0052\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6000,0x6000,0x6000,0x7000,0x3fc0,0x1fe0,0x0070,0x0030,\n  0x0030,0x0030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0053\n  0x0000,0x0000,0x0000,0x0000,0x7ff8,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0054\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0055\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x3060,0x3060,0x3060,0x3060,0x18c0,0x18c0,0x18c0,0x18c0,\n  0x0d80,0x0d80,0x0d80,0x0700,0x0700,0x0700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0056\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6318,0x6798,\n  0x6fd8,0x7cf8,0x7878,0x7038,0x6018,0x6018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0057\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x3060,0x3060,0x18c0,0x18c0,0x0d80,0x0d80,0x0700,0x0700,0x0d80,0x0d80,\n  0x18c0,0x18c0,0x3060,0x3060,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0058\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0059\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x0030,0x0030,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,\n  0x7000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005a\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005b\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x1800,0x1800,0x0c00,0x0c00,0x0600,0x0600,0x0300,0x0300,0x0180,0x0180,\n  0x00c0,0x00c0,0x0060,0x0060,0x0030,0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005c\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fc0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x00c0,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005d\n  0x0000,0x0000,0x0200,0x0700,0x0f80,0x1dc0,0x38e0,0x7070,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000, // u005f\n  0x1c00,0x0e00,0x0700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0060\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x1fe0,0x0070,0x0030,0x1ff0,0x3ff0,0x7030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0061\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6070,0x7fe0,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0062\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0063\n  0x0000,0x0000,0x0000,0x0000,0x0030,0x0030,0x0030,0x0030,0x0030,0x1ff0,0x3ff0,0x7030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0064\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x7ff0,0x7ff0,\n  0x6000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0065\n  0x0000,0x0000,0x0000,0x0000,0x03f0,0x07f0,0x0600,0x0600,0x0600,0x3fc0,0x3fc0,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0066\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff0,0x7030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,0x0030,0x0070,0x3fe0,0x3fc0,0x0000, // u0067\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0068\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000,0x0f00,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0069\n  0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0000,0x0000,0x01e0,0x01e0,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x3060,0x3060,0x38e0,0x1fc0,0x0f80,0x0000, // u006a\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3070,0x30e0,0x31c0,0x3380,0x3700,0x3e00,0x3c00,\n  0x3e00,0x3700,0x3380,0x31c0,0x30e0,0x3070,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u006b\n  0x0000,0x0000,0x0000,0x0000,0x0f00,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u006c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x7ff0,0x6338,0x6318,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u006d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u006e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u006f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6070,0x7fe0,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000, // u0070\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff0,0x7030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,0x0030,0x0030,0x0030,0x0030,0x0000, // u0071\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x67f0,0x6ff0,0x7c00,0x7800,0x7000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0072\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6000,0x7000,0x3fc0,0x1fe0,\n  0x0070,0x0030,0x0030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0073\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,0x3fc0,0x3fc0,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x07e0,0x03e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0074\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0075\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x3060,0x3060,0x3060,0x18c0,\n  0x18c0,0x18c0,0x0d80,0x0d80,0x0700,0x0700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0076\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x6018,0x6018,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x7338,0x3ff0,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0077\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x7070,0x38e0,0x1dc0,0x0f80,0x0700,\n  0x0f80,0x1dc0,0x38e0,0x7070,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0078\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,0x0030,0x0070,0x3fe0,0x3fc0,0x0000, // u0079\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x0070,0x00e0,0x01c0,0x0380,0x0700,\n  0x0e00,0x1c00,0x3800,0x7000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007a\n  0x0000,0x0000,0x0000,0x0000,0x01c0,0x03c0,0x0700,0x0600,0x0600,0x0600,0x0600,0x0600,0x1c00,0x1c00,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0700,0x03c0,0x01c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007b\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007c\n  0x0000,0x0000,0x0000,0x0000,0x1c00,0x1e00,0x0700,0x0300,0x0300,0x0300,0x0300,0x0300,0x01c0,0x01c0,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0700,0x1e00,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007d\n  0x0000,0x0000,0x3c30,0x7e30,0x6730,0x63f0,0x61e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a0\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0fc0,0x1fe0,0x3330,0x3300,0x3300,0x3300,0x3300,\n  0x3300,0x3300,0x3300,0x3330,0x1fe0,0x0fc0,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000, // u00a2\n  0x0000,0x0000,0x0000,0x0000,0x0780,0x0fc0,0x1c60,0x1860,0x1800,0x1800,0x1800,0x1800,0x3f80,0x3f80,0x1800,0x1800,\n  0x1800,0x1800,0x1830,0x1830,0x3ff0,0x3ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6018,0x7038,0x3ff0,0x1fe0,0x3870,0x3030,0x3030,0x3030,0x3870,\n  0x1fe0,0x3ff0,0x7038,0x6018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a4\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,0x0cc0,0x0cc0,0x0780,0x0300,0x3ff0,0x3ff0,\n  0x0300,0x0300,0x3ff0,0x3ff0,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a5\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a6\n  0x0000,0x0000,0x0000,0x0780,0x0fc0,0x1ce0,0x1800,0x1c00,0x0f00,0x0f80,0x19c0,0x18e0,0x1860,0x1860,0x1c60,0x0e60,\n  0x07c0,0x03c0,0x00e0,0x0060,0x1ce0,0x0fc0,0x0780,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a7\n  0x18c0,0x18c0,0x18c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fe0,0x7ff0,0xe038,0xcf98,0xdfd8,0xd8d8,0xd818,0xd818,0xd8d8,\n  0xdfd8,0xcf98,0xe038,0x7ff0,0x3fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a9\n  0x0000,0x1fc0,0x1fe0,0x0070,0x0ff0,0x1ff0,0x3830,0x3030,0x3830,0x1ff0,0x0ff0,0x0000,0x3ff0,0x3ff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x039c,0x0738,0x0e70,0x1ce0,0x39c0,0x7380,0xe700,\n  0x7380,0x39c0,0x1ce0,0x0e70,0x0738,0x039c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ab\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x0030,0x0030,0x0030,0x0030,\n  0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ac\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ad\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fe0,0x7ff0,0xe038,0xdf98,0xdfd8,0xd8d8,0xd8d8,0xdf98,0xdf18,\n  0xd998,0xd8d8,0xe038,0x7ff0,0x3fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ae\n  0x1fc0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00af\n  0x0000,0x0000,0x0f80,0x1fc0,0x18c0,0x18c0,0x18c0,0x1fc0,0x0f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x7ff8,0x7ff8,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0000,0x0000,0x7ff8,0x7ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b1\n  0x0000,0x0000,0x0f80,0x1fc0,0x18c0,0x00c0,0x01c0,0x0380,0x0700,0x0e00,0x1fc0,0x1fc0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b2\n  0x0000,0x0000,0x0f80,0x1fc0,0x00c0,0x00c0,0x0780,0x07c0,0x00c0,0x00c0,0x1fc0,0x0f80,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b3\n  0x01c0,0x0380,0x0700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6070,0x60f0,0x61f0,0x7fb0,0x7f30,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000, // u00b5\n  0x0000,0x0000,0x0000,0x0000,0x3ff8,0x7ff8,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x7f18,0x3f18,0x0318,\n  0x0318,0x0318,0x0318,0x0318,0x0318,0x0318,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0c00,0x1800,0x0000, // u00b8\n  0x0000,0x0000,0x0300,0x0700,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b9\n  0x0000,0x0fc0,0x1fe0,0x3870,0x3030,0x3030,0x3030,0x3030,0x3870,0x1fe0,0x0fc0,0x0000,0x3ff0,0x3ff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xe700,0x7380,0x39c0,0x1ce0,0x0e70,0x0738,0x039c,\n  0x0738,0x0e70,0x1ce0,0x39c0,0x7380,0xe700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00bb\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x3800,0x7800,0x1818,0x1838,0x1870,0x18e0,0x19c0,0x0380,0x0730,0x0e70,0x1cf0,\n  0x39b0,0x7330,0x67f0,0x07f0,0x0030,0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00bc\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x3800,0x7818,0x1838,0x1870,0x18e0,0x19c0,0x1b80,0x0700,0x0e00,0x1df0,0x3bf8,\n  0x7318,0x6030,0x0060,0x00c0,0x01f8,0x03f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00bd\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x7f00,0x0300,0x1e00,0x1f18,0x0338,0x7f70,0x3ee0,0x01c0,0x0398,0x0738,0x0e78,\n  0x1cd8,0x3998,0x73f8,0x63f8,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00be\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0000,0x0000,0x0600,0x0600,0x0600,0x0c00,0x1800,0x3000,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00bf\n  0x1c00,0x0e00,0x0700,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c0\n  0x01c0,0x0380,0x0700,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c1\n  0x0700,0x0f80,0x1dc0,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c2\n  0x1e60,0x3fe0,0x33c0,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c3\n  0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c4\n  0x0780,0x0cc0,0x0cc0,0x0780,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c5\n  0x0000,0x0000,0x0000,0x0000,0x3ff8,0x7ff8,0xe300,0xc300,0xc300,0xc300,0xc300,0xc300,0xfff0,0xfff0,0xc300,0xc300,\n  0xc300,0xc300,0xc300,0xc300,0xc3f8,0xc3f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c6\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0600,0x0600,0x0600,0x0c00,0x1800,0x0000, // u00c7\n  0x1c00,0x0e00,0x0700,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x7f80,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c8\n  0x01c0,0x0380,0x0700,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x7f80,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c9\n  0x0700,0x0f80,0x1dc0,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x7f80,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ca\n  0x18c0,0x18c0,0x18c0,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x7f80,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cb\n  0x0e00,0x0700,0x0380,0x0000,0x0fc0,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cc\n  0x01c0,0x0380,0x0700,0x0000,0x0fc0,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cd\n  0x0700,0x0f80,0x1dc0,0x0000,0x0fc0,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ce\n  0x18c0,0x18c0,0x18c0,0x0000,0x0fc0,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cf\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x7fc0,0x60e0,0x6060,0x6030,0x6030,0x6030,0x6030,0xfe30,0xfe30,0x6030,0x6030,\n  0x6030,0x6030,0x6060,0x60e0,0x7fc0,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d0\n  0x1e60,0x3fe0,0x33c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x7030,0x7830,0x7c30,0x6e30,0x6730,0x63b0,0x61f0,0x60f0,\n  0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d1\n  0x1c00,0x0e00,0x0700,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d2\n  0x01c0,0x0380,0x0700,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d3\n  0x0700,0x0f80,0x1dc0,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d4\n  0x1e60,0x3fe0,0x33c0,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d5\n  0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x7070,0x38e0,0x1dc0,0x0f80,0x0700,0x0f80,0x1dc0,\n  0x38e0,0x7070,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d7\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6038,0x6078,0x60f0,0x61f0,0x63b0,0x6730,0x6e30,0x7c30,0x7830,\n  0x7030,0xe030,0xe030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d8\n  0x1c00,0x0e00,0x0700,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d9\n  0x01c0,0x0380,0x0700,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00da\n  0x0700,0x0f80,0x1dc0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00db\n  0x18c0,0x18c0,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00dc\n  0x01c0,0x0380,0x0700,0x0000,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00dd\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6070,\n  0x7fe0,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00de\n  0x0000,0x0000,0x0000,0x0000,0x3f80,0x7fc0,0x60e0,0x6060,0x6060,0x6060,0x60c0,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,\n  0x6030,0x6030,0x7030,0x7870,0x6fe0,0x67c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00df\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0e00,0x0700,0x0000,0x1fc0,0x1fe0,0x0070,0x0030,0x1ff0,0x3ff0,0x7030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x0380,0x0700,0x0000,0x1fc0,0x1fe0,0x0070,0x0030,0x1ff0,0x3ff0,0x7030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0f80,0x1dc0,0x0000,0x1fc0,0x1fe0,0x0070,0x0030,0x1ff0,0x3ff0,0x7030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1e60,0x3fe0,0x33c0,0x0000,0x1fc0,0x1fe0,0x0070,0x0030,0x1ff0,0x3ff0,0x7030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x1fe0,0x0070,0x0030,0x1ff0,0x3ff0,0x7030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0780,0x0cc0,0x0cc0,0x0780,0x1fc0,0x1fe0,0x0070,0x0030,0x1ff0,0x3ff0,0x7030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7de0,0x7ff0,0x0738,0x0318,0x3f18,0x7ff8,0xe3f8,\n  0xc300,0xc300,0xc300,0xe398,0x7ff8,0x3ef0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0600,0x0600,0x0600,0x0c00,0x1800,0x0000, // u00e7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0e00,0x0700,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x7ff0,0x7ff0,\n  0x6000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x0380,0x0700,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x7ff0,0x7ff0,\n  0x6000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0f80,0x1dc0,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x7ff0,0x7ff0,\n  0x6000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x7ff0,0x7ff0,\n  0x6000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00eb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0e00,0x0700,0x0000,0x0f00,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ec\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x0380,0x0700,0x0000,0x0f00,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ed\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0f80,0x1dc0,0x0000,0x0f00,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ee\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x0f00,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ef\n  0x0000,0x0000,0x0000,0x0000,0x3980,0x1f00,0x1e00,0x3700,0x0380,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3c60,0x7fe0,0x63c0,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0e00,0x0700,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x0380,0x0700,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0f80,0x1dc0,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1e60,0x3fe0,0x33c0,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x7ff8,0x7ff8,0x0000,0x0000,\n  0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fd8,0x3ff8,0x6070,0x60f0,0x61f0,0x63b0,0x6730,\n  0x6e30,0x7c30,0x7830,0x7030,0xffe0,0xdfc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0e00,0x0700,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x0380,0x0700,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00fa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0f80,0x1dc0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00fb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00fc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x0380,0x0700,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,0x0030,0x0070,0x3fe0,0x3fc0,0x0000, // u00fd\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6070,0x7fe0,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000, // u00fe\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,0x0030,0x0070,0x3fe0,0x3fc0,0x0000, // u00ff\n  0x1fc0,0x1fc0,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0100\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x1fc0,0x0000,0x0000,0x1fc0,0x1fe0,0x0070,0x0030,0x1ff0,0x3ff0,0x7030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0101\n  0x18c0,0x1fc0,0x0f80,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0102\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x1fc0,0x0f80,0x0000,0x1fc0,0x1fe0,0x0070,0x0030,0x1ff0,0x3ff0,0x7030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0103\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0060,0x00c0,0x00c0,0x00f8,0x0078,0x0000, // u0104\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x1fe0,0x0070,0x0030,0x1ff0,0x3ff0,0x7030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0060,0x00c0,0x00c0,0x00f8,0x0078,0x0000, // u0105\n  0x01c0,0x0380,0x0700,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0106\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x0380,0x0700,0x0000,0x1fc0,0x3fe0,0x7070,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0107\n  0x0700,0x0f80,0x1dc0,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0108\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0f80,0x1dc0,0x0000,0x1fc0,0x3fe0,0x7070,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0109\n  0x0300,0x0300,0x0300,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u010a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0000,0x1fc0,0x3fe0,0x7070,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u010b\n  0x1dc0,0x0f80,0x0700,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u010c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1dc0,0x0f80,0x0700,0x0000,0x1fc0,0x3fe0,0x7070,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u010d\n  0x1dc0,0x0f80,0x0700,0x0000,0x7f00,0x7fc0,0x60e0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6060,0x60e0,0x7fc0,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u010e\n  0x1dc0,0x0f80,0x0700,0x0000,0x0030,0x0030,0x0030,0x0030,0x0030,0x1ff0,0x3ff0,0x7030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u010f\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x7fc0,0x60e0,0x6060,0x6030,0x6030,0x6030,0x6030,0xfe30,0xfe30,0x6030,0x6030,\n  0x6030,0x6030,0x6060,0x60e0,0x7fc0,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0110\n  0x0000,0x0000,0x0000,0x0000,0x0030,0x07f8,0x07f8,0x0030,0x0030,0x1ff0,0x3ff0,0x7030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0111\n  0x1fc0,0x1fc0,0x0000,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x7f80,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0112\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x1fc0,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x7ff0,0x7ff0,\n  0x6000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0113\n  0x18c0,0x1fc0,0x0f80,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x7f80,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0114\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x1fc0,0x0f80,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x7ff0,0x7ff0,\n  0x6000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0115\n  0x0300,0x0300,0x0300,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x7f80,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0116\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x7ff0,0x7ff0,\n  0x6000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0117\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x7f80,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0060,0x00c0,0x00c0,0x00f8,0x0078,0x0000, // u0118\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x7ff0,0x7ff0,\n  0x6000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0380,0x0600,0x0600,0x07c0,0x03c0,0x0000, // u0119\n  0x1dc0,0x0f80,0x0700,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x7f80,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u011a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1dc0,0x0f80,0x0700,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x7ff0,0x7ff0,\n  0x6000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u011b\n  0x0700,0x0f80,0x1dc0,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6000,0x6000,0x6000,0x63f0,0x63f0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u011c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0f80,0x1dc0,0x0000,0x1ff0,0x3ff0,0x7030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,0x0030,0x0070,0x3fe0,0x3fc0,0x0000, // u011d\n  0x18c0,0x1fc0,0x0f80,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6000,0x6000,0x6000,0x63f0,0x63f0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u011e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x1fc0,0x0f80,0x0000,0x1ff0,0x3ff0,0x7030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,0x0030,0x0070,0x3fe0,0x3fc0,0x0000, // u011f\n  0x0300,0x0300,0x0300,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6000,0x6000,0x6000,0x63f0,0x63f0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0120\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0000,0x1ff0,0x3ff0,0x7030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,0x0030,0x0070,0x3fe0,0x3fc0,0x0000, // u0121\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6000,0x6000,0x6000,0x63f0,0x63f0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0600,0x0600,0x0600,0x0c00,0x1800, // u0122\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0380,0x0300,0x0300,0x0000,0x1ff0,0x3ff0,0x7030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,0x0030,0x0070,0x3fe0,0x3fc0,0x0000, // u0123\n  0x0700,0x0f80,0x1dc0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0124\n  0x0700,0x0f80,0x1dc0,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0125\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0xfff8,0xfff8,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0126\n  0x0000,0x0000,0x0000,0x0000,0x6000,0xff00,0xff00,0x6000,0x6000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0127\n  0x1e60,0x3fe0,0x33c0,0x0000,0x0fc0,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0128\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1e60,0x3fe0,0x33c0,0x0000,0x0f00,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0129\n  0x1fc0,0x1fc0,0x0000,0x0000,0x0fc0,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u012a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x1fc0,0x0000,0x0000,0x0f00,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u012b\n  0x18c0,0x1fc0,0x0f80,0x0000,0x0fc0,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u012c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x1fc0,0x0f80,0x0000,0x0f00,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u012d\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0300,0x0600,0x0600,0x07c0,0x03c0,0x0000, // u012e\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000,0x0f00,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0300,0x0600,0x0600,0x07c0,0x03c0,0x0000, // u012f\n  0x0300,0x0300,0x0300,0x0000,0x0fc0,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0130\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0131\n  0x0000,0x0000,0x0000,0x0000,0xf078,0xf078,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6630,0x6630,0x6630,0x6630,0xf7f0,0xf3e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0132\n  0x0000,0x0000,0x0000,0x0000,0x3018,0x3018,0x3018,0x0000,0x0000,0x7038,0x7038,0x3018,0x3018,0x3018,0x3018,0x3018,\n  0x3018,0x3018,0x3018,0x3018,0x7818,0x7818,0x0018,0x0318,0x0318,0x03f8,0x01f0,0x0000, // u0133\n  0x00e0,0x01f0,0x03b8,0x0000,0x01f8,0x01f8,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x6060,0x6060,0x6060,0x70e0,0x3fc0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0134\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x00e0,0x01f0,0x03b8,0x0000,0x01e0,0x01e0,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x3060,0x3060,0x38e0,0x1fc0,0x0f80,0x0000, // u0135\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6070,0x60e0,0x61c0,0x6380,0x6700,0x6e00,0x7c00,0x7800,0x7800,0x7c00,0x6e00,\n  0x6700,0x6380,0x61c0,0x60e0,0x6070,0x6030,0x0000,0x0600,0x0600,0x0600,0x0c00,0x1800, // u0136\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3070,0x30e0,0x31c0,0x3380,0x3700,0x3e00,0x3c00,\n  0x3e00,0x3700,0x3380,0x31c0,0x30e0,0x3070,0x0000,0x0600,0x0600,0x0600,0x0c00,0x1800, // u0137\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3070,0x30e0,0x31c0,0x3380,0x3700,0x3e00,0x3c00,\n  0x3e00,0x3700,0x3380,0x31c0,0x30e0,0x3070,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0138\n  0x1c00,0x3800,0x7000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0139\n  0x01c0,0x0380,0x0700,0x0000,0x0f00,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u013a\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0600,0x0600,0x0600,0x0c00,0x1800, // u013b\n  0x0000,0x0000,0x0000,0x0000,0x0f00,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0300,0x0300,0x0300,0x0600,0x0c00, // u013c\n  0x1dc0,0x0f80,0x0700,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u013d\n  0x1dc0,0x0f80,0x0700,0x0000,0x0f00,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u013e\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x60c0,0x60c0,0x60c0,0x60c0,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u013f\n  0x0000,0x0000,0x0000,0x0000,0x0f00,0x0f00,0x0300,0x0300,0x0300,0x0300,0x030c,0x030c,0x030c,0x030c,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0140\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3300,0x3600,0x3c00,0x3800,0x3000,0x7000,0xf000,\n  0x3000,0x3000,0x3000,0x3000,0x3ff8,0x3ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0141\n  0x0000,0x0000,0x0000,0x0000,0x0f00,0x0f00,0x0300,0x0300,0x0300,0x0360,0x03c0,0x0380,0x0300,0x0700,0x0f00,0x1b00,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0142\n  0x01c0,0x0380,0x0700,0x0000,0x6030,0x6030,0x6030,0x6030,0x7030,0x7830,0x7c30,0x6e30,0x6730,0x63b0,0x61f0,0x60f0,\n  0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0143\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x0380,0x0700,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0144\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x7030,0x7830,0x7c30,0x6e30,0x6730,0x63b0,0x61f0,0x60f0,\n  0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0600,0x0600,0x0600,0x0c00,0x1800, // u0145\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0600,0x0600,0x0600,0x0c00,0x1800, // u0146\n  0x1dc0,0x0f80,0x0700,0x0000,0x6030,0x6030,0x6030,0x6030,0x7030,0x7830,0x7c30,0x6e30,0x6730,0x63b0,0x61f0,0x60f0,\n  0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0147\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1dc0,0x0f80,0x0700,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0148\n  0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0xc000,0xc000,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0149\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x7030,0x7830,0x7c30,0x6e30,0x6730,0x63b0,0x61f0,0x60f0,\n  0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x0030,0x0030,0x0070,0x03e0,0x03c0,0x0000, // u014a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0030,0x0030,0x0070,0x03e0,0x03c0,0x0000, // u014b\n  0x1fc0,0x1fc0,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u014c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x1fc0,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u014d\n  0x18c0,0x1fc0,0x0f80,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u014e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x1fc0,0x0f80,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u014f\n  0x0738,0x0e70,0x1ce0,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0150\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0738,0x0e70,0x1ce0,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0151\n  0x0000,0x0000,0x0000,0x0000,0x3ff8,0x7ff8,0xe300,0xc300,0xc300,0xc300,0xc300,0xc300,0xc3f0,0xc3f0,0xc300,0xc300,\n  0xc300,0xc300,0xc300,0xe300,0x7ff8,0x3ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0152\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fe0,0x7ff0,0xc318,0xc318,0xc318,0xc3f8,0xc3f8,\n  0xc300,0xc300,0xc300,0xc318,0x7ff8,0x3ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0153\n  0x01c0,0x0380,0x0700,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6070,0x7fe0,0x7fc0,0x7c00,\n  0x6e00,0x6700,0x6380,0x61c0,0x60e0,0x6070,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0154\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x0380,0x0700,0x0000,0x67f0,0x6ff0,0x7c00,0x7800,0x7000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0155\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6070,0x7fe0,0x7fc0,0x7c00,\n  0x6e00,0x6700,0x6380,0x61c0,0x60e0,0x6070,0x0000,0x0600,0x0600,0x0600,0x0c00,0x1800, // u0156\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x33f8,0x37f8,0x3e00,0x3c00,0x3800,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,0x3000,0x3000,0x3000,0x6000,0xc000, // u0157\n  0x1dc0,0x0f80,0x0700,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6070,0x7fe0,0x7fc0,0x7c00,\n  0x6e00,0x6700,0x6380,0x61c0,0x60e0,0x6070,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0158\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1dc0,0x0f80,0x0700,0x0000,0x67f0,0x6ff0,0x7c00,0x7800,0x7000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0159\n  0x01c0,0x0380,0x0700,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6000,0x6000,0x6000,0x7000,0x3fc0,0x1fe0,0x0070,0x0030,\n  0x0030,0x0030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u015a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x0380,0x0700,0x0000,0x1fc0,0x3fe0,0x7070,0x6000,0x7000,0x3fc0,0x1fe0,\n  0x0070,0x0030,0x0030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u015b\n  0x0700,0x0f80,0x1dc0,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6000,0x6000,0x6000,0x7000,0x3fc0,0x1fe0,0x0070,0x0030,\n  0x0030,0x0030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u015c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0f80,0x1dc0,0x0000,0x1fc0,0x3fe0,0x7070,0x6000,0x7000,0x3fc0,0x1fe0,\n  0x0070,0x0030,0x0030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u015d\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6000,0x6000,0x6000,0x7000,0x3fc0,0x1fe0,0x0070,0x0030,\n  0x0030,0x0030,0x6030,0x7070,0x3fe0,0x1fc0,0x0600,0x0600,0x0600,0x0c00,0x1800,0x0000, // u015e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6000,0x7000,0x3fc0,0x1fe0,\n  0x0070,0x0030,0x0030,0x7070,0x3fe0,0x1fc0,0x0600,0x0600,0x0600,0x0c00,0x1800,0x0000, // u015f\n  0x1dc0,0x0f80,0x0700,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6000,0x6000,0x6000,0x7000,0x3fc0,0x1fe0,0x0070,0x0030,\n  0x0030,0x0030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0160\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1dc0,0x0f80,0x0700,0x0000,0x1fc0,0x3fe0,0x7070,0x6000,0x7000,0x3fc0,0x1fe0,\n  0x0070,0x0030,0x0030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0161\n  0x0000,0x0000,0x0000,0x0000,0x7ff8,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0180,0x0180,0x0180,0x0300,0x0600,0x0000, // u0162\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,0x3fc0,0x3fc0,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x07e0,0x03e0,0x0180,0x0180,0x0180,0x0300,0x0600,0x0000, // u0163\n  0x1dc0,0x0f80,0x0700,0x0000,0x7ff8,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0164\n  0x3b80,0x1f00,0x0e00,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,0x3fc0,0x3fc0,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x07e0,0x03e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0165\n  0x0000,0x0000,0x0000,0x0000,0x7ff8,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x1fe0,0x1fe0,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0166\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,0x3fc0,0x3fc0,0x0600,0x0600,0x1f80,0x1f80,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x07e0,0x03e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0167\n  0x1e60,0x3fe0,0x33c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0168\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1e60,0x3fe0,0x33c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0169\n  0x1fc0,0x1fc0,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u016a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x1fc0,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u016b\n  0x18c0,0x1fc0,0x0f80,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u016c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x1fc0,0x0f80,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u016d\n  0x0780,0x0cc0,0x0cc0,0x0780,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u016e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0780,0x0cc0,0x0cc0,0x0780,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u016f\n  0x0738,0x0e70,0x1ce0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0170\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0738,0x0e70,0x1ce0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0171\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0380,0x0600,0x0600,0x07c0,0x03c0,0x0000, // u0172\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0060,0x00c0,0x00c0,0x00f8,0x0078,0x0000, // u0173\n  0x0700,0x0f80,0x1dc0,0x0000,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6318,0x6798,\n  0x6fd8,0x7cf8,0x7878,0x7038,0x6018,0x6018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0174\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0f80,0x1dc0,0x0000,0x6018,0x6018,0x6018,0x6018,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x7338,0x3ff0,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0175\n  0x0700,0x0f80,0x1dc0,0x0000,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0176\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0f80,0x1dc0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,0x0030,0x0070,0x3fe0,0x3fc0,0x0000, // u0177\n  0x18c0,0x18c0,0x18c0,0x0000,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0178\n  0x01c0,0x0380,0x0700,0x0000,0x7ff0,0x7ff0,0x0030,0x0030,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,\n  0x7000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0179\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x0380,0x0700,0x0000,0x7ff0,0x7ff0,0x0070,0x00e0,0x01c0,0x0380,0x0700,\n  0x0e00,0x1c00,0x3800,0x7000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u017a\n  0x0300,0x0300,0x0300,0x0000,0x7ff0,0x7ff0,0x0030,0x0030,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,\n  0x7000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u017b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0000,0x7ff0,0x7ff0,0x0070,0x00e0,0x01c0,0x0380,0x0700,\n  0x0e00,0x1c00,0x3800,0x7000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u017c\n  0x1dc0,0x0f80,0x0700,0x0000,0x7ff0,0x7ff0,0x0030,0x0030,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,\n  0x7000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u017d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1dc0,0x0f80,0x0700,0x0000,0x7ff0,0x7ff0,0x0070,0x00e0,0x01c0,0x0380,0x0700,\n  0x0e00,0x1c00,0x3800,0x7000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u017e\n  0x0000,0x0000,0x0000,0x0000,0x03f0,0x07f0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u017f\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,\n  0x0030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0186\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0ff0,0x0ff0,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u018e\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x0030,0x0030,0x0030,0x0030,0x7ff0,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u018f\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6000,0x6000,0x6000,0x6000,0x3f80,0x3f80,0x6000,0x6000,\n  0x6000,0x6000,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0190\n  0x0000,0x0000,0x0000,0x0000,0x01e0,0x03f0,0x0330,0x0330,0x0300,0x0300,0x0300,0x1fe0,0x1fe0,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x3300,0x3300,0x3f00,0x1e00,0x0000,0x0000, // u0192\n  0x0000,0x0000,0x0000,0x0000,0x3018,0x3018,0x3018,0x3018,0x3818,0x3c18,0x3e18,0x3718,0x3398,0x31d8,0x30f8,0x3078,\n  0x3038,0x3018,0x3018,0x3018,0x3018,0x3018,0x3000,0x3000,0x3000,0x7000,0xe000,0x0000, // u019d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0000, // u019e\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x0030,0x0030,0x0070,0x00e0,0x01c0,0x0380,0x7ff0,0x7ff0,0x0e00,0x1c00,\n  0x3800,0x7000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x00e0,0x01c0,0x0380,0x7ff0,0x7ff0,\n  0x0e00,0x1c00,0x3800,0x7000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01b6\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0fc0,0x0fe0,0x0070,0x0030,0x0030,\n  0x0030,0x0030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01b7\n  0x1dc0,0x0f80,0x0700,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01cd\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1dc0,0x0f80,0x0700,0x0000,0x1fc0,0x1fe0,0x0070,0x0030,0x1ff0,0x3ff0,0x7030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01ce\n  0x1dc0,0x0f80,0x0700,0x0000,0x0fc0,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01cf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1dc0,0x0f80,0x0700,0x0000,0x0f00,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d0\n  0x1dc0,0x0f80,0x0700,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1dc0,0x0f80,0x0700,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d2\n  0x1dc0,0x0f80,0x0700,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1dc0,0x0f80,0x0700,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d4\n  0x3ff0,0x3ff0,0x0000,0x0000,0x3ff8,0x7ff8,0xe300,0xc300,0xc300,0xc300,0xc300,0xc300,0xfff0,0xfff0,0xc300,0xc300,\n  0xc300,0xc300,0xc300,0xc300,0xc3f8,0xc3f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3fe0,0x3fe0,0x0000,0x0000,0x7de0,0x7ff0,0x0738,0x0318,0x3f18,0x7ff8,0xe3f8,\n  0xc300,0xc300,0xc300,0xe398,0x7ff8,0x3ef0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e3\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6000,0x6000,0x6000,0x63f0,0x63f0,0x6030,0x6030,\n  0x61fc,0x61fc,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff0,0x7030,0x6030,0x6030,0x61fc,0x61fc,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,0x0030,0x0070,0x3fe0,0x3fc0,0x0000, // u01e5\n  0x1dc0,0x0f80,0x0700,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6000,0x6000,0x6000,0x63f0,0x63f0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1dc0,0x0f80,0x0700,0x0000,0x1ff0,0x3ff0,0x7030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,0x0030,0x0070,0x3fe0,0x3fc0,0x0000, // u01e7\n  0x1dc0,0x0f80,0x0700,0x0000,0x6030,0x6070,0x60e0,0x61c0,0x6380,0x6700,0x6e00,0x7c00,0x7800,0x7800,0x7c00,0x6e00,\n  0x6700,0x6380,0x61c0,0x60e0,0x6070,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e8\n  0x1dc0,0x0f80,0x0700,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3070,0x30e0,0x31c0,0x3380,0x3700,0x3e00,0x3c00,\n  0x3e00,0x3700,0x3380,0x31c0,0x30e0,0x3070,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e9\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0380,0x0600,0x0600,0x07c0,0x03c0,0x0000, // u01ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0380,0x0600,0x0600,0x07c0,0x03c0,0x0000, // u01eb\n  0x1fc0,0x1fc0,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0380,0x0600,0x0600,0x07c0,0x03c0,0x0000, // u01ec\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x1fc0,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0380,0x0600,0x0600,0x07c0,0x03c0,0x0000, // u01ed\n  0x1dc0,0x0f80,0x0700,0x0000,0x7ff0,0x7ff0,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0fc0,0x0fe0,0x0070,0x0030,0x0030,\n  0x0030,0x0030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01ee\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1dc0,0x0f80,0x0700,0x0000,0x7ff0,0x7ff0,0x0070,0x00e0,0x01c0,0x0380,0x0700,\n  0x0fc0,0x0fe0,0x0070,0x0030,0x0030,0x0030,0x0030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000, // u01ef\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x03b8,0x01f0,0x00e0,0x0000,0x01e0,0x01e0,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x3060,0x3060,0x38e0,0x1fc0,0x0f80,0x0000, // u01f0\n  0x01c0,0x0380,0x0700,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6000,0x6000,0x6000,0x63f0,0x63f0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x00e0,0x01c0,0x0380,0x0000,0x1ff0,0x3ff0,0x7030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,0x0030,0x0070,0x3fe0,0x3fc0,0x0000, // u01f5\n  0x01c0,0x0380,0x0700,0x0000,0x3ff8,0x7ff8,0xe300,0xc300,0xc300,0xc300,0xc300,0xc300,0xfff0,0xfff0,0xc300,0xc300,\n  0xc300,0xc300,0xc300,0xc300,0xc3f8,0xc3f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01fc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x0380,0x0700,0x0000,0x7de0,0x7ff0,0x0738,0x0318,0x3f18,0x7ff8,0xe3f8,\n  0xc300,0xc300,0xc300,0xe398,0x7ff8,0x3ef0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01fd\n  0x01c0,0x0380,0x0700,0x0000,0x1fc0,0x3fe0,0x7070,0x6038,0x6078,0x60f0,0x61f0,0x63b0,0x6730,0x6e30,0x7c30,0x7830,\n  0x7030,0xe030,0xe030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01fe\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x0380,0x0700,0x0000,0x1fd8,0x3ff8,0x6070,0x60f0,0x61f0,0x63b0,0x6730,\n  0x6e30,0x7c30,0x7830,0x7030,0xffe0,0xdfc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01ff\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6000,0x6000,0x6000,0x7000,0x3fc0,0x1fe0,0x0070,0x0030,\n  0x0030,0x0030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0600,0x0600,0x0600,0x0c00,0x1800, // u0218\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6000,0x7000,0x3fc0,0x1fe0,\n  0x0070,0x0030,0x0030,0x7070,0x3fe0,0x1fc0,0x0000,0x0600,0x0600,0x0600,0x0c00,0x1800, // u0219\n  0x0000,0x0000,0x0000,0x0000,0x7ff8,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0300,0x0300,0x0300,0x0600,0x0c00, // u021a\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,0x3fc0,0x3fc0,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x07e0,0x03e0,0x0000,0x0180,0x0180,0x0180,0x0300,0x0600, // u021b\n  0x1fc0,0x1fc0,0x0000,0x0000,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0232\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x1fc0,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,0x0030,0x0070,0x3fe0,0x3fc0,0x0000, // u0233\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01e0,0x01e0,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x3060,0x3060,0x38e0,0x1fc0,0x0f80,0x0000, // u0237\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x0030,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0254\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x7ff0,0x7ff0,\n  0x0030,0x0030,0x0030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0258\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x0030,0x0030,0x0030,0x7ff0,\n  0x7ff0,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0259\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6000,0x7000,0x3f80,0x3f80,\n  0x7000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u025b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fe0,0x3ff0,0x3038,0x3018,0x3018,0x3018,0x3018,\n  0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3000,0x3000,0x3000,0x7000,0xe000,0x0000, // u0272\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x0070,0x00e0,0x01c0,0x0380,0x0700,\n  0x0fc0,0x0fe0,0x0070,0x0030,0x0030,0x0030,0x0030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000, // u0292\n  0x0300,0x0700,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bb\n  0x0300,0x0300,0x0700,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bc\n  0x0600,0x0600,0x0700,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bd\n  0x0700,0x0f80,0x1dc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02c6\n  0x1dc0,0x0f80,0x0700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02c7\n  0x18c0,0x1fc0,0x0f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02d8\n  0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02d9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0600,0x0600,0x07c0,0x03c0,0x0000, // u02db\n  0x1e60,0x3fe0,0x33c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02dc\n  0x0738,0x0e70,0x1ce0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02dd\n  0x1c00,0x0e00,0x0700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0300\n  0x01c0,0x0380,0x0700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0301\n  0x0700,0x0f80,0x1dc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0302\n  0x1e60,0x3fe0,0x33c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0303\n  0x1fc0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0304\n  0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0305\n  0x18c0,0x1fc0,0x0f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0306\n  0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0307\n  0x18c0,0x18c0,0x18c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0308\n  0x0780,0x0cc0,0x0cc0,0x0780,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030a\n  0x0738,0x0e70,0x1ce0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030b\n  0x1dc0,0x0f80,0x0700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u0329\n  0x0000,0x3800,0x7000,0xe000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0384\n  0x01c0,0x0380,0x0700,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0385\n  0x0000,0x3800,0x7000,0xe000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0386\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0387\n  0x0000,0x3800,0x7000,0xe000,0x3ff8,0x3ff8,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3fc0,0x3fc0,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3ff8,0x3ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0388\n  0x0000,0x3800,0x7000,0xe000,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3ff8,0x3ff8,0x3018,0x3018,\n  0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0389\n  0x0000,0x3800,0x7000,0xe000,0x0fc0,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u038a\n  0x0000,0x3800,0x7000,0xe000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u038c\n  0x0000,0x3800,0x7000,0xe000,0x300c,0x300c,0x1818,0x1818,0x0c30,0x0c30,0x0660,0x0660,0x03c0,0x03c0,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u038e\n  0x0000,0x3800,0x7000,0xe000,0x1fe0,0x3ff0,0x7038,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x7038,\n  0x3870,0x1ce0,0x0cc0,0x0cc0,0x7cf8,0x7cf8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u038f\n  0x0380,0x0700,0x0e00,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x1e00,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x07c0,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0390\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0391\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x7fc0,0x6060,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6070,0x7fe0,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0392\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0393\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0780,0x0780,0x0780,0x0cc0,0x0cc0,0x0cc0,0x1860,0x1860,0x1860,\n  0x3030,0x3030,0x3030,0x6018,0x7ff8,0x7ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0394\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x7f80,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0395\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x0030,0x0030,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,\n  0x7000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0396\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0397\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6fb0,0x6fb0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0398\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0399\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6070,0x60e0,0x61c0,0x6380,0x6700,0x6e00,0x7c00,0x7800,0x7800,0x7c00,0x6e00,\n  0x6700,0x6380,0x61c0,0x60e0,0x6070,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u039a\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0780,0x0780,0x0780,0x0cc0,0x0cc0,0x0cc0,0x1860,0x1860,0x1860,\n  0x3030,0x3030,0x3030,0x6018,0x6018,0x6018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u039b\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x7038,0x7878,0x7cf8,0x6fd8,0x6798,0x6318,0x6018,0x6018,0x6018,0x6018,\n  0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u039c\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x7030,0x7830,0x7c30,0x6e30,0x6730,0x63b0,0x61f0,0x60f0,\n  0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u039d\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x1fc0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u039e\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u039f\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a0\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6070,0x7fe0,0x7fc0,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a1\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x7000,0x3800,0x1c00,0x0e00,0x0700,0x0380,0x01c0,0x01c0,0x0380,0x0700,\n  0x0e00,0x1c00,0x3800,0x7000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a3\n  0x0000,0x0000,0x0000,0x0000,0x7ff8,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a4\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a5\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x1fe0,0x3ff0,0x7338,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,\n  0x6318,0x7338,0x3ff0,0x1fe0,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a6\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x3060,0x3060,0x18c0,0x18c0,0x0d80,0x0d80,0x0700,0x0700,0x0d80,0x0d80,\n  0x18c0,0x18c0,0x3060,0x3060,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a7\n  0x0000,0x0000,0x0000,0x0000,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x7338,\n  0x3ff0,0x1fe0,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a8\n  0x0000,0x0000,0x0000,0x0000,0x1fe0,0x3ff0,0x7038,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x7038,\n  0x3870,0x1ce0,0x0cc0,0x0cc0,0x7cf8,0x7cf8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a9\n  0x18c0,0x18c0,0x18c0,0x0000,0x0fc0,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03aa\n  0x18c0,0x18c0,0x18c0,0x0000,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ab\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x0380,0x0700,0x0000,0x1f98,0x3ff8,0x70f0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x70f0,0x3ff8,0x1f98,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ac\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x0380,0x0700,0x0000,0x1fc0,0x3fe0,0x7070,0x6000,0x7000,0x3f80,0x3f80,\n  0x7000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ad\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x0380,0x0700,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0000, // u03ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0700,0x0e00,0x0000,0x1e00,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x07c0,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03af\n  0x01c0,0x0380,0x0700,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f98,0x3ff8,0x70f0,0x6060,0x6060,0x6060,0x6060,\n  0x6060,0x6060,0x6060,0x70f0,0x3ff8,0x1f98,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b1\n  0x0000,0x0000,0x0000,0x0000,0x3f80,0x7fc0,0x60e0,0x6060,0x6060,0x6060,0x60e0,0x7fc0,0x7fc0,0x60e0,0x6070,0x6030,\n  0x6030,0x6030,0x6030,0x6070,0x7fe0,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000, // u03b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,\n  0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000, // u03b3\n  0x0000,0x0000,0x0000,0x0000,0x1fe0,0x1fe0,0x0e00,0x0700,0x0380,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6000,0x7000,0x3f80,0x3f80,\n  0x7000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b5\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,0x3000,0x7000,0x6000,\n  0x6000,0x6000,0x6000,0x7000,0x3fc0,0x1fe0,0x0070,0x0030,0x0030,0x00f0,0x00e0,0x0000, // u03b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0000, // u03b7\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x1fe0,0x3870,0x3030,0x3030,0x3030,0x3030,0x3030,0x3ff0,0x3ff0,0x3030,0x3030,\n  0x3030,0x3030,0x3030,0x3870,0x1fe0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x07c0,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3070,0x30e0,0x31c0,0x3380,0x3700,0x3e00,0x3c00,\n  0x3e00,0x3700,0x3380,0x31c0,0x30e0,0x3070,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ba\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x0c00,0x0c00,0x0600,0x0600,0x0700,0x0700,0x0d80,0x0d80,0x18c0,0x18c0,\n  0x3060,0x3060,0x3060,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6070,0x60f0,0x61f0,0x7fb0,0x7f30,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000, // u03bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x3060,0x3060,0x3060,0x18c0,\n  0x18c0,0x18c0,0x0d80,0x0d80,0x0700,0x0700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03bd\n  0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff0,0x7000,0x6000,0x6000,0x6000,0x3000,0x1fc0,0x1fc0,0x3800,0x7000,0x6000,\n  0x6000,0x6000,0x6000,0x7000,0x3fc0,0x1fe0,0x0070,0x0030,0x0030,0x00f0,0x00e0,0x0000, // u03be\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6070,0x7fe0,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000, // u03c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x7000,0x3fc0,0x1fe0,0x0070,0x0030,0x0030,0x00f0,0x00e0,0x0000, // u03c2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff8,0x3ff8,0x71c0,0x60e0,0x6070,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff8,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x03e0,0x01e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x19e0,0x3bf0,0x7338,0x6318,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x7338,0x3ff0,0x1fe0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000, // u03c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x3060,0x3060,0x18c0,0x18c0,0x0d80,\n  0x0d80,0x0700,0x0700,0x0d80,0x0d80,0x18c0,0x18c0,0x3060,0x3060,0x6030,0x6030,0x0000, // u03c7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x7338,0x3ff0,0x1fe0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000, // u03c8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1860,0x3870,0x7038,0x6018,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x77b8,0x3ff0,0x1ce0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3180,0x3180,0x3180,0x0000,0x1e00,0x1e00,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x07c0,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ca\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x0380,0x0700,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03cc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x0380,0x0700,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03cd\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x0380,0x0700,0x0000,0x1860,0x3870,0x7038,0x6018,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x77b8,0x3ff0,0x1ce0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ce\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x1fe0,0x3870,0x3030,0x3030,0x3030,0x3830,0x1ff8,0x0ff8,0x0030,0x0030,0xf030,\n  0xf030,0x3030,0x3030,0x3870,0x1fe0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x1fe0,0x3ff0,0x7338,0x6318,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x7338,0x3ff0,0x1fe0,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000, // u03d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7818,0x7c38,0x0e70,0x06e0,0x03c0,0x0380,0x0300,\n  0x0700,0x0f00,0x1d80,0x39c0,0x70f8,0x6078,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6070,0x7fe0,0x7fc0,0x6000,0x6000,0x7000,0x3fe0,0x1fe0,0x0000, // u03f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f2\n  0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0000,0x0000,0x01e0,0x01e0,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x3060,0x3060,0x38e0,0x1fc0,0x0f80,0x0000, // u03f3\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07f0,0x1ff0,0x3800,0x3000,0x6000,0x7fc0,0x7fc0,\n  0x6000,0x6000,0x3000,0x3800,0x1ff0,0x07f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x7fc0,0x00e0,0x0060,0x0030,0x1ff0,0x1ff0,\n  0x0030,0x0030,0x0060,0x00e0,0x7fc0,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f6\n  0x1c00,0x0e00,0x0700,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x7f80,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0400\n  0x18c0,0x18c0,0x18c0,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x7f80,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0401\n  0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x3000,0x3000,0x3000,0x3000,0x3fc0,0x3fe0,0x3070,0x3030,0x3030,0x3030,\n  0x3030,0x3030,0x3030,0x3070,0x31e0,0x31c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0402\n  0x01c0,0x0380,0x0700,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0403\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6000,0x6000,0x6000,0x6000,0x7f80,0x7f80,0x6000,0x6000,\n  0x6000,0x6000,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0404\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6000,0x6000,0x6000,0x7000,0x3fc0,0x1fe0,0x0070,0x0030,\n  0x0030,0x0030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0405\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0406\n  0x18c0,0x18c0,0x18c0,0x0000,0x0fc0,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0407\n  0x0000,0x0000,0x0000,0x0000,0x01f8,0x01f8,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x6060,0x6060,0x6060,0x70e0,0x3fc0,0x1f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0408\n  0x0000,0x0000,0x0000,0x0000,0x1f00,0x3f00,0x7300,0x6300,0x6300,0x6300,0x6300,0x63e0,0x63f0,0x6338,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x6338,0xe3f0,0xc3e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0409\n  0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x6300,0x6300,0x6300,0x6300,0x6300,0x63e0,0x7ff0,0x7f38,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x6338,0x63f0,0x63e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u040a\n  0x0000,0x0000,0x0000,0x0000,0xfc00,0xfc00,0x3000,0x3000,0x3000,0x3000,0x3fc0,0x3fe0,0x3070,0x3030,0x3030,0x3030,\n  0x3030,0x3030,0x3030,0x3030,0x3030,0x3030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u040b\n  0x01c0,0x0380,0x0700,0x0000,0x6030,0x6070,0x60e0,0x61c0,0x6380,0x6700,0x6e00,0x7c00,0x7800,0x7800,0x7c00,0x6e00,\n  0x6700,0x6380,0x61c0,0x60e0,0x6070,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u040c\n  0x1c00,0x0e00,0x0700,0x0000,0x6030,0x6030,0x6030,0x6030,0x6070,0x60f0,0x61f0,0x63b0,0x6730,0x6e30,0x7c30,0x7830,\n  0x7030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u040d\n  0x18c0,0x1fc0,0x0f80,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,\n  0x0030,0x0030,0x0030,0x0070,0x3fe0,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u040e\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,\n  0x6018,0x6018,0x6018,0x6018,0x7ff8,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000, // u040f\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0410\n  0x0000,0x0000,0x0000,0x0000,0x7fe0,0x7fe0,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6070,0x7fe0,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0411\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6060,0x7fc0,0x7fc0,0x6060,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6070,0x7fe0,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0412\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0413\n  0x0000,0x0000,0x0000,0x0000,0x07f0,0x0ff0,0x1c30,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,\n  0x1830,0x1830,0x1830,0x1830,0x3ff0,0x7ff8,0x6018,0x6018,0x6018,0x0000,0x0000,0x0000, // u0414\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x7f80,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0415\n  0x0000,0x0000,0x0000,0x0000,0x6318,0x6318,0x6318,0x6318,0x6318,0x7338,0x3b70,0x1fe0,0x0fc0,0x1fe0,0x3b70,0x7338,\n  0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0416\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x0030,0x0030,0x0030,0x0070,0x0fe0,0x0fe0,0x0070,0x0030,\n  0x0030,0x0030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0417\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6070,0x60f0,0x61f0,0x63b0,0x6730,0x6e30,0x7c30,0x7830,\n  0x7030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0418\n  0x18c0,0x1fc0,0x0f80,0x0000,0x6030,0x6030,0x6030,0x6030,0x6070,0x60f0,0x61f0,0x63b0,0x6730,0x6e30,0x7c30,0x7830,\n  0x7030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0419\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6070,0x60e0,0x61c0,0x6380,0x6700,0x6e00,0x7c00,0x7800,0x7800,0x7c00,0x6e00,\n  0x6700,0x6380,0x61c0,0x60e0,0x6070,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u041a\n  0x0000,0x0000,0x0000,0x0000,0x07f0,0x0ff0,0x1c30,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,\n  0x1830,0x1830,0x1830,0x1830,0x3830,0x7030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u041b\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x7038,0x7878,0x7cf8,0x6fd8,0x6798,0x6318,0x6018,0x6018,0x6018,0x6018,\n  0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u041c\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u041d\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u041e\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u041f\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6070,0x7fe0,0x7fc0,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0420\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0421\n  0x0000,0x0000,0x0000,0x0000,0x7ff8,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0422\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,\n  0x0030,0x0030,0x0030,0x0070,0x3fe0,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0423\n  0x0000,0x0000,0x0300,0x0300,0x1fe0,0x3ff0,0x7338,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x7338,0x3ff0,0x1fe0,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000, // u0424\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x3060,0x3060,0x18c0,0x18c0,0x0d80,0x0d80,0x0700,0x0700,0x0d80,0x0d80,\n  0x18c0,0x18c0,0x3060,0x3060,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0425\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff8,0x1ff8,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u0426\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0427\n  0x0000,0x0000,0x0000,0x0000,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x7318,0x3ff8,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0428\n  0x0000,0x0000,0x0000,0x0000,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x7318,0x3ffc,0x1ffc,0x000c,0x000c,0x000c,0x000c,0x0000,0x0000, // u0429\n  0x0000,0x0000,0x0000,0x0000,0xf000,0xf000,0x3000,0x3000,0x3000,0x3000,0x3fe0,0x3ff0,0x3038,0x3018,0x3018,0x3018,\n  0x3018,0x3018,0x3018,0x3038,0x3ff0,0x3fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u042a\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x7f18,0x7f98,0x61d8,0x60d8,0x60d8,0x60d8,\n  0x60d8,0x60d8,0x60d8,0x61d8,0x7f98,0x7f18,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u042b\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6070,0x7fe0,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u042c\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x0030,0x0030,0x0030,0x0030,0x0ff0,0x0ff0,0x0030,0x0030,\n  0x0030,0x0030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u042d\n  0x0000,0x0000,0x0000,0x0000,0x61e0,0x63f0,0x6738,0x6618,0x6618,0x6618,0x6618,0x6618,0x7e18,0x7e18,0x6618,0x6618,\n  0x6618,0x6618,0x6618,0x6738,0x63f0,0x61e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u042e\n  0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff0,0x7030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x01f0,\n  0x03b0,0x0730,0x0e30,0x1c30,0x3830,0x7030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u042f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x1fe0,0x0070,0x0030,0x1ff0,0x3ff0,0x7030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0430\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fc0,0x7000,0x6000,0x6000,0x6000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6070,0x7fe0,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0431\n  0x0000,0x0000,0x0000,0x0000,0x3f00,0x7f80,0x61c0,0x60c0,0x60c0,0x60c0,0x6180,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6070,0x7fe0,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0432\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0433\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff0,0x7030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,0x0030,0x0070,0x3fe0,0x3fc0,0x0000, // u0434\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x7ff0,0x7ff0,\n  0x6000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0435\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6318,0x6318,0x6318,0x7338,0x3b70,0x1fe0,0x0fc0,\n  0x1fe0,0x3b70,0x7338,0x6318,0x6318,0x6318,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0436\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x0030,0x0070,0x0fe0,0x0fe0,\n  0x0070,0x0030,0x0030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0437\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0438\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x1fc0,0x0f80,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0439\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3070,0x30e0,0x31c0,0x3380,0x3700,0x3e00,0x3c00,\n  0x3e00,0x3700,0x3380,0x31c0,0x30e0,0x3070,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u043a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07f0,0x0ff0,0x1c30,0x1830,0x1830,0x1830,0x1830,\n  0x1830,0x1830,0x1830,0x1830,0x3830,0x7030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u043b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6018,0x7038,0x7878,0x7cf8,0x6fd8,0x6798,0x6318,\n  0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u043c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u043d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u043e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u043f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6070,0x7fe0,0x7fc0,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000, // u0440\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0441\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff8,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0442\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,0x0030,0x0070,0x3fe0,0x3fc0,0x0000, // u0443\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x1fe0,0x3ff0,0x7338,0x6318,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x7338,0x3ff0,0x1fe0,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000, // u0444\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x7070,0x38e0,0x1dc0,0x0f80,0x0700,\n  0x0f80,0x1dc0,0x38e0,0x7070,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0445\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff8,0x1ff8,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u0446\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0447\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x7318,0x3ff8,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0448\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x7318,0x3ffc,0x1ffc,0x000c,0x000c,0x000c,0x000c,0x0000,0x0000, // u0449\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf000,0xf000,0x3000,0x3000,0x3fc0,0x3fe0,0x3070,\n  0x3030,0x3030,0x3030,0x3070,0x3fe0,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u044a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x6018,0x6018,0x7f18,0x7f98,0x61d8,\n  0x60d8,0x60d8,0x60d8,0x61d8,0x7f98,0x7f18,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u044b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3fc0,0x3fe0,0x3070,\n  0x3030,0x3030,0x3030,0x3070,0x3fe0,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u044c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x0030,0x0030,0x0ff0,0x0ff0,\n  0x0030,0x0030,0x0030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u044d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x61e0,0x63f0,0x6738,0x6618,0x6618,0x6618,0x7e18,\n  0x7e18,0x6618,0x6618,0x6738,0x63f0,0x61e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u044e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff0,0x7030,0x6030,0x6030,0x7030,0x3ff0,\n  0x1ff0,0x03b0,0x0730,0x0e30,0x1c30,0x3830,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u044f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0e00,0x0700,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x7ff0,0x7ff0,\n  0x6000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0450\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x7ff0,0x7ff0,\n  0x6000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0451\n  0x0000,0x0000,0x0000,0x0000,0x6000,0xff00,0xff00,0x6000,0x6000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0030,0x0030,0x0070,0x03e0,0x03c0,0x0000, // u0452\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x0380,0x0700,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0453\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6000,0x6000,0x7f80,0x7f80,\n  0x6000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0454\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6000,0x7000,0x3fc0,0x1fe0,\n  0x0070,0x0030,0x0030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0455\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000,0x0f00,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0456\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x0f00,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0457\n  0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0000,0x0000,0x01e0,0x01e0,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x3060,0x3060,0x38e0,0x1fc0,0x0f80,0x0000, // u0458\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3f00,0x7300,0x6300,0x63e0,0x63f0,0x6338,\n  0x6318,0x6318,0x6318,0x6338,0xe3f0,0xc3e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0459\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x6300,0x6300,0x63e0,0x7ff0,0x7f38,\n  0x6318,0x6318,0x6318,0x6338,0x63f0,0x63e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u045a\n  0x0000,0x0000,0x0000,0x0000,0x6000,0xff00,0xff00,0x6000,0x6000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u045b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x0380,0x0700,0x0000,0x3070,0x30e0,0x31c0,0x3380,0x3700,0x3e00,0x3c00,\n  0x3e00,0x3700,0x3380,0x31c0,0x30e0,0x3070,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u045c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0e00,0x0700,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u045d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x1fc0,0x0f80,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,0x0030,0x0070,0x3fe0,0x3fc0,0x0000, // u045e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,\n  0x6018,0x6018,0x6018,0x6018,0x7ff8,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000, // u045f\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0xff00,0xff00,0x3000,0x3000,0x3fe0,0x3ff0,0x3038,0x3018,0x3018,0x3018,\n  0x3018,0x3018,0x3018,0x3038,0x3ff0,0x3fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0462\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0xff00,0xff00,0x3000,0x3000,0x3000,0x3fc0,0x3fe0,0x3070,\n  0x3030,0x3030,0x3030,0x3070,0x3fe0,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0463\n  0x0000,0x0000,0x0000,0x0000,0x7ff8,0x7ff8,0x6018,0x7038,0x3870,0x1ce0,0x0fc0,0x0780,0x0fc0,0x1fe0,0x3b70,0x7338,\n  0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u046a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff8,0x7ff8,0x7038,0x3870,0x1ce0,0x0fc0,0x0fc0,\n  0x1fe0,0x3b70,0x7338,0x6318,0x6318,0x6318,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u046b\n  0x0000,0x0030,0x0030,0x0030,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0490\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0030,0x0030,0x0030,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0491\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0xff00,0xff00,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0492\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0xff00,\n  0xff00,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0493\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x7fe0,0x6070,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0030,0x0060,0x00c0,0x0000,0x0000,0x0000, // u0494\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x7f80,\n  0x7fc0,0x60e0,0x6060,0x6060,0x6060,0x6060,0x0060,0x00c0,0x0180,0x0000,0x0000,0x0000, // u0495\n  0x0000,0x0000,0x0000,0x0000,0x6318,0x6318,0x6318,0x6318,0x6318,0x7338,0x3b70,0x1fe0,0x0fc0,0x1fe0,0x3b70,0x7338,\n  0x6318,0x6318,0x6318,0x6318,0x631c,0x631c,0x000c,0x000c,0x000c,0x000c,0x0000,0x0000, // u0496\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6318,0x6318,0x6318,0x7338,0x3b70,0x1fe0,0x0fc0,\n  0x1fe0,0x3b70,0x7338,0x6318,0x631c,0x631c,0x000c,0x000c,0x000c,0x000c,0x0000,0x0000, // u0497\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x0030,0x0030,0x0030,0x0070,0x0fe0,0x0fe0,0x0070,0x0030,\n  0x0030,0x0030,0x6030,0x7070,0x3fe0,0x1fc0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000, // u0498\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x0030,0x0070,0x0fe0,0x0fe0,\n  0x0070,0x0030,0x0030,0x7070,0x3fe0,0x1fc0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000, // u0499\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6070,0x60e0,0x61c0,0x6380,0x6700,0x6e00,0x7c00,0x7800,0x7800,0x7c00,0x6e00,\n  0x6700,0x6380,0x61c0,0x60e0,0x6070,0x6038,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u049a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3070,0x30e0,0x31c0,0x3380,0x3700,0x3e00,0x3c00,\n  0x3e00,0x3700,0x3380,0x31c0,0x30e0,0x3070,0x0030,0x0030,0x0030,0x0030,0x0000,0x0000, // u049b\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x6038,0x6070,0x6ce0,0x6dc0,0x6f80,0x6f00,0x7e00,0x7e00,0x6f00,0x6f80,\n  0x6dc0,0x6ce0,0x6070,0x6038,0x6018,0x6018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u049c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6018,0x6038,0x6c70,0x6ce0,0x6dc0,0x7f80,0x7f00,\n  0x7f80,0x6dc0,0x6ce0,0x6c70,0x6038,0x6018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u049d\n  0x0000,0x0000,0x0000,0x0000,0xf018,0xf038,0x3070,0x30e0,0x31c0,0x3380,0x3700,0x3e00,0x3c00,0x3c00,0x3e00,0x3700,\n  0x3380,0x31c0,0x30e0,0x3070,0x3038,0x3018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf070,0xf0e0,0x31c0,0x3380,0x3700,0x3e00,0x3c00,\n  0x3e00,0x3700,0x3380,0x31c0,0x30e0,0x3070,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a1\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6038,0x6038,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u04a2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,\n  0x6030,0x6030,0x6030,0x6030,0x6038,0x6038,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u04a3\n  0x0000,0x0000,0x0000,0x0000,0x60fc,0x60fc,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7fc0,0x7fc0,0x60c0,0x60c0,\n  0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60fc,0x60fc,0x60c0,0x60c0,0x60c0,0x7fc0,0x7fc0,\n  0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a5\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000, // u04aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0600,0x0600,0x0600,0x0600,0x0600,0x0000, // u04ab\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,\n  0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000, // u04af\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x3ff0,\n  0x3ff0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,\n  0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x3ff0,0x3ff0,0x0300,0x0300,0x0300,0x0300,0x0000, // u04b1\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x3060,0x3060,0x18c0,0x18c0,0x0d80,0x0d80,0x0700,0x0700,0x0d80,0x0d80,\n  0x18c0,0x18c0,0x3060,0x3060,0x6038,0x6038,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u04b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x7070,0x38e0,0x1dc0,0x0f80,0x0700,\n  0x0f80,0x1dc0,0x38e0,0x7070,0x6038,0x6038,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u04b3\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0038,0x0038,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u04b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,\n  0x0030,0x0030,0x0030,0x0030,0x0038,0x0038,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u04b7\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6330,0x6330,0x6330,0x7330,0x3ff0,0x1ff0,0x0330,0x0330,\n  0x0330,0x0330,0x0030,0x0030,0x0030,0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6330,0x6330,0x7330,0x3ff0,0x1ff0,\n  0x0330,0x0330,0x0330,0x0030,0x0030,0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04b9\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x7fe0,\n  0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04bb\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04c0\n  0x18c0,0x1fc0,0x0f80,0x0000,0x6318,0x6318,0x6318,0x6318,0x6318,0x7338,0x3b70,0x1fe0,0x0fc0,0x1fe0,0x3b70,0x7338,\n  0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x1fc0,0x0f80,0x0000,0x6318,0x6318,0x6318,0x7338,0x3b70,0x1fe0,0x0fc0,\n  0x1fe0,0x3b70,0x7338,0x6318,0x6318,0x6318,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04c2\n  0x0000,0x0000,0x0000,0x0000,0x0f00,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04cf\n  0x18c0,0x1fc0,0x0f80,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x1fc0,0x0f80,0x0000,0x1fc0,0x1fe0,0x0070,0x0030,0x1ff0,0x3ff0,0x7030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d1\n  0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x1fe0,0x0070,0x0030,0x1ff0,0x3ff0,0x7030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d3\n  0x0000,0x0000,0x0000,0x0000,0x3ff8,0x7ff8,0xe300,0xc300,0xc300,0xc300,0xc300,0xc300,0xfff0,0xfff0,0xc300,0xc300,\n  0xc300,0xc300,0xc300,0xc300,0xc3f8,0xc3f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7de0,0x7ff0,0x0738,0x0318,0x3f18,0x7ff8,0xe3f8,\n  0xc300,0xc300,0xc300,0xe398,0x7ff8,0x3ef0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d5\n  0x18c0,0x1fc0,0x0f80,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x7f80,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x1fc0,0x0f80,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x7ff0,0x7ff0,\n  0x6000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d7\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x0030,0x0030,0x0030,0x0030,0x7ff0,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x0030,0x0030,0x0030,0x7ff0,\n  0x7ff0,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d9\n  0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x0030,0x0030,0x0030,0x0030,0x7ff0,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04da\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3fe0,0x7070,0x0030,0x0030,0x0030,0x7ff0,\n  0x7ff0,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04db\n  0x1860,0x1860,0x1860,0x0000,0x6318,0x6318,0x6318,0x6318,0x6318,0x7338,0x3b70,0x1fe0,0x0fc0,0x1fe0,0x3b70,0x7338,\n  0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04dc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1860,0x1860,0x1860,0x0000,0x6318,0x6318,0x6318,0x7338,0x3b70,0x1fe0,0x0fc0,\n  0x1fe0,0x3b70,0x7338,0x6318,0x6318,0x6318,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04dd\n  0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x0030,0x0030,0x0030,0x0070,0x0fe0,0x0fe0,0x0070,0x0030,\n  0x0030,0x0030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04de\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3fe0,0x7070,0x0030,0x0070,0x0fe0,0x0fe0,\n  0x0070,0x0030,0x0030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04df\n  0x1fc0,0x1fc0,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6070,0x60f0,0x61f0,0x63b0,0x6730,0x6e30,0x7c30,0x7830,\n  0x7030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x1fc0,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e3\n  0x18c0,0x18c0,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6070,0x60f0,0x61f0,0x63b0,0x6730,0x6e30,0x7c30,0x7830,\n  0x7030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e5\n  0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e7\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x7ff0,0x7ff0,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e9\n  0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x7ff0,0x7ff0,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04eb\n  0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x0030,0x0030,0x0030,0x0030,0x0ff0,0x0ff0,0x0030,0x0030,\n  0x0030,0x0030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ec\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x1fc0,0x3fe0,0x7070,0x0030,0x0030,0x0ff0,0x0ff0,\n  0x0030,0x0030,0x0030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ed\n  0x1fc0,0x1fc0,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,\n  0x0030,0x0030,0x0030,0x0070,0x3fe0,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ee\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x1fc0,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,0x0030,0x0070,0x3fe0,0x3fc0,0x0000, // u04ef\n  0x18c0,0x18c0,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,\n  0x0030,0x0030,0x0030,0x0070,0x3fe0,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,0x0030,0x0070,0x3fe0,0x3fc0,0x0000, // u04f1\n  0x0738,0x0e70,0x1ce0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,\n  0x0030,0x0030,0x0030,0x0070,0x3fe0,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0738,0x0e70,0x1ce0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,0x0030,0x0070,0x3fe0,0x3fc0,0x0000, // u04f3\n  0x18c0,0x18c0,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f5\n  0x18c0,0x18c0,0x18c0,0x0000,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x7f18,0x7f98,0x61d8,0x60d8,0x60d8,0x60d8,\n  0x60d8,0x60d8,0x60d8,0x61d8,0x7f98,0x7f18,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x0000,0x6018,0x6018,0x6018,0x6018,0x7f18,0x7f98,0x61d8,\n  0x60d8,0x60d8,0x60d8,0x61d8,0x7f98,0x7f18,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f9\n  0x0000,0x0000,0x0000,0x0000,0x3018,0x3018,0x1818,0x1818,0x0c18,0x0c18,0x0638,0x0e70,0x1fe0,0x3bc0,0x7180,0x6180,\n  0x60c0,0x60c0,0x6060,0x6060,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d0\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fe0,0x0070,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d1\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x3f00,0x0380,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0380,\n  0x07c0,0x0ec0,0x1c60,0x3860,0x7030,0xe030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d2\n  0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d3\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fe0,0x0070,0x0030,0x0030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d4\n  0x0000,0x0000,0x0000,0x0000,0x3c00,0x3e00,0x0700,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d5\n  0x0000,0x0000,0x0000,0x0000,0x1ff0,0x1ff0,0x00e0,0x01c0,0x0380,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d6\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d7\n  0x0000,0x0000,0x0000,0x0000,0x63c0,0x63e0,0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d8\n  0x0000,0x0000,0x0000,0x0000,0x3c00,0x3e00,0x0700,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d9\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fe0,0x0070,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0000,0x0000, // u05da\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fe0,0x0070,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0070,0x7fe0,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05db\n  0x0000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0030,0x0030,0x0030,0x0030,0x0030,0x0070,0x00e0,0x01c0,0x0380,0x0700,\n  0x0e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05dc\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05dd\n  0x0000,0x0000,0x0000,0x0000,0xe780,0xffe0,0x3870,0x3030,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,\n  0x3018,0x3018,0x3018,0x3018,0x30f8,0x30f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05de\n  0x0000,0x0000,0x0000,0x0000,0x3f00,0x3f80,0x01c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x0000,0x0000, // u05df\n  0x0000,0x0000,0x0000,0x0000,0x3f00,0x3f80,0x01c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x00c0,0x3fc0,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e0\n  0x0000,0x0000,0x0000,0x0000,0xffe0,0xfff0,0x3038,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,\n  0x3018,0x3018,0x3018,0x3838,0x1ff0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e1\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x3030,0x3030,0x3030,0x1830,0x1830,0x1860,0x0c60,0x0c60,0x0cc0,\n  0x06c0,0x06c0,0x0380,0x0700,0x7e00,0x7800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e2\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,0x7030,0x3e30,0x1e30,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0000,0x0000, // u05e3\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,0x7030,0x3e30,0x1e30,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0070,0x7fe0,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e4\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x3018,0x3018,0x1838,0x1870,0x0ce0,0x0dc0,0x0780,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000, // u05e5\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x3018,0x3018,0x1838,0x1870,0x0ce0,0x0dc0,0x0780,0x0300,0x0300,0x0180,\n  0x0180,0x00c0,0x00c0,0x0060,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e6\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x0030,0x0030,0x0030,0x6030,0x6030,0x6030,0x6070,0x60e0,0x61c0,0x6380,\n  0x6700,0x6600,0x6600,0x6600,0x6600,0x6600,0x6000,0x6000,0x6000,0x6000,0x0000,0x0000, // u05e7\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fe0,0x0070,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e8\n  0x0000,0x0000,0x0000,0x0000,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x6718,0x7e18,0x7c18,0x6018,\n  0x6018,0x6018,0x6018,0x6038,0x7ff0,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e9\n  0x0000,0x0000,0x0000,0x0000,0xffe0,0xfff0,0x3038,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,\n  0x3018,0x3018,0x3018,0x3018,0xf018,0xe018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05ea\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x7fc0,0x60e0,0x6060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6060,0x60e0,0x7fc0,0x7f00,0x0000,0x0600,0x0600,0x0600,0x0000,0x0000, // u1e0c\n  0x0000,0x0000,0x0000,0x0000,0x0030,0x0030,0x0030,0x0030,0x0030,0x1ff0,0x3ff0,0x7030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1e0d\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6070,0x60e0,0x61c0,0x6380,0x6700,0x6e00,0x7c00,0x7800,0x7800,0x7c00,0x6e00,\n  0x6700,0x6380,0x61c0,0x60e0,0x6070,0x6030,0x0000,0x0000,0x3fe0,0x3fe0,0x0000,0x0000, // u1e34\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3070,0x30e0,0x31c0,0x3380,0x3700,0x3e00,0x3c00,\n  0x3e00,0x3700,0x3380,0x31c0,0x30e0,0x3070,0x0000,0x0000,0x1fe0,0x1fe0,0x0000,0x0000, // u1e35\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1e36\n  0x0000,0x0000,0x0000,0x0000,0x0f00,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1e37\n  0x0300,0x0300,0x0300,0x0000,0x6018,0x6018,0x7038,0x7878,0x7cf8,0x6fd8,0x6798,0x6318,0x6018,0x6018,0x6018,0x6018,\n  0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e40\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0000,0x7fe0,0x7ff0,0x6338,0x6318,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e41\n  0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x7038,0x7878,0x7cf8,0x6fd8,0x6798,0x6318,0x6018,0x6018,0x6018,0x6018,\n  0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1e42\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x7ff0,0x6338,0x6318,0x6318,0x6318,0x6318,\n  0x6318,0x6318,0x6318,0x6318,0x6318,0x6318,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1e43\n  0x0300,0x0300,0x0300,0x0000,0x6030,0x6030,0x6030,0x6030,0x7030,0x7830,0x7c30,0x6e30,0x6730,0x63b0,0x61f0,0x60f0,\n  0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e44\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e45\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x7030,0x7830,0x7c30,0x6e30,0x6730,0x63b0,0x61f0,0x60f0,\n  0x6070,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1e46\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1e47\n  0x0000,0x0000,0x0000,0x0000,0x7ff8,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1e6c\n  0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0600,0x3fc0,0x3fc0,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x07e0,0x03e0,0x0000,0x0180,0x0180,0x0180,0x0000,0x0000, // u1e6d\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x7f80,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1eb8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x7ff0,0x7ff0,\n  0x6000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1eb9\n  0x1e60,0x3fe0,0x33c0,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x7f80,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1ebc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1e60,0x3fe0,0x33c0,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x7ff0,0x7ff0,\n  0x6000,0x6000,0x6000,0x7070,0x3fe0,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1ebd\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1eca\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000,0x0f00,0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1ecb\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1ecc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x7070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1ecd\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7070,0x3fe0,0x1fc0,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1ee4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0000,0x0300,0x0300,0x0300,0x0000,0x0000, // u1ee5\n  0x1e60,0x3fe0,0x33c0,0x0000,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1ef8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1e60,0x3fe0,0x33c0,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x7030,0x3ff0,0x1ff0,0x0030,0x0030,0x0070,0x3fe0,0x3fc0,0x0000, // u1ef9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2001\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2002\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2003\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2004\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2005\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2006\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2007\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2008\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2009\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2010\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2011\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2012\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2013\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff8,0x7ff8,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2014\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff8,0x7ff8,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2015\n  0x0000,0x0000,0x0000,0x0000,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2016\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x0000,0x7ff0,0x7ff0, // u2017\n  0x0000,0x0000,0x0300,0x0300,0x0600,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2018\n  0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2019\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u201a\n  0x0000,0x0000,0x0600,0x0600,0x0600,0x0600,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201b\n  0x0000,0x0000,0x0c60,0x0c60,0x18c0,0x18c0,0x18c0,0x18c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201c\n  0x0000,0x0000,0x0c60,0x0c60,0x0c60,0x0c60,0x18c0,0x18c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x18c0,0x3180,0x3180,0x0000,0x0000,0x0000,0x0000, // u201e\n  0x0000,0x0000,0x3180,0x3180,0x3180,0x3180,0x18c0,0x18c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201f\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x3ff0,0x3ff0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2020\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x3ff0,0x3ff0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x3ff0,0x3ff0,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2021\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0780,0x0fc0,0x0fc0,0x0fc0,0x0fc0,\n  0x0780,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2022\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x6318,0x6318,0x6318,0x6318,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2026\n  0x0000,0x0000,0x0000,0x0000,0x38c0,0x7cc0,0x6d80,0x7d80,0x3b00,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x1800,0x1800,\n  0x3000,0x3770,0x6ff8,0x6dd8,0xcff8,0xc770,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2030\n  0x0000,0x0000,0x0380,0x0380,0x0380,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2032\n  0x0000,0x0000,0x1ce0,0x1ce0,0x1ce0,0x18c0,0x18c0,0x18c0,0x18c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2033\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,\n  0x1c00,0x0e00,0x0700,0x0380,0x01c0,0x00e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x1c00,0x0e00,0x0700,0x0380,0x01c0,0x00e0,\n  0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u203a\n  0x0000,0x0000,0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,\n  0x0000,0x0000,0x18c0,0x18c0,0x18c0,0x18c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u203c\n  0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u203e\n  0x0000,0x0000,0x0f80,0x1fc0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x1fc0,0x0f80,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2070\n  0x0300,0x0300,0x0000,0x0700,0x0700,0x0300,0x0300,0x0300,0x0300,0x0300,0x0780,0x0780,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2071\n  0x0000,0x0000,0x00c0,0x01c0,0x03c0,0x07c0,0x0ec0,0x1cc0,0x1fc0,0x1fc0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2074\n  0x0000,0x0000,0x1f80,0x1f80,0x1800,0x1800,0x1f80,0x1fc0,0x00c0,0x00c0,0x1fc0,0x0f80,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2075\n  0x0000,0x0000,0x0780,0x0f80,0x1800,0x1800,0x1f80,0x1fc0,0x18c0,0x18c0,0x1fc0,0x0f80,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2076\n  0x0000,0x0000,0x1fc0,0x1fc0,0x00c0,0x0180,0x0180,0x0300,0x0300,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2077\n  0x0000,0x0000,0x0f80,0x1fc0,0x18c0,0x18c0,0x0f80,0x1fc0,0x18c0,0x18c0,0x1fc0,0x0f80,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2078\n  0x0000,0x0000,0x0f80,0x1fc0,0x18c0,0x18c0,0x1fc0,0x0fc0,0x00c0,0x00c0,0x0f80,0x0f00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2079\n  0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x1fe0,0x1fe0,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fe0,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207b\n  0x0000,0x0000,0x0000,0x0000,0x1fe0,0x1fe0,0x0000,0x0000,0x1fe0,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207c\n  0x0000,0x0000,0x0180,0x0300,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0300,0x0180,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207d\n  0x0000,0x0000,0x0600,0x0300,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0300,0x0600,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207e\n  0x0000,0x0000,0x0000,0x1fc0,0x1fe0,0x1860,0x1860,0x1860,0x1860,0x1860,0x1860,0x1860,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f80,0x1fc0,\n  0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x18c0,0x1fc0,0x0f80,0x0000,0x0000,0x0000,0x0000, // u2080\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0700,\n  0x0f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000, // u2081\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f80,0x1fc0,\n  0x18c0,0x00c0,0x01c0,0x0380,0x0700,0x0e00,0x1fc0,0x1fc0,0x0000,0x0000,0x0000,0x0000, // u2082\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f80,0x1fc0,\n  0x00c0,0x00c0,0x0780,0x07c0,0x00c0,0x00c0,0x1fc0,0x0f80,0x0000,0x0000,0x0000,0x0000, // u2083\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x01c0,\n  0x03c0,0x07c0,0x0ec0,0x1cc0,0x1fc0,0x1fc0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000, // u2084\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x1f80,\n  0x1800,0x1800,0x1f80,0x1fc0,0x00c0,0x00c0,0x1fc0,0x0f80,0x0000,0x0000,0x0000,0x0000, // u2085\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0780,0x0f80,\n  0x1800,0x1800,0x1f80,0x1fc0,0x18c0,0x18c0,0x1fc0,0x0f80,0x0000,0x0000,0x0000,0x0000, // u2086\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x1fc0,\n  0x00c0,0x0180,0x0180,0x0300,0x0300,0x0600,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000, // u2087\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f80,0x1fc0,\n  0x18c0,0x18c0,0x0f80,0x1fc0,0x18c0,0x18c0,0x1fc0,0x0f80,0x0000,0x0000,0x0000,0x0000, // u2088\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f80,0x1fc0,\n  0x18c0,0x18c0,0x1fc0,0x0fc0,0x00c0,0x00c0,0x0f80,0x0f00,0x0000,0x0000,0x0000,0x0000, // u2089\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,\n  0x0300,0x0300,0x1fe0,0x1fe0,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000, // u208a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1fe0,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u208b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x1fe0,0x1fe0,0x0000,0x0000,0x1fe0,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u208c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0300,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0300,0x0180,0x0000,0x0000,0x0000,0x0000, // u208d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0300,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0300,0x0600,0x0000,0x0000,0x0000,0x0000, // u208e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,\n  0x0fe0,0x0060,0x0fe0,0x1fe0,0x1860,0x1860,0x1fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000, // u2090\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,\n  0x1fe0,0x1860,0x1fe0,0x1fe0,0x1800,0x1800,0x1fe0,0x0fc0,0x0000,0x0000,0x0000,0x0000, // u2091\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,\n  0x1fe0,0x1860,0x1860,0x1860,0x1860,0x1860,0x1fe0,0x0fc0,0x0000,0x0000,0x0000,0x0000, // u2092\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1860,\n  0x1860,0x1ce0,0x0fc0,0x0780,0x0fc0,0x1ce0,0x1860,0x1860,0x0000,0x0000,0x0000,0x0000, // u2093\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,\n  0x1fe0,0x0060,0x0060,0x1fe0,0x1fe0,0x1860,0x1fe0,0x0fc0,0x0000,0x0000,0x0000,0x0000, // u2094\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x1fc0,\n  0x1fe0,0x1860,0x1860,0x1860,0x1860,0x1860,0x1860,0x1860,0x0000,0x0000,0x0000,0x0000, // u2095\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x18e0,\n  0x19c0,0x1b80,0x1f00,0x1e00,0x1f00,0x1b80,0x19c0,0x18e0,0x0000,0x0000,0x0000,0x0000, // u2096\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0700,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0780,0x0780,0x0000,0x0000,0x0000,0x0000, // u2097\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fe0,\n  0x3ff0,0x3330,0x3330,0x3330,0x3330,0x3330,0x3330,0x3330,0x0000,0x0000,0x0000,0x0000, // u2098\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,\n  0x1fe0,0x1860,0x1860,0x1860,0x1860,0x1860,0x1fe0,0x1fc0,0x1800,0x1800,0x1800,0x0000, // u209a\n  0x0000,0x0000,0x0000,0x0000,0xfe00,0xff00,0xc380,0xc180,0xc180,0xc180,0xc180,0xc380,0xff60,0xfe60,0xc1f8,0xc1f8,\n  0xc060,0xc060,0xc060,0xc060,0xc078,0xc038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u20a7\n  0x0000,0x0000,0x0000,0x0000,0xfe18,0xff18,0xc398,0xc198,0xc198,0xcd98,0xcd98,0xcd98,0xcd98,0xcd98,0xcd98,0xcd98,\n  0xcd98,0xcc18,0xcc18,0xcc38,0xcff0,0xcfe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u20aa\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x1fe0,0x3870,0x7000,0x6000,0x6000,0xff80,0xff80,0x6000,0x6000,0xff80,0xff80,\n  0x6000,0x6000,0x7000,0x3870,0x1fe0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u20ac\n  0x0000,0x0000,0x0000,0x0000,0x7ff8,0x7ff8,0x0300,0x0300,0x0300,0x0300,0x03f0,0x03c0,0x0f00,0x3ff0,0x03c0,0x0f00,\n  0x3f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u20ae\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3c60,0x6c30,0x6c30,0x6c30,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,0x6c00,\n  0x6c00,0x6c30,0x6c30,0x6c30,0x3c60,0x1fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2102\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u210e\n  0x0000,0x0000,0x0000,0x0000,0x6000,0xff00,0xff00,0x6000,0x6000,0x7fc0,0x7fe0,0x6070,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u210f\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x7030,0x7830,0x6c30,0x7630,0x7b30,0x6db0,0x66f0,0x6370,0x61b0,\n  0x60f0,0x6070,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2115\n  0x0000,0x0000,0x0000,0x0000,0xc300,0xc338,0xc37c,0xc36c,0xe37c,0xe338,0xf300,0xf300,0xdb00,0xdb00,0xcf00,0xcf00,\n  0xc77c,0xc77c,0xc300,0xc37c,0xc37c,0xc300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2116\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3c60,0x6c30,0x6c30,0x6c30,0x6c30,0x6c30,0x6c30,0x6c30,0x6c30,0x6c30,0x6c30,\n  0x6c30,0x6c30,0x6c30,0x6db0,0x3de0,0x1fc0,0x0060,0x0030,0x0000,0x0000,0x0000,0x0000, // u211a\n  0x0000,0x0000,0x0000,0x0000,0x7fc0,0x6c60,0x6c30,0x6c30,0x6c30,0x6c30,0x6c30,0x6c30,0x6c60,0x6fc0,0x6f00,0x6d80,\n  0x6ec0,0x6f60,0x6db0,0x6cd8,0x6c68,0x7c38,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u211d\n  0x0000,0x0000,0x0000,0x0000,0xfd04,0xfd8c,0x31fc,0x31ac,0x318c,0x318c,0x318c,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2122\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x0030,0x0030,0x0070,0x00f0,0x01b0,0x0360,0x06c0,0x0d80,0x1b00,0x3600,0x6c00,\n  0x7800,0x7000,0x6000,0x6000,0x6000,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2124\n  0x0000,0x0000,0x0000,0x0000,0x1fe0,0x3ff0,0x7038,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x7038,\n  0x3870,0x1ce0,0x0cc0,0x0cc0,0x7cf8,0x7cf8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2126\n  0x0000,0x0000,0x0000,0x0000,0x60c0,0x60c0,0x3060,0x3060,0x1830,0x1830,0x0c18,0x1c38,0x3e70,0x76e0,0xe3c0,0xc380,\n  0xc180,0xc180,0xc0c0,0xe0c0,0x7060,0x3860,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2135\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0c00,0x1c00,0x3800,0x7000,0xfff8,0xfff8,0x7000,\n  0x3800,0x1c00,0x0c00,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2190\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0780,0x0fc0,0x1fe0,0x3b70,0x7338,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2191\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0180,0x01c0,0x00e0,0x0070,0xfff8,0xfff8,0x0070,\n  0x00e0,0x01c0,0x0180,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2192\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x7338,0x3b70,0x1fe0,0x0fc0,0x0780,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2193\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0480,0x0cc0,0x1ce0,0x3870,0x7038,0xfffc,0xfffc,0x7038,\n  0x3870,0x1ce0,0x0cc0,0x0480,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2194\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0780,0x0fc0,0x1fe0,0x3b70,0x7338,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x7338,0x3b70,0x1fe0,0x0fc0,0x0780,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2195\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0418,0x0c18,0x1c18,0x3818,0x7018,0xfff8,0xfff8,0x7018,\n  0x3818,0x1c18,0x0c18,0x0418,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc100,0xc180,0xc1c0,0xc0e0,0xc070,0xfff8,0xfff8,0xc070,\n  0xc0e0,0xc1c0,0xc180,0xc100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a6\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0780,0x0fc0,0x1fe0,0x3b70,0x7338,0x0300,0x0300,0x0300,0x0300,0x0300,0x7338,\n  0x3b70,0x1fe0,0x0fc0,0x0780,0x7ff8,0x7ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a8\n  0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0418,0x0c18,0x1c18,0x3818,0x7018,0xfff8,\n  0xfff8,0x7000,0x3800,0x1c00,0x0c00,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e00,0x7e00,0x1e00,0x3e30,0x7638,0x6618,0x6018,0x6018,0x6018,\n  0x7038,0x3870,0x1fe0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x1800,0x3800,0x7000,0xfff8,0xfff8,0x0000,0x0000,0xfff8,\n  0xfff8,0x0070,0x00e0,0x00c0,0x0080,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x00c0,0x00e0,0x0070,0xfff8,0xfff8,0x0000,0x0000,0xfff8,\n  0xfff8,0x7000,0x3800,0x1800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21cc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0400,0x0c00,0x1c00,0x3ff8,0x7ff8,0xf000,0xf000,0x7ff8,\n  0x3ff8,0x1c00,0x0c00,0x0400,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d0\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0780,0x0fc0,0x1fe0,0x3cf0,0x7cf8,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0180,0x01c0,0xffe0,0xfff0,0x0078,0x0078,0xfff0,\n  0xffe0,0x01c0,0x0180,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d2\n  0x0000,0x0000,0x0000,0x0000,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,\n  0x7cf8,0x3cf0,0x1fe0,0x0fc0,0x0780,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0480,0x0cc0,0x1ce0,0x3ff0,0x7ff8,0xf03c,0xf03c,0x7ff8,\n  0x3ff0,0x1ce0,0x0cc0,0x0480,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d4\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0780,0x0fc0,0x1fe0,0x3cf0,0x7cf8,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,\n  0x7cf8,0x3cf0,0x1fe0,0x0fc0,0x0780,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d5\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x3060,0x3fe0,0x3fe0,0x3060,0x18c0,0x18c0,0x18c0,0x18c0,\n  0x0d80,0x0d80,0x0d80,0x0700,0x0700,0x0700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2200\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x7ff0,0x7ff0,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2203\n  0x0000,0x0000,0x0030,0x0030,0x7ff0,0x7ff0,0x00f0,0x00f0,0x01b0,0x01b0,0x0330,0x0330,0x7ff0,0x7ff0,0x0630,0x0c30,\n  0x0c30,0x1830,0x1830,0x3030,0x7ff0,0x7ff0,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000, // u2204\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x1fc0,0x3fe0,0x71f0,0x61b0,0x6330,0x6330,0x6630,0x6630,0x6c30,\n  0x7c70,0x3fe0,0x1fc0,0x3800,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2205\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0780,0x0780,0x0780,0x0cc0,0x0cc0,0x0cc0,0x1860,0x1860,0x1860,\n  0x3030,0x3030,0x3030,0x6018,0x7ff8,0x7ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2206\n  0x0000,0x0000,0x0000,0x0000,0x7ff8,0x7ff8,0x6018,0x3030,0x3030,0x3030,0x1860,0x1860,0x1860,0x0cc0,0x0cc0,0x0cc0,\n  0x0780,0x0780,0x0780,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2207\n  0x0000,0x0000,0x0000,0x0000,0x07f0,0x1ff0,0x3800,0x3000,0x6000,0x6000,0x6000,0x6000,0x7ff0,0x7ff0,0x6000,0x6000,\n  0x6000,0x6000,0x3000,0x3800,0x1ff0,0x07f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2208\n  0x0000,0x0000,0x0018,0x0018,0x07f0,0x1ff0,0x3860,0x3060,0x60c0,0x60c0,0x6180,0x6180,0x7ff0,0x7ff0,0x6300,0x6300,\n  0x6600,0x6600,0x3c00,0x3c00,0x1ff0,0x1ff0,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000, // u2209\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07f0,0x1ff0,0x3800,0x3000,0x6000,0x6000,0x7ff0,0x7ff0,0x6000,0x6000,\n  0x3000,0x3800,0x1ff0,0x07f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u220a\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x7fc0,0x00e0,0x0060,0x0030,0x0030,0x0030,0x0030,0x7ff0,0x7ff0,0x0030,0x0030,\n  0x0030,0x0030,0x0060,0x00e0,0x7fc0,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u220b\n  0x0000,0x0000,0x6000,0x6000,0x3f80,0x3fe0,0x1870,0x1830,0x0c18,0x0c18,0x0618,0x0618,0x3ff8,0x3ff8,0x0318,0x0318,\n  0x0198,0x0198,0x00f0,0x00f0,0x3fe0,0x3fe0,0x0030,0x0030,0x0000,0x0000,0x0000,0x0000, // u220c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x7fc0,0x00e0,0x0060,0x0030,0x0030,0x7ff0,0x7ff0,0x0030,0x0030,\n  0x0060,0x00e0,0x7fc0,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u220d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2212\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff8,0x7ff8,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x7ff8,\n  0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2213\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x7ff8,\n  0x7ff8,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2214\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0038,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,\n  0x3800,0x7000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2215\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x7000,0x3800,0x1c00,0x0e00,0x0700,0x0380,0x01c0,0x00e0,\n  0x0070,0x0038,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2216\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0f80,0x0f80,0x0f80,0x0700,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2219\n  0x0000,0x0000,0x0078,0x0078,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x6060,0x6060,0x6060,0x7060,\n  0x3860,0x1c60,0x0e60,0x0760,0x03e0,0x01e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u221a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ce0,0x3ff0,0x77b8,0x6318,0x6318,0x6318,0x77b8,\n  0x3ff0,0x1ce0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u221e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u221f\n  0x0000,0x0000,0x0000,0x0000,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2225\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0780,0x0780,0x0cc0,0x0cc0,0x1860,\n  0x1860,0x1860,0x3030,0x3030,0x6018,0x6018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2227\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,0x1860,\n  0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2228\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f80,0x1fc0,0x38e0,0x3060,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2229\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x3060,0x38e0,0x1fc0,0x0f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u222a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e18,0x3f38,0x73f0,0x61e0,0x0000,0x1e18,0x3f38,\n  0x73f0,0x60e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2248\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0070,0x7ff8,0x7ff8,0x01c0,0x0380,0x0700,0x0e00,0x7ff8,\n  0x7ff8,0x3800,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2260\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x0000,0x0000,\n  0x0000,0x0000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2261\n  0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,0x1c00,0x0e00,0x0700,0x0380,\n  0x01c0,0x00e0,0x0070,0x0000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2264\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x3800,0x1c00,0x0e00,0x0700,0x0380,0x01c0,0x00e0,0x01c0,0x0380,0x0700,0x0e00,\n  0x1c00,0x3800,0x7000,0x0000,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2265\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x018c,0x039c,0x0738,0x0e70,0x1ce0,0x39c0,0x7380,0xe700,0xe700,0x7380,0x39c0,\n  0x1ce0,0x0e70,0x0738,0x039c,0x018c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u226a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xc600,0xe700,0x7380,0x39c0,0x1ce0,0x0e70,0x0738,0x039c,0x039c,0x0738,0x0e70,\n  0x1ce0,0x39c0,0x7380,0xe700,0xc600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u226b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07f8,0x1ff8,0x3800,0x7000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x7000,0x3800,0x1ff8,0x07f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2282\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x7fe0,0x0070,0x0038,0x0018,0x0018,0x0018,0x0018,0x0018,\n  0x0038,0x0070,0x7fe0,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2283\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x07f8,0x1ff8,0x3800,0x7000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7000,0x3800,\n  0x1ff8,0x07f8,0x0000,0x0000,0x7ff8,0x7ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2286\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x7fe0,0x0070,0x0038,0x0018,0x0018,0x0018,0x0018,0x0018,0x0038,0x0070,\n  0x7fe0,0x7f80,0x0000,0x0000,0x7ff8,0x7ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2287\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x7ff8,0x7ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u22a5\n  0x0000,0x0000,0x0000,0x0000,0x0f80,0x1fc0,0x38e0,0x3060,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u22c2\n  0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x3060,0x38e0,0x1fc0,0x0f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u22c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x1fc0,0x3fe0,0x71f0,0x61b0,0x6330,0x6330,0x6630,0x6630,0x6c30,\n  0x7c70,0x3fe0,0x1fc0,0x3800,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2300\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0780,0x0fc0,0x1ce0,0x3870,0x7038,0x6018,0x6018,0x6018,\n  0x6018,0x6018,0x6018,0x6018,0x7ff8,0x7ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2302\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fc0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2308\n  0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fc0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2309\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u230a\n  0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x00c0,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u230b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2310\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7ff0,\n  0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2319\n  0x0000,0x0000,0x0000,0x0000,0x01f0,0x03f8,0x0318,0x0318,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2320\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x6300,0x6300,0x7f00,0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2321\n  0x0030,0x0060,0x00c0,0x0180,0x0300,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x0c00,0x1800,0x1800,0x1800,0x1800,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000, // u239b\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000, // u239c\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x1800,0x1800,0x1800,\n  0x1800,0x0c00,0x0c00,0x0c00,0x0600,0x0600,0x0300,0x0300,0x0180,0x00c0,0x0060,0x0030, // u239d\n  0x3000,0x1800,0x0c00,0x0600,0x0300,0x0300,0x0180,0x0180,0x00c0,0x00c0,0x00c0,0x0060,0x0060,0x0060,0x0060,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030, // u239e\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030, // u239f\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0060,0x0060,0x0060,\n  0x0060,0x00c0,0x00c0,0x00c0,0x0180,0x0180,0x0300,0x0300,0x0600,0x0c00,0x1800,0x3000, // u23a0\n  0x3ff0,0x3ff0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000, // u23a1\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000, // u23a2\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ff0,0x3ff0, // u23a3\n  0x3ff0,0x3ff0,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030, // u23a4\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030, // u23a5\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x3ff0,0x3ff0, // u23a6\n  0x00f8,0x03f8,0x0700,0x0600,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u23a7\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x1800,0xf000,0xf000,0x1800,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00, // u23a8\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0600,0x0700,0x03f8,0x00f8, // u23a9\n  0xf800,0xfe00,0x0700,0x0300,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u23ab\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x00c0,0x0078,0x0078,0x00c0,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u23ac\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0300,0x0700,0xfe00,0xf800, // u23ad\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u23ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23af\n  0xfffc,0xfffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0xfffc,0xfffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc, // u23bd\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u23d0\n  0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x6300,0x7f00,0x7f00,0x6300,0x6300,0x6300,0x0000,0x0000,0x07f8,0x07f8,\n  0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2409\n  0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f00,0x7f00,0x0000,0x0000,0x03f8,0x03f8,\n  0x0300,0x03e0,0x03e0,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u240a\n  0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x6300,0x6300,0x6300,0x3600,0x1c00,0x0800,0x0000,0x0000,0x07f8,0x07f8,\n  0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u240b\n  0x0000,0x0000,0x0000,0x0000,0x7f00,0x7f00,0x6000,0x7c00,0x7c00,0x6000,0x6000,0x6000,0x0000,0x0000,0x03f8,0x03f8,\n  0x0300,0x03e0,0x03e0,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u240c\n  0x0000,0x0000,0x0000,0x0000,0x3e00,0x7f00,0x6300,0x6000,0x6000,0x6300,0x7f00,0x3e00,0x0000,0x0000,0x03f0,0x03f8,\n  0x0318,0x0318,0x03f0,0x03e0,0x0330,0x0318,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u240d\n  0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x7300,0x7b00,0x6f00,0x6700,0x6300,0x6300,0x0000,0x0000,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x03f8,0x03f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2424\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2500\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0xfffc,0xfffc,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2501\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2502\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u2503\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xedd8,0xedd8,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2508\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xedd8,0xedd8,0xedd8,0xedd8,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2509\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000, // u250a\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0000,0x0000,0x0780,0x0780,0x0780,0x0780,0x0780,0x0000,0x0000,0x0780,0x0780,\n  0x0780,0x0780,0x0780,0x0000,0x0000,0x0780,0x0780,0x0780,0x0780,0x0780,0x0000,0x0000, // u250b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03fc,0x03fc,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u250c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03fc,0x03fc,0x03fc,0x03fc,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u250d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07fc,0x07fc,0x0780,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u250e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07fc,0x07fc,0x07fc,0x07fc,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u250f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2510\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0xff00,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2511\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,0xff80,0x0780,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u2512\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,0xff80,0xff80,0xff80,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u2513\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x03fc,0x03fc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2514\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x03fc,0x03fc,0x03fc,0x03fc,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2515\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x07fc,0x07fc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2516\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x07fc,0x07fc,0x07fc,0x07fc,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2517\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xff00,0xff00,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2518\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xff00,0xff00,0xff00,0xff00,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2519\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0xff80,0xff80,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u251a\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0xff80,0xff80,0xff80,0xff80,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u251b\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x03fc,0x03fc,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u251c\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x03fc,0x03fc,0x03fc,0x03fc,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u251d\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x07fc,0x07fc,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u251e\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x07fc,0x07fc,0x0780,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u251f\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x07fc,0x07fc,0x0780,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u2520\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x07fc,0x07fc,0x07fc,0x07fc,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2521\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x07fc,0x07fc,0x07fc,0x07fc,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u2522\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x07fc,0x07fc,0x07fc,0x07fc,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u2523\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xff00,0xff00,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2524\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xff00,0xff00,0xff00,0xff00,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2525\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0xff80,0xff80,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2526\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xff80,0xff80,0x0780,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u2527\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0xff80,0xff80,0x0780,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u2528\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0xff80,0xff80,0xff80,0xff80,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2529\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xff80,0xff80,0xff80,0xff80,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u252a\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0xff80,0xff80,0xff80,0xff80,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u252b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u252c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xfffc,0xfffc,0xff00,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u252d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03fc,0xfffc,0xfffc,0x03fc,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u252e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0xfffc,0xfffc,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u252f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0x0780,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u2530\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,0xfffc,0xfffc,0xff80,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u2531\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07fc,0xfffc,0xfffc,0x07fc,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u2532\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0xfffc,0xfffc,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u2533\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xfffc,0xfffc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2534\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xff00,0xfffc,0xfffc,0xff00,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2535\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x03fc,0xfffc,0xfffc,0x03fc,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2536\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xfffc,0xfffc,0xfffc,0xfffc,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2537\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0xfffc,0xfffc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2538\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0xff80,0xfffc,0xfffc,0xff80,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2539\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x07fc,0xfffc,0xfffc,0x07fc,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u253a\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0xfffc,0xfffc,0xfffc,0xfffc,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u253b\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xfffc,0xfffc,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u253c\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xff00,0xfffc,0xfffc,0xff00,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u253d\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x03fc,0xfffc,0xfffc,0x03fc,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u253e\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xfffc,0xfffc,0xfffc,0xfffc,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u253f\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0xfffc,0xfffc,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2540\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xfffc,0xfffc,0x0780,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u2541\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0xfffc,0xfffc,0x0780,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u2542\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0xff80,0xfffc,0xfffc,0xff00,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2543\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x07fc,0xfffc,0xfffc,0x03fc,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2544\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xff00,0xfffc,0xfffc,0xff80,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u2545\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x03fc,0xfffc,0xfffc,0x07fc,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u2546\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0xfffc,0xfffc,0xfffc,0xfffc,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2547\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xfffc,0xfffc,0xfffc,0xfffc,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u2548\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0xff80,0xfffc,0xfffc,0xff80,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u2549\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x07fc,0xfffc,0xfffc,0x07fc,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u254a\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0xfffc,0xfffc,0xfffc,0xfffc,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u254b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0x0000,0x0000,0xfffc,\n  0xfffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2550\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0, // u2551\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03fc,0x03fc,0x0300,0x0300,0x03fc,\n  0x03fc,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2552\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ffc,0x0ffc,0x0cc0,\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0, // u2553\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ffc,0x0ffc,0x0c00,0x0c00,0x0cfc,\n  0x0cfc,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0, // u2554\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x0300,0x0300,0xff00,\n  0xff00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2555\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x0cc0,\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0, // u2556\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0x00c0,0x00c0,0xfcc0,\n  0xfcc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0, // u2557\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x03fc,0x03fc,0x0300,0x0300,0x03fc,\n  0x03fc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2558\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0ffc,0x0ffc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2559\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cfc,0x0cfc,0x0c00,0x0c00,0x0ffc,\n  0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255a\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xff00,0xff00,0x0300,0x0300,0xff00,\n  0xff00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255b\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0xffc0,0xffc0,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255c\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0xfcc0,0xfcc0,0x00c0,0x00c0,0xffc0,\n  0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255d\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x03fc,0x03fc,0x0300,0x0300,0x03fc,\n  0x03fc,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u255e\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cfc,0x0cfc,0x0cc0,\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0, // u255f\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cfc,0x0cfc,0x0c00,0x0c00,0x0cfc,\n  0x0cfc,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0, // u2560\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xff00,0xff00,0x0300,0x0300,0xff00,\n  0xff00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2561\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0xfcc0,0xfcc0,0x0cc0,\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0, // u2562\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0xfcc0,0xfcc0,0x00c0,0x00c0,0xfcc0,\n  0xfcc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0, // u2563\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0x0000,0x0000,0xfffc,\n  0xfffc,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2564\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0x0cc0,\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0, // u2565\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0x0000,0x0000,0xfcfc,\n  0xfcfc,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0, // u2566\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xfffc,0xfffc,0x0000,0x0000,0xfffc,\n  0xfffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2567\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0xfffc,0xfffc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2568\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0xfcfc,0xfcfc,0x0000,0x0000,0xfffc,\n  0xfffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2569\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0xfffc,0xfffc,0x0300,0x0300,0xfffc,\n  0xfffc,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u256a\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0xfffc,0xfffc,0x0cc0,\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0, // u256b\n  0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0xfcfc,0xfcfc,0x0000,0x0000,0xfcfc,\n  0xfcfc,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0,0x0cc0, // u256c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x001c,0x007c,0x00e0,\n  0x01c0,0x0180,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u256d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xe000,0xf800,0x1c00,\n  0x0e00,0x0600,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u256e\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0600,0x0e00,0x1c00,0xf800,0xe000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u256f\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0180,0x01c0,0x00e0,0x007c,0x001c,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2570\n  0x0004,0x000c,0x000c,0x0018,0x0018,0x0030,0x0030,0x0060,0x0060,0x00c0,0x00c0,0x0180,0x0180,0x0300,0x0300,0x0600,\n  0x0600,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x6000,0x6000,0xc000,0xc000,0x8000, // u2571\n  0x8000,0xc000,0xc000,0x6000,0x6000,0x3000,0x3000,0x1800,0x1800,0x0c00,0x0c00,0x0600,0x0600,0x0300,0x0300,0x0180,\n  0x0180,0x00c0,0x00c0,0x0060,0x0060,0x0030,0x0030,0x0018,0x0018,0x000c,0x000c,0x0004, // u2572\n  0x8004,0xc00c,0xc00c,0x6018,0x6018,0x3030,0x3030,0x1860,0x1860,0x0cc0,0x0cc0,0x0780,0x0780,0x0300,0x0300,0x0780,\n  0x0780,0x0cc0,0x0cc0,0x1860,0x1860,0x3030,0x3030,0x6018,0x6018,0xc00c,0xc00c,0x8004, // u2573\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2574\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2575\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03fc,0x03fc,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2576\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u2577\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0xff00,0xff00,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2578\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2579\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03fc,0x03fc,0x03fc,0x03fc,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0780,0x0780,0x0780,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u257b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03fc,0xfffc,0xfffc,0x03fc,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257c\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0780,0x0780,0x0780,\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780, // u257d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xfffc,0xfffc,0xff00,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257e\n  0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0780,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300, // u257f\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2580\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0xfffc,0xfffc, // u2581\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc, // u2582\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc, // u2583\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc, // u2584\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc, // u2585\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc, // u2586\n  0x0000,0x0000,0x0000,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc, // u2587\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc, // u2588\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0, // u2589\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,\n  0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0,0xffe0, // u258a\n  0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,\n  0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80,0xff80, // u258b\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00, // u258c\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,\n  0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800,0xf800, // u258d\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000, // u258e\n  0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,\n  0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000, // u258f\n  0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,\n  0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc, // u2590\n  0xaaa8,0x0000,0xaaa8,0x0000,0xaaa8,0x0000,0xaaa8,0x0000,0xaaa8,0x0000,0xaaa8,0x0000,0xaaa8,0x0000,0xaaa8,0x0000,\n  0xaaa8,0x0000,0xaaa8,0x0000,0xaaa8,0x0000,0xaaa8,0x0000,0xaaa8,0x0000,0xaaa8,0x0000, // u2591\n  0xaaa8,0x5554,0xaaa8,0x5554,0xaaa8,0x5554,0xaaa8,0x5554,0xaaa8,0x5554,0xaaa8,0x5554,0xaaa8,0x5554,0xaaa8,0x5554,\n  0xaaa8,0x5554,0xaaa8,0x5554,0xaaa8,0x5554,0xaaa8,0x5554,0xaaa8,0x5554,0xaaa8,0x5554, // u2592\n  0xfffc,0xaaa8,0xfffc,0xaaa8,0xfffc,0xaaa8,0xfffc,0xaaa8,0xfffc,0xaaa8,0xfffc,0xaaa8,0xfffc,0xaaa8,0xfffc,0xaaa8,\n  0xfffc,0xaaa8,0xfffc,0xaaa8,0xfffc,0xaaa8,0xfffc,0xaaa8,0xfffc,0xaaa8,0xfffc,0xaaa8, // u2593\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfe00,0xfe00,\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00, // u2596\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01fc,0x01fc,\n  0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc, // u2597\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2598\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfffc,0xfffc,\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc, // u2599\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0x01fc,0x01fc,\n  0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc, // u259a\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfe00,0xfe00,\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00, // u259b\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0x01fc,0x01fc,\n  0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc, // u259c\n  0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u259d\n  0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0xfe00,0xfe00,\n  0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00,0xfe00, // u259e\n  0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0x01fc,0xfffc,0xfffc,\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc, // u259f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fe0,0x3fe0,0x3fe0,0x3fe0,0x3fe0,0x3fe0,0x3fe0,0x3fe0,\n  0x3fe0,0x3fe0,0x3fe0,0x3fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff8,\n  0x7ff8,0x7ff8,0x7ff8,0x7ff8,0x7ff8,0x7ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ac\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x7ff0,0x7ff0,0x7ff0,0x7ff0,0x7ff0,0x7ff0,0x7ff0,0x7ff0,0x7ff0,0x7ff0,\n  0x7ff0,0x7ff0,0x7ff0,0x7ff0,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0780,0x0780,0x0fc0,0x0fc0,0x1fe0,0x1fe0,0x3ff0,\n  0x3ff0,0x7ff8,0x7ff8,0xfffc,0xfffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xffc0,0xfff0,0xfffc,0xfffc,0xfff0,\n  0xffc0,0xff00,0xfc00,0xf000,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xffc0,0xfff0,0xfffc,0xfffc,0xfff0,\n  0xffc0,0xff00,0xfc00,0xf000,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffc,0xfffc,0x7ff8,0x7ff8,0x3ff0,0x3ff0,0x1fe0,0x1fe0,0x0fc0,\n  0x0fc0,0x0780,0x0780,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000c,0x003c,0x00fc,0x03fc,0x0ffc,0x3ffc,0xfffc,0xfffc,0x3ffc,\n  0x0ffc,0x03fc,0x00fc,0x003c,0x000c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000c,0x003c,0x00fc,0x03fc,0x0ffc,0x3ffc,0xfffc,0xfffc,0x3ffc,\n  0x0ffc,0x03fc,0x00fc,0x003c,0x000c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0200,0x0700,0x0f80,0x1fc0,0x3fe0,0x7ff0,0xfff8,0xfff8,0x7ff0,\n  0x3fe0,0x1fc0,0x0f80,0x0700,0x0200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0200,0x0700,0x0f80,0x1dc0,0x38e0,0x7070,0xe038,0xe038,0x7070,\n  0x38e0,0x1dc0,0x0f80,0x0700,0x0200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ca\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0780,0x0fc0,0x0cc0,0x0cc0,0x0fc0,\n  0x0780,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0780,0x0fc0,0x0fc0,0x0fc0,0x0fc0,\n  0x0780,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25cf\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xf87c,0xf03c,0xf03c,0xf03c,0xf03c,\n  0xf87c,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc, // u25d8\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xf87c,0xf03c,0xf33c,0xf33c,0xf03c,\n  0xf87c,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc, // u25d9\n  0x0000,0x0000,0x0000,0x0000,0x3fe0,0x7ff0,0xc018,0xc018,0xc018,0xddd8,0xddd8,0xc018,0xc018,0xc018,0xc018,0xdfd8,\n  0xcf98,0xc018,0xc018,0xc018,0x7ff0,0x3fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u263a\n  0x0000,0x0000,0x0000,0x0000,0x3fe0,0x7ff0,0xfff8,0xfff8,0xfff8,0xc718,0xc718,0xfff8,0xfff8,0xfff8,0xfff8,0xc018,\n  0xe038,0xfff8,0xfff8,0xfff8,0x7ff0,0x3fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u263b\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x6318,0x7338,0x3b70,0x1fe0,0x0fc0,0x7cf8,0x7cf8,0x0fc0,0x1fe0,\n  0x3b70,0x7338,0x6318,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u263c\n  0x0000,0x0000,0x0000,0x0000,0x1fe0,0x3ff0,0x7038,0x6018,0x6018,0x6018,0x6018,0x6018,0x7038,0x3ff0,0x1fe0,0x0300,\n  0x0300,0x7ff8,0x7ff8,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2640\n  0x0000,0x0000,0x0000,0x0000,0x03f8,0x03f8,0x0078,0x00f8,0x01d8,0x0398,0x0718,0x3f80,0x7fc0,0xe0e0,0xc060,0xc060,\n  0xc060,0xc060,0xc060,0xe0e0,0x7fc0,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2642\n  0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0780,0x0fc0,0x1fe0,0x3ff0,0x3ff0,0x7ff8,0x7ff8,0x7ff8,0x7ff8,0x7ff8,\n  0x7b78,0x3b70,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2660\n  0x0000,0x0000,0x0000,0x0000,0x0780,0x0fc0,0x0fc0,0x0fc0,0x0fc0,0x0780,0x0300,0x3b70,0x7ff8,0x7ff8,0x7ff8,0x7ff8,\n  0x7ff8,0x3b70,0x0300,0x0300,0x0fc0,0x0fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2663\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x78f0,0xfdf8,0xfdf8,0xfff8,0xfff8,0xfff8,0xfff8,0x7ff0,0x7ff0,\n  0x3fe0,0x1fc0,0x0f80,0x0700,0x0200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2665\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0200,0x0700,0x0f80,0x1fc0,0x3fe0,0x7ff0,0xfff8,0xfff8,0x7ff0,\n  0x3fe0,0x1fc0,0x0f80,0x0700,0x0200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2666\n  0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff0,0x3030,0x3030,0x3030,0x3ff0,0x3ff0,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0xf000,0xe000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u266a\n  0x0000,0x0000,0x0000,0x0000,0x7ff8,0x7ff8,0x6018,0x6018,0x6018,0x7ff8,0x7ff8,0x6018,0x6018,0x6018,0x6018,0x6018,\n  0x6018,0x6018,0x6018,0x6078,0xe070,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u266b\n  0x0000,0x0000,0x0000,0x0000,0x000c,0x000c,0x0018,0x0018,0x0030,0x0030,0x0060,0x0060,0xc0c0,0xc0c0,0x6180,0x6180,\n  0x3300,0x3300,0x1e00,0x1e00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2713\n  0x0000,0x0000,0x0000,0x0000,0x001c,0x001c,0x0038,0x0038,0x0070,0x0070,0x00e0,0x00e0,0xc1c0,0xc1c0,0xe380,0xe380,\n  0x7700,0x7700,0x3e00,0x3e00,0x1c00,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2714\n  0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x00c0,0x60c0,0x3180,0x1980,0x0f00,0x0700,0x0700,0x0780,0x0cc0,0x0c60,\n  0x1830,0x1800,0x3000,0x3000,0x6000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2717\n  0x0000,0x0000,0x0000,0x0000,0x00e0,0x00e0,0xe1c0,0x71c0,0x3b80,0x1f80,0x0f00,0x0700,0x0f80,0x0fc0,0x1ce0,0x1c70,\n  0x3830,0x3800,0x7000,0x7000,0xe000,0xe000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2718\n  0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x0180,0x0180,0x0300,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x0600,0x0600,\n  0x0300,0x0300,0x0180,0x0180,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u27e8\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0600,0x0600,0x0300,0x0300,0x0180,0x0180,0x00c0,0x00c0,0x0180,0x0180,\n  0x0300,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u27e9\n  0x0000,0x0000,0x0000,0x0000,0x0630,0x0630,0x0c60,0x0c60,0x18c0,0x18c0,0x3180,0x3180,0x6300,0x6300,0x3180,0x3180,\n  0x18c0,0x18c0,0x0c60,0x0c60,0x0630,0x0630,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u27ea\n  0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x3180,0x3180,0x18c0,0x18c0,0x0c60,0x0c60,0x0630,0x0630,0x0c60,0x0c60,\n  0x18c0,0x18c0,0x3180,0x3180,0x6300,0x6300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u27eb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2800\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2801\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2802\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2803\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2804\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2805\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2806\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2807\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2808\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2809\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280a\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280b\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280c\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280d\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280e\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2810\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2811\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2812\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2813\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2814\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2815\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2816\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2817\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2818\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2819\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281a\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281b\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281c\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281d\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281e\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2820\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2821\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2822\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2823\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2824\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2825\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2826\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2827\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2828\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2829\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282a\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282b\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282c\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282d\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282e\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2830\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2831\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2832\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2833\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2834\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2835\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2836\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2837\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2838\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2839\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283a\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283b\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283c\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283d\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283e\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2840\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2841\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2842\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2843\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2844\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2845\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2846\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2847\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2848\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2849\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u284a\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u284b\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u284c\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u284d\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u284e\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u284f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2850\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2851\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2852\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2853\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2854\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2855\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2856\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2857\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2858\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2859\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u285a\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u285b\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u285c\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u285d\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u285e\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u285f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2860\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2861\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2862\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2863\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2864\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2865\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2866\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2867\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2868\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2869\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u286a\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u286b\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u286c\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u286d\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u286e\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u286f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2870\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2871\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2872\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2873\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2874\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2875\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2876\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2877\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2878\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u2879\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u287a\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u287b\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u287c\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u287d\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u287e\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000, // u287f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2880\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2881\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2882\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2883\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2884\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2885\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2886\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2887\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2888\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2889\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u288a\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u288b\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u288c\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u288d\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u288e\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u288f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2890\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2891\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2892\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2893\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2894\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2895\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2896\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2897\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2898\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u2899\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u289a\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u289b\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u289c\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u289d\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u289e\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u289f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28a0\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28a2\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28a4\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28a5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28a6\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28a7\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28a8\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28a9\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28aa\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28ab\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28ac\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28ad\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28ae\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28af\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28b0\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28b1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28b2\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28b4\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28b6\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28b7\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28b8\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28b9\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28ba\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28bb\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28bc\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28bd\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28be\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000, // u28bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28c0\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28c2\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28c4\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28c6\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28c7\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28c8\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28c9\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28ca\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28cb\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28cc\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28cd\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28ce\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28cf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28d0\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28d2\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28d4\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28d6\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28d7\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28d8\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28d9\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28da\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28db\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28dc\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28dd\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28de\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,\n  0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28df\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28e0\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28e1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28e2\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28e3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28e4\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28e6\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28e7\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28e8\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28e9\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28ea\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28eb\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28ec\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28ed\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28ee\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28ef\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28f0\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28f2\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28f3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28f4\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28f6\n  0x0000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28f7\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28f8\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28f9\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28fa\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,\n  0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28fb\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28fc\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28fd\n  0x0000,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28fe\n  0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,\n  0x3060,0x3060,0x3060,0x0000,0x0000,0x0000,0x3060,0x3060,0x3060,0x3060,0x0000,0x0000, // u28ff\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x6030,0x6030,0x6030,0x6030,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2e2c\n  0xc000,0xc000,0xc000,0xc180,0xc3c0,0xc7e0,0xcff0,0xddb8,0xc180,0xc180,0xc180,0xc180,0xc180,0xc300,0x8600,0x0c00,\n  0x1800,0x3000,0x6000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000, // ue0a0\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x7f80,0x0000,0x0000,0x0618,\n  0x0618,0x0718,0x0798,0x07d8,0x06f8,0x0678,0x0638,0x0618,0x0618,0x0000,0x0000,0x0000, // ue0a1\n  0x0000,0x0000,0x0000,0x0f80,0x1fc0,0x3060,0x3060,0x3060,0x3060,0x3060,0x3060,0x3060,0x7ff0,0xfff8,0xfff8,0xfff8,\n  0xf8f8,0xf078,0xf078,0xf078,0xf8f8,0xfff8,0xfff8,0xfff8,0xfff8,0x0000,0x0000,0x0000, // ue0a2\n  0x8000,0xc000,0xe000,0xf000,0xf800,0xfc00,0xfe00,0xff00,0xff80,0xffc0,0xffe0,0xfff0,0xfff8,0xfffc,0xfffc,0xfff8,\n  0xfff0,0xffe0,0xffc0,0xff80,0xff00,0xfe00,0xfc00,0xf800,0xf000,0xe000,0xc000,0x8000, // ue0b0\n  0x8000,0xc000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x00c0,0x0060,0x0030,0x0018,0x000c,0x000c,0x0018,\n  0x0030,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0x8000, // ue0b1\n  0x0004,0x000c,0x001c,0x003c,0x007c,0x00fc,0x01fc,0x03fc,0x07fc,0x0ffc,0x1ffc,0x3ffc,0x7ffc,0xfffc,0xfffc,0x7ffc,\n  0x3ffc,0x1ffc,0x0ffc,0x07fc,0x03fc,0x01fc,0x00fc,0x007c,0x003c,0x001c,0x000c,0x0004, // ue0b2\n  0x0004,0x000c,0x0018,0x0030,0x0060,0x00c0,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0xc000,0xc000,0x6000,\n  0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x00c0,0x0060,0x0030,0x0018,0x000c,0x0004, // ue0b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01e0,0x01e0,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x3060,0x3060,0x38e0,0x1fc0,0x0f80,0x0000, // uf6be\n  0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff0,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x7ff0,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 // ufffd\n  };\n  // codepoints array\n  constexpr std::array<uint16_t, CHARCOUNT> fixedfont_codepoints = {\n  0x0000,0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,\n  0x002f,0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,\n  0x003f,0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,\n  0x004f,0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,\n  0x005f,0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,\n  0x006f,0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,\n  0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af,\n  0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf,\n  0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf,\n  0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df,\n  0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef,\n  0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff,\n  0x0100,0x0101,0x0102,0x0103,0x0104,0x0105,0x0106,0x0107,0x0108,0x0109,0x010a,0x010b,0x010c,0x010d,0x010e,0x010f,\n  0x0110,0x0111,0x0112,0x0113,0x0114,0x0115,0x0116,0x0117,0x0118,0x0119,0x011a,0x011b,0x011c,0x011d,0x011e,0x011f,\n  0x0120,0x0121,0x0122,0x0123,0x0124,0x0125,0x0126,0x0127,0x0128,0x0129,0x012a,0x012b,0x012c,0x012d,0x012e,0x012f,\n  0x0130,0x0131,0x0132,0x0133,0x0134,0x0135,0x0136,0x0137,0x0138,0x0139,0x013a,0x013b,0x013c,0x013d,0x013e,0x013f,\n  0x0140,0x0141,0x0142,0x0143,0x0144,0x0145,0x0146,0x0147,0x0148,0x0149,0x014a,0x014b,0x014c,0x014d,0x014e,0x014f,\n  0x0150,0x0151,0x0152,0x0153,0x0154,0x0155,0x0156,0x0157,0x0158,0x0159,0x015a,0x015b,0x015c,0x015d,0x015e,0x015f,\n  0x0160,0x0161,0x0162,0x0163,0x0164,0x0165,0x0166,0x0167,0x0168,0x0169,0x016a,0x016b,0x016c,0x016d,0x016e,0x016f,\n  0x0170,0x0171,0x0172,0x0173,0x0174,0x0175,0x0176,0x0177,0x0178,0x0179,0x017a,0x017b,0x017c,0x017d,0x017e,0x017f,\n  0x0186,0x018e,0x018f,0x0190,0x0192,0x019d,0x019e,0x01b5,0x01b6,0x01b7,0x01cd,0x01ce,0x01cf,0x01d0,0x01d1,0x01d2,\n  0x01d3,0x01d4,0x01e2,0x01e3,0x01e4,0x01e5,0x01e6,0x01e7,0x01e8,0x01e9,0x01ea,0x01eb,0x01ec,0x01ed,0x01ee,0x01ef,\n  0x01f0,0x01f4,0x01f5,0x01fc,0x01fd,0x01fe,0x01ff,0x0218,0x0219,0x021a,0x021b,0x0232,0x0233,0x0237,0x0254,0x0258,\n  0x0259,0x025b,0x0272,0x0292,0x02bb,0x02bc,0x02bd,0x02c6,0x02c7,0x02d8,0x02d9,0x02db,0x02dc,0x02dd,0x0300,0x0301,\n  0x0302,0x0303,0x0304,0x0305,0x0306,0x0307,0x0308,0x030a,0x030b,0x030c,0x0329,0x0384,0x0385,0x0386,0x0387,0x0388,\n  0x0389,0x038a,0x038c,0x038e,0x038f,0x0390,0x0391,0x0392,0x0393,0x0394,0x0395,0x0396,0x0397,0x0398,0x0399,0x039a,\n  0x039b,0x039c,0x039d,0x039e,0x039f,0x03a0,0x03a1,0x03a3,0x03a4,0x03a5,0x03a6,0x03a7,0x03a8,0x03a9,0x03aa,0x03ab,\n  0x03ac,0x03ad,0x03ae,0x03af,0x03b0,0x03b1,0x03b2,0x03b3,0x03b4,0x03b5,0x03b6,0x03b7,0x03b8,0x03b9,0x03ba,0x03bb,\n  0x03bc,0x03bd,0x03be,0x03bf,0x03c0,0x03c1,0x03c2,0x03c3,0x03c4,0x03c5,0x03c6,0x03c7,0x03c8,0x03c9,0x03ca,0x03cb,\n  0x03cc,0x03cd,0x03ce,0x03d1,0x03d5,0x03f0,0x03f1,0x03f2,0x03f3,0x03f4,0x03f5,0x03f6,0x0400,0x0401,0x0402,0x0403,\n  0x0404,0x0405,0x0406,0x0407,0x0408,0x0409,0x040a,0x040b,0x040c,0x040d,0x040e,0x040f,0x0410,0x0411,0x0412,0x0413,\n  0x0414,0x0415,0x0416,0x0417,0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e,0x041f,0x0420,0x0421,0x0422,0x0423,\n  0x0424,0x0425,0x0426,0x0427,0x0428,0x0429,0x042a,0x042b,0x042c,0x042d,0x042e,0x042f,0x0430,0x0431,0x0432,0x0433,\n  0x0434,0x0435,0x0436,0x0437,0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e,0x043f,0x0440,0x0441,0x0442,0x0443,\n  0x0444,0x0445,0x0446,0x0447,0x0448,0x0449,0x044a,0x044b,0x044c,0x044d,0x044e,0x044f,0x0450,0x0451,0x0452,0x0453,\n  0x0454,0x0455,0x0456,0x0457,0x0458,0x0459,0x045a,0x045b,0x045c,0x045d,0x045e,0x045f,0x0462,0x0463,0x046a,0x046b,\n  0x0490,0x0491,0x0492,0x0493,0x0494,0x0495,0x0496,0x0497,0x0498,0x0499,0x049a,0x049b,0x049c,0x049d,0x04a0,0x04a1,\n  0x04a2,0x04a3,0x04a4,0x04a5,0x04aa,0x04ab,0x04ae,0x04af,0x04b0,0x04b1,0x04b2,0x04b3,0x04b6,0x04b7,0x04b8,0x04b9,\n  0x04ba,0x04bb,0x04c0,0x04c1,0x04c2,0x04cf,0x04d0,0x04d1,0x04d2,0x04d3,0x04d4,0x04d5,0x04d6,0x04d7,0x04d8,0x04d9,\n  0x04da,0x04db,0x04dc,0x04dd,0x04de,0x04df,0x04e2,0x04e3,0x04e4,0x04e5,0x04e6,0x04e7,0x04e8,0x04e9,0x04ea,0x04eb,\n  0x04ec,0x04ed,0x04ee,0x04ef,0x04f0,0x04f1,0x04f2,0x04f3,0x04f4,0x04f5,0x04f8,0x04f9,0x05d0,0x05d1,0x05d2,0x05d3,\n  0x05d4,0x05d5,0x05d6,0x05d7,0x05d8,0x05d9,0x05da,0x05db,0x05dc,0x05dd,0x05de,0x05df,0x05e0,0x05e1,0x05e2,0x05e3,\n  0x05e4,0x05e5,0x05e6,0x05e7,0x05e8,0x05e9,0x05ea,0x1e0c,0x1e0d,0x1e34,0x1e35,0x1e36,0x1e37,0x1e40,0x1e41,0x1e42,\n  0x1e43,0x1e44,0x1e45,0x1e46,0x1e47,0x1e6c,0x1e6d,0x1eb8,0x1eb9,0x1ebc,0x1ebd,0x1eca,0x1ecb,0x1ecc,0x1ecd,0x1ee4,\n  0x1ee5,0x1ef8,0x1ef9,0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007,0x2008,0x2009,0x200a,0x200b,0x200c,\n  0x200d,0x200e,0x200f,0x2010,0x2011,0x2012,0x2013,0x2014,0x2015,0x2016,0x2017,0x2018,0x2019,0x201a,0x201b,0x201c,\n  0x201d,0x201e,0x201f,0x2020,0x2021,0x2022,0x2026,0x2030,0x2032,0x2033,0x2039,0x203a,0x203c,0x203e,0x2070,0x2071,\n  0x2074,0x2075,0x2076,0x2077,0x2078,0x2079,0x207a,0x207b,0x207c,0x207d,0x207e,0x207f,0x2080,0x2081,0x2082,0x2083,\n  0x2084,0x2085,0x2086,0x2087,0x2088,0x2089,0x208a,0x208b,0x208c,0x208d,0x208e,0x2090,0x2091,0x2092,0x2093,0x2094,\n  0x2095,0x2096,0x2097,0x2098,0x209a,0x20a7,0x20aa,0x20ac,0x20ae,0x2102,0x210e,0x210f,0x2115,0x2116,0x211a,0x211d,\n  0x2122,0x2124,0x2126,0x2135,0x2190,0x2191,0x2192,0x2193,0x2194,0x2195,0x21a4,0x21a6,0x21a8,0x21b5,0x21bb,0x21cb,\n  0x21cc,0x21d0,0x21d1,0x21d2,0x21d3,0x21d4,0x21d5,0x2200,0x2203,0x2204,0x2205,0x2206,0x2207,0x2208,0x2209,0x220a,\n  0x220b,0x220c,0x220d,0x2212,0x2213,0x2214,0x2215,0x2216,0x2219,0x221a,0x221e,0x221f,0x2225,0x2227,0x2228,0x2229,\n  0x222a,0x2248,0x2260,0x2261,0x2264,0x2265,0x226a,0x226b,0x2282,0x2283,0x2286,0x2287,0x22a5,0x22c2,0x22c3,0x2300,\n  0x2302,0x2308,0x2309,0x230a,0x230b,0x2310,0x2319,0x2320,0x2321,0x239b,0x239c,0x239d,0x239e,0x239f,0x23a0,0x23a1,\n  0x23a2,0x23a3,0x23a4,0x23a5,0x23a6,0x23a7,0x23a8,0x23a9,0x23ab,0x23ac,0x23ad,0x23ae,0x23af,0x23ba,0x23bb,0x23bc,\n  0x23bd,0x23d0,0x2409,0x240a,0x240b,0x240c,0x240d,0x2424,0x2500,0x2501,0x2502,0x2503,0x2508,0x2509,0x250a,0x250b,\n  0x250c,0x250d,0x250e,0x250f,0x2510,0x2511,0x2512,0x2513,0x2514,0x2515,0x2516,0x2517,0x2518,0x2519,0x251a,0x251b,\n  0x251c,0x251d,0x251e,0x251f,0x2520,0x2521,0x2522,0x2523,0x2524,0x2525,0x2526,0x2527,0x2528,0x2529,0x252a,0x252b,\n  0x252c,0x252d,0x252e,0x252f,0x2530,0x2531,0x2532,0x2533,0x2534,0x2535,0x2536,0x2537,0x2538,0x2539,0x253a,0x253b,\n  0x253c,0x253d,0x253e,0x253f,0x2540,0x2541,0x2542,0x2543,0x2544,0x2545,0x2546,0x2547,0x2548,0x2549,0x254a,0x254b,\n  0x2550,0x2551,0x2552,0x2553,0x2554,0x2555,0x2556,0x2557,0x2558,0x2559,0x255a,0x255b,0x255c,0x255d,0x255e,0x255f,\n  0x2560,0x2561,0x2562,0x2563,0x2564,0x2565,0x2566,0x2567,0x2568,0x2569,0x256a,0x256b,0x256c,0x256d,0x256e,0x256f,\n  0x2570,0x2571,0x2572,0x2573,0x2574,0x2575,0x2576,0x2577,0x2578,0x2579,0x257a,0x257b,0x257c,0x257d,0x257e,0x257f,\n  0x2580,0x2581,0x2582,0x2583,0x2584,0x2585,0x2586,0x2587,0x2588,0x2589,0x258a,0x258b,0x258c,0x258d,0x258e,0x258f,\n  0x2590,0x2591,0x2592,0x2593,0x2596,0x2597,0x2598,0x2599,0x259a,0x259b,0x259c,0x259d,0x259e,0x259f,0x25a0,0x25ac,\n  0x25ae,0x25b2,0x25b6,0x25ba,0x25bc,0x25c0,0x25c4,0x25c6,0x25ca,0x25cb,0x25cf,0x25d8,0x25d9,0x263a,0x263b,0x263c,\n  0x2640,0x2642,0x2660,0x2663,0x2665,0x2666,0x266a,0x266b,0x2713,0x2714,0x2717,0x2718,0x27e8,0x27e9,0x27ea,0x27eb,\n  0x2800,0x2801,0x2802,0x2803,0x2804,0x2805,0x2806,0x2807,0x2808,0x2809,0x280a,0x280b,0x280c,0x280d,0x280e,0x280f,\n  0x2810,0x2811,0x2812,0x2813,0x2814,0x2815,0x2816,0x2817,0x2818,0x2819,0x281a,0x281b,0x281c,0x281d,0x281e,0x281f,\n  0x2820,0x2821,0x2822,0x2823,0x2824,0x2825,0x2826,0x2827,0x2828,0x2829,0x282a,0x282b,0x282c,0x282d,0x282e,0x282f,\n  0x2830,0x2831,0x2832,0x2833,0x2834,0x2835,0x2836,0x2837,0x2838,0x2839,0x283a,0x283b,0x283c,0x283d,0x283e,0x283f,\n  0x2840,0x2841,0x2842,0x2843,0x2844,0x2845,0x2846,0x2847,0x2848,0x2849,0x284a,0x284b,0x284c,0x284d,0x284e,0x284f,\n  0x2850,0x2851,0x2852,0x2853,0x2854,0x2855,0x2856,0x2857,0x2858,0x2859,0x285a,0x285b,0x285c,0x285d,0x285e,0x285f,\n  0x2860,0x2861,0x2862,0x2863,0x2864,0x2865,0x2866,0x2867,0x2868,0x2869,0x286a,0x286b,0x286c,0x286d,0x286e,0x286f,\n  0x2870,0x2871,0x2872,0x2873,0x2874,0x2875,0x2876,0x2877,0x2878,0x2879,0x287a,0x287b,0x287c,0x287d,0x287e,0x287f,\n  0x2880,0x2881,0x2882,0x2883,0x2884,0x2885,0x2886,0x2887,0x2888,0x2889,0x288a,0x288b,0x288c,0x288d,0x288e,0x288f,\n  0x2890,0x2891,0x2892,0x2893,0x2894,0x2895,0x2896,0x2897,0x2898,0x2899,0x289a,0x289b,0x289c,0x289d,0x289e,0x289f,\n  0x28a0,0x28a1,0x28a2,0x28a3,0x28a4,0x28a5,0x28a6,0x28a7,0x28a8,0x28a9,0x28aa,0x28ab,0x28ac,0x28ad,0x28ae,0x28af,\n  0x28b0,0x28b1,0x28b2,0x28b3,0x28b4,0x28b5,0x28b6,0x28b7,0x28b8,0x28b9,0x28ba,0x28bb,0x28bc,0x28bd,0x28be,0x28bf,\n  0x28c0,0x28c1,0x28c2,0x28c3,0x28c4,0x28c5,0x28c6,0x28c7,0x28c8,0x28c9,0x28ca,0x28cb,0x28cc,0x28cd,0x28ce,0x28cf,\n  0x28d0,0x28d1,0x28d2,0x28d3,0x28d4,0x28d5,0x28d6,0x28d7,0x28d8,0x28d9,0x28da,0x28db,0x28dc,0x28dd,0x28de,0x28df,\n  0x28e0,0x28e1,0x28e2,0x28e3,0x28e4,0x28e5,0x28e6,0x28e7,0x28e8,0x28e9,0x28ea,0x28eb,0x28ec,0x28ed,0x28ee,0x28ef,\n  0x28f0,0x28f1,0x28f2,0x28f3,0x28f4,0x28f5,0x28f6,0x28f7,0x28f8,0x28f9,0x28fa,0x28fb,0x28fc,0x28fd,0x28fe,0x28ff,\n  0x2e2c,0xe0a0,0xe0a1,0xe0a2,0xe0b0,0xe0b1,0xe0b2,0xe0b3,0xf6be,0xfffd };\n} // namespace\n// -- end of autogenerated text ---\n\nnamespace fixed_font_32n {\n  // -- start of autogenerated text ---\n  // definition section for font: ter-u32n.bdf\n  constexpr int CHARCOUNT = 1354;\n  constexpr int WIDTH = 16;\n  constexpr int HEIGHT = 32;\n  constexpr int OFFSET_X = 0;\n  constexpr int OFFSET_Y = 0;\n  constexpr FixedFont_info_t fixedfont_info = {\n    \"Terminus\", // font name\n    \"ter-u32n.bdf\", // font name internal\n    CHARCOUNT, // num of chars\n    WIDTH, HEIGHT, OFFSET_X, OFFSET_Y,\n    false // bold\n  };\n  // font bitmap definitions\n  constexpr std::array<uint16_t, CHARCOUNT * HEIGHT> fixedfont_bitmap = {\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3c3c,0x3c3c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x300c,0x300c,\n  0x300c,0x300c,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x3c3c,0x3c3c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0020\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0021\n  0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0022\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0c30,0x3ffc,0x3ffc,0x0c30,0x0c30,0x0c30,\n  0x0c30,0x0c30,0x0c30,0x3ffc,0x3ffc,0x0c30,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0023\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0ff0,0x1ff8,0x399c,0x318c,0x3180,0x3180,0x3180,0x3980,0x1ff0,\n  0x0ff8,0x019c,0x018c,0x018c,0x018c,0x318c,0x399c,0x1ff8,0x0ff0,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000, // u0024\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e18,0x3f18,0x3330,0x3330,0x3f60,0x1e60,0x00c0,0x00c0,0x0180,0x0180,\n  0x0300,0x0300,0x0600,0x0600,0x0cf0,0x0df8,0x1998,0x1998,0x31f8,0x30f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0025\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f80,0x1fc0,0x38e0,0x3060,0x3060,0x3060,0x38e0,0x1dc0,0x0f80,0x0f00,\n  0x1f8c,0x39dc,0x70f8,0x6070,0x6030,0x6030,0x6070,0x70f8,0x3fdc,0x1f8c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0026\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0027\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x00e0,0x01c0,0x0380,0x0300,0x0700,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0700,0x0300,0x0380,0x01c0,0x00e0,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0028\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0700,0x0380,0x01c0,0x00c0,0x00e0,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x0060,0x0060,0x00e0,0x00c0,0x01c0,0x0380,0x0700,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0029\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x1c70,0x0ee0,0x07c0,0x0380,0x7ffc,\n  0x7ffc,0x0380,0x07c0,0x0ee0,0x1c70,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0180,0x3ffc,\n  0x3ffc,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0380,0x0300,0x0600,0x0000,0x0000,0x0000,0x0000, // u002c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,\n  0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0030,0x0030,0x0060,0x0060,0x00c0,0x00c0,0x0180,0x0180,\n  0x0300,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x301c,0x303c,0x307c,0x30ec,0x31cc,\n  0x338c,0x370c,0x3e0c,0x3c0c,0x380c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0030\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0380,0x0780,0x0f80,0x0d80,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0ff0,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0031\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x000c,0x001c,0x0038,\n  0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0032\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x000c,0x000c,0x000c,0x001c,0x07f8,\n  0x07f8,0x001c,0x000c,0x000c,0x000c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0033\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000c,0x001c,0x003c,0x007c,0x00ec,0x01cc,0x038c,0x070c,0x0e0c,0x1c0c,\n  0x380c,0x300c,0x300c,0x3ffc,0x3ffc,0x000c,0x000c,0x000c,0x000c,0x000c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0034\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ff0,0x3ff8,\n  0x001c,0x000c,0x000c,0x000c,0x000c,0x000c,0x300c,0x380c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0035\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff8,0x1ff8,0x3800,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ff0,0x3ff8,\n  0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0036\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x3018,0x0018,0x0030,0x0030,0x0060,\n  0x0060,0x00c0,0x00c0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0037\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,\n  0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0038\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,\n  0x1ffc,0x0ffc,0x000c,0x000c,0x000c,0x000c,0x000c,0x001c,0x1ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0380,0x0300,0x0600,0x0000,0x0000,0x0000,0x0000, // u003b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x001c,0x0038,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,\n  0x3800,0x1c00,0x0e00,0x0700,0x0380,0x01c0,0x00e0,0x0070,0x0038,0x001c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x0000,0x0000,\n  0x0000,0x0000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x1c00,0x0e00,0x0700,0x0380,0x01c0,0x00e0,0x0070,0x0038,0x001c,\n  0x001c,0x0038,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x001c,0x0038,0x0070,\n  0x00e0,0x01c0,0x0180,0x0180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x701c,0x600c,0x61fc,0x63fc,0x670c,0x660c,0x660c,0x660c,\n  0x660c,0x660c,0x660c,0x671c,0x63fc,0x61ec,0x6000,0x7000,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0040\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0041\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,0x300c,0x300c,0x300c,0x3018,0x3ff0,0x3ff0,\n  0x3038,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,0x3ff8,0x3ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0042\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0043\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x3ff0,0x3038,0x3018,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x3018,0x3038,0x3ff0,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0044\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3fe0,\n  0x3fe0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0045\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3fe0,\n  0x3fe0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0046\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x3000,0x3000,0x3000,0x3000,0x30fc,\n  0x30fc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0047\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x3ffc,\n  0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0048\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07e0,0x07e0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0049\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x007e,0x007e,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,\n  0x0018,0x0018,0x0018,0x0018,0x3018,0x3018,0x3018,0x3838,0x1ff0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u004a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x301c,0x3038,0x3070,0x30e0,0x31c0,0x3380,0x3700,0x3e00,0x3c00,\n  0x3c00,0x3e00,0x3700,0x3380,0x31c0,0x30e0,0x3070,0x3038,0x301c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u004b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u004c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x600c,0x600c,0x701c,0x783c,0x6c6c,0x6c6c,0x67cc,0x638c,0x638c,0x610c,\n  0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u004d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x3c0c,0x3e0c,0x370c,0x338c,\n  0x31cc,0x30ec,0x307c,0x303c,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u004e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u004f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,\n  0x3ff8,0x3ff0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0050\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x31cc,0x38fc,0x1ff8,0x0ff8,0x001c,0x000e,0x0000,0x0000,0x0000,0x0000, // u0051\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,\n  0x3ff8,0x3ff0,0x3700,0x3380,0x31c0,0x30e0,0x3070,0x3038,0x301c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0052\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x3000,0x3000,0x3000,0x3800,0x1ff0,\n  0x0ff8,0x001c,0x000c,0x000c,0x000c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0053\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0054\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0055\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x1818,0x1818,0x1818,0x1818,0x1818,\n  0x0c30,0x0c30,0x0c30,0x0c30,0x0660,0x0660,0x0660,0x03c0,0x03c0,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0056\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,\n  0x610c,0x638c,0x638c,0x67cc,0x6c6c,0x6c6c,0x783c,0x701c,0x600c,0x600c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0057\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x1818,0x1818,0x0c30,0x0c30,0x0660,0x0660,0x03c0,0x03c0,\n  0x03c0,0x03c0,0x0660,0x0660,0x0c30,0x0c30,0x1818,0x1818,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0058\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x1818,0x1818,0x0c30,0x0c30,0x0660,0x0660,0x03c0,\n  0x03c0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0059\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x000c,0x000c,0x000c,0x001c,0x0038,0x0070,0x00e0,0x01c0,\n  0x0380,0x0700,0x0e00,0x1c00,0x3800,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x0fe0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x1800,0x1800,0x0c00,0x0c00,0x0600,0x0600,0x0300,0x0300,\n  0x0180,0x0180,0x00c0,0x00c0,0x0060,0x0060,0x0030,0x0030,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x0fe0,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005d\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x1c38,0x381c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000, // u005f\n  0x0000,0x0e00,0x0700,0x0380,0x01c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0060\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x1ff8,0x001c,0x000c,\n  0x000c,0x0ffc,0x1ffc,0x380c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0061\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ff0,0x3ff8,0x301c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,0x3ff8,0x3ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0062\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0063\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x0ffc,0x1ffc,0x380c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0064\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x380c,0x1ffc,0x0ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0065\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x007e,0x00fe,0x01c0,0x0180,0x0180,0x0180,0x1ff8,0x1ff8,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0066\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ffc,0x1ffc,0x380c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x000c,0x000c,0x001c,0x1ff8,0x1ff0,0x0000, // u0067\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ff0,0x3ff8,0x301c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0068\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0780,0x0780,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0069\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0078,0x0078,0x0018,0x0018,\n  0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x1818,0x1818,0x1c38,0x0ff0,0x07e0,0x0000, // u006a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x181c,0x1838,0x1870,0x18e0,\n  0x19c0,0x1b80,0x1f00,0x1f00,0x1b80,0x19c0,0x18e0,0x1870,0x1838,0x181c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u006b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0780,0x0780,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u006c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x319c,0x318c,\n  0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u006d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u006e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u006f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,0x3ff8,0x3ff0,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000, // u0070\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ffc,0x1ffc,0x380c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x000c,0x000c,0x000c,0x000c,0x000c,0x0000, // u0071\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x33fc,0x37fc,0x3e00,0x3c00,\n  0x3800,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0072\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x3000,\n  0x3000,0x3800,0x1ff0,0x0ff8,0x001c,0x000c,0x000c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0073\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x3ff0,0x3ff0,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0380,0x01fc,0x00fc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0074\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0075\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x1818,\n  0x1818,0x1818,0x0c30,0x0c30,0x0c30,0x0660,0x0660,0x03c0,0x03c0,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0076\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x399c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0077\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x381c,0x1c38,\n  0x0e70,0x07e0,0x03c0,0x03c0,0x07e0,0x0e70,0x1c38,0x381c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0078\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x000c,0x000c,0x001c,0x1ff8,0x1ff0,0x0000, // u0079\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x001c,0x0038,\n  0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00f0,0x01f0,0x0380,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x1e00,\n  0x1e00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0380,0x01f0,0x00f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x1f00,0x0380,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x00f0,\n  0x00f0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0380,0x1f00,0x1e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007d\n  0x0000,0x0000,0x0000,0x0000,0x0e0c,0x1f0c,0x3b8c,0x31dc,0x30f8,0x3070,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0ff0,0x1ff8,0x399c,0x318c,\n  0x3180,0x3180,0x3180,0x3180,0x3180,0x3180,0x318c,0x399c,0x1ff8,0x0ff0,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000, // u00a2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03e0,0x07f0,0x0e38,0x0c18,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x3fe0,\n  0x3fe0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c0c,0x0c0c,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x381c,0x1c38,0x0ff0,0x0ff0,0x1c38,0x1818,0x1818,\n  0x1818,0x1818,0x1c38,0x0ff0,0x0ff0,0x1c38,0x381c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x1818,0x1818,0x0c30,0x0c30,0x0660,0x0660,0x03c0,0x03c0,\n  0x0180,0x0180,0x1ff8,0x1ff8,0x0180,0x0180,0x1ff8,0x1ff8,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,\n  0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a6\n  0x0000,0x0000,0x0000,0x0000,0x07c0,0x0fe0,0x1c70,0x1830,0x1800,0x1c00,0x0f80,0x0fc0,0x18e0,0x1870,0x1830,0x1830,\n  0x1830,0x1c30,0x0e30,0x07e0,0x03e0,0x0070,0x0030,0x1830,0x1c70,0x0fe0,0x07c0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a7\n  0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff8,0x3ffc,0x700e,0x67e6,0x6ff6,0x6c36,0x6c06,0x6c06,\n  0x6c06,0x6c06,0x6c36,0x6ff6,0x67e6,0x700e,0x3ffc,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a9\n  0x0000,0x0000,0x0fe0,0x0ff0,0x0038,0x0018,0x07f8,0x0ff8,0x1c18,0x1818,0x1c18,0x0ff8,0x07f8,0x0000,0x0000,0x1ff8,\n  0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01ce,0x039c,0x0738,0x0e70,\n  0x1ce0,0x39c0,0x7380,0x7380,0x39c0,0x1ce0,0x0e70,0x0738,0x039c,0x01ce,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ab\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x000c,0x000c,\n  0x000c,0x000c,0x000c,0x000c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ac\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff8,\n  0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ad\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff8,0x3ffc,0x700e,0x6fe6,0x6ff6,0x6c36,0x6c36,0x6c36,\n  0x6fe6,0x6fc6,0x6dc6,0x6ce6,0x6c76,0x700e,0x3ffc,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ae\n  0x0000,0x0000,0x0ff0,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00af\n  0x0000,0x0000,0x0000,0x0000,0x07e0,0x0ff0,0x0c30,0x0c30,0x0c30,0x0c30,0x0ff0,0x07e0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0180,0x3ffc,\n  0x3ffc,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b1\n  0x0000,0x0000,0x0000,0x07e0,0x0ff0,0x0c30,0x0c30,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0ff0,0x0ff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b2\n  0x0000,0x0000,0x0000,0x07e0,0x0ff0,0x0c30,0x0030,0x01e0,0x01e0,0x0030,0x0030,0x0c30,0x0ff0,0x07e0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b3\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,0x303c,0x307c,0x3fec,0x3fcc,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000, // u00b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ffc,0x3ffc,0x718c,0x618c,0x618c,0x618c,0x618c,0x618c,0x718c,0x3f8c,\n  0x1f8c,0x018c,0x018c,0x018c,0x018c,0x018c,0x018c,0x018c,0x018c,0x018c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,\n  0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0380,0x0300,0x0600,0x0000, // u00b8\n  0x0000,0x0000,0x0000,0x0180,0x0380,0x0780,0x0780,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b9\n  0x0000,0x0000,0x07e0,0x0ff0,0x1c38,0x1818,0x1818,0x1818,0x1818,0x1818,0x1c38,0x0ff0,0x07e0,0x0000,0x0000,0x1ff8,\n  0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7380,0x39c0,0x1ce0,0x0e70,\n  0x0738,0x039c,0x01ce,0x01ce,0x039c,0x0738,0x0e70,0x1ce0,0x39c0,0x7380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x1c00,0x3c00,0x0c00,0x0c06,0x0c0e,0x0c1c,0x0c38,0x0c70,0x00e0,\n  0x01c6,0x038e,0x071e,0x0e36,0x1c66,0x38c6,0x71fe,0x61fe,0x0006,0x0006,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x3800,0x7806,0x180e,0x181c,0x1838,0x1870,0x18e0,0x19c0,0x0380,\n  0x0700,0x0e7c,0x1cfe,0x38c6,0x70c6,0x600c,0x0018,0x0030,0x007e,0x00fe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00bd\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x7f80,0x6180,0x0f00,0x0f00,0x0186,0x618e,0x7f9c,0x3f38,0x0070,\n  0x00e6,0x01ce,0x039e,0x0736,0x0e66,0x1cc6,0x39fe,0x71fe,0x6006,0x0006,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00be\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0300,\n  0x0600,0x0c00,0x1800,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00bf\n  0x0000,0x0e00,0x0700,0x0380,0x01c0,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c0\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c1\n  0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c2\n  0x0000,0x0f18,0x1b98,0x19d8,0x18f0,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c3\n  0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c4\n  0x0000,0x03c0,0x0660,0x0660,0x0660,0x03c0,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fff,0x3fff,0x70c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7ffe,\n  0x7ffe,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60ff,0x60ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0180,0x0180,0x0380,0x0300,0x0600,0x0000, // u00c7\n  0x0000,0x0e00,0x0700,0x0380,0x01c0,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3fe0,\n  0x3fe0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c8\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3fe0,\n  0x3fe0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c9\n  0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3fe0,\n  0x3fe0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ca\n  0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3fe0,\n  0x3fe0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cb\n  0x0000,0x0e00,0x0700,0x0380,0x01c0,0x0000,0x07e0,0x07e0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cc\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x07e0,0x07e0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cd\n  0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x0000,0x07e0,0x07e0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ce\n  0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x07e0,0x07e0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x3ff0,0x3038,0x3018,0x300c,0x300c,0x300c,0x300c,0x300c,0x7f8c,\n  0x7f8c,0x300c,0x300c,0x300c,0x300c,0x300c,0x3018,0x3038,0x3ff0,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d0\n  0x0000,0x0f18,0x1b98,0x19d8,0x18f0,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x3c0c,0x3e0c,0x370c,0x338c,\n  0x31cc,0x30ec,0x307c,0x303c,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d1\n  0x0000,0x0e00,0x0700,0x0380,0x01c0,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d2\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d3\n  0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d4\n  0x0000,0x0f18,0x1b98,0x19d8,0x18f0,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d5\n  0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x3838,0x1c70,0x0ee0,0x07c0,\n  0x0380,0x07c0,0x0ee0,0x1c70,0x3838,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300e,0x300e,0x301c,0x303c,0x307c,0x30ec,0x31cc,\n  0x338c,0x370c,0x3e0c,0x3c0c,0x380c,0x700c,0x700c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d8\n  0x0000,0x0e00,0x0700,0x0380,0x01c0,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d9\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00da\n  0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00db\n  0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00dc\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x300c,0x300c,0x300c,0x1818,0x1818,0x0c30,0x0c30,0x0660,0x0660,0x03c0,\n  0x03c0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00dd\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3ff0,0x3ff8,0x301c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x301c,0x3ff8,0x3ff0,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00de\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fe0,0x3ff0,0x3038,0x3018,0x3018,0x3018,0x3018,0x3030,0x3ff0,0x3ff0,\n  0x3038,0x301c,0x300c,0x300c,0x300c,0x300c,0x380c,0x3c1c,0x37f8,0x33f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00df\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x0700,0x0380,0x01c0,0x0000,0x0000,0x1ff0,0x1ff8,0x001c,0x000c,\n  0x000c,0x0ffc,0x1ffc,0x380c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x1ff0,0x1ff8,0x001c,0x000c,\n  0x000c,0x0ffc,0x1ffc,0x380c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x0000,0x0000,0x1ff0,0x1ff8,0x001c,0x000c,\n  0x000c,0x0ffc,0x1ffc,0x380c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f18,0x1b98,0x19d8,0x18f0,0x0000,0x0000,0x1ff0,0x1ff8,0x001c,0x000c,\n  0x000c,0x0ffc,0x1ffc,0x380c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x1ff0,0x1ff8,0x001c,0x000c,\n  0x000c,0x0ffc,0x1ffc,0x380c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03c0,0x0660,0x0660,0x0660,0x03c0,0x0000,0x1ff0,0x1ff8,0x001c,0x000c,\n  0x000c,0x0ffc,0x1ffc,0x380c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ef8,0x3ffc,0x018e,0x0186,\n  0x0186,0x1f86,0x3ffe,0x71fe,0x6180,0x6180,0x6180,0x71c6,0x3ffe,0x1f7c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x300c,0x381c,0x1ff8,0x0ff0,0x0180,0x0180,0x0380,0x0300,0x0600,0x0000, // u00e7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x0700,0x0380,0x01c0,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x380c,0x1ffc,0x0ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x380c,0x1ffc,0x0ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x380c,0x1ffc,0x0ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x380c,0x1ffc,0x0ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00eb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0e00,0x0700,0x0380,0x0000,0x0000,0x0780,0x0780,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ec\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x0780,0x0780,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ed\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x0000,0x0000,0x0780,0x0780,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ee\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x0780,0x0780,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ef\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1dc0,0x0f80,0x1f00,0x3b80,0x01c0,0x00e0,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f18,0x1b98,0x19d8,0x18f0,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x0700,0x0380,0x01c0,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f18,0x1b98,0x19d8,0x18f0,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x3ffc,\n  0x3ffc,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff6,0x1ffe,0x381c,0x303c,\n  0x307c,0x30ec,0x31cc,0x338c,0x370c,0x3e0c,0x3c0c,0x381c,0x7ff8,0x6ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x0700,0x0380,0x01c0,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00fa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00fb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00fc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x000c,0x000c,0x001c,0x1ff8,0x1ff0,0x0000, // u00fd\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ff0,0x3ff8,0x301c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,0x3ff8,0x3ff0,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000, // u00fe\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x000c,0x000c,0x001c,0x1ff8,0x1ff0,0x0000, // u00ff\n  0x0000,0x0000,0x0ff0,0x0ff0,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0100\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x0ff0,0x0000,0x0000,0x1ff0,0x1ff8,0x001c,0x000c,\n  0x000c,0x0ffc,0x1ffc,0x380c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0101\n  0x0000,0x0c30,0x0c30,0x07e0,0x03c0,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0102\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x07e0,0x03c0,0x0000,0x0000,0x1ff0,0x1ff8,0x001c,0x000c,\n  0x000c,0x0ffc,0x1ffc,0x380c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0103\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x003c,0x0070,0x0060,0x007c,0x003c,0x0000, // u0104\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x1ff8,0x001c,0x000c,\n  0x000c,0x0ffc,0x1ffc,0x380c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x003c,0x0070,0x0060,0x007c,0x003c,0x0000, // u0105\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0106\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0107\n  0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0108\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0109\n  0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u010a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u010b\n  0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u010c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u010d\n  0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x3fc0,0x3ff0,0x3038,0x3018,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x3018,0x3038,0x3ff0,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u010e\n  0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x0ffc,0x1ffc,0x380c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u010f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x3ff0,0x3038,0x3018,0x300c,0x300c,0x300c,0x300c,0x300c,0x7f8c,\n  0x7f8c,0x300c,0x300c,0x300c,0x300c,0x300c,0x3018,0x3038,0x3ff0,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0110\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000c,0x000c,0x01ff,0x01ff,0x000c,0x000c,0x0ffc,0x1ffc,0x380c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0111\n  0x0000,0x0000,0x0ff0,0x0ff0,0x0000,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3fe0,\n  0x3fe0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0112\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x0ff0,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x380c,0x1ffc,0x0ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0113\n  0x0000,0x0c30,0x0c30,0x07e0,0x03c0,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3fe0,\n  0x3fe0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0114\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x07e0,0x03c0,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x380c,0x1ffc,0x0ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0115\n  0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3fe0,\n  0x3fe0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0116\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x380c,0x1ffc,0x0ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0117\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3fe0,\n  0x3fe0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x003c,0x0070,0x0060,0x007c,0x003c,0x0000, // u0118\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x380c,0x1ffc,0x0ff8,0x01c0,0x0380,0x0300,0x03e0,0x01e0,0x0000, // u0119\n  0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3fe0,\n  0x3fe0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u011a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x380c,0x1ffc,0x0ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u011b\n  0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x3000,0x3000,0x3000,0x3000,0x30fc,\n  0x30fc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u011c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x0000,0x0000,0x0ffc,0x1ffc,0x380c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x000c,0x000c,0x001c,0x1ff8,0x1ff0,0x0000, // u011d\n  0x0000,0x0c30,0x0c30,0x07e0,0x03c0,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x3000,0x3000,0x3000,0x3000,0x30fc,\n  0x30fc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u011e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x07e0,0x03c0,0x0000,0x0000,0x0ffc,0x1ffc,0x380c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x000c,0x000c,0x001c,0x1ff8,0x1ff0,0x0000, // u011f\n  0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x3000,0x3000,0x3000,0x3000,0x30fc,\n  0x30fc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0120\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0ffc,0x1ffc,0x380c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x000c,0x000c,0x001c,0x1ff8,0x1ff0,0x0000, // u0121\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x3000,0x3000,0x3000,0x3000,0x30fc,\n  0x30fc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0180,0x0180,0x0380,0x0300,0x0600, // u0122\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0030,0x0060,0x00e0,0x00c0,0x00c0,0x0000,0x0ffc,0x1ffc,0x380c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x000c,0x000c,0x001c,0x1ff8,0x1ff0,0x0000, // u0123\n  0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x3ffc,\n  0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0124\n  0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ff0,0x3ff8,0x301c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0125\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x7ffe,0x7ffe,0x300c,0x300c,0x300c,0x300c,0x3ffc,\n  0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0126\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0xff80,0xff80,0x3000,0x3000,0x3ff0,0x3ff8,0x301c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0127\n  0x0000,0x0f18,0x1b98,0x19d8,0x18f0,0x0000,0x07e0,0x07e0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0128\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f18,0x1b98,0x19d8,0x18f0,0x0000,0x0000,0x0780,0x0780,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0129\n  0x0000,0x0000,0x0ff0,0x0ff0,0x0000,0x0000,0x07e0,0x07e0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u012a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x0ff0,0x0000,0x0000,0x0780,0x0780,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u012b\n  0x0000,0x0c30,0x0c30,0x07e0,0x03c0,0x0000,0x07e0,0x07e0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u012c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x07e0,0x03c0,0x0000,0x0000,0x0780,0x0780,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u012d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07e0,0x07e0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0180,0x0380,0x0300,0x03e0,0x01e0,0x0000, // u012e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0780,0x0780,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0180,0x0380,0x0300,0x03e0,0x01e0,0x0000, // u012f\n  0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x07e0,0x07e0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0130\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0780,0x0780,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0131\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf01e,0xf01e,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,\n  0x600c,0x600c,0x600c,0x600c,0x630c,0x630c,0x630c,0x639c,0xf1f8,0xf0f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0132\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3006,0x3006,0x3006,0x3006,0x0000,0x0000,0x701e,0x701e,0x3006,0x3006,\n  0x3006,0x3006,0x3006,0x3006,0x3006,0x3006,0x3006,0x3006,0x7806,0x7806,0x0186,0x0186,0x01ce,0x00fc,0x0078,0x0000, // u0133\n  0x0000,0x0018,0x003c,0x007e,0x00e7,0x0000,0x007e,0x007e,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,\n  0x0018,0x0018,0x0018,0x0018,0x3018,0x3018,0x3018,0x3838,0x1ff0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0134\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x003c,0x007e,0x00e7,0x0000,0x0000,0x0078,0x0078,0x0018,0x0018,\n  0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x1818,0x1818,0x1c38,0x0ff0,0x07e0,0x0000, // u0135\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x301c,0x3038,0x3070,0x30e0,0x31c0,0x3380,0x3700,0x3e00,0x3c00,\n  0x3c00,0x3e00,0x3700,0x3380,0x31c0,0x30e0,0x3070,0x3038,0x301c,0x300c,0x0000,0x0180,0x0180,0x0380,0x0300,0x0600, // u0136\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x181c,0x1838,0x1870,0x18e0,\n  0x19c0,0x1b80,0x1f00,0x1f00,0x1b80,0x19c0,0x18e0,0x1870,0x1838,0x181c,0x0000,0x0180,0x0180,0x0380,0x0300,0x0600, // u0137\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x181c,0x1838,0x1870,0x18e0,\n  0x19c0,0x1b80,0x1f00,0x1f00,0x1b80,0x19c0,0x18e0,0x1870,0x1838,0x181c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0138\n  0x0000,0x0700,0x0e00,0x1c00,0x3800,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0139\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0780,0x0780,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u013a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0180,0x0180,0x0380,0x0300,0x0600, // u013b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0780,0x0780,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0180,0x0180,0x0380,0x0300,0x0600, // u013c\n  0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u013d\n  0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x0780,0x0780,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u013e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3030,0x3030,\n  0x3030,0x3030,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u013f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0780,0x0780,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0183,0x0183,\n  0x0183,0x0183,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0140\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3300,0x3600,0x3c00,\n  0x3800,0x7000,0xf000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0141\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0780,0x0780,0x0180,0x0180,0x0180,0x0180,0x0180,0x01b0,0x01e0,0x01c0,\n  0x0380,0x0780,0x0d80,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0142\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x3c0c,0x3e0c,0x370c,0x338c,\n  0x31cc,0x30ec,0x307c,0x303c,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0143\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0144\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x3c0c,0x3e0c,0x370c,0x338c,\n  0x31cc,0x30ec,0x307c,0x303c,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0180,0x0180,0x0380,0x0300,0x0600, // u0145\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0180,0x0180,0x0380,0x0300,0x0600, // u0146\n  0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x3c0c,0x3e0c,0x370c,0x338c,\n  0x31cc,0x30ec,0x307c,0x303c,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0147\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0148\n  0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x6000,0x6000,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0149\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x3c0c,0x3e0c,0x370c,0x338c,\n  0x31cc,0x30ec,0x307c,0x303c,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x000c,0x000c,0x001c,0x00f8,0x00f0,0x0000, // u014a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x000c,0x000c,0x001c,0x00f8,0x00f0,0x0000, // u014b\n  0x0000,0x0000,0x0ff0,0x0ff0,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u014c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x0ff0,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u014d\n  0x0000,0x0c30,0x0c30,0x07e0,0x03c0,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u014e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x07e0,0x03c0,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u014f\n  0x0000,0x01ce,0x039c,0x0738,0x0e70,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0150\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01ce,0x039c,0x0738,0x0e70,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0151\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fff,0x3fff,0x70c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60fe,\n  0x60fe,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x70c0,0x3fff,0x1fff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0152\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff8,0x3ffc,0x718e,0x6186,\n  0x6186,0x6186,0x61fe,0x61fe,0x6180,0x6180,0x6180,0x7186,0x3ffe,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0153\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,\n  0x3ff8,0x3ff0,0x3700,0x3380,0x31c0,0x30e0,0x3070,0x3038,0x301c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0154\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x33fc,0x37fc,0x3e00,0x3c00,\n  0x3800,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0155\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,\n  0x3ff8,0x3ff0,0x3700,0x3380,0x31c0,0x30e0,0x3070,0x3038,0x301c,0x300c,0x0000,0x0180,0x0180,0x0380,0x0300,0x0600, // u0156\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x31fc,0x33fc,0x3600,0x3c00,\n  0x3800,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,0x3000,0x3000,0x7000,0x6000,0xc000, // u0157\n  0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,\n  0x3ff8,0x3ff0,0x3700,0x3380,0x31c0,0x30e0,0x3070,0x3038,0x301c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0158\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x0000,0x33fc,0x37fc,0x3e00,0x3c00,\n  0x3800,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0159\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x3000,0x3000,0x3000,0x3800,0x1ff0,\n  0x0ff8,0x001c,0x000c,0x000c,0x000c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u015a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x3000,\n  0x3000,0x3800,0x1ff0,0x0ff8,0x001c,0x000c,0x000c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u015b\n  0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x3000,0x3000,0x3000,0x3800,0x1ff0,\n  0x0ff8,0x001c,0x000c,0x000c,0x000c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u015c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x3000,\n  0x3000,0x3800,0x1ff0,0x0ff8,0x001c,0x000c,0x000c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u015d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x3000,0x3000,0x3000,0x3800,0x1ff0,\n  0x0ff8,0x001c,0x000c,0x000c,0x000c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0180,0x0180,0x0380,0x0300,0x0600,0x0000, // u015e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x3000,\n  0x3000,0x3800,0x1ff0,0x0ff8,0x001c,0x000c,0x000c,0x381c,0x1ff8,0x0ff0,0x0180,0x0180,0x0380,0x0300,0x0600,0x0000, // u015f\n  0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x3000,0x3000,0x3000,0x3800,0x1ff0,\n  0x0ff8,0x001c,0x000c,0x000c,0x000c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0160\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x3000,\n  0x3000,0x3800,0x1ff0,0x0ff8,0x001c,0x000c,0x000c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0161\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x00c0,0x00c0,0x01c0,0x0180,0x0300,0x0000, // u0162\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x3ff0,0x3ff0,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0380,0x01fc,0x00fc,0x0030,0x0030,0x0070,0x0060,0x00c0,0x0000, // u0163\n  0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x3ffc,0x3ffc,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0164\n  0x0000,0x1ce0,0x0fc0,0x0780,0x0300,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x3ff0,0x3ff0,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0380,0x01fc,0x00fc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0165\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0ff0,\n  0x0ff0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0166\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x3ff0,0x3ff0,0x0300,0x0300,\n  0x0fc0,0x0fc0,0x0300,0x0300,0x0300,0x0300,0x0300,0x0380,0x01fc,0x00fc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0167\n  0x0000,0x0f18,0x1b98,0x19d8,0x18f0,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0168\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f18,0x1b98,0x19d8,0x18f0,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0169\n  0x0000,0x0000,0x0ff0,0x0ff0,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u016a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x0ff0,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u016b\n  0x0000,0x0c30,0x0c30,0x07e0,0x03c0,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u016c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x07e0,0x03c0,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u016d\n  0x0000,0x03c0,0x0660,0x0660,0x0660,0x03c0,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u016e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03c0,0x0660,0x0660,0x0660,0x03c0,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u016f\n  0x0000,0x01ce,0x039c,0x0738,0x0e70,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0170\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01ce,0x039c,0x0738,0x0e70,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0171\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x01c0,0x0380,0x0300,0x03e0,0x01e0,0x0000, // u0172\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x003c,0x0070,0x0060,0x007c,0x003c,0x0000, // u0173\n  0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x0000,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,\n  0x610c,0x638c,0x638c,0x67cc,0x6c6c,0x6c6c,0x783c,0x701c,0x600c,0x600c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0174\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x399c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0175\n  0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x0000,0x300c,0x300c,0x300c,0x1818,0x1818,0x0c30,0x0c30,0x0660,0x0660,0x03c0,\n  0x03c0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0176\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x000c,0x000c,0x001c,0x1ff8,0x1ff0,0x0000, // u0177\n  0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x300c,0x300c,0x300c,0x1818,0x1818,0x0c30,0x0c30,0x0660,0x0660,0x03c0,\n  0x03c0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0178\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x3ffc,0x3ffc,0x000c,0x000c,0x000c,0x001c,0x0038,0x0070,0x00e0,0x01c0,\n  0x0380,0x0700,0x0e00,0x1c00,0x3800,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0179\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x3ffc,0x3ffc,0x001c,0x0038,\n  0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u017a\n  0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x3ffc,0x3ffc,0x000c,0x000c,0x000c,0x001c,0x0038,0x0070,0x00e0,0x01c0,\n  0x0380,0x0700,0x0e00,0x1c00,0x3800,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u017b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x3ffc,0x3ffc,0x001c,0x0038,\n  0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u017c\n  0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x3ffc,0x3ffc,0x000c,0x000c,0x000c,0x001c,0x0038,0x0070,0x00e0,0x01c0,\n  0x0380,0x0700,0x0e00,0x1c00,0x3800,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u017d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x0000,0x3ffc,0x3ffc,0x001c,0x0038,\n  0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u017e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00fc,0x01fc,0x0380,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u017f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x000c,0x000c,0x000c,0x000c,0x000c,\n  0x000c,0x000c,0x000c,0x000c,0x000c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0186\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x07fc,\n  0x07fc,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u018e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x000c,0x000c,0x000c,0x000c,0x3ffc,\n  0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u018f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x3000,0x3000,0x3000,0x3800,0x1fe0,\n  0x1fe0,0x3800,0x3000,0x3000,0x3000,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0190\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00f8,0x01fc,0x018c,0x018c,0x0180,0x0180,0x0180,0x0180,0x0ff0,0x0ff0,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x3180,0x3180,0x3f80,0x1f00,0x0000,0x0000, // u0192\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x3c0c,0x3e0c,0x370c,0x338c,\n  0x31cc,0x30ec,0x307c,0x303c,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x3000,0x3000,0x3000,0x7000,0xe000,0x0000, // u019d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x000c,0x000c,0x000c,0x000c,0x000c,0x0000, // u019e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x000c,0x000c,0x000c,0x001c,0x0038,0x0070,0x00e0,0x3ffc,\n  0x3ffc,0x0380,0x0700,0x0e00,0x1c00,0x3800,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x0038,0x0070,\n  0x00e0,0x01c0,0x3ff8,0x3ff8,0x0700,0x0e00,0x1c00,0x3800,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x001c,0x0038,0x0070,0x00e0,0x01c0,0x0380,0x07f0,0x07f8,\n  0x001c,0x000c,0x000c,0x000c,0x000c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01b7\n  0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01cd\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x0000,0x1ff0,0x1ff8,0x001c,0x000c,\n  0x000c,0x0ffc,0x1ffc,0x380c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01ce\n  0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x07e0,0x07e0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01cf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x0000,0x0780,0x0780,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d0\n  0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d2\n  0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d4\n  0x0000,0x0000,0x1ffc,0x1ffc,0x0000,0x0000,0x1fff,0x3fff,0x70c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7ffe,\n  0x7ffe,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60ff,0x60ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff8,0x1ff8,0x0000,0x0000,0x3ef8,0x3ffc,0x018e,0x0186,\n  0x0186,0x1f86,0x3ffe,0x71fe,0x6180,0x6180,0x6180,0x71c6,0x3ffe,0x1f7c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x3000,0x3000,0x3000,0x3000,0x30fc,\n  0x30fc,0x300c,0x300c,0x30ff,0x30ff,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ffc,0x1ffc,0x380c,0x300c,\n  0x300c,0x300c,0x30ff,0x30ff,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x000c,0x000c,0x001c,0x1ff8,0x1ff0,0x0000, // u01e5\n  0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x3000,0x3000,0x3000,0x3000,0x30fc,\n  0x30fc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x0000,0x0ffc,0x1ffc,0x380c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x000c,0x000c,0x001c,0x1ff8,0x1ff0,0x0000, // u01e7\n  0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x300c,0x301c,0x3038,0x3070,0x30e0,0x31c0,0x3380,0x3700,0x3e00,0x3c00,\n  0x3c00,0x3e00,0x3700,0x3380,0x31c0,0x30e0,0x3070,0x3038,0x301c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e8\n  0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x181c,0x1838,0x1870,0x18e0,\n  0x19c0,0x1b80,0x1f00,0x1f00,0x1b80,0x19c0,0x18e0,0x1870,0x1838,0x181c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x01c0,0x0380,0x0300,0x03e0,0x01e0,0x0000, // u01ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x01c0,0x0380,0x0300,0x03e0,0x01e0,0x0000, // u01eb\n  0x0000,0x0000,0x0ff0,0x0ff0,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x01c0,0x0380,0x0300,0x03e0,0x01e0,0x0000, // u01ec\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x0ff0,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x01c0,0x0380,0x0300,0x03e0,0x01e0,0x0000, // u01ed\n  0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x3ffc,0x3ffc,0x001c,0x0038,0x0070,0x00e0,0x01c0,0x0380,0x07f0,0x07f8,\n  0x001c,0x000c,0x000c,0x000c,0x000c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01ee\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x0000,0x3ffc,0x3ffc,0x001c,0x0038,\n  0x0070,0x00e0,0x01c0,0x0380,0x07f0,0x07f8,0x001c,0x000c,0x000c,0x000c,0x000c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000, // u01ef\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00e7,0x007e,0x003c,0x0018,0x0000,0x0000,0x0078,0x0078,0x0018,0x0018,\n  0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x1818,0x1818,0x1c38,0x0ff0,0x07e0,0x0000, // u01f0\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x3000,0x3000,0x3000,0x3000,0x30fc,\n  0x30fc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0070,0x00e0,0x01c0,0x0000,0x0000,0x0ffc,0x1ffc,0x380c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x000c,0x000c,0x001c,0x1ff8,0x1ff0,0x0000, // u01f5\n  0x0000,0x0038,0x0070,0x00e0,0x01c0,0x0000,0x1fff,0x3fff,0x70c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7ffe,\n  0x7ffe,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60ff,0x60ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01fc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x3ef8,0x3ffc,0x018e,0x0186,\n  0x0186,0x1f86,0x3ffe,0x71fe,0x6180,0x6180,0x6180,0x71c6,0x3ffe,0x1f7c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01fd\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0ff0,0x1ff8,0x381c,0x300e,0x300e,0x301c,0x303c,0x307c,0x30ec,0x31cc,\n  0x338c,0x370c,0x3e0c,0x3c0c,0x380c,0x700c,0x700c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01fe\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x0ff6,0x1ffe,0x381c,0x303c,\n  0x307c,0x30ec,0x31cc,0x338c,0x370c,0x3e0c,0x3c0c,0x381c,0x7ff8,0x6ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01ff\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x3000,0x3000,0x3000,0x3800,0x1ff0,\n  0x0ff8,0x001c,0x000c,0x000c,0x000c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0180,0x0180,0x0380,0x0300,0x0600, // u0218\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x3000,\n  0x3000,0x3800,0x1ff0,0x0ff8,0x001c,0x000c,0x000c,0x381c,0x1ff8,0x0ff0,0x0000,0x0180,0x0180,0x0380,0x0300,0x0600, // u0219\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0180,0x0180,0x0380,0x0300,0x0600, // u021a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x3ff0,0x3ff0,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0380,0x01fc,0x00fc,0x0000,0x0030,0x0030,0x0070,0x0060,0x00c0, // u021b\n  0x0000,0x0000,0x0ff0,0x0ff0,0x0000,0x0000,0x300c,0x300c,0x300c,0x1818,0x1818,0x0c30,0x0c30,0x0660,0x0660,0x03c0,\n  0x03c0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0232\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x0ff0,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x000c,0x000c,0x001c,0x1ff8,0x1ff0,0x0000, // u0233\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0078,0x0078,0x0018,0x0018,\n  0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x1818,0x1818,0x1c38,0x0ff0,0x07e0,0x0000, // u0237\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0254\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x3ffc,0x3ffc,0x000c,0x000c,0x000c,0x301c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0258\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x301c,0x000c,\n  0x000c,0x000c,0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0259\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x3000,0x3800,0x1fc0,0x1fc0,0x3800,0x3000,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u025b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x3000,0x3000,0x3000,0x7000,0xe000,0x0000, // u0272\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x001c,0x0038,\n  0x0070,0x00e0,0x01c0,0x0380,0x07f0,0x07f8,0x001c,0x000c,0x000c,0x000c,0x000c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000, // u0292\n  0x0000,0x0060,0x00c0,0x01c0,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bb\n  0x0000,0x0180,0x0180,0x0380,0x0300,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bc\n  0x0000,0x0180,0x0180,0x01c0,0x00c0,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bd\n  0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02c6\n  0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02c7\n  0x0000,0x0c30,0x0c30,0x07e0,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02d8\n  0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02d9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x0380,0x0300,0x03e0,0x01e0,0x0000, // u02db\n  0x0000,0x0f18,0x1b98,0x19d8,0x18f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02dc\n  0x0000,0x01ce,0x039c,0x0738,0x0e70,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02dd\n  0x0000,0x0e00,0x0700,0x0380,0x01c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0300\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0301\n  0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0302\n  0x0000,0x0f18,0x1b98,0x19d8,0x18f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0303\n  0x0000,0x0000,0x0ff0,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0304\n  0x0000,0x0000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0305\n  0x0000,0x0c30,0x0c30,0x07e0,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0306\n  0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0307\n  0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0308\n  0x0000,0x03c0,0x0660,0x0660,0x0660,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030a\n  0x0000,0x01ce,0x039c,0x0738,0x0e70,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030b\n  0x0000,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000, // u0329\n  0x0000,0x0000,0x1c00,0x3800,0x7000,0xe000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0384\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0385\n  0x0000,0x0000,0x1c00,0x3800,0x7000,0xe000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0386\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0387\n  0x0000,0x0000,0x1c00,0x3800,0x7000,0xe000,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3fe0,\n  0x3fe0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0388\n  0x0000,0x0000,0x1c00,0x3800,0x7000,0xe000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x3ffc,\n  0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0389\n  0x0000,0x0000,0x1c00,0x3800,0x7000,0xe000,0x07e0,0x07e0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u038a\n  0x0000,0x0000,0x1c00,0x3800,0x7000,0xe000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u038c\n  0x0000,0x0000,0x1c00,0x3800,0x7000,0xe000,0x1806,0x1806,0x1806,0x0c0c,0x0c0c,0x0618,0x0618,0x0330,0x0330,0x01e0,\n  0x01e0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u038e\n  0x0000,0x0000,0x1c00,0x3800,0x7000,0xe000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x381c,0x1c38,0x0e70,0x0660,0x0660,0x3e7c,0x3e7c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u038f\n  0x0000,0x00e0,0x01c0,0x0380,0x0700,0x0000,0x1860,0x1860,0x1860,0x1860,0x0000,0x0000,0x0f00,0x0f00,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0380,0x01f0,0x00f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0390\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0391\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,0x300c,0x300c,0x300c,0x3018,0x3ff0,0x3ff0,\n  0x3038,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,0x3ff8,0x3ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0392\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0393\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x03c0,0x03c0,0x03c0,0x0660,0x0660,0x0660,0x0c30,\n  0x0c30,0x0c30,0x1818,0x1818,0x1818,0x300c,0x300c,0x300c,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0394\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3fe0,\n  0x3fe0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0395\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x000c,0x000c,0x000c,0x001c,0x0038,0x0070,0x00e0,0x01c0,\n  0x0380,0x0700,0x0e00,0x1c00,0x3800,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0396\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x3ffc,\n  0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0397\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x37ec,\n  0x37ec,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0398\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07e0,0x07e0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0399\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x301c,0x3038,0x3070,0x30e0,0x31c0,0x3380,0x3700,0x3e00,0x3c00,\n  0x3c00,0x3e00,0x3700,0x3380,0x31c0,0x30e0,0x3070,0x3038,0x301c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u039a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x03c0,0x03c0,0x03c0,0x0660,0x0660,0x0660,0x0c30,\n  0x0c30,0x0c30,0x1818,0x1818,0x1818,0x1818,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u039b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x600c,0x600c,0x701c,0x783c,0x6c6c,0x6c6c,0x67cc,0x638c,0x638c,0x610c,\n  0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u039c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x3c0c,0x3e0c,0x370c,0x338c,\n  0x31cc,0x30ec,0x307c,0x303c,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u039d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,\n  0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u039e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u039f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,\n  0x3ff8,0x3ff0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x3800,0x1c00,0x0e00,0x0700,0x0380,0x01c0,0x00e0,0x0070,\n  0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x1818,0x1818,0x0c30,0x0c30,0x0660,0x0660,0x03c0,\n  0x03c0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0ff0,0x1ff8,0x399c,0x318c,0x318c,0x318c,0x318c,0x318c,\n  0x318c,0x318c,0x318c,0x318c,0x318c,0x399c,0x1ff8,0x0ff0,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x1818,0x1818,0x0c30,0x0c30,0x0660,0x0660,0x03c0,0x03c0,\n  0x03c0,0x03c0,0x0660,0x0660,0x0c30,0x0c30,0x1818,0x1818,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,\n  0x318c,0x318c,0x318c,0x399c,0x1ff8,0x0ff0,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x381c,0x1c38,0x0e70,0x0660,0x0660,0x3e7c,0x3e7c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a9\n  0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x07e0,0x07e0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03aa\n  0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x300c,0x300c,0x300c,0x1818,0x1818,0x0c30,0x0c30,0x0660,0x0660,0x03c0,\n  0x03c0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ab\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x1fcc,0x3ffc,0x7038,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7038,0x3ffc,0x1fcc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ac\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x3000,0x3800,0x1fc0,0x1fc0,0x3800,0x3000,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ad\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x000c,0x000c,0x000c,0x000c,0x000c,0x0000, // u03ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00e0,0x01c0,0x0380,0x0700,0x0000,0x0000,0x0f00,0x0f00,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0380,0x01f0,0x00f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03af\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fcc,0x3ffc,0x7038,0x6030,\n  0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x6030,0x7038,0x3ffc,0x1fcc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fe0,0x3ff0,0x3038,0x3018,0x3018,0x3018,0x3018,0x3030,0x3ff0,0x3ff0,\n  0x3038,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,0x3ff8,0x3ff0,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000, // u03b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x1818,\n  0x1818,0x1818,0x0c30,0x0c30,0x0660,0x0660,0x03c0,0x03c0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000, // u03b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x1ff0,0x0e00,0x0700,0x0380,0x01c0,0x07e0,0x0ff0,0x1818,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x3000,0x3800,0x1fc0,0x1fc0,0x3800,0x3000,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x0038,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,\n  0x1800,0x3800,0x3000,0x3000,0x3000,0x3000,0x3000,0x3800,0x1ff0,0x0ff8,0x001c,0x000c,0x001c,0x0078,0x0070,0x0000, // u03b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x000c,0x000c,0x000c,0x000c,0x000c,0x0000, // u03b7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07e0,0x0ff0,0x1c38,0x1818,0x1818,0x1818,0x1818,0x1818,0x1818,0x1ff8,\n  0x1ff8,0x1818,0x1818,0x1818,0x1818,0x1818,0x1818,0x1c38,0x0ff0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f00,0x0f00,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0380,0x01f0,0x00f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x181c,0x1838,0x1870,0x18e0,\n  0x19c0,0x1b80,0x1f00,0x1f00,0x1b80,0x19c0,0x18e0,0x1870,0x1838,0x181c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0300,0x0300,0x0180,0x0180,0x03c0,0x03c0,0x0660,0x0660,\n  0x0660,0x0c30,0x0c30,0x0c30,0x1818,0x1818,0x1818,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,0x303c,0x307c,0x3fec,0x3fcc,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000, // u03bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x1818,\n  0x1818,0x1818,0x0c30,0x0c30,0x0c30,0x0660,0x0660,0x03c0,0x03c0,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03bd\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ffc,0x1ffc,0x3800,0x3000,0x3000,0x3000,0x3000,0x1800,0x0ff0,0x0ff0,\n  0x1c00,0x3800,0x3000,0x3000,0x3000,0x3000,0x3000,0x3800,0x1ff0,0x0ff8,0x001c,0x000c,0x001c,0x0078,0x0070,0x0000, // u03be\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,0x3ff8,0x3ff0,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000, // u03c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3800,0x1ff0,0x0ff8,0x001c,0x000c,0x001c,0x0078,0x0070,0x0000, // u03c2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ffe,0x1ffe,0x3870,0x3038,\n  0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x01c0,0x00f8,0x0078,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0cf0,0x1df8,0x399c,0x318c,\n  0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x399c,0x1ff8,0x0ff0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000, // u03c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x1818,0x1818,\n  0x0c30,0x0c30,0x0660,0x0660,0x03c0,0x03c0,0x03c0,0x0660,0x0660,0x0c30,0x0c30,0x1818,0x1818,0x300c,0x300c,0x0000, // u03c7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x318c,0x318c,0x318c,0x318c,\n  0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x399c,0x1ff8,0x0ff0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000, // u03c8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x1c38,0x381c,0x300c,\n  0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x3bdc,0x1ff8,0x0e70,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1860,0x1860,0x1860,0x1860,0x0000,0x0000,0x0f00,0x0f00,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0380,0x01f0,0x00f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ca\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03cc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03cd\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x0c30,0x1c38,0x381c,0x300c,\n  0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x3bdc,0x1ff8,0x0e70,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ce\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07e0,0x0ff0,0x1c38,0x1818,0x1818,0x1818,0x1818,0x0ffe,0x07fe,0x0018,\n  0x0018,0x0018,0x7818,0x7818,0x1818,0x1818,0x1818,0x1c38,0x0ff0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0ff0,0x1ff8,0x399c,0x318c,\n  0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x399c,0x1ff8,0x0ff0,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000, // u03d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x780c,0x7c1c,0x0e38,0x0670,\n  0x03e0,0x03c0,0x0380,0x0380,0x0780,0x0f80,0x1cc0,0x38e0,0x707c,0x603c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,0x3ff8,0x3ff0,0x3000,0x3000,0x3800,0x1ff8,0x0ff8,0x0000, // u03f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0078,0x0078,0x0018,0x0018,\n  0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x1818,0x1818,0x1c38,0x0ff0,0x07e0,0x0000, // u03f3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x3ffc,\n  0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03fc,0x0ffc,0x1c00,0x1800,\n  0x3000,0x3000,0x3ff0,0x3ff0,0x3000,0x3000,0x1800,0x1c00,0x0ffc,0x03fc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x3ff0,0x0038,0x0018,\n  0x000c,0x000c,0x0ffc,0x0ffc,0x000c,0x000c,0x0018,0x0038,0x3ff0,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f6\n  0x0000,0x0e00,0x0700,0x0380,0x01c0,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3fe0,\n  0x3fe0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0400\n  0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3fe0,\n  0x3fe0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0401\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1ff0,0x1ff8,0x181c,\n  0x180c,0x180c,0x180c,0x180c,0x180c,0x180c,0x180c,0x181c,0x18f8,0x18f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0402\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0403\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x3000,0x3000,0x3000,0x3000,0x3fe0,\n  0x3fe0,0x3000,0x3000,0x3000,0x3000,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0404\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x3000,0x3000,0x3000,0x3800,0x1ff0,\n  0x0ff8,0x001c,0x000c,0x000c,0x000c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0405\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07e0,0x07e0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0406\n  0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x07e0,0x07e0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0407\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x007e,0x007e,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,\n  0x0018,0x0018,0x0018,0x0018,0x3018,0x3018,0x3018,0x3838,0x1ff0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0408\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x3f80,0x7180,0x6180,0x6180,0x6180,0x6180,0x61f8,0x61fc,0x618e,\n  0x6186,0x6186,0x6186,0x6186,0x6186,0x6186,0x6186,0x618e,0xe1fc,0xc1f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0409\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x61f8,0x61fc,0x7f8e,\n  0x7f86,0x6186,0x6186,0x6186,0x6186,0x6186,0x6186,0x618e,0x61fc,0x61f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u040a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1ff0,0x1ff8,0x181c,\n  0x180c,0x180c,0x180c,0x180c,0x180c,0x180c,0x180c,0x180c,0x180c,0x180c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u040b\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x300c,0x301c,0x3038,0x3070,0x30e0,0x31c0,0x3380,0x3700,0x3e00,0x3c00,\n  0x3c00,0x3e00,0x3700,0x3380,0x31c0,0x30e0,0x3070,0x3038,0x301c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u040c\n  0x0000,0x0e00,0x0700,0x0380,0x01c0,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,0x303c,0x307c,0x30ec,0x31cc,\n  0x338c,0x370c,0x3e0c,0x3c0c,0x380c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u040d\n  0x0000,0x0c30,0x0c30,0x07e0,0x03c0,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,\n  0x1ffc,0x0ffc,0x000c,0x000c,0x000c,0x000c,0x000c,0x001c,0x1ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u040e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x3ffc,0x3ffc,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000, // u040f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0410\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff8,0x3ff8,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ff0,0x3ff8,0x301c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,0x3ff8,0x3ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0411\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,0x300c,0x300c,0x300c,0x3018,0x3ff0,0x3ff0,\n  0x3038,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,0x3ff8,0x3ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0412\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0413\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07f8,0x0ff8,0x1c18,0x1818,0x1818,0x1818,0x1818,0x1818,0x1818,0x1818,\n  0x1818,0x1818,0x1818,0x1818,0x1818,0x1818,0x1818,0x1818,0x3ffc,0x7ffe,0x6006,0x6006,0x6006,0x6006,0x0000,0x0000, // u0414\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3fe0,\n  0x3fe0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0415\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x399c,0x1db8,0x0ff0,0x07e0,\n  0x0ff0,0x1db8,0x399c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0416\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x000c,0x000c,0x000c,0x001c,0x07f8,\n  0x07f8,0x001c,0x000c,0x000c,0x000c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0417\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,0x303c,0x307c,0x30ec,0x31cc,\n  0x338c,0x370c,0x3e0c,0x3c0c,0x380c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0418\n  0x0000,0x0c30,0x0c30,0x07e0,0x03c0,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,0x303c,0x307c,0x30ec,0x31cc,\n  0x338c,0x370c,0x3e0c,0x3c0c,0x380c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0419\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x301c,0x3038,0x3070,0x30e0,0x31c0,0x3380,0x3700,0x3e00,0x3c00,\n  0x3c00,0x3e00,0x3700,0x3380,0x31c0,0x30e0,0x3070,0x3038,0x301c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u041a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03fc,0x07fc,0x0e0c,0x0c0c,0x0c0c,0x0c0c,0x0c0c,0x0c0c,0x0c0c,0x0c0c,\n  0x0c0c,0x0c0c,0x0c0c,0x0c0c,0x0c0c,0x0c0c,0x0c0c,0x0c0c,0x1c0c,0x380c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u041b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x600c,0x600c,0x701c,0x783c,0x6c6c,0x6c6c,0x67cc,0x638c,0x638c,0x610c,\n  0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u041c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x3ffc,\n  0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u041d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u041e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u041f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,\n  0x3ff8,0x3ff0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0420\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0421\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0422\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,\n  0x1ffc,0x0ffc,0x000c,0x000c,0x000c,0x000c,0x000c,0x001c,0x1ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0423\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0ff0,0x1ff8,0x399c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,\n  0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x399c,0x1ff8,0x0ff0,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000, // u0424\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x1818,0x1818,0x0c30,0x0c30,0x0660,0x0660,0x03c0,0x03c0,\n  0x03c0,0x03c0,0x0660,0x0660,0x0c30,0x0c30,0x1818,0x1818,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0425\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380e,0x1fff,0x0fff,0x0003,0x0003,0x0003,0x0003,0x0003,0x0000, // u0426\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,\n  0x1ffc,0x0ffc,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0427\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,\n  0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x398c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0428\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,\n  0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x398c,0x1ffe,0x0fff,0x0003,0x0003,0x0003,0x0003,0x0003,0x0000, // u0429\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf000,0xf000,0x3000,0x3000,0x3000,0x3000,0x3fe0,0x3ff0,0x3038,0x3018,\n  0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3038,0x3ff0,0x3fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u042a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x7f0c,0x7f8c,0x61cc,0x60cc,\n  0x60cc,0x60cc,0x60cc,0x60cc,0x60cc,0x60cc,0x60cc,0x61cc,0x7f8c,0x7f0c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u042b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3fe0,0x3ff0,0x3038,0x3018,\n  0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3038,0x3ff0,0x3fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u042c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x000c,0x000c,0x000c,0x000c,0x07fc,\n  0x07fc,0x000c,0x000c,0x000c,0x000c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u042d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60f0,0x61f8,0x639c,0x630c,0x630c,0x630c,0x630c,0x630c,0x630c,0x7f0c,\n  0x7f0c,0x630c,0x630c,0x630c,0x630c,0x630c,0x630c,0x639c,0x61f8,0x60f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u042e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ffc,0x1ffc,0x380c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,\n  0x1ffc,0x0ffc,0x00ec,0x01cc,0x038c,0x070c,0x0e0c,0x1c0c,0x380c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u042f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x1ff8,0x001c,0x000c,\n  0x000c,0x0ffc,0x1ffc,0x380c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0430\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff0,0x3800,0x3000,0x3000,0x3000,0x3000,0x3ff0,0x3ff8,0x301c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,0x3ff8,0x3ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0431\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x3fe0,0x3070,0x3030,0x3030,0x3030,0x3030,0x3070,0x3fe0,0x3ff0,\n  0x3038,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,0x3ff8,0x3ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0432\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0433\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ffc,0x1ffc,0x380c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x000c,0x000c,0x001c,0x1ff8,0x1ff0,0x0000, // u0434\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x380c,0x1ffc,0x0ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0435\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x318c,0x318c,0x318c,0x399c,\n  0x1db8,0x0ff0,0x07e0,0x0ff0,0x1db8,0x399c,0x318c,0x318c,0x318c,0x318c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0436\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x000c,0x001c,0x03f8,0x03f8,0x001c,0x000c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0437\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0438\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x07e0,0x03c0,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0439\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x181c,0x1838,0x1870,0x18e0,\n  0x19c0,0x1b80,0x1f00,0x1f00,0x1b80,0x19c0,0x18e0,0x1870,0x1838,0x181c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u043a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03fc,0x07fc,0x0e0c,0x0c0c,\n  0x0c0c,0x0c0c,0x0c0c,0x0c0c,0x0c0c,0x0c0c,0x0c0c,0x0c0c,0x1c0c,0x380c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u043b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x600c,0x701c,0x783c,0x7c7c,\n  0x6eec,0x67cc,0x638c,0x610c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u043c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u043d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u043e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u043f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,0x3ff8,0x3ff0,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000, // u0440\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0441\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0442\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x000c,0x000c,0x001c,0x1ff8,0x1ff0,0x0000, // u0443\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0ff0,0x1ff8,0x399c,0x318c,\n  0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x399c,0x1ff8,0x0ff0,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000, // u0444\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x381c,0x1c38,\n  0x0e70,0x07e0,0x03c0,0x03c0,0x07e0,0x0e70,0x1c38,0x381c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0445\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffe,0x0fff,0x0003,0x0003,0x0003,0x0003,0x0003,0x0000, // u0446\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x380c,0x1ffc,0x0ffc,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0447\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x318c,0x318c,0x318c,0x318c,\n  0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x398c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0448\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x318c,0x318c,0x318c,0x318c,\n  0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x398c,0x1ffe,0x0fff,0x0003,0x0003,0x0003,0x0003,0x0003,0x0000, // u0449\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3c00,0x3c00,0x0c00,0x0c00,\n  0x0ff0,0x0ff8,0x0c1c,0x0c0c,0x0c0c,0x0c0c,0x0c0c,0x0c1c,0x0ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u044a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x600c,0x600c,0x600c,0x600c,\n  0x7f0c,0x7f8c,0x61cc,0x60cc,0x60cc,0x60cc,0x60cc,0x61cc,0x7f8c,0x7f0c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u044b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,\n  0x1fe0,0x1ff0,0x1838,0x1818,0x1818,0x1818,0x1818,0x1838,0x1ff0,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u044c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x000c,0x000c,0x03fc,0x03fc,0x000c,0x000c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u044d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60f0,0x61f8,0x630c,0x630c,\n  0x630c,0x630c,0x7f0c,0x7f0c,0x630c,0x630c,0x630c,0x630c,0x61f8,0x60f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u044e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ffc,0x1ffc,0x380c,0x300c,\n  0x300c,0x380c,0x1ffc,0x0ffc,0x00ec,0x01cc,0x038c,0x070c,0x0e0c,0x1c0c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u044f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x0700,0x0380,0x01c0,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x380c,0x1ffc,0x0ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0450\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x380c,0x1ffc,0x0ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0451\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0xff80,0xff80,0x3000,0x3000,0x3ff0,0x3ff8,0x301c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x000c,0x000c,0x001c,0x00f8,0x00f0,0x0000, // u0452\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0453\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x3000,0x3000,0x3fc0,0x3fc0,0x3000,0x3000,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0454\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x3000,\n  0x3000,0x3800,0x1ff0,0x0ff8,0x001c,0x000c,0x000c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0455\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0780,0x0780,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0456\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x0780,0x0780,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0457\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0078,0x0078,0x0018,0x0018,\n  0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x1818,0x1818,0x1c38,0x0ff0,0x07e0,0x0000, // u0458\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f80,0x1f80,0x3980,0x3180,\n  0x31f8,0x31fc,0x318e,0x3186,0x3186,0x3186,0x3186,0x318e,0x71fc,0x61f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0459\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,\n  0x61f8,0x61fc,0x7f8e,0x7f86,0x6186,0x6186,0x6186,0x618e,0x61fc,0x61f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u045a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0xff80,0xff80,0x3000,0x3000,0x3ff0,0x3ff8,0x301c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u045b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x181c,0x1838,0x1870,0x18e0,\n  0x19c0,0x1b80,0x1f00,0x1f00,0x1b80,0x19c0,0x18e0,0x1870,0x1838,0x181c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u045c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x0700,0x0380,0x01c0,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u045d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x07e0,0x03c0,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x000c,0x000c,0x001c,0x1ff8,0x1ff0,0x0000, // u045e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x3ffc,0x3ffc,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000, // u045f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0xff00,0xff00,0x3000,0x3000,0x3fe0,0x3ff0,0x3038,0x3018,\n  0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3018,0x3038,0x3ff0,0x3fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0462\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x3fc0,0x3fc0,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0ff0,0x0ff8,0x0c1c,0x0c0c,0x0c0c,0x0c0c,0x0c0c,0x0c1c,0x0ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0463\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x300c,0x1818,0x1818,0x0c30,0x0c30,0x0660,0x03c0,0x07e0,\n  0x0ff0,0x1db8,0x399c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u046a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x300c,0x381c,\n  0x1c38,0x0e70,0x07e0,0x0ff0,0x1db8,0x399c,0x318c,0x318c,0x318c,0x318c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u046b\n  0x0000,0x0000,0x000c,0x000c,0x000c,0x000c,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0490\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000c,0x000c,0x000c,0x000c,0x3ffc,0x3ffc,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0491\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x7f80,\n  0x7f80,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0492\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,\n  0x3000,0x3000,0x7f80,0x7f80,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0493\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3ff0,0x3ff8,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x000c,0x000c,0x0018,0x0030,0x0000,0x0000, // u0494\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3fc0,0x3fe0,0x3070,0x3030,0x3030,0x3030,0x3030,0x0030,0x0030,0x0060,0x00c0,0x0000,0x0000, // u0495\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x399c,0x1db8,0x0ff0,0x07e0,\n  0x0ff0,0x1db8,0x399c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318e,0x318f,0x0003,0x0003,0x0003,0x0003,0x0003,0x0000, // u0496\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x318c,0x318c,0x318c,0x399c,\n  0x1db8,0x0ff0,0x07e0,0x0ff0,0x1db8,0x399c,0x318c,0x318c,0x318e,0x318f,0x0003,0x0003,0x0003,0x0003,0x0003,0x0000, // u0497\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x000c,0x000c,0x000c,0x001c,0x07f8,\n  0x07f8,0x001c,0x000c,0x000c,0x000c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000, // u0498\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x000c,0x001c,0x03f8,0x03f8,0x001c,0x000c,0x300c,0x381c,0x1ff8,0x0ff0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000, // u0499\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x301c,0x3038,0x3070,0x30e0,0x31c0,0x3380,0x3700,0x3e00,0x3c00,\n  0x3c00,0x3e00,0x3700,0x3380,0x31c0,0x30e0,0x3070,0x3038,0x301c,0x300e,0x0006,0x0006,0x0006,0x0006,0x0006,0x0000, // u049a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x181c,0x1838,0x1870,0x18e0,\n  0x19c0,0x1b80,0x1f00,0x1f00,0x1b80,0x19c0,0x18e0,0x1870,0x1838,0x181c,0x000c,0x000c,0x000c,0x000c,0x000c,0x0000, // u049b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x600c,0x600c,0x601c,0x6038,0x6c70,0x6ce0,0x6dc0,0x6f80,0x6f00,0x7e00,\n  0x7e00,0x6f00,0x6f80,0x6dc0,0x6ce0,0x6c70,0x6038,0x601c,0x600c,0x600c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u049c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x301c,0x3638,0x3670,\n  0x36e0,0x37c0,0x3f80,0x3f80,0x37c0,0x36e0,0x3670,0x3638,0x301c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u049d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf00c,0xf01c,0x3038,0x3070,0x30e0,0x31c0,0x3380,0x3700,0x3e00,0x3c00,\n  0x3c00,0x3e00,0x3700,0x3380,0x31c0,0x30e0,0x3070,0x3038,0x301c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x781c,0x7838,0x1870,0x18e0,\n  0x19c0,0x1b80,0x1f00,0x1f00,0x1b80,0x19c0,0x18e0,0x1870,0x1838,0x181c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x3ffc,\n  0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300e,0x300f,0x0003,0x0003,0x0003,0x0003,0x0003,0x0000, // u04a2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300e,0x300f,0x0003,0x0003,0x0003,0x0003,0x0003,0x0000, // u04a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x607f,0x607f,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x7fe0,\n  0x7fe0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x607f,0x607f,0x6060,0x6060,\n  0x6060,0x6060,0x7fe0,0x7fe0,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000, // u04aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x300c,0x381c,0x1ff8,0x0ff0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000, // u04ab\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x1818,0x1818,0x0c30,0x0c30,0x0660,0x0660,0x03c0,\n  0x03c0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x1818,\n  0x1818,0x1818,0x0c30,0x0c30,0x0660,0x0660,0x03c0,0x03c0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000, // u04af\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x1818,0x1818,0x0c30,0x0c30,0x0660,0x0660,0x03c0,\n  0x03c0,0x0180,0x1ff8,0x1ff8,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x1818,\n  0x1818,0x1818,0x0c30,0x0c30,0x0660,0x0660,0x03c0,0x03c0,0x0180,0x1ff8,0x1ff8,0x0180,0x0180,0x0180,0x0180,0x0000, // u04b1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x1818,0x1818,0x0c30,0x0c30,0x0660,0x0660,0x03c0,0x03c0,\n  0x03c0,0x03c0,0x0660,0x0660,0x0c30,0x0c30,0x1818,0x1818,0x300e,0x300f,0x0003,0x0003,0x0003,0x0003,0x0003,0x0000, // u04b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x381c,0x1c38,\n  0x0e70,0x07e0,0x03c0,0x03c0,0x07e0,0x0e70,0x1c38,0x381c,0x300e,0x300f,0x0003,0x0003,0x0003,0x0003,0x0003,0x0000, // u04b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,\n  0x1ffc,0x0ffc,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000e,0x000f,0x0003,0x0003,0x0003,0x0003,0x0003,0x0000, // u04b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x380c,0x1ffc,0x0ffc,0x000c,0x000c,0x000c,0x000c,0x000e,0x000f,0x0003,0x0003,0x0003,0x0003,0x0003,0x0000, // u04b7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x318c,0x318c,0x318c,0x398c,\n  0x1ffc,0x0ffc,0x018c,0x018c,0x018c,0x018c,0x000c,0x000c,0x000c,0x000c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x318c,\n  0x318c,0x398c,0x1ffc,0x0ffc,0x018c,0x018c,0x018c,0x000c,0x000c,0x000c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04b9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ff0,0x3ff8,\n  0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3ff0,0x3ff8,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07e0,0x07e0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04c0\n  0x0000,0x0c30,0x0c30,0x07e0,0x03c0,0x0000,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x399c,0x1db8,0x0ff0,0x07e0,\n  0x0ff0,0x1db8,0x399c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x07e0,0x03c0,0x0000,0x0000,0x318c,0x318c,0x318c,0x399c,\n  0x1db8,0x0ff0,0x07e0,0x0ff0,0x1db8,0x399c,0x318c,0x318c,0x318c,0x318c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04c2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0780,0x0780,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04cf\n  0x0000,0x0c30,0x0c30,0x07e0,0x03c0,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x07e0,0x03c0,0x0000,0x0000,0x1ff0,0x1ff8,0x001c,0x000c,\n  0x000c,0x0ffc,0x1ffc,0x380c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d1\n  0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x1ff0,0x1ff8,0x001c,0x000c,\n  0x000c,0x0ffc,0x1ffc,0x380c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fff,0x3fff,0x70c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x7ffe,\n  0x7ffe,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60ff,0x60ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ef8,0x3ffc,0x018e,0x0186,\n  0x0186,0x1f86,0x3ffe,0x71fe,0x6180,0x6180,0x6180,0x71c6,0x3ffe,0x1f7c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d5\n  0x0000,0x0c30,0x0c30,0x07e0,0x03c0,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3fe0,\n  0x3fe0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x07e0,0x03c0,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x380c,0x1ffc,0x0ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x000c,0x000c,0x000c,0x000c,0x3ffc,\n  0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x301c,0x000c,\n  0x000c,0x000c,0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d9\n  0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x000c,0x000c,0x000c,0x000c,0x3ffc,\n  0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04da\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x1ff0,0x3ff8,0x301c,0x000c,\n  0x000c,0x000c,0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04db\n  0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x399c,0x1db8,0x0ff0,0x07e0,\n  0x0ff0,0x1db8,0x399c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04dc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x318c,0x318c,0x318c,0x399c,\n  0x1db8,0x0ff0,0x07e0,0x0ff0,0x1db8,0x399c,0x318c,0x318c,0x318c,0x318c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04dd\n  0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x000c,0x000c,0x000c,0x001c,0x07f8,\n  0x07f8,0x001c,0x000c,0x000c,0x000c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04de\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x000c,0x001c,0x03f8,0x03f8,0x001c,0x000c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04df\n  0x0000,0x0000,0x0ff0,0x0ff0,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,0x303c,0x307c,0x30ec,0x31cc,\n  0x338c,0x370c,0x3e0c,0x3c0c,0x380c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x0ff0,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e3\n  0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,0x303c,0x307c,0x30ec,0x31cc,\n  0x338c,0x370c,0x3e0c,0x3c0c,0x380c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e5\n  0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x3ffc,\n  0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e9\n  0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x3ffc,\n  0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04eb\n  0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x000c,0x000c,0x000c,0x000c,0x07fc,\n  0x07fc,0x000c,0x000c,0x000c,0x000c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ec\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x000c,0x000c,0x03fc,0x03fc,0x000c,0x000c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ed\n  0x0000,0x0000,0x0ff0,0x0ff0,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,\n  0x1ffc,0x0ffc,0x000c,0x000c,0x000c,0x000c,0x000c,0x001c,0x1ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ee\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x0ff0,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x000c,0x000c,0x001c,0x1ff8,0x1ff0,0x0000, // u04ef\n  0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,\n  0x1ffc,0x0ffc,0x000c,0x000c,0x000c,0x000c,0x000c,0x001c,0x1ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x000c,0x000c,0x001c,0x1ff8,0x1ff0,0x0000, // u04f1\n  0x0000,0x01ce,0x039c,0x0738,0x0e70,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,\n  0x1ffc,0x0ffc,0x000c,0x000c,0x000c,0x000c,0x000c,0x001c,0x1ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01ce,0x039c,0x0738,0x0e70,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x000c,0x000c,0x001c,0x1ff8,0x1ff0,0x0000, // u04f3\n  0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,\n  0x1ffc,0x0ffc,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x380c,0x1ffc,0x0ffc,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f5\n  0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x7f0c,0x7f8c,0x61cc,0x60cc,\n  0x60cc,0x60cc,0x60cc,0x60cc,0x60cc,0x60cc,0x60cc,0x61cc,0x7f8c,0x7f0c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x600c,0x600c,0x600c,0x600c,\n  0x7f0c,0x7f8c,0x61cc,0x60cc,0x60cc,0x60cc,0x60cc,0x61cc,0x7f8c,0x7f0c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x180c,0x180c,0x0c0c,0x0c0c,0x060c,0x061c,0x0338,0x07f0,\n  0x0fe0,0x1cc0,0x3860,0x3060,0x3030,0x3030,0x3018,0x3018,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x7ff0,0x0038,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,\n  0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x7ffe,0x7ffe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x1fc0,0x00e0,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x00f0,0x01f0,0x0398,0x0718,0x0e0c,0x1c0c,0x3806,0x7006,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffe,0x7ffe,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,\n  0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x001c,0x000c,0x000c,0x000c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x1f00,0x0380,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff8,0x1ff8,0x0070,0x00e0,0x01c0,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30f0,0x30f8,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x1f00,0x0380,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x001c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,\n  0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x0000, // u05da\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x001c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,\n  0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x001c,0x3ff8,0x3ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05db\n  0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x001c,0x0038,\n  0x0070,0x00e0,0x01c0,0x0380,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05dc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05dd\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xe7c0,0xfff0,0x7838,0x3018,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x30fc,0x30fc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05de\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x1fc0,0x00e0,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0000, // u05df\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x0fe0,0x0070,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,\n  0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0030,0x0ff0,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff8,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x180c,0x180c,0x180c,0x0c0c,0x0c0c,0x0c0c,0x0618,\n  0x0618,0x0618,0x0330,0x0330,0x0330,0x01e0,0x01c0,0x0380,0x3f00,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1f0c,\n  0x0f0c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x0000, // u05e3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1f0c,\n  0x0f0c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x001c,0x3ff8,0x3ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x180c,0x180c,0x0c0c,0x0c1c,0x0638,0x0670,0x03e0,0x03c0,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000, // u05e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x180c,0x180c,0x0c0c,0x0c1c,0x0638,0x0670,0x03e0,0x03c0,\n  0x0180,0x0180,0x00c0,0x00c0,0x0060,0x0060,0x0030,0x0030,0x3ff8,0x3ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x000c,0x000c,0x000c,0x000c,0x300c,0x300c,0x301c,0x3038,\n  0x3070,0x30e0,0x31c0,0x3380,0x3300,0x3300,0x3300,0x3300,0x3300,0x3300,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000, // u05e7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x001c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,\n  0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x338c,\n  0x3f0c,0x3e0c,0x300c,0x300c,0x300c,0x300c,0x300c,0x301c,0x3ff8,0x3ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff8,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0xf00c,0xe00c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x3ff0,0x3038,0x3018,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x3018,0x3038,0x3ff0,0x3fc0,0x0000,0x0300,0x0300,0x0300,0x0300,0x0000, // u1e0c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x0ffc,0x1ffc,0x380c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x00c0,0x00c0,0x00c0,0x00c0,0x0000, // u1e0d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x301c,0x3038,0x3070,0x30e0,0x31c0,0x3380,0x3700,0x3e00,0x3c00,\n  0x3c00,0x3e00,0x3700,0x3380,0x31c0,0x30e0,0x3070,0x3038,0x301c,0x300c,0x0000,0x0000,0x0ff0,0x0ff0,0x0000,0x0000, // u1e34\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x181c,0x1838,0x1870,0x18e0,\n  0x19c0,0x1b80,0x1f00,0x1f00,0x1b80,0x19c0,0x18e0,0x1870,0x1838,0x181c,0x0000,0x0000,0x07f0,0x07f0,0x0000,0x0000, // u1e35\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000, // u1e36\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0780,0x0780,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000, // u1e37\n  0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x600c,0x600c,0x701c,0x783c,0x6c6c,0x6c6c,0x67cc,0x638c,0x638c,0x610c,\n  0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e40\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x3ff0,0x3ff8,0x319c,0x318c,\n  0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e41\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x600c,0x600c,0x701c,0x783c,0x6c6c,0x6c6c,0x67cc,0x638c,0x638c,0x610c,\n  0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x600c,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000, // u1e42\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x319c,0x318c,\n  0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000, // u1e43\n  0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x3c0c,0x3e0c,0x370c,0x338c,\n  0x31cc,0x30ec,0x307c,0x303c,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e44\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e45\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x3c0c,0x3e0c,0x370c,0x338c,\n  0x31cc,0x30ec,0x307c,0x303c,0x301c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000, // u1e46\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x301c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000, // u1e47\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000, // u1e6c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x3ff0,0x3ff0,0x0300,0x0300,\n  0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0380,0x01fc,0x00fc,0x0000,0x0030,0x0030,0x0030,0x0030,0x0000, // u1e6d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3fe0,\n  0x3fe0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000, // u1eb8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x380c,0x1ffc,0x0ff8,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000, // u1eb9\n  0x0000,0x0f18,0x1b98,0x19d8,0x18f0,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3fe0,\n  0x3fe0,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1ebc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f18,0x1b98,0x19d8,0x18f0,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x3ffc,0x3ffc,0x3000,0x3000,0x3000,0x380c,0x1ffc,0x0ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1ebd\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07e0,0x07e0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000, // u1eca\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0780,0x0780,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000, // u1ecb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000, // u1ecc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000, // u1ecd\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,0x0ff0,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000, // u1ee4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x0000,0x00c0,0x00c0,0x00c0,0x00c0,0x0000, // u1ee5\n  0x0000,0x0f18,0x1b98,0x19d8,0x18f0,0x0000,0x300c,0x300c,0x300c,0x1818,0x1818,0x0c30,0x0c30,0x0660,0x0660,0x03c0,\n  0x03c0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1ef8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f18,0x1b98,0x19d8,0x18f0,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x380c,0x1ffc,0x0ffc,0x000c,0x000c,0x001c,0x1ff8,0x1ff0,0x0000, // u1ef9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2001\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2002\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2003\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2004\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2005\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2006\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2007\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2008\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2009\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff8,\n  0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2010\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff8,\n  0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2011\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,\n  0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2012\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,\n  0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2013\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,\n  0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2014\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,\n  0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2015\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,\n  0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2016\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x0000,0x0000,0x3ffc,0x3ffc, // u2017\n  0x0000,0x0000,0x0000,0x0000,0x00c0,0x00c0,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2018\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2019\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000, // u201a\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x00c0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201b\n  0x0000,0x0000,0x0000,0x0000,0x0618,0x0618,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201c\n  0x0000,0x0000,0x0000,0x0000,0x0618,0x0618,0x0618,0x0618,0x0c30,0x0c30,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x1860,0x1860,0x0000,0x0000,0x0000,0x0000, // u201e\n  0x0000,0x0000,0x0000,0x0000,0x1860,0x1860,0x1860,0x1860,0x0c30,0x0c30,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x1ff8,0x1ff8,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2020\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x1ff8,0x1ff8,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x1ff8,0x1ff8,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2021\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03c0,0x07e0,0x07e0,\n  0x07e0,0x07e0,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2022\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x318c,0x318c,0x318c,0x318c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2026\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c30,0x3e30,0x3660,0x3660,0x3ec0,0x1cc0,0x0180,0x0180,0x0300,0x0300,\n  0x0600,0x0600,0x0c00,0x0c00,0x19dc,0x1bfe,0x3376,0x3376,0x63fe,0x61dc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2030\n  0x0000,0x0000,0x0000,0x0000,0x01c0,0x01c0,0x01c0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2032\n  0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x1c70,0x1860,0x1860,0x1860,0x1860,0x1860,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2033\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,\n  0x0700,0x0e00,0x1c00,0x1c00,0x0e00,0x0700,0x0380,0x01c0,0x00e0,0x0070,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0e00,0x0700,0x0380,\n  0x01c0,0x00e0,0x0070,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u203a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0c30,0x0c30,0x0c30,0x0c30,0x0c30,0x0c30,\n  0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x0000,0x0c30,0x0c30,0x0c30,0x0c30,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u203c\n  0x0000,0x0000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u203e\n  0x0000,0x0000,0x0000,0x03c0,0x07e0,0x0c30,0x0c30,0x0c30,0x0c30,0x0c30,0x0c30,0x0c30,0x07e0,0x03c0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2070\n  0x0180,0x0180,0x0180,0x0000,0x0780,0x0780,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2071\n  0x0000,0x0000,0x0000,0x0030,0x0070,0x00f0,0x01f0,0x03b0,0x0730,0x0e30,0x0ff0,0x0ff0,0x0030,0x0030,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2074\n  0x0000,0x0000,0x0000,0x0fe0,0x0fe0,0x0c00,0x0c00,0x0fe0,0x0ff0,0x0030,0x0030,0x0c30,0x0ff0,0x07e0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2075\n  0x0000,0x0000,0x0000,0x03e0,0x07e0,0x0c00,0x0c00,0x0fe0,0x0ff0,0x0c30,0x0c30,0x0c30,0x0ff0,0x07e0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2076\n  0x0000,0x0000,0x0000,0x0ff0,0x0ff0,0x0c30,0x0030,0x0060,0x0060,0x00c0,0x00c0,0x0180,0x0180,0x0180,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2077\n  0x0000,0x0000,0x0000,0x07e0,0x0ff0,0x0c30,0x0c30,0x0ff0,0x07e0,0x0c30,0x0c30,0x0c30,0x0ff0,0x07e0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2078\n  0x0000,0x0000,0x0000,0x07e0,0x0ff0,0x0c30,0x0c30,0x0c30,0x0ff0,0x07f0,0x0030,0x0030,0x07e0,0x07c0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2079\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0ff0,0x0ff0,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207c\n  0x0000,0x0000,0x0000,0x00c0,0x0180,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0180,0x00c0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207d\n  0x0000,0x0000,0x0000,0x0300,0x0180,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x0180,0x0300,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207e\n  0x0000,0x0000,0x0000,0x0000,0x1fc0,0x1fe0,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x03c0,0x07e0,0x0c30,0x0c30,0x0c30,0x0c30,0x0c30,0x0c30,0x0c30,0x07e0,0x03c0,0x0000,0x0000,0x0000, // u2080\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0180,0x0380,0x0780,0x0780,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000, // u2081\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x07e0,0x0ff0,0x0c30,0x0c30,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0ff0,0x0ff0,0x0000,0x0000,0x0000, // u2082\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x07e0,0x0ff0,0x0c30,0x0030,0x01e0,0x01e0,0x0030,0x0030,0x0c30,0x0ff0,0x07e0,0x0000,0x0000,0x0000, // u2083\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0030,0x0070,0x00f0,0x01f0,0x03b0,0x0730,0x0e30,0x0ff0,0x0ff0,0x0030,0x0030,0x0000,0x0000,0x0000, // u2084\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0fe0,0x0fe0,0x0c00,0x0c00,0x0fe0,0x0ff0,0x0030,0x0030,0x0c30,0x0ff0,0x07e0,0x0000,0x0000,0x0000, // u2085\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x03e0,0x07e0,0x0c00,0x0c00,0x0fe0,0x0ff0,0x0c30,0x0c30,0x0c30,0x0ff0,0x07e0,0x0000,0x0000,0x0000, // u2086\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0ff0,0x0ff0,0x0c30,0x0030,0x0060,0x0060,0x00c0,0x00c0,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000, // u2087\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x07e0,0x0ff0,0x0c30,0x0c30,0x0ff0,0x07e0,0x0c30,0x0c30,0x0c30,0x0ff0,0x07e0,0x0000,0x0000,0x0000, // u2088\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x07e0,0x0ff0,0x0c30,0x0c30,0x0c30,0x0ff0,0x07f0,0x0030,0x0030,0x07e0,0x07c0,0x0000,0x0000,0x0000, // u2089\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0ff0,0x0ff0,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000, // u208a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u208b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000, // u208c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x00c0,0x0180,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0180,0x00c0,0x0000,0x0000,0x0000, // u208d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0300,0x0180,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x0180,0x0300,0x0000,0x0000,0x0000, // u208e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0fc0,0x0fe0,0x0030,0x0030,0x0ff0,0x1ff0,0x1830,0x1830,0x1ff0,0x0ff0,0x0000,0x0000,0x0000, // u2090\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x07c0,0x0fe0,0x1830,0x1830,0x1ff0,0x1ff0,0x1800,0x1800,0x0ff0,0x07e0,0x0000,0x0000,0x0000, // u2091\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x07c0,0x0fe0,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,0x0fe0,0x07c0,0x0000,0x0000,0x0000, // u2092\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x1830,0x1c70,0x0ee0,0x07c0,0x0380,0x0380,0x07c0,0x0ee0,0x1c70,0x1830,0x0000,0x0000,0x0000, // u2093\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0fc0,0x1fe0,0x0030,0x0030,0x1ff0,0x1ff0,0x1830,0x1830,0x0fe0,0x07c0,0x0000,0x0000,0x0000, // u2094\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,\n  0x1800,0x1800,0x1800,0x1fc0,0x1fe0,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,0x0000,0x0000,0x0000, // u2095\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c38,0x0c70,0x0ce0,0x0dc0,0x0f80,0x0f80,0x0dc0,0x0ce0,0x0c70,0x0c38,0x0000,0x0000,0x0000, // u2096\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0780,\n  0x0780,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000, // u2097\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x318c,0x0000,0x0000,0x0000, // u2098\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x1fc0,0x1fe0,0x1830,0x1830,0x1830,0x1830,0x1830,0x1830,0x1fe0,0x1fc0,0x1800,0x1800,0x1800, // u209a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x7f80,0x61c0,0x60c0,0x60c0,0x60c0,0x60c0,0x60c0,0x61c0,0x7fb0,\n  0x7f30,0x6030,0x61fe,0x61fe,0x6030,0x6030,0x6030,0x6030,0x603e,0x601e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u20a7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f86,0x7fc6,0x60e6,0x6066,0x6066,0x6066,0x6666,0x6666,0x6666,0x6666,\n  0x6666,0x6666,0x6666,0x6666,0x6606,0x6606,0x6606,0x660e,0x67fc,0x67f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u20aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03f0,0x07f8,0x0e1c,0x1c0e,0x3800,0x3000,0x3000,0xffc0,0xffc0,0x3000,\n  0x3000,0xffc0,0xffc0,0x3000,0x3000,0x3800,0x1c0e,0x0e1c,0x07f8,0x03f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u20ac\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x0180,0x0180,0x0180,0x0180,0x0180,0x01b8,0x01f0,0x03c0,\n  0x0fb8,0x1df0,0x03c0,0x0f80,0x1d80,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u20ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x3e1c,0x360c,0x360c,0x3600,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x360c,0x360c,0x3e1c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2102\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3ff0,0x3ff8,0x301c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u210e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0xff80,0xff80,0x3000,0x3000,0x3ff0,0x3ff8,0x301c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u210f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x380c,0x3c0c,0x360c,0x3b0c,0x3d8c,0x36cc,\n  0x336c,0x31bc,0x30dc,0x306c,0x303c,0x301c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2115\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc180,0xc19c,0xc1be,0xe1b6,0xe1b6,0xf1be,0xf19c,0xf980,0xd980,0xdd80,\n  0xcd80,0xcf80,0xc780,0xc7be,0xc3be,0xc380,0xc1be,0xc1be,0xc180,0xc180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2116\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x3e1c,0x360c,0x360c,0x360c,0x360c,0x360c,0x360c,0x360c,\n  0x360c,0x360c,0x360c,0x360c,0x360c,0x360c,0x36cc,0x3efc,0x1ff8,0x0ff8,0x001c,0x000e,0x0000,0x0000,0x0000,0x0000, // u211a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x361c,0x360c,0x360c,0x360c,0x360c,0x360c,0x360c,0x361c,\n  0x37f8,0x37f0,0x36c0,0x3760,0x37b0,0x36d8,0x366c,0x3636,0x361a,0x3e0e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u211d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7e82,0x7ec6,0x18fe,0x18d6,0x18c6,0x18c6,0x18c6,0x18c6,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2122\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x000c,0x000c,0x001c,0x003c,0x006c,0x00d8,0x01b0,0x0360,\n  0x06c0,0x0d80,0x1b00,0x3600,0x3c00,0x3800,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2124\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x381c,0x1c38,0x0e70,0x0660,0x0660,0x3e7c,0x3e7c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2126\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3030,0x3030,0x1818,0x1818,0x0c0c,0x0c0c,0x0606,0x0e0e,0x1f1c,0x3b38,\n  0x71f0,0x61e0,0x60c0,0x60c0,0x6060,0x6060,0x6030,0x7030,0x3818,0x1c18,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2135\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0700,0x0e00,0x1c00,0x3800,0x7ffe,\n  0x7ffe,0x3800,0x1c00,0x0e00,0x0700,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2190\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x03c0,0x07e0,0x0ff0,0x1db8,0x399c,0x318c,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2191\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00e0,0x0070,0x0038,0x001c,0x7ffe,\n  0x7ffe,0x001c,0x0038,0x0070,0x00e0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2192\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x318c,0x399c,0x1db8,0x0ff0,0x07e0,0x03c0,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2193\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0660,0x0e70,0x1c38,0x381c,0x700e,0xffff,\n  0xffff,0x700e,0x381c,0x1c38,0x0e70,0x0660,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2194\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x03c0,0x07e0,0x0ff0,0x1db8,0x399c,0x318c,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x318c,0x399c,0x1db8,0x0ff0,0x07e0,0x03c0,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2195\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0306,0x0706,0x0e06,0x1c06,0x3806,0x7ffe,\n  0x7ffe,0x3806,0x1c06,0x0e06,0x0706,0x0306,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60e0,0x6070,0x6038,0x601c,0x7ffe,\n  0x7ffe,0x601c,0x6038,0x6070,0x60e0,0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x03c0,0x07e0,0x0ff0,0x1db8,0x399c,0x318c,0x0180,0x0180,0x0180,\n  0x0180,0x318c,0x399c,0x1db8,0x0ff0,0x07e0,0x03c0,0x0180,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x030c,0x070c,\n  0x0e0c,0x1c0c,0x380c,0x7ffc,0x7ffc,0x3800,0x1c00,0x0e00,0x0700,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f00,0x7f00,0x1f00,0x3b18,0x3318,0x630c,0x600c,\n  0x600c,0x600c,0x600c,0x3018,0x3838,0x1ff0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x1800,0x3800,0x7000,0xfffe,0xfffe,0x0000,\n  0x0000,0xfffe,0xfffe,0x001c,0x0038,0x0030,0x0020,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0020,0x0030,0x0038,0x001c,0xfffe,0xfffe,0x0000,\n  0x0000,0xfffe,0xfffe,0x7000,0x3800,0x1800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21cc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0e00,0x1c00,0x3ffe,0x7ffe,0xf000,\n  0xf000,0x7ffe,0x3ffe,0x1c00,0x0e00,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x03c0,0x07e0,0x0ff0,0x1e78,0x3e7c,0x366c,0x0660,0x0660,0x0660,\n  0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00e0,0x0070,0xfff8,0xfffc,0x001e,\n  0x001e,0xfffc,0xfff8,0x0070,0x00e0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,\n  0x0660,0x0660,0x0660,0x366c,0x3e7c,0x1e78,0x0ff0,0x07e0,0x03c0,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0660,0x0e70,0x1c38,0x3ffc,0x7ffe,0xf00f,\n  0xf00f,0x7ffe,0x3ffc,0x1c38,0x0e70,0x0660,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x03c0,0x07e0,0x0ff0,0x1e78,0x3e7c,0x366c,0x0660,0x0660,0x0660,\n  0x0660,0x0660,0x0660,0x366c,0x3e7c,0x1e78,0x0ff0,0x07e0,0x03c0,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x600c,0x600c,0x600c,0x600c,0x3018,0x3018,0x3ff8,0x3ff8,0x1830,0x1830,\n  0x1830,0x0c60,0x0c60,0x0c60,0x06c0,0x06c0,0x06c0,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2200\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x3ffc,\n  0x3ffc,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x000c,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2203\n  0x0000,0x0000,0x0000,0x000c,0x000c,0x001c,0x3ffc,0x3ffc,0x003c,0x006c,0x006c,0x00cc,0x00cc,0x018c,0x018c,0x3ffc,\n  0x3ffc,0x030c,0x030c,0x060c,0x060c,0x0c0c,0x0c0c,0x180c,0x3ffc,0x3ffc,0x3000,0x6000,0x6000,0x0000,0x0000,0x0000, // u2204\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0030,0x0030,0x0fe0,0x1ff0,0x30d8,0x30d8,0x3198,0x3198,\n  0x3318,0x3318,0x3618,0x3618,0x1ff0,0x0fe0,0x1800,0x1800,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2205\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x03c0,0x03c0,0x03c0,0x0660,0x0660,0x0660,0x0c30,\n  0x0c30,0x0c30,0x1818,0x1818,0x1818,0x300c,0x300c,0x300c,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2206\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x1818,0x1818,0x1818,0x0c30,0x0c30,\n  0x0c30,0x0660,0x0660,0x0660,0x03c0,0x03c0,0x03c0,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2207\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01fc,0x07fc,0x0e00,0x1800,0x1800,0x3000,0x3000,0x3000,0x3000,0x3ffc,\n  0x3ffc,0x3000,0x3000,0x3000,0x3000,0x1800,0x1800,0x0e00,0x07fc,0x01fc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2208\n  0x0000,0x0000,0x0000,0x0006,0x0006,0x000c,0x01fc,0x07fc,0x0e18,0x1830,0x1830,0x3060,0x3060,0x30c0,0x30c0,0x3ffc,\n  0x3ffc,0x3180,0x3180,0x3300,0x3300,0x1600,0x1e00,0x0e00,0x0ffc,0x19fc,0x1800,0x3000,0x3000,0x0000,0x0000,0x0000, // u2209\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03fc,0x0ffc,0x1c00,0x1800,0x3000,0x3000,0x3ffc,\n  0x3ffc,0x3000,0x3000,0x1800,0x1c00,0x0ffc,0x03fc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u220a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x3fe0,0x0070,0x0018,0x0018,0x000c,0x000c,0x000c,0x000c,0x3ffc,\n  0x3ffc,0x000c,0x000c,0x000c,0x000c,0x0018,0x0018,0x0070,0x3fe0,0x3f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u220b\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x3000,0x3f80,0x3fe0,0x1870,0x0c18,0x0c18,0x060c,0x060c,0x030c,0x030c,0x3ffc,\n  0x3ffc,0x018c,0x018c,0x00cc,0x00cc,0x0068,0x0078,0x0070,0x3ff0,0x3f98,0x0018,0x000c,0x000c,0x0000,0x0000,0x0000, // u220c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x3ff0,0x0038,0x0018,0x000c,0x000c,0x3ffc,\n  0x3ffc,0x000c,0x000c,0x0018,0x0038,0x3ff0,0x3fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u220d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,\n  0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2212\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x0000,0x0000,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x3ffc,0x3ffc,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2213\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x3ffc,0x3ffc,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2214\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000c,0x001c,0x0038,0x0070,0x00e0,0x01c0,\n  0x0380,0x0700,0x0e00,0x1c00,0x3800,0x7000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2215\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x7000,0x3800,0x1c00,0x0e00,0x0700,\n  0x0380,0x01c0,0x00e0,0x0070,0x0038,0x001c,0x000c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2216\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x07c0,0x07c0,\n  0x07c0,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2219\n  0x0000,0x0000,0x0000,0x001e,0x001e,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x3018,\n  0x3018,0x3018,0x3818,0x1c18,0x0e18,0x0718,0x0398,0x01d8,0x00f8,0x0078,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u221a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e78,0x3ffc,0x73ce,0x6186,0x6186,\n  0x6186,0x6186,0x73ce,0x3ffc,0x1e78,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u221e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u221f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,\n  0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2225\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x03c0,0x03c0,\n  0x0660,0x0660,0x0c30,0x0c30,0x0c30,0x1818,0x1818,0x1818,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2227\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x1818,0x1818,\n  0x1818,0x0c30,0x0c30,0x0c30,0x0660,0x0660,0x03c0,0x03c0,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2228\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07e0,0x0ff0,0x1c38,0x1818,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2229\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x1818,0x1c38,0x0ff0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u222a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f0c,0x3f9c,0x39fc,0x30f8,0x0000,\n  0x0000,0x1f0c,0x3f9c,0x39fc,0x30f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2248\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x001c,0x0038,0x7ffc,0x7ffc,0x00e0,0x01c0,\n  0x0380,0x0700,0x7ffc,0x7ffc,0x3800,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2260\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x3ffc,\n  0x3ffc,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2261\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x1c00,0x0e00,\n  0x0700,0x0380,0x01c0,0x00e0,0x0070,0x0038,0x0000,0x0000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2264\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0e00,0x0700,0x0380,0x01c0,0x00e0,0x0070,0x0038,0x0038,0x0070,\n  0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x0000,0x0000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2265\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c3,0x01c7,0x038e,0x071c,0x0e38,0x1c70,0x38e0,0x71c0,0xe380,\n  0xe380,0x71c0,0x38e0,0x1c70,0x0e38,0x071c,0x038e,0x01c7,0x00c3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u226a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc300,0xe380,0x71c0,0x38e0,0x1c70,0x0e38,0x071c,0x038e,0x01c7,\n  0x01c7,0x038e,0x071c,0x0e38,0x1c70,0x38e0,0x71c0,0xe380,0xc300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u226b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07fc,0x1ffc,0x3800,0x7000,0x6000,0x6000,0x6000,\n  0x6000,0x6000,0x6000,0x7000,0x3800,0x1ffc,0x07fc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2282\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7ff0,0x0038,0x001c,0x000c,0x000c,0x000c,\n  0x000c,0x000c,0x000c,0x001c,0x0038,0x7ff0,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2283\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07fc,0x1ffc,0x3800,0x7000,0x6000,0x6000,0x6000,0x6000,0x6000,\n  0x6000,0x7000,0x3800,0x1ffc,0x07fc,0x0000,0x0000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2286\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7ff0,0x0038,0x001c,0x000c,0x000c,0x000c,0x000c,0x000c,\n  0x000c,0x001c,0x0038,0x7ff0,0x7fc0,0x0000,0x0000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2287\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u22a5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07e0,0x0ff0,0x1c38,0x1818,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u22c2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x1818,0x1c38,0x0ff0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u22c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0030,0x0030,0x0fe0,0x1ff0,0x30d8,0x30d8,0x3198,0x3198,\n  0x3318,0x3318,0x3618,0x3618,0x1ff0,0x0fe0,0x1800,0x1800,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2300\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x1c38,0x381c,\n  0x700e,0x6006,0x6006,0x6006,0x6006,0x6006,0x6006,0x6006,0x7ffe,0x7ffe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2302\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x0fe0,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2308\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x0fe0,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2309\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,\n  0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u230a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,\n  0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u230b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x3000,0x3000,\n  0x3000,0x3000,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2310\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3000,0x3000,0x3000,0x3000,\n  0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2319\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00f8,0x01fc,0x018c,0x018c,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u2320\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x3180,0x3180,0x3f80,0x1f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2321\n  0x0018,0x0030,0x0060,0x00c0,0x0180,0x0180,0x0300,0x0300,0x0600,0x0600,0x0600,0x0c00,0x0c00,0x0c00,0x0c00,0x1800,\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u239b\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u239c\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,\n  0x1800,0x0c00,0x0c00,0x0c00,0x0c00,0x0600,0x0600,0x0600,0x0300,0x0300,0x0180,0x0180,0x00c0,0x0060,0x0030,0x0018, // u239d\n  0x1800,0x0c00,0x0600,0x0300,0x0180,0x0180,0x00c0,0x00c0,0x0060,0x0060,0x0060,0x0030,0x0030,0x0030,0x0030,0x0018,\n  0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018, // u239e\n  0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,\n  0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018, // u239f\n  0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,\n  0x0018,0x0030,0x0030,0x0030,0x0030,0x0060,0x0060,0x0060,0x00c0,0x00c0,0x0180,0x0180,0x0300,0x0600,0x0c00,0x1800, // u23a0\n  0x1ff8,0x1ff8,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u23a1\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800, // u23a2\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1ff8,0x1ff8, // u23a3\n  0x1ff8,0x1ff8,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,\n  0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018, // u23a4\n  0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,\n  0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018, // u23a5\n  0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,\n  0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x1ff8,0x1ff8, // u23a6\n  0x007e,0x01fe,0x0380,0x0300,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u23a7\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0e00,0x1c00,0xf800,\n  0xf800,0x1c00,0x0e00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600, // u23a8\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,\n  0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0600,0x0300,0x0380,0x01fe,0x007e, // u23a9\n  0xfc00,0xff00,0x0380,0x0180,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0, // u23ab\n  0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x0060,0x003e,\n  0x003e,0x0060,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0, // u23ac\n  0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,\n  0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x00c0,0x0180,0x0380,0xff00,0xfc00, // u23ad\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u23ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,\n  0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23af\n  0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff, // u23bd\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u23d0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x7f80,0x7f80,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x03fc,0x03fc,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2409\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x7f80,0x0000,\n  0x0000,0x03fc,0x03fc,0x0300,0x0300,0x03f0,0x03f0,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u240a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0c00,0x0000,\n  0x0000,0x03fc,0x03fc,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u240b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x7f80,0x6000,0x6000,0x7e00,0x7e00,0x6000,0x6000,0x6000,0x0000,\n  0x0000,0x03fc,0x03fc,0x0300,0x0300,0x03f0,0x03f0,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u240c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x7f80,0x6180,0x6000,0x6000,0x6000,0x6180,0x7f80,0x3f00,0x0000,\n  0x0000,0x03f8,0x03fc,0x030c,0x030c,0x03f8,0x03e0,0x0370,0x0338,0x031c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u240d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x7180,0x7980,0x6d80,0x6780,0x6380,0x6180,0x6180,0x0000,\n  0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x03fc,0x03fc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2424\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,\n  0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2500\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,\n  0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2501\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u2502\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u2503\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf7de,\n  0xf7de,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2508\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf7de,0xf7de,\n  0xf7de,0xf7de,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2509\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000, // u250a\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x0000,0x0000,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x0000,0x0000,\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x0000,0x0000,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x0000,0x0000, // u250b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01ff,\n  0x01ff,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u250c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01ff,0x01ff,\n  0x01ff,0x01ff,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u250d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03ff,\n  0x03ff,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u250e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03ff,0x03ff,\n  0x03ff,0x03ff,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u250f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,\n  0xff80,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u2510\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,0xff80,\n  0xff80,0xff80,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u2511\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,\n  0xffc0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u2512\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,\n  0xffc0,0xffc0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u2513\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x01ff,\n  0x01ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2514\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x01ff,0x01ff,\n  0x01ff,0x01ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2515\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03ff,\n  0x03ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2516\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03ff,0x03ff,\n  0x03ff,0x03ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2517\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0xff80,\n  0xff80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2518\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0xff80,0xff80,\n  0xff80,0xff80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2519\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0xffc0,\n  0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u251a\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u251b\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x01ff,\n  0x01ff,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u251c\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x01ff,0x01ff,\n  0x01ff,0x01ff,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u251d\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03ff,\n  0x03ff,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u251e\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x03ff,\n  0x03ff,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u251f\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03ff,\n  0x03ff,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u2520\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03ff,0x03ff,\n  0x03ff,0x03ff,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u2521\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x03ff,0x03ff,\n  0x03ff,0x03ff,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u2522\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03ff,0x03ff,\n  0x03ff,0x03ff,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u2523\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0xff80,\n  0xff80,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u2524\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0xff80,0xff80,\n  0xff80,0xff80,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u2525\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0xffc0,\n  0xffc0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u2526\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0xffc0,\n  0xffc0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u2527\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0xffc0,\n  0xffc0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u2528\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u2529\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0xffc0,0xffc0,\n  0xffc0,0xffc0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u252a\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u252b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,\n  0xffff,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u252c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,0xffff,\n  0xffff,0xff80,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u252d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01ff,0xffff,\n  0xffff,0x01ff,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u252e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,\n  0xffff,0xffff,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u252f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,\n  0xffff,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u2530\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffff,\n  0xffff,0xffc0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u2531\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03ff,0xffff,\n  0xffff,0x03ff,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u2532\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,\n  0xffff,0xffff,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u2533\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0xffff,\n  0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2534\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0xff80,0xffff,\n  0xffff,0xff80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2535\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x01ff,0xffff,\n  0xffff,0x01ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2536\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0xffff,0xffff,\n  0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2537\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0xffff,\n  0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2538\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0xffc0,0xffff,\n  0xffff,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2539\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03ff,0xffff,\n  0xffff,0x03ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u253a\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0xffff,0xffff,\n  0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u253b\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0xffff,\n  0xffff,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u253c\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0xff80,0xffff,\n  0xffff,0xff80,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u253d\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x01ff,0xffff,\n  0xffff,0x01ff,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u253e\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0xffff,0xffff,\n  0xffff,0xffff,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u253f\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0xffff,\n  0xffff,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u2540\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0xffff,\n  0xffff,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u2541\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0xffff,\n  0xffff,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u2542\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0xffc0,0xffff,\n  0xffff,0xff80,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u2543\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03ff,0xffff,\n  0xffff,0x01ff,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u2544\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0xff80,0xffff,\n  0xffff,0xffc0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u2545\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x01ff,0xffff,\n  0xffff,0x03ff,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u2546\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0xffff,0xffff,\n  0xffff,0xffff,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u2547\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0xffff,0xffff,\n  0xffff,0xffff,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u2548\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0xffc0,0xffff,\n  0xffff,0xffc0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u2549\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03ff,0xffff,\n  0xffff,0x03ff,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u254a\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0xffff,0xffff,\n  0xffff,0xffff,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u254b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0x0000,\n  0x0000,0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2550\n  0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,\n  0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660, // u2551\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01ff,0x01ff,0x0180,\n  0x0180,0x01ff,0x01ff,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u2552\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07ff,\n  0x07ff,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660, // u2553\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07ff,0x07ff,0x0600,\n  0x0600,0x067f,0x067f,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660, // u2554\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,0xff80,0x0180,\n  0x0180,0xff80,0xff80,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u2555\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,\n  0xffe0,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660, // u2556\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xffe0,0x0060,\n  0x0060,0xfe60,0xfe60,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660, // u2557\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x01ff,0x01ff,0x0180,\n  0x0180,0x01ff,0x01ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2558\n  0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x07ff,\n  0x07ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2559\n  0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x067f,0x067f,0x0600,\n  0x0600,0x07ff,0x07ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255a\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0xff80,0xff80,0x0180,\n  0x0180,0xff80,0xff80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255b\n  0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0xffe0,\n  0xffe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255c\n  0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0xfe60,0xfe60,0x0060,\n  0x0060,0xffe0,0xffe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255d\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x01ff,0x01ff,0x0180,\n  0x0180,0x01ff,0x01ff,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u255e\n  0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x067f,\n  0x067f,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660, // u255f\n  0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x067f,0x067f,0x0600,\n  0x0600,0x067f,0x067f,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660, // u2560\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0xff80,0xff80,0x0180,\n  0x0180,0xff80,0xff80,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u2561\n  0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0xfe60,\n  0xfe60,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660, // u2562\n  0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0xfe60,0xfe60,0x0060,\n  0x0060,0xfe60,0xfe60,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660, // u2563\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0x0000,\n  0x0000,0xffff,0xffff,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u2564\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,\n  0xffff,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660, // u2565\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0x0000,\n  0x0000,0xfe7f,0xfe7f,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660, // u2566\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0xffff,0xffff,0x0000,\n  0x0000,0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2567\n  0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0xffff,\n  0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2568\n  0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0xfe7f,0xfe7f,0x0000,\n  0x0000,0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2569\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0xffff,0xffff,0x0180,\n  0x0180,0xffff,0xffff,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u256a\n  0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0xffff,\n  0xffff,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660, // u256b\n  0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0xfe7f,0xfe7f,0x0000,\n  0x0000,0xfe7f,0xfe7f,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660,0x0660, // u256c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000f,\n  0x003f,0x0078,0x00e0,0x00c0,0x01c0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u256d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf000,\n  0xfc00,0x1e00,0x0700,0x0300,0x0380,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u256e\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0380,0x0300,0x0700,0x1e00,0xfc00,\n  0xf000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u256f\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x01c0,0x00c0,0x00e0,0x0078,0x003f,\n  0x000f,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2570\n  0x0001,0x0003,0x0003,0x0006,0x0006,0x000c,0x000c,0x0018,0x0018,0x0030,0x0030,0x0060,0x0060,0x00c0,0x00c0,0x0180,\n  0x0180,0x0300,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x6000,0x6000,0xc000,0xc000,0x8000, // u2571\n  0x8000,0xc000,0xc000,0x6000,0x6000,0x3000,0x3000,0x1800,0x1800,0x0c00,0x0c00,0x0600,0x0600,0x0300,0x0300,0x0180,\n  0x0180,0x00c0,0x00c0,0x0060,0x0060,0x0030,0x0030,0x0018,0x0018,0x000c,0x000c,0x0006,0x0006,0x0003,0x0003,0x0001, // u2572\n  0x8001,0xc003,0xc003,0x6006,0x6006,0x300c,0x300c,0x1818,0x1818,0x0c30,0x0c30,0x0660,0x0660,0x03c0,0x03c0,0x0180,\n  0x0180,0x03c0,0x03c0,0x0660,0x0660,0x0c30,0x0c30,0x1818,0x1818,0x300c,0x300c,0x6006,0x6006,0xc003,0xc003,0x8001, // u2573\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,\n  0xff80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2574\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,\n  0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2575\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01ff,\n  0x01ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2576\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u2577\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,0xff80,\n  0xff80,0xff80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2578\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,\n  0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2579\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01ff,0x01ff,\n  0x01ff,0x01ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03c0,\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u257b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01ff,0xffff,\n  0xffff,0x01ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257c\n  0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x03c0,\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0, // u257d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,0xffff,\n  0xffff,0xff80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257e\n  0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,0x03c0,\n  0x03c0,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180, // u257f\n  0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2580\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff, // u2581\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff, // u2582\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff, // u2583\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff, // u2584\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,\n  0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff, // u2585\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,\n  0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff, // u2586\n  0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,\n  0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff, // u2587\n  0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,\n  0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff, // u2588\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc, // u2589\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0, // u258a\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0, // u258b\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u258c\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00, // u258d\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000, // u258e\n  0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,\n  0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000, // u258f\n  0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,\n  0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff, // u2590\n  0xaaaa,0x0000,0xaaaa,0x0000,0xaaaa,0x0000,0xaaaa,0x0000,0xaaaa,0x0000,0xaaaa,0x0000,0xaaaa,0x0000,0xaaaa,0x0000,\n  0xaaaa,0x0000,0xaaaa,0x0000,0xaaaa,0x0000,0xaaaa,0x0000,0xaaaa,0x0000,0xaaaa,0x0000,0xaaaa,0x0000,0xaaaa,0x0000, // u2591\n  0xaaaa,0x5555,0xaaaa,0x5555,0xaaaa,0x5555,0xaaaa,0x5555,0xaaaa,0x5555,0xaaaa,0x5555,0xaaaa,0x5555,0xaaaa,0x5555,\n  0xaaaa,0x5555,0xaaaa,0x5555,0xaaaa,0x5555,0xaaaa,0x5555,0xaaaa,0x5555,0xaaaa,0x5555,0xaaaa,0x5555,0xaaaa,0x5555, // u2592\n  0xffff,0xaaaa,0xffff,0xaaaa,0xffff,0xaaaa,0xffff,0xaaaa,0xffff,0xaaaa,0xffff,0xaaaa,0xffff,0xaaaa,0xffff,0xaaaa,\n  0xffff,0xaaaa,0xffff,0xaaaa,0xffff,0xaaaa,0xffff,0xaaaa,0xffff,0xaaaa,0xffff,0xaaaa,0xffff,0xaaaa,0xffff,0xaaaa, // u2593\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2596\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff, // u2597\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2598\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,\n  0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff, // u2599\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,\n  0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff, // u259a\n  0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u259b\n  0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,\n  0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff, // u259c\n  0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u259d\n  0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u259e\n  0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,\n  0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff, // u259f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x1ff0,0x1ff0,0x1ff0,0x1ff0,0x1ff0,\n  0x1ff0,0x1ff0,0x1ff0,0x1ff0,0x1ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x7ffc,0x7ffc,0x7ffc,0x7ffc,0x7ffc,0x7ffc,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ac\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x3ffc,0x3ffc,0x3ffc,0x3ffc,0x3ffc,0x3ffc,0x3ffc,0x3ffc,\n  0x3ffc,0x3ffc,0x3ffc,0x3ffc,0x3ffc,0x3ffc,0x3ffc,0x3ffc,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0100,0x0100,0x0380,0x0380,0x07c0,0x07c0,0x0fe0,0x0fe0,\n  0x1ff0,0x1ff0,0x3ff8,0x3ff8,0x7ffc,0x7ffc,0xfffe,0xfffe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xffc0,0xfff0,0xfffc,0xffff,\n  0xfffc,0xfff0,0xffc0,0xff00,0xfc00,0xf000,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xffc0,0xfff0,0xfffc,0xffff,\n  0xfffc,0xfff0,0xffc0,0xff00,0xfc00,0xf000,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffe,0xfffe,0x7ffc,0x7ffc,0x3ff8,0x3ff8,0x1ff0,0x1ff0,\n  0x0fe0,0x0fe0,0x07c0,0x07c0,0x0380,0x0380,0x0100,0x0100,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0003,0x000f,0x003f,0x00ff,0x03ff,0x0fff,0x3fff,0xffff,\n  0x3fff,0x0fff,0x03ff,0x00ff,0x003f,0x000f,0x0003,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0003,0x000f,0x003f,0x00ff,0x03ff,0x0fff,0x3fff,0xffff,\n  0x3fff,0x0fff,0x03ff,0x00ff,0x003f,0x000f,0x0003,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x03c0,0x07e0,0x0ff0,0x1ff8,0x3ffc,0x7ffe,\n  0x7ffe,0x3ffc,0x1ff8,0x0ff0,0x07e0,0x03c0,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x03c0,0x07e0,0x0e70,0x1c38,0x381c,0x700e,\n  0x700e,0x381c,0x1c38,0x0e70,0x07e0,0x03c0,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ca\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03c0,0x07e0,0x0660,\n  0x0660,0x07e0,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03c0,0x07e0,0x07e0,\n  0x07e0,0x07e0,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25cf\n  0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xfc3f,0xf81f,0xf81f,\n  0xf81f,0xf81f,0xfc3f,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff, // u25d8\n  0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xfc3f,0xf81f,0xf99f,\n  0xf99f,0xf81f,0xfc3f,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff, // u25d9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff8,0x3ffc,0x700e,0x6006,0x6006,0x6006,0x6e76,0x6e76,0x6006,0x6006,\n  0x6006,0x6006,0x6ff6,0x67e6,0x6006,0x6006,0x6006,0x700e,0x3ffc,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u263a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff8,0x3ffc,0x7ffe,0x7ffe,0x7ffe,0x7ffe,0x718e,0x718e,0x7ffe,0x7ffe,\n  0x7ffe,0x7ffe,0x700e,0x781e,0x7c3e,0x7ffe,0x7ffe,0x7ffe,0x3ffc,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u263b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0180,0x318c,0x399c,0x1db8,0x0ff0,0x07e0,0x3e7c,\n  0x3e7c,0x07e0,0x0ff0,0x1db8,0x399c,0x318c,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u263c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x381c,0x300c,0x300c,0x300c,0x300c,0x300c,0x381c,0x1ff8,\n  0x0ff0,0x0180,0x0180,0x0180,0x3ffc,0x3ffc,0x0180,0x0180,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2640\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01fe,0x01fe,0x001e,0x003e,0x0076,0x00e6,0x01c6,0x0386,0x1fe0,0x3ff0,\n  0x7038,0x6018,0x6018,0x6018,0x6018,0x6018,0x6018,0x7038,0x3ff0,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2642\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x03c0,0x07e0,0x0ff0,0x1ff8,0x3ffc,0x3ffc,0x7ffe,0x7ffe,\n  0x7ffe,0x7ffe,0x7ffe,0x3dbc,0x1db8,0x0180,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2660\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03c0,0x07e0,0x07e0,0x07e0,0x07e0,0x07e0,0x03c0,0x0180,0x1db8,0x3ffc,\n  0x7ffe,0x7ffe,0x7ffe,0x7ffe,0x3ffc,0x1db8,0x0180,0x0180,0x07e0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2663\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3c3c,0x7e7e,0x7e7e,0x7ffe,0x7ffe,0x7ffe,0x7ffe,0x7ffe,\n  0x3ffc,0x3ffc,0x1ff8,0x0ff0,0x07e0,0x03c0,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2665\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x03c0,0x07e0,0x0ff0,0x1ff8,0x3ffc,0x7ffe,\n  0x7ffe,0x3ffc,0x1ff8,0x0ff0,0x07e0,0x03c0,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2666\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ffc,0x1ffc,0x180c,0x180c,0x180c,0x180c,0x1ffc,0x1ffc,0x1800,0x1800,\n  0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x1800,0x7800,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u266a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffe,0x3ffe,0x3006,0x3006,0x3006,0x3006,0x3ffe,0x3ffe,0x3006,0x3006,\n  0x3006,0x3006,0x3006,0x3006,0x3006,0x3006,0x3006,0x301e,0xf01c,0xe000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u266b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0003,0x0003,0x0006,0x0006,0x000c,0x000c,0x0018,0x0018,0xc030,0xc030,\n  0x6060,0x6060,0x30c0,0x30c0,0x1980,0x1980,0x0f00,0x0f00,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2713\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0007,0x0007,0x000e,0x000e,0x001c,0x001c,0x0038,0x0038,0xc070,0xc070,\n  0xe0e0,0xe0e0,0x71c0,0x71c0,0x3b80,0x3b80,0x1f00,0x1f00,0x0e00,0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2714\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0030,0x3030,0x1860,0x0c60,0x06c0,0x03c0,0x0180,0x01c0,\n  0x0360,0x0330,0x0618,0x060c,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2717\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x7070,0x3870,0x1ce0,0x0ee0,0x07c0,0x03c0,0x03c0,0x03e0,\n  0x0770,0x0738,0x0e1c,0x0e0c,0x1c00,0x1c00,0x3800,0x3800,0x7000,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2718\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0060,0x0060,0x00c0,0x00c0,0x0180,0x0180,0x0300,0x0300,0x0600,0x0600,\n  0x0600,0x0600,0x0300,0x0300,0x0180,0x0180,0x00c0,0x00c0,0x0060,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u27e8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0600,0x0300,0x0300,0x0180,0x0180,0x00c0,0x00c0,0x0060,0x0060,\n  0x0060,0x0060,0x00c0,0x00c0,0x0180,0x0180,0x0300,0x0300,0x0600,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u27e9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x030c,0x030c,0x0618,0x0618,0x0c30,0x0c30,0x1860,0x1860,0x30c0,0x30c0,\n  0x30c0,0x30c0,0x1860,0x1860,0x0c30,0x0c30,0x0618,0x0618,0x030c,0x030c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u27ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x30c0,0x30c0,0x1860,0x1860,0x0c30,0x0c30,0x0618,0x0618,0x030c,0x030c,\n  0x030c,0x030c,0x0618,0x0618,0x0c30,0x0c30,0x1860,0x1860,0x30c0,0x30c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u27eb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2800\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2801\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2802\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2803\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2804\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2805\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2806\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2807\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2808\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2809\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280a\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280b\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280c\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280d\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280e\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2810\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2811\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2812\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2813\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2814\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2815\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2816\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2817\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2818\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2819\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281a\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281b\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281c\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281d\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281e\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2820\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2821\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2822\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2823\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2824\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2825\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2826\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2827\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2828\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2829\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282a\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282b\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282c\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282d\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282e\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2830\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2831\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2832\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2833\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2834\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2835\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2836\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2837\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2838\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2839\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283a\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283b\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283c\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283d\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283e\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2840\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2841\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2842\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2843\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2844\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2845\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2846\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2847\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2848\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2849\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u284a\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u284b\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u284c\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u284d\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u284e\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u284f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2850\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2851\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2852\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2853\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2854\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2855\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2856\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2857\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2858\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2859\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u285a\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u285b\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u285c\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u285d\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u285e\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u285f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2860\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2861\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2862\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2863\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2864\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2865\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2866\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2867\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2868\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2869\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u286a\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u286b\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u286c\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u286d\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u286e\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u286f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2870\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2871\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2872\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2873\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2874\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2875\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2876\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2877\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2878\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u2879\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u287a\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u287b\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u287c\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u287d\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u287e\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000, // u287f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u2880\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u2881\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u2882\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u2883\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u2884\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u2885\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u2886\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u2887\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u2888\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u2889\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u288a\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u288b\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u288c\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u288d\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u288e\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u288f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u2890\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u2891\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u2892\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u2893\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u2894\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u2895\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u2896\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u2897\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u2898\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u2899\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u289a\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u289b\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u289c\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u289d\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u289e\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u289f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28a0\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28a2\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28a4\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28a5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28a6\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28a7\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28a8\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28a9\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28aa\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28ab\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28ac\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28ad\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28ae\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28af\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28b0\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28b1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28b2\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28b4\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28b6\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28b7\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28b8\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28b9\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28ba\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28bb\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28bc\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28bd\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28be\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000, // u28bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28c0\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28c2\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28c4\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28c6\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28c7\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28c8\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28c9\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28ca\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28cb\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28cc\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28cd\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28ce\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28cf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28d0\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28d2\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28d4\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28d6\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28d7\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28d8\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28d9\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28da\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28db\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28dc\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28dd\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28de\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28df\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28e0\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28e1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28e2\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28e3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28e4\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28e6\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28e7\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28e8\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28e9\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28ea\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28eb\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28ec\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28ed\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28ee\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28ef\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28f0\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28f2\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28f3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28f4\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28f6\n  0x0000,0x0000,0x1800,0x1800,0x1800,0x1800,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28f7\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28f8\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28f9\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28fa\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28fb\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28fc\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28fd\n  0x0000,0x0000,0x0018,0x0018,0x0018,0x0018,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28fe\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,\n  0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000,0x0000,0x0000,0x1818,0x1818,0x1818,0x1818,0x0000,0x0000, // u28ff\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2e2c\n  0x6000,0x6000,0x6000,0x6060,0x60f0,0x61f8,0x63fc,0x676e,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x6060,0x60c0,\n  0x4180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000, // ue0a0\n  0x0000,0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7fc0,0x7fc0,0x0000,0x0000,\n  0x060c,0x060c,0x070c,0x078c,0x06cc,0x066c,0x063c,0x061c,0x060c,0x060c,0x060c,0x0000,0x0000,0x0000,0x0000,0x0000, // ue0a1\n  0x0000,0x0000,0x0000,0x0000,0x07e0,0x0ff0,0x1818,0x1818,0x1818,0x1818,0x1818,0x1818,0x1818,0x1818,0x3ffc,0x7ffe,\n  0x7ffe,0x7ffe,0x7c3e,0x781e,0x781e,0x781e,0x7c3e,0x7ffe,0x7ffe,0x7ffe,0x7ffe,0x7ffe,0x0000,0x0000,0x0000,0x0000, // ue0a2\n  0x8000,0xc000,0xe000,0xf000,0xf800,0xfc00,0xfe00,0xff00,0xff80,0xffc0,0xffe0,0xfff0,0xfff8,0xfffc,0xfffe,0xffff,\n  0xffff,0xfffe,0xfffc,0xfff8,0xfff0,0xffe0,0xffc0,0xff80,0xff00,0xfe00,0xfc00,0xf800,0xf000,0xe000,0xc000,0x8000, // ue0b0\n  0x8000,0xc000,0xe000,0x7000,0x3800,0x1c00,0x0e00,0x0700,0x0380,0x01c0,0x00e0,0x0070,0x0038,0x001c,0x000e,0x0007,\n  0x0007,0x000e,0x001c,0x0038,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,0x7000,0xe000,0xc000,0x8000, // ue0b1\n  0x0001,0x0003,0x0007,0x000f,0x001f,0x003f,0x007f,0x00ff,0x01ff,0x03ff,0x07ff,0x0fff,0x1fff,0x3fff,0x7fff,0xffff,\n  0xffff,0x7fff,0x3fff,0x1fff,0x0fff,0x07ff,0x03ff,0x01ff,0x00ff,0x007f,0x003f,0x001f,0x000f,0x0007,0x0003,0x0001, // ue0b2\n  0x0001,0x0003,0x0007,0x000e,0x001c,0x0038,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,0x7000,0xe000,\n  0xe000,0x7000,0x3800,0x1c00,0x0e00,0x0700,0x0380,0x01c0,0x00e0,0x0070,0x0038,0x001c,0x000e,0x0007,0x0003,0x0001, // ue0b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0078,0x0078,0x0018,0x0018,\n  0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x0018,0x1818,0x1818,0x1c38,0x0ff0,0x07e0,0x0000, // uf6be\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,\n  0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x300c,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 // ufffd\n  };\n  // codepoints array\n  constexpr std::array<uint16_t, CHARCOUNT> fixedfont_codepoints = {\n  0x0000,0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,\n  0x002f,0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,\n  0x003f,0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,\n  0x004f,0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,\n  0x005f,0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,\n  0x006f,0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,\n  0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af,\n  0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf,\n  0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf,\n  0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df,\n  0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef,\n  0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff,\n  0x0100,0x0101,0x0102,0x0103,0x0104,0x0105,0x0106,0x0107,0x0108,0x0109,0x010a,0x010b,0x010c,0x010d,0x010e,0x010f,\n  0x0110,0x0111,0x0112,0x0113,0x0114,0x0115,0x0116,0x0117,0x0118,0x0119,0x011a,0x011b,0x011c,0x011d,0x011e,0x011f,\n  0x0120,0x0121,0x0122,0x0123,0x0124,0x0125,0x0126,0x0127,0x0128,0x0129,0x012a,0x012b,0x012c,0x012d,0x012e,0x012f,\n  0x0130,0x0131,0x0132,0x0133,0x0134,0x0135,0x0136,0x0137,0x0138,0x0139,0x013a,0x013b,0x013c,0x013d,0x013e,0x013f,\n  0x0140,0x0141,0x0142,0x0143,0x0144,0x0145,0x0146,0x0147,0x0148,0x0149,0x014a,0x014b,0x014c,0x014d,0x014e,0x014f,\n  0x0150,0x0151,0x0152,0x0153,0x0154,0x0155,0x0156,0x0157,0x0158,0x0159,0x015a,0x015b,0x015c,0x015d,0x015e,0x015f,\n  0x0160,0x0161,0x0162,0x0163,0x0164,0x0165,0x0166,0x0167,0x0168,0x0169,0x016a,0x016b,0x016c,0x016d,0x016e,0x016f,\n  0x0170,0x0171,0x0172,0x0173,0x0174,0x0175,0x0176,0x0177,0x0178,0x0179,0x017a,0x017b,0x017c,0x017d,0x017e,0x017f,\n  0x0186,0x018e,0x018f,0x0190,0x0192,0x019d,0x019e,0x01b5,0x01b6,0x01b7,0x01cd,0x01ce,0x01cf,0x01d0,0x01d1,0x01d2,\n  0x01d3,0x01d4,0x01e2,0x01e3,0x01e4,0x01e5,0x01e6,0x01e7,0x01e8,0x01e9,0x01ea,0x01eb,0x01ec,0x01ed,0x01ee,0x01ef,\n  0x01f0,0x01f4,0x01f5,0x01fc,0x01fd,0x01fe,0x01ff,0x0218,0x0219,0x021a,0x021b,0x0232,0x0233,0x0237,0x0254,0x0258,\n  0x0259,0x025b,0x0272,0x0292,0x02bb,0x02bc,0x02bd,0x02c6,0x02c7,0x02d8,0x02d9,0x02db,0x02dc,0x02dd,0x0300,0x0301,\n  0x0302,0x0303,0x0304,0x0305,0x0306,0x0307,0x0308,0x030a,0x030b,0x030c,0x0329,0x0384,0x0385,0x0386,0x0387,0x0388,\n  0x0389,0x038a,0x038c,0x038e,0x038f,0x0390,0x0391,0x0392,0x0393,0x0394,0x0395,0x0396,0x0397,0x0398,0x0399,0x039a,\n  0x039b,0x039c,0x039d,0x039e,0x039f,0x03a0,0x03a1,0x03a3,0x03a4,0x03a5,0x03a6,0x03a7,0x03a8,0x03a9,0x03aa,0x03ab,\n  0x03ac,0x03ad,0x03ae,0x03af,0x03b0,0x03b1,0x03b2,0x03b3,0x03b4,0x03b5,0x03b6,0x03b7,0x03b8,0x03b9,0x03ba,0x03bb,\n  0x03bc,0x03bd,0x03be,0x03bf,0x03c0,0x03c1,0x03c2,0x03c3,0x03c4,0x03c5,0x03c6,0x03c7,0x03c8,0x03c9,0x03ca,0x03cb,\n  0x03cc,0x03cd,0x03ce,0x03d1,0x03d5,0x03f0,0x03f1,0x03f2,0x03f3,0x03f4,0x03f5,0x03f6,0x0400,0x0401,0x0402,0x0403,\n  0x0404,0x0405,0x0406,0x0407,0x0408,0x0409,0x040a,0x040b,0x040c,0x040d,0x040e,0x040f,0x0410,0x0411,0x0412,0x0413,\n  0x0414,0x0415,0x0416,0x0417,0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e,0x041f,0x0420,0x0421,0x0422,0x0423,\n  0x0424,0x0425,0x0426,0x0427,0x0428,0x0429,0x042a,0x042b,0x042c,0x042d,0x042e,0x042f,0x0430,0x0431,0x0432,0x0433,\n  0x0434,0x0435,0x0436,0x0437,0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e,0x043f,0x0440,0x0441,0x0442,0x0443,\n  0x0444,0x0445,0x0446,0x0447,0x0448,0x0449,0x044a,0x044b,0x044c,0x044d,0x044e,0x044f,0x0450,0x0451,0x0452,0x0453,\n  0x0454,0x0455,0x0456,0x0457,0x0458,0x0459,0x045a,0x045b,0x045c,0x045d,0x045e,0x045f,0x0462,0x0463,0x046a,0x046b,\n  0x0490,0x0491,0x0492,0x0493,0x0494,0x0495,0x0496,0x0497,0x0498,0x0499,0x049a,0x049b,0x049c,0x049d,0x04a0,0x04a1,\n  0x04a2,0x04a3,0x04a4,0x04a5,0x04aa,0x04ab,0x04ae,0x04af,0x04b0,0x04b1,0x04b2,0x04b3,0x04b6,0x04b7,0x04b8,0x04b9,\n  0x04ba,0x04bb,0x04c0,0x04c1,0x04c2,0x04cf,0x04d0,0x04d1,0x04d2,0x04d3,0x04d4,0x04d5,0x04d6,0x04d7,0x04d8,0x04d9,\n  0x04da,0x04db,0x04dc,0x04dd,0x04de,0x04df,0x04e2,0x04e3,0x04e4,0x04e5,0x04e6,0x04e7,0x04e8,0x04e9,0x04ea,0x04eb,\n  0x04ec,0x04ed,0x04ee,0x04ef,0x04f0,0x04f1,0x04f2,0x04f3,0x04f4,0x04f5,0x04f8,0x04f9,0x05d0,0x05d1,0x05d2,0x05d3,\n  0x05d4,0x05d5,0x05d6,0x05d7,0x05d8,0x05d9,0x05da,0x05db,0x05dc,0x05dd,0x05de,0x05df,0x05e0,0x05e1,0x05e2,0x05e3,\n  0x05e4,0x05e5,0x05e6,0x05e7,0x05e8,0x05e9,0x05ea,0x1e0c,0x1e0d,0x1e34,0x1e35,0x1e36,0x1e37,0x1e40,0x1e41,0x1e42,\n  0x1e43,0x1e44,0x1e45,0x1e46,0x1e47,0x1e6c,0x1e6d,0x1eb8,0x1eb9,0x1ebc,0x1ebd,0x1eca,0x1ecb,0x1ecc,0x1ecd,0x1ee4,\n  0x1ee5,0x1ef8,0x1ef9,0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007,0x2008,0x2009,0x200a,0x200b,0x200c,\n  0x200d,0x200e,0x200f,0x2010,0x2011,0x2012,0x2013,0x2014,0x2015,0x2016,0x2017,0x2018,0x2019,0x201a,0x201b,0x201c,\n  0x201d,0x201e,0x201f,0x2020,0x2021,0x2022,0x2026,0x2030,0x2032,0x2033,0x2039,0x203a,0x203c,0x203e,0x2070,0x2071,\n  0x2074,0x2075,0x2076,0x2077,0x2078,0x2079,0x207a,0x207b,0x207c,0x207d,0x207e,0x207f,0x2080,0x2081,0x2082,0x2083,\n  0x2084,0x2085,0x2086,0x2087,0x2088,0x2089,0x208a,0x208b,0x208c,0x208d,0x208e,0x2090,0x2091,0x2092,0x2093,0x2094,\n  0x2095,0x2096,0x2097,0x2098,0x209a,0x20a7,0x20aa,0x20ac,0x20ae,0x2102,0x210e,0x210f,0x2115,0x2116,0x211a,0x211d,\n  0x2122,0x2124,0x2126,0x2135,0x2190,0x2191,0x2192,0x2193,0x2194,0x2195,0x21a4,0x21a6,0x21a8,0x21b5,0x21bb,0x21cb,\n  0x21cc,0x21d0,0x21d1,0x21d2,0x21d3,0x21d4,0x21d5,0x2200,0x2203,0x2204,0x2205,0x2206,0x2207,0x2208,0x2209,0x220a,\n  0x220b,0x220c,0x220d,0x2212,0x2213,0x2214,0x2215,0x2216,0x2219,0x221a,0x221e,0x221f,0x2225,0x2227,0x2228,0x2229,\n  0x222a,0x2248,0x2260,0x2261,0x2264,0x2265,0x226a,0x226b,0x2282,0x2283,0x2286,0x2287,0x22a5,0x22c2,0x22c3,0x2300,\n  0x2302,0x2308,0x2309,0x230a,0x230b,0x2310,0x2319,0x2320,0x2321,0x239b,0x239c,0x239d,0x239e,0x239f,0x23a0,0x23a1,\n  0x23a2,0x23a3,0x23a4,0x23a5,0x23a6,0x23a7,0x23a8,0x23a9,0x23ab,0x23ac,0x23ad,0x23ae,0x23af,0x23ba,0x23bb,0x23bc,\n  0x23bd,0x23d0,0x2409,0x240a,0x240b,0x240c,0x240d,0x2424,0x2500,0x2501,0x2502,0x2503,0x2508,0x2509,0x250a,0x250b,\n  0x250c,0x250d,0x250e,0x250f,0x2510,0x2511,0x2512,0x2513,0x2514,0x2515,0x2516,0x2517,0x2518,0x2519,0x251a,0x251b,\n  0x251c,0x251d,0x251e,0x251f,0x2520,0x2521,0x2522,0x2523,0x2524,0x2525,0x2526,0x2527,0x2528,0x2529,0x252a,0x252b,\n  0x252c,0x252d,0x252e,0x252f,0x2530,0x2531,0x2532,0x2533,0x2534,0x2535,0x2536,0x2537,0x2538,0x2539,0x253a,0x253b,\n  0x253c,0x253d,0x253e,0x253f,0x2540,0x2541,0x2542,0x2543,0x2544,0x2545,0x2546,0x2547,0x2548,0x2549,0x254a,0x254b,\n  0x2550,0x2551,0x2552,0x2553,0x2554,0x2555,0x2556,0x2557,0x2558,0x2559,0x255a,0x255b,0x255c,0x255d,0x255e,0x255f,\n  0x2560,0x2561,0x2562,0x2563,0x2564,0x2565,0x2566,0x2567,0x2568,0x2569,0x256a,0x256b,0x256c,0x256d,0x256e,0x256f,\n  0x2570,0x2571,0x2572,0x2573,0x2574,0x2575,0x2576,0x2577,0x2578,0x2579,0x257a,0x257b,0x257c,0x257d,0x257e,0x257f,\n  0x2580,0x2581,0x2582,0x2583,0x2584,0x2585,0x2586,0x2587,0x2588,0x2589,0x258a,0x258b,0x258c,0x258d,0x258e,0x258f,\n  0x2590,0x2591,0x2592,0x2593,0x2596,0x2597,0x2598,0x2599,0x259a,0x259b,0x259c,0x259d,0x259e,0x259f,0x25a0,0x25ac,\n  0x25ae,0x25b2,0x25b6,0x25ba,0x25bc,0x25c0,0x25c4,0x25c6,0x25ca,0x25cb,0x25cf,0x25d8,0x25d9,0x263a,0x263b,0x263c,\n  0x2640,0x2642,0x2660,0x2663,0x2665,0x2666,0x266a,0x266b,0x2713,0x2714,0x2717,0x2718,0x27e8,0x27e9,0x27ea,0x27eb,\n  0x2800,0x2801,0x2802,0x2803,0x2804,0x2805,0x2806,0x2807,0x2808,0x2809,0x280a,0x280b,0x280c,0x280d,0x280e,0x280f,\n  0x2810,0x2811,0x2812,0x2813,0x2814,0x2815,0x2816,0x2817,0x2818,0x2819,0x281a,0x281b,0x281c,0x281d,0x281e,0x281f,\n  0x2820,0x2821,0x2822,0x2823,0x2824,0x2825,0x2826,0x2827,0x2828,0x2829,0x282a,0x282b,0x282c,0x282d,0x282e,0x282f,\n  0x2830,0x2831,0x2832,0x2833,0x2834,0x2835,0x2836,0x2837,0x2838,0x2839,0x283a,0x283b,0x283c,0x283d,0x283e,0x283f,\n  0x2840,0x2841,0x2842,0x2843,0x2844,0x2845,0x2846,0x2847,0x2848,0x2849,0x284a,0x284b,0x284c,0x284d,0x284e,0x284f,\n  0x2850,0x2851,0x2852,0x2853,0x2854,0x2855,0x2856,0x2857,0x2858,0x2859,0x285a,0x285b,0x285c,0x285d,0x285e,0x285f,\n  0x2860,0x2861,0x2862,0x2863,0x2864,0x2865,0x2866,0x2867,0x2868,0x2869,0x286a,0x286b,0x286c,0x286d,0x286e,0x286f,\n  0x2870,0x2871,0x2872,0x2873,0x2874,0x2875,0x2876,0x2877,0x2878,0x2879,0x287a,0x287b,0x287c,0x287d,0x287e,0x287f,\n  0x2880,0x2881,0x2882,0x2883,0x2884,0x2885,0x2886,0x2887,0x2888,0x2889,0x288a,0x288b,0x288c,0x288d,0x288e,0x288f,\n  0x2890,0x2891,0x2892,0x2893,0x2894,0x2895,0x2896,0x2897,0x2898,0x2899,0x289a,0x289b,0x289c,0x289d,0x289e,0x289f,\n  0x28a0,0x28a1,0x28a2,0x28a3,0x28a4,0x28a5,0x28a6,0x28a7,0x28a8,0x28a9,0x28aa,0x28ab,0x28ac,0x28ad,0x28ae,0x28af,\n  0x28b0,0x28b1,0x28b2,0x28b3,0x28b4,0x28b5,0x28b6,0x28b7,0x28b8,0x28b9,0x28ba,0x28bb,0x28bc,0x28bd,0x28be,0x28bf,\n  0x28c0,0x28c1,0x28c2,0x28c3,0x28c4,0x28c5,0x28c6,0x28c7,0x28c8,0x28c9,0x28ca,0x28cb,0x28cc,0x28cd,0x28ce,0x28cf,\n  0x28d0,0x28d1,0x28d2,0x28d3,0x28d4,0x28d5,0x28d6,0x28d7,0x28d8,0x28d9,0x28da,0x28db,0x28dc,0x28dd,0x28de,0x28df,\n  0x28e0,0x28e1,0x28e2,0x28e3,0x28e4,0x28e5,0x28e6,0x28e7,0x28e8,0x28e9,0x28ea,0x28eb,0x28ec,0x28ed,0x28ee,0x28ef,\n  0x28f0,0x28f1,0x28f2,0x28f3,0x28f4,0x28f5,0x28f6,0x28f7,0x28f8,0x28f9,0x28fa,0x28fb,0x28fc,0x28fd,0x28fe,0x28ff,\n  0x2e2c,0xe0a0,0xe0a1,0xe0a2,0xe0b0,0xe0b1,0xe0b2,0xe0b3,0xf6be,0xfffd };\n} // namespace\n// -- end of autogenerated text ---\n\nnamespace fixed_font_32b {\n  // -- start of autogenerated text ---\n  // definition section for font: ter-u32b.bdf\n  constexpr int CHARCOUNT = 1354;\n  constexpr int WIDTH = 16;\n  constexpr int HEIGHT = 32;\n  constexpr int OFFSET_X = 0;\n  constexpr int OFFSET_Y = 0;\n  constexpr FixedFont_info_t fixedfont_info = {\n    \"Terminus\", // font name\n    \"ter-u32b.bdf\", // font name internal\n    CHARCOUNT, // num of chars\n    WIDTH, HEIGHT, OFFSET_X, OFFSET_Y,\n    true // bold\n  };\n  // font bitmap definitions\n  constexpr std::array<uint16_t, CHARCOUNT * HEIGHT> fixedfont_bitmap = {\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7c7c,0x7c7c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x701c,0x701c,\n  0x701c,0x701c,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x7c7c,0x7c7c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0020\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0021\n  0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0022\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x1c70,0x7ffc,0x7ffc,0x1c70,0x1c70,0x1c70,\n  0x1c70,0x1c70,0x1c70,0x7ffc,0x7ffc,0x1c70,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0023\n  0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x1ff0,0x3ff8,0x7bbc,0x739c,0x7380,0x7380,0x7380,0x7b80,0x3ff0,\n  0x1ff8,0x03bc,0x039c,0x039c,0x039c,0x739c,0x7bbc,0x3ff8,0x1ff0,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000, // u0024\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f1c,0x3f9c,0x3bb8,0x3bb8,0x3ff0,0x1f70,0x00e0,0x00e0,0x01c0,0x01c0,\n  0x0380,0x0380,0x0700,0x0700,0x0ef8,0x0ffc,0x1ddc,0x1ddc,0x39fc,0x38f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0025\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fc0,0x1fe0,0x3870,0x3870,0x3870,0x3870,0x3870,0x1ce0,0x0fc0,0x0f80,\n  0x1fce,0x38ee,0x707c,0x7038,0x7038,0x7038,0x7038,0x787c,0x3fee,0x1fce,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0026\n  0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0027\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00e0,0x01c0,0x0380,0x0700,0x0700,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0700,0x0700,0x0380,0x01c0,0x00e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0028\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x0700,0x0380,0x01c0,0x01c0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,\n  0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x01c0,0x01c0,0x0380,0x0700,0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0029\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x1c70,0x0ee0,0x07c0,0x0380,0x7ffc,\n  0x7ffc,0x0380,0x07c0,0x0ee0,0x1c70,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0380,0x7ffc,\n  0x7ffc,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0700,0x0e00,0x0000,0x0000,0x0000,0x0000, // u002c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,\n  0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x001c,0x001c,0x0038,0x0038,0x0070,0x0070,0x00e0,0x00e0,0x01c0,0x01c0,\n  0x0380,0x0380,0x0700,0x0700,0x0e00,0x0e00,0x1c00,0x1c00,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u002f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x703c,0x707c,0x70fc,0x71dc,0x739c,\n  0x771c,0x7e1c,0x7c1c,0x781c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0030\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0780,0x0f80,0x1f80,0x1f80,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x1ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0031\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x001c,0x0038,0x0070,\n  0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0032\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x001c,0x001c,0x001c,0x003c,0x0ff8,\n  0x0ff8,0x003c,0x001c,0x001c,0x001c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0033\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x001c,0x003c,0x007c,0x00fc,0x01dc,0x039c,0x071c,0x0e1c,0x1c1c,0x381c,\n  0x701c,0x701c,0x701c,0x7ffc,0x7ffc,0x001c,0x001c,0x001c,0x001c,0x001c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0034\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ff0,0x7ff8,\n  0x003c,0x001c,0x001c,0x001c,0x001c,0x001c,0x701c,0x781c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0035\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff8,0x3ff8,0x7800,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ff0,0x7ff8,\n  0x703c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0036\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x7038,0x0038,0x0070,0x0070,0x00e0,\n  0x00e0,0x01c0,0x01c0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0037\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,\n  0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0038\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,\n  0x3ffc,0x1ffc,0x001c,0x001c,0x001c,0x001c,0x001c,0x003c,0x3ff8,0x3ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0700,0x0e00,0x0000,0x0000,0x0000,0x0000, // u003b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x001c,0x0038,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,\n  0x3800,0x1c00,0x0e00,0x0700,0x0380,0x01c0,0x00e0,0x0070,0x0038,0x001c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x0000,0x0000,\n  0x0000,0x0000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x1c00,0x0e00,0x0700,0x0380,0x01c0,0x00e0,0x0070,0x0038,0x001c,\n  0x001c,0x0038,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x0038,0x0070,0x00e0,\n  0x01c0,0x0380,0x0380,0x0380,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u003f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff8,0x3ffc,0x780e,0x7006,0x71fe,0x73fe,0x778e,0x770e,0x770e,0x770e,\n  0x770e,0x770e,0x770e,0x779e,0x73fe,0x71f6,0x7000,0x7800,0x3ffe,0x1ffe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0040\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0041\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,0x701c,0x701c,0x701c,0x7038,0x7ff0,0x7ff0,\n  0x7038,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,0x7ff8,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0042\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x7000,0x7000,0x7000,0x7000,0x7000,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0043\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7ff0,0x7078,0x7038,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x7038,0x7078,0x7ff0,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0044\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7fe0,\n  0x7fe0,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0045\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7fe0,\n  0x7fe0,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0046\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x7000,0x7000,0x7000,0x7000,0x71fc,\n  0x71fc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0047\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x7ffc,\n  0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0048\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x0fe0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0049\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00fe,0x00fe,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,\n  0x0038,0x0038,0x0038,0x0038,0x7038,0x7038,0x7038,0x7878,0x3ff0,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u004a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x700c,0x701c,0x7038,0x7070,0x70e0,0x71c0,0x7380,0x7700,0x7e00,0x7c00,\n  0x7c00,0x7e00,0x7700,0x7380,0x71c0,0x70e0,0x7070,0x7038,0x701c,0x700c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u004b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u004c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x700e,0x700e,0x781e,0x7c3e,0x7e7e,0x7e7e,0x77ee,0x73ce,0x73ce,0x718e,\n  0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u004d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x7c1c,0x7e1c,0x771c,0x739c,\n  0x71dc,0x70fc,0x707c,0x703c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u004e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u004f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,\n  0x7ff8,0x7ff0,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0050\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x739c,0x79fc,0x3ff8,0x1ff0,0x0038,0x001c,0x0000,0x0000,0x0000,0x0000, // u0051\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,\n  0x7ff8,0x7ff0,0x7e00,0x7700,0x7380,0x71c0,0x70e0,0x7070,0x7038,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0052\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x7000,0x7000,0x7000,0x7800,0x3ff0,\n  0x1ff8,0x003c,0x001c,0x001c,0x001c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0053\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0054\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0055\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x3838,0x3838,0x3838,0x3838,0x3838,\n  0x1c70,0x1c70,0x1c70,0x1c70,0x0ee0,0x0ee0,0x0ee0,0x07c0,0x07c0,0x07c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0056\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,\n  0x718e,0x73ce,0x73ce,0x77ee,0x7e7e,0x7e7e,0x7c3e,0x781e,0x700e,0x700e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0057\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x3838,0x3838,0x1c70,0x1c70,0x0ee0,0x0ee0,0x07c0,0x07c0,\n  0x07c0,0x07c0,0x0ee0,0x0ee0,0x1c70,0x1c70,0x3838,0x3838,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0058\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x3838,0x3838,0x1c70,0x1c70,0x0ee0,0x0ee0,0x07c0,\n  0x07c0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0059\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x001c,0x001c,0x001c,0x0038,0x0070,0x00e0,0x01c0,0x0380,\n  0x0700,0x0e00,0x1c00,0x3800,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x0ff0,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0ff0,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x1c00,0x1c00,0x0e00,0x0e00,0x0700,0x0700,0x0380,0x0380,\n  0x01c0,0x01c0,0x00e0,0x00e0,0x0070,0x0070,0x0038,0x0038,0x001c,0x001c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x0ff0,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,\n  0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x0ff0,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005d\n  0x0000,0x0000,0x0000,0x0000,0x0380,0x07c0,0x0ee0,0x1c70,0x3838,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u005e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000, // u005f\n  0x0000,0x1c00,0x0e00,0x0700,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0060\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x003c,0x001c,\n  0x001c,0x1ffc,0x3ffc,0x781c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0061\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ff0,0x7ff8,0x703c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,0x7ff8,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0062\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0063\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x1ffc,0x3ffc,0x781c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0064\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x781c,0x3ffc,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0065\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00fe,0x01fe,0x03c0,0x0380,0x0380,0x0380,0x3ff8,0x3ff8,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0066\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ffc,0x3ffc,0x781c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x001c,0x001c,0x003c,0x3ff8,0x3ff0,0x0000, // u0067\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ff0,0x7ff8,0x703c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0068\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0f80,0x0f80,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0069\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x00f8,0x00f8,0x0038,0x0038,\n  0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x3838,0x3838,0x3c78,0x1ff0,0x0fe0,0x0000, // u006a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x381c,0x3838,0x3870,0x38e0,\n  0x39c0,0x3b80,0x3f00,0x3f00,0x3b80,0x39c0,0x38e0,0x3870,0x3838,0x381c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u006b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f80,0x0f80,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u006c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x73bc,0x739c,\n  0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u006d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u006e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u006f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,0x7ff8,0x7ff0,0x7000,0x7000,0x7000,0x7000,0x7000,0x0000, // u0070\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ffc,0x3ffc,0x781c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x001c,0x001c,0x001c,0x001c,0x001c,0x0000, // u0071\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x73fc,0x77fc,0x7e00,0x7c00,\n  0x7800,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0072\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x7000,\n  0x7000,0x7800,0x3ff0,0x1ff8,0x003c,0x001c,0x001c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0073\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x7ff0,0x7ff0,0x0700,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0780,0x03fc,0x01fc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0074\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0075\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x3838,\n  0x3838,0x3838,0x1c70,0x1c70,0x1c70,0x0ee0,0x0ee0,0x07c0,0x07c0,0x07c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0076\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x7bbc,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0077\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x3838,\n  0x1c70,0x0ee0,0x07c0,0x07c0,0x0ee0,0x1c70,0x3838,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0078\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x001c,0x001c,0x003c,0x3ff8,0x3ff0,0x0000, // u0079\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x0038,0x0070,\n  0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01f0,0x03f0,0x0780,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x3e00,\n  0x3e00,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0780,0x03f0,0x01f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x3f00,0x0780,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x01f0,\n  0x01f0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0780,0x3f00,0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007d\n  0x0000,0x0000,0x0000,0x0000,0x1e1c,0x3f1c,0x779c,0x73dc,0x71f8,0x70f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u007e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x1ff0,0x3ff8,0x7bbc,0x739c,\n  0x7380,0x7380,0x7380,0x7380,0x7380,0x7380,0x739c,0x7bbc,0x3ff8,0x1ff0,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000, // u00a2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07e0,0x0ff0,0x1e78,0x1c38,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x7fe0,\n  0x7fe0,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1c1c,0x1c1c,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x3838,0x1ff0,0x1ff0,0x3838,0x3838,0x3838,\n  0x3838,0x3838,0x3838,0x1ff0,0x1ff0,0x3838,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x3838,0x3838,0x1c70,0x1c70,0x0ee0,0x0ee0,0x07c0,0x07c0,\n  0x0380,0x0380,0x3ff8,0x3ff8,0x0380,0x0380,0x3ff8,0x3ff8,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,\n  0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a6\n  0x0000,0x0000,0x0000,0x0000,0x07e0,0x0ff0,0x1e78,0x1c38,0x1c00,0x1e00,0x0fc0,0x0fe0,0x1cf0,0x1c78,0x1c38,0x1c38,\n  0x1c38,0x1e38,0x0f38,0x07f0,0x03f0,0x0078,0x0038,0x1c38,0x1e78,0x0ff0,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a7\n  0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff8,0x3ffc,0x700e,0x67e6,0x6ff6,0x6e76,0x6e06,0x6e06,\n  0x6e06,0x6e06,0x6e76,0x6ff6,0x67e6,0x700e,0x3ffc,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00a9\n  0x0000,0x0000,0x1fe0,0x1ff0,0x0038,0x0038,0x0ff8,0x1ff8,0x3838,0x3838,0x3838,0x1ff8,0x0ff8,0x0000,0x0000,0x3ff8,\n  0x3ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01ce,0x039c,0x0738,0x0e70,\n  0x1ce0,0x39c0,0x7380,0x7380,0x39c0,0x1ce0,0x0e70,0x0738,0x039c,0x01ce,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ab\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x001c,0x001c,\n  0x001c,0x001c,0x001c,0x001c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ac\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff8,\n  0x3ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ad\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff8,0x3ffc,0x700e,0x6fe6,0x6ff6,0x6e76,0x6e76,0x6e76,\n  0x6fe6,0x6fc6,0x6fc6,0x6ee6,0x6e76,0x700e,0x3ffc,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ae\n  0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00af\n  0x0000,0x0000,0x0000,0x0000,0x0fe0,0x1ff0,0x1c70,0x1c70,0x1c70,0x1c70,0x1ff0,0x0fe0,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0380,0x7ffc,\n  0x7ffc,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b1\n  0x0000,0x0000,0x0000,0x0fe0,0x1ff0,0x1c70,0x1c70,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1ff0,0x1ff0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b2\n  0x0000,0x0000,0x0000,0x0fe0,0x1ff0,0x1c70,0x0070,0x03e0,0x03e0,0x0070,0x0070,0x1c70,0x1ff0,0x0fe0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b3\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,0x707c,0x70fc,0x7fdc,0x7f9c,0x7000,0x7000,0x7000,0x7000,0x7000,0x0000, // u00b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ffe,0x3ffe,0x79ce,0x71ce,0x71ce,0x71ce,0x71ce,0x71ce,0x79ce,0x3fce,\n  0x1fce,0x01ce,0x01ce,0x01ce,0x01ce,0x01ce,0x01ce,0x01ce,0x01ce,0x01ce,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,\n  0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0700,0x0e00,0x0000, // u00b8\n  0x0000,0x0000,0x0000,0x0380,0x0780,0x0f80,0x0f80,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00b9\n  0x0000,0x0000,0x0fe0,0x1ff0,0x3838,0x3838,0x3838,0x3838,0x3838,0x3838,0x3838,0x1ff0,0x0fe0,0x0000,0x0000,0x3ff8,\n  0x3ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7380,0x39c0,0x1ce0,0x0e70,\n  0x0738,0x039c,0x01ce,0x01ce,0x039c,0x0738,0x0e70,0x1ce0,0x39c0,0x7380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x1e00,0x3e00,0x0e00,0x0e06,0x0e0e,0x0e1c,0x0e38,0x0e70,0x00e0,\n  0x01ce,0x039e,0x073e,0x0e7e,0x1cee,0x39ce,0x73fe,0x63fe,0x000e,0x000e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x3c00,0x7c06,0x1c0e,0x1c1c,0x1c38,0x1c70,0x1ce0,0x1dc0,0x0380,\n  0x0700,0x0efc,0x1dfe,0x39ce,0x71ce,0x601c,0x0038,0x0070,0x00fe,0x01fe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00bd\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x7fc0,0x71c0,0x0f80,0x0f80,0x01c6,0x71ce,0x7fdc,0x3fb8,0x0070,\n  0x00ee,0x01de,0x03be,0x077e,0x0eee,0x1dce,0x3bfe,0x73fe,0x600e,0x000e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00be\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0380,0x0380,0x0380,0x0700,\n  0x0e00,0x1c00,0x3800,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00bf\n  0x0000,0x1c00,0x0e00,0x0700,0x0380,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c0\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c1\n  0x0000,0x0380,0x07c0,0x0ee0,0x1c70,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c2\n  0x0000,0x1f38,0x3bb8,0x3bb8,0x39f0,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c3\n  0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c4\n  0x0000,0x07c0,0x0ee0,0x0ee0,0x0ee0,0x07c0,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffe,0x7ffe,0xf1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xfffe,\n  0xfffe,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1fe,0xe1fe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x7000,0x7000,0x7000,0x7000,0x7000,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0380,0x0380,0x0380,0x0700,0x0e00,0x0000, // u00c7\n  0x0000,0x1c00,0x0e00,0x0700,0x0380,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7fe0,\n  0x7fe0,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c8\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7fe0,\n  0x7fe0,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00c9\n  0x0000,0x0380,0x07c0,0x0ee0,0x1c70,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7fe0,\n  0x7fe0,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ca\n  0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7fe0,\n  0x7fe0,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cb\n  0x0000,0x1c00,0x0e00,0x0700,0x0380,0x0000,0x0fe0,0x0fe0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cc\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0fe0,0x0fe0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cd\n  0x0000,0x0380,0x07c0,0x0ee0,0x1c70,0x0000,0x0fe0,0x0fe0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ce\n  0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0fe0,0x0fe0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00cf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7ff0,0x7078,0x7038,0x701c,0x701c,0x701c,0x701c,0x701c,0xff9c,\n  0xff9c,0x701c,0x701c,0x701c,0x701c,0x701c,0x7038,0x7078,0x7ff0,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d0\n  0x0000,0x1f38,0x3bb8,0x3bb8,0x39f0,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x7c1c,0x7e1c,0x771c,0x739c,\n  0x71dc,0x70fc,0x707c,0x703c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d1\n  0x0000,0x1c00,0x0e00,0x0700,0x0380,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d2\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d3\n  0x0000,0x0380,0x07c0,0x0ee0,0x1c70,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d4\n  0x0000,0x1f38,0x3bb8,0x3bb8,0x39f0,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d5\n  0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x700e,0x381c,0x1c38,0x0e70,0x07e0,0x03c0,\n  0x03c0,0x07e0,0x0e70,0x1c38,0x381c,0x700e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783e,0x701e,0x701c,0x703c,0x707c,0x70fc,0x71dc,0x739c,\n  0x771c,0x7e1c,0x7c1c,0x781c,0x701c,0xf01c,0xf01c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d8\n  0x0000,0x1c00,0x0e00,0x0700,0x0380,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00d9\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00da\n  0x0000,0x0380,0x07c0,0x0ee0,0x1c70,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00db\n  0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00dc\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x701c,0x701c,0x701c,0x3838,0x3838,0x1c70,0x1c70,0x0ee0,0x0ee0,0x07c0,\n  0x07c0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00dd\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x7000,0x7000,0x7000,0x7ff0,0x7ff8,0x703c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x703c,0x7ff8,0x7ff0,0x7000,0x7000,0x7000,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00de\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fe0,0x7ff0,0x7078,0x7038,0x7038,0x7038,0x7038,0x7070,0x7ff0,0x7ff0,\n  0x7038,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x7c3c,0x77f8,0x73f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00df\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0e00,0x0700,0x0380,0x0000,0x0000,0x3ff0,0x3ff8,0x003c,0x001c,\n  0x001c,0x1ffc,0x3ffc,0x781c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x3ff0,0x3ff8,0x003c,0x001c,\n  0x001c,0x1ffc,0x3ffc,0x781c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x07c0,0x0ee0,0x1c70,0x0000,0x0000,0x3ff0,0x3ff8,0x003c,0x001c,\n  0x001c,0x1ffc,0x3ffc,0x781c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f38,0x3bb8,0x3bb8,0x39f0,0x0000,0x0000,0x3ff0,0x3ff8,0x003c,0x001c,\n  0x001c,0x1ffc,0x3ffc,0x781c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x3ff0,0x3ff8,0x003c,0x001c,\n  0x001c,0x1ffc,0x3ffc,0x781c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07c0,0x0ee0,0x0ee0,0x0ee0,0x07c0,0x0000,0x3ff0,0x3ff8,0x003c,0x001c,\n  0x001c,0x1ffc,0x3ffc,0x781c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ef8,0x7ffc,0x039e,0x038e,\n  0x038e,0x3f8e,0x7ffe,0xf3fe,0xe380,0xe380,0xe380,0xf3ce,0x7ffe,0x3efc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x701c,0x783c,0x3ff8,0x1ff0,0x0380,0x0380,0x0380,0x0700,0x0e00,0x0000, // u00e7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0e00,0x0700,0x0380,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x781c,0x3ffc,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x781c,0x3ffc,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00e9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x07c0,0x0ee0,0x1c70,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x781c,0x3ffc,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x781c,0x3ffc,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00eb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0e00,0x0700,0x0380,0x0000,0x0000,0x0f80,0x0f80,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ec\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x0f80,0x0f80,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ed\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x07c0,0x0ee0,0x1c70,0x0000,0x0000,0x0f80,0x0f80,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ee\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x0f80,0x0f80,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00ef\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1dc0,0x0f80,0x1f00,0x3b80,0x01c0,0x00e0,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f38,0x3bb8,0x3bb8,0x39f0,0x0000,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0e00,0x0700,0x0380,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x07c0,0x0ee0,0x1c70,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f38,0x3bb8,0x3bb8,0x39f0,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x7ffc,\n  0x7ffc,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff6,0x3ffe,0x783c,0x707c,\n  0x70fc,0x71dc,0x739c,0x771c,0x7e1c,0x7c1c,0x781c,0x783c,0xfff8,0xdff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0e00,0x0700,0x0380,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00f9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00fa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x07c0,0x0ee0,0x1c70,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00fb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u00fc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x001c,0x001c,0x003c,0x3ff8,0x3ff0,0x0000, // u00fd\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ff0,0x7ff8,0x703c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,0x7ff8,0x7ff0,0x7000,0x7000,0x7000,0x7000,0x7000,0x0000, // u00fe\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x001c,0x001c,0x003c,0x3ff8,0x3ff0,0x0000, // u00ff\n  0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0100\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000,0x3ff0,0x3ff8,0x003c,0x001c,\n  0x001c,0x1ffc,0x3ffc,0x781c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0101\n  0x0000,0x1c70,0x1c70,0x0fe0,0x07c0,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0102\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x0fe0,0x07c0,0x0000,0x0000,0x3ff0,0x3ff8,0x003c,0x001c,\n  0x001c,0x1ffc,0x3ffc,0x781c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0103\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x007c,0x00f0,0x00e0,0x00fc,0x007c,0x0000, // u0104\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x003c,0x001c,\n  0x001c,0x1ffc,0x3ffc,0x781c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x007c,0x00f0,0x00e0,0x00fc,0x007c,0x0000, // u0105\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x7000,0x7000,0x7000,0x7000,0x7000,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0106\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0107\n  0x0000,0x0380,0x07c0,0x0ee0,0x1c70,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x7000,0x7000,0x7000,0x7000,0x7000,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0108\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x07c0,0x0ee0,0x1c70,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0109\n  0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x7000,0x7000,0x7000,0x7000,0x7000,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u010a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u010b\n  0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x7000,0x7000,0x7000,0x7000,0x7000,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u010c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u010d\n  0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x7fc0,0x7ff0,0x7078,0x7038,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x7038,0x7078,0x7ff0,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u010e\n  0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x1ffc,0x3ffc,0x781c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u010f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7ff0,0x7078,0x7038,0x701c,0x701c,0x701c,0x701c,0x701c,0xff9c,\n  0xff9c,0x701c,0x701c,0x701c,0x701c,0x701c,0x7038,0x7078,0x7ff0,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0110\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x001c,0x001c,0x03ff,0x03ff,0x001c,0x001c,0x1ffc,0x3ffc,0x781c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0111\n  0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7fe0,\n  0x7fe0,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0112\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x781c,0x3ffc,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0113\n  0x0000,0x1c70,0x1c70,0x0fe0,0x07c0,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7fe0,\n  0x7fe0,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0114\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x0fe0,0x07c0,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x781c,0x3ffc,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0115\n  0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7fe0,\n  0x7fe0,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0116\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x781c,0x3ffc,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0117\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7fe0,\n  0x7fe0,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x007c,0x00f0,0x00e0,0x00fc,0x007c,0x0000, // u0118\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x781c,0x3ffc,0x1ff8,0x03c0,0x0780,0x0700,0x07e0,0x03e0,0x0000, // u0119\n  0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7fe0,\n  0x7fe0,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u011a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x781c,0x3ffc,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u011b\n  0x0000,0x0380,0x07c0,0x0ee0,0x1c70,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x7000,0x7000,0x7000,0x7000,0x71fc,\n  0x71fc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u011c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x07c0,0x0ee0,0x1c70,0x0000,0x0000,0x1ffc,0x3ffc,0x781c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x001c,0x001c,0x003c,0x3ff8,0x3ff0,0x0000, // u011d\n  0x0000,0x1c70,0x1c70,0x0fe0,0x07c0,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x7000,0x7000,0x7000,0x7000,0x71fc,\n  0x71fc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u011e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x0fe0,0x07c0,0x0000,0x0000,0x1ffc,0x3ffc,0x781c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x001c,0x001c,0x003c,0x3ff8,0x3ff0,0x0000, // u011f\n  0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x7000,0x7000,0x7000,0x7000,0x71fc,\n  0x71fc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0120\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01c0,0x01c0,0x01c0,0x01c0,0x0000,0x0000,0x1ffc,0x3ffc,0x781c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x001c,0x001c,0x003c,0x3ff8,0x3ff0,0x0000, // u0121\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x7000,0x7000,0x7000,0x7000,0x71fc,\n  0x71fc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0380,0x0380,0x0380,0x0700,0x0e00, // u0122\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x01c0,0x01c0,0x0000,0x1ffc,0x3ffc,0x781c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x001c,0x001c,0x003c,0x3ff8,0x3ff0,0x0000, // u0123\n  0x0000,0x0380,0x07c0,0x0ee0,0x1c70,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x7ffc,\n  0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0124\n  0x0000,0x0380,0x07c0,0x0ee0,0x1c70,0x0000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ff0,0x7ff8,0x703c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0125\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0xfffe,0xfffe,0x701c,0x701c,0x701c,0x701c,0x7ffc,\n  0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0126\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0xffc0,0xffc0,0x3800,0x3800,0x3ff8,0x3ffc,0x381e,0x380e,\n  0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0127\n  0x0000,0x1f38,0x3bb8,0x3bb8,0x39f0,0x0000,0x0fe0,0x0fe0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0128\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f38,0x3bb8,0x3bb8,0x39f0,0x0000,0x0000,0x0f80,0x0f80,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0129\n  0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000,0x0fe0,0x0fe0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u012a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000,0x0f80,0x0f80,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u012b\n  0x0000,0x1c70,0x1c70,0x0fe0,0x07c0,0x0000,0x0fe0,0x0fe0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u012c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x0fe0,0x07c0,0x0000,0x0000,0x0f80,0x0f80,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u012d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x0fe0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0380,0x0780,0x0700,0x07e0,0x03e0,0x0000, // u012e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0f80,0x0f80,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0380,0x0780,0x0700,0x07e0,0x03e0,0x0000, // u012f\n  0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x0fe0,0x0fe0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0130\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f80,0x0f80,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0131\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf81f,0xf81f,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,\n  0x700e,0x700e,0x700e,0x700e,0x738e,0x738e,0x738e,0x73de,0xf9fc,0xf8f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0132\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x700e,0x700e,0x700e,0x700e,0x0000,0x0000,0xf03e,0xf03e,0x700e,0x700e,\n  0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0xf80e,0xf80e,0x038e,0x038e,0x03de,0x01fc,0x00f8,0x0000, // u0133\n  0x0000,0x0038,0x007c,0x00ee,0x01c7,0x0000,0x00fe,0x00fe,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,\n  0x0038,0x0038,0x0038,0x0038,0x7038,0x7038,0x7038,0x7878,0x3ff0,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0134\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x007c,0x00ee,0x01c7,0x0000,0x0000,0x00f8,0x00f8,0x0038,0x0038,\n  0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x3838,0x3838,0x3c78,0x1ff0,0x0fe0,0x0000, // u0135\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x700c,0x701c,0x7038,0x7070,0x70e0,0x71c0,0x7380,0x7700,0x7e00,0x7c00,\n  0x7c00,0x7e00,0x7700,0x7380,0x71c0,0x70e0,0x7070,0x7038,0x701c,0x700c,0x0000,0x0380,0x0380,0x0380,0x0700,0x0e00, // u0136\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x381c,0x3838,0x3870,0x38e0,\n  0x39c0,0x3b80,0x3f00,0x3f00,0x3b80,0x39c0,0x38e0,0x3870,0x3838,0x381c,0x0000,0x0380,0x0380,0x0380,0x0700,0x0e00, // u0137\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x381c,0x3838,0x3870,0x38e0,\n  0x39c0,0x3b80,0x3f00,0x3f00,0x3b80,0x39c0,0x38e0,0x3870,0x3838,0x381c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0138\n  0x0000,0x0e00,0x1c00,0x3800,0x7000,0x0000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0139\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0f80,0x0f80,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u013a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0380,0x0380,0x0380,0x0700,0x0e00, // u013b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f80,0x0f80,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0380,0x0380,0x0380,0x0700,0x0e00, // u013c\n  0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u013d\n  0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x0f80,0x0f80,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u013e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7070,0x7070,\n  0x7070,0x7070,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u013f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f80,0x0f80,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0387,0x0387,\n  0x0387,0x0387,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0140\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3b80,0x3f00,0x3e00,\n  0x3c00,0x7800,0xf800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3ffe,0x3ffe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0141\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f80,0x0f80,0x0380,0x0380,0x0380,0x0380,0x0380,0x03f0,0x03e0,0x03c0,\n  0x0780,0x0f80,0x1f80,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0142\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x7c1c,0x7e1c,0x771c,0x739c,\n  0x71dc,0x70fc,0x707c,0x703c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0143\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0144\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x7c1c,0x7e1c,0x771c,0x739c,\n  0x71dc,0x70fc,0x707c,0x703c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0380,0x0380,0x0380,0x0700,0x0e00, // u0145\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0380,0x0380,0x0380,0x0700,0x0e00, // u0146\n  0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x7c1c,0x7e1c,0x771c,0x739c,\n  0x71dc,0x70fc,0x707c,0x703c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0147\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0148\n  0x0000,0x0000,0x0000,0x0000,0x7000,0x7000,0x7000,0x7000,0xe000,0xe000,0x0000,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0149\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x7c1c,0x7e1c,0x771c,0x739c,\n  0x71dc,0x70fc,0x707c,0x703c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x001c,0x001c,0x003c,0x01f8,0x01f0,0x0000, // u014a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x001c,0x001c,0x003c,0x01f8,0x01f0,0x0000, // u014b\n  0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u014c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u014d\n  0x0000,0x1c70,0x1c70,0x0fe0,0x07c0,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u014e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x0fe0,0x07c0,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u014f\n  0x0000,0x038e,0x071c,0x0e38,0x1c70,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0150\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x038e,0x071c,0x0e38,0x1c70,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0151\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffe,0x7ffe,0xf1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1fe,\n  0xe1fe,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xf1c0,0x7ffe,0x3ffe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0152\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff8,0x7ffc,0xf39e,0xe38e,\n  0xe38e,0xe38e,0xe3fe,0xe3fe,0xe380,0xe380,0xe380,0xf38e,0x7ffe,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0153\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,\n  0x7ff8,0x7ff0,0x7e00,0x7700,0x7380,0x71c0,0x70e0,0x7070,0x7038,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0154\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x73fc,0x77fc,0x7e00,0x7c00,\n  0x7800,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0155\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,\n  0x7ff8,0x7ff0,0x7e00,0x7700,0x7380,0x71c0,0x70e0,0x7070,0x7038,0x701c,0x0000,0x0380,0x0380,0x0380,0x0700,0x0e00, // u0156\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x39fe,0x3bfe,0x3f00,0x3e00,\n  0x3c00,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x0000,0x3800,0x3800,0x3800,0x7000,0xe000, // u0157\n  0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,\n  0x7ff8,0x7ff0,0x7e00,0x7700,0x7380,0x71c0,0x70e0,0x7070,0x7038,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0158\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x0000,0x73fc,0x77fc,0x7e00,0x7c00,\n  0x7800,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0159\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x7000,0x7000,0x7000,0x7800,0x3ff0,\n  0x1ff8,0x003c,0x001c,0x001c,0x001c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u015a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x7000,\n  0x7000,0x7800,0x3ff0,0x1ff8,0x003c,0x001c,0x001c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u015b\n  0x0000,0x0380,0x07c0,0x0ee0,0x1c70,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x7000,0x7000,0x7000,0x7800,0x3ff0,\n  0x1ff8,0x003c,0x001c,0x001c,0x001c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u015c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x07c0,0x0ee0,0x1c70,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x7000,\n  0x7000,0x7800,0x3ff0,0x1ff8,0x003c,0x001c,0x001c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u015d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x7000,0x7000,0x7000,0x7800,0x3ff0,\n  0x1ff8,0x003c,0x001c,0x001c,0x001c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0380,0x0380,0x0380,0x0700,0x0e00,0x0000, // u015e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x7000,\n  0x7000,0x7800,0x3ff0,0x1ff8,0x003c,0x001c,0x001c,0x783c,0x3ff8,0x1ff0,0x0380,0x0380,0x0380,0x0700,0x0e00,0x0000, // u015f\n  0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x7000,0x7000,0x7000,0x7800,0x3ff0,\n  0x1ff8,0x003c,0x001c,0x001c,0x001c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0160\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x7000,\n  0x7000,0x7800,0x3ff0,0x1ff8,0x003c,0x001c,0x001c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0161\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x01c0,0x01c0,0x01c0,0x0380,0x0700,0x0000, // u0162\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x7ff0,0x7ff0,0x0700,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0780,0x03fc,0x01fc,0x0070,0x0070,0x0070,0x00e0,0x01c0,0x0000, // u0163\n  0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x7ffc,0x7ffc,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0164\n  0x0000,0x38e0,0x1dc0,0x0f80,0x0700,0x0000,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x7ff0,0x7ff0,0x0700,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0780,0x03fc,0x01fc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0165\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x1ff0,\n  0x1ff0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0166\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x7ff0,0x7ff0,0x0700,0x0700,\n  0x1fc0,0x1fc0,0x0700,0x0700,0x0700,0x0700,0x0700,0x0780,0x03fc,0x01fc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0167\n  0x0000,0x1f38,0x3bb8,0x3bb8,0x39f0,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0168\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f38,0x3bb8,0x3bb8,0x39f0,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0169\n  0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u016a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u016b\n  0x0000,0x1c70,0x1c70,0x0fe0,0x07c0,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u016c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x0fe0,0x07c0,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u016d\n  0x0000,0x07c0,0x0ee0,0x0ee0,0x0ee0,0x07c0,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u016e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07c0,0x0ee0,0x0ee0,0x0ee0,0x07c0,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u016f\n  0x0000,0x038e,0x071c,0x0e38,0x1c70,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0170\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x038e,0x071c,0x0e38,0x1c70,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0171\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x03c0,0x0780,0x0700,0x07e0,0x03e0,0x0000, // u0172\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x007c,0x00f0,0x00e0,0x00fc,0x007c,0x0000, // u0173\n  0x0000,0x0380,0x07c0,0x0ee0,0x1c70,0x0000,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,\n  0x718e,0x73ce,0x73ce,0x77ee,0x7e7e,0x7e7e,0x7c3e,0x781e,0x700e,0x700e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0174\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x07c0,0x0ee0,0x1c70,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x7bbc,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0175\n  0x0000,0x0380,0x07c0,0x0ee0,0x1c70,0x0000,0x701c,0x701c,0x701c,0x3838,0x3838,0x1c70,0x1c70,0x0ee0,0x0ee0,0x07c0,\n  0x07c0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0176\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x07c0,0x0ee0,0x1c70,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x001c,0x001c,0x003c,0x3ff8,0x3ff0,0x0000, // u0177\n  0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x701c,0x701c,0x701c,0x3838,0x3838,0x1c70,0x1c70,0x0ee0,0x0ee0,0x07c0,\n  0x07c0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0178\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x7ffc,0x7ffc,0x001c,0x001c,0x001c,0x0038,0x0070,0x00e0,0x01c0,0x0380,\n  0x0700,0x0e00,0x1c00,0x3800,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0179\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x7ffc,0x7ffc,0x0038,0x0070,\n  0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u017a\n  0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x7ffc,0x7ffc,0x001c,0x001c,0x001c,0x0038,0x0070,0x00e0,0x01c0,0x0380,\n  0x0700,0x0e00,0x1c00,0x3800,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u017b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x7ffc,0x7ffc,0x0038,0x0070,\n  0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u017c\n  0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x7ffc,0x7ffc,0x001c,0x001c,0x001c,0x0038,0x0070,0x00e0,0x01c0,0x0380,\n  0x0700,0x0e00,0x1c00,0x3800,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u017d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x0000,0x7ffc,0x7ffc,0x0038,0x0070,\n  0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u017e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00fe,0x01fe,0x03c0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u017f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x001c,0x001c,0x001c,0x001c,0x001c,\n  0x001c,0x001c,0x001c,0x001c,0x001c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0186\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x0ffc,\n  0x0ffc,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u018e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x001c,0x001c,0x001c,0x001c,0x7ffc,\n  0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u018f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x7000,0x7000,0x7000,0x7800,0x3fe0,\n  0x3fe0,0x7800,0x7000,0x7000,0x7000,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0190\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01f8,0x03fc,0x039c,0x039c,0x0380,0x0380,0x0380,0x0380,0x1ff0,0x1ff0,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x7380,0x7380,0x7f80,0x3f00,0x0000,0x0000, // u0192\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x380e,0x380e,0x380e,0x380e,0x380e,0x3c0e,0x3e0e,0x3f0e,0x3b8e,0x39ce,\n  0x38ee,0x387e,0x383e,0x381e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x3800,0x3800,0x3800,0x7800,0xf000,0x0000, // u019d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x001c,0x001c,0x001c,0x001c,0x001c,0x0000, // u019e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x001c,0x001c,0x001c,0x0038,0x0070,0x00e0,0x01c0,0x7ffc,\n  0x7ffc,0x0700,0x0e00,0x1c00,0x3800,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x0038,0x0070,\n  0x00e0,0x01c0,0x7ffc,0x7ffc,0x0700,0x0e00,0x1c00,0x3800,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x0038,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0ff0,0x0ff8,\n  0x003c,0x001c,0x001c,0x001c,0x001c,0x001c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01b7\n  0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01cd\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x0000,0x3ff0,0x3ff8,0x003c,0x001c,\n  0x001c,0x1ffc,0x3ffc,0x781c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01ce\n  0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x0fe0,0x0fe0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01cf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x0000,0x0f80,0x0f80,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d0\n  0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d2\n  0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01d4\n  0x0000,0x0000,0x3ff8,0x3ff8,0x0000,0x0000,0x3ffe,0x7ffe,0xf1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xfffe,\n  0xfffe,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1fe,0xe1fe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff8,0x3ff8,0x0000,0x0000,0x7ef8,0x7ffc,0x039e,0x038e,\n  0x038e,0x3f8e,0x7ffe,0xf3fe,0xe380,0xe380,0xe380,0xf3ce,0x7ffe,0x3efc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x7000,0x7000,0x7000,0x7000,0x71fc,\n  0x71fc,0x701c,0x701c,0x71ff,0x71ff,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ffc,0x3ffc,0x781c,0x701c,\n  0x701c,0x701c,0x71ff,0x71ff,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x001c,0x001c,0x003c,0x3ff8,0x3ff0,0x0000, // u01e5\n  0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x7000,0x7000,0x7000,0x7000,0x71fc,\n  0x71fc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x0000,0x1ffc,0x3ffc,0x781c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x001c,0x001c,0x003c,0x3ff8,0x3ff0,0x0000, // u01e7\n  0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x700c,0x701c,0x7038,0x7070,0x70e0,0x71c0,0x7380,0x7700,0x7e00,0x7c00,\n  0x7c00,0x7e00,0x7700,0x7380,0x71c0,0x70e0,0x7070,0x7038,0x701c,0x700c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e8\n  0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x381c,0x3838,0x3870,0x38e0,\n  0x39c0,0x3b80,0x3f00,0x3f00,0x3b80,0x39c0,0x38e0,0x3870,0x3838,0x381c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01e9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x03c0,0x0780,0x0700,0x07e0,0x03e0,0x0000, // u01ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x03c0,0x0780,0x0700,0x07e0,0x03e0,0x0000, // u01eb\n  0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x03c0,0x0780,0x0700,0x07e0,0x03e0,0x0000, // u01ec\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x03c0,0x0780,0x0700,0x07e0,0x03e0,0x0000, // u01ed\n  0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x7ffc,0x7ffc,0x0038,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0ff0,0x0ff8,\n  0x003c,0x001c,0x001c,0x001c,0x001c,0x001c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01ee\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x0000,0x7ffc,0x7ffc,0x0038,0x0070,\n  0x00e0,0x01c0,0x0380,0x0700,0x0ff0,0x0ff8,0x003c,0x001c,0x001c,0x001c,0x001c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000, // u01ef\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01c7,0x00ee,0x007c,0x0038,0x0000,0x0000,0x00f8,0x00f8,0x0038,0x0038,\n  0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x3838,0x3838,0x3c78,0x1ff0,0x0fe0,0x0000, // u01f0\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x7000,0x7000,0x7000,0x7000,0x71fc,\n  0x71fc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x1ffc,0x3ffc,0x781c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x001c,0x001c,0x003c,0x3ff8,0x3ff0,0x0000, // u01f5\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x3ffe,0x7ffe,0xf1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xfffe,\n  0xfffe,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1fe,0xe1fe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01fc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x7ef8,0x7ffc,0x039e,0x038e,\n  0x038e,0x3f8e,0x7ffe,0xf3fe,0xe380,0xe380,0xe380,0xf3ce,0x7ffe,0x3efc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01fd\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x1ff0,0x3ff8,0x783e,0x701e,0x701c,0x703c,0x707c,0x70fc,0x71dc,0x739c,\n  0x771c,0x7e1c,0x7c1c,0x781c,0x701c,0xf01c,0xf01c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01fe\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x1ff6,0x3ffe,0x783c,0x707c,\n  0x70fc,0x71dc,0x739c,0x771c,0x7e1c,0x7c1c,0x781c,0x783c,0xfff8,0xdff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u01ff\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x7000,0x7000,0x7000,0x7800,0x3ff0,\n  0x1ff8,0x003c,0x001c,0x001c,0x001c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0380,0x0380,0x0380,0x0700,0x0e00, // u0218\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x7000,\n  0x7000,0x7800,0x3ff0,0x1ff8,0x003c,0x001c,0x001c,0x783c,0x3ff8,0x1ff0,0x0000,0x0380,0x0380,0x0380,0x0700,0x0e00, // u0219\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0380,0x0380,0x0380,0x0700,0x0e00, // u021a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x7ff0,0x7ff0,0x0700,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0780,0x03fc,0x01fc,0x0000,0x0070,0x0070,0x0070,0x00e0,0x01c0, // u021b\n  0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000,0x701c,0x701c,0x701c,0x3838,0x3838,0x1c70,0x1c70,0x0ee0,0x0ee0,0x07c0,\n  0x07c0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0232\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x001c,0x001c,0x003c,0x3ff8,0x3ff0,0x0000, // u0233\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00f8,0x00f8,0x0038,0x0038,\n  0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x3838,0x3838,0x3c78,0x1ff0,0x0fe0,0x0000, // u0237\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0254\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x7ffc,0x7ffc,0x001c,0x001c,0x001c,0x703c,0x7ff8,0x3ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0258\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x7ff8,0x703c,0x001c,\n  0x001c,0x001c,0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0259\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x7000,0x7800,0x3fc0,0x3fc0,0x7800,0x7000,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u025b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff8,0x3ffc,0x381e,0x380e,\n  0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x3800,0x3800,0x3800,0x7800,0xf000,0x0000, // u0272\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x0038,0x0070,\n  0x00e0,0x01c0,0x0380,0x0700,0x0ff0,0x0ff8,0x003c,0x001c,0x001c,0x001c,0x001c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000, // u0292\n  0x0000,0x00e0,0x01c0,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bb\n  0x0000,0x0380,0x0380,0x0380,0x0700,0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bc\n  0x0000,0x0380,0x0380,0x0380,0x01c0,0x00e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02bd\n  0x0000,0x0380,0x07c0,0x0ee0,0x1c70,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02c6\n  0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02c7\n  0x0000,0x1c70,0x1c70,0x0fe0,0x07c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02d8\n  0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02d9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03c0,0x0780,0x0700,0x07e0,0x03e0,0x0000, // u02db\n  0x0000,0x1f38,0x3bb8,0x3bb8,0x39f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02dc\n  0x0000,0x038e,0x071c,0x0e38,0x1c70,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u02dd\n  0x0000,0x1c00,0x0e00,0x0700,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0300\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0301\n  0x0000,0x0380,0x07c0,0x0ee0,0x1c70,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0302\n  0x0000,0x1f38,0x3bb8,0x3bb8,0x39f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0303\n  0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0304\n  0x0000,0x0000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0305\n  0x0000,0x1c70,0x1c70,0x0fe0,0x07c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0306\n  0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0307\n  0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0308\n  0x0000,0x07c0,0x0ee0,0x0ee0,0x0ee0,0x07c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030a\n  0x0000,0x038e,0x071c,0x0e38,0x1c70,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030b\n  0x0000,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u030c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000, // u0329\n  0x0000,0x0000,0x1c00,0x3800,0x7000,0xe000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0384\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0385\n  0x0000,0x0000,0x1c00,0x3800,0x7000,0xe000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0386\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0387\n  0x0000,0x0000,0x1c00,0x3800,0x7000,0xe000,0x3ffe,0x3ffe,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3ff0,\n  0x3ff0,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3ffe,0x3ffe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0388\n  0x0000,0x0000,0x1c00,0x3800,0x7000,0xe000,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x3ffe,\n  0x3ffe,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0389\n  0x0000,0x0000,0x1c00,0x3800,0x7000,0xe000,0x0fe0,0x0fe0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u038a\n  0x0000,0x0000,0x1c00,0x3800,0x7000,0xe000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u038c\n  0x0000,0x0000,0x1c00,0x3800,0x7000,0xe000,0x380e,0x380e,0x380e,0x1c1c,0x1c1c,0x0e38,0x0e38,0x0770,0x0770,0x03e0,\n  0x03e0,0x01c0,0x01c0,0x01c0,0x01c0,0x01c0,0x01c0,0x01c0,0x01c0,0x01c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u038e\n  0x0000,0x0000,0x1c00,0x3800,0x7000,0xe000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x3838,0x1c70,0x1c70,0x1c70,0x7c7c,0x7c7c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u038f\n  0x0000,0x00e0,0x01c0,0x0380,0x0700,0x0000,0x38e0,0x38e0,0x38e0,0x38e0,0x0000,0x0000,0x1f00,0x1f00,0x0700,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0780,0x03f0,0x01f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0390\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0391\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,0x701c,0x701c,0x701c,0x7038,0x7ff0,0x7ff0,\n  0x7038,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,0x7ff8,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0392\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0393\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x07c0,0x07c0,0x07c0,0x0ee0,0x0ee0,0x0ee0,0x1c70,\n  0x1c70,0x1c70,0x3838,0x3838,0x3838,0x701c,0x701c,0x701c,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0394\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7fe0,\n  0x7fe0,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0395\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x001c,0x001c,0x001c,0x0038,0x0070,0x00e0,0x01c0,0x0380,\n  0x0700,0x0e00,0x1c00,0x3800,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0396\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x7ffc,\n  0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0397\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x77dc,\n  0x77dc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0398\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x0fe0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0399\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x700c,0x701c,0x7038,0x7070,0x70e0,0x71c0,0x7380,0x7700,0x7e00,0x7c00,\n  0x7c00,0x7e00,0x7700,0x7380,0x71c0,0x70e0,0x7070,0x7038,0x701c,0x700c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u039a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x07c0,0x07c0,0x07c0,0x0ee0,0x0ee0,0x0ee0,0x1c70,\n  0x1c70,0x1c70,0x3838,0x3838,0x3838,0x3838,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u039b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x700e,0x700e,0x781e,0x7c3e,0x7e7e,0x7e7e,0x77ee,0x73ce,0x73ce,0x718e,\n  0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u039c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x7c1c,0x7e1c,0x771c,0x739c,\n  0x71dc,0x70fc,0x707c,0x703c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u039d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,\n  0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u039e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u039f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,\n  0x7ff8,0x7ff0,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x7000,0x3800,0x1c00,0x0e00,0x0700,0x0380,0x01c0,0x00e0,\n  0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x3838,0x3838,0x1c70,0x1c70,0x0ee0,0x0ee0,0x07c0,\n  0x07c0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x1ff0,0x3ff8,0x7bbc,0x739c,0x739c,0x739c,0x739c,0x739c,\n  0x739c,0x739c,0x739c,0x739c,0x739c,0x7bbc,0x3ff8,0x1ff0,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x3838,0x3838,0x1c70,0x1c70,0x0ee0,0x0ee0,0x07c0,0x07c0,\n  0x07c0,0x07c0,0x0ee0,0x0ee0,0x1c70,0x1c70,0x3838,0x3838,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,\n  0x739c,0x739c,0x739c,0x7bbc,0x3ff8,0x1ff0,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x3838,0x1c70,0x1c70,0x1c70,0x7c7c,0x7c7c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03a9\n  0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0fe0,0x0fe0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03aa\n  0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x701c,0x701c,0x701c,0x3838,0x3838,0x1c70,0x1c70,0x0ee0,0x0ee0,0x07c0,\n  0x07c0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ab\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x1fee,0x3ffe,0x783c,0x7038,\n  0x7038,0x7038,0x7038,0x7038,0x7038,0x7038,0x7038,0x783c,0x3ffe,0x1fee,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ac\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x7000,0x7800,0x3fc0,0x3fc0,0x7800,0x7000,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ad\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x001c,0x001c,0x001c,0x001c,0x001c,0x0000, // u03ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00e0,0x01c0,0x0380,0x0700,0x0000,0x0000,0x1f00,0x1f00,0x0700,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0780,0x03f0,0x01f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03af\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fee,0x3ffe,0x783c,0x7038,\n  0x7038,0x7038,0x7038,0x7038,0x7038,0x7038,0x7038,0x783c,0x3ffe,0x1fee,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fe0,0x7ff0,0x7078,0x7038,0x7038,0x7038,0x7038,0x7070,0x7ff0,0x7ff0,\n  0x7038,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,0x7ff8,0x7ff0,0x7000,0x7000,0x7000,0x7000,0x7000,0x0000, // u03b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x3838,\n  0x3838,0x3838,0x1c70,0x1c70,0x0ee0,0x0ee0,0x07c0,0x07c0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000, // u03b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x1ff0,0x0e00,0x0700,0x0380,0x01c0,0x0fe0,0x1ff0,0x3838,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x7000,0x7800,0x3fc0,0x3fc0,0x7800,0x7000,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x0038,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,\n  0x3800,0x3800,0x7000,0x7000,0x7000,0x7000,0x7000,0x7800,0x3ff0,0x1ff8,0x003c,0x001c,0x001c,0x0078,0x0070,0x0000, // u03b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x001c,0x001c,0x001c,0x001c,0x001c,0x0000, // u03b7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x1ff0,0x3c78,0x3838,0x3838,0x3838,0x3838,0x3838,0x3838,0x3ff8,\n  0x3ff8,0x3838,0x3838,0x3838,0x3838,0x3838,0x3838,0x3c78,0x1ff0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x1f00,0x0700,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0780,0x03f0,0x01f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03b9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x381c,0x3838,0x3870,0x38e0,\n  0x39c0,0x3b80,0x3f00,0x3f00,0x3b80,0x39c0,0x38e0,0x3870,0x3838,0x381c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x0e00,0x0700,0x0700,0x0380,0x0380,0x07c0,0x07c0,0x0ee0,0x0ee0,\n  0x0ee0,0x1c70,0x1c70,0x1c70,0x3838,0x3838,0x3838,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,0x707c,0x70fc,0x7fdc,0x7f9c,0x7000,0x7000,0x7000,0x7000,0x7000,0x0000, // u03bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x3838,\n  0x3838,0x3838,0x1c70,0x1c70,0x1c70,0x0ee0,0x0ee0,0x07c0,0x07c0,0x07c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03bd\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ffc,0x3ffc,0x7800,0x7000,0x7000,0x7000,0x7000,0x3800,0x1ff0,0x1ff0,\n  0x3800,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7800,0x3ff0,0x1ff8,0x003c,0x001c,0x001c,0x0078,0x0070,0x0000, // u03be\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,0x7ff8,0x7ff0,0x7000,0x7000,0x7000,0x7000,0x7000,0x0000, // u03c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7800,0x3ff0,0x1ff8,0x003c,0x001c,0x001c,0x0078,0x0070,0x0000, // u03c2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ffe,0x3ffe,0x78f0,0x7078,\n  0x703c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x03c0,0x01f8,0x00f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x19f0,0x3bf8,0x7bbc,0x739c,\n  0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x7bbc,0x3ff8,0x1ff0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000, // u03c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x3838,0x3838,\n  0x1c70,0x1c70,0x0ee0,0x0ee0,0x07c0,0x07c0,0x07c0,0x0ee0,0x0ee0,0x1c70,0x1c70,0x3838,0x3838,0x701c,0x701c,0x0000, // u03c7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x739c,0x739c,0x739c,0x739c,\n  0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x7bbc,0x3ff8,0x1ff0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000, // u03c8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x701c,0x701c,\n  0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x77dc,0x3ff8,0x1ef0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03c9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x38e0,0x38e0,0x38e0,0x38e0,0x0000,0x0000,0x1f00,0x1f00,0x0700,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0780,0x03f0,0x01f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ca\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03cc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03cd\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x3838,0x3838,0x701c,0x701c,\n  0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x77dc,0x3ff8,0x1ef0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03ce\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x1ff0,0x3c78,0x3838,0x3838,0x3838,0x3838,0x1ffe,0x0ffe,0x0038,\n  0x0038,0x0038,0xf838,0xf838,0x3838,0x3838,0x3838,0x3c78,0x1ff0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x1ff0,0x3ff8,0x7bbc,0x739c,\n  0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x7bbc,0x3ff8,0x1ff0,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000, // u03d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7c0c,0x7e1c,0x0738,0x0770,\n  0x03e0,0x03c0,0x0380,0x0380,0x0780,0x0f80,0x1dc0,0x39c0,0x70fc,0x607c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,0x7ff8,0x7ff0,0x7000,0x7000,0x7800,0x3ff8,0x1ff8,0x0000, // u03f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x00f8,0x00f8,0x0038,0x0038,\n  0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x3838,0x3838,0x3c78,0x1ff0,0x0fe0,0x0000, // u03f3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x7ffc,\n  0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07fc,0x1ffc,0x3c00,0x3800,\n  0x7000,0x7000,0x7ff0,0x7ff0,0x7000,0x7000,0x3800,0x3c00,0x1ffc,0x07fc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7ff0,0x0078,0x0038,\n  0x001c,0x001c,0x1ffc,0x1ffc,0x001c,0x001c,0x0038,0x0078,0x7ff0,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u03f6\n  0x0000,0x1c00,0x0e00,0x0700,0x0380,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7fe0,\n  0x7fe0,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0400\n  0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7fe0,\n  0x7fe0,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0401\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,0xff80,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1ff8,0x1ffc,0x1c1e,\n  0x1c0e,0x1c0e,0x1c0e,0x1c0e,0x1c0e,0x1c0e,0x1c0e,0x1c1e,0x1c7c,0x1c78,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0402\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0403\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x7000,0x7000,0x7000,0x7000,0x7fe0,\n  0x7fe0,0x7000,0x7000,0x7000,0x7000,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0404\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x7000,0x7000,0x7000,0x7800,0x3ff0,\n  0x1ff8,0x003c,0x001c,0x001c,0x001c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0405\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x0fe0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0406\n  0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0fe0,0x0fe0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0407\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00fe,0x00fe,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,\n  0x0038,0x0038,0x0038,0x0038,0x7038,0x7038,0x7038,0x7878,0x3ff0,0x1fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0408\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x3f80,0x7b80,0x7380,0x7380,0x7380,0x7380,0x73f8,0x73fc,0x739e,\n  0x738e,0x738e,0x738e,0x738e,0x738e,0x738e,0x738e,0x739e,0xf3fc,0xe3f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0409\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xe380,0xe380,0xe380,0xe380,0xe380,0xe380,0xe380,0xe3f8,0xe3fc,0xff9e,\n  0xff8e,0xe38e,0xe38e,0xe38e,0xe38e,0xe38e,0xe38e,0xe39e,0xe3fc,0xe3f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u040a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,0xff80,0x1c00,0x1c00,0x1c00,0x1c00,0x1c00,0x1ff8,0x1ffc,0x1c1e,\n  0x1c0e,0x1c0e,0x1c0e,0x1c0e,0x1c0e,0x1c0e,0x1c0e,0x1c0e,0x1c0e,0x1c0e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u040b\n  0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x700c,0x701c,0x7038,0x7070,0x70e0,0x71c0,0x7380,0x7700,0x7e00,0x7c00,\n  0x7c00,0x7e00,0x7700,0x7380,0x71c0,0x70e0,0x7070,0x7038,0x701c,0x700c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u040c\n  0x0000,0x1c00,0x0e00,0x0700,0x0380,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,0x707c,0x70fc,0x71dc,\n  0x739c,0x771c,0x7e1c,0x7c1c,0x781c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u040d\n  0x0000,0x1c70,0x1c70,0x0fe0,0x07c0,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,\n  0x3ffc,0x1ffc,0x001c,0x001c,0x001c,0x001c,0x001c,0x003c,0x3ff8,0x3ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u040e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x7ffc,0x7ffc,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000, // u040f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0410\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff8,0x7ff8,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ff0,0x7ff8,0x703c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,0x7ff8,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0411\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,0x701c,0x701c,0x701c,0x7038,0x7ff0,0x7ff0,\n  0x7038,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,0x7ff8,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0412\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0413\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff8,0x1ff8,0x3c38,0x3838,0x3838,0x3838,0x3838,0x3838,0x3838,0x3838,\n  0x3838,0x3838,0x3838,0x3838,0x3838,0x3838,0x3838,0x3838,0x7ffc,0xfffe,0xe00e,0xe00e,0xe00e,0xe00e,0x0000,0x0000, // u0414\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7fe0,\n  0x7fe0,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0415\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x3bb8,0x1ff0,0x0fe0,\n  0x0fe0,0x1ff0,0x3bb8,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0416\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x001c,0x001c,0x001c,0x003c,0x0ff8,\n  0x0ff8,0x003c,0x001c,0x001c,0x001c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0417\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,0x707c,0x70fc,0x71dc,\n  0x739c,0x771c,0x7e1c,0x7c1c,0x781c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0418\n  0x0000,0x1c70,0x1c70,0x0fe0,0x07c0,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,0x707c,0x70fc,0x71dc,\n  0x739c,0x771c,0x7e1c,0x7c1c,0x781c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0419\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x700c,0x701c,0x7038,0x7070,0x70e0,0x71c0,0x7380,0x7700,0x7e00,0x7c00,\n  0x7c00,0x7e00,0x7700,0x7380,0x71c0,0x70e0,0x7070,0x7038,0x701c,0x700c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u041a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07fc,0x0ffc,0x1e1c,0x1c1c,0x1c1c,0x1c1c,0x1c1c,0x1c1c,0x1c1c,0x1c1c,\n  0x1c1c,0x1c1c,0x1c1c,0x1c1c,0x1c1c,0x1c1c,0x1c1c,0x1c1c,0x381c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u041b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x700e,0x700e,0x781e,0x7c3e,0x7e7e,0x7e7e,0x77ee,0x73ce,0x73ce,0x718e,\n  0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u041c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x7ffc,\n  0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u041d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u041e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u041f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,\n  0x7ff8,0x7ff0,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0420\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x7000,0x7000,0x7000,0x7000,0x7000,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0421\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0422\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,\n  0x3ffc,0x1ffc,0x001c,0x001c,0x001c,0x001c,0x001c,0x003c,0x3ff8,0x3ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0423\n  0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x1ff0,0x3ff8,0x7bbc,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,\n  0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x7bbc,0x3ff8,0x1ff0,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000, // u0424\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x3838,0x3838,0x1c70,0x1c70,0x0ee0,0x0ee0,0x07c0,0x07c0,\n  0x07c0,0x07c0,0x0ee0,0x0ee0,0x1c70,0x1c70,0x3838,0x3838,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0425\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781e,0x3fff,0x1fff,0x0007,0x0007,0x0007,0x0007,0x0007,0x0000, // u0426\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,\n  0x3ffc,0x1ffc,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0427\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,\n  0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x7b9c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0428\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,\n  0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x7b9c,0x3ffe,0x1fff,0x0007,0x0007,0x0007,0x0007,0x0007,0x0000, // u0429\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf800,0xf800,0x3800,0x3800,0x3800,0x3800,0x3ff0,0x3ff8,0x383c,0x381c,\n  0x381c,0x381c,0x381c,0x381c,0x381c,0x381c,0x381c,0x383c,0x3ff8,0x3ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u042a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x7f0e,0x7f8e,0x73ce,0x71ce,\n  0x71ce,0x71ce,0x71ce,0x71ce,0x71ce,0x71ce,0x71ce,0x73ce,0x7f8e,0x7f0e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u042b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3ff0,0x3ff8,0x383c,0x381c,\n  0x381c,0x381c,0x381c,0x381c,0x381c,0x381c,0x381c,0x383c,0x3ff8,0x3ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u042c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x001c,0x001c,0x001c,0x001c,0x0ffc,\n  0x0ffc,0x001c,0x001c,0x001c,0x001c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u042d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x70f8,0x71fc,0x738e,0x738e,0x738e,0x738e,0x738e,0x738e,0x738e,0x7f8e,\n  0x7f8e,0x738e,0x738e,0x738e,0x738e,0x738e,0x738e,0x738e,0x71fc,0x70f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u042e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ffc,0x3ffc,0x781c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,\n  0x3ffc,0x1ffc,0x00fc,0x01dc,0x039c,0x071c,0x0e1c,0x1c1c,0x381c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u042f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x003c,0x001c,\n  0x001c,0x1ffc,0x3ffc,0x781c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0430\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff0,0x7800,0x7000,0x7000,0x7000,0x7000,0x7ff0,0x7ff8,0x703c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,0x7ff8,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0431\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3fc0,0x7fe0,0x70f0,0x7070,0x7070,0x7070,0x7070,0x70e0,0x7fe0,0x7ff0,\n  0x7038,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,0x7ff8,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0432\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0433\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ffc,0x3ffc,0x781c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x001c,0x001c,0x003c,0x3ff8,0x3ff0,0x0000, // u0434\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x781c,0x3ffc,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0435\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x739c,0x739c,0x739c,0x739c,\n  0x3bb8,0x1ff0,0x0fe0,0x1ff0,0x3bb8,0x739c,0x739c,0x739c,0x739c,0x739c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0436\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x001c,0x003c,0x07f8,0x07f8,0x003c,0x001c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0437\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0438\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x0fe0,0x07c0,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0439\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x381c,0x3838,0x3870,0x38e0,\n  0x39c0,0x3b80,0x3f00,0x3f00,0x3b80,0x39c0,0x38e0,0x3870,0x3838,0x381c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u043a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07fc,0x0ffc,0x1e1c,0x1c1c,\n  0x1c1c,0x1c1c,0x1c1c,0x1c1c,0x1c1c,0x1c1c,0x1c1c,0x1c1c,0x381c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u043b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6006,0x700e,0x781e,0x7c3e,\n  0x7e7e,0x77ee,0x73ce,0x718e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u043c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u043d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u043e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u043f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,0x7ff8,0x7ff0,0x7000,0x7000,0x7000,0x7000,0x7000,0x0000, // u0440\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0441\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0442\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x001c,0x001c,0x003c,0x3ff8,0x3ff0,0x0000, // u0443\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x1ff0,0x3ff8,0x7bbc,0x739c,\n  0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x7bbc,0x3ff8,0x1ff0,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000, // u0444\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x3838,\n  0x1c70,0x0ee0,0x07c0,0x07c0,0x0ee0,0x1c70,0x3838,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0445\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffe,0x1fff,0x0007,0x0007,0x0007,0x0007,0x0007,0x0000, // u0446\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x781c,0x3ffc,0x1ffc,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0447\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x739c,0x739c,0x739c,0x739c,\n  0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x7b9c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0448\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x739c,0x739c,0x739c,0x739c,\n  0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x7b9c,0x3ffe,0x1fff,0x0007,0x0007,0x0007,0x0007,0x0007,0x0000, // u0449\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7c00,0x7c00,0x1c00,0x1c00,\n  0x1ff0,0x1ff8,0x1c3c,0x1c1c,0x1c1c,0x1c1c,0x1c1c,0x1c3c,0x1ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u044a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x700e,0x700e,0x700e,0x700e,\n  0x7f0e,0x7f8e,0x73ce,0x71ce,0x71ce,0x71ce,0x71ce,0x73ce,0x7f8e,0x7f0e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u044b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,\n  0x3fe0,0x3ff0,0x3878,0x3838,0x3838,0x3838,0x3838,0x3878,0x3ff0,0x3fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u044c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x001c,0x001c,0x07fc,0x07fc,0x001c,0x001c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u044d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x70f8,0x71fc,0x738e,0x738e,\n  0x738e,0x738e,0x7f8e,0x7f8e,0x738e,0x738e,0x738e,0x738e,0x71fc,0x70f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u044e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ffc,0x3ffc,0x781c,0x701c,\n  0x701c,0x781c,0x3ffc,0x1ffc,0x01dc,0x039c,0x071c,0x0e1c,0x1c1c,0x381c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u044f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0e00,0x0700,0x0380,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x781c,0x3ffc,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0450\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x781c,0x3ffc,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0451\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0xffc0,0xffc0,0x3800,0x3800,0x3ff8,0x3ffc,0x381e,0x380e,\n  0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x000e,0x000e,0x001e,0x00fc,0x00f8,0x0000, // u0452\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0453\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x7000,0x7000,0x7fc0,0x7fc0,0x7000,0x7000,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0454\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x7000,\n  0x7000,0x7800,0x3ff0,0x1ff8,0x003c,0x001c,0x001c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0455\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0f80,0x0f80,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0456\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x0f80,0x0f80,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0457\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x00f8,0x00f8,0x0038,0x0038,\n  0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x3838,0x3838,0x3c78,0x1ff0,0x0fe0,0x0000, // u0458\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f80,0x3f80,0x7b80,0x7380,\n  0x73f8,0x73fc,0x739e,0x738e,0x738e,0x738e,0x738e,0x739e,0xf3fc,0xe3f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0459\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xe380,0xe380,0xe380,0xe380,\n  0xe3f8,0xe3fc,0xff9e,0xff8e,0xe38e,0xe38e,0xe38e,0xe39e,0xe3fc,0xe3f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u045a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0xffc0,0xffc0,0x3800,0x3800,0x3ff8,0x3ffc,0x381e,0x380e,\n  0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u045b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,0x0000,0x0000,0x381c,0x3838,0x3870,0x38e0,\n  0x39c0,0x3b80,0x3f00,0x3f00,0x3b80,0x39c0,0x38e0,0x3870,0x3838,0x381c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u045c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0e00,0x0700,0x0380,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u045d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x0fe0,0x07c0,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x001c,0x001c,0x003c,0x3ff8,0x3ff0,0x0000, // u045e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x7ffc,0x7ffc,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000, // u045f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0xff80,0xff80,0x3800,0x3800,0x3ff0,0x3ff8,0x383c,0x381c,\n  0x381c,0x381c,0x381c,0x381c,0x381c,0x381c,0x381c,0x383c,0x3ff8,0x3ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0462\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x1c00,0x1c00,0x1c00,0x7fc0,0x7fc0,0x1c00,0x1c00,0x1c00,0x1c00,\n  0x1ff0,0x1ff8,0x1c3c,0x1c1c,0x1c1c,0x1c1c,0x1c1c,0x1c3c,0x1ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0463\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x701c,0x3838,0x3838,0x1c70,0x1c70,0x0ee0,0x0fe0,0x07c0,\n  0x0fe0,0x1ff0,0x3bb8,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u046a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x701c,0x3838,\n  0x1c70,0x0ee0,0x0fe0,0x1ff0,0x3bb8,0x739c,0x739c,0x739c,0x739c,0x739c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u046b\n  0x0000,0x0000,0x001c,0x001c,0x001c,0x001c,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0490\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x001c,0x001c,0x001c,0x001c,0x7ffc,0x7ffc,0x7000,0x7000,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0491\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0xff80,\n  0xff80,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0492\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,\n  0x7000,0x7000,0xff80,0xff80,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0493\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,\n  0x7ff0,0x7ff8,0x703c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x001c,0x001c,0x0038,0x0070,0x0000,0x0000, // u0494\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,\n  0x7000,0x7000,0x7000,0x7fc0,0x7fe0,0x70f0,0x7070,0x7070,0x7070,0x7070,0x0070,0x0070,0x00e0,0x01c0,0x0000,0x0000, // u0495\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x3bb8,0x1ff0,0x0fe0,\n  0x0fe0,0x1ff0,0x3bb8,0x739c,0x739c,0x739c,0x739c,0x739c,0x739e,0x739f,0x0007,0x0007,0x0007,0x0007,0x0007,0x0000, // u0496\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x739c,0x739c,0x739c,0x739c,\n  0x3bb8,0x1ff0,0x0fe0,0x1ff0,0x3bb8,0x739c,0x739c,0x739c,0x739e,0x739f,0x0007,0x0007,0x0007,0x0007,0x0007,0x0000, // u0497\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x001c,0x001c,0x001c,0x003c,0x0ff8,\n  0x0ff8,0x003c,0x001c,0x001c,0x001c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000, // u0498\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x001c,0x003c,0x07f8,0x07f8,0x003c,0x001c,0x701c,0x783c,0x3ff8,0x1ff0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000, // u0499\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x700c,0x701c,0x7038,0x7070,0x70e0,0x71c0,0x7380,0x7700,0x7e00,0x7c00,\n  0x7c00,0x7e00,0x7700,0x7380,0x71c0,0x70e0,0x7070,0x7038,0x701c,0x700e,0x0007,0x0007,0x0007,0x0007,0x0007,0x0000, // u049a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x381c,0x3838,0x3870,0x38e0,\n  0x39c0,0x3b80,0x3f00,0x3f00,0x3b80,0x39c0,0x38e0,0x3870,0x3838,0x381c,0x000e,0x000e,0x000e,0x000e,0x000e,0x0000, // u049b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x700e,0x700e,0x700e,0x701c,0x7638,0x7670,0x76e0,0x77c0,0x7780,0x7f00,\n  0x7f00,0x7780,0x77c0,0x76e0,0x7670,0x7638,0x701c,0x700e,0x700e,0x700e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u049c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x700e,0x701c,0x7638,0x7670,\n  0x76e0,0x77c0,0x7f80,0x7f80,0x77c0,0x76e0,0x7670,0x7638,0x701c,0x700e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u049d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf806,0xf80e,0x381c,0x3838,0x3870,0x38e0,0x39c0,0x3b80,0x3f00,0x3e00,\n  0x3e00,0x3f00,0x3b80,0x39c0,0x38e0,0x3870,0x3838,0x381c,0x380e,0x3806,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf81c,0xf838,0x3870,0x38e0,\n  0x39c0,0x3b80,0x3f00,0x3f00,0x3b80,0x39c0,0x38e0,0x3870,0x3838,0x381c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x7ffc,\n  0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701e,0x701f,0x0007,0x0007,0x0007,0x0007,0x0007,0x0000, // u04a2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701e,0x701f,0x0007,0x0007,0x0007,0x0007,0x0007,0x0000, // u04a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xe0ff,0xe0ff,0xe0e0,0xe0e0,0xe0e0,0xe0e0,0xe0e0,0xe0e0,0xe0e0,0xffe0,\n  0xffe0,0xe0e0,0xe0e0,0xe0e0,0xe0e0,0xe0e0,0xe0e0,0xe0e0,0xe0e0,0xe0e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xe0ff,0xe0ff,0xe0e0,0xe0e0,\n  0xe0e0,0xe0e0,0xffe0,0xffe0,0xe0e0,0xe0e0,0xe0e0,0xe0e0,0xe0e0,0xe0e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04a5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x7000,0x7000,0x7000,0x7000,0x7000,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000, // u04aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x701c,0x783c,0x3ff8,0x1ff0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000, // u04ab\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x3838,0x3838,0x1c70,0x1c70,0x0ee0,0x0ee0,0x07c0,\n  0x07c0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x3838,\n  0x3838,0x3838,0x1c70,0x1c70,0x0ee0,0x0ee0,0x07c0,0x07c0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000, // u04af\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x3838,0x3838,0x1c70,0x1c70,0x0ee0,0x0ee0,0x07c0,\n  0x07c0,0x0380,0x3ff8,0x3ff8,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04b0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x3838,\n  0x3838,0x3838,0x1c70,0x1c70,0x0ee0,0x0ee0,0x07c0,0x07c0,0x0380,0x3ff8,0x3ff8,0x0380,0x0380,0x0380,0x0380,0x0000, // u04b1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x3838,0x3838,0x1c70,0x1c70,0x0ee0,0x0ee0,0x07c0,0x07c0,\n  0x07c0,0x07c0,0x0ee0,0x0ee0,0x1c70,0x1c70,0x3838,0x3838,0x701e,0x701f,0x0007,0x0007,0x0007,0x0007,0x0007,0x0000, // u04b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x3838,\n  0x1c70,0x0ee0,0x07c0,0x07c0,0x0ee0,0x1c70,0x3838,0x701c,0x701e,0x701f,0x0007,0x0007,0x0007,0x0007,0x0007,0x0000, // u04b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,\n  0x3ffc,0x1ffc,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001e,0x001f,0x0007,0x0007,0x0007,0x0007,0x0007,0x0000, // u04b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x781c,0x3ffc,0x1ffc,0x001c,0x001c,0x001c,0x001c,0x001e,0x001f,0x0007,0x0007,0x0007,0x0007,0x0007,0x0000, // u04b7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x739c,0x739c,0x739c,0x7b9c,\n  0x3ffc,0x1ffc,0x039c,0x039c,0x039c,0x039c,0x001c,0x001c,0x001c,0x001c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04b8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x739c,\n  0x739c,0x7b9c,0x3ffc,0x1ffc,0x039c,0x039c,0x039c,0x001c,0x001c,0x001c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04b9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ff0,0x7ff8,\n  0x703c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x7000,0x7000,0x7000,\n  0x7000,0x7ff0,0x7ff8,0x703c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x0fe0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04c0\n  0x0000,0x1c70,0x1c70,0x0fe0,0x07c0,0x0000,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x3bb8,0x1ff0,0x0fe0,\n  0x0fe0,0x1ff0,0x3bb8,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x0fe0,0x07c0,0x0000,0x0000,0x739c,0x739c,0x739c,0x739c,\n  0x3bb8,0x1ff0,0x0fe0,0x1ff0,0x3bb8,0x739c,0x739c,0x739c,0x739c,0x739c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04c2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f80,0x0f80,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04cf\n  0x0000,0x1c70,0x1c70,0x0fe0,0x07c0,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x0fe0,0x07c0,0x0000,0x0000,0x3ff0,0x3ff8,0x003c,0x001c,\n  0x001c,0x1ffc,0x3ffc,0x781c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d1\n  0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x3ff0,0x3ff8,0x003c,0x001c,\n  0x001c,0x1ffc,0x3ffc,0x781c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffe,0x7ffe,0xf1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xfffe,\n  0xfffe,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1fe,0xe1fe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ef8,0x7ffc,0x039e,0x038e,\n  0x038e,0x3f8e,0x7ffe,0xf3fe,0xe380,0xe380,0xe380,0xf3ce,0x7ffe,0x3efc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d5\n  0x0000,0x1c70,0x1c70,0x0fe0,0x07c0,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7fe0,\n  0x7fe0,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x0fe0,0x07c0,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x781c,0x3ffc,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x001c,0x001c,0x001c,0x001c,0x7ffc,\n  0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x7ff8,0x703c,0x001c,\n  0x001c,0x001c,0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04d9\n  0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x001c,0x001c,0x001c,0x001c,0x7ffc,\n  0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04da\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x3ff0,0x7ff8,0x703c,0x001c,\n  0x001c,0x001c,0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04db\n  0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x3bb8,0x1ff0,0x0fe0,\n  0x0fe0,0x1ff0,0x3bb8,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04dc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x739c,0x739c,0x739c,0x739c,\n  0x3bb8,0x1ff0,0x0fe0,0x1ff0,0x3bb8,0x739c,0x739c,0x739c,0x739c,0x739c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04dd\n  0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x001c,0x001c,0x001c,0x003c,0x0ff8,\n  0x0ff8,0x003c,0x001c,0x001c,0x001c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04de\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x001c,0x003c,0x07f8,0x07f8,0x003c,0x001c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04df\n  0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,0x707c,0x70fc,0x71dc,\n  0x739c,0x771c,0x7e1c,0x7c1c,0x781c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e3\n  0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,0x707c,0x70fc,0x71dc,\n  0x739c,0x771c,0x7e1c,0x7c1c,0x781c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e5\n  0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x7ffc,\n  0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04e9\n  0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x7ffc,\n  0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04eb\n  0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x001c,0x001c,0x001c,0x001c,0x0ffc,\n  0x0ffc,0x001c,0x001c,0x001c,0x001c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ec\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x001c,0x001c,0x07fc,0x07fc,0x001c,0x001c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ed\n  0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,\n  0x3ffc,0x1ffc,0x001c,0x001c,0x001c,0x001c,0x001c,0x003c,0x3ff8,0x3ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04ee\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x001c,0x001c,0x003c,0x3ff8,0x3ff0,0x0000, // u04ef\n  0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,\n  0x3ffc,0x1ffc,0x001c,0x001c,0x001c,0x001c,0x001c,0x003c,0x3ff8,0x3ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x001c,0x001c,0x003c,0x3ff8,0x3ff0,0x0000, // u04f1\n  0x0000,0x038e,0x071c,0x0e38,0x1c70,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,\n  0x3ffc,0x1ffc,0x001c,0x001c,0x001c,0x001c,0x001c,0x003c,0x3ff8,0x3ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x038e,0x071c,0x0e38,0x1c70,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x001c,0x001c,0x003c,0x3ff8,0x3ff0,0x0000, // u04f3\n  0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,\n  0x3ffc,0x1ffc,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x781c,0x3ffc,0x1ffc,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f5\n  0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x7f0e,0x7f8e,0x73ce,0x71ce,\n  0x71ce,0x71ce,0x71ce,0x71ce,0x71ce,0x71ce,0x71ce,0x73ce,0x7f8e,0x7f0e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x700e,0x700e,0x700e,0x700e,\n  0x7f0e,0x7f8e,0x73ce,0x71ce,0x71ce,0x71ce,0x71ce,0x73ce,0x7f8e,0x7f0e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u04f9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x381c,0x381c,0x1c1c,0x1c1c,0x0e1c,0x0e1c,0x0738,0x0ff0,\n  0x1fe0,0x39c0,0x70e0,0x70e0,0x7070,0x7070,0x7038,0x7038,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffe0,0xfff0,0x0078,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,\n  0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0xfffe,0xfffe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x3fc0,0x01e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,\n  0x00e0,0x00e0,0x01f0,0x03f0,0x07b8,0x0f38,0x1e1c,0x3c1c,0x780e,0xf00e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfffe,0xfffe,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,\n  0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x003c,0x001c,0x001c,0x001c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x3f00,0x0780,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff8,0x3ff8,0x00f0,0x01e0,0x03c0,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x71f0,0x71f8,0x703c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e00,0x3f00,0x0780,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05d9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x003c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,\n  0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x0000, // u05da\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x003c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,\n  0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x003c,0x7ff8,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05db\n  0x0000,0x0000,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x003c,0x0078,\n  0x00f0,0x01e0,0x03c0,0x0780,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05dc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05dd\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xe7e0,0xfff8,0x7c3c,0x381c,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,\n  0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x387e,0x387e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05de\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x3fc0,0x01e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,\n  0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x0000, // u05df\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1fc0,0x1fe0,0x00f0,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,\n  0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x1ff0,0x1ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff8,0xfffc,0x381e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,\n  0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x3c1e,0x1ffc,0x0ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x381c,0x381c,0x381c,0x1c1c,0x1c1c,0x1c1c,0x0e38,\n  0x0e38,0x0e38,0x0770,0x0770,0x0770,0x03e0,0x03c0,0x0780,0x7f00,0x7c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3f1c,\n  0x1f1c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x0000, // u05e3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3f1c,\n  0x1f1c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x003c,0x7ff8,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x381c,0x381c,0x1c1c,0x1c3c,0x0e78,0x0ef0,0x07e0,0x07c0,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000, // u05e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x381c,0x381c,0x1c1c,0x1c3c,0x0e78,0x0ef0,0x07e0,0x07c0,\n  0x0380,0x0380,0x01c0,0x01c0,0x00e0,0x00e0,0x0070,0x0070,0x7ff8,0x7ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x001c,0x001c,0x001c,0x001c,0x701c,0x701c,0x701c,0x7038,\n  0x7070,0x70e0,0x71c0,0x7380,0x7380,0x7380,0x7380,0x7380,0x7380,0x7380,0x7000,0x7000,0x7000,0x7000,0x7000,0x0000, // u05e7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x003c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,\n  0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x779c,\n  0x7f1c,0x7e1c,0x701c,0x701c,0x701c,0x701c,0x701c,0x703c,0x7ff8,0x7ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05e9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff8,0xfffc,0x381e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,\n  0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0xf80e,0xf00e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u05ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7ff0,0x7078,0x7038,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x7038,0x7078,0x7ff0,0x7fc0,0x0000,0x0700,0x0700,0x0700,0x0700,0x0000, // u1e0c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x1ffc,0x3ffc,0x781c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x01c0,0x01c0,0x01c0,0x01c0,0x0000, // u1e0d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x700c,0x701c,0x7038,0x7070,0x70e0,0x71c0,0x7380,0x7700,0x7e00,0x7c00,\n  0x7c00,0x7e00,0x7700,0x7380,0x71c0,0x70e0,0x7070,0x7038,0x701c,0x700c,0x0000,0x0000,0x1ff0,0x1ff0,0x0000,0x0000, // u1e34\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x381c,0x3838,0x3870,0x38e0,\n  0x39c0,0x3b80,0x3f00,0x3f00,0x3b80,0x39c0,0x38e0,0x3870,0x3838,0x381c,0x0000,0x0000,0x0ff0,0x0ff0,0x0000,0x0000, // u1e35\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,\n  0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000, // u1e36\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f80,0x0f80,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000, // u1e37\n  0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x700e,0x700e,0x781e,0x7c3e,0x7e7e,0x7e7e,0x77ee,0x73ce,0x73ce,0x718e,\n  0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e40\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x7ff0,0x7ff8,0x73bc,0x739c,\n  0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e41\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x700e,0x700e,0x781e,0x7c3e,0x7e7e,0x7e7e,0x77ee,0x73ce,0x73ce,0x718e,\n  0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000, // u1e42\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x73bc,0x739c,\n  0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000, // u1e43\n  0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x7c1c,0x7e1c,0x771c,0x739c,\n  0x71dc,0x70fc,0x707c,0x703c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e44\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1e45\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x7c1c,0x7e1c,0x771c,0x739c,\n  0x71dc,0x70fc,0x707c,0x703c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000, // u1e46\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x703c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000, // u1e47\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000, // u1e6c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x7ff0,0x7ff0,0x0700,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0780,0x03fc,0x01fc,0x0000,0x0070,0x0070,0x0070,0x0070,0x0000, // u1e6d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7fe0,\n  0x7fe0,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000, // u1eb8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x781c,0x3ffc,0x1ff8,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000, // u1eb9\n  0x0000,0x1f38,0x3bb8,0x3bb8,0x39f0,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7fe0,\n  0x7fe0,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1ebc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f38,0x3bb8,0x3bb8,0x39f0,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x7ffc,0x7ffc,0x7000,0x7000,0x7000,0x781c,0x3ffc,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1ebd\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x0fe0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000, // u1eca\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0f80,0x0f80,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000, // u1ecb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000, // u1ecc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000, // u1ecd\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,0x1ff0,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000, // u1ee4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x0000,0x01c0,0x01c0,0x01c0,0x01c0,0x0000, // u1ee5\n  0x0000,0x1f38,0x3bb8,0x3bb8,0x39f0,0x0000,0x701c,0x701c,0x701c,0x3838,0x3838,0x1c70,0x1c70,0x0ee0,0x0ee0,0x07c0,\n  0x07c0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u1ef8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f38,0x3bb8,0x3bb8,0x39f0,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x781c,0x3ffc,0x1ffc,0x001c,0x001c,0x003c,0x3ff8,0x3ff0,0x0000, // u1ef9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2000\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2001\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2002\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2003\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2004\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2005\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2006\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2007\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2008\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2009\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u200f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff8,\n  0x3ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2010\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff8,\n  0x3ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2011\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,\n  0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2012\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,\n  0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2013\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffe,\n  0x7ffe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2014\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffe,\n  0x7ffe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2015\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,\n  0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2016\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x0000,0x0000,0x7ffc,0x7ffc, // u2017\n  0x0000,0x0000,0x0000,0x0000,0x01c0,0x01c0,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2018\n  0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0700,0x0700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2019\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0700,0x0700,0x0000,0x0000,0x0000,0x0000, // u201a\n  0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x01c0,0x01c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201b\n  0x0000,0x0000,0x0000,0x0000,0x0e38,0x0e38,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201c\n  0x0000,0x0000,0x0000,0x0000,0x0e38,0x0e38,0x0e38,0x0e38,0x1c70,0x1c70,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x38e0,0x38e0,0x0000,0x0000,0x0000,0x0000, // u201e\n  0x0000,0x0000,0x0000,0x0000,0x38e0,0x38e0,0x38e0,0x38e0,0x1c70,0x1c70,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u201f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x3ff8,0x3ff8,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2020\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x3ff8,0x3ff8,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x3ff8,0x3ff8,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2021\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03c0,0x07e0,0x0ff0,0x0ff0,\n  0x0ff0,0x0ff0,0x07e0,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2022\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x739c,0x739c,0x739c,0x739c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2026\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3870,0x7c70,0x6ce0,0x6ce0,0x7dc0,0x39c0,0x0380,0x0380,0x0700,0x0700,\n  0x0e00,0x0e00,0x1c00,0x1c00,0x39dc,0x3bfe,0x7376,0x7376,0xe3fe,0xe1dc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2030\n  0x0000,0x0000,0x0000,0x0000,0x03c0,0x03c0,0x03c0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2032\n  0x0000,0x0000,0x0000,0x0000,0x1e78,0x1e78,0x1e78,0x1c70,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2033\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x00e0,0x01c0,0x0380,\n  0x0700,0x0e00,0x1c00,0x1c00,0x0e00,0x0700,0x0380,0x01c0,0x00e0,0x0070,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0e00,0x0700,0x0380,\n  0x01c0,0x00e0,0x0070,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u203a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x1c70,0x1c70,0x1c70,0x1c70,0x1c70,0x1c70,\n  0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x0000,0x1c70,0x1c70,0x1c70,0x1c70,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u203c\n  0x0000,0x0000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u203e\n  0x0000,0x0000,0x0000,0x07c0,0x0fe0,0x1c70,0x1c70,0x1c70,0x1c70,0x1c70,0x1c70,0x1c70,0x0fe0,0x07c0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2070\n  0x01c0,0x01c0,0x01c0,0x0000,0x07c0,0x07c0,0x01c0,0x01c0,0x01c0,0x01c0,0x01c0,0x01c0,0x07f0,0x07f0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2071\n  0x0000,0x0000,0x0000,0x0030,0x0070,0x00f0,0x01f0,0x03f0,0x0770,0x0e70,0x1ff0,0x1ff0,0x0070,0x0070,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2074\n  0x0000,0x0000,0x0000,0x1fe0,0x1fe0,0x1c00,0x1c00,0x1fe0,0x1ff0,0x0070,0x0070,0x1c70,0x1ff0,0x0fe0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2075\n  0x0000,0x0000,0x0000,0x07e0,0x0fe0,0x1c00,0x1c00,0x1fe0,0x1ff0,0x1c70,0x1c70,0x1c70,0x1ff0,0x0fe0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2076\n  0x0000,0x0000,0x0000,0x1ff0,0x1ff0,0x1c70,0x0070,0x00e0,0x00e0,0x01c0,0x01c0,0x0380,0x0380,0x0380,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2077\n  0x0000,0x0000,0x0000,0x0fe0,0x1ff0,0x1c70,0x1c70,0x1ff0,0x0fe0,0x1c70,0x1c70,0x1c70,0x1ff0,0x0fe0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2078\n  0x0000,0x0000,0x0000,0x0fe0,0x1ff0,0x1c70,0x1c70,0x1c70,0x1ff0,0x0ff0,0x0070,0x0070,0x0fe0,0x0fc0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2079\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x1ff0,0x1ff0,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff8,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff8,0x1ff8,0x0000,0x0000,0x0000,0x1ff8,0x1ff8,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207c\n  0x0000,0x0000,0x0000,0x01c0,0x0380,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0380,0x01c0,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207d\n  0x0000,0x0000,0x0000,0x0700,0x0380,0x01c0,0x01c0,0x01c0,0x01c0,0x01c0,0x01c0,0x01c0,0x0380,0x0700,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207e\n  0x0000,0x0000,0x0000,0x0000,0x1fe0,0x1ff0,0x1c38,0x1c38,0x1c38,0x1c38,0x1c38,0x1c38,0x1c38,0x1c38,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u207f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x07c0,0x0fe0,0x1c70,0x1c70,0x1c70,0x1c70,0x1c70,0x1c70,0x1c70,0x0fe0,0x07c0,0x0000,0x0000,0x0000, // u2080\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0380,0x0780,0x0f80,0x0f80,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000, // u2081\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0fe0,0x1ff0,0x1c70,0x1c70,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1ff0,0x1ff0,0x0000,0x0000,0x0000, // u2082\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0fe0,0x1ff0,0x1c70,0x0070,0x03e0,0x03e0,0x0070,0x0070,0x1c70,0x1ff0,0x0fe0,0x0000,0x0000,0x0000, // u2083\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0030,0x0070,0x00f0,0x01f0,0x03f0,0x0770,0x0e70,0x1ff0,0x1ff0,0x0070,0x0070,0x0000,0x0000,0x0000, // u2084\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1fe0,0x1fe0,0x1c00,0x1c00,0x1fe0,0x1ff0,0x0070,0x0070,0x1c70,0x1ff0,0x0fe0,0x0000,0x0000,0x0000, // u2085\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x07e0,0x0fe0,0x1c00,0x1c00,0x1fe0,0x1ff0,0x1c70,0x1c70,0x1c70,0x1ff0,0x0fe0,0x0000,0x0000,0x0000, // u2086\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x1ff0,0x1ff0,0x1c70,0x0070,0x00e0,0x00e0,0x01c0,0x01c0,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000, // u2087\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0fe0,0x1ff0,0x1c70,0x1c70,0x1ff0,0x0fe0,0x1c70,0x1c70,0x1c70,0x1ff0,0x0fe0,0x0000,0x0000,0x0000, // u2088\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0fe0,0x1ff0,0x1c70,0x1c70,0x1c70,0x1ff0,0x0ff0,0x0070,0x0070,0x0fe0,0x0fc0,0x0000,0x0000,0x0000, // u2089\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x1ff0,0x1ff0,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000, // u208a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff8,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u208b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x1ff8,0x1ff8,0x0000,0x0000,0x0000,0x1ff8,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000, // u208c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x01c0,0x0380,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0380,0x01c0,0x0000,0x0000,0x0000, // u208d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0700,0x0380,0x01c0,0x01c0,0x01c0,0x01c0,0x01c0,0x01c0,0x01c0,0x0380,0x0700,0x0000,0x0000,0x0000, // u208e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0fe0,0x0ff0,0x0038,0x0038,0x0ff8,0x1ff8,0x1c38,0x1c38,0x1ff8,0x0ff8,0x0000,0x0000,0x0000, // u2090\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x07e0,0x0ff0,0x1c38,0x1c38,0x1ff8,0x1ff8,0x1c00,0x1c00,0x0ff8,0x07f0,0x0000,0x0000,0x0000, // u2091\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x07e0,0x0ff0,0x1c38,0x1c38,0x1c38,0x1c38,0x1c38,0x1c38,0x0ff0,0x07e0,0x0000,0x0000,0x0000, // u2092\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x1c38,0x1c38,0x0e70,0x07e0,0x03c0,0x03c0,0x07e0,0x0e70,0x1c38,0x1c38,0x0000,0x0000,0x0000, // u2093\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0fe0,0x1ff0,0x0038,0x0038,0x1ff8,0x1ff8,0x1c38,0x1c38,0x0ff0,0x07e0,0x0000,0x0000,0x0000, // u2094\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1fe0,0x1ff0,0x1c38,0x1c38,0x1c38,0x1c38,0x1c38,0x1c38,0x1c38,0x1c38,0x0000,0x0000,0x0000, // u2095\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,\n  0x1c00,0x1c00,0x1c00,0x1c38,0x1c70,0x1ce0,0x1dc0,0x1f80,0x1f80,0x1dc0,0x1ce0,0x1c70,0x1c38,0x0000,0x0000,0x0000, // u2096\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0f80,\n  0x0f80,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000, // u2097\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x7ff0,0x7ff8,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x739c,0x0000,0x0000,0x0000, // u2098\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x1fe0,0x1ff0,0x1c38,0x1c38,0x1c38,0x1c38,0x1c38,0x1c38,0x1ff0,0x1fe0,0x1c00,0x1c00,0x1c00, // u209a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff00,0xff80,0xe3c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe1c0,0xe3c0,0xfff0,\n  0xff70,0xe070,0xe3fe,0xe3fe,0xe070,0xe070,0xe070,0xe070,0xe07e,0xe03e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u20a7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f86,0x7fc6,0x60e6,0x6066,0x6066,0x6066,0x6666,0x6666,0x6666,0x6666,\n  0x6666,0x6666,0x6666,0x6666,0x6606,0x6606,0x6606,0x660e,0x67fc,0x67f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u20aa\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03f0,0x07f8,0x0e1c,0x1c0e,0x3800,0x3800,0x3800,0xffe0,0xffe0,0x3800,\n  0x3800,0xffe0,0xffe0,0x3800,0x3800,0x3800,0x1c0e,0x0e1c,0x07f8,0x03f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u20ac\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x0380,0x0380,0x0380,0x0380,0x03f8,0x03f0,0x07c0,0x1f80,\n  0x3ff8,0x03f0,0x07c0,0x1f80,0x3f80,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u20ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x3e1c,0x360c,0x360c,0x3600,0x3600,0x3600,0x3600,0x3600,\n  0x3600,0x3600,0x3600,0x3600,0x3600,0x360c,0x360c,0x3e1c,0x1ff8,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2102\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7ff0,0x7ff8,0x703c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u210e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0xffc0,0xffc0,0x3800,0x3800,0x3ff8,0x3ffc,0x381e,0x380e,\n  0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x380e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u210f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x300c,0x300c,0x300c,0x300c,0x380c,0x3c0c,0x360c,0x3b0c,0x3d8c,0x36cc,\n  0x336c,0x31bc,0x30dc,0x306c,0x303c,0x301c,0x300c,0x300c,0x300c,0x300c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2115\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xe1c0,0xe1ce,0xe1df,0xe1db,0xf1db,0xf1df,0xf9ce,0xf9c0,0xfdc0,0xedc0,\n  0xefc0,0xe7c0,0xe7c0,0xe3df,0xe3df,0xe1c0,0xe1df,0xe1df,0xe1c0,0xe1c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2116\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x1ff8,0x3e1c,0x360c,0x360c,0x360c,0x360c,0x360c,0x360c,0x360c,\n  0x360c,0x360c,0x360c,0x360c,0x360c,0x360c,0x36cc,0x3efc,0x1ff8,0x0ff8,0x001c,0x000e,0x0000,0x0000,0x0000,0x0000, // u211a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff0,0x3ff8,0x361c,0x360c,0x360c,0x360c,0x360c,0x360c,0x360c,0x361c,\n  0x37f8,0x37f0,0x36c0,0x3760,0x37b0,0x36d8,0x366c,0x3636,0x361a,0x3e0e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u211d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff86,0xffce,0x39fe,0x39fe,0x39ce,0x39ce,0x39ce,0x39ce,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2122\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x000c,0x000c,0x001c,0x003c,0x006c,0x00d8,0x01b0,0x0360,\n  0x06c0,0x0d80,0x1b00,0x3600,0x3c00,0x3800,0x3000,0x3000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2124\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x3838,0x1c70,0x1c70,0x1c70,0x7c7c,0x7c7c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2126\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7070,0x7070,0x3838,0x3838,0x1c1c,0x1c1c,0x0e0e,0x0e0e,0x1f1c,0x3f38,\n  0x73f0,0xe3e0,0xe1c0,0xe1c0,0xe0e0,0xe0e0,0xe070,0xe070,0x7038,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2135\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0300,0x0700,0x0e00,0x1c00,0x3800,0x7ffe,0x7ffe,\n  0x7ffe,0x3800,0x1c00,0x0e00,0x0700,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2190\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x07c0,0x0fe0,0x1ff0,0x3bb8,0x739c,0x638c,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2191\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00e0,0x0070,0x0038,0x001c,0x7ffe,0x7ffe,\n  0x7ffe,0x001c,0x0038,0x0070,0x00e0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2192\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x638c,0x739c,0x3bb8,0x1ff0,0x0fe0,0x07c0,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2193\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0660,0x0e70,0x1c38,0x381c,0x700e,0xffff,0xffff,\n  0xffff,0x700e,0x381c,0x1c38,0x0e70,0x0660,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2194\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x07c0,0x0fe0,0x1ff0,0x3bb8,0x739c,0x638c,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x638c,0x739c,0x3bb8,0x1ff0,0x0fe0,0x07c0,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2195\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0306,0x0706,0x0e06,0x1c06,0x3806,0x7ffe,0x7ffe,\n  0x7ffe,0x3806,0x1c06,0x0e06,0x0706,0x0306,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x60c0,0x60e0,0x6070,0x6038,0x601c,0x7ffe,0x7ffe,\n  0x7ffe,0x601c,0x6038,0x6070,0x60e0,0x60c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x07c0,0x0fe0,0x1ff0,0x3bb8,0x739c,0x638c,0x0380,0x0380,0x0380,\n  0x0380,0x638c,0x739c,0x3bb8,0x1ff0,0x0fe0,0x07c0,0x0380,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21a8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000e,0x000e,0x000e,0x000e,0x000e,0x000e,0x000e,0x030e,0x070e,0x0e0e,\n  0x1c0e,0x380e,0x7ffe,0x7ffe,0x7ffe,0x3800,0x1c00,0x0e00,0x0700,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x7f80,0x1f80,0x3f8c,0x3b8c,0x738e,0x700e,\n  0x700e,0x700e,0x700e,0x381c,0x3c3c,0x1ff8,0x07e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0800,0x1800,0x3800,0x7000,0xfffe,0xfffe,0xfffe,0x0000,\n  0x0000,0xfffe,0xfffe,0xfffe,0x001c,0x0038,0x0030,0x0020,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0020,0x0030,0x0038,0x001c,0xfffe,0xfffe,0xfffe,0x0000,\n  0x0000,0xfffe,0xfffe,0xfffe,0x7000,0x3800,0x1800,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21cc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0600,0x0e00,0x1ffe,0x3ffe,0x7ffe,0xf800,\n  0xf800,0x7ffe,0x3ffe,0x1ffe,0x0e00,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x03c0,0x07e0,0x0ff0,0x1ff8,0x3e7c,0x3e7c,0x0e70,0x0e70,0x0e70,\n  0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c0,0x00e0,0xfff0,0xfff8,0xfffc,0x003e,\n  0x003e,0xfffc,0xfff8,0xfff0,0x00e0,0x00c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,\n  0x0e70,0x0e70,0x0e70,0x3e7c,0x3e7c,0x1ff8,0x0ff0,0x07e0,0x03c0,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0660,0x0e70,0x1ff8,0x3ffc,0x7ffe,0xf81f,\n  0xf81f,0x7ffe,0x3ffc,0x1ff8,0x0e70,0x0660,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x03c0,0x07e0,0x0ff0,0x1ff8,0x3e7c,0x3e7c,0x0e70,0x0e70,0x0e70,\n  0x0e70,0x0e70,0x0e70,0x3e7c,0x3e7c,0x1ff8,0x0ff0,0x07e0,0x03c0,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u21d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x700e,0x700e,0x700e,0x700e,0x381c,0x381c,0x3ffc,0x3ffc,0x1c38,0x1c38,\n  0x1c38,0x0c30,0x0e70,0x0e70,0x0660,0x0660,0x07e0,0x03c0,0x03c0,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2200\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x7ffc,\n  0x7ffc,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x001c,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2203\n  0x0000,0x0000,0x0000,0x001c,0x001c,0x003c,0x7ffc,0x7ffc,0x007c,0x00fc,0x00dc,0x01dc,0x01dc,0x039c,0x039c,0x7ffc,\n  0x7ffc,0x071c,0x071c,0x0e1c,0x0e1c,0x1c1c,0x1c1c,0x381c,0x7ffc,0x7ffc,0x7000,0xe000,0xe000,0x0000,0x0000,0x0000, // u2204\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x001c,0x001c,0x0038,0x0038,0x0ff0,0x1ff8,0x38fc,0x38fc,0x39dc,0x39dc,\n  0x3b9c,0x3b9c,0x3f1c,0x3f1c,0x1ff8,0x0ff0,0x1c00,0x1c00,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2205\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x07c0,0x07c0,0x07c0,0x0ee0,0x0ee0,0x0ee0,0x1c70,\n  0x1c70,0x1c70,0x3838,0x3838,0x3838,0x701c,0x701c,0x701c,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2206\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x3838,0x3838,0x3838,0x1c70,0x1c70,\n  0x1c70,0x0ee0,0x0ee0,0x0ee0,0x07c0,0x07c0,0x07c0,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2207\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03fc,0x0ffc,0x1e00,0x3800,0x3800,0x7000,0x7000,0x7000,0x7000,0x7ffc,\n  0x7ffc,0x7000,0x7000,0x7000,0x7000,0x3800,0x3800,0x1e00,0x0ffc,0x03fc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2208\n  0x0000,0x0000,0x0000,0x000e,0x000e,0x001c,0x03fc,0x0ffc,0x1e38,0x3870,0x3870,0x70e0,0x70e0,0x71c0,0x71c0,0x7ffc,\n  0x7ffc,0x7380,0x7380,0x7700,0x7700,0x3e00,0x3e00,0x1e00,0x1ffc,0x3bfc,0x3800,0x7000,0x7000,0x0000,0x0000,0x0000, // u2209\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07fc,0x1ffc,0x3c00,0x3800,0x7000,0x7000,0x7ffc,\n  0x7ffc,0x7000,0x7000,0x3800,0x3c00,0x1ffc,0x07fc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u220a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x7fe0,0x00f0,0x0038,0x0038,0x001c,0x001c,0x001c,0x001c,0x7ffc,\n  0x7ffc,0x001c,0x001c,0x001c,0x001c,0x0038,0x0038,0x00f0,0x7fe0,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u220b\n  0x0000,0x0000,0x0000,0xe000,0xe000,0x7000,0x7f80,0x7fe0,0x38f0,0x1c38,0x1c38,0x0e1c,0x0e1c,0x071c,0x071c,0x7ffc,\n  0x7ffc,0x039c,0x039c,0x01dc,0x01dc,0x00f8,0x00f8,0x00f0,0x7ff0,0x7fb8,0x0038,0x001c,0x001c,0x0000,0x0000,0x0000, // u220c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7ff0,0x0078,0x0038,0x001c,0x001c,0x7ffc,\n  0x7ffc,0x001c,0x001c,0x0038,0x0078,0x7ff0,0x7fc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u220d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,\n  0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2212\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x0000,0x0000,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x7ffc,0x7ffc,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2213\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x7ffc,0x7ffc,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2214\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0006,0x000e,0x001c,0x0038,0x0070,0x00e0,0x01c0,\n  0x0380,0x0700,0x0e00,0x1c00,0x3800,0x7000,0x6000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2215\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6000,0x7000,0x3800,0x1c00,0x0e00,0x0700,0x0380,\n  0x01c0,0x00e0,0x0070,0x0038,0x001c,0x000e,0x0006,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2216\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03c0,0x07e0,0x07e0,\n  0x07e0,0x07e0,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2219\n  0x0000,0x0000,0x0000,0x003e,0x003e,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x7038,\n  0x7038,0x7038,0x7838,0x3c38,0x1e38,0x0f38,0x07b8,0x03f8,0x01f8,0x00f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u221a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ef8,0x7ffc,0xe7ce,0xe38e,0xe38e,\n  0xe38e,0xe38e,0xe7ce,0x7ffc,0x3ef8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u221e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,\n  0x7000,0x7000,0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u221f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,\n  0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2225\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x07c0,0x07c0,\n  0x0ee0,0x0ee0,0x1c70,0x1c70,0x1c70,0x3838,0x3838,0x3838,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2227\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x3838,0x3838,\n  0x3838,0x1c70,0x1c70,0x1c70,0x0ee0,0x0ee0,0x07c0,0x07c0,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2228\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07c0,0x1ff0,0x3c78,0x3838,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2229\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x3838,0x3c78,0x1ff0,0x07c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u222a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e1c,0x7fbc,0x7bfc,0x70f8,0x0000,\n  0x0000,0x3e1c,0x7fbc,0x7bfc,0x70f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2248\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000e,0x001c,0x7ffe,0x7ffe,0x00e0,0x01c0,\n  0x0380,0x0700,0x7ffe,0x7ffe,0x3800,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2260\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x7ffc,\n  0x7ffc,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2261\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x1c00,0x0e00,\n  0x0700,0x0380,0x01c0,0x00e0,0x0070,0x0038,0x0000,0x0000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2264\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1c00,0x0e00,0x0700,0x0380,0x01c0,0x00e0,0x0070,0x0038,0x0038,0x0070,\n  0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x0000,0x0000,0x3ffc,0x3ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2265\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00c3,0x01c7,0x038e,0x071c,0x0e38,0x1c70,0x38e0,0x71c0,0xe380,\n  0xe380,0x71c0,0x38e0,0x1c70,0x0e38,0x071c,0x038e,0x01c7,0x00c3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u226a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc300,0xe380,0x71c0,0x38e0,0x1c70,0x0e38,0x071c,0x038e,0x01c7,\n  0x01c7,0x038e,0x071c,0x0e38,0x1c70,0x38e0,0x71c0,0xe380,0xc300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u226b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07fe,0x1ffe,0x3c00,0x3800,0x7000,0x7000,0x7000,\n  0x7000,0x7000,0x7000,0x3800,0x3c00,0x1ffe,0x07fe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2282\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x7ff8,0x003c,0x001c,0x000e,0x000e,0x000e,\n  0x000e,0x000e,0x000e,0x001c,0x003c,0x7ff8,0x7fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2283\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07fe,0x1ffe,0x3c00,0x3800,0x7000,0x7000,0x7000,0x7000,0x7000,\n  0x7000,0x3800,0x3c00,0x1ffe,0x07fe,0x0000,0x0000,0x7ffe,0x7ffe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2286\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fe0,0x7ff8,0x003c,0x001c,0x000e,0x000e,0x000e,0x000e,0x000e,\n  0x000e,0x001c,0x003c,0x7ff8,0x7fe0,0x0000,0x0000,0x7ffe,0x7ffe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2287\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u22a5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07c0,0x1ff0,0x3c78,0x3838,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u22c2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x3838,0x3c78,0x1ff0,0x07c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u22c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x001c,0x001c,0x0038,0x0038,0x0ff0,0x1ff8,0x38fc,0x38fc,0x39dc,0x39dc,\n  0x3b9c,0x3b9c,0x3f1c,0x3f1c,0x1ff8,0x0ff0,0x1c00,0x1c00,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2300\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x07c0,0x0fe0,0x1ef0,0x3c78,0x783c,\n  0xf01e,0xe00e,0xe00e,0xe00e,0xe00e,0xe00e,0xe00e,0xe00e,0xfffe,0xfffe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2302\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x0ff0,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2308\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0ff0,0x0ff0,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,\n  0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2309\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0e00,0x0ff0,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u230a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,\n  0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x0ff0,0x0ff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u230b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x7000,0x7000,\n  0x7000,0x7000,0x7000,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2310\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x7000,0x7000,0x7000,\n  0x7000,0x7000,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2319\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x01f8,0x03fc,0x039c,0x039c,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u2320\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x7380,0x7380,0x7f80,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2321\n  0x0038,0x0070,0x00e0,0x01c0,0x0380,0x0380,0x0700,0x0700,0x0e00,0x0e00,0x0e00,0x1c00,0x1c00,0x1c00,0x1c00,0x3800,\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u239b\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u239c\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,\n  0x3800,0x1c00,0x1c00,0x1c00,0x1c00,0x0e00,0x0e00,0x0e00,0x0700,0x0700,0x0380,0x0380,0x01c0,0x00e0,0x0070,0x0038, // u239d\n  0x3800,0x1c00,0x0e00,0x0700,0x0380,0x0380,0x01c0,0x01c0,0x00e0,0x00e0,0x00e0,0x0070,0x0070,0x0070,0x0070,0x0038,\n  0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038, // u239e\n  0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,\n  0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038, // u239f\n  0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,\n  0x0038,0x0070,0x0070,0x0070,0x0070,0x00e0,0x00e0,0x00e0,0x01c0,0x01c0,0x0380,0x0380,0x0700,0x0e00,0x1c00,0x3800, // u23a0\n  0x3ff8,0x3ff8,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u23a1\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800, // u23a2\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3ff8,0x3ff8, // u23a3\n  0x3ff8,0x3ff8,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,\n  0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038, // u23a4\n  0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,\n  0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038, // u23a5\n  0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,\n  0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x3ff8,0x3ff8, // u23a6\n  0x007f,0x01ff,0x03c0,0x0380,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u23a7\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0f00,0x1e00,0xfc00,\n  0xfc00,0x1e00,0x0f00,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700, // u23a8\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,\n  0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0700,0x0380,0x03c0,0x01ff,0x007f, // u23a9\n  0xfe00,0xff80,0x03c0,0x01c0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,\n  0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0, // u23ab\n  0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x0070,0x003f,\n  0x003f,0x0070,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0, // u23ac\n  0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,\n  0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x00e0,0x01c0,0x03c0,0xff80,0xfe00, // u23ad\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u23ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,\n  0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23af\n  0xffff,0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23bb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u23bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff, // u23bd\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u23d0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x71c0,0x71c0,0x71c0,0x7fc0,0x7fc0,0x71c0,0x71c0,0x71c0,0x71c0,0x0000,\n  0x0000,0x03fe,0x03fe,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2409\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7fc0,0x7fc0,0x0000,\n  0x0000,0x03fe,0x03fe,0x0380,0x0380,0x03f8,0x03f8,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u240a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x71c0,0x71c0,0x71c0,0x71c0,0x71c0,0x71c0,0x3b80,0x1f00,0x0e00,0x0000,\n  0x0000,0x03fe,0x03fe,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x0070,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u240b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,0x7fc0,0x7000,0x7000,0x7f00,0x7f00,0x7000,0x7000,0x7000,0x0000,\n  0x0000,0x03fe,0x03fe,0x0380,0x0380,0x03f8,0x03f8,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u240c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x7fc0,0x71c0,0x7000,0x7000,0x7000,0x71c0,0x7fc0,0x3f80,0x0000,\n  0x0000,0x03fc,0x03fe,0x038e,0x038e,0x03fc,0x03f0,0x03b8,0x039c,0x038e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u240d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x71c0,0x71c0,0x79c0,0x7dc0,0x7fc0,0x77c0,0x73c0,0x71c0,0x71c0,0x0000,\n  0x0000,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x03fe,0x03fe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2424\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,\n  0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2500\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,\n  0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2501\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u2502\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u2503\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf7de,0xf7de,\n  0xf7de,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2508\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf7de,0xf7de,0xf7de,\n  0xf7de,0xf7de,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2509\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000, // u250a\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x0000,0x0000,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x0000,0x0000,\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x0000,0x0000,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x0000,0x0000, // u250b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03ff,0x03ff,\n  0x03ff,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u250c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03ff,0x03ff,0x03ff,\n  0x03ff,0x03ff,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u250d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07ff,0x07ff,\n  0x07ff,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u250e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07ff,0x07ff,0x07ff,\n  0x07ff,0x07ff,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u250f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,0xff80,\n  0xff80,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u2510\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,0xff80,0xff80,\n  0xff80,0xff80,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u2511\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,\n  0xffc0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u2512\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u2513\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x03ff,0x03ff,\n  0x03ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2514\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x03ff,0x03ff,0x03ff,\n  0x03ff,0x03ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2515\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07ff,0x07ff,\n  0x07ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2516\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07ff,0x07ff,0x07ff,\n  0x07ff,0x07ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2517\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0xff80,0xff80,\n  0xff80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2518\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0xff80,0xff80,0xff80,\n  0xff80,0xff80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2519\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0xffc0,0xffc0,\n  0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u251a\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u251b\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x03ff,0x03ff,\n  0x03ff,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u251c\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x03ff,0x03ff,0x03ff,\n  0x03ff,0x03ff,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u251d\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07ff,0x07ff,\n  0x07ff,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u251e\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x07ff,0x07ff,\n  0x07ff,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u251f\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07ff,0x07ff,\n  0x07ff,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u2520\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07ff,0x07ff,0x07ff,\n  0x07ff,0x07ff,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u2521\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x07ff,0x07ff,0x07ff,\n  0x07ff,0x07ff,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u2522\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07ff,0x07ff,0x07ff,\n  0x07ff,0x07ff,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u2523\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0xff80,0xff80,\n  0xff80,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u2524\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0xff80,0xff80,0xff80,\n  0xff80,0xff80,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u2525\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0xffc0,0xffc0,\n  0xffc0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u2526\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0xffc0,0xffc0,\n  0xffc0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u2527\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0xffc0,0xffc0,\n  0xffc0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u2528\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u2529\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u252a\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u252b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,\n  0xffff,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u252c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,0xffff,0xffff,\n  0xffff,0xff80,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u252d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03ff,0xffff,0xffff,\n  0xffff,0x03ff,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u252e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,\n  0xffff,0xffff,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u252f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,\n  0xffff,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u2530\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffc0,0xffff,0xffff,\n  0xffff,0xffc0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u2531\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07ff,0xffff,0xffff,\n  0xffff,0x07ff,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u2532\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,\n  0xffff,0xffff,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u2533\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0xffff,0xffff,\n  0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2534\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0xff80,0xffff,0xffff,\n  0xffff,0xff80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2535\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x03ff,0xffff,0xffff,\n  0xffff,0x03ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2536\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0xffff,0xffff,0xffff,\n  0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2537\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0xffff,0xffff,\n  0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2538\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0xffc0,0xffff,0xffff,\n  0xffff,0xffc0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2539\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07ff,0xffff,0xffff,\n  0xffff,0x07ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u253a\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0xffff,0xffff,0xffff,\n  0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u253b\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0xffff,0xffff,\n  0xffff,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u253c\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0xff80,0xffff,0xffff,\n  0xffff,0xff80,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u253d\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x03ff,0xffff,0xffff,\n  0xffff,0x03ff,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u253e\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0xffff,0xffff,0xffff,\n  0xffff,0xffff,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u253f\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0xffff,0xffff,\n  0xffff,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u2540\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0xffff,0xffff,\n  0xffff,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u2541\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0xffff,0xffff,\n  0xffff,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u2542\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0xffc0,0xffff,0xffff,\n  0xffff,0xff80,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u2543\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07ff,0xffff,0xffff,\n  0xffff,0x03ff,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u2544\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0xff80,0xffff,0xffff,\n  0xffff,0xffc0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u2545\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x03ff,0xffff,0xffff,\n  0xffff,0x07ff,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u2546\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0xffff,0xffff,0xffff,\n  0xffff,0xffff,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u2547\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0xffff,0xffff,0xffff,\n  0xffff,0xffff,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u2548\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0xffc0,0xffff,0xffff,\n  0xffff,0xffc0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u2549\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07ff,0xffff,0xffff,\n  0xffff,0x07ff,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u254a\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0xffff,0xffff,0xffff,\n  0xffff,0xffff,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u254b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0x0000,\n  0x0000,0xffff,0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2550\n  0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,\n  0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70, // u2551\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03ff,0x03ff,0x03ff,0x0380,\n  0x0380,0x03ff,0x03ff,0x03ff,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u2552\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fff,0x0fff,\n  0x0fff,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70, // u2553\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fff,0x0fff,0x0fff,0x0e00,\n  0x0e00,0x0e7f,0x0e7f,0x0e7f,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70, // u2554\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,0xff80,0xff80,0x0380,\n  0x0380,0xff80,0xff80,0xff80,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u2555\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0,\n  0xfff0,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70, // u2556\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xfff0,0xfff0,0xfff0,0x0070,\n  0x0070,0xfe70,0xfe70,0xfe70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70, // u2557\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x03ff,0x03ff,0x03ff,0x0380,\n  0x0380,0x03ff,0x03ff,0x03ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2558\n  0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0fff,0x0fff,\n  0x0fff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2559\n  0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e7f,0x0e7f,0x0e7f,0x0e00,\n  0x0e00,0x0fff,0x0fff,0x0fff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255a\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0xff80,0xff80,0xff80,0x0380,\n  0x0380,0xff80,0xff80,0xff80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255b\n  0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0xfff0,0xfff0,\n  0xfff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255c\n  0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0xfe70,0xfe70,0xfe70,0x0070,\n  0x0070,0xfff0,0xfff0,0xfff0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u255d\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x03ff,0x03ff,0x03ff,0x0380,\n  0x0380,0x03ff,0x03ff,0x03ff,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u255e\n  0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e7f,0x0e7f,\n  0x0e7f,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70, // u255f\n  0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e7f,0x0e7f,0x0e7f,0x0e00,\n  0x0e00,0x0e7f,0x0e7f,0x0e7f,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70, // u2560\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0xff80,0xff80,0xff80,0x0380,\n  0x0380,0xff80,0xff80,0xff80,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u2561\n  0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0xfe70,0xfe70,\n  0xfe70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70, // u2562\n  0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0xfe70,0xfe70,0xfe70,0x0070,\n  0x0070,0xfe70,0xfe70,0xfe70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70, // u2563\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0x0000,\n  0x0000,0xffff,0xffff,0xffff,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u2564\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,\n  0xffff,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70, // u2565\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0x0000,\n  0x0000,0xfe7f,0xfe7f,0xfe7f,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70, // u2566\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0xffff,0xffff,0xffff,0x0000,\n  0x0000,0xffff,0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2567\n  0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0xffff,0xffff,\n  0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2568\n  0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0xfe7f,0xfe7f,0xfe7f,0x0000,\n  0x0000,0xffff,0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2569\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0xffff,0xffff,0xffff,0x0380,\n  0x0380,0xffff,0xffff,0xffff,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u256a\n  0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0xffff,0xffff,\n  0xffff,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70, // u256b\n  0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0xfe7f,0xfe7f,0xfe7f,0x0000,\n  0x0000,0xfe7f,0xfe7f,0xfe7f,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70,0x0e70, // u256c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x001f,0x007f,\n  0x00ff,0x01f0,0x01c0,0x03c0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u256d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xf000,0xfc00,\n  0xfe00,0x1f00,0x0700,0x0780,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u256e\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0780,0x0700,0x1f00,0xfe00,0xfc00,\n  0xf000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u256f\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x03c0,0x01c0,0x01f0,0x00ff,0x007f,\n  0x001f,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2570\n  0x0003,0x0003,0x0007,0x0007,0x000e,0x000e,0x001c,0x001c,0x0038,0x0038,0x0070,0x0070,0x00e0,0x00e0,0x01c0,0x01c0,\n  0x0380,0x0380,0x0700,0x0700,0x0e00,0x0e00,0x1c00,0x1c00,0x3800,0x3800,0x7000,0x7000,0xe000,0xe000,0xc000,0xc000, // u2571\n  0xc000,0xc000,0xe000,0xe000,0x7000,0x7000,0x3800,0x3800,0x1c00,0x1c00,0x0e00,0x0e00,0x0700,0x0700,0x0380,0x0380,\n  0x01c0,0x01c0,0x00e0,0x00e0,0x0070,0x0070,0x0038,0x0038,0x001c,0x001c,0x000e,0x000e,0x0007,0x0007,0x0003,0x0003, // u2572\n  0xc003,0xc003,0xe007,0xe007,0x700e,0x700e,0x381c,0x381c,0x1c38,0x1c38,0x0e70,0x0e70,0x07e0,0x07e0,0x03c0,0x03c0,\n  0x03c0,0x03c0,0x07e0,0x07e0,0x0e70,0x0e70,0x1c38,0x1c38,0x381c,0x381c,0x700e,0x700e,0xe007,0xe007,0xc003,0xc003, // u2573\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,0xff80,\n  0xff80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2574\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,\n  0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2575\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03ff,0x03ff,\n  0x03ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2576\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u2577\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,0xff80,0xff80,\n  0xff80,0xff80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2578\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,\n  0x07c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2579\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03ff,0x03ff,0x03ff,\n  0x03ff,0x03ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07c0,0x07c0,\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u257b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03ff,0xffff,0xffff,\n  0xffff,0x03ff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257c\n  0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x07c0,0x07c0,\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0, // u257d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xff80,0xffff,0xffff,\n  0xffff,0xff80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u257e\n  0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,0x07c0,\n  0x07c0,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380,0x0380, // u257f\n  0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2580\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff, // u2581\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff, // u2582\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff, // u2583\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff, // u2584\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,\n  0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff, // u2585\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,\n  0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff, // u2586\n  0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,\n  0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff, // u2587\n  0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,\n  0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff, // u2588\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,\n  0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc,0xfffc, // u2589\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,\n  0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0,0xfff0, // u258a\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,\n  0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0,0xffc0, // u258b\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u258c\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,\n  0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00,0xfc00, // u258d\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,\n  0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000, // u258e\n  0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,\n  0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000,0xc000, // u258f\n  0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,\n  0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff, // u2590\n  0xaaaa,0x0000,0xaaaa,0x0000,0xaaaa,0x0000,0xaaaa,0x0000,0xaaaa,0x0000,0xaaaa,0x0000,0xaaaa,0x0000,0xaaaa,0x0000,\n  0xaaaa,0x0000,0xaaaa,0x0000,0xaaaa,0x0000,0xaaaa,0x0000,0xaaaa,0x0000,0xaaaa,0x0000,0xaaaa,0x0000,0xaaaa,0x0000, // u2591\n  0xaaaa,0x5555,0xaaaa,0x5555,0xaaaa,0x5555,0xaaaa,0x5555,0xaaaa,0x5555,0xaaaa,0x5555,0xaaaa,0x5555,0xaaaa,0x5555,\n  0xaaaa,0x5555,0xaaaa,0x5555,0xaaaa,0x5555,0xaaaa,0x5555,0xaaaa,0x5555,0xaaaa,0x5555,0xaaaa,0x5555,0xaaaa,0x5555, // u2592\n  0xffff,0xaaaa,0xffff,0xaaaa,0xffff,0xaaaa,0xffff,0xaaaa,0xffff,0xaaaa,0xffff,0xaaaa,0xffff,0xaaaa,0xffff,0xaaaa,\n  0xffff,0xaaaa,0xffff,0xaaaa,0xffff,0xaaaa,0xffff,0xaaaa,0xffff,0xaaaa,0xffff,0xaaaa,0xffff,0xaaaa,0xffff,0xaaaa, // u2593\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u2596\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff, // u2597\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2598\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,\n  0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff, // u2599\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,\n  0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff, // u259a\n  0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u259b\n  0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,\n  0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff, // u259c\n  0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u259d\n  0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,\n  0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00,0xff00, // u259e\n  0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,0x00ff,\n  0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff, // u259f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff8,0x1ff8,0x1ff8,0x1ff8,0x1ff8,0x1ff8,\n  0x1ff8,0x1ff8,0x1ff8,0x1ff8,0x1ff8,0x1ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25a0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x7ffe,0x7ffe,0x7ffe,0x7ffe,0x7ffe,0x7ffe,0x7ffe,0x7ffe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ac\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x7ffc,0x7ffc,0x7ffc,0x7ffc,0x7ffc,0x7ffc,0x7ffc,0x7ffc,\n  0x7ffc,0x7ffc,0x7ffc,0x7ffc,0x7ffc,0x7ffc,0x7ffc,0x7ffc,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ae\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x03c0,0x03c0,0x07e0,0x07e0,0x0ff0,0x0ff0,\n  0x1ff8,0x1ff8,0x3ffc,0x3ffc,0x7ffe,0x7ffe,0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25b2\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xffc0,0xfff0,0xfffc,0xffff,\n  0xffff,0xfffc,0xfff0,0xffc0,0xff00,0xfc00,0xf000,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc000,0xf000,0xfc00,0xff00,0xffc0,0xfff0,0xfffc,0xffff,\n  0xffff,0xfffc,0xfff0,0xffc0,0xff00,0xfc00,0xf000,0xc000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ba\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0x7ffe,0x7ffe,0x3ffc,0x3ffc,0x1ff8,0x1ff8,\n  0x0ff0,0x0ff0,0x07e0,0x07e0,0x03c0,0x03c0,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25bc\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0003,0x000f,0x003f,0x00ff,0x03ff,0x0fff,0x3fff,0xffff,\n  0xffff,0x3fff,0x0fff,0x03ff,0x00ff,0x003f,0x000f,0x0003,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c0\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0003,0x000f,0x003f,0x00ff,0x03ff,0x0fff,0x3fff,0xffff,\n  0xffff,0x3fff,0x0fff,0x03ff,0x00ff,0x003f,0x000f,0x0003,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x07c0,0x0fe0,0x1ff0,0x3ff8,0x7ffc,0xfffe,\n  0xfffe,0x7ffc,0x3ff8,0x1ff0,0x0fe0,0x07c0,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25c6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x07c0,0x0ee0,0x1c70,0x3838,0x701c,0xe00e,\n  0xe00e,0x701c,0x3838,0x1c70,0x0ee0,0x07c0,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25ca\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03c0,0x07e0,0x0e70,0x0c30,\n  0x0c30,0x0e70,0x07e0,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25cb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03c0,0x07e0,0x0ff0,0x0ff0,\n  0x0ff0,0x0ff0,0x07e0,0x03c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u25cf\n  0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xfc3f,0xf81f,0xf00f,0xf00f,\n  0xf00f,0xf00f,0xf81f,0xfc3f,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff, // u25d8\n  0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xfc3f,0xf81f,0xf18f,0xf3cf,\n  0xf3cf,0xf18f,0xf81f,0xfc3f,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff, // u25d9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff8,0x7ffc,0xf01e,0xe00e,0xe00e,0xe00e,0xeeee,0xeeee,0xe00e,0xe00e,\n  0xe00e,0xe00e,0xefee,0xe7ce,0xe00e,0xe00e,0xe00e,0xf01e,0x7ffc,0x3ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u263a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ff8,0x7ffc,0xfffe,0xfffe,0xfffe,0xfffe,0xe38e,0xe38e,0xfffe,0xfffe,\n  0xfffe,0xfffe,0xe00e,0xf01e,0xf83e,0xfffe,0xfffe,0xfffe,0x7ffc,0x3ff8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u263b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x0380,0x739c,0x739c,0x3bb8,0x1ff0,0x0fe0,0x7c7c,\n  0x7c7c,0x0fe0,0x1ff0,0x3bb8,0x739c,0x739c,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u263c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1ff0,0x3ff8,0x783c,0x701c,0x701c,0x701c,0x701c,0x701c,0x783c,0x3ff8,\n  0x1ff0,0x0380,0x0380,0x0380,0x7ffc,0x7ffc,0x0380,0x0380,0x0380,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2640\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x03fe,0x03fe,0x001e,0x003e,0x0076,0x00e6,0x01c6,0x0386,0x3fe0,0x7ff0,\n  0xf078,0xe038,0xe038,0xe038,0xe038,0xe038,0xe038,0xf078,0x7ff0,0x3fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2642\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x0380,0x07c0,0x0fe0,0x1ff0,0x3ff8,0x7ffc,0x7ffc,0xfffe,0xfffe,\n  0xfffe,0xfffe,0xfffe,0x7bbc,0x3bb8,0x0380,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2660\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x07c0,0x0fe0,0x0fe0,0x0fe0,0x0fe0,0x0fe0,0x07c0,0x0380,0x3bb8,0x7ffc,\n  0xfffe,0xfffe,0xfffe,0xfffe,0x7ffc,0x3bb8,0x0380,0x0380,0x0fe0,0x0fe0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2663\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x783c,0xfc7e,0xfefe,0xfffe,0xfffe,0xfffe,0xfffe,0xfffe,\n  0x7ffc,0x7ffc,0x3ff8,0x1ff0,0x0fe0,0x07c0,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2665\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0380,0x07c0,0x0fe0,0x1ff0,0x3ff8,0x7ffc,0xfffe,\n  0xfffe,0x7ffc,0x3ff8,0x1ff0,0x0fe0,0x07c0,0x0380,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2666\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3ffc,0x3ffc,0x381c,0x381c,0x381c,0x381c,0x3ffc,0x3ffc,0x3800,0x3800,\n  0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0x3800,0xf800,0xf000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u266a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffe,0x7ffe,0x700e,0x700e,0x700e,0x700e,0x7ffe,0x7ffe,0x700e,0x700e,\n  0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x700e,0x703e,0xf03c,0xe000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u266b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0007,0x0007,0x000e,0x000e,0x001c,0x001c,0x0038,0x0038,0xc070,0xc070,\n  0xe0e0,0xe0e0,0x71c0,0x71c0,0x3b80,0x3b80,0x1f00,0x1f00,0x0e00,0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2713\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x000f,0x000f,0x001e,0x001e,0x003c,0x003c,0x0078,0x0078,0xe0f0,0xe0f0,\n  0xf1e0,0xf1e0,0x7bc0,0x7bc0,0x3f80,0x3f80,0x1f00,0x1f00,0x0e00,0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2714\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x7070,0x3870,0x1ce0,0x0ee0,0x07c0,0x03c0,0x03c0,0x03e0,\n  0x0770,0x0738,0x0e1c,0x0e0c,0x1c00,0x1c00,0x3800,0x3800,0x7000,0x7000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2717\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x003c,0x003c,0x7878,0x3c78,0x1ef0,0x0ff0,0x07e0,0x03e0,0x03e0,0x03f0,\n  0x07f8,0x07bc,0x0f1e,0x0f0e,0x1e00,0x1e00,0x3c00,0x3c00,0x7800,0x7800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2718\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00e0,0x00e0,0x01c0,0x01c0,0x0380,0x0380,0x0700,0x0700,0x0e00,0x0e00,\n  0x0e00,0x0e00,0x0700,0x0700,0x0380,0x0380,0x01c0,0x01c0,0x00e0,0x00e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u27e8\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x0e00,0x0700,0x0700,0x0380,0x0380,0x01c0,0x01c0,0x00e0,0x00e0,\n  0x00e0,0x00e0,0x01c0,0x01c0,0x0380,0x0380,0x0700,0x0700,0x0e00,0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u27e9\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x071c,0x071c,0x0e38,0x0e38,0x1c70,0x1c70,0x38e0,0x38e0,0x71c0,0x71c0,\n  0x71c0,0x71c0,0x38e0,0x38e0,0x1c70,0x1c70,0x0e38,0x0e38,0x071c,0x071c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u27ea\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x71c0,0x71c0,0x38e0,0x38e0,0x1c70,0x1c70,0x0e38,0x0e38,0x071c,0x071c,\n  0x071c,0x071c,0x0e38,0x0e38,0x1c70,0x1c70,0x38e0,0x38e0,0x71c0,0x71c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u27eb\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2800\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2801\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2802\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2803\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2804\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2805\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2806\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2807\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2808\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2809\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280a\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280b\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280c\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280d\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280e\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u280f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2810\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2811\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2812\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2813\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2814\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2815\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2816\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2817\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2818\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2819\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281a\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281b\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281c\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281d\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281e\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u281f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2820\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2821\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2822\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2823\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2824\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2825\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2826\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2827\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2828\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2829\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282a\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282b\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282c\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282d\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282e\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u282f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2830\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2831\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2832\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2833\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2834\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2835\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2836\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2837\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2838\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2839\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283a\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283b\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283c\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283d\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283e\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u283f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2840\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2841\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2842\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2843\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2844\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2845\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2846\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2847\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2848\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2849\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u284a\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u284b\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u284c\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u284d\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u284e\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u284f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2850\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2851\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2852\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2853\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2854\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2855\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2856\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2857\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2858\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2859\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u285a\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u285b\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u285c\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u285d\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u285e\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u285f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2860\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2861\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2862\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2863\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2864\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2865\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2866\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2867\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2868\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2869\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u286a\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u286b\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u286c\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u286d\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u286e\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u286f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2870\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2871\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2872\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2873\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2874\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2875\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2876\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2877\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2878\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u2879\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u287a\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u287b\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u287c\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u287d\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u287e\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000, // u287f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u2880\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u2881\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u2882\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u2883\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u2884\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u2885\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u2886\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u2887\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u2888\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u2889\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u288a\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u288b\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u288c\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u288d\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u288e\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u288f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u2890\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u2891\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u2892\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u2893\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u2894\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u2895\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u2896\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u2897\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u2898\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u2899\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u289a\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u289b\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u289c\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u289d\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u289e\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u289f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28a0\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28a1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28a2\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28a4\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28a5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28a6\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28a7\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28a8\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28a9\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28aa\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28ab\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28ac\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28ad\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28ae\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28af\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28b0\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28b1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28b2\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28b4\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28b5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28b6\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28b7\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28b8\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28b9\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28ba\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28bb\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28bc\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28bd\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28be\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000, // u28bf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28c0\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28c1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28c2\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28c3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28c4\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28c5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28c6\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28c7\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28c8\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28c9\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28ca\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28cb\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28cc\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28cd\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28ce\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28cf\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28d0\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28d1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28d2\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28d3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28d4\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28d5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28d6\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28d7\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28d8\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28d9\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28da\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28db\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28dc\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28dd\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28de\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28df\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28e0\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28e1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28e2\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28e3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28e4\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28e6\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28e7\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28e8\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28e9\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28ea\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28eb\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28ec\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28ed\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28ee\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28ef\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28f0\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28f1\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28f2\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28f3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28f4\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28f5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28f6\n  0x0000,0x0000,0x3800,0x3800,0x3800,0x3800,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28f7\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28f8\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28f9\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28fa\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28fb\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28fc\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28fd\n  0x0000,0x0000,0x0038,0x0038,0x0038,0x0038,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28fe\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,\n  0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000,0x0000,0x0000,0x3838,0x3838,0x3838,0x3838,0x0000,0x0000, // u28ff\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x701c,0x701c,0x701c,0x701c,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u2e2c\n  0xe000,0xe000,0xe000,0xe0e0,0xe1f0,0xe3f8,0xe7fc,0xeeee,0xe0e0,0xe0e0,0xe0e0,0xe0e0,0xe0e0,0xe0e0,0xe0e0,0xe1c0,\n  0xc380,0x8700,0x0e00,0x1c00,0x3800,0x7000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000,0xe000, // ue0a0\n  0x0000,0x0000,0x0000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7000,0x7fe0,0x7fe0,0x0000,0x0000,\n  0x070e,0x070e,0x078e,0x07ce,0x07ee,0x077e,0x073e,0x071e,0x070e,0x070e,0x070e,0x0000,0x0000,0x0000,0x0000,0x0000, // ue0a1\n  0x0000,0x0000,0x0000,0x0000,0x0fe0,0x1ff0,0x3838,0x3838,0x3838,0x3838,0x3838,0x3838,0x3838,0x3838,0x7ffc,0xfffe,\n  0xfffe,0xfffe,0xfc7e,0xf83e,0xf83e,0xf83e,0xf83e,0xfc7e,0xfffe,0xfffe,0xfffe,0xfffe,0x0000,0x0000,0x0000,0x0000, // ue0a2\n  0x8000,0xc000,0xe000,0xf000,0xf800,0xfc00,0xfe00,0xff00,0xff80,0xffc0,0xffe0,0xfff0,0xfff8,0xfffc,0xfffe,0xffff,\n  0xffff,0xfffe,0xfffc,0xfff8,0xfff0,0xffe0,0xffc0,0xff80,0xff00,0xfe00,0xfc00,0xf800,0xf000,0xe000,0xc000,0x8000, // ue0b0\n  0x8000,0xc000,0xe000,0x7000,0x3800,0x1c00,0x0e00,0x0700,0x0380,0x01c0,0x00e0,0x0070,0x0038,0x001c,0x000e,0x0007,\n  0x0007,0x000e,0x001c,0x0038,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,0x7000,0xe000,0xc000,0x8000, // ue0b1\n  0x0001,0x0003,0x0007,0x000f,0x001f,0x003f,0x007f,0x00ff,0x01ff,0x03ff,0x07ff,0x0fff,0x1fff,0x3fff,0x7fff,0xffff,\n  0xffff,0x7fff,0x3fff,0x1fff,0x0fff,0x07ff,0x03ff,0x01ff,0x00ff,0x007f,0x003f,0x001f,0x000f,0x0007,0x0003,0x0001, // ue0b2\n  0x0001,0x0003,0x0007,0x000e,0x001c,0x0038,0x0070,0x00e0,0x01c0,0x0380,0x0700,0x0e00,0x1c00,0x3800,0x7000,0xe000,\n  0xe000,0x7000,0x3800,0x1c00,0x0e00,0x0700,0x0380,0x01c0,0x00e0,0x0070,0x0038,0x001c,0x000e,0x0007,0x0003,0x0001, // ue0b3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x00f8,0x00f8,0x0038,0x0038,\n  0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x0038,0x3838,0x3838,0x3c78,0x1ff0,0x0fe0,0x0000, // uf6be\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7ffc,0x7ffc,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,\n  0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x701c,0x7ffc,0x7ffc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 // ufffd\n  };\n  // codepoints array\n  constexpr std::array<uint16_t, CHARCOUNT> fixedfont_codepoints = {\n  0x0000,0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,\n  0x002f,0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,\n  0x003f,0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,\n  0x004f,0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,\n  0x005f,0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,\n  0x006f,0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,\n  0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af,\n  0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf,\n  0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf,\n  0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df,\n  0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef,\n  0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff,\n  0x0100,0x0101,0x0102,0x0103,0x0104,0x0105,0x0106,0x0107,0x0108,0x0109,0x010a,0x010b,0x010c,0x010d,0x010e,0x010f,\n  0x0110,0x0111,0x0112,0x0113,0x0114,0x0115,0x0116,0x0117,0x0118,0x0119,0x011a,0x011b,0x011c,0x011d,0x011e,0x011f,\n  0x0120,0x0121,0x0122,0x0123,0x0124,0x0125,0x0126,0x0127,0x0128,0x0129,0x012a,0x012b,0x012c,0x012d,0x012e,0x012f,\n  0x0130,0x0131,0x0132,0x0133,0x0134,0x0135,0x0136,0x0137,0x0138,0x0139,0x013a,0x013b,0x013c,0x013d,0x013e,0x013f,\n  0x0140,0x0141,0x0142,0x0143,0x0144,0x0145,0x0146,0x0147,0x0148,0x0149,0x014a,0x014b,0x014c,0x014d,0x014e,0x014f,\n  0x0150,0x0151,0x0152,0x0153,0x0154,0x0155,0x0156,0x0157,0x0158,0x0159,0x015a,0x015b,0x015c,0x015d,0x015e,0x015f,\n  0x0160,0x0161,0x0162,0x0163,0x0164,0x0165,0x0166,0x0167,0x0168,0x0169,0x016a,0x016b,0x016c,0x016d,0x016e,0x016f,\n  0x0170,0x0171,0x0172,0x0173,0x0174,0x0175,0x0176,0x0177,0x0178,0x0179,0x017a,0x017b,0x017c,0x017d,0x017e,0x017f,\n  0x0186,0x018e,0x018f,0x0190,0x0192,0x019d,0x019e,0x01b5,0x01b6,0x01b7,0x01cd,0x01ce,0x01cf,0x01d0,0x01d1,0x01d2,\n  0x01d3,0x01d4,0x01e2,0x01e3,0x01e4,0x01e5,0x01e6,0x01e7,0x01e8,0x01e9,0x01ea,0x01eb,0x01ec,0x01ed,0x01ee,0x01ef,\n  0x01f0,0x01f4,0x01f5,0x01fc,0x01fd,0x01fe,0x01ff,0x0218,0x0219,0x021a,0x021b,0x0232,0x0233,0x0237,0x0254,0x0258,\n  0x0259,0x025b,0x0272,0x0292,0x02bb,0x02bc,0x02bd,0x02c6,0x02c7,0x02d8,0x02d9,0x02db,0x02dc,0x02dd,0x0300,0x0301,\n  0x0302,0x0303,0x0304,0x0305,0x0306,0x0307,0x0308,0x030a,0x030b,0x030c,0x0329,0x0384,0x0385,0x0386,0x0387,0x0388,\n  0x0389,0x038a,0x038c,0x038e,0x038f,0x0390,0x0391,0x0392,0x0393,0x0394,0x0395,0x0396,0x0397,0x0398,0x0399,0x039a,\n  0x039b,0x039c,0x039d,0x039e,0x039f,0x03a0,0x03a1,0x03a3,0x03a4,0x03a5,0x03a6,0x03a7,0x03a8,0x03a9,0x03aa,0x03ab,\n  0x03ac,0x03ad,0x03ae,0x03af,0x03b0,0x03b1,0x03b2,0x03b3,0x03b4,0x03b5,0x03b6,0x03b7,0x03b8,0x03b9,0x03ba,0x03bb,\n  0x03bc,0x03bd,0x03be,0x03bf,0x03c0,0x03c1,0x03c2,0x03c3,0x03c4,0x03c5,0x03c6,0x03c7,0x03c8,0x03c9,0x03ca,0x03cb,\n  0x03cc,0x03cd,0x03ce,0x03d1,0x03d5,0x03f0,0x03f1,0x03f2,0x03f3,0x03f4,0x03f5,0x03f6,0x0400,0x0401,0x0402,0x0403,\n  0x0404,0x0405,0x0406,0x0407,0x0408,0x0409,0x040a,0x040b,0x040c,0x040d,0x040e,0x040f,0x0410,0x0411,0x0412,0x0413,\n  0x0414,0x0415,0x0416,0x0417,0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e,0x041f,0x0420,0x0421,0x0422,0x0423,\n  0x0424,0x0425,0x0426,0x0427,0x0428,0x0429,0x042a,0x042b,0x042c,0x042d,0x042e,0x042f,0x0430,0x0431,0x0432,0x0433,\n  0x0434,0x0435,0x0436,0x0437,0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e,0x043f,0x0440,0x0441,0x0442,0x0443,\n  0x0444,0x0445,0x0446,0x0447,0x0448,0x0449,0x044a,0x044b,0x044c,0x044d,0x044e,0x044f,0x0450,0x0451,0x0452,0x0453,\n  0x0454,0x0455,0x0456,0x0457,0x0458,0x0459,0x045a,0x045b,0x045c,0x045d,0x045e,0x045f,0x0462,0x0463,0x046a,0x046b,\n  0x0490,0x0491,0x0492,0x0493,0x0494,0x0495,0x0496,0x0497,0x0498,0x0499,0x049a,0x049b,0x049c,0x049d,0x04a0,0x04a1,\n  0x04a2,0x04a3,0x04a4,0x04a5,0x04aa,0x04ab,0x04ae,0x04af,0x04b0,0x04b1,0x04b2,0x04b3,0x04b6,0x04b7,0x04b8,0x04b9,\n  0x04ba,0x04bb,0x04c0,0x04c1,0x04c2,0x04cf,0x04d0,0x04d1,0x04d2,0x04d3,0x04d4,0x04d5,0x04d6,0x04d7,0x04d8,0x04d9,\n  0x04da,0x04db,0x04dc,0x04dd,0x04de,0x04df,0x04e2,0x04e3,0x04e4,0x04e5,0x04e6,0x04e7,0x04e8,0x04e9,0x04ea,0x04eb,\n  0x04ec,0x04ed,0x04ee,0x04ef,0x04f0,0x04f1,0x04f2,0x04f3,0x04f4,0x04f5,0x04f8,0x04f9,0x05d0,0x05d1,0x05d2,0x05d3,\n  0x05d4,0x05d5,0x05d6,0x05d7,0x05d8,0x05d9,0x05da,0x05db,0x05dc,0x05dd,0x05de,0x05df,0x05e0,0x05e1,0x05e2,0x05e3,\n  0x05e4,0x05e5,0x05e6,0x05e7,0x05e8,0x05e9,0x05ea,0x1e0c,0x1e0d,0x1e34,0x1e35,0x1e36,0x1e37,0x1e40,0x1e41,0x1e42,\n  0x1e43,0x1e44,0x1e45,0x1e46,0x1e47,0x1e6c,0x1e6d,0x1eb8,0x1eb9,0x1ebc,0x1ebd,0x1eca,0x1ecb,0x1ecc,0x1ecd,0x1ee4,\n  0x1ee5,0x1ef8,0x1ef9,0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007,0x2008,0x2009,0x200a,0x200b,0x200c,\n  0x200d,0x200e,0x200f,0x2010,0x2011,0x2012,0x2013,0x2014,0x2015,0x2016,0x2017,0x2018,0x2019,0x201a,0x201b,0x201c,\n  0x201d,0x201e,0x201f,0x2020,0x2021,0x2022,0x2026,0x2030,0x2032,0x2033,0x2039,0x203a,0x203c,0x203e,0x2070,0x2071,\n  0x2074,0x2075,0x2076,0x2077,0x2078,0x2079,0x207a,0x207b,0x207c,0x207d,0x207e,0x207f,0x2080,0x2081,0x2082,0x2083,\n  0x2084,0x2085,0x2086,0x2087,0x2088,0x2089,0x208a,0x208b,0x208c,0x208d,0x208e,0x2090,0x2091,0x2092,0x2093,0x2094,\n  0x2095,0x2096,0x2097,0x2098,0x209a,0x20a7,0x20aa,0x20ac,0x20ae,0x2102,0x210e,0x210f,0x2115,0x2116,0x211a,0x211d,\n  0x2122,0x2124,0x2126,0x2135,0x2190,0x2191,0x2192,0x2193,0x2194,0x2195,0x21a4,0x21a6,0x21a8,0x21b5,0x21bb,0x21cb,\n  0x21cc,0x21d0,0x21d1,0x21d2,0x21d3,0x21d4,0x21d5,0x2200,0x2203,0x2204,0x2205,0x2206,0x2207,0x2208,0x2209,0x220a,\n  0x220b,0x220c,0x220d,0x2212,0x2213,0x2214,0x2215,0x2216,0x2219,0x221a,0x221e,0x221f,0x2225,0x2227,0x2228,0x2229,\n  0x222a,0x2248,0x2260,0x2261,0x2264,0x2265,0x226a,0x226b,0x2282,0x2283,0x2286,0x2287,0x22a5,0x22c2,0x22c3,0x2300,\n  0x2302,0x2308,0x2309,0x230a,0x230b,0x2310,0x2319,0x2320,0x2321,0x239b,0x239c,0x239d,0x239e,0x239f,0x23a0,0x23a1,\n  0x23a2,0x23a3,0x23a4,0x23a5,0x23a6,0x23a7,0x23a8,0x23a9,0x23ab,0x23ac,0x23ad,0x23ae,0x23af,0x23ba,0x23bb,0x23bc,\n  0x23bd,0x23d0,0x2409,0x240a,0x240b,0x240c,0x240d,0x2424,0x2500,0x2501,0x2502,0x2503,0x2508,0x2509,0x250a,0x250b,\n  0x250c,0x250d,0x250e,0x250f,0x2510,0x2511,0x2512,0x2513,0x2514,0x2515,0x2516,0x2517,0x2518,0x2519,0x251a,0x251b,\n  0x251c,0x251d,0x251e,0x251f,0x2520,0x2521,0x2522,0x2523,0x2524,0x2525,0x2526,0x2527,0x2528,0x2529,0x252a,0x252b,\n  0x252c,0x252d,0x252e,0x252f,0x2530,0x2531,0x2532,0x2533,0x2534,0x2535,0x2536,0x2537,0x2538,0x2539,0x253a,0x253b,\n  0x253c,0x253d,0x253e,0x253f,0x2540,0x2541,0x2542,0x2543,0x2544,0x2545,0x2546,0x2547,0x2548,0x2549,0x254a,0x254b,\n  0x2550,0x2551,0x2552,0x2553,0x2554,0x2555,0x2556,0x2557,0x2558,0x2559,0x255a,0x255b,0x255c,0x255d,0x255e,0x255f,\n  0x2560,0x2561,0x2562,0x2563,0x2564,0x2565,0x2566,0x2567,0x2568,0x2569,0x256a,0x256b,0x256c,0x256d,0x256e,0x256f,\n  0x2570,0x2571,0x2572,0x2573,0x2574,0x2575,0x2576,0x2577,0x2578,0x2579,0x257a,0x257b,0x257c,0x257d,0x257e,0x257f,\n  0x2580,0x2581,0x2582,0x2583,0x2584,0x2585,0x2586,0x2587,0x2588,0x2589,0x258a,0x258b,0x258c,0x258d,0x258e,0x258f,\n  0x2590,0x2591,0x2592,0x2593,0x2596,0x2597,0x2598,0x2599,0x259a,0x259b,0x259c,0x259d,0x259e,0x259f,0x25a0,0x25ac,\n  0x25ae,0x25b2,0x25b6,0x25ba,0x25bc,0x25c0,0x25c4,0x25c6,0x25ca,0x25cb,0x25cf,0x25d8,0x25d9,0x263a,0x263b,0x263c,\n  0x2640,0x2642,0x2660,0x2663,0x2665,0x2666,0x266a,0x266b,0x2713,0x2714,0x2717,0x2718,0x27e8,0x27e9,0x27ea,0x27eb,\n  0x2800,0x2801,0x2802,0x2803,0x2804,0x2805,0x2806,0x2807,0x2808,0x2809,0x280a,0x280b,0x280c,0x280d,0x280e,0x280f,\n  0x2810,0x2811,0x2812,0x2813,0x2814,0x2815,0x2816,0x2817,0x2818,0x2819,0x281a,0x281b,0x281c,0x281d,0x281e,0x281f,\n  0x2820,0x2821,0x2822,0x2823,0x2824,0x2825,0x2826,0x2827,0x2828,0x2829,0x282a,0x282b,0x282c,0x282d,0x282e,0x282f,\n  0x2830,0x2831,0x2832,0x2833,0x2834,0x2835,0x2836,0x2837,0x2838,0x2839,0x283a,0x283b,0x283c,0x283d,0x283e,0x283f,\n  0x2840,0x2841,0x2842,0x2843,0x2844,0x2845,0x2846,0x2847,0x2848,0x2849,0x284a,0x284b,0x284c,0x284d,0x284e,0x284f,\n  0x2850,0x2851,0x2852,0x2853,0x2854,0x2855,0x2856,0x2857,0x2858,0x2859,0x285a,0x285b,0x285c,0x285d,0x285e,0x285f,\n  0x2860,0x2861,0x2862,0x2863,0x2864,0x2865,0x2866,0x2867,0x2868,0x2869,0x286a,0x286b,0x286c,0x286d,0x286e,0x286f,\n  0x2870,0x2871,0x2872,0x2873,0x2874,0x2875,0x2876,0x2877,0x2878,0x2879,0x287a,0x287b,0x287c,0x287d,0x287e,0x287f,\n  0x2880,0x2881,0x2882,0x2883,0x2884,0x2885,0x2886,0x2887,0x2888,0x2889,0x288a,0x288b,0x288c,0x288d,0x288e,0x288f,\n  0x2890,0x2891,0x2892,0x2893,0x2894,0x2895,0x2896,0x2897,0x2898,0x2899,0x289a,0x289b,0x289c,0x289d,0x289e,0x289f,\n  0x28a0,0x28a1,0x28a2,0x28a3,0x28a4,0x28a5,0x28a6,0x28a7,0x28a8,0x28a9,0x28aa,0x28ab,0x28ac,0x28ad,0x28ae,0x28af,\n  0x28b0,0x28b1,0x28b2,0x28b3,0x28b4,0x28b5,0x28b6,0x28b7,0x28b8,0x28b9,0x28ba,0x28bb,0x28bc,0x28bd,0x28be,0x28bf,\n  0x28c0,0x28c1,0x28c2,0x28c3,0x28c4,0x28c5,0x28c6,0x28c7,0x28c8,0x28c9,0x28ca,0x28cb,0x28cc,0x28cd,0x28ce,0x28cf,\n  0x28d0,0x28d1,0x28d2,0x28d3,0x28d4,0x28d5,0x28d6,0x28d7,0x28d8,0x28d9,0x28da,0x28db,0x28dc,0x28dd,0x28de,0x28df,\n  0x28e0,0x28e1,0x28e2,0x28e3,0x28e4,0x28e5,0x28e6,0x28e7,0x28e8,0x28e9,0x28ea,0x28eb,0x28ec,0x28ed,0x28ee,0x28ef,\n  0x28f0,0x28f1,0x28f2,0x28f3,0x28f4,0x28f5,0x28f6,0x28f7,0x28f8,0x28f9,0x28fa,0x28fb,0x28fc,0x28fd,0x28fe,0x28ff,\n  0x2e2c,0xe0a0,0xe0a1,0xe0a2,0xe0b0,0xe0b1,0xe0b2,0xe0b3,0xf6be,0xfffd };\n} // namespace\n// -- end of autogenerated text ---\n\nnamespace fixed_font_info_h {\n  // -- start of autogenerated text ---\n  // definition section for font: info_h\n  constexpr int CHARCOUNT = 196;\n  constexpr int WIDTH = 10;\n  constexpr int HEIGHT = 20;\n  constexpr int OFFSET_X = 0;\n  constexpr int OFFSET_Y = 0;\n  constexpr FixedFont_info_t fixedfont_info = {\n    \"info_h\", // font name\n    \"info_h\", // font name internal\n    CHARCOUNT, // num of chars\n    WIDTH, HEIGHT, OFFSET_X, OFFSET_Y,\n    false // bold\n  };\n  // font bitmap definitions\n  constexpr std::array<uint16_t, CHARCOUNT * HEIGHT> fixedfont_bitmap = {\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0020\n  0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0021\n  0x0000,0x0000,0x3300,0x3300,0x3300,0x1200,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0022\n  0x0000,0x0000,0x0000,0x0d80,0x0d80,0x0d80,0x3fc0,0x1b00,0x1b00,0x1b00,0x7f80,0x3600,0x3600,0x3600,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0023\n  0x0000,0x0000,0x0c00,0x3f00,0x6d80,0x6c00,0x6c00,0x6c00,0x3f00,0x0d80,0x0d80,0x0d80,0x6d80,0x3f00,0x0c00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0024\n  0x0000,0x0000,0x0000,0x3980,0x6d80,0x6f00,0x3b00,0x0600,0x0600,0x0c00,0x0c00,0x1b80,0x1ec0,0x36c0,0x3380,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0025\n  0x0000,0x0000,0x1c00,0x3600,0x3600,0x3600,0x3c00,0x1800,0x3800,0x6c00,0x66c0,0x6380,0x6300,0x7780,0x3cc0,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0026\n  0x0000,0x0000,0x0f00,0x0e00,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0027\n  0x0000,0x0000,0x0300,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x1800,0x1800,0x1800,0x0c00,0x0c00,0x0600,0x0300,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0028\n  0x0000,0x0000,0x3000,0x1800,0x0c00,0x0c00,0x0600,0x0600,0x0600,0x0600,0x0600,0x0c00,0x0c00,0x1800,0x3000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0029\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x3300,0x3300,0x1e00,0x7f80,0x1e00,0x3300,0x3300,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u002a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x7f80,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u002b\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x0e00,0x1800,\n  0x0000,0x0000,0x0000,0x0000, // u002c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u002d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x0e00,0x0e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u002e\n  0x0000,0x0000,0x0000,0x0180,0x0180,0x0300,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u002f\n  0x0000,0x0000,0x0c00,0x1e00,0x3300,0x3300,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x3300,0x1e00,0x0c00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0030\n  0x0000,0x0000,0x0c00,0x1c00,0x3c00,0x6c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x7f80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0031\n  0x0000,0x0000,0x1e00,0x3300,0x6180,0x6180,0x0180,0x0180,0x0300,0x0e00,0x1800,0x3000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0032\n  0x0000,0x0000,0x1e00,0x3300,0x6180,0x6180,0x0180,0x0300,0x0e00,0x0300,0x0180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0033\n  0x0000,0x0000,0x0100,0x0300,0x0700,0x0f00,0x1b00,0x3300,0x6300,0x6300,0x7f80,0x0300,0x0300,0x0300,0x0300,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0034\n  0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6e00,0x7300,0x0180,0x0180,0x0180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0035\n  0x0000,0x0000,0x1e00,0x3300,0x6100,0x6000,0x6000,0x6e00,0x7300,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0036\n  0x0000,0x0000,0x7f80,0x0180,0x0180,0x0300,0x0300,0x0600,0x0600,0x0c00,0x0c00,0x1800,0x1800,0x3000,0x3000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0037\n  0x0000,0x0000,0x1e00,0x3300,0x6180,0x6180,0x6180,0x3300,0x1e00,0x3300,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0038\n  0x0000,0x0000,0x1e00,0x3300,0x6180,0x6180,0x6180,0x6180,0x3380,0x1d80,0x0180,0x0180,0x2180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0039\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x0e00,0x0000,0x0000,0x0000,0x0000,0x0e00,0x0e00,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u003a\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x0e00,0x0000,0x0000,0x0000,0x0000,0x0e00,0x0e00,0x1c00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u003b\n  0x0000,0x0000,0x0100,0x0300,0x0600,0x0c00,0x1800,0x3000,0x6000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0100,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u003c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u003d\n  0x0000,0x0000,0x2000,0x3000,0x1800,0x0c00,0x0600,0x0300,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x2000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u003e\n  0x0000,0x0000,0x1e00,0x3300,0x6180,0x6180,0x6180,0x0300,0x0600,0x0c00,0x0c00,0x0c00,0x0000,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u003f\n  0x0000,0x0000,0x1e00,0x3300,0x6180,0x6780,0x6f80,0x6d80,0x6d80,0x6d80,0x6f00,0x6600,0x6000,0x3180,0x1f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0040\n  0x0000,0x0000,0x0c00,0x1e00,0x3300,0x3300,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0041\n  0x0000,0x0000,0x7c00,0x6600,0x6300,0x6300,0x6300,0x6600,0x7e00,0x6300,0x6180,0x6180,0x6180,0x6300,0x7e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0042\n  0x0000,0x0000,0x1e00,0x3300,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0043\n  0x0000,0x0000,0x7e00,0x6300,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6300,0x7e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0044\n  0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0045\n  0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0046\n  0x0000,0x0000,0x1e00,0x3300,0x6180,0x6000,0x6000,0x6000,0x6780,0x6180,0x6180,0x6180,0x6180,0x3380,0x1e80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0047\n  0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0048\n  0x0000,0x0000,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x7f80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0049\n  0x0000,0x0000,0x0f80,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u004a\n  0x0000,0x0000,0x6180,0x6180,0x6300,0x6300,0x6600,0x6600,0x7c00,0x6600,0x6600,0x6300,0x6300,0x6180,0x6180,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u004b\n  0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u004c\n  0x0000,0x0000,0x6180,0x6180,0x7380,0x7380,0x7f80,0x6d80,0x6d80,0x6d80,0x6d80,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u004d\n  0x0000,0x0000,0x6180,0x7180,0x7180,0x7980,0x7980,0x6d80,0x6d80,0x6780,0x6780,0x6380,0x6380,0x6180,0x6180,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u004e\n  0x0000,0x0000,0x1e00,0x3300,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u004f\n  0x0000,0x0000,0x7e00,0x6300,0x6180,0x6180,0x6180,0x6180,0x6300,0x7e00,0x6000,0x6000,0x6000,0x6000,0x6000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0050\n  0x0000,0x0000,0x1e00,0x3300,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6d80,0x6780,0x3300,0x1f00,0x0180,\n  0x0000,0x0000,0x0000,0x0000, // u0051\n  0x0000,0x0000,0x7e00,0x6300,0x6180,0x6180,0x6180,0x6180,0x6300,0x7e00,0x6600,0x6300,0x6300,0x6180,0x6180,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0052\n  0x0000,0x0000,0x1e00,0x3300,0x6180,0x6000,0x6000,0x3000,0x1e00,0x0300,0x0180,0x0180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0053\n  0x0000,0x0000,0x7f80,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0054\n  0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0055\n  0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x3300,0x3300,0x3300,0x1e00,0x1e00,0x1e00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0056\n  0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6d80,0x6d80,0x6d80,0x6d80,0x7380,0x7380,0x6180,0x6180,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0057\n  0x0000,0x0000,0x6180,0x6180,0x3300,0x3300,0x1e00,0x1e00,0x0c00,0x1e00,0x1e00,0x3300,0x3300,0x6180,0x6180,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0058\n  0x0000,0x0000,0x6180,0x6180,0x3300,0x3300,0x1e00,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0059\n  0x0000,0x0000,0x7f80,0x0180,0x0180,0x0300,0x0600,0x0600,0x0c00,0x1800,0x1800,0x3000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u005a\n  0x0000,0x0000,0x3f00,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x3f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u005b\n  0x0000,0x0000,0x0000,0x3000,0x3000,0x1800,0x1800,0x0c00,0x0c00,0x0600,0x0600,0x0300,0x0300,0x0180,0x0180,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u005c\n  0x0000,0x0000,0x3f00,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x3f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u005d\n  0x0000,0x0000,0x0c00,0x1e00,0x3300,0x6180,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u005e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7fc0,\n  0x0000,0x0000,0x0000,0x0000, // u005f\n  0x0000,0x0000,0x3c00,0x1c00,0x0600,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0060\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x3e80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0061\n  0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6e00,0x7300,0x6180,0x6180,0x6180,0x6180,0x7300,0x6e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0062\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x6000,0x6000,0x6000,0x6000,0x3180,0x1f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0063\n  0x0000,0x0000,0x0180,0x0180,0x0180,0x0180,0x0180,0x1d80,0x3380,0x6180,0x6180,0x6180,0x6180,0x3380,0x1d80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0064\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x6180,0x7f80,0x6000,0x6000,0x3180,0x1f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0065\n  0x0000,0x0000,0x0f00,0x1980,0x1980,0x1800,0x1800,0x1800,0x1800,0x7e00,0x1800,0x1800,0x1800,0x1800,0x1800,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0066\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3e80,0x6380,0x6300,0x6300,0x6300,0x3e00,0x6000,0x3f00,0x6180,\n  0x6180,0x6180,0x3f00,0x0000, // u0067\n  0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6e00,0x7300,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0068\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x3c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x7f80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0069\n  0x0000,0x0000,0x0000,0x0000,0x0180,0x0180,0x0000,0x0780,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x0180,0x3180,\n  0x3180,0x3180,0x1f00,0x0000, // u006a\n  0x0000,0x0000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6300,0x6600,0x6c00,0x7800,0x7c00,0x6600,0x6300,0x6180,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u006b\n  0x0000,0x0000,0x3c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x7f80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u006c\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x5b00,0x7f80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x6d80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u006d\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6e00,0x7300,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u006e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u006f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6e00,0x7300,0x6180,0x6180,0x6180,0x6180,0x7300,0x6e00,0x6000,\n  0x6000,0x6000,0x6000,0x0000, // u0070\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1d80,0x3380,0x6180,0x6180,0x6180,0x6180,0x3380,0x1d80,0x0180,\n  0x0180,0x0180,0x0180,0x0000, // u0071\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6f00,0x3980,0x3000,0x3000,0x3000,0x3000,0x3000,0x3000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0072\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x6180,0x6000,0x3f00,0x0180,0x0180,0x6180,0x3f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0073\n  0x0000,0x0000,0x0000,0x0000,0x1800,0x1800,0x1800,0x7e00,0x1800,0x1800,0x1800,0x1800,0x1800,0x1980,0x0f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0074\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3380,0x1d80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0075\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x3300,0x3300,0x1e00,0x1e00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0076\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6d80,0x6d80,0x6d80,0x7f80,0x3300,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0077\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x3300,0x1e00,0x0c00,0x0c00,0x1e00,0x3300,0x6180,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0078\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3380,0x1d80,0x0180,\n  0x6180,0x3300,0x1e00,0x0000, // u0079\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f80,0x0180,0x0300,0x0600,0x0c00,0x1800,0x3000,0x3f80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u007a\n  0x0000,0x0000,0x0780,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x7800,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0780,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u007b\n  0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u007c\n  0x0000,0x0000,0x7800,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0780,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x7800,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u007d\n  0x0000,0x0000,0x3980,0x6d80,0x6700,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u007e\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u007f\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00a0\n  0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00a1\n  0x0000,0x0000,0x0000,0x0c00,0x0c00,0x1e00,0x3300,0x6100,0x6000,0x6000,0x6100,0x3300,0x1e00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00a2\n  0x0000,0x0000,0x0000,0x0f00,0x1980,0x1980,0x1800,0x1800,0x7e00,0x1800,0x1800,0x1800,0x7c00,0x56c0,0x7380,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00a3\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x4040,0x2e80,0x1f00,0x3180,0x3180,0x3180,0x1f00,0x2e80,0x4040,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00a4\n  0x0000,0x0000,0x0000,0x0000,0x4080,0x6180,0x3300,0x1e00,0x3f00,0x0c00,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00a5\n  0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00a6\n  0x0000,0x0000,0x3e00,0x6300,0x6000,0x7000,0x7800,0x4c00,0x6600,0x3300,0x1900,0x0f00,0x0300,0x6300,0x3e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00a7\n  0x0000,0x0000,0x3300,0x3300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00a8\n  0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x6180,0x5e80,0x5280,0x5080,0x5280,0x5e80,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00a9\n  0x0000,0x0000,0x1f00,0x2180,0x0180,0x3f80,0x6180,0x6180,0x3e80,0x0000,0x7f80,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00aa\n  0x0000,0x0000,0x0000,0x0000,0x0480,0x0d80,0x1b00,0x3600,0x6c00,0xd800,0x6c00,0x3600,0x1b00,0x0d80,0x0480,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00ab\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7f80,0x7f80,0x0180,0x0180,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00ac\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3f00,0x3f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00ad\n  0x0000,0x0000,0x0000,0x0000,0x1e00,0x3300,0x6180,0x5e80,0x5280,0x5e80,0x5480,0x5680,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00ae\n  0x0000,0x0000,0x0000,0x7f00,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00af\n  0x0000,0x0000,0x0c00,0x1e00,0x3300,0x3300,0x1e00,0x0c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00b0\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x7f80,0x7f80,0x0c00,0x0c00,0x0000,0x7f80,0x7f80,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00b1\n  0x0000,0x0000,0x1c00,0x3600,0x0600,0x0c00,0x1800,0x3000,0x3e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00b2\n  0x0000,0x0000,0x1c00,0x3600,0x0200,0x0e00,0x0200,0x3600,0x1c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00b3\n  0x0000,0x0000,0x0600,0x0c00,0x1800,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00b4\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6300,0x6300,0x6300,0x6300,0x6300,0x7700,0x7d00,0x6000,\n  0x6000,0x6000,0x0000,0x0000, // u00b5\n  0x0000,0x0000,0x1f80,0x3f80,0x7d80,0x7d80,0x7d80,0x3d80,0x1d80,0x0580,0x0580,0x0580,0x0580,0x0580,0x0580,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00b6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0e00,0x0e00,0x0e00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00b7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0c00,\n  0x0400,0x1200,0x0c00,0x0000, // u00b8\n  0x0000,0x0000,0x1800,0x3800,0x1800,0x1800,0x1800,0x3c00,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00b9\n  0x0000,0x0000,0x1c00,0x3600,0x6300,0x6300,0x6300,0x3600,0x1c00,0x0000,0x7f00,0x0000,0x0000,0x0000,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00ba\n  0x0000,0x0000,0x0000,0x0000,0x4800,0x6c00,0x3600,0x1b00,0x0d80,0x06c0,0x0d80,0x1b00,0x3600,0x6c00,0x4800,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00bb\n  0x0000,0x0000,0x2000,0x6000,0x2080,0x2100,0x7200,0x0400,0x0900,0x1300,0x2500,0x4f00,0x0100,0x0100,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00bc\n  0x0000,0x0000,0x2000,0x6000,0x2080,0x2100,0x7200,0x0400,0x0b00,0x1480,0x2080,0x4100,0x0200,0x0780,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00bd\n  0x0000,0x0000,0x7000,0x0800,0x3080,0x0900,0x7200,0x0400,0x0900,0x1300,0x2500,0x4f80,0x0100,0x0100,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00be\n  0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0c00,0x0c00,0x0c00,0x1800,0x3000,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00bf\n  0x0000,0x0000,0x3000,0x1800,0x0c00,0x0000,0x0c00,0x1e00,0x3300,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00c0\n  0x0000,0x0000,0x0300,0x0600,0x0c00,0x0000,0x0c00,0x1e00,0x3300,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00c1\n  0x0000,0x0000,0x0c00,0x1e00,0x3300,0x0000,0x0c00,0x1e00,0x3300,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00c2\n  0x0000,0x0000,0x1900,0x3f00,0x2600,0x0000,0x0c00,0x1e00,0x3300,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00c3\n  0x0000,0x0000,0x3300,0x3300,0x0000,0x0000,0x0c00,0x1e00,0x3300,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00c4\n  0x0000,0x0000,0x0c00,0x1200,0x1200,0x0c00,0x0c00,0x1e00,0x3300,0x6180,0x6180,0x7f80,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00c5\n  0x0000,0x0000,0x0f80,0x1e00,0x3600,0x3600,0x6600,0x6600,0x7f80,0x6600,0x6600,0x6600,0x6600,0x6600,0x6780,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00c6\n  0x0000,0x0000,0x1e00,0x3300,0x6180,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6000,0x6180,0x3300,0x1e00,0x0c00,\n  0x0400,0x1200,0x0c00,0x0000, // u00c7\n  0x0000,0x0000,0x3000,0x1800,0x0c00,0x0000,0x7f80,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00c8\n  0x0000,0x0000,0x0600,0x0c00,0x1800,0x0000,0x7f80,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00c9\n  0x0000,0x0000,0x0c00,0x1e00,0x3300,0x0000,0x7f80,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00ca\n  0x0000,0x0000,0x3300,0x3300,0x0000,0x0000,0x7f80,0x6000,0x6000,0x6000,0x7e00,0x6000,0x6000,0x6000,0x7f80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00cb\n  0x0000,0x0000,0x3000,0x1800,0x0c00,0x0000,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x3f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00cc\n  0x0000,0x0000,0x0600,0x0c00,0x1800,0x0000,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x3f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00cd\n  0x0000,0x0000,0x0c00,0x1e00,0x3300,0x0000,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x3f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00ce\n  0x0000,0x0000,0x3300,0x3300,0x0000,0x0000,0x3f00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x3f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00cf\n  0x0000,0x0000,0x7e00,0x6300,0x6180,0x6180,0x6180,0x6180,0xf980,0x6180,0x6180,0x6180,0x6180,0x6300,0x7e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00d0\n  0x0000,0x0000,0x1900,0x3f00,0x2600,0x0000,0x4180,0x6180,0x7180,0x7980,0x7d80,0x6f80,0x6780,0x6380,0x6180,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00d1\n  0x0000,0x0000,0x3000,0x1800,0x0c00,0x0000,0x1e00,0x3300,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00d2\n  0x0000,0x0000,0x0300,0x0600,0x0c00,0x0000,0x1e00,0x3300,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00d3\n  0x0000,0x0000,0x0c00,0x1e00,0x3300,0x0000,0x1e00,0x3300,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00d4\n  0x0000,0x0000,0x1900,0x3f00,0x2600,0x0000,0x1e00,0x3300,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00d5\n  0x0000,0x0000,0x3300,0x3300,0x0000,0x0000,0x1e00,0x3300,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00d6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2080,0x3180,0x1b00,0x0e00,0x0e00,0x1b00,0x3180,0x2080,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00d7\n  0x0000,0x0080,0x1f00,0x3300,0x6380,0x6380,0x6580,0x6580,0x6580,0x6980,0x6980,0x6980,0x7180,0x3300,0x3e00,0x4000,\n  0x0000,0x0000,0x0000,0x0000, // u00d8\n  0x0000,0x0000,0x3000,0x1800,0x0c00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00d9\n  0x0000,0x0000,0x0300,0x0600,0x0c00,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00da\n  0x0000,0x0000,0x0c00,0x1e00,0x3300,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3380,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00db\n  0x0000,0x0000,0x3300,0x3300,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00dc\n  0x0000,0x0000,0x0300,0x0600,0x0c00,0x0000,0x4080,0x6180,0x3300,0x1e00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00dd\n  0x0000,0x0000,0x0000,0x0000,0x3c00,0x1800,0x1f00,0x1980,0x1980,0x1980,0x1f00,0x1800,0x1800,0x1800,0x3c00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00de\n  0x0000,0x0000,0x0000,0x1c00,0x3e00,0x7300,0x6300,0x6300,0x6600,0x6c00,0x6600,0x6300,0x6100,0x6300,0x6e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00df\n  0x0000,0x0000,0x3000,0x1800,0x0c00,0x0000,0x0000,0x3f00,0x6180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x3e80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00e0\n  0x0000,0x0000,0x0600,0x0c00,0x1800,0x0000,0x0000,0x3f00,0x6180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x3e80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00e1\n  0x0000,0x0000,0x0c00,0x1e00,0x3300,0x0000,0x0000,0x3f00,0x6180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x3e80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00e2\n  0x0000,0x0000,0x1900,0x3f00,0x2600,0x0000,0x0000,0x3f00,0x6180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x3e80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00e3\n  0x0000,0x0000,0x3300,0x3300,0x0000,0x0000,0x0000,0x3f00,0x6180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x3e80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00e4\n  0x0000,0x0000,0x0000,0x0c00,0x1200,0x1200,0x0c00,0x3f00,0x6180,0x0180,0x3f80,0x6180,0x6180,0x6180,0x3e80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00e5\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3b00,0x4d80,0x0d80,0x0f00,0x3c00,0x6c00,0x6c80,0x3700,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00e6\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1f00,0x3180,0x6000,0x6000,0x6000,0x6000,0x3180,0x1f00,0x0c00,\n  0x0400,0x1200,0x0c00,0x0000, // u00e7\n  0x0000,0x0000,0x3000,0x1800,0x0c00,0x0000,0x0000,0x1e00,0x3300,0x6180,0x7f80,0x6000,0x6000,0x3180,0x1f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00e8\n  0x0000,0x0000,0x0600,0x0c00,0x1800,0x0000,0x0000,0x1e00,0x3300,0x6180,0x7f80,0x6000,0x6000,0x3180,0x1f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00e9\n  0x0000,0x0000,0x0c00,0x1e00,0x3300,0x0000,0x0000,0x1e00,0x3300,0x6180,0x7f80,0x6000,0x6000,0x3180,0x1f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00ea\n  0x0000,0x0000,0x3300,0x3300,0x0000,0x0000,0x0000,0x1e00,0x3300,0x6180,0x7f80,0x6000,0x6000,0x3180,0x1f00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00eb\n  0x0000,0x0000,0x3000,0x1800,0x0c00,0x0000,0x0000,0x3c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x7f80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00ec\n  0x0000,0x0000,0x0600,0x0c00,0x1800,0x0000,0x0000,0x3c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x7f80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00ed\n  0x0000,0x0000,0x0c00,0x1e00,0x3300,0x0000,0x0000,0x3c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x7f80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00ee\n  0x0000,0x0000,0x3300,0x3300,0x0000,0x0000,0x0000,0x3c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x0c00,0x7f80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00ef\n  0x0000,0x0000,0x4400,0x6c00,0x3800,0x3800,0x6c00,0x4600,0x1f00,0x3380,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00f0\n  0x0000,0x0000,0x1900,0x3f00,0x2600,0x0000,0x0000,0x6e00,0x7300,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00f1\n  0x0000,0x0000,0x3000,0x1800,0x0c00,0x0000,0x0000,0x1e00,0x3300,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00f2\n  0x0000,0x0000,0x0600,0x0c00,0x1800,0x0000,0x0000,0x1e00,0x3300,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00f3\n  0x0000,0x0000,0x0c00,0x1e00,0x3300,0x0000,0x0000,0x1e00,0x3300,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00f4\n  0x0000,0x0000,0x1900,0x3f00,0x2600,0x0000,0x0000,0x1e00,0x3300,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00f5\n  0x0000,0x0000,0x3300,0x3300,0x0000,0x0000,0x0000,0x1e00,0x3300,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00f6\n  0x0000,0x0000,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0000,0x7f80,0x7f80,0x0000,0x0000,0x0c00,0x0c00,0x0000,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00f7\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0080,0x1f00,0x3300,0x6580,0x6580,0x6980,0x6980,0x3300,0x3e00,0x4000,\n  0x0000,0x0000,0x0000,0x0000, // u00f8\n  0x0000,0x0000,0x3000,0x1800,0x0c00,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3380,0x1d80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00f9\n  0x0000,0x0000,0x0600,0x0c00,0x1800,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3380,0x1d80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00fa\n  0x0000,0x0000,0x0c00,0x1e00,0x3300,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3380,0x1d80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00fb\n  0x0000,0x0000,0x3300,0x3300,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3380,0x1d80,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00fc\n  0x0000,0x0000,0x0600,0x0c00,0x1800,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x3380,0x1d80,0x0180,\n  0x6180,0x3300,0x1e00,0x0000, // u00fd\n  0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3800,0x1e00,0x1b00,0x1b00,0x1e00,0x1800,0x1800,0x3800,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u00fe\n  0x0000,0x0000,0x3300,0x3300,0x0000,0x0000,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x3380,0x1d80,0x0180,\n  0x6180,0x3300,0x1e00,0x0000, // u00ff\n  0x0000,0x0000,0x1980,0x3300,0x6600,0x0000,0x1e00,0x3300,0x6180,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0150\n  0x0000,0x0000,0x1980,0x3300,0x6600,0x0000,0x0000,0x1e00,0x3300,0x6180,0x6180,0x6180,0x6180,0x3300,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0151\n  0x0000,0x0000,0x1980,0x3300,0x6600,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3380,0x1e00,0x0000,\n  0x0000,0x0000,0x0000,0x0000, // u0170\n  0x0000,0x0000,0x1980,0x3300,0x6600,0x0000,0x0000,0x6180,0x6180,0x6180,0x6180,0x6180,0x6180,0x3380,0x1d80,0x0000,\n  0x0000,0x0000,0x0000,0x0000 // u0171\n  };\n  // codepoints array\n  constexpr std::array<uint16_t, CHARCOUNT> fixedfont_codepoints = {\n  0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f,\n  0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f,\n  0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f,\n  0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f,\n  0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f,\n  0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f,\n  0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af,\n  0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf,\n  0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf,\n  0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df,\n  0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef,\n  0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff,\n  0x0150,0x0151,0x0170,0x0171 };\n} // namespace\n// -- end of autogenerated text ---\n\n// this font has no bold version, still make it available for bold=true\nnamespace fixed_font_info_h_bold {\n  // -- start of autogenerated text ---\n  // definition section for font: info_h\n  constexpr int CHARCOUNT = 196;\n  constexpr int WIDTH = 10;\n  constexpr int HEIGHT = 20;\n  constexpr int OFFSET_X = 0;\n  constexpr int OFFSET_Y = 0;\n  constexpr FixedFont_info_t fixedfont_info = {\n    \"info_h\", // font name\n    \"info_h\", // font name internal\n    CHARCOUNT, // num of chars\n    WIDTH, HEIGHT, OFFSET_X, OFFSET_Y,\n    true // bold\n  };\n  // font bitmap definitions\n  // same as non-bold\n  // codepoints array\n  // same as non-bold\n} // namespace\n// -- end of autogenerated text ---\n\n// Predefined fonts main table\nconst uint16_t* font_bitmaps[PREDEFINED_FONT_COUNT] =\n{\n  &fixed_font_12n::fixedfont_bitmap[0],\n  &fixed_font_12n::fixedfont_bitmap[0], // 12b: same as non-bold\n  &fixed_font_14n::fixedfont_bitmap[0],\n  &fixed_font_14b::fixedfont_bitmap[0],\n  &fixed_font_16n::fixedfont_bitmap[0],\n  &fixed_font_16b::fixedfont_bitmap[0],\n  &fixed_font_18n::fixedfont_bitmap[0],\n  &fixed_font_18b::fixedfont_bitmap[0],\n  &fixed_font_20n::fixedfont_bitmap[0],\n  &fixed_font_20b::fixedfont_bitmap[0],\n  &fixed_font_22n::fixedfont_bitmap[0],\n  &fixed_font_22b::fixedfont_bitmap[0],\n  &fixed_font_24n::fixedfont_bitmap[0],\n  &fixed_font_24b::fixedfont_bitmap[0],\n  &fixed_font_28n::fixedfont_bitmap[0],\n  &fixed_font_28b::fixedfont_bitmap[0],\n  &fixed_font_32n::fixedfont_bitmap[0],\n  &fixed_font_32b::fixedfont_bitmap[0],\n  &fixed_font_info_h::fixedfont_bitmap[0],\n  &fixed_font_info_h::fixedfont_bitmap[0], // same as non-bold\n};\n\nconst uint16_t* font_codepoints[PREDEFINED_FONT_COUNT] =\n{\n  &fixed_font_12n::fixedfont_codepoints[0],\n  &fixed_font_12n::fixedfont_codepoints[0], // same as non-bold\n  &fixed_font_14n::fixedfont_codepoints[0],\n  &fixed_font_14b::fixedfont_codepoints[0],\n  &fixed_font_16n::fixedfont_codepoints[0],\n  &fixed_font_16b::fixedfont_codepoints[0],\n  &fixed_font_18n::fixedfont_codepoints[0],\n  &fixed_font_18b::fixedfont_codepoints[0],\n  &fixed_font_20n::fixedfont_codepoints[0],\n  &fixed_font_20b::fixedfont_codepoints[0],\n  &fixed_font_22n::fixedfont_codepoints[0],\n  &fixed_font_22b::fixedfont_codepoints[0],\n  &fixed_font_24n::fixedfont_codepoints[0],\n  &fixed_font_24b::fixedfont_codepoints[0],\n  &fixed_font_28n::fixedfont_codepoints[0],\n  &fixed_font_28b::fixedfont_codepoints[0],\n  &fixed_font_32n::fixedfont_codepoints[0],\n  &fixed_font_32b::fixedfont_codepoints[0],\n  &fixed_font_info_h::fixedfont_codepoints[0],\n  &fixed_font_info_h::fixedfont_codepoints[0], // same as non-bold\n};\n\nconst FixedFont_info_t* font_infos[PREDEFINED_FONT_COUNT] =\n{\n  &fixed_font_12n::fixedfont_info,\n  &fixed_font_12b::fixedfont_info, // report as bold\n  &fixed_font_14n::fixedfont_info,\n  &fixed_font_14b::fixedfont_info,\n  &fixed_font_16n::fixedfont_info,\n  &fixed_font_16b::fixedfont_info,\n  &fixed_font_18n::fixedfont_info,\n  &fixed_font_18b::fixedfont_info,\n  &fixed_font_20n::fixedfont_info,\n  &fixed_font_20b::fixedfont_info,\n  &fixed_font_22n::fixedfont_info,\n  &fixed_font_22b::fixedfont_info,\n  &fixed_font_24n::fixedfont_info,\n  &fixed_font_24b::fixedfont_info,\n  &fixed_font_28n::fixedfont_info,\n  &fixed_font_28b::fixedfont_info,\n  &fixed_font_32n::fixedfont_info,\n  &fixed_font_32b::fixedfont_info,\n  &fixed_font_info_h::fixedfont_info,\n  &fixed_font_info_h_bold::fixedfont_info, // report as bold\n};\n\n"
  },
  {
    "path": "avs_core/core/fonts/fixedfonts.h",
    "content": "#ifndef __FIXEDFONTS_H__\n#define __FIXEDFONTS_H__\n\n#include <cstdint>\n\ntypedef struct {\n  const char* const fontname;\n  const char* const fontname_internal;\n  int charcount;\n  uint8_t width; // like in global FONTBOUNDINGBOX\n  uint8_t height;\n  int8_t offset_x;\n  int8_t offset_y;\n  bool bold;\n} FixedFont_info_t;\n\nconstexpr int PREDEFINED_FONT_COUNT = 18 + 2; // 2x9 Terminus + info_h\n\n#endif  // __FIXEDFONTS_H__\n"
  },
  {
    "path": "avs_core/core/function.h",
    "content": "#pragma once\n\n#include <avisynth.h>\n\nstruct Function {\n\n  typedef AVSValue(__cdecl *apply_func_t)(AVSValue args, void* user_data, IScriptEnvironment* env);\n\n  apply_func_t apply;\n  const char* name;\n  const char* canon_name;\n  const char* param_types;\n  void* user_data;\n  const char* dll_path;\n  // can be filled during plugin load:\n  bool isPluginAvs25;\n  bool isPluginPreV11C;\n};\n\nstruct CaptureVars {\n  int count;\n  const char** var_names;\n  const AVSValue* var_data;\n};\n\nclass IFunction {\npublic:\n  IFunction() : refcnt(0) {}\n  virtual ~IFunction() { }\n  virtual const char* ToString(IScriptEnvironment* env) = 0;\n  virtual const char* GetLegacyName() = 0;\n  virtual const Function* GetDefinition() = 0;\n  virtual CaptureVars GetCaptures() = 0;\n\nprivate:\n  friend class PFunction;\n  friend class AVSValue;\n  unsigned long refcnt;\n  void AddRef();\n  void Release();\n};\n\n\nclass AVSFunction : public Function {\n\npublic:\n\n  typedef Function::apply_func_t apply_func_t;\n\n  AVSFunction(void*);\n  AVSFunction(const char* _name, const char* _plugin_basename, const char* _param_types, apply_func_t _apply);\n  AVSFunction(const char* _name, const char* _plugin_basename, const char* _param_types, apply_func_t _apply, void *_user_data);\n  AVSFunction(const char* _name, const char* _plugin_basename, const char* _param_types, apply_func_t _apply, void *_user_data, const char* _dll_path, \n    bool _isPluginAvs25, \n    bool _isPluginPreV11C);\n  ~AVSFunction();\n\n  AVSFunction() = delete;\n  AVSFunction(const AVSFunction&) = delete;\n  AVSFunction& operator=(const AVSFunction&) = delete;\n  AVSFunction(AVSFunction&&) = delete;\n  AVSFunction& operator=(AVSFunction&&) = delete;\n\n  bool empty() const;\n\n  static bool IsScriptFunction(const Function* func);\n  static bool ArgNameMatch(const char* param_types, size_t args_names_count, const char* const* arg_names);\n  static bool TypeMatch(const char* param_types, const AVSValue* args, size_t num_args, bool strict, IScriptEnvironment* env);\n  static bool SingleTypeMatch(char type, const AVSValue& arg, bool strict);\n  static bool SingleTypeMatchArray(char type, const AVSValue& arg, bool strict);\n};\n"
  },
  {
    "path": "avs_core/core/info.cpp",
    "content": "// Avisynth+\n// https://avs-plus.net\n//\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// pinterf:\n// high bit depth, planar RGB\n// utf8 option, internally unicode\n// info_h font definition reorganized, Latin-1 Supplement 00A0-00FF\n// Configurable color\n// Configurable halocolor (text outline)\n// Configurable background fading\n// Alignment\n// multiline\n// multiple size, multiple fonts, \"Terminus\", \"info_h\"\n// chroma location, overlay-like weighted chroma handling\n\n#include \"info.h\"\n#include <cstring>\n#include <sstream>\n#include <fstream>\n#include <unordered_map>\n#include <array>\n#include <iomanip>\n#include <avs/filesystem.h>\n\n#include <locale>\n#include <cstdio>\n#include <cassert>\n#include \"fonts/fixedfonts.h\"\n#include \"strings.h\"\n#include \"../convert/convert_helper.h\"\n\n// helper function for remapping an utf8 string to font index entry list\nstd::vector<int> BitmapFont::remap(const std::string& s_utf8)\n{\n  // new vector with characters remapped to font table indexes\n  std::vector<int> s_remapped;\n  const size_t real_len = str_utf8_size(s_utf8);\n  s_remapped.resize(real_len);\n\n  size_t index = 0;\n  const char* p = s_utf8.data();\n  const char* end = p + s_utf8.size();\n  while (p < end) {\n    // Get the lead byte of the current UTF-8 character\n    unsigned char lb = static_cast<unsigned char>(*p);\n    // Determine the number of bytes in the current UTF-8 character\n    int n = 0;\n    if ((lb & 0x80) == 0) n = 1; // 0xxxxxxx\n    else if ((lb & 0xE0) == 0xC0) n = 2; // 110xxxxx\n    else if ((lb & 0xF0) == 0xE0) n = 3; // 1110xxxx\n    else if ((lb & 0xF8) == 0xF0) n = 4; // 11110xxx\n    else {\n      // Invalid lead byte, skip\n      ++p;\n      continue;\n    }\n    // Create a buffer to store the UTF-8 character code\n    char utf8_char_buf[5] = { 0 };\n    // Copy the bytes from the string to the buffer\n    std::memcpy(utf8_char_buf, p, n);\n    // finds by utf8 character sequence in font index table\n    auto it = charReMapUtf8.find(utf8_char_buf);\n    if (it != charReMapUtf8.end())\n      s_remapped[index] = it->second;\n    else\n      s_remapped[index] = 0; // empty neutral character (space)\n    index++;\n    // Advance the pointer by the number of bytes\n    p += n;\n  }\n  return s_remapped;\n}\n\n// Internal function! For creating source code from a previously LoadBDF'd font file\n// see fixedfonts.cpp\nvoid BitmapFont::SaveAsC(const uint16_t* _codepoints)\n{\n  if (font_filename == \"\") return; // no GUS no sound :)\n\n  std::string fontname;\n  if (font_filename.substr(0, 4) == \"ter-\")\n    font_name = \"Terminus\";\n  else\n    font_name = font_filename;\n\n  std::ostringstream ss;\n  ss << \"namespace fixed_font_# {\" << std::endl;\n  ss << \"// -- start of autogenerated text ---\" << std::endl;\n  ss << \"// definition section for font: \" << font_filename << std::endl;\n  ss << \"constexpr int CHARCOUNT = \" << std::to_string(number_of_chars) << \";\" << std::endl;\n  ss << \"constexpr int WIDTH = \" << std::to_string(global_bbx.width) << \";\" << std::endl;\n  ss << \"constexpr int HEIGHT = \" << std::to_string(global_bbx.height) << \";\" << std::endl;\n  ss << \"constexpr int OFFSET_X = \" << std::to_string(global_bbx.offset_x) << \";\" << std::endl;\n  ss << \"constexpr int OFFSET_Y = \" << std::to_string(global_bbx.offset_y) << \";\" << std::endl;\n  ss << \"constexpr FixedFont_info_t fixedfont_info = {\" << std::endl;\n  ss << \"  \\\"\" << font_filename << \"\\\", // font name\" << std::endl;\n  ss << \"  \\\"\" << font_filename << \"\\\", // font name internal\" << std::endl;\n  ss << \"  CHARCOUNT, // num of chars\" << std::endl;\n  ss << \"  WIDTH, HEIGHT, OFFSET_X, OFFSET_Y,\" << std::endl;\n  ss << \"  \" << (bold ? \"true\" : \"false\") << \" // bold\" << std::endl;\n  ss << \"};\" << std::endl;\n  ss << \"// font bitmap definitions\" << std::endl;\n  ss << \"constexpr std::array<uint16_t, CHARCOUNT * HEIGHT> fixedfont_bitmap = {\" << std::endl;\n  for (int charcount = 0; charcount < number_of_chars; charcount++)\n  {\n    constexpr int LINES_BY_N = 16; // maximum number of constants per line\n    for (int y = 0; y < global_bbx.height; y++) {\n      ss << \"0x\";\n      for (int x = 0; x < fontline_bytes; x++) {\n        uint8_t charline = font_bitmaps[(charcount * global_bbx.height + y) * fontline_bytes + x];\n        ss << std::setfill('0') << std::setw(2) << std::hex << charline;\n      }\n      const bool last = charcount == number_of_chars - 1 && y == global_bbx.height - 1;\n      if (!last) ss << \",\";\n      if (y == global_bbx.height - 1)\n        ss << \" // u\" << std::setw(4) << std::hex << _codepoints[charcount];\n      if (y % LINES_BY_N == LINES_BY_N - 1) ss << std::endl; // last line of character- forced new line\n    }\n    if (global_bbx.height % LINES_BY_N != 0)\n      ss << std::endl;\n  };\n  // example output:\n  // 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,\n  // 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0020\n  // 0x0000,0x0000,0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,0x0300,\n  // 0x0000,0x0000,0x0300,0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, // u0021\n\n  ss << \"};\" << std::endl;\n  ss << \"// codepoints array\" << std::endl;\n  ss << \"constexpr std::array<uint16_t, CHARCOUNT> fixedfont_codepoints = {\" << std::endl;\n  for (int charcount = 0; charcount < number_of_chars; charcount++)\n  {\n    constexpr int LINES_BY_N = 16;\n    int val = _codepoints[charcount];\n    ss << \"0x\" << std::setfill('0') << std::setw(4) << std::hex << val;\n    const bool last = charcount == number_of_chars - 1;\n    if (!last) ss << \",\";\n    if (charcount % LINES_BY_N == LINES_BY_N - 1) ss << std::endl;\n  }\n  ss << \"};\" << std::endl;\n\n  ss << \"} // namespace\" << std::endl;\n  ss << \"// -- end of autogenerated text ---\" << std::endl;\n  //\n  std::ofstream outFile(font_filename + \".cpp_sample\");\n  outFile << ss.str();\n  outFile.close();\n\n  /* usage:\n  // Predefined fonts main table\n  constexpr int PREDEFINED_FONT_COUNT = 2;\n  static const uint16_t* font_bitmaps[PREDEFINED_FONT_COUNT] =\n  {\n    &fixed_font_1::fixedfont_bitmap[0],\n    &fixed_font_2::fixedfont_bitmap[0]\n    // ...\n  };\n  static const uint16_t* font_codepoints[PREDEFINED_FONT_COUNT] =\n  {\n    &fixed_font_1::fixedfont_codepoints[0],\n    &fixed_font_2::fixedfont_codepoints[0]\n    // ...\n  };\n  static const FixedFont_info_t* font_infos[PREDEFINED_FONT_COUNT] =\n  {\n    &fixed_font_1::fixedfont_info,\n    &fixed_font_2::fixedfont_info\n    // ...\n  };\n  */\n}\n\ntypedef struct CharInfo { // STARTCHAR charname\n  std::string friendly_name;\n  uint16_t encoding;\n  int dwidth_x, dwidth_y;\n  // DWIDTH not supported, same as main PIXELSIZE\n  // font properties can be overridden.\n  BBX bbx;\n  int empty_lines_bottom;\n  int empty_lines_top;\n  int bits_to_shift;\n} CharDef;\n\ntypedef struct FontProperties {\n  std::string Copyright;\n  std::string Notice;\n  std::string Family_name;\n  std::string Weight_name;\n  int pixel_size;\n  int font_ascent; // 12\n  int font_descent; // 4\n  uint16_t default_char; // 65533\n} FontProperties;\n\ntypedef struct FontInfo {\n  std::string font; // n/a\n  int size_points, size_dpi_x, size_dpi_y; // n/a\n  // these may be overridden by individual characters.\n  BBX bbx; // FONTBOUNDINGBOX e.g. 8 16 0 -4\n  int chars; // number of characters\n  int fontline_bytes; // length of a single font line in the byte array\n} FontInfo;\n\nclass BdfFont {\npublic:\n  std::string font_filename;\n  FontInfo font_info;\n  FontProperties font_properties;\n  std::vector<uint16_t> codepoints_array;\n  std::vector<std::string> charnames_array;\n  // each character can have different bounding box dimensions from global one\n  std::vector<BBX> bbx_array;\n  // one character line is not limited to 16/32 pixels anymore:\n  std::vector<uint8_t> font_bitmaps;\n};\n\nstd::string UnQuote(std::string s) {\n  if (s.size() >= 2 && s.substr(0, 1) == \"\\\"\" && (s.substr(s.size() - 1, 1) == \"\\\"\"))\n    return s.substr(1,s.size()-2); // zero based\n  return s;\n}\n\nstatic void vector_shl(uint8_t* buf, const size_t size, const size_t bits) {\n  const size_t whole_chunks = bits / 8;\n\n  // more bits that size\n  if (whole_chunks >= size) {\n    memset(buf, 0, size);\n    return;\n  }\n\n  if (whole_chunks) {\n    memmove(buf, buf + whole_chunks, size - whole_chunks);\n    memset(buf + size - whole_chunks, 0, whole_chunks);\n  }\n\n  const uint8_t final_shift = bits % 8;\n\n  if (final_shift) {\n    const auto right = 8 - final_shift;\n    const size_t len = size - whole_chunks - 1;\n    for (size_t i = 0; i < len; i++) {\n      buf[i] = (buf[i] << final_shift) | (buf[i + 1] >> right);\n    }\n    buf[len] = buf[len] << final_shift;\n  }\n}\n\nstatic void vector_shr(uint8_t* buf, const size_t size, const size_t bits) {\n  const size_t whole_chunks = bits / 8;\n\n  // more bits that size\n  if (whole_chunks >= size) {\n    memset(buf, 0, size);\n    return;\n  }\n\n  if (whole_chunks) {\n    memmove(buf + whole_chunks, buf, size - whole_chunks);\n    memset(buf, 0, whole_chunks);\n  }\n\n  const uint8_t final_shift = bits % 8;\n\n  if (final_shift) {\n    const auto left = 8 - final_shift;\n    const size_t len = size - whole_chunks - 1;\n    auto index = size - 1;\n    for (size_t i = 0; i < len; i++) {\n      buf[index] = (buf[index] >> final_shift) | (buf[index - 1] << left);\n      index--;\n    }\n    buf[index] = buf[index] >> final_shift;\n  }\n}\n\nstatic BdfFont LoadBMF(std::string name, bool bold) {\n\n  // https://en.wikipedia.org/wiki/Glyph_Bitmap_Distribution_Format\n  // also for make cpp source code, see BdfFont methods\n\n  enum loadstate { ls_Init, ls_StartFont, ls_StartProperties, ls_Char };\n\n  BdfFont fnt;\n  CharInfo current_char;\n\n  std::string temp;\n  //std::ifstream ss(\"c:\\\\Download\\\\terminus-font-4.48\\\\terminus-font-4.48\\\\ter-u16n.bdf\");\n  std::ifstream ss;\n  // explicite font file name\n  auto fname = fs::path(name);\n\n  if (!fs::exists(name))\n    return fnt;\n\n  fnt.font_filename = fname.filename().generic_string();\n  ss.open(name);\n\n  loadstate state = ls_Init;\n\n  size_t line_counter = 0;\n  int char_counter = 0;\n\n  // make list governed by LF separator\n  while (std::getline(ss, temp, '\\n')) {\n    std::string token;\n    std::istringstream ssline(temp);\n\n    std::getline(ssline, token, ' ');\n\n    if (token.size() == 0) continue;\n\n    switch (state) {\n    case ls_Init:\n      if (token == \"STARTFONT\")\n        state = ls_StartFont;\n      else {\n        // unexpected token\n      }\n      break;\n    case ls_StartFont:\n      if (token == \"ENDFONT\") {\n        state = ls_Init;\n      }\n      else if (token == \"FONT\") {\n        // FONT-xos4-Terminus-Bold-R-Normal--16-160-72-72-C-80-ISO10646-1\n        std::getline(ssline, token, ' ');\n        fnt.font_info.font = UnQuote(token);\n      }\n      else if (token == \"SIZE\") {\n        // SIZE 16 72 72\n        // size in points, X and Y-axis resolution\n        std::getline(ssline, token, ' ');\n        fnt.font_info.size_points = std::stoi(token);\n        std::getline(ssline, token, ' ');\n        fnt.font_info.size_dpi_x = std::stoi(token);\n        std::getline(ssline, token, ' ');\n        fnt.font_info.size_dpi_y = std::stoi(token);\n      }\n      else if (token == \"FONTBOUNDINGBOX\") {\n        // FONTBOUNDINGBOX 8 16 0 -4\n        // bounding box of 8 pixels wide and 16 pixels high\n        // lower left hand corner starting at x=0, y=-4. Note that although the bounding box is defined to be a 8x16 cell,\n        // this can be overridden for individual glyphs.\n\n        // e.g: Terminus: FONTBOUNDINGBOX 8 16 0 -4   Terminus\n        // later for \"A\": BBX 8 16 0 -4\n        //      Unifont:  FONTBOUNDINGBOX 16 16 0 -2  Unifont\n        // later for \"A\": BBX 8 16 0 -2  should override the global bounding box\n\n        std::getline(ssline, token, ' ');\n        fnt.font_info.bbx.width = std::stoi(token);\n        std::getline(ssline, token, ' ');\n        fnt.font_info.bbx.height = std::stoi(token);\n        std::getline(ssline, token, ' ');\n        fnt.font_info.bbx.offset_x = std::stoi(token);\n        std::getline(ssline, token, ' ');\n        fnt.font_info.bbx.offset_y = std::stoi(token);\n\n        // a single font line can occupy variable amount of bytes depending on font width\n        // Note: in this implementation these global font dimensions are _the_\n        // dimensions of the fixed size font\n        // Note, that this is the maximum theoretical width; some BDF fonts (unifont) contain variable width characters\n        // contrary to that it contains monospaced \"C\" type characters. In this case latin characters are 8 pixels wide,\n        // and use DWIDTH and BBOX as 8, less than FONTBOUNDINGBOX value of 16.\n        // but CJK characters are 16 pixels wide.\n        fnt.font_info.fontline_bytes = (fnt.font_info.bbx.width + 7) / 8;\n      }\n      else if (token == \"STARTPROPERTIES\") {\n        // STARTPROPERTIES 20\n        // do not check line count now\n        state = ls_StartProperties;\n      }\n      else if (token == \"CHARS\") {\n        std::getline(ssline, token);\n        fnt.font_info.chars = std::stoi(token);\n        // allocate area for \"character_count\" * \"height\"\n        fnt.font_bitmaps.resize(fnt.font_info.chars * fnt.font_info.bbx.height * fnt.font_info.fontline_bytes);\n        fnt.charnames_array.resize(fnt.font_info.chars);\n        fnt.codepoints_array.resize(fnt.font_info.chars);\n        fnt.bbx_array.resize(fnt.font_info.chars);\n      }\n      else if (token == \"STARTCHAR\") {\n        std::getline(ssline, token);\n        current_char.friendly_name = token;\n        current_char.encoding = 0;\n        current_char.dwidth_x = 0;\n        current_char.dwidth_y = 0;\n        current_char.bbx = fnt.font_info.bbx; // inherited from FONTBOUNDINGBOX\n        current_char.bits_to_shift = 0;\n        current_char.empty_lines_bottom = 0;\n        current_char.empty_lines_top = 0;\n\n        state = ls_Char;\n      }\n      else {\n        // unexpected token\n      }\n      break;\n    case ls_StartProperties:\n      if (token == \"ENDPROPERTIES\") {\n        state = ls_StartFont;\n      }\n      /*\n      FAMILY_NAME \"Terminus\"\n        FOUNDRY \"xos4\"\n        SETWIDTH_NAME \"Normal\"\n        ADD_STYLE_NAME \"\"\n        COPYRIGHT \"Copyright (C) 2019 Dimitar Toshkov Zhekov\"\n        NOTICE \"Licensed under the SIL Open Font License, Version 1.1\"\n        WEIGHT_NAME \"Bold\"\n        SLANT \"R\"\n        PIXEL_SIZE 16\n        POINT_SIZE 160\n        RESOLUTION_X 72\n        RESOLUTION_Y 72\n        SPACING \"C\"\n        AVERAGE_WIDTH 80\n        CHARSET_REGISTRY \"ISO10646\"\n        CHARSET_ENCODING \"1\"\n        MIN_SPACE 8\n        */\n      else if (token == \"FAMILY_NAME\") {\n        //FAMILY_NAME \"Terminus\"\n        std::getline(ssline, token, ' ');\n        fnt.font_properties.Family_name = UnQuote(token);\n      }\n      else if (token == \"COPYRIGHT\") {\n        std::getline(ssline, token, ' ');\n        fnt.font_properties.Copyright = UnQuote(token);\n      }\n      else if (token == \"NOTICE\") {\n        std::getline(ssline, token, ' ');\n        fnt.font_properties.Notice = UnQuote(token);\n      }\n      else if (token == \"WEIGHT_NAME\") {\n        // \"Medium\", \"Bold\"\n        std::getline(ssline, token, ' ');\n        fnt.font_properties.Weight_name = UnQuote(token);\n      }\n      else if (token == \"PIXEL_SIZE\") {\n        std::getline(ssline, token, ' ');\n        fnt.font_properties.pixel_size = std::stoi(token);\n      }\n      else if (token == \"FONT_ASCENT\") {\n        // FONT_ASCENT 12\n        // 12 of the 16 pixels in height are above the baseline.\n        std::getline(ssline, token, ' ');\n        fnt.font_properties.font_ascent = std::stoi(token);\n      }\n      else if (token == \"FONT_DESCENT\") {\n        // FONT_DESCENT 4\n        // 4 of the 16 pixels in height are below the baseline\n        std::getline(ssline, token, ' ');\n        fnt.font_properties.font_descent = std::stoi(token);\n      }\n      else if (token == \"DEFAULT_CHAR\") {\n        // DEFAULT_CHAR 65533\n        std::getline(ssline, token, ' ');\n        fnt.font_properties.default_char = std::stoi(token);\n      }\n      break;\n    case ls_Char:\n      if (token == \"ENDCHAR\") {\n        // add to vector\n        state = ls_StartFont;\n      }\n      else if (token == \"DWIDTH\") {\n        // DWIDTH 9 0\n        // declares the Device Width of a glyph. After the glyph is rendered, the start of the next glyph is \n        // offset 9 pixels on the X-axis and \n        // offset 0 pixels on the Y-axis from the current glyph origin.\n        // They are not necessarily equal to the width of the glyph. \n        // It is simply the offset on the X-axis to move the current point to the start of the next glyph. \n        // dwidth_y is not used in Avisynth, fonts are of fixed heights\n        std::getline(ssline, token, ' ');\n        current_char.dwidth_x = std::stoi(token);\n        std::getline(ssline, token, ' ');\n        current_char.dwidth_y = std::stoi(token);\n      }\n      else if (token == \"ENCODING\") {\n        // ENCODING 32\n        std::getline(ssline, token, ' ');\n        current_char.encoding = std::stoi(token);\n      }\n      else if (token == \"BBX\") {\n        // BBX 8 16 0 -4 bounding box. 8 pixels wide and 16 pixels tall;\n        // lower left corner is offset by 0 on the X and -4 pixels on the Y axis.\n\n        // Originally we only assumed Monospaced, uniformly fixed size fonts.\n        // But technically we can have variable width characters inside due to per character BBOX.\n        // E.g. Latin characters usually have a DWIDTH of 8, while others like CJK Unifont\n        // characters have a DWIDTH of 16. (like U + 007F and CJK glyphs). Because of these\n        // wider characters, the FONTBOUNDINGBOX must be 16 pixels wide to signal the renderer\n        // the maximum possible width for the font type (useful for buffer preallocation). But\n        // ordinarly Latin characters are still 8 bits wide.\n        // So can we support \"fixed width\" fonts which contains character bitmaps of different widths.\n\n        std::getline(ssline, token, ' ');\n        current_char.bbx.width = std::stoi(token);\n        std::getline(ssline, token, ' ');\n        current_char.bbx.height = std::stoi(token);\n        std::getline(ssline, token, ' ');\n        current_char.bbx.offset_x = std::stoi(token);\n        std::getline(ssline, token, ' ');\n        current_char.bbx.offset_y = std::stoi(token);\n        current_char.empty_lines_bottom = current_char.bbx.offset_y - fnt.font_info.bbx.offset_y;\n        current_char.empty_lines_top = fnt.font_info.bbx.height - (current_char.empty_lines_bottom + current_char.bbx.height);\n        current_char.bits_to_shift = current_char.bbx.width - current_char.dwidth_x; // actual per-characer dwidth_x can differ from font_info.bbx.width\n      }\n      else if (token == \"BITMAP\") {\n        /* space:\n          STARTCHAR space\n          ENCODING 32\n          SWIDTH 692 0\n          DWIDTH 9 0\n          BBX 0 0 0 0\n          BITMAP\n          ENDCHAR\n\n          or\n\n          6x12:\n          BITMAP\n          00\n          00\n          70\n          88\n          08\n          30\n          08\n          08\n          88\n          70\n          00\n          00\n          ENDCHAR\n\n          10x18:\n          BITMAP\n          0000\n          0000\n          0000\n          3F00\n          6180\n          6180\n          0180\n          0180\n          1F00\n          0180\n          0180\n          0180\n          6180\n          6180\n          3F00\n          0000\n          0000\n          0000\n          ENDCHAR\n        */\n        fnt.codepoints_array[char_counter] = current_char.encoding;\n        fnt.charnames_array[char_counter] = current_char.friendly_name;\n        fnt.bbx_array[char_counter] = current_char.bbx;\n        char_counter++;\n\n        // by spec: charlines are left aligned within byte boundaries\n\n        // fill empty top lines\n        for (int count = 0; count < current_char.empty_lines_top; count++) {\n          // fontline_bytes bytes per line\n          for(int i = 0; i < fnt.font_info.fontline_bytes; i++)\n            fnt.font_bitmaps[line_counter++] = 0;\n        }\n\n        // one character line is of (almost) arbitrary length, not limited to 16 or 32 bits\n        std::vector<uint8_t> charline_buffer(fnt.font_info.fontline_bytes);\n        const size_t linebuf_len = fnt.font_info.fontline_bytes;\n\n        for(int count = 0; count < current_char.bbx.height; count++)\n        {\n          std::getline(ss, temp);\n\n          size_t len = temp.length();\n          const size_t bytes_defined = len / 2;\n\n          if (len % 2) {\n            // weird, one byte must be defined on two hexadecimal characters\n            // FIXME: should give an error\n          }\n          if (bytes_defined > linebuf_len) {\n            // weird, more bytes defined that needed for the font width defined in the header\n            // FIXME: should give an error\n            len = linebuf_len * 2; // until then a safe limit\n          }\n          size_t buf_ctr = 0;\n          // two hex characters by two character then put into byte buffer\n          for (size_t i = 0; i < len; i += 2) {\n            auto ssss = temp.substr(i, 2); // next two hex chars\n            charline_buffer[buf_ctr++] = (uint8_t)std::stoul(ssss, nullptr, 16);\n          }\n          for (auto i = buf_ctr; i < linebuf_len; i++)\n            charline_buffer[i] = 0;\n\n          // shift full buffer, they are msb...lsb for increasing addresses\n          if (current_char.bits_to_shift < 0) {\n            const int bits_to_shift_left = -current_char.bits_to_shift;\n            vector_shl(charline_buffer.data(), fnt.font_info.fontline_bytes, bits_to_shift_left);\n          }\n          else if (current_char.bits_to_shift > 0) {\n            const int bits_to_shift_right = current_char.bits_to_shift;\n            vector_shr(charline_buffer.data(), fnt.font_info.fontline_bytes, bits_to_shift_right);\n          }\n\n          for(int i = 0; i < fnt.font_info.fontline_bytes; i++) {\n            fnt.font_bitmaps[line_counter++] = charline_buffer[i];\n          }\n        }\n\n        // fill empty bottom lines\n        for (int count = 0; count < current_char.empty_lines_bottom; count++) {\n          // fontline_bytes bytes per line\n          for (int i = 0; i < fnt.font_info.fontline_bytes; i++)\n            fnt.font_bitmaps[line_counter++] = 0;\n        }\n\n      }\n      break;\n    }\n  }\n\n  return fnt;\n}\n  /*\n\n  STARTFONT 2.1\n    FONT -xos4-Terminus-Bold-R-Normal--16-160-72-72-C-80-ISO10646-1\n    SIZE 16 72 72\n    FONTBOUNDINGBOX 8 16 0 -4\n\n    STARTPROPERTIES 20\n      FAMILY_NAME \"Terminus\"\n      FOUNDRY \"xos4\"\n      SETWIDTH_NAME \"Normal\"\n      ADD_STYLE_NAME \"\"\n      COPYRIGHT \"Copyright (C) 2019 Dimitar Toshkov Zhekov\"\n      NOTICE \"Licensed under the SIL Open Font License, Version 1.1\"\n      WEIGHT_NAME \"Bold\"\n      SLANT \"R\"\n      PIXEL_SIZE 16\n      POINT_SIZE 160\n      RESOLUTION_X 72\n      RESOLUTION_Y 72\n      SPACING \"C\"\n      AVERAGE_WIDTH 80\n      CHARSET_REGISTRY \"ISO10646\"\n      CHARSET_ENCODING \"1\"\n      MIN_SPACE 8\n      FONT_ASCENT 12\n      FONT_DESCENT 4\n      DEFAULT_CHAR 65533\n    ENDPROPERTIES\n\n    CHARS 1354\n\n    STARTCHAR space\n      ENCODING 32\n      SWIDTH 500 0\n      DWIDTH 8 0\n      BBX 8 16 0 -4\n      BITMAP\n      ...\n      00\n    ENDCHAR\n\n  ENDFONT\n  */\n\nstatic constexpr int ATA_LEFT = 1;\nstatic constexpr int ATA_RIGHT = 2;\nstatic constexpr int ATA_CENTER = 4;\n\nstatic constexpr int ATA_TOP = 8;\nstatic constexpr int ATA_BOTTOM = 16;\nstatic constexpr int ATA_BASELINE = 32;\n\nstatic int alignToBitmask(int align_1_to_9)\n{\n  // alignment 1-9: digit positions on numeric keypad\n  int al = 0;\n  switch (align_1_to_9) // This spec where [X, Y] is relative to the text (inverted logic)\n  {\n  case 1: al = ATA_BOTTOM | ATA_LEFT; break;     // .----\n  case 2: al = ATA_BOTTOM | ATA_CENTER; break;   // --.--\n  case 3: al = ATA_BOTTOM | ATA_RIGHT; break;    // ----.\n  case 4: al = ATA_BASELINE | ATA_LEFT; break;   // .____\n  case 5: al = ATA_BASELINE | ATA_CENTER; break; // __.__\n  case 6: al = ATA_BASELINE | ATA_RIGHT; break;  // ____.\n  case 7: al = ATA_TOP | ATA_LEFT; break;        // `----\n  case 8: al = ATA_TOP | ATA_CENTER; break;      // --`--\n  case 9: al = ATA_TOP | ATA_RIGHT; break;       // ----`\n  default: al = ATA_BASELINE | ATA_LEFT; break;  // .____\n  }\n  return al;\n}\n\nstatic int getColorForPlane(int plane, int color)\n{\n  switch (plane) {\n  case PLANAR_A:\n    return (color >> 24) & 0xff; break;\n  case PLANAR_R:\n  case PLANAR_Y:\n    return (color >> 16) & 0xff; break;\n  case PLANAR_G:\n  case PLANAR_U:\n    return (color >> 8) & 0xff; break;\n  case PLANAR_B:\n  case PLANAR_V:\n    return color & 0xff; break;\n  }\n  return color & 0xFF;\n}\n\ntemplate<typename pixel_t, bool fadeBackground>\nvoid AVS_FORCEINLINE LightOnePixelPackedRGB(const bool lightIt, BYTE* _dp, int val_color_R, int val_color_G, int val_color_B)\n{\n  pixel_t* dp = reinterpret_cast<pixel_t*>(_dp);\n  if (lightIt) {\n    dp[0] = val_color_B;\n    dp[1] = val_color_G;\n    dp[2] = val_color_R;\n  }\n  else {\n    if constexpr (fadeBackground) {\n      dp[0] = (pixel_t)((dp[0] * 7) >> 3);\n      dp[1] = (pixel_t)((dp[1] * 7) >> 3);\n      dp[2] = (pixel_t)((dp[2] * 7) >> 3);\n    }\n  }\n}\n\ntemplate<typename pixel_t, bool fadeBackground, bool isRGB>\nvoid AVS_FORCEINLINE LightOnePixel(const bool lightIt, pixel_t* dstp, int j, pixel_t& val_color, int bits_per_pixel)\n{\n  // some optimization hint\n  if constexpr (sizeof(pixel_t) == 1)\n    bits_per_pixel = 8;\n  else if constexpr (sizeof(pixel_t) == 4)\n    bits_per_pixel = 32;\n\n  if (lightIt) { // character definition bits aligned to msb\n    dstp[j] = val_color;\n  }\n  else {\n    // 16 = y_min\n    // speed optimization: one subtraction less, 5-8% faster\n    // (((Y - 16) * 7) >> 3) + 16 = ((Y * 7) >> 3) + 2\n    // in general: ((Y * 7) >> 3) + n, where n = range_min - ((range_min * 7) >> 3)\n    if constexpr (fadeBackground) {\n      // background darkening\n      if constexpr (isRGB) {\n        if constexpr (sizeof(pixel_t) != 4)\n          dstp[j] = (pixel_t)((dstp[j] * 7) >> 3);\n        else {\n          constexpr float factor = 7.0f / 8;\n          dstp[j] = (pixel_t)(dstp[j] * factor);\n        }\n      }\n      else {\n        if constexpr (sizeof(pixel_t) != 4) {\n          const int range_min = 16 << (bits_per_pixel - 8);\n          const int n = range_min - ((range_min * 7) >> 3);\n          dstp[j] = (pixel_t)(((dstp[j] * 7) >> 3) + n); // (_dstp[j] - range_min) * 7) >> 3) + range_min);\n        }\n        else {\n          constexpr float range_min_f = 16.0f / 255.0f;\n          dstp[j] = (pixel_t)(((dstp[j] - range_min_f) * 7 / 8) + range_min_f);\n        }\n      }\n    }\n  }\n}\n\ntemplate<typename pixel_t, int logXRatioUV, int logYRatioUV, bool fadeBackground, ChromaLocationMode chromaMode>\nstatic void LightOneUVPixel(pixel_t* dstpU, int j, pixel_t* dstpV, pixel_t& font_color_u, pixel_t& font_color_v, pixel_t& halo_color_u, pixel_t& halo_color_v,\n  int fontpixelcount, int halopixelcount,\n  int bits_per_pixel\n)\n{\n  if constexpr (!fadeBackground) {\n    if (halopixelcount == 0 && fontpixelcount == 0) return; // no change, keep background\n  }\n\n  // some optimization hint\n  if constexpr (sizeof(pixel_t) == 1)\n    bits_per_pixel = 8;\n  else if constexpr (sizeof(pixel_t) == 4)\n    bits_per_pixel = 32;\n\n  // weighed count\n  constexpr int totalpixelcount =\n    (chromaMode == LEFT_420) ? 8 : // 1-2-1 | 1-2-1\n    (chromaMode == LEFT_422) ? 4 : // 1-2-1\n    (chromaMode == CENTER_420) ? 4 : // 1-1 | 1-1\n    (chromaMode == CENTER_422) ? 2 : // 1-1\n    (chromaMode == CENTER_411) ? 4 : // 1-1-1-1\n    1; // unreached\n\n  if (fontpixelcount == totalpixelcount) {\n    dstpU[j] = font_color_u;\n    dstpV[j] = font_color_v;\n  }\n  else if (halopixelcount == totalpixelcount) {\n    dstpU[j] = halo_color_u;\n    dstpV[j] = halo_color_v;\n  }\n  else {\n    // not reached, only when subsampled\n    pixel_t actualU = dstpU[j];\n    pixel_t actualV = dstpV[j];\n    const int backgroundpixelcount = totalpixelcount - fontpixelcount - halopixelcount;\n\n    if constexpr (fadeBackground) {\n      // have to fade the existing background color\n      // speed optimization: one subtraction less\n      // (((U - 128) * 7) >> 3) + 128 = ((U * 7) >> 3) + 16\n      // in general: ((U * 7) >> 3) + n where n = range_half - ((range_half * 7) >> 3)\n      if constexpr (sizeof(pixel_t) != 4) {\n        int range_half = 1 << (bits_per_pixel - 1);\n        int n = range_half - ((range_half * 7) >> 3);\n        actualU = (pixel_t)(((actualU * 7) >> 3) + n); // ((((U - range_half) * 7) >> 3) + range_half);\n        actualV = (pixel_t)(((actualV * 7) >> 3) + n);\n      }\n      else {\n        constexpr float chroma_center = 0.0f; // ancient times this was 0.5\n        constexpr float factor = 7.0f / 8.0f;\n        actualU = (pixel_t)(((actualU - chroma_center) * factor) + chroma_center);\n        actualV = (pixel_t)(((actualV - chroma_center) * factor) + chroma_center);\n      }\n    }\n\n    // compute resulting color weighted by pixel kinds\n    if constexpr (sizeof(pixel_t) != 4) {\n      constexpr int rounder = totalpixelcount >> 1;\n      constexpr int divshift = \n        (chromaMode == LEFT_420) ? 3 :\n        (chromaMode == LEFT_422) ? 2 :\n        (chromaMode == CENTER_420) ? 2 :\n        (chromaMode == CENTER_422) ? 1 :\n        (chromaMode == CENTER_411) ? 2 :\n        0; // unreached\n\n      const int effective_color_u = (font_color_u * fontpixelcount + halo_color_u * halopixelcount + actualU * backgroundpixelcount + rounder);\n      const int effective_color_v = (font_color_v * fontpixelcount + halo_color_v * halopixelcount + actualV * backgroundpixelcount + rounder);\n      dstpU[j] = effective_color_u >> divshift;\n      dstpV[j] = effective_color_v >> divshift;\n    }\n    else {\n      constexpr float chroma_center = 0.0f;\n      float effective_color_u = (font_color_u - chroma_center) * fontpixelcount + (halo_color_u - chroma_center) * halopixelcount + (actualU - chroma_center) * backgroundpixelcount;\n      float effective_color_v = (font_color_v - chroma_center) * fontpixelcount + (halo_color_v - chroma_center) * halopixelcount + (actualV - chroma_center) * backgroundpixelcount;\n      dstpU[j] = effective_color_u / totalpixelcount + chroma_center;\n      dstpV[j] = effective_color_v / totalpixelcount + chroma_center;\n    }\n  }\n}\n\n// s (containing the indexes to the fontbitmap array) is modified in-place\nstatic void adjustWriteLimits(std::vector<int>& s, const std::vector<BBX>& bbx_array, const int vi_width, const int vi_height,\n  const int FONT_WIDTH_not_used, const int FONT_HEIGHT, \n  int align, \n  const bool useHalocolor,\n  int& x, int& y, int& len, int& startindex, int& xstart, int& ystart, int& yend)\n{\n  const int al = alignToBitmask(align);\n\n  // cannot calculate with len * FONT_WIDTH, because characters can have different widths\n  int total_width = 0;\n  for (int i = 0; i < len; i++) {\n    // bbx_array is the array of bounding boxes for each character\n    // s[i] is the index to the fontbitmap array\n    total_width += bbx_array[s[i]].width;\n  }\n\n  // alignment X\n  if (al & ATA_RIGHT)\n    x -= (total_width - 1);\n  else if (al & ATA_CENTER)\n    x -= (total_width / 2);\n\n  // alignment Y\n  if (al & ATA_BASELINE)\n    y -= FONT_HEIGHT / 2;\n  else if (al & ATA_BOTTOM)\n    y -= (FONT_HEIGHT - 1);\n\n  const int final_height = useHalocolor ? FONT_HEIGHT + 2 : FONT_HEIGHT;\n  if (useHalocolor) y = y - 1; // one more top line, adjust y (we do it after the alignment!)\n\n  // Chop text if exceed right margin\n  // keep last character of which at least one pixel can be drawn\n\n  // Fixed FONT_WIDTH calculation logic is replaced with logic which allows variable width characters\n  // Starting the truncation from the right side until the last character fits into the right margin, at least one pixel of it.\n  // bbx.width is the width of the character, not the whole font, this amount must be subtracted from the right margin.\n  while( total_width > vi_width - x + bbx_array[s[len - 1]].width && len > 0) {\n    // remove last character\n    len--;\n    total_width -= bbx_array[s[len]].width;\n  }\n  /* // old method left here intentionally:\n  if (len * FONT_WIDTH > width - x)\n    len = (width - x + FONT_WIDTH - 1) / FONT_WIDTH;\n  */\n\n  // FIXME: what if the character not, but its left side halo would be seen?\n\n  startindex = 0;\n  xstart = 0;\n  // Chop 1st char if exceed left margin\n  if (x < 0) {\n    // startindex is the first position in the string to be drawn\n    // Previously we had a global font-constant FONT_WIDTH, it was the same as x / FONT_WIDTH\n    // and the internal start position could be calculated as (-x) % FONT_WIDTH.\n    // Now that we allow that BDF originated characters can have different widths, we must\n    // calculate the startindex one-by-one from the left side.\n    while (startindex < len && x < 0) {\n      // s[startindex] is the index to the fontbitmap array\n      // bbx_array[s[startindex]].width is the width of the character\n      x += bbx_array[s[startindex]].width;\n      startindex++;\n    }\n    // x is the remaining negative offset, which is the start position of the first character\n    xstart = x; // this is the start position of the first character\n    // OLD method left here intentionally:\n    /*\n      startindex = (-x) / FONT_WIDTH;\n      xstart = (-x) % FONT_WIDTH;\n    */\n    x = 0;\n  }\n\n  ystart = 0;\n  yend = final_height;\n  // Chop font if exceed bottom margin\n  if (y > vi_height - final_height)\n    yend = vi_height - y;\n\n  // Chop font if exceed top margin\n  if (y < 0) {\n    ystart = -y;\n    y = 0;\n  }\n\n  // Roll in start index\n  if (startindex > 0) {\n    s.erase(s.begin(), s.begin() + startindex);\n    len -= startindex;\n  }\n}\n\n// Inserts leftmost 'bitcount' bits of fontlinebuf at the end of the byte buffer dst,\n// Target is the 'bitposition'th bit\nstatic void insert_from_msb_bit(uint8_t *dst, int bitposition, const uint8_t* fontlinebuf, int fontlinebuf_size, int bitcount)\n{\n  int pos = bitposition / 8;\n  int bitindex = bitposition % 8;\n  if (bitindex > 0) {\n    const int usable_msb_count = 8 - bitindex;\n    //                     mask       FF >> (bitindex)\n    // bitindex 1   mask = 10000000   01111111 \n    // bitindex 7   mask = 11111110   00000001\n    const uint8_t mask = (uint8_t)(0xFF >> bitindex); // leftmost (msb) N bits\n    const uint8_t partial_val = (uint8_t)((fontlinebuf[0] >> bitindex) & mask); // shift leftmost bits lsb\n    dst[pos++] |= partial_val; // or'd with existing\n\n    bitcount -= usable_msb_count;\n\n    // deal with shifted buffer from now on\n    int bufpos = 0;\n    while (bitcount > 0) {\n      uint8_t val;\n      if (bufpos <fontlinebuf_size - 1)\n        val = (fontlinebuf[bufpos] << usable_msb_count) | (fontlinebuf[bufpos + 1] >> (8 - usable_msb_count));\n      else \n        val = (fontlinebuf[bufpos] << usable_msb_count); // suppose that unused lsb bits were 0 in the end\n\n      // put actual byte into buffer\n      dst[pos++] = val;\n      bufpos++;\n      bitcount -= 8;\n    }\n    return;\n  }\n\n  int bufpos = 0;\n  while (bitcount > 0) {\n    // put actual byte into buffer\n    dst[pos++] = fontlinebuf[bufpos++]; // suppose that unused lsb bits were 0 in the end\n    bitcount -= 8;\n  }\n}\n\nstatic uint8_t get_bit(uint8_t* src, const int bitposition)\n{\n  int pos = bitposition / 8;\n  int bitindex = bitposition % 8;\n  const uint8_t mask = 1 << (7 - bitindex);\n  return src[pos] & mask;\n}\n\nstatic int get_bits(uint8_t* src, int bitposition, int count)\n{\n  int bitcounter = 0;\n  while (count--) {\n    if (0 != get_bit(src, bitposition++))\n      bitcounter++;\n  }\n  return bitcounter;\n}\n\nvoid PreRendered::make_outline() {\n  auto h = stringbitmap.size();\n  auto w = stringbitmap[0].size();\n\n  // circular line buffer for holding precalculated shifted lines\n  std::vector<uint8_t> buf1(w);\n  std::vector<uint8_t> buf2(w);\n  std::vector<uint8_t> buf3(w);\n\n  // it's unnecessary to mask the last byte against valid bitcounter, they won't drawn\n  // const uint8_t mask = ~(0xFF >> (8 - (bitcounter % 8)));\n\n  // shift a line left and rights and result is or'd\n  auto make_dizzyLR = [](uint8_t* dst, auto src, size_t w) {\n    if (w == 1)\n    {\n      *dst = (src[0] << 1) | (src[0] >> 1);\n      return;\n    }\n    // leftmost\n    uint8_t left = (src[0] << 1) | (src[1] >> (8 - 1));\n    uint8_t right = 0 | (src[0] >> 1);\n    *dst = left | right;\n    dst++;\n    src++;\n    // middle\n    for (size_t i = 1; i < w - 1; ++i)\n    {\n      left = (src[0] << 1) | (src[1] >> (8 - 1));\n      right = (src[-1] << (8 - 1)) | (src[0] >> 1);\n      *dst++ = left | right;\n      src++;\n    }\n    // rightmost\n    left = (src[0] << 1) | 0;\n    right = (src[-1] << (8 - 1)) | (src[0] >> 1);\n    *dst = left | right;\n    };\n\n#if defined(_MSC_VER) && _MSC_VER < 1944\n  // MSVC's optimizer fail (as of 17.8.4, release, optimize for speed, SSE2) would\n  // Workaround. Bad code generated. Compiler bug.\n  // Fixed (said) in 17.9 preview 3 (_MSC_VER 1939)\n  // Tested again in 17.14 (_MSC_VER 1944), it's OK.\n  // https://developercommunity.visualstudio.com/t/Bad-c-codegen-in-1784-x64-unless-se/10565370\n  volatile uint8_t* src_prev;\n  volatile uint8_t* src;\n#else\n  uint8_t* src_prev;\n  uint8_t* src;\n#endif\n  uint8_t* src_next;\n  uint8_t* dst;\n\n  uint8_t* tmp_line;\n  uint8_t* prev_line_LR = buf1.data();\n  uint8_t* curr_line_LR = buf2.data();\n  uint8_t* next_line_LR = buf3.data();\n\n  // line 0, no previous line\n  size_t y = 0;\n  dst = stringbitmap_outline[y].data();\n  src = stringbitmap[y].data();\n  src_next = stringbitmap[y + 1].data();\n  make_dizzyLR(curr_line_LR, src, w);\n  make_dizzyLR(next_line_LR, src_next, w);\n  for (size_t x = 0; x < w; x++) {\n    dst[x] = (curr_line_LR[x] | next_line_LR[x] | src_next[x]) & ~src[x];\n  }\n  tmp_line = prev_line_LR;\n  prev_line_LR = curr_line_LR;\n  curr_line_LR = next_line_LR;\n  next_line_LR = tmp_line;\n\n  src_prev = src;\n  src = src_next;\n  y++;\n\n  // middle lines, y runs on 1..(h-2)\n  for (; y < h - 1; y++)\n  {\n    dst = stringbitmap_outline[y].data();\n    src_next = stringbitmap[y + 1].data();\n    make_dizzyLR(next_line_LR, src_next, w);\n    for (size_t x = 0; x < w; x++) {\n      dst[x] = (prev_line_LR[x] | curr_line_LR[x] | next_line_LR[x] | src_prev[x] | src_next[x]) & ~src[x];\n    }\n    tmp_line = prev_line_LR;\n    prev_line_LR = curr_line_LR;\n    curr_line_LR = next_line_LR;\n    next_line_LR = tmp_line;\n    src_prev = src;\n    src = src_next;\n  }\n  // last one, no next line\n  dst = stringbitmap_outline[y].data();\n  for (size_t x = 0; x < w; x++) {\n    dst[x] = (prev_line_LR[x] | curr_line_LR[x] | src_prev[x]) & ~src[x];\n  }\n}\n\nPreRendered::PreRendered(\n  const uint8_t* fonts,\n  const int fontline_bytes_storage,\n  const int _vi_width, const int _vi_height, // from VideoInfo\n  int _x, int _y, // they may change\n  std::vector<int>& s,\n  // each character can have different width, variable bbx.width is used instead of font-level constant FONT_WIDTH\n  const std::vector<BBX>& bbx_array,\n  int align,\n  const bool _useHalocolor,\n\n  // Each character can have a different width; variable bbx.width is used instead of the font-level constant FONT_WIDTH.\n  //\n  // A BDF font can contain mixed sizes. The next two parameters (FONT_WIDTH, FONT_HEIGHT) represent the global maximum\n  // font size. A font file may contain per-character widths and heights in bbx_array.\n  //\n  // Regarding the wider spacing in Unifont:\n  // This is due to how FONTBOUNDINGBOX is interpreted during rendering. In Unifont's BDF header, FONTBOUNDINGBOX is set\n  // to 16 pixels wide. In earlier versions of Avisynth, having a BDF header with FONTBOUNDINGBOX set to 16 pixels wide\n  // globally caused all glyphs, regardless of their actual per-character width, to be rendered with 16-pixel spacing in\n  // Avisynth's Text() function. This resulted in visible gaps for narrower, 8-pixel wide Latin characters.\n  //\n  // While Unifont is conceptually monospaced, it technically includes variable-width glyphs.\n  // For example, Latin characters have DWIDTH 8, but others (like U+007F or CJK characters) use DWIDTH 16.\n  //\n  // Thus, the global FONTBOUNDINGBOX only specifies a maximum size for buffer allocation and must be 16 pixels wide.\n  // In a fully BDF-compliant renderer, the per-character DWIDTH and BBX values can override the global bounding box\n  // for spacing and alignment.\n  //\n  // Since Avisynth 3.7.6, the BDF renderer implements this override behavior.\n\n  const int FONT_WIDTH, const int FONT_HEIGHT,\n  const int _safety_bits_x_left,\n  const int _safety_bits_x_right\n  )\n  :\n  useHalocolor(_useHalocolor), vi_width(_vi_width), vi_height(_vi_height),\n  safety_bits_x_left(_safety_bits_x_left),\n  safety_bits_x_right(_safety_bits_x_right)\n{\n  len = (int)s.size();\n  x = _x;\n  y = _y;\n  xstart = 0;\n  ystart = 0;\n  yend = 0;\n  text_width = 0;\n\n  int startindex = 0;\n\n  // optional two additional lines for top and bottom for outline\n  stringbitmap_height = useHalocolor ? FONT_HEIGHT + 2 : FONT_HEIGHT;\n\n  adjustWriteLimits(s, // s is modified in-place\n    bbx_array,  // bounding boxes for each character\n    vi_width, vi_height,\n    FONT_WIDTH, // not used, bbx_array contains per-character widths, but must be passed\n    FONT_HEIGHT, // extra top and bottom for halo\n    align,\n    useHalocolor,\n    // adjusted parameters\n    x, y, len, startindex, xstart, ystart, yend\n    );\n\n  if (len <= 0)\n    return;\n\n  // prepare font mask and outline mask\n\n  // instead of FONT_WIDTH * len we have to calculate the total width of the string dynamically,\n  // because characters can have different widths, so we use bbx_array[s[i]].width\n  int total_font_width = 0;\n  for (int i = 0; i < len; i++) {\n    // bbx_array is the array of bounding boxes for each character\n    // s[i] is the index to the fontbitmap array\n    // total_font_width += bbx_array[s[i]].width;\n    total_font_width += bbx_array[s[i]].width; // this is the total width of the string\n  }\n\n  // left-right safety bits for horizontal subsampled cases\n  const int stringbitmap_width = safety_bits_x_left + total_font_width + (useHalocolor ? 2 : 0) + safety_bits_x_right;\n  const int stringbitmapline_bytes = (stringbitmap_width + 7) / 8;\n\n  // allocate actual space\n  stringbitmap.resize(stringbitmap_height);\n  for (auto& subarray : stringbitmap) subarray.resize(stringbitmapline_bytes);\n  if (useHalocolor) {\n    stringbitmap_outline.resize(stringbitmap_height);\n    for (auto& subarray : stringbitmap_outline) subarray.resize(stringbitmapline_bytes);\n  }\n\n  // fill matrix with fonts\n  // optionally leave spare left-right-top-bottom pixel lines for out-of-matrix halo pixels\n  // plus a final zero-cost bit column for safely drawing unaligned horizontal subsampling cases\n  uint8_t zerobyte[1] = { 0 };\n  int bitcounter = 0;\n\n  // safety columns for horizontal subsampling cases\n  // fill another column with 0\n  for (int ty = 0; ty < stringbitmap_height; ty++) {\n    insert_from_msb_bit(&stringbitmap[ty][0], bitcounter, &zerobyte[0], 1, safety_bits_x_left);\n  }\n  bitcounter += safety_bits_x_left;\n\n  if (useHalocolor) {\n    // fill leftmost 1 bitcolumn with 0\n    for (int ty = 0; ty < stringbitmap_height; ty++) {\n      uint8_t zerobyte[1] = { 0 };\n      insert_from_msb_bit(&stringbitmap[ty][0], 0, &zerobyte[0], 1, 1);\n    }\n    bitcounter++;\n  }\n\n  // if outline needed, leave place for top outline, copy actual character to the second row\n  const int ypos_of_char_in_bitmap = useHalocolor ? 1 : 0;\n\n  for (int i = 0; i < len; i++) {\n    int num = s[i];\n    int actual_font_width = bbx_array[num].width; // per character width, instead of font-level constant FONT_WIDTH;\n    const uint8_t* fontlinebuf = &fonts[num * FONT_HEIGHT * fontline_bytes_storage];\n    for (int ty = 0; ty < FONT_HEIGHT; ty++) {\n      // stuff FONT_WIDTH bits from fontline into bitcounter_th bit of target line\n      insert_from_msb_bit(&stringbitmap[ty + ypos_of_char_in_bitmap][0], bitcounter, fontlinebuf, fontline_bytes_storage, actual_font_width);\n      fontlinebuf += fontline_bytes_storage;\n    }\n    bitcounter += actual_font_width;\n  }\n  if (useHalocolor) {\n    // fill rightmost 'safety_bits' bitcolumn with 0\n    for (int ty = 0; ty < stringbitmap_height; ty++) {\n      insert_from_msb_bit(&stringbitmap[ty][0], bitcounter, &zerobyte[0], 1, 1);\n    }\n    bitcounter++;\n  }\n\n  // safety columns for horizontal subsampling cases\n  // fill another column with 0\n  for (int ty = 0; ty < stringbitmap_height; ty++) {\n    insert_from_msb_bit(&stringbitmap[ty][0], bitcounter, &zerobyte[0], 1, safety_bits_x_right);\n  }\n  bitcounter += safety_bits_x_right;\n\n  assert(bitcounter == stringbitmap_width);\n\n  if (useHalocolor)\n    make_outline();\n\n  // recalculate the text width with assuming variable character widths\n\n  // actual visible pixel count\n  // Instead of (len - 1) * FONT_WIDTH, we must calculate the text width based on the actual character widths\n  text_width = total_font_width - xstart;\n  if (x + text_width > vi_width) text_width -= (x + text_width - vi_width);\n\n  if (useHalocolor) {\n    // x was calculated w/o the extra left-right padding\n    xstart += 1; // worst case, skip leftmost extra halo column\n    if (x + xstart - 1 >= 0 && x > 0) {\n      x -= 1;\n      xstart -= 1;\n      text_width += 1;\n    }\n    // still good an increased text_width for last halo column?\n    if (x + text_width + 1 < vi_width)\n      text_width += 1;\n  }\n}\n\ntemplate<typename pixel_t>\nstatic auto getHBDColor_UV(int color, int bits_per_pixel)\n{\n  if (bits_per_pixel < 32)\n    return (pixel_t)(color << (bits_per_pixel - 8));\n  constexpr float shift = 0.0f;\n  return (pixel_t)((color - 128) / 255.0f + shift);\n  // FIXME: consistently using limited->fullscale conversion for float\n}\n\ntemplate<typename pixel_t>\nstatic auto getHBDColor_Y(int color, int bits_per_pixel)\n{\n  if (bits_per_pixel < 32)\n    return (pixel_t)(color << (bits_per_pixel - 8));\n  return (pixel_t)(color / 255.0f); // 0..255 -> 0..1.0\n  // FIXME: consistently using limited->fullscale conversion for float\n}\n\ntemplate<typename pixel_t>\nstatic auto getHBDColor_RGB(int color, int bits_per_pixel)\n{\n  if (bits_per_pixel <= 16) {\n    const int max_pixel_value = (1 << (bits_per_pixel & 31)) - 1;\n    return (pixel_t)((float)color * max_pixel_value / 255); // 0..255 --> 0..1023,4095,16383,65535\n  }\n  return (pixel_t)(color / 255.0f); // 0..255 -> 0..1.0\n}\n\n\ntemplate<typename pixel_t, bool useHalocolor, bool fadeBackground, bool isRGB>\nvoid Render1by1Planes(int bits_per_pixel, int color, int halocolor, int* pitches, BYTE** dstps, PreRendered& pre,\n  const int planeCount, const bool is444)\n{\n  // 1:1 planes, Y or planar RGB or 4:4:4 U/V\n\n  int planes_y[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };\n  int planes_r[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A };\n  int* planes = isRGB ? planes_r : planes_y;\n\n  for (int p = 0; p < planeCount; p++)\n  {\n    const int plane = planes[p];\n\n    if (!(isRGB || plane == PLANAR_Y || ((plane == PLANAR_U || plane == PLANAR_V) && is444)))\n      continue; // Y, R, G, B is O.K. U, V is OK if 444\n\n    pixel_t val_color;\n    pixel_t val_color_outline;\n\n    const int planecolor = getColorForPlane(plane, color);\n    const int planecolor_outline = getColorForPlane(plane, halocolor);\n    if (isRGB) {\n      val_color = getHBDColor_RGB<pixel_t>(planecolor, bits_per_pixel);\n      val_color_outline = getHBDColor_RGB<pixel_t>(planecolor_outline, bits_per_pixel);\n    }\n    else if (plane == PLANAR_U || plane == PLANAR_V) {\n      val_color = getHBDColor_UV<pixel_t>(planecolor, bits_per_pixel);\n      val_color_outline = getHBDColor_UV<pixel_t>(planecolor_outline, bits_per_pixel);\n    }\n    else {// Y\n      val_color = getHBDColor_Y<pixel_t>(planecolor, bits_per_pixel);\n      val_color_outline = getHBDColor_Y<pixel_t>(planecolor_outline, bits_per_pixel);\n    }\n\n    const int pitch = pitches[p];\n    BYTE* dstp = dstps[p] + pre.x * sizeof(pixel_t) + pre.y * pitch;\n\n    // Start rendering\n    for (int ty = pre.ystart; ty < pre.yend; ty++) {\n      pixel_t* _dstp = reinterpret_cast<pixel_t*>(dstp);\n      uint8_t* fontline_ptr = pre.stringbitmap[ty].data();\n      [[maybe_unused]] uint8_t* fontoutline_ptr;\n      if constexpr(useHalocolor)\n        fontoutline_ptr = pre.stringbitmap_outline[ty].data();\n      int j = 0;\n      const int shifted_xstart = pre.safety_bits_x_left + pre.xstart;\n      for (int tx = shifted_xstart; tx < shifted_xstart + pre.text_width; tx++)\n      {\n        const bool lightIt = 0 != get_bit(fontline_ptr, tx);\n        LightOnePixel<pixel_t, fadeBackground, isRGB>(lightIt, _dstp, j, val_color, bits_per_pixel);\n        if constexpr(useHalocolor) {\n          if (!lightIt)\n          {\n            const bool lightIt_outline = 0 != get_bit(fontoutline_ptr, tx);\n            LightOnePixel<pixel_t, fadeBackground, isRGB>(lightIt_outline, _dstp, j, val_color_outline, bits_per_pixel);\n          }\n        }\n        j += 1;\n      }\n      dstp += pitch;\n    }\n  }\n}\n\ntemplate<typename pixel_t, bool useHalocolor, bool fadeBackground, int logXRatioUV, int logYRatioUV, ChromaLocationMode chromaMode>\nvoid RenderUV(int bits_per_pixel, int color, int halocolor, int* pitches, BYTE** dstps, PreRendered& pre)\n{\n  // some optimization hint\n  if constexpr (sizeof(pixel_t) == 1)\n    bits_per_pixel = 8;\n  else if constexpr (sizeof(pixel_t) == 4)\n    bits_per_pixel = 32;\n\n  // draw U and V in one step\n  pixel_t color_u = getHBDColor_UV<pixel_t>(getColorForPlane(PLANAR_U, color), bits_per_pixel);\n  pixel_t color_v = getHBDColor_UV<pixel_t>(getColorForPlane(PLANAR_V, color), bits_per_pixel);\n  pixel_t color_outline_u = getHBDColor_UV<pixel_t>(getColorForPlane(PLANAR_U, halocolor), bits_per_pixel);\n  pixel_t color_outline_v = getHBDColor_UV<pixel_t>(getColorForPlane(PLANAR_V, halocolor), bits_per_pixel);\n\n  const int pitchUV = pitches[1];\n  const int offset = (pre.x >> logXRatioUV) * sizeof(pixel_t) + (pre.y >> logYRatioUV) * pitchUV;\n  BYTE* dstpU = dstps[1] + offset;\n  BYTE* dstpV = dstps[2] + offset;\n\n  // .SubS = 1, 2 or 4\n  constexpr int xSubS = 1 << logXRatioUV;\n  constexpr int ySubS = 1 << logYRatioUV;\n\n  /*\n    U and V handling, multiple luma/outline/background source for a given chroma point\n    resulting chroma is a weighted sum of the three pixel kinds (font/outline/background)\n    012345678901\n    ...#OOO#....\n    ..#O###O#...\n    ..#O#.#O#...\n    ..#O#.#O#...\n    ..#O#.#O#...\n  */\n\n  // unaligned x: for horizontal subsampling 420, 422 and 411:\n  // 420, 422, 411 horizontal subsampling: one more loop because of the leftmost orphan pixel(s)\n  // we can overaddress on the right, additional safety bit column(s) were added for the bitmap\n  const bool unaligned_x_start = logXRatioUV > 0 && 0 != pre.x % xSubS;\n  const int xplus = unaligned_x_start ? xSubS : 0; // extra orphan bits affecting rightmost chroma\n  const int xshift = pre.x % xSubS; // when aligned --> 0\n  // unaligned y: vertical subsampling 420\n  const bool odd_y_start = logYRatioUV == 1 && 0 != pre.y % 2;\n  const int yshift = odd_y_start ? 1 : 0;\n\n  constexpr bool hasVerticalSubsample = logYRatioUV > 0;\n\n  // safe zero array for vertical subsampled 4:2:0 case for orphan top/bottom\n  std::vector<uint8_t> zeros;\n  if constexpr (hasVerticalSubsample)\n    zeros.resize(pre.stringbitmap[0].size());\n\n  // second array element is only valid for vertically subsampled 4:2:0\n  uint8_t* fontlines_ptr[2] = { nullptr };\n  uint8_t* fontoutlines_ptr[2] = { nullptr };\n\n  for (int ty = pre.ystart; ty < pre.yend; ty += ySubS) {\n\n    pixel_t* _dstpU = reinterpret_cast<pixel_t*>(dstpU);\n    pixel_t* _dstpV = reinterpret_cast<pixel_t*>(dstpV);\n\n    if (hasVerticalSubsample && odd_y_start && ty == pre.ystart) {\n      // top font line on odd y position + vertically subsampled (420)\n      fontlines_ptr[0] = zeros.data();\n      fontlines_ptr[1] = pre.stringbitmap[ty].data();\n      if constexpr(useHalocolor) {\n        fontoutlines_ptr[0] = zeros.data();\n        fontoutlines_ptr[1] = pre.stringbitmap_outline[ty].data();\n      }\n    }\n    else if (hasVerticalSubsample && ty + 1 - yshift >= pre.stringbitmap_height) {\n      // bottom font line on even y position\n      fontlines_ptr[0] = pre.stringbitmap[ty - yshift].data();\n      fontlines_ptr[1] = zeros.data();\n      if constexpr(useHalocolor) {\n        fontoutlines_ptr[0] = pre.stringbitmap_outline[ty - yshift].data();\n        fontoutlines_ptr[1] = zeros.data();\n      }\n    }\n    else {\n      // all font lines contributing to chroma can safely be used\n      for (int m = 0; m < ySubS; m++)\n        fontlines_ptr[m] = pre.stringbitmap[ty + m - yshift].data();\n\n      if constexpr(useHalocolor) {\n        for (int m = 0; m < ySubS; m++)\n          fontoutlines_ptr[m] = pre.stringbitmap_outline[ty + m - yshift].data();\n      }\n    }\n\n    // render a horizontal line\n    int j = 0;\n    // (pre.xstart - xshift) is always on horizontal subsample boundary\n    const int shifted_xstart = pre.safety_bits_x_left + pre.xstart - xshift;\n\n    // left (mpeg2) location: \n    int fontpixels_right = 0; // used for left (mpeg2) chroma location case\n    int halopixels_right = 0;\n    // For the very first chroma pixel there is no previous rightside.\n    // Use index -1, safe because of safety columns\n    if constexpr (chromaMode == LEFT_420 || chromaMode == LEFT_422) {\n      for (int yy = 0; yy < ySubS; yy++) {\n        fontpixels_right += get_bits(fontlines_ptr[yy], shifted_xstart - 1, 1);\n        if constexpr (useHalocolor)\n          halopixels_right += get_bits(fontoutlines_ptr[yy], shifted_xstart - 1, 1);\n      }\n    }\n\n    for (int tx = shifted_xstart; tx < shifted_xstart + pre.text_width + xplus; tx += xSubS) {\n      int fontpixels = 0;\n      int halopixels = 0;\n\n      // 411\n      // +------+------+------+------+\n      // | 0.25 | 0.25 | 0.25 | 0.25 |\n      // +------+------+------+------+\n      // 420 center (mpeg1, jpeg)\n      // +------+------+\n      // | 0.25 | 0.25 |\n      // |------+------|\n      // | 0.25 | 0.25 |\n      // +------+------+\n      // 422 center\n      // +------+------+\n      // | 0.5  | 0.5  |\n      // +------+------+\n      // 420 left (mpeg2)\n      // ------+------+-------+\n      // 0.125 | 0.25 | 0.125 |\n      // ------|------+-------|\n      // 0.125 | 0.25 | 0.125 |\n      // ------+------+-------+\n      // 422 left (mpeg2)\n      // ------+------+-------+\n      // 0.25  | 0.5  | 0.25  |\n      // ------+------+-------+\n\n      if constexpr (chromaMode == LEFT_420 || chromaMode == LEFT_422) {\n        int fontpixels_left = 0;\n        int halopixels_left = 0;\n        int fontpixels_mid = 0;\n        int halopixels_mid = 0;\n\n        // shift variables\n        fontpixels_left = fontpixels_right;\n        if constexpr (useHalocolor)\n          halopixels_left = halopixels_right;\n        // gather counts\n        fontpixels_mid = get_bits(fontlines_ptr[0], tx, 1);\n        fontpixels_right = get_bits(fontlines_ptr[0], tx + 1, 1);\n        if constexpr (useHalocolor) {\n          halopixels_mid = get_bits(fontoutlines_ptr[0], tx, 1);\n          halopixels_right = get_bits(fontoutlines_ptr[0], tx + 1, 1);\n        }\n        if constexpr (chromaMode == LEFT_420) {\n          fontpixels_mid += get_bits(fontlines_ptr[1], tx, 1);\n          fontpixels_right += get_bits(fontlines_ptr[1], tx + 1, 1);\n          if constexpr (useHalocolor) {\n            halopixels_mid += get_bits(fontoutlines_ptr[1], tx, 1);\n            halopixels_right += get_bits(fontoutlines_ptr[1], tx + 1, 1);\n          }\n        }\n        // 1-2-1 weight\n        fontpixels = fontpixels_left + 2 * fontpixels_mid + fontpixels_right;\n        if constexpr (useHalocolor)\n          halopixels = halopixels_left + 2 * halopixels_mid + halopixels_right;\n      }\n      else {\n        // center, equal weights\n        for (int yy = 0; yy < ySubS; yy++) {\n          fontpixels += get_bits(fontlines_ptr[yy], tx, xSubS);\n          if constexpr (useHalocolor)\n            halopixels += get_bits(fontoutlines_ptr[yy], tx, xSubS);\n        }\n      }\n      LightOneUVPixel<pixel_t, logXRatioUV, logYRatioUV, fadeBackground, chromaMode>(_dstpU, j, _dstpV,\n        color_u, color_v, color_outline_u, color_outline_v,\n        fontpixels, halopixels,\n        bits_per_pixel\n        );\n\n      j += 1;\n    }\n\n    dstpU += pitchUV;\n    dstpV += pitchUV;\n  }\n}\n\ntemplate<typename pixel_t, bool fadeBackground, bool isRGB>\nvoid do_DrawStringPlanar(\n  const int width, const int height, BYTE** dstps, int* pitches, const int logXRatioUV, const int logYRatioUV, const int planeCount,\n  int bits_per_pixel,\n  const BitmapFont* bmfont, int x, int y, std::vector<int>& s, int color, int halocolor, int align, bool useHalocolor, int chromalocation)\n{\n  // some optimization hint\n  if constexpr (sizeof(pixel_t) == 1)\n    bits_per_pixel = 8;\n  else if constexpr (sizeof(pixel_t) == 4)\n    bits_per_pixel = 32;\n\n  // Chroma 411 would require 3 extra bits on both left and right.\n  // Chroma 420 and 422 need 1 bits on both left and right\n  // Left (mpeg2) chroma placement (420, 422) requires an additional one on the left.\n  const bool isLeftStyleChromaLoc = (logXRatioUV == 1) && \n    ((chromalocation == ChromaLocation_e::AVS_CHROMA_LEFT) || \n      (chromalocation == ChromaLocation_e::AVS_CHROMA_TOP_LEFT) || // not supported yet; for the sake of completeness\n      (chromalocation == ChromaLocation_e::AVS_CHROMA_BOTTOM_LEFT)); // not supported yet; for the sake of completeness\n  const int safety_bits_x_left = (1 << logXRatioUV) - 1 + (isLeftStyleChromaLoc ? 1 : 0);\n  const int safety_bits_x_right = (1 << logXRatioUV) - 1;\n\n  PreRendered pre(bmfont->font_bitmaps.data(), bmfont->fontline_bytes, width, height, x, y, s, bmfont->bbx_array, align, useHalocolor, \n    bmfont->global_bbx.width, bmfont->global_bbx.height, safety_bits_x_left, safety_bits_x_right);\n\n  if (pre.len <= 0)\n    return;\n\n  const bool is444 = !isRGB && (planeCount >= 3) && (logXRatioUV == 0) && (logYRatioUV == 0);\n\n  if (useHalocolor)\n    Render1by1Planes<pixel_t, true, fadeBackground, isRGB>(bits_per_pixel, color, halocolor, pitches, dstps, pre, planeCount, is444);\n  else\n    Render1by1Planes<pixel_t, false, fadeBackground, isRGB>(bits_per_pixel, color, halocolor, pitches, dstps, pre, planeCount, is444);\n\n  if constexpr (isRGB)\n    return;\n\n  if (is444)\n    return;\n\n  if (planeCount < 3)\n    return; // Y\n\n  // Subsampled cases, templates help a lot\n  // for 420 and 422 center and left supported only, what is not \"center\", we do the \"left\" method\n  if (logXRatioUV == 2 && logYRatioUV == 0) {// 411\n    // ignore chromalocation\n    if (useHalocolor)\n      RenderUV<pixel_t, true, fadeBackground, 2, 0, ChromaLocationMode::CENTER_411>(bits_per_pixel, color, halocolor, pitches, dstps, pre);\n    else\n      RenderUV<pixel_t, false, fadeBackground, 2, 0, ChromaLocationMode::CENTER_411>(bits_per_pixel, color, halocolor, pitches, dstps, pre);\n  }\n  else if (logXRatioUV == 1 && logYRatioUV == 0) {\n    if (chromalocation == ChromaLocation_e::AVS_CHROMA_CENTER) {\n      if (useHalocolor)\n        RenderUV<pixel_t, true, fadeBackground, 1, 0, ChromaLocationMode::CENTER_422>(bits_per_pixel, color, halocolor, pitches, dstps, pre);\n      else\n        RenderUV<pixel_t, false, fadeBackground, 1, 0, ChromaLocationMode::CENTER_422>(bits_per_pixel, color, halocolor, pitches, dstps, pre);\n    }\n    else {\n      if (useHalocolor)\n        RenderUV<pixel_t, true, fadeBackground, 1, 0, ChromaLocationMode::LEFT_422>(bits_per_pixel, color, halocolor, pitches, dstps, pre);\n      else\n        RenderUV<pixel_t, false, fadeBackground, 1, 0, ChromaLocationMode::LEFT_422>(bits_per_pixel, color, halocolor, pitches, dstps, pre);\n    }\n  }\n  else if (logXRatioUV == 1 && logYRatioUV == 1) {\n    if (chromalocation == ChromaLocation_e::AVS_CHROMA_CENTER) {\n      if (useHalocolor)\n        RenderUV<pixel_t, true, fadeBackground, 1, 1, ChromaLocationMode::CENTER_420>(bits_per_pixel, color, halocolor, pitches, dstps, pre);\n      else\n        RenderUV<pixel_t, false, fadeBackground, 1, 1, ChromaLocationMode::CENTER_420>(bits_per_pixel, color, halocolor, pitches, dstps, pre);\n    }\n    else {\n      if (useHalocolor)\n        RenderUV<pixel_t, true, fadeBackground, 1, 1, ChromaLocationMode::LEFT_420>(bits_per_pixel, color, halocolor, pitches, dstps, pre);\n      else\n        RenderUV<pixel_t, false, fadeBackground, 1, 1, ChromaLocationMode::LEFT_420>(bits_per_pixel, color, halocolor, pitches, dstps, pre);\n\n    }\n  }\n  else\n    assert(0);\n}\n\ntemplate<bool useHalocolor, bool fadeBackground, ChromaLocationMode chromaMode>\nvoid RenderYUY2(int color, int halocolor, int pitch, BYTE* _dstp, PreRendered& pre)\n{\n  BYTE* dstp = _dstp + pre.x * 2 + pre.y * pitch;\n  BYTE* dstpUV = _dstp + (pre.x / 2) * 4 + 1 + pre.y * pitch; // always points to U of a YUYV block\n\n  typedef uint8_t pixel_t;\n\n  pixel_t val_color = getColorForPlane(PLANAR_Y, color);\n  pixel_t val_color_outline = getColorForPlane(PLANAR_Y, halocolor);\n  pixel_t color_u = getColorForPlane(PLANAR_U, color);\n  pixel_t color_outline_u = getColorForPlane(PLANAR_U, halocolor);\n  pixel_t color_v = getColorForPlane(PLANAR_V, color);\n  pixel_t color_outline_v = getColorForPlane(PLANAR_V, halocolor);\n\n  // YUY2 like 422\n  constexpr int logXRatioUV = 1;\n  constexpr int logYRatioUV = 0;\n  constexpr int xSubS = 2;\n\n  // unaligned x: for horizontal subsampling 420, 422 (YUY2) and 411:\n  // 420, 422, 411, YUY2 horizontal subsampling: one more loop because of the leftmost orphan pixel(s)\n  // we can overaddress on the right, additional safety bit column(s) were added for the bitmap\n  const bool unaligned_x_start = 0 != pre.x % xSubS;\n  const int xplus = unaligned_x_start ? xSubS : 0; // extra orphan bits affecting rightmost chroma\n  const int xshift = pre.x % xSubS; // when aligned --> 0\n\n  for (int ty = pre.ystart; ty < pre.yend; ty++) {\n    BYTE* dp = dstp;\n    BYTE* dpUV = dstpUV;\n    uint8_t* fontline_ptr = pre.stringbitmap[ty].data();\n    [[maybe_unused]] uint8_t* fontoutline_ptr;\n    if constexpr (useHalocolor)\n      fontoutline_ptr = pre.stringbitmap_outline[ty].data();\n\n    // first Y, like in 4:4:4\n    int j = 0;\n    int shifted_xstart = pre.safety_bits_x_left + pre.xstart;\n    for (int tx = shifted_xstart; tx < shifted_xstart + pre.text_width; tx++) {\n      const bool lightIt = 0 != get_bit(fontline_ptr, tx);\n      LightOnePixel<uint8_t, fadeBackground, false>(lightIt, dp, j, val_color, 8);\n      if constexpr (useHalocolor) {\n        if (!lightIt)\n        {\n          const bool lightIt_outline = 0 != get_bit(fontoutline_ptr, tx);\n          LightOnePixel<uint8_t, fadeBackground, false>(lightIt_outline, dp, j, val_color_outline, 8);\n        }\n      }\n      j += 2; // next Y\n    }\n\n    // then chroma\n    j = 0;\n    // (pre.xstart - xshift) is always on horizontal subsample boundary\n    shifted_xstart = pre.safety_bits_x_left + pre.xstart - xshift;\n\n    // left (mpeg2) location: \n    int fontpixels_right = 0; // used for left (mpeg2) chroma location case\n    int halopixels_right = 0;\n    // For the very first chroma pixel there is no previous rightside.\n    // Use index -1, safe because of safety columns\n    if constexpr (chromaMode == LEFT_422) {\n      fontpixels_right = get_bits(fontline_ptr, shifted_xstart - 1, 1);\n      if constexpr (useHalocolor)\n        halopixels_right = get_bits(fontoutline_ptr, shifted_xstart - 1, 1);\n    }\n\n    for (int tx = shifted_xstart; tx < shifted_xstart + pre.text_width + xplus; tx += xSubS) {\n      int fontpixels = 0;\n      int halopixels = 0;\n      // 422 center (mpeg1, jpeg)\n      // +------+------+\n      // | 0.5  | 0.5  |\n      // +------+------+\n      // 422 left (mpeg2)\n      // ------+------+-------+\n      // 0.25  | 0.5  | 0.25  |\n      // ------+------+-------+\n\n      if constexpr (chromaMode == LEFT_422) {\n        int fontpixels_left = 0;\n        int halopixels_left = 0;\n        int fontpixels_mid = 0;\n        int halopixels_mid = 0;\n\n        // shift variables\n        fontpixels_left = fontpixels_right;\n        if constexpr (useHalocolor)\n          halopixels_left = halopixels_right;\n        // gather counts\n        fontpixels_mid = get_bits(fontline_ptr, tx, 1);\n        fontpixels_right = get_bits(fontline_ptr, tx + 1, 1);\n        if constexpr (useHalocolor) {\n          halopixels_mid = get_bits(fontoutline_ptr, tx, 1);\n          halopixels_right = get_bits(fontoutline_ptr, tx + 1, 1);\n        }\n        // 1-2-1 weight\n        fontpixels = fontpixels_left + 2 * fontpixels_mid + fontpixels_right;\n        if constexpr (useHalocolor)\n          halopixels = halopixels_left + 2 * halopixels_mid + halopixels_right;\n      }\n      else {\n        // center, equal weights\n        fontpixels += get_bits(fontline_ptr, tx, xSubS);\n        if constexpr (useHalocolor)\n          halopixels += get_bits(fontoutline_ptr, tx, xSubS);\n      }\n\n      LightOneUVPixel<uint8_t, logXRatioUV, logYRatioUV, fadeBackground, chromaMode>(dpUV /*U*/, j, dpUV + 2 /*V*/,\n        color_u, color_v, color_outline_u, color_outline_v,\n        fontpixels, halopixels,\n        8\n        );\n      j += 4; // YUYV\n    }\n\n    dstp += pitch;\n    dstpUV += pitch;\n  }\n}\n\ntemplate<bool fadeBackground>\nstatic void do_DrawStringYUY2(\n  const int width, const int height, BYTE* _dstp, int pitch, const BitmapFont* bmfont, int x, int y, std::vector<int>& s,\n  int color, int halocolor, int align, bool useHalocolor, int chromalocation)\n{\n  const bool isLeftStyleChromaLoc = chromalocation == ChromaLocation_e::AVS_CHROMA_LEFT;\n  // Like 422. Chroma subsampling would require 1 extra bit playground on both left and right\n  const int safety_bits_x_left = 1 + (isLeftStyleChromaLoc ? 1 : 0);\n  const int safety_bits_x_right = 1;\n\n  PreRendered pre(bmfont->font_bitmaps.data(), bmfont->fontline_bytes, width, height, x, y, s, bmfont->bbx_array, align, useHalocolor,\n    bmfont->global_bbx.width, bmfont->global_bbx.height,\n    safety_bits_x_left, safety_bits_x_right);\n\n  if (pre.len <= 0)\n    return;\n\n  if (useHalocolor) {\n    if (chromalocation == ChromaLocation_e::AVS_CHROMA_CENTER)\n      RenderYUY2<true, fadeBackground, ChromaLocationMode::CENTER_422>(color, halocolor, pitch, _dstp, pre);\n    else\n      RenderYUY2<true, fadeBackground, ChromaLocationMode::LEFT_422>(color, halocolor, pitch, _dstp, pre);\n  }\n  else {\n    if (chromalocation == ChromaLocation_e::AVS_CHROMA_CENTER)\n      RenderYUY2<false, fadeBackground, ChromaLocationMode::CENTER_422>(color, halocolor, pitch, _dstp, pre);\n    else\n      RenderYUY2<false, fadeBackground, ChromaLocationMode::LEFT_422>(color, halocolor, pitch, _dstp, pre);\n  }\n}\n\ntemplate<typename pixel_t, bool useHalocolor, bool fadeBackground, int rgbstep>\nstatic void RenderPackedRGB(int color, int halocolor, BYTE* _dstp, int pitch, int height, PreRendered& pre)\n{\n  // packed: only 8 and 16 bits\n  int bits_per_pixel = 0;\n  if constexpr (sizeof(pixel_t) == 1)\n    bits_per_pixel = 8;\n  else if constexpr (sizeof(pixel_t) == 2)\n    bits_per_pixel = 16;\n\n  const int val_color_R = getHBDColor_RGB<pixel_t>(getColorForPlane(PLANAR_R, color), bits_per_pixel);\n  const int val_color_R_outline = getHBDColor_RGB<pixel_t>(getColorForPlane(PLANAR_R, halocolor), bits_per_pixel);\n  const int val_color_G = getHBDColor_RGB<pixel_t>(getColorForPlane(PLANAR_G, color), bits_per_pixel);\n  const int val_color_G_outline = getHBDColor_RGB<pixel_t>(getColorForPlane(PLANAR_G, halocolor), bits_per_pixel);\n  const int val_color_B = getHBDColor_RGB<pixel_t>(getColorForPlane(PLANAR_B, color), bits_per_pixel);\n  const int val_color_B_outline = getHBDColor_RGB<pixel_t>(getColorForPlane(PLANAR_B, halocolor), bits_per_pixel);\n\n  // upside down\n  BYTE* dstp = _dstp + pre.x * rgbstep + (height - 1 - pre.y) * pitch;\n\n  // Start rendering\n  for (int ty = pre.ystart; ty < pre.yend; ty++) {\n    uint8_t* dp = dstp;\n    uint8_t* fontline_ptr = pre.stringbitmap[ty].data();\n    [[maybe_unused]] uint8_t* fontoutline_ptr;\n    if constexpr(useHalocolor)\n      fontoutline_ptr = pre.stringbitmap_outline[ty].data();\n\n    const int shifted_xstart = pre.safety_bits_x_left + pre.xstart; // though safety bit count must be 0 here\n    for (int tx = shifted_xstart; tx < shifted_xstart + pre.text_width; tx++)\n    {\n      const bool lightIt = 0 != get_bit(fontline_ptr, tx);\n      LightOnePixelPackedRGB<pixel_t, fadeBackground>(lightIt, dp, val_color_R, val_color_G, val_color_B);\n      if constexpr(useHalocolor) {\n        if (!lightIt) {\n          const bool lightIt_outline = 0 != get_bit(fontoutline_ptr, tx);\n          LightOnePixelPackedRGB<pixel_t, fadeBackground>(lightIt_outline, dp, val_color_R_outline, val_color_G_outline, val_color_B_outline);\n        }\n      }\n      dp += rgbstep;\n    }\n    dstp -= pitch;\n  }\n}\n\ntemplate<typename pixel_t, int rgbstep, bool fadeBackground>\nstatic void do_DrawStringPackedRGB(\n  const int width, const int height, BYTE* _dstp, int pitch,\n  const BitmapFont* bmfont, int x, int y, std::vector<int>& s, int color, int halocolor, int align, bool useHalocolor)\n{\n  const int safety_bits_x_left = 0; // no horizontal subsampling\n  const int safety_bits_x_right = 0; // no horizontal subsampling\n  PreRendered pre(bmfont->font_bitmaps.data(), bmfont->fontline_bytes, width, height, x, y, s, bmfont->bbx_array, align, useHalocolor,\n    bmfont->global_bbx.width, bmfont->global_bbx.height,\n    safety_bits_x_left, safety_bits_x_right);\n\n  if (pre.len <= 0)\n    return;\n\n  if (useHalocolor)\n    RenderPackedRGB<pixel_t, true, fadeBackground, rgbstep>(color, halocolor, _dstp, pitch, height, pre);\n  else\n    RenderPackedRGB<pixel_t, false, fadeBackground, rgbstep>(color, halocolor, _dstp, pitch, height, pre);\n}\n\n\nstatic bool strequals_i(const std::string& a, const std::string& b)\n{\n  return std::equal(a.begin(), a.end(),\n    b.begin(), b.end(),\n    [](char a, char b) {\n      return tolower(a) == tolower(b);\n    });\n}\n\n// in fixedfonts.cpp\nextern const uint16_t *font_bitmaps[];\nextern const uint16_t *font_codepoints[];\nextern const FixedFont_info_t *font_infos[];\n\nstd::unique_ptr<BitmapFont> GetBitmapFont(int size, const char *name, bool bold, bool debugSave) {\n\n  BitmapFont* current_font = nullptr;\n\n  // check internal embedded fonts\n  bool found = false;\n\n  // find font in internal list\n  for (int i = 0; i < PREDEFINED_FONT_COUNT; i++)\n  {\n    const FixedFont_info_t* fi = font_infos[i];\n    if (fi->height == size && fi->bold == bold && strequals_i(fi->fontname, name)) {\n      BBX global_bbx = BBX{ fi->width, fi->height, fi->offset_x, fi->offset_y }; // BBX from FONTBOUNDINGBOX\n      // max WIDTH, max HEIGHT, offset_x, offset_y\n      current_font = new BitmapFont(\n        fi->charcount,\n        font_bitmaps[i], // internal one\n        nullptr, // not a byte array from external BDF\n        sizeof(uint16_t), // sizeof(*font_bitmaps) 2: uint16_t\n        font_codepoints[i],\n        nullptr, // Individual BBX for each character. For our internal characters it comes from global bbx\n        global_bbx,\n        fi->fontname,\n        \"\",\n        fi->bold,\n        false);\n      found = true;\n      break;\n    }\n  }\n  // pass #2 when size does not match exactly, find nearest, but still smaller font.\n  if (!found) {\n    // find font i internal list\n    int last_good_size = 0;\n    int found_index = -1;\n    for (int i = 0; i < PREDEFINED_FONT_COUNT; i++)\n    {\n      const FixedFont_info_t* fi = font_infos[i];\n      if (fi->bold == bold && strequals_i(fi->fontname, name)) {\n        if (last_good_size == 0) {\n          found_index = i;\n          last_good_size = fi->height;\n        }\n        else if (std::abs(fi->height - size) < std::abs(last_good_size - size) && fi->height <= size) {\n          // has better size match and is not larger\n          found_index = i;\n          last_good_size = fi->height;\n        }\n      }\n    }\n    if (found_index >= 0) {\n      const FixedFont_info_t* fi = font_infos[found_index];\n      BBX global_bbx = BBX{ fi->width, fi->height, fi->offset_x, fi->offset_y }; // BBX from FONTBOUNDINGBOX\n      current_font = new BitmapFont(\n        fi->charcount,\n        font_bitmaps[found_index], // internal one\n        nullptr, // not a byte array from external BDF\n        sizeof(uint16_t), // sizeof(*font_bitmaps) 2: uint16_t\n        font_codepoints[found_index],\n        nullptr,  // Individual BBX for each character. For our internal characters it comes from global bbx\n        global_bbx,\n        fi->fontname,\n        \"\",\n        fi->bold,\n        false);\n      found = true;\n    }\n  }\n\n  if (!found) {\n    // fixme: make cache\n    BdfFont bdf;\n    bdf = LoadBMF(name, bold);\n    if (bdf.codepoints_array.size() == 0)\n      return nullptr;\n\n    current_font = new BitmapFont(\n      bdf.font_info.chars,\n      nullptr, // not an internal one\n      bdf.font_bitmaps.data(), // a byte array from external BDF\n      bdf.font_info.fontline_bytes,\n      bdf.codepoints_array.data(),\n      &bdf.bbx_array, // Individual BBX for each character, nullptr if not available for our internal fonts\n      bdf.font_info.bbx, // from FONTBOUNDINGBOX, max WIDTH, HEIGHT, offset_x, offset_y\n      bdf.font_info.font,\n      bdf.font_filename,\n      strequals_i(bdf.font_properties.Weight_name, \"bold\"),\n      debugSave);\n  }\n  return std::unique_ptr<BitmapFont>(current_font);\n}\n\nstatic void DrawString_internal(BitmapFont* current_font, const VideoInfo& vi, PVideoFrame& dst, int x, int y, std::string& s_utf8,\n  int color, int halocolor, bool useHalocolor, int align, bool fadeBackground, int chromalocation)\n{\n  //static BitmapFont_10_20 infoFont1020; // constructor runs once, single instance\n\n  // map an utf8 string to a sequence of character map indexes\n  auto s_remapped = current_font->remap(s_utf8); // array of font table indexes\n\n  //SaveBitmapSource(); // debug to generate source from original table\n\n  const bool isRGB = vi.IsRGB();\n  const int planes_y[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };\n  const int planes_r[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A };\n  const int* planes = isRGB ? planes_r : planes_y;\n\n  int logXRatioUV = 0;\n  int logYRatioUV = 0;\n  if (!vi.IsY() && !vi.IsRGB()) {\n    logXRatioUV = vi.IsYUY2() ? 1 : vi.GetPlaneWidthSubsampling(PLANAR_U);\n    logYRatioUV = vi.IsYUY2() ? 0 : vi.GetPlaneHeightSubsampling(PLANAR_U);\n  }\n  const int planecount = vi.IsYUY2() ? 1 : std::min(vi.NumComponents(), 3);\n  BYTE* dstps[3] = { nullptr };\n  int pitches[3] = { 0 };\n\n  for (int i = 0; i < planecount; i++)\n  {\n    int plane = planes[i];\n    dstps[i] = dst->GetWritePtr(plane);\n    pitches[i] = dst->GetPitch(plane);\n  }\n\n  const int width = vi.width;\n  const int height = vi.height;\n\n  const int bits_per_pixel = vi.BitsPerComponent();\n\n  // narrow down valid chroma choices, ignoring and moving to default what is not supported at the moment\n  if (vi.IsYV411()) {\n    // ignored, always left\n    chromalocation = ChromaLocation_e::AVS_CHROMA_LEFT;\n  }\n  else if (vi.Is420() || vi.Is422() || vi.IsYUY2()) {\n    if (chromalocation != ChromaLocation_e::AVS_CHROMA_CENTER)\n      chromalocation = ChromaLocation_e::AVS_CHROMA_LEFT;\n    // When CENTER is specified, do \"center\", all other cases fall back \n    // to \"left\" (mpeg2). Option is meaningful only 420 or 422 formats, otherwise ignored.\n  }\n\n  // YUY2\n  if (vi.IsYUY2()) {\n    if (fadeBackground)\n      do_DrawStringYUY2<true>(width, height, dstps[0], pitches[0], current_font, x, y, s_remapped, color, halocolor, align, useHalocolor, chromalocation);\n    else\n      do_DrawStringYUY2<false>(width, height, dstps[0], pitches[0], current_font, x, y, s_remapped, color, halocolor, align, useHalocolor, chromalocation);\n    return;\n  }\n\n  // Packed RGB24/32/48/64\n  if (isRGB && !vi.IsPlanar()) {\n    if (fadeBackground) {\n      if (vi.IsRGB24())\n        do_DrawStringPackedRGB<uint8_t, 3, true>(width, height, dstps[0], pitches[0], current_font, x, y, s_remapped, color, halocolor, align, useHalocolor);\n      else if (vi.IsRGB32())\n        do_DrawStringPackedRGB<uint8_t, 4, true>(width, height, dstps[0], pitches[0], current_font, x, y, s_remapped, color, halocolor, align, useHalocolor);\n      else if (vi.IsRGB48())\n        do_DrawStringPackedRGB<uint16_t, 6, true>(width, height, dstps[0], pitches[0], current_font, x, y, s_remapped, color, halocolor, align, useHalocolor);\n      else if (vi.IsRGB64())\n        do_DrawStringPackedRGB<uint16_t, 8, true>(width, height, dstps[0], pitches[0], current_font, x, y, s_remapped, color, halocolor, align, useHalocolor);\n    }\n    else {\n      if (vi.IsRGB24())\n        do_DrawStringPackedRGB<uint8_t, 3, false>(width, height, dstps[0], pitches[0], current_font, x, y, s_remapped, color, halocolor, align, useHalocolor);\n      else if (vi.IsRGB32())\n        do_DrawStringPackedRGB<uint8_t, 4, false>(width, height, dstps[0], pitches[0], current_font, x, y, s_remapped, color, halocolor, align, useHalocolor);\n      else if (vi.IsRGB48())\n        do_DrawStringPackedRGB<uint16_t, 6, false>(width, height, dstps[0], pitches[0], current_font, x, y, s_remapped, color, halocolor, align, useHalocolor);\n      else if (vi.IsRGB64())\n        do_DrawStringPackedRGB<uint16_t, 8, false>(width, height, dstps[0], pitches[0], current_font, x, y, s_remapped, color, halocolor, align, useHalocolor);\n    }\n    return;\n  }\n\n  // planar and Y\n  if (fadeBackground) {\n    if (isRGB) {\n      switch (bits_per_pixel)\n      {\n      case 8:\n        do_DrawStringPlanar<uint8_t, true, true>(width, height, dstps, pitches, logXRatioUV, logYRatioUV, planecount, bits_per_pixel, current_font, x, y, s_remapped, color, halocolor, align, useHalocolor, chromalocation);\n        break;\n      case 10:\n      case 12:\n      case 14:\n      case 16:\n        do_DrawStringPlanar<uint16_t, true, true>(width, height, dstps, pitches, logXRatioUV, logYRatioUV, planecount, bits_per_pixel, current_font, x, y, s_remapped, color, halocolor, align, useHalocolor, chromalocation);\n        break;\n      case 32:\n        do_DrawStringPlanar<float, true, true>(width, height, dstps, pitches, logXRatioUV, logYRatioUV, planecount, bits_per_pixel, current_font, x, y, s_remapped, color, halocolor, align, useHalocolor, chromalocation);\n        break;\n      }\n    }\n    else {\n      switch (bits_per_pixel)\n      {\n      case 8:\n        do_DrawStringPlanar<uint8_t, true, false>(width, height, dstps, pitches, logXRatioUV, logYRatioUV, planecount, bits_per_pixel, current_font, x, y, s_remapped, color, halocolor, align, useHalocolor, chromalocation);\n        break;\n      case 10:\n      case 12:\n      case 14:\n      case 16:\n        do_DrawStringPlanar<uint16_t, true, false>(width, height, dstps, pitches, logXRatioUV, logYRatioUV, planecount, bits_per_pixel, current_font, x, y, s_remapped, color, halocolor, align, useHalocolor, chromalocation);\n        break;\n      case 32:\n        do_DrawStringPlanar<float, true, false>(width, height, dstps, pitches, logXRatioUV, logYRatioUV, planecount, bits_per_pixel, current_font, x, y, s_remapped, color, halocolor, align, useHalocolor, chromalocation);\n        break;\n      }\n    }\n  }\n  else {\n    if (isRGB) {\n      switch (bits_per_pixel)\n      {\n      case 8:\n        do_DrawStringPlanar<uint8_t, false, true>(width, height, dstps, pitches, logXRatioUV, logYRatioUV, planecount, bits_per_pixel, current_font, x, y, s_remapped, color, halocolor, align, useHalocolor, chromalocation);\n        break;\n      case 10:\n      case 12:\n      case 14:\n      case 16:\n        do_DrawStringPlanar<uint16_t, false, true>(width, height, dstps, pitches, logXRatioUV, logYRatioUV, planecount, bits_per_pixel, current_font, x, y, s_remapped, color, halocolor, align, useHalocolor, chromalocation);\n        break;\n      case 32:\n        do_DrawStringPlanar<float, false, true>(width, height, dstps, pitches, logXRatioUV, logYRatioUV, planecount, bits_per_pixel, current_font, x, y, s_remapped, color, halocolor, align, useHalocolor, chromalocation);\n        break;\n      }\n    }\n    else {\n      switch (bits_per_pixel)\n      {\n      case 8:\n        do_DrawStringPlanar<uint8_t, false, false>(width, height, dstps, pitches, logXRatioUV, logYRatioUV, planecount, bits_per_pixel, current_font, x, y, s_remapped, color, halocolor, align, useHalocolor, chromalocation);\n        break;\n      case 10:\n      case 12:\n      case 14:\n      case 16:\n        do_DrawStringPlanar<uint16_t, false, false>(width, height, dstps, pitches, logXRatioUV, logYRatioUV, planecount, bits_per_pixel, current_font, x, y, s_remapped, color, halocolor, align, useHalocolor, chromalocation);\n        break;\n      case 32:\n        do_DrawStringPlanar<float, false, false>(width, height, dstps, pitches, logXRatioUV, logYRatioUV, planecount, bits_per_pixel, current_font, x, y, s_remapped, color, halocolor, align, useHalocolor, chromalocation);\n        break;\n      }\n    }\n  }\n}\n\nvoid SimpleTextOutW(BitmapFont *current_font, const VideoInfo& vi, PVideoFrame& frame, int real_x, int real_y, std::string& text_utf8,\n  bool fadeBackground, int textcolor, int halocolor, bool useHaloColor, int align, int chromalocation)\n{\n  DrawString_internal(current_font, vi, frame, real_x, real_y, text_utf8, textcolor, halocolor, useHaloColor, align, fadeBackground, chromalocation); // fully transparent background\n}\n\n// additional parameter: lsp line spacing\nvoid SimpleTextOutW_multi(BitmapFont *current_font, const VideoInfo& vi, PVideoFrame& frame, int real_x, int real_y, std::string& text_utf8,\n  bool fadeBackground, int textcolor, int halocolor, bool useHaloColor,\n  int align, int lsp, int chromalocation)\n{\n\n  // make list governed by LF separator\n  std::string temp;\n  std::vector<std::string> parts;\n  std::stringstream ss(text_utf8);\n  while (std::getline(ss, temp, '\\n'))\n    parts.push_back(temp); // still in utf8\n  // It doesn't result in a new line if the last character is \\n and is followed by nothing.\n  // \"Line1\\nLine2\" is the same as \"Line1\\nLine2\\n\"\n  // Like in SubTitle\n  /*\n  if(!text.empty())\n  {\n    if( *text.rbegin() == '\\n')\n      parts.push_back(\"\");\n  }\n  */\n  const int fontSize = current_font->global_bbx.height;\n\n  // when multiline, bottom and vertically centered cases affect starting y\n  // lsp units are in 1/8 pixels by definition\n  int al = alignToBitmask(align);\n  if (al & ATA_BOTTOM)\n    real_y -= (int)((fontSize + lsp / 8.0) * ((int)parts.size() - 1) + 0.5);\n  else if (al & ATA_BASELINE)\n    real_y -= (int)((fontSize + lsp / 8.0) * (int)(parts.size() - 1) / 2.0 + 0.5);\n\n  const int orig_real_y = real_y;\n  int linecount = 0;\n  for (auto s_utf8 : parts) {\n    real_y = orig_real_y + fontSize * linecount + (int)(lsp / 8.0 * linecount + 0.5);\n    SimpleTextOutW(current_font, vi, frame, real_x, real_y, s_utf8, fadeBackground, textcolor, halocolor, useHaloColor, align, chromalocation);\n    linecount++;\n  }\n}\n\n// Old legacy info.h functions, but with utf8 mode\n// w/o outline, originally with ASCII input, background fading\n// Despite name Planar, it works for all formats\nvoid DrawStringPlanar(VideoInfo& vi, PVideoFrame& dst, int x, int y, const char* s)\n{\n  int color;\n  if (vi.IsRGB())\n    color = (250 << 16) + (250 << 8) + (250);\n  else\n    color = (230 << 16) + (128 << 8) + (128);\n\n  // fadeBackground = true: background letter area is faded instead not being untouched.\n\n  std::string s_utf8 = charToUtf8(s, false);\n\n  int halocolor = 0;\n\n  std::unique_ptr<BitmapFont> current_font = GetBitmapFont(20, \"info_h\", false, false); // 10x20\n\n  if (current_font == nullptr)\n    return;\n\n  DrawString_internal(current_font.get(), vi, dst, x, y, s_utf8,\n    color,\n    halocolor,\n    false, // don't use halocolor\n    0 /* no align */,\n    true, // fadeBackGround\n    ChromaLocation_e::AVS_CHROMA_LEFT\n  );\n\n}\n\nvoid DrawStringYUY2(VideoInfo& vi, PVideoFrame& dst, int x, int y, const char* s)\n{\n  DrawStringPlanar(vi, dst, x, y, s);\n}\n\n// legacy function w/o outline, originally with ASCII input, background fading\nvoid DrawStringRGB24(VideoInfo &vi, PVideoFrame& dst, int x, int y, const char* s)\n{\n  DrawStringPlanar(vi, dst, x, y, s);\n}\n\n// legacy function w/o outline, originally with ASCII input, background fading\nvoid DrawStringRGB32(VideoInfo& vi, PVideoFrame& dst, int x, int y, const char* s)\n{\n  DrawStringPlanar(vi, dst, x, y, s);\n}\n"
  },
  {
    "path": "avs_core/core/info.h",
    "content": "// Avisynth+\n// https://avs-plus.net\n//\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __INFO_H__\n#define __INFO_H__\n\n#ifdef AVS_LINUX\n#include <uchar.h>\n#endif\n#include <sstream>\n#include \"internal.h\"\n#include <unordered_map>\n#include <array>\n#include <iomanip>\n#include <vector>\n#include <cstring>\n#include \"strings.h\"\n\nenum ChromaLocationMode {\n  CENTER_411,\n  CENTER_420,\n  LEFT_420,\n  CENTER_422,\n  LEFT_422\n};\n\ntypedef struct BBX {\n  uint8_t width; // e.g. 8\n  uint8_t height; // 16\n  int8_t offset_x; // 0\n  int8_t offset_y; // -4\n} BBX;\n\nclass PreRendered {\n  const bool useHalocolor;\n  const int vi_width;\n  const int vi_height;\n\npublic:\n  int x, y;\n  int len;\n  int xstart;\n  int text_width; // draw this amount of pixels starting from horizontal index xstart\n  int ystart; // vertical visibility: starting row in stringbitmap\n  int yend;   // vertical visibility: ending row in stringbitmap\n  int stringbitmap_height; // font height plus optinally added top/bottom line\n  const int safety_bits_x_left; // extra leftside playground for chroma rendering\n  const int safety_bits_x_right; // extra rightside playground for chroma rendering\n\n  std::vector<std::vector<uint8_t>> stringbitmap;\n  std::vector<std::vector<uint8_t>> stringbitmap_outline;\n\n  PreRendered(\n    const uint8_t* fonts,\n    const int fontline_bytes,\n    const int _vi_width, const int _vi_height,\n    int _x, int _y, // they may change\n    std::vector<int>& s, // it may get shortened\n    const std::vector<BBX>& bbx_array,\n    const int align,\n    const bool _useHalocolor,\n    const int FONT_WIDTH_notused, const int FONT_HEIGHT,\n    const int _safety_bits_x_left,\n    const int _safety_bits_x_right\n    );\n\n  void make_outline();\n};\n\nclass BitmapFont {\n\n  int number_of_chars;\n  std::string font_name;\n  std::string font_filename;\n\npublic:\n  const BBX global_bbx;\n\n  const bool bold;\n\n  std::vector<uint8_t> font_bitmaps;\n  std::vector<BBX> bbx_array; // FontBoundingBox BBX array, can be individual for each character\n  const int fontline_bytes;\n\n  std::unordered_map<std::string, int> charReMapUtf8; // utf8 vs. font image index\n\n  void SaveAsC(const uint16_t* _codepoints);\n\n  BitmapFont(int _number_of_chars,\n    const uint16_t* _src_font_bitmaps_internaluint16, \n    const uint8_t* _src_font_bitmaps, \n    const int _fontline_bytes, \n    const uint16_t* _codepoints,\n    const std::vector<BBX>* bbx_array_ptr,\n    const BBX& _global_bbx,\n    std::string _font_name, std::string _font_filename, bool _bold, bool debugSave) :\n    number_of_chars(_number_of_chars),\n    font_name(_font_name),\n    font_filename(_font_filename),\n    global_bbx(_global_bbx),\n    bold(_bold),\n    fontline_bytes(_fontline_bytes)\n    //font_bitmaps(_font_bitmaps),\n  {\n    //fixme: do not copy data\n    const int charline_count = global_bbx.height * number_of_chars;\n    font_bitmaps.resize(charline_count * fontline_bytes);\n    if (_src_font_bitmaps != nullptr) \n      std::memcpy(font_bitmaps.data(), _src_font_bitmaps, font_bitmaps.size());\n    else {\n      // this must be an internal, predefined array\n      // copy uint16_t array to byte array MSB-LSB order \n      // fontline_bytes is 2\n      const uint16_t* src = _src_font_bitmaps_internaluint16;\n      uint8_t* dst = font_bitmaps.data();\n      for (auto i = 0; i < charline_count; i++) {\n        uint16_t one_fontline = src[i];\n        dst[i * 2] = (uint8_t)(one_fontline >> 8);\n        dst[i * 2 + 1] = (uint8_t)(one_fontline & 0xFF);\n      }\n    }\n\n    // We always display utf8 strings, so the reverse lookup must be utf8 character based,\n    // which returns the index to the font bitmap and bbx array.\n    for (int i = 0; i < _number_of_chars; i++) {\n      std::string s_utf8 = U16_to_utf8(_codepoints[i]);\n      charReMapUtf8[s_utf8] = i;\n    }\n\n\n    // Many East Asian characters—especially CJK (Chinese, Japanese, Korean) ideographs\n    // are typically double-width compared to Latin characters when used in monospaced bitmap\n    // fonts like BDF.\n    // For Avisynth-embedded internal fonts (e.g., Terminus, Info_H), only a fixed global BBX is used,\n    // as these fonts do not include CJK characters, only Latin, Cyrillic, and Greek.\n    // The variable BBX array is optional and is intended for use with external fonts,\n    // such as unifont-16.0.04.bdf, where CJK characters have different BBX values\n    // compared to Latin characters.\n\n    if (bbx_array_ptr != nullptr) {\n      // copy BBX array if provided\n      bbx_array.insert(bbx_array.end(), bbx_array_ptr->begin(), bbx_array_ptr->end());\n    }\n    else {\n      // When no BBX array was provided (bbx_array_ptr is nullptr)\n      // fill bbx_array with constant default global values\n      bbx_array.assign(_number_of_chars, global_bbx);\n    }\n\n    if (debugSave)\n      SaveAsC(_codepoints);\n  }\n\n  // helper function for remapping an utf8 string to font index entry list\n  std::vector<int> remap(const std::string& s_utf8);\n};\n\nstd::unique_ptr<BitmapFont> GetBitmapFont(int size, const char* name, bool bold, bool debugSave);\n\nvoid SimpleTextOutW(BitmapFont* current_font, const VideoInfo& vi, PVideoFrame& frame, int real_x, int real_y, std::string& text_utf8,\n  bool fadeBackground, int textcolor, int halocolor, bool useHaloColor, int align, int chromaplacement);\nvoid SimpleTextOutW_multi(BitmapFont* current_font, const VideoInfo& vi, PVideoFrame& frame, int real_x, int real_y, std::string& text_utf8,\n  bool fadeBackground, int textcolor, int halocolor, bool useHaloColor, int align, int lsp, int chromaplacement);\n\n// legacy function w/o outline, originally with ASCII input, background fading\nvoid DrawStringPlanar(VideoInfo& vi, PVideoFrame& dst, int x, int y, const char* s);\nvoid DrawStringYUY2(VideoInfo& vi, PVideoFrame& dst, int x, int y, const char* s);\nvoid DrawStringRGB32(VideoInfo& vi, PVideoFrame& dst, int x, int y, const char* s);\nvoid DrawStringRGB24(VideoInfo& vi, PVideoFrame& dst, int x, int y, const char* s);\n\n#endif  // __INFO_H__\n"
  },
  {
    "path": "avs_core/core/initguid.cpp",
    "content": "// Avisynth v2.5.  Copyright 2007 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#define INITGUID\n\n#ifdef AVS_WINDOWS\n#define WIN32_LEAN_AND_MEAN\n\n#include <objbase.h>\n\n#pragma warning( push )\n#pragma warning (disable: 4201) // nonstandard extension used : nameless struct/union\n\n#include <vfw.h>\n\n#pragma warning( pop )\n\n// Just init the guid tables\n#endif\n"
  },
  {
    "path": "avs_core/core/interface.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002, 2005 Ben Rudiak-Gould et al.\n// Avisynth v2.6.  Copyright 2006 Klaus Post.\n// Avisynth v2.6.  Copyright 2009 Ian Brabham.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n/* Maintenance notes :-\n *\n *   All the code here was formally baked into the avisynth.h interface.\n *\n *   Whenever you modify any code here please keep and mark the original\n *   code with a block comment beginning with the word \"Baked\"\n *\n *   Be mindful with changes you do make that previous 2.5 plugins will\n *   still have the original code active. This may require other defensive\n *   or mitigating code elsewhere.\n */\n\n#include <avisynth.h>\n\n#ifdef AVS_WINDOWS\n    #include <avs/win.h>\n#else\n    #include <avs/posix.h>\n#endif\n#include \"InternalEnvironment.h\"\n#include \"DeviceManager.h\"\n#include \"AVSMap.h\"\n#include \"function.h\"\n#include \"assert.h\"\n\n/**********************************************************************/\n\n// struct VideoInfo\n\n// useful functions of the above\nbool VideoInfo::HasVideo() const { return (width!=0); }\nbool VideoInfo::HasAudio() const { return (audio_samples_per_second!=0); }\nbool VideoInfo::IsRGB() const { return !!(pixel_type&CS_BGR); }\nbool VideoInfo::IsRGB24() const { return ((pixel_type & CS_BGR24) == CS_BGR24) && ((pixel_type & CS_Sample_Bits_Mask) == CS_Sample_Bits_8); } // Clear out additional properties\nbool VideoInfo::IsRGB32() const { return ((pixel_type & CS_BGR32) == CS_BGR32) && ((pixel_type & CS_Sample_Bits_Mask) == CS_Sample_Bits_8); }\nbool VideoInfo::IsYUV() const { return !!(pixel_type&CS_YUV ); }\nbool VideoInfo::IsYUY2() const { return (pixel_type & CS_YUY2) == CS_YUY2; }\n\nbool VideoInfo::IsYV24()  const { return (pixel_type & CS_PLANAR_MASK) == (CS_YV24  & CS_PLANAR_FILTER); }\nbool VideoInfo::IsYV16()  const { return (pixel_type & CS_PLANAR_MASK) == (CS_YV16  & CS_PLANAR_FILTER); }\nbool VideoInfo::IsYV12()  const { return (pixel_type & CS_PLANAR_MASK) == (CS_YV12  & CS_PLANAR_FILTER); }\nbool VideoInfo::IsY8()    const { return (pixel_type & CS_PLANAR_MASK) == (CS_Y8    & CS_PLANAR_FILTER); }\n\nbool VideoInfo::IsYV411() const { return (pixel_type & CS_PLANAR_MASK) == (CS_YV411 & CS_PLANAR_FILTER); }\n//bool VideoInfo::IsYUV9()  const { return (pixel_type & CS_PLANAR_MASK) == (CS_YUV9  & CS_PLANAR_FILTER); }\n\n/* Baked ********************\nbool VideoInfo::IsColorSpace(int c_space) const { return ((pixel_type & c_space) == c_space); }\n   Baked ********************/\nbool VideoInfo::IsColorSpace(int c_space) const {\n  // This function will check if the colorspace (VideoInfo.pixel_type) is the same as given c_space (or more general it checks for a Colorspace property (see avisynth.h)).\n  // So it's not only for exact colorspace comparison but checking properties also.\n  return IsPlanar() ? ((pixel_type & CS_PLANAR_MASK) == (c_space & CS_PLANAR_FILTER)) :\n    // support exact individual flag checking\n    c_space == CS_YUVA ? ((c_space & CS_YUVA) == CS_YUVA) :\n    c_space == CS_BGR ? ((c_space & CS_BGR) == CS_BGR) :\n    c_space == CS_YUV ? ((c_space & CS_YUV) == CS_YUV) :\n    c_space == CS_INTERLEAVED ? ((c_space & CS_INTERLEAVED) == CS_INTERLEAVED) :\n  // RGB got sample bits:\n  // In order to work: RGB64.IsColorSpace(RGB32) => false, or else we get true (RGB64 & RGB32 == RGB32)\n  // Simple ((pixel_type & c_space) == c_space) would not work, does not take into account bit depth\n    ( ((pixel_type & ~CS_Sample_Bits_Mask & c_space) == (c_space & ~CS_Sample_Bits_Mask)) &&\n        ((pixel_type & CS_Sample_Bits_Mask) == (c_space & CS_Sample_Bits_Mask)) );\n}\n\nbool VideoInfo::Is(int property) const { return ((image_type & property)==property ); }\nbool VideoInfo::IsPlanar() const { return !!(pixel_type & CS_PLANAR); }\nbool VideoInfo::IsFieldBased() const { return !!(image_type & IT_FIELDBASED); }\nbool VideoInfo::IsParityKnown() const { return ((image_type & IT_FIELDBASED)&&(image_type & (IT_BFF|IT_TFF))); }\nbool VideoInfo::IsBFF() const { return !!(image_type & IT_BFF); }\nbool VideoInfo::IsTFF() const { return !!(image_type & IT_TFF); }\n\n/* Baked ********************\nbool VideoInfo::IsVPlaneFirst() const {return ((pixel_type & CS_YV12) == CS_YV12); }  // Don't use this\nint VideoInfo::BytesFromPixels(int pixels) const { return pixels * (BitsPerPixel()>>3); }   // Will not work on planar images, but will return only luma planes\nint VideoInfo::RowSize() const { return BytesFromPixels(width); }  // Also only returns first plane on planar images\nint VideoInfo::BMPSize() const { if (IsPlanar()) {int p = height * ((RowSize()+3) & ~3); p+=p>>1; return p;  } return height * ((RowSize()+3) & ~3); }\nint64_t VideoInfo::AudioSamplesFromFrames(int64_t frames) const { return (fps_numerator && HasVideo()) ? ((int64_t)(frames) * audio_samples_per_second * fps_denominator / fps_numerator) : 0; }\n   Baked ********************/\nint64_t VideoInfo::AudioSamplesFromFrames(int frames) const { return (fps_numerator && HasVideo()) ? ((int64_t)(frames) * audio_samples_per_second * fps_denominator / fps_numerator) : 0; }\nint VideoInfo::FramesFromAudioSamples(int64_t samples) const { return (fps_denominator && HasAudio()) ? (int)((samples * fps_numerator)/((int64_t)fps_denominator * audio_samples_per_second)) : 0; }\nint64_t VideoInfo::AudioSamplesFromBytes(int64_t bytes) const { return HasAudio() ? bytes / BytesPerAudioSample() : 0; }\nint64_t VideoInfo::BytesFromAudioSamples(int64_t samples) const { return samples * BytesPerAudioSample(); }\nint VideoInfo::AudioChannels() const { return HasAudio() ? nchannels : 0; }\nint VideoInfo::SampleType() const{ return sample_type;}\nbool VideoInfo::IsSampleType(int testtype) const{ return !!(sample_type&testtype);}\nint VideoInfo::SamplesPerSecond() const { return audio_samples_per_second; }\nint VideoInfo::BytesPerAudioSample() const { return nchannels*BytesPerChannelSample();}\nvoid VideoInfo::SetFieldBased(bool isfieldbased)  { if (isfieldbased) image_type|=IT_FIELDBASED; else  image_type&=~IT_FIELDBASED; }\nvoid VideoInfo::Set(int property)  { image_type|=property; }\nvoid VideoInfo::Clear(int property)  { image_type&=~property; }\n\n/* Baked ********************\nint VideoInfo::BitsPerPixel() const {\n  switch (pixel_type) {\n    case CS_BGR24:\n      return 24;\n    case CS_BGR32:\n      return 32;\n    case CS_YUY2:\n      return 16;\n    case CS_YV12:\n    case CS_I420:\n      return 12;\n    default:\n      return 0;\n  }\n}\n   Baked ********************/\n\nint VideoInfo::BytesPerChannelSample() const {\n  switch (sample_type) {\n  case SAMPLE_INT8:\n    return sizeof(unsigned char);\n  case SAMPLE_INT16:\n    return sizeof(signed short);\n  case SAMPLE_INT24:\n    return 3;\n  case SAMPLE_INT32:\n    return sizeof(signed int);\n  case SAMPLE_FLOAT:\n    return sizeof(SFLOAT);\n  default:\n    _ASSERTE(\"Audio sample type not recognized!\");\n    return 0;\n  }\n}\n\nbool VideoInfo::IsVPlaneFirst() const {\n  return (NumComponents() > 1) && IsPlanar() && (pixel_type & (CS_VPlaneFirst | CS_UPlaneFirst)) == CS_VPlaneFirst;   // Shouldn't use this\n}\n\nint VideoInfo::BytesFromPixels(int pixels) const {\n    const int componentSizes[8] = {1,2,4,0,0,2,2,2};\n    return (NumComponents() > 1) && IsPlanar() ? pixels * componentSizes[(pixel_type>>CS_Shift_Sample_Bits) & 7] : pixels * (BitsPerPixel()>>3);\n    // For planar images, will return luma plane\n}\n\nint VideoInfo::RowSize(int plane) const {\n  const int rowsize = BytesFromPixels(width);\n  switch (plane) {\n    case PLANAR_U: case PLANAR_V:\n      return ((NumComponents() > 1) && IsPlanar() && !IsPlanarRGB() && !IsPlanarRGBA()) ? rowsize>>GetPlaneWidthSubsampling(plane) : 0;\n\n    case PLANAR_U_ALIGNED: case PLANAR_V_ALIGNED:\n      return ((NumComponents() > 1) && IsPlanar() && !IsPlanarRGB() && !IsPlanarRGBA()) ? ((rowsize>>GetPlaneWidthSubsampling(plane))+FRAME_ALIGN-1)&(~(FRAME_ALIGN-1)) : 0; // Aligned rowsize\n\n    case PLANAR_Y_ALIGNED:\n      return (rowsize+FRAME_ALIGN-1)&(~(FRAME_ALIGN-1)); // Aligned rowsize\n\n    case PLANAR_R: case PLANAR_G: case PLANAR_B:\n        return ((NumComponents() > 1) && (IsPlanarRGB() || IsPlanarRGBA())) ? rowsize : 0;\n\n    case PLANAR_R_ALIGNED: case PLANAR_G_ALIGNED: case PLANAR_B_ALIGNED:\n        return IsPlanarRGB() || IsPlanarRGBA() ? (rowsize+FRAME_ALIGN-1)&(~(FRAME_ALIGN-1)) : 0; // Aligned rowsize\n\n    case PLANAR_A:\n        return ((NumComponents() == 4) && IsPlanar()) ? rowsize : 0;\n\n    case PLANAR_A_ALIGNED:\n        return ((NumComponents() == 4) && IsPlanar()) ? (rowsize+FRAME_ALIGN-1)&(~(FRAME_ALIGN-1)) : 0; // Aligned rowsize\n\n  }\n  return rowsize;\n}\n\nint VideoInfo::BMPSize() const {\n  if ((NumComponents() > 1) && IsPlanar()) {\n    if (IsPlanarRGB() || IsPlanarRGBA()) {\n      return ((RowSize(PLANAR_G) + 3) & ~3) * height * NumComponents(); // does it make sense for planar rgb?\n    }\n    // Y plane\n    const int Ybytes  = ((RowSize(PLANAR_Y)+3) & ~3) * height;\n    const int UVbytes = Ybytes >> (GetPlaneWidthSubsampling(PLANAR_U)+GetPlaneHeightSubsampling(PLANAR_U));\n    return Ybytes + UVbytes*2;\n  }\n  return height * ((RowSize()+3) & ~3);\n}\n\nint VideoInfo::GetPlaneWidthSubsampling(int plane) const {  // Subsampling in bitshifts!\n  if (plane == PLANAR_Y || plane == PLANAR_R || plane == PLANAR_G || plane == PLANAR_B || plane == PLANAR_A)  // No subsampling\n    return 0;\n  if (NumComponents() == 1)\n    throw AvisynthError(\"Filter error: GetPlaneWidthSubsampling not available on greyscale pixel type.\");\n  if (plane == PLANAR_U || plane == PLANAR_V) {\n    if (IsYUY2())\n      return 1;\n    else if (IsPlanar())\n      return ((pixel_type>>CS_Shift_Sub_Width)+1) & 3;\n    else\n      throw AvisynthError(\"Filter error: GetPlaneWidthSubsampling called with unsupported pixel type.\");\n  }\n  throw AvisynthError(\"Filter error: GetPlaneWidthSubsampling called with unsupported plane.\");\n}\n\nint VideoInfo::GetPlaneHeightSubsampling(int plane) const {  // Subsampling in bitshifts!\n  if (plane == PLANAR_Y || plane == PLANAR_R || plane == PLANAR_G || plane == PLANAR_B || plane == PLANAR_A)  // No subsampling\n    return 0;\n  if (NumComponents() == 1)\n    throw AvisynthError(\"Filter error: GetPlaneHeightSubsampling not available on greyscale pixel type.\");\n  if (plane == PLANAR_U || plane == PLANAR_V) {\n    if (IsYUY2())\n      return 0;\n    else if (IsPlanar())\n      return ((pixel_type>>CS_Shift_Sub_Height)+1) & 3;\n    else\n      throw AvisynthError(\"Filter error: GetPlaneHeightSubsampling called with unsupported pixel type.\");\n  }\n  throw AvisynthError(\"Filter error: GetPlaneHeightSubsampling called with unsupported plane.\");\n}\n\nint VideoInfo::BitsPerPixel() const {\n// Lookup Interleaved, calculate PLANAR's\n// Remark:\n// - total bitsize for interleaved/packed types, e.g. RGB48 = 48 = 3x16\n// - byte size corrected with U-V subsampling factor for Planar YUV/YUVA\n// - external softwares may use it for calculating buffer size\n// - use BitsPerComponent instead for returning the pixel component format 8/10/12/14/16/32 bits\n    switch (pixel_type) {\n      case CS_BGR24:\n        return 24;\n      case CS_BGR32:\n        return 32;\n      case CS_YUY2:\n        return 16;\n      case CS_Y8:\n        return 8;\n      case CS_Y10:\n      case CS_Y12:\n      case CS_Y14:\n      case CS_Y16: // AVS16\n        return 16;\n      case CS_Y32:\n        return 32;\n      case CS_BGR48:\n        return 48;\n      case CS_BGR64:\n        return 64;\n    }\n    if (IsPlanar()) {\n      const int componentSizes[8] = {1,2,4,0,0,2,2,2};\n      const int S = (IsYUV() || IsYUVA()) ? GetPlaneWidthSubsampling(PLANAR_U) + GetPlaneHeightSubsampling(PLANAR_U) : 0; // planar RGBA: no subsampling\n      const int fullSizePlaneCount = IsYUVA() || IsPlanarRGBA() ? 2 : 1; // alpha plane is always full size\n      return (((fullSizePlaneCount << S) + 2) * (componentSizes[(pixel_type >> CS_Shift_Sample_Bits) & 7]) * 8) >> S;\n    }\n    return 0;\n}\n\n// useful mutator\nvoid VideoInfo::SetFPS(unsigned numerator, unsigned denominator) {\n  if ((numerator == 0) || (denominator == 0)) {\n    fps_numerator = 0;\n    fps_denominator = 1;\n  }\n  else {\n    unsigned x=numerator, y=denominator;\n    while (y) {   // find gcd\n      unsigned t = x%y; x = y; y = t;\n    }\n    fps_numerator = numerator/x;\n    fps_denominator = denominator/x;\n  }\n}\n\n// Range protected multiply-divide of FPS\nvoid VideoInfo::MulDivFPS(unsigned multiplier, unsigned divisor) {\n  uint64_t numerator   = UInt32x32To64(fps_numerator,   multiplier);\n  uint64_t denominator = UInt32x32To64(fps_denominator, divisor);\n\n  uint64_t x=numerator, y=denominator;\n  while (y) {   // find gcd\n    uint64_t t = x%y; x = y; y = t;\n  }\n  numerator   /= x; // normalize\n  denominator /= x;\n\n  uint64_t temp = numerator | denominator; // Just looking top bit\n  unsigned u = 0;\n  while (temp & 0xffffffff80000000) { // or perhaps > 16777216*2\n    temp = Int64ShrlMod32(temp, 1);\n    u++;\n  }\n  if (u) { // Scale to fit\n    const unsigned round = 1 << (u-1);\n    SetFPS( (unsigned)Int64ShrlMod32(numerator   + round, u),\n            (unsigned)Int64ShrlMod32(denominator + round, u) );\n  }\n  else {\n    fps_numerator   = (unsigned)numerator;\n    fps_denominator = (unsigned)denominator;\n  }\n}\n\n// Test for same colorspace\nbool VideoInfo::IsSameColorspace(const VideoInfo& vi) const {\n  if (vi.pixel_type == pixel_type) return TRUE;\n  if (IsYV12() && vi.IsYV12()) return TRUE;\n  return FALSE;\n}\n\nint VideoInfo::NumComponents() const {\n\n  switch (pixel_type) {\n  case CS_UNKNOWN:\n     return 0;\n  case CS_RAW32:\n  case CS_Y8:\n  case CS_Y10:\n  case CS_Y12:\n  case CS_Y14:\n  case CS_Y16:\n  case CS_Y32:\n    return 1;\n  case CS_BGR32:\n  case CS_BGR64:\n    return 4; // these are not planar but return the count\n  default:\n      return (IsYUVA() || IsPlanarRGBA()) ? 4 : 3;\n      // 3: YUV, planar RGB, 24/48 bit RGB\n      // 4: YUVA and PlanarRGBA\n  }\n}\n\nint VideoInfo::ComponentSize() const {\n// occupied bytes per one pixel component\n  if(IsPlanar()) {\n    const int componentSizes[8] = {1,2,4,0,0,2,2,2};\n    return componentSizes[(pixel_type >> CS_Shift_Sample_Bits) & 7];\n  }\n  switch (pixel_type) {\n  case CS_UNKNOWN:\n    return 0;\n  case CS_RAW32:\n    return 4;\n  case CS_BGR48:\n  case CS_BGR64:\n    return 2;\n  default: // YUY2, packed 8 bit BGRs\n    return 1;\n  }\n}\n\nint VideoInfo::BitsPerComponent() const {\n// unlike BitsPerPixel, this returns the real\n// component size as 8/10/12/14/16/32 bit\n    if (pixel_type == CS_YUY2)\n        return 8;\n    else if (pixel_type == CS_RAW32)\n        return 32;\n    // planar YUV/RGB and packed RGB\n    const int componentBitSizes[8] = {8,16,32,0,0,10,12,14};\n    return componentBitSizes[(pixel_type >> CS_Shift_Sample_Bits) & 7];\n}\n\n// bit-depth independent helper functions instead of 8 bit specific IsYV24/16/12/8\nbool VideoInfo::Is444()  const { return ((pixel_type & CS_PLANAR_MASK & ~CS_Sample_Bits_Mask) == (CS_GENERIC_YUV444 & CS_PLANAR_FILTER)) ||\n                                        ((pixel_type & CS_PLANAR_MASK & ~CS_Sample_Bits_Mask) == (CS_GENERIC_YUVA444 & CS_PLANAR_FILTER)) ; }\nbool VideoInfo::Is422()  const { return ((pixel_type & CS_PLANAR_MASK & ~CS_Sample_Bits_Mask) == (CS_GENERIC_YUV422 & CS_PLANAR_FILTER)) ||\n                                        ((pixel_type & CS_PLANAR_MASK & ~CS_Sample_Bits_Mask) == (CS_GENERIC_YUVA422 & CS_PLANAR_FILTER)); }\nbool VideoInfo::Is420()  const { return ((pixel_type & CS_PLANAR_MASK & ~CS_Sample_Bits_Mask) == (CS_GENERIC_YUV420 & CS_PLANAR_FILTER)) ||\n                                        ((pixel_type & CS_PLANAR_MASK & ~CS_Sample_Bits_Mask) == (CS_GENERIC_YUVA420 & CS_PLANAR_FILTER)); }\nbool VideoInfo::IsY()       const { return (pixel_type & CS_PLANAR_MASK & ~CS_Sample_Bits_Mask) == (CS_GENERIC_Y      & CS_PLANAR_FILTER); }\nbool VideoInfo::IsRGB48()   const { return ((pixel_type & CS_BGR24) == CS_BGR24) && ((pixel_type & CS_Sample_Bits_Mask) == CS_Sample_Bits_16); } // Clear out additional properties\nbool VideoInfo::IsRGB64()   const { return ((pixel_type & CS_BGR32) == CS_BGR32) && ((pixel_type & CS_Sample_Bits_Mask) == CS_Sample_Bits_16); }\nbool VideoInfo::IsYUVA() const { return !!(pixel_type&CS_YUVA ); }\nbool VideoInfo::IsPlanarRGB() const { return !!(pixel_type&CS_PLANAR) && !!(pixel_type&CS_BGR) && !!(pixel_type&CS_RGB_TYPE); }\nbool VideoInfo::IsPlanarRGBA() const { return !!(pixel_type&CS_PLANAR) && !!(pixel_type&CS_BGR) && !!(pixel_type&CS_RGBA_TYPE); }\nbool VideoInfo::IsChannelMaskKnown() const { return !!(image_type & IT_HAS_CHANNELMASK); }\n// Re-maps and stores channel mask into image_type, sets the 'has channel mask' flag as well\nvoid VideoInfo::SetChannelMask(bool isChannelMaskKnown, unsigned int dwChannelMask)\n{\n  if (isChannelMaskKnown) image_type |= IT_HAS_CHANNELMASK; else image_type &= ~IT_HAS_CHANNELMASK;\n  if (!isChannelMaskKnown) dwChannelMask = 0;\n  if (dwChannelMask & AvsChannelMask::MASK_SPEAKER_ALL) // special mapping due to lack of bits in image_type\n    dwChannelMask = AvsImageTypeFlags::IT_SPEAKER_ALL;\n  else {\n    dwChannelMask &= AvsChannelMask::MASK_SPEAKER_DEFINED;\n    dwChannelMask <<= 4;\n  }\n  image_type &= ~AvsImageTypeFlags::IT_SPEAKER_BITS_MASK;\n  image_type |= dwChannelMask;\n}\n\nunsigned int VideoInfo::GetChannelMask() const\n{\n  // returns zero if not defined\n  if (!IsChannelMaskKnown()) return 0;\n  unsigned int dwChannelMask = image_type & AvsImageTypeFlags::IT_SPEAKER_BITS_MASK;\n  // returns the original SPEAKER_ALL constant\n  if (dwChannelMask == AvsImageTypeFlags::IT_SPEAKER_ALL)\n    return AvsChannelMask::MASK_SPEAKER_ALL;\n  // other SPEAKER bits were simply shifted by 4 bits\n  return dwChannelMask >> 4;\n}\n\n\n// end struct VideoInfo\n\n/**********************************************************************/\n\n// class VideoFrameBuffer\n\nconst BYTE* VideoFrameBuffer::GetReadPtr() const { return data; }\n/* Baked ********************\nBYTE* VideoFrameBuffer::GetWritePtr() { ++sequence_number; return data; }\n   Baked ********************/\nBYTE* VideoFrameBuffer::GetWritePtr() { InterlockedIncrement(&sequence_number); return data; }\nint VideoFrameBuffer::GetDataSize() const { return data_size; }\nint VideoFrameBuffer::GetSequenceNumber() const { return sequence_number; }\nint VideoFrameBuffer::GetRefcount() const { return refcount; }\n\n// end class VideoFrameBuffer\n\n/**********************************************************************/\n\n// class VideoFrame\n\n/* Baked ********************\nvoid VideoFrame::AddRef() { InterlockedIncrement((int *)&refcount); }\nvoid VideoFrame::Release() { if (refcount==1) InterlockedDecrement(&vfb->refcount); InterlockedDecrement((int *)&refcount); }\n\nint VideoFrame::GetPitch() const { return pitch; }\nint VideoFrame::GetPitch(int plane) const { switch (plane) {case PLANAR_U: case PLANAR_V: return pitchUV;} return pitch; }\nint VideoFrame::GetRowSize() const { return row_size; }\n\nint VideoFrame::GetRowSize(int plane) const {\n  switch (plane) {\n  case PLANAR_U: case PLANAR_V: if (pitchUV) return row_size>>1; else return 0;\n  case PLANAR_U_ALIGNED: case PLANAR_V_ALIGNED:\n    if (pitchUV) {\n      int r = ((row_size+FRAME_ALIGN-1)&(~(FRAME_ALIGN-1)) )>>1; // Aligned rowsize\n      if (r<=pitchUV)\n        return r;\n      return row_size>>1;\n    } else return 0;\n  case PLANAR_Y_ALIGNED:\n    int r = (row_size+FRAME_ALIGN-1)&(~(FRAME_ALIGN-1)); // Aligned rowsize\n    if (r<=pitch)\n      return r;\n    return row_size;\n  }\n  return row_size; }\n\nint VideoFrame::GetHeight() const { return height; }\nint VideoFrame::GetHeight(int plane) const {  switch (plane) {case PLANAR_U: case PLANAR_V: if (pitchUV) return height>>1; return 0;} return height; }\n\n// generally you shouldn't use these three\nVideoFrameBuffer* VideoFrame::GetFrameBuffer() const { return vfb; }\nint VideoFrame::GetOffset() const { return offset; }\nint VideoFrame::GetOffset(int plane) const { switch (plane) {case PLANAR_U: return offsetU;case PLANAR_V: return offsetV;default: return offset;}; }\n\nconst BYTE* VideoFrame::GetReadPtr() const { return vfb->GetReadPtr() + offset; }\nconst BYTE* VideoFrame::GetReadPtr(int plane) const { return vfb->GetReadPtr() + GetOffset(plane); }\n\nbool VideoFrame::IsWritable() const { return (refcount == 1 && vfb->refcount == 1); }\n\nBYTE* VideoFrame::GetWritePtr() const {\n  if (vfb->GetRefcount()>1) {\n    _ASSERT(FALSE);\n    //throw AvisynthError(\"Internal Error - refcount was more than one!\");\n  }\n  return IsWritable() ? (vfb->GetWritePtr() + offset) : 0;\n}\n   Baked ********************/\n\nvoid VideoFrame::AddRef() { InterlockedIncrement(&refcount); }\nvoid VideoFrame::Release() {\n  VideoFrameBuffer* _vfb = vfb;\n\n  if (!InterlockedDecrement(&refcount)) {\n    // Do NOT touch 'properties' here. The FrameRegistry (under memory_mutex) is the\n    // sole owner: it clears the AVSMap contents for reuse (winner frames) or deletes\n    // it entirely (discarded frames). Freeing or clearing here without that lock would\n    // race with concurrent FrameRegistry access.\n#ifdef ALTERNATIVE_VFB_TIMESTAMP\n    if (!InterlockedDecrement(&_vfb->refcount)) {\n      // all VideoFrameBuffer instances are actually VFBStorage, which has way mode admin fields\n      VFBHelper::UpdateVFBFreeTimestamp(_vfb);\n    }\n#else\n    InterlockedDecrement(&_vfb->refcount);\n#endif\n  }\n}\n\nint VideoFrame::GetPitch(int plane) const { switch (plane) { case PLANAR_U: case PLANAR_V: return pitchUV; case PLANAR_A: return pitchA; } return pitch; }\n\nint VideoFrame::GetRowSize(int plane) const {\n  switch (plane) {\n  case PLANAR_U: case PLANAR_V: if (pitchUV) return row_sizeUV; else return 0;\n  case PLANAR_U_ALIGNED: case PLANAR_V_ALIGNED:\n    if (pitchUV) {\n      const int r = (row_sizeUV+FRAME_ALIGN-1)&(~(FRAME_ALIGN-1)); // Aligned rowsize\n      if (r<=pitchUV)\n        return r;\n      return row_sizeUV;\n    }\n    else return 0;\n  case PLANAR_ALIGNED: case PLANAR_Y_ALIGNED:\n  case PLANAR_R_ALIGNED: case PLANAR_G_ALIGNED: case PLANAR_B_ALIGNED:\n    {\n    const int r = (row_size+FRAME_ALIGN-1)&(~(FRAME_ALIGN-1)); // Aligned rowsize\n    if (r<=pitch)\n      return r;\n    return row_size;\n  }\n  case PLANAR_A:\n    if (pitchA) return row_sizeA; else return 0;\n  case PLANAR_A_ALIGNED:\n    if(pitchA) {\n      const int r = (row_sizeA+FRAME_ALIGN-1)&(~(FRAME_ALIGN-1)); // Aligned rowsize\n      if (r<=pitchA)\n        return r;\n      return row_sizeA;\n    }\n    else return 0;\n  }\n  return row_size; // PLANAR_Y, PLANAR_G, PLANAR_B, PLANAR_R\n}\n\nint VideoFrame::GetHeight(int plane) const {\n  switch (plane) {\n  case PLANAR_U: case PLANAR_V: if (pitchUV) return heightUV; return 0;\n  case PLANAR_A: if (pitchA) return height; return 0;\n  }\n  return height;\n}\n\nint VideoFrame::GetPixelType() const { return pixel_type; }\nvoid VideoFrame::AmendPixelType(int new_pixel_type) { pixel_type = new_pixel_type; }\n\n// Generally you should not be using these two\nVideoFrameBuffer* VideoFrame::GetFrameBuffer() const { return vfb; }\nint VideoFrame::GetOffset(int plane) const {\n    switch (plane) {\n    case PLANAR_U: case PLANAR_B: return offsetU; // G is first. Then B,R order like U,V\n    case PLANAR_V: case PLANAR_R: return offsetV;\n    case PLANAR_A: return offsetA;\n    default: return offset; // PLANAR Y, PLANAR_G\n    };\n}\n\nconst BYTE* VideoFrame::GetReadPtr(int plane) const { return vfb->GetReadPtr() + GetOffset(plane); }\n\nbool VideoFrame::IsWritable() const {\n  if (refcount == 1 && vfb->refcount == 1) {\n    vfb->GetWritePtr(); // Bump sequence number\n    return true;\n  }\n  return false;\n}\n\nbool VideoFrame::IsPropertyWritable() const {\n  return (refcount == 1);\n}\n\nBYTE* VideoFrame::GetWritePtr(int plane) const {\n  if (!plane || plane == PLANAR_Y || plane == PLANAR_G) { // planar RGB order GBR\n    if (vfb->GetRefcount()>1) {\n      _ASSERT(FALSE);\n//        throw AvisynthError(\"Internal Error - refcount was more than one!\");\n    }\n    return (refcount == 1 && vfb->refcount == 1) ? vfb->GetWritePtr() + GetOffset(plane) : 0;\n  }\n  return vfb->data + GetOffset(plane);\n}\n\nAVSMap& VideoFrame::getProperties() {\n  return *properties;\n}\n\nconst AVSMap& VideoFrame::getConstProperties() {\n  return *properties;\n}\n\nvoid VideoFrame::setProperties(const AVSMap& properties) {\n  *(this->properties) = properties;\n}\n\nPDevice VideoFrame::GetDevice() const {\n  return vfb->device;\n}\n\nint VideoFrame::CheckMemory() const {\n#ifdef _DEBUG\n  if (vfb->data && vfb->device->device_type == DEV_TYPE_CPU) {\n    // check buffer overrun\n    int *pInt = (int *)(vfb->data + vfb->data_size);\n    if (pInt[0] != 0xDEADBEEF ||\n      pInt[1] != 0xDEADBEEF ||\n      pInt[2] != 0xDEADBEEF ||\n      pInt[3] != 0xDEADBEEF)\n    {\n      return 1;\n    }\n    return 0;\n  }\n#endif\n  return -1;\n}\n\n/* Baked ********************\nVideoFrame::~VideoFrame() { InterlockedDecrement(&vfb->refcount); }\n   Baked ********************/\nVideoFrame::~VideoFrame()     { DESTRUCTOR(); }\nvoid VideoFrame::DESTRUCTOR() { \n  Release(); \n  // finally destroyed when removed from FrameRegistry\n  if (properties) {\n    delete properties;\n    properties = nullptr;\n  }\n}\n\n// end class VideoFrame\n\n/**********************************************************************/\n\n// class IClip\n\n/* Baked ********************\n  void IClip::AddRef() { InterlockedIncrement((int *)&refcnt); }\n  void IClip::Release() { InterlockedDecrement((int *)&refcnt); if (!refcnt) delete this; }\n   Baked ********************/\nvoid IClip::AddRef() { InterlockedIncrement(&refcnt); }\nvoid IClip::Release() { if (!InterlockedDecrement(&refcnt)) delete this; }\n\n// end class IClip\n\n/**********************************************************************/\n\n// class PClip\n\nIClip* PClip::GetPointerWithAddRef() const { if (p) p->AddRef(); return p; }\n\nvoid PClip::Init(IClip* x) {\n  if (x) x->AddRef();\n  p=x;\n}\n\nvoid PClip::Set(IClip* x) {\n  if (x) x->AddRef();\n  if (p) p->Release();\n  p=x;\n}\n\nPClip::PClip()                               { CONSTRUCTOR0(); }\nvoid PClip::CONSTRUCTOR0()                   { p = 0; }\n\nPClip::PClip(const PClip& x)                 { CONSTRUCTOR1(x); }\nvoid PClip::CONSTRUCTOR1(const PClip& x)     { Init(x.p); }\n\nPClip::PClip(IClip* x)                       { CONSTRUCTOR2(x); }\nvoid PClip::CONSTRUCTOR2(IClip* x)           { Init(x); }\n\nvoid PClip::operator=(IClip* x)              { OPERATOR_ASSIGN0(x); }\nvoid PClip::OPERATOR_ASSIGN0(IClip* x)       { Set(x); }\n\nvoid PClip::operator=(const PClip& x)        { OPERATOR_ASSIGN1(x); }\nvoid PClip::OPERATOR_ASSIGN1(const PClip& x) { Set(x.p); }\n\nPClip::~PClip()                              { DESTRUCTOR(); }\nvoid PClip::DESTRUCTOR()                     { if (p) p->Release(); }\n\n// end class PClip\n\n/**********************************************************************/\n\n// class PVideoFrame\n\nvoid PVideoFrame::Init(VideoFrame* x) {\n  if (x) x->AddRef();\n  p=x;\n}\n\nvoid PVideoFrame::Set(VideoFrame* x) {\n  if (x) x->AddRef();\n  if (p) p->Release();\n  p=x;\n}\n\nPVideoFrame::PVideoFrame()                               { CONSTRUCTOR0(); }\nvoid PVideoFrame::CONSTRUCTOR0()                         { p = 0; }\n\nPVideoFrame::PVideoFrame(const PVideoFrame& x)           { CONSTRUCTOR1(x); }\nvoid PVideoFrame::CONSTRUCTOR1(const PVideoFrame& x)     { Init(x.p); }\n\nPVideoFrame::PVideoFrame(VideoFrame* x)                  { CONSTRUCTOR2(x); }\nvoid PVideoFrame::CONSTRUCTOR2(VideoFrame* x)            { Init(x); }\n\nvoid PVideoFrame::operator=(VideoFrame* x)               { OPERATOR_ASSIGN0(x); }\nvoid PVideoFrame::OPERATOR_ASSIGN0(VideoFrame* x)        { Set(x); }\n\nvoid PVideoFrame::operator=(const PVideoFrame& x)        { OPERATOR_ASSIGN1(x); }\nvoid PVideoFrame::OPERATOR_ASSIGN1(const PVideoFrame& x) { Set(x.p); }\n\nPVideoFrame::~PVideoFrame()                              { DESTRUCTOR(); }\nvoid PVideoFrame::DESTRUCTOR()                           { if (p) p->Release(); }\n\n\n// end class PVideoFrame\n\n/**********************************************************************/\n\n// class AVSValue\n\nAVSValue::AVSValue()                                     { CONSTRUCTOR0(); }\nvoid AVSValue::CONSTRUCTOR0()                            { type = 'v'; array_size = 0; clip = NULL; }\n\nAVSValue::AVSValue(IClip* c)                             { CONSTRUCTOR1(c); }\nvoid AVSValue::CONSTRUCTOR1(IClip* c)                    { type = 'c'; array_size = 0; clip = c; if (c) c->AddRef(); }\n\nAVSValue::AVSValue(const PClip& c)                       { CONSTRUCTOR2(c); }\nvoid AVSValue::CONSTRUCTOR2(const PClip& c)              { type = 'c'; array_size = 0; clip = c.GetPointerWithAddRef(); }\n\nAVSValue::AVSValue(bool b)                               { CONSTRUCTOR3(b); }\nvoid AVSValue::CONSTRUCTOR3(bool b)                      { type = 'b'; array_size = 0; clip = NULL; boolean = b; }\n\nAVSValue::AVSValue(int i)                                { CONSTRUCTOR4(i); }\nvoid AVSValue::CONSTRUCTOR4(int i)                       { type = 'i'; array_size = 0; clip = NULL; integer = i; }\n\nAVSValue::AVSValue(float f)                              { CONSTRUCTOR5(f); }\nvoid AVSValue::CONSTRUCTOR5(float f)                     { type = 'f'; array_size = 0; clip = NULL; floating_pt = f; }\n\nAVSValue::AVSValue(double f)                             { CONSTRUCTOR6(f); }\nvoid AVSValue::CONSTRUCTOR6(double f)\n{\n  type = 'd'; array_size = 0; clip = NULL;\n#if UINTPTR_MAX >= 0xffffffffffffffff\n  // pre-v11: floating_pt = float(f);\n  double_pt = f; // v11: real 64 bit double!\n#else\n  double_pt_ptr = new double;\n  *double_pt_ptr = f;\n#endif\n}\n\nAVSValue::AVSValue(const char* s)                        { CONSTRUCTOR7(s); }\nvoid AVSValue::CONSTRUCTOR7(const char* s)               { type = 's'; array_size = 0; string = s; }\n\n/* Baked ********************\nAVSValue::AVSValue(const AVSValue* a, int size) { type = 'a'; array = a; array_size = size; }\n   Baked ********************/\nAVSValue::AVSValue(const AVSValue& a, int size)          { CONSTRUCTOR8(&a, size); }\nAVSValue::AVSValue(const AVSValue* a, int size)          { CONSTRUCTOR8(a, size); }\nvoid AVSValue::CONSTRUCTOR8(const AVSValue* a, int size)\n{\n  type = 'a';\n  array_size = (short)size;\n  if (a == nullptr)\n    size = 0;\n  array = new AVSValue[size]; // even for size = 0 a valid ptr is given\n  for (int i = 0; i < size; i++) {\n    const_cast<AVSValue*>(array)[i].Assign(&a[i], true); // init from source\n  }\n}\n\nAVSValue::AVSValue(const AVSValue& v)                    { CONSTRUCTOR9(v); }\nvoid AVSValue::CONSTRUCTOR9(const AVSValue& v)           { Assign(&v, true); }\n\n// from compatibility interface\nAVSValue::AVSValue(const AVSValue& v, bool no_deep_arrays) { CONSTRUCTOR10(v, no_deep_arrays); }\nvoid AVSValue::CONSTRUCTOR10(const AVSValue& v, bool no_deep_arrays)  { Assign2(&v, true, no_deep_arrays); }\n\nAVSValue::AVSValue(const PFunction& n) { CONSTRUCTOR11(n); }\nvoid AVSValue::CONSTRUCTOR11(const PFunction& n) { type = 'n'; array_size = 0; function = n.GetPointerWithAddRef(); }\n\nAVSValue::AVSValue(int64_t l) { CONSTRUCTOR12(l); }\nvoid AVSValue::CONSTRUCTOR12(int64_t l) { type = 'l'; array_size = 0; clip = NULL; \n#if UINTPTR_MAX >= 0xffffffffffffffff\n  longlong = l; \n#else\n  longlong_ptr = new int64_t;\n  *longlong_ptr = l;\n#endif\n}\n\nAVSValue::~AVSValue()                                    { DESTRUCTOR(); }\nvoid AVSValue::DESTRUCTOR()\n{\n  if (IsClip() && clip)\n    clip->Release();\n  if (IsFunction() && function)\n    function->Release();\n#if !(UINTPTR_MAX >= 0xffffffffffffffff)\n  // 32-bit systems support 64-bit data through dynamic allocation.\n  if (type == 'l' && longlong_ptr) {\n    delete longlong_ptr;\n    longlong_ptr = nullptr;\n  }\n  else if (type == 'd' && double_pt_ptr) {\n    delete double_pt_ptr;\n    double_pt_ptr = nullptr;\n  }\n#endif\n  if (IsArray() && array) {\n    delete[] array; // calls AVSValue destructors for all elements\n    array = nullptr;\n  }\n}\n\nvoid AVSValue::MarkArrayAsNonDeepCopy()\n{\n  // Convert AVSValue content to a neutral 'v' type\n  // to prevent destructor from freeing up the allocated array \n  // and its elements.\n  // Set just before releasing AVSValue.\n  if (type == 'a')\n  {\n    type = 'v';\n    array_size = 0;\n    array = nullptr;\n  }\n}\n\nAVSValue& AVSValue::operator=(const AVSValue& v)         { return OPERATOR_ASSIGN(v); }\nAVSValue& AVSValue::OPERATOR_ASSIGN(const AVSValue& v)   { Assign(&v, false); return *this; }\n\n// pre-v11: Transparently allow 'int' to be treated as 'float'.\n// No int<->bool conversions.\n// v11 64 bit value changes:\n// - 'long' is int64_t.\n// - IsInt returns true for both 'long' and 'int' \n// - IsLong returns true only for exact 64-bit integer type\n// - Transparently allow 'long' and 'int' to be treated as 'float' or 'double'\n// - IsFloat returns true for both 'float' and 'double' (old IsFloat + 'double').\n// - new IsFloatfStrict returns true only for 32-bit floating-point numbers.\n// - new IsLongStrict returns true only for exact 64-bit integer types.\n\n// Note: Exact type check is available GetType() with returns AvsValueType enum\nbool AVSValue::Defined() const { return type != 'v'; }\nbool AVSValue::IsClip() const { return type == 'c'; }\nbool AVSValue::IsBool() const { return type == 'b'; }\nbool AVSValue::IsInt() const { return type == 'i' || type == 'l'; }\nbool AVSValue::IsLongStrict() const { return type == 'l'; }\nbool AVSValue::IsFloat() const { return type == 'd' || type == 'f' || type == 'i' || type == 'l'; }\nbool AVSValue::IsFloatfStrict() const { return type == 'f'; }\nbool AVSValue::IsString() const { return type == 's'; }\nbool AVSValue::IsArray() const { return type == 'a'; }\nbool AVSValue::IsFunction() const { return type == 'n'; }\n\nPClip AVSValue::AsClip() const { _ASSERTE(IsClip()); return IsClip()?clip:0; }\n\nbool AVSValue::AsBool1() const { _ASSERTE(IsBool()); return boolean; }\nbool AVSValue::AsBool() const { return AsBool1(); }\n\nint AVSValue::AsInt1() const { \n  _ASSERTE(IsInt()); \n  // simple typecast, no saturation\n#if UINTPTR_MAX >= 0xffffffffffffffff\n  return type == 'i' ? integer : (int)longlong;\n#else\n  return type == 'i' ? integer : (int)*longlong_ptr;\n#endif\n}\n\nint AVSValue::AsInt() const { return AsInt1(); }\n\nint64_t AVSValue::AsLong1() const {\n  _ASSERTE(IsInt());\n#if UINTPTR_MAX >= 0xffffffffffffffff\n  return type == 'i' ? integer : longlong;\n#else\n  return type == 'i' ? integer : *longlong_ptr;\n#endif\n}\nint64_t AVSValue::AsLong() const { return AsLong1(); }\n\nconst char* AVSValue::AsString1() const { _ASSERTE(IsString()); return IsString()?string:0; }\nconst char* AVSValue::AsString() const { return AVSValue::AsString1(); }\n\ndouble AVSValue::AsFloat1() const { \n#if UINTPTR_MAX >= 0xffffffffffffffff\n  _ASSERTE(IsFloat()); return type == 'i' ? (double)integer : type == 'l' ? (double)longlong : type == 'f' ? (double)floating_pt : double_pt;\n#else\n  _ASSERTE(IsFloat()); return type == 'i' ? (double)integer : type == 'l' ? (double)*longlong_ptr : type == 'f' ? (double)floating_pt : *double_pt_ptr;\n#endif\n}\n\ndouble AVSValue::AsFloat() const { return AsFloat1(); }\n\nfloat AVSValue::AsFloatf() const { \n#if UINTPTR_MAX >= 0xffffffffffffffff\n  _ASSERTE(IsFloat()); return type == 'i' ? (float)integer : type == 'l' ? (float)longlong : type == 'f' ? floating_pt : (float)double_pt;\n#else\n  _ASSERTE(IsFloat()); return type == 'i' ? (float)integer : type == 'l' ? (float)*longlong_ptr : type == 'f' ? floating_pt : (float)*double_pt_ptr;\n#endif\n}\n\nbool AVSValue::AsBool2(bool def) const { _ASSERTE(IsBool()||!Defined()); return IsBool() ? boolean : def; }\nbool AVSValue::AsBool(bool def) const { return AsBool2(def); }\n\nint AVSValue::AsInt2(int def) const { \n  _ASSERTE(IsInt()||!Defined());\n#if UINTPTR_MAX >= 0xffffffffffffffff\n  return type == 'i' ? integer : type == 'l' ? (int)longlong : def;\n#else\n  return type == 'i' ? integer : type == 'l' ? (int)*longlong_ptr : def;\n#endif\n}\n\nint AVSValue::AsInt(int def) const { return AsInt2(def); }\nint64_t AVSValue::AsLong2(int64_t def) const {\n  _ASSERTE(IsInt() || !Defined());\n#if UINTPTR_MAX >= 0xffffffffffffffff\n  return type == 'i' ? integer : type == 'l' ? longlong : def;\n#else\n  return type == 'i' ? integer : type == 'l' ? *longlong_ptr : def;\n#endif\n}\n\nint64_t AVSValue::AsLong(int64_t def) const {\n  return AsLong2(def);\n}\n\ndouble AVSValue::AsDblDef(double def) const { \n  _ASSERTE(IsFloat()||!Defined());\n#if UINTPTR_MAX >= 0xffffffffffffffff\n  return type == 'i' ? (double)integer : type == 'l' ? (double)longlong : type == 'f' ? (double)floating_pt : type == 'd' ? double_pt : def;\n#else\n  return type == 'i' ? (double)integer : type == 'l' ? (double)*longlong_ptr : type == 'f' ? (double)floating_pt : type == 'd' ? *double_pt_ptr : def;\n#endif\n}\n\ndouble AVSValue::AsFloat2(float def) const { \n  _ASSERTE(IsFloat()||!Defined()); \n#if UINTPTR_MAX >= 0xffffffffffffffff\n  return type == 'i' ? integer : type == 'l' ? (double)longlong : type == 'f' ? (double)floating_pt : type == 'd' ? double_pt : (double)def;\n#else\n  return type == 'i' ? integer : type == 'l' ? (double)*longlong_ptr : type == 'f' ? (double)floating_pt : type == 'd' ? *double_pt_ptr : (double)def;\n#endif\n}\n\ndouble AVSValue::AsFloat(float def) const { return AsFloat2(def); }\nfloat AVSValue::AsFloatf(float def) const { return float( AsFloat2(def) ); }\n\nconst char* AVSValue::AsString2(const char* def) const { _ASSERTE(IsString()||!Defined()); return IsString() ? string : def; }\nconst char* AVSValue::AsString(const char* def) const { return AVSValue::AsString2(def); }\n\nPFunction AVSValue::AsFunction() const { _ASSERTE(IsFunction()); return IsFunction() ? function : 0; }\n\nint AVSValue::ArraySize() const { _ASSERTE(IsArray()) ; return IsArray() ? array_size : 1; }\n\nconst AVSValue& AVSValue::operator[](int index) const     { return OPERATOR_INDEX(index); }\nconst AVSValue& AVSValue::OPERATOR_INDEX(int index) const {\n  _ASSERTE(IsArray() && index>=0 && index<array_size);\n  return (IsArray() && index>=0 && index<array_size) ? array[index] : *this;\n}\n\n// This Assign can deep-copy array elements\n// For compatibility interface, we use Assign2 through CONSTRUCTOR10\nvoid AVSValue::Assign(const AVSValue* src, bool init) {\n  Assign2(src, init, false);\n}\n\nvoid AVSValue::Assign2(const AVSValue* src, bool init, bool no_deep_arrays) {\n  if (src->IsClip() && src->clip)\n    src->clip->AddRef();\n  if (src->IsFunction() && src->function)\n    src->function->AddRef();\n\n  // The left side of the assignment (\"this\") will be overwritten by \"src\",\n  // so it should be released or freed if necessary.\n  // The relevant properties must be released/dereferenced at the end:\n  // clip, array, function, double_pt_ptr and longlong_ptr\n  // Since they share the same pointer, saving (void*)clip would do it;\n  const bool shouldReleaseClip = !init && IsClip() && clip;\n  const bool shouldReleaseFunction = !init && IsFunction() && function;\n  const bool shouldReleaseArray = !init && IsArray() && array && !no_deep_arrays;\n#if !(UINTPTR_MAX >= 0xffffffffffffffff)\n  const bool shouldReleaseDouble = !init && type == 'd' && double_pt_ptr;\n  const bool shouldReleaseLong = !init && type == 'l' && longlong_ptr;\n#endif\n  void* prev_pointer_to_release = (void*)clip;\n\n  // common fields\n  this->type = src->type;\n  this->array_size = src->array_size;\n\n  // no_deep_arrays: compatibility for AVS2.5: don't free or deep copy array elements!\n  if (src->IsArray() && !no_deep_arrays)\n  {\n    // Delay releasing the previous array to avoid the args = args[0] case.\n    // If an existing array were freed before this point, it would break the\n    // value = value[x] case where the source value[x] is not an array.\n    // Even for size == 0, this returns a valid pointer.\n    AVSValue* tmp = new AVSValue[array_size];\n    for (int i = 0; i < array_size; i++)\n      tmp[i].Assign(&src->array[i], true); // init from source\n    array = tmp;\n  }\n#if !(UINTPTR_MAX >= 0xffffffffffffffff)\n  // 32 bit Avisynth: new 64 bit types are specially treated\n  else if (this->type == 'l') {\n    const uint64_t l = *src->longlong_ptr;\n    this->longlong_ptr = new int64_t;\n    *this->longlong_ptr = l;\n  }\n  else if (this->type == 'd') {\n    const double d = *src->double_pt_ptr;\n    this->double_pt_ptr = new double;\n    *this->double_pt_ptr = d;\n  }\n#endif\n  else {\n    this->clip = (IClip*)((void*)src->clip);\n    // \"clip\" is the largest member of the union, making sure we copy everything\n  }\n\n  if (shouldReleaseClip)\n    ((IClip*)prev_pointer_to_release)->Release();\n  if (shouldReleaseFunction)\n    ((IFunction*)prev_pointer_to_release)->Release();\n  if (shouldReleaseArray)\n    delete[](AVSValue*)(prev_pointer_to_release);\n  // deallocates former array memory + calls destructor of AVSValue elements\n#if !(UINTPTR_MAX >= 0xffffffffffffffff)\n  if (shouldReleaseDouble)\n    delete (double*)prev_pointer_to_release;\n  else if (shouldReleaseLong)\n    delete (int64_t*)prev_pointer_to_release;\n#endif\n}\n\nAvsValueType AVSValue::GetType() const { return (AvsValueType)type; }\n\n// end class AVSValue\n\n/**********************************************************************/\n\nPFunction::PFunction() { CONSTRUCTOR0(); }\nvoid PFunction::CONSTRUCTOR0() { Init(0); }\n\nPFunction::PFunction(IFunction* p) { CONSTRUCTOR1(p); }\nvoid PFunction::CONSTRUCTOR1(IFunction* p) { Init(p); }\n\nPFunction::PFunction(const PFunction& p) { CONSTRUCTOR2(p); }\nvoid PFunction::CONSTRUCTOR2(const PFunction& p) { Init(p.e); }\n\nPFunction& PFunction::operator=(IFunction* p) { return OPERATOR_ASSIGN0(p); }\nPFunction& PFunction::OPERATOR_ASSIGN0(IFunction* p) { Set(p); return *this; }\n\nPFunction& PFunction::operator=(const PFunction& p) { return OPERATOR_ASSIGN1(p); }\nPFunction& PFunction::OPERATOR_ASSIGN1(const PFunction& p) { Set(p.e); return *this; }\n\nPFunction::~PFunction() { DESTRUCTOR(); }\nvoid PFunction::DESTRUCTOR() { if (e) e->Release(); }\n\nIFunction * PFunction::GetPointerWithAddRef() const { if (e) e->AddRef(); return e; }\nvoid PFunction::Init(IFunction* p) { e = p; if (e) e->AddRef(); }\nvoid PFunction::Set(IFunction* p) { if (p) p->AddRef(); if (e) e->Release(); e = p; }\n\nPDevice::PDevice() { CONSTRUCTOR0(); }\nvoid PDevice::CONSTRUCTOR0() { e = 0; }\n\nPDevice::PDevice(Device* p) { CONSTRUCTOR1(p); }\nvoid PDevice::CONSTRUCTOR1(Device* p) { e = p; }\n\nPDevice::PDevice(const PDevice& p) { CONSTRUCTOR2(p); }\nvoid PDevice::CONSTRUCTOR2(const PDevice& p) { e = p.e; }\n\nPDevice& PDevice::operator=(Device* p) { return OPERATOR_ASSIGN0(p); }\nPDevice& PDevice::OPERATOR_ASSIGN0(Device* p) { e = p; return *this; }\n\nPDevice& PDevice::operator=(const PDevice& p) { return OPERATOR_ASSIGN1(p); }\nPDevice& PDevice::OPERATOR_ASSIGN1(const PDevice& p) { e = p.e; return *this; }\n\nPDevice::~PDevice() { }\nvoid PDevice::DESTRUCTOR() { }\n\nAvsDeviceType PDevice::GetType() const { return e ? e->device_type : DEV_TYPE_NONE; }\nint PDevice::GetId() const { return e ? e->device_id : -1; }\nint PDevice::GetIndex() const { return e ? e->device_index : -1; }\nconst char* PDevice::GetName() const { return e ? e->GetName() : nullptr; }\n\nINeoEnv* __stdcall GetAvsEnv(IScriptEnvironment* env) { return static_cast<InternalEnvironment*>(env); }\n\nPNeoEnv::PNeoEnv(IScriptEnvironment* env) : p(static_cast<InternalEnvironment*>(env)) { }\nPNeoEnv::operator IScriptEnvironment2* () { return static_cast<InternalEnvironment*>(p); }\n\n/**********************************************************************/\n\nstatic const AVS_Linkage avs_linkage = {    // struct AVS_Linkage {\n\n  sizeof(AVS_Linkage),                      //   int Size;\n\n/***************************************************************************************************************/\n// struct VideoInfo\n  &VideoInfo::HasVideo,                     //   bool    (VideoInfo::*HasVideo)() const;\n  &VideoInfo::HasAudio,                     //   bool    (VideoInfo::*HasAudio)() const;\n  &VideoInfo::IsRGB,                        //   bool    (VideoInfo::*IsRGB)() const;\n  &VideoInfo::IsRGB24,                      //   bool    (VideoInfo::*IsRGB24)() const;\n  &VideoInfo::IsRGB32,                      //   bool    (VideoInfo::*IsRGB32)() const;\n  &VideoInfo::IsYUV,                        //   bool    (VideoInfo::*IsYUV)() const;\n  &VideoInfo::IsYUY2,                       //   bool    (VideoInfo::*IsYUY2)() const;\n  &VideoInfo::IsYV24,                       //   bool    (VideoInfo::*IsYV24)()  const;\n  &VideoInfo::IsYV16,                       //   bool    (VideoInfo::*IsYV16)()  const;\n  &VideoInfo::IsYV12,                       //   bool    (VideoInfo::*IsYV12)()  const;\n  &VideoInfo::IsYV411,                      //   bool    (VideoInfo::*IsYV411)() const;\n  &VideoInfo::IsY8,                         //   bool    (VideoInfo::*IsY8)()    const;\n  &VideoInfo::IsColorSpace,                 //   bool    (VideoInfo::*IsColorSpace)(int c_space) const;\n  &VideoInfo::Is,                           //   bool    (VideoInfo::*Is)(int property) const;\n  &VideoInfo::IsPlanar,                     //   bool    (VideoInfo::*IsPlanar)() const;\n  &VideoInfo::IsFieldBased,                 //   bool    (VideoInfo::*IsFieldBased)() const;\n  &VideoInfo::IsParityKnown,                //   bool    (VideoInfo::*IsParityKnown)() const;\n  &VideoInfo::IsBFF,                        //   bool    (VideoInfo::*IsBFF)() const;\n  &VideoInfo::IsTFF,                        //   bool    (VideoInfo::*IsTFF)() const;\n  &VideoInfo::IsVPlaneFirst,                //   bool    (VideoInfo::*IsVPlaneFirst)() const;\n  &VideoInfo::BytesFromPixels,              //   int     (VideoInfo::*BytesFromPixels)(int pixels) const;\n  &VideoInfo::RowSize,                      //   int     (VideoInfo::*RowSize)(int plane) const;\n  &VideoInfo::BMPSize,                      //   int     (VideoInfo::*BMPSize)() const;\n  &VideoInfo::AudioSamplesFromFrames,       //   int64_t (VideoInfo::*AudioSamplesFromFrames)(int frames) const;\n  &VideoInfo::FramesFromAudioSamples,       //   int     (VideoInfo::*FramesFromAudioSamples)(int64_t samples) const;\n  &VideoInfo::AudioSamplesFromBytes,        //   int64_t (VideoInfo::*AudioSamplesFromBytes)(int64_t bytes) const;\n  &VideoInfo::BytesFromAudioSamples,        //   int64_t (VideoInfo::*BytesFromAudioSamples)(int64_t samples) const;\n  &VideoInfo::AudioChannels,                //   int     (VideoInfo::*AudioChannels)() const;\n  &VideoInfo::SampleType,                   //   int     (VideoInfo::*SampleType)() const;\n  &VideoInfo::IsSampleType,                 //   bool    (VideoInfo::*IsSampleType)(int testtype) const;\n  &VideoInfo::SamplesPerSecond,             //   int     (VideoInfo::*SamplesPerSecond)() const;\n  &VideoInfo::BytesPerAudioSample,          //   int     (VideoInfo::*BytesPerAudioSample)() const;\n  &VideoInfo::SetFieldBased,                //   void    (VideoInfo::*SetFieldBased)(bool isfieldbased);\n  &VideoInfo::Set,                          //   void    (VideoInfo::*Set)(int property);\n  &VideoInfo::Clear,                        //   void    (VideoInfo::*Clear)(int property);\n  &VideoInfo::GetPlaneWidthSubsampling,     //   int     (VideoInfo::*GetPlaneWidthSubsampling)(int plane) const;\n  &VideoInfo::GetPlaneHeightSubsampling,    //   int     (VideoInfo::*GetPlaneHeightSubsampling)(int plane) const;\n  &VideoInfo::BitsPerPixel,                 //   int     (VideoInfo::*BitsPerPixel)() const;\n  &VideoInfo::BytesPerChannelSample,        //   int     (VideoInfo::*BytesPerChannelSample)() const;\n  &VideoInfo::SetFPS,                       //   void    (VideoInfo::*SetFPS)(unsigned numerator, unsigned denominator)\n  &VideoInfo::MulDivFPS,                    //   void    (VideoInfo::*MulDivFPS)(unsigned multiplier, unsigned divisor)\n  &VideoInfo::IsSameColorspace,             //   bool    (VideoInfo::*IsSameColorspace)(const VideoInfo& vi) const;\n// end struct VideoInfo\n/***************************************************************************************************************/\n// class VideoFrameBuffer\n  &VideoFrameBuffer::GetReadPtr,            //   const BYTE* (VideoFrameBuffer::*VFBGetReadPtr)() const;\n  &VideoFrameBuffer::GetWritePtr,           //   BYTE*       (VideoFrameBuffer::*VFBGetWritePtr)();\n  &VideoFrameBuffer::GetDataSize,           //   int         (VideoFrameBuffer::*GetDataSize)() const;\n  &VideoFrameBuffer::GetSequenceNumber,     //   int         (VideoFrameBuffer::*GetSequenceNumber)() const;\n  &VideoFrameBuffer::GetRefcount,           //   int         (VideoFrameBuffer::*GetRefcount)() const;\n// end class VideoFrameBuffer\n/***************************************************************************************************************/\n// class VideoFrame\n  &VideoFrame::GetPitch,                    //   int               (VideoFrame::*GetPitch)(int plane) const;\n  &VideoFrame::GetRowSize,                  //   int               (VideoFrame::*GetRowSize)(int plane) const;\n  &VideoFrame::GetHeight,                   //   int               (VideoFrame::*GetHeight)(int plane) const;\n  &VideoFrame::GetFrameBuffer,              //   VideoFrameBuffer* (VideoFrame::*GetFrameBuffer)() const;\n  &VideoFrame::GetOffset,                   //   int               (VideoFrame::*GetOffset)(int plane) const;\n  &VideoFrame::GetReadPtr,                  //   const BYTE*       (VideoFrame::*VFGetReadPtr)(int plane) const;\n  &VideoFrame::IsWritable,                  //   bool              (VideoFrame::*IsWritable)() const;\n  &VideoFrame::GetWritePtr,                 //   BYTE*             (VideoFrame::*VFGetWritePtr)(int plane) const;\n  &VideoFrame::DESTRUCTOR,                  //   void              (VideoFrame::*VideoFrame_DESTRUCTOR)();\n// end class VideoFrame\n/***************************************************************************************************************/\n// class IClip\n                                            //   /* nothing */\n// end class IClip\n/***************************************************************************************************************/\n// class PClip\n  &PClip::CONSTRUCTOR0,                     //   void (PClip::*PClip_CONSTRUCTOR0)();\n  &PClip::CONSTRUCTOR1,                     //   void (PClip::*PClip_CONSTRUCTOR1)(const PClip& x);\n  &PClip::CONSTRUCTOR2,                     //   void (PClip::*PClip_CONSTRUCTOR2)(IClip* x);\n  &PClip::OPERATOR_ASSIGN0,                 //   void (PClip::*PClip_OPERATOR_ASSIGN0)(IClip* x);\n  &PClip::OPERATOR_ASSIGN1,                 //   void (PClip::*PClip_OPERATOR_ASSIGN1)(const PClip& x);\n  &PClip::DESTRUCTOR,                       //   void (PClip::*PClip_DESTRUCTOR)();\n// end class PClip\n/***************************************************************************************************************/\n// class PVideoFrame\n  &PVideoFrame::CONSTRUCTOR0,               //   void (PVideoFrame::*PVideoFrame_CONSTRUCTOR0)();\n  &PVideoFrame::CONSTRUCTOR1,               //   void (PVideoFrame::*PVideoFrame_CONSTRUCTOR1)(const PVideoFrame& x);\n  &PVideoFrame::CONSTRUCTOR2,               //   void (PVideoFrame::*PVideoFrame_CONSTRUCTOR2)(VideoFrame* x);\n  &PVideoFrame::OPERATOR_ASSIGN0,           //   void (PVideoFrame::*PVideoFrame_OPERATOR_ASSIGN0(VideoFrame* x);\n  &PVideoFrame::OPERATOR_ASSIGN1,           //   void (PVideoFrame::*PVideoFrame_OPERATOR_ASSIGN1(const PVideoFrame& x);\n  &PVideoFrame::DESTRUCTOR,                 //   void (PVideoFrame::*PVideoFrame_DESTRUCTOR)();\n// end class PVideoFrame\n/***************************************************************************************************************/\n// class AVSValue\n  &AVSValue::CONSTRUCTOR0,                  //   void            (AVSValue::*AVSValue_CONSTRUCTOR0)();\n  &AVSValue::CONSTRUCTOR1,                  //   void            (AVSValue::*AVSValue_CONSTRUCTOR1)(IClip* c);\n  &AVSValue::CONSTRUCTOR2,                  //   void            (AVSValue::*AVSValue_CONSTRUCTOR2)(const PClip& c);\n  &AVSValue::CONSTRUCTOR3,                  //   void            (AVSValue::*AVSValue_CONSTRUCTOR3)(bool b);\n  &AVSValue::CONSTRUCTOR4,                  //   void            (AVSValue::*AVSValue_CONSTRUCTOR4)(int i);\n  &AVSValue::CONSTRUCTOR5,                  //   void            (AVSValue::*AVSValue_CONSTRUCTOR5)(float f);\n  &AVSValue::CONSTRUCTOR6,                  //   void            (AVSValue::*AVSValue_CONSTRUCTOR6)(double f);\n  &AVSValue::CONSTRUCTOR7,                  //   void            (AVSValue::*AVSValue_CONSTRUCTOR7)(const char* s);\n  &AVSValue::CONSTRUCTOR8,                  //   void            (AVSValue::*AVSValue_CONSTRUCTOR8)(const AVSValue* a, int\n  &AVSValue::CONSTRUCTOR9,                  //   void            (AVSValue::*AVSValue_CONSTRUCTOR9)(const AVSValue& v);\n  &AVSValue::DESTRUCTOR,                    //   void            (AVSValue::*AVSValue_DESTRUCTOR)();\n  &AVSValue::OPERATOR_ASSIGN,               //   AVSValue&       (AVSValue::*AVSValue_OPERATOR_ASSIGN)(const AVSValue& v);\n  &AVSValue::OPERATOR_INDEX,                //   const AVSValue& (AVSValue::*AVSValue_OPERATOR_INDEX)(int index) const;\n  &AVSValue::Defined,                       //   bool            (AVSValue::*Defined)() const;\n  &AVSValue::IsClip,                        //   bool            (AVSValue::*IsClip)() const;\n  &AVSValue::IsBool,                        //   bool            (AVSValue::*IsBool)() const;\n  &AVSValue::IsInt,                         //   bool            (AVSValue::*IsInt)() const;\n  &AVSValue::IsFloat,                       //   bool            (AVSValue::*IsFloat)() const;\n  &AVSValue::IsString,                      //   bool            (AVSValue::*IsString)() const;\n  &AVSValue::IsArray,                       //   bool            (AVSValue::*IsArray)() const;\n  &AVSValue::AsClip,                        //   PClip           (AVSValue::*AsClip)() const;\n  &AVSValue::AsBool1,                       //   bool            (AVSValue::*AsBool1)() const;\n  &AVSValue::AsInt1,                        //   int             (AVSValue::*AsInt1)() const;\n  &AVSValue::AsString1,                     //   const char*     (AVSValue::*AsString1)() const;\n  &AVSValue::AsFloat1,                      //   double          (AVSValue::*AsFloat1)() const; // AsDouble1\n  &AVSValue::AsBool2,                       //   bool            (AVSValue::*AsBool2)(bool def) const;\n  &AVSValue::AsInt2,                        //   int             (AVSValue::*AsInt2)(int def) const;\n  &AVSValue::AsDblDef,                      //   double          (AVSValue::*AsDblDef)(double def) const; // AsDouble2\n  &AVSValue::AsFloat2,                      //   double          (AVSValue::*AsFloat2)(float def) const;\n  &AVSValue::AsString2,                     //   const char*     (AVSValue::*AsString2)(const char* def) const;\n  &AVSValue::ArraySize,                     //   int             (AVSValue::*ArraySize)() const;\n  &AVSValue::IsLongStrict,                  //   bool            (AVSValue::*IsLongStrict)() const; // v11\n  &AVSValue::IsFloatfStrict,                //   bool            (AVSValue::*IsFloatfStrict() const; // v11\n  &AVSValue::AsLong1,                       //   int64_t         (AVSValue::*AsLong1)() const; // v11\n  &AVSValue::AsLong2,                       //   int64_t         (AVSValue::*AsLong2)(int64_t def) const; // v11\n  &AVSValue::CONSTRUCTOR12,                 //   void            (AVSValue::*AVSValue_CONSTRUCTOR12)(int64_ l); // v11\n  // end class AVSValue\n/**********************************************************************/\n  // a single { nullptr } initializes the whole placeholder array\n  { nullptr },                              // void    (VideoInfo::* reserved[27])(); // reserved for AVS classic\n/**********************************************************************/\n  // AviSynth+ additions\n  &VideoInfo::NumComponents,                //   int     (VideoInfo::*NumChannels)() const;\n  &VideoInfo::ComponentSize,                //   int     (VideoInfo::*ComponentSize)() const;\n  &VideoInfo::BitsPerComponent,             //   int     (VideoInfo::*BitsPerComponent)() const;\n  &VideoInfo::Is444,                        //   bool    (VideoInfo::*Is444)()  const;\n  &VideoInfo::Is422,                        //   bool    (VideoInfo::*Is422)()  const;\n  &VideoInfo::Is420,                        //   bool    (VideoInfo::*Is420)()  const;\n  &VideoInfo::IsY,                          //   bool    (VideoInfo::*IsY)()    const;\n  &VideoInfo::IsRGB48,                      //   bool    (VideoInfo::*IsRGB48)()  const;\n  &VideoInfo::IsRGB64,                      //   bool    (VideoInfo::*IsRGB64)()  const;\n  &VideoInfo::IsYUVA,                       //   bool    (VideoInfo::*IsYUVA)()  const;\n  &VideoInfo::IsPlanarRGB,                  //   bool    (VideoInfo::*IsPlanarRGB)()  const;\n  &VideoInfo::IsPlanarRGBA,                 //   bool    (VideoInfo::*IsPlanarRGBA)()  const;\n/**********************************************************************/\n  // Frame properties\n  &VideoFrame::getProperties, // AVSMap& (VideoFrame::* getProperties)();\n  &VideoFrame::getConstProperties, // const AVSMap& (VideoFrame::* getConstProperties)();\n  &VideoFrame::setProperties, // void (VideoFrame::* setProperties)(const AVSMap& properties);\n\n  // PFunction (Neo)\n  &AVSValue::CONSTRUCTOR11,\n  &AVSValue::IsFunction,\n  &PFunction::CONSTRUCTOR0,\n  &PFunction::CONSTRUCTOR1,\n  &PFunction::CONSTRUCTOR2,\n  &PFunction::OPERATOR_ASSIGN0,\n  &PFunction::OPERATOR_ASSIGN1,\n  &PFunction::DESTRUCTOR,\n  // end PFunction\n\n  // VideoFrame extras (Neo)\n  &VideoFrame::CheckMemory,\n  &VideoFrame::GetDevice,\n\n  // class PDevice (Neo)\n  &PDevice::CONSTRUCTOR0,\n  &PDevice::CONSTRUCTOR1,\n  &PDevice::CONSTRUCTOR2,\n  &PDevice::OPERATOR_ASSIGN0,\n  &PDevice::OPERATOR_ASSIGN1,\n  &PDevice::DESTRUCTOR,\n  &PDevice::GetType,\n  &PDevice::GetId,\n  &PDevice::GetIndex,\n  &PDevice::GetName,\n  // end class PDevice\n\n  // V9\n  &VideoFrame::IsPropertyWritable,\n\n  // V10\n  &VideoFrame::GetPixelType,                //   int          (VideoFrame::*VideoFrame_GetPixelType)() const;\n  &VideoFrame::AmendPixelType,              //   void         (VideoFrame::*VideoFrame_AmendPixelType)();\n  &VideoFrameBuffer::DESTRUCTOR,            //   void         (VideoFrameBuffer::*VideoFrameBuffer_DESTRUCTOR)();\n  &AVSValue::GetType,                       //   AvsValueType (AVSValue::*AVSValue_GetType)() const;\n\n  // V10.1\n  &VideoInfo::IsChannelMaskKnown,           //   bool    (VideoInfo::*IsChannelMaskKnown)()  const;\n  &VideoInfo::SetChannelMask,               //   void    (VideoInfo::*SetChannelMask)();\n  &VideoInfo::GetChannelMask,               //   int     (VideoInfo::*GetChannelMask)()  const;\n\n  // a single { nullptr } initializes the whole placeholder array\n  { nullptr },                              // void          (VideoInfo::* reserved2[64 - 31])(); // Reserve pointer space for Avisynth+\n\n/**********************************************************************/\n  // AviSynth Neo additions\n  &GetAvsEnv\n  // Most Neo linkage entries are moved to standard avs+ place.\n  // frame property logic has been replaced entirely\n\n// this part should be identical with struct AVS_Linkage in avisynth.h\n\n/**********************************************************************/\n};                                          // }\n\nextern __declspec(dllexport) const AVS_Linkage* const AVS_linkage = &avs_linkage;\n\n\n/**********************************************************************/\n// in UserPlugin.cpp\n#if 0\n\n#include \"avisynth.h\"\n\n/* New 2.6 requirment!!! */\n// Declare and initialise server pointers static storage.\nconst AVS_Linkage *AVS_linkage = 0;\n\n/* New 2.6 requirment!!! */\n// DLL entry point called from LoadPlugin() to setup a user plugin.\nextern \"C\" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors) {\n\n  /* New 2.6 requirment!!! */\n  // Save the server pointers.\n  AVS_linkage = vectors;\n\n  // Add the name of our function\n  env->AddFunction(\"Plugin\", \"c\", Create_Plugin, 0);\n\n  // Return plugin text identifier.\n  return \"Plugin\";\n}\n\n#endif\n/**********************************************************************/\n\n"
  },
  {
    "path": "avs_core/core/internal.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#ifndef __Internal_H__\n#define __Internal_H__\n\n#include <avs/config.h>\n#include <avs/minmax.h>\n#include <stdint.h>\n#include <string.h>\n#include \"version.h\"\n#include <memory>\n#include <string>\n#ifdef AVS_POSIX\n#include <limits.h>\n#endif\n#include \"InternalEnvironment.h\"\n\n#ifdef INTEL_INTRINSICS\n\n// Intrinsics base header + really required extension headers\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n\n#endif\n\n#if AVS_DEVNEXT_REV > 0\n#define AVS_DEVELOPMENT_BUILD \"\\nNext Version Development Build: \" AVS_PPSTR(AVS_DEV_REVDATE)\n#define AVS_DEVELOPMENT_BUILD_GIT \"\\nGit: \" AVS_PPSTR(AVS_DEV_GITHASH)\n#else\n#define AVS_DEVELOPMENT_BUILD\n#define AVS_DEVELOPMENT_BUILD_GIT\n#endif\n\n// !! precision problems 2.60f < 2.60. Extra care for scripts where the version checking occurs like \"IsAvs26 = VersionNumber()>=2.60\"\n#define AVS_VERSION 3.75  // Note: Used by VersionNumber() script function\n#define AVS_COPYRIGHT \"\\n\\xA9 2000-2015 Ben Rudiak-Gould, et al.\\nhttp://avisynth.nl\\n\\xA9 2013-2026 AviSynth+ Project\"\n#define AVS_COPYRIGHT_UTF8 u8\"\\n\\u00A9 2000-2015 Ben Rudiak-Gould, et al.\\nhttp://avisynth.nl\\n\\u00A9 2013-2026 AviSynth+ Project\"\n#define BUILTIN_FUNC_PREFIX \"AviSynth\"\n\nenum MANAGE_CACHE_KEYS\n{\n  MC_RegisterCache     = (int)0xFFFF0004,\n  MC_UnRegisterCache   = (int)0xFFFF0006,\n  MC_NodCache          = (int)0xFFFF0007,\n  MC_NodAndExpandCache = (int)0xFFFF0008,\n  MC_RegisterMTGuard,\n  MC_UnRegisterMTGuard,\n\n\tMC_RegisterGraphNode = (int)0xFFFF0100,\n\tMC_UnRegisterGraphNode,\n\n  MC_QueryAvs25        = (int)0xFFFF0200,\n  MC_QueryAvsPreV11C   = (int)0xFFFF0201,\n};\n\n#include <avisynth.h>\n#include <string>\n#include \"function.h\"\n\n\nconst char *GetPixelTypeName(const int pixel_type); // in script.c\nint GetPixelTypeFromName(const char *pixeltypename); // in script.c\nconst char* GetAVSTypeName(AVSValue value); // in script.c\nint GetDeviceTypes(const PClip& child); // in DeviceManager.cpp\nsize_t GetFrameHead(const PVideoFrame& vf); // in DeviceManager.cpp\nsize_t GetFrameTail(const PVideoFrame& vf); // in DeviceManager.cpp\n\nPClip Create_MessageClip(const char* message, int width, int height,\n  int pixel_type, bool shrink, int textcolor, int halocolor, int bgcolor,\n  int fps_numerator, int fps_denominator, int num_frames,\n  bool utf8,\n  IScriptEnvironment* env);\n\n\n/* Used to clip/clamp a byte to the 0-255 range.\n   Uses a look-up table internally for performance.\n*/\nclass _PixelClip {\n  enum { buffer=320 };\n  BYTE lut[256+buffer*2];\npublic:\n  _PixelClip() {\n    memset(lut, 0, buffer);\n    for (int i=0; i<256; ++i) lut[i+buffer] = (BYTE)i;\n    memset(lut+buffer+256, 255, buffer);\n  }\n  BYTE operator()(int i) const { return lut[i+buffer]; }\n};\n\nextern const _PixelClip PixelClip;\n\n\ntemplate<class ListNode>\nstatic __inline void Relink(ListNode* newprev, ListNode* me, ListNode* newnext) {\n  if (me == newprev || me == newnext) return;\n  me->next->prev = me->prev;\n  me->prev->next = me->next;\n  me->prev = newprev;\n  me->next = newnext;\n  me->prev->next = me->next->prev = me;\n}\n\nclass CWDChanger\n/**\n  * Class to change the current working directory\n **/\n{\npublic:\n  CWDChanger(const char* new_cwd);\n  CWDChanger(const wchar_t* new_cwd);\n  ~CWDChanger(void);\n\n#ifdef AVS_WINDOWS\n  static std::wstring GetCurrentWorkingDirectory();\n#else\n  static std::string GetCurrentWorkingDirectory();\n#endif\n\nprivate:\n  void Init(const wchar_t* new_cwd);\n#ifdef AVS_WINDOWS\n  std::unique_ptr<wchar_t[]> old_working_directory;\n#else\n  char old_working_directory[PATH_MAX];\n#endif\n  bool restore;\n};\n\nclass DllDirChanger\n{\npublic:\n  DllDirChanger(const char* new_cwd);\n  ~DllDirChanger(void);\n\nprivate:\n  std::unique_ptr<char[]> old_directory;\n  bool restore;\n};\n\nclass NonCachedGenericVideoFilter : public GenericVideoFilter\n/**\n  * Class to select a range of frames from a longer clip\n **/\n{\npublic:\n  NonCachedGenericVideoFilter(PClip _child);\n  int __stdcall SetCacheHints(int cachehints, int frame_range);\n};\n\n\n\n/*** Inline helper methods ***/\n\n// 8 bit uv to float\n// 16-128-240 -> -112-0-112 -> 1..255: +/-127 -> +/-0.5\n[[maybe_unused]] static AVS_FORCEINLINE float uv8tof(int color) {\n  return (color - 128) / 255.f; // consistent with convert_uintN_to_float_c\n}\n\n// 8 bit fullscale to float\n[[maybe_unused]] static AVS_FORCEINLINE float c8tof(int color) {\n  return color / 255.0f;\n}\n\n[[maybe_unused]] static AVS_FORCEINLINE uint8_t Scaled15bitPixelClip(int i) {\n  return (uint8_t)clamp((i + 16384) >> 15, 0, 255);\n}\n\n[[maybe_unused]] static AVS_FORCEINLINE uint8_t ScaledPixelClip(int i) {\n  // return PixelClip((i+32768) >> 16);\n  // PF: clamp is faster than lut\n  return (uint8_t)clamp((i + 32768) >> 16, 0, 255);\n}\n\n[[maybe_unused]] static AVS_FORCEINLINE uint16_t ScaledPixelClip(int64_t i) {\n    return (uint16_t)clamp((i + 32768) >> 16, (int64_t)0, (int64_t)65535);\n}\n\n[[maybe_unused]] static AVS_FORCEINLINE uint16_t ScaledPixelClipEx(int64_t i, int max_value) {\n  return (uint16_t)clamp((int)((i + 32768) >> 16), 0, max_value);\n}\n\n[[maybe_unused]] static AVS_FORCEINLINE bool IsClose(int a, int b, unsigned threshold)\n  { return (unsigned(a-b+threshold) <= threshold*2); }\n\n[[maybe_unused]] static AVS_FORCEINLINE bool IsCloseFloat(float a, float b, float threshold)\n{ return (a-b+threshold <= threshold*2); }\n\n#ifdef INTEL_INTRINSICS\n// useful SIMD helpers\n\n// sse2 replacement of _mm_mullo_epi32 in SSE4.1\n// use it after speed test, may have too much overhead and C is faster\n[[maybe_unused]] static AVS_FORCEINLINE __m128i _MM_MULLO_EPI32(const __m128i &a, const __m128i &b)\n{\n  // for SSE 4.1: return _mm_mullo_epi32(a, b);\n  __m128i tmp1 = _mm_mul_epu32(a,b); // mul 2,0\n  __m128i tmp2 = _mm_mul_epu32( _mm_srli_si128(a,4), _mm_srli_si128(b,4)); // mul 3,1\n  // shuffle results to [63..0] and pack. a2->a1, a0->a0\n  return _mm_unpacklo_epi32(_mm_shuffle_epi32(tmp1, _MM_SHUFFLE (0,0,2,0)), _mm_shuffle_epi32(tmp2, _MM_SHUFFLE (0,0,2,0)));\n}\n\n// fake _mm_packus_epi32 (orig is SSE4.1 only)\n[[maybe_unused]] static AVS_FORCEINLINE __m128i _MM_PACKUS_EPI32( __m128i a, __m128i b )\n{\n  const __m128i val_32 = _mm_set1_epi32(0x8000);\n  const __m128i val_16 = _mm_set1_epi16((short)0x8000);\n\n  a = _mm_sub_epi32(a, val_32);\n  b = _mm_sub_epi32(b, val_32);\n  a = _mm_packs_epi32(a, b);\n  a = _mm_add_epi16(a, val_16);\n  return a;\n}\n\n// fake _mm_packus_epi32 (orig is SSE4.1 only)\n// only for packing 00000000..0000FFFF range integers, does not clamp properly above that, e.g. 00010001\n[[maybe_unused]] static AVS_FORCEINLINE __m128i _MM_PACKUS_EPI32_SRC_TRUEWORD(__m128i a, __m128i b)\n{\n  a = _mm_slli_epi32 (a, 16);\n  a = _mm_srai_epi32 (a, 16);\n  b = _mm_slli_epi32 (b, 16);\n  b = _mm_srai_epi32 (b, 16);\n  a = _mm_packs_epi32 (a, b);\n  return a;\n}\n\n[[maybe_unused]] static AVS_FORCEINLINE __m128i _MM_CMPLE_EPU16(__m128i x, __m128i y)\n{\n  // Returns 0xFFFF where x <= y:\n  return _mm_cmpeq_epi16(_mm_subs_epu16(x, y), _mm_setzero_si128());\n}\n\n[[maybe_unused]] static AVS_FORCEINLINE __m128i _MM_BLENDV_SI128(__m128i x, __m128i y, __m128i mask)\n{\n  // Replace bit in x with bit in y when matching bit in mask is set:\n  return _mm_or_si128(_mm_andnot_si128(mask, x), _mm_and_si128(mask, y));\n}\n\n// SSE4.1 simulation for SSE2, same as above, intrisic name is _mm_blendv_epi8\n[[maybe_unused]] static AVS_FORCEINLINE __m128i _MM_BLENDV_EPI8(__m128i const& a, __m128i const& b, __m128i const& selector) {\n  return _mm_or_si128(_mm_andnot_si128(selector, a), _mm_and_si128(selector, b));\n}\n\n// sse2 simulation of SSE4's _mm_min_epu16\n[[maybe_unused]] static AVS_FORCEINLINE __m128i _MM_MIN_EPU16(__m128i x, __m128i y)\n{\n  // Returns x where x <= y, else y:\n  return _MM_BLENDV_SI128(y, x, _MM_CMPLE_EPU16(x, y));\n}\n\n// sse2 simulation of SSE4's _mm_max_epu16\n[[maybe_unused]] static AVS_FORCEINLINE __m128i _MM_MAX_EPU16(__m128i x, __m128i y)\n{\n  // Returns x where x >= y, else y:\n  return _MM_BLENDV_SI128(x, y, _MM_CMPLE_EPU16(x, y));\n}\n#endif\n\n#ifndef MAKEFOURCC\n#define MAKEFOURCC(ch0, ch1, ch2, ch3)                              \\\n                ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) |   \\\n                ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 ))\n#endif\n\nclass GlobalVarFrame\n{\n   InternalEnvironment* env;\npublic:\n   GlobalVarFrame(InternalEnvironment* env) : env(env) {\n      env->PushContextGlobal();\n   }\n   ~GlobalVarFrame() {\n      env->PopContextGlobal();\n   }\n};\n\n#endif  // __Internal_H__\n"
  },
  {
    "path": "avs_core/core/main.cpp",
    "content": "// Avisynth v2.5.  Copyright 2007 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include <avisynth.h>\n#include \"internal.h\"\n\n// master ifdef\n#ifdef AVS_WINDOWS // inspect for Linux; COM/VfW stuff not needed?\n\n#ifdef AVS_WINDOWS\n    #include <avs/win.h>\n    #include <initguid.h>\n    #include <vfw.h>\n#else\n    #include <avs/posix.h>\n#endif\n\n#include <avs/minmax.h>\n#include \"bitblt.h\"\n#include \"exception.h\"\n#include <cstdio>\n#include <new>\n#include \"AviHelper.h\"\n#include \"audio.h\"\n\n#include <float.h>\n\n#ifdef MSVC\nconstexpr uint32_t FP_STATE = 0x9001f;\n#ifdef _M_X64\nconstexpr uint32_t FP_MASK = 0xffffffff & !(_MCW_PC | _MCW_IC);\n// x64 ignores _MCW_PC and _MCW_IC, Debug CRT library actually asserts when these are passed.\n// https ://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/control87-controlfp-control87-2?redirectedfrom=MSDN&view=msvc-170\n#else\nconstexpr uint32_t FP_MASK = 0xffffffff;\n#endif\n#endif\n\n#ifndef _DEBUG\n// Release mode logging\n// #define OPT_RELS_LOGGING\n# ifdef OPT_RELS_LOGGING\n\n#undef _RPT0\n#undef _RPT1\n#undef _RPT2\n#undef _RPT3\n#undef _RPT4\n#  ifdef _RPT5\n#undef _RPT5\n#  endif\n\n#define _RPT0(rptno, msg)                     ReportMe(msg)\n#define _RPT1(rptno, msg, a1)                 ReportMe(msg, a1)\n#define _RPT2(rptno, msg, a1, a2)             ReportMe(msg, a1, a2)\n#define _RPT3(rptno, msg, a1, a2, a3)         ReportMe(msg, a1, a2, a3)\n#define _RPT4(rptno, msg, a1, a2, a3, a4)     ReportMe(msg, a1, a2, a3, a4)\n#define _RPT5(rptno, msg, a1, a2, a3, a4, a5) ReportMe(msg, a1, a2, a3, a4, a5)\n\nvoid ReportMe(const char * msg, ...) {\n  static char buf[256] = \"\";\n  va_list args;\n  int l = strlen(buf);\n\n  va_start(args, msg);\n  l = _vsnprintf(buf+l, sizeof(buf)-1-l, msg, args);\n  buf[sizeof(buf)-1] = 0;\n  va_end(args);\n\n  if (l == -1 || strchr(buf, '\\n')) {\n    OutputDebugString(buf);\n    buf[0] = 0;\n  }\n}\n\n# else\n#  ifndef _RPT5\n#define _RPT5(rptno, msg, a1, a2, a3, a4, a5)\n#  endif\n# endif\n#else\n# ifndef _RPT5\n#  ifdef _RPT_BASE\n#define _RPT5(rptno, msg, a1, a2, a3, a4, a5) \\\n  _RPT_BASE((rptno, NULL, 0, NULL, msg, a1, a2, a3, a4, a5))\n#  else\n#   ifdef _CrtDbgBreak\n#define _RPT5(rptno, msg, a1, a2, a3, a4, a5) \\\n  do { if ((1 == _CrtDbgReport(rptno, NULL, 0, NULL, msg, a1, a2, a3, a4, a5))) \\\n  _CrtDbgBreak(); } while (0)\n#   else\n#define _RPT5(rptno, msg, a1, a2, a3, a4, a5)\n#   endif\n#  endif\n# endif\n#endif\n\nstatic long gRefCnt=0;\n\n#ifdef XP_TLS\nDWORD dwTlsIndex = 0;\n#endif\n\nextern \"C\" const GUID CLSID_CAVIFileSynth   // {E6D6B700-124D-11D4-86F3-DB80AFD98778}\n= {0xe6d6b700, 0x124d, 0x11d4, {0x86, 0xf3, 0xdb, 0x80, 0xaf, 0xd9, 0x87, 0x78}};\n\nextern \"C\" const GUID IID_IAvisynthClipInfo   // {E6D6B708-124D-11D4-86F3-DB80AFD98778}\n= {0xe6d6b708, 0x124d, 0x11d4, {0x86, 0xf3, 0xdb, 0x80, 0xaf, 0xd9, 0x87, 0x78}};\n\n\nstruct IAvisynthClipInfo : IUnknown {\n  virtual int __stdcall GetError(const char** ppszMessage) = 0;\n  virtual bool __stdcall GetParity(int n) = 0;\n  virtual bool __stdcall IsFieldBased() = 0;\n};\n\n// Silence warning for STDMETHODIMP: \n// \"exception specification of overriding function is more lax than base version [-Wmicrosoft-exception-spec]\"\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wmicrosoft-exception-spec\"\n#elif defined(__GNUC__)\n//#pragma GCC diagnostic push\n// gcc has no problem\n// #pragma GCC diagnostic ignored \"-Wnoexcept\"\n#endif\n\n// final is used to silence warning:\n// delete called on non-final 'CAVIFileSynth' that has virtual functions but non-virtual destructor [-Wdelete-non-abstract-non-virtual-dtor]\nclass CAVIFileSynth final: public IAVIFile, public IPersistFile, public IClassFactory, public IAvisynthClipInfo {\n  friend class CAVIStreamSynth;\nprivate:\n  long m_refs;\n\n  char* szScriptName;\n  char* szScriptNameUTF8;\n  IScriptEnvironment2* env;\n  PClip filter_graph; // actual result of script evaluation\n  const VideoInfo* vi;\n  const char* error_msg;\n\n  CRITICAL_SECTION cs_filter_graph;\n\n  bool VDubPlanarHack;\n  bool AVIPadScanlines;\n  bool Enable_V210;\n  bool Enable_b64a;\n  bool Enable_Y3_10_10;\n  bool Enable_Y3_10_16;\n  bool Enable_PlanarToPackedRGB;\n\n\n  int ImageSize(const VideoInfo *vi);\n\n  bool DelayInit();\n  bool DelayInit2();\n\n  void MakeErrorStream(const char* msg);\n\n  void Lock();\n  void Unlock();\n\npublic:\n\n  CAVIFileSynth(const CLSID& rclsid);\n  ~CAVIFileSynth();\n\n  static HRESULT Create(const CLSID& rclsid, const IID& riid, void **ppv);\n\n  //////////// IUnknown\n\n  // 2023: Lots of clang-cl LLVM warning:\n  // \"exception specification of overriding function is more lax than base version[-Wmicrosoft-exception-spec]\"\n  // it's because STDMETHOD and STDMETHODIMP is differing by COM_DECLSPEC_NOTHROW that is __declspec(nothrow).\n  // All we can do is to disable warnings. This is by MS design.\n  STDMETHODIMP QueryInterface(const IID& iid, void** ppv);\n  STDMETHODIMP_(ULONG) AddRef();\n  STDMETHODIMP_(ULONG) Release();\n\n  //////////// IClassFactory\n\n  STDMETHODIMP CreateInstance (LPUNKNOWN pUnkOuter, REFIID riid,  void * * ppvObj) ;\n  STDMETHODIMP LockServer (BOOL fLock) ;\n\n  //////////// IPersistFile\n\n  STDMETHODIMP GetClassID(LPCLSID lpClassID);  // IPersist\n\n  STDMETHODIMP IsDirty();\n  STDMETHODIMP Load(LPCOLESTR lpszFileName, DWORD grfMode);\n  STDMETHODIMP Save(LPCOLESTR lpszFileName, BOOL fRemember);\n  STDMETHODIMP SaveCompleted(LPCOLESTR lpszFileName);\n  STDMETHODIMP GetCurFile(LPOLESTR *lplpszFileName);\n\n  //////////// IAVIFile\n\n  STDMETHODIMP CreateStream(PAVISTREAM *ppStream, AVISTREAMINFOW *psi);       // 5\n  STDMETHODIMP EndRecord();                                                   // 8\n  STDMETHODIMP GetStream(PAVISTREAM *ppStream, DWORD fccType, LONG lParam);   // 4\n  STDMETHODIMP Info(AVIFILEINFOW *psi, LONG lSize);                           // 3\n\n  STDMETHODIMP Open(LPCSTR szFile, UINT mode, LPCOLESTR lpszFileName);        // ???\n  STDMETHODIMP Save(LPCSTR szFile, AVICOMPRESSOPTIONS FAR *lpOptions,         // ???\n    AVISAVECALLBACK lpfnCallback);\n\n  STDMETHODIMP ReadData(DWORD fcc, LPVOID lp, LONG *lpcb);                    // 7\n  STDMETHODIMP WriteData(DWORD fcc, LPVOID lpBuffer, LONG cbBuffer);          // 6\n  STDMETHODIMP DeleteStream(DWORD fccType, LONG lParam);                      // 9\n\n                                                                              //////////// IAvisynthClipInfo\n\n  int __stdcall GetError(const char** ppszMessage);\n  bool __stdcall GetParity(int n);\n  bool __stdcall IsFieldBased();\n};\n\n///////////////////////////////////\n\nclass CAVIStreamSynth;\n\n// final is used to silence warning:\n// warning : delete called on non-final 'CAVIStreamSynth' that has virtual functions but non-virtual destructor\nclass CAVIStreamSynth final: public IAVIStream, public IAVIStreaming {\npublic:\n\n  //////////// IUnknown\n\n  STDMETHODIMP QueryInterface(const IID& iid, void **ppv);\n  STDMETHODIMP_(ULONG) AddRef();\n  STDMETHODIMP_(ULONG) Release();\n\n  CAVIStreamSynth(CAVIFileSynth *parentPtr, bool isAudio);\n  ~CAVIStreamSynth();\n\n  //////////// IAVIStream\n\n  STDMETHODIMP Create(LPARAM lParam1, LPARAM lParam2);\n  STDMETHODIMP Delete(LONG lStart, LONG lSamples);\n  STDMETHODIMP_(LONG) Info(AVISTREAMINFOW *psi, LONG lSize);\n  STDMETHODIMP_(LONG) FindSample(LONG lPos, LONG lFlags);\n  STDMETHODIMP Read(LONG lStart, LONG lSamples, LPVOID lpBuffer, LONG cbBuffer, LONG *plBytes, LONG *plSamples);\n  STDMETHODIMP ReadData(DWORD fcc, LPVOID lp, LONG *lpcb);\n  STDMETHODIMP ReadFormat(LONG lPos, LPVOID lpFormat, LONG *lpcbFormat);\n  STDMETHODIMP SetFormat(LONG lPos, LPVOID lpFormat, LONG cbFormat);\n  STDMETHODIMP Write(LONG lStart, LONG lSamples, LPVOID lpBuffer,\n    LONG cbBuffer, DWORD dwFlags, LONG FAR *plSampWritten,\n    LONG FAR *plBytesWritten);\n  STDMETHODIMP WriteData(DWORD fcc, LPVOID lpBuffer, LONG cbBuffer);\n  STDMETHODIMP SetInfo(AVISTREAMINFOW *psi, LONG lSize);\n\n  //////////// IAVIStreaming\n\n  STDMETHODIMP Begin(LONG lStart, LONG lEnd, LONG lRate);\n  STDMETHODIMP End();\n\nprivate:\n  long m_refs;\n\n  CAVIFileSynth *parent;\n  BOOL fAudio;\n\n  const char *sName;\n\n  //////////// internal\n\n  void ReadFrame(void* lpBuffer, int n);\n\n  HRESULT Read2(LONG lStart, LONG lSamples, LPVOID lpBuffer, LONG cbBuffer, LONG *plBytes, LONG *plSamples);\n};\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#elif defined(__GNUC__)\n//#pragma GCC diagnostic pop\n#endif\n\n#ifndef AVS_STATIC_LIB\nBOOL APIENTRY DllMain(HANDLE hModule, ULONG ulReason, LPVOID lpReserved) {\n\n  _RPT4(0,\"DllMain: hModule=0x%08x, ulReason=%x, lpReserved=0x%08x, gRefCnt = %ld\\n\",\n    hModule, ulReason, lpReserved, gRefCnt);\n\n#ifdef XP_TLS\n  if (ulReason == DLL_PROCESS_ATTACH) {\n    if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)\n      throw(\"Avisynth DLL load: TlsAlloc failed\");\n    _RPT1(0, \"DllMain: TlsAlloc: dwTlsIndex=0x%x\\n\", dwTlsIndex);\n  }\n  else if (ulReason == DLL_PROCESS_DETACH) {\n    _RPT1(0, \"DllMain: TlsFree: dwTlsIndex=0x%x\\n\", dwTlsIndex);\n    TlsFree(dwTlsIndex);\n    dwTlsIndex = 0;\n  }\n#endif\n\n  return TRUE;\n}\n\nSTDAPI DllGetClassObject(IN REFCLSID rclsid, IN REFIID riid, OUT LPVOID FAR* ppv){\n\n  if (rclsid != CLSID_CAVIFileSynth) {\n    _RPT0(0,\"DllGetClassObject() CLASS_E_CLASSNOTAVAILABLE\\n\");\n    return CLASS_E_CLASSNOTAVAILABLE;\n  }\n  _RPT0(0,\"DllGetClassObject() CLSID: CAVIFileSynth\\n\");\n\n  HRESULT hresult = CAVIFileSynth::Create(rclsid, riid, ppv);\n\n  _RPT2(0,\"DllGetClassObject() result=0x%X, object=%p\\n\", hresult, *ppv);\n\n  return hresult;\n}\n\nSTDAPI DllCanUnloadNow() {\n  _RPT1(0,\"DllCanUnloadNow(): gRefCnt = %ld\\n\", gRefCnt);\n\n  return gRefCnt ? S_FALSE : S_OK;\n}\n#endif\n\n///////////////////////////////////////////////////////////////////////////\n//\n//\tCAVIFileSynth\n//\n///////////////////////////////////////////////////////////////////////////\n//////////// IClassFactory\n\nSTDMETHODIMP CAVIFileSynth::CreateInstance (LPUNKNOWN pUnkOuter, REFIID riid,  void * * ppvObj) {\n\n  if (pUnkOuter) {\n    _RPT1(0,\"%p->CAVIFileSynth::CreateInstance() CLASS_E_NOAGGREGATION\\n\", this);\n    return CLASS_E_NOAGGREGATION;\n  }\n  _RPT1(0,\"%p->CAVIFileSynth::CreateInstance()\\n\", this);\n\n  HRESULT hresult = Create(CLSID_CAVIFileSynth, riid, ppvObj);\n\n  _RPT3(0,\"%p->CAVIFileSynth::CreateInstance() result=0x%X, object=%p\\n\", this, hresult, *ppvObj);\n\n  return hresult;\n}\n\nSTDMETHODIMP CAVIFileSynth::LockServer (BOOL fLock) {\n  _RPT2(0,\"%p->CAVIFileSynth::LockServer(%u)\\n\", this, fLock);\n  return S_OK;\n}\n\n///////////////////////////////////////////////////\n//////////// IPersistFile\n\nSTDMETHODIMP CAVIFileSynth::GetClassID(LPCLSID lpClassID) {  // IPersist\n  _RPT1(0,\"%p->CAVIFileSynth::GetClassID()\\n\", this);\n\n  if (!lpClassID) return E_POINTER;\n\n  *lpClassID = CLSID_CAVIFileSynth;\n\n  return S_OK;\n}\n\nSTDMETHODIMP CAVIFileSynth::IsDirty() {\n  _RPT1(0,\"%p->CAVIFileSynth::IsDirty()\\n\", this);\n  return S_FALSE;\n}\n\nSTDMETHODIMP CAVIFileSynth::Load(LPCOLESTR lpszFileName, DWORD grfMode) {\n  char filename[MAX_PATH];\n\n  WideCharToMultiByte(AreFileApisANSI() ? CP_ACP : CP_OEMCP, 0, lpszFileName, -1, filename, sizeof filename, NULL, NULL);\n\n  _RPT3(0,\"%p->CAVIFileSynth::Load(\\\"%s\\\", 0x%X)\\n\", this, filename, grfMode);\n\n  return Open(filename, grfMode, lpszFileName);\n}\n\nSTDMETHODIMP CAVIFileSynth::Save(LPCOLESTR lpszFileName, BOOL fRemember) {\n  _RPT1(0,\"%p->CAVIFileSynth::Save()\\n\", this);\n  return E_FAIL;\n}\n\nSTDMETHODIMP CAVIFileSynth::SaveCompleted(LPCOLESTR lpszFileName) {\n  _RPT1(0,\"%p->CAVIFileSynth::SaveCompleted()\\n\", this);\n  return S_OK;\n}\n\nSTDMETHODIMP CAVIFileSynth::GetCurFile(LPOLESTR *lplpszFileName) {\n  _RPT1(0,\"%p->CAVIFileSynth::GetCurFile()\\n\", this);\n\n  if (lplpszFileName) *lplpszFileName = NULL;\n\n  return E_FAIL;\n}\n\n///////////////////////////////////////////////////\n/////// static local\n\nHRESULT CAVIFileSynth::Create(const CLSID& rclsid, const IID& riid, void **ppv) {\n  HRESULT hresult;\n\n  //\t_RPT0(0,\"CAVIFileSynth::Create()\\n\");\n\n  CAVIFileSynth* pAVIFileSynth = new(std::nothrow) CAVIFileSynth(rclsid);\n\n  if (!pAVIFileSynth) return E_OUTOFMEMORY;\n\n  hresult = pAVIFileSynth->QueryInterface(riid, ppv);\n  pAVIFileSynth->Release();\n\n  //\t_RPT1(0,\"CAVIFileSynth::Create() exit, result=0x%X\\n\", hresult);\n\n  return hresult;\n}\n\n///////////////////////////////////////////////////\n//////////// IUnknown\n\nSTDMETHODIMP CAVIFileSynth::QueryInterface(const IID& iid, void **ppv) {\n\n  if (!ppv) {\n    _RPT1(0,\"%p->CAVIFileSynth::QueryInterface() E_POINTER\\n\", this);\n    return E_POINTER;\n  }\n\n  _RPT1(0,\"%p->CAVIFileSynth::QueryInterface() \", this);\n  _RPT3(0,\"{%08lx-%04x-%04x-\", iid.Data1, iid.Data2, iid.Data3);\n  _RPT4(0,\"%02x%02x-%02x%02x\", iid.Data4[0], iid.Data4[1], iid.Data4[2], iid.Data4[3]);\n  _RPT4(0,\"%02x%02x%02x%02x} (\", iid.Data4[4], iid.Data4[5], iid.Data4[6], iid.Data4[7]);\n\n  if (iid == IID_IUnknown) {\n    *ppv = (IUnknown *)(IAVIFile *)this;\n    _RPT0(0,\"IUnknown)\\n\");\n  } else if (iid == IID_IClassFactory) {\n    *ppv = (IClassFactory *)this;\n    _RPT0(0,\"IClassFactory)\\n\");\n  } else if (iid == IID_IPersist) {\n    *ppv = (IPersist *)this;\n    _RPT0(0,\"IPersist)\\n\");\n  } else if (iid == IID_IPersistFile) {\n    *ppv = (IPersistFile *)this;\n    _RPT0(0,\"IPersistFile)\\n\");\n  } else if (iid == IID_IAVIFile) {\n    *ppv = (IAVIFile *)this;\n    _RPT0(0,\"IAVIFile)\\n\");\n  } else if (iid == IID_IAvisynthClipInfo) {\n    *ppv = (IAvisynthClipInfo *)this;\n    _RPT0(0,\"IAvisynthClipInfo)\\n\");\n  } else {\n    _RPT0(0,\"unsupported!)\\n\");\n    *ppv = NULL;\n    return E_NOINTERFACE;\n  }\n\n  AddRef();\n\n  return S_OK;\n}\n\nSTDMETHODIMP_(ULONG) CAVIFileSynth::AddRef() {\n\n  const int refs = InterlockedIncrement(&m_refs);\n  InterlockedIncrement(&gRefCnt);\n\n  _RPT3(0,\"%p->CAVIFileSynth::AddRef() gRefCnt=%d, m_refs=%d\\n\", this, gRefCnt, refs);\n\n  return refs;\n}\n\nSTDMETHODIMP_(ULONG) CAVIFileSynth::Release() {\n\n  const int refs = InterlockedDecrement(&m_refs);\n  InterlockedDecrement(&gRefCnt);\n\n  _RPT3(0,\"%p->CAVIFileSynth::Release() gRefCnt=%d, m_refs=%d\\n\", this, gRefCnt, refs);\n\n  if (!refs) delete this;\n  return refs;\n}\n\n////////////////////////////////////////////////////////////////////////\n//\n//\t\tCAVIStreamSynth\n//\n////////////////////////////////////////////////////////////////////////\n//////////// IUnknown\n\nSTDMETHODIMP CAVIStreamSynth::QueryInterface(const IID& iid, void **ppv) {\n\n  if (!ppv) {\n    _RPT2(0,\"%p->CAVIStreamSynth::QueryInterface() (%s) E_POINTER\\n\", this, sName);\n    return E_POINTER;\n  }\n\n  _RPT2(0,\"%p->CAVIStreamSynth::QueryInterface() (%s) \", this, sName);\n  _RPT3(0,\"{%08lx-%04x-%04x-\", iid.Data1, iid.Data2, iid.Data3);\n  _RPT4(0,\"%02x%02x-%02x%02x\", iid.Data4[0], iid.Data4[1], iid.Data4[2], iid.Data4[3]);\n  _RPT4(0,\"%02x%02x%02x%02x} (\", iid.Data4[4], iid.Data4[5], iid.Data4[6], iid.Data4[7]);\n\n  if (iid == IID_IUnknown) {\n    *ppv = (IUnknown *)(IAVIStream *)this;\n    _RPT0(0,\"IUnknown)\\n\");\n  } else if (iid == IID_IAVIStream) {\n    *ppv = (IAVIStream *)this;\n    _RPT0(0,\"IAVIStream)\\n\");\n  } else if (iid == IID_IAVIStreaming) {\n    *ppv = (IAVIStreaming *)this;\n    _RPT0(0,\"IAVIStreaming)\\n\");\n  } else {\n    _RPT0(0,\"unsupported!)\\n\");\n    *ppv = NULL;\n    return E_NOINTERFACE;\n  }\n\n  AddRef();\n\n  return S_OK;\n}\n\nSTDMETHODIMP_(ULONG) CAVIStreamSynth::AddRef() {\n\n  const int refs = InterlockedIncrement(&m_refs);\n  InterlockedIncrement(&gRefCnt);\n\n  _RPT4(0,\"%p->CAVIStreamSynth::AddRef() (%s) gRefCnt=%d, m_refs=%d\\n\", this, sName, gRefCnt, refs);\n\n  return refs;\n}\n\nSTDMETHODIMP_(ULONG) CAVIStreamSynth::Release() {\n\n  const int refs = InterlockedDecrement(&m_refs);\n  InterlockedDecrement(&gRefCnt);\n\n  _RPT4(0,\"%p->CAVIStreamSynth::Release() (%s) gRefCnt=%d, m_refs=%d\\n\", this, sName, gRefCnt, refs);\n\n  if (!refs) delete this;\n  return refs;\n}\n\n////////////////////////////////////////////////////////////////////////\n//\n//\t\tCAVIFileSynth\n//\n////////////////////////////////////////////////////////////////////////\n//////////// IAVIFile\n\nSTDMETHODIMP CAVIFileSynth::CreateStream(PAVISTREAM *ppStream, AVISTREAMINFOW *psi) {\n  _RPT1(0,\"%p->CAVIFileSynth::CreateStream()\\n\", this);\n  *ppStream = NULL;\n  return S_OK;//AVIERR_READONLY;\n}\n\nSTDMETHODIMP CAVIFileSynth::EndRecord() {\n  _RPT1(0,\"%p->CAVIFileSynth::EndRecord()\\n\", this);\n  return AVIERR_READONLY;\n}\n\nSTDMETHODIMP CAVIFileSynth::Save(LPCSTR szFile, AVICOMPRESSOPTIONS FAR *lpOptions,\n  AVISAVECALLBACK lpfnCallback) {\n  _RPT1(0,\"%p->CAVIFileSynth::Save()\\n\", this);\n  return AVIERR_READONLY;\n}\n\nSTDMETHODIMP CAVIFileSynth::ReadData(DWORD fcc, LPVOID lp, LONG *lpcb) {\n  _RPT1(0,\"%p->CAVIFileSynth::ReadData()\\n\", this);\n  return AVIERR_NODATA;\n}\n\nSTDMETHODIMP CAVIFileSynth::WriteData(DWORD fcc, LPVOID lpBuffer, LONG cbBuffer) {\n  _RPT1(0,\"%p->CAVIFileSynth::WriteData()\\n\", this);\n  return AVIERR_READONLY;\n}\n\nSTDMETHODIMP CAVIFileSynth::DeleteStream(DWORD fccType, LONG lParam) {\n  _RPT1(0,\"%p->CAVIFileSynth::DeleteStream()\\n\", this);\n  return AVIERR_READONLY;\n}\n\n\n///////////////////////////////////////////////////\n/////// local\n\nCAVIFileSynth::CAVIFileSynth(const CLSID& rclsid) {\n  _RPT1(0,\"%p->CAVIFileSynth::CAVIFileSynth()\\n\", this);\n\n  m_refs = 0;\n  AddRef();\n\n  szScriptName = NULL;\n  env = NULL;\n  error_msg = NULL;\n\n  VDubPlanarHack = false;\n  AVIPadScanlines = false;\n  Enable_V210 = false;\n  Enable_b64a = false;\n  Enable_Y3_10_10 = false;\n  Enable_Y3_10_16 = false;\n  Enable_PlanarToPackedRGB = false;\n\n  InitializeCriticalSection(&cs_filter_graph);\n}\n\nCAVIFileSynth::~CAVIFileSynth() {\n  _RPT2(0,\"%p->CAVIFileSynth::~CAVIFileSynth(), gRefCnt = %d\\n\", this, gRefCnt);\n\n  Lock();\n\n  delete[] szScriptName;\n\n  filter_graph = 0;\n\n  if (env) env->DeleteScriptEnvironment();\n  env = NULL;\n\n  DeleteCriticalSection(&cs_filter_graph);\n}\n\n\nSTDMETHODIMP CAVIFileSynth::Open(LPCSTR szFile, UINT mode, LPCOLESTR lpszFileName) {\n\n  //\t_RPT3(0,\"%p->CAVIFileSynth::Open(\\\"%s\\\", 0x%08lx)\\n\", this, szFile, mode);\n\n  if (mode & (OF_CREATE|OF_WRITE))\n    return E_FAIL;\n\n  if (env) env->DeleteScriptEnvironment();   // just in case\n  env = NULL;\n  filter_graph = 0;\n  vi = NULL;\n\n  szScriptName = new(std::nothrow) char[lstrlen(szFile)+1];\n  if (!szScriptName)\n    return AVIERR_MEMORY;\n  lstrcpy(szScriptName, szFile);\n\n  // when unicode file names are given and cannot be converted to 8 bit, szFile has ??? chars\n  // szFile: 0x0018f198 \"C:\\\\unicode\\\\SNH48 - ??????.avs\"\n  // lpSzFileName 0x02631cc8 L\"C:\\\\unicode\\\\SNH48 - unicode_chars_here.avs\"\n  // use utf8 in DelayInit2 instead of szScriptName\n  std::wstring ScriptNameW = lpszFileName;\n\n  // wide -> utf8\n  int utf8len = WideCharToMultiByte(CP_UTF8, 0, ScriptNameW.c_str(), -1/*null terminated src*/, NULL, 0/*returns the required buffer size*/, 0, 0) + 1; // with \\0 terminator\n  szScriptNameUTF8 = new(std::nothrow) char[utf8len];\n  if (!szScriptNameUTF8)\n    return AVIERR_MEMORY;\n\n  WideCharToMultiByte(CP_UTF8, 0, ScriptNameW.c_str(), -1, szScriptNameUTF8, utf8len, 0, 0);\n  // conversion to c_str once, here, not in DelayInit2\n\n  return S_OK;\n}\n\nbool CAVIFileSynth::DelayInit() {\n\n  Lock();\n\n  bool result = DelayInit2();\n\n  Unlock();\n\n  return result;\n}\n\nbool CAVIFileSynth::DelayInit2() {\n  // _RPT1(0,\"Original: 0x%.4x\\n\", _control87( 0, 0 ) );\n#if defined(MSVC)\n  unsigned int fp_state = _controlfp(0, 0);\n  _controlfp(FP_STATE, FP_MASK);\n#endif\n  if (szScriptNameUTF8) // unicode!\n  {\n#ifndef _DEBUG\n    try {\n#endif\n      try {\n        // create a script environment and load the script into it\n        env = CreateScriptEnvironment2();\n        if (!env) return false;\n      }\n      catch (const AvisynthError &error) {\n        error_msg = error.msg;\n        return false;\n      }\n      try {\n        AVSValue new_args[2] = { szScriptNameUTF8, true };\n        AVSValue return_val = env->Invoke(\"Import\", AVSValue(new_args, 2));\n\n        // store the script's return value (a video clip)\n        if (return_val.IsClip()) {\n          filter_graph = return_val.AsClip();\n\n          // Allow WAVE_FORMAT_IEEE_FLOAT audio output\n          const bool AllowFloatAudio = env->GetVarBool(VARNAME_AllowFloatAudio, false);\n\n          if (!AllowFloatAudio && filter_graph->GetVideoInfo().IsSampleType(SAMPLE_FLOAT)) // Ensure samples are int\n            filter_graph = env->Invoke(\"ConvertAudioTo16bit\", AVSValue(&return_val, 1)).AsClip();\n\n          filter_graph = env->Invoke(\"Cache\", AVSValue(filter_graph)).AsClip();\n\n          // Tune top-level cache for encoding\n          filter_graph->SetCacheHints(CACHE_SET_MIN_CAPACITY, 0);\n          filter_graph->SetCacheHints(CACHE_SET_MAX_CAPACITY, 0);\n\n          // Alternate sample values for editors:\n          //filter_graph->SetCacheHints(CACHE_SET_MIN_CAPACITY, 10);\n          //filter_graph->SetCacheHints(CACHE_SET_MAX_CAPACITY, 100);\n        }\n        else if (return_val.IsBool())\n          env->ThrowError(\"The script's return value was not a video clip, (Is a bool, %s).\", return_val.AsBool() ? \"True\" : \"False\");\n        else if (return_val.IsInt())\n          env->ThrowError(\"The script's return value was not a video clip, (Is an int, %d).\", return_val.AsInt());\n        else if (return_val.IsFloat())\n          env->ThrowError(\"The script's return value was not a video clip, (Is a float, %f).\", return_val.AsFloat());\n        else if (return_val.IsString())\n          env->ThrowError(\"The script's return value was not a video clip, (Is a string, %s).\", return_val.AsString());\n        else if (return_val.IsArray())\n          env->ThrowError(\"The script's return value was not a video clip, (Is an array[%d]).\", return_val.ArraySize());\n        else if (!return_val.Defined())\n          env->ThrowError(\"The script's return value was not a video clip, (Is the undefined value).\");\n        else\n          env->ThrowError(\"The script's return value was not a video clip, (The type is unknown).\");\n\n        if (!filter_graph)\n          env->ThrowError(\"The returned video clip was nil (this is a bug)\");\n\n        // get information about the clip\n        vi = &filter_graph->GetVideoInfo();\n\n        // Hack YV16 and YV24 chroma plane order for old VDub's\n        VDubPlanarHack = env->GetVarBool(VARNAME_VDubPlanarHack, false);\n\n        // Option to have scanlines mod4 padded in all pixel formats\n        AVIPadScanlines = env->GetVarBool(VARNAME_AVIPadScanlines, false);\n\n        // AVS+ Enable_V210 instead of P210\n        Enable_V210 = env->GetVarBool(VARNAME_Enable_V210, false);\n        // AVS+ y3[10][10] instead of P210\n        Enable_Y3_10_10 = env->GetVarBool(VARNAME_Enable_Y3_10_10, false);\n        // AVS+ y3[10][16] instead of P216\n        Enable_Y3_10_16 = env->GetVarBool(VARNAME_Enable_Y3_10_16, false);\n        // AVS+ Enable_V210 instead of BRA[64]\n        Enable_b64a = env->GetVarBool(VARNAME_Enable_b64a, false);\n        // AVS+ Enable on-the-fly Planar RGB to Packed RGB conversion\n        Enable_PlanarToPackedRGB = env->GetVarBool(VARNAME_Enable_PlanarToPackedRGB, false);\n      }\n      catch (const AvisynthError &error) {\n        error_msg = error.msg;\n        try {\n          AVSValue args[2] = { error.msg, 0xff3333 };\n          static const char* const arg_names[2] = { 0, \"text_color\" };\n          filter_graph = env->Invoke(\"MessageClip\", AVSValue(args, 2), arg_names).AsClip();\n          vi = &filter_graph->GetVideoInfo();\n        }\n        catch (const AvisynthError&) {\n          filter_graph = 0;\n        }\n      }\n\n      delete[] szScriptName;\n      szScriptName = NULL;\n      delete[] szScriptNameUTF8;\n      szScriptNameUTF8 = NULL;\n#ifdef X86_32\n      _mm_empty();\n#endif\n#if defined(MSVC)\n      _clearfp();\n      _controlfp( fp_state, FP_MASK);\n#endif\n      return true;\n#ifndef _DEBUG\n    }\n    catch (...) {\n      _RPT0(1,\"DelayInit() caught general exception!\\n\");\n#if defined(MSVC)\n      _clearfp();\n#endif\n#ifdef X86_32\n      _mm_empty();\n#if defined(MSVC)\n      _controlfp( fp_state, FP_MASK );\n#endif\n#endif\n      return false;\n    }\n#endif\n  } else {\n#ifdef X86_32\n    _mm_empty();\n#endif\n#if defined(MSVC)\n    _clearfp();\n    _controlfp( fp_state, FP_MASK);\n#endif\n    return (env && filter_graph && vi);\n  }\n}\n\n\nvoid CAVIFileSynth::MakeErrorStream(const char* msg) {\n  error_msg = msg;\n  filter_graph = Create_MessageClip(msg, vi->width, vi->height, vi->pixel_type, false, 0xFF3333, 0, 0, -1, -1, -1,\n    true, /* may be utf8 when using AvisynthError::msgr */\n    env);\n}\n\nvoid CAVIFileSynth::Lock() {\n\n  EnterCriticalSection(&cs_filter_graph);\n\n}\n\nvoid CAVIFileSynth::Unlock() {\n\n  LeaveCriticalSection(&cs_filter_graph);\n\n}\n\n///////////////////////////////////////////////////\n//////////// IAVIFile\n\nSTDMETHODIMP CAVIFileSynth::Info(AVIFILEINFOW *pfi, LONG lSize) {\n\n  _RPT2(0,\"%p->CAVIFileSynth::Info(pfi, %d)\\n\", this, lSize);\n\n  if (!pfi) return E_POINTER;\n\n  if (!DelayInit()) return E_FAIL;\n\n  AVIFILEINFOW afi;\n\n  memset(&afi, 0, sizeof(afi));\n\n  afi.dwMaxBytesPerSec\t= 0;\n  afi.dwFlags\t\t\t\t= AVIFILEINFO_HASINDEX | AVIFILEINFO_ISINTERLEAVED;\n  afi.dwCaps\t\t\t\t= AVIFILECAPS_CANREAD | AVIFILECAPS_ALLKEYFRAMES | AVIFILECAPS_NOCOMPRESSION;\n\n  int nrStreams=0;\n  if (vi->HasVideo()==true)\tnrStreams=1;\n  if (vi->HasAudio()==true)\tnrStreams++;\n\n  afi.dwStreams\t\t\t\t= nrStreams;\n  afi.dwSuggestedBufferSize\t= 0;\n  afi.dwWidth\t\t\t\t\t= vi->width;\n  afi.dwHeight\t\t\t\t= vi->height;\n  afi.dwEditCount\t\t\t\t= 0;\n\n  afi.dwRate\t\t\t\t\t= vi->fps_numerator;\n  afi.dwScale\t\t\t\t\t= vi->fps_denominator;\n  afi.dwLength\t\t\t\t= vi->num_frames;\n\n  wcscpy(afi.szFileType, L\"Avisynth\");\n\n  // Maybe should return AVIERR_BUFFERTOOSMALL for lSize < sizeof(afi)\n  memset(pfi, 0, lSize);\n  memcpy(pfi, &afi, min(size_t(lSize), sizeof(afi)));\n  return S_OK;\n}\n\nstatic inline char BePrintable(int ch) {\n  ch &= 0xff;\n  return (char)(isprint(ch) ? ch : '.');\n}\n\n\nSTDMETHODIMP CAVIFileSynth::GetStream(PAVISTREAM *ppStream, DWORD fccType, LONG lParam) {\n  CAVIStreamSynth *casr;\n  char fcc[5];\n\n  fcc[0] = BePrintable(fccType      );\n  fcc[1] = BePrintable(fccType >>  8);\n  fcc[2] = BePrintable(fccType >> 16);\n  fcc[3] = BePrintable(fccType >> 24);\n  fcc[4] = 0;\n\n  _RPT4(0,\"%p->CAVIFileSynth::GetStream(*, %08x(%s), %ld)\\n\", this, fccType, fcc, lParam);\n\n  if (!DelayInit()) return E_FAIL;\n\n  *ppStream = NULL;\n\n  if (!fccType)\n  {\n    // Maybe an Option to set the order of stream discovery\n    if ((lParam==0) && (vi->HasVideo()) )\n      fccType = streamtypeVIDEO;\n    else\n      if ( ((lParam==1) && (vi->HasVideo())) ||  ((lParam==0) && vi->HasAudio()) )\n      {\n        lParam=0;\n        fccType = streamtypeAUDIO;\n      }\n  }\n\n  if (lParam > 0) return AVIERR_NODATA;\n\n  if (fccType == streamtypeVIDEO) {\n    if (!vi->HasVideo())\n      return AVIERR_NODATA;\n\n    if ((casr = new(std::nothrow) CAVIStreamSynth(this, false)) == 0)\n      return AVIERR_MEMORY;\n\n    *ppStream = (IAVIStream *)casr;\n\n  } else if (fccType == streamtypeAUDIO) {\n    if (!vi->HasAudio())\n      return AVIERR_NODATA;\n\n    if ((casr = new(std::nothrow) CAVIStreamSynth(this, true)) == 0)\n      return AVIERR_MEMORY;\n\n    *ppStream = (IAVIStream *)casr;\n  } else\n    return AVIERR_NODATA;\n\n  return S_OK;\n}\n\n\n////////////////////////////////////////////////////////////////////////\n//////////// IAvisynthClipInfo\n\nint __stdcall CAVIFileSynth::GetError(const char** ppszMessage) {\n  if (!DelayInit() && !error_msg)\n    error_msg = \"Avisynth: script open failed!\";\n\n  if (ppszMessage)\n    *ppszMessage = error_msg;\n  return !!error_msg;\n}\n\nbool __stdcall CAVIFileSynth::GetParity(int n) {\n  if (!DelayInit())\n    return false;\n  return filter_graph->GetParity(n);\n}\n\nbool __stdcall CAVIFileSynth::IsFieldBased() {\n  if (!DelayInit())\n    return false;\n  return vi->IsFieldBased();\n}\n\n\n////////////////////////////////////////////////////////////////////////\n//\n//\t\tCAVIStreamSynth\n//\n////////////////////////////////////////////////////////////////////////\n//////////// IAVIStreaming\n\nSTDMETHODIMP CAVIStreamSynth::Begin(LONG lStart, LONG lEnd, LONG lRate) {\n  _RPT5(0,\"%p->CAVIStreamSynth::Begin(%ld, %ld, %ld) (%s)\\n\", this, lStart, lEnd, lRate, sName);\n  return S_OK;\n}\n\nSTDMETHODIMP CAVIStreamSynth::End() {\n  _RPT2(0,\"%p->CAVIStreamSynth::End() (%s)\\n\", this, sName);\n  return S_OK;\n}\n\n//////////// IAVIStream\n\nSTDMETHODIMP CAVIStreamSynth::Create(LPARAM lParam1, LPARAM lParam2) {\n  _RPT1(0,\"%p->CAVIStreamSynth::Create()\\n\", this);\n  return AVIERR_READONLY;\n}\n\nSTDMETHODIMP CAVIStreamSynth::Delete(LONG lStart, LONG lSamples) {\n  _RPT1(0,\"%p->CAVIStreamSynth::Delete()\\n\", this);\n  return AVIERR_READONLY;\n}\n\nSTDMETHODIMP CAVIStreamSynth::ReadData(DWORD fcc, LPVOID lp, LONG *lpcb) {\n  _RPT1(0,\"%p->CAVIStreamSynth::ReadData()\\n\", this);\n  return AVIERR_NODATA;\n}\n\nSTDMETHODIMP CAVIStreamSynth::SetFormat(LONG lPos, LPVOID lpFormat, LONG cbFormat) {\n  _RPT1(0,\"%p->CAVIStreamSynth::SetFormat()\\n\", this);\n  return AVIERR_READONLY;\n}\n\nSTDMETHODIMP CAVIStreamSynth::WriteData(DWORD fcc, LPVOID lpBuffer, LONG cbBuffer) {\n  _RPT1(0,\"%p->CAVIStreamSynth::WriteData()\\n\", this);\n  return AVIERR_READONLY;\n}\n\nSTDMETHODIMP CAVIStreamSynth::SetInfo(AVISTREAMINFOW *psi, LONG lSize) {\n  _RPT1(0,\"%p->CAVIStreamSynth::SetInfo()\\n\", this);\n  return AVIERR_READONLY;\n}\n\n////////////////////////////////////////////////////////////////////////\n//////////// local\n\nCAVIStreamSynth::CAVIStreamSynth(CAVIFileSynth *parentPtr, bool isAudio) {\n\n  sName = isAudio ? \"audio\" : \"video\";\n\n  _RPT2(0,\"%p->CAVIStreamSynth(%s)\\n\", this, sName);\n\n  m_refs = 0; AddRef();\n\n  parent\t\t\t= parentPtr;\n  fAudio\t\t\t= isAudio;\n\n  parent->AddRef();\n}\n\nCAVIStreamSynth::~CAVIStreamSynth() {\n  _RPT3(0,\"%p->~CAVIStreamSynth() (%s), gRefCnt = %d\\n\", this, sName, gRefCnt);\n\n  if (parent)\n    parent->Release();\n}\n\n////////////////////////////////////////////////////////////////////////\n//////////// IAVIStream\n\nSTDMETHODIMP_(LONG) CAVIStreamSynth::Info(AVISTREAMINFOW *psi, LONG lSize) {\n  _RPT4(0,\"%p->CAVIStreamSynth::Info(%p, %ld) (%s)\\n\", this, psi, lSize, sName);\n\n  if (!psi) return E_POINTER;\n\n  AVISTREAMINFOW asi;\n\n  const VideoInfo* const vi = parent->vi;\n\n  memset(&asi, 0, sizeof(asi));\n  asi.fccType = fAudio ? streamtypeAUDIO : streamtypeVIDEO;\n  asi.dwQuality = DWORD(-1);\n  if (fAudio) {\n    asi.fccHandler = 0;\n    int bytes_per_sample = vi->BytesPerAudioSample();\n    asi.dwScale = bytes_per_sample;\n    asi.dwRate = vi->audio_samples_per_second * bytes_per_sample;\n    asi.dwLength = (unsigned int)vi->num_audio_samples;\n    asi.dwSampleSize = bytes_per_sample;\n    wcscpy(asi.szName, L\"Avisynth audio #1\");\n  } else {\n    bool targetIsConvertedToPackedRGB = (parent->Enable_PlanarToPackedRGB && (vi->IsPlanarRGB() || vi->IsPlanarRGBA()));\n\n    VideoInfo vi_final = *vi;\n    // if basic type is changed, that affects buffer size, we change the format here\n    if (targetIsConvertedToPackedRGB) {\n      // Enable_PlanarToPackedRGB results in packed RGB64 for bits>8, RGB24/32 for 8 bits\n      if (vi->BitsPerComponent() == 8) {\n        if (vi->IsPlanarRGB())\n          vi_final.pixel_type = VideoInfo::CS_BGR24;\n        else // planar RGBA\n          vi_final.pixel_type = VideoInfo::CS_BGR32;\n      }\n      else // all 8+ bit planar RGB(A) is converted to RGB64\n        vi_final.pixel_type = VideoInfo::CS_BGR64;\n    }\n    // silent mapping of 12/14 bit YUV formats to 16 bit\n    if (vi->pixel_type == VideoInfo::CS_YUV420P12 || vi->pixel_type == VideoInfo::CS_YUV420P14 || vi->pixel_type == VideoInfo::CS_YUV420PS)\n      vi_final.pixel_type = VideoInfo::CS_YUV420P16;\n    else if (vi->pixel_type == VideoInfo::CS_YUV422P12 || vi->pixel_type == VideoInfo::CS_YUV422P14 || vi->pixel_type == VideoInfo::CS_YUV422PS)\n      vi_final.pixel_type = VideoInfo::CS_YUV422P16;\n    else if (vi->pixel_type == VideoInfo::CS_YUV444P10 || vi->pixel_type == VideoInfo::CS_YUV444P12 || vi->pixel_type == VideoInfo::CS_YUV444P14 || vi->pixel_type == VideoInfo::CS_YUV444PS)\n      vi_final.pixel_type = VideoInfo::CS_YUV444P16;\n    else if (vi->pixel_type == VideoInfo::CS_YUVA444P10 || vi->pixel_type == VideoInfo::CS_YUVA444P12 || vi->pixel_type == VideoInfo::CS_YUVA444P14 || vi->pixel_type == VideoInfo::CS_YUVA444PS)\n      vi_final.pixel_type = VideoInfo::CS_YUVA444P16;\n    // -- pixel_type change end\n\n    const int image_size = parent->ImageSize(&vi_final);\n    asi.fccHandler = MAKEFOURCC('N','K','N','U'); // 'UNKN';\n\n    if (vi_final.IsRGB() && !vi_final.IsPlanar() && vi_final.BitsPerComponent() == 8)\n      asi.fccHandler = MAKEFOURCC('D','I','B',' ');\n    else if (vi_final.IsYUY2())\n      asi.fccHandler = MAKEFOURCC('Y','U','Y','2');\n    else if (vi_final.IsYV12())\n      asi.fccHandler = MAKEFOURCC('Y','V','1','2');\n    else if (vi_final.IsY8())\n      asi.fccHandler = MAKEFOURCC('Y','8','0','0');\n    else if (vi_final.IsYV24())\n      asi.fccHandler = MAKEFOURCC('Y','V','2','4');\n    else if (vi_final.IsYV16())\n      asi.fccHandler = MAKEFOURCC('Y','V','1','6');\n    else if (vi_final.IsYV411())\n      asi.fccHandler = MAKEFOURCC('Y','4','1','B');\n    // avs+\n    else if (vi_final.IsRGB64() && parent->Enable_b64a)\n      asi.fccHandler = MAKEFOURCC('b','6','4','a'); // b64a = packed rgba 4*16-bit\n    else if (vi_final.IsRGB64())\n      asi.fccHandler = MAKEFOURCC('B','R','A',64); // BRA@ ie. BRA[64]\n    else if (vi_final.IsRGB48())\n      asi.fccHandler = MAKEFOURCC('B','G','R',48); // BGR0 ie. BGR[48]\n    else if (vi_final.pixel_type == VideoInfo::CS_YUV420P10)\n      asi.fccHandler = MAKEFOURCC('P','0','1','0');\n    else if (vi_final.pixel_type == VideoInfo::CS_YUV420P16)\n      asi.fccHandler = MAKEFOURCC('P','0','1','6');\n    else if (vi_final.pixel_type == VideoInfo::CS_YUV422P10 && parent->Enable_V210)\n      asi.fccHandler = MAKEFOURCC('v','2','1','0');\n    else if (vi_final.pixel_type == VideoInfo::CS_YUV422P10 && parent->Enable_Y3_10_10)\n      asi.fccHandler = MAKEFOURCC('Y', '3', 10, 10); // Y3[10][10] (AV_PIX_FMT_YUV422P10) = planar YUV 422*10-bit\n    else if (vi_final.pixel_type == VideoInfo::CS_YUV422P10)\n      asi.fccHandler = MAKEFOURCC('P','2','1','0');\n    else if (vi_final.pixel_type == VideoInfo::CS_YUV422P16 && parent->Enable_Y3_10_16)\n      asi.fccHandler = MAKEFOURCC('Y', '3', 10, 16); // Y3[10][16] (AV_PIX_FMT_YUV422P16) = planar YUV 422*16-bit\n    else if (vi_final.pixel_type == VideoInfo::CS_YUV422P16)\n      asi.fccHandler = MAKEFOURCC('P','2','1','6');\n    else if (vi_final.pixel_type == VideoInfo::CS_YUV444P16 || vi_final.pixel_type == VideoInfo::CS_YUVA444P16)\n      asi.fccHandler = MAKEFOURCC('Y','4','1','6');\n    else if (vi_final.pixel_type == VideoInfo::CS_RGBP)\n      asi.fccHandler = MAKEFOURCC('G','3',0, 8); // similar to 10-16 bits G3[0][8]\n    // asi.fccHandler = MAKEFOURCC('8','B','P','S'); // this would be a special RLE encoded format\n    // MagicYUV implements these (planar rgb/rgba 10,12,14,16) G3[0][10], G4[0][10], G3[0][12], G4[0][12], G3[0][14], G4[0][14], G3[0][16], G4[0][16]\n    else if (vi_final.pixel_type == VideoInfo::CS_RGBP10)\n      asi.fccHandler = MAKEFOURCC('G','3',0,10);\n    else if (vi_final.pixel_type == VideoInfo::CS_RGBP12)\n      asi.fccHandler = MAKEFOURCC('G','3',0,12);\n    else if (vi_final.pixel_type == VideoInfo::CS_RGBP14)\n      asi.fccHandler = MAKEFOURCC('G','3',0,14);\n    else if (vi_final.pixel_type == VideoInfo::CS_RGBP16)\n      asi.fccHandler = MAKEFOURCC('G','3',0,16);\n    else if (vi_final.pixel_type == VideoInfo::CS_RGBAP)\n      asi.fccHandler = MAKEFOURCC('G','4',0, 8); // similar to 10-16 bits G4[0][10]\n    else if (vi_final.pixel_type == VideoInfo::CS_RGBAP10)\n      asi.fccHandler = MAKEFOURCC('G','4',0,10);\n    else if (vi_final.pixel_type == VideoInfo::CS_RGBAP12)\n      asi.fccHandler = MAKEFOURCC('G','4',0,12);\n    else if (vi_final.pixel_type == VideoInfo::CS_RGBAP14)\n      asi.fccHandler = MAKEFOURCC('G','4',0,14);\n    else if (vi_final.pixel_type == VideoInfo::CS_RGBAP16)\n      asi.fccHandler = MAKEFOURCC('G','4',0,16);\n    else {\n      // fixme: YUVA420P8, grey 10+ bits such as Y16 are not covered\n      _ASSERT(FALSE);\n    }\n\n    asi.dwScale = vi_final.fps_denominator;\n    asi.dwRate = vi_final.fps_numerator;\n    asi.dwLength = vi_final.num_frames;\n    asi.rcFrame.right = vi_final.width;\n    asi.rcFrame.bottom = vi_final.height;\n    asi.dwSampleSize = image_size;\n    asi.dwSuggestedBufferSize = image_size;\n    wcscpy(asi.szName, L\"Avisynth video #1\");\n  }\n\n  // Maybe should return AVIERR_BUFFERTOOSMALL for lSize < sizeof(asi)\n  memset(psi, 0, lSize);\n  memcpy(psi, &asi, min(size_t(lSize), sizeof(asi)));\n  return S_OK;\n}\n\nSTDMETHODIMP_(LONG) CAVIStreamSynth::FindSample(LONG lPos, LONG lFlags) {\n  //\t_RPT3(0,\"%p->CAVIStreamSynth::FindSample(%ld, %08lx)\\n\", this, lPos, lFlags);\n\n  if (lFlags & FIND_FORMAT)\n    return -1;\n\n  if (lFlags & FIND_FROM_START)\n    return 0;\n\n  return lPos;\n}\n\n\n////////////////////////////////////////////////////////////////////////\n//////////// local\n\nint CAVIFileSynth::ImageSize(const VideoInfo *vi) {\n  return AviHelper_ImageSize(vi, AVIPadScanlines, Enable_V210, false, false, false, false, false, false);\n}\n\nvoid CAVIStreamSynth::ReadFrame(void* lpBuffer, int n) {\n//  _RPT1(0, \"CAVIStreamSynth::ReadFrame %d\\r\\n\", n);\n  VideoInfo vi = parent->filter_graph->GetVideoInfo();\n  PVideoFrame frame;\n\n  if (((vi.Is420() || vi.Is422()) && (vi.BitsPerComponent() == 12 || vi.BitsPerComponent() == 14 || vi.BitsPerComponent() == 32)) ||\n    (vi.Is444() && (vi.BitsPerComponent() > 8 && vi.BitsPerComponent() != 16)))\n  {\n    // silent mapping of 12/14bit/float YUV420/422 formats to 16 bits\n    AVSValue new_args[2] = { parent->filter_graph, 16 };\n    PClip newClip = parent->env->Invoke(\"ConvertBits\", AVSValue(new_args, 2)).AsClip();\n    frame = newClip->GetFrame(n, parent->env);\n    vi = newClip->GetVideoInfo();\n  }\n  else if (parent->Enable_PlanarToPackedRGB && (vi.IsPlanarRGB() || vi.IsPlanarRGBA())) {\n    PClip newClip;\n    // convert Planar RGB to RGB24/32/RGB64\n    if (vi.BitsPerComponent() == 8) // 8 bit: ConvertToRGB24/32\n    {\n      if (vi.IsPlanarRGB()) {\n        AVSValue new_args[1] = { parent->filter_graph };\n        newClip = parent->env->Invoke(\"ConvertToRGB24\", AVSValue(new_args, 1)).AsClip();\n      }\n      else { // IsPlanarRGBA()\n        AVSValue new_args[1] = { parent->filter_graph };\n        newClip = parent->env->Invoke(\"ConvertToRGB32\", AVSValue(new_args, 1)).AsClip();\n      }\n    }\n    else {\n      // 8+ bits, always RGB64\n      newClip = parent->filter_graph;\n      if (vi.BitsPerComponent() != 16) {\n        AVSValue new_args[2] = { newClip, 16 };\n        newClip = parent->env->Invoke(\"ConvertBits\", AVSValue(new_args, 2)).AsClip();\n      }\n      AVSValue new_args[1] = { newClip };\n      newClip = parent->env->Invoke(\"ConvertToRGB64\", AVSValue(new_args, 1)).AsClip();\n    }\n    frame = newClip->GetFrame(n, parent->env);\n    vi = newClip->GetVideoInfo();\n  }\n  else {\n    // no on-the-fly conversion\n    frame = parent->filter_graph->GetFrame(n, parent->env);\n  }\n  if (!frame)\n    parent->env->ThrowError(\"Avisynth error: generated video frame was nil (this is a bug)\");\n\n  // Y416 packed U,Y,V,A\n  if (vi.pixel_type == VideoInfo::CS_YUV444P16 || vi.pixel_type == VideoInfo::CS_YUVA444P16) {\n    int width = vi.width;\n    int height = vi.height;\n    int ppitch_y = frame->GetPitch(PLANAR_Y);\n    int ppitch_uv = frame->GetPitch(PLANAR_U);\n    int ppitch_a = frame->GetPitch(PLANAR_A);\n    bool hasAlpha = (vi.NumComponents() == 4);\n    const uint8_t *yptr = frame->GetReadPtr(PLANAR_Y);\n    const uint8_t *uptr = frame->GetReadPtr(PLANAR_U);\n    const uint8_t *vptr = frame->GetReadPtr(PLANAR_V);\n    const uint8_t *aptr = frame->GetReadPtr(PLANAR_A);\n    uint8_t *outbuf = (uint8_t *)lpBuffer;\n    int out_pitch = width * 4 * sizeof(uint16_t);\n#ifdef INTEL_INTRINSICS\n    if ((parent->env->GetCPUFlags() & CPUF_SSE2) != 0) {\n      if (hasAlpha)\n        ToY416_sse2<true>(outbuf, out_pitch, yptr, ppitch_y, uptr, vptr, ppitch_uv, aptr, ppitch_a, width, height);\n      else\n        ToY416_sse2<false>(outbuf, out_pitch, yptr, ppitch_y, uptr, vptr, ppitch_uv, aptr, ppitch_a, width, height);\n    }\n    else\n#endif\n    {\n      if (hasAlpha)\n        ToY416_c<true>(outbuf, out_pitch, yptr, ppitch_y, uptr, vptr, ppitch_uv, aptr, ppitch_a, width, height);\n      else\n        ToY416_c<false>(outbuf, out_pitch, yptr, ppitch_y, uptr, vptr, ppitch_uv, aptr, ppitch_a, width, height);\n    }\n    return;\n  }\n\n  const int pitch    = frame->GetPitch();\n  const int row_size = frame->GetRowSize();\n  const int height   = frame->GetHeight();\n\n  int out_pitch;\n  int out_pitchUV;\n\n  // BMP scanlines are dword-aligned\n  if ((vi.IsRGB() && !vi.IsPlanar()) || vi.IsYUY2() || vi.IsY() || parent->AVIPadScanlines) {\n    out_pitch = (row_size+3) & ~3;\n    out_pitchUV = (frame->GetRowSize(PLANAR_U)+3) & ~3; // 0 for packed RGB\n  }\n  // Planar scanlines are packed\n  else {\n    out_pitch = row_size;\n    if(vi.IsRGB())\n      out_pitchUV = frame->GetRowSize(PLANAR_B); // G=B=R\n    else\n      out_pitchUV = frame->GetRowSize(PLANAR_U);\n  }\n\n  int plane1;\n  int plane2;\n\n  // Old VDub wants YUV for YV24 and YV16 and YVU for YV12.\n  if (parent->VDubPlanarHack && !vi.IsYV12() && !vi.IsRGB() && vi.BitsPerComponent() == 8) {\n    plane1 = PLANAR_U;\n    plane2 = PLANAR_V;\n  }\n  else {\n    if (vi.IsRGB() && vi.IsPlanar())\n    {\n      // (PLANAR_G)\n      plane1 = PLANAR_B;\n      plane2 = PLANAR_R;\n    }\n    else {\n      if (vi.BitsPerComponent() == 8) {\n      // Set default VFW output plane order.\n        plane1 = PLANAR_V;\n        plane2 = PLANAR_U;\n      }\n      else {\n        plane1 = PLANAR_U;\n        plane2 = PLANAR_V;\n      }\n    }\n  }\n\n  bool semi_packed_p10 = (vi.pixel_type == VideoInfo::CS_YUV420P10) || (vi.pixel_type == VideoInfo::CS_YUV422P10) ;\n  bool semi_packed_p16 = (vi.pixel_type == VideoInfo::CS_YUV420P16) || (vi.pixel_type == VideoInfo::CS_YUV422P16) ;\n\n#ifdef INTEL_INTRINSICS\n  const bool ssse3 = (parent->env->GetCPUFlags() & CPUF_SSSE3) != 0;\n  const bool sse2 = (parent->env->GetCPUFlags() & CPUF_SSE2) != 0;\n#endif\n\n  if ((vi.pixel_type == VideoInfo::CS_YUV420P10) || (vi.pixel_type == VideoInfo::CS_YUV420P16) ||\n      ((vi.pixel_type == VideoInfo::CS_YUV422P10) && !parent->Enable_Y3_10_10 && !parent->Enable_V210) ||\n      ((vi.pixel_type == VideoInfo::CS_YUV422P16) && !parent->Enable_Y3_10_16))\n  {\n    yuv42xp10_16_to_Px10_16((uint8_t *)lpBuffer, out_pitch,\n      frame->GetReadPtr(), frame->GetPitch(),\n      frame->GetReadPtr(PLANAR_U), frame->GetReadPtr(PLANAR_V), frame->GetPitch(PLANAR_U),\n      vi.width, vi.height, frame->GetHeight(PLANAR_U), semi_packed_p16, parent->env);\n\n  }\n  else {\n    if (vi.pixel_type == VideoInfo::CS_YUV422P10 && parent->Enable_V210) {\n      int width = frame->GetRowSize(PLANAR_Y) / vi.ComponentSize();\n      yuv422p10_to_v210((BYTE *)lpBuffer, frame->GetReadPtr(PLANAR_Y), frame->GetPitch(PLANAR_Y),\n        frame->GetReadPtr(PLANAR_U), frame->GetReadPtr(PLANAR_V), frame->GetPitch(PLANAR_U), width, height);\n    }\n    else if (semi_packed_p10 && !parent->Enable_Y3_10_10 && !parent->Enable_V210) {\n      // already handled\n    }\n    else if (vi.IsRGB64() && parent->Enable_b64a) {\n      // BGRA -> big endian ARGB with byte swap\n      uint8_t* pdst = (uint8_t *)lpBuffer + out_pitch * (height - 1); // upside down\n\n      int srcpitch = frame->GetPitch();\n      const BYTE *src = frame->GetReadPtr();\n#ifdef INTEL_INTRINSICS\n      if (ssse3)\n        bgra_to_argbBE_ssse3(pdst, -out_pitch, src, srcpitch, vi.width, vi.height);\n      else if (sse2)\n        bgra_to_argbBE_sse2(pdst, -out_pitch, src, srcpitch, vi.width, vi.height);\n      else\n#endif\n        bgra_to_argbBE_c(pdst, -out_pitch, src, srcpitch, vi.width, vi.height);\n    }\n    else if (vi.IsRGB48() || vi.IsRGB64())\n    {\n      // avisynth: upside down, output: back to normal\n      parent->env->BitBlt((BYTE*)lpBuffer + out_pitch * (height - 1), -out_pitch, frame->GetReadPtr(), pitch, row_size, height);\n    }\n    else {\n      parent->env->BitBlt((BYTE*)lpBuffer, out_pitch, frame->GetReadPtr(), pitch, row_size, height);\n    }\n\n    if (vi.pixel_type == VideoInfo::CS_YUV422P10 && parent->Enable_V210) {\n      // intentionally empty\n    }\n    else if ((semi_packed_p10 && !parent->Enable_Y3_10_10 && !parent->Enable_V210) ||\n      (semi_packed_p16 && !parent->Enable_Y3_10_16)) {\n      // already handled\n    }\n    else { // for RGB48 and 64 these are zero sized\n      parent->env->BitBlt((BYTE*)lpBuffer + (out_pitch*height),\n        out_pitchUV, frame->GetReadPtr(plane1),\n        frame->GetPitch(plane1), frame->GetRowSize(plane1),\n        frame->GetHeight(plane1));\n\n      parent->env->BitBlt((BYTE*)lpBuffer + (out_pitch*height + frame->GetHeight(plane1)*out_pitchUV),\n        out_pitchUV, frame->GetReadPtr(plane2),\n        frame->GetPitch(plane2), frame->GetRowSize(plane2),\n        frame->GetHeight(plane2));\n\n      // fill alpha, not from YUVA, only from RGBAP, because only RGBAP8-16 is mapped to alpha aware fourCCs\n      if (vi.IsPlanarRGBA()) {\n        parent->env->BitBlt((BYTE*)lpBuffer + (out_pitch*height + 2 * frame->GetHeight(plane1)*out_pitchUV),\n          out_pitchUV, frame->GetReadPtr(PLANAR_A),\n          frame->GetPitch(PLANAR_A), frame->GetRowSize(PLANAR_A),\n          frame->GetHeight(PLANAR_A));\n      }\n    }\n  }\n  // no alpha?\n//_RPT1(0, \"CAVIStreamSynth::ReadFrame %d END\\r\\n\", n);\n}\n\n\n////////////////////////////////////////////////////////////////////////\n//////////// IAVIStream\n\nSTDMETHODIMP CAVIStreamSynth::Read(LONG lStart, LONG lSamples, LPVOID lpBuffer, LONG cbBuffer, LONG *plBytes, LONG *plSamples) {\n\n#if defined(X86_32) && defined(MSVC)\n  // TODO: Does this need 64-bit porting?\n  __asm { // Force compiler to protect these registers!\n    mov ebx,ebx;\n    mov esi,esi;\n    mov edi,edi;\n  }\n#endif\n\n  parent->Lock();\n\n  HRESULT result = Read2(lStart, lSamples, lpBuffer, cbBuffer, plBytes, plSamples);\n\n  parent->Unlock();\n\n  return result;\n}\n\nHRESULT CAVIStreamSynth::Read2(LONG lStart, LONG lSamples, LPVOID lpBuffer, LONG cbBuffer, LONG *plBytes, LONG *plSamples) {\n\n  //  _RPT3(0,\"%p->CAVIStreamSynth::Read(%ld samples at %ld)\\n\", this, lSamples, lStart);\n  //  _RPT2(0,\"\\tbuffer: %ld bytes at %p\\n\", cbBuffer, lpBuffer);\n#ifdef MSVC\n  unsigned int fp_state = _controlfp( 0, 0 );\n  _controlfp( FP_STATE, FP_MASK);\n#endif\n\n  const VideoInfo* const vi = parent->vi;\n\n  bool targetIsConvertedToPackedRGB = (parent->Enable_PlanarToPackedRGB && (vi->IsPlanarRGB() || vi->IsPlanarRGBA()));\n\n  VideoInfo vi_final = *vi;\n  // if basic type is changed, that affects buffer size, we change the format here\n  if (targetIsConvertedToPackedRGB) {\n    // Enable_PlanarToPackedRGB results in packed RGB64 for bits>8, RGB24/32 for 8 bits\n    if (vi->BitsPerComponent() == 8) {\n      if (vi->IsPlanarRGB())\n        vi_final.pixel_type = VideoInfo::CS_BGR24;\n      else // planar RGBA\n        vi_final.pixel_type = VideoInfo::CS_BGR32;\n    }\n    else // all 8+ bit planar RGB(A) is converted to RGB64\n      vi_final.pixel_type = VideoInfo::CS_BGR64;\n  }\n  // silent mapping of 12/14/float bit YUV formats to 16 bit\n  if (vi->pixel_type == VideoInfo::CS_YUV420P12 || vi->pixel_type == VideoInfo::CS_YUV420P14 || vi->pixel_type == VideoInfo::CS_YUV420PS)\n    vi_final.pixel_type = VideoInfo::CS_YUV420P16;\n  else if (vi->pixel_type == VideoInfo::CS_YUV422P12 || vi->pixel_type == VideoInfo::CS_YUV422P14 || vi->pixel_type == VideoInfo::CS_YUV422PS)\n    vi_final.pixel_type = VideoInfo::CS_YUV422P16;\n  else if (vi->pixel_type == VideoInfo::CS_YUV444P10 || vi->pixel_type == VideoInfo::CS_YUV444P12 || vi->pixel_type == VideoInfo::CS_YUV444P14 || vi->pixel_type == VideoInfo::CS_YUV444PS)\n    vi_final.pixel_type = VideoInfo::CS_YUV444P16;\n  else if (vi->pixel_type == VideoInfo::CS_YUVA444P10 || vi->pixel_type == VideoInfo::CS_YUVA444P12 || vi->pixel_type == VideoInfo::CS_YUVA444P14 || vi->pixel_type == VideoInfo::CS_YUVA444PS)\n    vi_final.pixel_type = VideoInfo::CS_YUVA444P16;\n  // -- pixel_type change end\n\n  if (fAudio) {\n    // buffer overflow patch -- Avery Lee - Mar 2006\n    if (lSamples == AVISTREAMREAD_CONVENIENT)\n      lSamples = (int)vi->AudioSamplesFromFrames(1);\n\n    if (int64_t(lStart)+lSamples > vi->num_audio_samples) {\n      lSamples = (int)(vi->num_audio_samples - lStart);\n      if (lSamples < 0) lSamples = 0;\n    }\n\n    int bytes = (int)vi->BytesFromAudioSamples(lSamples);\n    if (lpBuffer && bytes > cbBuffer) {\n      lSamples = (int)vi->AudioSamplesFromBytes(cbBuffer);\n      bytes = (int)vi->BytesFromAudioSamples(lSamples);\n    }\n    if (plBytes) *plBytes = bytes;\n    if (plSamples) *plSamples = lSamples;\n    if (!lpBuffer || !lSamples)\n      return S_OK;\n\n  } else {\n    if (lStart >= vi->num_frames) {\n      if (plSamples) *plSamples = 0;\n      if (plBytes) *plBytes = 0;\n      return S_OK;\n    }\n\n    const int image_size = parent->ImageSize(&vi_final);\n    if (plSamples) *plSamples = 1;\n    if (plBytes) *plBytes = image_size;\n\n    if (!lpBuffer) {\n      return S_OK;\n    } else if (cbBuffer < image_size) {\n      //      _RPT1(0,\"\\tBuffer too small; should be %ld samples\\n\", image_size);\n      return AVIERR_BUFFERTOOSMALL;\n    }\n  }\n\n#ifndef _DEBUG\n  try {\n    try {\n#endif\n      SehGuard seh_guard;\n\n      if (fAudio)\n        parent->filter_graph->GetAudio(lpBuffer, lStart, lSamples, parent->env);\n      else\n        ReadFrame(lpBuffer, lStart);\n\n#ifndef _DEBUG\n    }\n    catch (AvisynthError &error) {\n      parent->MakeErrorStream(error.msg);\n      throw;\n    }\n    catch (SehException &seh) {\n      char buf[256];\n      _snprintf(buf, 255, \"CAVIStreamSynth: %s at 0x%p\", seh.m_msg, seh.m_addr);\n      parent->MakeErrorStream(parent->env->SaveString(buf));\n      throw;\n    }\n    catch (...) {\n      parent->MakeErrorStream(\"CAVIStreamSynth: unhandled C++ exception\");\n      throw;\n    }\n  }\n  catch (...) {\n#ifdef X86_32\n    _mm_empty();\n#endif\n#ifdef MSVC\n    _clearfp();\n    _controlfp( fp_state, FP_MASK);\n#endif\n    return E_FAIL;\n  }\n#endif\n#ifdef X86_32\n  _mm_empty();\n#endif\n#ifdef MSVC\n  _clearfp();\n  _controlfp( fp_state, FP_MASK);\n#endif\n  return S_OK;\n}\n\nSTDMETHODIMP CAVIStreamSynth::ReadFormat(LONG lPos, LPVOID lpFormat, LONG *lpcbFormat) {\n  _RPT2(0,\"%p->CAVIStreamSynth::ReadFormat() (%s)\\n\", this, sName);\n\n  if (!lpcbFormat) return E_POINTER;\n\n  const VideoInfo* const vi = parent->vi;\n\n  const bool UseWaveExtDefault = vi->IsChannelMaskKnown();\n  const bool UseWaveExtensible = parent->env->GetVarBool(VARNAME_UseWaveExtensible, UseWaveExtDefault);\n\n  if (!lpFormat) {\n    *lpcbFormat = fAudio ? ( UseWaveExtensible ? sizeof(WAVEFORMATEXTENSIBLE)\n      : sizeof(WAVEFORMATEX) )\n      : sizeof(BITMAPINFOHEADER);\n    return S_OK;\n  }\n\n  memset(lpFormat, 0, *lpcbFormat);\n\n  if (fAudio) {\n    if (UseWaveExtensible) {  // Use WAVE_FORMAT_EXTENSIBLE audio output format\n#ifndef MSVC\n      const GUID KSDATAFORMAT_SUBTYPE_PCM       = {0x00000001, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};\n#endif\n#ifndef MSVC\n      const GUID KSDATAFORMAT_SUBTYPE_IEEE_FLOAT= {0x00000003, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};\n#endif\n      WAVEFORMATEXTENSIBLE wfxt;\n\n      memset(&wfxt, 0, sizeof(wfxt));\n      wfxt.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;\n      wfxt.Format.nChannels = (WORD)vi->AudioChannels();\n      wfxt.Format.nSamplesPerSec = vi->SamplesPerSecond();\n      wfxt.Format.wBitsPerSample = (WORD)(vi->BytesPerChannelSample() * 8);\n      wfxt.Format.nBlockAlign = (WORD)vi->BytesPerAudioSample();\n      wfxt.Format.nAvgBytesPerSec = wfxt.Format.nSamplesPerSec * wfxt.Format.nBlockAlign;\n      wfxt.Format.cbSize = sizeof(wfxt) - sizeof(wfxt.Format);\n      wfxt.Samples.wValidBitsPerSample = wfxt.Format.wBitsPerSample;\n\n      // If is set, then let's use it.\n      if (vi->IsChannelMaskKnown())\n        wfxt.dwChannelMask = vi->GetChannelMask();\n      else {\n        wfxt.dwChannelMask = (unsigned)vi->AudioChannels() <= 8 ? GetDefaultChannelLayout(vi->AudioChannels())\n          : (unsigned)vi->AudioChannels() <= 18 ? DWORD(-1) >> (32 - vi->AudioChannels())\n          : SPEAKER_ALL;\n\n        unsigned int userChannelMask = (unsigned)(parent->env->GetVarInt(VARNAME_dwChannelMask, 0));\n        if (userChannelMask != 0)\n          wfxt.dwChannelMask = userChannelMask;\n      }\n\n      wfxt.SubFormat = vi->IsSampleType(SAMPLE_FLOAT) ? KSDATAFORMAT_SUBTYPE_IEEE_FLOAT : KSDATAFORMAT_SUBTYPE_PCM;\n      *lpcbFormat = min(*lpcbFormat, (LONG)sizeof(wfxt));\n      memcpy(lpFormat, &wfxt, size_t(*lpcbFormat));\n    }\n    else {\n      WAVEFORMATEX wfx;\n      memset(&wfx, 0, sizeof(wfx));\n      wfx.wFormatTag = vi->IsSampleType(SAMPLE_FLOAT) ? WAVE_FORMAT_IEEE_FLOAT : WAVE_FORMAT_PCM;\n      wfx.nChannels = (WORD)vi->AudioChannels();\n      wfx.nSamplesPerSec = vi->SamplesPerSecond();\n      wfx.wBitsPerSample = (WORD)(vi->BytesPerChannelSample() * 8);\n      wfx.nBlockAlign = (WORD)vi->BytesPerAudioSample();\n      wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;\n      *lpcbFormat = min(*lpcbFormat, (LONG)sizeof(wfx));\n      memcpy(lpFormat, &wfx, size_t(*lpcbFormat));\n    }\n  } else {\n    bool targetIsConvertedToPackedRGB = (parent->Enable_PlanarToPackedRGB && (vi->IsPlanarRGB() || vi->IsPlanarRGBA()));\n\n    VideoInfo vi_final = *vi;\n    // if basic type is changed, that affects buffer size, we change the format here\n    if (targetIsConvertedToPackedRGB) {\n      // Enable_PlanarToPackedRGB results in packed RGB64 for bits>8, RGB24/32 for 8 bits\n      if (vi->BitsPerComponent() == 8) {\n        if (vi->IsPlanarRGB())\n          vi_final.pixel_type = VideoInfo::CS_BGR24;\n        else // planar RGBA\n          vi_final.pixel_type = VideoInfo::CS_BGR32;\n      }\n      else // all 8+ bit planar RGB(A) is converted to RGB64\n        vi_final.pixel_type = VideoInfo::CS_BGR64;\n    }\n    // silent mapping of 12/14 bit YUV formats to 16 bit\n    if (vi->pixel_type == VideoInfo::CS_YUV420P12 || vi->pixel_type == VideoInfo::CS_YUV420P14 || vi->pixel_type == VideoInfo::CS_YUV420PS)\n      vi_final.pixel_type = VideoInfo::CS_YUV420P16;\n    else if (vi->pixel_type == VideoInfo::CS_YUV422P12 || vi->pixel_type == VideoInfo::CS_YUV422P14 || vi->pixel_type == VideoInfo::CS_YUV422PS)\n      vi_final.pixel_type = VideoInfo::CS_YUV422P16;\n    else if (vi->pixel_type == VideoInfo::CS_YUV444P10 || vi->pixel_type == VideoInfo::CS_YUV444P12 || vi->pixel_type == VideoInfo::CS_YUV444P14 || vi->pixel_type == VideoInfo::CS_YUV444PS)\n      vi_final.pixel_type = VideoInfo::CS_YUV444P16;\n    else if (vi->pixel_type == VideoInfo::CS_YUVA444P10 || vi->pixel_type == VideoInfo::CS_YUVA444P12 || vi->pixel_type == VideoInfo::CS_YUVA444P14 || vi->pixel_type == VideoInfo::CS_YUVA444PS)\n      vi_final.pixel_type = VideoInfo::CS_YUVA444P16;\n    // -- pixel_type change end\n\n    BITMAPINFOHEADER bi;\n    memset(&bi, 0, sizeof(bi));\n    bi.biSize = sizeof(bi);\n    bi.biWidth = vi_final.width;\n    bi.biHeight = vi_final.height;\n    bi.biPlanes = 1;\n    bi.biBitCount = (WORD)vi_final.BitsPerPixel();\n    if (vi_final.pixel_type == VideoInfo::CS_YUV422P10 && parent->Enable_V210)\n      bi.biBitCount = 20;\n\n    // Enable_PlanarToPackedRGB results in packed RGB64 for bits>8, RGB24/32 for 8 bits\n    if (vi_final.IsRGB() && !vi_final.IsPlanar() && vi_final.BitsPerComponent() == 8)\n      bi.biCompression = BI_RGB;\n    else if (vi_final.IsYUY2())\n      bi.biCompression = MAKEFOURCC('Y','U','Y','2');\n    else if (vi_final.IsYV12())\n      bi.biCompression = MAKEFOURCC('Y','V','1','2');\n    else if (vi_final.IsY8())\n      bi.biCompression = MAKEFOURCC('Y','8','0','0');\n    else if (vi_final.IsYV24())\n      bi.biCompression = MAKEFOURCC('Y','V','2','4');\n    else if (vi_final.IsYV16())\n      bi.biCompression = MAKEFOURCC('Y','V','1','6');\n    else if (vi_final.IsYV411())\n      bi.biCompression = MAKEFOURCC('Y','4','1','B');\n    // avs+\n    else if (vi_final.IsRGB64() && parent->Enable_b64a)\n      bi.biCompression = MAKEFOURCC('b','6','4','a');\n    else if (vi_final.IsRGB64())\n      bi.biCompression = MAKEFOURCC('B','R','A',64); // BRA@ ie. BRA[64]\n    else if (vi_final.IsRGB48())\n      bi.biCompression = MAKEFOURCC('B','G','R',48); // BGR0 ie. BGR[48]\n    else if (vi_final.pixel_type == VideoInfo::CS_YUV420P10)\n      bi.biCompression = MAKEFOURCC('P','0','1','0');\n    else if (vi_final.pixel_type == VideoInfo::CS_YUV420P16)\n      bi.biCompression = MAKEFOURCC('P','0','1','6');\n    else if (vi_final.pixel_type == VideoInfo::CS_YUV422P10 && parent->Enable_Y3_10_10)\n      bi.biCompression = MAKEFOURCC('Y', '3', 10, 10); // Y3[10][10] (AV_PIX_FMT_YUV422P10) = planar YUV 422*10-bit\n    else if (vi_final.pixel_type == VideoInfo::CS_YUV422P10 && parent->Enable_V210)\n      bi.biCompression = MAKEFOURCC('v','2','1','0');\n    else if (vi_final.pixel_type == VideoInfo::CS_YUV422P10)\n      bi.biCompression = MAKEFOURCC('P','2','1','0');\n    else if (vi_final.pixel_type == VideoInfo::CS_YUV422P16 && parent->Enable_Y3_10_16)\n      bi.biCompression = MAKEFOURCC('Y', '3', 10, 16); // Y3[10][16] (AV_PIX_FMT_YUV422P16) = planar YUV 422*16-bit\n    else if (vi_final.pixel_type == VideoInfo::CS_YUV422P16)\n      bi.biCompression = MAKEFOURCC('P','2','1','6');\n    else if (vi_final.pixel_type == VideoInfo::CS_YUV444P16 || vi_final.pixel_type == VideoInfo::CS_YUVA444P16)\n      bi.biCompression = MAKEFOURCC('Y','4','1','6');\n    else if (vi_final.pixel_type == VideoInfo::CS_RGBP)\n      bi.biCompression = MAKEFOURCC('G','3', 0, 8);\n    //      bi.biCompression = MAKEFOURCC('8','B','P','S'); special RLA encoded format, support G3[0][8] instead\n    // MagicYUV implements these (planar rgb/rgba 10,12,14,16) G3[0][10], G4[0][10], G3[0][12], G4[0][12], G3[0][14], G4[0][14], G3[0][16], G4[0][16]\n    else if (vi_final.pixel_type == VideoInfo::CS_RGBP10)\n      bi.biCompression = MAKEFOURCC('G','3',0,10);\n    else if (vi_final.pixel_type == VideoInfo::CS_RGBP12)\n      bi.biCompression = MAKEFOURCC('G','3',0,12);\n    else if (vi_final.pixel_type == VideoInfo::CS_RGBP14)\n      bi.biCompression = MAKEFOURCC('G','3',0,14);\n    else if (vi_final.pixel_type == VideoInfo::CS_RGBP16)\n      bi.biCompression = MAKEFOURCC('G','3',0,16);\n    else if (vi_final.pixel_type == VideoInfo::CS_RGBAP)\n      bi.biCompression = MAKEFOURCC('G','4',0, 8); // similar to 10-16 bits\n    else if (vi_final.pixel_type == VideoInfo::CS_RGBAP10)\n      bi.biCompression = MAKEFOURCC('G','4',0,10);\n    else if (vi_final.pixel_type == VideoInfo::CS_RGBAP12)\n      bi.biCompression = MAKEFOURCC('G','4',0,12);\n    else if (vi_final.pixel_type == VideoInfo::CS_RGBAP14)\n      bi.biCompression = MAKEFOURCC('G','4',0,14);\n    else if (vi_final.pixel_type == VideoInfo::CS_RGBAP16)\n      bi.biCompression = MAKEFOURCC('G','4',0,16);\n    else {\n      _ASSERT(FALSE);\n    }\n\n    bi.biSizeImage = parent->ImageSize(&vi_final);\n    *lpcbFormat = min(*lpcbFormat, (LONG)sizeof(bi));\n    memcpy(lpFormat, &bi, size_t(*lpcbFormat));\n  }\n  return S_OK;\n}\n\nSTDMETHODIMP CAVIStreamSynth::Write(LONG lStart, LONG lSamples, LPVOID lpBuffer,\n  LONG cbBuffer, DWORD dwFlags, LONG FAR *plSampWritten,\n  LONG FAR *plBytesWritten) {\n\n  _RPT1(0,\"%p->CAVIStreamSynth::Write()\\n\", this);\n\n  return AVIERR_READONLY;\n}\n#endif\n"
  },
  {
    "path": "avs_core/core/memcpy_amd.cpp",
    "content": "/******************************************************************************\n\n Copyright (c) 2001 Advanced Micro Devices, Inc.\n\n LIMITATION OF LIABILITY:  THE MATERIALS ARE PROVIDED *AS IS* WITHOUT ANY\n EXPRESS OR IMPLIED WARRANTY OF ANY KIND INCLUDING WARRANTIES OF MERCHANTABILITY,\n NONINFRINGEMENT OF THIRD-PARTY INTELLECTUAL PROPERTY, OR FITNESS FOR ANY\n PARTICULAR PURPOSE.  IN NO EVENT SHALL AMD OR ITS SUPPLIERS BE LIABLE FOR ANY\n DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS,\n BUSINESS INTERRUPTION, LOSS OF INFORMATION) ARISING OUT OF THE USE OF OR\n INABILITY TO USE THE MATERIALS, EVEN IF AMD HAS BEEN ADVISED OF THE POSSIBILITY\n OF SUCH DAMAGES.  BECAUSE SOME JURISDICTIONS PROHIBIT THE EXCLUSION OR LIMITATION\n OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE LIMITATION MAY\n NOT APPLY TO YOU.\n\n AMD does not assume any responsibility for any errors which may appear in the\n Materials nor any responsibility to support or update the Materials.  AMD retains\n the right to make changes to its test specifications at any time, without notice.\n\n NO SUPPORT OBLIGATION: AMD is not obligated to furnish, support, or make any\n further information, software, technical information, know-how, or show-how\n available to you.\n\n So that all may benefit from your experience, please report  any  problems\n or  suggestions about this software to 3dsdk.support@amd.com\n\n AMD Developer Technologies, M/S 585\n Advanced Micro Devices, Inc.\n 5900 E. Ben White Blvd.\n Austin, TX 78741\n 3dsdk.support@amd.com\n******************************************************************************/\n\n\n/*****************************************************************************\nMEMCPY_AMD.CPP\n******************************************************************************/\n\n// Very optimized memcpy() routine for all AMD Athlon and Duron family.\n// This code uses any of FOUR different basic copy methods, depending\n// on the transfer size.\n// NOTE:  Since this code uses MOVNTQ (also known as \"Non-Temporal MOV\" or\n// \"Streaming Store\"), and also uses the software prefetchnta instructions,\n// be sure you're running on Athlon/Duron or other recent CPU before calling!\n\n#define TINY_BLOCK_COPY 64       // upper limit for movsd type copy\n// The smallest copy uses the X86 \"movsd\" instruction, in an optimized\n// form which is an \"unrolled loop\".\n\n#define IN_CACHE_COPY 64 * 1024  // upper limit for movq/movq copy w/SW prefetch\n// Next is a copy that uses the MMX registers to copy 8 bytes at a time,\n// also using the \"unrolled loop\" optimization.   This code uses\n// the software prefetch instruction to get the data into the cache.\n\n#define UNCACHED_COPY 197 * 1024 // upper limit for movq/movntq w/SW prefetch\n// For larger blocks, which will spill beyond the cache, it's faster to\n// use the Streaming Store instruction MOVNTQ.   This write instruction\n// bypasses the cache and writes straight to main memory.  This code also\n// uses the software prefetch instruction to pre-read the data.\n// USE 64 * 1024 FOR THIS VALUE IF YOU'RE ALWAYS FILLING A \"CLEAN CACHE\"\n\n#define BLOCK_PREFETCH_COPY  infinity // no limit for movq/movntq w/block prefetch\n#define CACHEBLOCK 80h // number of 64-byte blocks (cache lines) for block prefetch\n// For the largest size blocks, a special technique called Block Prefetch\n// can be used to accelerate the read operations.   Block Prefetch reads\n// one address per cache line, for a series of cache lines, in a short loop.\n// This is faster than using software prefetch.  The technique is great for\n// getting maximum read bandwidth, especially in DDR memory systems.\n\n// Inline assembly syntax for use with Visual C++\n\n#include <avs/config.h>\n\n#if defined(X86_32) && defined(MSVC_PURE)\nvoid memcpy_amd(void *dest, const void *src, size_t n)\n{\n  // Warning! : If you modify this routine, check the generated assembler to make sure\n  //            the stupid compiler is saving the ebx register in the entry prologue.\n  //            And don't just add an extra push/pop ebx pair around the code, try to\n  //            convince the compiler to do the right thing, it's not hard, usually a\n  //            slight shuffle or a well placed \"__asm mov ebx,ebx\" does the trick.\n\n  __asm {\n\n\tmov\t\tecx, [n]\t\t; number of bytes to copy\n\tmov\t\tedi, [dest]\t\t; destination\n\tmov\t\tesi, [src]\t\t; source\n\tmov\t\tebx, ecx\t\t; keep a copy of count\n\n\tcld\n\tcmp\t\tecx, TINY_BLOCK_COPY\n\tjb\t\t$memcpy_ic_3\t; tiny? skip mmx copy\n\n\tcmp\t\tecx, 32*1024\t\t; // don't align between 32k-64k because\n\tjbe\t\t$memcpy_do_align\t;  it appears to be slower\n\tcmp\t\tecx, 64*1024\n\tjbe\t\t$memcpy_align_done\n$memcpy_do_align:\n\tmov\t\tecx, 8\t\t\t; // a trick that's faster than rep movsb...\n\tsub\t\tecx, edi\t\t; align destination to qword\n\tand\t\tecx, 111b\t\t; get the low bits\n\tsub\t\tebx, ecx\t\t; update copy count\n\tneg\t\tecx\t\t\t\t; set up to jump into the array\n\tadd\t\tecx, offset $memcpy_align_done\n\tjmp\t\tecx\t\t\t\t; // jump to array of movsb's\n\nalign 4\n\tmovsb\n\tmovsb\n\tmovsb\n\tmovsb\n\tmovsb\n\tmovsb\n\tmovsb\n\tmovsb\n\n$memcpy_align_done:\t\t\t; destination is dword aligned\n\tmov\t\tecx, ebx\t\t; number of bytes left to copy\n\tshr\t\tecx, 6\t\t\t; get 64-byte block count\n\tjz\t\t$memcpy_ic_2\t; finish the last few bytes\n\n\tcmp\t\tecx, IN_CACHE_COPY/64\t; too big 4 cache? use uncached copy\n\tjae\t\t$memcpy_uc_test\n\n// This is small block copy that uses the MMX registers to copy 8 bytes\n// at a time.  It uses the \"unrolled loop\" optimization, and also uses\n// the software prefetch instruction to get the data into the cache.\nalign 16\n$memcpy_ic_1:\t\t\t; 64-byte block copies, in-cache copy\n\n\tprefetchnta [esi + (200*64/34+192)]\t\t; start reading ahead\n\n\tmovq\tmm0, [esi+0]\t; read 64 bits\n\tmovq\tmm1, [esi+8]\n\tmovq\t[edi+0], mm0\t; write 64 bits\n\tmovq\t[edi+8], mm1\t;    note:  the normal movq writes the\n\tmovq\tmm2, [esi+16]\t;    data to cache; a cache line will be\n\tmovq\tmm3, [esi+24]\t;    allocated as needed, to store the data\n\tmovq\t[edi+16], mm2\n\tmovq\t[edi+24], mm3\n\tmovq\tmm0, [esi+32]\n\tmovq\tmm1, [esi+40]\n\tmovq\t[edi+32], mm0\n\tmovq\t[edi+40], mm1\n\tmovq\tmm2, [esi+48]\n\tmovq\tmm3, [esi+56]\n\tmovq\t[edi+48], mm2\n\tmovq\t[edi+56], mm3\n\n\tadd\t\tesi, 64\t\t\t; update source pointer\n\tadd\t\tedi, 64\t\t\t; update destination pointer\n\tdec\t\tecx\t\t\t\t; count down\n\tjnz\t\t$memcpy_ic_1\t; last 64-byte block?\n\n$memcpy_ic_2:\n\tmov\t\tecx, ebx\t\t; has valid low 6 bits of the byte count\n$memcpy_ic_3:\n\tshr\t\tecx, 2\t\t\t; dword count\n\tand\t\tecx, 1111b\t\t; only look at the \"remainder\" bits\n\tneg\t\tecx\t\t\t\t; set up to jump into the array\n\tadd\t\tecx, offset $memcpy_last_few\n\tjmp\t\tecx\t\t\t\t; // jump to array of movsd's\n\n$memcpy_uc_test:\n\tcmp\t\tecx, UNCACHED_COPY/64\t; big enough? use block prefetch copy\n\tjae\t\t$memcpy_bp_1\n\n$memcpy_64_test:\n\tor\t\tecx, ecx\t\t; tail end of block prefetch will jump here\n\tjz\t\t$memcpy_ic_2\t; no more 64-byte blocks left\n\n// For larger blocks, which will spill beyond the cache, it's faster to\n// use the Streaming Store instruction MOVNTQ.   This write instruction\n// bypasses the cache and writes straight to main memory.  This code also\n// uses the software prefetch instruction to pre-read the data.\nalign 16\n$memcpy_uc_1:\t\t\t\t; 64-byte blocks, uncached copy\n\n\tprefetchnta [esi + (200*64/34+192)]\t\t; start reading ahead\n\n\tmovq\tmm0,[esi+0]\t\t; read 64 bits\n\tadd\t\tedi,64\t\t\t; update destination pointer\n\tmovq\tmm1,[esi+8]\n\tadd\t\tesi,64\t\t\t; update source pointer\n\tmovq\tmm2,[esi-48]\n\tmovntq\t[edi-64], mm0\t; write 64 bits, bypassing the cache\n\tmovq\tmm0,[esi-40]\t;    note: movntq also prevents the CPU\n\tmovntq\t[edi-56], mm1\t;    from READING the destination address\n\tmovq\tmm1,[esi-32]\t;    into the cache, only to be over-written\n\tmovntq\t[edi-48], mm2\t;    so that also helps performance\n\tmovq\tmm2,[esi-24]\n\tmovntq\t[edi-40], mm0\n\tmovq\tmm0,[esi-16]\n\tmovntq\t[edi-32], mm1\n\tmovq\tmm1,[esi-8]\n\tmovntq\t[edi-24], mm2\n\tmovntq\t[edi-16], mm0\n\tdec\t\tecx\n\tmovntq\t[edi-8], mm1\n\tjnz\t\t$memcpy_uc_1\t; last 64-byte block?\n\n\tjmp\t\t$memcpy_ic_2\t\t; almost done\n\n// For the largest size blocks, a special technique called Block Prefetch\n// can be used to accelerate the read operations.   Block Prefetch reads\n// one address per cache line, for a series of cache lines, in a short loop.\n// This is faster than using software prefetch, in this case.\n// The technique is great for getting maximum read bandwidth,\n// especially in DDR memory systems.\n$memcpy_bp_1:\t\t\t; large blocks, block prefetch copy\n\n\tcmp\t\tecx, CACHEBLOCK\t\t\t; big enough to run another prefetch loop?\n\tjl\t\t$memcpy_64_test\t\t\t; no, back to regular uncached copy\n\n\tmov\t\teax, CACHEBLOCK / 2\t\t; block prefetch loop, unrolled 2X\n\tadd\t\tesi, CACHEBLOCK * 64\t; move to the top of the block\nalign 16\n$memcpy_bp_2:\n\tmov\t\tedx, [esi-64]\t\t; grab one address per cache line\n\tmov\t\tedx, [esi-128]\t\t; grab one address per cache line\n\tsub\t\tesi, 128\t\t\t; go reverse order\n\tdec\t\teax\t\t\t\t\t; count down the cache lines\n\tjnz\t\t$memcpy_bp_2\t\t; keep grabbing more lines into cache\n\n\tmov\t\teax, CACHEBLOCK\t\t; // now that it's in cache, do the copy\nalign 16\n$memcpy_bp_3:\n\tmovq\tmm0, [esi   ]\t\t; read 64 bits\n\tmovq\tmm1, [esi+ 8]\n\tmovq\tmm2, [esi+16]\n\tmovq\tmm3, [esi+24]\n\tmovq\tmm4, [esi+32]\n\tmovq\tmm5, [esi+40]\n\tmovq\tmm6, [esi+48]\n\tmovq\tmm7, [esi+56]\n\tadd\t\tesi, 64\t\t\t\t; update source pointer\n\tmovntq\t[edi   ], mm0\t\t; write 64 bits, bypassing cache\n\tmovntq\t[edi+ 8], mm1\t\t;    note: movntq also prevents the CPU\n\tmovntq\t[edi+16], mm2\t\t;    from READING the destination address\n\tmovntq\t[edi+24], mm3\t\t;    into the cache, only to be over-written,\n\tmovntq\t[edi+32], mm4\t\t;    so that also helps performance\n\tmovntq\t[edi+40], mm5\n\tmovntq\t[edi+48], mm6\n\tmovntq\t[edi+56], mm7\n\tadd\t\tedi, 64\t\t\t\t; update dest pointer\n\n\tdec\t\teax\t\t\t\t\t; count down\n\n\tjnz\t\t$memcpy_bp_3\t\t; keep copying\n\tsub\t\tecx, CACHEBLOCK\t\t; update the 64-byte block count\n\tjmp\t\t$memcpy_bp_1\t\t; keep processing chunks\n\n// The smallest copy uses the X86 \"movsd\" instruction, in an optimized\n// form which is an \"unrolled loop\".   Then it handles the last few bytes.\nalign 4\n\tmovsd\n\tmovsd\t\t\t; perform last 1-15 dword copies\n\tmovsd\n\tmovsd\n\tmovsd\n\tmovsd\n\tmovsd\n\tmovsd\n\tmovsd\n\tmovsd\t\t\t; perform last 1-7 dword copies\n\tmovsd\n\tmovsd\n\tmovsd\n\tmovsd\n\tmovsd\n\tmovsd\n\n$memcpy_last_few:\t\t; // dword aligned from before movsd's\n\tmov\t\tecx, ebx\t; has valid low 2 bits of the byte count\n\tand\t\tecx, 11b\t; the last few cows must come home\n\tjz\t\t$memcpy_final\t; // no more, let's leave\n\trep\t\tmovsb\t\t; the last 1, 2, or 3 bytes\n\n$memcpy_final:\n\temms\t\t\t\t; clean up the MMX state\n\tsfence\t\t\t\t; flush the write buffer\n\tmov\t\teax, [dest]\t; ret value = destination pointer\n\n    }\n}\n#endif\n"
  },
  {
    "path": "avs_core/core/memcpy_amd.h",
    "content": "/******************************************************************************\n\n Copyright (c) 2001 Advanced Micro Devices, Inc.\n\n LIMITATION OF LIABILITY:  THE MATERIALS ARE PROVIDED *AS IS* WITHOUT ANY\n EXPRESS OR IMPLIED WARRANTY OF ANY KIND INCLUDING WARRANTIES OF MERCHANTABILITY,\n NONINFRINGEMENT OF THIRD-PARTY INTELLECTUAL PROPERTY, OR FITNESS FOR ANY\n PARTICULAR PURPOSE.  IN NO EVENT SHALL AMD OR ITS SUPPLIERS BE LIABLE FOR ANY\n DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS,\n BUSINESS INTERRUPTION, LOSS OF INFORMATION) ARISING OUT OF THE USE OF OR\n INABILITY TO USE THE MATERIALS, EVEN IF AMD HAS BEEN ADVISED OF THE POSSIBILITY\n OF SUCH DAMAGES.  BECAUSE SOME JURISDICTIONS PROHIBIT THE EXCLUSION OR LIMITATION\n OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE LIMITATION MAY\n NOT APPLY TO YOU.\n\n AMD does not assume any responsibility for any errors which may appear in the\n Materials nor any responsibility to support or update the Materials.  AMD retains\n the right to make changes to its test specifications at any time, without notice.\n\n NO SUPPORT OBLIGATION: AMD is not obligated to furnish, support, or make any\n further information, software, technical information, know-how, or show-how\n available to you.\n\n So that all may benefit from your experience, please report  any  problems\n or  suggestions about this software to 3dsdk.support@amd.com\n\n AMD Developer Technologies, M/S 585\n Advanced Micro Devices, Inc.\n 5900 E. Ben White Blvd.\n Austin, TX 78741\n 3dsdk.support@amd.com\n******************************************************************************/\n\n/*****************************************************************************\nMEMCPY_AMD.CPP\n******************************************************************************/\n\n// Very optimized memcpy() routine for all AMD Athlon and Duron family.\n// This code uses any of FOUR different basic copy methods, depending\n// on the transfer size.\n// NOTE:  Since this code uses MOVNTQ (also known as \"Non-Temporal MOV\" or\n// \"Streaming Store\"), and also uses the software prefetchnta instructions,\n// be sure you're running on Athlon/Duron or other recent CPU before calling!\n\n#ifndef AVSCORE_MEMCPY_AMD\n#define AVSCORE_MEMCPY_AMD\n\n#include <stddef.h>\n\nvoid memcpy_amd(void *dest, const void *src, size_t n);\n\n#endif // AVSCORE_MEMCPY_AMD"
  },
  {
    "path": "avs_core/core/mpmc_bounded_queue.h",
    "content": "#include <vector>\n\ntemplate <typename T>\nclass circular_buffer\n{\npublic:\n\n  typedef size_t size_type;\n  typedef T value_type;\n\nprivate:\n  std::vector<T>  array;\n  const size_type max_size;\n  size_type head;\n  size_type tail;\n  size_type size;\n\npublic:\n\n  circular_buffer(size_type capacity) :\n    array(capacity),\n    max_size(capacity),\n    head(0),\n    tail(0),\n    size(0)\n  {\n  }\n\n  bool empty() const\n  {\n    return size == 0;\n  }\n\n  bool full() const\n  {\n    assert(size <= max_size);\n    return size == max_size;\n  }\n\n  bool push_front(T&& item)\n  {\n    if (full())\n      return false;\n\n    array[head] = std::move(item);\n    head = (head + 1) % max_size;\n    ++size;\n\n    return true;\n  }\n\n  bool pop_back(T* pItem)\n  {\n    if (empty())\n      return false;\n\n    *pItem = std::move(array[tail]);\n    tail = (tail + 1) % max_size;\n    --size;\n\n    return true;\n  }\n\n  size_type capacity() const\n  {\n    return max_size;\n  }\n};\n\n#include <mutex>\n#include <condition_variable>\n\ntemplate <typename T>\nclass mpmc_bounded_queue\n{\npublic:\n  typedef circular_buffer<T> container_type;\n  typedef typename container_type::size_type size_type;\n  typedef typename container_type::value_type value_type;\n\nprivate:\n  mpmc_bounded_queue(const mpmc_bounded_queue&);              // Disabled copy constructor\n  mpmc_bounded_queue& operator = (const mpmc_bounded_queue&); // Disabled assign operator\n\n  container_type m_container;\n  std::mutex m_mutex;\n  std::condition_variable m_not_empty;\n  std::condition_variable m_not_full;\n\tbool finished;\n\npublic:\n  mpmc_bounded_queue(size_type capacity) :\n    m_container(capacity),\n\t\tfinished(false)\n  {\n  }\n\n  size_type capacity() const\n  {\n    return m_container.capacity();\n  }\n\n\tvoid finish()\n\t{\n    std::unique_lock<std::mutex> lock(m_mutex);\n    if (finished == false) {\n      finished = true;\n      m_not_full.notify_all();\n      m_not_empty.notify_all();\n    }\n\t}\n\n\tbool is_finished()\n\t{\n    std::unique_lock<std::mutex> lock(m_mutex);\n\t\treturn finished;\n\t}\n\n  bool push_front(T&& item)\n  {\n    std::unique_lock<std::mutex> lock(m_mutex);\n\t\tif (finished) {\n      return false;\n\t\t}\n    while(m_container.full())\n    {\n      m_not_full.wait(lock);\n      if (finished) {\n        return false;\n      }\n    }\n    m_container.push_front(std::move(item));\n    lock.unlock();\n    m_not_empty.notify_one();\n    return true;\n  }\n\n  bool pop_back(value_type* pItem)\n  {\n    std::unique_lock<std::mutex> lock(m_mutex);\n    if (finished) {\n      return false;\n    }\n    while(m_container.empty())\n    {\n      m_not_empty.wait(lock);\n      if (finished) {\n        return false;\n      }\n    }\n    m_container.pop_back(pItem);\n    lock.unlock();\n    m_not_full.notify_one();\n    return true;\n  }\n\n\tbool pop_remain(value_type* pItem)\n\t{\n\t\tassert(finished);\n\t\tif (m_container.empty()) return false;\n\t\tm_container.pop_back(pItem);\n\t\treturn true;\n\t}\n};\n"
  },
  {
    "path": "avs_core/core/parser/expression.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include \"expression.h\"\n#include \"script.h\"\n#include \"../exception.h\"\n#include \"../internal.h\"\n#include \"../InternalEnvironment.h\"\n#ifdef AVS_WINDOWS\n#include <avs/win.h>\n#else\n#include <avs/posix.h>\n#endif\n#include <cassert>\n#include <vector>\n\n\nclass BreakStmtException\n{\n};\n\nclass ContinueStmtException\n{\n};\n\nAVSValue ExpRootBlock::Evaluate(IScriptEnvironment* env)\n{\n  AVSValue retval;\n\n  try {\n    retval = exp->Evaluate(env);\n  }\n  catch (const ReturnExprException &e) {\n    retval = e.value;\n  }\n\n  return retval;\n}\n\nAVSValue ExpSequence::Evaluate(IScriptEnvironment* env)\n{\n    AVSValue last = a->Evaluate(env);\n    if (last.IsClip()) env->SetVar(\"last\", last);\n    return b->Evaluate(env);\n}\n\nAVSValue ExpExceptionTranslator::Evaluate(IScriptEnvironment* env)\n{\n  try {\n    SehGuard seh_guard;\n    return exp->Evaluate(env);\n  }\n  catch (const IScriptEnvironment::NotFound&) {\n    throw;\n  }\n  catch (const AvisynthError&) {\n    throw;\n  }\n  catch (const BreakStmtException&) {\n    throw;\n  }\n  catch (const ContinueStmtException&) {\n    throw;\n  }\n  catch (const ReturnExprException&) {\n    throw;\n  }\n  catch (const SehException &seh) {\n    if (seh.m_msg)\n      env->ThrowError(seh.m_msg);\n    else\n      env->ThrowError(\"Evaluate: System exception - 0x%x\", seh.m_code);\n  }\n  catch (...) {\n    env->ThrowError(\"Evaluate: Unhandled C++ exception!\");\n  }\n  return 0;\n}\n\n\nAVSValue ExpTryCatch::Evaluate(IScriptEnvironment* env)\n{\n  AVSValue result;\n  try {\n    return ExpExceptionTranslator::Evaluate(env);\n  }\n  catch (const AvisynthError &ae) {\n    env->SetVar(id, ae.msg);\n    return catch_block->Evaluate(env);\n  }\n}\n\n\nAVSValue ExpLine::Evaluate(IScriptEnvironment* env)\n{\n  try {\n    return ExpExceptionTranslator::Evaluate(env);\n  }\n  catch (const AvisynthError &ae) {\n    env->ThrowError(\"%s\\n(%s, line %d)\", ae.msg, filename, line);\n  }\n  return 0;\n}\n\nAVSValue ExpBlockConditional::Evaluate(IScriptEnvironment* env)\n{\n  AVSValue result;\n  env->GetVarTry(\"last\", &result);\n\n  AVSValue cond = If->Evaluate(env);\n  if (!cond.IsBool())\n    env->ThrowError(\"if: condition must be boolean (true/false)\");\n  if (cond.AsBool())\n  {\n    if (Then) // note: \"Then\" can also be NULL if its block is empty\n      result = Then->Evaluate(env);\n  }\n  else if (Else) // note: \"Else\" can also be NULL if its block is empty\n    result = Else->Evaluate(env);\n\n  if (result.IsClip())\n    env->SetVar(\"last\", result);\n\n  return result;\n}\n\nAVSValue ExpWhileLoop::Evaluate(IScriptEnvironment* env)\n{\n  AVSValue result;\n  env->GetVarTry(\"last\", &result);\n\n  AVSValue cond;\n  do {\n    cond = condition->Evaluate(env);\n    if (!cond.IsBool())\n      env->ThrowError(\"while: condition must be boolean (true/false)\");\n\n    if (!cond.AsBool())\n      break;\n\n    if (body)\n    {\n      try\n      {\n        result = body->Evaluate(env);\n        if (result.IsClip())\n          env->SetVar(\"last\", result);\n      }\n      catch(const BreakStmtException&)\n      {\n        AVSValue result2;\n        env->GetVarTry(\"last\", &result2);\n        if (result2.IsClip())\n          result = result2;\n        break;\n      }\n      catch (const ContinueStmtException&)\n      {\n        AVSValue result2;\n        env->GetVarTry(\"last\", &result2);\n        if (result2.IsClip())\n          result = result2;\n      }\n    }\n  }\n  while (true);\n\n  return result;\n}\n\nAVSValue ExpForLoop::Evaluate(IScriptEnvironment* env)\n{\n  const AVSValue initVal = init->Evaluate(env),\n                 limitVal = limit->Evaluate(env),\n                 stepVal = step->Evaluate(env);\n\n  if (!initVal.IsInt())\n    env->ThrowError(\"for: initial value must be int\");\n  if (!limitVal.IsInt())\n    env->ThrowError(\"for: final value must be int\");\n  if (!stepVal.IsInt())\n    env->ThrowError(\"for: step value must be int\");\n  if (stepVal.AsLong() == 0)\n    env->ThrowError(\"for: step value must be non-zero\");\n\n  const int64_t iLimit = limitVal.AsLong();\n  const int64_t iStep = stepVal.AsLong();\n  int64_t i = initVal.AsLong();\n\n  AVSValue result;\n  env->GetVarTry(\"last\", &result);\n\n  env->SetVar(id, initVal);\n  while (iStep > 0 ? i <= iLimit : i >= iLimit)\n  {\n    if (body)\n    {\n      try\n      {\n        result = body->Evaluate(env);\n        if (result.IsClip())\n          env->SetVar(\"last\", result);\n      }\n      catch(const BreakStmtException&)\n      {\n        AVSValue result2;\n        env->GetVarTry(\"last\", &result2);\n        if (result2.IsClip())\n          result = result2;\n        break;\n      }\n      catch (const ContinueStmtException&)\n      {\n        AVSValue result2;\n        env->GetVarTry(\"last\", &result2);\n        if (result2.IsClip())\n          result = result2;\n      }\n    }\n\n    AVSValue idVal = env->GetVar(id); // may have been updated in body\n    if (!idVal.IsInt())\n      env->ThrowError(\"for: loop variable '%s' has been assigned a non-int value\", id);\n    i = idVal.AsLong() + iStep;\n    // store back to smaller type\n    if (i >= INT_MIN && i <= INT_MAX)\n      env->SetVar(id, (int)i);\n    else\n      env->SetVar(id, i);\n  }\n  return result;  // overall result is that of final body evaluation (if any)\n}\n\nAVSValue ExpBreak::Evaluate(IScriptEnvironment* env)\n{\n  throw BreakStmtException();\n}\n\nAVSValue ExpContinue::Evaluate(IScriptEnvironment* env)\n{\n  throw ContinueStmtException();\n}\n\nAVSValue ExpConditional::Evaluate(IScriptEnvironment* env)\n{\n  AVSValue cond = If->Evaluate(env);\n  if (!cond.IsBool())\n    env->ThrowError(\"Evaluate: left of `?' must be boolean (true/false)\");\n  return (cond.AsBool() ? Then : Else)->Evaluate(env);\n}\n\nAVSValue ExpReturn::Evaluate(IScriptEnvironment* env)\n{\n  ReturnExprException ret;\n  ret.value = value->Evaluate(env);\n  throw ret;\n}\n\n\n\n/**** Operators ****/\n\nAVSValue ExpOr::Evaluate(IScriptEnvironment* env)\n{\n  AVSValue x = a->Evaluate(env);\n  if (!x.IsBool())\n    env->ThrowError(\"Evaluate: left operand of || must be boolean (true/false)\");\n  if (x.AsBool())\n    return x;\n  AVSValue y = b->Evaluate(env);\n  if (!y.IsBool())\n    env->ThrowError(\"Evaluate: right operand of || must be boolean (true/false)\");\n  return y;\n}\n\n\nAVSValue ExpAnd::Evaluate(IScriptEnvironment* env)\n{\n  AVSValue x = a->Evaluate(env);\n  if (!x.IsBool())\n    env->ThrowError(\"Evaluate: left operand of && must be boolean (true/false)\");\n  if (!x.AsBool())\n    return x;\n  AVSValue y = b->Evaluate(env);\n  if (!y.IsBool())\n    env->ThrowError(\"Evaluate: right operand of && must be boolean (true/false)\");\n  return y;\n}\n\n\nAVSValue ExpEqual::Evaluate(IScriptEnvironment* env)\n{\n  AVSValue x = a->Evaluate(env);\n  AVSValue y = b->Evaluate(env);\n  if (x.IsBool() && y.IsBool()) {\n    return x.AsBool() == y.AsBool();\n  }\n  else if (x.IsInt() && y.IsInt()) { // true for any 32/64 bit data\n    return x.AsLong() == y.AsLong(); // work with 64 bits\n  }\n  else if (x.IsFloatfStrict() && y.IsFloatfStrict()) {\n    return x.AsFloatf() == y.AsFloatf();\n  }\n  else if (x.IsFloat() && y.IsFloat()) {\n    return x.AsFloat() == y.AsFloat(); // AsFloat returns double\n  }\n  else if (x.IsClip() && y.IsClip()) {\n    return x.AsClip() == y.AsClip();\n  }\n  else if (x.IsString() && y.IsString()) {\n    return !lstrcmpi(x.AsString(), y.AsString());\n  }\n  else if (x.IsFunction() && y.IsFunction()) {\n    return x.AsFunction() == y.AsFunction();\n  }\n  else {\n    env->ThrowError(\"Evaluate: operands of `==' and `!=' must be comparable\");\n    return 0;\n  }\n}\n\n\nAVSValue ExpLess::Evaluate(IScriptEnvironment* env)\n{\n  AVSValue x = a->Evaluate(env);\n  AVSValue y = b->Evaluate(env);\n  if (x.IsInt() && y.IsInt()) { // true for any 32/64 bit data\n    return x.AsLong() < y.AsLong(); // work with 64 bits\n  }\n  else if (x.IsFloatfStrict() && y.IsFloatfStrict()) {\n    return x.AsFloatf() < y.AsFloatf();\n  }\n  else if (x.IsFloat() && y.IsFloat()) {\n    return x.AsFloat() < y.AsFloat();\n  }\n  else if (x.IsString() && y.IsString()) {\n    return _stricmp(x.AsString(),y.AsString()) < 0 ? true : false;\n  }\n  else {\n    env->ThrowError(\"Evaluate: operands of `<' and friends must be string or numeric\");\n    return 0;\n  }\n}\n\nAVSValue ExpPlus::Evaluate(IScriptEnvironment* env)\n{\n  AVSValue x = a->Evaluate(env);\n  AVSValue y = b->Evaluate(env);\n  if (x.IsClip() && y.IsClip()) {\n    AVSValue arg[3] = { x, y, 0 };\n    return env->Invoke(\"UnalignedSplice\", AVSValue(arg, 3));\n  }\n  else if (x.IsInt() && y.IsInt()) { // they are true for any 32/64 bits inside\n    int64_t result = x.AsLong() + y.AsLong();\n    // keep the smaller type\n    if (result >= INT_MIN && result <= INT_MAX)\n      return (int)result;\n    return result;\n  }\n  else if (x.IsFloatfStrict() && y.IsFloatfStrict())\n    return x.AsFloatf() + y.AsFloatf();\n  else if (x.IsFloat() && y.IsFloat())\n    return x.AsFloat() + y.AsFloat(); // AsFloat returns double\n  else if (x.IsString() && y.IsString())\n    return env->Sprintf(\"%s%s\", x.AsString(), y.AsString());\n  else {\n    env->ThrowError(\"Evaluate: operands of `+' must both be numbers, strings, or clips\");\n    return 0;\n  }\n}\n\n\nAVSValue ExpDoublePlus::Evaluate(IScriptEnvironment* env)\n{\n  AVSValue x = a->Evaluate(env);\n  AVSValue y = b->Evaluate(env);\n if (x.IsClip() && y.IsClip()) {\n    AVSValue arg[3] = { x, y, 0 };\n    return env->Invoke(\"AlignedSplice\", AVSValue(arg, 3));\n  }\n  else {\n    env->ThrowError(\"Evaluate: operands of `++' must be clips\");\n    return 0;\n  }\n}\n\n\nAVSValue ExpMinus::Evaluate(IScriptEnvironment* env)\n{\n  AVSValue x = a->Evaluate(env);\n  AVSValue y = b->Evaluate(env);\n  if (x.IsInt() && y.IsInt()) { // they are true for any 32/64 bits inside\n    int64_t result = x.AsLong() - y.AsLong();\n    // keep the smaller type\n    if (result >= INT_MIN && result <= INT_MAX)\n      return (int)result;\n    return result;\n  }\n  else if (x.IsFloatfStrict() && y.IsFloatfStrict())\n    return x.AsFloatf() - y.AsFloatf();\n  else if (x.IsFloat() && y.IsFloat())\n    return x.AsFloat() - y.AsFloat(); // AsFloat returns double\n  else {\n    env->ThrowError(\"Evaluate: operands of `-' must be numeric\");\n    return 0;\n  }\n}\n\n\nAVSValue ExpMult::Evaluate(IScriptEnvironment* env)\n{\n  AVSValue x = a->Evaluate(env);\n  AVSValue y = b->Evaluate(env);\n  if (x.IsInt() && y.IsInt()) { // they are true for any 32/64 bits inside\n    int64_t result = x.AsLong() * y.AsLong();\n    // keep the smaller type\n    if (result >= INT_MIN && result <= INT_MAX)\n      return (int)result;\n    return result;\n  }\n  else if (x.IsFloatfStrict() && y.IsFloatfStrict())\n    return x.AsFloatf() * y.AsFloatf();\n  else if (x.IsFloat() && y.IsFloat())\n    return x.AsFloat() * y.AsFloat(); // AsFloat returns double\n  else {\n    env->ThrowError(\"Evaluate: operands of `*' must be numeric\");\n    return 0;\n  }\n}\n\n\nAVSValue ExpDiv::Evaluate(IScriptEnvironment* env)\n{\n  AVSValue x = a->Evaluate(env);\n  AVSValue y = b->Evaluate(env);\n  if (x.IsInt() && y.IsInt()) { // they are true for any 32/64 bits inside\n    if (y.AsLong() == 0)\n      env->ThrowError(\"Evaluate: division by zero\");\n    int64_t result = x.AsLong() / y.AsLong();\n    // keep the smaller type\n    if (result >= INT_MIN && result <= INT_MAX)\n      return (int)result;\n    return result;\n  }\n  else if (x.IsFloatfStrict() && y.IsFloatfStrict())\n    return x.AsFloatf() / y.AsFloatf();\n  else if (x.IsFloat() && y.IsFloat())\n    return x.AsFloat() / y.AsFloat(); // AsFloat returns double\n  else {\n    env->ThrowError(\"Evaluate: operands of `/' must be numeric\");\n    return 0;\n  }\n}\n\n\nAVSValue ExpMod::Evaluate(IScriptEnvironment* env)\n{\n  AVSValue x = a->Evaluate(env);\n  AVSValue y = b->Evaluate(env);\n  if (x.IsInt() && y.IsInt()) { // they are true for any 32/64 bits inside\n    if (y.AsLong() == 0)\n      env->ThrowError(\"Evaluate: division by zero\");\n    int64_t result = x.AsLong() % y.AsLong();\n    // keep the smaller type\n    if (result >= INT_MIN && result <= INT_MAX)\n      return (int)result;\n    return result;\n  }\n  else {\n    env->ThrowError(\"Evaluate: operands of `%%' must be integers\");\n    return 0;\n  }\n}\n\n\nAVSValue ExpNegate::Evaluate(IScriptEnvironment* env)\n{\n  AVSValue x = e->Evaluate(env);\n  if (x.IsInt()) { // true for any 32/64 bits inside\n    // Note: In the old 32-bit integer case, the special value -(INT_MIN) resulted in a negative value\n    // instead of a positive number.\n    // This change in version 11 is not 100% compatible with the old behavior.\n    int64_t result = -x.AsLong();\n    // keep the smaller type\n    if (result >= INT_MIN && result <= INT_MAX)\n      return (int)result;\n    return result;\n  }\n  else if (x.IsFloatfStrict())\n    return -x.AsFloatf();\n  else if (x.IsFloat())\n    return -x.AsFloat(); // AsFloat returns double\n  else {\n    env->ThrowError(\"Evaluate: unary minus can only by used with numbers\");\n    return 0;\n  }\n}\n\n\nAVSValue ExpNot::Evaluate(IScriptEnvironment* env)\n{\n  AVSValue x = e->Evaluate(env);\n  if (x.IsBool())\n    return !x.AsBool();\n  else {\n    env->ThrowError(\"Evaluate: operand of `!' must be boolean (true/false)\");\n    return 0;\n  }\n}\n\n\nAVSValue ExpVariableReference::Evaluate(IScriptEnvironment* env)\n{\n  AVSValue result;\n\n  // first look for a genuine variable\n  // Don't add a cache to this one, it's a Var\n  if (env->GetVarTry(name, &result)) {\n    return result;\n  }\n  else {\n    // Swap order to match ::Call below -- Gavino Jan 2010\n\n    // next look for an argless function\n    if (!env->InvokeTry(&result, name, AVSValue(0,0)))\n    {\n      // finally look for a single-arg function taking implicit \"last\"\n      AVSValue last;\n      if (!env->GetVarTry(\"last\", &last) || !env->InvokeTry(&result, name, last))\n      {\n        // and we are giving a last chance, the variable may exist here after the avsi autoload mechanism\n        if (env->GetVarTry(name, &result)) {\n          return result;\n        }\n        env->ThrowError(\"I don't know what '%s' means.\", name);\n        return 0;\n      }\n    }\n  }\n\n  return result;\n}\n\n\nAVSValue ExpAssignment::Evaluate(IScriptEnvironment* env)\n{\n  env->SetVar(lhs, rhs->Evaluate(env));\n  if (withret) {\n    AVSValue last;\n    AVSValue result;\n\n    if (!env->GetVarTry(\"last\", &last) || !env->InvokeTry(&result, lhs, last))\n    {\n      // and we are giving a last chance, the variable may exist here after the avsi autoload mechanism\n      if (env->GetVarTry(lhs, &result)) {\n        return result;\n      }\n      env->ThrowError(\"I don't know what '%s' means.\", lhs);\n      return 0;\n    }\n  }\n  return AVSValue();\n}\n\n\nAVSValue ExpGlobalAssignment::Evaluate(IScriptEnvironment* env)\n{\n  env->SetGlobalVar(lhs, rhs->Evaluate(env));\n  return AVSValue();\n}\n\n\nExpFunctionCall::ExpFunctionCall( const char* _name, const PExpression& _func, PExpression* _arg_exprs,\n                   const char** _arg_expr_names, int _arg_expr_count, bool _oop_notation )\n  : name(_name), func(_func), arg_expr_count(_arg_expr_count), oop_notation(_oop_notation)\n{\n  arg_exprs = new PExpression[arg_expr_count];\n  arg_expr_names = new const char*[arg_expr_count];\n  for (int i=0; i<arg_expr_count; ++i) {\n    arg_exprs[i] = _arg_exprs[i];\n    arg_expr_names[i] = _arg_expr_names[i];\n  }\n}\n\nExpFunctionCall::~ExpFunctionCall(void)\n{\n  delete[] arg_exprs;\n  delete[] arg_expr_names;\n}\n\nAVSValue ExpFunctionCall::Evaluate(IScriptEnvironment* env)\n{\n  AVSValue result;\n  InternalEnvironment *env2 = static_cast<InternalEnvironment*>(env);\n\n  const char* real_name = name;\n  const Function* real_func = nullptr;\n  AVSValue eval_result; // function must be exist until the function call ends\n  if (real_name == nullptr) {\n    // if name is not given, evaluate expression to get the function\n    eval_result = func->Evaluate(env);\n    if (!eval_result.IsFunction()) {\n        env->ThrowError(\n          \"Script error: '%s' cannot be called. Give me a function!\",\n        GetAVSTypeName(eval_result));\n    }\n    //auto& func = eval_result.AsFunction(); // c++ strict conformance: cannot Convert PFunction to PFunction&\n    const PFunction& func = eval_result.AsFunction();\n    real_name = func->GetLegacyName();\n    real_func = func->GetDefinition();\n  }\n\n  assert(real_name || real_func);\n\n  // Keep an entry at the beginning: 0th is implicite_last\n  std::vector<AVSValue> args(arg_expr_count+1, AVSValue());\n  for (int a = 0; a < arg_expr_count; ++a)\n    args[a + 1] = arg_exprs[a]->Evaluate(env);\n\n  AVSValue implicit_last = oop_notation ? AVSValue() : env2->GetVarDef(\"last\");\n  args[0] = implicit_last;\n  bool notfound = false;\n  try\n  { // Invoke can always throw by calling a constructor of a filter that throws\n    // first give args with implicite_last as a separate parameter\n    // and w/o implicit_last in the args array\n    if (env2->Invoke_(&result, implicit_last,\n      real_name, real_func, AVSValue(args.data() + 1, arg_expr_count), arg_expr_names))\n      return result;\n  }\n  catch (const IScriptEnvironment::NotFound&) {\n    notfound = true;\n  }\n\n  if (notfound && implicit_last.IsClip())\n  {\n    // Give a final chance with a forced implicite last trial for functions like \"Animate\"\n    // which has with-clip and clipless function signatures.\n    // For cases when clipless signature is found but during instantiating a function\n    // inside its internal expression parameter fails to intantiate without a clip input\n    // and it turnes out that the signature with implicit_last would work.\n    try\n    {\n      std::vector<const char *> arg_expr_names2(arg_expr_count + 1);\n      for (int a = 0; a < arg_expr_count; ++a)\n        arg_expr_names2[a + 1] = arg_expr_names[a];\n      arg_expr_names2[0] = nullptr;\n      // with impicite_last inside the array\n      if (env2->Invoke_(&result, AVSValue(),\n        real_name, real_func, AVSValue(args.data(), arg_expr_count + 1), arg_expr_names2.data()))\n        return result;\n    }\n    catch (const IScriptEnvironment::NotFound&) {}\n  }\n\n  if (real_name == nullptr) {\n    // anonymous function\n    env->ThrowError(\"Script error: Invalid arguments to %s.\",\n      eval_result.AsFunction()->ToString(env));\n  }\n  else {\n    AVSValue var;\n    if (env->GetVarTry(real_name, &var) && var.IsFunction() && var.AsFunction()->GetLegacyName()) {\n      real_name = var.AsFunction()->GetLegacyName();\n    }\n    env->ThrowError(env->FunctionExists(real_name) ?\n      \"Script error: Invalid arguments to function '%s'.\" :\n      \"Script error: There is no function named '%s'.\", real_name);\n  }\n\n  assert(0);  // we should never get here\n  return 0;\n}\n\n\nclass WrappedFunction : public IFunction\n{\npublic:\n  WrappedFunction(const char* const name)\n    : name(name) { }\n  virtual const char* ToString(IScriptEnvironment* env) {\n    return env->Sprintf(\"Wrapped Function: %s\", name);\n  }\n  virtual const char* GetLegacyName() { return name; }\n  virtual const Function* GetDefinition() { return nullptr; }\n  virtual CaptureVars GetCaptures() { return CaptureVars(); }\n\nprivate:\n  const char* const name;\n};\n\nExpFunctionWrapper::ExpFunctionWrapper(const char* name)\n  : func(new WrappedFunction(name)), name(name) { }\n\nAVSValue ExpFunctionWrapper::Evaluate(IScriptEnvironment* env) {\n  AVSValue result;\n  if (env->GetVarTry(name, &result) && result.IsFunction()) {\n    // if reference variable exists, returns it\n    return result;\n  }\n  return func;\n}\n\n\nExpFunctionDefinition::ExpFunctionDefinition(\n  const PExpression& body,\n  const char* name, const char* param_types,\n  const bool* _param_floats, const char** _param_names, int param_count,\n  const char** _var_names, int var_count,\n  const char* filename, int line)\n  : body(body)\n  , name(name)\n  , param_types(param_types)\n  , param_floats(nullptr)\n  , param_names(nullptr)\n  , var_count(var_count)\n  , var_names(nullptr)\n  , filename(filename)\n  , line(line)\n{\n  param_floats = new bool[param_count];\n  memcpy(param_floats, _param_floats, param_count * sizeof(const bool));\n\n  param_names = new const char*[param_count];\n  memcpy(param_names, _param_names, param_count * sizeof(const char*));\n\n  if (var_count > 0) {\n    var_names = new const char*[var_count];\n    memcpy(var_names, _var_names, var_count * sizeof(const char*));\n  }\n}\n\nAVSValue ExpFunctionDefinition::Evaluate(IScriptEnvironment* env)\n{\n  AVSValue func = PFunction(new FunctionInstance(this, env));\n  if (name == nullptr) {\n    return func;\n  }\n  env->SetGlobalVar(name, func);\n  return AVSValue();\n}\n\n\n\nFunctionInstance::FunctionInstance(ExpFunctionDefinition* pdef, IScriptEnvironment* env)\n  : data(), pdef(pdef), pdef_ref(pdef), var_data(nullptr)\n{\n  data.apply = Execute_;\n\n  if (pdef->name) {\n    std::string cn(\"_\");\n    cn.append(pdef->name);\n    data.name = pdef->name;\n    data.canon_name = env->SaveString(cn.c_str());\n  }\n\n  data.param_types = pdef->param_types;\n  data.user_data = this;\n  data.dll_path = nullptr;\n\n  if (pdef->var_count > 0) {\n    AVSValue result;\n    var_data = new AVSValue[pdef->var_count];\n    for (int i = 0; i < pdef->var_count; ++i) {\n      if (!env->GetVarTry(pdef->var_names[i], &result)) {\n        env->ThrowError(\"No variable named '%s'\", pdef->var_names[i]);\n      }\n      var_data[i] = result;\n    }\n  }\n}\nFunctionInstance::~FunctionInstance() {\n  delete[] var_data;\n}\n\nconst char* FunctionInstance::ToString(IScriptEnvironment* env)\n{\n  if (pdef->name) {\n    return env->Sprintf(\"Function: %s defined at %s, line %d\", pdef->name, pdef->filename, pdef->line);\n  }\n  else {\n    return env->Sprintf(\"Function: defined at %s, line %d\", pdef->filename, pdef->line);\n  }\n}\n\nstatic bool is_within_int_in_float32_range(int64_t value) {\n  // 2^24\n  return value >= -16777216 && value <= 16777216;\n}\n\nAVSValue FunctionInstance::Execute(const AVSValue& args, IScriptEnvironment* env)\n{\n  env->PushContext();\n  for (int i = 0; i < pdef->var_count; ++i) {\n    env->SetVar(pdef->var_names[i], var_data[i]);\n  }\n  for (int i = 0; i<args.ArraySize(); ++i)\n    env->SetVar(pdef->param_names[i],\n      // Same as in ScriptFunction::Execute and AVSValue FunctionInstance::Execute\n          \n      // force float args that are actually long/int (int64) to be float/double (depending on the range)\n      // opportunity to fit into the smaller float size\n      (pdef->param_floats[i] && args[i].IsInt()) ?\n      is_within_int_in_float32_range(args[i].AsLong()) ? (float)args[i].AsLong() : (double)args[i].AsLong() :\n      args[i]\n    );\n\n  AVSValue result;\n  try {\n    result = pdef->body->Evaluate(env);\n  }\n  catch (...) {\n    env->PopContext();\n    throw;\n  }\n\n  env->PopContext();\n  return result;\n}\n\nAVSValue FunctionInstance::Execute_(AVSValue args, void* user_data, IScriptEnvironment* env)\n{\n  FunctionInstance* self = (FunctionInstance*)user_data;\n  return self->Execute(args, env);\n}\n"
  },
  {
    "path": "avs_core/core/parser/expression.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Expression_H__\n#define __Expression_H__\n\n#include <avisynth.h>\n#include \"../function.h\"\n\n#include <vector>\n#include <atomic>\n\n/********************************************************************\n********************************************************************/\n\n\nstruct ReturnExprException\n{\n\tAVSValue value;\n};\n\n/**** Base Classes ****/\n\nclass Expression {\npublic:\n  Expression() : refcnt(0) {}\n  virtual AVSValue Evaluate(IScriptEnvironment* env) = 0;\n  virtual const char* GetLvalue() { return 0; }\n  virtual ~Expression() {}\n\nprivate:\n  friend class PExpression;\n  std::atomic<int> refcnt;\n  void AddRef() { ++refcnt; }\n  void Release() { if (--refcnt <= 0) delete this; }\n};\n\nclass PExpression\n{\npublic:\n  PExpression() { Init(0); }\n  PExpression(Expression* p) { Init(p); }\n  PExpression(const PExpression& p) { Init(p.e); }\n  PExpression& operator=(Expression* p) { Set(p); return *this; }\n  PExpression& operator=(const PExpression& p) { Set(p.e); return *this; }\n  int operator!() const { return !e; }\n  operator void*() const { return e; }\n  Expression* operator->() const { return e; }\n  ~PExpression() { Release(); }\n\nprivate:\n  Expression* e;\n  void Init(Expression* p) { e=p; if (e) e->AddRef(); }\n  void Set(Expression* p) { if (p) p->AddRef(); if (e) e->Release(); e=p; }\n  void Release() { if (e) e->Release(); }\n};\n\n\n\n\n\n\n\n/**** Object classes ****/\n\nclass ExpRootBlock : public Expression\n{\npublic:\n  ExpRootBlock(const PExpression& e) : exp(e) {}\n  virtual AVSValue Evaluate(IScriptEnvironment* env);\n\nprivate:\n  const PExpression exp;\n};\n\nclass ExpConstant : public Expression\n{\npublic:\n  ExpConstant(std::vector<AVSValue>* v) : val(v->data(), (int)(v->size())) {} // array of AVSValue*\n  ExpConstant(AVSValue v) : val(v) {}\n  ExpConstant(int i) : val(i) {}\n  ExpConstant(int64_t i) : val(i) {}\n  ExpConstant(float f) : val(f) {}\n  ExpConstant(double f) : val(f) {}\n  ExpConstant(const char* s) : val(s) {}\n  virtual AVSValue Evaluate(IScriptEnvironment* env) {\n    AVS_UNUSED(env);\n    return val; }\n\nprivate:\n  friend class ExpNegative;\n  const AVSValue val;\n};\n\n\nclass ExpSequence : public Expression\n{\npublic:\n  ExpSequence(const PExpression& _a, const PExpression& _b) : a(_a), b(_b) {}\n  virtual AVSValue Evaluate(IScriptEnvironment* env);\nprivate:\n  const PExpression a, b;\n};\n\n\nclass ExpExceptionTranslator : public Expression\n{\npublic:\n  ExpExceptionTranslator(const PExpression& _exp) : exp(_exp) {}\n  AVSValue Evaluate(IScriptEnvironment* env);\n\nprivate:\n  const PExpression exp;\n  void TrapEval(AVSValue&, unsigned &excode, IScriptEnvironment*);\n};\n\n\nclass ExpTryCatch : public ExpExceptionTranslator\n{\npublic:\n  ExpTryCatch(const PExpression& _try_block, const char* _id, const PExpression& _catch_block)\n    : ExpExceptionTranslator(_try_block), id(_id), catch_block(_catch_block) {}\n  AVSValue Evaluate(IScriptEnvironment* env);\n\nprivate:\n  const char* const id;\n  const PExpression catch_block;\n};\n\nclass ExpLine : public ExpExceptionTranslator\n{\npublic:\n  ExpLine(const PExpression& _exp, const char* _filename, int _line)\n    : ExpExceptionTranslator(_exp), filename(_filename), line(_line) {}\n  AVSValue Evaluate(IScriptEnvironment* env);\n\nprivate:\n  const char* const filename;\n  const int line;\n};\n\n\nclass ExpBlockConditional : public Expression\n{\npublic:\n  ExpBlockConditional(const PExpression& _If, const PExpression& _Then, const PExpression& _Else)\n   : If(_If), Then(_Then), Else(_Else) {}\n  virtual AVSValue Evaluate(IScriptEnvironment* env);\n\nprivate:\n  const PExpression If, Then, Else;\n};\n\n\nclass ExpWhileLoop : public Expression\n{\npublic:\n  ExpWhileLoop(const PExpression& _condition, const PExpression& _body)\n   : condition(_condition), body(_body) {}\n  virtual AVSValue Evaluate(IScriptEnvironment* env);\n\nprivate:\n  const PExpression condition, body;\n};\n\n\nclass ExpForLoop : public Expression\n{\npublic:\n  ExpForLoop(const char* const _id, const PExpression& _init, const PExpression& _limit,\n             const PExpression& _step, const PExpression& _body)\n   : id(_id), init(_init), limit(_limit), step(_step), body(_body) {}\n  virtual AVSValue Evaluate(IScriptEnvironment* env);\n\nprivate:\n  const char* const id;\n  const PExpression init, limit, step, body;\n};\n\nclass ExpBreak : public Expression\n{\npublic:\n  ExpBreak() {}\n  virtual AVSValue Evaluate(IScriptEnvironment* env);\n};\n\nclass ExpContinue : public Expression\n{\npublic:\n  ExpContinue() {}\n  virtual AVSValue Evaluate(IScriptEnvironment* env);\n};\n\nclass ExpConditional : public Expression\n{\npublic:\n  ExpConditional(const PExpression& _If, const PExpression& _Then, const PExpression& _Else)\n   : If(_If), Then(_Then), Else(_Else) {}\n  virtual AVSValue Evaluate(IScriptEnvironment* env);\n\nprivate:\n  const PExpression If, Then, Else;\n};\n\nclass ExpReturn : public Expression\n{\npublic:\n\tExpReturn(PExpression value) : value(value) {}\n\tvirtual AVSValue Evaluate(IScriptEnvironment* env);\n\nprivate:\n\tconst PExpression value;\n};\n\n\n\n/**** Operator classes ****/\n\nclass ExpOr : public Expression\n{\npublic:\n  ExpOr(const PExpression& _a, const PExpression& _b) : a(_a), b(_b) {}\n  virtual AVSValue Evaluate(IScriptEnvironment* env);\n\nprivate:\n  const PExpression a, b;\n};\n\n\nclass ExpAnd : public Expression\n{\npublic:\n  ExpAnd(const PExpression& _a, const PExpression& _b) : a(_a), b(_b) {}\n  virtual AVSValue Evaluate(IScriptEnvironment* env);\n\nprivate:\n  const PExpression a, b;\n};\n\n\nclass ExpEqual : public Expression\n{\npublic:\n  ExpEqual(const PExpression& _a, const PExpression& _b) : a(_a), b(_b) {}\n  virtual AVSValue Evaluate(IScriptEnvironment* env);\n\nprivate:\n  const PExpression a, b;\n};\n\n\nclass ExpLess : public Expression\n{\npublic:\n  ExpLess(const PExpression& _a, const PExpression& _b) : a(_a), b(_b) {}\n  virtual AVSValue Evaluate(IScriptEnvironment* env);\n\nprivate:\n  const PExpression a, b;\n};\n\n\nclass ExpPlus : public Expression\n{\npublic:\n  ExpPlus(const PExpression& _a, const PExpression& _b) : a(_a), b(_b) {}\n  virtual AVSValue Evaluate(IScriptEnvironment* env);\n\nprivate:\n  const PExpression a, b;\n};\n\n\nclass ExpDoublePlus : public Expression\n{\npublic:\n  ExpDoublePlus(const PExpression& _a, const PExpression& _b) : a(_a), b(_b) {}\n  virtual AVSValue Evaluate(IScriptEnvironment* env);\n\nprivate:\n  const PExpression a, b;\n};\n\n\nclass ExpMinus : public Expression\n{\npublic:\n  ExpMinus(const PExpression& _a, const PExpression& _b) : a(_a), b(_b) {}\n  virtual AVSValue Evaluate(IScriptEnvironment* env);\n\nprivate:\n  const PExpression a, b;\n};\n\n\nclass ExpMult : public Expression\n{\npublic:\n  ExpMult(const PExpression& _a, const PExpression& _b) : a(_a), b(_b) {}\n  virtual AVSValue Evaluate(IScriptEnvironment* env);\n\nprivate:\n  const PExpression a, b;\n};\n\n\nclass ExpDiv : public Expression\n{\npublic:\n  ExpDiv(const PExpression& _a, const PExpression& _b) : a(_a), b(_b) {}\n  virtual AVSValue Evaluate(IScriptEnvironment* env);\n\nprivate:\n  const PExpression a, b;\n};\n\n\nclass ExpMod : public Expression\n{\npublic:\n  ExpMod(const PExpression& _a, const PExpression& _b) : a(_a), b(_b) {}\n  virtual AVSValue Evaluate(IScriptEnvironment* env);\n\nprivate:\n  const PExpression a, b;\n};\n\n\nclass ExpNegate : public Expression\n{\npublic:\n  ExpNegate(const PExpression& _e) : e(_e) {}\nvirtual AVSValue Evaluate(IScriptEnvironment* env);\n\nprivate:\n  const PExpression e;\n};\n\n\nclass ExpNot : public Expression\n{\npublic:\n  ExpNot(const PExpression& _e) : e(_e) {}\n  virtual AVSValue Evaluate(IScriptEnvironment* env);\n\nprivate:\n  const PExpression e;\n};\n\n\nclass ExpVariableReference : public Expression\n{\npublic:\n  ExpVariableReference(const char* _name) : name(_name) {}\n  virtual AVSValue Evaluate(IScriptEnvironment* env);\n\n  virtual const char* GetLvalue() { return name; }\n\nprivate:\n  const char* const name;\n};\n\n\nclass ExpAssignment : public Expression\n{\npublic:\n  ExpAssignment(const char* _lhs, const PExpression& _rhs) : lhs(_lhs), rhs(_rhs), withret(false) {}\n  ExpAssignment(const char* _lhs, const PExpression& _rhs, bool wr) : lhs(_lhs), rhs(_rhs), withret(wr) {}\n\n  virtual AVSValue Evaluate(IScriptEnvironment* env);\n\nprivate:\n  const char* const lhs;\n  PExpression rhs;\n  bool withret;\n};\n\n\nclass ExpGlobalAssignment : public Expression\n{\npublic:\n  ExpGlobalAssignment(const char* _lhs, const PExpression& _rhs) : lhs(_lhs), rhs(_rhs) {}\n  virtual AVSValue Evaluate(IScriptEnvironment* env);\n\nprivate:\n  const char* const lhs;\n  PExpression rhs;\n};\n\n\nclass ExpFunctionCall : public Expression\n{\npublic:\n  ExpFunctionCall( const char* _name, const PExpression& _func, PExpression* _arg_exprs,\n                   const char** _arg_expr_names, int _arg_expr_count, bool _oop_notation );\n  ~ExpFunctionCall(void);\n\n  virtual AVSValue Evaluate(IScriptEnvironment* env);\n\nprivate:\n  const char* const name;\n  PExpression func;\n  PExpression* arg_exprs;\n  const char** arg_expr_names;\n  const int arg_expr_count;\n  const bool oop_notation;\n};\n\n\nclass ExpLegacyFunctionDefinition : public Expression {\npublic:\n  virtual AVSValue Evaluate(IScriptEnvironment* env) { return AVSValue(); }\n};\n\n\nclass ExpFunctionWrapper : public Expression\n{\npublic:\n  ExpFunctionWrapper(const char* name);\n  virtual AVSValue Evaluate(IScriptEnvironment* env);\nprivate:\n  PFunction func;\n  const char* const name;\n};\n\n\nclass ExpFunctionDefinition : public Expression\n{\npublic:\n  ExpFunctionDefinition(const PExpression& _body,\n    const char* _name, const char* _param_types,\n    const bool* _param_floats, const char** _param_names, int param_count,\n    const char** _var_names, int _var_count,\n    const char* filename, int line);\n  ~ExpFunctionDefinition() {\n    delete[]param_floats;\n    delete[]param_names;\n    delete[]var_names;\n  }\n\n  virtual AVSValue Evaluate(IScriptEnvironment* env);\n\n//private:\n  const PExpression body;\n  const char* name;\n  const char* param_types;\n  bool* param_floats;\n  const char** param_names;\n  int var_count;\n  const char** var_names;\n\n  const char* filename;\n  int line;\n};\n\n\nclass FunctionInstance : public IFunction\n{\npublic:\n  FunctionInstance(ExpFunctionDefinition* pdef, IScriptEnvironment* env);\n  virtual ~FunctionInstance();\n  virtual const char* ToString(IScriptEnvironment* env);\n  virtual const char* GetLegacyName() { return nullptr; }\n  virtual const Function* GetDefinition() { return &data; }\n  virtual CaptureVars GetCaptures() {\n    CaptureVars ret = { pdef->var_count, pdef->var_names, var_data };\n    return ret;\n  }\n  AVSValue Execute(const AVSValue& args, IScriptEnvironment* env);\n  static AVSValue Execute_(AVSValue args, void* user_data, IScriptEnvironment* env);\n\nprivate:\n  Function data;\n  ExpFunctionDefinition* pdef;\n  PExpression pdef_ref;\n  AVSValue *var_data;\n};\n\n\n#endif  // __Expression_H_\n"
  },
  {
    "path": "avs_core/core/parser/os/win32_string_compat.cpp",
    "content": "// Copy of AvxSynth's windowsPorts.cpp; it was missing the licensing\n// header there, too.\n\n#include \"win32_string_compat.h\"\n#include <stdio.h>\n#include <stdlib.h>\n#include <ctype.h>\n#include <string.h>\n#include <dirent.h>\n\nchar *_strrev(char *str)\n{\n    unsigned long nLength = strlen(str);\n    for(unsigned long i = 0; i < nLength/2; i++)\n    {\n        char chTemp = str[i];\n        str[i] = str[nLength - i - 1];\n        str[nLength - i - 1] = chTemp;\n    }\n    return str;\n}\n\nchar *_strupr(char *str)\n{\n    if (str)\n    {\n        unsigned long nLength = strlen(str);\n        for(unsigned long i = 0; i < nLength; i++)\n        {\n            str[i] = toupper(str[i]);\n        }\n    }\n\n\treturn str;\n}\n\nchar *_strlwr(char *str)\n{\n    if (str)\n    {\n        unsigned long nLength = strlen(str);\n        for(unsigned long i = 0; i < nLength; i++)\n        {\n            str[i] = tolower(str[i]);\n        }\n    }\n\n    return str;\n}\n"
  },
  {
    "path": "avs_core/core/parser/os/win32_string_compat.h",
    "content": "// Copy of AvxSynth's windowsPorts.h; it was missing the licensing\n// header there, too.\n\n#ifndef __WIN32_STRING_COMPAT_H__\n#define __WIN32_STRING_COMPAT_H__\n\n#include <stdarg.h>\n#include <limits.h>\n#include <time.h>\n#include <avs/types.h>\n\nchar* _strrev(char *str);\nchar* _strupr(char *str);\nchar* _strlwr(char *str);\n\n\nstruct _finddata_t\n{\n\tunsigned    attrib;\n    time_t      time_create;    /* -1 for FAT file systems */\n    time_t      time_access;    /* -1 for FAT file systems */\n    time_t      time_write;\n    uint64_t    size;\n    char        name[PATH_MAX]; // originally name[260]\n};\n\nintptr_t _findfirst(const char *filespec, struct _finddata_t *fileinfo);\n\n#endif // __WIN32_STRING_COMPAT_H__\n"
  },
  {
    "path": "avs_core/core/parser/script.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include \"script.h\"\n#include <time.h>\n#include <cstdio>\n#include <cstdlib>\n#include <cmath>\n#include <vector>\n#include <fstream>\n#include <memory>\n#include <limits>\n#include <bitset>\n\n#ifdef AVS_WINDOWS\n#include <io.h>\n#include <avs/win.h>\n#else\n#include <avs/posix.h>\n#include \"os/win32_string_compat.h\"\n#include <dirent.h>\n#endif\n\n#include <avs/filesystem.h>\n#include <avs/minmax.h>\n#include <new>\n#include \"../internal.h\"\n#include \"../Prefetcher.h\"\n#include \"../InternalEnvironment.h\"\n#include \"../strings.h\"\n#include <map>\n#include <string>\n#include <utility>\n#define __STDC_FORMAT_MACROS\n#include <inttypes.h>\n#include <algorithm>\n#include <cstring>\n#include <cctype>\n\n#ifndef MINGW_HAS_SECURE_API\n#define sprintf_s sprintf\n#endif\n\n\n\n/********************************************************************\n***** Declare index of new filters for Avisynth's filter engine *****\n********************************************************************/\n\n\nextern const AVSFunction Script_functions[] = {\n  { \"muldiv\",   BUILTIN_FUNC_PREFIX, \"iii\", Muldiv },\n\n  { \"floor\",    BUILTIN_FUNC_PREFIX, \"f\", Floor },\n  { \"ceil\",     BUILTIN_FUNC_PREFIX, \"f\", Ceil },\n  { \"round\",    BUILTIN_FUNC_PREFIX, \"f\", Round },\n\n  { \"acos\",     BUILTIN_FUNC_PREFIX, \"f\", Acos },\n  { \"asin\",     BUILTIN_FUNC_PREFIX, \"f\", Asin },\n  { \"atan\",     BUILTIN_FUNC_PREFIX, \"f\", Atan },\n  { \"atan2\",    BUILTIN_FUNC_PREFIX, \"ff\", Atan2 },\n  { \"cos\",      BUILTIN_FUNC_PREFIX, \"f\", Cos },\n  { \"cosh\",     BUILTIN_FUNC_PREFIX, \"f\", Cosh },\n  { \"exp\",      BUILTIN_FUNC_PREFIX, \"f\", Exp },\n  { \"fmod\",     BUILTIN_FUNC_PREFIX, \"ff\", Fmod },\n  { \"log\",      BUILTIN_FUNC_PREFIX, \"f\", Log },\n  { \"log10\",    BUILTIN_FUNC_PREFIX, \"f\", Log10 },\n  { \"pow\",      BUILTIN_FUNC_PREFIX, \"ff\", Pow },\n  { \"sin\",      BUILTIN_FUNC_PREFIX, \"f\", Sin },\n  { \"sinh\",     BUILTIN_FUNC_PREFIX, \"f\", Sinh },\n  { \"tan\",      BUILTIN_FUNC_PREFIX, \"f\", Tan },\n  { \"tanh\",     BUILTIN_FUNC_PREFIX, \"f\", Tanh },\n  { \"sqrt\",     BUILTIN_FUNC_PREFIX, \"f\", Sqrt },\n\n\n  { \"abs\",      BUILTIN_FUNC_PREFIX, \"i\", Abs },\n  { \"abs\",      BUILTIN_FUNC_PREFIX, \"f\", FAbs },\n  { \"pi\",       BUILTIN_FUNC_PREFIX, \"\", Pi },\n#ifdef OPT_ScriptFunctionTau\n  { \"tau\",      BUILTIN_FUNC_PREFIX, \"\", Tau },\n#endif\n  { \"sign\",     BUILTIN_FUNC_PREFIX, \"f\",Sign},\n\n  { \"bitand\",   BUILTIN_FUNC_PREFIX, \"ii\",BitAnd},\n  { \"bitnot\",   BUILTIN_FUNC_PREFIX, \"i\",BitNot},\n  { \"bitor\",    BUILTIN_FUNC_PREFIX, \"ii\",BitOr},\n  { \"bitxor\",   BUILTIN_FUNC_PREFIX, \"ii\",BitXor},\n  // v11\n  { \"bitand64\",   BUILTIN_FUNC_PREFIX, \"ii\",BitAnd64},\n  { \"bitnot64\",   BUILTIN_FUNC_PREFIX, \"i\",BitNot64},\n  { \"bitor64\",    BUILTIN_FUNC_PREFIX, \"ii\",BitOr64},\n  { \"bitxor64\",   BUILTIN_FUNC_PREFIX, \"ii\",BitXor64},\n\n  { \"bitlshift\",  BUILTIN_FUNC_PREFIX, \"ii\",BitLShift},\n  { \"bitlshiftl\", BUILTIN_FUNC_PREFIX, \"ii\",BitLShift},\n  { \"bitlshifta\", BUILTIN_FUNC_PREFIX, \"ii\",BitLShift},\n  { \"bitlshiftu\", BUILTIN_FUNC_PREFIX, \"ii\",BitLShift},\n  { \"bitlshifts\", BUILTIN_FUNC_PREFIX, \"ii\",BitLShift},\n  { \"bitshl\",     BUILTIN_FUNC_PREFIX, \"ii\",BitLShift},\n  { \"bitsal\",     BUILTIN_FUNC_PREFIX, \"ii\",BitLShift},\n  // v11 omg under how many names do the same?! keep only two\n  { \"bitshl64\",     BUILTIN_FUNC_PREFIX, \"ii\",BitLShift64},\n  { \"bitsal64\",     BUILTIN_FUNC_PREFIX, \"ii\",BitLShift64},\n\n  { \"bitrshiftl\", BUILTIN_FUNC_PREFIX, \"ii\",BitRShiftL},\n  { \"bitrshifta\", BUILTIN_FUNC_PREFIX, \"ii\",BitRShiftA},\n  { \"bitrshiftu\", BUILTIN_FUNC_PREFIX, \"ii\",BitRShiftL},\n  { \"bitrshifts\", BUILTIN_FUNC_PREFIX, \"ii\",BitRShiftA},\n  { \"bitshr\",     BUILTIN_FUNC_PREFIX, \"ii\",BitRShiftL},\n  { \"bitsar\",     BUILTIN_FUNC_PREFIX, \"ii\",BitRShiftA},\n  // v11\n  { \"bitshr64\",     BUILTIN_FUNC_PREFIX, \"ii\",BitRShift64L},\n  { \"bitsar64\",     BUILTIN_FUNC_PREFIX, \"ii\",BitRShift64A},\n\n  { \"bitlrotate\", BUILTIN_FUNC_PREFIX, \"ii\",BitRotateL},\n  { \"bitrrotate\", BUILTIN_FUNC_PREFIX, \"ii\",BitRotateR},\n  { \"bitrol\",     BUILTIN_FUNC_PREFIX, \"ii\",BitRotateL},\n  { \"bitror\",     BUILTIN_FUNC_PREFIX, \"ii\",BitRotateR},\n  // v11\n  { \"bitrol64\",     BUILTIN_FUNC_PREFIX, \"ii\",BitRotate64L},\n  { \"bitror64\",     BUILTIN_FUNC_PREFIX, \"ii\",BitRotate64R},\n\n  { \"bitchg\",    BUILTIN_FUNC_PREFIX, \"ii\",BitChg},\n  { \"bitchange\", BUILTIN_FUNC_PREFIX, \"ii\",BitChg},\n  { \"bitclr\",    BUILTIN_FUNC_PREFIX, \"ii\",BitClr},\n  { \"bitclear\",  BUILTIN_FUNC_PREFIX, \"ii\",BitClr},\n  { \"bitset\",    BUILTIN_FUNC_PREFIX, \"ii\",BitSet},\n  { \"bittst\",    BUILTIN_FUNC_PREFIX, \"ii\",BitTst},\n  { \"bittest\",   BUILTIN_FUNC_PREFIX, \"ii\",BitTst},\n  { \"bitsetcount\", BUILTIN_FUNC_PREFIX, \"i+\",BitSetCount }, // avs+ 180221\n  // v11\n  { \"bitchg64\",    BUILTIN_FUNC_PREFIX, \"ii\",BitChg64},\n  { \"bitclr64\",    BUILTIN_FUNC_PREFIX, \"ii\",BitClr64},\n  { \"bitset64\",    BUILTIN_FUNC_PREFIX, \"ii\",BitSet64},\n  { \"bittst64\",    BUILTIN_FUNC_PREFIX, \"ii\",BitTst64},\n  { \"bitsetcount64\", BUILTIN_FUNC_PREFIX, \"i+\",BitSetCount64 },\n\n  { \"lcase\",    BUILTIN_FUNC_PREFIX, \"s\",LCase},\n  { \"ucase\",    BUILTIN_FUNC_PREFIX, \"s\",UCase},\n  { \"strlen\",   BUILTIN_FUNC_PREFIX, \"s\",StrLen},\n  { \"revstr\",   BUILTIN_FUNC_PREFIX, \"s\",RevStr},\n  { \"leftstr\",  BUILTIN_FUNC_PREFIX, \"si\",LeftStr},\n  { \"midstr\",   BUILTIN_FUNC_PREFIX, \"si[length]i\",MidStr},\n  { \"rightstr\", BUILTIN_FUNC_PREFIX, \"si\",RightStr},\n  { \"findstr\",  BUILTIN_FUNC_PREFIX, \"ss\",FindStr},\n  { \"fillstr\",  BUILTIN_FUNC_PREFIX, \"i[]s\",FillStr},\n  { \"replacestr\", BUILTIN_FUNC_PREFIX, \"sss[sig]b\",ReplaceStr}, // avs+ 161230, case 180222\n  { \"trimall\",  BUILTIN_FUNC_PREFIX, \"s\",TrimAll }, // avs+ 180225 diff name of clip-function Trim\n  { \"trimleft\", BUILTIN_FUNC_PREFIX, \"s\",TrimLeft }, // avs+ 180225\n  { \"trimright\", BUILTIN_FUNC_PREFIX, \"s\",TrimRight }, // avs+ 180225\n\n  { \"strcmp\",   BUILTIN_FUNC_PREFIX, \"ss\",StrCmp},\n  { \"strcmpi\",  BUILTIN_FUNC_PREFIX, \"ss\",StrCmpi},\n\n  { \"rand\",     BUILTIN_FUNC_PREFIX, \"[max]i[scale]b[seed]b\", Rand },\n\n  { \"Select\",   BUILTIN_FUNC_PREFIX, \"i.+\", Select },\n\n  { \"nop\",      BUILTIN_FUNC_PREFIX, \"\", NOP },\n  { \"undefined\",BUILTIN_FUNC_PREFIX, \"\", Undefined },\n\n  { \"width\",      BUILTIN_FUNC_PREFIX, \"c\", Width },\n  { \"height\",     BUILTIN_FUNC_PREFIX, \"c\", Height },\n  { \"framecount\", BUILTIN_FUNC_PREFIX, \"c\", FrameCount },\n  { \"framerate\",  BUILTIN_FUNC_PREFIX, \"c\", FrameRate },\n  { \"frameratenumerator\",   BUILTIN_FUNC_PREFIX, \"c\", FrameRateNumerator },\n  { \"frameratedenominator\", BUILTIN_FUNC_PREFIX, \"c\", FrameRateDenominator },\n  { \"audiorate\",     BUILTIN_FUNC_PREFIX, \"c\", AudioRate },\n  { \"audiolength\",   BUILTIN_FUNC_PREFIX, \"c\", AudioLength },  // v11: returns real int64\n  { \"audiolengthlo\", BUILTIN_FUNC_PREFIX, \"c[]i\", AudioLengthLo }, // audiolength%i\n  { \"audiolengthhi\", BUILTIN_FUNC_PREFIX, \"c[]i\", AudioLengthHi }, // audiolength/i\n  { \"audiolengths\",  BUILTIN_FUNC_PREFIX, \"c\", AudioLengthS }, // as a string\n  { \"audiolengthf\",  BUILTIN_FUNC_PREFIX, \"c\", AudioLengthF }, // at least this will give an order of the size\n  { \"audioduration\", BUILTIN_FUNC_PREFIX, \"c\", AudioDuration }, // In seconds\n  { \"audiochannels\", BUILTIN_FUNC_PREFIX, \"c\", AudioChannels },\n  { \"audiobits\",     BUILTIN_FUNC_PREFIX, \"c\", AudioBits },\n  { \"IsAudioFloat\",  BUILTIN_FUNC_PREFIX, \"c\", IsAudioFloat },\n  { \"IsAudioInt\",    BUILTIN_FUNC_PREFIX, \"c\", IsAudioInt },\n\n  { \"IsChannelMaskKnown\",  BUILTIN_FUNC_PREFIX, \"c\", IsChannelMaskKnown },\n  { \"GetChannelMask\",  BUILTIN_FUNC_PREFIX, \"c\", GetChannelMask }, // SetChannelMask: see in audio.cpp\n\n  { \"IsRGB\",    BUILTIN_FUNC_PREFIX, \"c\", IsRGB },\n  { \"IsYUY2\",   BUILTIN_FUNC_PREFIX, \"c\", IsYUY2 },\n  { \"IsYUV\",    BUILTIN_FUNC_PREFIX, \"c\", IsYUV },\n  { \"IsY8\",     BUILTIN_FUNC_PREFIX, \"c\", IsY8 },\n  { \"IsYV12\",   BUILTIN_FUNC_PREFIX, \"c\", IsYV12 },\n  { \"IsYV16\",   BUILTIN_FUNC_PREFIX, \"c\", IsYV16 },\n  { \"IsYV24\",   BUILTIN_FUNC_PREFIX, \"c\", IsYV24 },\n  { \"IsYV411\",  BUILTIN_FUNC_PREFIX, \"c\", IsYV411 },\n  { \"IsPlanar\", BUILTIN_FUNC_PREFIX, \"c\", IsPlanar },\n  { \"IsInterleaved\", BUILTIN_FUNC_PREFIX, \"c\", IsInterleaved },\n  { \"IsRGB24\",       BUILTIN_FUNC_PREFIX, \"c\", IsRGB24 },\n  { \"IsRGB32\",       BUILTIN_FUNC_PREFIX, \"c\", IsRGB32 },\n  { \"IsFieldBased\",  BUILTIN_FUNC_PREFIX, \"c\", IsFieldBased },\n  { \"IsFrameBased\",  BUILTIN_FUNC_PREFIX, \"c\", IsFrameBased },\n  { \"GetParity\", BUILTIN_FUNC_PREFIX, \"c[n]i\", GetParity },\n  { \"String\",    BUILTIN_FUNC_PREFIX, \".[]s\", String },\n  { \"Hex\",       BUILTIN_FUNC_PREFIX, \"i[width]i\", Hex }, // avs+ 20180222 new width parameter\n  { \"Func\",    BUILTIN_FUNC_PREFIX, \"n\", Func },\n  { \"Format\",  BUILTIN_FUNC_PREFIX, \"s.*\", FormatString },\n\n  { \"IsBool\",   BUILTIN_FUNC_PREFIX, \".\", IsBool },\n  { \"IsInt\",    BUILTIN_FUNC_PREFIX, \".\", IsInt },\n  { \"IsLongStrict\",   BUILTIN_FUNC_PREFIX, \".\", IsLongStrict }, // v11\n  { \"IsFloat\",  BUILTIN_FUNC_PREFIX, \".\", IsFloat },\n  { \"IsFloatFStrict\", BUILTIN_FUNC_PREFIX, \".\", IsFloatfStrict }, // v11\n  { \"IsString\", BUILTIN_FUNC_PREFIX, \".\", IsString },\n  { \"IsClip\",   BUILTIN_FUNC_PREFIX, \".\", IsClip },\n  { \"IsFunction\", BUILTIN_FUNC_PREFIX, \".\", IsFunction },\n  { \"Defined\",  BUILTIN_FUNC_PREFIX, \".\", Defined },\n  { \"TypeName\",  BUILTIN_FUNC_PREFIX, \".\", TypeName },\n\n  { \"Default\",  BUILTIN_FUNC_PREFIX, \"..\", Default },\n\n  { \"Eval\",   BUILTIN_FUNC_PREFIX, \"s[name]s\", Eval },\n  { \"Eval\",   BUILTIN_FUNC_PREFIX, \"cs[name]s\", EvalOop },\n  { \"Apply\",  BUILTIN_FUNC_PREFIX, \"s.*\", Apply },\n  { \"Import\", BUILTIN_FUNC_PREFIX, \"s+[utf8]b\", Import },\n\n  { \"Assert\", BUILTIN_FUNC_PREFIX, \"b[message]s\", Assert },\n  { \"Assert\", BUILTIN_FUNC_PREFIX, \"s\", AssertEval },\n\n  { \"SetMemoryMax\", BUILTIN_FUNC_PREFIX, \"[]i[type]i[index]i\", SetMemoryMax }, // Neo\n  { \"SetWorkingDir\", BUILTIN_FUNC_PREFIX, \"s\", SetWorkingDir },\n  { \"Exist\",         BUILTIN_FUNC_PREFIX, \"s[utf8]b\", Exist },\n\n  { \"Chr\",    BUILTIN_FUNC_PREFIX, \"i\", AVSChr },\n  { \"Ord\",    BUILTIN_FUNC_PREFIX, \"s\", AVSOrd },\n  { \"Time\",   BUILTIN_FUNC_PREFIX, \"s\", AVSTime },\n  { \"Spline\", BUILTIN_FUNC_PREFIX, \"[x]ff+[cubic]b\", Spline },\n\n  // parameter is 'f' which cover any integer or float numbers\n  { \"int\",   BUILTIN_FUNC_PREFIX, \"f\", Int },\n  { \"frac\",  BUILTIN_FUNC_PREFIX, \"f\", Frac },\n  { \"float\", BUILTIN_FUNC_PREFIX, \"f\", Float },\n  { \"inti\",  BUILTIN_FUNC_PREFIX, \"f\", IntI }, // v11\n  { \"long\",  BUILTIN_FUNC_PREFIX, \"f\", Long }, // v11\n  { \"floatf\", BUILTIN_FUNC_PREFIX, \"f\", Floatf }, // v11\n  { \"double\", BUILTIN_FUNC_PREFIX, \"f\", Double }, // v11\n\n  { \"value\",    BUILTIN_FUNC_PREFIX, \"s\",Value},\n  { \"hexvalue\", BUILTIN_FUNC_PREFIX, \"s[pos]i\",HexValue}, // avs+ 20180222 new pos parameter\n  { \"hexvalue64\", BUILTIN_FUNC_PREFIX, \"s[pos]i\",HexValue64 }, // v11\n\n  { \"VersionNumber\", BUILTIN_FUNC_PREFIX, \"\", VersionNumber },\n  { \"VersionString\", BUILTIN_FUNC_PREFIX, \"\", VersionString },\n  { \"IsVersionOrGreater\", BUILTIN_FUNC_PREFIX, \"[majorversion]i[minorVersion]i[bugfixVersion]i\", IsVersionOrGreater },\n\n  { \"HasVideo\", BUILTIN_FUNC_PREFIX, \"c\", HasVideo },\n  { \"HasAudio\", BUILTIN_FUNC_PREFIX, \"c\", HasAudio },\n\n  { \"Min\", BUILTIN_FUNC_PREFIX, \"f+\", AvsMin },\n  { \"Max\", BUILTIN_FUNC_PREFIX, \"f+\", AvsMax },\n\n  { \"ScriptName\", BUILTIN_FUNC_PREFIX, \"\", ScriptName },\n  { \"ScriptFile\", BUILTIN_FUNC_PREFIX, \"\", ScriptFile },\n  { \"ScriptDir\",  BUILTIN_FUNC_PREFIX, \"\", ScriptDir  },\n  { \"ScriptNameUtf8\", BUILTIN_FUNC_PREFIX, \"\", ScriptNameUtf8 },\n  { \"ScriptFileUtf8\", BUILTIN_FUNC_PREFIX, \"\", ScriptFileUtf8 },\n  { \"ScriptDirUtf8\",  BUILTIN_FUNC_PREFIX, \"\", ScriptDirUtf8 },\n\n  { \"PixelType\",  BUILTIN_FUNC_PREFIX, \"c\", PixelType  },\n\n  { \"AddAutoloadDir\",     BUILTIN_FUNC_PREFIX, \"s[toFront]b[utf8]b\", AddAutoloadDir  },\n  { \"ClearAutoloadDirs\",  BUILTIN_FUNC_PREFIX, \"\", ClearAutoloadDirs  },\n  { \"ListAutoloadDirs\",   BUILTIN_FUNC_PREFIX, \"[utf8]b\", ListAutoloadDirs },\n  { \"AutoloadPlugins\",    BUILTIN_FUNC_PREFIX, \"\", AutoloadPlugins  },\n  { \"FunctionExists\",     BUILTIN_FUNC_PREFIX, \"s\", FunctionExists  },\n  { \"InternalFunctionExists\", BUILTIN_FUNC_PREFIX, \"s\", InternalFunctionExists  },\n\n  { \"SetFilterMTMode\",  BUILTIN_FUNC_PREFIX, \"si[force]b\", SetFilterMTMode  },\n  { \"Prefetch\",         BUILTIN_FUNC_PREFIX, \"c[threads]i[frames]i\", Prefetcher::Create },\n  { \"SetLogParams\",     BUILTIN_FUNC_PREFIX, \"[target]s[level]i\", SetLogParams },\n  { \"LogMsg\",           BUILTIN_FUNC_PREFIX, \"si\", LogMsg },\n  { \"SetCacheMode\",     BUILTIN_FUNC_PREFIX, \"[mode]i\", SetCacheMode }, // Neo\n  { \"SetDeviceOpt\",     BUILTIN_FUNC_PREFIX, \"[opt]i[val]i\", SetDeviceOpt }, // Neo\n  { \"SetMaxCPU\",        BUILTIN_FUNC_PREFIX, \"s\", SetMaxCPU }, // 20200331\n  { \"SetFilterProp\",   BUILTIN_FUNC_PREFIX, \"ss.[mode]i\",   SetFilterProp }, // any type (int/float/bool/string/fn/undef); clip rejected in body\n  { \"SetFilterProp\",   BUILTIN_FUNC_PREFIX, \"ss.s.[mode]i\", SetFilterProp }, // conditional: when param==match, inject key=value\n  { \"GetFilterProps\",        BUILTIN_FUNC_PREFIX, \"\", GetFilterProps },\n  { \"SetFilterPropPassthrough\", BUILTIN_FUNC_PREFIX, \"s\", SetFilterPropPassthrough },\n\n  { \"IsY\",       BUILTIN_FUNC_PREFIX, \"c\", IsY },\n  { \"Is420\",     BUILTIN_FUNC_PREFIX, \"c\", Is420 },\n  { \"Is422\",     BUILTIN_FUNC_PREFIX, \"c\", Is422 },\n  { \"Is444\",     BUILTIN_FUNC_PREFIX, \"c\", Is444 },\n  { \"IsRGB48\",       BUILTIN_FUNC_PREFIX, \"c\", IsRGB48 },\n  { \"IsRGB64\",       BUILTIN_FUNC_PREFIX, \"c\", IsRGB64 },\n  { \"ComponentSize\", BUILTIN_FUNC_PREFIX, \"c\", ComponentSize },\n  { \"BitsPerComponent\", BUILTIN_FUNC_PREFIX, \"c\", BitsPerComponent },\n  { \"IsYUVA\",       BUILTIN_FUNC_PREFIX, \"c\", IsYUVA },\n  { \"IsPlanarRGB\",  BUILTIN_FUNC_PREFIX, \"c\", IsPlanarRGB },\n  { \"IsPlanarRGBA\", BUILTIN_FUNC_PREFIX, \"c\", IsPlanarRGBA },\n  { \"ColorSpaceNameToPixelType\",  BUILTIN_FUNC_PREFIX, \"s\", ColorSpaceNameToPixelType },\n  { \"NumComponents\", BUILTIN_FUNC_PREFIX, \"c\", NumComponents }, // r2348+\n  { \"HasAlpha\", BUILTIN_FUNC_PREFIX, \"c\", HasAlpha }, // r2348+\n  { \"IsPackedRGB\", BUILTIN_FUNC_PREFIX, \"c\", IsPackedRGB }, // r2348+\n  { \"IsVideoFloat\", BUILTIN_FUNC_PREFIX, \"c\", IsVideoFloat }, // r2435+\n\n  { \"GetProcessInfo\", BUILTIN_FUNC_PREFIX, \"[type]i\", GetProcessInfo }, // 170526-\n#ifdef AVS_WINDOWS\n  { \"StrToUtf8\", BUILTIN_FUNC_PREFIX, \"s\", StrToUtf8 }, // 170601-\n  { \"StrFromUtf8\", BUILTIN_FUNC_PREFIX, \"s\", StrFromUtf8 }, // 170601-\n#endif\n\n  { \"IsFloatUvZeroBased\", BUILTIN_FUNC_PREFIX, \"\", IsFloatUvZeroBased }, // 180516-\n  { \"BuildPixelType\", BUILTIN_FUNC_PREFIX, \"[family]s[bits]i[chroma]i[compat]b[oldnames]b[sample_clip]c\", BuildPixelType }, // 180517-\n  { \"VarExist\", BUILTIN_FUNC_PREFIX, \"s\", VarExist }, // 180606-\n\n\n    // Creates script array from zero or more anything.\n    // Direct array constant syntax e.g. x = [arg1,arg2,...] is translated to x = Array(arg1,arg2,...)\n  { \"Array\", BUILTIN_FUNC_PREFIX, \".*\", ArrayCreate },\n  { \"IsArray\",   BUILTIN_FUNC_PREFIX, \".\", IsArray },\n    // dictionary type array indexing\n  { \"ArrayGet\",  BUILTIN_FUNC_PREFIX, \".s\", ArrayGet },\n    // classic array indexing background helper: e.g. a[3,4] -> ArrayGet(a, [2,3])\n  { \"ArrayGet\",  BUILTIN_FUNC_PREFIX, \".i+\", ArrayGet }, // .+i+ syntax is not possible.\n    // length can be zero\n  { \"ArraySize\", BUILTIN_FUNC_PREFIX, \".\", ArraySize },\n  { \"ArrayIns\",  BUILTIN_FUNC_PREFIX, \"..i+\", ArrayIns, (void*)0 },\n  { \"ArrayAdd\",  BUILTIN_FUNC_PREFIX, \"..i*\", ArrayIns, (void*)1 },\n  { \"ArraySet\",  BUILTIN_FUNC_PREFIX, \"..i+\", ArrayIns, (void*)2 },\n  { \"ArrayDel\",  BUILTIN_FUNC_PREFIX, \".i+\", ArrayIns, (void*)3 },\n  { \"ArraySort\",  BUILTIN_FUNC_PREFIX, \".\", ArraySort, (void*)0 },\n\n  /*\n  { \"IsArrayOf\", BUILTIN_FUNC_PREFIX, \".s\", IsArrayOf },\n  */\n  { 0 }\n};\n\n\n/**********************************\n *******   Script Function   ******\n *********************************/\n\nScriptFunction::ScriptFunction( const PExpression& _body, const bool* _param_floats,\n                                const char** _param_names, int param_count )\n  : body(_body)\n{\n  param_floats = new bool[param_count];\n  memcpy(param_floats, _param_floats, param_count * sizeof(const bool));\n\n  param_names = new const char* [param_count];\n  memcpy(param_names, _param_names, param_count * sizeof(const char*));\n}\n\nstatic bool is_within_int_in_float32_range(int64_t value) {\n  return value >= -16777216 && value <= 16777216;\n}\n\nAVSValue ScriptFunction::Execute(AVSValue args, void* user_data, IScriptEnvironment* env)\n{\n  ScriptFunction* self = (ScriptFunction*)user_data;\n  env->PushContext();\n  for (int i=0; i<args.ArraySize(); ++i)\n    env->SetVar(self->param_names[i], \n      // Same as in ScriptFunction::Execute and AVSValue FunctionInstance::Execute\n\n      // force float args that are actually long/int (int64) to be float/double (depending on the range)\n      // opportunity to fit into the smaller float size\n      (self->param_floats[i] && args[i].IsInt()) ?\n      is_within_int_in_float32_range(args[i].AsLong()) ? (float)args[i].AsLong() : (double)args[i].AsLong() :\n      args[i]\n    );\n\n  AVSValue result;\n  try {\n    result = self->body->Evaluate(env);\n  }\n  catch (...) {\n    env->PopContext();\n    throw;\n  }\n\n  env->PopContext();\n  return result;\n}\n\nvoid ScriptFunction::Delete(void* self, IScriptEnvironment*)\n{\n  delete (ScriptFunction*)self;\n}\n\n/***********************************\n *******   Helper Functions   ******\n **********************************/\n\n#ifdef AVS_WINDOWS\n\nstd::wstring CWDChanger::GetCurrentWorkingDirectory() {\n  DWORD length = GetCurrentDirectoryW(0, nullptr);\n  if (length == 0) return {};\n\n  std::wstring buffer(length, L'\\0');\n  if (GetCurrentDirectoryW(length, &buffer[0]) == 0) return {};\n\n  // Remove trailing null character if present\n  if (!buffer.empty() && buffer.back() == L'\\0') {\n    buffer.pop_back();\n  }\n\n  return buffer;\n}\n\n#else\n\nstd::string CWDChanger::GetCurrentWorkingDirectory() {\n  char buffer[FILENAME_MAX];\n  if (getcwd(buffer, sizeof(buffer)) == nullptr) return {};\n\n  return std::string(buffer);\n}\n\n#endif\n\n\n#ifdef AVS_WINDOWS\nvoid CWDChanger::Init(const wchar_t* new_cwd)\n{\n  // works in unicode internally\n  uint32_t cwdLen = GetCurrentDirectoryW(0, NULL);\n  old_working_directory = std::make_unique<wchar_t[]>(cwdLen); // instead of new wchar_t[cwdLen];\n  uint32_t save_cwd_success = GetCurrentDirectoryW(cwdLen, old_working_directory.get());\n  bool set_cwd_success = SetCurrentDirectoryW(new_cwd);\n  restore = (save_cwd_success && set_cwd_success);\n}\n\nCWDChanger::CWDChanger(const wchar_t* new_cwd)\n{\n  Init(new_cwd);\n}\n\n// utf8 on Windows as well\nCWDChanger::CWDChanger(const char* new_cwd_utf8)\n{\n  auto new_cwd_w = Utf8ToWideChar(new_cwd_utf8);\n  Init(new_cwd_w.get());\n}\n\nCWDChanger::~CWDChanger(void)\n{\n  if (restore)\n    SetCurrentDirectoryW(old_working_directory.get());\n}\n\nDllDirChanger::DllDirChanger(const char* new_dir)\n{\n  uint32_t len = GetDllDirectory (0, NULL);\n  old_directory = std::make_unique<char[]>(len + 1); // instead of new char[len+1]\n  uint32_t save_success = GetDllDirectory (len, old_directory.get());\n  bool set_success = SetDllDirectory(new_dir);\n  restore = (save_success && set_success);\n}\n\nDllDirChanger::~DllDirChanger(void)\n{\n  if (restore)\n    SetDllDirectory(old_directory.get());\n}\n#else // copied from AvxSynth\nCWDChanger::CWDChanger(const char* new_cwd)\n{\n\n  char* path = getcwd(old_working_directory, FILENAME_MAX);\n  bool save_cwd_success = (NULL != path);\n  bool set_cwd_success = (0 == chdir(new_cwd));\n  restore = (save_cwd_success && set_cwd_success);\n}\n\nCWDChanger::~CWDChanger(void)\n{\n  if (restore)\n    chdir(old_working_directory);\n}\n#endif\n\n\nAVSValue Assert(AVSValue args, void*, IScriptEnvironment* env)\n{\n  if (!args[0].AsBool())\n    env->ThrowError(\"%s\", args[1].Defined() ? args[1].AsString() : \"Assert: assertion failed\");\n  return AVSValue();\n}\n\nAVSValue AssertEval(AVSValue args, void*, IScriptEnvironment* env)\n{\n  const char* pred = args[0].AsString();\n  AVSValue eval_args[] = { args[0].AsString(), \"asserted expression\" };\n  AVSValue val = env->Invoke(\"Eval\", AVSValue(eval_args, 2));\n  if (!val.IsBool())\n    env->ThrowError(\"Assert: expression did not evaluate to true or false: \\\"%s\\\"\", pred);\n  if (!val.AsBool())\n    env->ThrowError(\"Assert: assertion failed: \\\"%s\\\"\", pred);\n  return AVSValue();\n}\n\nAVSValue Eval(AVSValue args, void*, IScriptEnvironment* env)\n{\n  const char *filename = args[1].AsString(0);\n  if (filename) filename = env->SaveString(filename);\n  ScriptParser parser(env, args[0].AsString(), filename);\n  PExpression exp = parser.Parse();\n  return exp->Evaluate(env);\n}\n\nAVSValue Apply(AVSValue args, void*, IScriptEnvironment* env)\n{\n  return env->Invoke(args[0].AsString(), args[1]);\n}\n\nAVSValue EvalOop(AVSValue args, void*, IScriptEnvironment* env)\n{\n  AVSValue prev_last = env->GetVarDef(\"last\");  // Store previous last\n  env->SetVar(\"last\", args[0]);              // Set implicit last\n\n  AVSValue result;\n  try {\n    result = Eval(AVSValue(&args[1], 2), 0, env);\n  }\n  catch(...) {\n    env->SetVar(\"last\", prev_last);          // Restore implicit last\n    throw;\n  }\n  env->SetVar(\"last\", prev_last);            // Restore implicit last\n  return result;\n}\n\nAVSValue Import(AVSValue args, void*, IScriptEnvironment* env)\n{\n  // called as s+ or s+[Utf8]b\n  const bool bHasUTF8param = args.IsArray() && args.ArraySize() == 2 && args[1].IsBool();\n  const bool bUtf8 = bHasUTF8param ? args[1].AsBool(false) : false;\n\n  args = args[0];\n  AVSValue result;\n\n  InternalEnvironment *envi = static_cast<InternalEnvironment*>(env);\n  const bool MainScript = (envi->IncrImportDepth() == 1);\n\n  AVSValue lastScriptName = env->GetVarDef(\"$ScriptName$\");\n  AVSValue lastScriptFile = env->GetVarDef(\"$ScriptFile$\");\n  AVSValue lastScriptDir  = env->GetVarDef(\"$ScriptDir$\");\n\n  AVSValue lastScriptNameUtf8 = env->GetVarDef(\"$ScriptNameUtf8$\");\n  AVSValue lastScriptFileUtf8 = env->GetVarDef(\"$ScriptFileUtf8$\");\n  AVSValue lastScriptDirUtf8 = env->GetVarDef(\"$ScriptDirUtf8$\");\n\n  for (int i = 0; i < args.ArraySize(); ++i) {\n    const char* script_name = args[i].AsString();\n\n#ifdef AVS_WINDOWS\n    /* Linux, macOS, pretty much every OS aside from Windows uses\n       UTF-8 pervasively and by default, making all the Ansi<->Unicode\n       stuff we have to specially handle on Windows (which uses UTF-16\n       when it does 'Unicode', further complicating things if you don't\n       force UTF-8) irrelevant. */\n\n      // Handling utf8 and ansi, working in wchar_t internally\n      // filename and path can be full unicode\n      // unicode input can come from CAVIFileSynth\n\n    std::unique_ptr<wchar_t[]> full_path_w;\n    wchar_t *file_part_w;\n\n    // make wchar_t full path strnig from either ansi or utf8\n    auto script_name_w = !bUtf8 ? AnsiToWideChar(script_name) : Utf8ToWideChar(script_name);\n\n    // Long (>MAX_PATH) path support starting in Windows 10, version 1607.\n    if (wcschr(script_name_w.get(), '\\\\') || wcschr(script_name_w.get(), '/')) {\n      DWORD len = GetFullPathNameW(script_name_w.get(), 0, NULL, NULL); // buffer size for path + terminating zero\n      full_path_w = std::make_unique<wchar_t[]>(len);\n      len = GetFullPathNameW(script_name_w.get(), len, full_path_w.get(), &file_part_w);\n      if (len == 0) {\n        auto script_name_utf8 = WideCharToUtf8(script_name_w.get());\n        env->ThrowError(\"Import: unable to open \\\"%s\\\" (path invalid?), error=0x%x\", script_name_utf8.get(), GetLastError());\n      }\n    }\n    else {\n      DWORD len = SearchPathW(NULL, script_name_w.get(), NULL, 0, NULL, NULL); // buffer size for path + terminating zero\n      full_path_w = std::make_unique<wchar_t[]>(len);\n      len = SearchPathW(NULL, script_name_w.get(), NULL, len, full_path_w.get(), &file_part_w);\n      if (len == 0) {\n        auto script_name_utf8 = WideCharToUtf8(script_name_w.get());\n        env->ThrowError(\"Import: unable to locate \\\"%s\\\" (try specifying a path), error=0x%x\", script_name_utf8.get(), GetLastError());\n      }\n    }\n\n    // back to 8 bit Ansi and Utf8\n    auto full_path = WideCharToAnsi(full_path_w.get());\n    auto full_path_utf8 = WideCharToUtf8(full_path_w.get());\n    auto file_part = WideCharToAnsi(file_part_w);\n    auto file_part_utf8 = WideCharToUtf8(file_part_w);\n    size_t dir_part_len = wcslen(full_path_w.get()) - wcslen(file_part_w);\n    auto dir_part = WideCharToAnsi_maxn(full_path_w.get(), dir_part_len);\n    auto dir_part_utf8 = WideCharToUtf8_maxn(full_path_w.get(), dir_part_len);\n\n    // supply L\"\\\\\\\\?\\\\\" if necessary for long file path support\n    std::wstring full_path_ex = std::wstring(full_path_w.get());\n    if (full_path_ex.length() > FILENAME_MAX && full_path_ex.substr(0, 4) != L\"\\\\\\\\?\\\\\")\n      full_path_ex = L\"\\\\\\\\?\\\\\" + full_path_ex;\n\n    HANDLE h = ::CreateFileW(full_path_ex.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);\n    if (h == INVALID_HANDLE_VALUE)\n      env->ThrowError(\"Import: couldn't open \\\"%s\\\"\", full_path.get());\n\n    env->SetGlobalVar(\"$ScriptName$\", env->SaveString(full_path.get()));\n    env->SetGlobalVar(\"$ScriptFile$\", env->SaveString(file_part.get()));\n    env->SetGlobalVar(\"$ScriptDir$\", env->SaveString(dir_part.get()));\n    env->SetGlobalVar(\"$ScriptNameUtf8$\", env->SaveString(full_path_utf8.get()));\n    env->SetGlobalVar(\"$ScriptFileUtf8$\", env->SaveString(file_part_utf8.get()));\n    env->SetGlobalVar(\"$ScriptDirUtf8$\", env->SaveString(dir_part_utf8.get()));\n    if (MainScript)\n    {\n      env->SetGlobalVar(\"$MainScriptName$\", env->SaveString(full_path.get()));\n      env->SetGlobalVar(\"$MainScriptFile$\", env->SaveString(file_part.get()));\n      env->SetGlobalVar(\"$MainScriptDir$\", env->SaveString(dir_part.get()));\n      env->SetGlobalVar(\"$MainScriptNameUtf8$\", env->SaveString(full_path_utf8.get()));\n      env->SetGlobalVar(\"$MainScriptFileUtf8$\", env->SaveString(file_part_utf8.get()));\n      env->SetGlobalVar(\"$MainScriptDirUtf8$\", env->SaveString(dir_part_utf8.get()));\n    }\n\n    *file_part_w = 0; // trunc full_path_w to dir-only\n    CWDChanger change_cwd(full_path_w.get());\n    // end of filename parsing / file open things\n\n    DWORD size = GetFileSize(h, NULL);\n    std::vector<char> buf(size + 1, 0);\n    bool status = ReadFile(h, buf.data(), size, &size, NULL);\n    CloseHandle(h);\n    if (!status)\n      env->ThrowError(\"Import: unable to read \\\"%s\\\"\", script_name);\n\n    // Give poor Unicode users a hint they need to use ANSI encoding import\"\n    if (size >= 2) {\n      unsigned char* q = reinterpret_cast<unsigned char*>(buf.data());\n\n      if ((q[0] == 0xFF && q[1] == 0xFE) || (q[0] == 0xFE && q[1] == 0xFF))\n        env->ThrowError(\"Import: Unicode source files are not supported, \"\n          \"re-save script with ANSI or UTF8 w/o BOM encoding! : \\\"%s\\\"\", script_name);\n\n      if (q[0] == 0xEF && q[1] == 0xBB && q[2] == 0xBF)\n        env->ThrowError(\"Import: UTF-8 source files with BOM are not supported, \"\n          \"re-save script with ANSI or UTF8 w/o BOM encoding! : \\\"%s\\\"\", script_name);\n    }\n\n#else // adapted from AvxSynth\n    std::string file_part = fs::path(script_name).filename().string();\n    std::string full_path = fs::path(script_name).remove_filename();\n    std::string dir_part = fs::path(script_name).parent_path();\n\n    FILE* h = fopen(script_name, \"r\");\n    if(NULL == h)\n      env->ThrowError(\"Import: couldn't open \\\"%s\\\"\", script_name );\n\n    env->SetGlobalVar(\"$ScriptName$\", env->SaveString(script_name));\n    env->SetGlobalVar(\"$ScriptFile$\", env->SaveString(file_part.c_str()));\n    env->SetGlobalVar(\"$ScriptDir$\", env->SaveString(full_path.c_str()));\n    env->SetGlobalVar(\"$ScriptNameUtf8$\", env->SaveString(script_name));\n    env->SetGlobalVar(\"$ScriptFileUtf8$\", env->SaveString(file_part.c_str()));\n    env->SetGlobalVar(\"$ScriptDirUtf8$\", env->SaveString(full_path.c_str()));\n    if (MainScript)\n    {\n      env->SetGlobalVar(\"$MainScriptName$\", env->SaveString(script_name));\n      env->SetGlobalVar(\"$MainScriptFile$\", env->SaveString(file_part.c_str()));\n      env->SetGlobalVar(\"$MainScriptDir$\", env->SaveString(full_path.c_str()));\n      env->SetGlobalVar(\"$MainScriptNameUtf8$\", env->SaveString(script_name));\n      env->SetGlobalVar(\"$MainScriptFileUtf8$\", env->SaveString(file_part.c_str()));\n      env->SetGlobalVar(\"$MainScriptDirUtf8$\", env->SaveString(full_path.c_str()));\n    }\n\n    //*file_part = 0; // trunc full_path to dir-only\n    CWDChanger change_cwd(full_path.c_str());\n    // end of filename parsing / file open things\n\n    fseek(h, 0, SEEK_END);\n    size_t size = ftell(h);\n    fseek(h, 0, SEEK_SET);\n\n    std::vector<char> buf(size + 1, 0);\n    if(size != fread(buf.data(), 1, size, h))\n      env->ThrowError(\"Import: unable to read \\\"%s\\\"\", script_name);\n\n    fclose(h);\n#endif\n\n    buf[size] = 0;\n    AVSValue eval_args[] = { buf.data(), script_name };\n    result = env->Invoke(\"Eval\", AVSValue(eval_args, 2));\n    //env->ThrowError(\"Import: test %s size %d\\n\", buf.data(), (int)size);\n  }\n\n  env->SetGlobalVar(\"$ScriptName$\", lastScriptName);\n  env->SetGlobalVar(\"$ScriptFile$\", lastScriptFile);\n  env->SetGlobalVar(\"$ScriptDir$\",  lastScriptDir);\n  env->SetGlobalVar(\"$ScriptNameUtf8$\", lastScriptNameUtf8);\n  env->SetGlobalVar(\"$ScriptFileUtf8$\", lastScriptFileUtf8);\n  env->SetGlobalVar(\"$ScriptDirUtf8$\", lastScriptDirUtf8);\n  envi->DecrImportDepth();\n\n  return result;\n}\n\n\nAVSValue ScriptName(AVSValue args, void*, IScriptEnvironment* env) { return env->GetVarDef(\"$ScriptName$\"); }\nAVSValue ScriptFile(AVSValue args, void*, IScriptEnvironment* env) { return env->GetVarDef(\"$ScriptFile$\"); }\nAVSValue ScriptDir (AVSValue args, void*, IScriptEnvironment* env) { return env->GetVarDef(\"$ScriptDir$\" ); }\nAVSValue ScriptNameUtf8(AVSValue args, void*, IScriptEnvironment* env) { return env->GetVarDef(\"$ScriptNameUtf8$\"); }\nAVSValue ScriptFileUtf8(AVSValue args, void*, IScriptEnvironment* env) { return env->GetVarDef(\"$ScriptFileUtf8$\"); }\nAVSValue ScriptDirUtf8(AVSValue args, void*, IScriptEnvironment* env) { return env->GetVarDef(\"$ScriptDirUtf8$\"); }\nAVSValue SetWorkingDir(AVSValue args, void*, IScriptEnvironment* env) { return env->SetWorkingDir(args[0].AsString()); }\n\nAVSValue Muldiv(AVSValue args, void*, IScriptEnvironment* ) {\n  // designed for 32 bits, no change other than read int64 parameters, \n  // though they are caster back immediately to int\n  auto result = MulDiv((int)args[0].AsLong(), (int)args[1].AsLong(), (int)args[2].AsLong());\n  return (int)result;\n}\n\n// v11: up to int64 range\nAVSValue Floor(AVSValue args, void*, IScriptEnvironment* ) { \n  int64_t result = static_cast<int64_t>(floor(args[0].AsFloat()));\n  if (result >= INT_MIN && result <= INT_MAX)\n    return (int)result;\n  return result;\n}\n// v11: up to int64 range\nAVSValue Ceil(AVSValue args, void*, IScriptEnvironment* ) { \n  int64_t result = static_cast<int64_t>(ceil(args[0].AsFloat()));\n  if (result >= INT_MIN && result <= INT_MAX)\n    return (int)result;\n  return result;\n}\n// v11: up to int64 range\nAVSValue Round(AVSValue args, void*, IScriptEnvironment* ) { \n  int64_t result = args[0].AsFloat() < 0 ? -static_cast<int64_t>(-args[0].AsFloat() + .5) : static_cast<int64_t>(args[0].AsFloat() + .5);\n  if (result >= INT_MIN && result <= INT_MAX)\n    return (int)result;\n  return result;\n}\n\nAVSValue Acos(AVSValue args, void* , IScriptEnvironment* ) { return acos(args[0].AsFloat()); }\nAVSValue Asin(AVSValue args, void* , IScriptEnvironment* ) { return asin(args[0].AsFloat()); }\nAVSValue Atan(AVSValue args, void* , IScriptEnvironment* ) { return atan(args[0].AsFloat()); }\nAVSValue Atan2(AVSValue args, void* , IScriptEnvironment* ) { return atan2(args[0].AsFloat(), args[1].AsFloat()); }\nAVSValue Cos(AVSValue args, void* , IScriptEnvironment* ) { return cos(args[0].AsFloat()); }\nAVSValue Cosh(AVSValue args, void* , IScriptEnvironment* ) { return cosh(args[0].AsFloat()); }\nAVSValue Exp(AVSValue args, void* , IScriptEnvironment* ) { return exp(args[0].AsFloat()); }\nAVSValue Fmod(AVSValue args, void* , IScriptEnvironment* ) { return fmod(args[0].AsFloat(), args[1].AsFloat()); }\nAVSValue Log(AVSValue args, void* , IScriptEnvironment* ) { return log(args[0].AsFloat()); }\nAVSValue Log10(AVSValue args, void* , IScriptEnvironment* ) { return log10(args[0].AsFloat()); }\nAVSValue Pow(AVSValue args, void* , IScriptEnvironment* ) { return pow(args[0].AsFloat(),args[1].AsFloat()); }\nAVSValue Sin(AVSValue args, void* , IScriptEnvironment* ) { return sin(args[0].AsFloat()); }\nAVSValue Sinh(AVSValue args, void* , IScriptEnvironment* ) { return sinh(args[0].AsFloat()); }\nAVSValue Tan(AVSValue args, void* , IScriptEnvironment* ) { return tan(args[0].AsFloat()); }\nAVSValue Tanh(AVSValue args, void* , IScriptEnvironment* ) { return tanh(args[0].AsFloat()); }\nAVSValue Sqrt(AVSValue args, void* , IScriptEnvironment* ) { return sqrt(args[0].AsFloat()); }\n\n// v11: up to int64 range\nAVSValue Abs(AVSValue args, void* , IScriptEnvironment* ) { \n  int64_t result = std::abs(args[0].AsLong());\n  if (result >= INT_MIN && result <= INT_MAX)\n    return (int)result;\n  return result;\n}\nAVSValue FAbs(AVSValue args, void* , IScriptEnvironment* ) { return fabs(args[0].AsFloat()); }\nAVSValue Pi(AVSValue args, void* , IScriptEnvironment* )  { return 3.14159265358979324; }\n#ifdef OPT_ScriptFunctionTau\nAVSValue Tau(AVSValue args, void* , IScriptEnvironment* ) { return 6.28318530717958648; }\n#endif\nAVSValue Sign(AVSValue args, void*, IScriptEnvironment* ) { return args[0].AsFloat()==0 ? 0 : args[0].AsFloat() > 0 ? 1 : -1; }\n\n// v11: These bitwise functions are strictly for 32 bit, if 64 bit versions are implemented they will have different names\n\nAVSValue BitAnd(AVSValue args, void*, IScriptEnvironment* ) { return args[0].AsInt() & args[1].AsInt(); }\nAVSValue BitNot(AVSValue args, void*, IScriptEnvironment* ) { return ~args[0].AsInt(); }\nAVSValue BitOr(AVSValue args, void*, IScriptEnvironment* )  { return args[0].AsInt() | args[1].AsInt(); }\nAVSValue BitXor(AVSValue args, void*, IScriptEnvironment* ) { return args[0].AsInt() ^ args[1].AsInt(); }\n\nAVSValue BitAnd64(AVSValue args, void*, IScriptEnvironment*) { return args[0].AsLong() & args[1].AsLong(); }\nAVSValue BitNot64(AVSValue args, void*, IScriptEnvironment*) { return ~args[0].AsLong(); }\nAVSValue BitOr64(AVSValue args, void*, IScriptEnvironment*) { return args[0].AsLong() | args[1].AsLong(); }\nAVSValue BitXor64(AVSValue args, void*, IScriptEnvironment*) { return args[0].AsLong() ^ args[1].AsLong(); }\n\nAVSValue BitLShift(AVSValue args, void*, IScriptEnvironment* ) { return args[0].AsInt() << args[1].AsInt(); }\nAVSValue BitRShiftL(AVSValue args, void*, IScriptEnvironment* ) { return int(unsigned(args[0].AsInt()) >> unsigned(args[1].AsInt())); }\nAVSValue BitRShiftA(AVSValue args, void*, IScriptEnvironment* ) { return args[0].AsInt() >> args[1].AsInt(); }\n\nAVSValue BitLShift64(AVSValue args, void*, IScriptEnvironment*) { return args[0].AsLong() << args[1].AsInt(); }\nAVSValue BitRShift64L(AVSValue args, void*, IScriptEnvironment*) { return int64_t(uint64_t(args[0].AsLong()) >> unsigned(args[1].AsInt())); }\nAVSValue BitRShift64A(AVSValue args, void*, IScriptEnvironment*) { return args[0].AsLong() >> args[1].AsInt(); }\n\nstatic unsigned int a_rol(unsigned int value, int shift) {\n  if ((shift &= sizeof(value)*8 - 1) == 0)\n      return value;\n  return (value << shift) | (value >> (sizeof(value)*8 - shift));\n}\nstatic uint64_t a_rol(uint64_t value, int shift) {\n  if ((shift &= sizeof(value) * 8 - 1) == 0)\n    return value;\n  return (value << shift) | (value >> (sizeof(value) * 8 - shift));\n}\n\nstatic unsigned int a_ror(unsigned int value, int shift) {\n  if ((shift &= sizeof(value)*8 - 1) == 0)\n      return value;\n  return (value >> shift) | (value << (sizeof(value)*8 - shift));\n}\nstatic uint64_t a_ror(uint64_t value, int shift) {\n  if ((shift &= sizeof(value) * 8 - 1) == 0)\n    return value;\n  return (value >> shift) | (value << (sizeof(value) * 8 - shift));\n}\n\nstatic int a_btc(int value, int bit) {\n  value ^= 1 << bit;\n  return value;\n}\nstatic int64_t a_btc(int64_t value, int bit) {\n  value ^= static_cast<int64_t>(1) << bit;\n  return value;\n}\n\nstatic int a_btr(int value, int bit) {\n  value &= ~(1 << bit);\n  return value;\n}\nstatic int64_t a_btr(int64_t value, int bit) {\n  value &= ~(static_cast<int64_t>(1) << bit);\n  return value;\n}\n\nstatic int a_bts(int value, int bit) {\n  value |= (1 << bit);\n  return value;\n}\nstatic int64_t a_bts(int64_t value, int bit) {\n  value |= (static_cast<int64_t>(1) << bit);\n  return value;\n}\n\nstatic bool a_bt(int value, int bit) {\n  return (value & (1 << bit)) ? true : false;\n}\nstatic bool a_bt(int64_t value, int bit) {\n  return (value & (static_cast<int64_t>(1)<< bit)) ? true : false;\n}\n\nAVSValue BitRotateL(AVSValue args, void*, IScriptEnvironment* ) { return (int)a_rol((unsigned int)args[0].AsInt(), args[1].AsInt()); }\nAVSValue BitRotateR(AVSValue args, void*, IScriptEnvironment* ) { return (int)a_ror((unsigned int)args[0].AsInt(), args[1].AsInt()); }\nAVSValue BitRotate64L(AVSValue args, void*, IScriptEnvironment*) { return (int64_t)a_rol((uint64_t)args[0].AsLong(), args[1].AsInt()); }\nAVSValue BitRotate64R(AVSValue args, void*, IScriptEnvironment*) { return (int64_t)a_ror((uint64_t)args[0].AsLong(), args[1].AsInt()); }\n\nAVSValue BitChg(AVSValue args, void*, IScriptEnvironment* ) { return a_btc(args[0].AsInt(), args[1].AsInt()); }\nAVSValue BitClr(AVSValue args, void*, IScriptEnvironment* ) { return a_btr(args[0].AsInt(), args[1].AsInt()); }\nAVSValue BitSet(AVSValue args, void*, IScriptEnvironment* ) { return a_bts(args[0].AsInt(), args[1].AsInt()); }\nAVSValue BitTst(AVSValue args, void*, IScriptEnvironment* ) { return a_bt (args[0].AsInt(), args[1].AsInt()); }\nAVSValue BitChg64(AVSValue args, void*, IScriptEnvironment*) { return a_btc(args[0].AsLong(), args[1].AsInt()); }\nAVSValue BitClr64(AVSValue args, void*, IScriptEnvironment*) { return a_btr(args[0].AsLong(), args[1].AsInt()); }\nAVSValue BitSet64(AVSValue args, void*, IScriptEnvironment*) { return a_bts(args[0].AsLong(), args[1].AsInt()); }\nAVSValue BitTst64(AVSValue args, void*, IScriptEnvironment*) { return a_bt(args[0].AsLong(), args[1].AsInt()); }\n\nstatic int numberOfSetBits(uint32_t i)\n{\n  i = i - ((i >> 1) & 0x55555555);\n  i = (i & 0x33333333) + ((i >> 2) & 0x33333333);\n  return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;\n}\n\nstatic int numberOfSetBits64(uint64_t i) {\n  return static_cast<int>(std::bitset<64>(i).count());\n}\n\nAVSValue BitSetCount(AVSValue args, void*, IScriptEnvironment*) {\n  if (args[0].IsInt())\n    return numberOfSetBits(static_cast<uint32_t>(args[0].AsInt()));\n  // multiple integer parameters\n  int count = 0;\n  for (int i = 0; i < args[0].ArraySize(); i++)\n    count += numberOfSetBits(static_cast<uint32_t>(args[0][i].AsInt()));\n  return count;\n}\n\nAVSValue BitSetCount64(AVSValue args, void*, IScriptEnvironment*) {\n  if (args[0].IsInt())\n    return numberOfSetBits64(static_cast<uint64_t>(args[0].AsLong()));\n  // multiple integer parameters\n  int count = 0;\n  for (int i = 0; i < args[0].ArraySize(); i++)\n    count += numberOfSetBits64(static_cast<uint64_t>(args[0][i].AsLong()));\n  return count;\n}\n\nstatic const char* toUpperCase(const char* string) {\n  // Make a temporary copy of the string\n  char* tmp = _strdup(string);\n  if (tmp == nullptr) {\n    return nullptr;\n  }\n  // Convert the copy to uppercase\n  _strupr(tmp);\n  return tmp;\n}\nAVSValue UCase(AVSValue args, void*, IScriptEnvironment* env) { \n  const char *res = toUpperCase(args[0].AsString());\n  if(res == nullptr)\n    env->ThrowError(\"UCase: memory allocation error\");\n  AVSValue result = env->SaveString(res);\n  free((void*)res);\n  return result;\n}\nstatic const char* toLowerCase(const char* string) {\n  // Make a temporary copy of the string\n  char* tmp = _strdup(string);\n  if (tmp == nullptr) {\n    return nullptr;\n  }\n  // Convert the copy to lowercase\n  _strlwr(tmp);\n  return tmp;\n}\nAVSValue LCase(AVSValue args, void*, IScriptEnvironment* env) {\n  const char* res = toLowerCase(args[0].AsString());\n  if (res == nullptr)\n    env->ThrowError(\"LCase: memory allocation error\");\n  AVSValue result = env->SaveString(res);\n  free((void*)res);\n  return result;\n}\n\nAVSValue StrLen(AVSValue args, void*, IScriptEnvironment* ) { \n  size_t len = strlen(args[0].AsString());\n  if (len > static_cast<size_t>(std::numeric_limits<int>::max()))\n    return static_cast<int64_t>(len);\n  else\n    return static_cast<int>(len);\n}\nstatic const char* toReversed(const char* string) {\n  // Make a temporary copy of the string\n  char* tmp = _strdup(string);\n  if (tmp == nullptr) {\n    return nullptr;\n  }\n  // reverse the copy\n  _strrev(tmp);\n  return tmp;\n}\n\nAVSValue RevStr(AVSValue args, void*, IScriptEnvironment* env) { \n  const char* res = toReversed(args[0].AsString());\n  if (res == nullptr)\n    env->ThrowError(\"RevStr: memory allocation error\");\n  AVSValue result = env->SaveString(res);\n  free((void*)res);\n  return result;\n}\n\nAVSValue LeftStr(AVSValue args, void*, IScriptEnvironment* env)\n{\n  const int64_t _count = args[1].AsLong();\n  if (_count < 0) {\n    env->ThrowError(\"LeftStr: Negative character count not allowed\");\n  }\n  if (static_cast<uint64_t>(_count) > std::numeric_limits<size_t>::max() - 1) {\n    env->ThrowError(\"LeftStr: Character count exceeds maximum allowed value\");\n  }\n  const size_t count = static_cast<size_t>(_count);\n\n  char* result = new(std::nothrow) char[count + 1];\n  if (!result) env->ThrowError(\"LeftStr: malloc failure (%zu bytes)!\", count + 1);\n  strncpy(result, args[0].AsString(), count);\n  result[count] = '\\0'; // Ensure null termination\n  AVSValue ret = env->SaveString(result);\n  delete[] result;\n  return ret;\n}\n\nAVSValue MidStr(AVSValue args, void*, IScriptEnvironment* env)\n{\n  const size_t maxlen = strlen(args[0].AsString());\n\n  if (args[1].AsLong() < 1)\n      env->ThrowError(\"MidStr: Illegal character location. Positions start with 1.\");\n\n  if (static_cast<uint64_t>(args[1].AsLong() - 1) > std::numeric_limits<size_t>::max() - 1)\n    env->ThrowError(\"MidStr: Offset exceeds maximum allowed value\");\n\n  size_t offset = static_cast<size_t>(args[1].AsLong() - 1); // pos=1 specifies start.\n\n  int64_t _len = args[2].AsLong(maxlen);\n  if (_len < 0)\n      env->ThrowError(\"MidStr: Character count cannot be negative\");\n  if (maxlen <= offset) { offset = 0; _len = 0;}\n\n  if (static_cast<uint64_t>(_len) > std::numeric_limits<size_t>::max() - 1)\n    env->ThrowError(\"MidStr: Character count exceeds maximum allowed value\");\n  size_t len = static_cast<size_t>(_len);\n\n  if (offset + len > maxlen)\n    len = maxlen - offset; // though strncpy handles premature string end\n\n  char *result = new(std::nothrow) char[len + 1];\n  if (!result) env->ThrowError(\"MidStr: malloc failure (%zu bytes)!\", len + 1);\n  strncpy(result, args[0].AsString() + offset, len);\n  result[len] = '\\0';\n\n  AVSValue ret = env->SaveString(result);\n  delete[] result;\n  return ret;\n}\n\nAVSValue RightStr(AVSValue args, void*, IScriptEnvironment* env)\n{\n  const int64_t _count = args[1].AsLong();\n  if (_count < 0)\n    env->ThrowError(\"RightStr: Negative character count not allowed\");\n\n  if (static_cast<uint64_t>(_count) > std::numeric_limits<size_t>::max() - 1)\n    env->ThrowError(\"RightStr: Character count exceeds maximum allowed value\");\n\n  size_t count = static_cast<size_t>(_count);\n  const size_t len = strlen(args[0].AsString());\n  if (count > len)\n    count = len;\n  // no error given, limit to string length\n  // env->ThrowError(\"RightStr: Character count (%zu) exceeds string length (%zu)\", count, len);\n\n  const size_t offset = len - count;\n\n  char* result = new(std::nothrow) char[count + 1];\n  if (!result) env->ThrowError(\"RightStr: memory allocation failure (%zu bytes)!\", count + 1);\n  strncpy(result, args[0].AsString() + offset, count);\n  result[count] = '\\0';\n\n  AVSValue ret = env->SaveString(result);\n  delete[] result;\n  return ret;\n}\n\nAVSValue ReplaceStr(AVSValue args, void*, IScriptEnvironment* env) {\n  char const * const original = args[0].AsString();\n  char const * const pattern = args[1].AsString();\n  char const * const replacement = args[2].AsString();\n  const bool case_insensitive = args[3].AsBool(false);\n\n  const size_t replace_len = strlen(replacement);\n  const size_t pattern_len = strlen(pattern);\n  const size_t orig_len = strlen(original);\n\n  size_t pattern_count = 0;\n  const char * orig_ptr;\n  const char * pattern_location;\n\n  if (0 == pattern_len)\n    return original;\n\n  if (case_insensitive) {\n    char *original_lower = new(std::nothrow) char[sizeof(char) * (orig_len + 1)];\n    if (!original_lower) env->ThrowError(\"ReplaceStr: malloc failure!\");\n    char *pattern_lower = new(std::nothrow) char[sizeof(char) * (pattern_len + 1)];\n    if (!pattern_lower) env->ThrowError(\"ReplaceStr: malloc failure!\");\n\n    // make them lowercase for comparison\n    strcpy(original_lower, original);\n    strcpy(pattern_lower, pattern);\n#ifdef MSVC\n    // works fine also for accented ANSI characters\n    _locale_t locale = _create_locale(LC_ALL, \".ACP\"); // Sets the locale to the ANSI code page obtained from the operating system.\n    _strlwr_l(original_lower, locale);\n    _strlwr_l(pattern_lower, locale);\n    _free_locale(locale);\n#else\n    _strlwr(original_lower);\n    _strlwr(pattern_lower);\n#endif\n\n    // find how many times the _lowercased_ pattern occurs in the _lowercased_ original string\n    for (orig_ptr = original_lower; (pattern_location = strstr(orig_ptr, pattern_lower)); orig_ptr = pattern_location + pattern_len)\n    {\n      pattern_count++;\n    }\n\n    // allocate memory for the new string\n    size_t const retlen = orig_len + pattern_count * (replace_len - pattern_len);\n    char *result = new(std::nothrow) char[sizeof(char) * (retlen + 1)];\n    if (!result) env->ThrowError(\"ReplaceStr: malloc failure!\");\n    *result = 0;\n\n    // copy the original string,\n    // replacing all the instances of the pattern\n    const char * orig_upper_ptr;\n    char * result_ptr = result;\n    // handling dual pointer set: orig, uppercase\n    for (orig_ptr = original, orig_upper_ptr = original_lower;\n      (pattern_location = strstr(orig_upper_ptr, pattern_lower));\n      orig_upper_ptr = pattern_location + pattern_len, orig_ptr = original + (orig_upper_ptr - original_lower))\n    {\n      const size_t skiplen = pattern_location - orig_upper_ptr;\n      // copy the section until the occurence of the pattern\n      strncpy(result_ptr, orig_ptr, skiplen);\n      result_ptr += skiplen;\n      // copy the replacement\n      strncpy(result_ptr, replacement, replace_len);\n      result_ptr += replace_len;\n    }\n    // copy rest\n    strcpy(result_ptr, orig_ptr);\n    AVSValue ret = env->SaveString(result);\n    delete[] result;\n    delete[] original_lower;\n    delete[] pattern_lower;\n    return ret;\n  }\n\n  // old case sensitive version\n\n    // find how many times the pattern occurs in the original string\n  for (orig_ptr = original; (pattern_location = strstr(orig_ptr, pattern)); orig_ptr = pattern_location + pattern_len)\n  {\n    pattern_count++;\n  }\n\n  // allocate memory for the new string\n  size_t const retlen = orig_len + pattern_count * (replace_len - pattern_len);\n  char *result = new(std::nothrow) char[sizeof(char) * (retlen + 1)];\n  if (!result) env->ThrowError(\"ReplaceStr: malloc failure!\");\n  *result = 0;\n\n  // copy the original string,\n  // replacing all the instances of the pattern\n  char * result_ptr = result;\n  for (orig_ptr = original; (pattern_location = strstr(orig_ptr, pattern)); orig_ptr = pattern_location + pattern_len)\n  {\n    const size_t skiplen = pattern_location - orig_ptr;\n    // copy the section until the occurence of the pattern\n    strncpy(result_ptr, orig_ptr, skiplen);\n    result_ptr += skiplen;\n    // copy the replacement\n    strncpy(result_ptr, replacement, replace_len);\n    result_ptr += replace_len;\n  }\n  // copy rest\n  strcpy(result_ptr, orig_ptr);\n  AVSValue ret = env->SaveString(result);\n  delete[] result;\n  return ret;\n}\n\nAVSValue TrimLeft(AVSValue args, void*, IScriptEnvironment* env)\n{\n  char const *original = args[0].AsString();\n  char const *s = original;\n  char ch;\n  // space, npsp, tab\n  while ((ch = *s) == (char)32 || ch == (char)160 || ch == (char)9)\n    s++;\n\n  if (original == s)\n    return args[0]; // avoid SaveString if no change\n\n  return env->SaveString(s);\n}\n\nAVSValue TrimRight(AVSValue args, void*, IScriptEnvironment* env)\n{\n  char const *original = args[0].AsString();\n  size_t len = strlen(original);\n  if (len == 0)\n    return args[0]; // avoid SaveString if no change\n\n  size_t orig_len = len;\n  char const *s = original + len;\n\n  char ch;\n  // space, npsp, tab\n  while ((len > 0) && ((ch = *--s) == (char)32 || ch == (char)160 || ch == (char)9)) {\n    len--;\n  }\n\n  if(orig_len == len)\n    return args[0]; // avoid SaveString if no change\n\n  if (len == 0)\n    return env->SaveString(\"\");\n\n  size_t retlen = s - original + 1;\n\n  char *result = new(std::nothrow) char[sizeof(char) * (retlen + 1)];\n  if (!result) env->ThrowError(\"TrimRight: malloc failure!\");\n  strncpy(result, original, retlen);\n  result[retlen] = 0;\n\n  AVSValue ret = env->SaveString(result);\n  delete[] result;\n  return ret;\n}\n\nAVSValue TrimAll(AVSValue args, void*, IScriptEnvironment* env)\n{\n  // not simplify with calling Left/Right, avoid double SaveStrings\n\n  // like TrimLeft\n  char const *original = args[0].AsString();\n  if (!*original)\n    return args[0]; // avoid SaveString if no change\n\n  char ch;\n  // space, npsp, tab\n  while ((ch = *original) == (char)32 || ch == (char)160 || ch == (char)9)\n    original++;\n\n  // almost like TrimRight\n  size_t len = strlen(original);\n  if (len == 0)\n    return env->SaveString(\"\");\n\n  size_t orig_len = len;\n  char const *s = original + len;\n\n  // space, npsp, tab\n  while ((len > 0) && ((ch = *--s) == (char)32 || ch == (char)160 || ch == (char)9))\n    len--;\n\n  if (orig_len == len)\n    return env->SaveString(original); // nothing to cut from right\n\n  if (len == 0)\n    return env->SaveString(\"\"); // full cut\n\n  size_t retlen = s - original + 1;\n\n  char *result = new(std::nothrow) char[sizeof(char) * (retlen + 1)];\n  if (!result) env->ThrowError(\"TrimAll: malloc failure!\");\n  strncpy(result, original, retlen);\n  result[retlen] = 0;\n\n  AVSValue ret = env->SaveString(result);\n  delete[] result;\n  return ret;\n}\n\n\nAVSValue StrCmp(AVSValue args, void*, IScriptEnvironment*)\n{\n  return lstrcmp( args[0].AsString(), args[1].AsString() );\n}\n\nAVSValue StrCmpi(AVSValue args, void*, IScriptEnvironment*)\n{\n  return lstrcmpi( args[0].AsString(), args[1].AsString() );\n}\n\nAVSValue FindStr(AVSValue args, void*, IScriptEnvironment*)\n{\n  const char *pdest = strstr( args[0].AsString(),args[1].AsString() );\n  int result = (int)(pdest - args[0].AsString() + 1);\n  if (pdest == NULL) result = 0;\n  return result;\n}\n\n// FIXME: to v11 64 bit support\nAVSValue Rand(AVSValue args, void*, IScriptEnvironment*)\n { int limit = args[0].AsInt(RAND_MAX);\n   bool scale_mode = args[1].AsBool((abs(limit) > RAND_MAX));\n\n   if (args[2].AsBool(false)) srand( (unsigned) time(NULL) ); //seed\n\n   if (scale_mode) {\n      double f = 1.0 / (RAND_MAX + 1.0);\n      return int(f * rand() * limit);\n   }\n   else { //modulus mode\n      int s = (limit < 0 ? -1 : 1);\n      if (limit==0) return 0;\n       else return s * rand() % limit;\n   }\n }\n\nAVSValue Select(AVSValue args, void*, IScriptEnvironment* env)\n{\n  // arraysize is still int\n  int64_t i = args[0].AsLong();\n  if ((args[1].ArraySize() <= i) || (i < 0) || (i > INT_MAX))\n    env->ThrowError(\"Select: Index value out of range\");\n  return args[1][static_cast<int>(i)];\n}\n\nAVSValue NOP(AVSValue args, void*, IScriptEnvironment*) { return 0;}\n\nAVSValue Undefined(AVSValue args, void*, IScriptEnvironment*) { return AVSValue();}\n\nAVSValue Exist(AVSValue args, void*, IScriptEnvironment*nv) {\n  const char *filename = args[0].AsString();\n#ifdef AVS_POSIX\n  constexpr bool utf8default = true;\n#else\n  constexpr bool utf8default = false;\n#endif\n  const bool utf8 = args[1].AsBool(utf8default);\n\n  if (strchr(filename, '*') || strchr(filename, '?')) // wildcard\n    return false;\n\n#ifdef AVS_WINDOWS\n  if (utf8) {\n    // fixme/enhance me: check win codepage 65001 UTF8 and do like posix native utf8\n    // (remark applies to all utf8 in avs+)\n    auto wsource = Utf8ToWideChar(filename);\n    std::wstring filename_w = wsource.get();\n    return fs::exists(filename_w);\n  }\n#endif\n  return fs::exists(filename);\n}\n\n\n//WE ->\n\n// Spline functions to generate and evaluate a natural bicubic spline\nvoid spline(float x[], float y[], int n, float y2[])\n{\n  int i, k;\n  float p, qn, sig, un, * u;\n\n  u = new float[n];\n\n  y2[1] = u[1] = 0.0f;\n\n  for (i = 2; i <= n - 1; i++) {\n    sig = (x[i] - x[i - 1]) / (x[i + 1] - x[i - 1]);\n    p = sig * y2[i - 1] + 2.0f;\n    y2[i] = (sig - 1.0f) / p;\n    u[i] = (y[i + 1] - y[i]) / (x[i + 1] - x[i]) - (y[i] - y[i - 1]) / (x[i] - x[i - 1]);\n    u[i] = (6.0f * u[i] / (x[i + 1] - x[i - 1]) - sig * u[i - 1]) / p;\n  }\n  qn = un = 0.0f;\n  y2[n] = (un - qn * u[n - 1]) / (qn * y2[n - 1] + 1.0f);\n  for (k = n - 1; k >= 1; k--) {\n    y2[k] = y2[k] * y2[k + 1] + u[k];\n  }\n\n  delete[] u;\n}\n\nint splint(float xa[], float ya[], float y2a[], int n, float x, float& y, bool cubic)\n{\n  int klo, khi, k;\n  float h, b, a;\n\n  klo = 1;\n  khi = n;\n  while (khi - klo > 1) {\n    k = (khi + klo) >> 1;\n    if (xa[k] > x) khi = k;\n    else klo = k;\n  }\n  h = xa[khi] - xa[klo];\n  if (h == 0.0f) {\n    y = 0.0f;\n    return -1;\t// all x's have to be different\n  }\n  a = (xa[khi] - x) / h;\n  b = (x - xa[klo]) / h;\n\n  if (cubic) {\n    y = a * ya[klo] + b * ya[khi] + ((a * a * a - a) * y2a[klo] + (b * b * b - b) * y2a[khi]) * (h * h) / 6.0f;\n  }\n  else {\n    y = a * ya[klo] + b * ya[khi];\n  }\n  return 0;\n}\n\n// the script functions\nAVSValue AVSChr(AVSValue args, void*, IScriptEnvironment* env)\n{\n  char s[2];\n\n  s[0] = (char)(args[0].AsInt());\n  s[1] = 0;\n  return env->SaveString(s);\n}\n\nAVSValue AVSOrd(AVSValue args, void*, IScriptEnvironment*)\n{\n    return (int)args[0].AsString()[0] & 0xFF;\n}\n\nAVSValue FillStr(AVSValue args, void*, IScriptEnvironment* env )\n{\n    const int64_t _count = args[0].AsLong();\n    if (_count <= 0)\n      env->ThrowError(\"FillStr: Repeat count must be greater than zero!\");\n\n    const char *str = args[1].AsString(\" \");\n    const size_t len_to_repeat = strlen(str);\n    if (len_to_repeat == 0)\n      return str;\n\n    constexpr size_t max_size_t = std::numeric_limits<size_t>::max();\n    size_t max_repeats = (max_size_t - 1) / len_to_repeat;\n\n    size_t count = static_cast<size_t>(_count);\n    if (count > max_repeats)\n      env->ThrowError(\"FillStr: too many repeats, resulting string exceeds the maximum allowed length!\");\n\n    const size_t total = count * len_to_repeat;\n\n    char *buff = new(std::nothrow) char[total+1];\n    if (!buff)\n      env->ThrowError(\"FillStr: memory allocation failure (%zu bytes)!\", total + 1);\n\n    if (len_to_repeat == 1)\n      std::fill_n(buff, total, str[0]);\n    else {\n      for (size_t i = 0; i < count; i++)\n        memcpy(buff + i * len_to_repeat, str, len_to_repeat);\n    }\n    buff[total] = '\\0';\n\n    AVSValue ret = env->SaveString(buff);\n    delete[] buff;\n    return ret;\n}\n\nAVSValue AVSTime(AVSValue args, void*, IScriptEnvironment* env)\n{\n  time_t lt_t;\n  struct tm* lt;\n  time(&lt_t);\n  lt = localtime(&lt_t);\n  char s[1024];\n  strftime(s, 1024, args[0].AsString(\"\"), lt);\n  s[1023] = 0;\n  return env->SaveString(s);\n}\n\n// FIXME: to v11 64 bit support\nAVSValue Spline(AVSValue args, void*, IScriptEnvironment* env)\n{\n  int n;\n  float x, y;\n  int i;\n  bool cubic;\n\n  AVSValue coordinates;\n\n  x = args[0].AsFloatf(0);\n  coordinates = args[1];\n  cubic = args[2].AsBool(true);\n\n  n = coordinates.ArraySize();\n\n  if (n < 4 || n & 1) env->ThrowError(\"To few arguments for Spline\");\n\n  n = n / 2;\n\n  float* buf = new float[(n + 1) * 3];\n  float* xa = &(buf[(n + 1) * 0]);\n  float* ya = &(buf[(n + 1) * 1]);\n  float* y2a = &(buf[(n + 1) * 2]);\n\n  for (i = 1; i <= n; i++) {\n    xa[i] = coordinates[(i - 1) * 2 + 0].AsFloatf(0);\n    ya[i] = coordinates[(i - 1) * 2 + 1].AsFloatf(0);\n  }\n\n  for (i = 1; i < n; i++) {\n    if (xa[i] >= xa[i + 1]) env->ThrowError(\"Spline: all x values have to be different and in ascending order!\");\n  }\n\n  spline(xa, ya, n, y2a);\n  splint(xa, ya, y2a, n, x, y, cubic);\n\n  delete[] buf;\n\n  return y;\n}\n\n// WE <-\n\nstatic inline const VideoInfo& VI(const AVSValue& arg) { return arg.AsClip()->GetVideoInfo(); }\n\nstatic const std::map<int, std::string> pixel_format_table =\n{ // names for lookup by pixel_type or name\n  {VideoInfo::CS_BGR24, \"RGB24\"},\n  {VideoInfo::CS_BGR32, \"RGB32\"},\n  {VideoInfo::CS_YUY2 , \"YUY2\"},\n  {VideoInfo::CS_YV24 , \"YV24\"},\n  {VideoInfo::CS_YV16 , \"YV16\"},\n  {VideoInfo::CS_YV12 , \"YV12\"},\n  {VideoInfo::CS_I420 , \"YV12\"},\n  {VideoInfo::CS_YUV9 , \"YUV9\"},\n  {VideoInfo::CS_YV411, \"YV411\"},\n  {VideoInfo::CS_Y8   , \"Y8\"},\n\n  {VideoInfo::CS_YUV420P10, \"YUV420P10\"},\n  {VideoInfo::CS_YUV422P10, \"YUV422P10\"},\n  {VideoInfo::CS_YUV444P10, \"YUV444P10\"},\n  {VideoInfo::CS_Y10      , \"Y10\"},\n  {VideoInfo::CS_YUV420P12, \"YUV420P12\"},\n  {VideoInfo::CS_YUV422P12, \"YUV422P12\"},\n  {VideoInfo::CS_YUV444P12, \"YUV444P12\"},\n  {VideoInfo::CS_Y12      , \"Y12\"},\n  {VideoInfo::CS_YUV420P14, \"YUV420P14\"},\n  {VideoInfo::CS_YUV422P14, \"YUV422P14\"},\n  {VideoInfo::CS_YUV444P14, \"YUV444P14\"},\n  {VideoInfo::CS_Y14      , \"Y14\"},\n  {VideoInfo::CS_YUV420P16, \"YUV420P16\"},\n  {VideoInfo::CS_YUV422P16, \"YUV422P16\"},\n  {VideoInfo::CS_YUV444P16, \"YUV444P16\"},\n  {VideoInfo::CS_Y16      , \"Y16\"},\n  {VideoInfo::CS_YUV420PS , \"YUV420PS\"},\n  {VideoInfo::CS_YUV422PS , \"YUV422PS\"},\n  {VideoInfo::CS_YUV444PS , \"YUV444PS\"},\n  {VideoInfo::CS_Y32      , \"Y32\"},\n\n  {VideoInfo::CS_BGR48    , \"RGB48\"},\n  {VideoInfo::CS_BGR64    , \"RGB64\"},\n\n  {VideoInfo::CS_RGBP     , \"RGBP\"},\n  {VideoInfo::CS_RGBP10   , \"RGBP10\"},\n  {VideoInfo::CS_RGBP12   , \"RGBP12\"},\n  {VideoInfo::CS_RGBP14   , \"RGBP14\"},\n  {VideoInfo::CS_RGBP16   , \"RGBP16\"},\n  {VideoInfo::CS_RGBPS    , \"RGBPS\"},\n\n  {VideoInfo::CS_YUVA420, \"YUVA420\"},\n  {VideoInfo::CS_YUVA422, \"YUVA422\"},\n  {VideoInfo::CS_YUVA444, \"YUVA444\"},\n  {VideoInfo::CS_YUVA420P10, \"YUVA420P10\"},\n  {VideoInfo::CS_YUVA422P10, \"YUVA422P10\"},\n  {VideoInfo::CS_YUVA444P10, \"YUVA444P10\"},\n  {VideoInfo::CS_YUVA420P12, \"YUVA420P12\"},\n  {VideoInfo::CS_YUVA422P12, \"YUVA422P12\"},\n  {VideoInfo::CS_YUVA444P12, \"YUVA444P12\"},\n  {VideoInfo::CS_YUVA420P14, \"YUVA420P14\"},\n  {VideoInfo::CS_YUVA422P14, \"YUVA422P14\"},\n  {VideoInfo::CS_YUVA444P14, \"YUVA444P14\"},\n  {VideoInfo::CS_YUVA420P16, \"YUVA420P16\"},\n  {VideoInfo::CS_YUVA422P16, \"YUVA422P16\"},\n  {VideoInfo::CS_YUVA444P16, \"YUVA444P16\"},\n  {VideoInfo::CS_YUVA420PS , \"YUVA420PS\"},\n  {VideoInfo::CS_YUVA422PS , \"YUVA422PS\"},\n  {VideoInfo::CS_YUVA444PS , \"YUVA444PS\"},\n\n  {VideoInfo::CS_RGBAP     , \"RGBAP\"},\n  {VideoInfo::CS_RGBAP10   , \"RGBAP10\"},\n  {VideoInfo::CS_RGBAP12   , \"RGBAP12\"},\n  {VideoInfo::CS_RGBAP14   , \"RGBAP14\"},\n  {VideoInfo::CS_RGBAP16   , \"RGBAP16\"},\n  {VideoInfo::CS_RGBAPS    , \"RGBAPS\"},\n};\n\nstatic const std::multimap<int, std::string> pixel_format_table_ex =\n{ // alternative names for lookup by name (multimap!)\n  {VideoInfo::CS_YV24 , \"YUV444\"},\n  {VideoInfo::CS_YV16 , \"YUV422\"},\n  {VideoInfo::CS_YV12 , \"YUV420\"},\n  {VideoInfo::CS_YV411, \"YUV411\"},\n  {VideoInfo::CS_RGBP , \"RGBP8\"},\n  {VideoInfo::CS_RGBAP, \"RGBAP8\"},\n  {VideoInfo::CS_YV24 , \"YUV444P8\"},\n  {VideoInfo::CS_YV16 , \"YUV422P8\"},\n  {VideoInfo::CS_YV12 , \"YUV420P8\"},\n  {VideoInfo::CS_YV411, \"YUV411P8\"},\n  {VideoInfo::CS_YUVA420, \"YUVA420P8\"},\n  {VideoInfo::CS_YUVA422, \"YUVA422P8\"},\n  {VideoInfo::CS_YUVA444, \"YUVA444P8\"},\n};\n\nconst char *GetPixelTypeName(const int pixel_type)\n{\n  const std::string name = \"\";\n  auto it = pixel_format_table.find(pixel_type);\n  if (it == pixel_format_table.end())\n    return \"\";\n  return (it->second).c_str();\n}\n\nint GetPixelTypeFromName(const char *pixeltypename)\n{\n  std::string name_to_find = pixeltypename;\n  for (auto & c: name_to_find) c = toupper(c); // uppercase input string\n  for (auto it = pixel_format_table.begin(); it != pixel_format_table.end(); it++)\n  {\n    if ((it->second).compare(name_to_find) == 0)\n      return it->first;\n  }\n  // find by alternative names e.g. YUV420 or YUV420P8 instead of YV12\n  for (auto it = pixel_format_table_ex.begin(); it != pixel_format_table_ex.end(); it++)\n  {\n    if ((it->second).compare(name_to_find) == 0)\n      return it->first;\n  }\n  return VideoInfo::CS_UNKNOWN;\n}\n\n\nAVSValue PixelType (AVSValue args, void*, IScriptEnvironment*) {\n  return GetPixelTypeName(VI(args[0]).pixel_type);\n}\n\n// AVS+\nAVSValue ColorSpaceNameToPixelType (AVSValue args, void*, IScriptEnvironment*) {\n  return GetPixelTypeFromName(args[0].AsString());\n}\n\nAVSValue Width(AVSValue args, void*, IScriptEnvironment*) { return VI(args[0]).width; }\nAVSValue Height(AVSValue args, void*, IScriptEnvironment*) { return VI(args[0]).height; }\nAVSValue FrameCount(AVSValue args, void*, IScriptEnvironment*) { return VI(args[0]).num_frames; }\nAVSValue FrameRate(AVSValue args, void*, IScriptEnvironment*) { const VideoInfo& vi = VI(args[0]); return (double)vi.fps_numerator / vi.fps_denominator; } // maximise available precision\nAVSValue FrameRateNumerator(AVSValue args, void*, IScriptEnvironment*) { return (int)VI(args[0]).fps_numerator; } // unsigned int truncated to int\nAVSValue FrameRateDenominator(AVSValue args, void*, IScriptEnvironment*) { return (int)VI(args[0]).fps_denominator; } // unsigned int truncated to int\nAVSValue AudioRate(AVSValue args, void*, IScriptEnvironment*) { return VI(args[0]).audio_samples_per_second; }\nAVSValue AudioLength(AVSValue args, void*, IScriptEnvironment*) { return VI(args[0]).num_audio_samples; }  // since v11 not truncated to int\nAVSValue AudioLengthLo(AVSValue args, void*, IScriptEnvironment*) { return (int)(VI(args[0]).num_audio_samples % (unsigned)args[1].AsInt(1000000000)); }\nAVSValue AudioLengthHi(AVSValue args, void*, IScriptEnvironment*) { return (int)(VI(args[0]).num_audio_samples / (unsigned)args[1].AsInt(1000000000)); }\nAVSValue AudioLengthS(AVSValue args, void*, IScriptEnvironment* env) {\n    char s[32];\n#ifdef AVS_WINDOWS\n    return env->SaveString(_i64toa(VI(args[0]).num_audio_samples, s, 10));\n#else\n    sprintf(s, \"%\" PRId64, VI(args[0]).num_audio_samples);\n    return env->SaveString(s);\n#endif\n}\nAVSValue AudioLengthF(AVSValue args, void*, IScriptEnvironment*) { return static_cast<double>(VI(args[0]).num_audio_samples); } // at least this will give an order of the size. \n// Since v11 it has of little use: AudioLength now can return int64, \n// anyway, cast to double instead of float\n\nAVSValue AudioDuration(AVSValue args, void*, IScriptEnvironment*) {\n  const VideoInfo& vi = VI(args[0]);\n  return (double)vi.num_audio_samples / vi.audio_samples_per_second;\n}\n\nAVSValue AudioChannels(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).HasAudio() ? VI(args[0]).nchannels : 0; }\nAVSValue AudioBits(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).BytesPerChannelSample()*8; }\nAVSValue IsAudioFloat(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).IsSampleType(SAMPLE_FLOAT); }\nAVSValue IsAudioInt(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).IsSampleType(SAMPLE_INT8 | SAMPLE_INT16 | SAMPLE_INT24 | SAMPLE_INT32 ); }\nAVSValue IsChannelMaskKnown(AVSValue args, void*, IScriptEnvironment*) { return VI(args[0]).IsChannelMaskKnown(); }\nAVSValue GetChannelMask(AVSValue args, void*, IScriptEnvironment*) { return (int)VI(args[0]).GetChannelMask(); }\n\nAVSValue IsRGB(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).IsRGB(); }\nAVSValue IsRGB24(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).IsRGB24(); }\nAVSValue IsRGB32(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).IsRGB32(); }\nAVSValue IsYUV(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).IsYUV(); }\nAVSValue IsYUY2(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).IsYUY2(); }\nAVSValue IsY8(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).IsY8(); }\nAVSValue IsYV12(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).IsYV12(); }\nAVSValue IsYV16(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).IsYV16(); }\nAVSValue IsYV24(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).IsYV24(); }\nAVSValue IsYV411(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).IsYV411(); }\nAVSValue IsPlanar(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).IsPlanar(); }\nAVSValue IsInterleaved(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).IsColorSpace(VideoInfo::CS_INTERLEAVED); }\nAVSValue IsFieldBased(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).IsFieldBased(); }\nAVSValue IsFrameBased(AVSValue args, void*, IScriptEnvironment*) {  return !VI(args[0]).IsFieldBased(); }\nAVSValue GetParity(AVSValue args, void*, IScriptEnvironment*) {  return args[0].AsClip()->GetParity(args[1].AsInt(0)); }\n\nAVSValue HasVideo(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).HasVideo(); }\nAVSValue HasAudio(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).HasAudio(); }\n\nAVSValue String(AVSValue args, void*, IScriptEnvironment* env)\n{\n  if (args[0].IsString()) return args[0];\n  if (args[0].IsBool()) return (args[0].AsBool() ? \"true\" : \"false\");\n  if (args[0].IsFunction()) return args[0].AsFunction()->ToString(env);\n  if (args[1].Defined()) {\n    // WE --> when a format parameter is present\n    // order! if it is an Int: IsFloat gives True\n    // If parameter exists, always convert to float\n    if (args[0].GetType() == AvsValueType::VALUE_TYPE_FLOAT) // real 32 bit float\n    {\n      return env->Sprintf(args[1].AsString(\"%f\"), args[0].AsFloatf());\n      // AsFloatf returns 32 bit float\n    }\n    else if (args[0].IsFloat()) // 32 or 64 bit integer or double\n    {\n      return env->Sprintf(args[1].AsString(\"%lf\"), args[0].AsFloat());\n      // AsFloat returns double\n    }\n    return \"\";\n  }\n  else {\n    // standard behaviour\n    if (args[0].IsLongStrict()) {\n      char s[21];\n      sprintf(s, \"%\" PRId64, args[0].AsLong());\n      return env->SaveString(s);\n    }\n    if (args[0].IsInt()) {\n      char s[12]; // with sign: worst case 11\n      sprintf(s, \"%d\", args[0].AsInt());\n      return env->SaveString(s);\n    }\n    if (args[0].IsFloat()) { // for double as well.\n      char s[50]; // safe size for double\n#ifdef MSVC\n      _locale_t locale = _create_locale(LC_NUMERIC, \"C\"); // decimal point: dot\n      _sprintf_l(s, \"%lf\", locale, args[0].AsFloat());\n      _free_locale(locale);\n#else\n      sprintf(s, \"%lf\", args[0].AsFloat());\n#endif\n      return env->SaveString(s);\n    }\n  }\n  return \"\";\n}\n\nAVSValue Hex(AVSValue args, void*, IScriptEnvironment* env)\n{\n  int n = args[0].AsInt();\n  int wid = args[1].AsInt(0); // 0..8 is the minimum width of the returned string\n  wid = (wid<0) ? 0 : (wid > 8) ? 8 : wid;\n  char buf[8 + 1];\n  sprintf_s(buf, \"%0*X\", wid, n); // uppercase, unlike <=r2580\n  return env->SaveString(buf);\n}\n\nstatic std::string AVSValue_to_string(AVSValue v, IScriptEnvironment* env) {\n  if (v.IsString()) return v.AsString();\n  if (v.IsBool()) return v.AsBool() ? \"true\" : \"false\";\n  if (v.IsFunction()) return v.AsFunction()->ToString(env);\n  if (v.IsInt()) return std::to_string(v.AsLong()); // AsLong handles both 32 and 64-bit int\n  if (v.IsFloat()) return double_to_string(v.AsFloat());\n  return \"\";\n}\n\n\n// Formatting function with parameter list with ordered, indexed or named replacements\nAVSValue FormatString(AVSValue args, void*, IScriptEnvironment* env)\n{\n  // Format(\"{} {}!\", \"Hello\", \"world\")\n  // max_pixel_value = 255\n  // Format(\"max pixel value = {max_pixel_value}!\")\n  // Format(\"Pi={1} x={0} y={0}!\", 12, Pi())\n  std::string format = args[0].AsString();\n  int numargs = args[1].ArraySize();\n\n  // (name), value pairs, name can be empty\n  std::vector<std::pair<std::string, std::string>> sv;\n  for (int i = 0; i < numargs; i++)\n  {\n    std::string name; // can be empty\n    std::string val_as_s;\n\n    AVSValue v = args[1][i];\n    // [\"name\", value] support\n    if (v.IsArray()) {\n      if (v.ArraySize() != 2 || !v[0].IsString())\n        env->ThrowError(\"Format: for key-value lookup parameter must be in [\\\"name\\\", value] array format\");\n      name = v[0].AsString();\n      v = v[1];\n    }\n\n    val_as_s = AVSValue_to_string(v, env);\n\n    sv.push_back(std::make_pair(name, val_as_s));\n  }\n\n  size_t supplied_params_count = sv.size();\n\n  size_t len = format.size();\n  size_t i = 0;\n  bool in_parenthesis = false;\n  std::string ss;\n  size_t last_pos = 0;\n  std::string last_param_section;\n\n  size_t param_counter = 0;\n\n  while (i < len) {\n    if (!in_parenthesis) {\n      size_t x = format.find_first_of('{', last_pos);\n      // }} can appear only when escaped\n      size_t cx = format.find_first_of('}', last_pos);\n      if (cx != std::string::npos && cx < x)\n      {\n        if (cx + 1 < len && format[cx + 1] == '}') // }} escaped\n        {\n          ss += format.substr(last_pos, cx - last_pos + 1);\n          last_pos = cx + 2;\n          i = last_pos;\n          continue;\n        }\n        env->ThrowError(\"Format: unbalanced curly bracket at position %zu\", cx);\n      }\n\n      if (x == std::string::npos) // { not found\n      {\n        ss += format.substr(last_pos); // copy rest\n        break;\n      }\n      else if (x + 1 < len && format[x + 1] == '{') // {{ escaped\n      {\n        ss += format.substr(last_pos, x - last_pos + 1);\n        last_pos = x + 2;\n        i = last_pos;\n      }\n      else {\n        // found {, not escaped\n        ss += format.substr(last_pos, x - last_pos);\n        last_pos = x + 1; // points to after the {\n        i = last_pos;\n        in_parenthesis = true;\n      }\n      continue;\n    } // end of not-in-bracket-mode\n\n    // in-curly-bracket: search for the closing bracket\n\n    size_t x = format.find_first_of('}', last_pos);\n    if (x == std::string::npos) // not found, will throw error outside\n      break;\n\n    last_param_section = format.substr(last_pos, x - last_pos); // name, order number or empty\n\n    if (last_param_section.empty()) {\n      // simple {}, insert next parameter, consume one from the list\n      // in c++20 you cannot mix\n      if (param_counter >= supplied_params_count)\n        env->ThrowError(\"Format: more parameter sections than parameters supplied\");\n      ss += sv[param_counter++].second;\n    }\n    else {\n      // name or number\n\n      bool validName = true;\n      // check for a valid identifier name\n      auto ch = last_param_section[0];\n      if (ch != '_' && !isalpha(ch))\n        validName = false;\n      else {\n        for (size_t i = 1; i < last_param_section.length(); i++) {\n          const char ch = last_param_section[i];\n          if (!(ch == '_' || isalnum(ch))) {\n            validName = false;\n            break;\n          }\n        }\n      }\n\n      if (!validName) {\n        // valid number like {2} to index parameters\n        int index;\n        try {\n          // string -> integer\n          index = std::stoi(last_param_section);\n        }\n        catch (...) {\n          env->ThrowError(\"Format: invalid parameter specifier: \\\"%s\\\".\", last_param_section.c_str());\n        }\n\n        if (index < 0 || index >= (int)supplied_params_count)\n          env->ThrowError(\"Format: parameter index is out of range: %d\", index);\n\n        ss += sv[index].second;\n      }\n      else {\n        // find among the named parameters\n        auto it = std::find_if(sv.begin(), sv.end(),\n          [&last_param_section](const std::pair<std::string, std::string>& element) { return element.first == last_param_section; });\n        if (it != sv.end())\n          ss += it->second; // name was found\n        else {\n          // last resort: variable with the given name\n          AVSValue v;\n          if (!env->GetVarTry(last_param_section.c_str(), &v))\n            env->ThrowError(\"Format: no parameter or variable found with name \\\"%s\\\".\", last_param_section.c_str());\n\n          std::string val_as_s = AVSValue_to_string(v, env);\n\n          ss += val_as_s;\n        }\n      }\n    }\n\n    last_pos = x + 1;\n    i = last_pos;\n    in_parenthesis = false;\n  }\n\n  if(in_parenthesis)\n    env->ThrowError(\"Format: unclosed curly bracket\");\n\n  return env->SaveString(ss.c_str());\n}\n\nAVSValue Func(AVSValue args, void*, IScriptEnvironment*) { return args[0]; }\n\nAVSValue IsBool(AVSValue args, void*, IScriptEnvironment*) {  return args[0].IsBool(); }\nAVSValue IsInt(AVSValue args, void*, IScriptEnvironment*) {  return args[0].IsInt(); }\nAVSValue IsLongStrict(AVSValue args, void*, IScriptEnvironment*) { return args[0].IsLongStrict(); }\nAVSValue IsFloat(AVSValue args, void*, IScriptEnvironment*) {  return args[0].IsFloat(); }\nAVSValue IsFloatfStrict(AVSValue args, void*, IScriptEnvironment*) { return args[0].IsFloatfStrict(); }\nAVSValue IsString(AVSValue args, void*, IScriptEnvironment*) {  return args[0].IsString(); }\nAVSValue IsClip(AVSValue args, void*, IScriptEnvironment*) {  return args[0].IsClip(); }\nAVSValue IsFunction(AVSValue args, void*, IScriptEnvironment*) { return args[0].IsFunction(); }\nAVSValue Defined(AVSValue args, void*, IScriptEnvironment*) {  return args[0].Defined(); }\n\nconst char* GetAVSTypeName(AVSValue value) {\n  if (value.IsClip())\n    return \"clip\";\n  else if (value.IsBool())\n    return \"bool\";\n  else if (value.IsLongStrict()) // must be before IsInt\n    return \"long\";\n  else if (value.IsInt())\n    return \"int\";\n  else if (value.IsFloatfStrict()) // before IsFloat\n    return \"float\";\n  else if (value.IsFloat())\n    return \"double\";\n  else if (value.IsString())\n    return \"string\";\n  else if (value.IsArray())\n    return \"array\";\n  else if (value.IsFunction())\n    return \"function\";\n  else if (!value.Defined())\n    return \"undefined value\";\n  else\n    return \"unknown type\";\n}\n\nAVSValue TypeName(AVSValue args, void*, IScriptEnvironment*) { return GetAVSTypeName(args[0]); }\n\nAVSValue Default(AVSValue args, void*, IScriptEnvironment*) {  return args[0].Defined() ? args[0] : args[1]; }\n\nstatic float find_next_valid_float(const double version) {\n  float version_f = static_cast<float>(version);\n  const float initial_value = version_f;\n  // float epsilon = std::nextafterf(version_f, INFINITY) - version_f;\n  int steps = 0;\n\n  while (version_f < version) {\n    version_f = std::nextafterf(version_f, INFINITY);\n    steps++;\n\n    // Safety check to prevent infinite loops\n    if (steps > 1000000) {\n      // std::cout << \"Too many steps required, possible overflow\\n\";\n      version_f = initial_value;\n      break;\n    }\n  }\n  return version_f;\n}\n\nAVSValue VersionNumber(AVSValue args, void*, IScriptEnvironment*) {\n  const double VersionToReturn = AVS_VERSION; // consider upgrading\n  float VersionToReturnf = find_next_valid_float(VersionToReturn);\n  return VersionToReturnf;\n  // A typical transition, when - even in Avisynth+ - we return 2.6f here.\n  // From 3.7.4 script constants are of 64-bit double precision, and \n  // the very popular IsAvs26 = VersionNumber() >= 2.6 will fail, since\n  // 2.6f < 2.6, (double)(float)2.6 is 2.5999999046. Arrrgh.\n  // 2.6 cannot be exactly specified as a floating point number and has\n  // differently rounded values in float and in double.\n  // Thus we start increasing the float value with the smallest available steps, \n  // until the comparison will be fine.\n  // Prior to interface version 11, Avisynth supported only 32-bit floating-point data (float), not 64-bit (double).\n  // To maintain compatibility (old plugins get this value as 32 bit float), this return \n  // value must remain a 32-bit float.\n}\n\nAVSValue VersionString(AVSValue args, void*, IScriptEnvironment*) {  return AVS_FULLVERSION; }\nAVSValue IsVersionOrGreater(AVSValue args, void*, IScriptEnvironment* env)\n{\n  if (!args[0].Defined() || !args[1].Defined()) {\n    env->ThrowError(\"IsVersionOrGreater error: at least two parameters (majorVersion, minorVersion) required!\");\n  }\n\n    // true when current version is at least the same or greater than the given three-part version\n  const int majorVersion = args[0].AsInt(0);\n  const int minorVersion = args[1].AsInt(0);\n  const int bugfixVersion = args[2].AsInt(0);\n  if (majorVersion != AVS_MAJOR_VER) return majorVersion < AVS_MAJOR_VER;\n  if (minorVersion != AVS_MINOR_VER) return minorVersion < AVS_MINOR_VER;\n  return bugfixVersion <= AVS_BUGFIX_VER;\n}\n\nAVSValue Frac(AVSValue args, void*, IScriptEnvironment*) {\n  if (args[0].IsInt()) return 0.f;\n  double result = args[0].AsFloat() - int64_t(args[0].AsFloat());\n  if (args[0].IsFloat())\n    return (float)result;\n  return result;\n}\n\nAVSValue Int(AVSValue args, void*, IScriptEnvironment*) {  \n  if (args[0].IsLongStrict()) return args[0].AsLong();\n  if (args[0].IsInt()) return args[0].AsInt();\n  \n  int64_t result = int64_t(args[0].AsFloat());\n  if (result >= INT_MIN && result <= INT_MAX)\n    return (int)result;\n  return result;\n}\n\nAVSValue IntI(AVSValue args, void*, IScriptEnvironment*) {\n  if (args[0].IsInt()) return static_cast<int>(args[0].AsLong());\n\n  int result = static_cast<int>(args[0].AsFloat());\n  return result;\n}\n\nAVSValue Long(AVSValue args, void*, IScriptEnvironment*) {\n  if (args[0].IsInt()) return args[0].AsLong();\n\n  int64_t result = static_cast<int64_t>(args[0].AsFloat());\n  return result;\n}\n\nAVSValue Float(AVSValue args, void*, IScriptEnvironment*) {\n  if (args[0].IsInt())\n    return (double)args[0].AsLong();\n  if(args[0].IsFloatfStrict())\n    return args[0].AsFloatf();\n  return args[0].AsFloat();\n}\n\n// Always to 64 bit double\nAVSValue Double(AVSValue args, void*, IScriptEnvironment*) {\n  return args[0].AsFloat();\n}\n\n// Always to 32 bit float\nAVSValue Floatf(AVSValue args, void*, IScriptEnvironment*) {\n  return args[0].AsFloatf();\n}\n\nAVSValue Value(AVSValue args, void*, IScriptEnvironment*) {  char *stopstring; return strtod(args[0].AsString(),&stopstring); }\n\nAVSValue HexValue(AVSValue args, void*, IScriptEnvironment*)\n{\n  // Added optional pos arg default = 1, start position in string of the HexString, 1 denotes the string beginning.\n  // Will return 0 if error in 'pos' ie if pos is less than 1 or greater than string length.\n  const char* str = args[0].AsString();\n  int64_t pos = args[1].AsLong(1) - 1; // start is pos 1\n  size_t sz = strlen(str);\n  if (pos < 0 || static_cast<size_t>(pos) >= sz)\n    return 0;\n  str += pos;\n  char* stopstring;\n  unsigned long result = strtoul(str, &stopstring, 16);\n  // keep int range, FFFFFFFF is negative - compatibility, see HexValue64\n  return (int)(result);\n}\n\n// new in v11\nAVSValue HexValue64(AVSValue args, void*, IScriptEnvironment*)\n{\n  // Added optional pos arg default = 1, start position in string of the HexString, 1 denotes the string beginning.\n  // Will return 0 if error in 'pos' ie if pos is less than 1 or greater than string length.\n  const char* str = args[0].AsString();\n  int64_t pos = args[1].AsLong(1) - 1; // start is pos 1\n  size_t sz = strlen(str);\n  if (pos < 0 || static_cast<size_t>(pos) >= sz)\n    return 0;\n  str += pos;\n  char* stopstring;\n  // v11: strtoul --> strtoull to 64 bit results long long\n  unsigned long long result = strtoull(str, &stopstring, 16);\n  // FFFFFFFF is positive\n  return static_cast<int64_t>(result);\n}\n\nAVSValue AvsMin(AVSValue args, void*, IScriptEnvironment* env)\n{\n  bool isInt = true;\n  bool isFloat32 = true;\n\n  const int n = args[0].ArraySize();\n  if (n < 2) env->ThrowError(\"Too few arguments for Min\");\n\n  // If all numbers are Ints return an Int\n  for (int i = 0; i < n; i++)\n    if (!args[0][i].IsInt()) {\n      isInt = false;\n      break;\n    }\n\n  // v11: If all numbers are 32 bit floats return real float instead of double\n  for (int i = 0; i < n; i++)\n    if (!args[0][i].IsFloatfStrict()) {\n      isFloat32 = false;\n      break;\n    }\n\n  if (isInt) {\n    int64_t V = args[0][0].AsLong();\n    for (int i = 1; i < n; i++)\n      V = min(V, args[0][i].AsLong());\n    // keep the smaller type\n    if (V >= INT_MIN && V <= INT_MAX)\n      return (int)V;\n    return V;\n  }\n  else {\n    double V = args[0][0].AsFloat();\n    for (int i = 1; i < n; i++)\n      V = min(V, args[0][i].AsFloat());\n    if (isFloat32)\n      return (float)V;\n    return V;\n  }\n}\n\nAVSValue AvsMax(AVSValue args, void*, IScriptEnvironment* env)\n{\n  bool isInt = true;\n  bool isFloat32 = true;\n\n  const int n = args[0].ArraySize();\n  if (n < 2) env->ThrowError(\"Too few arguments for Max\");\n\n  // If all numbers are Ints return an Int\n  for (int i = 0; i < n; i++)\n    if (!args[0][i].IsInt()) {\n      isInt = false;\n      break;\n    }\n\n  // v11: If all numbers are 32 bit floats return real float instead of double\n  for (int i = 0; i < n; i++)\n    if (!args[0][i].IsFloatfStrict()) {\n      isFloat32 = false;\n      break;\n    }\n\n  if (isInt) {\n    int64_t V = args[0][0].AsLong();\n    for (int i = 1; i < n; i++)\n      V = max(V, args[0][i].AsLong());\n    // keep the smaller type\n    if (V >= INT_MIN && V <= INT_MAX)\n      return (int)V;\n    return V;\n  }\n  else {\n    double V = args[0][0].AsFloat();\n    for (int i = 1; i < n; i++)\n      V = max(V, args[0][i].AsFloat());\n    if (isFloat32)\n      return (float)V;\n    return V;\n  }\n}\n\n// The \"AddAutoloadDir\" script function allows supplying a UTF-8 directory path\n// even when the system code page is ANSI.\n// On Windows the Avisynth script typically treats string parameters as ANSI\n// by default, unless we force the interpretation with an optional bool utf8 = true.\n// The directory parameter is converted from ANSI to UTF-8 internally before calling\n// the interface API. This behavior depends on the IScriptEnvironment2 (development)\n// interface, which provides an AddAutoloadDir method that requires now UTF-8 paths.\nAVSValue AddAutoloadDir (AVSValue args, void*, IScriptEnvironment* env)\n{\n  IScriptEnvironment2 *env2 = static_cast<IScriptEnvironment2*>(env);\n  const bool utf8 = args[2].AsBool(false); // default ANSI on Windows, n/a (see charToUtf8) on other OSes\n  auto dir_utf8 = charToUtf8(args[0].AsString(), utf8); // takes care of ANSI to UTF8 conversion on Windows if needed\n  env2->AddAutoloadDir(dir_utf8.c_str(), args[1].AsBool(true));\n\n  return AVSValue();\n}\n\nAVSValue ClearAutoloadDirs (AVSValue args, void*, IScriptEnvironment* env)\n{\n  IScriptEnvironment2 *env2 = static_cast<IScriptEnvironment2*>(env);\n  env2->ClearAutoloadDirs();\n  return AVSValue();\n}\n\nAVSValue ListAutoloadDirs(AVSValue args, void*, IScriptEnvironment* env)\n{\n  InternalEnvironment* envi = static_cast<InternalEnvironment*>(env);\n  const char* AutoLoadDirs = envi->ListAutoloadDirs(); // internally uses SaveString\n#if defined(AVS_WINDOWS)\n  const bool utf8 = args[0].AsBool(false); // default ANSI on Windows, n/a on other OSes\n  if (!utf8) {\n    // On Windows the environment uses ANSI by default. When the caller requests ANSI\n    // (utf8 == false), convert the internally stored UTF-8 string to ANSI before returning.\n    // Characters that cannot be represented in ANSI will be replaced with '?'.\n    return AVSValue(env->SaveString(Utf8ToAnsi(AutoLoadDirs).c_str())); // New SaveString needed.\n  }\n#endif\n  return AVSValue(AutoLoadDirs);\n}\n\n\nAVSValue AutoloadPlugins (AVSValue args, void*, IScriptEnvironment* env)\n{\n  IScriptEnvironment2 *env2 = static_cast<IScriptEnvironment2*>(env);\n  env2->AutoloadPlugins();\n  return AVSValue();\n}\n\nAVSValue FunctionExists (AVSValue args, void*, IScriptEnvironment* env)\n{\n  return env->FunctionExists(args[0].AsString());\n}\n\nAVSValue InternalFunctionExists (AVSValue args, void*, IScriptEnvironment* env)\n{\n  IScriptEnvironment2 *env2 = static_cast<IScriptEnvironment2*>(env);\n  return env2->InternalFunctionExists(args[0].AsString());\n}\n\nAVSValue SetFilterMTMode (AVSValue args, void*, IScriptEnvironment* env)\n{\n  IScriptEnvironment2 *env2 = static_cast<IScriptEnvironment2*>(env);\n  env2->SetFilterMTMode(args[0].AsString(), (MtMode)args[1].AsInt(), args[2].AsBool(false));\n  return AVSValue();\n}\n\nAVSValue SetLogParams(AVSValue args, void*, IScriptEnvironment* env)\n{\n    const char* target = args[0].AsString(\"stderr\");\n    const int level = args[1].AsInt(LOGLEVEL_INFO);\n\n    InternalEnvironment *envi = static_cast<InternalEnvironment*>(env);\n    envi->SetLogParams(target, level);\n    return AVSValue();\n}\n\nAVSValue LogMsg(AVSValue args, void*, IScriptEnvironment* env)\n{\n    if ((args.ArraySize() != 2) || !args[0].IsString() || !args[1].IsInt())\n    {\n        env->ThrowError(\"Invalid parameters to Log() function.\");\n    }\n    else\n    {\n        InternalEnvironment *envi = static_cast<InternalEnvironment*>(env);\n        envi->LogMsg(args[1].AsInt(), args[0].AsString());\n    }\n    return AVSValue();\n}\n\nAVSValue SetCacheMode(AVSValue args, void*, IScriptEnvironment* env)\n{\n  InternalEnvironment *envI = static_cast<InternalEnvironment*>(env);\n  envI->SetCacheMode((CacheMode)args[0].AsInt());\n  return AVSValue();\n}\n\nAVSValue SetDeviceOpt(AVSValue args, void*, IScriptEnvironment* env)\n{\n    InternalEnvironment *envI = static_cast<InternalEnvironment*>(env);\n    envI->SetDeviceOpt((DeviceOpt)args[0].AsInt(), args[1].AsInt(0));\n    return AVSValue();\n}\n\nAVSValue SetFilterProp(AVSValue args, void*, IScriptEnvironment* env)\n{\n  InternalEnvironment* envi = static_cast<InternalEnvironment*>(env);\n\n  // 3+1-arg: \"ss.[mode]i\"\n  // 5+1-arg: \"ss.s.[mode]i\":\n  // arg3 exists and is string or integer/undefined\n  if (args[3].IsString()) {\n    // 5+1-arg conditional form matched by \"ss.s.[mode]i\":\n    //   SetFilterProp(filter, param_name, param_match, prop_key, prop_value [, mode])\n    // Inject prop_key=prop_value only when the named call arg 'param_name' equals param_match.\n    const AVSValue& param_match = args[2];\n    // param_match may be a scalar (int/float/bool/string) or an array of scalars (aliases)\n    if (param_match.IsArray()) {\n      for (int j = 0; j < param_match.ArraySize(); ++j) {\n        const AVSValue& elem = param_match[j];\n        if (!elem.IsInt() && !elem.IsFloat() && !elem.IsString() && !elem.IsBool())\n          env->ThrowError(\"SetFilterProp: alias array element %d must be int, float, bool, or string\", j);\n      }\n    } else if (!param_match.IsInt() && !param_match.IsFloat() && !param_match.IsString() && !param_match.IsBool()) {\n      env->ThrowError(\"SetFilterProp: condition value must be int, float, bool, string, \"\n                      \"or an array of those\");\n    }\n    const AVSValue& prop_value = args[4];\n    if (prop_value.Defined() &&\n        !prop_value.IsInt() && !prop_value.IsFloat() && !prop_value.IsString() &&\n        !prop_value.IsBool() && !prop_value.IsFunction())\n      env->ThrowError(\"SetFilterProp: property value (arg 5) must be int, float, bool, string, or function\");\n    // Frame properties have no bool type: convert bool value to int 0/1\n    AVSValue stored_value = prop_value;\n    if (stored_value.IsBool())\n      stored_value = AVSValue(stored_value.AsBool() ? 1 : 0);\n    const int mode = args[5].AsInt(AVSPropAppendMode::PROPAPPENDMODE_REPLACE);\n    envi->SetFilterPropConditional(args[0].AsString(), args[1].AsString(), param_match,\n                                   args[3].AsString(), stored_value, mode);\n  } else {\n    // 3-arg simple form matched by \"ss.[mode]i\":\n    //   SetFilterProp(filter, prop_key, value [, mode])\n    const int mode = args[3].AsInt(AVSPropAppendMode::PROPAPPENDMODE_REPLACE);\n    AVSValue val = args[2];\n    if (val.Defined() && !val.IsInt() && !val.IsFloat() && !val.IsString() && !val.IsBool() && !val.IsFunction())\n      env->ThrowError(\"SetFilterProp: property value must be int, float, bool, string, function, or undefined()\");\n    // Frame properties have no bool type: convert bool to int 0/1\n    if (val.IsBool())\n      val = AVSValue(val.AsBool() ? 1 : 0);\n    envi->SetFilterProp(args[0].AsString(), args[1].AsString(), val, mode);\n  }\n  return AVSValue();\n}\n\nAVSValue GetFilterProps(AVSValue args, void*, IScriptEnvironment* env)\n{\n  InternalEnvironment* envi = static_cast<InternalEnvironment*>(env);\n  return AVSValue(envi->GetFilterProps());\n}\n\nAVSValue SetFilterPropPassthrough(AVSValue args, void*, IScriptEnvironment* env)\n{\n  InternalEnvironment* envi = static_cast<InternalEnvironment*>(env);\n  envi->SetFilterPropPassthrough(args[0].AsString());\n  return AVSValue();\n}\n\n// Neo style\nAVSValue SetMemoryMax(AVSValue args, void*, IScriptEnvironment* env)\n{\n  int memMax = args[0].AsInt(0);\n  int deviceType = args[1].AsInt(0);\n  int deviceIndex = args[2].AsInt(0);\n\n  if (deviceType == 0 || deviceType == DEV_TYPE_CPU) {\n    return env->SetMemoryMax(memMax);\n  }\n\n  InternalEnvironment *envI = static_cast<InternalEnvironment*>(env);\n  return envI->SetMemoryMax((AvsDeviceType)deviceType, deviceIndex, memMax);\n}\n\nAVSValue SetMaxCPU(AVSValue args, void*, IScriptEnvironment* env)\n{\n  InternalEnvironment* envI = static_cast<InternalEnvironment*>(env);\n  envI->SetMaxCPU(args[0].AsString());\n  return AVSValue();\n}\n\nAVSValue IsY(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).IsY(); }\nAVSValue Is420(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).Is420(); }\nAVSValue Is422(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).Is422(); }\nAVSValue Is444(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).Is444(); }\nAVSValue IsRGB48(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).IsRGB48(); }\nAVSValue IsRGB64(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).IsRGB64(); }\nAVSValue ComponentSize(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).ComponentSize(); }\nAVSValue BitsPerComponent(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).BitsPerComponent(); }\nAVSValue IsYUVA(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).IsYUVA(); }\nAVSValue IsPlanarRGB(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).IsPlanarRGB(); }\nAVSValue IsPlanarRGBA(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).IsPlanarRGBA(); }\nAVSValue NumComponents(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).NumComponents(); }\nAVSValue HasAlpha(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).IsPlanarRGBA() || VI(args[0]).IsYUVA() || VI(args[0]).IsRGB32() || VI(args[0]).IsRGB64(); }\nAVSValue IsPackedRGB(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).IsRGB24() || VI(args[0]).IsRGB32() || VI(args[0]).IsRGB48() || VI(args[0]).IsRGB64(); }\nAVSValue IsVideoFloat(AVSValue args, void*, IScriptEnvironment*) {  return VI(args[0]).BitsPerComponent() == 32; }\n\n// helper for GetProcessInfo\nstatic int ProcessType() {\n#define PROCESS_UNKNOWN  -1\n#define PROCESS_32_ON_32 0\n#define PROCESS_32_ON_64 1\n#define PROCESS_64_ON_64 2\n\n  if constexpr(sizeof(void*) == 8)\n    return PROCESS_64_ON_64;\n#ifdef AVS_WINDOWS\n  else {\n    // IsWow64Process is not available on all supported versions of Windows.\n    // Use GetModuleHandle to get a handle to the DLL that contains the function\n    // and GetProcAddress to get a pointer to the function if available.\n\n    BOOL bWoW64Process = FALSE;\n    typedef bool(WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);\n    LPFN_ISWOW64PROCESS fnIsWow64Process;\n    HMODULE hKernel32 = GetModuleHandle(\"kernel32.dll\");\n    if (hKernel32 == NULL)\n      return PROCESS_UNKNOWN;\n\n    fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(hKernel32, \"IsWow64Process\");\n    if (fnIsWow64Process != NULL)\n      fnIsWow64Process(GetCurrentProcess(), &bWoW64Process);\n    else\n      return PROCESS_UNKNOWN;\n\n    if (bWoW64Process)\n      return PROCESS_32_ON_64; //WoW64\n\n    return PROCESS_32_ON_32;\n  }\n#endif\n}\n\nAVSValue GetProcessInfo(AVSValue args, void*, IScriptEnvironment* env)\n{\n  int infoType = args[0].AsInt(0);\n  if (infoType < 0 || infoType > 1)\n    env->ThrowError(\"GetProcessInfo: type must be 0 or 1\");\n  if (infoType == 0) {\n    return sizeof(void *) == 8 ? 64 : 32;\n  }\n  // infoType == 1\n  return ProcessType();\n}\n\n#ifdef AVS_WINDOWS\nAVSValue StrToUtf8(AVSValue args, void*, IScriptEnvironment* env) {\n  const char *source = args[0].AsString();\n  // in two steps: Ansi -> WideChar -> Utf8\n  auto wsource = AnsiToWideCharACP(source);\n  // wide -> utf8\n  auto source_utf8 = WideCharToUtf8(wsource.get());\n  AVSValue ret = env->SaveString(source_utf8.get());\n  return ret;\n}\n\nAVSValue StrFromUtf8(AVSValue args, void*, IScriptEnvironment* env) {\n  const char *source_utf8 = args[0].AsString();\n  // in two steps: Utf8 -> WideChar -> Ansi\n  auto wsource = Utf8ToWideChar(source_utf8);\n  // wide -> ansi\n  auto source_ansi = WideCharToAnsiACP(wsource.get());\n  AVSValue ret = env->SaveString(source_ansi.get());\n  return ret;\n}\n#endif\n\n\nAVSValue IsFloatUvZeroBased(AVSValue args, void*, IScriptEnvironment*)\n{\n#ifdef FLOAT_CHROMA_IS_HALF_CENTERED\n  return false;\n#else\n  return true;\n#endif\n}\n\nAVSValue BuildPixelType(AVSValue args, void*, IScriptEnvironment* env)\n{\n  //  { \"BuildPixelType\", BUILTIN_FUNC_PREFIX, \"[family]s[bits]i[chroma]i[compat]b[oldnames]b[sample_clip]c\", BuildPixelType }, // 180517-\n  // family: YUV, YUVA, RGB, RGBA, Y\n  // bits: 8, 10, 12, 14, 16, 32\n  // chroma: for YUV(A) 420,422,444,411. Ignored for RGB(A) and Y\n  // compat (default false): returns packed rgb formats for 8/16 bits (RGB default: planar RGB)\n  // oldnames (default false): returns YV12/YV16/YV24 instead of YUV420P8/YUV422P8/YUV444P8\n  // sample_clip: when supported, its format is overridden by specified parameters (e.g. only change bits=10)\n\n  const bool hasTemplate = args[5].Defined();\n\n  if (!args[0].Defined() && !hasTemplate)\n    env->ThrowError(\"BuildPixelType error: no color space 'family' or template 'sample_clip' specified\");\n  if (!args[1].Defined() && !hasTemplate)\n    env->ThrowError(\"BuildPixelType error: no 'bits' or  template 'sample_clip' specified\");\n\n  std::string family;\n  if (!args[0].Defined() && hasTemplate) {\n    // no family parameter: use template\n    VideoInfo const &vi = args[5].AsClip()->GetVideoInfo();\n    if (vi.IsY())\n      family = \"Y\";\n    else if (vi.IsPlanar()) {\n      if (vi.IsYUV())\n        family = \"YUV\";\n      else if (vi.IsYUVA())\n        family = \"YUVA\";\n      else if (vi.IsPlanarRGB())\n        family = \"RGB\";\n      else if (vi.IsPlanarRGBA())\n        family = \"RGBA\";\n      else\n        env->ThrowError(\"BuildPixelType error: invalid sample_clip format\");\n    }\n    else if (vi.IsRGB24() || vi.IsRGB48())\n      family = \"RGB\";\n    else if (vi.IsRGB32() || vi.IsRGB64())\n      family = \"RGBA\";\n    else\n      env->ThrowError(\"BuildPixelType error: invalid sample_clip format\");\n  }\n  else {\n    family = args[0].AsString();\n    for (auto & c : family) c = toupper(c); // uppercase input string\n  }\n\n  const bool isYUV = family == \"YUV\";\n  const bool isYUVA = family == \"YUVA\";\n  const bool isRGB = family == \"RGB\";\n  const bool isRGBA = family == \"RGBA\";\n  const bool isY = family == \"Y\";\n\n  if(!isYUV && !isYUVA && !isRGB && !isRGBA && !isY)\n    env->ThrowError(\"BuildPixelType error: wrong 'family'.\", family.c_str());\n\n  int bits;\n  if (!args[1].Defined() && hasTemplate) {\n    // no bits parameter: get it from template sample_clip\n    bits = args[5].AsClip()->GetVideoInfo().BitsPerComponent();\n  } else {\n    bits = args[1].AsInt();\n  }\n\n  if (bits != 8 && bits != 10 && bits != 12 && bits != 14 && bits != 16 && bits != 32)\n    env->ThrowError(\"BuildPixelType error: 'bits'=%d is not valid.\", bits);\n\n  int chroma;\n\n  if (isYUV || isYUVA) {\n    if (!args[2].Defined() && hasTemplate) {\n      // no chroma parameter: subsampling from template clip\n      VideoInfo const &vi = args[5].AsClip()->GetVideoInfo();\n      const int hs = vi.GetPlaneWidthSubsampling(PLANAR_U);\n      const int vs = vi.GetPlaneHeightSubsampling(PLANAR_U);\n      if (hs == 0 && vs == 0) chroma = 444;\n      else if (hs == 1 && vs == 0) chroma = 422;\n      else if (hs == 1 && vs == 1) chroma = 420;\n      else if (hs == 2 && vs == 0) chroma = 411;\n      else\n        env->ThrowError(\"BuildPixelType error: sample_clip has invalid chroma subsampling.\");\n    }\n    else {\n      chroma = args[2].AsInt(444);\n    }\n  }\n  else {\n    chroma = 444; // n/a\n  }\n\n  if(chroma != 444 && chroma != 422 && chroma != 420 && chroma != 411)\n    env->ThrowError(\"BuildPixelType error: 'chroma' must be 444, 422, 420 or 411.\");\n\n  // packed RGB compatibility formats only for RGB(A)\n  const bool compat = isRGB || isRGBA ? args[3].AsBool(false) : false;\n\n  // e.g. return YV12 instead of YUV420P8\n  const bool oldNames = args[4].AsBool(false);\n\n  if(compat && bits != 8 && bits != 16)\n    env->ThrowError(\"BuildPixelType error: 'compat'=true requires bits=8 or 16 for RGB(A).\");\n\n  if(chroma == 411 && bits != 8)\n    env->ThrowError(\"BuildPixelType error: 411 is supported only for 8 bits.\");\n\n  if (compat) {\n    if (isRGB && bits == 8)\n      return \"RGB24\";\n    if (isRGB && bits == 16)\n      return \"RGB48\";\n    if (isRGBA && bits == 8)\n      return \"RGB32\";\n    return \"RGB64\"; // RGBA, bits==16\n  }\n\n  std::string format;\n\n  if (isYUV || isYUVA || isY)\n    format = family;\n  else if (isRGB)\n    format = \"RGBP\";\n  else if (isRGBA)\n    format = \"RGBAP\";\n\n  if (isYUV || isYUVA) {\n    if (chroma == 444)\n      format += \"444\";\n    else if(chroma == 422)\n      format += \"422\";\n    else if (chroma == 420)\n      format += \"420\";\n    else if (chroma == 411)\n      format += \"411\";\n\n    format = format + \"P\";\n  }\n\n  if (bits == 32)\n      format += (isY ? \"32\" : \"S\"); // no \"YS\", only \"Y32\"\n  else\n    format = format + std::to_string(bits);\n\n  if (oldNames) {\n    if (format == \"YUV420\" || format == \"YUV420P8\") format = \"YV12\";\n    else if (format == \"YUV422\" || format == \"YUV422P8\") format = \"YV16\";\n    else if (format == \"YUV444\" || format == \"YUV444P8\") format = \"YV24\";\n  }\n\n  // 411 has no alternative naming\n  if (format == \"YUV411\") format = \"YV411\";\n\n  return env->SaveString(format.c_str());\n}\n\nAVSValue VarExist(AVSValue args, void*, IScriptEnvironment* env)\n{\n  const char *name = args[0].AsString();\n  int len = (int)strlen(name);\n\n  bool validName = true;\n  // check for a valid identifier name\n  if (*name != '_' && !isalpha(*name))\n    validName = false;\n  else {\n    for (int i = 1; i < len; i++) {\n      const char ch = name[i];\n      if (!(ch == '_' || isalnum(ch))) {\n        validName = false;\n        break;\n      }\n    }\n  }\n\n  if (!validName)\n    env->ThrowError(\"VarExist: invalid variable name\");\n\n  AVSValue result;\n  return (env->GetVarTry(name, &result)); // true if exists\n}\n\n\nAVSValue ArrayCreate(AVSValue args, void*, IScriptEnvironment* env)\n{\n    return args[0];\n}\n\nAVSValue IsArray(AVSValue args, void*, IScriptEnvironment* env) { return args[0].IsArray(); }\n\nAVSValue ArrayGet(AVSValue args, void*, IScriptEnvironment* env)\n{\n  // signature .i+\n  // parameters: [0] array to index; [1] one or more integer indexes or a string\n  if (!args[0].IsArray())\n    env->ThrowError(\"ArrayGet: array type required.\");\n  const int size = args[0].ArraySize();\n  if (args[1].IsString()) {\n    // associative search\n    // { {\"a\", element1}, { \"b\", element2 }, etc..}\nconst char* tag = args[1].AsString();\nfor (int i = 0; i < size; i++)\n{\n  AVSValue currentTagValue = args[0][i]; // two elements e.g. { \"b\", element2 }\n  if (!currentTagValue.IsArray())\n    env->ThrowError(\"ArrayGet: Array must contain array[string, any] elements for dictionary lookup\");\n  if (currentTagValue.ArraySize() < 2)\n    env->ThrowError(\"ArrayGet: Internal array must have at least two elements (tag, value)\");\n  AVSValue currentTag = currentTagValue[0];\n  if (currentTag.IsString() && !lstrcmpi(currentTag.AsString(), tag))\n  {\n    return currentTagValue[1];\n  }\n}\nreturn AVSValue(); // undefined\n  }\n  else if (args[1].IsArray()) {\n  AVSValue indexes = args[1];\n  AVSValue currentValue = args[0];\n  int index_count = indexes.ArraySize(); // array of parameters. a[1,2] -> [1,2]\n  if (index_count == 0)\n    env->ThrowError(\"ArrayGet: no index specified\");\n  for (int i = 0; i < index_count; i++)\n  {\n    if (!currentValue.IsArray())\n      env->ThrowError(\"ArrayGet: not an array. Index=%d\", i);\n    int currentIndex = indexes[i].AsInt();\n    if (currentIndex < 0 || currentIndex >= currentValue.ArraySize())\n      env->ThrowError(\"ArrayGet: Array index out of range. Problematic index count: %d\", i + 1);\n    currentValue = currentValue[currentIndex];\n  }\n  return currentValue;\n  }\n  env->ThrowError(\"ArrayGet: Invalid array index, must be integer or string, or comma separated integers\");\n  return AVSValue(); // undefined\n}\n\nAVSValue ArraySize(AVSValue args, void*, IScriptEnvironment* env)\n{\n  // func signature: \".\"\n  if (!args[0].IsArray())\n    env->ThrowError(\"ArraySize: parameter must be an array\");\n  return args[0].ArraySize();\n}\n\nAVSValue ArrayIns(AVSValue args, void* user_data, IScriptEnvironment* env)\n{\n  int mode = (int)(intptr_t)user_data;\n  enum ArrayMode {\n    INSERT = 0,\n    APPEND = 1,\n    REPLACE = 2,\n    DEL = 3\n  };\n  // signature .. and ..i\n  // parameters:\n  // [0] array to modify;\n  // [1] element to insert (ArrayAdd, ArrayIns and ArraySet) [2] inserting index(es) (ArrayIns, ArraySet)\n  // or [1] delete index(es) ArrayDel\n\n  const char* funcname = mode == DEL ? \"ArrayDel\" : mode == REPLACE ? \"ArraySet\" : mode == APPEND ? \"ArrayAdd\" : \"ArrayIns\";\n\n  if (!args[0].IsArray())\n    env->ThrowError(\"%s error: array type required.\", funcname);\n\n  const auto orig_size = args[0].ArraySize();\n\n  const int index_param_pos = mode == DEL ? 1 : 2;\n  AVSValue indexes = args[index_param_pos];\n  int index_count = indexes.ArraySize(); // array of parameters. a[1,2] -> [1,2]\n\n  if (mode == INSERT || mode == REPLACE || mode == DEL) {\n    if (index_count == 0)\n      env->ThrowError(\"%s: no index specified\", funcname);\n  }\n\n  const int new_size =\n    mode == DEL && index_count == 1 ? orig_size - 1 :\n    mode == APPEND && index_count == 0 ? orig_size + 1 :\n    mode == INSERT && index_count == 1 ? orig_size + 1 :\n    orig_size; // replace and recurside other cases\n\n  std::vector<AVSValue> new_val(new_size);\n\n  int action_pos;\n  if (mode == APPEND)\n    action_pos = orig_size; // at the end\n  else\n    action_pos = indexes[0].AsInt();\n\n  // copy before insertion/replace point\n  for (int i = 0; i < action_pos; i++)\n    new_val[i] = args[0][i]; // avs+: automatic deep copy\n\n  if (\n    ((mode == REPLACE || mode == INSERT || mode == DEL) && index_count > 1) ||\n    ((mode == APPEND) && index_count >= 1))\n  {\n    int current_index = indexes[0].AsInt();\n    // for multi-level array recursion is needed because there is no exact reference to an inner element\n    if (mode == DEL) {\n      AVSValue params[2] = { args[0][current_index], index_count <= 1 ? AVSValue(nullptr, 0) : AVSValue(&indexes[1], index_count - 1) };\n      new_val[current_index] = env->Invoke(funcname, AVSValue(params, 2)); // recursively\n    }\n    else {\n      AVSValue params[3] = { args[0][current_index], args[1], index_count <= 1 ? AVSValue(nullptr, 0) : AVSValue(&indexes[1], index_count - 1) };\n      new_val[current_index] = env->Invoke(funcname, AVSValue(params, 3)); // recursively\n    }\n    mode = REPLACE;\n  }\n  else if (mode != DEL) {\n    new_val[action_pos] = args[1];\n  }\n\n  // copy from after insertion/replace/delete point\n  if (mode == DEL) {\n    for (int i = action_pos + 1; i < orig_size; i++)\n      new_val[i - 1] = args[0][i]; // avs+: automatic deep copy\n  }\n  else if (mode == REPLACE) {\n    for (int i = action_pos+1; i < orig_size; i++)\n      new_val[i] = args[0][i]; // avs+: automatic deep copy\n  }\n  else {\n    for (int i = action_pos; i < orig_size; i++)\n      new_val[i + 1] = args[0][i]; // avs+: automatic deep copy\n  }\n\n  if(new_size == 0)\n    return AVSValue(nullptr, 0); // zero array\n\n  return AVSValue(new_val.data(), new_size);\n}\n\n// Custom comparator functions for sorting\nbool customCompareBool(const std::pair<const AVSValue*, int>& a, const std::pair<const AVSValue*, int>& b) {\n  return (a.first)->AsBool() < (b.first)->AsBool();\n}\n\n// v11: 64 bit content as well\nbool customCompareInt(const std::pair<const AVSValue *, int>& a, const std::pair<const AVSValue *, int>& b) {\n  return (a.first)->AsLong() < (b.first)->AsLong(); // v11: AsLong instead of AsInt\n}\n\n// v11: 64 bit content as well\nbool customCompareFloat(const std::pair<const AVSValue*, int>& a, const std::pair<const AVSValue*, int>& b) {\n  return (a.first)->AsFloat() < (b.first)->AsFloat(); // v11: AsFloat instead of AsFloatf\n}\n\nbool customCompareString(const std::pair<const AVSValue*, int>& a, const std::pair<const AVSValue*, int>& b) {\n  return std::strcmp((a.first)->AsString(), (b.first)->AsString()) < 0;\n}\n\nAVSValue ArraySort(AVSValue args, void* user_data, IScriptEnvironment* env)\n{\n  // [0] array to sort;\n\n  if (!args[0].IsArray())\n    env->ThrowError(\"ArraySort error: array type required.\");\n\n  const auto size = args[0].ArraySize();\n\n  if (size == 0)\n    return AVSValue(nullptr, 0); // zero array\n\n  std::vector<std::pair<const AVSValue*, int>> indexedArr(size);\n\n  // Create a pair of (element reference, index) with type checks\n  // Note: integers and float can be mixed, sort by the broadest type\n  AvsValueType finalType = (args[0][0]).GetType();\n  for (int i = 0; i < size; ++i) {\n    indexedArr[i] = { &args[0][i], i };\n    AvsValueType currentType = indexedArr[i].first->GetType();\n    if (finalType == AvsValueType::VALUE_TYPE_INT && currentType == AvsValueType::VALUE_TYPE_LONG)\n    {\n      // promote int to long; note: since v11: long (int64) exists\n      finalType = currentType;\n    }\n    else if (finalType == AvsValueType::VALUE_TYPE_FLOAT && currentType == AvsValueType::VALUE_TYPE_DOUBLE)\n    {\n      // promote float to double; note: since v11: double exists\n      finalType = currentType;\n    }\n    else if ((finalType == AvsValueType::VALUE_TYPE_INT || finalType == AvsValueType::VALUE_TYPE_LONG) &&\n      (currentType == AvsValueType::VALUE_TYPE_FLOAT || currentType == AvsValueType::VALUE_TYPE_DOUBLE)) {\n      // promote int-like to float-like; note: since v11: int64/double exists\n      finalType = currentType;\n    }\n    // cannot mix bools, ints and strings\n    if (finalType == AvsValueType::VALUE_TYPE_STRING) {\n      if (currentType != AvsValueType::VALUE_TYPE_STRING)\n        env->ThrowError(\"ArraySort: array contains different basic types, string expected.\");\n    }\n    else if (finalType == AvsValueType::VALUE_TYPE_BOOL) {\n      if (currentType != AvsValueType::VALUE_TYPE_BOOL)\n        env->ThrowError(\"ArraySort: array contains different basic types, bool expected.\");\n    }\n    else {\n      // int-like or float-like\n      if (currentType != AvsValueType::VALUE_TYPE_INT &&\n        currentType != AvsValueType::VALUE_TYPE_LONG &&\n        currentType != AvsValueType::VALUE_TYPE_FLOAT &&\n        currentType != AvsValueType::VALUE_TYPE_DOUBLE)\n        env->ThrowError(\"ArraySort: array contains different basic types, number expected.\");\n    }\n  }\n\n  switch(finalType){\n  case AvsValueType::VALUE_TYPE_BOOL: std::sort(indexedArr.begin(), indexedArr.end(), customCompareBool); break;\n  case AvsValueType::VALUE_TYPE_INT:\n  case AvsValueType::VALUE_TYPE_LONG:\n    std::sort(indexedArr.begin(), indexedArr.end(), customCompareInt); break;\n  case AvsValueType::VALUE_TYPE_FLOAT:\n  case AvsValueType::VALUE_TYPE_DOUBLE:\n    std::sort(indexedArr.begin(), indexedArr.end(), customCompareFloat); break;\n  case AvsValueType::VALUE_TYPE_STRING: std::sort(indexedArr.begin(), indexedArr.end(), customCompareString); break;\n  default:\n    env->ThrowError(\"ArraySort: unsupported data type\");\n  }\n\n  // copy the results once\n  std::vector<AVSValue> new_val(size);\n  for (int i = 0; i < size; ++i) {\n    new_val[i] = *indexedArr[i].first;\n  }\n\n  return AVSValue(new_val.data(), size);\n}\n\n"
  },
  {
    "path": "avs_core/core/parser/script.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Script_H__\n#define __Script_H__\n\n#include <avisynth.h>\n#ifdef AVS_WINDOWS\n#include <avs/win.h>\n#include <tchar.h>\n#else\n#include <avs/posix.h>\n#endif\n\n#include \"../internal.h\"\n#include \"expression.h\"\n#include \"scriptparser.h\"\n\n\n/********************************************************************\n********************************************************************/\n\nclass ScriptFunction\n  /**\n    * Executes a script\n   **/\n{\npublic:\n  ScriptFunction(const PExpression& _body, const bool* _param_floats, const char** _param_names, int param_count);\n  virtual ~ScriptFunction()\n  {\n    delete[] param_floats;\n    delete[] param_names;\n  }\n\n  static AVSValue Execute(AVSValue args, void* user_data, IScriptEnvironment* env);\n  static void Delete(void* self, IScriptEnvironment*);\n\nprivate:\n  const PExpression body;\n  bool* param_floats;\n  const char** param_names;\n};\n\n\n/****    Helper functions   ****/\n\nAVSValue Assert(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue AssertEval(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue Eval(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue EvalOop(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue Apply(AVSValue args, void*, IScriptEnvironment* env) ;\n\nAVSValue Import(AVSValue args, void*, IScriptEnvironment* env);\n\nAVSValue SetWorkingDir(AVSValue args, void*, IScriptEnvironment* env);\n\n/*****   Entry/Factory Methods   ******/\n\nAVSValue Muldiv(AVSValue args, void*, IScriptEnvironment* env);\n\nAVSValue Floor(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue Ceil(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue Round(AVSValue args, void*, IScriptEnvironment* env);\n\nAVSValue Acos(AVSValue args, void* user_data, IScriptEnvironment* env);\nAVSValue Asin(AVSValue args, void* user_data, IScriptEnvironment* env);\nAVSValue Atan(AVSValue args, void* user_data, IScriptEnvironment* env);\nAVSValue Atan2(AVSValue args, void* user_data, IScriptEnvironment* env);\nAVSValue Cos(AVSValue args, void* user_data, IScriptEnvironment* env);\nAVSValue Cosh(AVSValue args, void* user_data, IScriptEnvironment* env);\nAVSValue Exp(AVSValue args, void* user_data, IScriptEnvironment* env);\nAVSValue Fmod(AVSValue args, void* user_data, IScriptEnvironment* env);\nAVSValue Log(AVSValue args, void* user_data, IScriptEnvironment* env);\nAVSValue Log10(AVSValue args, void* user_data, IScriptEnvironment* env);\nAVSValue Pow(AVSValue args, void* user_data, IScriptEnvironment* env);\nAVSValue Sin(AVSValue args, void* user_data, IScriptEnvironment* env);\nAVSValue Sinh(AVSValue args, void* user_data, IScriptEnvironment* env);\nAVSValue Tan(AVSValue args, void* user_data, IScriptEnvironment* env);\nAVSValue Tanh(AVSValue args, void* user_data, IScriptEnvironment* env);\nAVSValue Sqrt(AVSValue args, void* user_data, IScriptEnvironment* env);\n\nAVSValue Abs(AVSValue args, void* user_data, IScriptEnvironment* env);\nAVSValue FAbs(AVSValue args, void* user_data, IScriptEnvironment* env);\nAVSValue Pi(AVSValue args, void* user_data, IScriptEnvironment* env);\n#ifdef OPT_ScriptFunctionTau\nAVSValue Tau(AVSValue args, void* user_data, IScriptEnvironment* env);\n#endif\nAVSValue Sign(AVSValue args, void*, IScriptEnvironment* env);\n\nAVSValue PixelType (AVSValue args, void*, IScriptEnvironment* env);\nAVSValue Width(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue Height(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue FrameCount(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue FrameRate(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue FrameRateNumerator(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue FrameRateDenominator(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue AudioRate(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue AudioLength(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue AudioLengthLo(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue AudioLengthHi(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue AudioLengthS(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue AudioLengthF(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue AudioDuration(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue AudioChannels(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue AudioBits(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsAudioFloat(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsAudioInt(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsChannelMaskKnown(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue GetChannelMask(AVSValue args, void*, IScriptEnvironment* env);\n\nAVSValue IsRGB(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsY8(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsYV12(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsYV16(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsYV24(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsYV411(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsYUY2(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsYUV(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsRGB24(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsRGB32(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsPlanar(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsInterleaved(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsFieldBased(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsFrameBased(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue GetParity(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue String(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue Hex(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue Func(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue FormatString(AVSValue args, void*, IScriptEnvironment* env);\n\nAVSValue IsBool(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsInt(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsLongStrict(AVSValue args, void*, IScriptEnvironment* env); // v11\nAVSValue IsFloat(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsFloatfStrict(AVSValue args, void*, IScriptEnvironment* env); // v11\nAVSValue IsString(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsClip(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsFunction(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue Defined(AVSValue args, void*, IScriptEnvironment* env);\n\nAVSValue TypeName(AVSValue args, void*, IScriptEnvironment* env);\n\nAVSValue Default(AVSValue args, void*, IScriptEnvironment* env);\n\nAVSValue VersionNumber(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue VersionString(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsVersionOrGreater(AVSValue args, void*, IScriptEnvironment* env);\n\nAVSValue Int(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue Frac(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue Float(AVSValue args, void*,IScriptEnvironment* env);\nAVSValue IntI(AVSValue args, void*, IScriptEnvironment* env); // v11\nAVSValue Long(AVSValue args, void*, IScriptEnvironment* env); // v11\nAVSValue Double(AVSValue args, void*, IScriptEnvironment* env); // v11\nAVSValue Floatf(AVSValue args, void*, IScriptEnvironment* env); // v11\nAVSValue Value(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue HexValue(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue HexValue64(AVSValue args, void*, IScriptEnvironment* env); // v11\n\nAVSValue BitAnd(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue BitNot(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue BitOr(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue BitXor(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue BitAnd64(AVSValue args, void*, IScriptEnvironment* env); // v11\nAVSValue BitNot64(AVSValue args, void*, IScriptEnvironment* env); // v11\nAVSValue BitOr64(AVSValue args, void*, IScriptEnvironment* env); // v11\nAVSValue BitXor64(AVSValue args, void*, IScriptEnvironment* env); // v11\n\nAVSValue BitLShift(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue BitRShiftL(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue BitRShiftA(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue BitLShift64(AVSValue args, void*, IScriptEnvironment* env); // v11\nAVSValue BitRShift64L(AVSValue args, void*, IScriptEnvironment* env); // v11\nAVSValue BitRShift64A(AVSValue args, void*, IScriptEnvironment* env); // v11\n\nAVSValue BitRotateL(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue BitRotateR(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue BitRotate64L(AVSValue args, void*, IScriptEnvironment* env); // v11\nAVSValue BitRotate64R(AVSValue args, void*, IScriptEnvironment* env); // v11\n\nAVSValue BitChg(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue BitClr(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue BitSet(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue BitTst(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue BitChg64(AVSValue args, void*, IScriptEnvironment* env); // v11\nAVSValue BitClr64(AVSValue args, void*, IScriptEnvironment* env); // v11\nAVSValue BitSet64(AVSValue args, void*, IScriptEnvironment* env); // v11\nAVSValue BitTst64(AVSValue args, void*, IScriptEnvironment* env); // v11\nAVSValue BitSetCount(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue BitSetCount64(AVSValue args, void*, IScriptEnvironment* env); // v11\n\nAVSValue UCase(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue LCase(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue StrLen(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue RevStr(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue LeftStr(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue MidStr(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue RightStr(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue FindStr(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue FillStr(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue StrCmp(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue StrCmpi(AVSValue args, void*, IScriptEnvironment* env);\n\nAVSValue TrimAll(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue TrimLeft(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue TrimRight(AVSValue args, void*, IScriptEnvironment* env);\n\nAVSValue Rand(AVSValue args, void* user_data, IScriptEnvironment* env);\n\nAVSValue Select(AVSValue args, void*, IScriptEnvironment* env);\n\nAVSValue NOP(AVSValue args, void*, IScriptEnvironment* env);\n\nAVSValue Undefined(AVSValue args, void*, IScriptEnvironment* env);\n\nAVSValue Exist(AVSValue args, void*, IScriptEnvironment* env);\n\n// WE ->\nAVSValue AVSChr(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue AVSOrd(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue AVSTime(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue Spline(AVSValue args, void*, IScriptEnvironment* env);\n// WE <-\n\nAVSValue HasVideo(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue HasAudio(AVSValue args, void*, IScriptEnvironment* env);\n\nAVSValue AvsMin(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue AvsMax(AVSValue args, void*, IScriptEnvironment* env);\n\nAVSValue ScriptName(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue ScriptFile(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue ScriptDir (AVSValue args, void*, IScriptEnvironment* env);\nAVSValue ScriptNameUtf8(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue ScriptFileUtf8(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue ScriptDirUtf8(AVSValue args, void*, IScriptEnvironment* env);\n\nAVSValue AddAutoloadDir (AVSValue args, void*, IScriptEnvironment* env);\nAVSValue ClearAutoloadDirs (AVSValue args, void*, IScriptEnvironment* env);\nAVSValue ListAutoloadDirs(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue AutoloadPlugins (AVSValue args, void*, IScriptEnvironment* env);\nAVSValue FunctionExists (AVSValue args, void*, IScriptEnvironment* env);\nAVSValue InternalFunctionExists (AVSValue args, void*, IScriptEnvironment* env);\n\nAVSValue SetFilterMTMode (AVSValue args, void*, IScriptEnvironment* env);\nAVSValue SetLogParams(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue LogMsg(AVSValue args, void*, IScriptEnvironment* env);\n\nAVSValue SetCacheMode(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue SetDeviceOpt(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue SetMemoryMax(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue SetMaxCPU(AVSValue args, void*, IScriptEnvironment* env); // 20200331\nAVSValue SetFilterProp(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue GetFilterProps(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue SetFilterPropPassthrough(AVSValue args, void*, IScriptEnvironment* env);\n\nAVSValue IsY(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue Is420(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue Is422(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue Is444(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsRGB48(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsRGB64(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue ComponentSize(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue BitsPerComponent(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsYUVA(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsPlanarRGB(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsPlanarRGBA(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue ColorSpaceNameToPixelType(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue NumComponents(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue HasAlpha(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsPackedRGB(AVSValue args, void*, IScriptEnvironment* env);\n\nAVSValue ReplaceStr(AVSValue args, void*, IScriptEnvironment* env); // avs+ 161230\nAVSValue IsVideoFloat(AVSValue args, void*, IScriptEnvironment* env); // avs+ 170309\n\nAVSValue GetProcessInfo(AVSValue args, void*, IScriptEnvironment* env); // avs+ 170526\nAVSValue StrToUtf8(AVSValue args, void*, IScriptEnvironment* env); // avs+ 170601\nAVSValue StrFromUtf8(AVSValue args, void*, IScriptEnvironment* env); // avs+ 170601\n\nAVSValue IsFloatUvZeroBased(AVSValue args, void*, IScriptEnvironment* env); // avs+ 180516\nAVSValue BuildPixelType(AVSValue args, void*, IScriptEnvironment* env); // avs+ 180517\nAVSValue VarExist(AVSValue args, void*, IScriptEnvironment* env); // avs+ 180606\n\nAVSValue ArrayCreate(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue IsArray(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue ArrayGet(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue ArraySize(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue ArrayIns(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue ArrayDel(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue ArraySort(AVSValue args, void*, IScriptEnvironment* env);\n\n#endif  // __Script_H__\n"
  },
  {
    "path": "avs_core/core/parser/scriptparser.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include \"scriptparser.h\"\n#include \"../InternalEnvironment.h\"\n\n\n/********************************\n *******   Script Parser   ******\n *******************************/\n\n\nScriptParser::ScriptParser(IScriptEnvironment* _env, const char* _code, const char* _filename)\n   : env(static_cast<IScriptEnvironment2*>(_env)), tokenizer(_code, _env), code(_code), filename(_filename), loopDepth(0) {}\n\nPExpression ScriptParser::Parse(void)\n{\n  try {\n    return new ExpRootBlock(ParseBlock(false, NULL));\n  }\n  catch (const AvisynthError &ae) {\n    env->ThrowError(\"%s\\n(%s, line %d, column %d)\", ae.msg, filename, tokenizer.GetLine(), tokenizer.GetColumn(code));\n  }\n#ifndef _DEBUG\n  catch (...) {\n    env->ThrowError(\"Parse: Unrecognized exception!\");\n  }\n#endif\n  return 0; // To make VC++ happy.  Why isn't the __declspec(noreturn) on ThrowError good enough?\n}\n\n\nvoid ScriptParser::Expect(int op, const char* msg=0)\n{\n  if (tokenizer.IsOperator(op))\n    tokenizer.NextToken();\n  else {\n    if (msg)\n      env->ThrowError(msg);\n    else {\n      if (op < 256)\n        env->ThrowError(\"Script error: expected `%c'\", op);\n      else\n        env->ThrowError(\"Script error: expected `%c%c'\", (op>>8), (op&255));\n    }\n  }\n}\n\n\nPExpression ScriptParser::ParseFunctionDefinition(void)\n{\n  /*\n  bool global_spcified = false;\n  if (tokenizer.IsIdentifier(\"global\")) {\n    tokenizer.NextToken();\n\n  }\n  */\n  const char* name = nullptr;\n  if (tokenizer.IsIdentifier()) {\n    name = tokenizer.AsIdentifier();\n    tokenizer.NextToken();\n  }\n  const char* var_names[max_args];\n  int var_count = 0;\n  char param_types[4096];\n  int param_chars=0;\n  bool param_floats[max_args];\n  const char* param_names[max_args];\n  int param_count=0;\n\n  // variable capture\n  if (tokenizer.IsOperator('[')) {\n    if (name != nullptr) {\n      env->ThrowError(\"Script error: variable capture is not supported on legacy function definition.\");\n    }\n    tokenizer.NextToken();\n    bool need_comma = false;\n    for (;;) {\n      if (tokenizer.IsOperator(']')) {\n        tokenizer.NextToken();\n        break;\n      }\n      if (need_comma) {\n        Expect(',', \"Script error: expected a , or ]\");\n      }\n\n      if (tokenizer.IsIdentifier()) {\n        var_names[var_count++] = tokenizer.AsIdentifier();\n      }\n      else {\n        env->ThrowError(\"Script error: expected a parameter name\");\n      }\n\n      tokenizer.NextToken();\n      need_comma = true;\n    }\n  }\n\n  if (!tokenizer.IsOperator('{')) {\n    Expect('(', \"Script error: expected ( or { after function name\");\n    bool need_comma = false;\n    bool named_arg_found = false;\n    for (;;) {\n      if (tokenizer.IsOperator(')')) {\n         tokenizer.NextToken();\n        break;\n      }\n      if (need_comma) {\n        Expect(',', \"Script error: expected a , or )\");\n      }\n      if (param_count == max_args) {\n        env->ThrowError(\"Script error: parameter list too long\");\n      }\n\n      param_floats[param_count] = false;\n      char type = '.';\n      char array_kind = ' '; // can be * (zero_or_more) or + (one_or_more)\n      Tokenizer lookahead(&tokenizer);\n      if (lookahead.IsIdentifier() || lookahead.IsString()) {\n        // we have a variable type preceding its name\n        if (tokenizer.IsIdentifier(\"val\")) type = '.';\n        else if (tokenizer.IsIdentifier(\"bool\")) type = 'b';\n        else if (tokenizer.IsIdentifier(\"int\")) type = 'i'; // also accepts 64 bit long since v11\n        else if (tokenizer.IsIdentifier(\"float\")) {\n          param_floats[param_count] = true;\n          type = 'f'; // also accepts doubles since v11\n        }\n        else if (tokenizer.IsIdentifier(\"string\")) type = 's';\n        else if (tokenizer.IsIdentifier(\"clip\")) type = 'c';\n        else if (tokenizer.IsIdentifier(\"func\")) type = 'n';\n        // AVS+ 161028 array type in user defined functions\n        else if (tokenizer.IsIdentifier(\"array\") || tokenizer.IsIdentifier(\"val_array\")) {\n          array_kind = '*';  type = '.';\n          // or: isArray = false;  type = 'a'; ? No. Keeping the old syntax\n          // but .+ must be the very last parameter if parameter is unnamed\n        }\n        else if (tokenizer.IsIdentifier(\"array_nz\") || tokenizer.IsIdentifier(\"val_array_nz\")) {\n          array_kind = '+';  type = '.'; // _nz: non-zero size\n        }\n        else if (tokenizer.IsIdentifier(\"bool_array\")) {\n          array_kind = '*';  type = 'b';\n        }\n        else if (tokenizer.IsIdentifier(\"bool_array_nz\")) {\n          array_kind = '+';  type = 'b';\n        }\n        else if (tokenizer.IsIdentifier(\"int_array\")) {\n          array_kind = '*';  type = 'i';\n        }\n        else if (tokenizer.IsIdentifier(\"int_array_nz\")) {\n          array_kind = '+';  type = 'i';\n        }\n        else if (tokenizer.IsIdentifier(\"float_array\")) {\n          array_kind = '*';  type = 'f';\n        }\n        else if (tokenizer.IsIdentifier(\"float_array_nz\")) {\n          array_kind = '+';  type = 'f';\n        }\n        else if (tokenizer.IsIdentifier(\"string_array\")) {\n          array_kind = '*';  type = 's';\n        }\n        else if (tokenizer.IsIdentifier(\"string_array_nz\")) {\n          array_kind = '+';  type = 's';\n        }\n        else if (tokenizer.IsIdentifier(\"clip_array\")) {\n          array_kind = '*';  type = 'c';\n        }\n        else if (tokenizer.IsIdentifier(\"clip_array_nz\")) {\n          array_kind = '+';  type = 'c';\n        }\n        else if (tokenizer.IsIdentifier(\"func_array\")) {\n          array_kind = '*';  type = 'n';\n        }\n        else if (tokenizer.IsIdentifier(\"func_array_nz\")) {\n          array_kind = '+';  type = 'n';\n        }\n        else env->ThrowError(\"Script error: expected \\\"val\\\", \\\"bool\\\", \\\"int\\\", \\\"float\\\", \\\"string\\\", \\\"array\\\", or \\\"clip\\\" (or their \\\"_array\\\" or \\\"_array_nz\\\" versions\");\n        tokenizer.NextToken();\n      }\n\n      if (tokenizer.IsIdentifier()) {\n        if (named_arg_found)\n          env->ThrowError(\"Script error: can't have a named (quoted) parameter followed by an ordinary parameter\");\n        param_names[param_count++] = tokenizer.AsIdentifier();\n      } else if (tokenizer.IsString()) {\n        named_arg_found = true;\n        const char* param_name = param_names[param_count++] = tokenizer.AsString();\n        int len = lstrlen(param_name);\n        if (param_chars + lstrlen(param_name) >= 4000)\n          env->ThrowError(\"Script error: parameter list too long\");\n        param_types[param_chars] = '[';\n        memcpy(&param_types[param_chars+1], param_name, len);\n        param_types[param_chars+len+1] = ']';\n        param_chars += len+2;\n      } else {\n        env->ThrowError(\"Script error: expected a parameter name\");\n      }\n      param_types[param_chars++] = type;\n      if(array_kind == '*' || array_kind == '+')\n        param_types[param_chars++] = array_kind; // zero or more / one or more\n      tokenizer.NextToken();\n\n      need_comma = true;\n    }\n  }\n\n  int line = tokenizer.GetLine();\n\n  param_types[param_chars] = 0;\n  PExpression body = new ExpRootBlock(ParseBlock(true, NULL));\n\n  const char* saved_param_signature = env->SaveString(param_types);\n\n  if(name != nullptr) {\n    // legacy function definition\n    ScriptFunction* sf = new ScriptFunction(body, param_floats, param_names, param_count);\n    env->AtExit(ScriptFunction::Delete, sf);\n    env->AddFunction(name, saved_param_signature, ScriptFunction::Execute, sf, \"$UserFunctions$\");\n    return new ExpLegacyFunctionDefinition();\n  }\n\n  if (name) {\n    auto envi = static_cast<InternalEnvironment*>(env);\n    envi->UpdateFunctionExports(name, saved_param_signature, \"$UserFunctions$\");\n  }\n\n  return new ExpFunctionDefinition(body, name, saved_param_signature,\n    param_floats, param_names, param_count, var_names, var_count,\n    filename, line);\n  // was before 20200324:\n  // bool is_global = global_spcified || (var_count == 0);\n  // return new ExpFunctionDefinition(name, sf, is_global);\n}\n\n\nPExpression ScriptParser::ParseBlock(bool braced, bool *empty)\n{\n  if (braced) {\n    // allow newlines (and hence comments) before '{' -- Gavino 7 Dec 2009\n    while (tokenizer.IsNewline())\n      tokenizer.NextToken();\n\n    Expect('{');\n  }\n\n  // the purpose of this array and the accompanying code is to produce\n  // a nice balanced binary tree of ExpSequence objects, so that the\n  // maximum call depth in Evaluate grows logarithmically instead of\n  // linearly.\n  // For every i, either trees[i]==0 or it's a balanced tree of (1<<i) elts.\n  PExpression trees[20];\n\n  bool ignore_remainder = false;\n  for (;;) {\n    if (tokenizer.IsNewline()) {\n      tokenizer.NextToken();\n    } else if (tokenizer.IsOperator('}')) {\n      if (braced) {\n        tokenizer.NextToken();\n        break;\n      } else {\n        env->ThrowError(\"Script error: found } without a matching {\");\n      }\n    } else if (tokenizer.IsEOF()) {\n      if (braced) {\n        env->ThrowError(\"Script error: end of file reached without matching }\");\n      } else {\n        break;\n      }\n    } else {\n      bool stop;\n      PExpression exp = ParseStatement(&stop);\n      if (!braced && exp) {\n        auto ep = dynamic_cast<ExpLegacyFunctionDefinition*>((Expression*)(void*)exp);\n        if (ep != nullptr) {\n          // Inhibit legacy function definition to get into expression tree.\n          // Or else \"return last\" would be needed before them.\n          // We check actual type runtime with dynamic cast.\n          exp = nullptr;\n        }\n      }\n      if (exp && !ignore_remainder) {\n        if (filename)\n          exp = new ExpLine(exp, filename, tokenizer.GetLine());\n        for (int i=0; i<20; ++i) {\n          if (trees[i]) {\n            exp = new ExpSequence(trees[i], exp);\n            trees[i] = 0;\n          } else {\n            trees[i] = exp;\n            break;\n          }\n        }\n      }\n      ignore_remainder |= stop;\n    }\n  }\n\n  PExpression result = trees[0];\n  for (int i=1; i<20; ++i) {\n    if (trees[i])\n      result = result ? PExpression(new ExpSequence(trees[i], result)) : trees[i];\n  }\n\n  if (result)\n  {\n    if (empty) *empty = false;\n    return result;\n  }\n  else\n  {\n    if (empty) *empty = true;\n    return PExpression(new ExpConstant(AVSValue()));\n  }\n}\n\n\n\nPExpression ScriptParser::ParseStatement(bool* stop)\n{\n  *stop = false;\n  // null statement\n  if (tokenizer.IsNewline() || tokenizer.IsEOF()) {\n    return 0;\n  }\n  /*\n  // original AVS2.6/old Avs+: function definition returns 0\n  // Function declaration moved more inner\n  // Since Neo/3.6.0 we have function objects besides script functions.\n  // Thus return 0 is conditional and handled outside.\n  else if (tokenizer.IsIdentifier(\"function\")) {\n    tokenizer.NextToken();\n    ParseFunctionDefinition();\n    return 0;\n  }\n  */\n  // exception handling\n  else if (tokenizer.IsIdentifier(\"try\")) {\n    tokenizer.NextToken();\n    PExpression try_block = ParseBlock(true, NULL);\n    while (tokenizer.IsNewline())\n      tokenizer.NextToken();\n    if (!tokenizer.IsIdentifier(\"catch\"))\n      env->ThrowError(\"Script error: expected `catch'\");\n    tokenizer.NextToken();\n    Expect('(');\n    if (!tokenizer.IsIdentifier())\n      env->ThrowError(\"Script error: expected identifier\");\n    const char* id = tokenizer.AsIdentifier();\n    tokenizer.NextToken();\n    Expect(')');\n    return new ExpTryCatch(try_block, id, ParseBlock(true, NULL));\n  }\n  // 'if', 'while', 'for':\n  else if (tokenizer.IsIdentifier(\"if\")) {\n    return ParseIf();\n  }\n  else if (tokenizer.IsIdentifier(\"while\")) {\n    return ParseWhile();\n  }\n  else if (tokenizer.IsIdentifier(\"for\")) {\n    return ParseFor();\n  }\n  // return statement\n  else if (tokenizer.IsIdentifier(\"return\")) {\n    *stop = true;\n    tokenizer.NextToken();\n    return new ExpReturn(ParseAssignmentWithRet());\n  }\n  // break statement\n  else if (tokenizer.IsIdentifier(\"break\")) {\n    if (loopDepth <= 0)\n      throw AvisynthError(\"'Break' statement outside of loop.\");\n    tokenizer.NextToken();\n    return new ExpBreak();\n  }\n  // continue statement\n  else if (tokenizer.IsIdentifier(\"continue\")) {\n    if (loopDepth <= 0)\n      throw AvisynthError(\"'Continue' statement outside of loop.\");\n    tokenizer.NextToken();\n    return new ExpContinue();\n  }\n  else {\n    return ParseAssignment();\n  }\n}\n\nPExpression ScriptParser::ParseIf(void)\n{\n  bool blockEmpty;\n\n  PExpression If, Then, Else = 0;\n  tokenizer.NextToken();\n  Expect('(');\n  If = ParseAssignmentWithRet();\n  Expect(')');\n\n  Then = ParseBlock(true, &blockEmpty);\n  if (blockEmpty)\n    Then = NULL;\n\n  while (tokenizer.IsNewline())\n    tokenizer.NextToken();\n  if (tokenizer.IsIdentifier(\"else\")) {\n    tokenizer.NextToken();\n\n    if (tokenizer.IsIdentifier(\"if\"))\n    {\n      Else = ParseIf();\n    }\n    else\n    {\n      Else = ParseBlock(true, &blockEmpty);\n      if (blockEmpty)\n        Else = NULL;\n    }\n  }\n  return new ExpBlockConditional(If, Then, Else);\n}\n\nPExpression ScriptParser::ParseWhile(void)\n{\n  tokenizer.NextToken();\n  Expect('(');\n  const PExpression cond = ParseAssignmentWithRet();\n  Expect(')');\n\n  ++loopDepth;\n  bool blockEmpty;\n  PExpression body = ParseBlock(true, &blockEmpty);\n  if (blockEmpty)\n    body = NULL;\n  --loopDepth;\n\n  return new ExpWhileLoop(cond, body);\n}\n\nPExpression ScriptParser::ParseFor(void)\n{\n  tokenizer.NextToken();\n  Expect('(');\n  if (!tokenizer.IsIdentifier())\n    env->ThrowError(\"Script error: expected a variable name\");\n  const char* id = tokenizer.AsIdentifier();\n  tokenizer.NextToken();\n  Expect('=');\n  const PExpression init = ParseAssignmentWithRet();\n  Expect(',');\n  const PExpression limit = ParseAssignmentWithRet();\n  PExpression step = NULL;\n  if (tokenizer.IsOperator(',')) {\n    tokenizer.NextToken();\n    step = ParseAssignmentWithRet();\n  } else {\n    step = PExpression(new ExpConstant(AVSValue(1)));\n  }\n\n  Expect(')');\n\n  ++loopDepth;\n  bool blockEmpty;\n  PExpression body = ParseBlock(true, &blockEmpty);\n  if (blockEmpty)\n    body = NULL;\n  --loopDepth;\n\n  return new ExpForLoop(id, init, limit, step, body);\n}\n\nPExpression ScriptParser::ParseAssignment(void)\n{\n  if (tokenizer.IsIdentifier(\"global\")) {\n    tokenizer.NextToken();\n    if (!tokenizer.IsIdentifier())\n      env->ThrowError(\"Script error: `global' must be followed by a variable name\");\n    const char* name = tokenizer.AsIdentifier();\n    tokenizer.NextToken();\n    Expect('=');\n    PExpression exp = ParseConditional();\n\treturn new ExpGlobalAssignment(name, exp);\n  }\n  PExpression exp = ParseAssignmentWithRet();\n  if (tokenizer.IsOperator('=')) {\n    const char* name = exp->GetLvalue();\n    if (!name)\n      env->ThrowError(\"Script error: left operand of `=' must be a variable name\");\n    tokenizer.NextToken();\n\texp = ParseAssignmentWithRet();\n    return new ExpAssignment(name, exp);\n  }\n\n  return exp;\n}\n\nPExpression ScriptParser::ParseAssignmentWithRet(void)\n{\n\tPExpression exp = ParseConditional();\n\tif (tokenizer.IsOperator(\":=\"_i)) {\n\t\tconst char* name = exp->GetLvalue();\n\t\tif (!name)\n\t\t\tenv->ThrowError(\"Script error: left operand of `:=' must be a variable name\");\n\t\ttokenizer.NextToken();\n\t\texp = ParseAssignmentWithRet();\n\t\treturn new ExpAssignment(name, exp, true);\n\t}\n\treturn exp;\n}\n\nPExpression ScriptParser::ParseConditional(void)\n{\n  PExpression a = ParseOr();\n  if (tokenizer.IsOperator('?')) {\n    tokenizer.NextToken();\n    PExpression b = ParseAssignmentWithRet();\n    Expect(':');\n    PExpression c = ParseAssignmentWithRet();\n    return new ExpConditional(a, b, c);\n  }\n  return a;\n}\n\nPExpression ScriptParser::ParseOr(void)\n{\n  PExpression left = ParseAnd();\n  if (tokenizer.IsOperator(\"||\"_i)) {\n    tokenizer.NextToken();\n    PExpression right = ParseOr();\n    return new ExpOr(left, right);\n  }\n  return left;\n}\n\nPExpression ScriptParser::ParseAnd(void)\n{\n  PExpression left = ParseComparison();\n  if (tokenizer.IsOperator(\"&&\"_i)) {\n    tokenizer.NextToken();\n    PExpression right = ParseAnd();\n    return new ExpAnd(left, right);\n  }\n  return left;\n}\n\n\nPExpression ScriptParser::ParseComparison(void)\n{\n  PExpression left = ParseAddition(false);\n  PExpression result;\n  int op;\n  while ((op = GetTokenAsComparisonOperator()) != 0) {\n    tokenizer.NextToken();\n    PExpression right = ParseAddition(false);\n    PExpression term;\n    switch (op) {\n      case \"==\"_i: term = new ExpEqual(left, right); break;\n      case \"!=\"_i: term = new ExpNot(new ExpEqual(left, right)); break;\n      case \"<>\"_i: term = new ExpNot(new ExpEqual(left, right)); break;\n      case '<': term = new ExpLess(left, right); break;\n      case \">=\"_i: term = new ExpNot(new ExpLess(left, right)); break;\n      case '>': term = new ExpLess(right, left); break;\n      case \"<=\"_i: term = new ExpNot(new ExpLess(right, left)); break;\n    }\n    result = !result ? term : PExpression(new ExpAnd(result, term));\n    left = right;\n  }\n  return result ? result : left;\n}\n\n\n\nPExpression ScriptParser::ParseAddition(bool negationOnHold) //update exterior calls to ParseAddition(false)\n{\n  PExpression left = ParseMultiplication(negationOnHold);\n  bool plus = tokenizer.IsOperator('+');\n  bool minus = tokenizer.IsOperator('-');\n  bool doubleplus = tokenizer.IsOperator(\"++\"_i);\n  if (plus || minus || doubleplus) {\n    tokenizer.NextToken();\n    PExpression right = ParseAddition(minus);\n    if (doubleplus) {\n      return new ExpDoublePlus(left, right);\n    }\n    return new ExpPlus(left, right);   //no longer ExpMinus  'right' will be negated when needed\n  }\n  return left;\n}\n\nPExpression ScriptParser::ParseMultiplication(bool negationOnHold)\n{\n  PExpression left = ParseUnary();\n\n  for (;;) {\n    bool mult = tokenizer.IsOperator('*');\n    bool div = tokenizer.IsOperator('/');\n    bool mod = tokenizer.IsOperator('%');\n\n    if (mult || div || mod)\n      tokenizer.NextToken();\n    else break;                                 //exits the while if not a mult op\n\n    PExpression right = ParseUnary();\n    if (mult)\n      left = new ExpMult(left, right);\n    else if (div)\n      left = new ExpDiv(left, right);\n    else\n      left = new ExpMod(left, right);\n  }\n\n  if (negationOnHold)   //negate the factorised result if needed\n    left = new ExpNegate(left);\n  return left;\n}\n\n\nPExpression ScriptParser::ParseUnary(void) {\n  // accept '+' with anything\n  while (tokenizer.IsOperator('+'))\n    tokenizer.NextToken();\n\n  if (tokenizer.IsOperator('-')) {\n    tokenizer.NextToken();\n    return new ExpNegate(ParseUnary());\n  }\n  else if (tokenizer.IsOperator('!')) {\n    tokenizer.NextToken();\n    return new ExpNot(ParseUnary());\n  }\n  else {\n    return ParseOOP();\n  }\n}\n\nPExpression ScriptParser::ParseOOP(void)\n{\n  // check if need convert [] brackets to function calls: Array() and ArrayGet()\n  // no context and [: e.g. x = [23,2] --> x = Array(23,2)\n  PExpression left;\n  if (tokenizer.IsOperator('['))\n    left = ParseArray(nullptr);\n  else\n    left = ParseFunction(nullptr);\n  while (tokenizer.IsOperator('.') || tokenizer.IsOperator('[')) {\n    // OOP '.' or array indexing\n    // somename.function( ...\n    // somename[ ... : e.g. x = a[23,2] --> x = a.ArrayGet(23,2)\n    // context is 'somename'\n    const bool isArraySpecifier = tokenizer.IsOperator('[');\n    tokenizer.NextToken();\n    if(isArraySpecifier)\n      left = ParseArray(left);\n    else\n      left = ParseFunction(left);\n  }\n  return left;\n}\n\nPExpression ScriptParser::ParseArray(PExpression context)\n{\n  PExpression left;\n  if (context)\n    left = new ExpVariableReference(\"ArrayGet\"); // x = a[2,1] -> x = a.ArrayGet(2,1)\n  else\n    left = new ExpVariableReference(\"Array\"); // x = [23,3] --> x = Array(23,3)\n  PExpression result = ParseCall(left, context, true); // true: array syntax\n  return result;\n}\n\nPExpression ScriptParser::ParseFunction(PExpression context)\n{\n  PExpression left = ParseAtom();\n  if (context || tokenizer.IsOperator('(')) {\n    return ParseCall(left, context, false); // false: function syntax\n  }\n  return left;\n}\n\n/*\n  -NEW_AVSVALUE means arrays\n  - AVSValue deep copy for arrays (arrays in arrays in ...)\n    constant script arrays\n    array_variable = [[1, 2, 3], [4, 5, 8], \"hello\"]\n    dictionary = [[\"one\", 1], [\"two\", 2]]\n    empty = []\n    subarray = array_variable[0]\n    val = subarray[2]\n    val2 = array_variable[1, 3]\n    str = array_variable[2]\n    n = ArraySize(array_variable) #3\n    n2 = ArraySize(empty) #0\n    val3 = dictionary[\"two\"]\n\n    - arrays as filter parameters(named and unnamed) :\n    new 'a' type or use '.+' or '.*' and check AVSValue IsArray()\n    Concept is incompatible with avs 2.5 plugins due to their 'baked' interface code\n*/\nPExpression ScriptParser::ParseCall(PExpression left, PExpression context, bool isArraySpecifier)\n{\n  // though parser can do here arrays in general, isArraySpecifier is always false for non AVS_NEWVALUE\n  // array references are using [] brackets which are here\n  // converted to Array() and ArrayGet functions depending on the position\n  // x = a[23] --> x = a.ArrayGet(23)  has a variable reference (context is not null)\n  // x = [2,3] -> x = Array(2,3)       no context\n\n  // function\n  PExpression args[max_args];\n  const char* arg_names[max_args];\n  memset(arg_names, 0, sizeof(arg_names));\n  int params_count = 0;\n  int i=0;\n  if (context)\n    args[i++] = context; // first arg is the object before '.' or '['\n\n  if (\n    isArraySpecifier ||\n    tokenizer.IsOperator('(')) {\n\n    if(!(context != nullptr && isArraySpecifier)) // ParseOOP already had [ and also the next token\n      tokenizer.NextToken();\n\n    const char end_bracket = isArraySpecifier ? ']' : ')';\n    // arrays are delimited by ], functions by )\n\n    bool need_comma = false;\n    for (;;) {\n      if(tokenizer.IsOperator(end_bracket))\n      {\n        tokenizer.NextToken();\n        break;\n      }\n      if (need_comma) {\n        if(isArraySpecifier)\n          Expect(',', \"Script error: expected a , or ]\");\n        else\n          Expect(',', \"Script error: expected a , or )\");\n      }\n      // check for named argument syntax (name=val) for functions\n      if (!isArraySpecifier && tokenizer.IsIdentifier()) {\n        Tokenizer lookahead(&tokenizer);\n        if (lookahead.IsOperator('=')) {\n          arg_names[i] = tokenizer.AsIdentifier();\n          tokenizer.NextToken();\n          tokenizer.NextToken();\n        }\n      }\n      if (i == max_args) {\n        env->ThrowError(\"Script error: argument list too long\");\n      }\n      args[i++] = ParseAssignmentWithRet();\n      params_count++;\n      need_comma = true;\n    }\n  }\n\n  if (isArraySpecifier && params_count == 0)\n  {\n    if (context != nullptr)\n      env->ThrowError(\"Script error: array indexing must have at least one index\");\n    // contextless case is empty array definition: x = []\n  }\n\n  const char* name = left->GetLvalue();\n  if (name && i == 1 && args[0]->GetLvalue() && lstrcmpi(name, \"func\") == 0) {\n    // special case the parser should deal with\n    // \"func(LegacyFunctionName)\"\n    left = new ExpFunctionWrapper(args[0]->GetLvalue());\n  }\n  else {\n    // we have to set this true for array definitions x = [2,3] or else an\n    // implicite \"last\" will be passed on by ExpFunctionCall::Evaluate\n    const bool oop_notation_aka_disable_implicite_last = !!context || isArraySpecifier;\n    left = new ExpFunctionCall(name, left, args, arg_names, i, oop_notation_aka_disable_implicite_last);\n  }\n\n  if (tokenizer.IsOperator('(')) {\n    return ParseCall(left, nullptr, false);\n  }\n  return left;\n\n}\n\nPExpression ScriptParser::ParseAtom(void)\n{\n  if (tokenizer.IsIdentifier(\"function\")) {\n    tokenizer.NextToken();\n    return ParseFunctionDefinition();\n  }\n  else if (tokenizer.IsIdentifier()) {\n    const char* name = tokenizer.AsIdentifier();\n    tokenizer.NextToken();\n    return new ExpVariableReference(name);\n  }\n  else if (tokenizer.IsInt()) {\n    int result = tokenizer.AsInt();\n    tokenizer.NextToken();\n    return new ExpConstant(result);\n  }\n  else if (tokenizer.IsLong()) {\n    int64_t result = tokenizer.AsLong();\n    tokenizer.NextToken();\n    return new ExpConstant(result);\n  }\n  else if (tokenizer.IsFloat()) {\n    double result = tokenizer.AsFloat();\n    tokenizer.NextToken();\n    return new ExpConstant(result);\n  }\n  else if (tokenizer.IsString()) {\n    const char* result = tokenizer.AsString();\n    tokenizer.NextToken();\n    return new ExpConstant(result);\n  }\n#ifdef ARRAYS_AT_TOKENIZER_LEVEL\n  else if (tokenizer.IsArray()) {\n    std::vector<AVSValue>* result = tokenizer.AsArray(); // PF tokenizer returns new array\n    tokenizer.NextToken();\n    return new ExpConstant(result);\n  }\n#endif\n  else if (tokenizer.IsOperator('(')) {\n    tokenizer.NextToken();\n    PExpression result = ParseAssignmentWithRet();\n    Expect(')');\n    return result;\n  }\n  else if (tokenizer.IsOperator('[')) { // array\n    // with NEW_AVSVALUE this case is unreachable\n    env->ThrowError(\"Script error: array is not supported on this version of avisynth\");\n    return 0;\n  }\n  else {\n    env->ThrowError(\"Script error: syntax error\");\n    return 0;\n  }\n}\n\nint ScriptParser::GetTokenAsComparisonOperator()\n{\n  if (!tokenizer.IsOperator())\n    return 0;\n  int op = tokenizer.AsOperator();\n  if (op == \"==\"_i || op == \"!=\"_i || op == \"<>\"_i || op == '<' || op == '>' || op == \"<=\"_i || op == \">=\"_i)\n    return op;\n  else\n    return 0;\n}\n\n"
  },
  {
    "path": "avs_core/core/parser/scriptparser.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __ScriptParser_H__\n#define __ScriptParser_H__\n\n#include <avisynth.h>\n#include \"expression.h\"\n#include \"tokenizer.h\"\n#include \"script.h\"\n\n\n/********************************************************************\n********************************************************************/\n\n\n\nclass ScriptParser\n/**\n  * Insert intelligent comment here\n **/\n{\npublic:\n  ScriptParser(IScriptEnvironment* _env, const char* _code, const char* _filename);\n\n  PExpression Parse(void);\n\n  enum {max_args=1024};\n  // fixme: consider using vectors\n\nprivate:\n  IScriptEnvironment2* const env;\n  Tokenizer tokenizer;\n  const char* const code;\n  const char* const filename;\n  int loopDepth;    // how many loops are we in during parsing\n\n  void Expect(int op, const char* msg);\n\n  PExpression ParseFunctionDefinition(void);\n\n  PExpression ParseBlock(bool braced, bool *empty);\n  PExpression ParseStatement(bool* stop);\n  PExpression ParseAssignment(void);\n  PExpression ParseAssignmentWithRet(void);\n  PExpression ParseConditional(void);\n  PExpression ParseOr(void);\n  PExpression ParseAnd(void);\n  PExpression ParseComparison(void);\n  PExpression ParseAddition(bool negationOnHold);\n  PExpression ParseMultiplication(bool negationOnHold);\n  PExpression ParseUnary(void);\n  PExpression ParseOOP(void);\n  PExpression ParseArray(PExpression context);\n  PExpression ParseFunction(PExpression context);\n  PExpression ParseCall(PExpression left, PExpression context, bool isArraySpecifier);\n  PExpression ParseAtom(void);\n\n  PExpression ParseIf(void);\n  PExpression ParseWhile(void);\n  PExpression ParseFor(void);\n\n  // helper for ParseComparison\n  int GetTokenAsComparisonOperator();\n};\n\n// The following allows us to write multi-character tokens as string literals.\n// Originally, non-conformant multi-character characters were used.\n// For example: int('012') == 0x303132. Hence, the rightmost character\n// is placed at the least significant byte.\nstatic constexpr int operator \"\"_i(const char s[], const size_t len) {\n  int acc = 0;\n  for (size_t i = 0; i < len; ++i)\n    acc = (acc << 8) + (unsigned char) s[i];\n  return acc;\n}\n\n\n#endif  // __ScriptParser_H__\n"
  },
  {
    "path": "avs_core/core/parser/tokenizer.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include \"tokenizer.h\"\n#include \"../InternalEnvironment.h\"\n#ifdef AVS_WINDOWS\n#include <avs/win.h>\n#else\n#include <avs/posix.h>\n#endif\n\n#include <cfloat>\n#include <climits>\n\n\n\n/****************************\n *******   Tokenizer   ******\n ***************************/\n\nTokenizer::Tokenizer(const char* pc, IScriptEnvironment* _env)\n  : env(_env)\n{\n  this->pc = pc;\n  this->line = 1;\n  this->type = 0;\n  NextToken();\n}\n\nTokenizer::Tokenizer(Tokenizer* old)\n  : env(old->env)\n{\n  pc = old->pc;\n  line = old->line;\n  type = old->type;\n  NextToken();\n}\n\nbool Tokenizer::IsIdentifier(const char* id) const\n{\n  return IsIdentifier() && !lstrcmpi(id, identifier);\n}\n\n\nvoid Tokenizer::NextToken() {\n\n  if (IsNewline())\n    line++;\n\n  // skip whitespace, comments, and escaped newlines\n\n  for (;;) {\n    SkipWhitespace();\n    if (*pc == '\\\\') {\n      // eat backslash followed by newline\n      const char* const old_pc = pc;\n      pc++;\n      SkipWhitespace();\n      if (*pc == '\\n' || *pc == '\\r') {\n        SkipNewline();\n        continue;\n      } else {\n        token_start = old_pc;\n        env->ThrowError(\"Script error: `\\\\' can only appear at the beginning or end of a line\");\n      }\n    } else if (*pc == '\\n' || *pc == '\\r') {\n      // skip newline if it's followed by backslash or `{'     }\n      const char* const old_pc = pc;\n      const int old_line = line;\n      do {\n        SkipNewline();\n        SkipWhitespace();\n      } while (*pc == '\\n' || *pc == '\\r');\n      if (*pc == '\\\\') {\n        pc++;\n        continue;\n      } else if (*pc == '{') {\n        break;\n      } else {\n        pc = old_pc;\n        line = old_line;\n        break;\n      }\n    } else if (*pc == '#') {\n      // skip from # to end of line (comment)\n      while (*pc != 0 && *pc != '\\n' && *pc != '\\r')\n        pc++;\n      break;\n    } else if (pc[0] == '/' && pc[1] == '*') {    // Block comment /* */\n      const char *end = strstr(pc+2, \"*/\");\n      if (!end)\n        env->ThrowError(\"Parse error: block comment missing closing */\");\n\n      for (const char *cp = pc+2; cp < end; cp++) {\n        if (*cp == '\\n') { line++; }\n      }\n      pc = end+2;\n      continue;\n    } else if (pc[0] == '*' && pc[1] == '/') {\n      env->ThrowError(\"Parse error: orphan block comment closing */\");\n\n    } else if (pc[0] == '[' && pc[1] == '*') {    // Nestable block comment [* *]\n      const char *end = strstr(pc+2, \"*]\");\n      const char *nest = strstr(pc+2, \"[*\");\n\n      while (nest && nest+1 < end) {\n        end = strstr(end+2, \"*]\");\n        nest = strstr(nest+2, \"[*\");\n      }\n      if (!end)\n        env->ThrowError(\"Parse error: nestable block comment missing closing *]\");\n\n      for (const char *cp = pc+2; cp < end; cp++) {\n        if (*cp == '\\n') { line++; }\n      }\n      pc = end+2;\n      continue;\n    } else if (pc[0] == '*' && pc[1] == ']') {\n      env->ThrowError(\"Parse error: orphan nestable block comment closing *]\");\n\n    } else {\n      break;\n    }\n  }\n\n  token_start = pc;\n\n  switch (*pc) {\n\n    case 0:\n      type = 0;\n      break;\n\n    case '\\n': case '\\r':\n      SkipNewline();\n      type = 'n';\n      line--;\n      break;\n\n    case '.':\n      // a '.' followed by a digit is a number, otherwise it's an operator\n      if (isdigit(pc[1])) {\n        GetNumber();\n      } else {\n        ++pc;\n        SetToOperator('.');\n      }\n      break;\n\n    case '<':    // these operators have versions followed by '='\n      if ((pc[1] == '=') || (pc[1] == '>')) {\n        SetToOperator(pc[0] * 256 + pc[1]);\n        pc += 2;\n      } else {\n        SetToOperator(*pc++);\n      }\n      break;\n\n    case '>':    // these operators have versions followed by '='\n    case '!':\n    case '=':\n      if (pc[1] != '=') {\n        SetToOperator(*pc++);\n      } else {\n        SetToOperator(pc[0] * 256 + pc[1]);\n        pc += 2;\n      }\n      break;\n\n    case '+':    // these operators have single and double (++, &&, ||, ==) versions\n    case '&':\n    case '|':\n      if (pc[1] != pc[0]) {\n        SetToOperator(*pc++);\n      } else {\n        SetToOperator(pc[0] * 256 + pc[1]);\n        pc += 2;\n      }\n      break;\n\n    case '{':    // these operators are always lone characters\n    case '}':\n    case '(':\n    case ')':\n    case '[': // variable capture for function definition\n    case ']':\n    case ',':\n    case '?':\n    case ':':\n    case '-':\n    case '*':\n    case '/':\n    case '%':\n      SetToOperator(*pc++);\n      break;\n\n    case '$':\n      // hexadecimal constant $FFFFFFFF remains -1 int;\n      // or suffixed with L for 64 bit data: 0xFFFFFFFFL becomes 0x00000000FFFFFFFF\n    {\n      bool long64bit = false;\n      type = 'l';\n      longlong = 0;\n      ++pc;\n      do {\n        if (*pc >= '0' && *pc <= '9')\n          longlong = longlong * 16 + (*pc - '0');\n        else if (*pc >= 'a' && *pc <= 'f')\n          longlong = longlong * 16 + (*pc - 'a' + 10);\n        else if (*pc >= 'A' && *pc <= 'F')\n          longlong = longlong * 16 + (*pc - 'A' + 10);\n        else if (*pc == 'L' || *pc == 'l') {\n          long64bit = true;\n          ++pc;\n          break; // nothing allowed after L cast\n        }\n        else\n          env->ThrowError(\"$ must be followed by a hexadecimal number\");\n      } while (isalnum(*++pc));\n      if (!long64bit) {\n        // Default is integer.\n        // Thus we can avoid the color (like $FFFFFFFF) constants\n        // to be casted to 64 bit.\n        type = 'i';\n        integer = (int)longlong;\n      }\n    }\n    break;\n\n    default:\n      if(*pc == '\"' || (*pc == 'e' && pc[1] == '\"')) { // string\n        bool escape = false;\n        if (*pc == 'e') {\n          escape = true;\n          ++pc;\n        }\n        const char *start, *end;\n        if (pc[1] == '\"' && pc[2] == '\"') {\n          // \"\"\"...\"\"\"\n          start = pc+3;\n          bool escaped_quotation = false;\n          auto tmp_start = start;\n          do {\n            end = strstr(tmp_start, \"\\\"\\\"\\\"\");\n            if (!end)\n              env->ThrowError(\"Parse error: string missing closing quotation marks\");\n            escaped_quotation = escape && (*(end - 1) == '\\\\');\n            if (escaped_quotation)\n              tmp_start = end + 1;\n          } while (escaped_quotation);\n\n          while (end[3] == '\"')\n            end++;\n          pc = end+3;\n        } else {\n          // \"...\"\n          start = pc+1;\n          bool escaped_quotation = false;\n          auto tmp_start = start;\n          do {\n            end = strchr(tmp_start, '\"');\n            if (!end)\n              env->ThrowError(\"Parse error: string missing closing quotation mark\");\n            escaped_quotation = escape && (*(end - 1) == '\\\\');\n            if (escaped_quotation)\n              tmp_start = end + 1;\n          } while (escaped_quotation);\n\n          /* I like the ability to have newlines in strings, thanks */\n          // const char *cr = strchr(start, '\\r'), *lf = strchr(start, '\\n');\n          // if ((cr && cr < end) || (lf && lf < end))\n          //   env->ThrowError(\"Parse error: newline found in string\");\n\n          pc = end+1;\n        }\n        for (const char *cp = start; cp < end; cp++) {\n          if (*cp == '\\n') { line++; }\n        }        type = 's';\n        string = static_cast<InternalEnvironment*>(env)->SaveString(start, int(end-start), escape);\n      }\n      else if (isdigit(*pc)) {\n        // number\n        GetNumber();\n      } else if (*pc == '_' || isalpha(*pc)) {\n        // identifier\n        do {\n          pc++;\n        } while (*pc == '_' || isalnum(*pc));\n        type = 'I';\n        identifier = env->SaveString(token_start, int(pc - token_start));\n        if (!lstrcmpi(identifier, \"__END__\")) {\n          type = 0;\n        }\n      } else {\n        env->ThrowError(\"unexpected character \\\"%c\\\"\", *pc);\n      }\n      break;\n  }\n}\n\n\nint Tokenizer::GetColumn(const char* start_of_string) const\n{\n    const char* x = pc;\n    while (x > start_of_string && x[-1] != '\\n' && x[-1] != '\\r')\n      x--;\n    return int(pc-x);\n}\n\n\nvoid Tokenizer::SkipWhitespace()\n{\n  while (*pc == ' ' || *pc == '\\t')\n    pc++;\n}\n\nvoid Tokenizer::SkipNewline()\n{\n  if (*pc == '\\n' || *pc == '\\r')\n  {\n    pc++;\n    line++;\n    if ((*pc == '\\n' || *pc == '\\r') && *pc != *(pc-1))\n      pc++;\n  }\n}\n\nvoid Tokenizer::AssertType(char expected_type) const\n{\n  if (type != expected_type)\n    ThrowTypeMismatch(expected_type, type, env);\n}\n\nvoid Tokenizer::GetNumber()\n{\n  // old: start by assuming an int and switch to float if necessary\n  // v11: default precision is 64 bit\n  //      start by assuming long and switch to double if necessary\n  constexpr int64_t INT64_MAX_DIV_10 = INT64_MAX / 10;\n  constexpr int64_t INT64_MAX_MOD_10 = INT64_MAX % 10;\n  type = 'l';\n  longlong = 0;\n  double dtemp = 0;\n  double place = 1;\n\n  do {\n    if (*pc == '.') {\n      // first, gather into double\n      type = 'f';\n      ++pc;\n      while (isdigit(*pc)) {\n        place *= 10;\n        dtemp = dtemp * 10 + (*pc - '0');\n        ++pc;\n      }\n      break;\n    }\n    else {\n      if (type != 'f') {\n        // Check for potential overflow before performing the operation, but go on anyway\n        if (longlong > INT64_MAX_DIV_10 || (longlong == INT64_MAX_DIV_10 && (*pc - '0') > INT64_MAX_MOD_10))\n          type = 'f';\n        else\n          longlong = longlong * 10 + (*pc - '0');\n      }\n      dtemp = dtemp * 10 + (*pc - '0'); // gather always\n    }\n    ++pc;\n  } while (isdigit(*pc) || *pc == '.');\n\n  dtemp /= place;\n  if (dtemp >= DBL_MAX)\n    env->ThrowError(\"Tokenizer: Number is to big.\");\n\n  if (type == 'f') {\n    double_pt = dtemp; // v11: type name remained 'f' but content is double\n  }\n  else if (longlong <= INT_MAX) {\n    // store into a more simple type\n    type = 'i';\n    integer = (int)longlong;\n  }\n}\n\n\nvoid Tokenizer::SetToOperator(int o)\n{\n  type = 'o';\n  op = o;\n}\n\n\n\n/**** Helper Functions ****/\n\nstatic const char* GetTypeName(char type)\n{\n  switch (type)\n  {\n    case 0:   return \"undefined\";\n    case 'a': return \"array\";\n    case 'b': return \"boolean\";\n    case 'c': return \"clip\";\n    case 'I': return \"identifier\";\n    case 'f': return \"floating-point\"; // v11: double\n    case 'i': return \"integer\";\n    case 'l': return \"long\";\n    case 'o': return \"operator\";\n    case 's': return \"string\";\n    default: return \"unknown\";\n  }\n}\n\n\nvoid ThrowTypeMismatch(char expected, char actual, IScriptEnvironment* env)\n{\n  env->ThrowError(\"Tokenizer: expected type '%s' doesn't match actual type '%s' (this is a bug)\",\n      GetTypeName(expected), GetTypeName(actual));\n}\n\n"
  },
  {
    "path": "avs_core/core/parser/tokenizer.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#ifndef __Tokenizer_H__\n#define __Tokenizer_H__\n\n#include <avisynth.h>\n#include <vector>\n\n/*********************************************************\n*********************************************************/\n\n\nclass Tokenizer\n/**\n  * Breaks up scripts into tokens\n **/\n{\npublic:\n  Tokenizer(const char* pc, IScriptEnvironment* _env);\n  explicit Tokenizer(Tokenizer* old);\n\n  void NextToken();\n  \n  // unlike AVSValue, these Is-of-Type checks are exact\n  inline bool IsIdentifier() const { return type == 'I'; }\n  inline bool IsOperator() const { return type == 'o'; }\n  inline bool IsInt() const { return type == 'i'; }\n  inline bool IsFloat() const { return type == 'f'; } // means by double internally\n  inline bool IsLong() const { return type == 'l'; } \n  inline bool IsString() const { return type == 's'; }\n#ifdef ARRAYS_AT_TOKENIZER_LEVEL\n  inline bool IsArray() const { return type == 'a'; }\n#endif\n  inline bool IsNewline() const { return type == 'n'; }\n  inline bool IsEOF() const { return type == 0; }\n\n  bool IsIdentifier(const char* id) const;\n  inline bool IsOperator(int o) const\n    { return IsOperator() && o == op; }\n\n  const char* AsIdentifier() const { AssertType('I'); return identifier; }\n  int AsOperator() const { AssertType('o'); return op; }\n  int AsInt() const { AssertType('i'); return integer; }\n  //float AsFloat() const { AssertType('f'); return floating_pt; }\n  double AsFloat() const { AssertType('f'); return double_pt; } // v11: using double internally\n  int64_t AsLong() const { AssertType('l'); return longlong; }\n  const char* AsString() const { AssertType('s'); return string; }\n#ifdef ARRAYS_AT_TOKENIZER_LEVEL\n  std::vector<AVSValue>* AsArray() const { AssertType('a'); return array2; }\n#endif\n\n  int GetLine() const { return line; }\n  int GetColumn(const char* start_of_string) const;\n\nprivate:\n  void SkipWhitespace();\n  void SkipNewline();\n  void GetNumber();\n  void AssertType(char expected_type) const;\n  void SetToOperator(int o);\n\n  IScriptEnvironment* const env;\n  const char* token_start;\n  const char* pc;\n  int line;\n  char type;   // 'I'dentifier, 'o'perator, 'i'nt, 'f'loat, 's'tring, 'n'ewline, 'a'rray, 'l'ong, 0=eof. no 'd', float holds double\n  union\n  {\n    const char* identifier;\n    const char* string;\n    int op;   // '+', '++', '.', ',', '(', ')','[', ']', 0=eoln\n    int integer;\n    //float floating_pt; replaced by double internally\n    int64_t longlong; // if it fits, integer is used instead (leave as much compatibility)\n    double double_pt;\n#ifdef ARRAYS_AT_TOKENIZER_LEVEL\n    // not used now, finally arrays are implemented with helper script functions\n    std::vector<AVSValue>* array2;\n#endif\n  };\n};\n\n\n\n/**** Helper functions ****/\n\nvoid ThrowTypeMismatch(char expected, char actual, IScriptEnvironment* env);\n\n\n#endif  // __Tokenizer_H__"
  },
  {
    "path": "avs_core/core/strings.cpp",
    "content": "// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include <avs/config.h>\n#ifdef AVS_WINDOWS\n#include <io.h>\n#include <avs/win.h>\n#else\n#include <avs/posix.h>\n#include \"parser/os/win32_string_compat.h\"\n#endif\n#include <avs/filesystem.h>\n\n#include \"strings.h\"\n#include <cassert>\n#include <string>\n#include <algorithm>\n#include <codecvt>\n#include <locale>\n#include <vector>\n\n\nstatic inline char tolower(char c)\n{\n  // Works for letters of the english alphabet in ASCII\n  return ((c >=65) && (c <=90)) ? c + 32 : c;\n}\n\nbool streqi(const char* s1, const char* s2)\n{\n  // Why we dont use Windows's lstrcmpi? It is by multiple orders of magnitude slower and non-portable.\n  // lstrcmpi handles locales and UTF and whatnot, but because variable and function names in Avisynth\n  // are limited to ASCII, we don't need that funcationality.\n\n  while(1)\n  {\n    if ((*s1 == 0) && (*s2 == 0))\n      return true;\n\n    if (tolower(*s1) != tolower(*s2))\n      return false;\n\n    ++s1;\n    ++s2;\n  }\n\n  assert(0);\n  return false;\n}\n\nstd::string concat(const std::string &s1, const std::string &s2)\n{\n  std::string ret(s1);\n  return ret.append(s2);\n}\n\nbool replace(std::string &haystack, const std::string &needle, const std::string &newStr)\n{\n  bool replaced = false;\n  for(size_t pos = 0; ; pos += newStr.length())\n  {\n    // Locate the substring to replace\n    pos = haystack.find(needle, pos);\n    if(pos == std::string::npos) break;\n    // Replace by erasing and inserting\n    haystack.erase(pos, needle.length());\n    haystack.insert(pos, newStr);\n    replaced = true;\n  }\n\n  return replaced;\n}\n\nbool replace_beginning(std::string &haystack, const std::string &needle, const std::string &newStr)\n{\n  // Locate the substring to replace\n  size_t pos = haystack.find(needle);\n  if(pos == std::string::npos) return false;\n  if(pos != 0) return false;\n\n  // Replace by erasing and inserting\n  haystack.erase( pos, needle.length() );\n  haystack.insert( pos, newStr );\n\n  return true;\n}\n\nbool replace(std::string &haystack, char needle, char newChar)\n{\n  std::string haystack_bck = haystack;\n  std::replace(haystack.begin(),haystack.end(), needle, newChar);\n  return haystack.compare(haystack_bck) != 0;\n}\n\nconst char* ws = \" \\t\\n\\r\\f\\v\";\n\nstd::string trim(const std::string& s)\n{\n  auto wsfront = std::find_if_not(s.begin(), s.end(), [](int c) {return isspace(c); });\n  auto wsback = std::find_if_not(s.rbegin(), s.rend(), [](int c) {return isspace(c); }).base();\n  return (wsback <= wsfront ? std::string() : std::string(wsfront, wsback));\n}\n\n/***********************************\n *******   wchar_t-utf-ansi   ******\n **********************************/\n\n#ifdef AVS_WINDOWS\nstd::unique_ptr<char[]> AnsiToUtf8(const char* input)\n{\n  int wlen = MultiByteToWideChar(AreFileApisANSI() ? CP_ACP : CP_OEMCP, 0, input, -1, NULL, 0);\n  wchar_t* wstr = new wchar_t[wlen];\n  MultiByteToWideChar(AreFileApisANSI() ? CP_ACP : CP_OEMCP, 0, input, -1, wstr, wlen);\n  const auto utf8len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);\n  // The length comes with the \\0 terminator\n  // Allocate a buffer for the UTF-8 string\n  auto s_utf8 = std::make_unique<char[]>(utf8len);\n  // Convert the UTF-16 string from UTF-8\n  WideCharToMultiByte(CP_UTF8, 0, wstr, -1, s_utf8.get(), (int)utf8len, NULL, NULL);\n  delete[] wstr;\n  return s_utf8;\n}\n\nstd::unique_ptr<char[]> WideCharToUtf8(const wchar_t* w_string)\n{\n  const auto utf8len = WideCharToMultiByte(CP_UTF8, 0, w_string, -1, NULL, 0, 0, 0) - 1; // w/o the \\0 terminator\n  auto s_utf8 = std::make_unique<char[]>(utf8len + 1);\n  WideCharToMultiByte(CP_UTF8, 0, w_string, -1, s_utf8.get(), (int)utf8len + 1, 0, 0);\n  return s_utf8;\n}\n\nstd::unique_ptr<char[]> WideCharToAnsi(const wchar_t* w_string)\n{\n  const auto len = wcslen(w_string);\n  auto s_ansi = std::make_unique<char[]>(len + 1);\n  WideCharToMultiByte(AreFileApisANSI() ? CP_ACP : CP_OEMCP, 0, w_string, -1, s_ansi.get(), (int)len + 1, NULL, NULL); // replaces out-of-CP chars by ?\n  // int succ = wcstombs(s_ansi, w_string, len +1);\n  // no good, stops at non-replacable unicode chars. If wcstombs encounters a wide character it cannot convert to a multibyte character, it returns 1 cast to type size_t and sets errno to EILSEQ.\n  return s_ansi;\n}\n\nstd::unique_ptr<char[]> WideCharToAnsiACP(const wchar_t* w_string)\n{\n  const auto len = wcslen(w_string);\n  auto s_ansi = std::make_unique<char[]>(len + 1);\n  WideCharToMultiByte(CP_ACP, 0, w_string, -1, s_ansi.get(), (int)len + 1, NULL, NULL); // replaces out-of-CP chars by ?\n  // int succ = wcstombs(s_ansi, w_string, len +1);\n  // no good, stops at non-replacable unicode chars. If wcstombs encounters a wide character it cannot convert to a multibyte character, it returns 1 cast to type size_t and sets errno to EILSEQ.\n  return s_ansi;\n}\n\nstd::unique_ptr<char[]> WideCharToUtf8_maxn(const wchar_t* w_string, size_t maxn)\n{\n  const auto utf8len = WideCharToMultiByte(CP_UTF8, 0, w_string, (int)maxn, NULL, 0, 0, 0); // no \\0 terminator check requested here\n  auto s_utf8 = std::make_unique<char[]>(utf8len + 1);\n  WideCharToMultiByte(CP_UTF8, 0, w_string, -1, s_utf8.get(), utf8len, 0, 0);\n  s_utf8[utf8len] = 0;\n  return s_utf8;\n}\n\nstd::unique_ptr<char[]> WideCharToAnsi_maxn(const wchar_t* w_string, size_t maxn)\n{\n  auto s_ansi = std::make_unique<char[]>(maxn + 1);\n  WideCharToMultiByte(AreFileApisANSI() ? CP_ACP : CP_OEMCP, 0, w_string, -1, s_ansi.get(), (int)maxn, NULL, NULL); // replaces out-of-CP chars by ?\n  s_ansi[maxn] = 0;\n  return s_ansi;\n}\n\nstd::unique_ptr<wchar_t[]> AnsiToWideChar(const char* s_ansi)\n{\n  const size_t bufsize = strlen(s_ansi) + 1;\n  auto w_string = std::make_unique<wchar_t[]>(bufsize);\n  MultiByteToWideChar(AreFileApisANSI() ? CP_ACP : CP_OEMCP, 0, s_ansi, -1, w_string.get(), (int)bufsize);\n  //mbstowcs(script_name_w, script_name, len); // ansi to wchar_t, does not convert properly out-of-the box\n  return w_string;\n}\n\nstd::unique_ptr<wchar_t[]> AnsiToWideCharACP(const char* s_ansi)\n{\n  const size_t bufsize = strlen(s_ansi) + 1;\n  auto w_string = std::make_unique<wchar_t[]>(bufsize);\n  MultiByteToWideChar(CP_ACP, 0, s_ansi, -1, w_string.get(), (int)bufsize);\n  //mbstowcs(script_name_w, script_name, len); // ansi to wchar_t, does not convert properly out-of-the box\n  return w_string;\n}\n\nstd::unique_ptr<wchar_t[]> Utf8ToWideChar(const char* s_utf8)\n{\n  const size_t wchars_count = MultiByteToWideChar(CP_UTF8, 0, s_utf8, -1, NULL, 0);\n  const size_t bufsize = wchars_count + 1;\n  auto w_string = std::make_unique<wchar_t[]>(bufsize);\n  MultiByteToWideChar(CP_UTF8, 0, s_utf8, -1, w_string.get(), (int)bufsize);\n  return w_string;\n}\n\nstd::string Utf8ToAnsi(const char* s_utf8)\n{\n  std::string s;\n  auto w = Utf8ToWideChar(s_utf8);\n  auto ansi = WideCharToAnsi(w.get()); // replaces out-of-CP chars by ?\n  s = ansi.get();\n  return s;\n}\n\n#endif\n\nstd::string double_to_string(double d)\n{\n  char s[50]; // safe size for a double\n#ifdef MSVC\n  _locale_t locale = _create_locale(LC_NUMERIC, \"C\"); // force '.' as decimal separator\n  _sprintf_l(s, \"%lf\", locale, d);\n  _free_locale(locale);\n#else\n  sprintf(s, \"%lf\", d);\n#endif\n  return s;\n}\n\nstd::string GetFullPathNameWrapUtf8(const std::string& f)\n{\n#ifdef AVS_WINDOWS\n  // assume f is utf-8\n  auto f_wide = Utf8ToWideChar(f.c_str());\n  auto p = fs::absolute(fs::path(f_wide.get()).lexically_normal());\n  auto w = p.wstring(); // UTF-16 on Windows\n  auto utf8 = WideCharToUtf8(w.c_str());\n  return std::string(utf8.get());\n#else\n  return fs::absolute(fs::path(f).lexically_normal()).generic_string();\n#endif\n}\n\nsize_t str_utf8_size(const std::string& s) {\n  // Does not handle combined codepoints, e.g. diacritic mark modifications\n  // Leading UTF8 byte:\n  // 1 byte  0xxxxxxx\n  // 2 bytes 110xxxxx\n  // 3 bytes 1110xxxx\n  // 4 bytes 11110xxx\n  size_t len = 0;\n  for (char c : s) {\n    if ((c & 0xc0) != 0x80) // Not a trailing byte 10xxxxxx\n      len++;\n  }\n  return len;\n}\n\n// converts a 16 bit unicode codepoint to its utf8 string representation\nstd::string U16_to_utf8(uint16_t u16)\n{\n  uint8_t bytes[3];\n  int size = 0;\n  // check the range of the UTF-16 code point\n  if (u16 <= 0x007F) {\n    // one byte, 0xxxxxxx\n    bytes[0] = static_cast<uint8_t>(u16);\n    size = 1;\n  }\n  else if (u16 <= 0x07FF) {\n    // two bytes, 110xxxxx 10xxxxxx\n    bytes[0] = static_cast<uint8_t>(0xC0 | ((u16 >> 6) & 0x1F));\n    bytes[1] = static_cast<uint8_t>(0x80 | (u16 & 0x3F));\n    size = 2;\n  }\n  else {\n    // three bytes, 1110xxxx 10xxxxxx 10xxxxxx\n    bytes[0] = static_cast<uint8_t>(0xE0 | ((u16 >> 12) & 0x0F));\n    bytes[1] = static_cast<uint8_t>(0x80 | ((u16 >> 6) & 0x3F));\n    bytes[2] = static_cast<uint8_t>(0x80 | (u16 & 0x3F));\n    size = 3;\n  }\n  // convert the array of bytes to a string\n  std::string u8str(bytes, bytes + size);\n  return u8str;\n}\n\n// for posix: always assume utf8\nstd::string charToUtf8(const char* text, bool utf8)\n{\n  std::string s;\n  // AVS_POSIX: utf8 is always true, no ANSI here\n#ifdef AVS_POSIX\n  utf8 = true;\n#endif\n  if (utf8) {\n    s = text; // no change\n  }\n#ifdef AVS_WINDOWS\n  else {\n    // ANSI (or system local Active CP, since Win10 it can be UTF8), Windows\n    auto source = AnsiToUtf8(text);\n    s = source.get();\n  }\n#endif\n  return s;\n}\n"
  },
  {
    "path": "avs_core/core/strings.h",
    "content": "// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef AVSCORE_STRINGS_H\n#define AVSCORE_STRINGS_H\n\n#include <string>\n#include <memory>\n#include <cstdint>\n\nbool streqi(const char* s1, const char* s2);\nstd::string concat(const std::string &s1, const std::string &s2);\nbool replace_beginning(std::string &_haystack, const std::string &needle, const std::string &newStr);\nbool replace(std::string &haystack, const std::string &needle, const std::string &newStr);\nbool replace(std::string &haystack, char needle, char newChar);\nstd::string trim(const std::string& s);\n\n#ifdef AVS_WINDOWS\nstd::unique_ptr<char[]> AnsiToUtf8(const char* input);\nstd::unique_ptr<char[]> WideCharToUtf8(const wchar_t* w_string);\nstd::unique_ptr<char[]> WideCharToAnsi(const wchar_t* w_string);\nstd::unique_ptr<char[]> WideCharToAnsiACP(const wchar_t* w_string);\nstd::unique_ptr<char[]> WideCharToUtf8_maxn(const wchar_t* w_string, size_t maxn);\nstd::unique_ptr<char[]> WideCharToAnsi_maxn(const wchar_t* w_string, size_t maxn);\nstd::unique_ptr<wchar_t[]> AnsiToWideChar(const char* s_ansi);\nstd::unique_ptr<wchar_t[]> AnsiToWideCharACP(const char* s_ansi);\nstd::unique_ptr<wchar_t[]> Utf8ToWideChar(const char* s_utf8);\nstd::string Utf8ToAnsi(const char* s_utf8);\n#endif\n\nstd::string GetFullPathNameWrapUtf8(const std::string& f);\n\n// Converts a double to string using the \"C\" locale (always '.' as decimal\n// separator), matching the behaviour of String() and AVSValue_to_string().\nstd::string double_to_string(double d);\n\nsize_t str_utf8_size(const std::string& s);\nstd::string U16_to_utf8(uint16_t u16);\nstd::string charToUtf8(const char* text, bool utf8);\n\n#endif // AVSCORE_STRINGS_H\n"
  },
  {
    "path": "avs_core/core/vartable.h",
    "content": "// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#ifndef AVSCORE_VARTABLE_H\n#define AVSCORE_VARTABLE_H\n\n#include \"strings.h\"\n#include \"avs/alignment.h\"\n#include \"avs/minmax.h\"\n#include <avisynth.h>\n#include <unordered_map>\n#include <mutex>\n#include <iostream>\n#include <cstring>\n\nstruct iequal_to_ascii\n{\n  bool operator()(const char* str1, const char* str2) const\n  {\n    return streqi(str1, str2);\n  }\n};\n\nstruct ihash_ascii\n{\n  std::size_t operator()(const char* s) const\n  {\n\t  // NOTE the connection between the hash() and equals() functions!\n\t  // In order for the hash table to work correctly, if two strings compare\n\t  // equal, they MUST have the same hash.\n\n    size_t hash = 0;\n    while (*s)\n      hash = hash * 101  +  tolower(*s++);\n\n    return hash;\n  }\n};\n\n// Custom hash function for composite keys (const char* pointer + size_t length)\nstruct CompositeKeyDjb2Hash {\n  size_t operator()(const std::pair<const char*, size_t>& key) const {\n    const char* str = key.first;\n    size_t len = key.second;\n    size_t hash = 5381;\n\n    while (len--) {\n      hash = ((hash << 5) + hash) + *str;\n      ++str;\n    }\n    return hash;\n  }\n};\n\n// Custom equality function for composite keys\nstruct CompositeKeyEqual {\n  bool operator()(const std::pair<const char*, size_t>& lhs, const std::pair<const char*, size_t>& rhs) const {\n    return (lhs.second == rhs.second) && (std::strncmp(lhs.first, rhs.first, lhs.second) == 0);\n  }\n};\n\n// This doles out storage space for strings.  No space is ever freed\n// until the class instance is destroyed (which happens when a script\n// file is closed).\nclass StringDump {\n   enum { BLOCK_SIZE = 32768 };\n   char* current_block;\n   size_t block_pos, block_size;\n\n   // string cache\n   std::unordered_map<std::pair<const char*, size_t>, const char*, CompositeKeyDjb2Hash, CompositeKeyEqual> cache;\n\n   // Get the pointer to the string (if it exists)\n   const char* get_string(const char* keyStr, size_t keyLen) {\n     auto it = cache.find({ keyStr, keyLen });\n     if (it != cache.end()) {\n       return it->second; // Return existing pointer\n     }\n     else {\n       return nullptr;\n     }\n   }\n\n   void add_string(const char* keyStr, size_t keyLen) {\n     cache[{keyStr, keyLen}] = keyStr;\n   }\n\n   void ensure_length(size_t len)\n   {\n     if (block_pos + len + 1 > block_size) {\n       char* new_block = new char[block_size = max(block_size, len + 1 + sizeof(char*))];\n       //_RPT0(0, \"StringDump: Allocating new stringblock.\\r\\n\");\n       *(char**)new_block = current_block;   // beginning of block holds pointer to previous block\n       current_block = new_block;\n       block_pos = sizeof(char*);\n     }\n   }\n\npublic:\n   StringDump() : current_block(0), block_pos(BLOCK_SIZE), block_size(BLOCK_SIZE) {}\n\n   ~StringDump() {\n      _RPT0(0, \"StringDump: DeAllocating all stringblocks.\\r\\n\");\n      char* p = current_block;\n      while (p) {\n         char* next = *(char**)p;\n         delete[] p;\n         p = next;\n      }\n   }\n\n   // SaveString with len==-1 can store more than 'int' sized data\n   // up to size_t theoretically even on 32 bits.\n   // Public interface defines 'len' as int, this can we live with.\n   char* SaveString(const char* s, int _len = -1, bool escape = false) {\n     size_t srclen = (_len == -1) ? strlen(s) : _len >= 0 ? static_cast<size_t>(_len) : 0;\n     size_t len;\n\n     std::string ss;\n     if (escape) {\n       ss.reserve(srclen); // worst case. Note: input string may not be closed by 0x00\n       // PF: no need for WideString conversion, utf8 lower 128 ascii characters are freely searchable w/o conversion\n       len = 0;\n       for (size_t i = 0; s[i] && i<srclen; ++i, ++len) {\n         if (s[i] == '\\\\') {\n           switch (s[i + 1]) {\n           case 'n': ss += '\\n'; ++i; continue;\n           case 'r': ss += '\\r'; ++i; continue;\n           case 't': ss += '\\t'; ++i; continue;\n           case '0': ss += '\\0'; ++i; continue;\n           case 'a': ss += '\\a'; ++i; continue;\n           case 'f': ss += '\\f'; ++i; continue;\n           case '\\\\': ss += '\\\\'; ++i; continue;\n           case '\\\"': ss += '\\\"'; ++i; continue;\n           case '\\'': ss += '\\''; ++i; continue;\n           case 'b': ss += '\\b'; ++i; continue;\n           case 'v': ss += '\\v'; ++i; continue;\n           }\n         }\n         ss += s[i];\n       }\n       len = ss.size();\n       s = ss.c_str();\n     }\n     else {\n       len = srclen;\n     }\n\n    // check in cache content\n    const char* test_ptr = get_string(s, len);\n    if(test_ptr != nullptr) // same string found in cache\n      return const_cast<char *>(test_ptr);\n\n    ensure_length(len);\n    char* result = current_block + block_pos;\n    memcpy(result, s, len);\n    result[len] = 0;\n    block_pos += AlignNumber(len + 1, sizeof(char*)); // Keep word-aligned\n\n    add_string(result, len); // update cache\n\n    return result;\n   }\n\n   void Clear() {\n     if (current_block) {\n         // deallocate string blocks except the first one\n         while (char* p = *(char**)current_block) {\n            delete[] current_block;\n            current_block = p;\n         }\n         block_pos = sizeof(char*);\n         block_size = BLOCK_SIZE;\n      }\n   }\n};\n\nclass VarFrame\n{\n   typedef std::unordered_map<const char*, AVSValue, ihash_ascii, iequal_to_ascii> ValueMap;\n   ValueMap variables;\n\npublic:\n   VarFrame() {\n      variables.max_load_factor(0.8f);\n   }\n\n   // This method will not modify the *val argument if it returns false.\n   bool Get(const char* name, AVSValue *val) const\n   {\n      ValueMap::const_iterator v = variables.find(name);\n      if (v != variables.end())\n      {\n         *val = v->second;\n         return true;\n      }\n      return false;\n   }\n\n   bool Set(const char* name, const AVSValue& val)\n   {\n      std::pair<ValueMap::iterator, bool> ret = variables.insert(ValueMap::value_type(name, val));\n      ret.first->second = val;\n      return ret.second;\n   }\n\n   void Clear()\n   {\n      variables.clear();\n   }\n};\n\nclass VarStringFrame : public VarFrame\n{\n   StringDump string_dump;\npublic:\n   char* SaveString(const char* s, int len = -1, bool escape = false) {\n      return string_dump.SaveString(s, len, escape);\n   }\n\n   void Clear()\n   {\n      //string_dump.Clear(); // do not destroy string (it is destroyed at destructor)\n      VarFrame::Clear();\n   }\n};\n\nclass ConcurrentVarStringFrame : protected VarStringFrame\n{\n   // avoid write/read concurrency of global variables in runtime scripts in MT\n   mutable std::mutex var_mutex;\n\npublic:\n   // This method will not modify the *val argument if it returns false.\n   bool Get(const char* name, AVSValue *val) const\n   {\n      std::lock_guard<std::mutex> lock(var_mutex); // avoid concurrency for global variables\n      return VarFrame::Get(name, val);\n   }\n\n   bool Set(const char* name, const AVSValue& val)\n   {\n      std::lock_guard<std::mutex> lock(var_mutex); // avoid concurrency for global variables\n      return VarFrame::Set(name, val);\n   }\n\n   char* SaveString(const char* s, int len = -1, bool escape = false) {\n      std::lock_guard<std::mutex> lock(var_mutex); // avoid concurrency for global variables\n      return VarStringFrame::SaveString(s, len, escape);\n   }\n\n   void Clear()\n   {\n      std::lock_guard<std::mutex> lock(var_mutex); // avoid concurrency for global variables\n      VarStringFrame::Clear();\n   }\n};\n\nclass VarTable\n{\nprivate:\n   ConcurrentVarStringFrame* topFrame;\n\n   std::vector<std::unique_ptr<VarFrame>> stackFrames;\n   std::vector<std::unique_ptr<VarStringFrame>> globalFrames;\n\n   std::vector<std::unique_ptr<VarFrame>> stackPool;\n   std::vector<std::unique_ptr<VarStringFrame>> globalPool;\n\npublic:\n   VarTable(ConcurrentVarStringFrame* topFrame) : topFrame(topFrame)\n   {\n      Push();\n   }\n\n   void Clear()\n   {\n      stackFrames.clear();\n      globalFrames.clear();\n      stackPool.clear();\n      globalPool.clear();\n   }\n\n   void Push()\n   {\n      if (stackPool.size() > 0) {\n         stackFrames.emplace_back(std::move(stackPool.back()));\n         stackPool.pop_back();\n      }\n      else {\n         stackFrames.emplace_back(new VarFrame());\n      }\n   }\n\n   void Pop()\n   {\n      assert(stackFrames.size() > 0);\n      stackFrames.back()->Clear();\n      stackPool.emplace_back(std::move(stackFrames.back()));\n      stackFrames.pop_back();\n   }\n\n   void PushGlobal()\n   {\n      Push();\n      if (globalPool.size() > 0) {\n         globalFrames.emplace_back(std::move(globalPool.back()));\n         globalPool.pop_back();\n      }\n      else {\n         globalFrames.emplace_back(new VarStringFrame());\n      }\n   }\n\n   void PopGlobal()\n   {\n      Pop();\n      assert(globalFrames.size() > 0);\n      globalFrames.back()->Clear();\n      globalPool.emplace_back(std::move(globalFrames.back()));\n      globalFrames.pop_back();\n   }\n\n   bool Set(const char* name, const AVSValue& val)\n   {\n      return stackFrames.back()->Set(name, val);\n   }\n\n   bool SetGlobal(const char* name, const AVSValue& val)\n   {\n      if (globalFrames.size() > 0) {\n         return globalFrames.back()->Set(name, val);\n      }\n      return topFrame->Set(name, val);\n   }\n\n   bool Get(const char* name, AVSValue *val) const\n   {\n      if (stackFrames.size() > 0 && stackFrames.back()->Get(name, val)) {\n         return true;\n      }\n      for (auto it = globalFrames.rbegin(); it != globalFrames.rend(); ++it) {\n         if ((**it).Get(name, val)) {\n            return true;\n         }\n      }\n      return topFrame->Get(name, val);\n   }\n\n   char* SaveString(const char* s, int len = -1, bool escape = false)\n   {\n      if (globalFrames.size() > 0) {\n         return globalFrames.back()->SaveString(s, len, escape);\n      }\n      return topFrame->SaveString(s, len, escape);\n   }\n};\n\n#endif // AVSCORE_VARTABLE_H\n"
  },
  {
    "path": "avs_core/core/version.h.in",
    "content": "#ifndef _AVS_VERSION_H_\n#define _AVS_VERSION_H_\n\n#include \"arch.h\"\n\n#define       AVS_PPSTR_(x)    \t#x\n#define       AVS_PPSTR(x)    \tAVS_PPSTR_(x)\n\n#define       AVS_PROJECT       AviSynth+\n#define       AVS_MAJOR_VER     3\n#define       AVS_MINOR_VER     7\n#define       AVS_BUGFIX_VER    5\n#ifdef RELEASE_TARBALL\n#define       AVS_FULLVERSION\tAVS_PPSTR(AVS_PROJECT) \" \" AVS_PPSTR(AVS_MAJOR_VER) \".\" AVS_PPSTR(AVS_MINOR_VER) \".\" AVS_PPSTR(AVS_BUGFIX_VER) \" (\" AVS_PPSTR(AVS_ARCH) \")\"\n#else\n#define       AVS_DEVNEXT_REV   @AVS_DEVNEXT_REV@\n#define       AVS_DEV_REVDATE   @AVS_DEV_REVDATE@\n#define       AVS_DEV_GITHASH   @AVS_DEV_GITHASH@\n#define       AVS_SEQREV        @AVS_SEQREV@\t\t// e.g. 1576\n#define       AVS_BRANCH        @AVS_BRANCH@\t\t// e.g. master\n#define       AVS_FULLVERSION\tAVS_PPSTR(AVS_PROJECT) \" \" AVS_PPSTR(AVS_MAJOR_VER) \".\" AVS_PPSTR(AVS_MINOR_VER) \".\" AVS_PPSTR(AVS_BUGFIX_VER) \" (r\" AVS_PPSTR(AVS_SEQREV) \", \" AVS_PPSTR(AVS_BRANCH) \", \" AVS_PPSTR(AVS_ARCH) \")\"\n#endif\n\n#endif  //  _AVS_VERSION_H_\n"
  },
  {
    "path": "avs_core/filters/AviSource/AVIIndex.cpp",
    "content": "// Packaged with Avisynth v1.0 beta.\n// http://www.math.berkeley.edu/~benrg/avisynth.html\n\n//\tVirtualDub - Video processing and capture application\n//\tCopyright (C) 1998-2000 Avery Lee\n//\n//\tThis program is free software; you can redistribute it and/or modify\n//\tit under the terms of the GNU General Public License as published by\n//\tthe Free Software Foundation; either version 2 of the License, or\n//\t(at your option) any later version.\n//\n//\tThis program is distributed in the hope that it will be useful,\n//\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n//\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//\tGNU General Public License for more details.\n//\n//\tYou should have received a copy of the GNU General Public License\n//\talong with this program; if not, write to the Free Software\n//\tFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n#include <crtdbg.h>\n#include \"AVIIndex.h\"\n\n// #pragma warning(disable: 4244)    // conversion from __int64, possible loss of data\n\n///////////////////////////////////////////////////////////////////////////\n\nclass AVIIndexChainNode {\npublic:\n\tenum { ENTS=2048 };\n\n\tAVIIndexChainNode *next;\n\n\tAVIIndexEntry2 ient[ENTS];\n\tint num_ents;\n\n\tAVIIndexChainNode() {\n\t\tnum_ents = 0;\n\t\tnext = NULL;\n\t}\n\n\tbool add(FOURCC ckid, __int64 pos, long size, bool is_keyframe) {\n\t\tif (num_ents < ENTS) {\n\t\t\tient[num_ents].ckid = ckid;\n\t\t\tient[num_ents].pos = pos;\n\t\t\tient[num_ents].size = is_keyframe ? size : 0x80000000+size;\n\t\t\t++num_ents;\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tvoid put(AVIINDEXENTRY *&avieptr) {\n\t\tint i;\n\n\t\tfor(i=0; i<num_ents; i++) {\n\t\t\tavieptr->ckid\t\t\t= ient[i].ckid;\n\t\t\tavieptr->dwFlags\t\t= ient[i].size & 0x80000000 ? 0 : AVIIF_KEYFRAME;\n\t\t\tavieptr->dwChunkOffset\t= DWORD(ient[i].pos);\n\t\t\tavieptr->dwChunkLength\t= ient[i].size & 0x7FFFFFFF;\n\n\t\t\t++avieptr;\n\t\t}\n\t}\n\n\tvoid put(AVIIndexEntry2 *&avie2ptr) {\n\t\tint i;\n\n\t\tfor(i=0; i<num_ents; i++)\n\t\t\t*avie2ptr++ = ient[i];\n\t}\n\n\tvoid put(AVIIndexEntry3 *&avie3ptr, __int64 offset) {\n\t\tint i;\n\n\t\tfor(i=0; i<num_ents; i++) {\n\t\t\tavie3ptr->dwSizeKeyframe\t= ient[i].size;\n\t\t\tavie3ptr->dwOffset\t\t\t= (DWORD)(ient[i].pos - offset);\n\n\t\t\t++avie3ptr;\n\t\t}\n\t}\n};\n\n///////////////////////////////////////////////////////////////////////////\n\nAVIIndexChain::AVIIndexChain() {\n\thead = tail = NULL;\n\ttotal_ents = 0;\n}\n\nvoid AVIIndexChain::delete_chain() {\n\tAVIIndexChainNode *aicn = head,*aicn2;\n\n\twhile(aicn) {\n\t\taicn2 = aicn->next;\n\t\tdelete aicn;\n\t\taicn = aicn2;\n\t}\n\n\thead = tail = NULL;\n}\n\nAVIIndexChain::~AVIIndexChain() {\n\tdelete_chain();\n}\n\nbool AVIIndexChain::add(AVIINDEXENTRY *avie) {\n\tif (!tail || !tail->add(avie->ckid, avie->dwChunkOffset, avie->dwChunkLength, !!(avie->dwFlags & AVIIF_KEYFRAME))) {\n\t\tAVIIndexChainNode *aicn = new AVIIndexChainNode();\n\n\t\tif (tail) tail->next = aicn; else head=aicn;\n\t\ttail = aicn;\n\n\t\tif (tail->add(avie->ckid, avie->dwChunkOffset, avie->dwChunkLength, !!(avie->dwFlags & AVIIF_KEYFRAME))) {\n\t\t\t++total_ents;\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t++total_ents;\n\n\treturn true;\n}\n\nbool AVIIndexChain::add(AVIIndexEntry2 *avie2) {\n\treturn add(avie2->ckid, avie2->pos, avie2->size & 0x7FFFFFFF, !!(avie2->size & 0x80000000));\n}\n\nbool AVIIndexChain::add(FOURCC ckid, __int64 pos, long size, bool is_keyframe) {\n\tif (!tail || !tail->add(ckid, pos, size, is_keyframe)) {\n\t\tAVIIndexChainNode *aicn = new AVIIndexChainNode();\n\n\t\tif (tail) tail->next = aicn; else head=aicn;\n\t\ttail = aicn;\n\n\t\tif (tail->add(ckid, pos, size, is_keyframe)) {\n\t\t\t++total_ents;\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t++total_ents;\n\n\treturn true;\n}\n\nvoid AVIIndexChain::put(AVIINDEXENTRY *avietbl) {\n\tAVIIndexChainNode *aicn = head;\n\n\twhile(aicn) {\n\t\taicn->put(avietbl);\n\t\taicn=aicn->next;\n\t}\n\n\tdelete_chain();\n}\n\nvoid AVIIndexChain::put(AVIIndexEntry2 *avie2tbl) {\n\tAVIIndexChainNode *aicn = head;\n\n\twhile(aicn) {\n\t\taicn->put(avie2tbl);\n\t\taicn=aicn->next;\n\t}\n\n\tdelete_chain();\n}\n\nvoid AVIIndexChain::put(AVIIndexEntry3 *avie3tbl, __int64 offset) {\n\tAVIIndexChainNode *aicn = head;\n\n\twhile(aicn) {\n\t\taicn->put(avie3tbl, offset);\n\t\taicn=aicn->next;\n\t}\n\n\tdelete_chain();\n}\n\nAVIIndex::AVIIndex() {\n\tindex = NULL;\n\tindex2 = NULL;\n\tindex3 = NULL;\n}\n\nAVIIndex::~AVIIndex() {\n\tdelete[] index;\n\tdelete[] index2;\n\tdelete[] index3;\n}\n\nbool AVIIndex::makeIndex() {\n\tif (!allocateIndex(total_ents)) return false;\n\n\tput(indexPtr());\n\n\treturn true;\n}\n\nbool AVIIndex::makeIndex2() {\n\tif (!allocateIndex2(total_ents)) return false;\n\n\tput(index2Ptr());\n\n\treturn true;\n}\n\nbool AVIIndex::makeIndex3(__int64 offset) {\n\tif (!allocateIndex3(total_ents)) return false;\n\n\tput(index3Ptr(), offset);\n\n\treturn true;\n}\n\nvoid AVIIndex::clear() {\n\tdelete_chain();\n\tdelete[] index;\n\tdelete[] index2;\n\tdelete[] index3;\n\tindex = NULL;\n\tindex2 = NULL;\n\tindex3 = NULL;\n\ttotal_ents = 0;\n}\n"
  },
  {
    "path": "avs_core/filters/AviSource/AVIIndex.h",
    "content": "// Packaged with Avisynth v1.0 beta.\n// http://www.math.berkeley.edu/~benrg/avisynth.html\n\n//\tVirtualDub - Video processing and capture application\n//\tCopyright (C) 1998-2000 Avery Lee\n//\n//\tThis program is free software; you can redistribute it and/or modify\n//\tit under the terms of the GNU General Public License as published by\n//\tthe Free Software Foundation; either version 2 of the License, or\n//\t(at your option) any later version.\n//\n//\tThis program is distributed in the hope that it will be useful,\n//\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n//\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//\tGNU General Public License for more details.\n//\n//\tYou should have received a copy of the GNU General Public License\n//\talong with this program; if not, write to the Free Software\n//\tFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n#ifndef f_AVIINDEX_H\n#define f_AVIINDEX_H\n\n#include <avs/win.h>\n#include <vfw.h>\n\nclass AVIIndexChainNode;\n\nclass AVIIndexEntry2 {\npublic:\n\t__int64 pos;\n\tunion {\n\t\tFOURCC\tckid;\n\t\tint\t\tfileno;\n\t};\n\tLONG\tsize;\n};\n\nclass AVIIndexEntry3 {\npublic:\n\tDWORD\tdwOffset;\n\tDWORD\tdwSizeKeyframe;\n};\n\nclass AVIIndexChain {\nprotected:\n\tAVIIndexChainNode *head, *tail;\n\n\tvoid delete_chain();\npublic:\n\tint total_ents;\n\n\tAVIIndexChain();\n\tvirtual ~AVIIndexChain();\n\n\tbool add(AVIINDEXENTRY *avie);\n\tbool add(AVIIndexEntry2 *avie2);\n\tbool add(FOURCC ckid, __int64 pos, long len, bool is_keyframe);\n\tvoid put(AVIINDEXENTRY *avietbl);\n\tvoid put(AVIIndexEntry2 *avie2tbl);\n\tvoid put(AVIIndexEntry3 *avie3tbl, __int64 offset);\n};\n\nclass AVIIndex : public AVIIndexChain {\nprotected:\n\tAVIINDEXENTRY *index;\n\tAVIIndexEntry2 *index2;\n\tAVIIndexEntry3 *index3;\n\tint index_len;\n\n\tAVIINDEXENTRY *allocateIndex(int total_entries) {\n\t\treturn index = new AVIINDEXENTRY[index_len = total_entries];\n\t}\n\n\tAVIIndexEntry2 *allocateIndex2(int total_entries) {\n\t\treturn index2 = new AVIIndexEntry2[index_len = total_entries];\n\t}\n\n\tAVIIndexEntry3 *allocateIndex3(int total_entries) {\n\t\treturn index3 = new AVIIndexEntry3[index_len = total_entries];\n\t}\n\npublic:\n\tAVIIndex();\n\tvirtual ~AVIIndex();\n\n\tbool makeIndex();\n\tbool makeIndex2();\n\tbool makeIndex3(__int64 offset);\n\tvoid clear();\n\n\tAVIINDEXENTRY *indexPtr() {\n\t\treturn index;\n\t}\n\n\tAVIIndexEntry2 *index2Ptr() {\n\t\treturn index2;\n\t}\n\n\tAVIIndexEntry3 *index3Ptr() {\n\t\treturn index3;\n\t}\n\n\tAVIIndexEntry2 *takeIndex2() {\n\t\tAVIIndexEntry2 *idx = index2;\n\n\t\tindex2 = NULL;\n\t\treturn idx;\n\t}\n\n\tint size() { return total_ents; }\n\n\tint indexLen() {\n\t\treturn index_len;\n\t}\n};\n\n#endif"
  },
  {
    "path": "avs_core/filters/AviSource/AVIReadHandler.cpp",
    "content": "﻿//\tVirtualDub - Video processing and capture application\n//\tCopyright (C) 1998-2001 Avery Lee\n//\n//\tThis program is free software; you can redistribute it and/or modify\n//\tit under the terms of the GNU General Public License as published by\n//\tthe Free Software Foundation; either version 2 of the License, or\n//\t(at your option) any later version.\n//\n//\tThis program is distributed in the hope that it will be useful,\n//\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n//\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//\tGNU General Public License for more details.\n//\n//\tYou should have received a copy of the GNU General Public License\n//\talong with this program; if not, write to the Free Software\n//\tFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n#include <crtdbg.h>\n#include <new>\n\n#include \"AVIReadHandler.h\"\n//#include \"FastReadStream.h\"\n//#include \"ProgressDialog.h\"\n#include \"AVIIndex.h\"\n#include \"Error.h\"\n#include \"list.h\"\n#include \"Fixes.h\"\n#include \"File64.h\"\n\n#include \"clip_info.h\"\n#include \"../core/internal.h\"\n#include <cmath>\n#include <cstdint>\n#include \"../core/strings.h\"\n\n\n#pragma warning(disable: 4706)    // assignment within conditional expression\n\n// These two functions translate VirtualDub exceptions to Avisynth exceptions.\n\nchar exception_conversion_buffer[2048];\n\nAvisynthError MyError(const char* fmt, ...) {\n  va_list val;\n  va_start(val, fmt);\n  wvsprintf(exception_conversion_buffer, fmt, val);\n  va_end(val);\n  return AvisynthError(exception_conversion_buffer);\n}\n\nAvisynthError MyWin32Error(const char *format, DWORD err, ...) {\n  char szError[128];\n  char szTemp[256];\n\n  FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,\n    0, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), szError, sizeof szError, NULL);\n\n  if (szError[0]) {\n    size_t l = strlen(szError);\n    if (l>1 && szError[l-2] == '\\r')\n      szError[l-2] = 0;\n    else if (szError[l-1] == '\\n')\n      szError[l-1] = 0;\n  }\n\n  va_list val;\n  va_start(val, err);\n  wvsprintf(szTemp, format, val);\n  va_end(val);\n\n  wsprintf(exception_conversion_buffer, szTemp, szError);\n  return AvisynthError(exception_conversion_buffer);\n}\n\n// Copied over from VD_misc.cpp, as the only function being used from there\nstatic bool isValidFOURCC(FOURCC fcc) {\n\treturn isprint((unsigned char)(fcc>>24))\n\t\t&& isprint((unsigned char)(fcc>>16))\n\t\t&& isprint((unsigned char)(fcc>> 8))\n\t\t&& isprint((unsigned char)(fcc    ));\n}\n\n//#define STREAMING_DEBUG\n\n// HACK!!!!\n\nCRITICAL_SECTION g_diskcs;\nbool g_disklockinited=false;\n\n\n///////////////////////////////////////////\n\ntypedef __int64 QUADWORD;\n\n// The following comes from the OpenDML 1.0 spec for extended AVI files\n\n// bIndexType codes\n//\n#define AVI_INDEX_OF_INDEXES 0x00\t// when each entry in aIndex\n\t\t\t\t\t\t\t\t\t// array points to an index chunk\n\n#define AVI_INDEX_OF_CHUNKS 0x01\t// when each entry in aIndex\n\t\t\t\t\t\t\t\t\t// array points to a chunk in the file\n\n#define AVI_INDEX_IS_DATA\t0x80\t// when each entry is aIndex is\n\t\t\t\t\t\t\t\t\t// really the data\n\n// bIndexSubtype codes for INDEX_OF_CHUNKS\n\n#define AVI_INDEX_2FIELD\t0x01\t// when fields within frames\n\t\t\t\t\t\t\t\t\t// are also indexed\n\tstruct _avisuperindex_entry {\n\t\tQUADWORD qwOffset;\t\t// absolute file offset, offset 0 is\n\t\t\t\t\t\t\t\t// unused entry??\n\t\tDWORD dwSize;\t\t\t// size of index chunk at this offset\n\t\tDWORD dwDuration;\t\t// time span in stream ticks\n\t};\n\tstruct _avistdindex_entry {\n\t\tDWORD dwOffset;\t\t\t// qwBaseOffset + this is absolute file offset\n\t\tDWORD dwSize;\t\t\t// bit 31 is set if this is NOT a keyframe\n\t};\n\tstruct _avifieldindex_entry {\n\t\tDWORD\tdwOffset;\n\t\tDWORD\tdwSize;\n\t\tDWORD\tdwOffsetField2;\n\t};\n\n#pragma pack(push)\n#pragma pack(2)\n\n#pragma warning( push )\n#pragma warning (disable: 4200) // nonstandard extension used : zero-sized array in struct/union\n\n\ttypedef struct _avisuperindex_chunk {\n\tFOURCC fcc;\t\t\t\t\t// ’ix##’\n\tDWORD cb;\t\t\t\t\t// size of this structure\n\tWORD wLongsPerEntry;\t\t// must be 4 (size of each entry in aIndex array)\n\tBYTE bIndexSubType;\t\t\t// must be 0 or AVI_INDEX_2FIELD\n\tBYTE bIndexType;\t\t\t// must be AVI_INDEX_OF_INDEXES\n\tDWORD nEntriesInUse;\t\t// number of entries in aIndex array that\n\t\t\t\t\t\t\t\t// are used\n\tDWORD dwChunkId;\t\t\t// ’##dc’ or ’##db’ or ’##wb’, etc\n\tDWORD dwReserved[3];\t\t// must be 0\n\tstruct _avisuperindex_entry aIndex[];\n} AVISUPERINDEX, * PAVISUPERINDEX;\n\ntypedef struct _avistdindex_chunk {\n\tFOURCC fcc;\t\t\t\t\t// ’ix##’\n\tDWORD cb;\n\tWORD wLongsPerEntry;\t\t// must be sizeof(aIndex[0])/sizeof(DWORD)\n\tBYTE bIndexSubType;\t\t\t// must be 0\n\tBYTE bIndexType;\t\t\t// must be AVI_INDEX_OF_CHUNKS\n\tDWORD nEntriesInUse;\t\t//\n\tDWORD dwChunkId;\t\t\t// ’##dc’ or ’##db’ or ’##wb’ etc..\n\tQUADWORD qwBaseOffset;\t\t// all dwOffsets in aIndex array are\n\t\t\t\t\t\t\t\t// relative to this\n\tDWORD dwReserved3;\t\t\t// must be 0\n\tstruct _avistdindex_entry aIndex[];\n} AVISTDINDEX, * PAVISTDINDEX;\n\ntypedef struct _avifieldindex_chunk {\n\tFOURCC\t\tfcc;\n\tDWORD\t\tcb;\n\tWORD\t\twLongsPerEntry;\n\tBYTE\t\tbIndexSubType;\n\tBYTE\t\tbIndexType;\n\tDWORD\t\tnEntriesInUse;\n\tDWORD\t\tdwChunkId;\n\tQUADWORD\tqwBaseOffset;\n\tDWORD\t\tdwReserved3;\n\tstruct\t_avifieldindex_entry aIndex[];\n} AVIFIELDINDEX, * PAVIFIELDINDEX;\n\n#pragma warning( pop )\n\n#pragma pack(pop)\n\n///////////////////////////////////////////////////////////////////////////\n\nIAVIReadStream::~IAVIReadStream() {\n}\n\n///////////////////////////////////////////////////////////////////////////\n\nclass AVIStreamNode;\nclass AVIReadHandler;\n\nclass AVIReadCache {\npublic:\n\tlong cache_hit_bytes, cache_miss_bytes;\n\tint reads;\n\n\tAVIReadCache(int nlines, int nstream, AVIReadHandler *root, AVIStreamNode *psnData);\n\t~AVIReadCache();\n\n\tvoid ResetStatistics();\n\tbool WriteBegin(__int64 pos, long len);\n\tvoid Write(void *buffer, long len);\n\tvoid WriteEnd();\n\tlong Read(void *dest, __int64 chunk_pos, __int64 pos, long len);\n\n\tlong getMaxRead() {\n\t\treturn (lines_max - 1) << 4;\n\t}\n\nprivate:\n\tAVIStreamNode *psnData;\n\t__int64 (*buffer)[2];\n\tint lines_max, lines;\n\tlong read_tail, write_tail, write_hdr;\n\tint write_offset;\n\tint stream;\n\tAVIReadHandler *source;\n};\n\nclass AVIStreamNode : public ListNode2<AVIStreamNode> {\npublic:\n\tAVIStreamHeader_fixed\thdr;\n\tchar\t\t\t\t\t*pFormat;\n\tlong\t\t\t\t\tlFormatLen;\n\tAVIIndex\t\t\t\tindex;\n\t__int64\t\t\t\t\tbytes;\n\tbool\t\t\t\t\tkeyframe_only;\n\tbool\t\t\t\t\twas_VBR;\n\tdouble\t\t\t\t\tbitrate_mean;\n\tdouble\t\t\t\t\tbitrate_stddev;\n\tdouble\t\t\t\t\tmax_deviation;\t\t// seconds\n\tint\t\t\t\t\t\thandler_count;\n\tclass AVIReadCache\t\t*cache;\n\tint\t\t\t\t\t\tstreaming_count;\n\t__int64\t\t\t\t\tstream_push_pos;\n\t__int64\t\t\t\t\tstream_bytes;\n\tint\t\t\t\t\t\tstream_pushes;\n\tlong\t\t\t\t\tlength;\n\tlong\t\t\t\t\tframes;\n\tList2<class AVIReadStream>\tlistHandlers;\n\n\tAVIStreamNode();\n\t~AVIStreamNode();\n\n\tvoid FixVBRAudio();\n};\n\nAVIStreamNode::AVIStreamNode() {\n\tpFormat = NULL;\n\tbytes = 0;\n\thandler_count = 0;\n\tstreaming_count = 0;\n\n\tstream_bytes = 0;\n\tstream_pushes = 0;\n\tcache = NULL;\n\n\twas_VBR = false;\n}\n\nAVIStreamNode::~AVIStreamNode() {\n\tdelete [] pFormat;\n\tdelete cache;\n}\n\nvoid AVIStreamNode::FixVBRAudio() {\n\tWAVEFORMATEX *pWaveFormat = (WAVEFORMATEX *)pFormat;\n\n\t// If this is an MP3 stream, undo the Nandub 1152 value.\n\n\tif (pWaveFormat->wFormatTag == 0x0055) {\n\t\tpWaveFormat->nBlockAlign = 1;\n\t}\n\n\t// Determine VBR statistics.\n\n\twas_VBR = true;\n\n\tconst AVIIndexEntry2 *pent = index.index2Ptr();\n\t__int64 size_accum = 0;\n\t__int64 max_dev = 0;\n\tdouble size_sq_sum = 0.0;\n\n\tfor(int i=0; i<frames; ++i) {\n\t\tunsigned size = pent[i].size & 0x7ffffffful;\n\t\t__int64 mean_center = (bytes * (2*i+1)) / (2*frames);\n\t\t__int64 dev = mean_center - (size_accum + (size>>1));\n\n\t\tif (dev<0)\n\t\t\tdev = -dev;\n\n\t\tif (dev > max_dev)\n\t\t\tmax_dev = dev;\n\n\t\tsize_accum += size;\n\t\tsize_sq_sum += (double)size*size;\n\t}\n\n\t// I hate probability & sadistics.\n\t//\n\t// Var(X) = E(X2) - E(X)^2\n\t//\t\t  = S(X2)/n - (S(x)/n)^2\n\t//\t\t  = (n*S(X2) - S(X)^2)/n^2\n\t//\n\t// SD(x) = sqrt(n*S(X2) - S(X)^2) / n\n\n\tdouble frames_per_second = (double)hdr.dwRate / (double)hdr.dwScale;\n\tdouble sum1_bits = bytes * 8.0;\n\tdouble sum2_bits = size_sq_sum * 64.0;\n\n\tbitrate_mean\t\t= (sum1_bits / frames) * frames_per_second;\n\tbitrate_stddev\t\t= sqrt(frames * sum2_bits - sum1_bits * sum1_bits) / frames * frames_per_second;\n\tmax_deviation\t\t= (double)max_dev * 8.0 / bitrate_mean;\n\n\t// Assume that each audio block is of the same duration.\n\n\thdr.dwRate\t\t\t= (DWORD)(bitrate_mean/8.0 + 0.5);\n\thdr.dwScale\t\t\t= pWaveFormat->nBlockAlign;\n\thdr.dwSampleSize\t= pWaveFormat->nBlockAlign;\n}\n\n///////////////////////////////////////////////////////////////////////////\n\nclass AVIFileDesc : public ListNode2<AVIFileDesc> {\npublic:\n\tHANDLE\t\thFile;\n\tHANDLE\t\thFileUnbuffered;\n\t__int64\t\ti64Size;\n};\n\nclass AVIStreamNode;\n\nclass AVIReadHandler final: public IAVIReadHandler, private File64 {\npublic:\n\tbool\t\tfDisableFastIO;\n\n\tAVIReadHandler(const wchar_t *);\n\tAVIReadHandler(PAVIFILE);\n\t~AVIReadHandler();\n\n\tvoid AddRef();\n\tvoid Release();\n\tIAVIReadStream *GetStream(DWORD fccType, LONG lParam);\n\tvoid EnableFastIO(bool);\n\tbool isOptimizedForRealtime();\n\tbool isStreaming();\n\tbool isIndexFabricated();\n\tbool AppendFile(const wchar_t *pszFile);\n\tbool getSegmentHint(const char **ppszPath);\n\n\tvoid EnableStreaming(int stream);\n\tvoid DisableStreaming(int stream);\n\tvoid AdjustRealTime(bool fRealTime);\n\tbool Stream(AVIStreamNode *, int64_t pos);\n\tint64_t getStreamPtr();\n\tvoid FixCacheProblems(class AVIReadStream *);\n\tlong ReadData(int stream, void *buffer, int64_t position, long len);\n\nprivate:\n//\tenum { STREAM_SIZE = 65536 };\n\tenum { STREAM_SIZE = 1048576 };\n\tenum { STREAM_RT_SIZE = 65536 };\n\tenum { STREAM_BLOCK_SIZE = 4096 };\n\n\tIAvisynthClipInfo *pAvisynthClipInfo;\n\tPAVIFILE paf;\n\tint ref_count;\n\tint64_t\t\ti64StreamPosition;\n\tint\t\t\tstreams;\n\tchar\t\t*streamBuffer;\n\tint\t\t\tsbPosition;\n\tint\t\t\tsbSize;\n\tlong\t\tfStreamsActive;\n\tint\t\t\tnRealTime;\n\tint\t\t\tnActiveStreamers;\n\tbool\t\tfFakeIndex;\n\tint64_t\t\ti64Size;\n\tint\t\t\tnFiles, nCurrentFile;\n\tchar *\t\tpSegmentHint;\n\n\t// Whenever a file is aggressively recovered, do not allow streaming.\n\n\tbool\t\tbAggressivelyRecovered;\n\n\tList2<AVIStreamNode>\t\tlistStreams;\n\tList2<AVIFileDesc>\t\t\tlistFiles;\n\n\tvoid\t\t_construct(const wchar_t *pszFile_w);\n\tvoid\t\t_parseFile(List2<AVIStreamNode>& streams);\n\tbool\t\t_parseStreamHeader(List2<AVIStreamNode>& streams, DWORD dwLengthLeft, bool& bIndexDamaged);\n\tbool\t\t_parseIndexBlock(List2<AVIStreamNode>& streams, int count, __int64);\n\tvoid\t\t_parseExtendedIndexBlock(List2<AVIStreamNode>& streams, AVIStreamNode *pasn, __int64 fpos, DWORD dwLength);\n\tvoid\t\t_destruct();\n\n\tchar *\t\t_StreamRead(long& bytes);\n\tvoid\t\t_SelectFile(int file);\n\n};\n\nIAVIReadHandler *CreateAVIReadHandler(PAVIFILE paf) {\n\treturn new AVIReadHandler(paf);\n}\n\nIAVIReadHandler *CreateAVIReadHandler(const wchar_t *pszFile_w) {\n\treturn new AVIReadHandler(pszFile_w);\n}\n\n///////////////////////////////////////////////////////////////////////////\n\nAVIReadCache::AVIReadCache(int nlines, int nstream, AVIReadHandler *root, AVIStreamNode *psnData) {\n\tbuffer = new(std::nothrow) __int64[nlines][2];\n\tif (!buffer) throw MyMemoryError();\n\n\tthis->psnData\t= psnData;\n\tlines\t\t= 0;\n\tlines_max\t= nlines;\n\tread_tail\t= 0;\n\twrite_tail\t= 0;\n\tstream\t\t= nstream;\n\tsource\t\t= root;\n\tResetStatistics();\n}\n\nAVIReadCache::~AVIReadCache() {\n\tdelete[] buffer;\n}\n\nvoid AVIReadCache::ResetStatistics() {\n\treads\t\t= 0;\n\tcache_hit_bytes\t= cache_miss_bytes = 0;\n}\n\nbool AVIReadCache::WriteBegin(__int64 pos, long len) {\n\tint needed;\n\n\t// delete lines as necessary to make room\n\n\tneeded = 1 + (len+15)/16;\n\n\tif (needed > lines_max)\n\t\treturn false;\n\n\twhile(lines+needed > lines_max) {\n\t\tint siz = (int)((buffer[read_tail][1]+15)/16 + 1);\n\t\tread_tail += siz;\n\t\tlines -= siz;\n\t\tif (read_tail >= lines_max)\n\t\t\tread_tail -= lines_max;\n\t}\n\n\t// write in header\n\n//\t_RPT1(0,\"\\tbeginning write at line %ld\\n\", write_tail);\n\n\twrite_hdr = write_tail;\n\twrite_offset = 0;\n\n\tbuffer[write_tail][0] = pos;\n\tbuffer[write_tail][1] = 0;\n\n\tif (++write_tail >= lines_max)\n\t\twrite_tail = 0;\n\n\treturn true;\n}\n\nvoid AVIReadCache::Write(void *src, long len) {\n\tlong dest;\n\n\t// copy in data\n\n\tbuffer[write_hdr][1] += len;\n\n\tdest = write_tail + (len + write_offset + 15)/16;\n\n\tif (dest > lines_max) {\n\t\tint tc = (lines_max - write_tail)*16 - write_offset;\n\n\t\tmemcpy((char *)&buffer[write_tail][0] + write_offset, src, tc);\n\t\tmemcpy(&buffer[0][0], (char *)src + tc, len - tc);\n\n\t\twrite_tail = (len-tc)/16;\n\t\twrite_offset = (len-tc)&15;\n\n\t} else {\n\t\tmemcpy((char *)&buffer[write_tail][0] + write_offset, src, len);\n\t\twrite_tail += (len+write_offset)/16;\n\t\tif (write_tail >= lines_max)\n\t\t\twrite_tail = 0;\n\n\t\twrite_offset = (len+write_offset) & 15;\n\t}\n}\n\nvoid AVIReadCache::WriteEnd() {\n\tlong cnt = (long)(1 + (buffer[write_hdr][1]+15)/16);\n\tlines += cnt;\n\twrite_tail = write_hdr + cnt;\n\n\tif (write_tail >= lines_max)\n\t\twrite_tail -= lines_max;\n\n//\t_RPT3(0,\"\\twrite complete -- header at line %d, size %ld, next line %ld\\n\", write_hdr, (long)buffer[write_hdr][1], write_tail);\n}\n\n// #pragma function(memcpy)\n\nlong AVIReadCache::Read(void *dest, __int64 chunk_pos, __int64 pos, long len) {\n\tlong ptr;\n\t__int64 offset;\n\n//\t_RPT3(0,\"Read request: chunk %16I64, pos %16I64d, %ld bytes\\n\", chunk_pos, pos, len);\n\n\t++reads;\n\n\tdo {\n\t\t// scan buffer looking for a range that contains data\n\n\t\tptr = read_tail;\n\t\twhile(ptr != write_tail) {\n\t\t\toffset = pos - buffer[ptr][0];\n\n//\t\t_RPT4(0,\"line %8d: pos %16I64d, len %ld bytes (%ld lines)\\n\", ptr, buffer[ptr][0], (long)buffer[ptr][1], (long)(buffer[ptr][1]+15)/16);\n\n\t\t\tif (offset>=0 && offset < buffer[ptr][1]) {\n\t\t\t\tlong end;\n\n\t\t\t\t// cache hit\n\n//\t\t\t\t_RPT1(0, \"cache hit (offset %\" PRIu64 \")\\n\", chunk_pos);\n\n\t\t\t\tcache_hit_bytes += len;\n\n\t\t\t\twhile (cache_hit_bytes > 16777216) {\n\t\t\t\t\tcache_miss_bytes >>= 1;\n\t\t\t\t\tcache_hit_bytes >>= 1;\n\t\t\t\t}\n\n\t\t\t\tif (len > (long)(buffer[ptr][1]*16 - offset))\n\t\t\t\t\tlen = (long)(buffer[ptr][1]*16 - offset);\n\n\t\t\t\tptr += 1+((long)offset>>4);\n\t\t\t\tif (ptr >= lines_max)\n\t\t\t\t\tptr -= lines_max;\n\n\t\t\t\tend = ptr + ((len+((long)offset&15)+15)>>4);\n\n\t\t\t\tif (end > lines_max) {\n\t\t\t\t\tlong tc = (lines_max - ptr)*16 - ((long)offset&15);\n\t\t\t\t\tmemcpy(dest, (char *)&buffer[ptr][0] + ((long)offset&15), tc);\n\t\t\t\t\tmemcpy((char *)dest + tc, (char *)&buffer[0][0], len-tc);\n\t\t\t\t} else {\n\t\t\t\t\tmemcpy(dest, (char *)&buffer[ptr][0] + ((long)offset&15), len);\n\t\t\t\t}\n\n\t\t\t\treturn len;\n\t\t\t}\n\n//\t\t_RPT4(0,\"[x] line %8d: pos %16I64d, len %ld bytes (%ld lines)\\n\", ptr, buffer[ptr][0], (long)buffer[ptr][1], (long)(buffer[ptr][1]+15)/16);\n\t\t\tptr += (long)(1+(buffer[ptr][1] + 15)/16);\n\n\t\t\tif (ptr >= lines_max)\n\t\t\t\tptr -= lines_max;\n\t\t}\n\n\t\tif (source->getStreamPtr() > chunk_pos)\n\t\t\tbreak;\n\n\t} while(source->Stream(psnData, chunk_pos));\n\n//\tOutputDebugString(\"cache miss\\n\");\n//\t_RPT1(0, \"cache miss (offset %\" PRIu64 \")\\n\", chunk_pos);\n\n\tcache_miss_bytes += len;\n\n\twhile (cache_miss_bytes > 16777216) {\n\t\tcache_miss_bytes >>= 1;\n\t\tcache_hit_bytes >>= 1;\n\t}\n\n\treturn source->ReadData(stream, dest, pos, len);\n}\n\n///////////////////////////////////////////////////////////////////////////\n\nclass AVIReadTunnelStream : public IAVIReadStream {\npublic:\n\tAVIReadTunnelStream(AVIReadHandler *, PAVISTREAM, IAvisynthClipInfo *pClipInfo);\n\t~AVIReadTunnelStream();\n\n\tHRESULT BeginStreaming(long lStart, long lEnd, long lRate);\n\tHRESULT EndStreaming();\n\tHRESULT Info(AVISTREAMINFO *pasi, long lSize);\n\tbool IsKeyFrame(long lFrame);\n\tHRESULT Read(long lStart, long lSamples, void *lpBuffer, long cbBuffer, long *plBytes, long *plSamples);\n\tlong Start();\n\tlong End();\n\tlong PrevKeyFrame(long lFrame);\n\tlong NextKeyFrame(long lFrame);\n\tlong NearestKeyFrame(long lFrame);\n\tHRESULT FormatSize(long lFrame, long *plSize);\n\tHRESULT ReadFormat(long lFrame, void *pFormat, long *plSize);\n\tbool isStreaming();\n\tbool isKeyframeOnly();\n\tbool getVBRInfo(double& bitrate_mean, double& bitrate_stddev, double& maxdev) { return false; }\n\nprivate:\n\tIAvisynthClipInfo *const pAvisynthClipInfo;\n\tAVIReadHandler *const parent;\n\tconst PAVISTREAM pas;\n};\n\n///////////////////////////////////////////////////////////////////////////\n\nAVIReadTunnelStream::AVIReadTunnelStream(AVIReadHandler *_parent, PAVISTREAM _pas, IAvisynthClipInfo *pClipInfo)\n: pAvisynthClipInfo(pClipInfo)\n, parent(_parent)\n, pas(_pas)\n{\n\tparent->AddRef();\n}\n\nAVIReadTunnelStream::~AVIReadTunnelStream() {\n\tpas->Release();\n\tparent->Release();\n}\n\nHRESULT AVIReadTunnelStream::BeginStreaming(long lStart, long lEnd, long lRate) {\n\treturn AVIStreamBeginStreaming(pas, lStart, lEnd, lRate);\n}\n\nHRESULT AVIReadTunnelStream::EndStreaming() {\n\treturn AVIStreamEndStreaming(pas);\n}\n\nHRESULT AVIReadTunnelStream::Info(AVISTREAMINFO *pasi, long lSize) {\n\treturn AVIStreamInfo(pas, pasi, lSize);\n}\n\nbool AVIReadTunnelStream::IsKeyFrame(long lFrame) {\n\treturn !!AVIStreamIsKeyFrame(pas, lFrame);\n}\n\nHRESULT AVIReadTunnelStream::Read(long lStart, long lSamples, void *lpBuffer, long cbBuffer, long *plBytes, long *plSamples) {\n\tHRESULT hr;\n\n\thr = AVIStreamRead(pas, lStart, lSamples, lpBuffer, cbBuffer, plBytes, plSamples);\n\n\tif (pAvisynthClipInfo) {\n\t\tconst char *pszErr;\n\n\t\tif (pAvisynthClipInfo->GetError(&pszErr))\n\t\t\tthrow MyError(\"Avisynth read error:\\n%s\", pszErr);\n\t}\n\n\treturn hr;\n}\n\nlong AVIReadTunnelStream::Start() {\n\treturn AVIStreamStart(pas);\n}\n\nlong AVIReadTunnelStream::End() {\n\treturn AVIStreamEnd(pas);\n}\n\nlong AVIReadTunnelStream::PrevKeyFrame(long lFrame) {\n\treturn AVIStreamPrevKeyFrame(pas, lFrame);\n}\n\nlong AVIReadTunnelStream::NextKeyFrame(long lFrame) {\n\treturn AVIStreamNextKeyFrame(pas, lFrame);\n}\n\nlong AVIReadTunnelStream::NearestKeyFrame(long lFrame) {\n\treturn AVIStreamNearestKeyFrame(pas, lFrame);\n}\n\nHRESULT AVIReadTunnelStream::FormatSize(long lFrame, long *plSize) {\n\treturn AVIStreamFormatSize(pas, lFrame, plSize);\n}\n\nHRESULT AVIReadTunnelStream::ReadFormat(long lFrame, void *pFormat, long *plSize) {\n\treturn AVIStreamReadFormat(pas, lFrame, pFormat, plSize);\n}\n\nbool AVIReadTunnelStream::isStreaming() {\n\treturn false;\n}\n\nbool AVIReadTunnelStream::isKeyframeOnly() {\n   return false;\n}\n\n///////////////////////////////////////////////////////////////////////////\n\nclass AVIReadStream : public IAVIReadStream, public ListNode2<AVIReadStream> {\n\tfriend AVIReadHandler;\n\npublic:\n\tAVIReadStream(AVIReadHandler *, AVIStreamNode *, int);\n\t~AVIReadStream();\n\n\tHRESULT BeginStreaming(long lStart, long lEnd, long lRate);\n\tHRESULT EndStreaming();\n\tHRESULT Info(AVISTREAMINFO *pasi, long lSize);\n\tbool IsKeyFrame(long lFrame);\n\tHRESULT Read(long lStart, long lSamples, void *lpBuffer, long cbBuffer, long *plBytes, long *plSamples);\n\tlong Start();\n\tlong End();\n\tlong PrevKeyFrame(long lFrame);\n\tlong NextKeyFrame(long lFrame);\n\tlong NearestKeyFrame(long lFrame);\n\tHRESULT FormatSize(long lFrame, long *plSize);\n\tHRESULT ReadFormat(long lFrame, void *pFormat, long *plSize);\n\tbool isStreaming();\n\tbool isKeyframeOnly();\n\tvoid Reinit();\n\tbool getVBRInfo(double& bitrate_mean, double& bitrate_stddev, double& maxdev);\n\nprivate:\n\tAVIReadHandler *parent;\n\tAVIStreamNode *psnData;\n\tAVIIndexEntry2 *pIndex;\n\t//AVIReadCache *rCache;\n\tlong& length;\n\tlong& frames;\n\tlong sampsize;\n\tint streamno;\n\tbool fStreamingEnabled;\n\tbool fStreamingActive;\n\tint iStreamTrackCount;\n\tlong lStreamTrackValue;\n\tlong lStreamTrackInterval;\n\tbool fRealTime;\n\n\t__int64\t\ti64CachedPosition;\n\tAVIIndexEntry2\t*pCachedEntry;\n\n};\n\n///////////////////////////////////////////////////////////////////////////\n\nAVIReadStream::AVIReadStream(AVIReadHandler *parent, AVIStreamNode *psnData, int streamno)\n:length(psnData->length)\n,frames(psnData->frames)\n{\n\tthis->parent = parent;\n\tthis->psnData = psnData;\n\tthis->streamno = streamno;\n\n\tfStreamingEnabled = false;\n\tfStreamingActive = false;\n\tfRealTime = false;\n\n\tparent->AddRef();\n\n\tpIndex = psnData->index.index2Ptr();\n\tsampsize = psnData->hdr.dwSampleSize;\n\n\t// Hack to imitate Microsoft's parser.  It seems to ignore this value\n\t// for audio streams.\n\n\tif (psnData->hdr.fccType == streamtypeAUDIO)\n\t\tsampsize = ((WAVEFORMATEX *)psnData->pFormat)->nBlockAlign;\n\n\tif (sampsize) {\n\t\ti64CachedPosition = 0;\n\t\tpCachedEntry = pIndex;\n\t}\n\n\tpsnData->listHandlers.AddTail(this);\n}\n\nAVIReadStream::~AVIReadStream() {\n\tEndStreaming();\n\tparent->Release();\n\tRemove();\n}\n\nvoid AVIReadStream::Reinit() {\n\tpIndex = psnData->index.index2Ptr();\n\ti64CachedPosition = 0;\n\tpCachedEntry = pIndex;\n}\n\nHRESULT AVIReadStream::BeginStreaming(long lStart, long lEnd, long lRate) {\n\tif (fStreamingEnabled)\n\t\treturn 0;\n\n//\tOutputDebugString(lRate>1500 ? \"starting: fast\" : \"starting: slow\");\n\n\tif (lRate <= 1500) {\n\t\tparent->AdjustRealTime(true);\n\t\tfRealTime = true;\n\t} else\n\t\tfRealTime = false;\n\n\tif (parent->fDisableFastIO)\n\t\treturn 0;\n\n\tif (!psnData->streaming_count) {\n//\t\tif (!(psnData->cache = new AVIReadCache(psnData->hdr.fccType == 'sdiv' ? 65536 : 16384, streamno, parent, psnData)))\n//\t\t\treturn AVIERR_MEMORY;\n\n\t\tpsnData->stream_bytes = 0;\n\t\tpsnData->stream_pushes = 0;\n\t\tpsnData->stream_push_pos = 0;\n\t}\n\t++psnData->streaming_count;\n\n\tfStreamingEnabled = true;\n\tfStreamingActive = false;\n\tiStreamTrackCount = 0;\n\tlStreamTrackValue = -1;\n\tlStreamTrackInterval = -1;\n\treturn 0;\n}\n\nHRESULT AVIReadStream::EndStreaming() {\n\tif (!fStreamingEnabled)\n\t\treturn 0;\n\n\tif (fRealTime)\n\t\tparent->AdjustRealTime(false);\n\n\tif (fStreamingActive)\n\t\tparent->DisableStreaming(streamno);\n\n\tfStreamingEnabled = false;\n\tfStreamingActive = false;\n\n\tif (!--psnData->streaming_count) {\n\t\tdelete psnData->cache;\n\t\tpsnData->cache = NULL;\n\t}\n\treturn 0;\n}\n\nHRESULT AVIReadStream::Info(AVISTREAMINFO *pasi, long lSize) {\n\tAVISTREAMINFO asi;\n\n\tmemset(&asi, 0, sizeof asi);\n\n\tasi.fccType\t\t\t\t= psnData->hdr.fccType;\n\tasi.fccHandler\t\t\t= psnData->hdr.fccHandler;\n\tasi.dwFlags\t\t\t\t= psnData->hdr.dwFlags;\n\tasi.wPriority\t\t\t= psnData->hdr.wPriority;\n\tasi.wLanguage\t\t\t= psnData->hdr.wLanguage;\n\tasi.dwScale\t\t\t\t= psnData->hdr.dwScale;\n\tasi.dwRate\t\t\t\t= psnData->hdr.dwRate;\n\tasi.dwStart\t\t\t\t= psnData->hdr.dwStart;\n\tasi.dwLength\t\t\t= psnData->hdr.dwLength;\n\tasi.dwInitialFrames\t\t= psnData->hdr.dwInitialFrames;\n\tasi.dwSuggestedBufferSize = psnData->hdr.dwSuggestedBufferSize;\n\tasi.dwQuality\t\t\t= psnData->hdr.dwQuality;\n\tasi.dwSampleSize\t\t= psnData->hdr.dwSampleSize;\n\tasi.rcFrame.top\t\t\t= psnData->hdr.rcFrame.top;\n\tasi.rcFrame.left\t\t= psnData->hdr.rcFrame.left;\n\tasi.rcFrame.right\t\t= psnData->hdr.rcFrame.right;\n\tasi.rcFrame.bottom\t\t= psnData->hdr.rcFrame.bottom;\n\n\tif (lSize < sizeof asi)\n\t\tmemcpy(pasi, &asi, lSize);\n\telse {\n\t\tmemcpy(pasi, &asi, sizeof asi);\n\t\tmemset((char *)pasi + sizeof asi, 0, lSize - sizeof asi);\n\t}\n\n\treturn 0;\n}\n\nbool AVIReadStream::IsKeyFrame(long lFrame) {\n\tif (sampsize)\n\t\treturn true;\n\telse {\n\t\tif (lFrame < 0 || lFrame >= length)\n\t\t\treturn false;\n\n\t\treturn !(pIndex[lFrame].size & 0x80000000);\n\t}\n}\n\nHRESULT AVIReadStream::Read(long lStart, long lSamples, void *lpBuffer, long cbBuffer, long *plBytes, long *plSamples) {\n\tlong lActual;\n\n\tif (lStart < 0 || lStart >= length || (lSamples <= 0 && lSamples != AVISTREAMREAD_CONVENIENT)) {\n\t\t// umm... dummy!  can't read outside of stream!\n\n\t\tif (plBytes) *plBytes = 0;\n\t\tif (plSamples) *plSamples = 0;\n\n\t\treturn 0;\n\t}\n\n\t// blocked or discrete?\n\n\tif (sampsize) {\n\t\tAVIIndexEntry2 *avie2, *avie2_limit = pIndex+frames;\n\t\t__int64 byte_off = (__int64)lStart * sampsize;\n\t\t__int64 bytecnt;\n\t\t__int64 actual_bytes=0;\n\t\t__int64 block_pos;\n\n\t\t// too small to hold a sample?\n\n\t\tif (lpBuffer && cbBuffer < sampsize) {\n\t\t\tif (plBytes) *plBytes = sampsize * lSamples;\n\t\t\tif (plSamples) *plSamples = lSamples;\n\n\t\t\treturn AVIERR_BUFFERTOOSMALL;\n\t\t}\n\n\t\t// find the frame that has the starting sample -- try and work\n\t\t// from our last position to save time\n\n\t\tif (byte_off >= i64CachedPosition) {\n\t\t\tblock_pos = i64CachedPosition;\n\t\t\tavie2 = pCachedEntry;\n\t\t\tbyte_off -= block_pos;\n\t\t} else {\n\t\t\tblock_pos = 0;\n\t\t\tavie2 = pIndex;\n\t\t}\n\n\t\twhile(byte_off >= (avie2->size & 0x7FFFFFFF)) {\n\t\t\tbyte_off -= (avie2->size & 0x7FFFFFFF);\n\t\t\tblock_pos += (avie2->size & 0x7FFFFFFF);\n\t\t\t++avie2;\n\t\t}\n\n\t\tpCachedEntry = avie2;\n\t\ti64CachedPosition = block_pos;\n\n\t\t// Client too lazy to specify a size?\n\n\t\tif (lSamples == AVISTREAMREAD_CONVENIENT) {\n\t\t\tlSamples = ((avie2->size & 0x7FFFFFFF) - (long)byte_off) / sampsize;\n\n\t\t\tif (!lSamples && avie2+1 < avie2_limit)\n\t\t\t\tlSamples = ((avie2[0].size & 0x7FFFFFFF) + (avie2[1].size & 0x7FFFFFFF) - (long)byte_off) / sampsize;\n\n\t\t\tif (lSamples < 0)\n\t\t\t\tlSamples = 1;\n\t\t}\n\n\t\t// trim down sample count\n\n\t\tif (lpBuffer && lSamples > cbBuffer / sampsize)\n\t\t\tlSamples = cbBuffer / sampsize;\n\n\t\tif (lStart+lSamples > length)\n\t\t\tlSamples = length - lStart;\n\n\t\tbytecnt = lSamples * sampsize;\n\n\t\t// begin reading frames from this point on\n\n\t\tif (lpBuffer) {\n\t\t\t// detect streaming\n\n\t\t\tif (fStreamingEnabled) {\n\n\t\t\t\t// We consider the client to be streaming if we detect at least\n\t\t\t\t// 3 consecutive accesses\n\n\t\t\t\tif (lStart == lStreamTrackValue) {\n\t\t\t\t\t++iStreamTrackCount;\n\n\t\t\t\t\tif (iStreamTrackCount >= 15) {\n\n\t\t\t\t\t\t__int64 streamptr = parent->getStreamPtr();\n\t\t\t\t\t\t__int64 fptrdiff = streamptr - avie2->pos;\n\n\t\t\t\t\t\tif (!parent->isStreaming() || streamptr<0 || (fptrdiff<4194304 && fptrdiff>-4194304)) {\n\t\t\t\t\t\t\tif (!psnData->cache)\n\t\t\t\t\t\t\t\tpsnData->cache = new AVIReadCache(psnData->hdr.fccType == MAKEFOURCC('v','i','d','s') ? 131072 : 16384, streamno, parent, psnData);\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tpsnData->cache->ResetStatistics();\n\n\t\t\t\t\t\t\tif (!fStreamingActive) {\n\t\t\t\t\t\t\t\tfStreamingActive = true;\n\t\t\t\t\t\t\t\tparent->EnableStreaming(streamno);\n\t\t\t\t\t\t\t}\n\n#ifdef STREAMING_DEBUG\n\t\t\t\t\t\t\tOutputDebugString(\"[a] streaming enabled\\n\");\n#endif\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n#ifdef STREAMING_DEBUG\n\t\t\t\t\t\tOutputDebugString(\"[a] streaming detected\\n\");\n#endif\n\t\t\t\t\t}\n\t\t\t\t} else {\n#ifdef STREAMING_DEBUG\n\t\t\t\t\tOutputDebugString(\"[a] streaming disabled\\n\");\n#endif\n\t\t\t\t\tiStreamTrackCount = 0;\n\n\t\t\t\t\tif (fStreamingActive) {\n\t\t\t\t\t\tfStreamingActive = false;\n\t\t\t\t\t\tparent->DisableStreaming(streamno);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\twhile(bytecnt > 0) {\n\t\t\t\tlong tc;\n\n\t\t\t\ttc = (avie2->size & 0x7FFFFFFF) - (long)byte_off;\n\t\t\t\tif (tc > bytecnt)\n\t\t\t\t\ttc = (long)bytecnt;\n\n\t\t\t\tif (psnData->cache && fStreamingActive && tc < psnData->cache->getMaxRead()) {\n//OutputDebugString(\"[a] attempting cached read\\n\");\n\t\t\t\t\tlActual = psnData->cache->Read(lpBuffer, avie2->pos, avie2->pos + byte_off + 8, tc);\n\t\t\t\t\tpsnData->stream_bytes += lActual;\n\t\t\t\t} else\n\t\t\t\t\tlActual = parent->ReadData(streamno, lpBuffer, avie2->pos + byte_off + 8, tc);\n\n\t\t\t\tif (lActual < 0)\n\t\t\t\t\tbreak;\n\n\t\t\t\tactual_bytes += lActual;\n\t\t\t\t++avie2;\n\t\t\t\tbyte_off = 0;\n\n\t\t\t\tif (lActual < tc)\n\t\t\t\t\tbreak;\n\n\t\t\t\tbytecnt -= tc;\n\t\t\t\tlpBuffer = (char *)lpBuffer + tc;\n\t\t\t}\n\n\t\t\tif (actual_bytes < sampsize) {\n\t\t\t\tif (plBytes) *plBytes = 0;\n\t\t\t\tif (plSamples) *plSamples = 0;\n\t\t\t\treturn AVIERR_FILEREAD;\n\t\t\t}\n\n\t\t\tactual_bytes -= actual_bytes % sampsize;\n\n\t\t\tif (plBytes) *plBytes = (long)actual_bytes;\n\t\t\tif (plSamples) *plSamples = (long)actual_bytes / sampsize;\n\n\t\t\tlStreamTrackValue = lStart + (long)actual_bytes / sampsize;\n\n\t\t} else {\n\t\t\tif (plBytes) *plBytes = (long)bytecnt;\n\t\t\tif (plSamples) *plSamples = lSamples;\n\t\t}\n\n\t} else {\n\t\tAVIIndexEntry2 *avie2 = &pIndex[lStart];\n\n\t\tif (lpBuffer && (avie2->size & 0x7FFFFFFF) > cbBuffer) {\n\t\t\tif (plBytes) *plBytes = avie2->size & 0x7FFFFFFF;\n\t\t\tif (plSamples) *plSamples = 1;\n\n\t\t\treturn AVIERR_BUFFERTOOSMALL;\n\t\t}\n\n\t\tif (lpBuffer) {\n\n\t\t\t// detect streaming\n\n\t\t\tif (fStreamingEnabled && lStart != lStreamTrackValue) {\n\t\t\t\tif (lStreamTrackValue>=0 && lStart-lStreamTrackValue == lStreamTrackInterval) {\n\t\t\t\t\tif (++iStreamTrackCount >= 15) {\n\n\t\t\t\t\t\t__int64 streamptr = parent->getStreamPtr();\n\t\t\t\t\t\t__int64 fptrdiff = streamptr - avie2->pos;\n\n\t\t\t\t\t\tif (!parent->isStreaming() || streamptr<0 || (fptrdiff<4194304 && fptrdiff>-4194304)) {\n\t\t\t\t\t\t\tif (!psnData->cache)\n\t\t\t\t\t\t\t\tpsnData->cache = new AVIReadCache(psnData->hdr.fccType == MAKEFOURCC('v','i','d','s') ? 131072 : 16384, streamno, parent, psnData);\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tpsnData->cache->ResetStatistics();\n\n\t\t\t\t\t\t\tif (!fStreamingActive) {\n\t\t\t\t\t\t\t\tfStreamingActive = true;\n\t\t\t\t\t\t\t\tparent->EnableStreaming(streamno);\n\t\t\t\t\t\t\t}\n\n#ifdef STREAMING_DEBUG\n\t\t\t\t\t\t\tOutputDebugString(\"[v] streaming activated\\n\");\n#endif\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n#ifdef STREAMING_DEBUG\n\t\t\t\t\t\tOutputDebugString(\"[v] streaming detected\\n\");\n#endif\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tiStreamTrackCount = 0;\n#ifdef STREAMING_DEBUG\n\t\t\t\t\tOutputDebugString(\"[v] streaming disabled\\n\");\n#endif\n\t\t\t\t\tif (lStreamTrackValue>=0 && lStart > lStreamTrackValue) {\n\t\t\t\t\t\tlStreamTrackInterval = lStart - lStreamTrackValue;\n\t\t\t\t\t} else\n\t\t\t\t\t\tlStreamTrackInterval = -1;\n\n\t\t\t\t\tif (fStreamingActive) {\n\t\t\t\t\t\tfStreamingActive = false;\n\t\t\t\t\t\tparent->DisableStreaming(streamno);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tlStreamTrackValue = lStart;\n\t\t\t}\n\n\t\t\t// read data\n\n\t\t\tlong size = avie2->size & 0x7FFFFFFF;\n\n\t\t\tif (psnData->cache && fStreamingActive && size < psnData->cache->getMaxRead()) {\n//OutputDebugString(\"[v] attempting cached read\\n\");\n\t\t\t\tlActual = psnData->cache->Read(lpBuffer, avie2->pos, avie2->pos + 8, size);\n\t\t\t\tpsnData->stream_bytes += lActual;\n\t\t\t} else\n\t\t\t\tlActual = parent->ReadData(streamno, lpBuffer, avie2->pos+8, size);\n\n\t\t\tif (lActual != size) {\n\t\t\t\tif (plBytes) *plBytes = 0;\n\t\t\t\tif (plSamples) *plSamples = 0;\n\t\t\t\treturn AVIERR_FILEREAD;\n\t\t\t}\n\t\t}\n\n\t\tif (plBytes) *plBytes = avie2->size & 0x7FFFFFFF;\n\t\tif (plSamples) *plSamples = 1;\n\t}\n\n\tif (psnData->cache && fStreamingActive) {\n\n\t\t// Are we experiencing a high rate of cache misses?\n\n\t\tif (psnData->cache->cache_miss_bytes*2 > psnData->cache->cache_hit_bytes && psnData->cache->reads > 50) {\n\n\t\t\t// sh*t, notify the parent that we have cache misses so it can check which stream is\n\t\t\t// screwing up, and disable streaming on feeds that are too far off\n\n\t\t\tparent->FixCacheProblems(this);\n\t\t\tiStreamTrackCount = 0;\n\t\t}\n\t}/* else if (fStreamingEnabled) {\n\n\t\t// hmm... our cache got killed!\n\n\t\tiStreamTrackCount = 0;\n\n\t}*/\n\n\treturn 0;\n}\n\nlong AVIReadStream::Start() {\n\treturn 0;\n}\n\nlong AVIReadStream::End() {\n\treturn length;\n}\n\nlong AVIReadStream::PrevKeyFrame(long lFrame) {\n\tif (sampsize)\n\t\treturn lFrame>0 ? lFrame-1 : -1;\n\n\tif (lFrame < 0)\n\t\treturn -1;\n\n\tif (lFrame >= length)\n\t\tlFrame = length;\n\n\twhile(--lFrame > 0)\n\t\tif (!(pIndex[lFrame].size & 0x80000000))\n\t\t\treturn lFrame;\n\n\treturn -1;\n}\n\nlong AVIReadStream::NextKeyFrame(long lFrame) {\n\tif (sampsize)\n\t\treturn lFrame<length ? lFrame+1 : -1;\n\n\tif (lFrame < 0)\n\t\treturn 0;\n\n\tif (lFrame >= length)\n\t\treturn -1;\n\n\twhile(++lFrame < length)\n\t\tif (!(pIndex[lFrame].size & 0x80000000))\n\t\t\treturn lFrame;\n\n\treturn -1;\n}\n\nlong AVIReadStream::NearestKeyFrame(long lFrame) {\n\tlong lprev;\n\n\tif (sampsize)\n\t\treturn lFrame;\n\n\tif (IsKeyFrame(lFrame))\n\t\treturn lFrame;\n\n\tlprev = PrevKeyFrame(lFrame);\n\n\tif (lprev < 0)\n\t\treturn 0;\n\telse\n\t\treturn lprev;\n}\n\nHRESULT AVIReadStream::FormatSize(long lFrame, long *plSize) {\n\t*plSize = psnData->lFormatLen;\n\treturn 0;\n}\n\nHRESULT AVIReadStream::ReadFormat(long lFrame, void *pFormat, long *plSize) {\n\tif (!pFormat) {\n\t\t*plSize = psnData->lFormatLen;\n\t\treturn 0;\n\t}\n\n\tif (*plSize < psnData->lFormatLen) {\n\t\tmemcpy(pFormat, psnData->pFormat, *plSize);\n\t} else {\n\t\tmemcpy(pFormat, psnData->pFormat, psnData->lFormatLen);\n\t\t*plSize = psnData->lFormatLen;\n\t}\n\n\treturn 0;\n}\n\nbool AVIReadStream::isStreaming() {\n\treturn psnData->cache && fStreamingActive;\n}\n\nbool AVIReadStream::isKeyframeOnly() {\n   return psnData->keyframe_only;\n}\n\nbool AVIReadStream::getVBRInfo(double& bitrate_mean, double& bitrate_stddev, double& maxdev) {\n\tif (psnData->was_VBR) {\n\t\tbitrate_mean = psnData->bitrate_mean;\n\t\tbitrate_stddev = psnData->bitrate_stddev;\n\t\tmaxdev = psnData->max_deviation;\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n///////////////////////////////////////////////////////////////////////////\n\nAVIReadHandler::AVIReadHandler(const wchar_t *s)\n: pAvisynthClipInfo(0)\n, bAggressivelyRecovered(false)\n{\n\tthis->hFile = INVALID_HANDLE_VALUE;\n\tthis->hFileUnbuffered = INVALID_HANDLE_VALUE;\n\tthis->paf = NULL;\n\tref_count = 1;\n\tstreams=0;\n\tfStreamsActive = 0;\n\tfDisableFastIO = false;\n\tstreamBuffer = NULL;\n\tnRealTime = 0;\n\tnActiveStreamers = 0;\n\tfFakeIndex = false;\n\tnFiles = 1;\n\tnCurrentFile = 0;\n\tpSegmentHint = NULL;\n\n\tif (!g_disklockinited) {\n\t\tg_disklockinited=true;\n\t\tInitializeCriticalSection(&g_diskcs);\n\t}\n\n\t_construct(s);\n}\n\nAVIReadHandler::AVIReadHandler(PAVIFILE paf) {\n\tthis->hFile = INVALID_HANDLE_VALUE;\n\tthis->hFileUnbuffered = INVALID_HANDLE_VALUE;\n\tthis->paf = paf;\n\tref_count = 1;\n\tstreams=0;\n\tstreamBuffer = NULL;\n\tpSegmentHint = NULL;\n\tfFakeIndex = false;\n\n\tif (FAILED(paf->QueryInterface(IID_IAvisynthClipInfo, (void **)&pAvisynthClipInfo)))\n\t\tpAvisynthClipInfo = NULL;\n\telse {\n\t\tconst char *s;\n\n\t\tif (pAvisynthClipInfo->GetError(&s)) {\n\t\t\tchar* msg = _strdup(s);\n\t\t\tpAvisynthClipInfo->Release();\n\t\t\tpaf->Release();\n\t\t\ttry {\n\t\t\t\tthrow MyError(\"Avisynth open failure:%s\\n\", msg);\n\t\t\t} catch (...) {\n\t\t\t\tfree(msg);\n\t\t\t\tthrow;\n\t\t\t}\n\t\t}\n\t}\n}\n\nAVIReadHandler::~AVIReadHandler() {\n\t_destruct();\n}\n\nvoid AVIReadHandler::_construct(const wchar_t *pszFile_w) {\n\n\ttry {\n\t\tAVIFileDesc *pDesc;\n\n\t\t// open file\n\n\t\thFile = CreateFileW(pszFile_w, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);\n\n\t\tif (INVALID_HANDLE_VALUE == hFile)\n\t\t\tthrow MyWin32Error(\"Couldn't open %s: %%s\", GetLastError(), WideCharToAnsi(pszFile_w).get());\n\n\t\thFileUnbuffered = CreateFileW(\n\t\t\t\tpszFile_w,\n\t\t\t\tGENERIC_READ,\n\t\t\t\tFILE_SHARE_READ,\n\t\t\t\tNULL,\n\t\t\t\tOPEN_EXISTING,\n\t\t\t\tFILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING,\n\t\t\t\tNULL\n\t\t\t);\n\n\t\ti64FilePosition = 0;\n\n\t\t// recursively parse file\n\n\t\t_parseFile(listStreams);\n\n\t\t// Create first link\n\n\t\tif (!(pDesc = new(std::nothrow) AVIFileDesc))\n\t\t\tthrow MyMemoryError();\n\n\t\tpDesc->hFile\t\t\t= hFile;\n\t\tpDesc->hFileUnbuffered\t= hFileUnbuffered;\n\t\tpDesc->i64Size\t\t\t= i64Size = _sizeFile();\n\n\t\tlistFiles.AddHead(pDesc);\n\n\t} catch(...) {\n\t\t_destruct();\n\t\tthrow;\n\t}\n}\n\nbool AVIReadHandler::AppendFile(const wchar_t *pszFile_w) {\n\tList2<AVIStreamNode> newstreams;\n\tAVIStreamNode *pasn_old, *pasn_new, *pasn_old_next=NULL, *pasn_new_next=NULL;\n\tAVIFileDesc *pDesc;\n\n\tnCurrentFile = -1;\n\n\t// open file\n\n\thFile = CreateFileW(pszFile_w, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);\n\n\tif (INVALID_HANDLE_VALUE == hFile)\n\t\tthrow MyWin32Error(\"Couldn't open %s: %%s\", GetLastError(), WideCharToAnsi(pszFile_w).get());\n\n\thFileUnbuffered = CreateFileW(\n\t\t\tpszFile_w,\n\t\t\tGENERIC_READ,\n\t\t\tFILE_SHARE_READ,\n\t\t\tNULL,\n\t\t\tOPEN_EXISTING,\n\t\t\tFILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING,\n\t\t\tNULL\n\t\t);\n\n\ttry {\n\t\t_parseFile(newstreams);\n\n\t\tpasn_old = listStreams.AtHead();\n\t\tpasn_new = newstreams.AtHead();\n\n\t\twhile(!!(pasn_old_next = pasn_old->NextFromHead()) && !!(pasn_new_next = pasn_new->NextFromHead())) {\n\t\t\tconst char *szPrefix;\n\n\t\t\tswitch(pasn_old->hdr.fccType) {\n\t\t\tcase streamtypeAUDIO:\tszPrefix = \"Cannot append segment: The audio streams \"; break;\n\t\t\tcase streamtypeVIDEO:\tszPrefix = \"Cannot append segment: The video streams \"; break;\n\t\t\tcase MAKEFOURCC('i', 'v', 'a', 's'):\t\t\tszPrefix = \"Cannot append segment: The DV streams \"; break;\n\t\t\tdefault:\t\t\t\tszPrefix = \"\"; break;\n\t\t\t}\n\n\t\t\t// If it's not an audio or video stream, why do we care?\n\n\t\t\tif (szPrefix) {\n\t\t\t\t// allow ivas as a synonym for vids\n\n\t\t\t\tFOURCC fccOld = pasn_old->hdr.fccType;\n\t\t\t\tFOURCC fccNew = pasn_new->hdr.fccType;\n\n\t\t\t\tif (fccOld != fccNew)\n\t\t\t\t\tthrow MyError(\"Cannot append segment: The stream types do not match.\");\n\n//\t\t\t\tif (pasn_old->hdr.fccHandler != pasn_new->hdr.fccHandler)\n//\t\t\t\t\tthrow MyError(\"%suse incompatible compression types.\", szPrefix);\n\n\t\t\t\t// A/B ?= C/D ==> AD ?= BC\n\n\t\t\t\tif ((__int64)pasn_old->hdr.dwScale * pasn_new->hdr.dwRate != (__int64)pasn_new->hdr.dwScale * pasn_old->hdr.dwRate)\n\t\t\t\t\tthrow MyError(\"%shave different sampling rates (%.5f vs. %.5f)\"\n\t\t\t\t\t\t\t,szPrefix\n\t\t\t\t\t\t\t,(double)pasn_old->hdr.dwRate / pasn_old->hdr.dwScale\n\t\t\t\t\t\t\t,(double)pasn_new->hdr.dwRate / pasn_new->hdr.dwScale\n\t\t\t\t\t\t\t);\n\n\t\t\t\tif (pasn_old->hdr.dwSampleSize != pasn_new->hdr.dwSampleSize)\n\t\t\t\t\tthrow MyError(\"%shave different block sizes (%d vs %d).\", szPrefix, pasn_old->hdr.dwSampleSize, pasn_new->hdr.dwSampleSize);\n\n\t\t\t\t// I hate PCMWAVEFORMAT.\n\n\t\t\t\tbool fOk = pasn_old->lFormatLen == pasn_new->lFormatLen && !memcmp(pasn_old->pFormat, pasn_new->pFormat, pasn_old->lFormatLen);\n\n\t\t\t\tif (pasn_old->hdr.fccType == streamtypeAUDIO)\n\t\t\t\t\tif (((WAVEFORMATEX *)pasn_old->pFormat)->wFormatTag == WAVE_FORMAT_PCM\n\t\t\t\t\t\t&& ((WAVEFORMATEX *)pasn_new->pFormat)->wFormatTag == WAVE_FORMAT_PCM)\n\t\t\t\t\t\t\tfOk = !memcmp(pasn_old->pFormat, pasn_new->pFormat, sizeof(PCMWAVEFORMAT));\n\n\t\t\t\tif (!fOk)\n\t\t\t\t\tthrow MyError(\"%shave different data formats.\", szPrefix);\n\t\t\t}\n\n\t\t\tpasn_old = pasn_old_next;\n\t\t\tpasn_new = pasn_new_next;\n\t\t}\n\n\t\tif (pasn_old_next || pasn_new_next)\n\t\t\tthrow MyError(\"Cannot append segment: The segment has a different number of streams.\");\n\n\t\tif (!(pDesc = new(std::nothrow) AVIFileDesc))\n\t\t\tthrow MyMemoryError();\n\n\t\tpDesc->hFile\t\t\t= hFile;\n\t\tpDesc->hFileUnbuffered\t= hFileUnbuffered;\n\t\tpDesc->i64Size\t\t\t= _sizeFile();\n\t} catch(const AvisynthError&) {\n\t\twhile((pasn_new = newstreams.RemoveHead()))\n\t\t\tdelete pasn_new;\n\n\t\tCloseHandle(hFile);\n\t\tif (hFileUnbuffered != INVALID_HANDLE_VALUE)\n\t\t\tCloseHandle(hFileUnbuffered);\n\n\t\tthrow;\n\t}\n\n\t// Accept segment; begin merging process.\n\n\tpasn_old = listStreams.AtHead();\n\n\twhile((pasn_old_next = pasn_old->NextFromHead())) {\n\t\tpasn_new = newstreams.RemoveHead();\n\n\t\t// Fix up header.\n\n\t\tpasn_old->hdr.dwLength\t+= pasn_new->hdr.dwLength;\n\n\t\tif (pasn_new->hdr.dwSuggestedBufferSize > pasn_old->hdr.dwSuggestedBufferSize)\n\t\t\tpasn_old->hdr.dwSuggestedBufferSize = pasn_new->hdr.dwSuggestedBufferSize;\n\n\t\tpasn_old->bytes\t\t+= pasn_new->bytes;\n\t\tpasn_old->frames\t+= pasn_new->frames;\n\t\tpasn_old->length\t+= pasn_new->length;\n\n\t\t// Merge indices.\n\n\t\tint oldlen = pasn_old->index.indexLen();\n\t\tAVIIndexEntry2 *idx_old = pasn_old->index.takeIndex2();\n\t\tAVIIndexEntry2 *idx_new = pasn_new->index.index2Ptr();\n\t\tint i;\n\n\t\tpasn_old->index.clear();\n\n\t\tfor(i=0; i<oldlen; i++) {\n\t\t\tidx_old[i].size ^= 0x80000000;\n\t\t\tpasn_old->index.add(&idx_old[i]);\n\t\t}\n\n\t\tdelete[] idx_old;\n\n\t\tfor(i=pasn_new->index.indexLen(); i; i--) {\n\t\t\tidx_new->size ^= 0x80000000;\n\t\t\tidx_new->pos += (__int64)nFiles << 48;\n\t\t\tpasn_old->index.add(idx_new++);\n\t\t}\n\n\t\tpasn_old->index.makeIndex2();\n\n\t\t// Notify all handlers.\n\n\t\tAVIReadStream *pStream, *pStreamNext;\n\n\t\tpStream = pasn_old->listHandlers.AtHead();\n\t\twhile((pStreamNext = pStream->NextFromHead())) {\n\t\t\tpStream->Reinit();\n\n\t\t\tpStream = pStreamNext;\n\t\t}\n\n\t\t// Next!\n\n\t\tpasn_old = pasn_old_next;\n\t\tdelete pasn_new;\n\t}\n\n\t++nFiles;\n\tlistFiles.AddTail(pDesc);\n\n\treturn true;\n}\n\nvoid AVIReadHandler::_parseFile(List2<AVIStreamNode>& streamlist) {\n\tFOURCC fccType;\n\tDWORD dwLength;\n\tbool index_found = false;\n\tbool fAcceptIndexOnly = true;\n\tbool hyperindexed = false;\n\tbool bScanRequired = false;\n\tAVIStreamNode *pasn, *pasn_next;\n\n\t__int64\ti64ChunkMoviPos = 0;\n\tDWORD\tdwChunkMoviLength = 0;\n\n\tif (!_readChunkHeader(fccType, dwLength))\n\t\tthrow MyError(\"Invalid AVI file: File is less than 8 bytes\");\n\n\tif (fccType != FOURCC_RIFF)\n\t\tthrow MyError(\"Invalid AVI file: Not a RIFF file\");\n\n\t// If the RIFF header is <4 bytes, assume it was an improperly closed\n\t// file.\n\n\t_readFile2(&fccType, 4);\n\n\tif (fccType != MAKEFOURCC('A', 'V', 'I', ' '))\n\t\tthrow MyError(\"Invalid AVI file: RIFF type is not 'AVI'\");\n\n\t// Aggressive mode recovery does extensive validation and searching to attempt to\n\t// recover an AVI.  It is significantly slower, however.  We place the flag here\n\t// so we can set it if something dreadfully wrong is with the AVI.\n\n\tbool bAggressive = false;\n\n\t// begin parsing chunks\n\n\twhile(_readChunkHeader(fccType, dwLength)) {\n\n//\t\t_RPT4(0,\"%08I64x %08I64x Chunk '%-4s', length %08lx\\n\", _posFile()+dwLengthLeft, _posFile(), &fccType, dwLength);\n\n\t\t// Invalid FCCs are bad.  If we find one, set the aggressive flag so if a scan\n\t\t// starts, we aggressively search for and validate data.\n\n\t\tif (!isValidFOURCC(fccType)) {\n\t\t\tbAggressive = true;\n\t\t\tbreak;\n\t\t}\n\n\t\tswitch(fccType) {\n\t\tcase FOURCC_LIST:\n\t\t\t_readFile2(&fccType, 4);\n\n\t\t\t// Some idiot Premiere plugin is writing AVI files with an invalid\n\t\t\t// size field in the LIST/hdrl chunk.\n\n\t\t\tif (dwLength<4 && fccType != listtypeAVIHEADER)\n\t\t\t\tthrow MyError(\"Invalid AVI file: LIST chunk <4 bytes\");\n\n\t\t\tif (dwLength < 4)\n\t\t\t\tdwLength = 0;\n\t\t\telse\n\t\t\t\tdwLength -= 4;\n\n//\t\t\t_RPT1(0,\"\\tList type '%-4s'\\n\", &fccType);\n\n\t\t\tswitch(fccType) {\n      case MAKEFOURCC('m','o','v','i'):\n\n\t\t\t\tif (dwLength < 8) {\n\t\t\t\t\ti64ChunkMoviPos = _posFile();\n\t\t\t\t\tdwChunkMoviLength = 0xFFFFFFF0;\n\t\t\t\t\tdwLength = 0;\n\t\t\t\t} else {\n\t\t\t\t\ti64ChunkMoviPos = _posFile();\n\t\t\t\t\tdwChunkMoviLength = dwLength;\n\t\t\t\t}\n\n\t\t\t\tif (fAcceptIndexOnly)\n\t\t\t\t\tgoto terminate_scan;\n\n\t\t\t\tbreak;\n\t\t\tcase listtypeAVIHEADER:\n\t\t\t\tdwLength = 0;\t// silently enter the header block\n\t\t\t\tbreak;\n\t\t\tcase listtypeSTREAMHEADER:\n\t\t\t\tif (!_parseStreamHeader(streamlist, dwLength, bScanRequired))\n\t\t\t\t\tfAcceptIndexOnly = false;\n\t\t\t\telse\n\t\t\t\t\thyperindexed = true;\n\n\t\t\t\t++streams;\n\t\t\t\tdwLength = 0;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tbreak;\n\n\t\tcase ckidAVINEWINDEX:\t// idx1\n\t\t\tif (!hyperindexed) {\n\t\t\t\tindex_found = _parseIndexBlock(streamlist, dwLength/16, i64ChunkMoviPos);\n\t\t\t\tdwLength &= 15;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase ckidAVIPADDING:\t// JUNK\n\t\t\tbreak;\n\n\t\tcase MAKEFOURCC('s', 'e', 'g', 'm'):\t\t\t// VirtualDub segment hint block\n\t\t\tdelete [] pSegmentHint;\n\t\t\tif (!(pSegmentHint = new(std::nothrow) char[dwLength]))\n\t\t\t\tthrow MyMemoryError();\n\n\t\t\t_readFile2(pSegmentHint, dwLength);\n\n\t\t\tif (dwLength&1)\n\t\t\t\t_skipFile2(1);\n\n\t\t\tdwLength = 0;\n\t\t\tbreak;\n\n\t\t}\n\n\t\tif (dwLength) {\n\t\t\tif (!_skipFile2(dwLength + (dwLength&1)))\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// Quit as soon as we see the index block.\n\n\t\tif (fccType == ckidAVINEWINDEX)\n\t\t\tbreak;\n\t}\n\n\tif (i64ChunkMoviPos == 0)\n\t\tthrow MyError(\"This AVI file doesn't have a movie data block (movi)!\");\n\nterminate_scan:\n\n\tif (!hyperindexed && !index_found)\n\t\tbScanRequired = true;\n\n\tif (bScanRequired) {\n\t\t// It's possible that we were in the middle of reading an index when an error\n\t\t// occurred, so we need to clear all of the indices for all streams.\n\n\t\tpasn = streamlist.AtHead();\n\n\t\twhile((pasn_next = pasn->NextFromHead())) {\n\t\t\tpasn->index.clear();\n\t\t\tpasn = pasn_next;\n\t\t}\n\n\t\t// obtain length of file and limit scanning if so\n\n\t\t__int64 i64FileSize = _sizeFile();\n\n\t\tDWORD dwLengthLeft = dwChunkMoviLength;\n\n//\t\tlong short_length = (long)((dwChunkMoviLength + 1023i64) >> 10);\n//\t\tlong long_length = (long)((i64FileSize - i64ChunkMoviPos + 1023i64) >> 10);\n\n//\t\t__int64 length = (hyperindexed || bAggressive) ? long_length : short_length;\n//\t\tProgressDialog pd(NULL, \"AVI Import Filter\", bAggressive ? \"Reconstructing missing index block (aggressive mode)\" : \"Reconstructing missing index block\", length, true);\n\n//\t\tpd.setValueFormat(\"%ldK of %ldK\");\n\n\t\tfFakeIndex = true;\n\n\t\t_seekFile(i64ChunkMoviPos);\n\n\t\t// For standard AVI files, stop as soon as the movi chunk is exhausted or\n\t\t// the end of the AVI file is hit.  For OpenDML files, continue as long as\n\t\t// valid chunks are found.\n\n\t\tbool bStopWhenLengthExhausted = !hyperindexed && !bAggressive;\n\n\t\tfor(;;) {\n//\t\t\tpd.advance((long)((_posFile() - i64ChunkMoviPos)/1024));\n//\t\t\tpd.check();\n\n\t\t\t// Exit if we are out of movi chunk -- except for OpenDML files.\n\n\t\t\tif (!bStopWhenLengthExhausted && dwLengthLeft < 8)\n\t\t\t\tbreak;\n\n\t\t\t// Validate the FOURCC itself but avoid validating the size, since it\n\t\t\t// may be too large for the last LIST/movi.\n\n\t\t\tif (!_readChunkHeader(fccType, dwLength))\n\t\t\t\tbreak;\n\n\t\t\tbool bValid = isValidFOURCC(fccType) && ((_posFile() + dwLength) <= i64FileSize);\n\n\t\t\t// In aggressive mode, verify that a valid FOURCC follows this chunk.\n\n\t\t\tif (bAggressive) {\n\t\t\t\tint64_t current_pos = _posFile();\n\t\t\t\tint64_t rounded_length = (dwLength+1LL) & ~1LL;\n\n\t\t\t\tif (current_pos + dwLength > i64FileSize)\n\t\t\t\t\tbValid = false;\n\t\t\t\telse if (current_pos + rounded_length <= i64FileSize-8) {\n\t\t\t\t\tFOURCC fccNext;\n\t\t\t\t\tDWORD dwLengthNext;\n\n\t\t\t\t\t_seekFile(current_pos + rounded_length);\n\t\t\t\t\tif (!_readChunkHeader(fccNext, dwLengthNext))\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tbValid &= isValidFOURCC(fccNext) && ((_posFile() + dwLengthNext) <= i64FileSize);\n\n\t\t\t\t\t_seekFile(current_pos);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!bValid) {\n\t\t\t\t// Notify the user that recovering this file requires stronger measures.\n\n\t\t\t\tif (!bAggressive) {\n\t\t\t\t\tbAggressive = true;\n\t\t\t\t\tbStopWhenLengthExhausted = false;\n//\t\t\t\t\tpd.setCaption(\"Reconstructing missing index block (aggressive mode)\");\n//\t\t\t\t\tpd.setLimit(long_length);\n\t\t\t\t}\n\n\t\t\t\t// Backup by seven bytes and continue.\n\n\t\t\t\t_seekFile(_posFile()-7);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tint stream;\n\n//\t\t\t_RPT2(0,\"(stream header) Chunk '%-4s', length %08lx\\n\", &fccType, dwLength);\n\n\t\t\tdwLengthLeft -= 8+(dwLength + (dwLength&1));\n\n\t\t\t// Skip over the chunk.  Don't skip over RIFF chunks of type AVIX, or\n\t\t\t// LIST chunks of type 'movi'.\n\n\t\t\tif (dwLength) {\n\t\t\t\tif (fccType == MAKEFOURCC('R','I','F','F') || fccType == MAKEFOURCC('L','I','S','T')) {\n\t\t\t\t\tFOURCC fccType2;\n\n\t\t\t\t\tif (!_readFile(&fccType2, 4))\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tif (fccType2 != MAKEFOURCC('A','V','I','X') && fccType2 != MAKEFOURCC('m','o','v','i')) {\n\t\t\t\t\t\tif (!_skipFile2(dwLength + (dwLength&1) - 4))\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (!_skipFile2(dwLength + (dwLength&1)))\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (_posFile() > i64FileSize)\n\t\t\t\tbreak;\n\n\t\t\tif (isxdigit(fccType&0xff) && isxdigit((fccType>>8)&0xff)) {\n\t\t\t\tstream = StreamFromFOURCC(fccType);\n\n\t\t\t\tif (stream >=0 && stream < streams) {\n\n\t\t\t\t\tpasn = streamlist.AtHead();\n\n\t\t\t\t\twhile(stream-- && (pasn_next = pasn->NextFromHead()))\n\t\t\t\t\t\tpasn = pasn_next;\n\n\t\t\t\t\tif (pasn && pasn_next) {\n\n\t\t\t\t\t\t// Set the keyframe flag for the first sample in the stream, or\n\t\t\t\t\t\t// if this is known to be a keyframe-only stream.  Do not set the\n\t\t\t\t\t\t// keyframe flag if the frame has zero bytes (drop frame).\n\n\t\t\t\t\t\tpasn->index.add(fccType, _posFile()-(dwLength + (dwLength&1))-8, dwLength, (!pasn->bytes || pasn->keyframe_only) && dwLength>0);\n\t\t\t\t\t\tpasn->bytes += dwLength;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\t}\n\n\tbAggressivelyRecovered |= bAggressive;\n\n\t// glue together indices\n\n\tpasn = streamlist.AtHead();\n\n\twhile((pasn_next = pasn->NextFromHead())) {\n\t\tif (!pasn->index.makeIndex2())\n\t\t\tthrow MyMemoryError();\n\n\t\tpasn->frames = pasn->index.indexLen();\n\n\t\t// Clear sample size for video streams!\n\n\t\tif (pasn->hdr.fccType == streamtypeVIDEO)\n\t\t\tpasn->hdr.dwSampleSize=0;\n\n\t\t// Sample size == nBlockAlign for audio\n\n\t\tif (pasn->hdr.fccType == streamtypeAUDIO) {\n\t\t\tconst AVIIndexEntry2 *pIdx = pasn->index.index2Ptr();\n\t\t\tlong nBlockAlign = ((WAVEFORMATEX *)pasn->pFormat)->nBlockAlign;\n\n\t\t\tpasn->hdr.dwSampleSize = nBlockAlign;\n\n\t\t\tfor(int i=0; i<pasn->frames; ++i) {\n\t\t\t\tlong s = pIdx[i].size & 0x7FFFFFFF;\n\n\t\t\t\tif (s && s < nBlockAlign) {\n\t\t\t\t\tpasn->FixVBRAudio();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (pasn->hdr.dwSampleSize)\n\t\t\tpasn->length = (long)pasn->bytes / pasn->hdr.dwSampleSize;\n\t\telse\n\t\t\tpasn->length = pasn->frames;\n\n\t\tpasn = pasn_next;\n\t}\n\n//\tthrow MyError(\"Parse complete.  Aborting.\");\n}\n\nbool AVIReadHandler::_parseStreamHeader(List2<AVIStreamNode>& streamlist, DWORD dwLengthLeft, bool& bIndexDamaged) {\n\tAVIStreamNode *pasn;\n\tFOURCC fccType;\n\tDWORD dwLength;\n\tbool hyperindexed = false;\n\n\tif (!(pasn = new(std::nothrow) AVIStreamNode()))\n\t\tthrow MyMemoryError();\n\n\ttry {\n\t\twhile(dwLengthLeft >= 8 && _readChunkHeader(fccType, dwLength)) {\n\n//\t\t\t_RPT2(0,\"(stream header) Chunk '%-4s', length %08lx\\n\", &fccType, dwLength);\n\n\t\t\tdwLengthLeft -= 8;\n\n\t\t\tif (dwLength > dwLengthLeft)\n\t\t\t\tthrow MyError(\"Invalid AVI file: chunk size extends outside of parent\");\n\n\t\t\tdwLengthLeft -= (dwLength + (dwLength&1));\n\n\t\t\tswitch(fccType) {\n\n\t\t\tcase ckidSTREAMHEADER:\n\t\t\t\tmemset(&pasn->hdr, 0, sizeof pasn->hdr);\n\n\t\t\t\tif (dwLength < sizeof pasn->hdr) {\n\t\t\t\t\t_readFile2(&pasn->hdr, dwLength);\n\t\t\t\t\tif (dwLength & 1)\n\t\t\t\t\t\t_skipFile(1);\n\t\t\t\t} else {\n\t\t\t\t\t_readFile2(&pasn->hdr, sizeof pasn->hdr);\n\t\t\t\t\t_skipFile(dwLength+(dwLength&1) - sizeof pasn->hdr);\n\t\t\t\t}\n\t\t\t\tdwLength = 0;\n\n\t\t\t\tpasn->keyframe_only = false;\n\n\t\t\t\tbreak;\n\n\t\t\tcase ckidSTREAMFORMAT:\n\t\t\t\tif (!(pasn->pFormat = new(std::nothrow) char[pasn->lFormatLen = dwLength]))\n\t\t\t\t\tthrow MyMemoryError();\n\n\t\t\t\t_readFile2(pasn->pFormat, dwLength);\n\n\t\t\t\tif (pasn->hdr.fccType == streamtypeVIDEO) {\n\t\t\t\t\tswitch(((BITMAPINFOHEADER *)pasn->pFormat)->biCompression) {\n\t\t\t\t\t\tcase 0:\n\t\t\t\t\t\tcase MAKEFOURCC('R', 'A', 'W', ' '): // ' WAR'\n\t\t\t\t\t\tcase MAKEFOURCC('D', 'I', 'B', ' '): // ' BID'\n            case MAKEFOURCC('d', 'm', 'b', '1'): // '1bmd'\n            case MAKEFOURCC('m', 'j', 'p', 'g'): // 'gpjm'\n            case MAKEFOURCC('M', 'J', 'P', 'G'): // 'GPJM'\n            case MAKEFOURCC('V', 'Y', 'U', 'Y'): // 'YUYV'\n            case MAKEFOURCC('Y', 'U', 'Y', '2'): // '2YUY'\n            case MAKEFOURCC('U', 'Y', 'V', 'Y'): // 'YVYU'\n            case MAKEFOURCC('Y', 'V', 'Y', 'U'): // 'UYVY'\n            case MAKEFOURCC('Y', 'V', '1', '2'): // '21VY'\n            case MAKEFOURCC('Y', 'V', '1', '6'): // '61VY'\n            case MAKEFOURCC('Y', 'V', '2', '4'): // '42VY'\n            case MAKEFOURCC('Y', '4', '1', 'B'): // 'B14Y'\n            case MAKEFOURCC('Y', '8', '0', '0'): // '008Y'\n            case MAKEFOURCC('Y', '8', ' ', ' '): // '  8Y'\n            case MAKEFOURCC('I', '4', '2', '0'): // '024I'\n            case MAKEFOURCC('Y', '4', '1', 'P'): // 'P14Y'\n            case MAKEFOURCC('c', 'y', 'u', 'v'): // 'vuyc'\n            case MAKEFOURCC('H', 'F', 'Y', 'U'): // 'UYFH'\n            case MAKEFOURCC('b', 't', '2', '0'): // '02tb'\n\t\t\t\t\t\t\tpasn->keyframe_only = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (dwLength & 1)\n\t\t\t\t\t_skipFile(1);\n\t\t\t\tdwLength = 0;\n\t\t\t\tbreak;\n\n\t\t\tcase MAKEFOURCC('i', 'n', 'd', 'x'):\t\t\t// OpenDML extended index\n\t\t\t\t{\n\t\t\t\t\t__int64 posFileSave = _posFile();\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\t_parseExtendedIndexBlock(streamlist, pasn, -1, dwLength);\n\t\t\t\t\t} catch(const AvisynthError&) {\n\t\t\t\t\t\tbIndexDamaged = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t_seekFile(posFileSave);\n\t\t\t\t}\n\t\t\t\thyperindexed = true;\n\t\t\t\tbreak;\n\n\t\t\tcase ckidAVIPADDING:\t// JUNK\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (dwLength) {\n\t\t\t\tif (!_skipFile2(dwLength + (dwLength&1)))\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (dwLengthLeft)\n\t\t\t_skipFile2(dwLengthLeft);\n\t} catch(...) {\n\t\tdelete pasn;\n\t\tthrow;\n\t}\n\n//\t_RPT1(0,\"Found stream: type %s\\n\", pasn->hdr.fccType==streamtypeVIDEO ? \"video\" : pasn->hdr.fccType==streamtypeAUDIO ? \"audio\" : \"unknown\");\n\n\tstreamlist.AddTail(pasn);\n\n\treturn hyperindexed;\n}\n\nbool AVIReadHandler::_parseIndexBlock(List2<AVIStreamNode>& streamlist, int count, __int64 movi_offset) {\n\tAVIINDEXENTRY avie[32];\n\tAVIStreamNode *pasn, *pasn_next;\n\tbool absolute_addr = true;\n\n\t// Some AVI files have relative addresses in their AVI index chunks, and some\n\t// relative.  They're supposed to be relative to the 'movi' chunk; all versions\n\t// of VirtualDub using fast write routines prior to build 4936 generate absolute\n\t// addresses (oops). AVIFile and ActiveMovie are both ambivalent.  I guess we'd\n\t// better be as well.\n\n\twhile(count > 0) {\n\t\tint tc = count;\n\t\tint i;\n\n\t\tif (tc>32) tc=32;\n\t\tcount -= tc;\n\n\t\tif (tc*int(sizeof(AVIINDEXENTRY)) != _readFile(avie, tc*sizeof(AVIINDEXENTRY))) {\n\t\t\tpasn = streamlist.AtHead();\n\n\t\t\twhile((pasn_next = pasn->NextFromHead())) {\n\t\t\t\tpasn->index.clear();\n\t\t\t\tpasn->bytes = 0;\n\n\t\t\t\tpasn = pasn_next;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tfor(i=0; i<tc; i++) {\n\t\t\tint stream = StreamFromFOURCC(avie[i].ckid);\n\n\t\t\tif (absolute_addr && avie[i].dwChunkOffset<movi_offset)\n\t\t\t\tabsolute_addr = false;\n\n\t\t\tpasn = streamlist.AtHead();\n\n\t\t\twhile((pasn_next = (AVIStreamNode *)pasn->NextFromHead()) && stream--)\n\t\t\t\tpasn = pasn_next;\n\n\t\t\tif (pasn && pasn_next) {\n\t\t\t\tif (absolute_addr)\n\t\t\t\t\tpasn->index.add(&avie[i]);\n\t\t\t\telse\n\t\t\t\t\tpasn->index.add(avie[i].ckid, (movi_offset-4) + (__int64)avie[i].dwChunkOffset, avie[i].dwChunkLength, !!(avie[i].dwFlags & AVIIF_KEYFRAME));\n\n\t\t\t\tpasn->bytes += avie[i].dwChunkLength;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn true;\n\n}\n\nvoid AVIReadHandler::_parseExtendedIndexBlock(List2<AVIStreamNode>& streamlist, AVIStreamNode *pasn, __int64 fpos, DWORD dwLength) {\n#pragma warning( push )\n#pragma warning (disable: 4815) // zero-sized array in stack object will have no elements\n\tunion {\n\t\tAVISUPERINDEX idxsuper;\n\t\tAVISTDINDEX idxstd;\n\t};\n#pragma warning( pop )\n\n\tunion {\n\t\tstruct\t_avisuperindex_entry\t\tsuperent[64];\n\t\tDWORD\tdwHeap[256];\n\t};\n\n\tint entries, tp;\n\tint i;\n\t__int64 i64FPSave = _posFile();\n\n\tif (fpos>=0)\n\t\t_seekFile(fpos);\n\t_readFile2((char *)&idxsuper + 8, sizeof(AVISUPERINDEX) - 8);\n\n\tswitch(idxsuper.bIndexType) {\n\tcase AVI_INDEX_OF_INDEXES:\n\t\t// sanity check\n\n\t\tif (idxsuper.wLongsPerEntry != 4)\n\t\t\tthrow MyError(\"Invalid superindex block in stream\");\n\n//\t\tif (idxsuper.bIndexSubType != 0)\n//\t\t\tthrow MyError(\"Field indexes not supported\");\n\n\t\tentries = idxsuper.nEntriesInUse;\n\n\t\twhile(entries > 0) {\n\t\t\ttp = sizeof superent / sizeof superent[0];\n\t\t\tif (tp>entries) tp=entries;\n\n\t\t\t_readFile2(superent, tp*sizeof superent[0]);\n\n\t\t\tfor(i=0; i<tp; i++)\n\t\t\t\t_parseExtendedIndexBlock(streamlist, pasn, superent[i].qwOffset+8, superent[i].dwSize-8);\n\n\t\t\tentries -= tp;\n\t\t}\n\n\t\tbreak;\n\n\tcase AVI_INDEX_OF_CHUNKS:\n\n//\t\tif (idxstd.bIndexSubType != 0)\n//\t\t\tthrow MyError(\"Frame indexes not supported\");\n\n\t\tentries = idxstd.nEntriesInUse;\n\n\t\t// In theory, if bIndexSubType==AVI_INDEX_2FIELD it's supposed to have\n\t\t// wLongsPerEntry=3, and bIndexSubType==0 gives wLongsPerEntry=2.\n\t\t// Matrox's MPEG-2 stuff generates bIndexSubType=16 and wLongsPerEntry=6.\n\t\t// *sigh*\n\t\t//\n\t\t// For wLongsPerEntry==2 and ==3, dwOffset is at 0 and dwLength at 1;\n\t\t// for wLongsPerEntry==6, dwOffset is at 2 and all are keyframes.\n\n\t\t{\n\t\t\tif (idxstd.wLongsPerEntry!=2 && idxstd.wLongsPerEntry!=3 && idxstd.wLongsPerEntry!=6)\n\t\t\t\tthrow MyError(\"Invalid OpenDML index block in stream (wLongsPerEntry=%d)\", idxstd.wLongsPerEntry);\n\n\t\t\twhile(entries > 0) {\n\t\t\t\ttp = (sizeof dwHeap / sizeof dwHeap[0]) / idxstd.wLongsPerEntry;\n\t\t\t\tif (tp>entries) tp=entries;\n\n\t\t\t\t_readFile2(dwHeap, tp*idxstd.wLongsPerEntry*sizeof(DWORD));\n\n\t\t\t\tif (idxstd.wLongsPerEntry == 6)\n\t\t\t\t\tfor(i=0; i<tp; i++) {\n\t\t\t\t\t\tDWORD dwOffset = dwHeap[i*idxstd.wLongsPerEntry + 0];\n\t\t\t\t\t\tDWORD dwSize = dwHeap[i*idxstd.wLongsPerEntry + 2];\n\n\t\t\t\t\t\tpasn->index.add(idxstd.dwChunkId, (idxstd.qwBaseOffset+dwOffset)-8, dwSize, true);\n\n\t\t\t\t\t\tpasn->bytes += dwSize;\n\t\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tfor(i=0; i<tp; i++) {\n\t\t\t\t\t\tDWORD dwOffset = dwHeap[i*idxstd.wLongsPerEntry + 0];\n\t\t\t\t\t\tDWORD dwSize = dwHeap[i*idxstd.wLongsPerEntry + 1];\n\n\t\t\t\t\t\tpasn->index.add(idxstd.dwChunkId, (idxstd.qwBaseOffset+dwOffset)-8, dwSize&0x7FFFFFFF, !(dwSize&0x80000000));\n\n\t\t\t\t\t\tpasn->bytes += dwSize & 0x7FFFFFFF;\n\t\t\t\t\t}\n\n\t\t\t\tentries -= tp;\n\t\t\t}\n\t\t}\n\n\t\tbreak;\n\n\tdefault:\n\t\tthrow MyError(\"Unknown hyperindex type\");\n\t}\n\n\t_seekFile(i64FPSave);\n}\n\nvoid AVIReadHandler::_destruct() {\n\tAVIStreamNode *pasn;\n\tAVIFileDesc *pDesc;\n\n\tif (pAvisynthClipInfo)\n\t\tpAvisynthClipInfo->Release();\n\n\tif (paf)\n\t\tAVIFileRelease(paf);\n\n\twhile((pasn = listStreams.RemoveTail()))\n\t\tdelete pasn;\n\n\tdelete streamBuffer;\n\n\tif (listFiles.IsEmpty()) {\n\t\tif (hFile != INVALID_HANDLE_VALUE)\n\t\t\tCloseHandle(hFile);\n\t\tif (hFileUnbuffered != INVALID_HANDLE_VALUE)\n\t\t\tCloseHandle(hFileUnbuffered);\n\t} else\n\t\twhile((pDesc = listFiles.RemoveTail())) {\n\t\t\tCloseHandle(pDesc->hFile);\n\t\t\tCloseHandle(pDesc->hFileUnbuffered);\n\t\t\tdelete pDesc;\n\t\t}\n\n\tdelete [] pSegmentHint;\n}\n\n///////////////////////////////////////////////////////////////////////////\n\nvoid AVIReadHandler::Release() {\n\tif (!--ref_count)\n\t\tdelete this;\n}\n\nvoid AVIReadHandler::AddRef() {\n\t++ref_count;\n}\n\nIAVIReadStream *AVIReadHandler::GetStream(DWORD fccType, LONG lParam) {\n\tif (paf) {\n\t\tPAVISTREAM pas;\n\t\tHRESULT hr;\n\n\t\thr = AVIFileGetStream(paf, &pas, fccType, lParam);\n\n\t\tif (FAILED(hr))\n\t\t\treturn NULL;\n\n\t\treturn new AVIReadTunnelStream(this, pas, pAvisynthClipInfo);\n\t} else {\n\t\tAVIStreamNode *pasn, *pasn_next;\n\t\tint streamno = 0;\n\n\t\tpasn = listStreams.AtHead();\n\n\t\twhile((pasn_next = pasn->NextFromHead())) {\n\t\t\tif (pasn->hdr.fccType == fccType && !lParam--)\n\t\t\t\tbreak;\n\n\t\t\tpasn = pasn_next;\n\t\t\t++streamno;\n\t\t}\n\n\t\tif (pasn_next) {\n\t\t\treturn new AVIReadStream(this, pasn, streamno);\n\t\t}\n\n\t\treturn NULL;\n\t}\n}\n\nvoid AVIReadHandler::EnableFastIO(bool f) {\n\tfDisableFastIO = !f;\n}\n\nbool AVIReadHandler::isOptimizedForRealtime() {\n\treturn nRealTime!=0;\n}\n\nbool AVIReadHandler::isStreaming() {\n\treturn nActiveStreamers!=0;\n}\n\nbool AVIReadHandler::isIndexFabricated() {\n\treturn fFakeIndex;\n}\n\nbool AVIReadHandler::getSegmentHint(const char **ppszPath) {\n\tif (!pSegmentHint) {\n\t\tif (ppszPath)\n\t\t\t*ppszPath = NULL;\n\n\t\treturn false;\n\t}\n\n\tif (ppszPath)\n\t\t*ppszPath = pSegmentHint+1;\n\n\treturn !!pSegmentHint[0];\n}\n\n///////////////////////////////////////////////////////////////////////////\n\nvoid AVIReadHandler::EnableStreaming(int stream) {\n\tif (!fStreamsActive) {\n\t\tif (!(streamBuffer = new(std::nothrow) char[STREAM_SIZE]))\n\t\t\tthrow MyMemoryError();\n\n\t\ti64StreamPosition = -1;\n\t\tsbPosition = sbSize = 0;\n\t}\n\n\tfStreamsActive |= (1<<stream);\n\t++nActiveStreamers;\n}\n\nvoid AVIReadHandler::DisableStreaming(int stream) {\n\tfStreamsActive &= ~(1<<stream);\n\n\tif (!fStreamsActive) {\n\t\tdelete streamBuffer;\n\t\tstreamBuffer = NULL;\n\t}\n\t--nActiveStreamers;\n}\n\nvoid AVIReadHandler::AdjustRealTime(bool fInc) {\n\tif (fInc)\n\t\t++nRealTime;\n\telse\n\t\t--nRealTime;\n}\n\nchar *AVIReadHandler::_StreamRead(long& bytes) {\n\tif (nCurrentFile<0 || nCurrentFile != (int)(i64StreamPosition>>48))\n\t\t_SelectFile((int)(i64StreamPosition>>48));\n\n\tif (sbPosition >= sbSize) {\n\t\tif (nRealTime || (((i64StreamPosition&0x0000FFFFFFFFFFFFLL)+sbSize) & -STREAM_BLOCK_SIZE)+STREAM_SIZE > i64Size) {\n\t\t\ti64StreamPosition += sbSize;\n\t\t\tsbPosition = 0;\n\t\t\t_seekFile(i64StreamPosition & 0x0000FFFFFFFFFFFFLL);\n\n\t\t\tsbSize = _readFile(streamBuffer, STREAM_RT_SIZE);\n\n\t\t\tif (sbSize < 0) {\n\t\t\t\tsbSize = 0;\n\t\t\t\tthrow MyWin32Error(\"Failure streaming AVI file: %%s.\",GetLastError());\n\t\t\t}\n\t\t} else {\n\t\t\ti64StreamPosition += sbSize;\n\t\t\tsbPosition = (int)i64StreamPosition & (STREAM_BLOCK_SIZE-1);\n\t\t\ti64StreamPosition &= -STREAM_BLOCK_SIZE;\n\t\t\t_seekFileUnbuffered(i64StreamPosition & 0x0000FFFFFFFFFFFFLL);\n\n\t\t\tsbSize = _readFileUnbuffered(streamBuffer, STREAM_SIZE);\n\n\t\t\tif (sbSize < 0) {\n\t\t\t\tsbSize = 0;\n\t\t\t\tthrow MyWin32Error(\"Failure streaming AVI file: %%s.\",GetLastError());\n\t\t\t}\n\t\t}\n\t}\n\n\tif (sbPosition >= sbSize)\n\t\treturn NULL;\n\n\tif (bytes > sbSize - sbPosition)\n\t\tbytes = sbSize - sbPosition;\n\n\tsbPosition += bytes;\n\n\treturn streamBuffer + sbPosition - bytes;\n}\n\nbool AVIReadHandler::Stream(AVIStreamNode *pusher, __int64 pos) {\n\n\t// Do not stream aggressively recovered files.\n\n\tif (bAggressivelyRecovered)\n\t\treturn false;\n\n\tbool read_something = false;\n\n\tif (!streamBuffer)\n\t\treturn false;\n\n\tif (i64StreamPosition == -1) {\n\t\ti64StreamPosition = pos;\n\t\tsbPosition = 0;\n\t}\n\n\tif (pos < i64StreamPosition+sbPosition)\n\t\treturn false;\n\n\t// >4Mb past current position!?\n\n\tif (pos > i64StreamPosition+sbPosition+4194304) {\n//\t\tOutputDebugString(\"Resetting streaming position!\\n\");\n\t\ti64StreamPosition = pos;\n\t\tsbSize = sbPosition = 0;\n\t}\n\n/*\tif (pusher->hdr.fccType == 'sdiv')\n\t\tOutputDebugString(\"pushed by video\\n\");\n\telse\n\t\tOutputDebugString(\"pushed by audio\\n\");*/\n\n\t++pusher->stream_pushes;\n\tpusher->stream_push_pos = pos;\n\n\twhile(pos >= i64StreamPosition+sbPosition) {\n\t\tlong actual, left;\n\t\tchar *src;\n\t\tFOURCC hdr[2];\n\t\tint stream;\n\n\t\t// read next header\n\n\t\tleft = 8;\n\t\twhile(left > 0) {\n\t\t\tactual = left;\n\t\t\tsrc = _StreamRead(actual);\n\n\t\t\tif (!src)\n\t\t\t\treturn read_something;\n\n\t\t\tmemcpy((char *)hdr + (8-left), src, actual);\n\t\t\tleft -= actual;\n\t\t}\n\n\t\tstream = StreamFromFOURCC(hdr[0]);\n\n\t\tif (isxdigit(hdr[0]&0xff) && isxdigit((hdr[0]>>8)&0xff) && stream<32 &&\n\t\t\t((1L<<stream) & fStreamsActive)) {\n\n//\t\t\t_RPT3(0,\"\\tstream: reading chunk at %I64x, length %6ld, stream %ld\\n\", i64StreamPosition+sbPosition-8, hdr[1], stream);\n\n\t\t\tAVIStreamNode *pasn, *pasn_next;\n\t\t\tint streamno = 0;\n\n\t\t\tpasn = listStreams.AtHead();\n\n\t\t\twhile((pasn_next = pasn->NextFromHead())) {\n\t\t\t\tif (streamno == stream) {\n\t\t\t\t\tlong left = hdr[1] + (hdr[1]&1);\n\t\t\t\t\tbool fWrite = pasn->cache->WriteBegin(i64StreamPosition + sbPosition, left);\n\t\t\t\t\tchar *dst;\n\n\t\t\t\t\twhile(left > 0) {\n\t\t\t\t\t\tactual = left;\n\n\t\t\t\t\t\tdst = _StreamRead(actual);\n\n\t\t\t\t\t\tif (!dst) {\n\t\t\t\t\t\t\tif (fWrite)\n\t\t\t\t\t\t\t\tpasn->cache->WriteEnd();\n\t\t\t\t\t\t\treturn read_something;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (fWrite)\n\t\t\t\t\t\t\tpasn->cache->Write(dst, actual);\n\n\t\t\t\t\t\tleft -= actual;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (fWrite)\n\t\t\t\t\t\tpasn->cache->WriteEnd();\n\n\t\t\t\t\tread_something = true;\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tpasn = pasn_next;\n\t\t\t\t++streamno;\n\t\t\t}\n\t\t} else {\n\n\t\t\tif (hdr[0] != FOURCC_LIST && hdr[0] != FOURCC_RIFF) {\n\t\t\t\tlong actual;\n\n\t\t\t\t// skip chunk\n\n\t\t\t\tleft = hdr[1] + (hdr[1] & 1);\n\n\t\t\t\t// Determine if the chunk is overly large.  If the chunk is too large, don't\n\t\t\t\t// stream through it.\n\n\t\t\t\tif (left > 262144)\n\t\t\t\t\treturn read_something;\n\n\t\t\t\twhile(left > 0) {\n\t\t\t\t\tactual = left;\n\n\t\t\t\t\tif (!_StreamRead(actual))\n\t\t\t\t\t\treturn read_something;\n\n\t\t\t\t\tleft -= actual;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tleft = 4;\n\n\t\t\t\twhile(left > 0) {\n\t\t\t\t\tactual = left;\n\n\t\t\t\t\tif (!_StreamRead(actual))\n\t\t\t\t\t\treturn read_something;\n\n\t\t\t\t\tleft -= actual;\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\t}\n\n\treturn true;\n}\n\n__int64 AVIReadHandler::getStreamPtr() {\n\treturn i64StreamPosition + sbPosition;\n}\n\nvoid AVIReadHandler::FixCacheProblems(AVIReadStream *arse) {\n\tAVIStreamNode *pasn, *pasn_next;\n\n\t// The simplest fix is simply to disable caching on the stream that's\n\t// cache-missing.  However, this is a bad idea if the problem is a low-bandwidth\n\t// audio stream that's outrunning a high-bandwidth video stream behind it.\n\t// Check the streaming leader, and if the streaming leader is comparatively\n\t// low bandwidth and running at least 512K ahead of the cache-missing stream,\n\t// disable its cache.\n\n\tAVIStreamNode *stream_leader = NULL;\n\tint stream_leader_no=0;\n\tint streamno=0;\n\n\tpasn = listStreams.AtHead();\n\n\twhile((pasn_next = pasn->NextFromHead())) {\n\t\tif (pasn->cache)\n\t\t\tif (!stream_leader || pasn->stream_pushes > stream_leader->stream_pushes) {\n\t\t\t\tstream_leader = pasn;\n\t\t\t\tstream_leader_no = streamno;\n\t\t\t}\n\n\t\tpasn = pasn_next;\n\t\t++streamno;\n\t}\n\n\tif (stream_leader && stream_leader->stream_bytes*2 < arse->psnData->stream_bytes\n\t\t&& stream_leader->stream_push_pos >= arse->psnData->stream_push_pos+524288) {\n#ifdef STREAMING_DEBUG\n\t\tOutputDebugString(\"caching disabled on fast puny leader\\n\");\n#endif\n\t\tdelete stream_leader->cache;\n\t\tstream_leader->cache = NULL;\n\n\t\tDisableStreaming(stream_leader_no);\n\n\t\ti64StreamPosition = -1;\n\t\tsbPosition = sbSize = 0;\n\t} else {\n#ifdef STREAMING_DEBUG\n\t\tOutputDebugString(\"disabling caching at request of client\\n\");\n#endif\n\n\t\tarse->EndStreaming();\n\n\t\tif (arse->psnData == stream_leader) {\n\t\t\ti64StreamPosition = -1;\n\t\t\tsbPosition = sbSize = 0;\n\t\t}\n\t}\n\n\t// Reset cache statistics on all caches.\n\n\tpasn = listStreams.AtHead();\n\n\twhile((pasn_next = pasn->NextFromHead())) {\n\t\tif (pasn->cache)\n\t\t\tpasn->cache->ResetStatistics();\n\n\t\tpasn = pasn_next;\n\t}\n}\n\nlong AVIReadHandler::ReadData(int stream, void *buffer, __int64 position, long len) {\n\tif (nCurrentFile<0 || nCurrentFile != (int)(position>>48))\n\t\t_SelectFile((int)(position>>48));\n\n//\t_RPT3(0,\"Reading from file %d, position %I64x, size %d\\n\", nCurrentFile, position, len);\n\n\tif (!_seekFile2(position & 0x0000FFFFFFFFFFFFLL))\n\t\treturn -1;\n\treturn _readFile(buffer, len);\n}\n\nvoid AVIReadHandler::_SelectFile(int file) {\n\tAVIFileDesc *pDesc, *pDesc_next;\n\n\tnCurrentFile = file;\n\n\tpDesc = listFiles.AtHead();\n\twhile((pDesc_next = pDesc->NextFromHead()) && file--)\n\t\tpDesc = pDesc_next;\n\n\thFile\t\t\t= pDesc->hFile;\n\thFileUnbuffered\t= pDesc->hFileUnbuffered;\n\ti64Size\t\t\t= pDesc->i64Size;\n}\n"
  },
  {
    "path": "avs_core/filters/AviSource/AVIReadHandler.h",
    "content": "//\tVirtualDub - Video processing and capture application\n//\tCopyright (C) 1998-2001 Avery Lee\n//\n//\tThis program is free software; you can redistribute it and/or modify\n//\tit under the terms of the GNU General Public License as published by\n//\tthe Free Software Foundation; either version 2 of the License, or\n//\t(at your option) any later version.\n//\n//\tThis program is distributed in the hope that it will be useful,\n//\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n//\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//\tGNU General Public License for more details.\n//\n//\tYou should have received a copy of the GNU General Public License\n//\talong with this program; if not, write to the Free Software\n//\tFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n#ifndef f_AVIREADHANDLER_H\n#define f_AVIREADHANDLER_H\n\n#include <avs/win.h>\n#include <vfw.h>\n\n// These are meant as AVIFile replacements.  They're not quite to AVIFile\n// specs, but they'll do for now.\n\nclass IAVIReadStream {\npublic:\n\tvirtual ~IAVIReadStream();\n\n\tvirtual HRESULT BeginStreaming(long lStart, long lEnd, long lRate)=0;\n\tvirtual HRESULT EndStreaming()=0;\n\tvirtual HRESULT Info(AVISTREAMINFO *pasi, long lSize)=0;\n\tvirtual bool IsKeyFrame(long lFrame)=0;\n\tvirtual HRESULT Read(long lStart, long lSamples, void *lpBuffer, long cbBuffer, long *plBytes, long *plSamples)=0;\n\tvirtual long Start()=0;\n\tvirtual long End()=0;\n\tvirtual long PrevKeyFrame(long lFrame)=0;\n\tvirtual long NextKeyFrame(long lFrame)=0;\n\tvirtual long NearestKeyFrame(long lFrame)=0;\n\tvirtual HRESULT FormatSize(long lFrame, long *plSize)=0;\n\tvirtual HRESULT ReadFormat(long lFrame, void *pFormat, long *plSize)=0;\n\tvirtual bool isStreaming()=0;\n\tvirtual bool isKeyframeOnly()=0;\n\n\tvirtual bool getVBRInfo(double& bitrate_mean, double& bitrate_stddev, double& maxdev)=0;\n};\n\nclass IAVIReadHandler {\npublic:\n\tvirtual void AddRef()=0;\n\tvirtual void Release()=0;\n\tvirtual IAVIReadStream *GetStream(DWORD fccType, LONG lParam)=0;\n\tvirtual void EnableFastIO(bool)=0;\n\tvirtual bool isOptimizedForRealtime()=0;\n\tvirtual bool isStreaming()=0;\n\tvirtual bool isIndexFabricated()=0;\n\tvirtual bool AppendFile(const wchar_t *pszFile)=0;\n\tvirtual bool getSegmentHint(const char **ppszPath)=0;\n};\n\nIAVIReadHandler *CreateAVIReadHandler(PAVIFILE paf);\nIAVIReadHandler *CreateAVIReadHandler(const wchar_t *pszFile);\n\n#endif\n"
  },
  {
    "path": "avs_core/filters/AviSource/AudioSource.cpp",
    "content": "//\tVirtualDub - Video processing and capture application\n//\tCopyright (C) 1998-2001 Avery Lee\n//\n//\tThis program is free software; you can redistribute it and/or modify\n//\tit under the terms of the GNU General Public License as published by\n//\tthe Free Software Foundation; either version 2 of the License, or\n//\t(at your option) any later version.\n//\n//\tThis program is distributed in the hope that it will be useful,\n//\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n//\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//\tGNU General Public License for more details.\n//\n//\tYou should have received a copy of the GNU General Public License\n//\talong with this program; if not, write to the Free Software\n//\tFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n//#include \"gui.h\"\n#include \"AudioSource.h\"\n#include \"AVIReadHandler.h\"\n\n//extern HWND g_hWnd;\t\t// TODO: Remove in 1.5.0\n\n// #pragma warning(disable: 4018)    // signed/unsigned mismatch\n\n\nAudioSourceWAV::AudioSourceWAV(char *szFile, LONG inputBufferSize) {\n\tMMIOINFO mmi;\n\n\tmemset(&mmi,0,sizeof mmi);\n\tmmi.cchBuffer\t= inputBufferSize;\n\thmmioFile\t\t= mmioOpen(szFile, &mmi, MMIO_READ | MMIO_ALLOCBUF);\n}\n\nAudioSourceWAV::~AudioSourceWAV() {\n\tmmioClose(hmmioFile, 0);\n}\n\nBOOL AudioSourceWAV::init() {\n\tif (!hmmioFile) return FALSE;\n\n\tchunkRIFF.fccType = mmioFOURCC('W','A','V','E');\n\tif (MMSYSERR_NOERROR != mmioDescend(hmmioFile, &chunkRIFF, NULL, MMIO_FINDRIFF))\n\t\treturn FALSE;\n\n\tchunkDATA.ckid = mmioFOURCC('f','m','t',' ');\n\tif (MMSYSERR_NOERROR != mmioDescend(hmmioFile, &chunkDATA, &chunkRIFF, MMIO_FINDCHUNK))\n\t\treturn FALSE;\n\n\tif (!allocFormat(chunkDATA.cksize)) return FALSE;\n\tif (LONG(chunkDATA.cksize) != mmioRead(hmmioFile, (char *)getWaveFormat(), chunkDATA.cksize))\n\t\treturn FALSE;\n\n\tif (MMSYSERR_NOERROR != mmioAscend(hmmioFile, &chunkDATA, 0))\n\t\treturn FALSE;\n\n\tchunkDATA.ckid = mmioFOURCC('d','a','t','a');\n\tif (MMSYSERR_NOERROR != mmioDescend(hmmioFile, &chunkDATA, &chunkRIFF, MMIO_FINDCHUNK))\n\t\treturn FALSE;\n\n\tbytesPerSample\t= getWaveFormat()->nBlockAlign; //getWaveFormat()->nAvgBytesPerSec / getWaveFormat()->nSamplesPerSec;\n\tlSampleFirst\t= 0;\n\tlSampleLast\t\t= chunkDATA.cksize / bytesPerSample;\n\tlCurrentSample\t= 0;\n\n\tstreamInfo.fccType\t\t\t\t\t= streamtypeAUDIO;\n\tstreamInfo.fccHandler\t\t\t\t= 0;\n\tstreamInfo.dwFlags\t\t\t\t\t= 0;\n\tstreamInfo.wPriority\t\t\t\t= 0;\n\tstreamInfo.wLanguage\t\t\t\t= 0;\n\tstreamInfo.dwInitialFrames\t\t\t= 0;\n\tstreamInfo.dwScale\t\t\t\t\t= bytesPerSample;\n\tstreamInfo.dwRate\t\t\t\t\t= getWaveFormat()->nAvgBytesPerSec;\n\tstreamInfo.dwStart\t\t\t\t\t= 0;\n\tstreamInfo.dwLength\t\t\t\t\t= chunkDATA.cksize / bytesPerSample;\n\tstreamInfo.dwSuggestedBufferSize\t= 0;\n\tstreamInfo.dwQuality\t\t\t\t= 0xffffffff;\n\tstreamInfo.dwSampleSize\t\t\t\t= bytesPerSample;\n\n\treturn TRUE;\n}\n\nint AudioSourceWAV::_read(LONG lStart, LONG lCount, LPVOID buffer, LONG cbBuffer, LONG *lBytesRead, LONG *lSamplesRead) {\n\tLONG lBytes = lCount * bytesPerSample;\n\n\tif (buffer) {\n\t\tif (lStart != lCurrentSample)\n\t\t\tif (-1 == mmioSeek(hmmioFile, chunkDATA.dwDataOffset + bytesPerSample*lStart, SEEK_SET))\n\t\t\t\treturn AVIERR_FILEREAD;\n\n\t\tif (lBytes != mmioRead(hmmioFile, (char *)buffer, lBytes))\n\t\t\treturn AVIERR_FILEREAD;\n\n\t\tlCurrentSample = lStart + lCount;\n\t}\n\n\t*lSamplesRead = lCount;\n\t*lBytesRead = lBytes;\n\n\treturn AVIERR_OK;\n}\n\n///////////////////////////\n\nAudioSourceAVI::AudioSourceAVI(IAVIReadHandler *pAVI, bool bAutomated, int atrack) {\n\tpAVIFile\t= pAVI;\n\tpAVIStream\t= NULL;\n\tbQuiet = bAutomated;\t// ugh, this needs to go... V1.5.0.\n\taudiotrack = atrack;\n}\n\nAudioSourceAVI::~AudioSourceAVI() {\n\tif (pAVIStream)\n\t\tdelete pAVIStream;\n}\n\nBOOL AudioSourceAVI::init() {\n\tLONG format_len;\n\n\tpAVIStream = pAVIFile->GetStream(streamtypeAUDIO, audiotrack);\n\tif (!pAVIStream) return FALSE;\n\n\tif (FAILED(pAVIStream->Info(&streamInfo, sizeof streamInfo)))\n\t\treturn FALSE;\n\n\tpAVIStream->FormatSize(0, &format_len);\n\n\tif (!allocFormat(format_len)) return FALSE;\n\n\tif (FAILED(pAVIStream->ReadFormat(0, getFormat(), &format_len)))\n\t\treturn FALSE;\n\n\tlSampleFirst = pAVIStream->Start();\n\tlSampleLast = pAVIStream->End();\n\n\tif (!bQuiet) {\n\t\tdouble mean, stddev, maxdev;\n\n\t\tif (pAVIStream->getVBRInfo(mean, stddev, maxdev)) {\n/*\t\t\tguiMessageBoxF(g_hWnd, \"VBR audio stream detected\", MB_OK|MB_TASKMODAL|MB_SETFOREGROUND,\n\t\t\t\t\"VirtualDub has detected an improper VBR audio encoding in the source AVI file and will rewrite the audio header \"\n\t\t\t\t\"with standard CBR values during processing for better compatibility. This may introduce up to %.0lf ms of skew \"\n\t\t\t\t\"from the video stream. If this is unacceptable, decompress the *entire* audio stream to an uncompressed WAV file \"\n\t\t\t\t\"and recompress with a constant bitrate encoder. \"\n\t\t\t\t\"(bitrate: %.1lf  %.1lf kbps)\"\n\t\t\t\t,maxdev*1000.0,mean*0.001, stddev*0.001);\n */\n\t\t}\n\t}\n\n\treturn TRUE;\n}\n\nvoid AudioSourceAVI::Reinit() {\n\tpAVIStream->Info(&streamInfo, sizeof streamInfo);\n\tlSampleFirst = pAVIStream->Start();\n\tlSampleLast = pAVIStream->End();\n}\n\nbool AudioSourceAVI::isStreaming() {\n\treturn pAVIStream->isStreaming();\n}\n\nvoid AudioSourceAVI::streamBegin(bool fRealTime) {\n\tpAVIStream->BeginStreaming(lSampleFirst, lSampleLast, fRealTime ? 1000 : 2000);\n}\n\nvoid AudioSourceAVI::streamEnd() {\n\tpAVIStream->EndStreaming();\n\n}\n\nBOOL AudioSourceAVI::_isKey(LONG lSample) {\n\treturn pAVIStream->IsKeyFrame(lSample);\n}\nint AudioSourceAVI::_read(LONG lStart, LONG lCount, LPVOID lpBuffer, LONG cbBuffer, LONG *lpBytesRead, LONG *lpSamplesRead) {\n\tint err;\n\tlong lBytes, lSamples;\n\n\t// There are some video clips roaming around with truncated audio streams\n\t// (audio streams that state their length as being longer than they\n\t// really are).  We use a kludge here to get around the problem.\n\n\terr = pAVIStream->Read(lStart, lCount, lpBuffer, cbBuffer, lpBytesRead, lpSamplesRead);\n\n\tif (err != AVIERR_FILEREAD)\n\t\treturn err;\n\n\t// Suspect a truncated stream.\n\t//\n\t// AVISTREAMREAD_CONVENIENT will tell us if we're actually encountering a\n\t// true read error or not.  At least for the AVI handler, it returns\n\t// AVIERR_ERROR if we've broached the end.\n\n\t*lpBytesRead = *lpSamplesRead = 0;\n\n\twhile(lCount > 0) {\n\t\terr = pAVIStream->Read(lStart, AVISTREAMREAD_CONVENIENT, NULL, 0, &lBytes, &lSamples);\n\n\t\tif (err)\n\t\t\treturn 0;\n\n\t\tif (!lSamples) return AVIERR_OK;\n\n\t\tif (lSamples > lCount) lSamples = lCount;\n\n\t\terr = pAVIStream->Read(lStart, lSamples, lpBuffer, cbBuffer, &lBytes, &lSamples);\n\n\t\tif (err)\n\t\t\treturn err;\n\n\t\tlpBuffer = (LPVOID)((char *)lpBuffer + lBytes);\n\t\tcbBuffer -= lBytes;\n\t\tlCount -= lSamples;\n\n\t\t*lpBytesRead += lBytes;\n\t\t*lpSamplesRead += lSamples;\n\t}\n\n\treturn AVIERR_OK;\n}\n"
  },
  {
    "path": "avs_core/filters/AviSource/AudioSource.h",
    "content": "//\tVirtualDub - Video processing and capture application\n//\tCopyright (C) 1998-2001 Avery Lee\n//\n//\tThis program is free software; you can redistribute it and/or modify\n//\tit under the terms of the GNU General Public License as published by\n//\tthe Free Software Foundation; either version 2 of the License, or\n//\t(at your option) any later version.\n//\n//\tThis program is distributed in the hope that it will be useful,\n//\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n//\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//\tGNU General Public License for more details.\n//\n//\tYou should have received a copy of the GNU General Public License\n//\talong with this program; if not, write to the Free Software\n//\tFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n#ifndef f_AUDIOSOURCE_H\n#define f_AUDIOSOURCE_H\n\n#include \"DubSource.h\"\n\nclass IAVIReadHandler;\nclass IAVIReadStream;\n\nclass AudioSource : public DubSource {\npublic:\n\tWAVEFORMATEX *getWaveFormat() {\n\t\treturn (WAVEFORMATEX *)getFormat();\n\t}\n};\n\nclass AudioSourceWAV : public AudioSource {\nprivate:\n\tHMMIO\t\t\t\thmmioFile;\n\tMMCKINFO\t\t\tchunkRIFF;\n\tMMCKINFO\t\t\tchunkDATA;\n\tLONG\t\t\t\tlCurrentSample;\n\tLONG\t\t\t\tbytesPerSample;\n\npublic:\n\tAudioSourceWAV(char *fn, LONG inputBufferSize);\n\t~AudioSourceWAV();\n\n\tBOOL init();\n\tvirtual int _read(LONG lStart, LONG lCount, LPVOID lpBuffer, LONG cbBuffer, LONG *lSamplesRead, LONG *lBytesRead);\n};\n\nclass AudioSourceAVI : public AudioSource {\nprivate:\n\tIAVIReadHandler *pAVIFile;\n\tIAVIReadStream *pAVIStream;\n\tbool bQuiet;\n\tint audiotrack;\n\n\tBOOL _isKey(LONG lSample);\n\npublic:\n\tAudioSourceAVI(IAVIReadHandler *pAVIFile, bool bAutomated, int atrack);\n\t~AudioSourceAVI();\n\n\tvoid Reinit();\n\tbool isStreaming();\n\n\tvoid streamBegin(bool fRealTime);\n\tvoid streamEnd();\n\n\tBOOL init();\n\tint _read(LONG lStart, LONG lCount, LPVOID lpBuffer, LONG cbBuffer, LONG *lSamplesRead, LONG *lBytesRead);\n};\n\n#endif\n"
  },
  {
    "path": "avs_core/filters/AviSource/DubSource.cpp",
    "content": "//\tVirtualDub - Video processing and capture application\n//\tCopyright (C) 1998-2001 Avery Lee\n//\n//\tThis program is free software; you can redistribute it and/or modify\n//\tit under the terms of the GNU General Public License as published by\n//\tthe Free Software Foundation; either version 2 of the License, or\n//\t(at your option) any later version.\n//\n//\tThis program is distributed in the hope that it will be useful,\n//\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n//\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//\tGNU General Public License for more details.\n//\n//\tYou should have received a copy of the GNU General Public License\n//\talong with this program; if not, write to the Free Software\n//\tFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n#include \"DubSource.h\"\n\nDubSource::DubSource() {\n\tformat = NULL;\n}\n\nDubSource::~DubSource() {\n\tdelete [] format;\n}\n\nBOOL DubSource::init() {\n\treturn TRUE;\n}\n\nvoid *DubSource::allocFormat(int format_len) {\n\tdelete [] format;\n\n  this->format_len = format_len;\n\treturn format = new char[format_len];\n}\n\nbool DubSource::isStreaming() {\n\treturn false;\n}\n\nint DubSource::read(LONG lStart, LONG lCount, LPVOID lpBuffer, LONG cbBuffer, LONG *lBytesRead, LONG *lSamplesRead) {\n\tif (lStart < lSampleFirst) return AVIERR_BADPARAM;\n\tif (lStart >= lSampleLast) {\n\t\tif (lSamplesRead)\n\t\t\t*lSamplesRead = 0;\n\t\tif (lBytesRead)\n\t\t\t*lBytesRead = 0;\n\t\treturn 0;\n\t}\n\n\tif (lCount>0 && lCount > lSampleLast - lStart) lCount = lSampleLast - lStart;\n\n\treturn _read(lStart, lCount, lpBuffer, cbBuffer, lBytesRead, lSamplesRead);\n}\n\nBOOL DubSource::isKey(LONG lSample) {\n\tif (lSample<lSampleFirst || lSample>=lSampleLast) return TRUE;\n\n\treturn _isKey(lSample);\n}\n\nBOOL DubSource::_isKey(LONG lSample) {\n\treturn TRUE;\n}\n\nLONG DubSource::nearestKey(LONG lSample) {\n\treturn lSample;\n}\n\nLONG DubSource::prevKey(LONG lSample) {\n\treturn lSample <= lSampleFirst ? -1 : lSample-1;\n}\n\nLONG DubSource::nextKey(LONG lSample) {\n\treturn lSample+1 >= lSampleFirst ? -1 : lSample+1;\n}\n\nvoid DubSource::streamBegin(bool fRealTime) {\n}\n\nvoid DubSource::streamEnd() {\n}\n\n"
  },
  {
    "path": "avs_core/filters/AviSource/DubSource.h",
    "content": "//\tVirtualDub - Video processing and capture application\n//\tCopyright (C) 1998-2001 Avery Lee\n//\n//\tThis program is free software; you can redistribute it and/or modify\n//\tit under the terms of the GNU General Public License as published by\n//\tthe Free Software Foundation; either version 2 of the License, or\n//\t(at your option) any later version.\n//\n//\tThis program is distributed in the hope that it will be useful,\n//\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n//\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//\tGNU General Public License for more details.\n//\n//\tYou should have received a copy of the GNU General Public License\n//\talong with this program; if not, write to the Free Software\n//\tFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n#ifndef f_DUBSOURCE_H\n#define f_DUBSOURCE_H\n\n#include <avs/win.h>\n#include <vfw.h>\n\nclass InputFile;\n\nclass DubSource {\nprivate:\n\tchar  *format;\n\tint\t\tformat_len;\n\nprotected:\n\tvoid *allocFormat(int format_len);\n\tvirtual BOOL _isKey(LONG lSample);\n\npublic:\n\tLONG lSampleFirst, lSampleLast;\n\tAVISTREAMINFO\tstreamInfo;\n\n\tDubSource();\n\tvirtual ~DubSource();\n\n\tvirtual BOOL init();\n\tint read(LONG lStart, LONG lCount, LPVOID lpBuffer, LONG cbBuffer, LONG *lBytesRead, LONG *lSamplesRead);\n\tvirtual int _read(LONG lStart, LONG lCount, LPVOID lpBuffer, LONG cbBuffer, LONG *lBytesRead, LONG *lSamplesRead) = 0;\n\n\tvoid *getFormat() const { return format; }\n\tint getFormatLen() const { return format_len; }\n\n\tvirtual bool isStreaming();\n\n\tBOOL isKey(LONG lSample);\n\tvirtual LONG nearestKey(LONG lSample);\n\tvirtual LONG prevKey(LONG lSample);\n\tvirtual LONG nextKey(LONG lSample);\n\n\tvirtual void streamBegin( bool fRealTime);\n\tvirtual void streamEnd();\n\n\tLONG msToSamples(LONG lMs) const {\n\t\treturn (LONG)(((__int64)lMs * streamInfo.dwRate + (__int64)500 * streamInfo.dwScale) / ((__int64)1000 * streamInfo.dwScale));\n\t}\n\tLONG samplesToMs(LONG lSamples) const {\n\t\treturn (LONG)(\n\t\t\t\t(((__int64)lSamples * streamInfo.dwScale) * 1000 + streamInfo.dwRate/2) / streamInfo.dwRate\n\t\t\t);\n\t}\n\n\t// This is more accurate than AVIStreamSampleToSample(), which does a conversion to\n\t// milliseconds and back.\n\n\tstatic LONG samplesToSamples(const AVISTREAMINFO *dest, const AVISTREAMINFO *source, LONG lSamples) {\n\t\t__int64 divisor = (__int64)source->dwRate * dest->dwScale;\n\n\t\treturn (LONG)((((__int64)lSamples * source->dwScale) * dest->dwRate + divisor/2)\n\t\t\t\t/ divisor);\n\t}\n\n\tLONG samplesToSamples(const DubSource *source, LONG lSamples) const {\n\t\treturn samplesToSamples(&streamInfo, &source->streamInfo, lSamples);\n\t}\n};\n\n#endif"
  },
  {
    "path": "avs_core/filters/AviSource/Error.h",
    "content": "// Avisynth v1.0 beta.  Copyright 2000 Ben Rudiak-Gould.\n// http://www.math.berkeley.edu/~benrg/avisynth.html\n\n#ifndef f_ERROR_H\n#define f_ERROR_H\n\n#include <avisynth.h>\n#include <avs/win.h>\n\nstatic inline AvisynthError MyMemoryError() {\n  return AvisynthError(\"Out of memory\");\n}\n\n// the code for these is in AVIReadHandler.cpp\n\nAvisynthError MyError(const char* fmt, ...);\nAvisynthError MyWin32Error(const char *format, DWORD err, ...);\n\n#endif\n"
  },
  {
    "path": "avs_core/filters/AviSource/FastReadStream.cpp",
    "content": "// Packaged with Avisynth v1.0 beta.\n// http://www.math.berkeley.edu/~benrg/avisynth.html\n\n//\tVirtualDub - Video processing and capture application\n//\tCopyright (C) 1998-2000 Avery Lee\n//\n//\tThis program is free software; you can redistribute it and/or modify\n//\tit under the terms of the GNU General Public License as published by\n//\tthe Free Software Foundation; either version 2 of the License, or\n//\t(at your option) any later version.\n//\n//\tThis program is distributed in the hope that it will be useful,\n//\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n//\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//\tGNU General Public License for more details.\n//\n//\tYou should have received a copy of the GNU General Public License\n//\talong with this program; if not, write to the Free Software\n//\tFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n#include <crtdbg.h>\n#include \"FastReadStream.h\"\n\n#include \"Error.h\"\n#include <io.h>\n#include <cstdio>\n#include <cerrno>\n\n\n#pragma warning(disable: 4244)    // conversion from __int64, possible loss of data\n\nclass FastReadStreamHeader {\npublic:\n\t__int64 i64BlockNo;\n\tlong fAccessedBits;\n\tlong lBytes;\n\tlong lAge;\n\tlong lHistoryVal;\n};\n\nFastReadStream::FastReadStream(HANDLE hFile, long lBlockCount, long lBlockSize) {\n\tthis->hFile\t\t\t= hFile;\n\tthis->iFile\t\t\t= -1;\n\n\t_Init(lBlockCount, lBlockSize);\n}\n\nFastReadStream::FastReadStream(int iFile, long lBlockCount, long lBlockSize) {\n\tthis->hFile\t\t\t= INVALID_HANDLE_VALUE;\n\tthis->iFile\t\t\t= iFile;\n\t_Init(lBlockCount, lBlockSize);\n}\n\nvoid FastReadStream::_Init(long lBlockCount, long lBlockSize) {\n\tthis->lBlockCount\t= lBlockCount;\n\tthis->lBlockSize\t= (lBlockSize + 4095) & -4096;\n\tthis->pHeaders\t\t= new FastReadStreamHeader[this->lBlockCount];\n\tthis->pBuffer\t\t= VirtualAlloc(NULL, this->lBlockCount * this->lBlockSize, MEM_COMMIT, PAGE_READWRITE);\n\n\tif (!this->pHeaders || !this->pBuffer) {\n\t\tdelete this->pHeaders;\n\t\tif (this->pBuffer) VirtualFree(this->pBuffer, 0, MEM_RELEASE);\n\n\t\tthis->pHeaders = NULL;\n\t\tthis->pBuffer = NULL;\n\t} else {\n\t\tFlush();\n\t}\n\n\tlHistory\t\t\t= 0;\n}\n\nbool FastReadStream::Ready() {\n\treturn pHeaders && pBuffer;\n}\n\nFastReadStream::~FastReadStream() {\n\tdelete pHeaders;\n\tif (pBuffer) VirtualFree(pBuffer, 0, MEM_RELEASE);\n}\n\n///////////////////////////////////////////////////////////////////////////\n\n// #pragma function(memcpy)\n\nlong FastReadStream::Read(int stream, __int64 i64Pos, void *pDest, long lBytes) {\n\tlong lOffset, lActual = 0, lToCopy;\n\t__int64 i64BlockNo;\n\tchar *pBuffer2 = (char *)pDest;\n\tint iCacheBlock;\n\n\t// First block number and offset...\n\n\ti64BlockNo = i64Pos / lBlockSize;\n\tlOffset = long(i64Pos % lBlockSize);\n\n//\t_RPT3(0,\"Read request: %ld bytes, pos %I64x, first block %I64d\\n\", lBytes, i64Pos, i64BlockNo);\n\n\twhile(lBytes) {\n\t\tlong lInBlock;\n\n\t\tlToCopy = lBlockSize - lOffset;\n\t\tif (lToCopy > lBytes) lToCopy = lBytes;\n\n\t\tiCacheBlock = _Commit(stream, i64BlockNo);\n\t\tlInBlock = pHeaders[iCacheBlock].lBytes - lOffset;\n\n//\t\t_RPT4(0,\"(%ld) Reading %ld from cache block %d, offset %ld\\n\", stream, lToCopy, iCacheBlock, lOffset);\n\n\t\tif (lInBlock < lToCopy) {\n\t\t\tif (lInBlock > 0) {\n\t\t\t\tmemcpy(pBuffer2, (char *)pBuffer + iCacheBlock * lBlockSize + lOffset, lInBlock);\n\n\t\t\t\tlActual += lInBlock;\n\t\t\t}\n\n\t\t\tbreak;\n\t\t} else\n\t\t\tmemcpy(pBuffer2, (char *)pBuffer + iCacheBlock * lBlockSize + lOffset, lToCopy);\n\n\t\tpBuffer2 += lToCopy;\n\t\tlBytes -= lToCopy;\n\t\tlActual += lToCopy;\n\t\t++i64BlockNo;\n\t\tlOffset = 0;\n\t}\n\n\treturn lActual;\n}\n\nvoid FastReadStream::Flush() {\n\tfor(int i=0; i<lBlockCount; i++) {\n\t\tpHeaders[i].i64BlockNo = -1;\n\t\tpHeaders[i].fAccessedBits = 0;\n\t\tpHeaders[i].lHistoryVal = 0;\n\t}\n\n\tlHistory = 0;\n}\n\n///////////////////////////////////////////////////////////////////////////\n\nint FastReadStream::_PickVictim(int stream) {\n\tint i;\n\tlong fStreamEncounteredBits=0, fStreamNotLoneBits=0;\n\tint iOurLowest=-1, iGlobalLowest=-1, iPreferred=-1;\n\tlong fStreamMask = 1L<<stream;\n\n\t// Look for an unused block.\n\n\tfor(i=0; i<lBlockCount; i++)\n\t\tif (pHeaders[i].i64BlockNo == -1)\n\t\t\treturn i;\n\n\t// Compile a list of streams with lone blocks.  These can't be replaced.\n\t// Look for our lone block.\n\n\tfor(i=0; i<lBlockCount; i++) {\n\t\t// Encountered bits -> NotLone bits\n\n\t\tfStreamNotLoneBits |= fStreamEncounteredBits & pHeaders[i].fAccessedBits;\n\t\tfStreamEncounteredBits |= pHeaders[i].fAccessedBits;\n\t}\n\n\t// Look at the histories, and choose a few candidates.\n\n\tfor(i=0; i<lBlockCount; i++) {\n\t\tlong lThisHistory = lHistory - pHeaders[i].lHistoryVal;\n\n\t\tif (lThisHistory<0) lThisHistory = 0x7FFFFFFF;\n\n\t\tpHeaders[i].lAge = lThisHistory;\n\n\t\t// Our oldest block\n\n\t\tif (pHeaders[i].fAccessedBits & fStreamMask)\n\t\t\tif (iOurLowest<0 || lThisHistory > pHeaders[iOurLowest].lAge)\n\t\t\t\tiOurLowest = i;\n\n\t\t// Global oldest block\n\n\t\tif (iGlobalLowest<0 || lThisHistory > pHeaders[iGlobalLowest].lAge)\n\t\t\tiGlobalLowest = i;\n\n\t\t// Preferred lowest block\n\n\t\tif (pHeaders[i].fAccessedBits & fStreamMask\n\t\t\t&& !(pHeaders[i].fAccessedBits & ~fStreamNotLoneBits))\n\t\t\tif (iPreferred<0 || lThisHistory > pHeaders[iPreferred].lAge)\n\t\t\t\tiPreferred = i;\n\t}\n\n\treturn iPreferred>=0 ? iPreferred : iOurLowest>=0 ? iOurLowest : iGlobalLowest;\n}\n\nint FastReadStream::_Commit(int stream, __int64 i64BlockNo) {\n\tint iCacheBlock;\n\tint i;\n\n\t// Already have the block?\n\n\tfor(i=0; i<lBlockCount; i++)\n\t\tif (pHeaders[i].i64BlockNo == i64BlockNo) {\n\t\t\tpHeaders[i].fAccessedBits |= 1L<<stream;\n//\t\t\t_RPT1(0,\"Commit(%I64d): cache hit\\n\", i64BlockNo);\n\t\t\treturn i;\n\t\t}\n\n\t// Pick a replacement candidate.\n\n\tiCacheBlock = _PickVictim(stream);\n\n\t// Replace it.\n\n\ttry {\n\t\t++lHistory;\n\n\t\t_RPT2(0,\"Commit(%I64d): cache miss (stream %d)\\n\", i64BlockNo, stream);\n\t\tif (iFile >= 0) {\n\t\t\tint iActual;\n\n\t\t\tif (-1 == _lseeki64(iFile, i64BlockNo * lBlockSize, SEEK_SET))\n\t\t\t\tthrow MyError(\"FastRead seek error: %s.\", strerror(errno));\n\n\t\t\tiActual = _read(iFile, (char *)pBuffer + iCacheBlock * lBlockSize, lBlockSize);\n\n\t\t\tif (iActual < 0)\n\t\t\t\tthrow MyError(\"FastRead read error: %s.\", strerror(errno));\n\n\t\t\tpHeaders[iCacheBlock].lBytes = iActual;\n\n\t\t} else {\n\t\t\tLONG lLow = (LONG)i64BlockNo*lBlockSize;\n\t\t\tLONG lHigh = (LONG)((i64BlockNo*lBlockSize) >> 32);\n\t\t\tDWORD err, dwActual;\n\n\t\t\tif (0xFFFFFFFF == SetFilePointer(hFile, lLow, &lHigh, FILE_BEGIN))\n\t\t\t\tif ((err = GetLastError()) != NO_ERROR)\n\t\t\t\t\tthrow MyWin32Error(\"FastRead seek error: %%s\", GetLastError());\n\n\t\t\tif (!ReadFile(hFile, (char *)pBuffer + iCacheBlock * lBlockSize, lBlockSize, &dwActual, NULL))\n\t\t\t\tthrow MyWin32Error(\"FastRead read error: %%s\", GetLastError());\n\n\t\t\tpHeaders[iCacheBlock].lBytes = dwActual;\n\t\t}\n\t\tpHeaders[iCacheBlock].i64BlockNo = i64BlockNo;\n\t\tpHeaders[iCacheBlock].fAccessedBits = 1L<<stream;\n\t\tpHeaders[iCacheBlock].lHistoryVal = lHistory;\n\t} catch(...) {\n\t\tpHeaders[iCacheBlock].i64BlockNo = -1;\n\t\tpHeaders[iCacheBlock].fAccessedBits = 0;\n\t}\n\n\treturn iCacheBlock;\n}"
  },
  {
    "path": "avs_core/filters/AviSource/FastReadStream.h",
    "content": "// Packaged with Avisynth v1.0 beta.\n// http://www.math.berkeley.edu/~benrg/avisynth.html\n\n//\tVirtualDub - Video processing and capture application\n//\tCopyright (C) 1998-2000 Avery Lee\n//\n//\tThis program is free software; you can redistribute it and/or modify\n//\tit under the terms of the GNU General Public License as published by\n//\tthe Free Software Foundation; either version 2 of the License, or\n//\t(at your option) any later version.\n//\n//\tThis program is distributed in the hope that it will be useful,\n//\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n//\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//\tGNU General Public License for more details.\n//\n//\tYou should have received a copy of the GNU General Public License\n//\talong with this program; if not, write to the Free Software\n//\tFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n#ifndef f_VIRTUALDUB_FASTREADSTREAM_H\n#define f_VIRTUALDUB_FASTREADSTREAM_H\n\n#include <avs/win.h>\n\nclass FastReadStreamHeader;\n\nclass FastReadStream {\npublic:\n\tFastReadStream(HANDLE hFile, long lBlockCount, long lBlockSize);\n\tFastReadStream(int iFile, long lBlockCount, long lBlockSize);\n\tvirtual ~FastReadStream();\n\n\tbool Ready();\n\tlong Read(int stream, __int64 i64Pos, void *pBuffer, long lBytes);\n\tvoid Flush();\n\nprivate:\n\tHANDLE hFile;\n\tint iFile;\n\tlong lBlockCount;\n\tlong lBlockSize;\n\tlong lHistory;\n\n\tFastReadStreamHeader *pHeaders;\n\tvoid *pBuffer;\n\n\tvoid _Init(long lBlockCount, long lBlockSize);\n\tint _PickVictim(int stream);\n\tint _Commit(int stream, __int64 i64BlockNo);\n};\n\n#endif\n"
  },
  {
    "path": "avs_core/filters/AviSource/File64.cpp",
    "content": "// Packaged with Avisynth v1.0 beta.\n// http://www.math.berkeley.edu/~benrg/avisynth.html\n\n//\tVirtualDub - Video processing and capture application\n//\tCopyright (C) 1998-2000 Avery Lee\n//\n//\tThis program is free software; you can redistribute it and/or modify\n//\tit under the terms of the GNU General Public License as published by\n//\tthe Free Software Foundation; either version 2 of the License, or\n//\t(at your option) any later version.\n//\n//\tThis program is distributed in the hope that it will be useful,\n//\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n//\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//\tGNU General Public License for more details.\n//\n//\tYou should have received a copy of the GNU General Public License\n//\talong with this program; if not, write to the Free Software\n//\tFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n#include \"Error.h\"\n\n#include \"File64.h\"\n\n// hack...\n\nextern CRITICAL_SECTION g_diskcs;\n\n////////////\n\nFile64::File64() {\n}\n\nFile64::File64(HANDLE _hFile, HANDLE _hFileUnbuffered)\n: hFile(_hFile), hFileUnbuffered(_hFileUnbuffered)\n{\n\ti64FilePosition = 0;\n}\n\nlong File64::_readFile(void *data, long len) {\n\tDWORD dwActual;\n\n\tif (!ReadFile(hFile, data, len, &dwActual, NULL))\n\t\treturn -1;\n\n\ti64FilePosition += dwActual;\n\n\treturn (long)dwActual;\n}\n\nvoid File64::_readFile2(void *data, long len) {\n\tlong lActual = _readFile(data, len);\n\n\tif (lActual < 0)\n\t\tthrow MyWin32Error(\"Failure reading file: %%s.\",GetLastError());\n\n\tif (lActual != len)\n\t\tthrow MyError(\"Failure reading file: Unexpected end of file\");\n}\n\nbool File64::_readChunkHeader(FOURCC& pfcc, DWORD& pdwLen) {\n\tDWORD dw[2];\n\tlong actual;\n\n\tactual = _readFile(dw, 8);\n\n\tif (actual != 8)\n\t\treturn false;\n\n\tpfcc = dw[0];\n\tpdwLen = dw[1];\n\n\treturn true;\n}\n\nvoid File64::_seekFile(__int64 i64NewPos) {\n\tLONG lHi = (LONG)(i64NewPos>>32);\n\tDWORD dwError;\n\n\tif (0xFFFFFFFF == SetFilePointer(hFile, (LONG)i64NewPos, &lHi, FILE_BEGIN))\n\t\tif ((dwError = GetLastError()) != NO_ERROR)\n\t\t\tthrow MyWin32Error(\"File64: %%s\", dwError);\n\n\ti64FilePosition = i64NewPos;\n}\n\nbool File64::_seekFile2(__int64 i64NewPos) {\n\tLONG lHi = (LONG)(i64NewPos>>32);\n\tDWORD dwError;\n\n//\t_RPT1(0,\"Seeking to %\" PRIu64 \"\\n\", i64NewPos);\n\n\tif (0xFFFFFFFF == SetFilePointer(hFile, (LONG)i64NewPos, &lHi, FILE_BEGIN))\n\t\tif ((dwError = GetLastError()) != NO_ERROR)\n\t\t\treturn false;\n\n\ti64FilePosition = i64NewPos;\n\n\treturn true;\n}\n\nvoid File64::_skipFile(__int64 bytes) {\n\tLONG lHi = (LONG)(bytes>>32);\n\tDWORD dwError;\n\tLONG lNewLow;\n\n\tif (0xFFFFFFFF == (lNewLow = SetFilePointer(hFile, (LONG)bytes, &lHi, FILE_CURRENT)))\n\t\tif ((dwError = GetLastError()) != NO_ERROR)\n\t\t\tthrow MyWin32Error(\"File64: %%s\", dwError);\n\n\ti64FilePosition = (unsigned long)lNewLow | (((__int64)(unsigned long)lHi)<<32);\n}\n\nbool File64::_skipFile2(__int64 bytes) {\n\tLONG lHi = (LONG)(bytes>>32);\n\tDWORD dwError;\n\tLONG lNewLow;\n\n\tif (0xFFFFFFFF == (lNewLow = SetFilePointer(hFile, (LONG)bytes, &lHi, FILE_CURRENT)))\n\t\tif ((dwError = GetLastError()) != NO_ERROR)\n\t\t\treturn false;\n\n\ti64FilePosition = (unsigned long)lNewLow | (((__int64)(unsigned long)lHi)<<32);\n\n\treturn true;\n}\n\nlong File64::_readFileUnbuffered(void *data, long len) {\n\tDWORD dwActual;\n\n\tEnterCriticalSection(&g_diskcs);\n\tif (!ReadFile(hFileUnbuffered, data, len, &dwActual, NULL)) {\n\t\tLeaveCriticalSection(&g_diskcs);\n\t\treturn -1;\n\t}\n\tLeaveCriticalSection(&g_diskcs);\n\n\treturn (long)dwActual;\n}\n\nvoid File64::_seekFileUnbuffered(__int64 i64NewPos) {\n\tLONG lHi = (LONG)(i64NewPos>>32);\n\tDWORD dwError;\n\n\tif (0xFFFFFFFF == SetFilePointer(hFileUnbuffered, (LONG)i64NewPos, &lHi, FILE_BEGIN))\n\t\tif ((dwError = GetLastError()) != NO_ERROR)\n\t\t\tthrow MyWin32Error(\"File64: %%s\", dwError);\n}\n\n__int64 File64::_posFile() {\n\treturn i64FilePosition;\n}\n\n__int64 File64::_sizeFile() {\n\tDWORD dwLow, dwHigh;\n\tDWORD dwError;\n\n\tdwLow = GetFileSize(hFile, &dwHigh);\n\n\tif (dwLow == 0xFFFFFFFF && (dwError = GetLastError()) != NO_ERROR)\n\t\tthrow MyWin32Error(\"Cannot determine file size: %%s\", dwError);\n\n\treturn ((__int64)dwHigh << 32) | (unsigned long)dwLow;\n}\n"
  },
  {
    "path": "avs_core/filters/AviSource/File64.h",
    "content": "// Packaged with Avisynth v1.0 beta.\n// http://www.math.berkeley.edu/~benrg/avisynth.html\n\n//\tVirtualDub - Video processing and capture application\n//\tCopyright (C) 1998-2000 Avery Lee\n//\n//\tThis program is free software; you can redistribute it and/or modify\n//\tit under the terms of the GNU General Public License as published by\n//\tthe Free Software Foundation; either version 2 of the License, or\n//\t(at your option) any later version.\n//\n//\tThis program is distributed in the hope that it will be useful,\n//\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n//\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//\tGNU General Public License for more details.\n//\n//\tYou should have received a copy of the GNU General Public License\n//\talong with this program; if not, write to the Free Software\n//\tFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n#ifndef f_FILE64_H\n#define f_FILE64_H\n\n#include <avs/win.h>\n#include <mmsystem.h>\n\n\nclass File64 {\npublic:\n\tHANDLE hFile, hFileUnbuffered;\n\t__int64 i64FilePosition;\n\n\tFile64();\n\tFile64(HANDLE _hFile, HANDLE _hFileUnbuffered);\n\tlong _readFile(void *data, long len);\n\tvoid _readFile2(void *data, long len);\n\tbool _readChunkHeader(FOURCC& pfcc, DWORD& pdwLen);\n\tvoid _seekFile(__int64 i64NewPos);\n\tbool _seekFile2(__int64 i64NewPos);\n\tvoid _skipFile(__int64 bytes);\n\tbool _skipFile2(__int64 bytes);\n\tlong _readFileUnbuffered(void *data, long len);\n\tvoid _seekFileUnbuffered(__int64 i64NewPos);\n\t__int64 _posFile();\n\t__int64 _sizeFile();\n};\n\n#endif\n"
  },
  {
    "path": "avs_core/filters/AviSource/Fixes.h",
    "content": "// Packaged with Avisynth v1.0 beta.\n// http://www.math.berkeley.edu/~benrg/avisynth.html\n\n//\tVirtualDub - Video processing and capture application\n//\tCopyright (C) 1998-2000 Avery Lee\n//\n//\tThis program is free software; you can redistribute it and/or modify\n//\tit under the terms of the GNU General Public License as published by\n//\tthe Free Software Foundation; either version 2 of the License, or\n//\t(at your option) any later version.\n//\n//\tThis program is distributed in the hope that it will be useful,\n//\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n//\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//\tGNU General Public License for more details.\n//\n//\tYou should have received a copy of the GNU General Public License\n//\talong with this program; if not, write to the Free Software\n//\tFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n#ifndef f_FIXES_H\n#define f_FIXES_H\n\n// Those stupid idiots at Microsoft forgot to change this structure\n// when making the VfW headers for Win32.  The result is that the\n// AVIStreamHeader is correct in 16-bit Windows, but the 32-bit\n// headers define RECT as LONGs instead of SHORTs.  This creates\n// invalid AVI files!!!!\n\ntypedef struct {\n\tSHORT\tleft;\n\tSHORT\ttop;\n\tSHORT\tright;\n\tSHORT\tbottom;\n} RECT16;\n\ntypedef struct {\n    FOURCC\t\tfccType;\n    FOURCC\t\tfccHandler;\n    DWORD\t\tdwFlags;\n    WORD\t\twPriority;\n    WORD\t\twLanguage;\n    DWORD\t\tdwInitialFrames;\n    DWORD\t\tdwScale;\n    DWORD\t\tdwRate;\n    DWORD\t\tdwStart;\n    DWORD\t\tdwLength;\n    DWORD\t\tdwSuggestedBufferSize;\n    DWORD\t\tdwQuality;\n    DWORD\t\tdwSampleSize;\n    RECT16\t\trcFrame;\n} AVIStreamHeader_fixed;\n\n#endif\n"
  },
  {
    "path": "avs_core/filters/AviSource/VD_Audio.cpp",
    "content": "//\tVirtualDub - Video processing and capture application\n//\tCopyright (C) 1998-2001 Avery Lee\n//\n//\tThis program is free software; you can redistribute it and/or modify\n//\tit under the terms of the GNU General Public License as published by\n//\tthe Free Software Foundation; either version 2 of the License, or\n//\t(at your option) any later version.\n//\n//\tThis program is distributed in the hope that it will be useful,\n//\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n//\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//\tGNU General Public License for more details.\n//\n//\tYou should have received a copy of the GNU General Public License\n//\talong with this program; if not, write to the Free Software\n//\tFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n//#include \"VirtualDub.h\"\n\n#include <crtdbg.h>\n#include <cassert>\n#include <limits>\n#include <new>\n\n//#include \"gui.h\"\n//#include \"crash.h\"\n\n#include \"Error.h\"\n#include <avs/minmax.h>\n#include \"AudioSource.h\"\n\n#include \"VD_Audio.h\"\n\n\n#pragma warning(disable: 4706)    // assignment within conditional expression\n\n\nAudioFormatConverter AudioPickConverter(WAVEFORMATEX *src, BOOL to_16bit, BOOL to_stereo);\n\n//////////////// no change converters /////////////////////////////////////\n\nstatic void convert_audio_nochange8(void *dest, void *src, long count) {\n\tmemcpy(dest, src, count);\n}\n\nstatic void convert_audio_nochange16(void *dest, void *src, long count) {\n\tmemcpy(dest, src, count*2);\n}\n\nstatic void convert_audio_nochange32(void *dest, void *src, long count) {\n\tmemcpy(dest, src, count*4);\n}\n\n//////////////// regular converters /////////////////////////////////////\n\nstatic void convert_audio_mono8_to_mono16(void *dest, void *src, long count) {\n\tunsigned char *s = (unsigned char *)src;\n\tsigned short *d = (signed short *)dest;\n\n\tdo {\n\t\t*d++ = (signed short)((unsigned long)(*s++-0x80)<<8);\n\t} while(--count);\n}\n\nstatic void convert_audio_mono8_to_stereo8(void *dest, void *src, long count) {\n\tunsigned char c,*s = (unsigned char *)src;\n\tunsigned char *d = (unsigned char *)dest;\n\n\tdo {\n\t\tc = *s++;\n\t\t*d++ = c;\n\t\t*d++ = c;\n\t} while(--count);\n}\n\nstatic void convert_audio_mono8_to_stereo16(void *dest, void *src, long count) {\n\tunsigned char *s = (unsigned char *)src;\n\tunsigned long c, *d = (unsigned long *)dest;\n\n\tdo {\n\t\tc = ((*s++-0x80)&0xff) << 8;\n\t\t*d++ = c | (c<<16);\n\t} while(--count);\n}\n\nstatic void convert_audio_mono16_to_mono8(void *dest, void *src, long count) {\n\tsigned short *s = (signed short *)src;\n\tunsigned char *d = (unsigned char *)dest;\n\n\tdo {\n\t\t*d++ = (unsigned char)((((unsigned long)*s++)+0x8000)>>8);\n\t} while(--count);\n}\n\nstatic void convert_audio_mono16_to_stereo8(void *dest, void *src, long count) {\n\tsigned short *s = (signed short *)src;\n\tunsigned char c, *d = (unsigned char *)dest;\n\n\tdo {\n\t\tc = (unsigned char)((((unsigned long)*s++)+0x8000)>>8);\n\t\t*d++ = c;\n\t\t*d++ = c;\n\t} while(--count);\n}\n\nstatic void convert_audio_mono16_to_stereo16(void *dest, void *src, long count) {\n\tsigned short *s = (signed short *)src;\n\tunsigned long *d = (unsigned long *)dest, c;\n\n\tdo {\n\t\tc = 0xffff & *s++;\n\t\t*d++ = (c | (c<<16));\n\t} while(--count);\n}\n\nstatic void convert_audio_stereo8_to_mono8(void *dest, void *src, long count) {\n\tunsigned short *s = (unsigned short *)src;\n\tunsigned char *d = (unsigned char *)dest;\n\tunsigned long c;\n\n\tdo {\n\t\tc = *s++;\n\t\t*d++ = (unsigned char)(((c&0xff) + (c>>8))/2);\n\t} while(--count);\n}\n\nstatic void convert_audio_stereo8_to_mono16(void *dest, void *src, long count) {\n\tunsigned short *s = (unsigned short *)src;\n\tsigned short *d = (signed short *)dest;\n\tunsigned long c;\n\n\tdo {\n\t\tc = *s++;\n\t\t*d++ = (signed short)((((c&0xff) + (c>>8))<<7)-0x8000);\n\t} while(--count);\n}\n\nstatic void convert_audio_stereo8_to_stereo16(void *dest, void *src, long count) {\n\tunsigned short c,*s = (unsigned short *)src;\n\tunsigned long *d = (unsigned long *)dest;\n\n\tdo {\n\t\tc = *s++;\n\t\t*d++ = ((unsigned long)((c-0x80)&0xff)<<8) | ((unsigned long)((c&0xff00)-0x8000)<<16);\n\t} while(--count);\n}\n\nstatic void convert_audio_stereo16_to_mono8(void *dest, void *src, long count) {\n\tunsigned long c, *s = (unsigned long *)src;\n\tunsigned char *d = (unsigned char *)dest;\n\n\tdo {\n\t\tc = *s++;\n\t\t*d++ = (unsigned char)(((((c&0xffff)+0xffff8000)^0xffff8000) + ((signed long)c>>16) + 0x10000)>>9);\n\t} while(--count);\n}\n\nstatic void convert_audio_stereo16_to_mono16(void *dest, void *src, long count) {\n\tunsigned long c, *s = (unsigned long *)src;\n\tsigned short *d = (signed short *)dest;\n\n\tdo {\n\t\tc = *s++;\n\t\t*d++ = (signed short)(((((c&0xffff)+0xffff8000)^0xffff8000) + ((signed long)c>>16))/2);\n\t} while(--count);\n}\n\nstatic void convert_audio_stereo16_to_stereo8(void *dest, void *src, long count) {\n\tunsigned long c,*s = (unsigned long *)src;\n\tunsigned char *d = (unsigned char *)dest;\n\n\tdo {\n\t\tc = *s++;\n\t\t*d++ = (unsigned char)((((unsigned long)(c & 0xffff))+0x8000)>>8);\n\t\t*d++ = (unsigned char)((((unsigned long)(c>>16))+0x8000)>>8);\n\t} while(--count);\n}\n\nstatic void convert_audio_dual8_to_mono8(void *dest, void *src, long count) {\n\tconst unsigned char *s = (unsigned char *)src;\n\tunsigned char *d = (unsigned char *)dest;\n\n\tdo {\n\t\t*d++ = *s;\n\t\ts+=2;\n\t} while(--count);\n}\n\nstatic void convert_audio_dual8_to_mono16(void *dest, void *src, long count) {\n\tunsigned char *s = (unsigned char *)src;\n\tsigned short *d = (signed short *)dest;\n\n\tdo {\n\t\t*d++ = (signed short)((unsigned long)(*s-0x80)<<8);\n\t\ts += 2;\n\t} while(--count);\n}\n\nstatic void convert_audio_dual16_to_mono8(void *dest, void *src, long count) {\n\tsigned short *s = (signed short *)src;\n\tunsigned char *d = (unsigned char *)dest;\n\n\tdo {\n\t\t*d++ = (unsigned char)((((unsigned long)*s)+0x8000)>>8);\n\t\ts += 2;\n\t} while(--count);\n}\n\nstatic void convert_audio_dual16_to_mono16(void *dest, void *src, long count) {\n\tconst signed short *s = (signed short *)src;\n\tsigned short *d = (signed short *)dest;\n\n\tdo {\n\t\t*d++ = *s;\n\t\ts+=2;\n\t} while(--count);\n}\n\n////////////////////////////////////////////\n\nstatic const AudioFormatConverter acv[]={\n\tconvert_audio_nochange8,\n\tconvert_audio_mono8_to_mono16,\n\tconvert_audio_mono8_to_stereo8,\n\tconvert_audio_mono8_to_stereo16,\n\tconvert_audio_mono16_to_mono8,\n\tconvert_audio_nochange16,\n\tconvert_audio_mono16_to_stereo8,\n\tconvert_audio_mono16_to_stereo16,\n\tconvert_audio_stereo8_to_mono8,\n\tconvert_audio_stereo8_to_mono16,\n\tconvert_audio_nochange16,\n\tconvert_audio_stereo8_to_stereo16,\n\tconvert_audio_stereo16_to_mono8,\n\tconvert_audio_stereo16_to_mono16,\n\tconvert_audio_stereo16_to_stereo8,\n\tconvert_audio_nochange32,\n};\n\nstatic const AudioFormatConverter acv2[]={\n\tconvert_audio_nochange8,\n\tconvert_audio_mono8_to_mono16,\n\tconvert_audio_mono16_to_mono8,\n\tconvert_audio_nochange16,\n\tconvert_audio_dual8_to_mono8,\n\tconvert_audio_dual8_to_mono16,\n\tconvert_audio_dual16_to_mono8,\n\tconvert_audio_dual16_to_mono16,\n};\n\nAudioFormatConverter AudioPickConverter(WAVEFORMATEX *src, BOOL to_16bit, BOOL to_stereo) {\n\treturn acv[\n\t\t\t  (src->nChannels>1 ? 8 : 0)\n\t\t\t +(src->wBitsPerSample>8 ? 4 : 0)\n\t\t\t +(to_stereo ? 2 : 0)\n\t\t\t +(to_16bit ? 1 : 0)\n\t\t];\n}\n\nAudioFormatConverter AudioPickConverterSingleChannel(WAVEFORMATEX *src, bool to_16bit) {\n\treturn acv2[\n\t\t\t  (src->nChannels>1 ? 4 : 0)\n\t\t\t +(src->wBitsPerSample>8 ? 2 : 0)\n\t\t\t +(to_16bit ? 1 : 0)\n\t\t];\n}\n\n///////////////////////////////////\n\nAudioStream::AudioStream() {\n\tformat = NULL;\n\tformat_len = 0;\n\tsamples_read = 0;\n\tstream_limit = 0x7FFFFFFF;\n}\n\nAudioStream::~AudioStream() {\n\tfree(format);\n}\n\nWAVEFORMATEX *AudioStream::AllocFormat(long len) {\n\tif (format) { free(format); format = 0; }\n\n\tif (!(format = (WAVEFORMATEX *)malloc(len)))\n\t\tthrow MyError(\"AudioStream: Out of memory\");\n\n    format_len = len;\n\n\treturn format;\n}\n\nWAVEFORMATEX *AudioStream::GetFormat() {\n\treturn format;\n}\n\nlong AudioStream::GetFormatLen() {\n\treturn format_len;\n}\n\nlong AudioStream::GetSampleCount() {\n\treturn samples_read;\n}\n\nlong AudioStream::GetLength() {\n\treturn stream_limit < stream_len ? stream_limit : stream_len;\n}\n\nlong AudioStream::Read(void *buffer, long max_samples, long *lplBytes) {\n\tlong actual;\n\n\tif (max_samples <= 0) {\n\t\t*lplBytes = 0;\n\t\treturn 0;\n\t}\n\n\tif (samples_read >= stream_limit) {\n\t\t*lplBytes = 0;\n\t\treturn 0;\n\t}\n\n    if (samples_read + max_samples > stream_limit)\n\t\tmax_samples = stream_limit - samples_read;\n\n\tactual = _Read(buffer, max_samples, lplBytes);\n\n\t_ASSERT(actual >= 0 && actual <= max_samples);\n\n\tsamples_read += actual;\n\n\treturn actual;\n}\n\nbool AudioStream::Skip(long samples) {\n\treturn false;\n}\n\nvoid AudioStream::SetLimit(long limit) {\n\t_RPT1(0,\"AudioStream: limit set to %ld\\n\",limit);\n\tstream_limit = limit;\n}\n\nvoid AudioStream::SetSource(AudioStream *src) {\n\tsource = src;\n\tstream_len = src->GetLength();\n}\n\nBOOL AudioStream::isEnd() {\n\treturn samples_read >= stream_limit || _isEnd();\n}\n\nlong AudioStream::_Read(void *buffer, long max_samples, long *lplBytes) {\n\t*lplBytes = 0;\n\n\treturn 0;\n}\n\nBOOL AudioStream::_isEnd() {\n\treturn FALSE;\n}\n\n////////////////////\n\nAudioStreamSource::AudioStreamSource(AudioSource *src, long first_samp, long max_samples, BOOL allow_decompression) : AudioStream() {\n\tWAVEFORMATEX *iFormat = src->getWaveFormat();\n\tWAVEFORMATEX *oFormat;\n\tWAVEFORMATEX  tFormat;\n\tMMRESULT res = 0;\n\n\thACStream = NULL;\n\tinputBuffer = outputBuffer = NULL;\n\tfZeroRead = false;\n\tfStart = true;\n\tpwfexTempInput = NULL;\n\tlPreskip = 0;\n\n\tif (max_samples < 0)\n\t\tmax_samples = 0;\n\n    // Undo any Wave Format Extensible back to standard Wave FormatEx\n\tif (iFormat->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&\n\t    iFormat->cbSize == sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX))\n    {\n      memcpy(&tFormat, iFormat, sizeof(WAVEFORMATEX));\n      tFormat.cbSize = 0;\n      tFormat.wFormatTag = (WORD)((WAVEFORMATEXTENSIBLE*)iFormat)->SubFormat.Data1;\n      iFormat = &tFormat;\n\t}\n\n\tif (iFormat->wFormatTag != WAVE_FORMAT_PCM &&\n\t\tiFormat->wFormatTag != WAVE_FORMAT_IEEE_FLOAT && allow_decompression) {\n\t\tDWORD dwOutputBufferSize;\n\t\tDWORD dwOutputFormatSize;\n\t\tDWORD dwSuggest=0;\n\t\tint i;\n\n\t\tif (!AllocFormat(sizeof(WAVEFORMATEX)))\n\t\t\tthrow MyMemoryError();\n\n\t\tif (acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FORMAT, (LPVOID)&dwOutputFormatSize))\n\t\t\tthrow MyError(\"Couldn't get ACM's max format size\");\n\n\t\toFormat = (WAVEFORMATEX *)malloc(dwOutputFormatSize); //AllocFormat(dwOutputFormatSize);\n\t\tif (!oFormat) throw MyMemoryError();\n\n#define MAX_TRIES 10\n\t\tfor (i=0; i<=MAX_TRIES; i++) {\n\t\t\tswitch (i) {\n\t\t\tcase 0: oFormat->wFormatTag = WAVE_FORMAT_IEEE_FLOAT;\n\t\t\t\t\toFormat->nChannels = iFormat->nChannels;\n\t\t\t\t\toFormat->nSamplesPerSec = iFormat->nSamplesPerSec;\n\t\t\t\t\tdwSuggest = ACM_FORMATSUGGESTF_WFORMATTAG | ACM_FORMATSUGGESTF_NCHANNELS |\n\t\t\t\t\t\tACM_FORMATSUGGESTF_NSAMPLESPERSEC;\n\t\t\t\t\tbreak;\n\t\t\tcase 1: oFormat->nSamplesPerSec = 0;\n\t\t\t\t\tdwSuggest = ACM_FORMATSUGGESTF_WFORMATTAG | ACM_FORMATSUGGESTF_NCHANNELS;\n\t\t\t\t\tbreak;\n\t\t\tcase 2: oFormat->nChannels = 0;\n\t\t\t\t\tdwSuggest = ACM_FORMATSUGGESTF_WFORMATTAG;\n\t\t\t\t\tbreak;\n\t\t\tcase 3: oFormat->wFormatTag = WAVE_FORMAT_PCM;\n\t\t\t\t\toFormat->nChannels = iFormat->nChannels;\n\t\t\t\t\toFormat->wBitsPerSample = 32;\n\t\t\t\t\toFormat->nSamplesPerSec = iFormat->nSamplesPerSec;\n\t\t\t\t\tdwSuggest = ACM_FORMATSUGGESTF_WFORMATTAG | ACM_FORMATSUGGESTF_NCHANNELS |\n\t\t\t\t\t\tACM_FORMATSUGGESTF_WBITSPERSAMPLE | ACM_FORMATSUGGESTF_NSAMPLESPERSEC;\n\t\t\t\t\tbreak;\n\t\t\tcase 4: oFormat->nSamplesPerSec = 0;\n\t\t\t\t\tdwSuggest = ACM_FORMATSUGGESTF_WFORMATTAG | ACM_FORMATSUGGESTF_NCHANNELS |\n\t\t\t\t\t\tACM_FORMATSUGGESTF_WBITSPERSAMPLE;\n\t\t\t\t\tbreak;\n\t\t\tcase 5: oFormat->wBitsPerSample = 24;\n\t\t\t\t\tbreak;\n\t\t\tcase 6: oFormat->wBitsPerSample = 0;\n\t\t\t\t\tdwSuggest = ACM_FORMATSUGGESTF_WFORMATTAG | ACM_FORMATSUGGESTF_NCHANNELS;\n\t\t\t\t\tbreak;\n\t\t\tcase 7: oFormat->nChannels = 0;\n\t\t\t\t\toFormat->wBitsPerSample = 32;\n\t\t\t\t\tdwSuggest = ACM_FORMATSUGGESTF_WFORMATTAG | ACM_FORMATSUGGESTF_WBITSPERSAMPLE;\n\t\t\t\t\tbreak;\n\t\t\tcase 8: oFormat->wBitsPerSample = 24;\n\t\t\t\t\tbreak;\n\t\t\tcase 9: oFormat->wBitsPerSample = 0;\n\t\t\t\t\tdwSuggest = ACM_FORMATSUGGESTF_WFORMATTAG;\n\t\t\t\t\tbreak;\n\t\t\t\t\t// Hack to get Fraunhoffer MP3 codec to accept data when wBitsPerSample==16\n\t\t\tcase 10: if(iFormat->wFormatTag == 0x0055 && iFormat->wBitsPerSample != 0) {\n\t\t\t\t\t\tiFormat->wBitsPerSample = 0;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (acmFormatSuggest(NULL, iFormat, oFormat, dwOutputFormatSize, dwSuggest)) continue;\n\n\t\t\tif (oFormat->wBitsPerSample!=8  && oFormat->wBitsPerSample!=16 &&\n\t\t\t\toFormat->wBitsPerSample!=24 && oFormat->wBitsPerSample!=32)\n\t\t\t\t\toFormat->wBitsPerSample=16;\n\n\t\t\tif (oFormat->nChannels==0)\n\t\t\t\toFormat->nChannels = 2;\n\n\t\t\toFormat->nBlockAlign\t\t= (oFormat->wBitsPerSample/8) * oFormat->nChannels;\n\t\t\toFormat->nAvgBytesPerSec\t= oFormat->nBlockAlign * oFormat->nSamplesPerSec;\n\t\t\toFormat->cbSize\t\t\t\t= 0;\n\n\n\t\t\tif (!(res = acmStreamOpen(&hACStream, NULL, iFormat, oFormat, NULL, 0, 0, ACM_STREAMOPENF_NONREALTIME)))\n\t\t\t\tbreak;\n\t\t}\n\t\tif (res) {\n\t\t\tfree(oFormat);\n\t\t\tif (res == ACMERR_NOTPOSSIBLE) {\n\t\t\t\tthrow MyError(\n\t\t\t\t\t\t\t\"Error initializing audio stream decompression:\\n\"\n\t\t\t\t\t\t\t\"The requested conversion is not possible.\\n\"\n\t\t\t\t\t\t\t\"\\n\"\n\t\t\t\t\t\t\t\"Check to make sure you have the required codec%s.\"\n\t\t\t\t\t\t\t,\n\t\t\t\t\t\t\t(iFormat->wFormatTag&~1)==0x160 ? \" (Microsoft Audio Codec)\" : \"\"\n\t\t\t\t\t\t);\n\t\t\t} else\n\t\t\t\tthrow MyError(\"Error initializing audio stream decompression.\");\n\t\t}\n\t\tif (i > MAX_TRIES) {\n\t\t\tfree(oFormat);\n\t\t\tthrow MyError(\"No compatible ACM codec to decode 0x%04X audio stream to PCM.\", iFormat->wFormatTag);\n\t\t}\n\n\t\tmemcpy(GetFormat(), oFormat, sizeof(WAVEFORMATEX));\n\t\tfree(oFormat);\n\n\t\tif (acmStreamSize(hACStream, INPUT_BUFFER_SIZE, &dwOutputBufferSize, ACM_STREAMSIZEF_SOURCE))\n\t\t\tthrow MyError(\"Error initializing audio stream output size.\");\n\n\t\tif (!(inputBuffer = malloc(INPUT_BUFFER_SIZE))\n\t\t\t|| !(outputBuffer = malloc(dwOutputBufferSize)))\n\n\t\t\tthrow MyMemoryError();\n\n\t\tmemset(&ashBuffer, 0, sizeof ashBuffer);\n\t\tashBuffer.cbStruct\t\t= sizeof(ACMSTREAMHEADER);\n\t\tashBuffer.pbSrc\t\t\t= (LPBYTE)inputBuffer;\n\t\tashBuffer.cbSrcLength\t= INPUT_BUFFER_SIZE;\n\t\tashBuffer.pbDst\t\t\t= (LPBYTE)outputBuffer;\n\t\tashBuffer.cbDstLength\t= dwOutputBufferSize;\n\n\t\tif (acmStreamPrepareHeader(hACStream, &ashBuffer, 0))\n\t\t\tthrow MyError(\"Error preparing audio decompression buffers.\");\n\n\t\tashBuffer.cbSrcLength = 0;\n\t\tashBuffer.cbDstLengthUsed = 0;\n\t} else {\n\n\t\t// FIX: If we have a PCMWAVEFORMAT stream, artificially cut the format size\n\t\t//\t\tto sizeof(PCMWAVEFORMAT).  LSX-MPEG Encoder doesn't like large PCM\n\t\t//\t\tformats!\n\n\t\tif (iFormat->wFormatTag == WAVE_FORMAT_PCM) {\n\t\t\toFormat = AllocFormat(sizeof(PCMWAVEFORMAT));\n\t\t\tmemcpy(oFormat, iFormat, sizeof(PCMWAVEFORMAT));\n\t\t} else {\n\t\t\toFormat = AllocFormat(src->getFormatLen());\n\t\t\tmemcpy(oFormat, iFormat, GetFormatLen());\n\t\t}\n\t}\n\n\taSrc = src;\n\tstream_len = min(max_samples, aSrc->lSampleLast - first_samp);\n\n\tif (hACStream) {\n\t\tstream_len = MulDiv(stream_len, GetFormat()->nSamplesPerSec * aSrc->getWaveFormat()->nBlockAlign, aSrc->getWaveFormat()->nAvgBytesPerSec);\n\t}\n\n\tcur_samp = first_samp;\n\tend_samp = first_samp + max_samples;\n\n}\n\nAudioStreamSource::~AudioStreamSource() {\n\tif (hACStream) {\n\t\tif (ashBuffer.fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED) {\n\t\t\tashBuffer.cbSrcLength = INPUT_BUFFER_SIZE;\n\t\t\tacmStreamUnprepareHeader(hACStream, &ashBuffer, 0);\n\t\t}\n\t\tacmStreamClose(hACStream, 0);\n\t}\n\tif (inputBuffer)\tfree(inputBuffer);\n\tif (outputBuffer)\tfree(outputBuffer);\n\tdelete[] pwfexTempInput;\n}\n\nlong AudioStreamSource::_Read(void *buffer, long max_samples, long *lplBytes) {\n\tLONG lSamples=0;\n\tLONG lAddedBytes=0;\n\tLONG lAddedSamples=0;\n\tint err;\n\tMMRESULT res;\n\n\t// add filler samples as necessary\n\n\tif (cur_samp < 0) {\n\t\tlong tc = -cur_samp;\n\t\tconst int nBlockAlign = aSrc->getWaveFormat()->nBlockAlign;\n\n\t\tif (tc > max_samples)\n\t\t\ttc = max_samples;\n\n\t\tif (GetFormat()->nChannels > 1)\n\t\t\tmemset(buffer, 0, nBlockAlign*tc);\n\t\telse\n\t\t\tmemset(buffer, 0x80, nBlockAlign*tc);\n\n\t\tbuffer = (char *)buffer + nBlockAlign*tc;\n\n\t\tmax_samples -= tc;\n\t\tlAddedBytes = tc*nBlockAlign;\n\t\tlAddedSamples = tc;\n\t\tcur_samp += tc;\n\t}\n\n\t// read actual samples\n\n\tif (hACStream) {\n\t\tLONG ltActualBytes, ltActualSamples;\n\t\tLONG lBytesLeft = max_samples * GetFormat()->nBlockAlign;\n\t\tLONG lTotalBytes = lBytesLeft;\n\t\tconst int nBlockAlign = aSrc->getWaveFormat()->nBlockAlign;\n\n\t\twhile(lBytesLeft > 0) {\n\t\t\t// hmm... data still in the output buffer?\n\n\t\t\tif (ashBuffer.cbDstLengthUsed>0) {\n\t\t\t\tlong tc = min(lBytesLeft, long(ashBuffer.cbDstLengthUsed));\n\n\n\t\t\t\tif (lPreskip) {\n\t\t\t\t\tif (tc > lPreskip)\n\t\t\t\t\t\ttc = lPreskip;\n\n\t\t\t\t\tlPreskip -= tc;\n\t\t\t\t} else {\n\t\t\t\t\tmemcpy(buffer, outputBufferPtr, tc);\n\t\t\t\t\tbuffer = (void *)((char *)buffer + tc);\n\t\t\t\t\tlBytesLeft -= tc;\n\t\t\t\t}\n\n\t\t\t\toutputBufferPtr += tc;\n\t\t\t\tashBuffer.cbDstLengthUsed -= tc;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// fill the input buffer up... if we haven't gotten a zero yet.\n\n\t\t\tif (ashBuffer.cbSrcLength < INPUT_BUFFER_SIZE && !fZeroRead) {\n\t\t\t\tLONG lBytes=0;\n\n\t\t\t\tdo {\n\t\t\t\t\tLONG to_read = (INPUT_BUFFER_SIZE - ashBuffer.cbSrcLength)/nBlockAlign;\n\n\t\t\t\t\tif (to_read > end_samp - cur_samp)\n\t\t\t\t\t\tto_read = end_samp - cur_samp;\n\n\t\t\t\t\terr = aSrc->read(cur_samp, to_read, (char *)inputBuffer + ashBuffer.cbSrcLength, INPUT_BUFFER_SIZE - ashBuffer.cbSrcLength, &ltActualBytes, &ltActualSamples);\n\n\t\t\t\t\tif (err != AVIERR_OK && err != AVIERR_BUFFERTOOSMALL) {\n\t\t\t\t\t\tif (err == AVIERR_FILEREAD)\n\t\t\t\t\t\t\tthrow MyError(\"Audio samples %lu-%lu could not be read in the source.  The file may be corrupted.\", cur_samp, cur_samp+to_read-1);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tthrow MyWin32Error(\"AudioStreamSource\", err);\n\t\t\t\t\t}\n\n\t\t\t\t\tcur_samp += ltActualSamples;\n\n//\t\t\t\t\t_RPT1(0,\"Read to %ld\\n\", cur_samp);\n\n\t\t\t\t\tashBuffer.cbSrcLength += ltActualBytes;\n\n\t\t\t\t\tlBytes += ltActualBytes;\n\n\t\t\t\t} while(err != AVIERR_BUFFERTOOSMALL && ashBuffer.cbSrcLength < INPUT_BUFFER_SIZE && ltActualBytes && cur_samp < end_samp);\n\n\t\t\t\tif (!lBytes) fZeroRead = true;\n\t\t\t}\n\n\t\t\t// ask ACM to convert for us\n\n\t\t\tashBuffer.cbSrcLengthUsed = 0;\n\t\t\tashBuffer.cbDstLengthUsed = 0;\n\n//\tVDCHECKPOINT;\n      if (ashBuffer.cbSrcLength) {\n        res = acmStreamConvert(hACStream, &ashBuffer, (fStart ? ACM_STREAMCONVERTF_START : 0) | ACM_STREAMCONVERTF_BLOCKALIGN);\n        if (res)\n          throw MyError(\"ACM reported error on audio decompress (%lx)\", res);\n      }\n//\tVDCHECKPOINT;\n\n\t\t\tfStart = false;\n\n\t\t\t_RPT2(0,\"Converted %ld bytes to %ld\\n\", ashBuffer.cbSrcLengthUsed, ashBuffer.cbDstLengthUsed);\n\n\t\t\tif (!ashBuffer.cbSrcLengthUsed && fZeroRead)\n\t\t\t\tbreak;\n\n\t\t\t// if ACM didn't use all the source data, copy the remainder down\n\n\t\t\tif (ashBuffer.cbSrcLengthUsed < ashBuffer.cbSrcLength) {\n\t\t\t\tlong left = ashBuffer.cbSrcLength - ashBuffer.cbSrcLengthUsed;\n\n\t\t\t\tmemmove(inputBuffer, (char *)inputBuffer + ashBuffer.cbSrcLengthUsed, left);\n\n\t\t\t\tashBuffer.cbSrcLength = left;\n\t\t\t} else\n\t\t\t\tashBuffer.cbSrcLength = 0;\n\n\t\t\toutputBufferPtr = (char *)outputBuffer;\n\t\t};\n\n\t\t*lplBytes = (lTotalBytes - lBytesLeft) + lAddedBytes;\n\n\t\treturn *lplBytes / GetFormat()->nBlockAlign + lAddedSamples;\n\t} else {\n\t\tif (max_samples > end_samp - cur_samp)\n\t\t\tmax_samples = end_samp - cur_samp;\n\n\t\tif (max_samples) {\n\t\t\tif (AVIERR_OK != (err = aSrc->read(cur_samp, max_samples, buffer, 0x7FFFFFFFL, lplBytes, &lSamples))) {\n\t\t\t\tif (err == AVIERR_FILEREAD)\n\t\t\t\t\tthrow MyError(\"Audio samples %lu-%lu could not be read in the source.  The file may be corrupted.\", cur_samp, cur_samp+max_samples-1);\n\t\t\t\telse\n\t\t\t\t\tthrow MyWin32Error(\"AudioStreamSource\", err);\n\t\t\t}\n\n\t\t} else\n\t\t\tlSamples = *lplBytes = 0;\n\n\t\t*lplBytes += lAddedBytes;\n\n\t\tcur_samp += lSamples;\n\n\t\treturn lSamples + lAddedSamples;\n\t}\n}\n\nbool AudioStreamSource::Skip(long samples) {\n\n\t// nBlockAlign = bytes per block.\n\t//\n\t// nAvgBytesPerSec / nBlockAlign = blocks per second.\n\t// nSamplesPerSec * nBlockAlign / nAvgBytesPerSec = samples per block.\n\n\tif (hACStream) {\n\t\tconst WAVEFORMATEX *pwfex = aSrc->getWaveFormat();\n\n\t\tif (samples < MulDiv(4*pwfex->nBlockAlign, pwfex->nSamplesPerSec, pwfex->nAvgBytesPerSec)) {\n\t\t\tlPreskip += samples*GetFormat()->nBlockAlign;\n\t\t\treturn true;\n\t\t}\n\n\t\t// Flush input and output buffers.\n\n\t\tashBuffer.cbSrcLength = 0;\n\t\tashBuffer.cbDstLengthUsed = 0;\n\n\t\t// Trigger a reseek.\n\n\t\tlong new_pos = long(((samples_read + samples) * (__int64)pwfex->nAvgBytesPerSec) / ((__int64)pwfex->nBlockAlign*pwfex->nSamplesPerSec));\n\n\t\tif (new_pos > cur_samp)\n\t\t\tcur_samp = new_pos;\n\n\t\tfStart = true;\n\n\t\t// Skip fractional samples.\n\n\t\tlong samp_start = long((new_pos * (__int64)pwfex->nSamplesPerSec*pwfex->nBlockAlign) / pwfex->nAvgBytesPerSec);\n\n\t\tlPreskip = ((samples_read + samples) - samp_start)*GetFormat()->nBlockAlign;\n\n\t\tsamples_read = samp_start;\n\n\t\treturn true;\n\n\t} else {\n\t\tcur_samp += samples;\n\t\tsamples_read += samples;\n\n\t\treturn true;\n\t}\n}\n\nbool AudioStreamSource::Seek(long samples) {\n\n\t// nBlockAlign = bytes per block.\n\t//\n\t// nAvgBytesPerSec / nBlockAlign = blocks per second.\n\t// nSamplesPerSec * nBlockAlign / nAvgBytesPerSec = samples per block.\n\n\tif (samples < end_samp)\n\t\tfZeroRead = false;\n\n\tif (hACStream) {\n\t\tconst WAVEFORMATEX *pwfex = aSrc->getWaveFormat();\n\n\t\tif (samples > samples_read && samples - samples_read < MulDiv(4*pwfex->nBlockAlign, pwfex->nSamplesPerSec, pwfex->nAvgBytesPerSec)) {\n\t\t\tlPreskip += (samples - samples_read)*GetFormat()->nBlockAlign;\n\t\t\treturn true;\n\t\t}\n\n\t\t// Flush input and output buffers.\n\n\t\tashBuffer.cbSrcLength = 0;\n\t\tashBuffer.cbDstLengthUsed = 0;\n\n\t\t// Trigger a reseek.\n\n\t\tlong new_pos = long((samples * (__int64)pwfex->nAvgBytesPerSec) / ((__int64)pwfex->nBlockAlign*pwfex->nSamplesPerSec));\n\n\t\tcur_samp = new_pos;\n\n\t\tfStart = true;\n\n\t\t// Skip fractional samples.\n\n\t\tlong samp_start = long((new_pos * (__int64)pwfex->nSamplesPerSec*pwfex->nBlockAlign) / pwfex->nAvgBytesPerSec);\n\n\t\tlPreskip = (samples - samp_start)*GetFormat()->nBlockAlign;\n\n\t\tsamples_read = samp_start;\n\n\t\treturn true;\n\n\t} else {\n\t\tcur_samp = samples;\n\t\tsamples_read = samples;\n\n\t\treturn true;\n\t}\n}\n\nBOOL AudioStreamSource::_isEnd() {\n\treturn (cur_samp >= end_samp || fZeroRead) && (!hACStream || !ashBuffer.cbDstLengthUsed);\n}\n\n\n\n///////////////////////////////////////////////////////////////////////////\n//\n//\t\tAudioStreamConverter\n//\n//\t\tThis audio filter handles changes in format between 8/16-bit\n//\t\tand mono/stereo.\n//\n///////////////////////////////////////////////////////////////////////////\n\n\n\nAudioStreamConverter::AudioStreamConverter(AudioStream *src, bool to_16bit, bool to_stereo_or_right, bool single_only) {\n\tWAVEFORMATEX *iFormat = src->GetFormat();\n\tWAVEFORMATEX *oFormat;\n\tbool to_stereo = single_only ? false : to_stereo_or_right;\n\n\tmemcpy(oFormat = AllocFormat(src->GetFormatLen()), iFormat, src->GetFormatLen());\n\n\toFormat->nChannels = to_stereo ? 2 : 1;\n\toFormat->wBitsPerSample = to_16bit ? 16 : 8;\n\n\tbytesPerInputSample = (iFormat->nChannels>1 ? 2 : 1)\n\t\t\t\t\t\t* (iFormat->wBitsPerSample>8 ? 2 : 1);\n\n\tbytesPerOutputSample = (to_stereo ? 2 : 1)\n\t\t\t\t\t\t * (to_16bit ? 2 : 1);\n\n\toffset = 0;\n\n\tif (single_only) {\n\t\tconvRout = AudioPickConverterSingleChannel(iFormat, to_16bit);\n\n\t\tif (to_stereo_or_right && iFormat->nChannels>1) {\n\t\t\toffset = 1;\n\n\t\t\tif (iFormat->wBitsPerSample>8)\n\t\t\t\toffset = 2;\n\t\t}\n\t} else\n\t\tconvRout = AudioPickConverter(iFormat, to_16bit, to_stereo);\n\tSetSource(src);\n\n\toFormat->nAvgBytesPerSec = oFormat->nSamplesPerSec * bytesPerOutputSample;\n\toFormat->nBlockAlign = (WORD)bytesPerOutputSample;\n\n\n\tif (!(cbuffer = malloc(bytesPerInputSample * BUFFER_SIZE)))\n\t\tthrow MyError(\"AudioStreamConverter: out of memory\");\n}\n\nAudioStreamConverter::~AudioStreamConverter() {\n\tfree(cbuffer);\n}\n\nlong AudioStreamConverter::_Read(void *buffer, long samples, long *lplBytes) {\n\tlong lActualSamples=0;\n\n\twhile(samples>0) {\n\t\tlong srcSamples;\n\t\tlong lBytes;\n\n\t\t// figure out how many source samples we need\n\n\t\tsrcSamples = samples;\n\n\t\tif (srcSamples > BUFFER_SIZE) srcSamples = BUFFER_SIZE;\n\n\t\tsrcSamples = source->Read(cbuffer, srcSamples, &lBytes);\n\n\t\tif (!srcSamples) break;\n\n\t\tconvRout(buffer, (char *)cbuffer + offset, srcSamples);\n\n\t\tbuffer = (void *)((char *)buffer + bytesPerOutputSample * srcSamples);\n\t\tlActualSamples += srcSamples;\n\t\tsamples -= srcSamples;\n\n\t}\n\n\t*lplBytes = lActualSamples * bytesPerOutputSample;\n\n\treturn lActualSamples;\n}\n\nBOOL AudioStreamConverter::_isEnd() {\n\treturn source->isEnd();\n}\n\nbool AudioStreamConverter::Skip(long samples) {\n\treturn source->Skip(samples);\n}\n\n\n\n///////////////////////////////////////////////////////////////////////////\n//\n//\t\tAudioStreamResampler\n//\n//\t\tThis audio filter handles changes in sampling rate.\n//\n///////////////////////////////////////////////////////////////////////////\n\nstatic long audio_pointsample_8(void *dst, void *src, long accum, long samp_frac, long cnt) {\n\tunsigned char *d = (unsigned char *)dst;\n\tunsigned char *s = (unsigned char *)src;\n\n\tdo {\n\t\t*d++ = s[accum>>19];\n\t\taccum += samp_frac;\n\t} while(--cnt);\n\n\treturn accum;\n}\n\nstatic long audio_pointsample_16(void *dst, void *src, long accum, long samp_frac, long cnt) {\n\tunsigned short *d = (unsigned short *)dst;\n\tunsigned short *s = (unsigned short *)src;\n\n\tdo {\n\t\t*d++ = s[accum>>19];\n\t\taccum += samp_frac;\n\t} while(--cnt);\n\n\treturn accum;\n}\n\nstatic long audio_pointsample_32(void *dst, void *src, long accum, long samp_frac, long cnt) {\n\tunsigned long *d = (unsigned long *)dst;\n\tunsigned long *s = (unsigned long *)src;\n\n\tdo {\n\t\t*d++ = s[accum>>19];\n\t\taccum += samp_frac;\n\t} while(--cnt);\n\n\treturn accum;\n}\n\nstatic long audio_downsample_mono8(void *dst, void *src, long *filter_bank, int filter_width, long accum, long samp_frac, long cnt) {\n\tunsigned char *d = (unsigned char *)dst;\n\tunsigned char *s = (unsigned char *)src;\n\n\tdo {\n\t\tlong sum = 0;\n\t\tint w;\n\t\tlong *fb_ptr;\n\t\tunsigned char *s_ptr;\n\n\t\tw = filter_width;\n\t\tfb_ptr = filter_bank + filter_width * ((accum>>11)&0xff);\n\t\ts_ptr = s + (accum>>19);\n\t\tdo {\n\t\t\tsum += *fb_ptr++ * (int)*s_ptr++;\n\t\t} while(--w);\n\n\t\tif (sum < 0)\n\t\t\t*d++ = 0;\n\t\telse if (sum > 0x3fffff)\n\t\t\t*d++ = 0xff;\n\t\telse\n\t\t\t*d++ = (unsigned char)((sum + 0x2000)>>14);\n\n\t\taccum += samp_frac;\n\t} while(--cnt);\n\n\treturn accum;\n}\n\nstatic long audio_downsample_mono16(void *dst, void *src, long *filter_bank, int filter_width, long accum, long samp_frac, long cnt) {\n\tsigned short *d = (signed short *)dst;\n\tsigned short *s = (signed short *)src;\n\n\tdo {\n\t\tlong sum = 0;\n\t\tint w;\n\t\tlong *fb_ptr;\n\t\tsigned short *s_ptr;\n\n\t\tw = filter_width;\n\t\tfb_ptr = filter_bank + filter_width * ((accum>>11)&0xff);\n\t\ts_ptr = s + (accum>>19);\n\t\tdo {\n\t\t\tsum += *fb_ptr++ * (int)*s_ptr++;\n\t\t} while(--w);\n\n\t\tif (sum < -0x20000000)\n\t\t\t*d++ = -0x8000;\n\t\telse if (sum > 0x1fffffff)\n\t\t\t*d++ = 0x7fff;\n\t\telse\n\t\t\t*d++ = (short)((sum + 0x2000)>>14);\n\n\t\taccum += samp_frac;\n\t} while(--cnt);\n\n\treturn accum;\n}\n\nstatic long audio_downsample_stereo8(void *dst, void *src, long *filter_bank, int filter_width, long accum, long samp_frac, long cnt) {\n\tunsigned char *d = (unsigned char *)dst;\n\tunsigned char *s = (unsigned char *)src;\n\n\tdo {\n\t\tlong sum_l = 0, sum_r = 0;\n\t\tint w;\n\t\tlong *fb_ptr;\n\t\tunsigned char *s_ptr;\n\n\t\tw = filter_width;\n\t\tfb_ptr = filter_bank + filter_width * ((accum>>11)&0xff);\n\t\ts_ptr = s + (accum>>19)*2;\n\t\tdo {\n\t\t\tlong f = *fb_ptr++;\n\n\t\t\tsum_l += f * (int)*s_ptr++;\n\t\t\tsum_r += f * (int)*s_ptr++;\n\t\t} while(--w);\n\n\t\tif (sum_l < 0)\n\t\t\t*d++ = 0;\n\t\telse if (sum_l > 0x3fffff)\n\t\t\t*d++ = 0xff;\n\t\telse\n\t\t\t*d++ = (unsigned char)((sum_l + 0x2000)>>14);\n\n\t\tif (sum_r < 0)\n\t\t\t*d++ = 0;\n\t\telse if (sum_r > 0x3fffff)\n\t\t\t*d++ = 0xff;\n\t\telse\n\t\t\t*d++ = (unsigned char)((sum_r + 0x2000)>>14);\n\n\t\taccum += samp_frac;\n\t} while(--cnt);\n\n\treturn accum;\n}\n\nstatic long audio_downsample_stereo16(void *dst, void *src, long *filter_bank, int filter_width, long accum, long samp_frac, long cnt) {\n\tsigned short *d = (signed short *)dst;\n\tsigned short *s = (signed short *)src;\n\n\tdo {\n\t\tlong sum_l = 0, sum_r = 0;\n\t\tint w;\n\t\tlong *fb_ptr;\n\t\tsigned short *s_ptr;\n\n\t\tw = filter_width;\n\t\tfb_ptr = filter_bank + filter_width * ((accum>>11)&0xff);\n\t\ts_ptr = s + (accum>>19)*2;\n\t\tdo {\n\t\t\tlong f = *fb_ptr++;\n\n\t\t\tsum_l += f * (int)*s_ptr++;\n\t\t\tsum_r += f * (int)*s_ptr++;\n\t\t} while(--w);\n\n\t\tif (sum_l < -0x20000000)\n\t\t\t*d++ = -0x8000;\n\t\telse if (sum_l > 0x1fffffff)\n\t\t\t*d++ = 0x7fff;\n\t\telse\n\t\t\t*d++ = (short)((sum_l + 0x2000)>>14);\n\n\t\tif (sum_r < -0x20000000)\n\t\t\t*d++ = -0x8000;\n\t\telse if (sum_r > 0x1fffffff)\n\t\t\t*d++ = 0x7fff;\n\t\telse\n\t\t\t*d++ = (short)((sum_r + 0x2000)>>14);\n\n\t\taccum += samp_frac;\n\t} while(--cnt);\n\n\treturn accum;\n}\n\nstatic long audio_upsample_mono8(void *dst, void *src, long accum, long samp_frac, long cnt) {\n\tunsigned char *d = (unsigned char *)dst;\n\tunsigned char *s = (unsigned char *)src;\n\n\tdo {\n\t\tunsigned char *s_ptr = s + (accum>>19);\n\t\tlong frac = (accum>>3) & 0xffff;\n\n\t\t*d++ = (unsigned char)(((int)s_ptr[0] * (0x10000 - frac) + (int)s_ptr[1] * frac) >> 16);\n\t\taccum += samp_frac;\n\t} while(--cnt);\n\n\treturn accum;\n}\n\nstatic long audio_upsample_mono16(void *dst, void *src, long accum, long samp_frac, long cnt) {\n\tsigned short *d = (signed short *)dst;\n\tsigned short *s = (signed short *)src;\n\n\tdo {\n\t\tsigned short *s_ptr = s + (accum>>19);\n\t\tlong frac = (accum>>3) & 0xffff;\n\n\t\t*d++ = short(((int)s_ptr[0] * (0x10000 - frac) + (int)s_ptr[1] * frac) >> 16);\n\t\taccum += samp_frac;\n\t} while(--cnt);\n\n\treturn accum;\n}\n\nstatic long audio_upsample_stereo8(void *dst, void *src, long accum, long samp_frac, long cnt) {\n\tunsigned char *d = (unsigned char *)dst;\n\tunsigned char *s = (unsigned char *)src;\n\n\tdo {\n\t\tunsigned char *s_ptr = s + (accum>>19)*2;\n\t\tlong frac = (accum>>3) & 0xffff;\n\n\t\t*d++ = (unsigned char)(((int)s_ptr[0] * (0x10000 - frac) + (int)s_ptr[2] * frac) >> 16);\n\t\t*d++ = (unsigned char)(((int)s_ptr[1] * (0x10000 - frac) + (int)s_ptr[3] * frac) >> 16);\n\t\taccum += samp_frac;\n\t} while(--cnt);\n\n\treturn accum;\n}\n\nstatic long audio_upsample_stereo16(void *dst, void *src, long accum, long samp_frac, long cnt) {\n\tsigned short *d = (signed short *)dst;\n\tsigned short *s = (signed short *)src;\n\n\tdo {\n\t\tsigned short *s_ptr = s + (accum>>19)*2;\n\t\tlong frac = (accum>>3) & 0xffff;\n\n\t\t*d++ = short(((int)s_ptr[0] * (0x10000 - frac) + (int)s_ptr[2] * frac) >> 16);\n\t\t*d++ = short(((int)s_ptr[1] * (0x10000 - frac) + (int)s_ptr[3] * frac) >> 16);\n\t\taccum += samp_frac;\n\t} while(--cnt);\n\n\treturn accum;\n}\n\nstatic int permute_index(int a, int b) {\n\treturn (b-(a>>8)-1) + (a&255)*b;\n}\n\nstatic void make_downsample_filter(long *filter_bank, int filter_width, long samp_frac) {\n\tint i, j, v;\n\tdouble filt_max;\n\tdouble filtwidth_frac;\n\n\tfiltwidth_frac = samp_frac/2048.0;\n\n\tfilter_bank[filter_width-1] = 0;\n\n\tfilt_max = (16384.0 * 524288.0) / samp_frac;\n\n\tfor(i=0; i<128*filter_width; i++) {\n\t\tint y = 0;\n\t\tdouble d = i / filtwidth_frac;\n\n\t\tif (d<1.0)\n\t\t\ty = (int)(0.5 + filt_max*(1.0 - d));\n\n\t\tfilter_bank[permute_index(128*filter_width + i, filter_width)]\n\t\t\t= filter_bank[permute_index(128*filter_width - i, filter_width)]\n\t\t\t= y;\n\t}\n\n\t// Normalize the filter to correct for integer roundoff errors\n\n\tfor(i=0; i<256*filter_width; i+=filter_width) {\n\t\tv=0;\n\t\tfor(j=0; j<filter_width; j++)\n\t\t\tv += filter_bank[i+j];\n\n\t\t_RPT2(0,\"error[%02x] = %04x\\n\", i/filter_width, 0x4000 - v);\n\n\t\tv = (0x4000 - v)/filter_width;\n\t\tfor(j=0; j<filter_width; j++)\n\t\t\tfilter_bank[i+j] += v;\n\t}\n\n\t_CrtCheckMemory();\n}\n\nAudioStreamResampler::AudioStreamResampler(AudioStream *src, long new_rate, bool integral_conversion, bool hi_quality) : AudioStream() {\n\tWAVEFORMATEX *iFormat = src->GetFormat();\n\tWAVEFORMATEX *oFormat;\n\n\tmemcpy(oFormat = AllocFormat(src->GetFormatLen()), iFormat, src->GetFormatLen());\n\n\tif (oFormat->nChannels>1)\n\t\tif (oFormat->wBitsPerSample>8) {\n\t\t\tptsampleRout = audio_pointsample_32;\n\t\t\tupsampleRout = audio_upsample_stereo16;\n\t\t\tdnsampleRout = audio_downsample_stereo16;\n\t\t} else {\n\t\t\tptsampleRout = audio_pointsample_16;\n\t\t\tupsampleRout = audio_upsample_stereo8;\n\t\t\tdnsampleRout = audio_downsample_stereo8;\n\t\t}\n\telse\n\t\tif (oFormat->wBitsPerSample>8) {\n\t\t\tptsampleRout = audio_pointsample_16;\n\t\t\tupsampleRout = audio_upsample_mono16;\n\t\t\tdnsampleRout = audio_downsample_mono16;\n\t\t} else {\n\t\t\tptsampleRout = audio_pointsample_8;\n\t\t\tupsampleRout = audio_upsample_mono8;\n\t\t\tdnsampleRout = audio_downsample_mono8;\n\t\t}\n\n\tSetSource(src);\n\n\tbytesPerSample = (iFormat->nChannels>1 ? 2 : 1)\n\t\t\t\t\t\t* (iFormat->wBitsPerSample>8 ? 2 : 1);\n\n\t_RPT2(0,\"AudioStreamResampler: converting from %ldHz to %ldHz\\n\", iFormat->nSamplesPerSec, new_rate);\n\n\tif (integral_conversion)\n\t\tif (new_rate > long(iFormat->nSamplesPerSec))\n//\t\t\tsamp_frac = MulDiv(0x10000, new_rate + iFormat->nSamplesPerSec/2, iFormat->nSamplesPerSec);\n\t\t\tsamp_frac = 0x80000 / ((new_rate + iFormat->nSamplesPerSec/2) / iFormat->nSamplesPerSec);\n\t\telse\n\t\t\tsamp_frac = 0x80000 * ((iFormat->nSamplesPerSec + new_rate/2) / new_rate);\n\telse\n\t\tsamp_frac = MulDiv(iFormat->nSamplesPerSec, 0x80000L, new_rate);\n\n\tstream_len = MulDiv(stream_len, 0x80000L, samp_frac);\n\n\toFormat->nSamplesPerSec = MulDiv(iFormat->nSamplesPerSec, 0x80000L, samp_frac);\n\toFormat->nAvgBytesPerSec = oFormat->nSamplesPerSec * bytesPerSample;\n\toFormat->nBlockAlign = (WORD)bytesPerSample;\n\n\tholdover = 0;\n\tfilter_bank = NULL;\n\tfilter_width = 1;\n\taccum=0;\n\tfHighQuality = hi_quality;\n\n\tif (!(cbuffer = malloc(bytesPerSample * BUFFER_SIZE)))\n\t\tthrow MyMemoryError();\n\n\t// Initialize the buffer.\n\n\tif (oFormat->wBitsPerSample>8)\n\t\tmemset(cbuffer, 0x00, bytesPerSample * BUFFER_SIZE);\n\telse\n\t\tmemset(cbuffer, 0x80, bytesPerSample * BUFFER_SIZE);\n\n\t// If this is a high-quality downsample, allocate memory for the filter bank\n\n\tif (hi_quality) {\n\t\tif (samp_frac>0x80000) {\n\n\t\t\t// HQ downsample: allocate filter bank\n\n\t\t\tfilter_width = ((samp_frac + 0x7ffff)>>19)<<1;\n\n\t\t\tif (!(filter_bank = new(std::nothrow) long[filter_width * 256])) {\n\t\t\t\tfree(cbuffer);\n\t\t\t\tthrow MyMemoryError();\n\t\t\t}\n\n\t\t\tmake_downsample_filter(filter_bank, filter_width, samp_frac);\n\n\t\t\t// Clear lower samples\n\n\t\t\tif (oFormat->wBitsPerSample>8)\n\t\t\t\tmemset(cbuffer, 0, bytesPerSample*filter_width);\n\t\t\telse\n\t\t\t\tmemset(cbuffer, 0x80, bytesPerSample*filter_width);\n\n\t\t\tholdover = filter_width/2;\n\t\t}\n\t}\n}\n\nAudioStreamResampler::~AudioStreamResampler() {\n\tfree(cbuffer);\n\tdelete filter_bank;\n}\n\nlong AudioStreamResampler::_Read(void *buffer, long samples, long *lplBytes) {\n\n\tif (samp_frac == 0x80000)\n\t\treturn source->Read(buffer, samples, lplBytes);\n\n\tif (samp_frac < 0x80000)\n\t\treturn Upsample(buffer, samples, lplBytes);\n\telse\n\t\treturn Downsample(buffer, samples, lplBytes);\n}\n\n\nlong AudioStreamResampler::Upsample(void *buffer, long samples, long *lplBytes) {\n\tlong lActualSamples=0;\n\n\t// Upsampling: producing more output samples than input\n\t//\n\t// There are two issues we need to watch here:\n\t//\n\t//\to  An input sample can be read more than once.  In particular, even\n\t//\t   when point sampling, we may need the last input sample again.\n\t//\n\t//\to  When interpolating (HQ), we need one additional sample.\n\n\twhile(samples>0) {\n\t\tlong srcSamples, dstSamples;\n\t\tlong lBytes;\n\t\tint holdover = 0;\n\n\t\t// A negative accum value indicates that we need to reprocess a sample.\n\t\t// The last iteration should have left it at the bottom of the buffer\n\t\t// for us.  In interpolation mode, we'll always have at least a 1\n\t\t// sample overlap.\n\n\t\tif (accum<0) {\n\t\t\tholdover = 1;\n\t\t\taccum += 0x80000;\n\t\t}\n\n\t\tif (fHighQuality)\n\t\t\t++holdover;\n\n\t\t// figure out how many source samples we need\n\n\t\tsrcSamples = (long)(((__int64)samp_frac*(samples-1) + accum) >> 19) + 1 - holdover;\n\n\t\tif (fHighQuality)\n\t\t\t++srcSamples;\n\n\t\tif (srcSamples > BUFFER_SIZE-holdover) srcSamples = BUFFER_SIZE-holdover;\n\n\t\tsrcSamples = source->Read((char *)cbuffer + holdover * bytesPerSample, srcSamples, &lBytes);\n\n\t\tif (!srcSamples) break;\n\n\t\tsrcSamples += holdover;\n\n\t\t// figure out how many destination samples we'll get out of what we read\n\n\t\tif (fHighQuality)\n\t\t\tdstSamples = ((srcSamples<<19) - accum - 0x80001)/samp_frac + 1;\n\t\telse\n\t\t\tdstSamples = ((srcSamples<<19) - accum - 1)/samp_frac + 1;\n\n\t\tif (dstSamples > samples)\n\t\t\tdstSamples = samples;\n\n\t\tif (dstSamples>=1) {\n\n\t\t\tif (fHighQuality)\n\t\t\t\taccum = upsampleRout(buffer, cbuffer, accum, samp_frac, dstSamples);\n\t\t\telse\n\t\t\t\taccum = ptsampleRout(buffer, cbuffer, accum, samp_frac, dstSamples);\n\n\t\t\tbuffer = (void *)((char *)buffer + bytesPerSample * dstSamples);\n\t\t\tlActualSamples += dstSamples;\n\t\t\tsamples -= dstSamples;\n\t\t}\n\n\t\tif (fHighQuality)\n\t\t\taccum -= ((srcSamples-1)<<19);\n\t\telse\n\t\t\taccum -= (srcSamples<<19);\n\n\t\t// do we need to hold a sample over?\n\n\t\tif (fHighQuality)\n\t\t\tif (accum<0)\n\t\t\t\tmemcpy(cbuffer, (char *)cbuffer + (srcSamples-2)*bytesPerSample, bytesPerSample*2);\n\t\t\telse\n\t\t\t\tmemcpy(cbuffer, (char *)cbuffer + (srcSamples-1)*bytesPerSample, bytesPerSample);\n\t\telse if (accum<0)\n\t\t\tmemcpy(cbuffer, (char *)cbuffer + (srcSamples-1)*bytesPerSample, bytesPerSample);\n\t}\n\n\t*lplBytes = lActualSamples * bytesPerSample;\n\n//\t_RPT2(0,\"Converter: %ld samples, %ld bytes\\n\", lActualSamples, *lplBytes);\n\n\treturn lActualSamples;\n}\n\nlong AudioStreamResampler::Downsample(void *buffer, long samples, long *lplBytes) {\n\tlong lActualSamples=0;\n\n\t// Downsampling is even worse because we have overlap to the left and to the\n\t// right of the interpolated point.\n\t//\n\t// We need (n/2) points to the left and (n/2-1) points to the right.\n\n\twhile(samples>0) {\n\t\tlong srcSamples, dstSamples;\n\t\tlong lBytes;\n\t\tint nhold;\n\n\t\t// Figure out how many source samples we need.\n\t\t//\n\t\t// To do this, compute the highest fixed-point accumulator we'll reach.\n\t\t// Truncate that, and add the filter width.  Then subtract however many\n\t\t// samples are sitting at the bottom of the buffer.\n\n\t\tsrcSamples = (long)(((__int64)samp_frac*(samples-1) + accum) >> 19) + filter_width - holdover;\n\n\t\t// Don't exceed the buffer (BUFFER_SIZE - holdover).\n\n\t\tif (srcSamples > BUFFER_SIZE - holdover)\n\t\t\tsrcSamples = BUFFER_SIZE - holdover;\n\n\t\t// Read into buffer.\n\n\t\tsrcSamples = source->Read((char *)cbuffer + holdover*bytesPerSample, srcSamples, &lBytes);\n\n\t\tif (!srcSamples) break;\n\n\t\t// Figure out how many destination samples we'll get out of what we\n\t\t// read.  We'll have (srcSamples+holdover) bytes, so the maximum\n\t\t// fixed-pt accumulator we can hit is\n\t\t// (srcSamples+holdover-filter_width)<<16 + 0xffff.\n\n\t\tdstSamples = (((srcSamples+holdover-filter_width)<<19) + 0x7ffff - accum) / samp_frac + 1;\n\n\t\tif (dstSamples > samples)\n\t\t\tdstSamples = samples;\n\n\t\tif (dstSamples>=1) {\n\t\t\tif (filter_bank)\n\t\t\t\taccum = dnsampleRout(buffer, cbuffer, filter_bank, filter_width, accum, samp_frac, dstSamples);\n\t\t\telse\n\t\t\t\taccum = ptsampleRout(buffer, cbuffer, accum, samp_frac, dstSamples);\n\n\t\t\tbuffer = (void *)((char *)buffer + bytesPerSample * dstSamples);\n\t\t\tlActualSamples += dstSamples;\n\t\t\tsamples -= dstSamples;\n\t\t}\n\n\t\t// We're \"shifting\" the new samples down to the bottom by discarding\n\t\t// all the samples in the buffer, so adjust the fixed-pt accum\n\t\t// accordingly.\n\n\t\taccum -= ((srcSamples+holdover)<<19);\n\n\t\t// Oops, did we need some of those?\n\t\t//\n\t\t// If accum=0, we need (n/2) samples back.  accum>=0x10000 is fewer,\n\t\t// accum<0 is more.\n\n\t\tnhold = - (accum>>19);\n\n//\t\t_ASSERT(nhold<=(filter_width/2));\n\n\t\tif (nhold>0) {\n\t\t\tmemmove(cbuffer, (char *)cbuffer+bytesPerSample*(srcSamples+holdover-nhold), bytesPerSample*nhold);\n\t\t\tholdover = nhold;\n\t\t\taccum += nhold<<19;\n\t\t} else\n\t\t\tholdover = 0;\n\n\t\t_ASSERT(accum>=0);\n\t}\n\n\t*lplBytes = lActualSamples * bytesPerSample;\n\n\treturn lActualSamples;\n}\n\nBOOL AudioStreamResampler::_isEnd() {\n\treturn accum>=0 && source->isEnd();\n}\n\n\n\n///////////////////////////////////////////////////////////////////////////\n//\n//\t\tAudioCompressor\n//\n//\t\tThis audio filter handles audio compression.\n//\n///////////////////////////////////////////////////////////////////////////\n\n\nstruct FrustratedACMOpenData {\n\tHACMSTREAM *pp;\n\tHACMDRIVER hdrv;\n\tWAVEFORMATEX *iFormat;\n\tWAVEFORMATEX *oFormat;\n\tbool success;\n};\n\n\nBOOL CALLBACK ACMStreamOpenCallback(HACMDRIVERID hadid, DWORD_PTR dwInstance, DWORD fdwSupport)\n{\n\tFrustratedACMOpenData *pfad = (FrustratedACMOpenData *)dwInstance;\n\n\t// Ignore drivers that don't do format conversion.\n\n\tif (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CODEC) {\n\t\tMMRESULT res;\n\t\tACMDRIVERDETAILS add;\n\n\t\tmemset(&add, 0, sizeof add);\n\t\tadd.cbStruct = sizeof add;\n\n\t\t// Attempt to open driver.\n\n\t\tres = acmDriverOpen(&pfad->hdrv, hadid, 0);\n\n\t\tif (!res) {\n\n\t\t\tres = acmDriverDetails(hadid, &add, 0);\n      if (!res) {\n\t\t\t\t_RPT1(0,\"Trying driver: [%s]\\n\", add.szLongName);\n      }\n\n\t\t\t// Attempt our stream open!\n\n\t\t\tres = acmStreamOpen(pfad->pp, pfad->hdrv, pfad->iFormat, pfad->oFormat, NULL, 0, 0, ACM_STREAMOPENF_NONREALTIME);\n\t\t\tif (!res)\n\t\t\t\tpfad->success = true;\n\t\t\telse {\n\t\t\t\tres = acmStreamOpen(pfad->pp, pfad->hdrv, pfad->iFormat, pfad->oFormat, NULL, 0, 0, 0);\n\t\t\t\tif (!res)\n\t\t\t\t\tpfad->success = true;\n\t\t\t\telse\n\t\t\t\t\tacmDriverClose(pfad->hdrv, 0);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn !pfad->success;\n}\n\n\nAudioCompressor::AudioCompressor(AudioStream *src, WAVEFORMATEX *dst_format, long dst_format_len) : AudioStream() {\n\tWAVEFORMATEX *iFormat = src->GetFormat();\n\tWAVEFORMATEX *oFormat;\n\tDWORD dwOutputBufferSize;\n\tMMRESULT err;\n\n\thADriver = NULL;\n\thACStream = NULL;\n\tpwfexTempOutput = NULL;\n\tinputBuffer = outputBuffer = NULL;\n\tholdBuffer = NULL;\n\tholdBufferSize = 0;\n\tholdBufferOffset = 0;\n\n\t// Stupid Microsoft Audio Codec.\n\n\toFormat = AllocFormat(dst_format_len);\n\tmemcpy(oFormat, dst_format, dst_format_len);\n\n\tSetSource(src);\n\n\tmemset(&ashBuffer, 0, sizeof ashBuffer);\n\n\tfor (;;) {\n\t\t// Try opening with ACM_STREAMOPENF_NONREALTIME.\n\n\t\tif (!(err = acmStreamOpen(&hACStream, NULL, iFormat, oFormat, NULL, 0, 0, ACM_STREAMOPENF_NONREALTIME)))\n\t\t\tbreak;\n\n\t\t// Still didn't work, try every f*cking driver.\n\n\t\tstruct FrustratedACMOpenData fad;\n\n\t\tfad.pp\t\t= &hACStream;\n\t\tfad.hdrv\t= NULL;\n\t\tfad.iFormat = iFormat;\n\t\tfad.oFormat = oFormat;\n\t\tfad.success = false;\n\n\t\tif (!acmDriverEnum(ACMStreamOpenCallback, (DWORD_PTR)&fad, 0) && fad.success) {\n\t\t\thADriver = fad.hdrv;\n\t\t\tbreak;\n\t\t}\n\n\t\t// Damn!\n\n\t\tif (err == ACMERR_NOTPOSSIBLE)\n\t\t\tthrow MyError(\"Error initializing audio stream compression:\\nThe requested conversion is not possible.\");\n\t\telse\n\t\t\tthrow MyError(\"Error initializing audio stream compression.\");\n\t}\n\n\tif (acmStreamSize(hACStream, INPUT_BUFFER_SIZE, &dwOutputBufferSize, ACM_STREAMSIZEF_SOURCE))\n\t\tthrow MyError(\"Error querying audio compression.\");\n\n\tif (!(inputBuffer = malloc(INPUT_BUFFER_SIZE))\n\t\t|| !(outputBuffer = malloc(dwOutputBufferSize)))\n\n\t\tthrow MyMemoryError();\n\n\tashBuffer.cbStruct\t\t= sizeof(ACMSTREAMHEADER);\n\tashBuffer.pbSrc\t\t\t= (LPBYTE)inputBuffer;\n\tashBuffer.cbSrcLength\t= INPUT_BUFFER_SIZE;\n\tashBuffer.pbDst\t\t\t= (LPBYTE)outputBuffer;\n\tashBuffer.cbDstLength\t= dwOutputBufferSize;\n\n\tif (acmStreamPrepareHeader(hACStream, &ashBuffer, 0))\n\t\tthrow MyError(\"Error preparing audio compression buffers.\");\n\n\tashBuffer.cbSrcLength = 0;\n\n\tbytesPerInputSample = iFormat->nBlockAlign;\n\tbytesPerOutputSample = oFormat->nBlockAlign;\n\n\tfStreamEnded = FALSE;\n}\n\nAudioCompressor::~AudioCompressor() {\n\tif (hACStream) {\n\t\tif (ashBuffer.fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED) acmStreamUnprepareHeader(hACStream, &ashBuffer, 0);\n\t\tacmStreamClose(hACStream, 0);\n\t}\n\tif (hADriver)\n\t\tacmDriverClose(hADriver, 0);\n\n\tif (inputBuffer)\tfree(inputBuffer);\n\tif (outputBuffer)\tfree(outputBuffer);\n\tif (holdBuffer)\t\tfree(holdBuffer);\n\n\tdelete[] pwfexTempOutput;\n}\n\nvoid AudioCompressor::CompensateForMP3() {\n\n\t// Fraunhofer-IIS's MP3 codec has a compression delay that we need to\n\t// compensate for.  Comparison of PCM input, F-IIS output, and\n\t// WinAmp's Nitrane output reveals that the decompressor half of the\n\t// ACM codec is fine, but the compressor inserts a delay of 1373\n\t// (0x571) samples at the start.  This is a lag of 2 frames at\n\t// 30fps and 22KHz, so it's significant enough to be noticed.  At\n\t// 11KHz, this becomes a tenth of a second.  Needless to say, the\n\t// F-IIS MP3 codec is a royal piece of sh*t.\n\t//\n\t// By coincidence, the MPEGLAYER3WAVEFORMAT struct has a field\n\t// called nCodecDelay which is set to this value...\n\n\tif (GetFormat()->wFormatTag == WAVE_FORMAT_MPEGLAYER3) {\n\t\tlong lSamplesToRead = ((MPEGLAYER3WAVEFORMAT *)GetFormat())->nCodecDelay;\n\n\t\t// Note: LameACM does not have a codec delay!\n\n\t\tif (lSamplesToRead) {\n\t\t\tlong ltActualBytes, ltActualSamples;\n\t\t\tint nBlockAlign = source->GetFormat()->nBlockAlign;\n\n\t\t\tdo {\n\t\t\t\tlong tc;\n\n\t\t\t\ttc = lSamplesToRead;\n\t\t\t\tif (tc > INPUT_BUFFER_SIZE / nBlockAlign)\n\t\t\t\t\ttc = INPUT_BUFFER_SIZE / nBlockAlign;\n\n\t\t\t\tltActualSamples = source->Read((char *)inputBuffer, tc,\n\t\t\t\t\t\t\t&ltActualBytes);\n\n\t\t\t\tlSamplesToRead -= ltActualSamples;\n\t\t\t} while(lSamplesToRead>0 && ltActualBytes);\n\n\t\t\tif (!ltActualBytes || source->isEnd())\n\t\t\t\tfStreamEnded = TRUE;\n\t\t}\n\t}\n}\n\nvoid AudioCompressor::ResizeHoldBuffer(long lNewSize) {\n\tvoid *holdBufferTemp;\n\n\tif (holdBufferSize >= lNewSize) return;\n\n\tif (!(holdBufferTemp = malloc(holdBufferSize = ((lNewSize + 65535) & -65536))))\n\t\tthrow MyError(\"AudioCompressor: Unable to resize hold buffer\");\n\n\tmemcpy(holdBufferTemp, holdBuffer, holdBufferOffset);\n\tfree(holdBuffer);\n\n\tholdBuffer = holdBufferTemp;\n}\n\nvoid AudioCompressor::WriteToHoldBuffer(void *data, long lBytes) {\n\tif (lBytes + holdBufferOffset > holdBufferSize)\n\t\tResizeHoldBuffer(lBytes + holdBufferOffset);\n\n\tmemcpy((char *)holdBuffer + holdBufferOffset, data, lBytes);\n\tholdBufferOffset += lBytes;\n}\n\nvoid *AudioCompressor::Compress(long lInputSamples, long *lplSrcInputSamples, long *lplOutputBytes, long *lplOutputSamples) {\n\tLONG ltActualSamples, ltActualBytes;\n\tLONG lActualSrcSamples = 0;\n\n//\t_RPT1(0,\"Compressor: we want to convert %ld input samples\\n\", lInputSamples);\n\n\tholdBufferOffset = 0;\n\n\twhile(lInputSamples > 0 && !fStreamEnded) {\n\n\t\t// fill the input buffer up!\n\n\t\tif (ashBuffer.cbSrcLength < INPUT_BUFFER_SIZE) {\n\t\t\t//LONG lBytes=0;\n\t\t\tlong lSamplesToRead;\n\n\t\t\tdo {\n\t\t\t\tlSamplesToRead = min(lInputSamples, (INPUT_BUFFER_SIZE - (long)ashBuffer.cbSrcLength)/bytesPerInputSample);\n\n\t\t\t\tltActualSamples = source->Read((char *)inputBuffer + ashBuffer.cbSrcLength, lSamplesToRead,\n\t\t\t\t\t\t\t&ltActualBytes);\n\n\t\t\t\tashBuffer.cbSrcLength += ltActualBytes;\n\n\t\t\t\t//lBytes += ltActualBytes;\n\n\t\t\t\tlInputSamples -= ltActualSamples;\n\t\t\t\tlActualSrcSamples += ltActualSamples;\n\n\t\t\t\t_ASSERT(lInputSamples >= 0);\n\t\t\t} while(ashBuffer.cbSrcLength < INPUT_BUFFER_SIZE && lInputSamples>0 && ltActualBytes);\n\n\t\t\tif (!ltActualBytes || source->isEnd())\n\t\t\t\tfStreamEnded = TRUE;\n\t\t}\n\n\t\t// ask ACM to convert for us\n\n\t\tashBuffer.cbSrcLengthUsed = 0;\n\t\tashBuffer.cbDstLengthUsed = 0;\n\n//\t\t_RPT2(0,\"Converting %ld bytes to %ld\\n\", ashBuffer.cbSrcLength, ashBuffer.cbDstLength);\n\n//\tVDCHECKPOINT;\n\t\tif (acmStreamConvert(hACStream, &ashBuffer, fStreamEnded ? ACM_STREAMCONVERTF_END : ACM_STREAMCONVERTF_BLOCKALIGN))\n\t\t\tthrow MyError(\"Audio Compression Manager (ACM) failure on compress\");\n//\tVDCHECKPOINT;\n\n//\t\t_RPT2(0,\"Converted %ld bytes to %ld\\n\", ashBuffer.cbSrcLengthUsed, ashBuffer.cbDstLengthUsed);\n\n\t\t// if ACM didn't use all the source data, copy the remainder down\n\n\t\tif (ashBuffer.cbSrcLengthUsed < ashBuffer.cbSrcLength) {\n\t\t\tlong left = ashBuffer.cbSrcLength - ashBuffer.cbSrcLengthUsed;\n\n\t\t\tmemmove(inputBuffer, (char *)inputBuffer + ashBuffer.cbSrcLengthUsed, left);\n\n\t\t\tashBuffer.cbSrcLength = left;\n\t\t} else\n\t\t\tashBuffer.cbSrcLength = 0;\n\n\t\t// chuck all pending data to the hold buffer\n\n\t\tWriteToHoldBuffer(outputBuffer, ashBuffer.cbDstLengthUsed);\n\t}\n\n\t*lplOutputBytes = holdBufferOffset;\n\t*lplOutputSamples = (holdBufferOffset + bytesPerOutputSample - 1) / bytesPerOutputSample;\n\t*lplSrcInputSamples = lActualSrcSamples;\n\n//\t_RPT2(0,\"Compressor: %ld bytes, %ld samples\\n\", *lplOutputBytes, *lplOutputSamples);\n\n\treturn holdBuffer;\n}\n\nBOOL AudioCompressor::isEnd() {\n\treturn fStreamEnded;\n}\n\n///////////////////////////////////////////////////////////////////////////\n//\n//\tCorrects the nAvgBytesPerFrame for that stupid Fraunhofer-IIS\n//\tcodec.\n\n\nAudioL3Corrector::AudioL3Corrector() {\n\tsamples = frame_bytes = 0;\n\tread_left = 4;\n\theader_mode = true;\n}\n\nlong AudioL3Corrector::ComputeByterate(long sample_rate) {\n\treturn MulDiv(frame_bytes, sample_rate, samples);\n}\n\nvoid AudioL3Corrector::Process(void *buffer, long bytes) {\n\tstatic const int bitrates[2][16]={\n\t\t{0, 8,16,24,32,40,48,56, 64, 80, 96,112,128,144,160,0},\n\t\t{0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}\n\t};\n\tstatic const long samp_freq[4] = {44100, 48000, 32000, 0};\n\n\tint cnt=0;\n\tint tc;\n\n\twhile(cnt < bytes) {\n\t\ttc = bytes - cnt;\n\t\tif (tc > read_left)\n\t\t\ttc = read_left;\n\n\t\tif (header_mode)\n\t\t\tmemcpy(&hdr_buffer[4-read_left], buffer, tc);\n\n\t\tbuffer = (char *)buffer + tc;\n\t\tcnt += tc;\n\t\tread_left -= tc;\n\n    if (read_left <= 0) {\n      if (header_mode) {\n        // We've got a header!  Process it...\n\n        long hdr = *(long *)hdr_buffer;\n        long samp_rate, framelen;\n\n        if ((hdr & 0xE0FF) != 0xE0FF)\n          throw MyError(\"MPEG audio sync error: try disabling MPEG audio time correction\");\n\n        samp_rate = samp_freq[(hdr >> 18) & 3];\n\n        if (!((hdr >> 11) & 1)) {\n          samp_rate /= 2;\n          samples += 576;\n        }\n        else {\n          samples += 1152;\n        }\n\n        if (!(hdr & 0x1000))\n          samp_rate /= 2;\n\n        framelen = (bitrates[(hdr >> 11) & 1][(hdr >> 20) & 15] * (((hdr >> 11) & 1) ? 144000 : 72000)) / samp_rate;\n\n        if (hdr & 0x20000) ++framelen;\n\n        // update statistics\n\n        frame_bytes += framelen;\n\n        // start skipping the remainder\n\n        read_left = framelen - 4;\n        header_mode = false;\n\n      }\n      else {\n\n     // Done skipping frame data; collect the next header\n\n        read_left = 4;\n        header_mode = true;\n      }\n    }\n\t}\n}\n\n///////////////////////////////////////////////////////////////////////////\n/*\nlong AudioTranslateVideoSubset(FrameSubset& dst, FrameSubset& src, long usPerFrame, WAVEFORMATEX *pwfex) {\n\tFrameSubsetNode *fsn = src.getFirstFrame();\n\tconst __int64 i64usPerFrame = usPerFrame;\n\tconst long lSampPerSec = pwfex->nSamplesPerSec;\n\tconst long nBytesPerSec = pwfex->nAvgBytesPerSec;\n\tconst int nBlockAlign = pwfex->nBlockAlign;\n\tlong total = 0;\n\n\t// I like accuracy, so let's strive for accuracy.  Accumulate errors as we go;\n\t// use them to offset the starting points of subsequent segments, never being\n\t// more than 1/2 segment off.\n\t//\n\t// The conversion equation is in units of (1000000*nBlockAlign).\n\n\t__int64 nError = 0;\n\t__int64 nMultiplier = i64usPerFrame * nBytesPerSec;\n\t__int64 nDivisor = 1000000i64*nBlockAlign;\n\t__int64 nRound = nDivisor/2;\n\tlong nTotalFramesAccumulated = 0;\n\n\twhile(fsn) {\n\t\tlong start, end;\n\n\t\t// Compute error.\n\t\t//\n\t\t// Ideally, we want the audio and video streams to be of the exact length.\n\t\t//\n\t\t// Audiolen = (videolen * usPerFrame * nBytesPerSec) / (1000000*nBlockAlign);\n\n\t\tnError = total*nDivisor - (nTotalFramesAccumulated * nMultiplier);\n\n_RPT1(0,\"nError = %I64d\\n\", nError);\n\n\t\t// Add a block.\n\n\t\tstart = ((__int64)fsn->start * nMultiplier + nRound + nError) / nDivisor;\n\t\tend = ((__int64)(fsn->start + fsn->len) * nMultiplier + nRound) / nDivisor;\n\n\t\tnTotalFramesAccumulated += fsn->len;\n\n\t\tdst.addRange(start, end-start, false);\n\n\t\ttotal += end-start;\n\n\t\tfsn = src.getNextFrame(fsn);\n\t}\n\n\treturn total;\n}\n\nAudioSubset::AudioSubset(AudioStream *src, FrameSubset *pfs, long usPerFrame, long preskew) : AudioStream() {\n\tmemcpy(AllocFormat(src->GetFormatLen()), src->GetFormat(), src->GetFormatLen());\n\n\tSetSource(src);\n\n#if 1\n\n\tlong total = AudioTranslateVideoSubset(subset, *pfs, usPerFrame, src->GetFormat());\n\n#else\n\twhile(fsn) {\n\t\tlong start, end;\n\n//\t\tstart = ((__int64)fsn->start * i64usPerFrame * lSampPerSec) / 1000000;\n//\t\tend = ((__int64)(fsn->start + fsn->len) * i64usPerFrame * lSampPerSec) / 1000000;\n\n\t\tstart = ((__int64)fsn->start * i64usPerFrame * nBytesPerSec + 500000*nBlockAlign) / (1000000*nBlockAlign);\n\t\tend = ((__int64)(fsn->start + fsn->len) * i64usPerFrame * nBytesPerSec + 500000*nBlockAlign) / (1000000*nBlockAlign);\n\n\t\tsubset.addRange(start, end-start);\n\n\t\ttotal += end-start;\n\n\t\tfsn = pfs->getNextFrame(fsn);\n\t}\n#endif\n\n\tsubset.deleteRange(0, MulDiv(preskew, src->GetFormat()->nSamplesPerSec, 1000));\n\n\tstream_len = total;\n\n\tSetLimit(total);\n\n\tpfsnCur = subset.getFirstFrame();\n\tiOffset = 0;\n\tlSrcPos = 0;\n\tlSkipSize = sizeof skipBuffer / src->GetFormat()->nBlockAlign;\n}\n\nAudioSubset::~AudioSubset() {\n}\n\nlong AudioSubset::_Read(void *buffer, long samples, long *lplBytes) {\n\tint offset, actual;\n\n\tif (!pfsnCur) {\n\t\t*lplBytes = 0;\n\t\treturn 0;\n\t}\n\n\twhile ((offset = pfsnCur->start - lSrcPos) > 0) {\n\t\tlong t;\n\n\t\tif (source->Skip(offset)) {\n\t\t\tlSrcPos += offset;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (offset > lSkipSize) offset = lSkipSize;\n\n\t\tactual = source->Read(skipBuffer, offset, &t);\n\n\t\tif (!actual) {\n\t\t\t*lplBytes = 0;\n\t\t\treturn 0;\n\t\t}\n\n\t\tlSrcPos += actual;\n\t}\n\n\tif (samples > pfsnCur->len - iOffset)\n\t\tsamples = pfsnCur->len - iOffset;\n\n\tsamples = source->Read(buffer, samples, lplBytes);\n\n\tiOffset += samples;\n\tlSrcPos += samples;\n\twhile (pfsnCur && iOffset >= pfsnCur->len) {\n\t\tiOffset -= pfsnCur->len;\n\t\tpfsnCur = subset.getNextFrame(pfsnCur);\n\t}\n\n\treturn samples;\n}\n\nBOOL AudioSubset::_isEnd() {\n\treturn !pfsnCur || source->isEnd();\n}\n*/\n\n///////////////////////////////////////////////////////////////////////////\n//\n//\tAudioAmplifier\n//\n///////////////////////////////////////////////////////////////////////////\n\nstatic void amplify8(unsigned char *dst, int count, long lFactor) {\n\tlong lBias = 0x8080 - 0x80*lFactor;\n\n\tif (count)\n\t\tdo {\n\t\t\tint y = ((long)*dst++ * lFactor + lBias) >> 8;\n\n\t\t\tif (y<0) y=0; else if (y>255) y=255;\n\n\t\t\tdst[-1] = (unsigned char)y;\n\t\t} while(--count);\n}\n\nstatic void amplify16(signed short *dst, int count, long lFactor) {\n\tif (count)\n\t\tdo {\n\t\t\tint y = ((long)*dst++ * lFactor + 0x80) >> 8;\n\n\t\t\tif (y<-0x7FFF) y=-0x7FFF; else if (y>0x7FFF) y=0x7FFF;\n\n\t\t\tdst[-1] = (signed short)y;\n\t\t} while(--count);\n}\n\nAudioStreamAmplifier::AudioStreamAmplifier(AudioStream *src, long _lFactor)\n: lFactor(_lFactor) {\n\n\tWAVEFORMATEX *iFormat = src->GetFormat();\n\tWAVEFORMATEX *oFormat;\n\n\tmemcpy(oFormat = AllocFormat(src->GetFormatLen()), iFormat, src->GetFormatLen());\n\n\tSetSource(src);\n}\n\nAudioStreamAmplifier::~AudioStreamAmplifier() {\n}\n\nlong AudioStreamAmplifier::_Read(void *buffer, long samples, long *lplBytes) {\n\tlong lActualSamples=0;\n\tlong lBytes;\n\n\tlActualSamples = source->Read(buffer, samples, &lBytes);\n\n\tif (lActualSamples) {\n\t\tif (GetFormat()->wBitsPerSample > 8)\n\t\t\tamplify16((signed short *)buffer, lBytes/2, lFactor);\n\t\telse\n\t\t\tamplify8((unsigned char *)buffer, lBytes, lFactor);\n\t}\n\n\tif (lplBytes)\n\t\t*lplBytes = lBytes;\n\n\treturn lActualSamples;\n}\n\nBOOL AudioStreamAmplifier::_isEnd() {\n\treturn source->isEnd();\n}\n\nbool AudioStreamAmplifier::Skip(long samples) {\n\treturn source->Skip(samples);\n}\n"
  },
  {
    "path": "avs_core/filters/AviSource/VD_Audio.h",
    "content": "//\tVirtualDub - Video processing and capture application\n//\tCopyright (C) 1998-2001 Avery Lee\n//\n//\tThis program is free software; you can redistribute it and/or modify\n//\tit under the terms of the GNU General Public License as published by\n//\tthe Free Software Foundation; either version 2 of the License, or\n//\t(at your option) any later version.\n//\n//\tThis program is distributed in the hope that it will be useful,\n//\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n//\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//\tGNU General Public License for more details.\n//\n//\tYou should have received a copy of the GNU General Public License\n//\talong with this program; if not, write to the Free Software\n//\tFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n#ifndef f_AUDIO_H\n#define f_AUDIO_H\n\n#include <avs/win.h>\n#include <vfw.h>\n//#include \"FrameSubset.h\"      // no need for this in avisynth\n\ntypedef void (*AudioFormatConverter)(void *, void *, long);\ntypedef long (*AudioPointSampler)(void *, void *, long, long, long);\ntypedef long (*AudioUpSampler)(void *, void *, long, long, long);\ntypedef long (*AudioDownSampler)(void *, void *, long *, int, long, long, long);\n\nclass AudioSource;\n\n///////\n\nclass AudioStream {\nprotected:\n\tWAVEFORMATEX *format;\n\tlong format_len;\n\n\tAudioStream *source;\n\tlong samples_read;\n\tlong stream_len;\n\tlong stream_limit;\n\n\tAudioStream();\n\n\tWAVEFORMATEX *AllocFormat(long len);\npublic:\n\tvirtual ~AudioStream();\n\n\tvirtual WAVEFORMATEX *GetFormat();\n\tvirtual long GetFormatLen();\n\tvirtual long GetSampleCount();\n\tvirtual long GetLength();\n\n\tvirtual long _Read(void *buffer, long max_samples, long *lplBytes);\n\tvirtual long Read(void *buffer, long max_samples, long *lplBytes);\n\tvirtual bool Skip(long samples);\n\tvirtual void SetSource(AudioStream *source);\n\tvirtual void SetLimit(long limit);\n\tvirtual BOOL isEnd();\n\tvirtual BOOL _isEnd();\n};\n\nclass AudioStreamSource : public AudioStream {\nprivate:\n\tAudioSource *aSrc;\n\tWAVEFORMATEX *pwfexTempInput;\n\tlong cur_samp;\n\tlong end_samp;\n\tHACMSTREAM hACStream;\n\tACMSTREAMHEADER ashBuffer;\n\tvoid *inputBuffer;\n\tvoid *outputBuffer;\n\tchar *outputBufferPtr;\n\tlong lPreskip;\n\tbool fZeroRead;\n\tbool fStart;\n\n\tenum { INPUT_BUFFER_SIZE = 16384 };\n\npublic:\n\tAudioStreamSource(AudioSource *src, long first_sample, long max_sample, BOOL allow_decompression);\n\t~AudioStreamSource();\n\n\tlong _Read(void *buffer, long max_samples, long *lplBytes);\n\tbool Skip(long samples);\n\tbool Seek(long samples);\n\tBOOL _isEnd();\n};\n\nclass AudioStreamConverter : public AudioStream {\nprivate:\n\tAudioFormatConverter convRout;\n\tvoid *cbuffer;\n\tint bytesPerInputSample, bytesPerOutputSample;\n\tint offset;\n\n\tenum { BUFFER_SIZE=4096 };\n\npublic:\n\tAudioStreamConverter(AudioStream *src, bool to_16bit, bool to_stereo_or_right, bool single_only);\n\t~AudioStreamConverter();\n\n\tlong _Read(void *buffer, long max_samples, long *lplBytes);\n\tBOOL _isEnd();\n\n\tbool Skip(long);\n};\n\nclass AudioStreamResampler : public AudioStream {\nprivate:\n\tAudioPointSampler ptsampleRout;\n\tAudioUpSampler upsampleRout;\n\tAudioDownSampler dnsampleRout;\n\tvoid *cbuffer;\n\tint bytesPerSample;\n\tlong samp_frac;\n\tlong accum;\n\tint holdover;\n\tlong *filter_bank;\n\tint filter_width;\n\tbool fHighQuality;\n\n\tenum { BUFFER_SIZE=512 };\n\n\tlong Upsample(void *buffer, long samples, long *lplBytes);\n\tlong Downsample(void *buffer, long samples, long *lplBytes);\n\npublic:\n\tAudioStreamResampler(AudioStream *source, long new_rate, bool integral_rate, bool high_quality);\n\t~AudioStreamResampler();\n\n\tlong _Read(void *buffer, long max_samples, long *lplBytes);\n\tBOOL _isEnd();\n};\n\nclass AudioCompressor : public AudioStream {\nprivate:\n\tHACMSTREAM hACStream;\n\tHACMDRIVER hADriver;\n\tACMSTREAMHEADER ashBuffer;\n\tWAVEFORMATEX *pwfexTempOutput;\n\tvoid *inputBuffer;\n\tvoid *outputBuffer;\n\t//char *outputBufferPtr;\n\tvoid *holdBuffer;\n\tlong holdBufferSize;\n\tlong holdBufferOffset;\n\tBOOL fStreamEnded;\n\tLONG bytesPerInputSample;\n\tLONG bytesPerOutputSample;\n\n\tenum { INPUT_BUFFER_SIZE = 16384 };\n\n\tvoid\tResizeHoldBuffer(long lNewSize);\n\tvoid\tWriteToHoldBuffer(void *data, long lBytes);\n\npublic:\n\tAudioCompressor(AudioStream *src, WAVEFORMATEX *dst_format, long dst_format_len);\n\t~AudioCompressor();\n\tvoid CompensateForMP3();\n\tvoid *\tCompress(long lInputSamples, long *lplSrcInputSamples, long *lplOutputBytes, long *lplOutputSamples);\n\tBOOL\tisEnd();\n};\n\nclass AudioL3Corrector {\nprivate:\n\tlong samples, frame_bytes, read_left;\n\tbool header_mode;\n\tchar hdr_buffer[4];\n\npublic:\n\tAudioL3Corrector();\n\tlong ComputeByterate(long sample_rate);\n\tvoid Process(void *buffer, long bytes);\n};\n/*\nclass AudioSubset : public AudioStream {\nprivate:\n\tFrameSubset subset;\n\tFrameSubsetNode *pfsnCur;\n\tint iOffset;\n\tlong lSrcPos;\n\tlong lSkipSize;\n\n\tchar skipBuffer[512];\n\npublic:\n\tAudioSubset(AudioStream *, FrameSubset *, long, long);\n\t~AudioSubset();\n\tlong _Read(void *, long, long *);\n\tBOOL _isEnd();\n};\n*/\nclass AudioStreamAmplifier : public AudioStream {\nprivate:\n\tlong lFactor;\n\npublic:\n\tAudioStreamAmplifier(AudioStream *src, long lFactor);\n\t~AudioStreamAmplifier();\n\n\tlong _Read(void *buffer, long max_samples, long *lplBytes);\n\tBOOL _isEnd();\n\tbool Skip(long);\n};\n\n//long AudioTranslateVideoSubset(FrameSubset& dst, FrameSubset& src, long usPerFrame, WAVEFORMATEX *pwfex);\n\n#endif\n"
  },
  {
    "path": "avs_core/filters/AviSource/avi_source.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include <avisynth.h>\n#include \"../../convert/convert.h\"\n#include \"../../filters/transform.h\"\n#include \"../../core/alignplanar.h\"\n#include \"../../core/strings.h\"\n#include \"AudioSource.h\"\n#include \"VD_Audio.h\"\n#include \"AVIReadHandler.h\"\n#include \"avi_source.h\"\n#include <vfw.h>\n#include <avs/minmax.h>\n#ifdef INTEL_INTRINSICS\n\n// Intrinsics base header + really required extension headers\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n\n#endif\n#include <string>\n#include <sstream>\n\n#include \"../../core/AviHelper.h\"\n\nstatic void __cdecl free_buffer(void* buff, IScriptEnvironment* env)\n{\n  if (buff)\n    static_cast<IScriptEnvironment2*>(env)->Free(buff);\n}\n\nTemporalBuffer::TemporalBuffer(const VideoInfo& vi, bool bMediaPad,\n  AVI_SpecialFormats specf,\n  IScriptEnvironment* env)\n{\n  int heightY = vi.height;\n  int heightUV = (vi.pixel_type & VideoInfo::CS_INTERLEAVED) ? 0 : heightY >> vi.GetPlaneHeightSubsampling(PLANAR_U);\n\n  if (specf == AVI_SpecialFormats::Y410)\n  { // Y410 packed 4444 U,Y,V,A\n    // This format is a packed 10-bit representation that includes 2 bits of alpha.\n    // Bits 0 - 9 contain the U sample, bits 10 - 19 contain the Y sample, bits 20 - 29 contain the V sample, \n    // and bits 30 - 31 contain the alpha value.\n    // To indicate that a pixel is fully opaque, an application must set the two alpha bits equal to 0x03.\n    pitchY = vi.width * sizeof(uint32_t) ; // n/a\n    pitchUV = 0;\n  }\n  else if (specf == AVI_SpecialFormats::Y416)\n  { // Y416 packed 4444 U,Y,V,A\n    // image_size = vi->width * vi->height * 4 * sizeof(uint16_t);\n    pitchY = vi.width * 4 * sizeof(uint16_t); // n/a\n    pitchUV = 0;\n  }\n  else if (specf == AVI_SpecialFormats::v308)\n  { // v308 packed 444\n    // image_size = vi->width * vi->height * 3 * sizeof(uint8_t);\n    pitchY = vi.width * 3; // n/a\n    pitchUV = 0;\n  }\n  else if (specf == AVI_SpecialFormats::v408)\n  { // v408 packed 4444\n    // image_size = vi->width * vi->height * 4 * sizeof(uint8_t);\n    pitchY = vi.width * 4; // n/a\n    pitchUV = 0;\n  }\n  else if (specf == AVI_SpecialFormats::v410)\n  { // v410 packed 444 U,Y,V\n    // image_size = vi->width * vi->height * 4 (32 bit holds 3x10 bits);\n    pitchY = vi.width * 4; // n/a\n    pitchUV = 0;\n  }\n  else if (specf == AVI_SpecialFormats::v210) {\n    pitchY = ((16 * ((vi.width + 5) / 6) + 127) & ~127);\n    pitchUV = 0;\n  }\n  else if (specf == AVI_SpecialFormats::r210) {\n    pitchY = ((vi.width + 63) / 64) * 256;\n    pitchUV = 0;\n  }\n  else if (specf == AVI_SpecialFormats::R10k) {\n    pitchY = vi.width * 4;\n    pitchUV = 0;\n  }\n  else if (vi.IsPlanarRGB() || vi.IsPlanarRGBA()) {\n    pitchY = vi.RowSize();\n  }\n  else {\n    if (!bMediaPad) { // do not padding at all.\n      pitchY = vi.RowSize();\n      pitchUV = vi.RowSize(PLANAR_U);\n    }\n    else { // align 4bytes with minimum padding.\n      pitchY = (vi.RowSize() + 3) & ~3;\n      pitchUV = (vi.RowSize(PLANAR_U) + 3) & ~3;\n    }\n  }\n\n  size_t sizeY = pitchY * heightY;\n  size_t sizeUV = pitchUV * heightUV;\n  if(specf == AVI_SpecialFormats::r210 || \n    specf == AVI_SpecialFormats::R10k || \n    specf == AVI_SpecialFormats::Y416 || \n    specf == AVI_SpecialFormats::v410 || \n    specf == AVI_SpecialFormats::v210 || \n    specf == AVI_SpecialFormats::v308 || \n    specf == AVI_SpecialFormats::v408 ||\n    specf == AVI_SpecialFormats::Y410\n  )\n    size = sizeY;\n  else if (vi.IsPlanarRGB())\n    size = sizeY * 3;\n  else if (vi.IsPlanarRGBA())\n    size = sizeY * 4;\n  else\n    size = sizeY + 2 * sizeUV;\n\n  // maybe memcpy become fast by aligned start address.\n  orig = env->Allocate(size, FRAME_ALIGN, AVS_POOLED_ALLOC);\n  if (!orig)\n    env->ThrowError(\"AVISource: couldn't allocate temporal buffer.\");\n  env->AtExit(free_buffer, orig);\n\n  pY = reinterpret_cast<uint8_t*>(orig);\n  pA = nullptr;\n  if (vi.IsPlanarRGB() || vi.IsPlanarRGBA())\n  {\n    // pY: G\n    pU = pY + sizeY; // B\n    pV = pU + sizeY; // R\n    if (vi.IsPlanarRGBA())\n      pA = pV + sizeY; // A\n  } else if (vi.pixel_type & VideoInfo::CS_UPlaneFirst) {\n    pU = pY + sizeY;\n    pV = pU + sizeUV;\n  } else {\n    pV = pY + sizeY;\n    pU = pV + sizeUV;\n  }\n}\n\n// todo:\n// // 10-bit+ planar RGB\n/*\nmmioFOURCC('G', '3', 00, 10); // ffmpeg GBRP10LE\nmmioFOURCC('G', '3', 00, 12); // ffmpeg GBRP12LE\nmmioFOURCC('G', '3', 00, 14); // ffmpeg GBRP14LE\nmmioFOURCC('G', '3', 00, 16); // ffmpeg GBRP16LE\nmmioFOURCC('G', '4', 00, 10); // ffmpeg GBRAP10LE\nmmioFOURCC('G', '4', 00, 12); // ffmpeg GBRAP12LE\nmmioFOURCC('G', '4', 00, 14); // ffmpeg GBRAP14LE\nmmioFOURCC('G', '4', 00, 16); // ffmpeg GBRAP16LE\n*/\nstatic PVideoFrame AdjustFrameAlignment(TemporalBuffer* frame, const VideoInfo& vi, bool bInvertFrames,\n  AVI_SpecialFormats specf,\n  IScriptEnvironment* env)\n{\n    auto result = env->NewVideoFrame(vi);\n    // fixme: this is source filter, add frame properties if possible\n    BYTE* dstp = result->GetWritePtr();\n    int pitch = result->GetPitch();\n    int height = result->GetHeight();\n    if (bInvertFrames) { // write from bottom to top\n      dstp += pitch * (height - 1);\n      pitch = -pitch;\n    }\n\n    // From TemporalBuffer only frame->GetPtr() points to a proper Avisynth-aligned \n    // memory location. Other field like frame->GetPitch or frame->GetPtr(PLANAR_U)\n    // may not be mod16 aligned values!\n\n    switch(specf) {\n    case AVI_SpecialFormats::v210:\n      v210_to_yuv422p10(dstp, pitch, result->GetWritePtr(PLANAR_U), result->GetWritePtr(PLANAR_V), result->GetPitch(PLANAR_U),\n        frame->GetPtr(), vi.width, vi.height);\n      break;\n    case AVI_SpecialFormats::P210:\n    case AVI_SpecialFormats::P216:\n    case AVI_SpecialFormats::P010:\n    case AVI_SpecialFormats::P016:\n        Px10_16_to_yuv42xp10_16(dstp, pitch, result->GetWritePtr(PLANAR_U), result->GetWritePtr(PLANAR_V), result->GetPitch(PLANAR_U),\n          frame->GetPtr(), frame->GetPitch(), vi.width, vi.height, result->GetHeight(PLANAR_U),\n          specf == AVI_SpecialFormats::P016 || specf == AVI_SpecialFormats::P216, env);\n        break;\n    case AVI_SpecialFormats::Y416:\n      if(vi.pixel_type == VideoInfo::CS_YUVA444P16)\n        FromY416_c<true>(dstp, pitch, result->GetWritePtr(PLANAR_U), result->GetWritePtr(PLANAR_V), result->GetPitch(PLANAR_U),\n          result->GetWritePtr(PLANAR_A), result->GetPitch(PLANAR_A),\n          frame->GetPtr(), frame->GetPitch(), vi.width, vi.height);\n      else\n        FromY416_c<false>(dstp, pitch, result->GetWritePtr(PLANAR_U), result->GetWritePtr(PLANAR_V), result->GetPitch(PLANAR_U),\n          result->GetWritePtr(PLANAR_A), result->GetPitch(PLANAR_A),\n          frame->GetPtr(), frame->GetPitch(), vi.width, vi.height);\n      break;\n    case AVI_SpecialFormats::r210:\n      From_r210_c(result->GetWritePtr(PLANAR_R), result->GetWritePtr(PLANAR_G), result->GetWritePtr(PLANAR_B), result->GetPitch(PLANAR_G),\n        frame->GetPtr(), frame->GetPitch(), vi.width, vi.height);\n      break;\n    case AVI_SpecialFormats::R10k:\n      From_R10k_c(result->GetWritePtr(PLANAR_R), result->GetWritePtr(PLANAR_G), result->GetWritePtr(PLANAR_B), result->GetPitch(PLANAR_G),\n        frame->GetPtr(), frame->GetPitch(), vi.width, vi.height);\n      break;\n    case AVI_SpecialFormats::v410:\n      v410_to_yuv444p10(dstp, pitch, result->GetWritePtr(PLANAR_U), result->GetWritePtr(PLANAR_V), result->GetPitch(PLANAR_U),\n        frame->GetPtr(), vi.width, vi.height);\n      break;\n    case AVI_SpecialFormats::v308:\n      v308_to_yuv444p8(dstp, pitch, result->GetWritePtr(PLANAR_U), result->GetWritePtr(PLANAR_V), result->GetPitch(PLANAR_U),\n        frame->GetPtr(), vi.width, vi.height);\n      break;\n    case AVI_SpecialFormats::v408:\n      v408_to_yuva444p8(dstp, pitch, result->GetWritePtr(PLANAR_U), result->GetWritePtr(PLANAR_V), result->GetWritePtr(PLANAR_A), result->GetPitch(PLANAR_U), result->GetPitch(PLANAR_A),\n        frame->GetPtr(), vi.width, vi.height);\n      break;\n    case AVI_SpecialFormats::Y410:\n      if (vi.pixel_type == VideoInfo::CS_YUVA444P10)\n        FromY410_c<true>(dstp, pitch, result->GetWritePtr(PLANAR_U), result->GetWritePtr(PLANAR_V), result->GetPitch(PLANAR_U),\n          result->GetWritePtr(PLANAR_A), result->GetPitch(PLANAR_A),\n          frame->GetPtr(), frame->GetPitch(), vi.width, vi.height);\n      else\n        FromY410_c<false>(dstp, pitch, result->GetWritePtr(PLANAR_U), result->GetWritePtr(PLANAR_V), result->GetPitch(PLANAR_U),\n          result->GetWritePtr(PLANAR_A), result->GetPitch(PLANAR_A),\n          frame->GetPtr(), frame->GetPitch(), vi.width, vi.height);\n      break;\n    case AVI_SpecialFormats::b64a:\n    {\n      // BGRA <-> big endian ARGB with byte swap\n      uint8_t* pdst = dstp;\n\n      int srcpitch = frame->GetPitch(); // may not be mod16\n      const BYTE* src = frame->GetPtr();\n#ifdef INTEL_INTRINSICS\n      const bool ssse3 = (env->GetCPUFlags() & CPUF_SSSE3) != 0;\n      const bool sse2 = (env->GetCPUFlags() & CPUF_SSE2) != 0;\n      if (ssse3)\n        bgra_to_argbBE_ssse3(pdst, pitch, src, srcpitch, vi.width, vi.height);\n      else if (sse2)\n        bgra_to_argbBE_sse2(pdst, pitch, src, srcpitch, vi.width, vi.height);\n      else\n#endif // INTEL_INTRINSICS\n        bgra_to_argbBE_c(pdst, pitch, src, srcpitch, vi.width, vi.height);\n    }\n        break;\n    case AVI_SpecialFormats::b48r:\n    {\n      // BGR <-> 16 bits per component big-endian Red, Green and Blue with byte swap\n      uint8_t* pdst = dstp;\n\n      int srcpitch = frame->GetPitch();\n      const BYTE* src = frame->GetPtr();\n      // c only\n      bgr_to_rgbBE_c(pdst, pitch, src, srcpitch, vi.width, vi.height);\n    }\n    break;\n    default:\n        if (vi.IsPlanarRGB() || vi.IsPlanarRGBA()) {\n          env->BitBlt(result->GetWritePtr(PLANAR_G), result->GetPitch(PLANAR_G), frame->GetPtr(PLANAR_G), frame->GetPitch(PLANAR_G), result->GetRowSize(PLANAR_G), result->GetHeight(PLANAR_G));\n          env->BitBlt(result->GetWritePtr(PLANAR_B), result->GetPitch(PLANAR_B), frame->GetPtr(PLANAR_B), frame->GetPitch(PLANAR_B), result->GetRowSize(PLANAR_B), result->GetHeight(PLANAR_B));\n          env->BitBlt(result->GetWritePtr(PLANAR_R), result->GetPitch(PLANAR_R), frame->GetPtr(PLANAR_R), frame->GetPitch(PLANAR_R), result->GetRowSize(PLANAR_R), result->GetHeight(PLANAR_R));\n          if(vi.IsPlanarRGBA())\n            env->BitBlt(result->GetWritePtr(PLANAR_A), result->GetPitch(PLANAR_A), frame->GetPtr(PLANAR_A), frame->GetPitch(PLANAR_A), result->GetRowSize(PLANAR_A), result->GetHeight(PLANAR_A));\n        }\n        else {\n          env->BitBlt(dstp, pitch, frame->GetPtr(), frame->GetPitch(), result->GetRowSize(), result->GetHeight());\n          // when no U or V plane these do nothing\n          env->BitBlt(result->GetWritePtr(PLANAR_V), result->GetPitch(PLANAR_V), frame->GetPtr(PLANAR_V), frame->GetPitch(PLANAR_V), result->GetRowSize(PLANAR_V), result->GetHeight(PLANAR_V));\n          env->BitBlt(result->GetWritePtr(PLANAR_U), result->GetPitch(PLANAR_U), frame->GetPtr(PLANAR_U), frame->GetPitch(PLANAR_U), result->GetRowSize(PLANAR_U), result->GetHeight(PLANAR_U));\n        }\n    } // switch\n    return result;\n}\n\n#ifndef MSVC\nstatic __inline LRESULT\nICDecompressEx(HIC hic,DWORD dwFlags,LPBITMAPINFOHEADER lpbiSrc,LPVOID lpSrc,INT xSrc,INT ySrc,INT dxSrc,INT dySrc,LPBITMAPINFOHEADER lpbiDst,LPVOID lpDst,INT xDst,INT yDst,INT dxDst,INT dyDst)\n{\n  ICDECOMPRESSEX ic;\n  ic.dwFlags = dwFlags;\n  ic.lpbiSrc = lpbiSrc;\n  ic.lpSrc = lpSrc;\n  ic.xSrc = xSrc;\n  ic.ySrc = ySrc;\n  ic.dxSrc = dxSrc;\n  ic.dySrc = dySrc;\n  ic.lpbiDst = lpbiDst;\n  ic.lpDst = lpDst;\n  ic.xDst = xDst;\n  ic.yDst = yDst;\n  ic.dxDst = dxDst;\n  ic.dyDst = dyDst;\n  return ICSendMessage(hic,ICM_DECOMPRESSEX,(DWORD_PTR)&ic,sizeof(ic));\n}\n\nstatic __inline LRESULT\nICDecompressExBegin(HIC hic,DWORD dwFlags,LPBITMAPINFOHEADER lpbiSrc,LPVOID lpSrc,INT xSrc,INT ySrc,INT dxSrc,INT dySrc,LPBITMAPINFOHEADER lpbiDst,LPVOID lpDst,INT xDst,INT yDst,INT dxDst,INT dyDst)\n{\n  ICDECOMPRESSEX ic;\n  ic.dwFlags = dwFlags;\n  ic.lpbiSrc = lpbiSrc;\n  ic.lpSrc = lpSrc;\n  ic.xSrc = xSrc;\n  ic.ySrc = ySrc;\n  ic.dxSrc = dxSrc;\n  ic.dySrc = dySrc;\n  ic.lpbiDst = lpbiDst;\n  ic.lpDst = lpDst;\n  ic.xDst = xDst;\n  ic.yDst = yDst;\n  ic.dxDst = dxDst;\n  ic.dyDst = dyDst;\n  return ICSendMessage(hic,ICM_DECOMPRESSEX_BEGIN,(DWORD_PTR)&ic,sizeof(ic));\n}\n#endif // MSVC\n\nLRESULT AVISource::DecompressBegin(LPBITMAPINFOHEADER lpbiSrc, LPBITMAPINFOHEADER lpbiDst) {\n  if (!ex) {\n    LRESULT result = ICDecompressBegin(hic, lpbiSrc, lpbiDst);\n    if (result != ICERR_UNSUPPORTED)\n      return result;\n    else\n      ex = true;\n      // and fall thru\n  }\n  return ICDecompressExBegin(hic, 0,\n    lpbiSrc, 0, 0, 0, lpbiSrc->biWidth, lpbiSrc->biHeight,\n    lpbiDst, 0, 0, 0, lpbiDst->biWidth, lpbiDst->biHeight);\n}\n\nLRESULT AVISource::DecompressFrame(int n, bool preroll, IScriptEnvironment* env) {\n  AVS_UNUSED(env);\n  _RPT2(0,\"AVISource: Decompressing frame %d%s\\n\", n, preroll ? \" (preroll)\" : \"\");\n  BYTE* buf = frame->GetPtr();\n  long bytes_read;\n\n  if (!hic) {\n    bytes_read = long(frame->GetSize());\n    pvideo->Read(n, 1, buf, bytes_read, &bytes_read, NULL);\n    dropped_frame = !bytes_read;\n    if (dropped_frame) return ICERR_OK;  // If frame is 0 bytes (dropped), return instead of attempt decompressing as Vdub.\n  }\n  else {\n    bytes_read = srcbuffer_size;\n    LRESULT err = pvideo->Read(n, 1, srcbuffer, srcbuffer_size, &bytes_read, NULL);\n    while (err == AVIERR_BUFFERTOOSMALL || (err == 0 && !srcbuffer)) {\n      delete[] srcbuffer;\n      pvideo->Read(n, 1, 0, srcbuffer_size, &bytes_read, NULL);\n      srcbuffer_size = bytes_read;\n      srcbuffer = new BYTE[bytes_read + 16]; // Provide 16 hidden guard bytes for HuffYUV, Xvid, etc bug\n      err = pvideo->Read(n, 1, srcbuffer, srcbuffer_size, &bytes_read, NULL);\n    }\n    dropped_frame = !bytes_read;\n    if (dropped_frame) return ICERR_OK;  // If frame is 0 bytes (dropped), return instead of attempt decompressing as Vdub.\n\n    // Fill guard bytes with 0xA5's for Xvid bug\n    memset(srcbuffer + bytes_read, 0xA5, 16);\n    // and a Null terminator for good measure\n    srcbuffer[bytes_read + 15] = 0;\n\n    int flags = preroll ? ICDECOMPRESS_PREROLL : 0;\n    flags |= dropped_frame ? ICDECOMPRESS_NULLFRAME : 0;\n    flags |= !pvideo->IsKeyFrame(n) ? ICDECOMPRESS_NOTKEYFRAME : 0;\n    pbiSrc->biSizeImage = bytes_read;\n    LRESULT result = !ex ? ICDecompress(hic, flags, pbiSrc, srcbuffer, &biDst, buf)\n                         : ICDecompressEx(hic, flags, pbiSrc, srcbuffer,\n                                          0, 0, vi.width, vi.height, &biDst, buf,\n                                          0, 0, vi.width, vi.height);\n    if (result != ICERR_OK) return result;\n  }\n  return ICERR_OK;\n}\n\n\nvoid AVISource::CheckHresult(HRESULT hr, const char* msg, IScriptEnvironment* env) {\n  if (SUCCEEDED(hr)) return;\n  char buf[1024] = {0};\n  if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, hr, 0, buf, 1024, NULL))\n    wsprintf(buf, \"error code 0x%x\", hr);\n  env->ThrowError(\"AVISource: %s:\\n%s\", msg, buf);\n}\n\n\n// taken from VirtualDub\nbool AVISource::AttemptCodecNegotiation(DWORD fccHandler, BITMAPINFOHEADER* bmih) {\n\n    // Try the handler specified in the file first.  In some cases, it'll\n  // be wrong or missing.\n\n  if (fccHandler)\n    hic = ICOpen(ICTYPE_VIDEO, fccHandler, ICMODE_DECOMPRESS);\n\n  if (!hic || ICERR_OK!=ICDecompressQuery(hic, bmih, NULL)) {\n    if (hic)\n      ICClose(hic);\n\n    // Pick a handler based on the biCompression field instead.\n\n    hic = ICOpen(ICTYPE_VIDEO, bmih->biCompression, ICMODE_DECOMPRESS);\n\n    if (!hic || ICERR_OK!=ICDecompressQuery(hic, bmih, NULL)) {\n      if (hic)\n        ICClose(hic);\n\n      // This never seems to work...\n\n      hic = ICLocate(ICTYPE_VIDEO, 0, bmih, NULL, ICMODE_DECOMPRESS);\n    }\n  }\n\n    return !!hic;\n}\n\nstatic std::string fourCCtoString(DWORD fourCC) {\n  std::ostringstream oss;\n  for (int i = 0; i < 4; i++) {\n    uint8_t b = fourCC & 0xFF;\n    fourCC >>= 8;\n    if (b < 32)\n      oss << \"[\" << std::to_string(b) << \"]\";\n    else\n      oss << char(b);\n  }\n  return oss.str();\n}\n\nvoid AVISource::LocateVideoCodec(const char fourCC[], IScriptEnvironment* env) {\n  AVISTREAMINFO asi;\n  CheckHresult(pvideo->Info(&asi, sizeof(asi)), \"couldn't get video info\", env);\n  long size = sizeof(BITMAPINFOHEADER);\n\n  // Read video format.  If it's a\n  // type-1 DV, we're going to have to fake it.\n\n  if (bIsType1) {\n    pbiSrc = (BITMAPINFOHEADER *)malloc(size);\n    if (!pbiSrc) env->ThrowError(\"AviSource: Could not allocate BITMAPINFOHEADER.\");\n\n    pbiSrc->biSize      = sizeof(BITMAPINFOHEADER);\n    pbiSrc->biWidth     = 720;\n\n    if (asi.dwRate > asi.dwScale*26LL)\n      pbiSrc->biHeight      = 480;\n    else\n      pbiSrc->biHeight      = 576;\n\n    pbiSrc->biPlanes      = 1;\n    pbiSrc->biBitCount    = 24;\n    pbiSrc->biCompression = MAKEFOURCC('d','v','s','d'); // 'dsvd';\n    pbiSrc->biSizeImage   = asi.dwSuggestedBufferSize;\n    pbiSrc->biXPelsPerMeter = 0;\n    pbiSrc->biYPelsPerMeter = 0;\n    pbiSrc->biClrUsed     = 0;\n    pbiSrc->biClrImportant  = 0;\n\n  } else {\n    CheckHresult(pvideo->ReadFormat(0, 0, &size), \"couldn't get video format size\", env);\n    pbiSrc = (LPBITMAPINFOHEADER)malloc(size);\n    CheckHresult(pvideo->ReadFormat(0, pbiSrc, &size), \"couldn't get video format\", env);\n  }\n\n  vi.width = pbiSrc->biWidth;\n  vi.height = pbiSrc->biHeight < 0 ? -pbiSrc->biHeight : pbiSrc->biHeight;\n  vi.SetFPS(asi.dwRate, asi.dwScale);\n  vi.num_frames = asi.dwLength;\n\n  bool overridden = false;\n\n  // try the requested decoder, if specified\n  if (fourCC != NULL /*&& strlen(fourCC) == 4*/) { // no strlen! fourCC can contain zeros as well\n    DWORD fcc = fourCC[0] | (fourCC[1] << 8) | (fourCC[2] << 16) | (fourCC[3] << 24);\n    if (pbiSrc->biCompression != fcc)\n      overridden = true;\n    asi.fccHandler = pbiSrc->biCompression = fcc;\n  }\n\n  // see if we can handle the video format directly\n  // when recognizing these formats in input fourCC, use them directly\n  // Note: forced overrides may not work\n\n  // check for only basic formats only. Known formats with special unpackers are handled outside.\n  if (pbiSrc->biCompression == MAKEFOURCC('Y', 'U', 'Y', '2')) { // :FIXME: Handle UYVY, etc\n    vi.pixel_type = VideoInfo::CS_YUY2;\n  } else if (pbiSrc->biCompression == MAKEFOURCC('Y', 'V', '1', '2')) {\n    vi.pixel_type = VideoInfo::CS_YV12;\n  } else if (pbiSrc->biCompression == MAKEFOURCC('I', '4', '2', '0')) {\n    vi.pixel_type = VideoInfo::CS_I420;\n  } else if (pbiSrc->biCompression == BI_RGB && pbiSrc->biBitCount == 32) {\n    vi.pixel_type = VideoInfo::CS_BGR32;\n  } else if (pbiSrc->biCompression == BI_RGB && pbiSrc->biBitCount == 24) {\n    vi.pixel_type = VideoInfo::CS_BGR24;\n  } else if (pbiSrc->biCompression == MAKEFOURCC('G', 'R', 'E', 'Y')) {\n    vi.pixel_type = VideoInfo::CS_Y8;\n  } else if (pbiSrc->biCompression == MAKEFOURCC('Y', '8', '0', '0')) {\n    vi.pixel_type = VideoInfo::CS_Y8;\n  } else if (pbiSrc->biCompression == MAKEFOURCC('Y', '8', ' ', ' ')) {\n    vi.pixel_type = VideoInfo::CS_Y8;\n  } else if (pbiSrc->biCompression == MAKEFOURCC('Y', 'V', '2', '4')) {\n    vi.pixel_type = VideoInfo::CS_YV24;\n  } else if (pbiSrc->biCompression == MAKEFOURCC('Y', 'V', '1', '6')) {\n    vi.pixel_type = VideoInfo::CS_YV16;\n  } else if (pbiSrc->biCompression == MAKEFOURCC('Y', '4', '1', 'B')) {\n    vi.pixel_type = VideoInfo::CS_YV411;\n  }\n  else if (pbiSrc->biCompression == MAKEFOURCC('B', 'R', 'A', 64)) { // BRA@ ie. BRA[64]\n    vi.pixel_type = VideoInfo::CS_BGR64;\n  }\n  else if (pbiSrc->biCompression == MAKEFOURCC('b', '6', '4', 'a')) { // b64a\n    vi.pixel_type = VideoInfo::CS_BGR64;\n  }\n  else if (pbiSrc->biCompression == MAKEFOURCC('B', 'G', 'R', 48)) { // BGR0 ie. BGR[48]\n    vi.pixel_type = VideoInfo::CS_BGR48;\n  }\n  else if (pbiSrc->biCompression == MAKEFOURCC('b', '4', '8', 'r')) { // b48r\n    vi.pixel_type = VideoInfo::CS_BGR48;\n  }\n  else if (pbiSrc->biCompression == MAKEFOURCC('v', '2', '1', '0')) { // v210\n    vi.pixel_type = VideoInfo::CS_YUV422P10;\n  }\n  else if (pbiSrc->biCompression == MAKEFOURCC('P', '2', '1', '0')) { // P210\n    vi.pixel_type = VideoInfo::CS_YUV422P10;\n  }\n  else if (pbiSrc->biCompression == MAKEFOURCC('P', '0', '1', '0')) { // P010\n    vi.pixel_type = VideoInfo::CS_YUV420P10;\n  }\n  else if (pbiSrc->biCompression == MAKEFOURCC('P', '0', '1', '6')) { // P016\n    vi.pixel_type = VideoInfo::CS_YUV420P16;\n  }\n  else if (pbiSrc->biCompression == MAKEFOURCC('P', '2', '1', '6')) { // P216\n    vi.pixel_type = VideoInfo::CS_YUV422P16;\n  }\n  else if (pbiSrc->biCompression == MAKEFOURCC('v', '4', '1', '0')) { // v410\n    vi.pixel_type = VideoInfo::CS_YUV444P10;\n  }\n  else if (pbiSrc->biCompression == MAKEFOURCC('Y', '4', '1', '6')) { // Y416\n    vi.pixel_type = VideoInfo::CS_YUV444P16;\n    // FIXME/Decide: Y416 contains alpha, we ignore it now\n  }\n  else if (pbiSrc->biCompression == MAKEFOURCC('r', '2', '1', '0')) { // r210\n    vi.pixel_type = VideoInfo::CS_RGBP10;\n  }\n  else if (pbiSrc->biCompression == MAKEFOURCC('R', '1', '0', 'k')) { // R10k\n    vi.pixel_type = VideoInfo::CS_RGBP10;\n  }\n  else if (pbiSrc->biCompression == MAKEFOURCC('v', '3', '0', '8')) { // v308\n    vi.pixel_type = VideoInfo::CS_YV24;\n  }\n  else if (pbiSrc->biCompression == MAKEFOURCC('v', '4', '0', '8')) { // v408\n    vi.pixel_type = VideoInfo::CS_YUVA444;\n  }\n  else if (pbiSrc->biCompression == MAKEFOURCC('Y', '4', '1', '0')) { // Y410\n    vi.pixel_type = VideoInfo::CS_YUVA444P10;\n    // Y410 contains a 2 bit alpha, so we use YUVA\n  } else {\n    // otherwise, find someone who will decompress it\n    switch(pbiSrc->biCompression) {\n    case MAKEFOURCC('M','P','4','3'):    // Microsoft MPEG-4 V3 '34PM'\n    case MAKEFOURCC('D','I','V','3'):    // \"DivX Low-Motion\" (4.10.0.3917) '3VID'\n    case MAKEFOURCC('D','I','V','4'):    // \"DivX Fast-Motion\" (4.10.0.3920) 4VID'\n    case MAKEFOURCC('A','P','4','1'):    // \"AngelPotion Definitive\" (4.0.00.3688) '14PA'\n      if (AttemptCodecNegotiation(asi.fccHandler, pbiSrc)) return;\n      pbiSrc->biCompression = MAKEFOURCC('M', 'P', '4', '3');\n      if (AttemptCodecNegotiation(asi.fccHandler, pbiSrc)) return;\n      pbiSrc->biCompression = MAKEFOURCC('D', 'I', 'V', '3');\n      if (AttemptCodecNegotiation(asi.fccHandler, pbiSrc)) return;\n      pbiSrc->biCompression = MAKEFOURCC('D', 'I', 'V', '4');\n      if (AttemptCodecNegotiation(asi.fccHandler, pbiSrc)) return;\n      pbiSrc->biCompression = MAKEFOURCC('A', 'P', '4', '1');\n    default:\n      if (AttemptCodecNegotiation(asi.fccHandler, pbiSrc)) return;\n    }\n    auto fourCCstr = fourCCtoString(asi.fccHandler);\n    const char *s = fourCCstr.c_str();\n    env->SaveString(s);\n    env->ThrowError(\"AVISource: couldn't locate a decompressor for fourcc %s\", s);\n  }\n  if (!overridden) return;\n  if (AttemptCodecNegotiation(asi.fccHandler, pbiSrc)) return;\n  // note: it is possible that fourCC G3[0][10] cannot be negotiated\n  // but if e.g. M0RG is negotiated here, the driver can support G3[0][10] later in icDecompressQuery\n  auto fourCCstr = fourCCtoString(asi.fccHandler);\n  const char* s = fourCCstr.c_str();\n  env->SaveString(s);\n  env->ThrowError(\"AVISource: couldn't locate a decompressor for overridden fourcc %s\", s);\n}\n\nstatic bool setInternalFormat_b64a(VideoInfo& vi, HIC& hic, BITMAPINFOHEADER* pbiSrc, BITMAPINFOHEADER* biDst, DWORD fourCC, int pixel_type) {\n  vi.pixel_type = pixel_type;\n  biDst->biSizeImage = vi.BMPSize();\n  biDst->biCompression = fourCC; // BRA@ ie. BRA[64]\n  biDst->biBitCount = 64;\n  if (hic == nullptr) return true;\n  return (ICERR_OK == ICDecompressQuery(hic, pbiSrc, biDst));\n}\n\nstatic bool setInternalFormat_BRA64(VideoInfo& vi, HIC& hic, BITMAPINFOHEADER* pbiSrc, BITMAPINFOHEADER* biDst, DWORD fourCC, int pixel_type) {\n  vi.pixel_type = pixel_type;\n  biDst->biSizeImage = vi.BMPSize();\n  biDst->biCompression = fourCC; // BRA@ ie. BRA[64]\n  biDst->biBitCount = 64;\n  if (hic == nullptr) return true;\n  return (ICERR_OK == ICDecompressQuery(hic, pbiSrc, biDst));\n}\n\nstatic bool setInternalFormat_BGR48(VideoInfo& vi, HIC& hic, BITMAPINFOHEADER* pbiSrc, BITMAPINFOHEADER* biDst, DWORD fourCC, int pixel_type) {\n  vi.pixel_type = pixel_type;\n  biDst->biSizeImage = vi.BMPSize();\n  biDst->biCompression = fourCC; // BGR0 ie. BGR48[64]\n  biDst->biBitCount = 48;\n  if (hic == nullptr) return true;\n  return (ICERR_OK == ICDecompressQuery(hic, pbiSrc, biDst));\n}\n\nstatic bool setInternalFormat_b48r(VideoInfo& vi, HIC& hic, BITMAPINFOHEADER* pbiSrc, BITMAPINFOHEADER* biDst, DWORD fourCC, int pixel_type) {\n  vi.pixel_type = pixel_type;\n  biDst->biSizeImage = vi.BMPSize();\n  biDst->biCompression = fourCC; // BGR0 ie. BGR48[64]\n  biDst->biBitCount = 48;\n  if (hic == nullptr) return true;\n  return (ICERR_OK == ICDecompressQuery(hic, pbiSrc, biDst));\n}\n\nstatic bool setInternalFormat_v210(VideoInfo& vi, HIC& hic, BITMAPINFOHEADER* pbiSrc, BITMAPINFOHEADER* biDst, DWORD fourCC, int pixel_type) {\n  vi.pixel_type = pixel_type;\n  biDst->biSizeImage = AviHelper_ImageSize(&vi, false, true, false, false, false, false, false, false);\n  biDst->biCompression = fourCC; // v210 (422P10)\n  biDst->biBitCount = 30;\n  if (hic == nullptr) return true;\n  return (ICERR_OK == ICDecompressQuery(hic, pbiSrc, biDst));\n}\n\nstatic bool setInternalFormat_P210(VideoInfo& vi, HIC& hic, BITMAPINFOHEADER* pbiSrc, BITMAPINFOHEADER* biDst, DWORD fourCC, int pixel_type) {\n  vi.pixel_type = pixel_type;\n  biDst->biSizeImage = vi.BMPSize();\n  biDst->biCompression = fourCC; // P210 (422P10)\n  biDst->biBitCount = 30; // should be 30, not 10+(10+10)/2\n  if (hic == nullptr) return true;\n  return (ICERR_OK == ICDecompressQuery(hic, pbiSrc, biDst));\n}\n\nstatic bool setInternalFormat_P010(VideoInfo& vi, HIC& hic, BITMAPINFOHEADER* pbiSrc, BITMAPINFOHEADER* biDst, DWORD fourCC, int pixel_type) {\n  vi.pixel_type = pixel_type;\n  biDst->biSizeImage = vi.BMPSize();\n  biDst->biCompression = fourCC; // P010 (420P10)\n  biDst->biBitCount = 15; // 10+(10+10)/4 or 3x10?\n  if (hic == nullptr) return true;\n  return (ICERR_OK == ICDecompressQuery(hic, pbiSrc, biDst));\n}\n\nstatic bool setInternalFormat_P016(VideoInfo& vi, HIC& hic, BITMAPINFOHEADER* pbiSrc, BITMAPINFOHEADER* biDst, DWORD fourCC, int pixel_type) {\n  vi.pixel_type = pixel_type;\n  biDst->biSizeImage = vi.BMPSize();\n  biDst->biCompression = fourCC; // P016 (420P16)\n  biDst->biBitCount = 24; // 16+(16+16)/4 or 3x16?\n  if (hic == nullptr) return true;\n  return (ICERR_OK == ICDecompressQuery(hic, pbiSrc, biDst));\n}\n\nstatic bool setInternalFormat_Y416(VideoInfo& vi, HIC& hic, BITMAPINFOHEADER* pbiSrc, BITMAPINFOHEADER* biDst, DWORD fourCC, int pixel_type) {\n  vi.pixel_type = pixel_type;\n  biDst->biSizeImage = vi.BMPSize();\n  biDst->biCompression = fourCC; // Y416 (444P16)\n  biDst->biBitCount = 48; // 3x16?\n  if (hic == nullptr) return true;\n  return (ICERR_OK == ICDecompressQuery(hic, pbiSrc, biDst));\n}\n\nstatic bool setInternalFormat_Y410(VideoInfo& vi, HIC& hic, BITMAPINFOHEADER* pbiSrc, BITMAPINFOHEADER* biDst, DWORD fourCC, int pixel_type) {\n  vi.pixel_type = pixel_type;\n  biDst->biSizeImage = AviHelper_ImageSize(&vi, false, false, false, false, false, false, false, true);\n  biDst->biCompression = fourCC; // Y410 (444P10)\n  biDst->biBitCount = 32; // 3x10+2?\n  if (hic == nullptr) return true;\n  return (ICERR_OK == ICDecompressQuery(hic, pbiSrc, biDst));\n}\n\nstatic bool setInternalFormat_P216(VideoInfo& vi, HIC& hic, BITMAPINFOHEADER* pbiSrc, BITMAPINFOHEADER* biDst, DWORD fourCC, int pixel_type) {\n  vi.pixel_type = pixel_type;\n  biDst->biSizeImage = vi.BMPSize();\n  biDst->biCompression = fourCC; // P216 (422P16)\n  biDst->biBitCount = 32; // 16+(16+16)/2 or 3x16?\n  if (hic == nullptr) return true;\n  return (ICERR_OK == ICDecompressQuery(hic, pbiSrc, biDst));\n}\n\nstatic bool setInternalFormat_v410(VideoInfo& vi, HIC& hic, BITMAPINFOHEADER* pbiSrc, BITMAPINFOHEADER* biDst, DWORD fourCC, int pixel_type) {\n  vi.pixel_type = pixel_type;\n  biDst->biSizeImage = AviHelper_ImageSize(&vi, false, false, true, false, false, false, false, false);\n  biDst->biCompression = fourCC; // v410 (444P10)\n  biDst->biBitCount = 30; // 3x10?\n  if (hic == nullptr) return true;\n  return (ICERR_OK == ICDecompressQuery(hic, pbiSrc, biDst));\n}\n\nstatic bool setInternalFormat_r210(VideoInfo& vi, HIC& hic, BITMAPINFOHEADER* pbiSrc, BITMAPINFOHEADER* biDst, DWORD fourCC, int pixel_type) {\n  vi.pixel_type = pixel_type;\n  biDst->biSizeImage = AviHelper_ImageSize(&vi, false, false, false, true, false, false, false, false);\n  biDst->biCompression = fourCC; // r210 (RGBP10)\n  biDst->biBitCount = 30; // 3x10?\n  if (hic == nullptr) return true;\n  return (ICERR_OK == ICDecompressQuery(hic, pbiSrc, biDst));\n}\n\nstatic bool setInternalFormat_R10k(VideoInfo& vi, HIC& hic, BITMAPINFOHEADER* pbiSrc, BITMAPINFOHEADER* biDst, DWORD fourCC, int pixel_type) {\n  vi.pixel_type = pixel_type;\n  biDst->biSizeImage = AviHelper_ImageSize(&vi, false, false, false, false, true, false, false, false);\n  biDst->biCompression = fourCC; // R10k (RGBP10)\n  biDst->biBitCount = 30; // 3x10?\n  if (hic == nullptr) return true;\n  return (ICERR_OK == ICDecompressQuery(hic, pbiSrc, biDst));\n}\n\nstatic bool setInternalFormat_v308(VideoInfo& vi, HIC& hic, BITMAPINFOHEADER* pbiSrc, BITMAPINFOHEADER* biDst, DWORD fourCC, int pixel_type) {\n  vi.pixel_type = pixel_type;\n  biDst->biSizeImage = AviHelper_ImageSize(&vi, false, false, false, false, false, true, false, false);\n  biDst->biCompression = fourCC; // v308 (YV24 YUV444P8)\n  biDst->biBitCount = 24;\n  if (hic == nullptr) return true;\n  return (ICERR_OK == ICDecompressQuery(hic, pbiSrc, biDst));\n}\n\nstatic bool setInternalFormat_v408(VideoInfo& vi, HIC& hic, BITMAPINFOHEADER* pbiSrc, BITMAPINFOHEADER* biDst, DWORD fourCC, int pixel_type) {\n  vi.pixel_type = pixel_type;\n  biDst->biSizeImage = AviHelper_ImageSize(&vi, false, false, false, false, false, false, true, false);\n  biDst->biCompression = fourCC; // v408 (YUVA444P8)\n  biDst->biBitCount = 32;\n  if (hic == nullptr) return true;\n  return (ICERR_OK == ICDecompressQuery(hic, pbiSrc, biDst));\n}\n\nAVISource::AVISource(const char filename[], bool fAudio, const char pixel_type[], const char fourCC[], int vtrack, int atrack, avi_mode_e mode, bool utf8, IScriptEnvironment* env) {\n  srcbuffer = 0; srcbuffer_size = 0;\n  memset(&vi, 0, sizeof(vi));\n  ex = false;\n  last_frame_no = -1;\n  pbiSrc = 0;\n  aSrc = 0;\n  audioStreamSource = 0;\n  pvideo=0;\n  pfile=0;\n  bIsType1 = false;\n  hic = 0;\n  bInvertFrames = false;\n\n  specf = AVI_SpecialFormats::none;\n  bMediaPad = false;\n  frame = 0;\n\n  auto filename_w = utf8 ? Utf8ToWideChar(filename) : AnsiToWideChar(filename);\n  auto filename_utf8 = WideCharToUtf8(filename_w.get());\n  AVIFileInit();\n  try {\n\n    if (mode == MODE_NORMAL) {\n      // if it looks like an AVI file, open in OpenDML mode; otherwise AVIFile mode\n      HANDLE h = CreateFileW(filename_w.get(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);\n      if (h == INVALID_HANDLE_VALUE) {\n        env->ThrowError(\"AVISource autodetect: couldn't open file '%s'\\nError code: %d\", filename_utf8.get(), GetLastError());\n      }\n      unsigned int buf[3];\n      DWORD bytes_read;\n      if (ReadFile(h, buf, 12, &bytes_read, NULL) && bytes_read == 12 && buf[0] == MAKEFOURCC('R','I','F','F') && buf[2] == MAKEFOURCC('A','V','I',' '))\n        mode = MODE_OPENDML;\n      else\n        mode = MODE_AVIFILE;\n      CloseHandle(h);\n    }\n\n    if (mode == MODE_AVIFILE || mode == MODE_WAV) {    // AVIFile mode\n      PAVIFILE paf = NULL;\n      try { // The damn .WAV clsid handler has only a 48 byte buffer to parse the filename and GPF's\n    if (FAILED(AVIFileOpenW(&paf, filename_w.get(), OF_READ, 0)))\n      env->ThrowError(\"AVIFileSource: couldn't open file '%s'\", filename_utf8.get());\n      }\n    catch (AvisynthError) {\n    throw;\n    }\n    catch (...) {\n    env->ThrowError(\"AVIFileSource: VFW failure, AVIFileOpen(%s), length of filename part must be < 48\", filename);\n    }\n    pfile = CreateAVIReadHandler(paf);\n    } else {              // OpenDML mode\n      pfile = CreateAVIReadHandler(filename_w.get());\n    }\n\n    if (mode != MODE_WAV) { // check for video stream\n      pvideo = pfile->GetStream(streamtypeVIDEO, vtrack);\n\n      if (!pvideo) { // Attempt DV type 1 video.\n        pvideo = pfile->GetStream(MAKEFOURCC('i','a','v','s'), vtrack);\n        bIsType1 = true;\n      }\n\n      if (pvideo) {\n        // accept code-in-the-bracker style like G4[0][16]\n        bool inBracket = false;\n        char buf[4+1];\n        int len = 0;\n        char ch;\n        int number = 0;\n        const char* fc = fourCC;\n        while ((ch = *fc++)) {\n          if (len == 4)\n            env->ThrowError(\"Avisource: fourCC must be four characters\");\n          if (ch == '[') {\n            if (inBracket)\n              env->ThrowError(\"Avisource: fourCC syntax error: unexpected [\");\n            inBracket = true;\n            number = 0;\n            continue;\n          }\n          if (ch == ']') {\n            if (!inBracket)\n              env->ThrowError(\"Avisource: fourCC syntax error: unexpected ]\");\n            buf[len++] = number;\n            inBracket = false;\n            continue;\n          }\n          if (inBracket) {\n            if(!isdigit(ch))\n              env->ThrowError(\"Avisource: fourCC parsing: only numbers allowed inside brackets\");\n            number = number * 10 + (ch - '0');\n            if (number>255)\n              env->ThrowError(\"Avisource: fourCC parsing: maximum code cannot exceed 255\");\n            continue;\n          }\n          buf[len++] =  ch;\n        }\n        if (inBracket)\n          env->ThrowError(\"Avisource: fourCC syntax error: unclosed [\");\n        buf[len] = 0;\n\n        LocateVideoCodec(len == 0 ? nullptr : buf, env);\n        if (hic) {\n          if (pixel_type[0] == '+') {\n            pixel_type += 1;\n            bMediaPad = true;\n          }\n          bool forcedType = !(pixel_type[0] == 0);\n\n          bool fY8    = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"Y8\"   ) == 0;\n          bool fYV12  = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"YV12\" ) == 0;\n          bool fYV16  = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"YV16\" ) == 0;\n          bool fYV24  = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"YV24\" ) == 0;\n          bool fv308  = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"v308\") == 0;\n          bool fv408  = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"v408\") == 0;\n\n          bool fYV411 = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"YV411\") == 0;\n          bool fYUY2  = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"YUY2\" ) == 0;\n          bool fRGB32 = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"RGB32\") == 0;\n          bool fRGB24 = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"RGB24\") == 0;\n          bool fRGB48 = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"RGB48\") == 0;\n          bool fRGB64 = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"RGB64\") == 0;\n\n          bool fYUV420P10 = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"YUV420P10\") == 0;\n          bool fP010 = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"P010\") == 0;\n\n          bool fYUV420P16 = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"YUV420P16\") == 0;\n          bool fP016 = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"P016\") == 0;\n\n          bool fYUV422P10 = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"YUV422P10\") == 0;\n          // we cannot know it beforehand, don't set it true if not specified, only generic YUV422P10 is valid\n          bool fv210 = lstrcmpi(pixel_type, \"v210\") == 0;\n          bool fP210 = lstrcmpi(pixel_type, \"P210\") == 0;\n\n          bool fYUV422P16 = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"YUV422P16\") == 0;\n          bool fP216 = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"P216\") == 0;\n\n          bool fYUV444P10 = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"YUV444P10\") == 0;\n          bool fv410 = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"v410\") == 0;\n          bool fY410 = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"Y410\") == 0;\n\n          bool fYUV444P16 = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"YUV444P16\") == 0;\n          bool fY416 = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"Y416\") == 0;\n\n          bool fRGBP = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"RGBP\") == 0; // RGBP means planar RGB 10-16\n          // FIXME: 8 bit planar RGB possible?\n          // FIXME: hint for RGBPA priority?\n          bool fGrayscale = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"Y\") == 0; // Y8-16\n\n          // special 10 bit RGB, multiple formats supported\n          bool fRGBP10 = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"RGBP10\") == 0;\n          bool fr210 = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"r210\") == 0;\n          bool fR10k = pixel_type[0] == 0 || lstrcmpi(pixel_type, \"R10k\") == 0;\n\n          // we don't set specifically v210, P010, P016, P210, P216, Y410, Y416, v308, v408 for auto.\n          // These are set only when negotiated\n          if (lstrcmpi(pixel_type, \"AUTO\") == 0) {\n            fY8 = fYV12 = fYUY2 = fRGB32 = fRGB24 = fRGB48 = fRGB64 = true;\n            fYUV420P10 = true;\n            fYUV420P16 = true;\n            fYUV422P10 = true;\n            fYUV422P16 = true;\n            fYUV444P10 = true;\n            fYUV444P16 = true;\n            fRGBP = true;\n            fRGBP10 = true;\n            fr210 = true;\n            fR10k = true;\n            fGrayscale = true;\n            forcedType = false;\n          }\n          else if (lstrcmpi(pixel_type, \"FULL\") == 0) {\n            fY8 = fYV12 = fYV16 = fYV24 = fYV411 = fYUY2 = fRGB32 = fRGB24 = fRGB48 = fRGB64 = true;\n            fYUV420P10 = true;\n            fYUV420P16 = true;\n            fYUV422P10 = true;\n            fYUV422P16 = true;\n            fYUV444P10 = true;\n            fYUV444P16 = true;\n            fRGBP = true;\n            fRGBP10 = true;\n            fr210 = true;\n            fR10k = true;\n            fGrayscale = true;\n            forcedType = false;\n          }\n\n          if (!(fY8 || fYV12 || fYV16 || fYV24 || fYV411 || fYUY2 || fRGB32 || fRGB24 || fRGB48 || fRGB64\n            || fv308 || fv408\n            || fYUV420P10 || fP010\n            || fYUV420P16 || fP016\n            || fYUV422P10 || fP210 || fv210\n            || fYUV422P16 || fP216\n            || fYUV444P10 || fv410 || fY410\n            || fYUV444P16 || fY416\n            || fRGBP\n            || fRGBP10\n            || fr210 || fR10k\n            || fGrayscale\n            ))\n            env->ThrowError(\"AVISource: requested format must be one of YV12/16/24, YV411, YUY2, Y8, Y, RGBP, RGBP10, r210, R10k, RGB24/32/48/64, YUV420P10/16, YUV422P10/16, YUV444P10/16, v210, P010/16, P210/16, v410, Y410, Y416, v308, v408, AUTO or FULL\");\n\n          // try to decompress to YV12, YV411, YV16, YV24, YUY2, Y8, RGB32, and RGB24, RGB48, RGB64, YUV422P10 in turn\n          memset(&biDst, 0, sizeof(BITMAPINFOHEADER));\n          biDst.biSize = sizeof(BITMAPINFOHEADER);\n          biDst.biWidth = vi.width;\n          biDst.biHeight = vi.height;\n          biDst.biPlanes = 1;\n          bool bOpen = true;\n\n          // YV24\n          if (fYV24 && bOpen) {\n            vi.pixel_type = VideoInfo::CS_YV24;\n            biDst.biSizeImage = vi.BMPSize();\n            biDst.biCompression = MAKEFOURCC('Y', 'V', '2', '4');\n            biDst.biBitCount = 24;\n            if (ICERR_OK == ICDecompressQuery(hic, pbiSrc, &biDst)) {\n              _RPT0(0,\"AVISource: Opening as YV24.\\n\");\n              bOpen = false;  // Skip further attempts\n            } else if (forcedType) {\n               env->ThrowError(\"AVISource: the video decompressor couldn't produce YV24 output\");\n            }\n          }\n\n          // YV16\n          if (fYV16 && bOpen) {\n            vi.pixel_type = VideoInfo::CS_YV16;\n            biDst.biSizeImage = vi.BMPSize();\n            biDst.biCompression = MAKEFOURCC('Y', 'V', '1', '6');\n            biDst.biBitCount = 16;\n            if (ICERR_OK == ICDecompressQuery(hic, pbiSrc, &biDst)) {\n              _RPT0(0,\"AVISource: Opening as YV16.\\n\");\n              bOpen = false;  // Skip further attempts\n            } else if (forcedType) {\n               env->ThrowError(\"AVISource: the video decompressor couldn't produce YV16 output\");\n            }\n          }\n\n          // YV12\n          if (fYV12 && bOpen) {\n            vi.pixel_type = VideoInfo::CS_YV12;\n            biDst.biSizeImage = vi.BMPSize();\n            biDst.biCompression = MAKEFOURCC('Y', 'V', '1', '2');\n            biDst.biBitCount = 12;\n            if (ICERR_OK == ICDecompressQuery(hic, pbiSrc, &biDst)) {\n              _RPT0(0,\"AVISource: Opening as YV12.\\n\");\n              bOpen = false;  // Skip further attempts\n            } else if (forcedType) {\n               env->ThrowError(\"AVISource: the video decompressor couldn't produce YV12 output\");\n            }\n          }\n\n// ::FIXME:: Is this the most appropriate order.  Not sure about YUY2 vrs YV411\n\n          // YV411\n          if (fYV411 && bOpen) {\n            vi.pixel_type = VideoInfo::CS_YV411;\n            biDst.biSizeImage = vi.BMPSize();\n            biDst.biCompression = MAKEFOURCC('Y', '4', '1', 'B');\n            biDst.biBitCount = 16;\n            if (ICERR_OK == ICDecompressQuery(hic, pbiSrc, &biDst)) {\n              _RPT0(0,\"AVISource: Opening as YV411.\\n\");\n              bOpen = false;  // Skip further attempts\n            } else if (forcedType) {\n               env->ThrowError(\"AVISource: the video decompressor couldn't produce YV411 output\");\n            }\n          }\n\n          // YUY2\n          if (fYUY2 && bOpen) {\n            vi.pixel_type = VideoInfo::CS_YUY2;\n            biDst.biSizeImage = vi.BMPSize();\n            biDst.biCompression = MAKEFOURCC('Y', 'U', 'Y', '2'); // :FIXME: Handle UYVY, etc\n            biDst.biBitCount = 16;\n            if (ICERR_OK == ICDecompressQuery(hic, pbiSrc, &biDst)) {\n              _RPT0(0,\"AVISource: Opening as YUY2.\\n\");\n              bOpen = false;  // Skip further attempts\n            } else if (forcedType) {\n               env->ThrowError(\"AVISource: the video decompressor couldn't produce YUY2 output\");\n            }\n          }\n\n          // RGBP 10 bit special\n          if ((fRGBP10 || fr210 || fR10k) && bOpen) {\n            if (fRGBP10 && bOpen) {\n              vi.pixel_type = VideoInfo::CS_RGBP10;\n              biDst.biSizeImage = vi.BMPSize();\n              biDst.biCompression = MAKEFOURCC('G', '3', 0, 10); // ffmpeg GBRP10LE\n              biDst.biBitCount = 30;\n              if (ICERR_OK == ICDecompressQuery(hic, pbiSrc, &biDst)) {\n                _RPT0(0, \"AVISource: Opening as G3[0][10].\\n\");\n                bOpen = false;  // Skip further attempts\n              }\n            }\n            if ((fRGBP10 || fr210) && bOpen) {\n              vi.pixel_type = VideoInfo::CS_RGBP10;\n              if (setInternalFormat_r210(vi, hic, pbiSrc, &biDst, MAKEFOURCC('r', '2', '1', '0'), VideoInfo::CS_RGBP10)) {\n                _RPT0(0, \"AVISource: Opening as r210.\\n\");\n                specf = AVI_SpecialFormats::r210;\n                bOpen = false;  // Skip further attempts\n              }\n            }\n            if ((fRGBP10 || fR10k) && bOpen) {\n              vi.pixel_type = VideoInfo::CS_RGBP10;\n              if (setInternalFormat_R10k(vi, hic, pbiSrc, &biDst, MAKEFOURCC('R', '1', '0', 'k'), VideoInfo::CS_RGBP10)) {\n                _RPT0(0, \"AVISource: Opening as R10k.\\n\");\n                specf = AVI_SpecialFormats::R10k;\n                bOpen = false;  // Skip further attempts\n              }\n            }\n            if (bOpen && forcedType) {\n              env->ThrowError(\"AVISource: the video decompressor couldn't produce Planar RGB 10 output\");\n            }\n          }\n\n          // \"RGBP\": this is a hint that planar RGB is preferred, no specific bit depth needed\n          if (fRGBP && bOpen) {\n            // FIXME: consider putting here G3[0][8] and G4[0][8]\n            vi.pixel_type = VideoInfo::CS_RGBP10;\n            biDst.biSizeImage = vi.BMPSize();\n            biDst.biCompression = MAKEFOURCC('G', '3', 0, 10); // ffmpeg GBRP10LE\n            biDst.biBitCount = 30;\n            if (ICERR_OK == ICDecompressQuery(hic, pbiSrc, &biDst)) {\n              _RPT0(0, \"AVISource: Opening as G3[0][10].\\n\");\n              bOpen = false;  // Skip further attempts\n            }\n            else {\n              vi.pixel_type = VideoInfo::CS_RGBP10;\n              if (setInternalFormat_r210(vi, hic, pbiSrc, &biDst, MAKEFOURCC('r', '2', '1', '0'), VideoInfo::CS_RGBP10)) {\n                _RPT0(0, \"AVISource: Opening as r210.\\n\");\n                specf = AVI_SpecialFormats::r210;\n                bOpen = false;  // Skip further attempts\n              }\n              else {\n                vi.pixel_type = VideoInfo::CS_RGBP10;\n                if (setInternalFormat_R10k(vi, hic, pbiSrc, &biDst, MAKEFOURCC('R', '1', '0', 'k'), VideoInfo::CS_RGBP10)) {\n                  _RPT0(0, \"AVISource: Opening as R10k.\\n\");\n                  specf = AVI_SpecialFormats::R10k;\n                  bOpen = false;  // Skip further attempts\n                }\n                else {\n                  vi.pixel_type = VideoInfo::CS_RGBP12;\n                  biDst.biCompression = MAKEFOURCC('G', '3', 0, 12); // ffmpeg GBRP12LE\n                  biDst.biBitCount = 36;\n                  if (ICERR_OK == ICDecompressQuery(hic, pbiSrc, &biDst)) {\n                    _RPT0(0, \"AVISource: Opening as G3[0][12].\\n\");\n                    bOpen = false;  // Skip further attempts\n                  }\n                  else {\n                    vi.pixel_type = VideoInfo::CS_RGBP14;\n                    biDst.biCompression = MAKEFOURCC('G', '3', 0, 14); // ffmpeg GBRP14LE\n                    biDst.biBitCount = 42;\n                    if (ICERR_OK == ICDecompressQuery(hic, pbiSrc, &biDst)) {\n                      _RPT0(0, \"AVISource: Opening as G3[0][14].\\n\");\n                      bOpen = false;  // Skip further attempts\n                    }\n                    else {\n                      vi.pixel_type = VideoInfo::CS_RGBP16;\n                      biDst.biCompression = MAKEFOURCC('G', '3', 0, 16); // ffmpeg GBRP16LE\n                      biDst.biBitCount = 48;\n                      if (ICERR_OK == ICDecompressQuery(hic, pbiSrc, &biDst)) {\n                        _RPT0(0, \"AVISource: Opening as G3[0][16].\\n\");\n                        bOpen = false;  // Skip further attempts\n                      }\n                      else {\n                        vi.pixel_type = VideoInfo::CS_RGBAP10;\n                        biDst.biSizeImage = vi.BMPSize();\n                        biDst.biCompression = MAKEFOURCC('G', '4', 0, 10); // ffmpeg GBRAP10LE\n                        biDst.biBitCount = 40; // FIXME: 4*10 = 40?\n                        if (ICERR_OK == ICDecompressQuery(hic, pbiSrc, &biDst)) {\n                          _RPT0(0, \"AVISource: Opening as G4[0][10].\\n\");\n                          bOpen = false;  // Skip further attempts\n                        }\n                        else {\n                          vi.pixel_type = VideoInfo::CS_RGBAP12;\n                          biDst.biCompression = MAKEFOURCC('G', '4', 0, 12); // ffmpeg GBRAP12LE\n                          biDst.biBitCount = 48; // FIXME: 4*12 = 48?\n                          if (ICERR_OK == ICDecompressQuery(hic, pbiSrc, &biDst)) {\n                            _RPT0(0, \"AVISource: Opening as G4[0][12].\\n\");\n                            bOpen = false;  // Skip further attempts\n                          }\n                          else {\n                            vi.pixel_type = VideoInfo::CS_RGBAP14;\n                            biDst.biCompression = MAKEFOURCC('G', '4', 0, 14); // ffmpeg GBRAP14LE\n                            biDst.biBitCount = 56; // FIXME: 4*14 = 56?\n                            if (ICERR_OK == ICDecompressQuery(hic, pbiSrc, &biDst)) {\n                              _RPT0(0, \"AVISource: Opening as G4[0][14].\\n\");\n                              bOpen = false;  // Skip further attempts\n                            }\n                            else {\n                              vi.pixel_type = VideoInfo::CS_RGBAP16;\n                              biDst.biCompression = MAKEFOURCC('G', '4', 0, 16); // ffmpeg GBRAP16LE\n                              biDst.biBitCount = 64; // FIXME: 4*16 = 64?\n                              if (ICERR_OK == ICDecompressQuery(hic, pbiSrc, &biDst)) {\n                                _RPT0(0, \"AVISource: Opening as G4[0][16].\\n\");\n                                bOpen = false;  // Skip further attempts\n                              }\n                              else\n                                if (forcedType) {\n                                  env->ThrowError(\"AVISource: the video decompressor couldn't produce Planar RGB(A) output\");\n                                }\n                            }\n                          }\n                        }\n                      }\n                    }\n                  }\n                }\n              }\n            }\n          }\n\n          // RGB32\n          if (fRGB32 && bOpen) {\n            vi.pixel_type = VideoInfo::CS_BGR32;\n            biDst.biSizeImage = vi.BMPSize();\n            biDst.biCompression = BI_RGB;\n            biDst.biBitCount = 32;\n            if (ICERR_OK == ICDecompressQuery(hic, pbiSrc, &biDst)) {\n              _RPT0(0,\"AVISource: Opening as RGB32.\\n\");\n              bOpen = false;  // Skip further attempts\n            } else if (forcedType) {\n               env->ThrowError(\"AVISource: the video decompressor couldn't produce RGB32 output\");\n            }\n          }\n\n          // RGB24\n          if (fRGB24 && bOpen) {\n            vi.pixel_type = VideoInfo::CS_BGR24;\n            biDst.biSizeImage = vi.BMPSize();\n            biDst.biCompression = BI_RGB;\n            biDst.biBitCount = 24;\n            if (ICERR_OK == ICDecompressQuery(hic, pbiSrc, &biDst)) {\n              _RPT0(0,\"AVISource: Opening as RGB24.\\n\");\n              bOpen = false;  // Skip further attempts\n            } else if (forcedType) {\n               env->ThrowError(\"AVISource: the video decompressor couldn't produce RGB24 output\");\n            }\n          }\n\n          // RGB48\n          if (fRGB48 && bOpen) {\n            if (setInternalFormat_BGR48(vi, hic, pbiSrc, &biDst, MAKEFOURCC('B', 'G', 'R', 48), VideoInfo::CS_BGR48)) {\n              _RPT0(0, \"AVISource: Opening as BGR0 (BGR[48]).\\n\");\n              bOpen = false;  // Skip further attempts\n            }\n            else {\n              // e.g. preferred by UT RGB 10 bits : UQRG\n              if (setInternalFormat_b48r(vi, hic, pbiSrc, &biDst, MAKEFOURCC('b', '4', '8', 'r'), VideoInfo::CS_BGR48)) {\n                _RPT0(0, \"AVISource: Opening as b48r.\\n\");\n                specf = AVI_SpecialFormats::b48r;\n                bOpen = false;  // Skip further attempts\n              }\n              else if (forcedType) {\n                env->ThrowError(\"AVISource: the video decompressor couldn't produce RGB48 output\");\n              }\n            }\n          }\n\n          // RGB64\n          if (fRGB64 && bOpen) {\n            if (setInternalFormat_BRA64(vi, hic, pbiSrc, &biDst, MAKEFOURCC('B', 'R', 'A', 64), VideoInfo::CS_BGR64)) {\n              _RPT0(0, \"AVISource: Opening as BRA@ (BRA[64]).\\n\");\n              bOpen = false;  // Skip further attempts\n            }\n            else {\n              if (setInternalFormat_b64a(vi, hic, pbiSrc, &biDst, MAKEFOURCC('b', '6', '4', 'a'), VideoInfo::CS_BGR64)) {\n                _RPT0(0, \"AVISource: Opening as b64a.\\n\");\n                bOpen = false;  // Skip further attempts\n                specf = AVI_SpecialFormats::b64a;\n              }\n              else\n                if (forcedType) {\n                  env->ThrowError(\"AVISource: the video decompressor couldn't produce RGB64 output\");\n                }\n            }\n          }\n\n          // Y8\n          if ((fY8 || fGrayscale) && bOpen) {\n            vi.pixel_type = VideoInfo::CS_Y8;\n            biDst.biSizeImage = vi.BMPSize();\n            biDst.biCompression = MAKEFOURCC('Y', '8', '0', '0');\n            biDst.biBitCount = 8;\n            if (ICERR_OK == ICDecompressQuery(hic, pbiSrc, &biDst)) {\n              _RPT0(0,\"AVISource: Opening as Y800.\\n\");\n              bOpen = false;  // Skip further attempts\n            } else {\n              biDst.biCompression = MAKEFOURCC('Y', '8', ' ', ' ');\n              if (ICERR_OK == ICDecompressQuery(hic, pbiSrc, &biDst)) {\n                _RPT0(0,\"AVISource: Opening as Y8.\\n\");\n                bOpen = false;  // Skip further attempts\n              } else {\n                biDst.biCompression = MAKEFOURCC('G', 'R', 'E', 'Y');\n                if (ICERR_OK == ICDecompressQuery(hic, pbiSrc, &biDst)) {\n                  _RPT0(0,\"AVISource: Opening as GREY.\\n\");\n                  bOpen = false;  // Skip further attempts\n                } else if (forcedType) {\n                   env->ThrowError(\"AVISource: the video decompressor couldn't produce Y8 output\");\n                }\n              }\n            }\n          }\n\n          // Greyscale 'Y' no specific bit depth\n          if (fGrayscale && bOpen) {\n            vi.pixel_type = VideoInfo::CS_Y10;\n            biDst.biSizeImage = vi.BMPSize();\n            biDst.biCompression = MAKEFOURCC('Y', '1', 0, 10);\n            biDst.biBitCount = 10;\n            if (ICERR_OK == ICDecompressQuery(hic, pbiSrc, &biDst)) {\n              _RPT0(0, \"AVISource: Opening as Y1[0][10].\\n\");\n              bOpen = false;  // Skip further attempts\n            }\n            else {\n              vi.pixel_type = VideoInfo::CS_Y12;\n              biDst.biSizeImage = vi.BMPSize();\n              biDst.biCompression = MAKEFOURCC('Y', '1', 0, 12);\n              biDst.biBitCount = 12;\n              if (ICERR_OK == ICDecompressQuery(hic, pbiSrc, &biDst)) {\n                _RPT0(0, \"AVISource: Opening as Y1[0][12].\\n\");\n                bOpen = false;  // Skip further attempts\n              }\n              else {\n                vi.pixel_type = VideoInfo::CS_Y14;\n                biDst.biSizeImage = vi.BMPSize();\n                biDst.biCompression = MAKEFOURCC('Y', '1', 0, 14);\n                biDst.biBitCount = 14;\n                if (ICERR_OK == ICDecompressQuery(hic, pbiSrc, &biDst)) {\n                  _RPT0(0, \"AVISource: Opening as Y1[0][14].\\n\");\n                  bOpen = false;  // Skip further attempts\n                }\n                else {\n                  vi.pixel_type = VideoInfo::CS_Y16;\n                  biDst.biSizeImage = vi.BMPSize();\n                  biDst.biCompression = MAKEFOURCC('Y', '1', 0, 16);\n                  biDst.biBitCount = 16;\n                  if (ICERR_OK == ICDecompressQuery(hic, pbiSrc, &biDst)) {\n                    _RPT0(0, \"AVISource: Opening as Y1[0][16].\\n\");\n                    bOpen = false;  // Skip further attempts\n                  }\n                  else\n                    if (forcedType) {\n                      env->ThrowError(\"AVISource: the video decompressor couldn't produce grayscale output\");\n                    }\n                }\n              }\n            }\n          }\n\n          // YUV422P10\n          if ((fYUV422P10 || fv210 || fP210) && bOpen) {\n            vi.pixel_type = VideoInfo::CS_YUV422P10;\n            if ((fv210 || fYUV422P10) && bOpen) {\n              if (setInternalFormat_v210(vi, hic, pbiSrc, &biDst, MAKEFOURCC('v', '2', '1', '0'), VideoInfo::CS_YUV422P10)) {\n                _RPT0(0, \"AVISource: Opening as v210.\\n\");\n                specf = AVI_SpecialFormats::v210;\n                bOpen = false;  // Skip further attempts\n              }\n            }\n            if ((fP210 || fYUV422P10) && bOpen) {\n              if (setInternalFormat_P210(vi, hic, pbiSrc, &biDst, MAKEFOURCC('P', '2', '1', '0'), VideoInfo::CS_YUV422P10)) {\n                _RPT0(0, \"AVISource: Opening as P210.\\n\");\n                specf = AVI_SpecialFormats::P210;\n                bOpen = false;  // Skip further attempts\n              }\n            }\n            else if (forcedType && bOpen) {\n              env->ThrowError(\"AVISource: the video decompressor couldn't produce YUV422P10 output\");\n            }\n          }\n\n          // YUV422P16\n          if ((fYUV422P16 || fP216) && bOpen) {\n            vi.pixel_type = VideoInfo::CS_YUV422P16;\n            if (setInternalFormat_P216(vi, hic, pbiSrc, &biDst, MAKEFOURCC('P', '2', '1', '6'), VideoInfo::CS_YUV422P16)) {\n              _RPT0(0, \"AVISource: Opening as P216.\\n\");\n              specf = AVI_SpecialFormats::P216;\n              bOpen = false;  // Skip further attempts\n            }\n            else if (forcedType) {\n              env->ThrowError(\"AVISource: the video decompressor couldn't produce YUV422P16 output\");\n            }\n          }\n\n          // YUV420P10\n          if ((fYUV420P10 || fP010) && bOpen) {\n            vi.pixel_type = VideoInfo::CS_YUV420P10;\n            if (setInternalFormat_P010(vi, hic, pbiSrc, &biDst, MAKEFOURCC('P', '0', '1', '0'), VideoInfo::CS_YUV420P10)) {\n              _RPT0(0, \"AVISource: Opening as P010.\\n\");\n              specf = AVI_SpecialFormats::P010;\n              bOpen = false;  // Skip further attempts\n            }\n            else if (forcedType) {\n              env->ThrowError(\"AVISource: the video decompressor couldn't produce YUV420P10 output\");\n            }\n          }\n\n          // YUV420P16\n          if ((fYUV420P16 || fP016) && bOpen) {\n            vi.pixel_type = VideoInfo::CS_YUV420P16;\n            if (setInternalFormat_P016(vi, hic, pbiSrc, &biDst, MAKEFOURCC('P', '0', '1', '6'), VideoInfo::CS_YUV420P16)) {\n              _RPT0(0, \"AVISource: Opening as P016.\\n\");\n              specf = AVI_SpecialFormats::P016;\n              bOpen = false;  // Skip further attempts\n            }\n            else if (forcedType) {\n              env->ThrowError(\"AVISource: the video decompressor couldn't produce YUV420P16 output\");\n            }\n          }\n\n          // YUV444P16\n          if ((fYUV444P16 || fY416) && bOpen) {\n            vi.pixel_type = VideoInfo::CS_YUV444P16;\n            if (setInternalFormat_Y416(vi, hic, pbiSrc, &biDst, MAKEFOURCC('Y', '4', '1', '6'), VideoInfo::CS_YUV444P16)) {\n              _RPT0(0, \"AVISource: Opening as Y416.\\n\");\n              specf = AVI_SpecialFormats::Y416;\n              bOpen = false;  // Skip further attempts\n            }\n            else if (forcedType) {\n              env->ThrowError(\"AVISource: the video decompressor couldn't produce YUV444P16 output\");\n            }\n          }\n\n          // YUV444P10\n          if ((fYUV444P10 || fv410 || fY410) && bOpen) {\n            vi.pixel_type = VideoInfo::CS_YUV444P10;\n            if ((fYUV444P10 || fv410) && setInternalFormat_v410(vi, hic, pbiSrc, &biDst, MAKEFOURCC('v', '4', '1', '0'), VideoInfo::CS_YUV444P10)) {\n              _RPT0(0, \"AVISource: Opening as v410.\\n\");\n              specf = AVI_SpecialFormats::v410;\n              bOpen = false;  // Skip further attempts\n            }\n            else if ((fYUV444P10 || fY410) && setInternalFormat_Y410(vi, hic, pbiSrc, &biDst, MAKEFOURCC('Y', '4', '1', '0'), VideoInfo::CS_YUVA444P10)) {\n                _RPT0(0, \"AVISource: Opening as Y410.\\n\");\n                specf = AVI_SpecialFormats::Y410;\n                bOpen = false;  // Skip further attempts\n            }\n            else if (forcedType) {\n              env->ThrowError(\"AVISource: the video decompressor couldn't produce YUV444P10 output\");\n            }\n          }\n\n          // v308 to YUV444P8 aka YV24\n          if ((fv308) && bOpen) {\n            vi.pixel_type = VideoInfo::CS_YV24;\n            if (setInternalFormat_v308(vi, hic, pbiSrc, &biDst, MAKEFOURCC('v', '3', '0', '8'), VideoInfo::CS_YV24)) {\n              _RPT0(0, \"AVISource: Opening as v308.\\n\");\n              specf = AVI_SpecialFormats::v308;\n              bOpen = false;  // Skip further attempts\n            }\n            else if (forcedType) {\n              env->ThrowError(\"AVISource: the video decompressor couldn't produce v308 output\");\n            }\n          }\n\n          // v408 to YUVA444P8\n          if ((fv408) && bOpen) {\n            vi.pixel_type = VideoInfo::CS_YUVA444;\n            if (setInternalFormat_v408(vi, hic, pbiSrc, &biDst, MAKEFOURCC('v', '4', '0', '8'), VideoInfo::CS_YUVA444)) {\n              _RPT0(0, \"AVISource: Opening as v408.\\n\");\n              specf = AVI_SpecialFormats::v408;\n              bOpen = false;  // Skip further attempts\n            }\n            else if (forcedType) {\n              env->ThrowError(\"AVISource: the video decompressor couldn't produce v408 output\");\n            }\n          }\n\n          // No takers!\n          if (bOpen)\n            env->ThrowError(\"AviSource: Could not open video stream in any supported format.\");\n\n          DecompressBegin(pbiSrc, &biDst);\n        }\n        else {\n          // no hic\n\n          // when we reach here, maybe a natively supported fourCC format was reported\n          if (pbiSrc->biCompression == MAKEFOURCC('b', '6', '4', 'a')) {\n            if (setInternalFormat_b64a(vi, hic, pbiSrc, &biDst, pbiSrc->biCompression, VideoInfo::CS_BGR64)) {\n              _RPT0(0, \"AVISource: Opening as b64a.\\n\");\n              specf = AVI_SpecialFormats::b64a; // special flag!\n            }\n          }\n          if (pbiSrc->biCompression == MAKEFOURCC('B', 'R', 'A', 64)) {\n            if (setInternalFormat_BRA64(vi, hic, pbiSrc, &biDst, pbiSrc->biCompression, VideoInfo::CS_BGR64)) {\n              _RPT0(0, \"AVISource: Opening as BRA@.\\n\");\n            }\n          }\n          if (pbiSrc->biCompression == MAKEFOURCC('B', 'G', 'R', 48)) {\n            if (setInternalFormat_BGR48(vi, hic, pbiSrc, &biDst, pbiSrc->biCompression, VideoInfo::CS_BGR48)) {\n              _RPT0(0, \"AVISource: Opening as BGR[48].\\n\");\n            }\n          }\n          if (pbiSrc->biCompression == MAKEFOURCC('b', '4', '8', 'r')) {\n            if (setInternalFormat_b48r(vi, hic, pbiSrc, &biDst, pbiSrc->biCompression, VideoInfo::CS_BGR48)) {\n              _RPT0(0, \"AVISource: Opening as b48r.\\n\");\n              specf = AVI_SpecialFormats::b48r; // special flag!\n            }\n          }\n          if (pbiSrc->biCompression == MAKEFOURCC('v', '2', '1', '0')) {\n            if (setInternalFormat_v210(vi, hic, pbiSrc, &biDst, pbiSrc->biCompression, VideoInfo::CS_YUV422P10)) {\n              _RPT0(0, \"AVISource: Opening as v210.\\n\");\n              specf = AVI_SpecialFormats::v210; // special flag!\n            }\n          }\n          if (pbiSrc->biCompression == MAKEFOURCC('P', '2', '1', '0')) {\n            if (setInternalFormat_P210(vi, hic, pbiSrc, &biDst, pbiSrc->biCompression, VideoInfo::CS_YUV422P10)) {\n              _RPT0(0, \"AVISource: Opening as P210.\\n\");\n              specf = AVI_SpecialFormats::P210;\n            }\n          }\n          if (pbiSrc->biCompression == MAKEFOURCC('P', '0', '1', '0')) {\n            if (setInternalFormat_P010(vi, hic, pbiSrc, &biDst, pbiSrc->biCompression, VideoInfo::CS_YUV420P10)) {\n              _RPT0(0, \"AVISource: Opening as P010.\\n\");\n              specf = AVI_SpecialFormats::P010;\n            }\n          }\n          if (pbiSrc->biCompression == MAKEFOURCC('P', '0', '1', '6')) {\n            if (setInternalFormat_P016(vi, hic, pbiSrc, &biDst, pbiSrc->biCompression, VideoInfo::CS_YUV420P16)) {\n              _RPT0(0, \"AVISource: Opening as P016.\\n\");\n              specf = AVI_SpecialFormats::P016;\n            }\n          }\n          if (pbiSrc->biCompression == MAKEFOURCC('P', '2', '1', '6')) {\n            if (setInternalFormat_P216(vi, hic, pbiSrc, &biDst, pbiSrc->biCompression, VideoInfo::CS_YUV422P16)) {\n              _RPT0(0, \"AVISource: Opening as P216.\\n\");\n              specf = AVI_SpecialFormats::P216;\n            }\n          }\n          if (pbiSrc->biCompression == MAKEFOURCC('v', '4', '1', '0')) {\n            if (setInternalFormat_v410(vi, hic, pbiSrc, &biDst, pbiSrc->biCompression, VideoInfo::CS_YUV444P10)) {\n              _RPT0(0, \"AVISource: Opening as v410.\\n\");\n              specf = AVI_SpecialFormats::v410;\n            }\n          }\n          if (pbiSrc->biCompression == MAKEFOURCC('Y', '4', '1', '0')) {\n            if (setInternalFormat_Y410(vi, hic, pbiSrc, &biDst, pbiSrc->biCompression, VideoInfo::CS_YUVA444P10)) {\n              _RPT0(0, \"AVISource: Opening as Y410.\\n\");\n              specf = AVI_SpecialFormats::Y410;\n            }\n          }\n          if (pbiSrc->biCompression == MAKEFOURCC('Y', '4', '1', '6')) {\n            if (setInternalFormat_Y416(vi, hic, pbiSrc, &biDst, pbiSrc->biCompression, VideoInfo::CS_YUV444P16)) {\n              _RPT0(0, \"AVISource: Opening as Y416.\\n\");\n              specf = AVI_SpecialFormats::Y416;\n            }\n          }\n          if (pbiSrc->biCompression == MAKEFOURCC('r', '2', '1', '0')) {\n            if (setInternalFormat_r210(vi, hic, pbiSrc, &biDst, pbiSrc->biCompression, VideoInfo::CS_RGBP10)) {\n              _RPT0(0, \"AVISource: Opening as r210.\\n\");\n              specf = AVI_SpecialFormats::r210;\n            }\n          }\n          if (pbiSrc->biCompression == MAKEFOURCC('R', '1', '0', 'k')) {\n            if (setInternalFormat_R10k(vi, hic, pbiSrc, &biDst, pbiSrc->biCompression, VideoInfo::CS_RGBP10)) {\n              _RPT0(0, \"AVISource: Opening as R10k.\\n\");\n              specf = AVI_SpecialFormats::R10k;\n            }\n          }\n          if (pbiSrc->biCompression == MAKEFOURCC('v', '3', '0', '8')) {\n            if (setInternalFormat_v308(vi, hic, pbiSrc, &biDst, pbiSrc->biCompression, VideoInfo::CS_YV24)) {\n              _RPT0(0, \"AVISource: Opening as v308.\\n\");\n              specf = AVI_SpecialFormats::v308;\n            }\n          }\n          if (pbiSrc->biCompression == MAKEFOURCC('v', '4', '0', '8')) {\n            if (setInternalFormat_v408(vi, hic, pbiSrc, &biDst, pbiSrc->biCompression, VideoInfo::CS_YUVA444)) {\n              _RPT0(0, \"AVISource: Opening as v408.\\n\");\n              specf = AVI_SpecialFormats::v408;\n            }\n          }\n        }\n        // Flip DIB formats if negative height (FIXME: Y8 too?). Flip RGB48/64 always.\n        if ((pbiSrc->biHeight < 0 && (vi.IsRGB24() || vi.IsRGB32() || vi.IsY8())) || vi.IsRGB48() || vi.IsRGB64())\n          bInvertFrames = true;\n      }\n      else {\n        env->ThrowError(\"AviSource: Could not locate video stream.\");\n      }\n    }\n\n    // check for audio stream\n    if (fAudio) /*  && pfile->GetStream(streamtypeAUDIO, 0)) */ {\n      aSrc = new AudioSourceAVI(pfile, true, atrack);\n      if (aSrc->init()) {\n          audioStreamSource = new AudioStreamSource(aSrc,\n                                                    aSrc->lSampleFirst,\n                                                    aSrc->lSampleLast - aSrc->lSampleFirst,\n                                                    true);\n          WAVEFORMATEX* pwfx;\n          pwfx = audioStreamSource->GetFormat();\n          vi.audio_samples_per_second = pwfx->nSamplesPerSec;\n          vi.nchannels = pwfx->nChannels;\n          if (pwfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) {\n            vi.sample_type = SAMPLE_FLOAT;\n          } else if (pwfx->wBitsPerSample == 16) {\n            vi.sample_type = SAMPLE_INT16;\n          } else if (pwfx->wBitsPerSample == 8) {\n            vi.sample_type = SAMPLE_INT8;\n          } else if (pwfx->wBitsPerSample == 24) {\n            vi.sample_type = SAMPLE_INT24;\n          } else if (pwfx->wBitsPerSample == 32) {\n            vi.sample_type = SAMPLE_INT32;\n          }\n          vi.num_audio_samples = audioStreamSource->GetLength();\n\n          audio_stream_pos = 0;\n        }\n    }\n\n    // try to decompress frame 0 if not audio only.\n\n    dropped_frame=false;\n\n    if (mode != MODE_WAV) {\n      bMediaPad = !(!bMediaPad && !vi.IsY8() && vi.IsPlanar());\n      int keyframe = pvideo->NearestKeyFrame(0);\n      frame = new TemporalBuffer(vi, bMediaPad, specf, env);\n\n      LRESULT error = DecompressFrame(keyframe, false, env);\n      if (error != ICERR_OK)   // shutdown, if init not succesful.\n        env->ThrowError(\"AviSource: Could not decompress frame 0\");\n\n      // Cope with dud AVI files that start with drop\n      // frames, just return the first key frame\n      if (dropped_frame) {\n        keyframe = pvideo->NextKeyFrame(0);\n        error = DecompressFrame(keyframe, false, env);\n        if (error != ICERR_OK)   // shutdown, if init not succesful.\n          env->ThrowError(\"AviSource: Could not decompress first keyframe %d\", keyframe);\n      }\n      last_frame_no=0;\n      last_frame = AdjustFrameAlignment(frame, vi, bInvertFrames, specf, env);\n    }\n  }\n  catch (...) {\n    AVISource::CleanUp();\n    throw;\n  }\n}\n\nAVISource::~AVISource() {\n  AVISource::CleanUp();\n}\n\nvoid AVISource::CleanUp() { // Tritical - Jan 2006\n  if (hic) {\n    !ex ? ICDecompressEnd(hic) : ICDecompressExEnd(hic);\n    ICClose(hic);\n  }\n  if (pvideo) delete pvideo;\n  if (aSrc) delete aSrc;\n  if (audioStreamSource) delete audioStreamSource;\n  if (pfile)\n    pfile->Release();\n  AVIFileExit();\n  if (pbiSrc)\n    free(pbiSrc);\n  if (srcbuffer)  // Tritical May 2005\n    delete[] srcbuffer;\n  if (frame)\n    delete frame;\n}\n\nconst VideoInfo& AVISource::GetVideoInfo() { return vi; }\n\nPVideoFrame AVISource::GetFrame(int n, IScriptEnvironment* env) {\n\n  n = clamp(n, 0, vi.num_frames-1);\n  dropped_frame=false;\n  if (n != last_frame_no) {\n    // find the last keyframe\n    int keyframe = pvideo->NearestKeyFrame(n);\n    // maybe we don't need to go back that far\n    if (last_frame_no < n && last_frame_no >= keyframe)\n      keyframe = last_frame_no+1;\n    if (keyframe < 0) keyframe = 0;\n\n    bool frameok = false;\n    //PVideoFrame frame = env->NewVideoFrameP(vi, -4);\n\n    bool not_found_yet;\n    do {\n      not_found_yet=false;\n      for (int i = keyframe; i <= n; ++i) {\n        LRESULT error = DecompressFrame(i, i != n, env);\n        if ((!dropped_frame) && (error == ICERR_OK)) frameok = true;   // Better safe than sorry\n      }\n      last_frame_no = n;\n\n      if (!last_frame && !frameok) {  // Last keyframe was not valid.\n        const int key_pre=keyframe;\n        keyframe = pvideo->NearestKeyFrame(keyframe-1);\n        if (keyframe < 0) keyframe = 0;\n        if (keyframe == key_pre)\n          env->ThrowError(\"AVISource: could not find valid keyframe for frame %d.\", n);\n\n        not_found_yet=true;\n      }\n    } while(not_found_yet);\n\n    if (frameok) {\n      last_frame = AdjustFrameAlignment(frame, vi, bInvertFrames, specf, env);\n    }\n  }\n  return last_frame;\n}\n\nvoid AVISource::GetAudio(void* buf, __int64 start, __int64 count, IScriptEnvironment* env) {\n  AVS_UNUSED(env);\n  long bytes_read=0;\n  __int64 samples_read=0;\n\n  if (start < 0) {\n    int bytes = (int)vi.BytesFromAudioSamples(min(-start, count));\n    memset(buf, 0, bytes);\n    buf = (char*)buf + bytes;\n    count -= vi.AudioSamplesFromBytes(bytes);\n    start += vi.AudioSamplesFromBytes(bytes);\n  }\n\n  if (audioStreamSource) {\n    if (start != audio_stream_pos)\n        audioStreamSource->Seek((long)start);\n    samples_read = audioStreamSource->Read(buf, (long)count, &bytes_read);\n    audio_stream_pos = start + samples_read;\n  }\n\n  if (samples_read < count)\n    memset((char*)buf + bytes_read, 0, (size_t)(vi.BytesFromAudioSamples(count) - bytes_read));\n}\n\nbool AVISource::GetParity(int n) {\n  AVS_UNUSED(n);\n  return false;\n}\n\nint __stdcall AVISource::SetCacheHints(int cachehints,int frame_range)\n{\n  AVS_UNUSED(frame_range);\n  switch(cachehints)\n  {\n  case CACHE_GET_MTMODE:\n    return MT_SERIALIZED;\n  default:\n    return 0;\n  }\n}\n"
  },
  {
    "path": "avs_core/filters/AviSource/avi_source.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include \"../../core/alignplanar.h\"\n#include \"VD_Audio.h\"\n#include \"AVIReadHandler.h\"\n\n\n// AVI Decompressors require 4bytes aligned buffer with minimum padding or no padding buffer.\n// or other specialities.\n// Therefore, PVideoFrame shouldn't be used as those.\n\ntypedef enum class _AVI_SpecialFormats\n{\n  none, b64a, b48r, v210, P010, P016, P210, P216, v410, Y416,\n  r210, R10k,\n  v308, v408,\n  Y410\n} AVI_SpecialFormats;\n\nclass TemporalBuffer {\n  void* orig;\n  BYTE* pY;\n  BYTE* pV;\n  BYTE* pU;\n  BYTE* pA;\n  int pitchY;\n  int pitchUV;\n  size_t size;\npublic:\n  TemporalBuffer(const VideoInfo& vi, bool bMediaPad,\n    AVI_SpecialFormats specf,\n    IScriptEnvironment* env);\n  ~TemporalBuffer() {}\n  int GetPitch(int plane=PLANAR_Y) {\n    return (plane == PLANAR_Y || plane == PLANAR_G || plane == PLANAR_B || plane == PLANAR_R || plane == PLANAR_A) ? pitchY : pitchUV; }\n  size_t GetSize() { return size; }\n  BYTE* GetPtr(int plane=PLANAR_Y)\n  {\n    switch (plane) {\n    case PLANAR_U: return pU;\n    case PLANAR_V: return pV;\n    case PLANAR_G: return pY;\n    case PLANAR_B: return pU;\n    case PLANAR_R: return pV;\n    case PLANAR_A: return pA;\n    default: return pY;\n    }\n  }\n};\n\n\nclass AVISource : public IClip {\n  IAVIReadHandler *pfile;\n  IAVIReadStream *pvideo;\n  HIC hic;\n  VideoInfo vi;\n  BYTE* srcbuffer;\n  int srcbuffer_size;\n  BITMAPINFOHEADER* pbiSrc;\n  BITMAPINFOHEADER biDst;\n  bool ex;\n  bool dropped_frame;\n  bool bIsType1;\n  bool bInvertFrames;\n  bool bMediaPad;\n  AVI_SpecialFormats specf;\n\n  PVideoFrame last_frame;\n  int last_frame_no;\n  AudioSource* aSrc;\n  AudioStreamSource* audioStreamSource;\n  __int64 audio_stream_pos;\n  TemporalBuffer* frame;\n\n  LRESULT DecompressBegin(LPBITMAPINFOHEADER lpbiSrc, LPBITMAPINFOHEADER lpbiDst);\n  LRESULT DecompressFrame(int n, bool preroll, IScriptEnvironment* env);\n\n  void CheckHresult(HRESULT hr, const char* msg, IScriptEnvironment* env);\n  bool AttemptCodecNegotiation(DWORD fccHandler, BITMAPINFOHEADER* bmih);\n  void LocateVideoCodec(const char fourCC[], IScriptEnvironment* env);\n\npublic:\n\n  typedef enum {\n    MODE_NORMAL = 0,\n    MODE_AVIFILE,\n    MODE_OPENDML,\n    MODE_WAV\n  } avi_mode_e;\n\n  AVISource(const char filename[], bool fAudio, const char pixel_type[],\n            const char fourCC[], int vtrack, int atrack, avi_mode_e mode, bool utf8, IScriptEnvironment* env);  // mode: 0=detect, 1=avifile, 2=opendml, 3=avifile (audio only)\n  ~AVISource();\n  void CleanUp(); // Tritical - Jan 2006\n  const VideoInfo& __stdcall GetVideoInfo();\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n  void __stdcall GetAudio(void* buf, __int64 start, __int64 count, IScriptEnvironment* env) ;\n  bool __stdcall GetParity(int n);\n  int __stdcall SetCacheHints(int cachehints,int frame_range);\n\n  static AVSValue __cdecl Create(AVSValue args, void* user_data, IScriptEnvironment* env) {\n    //               0  1\n    // MODE_WAV:    \"s+[utf8]b\"\n    //               0  1       2            3        4        5        6\n    // other modes: \"s+[audio]b[pixel_type]s[fourCC]s[vtrack]i[atrack]i[utf8]b\"\n\n    const avi_mode_e mode = (avi_mode_e)size_t(user_data);\n    const bool fAudio = (mode == MODE_WAV) || args[1].AsBool(true);\n    const char* pixel_type = (mode != MODE_WAV) ? args[2].AsString(\"\") : \"\";\n    const char* fourCC = (mode != MODE_WAV) ? args[3].AsString(\"\") : \"\";\n    const int vtrack = (mode != MODE_WAV) ? args[4].AsInt(0) : 0;\n    const int atrack = (mode != MODE_WAV) ? args[5].AsInt(0) : 0;\n    const int utf8 = (mode != MODE_WAV) ? args[6].AsBool(false) : args[1].AsBool(false);\n\n    PClip result = new AVISource(args[0][0].AsString(), fAudio, pixel_type, fourCC, vtrack, atrack, mode, utf8, env);\n    for (int i = 1; i < args[0].ArraySize(); ++i) {\n      AVSValue arg[3] = { result, new AVISource(args[0][i].AsString(), fAudio, pixel_type, fourCC, vtrack, atrack, mode, utf8, env), 0 };\n      result = env->Invoke(\"UnalignedSplice\", AVSValue(arg, 3)).AsClip();\n    }\n    return AlignPlanar::Create(result);\n  }\n};\n"
  },
  {
    "path": "avs_core/filters/AviSource/clip_info.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __CLIP_INFO_H__\n#define __CLIP_INFO_H__\n\n\nextern \"C\" const GUID CLSID_CAVIFileSynth;   // {E6D6B700-124D-11D4-86F3-DB80AFD98778}\n\nextern \"C\" const GUID IID_IAvisynthClipInfo;   // {E6D6B708-124D-11D4-86F3-DB80AFD98778}\n\nstruct IAvisynthClipInfo : IUnknown {\n  virtual int __stdcall GetError(const char** ppszMessage) = 0;\n  virtual bool __stdcall GetParity(int n) = 0;\n  virtual bool __stdcall IsFieldBased() = 0;\n};\n\n\n#endif"
  },
  {
    "path": "avs_core/filters/AviSource/list.cpp",
    "content": "// Packaged with Avisynth v1.0 beta.\n// http://www.math.berkeley.edu/~benrg/avisynth.html\n\n//\tVirtualDub - Video processing and capture application\n//\tCopyright (C) 1998-2000 Avery Lee\n//\n//\tThis program is free software; you can redistribute it and/or modify\n//\tit under the terms of the GNU General Public License as published by\n//\tthe Free Software Foundation; either version 2 of the License, or\n//\t(at your option) any later version.\n//\n//\tThis program is distributed in the hope that it will be useful,\n//\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n//\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//\tGNU General Public License for more details.\n//\n//\tYou should have received a copy of the GNU General Public License\n//\talong with this program; if not, write to the Free Software\n//\tFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n///////////////////////////////////////////////////////////////////////////\n//\n//\tFor those of you who say this looks familiar... it should.  This is\n//\tthe same linked-list style that the Amiga Exec uses, with dummy head\n//\tand tail nodes.  It's really a very convienent way to implement\n//\tdoubly-linked lists.\n//\n\n#include \"list.h\"\n\nList::List() {\n  head.next = tail.prev = 0;\n  head.prev = &tail;\n  tail.next = &head;\n}\n\nListNode *List::RemoveHead() {\n  if (head.prev->prev) {\n    ListNode *t = head.prev;\n\n    head.prev->Remove();\n    return t;\n  }\n\n  return 0;\n}\n\nListNode *List::RemoveTail() {\n  if (tail.next->next) {\n    ListNode *t = tail.next;\n\n    tail.next->Remove();\n    return t;\n  }\n\n  return 0;\n}\n"
  },
  {
    "path": "avs_core/filters/AviSource/list.h",
    "content": "// Packaged with Avisynth v1.0 beta.\n// http://www.math.berkeley.edu/~benrg/avisynth.html\n\n//\tVirtualDub - Video processing and capture application\n//\tCopyright (C) 1998-2000 Avery Lee\n//\n//\tThis program is free software; you can redistribute it and/or modify\n//\tit under the terms of the GNU General Public License as published by\n//\tthe Free Software Foundation; either version 2 of the License, or\n//\t(at your option) any later version.\n//\n//\tThis program is distributed in the hope that it will be useful,\n//\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n//\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//\tGNU General Public License for more details.\n//\n//\tYou should have received a copy of the GNU General Public License\n//\talong with this program; if not, write to the Free Software\n//\tFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n#ifndef f_LIST_H\n#define f_LIST_H\n\nclass ListNode {\npublic:\n\tListNode *next, *prev;\n\n  ListNode() {}\n  ListNode(void *pv) {}\n\n\tvoid Remove() {\n\t\tnext->prev = prev;\n\t\tprev->next = next;\n\t}\n\n\tvoid InsertAfter(ListNode *node) {\n\t\tnext = node;\n\t\tprev = node->prev;\n\t\tif (node->prev) node->prev->next = this;\n\t\tnode->prev = this;\n\t}\n\n\tvoid InsertBefore(ListNode *node) {\n\t\tnext = node->next;\n\t\tprev = node;\n\t\tif (node->next) node->next->prev = this;\n\t\tnode->next = this;\n\t}\n\n\tListNode *NextFromHead() {\n\t\treturn prev;\n\t}\n\n\tListNode *NextFromTail() {\n\t\treturn next;\n\t}\n};\n\nclass List {\nprivate:\npublic:\n\tListNode head, tail;\n\n\t// <--- next             prev --->\n\t//\n\t// head <-> node <-> node <-> tail\n\n\tList();\n\n\tvoid AddHead(ListNode *node) {\n\t\tnode->InsertAfter(&head);\n\t}\n\n\tvoid AddTail(ListNode *node) {\n\t\tnode->InsertBefore(&tail);\n\t}\n\n\tListNode *RemoveHead();\n\tListNode *RemoveTail();\n\n\tbool IsEmpty() {\n\t\treturn !head.prev->prev;\n\t}\n\n\tListNode *AtHead() {\n\t\treturn head.prev;\n\t}\n\n\tListNode *AtTail() {\n\t\treturn tail.next;\n\t}\n};\n\n// Templated classes... no code.\n\ntemplate<class T> class List2;\n\ntemplate<class T>\nclass ListNode2 : public ListNode {\nfriend List2<T>;\npublic:\n\tListNode2<T>() {}\n\tListNode2<T>(void *pv) : ListNode(pv) {}\n\n\tvoid InsertBefore(ListNode2<T> *node) { ListNode::InsertBefore(node); }\n\tvoid InsertAfter(ListNode2<T> *node) { ListNode::InsertAfter(node); }\n\n\tvoid Remove() { ListNode::Remove(); }\n\tT *NextFromHead() { return (T *)ListNode::NextFromHead(); }\n\tT *NextFromTail() { return (T *)ListNode::NextFromTail(); }\n};\n\ntemplate<class T>\nclass List2 : public List {\npublic:\n\tList2<T>() {}\n\n\tvoid AddHead(ListNode2<T> *node) { List::AddHead(node); }\n\tvoid AddTail(ListNode2<T> *node) { List::AddTail(node); }\n\tT *RemoveHead() { return (T *)List::RemoveHead(); }\n\tT *RemoveTail() { return (T *)List::RemoveTail(); }\n\tT *AtHead() { return (T *)List::AtHead(); }\n\tT *AtTail() { return (T *)List::AtTail(); }\n};\n\n#endif\n"
  },
  {
    "path": "avs_core/filters/aarch64/turn_neon.cpp",
    "content": "// AviSynth+.  Copyright 2025 AviSynth+ Project\n// https://avs-plus.net\n// http://avisynth.nl\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include <avs/types.h>\n#include <avs/config.h>\n#include \"../turn.h\"\n#include <cstdint>\n\n#include <arm_neon.h>\n\n/*\nSSE Intrinsic,AArch64 NEON Equivalent,Description\n__m128i              uint8x16_t                 128-bit vector of 8-bit unsigned integers (bytes)\n_mm_loadl_epi64      vld1_u8 (into uint8x8_t)   Load 64 bits (8 bytes)\n_mm_unpacklo_epi8    vzip_u8 (64 bit)\n                     vzipq_u16/vzipq_u32 (128 bit)\n                     Interleaves the low elements of two vectors\n_mm_unpackhi_epi8    Handled implicitly by vzip structure or\n                     equivalent to high 64-bit of vzipq output\n                     Interleaves the high elements of two vectors\n_mm_storel_epi64     vst1_u8 (from uint8x8_t)   Store 64 bits (8 bytes)\n_mm_movehl_ps        vget_high_u8               Extracts the high 64 bits from a 128-bit vector\n*/\n\n// --------------------------------------------------------------------------\n// 8-bit Block Rotate 90 CW (Transpose + Flip Horizontal)\n// --------------------------------------------------------------------------\nstatic AVS_FORCEINLINE void transpose_8x8x8_neon(const BYTE* AVS_RESTRICT srcp, BYTE* AVS_RESTRICT dstp, int src_pitch, int dst_pitch)\n{\n  // 1. Load 8 rows (8x8 block)\n  // Assume srcp points to the top left of the block to be rotated.\n  uint8x8_t r0 = vld1_u8(srcp); srcp += src_pitch;\n  uint8x8_t r1 = vld1_u8(srcp); srcp += src_pitch;\n  uint8x8_t r2 = vld1_u8(srcp); srcp += src_pitch;\n  uint8x8_t r3 = vld1_u8(srcp); srcp += src_pitch;\n  uint8x8_t r4 = vld1_u8(srcp); srcp += src_pitch;\n  uint8x8_t r5 = vld1_u8(srcp); srcp += src_pitch;\n  uint8x8_t r6 = vld1_u8(srcp); srcp += src_pitch;\n  uint8x8_t r7 = vld1_u8(srcp);\n\n  // 2. Transpose logic (standard butterfly)\n  // Stage 1: Swap 8-bit neighbors\n  uint8x8x2_t t0 = vtrn_u8(r0, r1);\n  uint8x8x2_t t1 = vtrn_u8(r2, r3);\n  uint8x8x2_t t2 = vtrn_u8(r4, r5);\n  uint8x8x2_t t3 = vtrn_u8(r6, r7);\n\n  // Stage 2: Swap 16-bit pairs\n  uint16x4x2_t m0 = vtrn_u16(vreinterpret_u16_u8(t0.val[0]), vreinterpret_u16_u8(t1.val[0]));\n  uint16x4x2_t m1 = vtrn_u16(vreinterpret_u16_u8(t0.val[1]), vreinterpret_u16_u8(t1.val[1]));\n  uint16x4x2_t m2 = vtrn_u16(vreinterpret_u16_u8(t2.val[0]), vreinterpret_u16_u8(t3.val[0]));\n  uint16x4x2_t m3 = vtrn_u16(vreinterpret_u16_u8(t2.val[1]), vreinterpret_u16_u8(t3.val[1]));\n\n  // Stage 3: Swap 32-bit quads\n  uint32x2x2_t y04 = vtrn_u32(vreinterpret_u32_u16(m0.val[0]), vreinterpret_u32_u16(m2.val[0]));\n  uint32x2x2_t y15 = vtrn_u32(vreinterpret_u32_u16(m1.val[0]), vreinterpret_u32_u16(m3.val[0]));\n  uint32x2x2_t y26 = vtrn_u32(vreinterpret_u32_u16(m0.val[1]), vreinterpret_u32_u16(m2.val[1]));\n  uint32x2x2_t y37 = vtrn_u32(vreinterpret_u32_u16(m1.val[1]), vreinterpret_u32_u16(m3.val[1]));\n\n  // 3. Mirror horizontal, store\n  // The transpose put the pixels in order 0,1,2... but Turn Right requires 7,6,5...\n  // We reverse the bytes in each 64-bit register.\n\n  auto store_rev = [&](const uint32x2x2_t& v, int idx) {\n    // vrev64_u8 reverses bytes in the 64-bit vector (Horizontal Flip)\n    uint8x8_t flipped = vrev64_u8(vreinterpret_u8_u32(v.val[idx]));\n    vst1_u8(dstp, flipped);\n    dstp += dst_pitch;\n    };\n\n  store_rev(y04, 0); // Row 0\n  store_rev(y15, 0); // Row 1\n  store_rev(y26, 0); // Row 2\n  store_rev(y37, 0); // Row 3\n  store_rev(y04, 1); // Row 4\n  store_rev(y15, 1); // Row 5\n  store_rev(y26, 1); // Row 6\n  store_rev(y37, 1); // Row 7\n}\n\n// --------------------------------------------------------------------------\n// 16-bit Block Rotate 90 CW (Transpose + Flip Horizontal)\n// --------------------------------------------------------------------------\nstatic AVS_FORCEINLINE void transpose_8x8x16_neon(const BYTE* AVS_RESTRICT srcp, BYTE* AVS_RESTRICT dstp, int src_pitch, int dst_pitch)\n{\n  auto p16 = [](const BYTE* p) { return reinterpret_cast<const uint16_t*>(p); };\n  auto d16 = [](BYTE* p) { return reinterpret_cast<uint16_t*>(p); };\n\n  // 1. Load 8 rows (8x8 block of uint16)\n  uint16x8_t r0 = vld1q_u16(p16(srcp)); srcp += src_pitch;\n  uint16x8_t r1 = vld1q_u16(p16(srcp)); srcp += src_pitch;\n  uint16x8_t r2 = vld1q_u16(p16(srcp)); srcp += src_pitch;\n  uint16x8_t r3 = vld1q_u16(p16(srcp)); srcp += src_pitch;\n  uint16x8_t r4 = vld1q_u16(p16(srcp)); srcp += src_pitch;\n  uint16x8_t r5 = vld1q_u16(p16(srcp)); srcp += src_pitch;\n  uint16x8_t r6 = vld1q_u16(p16(srcp)); srcp += src_pitch;\n  uint16x8_t r7 = vld1q_u16(p16(srcp));\n\n  // 2. Transpose logic (standard butterfly)\n  // Stage 1: Swap 16-bit neighbors\n  uint16x8x2_t trn0 = vtrnq_u16(r0, r1);\n  uint16x8x2_t trn1 = vtrnq_u16(r2, r3);\n  uint16x8x2_t trn2 = vtrnq_u16(r4, r5);\n  uint16x8x2_t trn3 = vtrnq_u16(r6, r7);\n\n  // Stage 2: Swap 32-bit pairs\n  uint32x4x2_t q0 = vtrnq_u32(vreinterpretq_u32_u16(trn0.val[0]), vreinterpretq_u32_u16(trn1.val[0]));\n  uint32x4x2_t q1 = vtrnq_u32(vreinterpretq_u32_u16(trn0.val[1]), vreinterpretq_u32_u16(trn1.val[1]));\n  uint32x4x2_t q2 = vtrnq_u32(vreinterpretq_u32_u16(trn2.val[0]), vreinterpretq_u32_u16(trn3.val[0]));\n  uint32x4x2_t q3 = vtrnq_u32(vreinterpretq_u32_u16(trn2.val[1]), vreinterpretq_u32_u16(trn3.val[1]));\n\n  // Stage 3: Swap 64-bit halves (Assembly)\n  uint64x2_t q0_0 = vreinterpretq_u64_u32(q0.val[0]);\n  uint64x2_t q2_0 = vreinterpretq_u64_u32(q2.val[0]);\n  uint64x2_t q1_0 = vreinterpretq_u64_u32(q1.val[0]);\n  uint64x2_t q3_0 = vreinterpretq_u64_u32(q3.val[0]);\n\n  uint64x2_t q0_1 = vreinterpretq_u64_u32(q0.val[1]);\n  uint64x2_t q2_1 = vreinterpretq_u64_u32(q2.val[1]);\n  uint64x2_t q1_1 = vreinterpretq_u64_u32(q1.val[1]);\n  uint64x2_t q3_1 = vreinterpretq_u64_u32(q3.val[1]);\n\n  // 3. Mirror Horizontal & Store\n  // To reverse a 128-bit vector of 16-bit elements: [ABCDEFGH] -> [HGFEDCBA]\n  // vrev64 swaps within halves: [DCBA][HGFE]\n  // vext(4) swaps the halves:   [HGFE][DCBA]\n\n  auto store_rev = [&](uint64x2_t a, uint64x2_t b, bool high) {\n    uint16x8_t row;\n    if (!high) row = vreinterpretq_u16_u64(vzip1q_u64(a, b));\n    else       row = vreinterpretq_u16_u64(vzip2q_u64(a, b));\n\n    // Flip Horizontal Logic\n    uint16x8_t rev_halves = vrev64q_u16(row);\n    // Swap the 64-bit halves (index 4 corresponds to 4 * 16-bit = 64 bits)\n    uint16x8_t fully_flipped = vextq_u16(rev_halves, rev_halves, 4);\n\n    vst1q_u16(d16(dstp), fully_flipped);\n    dstp += dst_pitch;\n    };\n\n  store_rev(q0_0, q2_0, false); // Row 0\n  store_rev(q1_0, q3_0, false); // Row 1\n  store_rev(q0_1, q2_1, false); // Row 2\n  store_rev(q1_1, q3_1, false); // Row 3\n  store_rev(q0_0, q2_0, true);  // Row 4\n  store_rev(q1_0, q3_0, true);  // Row 5\n  store_rev(q0_1, q2_1, true);  // Row 6\n  store_rev(q1_1, q3_1, true);  // Row 7\n}\n\n// Main loop for 8 bit plane turn\nvoid turn_right_plane_8_neon(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n  const BYTE* s0 = srcp;\n  int w = src_rowsize & ~7;\n  int h = src_height & ~7;\n\n  for (int y = 0; y < h; y += 8)\n  {\n    BYTE* d0 = dstp + src_height - 8 - y;\n    for (int x = 0; x < w; x += 8)\n    {\n      transpose_8x8x8_neon(s0 + x, d0, src_pitch, dst_pitch);\n      d0 += dst_pitch * 8;\n    }\n    s0 += src_pitch * 8;\n  }\n\n  if (src_rowsize != w)\n  {\n    // Assuming turn_right_plane_8_c is the C fallback function\n    turn_right_plane_8_c(srcp + w, dstp + w * dst_pitch, src_rowsize - w, src_height, src_pitch, dst_pitch);\n  }\n\n  if (src_height != h)\n  {\n    turn_right_plane_8_c(srcp + h * src_pitch, dstp, src_rowsize, src_height - h, src_pitch, dst_pitch);\n  }\n}\n\nvoid turn_left_plane_8_neon(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n  // The direction and stride logic is independent of the intrinsics used\n  turn_right_plane_8_neon(srcp + (src_height - 1) * src_pitch, dstp + (src_rowsize - 1) * dst_pitch, src_rowsize, src_height, -src_pitch, -dst_pitch);\n}\n\n// Transposes 8 rows of 4x16-bit values (shorts/words) into 4 rows of 8x16-bit values.\nstatic AVS_FORCEINLINE void transpose_16x4x8_neon(const BYTE* srcp, BYTE* dstp, const int src_pitch, const int dst_pitch)\n{\n  // Load 8 rows of 8 bytes (4 x 16-bit elements)\n  uint64x1_t a03_l = vld1_u64(reinterpret_cast<const uint64_t*>(srcp + src_pitch * 0));\n  uint64x1_t b03_l = vld1_u64(reinterpret_cast<const uint64_t*>(srcp + src_pitch * 1));\n  uint64x1_t c03_l = vld1_u64(reinterpret_cast<const uint64_t*>(srcp + src_pitch * 2));\n  uint64x1_t d03_l = vld1_u64(reinterpret_cast<const uint64_t*>(srcp + src_pitch * 3));\n  uint64x1_t e03_l = vld1_u64(reinterpret_cast<const uint64_t*>(srcp + src_pitch * 4));\n  uint64x1_t f03_l = vld1_u64(reinterpret_cast<const uint64_t*>(srcp + src_pitch * 5));\n  uint64x1_t g03_l = vld1_u64(reinterpret_cast<const uint64_t*>(srcp + src_pitch * 6));\n  uint64x1_t h03_l = vld1_u64(reinterpret_cast<const uint64_t*>(srcp + src_pitch * 7));\n\n  // Convert to 16-bit vectors (4 elements)\n  uint16x4_t a03 = vreinterpret_u16_u64(a03_l);\n  uint16x4_t b03 = vreinterpret_u16_u64(b03_l);\n  uint16x4_t c03 = vreinterpret_u16_u64(c03_l);\n  uint16x4_t d03 = vreinterpret_u16_u64(d03_l);\n  uint16x4_t e03 = vreinterpret_u16_u64(e03_l);\n  uint16x4_t f03 = vreinterpret_u16_u64(f03_l);\n  uint16x4_t g03 = vreinterpret_u16_u64(g03_l);\n  uint16x4_t h03 = vreinterpret_u16_u64(h03_l);\n\n  // NEON Transpose on 16-bit elements (VTRN.16)\n  // Step 1: Interleave pairs (a/e, b/f, c/g, d/h)\n  // SSE: _mm_unpacklo_epi16(A, B) -> A0 B0 A1 B1 ...\n  uint16x4x2_t ae = vtrn_u16(a03, e03); // {a0 e0 a1 e1}, {a2 e2 a3 e3}\n  uint16x4x2_t bf = vtrn_u16(b03, f03);\n  uint16x4x2_t cg = vtrn_u16(c03, g03);\n  uint16x4x2_t dh = vtrn_u16(d03, h03);\n\n  // Step 2: Interleave pairs of pairs (ae/cg, bf/dh)\n  uint16x4x2_t aceg01 = vtrn_u16(ae.val[0], cg.val[0]);\n  uint16x4x2_t aceg23 = vtrn_u16(ae.val[1], cg.val[1]);\n  uint16x4x2_t bdfh01 = vtrn_u16(bf.val[0], dh.val[0]);\n  uint16x4x2_t bdfh23 = vtrn_u16(bf.val[1], dh.val[1]);\n\n  // SSE: _mm_unpacklo_epi16(A, B) -> A0 B0 A1 B1 ... (A0 B0 C0 D0...)\n  // Step 3: Final combination/concatenation of the 4-element blocks.\n  // combine the left-half blocks (ACEG) with the right-half blocks (BDFH).\n\n  // Output Row 0: {A0 B0 C0 D0} + {E0 F0 G0 H0} (from the first elements of the transposed groups)\n  uint16x8_t abcdefgh0 = vcombine_u16(aceg01.val[0], bdfh01.val[0]);\n\n  // Output Row 1: {A1 B1 C1 D1} + {E1 F1 G1 H1}\n  uint16x8_t abcdefgh1 = vcombine_u16(aceg01.val[1], bdfh01.val[1]);\n\n  // Output Row 2: {A2 B2 C2 D2} + {E2 F2 G2 H2}\n  uint16x8_t abcdefgh2 = vcombine_u16(aceg23.val[0], bdfh23.val[0]);\n\n  // Output Row 3: {A3 B3 C3 D3} + {E3 F3 G3 H3}\n  uint16x8_t abcdefgh3 = vcombine_u16(aceg23.val[1], bdfh23.val[1]);\n\n  // Store results\n  // SSE: _mm_store_si128 (aligned store)\n  vst1q_u16(reinterpret_cast<uint16_t*>(dstp + dst_pitch * 0), abcdefgh0);\n  vst1q_u16(reinterpret_cast<uint16_t*>(dstp + dst_pitch * 1), abcdefgh1);\n  vst1q_u16(reinterpret_cast<uint16_t*>(dstp + dst_pitch * 2), abcdefgh2);\n  vst1q_u16(reinterpret_cast<uint16_t*>(dstp + dst_pitch * 3), abcdefgh3);\n}\n\n// Main loop for 16 bit plane turn\nvoid turn_right_plane_16_neon(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n  const BYTE* s0 = srcp;\n  int w = src_rowsize & ~15;\n  int h = src_height & ~7;\n\n  for (int y = 0; y < h; y += 8)\n  {\n    BYTE* d0 = dstp + src_height * 2 - 16 - y * 2;\n    for (int x = 0; x < w; x += 16)\n    {\n      transpose_8x8x16_neon(s0 + x, d0, src_pitch, dst_pitch);\n      d0 += dst_pitch * 8;\n    }\n    s0 += src_pitch * 8;\n  }\n\n  if (src_rowsize != w)\n  {\n    turn_right_plane_16_c(srcp + w, dstp + w / 2 * dst_pitch, src_rowsize - w, src_height, src_pitch, dst_pitch);\n  }\n\n  if (src_height != h)\n  {\n    turn_right_plane_16_c(srcp + h * src_pitch, dstp, src_rowsize, src_height - h, src_pitch, dst_pitch);\n  }\n}\n\n\nvoid turn_left_plane_16_neon(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n  turn_right_plane_16_neon(srcp + src_pitch * (src_height - 1), dstp + dst_pitch * (src_rowsize / 2 - 1), src_rowsize, src_height, -src_pitch, -dst_pitch);\n}\n\n\n// Transposes 4 rows of 4x32-bit values (words) into 4 rows of 4x32-bit values.\n// float helper\nstatic AVS_FORCEINLINE void transpose_32x4x4_neon(const BYTE* srcp, BYTE* dstp, const int src_pitch, const int dst_pitch)\n{\n  // Load 4 128-bit vectors (4 x 32-bit elements per vector)\n  // SSE: _mm_loadu_si128 (unaligned load)\n  uint32x4_t a03 = vld1q_u32(reinterpret_cast<const uint32_t*>(srcp + src_pitch * 0));\n  uint32x4_t b03 = vld1q_u32(reinterpret_cast<const uint32_t*>(srcp + src_pitch * 1));\n  uint32x4_t c03 = vld1q_u32(reinterpret_cast<const uint32_t*>(srcp + src_pitch * 2));\n  uint32x4_t d03 = vld1q_u32(reinterpret_cast<const uint32_t*>(srcp + src_pitch * 3));\n\n  uint32x4x2_t ab = vtrnq_u32(a03, b03);\n  uint32x4x2_t cd = vtrnq_u32(c03, d03);\n\n  uint32x4_t t0 = vcombine_u32(vget_low_u32(ab.val[0]), vget_low_u32(cd.val[0]));\n  uint32x4_t t1 = vcombine_u32(vget_low_u32(ab.val[1]), vget_low_u32(cd.val[1]));\n  uint32x4_t t2 = vcombine_u32(vget_high_u32(ab.val[0]), vget_high_u32(cd.val[0]));\n  uint32x4_t t3 = vcombine_u32(vget_high_u32(ab.val[1]), vget_high_u32(cd.val[1]));\n\n  uint32x4x4_t result = { { t0, t1, t2, t3 } };\n\n  // Store results\n  // SSE: _mm_storeu_si128 (unaligned store)\n  vst1q_u32(reinterpret_cast<uint32_t*>(dstp + dst_pitch * 0), result.val[0]);\n  vst1q_u32(reinterpret_cast<uint32_t*>(dstp + dst_pitch * 1), result.val[1]);\n  vst1q_u32(reinterpret_cast<uint32_t*>(dstp + dst_pitch * 2), result.val[2]);\n  vst1q_u32(reinterpret_cast<uint32_t*>(dstp + dst_pitch * 3), result.val[3]);\n}\n\n\nvoid turn_right_plane_32_neon(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n  const BYTE* s0 = srcp + src_pitch * (src_height - 1);\n  int w = src_rowsize & ~15; // 16 bytes for 32-bit elements (4 elements)\n  int h = src_height & ~3; // mod4 height\n\n  for (int y = 0; y < h; y += 4)\n  {\n    BYTE* d0 = dstp + y * 4;\n    // in 4x4 units, 16 bytes = 4x32-bit elements\n    for (int x = 0; x < w; x += 16)\n    {\n      transpose_32x4x4_neon(s0 + x, d0, -src_pitch, dst_pitch);\n      d0 += 4 * dst_pitch;\n    }\n    s0 -= 4 * src_pitch;\n  }\n  // rest non-mod4\n  if (src_rowsize != w)\n  {\n    turn_right_plane_32_c(srcp + w, dstp + w / 4 * dst_pitch, src_rowsize - w, src_height, src_pitch, dst_pitch);\n  }\n\n  if (src_height != h)\n  {\n    turn_right_plane_32_c(srcp, dstp + h * 4, src_rowsize, src_height - h, src_pitch, dst_pitch);\n  }\n}\n\nvoid turn_left_plane_32_neon(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n  turn_right_plane_32_neon(srcp + src_pitch * (src_height - 1), dstp + dst_pitch * (src_rowsize / 4 - 1), src_rowsize, src_height, -src_pitch, -dst_pitch);\n}\n\n\n// The 64-bit transpose: 2x2 double-word transpose\n// rgb64 helper\nstatic inline void turn_right_plane_64_neon(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n  const BYTE* s0 = srcp + src_pitch * (src_height - 1);\n  int w = src_rowsize & ~15; // 16 bytes = 2x64-bit elements\n  int h = src_height & ~1;\n\n  for (int y = 0; y < h; y += 2)\n  {\n    BYTE* d0 = dstp + y * 8;\n    for (int x = 0; x < w; x += 16)\n    {\n      // Load two 128-bit vectors\n      uint64x2_t a01 = vld1q_u64(reinterpret_cast<const uint64_t*>(s0 + x));\n      uint64x2_t b01 = vld1q_u64(reinterpret_cast<const uint64_t*>(s0 + x - src_pitch));\n\n      // Manual 2x2 64-bit element transpose\n      uint64x2x2_t ab;\n      ab.val[0] = vcombine_u64(vget_low_u64(a01), vget_low_u64(b01));   // {a0, b0}\n      ab.val[1] = vcombine_u64(vget_high_u64(a01), vget_high_u64(b01)); // {a1, b1}\n\n      vst1q_u64(reinterpret_cast<uint64_t*>(d0), ab.val[0]);         // a0 b0\n      vst1q_u64(reinterpret_cast<uint64_t*>(d0 + dst_pitch), ab.val[1]); // a1 b1\n      d0 += 2 * dst_pitch;\n    }\n    s0 -= 2 * src_pitch;\n  }\n\n  if (src_rowsize != w)\n  {\n    turn_right_plane_c<uint64_t>(srcp + w, dstp + w / 8 * dst_pitch, 8, src_height, src_pitch, dst_pitch);\n  }\n\n  if (src_height != h)\n  {\n    turn_right_plane_c<uint64_t>(srcp, dstp + h * 8, src_rowsize, 1, src_pitch, dst_pitch);\n  }\n\n}\n\n\nvoid turn_left_rgb64_neon(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n  turn_right_plane_64_neon(srcp, dstp, src_rowsize, src_height, src_pitch, dst_pitch);\n}\n\n\nvoid turn_right_rgb64_neon(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n  turn_right_plane_64_neon(srcp + src_pitch * (src_height - 1), dstp + dst_pitch * (src_rowsize / 8 - 1), src_rowsize, src_height, -src_pitch, -dst_pitch);\n}\n\n\n// Helper: swap the two 64-bit halves of a 128-bit vector.\n// vextq_* with an 8-byte offset concatenates the vector with itself and takes the high half.\nAVS_FORCEINLINE static uint8x16_t swap64_u8(uint8x16_t v) {\n  return vextq_u8(v, v, 8);\n}\n\n// lookup tables for byte and word reversal\nstatic const uint8_t idx_data_for_uint8[16] = { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };\nstatic const uint8_t idx_data_for_uint16[16] = { 14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1 };\n\ntemplate <typename T>\nvoid turn_180_plane_neon(const BYTE* srcp, BYTE* dstp,\n  int src_rowsize, int src_height,\n  int src_pitch, int dst_pitch)\n{\n  const uint8_t* AVS_RESTRICT s0 = srcp;\n  // always process 16 bytes at a time, 16 uint8_t or 8 uint16_t or 4 uint32_t or 2 uint64_t\n  uint8_t* AVS_RESTRICT d0 = dstp + dst_pitch * (src_height - 1) + src_rowsize;\n\n  const int mod16width = src_rowsize / 16 * 16; // mod16 width\n  const int mod8width = src_rowsize / 8 * 8;  // mod8 width\n  const uint8x16_t idx_8 = vld1q_u8(idx_data_for_uint8);\n  const uint8x16_t idx_16 = vld1q_u8(idx_data_for_uint16);\n\n  for (int y = 0; y < src_height; ++y) {\n    for (int x = 0; x < mod16width; x += 16) {\n      // load 16 bytes\n      uint8x16_t src = vld1q_u8(reinterpret_cast<const uint8_t*>(s0 + x));\n\n      uint8x16_t dst;\n\n      if constexpr (sizeof(T) == 8) {\n        // 64-bit pixels: reverse pixel ORDER but DO NOT reverse bytes per pixel.\n        // Swap the two 64-bit lanes only.\n        uint64x2_t src64 = vreinterpretq_u64_u8(src);\n        uint64x2_t rev = vextq_u64(src64, src64, 1);  // [hi, lo]\n        dst = vreinterpretq_u8_u64(rev);\n      }\n      else if constexpr (sizeof(T) == 4) {\n        // 32-bit pixels: reverse order of the 4 dwords.\n        //   1) reverse 32-bit elements within each 64-bit lane\n        //   2) swap the 64-bit lanes\n        uint32x4_t t1 = vrev64q_u32(vreinterpretq_u32_u8(src));  // per-lane 32-bit reverse\n        uint8x16_t t1b = vreinterpretq_u8_u32(t1);\n        dst = swap64_u8(t1b);  // swap halves via vextq_u8(t1b, t1b, 8)\n      }\n      else if constexpr (sizeof(T) == 2) {\n        // 16-bit pixels: reverse order of the 8 words.\n        //   1) reverse 16-bit elements within each 64-bit lane\n        //   2) swap the 64-bit lanes\n        /* slower:\n        uint16x8_t t1 = vrev64q_u16(vreinterpretq_u16_u8(src));\n        uint8x16_t t1b = vreinterpretq_u8_u16(t1);\n        dst = swap64_u8(t1b);  // swap halves\n        */\n        // do table lookup for full 16-byte reverse\n        dst = vqtbl1q_u8(src, idx_16);\n      }\n      else { // sizeof(T) == 1\n        // Use NEON table lookup for full 16-byte reverse\n        // Define the index array as a static const array\n        // let's hope, compiler optimizes this well\n        dst = vqtbl1q_u8(src, idx_8);\n        // this is said to have lower throughput than the vrev + vext method\n        // but benchmark shows it quicker on RPi5\n      }\n\n      // store reversed block to the mirror position in the destination row\n      vst1q_u8(reinterpret_cast<uint8_t*>(d0 - 16 - x), dst); // -16 SIMD width\n    }\n    for (int x = mod16width; x < mod8width; x+=8) {\n      // process 8 bytes at a time\n      uint8x8_t src = vld1_u8(reinterpret_cast<const uint8_t*>(s0 + x));\n\n      uint8x8_t dst;\n\n      if constexpr (sizeof(T) == 8) {\n        // mod8 block, size is 8, nothing to change.\n        dst = src; // Copy src to dst directly.\n      }\n      else if constexpr (sizeof(T) == 4) {\n        // 1) reverse 32-bit elements within the 64-bit lane. This is the whole job.\n        uint32x2_t t1 = vrev64_u32(vreinterpret_u32_u8(src));\n        dst = vreinterpret_u8_u32(t1); // Reinterpret and assign directly\n      }\n      else if constexpr (sizeof(T) == 2) {\n        // 16-bit pixels: reverse order of the 4 words.\n        dst = vtbl1_u8(src, vld1_u8(&idx_data_for_uint16[8])); // use upper half of idx\n      }\n      else { // sizeof(T) == 1\n        dst = vtbl1_u8(src, vld1_u8(&idx_data_for_uint8[8])); // use upper half of idx\n      }\n      vst1_u8(reinterpret_cast<uint8_t*>(d0 - 8 - x), dst); // -8 SIMD width\n    }\n\n    if (mod8width < src_rowsize) {\n      // plain C fallback for remaining bytes\n      const T* s00 = reinterpret_cast<const T*>(s0 + mod8width);\n      T* d00 = reinterpret_cast<T*>(d0 - sizeof(T) - mod8width); // - sizeof(T) \"SIMD\" width\n\n      for (int x = mod8width; x < src_rowsize; x += sizeof(T)) {\n        *d00-- = *s00++;\n      }\n    }\n\n    s0 += src_pitch;   // next source row\n    d0 -= dst_pitch;   // previous destination row (since we started at the last)\n  }\n\n}\n\n\n// instantiate\ntemplate void turn_180_plane_neon<uint8_t>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\ntemplate void turn_180_plane_neon<uint16_t>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\ntemplate void turn_180_plane_neon<uint32_t>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\ntemplate void turn_180_plane_neon<uint64_t>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\n\n\n\n// RGB functions (just calling the plane functions)\nvoid turn_left_rgb32_neon(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n  turn_right_plane_32_neon(srcp, dstp, src_rowsize, src_height, src_pitch, dst_pitch);\n}\n\n\nvoid turn_right_rgb32_neon(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n  turn_left_plane_32_neon(srcp, dstp, src_rowsize, src_height, src_pitch, dst_pitch);\n}\n\n\n"
  },
  {
    "path": "avs_core/filters/aarch64/turn_neon.h",
    "content": "// AviSynth+.  Copyright 2025 AviSynth+ Project\n// https://avs-plus.net\n// http://avisynth.nl\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef _AVS_TURN_NEON_H\n#define _AVS_TURN_NEON_H\n\n#include <avisynth.h>\n#include \"../turn.h\"\n\n// Other filters (e.g. resampler) might also use these functions\nvoid turn_left_plane_8_neon(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\nvoid turn_left_plane_16_neon(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\nvoid turn_left_plane_32_neon(const BYTE* srcp, BYTE* dstp, int src_rowsize, int srcHeight, int src_pitch, int dst_pitch);\nvoid turn_left_rgb32_neon(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\nvoid turn_left_rgb64_neon(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\nvoid turn_right_plane_8_neon(const BYTE* srcp, BYTE* dstp, int src_rowsize, int srcHeight, int src_pitch, int dst_pitch);\nvoid turn_right_plane_16_neon(const BYTE* srcp, BYTE* dstp, int src_rowsize, int srcHeight, int src_pitch, int dst_pitch);\nvoid turn_right_plane_32_neon(const BYTE* srcp, BYTE* dstp, int src_rowsize, int srcHeight, int src_pitch, int dst_pitch);\nvoid turn_right_rgb32_neon(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\nvoid turn_right_rgb64_neon(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\ntemplate <typename T>\nvoid turn_180_plane_neon(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\n\n#endif  // _AVS_TURN_NEON_H\n"
  },
  {
    "path": "avs_core/filters/color.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include \"color.h\"\n\n#include <math.h>\n#include <float.h>\n#if defined(AVS_BSD) || defined(AVS_MACOS)\n    #include <stdlib.h>\n#else\n    #include <malloc.h>\n#endif\n#include <stdio.h>\n\n#ifdef AVS_WINDOWS\n    #include <avs/win.h>\n#else\n    #include <avs/posix.h>\n#endif\n\n#include <avs/minmax.h>\n#include \"../core/internal.h\"\n#include <algorithm>\n#include <sstream> // stringstream\n#include <iomanip> // setprecision\n#include <string>\n#include \"../convert/convert_helper.h\"\n\nstatic void coloryuv_showyuv(BYTE* pY, BYTE* pU, BYTE* pV, int y_pitch, int u_pitch, int v_pitch, int framenumber, bool full_range, int bits_per_pixel)\n{\n  int internal_bitdepth = bits_per_pixel == 8 ? 8 : 10;\n\n  const int luma_min = full_range ? 0 : (16 << (internal_bitdepth - 8));\n  const int luma_max = full_range ? (1 << internal_bitdepth) - 1 : (235 << (internal_bitdepth - 8));\n\n  const int chroma_center = 128 << (internal_bitdepth - 8);\n  const int chroma_span = full_range ? (1 << (internal_bitdepth - 1)) - 1 : (112 << (internal_bitdepth - 8)); // +-127/+-112\n  const int chroma_min = chroma_center - chroma_span; // +-112 (16-240) -> +-127 (1-255)\n  const int chroma_max = chroma_center + chroma_span;\n\n  const int luma_range = luma_max - luma_min + 1; // 256/220 ,1024/880\n  const int chroma_range = chroma_max - chroma_min + 1;\n\n  const int luma_size = chroma_range * 2; // YUV output is always 4:2:0. Horizontal subsampling 2.\n\n  int luma;\n  // Calculate luma cycle\n  // 0,1..255,254,..1 = 2x256-2\n  // 0,1..1023,1022,..1 = 2*1024-2\n  luma = framenumber % (luma_range * 2 - 2);\n  if (luma > luma_range - 1)\n    luma = (luma_range * 2 - 2) - luma;\n  luma += luma_min;\n\n  // Set luma value\n  if (bits_per_pixel == 8) {\n    for (int y = 0; y < luma_size; y++) {\n      memset(pY, luma, luma_size);\n      pY += y_pitch;\n    }\n  }\n  else if (bits_per_pixel <= 16) {\n    // display size (thus luma range) covers the same as at 10 bits.\n    if (full_range) {\n      // stretch\n      const float factor = (float)((1 << bits_per_pixel) - 1) / ((1 << internal_bitdepth) - 1);\n      const int luma_target = (int)(luma * factor + 0.5f);\n      for (int y = 0; y < luma_size; y++) {\n        std::fill_n((uint16_t*)pY, luma_size, luma_target);\n        pY += y_pitch;\n      }\n    }\n    else {\n      // shift\n      const int luma_target = luma << (bits_per_pixel - internal_bitdepth);\n      for (int y = 0; y < luma_size; y++) {\n        std::fill_n((uint16_t*)pY, luma_size, luma_target);\n        pY += y_pitch;\n      }\n    }\n  }\n  else {\n    // 32 bit float\n    const float factor = 1.0f / ((1 << internal_bitdepth) - 1);\n    const float luma_target = luma * factor;\n    for (int y = 0; y < luma_size; y++) {\n      std::fill_n((float*)pY, luma_size, luma_target);\n      pY += y_pitch;\n    }\n  }\n\n  // Set chroma\n  if (full_range) {\n    if (bits_per_pixel != 32) {\n      // 8-16 bit full\n      const int chroma_center_target = 128 << (bits_per_pixel - 8);\n      const int chroma_span_target = full_range ? (1 << (bits_per_pixel - 1)) - 1 : (112 << (bits_per_pixel - 8)); // +-127/+-112\n      const float factor = (float)chroma_span_target / chroma_span;\n      const float chroma_center_target_plus_round = chroma_center_target + 0.5f;\n\n      if (bits_per_pixel == 8) {\n        for (int y = 0; y < chroma_range; y++)\n        {\n          for (int x = 0; x < chroma_range; x++) {\n            int pixel_u = chroma_min + x;\n            pixel_u = (int)((pixel_u - chroma_center) * factor + chroma_center_target_plus_round);\n            pU[x] = pixel_u;\n          }\n          int pixel_v = chroma_min + y;\n          pixel_v = (int)((pixel_v - chroma_center) * factor + chroma_center_target_plus_round);\n          std::fill_n((uint8_t*)pV, chroma_range, pixel_v);\n\n          pU += u_pitch;\n          pV += v_pitch;\n        }\n      }\n      else if (bits_per_pixel <= 16) {\n        for (int y = 0; y < chroma_range; y++)\n        {\n          for (int x = 0; x < chroma_range; x++) {\n            int pixel_u = chroma_min + x;\n            pixel_u = (int)((pixel_u - chroma_center) * factor + chroma_center_target_plus_round);\n            reinterpret_cast<uint16_t*>(pU)[x] = pixel_u;\n          }\n          int pixel_v = chroma_min + y;\n          pixel_v = (int)((pixel_v - chroma_center) * factor + chroma_center_target_plus_round);\n          std::fill_n((uint16_t*)pV, chroma_range, pixel_v);\n\n          pU += u_pitch;\n          pV += v_pitch;\n        }\n      }\n    }\n    else {\n      // 32 bit float, full\n      const float chroma_span_target = 0.5f; // +-0.5/+-112\n      const float factor = chroma_span_target / chroma_span;\n\n      for (int y = 0; y < chroma_range; y++)\n      {\n        for (int x = 0; x < chroma_range; x++) {\n          const int pixel_u = chroma_min + x;\n          const float pixel_u_f = (pixel_u - chroma_center) * factor;\n          reinterpret_cast<float*>(pU)[x] = pixel_u_f;\n        }\n\n        const int pixel_v = chroma_min + y;\n        const float pixel_v_f = (pixel_v - chroma_center) * factor;\n        std::fill_n((float*)pV, chroma_range, pixel_v_f);\n\n        pU += u_pitch;\n        pV += v_pitch;\n      }\n    }\n    // full end\n  }\n  else {\n    if (bits_per_pixel == 8) {\n      // 8 bit limited range\n      for (int y = 0; y < chroma_range; y++)\n      {\n        for (int x = 0; x < chroma_range; x++)\n          pU[x] = chroma_min + x;\n        const int pixel_v = chroma_min + y;\n        std::fill_n((uint8_t*)pV, chroma_range, pixel_v);\n        pU += u_pitch;\n        pV += v_pitch;\n      }\n    }\n    else if (bits_per_pixel <= 16) {\n      // 16 bit limited range\n      const int bitdiff = (bits_per_pixel - internal_bitdepth);\n      for (int y = 0; y < chroma_range; y++)\n      {\n        for (int x = 0; x < chroma_range; x++) {\n          reinterpret_cast<uint16_t*>(pU)[x] = (chroma_min + x) << bitdiff;\n        }\n        const int pixel_v = (chroma_min + y) << bitdiff;\n        std::fill_n((uint16_t*)pV, chroma_range, pixel_v);\n        pU += u_pitch;\n        pV += v_pitch;\n      }\n    }\n    else {\n      // 32 bit float limited\n      const float factor = 1.0f / ((1 << internal_bitdepth) - 1);\n      for (int y = 0; y < chroma_range; y++)\n      {\n        for (int x = 0; x < chroma_range; x++) {\n          reinterpret_cast<float*>(pU)[x] = (float)(chroma_min + x - chroma_center) * factor;\n        }\n        const float pixel_v = (float)(chroma_min + y - chroma_center) * factor;\n        std::fill_n((float*)pV, chroma_range, pixel_v);\n        pU += u_pitch;\n        pV += v_pitch;\n      }\n    }\n  }\n}\n\n// luts are only for integer bits 8/10/12/14/16. float will be realtime\ntemplate<typename pixel_t>\nstatic void coloryuv_create_lut(BYTE* lut8, const ColorYUVPlaneConfig* config, int bits_per_pixel, bool tweaklike_params)\n{\n  pixel_t* lut = reinterpret_cast<pixel_t*>(lut8);\n\n  // scale is 256/1024/4096/16384/65536\n  // normalize to [0..1) working range\n  const double value_normalization_scale = (double)((int64_t)1 << bits_per_pixel);\n  // For gamma pre-post correction. \n  const double tv_range_lo_normalized = 16.0 / 256.0;\n\n  const int lookup_size = 1 << bits_per_pixel; // 256, 1024, 4096, 16384, 65536\n  const int source_max = (1 << bits_per_pixel) - 1;\n  const bool chroma = config->plane == PLANAR_U || config->plane == PLANAR_V;\n  const bool fulls = config->range == COLORYUV_RANGE_PC_TV;\n  const bool fulld = config->range == COLORYUV_RANGE_TV_PC;\n  // when COLORYUV_RANGE_NONE both are the same false\n\n  //-----------------------\n  bits_conv_constants d;\n  // When calculating src_pixel, src and dst are of the same bit depth\n  get_bits_conv_constants(d, chroma, fulls, fulld, bits_per_pixel, bits_per_pixel);\n\n  auto dst_offset_plus_round = d.dst_offset + 0.5;\n  const int src_pixel_min = 0;\n  const int src_pixel_max = source_max;\n\n  // parameters are not scaled by bitdepth (legacy 8 bit behaviour)\n  double gain = tweaklike_params ? config->gain : (config->gain / 256 + 1.0);\n  double contrast = tweaklike_params ? config->contrast : (config->contrast / 256 + 1.0);\n  double gamma = tweaklike_params ? config->gamma : (config->gamma / 256 + 1.0);\n  double offset = config->offset / 256;\n\n  // for correct Y gamma\n  double range_factor_tv_to_pc = 255.0 / 219.0; // 16-235 ==> 0..255\n  double range_factor_pc_to_tv = 219.0 / 255.0; // 0..255 ==> 16-235 (219)\n\n  // for coring\n  const int tv_range_lo_luma_chroma = (16 << (bits_per_pixel - 8));\n  const int tv_range_hi_luma = (235 << (bits_per_pixel - 8));\n  const int tv_range_hi_chroma = (240 << (bits_per_pixel - 8));\n\n  // We know that the input is TV range for sure: (coring=true and !PC->TV), levels=\"TV->PC\" or (new!) levels=\"TV\"\n  const bool source_is_limited = (config->clip_tv && config->range != COLORYUV_RANGE_PC_TV) || config->range == COLORYUV_RANGE_TV_PC || config->force_tv_range;\n\n  for (int i = 0; i < lookup_size; i++) {\n    double value = double(i);\n    value /= value_normalization_scale; // normalize to [0..1). For chroma this makes the center to 0.5.\n    value *= gain; // Applying gain\n    // Applying contrast. For chroma, this sets saturation\n    value = (value - 0.5) * contrast + 0.5; // integer chroma center is transformed to 0, apply contrast\n    // in Classic AVS: constract is applied on the original value and not on the already gained value\n    // value = (value * gain) + ((value - 0.5) * contrast + 0.5) - value + (bright - 1);\n    value += offset; // Applying offset\n\n    // Applying gamma. Only on Y\n    if (gamma != 0) {\n      if (source_is_limited) {\n        // avs+ 180301- use gamma on the proper 0.0 based value\n        if (value > tv_range_lo_normalized)\n        {\n          // tv->pc\n          value = (value - tv_range_lo_normalized) * range_factor_tv_to_pc; // (v-16)*range\n          value = pow(value, 1.0 / gamma);\n          // pc->tv\n          value = value * range_factor_pc_to_tv + tv_range_lo_normalized; // v*range - 16\n        }\n      }\n      else { // full (PC) range\n        if (value > 0)\n          value = pow(value, 1.0 / gamma);\n      }\n    }\n\n    value *= value_normalization_scale; // back from [0..1) range\n\n    if (fulls != fulld)\n      // Range conversion\n      value = (value - d.src_offset) * d.mul_factor + dst_offset_plus_round;\n    else\n      value = value + 0.5; // rounder\n\n    // back to the integer world\n    int iValue = clamp((int)value, src_pixel_min, src_pixel_max);\n\n    if (config->clip_tv) // set when coring\n    {\n      iValue = clamp(iValue, tv_range_lo_luma_chroma, config->plane == PLANAR_Y ? tv_range_hi_luma : tv_range_hi_chroma);\n    }\n\n    lut[i] = iValue;\n  }\n}\n\n// works with <= 16 bits, but used only for float\nstatic std::string coloryuv_create_lut_expr(const ColorYUVPlaneConfig* config, int bits_per_pixel, bool tweaklike_params)\n{\n  const bool f32 = bits_per_pixel == 32;\n  const bool chroma = config->plane == PLANAR_U || config->plane == PLANAR_V;\n  // 32 bit float is already in [0..1] range but we have to make it similar to integer [0..1): needs /256 and not /255.\n  // Reason: match to the integer behaviour\n  // integer: normalize to [0..1) working range\n  const double value_normalization_scale = f32 ? (256.0 / 255.0) : (double)((int64_t)1 << bits_per_pixel);\n  // For gamma pre-post correction. we are in [0..1) working range\n  const double tv_range_lo_normalized = 16.0 / 256.0;\n\n  //const double source_max = f32 ? 1.0 : (double)((1 << bits_per_pixel) - 1);\n  const bool fulls = config->range == COLORYUV_RANGE_PC_TV;\n  const bool fulld = config->range == COLORYUV_RANGE_TV_PC;\n  // when COLORYUV_RANGE_NONE both are the same false\n\n  bits_conv_constants d;\n  // When calculating src_pixel, src and dst are of the same bit depth\n  get_bits_conv_constants(d, chroma, fulls, fulld, bits_per_pixel, bits_per_pixel);\n\n  auto dst_offset_no_round = d.dst_offset;\n  //const auto src_pixel_max = source_max;\n\n  // parameters are not scaled by bitdepth (legacy 8 bit behaviour)\n  double gain = tweaklike_params ? config->gain : (config->gain / 256 + 1.0);\n  double contrast = tweaklike_params ? config->contrast : (config->contrast / 256 + 1.0);\n  double gamma = tweaklike_params ? config->gamma : (config->gamma / 256 + 1.0);\n  double offset = config->offset / 256; // always in the 256 range\n\n  // for correct Y gamma\n  double range_factor_tv_to_pc = 255.0 / 219.0; // 16-235 ==> 0..255\n  double range_factor_pc_to_tv = 219.0 / 255.0; // 0..255 ==> 16-235 (219)\n\n  // We know that the input is TV range for sure: (coring=true and !PC->TV), levels=\"TV->PC\" or (new!) levels=\"TV\"\n  const bool source_is_limited = (config->clip_tv && config->range != COLORYUV_RANGE_PC_TV) || config->range == COLORYUV_RANGE_TV_PC || config->force_tv_range;\n\n  std::stringstream ss;\n\n  // value = double(i), we are using floats here\n  ss << \"x\";\n\n  // value = value / value_normalization_scale;\n  if (chroma && f32)\n    ss << \" 255 * 256 / 0.5 + \"; // from float chroma +/- to match with legacy integer behaviour\n  else\n    ss << \" \" << value_normalization_scale << \" /\";\n\n  if (gain != 1.0)\n    ss << \" \" << gain << \" *\"; // Applying gain // value *= gain;\n\n  // Applying contrast. For chroma, this sets saturation\n  //  value = (value - 0.5) * contrast + 0.5;\n  // earlier we made measures that float chroma center is kept at 0.5\n  ss << \" 0.5 - \" << contrast << \" * 0.5 +\";\n\n  // value += offset; // Applying offset\n  ss << \" \" << offset << \" +\";\n\n  // Applying gamma. Only on Y\n  if (gamma != 0) {\n    if (source_is_limited) {\n      // avs+ 180301- use gamma on the proper 0.0 based value\n      // value = value > 16scaled ? (pow((value - 16scl)*range_tv_pc,(1/gamma))*range_pc_tv+16d : value\n      ss << \" A@ \" << tv_range_lo_normalized << \" > \" // condition: value > tv_range_lo_normalized\n        // case: true. tv->pc, power, pc->tv\n        << \"A \" << tv_range_lo_normalized << \" - \" << range_factor_tv_to_pc << \" * \" << (1.0 / gamma) << \" pow \" << range_factor_pc_to_tv << \" * \" << tv_range_lo_normalized << \" + \" \n        // case: false. Original value\n        << \" A ? \";\n    }\n    else { // full (PC) range\n      //if (value > 0)\n      //  value = pow(value, 1.0 / gamma);\n      // value = value > 0 ? pow(value,(1/gamma)) : value\n      ss << \" A@ 0 > A \" << (1.0 / gamma) << \" pow A ? \";\n    }\n  }\n\n  if (chroma && f32)\n    ss << \" 0.5 - 256 * 255 / \";\n  else\n    ss << \" \" << value_normalization_scale << \" * \"; // value *= value_normalization_scale; // back from [0..1) range\n\n  if (fulls != fulld) {\n    ss << d.src_offset << \" - \" << d.mul_factor << \" * \" << dst_offset_no_round << \" + \";\n    // value = (value - d.src_offset) * d.mul_factor + dst_offset_no_round; // no rounder, Expr will round automatically before return\n  }\n  else {\n    // value = value + 0.5; // no rounder, Expr rounds\n  }\n\n  // clamp to the original valid bitdepth is done by Expr\n  // int iValue = clamp((int)value, src_pixel_min, src_pixel_max);\n  // ss << \" \" << src_pixel_min << \" max \" << src_pixel_max << \" min \";\n\n  if (config->clip_tv) // set when coring\n  {\n    double tv_range_lo_luma = f32 ? (16.0 / 255) : ((int64_t)16 << (bits_per_pixel - 8));\n    double tv_range_hi_luma = f32 ? (235.0 / 255) : ((int64_t)235 << (bits_per_pixel - 8));\n    double tv_range_lo_chroma = f32 ? (-112.0 / 255.0) : ((int64_t)16 << (bits_per_pixel - 8)); // 112/255.0 consistent with get_bits_conv_constants()\n    double tv_range_hi_chroma = f32 ? (+112.0 / 255.0) : ((int64_t)240 << (bits_per_pixel - 8));\n    ss << (config->plane == PLANAR_Y ? tv_range_lo_luma : tv_range_lo_chroma) << \" max \";\n    ss << (config->plane == PLANAR_Y ? tv_range_hi_luma : tv_range_hi_chroma) << \" min \";\n    //iValue = clamp(iValue, tv_range_lo_luma, config->plane == PLANAR_Y ? tv_range_hi_luma : tv_range_hi_chroma);\n  }\n\n  std::string exprString = ss.str();\n  return exprString;\n\n}\n\n// for float, only loose_min and loose_max is counted\ntemplate<bool forFloat>\nstatic void coloryuv_analyse_core(const int* freq, const int pixel_num, ColorYUVPlaneData* data, int bits_per_pixel_for_stat)\n{\n  // 32 bit float reached here as split into ranges like a 16bit clip\n  int pixel_value_count = 1 << bits_per_pixel_for_stat; // size of freq table\n\n  const int pixel_256th = pixel_num / 256; // For loose max/min yes, still 1/256!\n\n  double avg = 0.0;\n  int real_min, real_max;\n\n  if (!forFloat) {\n    real_min = -1;\n    real_max = -1;\n  }\n  data->loose_max = -1;\n  data->loose_min = -1;\n\n  int px_min_c = 0, px_max_c = 0;\n\n  for (int i = 0; i < pixel_value_count; i++)\n  {\n    if (!forFloat) {\n      avg += freq[i] * double(i);\n\n      if (freq[i] > 0 && real_min == -1)\n      {\n        real_min = i;\n      }\n    }\n\n    if (data->loose_min == -1)\n    {\n      px_min_c += freq[i];\n\n      if (px_min_c > pixel_256th)\n      {\n        data->loose_min = i;\n      }\n    }\n\n    if (!forFloat) {\n      if (freq[pixel_value_count - 1 - i] > 0 && real_max == -1)\n      {\n        real_max = pixel_value_count - 1 - i;\n      }\n    }\n\n    if (data->loose_max == -1)\n    {\n      px_max_c += freq[pixel_value_count - 1 - i];\n\n      if (px_max_c > pixel_256th)\n      {\n        data->loose_max = pixel_value_count - 1 - i;\n      }\n    }\n  }\n\n  if (!forFloat) {\n    avg /= pixel_num;\n    data->average = avg;\n    data->real_min = (float)real_min;\n    data->real_max = (float)real_max;\n  }\n}\n\n\nstatic void coloryuv_analyse_planar(const BYTE* pSrc, int src_pitch, int width, int height, ColorYUVPlaneData* data, int bits_per_pixel, bool chroma)\n{\n    // We can gather statistics from float, but for population count we have to\n    // split the range. We decide to split it into 2^16 ranges.\n    int bits_per_pixel_for_freq = bits_per_pixel <= 16 ? bits_per_pixel : 16;\n    int statistics_size = 1 << bits_per_pixel_for_freq; // float: 65536\n    int *freq = new int[statistics_size];\n    std::fill_n(freq, statistics_size, 0);\n\n    double sum = 0.0; // for float\n    float real_min;\n    float real_max;\n\n    if(bits_per_pixel==8) {\n      for (int y = 0; y < height; y++)\n      {\n          for (int x = 0; x < width; x++)\n          {\n              freq[pSrc[x]]++;\n          }\n\n          pSrc += src_pitch;\n      }\n    }\n    else if (bits_per_pixel >= 10 && bits_per_pixel <= 14) {\n      uint16_t mask = statistics_size - 1; // e.g. 0x3FF for 10 bit\n      for (int y = 0; y < height; y++)\n      {\n        for (int x = 0; x < width; x++)\n        {\n          freq[clamp(reinterpret_cast<const uint16_t *>(pSrc)[x],(uint16_t)0,mask)]++;\n        }\n\n        pSrc += src_pitch;\n      }\n    }\n    else if (bits_per_pixel == 16) {\n      // no clamp, faster\n      for (int y = 0; y < height; y++)\n      {\n        for (int x = 0; x < width; x++)\n        {\n          freq[reinterpret_cast<const uint16_t *>(pSrc)[x]]++;\n        }\n\n        pSrc += src_pitch;\n      }\n    } else if(bits_per_pixel==32) {\n      // 32 bits: we populate pixels only for loose_min and loose_max\n      // real_min and real_max, average (sum) is computed differently\n      real_min = reinterpret_cast<const float *>(pSrc)[0];\n      real_max = real_min;\n      if (chroma) {\n        const float shift = 32768.0f;\n        for (int y = 0; y < height; y++)\n        {\n          for (int x = 0; x < width; x++)\n          {\n            // -0.5..0.5 (0..1.0 when FLOAT_CHROMA_IS_HALF_CENTERED) to 0..65535\n            // see also: ConditionalFunctions MinMax\n            const float pixel = reinterpret_cast<const float *>(pSrc)[x];\n            freq[clamp((int)(65535.0f*pixel + shift + 0.5f), 0, 65535)]++;\n            // todo: SSE2\n            real_min = min(real_min, pixel);\n            real_max = max(real_max, pixel);\n            sum += pixel;\n          }\n          pSrc += src_pitch;\n        }\n      }\n      else {\n        for (int y = 0; y < height; y++)\n        {\n          for (int x = 0; x < width; x++)\n          {\n            // 0..1 -> 0..65535\n            const float pixel = reinterpret_cast<const float *>(pSrc)[x];\n            freq[clamp((int)(65535.0f*pixel + 0.5f), 0, 65535)]++;\n            // todo: SSE2\n            real_min = min(real_min, pixel);\n            real_max = max(real_max, pixel);\n            sum += pixel;\n          }\n\n          pSrc += src_pitch;\n        }\n      }\n    }\n\n\n    if (bits_per_pixel == 32) {\n      coloryuv_analyse_core<true>(freq, width*height, data, bits_per_pixel_for_freq);\n      data->average = sum / (height * width);\n      data->real_max = real_max;\n      data->real_min = real_min;\n      // loose min and max was shifted by half of 16bit range. We still keep here the range\n      if (chroma) {\n        data->loose_max = data->loose_max - 32768;\n        data->loose_min = data->loose_min - 32768;\n      }\n      // autogain treats it as a value of 16bit magnitude, show=true as well\n      //data->loose_min = data->loose_min / 65535.0f; not now.\n      //data->loose_max = data->loose_max / 65535.0f;\n    }\n    else {\n      coloryuv_analyse_core<false>(freq, width*height, data, bits_per_pixel_for_freq);\n    }\n\n    delete[] freq;\n}\n\nstatic void coloryuv_analyse_yuy2(const BYTE* pSrc, int src_pitch, int width, int height, ColorYUVPlaneData* dataY, ColorYUVPlaneData* dataU, ColorYUVPlaneData* dataV)\n{\n    int freqY[256], freqU[256], freqV[256];\n    memset(freqY, 0, sizeof(freqY));\n    memset(freqU, 0, sizeof(freqU));\n    memset(freqV, 0, sizeof(freqV));\n\n    for (int y = 0; y < height; y++)\n    {\n        for (int x = 0; x < width*2; x+=4)\n        {\n            freqY[pSrc[x+0]]++;\n            freqU[pSrc[x+1]]++;\n            freqY[pSrc[x+2]]++;\n            freqV[pSrc[x+3]]++;\n        }\n\n        pSrc += src_pitch;\n    }\n\n    coloryuv_analyse_core<false>(freqY, width*height, dataY, 8);\n    coloryuv_analyse_core<false>(freqU, width*height/2, dataU, 8);\n    coloryuv_analyse_core<false>(freqV, width*height/2, dataV, 8);\n}\n\nstatic void coloryuv_autogain(const ColorYUVPlaneData* dY, const ColorYUVPlaneData* dU, const ColorYUVPlaneData* dV, ColorYUVPlaneConfig* cY, ColorYUVPlaneConfig* cU, ColorYUVPlaneConfig* cV,\n  int bits_per_pixel, bool tweaklike_params)\n{\n  int bits_per_pixel_for_freq = bits_per_pixel <= 16 ? bits_per_pixel : 16; // for float: \"loose\" statistics like uint16_t\n  // always 16..235\n  int loose_max_limit = (235 + 1) << (bits_per_pixel_for_freq - 8);\n  int loose_min_limit = 16 << (bits_per_pixel_for_freq - 8);\n  int maxY = min(dY->loose_max, loose_max_limit);\n  int minY = max(dY->loose_min, loose_min_limit);\n\n  int range = maxY - minY;\n\n  if (range > 0) {\n    double scale = double(loose_max_limit - loose_min_limit) / range;\n    cY->offset = (loose_min_limit - scale * minY) / (1 << (bits_per_pixel_for_freq - 8)); // good for float also, 0..256 range\n    cY->gain = tweaklike_params ? scale : (256 * (scale - 1.0));\n    cY->changed = true;\n  }\n}\n\nstatic void coloryuv_autowhite(const ColorYUVPlaneData* dY, const ColorYUVPlaneData* dU, const ColorYUVPlaneData* dV, ColorYUVPlaneConfig* cY, ColorYUVPlaneConfig* cU, ColorYUVPlaneConfig* cV,\n  int bits_per_pixel)\n{\n  if (bits_per_pixel == 32) {\n#ifdef FLOAT_CHROMA_IS_HALF_CENTERED\n    double middle = 0.5;\n#else\n    double middle = 0.0;\n#endif\n    cU->offset = (middle - dU->average) * 256; // parameter is in 256 range\n    cV->offset = (middle - dV->average) * 256;\n  }\n  else {\n    double middle = (1 << (bits_per_pixel - 1)) - 1; // 128-1, 2048-1 ...\n    cU->offset = (middle - dU->average) / (1 << (bits_per_pixel - 8)); // parameter is in 256 range\n    cV->offset = (middle - dV->average) / (1 << (bits_per_pixel - 8));\n  }\n  cU->changed = true;\n  cV->changed = true;\n}\n\n// only for integer samples\nstatic void coloryuv_apply_lut_planar(BYTE* pDst, const BYTE* pSrc, int dst_pitch, int src_pitch, int width, int height, const BYTE* lut, int bits_per_pixel)\n{\n    if(bits_per_pixel==8)\n    {\n      for (int y = 0; y < height; y++)\n      {\n          for (int x = 0; x < width; x++)\n          {\n              pDst[x] = lut[pSrc[x]];\n          }\n\n          pSrc += src_pitch;\n          pDst += dst_pitch;\n      }\n    }\n    else if (bits_per_pixel >= 10 && bits_per_pixel <= 14) {\n      uint16_t max_pixel_value = (1 << bits_per_pixel) - 1;\n      // protection needed for lut\n      for (int y = 0; y < height; y++)\n      {\n        for (int x = 0; x < width; x++)\n        {\n          uint16_t pixel = reinterpret_cast<const uint16_t *>(pSrc)[x];\n          pixel = pixel <= max_pixel_value ? pixel : max_pixel_value;\n          reinterpret_cast<uint16_t *>(pDst)[x] = reinterpret_cast<const uint16_t *>(lut)[pixel];\n        }\n\n        pSrc += src_pitch;\n        pDst += dst_pitch;\n      }\n    }\n    else if (bits_per_pixel == 16) {\n      // no protection, faster\n      for (int y = 0; y < height; y++)\n      {\n        for (int x = 0; x < width; x++)\n        {\n          reinterpret_cast<uint16_t *>(pDst)[x] = reinterpret_cast<const uint16_t *>(lut)[reinterpret_cast<const uint16_t *>(pSrc)[x]];\n        }\n\n        pSrc += src_pitch;\n        pDst += dst_pitch;\n      }\n    }\n}\n\nstatic void coloryuv_apply_lut_yuy2(BYTE* pDst, const BYTE* pSrc, int dst_pitch, int src_pitch, int width, int height, const BYTE* lutY, const BYTE* lutU, const BYTE* lutV)\n{\n    for (int y = 0; y < height; y++)\n    {\n        for (int x = 0; x < width * 2; x += 4)\n        {\n            pDst[x+0] = lutY[pSrc[x + 0]];\n            pDst[x+1] = lutU[pSrc[x + 1]];\n            pDst[x+2] = lutY[pSrc[x + 2]];\n            pDst[x+3] = lutV[pSrc[x + 3]];\n        }\n\n        pSrc += src_pitch;\n        pDst += dst_pitch;\n    }\n}\n\n#define READ_CONDITIONAL(plane, var_name, internal_name, condVarSuffix)  \\\n    {            \\\n        std::string s = \"coloryuv_\" #var_name \"_\" #plane;\\\n        s = s + condVarSuffix; \\\n        const double t = env->GetVarDouble(s.c_str(), DBL_MIN); \\\n        if (t != DBL_MIN) {                               \\\n            c_##plane->internal_name = t;               \\\n            c_##plane->changed = true;                  \\\n        }                                                 \\\n    }\n\n// extra: add extra at the end of variable names: different variables for multiple instances of coloryuv\nstatic void coloryuv_read_conditional(IScriptEnvironment* env, ColorYUVPlaneConfig* c_y, ColorYUVPlaneConfig* c_u, ColorYUVPlaneConfig* c_v, const char *condVarSuffix)\n{\n    READ_CONDITIONAL(y, gain, gain, condVarSuffix);\n    READ_CONDITIONAL(y, off, offset, condVarSuffix);\n    READ_CONDITIONAL(y, gamma, gamma, condVarSuffix);\n    READ_CONDITIONAL(y, cont, contrast, condVarSuffix);\n\n    READ_CONDITIONAL(u, gain, gain, condVarSuffix);\n    READ_CONDITIONAL(u, off, offset, condVarSuffix);\n    READ_CONDITIONAL(u, gamma, gamma, condVarSuffix);\n    READ_CONDITIONAL(u, cont, contrast, condVarSuffix);\n\n    READ_CONDITIONAL(v, gain, gain, condVarSuffix);\n    READ_CONDITIONAL(v, off, offset, condVarSuffix);\n    READ_CONDITIONAL(v, gamma, gamma, condVarSuffix);\n    READ_CONDITIONAL(v, cont, contrast, condVarSuffix);\n}\n\n#undef READ_CONDITIONAL\n\nColorYUV::ColorYUV(PClip child,\n  double gain_y, double offset_y, double gamma_y, double contrast_y,\n  double gain_u, double offset_u, double gamma_u, double contrast_u,\n  double gain_v, double offset_v, double gamma_v, double contrast_v,\n  const char* level, const char* opt,\n  bool showyuv, bool analyse, bool autowhite, bool autogain, bool conditional,\n  int bits, bool showyuv_fullrange,\n  bool tweaklike_params, // ColorYUV2: 0.0/0.5/1.0/2.0/3.0 instead of -256/-128/0/256/512\n  const char* condVarSuffix,\n  bool optForceUseExpr,\n  IScriptEnvironment* env)\n  : GenericVideoFilter(child),\n  colorbar_bits(showyuv ? bits : 0), colorbar_fullrange(showyuv_fullrange),\n  analyse(analyse), autowhite(autowhite), autogain(autogain), conditional(conditional),\n  tweaklike_params(tweaklike_params), condVarSuffix(condVarSuffix), optForceUseExpr(optForceUseExpr)\n{\n  luts[0] = luts[1] = luts[2] = nullptr;\n\n  if (!vi.IsYUV() && !vi.IsYUVA())\n    env->ThrowError(\"ColorYUV: Only work with YUV colorspace.\");\n\n  bool ColorRangeCanBeGuessed = false;\n  if (gamma_y != 0) {\n    ColorRangeCanBeGuessed = true;\n    // when gamma is used then we must know the color range full/limited\n    // and the default is full_scale if gamma is not zero\n  }\n\n  configY.gain = gain_y;\n  configY.offset = offset_y;\n  configY.gamma = gamma_y;\n  configY.contrast = contrast_y;\n  configY.changed = false;\n  configY.clip_tv = false;\n  configY.force_tv_range = false;\n  configY.plane = PLANAR_Y;\n\n  configU.gain = gain_u;\n  configU.offset = offset_u;\n  configU.gamma = gamma_u;\n  configU.contrast = contrast_u;\n  configU.changed = false;\n  configU.clip_tv = false;\n  configU.force_tv_range = false; // n/a. in chroma. For gamma\n  configU.plane = PLANAR_U;\n\n  configV.gain = gain_v;\n  configV.offset = offset_v;\n  configV.gamma = gamma_v;\n  configV.contrast = contrast_v;\n  configV.changed = false;\n  configV.clip_tv = false;\n  configV.force_tv_range = false; // n/a. in chroma. For gamma\n  configV.plane = PLANAR_V;\n\n  // Range\n  if (lstrcmpi(level, \"TV->PC\") == 0)\n  {\n    ColorRangeCanBeGuessed = true; // will be full\n    configV.range = configU.range = configY.range = COLORYUV_RANGE_TV_PC;\n  }\n  else if (lstrcmpi(level, \"PC->TV\") == 0)\n  {\n    ColorRangeCanBeGuessed = true;// will be limited\n    configV.range = configU.range = configY.range = COLORYUV_RANGE_PC_TV;\n  }\n  else if (lstrcmpi(level, \"PC->TV.Y\") == 0)\n  {   // ?\n    ColorRangeCanBeGuessed = true;// will be limited\n    configV.range = configU.range = COLORYUV_RANGE_NONE;\n    configY.range = COLORYUV_RANGE_PC_TV;\n  }\n  else if (lstrcmpi(level, \"TV\") == 0)\n  {\n    // When no range conversion occurs only gamma correction\n    // By this parameter we know it will be limited, this info is used for gamma adjustment\n    ColorRangeCanBeGuessed = true;\n    configV.force_tv_range = configU.force_tv_range = configY.force_tv_range = true;\n  }\n  else if (lstrcmpi(level, \"\") != 0)\n  {\n    env->ThrowError(\"ColorYUV: invalid parameter : levels\");\n  }\n  else {\n    configV.range = configU.range = configY.range = COLORYUV_RANGE_NONE;\n  }\n\n  // Option\n  if (lstrcmpi(opt, \"coring\") == 0)\n  {\n    // note: this setting can conflict with e.g. TV->PC but we do not report an error\n    ColorRangeCanBeGuessed = true; // used to set _ColorRange=limited only if not conversion mode is specified\n    configY.clip_tv = true;\n    configU.clip_tv = true;\n    configV.clip_tv = true;\n  }\n  else if (lstrcmpi(opt, \"\") != 0)\n  {\n    env->ThrowError(\"ColorYUV: invalid parameter : opt\");\n  }\n\n  if (showyuv) {\n    if (colorbar_bits != 8 && colorbar_bits != 10 && colorbar_bits != 12 && colorbar_bits != 14 && colorbar_bits != 16 && colorbar_bits != 32)\n      env->ThrowError(\"ColorYUV: bits parameter for showyuv must be 8, 10, 12, 14, 16 or 32\");\n\n    switch (colorbar_bits) {\n    case 8: vi.pixel_type = VideoInfo::CS_YV12; break;\n    case 10: vi.pixel_type = VideoInfo::CS_YUV420P10; break;\n    case 12: vi.pixel_type = VideoInfo::CS_YUV420P12; break;\n    case 14: vi.pixel_type = VideoInfo::CS_YUV420P14; break;\n    case 16: vi.pixel_type = VideoInfo::CS_YUV420P16; break;\n    case 32: vi.pixel_type = VideoInfo::CS_YUV420PS; break;\n    }\n    // pre-avs+: coloryuv_showyuv is always called with full_range false\n    const int internal_bitdepth = colorbar_bits == 8 ? 8 : 10;\n    const int chroma_span = colorbar_fullrange ? (1 << (internal_bitdepth - 1)) - 1 : (112 << (internal_bitdepth - 8)); // +-127/+-112\n    const int chroma_range = 2 * chroma_span + 1; // 1..255 (+-127), 16..240 (+-112)\n    // size limited to either 8 or 10 bits, independenly of 12/14/16 or 32bit float bit-depth\n    vi.width = chroma_range << vi.GetPlaneWidthSubsampling(PLANAR_U);\n    vi.height = vi.width;\n    theColorRange = colorbar_fullrange ? ColorRange_Compat_e::AVS_COLORRANGE_FULL : ColorRange_Compat_e::AVS_COLORRANGE_LIMITED;\n    theMatrix = Matrix_e::AVS_MATRIX_BT470_BG; // all the same\n    theChromaLocation = ChromaLocation_e::AVS_CHROMA_CENTER; // default \"mpeg1\" for 4:2:0\n    return;\n  }\n\n  // !showyuv, real filter\n\n  auto frame0 = child->GetFrame(0, env);\n  const AVSMap* props = env->getFramePropsRO(frame0);\n  matrix_parse_merge_with_props_def(vi.IsRGB(), vi.IsRGB(), nullptr, props, theMatrix, theColorRange,\n    theOutColorRange, // n/a\n    Matrix_e::AVS_MATRIX_UNSPECIFIED, // default matrix n/a\n    configY.force_tv_range ? \n    ColorRange_Compat_e::AVS_COLORRANGE_LIMITED :  \n    ColorRangeCanBeGuessed ? ColorRange_Compat_e::AVS_COLORRANGE_FULL : -1 /* n/a invalid */, env);\n  // although we read _ColorRange full/limited, nothing stops us to feed with full-range clip a \"TV->PC\" conversion\n  // Anyway: a frame property can set theColorRange from the default \"FULL\" to the actual one.\n  switch (configY.range) {\n  case COLORYUV_RANGE_PC_TV:\n  case COLORYUV_RANGE_PC_TVY:\n    theColorRange = ColorRange_Compat_e::AVS_COLORRANGE_LIMITED;\n    break;\n  case COLORYUV_RANGE_TV_PC:\n    theColorRange = ColorRange_Compat_e::AVS_COLORRANGE_FULL;\n    break;\n  default:\n    if (configY.force_tv_range) // \"TV\" overrides default \"PC\". Info is needed for gamma correction\n      theColorRange = ColorRange_Compat_e::AVS_COLORRANGE_LIMITED;\n    else if (configY.clip_tv) // coring is also sets this frame property\n      theColorRange = ColorRange_Compat_e::AVS_COLORRANGE_LIMITED;\n    else\n      theColorRange = theOutColorRange;\n    break;\n    // leave color range as is\n  }\n  // theMatrix and theColorRange will set frame properties in GetFrame\n\n  // prepare basic LUT\n  int pixelsize = vi.ComponentSize();\n  int bits_per_pixel = vi.BitsPerComponent();\n\n  if (pixelsize == 1 || pixelsize == 2) {\n    // no float lut. float will be realtime\n    int lut_size = pixelsize * (1 << bits_per_pixel); // 256*1 / 1024*2 .. 65536*2\n    luts[0] = new BYTE[lut_size];\n    if (!vi.IsY()) {\n      luts[1] = new BYTE[lut_size];\n      luts[2] = new BYTE[lut_size];\n    }\n\n    if (pixelsize == 1) {\n      coloryuv_create_lut<uint8_t>(luts[0], &configY, bits_per_pixel, tweaklike_params);\n      if (!vi.IsY())\n      {\n        coloryuv_create_lut<uint8_t>(luts[1], &configU, bits_per_pixel, tweaklike_params);\n        coloryuv_create_lut<uint8_t>(luts[2], &configV, bits_per_pixel, tweaklike_params);\n      }\n    }\n    else if (pixelsize == 2) { // pixelsize==2\n      coloryuv_create_lut<uint16_t>(luts[0], &configY, bits_per_pixel, tweaklike_params);\n      if (!vi.IsY())\n      {\n        coloryuv_create_lut<uint16_t>(luts[1], &configU, bits_per_pixel, tweaklike_params);\n        coloryuv_create_lut<uint16_t>(luts[2], &configV, bits_per_pixel, tweaklike_params);\n      }\n    }\n  }\n}\n\nColorYUV::~ColorYUV() {\n  if (luts[0]) delete[] luts[0];\n  if (luts[1]) delete[] luts[1];\n  if (luts[2]) delete[] luts[2];\n}\n\n\nPVideoFrame __stdcall ColorYUV::GetFrame(int n, IScriptEnvironment* env)\n{\n    if (colorbar_bits>0)\n    {\n        PVideoFrame dst = env->NewVideoFrame(vi);\n        // no frame property source. It's like a source filter\n\n        auto props = env->getFramePropsRW(dst);\n        update_Matrix_and_ColorRange(props, theMatrix, theColorRange, env);\n        update_ChromaLocation(props, theChromaLocation, env);\n\n        // pre AVS+: full_range is always false\n        // AVS+: showyuv_fullrange bool parameter\n        // AVS+: bits parameter\n        coloryuv_showyuv(dst->GetWritePtr(), dst->GetWritePtr(PLANAR_U), dst->GetWritePtr(PLANAR_V), dst->GetPitch(), dst->GetPitch(PLANAR_U), dst->GetPitch(PLANAR_V), n, colorbar_fullrange, colorbar_bits);\n        return dst;\n    }\n\n    PVideoFrame src = child->GetFrame(n, env);\n    PVideoFrame dst;\n\n    int pixelsize = vi.ComponentSize();\n    int bits_per_pixel = vi.BitsPerComponent();\n\n    ColorYUVPlaneConfig // Yes, we copy these struct\n        cY = configY,\n        cU = configU,\n        cV = configV;\n\n    // for analysing data\n    char text[512];\n\n    if (analyse || autowhite || autogain)\n    {\n        ColorYUVPlaneData dY, dU, dV;\n\n        if (vi.IsYUY2())\n        {\n            coloryuv_analyse_yuy2(src->GetReadPtr(), src->GetPitch(), vi.width, vi.height, &dY, &dU, &dV);\n        }\n        else\n        {\n            coloryuv_analyse_planar(src->GetReadPtr(), src->GetPitch(), vi.width, vi.height, &dY, bits_per_pixel, false); // false: not chroma\n            if (!vi.IsY())\n            {\n                const int width = vi.width >> vi.GetPlaneWidthSubsampling(PLANAR_U);\n                const int height = vi.height >> vi.GetPlaneHeightSubsampling(PLANAR_U);\n\n                coloryuv_analyse_planar(src->GetReadPtr(PLANAR_U), src->GetPitch(PLANAR_U), width, height, &dU, bits_per_pixel, true); // true: chroma\n                coloryuv_analyse_planar(src->GetReadPtr(PLANAR_V), src->GetPitch(PLANAR_V), width, height, &dV, bits_per_pixel, true);\n            }\n        }\n\n        if (analyse)\n        {\n          if (!vi.IsY())\n          {\n            if (bits_per_pixel == 32)\n              sprintf(text,\n                \"        Frame: %-8u ( Luma Y / ChromaU / ChromaV )\\n\"\n                \"      Average:      ( %7.5f / %7.5f / %7.5f )\\n\"\n                \"      Minimum:      ( %7.5f / %7.5f / %7.5f )\\n\"\n                \"      Maximum:      ( %7.5f / %7.5f / %7.5f )\\n\"\n                \"Loose Minimum:      ( %7.5f / %7.5f / %7.5f )\\n\"\n                \"Loose Maximum:      ( %7.5f / %7.5f / %7.5f )\\n\",\n                n,\n                dY.average, dU.average, dV.average,\n                dY.real_min, dU.real_min, dV.real_min,\n                dY.real_max, dU.real_max, dV.real_max,\n                (float)dY.loose_min / 65535.0f, (float)dU.loose_min / 65535.0f, (float)dV.loose_min / 65535.0f,\n                (float)dY.loose_max / 65535.0f, (float)dU.loose_max / 65535.0f, (float)dV.loose_max / 65535.0f\n              );\n            else\n              sprintf(text,\n                \"        Frame: %-8u ( Luma Y / ChromaU / ChromaV )\\n\"\n                \"      Average:      ( %7.2f / %7.2f / %7.2f )\\n\"\n                \"      Minimum:      (  %5d  /  %5d  /  %5d   )\\n\"\n                \"      Maximum:      (  %5d  /  %5d  /  %5d   )\\n\"\n                \"Loose Minimum:      (  %5d  /  %5d  /  %5d   )\\n\"\n                \"Loose Maximum:      (  %5d  /  %5d  /  %5d   )\\n\",\n                n,\n                dY.average, dU.average, dV.average,\n                (int)dY.real_min, (int)dU.real_min, (int)dV.real_min,\n                (int)dY.real_max, (int)dU.real_max, (int)dV.real_max,\n                dY.loose_min, dU.loose_min, dV.loose_min,\n                dY.loose_max, dU.loose_max, dV.loose_max\n              );\n          }\n          else\n          {\n            if (bits_per_pixel == 32)\n              sprintf(text,\n                \"        Frame: %-8u\\n\"\n                \"      Average: %7.5f\\n\"\n                \"      Minimum: %7.5f\\n\"\n                \"      Maximum: %7.5f\\n\"\n                \"Loose Minimum: %7.5f\\n\"\n                \"Loose Maximum: %7.5f\\n\",\n                n,\n                dY.average,\n                dY.real_min,\n                dY.real_max,\n                (float)dY.loose_min / 65535.0f,\n                (float)dY.loose_max / 65535.0f\n              );\n            else\n              sprintf(text,\n                \"        Frame: %-8u\\n\"\n                \"      Average: %7.2f\\n\"\n                \"      Minimum: %5d\\n\"\n                \"      Maximum: %5d\\n\"\n                \"Loose Minimum: %5d\\n\"\n                \"Loose Maximum: %5d\\n\",\n                n,\n                dY.average,\n                (int)dY.real_min,\n                (int)dY.real_max,\n                dY.loose_min,\n                dY.loose_max\n              );\n          }\n        }\n\n        if (autowhite && !vi.IsY())\n        {\n            coloryuv_autowhite(&dY, &dU, &dV, &cY, &cU, &cV, bits_per_pixel);\n        }\n\n        if (autogain)\n        {\n            coloryuv_autogain(&dY, &dU, &dV, &cY, &cU, &cV, bits_per_pixel, tweaklike_params);\n        }\n    }\n\n    // Read conditional variables\n    if(conditional)\n      coloryuv_read_conditional(env, &cY, &cU, &cV, condVarSuffix);\n\n    // no float lut. float will be realtime\n    if ((pixelsize == 1 || pixelsize == 2) && !optForceUseExpr) {\n\n      BYTE *luts_live[3] = { nullptr };\n\n      BYTE *lutY = luts[0];\n      BYTE *lutU = luts[1];\n      BYTE *lutV = luts[2];\n\n      // recalculate plane LUT only if changed\n      int lut_size = pixelsize * (1 << bits_per_pixel); // 256*1 / 1024*2 .. 65536*2\n      if (cY.changed) {\n        luts_live[0] = new BYTE[lut_size];\n        lutY = luts_live[0];\n        if (pixelsize == 1)\n          coloryuv_create_lut<uint8_t>(lutY, &cY, bits_per_pixel, tweaklike_params);\n        else if (pixelsize == 2)\n          coloryuv_create_lut<uint16_t>(lutY, &cY, bits_per_pixel, tweaklike_params);\n      }\n\n      if (!vi.IsY())\n      {\n        if (cU.changed) {\n          luts_live[1] = new BYTE[lut_size];\n          lutU = luts_live[1];\n          if (pixelsize == 1)\n            coloryuv_create_lut<uint8_t>(lutU, &cU, bits_per_pixel, tweaklike_params);\n          else if (pixelsize == 2)\n            coloryuv_create_lut<uint16_t>(lutU, &cU, bits_per_pixel, tweaklike_params);\n        }\n        if (cV.changed) {\n          luts_live[2] = new BYTE[lut_size];\n          lutV = luts_live[2];\n          if (pixelsize == 1)\n            coloryuv_create_lut<uint8_t>(lutV, &cV, bits_per_pixel, tweaklike_params);\n          else if (pixelsize == 2)\n            coloryuv_create_lut<uint16_t>(lutV, &cV, bits_per_pixel, tweaklike_params);\n        }\n      }\n      dst = env->NewVideoFrameP(vi, &src);\n\n      if (vi.IsYUY2())\n      {\n        coloryuv_apply_lut_yuy2(dst->GetWritePtr(), src->GetReadPtr(), dst->GetPitch(), src->GetPitch(), vi.width, vi.height, lutY, lutU, lutV);\n      }\n      else\n      {\n        coloryuv_apply_lut_planar(dst->GetWritePtr(), src->GetReadPtr(), dst->GetPitch(), src->GetPitch(), vi.width, vi.height, lutY, bits_per_pixel);\n        if (!vi.IsY())\n        {\n          const int width = vi.width >> vi.GetPlaneWidthSubsampling(PLANAR_U);\n          const int height = vi.height >> vi.GetPlaneHeightSubsampling(PLANAR_U);\n\n          coloryuv_apply_lut_planar(dst->GetWritePtr(PLANAR_U), src->GetReadPtr(PLANAR_U), dst->GetPitch(PLANAR_U), src->GetPitch(PLANAR_U), width, height, lutU, bits_per_pixel);\n          coloryuv_apply_lut_planar(dst->GetWritePtr(PLANAR_V), src->GetReadPtr(PLANAR_V), dst->GetPitch(PLANAR_V), src->GetPitch(PLANAR_V), width, height, lutV, bits_per_pixel);\n        }\n        if (vi.IsYUVA()) {\n          env->BitBlt(dst->GetWritePtr(PLANAR_A), dst->GetPitch(PLANAR_A), src->GetReadPtr(PLANAR_A), src->GetPitch(PLANAR_A), src->GetRowSize(PLANAR_A), src->GetHeight(PLANAR_A));\n        }\n      }\n\n      if (luts_live[0]) delete[] luts_live[0];\n      if (luts_live[1]) delete[] luts_live[1];\n      if (luts_live[2]) delete[] luts_live[2];\n    } // lut create and use\n    else {\n      // 32 bit float: expr\n      std::string exprY = coloryuv_create_lut_expr(&cY, bits_per_pixel, tweaklike_params);\n      std::string exprU = !vi.IsY() ? coloryuv_create_lut_expr(&cU, bits_per_pixel, tweaklike_params) : \"\";\n      std::string exprV = !vi.IsY() ? coloryuv_create_lut_expr(&cV, bits_per_pixel, tweaklike_params) : \"\";\n      std::string exprA = \"\"; // copy\n      // Invoke Expr\n      AVSValue child2;\n      if (vi.IsY()) {\n        AVSValue new_args[2] = { child, exprY.c_str() };\n        child2 = env->Invoke(\"Expr\", AVSValue(new_args, 2)).AsClip();\n      }\n      else if(vi.IsYUV()) {\n        AVSValue new_args[4] = { child, exprY.c_str(), exprU.c_str(), exprV.c_str() };\n        child2 = env->Invoke(\"Expr\", AVSValue(new_args, 4)).AsClip();\n      }\n      else if (vi.IsYUVA()) {\n        AVSValue new_args[5] = { child, exprY.c_str(), exprU.c_str(), exprV.c_str(), exprA.c_str() };\n        child2 = env->Invoke(\"Expr\", AVSValue(new_args, 5)).AsClip();\n      }\n      dst = child2.AsClip()->GetFrame(n, env);\n    }\n\n    if (analyse)\n    {\n        env->ApplyMessage(&dst, vi, text, vi.width / 4, 0xa0a0a0, 0, 0);\n    }\n\n    // when there was no such property from constructor and it could not be guessed then we do not put one\n    if (theColorRange == ColorRange_Compat_e::AVS_COLORRANGE_FULL || theColorRange == ColorRange_Compat_e::AVS_COLORRANGE_LIMITED) {\n      auto props = env->getFramePropsRW(dst);\n      update_ColorRange(props, theColorRange, env);\n    }\n\n    return dst;\n}\n\nAVSValue __cdecl ColorYUV::Create(AVSValue args, void* , IScriptEnvironment* env)\n{\n    const bool tweaklike_params = args[23].AsBool(false); // f2c = true: for tweak-like parameter interpretation\n    const float def = tweaklike_params ? 1.0f : 0.0f;\n    return new ColorYUV(args[0].AsClip(),\n                        args[1].AsFloat(def),                // gain_y\n                        args[2].AsFloat(0.0f),                // off_y      bright\n                        args[3].AsFloat(def),                // gamma_y\n                        args[4].AsFloat(def),                // cont_y\n                        args[5].AsFloat(def),                // gain_u\n                        args[6].AsFloat(0.0f),                // off_u      bright\n                        args[7].AsFloat(def),                // gamma_u\n                        args[8].AsFloat(def),                // cont_u\n                        args[9].AsFloat(def),                // gain_v\n                        args[10].AsFloat(0.0f),                // off_v\n                        args[11].AsFloat(def),                // gamma_v\n                        args[12].AsFloat(def),                // cont_v\n                        args[13].AsString(\"\"),                // levels = \"\", \"TV->PC\", \"PC->TV\"\n                        args[14].AsString(\"\"),                // opt = \"\", \"coring\"\n//                      args[15].AsString(\"\"),                // matrix = \"\", \"rec.709\"\n                        args[16].AsBool(false),                // colorbars\n                        args[17].AsBool(false),                // analyze\n                        args[18].AsBool(false),                // autowhite\n                        args[19].AsBool(false),                // autogain\n                        args[20].AsBool(false),                // conditional\n                        args[21].AsInt(8),                     // bits avs+\n                        args[22].AsBool(false),                // showyuv_fullrange avs+\n                        tweaklike_params,                      // for gain, gamma, cont: 0.0/0.5/1.0/2.0/3.0 instead of -256/-128/0/256/512\n                        args[24].AsString(\"\"),                // condvarsuffix avs+\n                        args[25].AsBool(false),               // optForceUseExpr debug parameter\n      env);\n}\n\nextern const AVSFunction Color_filters[] = {\n    { \"ColorYUV\", BUILTIN_FUNC_PREFIX,\n                  \"c[gain_y]f[off_y]f[gamma_y]f[cont_y]f\" \\\n                  \"[gain_u]f[off_u]f[gamma_u]f[cont_u]f\" \\\n                  \"[gain_v]f[off_v]f[gamma_v]f[cont_v]f\" \\\n                  \"[levels]s[opt]s[matrix]s[showyuv]b\" \\\n                  \"[analyze]b[autowhite]b[autogain]b[conditional]b\" \\\n                  \"[bits]i[showyuv_fullrange]b[f2c]b[condvarsuffix]s[optForceUseExpr]b\", // avs+ 20180226- f2c-like parameters\n                  ColorYUV::Create},\n    { 0 }\n};\n\n"
  },
  {
    "path": "avs_core/filters/color.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#ifndef __Color_h\n#define __Color_h\n\n#include <avisynth.h>\n\nenum\n{\n    COLORYUV_RANGE_NONE,\n    COLORYUV_RANGE_TV_PC,\n    COLORYUV_RANGE_PC_TV,\n    COLORYUV_RANGE_PC_TVY\n};\n\nstruct ColorYUVPlaneData\n{\n    double average;\n    float real_min, real_max;\n    int loose_min, loose_max;\n};\n\nstruct ColorYUVPlaneConfig\n{\n    double gain, offset, gamma, contrast;\n    int range, plane;\n    bool clip_tv;\n    bool changed; // for lut recalc\n    bool force_tv_range; // telling to have TV range for gamma when no other parameters\n};\n\nclass ColorYUV : public GenericVideoFilter\n{\npublic:\n    ColorYUV(PClip child,\n             double gain_y, double offset_y, double gamma_y, double contrast_y,\n             double gain_u, double offset_u, double gamma_u, double contrast_u,\n             double gain_v, double offset_v, double gamma_v, double contrast_v,\n             const char* level, const char* opt,\n             bool showyuv, bool analyse, bool autowhite, bool autogain, bool conditional,\n             int bits, bool showyuv_fullrange, // avs+\n             bool tweaklike_params, // ColorYUV2: 0.0/0.5/1.0/2.0/3.0 instead of -256/-128/0/256/512\n             const char *condVarSuffix,\n             bool optForceUseExpr,\n             IScriptEnvironment* env);\n\n    PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n    int __stdcall SetCacheHints(int cachehints, int frame_range) override\n    {\n      AVS_UNUSED(frame_range);\n      return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n    }\n\n    static AVSValue Create(AVSValue args, void*, IScriptEnvironment* env);\n\n    ~ColorYUV();\n\nprivate:\n    ColorYUVPlaneConfig configY, configU, configV;\n    int colorbar_bits;\n    bool colorbar_fullrange;\n    bool analyse, autowhite, autogain, conditional;\n    bool tweaklike_params;\n    const char* condVarSuffix;\n    bool optForceUseExpr;\n    BYTE *luts[3];\n\n    int theColorRange;\n    int theOutColorRange;\n    int theMatrix;\n    int theChromaLocation;\n\n};\n\n#endif // __Color_h\n"
  },
  {
    "path": "avs_core/filters/colorbars_const.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#ifndef __COLORBARS_CONST_H\n#define __COLORBARS_CONST_H\n\n// ===== -I AND +Q SIGNAL CONSTANTS =====\n// Extracted for reuse in vectorscope graticule rendering\n// RGB-native values (lifted to studio black, code 16)\nconstexpr double MINUS_I_R = 0.0;\nconstexpr double MINUS_I_G = 0.33856;\nconstexpr double MINUS_I_B = 0.51916;\n\nconstexpr double PLUS_Q_R = 0.34736;\nconstexpr double PLUS_Q_G = 0.0;\nconstexpr double PLUS_Q_B = 0.58156;\n\n// YUV-targeted values (zero-luma, produces Y=16 after BT.601 conversion)\nconstexpr double MINUS_I_R_YUV = -0.20654;\nconstexpr double MINUS_I_G_YUV = 0.05911;\nconstexpr double MINUS_I_B_YUV = 0.23732;\n\nconstexpr double PLUS_Q_R_YUV = 0.13144;\nconstexpr double PLUS_Q_G_YUV = -0.13762;\nconstexpr double PLUS_Q_B_YUV = 0.36390;\n\n// Legacy 8-bit YUV codes for direct comparison\nconstexpr int MINUS_I_Y8_SD601 = 16;\nconstexpr int MINUS_I_CB8_SD601 = 158;\nconstexpr int MINUS_I_CR8_SD601 = 95;\n\n// Legacy 8-bit YUV codes (BT.601)\nconstexpr int PLUS_Q_Y8_SD601 = 16;\nconstexpr int PLUS_Q_CB8_SD601 = 174;\nconstexpr int PLUS_Q_CR8_SD601 = 149;\n\n// Legacy 8-bit YUV codes (BT.709)\nconstexpr int PLUS_Q_Y8_HD709 = 53;\nconstexpr int PLUS_Q_CB8_HD709 = 178;\nconstexpr int PLUS_Q_CR8_HD709 = 154;\n\n// ===== ColorBarsHD +I SIGNAL CONSTANT (BT.709) =====\n// SMPTE RP 219 / EG 1: +I Signal Reference (Rec. 709 / HD)\n// The +I (In-phase) signal is defined by its analog IRE levels:\n//   R = 41.2545 IRE, G = 16.6946 IRE, B = 0 IRE\n// Normalized Linear RGB (full range [0,1]): R: 0.412545, G: 0.166946, B: 0.000000\n// After BT.709 conversion: Y=61, Cb=103, Cr=157 at 8-bit\nconstexpr double PLUS_I_R_YUV = 0.412545;\nconstexpr double PLUS_I_G_YUV = 0.166946;\nconstexpr double PLUS_I_B_YUV = 0.0;\n\n// Legacy 8-bit YUV codes for +I (BT.709)\nconstexpr int PLUS_I_Y8_HD709 = 61;\nconstexpr int PLUS_I_CB8_HD709 = 103;\nconstexpr int PLUS_I_CR8_HD709 = 157;\n\n#endif // __COLORBARS_CONST_H\n"
  },
  {
    "path": "avs_core/filters/combine.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include \"combine.h\"\n#include \"../core/internal.h\"\n\n#ifdef AVS_WINDOWS\n    #include <avs/win.h>\n#else\n    #include <avs/posix.h>\n#endif\n\n#include <avs/minmax.h>\n#include <cmath>\n#include <cassert>\n#include <algorithm>\n\n\n\n\n/********************************************************************\n***** Declare index of new filters for Avisynth's filter engine *****\n********************************************************************/\n\nextern const AVSFunction Combine_filters[] = {\n  { \"StackVertical\", BUILTIN_FUNC_PREFIX, \"cc+\", StackVertical::Create },\n  { \"StackHorizontal\", BUILTIN_FUNC_PREFIX, \"cc+\", StackHorizontal::Create },\n  { \"MultiOverlay\", BUILTIN_FUNC_PREFIX, \"cc+i+\", MultiOverlay::Create },\n  { \"ShowFiveVersions\", BUILTIN_FUNC_PREFIX, \"ccccc\", ShowFiveVersions::Create },\n  // first come the custom function versions, bacause of array_of_anything finish\n  { \"Animate\", BUILTIN_FUNC_PREFIX, \"iisn.*\", Animate::Create, (void*)1 },  // start frame, end frame, filter, function, start-args, end-args\n  { \"Animate\", BUILTIN_FUNC_PREFIX, \"ciisn.*\", Animate::Create, (void*)1 },\n  // then the legacy linear version\n  { \"Animate\", BUILTIN_FUNC_PREFIX, \"iis.*\", Animate::Create, (void *)0 },  // start frame, end frame, filter, start-args, end-args\n  { \"Animate\", BUILTIN_FUNC_PREFIX, \"ciis.*\", Animate::Create, (void*)0 },\n  { \"ApplyRange\", BUILTIN_FUNC_PREFIX, \"ciis.*\", Animate::Create_Range, (void*)0 },\n  { 0 }\n};\n\n\n\n\n\n\n/********************************\n *******   StackVertical   ******\n ********************************/\n\nStackVertical::StackVertical(const std::vector<PClip>& child_array, IScriptEnvironment* env) :\n  children(child_array)\n{\n  vi = children[0]->GetVideoInfo();\n\n  for (size_t i = 1; i < children.size(); ++i) {\n    const VideoInfo& vin = children[i]->GetVideoInfo();\n\n    if (vi.width != vin.width)\n      env->ThrowError(\"StackVertical: image widths don't match\");\n\n    if (!vi.IsSameColorspace(vin))\n      env->ThrowError(\"StackVertical: image formats don't match\");\n\n    if (vi.num_frames < vin.num_frames) // Max of all clips\n      vi.num_frames = vin.num_frames;\n\n    vi.height += vin.height;\n  }\n\n  // reverse the order of the clips in RGB mode because it's upside-down\n  if (vi.IsRGB() && !vi.IsPlanarRGB() && !vi.IsPlanarRGBA()) {\n    std::reverse(children.begin(), children.end());\n    // get audio and parity from the first in the original list\n    firstchildindex = (int)children.size() - 1;\n  }\n  else {\n    firstchildindex = 0;\n  }\n}\n\n\nPVideoFrame __stdcall StackVertical::GetFrame(int n, IScriptEnvironment* env)\n{\n  std::vector<PVideoFrame> frames;\n  frames.reserve(children.size());\n\n  for (const auto& child: children)\n    frames.emplace_back(child->GetFrame(n, env));\n\n  PVideoFrame dst = env->NewVideoFrameP(vi, &frames[0]);\n\n  const int dst_pitch = dst->GetPitch();\n  const int row_size = dst->GetRowSize();\n  BYTE* dstp = dst->GetWritePtr();\n\n  for (const auto& src: frames)\n  {\n    const int src_height = src->GetHeight();\n    env->BitBlt(dstp, dst_pitch, src->GetReadPtr(), src->GetPitch(), row_size, src_height);\n    dstp += dst_pitch * src_height;\n  }\n\n  if (vi.IsPlanar() && (vi.NumComponents() > 1))\n  {\n    // Copy Planar\n    const int planesYUV[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A};\n    const int planesRGB[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A};\n    const int *planes = vi.IsYUV() || vi.IsYUVA() ? planesYUV : planesRGB;\n\n    // first plane is already processed\n    for (int p = 1; p < vi.NumComponents(); p++) {\n      const int plane = planes[p];\n      dstp = dst->GetWritePtr(plane);\n      const int dst_pitch = dst->GetPitch(plane);\n      const int row_size = dst->GetRowSize(plane);\n\n      for (const auto& src: frames)\n      {\n        const int src_height = src->GetHeight(plane);\n        env->BitBlt(dstp, dst_pitch, src->GetReadPtr(plane), src->GetPitch(plane), row_size, src_height);\n        dstp += dst_pitch * src_height;\n      }\n    }\n  }\n\n  return dst;\n}\n\nAVSValue __cdecl StackVertical::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  if (args[1].IsArray()) {\n    std::vector<PClip> children(1+args[1].ArraySize());\n\n    children[0] = args[0].AsClip();\n    for (int i = 1; i < (int)children.size(); ++i) // Copy clips\n      children[i] = args[1][i-1].AsClip();\n\n    return new StackVertical(children, env);\n  }\n  else if (args[1].IsClip()) { // Make easy to call with trivial 2 clips\n    std::vector<PClip> children(2);\n\n    children[0] = args[0].AsClip();\n    children[1] = args[1].AsClip();\n\n    return new StackVertical(children, env);\n  }\n  else {\n    env->ThrowError(\"StackVertical: clip array not recognized!\");\n    return 0;\n  }\n}\n\n/**********************************\n *******   MultiOverlay   ******\n **********************************/\n\n// Quick and dirty copy paste of N input clips onto the original (x,y)\n// optionally specifying offsets in source and dimensions\nMultiOverlay::MultiOverlay(const std::vector<PClip>& child_array, const std::vector<int>& position_array, IScriptEnvironment* env) :\n  children(child_array), positions(position_array)\n{\n  vi = children[0]->GetVideoInfo();\n\n  // 0th is the base clip\n  // 1.. the clips to overlay\n  for (size_t i = 1; i < children.size(); ++i) {\n    const VideoInfo& vin = children[i]->GetVideoInfo();\n    if (!vi.IsSameColorspace(vin))\n      env->ThrowError(\"MultiOverlay: image format must match with the base\");\n  }\n\n  const size_t copy_paste_count = children.size() - 1;\n  const size_t param_count = position_array.size();\n\n  // either 2 values per clip\n  //   target_x, target_y \n  // or 6 values per clip\n  //   target_x, target_y, src_x, src_y, src_width, src_height\n  if(copy_paste_count * 2 != param_count && copy_paste_count * 6 != param_count)\n    env->ThrowError(\"MultiOverlay: expected 2 or 6 values per source clip.\");\n\n  const bool grey = vi.IsY();\n  const bool isRGBPfamily = vi.IsPlanarRGB() || vi.IsPlanarRGBA();\n\n  const int shift_w = (vi.IsPlanar() && !grey && !isRGBPfamily) ? vi.GetPlaneWidthSubsampling(PLANAR_U) : 0;\n  const int shift_h = (vi.IsPlanar() && !grey && !isRGBPfamily) ? vi.GetPlaneHeightSubsampling(PLANAR_U) : 0;\n  const int mask_w = (1 << shift_w) - 1;\n  const int mask_h = (1 << shift_h) - 1;\n\n  auto params_per_clip = param_count / copy_paste_count;\n  for (size_t i = 0; i < copy_paste_count; i++) {\n    const VideoInfo& vin = children[i + 1]->GetVideoInfo();\n\n    const int target_x = positions[i * params_per_clip + 0];\n    const int target_y = positions[i * params_per_clip + 1];\n    if (target_x & mask_w)\n      env->ThrowError(\"MultiOverlay: target x must be mod %d for this video format\", (1 << shift_w));\n    if (target_y & mask_h)\n      env->ThrowError(\"MultiOverlay: target y must be mod %d for this video format\", (1 << shift_h));\n\n    if (params_per_clip == 6) {\n      // additional source position and dimensions\n      const int src_x = positions[i * params_per_clip + 2];\n      const int src_y = positions[i * params_per_clip + 3];\n      if (src_x < 0 || src_y < 0)\n        env->ThrowError(\"MultiOverlay: source coordinate cannot be negative.\");\n\n      const int src_w = positions[i * params_per_clip + 4];\n      const int src_h = positions[i * params_per_clip + 5];\n      if (src_w <= 0 || src_h <= 0)\n        env->ThrowError(\"MultiOverlay: source width and height must be positive.\");\n\n      if (src_x & mask_w)\n        env->ThrowError(\"MultiOverlay: source x must be mod %d for this video format\", (1 << shift_w));\n      if (src_y & mask_h)\n        env->ThrowError(\"MultiOverlay: source y must be mod %d for this video format\", (1 << shift_h));\n      if (src_w & mask_w)\n        env->ThrowError(\"MultiOverlay: source width must be mod %d for this video format\", (1 << shift_w));\n      if (src_h & mask_h)\n        env->ThrowError(\"MultiOverlay: source height must be mod %d for this video format\", (1 << shift_h));\n\n      if (src_x + src_w > vin.width)\n        env->ThrowError(\"MultiOverlay: copy exceeds clip width. x=%d, size=%d, clip width=%d\", src_x, src_w, vin.width);\n      if (src_y + src_h > vin.height)\n        env->ThrowError(\"MultiOverlay: copy exceeds clip height. y=%d, size=%d, clip height=%d\", src_y, src_h, vin.height);\n    }\n  }\n}\n\nPVideoFrame __stdcall MultiOverlay::GetFrame(int n, IScriptEnvironment* env)\n{\n  std::vector<PVideoFrame> frames;\n  frames.reserve(children.size());\n\n  for (const auto& child : children)\n    frames.emplace_back(child->GetFrame(n, env));\n\n  PVideoFrame dst = frames[0]; // multioverlay target clip\n  env->MakeWritable(&dst);\n\n  const size_t copy_paste_count = children.size() - 1;\n  const size_t param_count = positions.size();\n  const size_t params_per_clip = param_count / copy_paste_count; // 2 or 6\n  const bool source_extra = params_per_clip == 6;\n\n  // packed RGB is upside down\n  const bool is_packed_rgb = vi.IsRGB24() || vi.IsRGB32() || vi.IsRGB48() || vi.IsRGB64();\n  const int bfp = is_packed_rgb || vi.IsYUY2() ? vi.BytesFromPixels(1) : vi.ComponentSize();\n  // also for packed RGBs, pixelsize is not enough\n\n  const int planesPacked[] = { DEFAULT_PLANE, DEFAULT_PLANE , DEFAULT_PLANE , DEFAULT_PLANE };\n  const int planesYUV[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };\n  const int planesRGB[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A };\n  const int* planes = is_packed_rgb ? planesPacked : vi.IsY() || vi.IsYUV() || vi.IsYUVA() ? planesYUV : planesRGB;\n\n  const int planecount = is_packed_rgb || vi.IsYUY2() ? 1 : vi.NumComponents();\n\n  for (int p = 0; p < planecount; p++) {\n    const int plane = planes[p];\n    BYTE* dstp = dst->GetWritePtr(plane);\n    const int dst_pitch = dst->GetPitch(plane);\n    const int dst_height = dst->GetHeight(plane);\n\n    // 0th was the target\n    for (size_t i = 1; i < frames.size(); i++)\n    {\n      const auto& src = frames[i];\n      const int src_rowsize = src->GetRowSize(plane);\n\n      // these may be safely overridden\n      int src_width = src_rowsize / bfp;\n      int src_height = src->GetHeight(plane);\n\n      const BYTE* srcp = src->GetReadPtr(plane);\n      const int src_pitch = src->GetPitch(plane);\n\n      // packed RGB a Y and all 0th plane is not subsampled.\n      const int shift_w = p == 0 ? 0 : vi.GetPlaneWidthSubsampling(plane);\n      const int shift_h = p == 0 ? 0 : vi.GetPlaneHeightSubsampling(plane);\n\n      int target_x = positions[(i - 1) * params_per_clip + 0] >> shift_w;\n      int target_y = positions[(i - 1) * params_per_clip + 1] >> shift_h;\n\n      int dst_w = dst->GetRowSize(plane) / bfp;\n\n      int src_x = 0;\n      int src_y = 0;\n      int src_w = src_width;\n      int src_h = src_height;\n\n      if (source_extra) {\n        src_x = positions[(i - 1) * params_per_clip + 2] >> shift_w;;\n        src_y = positions[(i - 1) * params_per_clip + 3] >> shift_h;;\n        src_w = positions[(i - 1) * params_per_clip + 4] >> shift_w;;\n        src_h = positions[(i - 1) * params_per_clip + 5] >> shift_h;;\n      }\n      // bring negative target coordinates to 0, \n      // adjust source position and dimension accordingly\n      if (target_x < 0) {\n        src_x += -target_x;\n        src_w -= -target_x;\n        target_x = 0;\n      }\n      if (target_y < 0) {\n        src_y += -target_y;\n        src_h -= -target_y;\n        target_y = 0;\n      }\n\n      // check and limit dimension parameters\n      \n      // Already checked at filter creation:\n      // o coordinates and dimensions are subsampling friendly\n      // o target x and y >= 0\n      // o source width and height > 0\n      // o src_x + src_width and src_y + src_height fit in source clip dimensions\n\n      if (src_h > src_height)\n        src_h = src_height;\n      if (target_y + src_h > dst_height)\n        src_h -= (target_y + src_h - dst_height);\n\n      if (src_w > src_width)\n        src_w = src_width;\n      if (target_x + src_w > dst_w)\n        src_w -= (target_x + src_w - dst_w);\n\n      if (src_w > 0 && src_h > 0) {\n        src_height = src_h;\n        src_width = src_w * bfp;\n\n        if (is_packed_rgb) {\n          // start from bottom: packed RGB is upside down\n          src_y = (src->GetHeight(plane) - src_y - 1) - (src_height - 1);\n          target_y = (dst_height - target_y - 1) - (src_height - 1);\n        }\n\n        env->BitBlt(\n          dstp + target_x * bfp + target_y * dst_pitch, dst_pitch,\n          srcp + src_x * bfp + src_y * src_pitch, src_pitch, src_width, src_height);\n      }\n    }\n  }\n\n  return dst;\n}\n\nAVSValue __cdecl MultiOverlay::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  std::vector<PClip> children;\n  if (args[1].IsArray()) {\n    children.resize(1 + args[1].ArraySize());\n\n    children[0] = args[0].AsClip();\n    for (int i = 1; i < (int)children.size(); ++i) // Copy clips\n      children[i] = args[1][i - 1].AsClip();\n  }\n  else if (args[1].IsClip()) { // Make easy to call with trivial 2 clips\n    children.resize(2);\n\n    children[0] = args[0].AsClip();\n    children[1] = args[1].AsClip();\n\n  }\n  else {\n    env->ThrowError(\"MultiOverlay: clip array not recognized!\");\n    return 0;\n  }\n\n  std::vector<int> positions;\n  if (!args[2].IsArray()) {\n    env->ThrowError(\"MultiOverlay: position array not recognized!\");\n    return 0;\n  }\n  const int pos_count = args[2].ArraySize();\n  if (pos_count != 2 * (children.size() - 1) && pos_count != 6 * (children.size() - 1))\n    env->ThrowError(\"MultiOverlay: position array must contain 2 or 6 entries for each clip to overlay!\");\n  positions.resize(pos_count); // x,y for each overlay clip\n\n  for (int i = 0; i < pos_count; ++i) // Copy positions, x, y, or x, y, src_x, src_y, src_width, src_height\n    positions[i] = args[2][i].AsInt();\n\n  return new MultiOverlay(children, positions, env);\n\n}\n\n\n/**********************************\n *******   StackHorizontal   ******\n **********************************/\n\nStackHorizontal::StackHorizontal(const std::vector<PClip>& child_array, IScriptEnvironment* env) :\n  children(child_array)\n{\n  vi = children[0]->GetVideoInfo();\n\n  for (size_t i = 1; i < children.size(); ++i) {\n    const VideoInfo& vin = children[i]->GetVideoInfo();\n\n    if (vi.height != vin.height)\n      env->ThrowError(\"StackHorizontal: image heights don't match\");\n\n    if (!vi.IsSameColorspace(vin))\n      env->ThrowError(\"StackHorizontal: image formats don't match\");\n\n    if (vi.num_frames < vin.num_frames) // Max of all clips\n      vi.num_frames = vin.num_frames;\n\n    vi.width += vin.width;\n  }\n}\n\nPVideoFrame __stdcall StackHorizontal::GetFrame(int n, IScriptEnvironment* env)\n{\n  std::vector<PVideoFrame> frames;\n  frames.reserve(children.size());\n\n  for (const auto& child : children)\n    frames.emplace_back(child->GetFrame(n, env));\n\n  PVideoFrame dst = env->NewVideoFrameP(vi, &frames[0]);\n  const int dst_pitch = dst->GetPitch();\n  const int height = dst->GetHeight();\n\n  BYTE* dstp = dst->GetWritePtr();\n  for (const auto& src: frames)\n  {\n    const int src_rowsize = src->GetRowSize();\n    env->BitBlt(dstp, dst_pitch, src->GetReadPtr(), src->GetPitch(), src_rowsize, height);\n    dstp += src_rowsize;\n  }\n\n  if (vi.IsPlanar() && (vi.NumComponents() > 1)) {\n    // Copy Planar\n\n    const int planesYUV[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A};\n    const int planesRGB[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A};\n    const int *planes = vi.IsYUV() || vi.IsYUVA() ? planesYUV : planesRGB;\n\n    // first plane is already processed\n    for (int p = 1; p < vi.NumComponents(); p++) {\n      const int plane = planes[p];\n      dstp = dst->GetWritePtr(plane);\n      const int dst_pitch = dst->GetPitch(plane);\n      const int height = dst->GetHeight(plane);\n\n      for (const auto& src: frames)\n      {\n        const int src_rowsize = src->GetRowSize(plane);\n        env->BitBlt(dstp, dst_pitch, src->GetReadPtr(plane), src->GetPitch(plane), src_rowsize, height);\n        dstp += src_rowsize;\n      }\n    }\n  }\n\n  return dst;\n}\n\nAVSValue __cdecl StackHorizontal::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  if (args[1].IsArray()) {\n    std::vector<PClip> children(1+args[1].ArraySize());\n\n    children[0] = args[0].AsClip();\n    for (int i = 1; i < (int)children.size(); ++i) // Copy clips\n      children[i] = args[1][i-1].AsClip();\n\n    return new StackHorizontal(children, env);\n  }\n  else if (args[1].IsClip()) { // Make easy to call with trivial 2 clips\n    std::vector<PClip> children(2);\n\n    children[0] = args[0].AsClip();\n    children[1] = args[1].AsClip();\n\n    return new StackHorizontal(children, env);\n  }\n  else {\n    env->ThrowError(\"StackHorizontal: clip array not recognized!\");\n    return 0;\n  }\n}\n\n\n\n/********************************\n *******   Five Versions   ******\n ********************************/\n\nShowFiveVersions::ShowFiveVersions(PClip* children, IScriptEnvironment* env)\n{\n  for (int b=0; b<5; ++b)\n    child[b] = children[b];\n\n  vi = child[0]->GetVideoInfo();\n\n  for (int c=1; c<5; ++c)\n  {\n    const VideoInfo& viprime = child[c]->GetVideoInfo();\n    vi.num_frames = max(vi.num_frames, viprime.num_frames);\n    if (vi.width != viprime.width || vi.height != viprime.height || vi.pixel_type != viprime.pixel_type)\n      env->ThrowError(\"ShowFiveVersions: video attributes of all clips must match\");\n  }\n\n  vi.width  *= 3;\n  vi.height *= 2;\n}\n\nPVideoFrame __stdcall ShowFiveVersions::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame dst = env->NewVideoFrame(vi);\n  // frame property source is set later\n  BYTE* dstp = dst->GetWritePtr();\n  BYTE* dstpU = dst->GetWritePtr(PLANAR_U);\n  BYTE* dstpV = dst->GetWritePtr(PLANAR_V);\n  const int dst_pitch = dst->GetPitch();\n  const int dst_pitchUV = dst->GetPitch(PLANAR_U);\n  const int height = dst->GetHeight()/2;\n  const int heightUV = dst->GetHeight(PLANAR_U)/2;\n  // todo: >8 bits, planar RGB\n  if (vi.IsYUV()) {\n    const int wg = dst->GetRowSize()/6;\n    for (int i=0; i<height; i++){\n      memset(dstp + ((height+i)*dst_pitch),        128, wg);\n      memset(dstp + ((height+i)*dst_pitch) + wg*5, 128, wg);\n    }\n    if (dst_pitchUV) {\n      const int wgUV = dst->GetRowSize(PLANAR_U)/6;\n      for (int i=0; i<heightUV; i++) {\n        memset(dstpU + ((heightUV+i)*dst_pitchUV),          128, wgUV);\n        memset(dstpU + ((heightUV+i)*dst_pitchUV) + wgUV*5, 128, wgUV);\n        memset(dstpV + ((heightUV+i)*dst_pitchUV),          128, wgUV);\n        memset(dstpV + ((heightUV+i)*dst_pitchUV) + wgUV*5, 128, wgUV);\n      }\n    }\n  }\n  else { // vi.IsRGB()\n    const int wg = dst->GetRowSize()/6;\n    for (int i=0; i<height; i++){\n      memset(dstp + i*dst_pitch,        128, wg);\n      memset(dstp + i*dst_pitch + wg*5, 128, wg);\n    }\n  }\n\n  for (int c=0; c<5; ++c)\n  {\n    PVideoFrame src = child[c]->GetFrame(n, env);\n\n    if(c == 0) // copy frame properties from the very first\n      env->copyFrameProps(src, dst);\n\n    if (vi.IsPlanar()) {\n      const BYTE* srcpY = src->GetReadPtr(PLANAR_Y);\n      const BYTE* srcpU = src->GetReadPtr(PLANAR_U);\n      const BYTE* srcpV = src->GetReadPtr(PLANAR_V);\n      const int src_pitchY  = src->GetPitch(PLANAR_Y);\n      const int src_pitchUV = src->GetPitch(PLANAR_U);\n      const int src_row_sizeY  = src->GetRowSize(PLANAR_Y);\n      const int src_row_sizeUV = src->GetRowSize(PLANAR_U);\n\n      // staggered arrangement\n      BYTE* dstp2  = dstp  + (c>>1) * src_row_sizeY;\n      BYTE* dstp2U = dstpU + (c>>1) * src_row_sizeUV;\n      BYTE* dstp2V = dstpV + (c>>1) * src_row_sizeUV;\n      if (c&1) {\n        dstp2  += (height   * dst_pitch)   + src_row_sizeY /2;\n        dstp2U += (heightUV * dst_pitchUV) + src_row_sizeUV/2;\n        dstp2V += (heightUV * dst_pitchUV) + src_row_sizeUV/2;\n      }\n\n      env->BitBlt(dstp2,  dst_pitch,   srcpY, src_pitchY,  src_row_sizeY,  height);\n      env->BitBlt(dstp2U, dst_pitchUV, srcpU, src_pitchUV, src_row_sizeUV, heightUV);\n      env->BitBlt(dstp2V, dst_pitchUV, srcpV, src_pitchUV, src_row_sizeUV, heightUV);\n    }\n    else {\n      const BYTE* srcp = src->GetReadPtr();\n      const int src_pitch = src->GetPitch();\n      const int src_row_size = src->GetRowSize();\n\n      // staggered arrangement\n      BYTE* dstp2 = dstp + (c>>1) * src_row_size;\n      if ((c&1)^vi.IsRGB())\n        dstp2 += (height * dst_pitch);\n      if (c&1)\n        dstp2 += vi.BytesFromPixels(vi.width/6);\n\n      env->BitBlt(dstp2, dst_pitch, srcp, src_pitch, src_row_size, height);\n    }\n  }\n\n  return dst;\n}\n\n\nAVSValue __cdecl ShowFiveVersions::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  PClip children[5];\n  for (int i=0; i<5; ++i)\n    children[i] = args[i].AsClip();\n  return new ShowFiveVersions(children, env);\n}\n\n\n\n\n\n\n\n\n\n\n/**************************************\n *******   Animate (Recursive)   ******\n **************************************/\n\nAnimate::Animate( PClip context, int _first, int _last, const char* _name, const AVSValue* _args_before,\n                  const AVSValue* _args_after, int _num_args, bool _range_limit, const AVSValue& _custom_fn, IScriptEnvironment* env )\n   : first(_first), last(_last), num_args(_num_args), name(_name), range_limit(_range_limit), custom_fn(_custom_fn)\n{\n  if (first > last)\n    env->ThrowError(\"Animate: final frame number must be greater than initial.\");\n\n  if (first == last && (!range_limit))\n    env->ThrowError(\"Animate: final frame cannot be the same as initial frame.\");\n\n  // check that argument types match\n  for (int arg=0; arg<num_args; ++arg) {\n    const AVSValue& a = _args_before[arg];\n    const AVSValue& b = _args_after[arg];\n    if (a.IsString() && b.IsString()) {\n      if (lstrcmp(a.AsString(), b.AsString()))\n        env->ThrowError(\"Animate: string arguments must match before and after\");\n    }\n    else if (a.IsBool() && b.IsBool()) {\n      if (a.AsBool() != b.AsBool())\n        env->ThrowError(\"Animate: boolean arguments must match before and after\");\n    }\n    else if (a.IsFloat() && b.IsFloat()) {\n      // ok; also catches other numeric types\n    }\n    else if (a.IsClip() && b.IsClip()) {\n      // ok\n    }\n    else {\n      env->ThrowError(\"Animate: must have two argument lists with matching types\");\n    }\n  }\n\n  if (custom_fn.IsFunction()) {\n    // pre-check validity\n\n    // We could even check if function returns f(0.0) = 0.0 and f(1.0) = 1.0\n    // But we are not that serious. Who implements custom function, will take care of it if needed\n    constexpr bool check_first = false;\n    constexpr bool check_last = false;\n\n    double result_first = 0.0;\n    double result_last = 1.0;\n    PFunction func = custom_fn.AsFunction();\n    try {\n\n      // The Animate callback is a plain scalar function, no child\n      // one compulsory double \"stage\" parameter\n      const char* argnames[1] = { \"stage\" };\n\n      // for syntax check this is always called\n      AVSValue test1_args[1] = { 0.0 };\n      const AVSValue test1_args_array = AVSValue(test1_args, 1);\n      result_first = env->Invoke3(AVSValue(), func, test1_args_array, argnames).AsFloat();\n\n      if (check_last) {\n        if (first != last) {\n          AVSValue test2_args[1] = { 1.0 };\n          const AVSValue test2_args_array = AVSValue(test2_args, 1);\n          result_last = env->Invoke3(AVSValue(), func, test2_args_array, argnames).AsFloat();\n        }\n      }\n    }\n    catch (IScriptEnvironment::NotFound) {\n      env->ThrowError(\"Animate: Invalid function parameter type '%s'(%s)\\n\"\n        \"Function must have exactly one float argument: stage\",\n        func->GetDefinition()->param_types, func->ToString(env));\n    }\n    catch (const AvisynthError& error) {\n      env->ThrowError(\"Animate: Error in custom function: %s\\n%s\",\n        func->ToString(env), error.msg);\n    }\n\n    if (check_first && result_first != 0.0)\n      env->ThrowError(\"Animate: Error in custom function, for stage 0.0: 0.0 must be returned.\\n%s\\n\",\n        func->ToString(env));\n    if (check_last && result_last != 1.0)\n      env->ThrowError(\"Animate: Error in custom function, for stage 1.0: 1.0 must be returned.\\n%s\\n\",\n        func->ToString(env));\n  }\n\n  // copy args, and add initial clip arg for OOP notation\n\n  if (context)\n    num_args++;\n\n  args_before = std::vector<AVSValue>(num_args*3);\n  args_after = args_before.data() + num_args;\n  args_now = args_after + num_args;\n\n  if (context) {\n    args_after[0] = args_before[0] = context;\n    for (int i=1; i<num_args; ++i) {\n      args_before[i] = _args_before[i-1];\n      args_after[i] = _args_after[i-1];\n    }\n  }\n  else {\n    for (int i=0; i<num_args; ++i) {\n      args_before[i] = _args_before[i];\n      args_after[i] = _args_after[i];\n    }\n  }\n\n  memset(cache_stage, -1, sizeof(cache_stage));\n\n  // first clip with starting parameter values\n  cache[0] = env->Invoke(name, AVSValue(args_before.data(), num_args)).AsClip();\n  cache_stage[0] = 0;\n  VideoInfo vi1 = cache[0]->GetVideoInfo();\n\n  if (range_limit) {\n    VideoInfo vi = context->GetVideoInfo();\n\n    if (vi.width != vi1.width || vi.height != vi1.height)\n      env->ThrowError(\"ApplyRange: Filtered and unfiltered video frame sizes must match\");\n\n    if (!vi.IsSameColorspace(vi1))\n      env->ThrowError(\"ApplyRange: Filtered and unfiltered video colorspace must match\");\n  }\n  else {\n    // last clip with ending parameter values\n    cache[1] = env->Invoke(name, AVSValue(args_after, num_args)).AsClip();\n    cache_stage[1] = last-first;\n    VideoInfo vi2 = cache[1]->GetVideoInfo();\n\n    if (vi1.width != vi2.width || vi1.height != vi2.height)\n      env->ThrowError(\"Animate: initial and final video frame sizes must match\");\n  }\n}\n\n\nbool __stdcall Animate::GetParity(int n)\n{\n  if (range_limit) {\n    if ((n<first) || (n>last)) {\n      return args_after[0].AsClip()->GetParity(n);\n    }\n  }\n  // We could go crazy here and replicate the GetFrame\n  // logic and share the cache_stage but it is not\n  // really worth it. Although clips that change parity\n  // are supported they are very confusing.\n  return cache[0]->GetParity(n);\n}\n\n// 96.32 bit arithmetic helper stuff for Animate\n\n// 128-bit integer structure\nstruct my_int128_t {\n  int64_t H;  // High 64 bits (includes sign)\n  uint64_t L; // Low 64 bits (unsigned)\n};\n\n// Function to multiply two 64-bit values and produce a 128-bit result\nstatic inline my_int128_t mul_64_64_to_128(int64_t a, int64_t b) {\n  my_int128_t result;\n\n  // Handle sign separately\n  uint64_t sign = ((a < 0) ^ (b < 0)) ? 1 : 0;\n\n  // Use absolute values for multiplication\n  uint64_t abs_a = (a < 0) ? -a : a;\n  uint64_t abs_b = (b < 0) ? -b : b;\n\n  // Multiply using 32-bit parts to avoid overflow\n  uint64_t a_lo = abs_a & 0xFFFFFFFF;\n  uint64_t a_hi = abs_a >> 32;\n  uint64_t b_lo = abs_b & 0xFFFFFFFF;\n  uint64_t b_hi = abs_b >> 32;\n\n  // Multiply the components\n  uint64_t lo_lo = a_lo * b_lo;\n  uint64_t hi_lo = a_hi * b_lo;\n  uint64_t lo_hi = a_lo * b_hi;\n  uint64_t hi_hi = a_hi * b_hi;\n\n  // Combine the results\n  uint64_t mid = (lo_lo >> 32) + (hi_lo & 0xFFFFFFFF) + (lo_hi & 0xFFFFFFFF);\n  uint64_t carry = mid >> 32;\n\n  result.L = (lo_lo & 0xFFFFFFFF) | ((mid & 0xFFFFFFFF) << 32);\n  result.H = (hi_lo >> 32) + (lo_hi >> 32) + hi_hi + carry;\n\n  // Apply sign if needed\n  if (sign) {\n    // Two's complement negation\n    result.L = ~result.L + 1;\n    result.H = ~result.H + (result.L == 0);\n  }\n\n  return result;\n}\n\n// Function to add two 128-bit integers\nstatic inline my_int128_t add_128(my_int128_t a, my_int128_t b) {\n  my_int128_t result;\n\n  result.L = a.L + b.L;\n  // Check for carry\n  result.H = a.H + b.H + (result.L < a.L ? 1 : 0);\n\n  return result;\n}\n\n// Function to shift a 128-bit integer right by 'shift' bits\nstatic inline int64_t shift_right_128(my_int128_t a, int shift) {\n  if (shift >= 64) {\n    // If shifting by 64 or more, the result comes entirely from the high part\n    return a.H >> (shift - 64);\n  }\n  else {\n    // Combine portions from both high and low parts\n    return (a.H << (64 - shift)) | (a.L >> shift);\n  }\n}\n\n// Constants for 96.32 integer arithmetic\nconstexpr int ANIMATE_INT_ARITH_SCALEBITS = 32;\nconstexpr uint64_t ANIMATE_FULL_SCALE = 1ULL << ANIMATE_INT_ARITH_SCALEBITS; // 2^32\nconstexpr uint64_t ANIMATE_ROUND = ANIMATE_FULL_SCALE >> 1; // 2^31\n\n// Main interpolation function with uint64_t factor\n// factor = 2^32 means 1.0\nstatic int64_t Muldiv_64_32_integer_arithm(int64_t a, int64_t b, uint64_t factor) {\n\n  // Special case handling for factor = 0 or factor = 2^32 (0.0 or 1.0)\n  if (factor == 0)\n    return a;\n  else if (factor == ANIMATE_FULL_SCALE)\n    return b;\n\n  // Calculate the interpolation\n  // (a*(1-factor) + b*factor + round) / fullscale\n\n  my_int128_t temp_a, temp_b;\n  temp_a = mul_64_64_to_128(a, ANIMATE_FULL_SCALE - factor);\n  temp_b = mul_64_64_to_128(b, factor);\n  my_int128_t temp = add_128(temp_a, temp_b);\n\n  // Add rounding constant\n  temp.L += ANIMATE_ROUND;\n  // Check for carry\n  if (temp.L < ANIMATE_ROUND) {\n    temp.H++;\n  }\n\n  // Back to the real integer domain\n  return shift_right_128(temp, ANIMATE_INT_ARITH_SCALEBITS);\n}\n\nPVideoFrame __stdcall Animate::GetFrame(int n, IScriptEnvironment* env)\n{\n  if (range_limit) {\n    if ((n<first) || (n>last)) {\n      return args_after[0].AsClip()->GetFrame(n, env);\n    }\n    return cache[0]->GetFrame(n, env);\n  }\n  int stage = clamp(n, first, last) - first;\n  for (int i=0; i<cache_size; ++i)\n    if (cache_stage[i] == stage)\n      return cache[i]->GetFrame(n, env);\n\n  // filter not found in cache--create it\n  int furthest = 0;\n  for (int j=1; j<cache_size; ++j)\n    if (abs(stage-cache_stage[j]) > abs(stage-cache_stage[furthest]))\n      furthest = j;\n\n  int scale = last-first;\n  double stage_mod = (double)stage / scale; // linear 0.0 .. 1.0\n\n  if (custom_fn.IsFunction()) {\n    // custom function maps x -> fn(x), so that x=0.0 and x=1.0 still returns 0.0 and 1.0 (ideally)\n    PFunction func = custom_fn.AsFunction();\n    const char* argnames[1] = { \"stage\" };\n    AVSValue actual_args[1] = { stage_mod };\n    const AVSValue actual_args_array = AVSValue(actual_args, 1);\n    stage_mod = env->Invoke3(AVSValue(), func, actual_args_array, argnames).AsFloat();\n    // Used for integer interpolations as well.\n    // Since normalization is at 2^32 (where 1.0 equals 2^32), and int64_t is used,\n    // it can handle up to a 2^31 multiplier from fn(x).\n    // However, a return value range of 0.0 to 1.0 is ideal.\n  }\n\n  const uint64_t stage_int_arith = (int64_t)(double(ANIMATE_FULL_SCALE) * stage_mod);\n\n  for (int a = 0; a < num_args; ++a) {\n    if (args_before[a].IsInt() && args_after[a].IsInt()) {\n      // 96.32 bit arithmetic, intermediate 128 bits inside. \n      // Uses proper rounding when returning to real integer domain.\n      int64_t start = args_before[a].AsLong();\n      int64_t end = args_after[a].AsLong();\n      int64_t interpolated_value = Muldiv_64_32_integer_arithm(start, end, stage_int_arith);\n      int64_t lower_bound = std::min(start, end);\n      int64_t upper_bound = std::max(start, end);\n      // rounding error can occur, so that the intermediate result is not between the two values\n      if (interpolated_value < lower_bound) {\n        interpolated_value = lower_bound;\n      }\n      else if (interpolated_value > upper_bound) {\n        interpolated_value = upper_bound;\n      }\n      args_now[a] = interpolated_value;\n    }\n    else if (args_before[a].IsFloat() && args_after[a].IsFloat()) {\n      // note: AsFloat() returns double\n      double start = args_before[a].AsFloat();\n      double end = args_after[a].AsFloat();\n      double interpolated_value = start * (1 - stage_mod) + end * stage_mod;\n      double lower_bound = std::min(start, end);\n      double upper_bound = std::max(start, end);\n      // rounding error can occur, so that the intermediate result is not between the two values\n      if (interpolated_value < lower_bound) {\n        interpolated_value = lower_bound;\n      }\n      else if (interpolated_value > upper_bound) {\n        interpolated_value = upper_bound;\n      }\n      args_now[a] = interpolated_value;\n    }\n    else {\n      args_now[a] = args_before[a]; // bool, string, etc.. no transition\n    }\n  }\n#if 0\n  // old classic linear, 32 bit only kept for reference\n  int scale = last - first;\n\n  for (int a=0; a<num_args; ++a) {\n    if (args_before[a].IsInt() && args_after[a].IsInt()) {\n      // no rounding here\n      args_now[a] = int((Int32x32To64(args_before[a].AsInt(), scale-stage) + Int32x32To64(args_after[a].AsInt(), stage)) / scale);\n    }\n    else if (args_before[a].IsFloat() && args_after[a].IsFloat()) {\n      args_now[a] = (args_before[a].AsFloat()*(scale-stage) + args_after[a].AsFloat()*stage) / scale;\n    }\n    else {\n      args_now[a] = args_before[a];\n    }\n  }\n#endif\n  cache_stage[furthest] = stage;\n  cache[furthest] = env->Invoke(name, AVSValue(args_now, num_args)).AsClip();\n  return cache[furthest]->GetFrame(n, env);\n}\n\nvoid __stdcall Animate::GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env)  {\n  if (range_limit) {  // Applyrange - hard switch between streams.\n\n    const VideoInfo& vi1 = cache[0]->GetVideoInfo();\n    const int64_t start_switch =  vi1.AudioSamplesFromFrames(first);\n    const int64_t end_switch   =  vi1.AudioSamplesFromFrames(last+1);\n\n    if ( (start+count <= start_switch) || (start >= end_switch) ) {\n      // Everything unfiltered\n      args_after[0].AsClip()->GetAudio(buf, start, count, env);\n      return;\n    }\n    else if ( (start < start_switch) || (start+count > end_switch) ) {\n      // We are at one or both switchover points\n\n      // The bit before\n      if (start_switch > start) {\n    const int64_t pre_count = start_switch - start;\n        args_after[0].AsClip()->GetAudio(buf, start, pre_count, env);  // UnFiltered\n    start += pre_count;\n    count -= pre_count;\n    buf = (void*)( (BYTE*)buf + vi1.BytesFromAudioSamples(pre_count) );\n      }\n\n      // The bit in the middle\n      const int64_t filt_count = (end_switch < start+count) ? (end_switch - start) : count;\n      cache[0]->GetAudio(buf, start, filt_count, env);  // Filtered\n      start += filt_count;\n      count -= filt_count;\n      buf = (void*)( (BYTE*)buf + vi1.BytesFromAudioSamples(filt_count) );\n\n      // The bit after\n      if (count > 0)\n        args_after[0].AsClip()->GetAudio(buf, start, count, env);  // UnFiltered\n\n      return;\n    }\n    // Everything filtered\n  }\n  cache[0]->GetAudio(buf, start, count, env);  // Filtered\n}\n\n\nAVSValue __cdecl Animate::Create(AVSValue args, void* user_data, IScriptEnvironment* env)\n{\n  auto anim_kind = reinterpret_cast<intptr_t>(user_data);\n  // 0: legacy 1: extra callback function parameter\n\n  PClip context;\n  // When function parameter exists, it shifts the parameter array by one\n  const int param_index = (anim_kind == 0) ? 3 : 4;\n  // Convert the clip-at-zeroth-param version to the other signature.\n  if (args[0].IsClip()) {\n    // ciis.* -> iis.*\n    // ciisn.* -> iisn.*\n    context = args[0].AsClip();\n    args = AVSValue(&args[1], param_index + 1);\n  }\n  const int first = args[0].AsInt();\n  const int last = args[1].AsInt();\n  const char* const name = args[2].AsString();\n\n  int n = args[param_index].ArraySize();\n  if (n&1)\n    env->ThrowError(\"Animate: must have two argument lists of the same length\"); // two sets\n  return new Animate(context, first, last, name, &args[param_index][0], &args[param_index][n>>1], n>>1, false, \n    anim_kind == 0 ? AVSValue() : args[3], env);\n}\n\n\nAVSValue __cdecl Animate::Create_Range(AVSValue args, void*, IScriptEnvironment* env)\n{\n  PClip context = args[0].AsClip();\n\n  const int first = args[1].AsInt();\n  const int last = args[2].AsInt();\n  const char* const name = args[3].AsString();\n  int n = args[4].ArraySize();\n  return new Animate(context, first, last, name, &args[4][0], &args[4][0], n, true, AVSValue(), env);\n}\n"
  },
  {
    "path": "avs_core/filters/combine.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Combine_H__\n#define __Combine_H__\n\n#include <avisynth.h>\n#include <vector>\n\n/********************************************************************\n********************************************************************/\nclass MultiOverlay : public IClip\n  /**\n    * Class to Overlay multiple clips in one pass\n    **/\n{\nprivate:\n  std::vector<PClip> children;\n  std::vector<int> positions;\n  VideoInfo vi;\n\npublic:\n  MultiOverlay(const std::vector<PClip>& child_array, const std::vector<int>& position_array, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n\n  inline void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) {\n    children[0]->GetAudio(buf, start, count, env);\n  }\n\n  inline const VideoInfo& __stdcall GetVideoInfo() {\n    return vi;\n  }\n\n  inline bool __stdcall GetParity(int n) {\n    return children[0]->GetParity(n);\n  }\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n};\n\n\n\nclass StackVertical : public IClip\n  /**\n    * Class to stack clips vertically\n    **/\n{\nprivate:\n  std::vector<PClip> children;\n  VideoInfo vi;\n  int firstchildindex;\n\npublic:\n  StackVertical(const std::vector<PClip>& child_array, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n\n  inline void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) {\n    children[firstchildindex]->GetAudio(buf, start, count, env);\n  }\n\n  inline const VideoInfo& __stdcall GetVideoInfo() {\n    return vi;\n  }\n\n  inline bool __stdcall GetParity(int n) {\n    return children[firstchildindex]->GetParity(n);\n  }\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n};\n\n\n\nclass StackHorizontal : public IClip\n  /**\n    * Class to stack clips vertically\n    **/\n{\nprivate:\n  std::vector<PClip> children;\n  VideoInfo vi;\n\npublic:\n  StackHorizontal(const std::vector<PClip>& child_array, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n\n  inline void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) {\n    children[0]->GetAudio(buf, start, count, env);\n  }\n\n  inline const VideoInfo& __stdcall GetVideoInfo() {\n    return vi;\n  }\n\n  inline bool __stdcall GetParity(int n) {\n    return children[0]->GetParity(n);\n  }\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n};\n\n\n\n\nclass ShowFiveVersions : public IClip\n/**\n  * Class to show every pulldown combination\n **/\n{\npublic:\n  ShowFiveVersions(PClip* children, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n\n  inline void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env)\n    { child[0]->GetAudio(buf, start, count, env); }\n  inline const VideoInfo& __stdcall GetVideoInfo()\n    { return vi; }\n  inline bool __stdcall GetParity(int n)\n    { return child[0]->GetParity(n); }\n  int __stdcall SetCacheHints(int cachehints,int frame_range) {\n    AVS_UNUSED(cachehints);\n    AVS_UNUSED(frame_range);\n    return 0;\n  };\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\nprivate:\n  PClip child[5];\n  VideoInfo vi;\n};\n\n\n\nclass Animate : public IClip\n/**\n  * Class to allow recursive animation of multiple clips (see docs)  *\n **/\n{\n  enum { cache_size = 3 };\n  PClip cache[cache_size];\n  int cache_stage[cache_size];\n  const int first, last;\n  std::vector<AVSValue> args_before;\n  AVSValue *args_after, *args_now;\n  int num_args;\n  const char* name;\n  bool range_limit;\n  AVSValue custom_fn;\npublic:\n  Animate( PClip context, int _first, int _last, const char* _name, const AVSValue* _args_before,\n           const AVSValue* _args_after, int _num_args, bool _range_limit, const AVSValue& _custom_fn, IScriptEnvironment* env );\n  virtual ~Animate() { }\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env);\n\n  inline const VideoInfo& __stdcall GetVideoInfo()\n    { return cache[0]->GetVideoInfo(); }\n  bool __stdcall GetParity(int n);\n\n  int __stdcall SetCacheHints(int cachehints,int frame_range) {\n    AVS_UNUSED(frame_range);\n    switch (cachehints)\n    {\n    case CACHE_GET_MTMODE:\n      return MT_MULTI_INSTANCE;\n    }\n    return 0;  // We do not pass cache requests upwards.\n  };\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n  static AVSValue __cdecl Create_Range(AVSValue args, void*, IScriptEnvironment* env);\n};\n\n\n#endif  // __Combine_H__\n"
  },
  {
    "path": "avs_core/filters/conditional/conditional.cpp",
    "content": "\n// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include \"conditional.h\"\n#include \"../../core/parser/scriptparser.h\"\n#include \"conditional_reader.h\"\n#include <cmath>\n\n#ifdef AVS_WINDOWS\n    #include <avs/win.h>\n#else\n    #include <avs/posix.h>\n#endif\n\n#include <avs/minmax.h>\n#include \"../../core/internal.h\"\n#include \"../../core/InternalEnvironment.h\"\n\nextern const AVSFunction Conditional_filters[] = {\n  // 2020.03.28 bool \"local\" parameter like in gRunT. Default false. Note! AvsNeo works as local=true, but it's incompatible with old Avisynth\n  // with \"function\" input local default is true\n  {  \"ConditionalSelect\", BUILTIN_FUNC_PREFIX, \"csc+[show]b[local]b\", ConditionalSelect::Create },\n  {  \"ConditionalSelect\", BUILTIN_FUNC_PREFIX, \"cnc+[show]b[local]b\", ConditionalSelect::Create }, // function input\n  {  \"ConditionalFilter\", BUILTIN_FUNC_PREFIX, \"cccsss[show]b[local]b\", ConditionalFilter::Create, (void *)0 },\n  // easy syntax from GConditionalFilter, args3 and 4 to \"=\" and \"true\":\n  {  \"ConditionalFilter\", BUILTIN_FUNC_PREFIX, \"cccs[show]b[local]b\", ConditionalFilter::Create, (void *)1 },\n  {  \"ConditionalFilter\", BUILTIN_FUNC_PREFIX, \"cccn[show]b[local]b\", ConditionalFilter::Create, (void *)2 }, // function input\n  {  \"ScriptClip\",        BUILTIN_FUNC_PREFIX, \"cs[show]b[after_frame]b[local]b\", ScriptClip::Create },\n  {  \"ScriptClip\",        BUILTIN_FUNC_PREFIX, \"cn[show]b[after_frame]b[local]b\", ScriptClip::Create }, // function input\n  {  \"ConditionalReader\", BUILTIN_FUNC_PREFIX, \"css[show]b[condvarsuffix]s[local]b\", ConditionalReader::Create },\n  {  \"FrameEvaluate\",     BUILTIN_FUNC_PREFIX, \"cs[show]b[after_frame]b[local]b\", ScriptClip::Create_eval },\n  {  \"WriteFile\",         BUILTIN_FUNC_PREFIX, \"c[filename]ss+[append]b[flush]b[local]b\", Write::Create },\n  {  \"WriteFileIf\",       BUILTIN_FUNC_PREFIX, \"c[filename]ss+[append]b[flush]b[local]b\", Write::Create_If },\n  {  \"WriteFileStart\",    BUILTIN_FUNC_PREFIX, \"c[filename]ss+[append]b[local]b\", Write::Create_Start },\n  {  \"WriteFileEnd\",      BUILTIN_FUNC_PREFIX, \"c[filename]ss+[append]b[local]b\", Write::Create_End },\n  {  \"WriteFile\",         BUILTIN_FUNC_PREFIX, \"c[filename]sn+[append]b[flush]b[local]b\", Write::Create }, // function input\n  {  \"WriteFileIf\",       BUILTIN_FUNC_PREFIX, \"c[filename]sn+[append]b[flush]b[local]b\", Write::Create_If }, // function input\n  {  \"WriteFileStart\",    BUILTIN_FUNC_PREFIX, \"c[filename]sn+[append]b[local]b\", Write::Create_Start }, // function input\n  {  \"WriteFileEnd\",      BUILTIN_FUNC_PREFIX, \"c[filename]sn+[append]b[local]b\", Write::Create_End }, // function input\n  { \"UseVar\", BUILTIN_FUNC_PREFIX, \"cs+\", UseVar::Create },\n  // in conditional_reader.cpp, see property getters in conditional_functions.cpp\n\n  // value from Function\n  { \"propSet\", BUILTIN_FUNC_PREFIX, \"csn[mode]i\", SetProperty::Create, (void *)0 }, // auto from function result type\n  { \"propSetInt\", BUILTIN_FUNC_PREFIX, \"csn[mode]i\", SetProperty::Create, (void*)1 }, // forced check for int\n  { \"propSetFloat\", BUILTIN_FUNC_PREFIX, \"csn[mode]i\", SetProperty::Create, (void*)2 }, // forced check for float\n  { \"propSetString\", BUILTIN_FUNC_PREFIX, \"csn[mode]i\", SetProperty::Create, (void*)3 }, // forced check for string\n  { \"propSetArray\", BUILTIN_FUNC_PREFIX, \"csn\", SetProperty::Create, (void*)4 }, // no mode parameter, full entry refresh\n  { \"propSetClip\", BUILTIN_FUNC_PREFIX, \"csn[mode]i\", SetProperty::Create, (void*)5 }, // forced check for clip\n\n  // value from direct data\n  { \"propSet\", BUILTIN_FUNC_PREFIX, \"csi[mode]i\", SetProperty::Create, (void*)10 },\n  { \"propSet\", BUILTIN_FUNC_PREFIX, \"csf[mode]i\", SetProperty::Create, (void*)11 },\n  { \"propSet\", BUILTIN_FUNC_PREFIX, \"css[mode]i\", SetProperty::Create, (void*)12 },\n  { \"propSet\", BUILTIN_FUNC_PREFIX, \"csa\", SetProperty::Create, (void*)13 }, // no mode parameter, full entry refresh\n  { \"propSet\", BUILTIN_FUNC_PREFIX, \"csc[mode]i\", SetProperty::Create, (void*)14 },\n\n  { \"propDelete\", BUILTIN_FUNC_PREFIX, \"cs+\", DeleteProperty::Create },\n  { \"propClearAll\", BUILTIN_FUNC_PREFIX, \"c\", ClearProperties::Create },\n\n  { \"propShow\", BUILTIN_FUNC_PREFIX, \"c[size]i[showtype]b[font]s[text_color]i[halo_color]i[bold]b[x]f[y]f[align]i[props]s+\", ShowProperties::Create },\n\n  { \"propCopy\", BUILTIN_FUNC_PREFIX, \"cc[merge]b[props]s+[exclude]b\", CopyProperties::Create},\n\n  { 0 }\n};\n\n#define W_DIVISOR 5  // Width divisor for onscreen messages\n\n\n/********************************\n * Conditional Select\n *\n * Returns each one frame from N sources\n * based on an integer evaluator.\n ********************************/\n\nConditionalSelect::ConditionalSelect(PClip _child, AVSValue _script,\n                                     int _num_args, PClip *_child_array,\n                                     bool _show, bool _local, IScriptEnvironment* env) :\n  GenericVideoFilter(_child), script(_script),\n  num_args(_num_args), child_array(_child_array), show(_show), local(_local) {\n\n  child_devs = DEV_TYPE_ANY;\n  for (int i=0; i<num_args; i++) {\n    const VideoInfo& vin = child_array[i]->GetVideoInfo();\n\n    if (vi.height != vin.height)\n      env->ThrowError(\"ConditionalSelect: The sources must all have the same height!\");\n\n    if (vi.width != vin.width)\n      env->ThrowError(\"ConditionalSelect: The sources must all have the same width!\");\n\n    if (!vi.IsSameColorspace(vin))\n      env->ThrowError(\"ConditionalSelect: The sources must all be the same colorspace!\");\n\n    if (vi.num_frames < vin.num_frames) // Max of all clips\n      vi.num_frames = vin.num_frames;\n\n    child_devs &= GetDeviceTypes(child_array[i]);\n  }\n\n  if (child_devs == 0) {\n    env->ThrowError(\"ConditionalSelect: No common device among sources!\");\n  }\n}\n\n\nConditionalSelect::~ConditionalSelect() {\n  delete[] child_array;\n}\n\nint __stdcall ConditionalSelect::SetCacheHints(int cachehints, int frame_range)\n{\n  AVS_UNUSED(frame_range);\n  switch (cachehints)\n  {\n  case CACHE_GET_MTMODE:\n    return MT_NICE_FILTER;\n  case CACHE_GET_DEV_TYPE:\n    return child_devs;\n  case CACHE_GET_CHILD_DEV_TYPE:\n    return DEV_TYPE_ANY;\n  }\n  return 0;  // We do not pass cache requests upwards.\n}\n\nPVideoFrame __stdcall ConditionalSelect::GetFrame(int n, IScriptEnvironment* env_)\n{\n  InternalEnvironment* IEnv = GetAndRevealCamouflagedEnv(env_);\n  IScriptEnvironment* env = static_cast<IScriptEnvironment*>(IEnv);\n\n  AVSValue prev_last;\n  AVSValue prev_current_frame;\n  std::unique_ptr<GlobalVarFrame> var_frame;\n\n  AVSValue child_val = child;\n\n  if (!local) {\n    prev_last = env->GetVarDef(\"last\");  // Store previous last\n    prev_current_frame = env->GetVarDef(\"current_frame\");  // Store previous current_frame\n    env->SetVar(\"last\", child_val);       // Set implicit last\n    env->SetVar(\"current_frame\", (AVSValue)n);  // Set frame to be tested by the conditional filters.\n  }\n  else {\n    // Neo's default, correct but incompatible with previous Avisynth versions\n    var_frame = std::unique_ptr<GlobalVarFrame>(new GlobalVarFrame(IEnv)); // allocate new frame\n    env->SetGlobalVar(\"last\", child_val);       // Set explicit last\n    env->SetGlobalVar(\"current_frame\", (AVSValue)n);  // Set frame to be tested by the conditional filters.\n  }\n\n  AVSValue result;\n\n  try {\n    if (script.IsString()) {\n      ScriptParser parser(env, script.AsString(), \"[Conditional Select, Expression]\");\n      PExpression exp = parser.Parse();\n      result = exp->Evaluate(env);\n    }\n    else {\n      //auto& func = script.AsFunction(); // c++ strict conformance: cannot Convert PFunction to PFunction&\n      const PFunction& func = script.AsFunction();\n      const AVSValue empty_args_array = AVSValue(nullptr, 0); // Invoke_ parameter is const AVSValue&, don't do it inline.\n      if (!IEnv->Invoke_(&result, child_val,\n        func->GetLegacyName(), func->GetDefinition(), empty_args_array, 0))\n      {\n        env->ThrowError(\n          \"ConditionalSelect: Invalid function parameter type '%s'(%s)\\n\"\n          \"Function should have one clip argument or no argument\",\n          func->GetDefinition()->param_types, func->ToString(env));\n      }\n    }\n\n    if (!result.IsInt())\n      env->ThrowError(\"Conditional Select: Expression must return an integer!\");\n  }\n  catch (const AvisynthError &error) {\n    if (!local) {\n      env->SetVar(\"last\", prev_last);       // Restore implicit last\n      env->SetVar(\"current_frame\", prev_current_frame);       // Restore current_frame\n    }\n\n    const int num_frames = child->GetVideoInfo().num_frames;\n    PVideoFrame dst = child->GetFrame(min(num_frames-1, n), env);\n\n    env->MakeWritable(&dst);\n    env->ApplyMessageEx(&dst, vi, error.msg, vi.width/W_DIVISOR, 0xa0a0a0, 0, 0, true);\n\n    return dst;\n  }\n\n  if (!local) {\n    env->SetVar(\"last\", prev_last);       // Restore implicit last\n    env->SetVar(\"current_frame\", prev_current_frame);       // Restore current_frame\n  }\n\n  const int i = result.AsInt();\n\n  PVideoFrame dst;\n\n  if (i < 0 || i >= num_args) {\n    const int num_frames = child->GetVideoInfo().num_frames;\n    dst = child->GetFrame(min(num_frames-1, n), env);\n  }\n  else {\n    const int num_frames = child_array[i]->GetVideoInfo().num_frames;\n    dst = child_array[i]->GetFrame(min(num_frames-1, n), env);\n  }\n\n  if (show) {\n    char text[32];\n\n    snprintf(text, sizeof(text)-1, \"Expression Result:%i\\n\", result.AsInt());\n    text[sizeof(text)-1] = '\\0';\n\n    env->MakeWritable(&dst);\n    env->ApplyMessage(&dst, vi, text, vi.width/4, 0xa0a0a0, 0, 0);\n  }\n\n  return dst;\n}\n\n\nAVSValue __cdecl ConditionalSelect::Create(AVSValue args, void* , IScriptEnvironment* env)\n{\n  int num_args = 0;\n  PClip* child_array = 0;\n\n  if(!args[1].IsFunction() && (!args[1].IsString() || !args[1].AsString(nullptr)))\n    env->ThrowError(\"Conditional Select: expression missing!\");\n\n  if (args[2].IsArray()) {\n    num_args = args[2].ArraySize();\n    child_array = new PClip[num_args];\n\n    for (int i = 0; i < num_args; ++i) // Copy clips\n      child_array[i] = args[2][i].AsClip();\n  }\n  else if (args[2].IsClip()) { // Make easy to call with trivial 1 clip\n    num_args = 1;\n    child_array = new PClip[1];\n\n    child_array[0] = args[2].AsClip();\n  }\n  else {\n    env->ThrowError(\"Conditional Select: clip array not recognized!\");\n  }\n\n  const bool runtime_local_default = args[1].IsFunction() ?  true : false; // Avisynth compatibility: false, Neo: true. functions are legacy Neo\n\n  return new ConditionalSelect(args[0].AsClip(), args[1], num_args, child_array, args[3].AsBool(false), args[4].AsBool(runtime_local_default), env);\n}\n\n\n/********************************\n * Conditional filter\n *\n * Returns each one frame from two sources,\n * based on an evaluator.\n ********************************/\n\nConditionalFilter::ConditionalFilter(PClip _child, PClip _source1, PClip _source2,\n                                     AVSValue  _condition1, AVSValue  _evaluator, AVSValue  _condition2,\n                                     bool _show, bool _local, IScriptEnvironment* env) :\n  GenericVideoFilter(_child), source1(_source1), source2(_source2),\n  eval1(_condition1), eval2(_condition2), show(_show), local(_local) {\n\n    evaluator = NONE;\n\n    if (lstrcmpi(_evaluator.AsString(), \"equals\") == 0 ||\n        lstrcmpi(_evaluator.AsString(), \"=\") == 0 ||\n        lstrcmpi(_evaluator.AsString(), \"==\") == 0)\n      evaluator = EQUALS;\n    if (lstrcmpi(_evaluator.AsString(), \"greaterthan\") == 0 || lstrcmpi(_evaluator.AsString(), \">\") == 0)\n      evaluator = GREATERTHAN;\n    if (lstrcmpi(_evaluator.AsString(), \"lessthan\") == 0 || lstrcmpi(_evaluator.AsString(), \"<\") == 0)\n      evaluator = LESSTHAN;\n\n    if (evaluator == NONE)\n      env->ThrowError(\"ConditionalFilter: Evaluator could not be recognized!\");\n\n    VideoInfo vi1 = source1->GetVideoInfo();\n    VideoInfo vi2 = source2->GetVideoInfo();\n\n    if (vi1.height != vi2.height)\n      env->ThrowError(\"ConditionalFilter: The two sources must have the same height!\");\n    if (vi1.width != vi2.width)\n      env->ThrowError(\"ConditionalFilter: The two sources must have the same width!\");\n    if (!vi1.IsSameColorspace(vi2))\n      env->ThrowError(\"ConditionalFilter: The two sources must be the same colorspace!\");\n\n    vi.height = vi1.height;\n    vi.width = vi1.width;\n    vi.pixel_type = vi1.pixel_type;\n    vi.num_frames = max(vi1.num_frames,vi2.num_frames);\n    vi.num_audio_samples = vi1.num_audio_samples;\n    vi.audio_samples_per_second = vi1.audio_samples_per_second;\n    vi.image_type = vi1.image_type;\n    vi.fps_denominator = vi1.fps_denominator;\n    vi.fps_numerator = vi1.fps_numerator;\n    vi.nchannels = vi1.nchannels;\n    vi.sample_type = vi1.sample_type;\n\n    child_devs = (GetDeviceTypes(source1) & GetDeviceTypes(source2));\n\n    if (child_devs == 0) {\n      env->ThrowError(\"ConditionalFilter: The two sources must support the same device!\");\n    }\n  }\n\nconst char* const t_TRUE=\"TRUE\";\nconst char* const t_FALSE=\"FALSE\";\n\nint __stdcall ConditionalFilter::SetCacheHints(int cachehints, int frame_range)\n{\n  AVS_UNUSED(frame_range);\n  switch (cachehints)\n  {\n  case CACHE_GET_MTMODE:\n    return MT_NICE_FILTER;\n  case CACHE_GET_DEV_TYPE:\n    return child_devs;\n  case CACHE_GET_CHILD_DEV_TYPE:\n    return DEV_TYPE_ANY;\n  }\n  return 0;  // We do not pass cache requests upwards.\n}\n\nPVideoFrame __stdcall ConditionalFilter::GetFrame(int n, IScriptEnvironment* env_)\n{\n  InternalEnvironment* IEnv = GetAndRevealCamouflagedEnv(env_);\n  IScriptEnvironment* env = static_cast<IScriptEnvironment*>(IEnv);\n\n  AVSValue prev_last;\n  AVSValue prev_current_frame;\n  std::unique_ptr<GlobalVarFrame> var_frame;\n\n  AVSValue child_val = child;\n\n  if (!local) {\n    prev_last = env->GetVarDef(\"last\");  // Store previous last\n    prev_current_frame = env->GetVarDef(\"current_frame\");  // Store previous current_frame\n    env->SetVar(\"last\", (AVSValue)child_val);       // Set implicit last\n    env->SetVar(\"current_frame\", (AVSValue)n);  // Set frame to be tested by the conditional filters.\n  }\n  else {\n    // Neo's default, correct but incompatible with previous Avisynth versions\n    var_frame = std::unique_ptr<GlobalVarFrame>(new GlobalVarFrame(IEnv)); // allocate new frame\n    env->SetGlobalVar(\"last\", child_val);       // Set explicit last\n    env->SetGlobalVar(\"current_frame\", (AVSValue)n);  // Set frame to be tested by the conditional filters.\n  }\n\n  VideoInfo vi1 = source1->GetVideoInfo();\n  VideoInfo vi2 = source2->GetVideoInfo();\n\n  AVSValue e1_result;\n  AVSValue e2_result;\n  try {\n    if (eval1.IsString()) {\n      ScriptParser parser(env, eval1.AsString(), \"[Conditional Filter, Expresion 1]\");\n      PExpression exp = parser.Parse();\n      e1_result = exp->Evaluate(env);\n\n      ScriptParser parser2(env, eval2.AsString(), \"[Conditional Filter, Expression 2]\");\n      exp = parser2.Parse();\n      e2_result = exp->Evaluate(env);\n    }\n    else {\n      //auto& func = eval1.AsFunction(); // c++ strict conformance: cannot Convert PFunction to PFunction&\n      const PFunction& func = eval1.AsFunction();\n      const AVSValue empty_args_array = AVSValue(nullptr, 0); // Invoke_ parameter is const AVSValue&, don't do it inline.\n      if (!IEnv->Invoke_(&e1_result, child_val,\n        func->GetLegacyName(), func->GetDefinition(), empty_args_array, 0))\n      {\n        env->ThrowError(\n          \"ConditionalFilter: Invalid function parameter type '%s'(%s)\\n\"\n          \"Function should have one clip argument or no argument\",\n          func->GetDefinition()->param_types, func->ToString(env));\n      }\n      e2_result = true;\n    }\n  } catch (const AvisynthError &error) {\n    const char* error_msg = error.msg;\n\n    PVideoFrame dst = source1->GetFrame(n,env);\n    env->MakeWritable(&dst);\n    env->ApplyMessageEx(&dst, vi1, error_msg, vi.width/W_DIVISOR, 0xa0a0a0, 0, 0, true);\n\n    if (!local) {\n      env->SetVar(\"last\", prev_last);       // Restore implicit last\n      env->SetVar(\"current_frame\", prev_current_frame);       // Restore current_frame\n    }\n\n    return dst;\n  }\n\n  if (!local) {\n    env->SetVar(\"last\", prev_last);       // Restore implicit last\n    env->SetVar(\"current_frame\", prev_current_frame);       // Restore current_frame\n  }\n\n  bool test_int=false;\n  bool test_string=false;\n\n  int e1 = 0;\n  int e2 = 0;\n  double f1 = 0.0;\n  double f2 = 0.0;\n  try {\n    if (e1_result.IsString()) {\n      if (!e2_result.IsString())\n        env->ThrowError(\"Conditional filter: Second expression did not return a string, as in first string expression.\");\n      test_string = true;\n      test_int = true;\n      e1 = lstrcmp(e1_result.AsString(), e2_result.AsString());\n      e2 = 0;\n\n    } else if (e1_result.IsBool()) {\n      if (!(e2_result.IsInt() || e2_result.IsBool()))\n        env->ThrowError(\"Conditional filter: Second expression did not return an integer or bool, as in first bool expression.\");\n      test_int = true;\n      e1 = e1_result.AsBool();\n      e2 = e2_result.IsInt() ? e2_result.AsInt() : e2_result.AsBool();\n\n    } else if (e1_result.IsInt()) {\n      if (e2_result.IsInt() || e2_result.IsBool()) {\n        test_int = true;\n        e1 = e1_result.AsInt();\n        e2 = e2_result.IsInt() ? e2_result.AsInt() : e2_result.AsBool();\n      } else if (e2_result.IsFloat()) {\n        f1 = (float)e1_result.AsFloat();\n        f2 = (float)e2_result.AsFloat();\n      } else\n        env->ThrowError(\"Conditional filter: Second expression did not return a float, integer or bool, as in first integer expression.\");\n\n    } else if (e1_result.IsFloat()) {\n      f1 = (float)e1_result.AsFloat();\n      if (!e2_result.IsFloat())\n        env->ThrowError(\"Conditional filter: Second expression did not return a float or an integer, as in first float expression.\");\n      f2 = (float)e2_result.AsFloat();\n    } else {\n      env->ThrowError(\"ConditionalFilter: First expression did not return an integer, bool or float!\");\n    }\n  } catch (const AvisynthError &error) {\n    const char* error_msg = error.msg;\n\n    PVideoFrame dst = source1->GetFrame(n,env);\n    env->MakeWritable(&dst);\n    env->ApplyMessageEx(&dst, vi1, error_msg, vi.width/W_DIVISOR, 0xa0a0a0, 0, 0, true);\n    return dst;\n  }\n\n\n  bool state = false;\n\n  if (test_int) { // String and Int compare\n    if (evaluator == EQUALS)\n      if (e1 == e2) state = true;\n\n    if (evaluator == GREATERTHAN)\n      if (e1 > e2) state = true;\n\n    if (evaluator == LESSTHAN)\n      if (e1 < e2) state = true;\n\n  } else {  // Float compare\n    if (evaluator == EQUALS)\n      if (fabs(f1-f2)<0.000001) state = true;   // Exact equal will sometimes be rounded to wrong values.\n\n    if (evaluator == GREATERTHAN)\n      if (f1 > f2) state = true;\n\n    if (evaluator == LESSTHAN)\n      if (f1 < f2) state = true;\n  }\n\n  if (show) {\n      char text[400];\n      if (test_string) {\n        snprintf(text, sizeof(text)-1,\n          \"Left side Conditional Result:%.40s\\n\"\n          \"Right side Conditional Result:%.40s\\n\"\n          \"Evaluate result: %s\\n\",\n          e1_result.AsString(), e2_result.AsString(), (state) ? t_TRUE : t_FALSE\n        );\n      } else if (test_int) {\n        snprintf(text, sizeof(text)-1,\n          \"Left side Conditional Result:%i\\n\"\n          \"Right side Conditional Result:%i\\n\"\n          \"Evaluate result: %s\\n\",\n          e1, e2, (state) ? t_TRUE : t_FALSE\n        );\n      } else {\n        snprintf(text, sizeof(text)-1,\n          \"Left side Conditional Result:%7.4f\\n\"\n          \"Right side Conditional Result:%7.4f\\n\"\n          \"Evaluate result: %s\\n\",\n          f1, f2, (state) ? t_TRUE : t_FALSE\n        );\n      }\n\n      PVideoFrame dst = (state) ? source1->GetFrame(min(vi1.num_frames-1,n),env) : source2->GetFrame(min(vi2.num_frames-1,n),env);\n      env->MakeWritable(&dst);\n      env->ApplyMessage(&dst, vi, text, vi.width/4, 0xa0a0a0, 0, 0);\n    return dst;\n  }\n\n  if (state)\n    return source1->GetFrame(min(vi1.num_frames-1,n),env);\n\n  return source2->GetFrame(min(vi1.num_frames-1,n),env);\n}\n\nvoid __stdcall ConditionalFilter::GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) {\n  source1->GetAudio(buf, start, count, env);\n}\n\n\nAVSValue __cdecl ConditionalFilter::Create(AVSValue args, void* user_data, IScriptEnvironment* env)\n{\n  intptr_t userdata = (intptr_t)user_data;\n\n  const bool runtime_local_default = args[3].IsFunction() ? true : false; // Avisynth compatibility: false, Neo: true. functions are legacy Neo\n\n  if (userdata == 0)\n    return new ConditionalFilter(args[0].AsClip(), args[1].AsClip(), args[2].AsClip(), args[3], args[4], args[5], args[6].AsBool(false), args[7].AsBool(runtime_local_default), env);\n  else // like GConditional filter shortcut: no \"=\" \"true\" needed\n    return new ConditionalFilter(args[0].AsClip(), args[1].AsClip(), args[2].AsClip(), args[3], \"=\", \"true\", args[4].AsBool(false), args[5].AsBool(runtime_local_default), env);\n}\n\n\n/**************************\n * ScriptClip.\n *\n * Returns the value of a script evaluated at each frame.\n *\n * Implicit last, and current frame is set on each frame.\n **************************/\n\nScriptClip::ScriptClip(PClip _child, AVSValue  _script, bool _show, bool _only_eval, bool _eval_after_frame, bool _local, IScriptEnvironment* env) :\n  GenericVideoFilter(_child), script(_script), show(_show), only_eval(_only_eval), eval_after(_eval_after_frame), local(_local) {\n  AVS_UNUSED(env);\n}\n\n\nint __stdcall ScriptClip::SetCacheHints(int cachehints, int frame_range)\n{\n  switch (cachehints)\n  {\n  case CACHE_GET_MTMODE:\n    return MT_NICE_FILTER;\n  case CACHE_GET_DEV_TYPE:\n    return (child->GetVersion() >= 5) ? child->SetCacheHints(CACHE_GET_DEV_TYPE, 0) : 0;\n  }\n  return 0;  // We do not pass cache requests upwards.\n}\n\nPVideoFrame __stdcall ScriptClip::GetFrame(int n, IScriptEnvironment* env_)\n{\n\n  InternalEnvironment* IEnv = GetAndRevealCamouflagedEnv(env_);\n  IScriptEnvironment* env = static_cast<IScriptEnvironment*>(IEnv);\n\n  AVSValue prev_last;\n  AVSValue prev_current_frame;\n  std::unique_ptr<GlobalVarFrame> var_frame;\n\n  AVSValue child_val = child;\n\n  if (!local) {\n    prev_last = env->GetVarDef(\"last\");  // Store previous last\n    prev_current_frame = env->GetVarDef(\"current_frame\");  // Store previous current_frame\n    env->SetVar(\"last\", (AVSValue)child_val);       // Set implicit last\n    env->SetVar(\"current_frame\", (AVSValue)n);  // Set frame to be tested by the conditional filters.\n  }\n  else {\n    // Neo's default, correct but incompatible with previous Avisynth versions\n    var_frame = std::unique_ptr<GlobalVarFrame>(new GlobalVarFrame(IEnv)); // allocate new frame\n    env->SetGlobalVar(\"last\", child_val);       // Set explicit last\n    env->SetGlobalVar(\"current_frame\", (AVSValue)n);  // Set frame to be tested by the conditional filters.\n  }\n\n  if (show) {\n    PVideoFrame dst = child->GetFrame(n,env);\n    const char* text = script.IsString() ? script.AsString() : script.AsFunction()->ToString(env);\n    env->MakeWritable(&dst);\n    env->ApplyMessage(&dst, vi, text, vi.width/6, 0xa0a0a0, 0, 0);\n    if (!local) {\n      env->SetVar(\"last\", prev_last);       // Restore implicit last\n      env->SetVar(\"current_frame\", prev_current_frame);       // Restore current_frame\n    }\n    return dst;\n  }\n\n  AVSValue result;\n  PVideoFrame eval_return;   // Frame to be returned if script should be evaluated AFTER frame has been fetched. Otherwise not used.\n\n  if (eval_after) eval_return = child->GetFrame(n,env);\n\n  try {\n    if (script.IsString()) {\n      ScriptParser parser(env, script.AsString(), \"[ScriptClip]\");\n      PExpression exp = parser.Parse();\n      result = exp->Evaluate(env);\n    }\n    else {\n      const PFunction& func = script.AsFunction();\n      const AVSValue empty_args_array = AVSValue(nullptr, 0); // Invoke_ parameter is const AVSValue&, don't do it inline.\n      const Function* fd = func->GetDefinition();\n      if (!IEnv->Invoke_(&result, child_val,\n        func->GetLegacyName(),fd , empty_args_array, 0))\n      {\n        /* fd is nullptr:\n           ps = function propSetterFunc(Clip c) { propSetInt(\"frameluma_sc_func\",func(AverageLuma)) }\n           ScriptClip(func(ps))\n        */\n        if (fd == nullptr)\n          env->ThrowError(\n            \"ScriptClip: Invalid function parameter type '%s'(%s)\\n\"\n            \"Function should have one clip argument or no argument\",\n            \"<no definition>\", func->ToString(env));\n        else\n          env->ThrowError(\n            \"ScriptClip: Invalid function parameter type '%s'(%s)\\n\"\n            \"Function should have one clip argument or no argument\",\n            func->GetDefinition()->param_types, func->ToString(env));\n      }\n    }\n  } catch (const AvisynthError &error) {\n    const char* error_msg = error.msg;\n\n    PVideoFrame dst = child->GetFrame(n,env);\n    env->MakeWritable(&dst);\n    env->ApplyMessageEx(&dst, vi, error_msg, vi.width/W_DIVISOR, 0xa0a0a0, 0, 0, true);\n    if (!local) {\n      env->SetVar(\"last\", prev_last);       // Restore implicit last\n      env->SetVar(\"current_frame\", prev_current_frame);       // Restore current_frame\n    }\n    return dst;\n  }\n\n  if (!local) {\n    env->SetVar(\"last\", prev_last);       // Restore implicit last\n    env->SetVar(\"current_frame\", prev_current_frame);       // Restore current_frame\n  }\n\n  if (eval_after && only_eval) return eval_return;\n  if (only_eval) return child->GetFrame(n,env);\n\n  const char* error = NULL;\n  VideoInfo vi2 = vi;\n  if (!result.IsClip()) {\n    if (result.IsBool())\n      error = \"ScriptClip: Function did not return a video clip! (Was a bool)\";\n    else if (result.IsInt())\n      error = \"ScriptClip: Function did not return a video clip! (Was an int)\";\n    else if (result.IsFloat())\n      error = \"ScriptClip: Function did not return a video clip! (Was a float)\";\n    else if (result.IsString())\n      error = \"ScriptClip: Function did not return a video clip! (Was a string)\";\n    else if (result.IsArray())\n      error = \"ScriptClip: Function did not return a video clip! (Was an array)\";\n    else if (!result.Defined())\n      error = \"ScriptClip: Function did not return a video clip! (Was the undefined value)\";\n    else\n      error = \"ScriptClip: Function did not return a video clip! (type is unknown)\";\n  } else {\n    vi2 = result.AsClip()->GetVideoInfo();\n    if (!vi.IsSameColorspace(vi2)) {\n      error = \"ScriptClip: Function did not return a video clip of the same colorspace as the source clip!\";\n    } else if (vi2.width != vi.width) {\n      error = \"ScriptClip: Function did not return a video clip with the same width as the source clip!\";\n    } else if (vi2.height != vi.height) {\n      error = \"ScriptClip: Function did not return a video clip with the same height as the source clip!\";\n    }\n  }\n\n  if (error != NULL) {\n    PVideoFrame dst = child->GetFrame(n,env);\n    env->MakeWritable(&dst);\n    env->ApplyMessage(&dst, vi, error, vi.width/W_DIVISOR, 0xa0a0a0, 0, 0);\n    return dst;\n  }\n\n  n = min(n,vi2.num_frames-1);  // We ignore it if the new clip is not as long as the current one. This can allow the resulting clip to be one frame.\n\n  return result.AsClip()->GetFrame(n,env);\n}\n\n\nAVSValue __cdecl ScriptClip::Create(AVSValue args, void* , IScriptEnvironment* env)\n{\n  const bool runtime_local_default = args[1].IsFunction() ? true : false; // Avisynth compatibility: false, Neo: true. functions are legacy Neo\n\n  return new ScriptClip(args[0].AsClip(), args[1], args[2].AsBool(false),false, args[3].AsBool(false), args[4].AsBool(runtime_local_default), env);\n}\n\n\nAVSValue __cdecl ScriptClip::Create_eval(AVSValue args, void* , IScriptEnvironment* env)\n{\n  const bool runtime_local_default = args[1].IsFunction() ? true : false; // Avisynth compatibility: false, Neo: true. functions are legacy Neo\n\n  return new ScriptClip(args[0].AsClip(), args[1], args[2].AsBool(false),true, args[3].AsBool(false), args[4].AsBool(runtime_local_default), env);}\n"
  },
  {
    "path": "avs_core/filters/conditional/conditional.h",
    "content": "\n// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include <avisynth.h>\n\n\nclass ConditionalSelect : public GenericVideoFilter\n{\npublic:\n  ConditionalSelect(PClip _child, AVSValue _script, int _num_args, PClip *_child_array, bool _show, bool _local, IScriptEnvironment* env);\n  ~ConditionalSelect();\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n  int __stdcall SetCacheHints(int cachehints, int frame_range);\n  static AVSValue __cdecl Create(AVSValue args, void* user_data, IScriptEnvironment* env);\n\nprivate:\n  AVSValue script;\n  const int num_args;\n  PClip *child_array;\n  const bool show;\n  bool local;\n  int child_devs;\n};\n\n\nclass ConditionalFilter : public GenericVideoFilter\n/**\n  * Conditional\n **/\n{\n  enum Eval {\n    NONE = 0,\n    EQUALS = 1,\n    GREATERTHAN = 2,\n    LESSTHAN = 4\n  };\n\npublic:\n  ConditionalFilter(PClip _child, PClip _source1, PClip _source2, AVSValue  _condition1, AVSValue  _evaluator, AVSValue  _condition2, bool _show, bool _local, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env);\n  int __stdcall SetCacheHints(int cachehints, int frame_range);\n  static AVSValue __cdecl Create(AVSValue args, void* user_data, IScriptEnvironment* env);\n\nprivate:\n  PClip source1;\n  PClip source2;\n  Eval evaluator;\n  AVSValue eval1;\n  AVSValue eval2;\n  bool show;\n  bool local;\n  int child_devs;\n};\n\nclass ScriptClip : public GenericVideoFilter\n{\npublic:\n  ScriptClip(PClip _child, AVSValue  _script, bool _show, bool _only_eval, bool _eval_after_frame, bool _local, IScriptEnvironment* env);\n  int __stdcall SetCacheHints(int cachehints, int frame_range);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n  static AVSValue __cdecl Create(AVSValue args, void* user_data, IScriptEnvironment* env);\n  static AVSValue __cdecl Create_eval(AVSValue args, void* user_data, IScriptEnvironment* env);\n\nprivate:\n  AVSValue script;\n  bool show;\n  bool only_eval;\n  bool eval_after;\n  bool local; // like in gRunT, watch at Neo and AVS+ differences! Compatibility is local=false\n};\n"
  },
  {
    "path": "avs_core/filters/conditional/conditional_functions.cpp",
    "content": "\n// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include \"conditional_functions.h\"\n#include \"../focus.h\" // sad\n#ifdef INTEL_INTRINSICS\n#include \"intel/conditional_functions_sse.h\"\n#include \"../intel/focus_sse.h\" // sad\n#endif\n#include \"../../core/internal.h\"\n#include <avs/config.h>\n#include <avs/minmax.h>\n#include <avs/alignment.h>\n#include <limits>\n#include <algorithm>\n#include <cmath>\n#include \"../core/AVSMap.h\"\n\nextern const AVSFunction Conditional_funtions_filters[] = {\n  {  \"AverageLuma\",    BUILTIN_FUNC_PREFIX, \"c[offset]i\", AveragePlane::Create, (void *)PLANAR_Y },\n  {  \"AverageChromaU\", BUILTIN_FUNC_PREFIX, \"c[offset]i\", AveragePlane::Create, (void *)PLANAR_U },\n  {  \"AverageChromaV\", BUILTIN_FUNC_PREFIX, \"c[offset]i\", AveragePlane::Create, (void *)PLANAR_V },\n  {  \"AverageR\", BUILTIN_FUNC_PREFIX, \"c[offset]i\", AveragePlane::Create, (void *)PLANAR_R },\n  {  \"AverageG\", BUILTIN_FUNC_PREFIX, \"c[offset]i\", AveragePlane::Create, (void *)PLANAR_G },\n  {  \"AverageB\", BUILTIN_FUNC_PREFIX, \"c[offset]i\", AveragePlane::Create, (void *)PLANAR_B },\n  {  \"AverageA\", BUILTIN_FUNC_PREFIX, \"c[offset]i\", AveragePlane::Create, (void *)PLANAR_A },\n  //{  \"AverageSat\",\"c[offset]i\", AverageSat::Create }, Sum(SatLookup[U,V])/N, SatLookup[U,V]=1.4087*sqrt((U-128)**2+(V-128)**2)\n//{  \"AverageHue\",\"c[offset]i\", AverageHue::Create }, Sum(HueLookup[U,V])/N, HueLookup[U,V]=40.5845*Atan2(U-128,V-128)\n\n  {  \"RGBDifference\",     BUILTIN_FUNC_PREFIX, \"cc\", ComparePlane::Create, (void *)-1 },\n  {  \"LumaDifference\",    BUILTIN_FUNC_PREFIX, \"cc\", ComparePlane::Create, (void *)PLANAR_Y },\n  {  \"ChromaUDifference\", BUILTIN_FUNC_PREFIX, \"cc\", ComparePlane::Create, (void *)PLANAR_U },\n  {  \"ChromaVDifference\", BUILTIN_FUNC_PREFIX, \"cc\", ComparePlane::Create, (void *)PLANAR_V },\n  {  \"RDifference\", BUILTIN_FUNC_PREFIX, \"cc\", ComparePlane::Create, (void *)PLANAR_R },\n  {  \"GDifference\", BUILTIN_FUNC_PREFIX, \"cc\", ComparePlane::Create, (void *)PLANAR_G },\n  {  \"BDifference\", BUILTIN_FUNC_PREFIX, \"cc\", ComparePlane::Create, (void *)PLANAR_B },\n  //{  \"SatDifference\",\"cc\", CompareSat::Create }, Sum(Abs(SatLookup[U1,V1]-SatLookup[U2,V2]))/N\n//{  \"HueDifference\",\"cc\", CompareHue::Create }, Sum(Abs(HueLookup[U1,V1]-HueLookup[U2,V2]))/N\n\n  {  \"YDifferenceFromPrevious\",   BUILTIN_FUNC_PREFIX, \"c\", ComparePlane::Create_prev, (void *)PLANAR_Y },\n  {  \"UDifferenceFromPrevious\",   BUILTIN_FUNC_PREFIX, \"c\", ComparePlane::Create_prev, (void *)PLANAR_U },\n  {  \"VDifferenceFromPrevious\",   BUILTIN_FUNC_PREFIX, \"c\", ComparePlane::Create_prev, (void *)PLANAR_V },\n  {  \"RGBDifferenceFromPrevious\", BUILTIN_FUNC_PREFIX, \"c\", ComparePlane::Create_prev, (void *)-1 },\n  {  \"RDifferenceFromPrevious\",   BUILTIN_FUNC_PREFIX, \"c\", ComparePlane::Create_prev, (void *)PLANAR_R },\n  {  \"GDifferenceFromPrevious\",   BUILTIN_FUNC_PREFIX, \"c\", ComparePlane::Create_prev, (void *)PLANAR_G },\n  {  \"BDifferenceFromPrevious\",   BUILTIN_FUNC_PREFIX, \"c\", ComparePlane::Create_prev, (void *)PLANAR_B },\n  //{  \"SatDifferenceFromPrevious\",\"c\", CompareSat::Create_prev },\n//{  \"HueDifferenceFromPrevious\",\"c\", CompareHue::Create_prev },\n\n  {  \"YDifferenceToNext\",   BUILTIN_FUNC_PREFIX, \"c[offset]i\", ComparePlane::Create_next, (void *)PLANAR_Y },\n  {  \"UDifferenceToNext\",   BUILTIN_FUNC_PREFIX, \"c[offset]i\", ComparePlane::Create_next, (void *)PLANAR_U },\n  {  \"VDifferenceToNext\",   BUILTIN_FUNC_PREFIX, \"c[offset]i\", ComparePlane::Create_next, (void *)PLANAR_V },\n  {  \"RGBDifferenceToNext\", BUILTIN_FUNC_PREFIX, \"c[offset]i\", ComparePlane::Create_next, (void *)-1 },\n  {  \"RDifferenceToNext\",   BUILTIN_FUNC_PREFIX, \"c[offset]i\", ComparePlane::Create_next, (void *)PLANAR_R },\n  {  \"GDifferenceToNext\",   BUILTIN_FUNC_PREFIX, \"c[offset]i\", ComparePlane::Create_next, (void *)PLANAR_G },\n  {  \"BDifferenceToNext\",   BUILTIN_FUNC_PREFIX, \"c[offset]i\", ComparePlane::Create_next, (void *)PLANAR_B },\n  //{  \"SatDifferenceFromNext\",\"c[offset]i\", CompareSat::Create_next },\n//{  \"HueDifferenceFromNext\",\"c[offset]i\", CompareHue::Create_next },\n  {  \"PlaneMinMaxStats\", BUILTIN_FUNC_PREFIX, \"c[threshold]f[offset]i[plane]i[setvar]b\", MinMaxPlane::Create_minmax_stats, (void*)-1 },\n  {  \"YPlaneMax\",    BUILTIN_FUNC_PREFIX, \"c[threshold]f[offset]i\", MinMaxPlane::Create_max, (void *)PLANAR_Y },\n  {  \"YPlaneMin\",    BUILTIN_FUNC_PREFIX, \"c[threshold]f[offset]i\", MinMaxPlane::Create_min, (void *)PLANAR_Y },\n  {  \"YPlaneMedian\", BUILTIN_FUNC_PREFIX, \"c[offset]i\", MinMaxPlane::Create_median, (void *)PLANAR_Y },\n  {  \"UPlaneMax\",    BUILTIN_FUNC_PREFIX, \"c[threshold]f[offset]i\", MinMaxPlane::Create_max, (void *)PLANAR_U },\n  {  \"UPlaneMin\",    BUILTIN_FUNC_PREFIX, \"c[threshold]f[offset]i\", MinMaxPlane::Create_min, (void *)PLANAR_U },\n  {  \"UPlaneMedian\", BUILTIN_FUNC_PREFIX, \"c[offset]i\", MinMaxPlane::Create_median, (void *)PLANAR_U },\n  {  \"VPlaneMax\",    BUILTIN_FUNC_PREFIX, \"c[threshold]f[offset]i\", MinMaxPlane::Create_max, (void *)PLANAR_V }, // AVS+! was before: missing offset parameter\n  {  \"VPlaneMin\",    BUILTIN_FUNC_PREFIX, \"c[threshold]f[offset]i\", MinMaxPlane::Create_min, (void *)PLANAR_V }, // AVS+! was before: missing offset parameter\n  {  \"VPlaneMedian\", BUILTIN_FUNC_PREFIX, \"c[offset]i\", MinMaxPlane::Create_median, (void *)PLANAR_V },\n  {  \"RPlaneMax\",    BUILTIN_FUNC_PREFIX, \"c[threshold]f[offset]i\", MinMaxPlane::Create_max, (void *)PLANAR_R },\n  {  \"RPlaneMin\",    BUILTIN_FUNC_PREFIX, \"c[threshold]f[offset]i\", MinMaxPlane::Create_min, (void *)PLANAR_R },\n  {  \"RPlaneMedian\", BUILTIN_FUNC_PREFIX, \"c[offset]i\", MinMaxPlane::Create_median, (void *)PLANAR_R },\n  {  \"GPlaneMax\",    BUILTIN_FUNC_PREFIX, \"c[threshold]f[offset]i\", MinMaxPlane::Create_max, (void *)PLANAR_G },\n  {  \"GPlaneMin\",    BUILTIN_FUNC_PREFIX, \"c[threshold]f[offset]i\", MinMaxPlane::Create_min, (void *)PLANAR_G },\n  {  \"GPlaneMedian\", BUILTIN_FUNC_PREFIX, \"c[offset]i\", MinMaxPlane::Create_median, (void *)PLANAR_G },\n  {  \"BPlaneMax\",    BUILTIN_FUNC_PREFIX, \"c[threshold]f[offset]i\", MinMaxPlane::Create_max, (void *)PLANAR_B },\n  {  \"BPlaneMin\",    BUILTIN_FUNC_PREFIX, \"c[threshold]f[offset]i\", MinMaxPlane::Create_min, (void *)PLANAR_B },\n  {  \"BPlaneMedian\", BUILTIN_FUNC_PREFIX, \"c[offset]i\", MinMaxPlane::Create_median, (void *)PLANAR_B },\n  {  \"YPlaneMinMaxDifference\", BUILTIN_FUNC_PREFIX, \"c[threshold]f[offset]i\", MinMaxPlane::Create_minmax, (void *)PLANAR_Y },\n  {  \"UPlaneMinMaxDifference\", BUILTIN_FUNC_PREFIX, \"c[threshold]f[offset]i\", MinMaxPlane::Create_minmax, (void *)PLANAR_U }, // AVS+! was before: missing offset parameter\n  {  \"VPlaneMinMaxDifference\", BUILTIN_FUNC_PREFIX, \"c[threshold]f[offset]i\", MinMaxPlane::Create_minmax, (void *)PLANAR_V }, // AVS+! was before: missing offset parameter\n  {  \"RPlaneMinMaxDifference\", BUILTIN_FUNC_PREFIX, \"c[threshold]f[offset]i\", MinMaxPlane::Create_minmax, (void *)PLANAR_R },\n  {  \"GPlaneMinMaxDifference\", BUILTIN_FUNC_PREFIX, \"c[threshold]f[offset]i\", MinMaxPlane::Create_minmax, (void *)PLANAR_G },\n  {  \"BPlaneMinMaxDifference\", BUILTIN_FUNC_PREFIX, \"c[threshold]f[offset]i\", MinMaxPlane::Create_minmax, (void *)PLANAR_B },\n\n//{  \"SatMax\",\"c[threshold]f[offset]i\", MinMaxPlane::Create_maxsat },  ++accum[SatLookup[U,V]]\n//{  \"SatMin\",\"c[threshold]f[offset]i\", MinMaxPlane::Create_minsat },\n//{  \"SatMedian\",\"c[offset]i\", MinMaxPlane::Create_mediansat },\n//{  \"SatMinMaxDifference\",\"c[threshold]f[offset]i\", MinMaxPlane::Create_minmaxsat },\n\n//{  \"HueMax\",\"c[threshold]f[offset]i\", MinMaxPlane::Create_maxhue },  ++accum[HueLookup[U,V]]\n//{  \"HueMin\",\"c[threshold]f[offset]i\", MinMaxPlane::Create_minhue },\n//{  \"HueMedian\",\"c[offset]i\", MinMaxPlane::Create_medianhue },\n//{  \"HueMinMaxDifference\",\"c[threshold]f[offset]i\", MinMaxPlane::Create_minmaxhue },\n\n  // frame property setters in conditional_reader\n  { \"propGetAny\", BUILTIN_FUNC_PREFIX, \"cs[index]i[offset]i\", GetProperty::Create, (void*)0 },\n  { \"propGetInt\", BUILTIN_FUNC_PREFIX, \"cs[index]i[offset]i\", GetProperty::Create, (void *)1 },\n  { \"propGetFloat\", BUILTIN_FUNC_PREFIX, \"cs[index]i[offset]i\", GetProperty::Create, (void*)2 },\n  { \"propGetString\", BUILTIN_FUNC_PREFIX, \"cs[index]i[offset]i\", GetProperty::Create, (void*)3 },\n  { \"propGetClip\", BUILTIN_FUNC_PREFIX, \"cs[index]i[offset]i\", GetProperty::Create, (void*)4 },\n  { \"propGetDataSize\", BUILTIN_FUNC_PREFIX, \"cs[index]i[offset]i\", GetPropertyDataSize::Create },\n  { \"propNumElements\", BUILTIN_FUNC_PREFIX, \"cs[offset]i\", GetPropertyNumElements::Create},\n  { \"propNumKeys\", BUILTIN_FUNC_PREFIX, \"c[offset]i\", GetPropertyNumKeys::Create},\n  { \"propGetKeyByIndex\", BUILTIN_FUNC_PREFIX, \"c[index]i[offset]i\", GetPropertyKeyByIndex::Create},\n  { \"propGetType\", BUILTIN_FUNC_PREFIX, \"cs[offset]i\", GetPropertyType::Create},\n  { \"propGetAsArray\", BUILTIN_FUNC_PREFIX, \"cs[offset]i\", GetPropertyAsArray::Create},\n  { \"propGetAll\", BUILTIN_FUNC_PREFIX, \"c[offset]i\", GetAllProperties::Create},\n\n  { 0 }\n};\n\n\nAVSValue AveragePlane::Create(AVSValue args, void* user_data, IScriptEnvironment* env) {\n  int plane = (int)reinterpret_cast<intptr_t>(user_data);\n  return AvgPlane(args[0], user_data, plane, args[1].AsInt(0), env);\n}\n\n// Average plane\ntemplate<typename pixel_t>\nstatic double get_sum_of_pixels_c(const BYTE* srcp8, size_t height, size_t width, size_t pitch) {\n  typedef typename std::conditional < sizeof(pixel_t) == 4, double, int64_t>::type sum_t;\n  sum_t accum = 0; // int32 holds sum of maximum 16 Mpixels for 8 bit, and 65536 pixels for uint16_t pixels\n  const pixel_t *srcp = reinterpret_cast<const pixel_t *>(srcp8);\n  pitch /= sizeof(pixel_t);\n  for (size_t y = 0; y < height; y++) {\n    for (size_t x = 0; x < width; x++) {\n      accum += srcp[x];\n    }\n    srcp += pitch;\n  }\n  return (double)accum;\n}\n\nAVSValue AveragePlane::AvgPlane(AVSValue clip, void* , int plane, int offset, IScriptEnvironment* env)\n{\n  if (!clip.IsClip())\n    env->ThrowError(\"Average Plane: No clip supplied!\");\n\n  PClip child = clip.AsClip();\n  VideoInfo vi = child->GetVideoInfo();\n\n  // input clip to always planar\n  if (vi.IsRGB() && !vi.IsPlanar()) {\n    AVSValue new_args[1] = { child };\n    if (vi.IsRGB24() || vi.IsRGB48())\n      child = env->Invoke(\"ConvertToPlanarRGB\", AVSValue(new_args, 1)).AsClip();\n    else // RGB32, RGB64\n      child = env->Invoke(\"ConvertToPlanarRGBA\", AVSValue(new_args, 1)).AsClip();\n    vi = child->GetVideoInfo();\n  }\n  else if (vi.IsYUY2()) {\n    AVSValue new_args[2] = { child, false };\n    child = env->Invoke(\"ConvertToYUV422\", AVSValue(new_args, 2)).AsClip();\n    vi = child->GetVideoInfo();\n  }\n\n  if (!vi.IsPlanar())\n    env->ThrowError(\"Average Plane: Only planar YUV or planar RGB images supported!\");\n\n  if (plane == PLANAR_A)\n  {\n    if (!vi.IsPlanarRGBA() && !vi.IsYUVA())\n      env->ThrowError(\"Average Plane: clip has no Alpha plane!\");\n  }\n  else if(vi.IsRGB())\n  { \n    if (plane != PLANAR_R && plane != PLANAR_G && plane != PLANAR_B)\n      env->ThrowError(\"Average Plane: not a valid plane for an RGB clip!\");\n  }\n  else if (vi.IsY()){\n    if (plane != PLANAR_Y)\n      env->ThrowError(\"Average Plane: not a valid plane for an greyscale clip!\");\n  }\n  else {\n    if (plane != PLANAR_Y && plane != PLANAR_U && plane != PLANAR_V)\n      env->ThrowError(\"Average Plane: not a valid plane for a YUV clip!\");\n  }\n\n  AVSValue cn = env->GetVarDef(\"current_frame\");\n  if (!cn.IsInt())\n    env->ThrowError(\"Average Plane: This filter can only be used within run-time filters\");\n\n  int n = cn.AsInt();\n  n = min(max(n+offset,0), vi.num_frames-1);\n\n  PVideoFrame src = child->GetFrame(n,env);\n\n  int pixelsize = vi.ComponentSize();\n\n  const BYTE* srcp = src->GetReadPtr(plane);\n  int height = src->GetHeight(plane);\n  int width = src->GetRowSize(plane) / pixelsize;\n  int pitch = src->GetPitch(plane);\n\n  if (width == 0 || height == 0)\n    env->ThrowError(\"Average Plane: plane does not exist!\");\n\n  double sum = 0.0;\n\n\n  int total_pixels = width*height;\n  bool sum_in_32bits;\n  if (pixelsize == 4)\n    sum_in_32bits = false;\n  else // worst case\n    sum_in_32bits = ((int64_t)total_pixels * (pixelsize == 1 ? 255 : 65535)) <= std::numeric_limits<int>::max();\n\n#ifdef INTEL_INTRINSICS\n  if ((pixelsize==1) && sum_in_32bits && (env->GetCPUFlags() & CPUF_SSE2) && width >= 16) {\n    sum = get_sum_of_pixels_sse2(srcp, height, width, pitch);\n  } else\n#ifdef X86_32\n  if ((pixelsize==1) && sum_in_32bits && (env->GetCPUFlags() & CPUF_INTEGER_SSE) && width >= 8) {\n    sum = get_sum_of_pixels_isse(srcp, height, width, pitch);\n  } else\n#endif\n#endif\n  {\n    if(pixelsize==1)\n      sum = get_sum_of_pixels_c<uint8_t>(srcp, height, width, pitch);\n    else if(pixelsize==2)\n      sum = get_sum_of_pixels_c<uint16_t>(srcp, height, width, pitch);\n    else // pixelsize==4\n      sum = get_sum_of_pixels_c<float>(srcp, height, width, pitch);\n  }\n\n  float f = (float)(sum / (height * width));\n\n  return (AVSValue)f;\n}\n\nAVSValue ComparePlane::Create(AVSValue args, void* user_data, IScriptEnvironment* env) {\n  int plane = (int)reinterpret_cast<intptr_t>(user_data);\n  return CmpPlane(args[0],args[1], user_data, plane, env);\n}\n\nAVSValue ComparePlane::Create_prev(AVSValue args, void* user_data, IScriptEnvironment* env) {\n  int plane = (int)reinterpret_cast<intptr_t>(user_data);\n  return CmpPlaneSame(args[0], user_data, -1, plane, env);\n}\n\nAVSValue ComparePlane::Create_next(AVSValue args, void* user_data, IScriptEnvironment* env) {\n  int plane = (int)reinterpret_cast<intptr_t>(user_data);\n  return CmpPlaneSame(args[0], user_data, args[1].AsInt(1), plane, env);\n}\n\n\ntemplate<typename pixel_t>\nstatic double get_sad_c(const BYTE* c_plane8, const BYTE* t_plane8, size_t height, size_t width, size_t c_pitch, size_t t_pitch) {\n  const pixel_t *c_plane = reinterpret_cast<const pixel_t *>(c_plane8);\n  const pixel_t *t_plane = reinterpret_cast<const pixel_t *>(t_plane8);\n  c_pitch /= sizeof(pixel_t);\n  t_pitch /= sizeof(pixel_t);\n  typedef typename std::conditional < sizeof(pixel_t) == 4, double, int64_t>::type sum_t;\n  sum_t accum = 0; // int32 holds sum of maximum 16 Mpixels for 8 bit, and 65536 pixels for uint16_t pixels\n\n  for (size_t y = 0; y < height; y++) {\n    for (size_t x = 0; x < width; x++) {\n      accum += std::abs(t_plane[x] - c_plane[x]);\n    }\n    c_plane += c_pitch;\n    t_plane += t_pitch;\n  }\n  return (double)accum;\n\n}\n\ntemplate<typename pixel_t>\nstatic double get_sad_rgb_c(const BYTE* c_plane8, const BYTE* t_plane8, size_t height, size_t width, size_t c_pitch, size_t t_pitch) {\n  const pixel_t *c_plane = reinterpret_cast<const pixel_t *>(c_plane8);\n  const pixel_t *t_plane = reinterpret_cast<const pixel_t *>(t_plane8);\n  c_pitch /= sizeof(pixel_t);\n  t_pitch /= sizeof(pixel_t);\n  int64_t accum = 0; // packed rgb: integer type only\n  for (size_t y = 0; y < height; y++) {\n    for (size_t x = 0; x < width; x+=4) {\n      accum += std::abs(t_plane[x] - c_plane[x]);\n      accum += std::abs(t_plane[x+1] - c_plane[x+1]);\n      accum += std::abs(t_plane[x+2] - c_plane[x+2]);\n    }\n    c_plane += c_pitch;\n    t_plane += t_pitch;\n  }\n  return (double)accum;\n\n}\n\nAVSValue ComparePlane::CmpPlane(AVSValue clip, AVSValue clip2, void* , int plane, IScriptEnvironment* env)\n{\n  if (!clip.IsClip())\n    env->ThrowError(\"Plane Difference: No clip supplied!\");\n  if (!clip2.IsClip())\n    env->ThrowError(\"Plane Difference: Second parameter is not a clip!\");\n\n  PClip child = clip.AsClip();\n  VideoInfo vi = child->GetVideoInfo();\n  PClip child2 = clip2.AsClip();\n  VideoInfo vi2 = child2->GetVideoInfo();\n  if (plane !=-1 ) {\n    if (!vi.IsPlanar() || !vi2.IsPlanar())\n      env->ThrowError(\"Plane Difference: Only planar YUV or planar RGB images supported!\");\n  } else {\n    if(vi.IsPlanarRGB() || vi.IsPlanarRGBA())\n      env->ThrowError(\"RGB Difference: Planar RGB is not supported here (clip 1)\");\n    if(vi2.IsPlanarRGB() || vi2.IsPlanarRGBA())\n      env->ThrowError(\"RGB Difference: Planar RGB is not supported here (clip 2)\");\n    if (!vi.IsRGB())\n      env->ThrowError(\"RGB Difference: RGB difference can only be tested on RGB images! (clip 1)\");\n    if (!vi2.IsRGB())\n      env->ThrowError(\"RGB Difference: RGB difference can only be tested on RGB images! (clip 2)\");\n    plane = 0;\n  }\n\n  AVSValue cn = env->GetVarDef(\"current_frame\");\n  if (!cn.IsInt())\n    env->ThrowError(\"Plane Difference: This filter can only be used within run-time filters\");\n\n  int n = cn.AsInt();\n  n = clamp(n,0,vi.num_frames-1);\n\n  PVideoFrame src = child->GetFrame(n,env);\n  PVideoFrame src2 = child2->GetFrame(n,env);\n\n  int pixelsize = vi.ComponentSize();\n\n  const BYTE* srcp = src->GetReadPtr(plane);\n  const BYTE* srcp2 = src2->GetReadPtr(plane);\n  const int height = src->GetHeight(plane);\n  const int rowsize = src->GetRowSize(plane);\n  const int width = rowsize / pixelsize;\n  const int pitch = src->GetPitch(plane);\n  const int height2 = src2->GetHeight(plane);\n  const int rowsize2 = src2->GetRowSize(plane);\n  const int width2 = rowsize2 / pixelsize;\n  const int pitch2 = src2->GetPitch(plane);\n\n  if(vi.ComponentSize() != vi2.ComponentSize())\n    env->ThrowError(\"Plane Difference: Bit-depth are not the same!\");\n\n  if (width == 0 || height == 0)\n    env->ThrowError(\"Plane Difference: plane does not exist!\");\n\n  if (height != height2 || width != width2)\n    env->ThrowError(\"Plane Difference: Images are not the same size!\");\n\n#ifdef X86_32\n  int bits_per_pixel = vi.BitsPerComponent();\n  int total_pixels = width*height;\n  bool sum_in_32bits;\n  if (pixelsize == 4)\n    sum_in_32bits = false;\n  else // worst case check\n    sum_in_32bits = ((int64_t)total_pixels * ((1 << bits_per_pixel) - 1)) <= std::numeric_limits<int>::max();\n#endif\n\n  double sad = 0.0;\n\n  // for c: width, for sse: rowsize\n  if (vi.IsRGB32() || vi.IsRGB64()) {\n#ifdef INTEL_INTRINSICS\n    if ((pixelsize == 2) && (env->GetCPUFlags() & CPUF_SSE2) && rowsize >= 16) {\n      // int64 internally, no sum_in_32bits\n      sad = (double)calculate_sad_8_or_16_sse2<uint16_t,true>(srcp, srcp2, pitch, pitch2, width*pixelsize, height); // in focus. 21.68/21.39\n    } else if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_SSE2) && rowsize >= 16) {\n      sad = (double)calculate_sad_8_or_16_sse2<uint8_t,true>(srcp, srcp2, pitch, pitch2, rowsize, height); // in focus, no overflow\n    } else\n#ifdef X86_32\n      if ((pixelsize==1) && sum_in_32bits && (env->GetCPUFlags() & CPUF_INTEGER_SSE) && width >= 8) {\n        sad = get_sad_rgb_isse(srcp, srcp2, height, rowsize, pitch, pitch2);\n      } else\n#endif\n#endif\n      {\n        if (pixelsize == 1)\n          sad = (double)get_sad_rgb_c<uint8_t>(srcp, srcp2, height, width, pitch, pitch2);\n        else // pixelsize==2\n          sad = (double)get_sad_rgb_c<uint16_t>(srcp, srcp2, height, width, pitch, pitch2);\n      }\n  } else {\n#ifdef INTEL_INTRINSICS\n    if ((pixelsize==2) && (env->GetCPUFlags() & CPUF_SSE2) && rowsize >= 16) {\n      sad = (double)calculate_sad_8_or_16_sse2<uint16_t,false>(srcp, srcp2, pitch, pitch2, rowsize, height); // in focus, no overflow\n    } else\n      if ((pixelsize==1) && (env->GetCPUFlags() & CPUF_SSE2) && rowsize >= 16) {\n      sad = (double)calculate_sad_8_or_16_sse2<uint8_t,false>(srcp, srcp2, pitch, pitch2, rowsize, height); // in focus, no overflow\n    } else\n#ifdef X86_32\n      if ((pixelsize==1) && sum_in_32bits && (env->GetCPUFlags() & CPUF_INTEGER_SSE) && width >= 8) {\n        sad = get_sad_isse(srcp, srcp2, height, rowsize, pitch, pitch2);\n      } else\n#endif\n#endif\n      {\n        if(pixelsize==1)\n          sad = get_sad_c<uint8_t>(srcp, srcp2, height, width, pitch, pitch2);\n        else if(pixelsize==2)\n          sad = get_sad_c<uint16_t>(srcp, srcp2, height, width, pitch, pitch2);\n        else // pixelsize==4\n          sad = get_sad_c<float>(srcp, srcp2, height, width, pitch, pitch2);\n      }\n  }\n\n  float f;\n\n  if (vi.IsRGB32() || vi.IsRGB64())\n    f = (float)((sad * 4) / (height * width * 3)); // why * 4/3? alpha plane was masked out, anyway\n  else\n    f = (float)(sad / (height * width));\n\n  return (AVSValue)f;\n}\n\n\nAVSValue ComparePlane::CmpPlaneSame(AVSValue clip, void* , int offset, int plane, IScriptEnvironment* env)\n{\n  if (!clip.IsClip())\n    env->ThrowError(\"Plane Difference: No clip supplied!\");\n\n  PClip child = clip.AsClip();\n  VideoInfo vi = child->GetVideoInfo();\n  if (plane ==-1 ) {\n    if (!vi.IsRGB() || vi.IsPlanarRGB() || vi.IsPlanarRGBA())\n      env->ThrowError(\"RGB Difference: RGB difference can only be calculated on packed RGB images\");\n    plane = 0;\n  } else {\n    if (!vi.IsPlanar())\n      env->ThrowError(\"Plane Difference: Only planar YUV or planar RGB images images supported!\");\n  }\n\n  AVSValue cn = env->GetVarDef(\"current_frame\");\n  if (!cn.IsInt())\n    env->ThrowError(\"Plane Difference: This filter can only be used within run-time filters\");\n\n  int n = cn.AsInt();\n  n = clamp(n,0,vi.num_frames-1);\n  int n2 = clamp(n+offset,0,vi.num_frames-1);\n\n  PVideoFrame src = child->GetFrame(n,env);\n  PVideoFrame src2 = child->GetFrame(n2,env);\n\n  int pixelsize = vi.ComponentSize();\n\n  const BYTE* srcp = src->GetReadPtr(plane);\n  const BYTE* srcp2 = src2->GetReadPtr(plane);\n  int height = src->GetHeight(plane);\n  int rowsize = src->GetRowSize(plane);\n  int width = rowsize / pixelsize;\n  int pitch = src->GetPitch(plane);\n  int pitch2 = src2->GetPitch(plane);\n\n  if (width == 0 || height == 0)\n    env->ThrowError(\"Plane Difference: No chroma planes in greyscale clip!\");\n\n#ifdef X86_32\n  int bits_per_pixel = vi.BitsPerComponent();\n  int total_pixels = width * height;\n  bool sum_in_32bits;\n  if (pixelsize == 4)\n    sum_in_32bits = false;\n  else // worst case check\n    sum_in_32bits = ((int64_t)total_pixels * ((1 << bits_per_pixel) - 1)) <= std::numeric_limits<int>::max();\n#endif\n\n  double sad = 0;\n  // for c: width, for sse: rowsize\n  if (vi.IsRGB32() || vi.IsRGB64()) {\n#ifdef INTEL_INTRINSICS\n    if ((pixelsize == 2) && (env->GetCPUFlags() & CPUF_SSE2) && rowsize >= 16) {\n      // int64 internally, no sum_in_32bits\n      sad = (double)calculate_sad_8_or_16_sse2<uint16_t,true>(srcp, srcp2, pitch, pitch2, rowsize, height); // in focus. 21.68/21.39\n    } else if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_SSE2) && rowsize >= 16) {\n      sad = (double)calculate_sad_8_or_16_sse2<uint8_t,true>(srcp, srcp2, pitch, pitch2, rowsize, height); // in focus, no overflow\n    } else\n#ifdef X86_32\n      if ((pixelsize==1) && sum_in_32bits && (env->GetCPUFlags() & CPUF_INTEGER_SSE) && width >= 8) {\n        sad = get_sad_rgb_isse(srcp, srcp2, height, rowsize, pitch, pitch2);\n      } else\n#endif\n#endif\n      {\n        if(pixelsize==1)\n          sad = get_sad_rgb_c<uint8_t>(srcp, srcp2, height, width, pitch, pitch2);\n        else\n          sad = get_sad_rgb_c<uint16_t>(srcp, srcp2, height, width, pitch, pitch2);\n      }\n  } else {\n#ifdef INTEL_INTRINSICS\n    if ((pixelsize==2) && (env->GetCPUFlags() & CPUF_SSE2) && rowsize >= 16) {\n      sad = (double)calculate_sad_8_or_16_sse2<uint16_t,false>(srcp, srcp2, pitch, pitch2, rowsize, height); // in focus, no overflow\n    } else if ((pixelsize==1) && (env->GetCPUFlags() & CPUF_SSE2) && rowsize >= 16) {\n      sad = (double)calculate_sad_8_or_16_sse2<uint8_t,false>(srcp, srcp2, pitch, pitch2, rowsize, height); // in focus, no overflow\n    } else\n#ifdef X86_32\n      if ((pixelsize==1) && sum_in_32bits && (env->GetCPUFlags() & CPUF_INTEGER_SSE) && width >= 8) {\n        sad = get_sad_isse(srcp, srcp2, height, width, pitch, pitch2);\n      } else\n#endif\n#endif\n      {\n        if(pixelsize==1)\n          sad = get_sad_c<uint8_t>(srcp, srcp2, height, width, pitch, pitch2);\n        else if (pixelsize==2)\n          sad = get_sad_c<uint16_t>(srcp, srcp2, height, width, pitch, pitch2);\n        else // pixelsize==4\n          sad = get_sad_c<float>(srcp, srcp2, height, width, pitch, pitch2);\n      }\n  }\n\n  float f;\n\n  if (vi.IsRGB32() || vi.IsRGB64())\n    f = (float)((sad * 4) / (height * width * 3));\n  else\n    f = (float)(sad / (height * width));\n\n  return (AVSValue)f;\n}\n\nAVSValue MinMaxPlane::Create_minmax_stats(AVSValue args, void* user_data, IScriptEnvironment* env) {\n  const int plane = args[3].AsInt(0); // 0:Y or R  1:U or G  2: V or B  3:A\n  if (plane < 0 || plane>3)\n    env->ThrowError(\"MinMax Stats: plane index must be between 0-3!\");\n\n  if (!args[0].IsClip())\n    env->ThrowError(\"MinMax Stats: No clip supplied!\");\n\n  VideoInfo vi = args[0].AsClip()->GetVideoInfo();\n  const int planes_y[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };\n  const int planes_r[4] = { PLANAR_R, PLANAR_G, PLANAR_B, PLANAR_A }; // in 'logical' RGB order\n  const int* planes = (vi.IsYUV() || vi.IsYUVA()) ? planes_y : planes_r;\n\n  const int current_plane = planes[plane];\n\n  const int setvar = args[4].AsBool(false);\n\n  return MinMax(args[0], user_data, args[1].AsDblDef(0.0), args[2].AsInt(0), current_plane, MinMaxPlane::STATS, setvar, env);\n}\n\n\nAVSValue MinMaxPlane::Create_max(AVSValue args, void* user_data, IScriptEnvironment* env) {\n  int plane = (int)reinterpret_cast<intptr_t>(user_data);\n  return MinMax(args[0], user_data, args[1].AsDblDef(0.0), args[2].AsInt(0), plane, MinMaxPlane::MAX, false, env);\n}\n\nAVSValue MinMaxPlane::Create_min(AVSValue args, void* user_data, IScriptEnvironment* env) {\n  int plane = (int)reinterpret_cast<intptr_t>(user_data);\n  return MinMax(args[0], user_data, args[1].AsDblDef(0.0), args[2].AsInt(0), plane, MinMaxPlane::MIN, false, env);\n}\n\nAVSValue MinMaxPlane::Create_median(AVSValue args, void* user_data, IScriptEnvironment* env) {\n  int plane = (int)reinterpret_cast<intptr_t>(user_data);\n  // MEDIAN: min 50%\n  return MinMax(args[0], user_data, 50.0, args[1].AsInt(0), plane, MinMaxPlane::MIN, false, env);\n}\n\nAVSValue MinMaxPlane::Create_minmax(AVSValue args, void* user_data, IScriptEnvironment* env) {\n  int plane = (int)reinterpret_cast<intptr_t>(user_data);\n  return MinMax(args[0], user_data, args[1].AsDblDef(0.0), args[2].AsInt(0), plane, MinMaxPlane::MINMAX_DIFFERENCE, false, env);\n}\n\ntemplate<bool average>\nvoid get_minmax_float_c(const BYTE* srcp, int pitch, int w, int h, float& min, float& max, double &sum)\n{\n  min = *reinterpret_cast<const float*>(srcp);\n  max = min;\n  sum = 0;\n\n  for (int y = 0; y < h; y++) {\n    for (int x = 0; x < w; x++) {\n      const float pix = reinterpret_cast<const float*>(srcp)[x];\n      if constexpr(average)\n        sum += pix;\n      if (pix < min) min = pix;\n      if (pix > max) max = pix;\n    }\n    srcp += pitch;\n  }\n}\n\ntemplate<typename pixel_t, bool average>\nvoid get_minmax_int_c(const BYTE* srcp, int pitch, int w, int h, int& min, int& max, int64_t& sum)\n{\n  min = *reinterpret_cast<const pixel_t*>(srcp);\n  max = min;\n  sum = 0;\n\n  for (int y = 0; y < h; y++) {\n    int tmpsum = 0;\n    for (int x = 0; x < w; x++) {\n      const int pix = reinterpret_cast<const pixel_t*>(srcp)[x];\n      if constexpr (average)\n        sum += pix;\n      if (pix < min) min = pix;\n      if (pix > max) max = pix;\n    }\n    if constexpr (average)\n      sum += tmpsum;\n    srcp += pitch;\n  }\n}\n\nAVSValue MinMaxPlane::MinMax(AVSValue clip, void* , double threshold, int offset, int plane, int mode, bool setvar, IScriptEnvironment* env) {\n\n  if (!clip.IsClip())\n    env->ThrowError(\"MinMax: No clip supplied!\");\n\n  PClip child = clip.AsClip();\n  VideoInfo vi = child->GetVideoInfo();\n\n  if (vi.IsRGB()) {\n    if (plane == PLANAR_Y || plane == PLANAR_U || plane == PLANAR_V)\n      env->ThrowError(\"MinMax: no such plane in RGB format\");\n  }\n  else if (vi.IsY()) {\n    if (plane != PLANAR_Y)\n      env->ThrowError(\"MinMax: no such plane in Y (greyscale) format\");\n  }\n  else {\n    if (plane == PLANAR_R || plane == PLANAR_G || plane == PLANAR_B)\n      env->ThrowError(\"MinMax: no such plane in YUV format\");\n  }\n  if (vi.NumComponents() < 4 && plane == PLANAR_A)\n    env->ThrowError(\"MinMax: no Alpha plane in this format\");\n\n  // input clip to always planar\n  if (vi.IsRGB() && !vi.IsPlanar()) {\n    AVSValue new_args[1] = { child };\n    if (vi.IsRGB24() || vi.IsRGB48())\n      child = env->Invoke(\"ConvertToPlanarRGB\", AVSValue(new_args, 1)).AsClip();\n    else // RGB32, RGB64\n      child = env->Invoke(\"ConvertToPlanarRGBA\", AVSValue(new_args, 1)).AsClip();\n    vi = child->GetVideoInfo();\n  }\n  else if (vi.IsYUY2()) {\n    AVSValue new_args[2] = { child, false };\n    child = env->Invoke(\"ConvertToYUV422\", AVSValue(new_args, 2)).AsClip();\n    vi = child->GetVideoInfo();\n  }\n\n  if (!vi.IsPlanar())\n    env->ThrowError(\"MinMax: Image must be planar\");\n\n  // Get current frame number\n  AVSValue cn = env->GetVarDef(\"current_frame\");\n  if (!cn.IsInt())\n    env->ThrowError(\"MinMax: This filter can only be used within run-time filters\");\n\n  int n = cn.AsInt();\n  n = min(max(n + offset, 0), vi.num_frames - 1);\n\n  // Prepare the source\n  PVideoFrame src = child->GetFrame(n, env);\n\n  const BYTE* srcp = src->GetReadPtr(plane);\n  int pitch = src->GetPitch(plane);\n  int pixelsize = vi.ComponentSize();\n  int w = src->GetRowSize(plane) / pixelsize; // good for packed rgb as well\n  int h = src->GetHeight(plane);\n\n  if (w == 0 || h == 0)\n    env->ThrowError(\"MinMax: plane does not exist!\");\n\n  float stats_min;\n  float stats_max;\n  float stats_median;\n  float stats_thresholded_min;\n  float stats_thresholded_max;\n  float stats_average;\n\n  if (threshold == 0 || mode == MinMaxPlane::STATS) {\n    // special case, no histogram needed\n\n    if (pixelsize == 4) // 32 bit float\n    {\n      double sum = 0;\n      if (mode == MinMaxPlane::STATS)\n        get_minmax_float_c<true>(srcp, pitch, w, h, stats_min, stats_max, sum);\n      else\n        get_minmax_float_c<false>(srcp, pitch, w, h, stats_min, stats_max, sum);\n\n      if (mode == MinMaxPlane::MIN) return stats_min;\n      else if (mode == MinMaxPlane::MAX) return stats_max;\n      else if (mode == MinMaxPlane::MINMAX_DIFFERENCE) return stats_max - stats_min;\n      stats_average = (float)(sum / (w * h));\n      // STATS: go on\n    }\n    else\n    {\n      int min, max;\n      int64_t sum = 0;\n      // sse4.1 is not any faster\n      if(pixelsize == 1)\n        if (mode == MinMaxPlane::STATS)\n          get_minmax_int_c<uint8_t, true>(srcp, pitch, w, h, min, max, sum);\n        else\n          get_minmax_int_c<uint8_t, false>(srcp, pitch, w, h, min, max, sum);\n      else\n        if (mode == MinMaxPlane::STATS)\n          get_minmax_int_c<uint16_t, true>(srcp, pitch, w, h, min, max, sum);\n        else\n          get_minmax_int_c<uint16_t, false>(srcp, pitch, w, h, min, max, sum);\n\n      if (mode == MinMaxPlane::MIN) return min;\n      else if (mode == MinMaxPlane::MAX) return max;\n      else if (mode == MinMaxPlane::MINMAX_DIFFERENCE) return max - min;\n\n      // STATS: go on\n      stats_min = (float)min;\n      stats_max = (float)max;\n      stats_average = (float)((double)sum / (w * h));\n    }\n  }\n\n  const int bits_per_pixel = vi.BitsPerComponent();\n  const int max_pixel_value = (1 << bits_per_pixel) - 1;\n\n  const int buffersize = pixelsize == 4 ? 65536 : (1 << bits_per_pixel); // 65536 for float, too, reason for 10-14 bits: avoid overflow\n  uint32_t* accum_buf = new uint32_t[buffersize];\n\n  // Reset accumulators\n  std::fill_n(accum_buf, buffersize, 0);\n\n  // Count each component\n  if (pixelsize == 1) {\n    for (int y = 0; y < h; y++) {\n      for (int x = 0; x < w; x++) {\n        accum_buf[srcp[x]]++; // safe\n      }\n      srcp += pitch;\n    }\n  }\n  else if (pixelsize == 2) {\n    for (int y = 0; y < h; y++) {\n      for (int x = 0; x < w; x++) {\n        accum_buf[min((int)(reinterpret_cast<const uint16_t *>(srcp)[x]), max_pixel_value)]++;\n      }\n      srcp += pitch;\n    }\n  }\n  else { //pixelsize==4 float\n // for float results are always checked with 16 bit precision only\n // or else we cannot populate non-digital steps with this standard method\n    // See similar in colors, ColorYUV analyze\n    const bool chroma = (plane == PLANAR_U) || (plane == PLANAR_V);\n    if (chroma) {\n      const float shift = 32768.0f;\n      for (int y = 0; y < h; y++) {\n        for (int x = 0; x < w; x++) {\n          // -0.5..0.5 to 0..65535\n          const float pixel = reinterpret_cast<const float *>(srcp)[x];\n          accum_buf[clamp((int)(65535.0f*pixel + shift + 0.5f), 0, 65535)]++;\n        }\n        srcp += pitch;\n      }\n    }\n    else {\n      for (int y = 0; y < h; y++) {\n        for (int x = 0; x < w; x++) {\n          const float pixel = reinterpret_cast<const float *>(srcp)[x];\n          accum_buf[clamp((int)(65535.0f * pixel + 0.5f), 0, 65535)]++;\n        }\n        srcp += pitch;\n      }\n    }\n  }\n\n  int pixels = w*h;\n  threshold /=100.0;  // Thresh now 0-1\n  threshold = clamp(threshold, 0.0, 1.0);\n\n  unsigned int tpixels = (unsigned int)(pixels*threshold);\n\n  int retval;\n\n    // Find the value we need.\n  if (mode == MinMaxPlane::MIN) {\n    // threshold == 0 was covered already\n    unsigned int counted=0;\n    retval = buffersize - 1;\n    for (int i = 0; i< buffersize;i++) {\n      counted += accum_buf[i];\n      if (counted>tpixels) {\n        retval = i;\n        break;\n      }\n    }\n  }\n  else if (mode == MinMaxPlane::MAX) {\n    unsigned int counted=0;\n    retval = 0;\n    for (int i = buffersize-1; i>=0;i--) {\n      counted += accum_buf[i];\n      if (counted>tpixels) {\n        retval = i;\n        break;\n      }\n    }\n  }\n  else if (mode == MinMaxPlane::STATS && threshold == 0) {\n    stats_thresholded_min = (float)stats_min;\n    stats_thresholded_max = (float)stats_max;\n    retval = -1; // stats: n/a\n  }\n  else if (mode == MinMaxPlane::MINMAX_DIFFERENCE || mode == MinMaxPlane::STATS) {\n    // thresholded case\n    unsigned int counted=0;\n    int i, t_min = 0;\n    // Find min\n    for (i = 0; i < buffersize;i++) {\n      counted += accum_buf[i];\n      if (counted>tpixels) {\n        t_min=i;\n        break;\n      }\n    }\n\n    // Find max\n    counted=0;\n    int t_max = buffersize-1;\n    for (i = buffersize-1; i>=0;i--) {\n      counted += accum_buf[i];\n      if (counted>tpixels) {\n        t_max=i;\n        break;\n      }\n    }\n\n    retval = t_max - t_min; // results <0 will be returned if threshold > 50\n    stats_thresholded_min = (float)t_min;\n    stats_thresholded_max = (float)t_max;\n  }\n  \n  if (mode == MinMaxPlane::STATS) {\n    // for STATS we already have min and max, thresholded min and max\n    // let's gather median, which is equal to 50% MIN\n    // comment: no separate MEDIAN mode is used, already converted to MIN 50% in ctor\n    unsigned int tpixels = (unsigned int)(pixels * 0.5f);\n    unsigned int counted = 0;\n    retval = buffersize - 1;\n    for (int i = 0; i < buffersize; i++) {\n      counted += accum_buf[i];\n      if (counted > tpixels) {\n        retval = i;\n        break;\n      }\n    }\n    stats_median = (float)retval;\n  }\n\n  delete[] accum_buf;\n  //_RPT2(0, \"End of MinMax cn=%d n=%d\\r\", cn.AsInt(), n);\n\n  if (mode == MinMaxPlane::STATS) {\n    if (pixelsize == 4) {\n      const bool chroma = (plane == PLANAR_U) || (plane == PLANAR_V);\n      const float shift = chroma ? 32768.0f : 0;\n      stats_thresholded_min = (float)((double)(stats_thresholded_min - shift) / (buffersize - 1)); // convert back to float, /65535\n      stats_thresholded_max = (float)((double)(stats_thresholded_max - shift) / (buffersize - 1)); // convert back to float, /65535\n      stats_median = (float)((double)(stats_median - shift) / (buffersize - 1)); // convert back to float, /65535\n    }\n\n    AVSValue result[] = { stats_min, stats_max, stats_thresholded_min, stats_thresholded_max, stats_median, stats_average };\n    AVSValue ret = AVSValue(result, 6);\n    if (setvar) {\n      env->SetGlobalVar(\"PlaneStats_min\", stats_min);\n      env->SetGlobalVar(\"PlaneStats_max\", stats_max);\n      env->SetGlobalVar(\"PlaneStats_thmin\", stats_thresholded_min);\n      env->SetGlobalVar(\"PlaneStats_thmax\", stats_thresholded_max);\n      env->SetGlobalVar(\"PlaneStats_median\", stats_median);\n      env->SetGlobalVar(\"PlaneStats_average\", stats_average);\n    }\n\n    return ret;\n  }\n\n  if (pixelsize == 4) {\n    const bool chroma = (plane == PLANAR_U) || (plane == PLANAR_V);\n    if (chroma && (mode == MIN || mode == MAX)) {\n      const float shift = 32768.0f;\n      return AVSValue((double)(retval - shift) / (buffersize - 1)); // convert back to float, /65535\n    }\n    else {\n      return AVSValue((double)retval / (buffersize - 1)); // convert back to float, /65535\n    }\n  }\n  else\n    return AVSValue(retval);\n}\n\n\nAVSValue GetProperty::Create(AVSValue args, void* user_data, IScriptEnvironment* env_) {\n  InternalEnvironment* IEnv = GetAndRevealCamouflagedEnv(env_);\n  IScriptEnvironment* env = static_cast<IScriptEnvironment*>(IEnv);\n\n  AVSValue clip = args[0];\n  if (!clip.IsClip())\n    env->ThrowError(\"propGetxxxxx: No clip supplied!\");\n\n  PClip child = clip.AsClip();\n  VideoInfo vi = child->GetVideoInfo();\n\n  AVSValue cn = env->GetVarDef(\"current_frame\");\n  const bool calledFromRunTime = cn.IsInt();\n\n  int propType = (int)(intptr_t)user_data;\n  // vUnset, vInt, vFloat, vData, vNode/Clip, vFrame/*, vMethod*/ }\n  // 0: auto\n  // 1: integer (int64 long)\n  // 2: float (double)\n  // 3: char (null terminated data)\n  // 4: Clip\n\n  const char* propName = args[1].AsString();\n  const int index = args[2].AsInt(0);\n  const int offset = args[3].AsInt(0);\n\n  int n = calledFromRunTime ? cn.AsInt() : 0;\n  n = min(max(n + offset, 0), vi.num_frames - 1);\n\n  PVideoFrame src = child->GetFrame(n, env);\n\n  const AVSMap* avsmap = env->getFramePropsRO(src);\n\n  int error = 0;\n\n  // check auto\n  if (propType == 0) {\n    char res = env->propGetType(avsmap, propName);\n    // 'u'nset, 'i'nteger, 'f'loat, 's'string, 'c'lip, 'v'ideoframe, 'm'ethod };\n    switch (res) {\n    case 'u': return AVSValue(); // unSet = AVS undefined\n    case 'v': env->ThrowError(\"Error getting frame property \\\"%s\\\": video frames not supported as function return values\", propName);\n      break;\n    case 'i': propType = 1; break;\n    case 'f': propType = 2; break;\n    case 's': propType = 3; break;\n    case 'c': propType = 4; break;\n    default:\n      env->ThrowError(\"Error getting frame property \\\"%s\\\": type '%c' not supported\", propName, res);\n    }\n  }\n\n  if (propType == 1) {\n    int64_t result = env->propGetInt(avsmap, propName, index, &error);\n    if(!error)\n      return AVSValue(result); // v11: no need for (int) cast\n  }\n  else if (propType == 2) {\n    double result = env->propGetFloat(avsmap, propName, index, &error);\n    if (!error)\n      return AVSValue(result);\n  }\n  else if (propType == 3) {\n    const char *result = env->propGetData(avsmap, propName, index, &error);\n    if (!error) {\n      result = env->SaveString(result); // property had its own storage\n      return AVSValue(result);\n    }\n  }\n  else if (propType == 4) {\n    PClip result = env->propGetClip(avsmap, propName, index, &error);\n    if (!error)\n      return AVSValue(result);\n  }\n  else {\n    error = AVSGetPropErrors::GETPROPERROR_TYPE;\n  }\n\n  const char* error_msg = nullptr;\n\n  // really, errors are bits\n  if (error & AVSGetPropErrors::GETPROPERROR_UNSET)\n    error_msg = \"property is not set\";\n  else if (error & AVSGetPropErrors::GETPROPERROR_TYPE)\n    error_msg = \"wrong type\";\n  else if (error & AVSGetPropErrors::GETPROPERROR_INDEX)\n    error_msg = \"index error\"; // arrays\n\n  if (error)\n    env->ThrowError(\"Error getting frame property \\\"%s\\\": %s \", propName, error_msg);\n\n  return AVSValue();\n}\n\nAVSValue GetPropertyAsArray::Create(AVSValue args, void* , IScriptEnvironment* env_)\n{\n  InternalEnvironment* IEnv = GetAndRevealCamouflagedEnv(env_);\n  IScriptEnvironment* env = static_cast<IScriptEnvironment*>(IEnv);\n\n  AVSValue clip = args[0];\n  if (!clip.IsClip())\n    env->ThrowError(\"propGetAsArray: No clip supplied!\");\n\n  PClip child = clip.AsClip();\n  VideoInfo vi = child->GetVideoInfo();\n\n  AVSValue cn = env->GetVarDef(\"current_frame\");\n  const bool calledFromRunTime = cn.IsInt();\n\n  const char* propName = args[1].AsString();\n  const int offset = args[2].AsInt(0);\n\n  int n = calledFromRunTime ? cn.AsInt() : 0;\n  n = min(max(n + offset, 0), vi.num_frames - 1);\n\n  PVideoFrame src = child->GetFrame(n, env);\n\n  const AVSMap* avsmap = env->getFramePropsRO(src);\n\n  int error = 0;\n\n  char propType = env->propGetType(avsmap, propName);\n  if (propType == 'u') {\n    // special: zero array\n    return AVSValue(nullptr, 0);\n  }\n  // check auto\n  int size = env->propNumElements(avsmap, propName);\n\n  std::vector<AVSValue> result(size);\n\n  // propGetIntArray or propGetFloatArray is available\n  // Pre interface V11: AVSValue is int and float, prop arrays are int64_t and double\n  if (propType == 'i') {\n    const int64_t* arr = env->propGetIntArray(avsmap, propName, &error);\n    for (int i = 0; i < size; ++i)\n      result[i] = arr[i]; // v11: no need for (int) cast\n  }\n  else if (propType == 'f') {\n    const double* arr = env->propGetFloatArray(avsmap, propName, &error);\n    for (int i = 0; i < size; ++i)\n      result[i] = arr[i]; // v11: no need for (float) cast\n  }\n  else\n  {\n    // generic\n    for (int i = 0; i < size; ++i) {\n      AVSValue elem;\n      switch (propType) {\n      case 'i': elem = AVSValue(env->propGetInt(avsmap, propName, i, &error)); break; // though handled earlier\n      case 'f': elem = AVSValue(env->propGetFloat(avsmap, propName, i, &error)); break; // though handled earlier\n      case 's': {\n        const char* s = env->propGetData(avsmap, propName, i, &error);\n        if (!error)\n          elem = AVSValue(env->SaveString(s));\n      }\n        break;\n      case 'v': elem = AVSValue(env->propGetFrame(avsmap, propName, i, &error)); break;\n      case 'c': elem = AVSValue(env->propGetClip(avsmap, propName, i, &error)); break;\n      default:\n        elem = AVSValue();\n      }\n      if (error)\n        break;\n      result[i] = elem;\n    }\n  }\n\n  const char* error_msg = nullptr;\n\n  // really, errors are bits\n  if (error & AVSGetPropErrors::GETPROPERROR_UNSET)\n    error_msg = \"property is not set\";\n  else if (error & AVSGetPropErrors::GETPROPERROR_TYPE)\n    error_msg = \"wrong type\";\n  else if (error & AVSGetPropErrors::GETPROPERROR_INDEX)\n    error_msg = \"index error\"; // arrays\n\n  if (error)\n    env->ThrowError(\"propGetAsArray: Error getting frame property \\\"%s\\\": %s \", propName, error_msg);\n\n  return AVSValue(result.data(), size); // array deep copy\n}\n\n// propGetAll\n// fills an AVSValue array with key-value pairs\n// array size will be numProps\n// each array element is a two dimensional array [key, value]\n// value can be an array as well, depending on the property\n// only int, float and string data extracted\nAVSValue GetAllProperties::Create(AVSValue args, void*, IScriptEnvironment* env_)\n{\n  InternalEnvironment* IEnv = GetAndRevealCamouflagedEnv(env_);\n  IScriptEnvironment* env = static_cast<IScriptEnvironment*>(IEnv);\n\n  AVSValue clip = args[0];\n  if (!clip.IsClip())\n    env->ThrowError(\"propGetAll: No clip supplied!\");\n\n  PClip child = clip.AsClip();\n  VideoInfo vi = child->GetVideoInfo();\n\n  AVSValue cn = env->GetVarDef(\"current_frame\");\n  const bool calledFromRunTime = cn.IsInt();\n\n  const int offset = args[1].AsInt(0);\n\n  int n = calledFromRunTime ? cn.AsInt() : 0;\n  n = min(max(n + offset, 0), vi.num_frames - 1);\n\n  PVideoFrame src = child->GetFrame(n, env);\n\n  const AVSMap* avsmap = env->getFramePropsRO(src);\n\n  const int propNum = env->propNumKeys(avsmap);\n\n  if (0 == propNum)\n    return AVSValue(nullptr, 0); // zero sized array\n\n  std::vector<AVSValue> result(propNum);\n\n  for (int index = 0; index < propNum; index++) {\n    std::vector<AVSValue> pair(2);\n    const char* propName = env->propGetKey(avsmap, index);\n    pair[0] = env->SaveString(propName);\n    const char propType = env->propGetType(avsmap, propName);\n    const int propNumElements = env->propNumElements(avsmap, propName);\n\n    int error;\n\n    AVSValue elem;\n    if (propType == 'u') {\n      // unSet: undefined value\n    }\n    else if (propType == 'i') {\n      if(propNumElements == 1)\n        elem = AVSValue(env->propGetInt(avsmap, propName, 0, &error)); // v11: no need for (int) cast\n      else {\n        std::vector<AVSValue> avsarr(propNumElements);\n        const int64_t* arr = env->propGetIntArray(avsmap, propName, &error);\n        for (int i = 0; i < propNumElements; ++i)\n          avsarr[i] = arr[i]; // v11: no need for (int) cast\n        elem = AVSValue(avsarr.data(), propNumElements); // array deep copy\n      }\n    }\n    else if (propType == 'f') {\n      if(propNumElements == 1)\n        elem = AVSValue(env->propGetFloat(avsmap, propName, 0, &error)); // since v11 no need for (float) cast\n      else {\n        std::vector<AVSValue> avsarr(propNumElements);\n        const double* arr = env->propGetFloatArray(avsmap, propName, &error);\n        for (int i = 0; i < propNumElements; ++i)\n          avsarr[i] = arr[i]; // v11: no need for (float) cast\n        elem = AVSValue(avsarr.data(), propNumElements); // array deep copy\n      }\n    }\n    else if (propType == 's') {\n      // no string arrays\n      const char* s = env->propGetData(avsmap, propName, 0, &error);\n      if (!error)\n        elem = AVSValue(env->SaveString(s));\n    }\n    else if (propType == 'c') {\n      if (propNumElements == 1)\n        elem = AVSValue(env->propGetClip(avsmap, propName, 0, &error));\n      else {\n        std::vector<AVSValue> avsarr(propNumElements);\n        for (int i = 0; i < propNumElements; ++i)\n          avsarr[i] = AVSValue(env->propGetClip(avsmap, propName, i, &error));\n        elem = AVSValue(avsarr.data(), propNumElements); // array deep copy\n      }\n    }\n    else {\n      // 'v': ignore no such AVSValue in Avisynth \n    }\n\n    pair[1] = elem;\n    result[index] = AVSValue(pair.data(), 2); // arrays in arrays, automatic deep copy\n  }\n\n  return AVSValue(result.data(), propNum); // array deep copy\n}\n\n// e.g. string length\nAVSValue GetPropertyDataSize::Create(AVSValue args, void* , IScriptEnvironment* env_) {\n  InternalEnvironment* IEnv = GetAndRevealCamouflagedEnv(env_);\n  IScriptEnvironment* env = static_cast<IScriptEnvironment*>(IEnv);\n\n  AVSValue clip = args[0];\n  if (!clip.IsClip())\n    env->ThrowError(\"propGetDataSize: No clip supplied!\");\n\n  PClip child = clip.AsClip();\n  VideoInfo vi = child->GetVideoInfo();\n\n  AVSValue cn = env->GetVarDef(\"current_frame\");\n  const bool calledFromRunTime = cn.IsInt();\n\n  const char* propName = args[1].AsString();\n  const int index = args[2].AsInt(0);\n  const int offset = args[3].AsInt(0);\n\n  int n = calledFromRunTime ? cn.AsInt() : 0;\n  n = min(max(n + offset, 0), vi.num_frames - 1);\n\n  PVideoFrame src = child->GetFrame(n, env);\n\n  const AVSMap* avsmap = env->getFramePropsRO(src);\n\n  int error = 0;\n\n  int size = env->propGetDataSize(avsmap, propName, index, &error);\n  if (!error)\n    return AVSValue(size);\n\n  const char* error_msg = nullptr;\n\n  // really, errors are bits\n  if (error & AVSGetPropErrors::GETPROPERROR_UNSET)\n    error_msg = \"property is not set\";\n  else if (error & AVSGetPropErrors::GETPROPERROR_TYPE)\n    error_msg = \"wrong type\";\n  else if (error & AVSGetPropErrors::GETPROPERROR_INDEX)\n    error_msg = \"index error\"; // arrays\n\n  if (error)\n    env->ThrowError(\"Error getting frame property data size \\\"%s\\\": %s \", propName, error_msg);\n\n  return AVSValue();\n}\n\n// array size of a given property, (by setProp append mode arrays can be constructed)\nAVSValue GetPropertyNumElements::Create(AVSValue args, void*, IScriptEnvironment* env_) {\n  InternalEnvironment* IEnv = GetAndRevealCamouflagedEnv(env_);\n  IScriptEnvironment* env = static_cast<IScriptEnvironment*>(IEnv);\n\n  AVSValue clip = args[0];\n  if (!clip.IsClip())\n    env->ThrowError(\"propNumElements: No clip supplied!\");\n\n  PClip child = clip.AsClip();\n  VideoInfo vi = child->GetVideoInfo();\n\n  AVSValue cn = env->GetVarDef(\"current_frame\");\n  const bool calledFromRunTime = cn.IsInt();\n\n  const char* propName = args[1].AsString();\n  const int offset = args[2].AsInt(0);\n\n  int n = calledFromRunTime ? cn.AsInt() : 0;\n  n = min(max(n + offset, 0), vi.num_frames - 1);\n\n  PVideoFrame src = child->GetFrame(n, env);\n\n  const AVSMap* avsmap = env->getFramePropsRO(src);\n\n  try {\n    int size = env->propNumElements(avsmap, propName);\n    return AVSValue(size);\n  }\n  catch (const AvisynthError& error) {\n    env->ThrowError(\"propNumElements: %s\", error.msg);\n  }\n\n  return AVSValue();\n}\n\n// returns integer enums instead of char (string)\nAVSValue GetPropertyType::Create(AVSValue args, void*, IScriptEnvironment* env_) {\n  InternalEnvironment* IEnv = GetAndRevealCamouflagedEnv(env_);\n  IScriptEnvironment* env = static_cast<IScriptEnvironment*>(IEnv);\n\n  AVSValue clip = args[0];\n  if (!clip.IsClip())\n    env->ThrowError(\"propGetType: No clip supplied!\");\n\n  PClip child = clip.AsClip();\n  VideoInfo vi = child->GetVideoInfo();\n\n  AVSValue cn = env->GetVarDef(\"current_frame\");\n  const bool calledFromRunTime = cn.IsInt();\n\n  const char* propName = args[1].AsString();\n  const int offset = args[2].AsInt(0);\n\n  int n = calledFromRunTime ? cn.AsInt() : 0;\n  n = min(max(n + offset, 0), vi.num_frames - 1);\n\n  PVideoFrame src = child->GetFrame(n, env);\n\n  const AVSMap* avsmap = env->getFramePropsRO(src);\n\n  try {\n    char prop_type = env->propGetType(avsmap, propName);\n    // 'u'nset, 'i'nteger, 'f'loat, 's'string, 'c'lip, 'v'ideoframe, 'm'ethod };\n    switch (prop_type) {\n    case 'u': return 0;\n    case 'i': return 1;\n    case 'f': return 2;\n    case 's': return 3;\n    case 'c': return 4;\n    case 'v': return 5;\n      //case 'm': return 6;\n    default:\n      return -1;\n    }\n  }\n  catch (const AvisynthError& error) {\n    env->ThrowError(\"propGetType: %s\", error.msg);\n  }\n\n  return AVSValue();\n}\n\n\n// Number of properties (keys) for a frame\nAVSValue GetPropertyNumKeys::Create(AVSValue args, void*, IScriptEnvironment* env_) {\n  InternalEnvironment* IEnv = GetAndRevealCamouflagedEnv(env_);\n  IScriptEnvironment* env = static_cast<IScriptEnvironment*>(IEnv);\n\n  AVSValue clip = args[0];\n  if (!clip.IsClip())\n    env->ThrowError(\"propNumKeys: No clip supplied!\");\n\n  PClip child = clip.AsClip();\n  VideoInfo vi = child->GetVideoInfo();\n\n  AVSValue cn = env->GetVarDef(\"current_frame\");\n  const bool calledFromRunTime = cn.IsInt();\n\n  int n = calledFromRunTime ? cn.AsInt() : 0;\n  int offset = args[1].AsInt(0);\n  n = min(max(n + offset, 0), vi.num_frames - 1);\n\n  PVideoFrame src = child->GetFrame(n, env);\n\n  const AVSMap* avsmap = env->getFramePropsRO(src);\n\n  try {\n    int size = env->propNumKeys(avsmap);\n    return AVSValue(size);\n  }\n  catch (const AvisynthError& error) {\n    env->ThrowError(\"propNumKeys: %s\", error.msg);\n  }\n\n  return AVSValue();\n}\n\n// Get the name (key) of the Nth frame property\nAVSValue GetPropertyKeyByIndex::Create(AVSValue args, void*, IScriptEnvironment* env_) {\n  InternalEnvironment* IEnv = GetAndRevealCamouflagedEnv(env_);\n  IScriptEnvironment* env = static_cast<IScriptEnvironment*>(IEnv);\n\n  AVSValue clip = args[0];\n  if (!clip.IsClip())\n    env->ThrowError(\"propNumKeys: No clip supplied!\");\n\n  PClip child = clip.AsClip();\n  VideoInfo vi = child->GetVideoInfo();\n\n  AVSValue cn = env->GetVarDef(\"current_frame\");\n  const bool calledFromRunTime = cn.IsInt();\n\n  const int index = args[1].AsInt(0);\n  const int offset = args[2].AsInt(0);\n\n  int n = calledFromRunTime ? cn.AsInt() : 0;\n  n = min(max(n + offset, 0), vi.num_frames - 1);\n\n  PVideoFrame src = child->GetFrame(n, env);\n\n  const AVSMap* avsmap = env->getFramePropsRO(src);\n\n  try {\n    const char* prop_name = env->propGetKey(avsmap, index);\n    return AVSValue(env->SaveString(prop_name));\n  }\n  catch (const AvisynthError& error) {\n    env->ThrowError(\"propGetKeyByIndex: %s\", error.msg);\n  }\n\n  return AVSValue();\n}\n"
  },
  {
    "path": "avs_core/filters/conditional/conditional_functions.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include <avisynth.h>\n\n\nclass AveragePlane {\n\npublic:\n  static AVSValue Create(AVSValue args, void* user_data, IScriptEnvironment* env);\n  static AVSValue AvgPlane(AVSValue clip, void* user_data, int plane, int offset, IScriptEnvironment* env);\n};\n\nclass ComparePlane {\n\npublic:\n  static AVSValue CmpPlane(AVSValue clip, AVSValue clip2, void* user_data, int plane, IScriptEnvironment* env);\n  static AVSValue CmpPlaneSame(AVSValue clip, void* user_data, int offset, int plane, IScriptEnvironment* env);\n\n  static AVSValue Create(AVSValue args, void* user_data, IScriptEnvironment* env);\n  static AVSValue Create_prev(AVSValue args, void* user_data, IScriptEnvironment* env);\n  static AVSValue Create_next(AVSValue args, void* user_data, IScriptEnvironment* env);\n};\n\n\nclass MinMaxPlane {\n\npublic:\n  static AVSValue MinMax(AVSValue clip, void* user_data, double threshold, int offset, int plane, int mode, bool setvar, IScriptEnvironment* env);\n\n  static AVSValue Create_max(AVSValue args, void* user_data, IScriptEnvironment* env);\n  static AVSValue Create_min(AVSValue args, void* user_data, IScriptEnvironment* env);\n  static AVSValue Create_median(AVSValue args, void* user_data, IScriptEnvironment* env);\n  static AVSValue Create_minmax(AVSValue args, void* user_data, IScriptEnvironment* env);\n  static AVSValue Create_minmax_stats(AVSValue args, void* user_data, IScriptEnvironment* env);\n\nprivate:\n  enum { MIN = 1, MAX = 2, MEDIAN = 3, MINMAX_DIFFERENCE = 4, STATS = 5 };\n\n};\n\n\nclass GetProperty {\npublic:\n  static AVSValue Create(AVSValue args, void* user_data, IScriptEnvironment* env);\n};\n\nclass GetPropertyAsArray {\npublic:\n  static AVSValue Create(AVSValue args, void* user_data, IScriptEnvironment* env);\n};\n\nclass GetAllProperties {\npublic:\n  static AVSValue Create(AVSValue args, void* user_data, IScriptEnvironment* env);\n};\n\nclass GetPropertyDataSize {\npublic:\n  static AVSValue Create(AVSValue args, void* , IScriptEnvironment* env);\n};\n\nclass GetPropertyType {\npublic:\n  static AVSValue Create(AVSValue args, void*, IScriptEnvironment* env);\n};\n\nclass GetPropertyNumElements {\npublic:\n  static AVSValue Create(AVSValue args, void* , IScriptEnvironment* env);\n};\n\nclass GetPropertyNumKeys {\npublic:\n  static AVSValue Create(AVSValue args, void*, IScriptEnvironment* env);\n};\n\nclass GetPropertyKeyByIndex {\npublic:\n  static AVSValue Create(AVSValue args, void*, IScriptEnvironment* env);\n};\n\n"
  },
  {
    "path": "avs_core/filters/conditional/conditional_reader.cpp",
    "content": "/*\n  ConditionalReader  (c) 2004 by Klaus Post\n\n  This program is free software; you can redistribute it and/or modify\n  it under the terms of the GNU General Public License as published by\n  the Free Software Foundation.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program; if not, write to the Free Software\n  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n  The author can be contacted at:\n  sh0dan[at]stofanet.dk\n*/\n\n#include \"conditional_reader.h\"\n#include \"../core/internal.h\"\n#include \"../core/parser/scriptparser.h\"\n#include <cstdlib>\n\n#ifdef AVS_WINDOWS\n    #include <avs/win.h>\n#else\n    #include <avs/posix.h>\n#endif\n\n#include <avs/minmax.h>\n#include \"../core/parser/scriptparser.h\"\n#include \"../core/AVSMap.h\"\n#include <iostream>\n#include <sstream>\n#include <iomanip>\n#include <string>\n#include <cstring>\n#include \"../convert/convert_helper.h\"\n#include <regex>\n\n\n/*****************************************************************************\n *  Helper code from XviD (http://www.xvid.org)\n *\n *  Copyright (C)      2002 Foxer <email?>\n *                     2002 Dirk Knop <dknop@gwdg.de>\n *                2002-2003 Edouard Gomez <ed.gomez@free.fr>\n *                     2003 Pete Ross <pross@xvid.org>\n *****************************************************************************/\n\n/* Default buffer size for reading lines */\n#define BUF_SZ   1024\n\n\n/* This function returns an allocated string containing a complete line read\n * from the file starting at the current position */\nstatic char *\nreadline(FILE *f)\n{\n  char *buffer = NULL;\n  int buffer_size = 0;\n  int pos = 0;\n\n  for (;;) {\n    int c;\n\n    /* Read a character from the stream */\n    c = fgetc(f);\n\n    /* Is that EOF or new line ? */\n    if(c == EOF || c == '\\n')\n      break;\n\n    /* Do we have to update buffer ? */\n    if(pos >= buffer_size - 1) {\n      buffer_size += BUF_SZ;\n      char *tmpbuffer = (char*)realloc(buffer, buffer_size);\n      if (tmpbuffer == NULL) {\n        free(buffer);\n        return(NULL);\n        }\n      buffer = tmpbuffer;\n    }\n\n    buffer[pos] = (char)c;\n    pos++;\n  }\n\n  /* Read \\n or EOF */\n  if (buffer == NULL) {\n    /* EOF, so we reached the end of the file, return NULL */\n    if(feof(f))\n      return(NULL);\n\n    /* Just an empty line with just a newline, allocate a 1 byte buffer to\n     * store a zero length string */\n    buffer = (char*)malloc(1);\n    if(buffer == NULL)\n      return(NULL);\n  }\n\n  /* Zero terminated string */\n  if (pos && buffer[pos-1] == '\\r')\n    buffer[pos-1] = '\\0';\n  else\n    buffer[pos] = '\\0';\n\n  return(buffer);\n}\n\n/* This function returns a pointer to the first non space char in the given\n * string or the end of the string */\n\nstatic char *\nskipspaces(char *string)\n{\n  if (string == NULL) return(NULL);\n\n  while (*string != '\\0') {\n    /* Test against space chars */\n    if (!isspace(*string)) return(string);\n    string++;\n  }\n  return(string);\n}\n\n/* This function returns a pointer to the first space char in the given\n * string or the end of the string */\n\nstatic char *\nfindspace(char *string)\n{\n  if (string == NULL) return(NULL);\n\n  while (*string != '\\0') {\n    /* Test against space chars */\n    if (isspace(*string)) return(string);\n    string++;\n  }\n  return(string);\n}\n\n/* This function returns a boolean that tells if the string is only a\n * comment */\nstatic int\niscomment(char *string)\n{\n  const char comments[] =\n    {\n      '#',';', '%', '\\0'\n    };\n  const char *cmtchar = comments;\n  int iscomment = 0;\n\n  if (string == NULL) return(1);\n\n  string = skipspaces(string);\n\n  while(*cmtchar != '\\0') {\n    if(*string == *cmtchar) {\n      iscomment = 1;\n      break;\n    }\n    cmtchar++;\n  }\n\n  return(iscomment);\n}\n\n\n// Reader ------------------------------------------------\n\n\nConditionalReader::ConditionalReader(PClip _child, const char* filename, const char _varname[],\n  bool _show, const char *_condVarSuffix, bool _local, IScriptEnvironment* env)\n : GenericVideoFilter(_child), show(_show), mode(MODE_UNKNOWN), offset(0), local(_local), stringcache(0)\n{\n  FILE * f;\n  char *line = 0;\n  int lines;\n\n  variableName = _varname; // std::string\n  if (_condVarSuffix[0])\n    variableName += _condVarSuffix; // append if parameter exists\n  variableNameFixed = env->SaveString(variableName.c_str());\n\n  if ((f = fopen(filename, \"rb\")) == NULL)\n    env->ThrowError(\"ConditionalReader: Could not open file '%s'.\", filename);\n\n  lines = 0;\n\n  try {\n    while ((line = readline(f)) != NULL) {\n      char *ptr;\n      int fields;\n\n      lines++;\n\n      /* We skip spaces */\n      ptr = skipspaces(line);\n\n      /* Skip coment lines or empty lines */\n      if(iscomment(ptr) || *ptr == '\\0') {\n        free(line);\n        line = 0;\n        continue;\n      }\n\n      if (mode == MODE_UNKNOWN) {\n        // We have not recieved a mode - We expect type.\n        char* keyword = ptr;\n\n        ptr = findspace(ptr);\n        if (*ptr) {\n          *ptr++ = '\\0';\n          if (!lstrcmpi(keyword, \"type\")) {\n            /* We skip spaces */\n            char* type = skipspaces(ptr);\n\n            ptr = findspace(type);\n            *ptr = '\\0';\n\n            if (!lstrcmpi(type, \"int\")) {\n              mode = MODE_INT;\n              intVal = new int[vi.num_frames];\n            } else if (!lstrcmpi(type, \"float\")) {\n              mode = MODE_FLOAT;\n              floatVal = new float[vi.num_frames];\n            } else if (!lstrcmpi(type, \"bool\")) {\n              mode = MODE_BOOL;\n              boolVal = new bool[vi.num_frames];\n            } else if (!lstrcmpi(type, \"string\")) {\n              mode = MODE_STRING;\n              stringVal = new const char*[vi.num_frames];\n            } else {\n              ThrowLine(\"ConditionalReader: Unknown 'Type' specified in line %d\", lines, env);\n            }// end if compare type\n            SetRange(0, vi.num_frames-1, AVSValue());\n          }// end if compare keyword\n        }// end if fields\n\n      } else { // We have a defined mode and allocated the values.\n\n        char* keyword = ptr;\n        char* type = findspace(keyword);\n\n        if (*type) *type++ = '\\0';\n\n        if (!lstrcmpi(keyword, \"default\")) {\n          AVSValue def = ConvertType(type, lines, env);\n          SetRange(0, vi.num_frames-1, def);\n\n        } else if (!lstrcmpi(keyword, \"offset\")) {\n          fields = sscanf(type, \"%d\", &offset);\n          if (fields != 1)\n            ThrowLine(\"ConditionalReader: Could not read Offset in line %d\", lines, env);\n\n        } else if (keyword[0] == 'R' || keyword[0] == 'r') {  // Range\n          int start;\n          int stop;\n\n          type = skipspaces(type);\n          fields = sscanf(type, \"%d\", &start);\n\n          type = findspace(type);\n          type = skipspaces(type);\n          fields += sscanf(type, \"%d\", &stop);\n\n          type = findspace(type);\n          if (!*type || fields != 2)\n            ThrowLine(\"ConditionalReader: Could not read Range in line %d\", lines, env);\n\n          if (start > stop)\n            ThrowLine(\"ConditionalReader: The Range start frame is after the end frame in line %d\", lines, env);\n\n          AVSValue set = ConvertType(type+1, lines, env);\n          SetRange(start, stop, set);\n\n        } else if (keyword[0] == 'I' || keyword[0] == 'i') {  // Interpolate\n          if (mode == MODE_BOOL)\n            ThrowLine(\"ConditionalReader: Cannot Interpolate booleans in line %d\", lines, env);\n\n          if (mode == MODE_STRING)\n            ThrowLine(\"ConditionalReader: Cannot Interpolate strings in line %d\", lines, env);\n\n          type = skipspaces(type);\n          int start;\n          int stop;\n          char start_value[64];\n          char stop_value[64];\n          fields = sscanf(type, \"%d %d %63s %63s\", &start, &stop, start_value, stop_value);\n\n          if (fields != 4)\n            ThrowLine(\"ConditionalReader: Could not read Interpolation range in line %d\", lines, env);\n          if (start > stop)\n            ThrowLine(\"ConditionalReader: The Interpolation start frame is after the end frame in line %d\", lines, env);\n\n          start_value[63] = '\\0';\n          AVSValue set_start = ConvertType(start_value, lines, env);\n\n          stop_value[63] = '\\0';\n          AVSValue set_stop = ConvertType(stop_value, lines, env);\n\n          const int range = stop-start;\n          const double diff = (set_stop.AsFloat() - set_start.AsFloat()) / range;\n          for (int i = 0; i<=range; i++) {\n            const double n = i * diff + set_start.AsFloat();\n            SetFrame(i+start, (mode == MODE_FLOAT)\n                    ? AVSValue(n)\n                    : AVSValue((int)(n+0.5)));\n          }\n        } else {\n          int cframe;\n          fields = sscanf(keyword, \"%d\", &cframe);\n          if ((*type || mode == MODE_STRING) && fields == 1) { // allow empty string\n            AVSValue set = ConvertType(type, lines, env);\n            SetFrame(cframe, set);\n          } else {\n            ThrowLine(\"ConditionalReader: Do not understand line %d\", lines, env);\n          }\n        }\n\n      } // End we have defined type\n      free(line);\n      line = 0;\n    }// end while still some file left to read.\n  }\n  catch (...) {\n    free(line);\n    fclose(f);\n    CleanUp();\n    throw;\n  }\n\n  /* We are done with the file */\n  fclose(f);\n\n  if (mode == MODE_UNKNOWN)\n    env->ThrowError(\"ConditionalReader: Type was not defined!\");\n\n}\n\n\n\n// Converts from the char array given to the type specified.\n\nAVSValue ConditionalReader::ConvertType(const char* content, int line, IScriptEnvironment* env)\n{\n  if (mode == MODE_UNKNOWN)\n    ThrowLine(\"ConditionalReader: Type has not been defined. Line %d\", line, env);\n\n  int fields;\n  switch (mode) {\n    case MODE_INT:\n      int ival;\n      fields = sscanf(content, \"%d\", &ival);\n      if (fields != 1)\n        ThrowLine(\"ConditionalReader: Could not find an expected integer at line %d!\", line, env);\n\n      return AVSValue(ival);\n\n    case MODE_FLOAT:\n      float fval;\n      fields = sscanf(content, \"%e\", &fval);\n      if (fields != 1)\n        ThrowLine(\"ConditionalReader: Could not find an expected float at line %d!\", line, env);\n\n      return AVSValue(fval);\n\n    case MODE_BOOL:\n      char bval[8];\n      bval[0] = '\\0';\n      fields = sscanf(content, \"%7s\", bval);\n      bval[7] = '\\0';\n      if (!lstrcmpi(bval, \"true\")) {\n        return AVSValue(true);\n      }\n      else if (!lstrcmpi(bval, \"t\")) {\n        return AVSValue(true);\n      }\n      else if (!lstrcmpi(bval, \"yes\")) {\n        return AVSValue(true);\n      }\n      else if (!lstrcmp(bval, \"1\")) {\n        return AVSValue(true);\n      }\n      else if (!lstrcmpi(bval, \"false\")) {\n        return AVSValue(false);\n      }\n      else if (!lstrcmpi(bval, \"f\")) {\n        return AVSValue(false);\n      }\n      else if (!lstrcmpi(bval, \"no\")) {\n        return AVSValue(false);\n      }\n      else if (!lstrcmp(bval, \"0\")) {\n        return AVSValue(false);\n      }\n      ThrowLine(\"ConditionalReader: Boolean value was not true or false in line %d\", line, env);\n\n    case MODE_STRING:\n      StringCache *str;\n\n      // Look for an existing duplicate\n      for (str = stringcache; str; str = str->next ) {\n        if (!lstrcmp(str->string, content)) break;\n      }\n      // Could not find one, add it\n      if (!str) {\n        str = new StringCache;\n        str->string = _strdup(content);\n        str->next   = stringcache;\n        stringcache = str;\n      }\n      return AVSValue(str->string);\n  }\n  return AVSValue();\n}\n\n\n// Sets range with both start and stopframe inclusive.\n\nvoid ConditionalReader::SetRange(int start_frame, int stop_frame, AVSValue v) {\n  int i;\n  start_frame = max(start_frame+offset, 0);\n  stop_frame = min(stop_frame+offset, vi.num_frames-1);\n  int p;\n  float q;\n  bool r;\n  const char* s;\n\n  switch (mode) {\n    case MODE_INT:\n      p = v.Defined() ? v.AsInt() : 0;\n      for (i = start_frame; i <= stop_frame; i++) {\n        intVal[i] = p;\n      }\n      break;\n    case MODE_FLOAT:\n      q = v.Defined() ? v.AsFloatf() : 0.0f;\n      for (i = start_frame; i <= stop_frame; i++) {\n        floatVal[i] = q;\n      }\n      break;\n    case MODE_BOOL:\n      r = v.Defined() ? v.AsBool() : false;\n      for (i = start_frame; i <= stop_frame; i++) {\n        boolVal[i] = r;\n      }\n      break;\n    case MODE_STRING:\n      s = v.AsString(\"\");\n      for (i = start_frame; i <= stop_frame; i++) {\n        stringVal[i] = s;\n      }\n      break;\n  }\n}\n\n// Sets the value of one frame.\n\nvoid ConditionalReader::SetFrame(int framenumber, AVSValue v) {\n\n  if ((framenumber+offset) < 0 || (framenumber+offset) > vi.num_frames-1 )\n    return;\n\n  switch (mode) {\n    case MODE_INT:\n      intVal[framenumber+offset] = v.AsInt();\n      break;\n    case MODE_FLOAT:\n      floatVal[framenumber+offset] = v.AsFloatf();\n      break;\n    case MODE_BOOL:\n      boolVal[framenumber+offset] = v.AsBool();\n      break;\n    case MODE_STRING:\n      stringVal[framenumber+offset] = v.AsString(\"\");\n      break;\n  }\n}\n\n// Get the value of a frame.\nAVSValue ConditionalReader::GetFrameValue(int framenumber) {\n  framenumber = clamp(framenumber, 0, vi.num_frames-1);\n\n  switch (mode) {\n    case MODE_INT:\n      return AVSValue(intVal[framenumber]);\n\n    case MODE_FLOAT:\n      return AVSValue(floatVal[framenumber]);\n\n    case MODE_BOOL:\n      return AVSValue(boolVal[framenumber]);\n\n    case MODE_STRING:\n      return AVSValue(stringVal[framenumber]);\n\n  }\n  return AVSValue(0);\n}\n\n// Destructor\nConditionalReader::~ConditionalReader(void)\n{\n  CleanUp();\n}\n\n\nvoid ConditionalReader::CleanUp(void)\n{\n  switch (mode) {\n    case MODE_INT:\n      delete[] intVal;\n      break;\n    case MODE_FLOAT:\n      delete[] floatVal;\n      break;\n    case MODE_BOOL:\n      delete[] boolVal;\n      break;\n    case MODE_STRING:\n      delete[] stringVal;\n\n      //free the cached strings\n      for (StringCache* str = stringcache; str; ) {\n        StringCache* curr = str;\n        free(str->string);\n        str = str->next;\n        delete curr;\n      }\n      stringcache = 0;\n\n      break;\n  }\n  mode = MODE_UNKNOWN;\n}\n\n\nvoid ConditionalReader::ThrowLine(const char* err, int line, IScriptEnvironment* env) {\n  env->ThrowError(err, line);\n}\n\n\nPVideoFrame __stdcall ConditionalReader::GetFrame(int n, IScriptEnvironment* env_)\n{\n  AVSValue v = GetFrameValue(n);\n\n  InternalEnvironment* IEnv = GetAndRevealCamouflagedEnv(env_);\n  IScriptEnvironment* env = static_cast<IScriptEnvironment*>(IEnv);\n\n  std::unique_ptr<GlobalVarFrame> var_frame;\n\n  AVSValue child_val = child;\n\n  if (!local) {\n    env->SetGlobalVar(variableNameFixed, v);\n  }\n  else {\n    // Neo's default, correct but incompatible with previous Avisynth versions\n    var_frame = std::unique_ptr<GlobalVarFrame>(new GlobalVarFrame(IEnv)); // allocate new frame\n    env->SetGlobalVar(variableNameFixed, v);\n  }\n\n\n  PVideoFrame src = child->GetFrame(n,env);\n\n  if (show) {\n    AVSValue v2 = env->Invoke(\"String\", v);\n    env->MakeWritable(&src);\n    env->ApplyMessage(&src, vi, v2.AsString(\"\"), vi.width/2, 0xa0a0a0, 0, 0);\n  }\n  return src;\n}\n\nint __stdcall ConditionalReader::SetCacheHints(int cachehints, int frame_range)\n{\n  switch (cachehints)\n  {\n  case CACHE_GET_MTMODE:\n    return MT_NICE_FILTER;\n  case CACHE_GET_DEV_TYPE:\n    return (child->GetVersion() >= 5) ? child->SetCacheHints(CACHE_GET_DEV_TYPE, 0) : 0;\n  }\n  return 0;  // We do not pass cache requests upwards.\n}\n\n\n\nAVSValue __cdecl ConditionalReader::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  const bool runtime_local_default = false; // Avisynth compatibility: false, Neo: true.\n\n  return new ConditionalReader(args[0].AsClip(), args[1].AsString(\"\"), args[2].AsString(\"Conditional\") , args[3].AsBool(false), args[4].AsString(\"\"), args[5].AsBool(runtime_local_default), env);\n}\n\n\n// Write ------------------------------------------------\n\n\nstatic const char EMPTY[]  = \"\";\nstatic const char AplusT[] = \"a+t\";\nstatic const char WplusT[] = \"w+t\";\n\n\nWrite::Write(PClip _child, const char* _filename, AVSValue args, int _linecheck, bool _append, bool _flush, bool _local, IScriptEnvironment* env_) :\n  GenericVideoFilter(_child), linecheck(_linecheck), flush(_flush), append(_append), local(_local), arglist(0)\n{\n  InternalEnvironment* IEnv = GetAndRevealCamouflagedEnv(env_);\n  IScriptEnvironment* env = static_cast<IScriptEnvironment*>(IEnv);\n\n#ifdef AVS_WINDOWS\n  _fullpath(filename, _filename, _MAX_PATH);\n#else\n  // Use realpath and handle possible failure to avoid unused-result warning.\n  if (realpath(_filename, filename) == NULL) {\n    // Fallback: copy original input path into filename safely.\n    size_t len = strlen(_filename);\n    if (len >= sizeof(filename)) len = sizeof(filename) - 1;\n    memcpy(filename, _filename, len);\n    filename[len] = '\\0';\n  }\n#endif\n\n  fout = fopen(filename, append ? AplusT : WplusT); //append or purge file\n  if (!fout) env->ThrowError(\"Write: File '%s' cannot be opened.\", filename);\n\n  if (flush) fclose(fout);\t//will be reopened in FileOut\n\n  arrsize = args.ArraySize();\n\n  arglist = new exp_res[arrsize];\n\n  for (int i = 0; i < arrsize; i++) {\n    arglist[i].expression = args[i];\n    arglist[i].string = EMPTY;\n  }\n\n  if (linecheck != -1 && linecheck != -2)\n    return;\n\n  AVSValue prev_last;\n  AVSValue prev_current_frame;\n  std::unique_ptr<GlobalVarFrame> var_frame;\n\n  AVSValue child_val = child;\n\n  if (!local) {\n    prev_last = env->GetVarDef(\"last\");  // Store previous last\n    prev_current_frame = env->GetVarDef(\"current_frame\");  // Store previous current_frame\n    env->SetVar(\"last\", child_val);       // Set implicit last\n    env->SetVar(\"current_frame\", (AVSValue)linecheck);  // special -1 or -2\n  }\n  else {\n    // Neo's default, correct but incompatible with previous Avisynth versions\n    var_frame = std::unique_ptr<GlobalVarFrame>(new GlobalVarFrame(IEnv)); // allocate new frame\n    env->SetGlobalVar(\"last\", child_val);       // Set explicit last\n    env->SetGlobalVar(\"current_frame\", (AVSValue)linecheck);  // special -1 or -2\n  }\n\n  Write::DoEval(env); // at both write at start and write at end\n\n  if (linecheck == -1) { //write at start\n    Write::FileOut(env, AplusT);\n  }\n\n  if (!local) {\n    env->SetVar(\"last\", prev_last);       // Restore implicit last\n    env->SetVar(\"current_frame\", prev_current_frame);       // Restore current_frame\n  }\n}\n\nPVideoFrame __stdcall Write::GetFrame(int n, IScriptEnvironment* env_) {\n\n  //changed to call write AFTER the child->GetFrame\n\n  InternalEnvironment* IEnv = GetAndRevealCamouflagedEnv(env_);\n  IScriptEnvironment* env = static_cast<IScriptEnvironment*>(IEnv);\n\n  PVideoFrame tmpframe = child->GetFrame(n, env);\n\n  if (linecheck < 0) return tmpframe;\t//do nothing here when writing only start or end\n\n  AVSValue prev_last;\n  AVSValue prev_current_frame;\n  std::unique_ptr<GlobalVarFrame> var_frame;\n\n  AVSValue child_val = child;\n\n  if (!local) {\n    prev_last = env->GetVarDef(\"last\");  // Store previous last\n    prev_current_frame = env->GetVarDef(\"current_frame\");  // Store previous current_frame\n    env->SetVar(\"last\", (AVSValue)child_val);       // Set implicit last\n    env->SetVar(\"current_frame\", (AVSValue)n);  // Set frame to be tested by the conditional filters.\n  }\n  else {\n    // Neo's default, correct but incompatible with previous Avisynth versions\n    var_frame = std::unique_ptr<GlobalVarFrame>(new GlobalVarFrame(IEnv)); // allocate new frame\n    env->SetGlobalVar(\"last\", child_val);       // Set implicit last (to avoid recursive stack calls?)\n    env->SetGlobalVar(\"current_frame\", (AVSValue)n);  // Set frame to be tested by the conditional filters.\n  }\n\n  if (Write::DoEval(env)) {\n    Write::FileOut(env, AplusT);\n  }\n\n  if (!local) {\n    env->SetVar(\"last\", prev_last);       // Restore implicit last\n    env->SetVar(\"current_frame\", prev_current_frame);       // Restore current_frame\n  }\n\n  return tmpframe;\n\n};\n\nWrite::~Write(void) {\n  if (linecheck == -2) {\t//write at end\n    Write::FileOut(0, append ? AplusT : WplusT); // Allow for retruncating at actual end\n  }\n  if (!flush) fclose(fout);\n\n  delete[] arglist;\n};\n\nvoid Write::FileOut(IScriptEnvironment* env, const char* mode) {\n  int i;\n  if (flush) {\n    fout = fopen(filename, mode);\n    if (!fout) {\n      if (env) env->ThrowError(\"Write: File '%s' cannot be opened.\", filename);\n      return;\n    }\n  }\n  for (i= ( (linecheck==1) ? 1 : 0) ; i<arrsize; i++ ) {\n    fputs(arglist[i].string, fout);\n  }\n  fputs(\"\\n\", fout);\n  if (flush) {\n    fclose(fout);\n  }\n}\n\nbool Write::DoEval( IScriptEnvironment* env) {\n  bool keep_this_line = true;\n  int i;\n  AVSValue expr;\n  AVSValue result;\n\n  for (i=0; i<arrsize; i++) {\n    expr = arglist[i].expression;\n\n    if ( (linecheck==1) && (i==0)) {\n      try {\n        if (expr.IsFunction()) {\n          result = env->Invoke3(child, expr.AsFunction(), AVSValue(nullptr, 0));\n        }\n        else {\n          expr = expr.AsString(EMPTY);\n          result = env->Invoke(\"Eval\", expr);\n        }\n        if (!result.AsBool(true)) {\n          keep_this_line = false;\n          break;\n        }\n      } catch (const AvisynthError&) {\n//\t\t\t\tenv->ThrowError(\"Write: Can't eval linecheck expression!\"); // results in KEEPING the line\n      }\n    } else {\n      try {\n        if (expr.IsFunction()) {\n          result = env->Invoke3(child, expr.AsFunction(), AVSValue(nullptr, 0));\n        }\n        else {\n          expr = expr.AsString(EMPTY);\n          result = env->Invoke(\"Eval\", expr);\n        }\n        result = env->Invoke(\"string\",result);\t//convert all results to a string\n        arglist[i].string = result.AsString(EMPTY);\n      } catch (const AvisynthError &error) {\n        arglist[i].string = env->SaveString(error.msg);\n      }\n    }\n  }\n  return keep_this_line;\n}\n\nint __stdcall Write::SetCacheHints(int cachehints, int frame_range)\n{\n  switch (cachehints)\n  {\n  case CACHE_GET_MTMODE:\n    return MT_SERIALIZED;\n  }\n  return 0;  // We do not pass cache requests upwards.\n}\n\nAVSValue __cdecl Write::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  bool runtime_local_default = false;\n  // Param 2: string/function or array of strings/functions\n  if (args[2].IsFunction() || (args[2].IsArray() && args[2].ArraySize() > 0 && args[2][0].IsFunction()))\n    runtime_local_default = true;\n  // Avisynth compatibility: false, Neo: true. functions are legacy Neo\n\n  return new Write(args[0].AsClip(), args[1].AsString(EMPTY), args[2], 0, args[3].AsBool(true),args[4].AsBool(true), args[5].AsBool(runtime_local_default), env);\n}\n\nAVSValue __cdecl Write::Create_If(AVSValue args, void*, IScriptEnvironment* env)\n{\n  bool runtime_local_default = false;\n  // Param 2: string/function or array of strings/functions\n  if (args[2].IsFunction() || (args[2].IsArray() && args[2].ArraySize() > 0 && args[2][0].IsFunction()))\n    runtime_local_default = true;\n  // Avisynth compatibility: false, Neo: true. functions are legacy Neo\n\n  return new Write(args[0].AsClip(), args[1].AsString(EMPTY), args[2], 1, args[3].AsBool(true),args[4].AsBool(true), args[5].AsBool(runtime_local_default), env);\n}\n\nAVSValue __cdecl Write::Create_Start(AVSValue args, void*, IScriptEnvironment* env)\n{\n  bool runtime_local_default = false;\n  // Param 2: string/function or array of strings/functions\n  /*if (args[2].IsFunction() || (args[2].IsArray() && args[2].ArraySize() > 0 && args[2][0].IsFunction()))\n    runtime_local_default = true;\n  */\n  // Avisynth compatibility: false, Neo: also false as of 2020.03.28\n\n  return new Write(args[0].AsClip(), args[1].AsString(EMPTY), args[2], -1, args[3].AsBool(false), true, args[4].AsBool(runtime_local_default), env);\n}\n\nAVSValue __cdecl Write::Create_End(AVSValue args, void*, IScriptEnvironment* env)\n{\n  bool runtime_local_default = false;\n  // Param 2: string/function or array of strings/functions\n  /*\n  if (args[2].IsFunction() || (args[2].IsArray() && args[2].ArraySize() > 0 && args[2][0].IsFunction()))\n    runtime_local_default = true;\n  */\n  // Avisynth compatibility: false, Neo: also false as of 2020.03.28\n\n  return new Write(args[0].AsClip(), args[1].AsString(EMPTY), args[2], -2, args[3].AsBool(true), args[4].AsBool(runtime_local_default), true, env);\n}\n\n\nUseVar::UseVar(PClip _child, AVSValue vars, IScriptEnvironment* env)\n   : GenericVideoFilter(_child)\n{\n   vars_.resize(vars.ArraySize());\n   for (int i = 0; i < vars.ArraySize(); ++i) {\n      auto name = vars_[i].name = vars[i].AsString();\n      if (!env->GetVarTry(name, &vars_[i].val)) {\n        env->ThrowError(\"UseVar: No variable named %s\", name);\n      }\n   }\n}\n\nUseVar::~UseVar() { }\n\nPVideoFrame __stdcall UseVar::GetFrame(int n, IScriptEnvironment* env_)\n{\n  InternalEnvironment* IEnv = GetAndRevealCamouflagedEnv(env_);\n  IScriptEnvironment* env = static_cast<IScriptEnvironment*>(IEnv);\n\n  GlobalVarFrame var_frame(IEnv); // allocate new frame\n\n   // set variables\n   for (int i = 0; i < (int)vars_.size(); ++i) {\n      env->SetGlobalVar(vars_[i].name, vars_[i].val);\n   }\n\n   return child->GetFrame(n, env);\n}\n\nint __stdcall UseVar::SetCacheHints(int cachehints, int frame_range) {\n  switch (cachehints)\n  {\n  case CACHE_GET_MTMODE:\n    return MT_NICE_FILTER;\n  case CACHE_GET_DEV_TYPE:\n    return (child->GetVersion() >= 5) ? child->SetCacheHints(CACHE_GET_DEV_TYPE, 0) : 0;\n  }\n  return 0;  // We do not pass cache requests upwards.\n}\n\nAVSValue __cdecl UseVar::Create(AVSValue args, void* user_data, IScriptEnvironment* env)\n{\n   return new UseVar(args[0].AsClip(), args[1], env);\n}\n\n#define W_DIVISOR 5  // Width divisor for onscreen messages\n\n\n// Avisynth+ frame property support\n//**************************************************\n// propSet, propSetInt, propSetFloat, propSetString\n\nSetProperty::SetProperty(PClip _child, const char* name, const AVSValue& value, const int kind,\n  const int mode, IScriptEnvironment* env)\n  : GenericVideoFilter(_child)\n  , name(name)\n  , value(value)\n  , kind(kind)\n  , append_mode(mode)\n{ }\n\nSetProperty::~SetProperty() { }\n\nPVideoFrame __stdcall SetProperty::GetFrame(int n, IScriptEnvironment* env)\n{\n  // parameter type to set, comes different for each script function version\n  int propType = kind;\n\n  // 0: auto by result type\n  // 1: integer from function\n  // 2: float from function\n  // 3: char (null terminated data) from function\n  // 4: array from function (all elements have the same type)\n  // 5: clip from function\n  // 10: integer from direct\n  // 11: float from direct\n  // 12: string from direct\n  // 13: array from direct (all elements have the same type)\n  // 14: clip from direct\n\n  AVSValue result;\n  const char* error_msg = nullptr;\n  if (value.IsFunction()) {\n    PFunction func = value.AsFunction();\n    try {\n      const AVSValue empty_args_array = AVSValue(nullptr, 0); // invoke's parameter is const AVSValue&, don't do it inline.\n      result = env->Invoke3(child, func, empty_args_array);\n    }\n    catch (IScriptEnvironment::NotFound) {\n      error_msg = env->Sprintf(\"AddProperties: Invalid function parameter type '%s'(%s)\\n\"\n        \"Function should have no argument\",\n        func->GetDefinition()->param_types, func->ToString(env));\n    }\n    catch (const AvisynthError& error) {\n      error_msg = env->Sprintf(\"%s\\nAddProperties: Error in %s\",\n        error.msg, func->ToString(env));\n    }\n  }\n  else {\n    // direct input\n    result = value;\n    propType = 0; // autodetect type\n  }\n\n  PVideoFrame frame = child->GetFrame(n, env);\n\n  if (error_msg) {\n    env->MakeWritable(&frame);\n    env->ApplyMessage(&frame, vi, error_msg, vi.width / W_DIVISOR, 0xa0a0a0, 0, 0);\n    return frame;\n  }\n\n/*\n  usage:\n   propSet(\"hello\",1)\n   ScriptClip(\"\"\"propSetInt(\"frameluma\",func(AverageLuma))\"\"\")\n   ScriptClip(\"\"\"propSet(\"frameluma2\",AverageLuma)\"\"\")\n   ScriptClip(\"\"\"SubTitle(string(propGetInt(\"frameluma\")))\"\"\")\n  or\n   ps = func(propSetterFunc) # make function object from function\n   ScriptClip(ps) # pass function object to scriptclip\n   ScriptClip(function[](clip c) { SubTitle(string(propGetInt(\"frameprop_demo\")), y=20) })\n   ScriptClip(function[](clip c) { SubTitle(string(propGetInt(\"frameprop_demo2\")), y=40) })\n   function propSetterFunc(Clip x) {\n    x\n    propSetInt(\"frameprop_demo\", func(AverageLuma))\n    propSetInt(\"frameprop_demo2\", function[]() { current_frame })\n  }\n*/\n\n  try {\n    // check auto\n    if (propType == 0) {\n      // 'u'nset, 'i'nteger, 'f'loat, 's'string, 'c'lip, 'v'ideoframe, 'm'ethod };\n      if (result.IsInt())\n        propType = 1;\n      else if (result.IsFloat())\n        propType = 2;\n      else if (result.IsString())\n        propType = 3;\n      else if (result.IsArray())\n        propType = 4;\n      else if (result.IsClip())\n        propType = 5;\n      else\n        env->ThrowError(\"Invalid return type (Was a %s)\", GetAVSTypeName(result));\n    }\n\n    // env->MakeWritable(&frame);\n    // do we need this? Yes! better: MakePropertyWritable since V9 interface\n\n    // Check setting a constant value to the same as it was before (int, float, string case)\n    // We'd avoid even MakePropertyWritable and return a fully unaltered frame\n    do {\n      if (append_mode != AVSPropAppendMode::PROPAPPENDMODE_REPLACE) break; // only optimize replace\n      if (propType != 1 && propType != 2 && propType != 3) break; // only optimize traditional types\n\n      const AVSMap* avsmap_r = env->getFramePropsRO(frame);\n      auto size = env->propNumElements(avsmap_r, name); // 1 if single item, >1 size of array, 0 if not exists\n      if(size != 1) break; // no such property or property is an array\n\n      char x = env->propGetType(avsmap_r, name);\n      if (propType == 1 && x != 'i') break; // int does not match\n      if (propType == 2 && x != 'f') break; // float does not match\n      if (propType == 3 && x != 's') break; // string does not match\n      \n      if (propType == 1) {\n        if (!result.IsInt()) break; // IsInt checks for Long as well\n        auto val = env->propGetInt(avsmap_r, name, 0, nullptr);\n        if (val == result.AsLong()) return frame; // value match -> return unaltered\n        // v11: AsLong instead of AsInt\n      } \n      else if (propType == 2) {\n        if (!result.IsFloat()) break;\n        auto val = env->propGetFloat(avsmap_r, name, 0, nullptr);\n        if (val == result.AsFloat()) return frame; // value match -> return unaltered\n        // memo: AsFloat returns double\n      }\n      else if (propType == 3) {\n        if (!result.IsString()) break;\n        const char* val_to_set = result.AsString();\n        if (val_to_set == nullptr) break;\n        auto length_to_set = strlen(val_to_set);\n        auto length = env->propGetDataSize(avsmap_r, name, 0, nullptr);\n        if (length != length_to_set) break; // different size\n        const char* val_storage = env->propGetData(avsmap_r, name, 0, nullptr);\n        if(std::memcmp(val_to_set, val_storage, length) == 0) return frame; // value match -> return unaltered\n      }\n      break;\n    } while (0);\n\n    env->MakePropertyWritable(&frame);\n    AVSMap* avsmap = env->getFramePropsRW(frame);\n\n    int res = 0;\n\n    // special case: zero sized array -> entry deleted\n    if (result.IsArray() && result.ArraySize() == 0)\n      res = env->propDeleteKey(avsmap, name); // 0 is success\n    else if (propType == 1 && result.IsInt()) // IsInt checks for Long as well\n      res = env->propSetInt(avsmap, name, result.AsLong(), append_mode); // v11: AsLong instead of AsInt\n    else if (propType == 2 && result.IsFloat())\n      res = env->propSetFloat(avsmap, name, result.AsFloat(), append_mode);\n    else if (propType == 3 && result.IsString())\n    {\n      const char* s = result.AsString(); // no need for SaveString, it has its own storage\n      // assume string: AVSPropDataTypeHint::DATATYPEHINT_UTF8\n      res = env->propSetDataH(avsmap, name, s, -1, AVSPropDataTypeHint::PROPDATATYPEHINT_UTF8, append_mode); // -1: auto string length\n      // test res = env->propSetDataH(avsmap, name, s, -1, AVSPropDataTypeHint::DATATYPEHINT_BINARY, append_mode);\n    }\n    else if (propType == 4 && result[0].IsInt())\n    {\n      int size = result.ArraySize();\n      std::vector<int64_t> int64array(size); // avs can do int only, temporary array needed\n      for (int i = 0; i < size; i++) {\n        if (!result[i].IsInt()) // IsInt checks for Long as well\n          env->ThrowError(\"Wrong data type in property '%s': all array elements should be the same (integer) type\", name);\n        int64array[i] = result[i].AsLong(); // all elements should be int\n      }\n      res = env->propSetIntArray(avsmap, name, int64array.data(), size);\n    }\n    else if (propType == 4 && result[0].IsFloat())\n    {\n      int size = result.ArraySize();\n      std::vector<double> d_array(size); // avs can do float only, temporary array needed\n      for (int i = 0; i < size; i++) {\n        if (!result[i].IsFloat())\n          env->ThrowError(\"Wrong data type in property '%s': all array elements should be the same (float) type\", name);\n        d_array[i] = result[i].AsFloat(); // all elements should be float/double or int/long\n      }\n      res = env->propSetFloatArray(avsmap, name, d_array.data(), size);\n    }\n    else if (propType == 4 && result[0].IsString())\n    {\n      const int size = result.ArraySize();\n      // no such api like propSetDataArray\n      env->propDeleteKey(avsmap, name);\n      for (int i = 0; i < size; i++) {\n        if (!result[i].IsString())\n          env->ThrowError(\"Wrong data type in property '%s': all array elements should be the same (string) type\", name);\n        // assume string: AVSPropDataTypeHint::DATATYPEHINT_UTF8\n        res = env->propSetDataH(avsmap, name, result[i].AsString(), -1, AVSPropDataTypeHint::PROPDATATYPEHINT_UTF8, AVSPropAppendMode::PROPAPPENDMODE_APPEND); // all elements should be string\n        if (res)\n          break;\n      }\n    }\n    else if (propType == 4 && result[0].IsClip())\n    {\n      int size = result.ArraySize();\n      // no such api like propSetClipArray\n      env->propDeleteKey(avsmap, name);\n      for (int i = 0; i < size; i++) {\n        if (!result[i].IsClip())\n          env->ThrowError(\"Wrong data type in property '%s': all array elements should be the same (Clip) type\", name);\n        PClip clip = result[i].AsClip();\n        res = env->propSetClip(avsmap, name, clip, AVSPropAppendMode::PROPAPPENDMODE_APPEND); // all elements should be Clip\n        if (res)\n          break;\n      }\n    }\n    else if (propType == 5 && result.IsClip()) {\n      PClip clp = result.AsClip();\n      res = env->propSetClip(avsmap, name, clp, append_mode);\n    }\n    else\n    {\n      env->ThrowError(\"Wrong data type, property '%s' type is not %s\", name, GetAVSTypeName(result));\n    }\n\n    if (res)\n      env->ThrowError(\"error setting property '%s', error = %d\", name, res); // fixme: res reasons\n  }\n  catch (const AvisynthError& error) {\n    error_msg = env->Sprintf(\"propAdd: %s\", error.msg);\n  }\n\n  if (error_msg) {\n    env->MakeWritable(&frame);\n    env->ApplyMessage(&frame, vi, error_msg, vi.width / W_DIVISOR, 0xa0a0a0, 0, 0);\n  }\n\n  return frame;\n}\n\nint __stdcall SetProperty::SetCacheHints(int cachehints, int frame_range)\n{\n  AVS_UNUSED(frame_range);\n  switch (cachehints)\n  {\n  case CACHE_GET_MTMODE:\n    return MT_NICE_FILTER;\n  }\n  return 0;  // We do not pass cache requests upwards.\n}\n\nAVSValue __cdecl SetProperty::Create(AVSValue args, void* user_data, IScriptEnvironment* env)\n{\n  const int kind = (int)(intptr_t)user_data;\n  const int defaultMode = AVSPropAppendMode::PROPAPPENDMODE_REPLACE;\n\n  int mode = AVSPropAppendMode::PROPAPPENDMODE_REPLACE;\n  if(kind != 4) // at propSetArray there is no mode parameter\n    mode = args[3].AsInt(defaultMode);\n\n  /*\n    paReplace = 0,\n    paAppend = 1,\n    paTouch = 2\n  */\n  return new SetProperty(args[0].AsClip(), args[1].AsString(), args[2], kind, mode, env);\n}\n\n//**************************************************\n// helper for property name list\n\nstatic bool PropNamesToArray(const char* filtername, AVSValue& _propNames, std::vector<std::string>& propNames, IScriptEnvironment* env)\n{\n  if (!_propNames.Defined())\n    return false;\n  const int size = _propNames.ArraySize();\n  propNames.resize(size);\n  for (int i = 0; i < size; i++) {\n    const char* name = _propNames[i].AsString();\n    if (name == nullptr || !*name)\n      env->ThrowError(\"%s error: list contains empty name.\", filtername);\n\n    // Recognize \n    // - wildcards: \"Myprops_*\" or \"ab*cd\"\n    // - regex with ^ $ delimiters\n\n    std::string nameStr(name);\n\n    // Check if it's already a regex\n    if (nameStr.front() == '^' && nameStr.back() == '$') {\n      try {\n        std::regex re(nameStr);\n      }\n      catch (const std::regex_error&) {\n        env->ThrowError(\"%s error: invalid regex string.\", filtername);\n      }\n    }\n    else {\n      // Convert wildcard to regex\n      if (nameStr.find('*') != std::string::npos) {\n        nameStr = std::regex_replace(nameStr, std::regex(\"\\\\*\"), \".*\");\n        // Add regex delimiters\n        nameStr = \"^\" + nameStr + \"$\";\n      }\n      try {\n        std::regex re(nameStr);\n      }\n      catch (const std::regex_error&) {\n        env->ThrowError(\"%s error: invalid regex string while converting * wildcard.\", filtername);\n      }\n    }\n    propNames[i] = nameStr;\n  }\n  return true;\n}\n\n//**************************************************\n// propDelete\n\nDeleteProperty::DeleteProperty(PClip _child, AVSValue _propNames, IScriptEnvironment* env)\n  : GenericVideoFilter(_child)\n{ \n  propNames_defined = PropNamesToArray(\"propDelete\", _propNames, propNames, env);\n}\n\nDeleteProperty::~DeleteProperty() { }\n\nPVideoFrame __stdcall DeleteProperty::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame frame = child->GetFrame(n, env);\n\n  // Erase only if needed\n  const AVSMap* avsmap_test = env->getFramePropsRO(frame);\n  if (0 == env->propNumKeys(avsmap_test))\n    return frame;\n\n  /*\n    usage:\n      propDelete(\"frameluma\")\n      propDelete([\"_Matrix\",\"prop2\"])\n  */\n\n  env->MakePropertyWritable(&frame);\n\n  AVSMap* avsmap = env->getFramePropsRW(frame);\n\n  /*\n  // ignore when property does not exist\n  if (!res) {\n    const char *error_msg = env->Sprintf(\"propDelete: error deleting property '%s'\", name);\n    env->ApplyMessage(&frame, vi, error_msg, vi.width / W_DIVISOR, 0xa0a0a0, 0, 0);\n  }\n  */\n  // delete selected names\n  // positive list\n  for (auto& s : propNames) {\n    const char* key = s.c_str();\n    if (s.front() == '^' && s.back() == '$') {\n      // positive regex list \n      const int numKeys = env->propNumKeys(avsmap);\n      int index = 0;\n      for (int i = 0; i < numKeys; i++) {\n        const char* key = env->propGetKey(avsmap, index);\n        if (std::regex_match(key, std::regex(s)))\n          env->propDeleteKey(avsmap, key); // 0 is success, ignored, index does not change\n        else\n          index++; \n      }\n    }\n    else {\n      env->propDeleteKey(avsmap, key); // 0 is success, ignored\n    }\n  }\n\n  return frame;\n}\n\nint __stdcall DeleteProperty::SetCacheHints(int cachehints, int frame_range)\n{\n  AVS_UNUSED(frame_range);\n  switch (cachehints)\n  {\n  case CACHE_GET_MTMODE:\n    return MT_NICE_FILTER;\n  }\n  return 0;  // We do not pass cache requests upwards.\n}\n\nAVSValue __cdecl DeleteProperty::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  return new DeleteProperty(args[0].AsClip(), args[1], env);\n}\n\n//**************************************************\n// propDelete\n\nClearProperties::ClearProperties(PClip _child, IScriptEnvironment* env)\n  : GenericVideoFilter(_child)\n{ }\n\nClearProperties::~ClearProperties() { }\n\nPVideoFrame __stdcall ClearProperties::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame frame = child->GetFrame(n, env);\n\n  /*\n    usage:\n      ScriptClip(\"\"\"propClear()\"\"\")\n  */\n\n  // Erase only if needed\n  const AVSMap* avsmap_test = env->getFramePropsRO(frame);\n  if (0 != env->propNumKeys(avsmap_test)) {\n    env->MakePropertyWritable(&frame);\n    AVSMap* avsmap = env->getFramePropsRW(frame);\n    env->clearMap(avsmap);\n  }\n\n  return frame;\n}\n\nint __stdcall ClearProperties::SetCacheHints(int cachehints, int frame_range)\n{\n  AVS_UNUSED(frame_range);\n  switch (cachehints)\n  {\n  case CACHE_GET_MTMODE:\n    return MT_NICE_FILTER;\n  }\n  return 0;  // We do not pass cache requests upwards.\n}\n\nAVSValue __cdecl ClearProperties::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  return new ClearProperties(args[0].AsClip(), env);\n}\n\n//**************************************************\n// PropPassthrough — compatibility helper for old filters that predate frame properties\n\nPropPassthrough::PropPassthrough(PClip _child, PClip _prop_src, IScriptEnvironment* env)\n  : GenericVideoFilter(_child), prop_src(_prop_src)\n{ }\n\nPVideoFrame __stdcall PropPassthrough::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame out = child->GetFrame(n, env);\n  // Self-healing: if the filter was updated to use NewVideoFrameP it will already\n  // carry properties. In that case trust it and skip the copy.\n  const AVSMap* out_map = env->getFramePropsRO(out);\n  if (env->propNumKeys(out_map) > 0)\n    return out;\n  PVideoFrame src = prop_src->GetFrame(n, env);\n  env->MakePropertyWritable(&out);\n  env->copyFrameProps(src, out);\n  return out;\n}\n\nint __stdcall PropPassthrough::SetCacheHints(int cachehints, int frame_range)\n{\n  AVS_UNUSED(frame_range);\n  switch (cachehints)\n  {\n  case CACHE_GET_MTMODE:\n    return MT_NICE_FILTER;\n  }\n  return 0;\n}\n\n//**************************************************\n// propCopy\n\nCopyProperties::CopyProperties(PClip _child, PClip _child2, bool _merge, AVSValue _propNames, bool _exclude, IScriptEnvironment* env)\n  : GenericVideoFilter(_child), child2(_child2), merge(_merge), exclude(_exclude)\n{ \n  propNames_defined = PropNamesToArray(\"propCopy\", _propNames, propNames, env);\n}\n\nCopyProperties::~CopyProperties() { }\n\nAVSValue __cdecl CopyProperties::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  const bool merge = args[2].AsBool(false);\n  const bool exclude = args[4].AsBool(false);\n  return new CopyProperties(args[0].AsClip(), args[1].AsClip(), merge, args[3], exclude, env);\n}\n\nint __stdcall CopyProperties::SetCacheHints(int cachehints, int frame_range)\n{\n  AVS_UNUSED(frame_range);\n  switch (cachehints)\n  {\n  case CACHE_GET_MTMODE:\n    return MT_NICE_FILTER;\n  }\n  return 0;  // We do not pass cache requests upwards.\n}\n\nstatic void CopyOneFrameProp(const char* key, AVSMap* mapv, const AVSMap* avsmap_from, IScriptEnvironment* env)\n{\n  const int numElements = env->propNumElements(avsmap_from, key);\n  char propType = env->propGetType(avsmap_from, key);\n  int error;\n\n  // int and float (int64 and double) supports array get set\n  if (propType == AVSPropTypes::PROPTYPE_INT) {\n    auto srcval = env->propGetIntArray(avsmap_from, key, &error);\n    env->propSetIntArray(mapv, key, srcval, numElements);\n  }\n  else if (propType == AVSPropTypes::PROPTYPE_FLOAT) {\n    auto srcval = env->propGetFloatArray(avsmap_from, key, &error);\n    env->propSetFloatArray(mapv, key, srcval, numElements);\n  }\n  else {\n    // assumes the property is cleared beforehand\n\n    // frame, clip and data (string)\n    if (propType == AVSPropTypes::PROPTYPE_FRAME) {\n      for (int index = 0; index < numElements; index++) {\n        auto src = env->propGetFrame(avsmap_from, key, index, &error);\n        env->propSetFrame(mapv, key, src, AVSPropAppendMode::PROPAPPENDMODE_APPEND);\n      }\n    }\n    else if (propType == AVSPropTypes::PROPTYPE_CLIP) {\n      for (int index = 0; index < numElements; index++) {\n        auto src = env->propGetClip(avsmap_from, key, index, &error);\n        env->propSetClip(mapv, key, src, AVSPropAppendMode::PROPAPPENDMODE_APPEND);\n      }\n    }\n    else if (propType == AVSPropTypes::PROPTYPE_DATA) {\n      for (int index = 0; index < numElements; index++) {\n        // string, byte array in general\n        auto src = env->propGetData(avsmap_from, key, index, &error);\n        auto size = env->propGetDataSize(avsmap_from, key, index, &error);\n        auto typehint = env->propGetDataTypeHint(avsmap_from, key, index, &error); // v11\n        env->propSetDataH(mapv, key, src, size, typehint, AVSPropAppendMode::PROPAPPENDMODE_APPEND);\n      }\n    }\n  }\n}\n\nPVideoFrame __stdcall CopyProperties::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame frame = child->GetFrame(n, env);\n  PVideoFrame frame2 = child2->GetFrame(n, env);\n\n  const AVSMap* avsmap_from = env->getFramePropsRO(frame2);\n  const int propNum = env->propNumKeys(avsmap_from);\n\n  if (0 == propNum) {\n    // source has no properties at all\n    if (!merge) {\n      // exact copy: make target empty as well.\n      // Erase only if needed\n      const AVSMap* avsmap_to_test = env->getFramePropsRO(frame);\n      if (0 != env->propNumKeys(avsmap_to_test)) {\n        env->MakePropertyWritable(&frame);\n        AVSMap* avsmap_to = env->getFramePropsRW(frame);\n        env->clearMap(avsmap_to);\n      }\n    }\n    // source has no properties\n    return frame;\n  }\n\n  env->MakePropertyWritable(&frame);\n\n  if (!merge) {\n    // exact copy\n    if (!propNames_defined)\n      env->copyFrameProps(frame2, frame);\n    else {\n      // copy only selected / not excluded names\n      AVSMap* mapv = env->getFramePropsRW(frame);\n      env->clearMap(mapv); // clear all\n      if (!exclude) {\n        // positive list\n        for (auto& s : propNames) {\n          const char* key = s.c_str();\n          if (s.front() == '^' && s.back() == '$') {\n            // positive regex list \n            const int numKeys = env->propNumKeys(avsmap_from);\n            for (int i = 0; i < numKeys; i++) {\n              const char* key = env->propGetKey(avsmap_from, i);\n              if (std::regex_match(key, std::regex(s))) {\n                // regex match -> copy\n                CopyOneFrameProp(key, mapv, avsmap_from, env);\n              }\n            }\n          }\n          else {\n            CopyOneFrameProp(key, mapv, avsmap_from, env);\n          }\n        }\n      }\n      else {\n        // negative list\n        const int numKeys = env->propNumKeys(avsmap_from);\n        for (int i = 0; i < numKeys; i++) {\n          const char* key = env->propGetKey(avsmap_from, i);\n          bool matchFound = false;\n          for (auto& s : propNames) {\n            if (s.front() == '^' && s.back() == '$') {\n              // negative regex list\n              if (std::regex_match(key, std::regex(s))) {\n                matchFound = true;\n                break;\n              }\n            }\n            else if (s == key) {\n              matchFound = true;\n              break;\n            }\n          }\n          if (!matchFound) {\n            // not in negative list -> copy\n            CopyOneFrameProp(key, mapv, avsmap_from, env);\n          }\n        }\n      }\n    }\n    return frame;\n  }\n\n  // merge\n  AVSMap* mapv = env->getFramePropsRW(frame);\n\n  // add from source, replace if needed\n  const int numKeys = env->propNumKeys(avsmap_from);\n  for (int i = 0; i < numKeys; i++) {\n    const char* key = env->propGetKey(avsmap_from, i);\n    // merge if no list specified or name is in the list\n\n    bool need_copy = true;\n\n    if (propNames_defined) {\n      need_copy = false;\n      for (const auto& s : propNames) {\n        if (s.front() == '^' && s.back() == '$') {\n          // regex match\n          if (std::regex_match(key, std::regex(s))) {\n            need_copy = true;\n            break;\n          }\n        }\n        else if (s == key) {\n          // plain string match\n          need_copy = true;\n          break;\n        }\n      }\n      if (exclude) {\n        need_copy = !need_copy;\n      }\n    }\n\n    if(need_copy) {\n      env->propDeleteKey(mapv, key); // delete if existed\n      CopyOneFrameProp(key, mapv, avsmap_from, env);\n    }\n  }\n\n  return frame;\n}\n\n//**************************************************\n// propShow\n\nShowProperties::ShowProperties(PClip _child, int size, bool showtype, \n  const char *_font, int _text_color, int _halo_color, bool _bold,\n  int _x, int _y, int _align, AVSValue _propNames, IScriptEnvironment* env)\n  : GenericVideoFilter(_child), size(size), showtype(showtype),\n  fontname(_font), textcolor(_text_color), halocolor(_halo_color), bold(_bold),\n  x(_x), y(_y), align(_align)\n{\n  propNames_defined = PropNamesToArray(\"propShow\", _propNames, propNames, env);\n}\n\nShowProperties::~ShowProperties() { }\n\nPVideoFrame __stdcall ShowProperties::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame frame = child->GetFrame(n, env);\n\n  const AVSMap* avsmap = env->getFramePropsRO(frame);\n\n  const int propNum = env->propNumKeys(avsmap);\n\n  if (0 == propNum)\n    return frame;\n\n  std::stringstream ss;\n  if (!propNames_defined) // no header displayed if filter is given\n    ss << \"Number of keys = \" << std::to_string(propNum) << std::endl;\n\n  for (int index = 0; index < propNum; index++) {\n    const char* propName = env->propGetKey(avsmap, index);\n\n    bool display = true;\n    if (propNames_defined) {\n      display = false;\n      for (const auto& s : propNames) {\n        if (s.front() == '^' && s.back() == '$') {\n          // regex match\n          if (std::regex_match(propName, std::regex(s))) {\n            display = true;\n            break;\n          }\n        }\n        else if (s == propName) {\n          // plain string match\n          display = true;\n          break;\n        }\n      }\n    }\n\n    if (display) {\n      std::string propName_s = propName;\n\n      const char propType = env->propGetType(avsmap, propName);\n      ss << propName;\n      if (showtype)\n        ss << \" (\" << propType << \")\";\n      ss << \" = \";\n\n      const int propNumElements = env->propNumElements(avsmap, propName);\n\n      int error;\n\n      if (propType == 'u') {\n        // unSet: undefined value\n        ss << \"<unset!>\";\n      }\n      else if (propType == 'i') {\n        if (propNumElements > 1)\n          ss << \"[\";\n        const int64_t* arr = env->propGetIntArray(avsmap, propName, &error);\n        for (int i = 0; i < propNumElements; ++i) {\n          ss << std::to_string(arr[i]);\n          if (i < propNumElements - 1)\n            ss << \", \";\n        }\n        if (propNumElements > 1)\n          ss << \"]\";\n\n        if (propName_s == \"_ColorRange\") {\n          ss << \" = \";\n          switch (arr[0]) {\n          case ColorRange_Compat_e::AVS_COLORRANGE_LIMITED: ss << \"limited\"; break;\n          case ColorRange_Compat_e::AVS_COLORRANGE_FULL: ss << \"full\"; break;\n          }\n        }\n        else if (propName_s == \"_Matrix\") {\n          ss << \" = \";\n          switch (arr[0]) {\n          case Matrix_e::AVS_MATRIX_RGB: ss << \"rgb\"; break;\n          case Matrix_e::AVS_MATRIX_BT709: ss << \"709\"; break;\n          case Matrix_e::AVS_MATRIX_UNSPECIFIED: ss << \"unspec\"; break;\n          case Matrix_e::AVS_MATRIX_ST170_M: ss << \"170m\"; break;\n          case Matrix_e::AVS_MATRIX_ST240_M: ss << \"240m\"; break;\n          case Matrix_e::AVS_MATRIX_BT470_BG: ss << \"470bg (601)\"; break;\n          case Matrix_e::AVS_MATRIX_BT470_M: ss << \"470m (fcc)\"; break;\n          case Matrix_e::AVS_MATRIX_YCGCO: ss << \"YCgCo\"; break;\n          case Matrix_e::AVS_MATRIX_BT2020_NCL: ss << \"2020ncl (2020)\"; break;\n          case Matrix_e::AVS_MATRIX_BT2020_CL: ss << \"2020cl\"; break;\n          case Matrix_e::AVS_MATRIX_CHROMATICITY_DERIVED_CL: ss << \"chromacl\"; break;\n          case Matrix_e::AVS_MATRIX_CHROMATICITY_DERIVED_NCL: ss << \"chromancl\"; break;\n          case Matrix_e::AVS_MATRIX_ICTCP: ss << \"ictcp\"; break;\n          case Matrix_e::AVS_MATRIX_AVERAGE: ss << \"AVERAGE-Legacy Avisynth\"; break;\n          }\n        }\n        else if (propName_s == \"_ChromaLocation\") {\n          ss << \" = \";\n          switch (arr[0]) {\n          case ChromaLocation_e::AVS_CHROMA_LEFT: ss << \"left (mpeg2)\"; break;\n          case ChromaLocation_e::AVS_CHROMA_CENTER: ss << \"center (mpeg1, jpeg)\"; break;\n          case ChromaLocation_e::AVS_CHROMA_TOP_LEFT: ss << \"top_left\"; break;\n          case ChromaLocation_e::AVS_CHROMA_TOP: ss << \"top\"; break;\n          case ChromaLocation_e::AVS_CHROMA_BOTTOM_LEFT: ss << \"bottom_left\"; break;\n          case ChromaLocation_e::AVS_CHROMA_BOTTOM: ss << \"bottom\"; break;\n          case ChromaLocation_e::AVS_CHROMA_DV: ss << \"dv-Legacy Avisynth\"; break;\n          }\n        }\n      }\n      else if (propType == 'f') {\n        if (propNumElements > 1)\n          ss << \"[\";\n        const double* arr = env->propGetFloatArray(avsmap, propName, &error);\n        for (int i = 0; i < propNumElements; ++i) {\n          ss << std::to_string(arr[i]);\n          if (i < propNumElements - 1)\n            ss << \", \";\n        }\n        if (propNumElements > 1)\n          ss << \"]\";\n      }\n      else if (propType == 's') {\n        if (propNumElements > 1)\n          ss << \"[\";\n        for (int i = 0; i < propNumElements; ++i) {\n          const char* s = env->propGetData(avsmap, propName, i, &error);\n          const int type = env->propGetDataTypeHint(avsmap, propName, i, &error);\n          if (type == AVSPropDataTypeHint::PROPDATATYPEHINT_BINARY)\n          {\n            auto len = env->propGetDataSize(avsmap, propName, i, &error);\n            ss << \"Data length=\" << len << \": [\";\n            // print up to 16 comma separated bytes in HEX, ... at the end if there are more.\n            int count = std::min(len, 16);\n            for (int i = 0; i < count; ++i) {\n              if (i > 0) ss << \",\";\n              ss << std::uppercase << std::hex << std::setw(2) << std::setfill('0') << (static_cast<unsigned int>(s[i]) & 0xFF);\n            }\n            if (len > 16) ss << \"...\";\n            ss << \"]\";\n          }\n          else\n          {\n            // AVSPropDataTypeHint::DATATYPEHINT_UTF8 and AVSPropDataTypeHint::DATATYPEHINT_UNKNOWN\n            // suppose string\n            ss << \"\\\"\" << s << \"\\\"\";\n          }\n          if (i < propNumElements - 1)\n            ss << \", \";\n        }\n        if (propNumElements > 1)\n          ss << \"]\";\n      }\n      else {\n        ss << \"<cannot display!>\";\n      }\n      ss << std::endl;\n    }\n  }\n\n  std::string t = ss.str();\n  const char* text = t.c_str();\n  AVSValue args[10] = { child, text, size, fontname, textcolor, halocolor, bold, x, y, align };\n  const char* argnames[10] = { 0, 0, \"size\", \"font\", \"text_color\", \"halo_color\", \"bold\", \"x\", \"y\", \"align\" };\n  PClip child2 = env->Invoke(\"Text\", AVSValue(args, 10), argnames).AsClip();\n  frame = child2->GetFrame(n, env);\n\n  return frame;\n}\n\nint __stdcall ShowProperties::SetCacheHints(int cachehints, int frame_range)\n{\n  AVS_UNUSED(frame_range);\n  switch (cachehints)\n  {\n  case CACHE_GET_MTMODE:\n    return MT_NICE_FILTER;\n  }\n  return 0;  // We do not pass cache requests upwards.\n}\n\nAVSValue __cdecl ShowProperties::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  // 0   1        2       3         4             5        6     7   8     9       10\n  // c[size]i[showtype]b[font]s[text_color]i[halo_color]i[bold]b[x]f[y]f[align]i[props]s+\n\n  PClip clip = args[0].AsClip();\n\n  const int size = args[1].AsInt(16);\n  const bool showtype = args[2].AsBool(false);\n  const char* font = args[3].AsString(\"Terminus\");\n  const int text_color = args[4].AsInt(0xFFFF00);\n  const int halo_color = args[5].AsInt(0);\n  const bool bold = args[6].AsBool(false);\n\n  const int align = args[9].AsInt(7); // default top left\n\n  const int info_default_x = 0; // subtitle: 8, Info: 4\n  const int PIXEL_MUL_FACTOR = 1; // like \"Text\"\n  // similar to SubTitle/FilterInfo.Create\n  int defx, defy;\n  bool x_center = false;\n  bool y_center = false;\n\n  switch (align) {\n  case 1: case 4: case 7: defx = 8; break;\n  case 2: case 5: case 8:\n    defx = 0; // n/a if not set later\n    x_center = true;\n    break;\n  case 3: case 6: case 9: defx = clip->GetVideoInfo().width - info_default_x; break; // subtitle: 8, Info: 4\n  default: defx = info_default_x; break;\n  }\n\n  switch (align) {\n  case 1: case 2: case 3: defy = clip->GetVideoInfo().height - 2; break; // bottom alignment 2 pixel above\n  case 4: case 5: case 6:\n    defy = 0; // n/a if not set later\n    y_center = true;\n    break;\n  case 7: case 8: case 9: defy = 0; break;\n  default: defy = (size + 4) / 8; break;\n  }\n\n  const bool isXdefined = args[7].Defined();\n  const bool isYdefined = args[8].Defined();\n\n  int x = int(args[7].AsDblDef(defx) * PIXEL_MUL_FACTOR + 0.5);\n  int y = int(args[8].AsDblDef(defy) * PIXEL_MUL_FACTOR + 0.5);\n\n  if (!isXdefined && x_center)\n    x = (clip->GetVideoInfo().width >> 1) * PIXEL_MUL_FACTOR;\n\n  if (!isYdefined && y_center)\n    y = (clip->GetVideoInfo().height >> 1) * PIXEL_MUL_FACTOR;\n\n\n  if ((align < 1) || (align > 9))\n    env->ThrowError(\"propShow: Align values are 1 - 9 mapped to your numeric pad\");\n\n  return new ShowProperties(clip, size, showtype, font, text_color, halo_color, bold, x, y, align, args[10], env);\n}\n"
  },
  {
    "path": "avs_core/filters/conditional/conditional_reader.h",
    "content": "/*\n  ConditionalReader  (c) 2004 by Klaus Post\n\n  This program is free software; you can redistribute it and/or modify\n  it under the terms of the GNU General Public License as published by\n  the Free Software Foundation.\n\n  This program is distributed in the hope that it will be useful,\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n  GNU General Public License for more details.\n\n  You should have received a copy of the GNU General Public License\n  along with this program; if not, write to the Free Software\n  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n  The author can be contacted at:\n  sh0dan[at]stofanet.dk\n*/\n\n#include <avisynth.h>\n#include <cstdio>\n#include <cstdlib>\n#include <vector>\n#include <string>\n#include <mutex>\n\n#ifdef AVS_POSIX\n#include <limits.h>\n#endif\n\nenum {\n  MODE_UNKNOWN = -1,\n  MODE_INT = 1,\n  MODE_FLOAT = 2,\n  MODE_BOOL = 3,\n  MODE_STRING = 4\n};\n\nstruct StringCache {\n  char* string;\n  StringCache *next;\n};\n\nclass ConditionalReader : public GenericVideoFilter\n{\nprivate:\n  const bool show;\n  std::string variableName;\n  const char* variableNameFixed;\n  int mode;\n  int offset;\n  const bool local;\n  StringCache* stringcache; // fixme: to vector\n  union {\n    int* intVal;\n    bool* boolVal;\n    float* floatVal;\n    const char* *stringVal;\n  };\n\n  AVSValue ConvertType(const char* content, int line, IScriptEnvironment* env);\n  void SetRange(int start_frame, int stop_frame, AVSValue v);\n  void SetFrame(int framenumber, AVSValue v);\n  void ThrowLine(const char* err, int line, IScriptEnvironment* env);\n  AVSValue GetFrameValue(int framenumber);\n  void CleanUp(void);\n\npublic:\n  ConditionalReader(PClip _child, const char* filename, const char _varname[], bool _show, const char *_condVarSuffix, bool _local, IScriptEnvironment* env);\n  ~ConditionalReader(void);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n  int __stdcall SetCacheHints(int cachehints, int frame_range);\n  static AVSValue __cdecl Create(AVSValue args, void* user_data, IScriptEnvironment* env);\n};\n\n\n/* ------------------------------------------------------------------------------\n** Write function to evaluate expressions per frame and write the results to file\n** Ernst Peché, 2004\n*/\n\nclass Write : public GenericVideoFilter\n{\nprivate:\n  FILE * fout;\n  int linecheck;\t// 0=write each line, 1=write only if first expression == true, -1 = write at start, -2 = write at end\n  bool flush;\n  bool append;\n  bool local;\n\n#ifdef AVS_WINDOWS\n  char filename[_MAX_PATH];\n#else\n  char filename[PATH_MAX];\n#endif\n  int arrsize;\n  struct exp_res {\n    AVSValue expression;\n    const char* string;\n  };\n  exp_res* arglist;\n\n  bool DoEval(IScriptEnvironment* env);\n  void FileOut(IScriptEnvironment* env, const char* mode);\n\npublic:\n    Write(PClip _child, const char* _filename, AVSValue args, int _linecheck, bool _flush, bool _append, bool _local, IScriptEnvironment* env);\n  ~Write(void);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n  int __stdcall SetCacheHints(int cachehints, int frame_range);\n  static AVSValue __cdecl Create(AVSValue args, void* user_data, IScriptEnvironment* env);\n  static AVSValue __cdecl Create_If(AVSValue args, void* user_data, IScriptEnvironment* env);\n  static AVSValue __cdecl Create_Start(AVSValue args, void* user_data, IScriptEnvironment* env);\n    static AVSValue __cdecl Create_End(AVSValue args, void* user_data, IScriptEnvironment* env);\n};\n\n\nclass UseVar : public GenericVideoFilter\n{\nprivate:\n   struct Var {\n      const char* name;\n      AVSValue val;\n   };\n\n   std::vector<Var> vars_;\n\npublic:\n   UseVar(PClip _child, AVSValue vars, IScriptEnvironment* env);\n   ~UseVar();\n   PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n   int __stdcall SetCacheHints(int cachehints, int frame_range);\n   static AVSValue __cdecl Create(AVSValue args, void* user_data, IScriptEnvironment* env);\n};\n\n// avs+ (vs) style frame properties\nclass SetProperty : public GenericVideoFilter\n{\nprivate:\n  const char* name;\n  AVSValue value;\n  const int kind;\n  const int append_mode; // AVSPropAppendMode\n\npublic:\n  SetProperty(PClip _child, const char* name, const AVSValue& value, const int kind, const int mode, IScriptEnvironment* env);\n  ~SetProperty();\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n  int __stdcall SetCacheHints(int cachehints, int frame_range);\n  static AVSValue __cdecl Create(AVSValue args, void* user_data, IScriptEnvironment* env);\n};\n\nclass DeleteProperty : public GenericVideoFilter\n{\nprivate:\n  bool propNames_defined;\n  std::vector<std::string> propNames;\n\npublic:\n  DeleteProperty(PClip _child, AVSValue _propNames, IScriptEnvironment* env);\n  ~DeleteProperty();\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n  int __stdcall SetCacheHints(int cachehints, int frame_range);\n  static AVSValue __cdecl Create(AVSValue args, void* , IScriptEnvironment* env);\n};\n\nclass ClearProperties : public GenericVideoFilter\n{\nprivate:\n\npublic:\n  ClearProperties(PClip _child, IScriptEnvironment* env);\n  ~ClearProperties();\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n  int __stdcall SetCacheHints(int cachehints, int frame_range);\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n};\n\n// Compatibility helper for old filters that predate frame property support.\n// Copies all frame properties from the filter's first input clip to its output,\n// but only when the output has no properties of its own (self-healing: becomes a\n// no-op if the plugin is later updated to pass properties e.g. by using NewVideoFrameP).\nclass PropPassthrough : public GenericVideoFilter\n{\nprivate:\n  PClip prop_src; // first input clip — source of properties\n\npublic:\n  PropPassthrough(PClip _child, PClip _prop_src, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n  int __stdcall SetCacheHints(int cachehints, int frame_range);\n};\n\nclass CopyProperties : public GenericVideoFilter\n{\nprivate:\n  PClip child2;\n  bool merge;\n  bool propNames_defined;\n  std::vector<std::string> propNames;\n  bool exclude;\n\npublic:\n  CopyProperties(PClip _child, PClip _child2, bool _merge, AVSValue _propNames, bool _exclude, IScriptEnvironment* env);\n  ~CopyProperties();\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n  int __stdcall SetCacheHints(int cachehints, int frame_range);\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n};\n\nclass ShowProperties : public GenericVideoFilter\n{\nprivate:\n  int size;\n  bool showtype;\n  const char* const fontname; // Terminus or info_h\n  const int textcolor, halocolor;\n  const bool bold;\n  int x, y;\n  int align;\n  bool propNames_defined;\n  std::vector<std::string> propNames;\n\npublic:\n  ShowProperties(PClip _child, int size, bool showtype, const char* _font, int _text_color, int _halo_color, bool _bold, int _x, int _y, int _align, AVSValue _propNames, IScriptEnvironment* env);\n  ~ShowProperties();\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n  int __stdcall SetCacheHints(int cachehints, int frame_range);\n  static AVSValue __cdecl Create(AVSValue args, void* user_data, IScriptEnvironment* env);\n};\n"
  },
  {
    "path": "avs_core/filters/conditional/intel/conditional_functions_sse.cpp",
    "content": "\n// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include <avisynth.h>\n#include <cstdint>\n\n// Intrinsics base header + really required extension headers\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n\n#include <algorithm>\n\n// sum: sad with zero\ndouble get_sum_of_pixels_sse2(const uint8_t* srcp, size_t height, size_t width, size_t pitch) {\n  size_t mod16_width = width / 16 * 16;\n  int64_t result = 0;\n  __m128i sum = _mm_setzero_si128();\n  __m128i zero = _mm_setzero_si128();\n\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < mod16_width; x+=16) {\n      __m128i src = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x));\n      __m128i sad = _mm_sad_epu8(src, zero);\n      sum = _mm_add_epi32(sum, sad);\n    }\n\n    for (size_t x = mod16_width; x < width; ++x) {\n      result += srcp[x];\n    }\n\n    srcp += pitch;\n  }\n  __m128i upper = _mm_castps_si128(_mm_movehl_ps(_mm_setzero_ps(), _mm_castsi128_ps(sum)));\n  sum = _mm_add_epi32(sum, upper);\n  result += _mm_cvtsi128_si32(sum);\n  return (double)result;\n}\n\n#ifdef X86_32\ndouble get_sum_of_pixels_isse(const uint8_t* srcp, size_t height, size_t width, size_t pitch) {\n  size_t mod8_width = width / 8 * 8;\n  int64_t result = 0;\n  __m64 sum = _mm_setzero_si64();\n  __m64 zero = _mm_setzero_si64();\n\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < mod8_width; x+=8) {\n      __m64 src = *reinterpret_cast<const __m64*>(srcp + x);\n      __m64 sad = _mm_sad_pu8(src, zero);\n      sum = _mm_add_pi32(sum, sad);\n    }\n\n    for (size_t x = mod8_width; x < width; ++x) {\n      result += srcp[x];\n    }\n\n    srcp += pitch;\n  }\n  result += _mm_cvtsi64_si32(sum);\n  _mm_empty();\n  return (double)result;\n}\n\nsize_t get_sad_isse(const uint8_t* src_ptr, const uint8_t* other_ptr, size_t height, size_t width, size_t src_pitch, size_t other_pitch) {\n  size_t mod8_width = width / 8 * 8;\n  size_t result = 0;\n  __m64 sum = _mm_setzero_si64();\n\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < mod8_width; x+=8) {\n      __m64 src = *reinterpret_cast<const __m64*>(src_ptr + x);\n      __m64 other = *reinterpret_cast<const __m64*>(other_ptr + x);\n      __m64 sad = _mm_sad_pu8(src, other);\n      sum = _mm_add_pi32(sum, sad);\n    }\n\n    for (size_t x = mod8_width; x < width; ++x) {\n      result += std::abs(src_ptr[x] - other_ptr[x]);\n    }\n\n    src_ptr += src_pitch;\n    other_ptr += other_pitch;\n  }\n  result += _mm_cvtsi64_si32(sum);\n  _mm_empty();\n  return result;\n}\n\nsize_t get_sad_rgb_isse(const uint8_t* src_ptr, const uint8_t* other_ptr, size_t height, size_t width, size_t src_pitch, size_t other_pitch) {\n  size_t mod8_width = width / 8 * 8;\n  size_t result = 0;\n  __m64 rgb_mask = _mm_set1_pi32(0x00FFFFFF);\n  __m64 sum = _mm_setzero_si64();\n\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < mod8_width; x+=8) {\n      __m64 src = *reinterpret_cast<const __m64*>(src_ptr + x);\n      __m64 other = *reinterpret_cast<const __m64*>(other_ptr + x);\n      src = _mm_and_si64(src, rgb_mask);\n      other = _mm_and_si64(other, rgb_mask);\n      __m64 sad = _mm_sad_pu8(src, other);\n      sum = _mm_add_pi32(sum, sad);\n    }\n\n    for (size_t x = mod8_width; x < width; ++x) {\n      result += std::abs(src_ptr[x] - other_ptr[x]);\n    }\n\n    src_ptr += src_pitch;\n    other_ptr += other_pitch;\n  }\n  result += _mm_cvtsi64_si32(sum);\n  _mm_empty();\n  return result;\n}\n\n#endif\n\n"
  },
  {
    "path": "avs_core/filters/conditional/intel/conditional_functions_sse.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include <avisynth.h>\n\ndouble get_sum_of_pixels_sse2(const uint8_t* srcp, size_t height, size_t width, size_t pitch);\n#ifdef X86_32\ndouble get_sum_of_pixels_isse(const uint8_t* srcp, size_t height, size_t width, size_t pitch);\nsize_t get_sad_isse(const uint8_t* src_ptr, const uint8_t* other_ptr, size_t height, size_t width, size_t src_pitch, size_t other_pitch);\nsize_t get_sad_rgb_isse(const uint8_t* src_ptr, const uint8_t* other_ptr, size_t height, size_t width, size_t src_pitch, size_t other_pitch);\n#endif\n"
  },
  {
    "path": "avs_core/filters/convolution.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include <cstdint>\n#include <cstdlib>\n#include <cmath>\n\n// Avisynth filter: general convolution\n// by Richard Berg (avisynth-dev@richardberg.net)\n// adapted from General Convolution 3D for VDub by Gunnar Thalin (guth@home.se)\n// avs+: all color spaces, 8-32 bits, 7x7, 9x9, luma/chroma/alpha option\n\n#include \"convolution.h\"\n#include \"../core/internal.h\"\n\n#include <regex>\n#include <iostream>\n#include <iterator>\n#include <string>\n\n/********************************************************************\n***** Declare index of new filters for Avisynth's filter engine *****\n********************************************************************/\n\nextern const AVSFunction Convolution_filters[] = {\n// Please when adding parameters try not to break the legacy order - IanB July 2004\n  { \"GeneralConvolution\", BUILTIN_FUNC_PREFIX, \"c[bias]f[matrix]s[divisor]f[auto]b[luma]b[chroma]b[alpha]b\", GeneralConvolution::Create },\n    /**\n      * GeneralConvolution(PClip clip, int divisor=1, int bias=0, string matrix)\n      * clip     =  input video\n      * bias     =  additive bias to adjust the total output intensity\n      * matrix   =  the kernel (3x3 or 5x5).  any kind of whitespace is ok, see example\n      * divisor  =  divides the output of the convolution (calculated before adding bias)\n      * auto     =  automaticly scale the result based on the sum of the matrix elements\n      * luma     =  apply on luma (if applicable) avs+\n      * chroma   =  apply on chroma (if applicable) avs+\n      * alpha    =  apply on alpha (if applicable e.g. RGB32 converted to planar RGBA) avs+\n      *\n      * clip.GeneralConvolution(matrix = \"1 2 3\n      *                                   4 5 6\n      *                                   7 8 9\")\n     **/\n\n  { 0 }\n};\n\ntemplate<int mi, int ma>\nAVS_FORCEINLINE int static_clip(int value) {\n  if (value < mi) {\n    return mi;\n  }\n  if (value > ma) {\n    return ma;\n  }\n  return value;\n}\n\n/*****************************************\n****** General Convolution 2D filter *****\n*****************************************/\n\n// safe_int_t is int or int64_t. Int is faster but for larger bitdepth int32 overflows\ntemplate<typename pixel_t, int matrix_size, typename safe_int_t>\nstatic void do_conv_integer(BYTE* dstp8, int dst_pitch, const BYTE *srcp8, int src_pitch, int width, int height, const int *matrix, int iCountDiv, int iBias, int bits_per_pixel)\n{\n  pixel_t *dstp = reinterpret_cast<pixel_t *>(dstp8);\n  const pixel_t *srcp = reinterpret_cast<const pixel_t *>(srcp8);\n  dst_pitch /= sizeof(pixel_t);\n  src_pitch /= sizeof(pixel_t);\n\n  constexpr int limit = (matrix_size - 1) / 2; // +-1, +-2, +-3\n  const int max_pixel_value = (1 << bits_per_pixel) - 1;\n\n  std::vector<const pixel_t*> src_lineptrs;\n  src_lineptrs.resize(limit + height + limit);\n\n  // prefill line pointers\n  for (int y = -limit; y < height + limit; y++)\n  {\n    if (y < 0)\n      src_lineptrs[y + limit] = srcp + src_pitch * 0; // duplicate top\n    else if (y < height)\n      src_lineptrs[y + limit] = srcp + src_pitch * y;\n    else\n      src_lineptrs[y + limit] = srcp + src_pitch * (height - 1); // duplicate bottom\n  }\n\n  std::vector<const pixel_t *> src_current_lineptrs(matrix_size); // +/-limit => 2*limit + 1\n\n  constexpr safe_int_t rounder = 1 << (20 - 1);\n\n  for (int y = 0; y < height; ++y) {\n    // prefill current vertical line pointers\n    for (int yy = -limit; yy <= limit; yy++) {\n      src_current_lineptrs[yy + limit] = src_lineptrs[limit + (y + yy)];\n    }\n    int x = 0;\n    // left area: check valid x\n    for (; x < limit; x++)\n    {\n      safe_int_t sum = 0; // int or int64_t!!!\n      const int *current_matrix = matrix + limit; // center of the matrix line\n      for (int yy = 0; yy < matrix_size; yy++) { // 0..limit * 2 + 1\n        const pixel_t *current_line = src_current_lineptrs[yy];\n        for (int xx = -limit; xx <= limit; xx++) {\n          int current_x = x + xx;\n          if (current_x < 0) current_x = 0;\n          else if (current_x >= width) current_x = width - 1;\n          const int current_pixel = current_line[current_x];\n          const int current_weight = current_matrix[xx];\n          sum += current_pixel * current_weight;\n        }\n        current_matrix += matrix_size; // next matrix line\n      }\n      int result = (int)((sum * iCountDiv + rounder) >> 20) + iBias;\n      dstp[x] = clamp(result, 0, max_pixel_value);\n    }\n    // middle area: no x check: fast!\n    for (; x < width - limit; x++) {\n      safe_int_t sum = 0;\n      const int *current_matrix = matrix + limit; // center of the matrix line\n      for (int yy = 0; yy < matrix_size; yy++) { // 0..limit * 2 + 1\n        const pixel_t *current_line = src_current_lineptrs[yy];\n        // compilers are smart nowadays but let's help them\n        if constexpr (matrix_size == 3) {\n          sum +=\n            current_line[x - 1] * current_matrix[-1] +\n            current_line[x + 0] * current_matrix[0] +\n            current_line[x + 1] * current_matrix[1];\n        }\n        else if constexpr (matrix_size == 5) {\n          sum +=\n            current_line[x - 2] * current_matrix[-2] +\n            current_line[x - 1] * current_matrix[-1] +\n            current_line[x + 0] * current_matrix[0] +\n            current_line[x + 1] * current_matrix[1] +\n            current_line[x + 2] * current_matrix[2];\n        }\n        else {\n          for (int xx = -limit; xx <= limit; xx++) {\n            int current_x = x + xx;\n            // no checking!\n            /*if (current_x < 0) current_x = 0;\n            else if (current_x >= width) current_x = width - 1;*/\n            const int current_pixel = current_line[current_x];\n            const int current_weight = current_matrix[xx];\n            sum += current_pixel * current_weight;\n          }\n        }\n        current_matrix += matrix_size; // next matrix line\n      }\n      int result = (int)((sum * iCountDiv + rounder) >> 20) + iBias;\n      dstp[x] = clamp(result, 0, max_pixel_value);\n    }\n    // right area: check valid x\n    for (; x < width; x++)\n    {\n      safe_int_t sum = 0;\n      const int *current_matrix = matrix + limit; // center of the matrix line\n      for (int yy = 0; yy < matrix_size; yy++) { // 0..limit * 2 + 1\n        const pixel_t *current_line = src_current_lineptrs[yy];\n        for (int xx = -limit; xx <= limit; xx++) {\n          int current_x = x + xx;\n          if (current_x < 0) current_x = 0;\n          else if (current_x >= width) current_x = width - 1;\n          const int current_pixel = current_line[current_x];\n          const int current_weight = current_matrix[xx];\n          sum += current_pixel * current_weight;\n        }\n        current_matrix += matrix_size; // next matrix line\n      }\n      int result = (int)((sum * iCountDiv + rounder) >> 20) + iBias;\n      dstp[x] = clamp(result, 0, max_pixel_value);\n    }\n    dstp += dst_pitch;\n    srcp += src_pitch;\n  }\n}\n\n// instantiate for 8 bit 3,5,7 and 9\ntemplate void do_conv_integer<uint8_t, 3, int>(BYTE* dstp8, int dst_pitch, const BYTE *srcp8, int src_pitch, int width, int height, const int *matrix, int iCountDiv, int iBias, int bits_per_pixel);\ntemplate void do_conv_integer<uint8_t, 5, int>(BYTE* dstp8, int dst_pitch, const BYTE *srcp8, int src_pitch, int width, int height, const int *matrix, int iCountDiv, int iBias, int bits_per_pixel);\ntemplate void do_conv_integer<uint8_t, 7, int>(BYTE* dstp8, int dst_pitch, const BYTE *srcp8, int src_pitch, int width, int height, const int *matrix, int iCountDiv, int iBias, int bits_per_pixel);\ntemplate void do_conv_integer<uint8_t, 9, int>(BYTE* dstp8, int dst_pitch, const BYTE *srcp8, int src_pitch, int width, int height, const int *matrix, int iCountDiv, int iBias, int bits_per_pixel);\ntemplate void do_conv_integer<uint8_t, 3, int64_t>(BYTE* dstp8, int dst_pitch, const BYTE *srcp8, int src_pitch, int width, int height, const int *matrix, int iCountDiv, int iBias, int bits_per_pixel);\ntemplate void do_conv_integer<uint8_t, 5, int64_t>(BYTE* dstp8, int dst_pitch, const BYTE *srcp8, int src_pitch, int width, int height, const int *matrix, int iCountDiv, int iBias, int bits_per_pixel);\ntemplate void do_conv_integer<uint8_t, 7, int64_t>(BYTE* dstp8, int dst_pitch, const BYTE *srcp8, int src_pitch, int width, int height, const int *matrix, int iCountDiv, int iBias, int bits_per_pixel);\ntemplate void do_conv_integer<uint8_t, 9, int64_t>(BYTE* dstp8, int dst_pitch, const BYTE *srcp8, int src_pitch, int width, int height, const int *matrix, int iCountDiv, int iBias, int bits_per_pixel);\n\ntemplate void do_conv_integer<uint16_t, 3, int>(BYTE* dstp8, int dst_pitch, const BYTE *srcp8, int src_pitch, int width, int height, const int *matrix, int iCountDiv, int iBias, int bits_per_pixel);\ntemplate void do_conv_integer<uint16_t, 5, int>(BYTE* dstp8, int dst_pitch, const BYTE *srcp8, int src_pitch, int width, int height, const int *matrix, int iCountDiv, int iBias, int bits_per_pixel);\ntemplate void do_conv_integer<uint16_t, 7, int>(BYTE* dstp8, int dst_pitch, const BYTE *srcp8, int src_pitch, int width, int height, const int *matrix, int iCountDiv, int iBias, int bits_per_pixel);\ntemplate void do_conv_integer<uint16_t, 9, int>(BYTE* dstp8, int dst_pitch, const BYTE *srcp8, int src_pitch, int width, int height, const int *matrix, int iCountDiv, int iBias, int bits_per_pixel);\ntemplate void do_conv_integer<uint16_t, 3, int64_t>(BYTE* dstp8, int dst_pitch, const BYTE *srcp8, int src_pitch, int width, int height, const int *matrix, int iCountDiv, int iBias, int bits_per_pixel);\ntemplate void do_conv_integer<uint16_t, 5, int64_t>(BYTE* dstp8, int dst_pitch, const BYTE *srcp8, int src_pitch, int width, int height, const int *matrix, int iCountDiv, int iBias, int bits_per_pixel);\ntemplate void do_conv_integer<uint16_t, 7, int64_t>(BYTE* dstp8, int dst_pitch, const BYTE *srcp8, int src_pitch, int width, int height, const int *matrix, int iCountDiv, int iBias, int bits_per_pixel);\ntemplate void do_conv_integer<uint16_t, 9, int64_t>(BYTE* dstp8, int dst_pitch, const BYTE *srcp8, int src_pitch, int width, int height, const int *matrix, int iCountDiv, int iBias, int bits_per_pixel);\n\ntemplate<int matrix_size>\nstatic void do_conv_float(BYTE* dstp8, int dst_pitch, const BYTE *srcp8, int src_pitch, int width, int height, const float *matrix, float fCountDiv, float fBias)\n{\n  float *dstp = reinterpret_cast<float *>(dstp8);\n  const float *srcp = reinterpret_cast<const float *>(srcp8);\n  dst_pitch /= sizeof(float);\n  src_pitch /= sizeof(float);\n\n  constexpr int limit = (matrix_size - 1) / 2; // +-1, +-2, +-3\n\n  std::vector<const float*> src_lineptrs;\n  src_lineptrs.resize(limit + height + limit);\n\n  // prefill line pointers\n  for (int y = -limit; y < height + limit; y++)\n  {\n    if (y < 0)\n      src_lineptrs[y + limit] = srcp + src_pitch * 0;\n    else if (y < height)\n      src_lineptrs[y + limit] = srcp + src_pitch * y;\n    else\n      src_lineptrs[y + limit] = srcp + src_pitch * (height - 1);\n  }\n\n  std::vector<const float *> src_current_lineptrs(matrix_size); // +/-limit => 2*limit + 1\n\n  for (int y = 0; y < height; ++y) {\n    // prefill current vertical line pointers\n    for (int yy = -limit; yy <= limit; yy++) {\n      src_current_lineptrs[yy + limit] = src_lineptrs[limit + (y + yy)];\n    }\n    int x = 0;\n    // left area: check valid x\n    for (; x < limit; x++)\n    {\n      float sum = 0.0f;\n      const float *current_matrix = matrix + limit; // center of the matrix line\n      for (int yy = 0; yy < matrix_size; yy++) { // 0..limit * 2 + 1\n        const float *current_line = src_current_lineptrs[yy];\n        for (int xx = -limit; xx <= limit; xx++) {\n          int current_x = x + xx;\n          if (current_x < 0) current_x = 0;\n          else if (current_x >= width) current_x = width - 1;\n          const float current_pixel = current_line[current_x];\n          const float current_weight = current_matrix[xx];\n          sum += current_pixel * current_weight;\n        }\n        current_matrix += matrix_size; // next matrix line\n      }\n      float result = sum * fCountDiv + fBias;\n      dstp[x] = result; // no clipping for float\n    }\n    // middle area: no x check: fast!\n    for (; x < width - limit; x++) {\n      float sum = 0.0f;\n      const float *current_matrix = matrix + limit; // center of the matrix line\n      for (int yy = 0; yy < matrix_size; yy++) { // 0..limit * 2 + 1\n        const float *current_line = src_current_lineptrs[yy];\n        // compilers are smart nowadays but let's help them\n        if constexpr (matrix_size == 3) {\n          sum +=\n            current_line[x - 1] * current_matrix[-1] +\n            current_line[x + 0] * current_matrix[0] +\n            current_line[x + 1] * current_matrix[1];\n        }\n        else if constexpr (matrix_size == 5) {\n          sum +=\n            current_line[x - 2] * current_matrix[-2] +\n            current_line[x - 1] * current_matrix[-1] +\n            current_line[x + 0] * current_matrix[0] +\n            current_line[x + 1] * current_matrix[1] +\n            current_line[x + 2] * current_matrix[2];\n        }\n        else {\n          // surprise: even MSVC unrolls this loop for 7 and 9\n          for (int xx = -limit; xx <= limit; xx++) {\n            int current_x = x + xx;\n            // no checking!\n            /*if (current_x < 0) current_x = 0;\n            else if (current_x >= width) current_x = width - 1;*/\n            const float current_pixel = current_line[current_x];\n            const float current_weight = current_matrix[xx];\n            sum += current_pixel * current_weight;\n          }\n        }\n        current_matrix += matrix_size; // next matrix line\n      }\n      float result = sum * fCountDiv + fBias;\n      dstp[x] = result; // no clipping for float\n    }\n    // right area: check valid x\n    for (; x < width; x++)\n    {\n      float sum = 0.0f;\n      const float *current_matrix = matrix + limit; // center of the matrix line\n      for (int yy = 0; yy < matrix_size; yy++) { // 0..limit * 2 + 1\n        const float *current_line = src_current_lineptrs[yy];\n        for (int xx = -limit; xx <= limit; xx++) {\n          int current_x = x + xx;\n          if (current_x < 0) current_x = 0;\n          else if (current_x >= width) current_x = width - 1;\n          const float current_pixel = current_line[current_x];\n          const float current_weight = current_matrix[xx];\n          sum += current_pixel * current_weight;\n        }\n        current_matrix += matrix_size; // next matrix line\n      }\n      float result = sum * fCountDiv + fBias;\n      dstp[x] = result; // no clipping for float\n    }\n    dstp += dst_pitch;\n    srcp += src_pitch;\n  }\n}\n\ntemplate void do_conv_float<3>(BYTE* dstp8, int dst_pitch, const BYTE *srcp8, int src_pitch, int width, int height, const float *matrix, float fCountDiv, float fBias);\ntemplate void do_conv_float<5>(BYTE* dstp8, int dst_pitch, const BYTE *srcp8, int src_pitch, int width, int height, const float *matrix, float fCountDiv, float fBias);\ntemplate void do_conv_float<7>(BYTE* dstp8, int dst_pitch, const BYTE *srcp8, int src_pitch, int width, int height, const float *matrix, float fCountDiv, float fBias);\ntemplate void do_conv_float<9>(BYTE* dstp8, int dst_pitch, const BYTE *srcp8, int src_pitch, int width, int height, const float *matrix, float fCountDiv, float fBias);\n\n/***** Setup stuff ****/\n\nGeneralConvolution::GeneralConvolution(PClip _child, double _divisor, float _nBias, const char * _matrix,\n  bool _autoscale, bool _luma, bool _chroma, bool _alpha, IScriptEnvironment* _env)\n  : GenericVideoFilter(_child), divisor(_divisor), nBias((int)_nBias), fBias(_nBias), autoscale(_autoscale), luma(_luma), chroma(_chroma), alpha(_alpha)\n{\n  if (vi.Is420() || vi.Is422() || vi.IsYV411()) {\n    if (luma && chroma)\n      _env->ThrowError(\"GeneralConvolution: both luma and chroma cannot be set for subsampled video formats\");\n  }\n  if (!vi.IsRGB() && !vi.IsYUV() && !vi.IsYUVA())\n    _env->ThrowError(\"GeneralConvolution requires RGB (planar or packed), greyscale or YUV(A) input\");\n  if (divisor == 0.0)\n    _env->ThrowError(\"GeneralConvolution: divisor cannot be zero\");\n  setMatrix(_matrix, vi.BitsPerComponent() < 32, _env); // float: todo\n\n  if (vi.BitsPerComponent() <= 16) {\n    // precompute divisor\n    int iCountT;\n    if (autoscale) {\n      iCountT = iNormalizeSum;\n    }\n    else {\n      iCountT = 0;\n    }\n\n    // Truncate instead of round - keep in the spirit of the original code\n    // 3.6.3: we do introduce rounding before scaling back from +20 bit range\n    // 0x100000: 20 bit precision integer arithmetic\n    // todo: check overflow for matrices larger than 5x5\n    iCountDiv = (int)(0x100000 / (iCountT == 0 ? divisor : iCountT * divisor));\n    if (iCountDiv == 0)\n      _env->ThrowError(\"GeneralConvolution: normalizing factor is zero, check for too large elements or divisor value\");\n\n    // safety check\n    int64needed = false;\n\n    // check possible overflow:\n    // Worst case: maximum pixel values, matrix multiplications will overflow either on positive or negative direction\n    // When max_pixel_value * sum(max(weight_pos, -weight_neg)) * iCountDiv > 1 << 31 = > int64_t needed(safe_int_t is int64_t)\n    const int max_pixel_value = (1 << vi.BitsPerComponent()) - 1;\n    const int maxWeightSum = max(iWeightSumPositives, -iWeightSumNegatives);\n    if ((int64_t)max_pixel_value * maxWeightSum * std::abs(iCountDiv) >= std::numeric_limits<int>::max())\n      int64needed = true;\n\n    switch (vi.BitsPerComponent()) {\n\n    case 8:\n      if (nSize == 3 * 3) {\n        if (int64needed) conversionFnPtr = do_conv_integer<uint8_t, 3, int64_t>;\n        else conversionFnPtr = do_conv_integer<uint8_t, 3, int>;\n      }\n      else if (nSize == 5 * 5) {\n        if (int64needed) conversionFnPtr = do_conv_integer<uint8_t, 5, int64_t>;\n        else conversionFnPtr = do_conv_integer<uint8_t, 5, int>;\n      }\n      else if (nSize == 7 * 7) {\n        if (int64needed) conversionFnPtr = do_conv_integer<uint8_t, 7, int64_t>;\n        else conversionFnPtr = do_conv_integer<uint8_t, 7, int>;\n      }\n      else if (nSize == 9 * 9) {\n        if (int64needed) conversionFnPtr = do_conv_integer<uint8_t, 9, int64_t>;\n        else conversionFnPtr = do_conv_integer<uint8_t, 9, int>;\n      }\n      break;\n\n    case 10:\n    case 12:\n    case 14:\n    case 16:\n      if (nSize == 3 * 3) {\n        if (int64needed) conversionFnPtr = do_conv_integer<uint16_t, 3, int64_t>;\n        else conversionFnPtr = do_conv_integer<uint16_t, 3, int>;\n      }\n      else if (nSize == 5 * 5) {\n        if (int64needed) conversionFnPtr = do_conv_integer<uint16_t, 5, int64_t>;\n        else conversionFnPtr = do_conv_integer<uint16_t, 5, int>;\n      }\n      else if (nSize == 7 * 7) {\n        if (int64needed) conversionFnPtr = do_conv_integer<uint16_t, 7, int64_t>;\n        else conversionFnPtr = do_conv_integer<uint16_t, 7, int>;\n      }\n      else if (nSize == 9 * 9) {\n        if (int64needed) conversionFnPtr = do_conv_integer<uint16_t, 9, int64_t>;\n        else conversionFnPtr = do_conv_integer<uint16_t, 9, int>;\n      }\n      break;\n    }\n  }\n  else {\n    // 32 bit float clip\n    // precompute divisor\n    float fCountT;\n    if (autoscale) {\n      fCountT = fNormalizeSum;\n    }\n    else {\n      fCountT = 0.0f;\n    }\n\n    fCountDiv = (float)(1.0f / (fCountT == 0 ? divisor : fCountT * divisor));\n\n    if (nSize == 3 * 3)\n      FconversionFnPtr = do_conv_float<3>;\n    else if (nSize == 5 * 5)\n      FconversionFnPtr = do_conv_float<5>;\n    else if (nSize == 7 * 7)\n      FconversionFnPtr = do_conv_float<7>;\n    else if (nSize == 9 * 9)\n      FconversionFnPtr = do_conv_float<9>;\n  }\n}\n\nAVSValue __cdecl GeneralConvolution::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  const VideoInfo& vi_orig = args[0].AsClip()->GetVideoInfo();\n\n  // convert old RGB format to planar RGB\n  AVSValue new_args[1] = { args[0].AsClip() };\n  PClip clip;\n  if (vi_orig.IsRGB24() || vi_orig.IsRGB48()) {\n    clip = env->Invoke(\"ConvertToPlanarRGB\", AVSValue(new_args, 1)).AsClip();\n  }\n  else if (vi_orig.IsRGB32() || vi_orig.IsRGB64()) {\n    clip = env->Invoke(\"ConvertToPlanarRGBA\", AVSValue(new_args, 1)).AsClip();\n  }\n  else if (vi_orig.IsYUY2()) {\n    clip = env->Invoke(\"ConvertToYV16\", AVSValue(new_args, 1)).AsClip();\n  }\n  else {\n    clip = args[0].AsClip();\n  }\n\n  GeneralConvolution* Result = new GeneralConvolution(clip, args[3].AsFloat(1.0f), args[1].AsFloatf(0.0f),\n    args[2].AsString(\"0 0 0 0 1 0 0 0 0\"), args[4].AsBool(true),\n    args[5].AsBool(true), args[6].AsBool(true), args[7].AsBool(true), // luma, chroma, alpha, when n/a then ignored\n    env);\n\n  AVSValue new_args2[1] = { Result };\n  if (vi_orig.IsRGB24()) {\n    return env->Invoke(\"ConvertToRGB24\", AVSValue(new_args2, 1)).AsClip();\n  }\n  else if (vi_orig.IsRGB48()) {\n    return env->Invoke(\"ConvertToRGB48\", AVSValue(new_args2, 1)).AsClip();\n  }\n  else if (vi_orig.IsRGB32()) {\n    return env->Invoke(\"ConvertToRGB32\", AVSValue(new_args2, 1)).AsClip();\n  }\n  else if (vi_orig.IsRGB64()) {\n    return env->Invoke(\"ConvertToRGB64\", AVSValue(new_args2, 1)).AsClip();\n  }\n  else if (vi_orig.IsYUY2()) {\n    return env->Invoke(\"ConvertToYUY2\", AVSValue(new_args2, 1)).AsClip();\n  }\n\n  return Result;\n}\n\n\nvoid GeneralConvolution::setMatrix(const char * _matrix, bool _isInteger, IScriptEnvironment* env)\n{\n  char delimiter[] = \"([ \\t\\n\\r]+)\";\n  std::regex regex(delimiter);\n  std::string str(_matrix);\n  std::vector<std::string> out(\n    std::sregex_token_iterator(str.begin(), str.end(), regex, -1),\n    std::sregex_token_iterator()\n  );\n\n  fNormalizeSum = 0.0f;\n  iNormalizeSum = 0;\n  iWeightSumPositives = 0; // for int32 overflow decision\n  iWeightSumNegatives = 0;\n  const int MAX_DIMENSION = 9; // 9 is the max matrix size which is templated\n\n  nSize = 0;\n  int dim = 3;\n  int maxsize = dim * dim;\n  if (_isInteger)\n    iMatrix.resize(maxsize);\n  else\n    fMatrix.resize(maxsize);\n  for (auto &s : out) {\n    if (s.length() == 0) continue; // first string can be empty is matrix string is starting with separators\n\n    if (nSize == maxsize) {\n      if (dim == MAX_DIMENSION) {\n        env->ThrowError(\"GeneralConvolution: matrix too big, maximum %dx%d elements allowed\", MAX_DIMENSION, MAX_DIMENSION);\n      }\n      dim += 2;\n      maxsize = dim * dim;\n      if (_isInteger)\n        iMatrix.resize(maxsize);\n      else\n        fMatrix.resize(maxsize);\n    }\n    if (_isInteger) {\n      const double val = atof(s.c_str());\n      const int ival = (int)std::lround(val);\n      iNormalizeSum += ival;\n      iMatrix[nSize++] = ival;\n      if (ival >= 0)\n        iWeightSumPositives += ival;\n      else\n        iWeightSumNegatives += ival;\n    }\n    else {\n      const float val = (float)atof(s.c_str());\n      fNormalizeSum += val;\n      fMatrix[nSize++] = val;\n    }\n\n  }\n\n  if (nSize < 9)\n    env->ThrowError(\"GeneralConvolution: matrix too small, need at least 3x3 elements\");\n  else if (nSize != maxsize)\n    env->ThrowError(\"GeneralConvolution: matrix incomplete, possible size %dx%d but element count %d\", dim, dim, nSize);\n}\n\nPVideoFrame __stdcall GeneralConvolution::GetFrame(int n, IScriptEnvironment* env)\n{\n  int h = vi.height;\n  int w = vi.width;\n\n  PVideoFrame src = child->GetFrame(n, env);\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n\n  const int *matrix = iMatrix.data();\n  const float *matrixf = fMatrix.data();\n\n  int planes_y[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };\n  int planes_r[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A };\n  int *planes = (vi.IsYUV() || vi.IsYUVA()) ? planes_y : planes_r;\n  for (int p = 0; p < vi.NumComponents(); ++p) {\n    const int plane = planes[p];\n    if ((plane == PLANAR_Y && !luma) ||\n        ((plane == PLANAR_U || plane == PLANAR_V) && !chroma) ||\n        (plane == PLANAR_A && !alpha))\n    {\n      env->BitBlt(dst->GetWritePtr(plane), dst->GetPitch(plane), src->GetReadPtr(plane), src->GetPitch(plane), src->GetRowSize(plane), src->GetHeight(plane));\n      continue;\n    }\n\n    int width = w;\n    int height = h;\n    if (plane == PLANAR_U || plane == PLANAR_V) {\n      width >>= vi.GetPlaneWidthSubsampling(plane);\n      height >>= vi.GetPlaneHeightSubsampling(plane);\n    }\n\n    if(vi.BitsPerComponent() <= 16)\n      conversionFnPtr(dst->GetWritePtr(plane), dst->GetPitch(plane), src->GetReadPtr(plane), src->GetPitch(plane), width, height, matrix, iCountDiv, nBias, vi.BitsPerComponent());\n    else\n      FconversionFnPtr(dst->GetWritePtr(plane), dst->GetPitch(plane), src->GetReadPtr(plane), src->GetPitch(plane), width, height, matrixf, fCountDiv, fBias);\n  }\n  return dst;\n  // really, not other case left... packed RGB was converted to planar RGB, YUY2 to YV16\n}\n"
  },
  {
    "path": "avs_core/filters/convolution.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n\n// Avisynth filter: general convolution 3d\n// by Richard Berg (avisynth-dev@richardberg.net)\n// adapted from General Convolution 3D for VDub by Gunnar Thalin (guth@home.se)\n\n#ifndef __GeneralConvolution_H__\n#define __GeneralConvolution_H__\n\n#include <avisynth.h>\n#include <vector>\n\n/*****************************************\n****** General Convolution 2D filter *****\n*****************************************/\n\n\nclass GeneralConvolution : public GenericVideoFilter\n/** This class exposes a video filter that applies general convolutions -- up to a 5x5\n  * kernel -- to a clip.  Smaller (3x3) kernels have their own code path.  SIMD support forthcoming.\n **/\n{\n  using do_conv_int_t = void(BYTE* dstp8, int dst_pitch, const BYTE *srcp8, int src_pitch, int width, int height, const int *matrix, int iCountDiv, int iBias, int bits_per_pixel);\n  using do_conv_float_t = void(BYTE* dstp8, int dst_pitch, const BYTE *srcp8, int src_pitch, int width, int height, const float *matrix, float fCountDiv, float fBias);\n\npublic:\n    GeneralConvolution(PClip _child, double _divisor, float _nBias, const char * _matrix, bool _autoscale, bool _luma, bool _chroma, bool _alpha, IScriptEnvironment* _env);\n    PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n    static AVSValue __cdecl Create(AVSValue args, void* user_data, IScriptEnvironment* env);\n\n    int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n      AVS_UNUSED(frame_range);\n      return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n    }\n\nprotected:\n    void setMatrix(const char * _matrix, bool _isinteger, IScriptEnvironment* env);\n\nprivate:\n    double divisor;\n    size_t nSize;\n    int nBias;\n    float fBias;\n    bool autoscale;\n\n    int iCountDiv;\n    float fCountDiv;\n    bool int64needed;\n\n    bool luma;\n    bool chroma;\n    bool alpha;\n\n    std::vector<int> iMatrix;\n    std::vector<float> fMatrix;\n    float fNormalizeSum;\n    int iNormalizeSum;\n    int iWeightSumPositives;\n    int iWeightSumNegatives;\n\n    do_conv_int_t *conversionFnPtr;\n    do_conv_float_t *FconversionFnPtr;\n\n};\n\n\n\n#endif  // __GeneralConvolution_H__\n"
  },
  {
    "path": "avs_core/filters/debug.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include \"debug.h\"\n\n#ifdef AVS_WINDOWS\n    #include <avs/win.h>\n#else\n    #include <avs/posix.h>\n#endif\n\n#include \"../core/bitblt.h\"\n#include \"../core/internal.h\"\n\n\n\n/**********************************************\n *******  PlanarLegacyAlignment Filter  *******\n *******  for pitch challenged plugins  *******\n **********************************************/\n\nclass PlanarLegacyAlignment : public GenericVideoFilter\n{\nprivate:\n  const IScriptEnvironment::PlanarChromaAlignmentMode mode;\n\npublic:\n  PlanarLegacyAlignment( PClip _child, const bool _mode, IScriptEnvironment* env )\n    : GenericVideoFilter(_child),\n    mode(_mode ?  IScriptEnvironment::PlanarChromaAlignmentOff  // Legacy PLANAR_Y alignment\n            : IScriptEnvironment::PlanarChromaAlignmentOn)  // New PLANAR_UV priority alignment\n  {\n    AVS_UNUSED(env);\n  }\n\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env)\n  {\n  const IScriptEnvironment::PlanarChromaAlignmentMode\n    oldmode = env->PlanarChromaAlignment(mode)            // Set the PLANAR alignement mode\n            ? IScriptEnvironment::PlanarChromaAlignmentOn\n            : IScriptEnvironment::PlanarChromaAlignmentOff;\n\n  PVideoFrame src = child->GetFrame(n, env);              // run the GetFrame chain\n\n  env->PlanarChromaAlignment(oldmode);                    // reset the PLANAR alignement mode\n\n  return src;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env)\n  {\n  return new PlanarLegacyAlignment(args[0].AsClip(), args[1].AsBool(), env);\n  }\n\n};\n\n\n\n/***********************************************\n *******  Echo Filter  *******\n *******  Call GetFrame on all source clips*****\n ***********************************************/\n\nclass Echo : public GenericVideoFilter\n{\nprivate:\n  const int ClipCount;\n  PClip *clips;\n\npublic:\n  Echo( PClip _child, const AVSValue _clips, IScriptEnvironment* env )\n     : GenericVideoFilter(_child), ClipCount(_clips.ArraySize()) {\n    AVS_UNUSED(env);\n\n    clips = new PClip[ClipCount];\n    for (int i=0; i < ClipCount; i++)\n      clips[i] = _clips[i].AsClip();\n  }\n\n  ~Echo() {\n    delete[] clips;\n    clips = 0;\n  }\n\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) {\n\n  PVideoFrame src = child->GetFrame(n, env);\n\n    for (int i=0; i < ClipCount; i++)\n      clips[i]->GetFrame(n, env);           // run the GetFrame chains\n\n    return src;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env) {\n    return new Echo(args[0].AsClip(), args[1], env);\n  }\n\n};\n\n\n\n/***********************************************\n ******  Preroll GetFrame/GetAudio Filter ******\n ***********************************************/\n\nclass Preroll : public GenericVideoFilter\n{\nprivate:\n  const int videopr;\n  const int64_t audiopr;\n\n  int videonext;\n  int64_t audionext;\n\npublic:\n  Preroll( PClip _child, const int _videopr, const double _audiopr, IScriptEnvironment* env )\n    : GenericVideoFilter(_child),\n      videopr(_videopr),\n      audiopr(int64_t(_audiopr*vi.audio_samples_per_second+0.5)),\n      videonext(0),\n      audionext(0) {\n\n    AVS_UNUSED(env);\n    // Force source filter to honour preroll\n    child->SetCacheHints(CACHE_NOTHING, 0);       // Disable Video cache\n    child->SetCacheHints(CACHE_AUDIO_NOTHING, 0); // Disable Audio cache\n  }\n\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) {\n    if (n != videonext) {\n      int i = n - videopr;\n      if (i < 0) i = 0;\n\n      // Optimise if n is within pr frames of last\n      if (i < videonext && n > videonext) i = videonext;\n\n      while (i < n) {\n        child->GetFrame(i, env);\n        i += 1;\n      }\n    }\n\n    videonext = n+1;\n    return child->GetFrame(n, env);\n  }\n\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) {\n    if (start != audionext) {\n      int64_t s = start - audiopr;\n      if (s < 0) s = 0;\n\n      // Optimise if start is within pr sample of last\n      if (s < audionext && start > audionext) s = audionext;\n\n      while (s < start) {\n        int64_t c = start - s;\n        if (c > count) c = count;\n\n        child->GetAudio(buf, s, c, env);\n        s += c;\n      }\n    }\n\n    audionext = start+count;\n    child->GetAudio(buf, start, count, env);\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env) {\n    return new Preroll(args[0].AsClip(), args[1].AsInt(0), (float)args[2].AsDblDef(0.0), env);\n  }\n\n};\n\n\n\n/********************************************************************\n***** Declare index of new filters for Avisynth's filter engine *****\n********************************************************************/\n\nextern const AVSFunction Debug_filters[] = {\n  { \"Null\", BUILTIN_FUNC_PREFIX, \"c[copy]s\", Null::Create },     // clip, copy\n  { \"SetPlanarLegacyAlignment\", BUILTIN_FUNC_PREFIX, \"cb\", PlanarLegacyAlignment::Create },     // clip, legacy alignment\n  { \"Echo\", BUILTIN_FUNC_PREFIX, \"cc+\", Echo::Create },\n  { \"Preroll\", BUILTIN_FUNC_PREFIX, \"c[video]i[audio]f\", Preroll::Create },\n  { NULL }\n};\n\n\n\n/*******************************\n *******   Null Filter   *******\n *******  for debugging  *******\n ******************************/\n\nNull::Null(PClip _child, const char * _copy, IScriptEnvironment* env)\n  : GenericVideoFilter(_child), copy(_copy)\n{\n  AVS_UNUSED(env);\n}\n\nNull::~Null()\n{\n}\n\n\nPVideoFrame __stdcall Null::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame src = child->GetFrame(n, env);\n\n  BYTE * foo = new BYTE[256];\n  BYTE * bar = new BYTE[256];\n  MemDebug md;\n\n  md.randomFill(foo, 8, 8, 8);\n  env->BitBlt(bar, 8, foo, 8, 8, 8);\n\n  md.reset();\n  int i = md.randomCheck(bar, 9, 8, 8);\n\n  if (i)\n    env->ThrowError(\"bug found\");\n\n  delete [] foo;\n  delete [] bar;\n\n  if (!lstrcmpi(copy, \"makewritable\"))\n  {\n    env->MakeWritable(&src);\n    return src;\n  }\n\n  // TODO: no support for planar formats!\n  if (!lstrcmpi(copy, \"memcopy\"))\n  {\n    PVideoFrame dst = env->NewVideoFrame(child->GetVideoInfo(), 16);\n    if (dst->IsWritable() == false)\n      env->ThrowError(\"new frame not writable\"); // honestly don't know whether to expect this condition\n\n    memcpy( dst->GetWritePtr(), src->GetReadPtr(), src->GetPitch() * src->GetHeight() );\n    return dst;\n  }\n\n  if (!lstrcmpi(copy, \"bitblt\"))\n  {\n    PVideoFrame dst = env->NewVideoFrame(child->GetVideoInfo(), 16);\n    if (dst->IsWritable() == false)\n      env->ThrowError(\"new frame not writable\"); // honestly don't know whether to expect this condition\n\n    env->BitBlt( dst->GetWritePtr(), src->GetPitch(), src->GetReadPtr(), src->GetPitch(),\n            src->GetRowSize(), src->GetHeight() );\n    return dst;\n  }\n\n  //if (!lstrcmpi(copy, \"none\"))\n    // do nothing\n  return src;\n}\n\nAVSValue __cdecl Null::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  return new Null(args[0].AsClip(), args[1].AsString(\"none\"), env);\n}\n\n\n\n\nMemDebug::MemDebug() : mask(0xff)\n{\n  reset();\n}\n\n\nMemDebug::~MemDebug()\n{\n}\n\n\n// fills a buffer with \"random\" (the same every time) data we can\n// test for after some manipulation (e.g. BitBlt)\nvoid MemDebug::randomFill(BYTE* const buf, const int pitch, const int row_size, const int height)\n{\n  for(int x=0; x<height; ++x)\n  {\n    for(int y=0; y<row_size; ++y)\n    {\n      buf[x*pitch + y] = nextNum();\n    }\n  }\n}\n\n\n// checks a buffer to see if \"random\" data is intact or copied correctly\n// return value == offset of first discrepancy, or 0 if all's well\nint MemDebug::randomCheck(BYTE* const buf, const int pitch, const int row_size, const int height)\n{\n  for(int x=0; x<height; ++x)\n  {\n    for(int y=0; y<row_size; ++y)\n    {\n      int n = nextNum();\n      if (buf[x*pitch + y] != n) return x*pitch + y;\n    }\n  }\n\n  return 0;\n}\n\n\nchar MemDebug::nextNum()\n{\n  ++whichByte;\n  whichByte &= 3;\n  if (whichByte == 0)\n  {\n    randNum *= 0x41c64e6d;\n    randNum += 0x3039;\n  }\n\n  return char((randNum & (mask << (whichByte * 8))) >> (whichByte * 8));\n}\n\n\nvoid MemDebug::reset()\n{\n  randNum = -591377182;  // pulled out of my ass\n  whichByte = 3;\n}\n"
  },
  {
    "path": "avs_core/filters/debug.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n\n\n\n#ifndef __Null_H__\n#define __Null_H__\n\n#include <avisynth.h>\n\n\nclass Null : public GenericVideoFilter\n/**\n  * Class for debugging Avisynth internals.\n **/\n{\npublic:\n  Null( PClip _child, const char * _copy, IScriptEnvironment* env );\n  virtual ~Null(void);\n\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\nprivate:\n  const char* copy;\n};\n\n\nclass MemDebug\n{\npublic:\n  MemDebug(void);\n  virtual ~MemDebug(void);\n\n  void randomFill(BYTE* const buf, const int pitch, const int row_size, const int height);\n  int randomCheck(BYTE* const buf, const int pitch, const int row_size, const int height);\n\n  void reset();\n\nprivate:\n  char nextNum();\n\n  int randNum;\n  int whichByte;\n  const int mask;\n};\n\n\n#endif  // __Null_H__"
  },
  {
    "path": "avs_core/filters/edit.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include \"edit.h\"\n#include \"../convert/convert_audio.h\"\n#include \"../core/internal.h\"\n#include \"merge.h\"\n#include <climits>\n#include <cmath>\n\n#ifdef AVS_WINDOWS\n    #include <avs/win.h>\n#else\n    #include <avs/posix.h>\n#endif\n\n#include <avs/minmax.h>\n#include <avs/alignment.h>\n#include <stdint.h>\n#include <utility>\n\n\n\n/********************************************************************\n***** Declare index of new filters for Avisynth's filter engine *****\n********************************************************************/\n\nenum { FADE_MODE_OUT0, FADE_MODE_OUT, FADE_MODE_OUT2, FADE_MODE_IN0, FADE_MODE_IN, FADE_MODE_IN2, FADE_MODE_IO0, FADE_MODE_IO, FADE_MODE_IO2 };\n\nextern const AVSFunction Edit_filters[] = {\n  { \"AudioTrim\", BUILTIN_FUNC_PREFIX, \"cff[cache]b\",          Trim::CreateA, (void*)Trim::Default}, // start time, end time\n  { \"AudioTrim\", BUILTIN_FUNC_PREFIX, \"cf[cache]b\",           Trim::CreateA, (void*)Trim::Invalid}, // Throw Invalid argument to AudioTrim because 4 parameters expected\n  { \"AudioTrim\", BUILTIN_FUNC_PREFIX, \"cf[length]f[cache]b\",  Trim::CreateA, (void*)Trim::Length},  // start time, duration\n  { \"AudioTrim\", BUILTIN_FUNC_PREFIX, \"cf[end]f[cache]b\",     Trim::CreateA, (void*)Trim::End},     // start time, end time\n  { \"Trim\", BUILTIN_FUNC_PREFIX, \"cii[pad]b[cache]b\",         Trim::Create,  (void*)Trim::Default}, // first frame, last frame[, pad audio]\n  { \"Trim\", BUILTIN_FUNC_PREFIX, \"ci[pad]b[cache]b\",          Trim::Create,  (void*)Trim::Invalid}, // Throw Invalid argument to Trim because 5 parameters expected\n  { \"Trim\", BUILTIN_FUNC_PREFIX, \"ci[length]i[pad]b[cache]b\", Trim::Create,  (void*)Trim::Length},  // first frame, frame count[, pad audio]\n  { \"Trim\", BUILTIN_FUNC_PREFIX, \"ci[end]i[pad]b[cache]b\",    Trim::Create,  (void*)Trim::End},     // first frame, last frame[, pad audio]\n  { \"FreezeFrame\", BUILTIN_FUNC_PREFIX, \"ciii\", FreezeFrame::Create },           // first frame, last frame, source frame\n  { \"DeleteFrame\", BUILTIN_FUNC_PREFIX, \"ci+\", DeleteFrame::Create },            // frame #\n  { \"DuplicateFrame\",  BUILTIN_FUNC_PREFIX, \"ci+\", DuplicateFrame::Create },      // frame #\n  { \"UnalignedSplice\", BUILTIN_FUNC_PREFIX, \"cc+\", Splice::CreateUnaligned },    // clips\n  { \"AlignedSplice\", BUILTIN_FUNC_PREFIX, \"cc+\", Splice::CreateAligned },        // clips\n  { \"UnalignedSplice\", BUILTIN_FUNC_PREFIX, \"cci\", Splice::CreateUnalignedNoCache },    // clips\n  { \"AlignedSplice\", BUILTIN_FUNC_PREFIX, \"cci\", Splice::CreateAlignedNoCache },        // clips\n  { \"Dissolve\",   BUILTIN_FUNC_PREFIX, \"cc+i[fps]f\", Dissolve::Create },           // clips, overlap frames[, fps]\n  { \"AudioDub\",   BUILTIN_FUNC_PREFIX, \"cc\", AudioDub::Create, (void*)0},          // video src, audio src\n  { \"AudioDubEx\", BUILTIN_FUNC_PREFIX, \"cc\", AudioDub::Create, (void*)1},        // video! src, audio! src\n  { \"Reverse\",  BUILTIN_FUNC_PREFIX, \"c\", Reverse::Create },                      // plays backwards\n  { \"FadeOut0\", BUILTIN_FUNC_PREFIX, \"ci[color]i[fps]f[color_yuv]i[colors]f+\", Create_Fade, (void*)FADE_MODE_OUT0 },\n  { \"FadeOut\",  BUILTIN_FUNC_PREFIX, \"ci[color]i[fps]f[color_yuv]i[colors]f+\", Create_Fade, (void*)FADE_MODE_OUT },\n  { \"FadeOut2\", BUILTIN_FUNC_PREFIX, \"ci[color]i[fps]f[color_yuv]i[colors]f+\", Create_Fade, (void*)FADE_MODE_OUT2 },\n  { \"FadeIn0\",  BUILTIN_FUNC_PREFIX, \"ci[color]i[fps]f[color_yuv]i[colors]f+\", Create_Fade, (void*)FADE_MODE_IN0 },\n  { \"FadeIn\",   BUILTIN_FUNC_PREFIX, \"ci[color]i[fps]f[color_yuv]i[colors]f+\", Create_Fade, (void*)FADE_MODE_IN },\n  { \"FadeIn2\",  BUILTIN_FUNC_PREFIX, \"ci[color]i[fps]f[color_yuv]i[colors]f+\", Create_Fade, (void*)FADE_MODE_IN2 },\n  { \"FadeIO0\",  BUILTIN_FUNC_PREFIX, \"ci[color]i[fps]f[color_yuv]i[colors]f+\", Create_Fade, (void*)FADE_MODE_IO0 },\n  { \"FadeIO\",   BUILTIN_FUNC_PREFIX, \"ci[color]i[fps]f[color_yuv]i[colors]f+\", Create_Fade, (void*)FADE_MODE_IO },\n  { \"FadeIO2\",  BUILTIN_FUNC_PREFIX, \"ci[color]i[fps]f[color_yuv]i[colors]f+\", Create_Fade, (void*)FADE_MODE_IO2 },\n  { \"Loop\",     BUILTIN_FUNC_PREFIX, \"c[times]i[start]i[end]i\", Loop::Create },      // number of loops, first frame, last frames\n  { NULL }\n};\n\n\n\n/******************************\n *******   NonCachedGenericVideoFilter Filter   ******\n ******************************/\n\nNonCachedGenericVideoFilter::NonCachedGenericVideoFilter(PClip _child) :\n  GenericVideoFilter(_child)\n{\n};\n\n\nint __stdcall NonCachedGenericVideoFilter::SetCacheHints(int cachehints, int frame_range)\n{\n  switch(cachehints)\n  {\n    case CACHE_DONT_CACHE_ME:\n      return 1;\n    case CACHE_GET_MTMODE:\n      return MT_NICE_FILTER;\n\n    case CACHE_GET_DEV_TYPE:\n      return (child->GetVersion() >= 5) ? child->SetCacheHints(CACHE_GET_DEV_TYPE, 0) : 0;\n\n    default:\n      return GenericVideoFilter::SetCacheHints(cachehints, frame_range);\n  }\n}\n\n\n/******************************\n *******   AudioTrim Filter   ******\n ******************************/\n\nTrim::Trim(double starttime, double endtime, PClip _child, trim_mode_e mode, bool _cache, IScriptEnvironment* env)\n : GenericVideoFilter(_child), cache(_cache)\n{\n  int64_t esampleno = 0;\n\n  if (!vi.HasAudio())\n    env->ThrowError(\"AudioTrim: Cannot trim if there is no audio.\");\n\n  audio_offset = clamp(int64_t(starttime*vi.audio_samples_per_second + 0.5), (int64_t)0ll, vi.num_audio_samples);\n\n  switch (mode) {\n    case Default:\n    if (endtime == 0.0)\n    esampleno = vi.num_audio_samples;\n    else if (endtime < 0.0)\n    esampleno = int64_t((starttime-endtime)*vi.audio_samples_per_second + 0.5);\n    else\n    esampleno = int64_t(endtime*vi.audio_samples_per_second + 0.5);\n\n    break;\n  case Length:\n    if (endtime < 0.0)\n    env->ThrowError(\"AudioTrim: Length must be >= 0\");\n\n    esampleno = int64_t((starttime+endtime)*vi.audio_samples_per_second + 0.5);\n\n    break;\n  case End:\n    if (endtime < starttime)\n    env->ThrowError(\"AudioTrim: End must be >= Start\");\n\n    esampleno = int64_t(endtime*vi.audio_samples_per_second + 0.5);\n\n    break;\n  default:\n    env->ThrowError(\"Script error: Invalid arguments to function \\\"AudioTrim\\\"\");\n  }\n\n  if (esampleno > vi.num_audio_samples)\n  esampleno = vi.num_audio_samples;\n\n  vi.num_audio_samples = esampleno - audio_offset;\n\n  if (vi.num_audio_samples < 0)\n  vi.num_audio_samples = 0;\n\n  firstframe= vi.FramesFromAudioSamples(audio_offset); // Floor\n\n  if (endtime == 0.0 && mode == Default)\n  vi.num_frames -= firstframe;\n  else\n  vi.num_frames = vi.FramesFromAudioSamples(vi.num_audio_samples + vi.AudioSamplesFromFrames(1) - 1); // Ceil\n\n  if (vi.num_frames < 0)\n  vi.num_frames = 0;\n\n}\n\n\nAVSValue __cdecl Trim::CreateA(AVSValue args, void* user_arg, IScriptEnvironment* env)\n{\n    trim_mode_e mode = (trim_mode_e)size_t(user_arg);\n    if (mode == Trim::Invalid)\n        env->ThrowError(\"Script error: Invalid arguments to function \\\"AudioTrim\\\"\");\n\n    const bool cache = args[3].AsBool(true);\n\n    return new Trim(args[1].AsFloat(), args[2].AsFloat(), args[0].AsClip(), mode, cache, env);\n}\n\n\n/******************************\n *******   Trim Filter   ******\n ******************************/\n\nTrim::Trim(int _firstframe, int _lastframe, bool _padaudio, PClip _child, trim_mode_e mode, bool _cache, IScriptEnvironment* env)\n : GenericVideoFilter(_child), cache(_cache)\n{\n  int lastframe = 0;\n\n  if (!vi.HasVideo())\n    env->ThrowError(\"Trim: Cannot trim if there is no video.\");\n\n  firstframe = clamp(_firstframe, 0, vi.num_frames-1);\n\n  switch (mode) {\n    case Default:\n    if (_lastframe == 0)\n    lastframe = vi.num_frames-1;\n    else if (_lastframe < 0)\n    lastframe = firstframe - _lastframe - 1;\n    else\n    lastframe = _lastframe;\n\n    lastframe = clamp(lastframe, firstframe, vi.num_frames-1);\n\n    break;\n\n  case Length:\n    if (_lastframe < 0)\n    env->ThrowError(\"Trim: Length must be >= 0\");\n\n    lastframe = firstframe + _lastframe - 1;\n\n    if (lastframe > vi.num_frames-1)\n      lastframe = vi.num_frames-1;\n\n    break;\n\n  case End:\n    if (_lastframe < firstframe)\n    env->ThrowError(\"Trim: End must be >= Start\");\n\n    lastframe = _lastframe;\n\n    if (lastframe > vi.num_frames-1)\n      lastframe = vi.num_frames-1;\n\n    break;\n\n  default:\n    env->ThrowError(\"Script error: Invalid arguments to function \\\"Trim\\\"\");\n  }\n\n  vi.num_frames = lastframe+1 - firstframe;\n\n  audio_offset = vi.AudioSamplesFromFrames(firstframe);\n  if (_padaudio)\n    vi.num_audio_samples = vi.AudioSamplesFromFrames(lastframe+1) - audio_offset;\n  else {\n  int64_t samples;\n\n    if (_lastframe == 0 && mode == Default)\n      samples = vi.num_audio_samples;\n  else {\n    samples = vi.AudioSamplesFromFrames(lastframe+1);\n    if (samples > vi.num_audio_samples)\n    samples = vi.num_audio_samples;\n  }\n    if (audio_offset >= samples)\n      vi.num_audio_samples = 0;\n    else\n      vi.num_audio_samples = samples - audio_offset;\n  }\n}\n\n\nPVideoFrame Trim::GetFrame(int n, IScriptEnvironment* env)\n{\n  return child->GetFrame(n+firstframe, env);\n}\n\n\nvoid __stdcall Trim::GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env)\n{\n  child->GetAudio(buf, start+audio_offset, count, env);\n}\n\n\nbool Trim::GetParity(int n)\n{\n  return child->GetParity(n+firstframe);\n}\n\n\nAVSValue __cdecl Trim::Create(AVSValue args, void* user_arg, IScriptEnvironment* env)\n{\n    trim_mode_e mode = (trim_mode_e)size_t(user_arg);\n\n    if (mode == Trim::Invalid)\n        env->ThrowError(\"Script error: Invalid arguments to function \\\"Trim\\\"\");\n\n    const bool cache = args[4].AsBool(true);\n\n    return new Trim(args[1].AsInt(), args[2].AsInt(), args[3].AsBool(true), args[0].AsClip(), mode, cache, env);\n}\n\n\n\n\n\n\n\n\n/*******************************\n *******   Freeze Frame   ******\n *******************************/\n\nFreezeFrame::FreezeFrame(int _first, int _last, int _source, PClip _child)\n : GenericVideoFilter(_child), first(_first), last(_last), source(_source) {}\n\n\nPVideoFrame FreezeFrame::GetFrame(int n, IScriptEnvironment* env)\n{\n  return child->GetFrame((n >= first && n <= last) ? source : n, env);\n}\n\n\nbool FreezeFrame::GetParity(int n)\n{\n  return child->GetParity((n >= first && n <= last) ? source : n);\n}\n\n\nAVSValue __cdecl FreezeFrame::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  AVS_UNUSED(env);\n  return new FreezeFrame(args[1].AsInt(), args[2].AsInt(), args[3].AsInt(), args[0].AsClip());\n}\n\n\n/******************************\n *******   Delete Frame  ******\n ******************************/\n\nDeleteFrame::DeleteFrame(int _frame, PClip _child)\n : GenericVideoFilter(_child), frame(_frame) { --vi.num_frames; }\n\n\nPVideoFrame DeleteFrame::GetFrame(int n, IScriptEnvironment* env)\n{\n  return child->GetFrame(n + (n>=frame), env);\n}\n\n\nbool DeleteFrame::GetParity(int n)\n{\n  return child->GetParity(n + (n>=frame));\n}\n\n\nAVSValue __cdecl DeleteFrame::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  AVS_UNUSED(env);\n  const int n = args[1].ArraySize();\n  int m = n-1;\n  int *frames = new int[n];\n\n  frames[0] = args[1][0].AsInt();\n  for (int i=1; i<n; ++i) {\n    frames[i] = args[1][i].AsInt();\n    // Bubble insert\n    for (int j=0; j<i; ++j) {\n      // Remove duplicates\n      if (frames[i] == frames[j]) {\n        m -= 1;\n        frames[i] = INT_MAX;\n        break;\n      }\n      else if (frames[i] < frames[j]) {\n        const int t = frames[j];\n        frames[j] = frames[i];\n        frames[i] = t;\n      }\n    }\n  }\n  PClip result = args[0].AsClip();\n  for (int k=m; k>=0; --k)\n    result = new DeleteFrame(frames[k], result);\n\n  delete[] frames;\n  return result;\n}\n\n\n\n/*********************************\n *******   Duplicate Frame  ******\n *********************************/\n\nDuplicateFrame::DuplicateFrame(int _frame, PClip _child)\n : GenericVideoFilter(_child), frame(_frame) { ++vi.num_frames; }\n\n\nPVideoFrame DuplicateFrame::GetFrame(int n, IScriptEnvironment* env)\n{\n  return child->GetFrame(n - (n>frame), env);\n}\n\n\nbool DuplicateFrame::GetParity(int n)\n{\n  return child->GetParity(n - (n>frame));\n}\n\n\nAVSValue __cdecl DuplicateFrame::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  AVS_UNUSED(env);\n  const int n = args[1].ArraySize();\n  int *frames = new int[n];\n\n  frames[0] = args[1][0].AsInt();\n  for (int i=1; i<n; ++i) {\n    frames[i] = args[1][i].AsInt();\n    // Bubble insert\n    for (int j=0; j<i; ++j) {\n      if (frames[i] < frames[j]) {\n        const int t = frames[j];\n        frames[j] = frames[i];\n        frames[i] = t;\n      }\n    }\n  }\n  PClip result = args[0].AsClip();\n  for (int k=n-1; k>=0; --k)\n    result = new DuplicateFrame(frames[k], result);\n\n  delete[] frames;\n  return result;\n}\n\n\n\n/*******************************\n *******   Splice Filter  ******\n *******************************/\n\nSplice::Splice(PClip _child1, PClip _child2, bool realign_sound, bool _passCache, IScriptEnvironment* env)\n : GenericVideoFilter(_child1), child2(_child2), passCache(_passCache)\n{\n  VideoInfo vi2 = child2->GetVideoInfo();\n\n  if (vi.HasVideo() ^ vi2.HasVideo())\n    env->ThrowError(\"Splice: one clip has video and the other doesn't (not allowed)\");\n  if (vi.HasAudio() ^ vi2.HasAudio())\n    env->ThrowError(\"Splice: one clip has audio and the other doesn't (not allowed)\");\n\n\n  // Check video\n  if (vi.HasVideo()) {\n    if (vi.width != vi2.width || vi.height != vi2.height)\n      env->ThrowError(\"Splice: Frame sizes don't match\");\n\n    if (!vi.IsSameColorspace(vi2))\n      env->ThrowError(\"Splice: Video formats don't match\");\n\n    double fps_v1 = (double)vi.fps_numerator / (double)vi.fps_denominator;\n    double fps_v2 = (double)vi2.fps_numerator / (double)vi2.fps_denominator;\n    if (fabs(fps_v1-fps_v2) > 0.000001)\n      env->ThrowError(\"Splice: Video framerate doesn't match\");\n  }\n\n  // Check Audio\n  if (vi.HasAudio()) {\n    // If sample types do not match they are both converted to float samples to avoid loss of precision.\n    child2 = ConvertAudio::Create(child2, vi.SampleType(), SAMPLE_FLOAT);  // Clip 1 is check to be same type as clip 1, if not, convert to float samples.\n    vi2 = child2->GetVideoInfo();\n\n    child = ConvertAudio::Create(child, vi2.SampleType(), vi2.SampleType());  // Clip 1 is now be same type as clip 2.\n    vi = child->GetVideoInfo();\n\n    if (vi.AudioChannels() != vi2.AudioChannels())\n      env->ThrowError(\"Splice: The number of audio channels doesn't match\");\n\n    if (vi.SamplesPerSecond() != vi2.SamplesPerSecond())\n      env->ThrowError(\"Splice: The audio of the two clips have different samplerates! Use SSRC()/ResampleAudio()\");\n  }\n\n  video_switchover_point = vi.num_frames;\n\n  if (!video_switchover_point)  // We don't have video, so we cannot align sound to frames\n    realign_sound = false;\n\n  if (realign_sound)\n    audio_switchover_point = vi.AudioSamplesFromFrames(video_switchover_point);\n  else\n    audio_switchover_point = vi.num_audio_samples;\n\n  vi.num_frames += vi2.num_frames;\n\n  if (vi.num_frames < 0)\n    env->ThrowError(\"Splice: Maximum number of frames exceeded.\");\n\n  vi.num_audio_samples = audio_switchover_point + vi2.num_audio_samples;\n\n  child_devs = (GetDeviceTypes(child) & GetDeviceTypes(child2));\n}\n\n\nPVideoFrame Splice::GetFrame(int n, IScriptEnvironment* env)\n{\n  if (n < video_switchover_point)\n    return child->GetFrame(n, env);\n  else\n    return child2->GetFrame(n - video_switchover_point, env);\n}\n\n\nvoid Splice::GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env)\n{\n  if (start+count <= audio_switchover_point)\n    child->GetAudio(buf, start, count, env);\n  else if (start >= audio_switchover_point)\n    child2->GetAudio(buf, start - audio_switchover_point, count, env);\n  else {\n    const int64_t count1 = audio_switchover_point - start;\n    child->GetAudio(buf, start, count1, env);\n    child2->GetAudio((char*)buf+vi.BytesFromAudioSamples(count1), 0, count-count1, env);\n  }\n}\n\n\nbool Splice::GetParity(int n)\n{\n  if (n < video_switchover_point)\n    return child->GetParity(n);\n  else\n    return child2->GetParity(n - video_switchover_point);\n}\n\n\nint Splice::SetCacheHints(int cachehints,int frame_range)\n{\n  switch(cachehints)\n  {\n  case CACHE_DONT_CACHE_ME:\n    return 1;\n  case CACHE_GET_MTMODE:\n    return MT_NICE_FILTER;\n  case CACHE_GET_DEV_TYPE:\n    return child_devs;\n  default:\n    if (passCache) {\n      child2->SetCacheHints(cachehints, frame_range);\n      return child->SetCacheHints(cachehints, frame_range);\n    }\n    break;\n  }\n  return 0;  // We do not pass cache requests upwards.\n}\n\n\nAVSValue __cdecl Splice::CreateUnaligned(AVSValue args, void*, IScriptEnvironment* env)\n{\n  PClip result = args[0].AsClip();\n  for (int i=0; i<args[1].ArraySize(); ++i)\n    result = new Splice(result, args[1][i].AsClip(), false, false, env);\n  return result;\n}\n\n\n\nAVSValue __cdecl Splice::CreateAligned(AVSValue args, void*, IScriptEnvironment* env)\n{\n  PClip result = args[0].AsClip();\n  for (int i=0; i<args[1].ArraySize(); ++i)\n    result = new Splice(result, args[1][i].AsClip(), true, false, env);\n  return result;\n}\n\n\n\nAVSValue __cdecl Splice::CreateUnalignedNoCache(AVSValue args, void*, IScriptEnvironment* env)\n{\n  return new Splice(args[0].AsClip(), args[1].AsClip(), false, true, env);\n}\n\nAVSValue __cdecl Splice::CreateAlignedNoCache(AVSValue args, void*, IScriptEnvironment* env)\n{\n  return new Splice(args[0].AsClip(), args[1].AsClip(), true, true, env);\n}\n\n\n\n\n\n\n\n\n\n/*********************************\n *******   Dissolve Filter  ******\n *********************************/\n\n\nAVSValue __cdecl Dissolve::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  const int overlap = args[2].AsInt();\n  const double fps = args[3].AsDblDef(24.0);\n  PClip result = args[0].AsClip();\n  for (int i=0; i < args[1].ArraySize(); ++i)\n    result = new Dissolve(result, args[1][i].AsClip(), overlap, fps, env);\n  return result;\n}\n\n\nDissolve::~Dissolve()\n{\n  delete[] audbuffer;\n  audbuffer = 0;\n  audbufsize = 0;\n}\n\nDissolve::Dissolve(PClip _child1, PClip _child2, int _overlap, double fps, IScriptEnvironment* env)\n : GenericVideoFilter(ConvertAudio::Create(_child1,SAMPLE_INT16|SAMPLE_FLOAT,SAMPLE_FLOAT)),\n   child2(_child2),\n   overlap(_overlap),\n   audbuffer(0),\n   audbufsize(0)\n{\n  VideoInfo vi2 = child2->GetVideoInfo();\n\n  if (vi.HasVideo() ^ vi2.HasVideo())\n    env->ThrowError(\"Dissolve: one clip has video and the other doesn't (not allowed)\");\n  if (vi.HasAudio() ^ vi2.HasAudio())\n    env->ThrowError(\"Dissolve: one clip has audio and the other doesn't (not allowed)\");\n\n  if (overlap<0)\n    env->ThrowError(\"Dissolve: Cannot dissolve if overlap is less than zero\");\n\n  if (vi.HasAudio()) {\n    child2 = ConvertAudio::Create(child2, vi.SampleType(), SAMPLE_FLOAT);  // Clip 1 is check to be same type as clip 1, if not, convert to float samples.\n    vi2 = child2->GetVideoInfo();\n\n    child = ConvertAudio::Create(child, vi2.SampleType(), vi2.SampleType());  // Clip 1 is now be same type as clip 2.\n    vi = child->GetVideoInfo();\n\n    if (vi.AudioChannels() != vi2.AudioChannels())\n      env->ThrowError(\"Dissolve: The number of audio channels doesn't match\");\n\n    if (vi.SamplesPerSecond() != vi2.SamplesPerSecond())\n      env->ThrowError(\"Dissolve: The audio of the two clips have different samplerates! Use SSRC()/ResampleAudio()\");\n  }\n\n  if (vi.HasVideo()) {\n    if (vi.width != vi2.width || vi.height != vi2.height)\n      env->ThrowError(\"Dissolve: frame sizes don't match\");\n    if (!(vi.IsSameColorspace(vi2)))\n      env->ThrowError(\"Dissolve: video formats don't match\");\n\n    pixelsize = vi.ComponentSize(); // AVS16\n    bits_per_pixel = vi.BitsPerComponent();\n\n    video_fade_start = vi.num_frames - overlap;\n    video_fade_end = vi.num_frames - 1;\n\n    audio_fade_start = vi.AudioSamplesFromFrames(video_fade_start);\n    audio_fade_end = vi.AudioSamplesFromFrames(video_fade_end+1)-1;\n  }\n  else {\n  video_fade_start = 0;\n  video_fade_end = 0;\n\n  audio_fade_start = vi.num_audio_samples - int64_t(Int32x32To64(vi.SamplesPerSecond(), overlap)/fps+0.5);\n  audio_fade_end = vi.num_audio_samples-1;\n  }\n  audio_overlap = int(audio_fade_end - audio_fade_start);\n\n  if (video_fade_start < 0) video_fade_start= 0;\n  if (audio_fade_start < 0) audio_fade_start= 0;\n\n  vi.num_frames = video_fade_start + vi2.num_frames;\n\n  if (vi.num_frames < 0)\n    env->ThrowError(\"Dissolve: Maximum number of frames exceeded.\");\n\n  vi.num_audio_samples = audio_fade_start + vi2.num_audio_samples;\n}\n\n\nbool Dissolve::GetParity(int n)\n{\n  return (n < video_fade_start) ? child->GetParity(n) : child2->GetParity(n - video_fade_start);\n}\n\n\nPVideoFrame Dissolve::GetFrame(int n, IScriptEnvironment* env)\n{\n  if (n < video_fade_start)\n    return child->GetFrame(n, env);\n  if (n > video_fade_end)\n    return child2->GetFrame(n - video_fade_start, env);\n\n  PVideoFrame a = child->GetFrame(n, env);\n  PVideoFrame b = child2->GetFrame(n - video_fade_start, env);\n\n  const double multiplier = n - video_fade_end + overlap;\n  float weight = (float)(multiplier / (overlap + 1.0));\n\n  env->MakeWritable(&a);\n\n  const int planes_y[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };\n  const int planes_r[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A };\n  const int *planes;\n\n  int planeCount;\n  planeCount = vi.IsPlanar() ? vi.NumComponents() : 1;\n  planes = (!vi.IsPlanar() || vi.IsYUV() || vi.IsYUVA()) ? planes_y : planes_r;\n\n  const int bits_per_pixel = vi.BitsPerComponent();\n  for (int j = 0; j < planeCount; ++j)\n  {\n    const int plane = planes[j];\n    const BYTE*  b_data = b->GetReadPtr(plane);\n    int          b_pitch = b->GetPitch(plane);\n    BYTE*        a_data = a->GetWritePtr(plane);\n    int          a_pitch = a->GetPitch(plane);\n    int          row_size = a->GetRowSize(plane);\n    int          height = a->GetHeight(plane);\n\n    int weight_i;\n    int invweight_i;\n#ifdef INTEL_INTRINSICS\n    MergeFuncPtr weighted_merge_planar = getMergeFunc(bits_per_pixel, env->GetCPUFlags(), a_data, b_data, weight, /*out*/weight_i, /*out*/invweight_i);\n#else\n    MergeFuncPtr weighted_merge_planar = getMergeFunc(bits_per_pixel, a_data, b_data, weight, /*out*/weight_i, /*out*/invweight_i);\n#endif\n    weighted_merge_planar(a_data, b_data, a_pitch, b_pitch, row_size, height, weight, weight_i, invweight_i);\n  }\n  return a;\n}\n\n\nvoid Dissolve::GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env)\n{\n  if (start+count <= audio_fade_start) {\n    child->GetAudio(buf, start, count, env);\n    return;\n  }\n\n  if (start > audio_fade_end) {\n    child2->GetAudio(buf, start - audio_fade_start, count, env);\n    return;\n  }\n\n  const size_t bytes = (size_t)vi.BytesFromAudioSamples(count);\n  if (audbufsize < bytes) {\n    delete[] audbuffer;\n    audbuffer = new BYTE[bytes];\n    audbufsize = bytes;\n  }\n\n  child->GetAudio(buf, start, count, env);\n  child2->GetAudio(audbuffer, start - audio_fade_start, count, env);\n\n  const int nch = vi.AudioChannels();\n  const int countXnch = (int)count*nch;\n  const int denominator = audio_overlap;\n  int numerator = (int)(audio_fade_end - start);\n\n  if (vi.IsSampleType(SAMPLE_INT16)) {\n    short *const a = (short*)buf;\n    const short *const b = (short*)audbuffer;\n\n    int i;\n  for (i=0; i<countXnch; i+=nch) {\n      if (numerator <= 0) {                          // Past end of dissolve\n        break;\n      }\n      else if (numerator < denominator) {            // In dissolve region\n        for (int p=0; p < nch; p++)\n          a[i+p] = short(b[i+p] + MulDiv(a[i+p]-b[i+p], numerator, denominator));\n      }\n   // else                                           // Before begining of dissolve\n      numerator--;\n    }\n    const int nchb = (countXnch - i) * sizeof(short);\n    memcpy(a+i, b+i, nchb);\n    return;\n  }\n\n  if (vi.IsSampleType(SAMPLE_FLOAT)) {\n    const SFLOAT frdenominator = SFLOAT(1.0/denominator);\n    SFLOAT *const a = (SFLOAT*)buf;\n    const SFLOAT *const b = (SFLOAT*)audbuffer;\n\n    int i;\n  for (i=0; i<countXnch; i+=nch) {\n      if (numerator <= 0) {                          // Past end of dissolve\n        break;\n      }\n      else if (numerator < denominator) {            // In dissolve region\n        const SFLOAT w = numerator * frdenominator;  // How far into the fade are we?\n        for (int p=0; p < nch; p++)\n          a[i+p] = b[i+p] + w * (a[i+p]-b[i+p]);\n      }\n   // else                                           // Before begining of dissolve\n      numerator--; // When was a float only worked for N < 2^24\n    }\n    const int nchb = (countXnch - i) * sizeof(SFLOAT);\n    memcpy(a+i, b+i, nchb);\n    return;\n  }\n\n  env->ThrowError(\"Dissolve: Wow - this should never happend!\");\n\n}\n\n\n\n\n\n\n\n\n\n/*********************************\n *******   AudioDub Filter  ******\n *********************************/\n\nAudioDub::AudioDub(PClip child1, PClip child2, int mode, IScriptEnvironment* env)\n{\n  const VideoInfo& vi1 = child1->GetVideoInfo();\n  const VideoInfo& vi2 = child2->GetVideoInfo();\n  const VideoInfo *vi_video=0, *vi_audio=0;\n  if (mode) { // Unconditionally accept audio and video\n  vchild = child1; achild = child2;\n  vi_video = &vi1; vi_audio = &vi2;\n  }\n  else {\n  if (vi1.HasVideo() && vi2.HasAudio()) {\n    vchild = child1; achild = child2;\n    vi_video = &vi1, vi_audio = &vi2;\n  } else if (vi2.HasVideo() && vi1.HasAudio()) {\n    vchild = child2; achild = child1;\n    vi_video = &vi2, vi_audio = &vi1;\n  } else {\n    env->ThrowError(\"AudioDub: need an audio and a video track\");\n  }\n  }\n\n  vi = *vi_video;\n  vi.audio_samples_per_second = vi_audio->audio_samples_per_second;\n  vi.num_audio_samples = vi_audio->num_audio_samples;\n  vi.sample_type = vi_audio->sample_type;\n  vi.nchannels = vi_audio->nchannels;\n  vi.SetChannelMask(vi_audio->IsChannelMaskKnown(), vi_audio->GetChannelMask());\n}\n\n\nconst VideoInfo& AudioDub::GetVideoInfo()\n{\n  return vi;\n}\n\n\nPVideoFrame AudioDub::GetFrame(int n, IScriptEnvironment* env)\n{\n  return vchild->GetFrame(n, env);\n}\n\n\nbool AudioDub::GetParity(int n)\n{\n  return vchild->GetParity(n);\n}\n\n\nvoid AudioDub::GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env)\n{\n  achild->GetAudio(buf, start, count, env);\n}\n\nint __stdcall AudioDub::SetCacheHints(int cachehints,int frame_range)\n{\n  AVS_UNUSED(frame_range);\n  switch(cachehints)\n  {\n  case CACHE_DONT_CACHE_ME:\n    return 1;\n  case CACHE_GET_MTMODE:\n    return MT_NICE_FILTER;\n  case CACHE_GET_DEV_TYPE:\n    return (vchild->GetVersion() >= 5) ? vchild->SetCacheHints(CACHE_GET_DEV_TYPE, 0) : 0;\n  default:\n    return 0;\n  }\n}\n\n\n\nAVSValue __cdecl AudioDub::Create(AVSValue args, void* mode, IScriptEnvironment* env)\n{\n  return new AudioDub(args[0].AsClip(), args[1].AsClip(), (int)size_t(mode), env);\n}\n\n\n\n\n\n\n\n\n\n/*******************************\n *******   Reverse Filter  ******\n *******************************/\n\nReverse::Reverse(PClip _child) : GenericVideoFilter(_child) {}\n\n\nPVideoFrame Reverse::GetFrame(int n, IScriptEnvironment* env)\n{\n  return child->GetFrame(vi.num_frames-n-1, env);\n}\n\n\nbool Reverse::GetParity(int n)\n{\n  return child->GetParity(vi.num_frames-n-1);\n}\n\n\nvoid Reverse::GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env)\n{\n  child->GetAudio(buf, vi.num_audio_samples - start - count, count, env);\n  const int bytes_per_sample = vi.BytesPerAudioSample(); // includes all channels\n  const int bytes_per_channel_sample = vi.BytesPerChannelSample();\n  const int nch = vi.AudioChannels();\n  uint8_t* buf2 = reinterpret_cast<uint8_t*>(buf);\n\n  switch (bytes_per_channel_sample) {\n  case 1: // 8-bit\n    for (int64_t i = 0; i < count / 2; ++i) {\n      uint8_t* a_ptr = buf2 + i * bytes_per_sample;\n      uint8_t* b_ptr = buf2 + (count - 1 - i) * bytes_per_sample;\n      for (int c = 0; c < nch; ++c) {\n        std::swap(a_ptr[c], b_ptr[c]);\n      }\n    }\n    break;\n  case 2: // 16-bit\n    for (int64_t i = 0; i < count / 2; ++i) {\n      int16_t* a_ptr = reinterpret_cast<int16_t*>(buf2 + i * bytes_per_sample);\n      int16_t* b_ptr = reinterpret_cast<int16_t*>(buf2 + (count - 1 - i) * bytes_per_sample);\n      for (int c = 0; c < nch; ++c) {\n        std::swap(a_ptr[c], b_ptr[c]);\n      }\n    }\n    break;\n  case 3: // 24-bit, keep brute force\n    for (int64_t i = 0; i < count / 2; ++i) {\n      uint8_t* a_ptr = buf2 + i * bytes_per_sample;\n      uint8_t* b_ptr = buf2 + (count - 1 - i) * bytes_per_sample;\n      for (int c = 0; c < nch; ++c) {\n        uint8_t* a_chan = a_ptr + c * 3;\n        uint8_t* b_chan = b_ptr + c * 3;\n        for (int j = 0; j < 3; ++j) {\n          std::swap(a_chan[j], b_chan[j]);\n        }\n      }\n    }\n    break;\n  case 4: // 32-bit int or float, separate because of swap templates\n    if (vi.IsSampleType(SAMPLE_FLOAT)) {\n      for (int64_t i = 0; i < count / 2; ++i) {\n        float* a_ptr = reinterpret_cast<float*>(buf2 + i * bytes_per_sample);\n        float* b_ptr = reinterpret_cast<float*>(buf2 + (count - 1 - i) * bytes_per_sample);\n        for (int c = 0; c < nch; ++c) {\n          std::swap(a_ptr[c], b_ptr[c]);\n        }\n      }\n    }\n    else {\n      for (int64_t i = 0; i < count / 2; ++i) {\n        int32_t* a_ptr = reinterpret_cast<int32_t*>(buf2 + i * bytes_per_sample);\n        int32_t* b_ptr = reinterpret_cast<int32_t*>(buf2 + (count - 1 - i) * bytes_per_sample);\n        for (int c = 0; c < nch; ++c) {\n          std::swap(a_ptr[c], b_ptr[c]);\n        }\n      }\n    }\n    break;\n  default: // generic case, no such sample size though\n    for (int64_t i = 0; i < count / 2; ++i) {\n      uint8_t* a_ptr = buf2 + i * bytes_per_sample;\n      uint8_t* b_ptr = buf2 + (count - 1 - i) * bytes_per_sample;\n      for (int c = 0; c < nch; ++c) {\n        uint8_t* a_chan = a_ptr + c * bytes_per_channel_sample;\n        uint8_t* b_chan = b_ptr + c * bytes_per_channel_sample;\n        for (int j = 0; j < bytes_per_channel_sample; ++j) {\n          std::swap(a_chan[j], b_chan[j]);\n        }\n      }\n    }\n    break;\n  }\n}\n\n\nAVSValue __cdecl Reverse::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  AVS_UNUSED(env);\n  return new Reverse(args[0].AsClip());\n}\n\n\n\n\n\n\n\n\n/*****************************\n ******   Loop Filter   *******\n *****************************/\n\nLoop::Loop(PClip _child, int times, int _start, int _end, IScriptEnvironment* env)\n : GenericVideoFilter(_child), start(_start), end(_end)\n{\n  start = clamp(start,0,vi.num_frames-1);\n  end = clamp(end,start,vi.num_frames-1);\n  frames = end-start+1;\n  if (times<0) { // Loop nearly forever\n    vi.num_frames = 10000000;\n    end = vi.num_frames;\n  if (vi.HasAudio()) {\n    if (vi.HasVideo()) {\n    aud_start = vi.AudioSamplesFromFrames(start);\n    aud_end = vi.AudioSamplesFromFrames(end+1) - 1; // This is the output end sample\n    aud_count = vi.AudioSamplesFromFrames(frames); // length of each loop in samples\n    } else {\n    // start and end frame numbers are meaningless without video\n    aud_start = 0;\n    aud_count = vi.num_audio_samples;\n    aud_end = Int32x32To64(400000, vi.audio_samples_per_second);\n    }\n    vi.num_audio_samples = aud_end+1;\n  }\n  }\n  else {\n    vi.num_frames += (times-1) * frames;\n\n    if (vi.num_frames < 0)\n      env->ThrowError(\"Loop: Maximum number of frames exceeded.\");\n\n    end = start + times * frames - 1;\n  if (vi.HasAudio()) {\n    if (vi.HasVideo()) {\n    aud_start = vi.AudioSamplesFromFrames(start);\n    aud_end = vi.AudioSamplesFromFrames(end+1) - 1; // This is the output end sample\n    aud_count = vi.AudioSamplesFromFrames(frames); // length of each loop in samples\n    } else {\n    // start and end frame numbers are meaningless without video\n    aud_start = 0;\n    aud_count = vi.num_audio_samples;\n    aud_end = vi.num_audio_samples * times;\n    }\n    vi.num_audio_samples += (times-1) * aud_count;\n  }\n  }\n}\n\n\nPVideoFrame Loop::GetFrame(int n, IScriptEnvironment* env)\n{\n  return child->GetFrame(convert(n), env);\n}\n\n\nbool Loop::GetParity(int n)\n{\n  return child->GetParity(convert(n));\n}\n\nvoid Loop::GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) {\n  int64_t get_count, get_start;\n  const int bpas = vi.BytesPerAudioSample();\n  char* samples = (char*)buf;\n\n  while (count > 0) {\n  if (start > aud_end) {   // tail of clip\n    get_start = aud_start + aud_count + start - (aud_end+1);\n    get_count = count;\n  }\n  else {\n    if (start > aud_start) // loop part of clip\n    get_start = (start - aud_start) % aud_count + aud_start;\n    else                   // head of clip\n    get_start = start;\n\n    get_count = aud_count - (get_start - aud_start); // count to end of next iteration\n\n    if (get_start+get_count > aud_end+1) // loop(0) case\n    get_count = aud_end+1 - get_start;\n    else if (start+get_count > aud_end)\n    get_count = count; // if is last iteration do all of remainder\n\n    if (get_count > count) get_count = count;\n  }\n\n  child->GetAudio(samples, get_start, get_count, env);\n\n  samples += get_count * bpas;  // update dest start pointer\n  start   += get_count;\n  count   -= get_count;\n  }\n}\n\n__inline int Loop::convert(int n)\n{\n  if (n>end) return n - end + start + frames - 1;\n  else if (n>=start) return ((n - start) % frames) + start;\n  else return n;\n}\n\n\nAVSValue __cdecl Loop::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  if (!args[0].AsClip()->GetVideoInfo().HasVideo() &&\n       (args[2].Defined() || args[3].Defined())) {\n    env->ThrowError(\"Loop: cannot use start or end frame numbers without a video track\");\n  }\n  return new Loop(args[0].AsClip(), args[1].AsInt(-1), args[2].AsInt(0), args[3].AsInt(10000000),env);\n}\n\n\n\n\n\n\n\n/******************************\n ** Assorted factory methods **\n *****************************/\n\n\nPClip __cdecl ColorClip(PClip a, int duration, AVSValue color, AVSValue color_yuv, AVSValue colors, float fps, IScriptEnvironment* env) {\n  if (a->GetVideoInfo().HasVideo())\n  {\n    AVSValue blackness_args[] = { a, duration, color, color_yuv, colors };\n    static const char* const arg_names[5] = { 0, 0, \"color\", \"color_yuv\", \"colors\" };\n    return env->Invoke(\"BlankClip\", AVSValue(blackness_args, 5), arg_names).AsClip();\n  }\n  else\n  {\n    AVSValue blackness_args[] = { a, duration, color, fps, color_yuv, colors };\n    static const char* const arg_names[6] = { 0, 0, \"color\", \"fps\", \"color_yuv\", \"colors\" };\n    return env->Invoke(\"BlankClip\", AVSValue(blackness_args, 6), arg_names).AsClip();\n  }\n}\n\nAVSValue __cdecl Create_Fade(AVSValue args, void* user_data, IScriptEnvironment* env) {\n  const int fade_type = (int)(intptr_t)user_data;\n\n  const int duration = args[1].AsInt();\n  const float fps = args[3].AsFloatf(24.0f);\n\n  int offset = 0;\n\n  PClip a = args[0].AsClip();\n\n  switch (fade_type) {\n  case FADE_MODE_OUT0:\n  case FADE_MODE_IN0:\n  case FADE_MODE_IO0: offset = 0; break;\n  case FADE_MODE_OUT:\n  case FADE_MODE_IN:\n  case FADE_MODE_IO: offset = 1; break;\n  case FADE_MODE_OUT2:\n  case FADE_MODE_IN2:\n  case FADE_MODE_IO2: offset = 2; break;\n  }\n\n  PClip b = ColorClip(a, duration + offset, args[2] /* color */, args[4] /* color_yuv */, args[5] /* colors */, fps, env);\n\n  if(fade_type == FADE_MODE_OUT0 || fade_type == FADE_MODE_OUT || fade_type == FADE_MODE_OUT2)\n    return new Dissolve(a, b, duration, fps, env);\n  else if (fade_type == FADE_MODE_IN0 || fade_type == FADE_MODE_IN || fade_type == FADE_MODE_IN2)\n    return new Dissolve(b, a, duration, fps, env);\n  else {\n    /* IO In-Out */\n    AVSValue dissolve_args[] = { b, a, b, duration, fps };\n    return env->Invoke(\"Dissolve\", AVSValue(dissolve_args, 5)).AsClip();\n  }\n}\n"
  },
  {
    "path": "avs_core/filters/edit.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Edit_H__\n#define __Edit_H__\n\n#include <avisynth.h>\n#include \"../core/internal.h\"\n\n/********************************************************************\n********************************************************************/\n\nclass Trim : public GenericVideoFilter\n/**\n  * Class to select a range of frames from a longer clip\n **/\n{\npublic:\n  typedef enum { Invalid = 0, Default, Length, End } trim_mode_e;\n\n  Trim(int _firstframe, int _lastframe, bool _padaudio, PClip _child, trim_mode_e mode, bool _cache, IScriptEnvironment* env);\n  Trim(double starttime, double endtime, PClip _child, trim_mode_e mode, bool _cache, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) override;\n  bool __stdcall GetParity(int n) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    switch (cachehints) {\n    case CACHE_DONT_CACHE_ME:\n      return cache ? 0 : 1; // adaptively cache-able\n    case CACHE_GET_MTMODE:\n      return MT_NICE_FILTER;\n    case CACHE_GET_DEV_TYPE:\n      return (child->GetVersion() >= 5) ? child->SetCacheHints(CACHE_GET_DEV_TYPE, 0) : 0;\n    default:\n      return 0;\n    }\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void* mode, IScriptEnvironment* env);\n  static AVSValue __cdecl CreateA(AVSValue args, void* mode, IScriptEnvironment* env);\n\nprivate:\n  int firstframe;\n  int64_t audio_offset;\n  bool cache;\n};\n\n\n\n\nclass FreezeFrame : public GenericVideoFilter\n/**\n  * Class to display a single frame for the duration of several\n **/\n{\npublic:\n  FreezeFrame(int _first, int _last, int _source, PClip _child);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n  bool __stdcall GetParity(int n) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\nprivate:\n  const int first, last, source;\n};\n\n\n\n\nclass DeleteFrame : public GenericVideoFilter\n/**\n  * Class to delete a frame\n **/\n{\npublic:\n  DeleteFrame(int _frame, PClip _child);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n  bool __stdcall GetParity(int n) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\nprivate:\n  const int frame;\n};\n\n\n\n\nclass DuplicateFrame : public GenericVideoFilter\n/**\n  * Class to duplicate a frame\n **/\n{\npublic:\n  DuplicateFrame(int _frame, PClip _child);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n  bool __stdcall GetParity(int n) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\nprivate:\n  const int frame;\n};\n\n\n\n\nclass Splice : public GenericVideoFilter\n/**\n  * Class to splice together video clips\n **/\n{\npublic:\n  Splice(PClip _child1, PClip _child2, bool realign_sound, bool passCache, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env);\n  bool __stdcall GetParity(int n);\n  int __stdcall SetCacheHints(int cachehints,int frame_range);\n\n  static AVSValue __cdecl CreateUnaligned(AVSValue args, void*, IScriptEnvironment* env);\n  static AVSValue __cdecl CreateAligned(AVSValue args, void*, IScriptEnvironment* env);\n  static AVSValue __cdecl CreateUnalignedNoCache(AVSValue args, void*, IScriptEnvironment* env);\n  static AVSValue __cdecl CreateAlignedNoCache(AVSValue args, void*, IScriptEnvironment* env);\n\nprivate:\n  PClip child2;\n  int video_switchover_point;\n  int64_t audio_switchover_point;\n  const bool passCache;\n  int child_devs;\n};\n\n\n\n\nclass Dissolve : public GenericVideoFilter\n/**\n  * Class to smoothly transition from one video clip to another\n **/\n{\npublic:\n  Dissolve(PClip _child1, PClip _child2, int _overlap, double fps, IScriptEnvironment* env);\n  virtual ~Dissolve();\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env);\n  bool __stdcall GetParity(int n);\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\nprivate:\n  PClip child2;\n  const int overlap;\n  int video_fade_start, video_fade_end;\n  int64_t audio_fade_start, audio_fade_end;\n  int audio_overlap;\n  BYTE* audbuffer;\n  size_t audbufsize;\n  int pixelsize;\n  int bits_per_pixel;\n  void EnsureBuffer(int minsize);\n};\n\n\n\n\nclass AudioDub : public IClip {\n/**\n  * Class to mux the audio track of one clip with the video of another\n **/\npublic:\n  AudioDub(PClip child1, PClip child2, int mode, IScriptEnvironment* env);\n  const VideoInfo& __stdcall GetVideoInfo();\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env);\n  bool __stdcall GetParity(int n);\n  int __stdcall SetCacheHints(int cachehints,int frame_range);\n\n  static AVSValue __cdecl Create(AVSValue args, void* mode, IScriptEnvironment* env);\n\nprivate:\n  /*const*/ PClip vchild, achild;\n  VideoInfo vi;\n};\n\n\n\n\nclass Reverse : public GenericVideoFilter\n/**\n  * Class to play a clip backwards\n **/\n{\npublic:\n  Reverse(PClip _child);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n  bool __stdcall GetParity(int n) override;\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n};\n\n\n\n\nclass Loop : public GenericVideoFilter {\n/**\n  * Class to loop over a range of frames\n**/\npublic:\n\tLoop(PClip _child, int times, int _start, int _end, IScriptEnvironment* env);\n\tPVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\tbool __stdcall GetParity(int n) override;\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n\tstatic AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\nprivate:\n\tint   frames,    start,     end;\n  int64_t aud_count, aud_start, aud_end;\n\tint convert(int n);\n};\n\n\n\n\n/**** A few factory methods ****/\n\nAVSValue __cdecl Create_Fade(AVSValue args, void* user_data, IScriptEnvironment* env);\n\n\n#endif  // __Edit_H__\n"
  },
  {
    "path": "avs_core/filters/exprfilter/exprfilter.cpp",
    "content": "/*\n*\n* Avisynth+ Expression filter, ported from the VapourSynth project\n* Copyright (c) 2012-2015 Fredrik Mellbin\n*\n* Additions and differences to VS r39 version:\n* ------------------------------\n* (similar features to the masktools mt_lut family syntax)\n* Operator aliases:\n*   Caret (^) can be used like pow\n*   For equality check \"==\" can be used like \"=\"\n*   & same as and\n*   | same as or\n* New operator: != (not equal)\n* Built-in constants\n*   ymin, ymax (ymin_a .. ymin_z for individual clips) - the usual luma limits (16..235 or scaled equivalents)\n*   cmin, cmax (cmin_a .. cmin_z) - chroma limits (16..240 or scaled equivalents)\n*   range_half (range_half_a .. range_half_z) - half of the range, (128 or scaled equivalents)\n*   range_size, range_half, range_min, range_max (range_size_a .. range_size_z , etc..)\n* Autoscale helper functions (operand is treated as being a 8 bit constant unless i8..i16 or f32 is specified)\n*   scaleb (scale by bit shift - mul or div by 2, 4, 6, 8...)\n*   scalef (scale by stretch full scale - mul or div by source_max/target_max\n* Keywords for modifying base bit depth for scaleb and scalef\n*   i8, i10, i12, i14, i16, f32\n* Built-in math constant\n*   pi\n* Alpha plane handling. When no separate expression is supplied for alpha, plane is copied instead of reusing last expression parameter\n* Proper clamping when storing 10,12 or 14 bit outputs\n* Faster storing of results for 8 and 10-16 bit outputs\n* 16 pixels/cycle instead of 8 when avx2, with fallback to 8-pixel case on the right edge. Thus no need for 64 byte alignment for 32 bit float.\n* (Load zeros for nonvisible pixels, when simd block size goes beyond image width, to prevent garbage input for simd calculation)\n* Optimizations: x^0.5 is sqrt, ^1 +0 -0 *1 /1 to nothing, ^2, ^3, ^4 is done by faster and more precise multiplication\n* spatial input variables in expr syntax:\n*    sx, sy (absolute x and y coordinates, 0 to width-1 and 0 to height-1)\n*    sxr, syr (relative x and y coordinates, from 0 to 1.0)\n* Optimize: recognize constant plane expression: use fast memset instead of generic simd process. Approx. 3-4x (32 bits) to 10-12x (8 bits) speedup\n* Optimize: Recognize single clip letter in expression: use fast plane copy (BitBlt)\n*   (e.g. for 8-16 bits: instead of load-convert_to_float-clamp-convert_to_int-store). Approx. 1.4x (32 bits), 3x (16 bits), 8-9x (8 bits) speedup\n* Optimize: do not call GetFrame for input clips that are not referenced or plane-copied\n* 20171211: Implement relative pixel indexing e.g. x[-1,-3], requires SSSE3\n*           Fix jitasm code generation (corrupt code when doing register reorders)\n* 20171212: Variables:  A..Z\n*           To store the current top value of the stack to a variable: A@ .. Z@\n*           To store the current top value and pop it from the top of the stack: A^.. Z^\n*           To use a stored variable: single uppercase letter. E.g. A\n* 20171214: Trig.functions (C only): sin, cos, tan, asin, acos, atan\n*           '%' The implementation is fmod-like: x - trunc(x/d)*d.\n*             Note: SSE2 and up is using trunc for float->integer conversion, works for usual width/height magnitude.\n*             (A float can hold a 24 bit integer w/o losing precision)\n*           expr constants: 'width', 'height' for current plane width and height\n*           expr auto variable: 'frameno' holds the current frame number 0..total number of frames-1\n*           expr auto variable: 'time' relative time in clip, 0 <= time <= 1\n*                calculation: time = frameno/(total number of frames - 1)\n* 20180614 new parameters: scale_inputs, clamp_float\n*          implement 'clip' three operand operator like in masktools2: x minvalue maxvalue clip -> max(min(x, maxvalue), minvalue)\n* 20191120 yrange_min, yrange_half, yrange_max, clamp_float_UV param, allow \"float_UV\" for scale_inputs\n*          yscalef, yscaleb forcing non-chroma rules for scaling even when processing chroma planes\n* 202107xx round, floor, ceil, trunc (acceleration from SSE4.1 and up)\n*          arbitrary variable names; instead of 'A' to 'Z', up to 256 of them can be used\n* 20210924 frame property access clip.framePropName syntax after VSAkarin idea (no array access yet)\n*          sin and cos as SIMD (VSAkarin, port from VS)\n* 20211116 neg\n* 20211117 atan2 as SIMD\n* 20211118 sgn\n* 20211127 lutx, lutxy (lut=1 and 2)\n* 20211128 allow f32 for 'scale_inputs' when \"int\", \"intf\", \"all\", \"allf\"\n* 20250309 tan as SIMD\n*\n* Differences from masktools 2.2.15\n* ---------------------------------\n*   Up to 26 clips are allowed (x,y,z,a,b,...w). Masktools handles only up to 4 clips with its mt_lut, my_lutxy, mt_lutxyz, mt_lutxyza\n*   Clips with different bit depths are allowed\n*   works with 32 bit floats instead of 64 bit double internally\n*   less functions (e.g. no bit shifts)\n*   logical 'false' is 0 instead of -1\n*   avs+: ymin, ymax, etc built-in constants can have a _X suffix, where X is the corresponding clip designator letter. E.g. cmax_z, range_half_x\n*   mt_lutspa-like functionality is available through \"sx\", \"sy\", \"sxr\", \"syr\"\n*/\n\n#include <iostream>\n#include <locale>\n#include <sstream>\n#include <vector>\n#include <list>\n#include <string>\n#include <algorithm>\n#include <stdexcept>\n#include <memory>\n#include <cmath>\n#include <unordered_map>\n\n#include <avisynth.h>\n\n#ifdef AVS_WINDOWS\n    #include <avs/win.h>\n#else\n    #include <avs/posix.h>\n#endif\n\n#include <stdlib.h>\n#include \"../../core/internal.h\"\n#include \"../../convert/convert_planar.h\" // fill_plane\n#include \"../../convert/convert_helper.h\"\n#include \"avs/alignment.h\"\n\n#if defined(_MSC_VER) || (defined(__clang__) && defined(_MSC_VER)) || defined(__MINGW32__) || defined(__MINGW64__)\n#include <malloc.h>  // For _aligned_malloc and _aligned_free\n#endif\n\n#if (defined(_WIN64) && (defined(_M_AMD64) || defined(_M_X64))) || defined(__x86_64__)\n#define JITASM64\n#endif\n\n#ifdef INTEL_INTRINSICS\n#define VS_TARGET_CPU_X86\n#endif\n#ifdef AVS_WINDOWS\n#define VS_TARGET_OS_WINDOWS\n#endif\n#include \"exprfilter.h\"\n\n#ifdef VS_TARGET_CPU_X86\n#ifndef NOMINMAX\n#define NOMINMAX\n#endif\n#include \"jitasm.h\"\n#endif\n\n#ifndef VS_TARGET_OS_WINDOWS\n#include <sys/mman.h>\n#endif\n\n#ifdef XP_TLS\n#ifdef MSVC_PURE\n// v141_xp workaround: disabling /O2 global optimizations reduces build time\n// from 56 minutes to 48 seconds.\n#pragma optimize(\"g\", off) // disables global optimizations (e.g. /O2 max opt,speed)\n#pragma optimize(\"t\", on) // favor speed /Ot\n#pragma auto_inline(on) // enable aggressive inlining, equivalent of /Ob2\n#endif\n#endif\n\n#ifdef VS_TARGET_CPU_X86\n\n//#define TEST_AVX2_CODEGEN_IN_AVX\n\n#include <immintrin.h>\n\n#if defined(GCC) || defined(CLANG)\n#include <avxintrin.h>\n#endif\n\n// rounder constants\nconstexpr int FROUND_TO_NEAREST_INT = 0x00;\nconstexpr int FROUND_TO_NEG_INF = 0x01;\nconstexpr int FROUND_TO_POS_INF = 0x02;\nconstexpr int FROUND_TO_ZERO = 0x03;\nconstexpr int FROUND_NO_EXC = 0x08;\n\n// normal versions work with two xmm or ymm registers (2*4 or 2*8 pixels per cycle)\n// _Single suffixed versions work only one xmm or ymm registers at a time (1*4 or 1*8 pixels per cycle)\n\n#define OneArgOp(instr) \\\nauto &t1 = stack.back(); \\\ninstr(t1.first, t1.first); \\\ninstr(t1.second, t1.second);\n\n#define OneArgOp_Single(instr) \\\nauto &t1 = stack1.back(); \\\ninstr(t1, t1);\n\n#define TwoArgOp(instr) \\\nauto t1 = stack.back(); \\\nstack.pop_back(); \\\nauto &t2 = stack.back(); \\\ninstr(t2.first, t1.first); \\\ninstr(t2.second, t1.second);\n\n#define TwoArgOp_Single(instr) \\\nauto t1 = stack1.back(); \\\nstack1.pop_back(); \\\nauto &t2 = stack1.back(); \\\ninstr(t2, t1);\n\n#define TwoArgOp_Avx(instr) \\\nauto t1 = stack.back(); \\\nstack.pop_back(); \\\nauto &t2 = stack.back(); \\\ninstr(t2.first, t2.first, t1.first); \\\ninstr(t2.second, t2.second, t1.second);\n\n#define TwoArgOp_Single_Avx(instr) \\\nauto t1 = stack1.back(); \\\nstack1.pop_back(); \\\nauto &t2 = stack1.back(); \\\ninstr(t2, t2, t1);\n\n#define CmpOp(instr) \\\nauto t1 = stack.back(); \\\nstack.pop_back(); \\\nauto t2 = stack.back(); \\\nstack.pop_back(); \\\ninstr(t1.first, t2.first); \\\ninstr(t1.second, t2.second); \\\nandps(t1.first, CPTR(elfloat_one)); \\\nandps(t1.second, CPTR(elfloat_one)); \\\nstack.push_back(t1);\n\n#define CmpOp_Single(instr) \\\nauto t1 = stack1.back(); \\\nstack1.pop_back(); \\\nauto t2 = stack1.back(); \\\nstack1.pop_back(); \\\ninstr(t1, t2); \\\nandps(t1, CPTR(elfloat_one)); \\\nstack1.push_back(t1);\n\n#define CmpOp_Avx(instr, op) \\\nauto t1 = stack.back(); \\\nstack.pop_back(); \\\nauto t2 = stack.back(); \\\nstack.pop_back(); \\\ninstr(t1.first, t1.first, t2.first, op); \\\ninstr(t1.second, t1.second, t2.second, op); \\\nvandps(t1.first, t1.first, CPTR_AVX(elfloat_one)); \\\nvandps(t1.second, t1.second, CPTR_AVX(elfloat_one)); \\\nstack.push_back(t1);\n\n#define CmpOp_Single_Avx(instr, op) \\\nauto t1 = stack1.back(); \\\nstack1.pop_back(); \\\nauto t2 = stack1.back(); \\\nstack1.pop_back(); \\\ninstr(t1, t1, t2, op); \\\nvandps(t1, t1, CPTR_AVX(elfloat_one)); \\\nstack1.push_back(t1);\n\n#define LogicOp(instr) \\\nauto t1 = stack.back(); \\\nstack.pop_back(); \\\nauto t2 = stack.back(); \\\nstack.pop_back(); \\\ncmpnleps(t1.first, zero); \\\ncmpnleps(t1.second, zero); \\\ncmpnleps(t2.first, zero); \\\ncmpnleps(t2.second, zero); \\\ninstr(t1.first, t2.first); \\\ninstr(t1.second, t2.second); \\\nandps(t1.first, CPTR(elfloat_one)); \\\nandps(t1.second, CPTR(elfloat_one)); \\\nstack.push_back(t1);\n\n#define LogicOp_Single(instr) \\\nauto t1 = stack1.back(); \\\nstack1.pop_back(); \\\nauto t2 = stack1.back(); \\\nstack1.pop_back(); \\\ncmpnleps(t1, zero); \\\ncmpnleps(t2, zero); \\\ninstr(t1, t2); \\\nandps(t1, CPTR(elfloat_one)); \\\nstack1.push_back(t1);\n\n#define LogicOp_Avx(instr) \\\nauto t1 = stack.back(); \\\nstack.pop_back(); \\\nauto t2 = stack.back(); \\\nstack.pop_back(); \\\nvcmpps(t1.first, t1.first, zero, _CMP_GT_OQ); \\\nvcmpps(t1.second, t1.second, zero, _CMP_GT_OQ); \\\nvcmpps(t2.first, t2.first, zero, _CMP_GT_OQ); \\\nvcmpps(t2.second, t2.second, zero, _CMP_GT_OQ); \\\ninstr(t1.first, t1.first, t2.first); \\\ninstr(t1.second, t1.second, t2.second); \\\nvandps(t1.first, t1.first, CPTR_AVX(elfloat_one)); \\\nvandps(t1.second, t1.second, CPTR_AVX(elfloat_one)); \\\nstack.push_back(t1);\n\n#define LogicOp_Single_Avx(instr) \\\nauto t1 = stack1.back(); \\\nstack1.pop_back(); \\\nauto t2 = stack1.back(); \\\nstack1.pop_back(); \\\nvcmpps(t1, t1, zero, _CMP_GT_OQ); \\\nvcmpps(t2, t2, zero, _CMP_GT_OQ); \\\ninstr(t1, t1, t2); \\\nvandps(t1, t1, CPTR_AVX(elfloat_one)); \\\nstack1.push_back(t1);\n\nenum {\n    elabsmask, elc7F, elmin_norm_pos, elinv_mant_mask,\n    elfloat_one, elfloat_minusone, elfloat_half, elsignmask, elstore8, elstore10, elstore12, elstore14, elstore16,\n    spatialX, spatialX2,\n    loadmask1000, loadmask1100, loadmask1110,\n    elShuffleForRight0, elShuffleForRight1, elShuffleForRight2, elShuffleForRight3, elShuffleForRight4, elShuffleForRight5, elShuffleForRight6,\n    elShuffleForLeft0, elShuffleForLeft1, elShuffleForLeft2, elShuffleForLeft3, elShuffleForLeft4, elShuffleForLeft5, elShuffleForLeft6,\n    elexp_hi, elexp_lo, elcephes_LOG2EF,\n    elcephes_exp_C1, elcephes_log_q2 = elcephes_exp_C1, elcephes_exp_C2, elcephes_log_q1 = elcephes_exp_C2, elcephes_exp_p0, elcephes_exp_p1, elcephes_exp_p2, elcephes_exp_p3, elcephes_exp_p4, elcephes_exp_p5, elcephes_SQRTHF,\n    elcephes_log_p0, elcephes_log_p1, elcephes_log_p2, elcephes_log_p3, elcephes_log_p4, elcephes_log_p5, elcephes_log_p6, elcephes_log_p7, elcephes_log_p8,\n    float_invpi, float_rintf,\n    float_pi1, float_pi2, float_pi3, float_pi4,\n    float_sinC3, float_sinC5, float_sinC7, float_sinC9,\n    float_cosC2, float_cosC4, float_cosC6, float_cosC8,\n    float_atan2f_rmul, float_atan2f_radd, float_atan2f_tmul, float_atan2f_tadd, float_atan2f_halfpi, float_atan2f_pi,\n    float_tan_p0, float_tan_p2, float_tan_p4, float_tan_p6, float_tan_p8,\n    float_tan_q0, float_tan_q2, float_tan_q4, float_tan_q6, float_tan_q8,\n    float_tan_small_limit, float_tan_asympt_a1, float_tan_asympt_a2, float_tan_asympt_limit\n};\n\n// constants for xmm\n\n#define XCONST(x) { x, x, x, x }\n#define MAKEDWORD(ch0, ch1, ch2, ch3)                              \\\n                ((uint32_t)(unsigned char)(ch0) | ((uint32_t)(unsigned char)(ch1) << 8) |   \\\n                ((uint32_t)(unsigned char)(ch2) << 16) | ((uint32_t)(unsigned char)(ch3) << 24 ))\n#define XBYTECONST(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) \\\n  { (int)MAKEDWORD(a0,a1,a2,a3), (int)MAKEDWORD(a4,a5,a6,a7), (int)MAKEDWORD(a8,a9,a10,a11), (int)MAKEDWORD(a12,a13,a14,a15) }\n\n\nstatic constexpr ExprUnion logexpconst alignas(16)[87][4] = {\n    XCONST(0x7FFFFFFF), // absmask\n    XCONST(0x7F), // c7F\n    XCONST(0x00800000), // min_norm_pos\n    XCONST(~0x7f800000), // inv_mant_mask\n    XCONST(1.0f), // float_one\n    XCONST(-1.0f), // float_minusone\n    XCONST(0.5f), // float_half\n    XCONST(0x80000000), // elsignmask\n    XCONST(255.0f), // store8\n    XCONST(1023.0f), // store10 (avs+)\n    XCONST(4095.0f), // store12 (avs+)\n    XCONST(16383.0f), // store14 (avs+)\n    XCONST(65535.0f), // store16\n    { 0.0f, 1.0f, 2.0f, 3.0f }, // spatialX\n    { 4.0f, 5.0f, 6.0f, 7.0f }, // spatialX2\n    { (int)0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000 }, // loadmask1000\n    { (int)0xFFFFFFFF, (int)0xFFFFFFFF, 0x00000000, 0x00000000 }, // loadmask1100\n    { (int)0xFFFFFFFF, (int)0xFFFFFFFF, (int)0xFFFFFFFF, 0x00000000 }, // loadmask1110\n    XBYTECONST(0,1,2,3,4,5,6,7,  8,9,10,11,12,13,12,13), // elShuffleForRight0\n    XBYTECONST(0,1,2,3,4,5,6,7,  8,9,10,11,10,11,10,11), // elShuffleForRight1\n    XBYTECONST(0,1,2,3,4,5,6,7,  8,9,8,9,8,9,8,9), // elShuffleForRight2\n    XBYTECONST(0,1,2,3,4,5,6,7,  6,7,6,7,6,7,6,7), // elShuffleForRight3\n    XBYTECONST(0,1,2,3,4,5,4,5,  4,5,4,5,4,5,4,5), // elShuffleForRight4\n    XBYTECONST(0,1,2,3,2,3,2,3,  2,3,2,3,2,3,2,3), // elShuffleForRight5\n    XBYTECONST(0,1,0,1,0,1,0,1,  0,1,0,1,0,1,0,1), // elShuffleForRight6\n    XBYTECONST(2,3,2,3,4,5,6,7,  8,9,10,11,12,13,14,15), // elShuffleForLeft0\n    XBYTECONST(4,5,4,5,4,5,6,7,  8,9,10,11,12,13,14,15), // elShuffleForLeft1\n    XBYTECONST(6,7,6,7,6,7,6,7,  8,9,10,11,12,13,14,15), // elShuffleForLeft2\n    XBYTECONST(8,9,8,9,8,9,8,9,  8,9,10,11,12,13,14,15), // elShuffleForLeft3\n    XBYTECONST(10,11,10,11,10,11,10,11, 10,11,10,11,12,13,14,15), // elShuffleForLeft4\n    XBYTECONST(12,13,12,13,12,13,12,13, 12,13,12,13,12,13,14,15), // elShuffleForLeft5\n    XBYTECONST(14,15,14,15,14,15,14,15, 14,15,14,15,14,15,14,15), // elShuffleForLeft6\n    XCONST(88.3762626647949f), // exp_hi\n    XCONST(-88.3762626647949f), // exp_lo\n    XCONST(1.44269504088896341f), // cephes_LOG2EF\n    XCONST(0.693359375f), // cephes_exp_C1\n    XCONST(-2.12194440e-4f), // cephes_exp_C2\n    XCONST(1.9875691500E-4f), // cephes_exp_p0\n    XCONST(1.3981999507E-3f), // cephes_exp_p1\n    XCONST(8.3334519073E-3f), // cephes_exp_p2\n    XCONST(4.1665795894E-2f), // cephes_exp_p3\n    XCONST(1.6666665459E-1f), // cephes_exp_p4\n    XCONST(5.0000001201E-1f), // cephes_exp_p5\n    XCONST(0.707106781186547524f), // cephes_SQRTHF\n    XCONST(7.0376836292E-2f), // cephes_log_p0\n    XCONST(-1.1514610310E-1f), // cephes_log_p1\n    XCONST(1.1676998740E-1f), // cephes_log_p2\n    XCONST(-1.2420140846E-1f), // cephes_log_p3\n    XCONST(+1.4249322787E-1f), // cephes_log_p4\n    XCONST(-1.6668057665E-1f), // cephes_log_p5\n    XCONST(+2.0000714765E-1f), // cephes_log_p6\n    XCONST(-2.4999993993E-1f), // cephes_log_p7\n    XCONST(+3.3333331174E-1f), // cephes_log_p8\n    XCONST(0x3ea2f983), // float_invpi, 1/pi = 0.31830988618379067154f\n    XCONST(0x4b400000), // float_rintf  Used for rounding\n    XCONST(0x40490000), // float_pi1    High precision part of Pi\n    XCONST(0x3a7da000), // float_pi2    Second part of Pi for extended precision\n    XCONST(0x34222000), // float_pi3    Third part of Pi for extended precision\n    XCONST(0x2cb4611a), // float_pi4    Fourth part of Pi for extended precision\n    XCONST(0xbe2aaaa6), // float_sinC3\n    XCONST(0x3c08876a), // float_sinC5\n    XCONST(0xb94fb7ff), // float_sinC7\n    XCONST(0x362edef8), // float_sinC9\n    XCONST(static_cast<int32_t>(0xBEFFFFE2)), // float_cosC2\n    XCONST(0x3D2AA73C), // float_cosC4\n    XCONST(static_cast<int32_t>(0XBAB58D50)), // float_cosC6\n    XCONST(0x37C1AD76), // float_cosC8\n    XCONST(0x3ccb7dda), // float_atan2f_rmul 0.024840285f\n    XCONST(0x3e3f4c37), // float_atan2f_radd 0.18681418f\n    XCONST(0xbdc0b66d), // float_atan2f_tmul -0.094097948f\n    XCONST(0xbeaa0d0a), // float_atan2f_tadd -0.33213072f\n    XCONST(0x3fc90fdb), // float_atan2f_halfpi 1.57079637f\n    XCONST(0x40490fdb), // float_atan2f_pi 3.14159274f\n    // Tangent approximation coefficients up to p8 and helpers\n    XCONST(1.0f),          // float_tan_p0 - Numerator constant term\n    XCONST(0.3333314036f), // float_tan_p2 - Numerator x^2 coefficient\n    XCONST(0.1333923995f), // float_tan_p4 - Numerator x^4 coefficient \n    XCONST(0.0533740603f), // float_tan_p6 - Numerator x^6 coefficient\n    XCONST(0.0245650893f), // float_tan_p8 - Numerator x^8 coefficient\n    XCONST(1.0f),          // float_tan_q0 - Denominator constant term\n    XCONST(0.1333835001f), // float_tan_q2 - Denominator x^2 coefficient\n    XCONST(0.0089270802f), // float_tan_q4 - Denominator x^4 coefficient\n    XCONST(0.0005908960f), // float_tan_q6 - Denominator x^6 coefficient\n    XCONST(0.0000342237f), // float_tan_q8 - Denominator x^8 coefficient\n    XCONST(1e-4f), // float_tan_small_limit\n    XCONST(0.97f), // float_tan_asympt_a1\n    XCONST(0.35f), // float_tan_asympt_a2\n    XCONST(0.8f), // float_tan_asympt_limit\n};\n\n\n#define CPTR(x) (xmmword_ptr[constptr + (x) * 16])\n\n// AVX2 stuff\n// constants for ymm\n\n#undef XCONST\n#define XCONST(x) { x, x, x, x, x, x, x, x }\n\nstatic constexpr ExprUnion logexpconst_avx alignas(32)[87][8] = {\n  XCONST(0x7FFFFFFF), // absmask\n  XCONST(0x7F), // c7F\n  XCONST(0x00800000), // min_norm_pos\n  XCONST(~0x7f800000), // inv_mant_mask\n  XCONST(1.0f), // float_one\n  XCONST(-1.0f), // float_minusone\n  XCONST(0.5f), // float_half\n  XCONST(0x80000000), // elsignmask\n  XCONST(255.0f), // store8\n  XCONST(1023.0f), // store10 (avs+)\n  XCONST(4095.0f), // store12 (avs+)\n  XCONST(16383.0f), // store14 (avs+)\n  XCONST(65535.0f), // store16\n  { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f }, // spatialX\n  { 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f }, // spatialX2\n  { (int)0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0, 0, 0, 0 }, // loadmask1000 not used, avx supports blendps\n  { (int)0xFFFFFFFF, (int)0xFFFFFFFF, 0x00000000, 0x00000000, 0, 0, 0, 0 }, // loadmask1100 not used, avx supports blendps\n  { (int)0xFFFFFFFF, (int)0xFFFFFFFF, (int)0xFFFFFFFF, 0x00000000, 0, 0, 0, 0 }, // loadmask1110 not used, avx supports blendps\n  XCONST(0), // n/a elShuffleForRight0\n  XCONST(0), // n/a elShuffleForRight1\n  XCONST(0), // n/a elShuffleForRight2\n  XCONST(0), // n/a elShuffleForRight3\n  XCONST(0), // n/a elShuffleForRight4\n  XCONST(0), // n/a elShuffleForRight5\n  XCONST(0), // n/a elShuffleForRight6\n  XCONST(0), // n/a elShuffleForLeft0\n  XCONST(0), // n/a elShuffleForLeft1\n  XCONST(0), // n/a elShuffleForLeft2\n  XCONST(0), // n/a elShuffleForLeft3\n  XCONST(0), // n/a elShuffleForLeft4\n  XCONST(0), // n/a elShuffleForLeft5\n  XCONST(0), // n/a elShuffleForLeft6\n  XCONST(88.3762626647949f), // exp_hi\n  XCONST(-88.3762626647949f), // exp_lo\n  XCONST(1.44269504088896341f), // cephes_LOG2EF\n  XCONST(0.693359375f), // cephes_exp_C1\n  XCONST(-2.12194440e-4f), // cephes_exp_C2\n  XCONST(1.9875691500E-4f), // cephes_exp_p0\n  XCONST(1.3981999507E-3f), // cephes_exp_p1\n  XCONST(8.3334519073E-3f), // cephes_exp_p2\n  XCONST(4.1665795894E-2f), // cephes_exp_p3\n  XCONST(1.6666665459E-1f), // cephes_exp_p4\n  XCONST(5.0000001201E-1f), // cephes_exp_p5\n  XCONST(0.707106781186547524f), // cephes_SQRTHF\n  XCONST(7.0376836292E-2f), // cephes_log_p0\n  XCONST(-1.1514610310E-1f), // cephes_log_p1\n  XCONST(1.1676998740E-1f), // cephes_log_p2\n  XCONST(-1.2420140846E-1f), // cephes_log_p3\n  XCONST(+1.4249322787E-1f), // cephes_log_p4\n  XCONST(-1.6668057665E-1f), // cephes_log_p5\n  XCONST(+2.0000714765E-1f), // cephes_log_p6\n  XCONST(-2.4999993993E-1f), // cephes_log_p7\n  XCONST(+3.3333331174E-1f), // cephes_log_p8\n  XCONST(0x3ea2f983), // float_invpi, 1/pi = 0.31830988618379067154f\n  XCONST(0x4b400000), // float_rintf  Used for rounding\n  XCONST(0x40490000), // float_pi1    High precision part of Pi\n  XCONST(0x3a7da000), // float_pi2    Second part of Pi for extended precision\n  XCONST(0x34222000), // float_pi3    Third part of Pi for extended precision\n  XCONST(0x2cb4611a), // float_pi4    Fourth part of Pi for extended precision\n  XCONST(0xbe2aaaa6), // float_sinC3\n  XCONST(0x3c08876a), // float_sinC5\n  XCONST(0xb94fb7ff), // float_sinC7\n  XCONST(0x362edef8), // float_sinC9\n  XCONST(static_cast<int32_t>(0xBEFFFFE2)), // float_cosC2\n  XCONST(0x3D2AA73C), // float_cosC4\n  XCONST(static_cast<int32_t>(0XBAB58D50)), // float_cosC6\n  XCONST(0x37C1AD76), // float_cosC8 \n  XCONST(0x3ccb7dda), // float_atan2f_rmul 0.024840285f\n  XCONST(0x3e3f4c37), // float_atan2f_radd 0.18681418f\n  XCONST(0xbdc0b66d), // float_atan2f_tmul -0.094097948f\n  XCONST(0xbeaa0d0a), // float_atan2f_tadd -0.33213072f\n  XCONST(0x3fc90fdb), // float_atan2f_halfpi 1.57079637f\n  XCONST(0x40490fdb), // float_atan2f_pi 3.14159274f\n  // Tangent approximation coefficients up to p8 and helpers\n  XCONST(1.0f),          // float_tan_p0 - Numerator constant term\n  XCONST(0.3333314036f), // float_tan_p2 - Numerator x^2 coefficient\n  XCONST(0.1333923995f), // float_tan_p4 - Numerator x^4 coefficient \n  XCONST(0.0533740603f), // float_tan_p6 - Numerator x^6 coefficient\n  XCONST(0.0245650893f), // float_tan_p8 - Numerator x^8 coefficient\n  XCONST(1.0f),          // float_tan_q0 - Denominator constant term\n  XCONST(0.1333835001f), // float_tan_q2 - Denominator x^2 coefficient\n  XCONST(0.0089270802f), // float_tan_q4 - Denominator x^4 coefficient\n  XCONST(0.0005908960f), // float_tan_q6 - Denominator x^6 coefficient\n  XCONST(0.0000342237f),  // float_tan_q8 - Denominator x^8 coefficient\n  XCONST(1e-4f), // float_tan_small_limit\n  XCONST(0.97f), // float_tan_asympt_a1\n  XCONST(0.35f), // float_tan_asympt_a2\n  XCONST(0.8f), // float_tan_asympt_limit\n};\n#undef XCONST\n\n#define CPTR_AVX(x) (ymmword_ptr[constptr + (x) * 32])\n\n#define EXP_PS(x) { \\\nXmmReg fx, emm0, etmp, y, mask, z; \\\nminps(x, CPTR(elexp_hi)); \\\nmaxps(x, CPTR(elexp_lo)); \\\nmovaps(fx, x); \\\nmulps(fx, CPTR(elcephes_LOG2EF)); \\\naddps(fx, CPTR(elfloat_half)); \\\ncvttps2dq(emm0, fx); \\\ncvtdq2ps(etmp, emm0); \\\nmovaps(mask, etmp); \\\ncmpnleps(mask, fx); \\\nandps(mask, CPTR(elfloat_one)); \\\nmovaps(fx, etmp); \\\nsubps(fx, mask); \\\nmovaps(etmp, fx); \\\nmulps(etmp, CPTR(elcephes_exp_C1)); \\\nmovaps(z, fx); \\\nmulps(z, CPTR(elcephes_exp_C2)); \\\nsubps(x, etmp); \\\nsubps(x, z); \\\nmovaps(z, x); \\\nmulps(z, z); \\\nmovaps(y, CPTR(elcephes_exp_p0)); \\\nmulps(y, x); \\\naddps(y, CPTR(elcephes_exp_p1)); \\\nmulps(y, x); \\\naddps(y, CPTR(elcephes_exp_p2)); \\\nmulps(y, x); \\\naddps(y, CPTR(elcephes_exp_p3)); \\\nmulps(y, x); \\\naddps(y, CPTR(elcephes_exp_p4)); \\\nmulps(y, x); \\\naddps(y, CPTR(elcephes_exp_p5)); \\\nmulps(y, z); \\\naddps(y, x); \\\naddps(y, CPTR(elfloat_one)); \\\ncvttps2dq(emm0, fx); \\\npaddd(emm0, CPTR(elc7F)); \\\npslld(emm0, 23); \\\nmulps(y, emm0); \\\nx = y; }\n\n#define LOG_PS(x) { \\\nXmmReg emm0, invalid_mask, mask, y, etmp, z; \\\nxorps(invalid_mask, invalid_mask); \\\ncmpnleps(invalid_mask, x); \\\nmaxps(x, CPTR(elmin_norm_pos)); \\\nmovaps(emm0, x); \\\npsrld(emm0, 23); \\\nandps(x, CPTR(elinv_mant_mask)); \\\norps(x, CPTR(elfloat_half)); \\\npsubd(emm0, CPTR(elc7F)); \\\ncvtdq2ps(emm0, emm0); \\\naddps(emm0, CPTR(elfloat_one)); \\\nmovaps(mask, x); \\\ncmpltps(mask, CPTR(elcephes_SQRTHF)); \\\nmovaps(etmp, x); \\\nandps(etmp, mask); \\\nsubps(x, CPTR(elfloat_one)); \\\nandps(mask, CPTR(elfloat_one)); \\\nsubps(emm0, mask); \\\naddps(x, etmp); \\\nmovaps(z, x); \\\nmulps(z, z); \\\nmovaps(y, CPTR(elcephes_log_p0)); \\\nmulps(y, x); \\\naddps(y, CPTR(elcephes_log_p1)); \\\nmulps(y, x); \\\naddps(y, CPTR(elcephes_log_p2)); \\\nmulps(y, x); \\\naddps(y, CPTR(elcephes_log_p3)); \\\nmulps(y, x); \\\naddps(y, CPTR(elcephes_log_p4)); \\\nmulps(y, x); \\\naddps(y, CPTR(elcephes_log_p5)); \\\nmulps(y, x); \\\naddps(y, CPTR(elcephes_log_p6)); \\\nmulps(y, x); \\\naddps(y, CPTR(elcephes_log_p7)); \\\nmulps(y, x); \\\naddps(y, CPTR(elcephes_log_p8)); \\\nmulps(y, x); \\\nmulps(y, z); \\\nmovaps(etmp, emm0); \\\nmulps(etmp, CPTR(elcephes_log_q1)); \\\naddps(y, etmp); \\\nmulps(z, CPTR(elfloat_half)); \\\nsubps(y, z); \\\nmulps(emm0, CPTR(elcephes_log_q2)); \\\naddps(x, y); \\\naddps(x, emm0); \\\norps(x, invalid_mask); }\n\n#define EXP_PS_AVX(x) { \\\nYmmReg fx, emm0, etmp, y, mask, z; \\\nvminps(x, x, CPTR_AVX(elexp_hi)); \\\nvmaxps(x, x, CPTR_AVX(elexp_lo)); \\\nvmulps(fx, x, CPTR_AVX(elcephes_LOG2EF)); \\\nvaddps(fx, fx, CPTR_AVX(elfloat_half)); \\\nvcvttps2dq(emm0, fx); \\\nvcvtdq2ps(etmp, emm0); \\\nvcmpps(mask, etmp, fx, _CMP_GT_OQ); /* cmpnleps */ \\\nvandps(mask, mask, CPTR_AVX(elfloat_one)); \\\nvsubps(fx, etmp, mask); \\\nvfnmadd231ps(x, fx, CPTR_AVX(elcephes_exp_C1)); \\\nvfnmadd231ps(x, fx, CPTR_AVX(elcephes_exp_C2)); \\\nvmulps(z, x, x); \\\nvmovaps(y, CPTR_AVX(elcephes_exp_p0)); \\\nvfmadd213ps(y, x, CPTR_AVX(elcephes_exp_p1)); \\\nvfmadd213ps(y, x, CPTR_AVX(elcephes_exp_p2)); \\\nvfmadd213ps(y, x, CPTR_AVX(elcephes_exp_p3)); \\\nvfmadd213ps(y, x, CPTR_AVX(elcephes_exp_p4)); \\\nvfmadd213ps(y, x, CPTR_AVX(elcephes_exp_p5)); \\\nvfmadd213ps(y, z, x); \\\nvaddps(y, y, CPTR_AVX(elfloat_one)); \\\nvcvttps2dq(emm0, fx); \\\nvpaddd(emm0, emm0, CPTR_AVX(elc7F)); \\\nvpslld(emm0, emm0, 23); \\\nvmulps(x, y, emm0); \\\n}\n\n#define LOG_PS_AVX(x) { \\\nYmmReg emm0, invalid_mask, mask, y, etmp, z; \\\nvcmpps(invalid_mask, zero, x, _CMP_GT_OQ); /* cmpnleps. or signalling _CMP_NLE_US? */ \\\nvmaxps(x, x, CPTR_AVX(elmin_norm_pos)); \\\nvpsrld(emm0, x, 23); \\\nvandps(x, x, CPTR_AVX(elinv_mant_mask)); \\\nvorps(x, x, CPTR_AVX(elfloat_half)); \\\nvpsubd(emm0, emm0, CPTR_AVX(elc7F)); \\\nvcvtdq2ps(emm0, emm0); \\\nvaddps(emm0, emm0, CPTR_AVX(elfloat_one)); \\\nvcmpps(mask, x, CPTR_AVX(elcephes_SQRTHF), _CMP_LT_OQ); /* cmpltps. or signalling _CMP_LT_OS? */ \\\nvandps(etmp, x, mask); \\\nvsubps(x, x, CPTR_AVX(elfloat_one)); \\\nvandps(mask, mask, CPTR_AVX(elfloat_one)); \\\nvsubps(emm0, emm0, mask); \\\nvaddps(x, x, etmp); \\\nvmulps(z, x, x); \\\nvmovaps(y, CPTR_AVX(elcephes_log_p0)); \\\nvfmadd213ps(y, x, CPTR_AVX(elcephes_log_p1)); \\\nvfmadd213ps(y, x, CPTR_AVX(elcephes_log_p2)); \\\nvfmadd213ps(y, x, CPTR_AVX(elcephes_log_p3)); \\\nvfmadd213ps(y, x, CPTR_AVX(elcephes_log_p4)); \\\nvfmadd213ps(y, x, CPTR_AVX(elcephes_log_p5)); \\\nvfmadd213ps(y, x, CPTR_AVX(elcephes_log_p6)); \\\nvfmadd213ps(y, x, CPTR_AVX(elcephes_log_p7)); \\\nvfmadd213ps(y, x, CPTR_AVX(elcephes_log_p8)); \\\nvmulps(y, y, x); \\\nvmulps(y, y, z); \\\nvfmadd231ps(y, emm0, CPTR_AVX(elcephes_log_q1)); \\\nvfnmadd231ps(y, z, CPTR_AVX(elfloat_half)); \\\nvaddps(x, x, y); \\\nvfmadd231ps(x, emm0, CPTR_AVX(elcephes_log_q2)); \\\nvorps(x, x, invalid_mask); }\n\n// Note: VS Expr changed a lot since ported to Avisynth, \n// Here we are using their VEX macros for easy port of new sin and cos\n// however we do not support VEX encoding or FMA3 in xmm register mode\n// Note: VEX2 cmpltps -> vcmpltps does not work so we uncomment v##op parts as well (comparisons changed in vex)\n#define VEX1(op, arg1, arg2) \\\ndo { \\\n  if constexpr(false /*cpuFlags & CPUF_AVX*/) \\\n    /*v##op(arg1, arg2)*/; \\\n  else \\\n    op(arg1, arg2); \\\n} while (0)\n#define VEX1IMM(op, arg1, arg2, imm) \\\ndo { \\\n  if constexpr(false /*cpuFlags & CPUF_AVX*/) { \\\n    /*v##op(arg1, arg2, imm)*/; \\\n  } else if (arg1 == arg2) { \\\n    op(arg2, imm); \\\n  } else { \\\n    movdqa(arg1, arg2); \\\n    op(arg1, imm); \\\n  } \\\n} while (0)\n#define VEX2(op, arg1, arg2, arg3) \\\ndo { \\\n  if constexpr(false /*cpuFlags & CPUF_AVX*/) { \\\n    /*v##op(arg1, arg2, arg3)*/; \\\n  } else if (arg1 == arg2) { \\\n    op(arg2, arg3); \\\n  } else if (arg1 != arg3) { \\\n    movdqa(arg1, arg2); \\\n    op(arg1, arg3); \\\n  } else { \\\n    XmmReg tmp; \\\n    movdqa(tmp, arg2); \\\n    op(tmp, arg3); \\\n    movdqa(arg1, tmp); \\\n  } \\\n} while (0)\n#define VEX2IMM(op, arg1, arg2, arg3, imm) \\\ndo { \\\n  if constexpr(false/*cpuFlags & CPUF_AVX*/) { \\\n    /*v##op(arg1, arg2, arg3, imm)*/; \\\n  } else if (arg1 == arg2) { \\\n    op(arg2, arg3, imm); \\\n  } else if (arg1 != arg3) { \\\n    movdqa(arg1, arg2); \\\n    op(arg1, arg3, imm); \\\n  } else { \\\n    XmmReg tmp; \\\n    movdqa(tmp, arg2); \\\n    op(tmp, arg3, imm); \\\n    movdqa(arg1, tmp); \\\n  } \\\n} while (0)\n\n#if 0\n// Fast tangent approximation using rational function with 8th order terms\nfloat fast_tanf(float x) {\n  // Constants for Pi approximation and range reduction\n  const float polyPI = 3.14159265358979f;\n  const float halfPI = polyPI * 0.5f;\n  // Reduce to [-polyPI, polyPI] range\n  float y = fmodf(x, polyPI);\n  if (y > halfPI) y -= polyPI;\n  else if (y < -halfPI) y += polyPI;\n  // At this point y is in [-polyPI/2, polyPI/2]\n  // For very small angles, return the angle itself\n  // LLVM would add a small epsilon: sign(y)*2^-25 (0x1p-25f)\n  float abs_y = fabsf(y);\n  const float small_limit = 1e-4f;\n  if (abs_y < small_limit) {\n    return y;\n  }\n  // Check proximity to asymptotes\n  const float asympt_limit = 0.8f;\n  float distToAsymptote = halfPI - abs_y;\n  // If very close to ±polyPI/2, use asymptotic approximation\n  if (distToAsymptote < asympt_limit) {\n    // The tangent function approaches 1/distToAsymptote as y approaches +/-polyPI/2\n    // Improved coefficients based on curve fitting to better match std::tan\n    // not needed a 3rd term float asymptotic = 1.0f / (distToAsymptote * (0.9963f + distToAsymptote * (0.3642f + distToAsymptote * 0.0173f)));\n    float asymptotic = 1.0f / (distToAsymptote * (0.97f + distToAsymptote * 0.35f));\n    // Preserve sign\n    return (y < 0) ? -asymptotic : asymptotic;\n  }\n  float y2 = y * y;\n  // Optimized coefficients with terms up to 8th order\n  // Numerator coefficients\n  const float p0 = 1.0f;\n  const float p2 = 0.3333314036f;\n  const float p4 = 0.1333923995f;\n  const float p6 = 0.0533740603f;\n  const float p8 = 0.0245650893f;\n  // Denominator coefficients\n  const float q0 = 1.0f;\n  const float q2 = 0.1333835001f;\n  const float q4 = 0.0089270802f;\n  const float q6 = 0.0005908960f;\n  const float q8 = 0.0000342237f;\n  // Calculate approximation using Horner's method for efficiency\n  float num = y * (p0 + y2 * (p2 + y2 * (p4 + y2 * (p6 + y2 * p8))));\n  float den = q0 + y2 * (q2 + y2 * (q4 + y2 * (q6 + y2 * q8)));\n  return num / den;\n}\n// We are good with this, but LLVM does differently:\n// https://github.com/llvm/llvm-project/blob/main/libc/src/math/generic/tanf.cpp\n#endif\n\n// Fast tangent approximation for non-AVX version\n#define TAN_PS(x0) { \\\nXmmReg x1, x2, x3, x4, x5, x6, x7, x8, x9, x10; \\\n/* Normalize to [-pi, pi] using multiplication and subtraction */ \\\nVEX1(movaps, x1, CPTR(float_invpi)); /* 1/pi */ \\\nVEX2(mulps, x2, x0, x1); /* x / pi */ \\\n/* round to nearest integer */ \\\nVEX1(movaps, x3, CPTR(float_rintf)); /* round to int helper */ \\\nVEX2(addps, x4, x3, x2); /* x/pi + 2^23 */ \\\nVEX2(subps, x4, x4, x3); /* round(x/pi) */ \\\nVEX1(movaps, x5, CPTR(float_pi1)); /* Load pi1 (highest precision part) */ \\\nVEX2(mulps, x6, x4, x5); /* round(x/pi) * pi1 */ \\\nVEX2(subps, x7, x0, x6); /* Remainder after subtracting largest part */ \\\n/* Subtract remaining parts for higher precision */ \\\nVEX1(movaps, x3, CPTR(float_pi2)); \\\nVEX2(mulps, x3, x4, x3); /* round(x/pi) * pi2 */ \\\nVEX2(subps, x7, x7, x3); /* Further refine remainder */ \\\nVEX1(movaps, x3, CPTR(float_pi3)); \\\nVEX2(mulps, x3, x4, x3); /* round(x/pi) * pi3 */ \\\nVEX2(subps, x7, x7, x3); /* Further refine remainder */ \\\nVEX1(movaps, x3, CPTR(float_pi4)); \\\nVEX2(mulps, x3, x4, x3); /* round(x/pi) * pi4 */ \\\nVEX2(subps, x7, x7, x3); /* Final remainder, now x is in range [-pi, pi] */ \\\n/* Check range for symmetry, normalize to [-pi/2, pi/2] */ \\\nVEX2(mulps, x6, x5, CPTR(elfloat_half)); /* halfPI = pi/2 */ \\\nVEX2(cmpltps, x3, x6, x7); /* halfPI < y (cmpgt -> cmplt)*/ \\\nVEX2(subps, x4, x5, x7); /* pi - y */ \\\n/* blend: if y > halfPI, use pi - y */ \\\nVEX1(movaps, x2, x3); \\\nVEX2(andps, x2, x2, x4); \\\nVEX2(andnps, x3, x3, x7); \\\nVEX2(orps, x7, x3, x2); /* now y is <= pi/2 */ \\\n/* Check for y < -halfPI */ \\\nVEX1(movaps, x3, x6); \\\nVEX2(xorps, x3, x3, CPTR(elsignmask)); /* -halfPI */ \\\nVEX2(cmpltps, x2, x7, x3); /* y < -halfPI */ \\\nVEX2(xorps, x4, x5, CPTR(elsignmask)); /* -pi */ \\\nVEX2(subps, x4, x4, x7); /* -pi - y */ \\\n/* blend: if y < -halfPI, use -pi - y */ \\\nVEX1(movaps, x3, x2); \\\nVEX2(andps, x3, x3, x4); \\\nVEX2(andnps, x2, x2, x7); \\\nVEX2(orps, x7, x2, x3); /* now y is in [-pi/2, pi/2] */ \\\n/* Range reduction end */ \\\n\\\n/* Check for small values */ \\\nVEX1(movaps, x2, x7); \\\nVEX2(andps, x2, x2, CPTR(elabsmask)); /* abs_y */ \\\nVEX2(cmpltps, x3, x2, CPTR(float_tan_small_limit)); /* abs_y < small_limit */ \\\nVEX2(andps, x3, x3, x7); /* y * (abs_y < small_limit) */ \\\n\\\n/* Check for asymptotic proximity */ \\\nVEX1(movaps, x4, x6); /* Load halfPI */ \\\nVEX2(subps, x4, x4, x2); /* distToAsymptote = halfPI - abs_y */ \\\nVEX2(cmpltps, x5, x4, CPTR(float_tan_asympt_limit)); /* distToAsymptote < asympt_limit */ \\\n\\\n/* Calculate asymptotic approximation: 1.0f / (distToAsymptote * (0.97f + distToAsymptote * 0.35f)) */ \\\nVEX2(mulps, x8, x4, CPTR(float_tan_asympt_a2)); /* distToAsymptote * 0.35f */ \\\nVEX2(addps, x8, x8, CPTR(float_tan_asympt_a1)); /* 0.97f + distToAsymptote * 0.35f */ \\\nVEX2(mulps, x8, x8, x4); /* distToAsymptote * (0.97f + distToAsymptote * 0.35f) */ \\\nVEX1(movaps, x4, CPTR(elfloat_one)); /* 1.0f */ \\\nVEX2(divps, x9, x4, x8); /* 1.0f / (distToAsymptote * (0.97f + distToAsymptote * 0.35f)) */ \\\n\\\n/* Adjust sign for asymptotic approximation */ \\\nVEX1(movaps, x8, x7); /* original y */ \\\nVEX2(andps, x8, x8, CPTR(elsignmask)); /* sign of y */ \\\nVEX2(xorps, x9, x9, x8); /* apply sign to asymptotic result */ \\\n\\\n/* Calculate rational approximation for regular values */ \\\nVEX1(movaps, x2, x7); \\\nVEX2(mulps, x2, x2, x7); /* y^2 */ \\\n\\\n/* Compute numerator with higher order terms */ \\\nVEX1(movaps, x10, CPTR(float_tan_p8)); /* p8 */ \\\nVEX2(mulps, x10, x10, x2); /* p8*y^2 */ \\\nVEX2(addps, x10, x10, CPTR(float_tan_p6)); /* p6 + p8*y^2 */ \\\nVEX2(mulps, x10, x10, x2); /* y^2 * (p6 + p8*y^2) */ \\\nVEX2(addps, x10, x10, CPTR(float_tan_p4)); /* p4 + y^2 * (p6 + p8*y^2) */ \\\nVEX2(mulps, x10, x10, x2); /* y^2 * (p4 + y^2 * (p6 + p8*y^2)) */ \\\nVEX2(addps, x10, x10, CPTR(float_tan_p2)); /* p2 + y^2 * (p4 + y^2 * (p6 + p8*y^2)) */ \\\nVEX2(mulps, x10, x10, x2); /* y^2 * (p2 + y^2 * (p4 + y^2 * (p6 + p8*y^2))) */ \\\nVEX2(addps, x10, x10, CPTR(float_tan_p0)); /* p0 + y^2 * (p2 + y^2 * (p4 + y^2 * (p6 + p8*y^2))) */ \\\nVEX2(mulps, x10, x10, x7); /* y * (p0 + y^2 * (p2 + y^2 * (p4 + y^2 * (p6 + p8*y^2)))) */ \\\n\\\n/* Compute denominator with higher order terms */ \\\nVEX1(movaps, x8, CPTR(float_tan_q8)); /* q8 */ \\\nVEX2(mulps, x8, x8, x2); /* q8*y^2 */ \\\nVEX2(addps, x8, x8, CPTR(float_tan_q6)); /* q6 + q8*y^2 */ \\\nVEX2(mulps, x8, x8, x2); /* y^2 * (q6 + q8*y^2) */ \\\nVEX2(addps, x8, x8, CPTR(float_tan_q4)); /* q4 + y^2 * (q6 + q8*y^2) */ \\\nVEX2(mulps, x8, x8, x2); /* y^2 * (q4 + y^2 * (q6 + q8*y^2)) */ \\\nVEX2(addps, x8, x8, CPTR(float_tan_q2)); /* q2 + y^2 * (q4 + y^2 * (q6 + q8*y^2)) */ \\\nVEX2(mulps, x8, x8, x2); /* y^2 * (q2 + y^2 * (q4 + y^2 * (q6 + q8*y^2))) */ \\\nVEX2(addps, x8, x8, CPTR(float_tan_q0)); /* q0 + y^2 * (q2 + y^2 * (q4 + y^2 * (q6 + q8*y^2))) */ \\\n\\\n/* Division: numerator/denominator for regular case */ \\\nVEX2(divps, x1, x10, x8); /* Final result: tan(y) = numerator/denominator */ \\\n\\\n/* Select the appropriate result based on conditions */ \\\n/* If close to asymptote, use asymptotic approximation, else use rational approximation */ \\\nVEX1(movaps, x2, x5); /* Load asymptote condition */ \\\nVEX2(andps, x2, x2, x9); /* asymptotic * (distToAsymptote < asympt_limit) */ \\\nVEX2(andnps, x5, x5, x1); /* rational * !(distToAsymptote < asympt_limit) */ \\\nVEX2(orps, x1, x5, x2); /* Blend asymptotic and rational results */ \\\n\\\n/* If very small value, use y itself, otherwise use computed result */ \\\nVEX2(andnps, x5, x3, x1); /* result * !(abs_y < small_limit) */ \\\nVEX2(orps, x0, x3, x5); /* Final result with small value handling */ \\\n}\n\n// Fast tangent approximation for AVX version\n#define TAN_PS_AVX(x0) { \\\nYmmReg x1, x2, x3, x4, x5, x6, x7, x8, x9, x10; \\\n/* Normalize to [-pi, pi] using multiplication and subtraction */ \\\nvmovaps(x1, CPTR_AVX(float_invpi)); /* 1/pi */ \\\nvmulps(x2, x0, x1); /* x / pi */ \\\nvroundps(x3, x2, FROUND_TO_NEAREST_INT); /* round(x / pi) */ \\\nvmovaps(x4, CPTR_AVX(float_pi1)); /* Load pi1 (highest precision part) */ \\\nvmulps(x5, x3, x4); /* round(x / pi) * pi1 */ \\\nvsubps(x6, x0, x5); /* Remainder after subtracting largest part */ \\\n/* Subtract remaining parts for higher precision */ \\\nvmovaps(x7, CPTR_AVX(float_pi2)); \\\nvmulps(x7, x3, x7); /* round(x / pi) * pi2 */ \\\nvsubps(x6, x6, x7); /* Further refine remainder */ \\\nvmovaps(x7, CPTR_AVX(float_pi3)); \\\nvmulps(x7, x3, x7); /* round(x / pi) * pi3 */ \\\nvsubps(x6, x6, x7); /* Further refine remainder */ \\\nvmovaps(x7, CPTR_AVX(float_pi4)); \\\nvmulps(x7, x3, x7); /* round(x / pi) * pi4 */ \\\nvsubps(x6, x6, x7); /* Final remainder, now x is in range [-pi, pi] */ \\\n/* Check range for symmetry, normalize to [-pi/2, pi/2] */ \\\nvmulps(x5, x4, CPTR_AVX(elfloat_half)); /* halfPI = pi/2 */ \\\nvcmpps(x7, x6, x5, _CMP_GT_OQ); /* y > halfPI */ \\\nvsubps(x8, x4, x6); /* pi - y */ \\\nvblendvps(x6, x6, x8, x7); /* if (y > halfPI) y = pi - y; */ \\\n/* Check for y < -halfPI */ \\\nvxorps(x7, x5, CPTR_AVX(elsignmask)); /* -halfPI */ \\\nvcmpps(x8, x6, x7, _CMP_LT_OQ); /* y < -halfPI */ \\\nvxorps(x2, x4, CPTR_AVX(elsignmask)); /* -pi */ \\\nvsubps(x2, x2, x6); /* -pi - y */ \\\nvblendvps(x6, x6, x2, x8); /* if (y < -halfPI) y = -pi - y; */ \\\n/* now y is in [-pi/2, pi/2] */ \\\n/* Range reduction end */ \\\n\\\n/* Check for small values */ \\\nvandps(x2, x6, CPTR_AVX(elabsmask)); /* abs_y */ \\\nvcmpps(x3, x2, CPTR_AVX(float_tan_small_limit), _CMP_LT_OQ); /* abs_y < small_limit */ \\\n/* Save small value result for later blending */ \\\nvandps(x7, x6, x3); /* y * (abs_y < small_limit) */ \\\n\\\n/* Check for asymptotic proximity */ \\\nvmovaps(x4, x5); /* Load halfPI */ \\\nvsubps(x4, x4, x2); /* distToAsymptote = halfPI - abs_y */ \\\nvcmpps(x5, x4, CPTR_AVX(float_tan_asympt_limit), _CMP_LT_OQ); /* distToAsymptote < asympt_limit */ \\\n\\\n/* Calculate asymptotic approximation */ \\\nvmulps(x8, x4, CPTR_AVX(float_tan_asympt_a2)); /* distToAsymptote * 0.35f */ \\\nvaddps(x8, x8, CPTR_AVX(float_tan_asympt_a1)); /* 0.97f + distToAsymptote * 0.35f */ \\\nvmulps(x8, x8, x4); /* distToAsymptote * (0.97f + distToAsymptote * 0.35f) */ \\\nvmovaps(x4, CPTR_AVX(elfloat_one)); /* Load 1.0f */ \\\nvdivps(x9, x4, x8); /* 1.0f / (distToAsymptote * (0.97f + distToAsymptote * 0.35f)) */ \\\n\\\n/* Adjust sign for asymptotic approximation */ \\\nvmovaps(x8, x6); /* original y */ \\\nvandps(x8, x8, CPTR_AVX(elsignmask)); /* sign of y */ \\\nvxorps(x9, x9, x8); /* apply sign to asymptotic result */ \\\n\\\n/* Calculate rational approximation for regular values */ \\\nvmulps(x2, x6, x6); /* y^2 */ \\\n\\\n/* Compute numerator with higher order terms using FMA instructions */ \\\nvmovaps(x10, CPTR_AVX(float_tan_p8)); /* p8 */ \\\nvfmadd213ps(x10, x2, CPTR_AVX(float_tan_p6)); /* p6 + p8*y^2 */ \\\nvfmadd213ps(x10, x2, CPTR_AVX(float_tan_p4)); /* p4 + y^2 * (p6 + p8*y^2) */ \\\nvfmadd213ps(x10, x2, CPTR_AVX(float_tan_p2)); /* p2 + y^2 * (p4 + y^2 * (p6 + p8*y^2)) */ \\\nvfmadd213ps(x10, x2, CPTR_AVX(float_tan_p0)); /* p0 + y^2 * (p2 + y^2 * (p4 + y^2 * (p6 + p8*y^2))) */ \\\nvmulps(x10, x10, x6); /* y * (p0 + y^2 * (p2 + y^2 * (p4 + y^2 * (p6 + p8*y^2)))) */ \\\n\\\n/* Compute denominator with higher order terms using FMA instructions */ \\\nvmovaps(x8, CPTR_AVX(float_tan_q8)); /* q8 */ \\\nvfmadd213ps(x8, x2, CPTR_AVX(float_tan_q6)); /* q6 + q8*y^2 */ \\\nvfmadd213ps(x8, x2, CPTR_AVX(float_tan_q4)); /* q4 + y^2 * (q6 + q8*y^2) */ \\\nvfmadd213ps(x8, x2, CPTR_AVX(float_tan_q2)); /* q2 + y^2 * (q4 + y^2 * (q6 + q8*y^2)) */ \\\nvfmadd213ps(x8, x2, CPTR_AVX(float_tan_q0)); /* q0 + y^2 * (q2 + y^2 * (q4 + y^2 * (q6 + q8*y^2))) */ \\\n\\\n/* Division: numerator/denominator */ \\\nvdivps(x1, x10, x8); /* tan(y) = numerator/denominator */ \\\n\\\n/* Select appropriate result based on conditions */ \\\n/* If close to asymptote, use asymptotic approximation, else use rational approximation */ \\\nvblendvps(x1, x1, x9, x5); /* Blend asymptotic and rational results */ \\\n\\\n/* If very small value, use y itself, otherwise use computed result */ \\\nvblendvps(x0, x1, x7, x3); /* Final result with small value handling */ \\\n}\n\n// atan2: based on https://stackoverflow.com/questions/46210708/atan2-approximation-with-11bits-in-mantissa-on-x86with-sse2-and-armwith-vfpv4?noredirect=1&lq=1\n#if 0\nfloat fast_atan2f(float y, float x)\n{\n  // max rel err = 3.53486939e-5\n  const float atan2f_rmul = 0.024840285f;\n  const float atan2f_radd = 0.18681418f;\n  const float atan2f_tmul = -0.094097948f;\n  const float atan2f_tadd = -0.33213072f;\n  const float atan2f_halfpi = 1.57079637f;\n  const float atan2f_pi = 3.14159274f;\n\n  float a, r, s, t, c, q, ax, ay, mx, mn;\n  ax = fabsf(x);\n  ay = fabsf(y);\n\n  mx = fmaxf(ay, ax);\n  mn = fminf(ay, ax);\n  a = mn / mx;\n  // Minimax polynomial approximation to atan(a) on [0,1]\n  s = a * a;\n  c = s * a;\n  q = s * s;\n  r = atan2f_rmul * q + atan2f_radd;\n  t = atan2f_tmul * q + atan2f_tadd;\n  r = r * s + t;\n  r = r * c + a;\n  // Map to full circle\n  if (ay > ax) r = atan2f_halfpi - r;\n  if (x < 0) r = atan2f_pi - r;\n  if (y < 0) r = -r;\n  return r;\n}\n#endif\n\n// atan2(0, 0) = 0\n// ~speed: \"y x atan2\" C/SSE2/AVX2:52/480/1000 fps\n#define ATAN2_PS(x0 /*y*/, /*x*/x1) { \\\nXmmReg x2, x3, x4, x5, x6, x7, x8; \\\n/*VEX1(movaps, x1, x);*/ \\\n/*VEX1(movaps, x0, y);*/ \\\n/* Remove sign */ \\\nVEX1(movaps, x3, CPTR(elabsmask)); \\\nVEX1(movaps, x2, x1); \\\nVEX2(andps, x2, x2, x3); /* ax = fabsf (x); */ \\\nVEX2(andps, x3, x3, x0); /* ay = fabsf (y); */ \\\nVEX1(movaps, x4, x3); \\\nVEX2(maxps, x4, x4, x2); /* mx = fmaxf (ay, ax); */ \\\nVEX1(movaps, x5, x3); \\\nVEX2(minps, x5, x5, x2); /* fminf (ay, ax); */ \\\nVEX2(divps, x5, x5, x4); /* a = mn / mx; */ \\\nVEX1(movaps, x4, x5); \\\nVEX2(mulps, x4, x4, x5); /* s = a * a; */ \\\nVEX1(movaps, x6, x4); \\\nVEX2(mulps, x6, x6, x4); /* q = s * s; */ \\\nVEX1(movaps, x7, CPTR(float_atan2f_rmul)); \\\nVEX2(mulps, x7, x7, x6); /* r = atan2f_rmul * q (+ atan2f_radd) */ \\\nVEX2(addps, x7, x7, CPTR(float_atan2f_radd)); /* r = (atan2f_rmul * q) + atan2f_radd; */ \\\nVEX2(mulps, x7, x7, x4); /* r = r * s (+ t) */ \\\nVEX2(mulps, x4, x4, x5); /* c = s * a; */ \\\nVEX2(mulps, x6, x6, CPTR(float_atan2f_tmul)); /* t = atan2f_tmul * q (+ atan2f_tadd) */ \\\nVEX2(addps, x6, x6, CPTR(float_atan2f_tadd)); /* t = (atan2f_tmul * q) + atan2f_tadd; */ \\\nVEX2(addps, x7, x7, x6); /* r = (r * s) + t; */ \\\nVEX2(mulps, x7, x7, x4); /* r = r * c (+ a) */ \\\nVEX2(addps, x7, x7, x5); /* r = (r * c) + a */ \\\n/* Map to full circle */ \\\n/* if (ay > ax) r = atan2f_halfpi - r; */ \\\n/* if (x < 0) r = atan2f_pi - r; */ \\\n/* if (y < 0) r = -r; */ \\\n/* r = atan2f_halfpi - r */ \\\nVEX1(movaps, x4, CPTR(float_atan2f_halfpi)); \\\nVEX2(subps, x4, x4, x7); /* r = atan2f_halfpi - r */ \\\nVEX2(cmpltps, x2, x2, x3); /* if (ay > ax) */ \\\n/* blend */ \\\nVEX1(movaps, x3, x2); \\\nVEX2(andnps, x3, x3, x7); \\\nVEX2(andps, x2, x2, x4); \\\nVEX2(orps, x2, x2, x3); \\\n/* r = atan2f_pi - r; */ \\\nVEX1(movaps, x3, CPTR(float_atan2f_pi)); \\\nVEX2(subps, x3, x3, x2); /* r = atan2f_pi - r */ \\\n/* if (x < 0) */ \\\nVEX2(xorps, x4, x4, x4); /* zero */ \\\nVEX2(cmpltps, x1, x1, x4); /* if (x < 0) */ \\\n/* blend */ \\\nVEX1(movaps, x5, x1); \\\nVEX2(andnps, x5, x5, x2); \\\nVEX2(andps, x1, x1, x3); \\\nVEX2(orps, x1, x1, x5); \\\n/* r = -r; */ \\\nVEX1(movaps, x2, CPTR(elsignmask)); \\\nVEX2(subps, x2, x2, x1); /* r = -r */ \\\n/* if (y < 0) */ \\\nVEX2(cmpltps, x0, x0, x4); /* if (y < 0) */ \\\n/* blend */ \\\nVEX1(movaps, x3, x0); \\\nVEX2(andnps, x3, x3, x1); \\\nVEX2(andps, x0, x0, x2); \\\nVEX2(orps, x0, x0, x3); \\\n/* extra check when 0,0 given -> convert NaN to 0 */ \\\nVEX1(movaps, x3, x0); \\\nVEX2(cmpordps, x3, x3, x3);/* find NaNs. 0: NaN in either. FFFF: both non-Nan */ \\\n/* mask NaN to zero */ \\\nVEX2(andps, x0, x0, x3); \\\n/* return value in y */ \\\n/* input was \"x0 for y */ \\\n}\n\n#define ATAN2_PS_AVX(x0 /*y*/, x1 /*x*/) { \\\nYmmReg x2, x3, x4, x5, x6, x7, x8; \\\n/* Remove sign */ \\\n/* vmovaps(x1, x); */ \\\n/* vmovaps(x0, y); */ \\\nvmovaps(x2, CPTR_AVX(elabsmask)); \\\nvandps(x8, x1, x2); /* ax = fabsf (x); */ \\\nvandps(x2, x0, x2); /* ay = fabsf (y); */ \\\nvmaxps(x4, x8, x2); /* mx = fmaxf (ay, ax); */ \\\nvminps(x5, x8, x2); /* fminf (ay, ax); */ \\\nvdivps(x4, x5, x4); /* a = mn / mx; */ \\\nvmulps(x5, x4, x4); /* s = a * a; */ \\\nvmulps(x6, x5, x5); /* q = s * s; */ \\\nvmovaps(x7, CPTR_AVX(float_atan2f_rmul)); \\\nvmovaps(x3, CPTR_AVX(float_atan2f_radd)); \\\nvfmadd213ps(x7, x6, CPTR_AVX(float_atan2f_radd)); /* r = atan2f_rmul * q + atan2f_radd; */ \\\nvmovaps(x3, CPTR_AVX(float_atan2f_tmul)); \\\nvfmadd213ps(x3, x6, CPTR_AVX(float_atan2f_tadd)); /* t = atan2f_tmul * q + atan2f_tadd */ \\\nvmulps(x6, x5, x4); \\\nvfmadd231ps(x3, x5, x7); /* r = r * s + t; */ \\\nvfmadd213ps(x3, x6, x4); /* r = (r * c) + a */ \\\n/* Map to full circle */ \\\n/* if (ay > ax) r = atan2f_halfpi - r; */ \\\n/* if (x < 0) r = atan2f_pi - r; */ \\\n/* if (y < 0) r = -r; */ \\\n/* r = atan2f_pi - r */ \\\nvmovaps(x4, CPTR_AVX(float_atan2f_halfpi)); \\\nvsubps(x4, x4, x3); /* r = atan2f_halfpi - r */ \\\nvcmpps(x2, x8, x2, _CMP_LT_OQ); /*vcmpltps(x2, x8, x2);*/ /* if (ay > ax) */ \\\nvblendvps(x2, x3, x4, x2); \\\nvmovaps(x3, CPTR_AVX(float_atan2f_pi)); \\\nvsubps(x3, x3, x2); /* r = atan2f_pi - r */ \\\nvxorps(x4, x4, x4); \\\nvcmpps(x1, x1, x4, _CMP_LT_OQ); /* vcmpltps(x1, x1, x4); */ /* if (x < 0) */ \\\nvblendvps(x1, x2, x3, x1); \\\nvmovaps(x2, CPTR_AVX(elsignmask)); \\\nvxorps(x2, x1, x2); /* r = -r */ \\\nvcmpps(x0, x0, x4, _CMP_LT_OQ); /* vcmpltps(x0, x0, x4); */ /* if (y < 0) */ \\\nvblendvps(x0, x1, x2, x0); \\\n/* extra check when 0,0 given -> convert NaN to 0 */ \\\nvcmpps(x3, x0, x0, _CMP_ORD_Q); /* vcmpordps, x3, x3, x3);*/ /* find NaNs. 0: NaN in either. FFFF: both non-Nan */ \\\n/* mask NaN to zero */ \\\nvandps(x0, x0, x3); \\\n/* return value in y */ \\\n/* no need. input was \"x0\" for y */ \\\n}\n\n#define SINCOS_PS(issin, y, x) { \\\nXmmReg t1, sign, t2, t3, t4; \\\n/* // Remove sign */ \\\nVEX1(movaps, t1, CPTR(elabsmask)); \\\nif (issin) { \\\n  VEX1(movaps, sign, t1); \\\n  VEX2(andnps, sign, sign, x); \\\n} \\\nelse { \\\n  VEX2(pxor, sign, sign, sign); \\\n} \\\nVEX2(andps, t1, t1, x); \\\n/*// Range reduction*/ \\\nVEX1(movaps, t3, CPTR(float_rintf)); \\\nVEX2(mulps, t2, t1, CPTR(float_invpi)); \\\nVEX2(addps, t2, t2, t3); \\\nVEX1IMM(pslld, t4, t2, 31); \\\nVEX2(xorps, sign, sign, t4); \\\nVEX2(subps, t2, t2, t3); \\\nif constexpr(false /*cpuFlags & CPUF_FMA3*/) { \\\n  vfnmadd231ps(t1, t2, CPTR(float_pi1)); \\\n  vfnmadd231ps(t1, t2, CPTR(float_pi2)); \\\n  vfnmadd231ps(t1, t2, CPTR(float_pi3)); \\\n  vfnmadd231ps(t1, t2, CPTR(float_pi4)); \\\n} \\\nelse { \\\n  VEX2(mulps, t4, t2, CPTR(float_pi1)); \\\n  VEX2(subps, t1, t1, t4); \\\n  VEX2(mulps, t4, t2, CPTR(float_pi2)); \\\n  VEX2(subps, t1, t1, t4); \\\n  VEX2(mulps, t4, t2, CPTR(float_pi3)); \\\n  VEX2(subps, t1, t1, t4); \\\n  VEX2(mulps, t4, t2, CPTR(float_pi4)); \\\n  VEX2(subps, t1, t1, t4); \\\n} \\\nif (issin) { \\\n  /* // Evaluate minimax polynomial for sin(x) in [-pi/2, pi/2] interval */ \\\n  /* // Y <- X + X * X^2 * (C3 + X^2 * (C5 + X^2 * (C7 + X^2 * C9))) */ \\\n  VEX2(mulps, t2, t1, t1); \\\n  if constexpr(false /*cpuFlags & CPUF_FMA3*/) { \\\n    vmovaps(t3,  CPTR(float_sinC7)); \\\n    vfmadd231ps(t3, t2, CPTR(float_sinC9)); \\\n    vfmadd213ps(t3, t2, CPTR(float_sinC5)); \\\n    vfmadd213ps(t3, t2, CPTR(float_sinC3)); \\\n    VEX2(mulps, t3, t3, t2); \\\n    vfmadd231ps(t1, t1, t3); \\\n  } \\\n  else { \\\n    VEX2(mulps, t3, t2, CPTR(float_sinC9)); \\\n    VEX2(addps, t3, t3, CPTR(float_sinC7)); \\\n    VEX2(mulps, t3, t3, t2); \\\n    VEX2(addps, t3, t3, CPTR(float_sinC5)); \\\n    VEX2(mulps, t3, t3, t2); \\\n    VEX2(addps, t3, t3, CPTR(float_sinC3)); \\\n    VEX2(mulps, t3, t3, t2); \\\n    VEX2(mulps, t3, t3, t1); \\\n    VEX2(addps, t1, t1, t3); \\\n  } \\\n} \\\nelse { \\\n/*  // Evaluate minimax polynomial for cos(x) in [-pi/2, pi/2] interval */ \\\n/*  // Y <- 1 + X^2 * (C2 + X^2 * (C4 + X^2 * (C6 + X^2 * C8))) */ \\\n  VEX2(mulps, t2, t1, t1); \\\n  if constexpr(false /*cpuFlags & CPUF_FMA3*/) { \\\n    vmovaps(t1, CPTR(float_cosC6)); \\\n    vfmadd231ps(t1, t2, CPTR(float_cosC8)); \\\n    vfmadd213ps(t1, t2, CPTR(float_cosC4)); \\\n    vfmadd213ps(t1, t2, CPTR(float_cosC2)); \\\n    vfmadd213ps(t1, t2, CPTR(elfloat_one)); \\\n  } \\\n  else { \\\n    VEX2(mulps, t1, t2, CPTR(float_cosC8)); \\\n    VEX2(addps, t1, t1, CPTR(float_cosC6)); \\\n    VEX2(mulps, t1, t1, t2); \\\n    VEX2(addps, t1, t1, CPTR(float_cosC4)); \\\n    VEX2(mulps, t1, t1, t2); \\\n    VEX2(addps, t1, t1, CPTR(float_cosC2)); \\\n    VEX2(mulps, t1, t1, t2); \\\n    VEX2(addps, t1, t1, CPTR(elfloat_one)); \\\n  } \\\n} \\\n/*// Apply sign */ \\\nVEX2(xorps, y, t1, sign); \\\n}\n\n// y dst x src\n#define SINCOS_PS_AVX(issin, y, x) { \\\nYmmReg t1, sign, t2, t3, t4; \\\n/* // Remove sign */ \\\nvmovaps(t1, CPTR_AVX(elabsmask)); \\\nif (issin) { \\\n  vmovaps(sign, t1); \\\n  vandnps(sign, sign, x); \\\n} \\\nelse { \\\n  vxorps(sign, sign, sign); \\\n} \\\nvandps(t1, t1, x); \\\n/*// Range reduction*/ \\\nvmovaps(t3, CPTR_AVX(float_rintf)); \\\nvmulps(t2, t1, CPTR_AVX(float_invpi)); \\\nvaddps(t2, t2, t3); \\\nvpslld(t4, t2, 31); \\\nvxorps(sign, sign, t4); \\\nvsubps(t2, t2, t3); \\\nvfnmadd231ps(t1, t2, CPTR_AVX(float_pi1)); \\\nvfnmadd231ps(t1, t2, CPTR_AVX(float_pi2)); \\\nvfnmadd231ps(t1, t2, CPTR_AVX(float_pi3)); \\\nvfnmadd231ps(t1, t2, CPTR_AVX(float_pi4)); \\\nif (issin) { \\\n  /* // Evaluate minimax polynomial for sin(x) in [-pi/2, pi/2] interval */ \\\n  /* // Y <- X + X * X^2 * (C3 + X^2 * (C5 + X^2 * (C7 + X^2 * C9))) */ \\\n  vmulps(t2, t1, t1); \\\n  vmovaps(t3,  CPTR_AVX(float_sinC7)); \\\n  vfmadd231ps(t3, t2, CPTR_AVX(float_sinC9)); \\\n  vfmadd213ps(t3, t2, CPTR_AVX(float_sinC5)); \\\n  vfmadd213ps(t3, t2, CPTR_AVX(float_sinC3)); \\\n  vmulps(t3, t3, t2); \\\n  vfmadd231ps(t1, t1, t3); \\\n} \\\nelse { \\\n/*  // Evaluate minimax polynomial for cos(x) in [-pi/2, pi/2] interval */ \\\n/*  // Y <- 1 + X^2 * (C2 + X^2 * (C4 + X^2 * (C6 + X^2 * C8))) */ \\\n  vmulps(t2, t1, t1); \\\n  vmovaps(t1, CPTR_AVX(float_cosC6)); \\\n  vfmadd231ps(t1, t2, CPTR_AVX(float_cosC8)); \\\n  vfmadd213ps(t1, t2, CPTR_AVX(float_cosC4)); \\\n  vfmadd213ps(t1, t2, CPTR_AVX(float_cosC2)); \\\n  vfmadd213ps(t1, t2, CPTR_AVX(elfloat_one)); \\\n} \\\n/*// Apply sign */ \\\nvxorps(y, t1, sign); \\\n}\n\n// return (x - std::round(x / d)*d);\n#define FMOD_PS(x, d) { \\\nXmmReg aTmp; \\\nmovaps(aTmp, x); \\\ndivps(aTmp, d); \\\ncvttps2dq(aTmp,aTmp); \\\ncvtdq2ps(aTmp,aTmp); \\\nmulps(aTmp, d); \\\nsubps(x, aTmp); }\n\n#define FMOD_PS_AVX(x, d) { \\\nYmmReg aTmp; \\\nvdivps(aTmp, x, d); \\\nvcvttps2dq(aTmp,aTmp); \\\nvcvtdq2ps(aTmp,aTmp); \\\nvmulps(aTmp, aTmp, d); \\\nvsubps(x, x, aTmp); }\n\nstruct ExprEval : public jitasm::function<void, ExprEval, uint8_t *, const intptr_t *, intptr_t, intptr_t> {\n\n  std::vector<ExprOp> ops;\n  int numInputs;\n  int cpuFlags;\n  int planeheight;\n  int planewidth;\n  bool singleMode;\n  int labelCount; // to have unique label strings\n\n  std::string getLabelCount()\n  {\n    return std::to_string(++labelCount);\n  }\n\n  ExprEval(std::vector<ExprOp> &ops, int numInputs, int cpuFlags, int planewidth, int planeheight, bool singleMode) : ops(ops), numInputs(numInputs), cpuFlags(cpuFlags),\n    planeheight(planeheight), planewidth(planewidth), singleMode(singleMode), labelCount(0) {}\n\n  AVS_FORCEINLINE void doMask(XmmReg &r, Reg &constptr, int _planewidth)\n  {\n    switch (_planewidth & 3) {\n    case 1: andps(r, CPTR(loadmask1000)); break;\n    case 2: andps(r, CPTR(loadmask1100)); break;\n    case 3: andps(r, CPTR(loadmask1110)); break;\n    }\n  }\n\n  template<bool processSingle, bool maskUnused>\n  AVS_FORCEINLINE void processingLoop(Reg &regptrs, XmmReg &zero, Reg &constptr, Reg &SpatialY)\n  {\n    std::list<std::pair<XmmReg, XmmReg>> stack;\n    std::list<XmmReg> stack1;\n\n    const int pixels_per_cycle = processSingle ? 4 : 8;\n\n    const bool maskIt = (maskUnused && ((planewidth & 3) != 0));\n\n    for (const auto &iter : ops) {\n      if (iter.op == opLoadSpatialX) {\n        if (processSingle) {\n          XmmReg r1;\n          movd(r1, dword_ptr[regptrs + sizeof(void *) * (RWPTR_START_OF_XCOUNTER)]);\n          shufps(r1, r1, 0);\n          cvtdq2ps(r1, r1);\n          addps(r1, CPTR(spatialX));\n          stack1.push_back(r1);\n        }\n        else {\n          XmmReg r1, r2;\n          movd(r1, dword_ptr[regptrs + sizeof(void *) * (RWPTR_START_OF_XCOUNTER)]);\n          shufps(r1, r1, 0);\n          cvtdq2ps(r1, r1);\n          movaps(r2, r1);\n          addps(r1, CPTR(spatialX));\n          addps(r2, CPTR(spatialX2));\n          stack.push_back(std::make_pair(r1, r2));\n        }\n      }\n      else if (iter.op == opLoadSpatialY) {\n        if (processSingle) {\n          XmmReg r1;\n          movd(r1, SpatialY);\n          shufps(r1, r1, 0);\n          cvtdq2ps(r1, r1);\n          stack1.push_back(r1);\n        }\n        else {\n          XmmReg r1, r2;\n          movd(r1, SpatialY);\n          shufps(r1, r1, 0);\n          cvtdq2ps(r1, r1);\n          movaps(r2, r1);\n          stack.push_back(std::make_pair(r1, r2));\n        }\n      }\n      else if (iter.op == opLoadInternalVar) {\n        if (processSingle) {\n          XmmReg r1;\n          movd(r1, dword_ptr[regptrs + sizeof(void *) * (iter.e.ival + RWPTR_START_OF_INTERNAL_VARIABLES)]);\n          shufps(r1, r1, 0);\n          stack1.push_back(r1);\n        }\n        else {\n          XmmReg r1, r2;\n          movd(r1, dword_ptr[regptrs + sizeof(void *) * (iter.e.ival + RWPTR_START_OF_INTERNAL_VARIABLES)]);\n          shufps(r1, r1, 0);\n          movaps(r2, r1);\n          stack.push_back(std::make_pair(r1, r2));\n        }\n      }\n      else if (iter.op == opLoadFramePropVar) {\n        if (processSingle) {\n          XmmReg r1;\n          movd(r1, dword_ptr[regptrs + sizeof(void*) * (iter.e.ival + RWPTR_START_OF_INTERNAL_FRAMEPROP_VARIABLES)]);\n          shufps(r1, r1, 0);\n          stack1.push_back(r1);\n        }\n        else {\n          XmmReg r1, r2;\n          movd(r1, dword_ptr[regptrs + sizeof(void*) * (iter.e.ival + RWPTR_START_OF_INTERNAL_FRAMEPROP_VARIABLES)]);\n          shufps(r1, r1, 0);\n          movaps(r2, r1);\n          stack.push_back(std::make_pair(r1, r2));\n        }\n      }\n      else if (iter.op == opLoadRelSrc8 || iter.op == opLoadRelSrc16 || iter.op == opLoadRelSrcF32) {\n        // either dx or dy is nonzero\n        // common part follows for single 4 pixels/cycle and dual 8 pixels/cycle\n        Reg newx;\n        if (iter.dx != 0) {\n          mov(newx, ptr[regptrs + sizeof(void *) * (RWPTR_START_OF_XCOUNTER)]); // original base\n          add(newx, iter.dx); // new base\n        }\n\n        Reg a;\n        mov(a, ptr[regptrs + sizeof(void *) * (iter.e.ival + RWPTR_START_OF_INPUTS)]); // current pixel group of current line\n                                                                                       // adjust read pointer vertically for nonzero dy, keep 0..height-1 limits\n        if (iter.dy < 0) {\n          // Read from above\n          Reg dy, sy;\n          mov(sy, SpatialY);\n          mov(dy, -iter.dy); // dy = -dy;\n          cmp(dy, sy);\n          cmovg(dy, sy); // mov if greater: if (dy > SpatialY) dy = SpatialY;\n#ifdef JITASM64\n          imul(dy, qword_ptr[regptrs + sizeof(void *) * (iter.e.ival + RWPTR_START_OF_STRIDES)]); // dy * stride\n#else\n          imul(dy, dword_ptr[regptrs + sizeof(void *) * (iter.e.ival + RWPTR_START_OF_STRIDES)]); // dy * stride\n#endif\n          sub(a, dy); // a -= dy * stride\n        }\n        else if (iter.dy > 0) {\n          // Read from bottom\n          Reg dy, sy;\n          mov(sy, planeheight - 1);\n          sub(sy, SpatialY);\n          mov(dy, iter.dy);\n          cmp(dy, sy);\n          cmovg(dy, sy); // mov if greater: if (dy > (planeheight - 1) - SpatialY) dy = SpatialY;\n#ifdef JITASM64\n          imul(dy, qword_ptr[regptrs + sizeof(void *) * (iter.e.ival + RWPTR_START_OF_STRIDES)]); // dy * stride\n#else\n          imul(dy, dword_ptr[regptrs + sizeof(void *) * (iter.e.ival + RWPTR_START_OF_STRIDES)]); // dy * stride\n#endif\n          add(a, dy); // a += dy * stride\n        }\n\n        // dy shift is done already. newx holds xcounter + dx\n        // Cases:\n        // ReadBefore: xcounter + dx < 0 (only when dx < 0):\n        //   FullReadBefore: dx <= pixels_per_cycle: clone leftmost pixel to each pixel posision in the group\n        //   PartialReadBefore: pixels_per_cycle < dx < 0: close leftmost pixel to -dx positions\n        // NormalRead: 0 <= xcounter + dx < planewidth - (pixels_per_cycle - 1) (can read whole pixel group)\n        // OverRead:\n        //   PartialOverRead when pixel at (planewidth-1) is current read position\n        //   PartialOverRead when pixel at (planewidth-1) is after current read position\n        //   FullOverRead: clone pixel at (planewidth-1) to each pixel posision in the group\n        if (processSingle) {\n          // LoadRel8/16/32, single register mode 1x4 pixels\n\n          // Use getLabelCount: names should be unique across multiple calls to processingLoop\n          std::string LabelNeg = \"neg\" + getLabelCount();\n          std::string LabelOver = \"over\" + getLabelCount();\n          std::string LabelEnd = \"end\" + getLabelCount();\n\n          XmmReg r1;\n\n          if (iter.dx < 0) { // Optim: read from left is possible only for dx<0 case\n            cmp(newx, 0);\n            jl(LabelNeg); // newx < 0, read (partially or fully) from before the leftmost pixel\n          }\n          if (iter.dx != 0) { // Optim: read after rightmost pixel is possible only for dx>0 case\n                              // Also check for dx<0, because of possible memory overread\n                              // e.g.: planewidth = 64, dx = -1, 16 bit pixels, 16 bytes/cycle, reading from offsets -1(0), 15, 31, 47, then 63\n                              // When we read 16 bytes from offset 63, we are overaddressing the 64 byte scanline,\n                              // which may give access violation when pointer is in the most bottom line.\n            cmp(newx, planewidth - (pixels_per_cycle - 1)); // read (partially of fully) after the rightmost pixel\n            jge(LabelOver);\n          }\n\n          // It's safe to read the whole pixel group\n          int offset;\n          if (iter.op == opLoadRelSrc8)\n            offset = iter.dx;\n          else if (iter.op == opLoadRelSrc16)\n            offset = iter.dx * sizeof(uint16_t);\n          else if (iter.op == opLoadRelSrcF32)\n            offset = iter.dx * sizeof(float);\n\n          if (iter.op == opLoadRelSrc8) {\n            movd(r1, dword_ptr[a + offset]); // 4 pixels, 4 bytes\n            punpcklbw(r1, zero);\n            punpcklwd(r1, zero);\n            cvtdq2ps(r1, r1);\n          }\n          else if (iter.op == opLoadRelSrc16) {\n            movq(r1, mmword_ptr[a + offset]); // 4 pixels, 8 bytes\n            punpcklwd(r1, zero);\n            cvtdq2ps(r1, r1);\n          }\n          else if (iter.op == opLoadRelSrcF32) {\n            if (iter.dx % 4 == 0)\n              movdqa(r1, xmmword_ptr[a + offset]); // 4 pixels, 16 bytes aligned\n            else\n              movdqu(r1, xmmword_ptr[a + offset]); // 4 pixels, 16 bytes unaligned\n          }\n          if (iter.dx != 0) {\n            jmp(LabelEnd); // generate jump only when over/negative branches exist\n          }\n\n          if (iter.dx != 0) {\n            L(LabelOver);\n            std::string PartialOverread = \"PartialOverread\" + getLabelCount();\n            std::string NoFullOverReadFromNewX = \"NoFullOverReadFromNewX\" + getLabelCount();\n            std::string labelDoOver = \"DoOver\" + getLabelCount();\n\n            if (iter.dx > 0) { // FullOverRead possible only when dx>0\n              cmp(newx, planewidth);\n              jl(PartialOverread); // if newx < planewidth ->\n\n                                   // case: FullOver\n                                   // even the first pixel to read is beyond the end of line\n                                   // We have to clone the rightmost pixel from (planewidth-1)\n              if (iter.op == opLoadRelSrc8) {\n                sub(a, ptr[regptrs + sizeof(void *) * (RWPTR_START_OF_XCOUNTER)]);\n                add(a, planewidth - 1);\n                // reuse newx\n                movzx(newx, byte_ptr[a]);\n                movd(r1, newx);\n                punpcklbw(r1, zero); // words\n                pshufb(r1, CPTR(elShuffleForRight6)); // duplicate last word to all\n\n                punpcklwd(r1, zero);\n                cvtdq2ps(r1, r1);\n              }\n              else if (iter.op == opLoadRelSrc16) {\n                Reg tmp;\n                mov(tmp, ptr[regptrs + sizeof(void *) * (RWPTR_START_OF_XCOUNTER)]);\n                shl(tmp, 1); // for 16 bit 2*xcounter\n                sub(a, tmp);\n                add(a, (planewidth - 1) * 2);\n                // reuse newx\n                movzx(newx, word_ptr[a]);\n                movd(r1, newx);\n                pshufb(r1, CPTR(elShuffleForRight6)); // duplicate last word to all\n\n                punpcklwd(r1, zero);\n                cvtdq2ps(r1, r1);\n              }\n              else if (iter.op == opLoadRelSrcF32) {\n                Reg tmp;\n                mov(tmp, ptr[regptrs + sizeof(void *) * (RWPTR_START_OF_XCOUNTER)]);\n                shl(tmp, 2); // for 32 bit 4*xcounter\n                sub(a, tmp);\n                add(a, (planewidth - 1) * 4);\n                movd(r1, dword_ptr[a]);\n                pshufd(r1, r1, (0 << 0) | (0 << 2) | (0 << 4) | (0 << 6));\n              }\n              jmp(LabelEnd);\n            } // full OverRead path, needed when iter.dx>0\n\n              // case: Partial overread\n              // read the block, then clone the last valid pixel from position (planewidth-1)\n              // problem: newx is not aligned\n            L(PartialOverread);\n\n            // planewidth == 14  dx=7   newx = 0+7=7, newx>=planewidth-7, then not newx>=planewidth => newx = 13 => planewidth-newx = 1\n            // sample 1: newx is in different segment than planewidth-1\n            // [xcounter]\n            // [a]           [newx]    [pw-1]\n            // V             V           V\n            // 0 1 2 3 4 5 6 7 8 9 A B C D e f g h i j k l\n            //               P Q R S T U V w              need this\n            //               0 1 2 3 4 5 6 7              we can read this\n            //               P Q R S T U V w              last pixel is beyond\n            //               P Q R S T U V V              need this\n            // sample 2: newx is in the same segment than planewidth-1\n            // planewidth == 13  dx=3\n            //           [xcounter] [newx]\n            //                [a][newx][pw-1]\n            //                 V     V V\n            // 0 1 2 3 4 5 6 7 8 9 A B C d e f g h i j\n            //                       P Q x x x x x x        need this\n            //                       P Q Q Q Q Q Q Q        duplicated the last valid pixel\n            //                 0 1 2 3 4 5 6 7              we can read this\n            // when newx and (planewidth-1) are in different segments then we read from newx\n            Reg tmp;\n            mov(tmp, newx);\n            and_(tmp, ~(pixels_per_cycle - 1));\n            cmp(tmp, (planewidth & ~(pixels_per_cycle - 1)));\n            jle(NoFullOverReadFromNewX); // jump if (newx and ~0x07) < (planewidth & ~0x07) (in another segment)\n\n                                         // read from current (last) pointer,\n            if (iter.op == opLoadRelSrc8 || iter.op == opLoadRelSrc16) {\n              if (iter.op == opLoadRelSrc8) {\n                movd(r1, dword_ptr[a]); // 4 pixels, 4 bytes\n                punpcklbw(r1, zero); // words\n              }\n              else { // opLoadRel16\n                movq(r1, mmword_ptr[a]); // 8 pixels, 16 bytes, here still aligned\n              }\n              /*\n              psrldq(r1, ((planewidth - 1) & (pixels_per_cycle - 1)) * sizeof(uint16_t)); // Shift right by (planewidth - 1) & 7 to lose low words\n              sub(newx, planewidth - (pixels_per_cycle - 1)); // find out shuffle pointer -1, ... -7 -> 6 ... 0\n              shl(newx, 4); // *16 for shuffle table\n              // LabelDoOver copied here\n              // reuse a : Reg shuffleTable;\n              lea(a, CPTR(elShuffleForRight0)); // ptr for word shuffle\n              pshufb(r1, xmmword_ptr[a + newx]);\n              */\n              punpcklwd(r1, zero);\n              cvtdq2ps(r1, r1);\n              //jmp(LabelEnd);\n              //jmp(labelDoOver);\n            }\n            else if (iter.op == opLoadRelSrcF32) {\n              // omg it's complicated\n              movdqa(r1, xmmword_ptr[a]); // 4 pixels, 16 bytes, here still aligned\n            }\n            int bytes_to_shift = ((planewidth - 1) & (pixels_per_cycle - 1)) * sizeof(float);\n            if (bytes_to_shift > 0) {\n              psrldq(r1, bytes_to_shift);\n              switch (bytes_to_shift) { // 4, 8, 12\n              case 4:\n                pshufd(r1, r1, (0 << 0) | (1 << 2) | (2 << 4) | (2 << 6));\n                break;\n              case 8:\n                pshufd(r1, r1, (0 << 0) | (1 << 2) | (1 << 4) | (1 << 6));\n                break;\n              case 12:\n                pshufd(r1, r1, (0 << 0) | (0 << 2) | (0 << 4) | (0 << 6));\n                break;\n              }\n            }\n            jmp(LabelEnd);\n            //}\n\n            L(NoFullOverReadFromNewX);\n            // read from newx\n            if (iter.op == opLoadRelSrc8) {\n              sub(a, ptr[regptrs + sizeof(void *) * (RWPTR_START_OF_XCOUNTER)]); // back x counter bytes to the beginning\n              add(a, newx);     // new position\n              movd(r1, dword_ptr[a]); // 4 pixels, 4 bytes\n              punpcklbw(r1, zero); // words\n                                   /*\n                                   // no shift here, just duplicate appropriate pixel into the high ones\n                                   mov(newx, (6 - ((planewidth - iter.dx - 1) & (pixels_per_cycle - 1))) << 4); // find out shuffle pointer\n                                   // shuffle by the pattern, table offset in newx, and finalizes\n                                   // here r1 contains words\n                                   // todo direct load\n                                   Reg shuffleTable;\n                                   lea(shuffleTable, CPTR(elShuffleForRight4)); // for dual: elShuffleForRight0\n                                   add(shuffleTable, newx);\n                                   pshufb(r1, xmmword_ptr[shuffleTable]);\n                                   */\n              punpcklwd(r1, zero);\n              cvtdq2ps(r1, r1);\n            }\n            else if (iter.op == opLoadRelSrc16) {\n              //a = a - 2 * xcounter + 2 * newx;\n              sub(newx, ptr[regptrs + sizeof(void *) * (RWPTR_START_OF_XCOUNTER)]);\n              shl(newx, 1);\n              add(a, newx);\n              movq(r1, mmword_ptr[a]); // 4 pixels, 8 bytes\n                                       // no shift here, just duplicate appropriate pixel into the high ones\n                                       /*\n                                       // reuse newx\n                                       mov(newx, (6 - ((planewidth - iter.dx - 1) & (pixels_per_cycle - 1))) << 4); // find out shuffle pointer\n                                       // ((planewidth - iter.dx - 1) & (pixels_per_cycle - 1))    keep\n                                       //                         0                                ShuffleForRight6     keep word #0, spread it to 1..7\n                                       //                         1                                ShuffleForRight5     keep word #0..1, spread it to 2..7\n                                       //\n                                       //                         6                                ShuffleForRight0     keep word #0..6, spread it to 7..7\n                                       // continues on labelDoOver\n                                       // todo direct load\n                                       Reg shuffleTable;\n                                       lea(shuffleTable, CPTR(elShuffleForRight4)); // for dual: elShuffleForRight0\n                                       add(shuffleTable, newx);\n                                       pshufb(r1, xmmword_ptr[shuffleTable]);\n                                       */\n              punpcklwd(r1, zero);\n              cvtdq2ps(r1, r1);\n            }\n            else if (iter.op == opLoadRelSrcF32) {\n              //a = a - 4 * xcounter + 4 * newx;\n              sub(newx, ptr[regptrs + sizeof(void *) * (RWPTR_START_OF_XCOUNTER)]);\n              shl(newx, 2);\n              add(a, newx);\n\n\n              // no real shift here, just duplicate appropriate pixel into the high ones. But we have two registers\n              movdqu(r1, xmmword_ptr[a]); // 4 pixels, 16 bytes, no need for upper 4 pixels\n            }\n            // we have 4 floats here in r1, common part\n            int what = ((planewidth - iter.dx - 1) & (pixels_per_cycle - 1));\n            //                        what\n            //                         0     ShuffleForRight2_32  keep r1 dword #0   , spread it to 1..3, then spread r1.3 to r2 (ShuffleForRight2_32(r2,r1)\n            //                         1     ShuffleForRight1_32  keep r1 dword #0..1, spread it to 2..3, then spread r1.3 to r2\n            //                         2     ShuffleForRight0_32  keep r1 dword #0..2, spread it to 3   , then spread r1.3 to r2\n            //                         3                          keep r1 dword #0..3,                   , then spread r1.3 to r2\n            //                         4                          keep r1 dword #0..3,                   , keep r2 dword #0   , spread it to 1..3\n            //                         5                          keep r1 dword #0..3,                   , keep r2 dword #0..1, spread it to 2..3\n            //                         6                          keep r1 dword #0..3,                   , keep r2 dword #0..2, spread it to    3\n\n            switch (what) {\n            case 0:\n              pshufd(r1, r1, (0 << 0) | (0 << 2) | (0 << 4) | (0 << 6)); // fill 3 upper dwords of r1 from r1.0\n              break;\n            case 1:\n              pshufd(r1, r1, (0 << 0) | (1 << 2) | (1 << 4) | (1 << 6)); // fill 2 upper dwords of r1 from r1.1\n              break;\n            case 2:\n              pshufd(r1, r1, (0 << 0) | (1 << 2) | (2 << 4) | (2 << 6)); // fill 1 upper dwords of r1 from r1.2\n              break;\n            }\n            // continues on labelEnd\n            //}\n            if (iter.dx < 0)\n              jmp(LabelEnd);\n          } // over: iter.dx != 0\n          if (iter.dx < 0) {\n            L(LabelNeg);\n            // read from negative area on the left side, read exactly from 0th, then shift\n            // When reading from negative x coordinates we read exactly from 0th, then shift and duplicate\n            // For extreme minus offsets we duplicate 0th (leftmost) pixel to each position\n            // example: dx = -1\n            // -1 0  1  2  3  4  5  6  7\n            // A  A  B  C  D  E  F  G         we need this\n            //    A  B  C  D  E  F  G  H      read [0]\n            //    0  A  B  C  D  E  F  G  H   shift\n            //    A  A  B  C  D  E  F  G  H   duplicate by shuffle\n            if (iter.op == opLoadRelSrc8 || iter.op == opLoadRelSrc16) {\n              if (iter.op == opLoadRelSrc8) {\n                sub(a, ptr[regptrs + sizeof(void *) * (RWPTR_START_OF_XCOUNTER)]); // go back to the beginning\n                movd(r1, dword_ptr[a]); // 8 pixels, 8 bytes\n                punpcklbw(r1, zero); // bytes to words\n              }\n              else if (iter.op == opLoadRelSrc16) {\n                // go back to the beginning, in 16 bit, *2\n                Reg tmp;\n                mov(tmp, ptr[regptrs + sizeof(void *) * (RWPTR_START_OF_XCOUNTER)]);\n                shl(tmp, 1); // for 16 bit 2*xcounter\n                sub(a, tmp);\n                movq(r1, mmword_ptr[a]); // 8 pixels, 16 bytes\n              }\n              punpcklwd(r1, zero);\n              cvtdq2ps(r1, r1);\n            }\n            else if (iter.op == opLoadRelSrcF32) {\n              Reg tmp;\n              mov(tmp, ptr[regptrs + sizeof(void *) * (RWPTR_START_OF_XCOUNTER)]);\n              shl(tmp, 2); // *4\n              sub(a, tmp);\n              movdqa(r1, xmmword_ptr[a]); // 4 pixels, 16 bytes aligned\n            }\n            std::string PartialReadBefore = \"PartialReadBefore\" + getLabelCount();\n\n            cmp(newx, -pixels_per_cycle);\n            jg(PartialReadBefore);\n            // FullReadBefore: newx <= -pixels_per_cycle, clone 0th (leftmost) pixel to all\n            pshufd(r1, r1, (0 << 0) | (0 << 2) | (0 << 4) | (0 << 6));\n            jmp(LabelEnd);\n\n            L(PartialReadBefore);\n            // -pixels_per_cycle < newx < 0\n            int bytes_to_shift = sizeof(float) * min(pixels_per_cycle - 1, (-iter.dx) & (pixels_per_cycle - 1));\n            //    shift bytes\n            //         4                  r1 << 4     shuffle r1.1 to r1.0-0\n            //         8                  r1 << 8     shuffle r1.2 to r1.0-1\n            //         12                 r1 << 12    shuffle r1.3 to r1.0-2\n            pslldq(r1, bytes_to_shift); // todo: shift + shuffle = single shuffle\n\n            switch (bytes_to_shift) { // 4, 8, 12\n            case 4:\n              pshufd(r1, r1, (1 << 0) | (1 << 2) | (2 << 4) | (3 << 6)); // elShuffleForLeft0_32 // shuffle r1.1 to r1.0-0\n              break;\n            case 8:\n              pshufd(r1, r1, (2 << 0) | (2 << 2) | (2 << 4) | (3 << 6)); // elShuffleForLeft1_32 // shuffle r1.2 to r1.0-1\n              break;\n            case 12:\n              pshufd(r1, r1, (3 << 0) | (3 << 2) | (3 << 4) | (3 << 6)); // elShuffleForLeft2_32 // shuffle r1.3 to r1.0-2\n              break;\n            }\n          } // negative\n          L(LabelEnd);\n          stack1.push_back(r1);\n        } // end of single Relative Mode\n        else {\n          // LoadRel8/16/32, dual register mode 2x4 pixels\n\n          // Use getLabelCount: names should be unique across multiple calls to processingLoop\n          std::string LabelNeg = \"neg\" + getLabelCount();\n          std::string LabelOver = \"over\" + getLabelCount();\n          std::string LabelEnd = \"end\" + getLabelCount();\n\n          XmmReg r1, r2;\n\n          // damn, when the order of the two comparisons is exchanged, bad code is generated for dx=-1 (expr=x[-1]).\n          // jitasm cannot guess the proper register for 'a', it uses register 'xcounter' instead\n          // maybe the jump order has to match the label order?\n          // good: LabelOver, LabelNeg. Bad: LabelNeg, LabelOver\n          // But it's not true. Now x[-2] fails for 32 bit clip\n          if (iter.dx < 0) { // Optim: read from left is possible only for dx<0 case\n            cmp(newx, 0);\n            jl(LabelNeg); // newx < 0, read (partially or fully) from before the leftmost pixel\n          }\n          if (iter.dx != 0) {\n            // Also check for dx<0, because of possible memory overread\n            // e.g.: planewidth = 64, dx = -1, 16 bit pixels, 16 bytes/cycle, reading from offsets -1(0), 15, 31, 47, then 63\n            // When we read 16 bytes from offset 63, we are overaddressing the 64 byte scanline,\n            // which may give access violation when pointer is in the most bottom line.\n            cmp(newx, planewidth - (pixels_per_cycle - 1)); // read (partially of fully) after the rightmost pixel\n            jge(LabelOver);\n          }\n          /*\n          if (iter.dx < 0) { // Optim: read from left is possible only for dx<0 case\n          cmp(newx, 0);\n          jl(LabelNeg); // newx < 0, read (partially or fully) from before the leftmost pixel\n          }\n          */\n\n          // It's safe to read the whole pixel group\n          int offset;\n          if (iter.op == opLoadRelSrc8)\n            offset = iter.dx;\n          else if (iter.op == opLoadRelSrc16)\n            offset = iter.dx * sizeof(uint16_t);\n          else if (iter.op == opLoadRelSrcF32)\n            offset = iter.dx * sizeof(float);\n\n          if (iter.op == opLoadRelSrc8) {\n            movq(r1, mmword_ptr[a + offset]); // 8 pixels, 8 bytes\n            punpcklbw(r1, zero);\n            movdqa(r2, r1);\n            punpcklwd(r1, zero);\n            punpckhwd(r2, zero);\n            cvtdq2ps(r1, r1);\n            cvtdq2ps(r2, r2);\n          }\n          else if (iter.op == opLoadRelSrc16) {\n            if (iter.dx % 8 == 0)\n              movdqa(r1, xmmword_ptr[a + offset]); // 8 pixels 16 byte boundary, aligned\n            else\n              movdqu(r1, xmmword_ptr[a + offset]);\n            movdqa(r2, r1);\n            punpcklwd(r1, zero);\n            punpckhwd(r2, zero);\n            cvtdq2ps(r1, r1);\n            cvtdq2ps(r2, r2);\n          }\n          else if (iter.op == opLoadRelSrcF32) {\n            if (iter.dx % 4 == 0) {\n              movdqa(r1, xmmword_ptr[a + offset]); // // 4 pixels 16 byte boundary, aligned\n              movdqa(r2, xmmword_ptr[a + offset + 16]);\n            }\n            else {\n              movdqu(r1, xmmword_ptr[a + offset]); // unaligned\n              movdqu(r2, xmmword_ptr[a + offset + 16]);\n            }\n          }\n          if (iter.dx != 0) {\n            jmp(LabelEnd); // Optim: generate jump only when over/negative branches exist\n          }\n\n          if (iter.dx != 0) {\n            L(LabelOver);\n\n            // x  dx   newx\n            // 8   1  8+1=9\n            // planewidth == 16\n            // 0 1 2 3 4 5 6 7 8 9 A B C D E F g h i j\n            //                   P Q R S T U V x            need this\n            //                   P Q R S T U V V            duplicated the last valid pixel\n            //                 0 1 2 3 4 5 6 7              we can read this\n            //                 1 2 3 4 5 6 7 -              Shift right by dx to lose low bytes\n            //                 1 2 3 4 5 6 7 7              have to make this one from it. Only the first planewidth-newx (7) bytes valid\n            // x  dx   newx\n            // 8   3  8+3=11\n            // planewidth == 15\n            // 0 1 2 3 4 5 6 7 8 9 A B C D E f g h i j\n            //                       P Q R S T x x x        need this\n            //                       P Q R S S S S S        duplicated the last valid pixel\n            //                 0 1 2 3 4 5 6 7              we can read this\n            //                 3 4 5 6 7 - - -              Shift right by dx to lose low bytes\n            //                 3 4 5 6 6 6 6 6              have to make this one from it. Only the first planewidth-newx (4) bytes valid\n            // planewidth == 14\n            // 0 1 2 3 4 5 6 7 8 9 A B C D e f g h i j\n            //                       P Q R x x x x x        need this\n            //                       P Q R R R R R R        duplicated the last valid pixel\n            //                 0 1 2 3 4 5 6 7              we can read this\n            //                 3 4 5 6 7 - - -              Shift right by dx to lose low bytes\n            //                 3 4 5 5 5 5 5 5              have to make this one from it. Only the first planewidth-newx (3) bytes valid\n            // special case: full read from beyond line\n            // planewidth == 14  dx=6   newx = 8+6=14, newx>=planewidth => newx = 13 => planewidth-newx = 1\n            // 0 1 2 3 4 5 6 7 8 9 A B C D e f g h i j k l\n            //                             ? ? ? ? ? ? ? ?  need this, but overread\n            //                             ? ? ? ? ? ? ? ?  duplicated the last valid pixel\n            //                 0 1 2 3 4 5 6 7              we can read this\n            //                 5 6 7 - - - - -              Shift right by not dx but (planewidth-1)&7, it's 5 in this example, to lose low bytes\n            //                 5 5 5 5 5 5 5 5              case(1): duplicate very first\n            // planewidth == 14  dx=7   newx = 0+7=7, newx>=planewidth-7, then not newx>=planewidth => newx = 13 => planewidth-newx = 1\n            // 0 1 2 3 4 5 6 7 8 9 A B C D e f g h i j k l\n            //               P Q R S T U V w                need this\n            //               P Q R S T U V V                duplicated the last valid pixel\n            //                 0 1 2 3 4 5 6 7              we can read this\n            //                 5 6 7 - - - - -              Shift right by not dx but (planewidth-1)&7, it's 5 in this example, to lose low bytes\n            //                 5 5 5 5 5 5 5 5              case(1): duplicate very first\n            // planewidth == 14  dx=7   newx = 8+7=15, newx>=planewidth => newx = 13 => planewidth-newx = 1\n            //                             ? ? ? ? ? ? ? ?  need this, but overread\n            //                 0 1 2 3 4 5 6 7              we can read this\n            //                 5 - - - - - - -              Shift right to have the last pixel\n            //                 5 5 5 5 5 5 5 5              case(1): duplicate very first\n            // planewidth == 13\n            // 0 1 2 3 4 5 6 7 8 9 A B C d e f g h i j\n            //                       P Q x x x x x x        need this\n            //                       P Q Q Q Q Q Q Q        duplicated the last valid pixel\n            //                 0 1 2 3 4 5 6 7              we can read this\n            //                 3 4 5 6 7 - - -              Shift right by dx to lose low bytes\n            //                 3 4 4 4 4 4 4 4              have to make this one from it. Only the first planewidth-newx (2) bytes valid\n            // planewidth == 12\n            // 0 1 2 3 4 5 6 7 8 9 A B c d e f g h i j\n            //                       P x x x x x x x        need this\n            //                       P P P P P P P P        duplicated the last valid pixel\n            //                 0 1 2 3 4 5 6 7              we can read this\n            //                 3 4 5 6 7 - - -              Shift right by dx to lose low bytes\n            //                 3 3 3 3 3 3 3 3              have to make this one from it. Only the first planewidth-newx (1) bytes valid\n\n            // duplicate highest, make a shuffle table by planewidth-newx (1..7)\n            // planewidth - newx    newx-pw  newx-pw+7    shuffle\n            //                               newx-(pw-7)\n            //           1            -1         6        0->0 0->1 0->2 0->3 0->4 0->5 0->6 0->7 elSuffleForRight6 (lowest to everywhere)\n            //           2            -2         5        0->0 1->1 1->2 1->3 1->4 1->5 1->6 1->7 elSuffleForRight5 (lowest two remains then second duplicates)\n            //           3            -3         4        0->0 1->1 2->2 2->3 2->4 2->5 2->6 2->7 elSuffleForRight4 (lowest three remains then third duplicates)\n            //           4            -4         3        0->0 1->1 2->2 3->3 3->4 3->5 3->6 3->7 elSuffleForRight3\n            //           5            -5         2        0->0 1->1 2->2 3->3 4->4 4->5 4->6 4->7 elSuffleForRight2\n            //           6            -6         1        0->0 1->1 2->2 3->3 4->4 5->5 5->6 5->7 elSuffleForRight1\n            //           7            -7         0        0->0 1->1 2->2 3->3 4->4 5->5 6->6 6->7 elSuffleForRight0 (lowest seven remains then seventh duplicates)\n            // in extreme case (read all beyond last pixel): newx >= planewidth: ==> case of elSuffleForRight6\n\n            // shuffleTable = elShuffleForRight0 + 16*(newx-(planewidth-7))\n            std::string PartialOverread = \"PartialOverread\" + getLabelCount();\n            std::string NoFullOverReadFromNewX = \"NoFullOverReadFromNewX\" + getLabelCount();\n            std::string labelDoOver = \"DoOver\" + getLabelCount();\n\n            if (iter.dx > 0) { // FullOverRead possible only when dx>0\n              cmp(newx, planewidth);\n              jl(PartialOverread); // if newx < planewidth ->\n\n                                   // case: FullOver\n                                   // even the first pixel to read is beyond the end of line\n                                   // We have to clone the rightmost pixel from (planewidth-1)\n              if (iter.op == opLoadRelSrc8) {\n                sub(a, ptr[regptrs + sizeof(void *) * (RWPTR_START_OF_XCOUNTER)]);\n                add(a, planewidth - 1);\n                // reuse newx\n                movzx(newx, byte_ptr[a]);\n                movd(r1, newx);\n                punpcklbw(r1, zero); // words\n                pshufb(r1, CPTR(elShuffleForRight6)); // duplicate last word to all\n\n                movdqa(r2, r1);\n                punpcklwd(r1, zero);\n                punpckhwd(r2, zero);\n                cvtdq2ps(r1, r1);\n                cvtdq2ps(r2, r2);\n              }\n              else if (iter.op == opLoadRelSrc16) {\n                Reg tmp;\n                mov(tmp, ptr[regptrs + sizeof(void *) * (RWPTR_START_OF_XCOUNTER)]);\n                shl(tmp, 1); // for 16 bit 2*xcounter\n                sub(a, tmp);\n                add(a, (planewidth - 1) * 2);\n                // reuse newx\n                movzx(newx, word_ptr[a]);\n                movd(r1, newx);\n                pshufb(r1, CPTR(elShuffleForRight6)); // duplicate last word to all\n\n                movdqa(r2, r1);\n                punpcklwd(r1, zero);\n                punpckhwd(r2, zero);\n                cvtdq2ps(r1, r1);\n                cvtdq2ps(r2, r2);\n              }\n              else if (iter.op == opLoadRelSrcF32) {\n                Reg tmp;\n                mov(tmp, ptr[regptrs + sizeof(void *) * (RWPTR_START_OF_XCOUNTER)]);\n                shl(tmp, 2); // for 32 bit 4*xcounter\n                sub(a, tmp);\n                add(a, (planewidth - 1) * 4);\n                movd(r1, dword_ptr[a]);\n                pshufd(r1, r1, (0 << 0) | (0 << 2) | (0 << 4) | (0 << 6));\n                movdqa(r2, r1);\n              }\n              jmp(LabelEnd);\n            } // full OverRead path, needed when iter.dx>0\n\n              // case: Partial overread\n              // read the block, then clone the last valid pixel from position (planewidth-1)\n              // problem: newx is not aligned\n            L(PartialOverread);\n            // planewidth == 14  dx=7   newx = 0+7=7, newx>=planewidth-7, then not newx>=planewidth => newx = 13 => planewidth-newx = 1\n            // sample 1: newx is in different segment than planewidth-1\n            // [xcounter]\n            // [a]           [newx]    [pw-1]\n            // V             V           V\n            // 0 1 2 3 4 5 6 7 8 9 A B C D e f g h i j k l\n            //               P Q R S T U V w              need this\n            //               0 1 2 3 4 5 6 7              we can read this\n            //               P Q R S T U V w              last pixel is beyond\n            //               P Q R S T U V V              need this\n            // sample 2: newx is in the same segment than planewidth-1\n            // planewidth == 13  dx=3\n            //           [xcounter] [newx]\n            //                [a][newx][pw-1]\n            //                 V     V V\n            // 0 1 2 3 4 5 6 7 8 9 A B C d e f g h i j\n            //                       P Q x x x x x x        need this\n            //                       P Q Q Q Q Q Q Q        duplicated the last valid pixel\n            //                 0 1 2 3 4 5 6 7              we can read this\n            // when newx and (planewidth-1) are in different segments then we read from newx\n            Reg tmp;\n            mov(tmp, newx);\n            and_(tmp, ~(pixels_per_cycle - 1));\n            cmp(tmp, (planewidth & ~(pixels_per_cycle - 1)));\n            jle(NoFullOverReadFromNewX); // jump if (newx and ~0x07) < (planewidth & ~0x07) (in another segment)\n\n                                         // read from current (last) pointer,\n            if (iter.op == opLoadRelSrc8 || iter.op == opLoadRelSrc16) {\n              if (iter.op == opLoadRelSrc8) {\n                movq(r1, mmword_ptr[a]); // 8 pixels, 8 bytes\n                punpcklbw(r1, zero); // words\n              }\n              else { // opLoadRel16\n                movdqa(r1, xmmword_ptr[a]); // 8 pixels, 16 bytes, here still aligned\n              }\n              psrldq(r1, ((planewidth - 1) & (pixels_per_cycle - 1)) * sizeof(uint16_t)); // Shift right by (planewidth - 1) & 7 to lose low words\n              sub(newx, planewidth - (pixels_per_cycle - 1)); // find out shuffle pointer -1, ... -7 -> 6 ... 0\n              shl(newx, 4); // *16 for shuffle table\n                            // LabelDoOver copied here\n                            // reuse a : Reg shuffleTable;\n              lea(a/*shuffleTable*/, CPTR(elShuffleForRight0)); // ptr for word shuffle\n                                                                //add(a/*shuffleTable*/, newx);\n              pshufb(r1, xmmword_ptr[a/*shuffleTable*/ + newx]);\n\n              movdqa(r2, r1);\n              punpcklwd(r1, zero);\n              punpckhwd(r2, zero);\n              cvtdq2ps(r1, r1);\n              cvtdq2ps(r2, r2);\n              jmp(LabelEnd);\n            }\n            else if (iter.op == opLoadRelSrcF32) {\n              // omg it's complicated\n\n              // palignr memo\n              // temp1[255:0]  ((DEST[127:0] << 128) OR SRC[127:0]) >> (imm8*8);\n              // DEST[127:0]  temp1[127:0]\n\n              int bytes_to_shift = ((planewidth - 1) & (pixels_per_cycle - 1)) * sizeof(float);\n              if (bytes_to_shift < 16) {\n                // src              dst\n                // r2               r1\n                // 15 14 13.... 0   15 14 13 ... 0\n                //    15 14 13  1   0  15 14.... 1  palignr(dst, src, 1)\n                //              15  14 13  ..... 15 palignr(dst, src, 15)\n                movdqa(r1, xmmword_ptr[a]); // 4 pixels, 16 bytes, here still aligned\n                movdqa(r2, xmmword_ptr[a + 16]); // 4 pixels, 16 bytes\n                if (bytes_to_shift > 0) {\n                  palignr(r1, r2, bytes_to_shift); // shift right dualreg. r1 is ready.\n                  psrldq(r2, bytes_to_shift); // Shift right upper part\n                  switch (bytes_to_shift) { // 4, 8, 12\n                  case 4:\n                    pshufd(r2, r2, (0 << 0) | (1 << 2) | (2 << 4) | (2 << 6)); // elShuffleForRight0_32\n                    break;\n                  case 8:\n                    pshufd(r2, r2, (0 << 0) | (1 << 2) | (1 << 4) | (1 << 6));\n                    break;\n                  case 12:\n                    pshufd(r2, r2, (0 << 0) | (0 << 2) | (0 << 4) | (0 << 6)); // elShuffleForRight2_32\n                    break;\n                  }\n                }\n              }\n              else if (bytes_to_shift == 16) {\n                // src              dst\n                // r2               r1\n                // 15 14 13.... 0   15 14 13 ... 0  --> 16 bytes: r1 = r2\n                movdqa(r1, xmmword_ptr[a + 16]); // 4 pixels, 16 bytes, no need [a + 0], here still aligned\n                pshufd(r2, r1, (3 << 0) | (3 << 2) | (3 << 4) | (3 << 6)); // fill r2 with highest dword of r1\n              }\n              else {\n                // bytes to shift > 16 (20, 24, 28), ignore lower 4 pixels, move and shift and spread from upper 4 pixels\n                movdqa(r1, xmmword_ptr[a + 16]); // 4 pixels, 16 bytes, no need [a + 0], here still aligned\n                psrldq(r1, bytes_to_shift - 16); // Shift right upper part\n                switch (bytes_to_shift) { // 0, 4, 8, 12\n                case 20:\n                  pshufd(r1, r1, (0 << 0) | (1 << 2) | (2 << 4) | (2 << 6)); // elShuffleForRight0_32\n                  break;\n                case 24:\n                  pshufd(r1, r1, (0 << 0) | (1 << 2) | (1 << 4) | (1 << 6));\n                  break;\n                case 28:\n                  pshufd(r1, r1, (0 << 0) | (0 << 2) | (0 << 4) | (0 << 6)); // elShuffleForRight2_32\n                  break;\n                }\n                pshufd(r2, r1, (3 << 0) | (3 << 2) | (3 << 4) | (3 << 6)); // fill r2 with highest dword of r1\n              }\n              jmp(LabelEnd);\n            }\n\n            L(NoFullOverReadFromNewX);\n            // read from newx\n            //a = a - 1,2,4 * xcounter + 1,2,4 * newx;\n            sub(newx, ptr[regptrs + sizeof(void *) * (RWPTR_START_OF_XCOUNTER)]);\n            if (iter.op == opLoadRelSrc8 || iter.op == opLoadRelSrc16) {\n              if (iter.op == opLoadRelSrc8)\n              {\n                add(a, newx);     // new position\n                movq(r1, mmword_ptr[a]); // 8 pixels, 8 bytes\n                punpcklbw(r1, zero); // words\n              }\n              else {\n                shl(newx, 1); //a = a - 2 * xcounter + 2 * newx;\n                add(a, newx);\n                movdqu(r1, xmmword_ptr[a]); // 8 pixels, 16 bytes\n              }\n              // no shift here, just duplicate appropriate pixel into the high ones\n              int what = ((planewidth - iter.dx - 1) & (pixels_per_cycle - 1));\n              switch (what) {\n              case 0:\n                pshufb(r1, CPTR(elShuffleForRight6));\n                break;\n              case 1:\n                pshufb(r1, CPTR(elShuffleForRight5));\n                break;\n              case 2:\n                pshufb(r1, CPTR(elShuffleForRight4));\n                break;\n              case 3:\n                pshufb(r1, CPTR(elShuffleForRight3));\n                break;\n              case 4:\n                pshufb(r1, CPTR(elShuffleForRight2));\n                break;\n              case 5:\n                pshufb(r1, CPTR(elShuffleForRight1));\n                break;\n              case 6:\n                pshufb(r1, CPTR(elShuffleForRight0));\n                break;\n              }\n              movdqa(r2, r1);\n              punpcklwd(r1, zero);\n              punpckhwd(r2, zero);\n              cvtdq2ps(r1, r1);\n              cvtdq2ps(r2, r2);\n              //jmp(LabelEnd);\n            }\n            else if (iter.op == opLoadRelSrcF32) {\n              shl(newx, 2); // float: *4\n              add(a, newx);\n\n              int what = ((planewidth - iter.dx - 1) & (pixels_per_cycle - 1));\n              //                        what\n              //                         0     ShuffleForRight2_32  keep r1 dword #0   , spread it to 1..3, then spread r1.3 to r2 (ShuffleForRight2_32(r2,r1)\n              //                         1     ShuffleForRight1_32  keep r1 dword #0..1, spread it to 2..3, then spread r1.3 to r2\n              //                         2     ShuffleForRight0_32  keep r1 dword #0..2, spread it to 3   , then spread r1.3 to r2\n              //                         3                          keep r1 dword #0..3,                   , then spread r1.3 to r2\n              //                         4                          keep r1 dword #0..3,                   , keep r2 dword #0   , spread it to 1..3\n              //                         5                          keep r1 dword #0..3,                   , keep r2 dword #0..1, spread it to 2..3\n              //                         6                          keep r1 dword #0..3,                   , keep r2 dword #0..2, spread it to    3\n\n              // no real shift here, just duplicate appropriate pixel into the high ones. But we have two registers\n              if (what <= 3) {\n                movdqu(r1, xmmword_ptr[a]); // 4 pixels, 16 bytes, no need for upper 4 pixels\n                switch (what) {\n                case 0:\n                  pshufd(r1, r1, (0 << 0) | (0 << 2) | (0 << 4) | (0 << 6)); // elShuffleForRight2_32 // fill 3 upper dwords of r1 from r1.0\n                  break;\n                case 1:\n                  pshufd(r1, r1, (0 << 0) | (1 << 2) | (1 << 4) | (1 << 6)); // fill 2 upper dwords of r1 from r1.1\n                  break;\n                case 2:\n                  pshufd(r1, r1, (0 << 0) | (1 << 2) | (2 << 4) | (2 << 6)); // elShuffleForRight0_32 // fill 1 upper dwords of r1 from r1.2\n                  break;\n                }\n                pshufd(r2, r1, (3 << 0) | (3 << 2) | (3 << 4) | (3 << 6)); // fill all dwords of r2 from r1.3\n              }\n              else {\n                movdqu(r1, xmmword_ptr[a]); // 4 pixels, 16 bytes, low 4 pixels keep them as is\n                movdqu(r2, xmmword_ptr[a + 16]); // 4 pixels, 16 bytes\n                switch (what) {\n                case 4:\n                  pshufd(r2, r2, (0 << 0) | (0 << 2) | (0 << 4) | (0 << 6)); // elShuffleForRight2_32 // fill 3 upper dwords of r1 from r2.0\n                  break;\n                case 5:\n                  pshufd(r2, r2, (0 << 0) | (1 << 2) | (1 << 4) | (1 << 6)); // fill 2 upper dwords of r1 from r2.1\n                  break;\n                case 6:\n                  pshufd(r2, r2, (0 << 0) | (1 << 2) | (2 << 4) | (2 << 6)); // elShuffleForRight0_32 // fill 1 upper dwords of r1 from r2.2\n                  break;\n                }\n              }\n              // continues on labelEnd\n            }\n            if (iter.dx < 0)\n              jmp(LabelEnd);\n          } // over: iter.dx != 0\n          if (iter.dx < 0) {\n            L(LabelNeg);\n            // When reading from negative x coordinates we read exactly from 0th, then shift and duplicate\n            // For extreme minus offsets we duplicate 0th (leftmost) pixel to each position\n            // example: dx = -1\n            // -1 0  1  2  3  4  5  6  7\n            // A  A  B  C  D  E  F  G         we need this\n            //    A  B  C  D  E  F  G  H      read [0]\n            //    0  A  B  C  D  E  F  G  H   shift\n            //    A  A  B  C  D  E  F  G  H   duplicate by shuffle\n            if (iter.op == opLoadRelSrc8 || iter.op == opLoadRelSrc16) {\n              if (iter.op == opLoadRelSrc8) {\n                sub(a, ptr[regptrs + sizeof(void *) * (RWPTR_START_OF_XCOUNTER)]); // go back to the beginning\n                movq(r1, mmword_ptr[a]); // 8 pixels, 8 bytes\n                punpcklbw(r1, zero); // bytes to words\n              }\n              else if (iter.op == opLoadRelSrc16) {\n                // go back to the beginning, in 16 bit, *2\n                Reg tmp;\n                mov(tmp, ptr[regptrs + sizeof(void *) * (RWPTR_START_OF_XCOUNTER)]);\n                shl(tmp, 1); // for 16 bit 2*xcounter\n                sub(a, tmp);\n                movdqa(r1, xmmword_ptr[a]); // 8 pixels, 16 bytes\n              }\n\n              std::string PartialReadBefore = \"PartialReadBefore\" + getLabelCount();\n              std::string Finalize = \"Finalize\" + getLabelCount();\n              cmp(newx, -pixels_per_cycle); // pixels_per_cycle words\n              jg(PartialReadBefore);\n              // FullReadBefore: newx <= -pixels_per_cycle, clone 0th (leftmost) pixel to all\n              pshufb(r1, CPTR(elShuffleForRight6)); // lowest word to all\n              jmp(Finalize);\n              L(PartialReadBefore);\n              // -pixels_per_cycle < newx < 0\n              int toShift = min(pixels_per_cycle - 1, (-iter.dx) & (pixels_per_cycle - 1));\n              pslldq(r1, toShift * 2); // shift in word domain\n              switch (toShift) {\n              case 1: pshufb(r1, CPTR(elShuffleForLeft0)); break;\n              case 2: pshufb(r1, CPTR(elShuffleForLeft1)); break;\n              case 3: pshufb(r1, CPTR(elShuffleForLeft2)); break;\n              case 4: pshufb(r1, CPTR(elShuffleForLeft3)); break;\n              case 5: pshufb(r1, CPTR(elShuffleForLeft4)); break;\n              case 6: pshufb(r1, CPTR(elShuffleForLeft5)); break;\n              case 7: pshufb(r1, CPTR(elShuffleForLeft6)); break;\n              }\n              L(Finalize);\n\n              movdqa(r2, r1);\n              punpcklwd(r1, zero);\n              punpckhwd(r2, zero);\n              cvtdq2ps(r1, r1);\n              cvtdq2ps(r2, r2);\n            }\n            else if (iter.op == opLoadRelSrcF32) {\n              // negative\n              // go back to the beginning, in 16 bit, *2\n              Reg tmp;\n              mov(tmp, ptr[regptrs + sizeof(void *) * (RWPTR_START_OF_XCOUNTER)]);\n              shl(tmp, 2); // go back to the beginning, in 32 bit, *4\n              sub(a, tmp);\n\n              std::string PartialReadBefore = \"PartialReadBefore\" + getLabelCount();\n\n              cmp(newx, -pixels_per_cycle);\n              jg(PartialReadBefore);\n              // FullReadBefore: newx <= -pixels_per_cycle, clone 0th (leftmost) pixel to all\n              movdqa(r1, xmmword_ptr[a]);\n              pshufd(r1, r1, (0 << 0) | (0 << 2) | (0 << 4) | (0 << 6));\n              movdqa(r2, r1);\n              jmp(LabelEnd);\n\n              L(PartialReadBefore);\n              // -pixels_per_cycle < newx < 0\n              int bytes_to_shift = sizeof(float) * min(pixels_per_cycle - 1, (-iter.dx) & (pixels_per_cycle - 1));\n              //    shift bytes\n              //         4                  r2r1 << 4     shuffle r1.1 to r1.0-0\n              //         8                  r2r1 << 8     shuffle r1.2 to r1.0-1\n              //         12                 r2r1 << 12    shuffle r1.3 to r1.0-2\n              //         16                 r2r1 << 16    -> r2 = r1,                                     , shuffle r2.0 to all r1\n              //         20                 r2r1 << 20    -> r2 = r1, r2 << (20-4), shuffle r2.1 to r2.0-0, shuffle r2.0 to all r1\n              //         24                 r2r1 << 24    -> r2 = r1, r2 << (24-4), shuffle r2.2 to r2.0-1, shuffle r2.0 to all r1\n              //         28                 r2r1 << 28    -> r2 = r1, r2 << (28-4), shuffle r2.3 to r2.0-2, shuffle r2.0 to all r1\n              if (bytes_to_shift < 16) {\n                movdqa(r1, xmmword_ptr[a]); // 4 pixels, 16 bytes\n                movdqa(r2, xmmword_ptr[a + 16]); // 4 pixels, 16 bytes\n                                                 // 4 floats\n                                                 // r2            r1\n                                                 // H3 H2 H1 H0   L3 L2 L1 L0   << 1*4 byte\n                                                 // H2 H1 H0 L3   L2 L1 L0 00\n                                                 // H2 H1 H0 00   or\n                                                 // 00 00 00 L3   L2 L1 L0 00\n                psrldq(r1, 16 - bytes_to_shift);\n                pslldq(r2, bytes_to_shift);\n                por(r2, r1);\n                movdqa(r1, xmmword_ptr[a]); // load again\n                pslldq(r1, bytes_to_shift); // todo: shift + shuffle = single shuffle\n\n                switch (bytes_to_shift) { // 4, 8, 12\n                case 4:\n                  pshufd(r1, r1, (1 << 0) | (1 << 2) | (2 << 4) | (3 << 6)); // elShuffleForLeft0_32 // shuffle r1.1 to r1.0-0\n                  break;\n                case 8:\n                  pshufd(r1, r1, (2 << 0) | (2 << 2) | (2 << 4) | (3 << 6)); // elShuffleForLeft1_32 // shuffle r1.2 to r1.0-1\n                  break;\n                case 12:\n                  pshufd(r1, r1, (3 << 0) | (3 << 2) | (3 << 4) | (3 << 6)); // elShuffleForLeft2_32 // shuffle r1.3 to r1.0-2\n                  break;\n                }\n              }\n              else {\n                // toShift >= 16\n                //movdqa(r1, xmmword_ptr[a]); // no need for 15..31\n                movdqa(r2, xmmword_ptr[a]); // 4 pixels, 16 bytes\n                if (bytes_to_shift > 16)\n                  pslldq(r2, bytes_to_shift - 16);\n\n                switch (bytes_to_shift) { // 20, 24, 28\n                case 20:\n                  pshufd(r2, r2, (1 << 0) | (1 << 2) | (2 << 4) | (3 << 6)); // elShuffleForLeft0_32 // shuffle r2.1 to r2.0-0\n                  break;\n                case 24:\n                  pshufd(r2, r2, (2 << 0) | (2 << 2) | (2 << 4) | (3 << 6)); // elShuffleForLeft1_32 // shuffle r2.2 to r2.0-1\n                  break;\n                case 28:\n                  pshufd(r2, r2, (3 << 0) | (3 << 2) | (3 << 4) | (3 << 6)); // elShuffleForLeft2_32 // shuffle r2.3 to r2.0-2\n                  break;\n                }\n                pshufd(r1, r2, (0 << 0) | (0 << 2) | (0 << 4) | (0 << 6)); // shuffle r2.0 to all r1\n              }\n            }\n          }\n          L(LabelEnd);\n          stack.push_back(std::make_pair(r1, r2));\n        }\n      } // oploadRel8/16/32\n      else if (iter.op == opLoadSrc8) {\n        if (processSingle) {\n          XmmReg r1;\n          Reg a;\n          mov(a, ptr[regptrs + sizeof(void *) * (iter.e.ival + RWPTR_START_OF_INPUTS)]);\n          movd(r1, dword_ptr[a]); // 4 pixels, 4 bytes\n          punpcklbw(r1, zero);\n          punpcklwd(r1, zero);\n          cvtdq2ps(r1, r1);\n          if (maskIt)\n            doMask(r1, constptr, planewidth);\n          stack1.push_back(r1);\n        }\n        else {\n          XmmReg r1, r2;\n          Reg a;\n          mov(a, ptr[regptrs + sizeof(void *) * (iter.e.ival + RWPTR_START_OF_INPUTS)]);\n          movq(r1, mmword_ptr[a]);\n          punpcklbw(r1, zero);\n          movdqa(r2, r1);\n          punpcklwd(r1, zero);\n          punpckhwd(r2, zero);\n          cvtdq2ps(r1, r1);\n          cvtdq2ps(r2, r2);\n          if (maskIt)\n            doMask(r2, constptr, planewidth);\n          stack.push_back(std::make_pair(r1, r2));\n        }\n      }\n      else if (iter.op == opLoadSrc16) {\n        if (processSingle) {\n          XmmReg r1;\n          Reg a;\n          mov(a, ptr[regptrs + sizeof(void *) * (iter.e.ival + RWPTR_START_OF_INPUTS)]);\n          movq(r1, mmword_ptr[a]); // 4 pixels, 8 bytes\n          punpcklwd(r1, zero);\n          cvtdq2ps(r1, r1);\n          if (maskIt)\n            doMask(r1, constptr, planewidth);\n          stack1.push_back(r1);\n        }\n        else {\n          XmmReg r1, r2;\n          Reg a;\n          mov(a, ptr[regptrs + sizeof(void *) * (iter.e.ival + RWPTR_START_OF_INPUTS)]);\n          movdqa(r1, xmmword_ptr[a]);\n          movdqa(r2, r1);\n          punpcklwd(r1, zero);\n          punpckhwd(r2, zero);\n          cvtdq2ps(r1, r1);\n          cvtdq2ps(r2, r2);\n          if (maskIt)\n            doMask(r2, constptr, planewidth);\n          stack.push_back(std::make_pair(r1, r2));\n        }\n      }\n      else if (iter.op == opLoadSrcF32) {\n        if (processSingle) {\n          XmmReg r1;\n          Reg a;\n          mov(a, ptr[regptrs + sizeof(void *) * (iter.e.ival + RWPTR_START_OF_INPUTS)]);\n          movdqa(r1, xmmword_ptr[a]);\n          if (maskIt)\n            doMask(r1, constptr, planewidth);\n          stack1.push_back(r1);\n        }\n        else {\n          XmmReg r1, r2;\n          Reg a;\n          mov(a, ptr[regptrs + sizeof(void *) * (iter.e.ival + RWPTR_START_OF_INPUTS)]);\n          movdqa(r1, xmmword_ptr[a]);\n          movdqa(r2, xmmword_ptr[a + 16]);\n          if (maskIt)\n            doMask(r2, constptr, planewidth);\n          stack.push_back(std::make_pair(r1, r2));\n        }\n      }\n      else if (iter.op == opLoadSrcF16) { // not supported in avs+\n        if (processSingle) {\n          XmmReg r1;\n          Reg a;\n          mov(a, ptr[regptrs + sizeof(void *) * (iter.e.ival + RWPTR_START_OF_INPUTS)]);\n          vcvtph2ps(r1, qword_ptr[a]);\n          if (maskIt)\n            doMask(r1, constptr, planewidth);\n          stack1.push_back(r1);\n        }\n        else {\n          XmmReg r1, r2;\n          Reg a;\n          mov(a, ptr[regptrs + sizeof(void *) * (iter.e.ival + RWPTR_START_OF_INPUTS)]);\n          vcvtph2ps(r1, qword_ptr[a]);\n          vcvtph2ps(r2, qword_ptr[a + 8]);\n          if (maskIt)\n            doMask(r2, constptr, planewidth);\n          stack.push_back(std::make_pair(r1, r2));\n        }\n      }\n      else if (iter.op == opLoadVar) {\n        if (processSingle) {\n          XmmReg r1;\n          // 16 bytes/variable\n          int offset = sizeof(void *) * RWPTR_START_OF_USERVARIABLES + 16 * iter.e.ival;\n          movdqa(r1, xmmword_ptr[regptrs + offset]);\n          if (maskIt)\n            doMask(r1, constptr, planewidth);\n          stack1.push_back(r1);\n        }\n        else {\n          XmmReg r1, r2;\n          // 32 bytes/variable\n          int offset = sizeof(void *) * RWPTR_START_OF_USERVARIABLES + 32 * iter.e.ival;\n          movdqa(r1, xmmword_ptr[regptrs + offset]);\n          movdqa(r2, xmmword_ptr[regptrs + offset + 16]);\n          if (maskIt)\n            doMask(r2, constptr, planewidth);\n          stack.push_back(std::make_pair(r1, r2));\n        }\n      }\n      else if (iter.op == opLoadConst) {\n        if (processSingle) {\n          XmmReg r1;\n          Reg a;\n          mov(a, iter.e.ival);\n          movd(r1, a);\n          shufps(r1, r1, 0);\n          if (maskIt)\n            doMask(r1, constptr, planewidth);\n          stack1.push_back(r1);\n        }\n        else {\n          XmmReg r1, r2;\n          Reg a;\n          mov(a, iter.e.ival);\n          movd(r1, a);\n          shufps(r1, r1, 0);\n          movaps(r2, r1);\n          if (maskIt)\n            doMask(r2, constptr, planewidth);\n          stack.push_back(std::make_pair(r1, r2));\n        }\n      }\n      else if (iter.op == opDup) {\n        if (processSingle) {\n          auto p = std::next(stack1.rbegin(), iter.e.ival);\n          XmmReg r1;\n          movaps(r1, *p);\n          stack1.push_back(r1);\n        }\n        else {\n          auto p = std::next(stack.rbegin(), iter.e.ival);\n          XmmReg r1, r2;\n          movaps(r1, p->first);\n          movaps(r2, p->second);\n          stack.push_back(std::make_pair(r1, r2));\n        }\n      }\n      else if (iter.op == opSwap) {\n        if (processSingle) {\n          std::swap(stack1.back(), *std::next(stack1.rbegin(), iter.e.ival));\n        }\n        else {\n          std::swap(stack.back(), *std::next(stack.rbegin(), iter.e.ival));\n        }\n      }\n      else if (iter.op == opAdd) {\n        if (processSingle) {\n          TwoArgOp_Single(addps)\n        }\n        else {\n          TwoArgOp(addps)\n        }\n      }\n      else if (iter.op == opSub) {\n        if (processSingle) {\n          TwoArgOp_Single(subps)\n        }\n        else {\n          TwoArgOp(subps)\n        }\n      }\n      else if (iter.op == opMul) {\n        if (processSingle) {\n          TwoArgOp_Single(mulps)\n        }\n        else {\n          TwoArgOp(mulps)\n        }\n      }\n      else if (iter.op == opDiv) {\n        if (processSingle) {\n          TwoArgOp_Single(divps)\n        }\n        else {\n          TwoArgOp(divps)\n        }\n      }\n      else if (iter.op == opFmod) {\n        if (processSingle) {\n          auto t1 = stack1.back(); // despite the Intel compiler warnings, this is intentionally a copy and not a reference (valid for all such messages as well)\n          stack1.pop_back();\n          auto &t2 = stack1.back();\n          FMOD_PS(t2, t1)\n        }\n        else {\n          auto t1 = stack.back();\n          stack.pop_back();\n          auto &t2 = stack.back();\n          FMOD_PS(t2.first, t1.first)\n          FMOD_PS(t2.second, t1.second)\n        }\n      }\n      else if (iter.op == opMax) {\n        if (processSingle) {\n          TwoArgOp_Single(maxps)\n        }\n        else {\n          TwoArgOp(maxps)\n        }\n      }\n      else if (iter.op == opMin) {\n        if (processSingle) {\n          TwoArgOp_Single(minps)\n        }\n        else {\n          TwoArgOp(minps)\n        }\n      }\n      else if (iter.op == opSqrt) {\n        if (processSingle) {\n          auto &t1 = stack1.back();\n          maxps(t1, zero);\n          sqrtps(t1, t1);\n        }\n        else {\n          auto &t1 = stack.back();\n          maxps(t1.first, zero);\n          maxps(t1.second, zero);\n          sqrtps(t1.first, t1.first);\n          sqrtps(t1.second, t1.second);\n        }\n      }\n      // Integer store operations: Why sometimes C version differs from SSE: convert to int from .5 intermediates.\n      // Simd version of float -> int32 (cvtps2dq) is using the SSE rounding mode \"round to nearest\"\n      // C version is using: (uint8_t)(f + 0.5f) which turnes into cvttps, typecast to int uses trunc\n      // Even for positive numbers they are not the same, when converting occurs exactly from the halfway\n      // SSE is using Banker's rounding, which rounds to the nearest _even_ integer value. https://en.wikipedia.org/wiki/IEEE_754#Roundings_to_nearest\n      //        C   SSE\n      //  0.5   1   0\n      //  1.5   2   2\n      //  2.5   3   2\n      //  3.5   4   4\n      // 3.7.1test27: no more banker's rounding. Using cvttps and +0.5f\n      else if (iter.op == opStore8) {\n        if (processSingle) {\n          auto t1 = stack1.back();\n          stack1.pop_back();\n          XmmReg r1;\n          Reg a;\n          addps(t1, CPTR(elfloat_half)); // rounder for truncate! no banker's rounding\n          maxps(t1, zero);\n          minps(t1, CPTR(elstore8));\n          mov(a, ptr[regptrs]);\n          cvttps2dq(t1, t1);    // 00 w3 00 w2 00 w1 00 w0 -- min/max clamp ensures that high words are zero\n          packssdw(t1, zero);  // _mm_packs_epi32: w7 w6 w5 w4 w3 w2 w1 w0\n          packuswb(t1, zero);  // _mm_packus_epi16: 0 0 0 0 0 0 0 0 b7 b6 b5 b4 b3 b2 b1 b0\n          movd(dword_ptr[a], t1);\n        }\n        else {\n          auto t1 = stack.back();\n          stack.pop_back();\n          XmmReg r1, r2;\n          Reg a;\n          addps(t1.first, CPTR(elfloat_half)); // rounder for truncate! no banker's rounding\n          maxps(t1.first, zero);\n          addps(t1.second, CPTR(elfloat_half)); // rounder for truncate! no banker's rounding\n          maxps(t1.second, zero);\n          minps(t1.first, CPTR(elstore8));\n          minps(t1.second, CPTR(elstore8));\n          mov(a, ptr[regptrs]);\n          cvttps2dq(t1.first, t1.first);    // 00 w3 00 w2 00 w1 00 w0 -- min/max clamp ensures that high words are zero\n          cvttps2dq(t1.second, t1.second);  // 00 w7 00 w6 00 w5 00 w4\n          // t1.second is the lo\n          packssdw(t1.first, t1.second);   // _mm_packs_epi32: w7 w6 w5 w4 w3 w2 w1 w0\n          packuswb(t1.first, zero);       // _mm_packus_epi16: 0 0 0 0 0 0 0 0 b7 b6 b5 b4 b3 b2 b1 b0\n          movq(mmword_ptr[a], t1.first);\n        }\n      }\n      else if (iter.op == opStore10 // avs+\n        || iter.op == opStore12 // avs+\n        || iter.op == opStore14 // avs+\n        || iter.op == opStore16\n        ) {\n        if (processSingle) {\n          auto t1 = stack1.back();\n          stack1.pop_back();\n          XmmReg r1;\n          Reg a;\n          addps(t1, CPTR(elfloat_half)); // rounder for truncate! no banker's rounding\n          maxps(t1, zero);\n          switch (iter.op) {\n          case opStore10:\n            minps(t1, CPTR(elstore10));\n            break;\n          case opStore12:\n            minps(t1, CPTR(elstore12));\n            break;\n          case opStore14:\n            minps(t1, CPTR(elstore14));\n            break;\n          case opStore16:\n            minps(t1, CPTR(elstore16));\n            break;\n          }\n          mov(a, ptr[regptrs]);\n          cvttps2dq(t1, t1); // no cvtps, but cvttps\n          // new\n          switch (iter.op) {\n          case opStore10:\n          case opStore12:\n          case opStore14:\n            packssdw(t1, zero);   // _mm_packs_epi32: w7 w6 w5 w4 w3 w2 w1 w0\n            break;\n          case opStore16:\n            if (cpuFlags & CPUF_SSE4_1) {\n              packusdw(t1, zero);   // _mm_packus_epi32: w7 w6 w5 w4 w3 w2 w1 w0\n            }\n            else {\n              // old, sse2\n              movdqa(r1, t1);   // 00 w3 00 w2 00 w1 00 w0 -- min/max clamp ensures that high words are zero\n              psrldq(t1, 6);\n              por(t1, r1);\n              pshuflw(t1, t1, 0b11011000);\n              punpcklqdq(t1, zero);\n            }\n            break;\n          }\n          movq(mmword_ptr[a], t1);\n        }\n        else {\n          auto t1 = stack.back();\n          stack.pop_back();\n          XmmReg r1, r2;\n          Reg a;\n          addps(t1.first, CPTR(elfloat_half)); // rounder for truncate! no banker's rounding\n          maxps(t1.first, zero);\n          addps(t1.second, CPTR(elfloat_half)); // rounder for truncate! no banker's rounding\n          maxps(t1.second, zero);\n          switch (iter.op) {\n          case opStore10:\n            minps(t1.first, CPTR(elstore10));\n            minps(t1.second, CPTR(elstore10));\n            break;\n          case opStore12:\n            minps(t1.first, CPTR(elstore12));\n            minps(t1.second, CPTR(elstore12));\n            break;\n          case opStore14:\n            minps(t1.first, CPTR(elstore14));\n            minps(t1.second, CPTR(elstore14));\n            break;\n          case opStore16:\n            minps(t1.first, CPTR(elstore16));\n            minps(t1.second, CPTR(elstore16));\n            break;\n          }\n          mov(a, ptr[regptrs]);\n          cvttps2dq(t1.first, t1.first); // no bankers rounding\n          cvttps2dq(t1.second, t1.second);\n          // new\n          switch (iter.op) {\n          case opStore10:\n          case opStore12:\n          case opStore14:\n            packssdw(t1.first, t1.second);   // _mm_packs_epi32: w7 w6 w5 w4 w3 w2 w1 w0\n            break;\n          case opStore16:\n            if (cpuFlags & CPUF_SSE4_1) {\n              packusdw(t1.first, t1.second);   // _mm_packus_epi32: w7 w6 w5 w4 w3 w2 w1 w0\n            }\n            else {\n              // old, sse2\n              movdqa(r1, t1.first);   // 00 w3 00 w2 00 w1 00 w0 -- min/max clamp ensures that high words are zero\n              movdqa(r2, t1.second);  // 00 w7 00 w6 00 w5 00 w4\n              psrldq(t1.first, 6);\n              psrldq(t1.second, 6);\n              por(t1.first, r1);\n              por(t1.second, r2);\n              pshuflw(t1.first, t1.first, 0b11011000);\n              pshuflw(t1.second, t1.second, 0b11011000);\n              punpcklqdq(t1.first, t1.second);\n            }\n            break;\n          }\n          movdqa(xmmword_ptr[a], t1.first);\n        }\n      }\n      else if (iter.op == opStoreF32) {\n        if (processSingle) {\n          auto t1 = stack1.back();\n          stack1.pop_back();\n          Reg a;\n          mov(a, ptr[regptrs]);\n          movaps(xmmword_ptr[a], t1);\n        }\n        else {\n          auto t1 = stack.back();\n          stack.pop_back();\n          Reg a;\n          mov(a, ptr[regptrs]);\n          movaps(xmmword_ptr[a], t1.first);\n          movaps(xmmword_ptr[a + 16], t1.second);\n        }\n      }\n      else if (iter.op == opStoreF16) { // not supported in avs+\n        if (processSingle) {\n          auto t1 = stack1.back();\n          stack1.pop_back();\n          Reg a;\n          mov(a, ptr[regptrs]);\n          vcvtps2ph(qword_ptr[a], t1, 0);\n        }\n        else {\n          auto t1 = stack.back();\n          stack.pop_back();\n          Reg a;\n          mov(a, ptr[regptrs]);\n          vcvtps2ph(qword_ptr[a], t1.first, 0);\n          vcvtps2ph(qword_ptr[a + 8], t1.second, 0);\n        }\n      }\n      else if (iter.op == opStoreVar || iter.op == opStoreVarAndDrop1) {\n        if (processSingle) {\n          auto t1 = stack1.back();\n          // 16 bytes/variable\n          int offset = sizeof(void *) * RWPTR_START_OF_USERVARIABLES + 16 * iter.e.ival;\n          movaps(xmmword_ptr[regptrs + offset], t1);\n          if (iter.op == opStoreVarAndDrop1)\n            stack1.pop_back();\n        }\n        else {\n          auto t1 = stack.back();\n          // 32 byte/variable\n          int offset = sizeof(void *) * RWPTR_START_OF_USERVARIABLES + 32 * iter.e.ival;\n          movaps(xmmword_ptr[regptrs + offset], t1.first);\n          movaps(xmmword_ptr[regptrs + offset + 16], t1.second);\n          if (iter.op == opStoreVarAndDrop1)\n            stack.pop_back();\n        }\n      }\n      else if (iter.op == opAbs) {\n        if (processSingle) {\n          auto &t1 = stack1.back();\n          andps(t1, CPTR(elabsmask));\n        }\n        else {\n          auto &t1 = stack.back();\n          andps(t1.first, CPTR(elabsmask));\n          andps(t1.second, CPTR(elabsmask));\n        }\n      }\n      else if (iter.op == opSgn) {\n        // 1, 0, -1\n        /*\n          __m128 sgn(__m128 value) {\n            const __m128 zero = _mm_set_ps1 (0.0f);\n            __m128 p = _mm_and_ps(_mm_cmpgt_ps(value, zero), _mm_set_ps1(1.0f));\n            __m128 n = _mm_and_ps(_mm_cmplt_ps(value, zero), _mm_set_ps1(-1.0f));\n            return _mm_or_ps(p, n);\n          }\n        */\n        if (processSingle) {\n          auto &t1 = stack1.back();\n          XmmReg r1, r2;\n          xorps(r2, r2);\n          movaps(r1, t1);\n          movaps(t1, r2);\n          cmpltps(t1, r1);\n          cmpltps(r1, r2);\n          andps(t1, CPTR(elfloat_one));\n          andps(r1, CPTR(elfloat_minusone));\n          orps(t1, r1);\n        }\n        else {\n          auto &t1 = stack.back();\n          XmmReg r2, r3, r4, r5;\n          xorps(r2, r2);\n          xorps(r3, r3);\n          cmpltps(r3, t1.first);\n          cmpltps(t1.first, r2);\n          movaps(r4, t1.first);\n          andnps(r4, r3);\n          movaps(r3, CPTR(elfloat_one));\n          xorps(r5, r5);\n          cmpltps(r5, t1.second);\n          cmpltps(t1.second, r2);\n          movaps(r2, CPTR(elfloat_minusone));\n          andps(t1.first, r2);\n          andps(r2, t1.second);\n          andnps(t1.second, r5);\n          andps(r4, r3);\n          orps(t1.first, r4);\n          andps(t1.second, r3);\n          orps(t1.second, r2);\n        }\n      }\n      else if (iter.op == opNeg) {\n        if (processSingle) {\n          auto &t1 = stack1.back();\n          cmpleps(t1, zero);\n          andps(t1, CPTR(elfloat_one));\n        }\n        else {\n          auto &t1 = stack.back();\n          cmpleps(t1.first, zero);\n          cmpleps(t1.second, zero);\n          andps(t1.first, CPTR(elfloat_one));\n          andps(t1.second, CPTR(elfloat_one));\n        }\n      }\n      else if (iter.op == opNegSign) {\n        if (processSingle) {\n          auto& t1 = stack1.back();\n          xorps(t1, CPTR(elsignmask));\n        }\n        else {\n          auto& t1 = stack.back();\n          xorps(t1.first, CPTR(elsignmask));\n          xorps(t1.second, CPTR(elsignmask));\n        }\n      }\n      else if (iter.op == opAnd) {\n        if (processSingle) {\n          LogicOp_Single(andps)\n        }\n        else {\n          LogicOp(andps)\n        }\n      }\n      else if (iter.op == opOr) {\n        if (processSingle) {\n          LogicOp_Single(orps)\n        }\n        else {\n          LogicOp(orps)\n        }\n      }\n      else if (iter.op == opXor) {\n        if (processSingle) {\n          LogicOp_Single(xorps)\n        }\n        else {\n          LogicOp(xorps)\n        }\n      }\n      else if (iter.op == opGt) { // a > b (gt) -> b < (lt) a\n        if (processSingle) {\n          CmpOp_Single(cmpltps)\n        }\n        else {\n          CmpOp(cmpltps)\n        }\n      }\n      else if (iter.op == opLt) { // a < b (lt) -> b > (gt,nle) a\n        if (processSingle) {\n          CmpOp_Single(cmpnleps)\n        }\n        else {\n          CmpOp(cmpnleps)\n        }\n      }\n      else if (iter.op == opEq) { // a == b -> b == a\n        if (processSingle) {\n          CmpOp_Single(cmpeqps)\n        }\n        else {\n          CmpOp(cmpeqps)\n        }\n      }\n      else if (iter.op == opNotEq) { // a != b\n        if (processSingle) {\n          CmpOp_Single(cmpneqps)\n        }\n        else {\n          CmpOp(cmpneqps)\n        }\n      }\n      else if (iter.op == opLE) { // a <= b -> b >= (ge,nlt) a\n        if (processSingle) {\n          CmpOp_Single(cmpnltps)\n        }\n        else {\n          CmpOp(cmpnltps)\n        }\n      }\n      else if (iter.op == opGE) { // a >= b -> b <= (le) a\n        if (processSingle) {\n          CmpOp_Single(cmpleps)\n        }\n        else {\n          CmpOp(cmpleps)\n        }\n      }\n      else if (iter.op == opTernary) {\n        if (processSingle) {\n          auto t1 = stack1.back();\n          stack1.pop_back();\n          auto t2 = stack1.back();\n          stack1.pop_back();\n          auto t3 = stack1.back();\n          stack1.pop_back();\n          XmmReg r1;\n          xorps(r1, r1);\n          cmpltps(r1, t3);\n          andps(t2, r1);\n          andnps(r1, t1);\n          orps(r1, t2);\n          stack1.push_back(r1);\n        }\n        else {\n          auto t1 = stack.back();\n          stack.pop_back();\n          auto t2 = stack.back();\n          stack.pop_back();\n          auto t3 = stack.back();\n          stack.pop_back();\n          XmmReg r1, r2;\n          xorps(r1, r1);\n          xorps(r2, r2);\n          cmpltps(r1, t3.first);\n          cmpltps(r2, t3.second);\n          andps(t2.first, r1);\n          andps(t2.second, r2);\n          andnps(r1, t1.first);\n          andnps(r2, t1.second);\n          orps(r1, t2.first);\n          orps(r2, t2.second);\n          stack.push_back(std::make_pair(r1, r2));\n        }\n      }\n      else if (iter.op == opExp) {\n        if (processSingle) {\n          auto &t1 = stack1.back();\n          EXP_PS(t1)\n        }\n        else {\n          auto &t1 = stack.back();\n          EXP_PS(t1.first)\n            EXP_PS(t1.second)\n        }\n      }\n      else if (iter.op == opLog) {\n        if (processSingle) {\n          auto &t1 = stack1.back();\n          LOG_PS(t1)\n        }\n        else {\n          auto &t1 = stack.back();\n          LOG_PS(t1.first)\n            LOG_PS(t1.second)\n        }\n      }\n      else if (iter.op == opPow) {\n        if (processSingle) {\n          auto t1 = stack1.back();\n          stack1.pop_back();\n          auto &t2 = stack1.back();\n          LOG_PS(t2)\n            mulps(t2, t1);\n          EXP_PS(t2)\n        }\n        else {\n          auto t1 = stack.back();\n          stack.pop_back();\n          auto &t2 = stack.back();\n          LOG_PS(t2.first)\n            mulps(t2.first, t1.first);\n          EXP_PS(t2.first)\n            LOG_PS(t2.second)\n            mulps(t2.second, t1.second);\n          EXP_PS(t2.second)\n        }\n      }\n      else if (iter.op == opSin) {\n        if (processSingle) {\n          auto& _t1 = stack1.back();\n          SINCOS_PS(true, _t1, _t1)\n        }\n        else {\n          auto& _t1 = stack.back();\n          SINCOS_PS(true, _t1.first, _t1.first);\n          SINCOS_PS(true, _t1.second, _t1.second);\n        }\n      }\n      else if (iter.op == opCos) {\n        if (processSingle) {\n          auto& _t1 = stack1.back();\n          SINCOS_PS(false, _t1, _t1)\n        }\n        else {\n          auto& _t1 = stack.back();\n          SINCOS_PS(false, _t1.first, _t1.first);\n          SINCOS_PS(false, _t1.second, _t1.second);\n        }\n      }\n      else if (iter.op == opTan) {\n        if (processSingle) {\n          auto& t1 = stack1.back();\n          TAN_PS(t1)\n        }\n        else {\n          auto& t1 = stack.back();\n          TAN_PS(t1.first);\n          TAN_PS(t1.second);\n        }\n      }\n      else if (iter.op == opAtan2) {\n        if (processSingle) {\n          auto t1 = stack1.back();\n          stack1.pop_back();\n          auto& t2 = stack1.back();\n          ATAN2_PS(t2, t1);\n        }\n        else {\n          auto t1 = stack.back();\n          stack.pop_back();\n          auto& t2 = stack.back();\n          ATAN2_PS(t2.first, t1.first);\n          ATAN2_PS(t2.second, t1.second);\n        }\n      }\n      else if (iter.op == opClip) {\n        // clip(a, low, high) = min(max(a, low),high)\n        if (processSingle) {\n          auto t1 = stack1.back();\n          stack1.pop_back();\n          auto t2 = stack1.back();\n          stack1.pop_back();\n          auto &t3 = stack1.back();\n          maxps(t3, t2);\n          minps(t3, t1);\n        }\n        else {\n          auto t1 = stack.back();\n          stack.pop_back();\n          auto t2 = stack.back();\n          stack.pop_back();\n          auto &t3 = stack.back();\n          maxps(t3.first, t2.first);\n          minps(t3.first, t1.first);\n          maxps(t3.second, t2.second);\n          minps(t3.second, t1.second);\n        }\n      }\n      else if (iter.op == opRound || iter.op == opFloor || iter.op == opCeil || iter.op == opTrunc) {\n         const int rounder_flag =\n           (iter.op == opRound) ? (FROUND_TO_NEAREST_INT | FROUND_NO_EXC) :\n           (iter.op == opFloor) ? (FROUND_TO_NEG_INF | FROUND_NO_EXC) :\n           (iter.op == opCeil) ? (FROUND_TO_POS_INF | FROUND_NO_EXC) :\n           (FROUND_TO_ZERO | FROUND_NO_EXC); // opTrunc\n        if (processSingle) {\n          auto& t1 = stack1.back();\n          roundps(t1, t1, rounder_flag);\n        }\n        else {\n          auto& t1 = stack.back();\n          roundps(t1.first, t1.first, rounder_flag);\n          roundps(t1.second, t1.second, rounder_flag);\n        }\n      }\n\n    }\n  }\n\n    void main(Reg regptrs, Reg regoffs, Reg niter, Reg SpatialY)\n    {\n        XmmReg zero;\n        pxor(zero, zero);\n        Reg constptr;\n        mov(constptr, (uintptr_t)logexpconst);\n\n        L(\"wloop\");\n        cmp(niter, 0);\n        je(\"wend\");\n        //sub(niter, 1);\n        dec(niter);\n\n        // process two sets, no partial input masking\n        if (singleMode)\n          processingLoop<true, false>(regptrs, zero, constptr, SpatialY);\n        else\n          processingLoop<false, false>(regptrs, zero, constptr, SpatialY);\n\n        const int EXTRA = 2; // output pointer, xcounter\n        if constexpr(sizeof(void *) == 8) {\n            int numIter = (numInputs + EXTRA + 1) / 2;\n            for (int i = 0; i < numIter; i++) {\n                XmmReg r1, r2;\n                movdqu(r1, xmmword_ptr[regptrs + 16 * i]);\n                movdqu(r2, xmmword_ptr[regoffs + 16 * i]);\n                paddq(r1, r2);\n                movdqu(xmmword_ptr[regptrs + 16 * i], r1);\n            }\n        } else {\n            int numIter = (numInputs + EXTRA + 3) / 4;\n            for (int i = 0; i < numIter; i++) {\n                XmmReg r1, r2;\n                movdqu(r1, xmmword_ptr[regptrs + 16 * i]);\n                movdqu(r2, xmmword_ptr[regoffs + 16 * i]);\n                paddd(r1, r2);\n                movdqu(xmmword_ptr[regptrs + 16 * i], r1);\n            }\n        }\n\n        jmp(\"wloop\");\n        L(\"wend\");\n\n        int nrestpixels = planewidth & (singleMode ? 3 : 7);\n        if (nrestpixels > 4) // dual process with masking\n          processingLoop<false, true>(regptrs, zero, constptr, SpatialY);\n        else if (nrestpixels == 4) // single process, no masking\n          processingLoop<true, false>(regptrs, zero, constptr, SpatialY);\n        else if (nrestpixels > 0) // single process, masking\n          processingLoop<true, true>(regptrs, zero, constptr, SpatialY);\n    }\n};\n\n// avx2 evaluator with two ymm registers\nstruct ExprEvalAvx2 : public jitasm::function<void, ExprEvalAvx2, uint8_t *, const intptr_t *, intptr_t, intptr_t> {\n\n  std::vector<ExprOp> ops;\n  int numInputs;\n  int cpuFlags;\n  int planewidth; // original, lut can overwrite\n  int planeheight;\n  bool singleMode;\n\n  ExprEvalAvx2(std::vector<ExprOp> &ops, int numInputs, int cpuFlags, int planewidth, int planeheight, bool singleMode) : ops(ops), numInputs(numInputs), cpuFlags(cpuFlags),\n    planewidth(planewidth), planeheight(planeheight), singleMode(singleMode) {}\n\n  template<bool processSingle, bool maskUnused>\n  AVS_FORCEINLINE void processingLoop(Reg &regptrs, YmmReg &zero, Reg &constptr, Reg &SpatialY)\n  {\n    std::list<std::pair<YmmReg, YmmReg>> stack;\n    std::list<YmmReg> stack1;\n\n    // reason of masking: prevent loading 'junk', out of frame pixels, which can be NaN floats for example.\n    // If processingLoop works in dual lane mode (!processSingle), masking occurs only for the high lane,\n    // when there is no need for dual lanes (width mod 16 is <= 8 pixels), processSingle=true is used\n    const bool maskIt = maskUnused && ((planewidth & 7) != 0);\n    const int mask = ((1 << (planewidth & 7)) - 1);\n\n    // mask by zero when we have only 1-7 valid pixels in the lower (single-lane) or upper (dual-lane)\n    // 1: 2-1   = 1   // 00000001\n    // 2: 4-1   = 3   // 00000011\n    // 7: 128-1 = 127 // 01111111\n\n    for (const auto &iter : ops) {\n      if (iter.op == opLoadSpatialX) {\n        if (processSingle) {\n          YmmReg r1;\n          XmmReg r1x;\n          vmovd(r1x, dword_ptr[regptrs + sizeof(void *) * (RWPTR_START_OF_XCOUNTER)]);\n          vcvtdq2ps(r1x, r1x);\n          vbroadcastss(r1, r1x);\n          vaddps(r1, r1, CPTR_AVX(spatialX));\n          stack1.push_back(r1);\n        }\n        else {\n          YmmReg r1, r2;\n          XmmReg r1x;\n          vmovd(r1x, dword_ptr[regptrs + sizeof(void *) * (RWPTR_START_OF_XCOUNTER)]);\n          vcvtdq2ps(r1x, r1x);\n          vbroadcastss(r1, r1x);\n          vmovaps(r2, r1);\n          vaddps(r1, r1, CPTR_AVX(spatialX));\n          vaddps(r2, r2, CPTR_AVX(spatialX2));\n          stack.push_back(std::make_pair(r1, r2));\n        }\n      }\n      else if (iter.op == opLoadSpatialY) {\n        if (processSingle) {\n          YmmReg r1;\n          XmmReg r1x;\n#ifdef JITASM64\n          vmovq(r1x, SpatialY);\n#else\n          vmovd(r1x, SpatialY);\n#endif\n          vcvtdq2ps(r1x, r1x);\n          vbroadcastss(r1, r1x);\n          stack1.push_back(r1);\n        }\n        else {\n          YmmReg r1, r2;\n          XmmReg r1x;\n#ifdef JITASM64\n          vmovq(r1x, SpatialY);\n#else\n          vmovd(r1x, SpatialY);\n#endif\n          vcvtdq2ps(r1x, r1x);\n          vbroadcastss(r1, r1x);\n          vmovaps(r2, r1);\n          stack.push_back(std::make_pair(r1, r2));\n        }\n      }\n      else if (iter.op == opLoadInternalVar) {\n        if (processSingle) {\n          YmmReg r1;\n          XmmReg r1x;\n          vmovd(r1x, dword_ptr[regptrs + sizeof(void *) * (iter.e.ival + RWPTR_START_OF_INTERNAL_VARIABLES)]);\n          vbroadcastss(r1, r1x);\n          stack1.push_back(r1);\n        }\n        else {\n          YmmReg r1, r2;\n          XmmReg r1x;\n          vmovd(r1x, dword_ptr[regptrs + sizeof(void *) * (iter.e.ival + RWPTR_START_OF_INTERNAL_VARIABLES)]);\n          vbroadcastss(r1, r1x);\n          vmovaps(r2, r1);\n          stack.push_back(std::make_pair(r1, r2));\n        }\n      }\n      else if (iter.op == opLoadFramePropVar) {\n        if (processSingle) {\n          YmmReg r1;\n          XmmReg r1x;\n          vmovd(r1x, dword_ptr[regptrs + sizeof(void*) * (iter.e.ival + RWPTR_START_OF_INTERNAL_FRAMEPROP_VARIABLES)]);\n          vbroadcastss(r1, r1x);\n          stack1.push_back(r1);\n        }\n        else {\n          YmmReg r1, r2;\n          XmmReg r1x;\n          vmovd(r1x, dword_ptr[regptrs + sizeof(void*) * (iter.e.ival + RWPTR_START_OF_INTERNAL_FRAMEPROP_VARIABLES)]);\n          vbroadcastss(r1, r1x);\n          vmovaps(r2, r1);\n          stack.push_back(std::make_pair(r1, r2));\n        }\n      }\n      else if (iter.op == opLoadSrc8) {\n        if (processSingle) {\n          XmmReg r1x;\n          YmmReg r1;\n          Reg a;\n          mov(a, ptr[regptrs + sizeof(void *) * (iter.e.ival + RWPTR_START_OF_INPUTS)]);\n          // 8 bytes, 8 pixels * uint8_t\n          vmovq(r1x, mmword_ptr[a]);\n          // 8->32 bits like _mm256_cvtepu8_epi32\n          vpmovzxbd(r1, r1x);\n          // int -> float\n          vcvtdq2ps(r1, r1);\n          if (maskIt)\n            vblendps(r1, zero, r1, mask);\n          stack1.push_back(r1);\n        }\n        else {\n          XmmReg r1x;\n          YmmReg r1, r2;\n          Reg a;\n          mov(a, ptr[regptrs + sizeof(void *) * (iter.e.ival + RWPTR_START_OF_INPUTS)]);\n          // 16 bytes, 16 pixels * uint8_t\n          vmovdqa(r1x, xmmword_ptr[a]);\n          // 8->16 bits like _mm256_cvtepu8_epi16\n          vpmovzxbw(r1, r1x);\n          // 16->32 bit like _mm256_cvtepu16_epi32\n          vextracti128(r1x, r1, 1); // upper 128\n          vpmovzxwd(r2, r1x);\n          vextracti128(r1x, r1, 0); // lower 128\n          vpmovzxwd(r1, r1x);\n          // int -> float\n          vcvtdq2ps(r1, r1);\n          vcvtdq2ps(r2, r2);\n          if (maskIt)\n            vblendps(r2, zero, r2, mask);\n          stack.push_back(std::make_pair(r1, r2));\n        }\n      }\n      else if (iter.op == opLoadSrc16) {\n        if (processSingle) {\n          XmmReg r1x;\n          YmmReg r1;\n          Reg a;\n          mov(a, ptr[regptrs + sizeof(void *) * (iter.e.ival + RWPTR_START_OF_INPUTS)]);\n          // 16 bytes, 8 pixels * uint16_t\n          vmovdqa(r1x, xmmword_ptr[a]);\n          // 16->32 bit like _mm256_cvtepu16_epi32\n          vpmovzxwd(r1, r1x);\n          // int -> float\n          vcvtdq2ps(r1, r1);\n          if (maskIt)\n            vblendps(r1, zero, r1, mask);\n          stack1.push_back(r1);\n        }\n        else {\n          XmmReg r1x;\n          YmmReg r1, r2;\n          Reg a;\n          mov(a, ptr[regptrs + sizeof(void *) * (iter.e.ival + RWPTR_START_OF_INPUTS)]);\n          // 32 bytes, 16 pixels * uint16_t\n          vmovdqa(r1, ymmword_ptr[a]);\n          // 16->32 bit like _mm256_cvtepu16_epi32\n          vextracti128(r1x, r1, 1); // upper 128\n          vpmovzxwd(r2, r1x);\n          vextracti128(r1x, r1, 0); // lower 128\n          vpmovzxwd(r1, r1x);\n          // int -> float\n          vcvtdq2ps(r1, r1);\n          vcvtdq2ps(r2, r2);\n          if (maskIt)\n            vblendps(r2, zero, r2, mask);\n          stack.push_back(std::make_pair(r1, r2));\n        }\n      }\n      else if (iter.op == opLoadSrcF32) {\n        if (processSingle) {\n          YmmReg r1;\n          Reg a;\n          mov(a, ptr[regptrs + sizeof(void *) * (iter.e.ival + RWPTR_START_OF_INPUTS)]);\n          // 32 bytes, 8 * float\n          vmovdqa(r1, ymmword_ptr[a]);\n          if (maskIt)\n            vblendps(r1, zero, r1, mask);\n          stack1.push_back(r1);\n        }\n        else {\n          YmmReg r1, r2;\n          Reg a;\n          mov(a, ptr[regptrs + sizeof(void *) * (iter.e.ival + RWPTR_START_OF_INPUTS)]);\n          // 32 bytes, 8 * float\n          vmovdqa(r1, ymmword_ptr[a]);\n          vmovdqa(r2, ymmword_ptr[a + 32]); // needs 64 byte aligned data to prevent read past valid data!\n          if (maskIt)\n            vblendps(r2, zero, r2, mask);\n          stack.push_back(std::make_pair(r1, r2));\n        }\n      }\n      else if (iter.op == opLoadSrcF16) { // not supported in avs+\n        if (processSingle) {\n          YmmReg r1;\n          Reg a;\n          mov(a, ptr[regptrs + sizeof(void *) * (iter.e.ival + RWPTR_START_OF_INPUTS)]);\n          vcvtph2ps(r1, xmmword_ptr[a]);\n          if (maskIt)\n            vblendps(r1, zero, r1, mask);\n          stack1.push_back(r1);\n        }\n        else {\n          YmmReg r1, r2;\n          Reg a;\n          mov(a, ptr[regptrs + sizeof(void *) * (iter.e.ival + RWPTR_START_OF_INPUTS)]);\n          vcvtph2ps(r1, xmmword_ptr[a]);\n          vcvtph2ps(r2, xmmword_ptr[a + 16]);\n          if (maskIt)\n            vblendps(r2, zero, r2, mask);\n          stack.push_back(std::make_pair(r1, r2));\n        }\n      }\n      else if (iter.op == opLoadVar) {\n        if (processSingle) {\n          YmmReg r1;\n          // 32 bytes/variable\n          int offset = sizeof(void *) * RWPTR_START_OF_USERVARIABLES + 32 * iter.e.ival;\n          // 32 bytes, 8 * float\n          vmovdqa(r1, ymmword_ptr[regptrs + offset]);\n          if (maskIt)\n            vblendps(r1, zero, r1, mask);\n          stack1.push_back(r1);\n        }\n        else {\n          YmmReg r1, r2;\n          // 64 bytes/variable\n          int offset = sizeof(void *) * RWPTR_START_OF_USERVARIABLES + 64 * iter.e.ival;\n          // 32 bytes, 8 * float\n          vmovdqa(r1, ymmword_ptr[regptrs + offset]);\n          vmovdqa(r2, ymmword_ptr[regptrs + offset + 32]); // needs 64 byte aligned data to prevent read past valid data!\n          if (maskIt)\n            vblendps(r2, zero, r2, mask);\n          stack.push_back(std::make_pair(r1, r2));\n        }\n      }\n      else if (iter.op == opLoadConst) {\n        if (processSingle) {\n          YmmReg r1;\n          Reg32 a;\n          XmmReg r1x;\n          mov(a, iter.e.ival);\n          vmovd(r1x, a);\n          vbroadcastss(r1, r1x);\n          stack1.push_back(r1);\n        }\n        else {\n          YmmReg r1, r2;\n          Reg32 a;\n          XmmReg r1x;\n          mov(a, iter.e.ival);\n          vmovd(r1x, a);\n          vbroadcastss(r1, r1x);\n          vmovaps(r2, r1);\n          stack.push_back(std::make_pair(r1, r2));\n        }\n      }\n      else if (iter.op == opDup) {\n        if (processSingle) {\n          auto p = std::next(stack1.rbegin(), iter.e.ival);\n          YmmReg r1;\n          vmovaps(r1, *p);\n          stack1.push_back(r1);\n        }\n        else {\n          auto p = std::next(stack.rbegin(), iter.e.ival);\n          YmmReg r1, r2;\n          vmovaps(r1, p->first);\n          vmovaps(r2, p->second);\n          stack.push_back(std::make_pair(r1, r2));\n        }\n      }\n      else if (iter.op == opSwap) {\n        if(processSingle)\n          std::swap(stack1.back(), *std::next(stack1.rbegin(), iter.e.ival));\n        else\n          std::swap(stack.back(), *std::next(stack.rbegin(), iter.e.ival));\n      }\n      else if (iter.op == opAdd) {\n        if (processSingle) {\n          TwoArgOp_Single_Avx(vaddps);\n        }\n        else {\n          TwoArgOp_Avx(vaddps);\n        }\n      }\n      else if (iter.op == opSub) {\n        if (processSingle) {\n          TwoArgOp_Single_Avx(vsubps);\n        }\n        else {\n          TwoArgOp_Avx(vsubps);\n        }\n      }\n      else if (iter.op == opMul) {\n        if (processSingle) {\n          TwoArgOp_Single_Avx(vmulps);\n        }\n        else {\n          TwoArgOp_Avx(vmulps);\n        }\n      }\n      else if (iter.op == opDiv) {\n        if (processSingle) {\n          TwoArgOp_Single_Avx(vdivps);\n        }\n        else {\n          TwoArgOp_Avx(vdivps);\n        }\n      }\n      else if (iter.op == opFmod) {\n        if (processSingle) {\n          auto t1 = stack1.back();\n          stack1.pop_back();\n          auto &t2 = stack1.back();\n          FMOD_PS_AVX(t2, t1)\n        }\n        else {\n          auto t1 = stack.back();\n          stack.pop_back();\n          auto &t2 = stack.back();\n          FMOD_PS_AVX(t2.first, t1.first)\n          FMOD_PS_AVX(t2.second, t1.second)\n        }\n      }\n      else if (iter.op == opMax) {\n        if (processSingle) {\n          TwoArgOp_Single_Avx(vmaxps);\n        }\n        else {\n          TwoArgOp_Avx(vmaxps);\n        }\n      }\n      else if (iter.op == opMin) {\n        if (processSingle) {\n          TwoArgOp_Single_Avx(vminps);\n        }\n        else {\n          TwoArgOp_Avx(vminps);\n        }\n      }\n      else if (iter.op == opSqrt) {\n        if (processSingle) {\n          auto &t1 = stack1.back();\n          vmaxps(t1, t1, zero);\n          vsqrtps(t1, t1);\n        }\n        else {\n          auto &t1 = stack.back();\n          vmaxps(t1.first, t1.first, zero);\n          vmaxps(t1.second, t1.second, zero);\n          vsqrtps(t1.first, t1.first);\n          vsqrtps(t1.second, t1.second);\n        }\n      }\n      else if (iter.op == opStore8) {\n        if (processSingle) {\n          auto t1 = stack1.back();\n          stack1.pop_back();\n          Reg a;\n          vaddps(t1, t1, CPTR_AVX(elfloat_half)); // rounder for truncate! no banker's rounding\n          vmaxps(t1, t1, zero);\n          vminps(t1, t1, CPTR_AVX(elstore8));\n          mov(a, ptr[regptrs]);\n          vcvttps2dq(t1, t1);   // float to int32 no bankers rounding\n          XmmReg r1x, r2x;\n          // 32 -> 16 bits from ymm 8 integers to xmm 8 words\n          // first\n          vextracti128(r1x, t1, 0);\n          vextracti128(r2x, t1, 1);\n          vpackusdw(r1x, r1x, r2x); // _mm_packus_epi32: w7 w6 w5 w4 w3 w2 w1 w0\n          // 16 -> 8 bits\n          vpackuswb(r1x, r1x, r1x); // _mm_packus_epi16: w3 w2 w1 w0 w3 w2 w1 w0\n          vmovq(mmword_ptr[a], r1x); // store 8 bytes\n        }\n        else {\n          auto t1 = stack.back();\n          stack.pop_back();\n          Reg a;\n          vaddps(t1.first, t1.first, CPTR_AVX(elfloat_half)); // rounder for truncate! no banker's rounding\n          vmaxps(t1.first, t1.first, zero);\n          vaddps(t1.second, t1.second, CPTR_AVX(elfloat_half)); // rounder for truncate! no banker's rounding\n          vmaxps(t1.second, t1.second, zero);\n          vminps(t1.first, t1.first, CPTR_AVX(elstore8));\n          vminps(t1.second, t1.second, CPTR_AVX(elstore8));\n          mov(a, ptr[regptrs]);\n          vcvttps2dq(t1.first, t1.first);   // float to int32 no bankers rounding\n          vcvttps2dq(t1.second, t1.second);\n          // we have 8 integers in t.first and another 8 in t.second\n          // second                           first\n          // d15 d14 d13 d12 d11 d10 d9 d8    d7 d6 d5 d4 d3 d2 d1 d0  // 16x32 bit integers in two ymm registers. not really 256 bits, but 2x128 bits\n          XmmReg r1x, r2x, r_lo_x;\n          // 32 -> 16 bits from ymm 8 integers to xmm 8 words\n          // first\n          vextracti128(r1x, t1.first, 0);\n          vextracti128(r2x, t1.first, 1);\n          vpackusdw(r_lo_x, r1x, r2x); // _mm_packus_epi32: w7 w6 w5 w4 w3 w2 w1 w0\n          // second\n          vextracti128(r1x, t1.second, 0); // not perfect, lower 128 bits of t1 could be used as xmm in packus. Cannot tell jitasm that xxmN is lower ymmN\n          vextracti128(r2x, t1.second, 1);\n          vpackusdw(r1x, r1x, r2x); //  _mm_packus_epi32: w7 w6 w5 w4 w3 w2 w1 w0\n          // 16 -> 8 bits\n          vpackuswb(r1x, r_lo_x, r1x); // _mm_packus_epi16: w3 w2 w1 w0 w3 w2 w1 w0\n          vmovdqa(xmmword_ptr[a], r1x); // store 16 bytes\n        }\n      }\n      else if (iter.op == opStore10 // avs+\n        || iter.op == opStore12 // avs+\n        || iter.op == opStore14 // avs+\n        || iter.op == opStore16\n        ) {\n        if (processSingle) {\n          auto t1 = stack1.back();\n          stack1.pop_back();\n          Reg a;\n          vaddps(t1, t1, CPTR_AVX(elfloat_half)); // rounder for truncate! no banker's rounding\n          vmaxps(t1, t1, zero);\n          switch (iter.op) {\n          case opStore10:\n            vminps(t1, t1, CPTR_AVX(elstore10));\n            break;\n          case opStore12:\n            vminps(t1, t1, CPTR_AVX(elstore12));\n            break;\n          case opStore14:\n            vminps(t1, t1, CPTR_AVX(elstore14));\n            break;\n          case opStore16:\n            vminps(t1, t1, CPTR_AVX(elstore16));\n            break;\n          }\n          mov(a, ptr[regptrs]);\n          vcvttps2dq(t1, t1);   // min / max clamp ensures that high words are zero\n          XmmReg r1x, r2x;\n          // 32 -> 16 bits from ymm 8 integers to xmm 8 words\n          vextracti128(r1x, t1, 0); // not perfect, lower 128 bits of t1 could be used as xmm in packus. Cannot tell jitasm that xxmN is lower ymmN\n          vextracti128(r2x, t1, 1);\n          vpackusdw(r1x, r1x, r2x); //  _mm_packus_epi32: w7 w6 w5 w4 w3 w2 w1 w0\n          vmovdqa(xmmword_ptr[a], r1x);\n        }\n        else {\n          auto t1 = stack.back();\n          stack.pop_back();\n          Reg a;\n          vaddps(t1.first, t1.first, CPTR_AVX(elfloat_half)); // rounder for truncate! no banker's rounding\n          vmaxps(t1.first, t1.first, zero);\n          vaddps(t1.second, t1.second, CPTR_AVX(elfloat_half)); // rounder for truncate! no banker's rounding\n          vmaxps(t1.second, t1.second, zero);\n          switch (iter.op) {\n          case opStore10:\n            vminps(t1.first, t1.first, CPTR_AVX(elstore10));\n            vminps(t1.second, t1.second, CPTR_AVX(elstore10));\n            break;\n          case opStore12:\n            vminps(t1.first, t1.first, CPTR_AVX(elstore12));\n            vminps(t1.second, t1.second, CPTR_AVX(elstore12));\n            break;\n          case opStore14:\n            vminps(t1.first, t1.first, CPTR_AVX(elstore14));\n            vminps(t1.second, t1.second, CPTR_AVX(elstore14));\n            break;\n          case opStore16:\n            vminps(t1.first, t1.first, CPTR_AVX(elstore16));\n            vminps(t1.second, t1.second, CPTR_AVX(elstore16));\n            break;\n          }\n          mov(a, ptr[regptrs]);\n          vcvttps2dq(t1.first, t1.first);   // min / max clamp ensures that high words are zero\n          vcvttps2dq(t1.second, t1.second);\n          // we have 8 integers in t.first and another 8 in t.second\n          // second                           first\n          // d15 d14 d13 d12 d11 d10 d9 d8    d7 d6 d5 d4 d3 d2 d1 d0  // 16x32 bit integers in two ymm registers. not really 256 bits, but 2x128 bits\n          XmmReg r1x, r2x;\n          // 32 -> 16 bits from ymm 8 integers to xmm 8 words\n          // first\n          vextracti128(r1x, t1.first, 0); // not perfect, lower 128 bits of t1 could be used as xmm in packus. Cannot tell jitasm that xxmN is lower ymmN\n          vextracti128(r2x, t1.first, 1);\n          vpackusdw(r1x, r1x, r2x); //  _mm_packus_epi32: w7 w6 w5 w4 w3 w2 w1 w0\n          vmovdqa(xmmword_ptr[a], r1x);\n          // second\n          vextracti128(r1x, t1.second, 0);\n          vextracti128(r2x, t1.second, 1);\n          vpackusdw(r1x, r1x, r2x); //  _mm_packus_epi32: w7 w6 w5 w4 w3 w2 w1 w0\n          vmovdqa(xmmword_ptr[a + 16], r1x);\n        }\n      }\n      else if (iter.op == opStoreF32) {\n        if (processSingle) {\n          auto t1 = stack1.back();\n          stack1.pop_back();\n          Reg a;\n          mov(a, ptr[regptrs]);\n          vmovaps(ymmword_ptr[a], t1);\n        } else {\n          auto t1 = stack.back();\n          stack.pop_back();\n          Reg a;\n          mov(a, ptr[regptrs]);\n          vmovaps(ymmword_ptr[a], t1.first);\n          vmovaps(ymmword_ptr[a + 32], t1.second); // this needs 64 byte aligned data to prevent overwrite!\n        }\n      }\n      else if (iter.op == opStoreF16) { // not supported in avs+\n        if (processSingle) {\n          auto t1 = stack1.back();\n          stack1.pop_back();\n          Reg a;\n          mov(a, ptr[regptrs]);\n          vcvtps2ph(xmmword_ptr[a], t1, 0);\n        } else {\n          auto t1 = stack.back();\n          stack.pop_back();\n          Reg a;\n          mov(a, ptr[regptrs]);\n          vcvtps2ph(xmmword_ptr[a], t1.first, 0);\n          vcvtps2ph(xmmword_ptr[a + 16], t1.second, 0);\n        }\n      }\n      else if (iter.op == opStoreVar || iter.op == opStoreVarAndDrop1) {\n        if (processSingle) {\n          auto t1 = stack1.back();\n          // 32 bytes/variable\n          int offset = sizeof(void *) * RWPTR_START_OF_USERVARIABLES + 32 * iter.e.ival;\n          vmovaps(ymmword_ptr[regptrs + offset], t1);\n          if (iter.op == opStoreVarAndDrop1)\n            stack1.pop_back();\n        }\n        else {\n          auto t1 = stack.back();\n          // 64 bytes/variable\n          int offset = sizeof(void *) * RWPTR_START_OF_USERVARIABLES + 64 * iter.e.ival;\n          vmovaps(ymmword_ptr[regptrs + offset], t1.first);\n          vmovaps(ymmword_ptr[regptrs + offset + 32], t1.second); // this needs 64 byte aligned data to prevent overwrite!\n          if (iter.op == opStoreVarAndDrop1)\n            stack.pop_back();\n        }\n      }\n      else if (iter.op == opAbs) {\n        if (processSingle) {\n          auto &t1 = stack1.back();\n          vandps(t1, t1, CPTR_AVX(elabsmask));\n        }\n        else {\n          auto &t1 = stack.back();\n          vandps(t1.first, t1.first, CPTR_AVX(elabsmask));\n          vandps(t1.second, t1.second, CPTR_AVX(elabsmask));\n        }\n      } \n      else if (iter.op == opSgn) {\n        // 1, 0, -1\n        if (processSingle) {\n          auto &t1 = stack1.back();\n          YmmReg r1, r2;\n          vxorps(r2, r2, r2);\n          vcmpps(r1, t1, r2, _CMP_GT_OQ);\n          vcmpps(t1, t1, r2, _CMP_LT_OQ);\n          vandps(r1, r1, CPTR_AVX(elfloat_one));\n          vandps(t1, t1, CPTR_AVX(elfloat_minusone));\n          vorps(t1, r1, t1);\n        }\n        else {\n          auto &t1 = stack.back();\n          YmmReg r2, r3, r4, r5;\n          vxorps(r2, r2, r2);\n          vcmpps(r3, t1.first, r2, _CMP_GT_OQ);\n          vcmpps(t1.first, t1.first, r2, _CMP_LT_OQ);\n          vcmpps(r4, t1.second, r2, _CMP_GT_OQ);\n          vcmpps(t1.second, t1.second, r2, _CMP_LT_OQ);\n          vmovaps(r2, CPTR_AVX(elfloat_one));\n          vandps(r3, r3, r2);\n          vmovaps(r5, CPTR_AVX(elfloat_minusone));\n          vblendvps(t1.first, r3, r5, t1.first);\n          vandps(r2, r4, r2);\n          vblendvps(t1.second, r2, r5, t1.second);\n        }\n      }\n      else if (iter.op == opNeg) {\n        if (processSingle) {\n          auto &t1 = stack1.back();\n          vcmpps(t1, t1, zero, _CMP_LE_OQ); // cmpleps\n          vandps(t1, t1, CPTR_AVX(elfloat_one));\n        }\n        else {\n          auto &t1 = stack.back();\n          vcmpps(t1.first, t1.first, zero, _CMP_LE_OQ); // cmpleps\n          vcmpps(t1.second, t1.second, zero, _CMP_LE_OQ);\n          vandps(t1.first, t1.first, CPTR_AVX(elfloat_one));\n          vandps(t1.second, t1.second, CPTR_AVX(elfloat_one));\n        }\n      }\n      else if (iter.op == opNegSign) {\n        if (processSingle) {\n          auto& t1 = stack1.back();\n          vxorps(t1, t1, CPTR_AVX(elsignmask));\n        }\n        else {\n          auto& t1 = stack.back();\n          vxorps(t1.first, t1.first, CPTR_AVX(elsignmask));\n          vxorps(t1.second, t1.second, CPTR_AVX(elsignmask));\n        }\n      }\n      else if (iter.op == opAnd) {\n        if (processSingle) {\n          LogicOp_Single_Avx(vandps);\n        }\n        else {\n          LogicOp_Avx(vandps);\n        }\n      }\n      else if (iter.op == opOr) {\n        if (processSingle) {\n          LogicOp_Single_Avx(vorps);\n        }\n        else {\n          LogicOp_Avx(vorps);\n        }\n      }\n      else if (iter.op == opXor) {\n        if (processSingle) {\n          LogicOp_Single_Avx(vxorps);\n        }\n        else {\n          LogicOp_Avx(vxorps);\n        }\n      }\n      else if (iter.op == opGt) { // a > b (gt) -> b < (lt) a\n        if (processSingle) {\n          CmpOp_Single_Avx(vcmpps, _CMP_LT_OQ); // cmpltps\n        }\n        else {\n          CmpOp_Avx(vcmpps, _CMP_LT_OQ) // cmpltps\n        }\n      }\n      else if (iter.op == opLt) { // a < b (lt) -> b > (gt,nle) a\n        if (processSingle) {\n          CmpOp_Single_Avx(vcmpps, _CMP_GT_OQ); // cmpnleps\n        }\n        else {\n          CmpOp_Avx(vcmpps, _CMP_GT_OQ); // cmpnleps\n        }\n      }\n      else if (iter.op == opEq) {\n        if (processSingle) {\n          CmpOp_Single_Avx(vcmpps, _CMP_EQ_OQ);\n        }\n        else {\n          CmpOp_Avx(vcmpps, _CMP_EQ_OQ);\n        }\n      }\n      else if (iter.op == opNotEq) { // avs+\n        if (processSingle) {\n          CmpOp_Single_Avx(vcmpps, _CMP_NEQ_OQ);\n        }\n        else {\n          CmpOp_Avx(vcmpps, _CMP_NEQ_OQ);\n        }\n      }\n      else if (iter.op == opLE) { // a <= b -> b >= (ge,nlt) a\n        if (processSingle) {\n          CmpOp_Single_Avx(vcmpps, _CMP_GE_OS); // cmpnltps\n        }\n        else {\n          CmpOp_Avx(vcmpps, _CMP_GE_OS) // cmpnltps\n        }\n      }\n      else if (iter.op == opGE) { // a >= b -> b <= (le) a\n        if (processSingle) {\n          CmpOp_Single_Avx(vcmpps, _CMP_LE_OS) // cmpleps\n        }\n        else {\n          CmpOp_Avx(vcmpps, _CMP_LE_OS) // cmpleps\n        }\n      }\n      else if (iter.op == opTernary) {\n        if (processSingle) {\n          auto t1 = stack1.back();\n          stack1.pop_back();\n          auto t2 = stack1.back();\n          stack1.pop_back();\n          auto t3 = stack1.back();\n          stack1.pop_back();\n          YmmReg r1;\n          vxorps(r1, r1, r1);\n          vcmpps(r1, r1, t3, _CMP_LT_OQ); // cmpltps -> vcmpps ... _CMP_LT_OQ\n          vandps(t2, t2, r1);\n          vandnps(r1, r1, t1);\n          vorps(r1, r1, t2);\n          stack1.push_back(r1);\n        }\n        else {\n          auto t1 = stack.back();\n          stack.pop_back();\n          auto t2 = stack.back();\n          stack.pop_back();\n          auto t3 = stack.back();\n          stack.pop_back();\n          YmmReg r1, r2;\n          vxorps(r1, r1, r1);\n          vxorps(r2, r2, r2);\n          vcmpps(r1, r1, t3.first, _CMP_LT_OQ); // cmpltps -> vcmpps ... _CMP_LT_OQ\n          vcmpps(r2, r2, t3.second, _CMP_LT_OQ);\n          vandps(t2.first, t2.first, r1);\n          vandps(t2.second, t2.second, r2);\n          vandnps(r1, r1, t1.first);\n          vandnps(r2, r2, t1.second);\n          vorps(r1, r1, t2.first);\n          vorps(r2, r2, t2.second);\n          stack.push_back(std::make_pair(r1, r2));\n        }\n      }\n      else if (iter.op == opExp) {\n        if (processSingle) {\n          auto &t1 = stack1.back();\n          EXP_PS_AVX(t1);\n        }\n        else {\n          auto &t1 = stack.back();\n          EXP_PS_AVX(t1.first);\n          EXP_PS_AVX(t1.second);\n        }\n      }\n      else if (iter.op == opLog) {\n        if (processSingle) {\n          auto &t1 = stack1.back();\n          LOG_PS_AVX(t1);\n        } else {\n          auto &t1 = stack.back();\n          LOG_PS_AVX(t1.first);\n          LOG_PS_AVX(t1.second);\n        }\n      }\n      else if (iter.op == opPow) {\n        if (processSingle) {\n          auto t1 = stack1.back();\n          stack1.pop_back();\n          auto &t2 = stack1.back();\n          LOG_PS_AVX(t2);\n          vmulps(t2, t2, t1);\n          EXP_PS_AVX(t2);\n        } else {\n          auto t1 = stack.back();\n          stack.pop_back();\n          auto &t2 = stack.back();\n          LOG_PS_AVX(t2.first);\n          vmulps(t2.first, t2.first, t1.first);\n          EXP_PS_AVX(t2.first);\n          LOG_PS_AVX(t2.second);\n          vmulps(t2.second, t2.second, t1.second);\n          EXP_PS_AVX(t2.second);\n        }\n      }\n      else if (iter.op == opSin) {\n        if (processSingle) {\n          auto& _t1 = stack1.back();\n          SINCOS_PS_AVX(true, _t1, _t1);\n        }\n        else {\n          auto& _t1 = stack.back();\n          SINCOS_PS_AVX(true, _t1.first, _t1.first);\n          SINCOS_PS_AVX(true, _t1.second, _t1.second);\n        }\n      }\n      else if (iter.op == opCos) {\n        if (processSingle) {\n          auto& _t1 = stack1.back();\n          SINCOS_PS_AVX(false, _t1, _t1);\n        }\n        else {\n          auto& _t1 = stack.back();\n          SINCOS_PS_AVX(false, _t1.first, _t1.first);\n          SINCOS_PS_AVX(false, _t1.second, _t1.second);\n        }\n      }\n      else if (iter.op == opTan) {\n        if (processSingle) {\n          auto& t1 = stack1.back();\n          TAN_PS_AVX(t1);\n        }\n        else {\n          auto& t1 = stack.back();\n          TAN_PS_AVX(t1.first);\n          TAN_PS_AVX(t1.second);\n        }\n      }\n      else if (iter.op == opAtan2) {\n        if (processSingle) {\n          auto t1 = stack1.back();\n          stack1.pop_back();\n          auto &t2 = stack1.back();\n          ATAN2_PS_AVX(t2, t1);\n        } else {\n          auto t1 = stack.back();\n          stack.pop_back();\n          auto &t2 = stack.back();\n          ATAN2_PS_AVX(t2.first, t1.first);\n          ATAN2_PS_AVX(t2.second, t1.second);\n        }\n      }\n      else if (iter.op == opClip) {\n        // clip(a, low, high) = min(max(a, low),high)\n        if (processSingle) {\n          auto t1 = stack1.back();\n          stack1.pop_back();\n          auto t2 = stack1.back();\n          stack1.pop_back();\n          auto &t3 = stack1.back();\n          vmaxps(t3, t3, t2);\n          vminps(t3, t3, t1);\n        }\n        else {\n          auto t1 = stack.back();\n          stack.pop_back();\n          auto t2 = stack.back();\n          stack.pop_back();\n          auto &t3 = stack.back();\n          vmaxps(t3.first, t3.first, t2.first);\n          vminps(t3.first, t3.first, t1.first);\n          vmaxps(t3.second, t3.second, t2.second);\n          vminps(t3.second, t3.second, t1.second);\n        }\n      }\n      else if (iter.op == opRound || iter.op == opFloor || iter.op == opCeil || iter.op == opTrunc) {\n        const int rounder_flag =\n          (iter.op == opRound) ? (FROUND_TO_NEAREST_INT | FROUND_NO_EXC) :\n          (iter.op == opFloor) ? (FROUND_TO_NEG_INF | FROUND_NO_EXC) :\n          (iter.op == opCeil) ? (FROUND_TO_POS_INF | FROUND_NO_EXC) :\n          (FROUND_TO_ZERO | FROUND_NO_EXC); // opTrunc\n        if (processSingle) {\n          auto& t1 = stack1.back();\n          vroundps(t1, t1, rounder_flag);\n        }\n        else {\n          auto& t1 = stack.back();\n          vroundps(t1.first, t1.first, rounder_flag);\n          vroundps(t1.second, t1.second, rounder_flag);\n        }\n      }\n    }\n  }\n/*\nIn brief:\njitasm was modded to accept avx_epilog_=true for code generation\n\nWhy: couldn't use vzeroupper because prolog/epilog was saving all xmm6:xmm15 registers even if they were not used at all\nWhy2: movaps was generated instead of vmovaps for prolog/epilog\nWhy3: internal register reordering/saving was non-vex encoded\nAll these issues resulted in AVX->SSE2 penalty\n\nFrom MSDN:\nXMM6:XMM15, YMM6:YMM15 rules for x64:\nNonvolatile (XMM), Volatile (upper half of YMM)\nXMM6:XMM15 Must be preserved as needed by callee.\nYMM registers must be preserved as needed by caller. (they do not need to be preserved)\n\nProblem:\n- Jitasm saves xmm6..xmm15 when vzeroupper is used,even if only an xmm0 is used (Why?)\nNo problem (looking at the disassembly list):\n- when there is no vzeroupper, then the xmm6:xmm11 is properly saved/restored in prolog/epilog but only\n  if ymm6:ymm11 (in this example) is used. If no register is used over xmm6/ymm6 then xmm registers are not saved at all.\n- question: does it have any penalty when movaps is used w/o vzeroupper?\n  The epilog generates movaps\n  movaps      xmm11,xmmword ptr [rbx-10h]\n\n0000000002430000  push        rbp\n0000000002430001  mov         rbp,rsp\n0000000002430004  push        rbx\n0000000002430005  lea         rbx,[rsp-8]\n000000000243000A  sub         rsp,0A8h\n0000000002430011  movaps      xmmword ptr [rbx-0A0h],xmm6\n0000000002430018  movaps      xmmword ptr [rbx-90h],xmm7\n000000000243001F  movaps      xmmword ptr [rbx-80h],xmm8\n0000000002430024  movaps      xmmword ptr [rbx-70h],xmm9\n0000000002430029  movaps      xmmword ptr [rbx-60h],xmm10\n000000000243002E  movaps      xmmword ptr [rbx-50h],xmm11\n0000000002430033  movaps      xmmword ptr [rbx-40h],xmm12\n0000000002430038  movaps      xmmword ptr [rbx-30h],xmm13\n000000000243003D  movaps      xmmword ptr [rbx-20h],xmm14\n0000000002430042  movaps      xmmword ptr [rbx-10h],xmm15\n-- end of jitasm generated prolog\n\n-- PF AVX+: passing avx_epilog_ = true for codegen, vmovaps is generated instead of movaps\n0000000001E60010  vmovaps     xmmword ptr [rbx-60h],xmm6\n0000000001E60015  vmovaps     xmmword ptr [rbx-50h],xmm7\n0000000001E6001A  vmovaps     xmmword ptr [rbx-40h],xmm8\n0000000001E6001F  vmovaps     xmmword ptr [rbx-30h],xmm9\n0000000001E60024  vmovaps     xmmword ptr [rbx-20h],xmm10\n0000000001E60029  vmovaps     xmmword ptr [rbx-10h],xmm11\n\n// PF comment: user's code like this:\n  YmmReg zero;\n  vpxor(zero, zero, zero);\n  Reg constptr;\n  mov(constptr, (uintptr_t)logexpconst_avx);\n  vzeroupper();\nAnd the generated instructions:\n0000000002430047  vpxor       ymm0,ymm0,ymm0\n000000000243004B  mov         rax,7FECCBD15C0h\n0000000002430055  vzeroupper\nNote: Don't use vzeroupper manually. When vzeroupper is issued manually, jitasm is not too generous: marks all xmm6:xmm15 registers as used\n      and epilog and prolog will save all of them, even if none of those xmm/ymm registers are used in the code.\n      Modded jitasm: pass avx_epilog_ = true for codegen, it will issue vzeroupper automatically (and has other benefits)\n\n-- start of jitasm generated epilog (old)\n0000000002430058  movaps      xmm15,xmmword ptr [rbx-10h]\n000000000243005D  movaps      xmm14,xmmword ptr [rbx-20h]\n0000000002430062  movaps      xmm13,xmmword ptr [rbx-30h]\n0000000002430067  movaps      xmm12,xmmword ptr [rbx-40h]\n000000000243006C  movaps      xmm11,xmmword ptr [rbx-50h]\n0000000002430071  movaps      xmm10,xmmword ptr [rbx-60h]\n0000000002430076  movaps      xmm9,xmmword ptr [rbx-70h]\n000000000243007B  movaps      xmm8,xmmword ptr [rbx-80h]\n0000000002430080  movaps      xmm7,xmmword ptr [rbx-90h]\n0000000002430087  movaps      xmm6,xmmword ptr [rbx-0A0h]\n000000000243008E  add         rsp,0A8h\n0000000002430095  pop         rbx\n0000000002430096  pop         rbp\n0000000002430097  ret\n-- end of jitasm generated epilog (old)\n\nPF: modded jitasm (calling codegen with avx_epilog_ = true) generates vmovaps instead of movaps and and automatic vzeroupper before the ret instruction\ngenerated epilog example (new):\n0000000001E70613  vmovaps     xmm11,xmmword ptr [rbx-10h]\n0000000001E70618  vmovaps     xmm10,xmmword ptr [rbx-20h]\n0000000001E7061D  vmovaps     xmm9,xmmword ptr [rbx-30h]\n0000000001E70622  vmovaps     xmm8,xmmword ptr [rbx-40h]\n0000000001E70627  vmovaps     xmm7,xmmword ptr [rbx-50h]\n0000000001E7062C  vmovaps     xmm6,xmmword ptr [rbx-60h]\n0000000001E70631  add         rsp,68h\n0000000001E70635  pop         rdi\n0000000001E70636  pop         rsi\n0000000001E70637  pop         rbx\n0000000001E70638  pop         rbp\n0000000001E70639  vzeroupper\n0000000001E7063C  ret\n\n*/\n  void main(Reg regptrs, Reg regoffs, Reg niter, Reg SpatialY)\n  {\n    YmmReg zero;\n    vpxor(zero, zero, zero);\n    Reg constptr;\n    mov(constptr, (uintptr_t)logexpconst_avx);\n\n    L(\"wloop\");\n    cmp(niter, 0); // while(niter>0)\n    je(\"wend\");\n    sub(niter, 1);\n\n    // process two sets, no partial input masking\n    if(singleMode)\n      processingLoop<true, false>(regptrs, zero, constptr, SpatialY);\n    else\n      processingLoop<false, false>(regptrs, zero, constptr, SpatialY);\n\n    // increase read and write pointers by 16 pixels\n    const int EXTRA = 2; // output pointer, xcounter\n    if constexpr(sizeof(void *) == 8) {\n      // x64: two 8 byte pointers in an xmm\n      int numIter = (numInputs + EXTRA + 1) / 2;\n\n      for (int i = 0; i < numIter; i++) {\n        XmmReg r1, r2;\n        vmovdqu(r1, xmmword_ptr[regptrs + 16 * i]);\n        vmovdqu(r2, xmmword_ptr[regoffs + 16 * i]);\n        vpaddq(r1, r1, r2); // pointers are 64 bits\n        vmovdqu(xmmword_ptr[regptrs + 16 * i], r1);\n      }\n    }\n    else {\n      // x86: four 4 byte pointers in an xmm\n      int numIter = (numInputs + EXTRA + 3) / 4;\n      for (int i = 0; i < numIter; i++) {\n        XmmReg r1, r2;\n        vmovdqu(r1, xmmword_ptr[regptrs + 16 * i]);\n        vmovdqu(r2, xmmword_ptr[regoffs + 16 * i]);\n        vpaddd(r1, r1, r2); // pointers are 32 bits\n        vmovdqu(xmmword_ptr[regptrs + 16 * i], r1);\n      }\n    }\n\n    jmp(\"wloop\");\n    L(\"wend\");\n\n    int nrestpixels = planewidth & (singleMode ? 7 : 15);\n    if(nrestpixels > 8) // dual process with masking\n      processingLoop<false, true>(regptrs, zero, constptr, SpatialY);\n    else if (nrestpixels == 8) // single process, no masking\n      processingLoop<true, false>(regptrs, zero, constptr, SpatialY);\n    else if (nrestpixels > 0) // single process, masking\n      processingLoop<true, true>(regptrs, zero, constptr, SpatialY);\n    // bug in jitasm?\n    // on x64, when this is here, debug throws an assert, that a register save/load has an\n    // operand size 8 bit, instead of 128 (XMM) or 256 (YMM)\n    // vzeroupper(); // don't use it directly. Generate code with avx_epilog_=true\n  }\n};\n\n#endif\n\n\n/********************************************************************\n***** Declare index of new filters for Avisynth's filter engine *****\n********************************************************************/\n\nextern const AVSFunction Exprfilter_filters[] = {\n  { \"Expr\", BUILTIN_FUNC_PREFIX, \"c+s+[format]s[optAvx2]b[optSingleMode]b[optSSE2]b[scale_inputs]s[clamp_float]b[clamp_float_UV]b[lut]i[optVectorC]b\", Exprfilter::Create },\n  { 0 }\n};\n\n\nAVSValue __cdecl Exprfilter::Create(AVSValue args, void* , IScriptEnvironment* env) {\n\n  std::vector<PClip> children;\n  std::vector<std::string> expressions;\n  int next_paramindex;\n\n  // one or more clips\n  if (args[0].IsArray() && args[0][0].IsClip()) { // c+s+ case\n    children.resize(args[0].ArraySize());\n\n    for (int i = 0; i < (int)children.size(); ++i) // Copy all\n      children[i] = args[0][i].AsClip();\n\n    next_paramindex = 1;\n  }\n  else if (args[1].IsArray() && args[1][0].IsClip()) { // cc+s+ case\n    children.resize(1 + args[1].ArraySize());\n\n    children[0] = args[0].AsClip(); // Copy 1st\n    for (int i = 1; i < (int)children.size(); ++i) // Copy rest\n      children[i] = args[1][i - 1].AsClip();\n\n    next_paramindex = 2;\n  }\n  else if (args[1].IsClip()) { //cc case\n    children.resize(2);\n\n    children[0] = args[0].AsClip();\n    children[1] = args[1].AsClip();\n\n    next_paramindex = 2;\n  }\n  else if (args[0].IsClip()) { // single clip, cs+ case\n    children.resize(1);\n    children[0] = args[0].AsClip();\n\n    next_paramindex = 1;\n  }\n  else {\n    env->ThrowError(\"Expr: Invalid parameter type\");\n  }\n\n  // one or more expressions: s+\n  if (args[next_paramindex].Defined()) {\n    AVSValue exprarg = args[next_paramindex++];\n    if (exprarg.IsArray()) {\n      int nexpr = exprarg.ArraySize();\n      expressions.resize(nexpr);\n      for (int i = 0; i < nexpr; i++)\n        expressions[i] = exprarg[i].AsString();\n    }\n    else if (exprarg.IsString()) {\n      expressions.resize(1);\n      expressions[0] = exprarg.AsString();\n    }\n    else {\n      env->ThrowError(\"Expr: Invalid parameter type for expression string\");\n    }\n  }\n\n  // optional named argument: format\n  const char *newformat = nullptr;\n  if (args[next_paramindex].Defined()) {\n    // always string\n    newformat = args[next_paramindex].AsString();\n  }\n  next_paramindex++;\n\n#ifdef VS_TARGET_CPU_X86\n  // test parameter for avx2-less mode even with avx2 available\n#ifdef TEST_AVX2_CODEGEN_IN_AVX\n  bool optAvx2 = !!(env->GetCPUFlags() & CPUF_AVX);\n#else\n  bool optAvx2 = !!(env->GetCPUFlags() & CPUF_AVX2);\n#endif\n  bool optSSE2 = !!(env->GetCPUFlags() & CPUF_SSE2);\n#else\n  bool optAvx2 = false;\n  bool optSSE2 = false;\n#endif\n\n  if (args[next_paramindex].Defined()) {\n    if (optAvx2) // disable only\n      optAvx2 = args[next_paramindex].AsBool();\n  }\n  next_paramindex++;\n\n  bool optSingleMode = false;\n  if (args[next_paramindex].Defined()) {\n    optSingleMode = args[next_paramindex].AsBool();\n  }\n  next_paramindex++;\n\n  if (args[next_paramindex].Defined()) {\n    if (optSSE2) // disable only\n      optSSE2 = args[next_paramindex].AsBool();\n  }\n  next_paramindex++;\n\n  std::string scale_inputs = args[next_paramindex].Defined() ? args[next_paramindex].AsString(\"none\") : \"none\";\n  transform(scale_inputs.begin(), scale_inputs.end(), scale_inputs.begin(), ::tolower);\n  next_paramindex++;\n\n  const bool clamp_float = args[next_paramindex].AsBool(false);\n  next_paramindex++;\n\n  const bool clamp_float_UV = args[next_paramindex].AsBool(false);\n  next_paramindex++;\n\n  // clamp_float clamp_float_uv -> clamp_float_i   clamp range for Y clamp range for UV\n  // false       x                 0               0..1              -0.5..+0.5\n  // true        false             1               0..1              -0.5..+0.5\n  // true        true              2               0..1              0..1\n\n  int clamp_float_i;\n  if (clamp_float)\n    clamp_float_i = clamp_float_UV ? 2 : 1;\n  else\n    clamp_float_i = 0;\n\n  const int lutmode = args[next_paramindex].AsInt(0); // 0, 1, 2\n  next_paramindex++;\n\n  const bool optVectorC = args[next_paramindex].AsBool(true);\n\n  return new Exprfilter(children, expressions, newformat, optAvx2, optSingleMode, optSSE2, optVectorC, scale_inputs, clamp_float_i, lutmode, env);\n\n}\n\n// Base SIMD Processor interface\nclass ISIMDProcessor {\npublic:\n  virtual void processVector(\n    std::vector<const uint8_t*>&srcp,\n    uint8_t*& dstp,\n    int x, int y) = 0;\n  virtual ~ISIMDProcessor() = default;\n};\n\n/**\n * Custom aligned memory allocator for STL containers like std::vector\n *\n * This allocator ensures that the underlying data pointer returned by container.data()\n * is aligned to the specified alignment boundary, which is critical for:\n *   - SIMD vector operations that require aligned memory access\n *   - Cache-friendly data structures\n *   - Hardware-specific memory alignment requirements\n *\n * Platform-specific implementation:\n *   - Windows (MSVC, ClangCL): Uses _aligned_malloc/_aligned_free\n *   - MinGW: Uses _aligned_malloc/_aligned_free\n *   - POSIX systems (Linux, Unix, macOS): Uses aligned_alloc/free\n *   - C++17 fallback: Uses std::aligned_alloc/free\n *\n * Usage:\n *   std::vector<float, aligned_allocator<float, 32>> aligned_vector;\n */\ntemplate <typename T, size_t Alignment>\nstruct aligned_allocator {\n  // Standard allocator typedefs\n  typedef T value_type;\n  typedef T* pointer;\n  typedef const T* const_pointer;\n  typedef T& reference;\n  typedef const T& const_reference;\n  typedef std::size_t size_type;\n  typedef std::ptrdiff_t difference_type;\n  // Rebind allocator to type U\n  template <typename U>\n  struct rebind {\n    typedef aligned_allocator<U, Alignment> other;\n  };\n  aligned_allocator() noexcept {}\n  template <typename U>\n  aligned_allocator(const aligned_allocator<U, Alignment>&) noexcept {}\n  T* allocate(std::size_t n) {\n#if defined(_MSC_VER) || (defined(__clang__) && defined(_MSC_VER))\n    // Both MSVC and ClangCL should use _aligned_malloc\n    void* ptr = _aligned_malloc(n * sizeof(T), Alignment);\n    if (!ptr) throw std::bad_alloc();\n#elif defined(__MINGW32__) || defined(__MINGW64__)\n    // MinGW/MinGW-w64 specific\n    void* ptr = _aligned_malloc(n * sizeof(T), Alignment);\n    if (!ptr) throw std::bad_alloc();\n#elif defined(__INTEL_COMPILER) || defined(__INTEL_LLVM_COMPILER) || defined(__APPLE__) || (defined(__GNUC__) && !defined(_WIN32) && !defined(__CYGWIN__))\n    // POSIX-compliant systems: Intel compilers, macOS, GCC on non-Windows\n    // aligned_alloc requires size to be a multiple of alignment\n    size_t size = n * sizeof(T);\n    if (size % Alignment != 0) {\n      size = (size / Alignment + 1) * Alignment;\n    }\n    void* ptr = aligned_alloc(Alignment, size);\n    if (!ptr) throw std::bad_alloc();\n#else\n    // Generic fallback for C++17 and later\n    // std::aligned_alloc requires size to be a multiple of alignment\n    size_t size = n * sizeof(T);\n    if (size % Alignment != 0) {\n      size = (size / Alignment + 1) * Alignment;\n    }\n    void* ptr = std::aligned_alloc(Alignment, size);\n    if (!ptr) throw std::bad_alloc();\n#endif\n    return static_cast<T*>(ptr);\n  }\n  void deallocate(T* p, std::size_t) noexcept {\n#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__) || (defined(__clang__) && defined(_MSC_VER))\n    _aligned_free(p);\n#else\n    free(p);\n#endif\n  }\n};\n\n// convenient type def\nusing aligned_float_vector = std::vector<float, aligned_allocator<float, 32>>;\n\ntemplate<int VectorSize>\nclass SIMDProcessor : public ISIMDProcessor {\n  int w, h;\n  size_t maxStackSize;\n\n  // Define the aligned stack with custom allocator\n  std::vector<aligned_float_vector> stack;\n\n  aligned_float_vector& variable_area;\n  std::vector<float>& internal_vars;\n  std::vector<int>& src_stride;\n  std::vector<const uint8_t*>& srcp_orig;\n  const ExprOp* vops;\npublic:\n  SIMDProcessor(int _w, int _h, size_t _maxStackSize, \n    aligned_float_vector& var_area,\n    std::vector<float>& int_vars, std::vector<int>& src_str, std::vector<const uint8_t*>& src_orig, const ExprOp* vops)\n    : w(_w), h(_h), maxStackSize(_maxStackSize), \n    stack(_maxStackSize, aligned_float_vector(VectorSize)), \n    variable_area(var_area), internal_vars(int_vars), src_stride(src_str), srcp_orig(src_orig), vops(vops) {\n  }\n\n  int stackIndex = 0;\n  alignas(32) float stacktop[VectorSize] = {};\n\n  // Broadcast a single value across the vector\n  inline void push_and_broadcast(float val) {\n    auto& current_stack = stack[stackIndex];\n\n    // First loop: copy stacktop to stack - help vectorization pattern\n    for (int i = 0; i < VectorSize; ++i)\n      current_stack[i] = stacktop[i];\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = val;\n    stackIndex++;\n  }\n\n  inline void broadcast(float val) {\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = val;\n  }\n\n  // Load spatial X coordinate\n  inline void loadSpatialX(int x) {\n    // Push current stacktop and fills x, x+1, x+2, x+3, ...\n    auto& current_stack = stack[stackIndex];\n    for (int i = 0; i < VectorSize; ++i)\n      current_stack[i] = stacktop[i];\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = static_cast<float>(x + i);\n    stackIndex++;\n  }\n\n  // Load vector from source from x\n  template<typename T>\n  inline void loadSource(const T* src, int x) {\n    auto& current_stack = stack[stackIndex];\n    for (int i = 0; i < VectorSize; ++i)\n      current_stack[i] = stacktop[i];\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = static_cast<float>(src[x + i]);\n    stackIndex++;\n  }\n\n  // Load from source with relative offset\n  template<typename T>\n  void loadRelSource(const T* src, int x, int dx, int dy, int width, int height, int stride) {\n    auto& current_stack = stack[stackIndex];\n    for (int i = 0; i < VectorSize; ++i)\n      current_stack[i] = stacktop[i];\n    // At edges: repeat, no mirror\n    int newY = std::max(0, std::min(dy, height - 1));\n    for (int i = 0; i < VectorSize; ++i) {\n      int newX = std::max(0, std::min(x + dx + i, width - 1));\n      stacktop[i] = static_cast<float>(reinterpret_cast<const T*>((uint8_t*)&src[newY * stride])[newX]);\n    }\n    stackIndex++;\n  }\n\n  // Load from user variable area\n  inline void loadVar(int index) {\n    auto& current_stack = stack[stackIndex];\n    for (int i = 0; i < VectorSize; ++i)\n      current_stack[i] = stacktop[i];\n    // Push current stacktop and broadcast x\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = variable_area[index * MAX_C_VECT + i];\n    stackIndex++;\n  }\n\n  // Vectorized duplicate\n  inline void dup(int offset) {\n    auto& current_stack = stack[stackIndex];\n    for (int i = 0; i < VectorSize; ++i)\n      current_stack[i] = stacktop[i];\n    auto& prev = stack[stackIndex - offset];\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = prev[i];\n    stackIndex++;\n  }\n\n  // Vectorized swap\n  inline void swap(int offset) {\n    auto& prev = stack[stackIndex - offset];\n    for (int i = 0; i < VectorSize; ++i)\n      std::swap(stacktop[i], prev[i]);\n  }\n\n  // Vectorized addition\n  inline void add() {\n    stackIndex--;\n    auto& prev = stack[stackIndex];\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] += prev[i];\n  }\n\n  // Vectorized subtract\n  inline void sub() {\n    stackIndex--;\n    auto& prev = stack[stackIndex];\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = prev[i] - stacktop[i];\n  }\n\n  // Vectorized multiplication\n  inline void multiply() {\n    stackIndex--;\n    auto& prev = stack[stackIndex];\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] *= prev[i];\n  }\n\n  inline void divide() {\n    stackIndex--;\n    auto& prev = stack[stackIndex];\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = prev[i] / stacktop[i];\n  }\n\n  void fmod() {\n    stackIndex--;\n    auto& prev = stack[stackIndex];\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = std::fmod(prev[i], stacktop[i]);\n  }\n\n  inline void max() {\n    stackIndex--;\n    auto& prev = stack[stackIndex];\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = std::max(prev[i], stacktop[i]);\n  }\n\n  inline void min() {\n    stackIndex--;\n    auto& prev = stack[stackIndex];\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = std::min(prev[i], stacktop[i]);\n  }\n\n  void exp() {\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = std::exp(stacktop[i]);\n  }\n\n  void log() {\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = std::log(stacktop[i]);\n  }\n\n  void pow() {\n    stackIndex--;\n    auto& prev = stack[stackIndex];\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = std::pow(prev[i], stacktop[i]);\n  }\n\n  // Vectorized clip\n  inline void clip() {\n    stackIndex -= 2;\n    auto& prev = stack[stackIndex];\n    auto& prev1 = stack[stackIndex + 1];\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = std::max(std::min(prev[i], stacktop[i]), prev1[i]);\n  }\n\n  // Vectorized round\n  inline void round() {\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = std::round(stacktop[i]);\n  }\n\n  // Vectorized floor\n  inline void floor() {\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = std::floor(stacktop[i]);\n  }\n\n  // Vectorized ceil\n  void ceil() {\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = std::ceil(stacktop[i]);\n  }\n\n  // Vectorized trunc\n  inline void trunc() {\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = std::trunc(stacktop[i]);\n  }\n\n  // Vectorized sqrt\n  void sqrt() {\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = std::sqrt(stacktop[i]);\n  }\n\n  // Vectorized abs\n  inline void abs() {\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = std::abs(stacktop[i]);\n  }\n\n  // Vectorized sgn\n  inline void sgn() {\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = stacktop[i] < 0 ? -1.0f : stacktop[i] > 0 ? 1.0f : 0.0f;\n  }\n\n  // Vectorized sin\n  void sin() {\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = std::sin(stacktop[i]);\n  }\n\n  // Vectorized cos\n  void cos() {\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = std::cos(stacktop[i]);\n  }\n\n  // Vectorized tan\n  void tan() {\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = std::tan(stacktop[i]);\n    // reference of JITAsm code test: fast_tanf(stacktop[i]); \n  }\n\n  // Vectorized asin\n  void asin() {\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = std::asin(stacktop[i]);\n  }\n\n  // Vectorized acos\n  void acos() {\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = std::acos(stacktop[i]);\n  }\n\n  // Vectorized atan\n  void atan() {\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = std::atan(stacktop[i]);\n  }\n\n  // Vectorized atan2\n  void atan2() {\n    stackIndex--;\n    auto& prev = stack[stackIndex];\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = std::atan2(prev[i], stacktop[i]); // y, x -> -Pi..+Pi\n  }\n\n  // Vectorized greater than\n  inline void gt() {\n    stackIndex--;\n    auto& prev = stack[stackIndex];\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = (prev[i] > stacktop[i]) ? 1.0f : 0.0f;\n  }\n\n  // Vectorized less than\n  inline void lt() {\n    stackIndex--;\n    auto& prev = stack[stackIndex];\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = (prev[i] < stacktop[i]) ? 1.0f : 0.0f;\n  }\n\n  // Vectorized equal\n  inline void eq() {\n    stackIndex--;\n    auto& prev = stack[stackIndex];\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = (prev[i] == stacktop[i]) ? 1.0f : 0.0f; // consider with not 100% match, use epsilon\n  }\n\n  // Vectorized not equal\n  inline void notEq() {\n    stackIndex--;\n    auto& prev = stack[stackIndex];\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = (prev[i] != stacktop[i]) ? 1.0f : 0.0f; // consider with not 100% match, use epsilon\n  }\n\n  // Vectorized less than or equal\n  inline void le() {\n    stackIndex--;\n    auto& prev = stack[stackIndex];\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = (prev[i] <= stacktop[i]) ? 1.0f : 0.0f;\n  }\n\n  // Vectorized greater than or equal\n  inline void ge() {\n    stackIndex--;\n    auto& prev = stack[stackIndex];\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = (prev[i] >= stacktop[i]) ? 1.0f : 0.0f;\n  }\n\n  // Vectorized ternary\n  inline void ternary() {\n    stackIndex -= 2;\n    auto& prev = stack[stackIndex];\n    auto& prev1 = stack[stackIndex + 1];\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = (prev[i] > 0) ? prev1[i] : stacktop[i];\n  }\n\n  // Vectorized logical AND\n  inline void logicalAnd() {\n    stackIndex--;\n    auto& prev = stack[stackIndex];\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = (stacktop[i] > 0 && prev[i] > 0) ? 1.0f : 0.0f;\n  }\n\n  // Vectorized logical OR\n  inline void logicalOr() {\n    stackIndex--;\n    auto& prev = stack[stackIndex];\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = (stacktop[i] > 0 || prev[i] > 0) ? 1.0f : 0.0f;\n  }\n\n  // Vectorized logical XOR\n  inline  void logicalXor() {\n    stackIndex--;\n    auto& prev = stack[stackIndex];\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = ((stacktop[i] > 0) != (prev[i] > 0)) ? 1.0f : 0.0f;\n  }\n\n  // Vectorized logical NOT\n  inline void logicalNot() {\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = (stacktop[i] > 0) ? 0.0f : 1.0f;\n  }\n\n  // Vectorized negation\n  inline void negSign() {\n    for (int i = 0; i < VectorSize; ++i)\n      stacktop[i] = -stacktop[i];\n  }\n\n  // Templatized store function\n  template<typename T, int MaxValue>\n  inline void store(T* dst, int x) {\n    for (int i = 0; i < VectorSize; ++i)\n      dst[x + i] = static_cast<T>(std::max(0.0f, std::min(stacktop[i], static_cast<float>(MaxValue))) + 0.5f);\n  }\n\n  // Specialized store function for float\n  inline void store(float* dst, int x) {\n    for (int i = 0; i < VectorSize; ++i)\n      dst[x + i] = stacktop[i];\n  }\n\n  // Store variable\n  inline void storeVar(int index) {\n    for (int i = 0; i < VectorSize; ++i)\n      variable_area[index * MAX_C_VECT + i] = stacktop[i];\n  }\n\n  // Store variable and drop one element from the stack\n  inline void storeVarAndDrop1(int index) {\n    for (int i = 0; i < VectorSize; ++i)\n      variable_area[index * MAX_C_VECT + i] = stacktop[i];\n    stackIndex--;\n    if (stackIndex >= 0) {\n      auto& prev = stack[stackIndex];\n      for (int i = 0; i < VectorSize; ++i)\n        stacktop[i] = prev[i];\n    }\n  }\n\n  // Process a sequence of operations\n  void processVector(std::vector<const uint8_t*>& srcp, uint8_t*& dstp, int x, int y) override {\n\n    // Reset stack\n    stackIndex = 0;\n    broadcast(0); // stacktop = 0\n\n    const ExprOp* vops_current = vops; // reset instruction pointer\n\n    while (true) {\n      // Process instruction sequence\n      switch (vops_current->op) {\n      case opLoadSrc8:\n        loadSource<uint8_t>(reinterpret_cast<const uint8_t*>(srcp[vops_current->e.ival]), x);\n        break;\n      case opLoadSrc16:\n        loadSource<uint16_t>(reinterpret_cast<const uint16_t*>(srcp[vops_current->e.ival]), x);\n        break;\n      case opLoadSrcF32:\n        loadSource<float>(reinterpret_cast<const float*>(srcp[vops_current->e.ival]), x);\n        break;\n      case opLoadRelSrc8:\n        loadRelSource<uint8_t>(reinterpret_cast<const uint8_t*>(srcp[vops_current->e.ival]), x, vops_current->dx, vops_current->dy, w, h, src_stride[vops_current->e.ival]);\n        break;\n      case opLoadRelSrc16:\n        loadRelSource<uint16_t>(reinterpret_cast<const uint16_t*>(srcp[vops_current->e.ival]), x, vops_current->dx, vops_current->dy, w, h, src_stride[vops_current->e.ival]);\n        break;\n      case opLoadRelSrcF32:\n        loadRelSource<float>(reinterpret_cast<const float*>(srcp[vops_current->e.ival]), x, vops_current->dx, vops_current->dy, w, h, src_stride[vops_current->e.ival]);\n        break;\n      case opLoadConst:\n        push_and_broadcast(vops_current->e.fval);\n        break;\n      case opLoadSpatialX:\n        loadSpatialX(x);\n        break;\n      case opLoadSpatialY:\n        push_and_broadcast(static_cast<float>(y));\n        break;\n      case opLoadInternalVar:\n        push_and_broadcast(internal_vars[vops_current->e.ival]);\n        break;\n      case opStore8:\n        store<uint8_t, 255>(reinterpret_cast<uint8_t*>(dstp), x);\n        goto loopend;\n      case opStore10:\n        store<uint16_t, 1023>(reinterpret_cast<uint16_t*>(dstp), x);\n        goto loopend;\n      case opStore12:\n        store<uint16_t, 4095>(reinterpret_cast<uint16_t*>(dstp), x);\n        goto loopend;\n      case opStore14:\n        store<uint16_t, 16383>(reinterpret_cast<uint16_t*>(dstp), x);\n        goto loopend;\n      case opStore16:\n        store<uint16_t, 65535>(reinterpret_cast<uint16_t*>(dstp), x);\n        goto loopend;\n      case opStoreF32:\n        store(reinterpret_cast<float*>(dstp), x);\n        goto loopend;\n\n      case opDup: dup(vops_current->e.ival); break;\n      case opSwap: swap(vops_current->e.ival); break;\n      case opAdd: add(); break;\n      case opSub: sub(); break;\n      case opMul: multiply(); break;\n      case opDiv: divide(); break;\n      case opMax: max(); break;\n      case opMin: min(); break;\n      case opSqrt: sqrt(); break;\n      case opAbs: abs(); break;\n      case opSgn: sgn(); break;\n      case opFmod: fmod(); break;\n      case opGt: gt(); break;\n      case opLt: lt(); break;\n      case opEq: eq(); break;\n      case opNotEq: notEq(); break;\n      case opLE: le(); break;\n      case opGE: ge(); break;\n      case opTernary: ternary(); break;\n      case opAnd: logicalAnd(); break;\n      case opOr: logicalOr(); break;\n      case opXor: logicalXor(); break;\n      case opNeg: logicalNot(); break;\n      case opNegSign: negSign(); break;\n      case opExp: exp(); break;\n      case opLog: log(); break;\n      case opPow: pow(); break;\n      case opSin: sin(); break;\n      case opCos: cos(); break;\n      case opTan: tan(); break;\n      case opAsin: asin(); break;\n      case opAcos: acos(); break;\n      case opAtan: atan(); break;\n      case opAtan2: atan2(); break;\n      case opClip: clip(); break;\n      case opRound: round(); break;\n      case opFloor: floor(); break;\n      case opCeil: ceil(); break;\n      case opTrunc: trunc(); break;\n\n      case opStoreVar:\n        storeVar(vops_current->e.ival);\n        break;\n      case opLoadVar:\n        loadVar(vops_current->e.ival);\n        break;\n      case opLoadFramePropVar:\n        push_and_broadcast(internal_vars[INTERNAL_VAR_FRAMEPROP_VARIABLES_START + vops_current->e.ival]);\n        break;\n      case opStoreVarAndDrop1:\n        storeVarAndDrop1(vops_current->e.ival);\n        break;\n      }\n      vops_current++; // next opcode\n    }\n  // store makes the sequence end, wherever it was\n  loopend:;\n  }\n};\n\n\n// Factory to create appropriate SIMD processors\nclass SIMDProcessorFactory {\npublic:\n  template<int MaxVectorSize>\n  static std::unique_ptr<ISIMDProcessor> createProcessor(\n    int w, int h, size_t maxStackSize, \n    aligned_float_vector& var_area,\n    std::vector<float>& int_vars, std::vector<int>& src_str, std::vector<const uint8_t*>& src_orig, const ExprOp* vops) {\n    if constexpr (MaxVectorSize >= 16) {\n      return std::make_unique<SIMDProcessor<16>>(w, h, maxStackSize, var_area, int_vars, src_str, src_orig, vops);\n    }\n    if constexpr (MaxVectorSize >= 8) {\n      return std::make_unique<SIMDProcessor<8>>(w, h, maxStackSize, var_area, int_vars, src_str, src_orig, vops);\n    }\n    else if constexpr (MaxVectorSize >= 4) {\n      return std::make_unique<SIMDProcessor<4>>(w, h, maxStackSize, var_area, int_vars, src_str, src_orig, vops);\n    }\n    else {\n      return std::make_unique<SIMDProcessor<1>>(w, h, maxStackSize, var_area, int_vars, src_str, src_orig, vops);\n    }\n  }\n};\n\n\ntemplate<int MaxVectorSize>\nvoid processFrameWithDynamicVectors(int plane, int w, int h, int pixels_per_iter, float framecount, float relative_time, int numInputs,\n  uint8_t* &dstp, int dst_stride,\n  std::vector<const uint8_t*>& srcp, std::vector<int>& src_stride, std::vector<intptr_t>& ptroffsets, std::vector<const uint8_t*>& srcp_orig, ExprData& d) {\n\n  const ExprOp* vops = d.ops[plane].data();\n  aligned_float_vector variable_area(MAX_USER_VARIABLES * MAX_C_VECT); // for C, place for expr variables (each is a vector)\n\n  std::vector<float> internal_vars(INTERNAL_VARIABLES + MAX_FRAMEPROP_VARIABLES);\n  // frame dependent internal variables\n  internal_vars[INTERNAL_VAR_CURRENT_FRAME] = (float)framecount;\n  internal_vars[INTERNAL_VAR_RELTIME] = (float)relative_time;\n  // followed by dynamic frame properties\n  for (auto& framePropToRead : d.frameprops[plane]) {\n    int whereToPut = framePropToRead.var_index;\n    internal_vars[INTERNAL_VAR_FRAMEPROP_VARIABLES_START + whereToPut] = framePropToRead.value;\n  };\n\n  // Create processors dynamically based on MaxVectorSize\n  std::unique_ptr<ISIMDProcessor> processor16 = MaxVectorSize >= 16 ?\n    SIMDProcessorFactory::createProcessor<16>(w, h, d.maxStackSize, variable_area, internal_vars, src_stride, srcp_orig, vops) : nullptr;\n  std::unique_ptr<ISIMDProcessor> processor8 = MaxVectorSize >= 8 ?\n    SIMDProcessorFactory::createProcessor<8>(w, h, d.maxStackSize, variable_area, internal_vars, src_stride, srcp_orig, vops) : nullptr;\n  std::unique_ptr<ISIMDProcessor> processor4 = MaxVectorSize >= 4 ?\n    SIMDProcessorFactory::createProcessor<4>(w, h, d.maxStackSize, variable_area, internal_vars, src_stride, srcp_orig, vops) : nullptr;\n  std::unique_ptr<ISIMDProcessor> processor1 = SIMDProcessorFactory::createProcessor<1>(w, h, d.maxStackSize, variable_area, internal_vars, src_stride, srcp_orig, vops);\n\n  for (int y = 0; y < h; y++) {\n    int x = 0;\n\n    // Conditionally process larger vector sizes\n    if (MaxVectorSize >= 16 && processor16) {\n      for (; x + 16 <= w; x += 16) {\n        processor16->processVector(srcp, dstp, x, y);\n      }\n    }\n\n    if (MaxVectorSize >= 8 && processor8) {\n      for (; x + 8 <= w; x += 8) {\n        processor8->processVector(srcp, dstp, x, y);\n      }\n    }\n\n    if (MaxVectorSize >= 4 && processor4) {\n      for (; x + 4 <= w; x += 4) {\n        processor4->processVector(srcp, dstp, x, y);\n      }\n    }\n\n    // Always process remaining pixels\n    for (; x < w; x++) {\n      processor1->processVector(srcp, dstp, x, y);\n    }\n\n    // Update destination and source pointers for next row\n    dstp += dst_stride;\n    if (d.lutmode == 0) {\n      for (int i = 0; i < numInputs; i++)\n        srcp[i] += src_stride[i];\n    }\n  }\n}\n\nvoid Exprfilter::processFrame(int plane, int w, int h, int pixels_per_iter, float framecount, float relative_time, int numInputs, \n  uint8_t*& dstp, int dst_stride,\n  std::vector<const uint8_t*>& srcp, std::vector<int>& src_stride, std::vector<intptr_t>& ptroffsets, std::vector<const uint8_t*>& srcp_orig)\n{\n#ifdef VS_TARGET_CPU_X86\n  if (optSSE2 && d.planeOptSSE2[plane]) {\n\n    int nfulliterations = w / pixels_per_iter;\n\n    ExprData::ProcessLineProc proc = d.proc[plane];\n\n    alignas(32) intptr_t rwptrs[RWPTR_SIZE]; // should work, gcc 8.3 gives false warning\n    \n    *reinterpret_cast<float*>(&rwptrs[RWPTR_START_OF_INTERNAL_VARIABLES + INTERNAL_VAR_CURRENT_FRAME]) = (float)framecount;\n    *reinterpret_cast<float*>(&rwptrs[RWPTR_START_OF_INTERNAL_VARIABLES + INTERNAL_VAR_RELTIME]) = (float)relative_time;\n    // refresh frame properties\n    for (auto& framePropToRead : d.frameprops[plane]) {\n      int whereToPut = framePropToRead.var_index;\n      *reinterpret_cast<float*>(&rwptrs[RWPTR_START_OF_INTERNAL_FRAMEPROP_VARIABLES + whereToPut]) = framePropToRead.value;\n    };\n    for (int y = 0; y < h; y++) {\n      rwptrs[RWPTR_START_OF_OUTPUT] = reinterpret_cast<intptr_t>(dstp + dst_stride * y);\n      rwptrs[RWPTR_START_OF_XCOUNTER] = 0; // xcounter internal variable\n      for (int i = 0; i < numInputs; i++) {\n        rwptrs[i + RWPTR_START_OF_INPUTS] = reinterpret_cast<intptr_t>(srcp[i] + src_stride[i] * y); // input pointers 1..Nth\n        rwptrs[i + RWPTR_START_OF_STRIDES] = static_cast<intptr_t>(src_stride[i]);\n      }\n      // a single line at a time\n      proc(rwptrs, ptroffsets.data(), nfulliterations, y); // parameters are put directly in registers\n    }\n  }\n  else\n#endif // VS_TARGET_CPU_X86\n  if (optVectorC) {\n    // SIMD factory, vector friendly C version 16 then 8, 4, 1 floats at a time\n    // Even if the compiler does not vectorize, we have less overhead during the opcode flow processing\n    // As of 2025: original:1-2.5fps, new MAX_C_VECT=16: MSVC~6fps MSVC AVX2:~6fps, LLVM-14,7fps, LLVM AVX2-19fps\n\n    processFrameWithDynamicVectors<MAX_C_VECT>(\n      plane, w, h, pixels_per_iter, framecount, relative_time, numInputs,\n      dstp, dst_stride,\n      srcp, src_stride, ptroffsets, srcp_orig, d);\n  }\n  else\n  {\n    // C version, single pixel/loop reference\n    std::vector<float> stackVector(d.maxStackSize);\n\n    const ExprOp* vops = d.ops[plane].data();\n    float* stack = stackVector.data();\n    float stacktop = 0;\n\n    std::vector<float> variable_area(MAX_USER_VARIABLES); // for C, place for expr variables A..Z\n    std::vector<float> internal_vars(INTERNAL_VARIABLES + MAX_FRAMEPROP_VARIABLES);\n    internal_vars[INTERNAL_VAR_CURRENT_FRAME] = (float)framecount;\n    internal_vars[INTERNAL_VAR_RELTIME] = (float)relative_time;\n    // followed by dynamic frame properties\n    for (auto& framePropToRead : d.frameprops[plane]) {\n      int whereToPut = framePropToRead.var_index;\n      internal_vars[INTERNAL_VAR_FRAMEPROP_VARIABLES_START + whereToPut] = framePropToRead.value;\n    };\n\n    for (int y = 0; y < h; y++) {\n      for (int x = 0; x < w; x++) {\n        int si = 0;\n        int i = -1;\n        while (true) {\n          i++;\n          switch (vops[i].op) {\n          case opLoadSpatialX:\n            stack[si] = stacktop;\n            stacktop = (float)x;\n            ++si;\n            break;\n          case opLoadSpatialY:\n            stack[si] = stacktop;\n            stacktop = (float)y;\n            ++si;\n            break;\n          case opLoadInternalVar:\n            stack[si] = stacktop;\n            stacktop = internal_vars[vops[i].e.ival];\n            ++si;\n            break;\n          case opLoadFramePropVar:\n            stack[si] = stacktop;\n            stacktop = internal_vars[INTERNAL_VAR_FRAMEPROP_VARIABLES_START + vops[i].e.ival];\n            ++si;\n            break;\n          case opLoadSrc8:\n            stack[si] = stacktop;\n            stacktop = srcp[vops[i].e.ival][x];\n            ++si;\n            break;\n          case opLoadSrc16:\n            stack[si] = stacktop;\n            stacktop = reinterpret_cast<const uint16_t*>(srcp[vops[i].e.ival])[x];\n            ++si;\n            break;\n          case opLoadSrcF32:\n            stack[si] = stacktop;\n            stacktop = reinterpret_cast<const float*>(srcp[vops[i].e.ival])[x];\n            ++si;\n            break;\n          case opLoadRelSrc8:\n            stack[si] = stacktop;\n            {\n              const int newx = x + vops[i].dx;\n              const int newy = y + vops[i].dy;\n              const int clipIndex = vops[i].e.ival;\n              const uint8_t* srcp2 = srcp_orig[clipIndex] + max(0, min(newy, h - 1)) * src_stride[clipIndex];\n              stacktop = srcp2[max(0, min(newx, w - 1))];\n            }\n            ++si;\n            break;\n          case opLoadRelSrc16:\n            stack[si] = stacktop;\n            {\n              const int newx = x + vops[i].dx;\n              const int newy = y + vops[i].dy;\n              const int clipIndex = vops[i].e.ival;\n              const uint16_t* srcp2 = reinterpret_cast<const uint16_t*>(srcp_orig[clipIndex] + max(0, min(newy, h - 1)) * src_stride[clipIndex]);\n              stacktop = srcp2[max(0, min(newx, w - 1))];\n            }\n            ++si;\n            break;\n          case opLoadRelSrcF32:\n            stack[si] = stacktop;\n            {\n              const int newx = x + vops[i].dx;\n              const int newy = y + vops[i].dy;\n              const int clipIndex = vops[i].e.ival;\n              const float* srcp2 = reinterpret_cast<const float*>(srcp_orig[clipIndex] + max(0, min(newy, h - 1)) * src_stride[clipIndex]);\n              stacktop = srcp2[max(0, min(newx, w - 1))];\n            }\n            ++si;\n            break;\n          case opLoadConst:\n            stack[si] = stacktop;\n            stacktop = vops[i].e.fval;\n            ++si;\n            break;\n          case opLoadVar:\n            stack[si] = stacktop;\n            stacktop = variable_area[vops[i].e.ival];\n            ++si;\n            break;\n          case opDup:\n            stack[si] = stacktop;\n            stacktop = stack[si - vops[i].e.ival];\n            ++si;\n            break;\n          case opSwap:\n            std::swap(stacktop, stack[si - vops[i].e.ival]);\n            break;\n          case opAdd:\n            --si;\n            stacktop += stack[si];\n            break;\n          case opSub:\n            --si;\n            stacktop = stack[si] - stacktop;\n            break;\n          case opMul:\n            --si;\n            stacktop *= stack[si];\n            break;\n          case opDiv:\n            --si;\n            stacktop = stack[si] / stacktop;\n            break;\n          case opFmod:\n            --si;\n            stacktop = std::fmod(stack[si], stacktop);\n            break;\n          case opMax:\n            --si;\n            stacktop = std::max(stacktop, stack[si]);\n            break;\n          case opMin:\n            --si;\n            stacktop = std::min(stacktop, stack[si]);\n            break;\n          case opExp:\n            stacktop = std::exp(stacktop);\n            break;\n          case opLog:\n            stacktop = std::log(stacktop);\n            break;\n          case opPow:\n            --si;\n            stacktop = std::pow(stack[si], stacktop);\n            break;\n          case opClip:\n            // clip(a, low, high) = min(max(a, low),high)\n            si -= 2;\n            stacktop = std::max(std::min(stack[si], stacktop), stack[si + 1]);\n            break;\n          case opRound:\n            stacktop = std::round(stacktop);\n            break;\n          case opFloor:\n            stacktop = std::floor(stacktop);\n            break;\n          case opCeil:\n            stacktop = std::ceil(stacktop);\n            break;\n          case opTrunc:\n            stacktop = std::trunc(stacktop);\n            break;\n          case opSqrt:\n            stacktop = std::sqrt(stacktop);\n            break;\n          case opAbs:\n            stacktop = std::abs(stacktop);\n            break;\n          case opSgn:\n            stacktop = stacktop < 0 ? -1.0f : stacktop > 0 ? 1.0f : 0.0f;\n            break;\n          case opSin:\n            stacktop = std::sin(stacktop);\n            break;\n          case opCos:\n            stacktop = std::cos(stacktop);\n            break;\n          case opTan:\n            stacktop = std::tan(stacktop);\n            break;\n          case opAsin:\n            stacktop = std::asin(stacktop);\n            break;\n          case opAcos:\n            stacktop = std::acos(stacktop);\n            break;\n          case opAtan:\n            stacktop = std::atan(stacktop);\n            break;\n          case opAtan2:\n            --si;\n            stacktop = std::atan2(stack[si], stacktop); // y, x -> -Pi..+Pi\n            break;\n          case opGt:\n            --si;\n            stacktop = (stack[si] > stacktop) ? 1.0f : 0.0f;\n            break;\n          case opLt:\n            --si;\n            stacktop = (stack[si] < stacktop) ? 1.0f : 0.0f;\n            break;\n          case opEq:\n            --si;\n            stacktop = (stack[si] == stacktop) ? 1.0f : 0.0f;\n            break;\n          case opNotEq:\n            --si;\n            stacktop = (stack[si] != stacktop) ? 1.0f : 0.0f;\n            break;\n          case opLE:\n            --si;\n            stacktop = (stack[si] <= stacktop) ? 1.0f : 0.0f;\n            break;\n          case opGE:\n            --si;\n            stacktop = (stack[si] >= stacktop) ? 1.0f : 0.0f;\n            break;\n          case opTernary:\n            si -= 2;\n            stacktop = (stack[si] > 0) ? stack[si + 1] : stacktop;\n            break;\n          case opAnd:\n            --si;\n            stacktop = (stacktop > 0 && stack[si] > 0) ? 1.0f : 0.0f;\n            break;\n          case opOr:\n            --si;\n            stacktop = (stacktop > 0 || stack[si] > 0) ? 1.0f : 0.0f;\n            break;\n          case opXor:\n            --si;\n            stacktop = ((stacktop > 0) != (stack[si] > 0)) ? 1.0f : 0.0f;\n            break;\n          case opNeg:\n            stacktop = (stacktop > 0) ? 0.0f : 1.0f;\n            break;\n          case opNegSign:\n            stacktop = -stacktop;\n            break;\n          case opStore8:\n            dstp[x] = (uint8_t)(std::max(0.0f, std::min(stacktop, 255.0f)) + 0.5f);\n            goto loopend;\n          case opStore10:\n            reinterpret_cast<uint16_t*>(dstp)[x] = (uint16_t)(std::max(0.0f, std::min(stacktop, 1023.0f)) + 0.5f);\n            goto loopend;\n          case opStore12:\n            reinterpret_cast<uint16_t*>(dstp)[x] = (uint16_t)(std::max(0.0f, std::min(stacktop, 4095.0f)) + 0.5f);\n            goto loopend;\n          case opStore14:\n            reinterpret_cast<uint16_t*>(dstp)[x] = (uint16_t)(std::max(0.0f, std::min(stacktop, 16383.0f)) + 0.5f);\n            goto loopend;\n          case opStore16:\n            reinterpret_cast<uint16_t*>(dstp)[x] = (uint16_t)(std::max(0.0f, std::min(stacktop, 65535.0f)) + 0.5f);\n            goto loopend;\n          case opStoreF32:\n            reinterpret_cast<float*>(dstp)[x] = stacktop;\n            goto loopend;\n          case opStoreVar:\n            variable_area[vops[i].e.ival] = stacktop;\n            break;\n          case opStoreVarAndDrop1:\n            variable_area[vops[i].e.ival] = stacktop;\n            --si;\n            if (si >= 0)\n              stacktop = stack[si];\n            break;\n          }\n        }\n      loopend:;\n      }\n      dstp += dst_stride;\n      if (d.lutmode == 0) {\n        for (int i = 0; i < numInputs; i++)\n          srcp[i] += src_stride[i];\n      }\n    }\n  }\n}\n\nvoid Exprfilter::preReadFrameProps(int plane, std::vector<PVideoFrame>& src, IScriptEnvironment* env)\n{\n  for (auto& framePropToRead : d.frameprops[plane]) {\n    int srcIndex = framePropToRead.srcIndex;\n    auto fpname = framePropToRead.name;\n\n    const AVSMap* avsmap = env->getFramePropsRO(src[srcIndex]);\n\n    // default is 0f\n    float varToStore = 0.0f; //  std::numeric_limits<float>::quiet_NaN();\n\n    char res = env->propGetType(avsmap, fpname.c_str());\n    // 'u'nset, 'i'nteger, 'f'loat, 's'string, 'c'lip, 'v'ideoframe, 'm'ethod };\n\n    int error;\n    // only float and int are valid\n    // cast to float: Expr supports 32 bit float, no double, \n    if (res == 'i') {\n      int64_t result = env->propGetInt(avsmap, fpname.c_str(), 0, &error);\n      if (!error) varToStore = static_cast<float>(result);\n    }\n    else if (res == 'f') {\n      float result = env->propGetFloatSaturated(avsmap, fpname.c_str(), 0, &error);\n      if (!error) varToStore = result;\n    }\n\n    framePropToRead.value = varToStore;\n  }\n}\n\nvoid Exprfilter::calculate_lut(IScriptEnvironment* env)\n{\n  // ExprData d class variable already filled\n\n  // Only when there are frame props.\n  // frame property set from GetFrame(0) is treated as Clip prop\n\n  std::vector<PVideoFrame> src;\n\n  bool frameprops = false;\n  for (int plane = 0; plane < d.vi.NumComponents(); plane++) {\n    if (d.frameprops[plane].size() > 0) {\n      frameprops = true;\n      break;\n    }\n  }\n\n  if (frameprops) {\n    src.reserve(children.size());\n    // fetch 0th frame only when needed in lut\n    for (size_t i = 0; i < children.size(); i++) {\n      const auto& child = children[i];\n      src.emplace_back(child->GetFrame(0, env));\n    }\n  }\n\n  std::vector<const uint8_t*> srcp(MAX_EXPR_INPUTS);\n  std::vector<const uint8_t*> srcp_orig(MAX_EXPR_INPUTS);\n  std::vector<int> src_stride(MAX_EXPR_INPUTS);\n\n  for (int plane = 0; plane < d.vi.NumComponents(); plane++) {\n    // calculate only if plane is processed\n    if (d.plane[plane] != poProcess)\n      continue;\n\n    // read actually needed frame properties into the variable storage area\n    preReadFrameProps(plane, src, env);\n\n    uint8_t* dstp;\n    int dst_stride;\n    int h, w;\n\n    // no buffer allocated yet, prepare lut target buffer, and fake input frame dimensions\n    const int bits_per_pixel = d.vi.BitsPerComponent();\n    const int pixelsize = d.vi.ComponentSize();\n    const auto lut1d_size = (1 << bits_per_pixel); // 1 or 2 bytes per entry\n    const auto lut1d_bytesize = lut1d_size * pixelsize;\n    const auto lut_size = d.lutmode == 1 ? lut1d_bytesize : lut1d_bytesize * lut1d_bytesize;\n    // buffer start must be aligned to at least 32 bytes for avx2.\n    // Size must be mod64 but it is fulfilled always.\n    d.luts[plane] = (uint8_t *)avs_malloc(lut_size, 32); // 256 lut_x    65536: lut_xy (8 bit)\n    dstp = d.luts[plane];\n    dst_stride = lut1d_bytesize;\n    h = lutmode == 1 ? 1 : lut1d_size; // 1x256, 256x256. 10 bit: 1024, 1024x1024\n    w = lut1d_size;\n\n    // for simd:\n    // same as in GetFrame\n    const int pixels_per_iter = (optAvx2 && d.planeOptAvx2[plane]) ? (optSingleMode ? 8 : 16) : (optSingleMode ? 4 : 8);\n    std::vector<intptr_t> ptroffsets(1 + 1 + MAX_EXPR_INPUTS);\n    ptroffsets[RWPTR_START_OF_OUTPUT] = d.vi.ComponentSize() * pixels_per_iter; // stepping for output pointer\n    ptroffsets[RWPTR_START_OF_XCOUNTER] = pixels_per_iter; // stepping for xcounter\n\n    // no srcp pointers in lut. Technically only inputless sx,sy relative coordinates are in there\n    for (int i = 0; i < d.numInputs; i++) {\n      srcp[i] = nullptr;\n      srcp_orig[i] = nullptr;\n      src_stride[i] = 0;\n      ptroffsets[RWPTR_START_OF_INPUTS + i] = 0;\n    }\n\n    const int dummy_framecount = 0;\n    const int dummy_relative_time = 0;\n    processFrame(plane, w, h, pixels_per_iter, dummy_framecount, dummy_relative_time, d.numInputs, dstp, dst_stride, srcp, src_stride, ptroffsets, srcp_orig);\n  } // for planes\n}\n\ntemplate<typename pixel_t, int bits_per_pixel>\nstatic void do_lut_xy(const uint8_t* lut8, uint8_t* dstp, int dst_stride, const uint8_t** srcp, const int* src_stride, int w, int h)\n{\n  const int max_pixel_value = (1 << bits_per_pixel) - 1;\n  const pixel_t* lut = reinterpret_cast<const pixel_t*>(lut8);\n  const uint8_t* src0 = srcp[0];\n  const uint8_t* src1 = srcp[1];\n  const auto pitch0 = src_stride[0];\n  const auto pitch1 = src_stride[1];\n  for (auto y = 0; y < h; y++) {\n    for (auto x = 0; x < w; x++) {\n      if constexpr (bits_per_pixel == 8 || bits_per_pixel == 16) {\n        // no limit check\n        const int pixel0 = reinterpret_cast<const pixel_t*>(src0)[x];\n        const int pixel1 = reinterpret_cast<const pixel_t*>(src1)[x];\n        reinterpret_cast<pixel_t*>(dstp)[x] = lut[(pixel1 << bits_per_pixel) + pixel0];\n      }\n      else {\n        const int pixel0 = min((int)reinterpret_cast<const pixel_t*>(src0)[x], max_pixel_value);\n        const int pixel1 = min((int)reinterpret_cast<const pixel_t*>(src1)[x], max_pixel_value);\n        reinterpret_cast<pixel_t*>(dstp)[x] = lut[(pixel1 << bits_per_pixel) + pixel0];\n      }\n    }\n    src0 += pitch0;\n    src1 += pitch1;\n    dstp += dst_stride;\n  }\n}\n\nPVideoFrame __stdcall Exprfilter::GetFrame(int n, IScriptEnvironment *env) {\n  // ExprData d class variable already filled\n\n  std::vector<PVideoFrame> src;\n  src.reserve(children.size());\n\n  int first_used_clip_index = -1;\n  for (size_t i = 0; i < children.size(); i++) {\n    const auto &child = children[i];\n    src.emplace_back(d.clipsUsed[i] ? child->GetFrame(n, env) : nullptr); // GetFrame only when really referenced\n    if (first_used_clip_index < 0) {\n      if (d.clipsUsed[i])\n        first_used_clip_index = (int)i; // inherit frameprop from\n    }\n  }\n\n  PVideoFrame dst;\n  if (first_used_clip_index >= 0)\n    dst = env->NewVideoFrameP(d.vi, &src[first_used_clip_index]);\n  else\n    dst = env->NewVideoFrame(d.vi);\n\n  std::vector<const uint8_t*> srcp(MAX_EXPR_INPUTS);\n  std::vector<const uint8_t*> srcp_orig(MAX_EXPR_INPUTS);\n  std::vector<int> src_stride(MAX_EXPR_INPUTS);\n\n  const float framecount = (float)n; // max precision: 2^24 (16M) frames (32 bit float precision)\n  const float relative_time = vi.num_frames > 1 ? (float)((double)n / (vi.num_frames - 1)) : 0.0f; // 0 <= time <= 1\n  const int planes_y[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };\n  const int planes_r[4] = { PLANAR_R, PLANAR_G, PLANAR_B, PLANAR_A }; // expression string order is R G B unlike internal G B R plane order\n  const int *plane_enums_d = (d.vi.IsYUV() || d.vi.IsYUVA()) ? planes_y : planes_r;\n\n  for (int plane = 0; plane < d.vi.NumComponents(); plane++) {\n\n    const int plane_enum_d = plane_enums_d[plane];\n\n    if (d.plane[plane] == poProcess) {\n\n      // read actually needed frame properties into the variable storage area\n      preReadFrameProps(plane, src, env);\n\n      uint8_t* dstp;\n      int dst_stride;\n      int h, w;\n\n      dstp = dst->GetWritePtr(plane_enum_d);\n      dst_stride = dst->GetPitch(plane_enum_d);\n      h = d.vi.height >> d.vi.GetPlaneHeightSubsampling(plane_enum_d);\n      w = d.vi.width >> d.vi.GetPlaneWidthSubsampling(plane_enum_d);\n\n      // for simd:\n      const int pixels_per_iter = (optAvx2 && d.planeOptAvx2[plane]) ? (optSingleMode ? 8 : 16) : (optSingleMode ? 4 : 8);\n      std::vector<intptr_t> ptroffsets(1 + 1 + MAX_EXPR_INPUTS);\n      ptroffsets[RWPTR_START_OF_OUTPUT] = d.vi.ComponentSize() * pixels_per_iter; // stepping for output pointer\n      ptroffsets[RWPTR_START_OF_XCOUNTER] = pixels_per_iter; // stepping for xcounter\n\n      for (int i = 0; i < d.numInputs; i++) {\n        if (d.clips[i]) {\n          if (d.clipsUsed[i]) {\n            // when input is a single Y, use PLANAR_Y instead of the plane matching to the output\n            const VideoInfo& vi_src = d.clips[i]->GetVideoInfo();\n            const int* plane_enums_s = (vi_src.IsYUV() || d.vi.IsYUVA()) ? planes_y : planes_r;\n            const int plane_enum_s = vi_src.IsY() ? PLANAR_Y : plane_enums_s[plane];\n\n            srcp[i] = src[i]->GetReadPtr(plane_enum_s);\n            // C only:\n            srcp_orig[i] = srcp[i];\n            src_stride[i] = src[i]->GetPitch(plane_enum_s);\n            // SIMD only\n            ptroffsets[RWPTR_START_OF_INPUTS + i] = d.clips[i]->GetVideoInfo().ComponentSize() * pixels_per_iter; // 1..Nth: inputs\n          }\n          else {\n            srcp[i] = nullptr;\n            srcp_orig[i] = nullptr;\n            src_stride[i] = 0;\n            ptroffsets[RWPTR_START_OF_INPUTS + i] = 0;\n          }\n        }\n      }\n\n      if (lutmode == 0) {\n        processFrame(plane, w, h, pixels_per_iter, framecount, relative_time, d.numInputs, dstp, dst_stride, srcp, src_stride, ptroffsets, srcp_orig);\n      } else {\n        // lut table for plane is filled, do lookup now\n        const int bits_per_pixel = d.vi.BitsPerComponent();\n\n        if (d.lutmode == 1) {\n          // lut_x\n          if (bits_per_pixel == 8)\n          {\n            uint8_t* lut = d.luts[plane];\n            const uint8_t* src0 = srcp[0];\n            const auto pitch0 = src_stride[0];\n            for (auto y = 0; y < h; y++) {\n              for (auto x = 0; x < w; x++) {\n                const int pixel = src0[x];\n                dstp[x] = lut[pixel];\n              }\n              src0 += pitch0;\n              dstp += dst_stride;\n            }\n          }\n          else {\n            const int max_pixel_value = (1 << bits_per_pixel) - 1;\n            uint16_t* lut = reinterpret_cast<uint16_t*>(d.luts[plane]);\n            const uint8_t* src0 = srcp[0];\n            const auto pitch0 = src_stride[0];\n            if (bits_per_pixel == 16) {\n              // no limit check\n              for (auto y = 0; y < h; y++) {\n                for (auto x = 0; x < w; x++) {\n                  const int pixel = reinterpret_cast<const uint16_t*>(src0)[x];\n                  reinterpret_cast<uint16_t*>(dstp)[x] = lut[pixel];\n                }\n                src0 += pitch0;\n                dstp += dst_stride;\n              }\n            }\n            else {\n              for (auto y = 0; y < h; y++) {\n                for (auto x = 0; x < w; x++) {\n                  const int pixel = reinterpret_cast<const uint16_t*>(src0)[x];\n                  reinterpret_cast<uint16_t*>(dstp)[x] = lut[min(pixel, max_pixel_value)]; // e.g. 10 bits in 2 byte safety\n                }\n                src0 += pitch0;\n                dstp += dst_stride;\n              }\n            }\n          }\n        }\n        else if (d.lutmode == 2) {\n          // lut_xy\n          // templates for speed: bitshift with immediate constant\n          const uint8_t* lut = d.luts[plane];\n          if (bits_per_pixel == 8)\n            do_lut_xy<uint8_t, 8>(lut, dstp, dst_stride, srcp_orig.data(), src_stride.data(), w, h);\n          else if (bits_per_pixel == 10)\n            do_lut_xy<uint16_t, 10>(lut, dstp, dst_stride, srcp_orig.data(), src_stride.data(), w, h);\n          else if (bits_per_pixel == 12)\n            do_lut_xy<uint16_t, 12>(lut, dstp, dst_stride, srcp_orig.data(), src_stride.data(), w, h);\n          else if (bits_per_pixel == 14)\n            do_lut_xy<uint16_t, 14>(lut, dstp, dst_stride, srcp_orig.data(), src_stride.data(), w, h);\n          else if (bits_per_pixel == 16) // well, this is not enabled 16bit lutxy would take a 8GB table\n            do_lut_xy<uint16_t, 16>(lut, dstp, dst_stride, srcp_orig.data(), src_stride.data(), w, h);\n          else\n            assert(0);\n        }\n        else { // 1d lut, 2d lut\n          assert(0); // no lut_xyz\n        }\n      } // lut branch\n    }\n    // avs+: copy plane here\n    else if (d.plane[plane] == poCopy) {\n      // avs+ copy from Nth clip\n      const int copySource = d.planeCopySourceClip[plane];\n      // when input is a single Y, use PLANAR_Y instead of the plane matching to the output\n      const VideoInfo& vi_src = d.clips[copySource]->GetVideoInfo();\n      const int plane_enum_s = vi_src.IsY() ? PLANAR_Y : plane_enums_d[plane];\n\n      env->BitBlt(dst->GetWritePtr(plane_enum_d), dst->GetPitch(plane_enum_d),\n        src[copySource]->GetReadPtr(plane_enum_s),\n        src[copySource]->GetPitch(plane_enum_s),\n        src[copySource]->GetRowSize(plane_enum_s),\n        src[copySource]->GetHeight(plane_enum_s)\n      );\n    }\n    else if (d.plane[plane] == poFill) { // avs+\n      uint8_t *dstp = dst->GetWritePtr(plane_enum_d);\n      const int dst_rowsize = dst->GetRowSize(plane_enum_d);\n      const int dst_stride = dst->GetPitch(plane_enum_d);\n      const int h = dst->GetHeight(plane_enum_d);\n\n      const int bits_per_pixel = vi.BitsPerComponent();\n\n      float val = d.planeFillValue[plane];\n      int val_i = 0;\n      if (bits_per_pixel <= 16) {\n        const int max_pixel_value = (1 << bits_per_pixel) - 1;\n        val_i = (int)(std::max(0.0f, std::min(val, (float)max_pixel_value)) + 0.5f);\n      }\n\n      if(bits_per_pixel == 8)\n        fill_plane<BYTE>(dstp, h, dst_rowsize, dst_stride, val_i);\n      else if(bits_per_pixel <= 16)\n        fill_plane<uint16_t>(dstp, h, dst_rowsize, dst_stride, val_i);\n      else // 32 bit float\n        fill_plane<float>(dstp, h, dst_rowsize, dst_stride, val);\n\n    } // plane modes\n  } // for planes\n\n  return dst;\n}\n\nExprfilter::~Exprfilter() {\n  for (int i = 0; i < MAX_EXPR_INPUTS; i++)\n    d.clips[i] = nullptr;\n  for (int i = 0; i < 4; i++)\n    if(d.luts[i]) avs_free(d.luts[i]); // aligned free\n}\n\nstatic SOperation getLoadOp(const VideoInfo *vi, bool relativeKind) {\n  if (!vi)\n    return relativeKind ? opLoadRelSrcF32 : opLoadSrcF32;\n  if (vi->BitsPerComponent() == 32) // float, avs has no f16c float\n    return relativeKind ? opLoadRelSrcF32 : opLoadSrcF32;\n  else if (vi->BitsPerComponent() == 8)\n    return relativeKind ? opLoadRelSrc8 : opLoadSrc8;\n  else\n    return relativeKind ? opLoadRelSrc16 : opLoadSrc16; // 10..16 bits common\n}\n\nstatic SOperation getStoreOp(const VideoInfo *vi) {\n  // avs+ has no f16c float\n  switch (vi->BitsPerComponent()) {\n  case 8: return opStore8;\n  case 10: return opStore10; // avs+\n  case 12: return opStore12; // avs+\n  case 14: return opStore14; // avs+\n  case 16: return opStore16;\n  case 32: return opStoreF32;\n  default: return opStoreF32;\n  }\n}\n\n#define LOAD_OP(op,v,req) do { if (stackSize < req) env->ThrowError(\"Expr: Not enough elements on stack to perform operation %s\", tokens[i].c_str()); ops.push_back(ExprOp(op, (v))); maxStackSize = std::max(++stackSize, maxStackSize); } while(0)\n#define LOAD_REL_OP(op,v,req,dx,dy) do { if (stackSize < req) env->ThrowError(\"Expr: Not enough elements on stack to perform operation %s\", tokens[i].c_str()); ops.push_back(ExprOp(op, (v), (dx), (dy))); maxStackSize = std::max(++stackSize, maxStackSize); } while(0)\n#define GENERAL_OP(op, v, req, dec) do { if (stackSize < req) env->ThrowError(\"Expr: Not enough elements on stack to perform operation %s\", tokens[i].c_str()); ops.push_back(ExprOp(op, (v))); stackSize-=(dec); } while(0)\n#define ONE_ARG_OP(op) GENERAL_OP(op, 0, 1, 0)\n#define VAR_STORE_OP(op,v) GENERAL_OP(op, v, 1, 0)\n#define VAR_STORE_SPEC_OP(op,v) GENERAL_OP(op, v, 1, 1)\n#define TWO_ARG_OP(op) GENERAL_OP(op, 0, 2, 1)\n#define THREE_ARG_OP(op) GENERAL_OP(op, 0, 3, 2)\n// defines for special scale-back-before-store where no token is in context:\n#define LOAD_OP_NOTOKEN(op,v,req) do { if (stackSize < req) env->ThrowError(\"Expr: Not enough elements on stack to perform a load operation\"); ops.push_back(ExprOp(op, (v))); maxStackSize = std::max(++stackSize, maxStackSize); } while(0)\n#define GENERAL_OP_NOTOKEN(op, v, req, dec) do { if (stackSize < req) env->ThrowError(\"Expr: Not enough elements on stack to perform an operation\"); ops.push_back(ExprOp(op, (v))); stackSize-=(dec); } while(0)\n#define TWO_ARG_OP_NOTOKEN(op) GENERAL_OP_NOTOKEN(op, 0, 2, 1)\n\nstatic inline bool isAlphaUnderscore(char c) {\n  return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';\n}\n\nstatic inline bool isAlphaNumUnderscore(char c) {\n  return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';\n}\n\nstatic bool isValidVarName(const std::string& s) {\n  size_t len = s.length();\n  if (!len)\n    return false;\n\n  if (!isAlphaUnderscore(s[0]))\n    return false;\n  for (size_t i = 1; i < len; i++)\n    if (!isAlphaNumUnderscore(s[i]))\n      return false;\n  return true;\n}\n\n\n// finds _X suffix (clip letter) and returns 0..25 for x,y,z,a,b,...w\n// no suffix means 0\nstatic int getSuffix(std::string token, std::string base) {\n  size_t len = base.length();\n\n  if (token.substr(0, len) != base)\n    return -1; // no match\n\n  if (token.length() == len)\n    return 0; // no suffix, treat as _x\n\n    // find _X suffix, where X is x,y,z,a..w\n  if (token.length() != len + 2 || token[len] != '_')\n    return -2; // no proper suffix\n\n  char srcChar = token[len + 1]; // last char\n  int loadIndex;\n  if (srcChar >= 'x')\n    loadIndex = srcChar - 'x';\n  else\n    loadIndex = srcChar - 'a' + 3;\n  return loadIndex;\n}\n\n// if automatic source bit depth conversion takes place, ymax, ymin, range_xxx, etc.. constants are changed accordingly\nstatic int getEffectiveBitsPerComponent(int bitsPerComponent, bool autoconv_conv_float, bool autoconv_conv_int, int autoScaleSourceBitDepth)\n{\n  if ((autoconv_conv_float && bitsPerComponent == 32) || (autoconv_conv_int && bitsPerComponent != 32))\n    return autoScaleSourceBitDepth;\n  return bitsPerComponent;\n}\n\nstatic size_t parseExpression(const std::string &expr, std::vector<ExprOp> &ops, std::vector<ExprFramePropData>& fp, const VideoInfo **vi, const VideoInfo *vi_output, const SOperation storeOp, int numInputs, int planewidth, int planeheight, bool chroma,\n  const bool autoconv_full_scale, const bool autoconv_conv_int, const bool autoconv_conv_float, const int clamp_float_i, const bool shift_float, const int lutmode,\n  IScriptEnvironment *env)\n{\n    // vi_output is new in avs+, and is not used yet\n\n    // optional scaling, scale_from bit depth, default scale_to bitdepth, used in scaleb and scalef (yscaleb, yscalef)\n    int targetBitDepth = vi[0]->BitsPerComponent(); // avs+\n    int autoScaleSourceBitDepth = 8; // avs+ scalable constants are in 8 bit range by default\n\n    std::vector<std::string> tokens;\n    split(tokens, expr, \" \\r\\n\\t\", split1::no_empties);\n\n    std::unordered_map<std::string, int> varnames;\n    int varindex = 0;\n    std::unordered_map<std::string, int> fpnames;\n    int fpindex = 0;\n\n    size_t maxStackSize = 0;\n    size_t stackSize = 0;\n\n    for (size_t i = 0; i < tokens.size(); i++) {\n        const size_t tokenlen = tokens[i].length();\n        if (tokens[i] == \"+\")\n            TWO_ARG_OP(opAdd);\n        else if (tokens[i] == \"-\")\n            TWO_ARG_OP(opSub);\n        else if (tokens[i] == \"*\")\n            TWO_ARG_OP(opMul);\n        else if (tokens[i] == \"/\")\n            TWO_ARG_OP(opDiv);\n        else if (tokens[i] == \"%\")\n            TWO_ARG_OP(opFmod);\n        else if (tokens[i] == \"max\")\n            TWO_ARG_OP(opMax);\n        else if (tokens[i] == \"min\")\n            TWO_ARG_OP(opMin);\n        else if (tokens[i] == \"exp\")\n            ONE_ARG_OP(opExp);\n        else if (tokens[i] == \"log\")\n            ONE_ARG_OP(opLog);\n        else if (tokens[i] == \"pow\" || tokens[i] == \"^\") // avs+: ^ can be used for power\n            TWO_ARG_OP(opPow);\n        else if (tokens[i] == \"sqrt\")\n            ONE_ARG_OP(opSqrt);\n        else if (tokens[i] == \"abs\")\n            ONE_ARG_OP(opAbs);\n        else if (tokens[i] == \"sgn\")\n          ONE_ARG_OP(opSgn);\n        else if (tokens[i] == \"sin\")\n          ONE_ARG_OP(opSin);\n        else if (tokens[i] == \"cos\")\n          ONE_ARG_OP(opCos);\n        else if (tokens[i] == \"tan\")\n          ONE_ARG_OP(opTan);\n        else if (tokens[i] == \"asin\")\n          ONE_ARG_OP(opAsin);\n        else if (tokens[i] == \"acos\")\n          ONE_ARG_OP(opAcos);\n        else if (tokens[i] == \"atan\")\n          ONE_ARG_OP(opAtan);\n        else if (tokens[i] == \"atan2\")\n          TWO_ARG_OP(opAtan2);\n        else if (tokens[i] == \"clip\")\n          THREE_ARG_OP(opClip);\n        else if (tokens[i] == \"round\")\n          ONE_ARG_OP(opRound);\n        else if (tokens[i] == \"floor\")\n          ONE_ARG_OP(opFloor);\n        else if (tokens[i] == \"ceil\")\n          ONE_ARG_OP(opCeil);\n        else if (tokens[i] == \"trunc\")\n          ONE_ARG_OP(opTrunc);\n        else if (tokens[i] == \">\")\n            TWO_ARG_OP(opGt);\n        else if (tokens[i] == \"<\")\n            TWO_ARG_OP(opLt);\n        else if (tokens[i] == \"=\" || tokens[i] == \"==\") // avs+: == can be used to equality check\n            TWO_ARG_OP(opEq);\n        else if (tokens[i] == \"!=\") // avs+: not equal\n          TWO_ARG_OP(opNotEq);\n        else if (tokens[i] == \">=\")\n            TWO_ARG_OP(opGE);\n        else if (tokens[i] == \"<=\")\n            TWO_ARG_OP(opLE);\n        else if (tokens[i] == \"?\")\n            THREE_ARG_OP(opTernary);\n        else if (tokens[i] == \"and\" || tokens[i] == \"&\") // avs+: & alias for and\n            TWO_ARG_OP(opAnd);\n        else if (tokens[i] == \"or\" || tokens[i] == \"|\") // avs+: | alias for or\n            TWO_ARG_OP(opOr);\n        else if (tokens[i] == \"xor\")\n            TWO_ARG_OP(opXor);\n        else if (tokens[i] == \"not\")\n            ONE_ARG_OP(opNeg);\n        else if (tokens[i] == \"neg\")\n            ONE_ARG_OP(opNegSign);\n        else if (tokens[i].substr(0, 3) == \"dup\")\n            if (tokens[i].size() == 3) {\n                LOAD_OP(opDup, 0, 1);\n            }\n            else {\n              try {\n                int tmp = std::stoi(tokens[i].substr(3));\n                if (tmp < 0)\n                  env->ThrowError(\"Expr: Dup suffix can't be less than 0 '%s'\", tokens[i].c_str());\n                LOAD_OP(opDup, tmp, (size_t)(tmp + 1));\n              }\n              catch (std::logic_error &) {\n                env->ThrowError(\"Expr: Failed to convert dup suffix '%s' to valid index\", tokens[i].c_str());\n              }\n            }\n        else if (tokens[i].substr(0, 4) == \"swap\")\n            if (tokens[i].size() == 4) {\n                GENERAL_OP(opSwap, 1, 2, 0);\n            }\n            else {\n              try {\n                int tmp = std::stoi(tokens[i].substr(4));\n                if (tmp < 1)\n                  env->ThrowError(\"Expr: Swap suffix can't be less than 1 '%s'\", tokens[i].c_str());\n                GENERAL_OP(opSwap, tmp, (size_t)(tmp + 1), 0);\n              }\n              catch (std::logic_error &) {\n                env->ThrowError(\"Expr: Failed to convert swap suffix '%s' to valid index\", tokens[i].c_str());\n              }\n            }\n        else if (tokens[i] == \"sx\") { // avs+\n          // spatial\n          if (lutmode > 0)\n            env->ThrowError(\"Expr: 'sx' is forbidden in lut mode\");\n          LOAD_OP(opLoadSpatialX, 0, 0);\n        }\n        else if (tokens[i] == \"sy\") { // avs+\n          // spatial\n          if (lutmode > 0)\n            env->ThrowError(\"Expr: 'sy' is forbidden in lut mode\");\n          LOAD_OP(opLoadSpatialY, 0, 0);\n        }\n        else if (tokens[i] == \"sxr\") { // avs+\n          // spatial X relative 0..1\n          if (lutmode > 0)\n            env->ThrowError(\"Expr: 'sxr' is forbidden in lut mode\");\n          LOAD_OP(opLoadSpatialX, 0, 0);\n          /* Paranoia: precision at rightmost position? Ensure that sxr == 1.0 there\n          Multiply by 1/x is different.\n          Test:\n          constexpr float x = 1919.0f;\n          constexpr float y = 1 / 1919.0f;\n          constexpr float zz = x * y;\n          constexpr bool b = zz == 1.0f; // false!\n\n          const float p = planewidth > 1 ? 1.0f / ((float)planewidth - 1.0f) : 1.0f;\n          LOAD_OP(opLoadConst, p, 0);\n          TWO_ARG_OP(opMul);\n          */\n          const float p = planewidth > 1 ? (float)planewidth - 1.0f : 1.0f;\n          LOAD_OP(opLoadConst, p, 0);\n          TWO_ARG_OP(opDiv);\n        }\n        else if (tokens[i] == \"syr\") { // avs+\n          // spatial Y relative 0..1\n          if (lutmode > 0)\n            env->ThrowError(\"Expr: 'syr' is forbidden in lut mode\");\n          LOAD_OP(opLoadSpatialY, 0, 0);\n          /* Multiply by 1/x is different\n          const float p = planeheight > 1 ? 1.0f / ((float)planeheight - 1.0f) : 1.0f;\n          LOAD_OP(opLoadConst, p, 0);\n          TWO_ARG_OP(opMul);\n          */\n          const float p = planeheight > 1 ? (float)planeheight - 1.0f : 1.0f;\n          LOAD_OP(opLoadConst, p, 0);\n          TWO_ARG_OP(opDiv);\n        }\n        else if (tokens[i] == \"frameno\") { // avs+\n          if (lutmode > 0)\n            env->ThrowError(\"Expr: 'frameno' is forbidden in lut mode\");\n          LOAD_OP(opLoadInternalVar, INTERNAL_VAR_CURRENT_FRAME, 0);\n        }\n        else if (tokens[i] == \"time\") { // avs+\n          if (lutmode > 0)\n            env->ThrowError(\"Expr: 'time' is forbidden in lut mode\");\n          LOAD_OP(opLoadInternalVar, INTERNAL_VAR_RELTIME, 0);\n        }\n        else if (tokens[i] == \"width\") { // avs+\n          LOAD_OP(opLoadConst, (float)planewidth, 0);\n        }\n        else if (tokens[i] == \"height\") { // avs+\n          LOAD_OP(opLoadConst, (float)planeheight, 0);\n        }\n        else if ((tokens[i].length() == 1 || (tokens[i].length() > 1 && tokens[i][1] == '[')) && tokens[i][0] >= 'a' && tokens[i][0] <= 'z') {\n          const bool rel = tokens[i].length() > 1; // relative pixel addressing; indexed clips e.g. x[-1,-2]\n          // loading source clip pixels\n          char srcChar = tokens[i][0];\n          int loadIndex;\n          if (srcChar >= 'x')\n            loadIndex = srcChar - 'x';\n          else\n            loadIndex = srcChar - 'a' + 3;\n          if (loadIndex >= numInputs)\n            env->ThrowError(\"Expr: Too few input clips supplied to reference '%s'\", tokens[i].c_str());\n\n          if (rel) {\n            int dx, dy;\n            std::string s;\n            std::istringstream numStream(tokens[i].substr(2)); // after '['\n            numStream.imbue(std::locale::classic());\n            // first coord\n            if (!(numStream >> dx))\n              env->ThrowError(\"Expr: Failed to convert '%s' to integer, relative index dx\", tokens[i].c_str());\n            // separator ','\n            if (numStream.get() != ',')\n              env->ThrowError(\"Expr: Failed to convert '%s', character ',' expected between the coordinates\", tokens[i].c_str());\n            // second coord\n            if (!(numStream >> dy))\n              env->ThrowError(\"Expr: Failed to convert '%s' to integer, relative index dy\", tokens[i].c_str());\n            // ending ']'\n            if (numStream.get() != ']')\n              env->ThrowError(\"Expr: Failed to convert '%s' to [x,y], closing ']' expected \", tokens[i].c_str());\n            if (numStream >> s)\n              env->ThrowError(\"Expr: Failed to convert '%s' to [x,y], invalid character after ']'\", tokens[i].c_str());\n\n            if (lutmode > 0)\n              env->ThrowError(\"Expr: relative pixel addressing is forbidden in lut mode\");\n\n            if (dx <= -vi_output->width || dx >= vi_output->width)\n              env->ThrowError(\"Expr: dx must be between +/- (width-1) in '%s'\", tokens[i].c_str());\n            if (dy <= -vi_output->height || dy >= vi_output->height)\n              env->ThrowError(\"Expr: dy must be between +/- (height-1) in '%s'\", tokens[i].c_str());\n            LOAD_REL_OP(getLoadOp(vi[loadIndex], true), loadIndex, 0, dx, dy);\n          }\n          else {\n            // not relative, single clip letter\n            if (lutmode == 0) {\n              LOAD_OP(getLoadOp(vi[loadIndex], false), loadIndex, 0);\n            }\n            else {\n              // for lut we replace x and y to sx and sy to make the initialization\n              if (loadIndex >= lutmode) // lutx\n                env->ThrowError(\"Expr: more input clips than lut's dimension. Problematic clip: '%s'\", tokens[i].c_str());\n              // spatial\n              if (loadIndex == 0)\n                LOAD_OP(opLoadSpatialX, 0, 0);\n              else // if (loadIndex == 1)\n                LOAD_OP(opLoadSpatialY, 0, 0);\n            }\n          }\n\n          // avs+: 'scale_inputs': converts input pixels to a common specified range\n          // Apply full or limited conversion to integer and/or float bit depths.\n          // For integers bit-shift or full-scale-stretch method can be chosen\n          // There is no precision loss, since the multiplication/division occurs when original pixels\n          // are already loaded as float\n          const int srcBitDepth = vi[loadIndex]->BitsPerComponent();\n          const int dstBitDepth = autoScaleSourceBitDepth; // internal precision\n\n          const bool use_chroma = chroma; // && !forceNonUV;\n          const bool isfull = autoconv_full_scale;\n\n          if (autoconv_conv_int || autoconv_conv_float) {\n\n            if ((srcBitDepth != 32 && autoconv_conv_int) ||\n              ((srcBitDepth == 32 && autoconv_conv_float))) {\n\n              bits_conv_constants d;\n              get_bits_conv_constants(d, use_chroma, isfull, isfull, srcBitDepth, dstBitDepth);\n              // chroma is spec: signed. Limited:16-240 is really 128 +/-112. Full:1-255 is really 128+/-127\n\n              if (d.src_offset != 0) {\n                LOAD_OP(opLoadConst, (float)d.src_offset, 0);\n                TWO_ARG_OP(opSub);\n              }\n              if (d.mul_factor != 1.0f) {\n                LOAD_OP(opLoadConst, d.mul_factor, 0);\n                TWO_ARG_OP(opMul);\n              }\n              if (d.dst_offset != 0) {\n                LOAD_OP(opLoadConst, (float)d.dst_offset, 0);\n                TWO_ARG_OP(opAdd);\n              }\n            }\n          }\n\n          // \"floatUV\" - shifts -0.5 .. +0.5 chroma range to 0 .. 1.0 only when no other autoscaling is active\n          // the effect of this pre-shift is reversed at the storage phase\n          if ((!autoconv_conv_float || dstBitDepth == 32) && srcBitDepth == 32) {\n            if (chroma && shift_float) {\n              LOAD_OP(opLoadConst, 0.5f, 0);\n              TWO_ARG_OP(opAdd); // at the end pixel exit: opSub\n            }\n          }\n        }\n        else if (tokens[i] == \"pi\") // avs+\n        {\n          float pi = 3.141592653589793f;\n          LOAD_OP(opLoadConst, pi, 0);\n        }\n        // avs+\n        // bitdepth: automatic silent parameter of the lut expression(clip bit depth)\n        // clip-specific bitdepths: bitdepth_x, bitdepth_y, bitdepth_z, bitdepth_a, .. bitdepth_w,\n        // sbitdepth : automatic silent parameter of the lut expression(bit depth of values to scale)\n        //\n        // pre-defined, bit depth aware constants\n        //   range_half : autoscaled 128 or 0.5 for float, (or 0.0 for chroma with zero-base float chroma version)\n        //   range_max  : 255 / 1023 / 4095 / 16383 / 65535 or 1.0 for float\n        //                                                     0.5 for float chroma (new zero-based style)\n        //   range_min  : 0 for 8-16bits, or 0 for float luma, or -0.5 for float chroma\n        //                -0.5 for float chroma (new zero-based style)\n        //   range_size : 256 / 1024...65536\n        //   ymin, ymax : 16 / 235 autoscaled.\n        //   cmin, cmax : 16 / 240 autoscaled. For 32bits zero based chroma: (16-128)/255.0, (240-128)/255.0\n\n        // ymin or ymin_x, ymin_y, ymin_y, ymin_a....\n        // similarly: ymax, range_max, cmin, cmax, range_half\n        // without clip index specifier, or with '_'+letter suffix\n        else if (tokens[i].substr(0, 8) == \"bitdepth\") // avs+\n        {\n          int loadIndex = -1;\n          std::string toFind = \"bitdepth\";\n          if (tokens[i].substr(0, toFind.length()) == toFind)\n            loadIndex = getSuffix(tokens[i], toFind);\n          if (loadIndex < 0)\n            env->ThrowError(\"Expr: Error in built-in constant expression '%s'\", tokens[i].c_str());\n          if (loadIndex >= numInputs)\n            env->ThrowError(\"Expr: Too few input clips supplied for reference '%s'\", tokens[i].c_str());\n\n          int bitsPerComponent = getEffectiveBitsPerComponent(vi[loadIndex]->BitsPerComponent(), autoconv_conv_float, autoconv_conv_int, autoScaleSourceBitDepth);\n          float q = (float)bitsPerComponent;\n          LOAD_OP(opLoadConst, q, 0);\n        }\n        else if (tokens[i] == \"sbitdepth\") // avs+\n        {\n          float q = (float)autoScaleSourceBitDepth;\n          LOAD_OP(opLoadConst, q, 0);\n        }\n        else if (tokens[i].substr(0, 4) == \"ymin\") // avs+\n        {\n          int loadIndex = -1;\n          std::string toFind = \"ymin\";\n          if (tokens[i].substr(0, toFind.length()) == toFind)\n            loadIndex = getSuffix(tokens[i], toFind);\n          if (loadIndex < 0)\n            env->ThrowError(\"Expr: Error in built-in constant expression '%s'\", tokens[i].c_str());\n          if (loadIndex >= numInputs)\n            env->ThrowError(\"Expr: Too few input clips supplied for reference '%s'\", tokens[i].c_str());\n\n          int bitsPerComponent = getEffectiveBitsPerComponent(vi[loadIndex]->BitsPerComponent(), autoconv_conv_float, autoconv_conv_int, autoScaleSourceBitDepth);\n          float q = bitsPerComponent == 32 ? 16.0f / 255 : (16 << (bitsPerComponent - 8)); // scale luma min 16\n          LOAD_OP(opLoadConst, q, 0);\n        }\n        else if (tokens[i].substr(0, 4) == \"ymax\") // avs+\n        {\n          int loadIndex = -1;\n          std::string toFind = \"ymax\";\n          if (tokens[i].substr(0, toFind.length()) == toFind)\n            loadIndex = getSuffix(tokens[i], toFind);\n          if (loadIndex < 0)\n            env->ThrowError(\"Expr: Error in built-in constant expression '%s'\", tokens[i].c_str());\n          if (loadIndex >= numInputs)\n            env->ThrowError(\"Expr: Too few input clips supplied for reference '%s'\", tokens[i].c_str());\n\n          int bitsPerComponent = getEffectiveBitsPerComponent(vi[loadIndex]->BitsPerComponent(), autoconv_conv_float, autoconv_conv_int, autoScaleSourceBitDepth);\n          float q = bitsPerComponent == 32 ? 235.0f / 255 : (235 << (bitsPerComponent - 8)); // scale luma max 235\n          LOAD_OP(opLoadConst, q, 0);\n        }\n        else if (tokens[i].substr(0, 4) == \"cmin\") // avs+\n        {\n          int loadIndex = -1;\n          std::string toFind = \"cmin\";\n          if (tokens[i].substr(0, toFind.length()) == toFind)\n            loadIndex = getSuffix(tokens[i], toFind);\n          if (loadIndex < 0)\n            env->ThrowError(\"Expr: Error in built-in constant expression '%s'\", tokens[i].c_str());\n          if (loadIndex >= numInputs)\n            env->ThrowError(\"Expr: Too few input clips supplied for reference '%s'\", tokens[i].c_str());\n\n          int bitsPerComponent = getEffectiveBitsPerComponent(vi[loadIndex]->BitsPerComponent(), autoconv_conv_float, autoconv_conv_int, autoScaleSourceBitDepth);\n\n          float q = bitsPerComponent == 32 ? uv8tof(16) : (16 << (bitsPerComponent - 8)); // scale chroma min 16\n          if (shift_float && bitsPerComponent) q += 0.5f;\n          LOAD_OP(opLoadConst, q, 0);\n        }\n        else if (tokens[i].substr(0, 4) == \"cmax\") // avs+\n        {\n          int loadIndex = -1;\n          std::string toFind = \"cmax\";\n          if (tokens[i].substr(0, toFind.length()) == toFind)\n            loadIndex = getSuffix(tokens[i], toFind);\n          if (loadIndex < 0)\n            env->ThrowError(\"Expr: Error in built-in constant expression '%s'\", tokens[i].c_str());\n          if (loadIndex >= numInputs)\n            env->ThrowError(\"Expr: Too few input clips supplied for reference '%s'\", tokens[i].c_str());\n\n          int bitsPerComponent = getEffectiveBitsPerComponent(vi[loadIndex]->BitsPerComponent(), autoconv_conv_float, autoconv_conv_int, autoScaleSourceBitDepth);\n          float q = bitsPerComponent == 32 ? uv8tof(240) : (240 << (bitsPerComponent - 8)); // scale chroma max 240\n          if (shift_float && bitsPerComponent == 32) q += 0.5f;\n          LOAD_OP(opLoadConst, q, 0);\n        }\n        else if (tokens[i].substr(0, 10) == \"range_size\") // avs+\n        {\n          int loadIndex = -1;\n          std::string toFind = \"range_size\";\n          if (tokens[i].substr(0, toFind.length()) == toFind)\n            loadIndex = getSuffix(tokens[i], toFind);\n          if (loadIndex < 0)\n            env->ThrowError(\"Expr: Error in built-in constant expression '%s'\", tokens[i].c_str());\n          if (loadIndex >= numInputs)\n            env->ThrowError(\"Expr: Too few input clips supplied for reference '%s'\", tokens[i].c_str());\n\n          int bitsPerComponent = getEffectiveBitsPerComponent(vi[loadIndex]->BitsPerComponent(), autoconv_conv_float, autoconv_conv_int, autoScaleSourceBitDepth);\n          float q = bitsPerComponent == 32 ? 1.0f : (1 << bitsPerComponent); // 1.0, 256, 1024,... 65536\n          LOAD_OP(opLoadConst, q, 0);\n        }\n        else if (tokens[i].substr(0, 9) == \"range_min\") // avs+ > r2636\n        {\n          int loadIndex = -1;\n          std::string toFind = \"range_min\";\n          if (tokens[i].substr(0, toFind.length()) == toFind)\n            loadIndex = getSuffix(tokens[i], toFind);\n          if (loadIndex < 0)\n            env->ThrowError(\"Expr: Error in built-in constant expression '%s'\", tokens[i].c_str());\n          if (loadIndex >= numInputs)\n            env->ThrowError(\"Expr: Too few input clips supplied for reference '%s'\", tokens[i].c_str());\n\n          int bitsPerComponent = getEffectiveBitsPerComponent(vi[loadIndex]->BitsPerComponent(), autoconv_conv_float, autoconv_conv_int, autoScaleSourceBitDepth);\n          // 0.0 (or -0.5 for 32bit float chroma)\n          float q = bitsPerComponent == 32 ? (chroma ? -0.5f : 0.0f) : 0;\n          if (chroma && shift_float && bitsPerComponent == 32) q += 0.5f;\n          LOAD_OP(opLoadConst, q, 0);\n        }\n        else if (tokens[i].substr(0, 10) == \"yrange_min\")\n        {\n          int loadIndex = -1;\n          std::string toFind = \"yrange_min\";\n          if (tokens[i].substr(0, toFind.length()) == toFind)\n            loadIndex = getSuffix(tokens[i], toFind);\n          if (loadIndex < 0)\n            env->ThrowError(\"Expr: Error in built-in constant expression '%s'\", tokens[i].c_str());\n          if (loadIndex >= numInputs)\n            env->ThrowError(\"Expr: Too few input clips supplied for reference '%s'\", tokens[i].c_str());\n\n          int bitsPerComponent = getEffectiveBitsPerComponent(vi[loadIndex]->BitsPerComponent(), autoconv_conv_float, autoconv_conv_int, autoScaleSourceBitDepth);\n          float q = bitsPerComponent == 32 ? 0.0f : 0;\n          LOAD_OP(opLoadConst, q, 0);\n        }\n        else if (tokens[i].substr(0, 9) == \"range_max\") // avs+\n        {\n          int loadIndex = -1;\n          std::string toFind = \"range_max\";\n          if (tokens[i].substr(0, toFind.length()) == toFind)\n            loadIndex = getSuffix(tokens[i], toFind);\n          if (loadIndex < 0)\n            env->ThrowError(\"Expr: Error in built-in constant expression '%s'\", tokens[i].c_str());\n          if (loadIndex >= numInputs)\n            env->ThrowError(\"Expr: Too few input clips supplied for reference '%s'\", tokens[i].c_str());\n\n          int bitsPerComponent = getEffectiveBitsPerComponent(vi[loadIndex]->BitsPerComponent(), autoconv_conv_float, autoconv_conv_int, autoScaleSourceBitDepth);\n          // 1.0 (or 0.5 for 32bit float chroma), 255, 1023,... 65535\n          float q = bitsPerComponent == 32 ? (chroma ? + 0.5f : 1.0f) : ((1 << bitsPerComponent) - 1);\n          if (chroma && shift_float && bitsPerComponent == 32) q += 0.5f;\n          LOAD_OP(opLoadConst, q, 0);\n        }\n        else if (tokens[i].substr(0, 10) == \"yrange_max\")\n        {\n          int loadIndex = -1;\n          std::string toFind = \"yrange_max\";\n          if (tokens[i].substr(0, toFind.length()) == toFind)\n            loadIndex = getSuffix(tokens[i], toFind);\n          if (loadIndex < 0)\n            env->ThrowError(\"Expr: Error in built-in constant expression '%s'\", tokens[i].c_str());\n          if (loadIndex >= numInputs)\n            env->ThrowError(\"Expr: Too few input clips supplied for reference '%s'\", tokens[i].c_str());\n\n          int bitsPerComponent = getEffectiveBitsPerComponent(vi[loadIndex]->BitsPerComponent(), autoconv_conv_float, autoconv_conv_int, autoScaleSourceBitDepth);\n          // 1.0, 255, 1023,... 65535\n          float q = bitsPerComponent == 32 ? 1.0f : ((1 << bitsPerComponent) - 1);\n          LOAD_OP(opLoadConst, q, 0);\n        }\n        else if (tokens[i].substr(0, 10) == \"range_half\") // avs+\n        {\n          int loadIndex = -1;\n          std::string toFind = \"range_half\";\n          if (tokens[i].substr(0, toFind.length()) == toFind)\n            loadIndex = getSuffix(tokens[i], toFind);\n          if (loadIndex < 0)\n            env->ThrowError(\"Expr: Error in built-in constant expression '%s'\", tokens[i].c_str());\n          if (loadIndex >= numInputs)\n            env->ThrowError(\"Expr: Too few input clips supplied for reference '%s'\", tokens[i].c_str());\n\n          // for chroma: range_half is 0.0 for 32bit float (or 0.5 for old float chroma representation)\n          int bitsPerComponent = getEffectiveBitsPerComponent(vi[loadIndex]->BitsPerComponent(), autoconv_conv_float, autoconv_conv_int, autoScaleSourceBitDepth);\n          float q = bitsPerComponent == 32 ? (chroma ? uv8tof(128) : 0.5f) : (1 << (bitsPerComponent - 1)); // 0.5f, 128, 512, ... 32768\n          if (chroma && shift_float && bitsPerComponent == 32) q += 0.5f;\n          LOAD_OP(opLoadConst, q, 0);\n        }\n        else if (tokens[i].substr(0, 11) == \"yrange_half\") // avs+\n        {\n          int loadIndex = -1;\n          std::string toFind = \"yrange_half\";\n          if (tokens[i].substr(0, toFind.length()) == toFind)\n            loadIndex = getSuffix(tokens[i], toFind);\n          if (loadIndex < 0)\n            env->ThrowError(\"Expr: Error in built-in constant expression '%s'\", tokens[i].c_str());\n          if (loadIndex >= numInputs)\n            env->ThrowError(\"Expr: Too few input clips supplied for reference '%s'\", tokens[i].c_str());\n\n          int bitsPerComponent = getEffectiveBitsPerComponent(vi[loadIndex]->BitsPerComponent(), autoconv_conv_float, autoconv_conv_int, autoScaleSourceBitDepth);\n          float q = bitsPerComponent == 32 ? 0.5f : (1 << (bitsPerComponent - 1)); // 0.5f, 128, 512, ... 32768\n          LOAD_OP(opLoadConst, q, 0);\n        }\n        // \"scaleb\" and \"scalef\" functions scale their operand from 8 bit to the bit depth of the first clip.\n        // \"i8\", \"i10\", \"i14\", \"i16\" and \"f32\" (typically at the beginning of the expression) sets the scale-base to 8..16 bits or float, respectively.\n        // \"i8\"..\"f32\" keywords can appear anywhere in the expression, but only the last occurence will be effective for the whole expression.\n        else if (tokens[i] == \"scaleb\" || tokens[i] == \"yscaleb\" || tokens[i] == \"scalef\" || tokens[i] == \"yscalef\") // avs+, scale by bit shift\n        {\n          // Note: if 'scale_float' is used then all float input is automatically converted to integer\n          // in this case the targetBitDepth is not 32 for float clips but the actual autoscaleSourceBitDepth\n          int effectivetargetBitDepth = getEffectiveBitsPerComponent(targetBitDepth, autoconv_conv_float, autoconv_conv_int, autoScaleSourceBitDepth);\n          // number to scale is not chroma-related one even if we are in chroma (U,V) plane\n          const bool forceNonUV = (tokens[i] == \"yscaleb\") || (tokens[i] == \"yscalef\");\n\n          const int srcBitDepth = autoScaleSourceBitDepth;\n          const int dstBitDepth = effectivetargetBitDepth;\n          const bool use_chroma = chroma && !forceNonUV;\n\n          const bool isfull = tokens[i] == \"scalef\" || tokens[i] == \"yscalef\";\n\n          bits_conv_constants d;\n          get_bits_conv_constants(d, use_chroma, isfull, isfull, srcBitDepth, dstBitDepth);\n          // chroma is spec: signed. Limited:16-240 is really 128 +/-112. Full:1-255 is really 128+/-127\n\n          // floatUV\n          if (use_chroma && shift_float && dstBitDepth == 32 && srcBitDepth < 32) {\n            d.dst_offset = 0.5f; // get out from -0.5..0.5 to 0..1\n          }\n\n          if (d.src_offset != 0) {\n            LOAD_OP(opLoadConst, (float)d.src_offset, 0);\n            TWO_ARG_OP(opSub);\n          }\n          if (d.mul_factor != 1.0f) {\n            LOAD_OP(opLoadConst, d.mul_factor, 0);\n            TWO_ARG_OP(opMul);\n          }\n          if (d.dst_offset != 0) {\n            LOAD_OP(opLoadConst, (float)d.dst_offset, 0);\n            TWO_ARG_OP(opAdd);\n          }\n        }\n        else if (tokens[i] == \"i8\") // avs+\n        {\n          autoScaleSourceBitDepth = 8;\n        }\n        else if (tokens[i] == \"i10\") // avs+\n        {\n          autoScaleSourceBitDepth = 10;\n        }\n        else if (tokens[i] == \"i12\") // avs+\n        {\n          autoScaleSourceBitDepth = 12;\n        }\n        else if (tokens[i] == \"i14\") // avs+\n        {\n          autoScaleSourceBitDepth = 14;\n        }\n        else if (tokens[i] == \"i16\") // avs+\n        {\n          autoScaleSourceBitDepth = 16;\n        }\n        else if (tokens[i] == \"f32\") // avs+\n        {\n          autoScaleSourceBitDepth = 32;\n        }\n        else if (tokens[i].length() > 1 && tokens[i][0] >= 'a' && tokens[i][0] <= 'z' && tokens[i][1] == '.') {\n          // frame property access: x.framePropName syntax\n          char srcChar = tokens[i][0];\n          int srcIndex;\n          if (srcChar >= 'x')\n            srcIndex = srcChar - 'x';\n          else\n            srcIndex = srcChar - 'a' + 3;\n          if (srcIndex >= numInputs)\n            env->ThrowError(\"Expr: Too few input clips supplied to reference '%s'\", tokens[i].c_str());\n\n          auto fullname = tokens[i];\n          auto fpname = tokens[i].substr(2); // after '.'\n          if(fpname.length() == 0)\n            env->ThrowError(\"Expr: no frame property name is specified\");\n          if (!isValidVarName(fpname))\n            env->ThrowError(\"Expr: invalid frame property name '%s'\", fpname.c_str());\n\n          // check if frame property already existed in a variable slots\n          auto key = fullname;\n          auto it = fpnames.find(key);\n          int loadIndex;\n          if (it == fpnames.end()) {\n            // first occurance, insert name and actual index\n            if (fpindex >= MAX_FRAMEPROP_VARIABLES)\n              env->ThrowError(\"Expr: too many frame property references, maximum reached (%d)\", MAX_FRAMEPROP_VARIABLES);\n            loadIndex = fpindex++;\n            fpnames[key] = loadIndex;\n            // Register into the list of frame properties to read\n            // input clip index: srcIndex\n            // name of frame property: fpname\n            // variable index to fill: loadindex\n            ExprFramePropData fpData;\n            fpData.name = fpname;\n            fpData.srcIndex = srcIndex;\n            fpData.var_index = loadIndex;\n            fp.push_back(fpData);\n          }\n          else {\n            loadIndex = it->second;\n          }\n          LOAD_OP(opLoadFramePropVar, loadIndex, 0);\n        }\n        else if (tokenlen >= 2 && (tokens[i][tokenlen - 1] == '^' || tokens[i][tokenlen - 1] == '@'))\n        {\n          // storing a variable: A@ .. Z@\n          // storing a variable and remove from stack: A^..Z^\n          auto key = tokens[i].substr(0, tokenlen - 1);\n          auto opchar = tokens[i][tokenlen - 1];\n          auto it = varnames.find(key);\n          int loadIndex;\n          if (it == varnames.end()) {\n            if(!isValidVarName(key))\n              env->ThrowError(\"Expr: invalid variable name '%s'\", key.c_str());\n            // first occurance, insert name and actual index\n            if (varindex >= MAX_USER_VARIABLES)\n              env->ThrowError(\"Expr: too many variables, maximum reached (%d)\", MAX_USER_VARIABLES);\n            loadIndex = varindex++;\n            varnames[key] = loadIndex;\n          }\n          else {\n            loadIndex = it->second;\n          }\n          if (opchar == '^')\n            VAR_STORE_SPEC_OP(opStoreVarAndDrop1, loadIndex);\n          else // if (opchar == '@')\n            VAR_STORE_OP(opStoreVar, loadIndex);\n        }\n        else if (isValidVarName(tokens[i]))\n        {\n          // variable names\n          // the very end, all reserved expr words were processed\n          auto key = tokens[i];\n          auto it = varnames.find(key);\n          if (it == varnames.end())\n            env->ThrowError(\"Expr: keyword or variable not found: '%s'\", key.c_str());\n          auto loadIndex = it->second;\n          LOAD_OP(opLoadVar, loadIndex, 0);\n        }\n        else {\n          // parse a number\n            float f;\n            std::string s;\n            std::istringstream numStream(tokens[i]);\n            numStream.imbue(std::locale::classic());\n            if (!(numStream >> f))\n              env->ThrowError(\"Expr: Failed to convert '%s' to float\", tokens[i].c_str());\n            if (numStream >> s)\n              env->ThrowError(\"Expr: Failed to convert '%s' to float, not the whole token could be converted\", tokens[i].c_str());\n            LOAD_OP(opLoadConst, f, 0);\n        }\n    }\n\n    if (tokens.size() > 0) {\n        if (stackSize != 1)\n            env->ThrowError(\"Expr: Stack unbalanced at end of expression (size=%zu). Need to have exactly one value on the stack to return.\", stackSize);\n\n        // When scale_inputs option was used for scaling input to a common internal range,\n        // we have to scale pixels before storing them back\n        // need any conversion?\n        // or use effectiveTargetBitDepth instead of autoScaleSourceBitDepth\n        const int srcBitDepth = autoScaleSourceBitDepth;\n        const int dstBitDepth = targetBitDepth;\n        const bool use_chroma = chroma; // && !forceNonUV;\n\n        const bool isfull = autoconv_full_scale;\n\n        if (autoconv_conv_int || autoconv_conv_float) {\n\n          if ((targetBitDepth != 32 && autoconv_conv_int) || \n            ((targetBitDepth == 32 && autoconv_conv_float))) {\n\n            bits_conv_constants d;\n            get_bits_conv_constants(d, use_chroma, isfull, isfull, srcBitDepth, dstBitDepth);\n            // chroma is spec: signed. Limited:16-240 is really 128 +/-112. Full:1-255 is really 128+/-127\n\n            if (d.src_offset != 0) {\n              LOAD_OP_NOTOKEN(opLoadConst, (float)d.src_offset, 0);\n              TWO_ARG_OP_NOTOKEN(opSub);\n            }\n            if (d.mul_factor != 1.0f) {\n              LOAD_OP_NOTOKEN(opLoadConst, d.mul_factor, 0);\n              TWO_ARG_OP_NOTOKEN(opMul);\n            }\n            if (d.dst_offset != 0) {\n              LOAD_OP_NOTOKEN(opLoadConst, (float)d.dst_offset, 0);\n              TWO_ARG_OP_NOTOKEN(opAdd);\n            }\n          }\n        }\n        // \"floatUV\" -\n        // this reverses the effect of the 0.5 float-type pre-shift is the pixel load phase\n        // pre-shifts chroma pixels by +0.5 before applying the expression (see at pixel load),\n        // then here the result is shifted back by -0.5\n        // Thus expressions, which rely on a working range of 0..1.0 will work transparently\n        if ((!autoconv_conv_float || srcBitDepth == 32) && targetBitDepth == 32) {\n          if (chroma && shift_float) {\n            LOAD_OP_NOTOKEN(opLoadConst, 0.5f, 0);\n            TWO_ARG_OP_NOTOKEN(opSub); // at pixel load it was opAdd\n          }\n        }\n\n        if (clamp_float_i > 0 && targetBitDepth == 32) {\n          if (chroma) {\n            // clamp_float clamp_float_uv -> clamp_float_i   clamp range for Y clamp range for UV\n            // false       x                 0               0..1              -0.5..+0.5\n            // true        false             1               0..1              -0.5..+0.5\n            // true        true              2               0..1              0..1\n            LOAD_OP_NOTOKEN(opLoadConst, clamp_float_i == 2 ? 0.0f : -0.5f, 0);\n            TWO_ARG_OP_NOTOKEN(opMax);\n            LOAD_OP_NOTOKEN(opLoadConst, clamp_float_i == 2 ? 1.0f : 0.5f, 0);\n            TWO_ARG_OP_NOTOKEN(opMin);\n          }\n          else\n          { // luma\n            LOAD_OP_NOTOKEN(opLoadConst, 0.0f, 0);\n            TWO_ARG_OP_NOTOKEN(opMax);\n            LOAD_OP_NOTOKEN(opLoadConst, 1.0f, 0);\n            TWO_ARG_OP_NOTOKEN(opMin);\n          }\n        }\n\n        // and finally store it\n        ops.push_back(storeOp);\n    }\n\n    return maxStackSize;\n}\n\nstatic float calculateOneOperand(uint32_t op, float a) {\n    switch (op) {\n        case opSqrt:\n            return std::sqrt(a);\n        case opAbs:\n            return std::abs(a);\n        case opSgn:\n            return (a < 0) ? -1.0f : (a > 0) ? 1.0f : 0.0f;\n        case opNeg: // Expr \"boolean\": not\n            return (a > 0) ? 0.0f : 1.0f;\n        case opNegSign:\n            return -a;\n        case opExp:\n            return std::exp(a);\n        case opLog:\n            return std::log(a);\n        case opSin:\n          return std::sin(a);\n        case opCos:\n          return std::cos(a);\n        case opTan:\n          return std::tan(a);\n        case opAsin:\n          return std::asin(a);\n        case opAcos:\n          return std::acos(a);\n        case opAtan:\n          return std::atan(a);\n        case opRound:\n          return std::round(a);\n        case opFloor:\n          return std::floor(a);\n        case opCeil:\n          return std::ceil(a);\n        case opTrunc:\n          return std::trunc(a);\n    }\n\n    return 0.0f;\n}\n\nstatic float calculateTwoOperands(uint32_t op, float a, float b) {\n    switch (op) {\n        case opAdd:\n            return a + b;\n        case opSub:\n            return a - b;\n        case opMul:\n            return a * b;\n        case opDiv:\n            return a / b;\n        case opFmod:\n            return std::fmod(a, b);\n        case opMax:\n            return std::max(a, b);\n        case opMin:\n            return std::min(a, b);\n        case opGt:\n            return (a > b) ? 1.0f : 0.0f;\n        case opLt:\n            return (a < b) ? 1.0f : 0.0f;\n        case opEq:\n            return (a == b) ? 1.0f : 0.0f;\n        case opNotEq:\n            return (a != b) ? 1.0f : 0.0f;\n        case opLE:\n            return (a <= b) ? 1.0f : 0.0f;\n        case opGE:\n            return (a >= b) ? 1.0f : 0.0f;\n        case opAnd:\n            return (a > 0 && b > 0) ? 1.0f : 0.0f;\n        case opOr:\n            return (a > 0 || b > 0) ? 1.0f : 0.0f;\n        case opXor:\n            return ((a > 0) != (b > 0)) ? 1.0f : 0.0f;\n        case opPow:\n            return std::pow(a, b);\n        case opAtan2:\n            return std::atan2(a, b);\n    }\n\n    return 0.0f;\n}\n\nstatic int numOperands(uint32_t op) {\n    switch (op) {\n        case opLoadConst:\n        case opLoadSrc8:\n        case opLoadSrc16:\n        case opLoadSrcF32:\n        case opLoadSrcF16:\n        case opLoadRelSrc8:\n        case opLoadRelSrc16:\n        case opLoadRelSrcF32:\n        case opDup:\n        case opLoadSpatialX:\n        case opLoadSpatialY:\n        case opLoadVar:\n        case opLoadFramePropVar:\n        case opLoadInternalVar:\n        case opSwap:\n        case opStoreVar:\n        case opStoreVarAndDrop1:\n          return 0;\n\n        case opSqrt:\n        case opAbs:\n        case opSgn:\n        case opNeg:\n        case opNegSign:\n        case opExp:\n        case opLog:\n        case opSin:\n        case opCos:\n        case opTan:\n        case opAsin:\n        case opAcos:\n        case opAtan:\n        case opRound:\n        case opFloor:\n        case opCeil:\n        case opTrunc:\n          return 1;\n\n        case opAdd:\n        case opSub:\n        case opMul:\n        case opDiv:\n        case opFmod:\n        case opMax:\n        case opMin:\n        case opGt:\n        case opLt:\n        case opEq:\n        case opNotEq:\n        case opLE:\n        case opGE:\n        case opAnd:\n        case opOr:\n        case opXor:\n        case opPow:\n        case opAtan2:\n          return 2;\n\n        case opTernary:\n        case opClip:\n            return 3;\n    }\n\n    return 0;\n}\n\nstatic bool isLoadOp(uint32_t op) {\n    switch (op) {\n        case opLoadConst:\n        case opLoadSrc8:\n        case opLoadSrc16:\n        case opLoadSrcF32:\n        case opLoadSrcF16:\n        case opLoadRelSrc8:\n        case opLoadRelSrc16:\n        case opLoadRelSrcF32:\n        case opLoadSpatialX:\n        case opLoadSpatialY:\n        case opLoadVar:\n        case opLoadFramePropVar:\n        case opLoadInternalVar:\n          return true;\n    }\n\n    return false;\n}\n\nstatic void findBranches(std::vector<ExprOp>& ops, size_t pos, size_t* start1, size_t* start2, size_t* start3) {\n  int operands = numOperands(ops[pos].op);\n\n  size_t temp1, temp2, temp3;\n\n  if (operands == 0) {\n    // dup loadsrc loadrel loadconst swap, storevar\n    if (ops[pos].op == opSwap || ops[pos].op == opStoreVar || ops[pos].op == opStoreVarAndDrop1)\n    {\n      findBranches(ops, pos - 1, &temp1, &temp2, &temp3);\n      *start1 = temp1;\n      if (ops[pos].op == opStoreVarAndDrop1) {\n        // StoreAndPopVar: opStoreVar + Ignore topmost stack.\n        // Branch was calculated only for storing its result into var.\n        // Leaves no trace on stack.\n        // So we go on with next branch\n        pos = *start1;\n        findBranches(ops, pos - 1, &temp1, &temp2, &temp3);\n        *start1 = temp1;\n      }\n    }\n    else\n      *start1 = pos;\n  }\n  else if (operands == 1) {\n    if (isLoadOp(ops[pos - 1].op)) {\n      *start1 = pos - 1;\n    }\n    else {\n      findBranches(ops, pos - 1, &temp1, &temp2, &temp3);\n      *start1 = temp1;\n    }\n  }\n  else if (operands == 2) {\n    if (isLoadOp(ops[pos - 1].op)) {\n      *start2 = pos - 1;\n    }\n    else {\n      findBranches(ops, pos - 1, &temp1, &temp2, &temp3);\n      *start2 = temp1;\n    }\n\n    if (isLoadOp(ops[*start2 - 1].op)) {\n      *start1 = *start2 - 1;\n    }\n    else {\n      findBranches(ops, *start2 - 1, &temp1, &temp2, &temp3);\n      *start1 = temp1;\n    }\n  }\n  else if (operands == 3) {\n    if (isLoadOp(ops[pos - 1].op)) {\n      *start3 = pos - 1;\n    }\n    else {\n      findBranches(ops, pos - 1, &temp1, &temp2, &temp3);\n      *start3 = temp1;\n    }\n\n    if (isLoadOp(ops[*start3 - 1].op)) {\n      *start2 = *start3 - 1;\n    }\n    else {\n      findBranches(ops, *start3 - 1, &temp1, &temp2, &temp3);\n      *start2 = temp1;\n    }\n\n    if (isLoadOp(ops[*start2 - 1].op)) {\n      *start1 = *start2 - 1;\n    }\n    else {\n      findBranches(ops, *start2 - 1, &temp1, &temp2, &temp3);\n      *start1 = temp1;\n    }\n  }\n}\n\n\nstatic void foldConstants(std::vector<ExprOp> &ops) {\n    for (size_t i = 0; i < ops.size(); i++) {\n        switch (ops[i].op) {\n          // optimize pow\n        case opPow:\n          if (ops[i - 1].op == opLoadConst) {\n            if (ops[i - 1].e.fval == 0.5f) {\n              // replace pow 0.5 with sqrt\n              ops[i].op = opSqrt;\n              ops.erase(ops.begin() + i - 1);\n              i--;\n            }\n            else if (ops[i - 1].e.fval == 1.0f) {\n              // replace pow 1 with nothing\n              ops.erase(ops.begin() + i - 1, ops.begin() + i + 1);\n              i -= 2;\n            }\n            else if (ops[i - 1].e.fval == 2.0f) {\n              // replace pow 2 with dup *\n              ops[i].op = opMul;\n              ops[i - 1].op = opDup; ops[i - 1].e.ival = 0; // dup 0\n              i--;\n            }\n            else if (ops[i - 1].e.fval == 3.0f) {\n              // replace pow 3 with dup dup * *\n              ops[i].op = opMul;\n              ops[i - 1].op = opMul;\n              ExprOp extraDup(opDup, 0);\n              ops.insert(ops.begin() + i - 1, extraDup);\n              ops.insert(ops.begin() + i - 1, extraDup);\n              i--;\n            }\n            else if (ops[i - 1].e.fval == 4.0f) {\n              // replace pow 4 with dup * dup *\n              ops[i].op = opMul;\n              ops[i - 1].op = opDup; ops[i - 1].e.ival = 0; // dup 0\n              ExprOp extraMul(opMul);\n              ExprOp extraDup(opDup, 0);\n              ops.insert(ops.begin() + i - 1, extraMul);\n              ops.insert(ops.begin() + i - 1, extraDup);\n              i--;\n            }\n          }\n          break;\n          // optimize Mul 1 Div 1, Mul -1, Div -1\n        case opMul: case opDiv:\n          if (ops[i - 1].op == opLoadConst) {\n            if (ops[i - 1].e.fval == 1.0f) {\n              // replace mul 1 or div 1 with nothing\n              ops.erase(ops.begin() + i - 1, ops.begin() + i + 1);\n              i -= 2;\n            }\n            else if (ops[i - 1].e.fval == -1.0f) {\n              // replace mul -1 or div -1 with neg\n              ops[i].op = opNegSign;\n              ops.erase(ops.begin() + i - 1);\n              i--;\n            }\n          }\n          break;\n          // optimize Add 0 or Sub 0\n        case opAdd: case opSub:\n          if (ops[i - 1].op == opLoadConst) {\n            if (ops[i - 1].e.fval == 0.0f) {\n              // replace add 0 or sub 0 with nothing\n              ops.erase(ops.begin() + i - 1, ops.begin() + i + 1);\n              i -= 2;\n            }\n          }\n          break;\n\n        }\n\n        // fold constant\n        switch (ops[i].op) {\n            case opDup:\n              if (ops[i - 1].op == opLoadConst && ops[i].e.ival == 0) {\n                ops[i] = ops[i - 1];\n              }\n              break;\n\n            case opSqrt:\n            case opAbs:\n            case opSgn:\n            case opNeg:\n            case opNegSign:\n            case opExp:\n            case opLog:\n            case opSin:\n            case opCos:\n            case opTan:\n            case opAsin:\n            case opAcos:\n            case opAtan:\n            case opRound:\n            case opFloor:\n            case opCeil:\n            case opTrunc:\n              if (ops[i - 1].op == opLoadConst) {\n                ops[i].e.fval = calculateOneOperand(ops[i].op, ops[i - 1].e.fval);\n                ops[i].op = opLoadConst;\n                ops.erase(ops.begin() + i - 1);\n                i--;\n              }\n              break;\n\n            case opSwap:\n              if (ops[i - 2].op == opLoadConst && ops[i - 1].op == opLoadConst && ops[i].e.ival == 1) {\n                const float temp = ops[i - 2].e.fval;\n                ops[i - 2].e.fval = ops[i - 1].e.fval;\n                ops[i - 1].e.fval = temp;\n                ops.erase(ops.begin() + i);\n                i--;\n              }\n              break;\n\n            case opAdd:\n            case opSub:\n            case opMul:\n            case opDiv:\n            case opFmod:\n            case opMax:\n            case opMin:\n            case opGt:\n            case opLt:\n            case opEq:\n            case opNotEq:\n            case opLE:\n            case opGE:\n            case opAnd:\n            case opOr:\n            case opXor:\n            case opPow:\n            case opAtan2:\n              if (ops[i - 2].op == opLoadConst && ops[i - 1].op == opLoadConst) {\n                ops[i].e.fval = calculateTwoOperands(ops[i].op, ops[i - 2].e.fval, ops[i - 1].e.fval);\n                ops[i].op = opLoadConst;\n                ops.erase(ops.begin() + i - 2, ops.begin() + i);\n                i -= 2;\n              }\n              break;\n\n            case opTernary:\n              size_t start1, start2, start3;\n              findBranches(ops, i, &start1, &start2, &start3);\n              // start1/2/3: condition/true/false branch\n              if (ops[start2 - 1].op == opLoadConst) { // condition expression is a single constant\n                ops.erase(ops.begin() + i); // erase ternary op\n                if (ops[start1].e.fval > 0.0f) { // condition is constant 'true'\n                  // start1 is start2 - 1\n                  ops.erase(ops.begin() + start3, ops.begin() + i); // erase 'false' branch\n                  i = start3;\n                } else {\n                  ops.erase(ops.begin() + start2, ops.begin() + start3);  // erase 'true' branch\n                  i -= start3 - start2;\n                }\n                ops.erase(ops.begin() + start1); // erase constant\n                i -= 2;\n              }\n              break;\n      }\n    }\n}\n\nExprfilter::Exprfilter(const std::vector<PClip>& _child_array, const std::vector<std::string>& _expr_array, const char *_newformat, const bool _optAvx2,\n  const bool _optSingleMode, const bool _optSSE2, const bool _optVectorC, const std::string _scale_inputs, const int _clamp_float_i, const int _lutmode, IScriptEnvironment *env) :\n  children(_child_array), expressions(_expr_array), optAvx2(_optAvx2), optSingleMode(_optSingleMode), optSSE2(_optSSE2),\n  optVectorC(_optVectorC), scale_inputs(_scale_inputs), clamp_float_i(_clamp_float_i), lutmode(_lutmode) {\n\n  vi = children[0]->GetVideoInfo();\n  d.vi = vi;\n  if (lutmode < 0 || lutmode>2)\n    env->ThrowError(\"'Expr: 'lut' can be 0 (no lut), 1 (lut_x) or 2 (lut_xy)\");\n  if (lutmode == 1 && vi.BitsPerComponent() == 32)\n    lutmode = 0; // fallback to realtime\n  if (lutmode == 2 && vi.BitsPerComponent() > 14)\n    lutmode = 0; // fallback to realtime\n  d.lutmode = lutmode;\n\n  for (int i = 0; i < 4; i++)\n    d.luts[i] = nullptr;\n\n  // parse \"scale_inputs\"\n  autoconv_full_scale = false;\n  autoconv_conv_float = false;\n  autoconv_conv_int = false;\n  shift_float = false;\n\n  if (scale_inputs == \"allf\") {\n    autoconv_full_scale = true;\n    autoconv_conv_int = true;\n    autoconv_conv_float = true;\n  }\n  else if (scale_inputs == \"intf\") {\n    autoconv_full_scale = true;\n    autoconv_conv_int = true;\n  }\n  else if (scale_inputs == \"floatf\") {\n    autoconv_full_scale = true;\n    autoconv_conv_float = true;\n  }\n  else if (scale_inputs == \"all\") {\n    autoconv_conv_int = true;\n    autoconv_conv_float = true;\n  }\n  else if (scale_inputs == \"int\") {\n    autoconv_conv_int = true;\n  }\n  else if (scale_inputs == \"float\") {\n    autoconv_conv_float = true;\n  }\n  else if (scale_inputs == \"floatuv\") {\n    autoconv_conv_float = false; // !! really\n    // like in masktools2 2.2.20+\n    shift_float = true; // !!\n  }\n  else if (scale_inputs != \"none\") {\n    env->ThrowError(\"Expr: scale_inputs must be 'all','allf','int','intf','float','floatf','floatUV' or 'none'\");\n  }\n\n  try {\n    d.numInputs = (int)children.size(); // d->numInputs = vsapi->propNumElements(in, \"clips\");\n    if (d.numInputs > 26)\n      env->ThrowError(\"Expr: More than 26 input clips provided\");\n\n    for (int i = 0; i < d.numInputs; i++)\n      d.clips[i] = children[i];\n\n    if (d.lutmode > 0) {\n      if(d.numInputs != d.lutmode)\n        env->ThrowError(\"Expr lut: number of input clips must be the same as LUT's dimension. LUT is %dD. Passed clip(s): %d\", d.lutmode, d.numInputs);\n    }\n\n    // checking formats\n    const VideoInfo* vi_array[MAX_EXPR_INPUTS] = {};\n    for (int i = 0; i < d.numInputs; i++)\n      if (d.clips[i])\n        vi_array[i] = &d.clips[i]->GetVideoInfo();\n\n\n    int planes_y[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };\n    int planes_r[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A }; // for checking GBR order is OK\n    int *plane_enums = (d.vi.IsYUV() || d.vi.IsYUVA()) ? planes_y : planes_r;\n    const int plane_enum = plane_enums[1]; // for subsampling check U only\n\n    // check all clips against first one\n    for (int i = 0; i < d.numInputs; i++) {\n\n      int *plane_enums_i = (vi_array[i]->IsYUV() || vi_array[i]->IsYUVA()) ? planes_y : planes_r;\n      const int plane_enum_i = plane_enums_i[1];\n\n      if (vi_array[0]->NumComponents() != vi_array[i]->NumComponents() // number of planes should match\n        ||\n        ( !vi_array[0]->IsY() && ( // no subsampling for Y\n           vi_array[0]->GetPlaneWidthSubsampling(plane_enum) != vi_array[i]->GetPlaneWidthSubsampling(plane_enum_i)\n           || vi_array[0]->GetPlaneHeightSubsampling(plane_enum) != vi_array[i]->GetPlaneHeightSubsampling(plane_enum_i)\n          )\n        )\n        || vi_array[0]->width != vi_array[i]->width\n        || vi_array[0]->height != vi_array[i]->height)\n        env->ThrowError(\"Expr: All inputs must have the same number of planes and the same dimensions, subsampling included\");\n\n      if (vi_array[i]->IsRGB() && !vi_array[i]->IsPlanar())\n        env->ThrowError(\"Expr: No packed RGB format allowed for clip #%d, use planar RGB instead\",i+1);\n      if (vi_array[i]->IsYUY2())\n        env->ThrowError(\"Expr: YUY2 format not allowed for clip #%d\", i+1);\n    }\n\n    // format override\n    if (_newformat != nullptr) {\n      int pixel_type = GetPixelTypeFromName(_newformat);\n      if (pixel_type == VideoInfo::CS_UNKNOWN)\n        env->ThrowError(\"Expr: Invalid video format string parameter\");\n      d.vi.pixel_type = pixel_type;\n      if(d.vi.IsRGB() && !d.vi.IsPlanar())\n        env->ThrowError(\"Expr: No packed RGB format allowed\");\n      if (d.vi.IsYUY2())\n        env->ThrowError(\"Expr: YUY2 format not allowed\");\n\n      const bool isSinglePlaneInput = vi_array[0]->IsY();\n\n      // input number of planes >= output planes\n      if (!isSinglePlaneInput && vi_array[0]->NumComponents() < d.vi.NumComponents())\n        env->ThrowError(\"Expr: number of planes in input should be greater than or equal than of output\");\n\n      // subsampling should match\n      int *plane_enums_s = (vi_array[0]->IsYUV() || vi_array[0]->IsYUVA()) ? planes_y : planes_r;\n      int *plane_enums_d = (d.vi.IsYUV() || d.vi.IsYUVA()) ? planes_y : planes_r;\n      for (int p = 0; p < d.vi.NumComponents(); p++) {\n        const int plane_enum_s = isSinglePlaneInput ? plane_enums_s[0] : plane_enums_s[p]; // for Y inputs, reference is Y for each output plane\n        const int plane_enum_d = plane_enums_d[p];\n        if (vi_array[0]->GetPlaneWidthSubsampling(plane_enum_s) != d.vi.GetPlaneWidthSubsampling(plane_enum_d)\n          || vi_array[0]->GetPlaneHeightSubsampling(plane_enum_s) != d.vi.GetPlaneHeightSubsampling(plane_enum_d)) {\n          if(isSinglePlaneInput)\n            env->ThrowError(\"Expr: output must not be a subsampled format for Y-only input(s)\");\n          else\n            env->ThrowError(\"Expr: inputs and output must have the same subsampling\");\n        }\n      }\n\n      vi = d.vi;\n    }\n\n    // check expression count, duplicate omitted expressions from previous one\n    int nexpr = (int)expressions.size();\n    if (nexpr > d.vi.NumComponents()) // ->numPlanes)\n      env->ThrowError(\"Expr: More expressions given than there are planes\");\n\n    std::string expr[4]; // 4th: alpha\n    for (int i = 0; i < nexpr; i++)\n      expr[i] = expressions[i];\n    if (nexpr == 1) {\n      expr[1] = expr[0];\n      expr[2] = expr[0]; // e.g. exprU = exprV = exprY\n    }\n    else if (nexpr == 2) {\n      expr[2] = expr[1]; // e.g. exprV = exprU\n    }\n    if(nexpr <= 3)\n      expr[3] = \"\"; // do not use previous expression to alpha expr. Default: \"\" (copy)\n\n    // default: all clips unused\n    for (int i = 0; i < MAX_EXPR_INPUTS; i++) {\n      d.clipsUsed[i] = false;\n    }\n\n    for (int i = 0; i < d.vi.NumComponents(); i++) {\n      if (!expr[i].empty()) {\n        d.plane[i] = poProcess;\n      }\n      else {\n        if (d.vi.BitsPerComponent() == vi_array[0]->BitsPerComponent()) {\n          d.plane[i] = poCopy; // copy only when target clip format bit depth == 1st clip's bit depth\n          d.planeCopySourceClip[i] = 0; // default source clip from empty expression: first one\n          d.clipsUsed[0] = true; // mark clip to have its GetFrame\n        }\n        else\n          d.plane[i] = poUndefined;\n      }\n    }\n\n    int* plane_enums_d = (d.vi.IsYUV() || d.vi.IsYUVA()) ? planes_y : planes_r;\n\n    d.maxStackSize = 0;\n    for (int i = 0; i < d.vi.NumComponents(); i++) {\n      const int plane_enum_s = plane_enums[i];\n      const int plane_enum = plane_enums_d[i];\n      const int planewidth = d.vi.width >> d.vi.GetPlaneWidthSubsampling(plane_enum);\n      const int planeheight = d.vi.height >> d.vi.GetPlaneHeightSubsampling(plane_enum);\n      const bool chroma = (plane_enum_s == PLANAR_U || plane_enum_s == PLANAR_V);\n      d.maxStackSize = std::max(parseExpression(expr[i], d.ops[i], d.frameprops[i], vi_array, &d.vi, getStoreOp(&d.vi), d.numInputs, planewidth, planeheight, chroma,\n        autoconv_full_scale, autoconv_conv_int, autoconv_conv_float, clamp_float_i, shift_float, d.lutmode,\n        env), d.maxStackSize);\n      foldConstants(d.ops[i]);\n\n      // optimize constant store, change operation to \"fill\"\n      if (d.plane[i] == poProcess && d.ops[i].size() == 2 && d.ops[i][0].op == opLoadConst) {\n        uint32_t op = d.ops[i][1].op;\n        if (op == opStore8 || op == opStore10 || op == opStore12 || op == opStore14 || op == opStore16 || op == opStoreF32)\n        {\n          d.plane[i] = poFill;\n          d.planeFillValue[i] = d.ops[i][0].e.fval;\n        }\n      }\n\n      // optimize single clip letter in expression: Load-Store. Change operation to \"copy\"\n      // no relative loads here\n      if (d.plane[i] == poProcess && d.ops[i].size() == 2 &&\n        (d.ops[i][0].op == opLoadSrc8 || d.ops[i][0].op == opLoadSrc16 || d.ops[i][0].op == opLoadSrcF16 || d.ops[i][0].op == opLoadSrcF32) &&\n        (d.ops[i][1].op == opStore8 || d.ops[i][1].op == opStore10 || d.ops[i][1].op == opStore12 || d.ops[i][1].op == opStore14 || d.ops[i][1].op == opStore16 || d.ops[i][1].op == opStoreF16 || d.ops[i][1].op == opStoreF32))\n      {\n        const int sourceClip = d.ops[i][0].e.ival;\n        // check target vs source bit depth\n        if(d.vi.BitsPerComponent() == vi_array[sourceClip]->BitsPerComponent()) // no 16bit float in avs+\n        {\n          d.plane[i] = poCopy;\n          d.planeCopySourceClip[i] = sourceClip;\n          d.clipsUsed[sourceClip] = true; // mark clip to have its GetFrame\n        }\n      }\n\n      // optimize: mark referenced input clips in order to not call GetFrame for unused inputs\n      if (lutmode == 0) {\n        for (size_t j = 0; j < d.ops[i].size(); j++) {\n          const uint32_t op = d.ops[i][j].op;\n          if (op == opLoadSrc8 || op == opLoadSrc16 || op == opLoadSrcF16 || op == opLoadSrcF32 ||\n            op == opLoadRelSrc8 || op == opLoadRelSrc16 || op == opLoadRelSrcF32)\n          {\n            const int sourceClip = d.ops[i][j].e.ival;\n            d.clipsUsed[sourceClip] = true;\n          }\n        }\n        // input clips with frame property access are used as well\n        for (auto framePropToRead : d.frameprops[i]) {\n          const int sourceClip = framePropToRead.srcIndex;\n          d.clipsUsed[sourceClip] = true;\n        }\n      }\n\n      if (lutmode > 0) {\n        for (int i = 0; i < lutmode; i++) // lut: always get. Needed for the init\n          d.clipsUsed[i] = true;\n        // * bit depth of input clip(s) and output must match\n        bool lut_ok = \n          (d.numInputs == 1\n            && d.vi.BitsPerComponent() == vi_array[0]->BitsPerComponent())\n          ||\n          (\n            d.numInputs == 2\n            && d.vi.BitsPerComponent() == vi_array[0]->BitsPerComponent()\n            && d.vi.BitsPerComponent() == vi_array[1]->BitsPerComponent()\n            );\n        if(!lut_ok)\n          env->ThrowError(\"Expr: error in lut mode: input bit depths and output bit depth must be the same\");\n      }\n\n\n#ifdef INTEL_INTRINSICS\n      // Check CPU instuction level constraints:\n      // opLoadRel8/16/32: minimum SSSE3 (pshufb, alignr) for SIMD, and no AVX2 support\n      // round, floor, ceil, trunc: minimun SSE4.1\n      // Trig.func: C only\n      d.planeOptAvx2[i] = optAvx2;\n      d.planeOptSSE2[i] = optSSE2;\n      for (size_t j = 0; j < d.ops[i].size(); j++) {\n        const uint32_t op = d.ops[i][j].op;\n        if (op == opLoadRelSrc8 || op == opLoadRelSrc16 || op == opLoadRelSrcF32)\n        {\n          d.planeOptAvx2[i] = false; // avx2 path not implemented\n          if(!(env->GetCPUFlags() & CPUF_SSSE3)) // required minimum (pshufb, alignr)\n            d.planeOptSSE2[i] = false;\n        }\n        // some trig.functions C only, except Sin and Cos and Atan2 and tan\n        if (op == opAsin || op == opAcos || op == opAtan) {\n          d.planeOptAvx2[i] = false;\n          d.planeOptSSE2[i] = false;\n          break;\n        }\n        // round, trunc, ceil: minimum of SSE4.1\n        if (op == opRound || op == opFloor || op == opCeil || op == opTrunc ) {\n          if (!(env->GetCPUFlags() & CPUF_SSE4_1)) // required minimum (_mm_round_ps...)\n            d.planeOptSSE2[i] = false;\n          break;\n        }\n      }\n#endif\n\n    }\n\n#ifdef VS_TARGET_CPU_X86\n    // optAvx2 can only disable avx2 when available\n\n    for (int i = 0; i < d.vi.NumComponents(); i++) {\n      if (d.plane[i] == poProcess) {\n\n        const int plane_enum = plane_enums_d[i];\n        int planewidth = d.vi.width >> d.vi.GetPlaneWidthSubsampling(plane_enum);\n        int planeheight = d.vi.height >> d.vi.GetPlaneHeightSubsampling(plane_enum);\n\n        const int planewidth_real_or_lut = (lutmode == 0) ? planewidth: (1 << d.vi.BitsPerComponent());\n        // to decide if partial chunk is left from the width at the end of the 4/8/16 pixel processing unit big main loops\n        // when lut: fake width (x size of lut table) of the lut-init\n\n        if (optAvx2 && d.planeOptAvx2[i]) {\n\n          // avx2\n          ExprEvalAvx2 ExprObj(d.ops[i], d.numInputs, env->GetCPUFlags(), planewidth_real_or_lut, planeheight, optSingleMode);\n          if (ExprObj.GetCode(true) && ExprObj.GetCodeSize()) { // PF modded jitasm. true: epilog with vmovaps, and vzeroupper\n#ifdef VS_TARGET_OS_WINDOWS\n            d.proc[i] = (ExprData::ProcessLineProc)VirtualAlloc(nullptr, ExprObj.GetCodeSize(), MEM_COMMIT, PAGE_EXECUTE_READWRITE);\n#else\n            d.proc[i] = (ExprData::ProcessLineProc)mmap(nullptr, ExprObj.GetCodeSize(), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, 0, 0);\n#endif\n            memcpy((void *)d.proc[i], ExprObj.GetCode(), ExprObj.GetCodeSize());\n          }\n        }\n        else if (optSSE2 && d.planeOptSSE2[i]) {\n          // sse2, sse4\n          ExprEval ExprObj(d.ops[i], d.numInputs, env->GetCPUFlags(), planewidth_real_or_lut, planeheight, optSingleMode);\n          if (ExprObj.GetCode() && ExprObj.GetCodeSize()) {\n#ifdef VS_TARGET_OS_WINDOWS\n            d.proc[i] = (ExprData::ProcessLineProc)VirtualAlloc(nullptr, ExprObj.GetCodeSize(), MEM_COMMIT, PAGE_EXECUTE_READWRITE);\n#else\n            d.proc[i] = (ExprData::ProcessLineProc)mmap(nullptr, ExprObj.GetCodeSize(), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, 0, 0);\n#endif\n            memcpy((void *)d.proc[i], ExprObj.GetCode(), ExprObj.GetCodeSize());\n          }\n        }\n\n      } // if plane is to be processed\n    }\n#ifdef VS_TARGET_OS_WINDOWS\n    if (optSSE2)\n      FlushInstructionCache(GetCurrentProcess(), nullptr, 0);\n#endif\n#endif\n\n    if (lutmode > 0)\n      calculate_lut(env);\n  }\n  catch (std::runtime_error &e) {\n    for (int i = 0; i < MAX_EXPR_INPUTS; i++)\n      d.clips[i] = nullptr; //  vsapi->freeNode(d->node[i]);\n    std::string s = \"Expr: \";\n    s += e.what();\n    env->ThrowError(s.c_str());\n    return;\n  }\n\n}\n\n#ifdef XP_TLS\n#ifdef MSVC_PURE\n// end of v141_xp toolset ultra slow build workaround\n#pragma optimize(\"\", on)\n#endif\n#endif\n"
  },
  {
    "path": "avs_core/filters/exprfilter/exprfilter.h",
    "content": "#ifndef __Exprfilter_h\n#define __Exprfilter_h\n\n#include <avisynth.h>\n#include <mutex>\n#ifdef AVS_POSIX\n#include <sys/mman.h>\n#endif\n\n#define MAX_C_VECT 16 // C Expr part: 16*float has still have benefit, less interpreter overhead.\n\n#define MAX_EXPR_INPUTS 26\n#define INTERNAL_VARIABLES 6\n#define MAX_FRAMEPROP_VARIABLES 64\n#define MAX_USER_VARIABLES 128\n\n// indexing RWPTR array (pointer sized elements)\n#define RWPTR_START_OF_OUTPUT 0   // 1\n#define RWPTR_START_OF_XCOUNTER 1 // 1\n#define RWPTR_START_OF_INPUTS 2   // count = 26\n#define RWPTR_START_OF_PADDING 4  // padding to have 32 pointers (rfu for 8 ptr/cycle ymm simd)\n#define RWPTR_START_OF_STRIDES 32 // count = 26 for relative_y\n#define RWPTR_START_OF_INTERNAL_VARIABLES 58 // count = 6\n\n// special frame-by-frame variables (incl. frame properties) occupy only float size\n#define INTERNAL_VAR_CURRENT_FRAME 0\n#define INTERNAL_VAR_RELTIME 1\n#define INTERNAL_VAR_RFU2 2\n#define INTERNAL_VAR_RFU3 3\n#define INTERNAL_VAR_RFU4 4\n#define INTERNAL_VAR_RFU5 5\n#define INTERNAL_VAR_FRAMEPROP_VARIABLES_START 6\n#define RWPTR_START_OF_INTERNAL_FRAMEPROP_VARIABLES (RWPTR_START_OF_INTERNAL_VARIABLES + INTERNAL_VAR_FRAMEPROP_VARIABLES_START) // count = 256\n\n// pad to 32 bytes boundary in x86: 64 * sizeof(pointer) is 32 byte aligned\n#define RWPTR_START_OF_USERVARIABLES (RWPTR_START_OF_INTERNAL_FRAMEPROP_VARIABLES + MAX_FRAMEPROP_VARIABLES) // count = max.256 (for 2*ymm sized variables)\n#define RWPTR_SIZE (RWPTR_START_OF_USERVARIABLES + MAX_USER_VARIABLES * (2*32 / sizeof(void *)))\n\nstruct split1 {\n  enum empties_t { empties_ok, no_empties };\n};\n\ntemplate <typename Container>\nContainer& split(\n  Container& result,\n  const typename Container::value_type& s,\n  const typename Container::value_type& delimiters,\n  split1::empties_t empties = split1::empties_ok)\n{\n  result.clear();\n  size_t current;\n  size_t next = (size_t)-1;\n  do {\n    if (empties == split1::no_empties) {\n      next = s.find_first_not_of(delimiters, next + 1);\n      if (next == Container::value_type::npos) break;\n      next -= 1;\n    }\n    current = next + 1;\n    next = s.find_first_of(delimiters, current);\n    result.push_back(s.substr(current, next - current));\n  } while (next != Container::value_type::npos);\n  return result;\n}\n\ntypedef enum {\n  opLoadSrc8, opLoadSrc16, opLoadSrcF32, opLoadSrcF16,\n  opLoadRelSrc8, opLoadRelSrc16, opLoadRelSrcF32,\n  opLoadConst,\n  opLoadSpatialX, opLoadSpatialY,\n  opLoadInternalVar,\n  opStore8, opStore10, opStore12, opStore14, opStore16, opStoreF32, opStoreF16, // avs+: 10,12,14 bit store\n  opDup, opSwap,\n  opAdd, opSub, opMul, opDiv, opMax, opMin, opSqrt, opAbs, opSgn,\n  opFmod,\n  opGt, opLt, opEq, opNotEq, opLE, opGE, opTernary,\n  opAnd, opOr, opXor, opNeg, opNegSign,\n  opExp, opLog, opPow,\n  opSin, opCos, opTan, opAsin, opAcos, opAtan, opAtan2,\n  opClip, opRound, opFloor, opCeil, opTrunc,\n  opStoreVar, opLoadVar, opLoadFramePropVar, opStoreVarAndDrop1\n} SOperation;\n\nunion ExprUnion {\n  float fval;\n  int32_t ival;\n  uint32_t uval;\n  constexpr ExprUnion() : uval{} {}\n  constexpr ExprUnion(int32_t _i) : ival(_i) {}\n  constexpr ExprUnion(uint32_t _u) : uval(_u) {}\n  constexpr ExprUnion(float _f) : fval(_f) {}\n} ;\n\nstruct ExprOp {\n  ExprUnion e;\n  uint32_t op;\n  int dx, dy;\n  ExprOp(SOperation op, float val) : op(op), dx(0), dy(0) {\n    e.fval = val;\n  }\n  ExprOp(SOperation op, int32_t val = 0) : op(op), dx(0), dy(0) {\n    e.ival = val;\n  }\n  ExprOp(SOperation op, int32_t val, int dx, int dy) : op(op), dx(dx), dy(dy) {\n    e.ival = val;\n  }\n};\n\nstruct ExprFramePropData {\n  int srcIndex;\n  std::string name;\n  int var_index;\n  float value;\n};\n\nenum PlaneOp {\n  poProcess, poCopy, poUndefined, poFill\n};\n\nstruct ExprData {\n#ifdef __VAPOURSYNTH__\n  VSNodeRef *node[MAX_EXPR_INPUTS];\n  VSVideoInfo vi;\n#else\n  PClip clips[MAX_EXPR_INPUTS];\n  VideoInfo vi;\n#endif\n  bool clipsUsed[MAX_EXPR_INPUTS]; // not doing GetFrame unreferenced input clips\n  std::vector<ExprOp> ops[4]; // 4th: alpha\n  std::vector<ExprFramePropData> frameprops[4];\n  int plane[4];\n  float planeFillValue[4]; // optimize: fill plane with const\n  int planeCopySourceClip[4]; // optimize: copy plane from which clip\n  bool planeOptAvx2[4]; // instruction set constraints\n  bool planeOptSSE2[4];\n\n  int lutmode; // 0: no, 1:1D (lutx), 2:2D (lutxy)\n  uint8_t* luts[4]; // different lut tables, reusable by multiple planes\n  // int planeLutIndex[4]; // which luts is used by the plane. todo: when luts are the same for different planes\n  \n  size_t maxStackSize;\n  int numInputs;\n#ifdef VS_TARGET_CPU_X86\n  typedef void(*ProcessLineProc)(void *rwptrs, intptr_t ptroff[RWPTR_SIZE], intptr_t niter, uint32_t spatialY);\n  ProcessLineProc proc[4]; // 4th: alpha\n  ExprData() : clips(), vi(), proc() {}\n#else\n  ExprData() : clips(), vi() {}\n#endif\n  ~ExprData() {\n#ifdef VS_TARGET_CPU_X86\n    for (int i = 0; i < 4; i++) // 4th: alpha\n#ifdef VS_TARGET_OS_WINDOWS\n      VirtualFree((LPVOID)proc[i], 0, MEM_RELEASE);\n#else\n      munmap((void *)proc[i], 0);\n#endif\n#endif\n  }\n};\n\nclass Exprfilter : public IClip\n/**\n  *\n**/\n{\nprivate:\n  std::vector<PClip> children;\n  std::vector<std::string> expressions;\n  VideoInfo vi;\n  ExprData d;\n  const bool optAvx2; // disable avx2 path\n  const bool optSingleMode; // generate asm code using only one XMM/YMM register set instead of two\n  const bool optSSE2; // disable simd path\n  const bool optVectorC; // if non-SIMD C path, then this goes to a vectorization friendly implementation\n\n  // scale_inputs related settings\n  const std::string scale_inputs;\n  bool autoconv_full_scale;\n  bool autoconv_conv_int;\n  bool autoconv_conv_float;\n  const int clamp_float_i;\n  int lutmode;\n\n  // special internal flag since v2.2.20: set when scale_inputs is \"floatUV\"\n  // like in masktools 2.2.20+, preshifts chroma -0.5..+0.5 to 0..1.0 range and then shifts the result back.\n  bool shift_float;\n\n  void preReadFrameProps(int plane, std::vector<PVideoFrame>& src, IScriptEnvironment* env);\n  void calculate_lut(IScriptEnvironment *env);\npublic:\n  Exprfilter(const std::vector<PClip>& _child_array, const std::vector<std::string>& _expr_array, const char *_newformat, const bool _optAvx2,\n    const bool _optSingleMode2, const bool _optSSE2, const bool _optVectorC, const std::string _scale_inputs, const int _clamp_float, const int _lutmode, IScriptEnvironment *env);\n  void processFrame(int plane, int w, int h, int pixels_per_iter, float framecount, float relative_time, int numInputs,\n    uint8_t*& dstp, int dst_stride,\n    std::vector<const uint8_t*>& srcp, std::vector<int>& src_stride, std::vector<intptr_t>& ptroffsets, std::vector<const uint8_t*>& srcp_orig);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment *env);\n  ~Exprfilter();\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\n  inline void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) {\n    children[0]->GetAudio(buf, start, count, env);\n  }\n\n  inline const VideoInfo& __stdcall GetVideoInfo() {\n    return vi;\n  }\n\n  inline bool __stdcall GetParity(int n) {\n    return children[0]->GetParity(n);\n  }\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n};\n\n#endif //__Exprfilter_h\n"
  },
  {
    "path": "avs_core/filters/exprfilter/jitasm.h",
    "content": "// Copyright (c) 2009-2011, Hikaru Inoue, Akihiro Yamasaki,\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//    * Redistributions of source code must retain the above copyright\n//      notice, this list of conditions and the following disclaimer.\n//    * Redistributions in binary form must reproduce the above\n//      copyright notice, this list of conditions and the following\n//      disclaimer in the documentation and/or other materials provided\n//      with the distribution.\n//    * The names of the contributors may not be used to endorse or promote\n//      products derived from this software without specific prior written\n//      permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Changes 2017 by pinterf\n// - AVX friendly prolog/epilog with vzeroupper\n// - Aligned stack slots for ymm spill variables\n// - VEX encoded aligned store and load for temporary xmm/ymm registers\n// - Fix: false codegen when rearranging multiple working registers in MoveGenerator by\n//   tracking real register usage for an xchg sequence\n\n#include <stdint.h>\n\n#pragma once\n#ifndef JITASM_H\n#define JITASM_H\n\n#if defined(_WIN32)\n#define JITASM_WIN\t\t// Windows\n#endif\n\n#if (defined(_WIN64) && (defined(_M_AMD64) || defined(_M_X64))) || defined(__x86_64__)\n#define JITASM64\n#endif\n\n#if defined(__GNUC__)\n#define JITASM_GCC\n#endif\n\n#if !defined(JITASM_MMINTRIN)\n\t#if !defined(__GNUC__) || defined(__MMX__)\n\t#define JITASM_MMINTRIN 1\n\t#else\n\t#define JITASM_MMINTRIN 0\n\t#endif\n#endif\n#if !defined(JITASM_XMMINTRIN)\n\t#if !defined(__GNUC__) || defined(__SSE__)\n\t#define JITASM_XMMINTRIN 1\n\t#else\n\t#define JITASM_XMMINTRIN 0\n\t#endif\n#endif\n#if !defined(JITASM_EMMINTRIN)\n\t#if !defined(__GNUC__) || defined(__SSE2__)\n\t#define JITASM_EMMINTRIN 1\n\t#else\n\t#define JITASM_EMMINTRIN 0\n\t#endif\n#endif\n\n\n#include <string>\n#include <deque>\n#include <vector>\n#include <map>\n#include <algorithm>\n#include <string.h>\n\n#if defined(JITASM_WIN)\n#include <windows.h>\n#else\n#include <unistd.h>\n#include <sys/types.h>\n#include <sys/mman.h>\n#endif\n\n#if JITASM_MMINTRIN\n\t#include <mmintrin.h>\n#endif\n#if JITASM_XMMINTRIN\n\t#include <xmmintrin.h>\n#endif\n#if JITASM_EMMINTRIN\n\t#include <emmintrin.h>\n#endif\n\n#if _MSC_VER >= 1400\t// VC8 or later\n#include <intrin.h>\n#endif\n\n#if defined(JITASM_GCC)\n#define JITASM_ATTRIBUTE_WEAK\n// #define JITASM_ATTRIBUTE_WEAK __attribute__((weak))\n// PF 20211013 remark, intentionally kept here:\n// Do not use weak attribute! GCC Bug?\n// With weak attributes mingw64 g++ 10.3 will miss a few initializations of structs during DLL load,\n// for example these initializations will never be called(!):\n//   Reg8 JITASM_ATTRIBUTE_WEAK Frontend::r8b  = Reg8(R8B);\n//   YmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm8  = YmmReg(YMM8);\n//   (list not complete).\n// But most horribly: after\n//   Reg32 JITASM_ATTRIBUTE_WEAK Frontend::r13d = Reg32(R13D);\n// but before\n//   Reg32 JITASM_ATTRIBUTE_WEAK Frontend::r14d = Reg32(R14D);\n// it will overwrite some other, already initialized variable areas at a totally different \n// memory space, some hundred bytes before.\n// Anyway, 'weak' is probably not needed, in ExprFilter use case we do not want a different\n// implementations of these functions.\n#elif defined(_MSC_VER)\n#define JITASM_ATTRIBUTE_WEAK __declspec(selectany)\n#else\n#define JITASM_ATTRIBUTE_WEAK\n#endif\n\n#if defined(_MSC_VER)\n#pragma warning( push )\n#pragma warning( disable : 4127 )\t// conditional expression is constant.\n#pragma warning( disable : 4201 )\t// nonstandard extension used : nameless struct/union\n#endif\n\n#if defined(JITASM_GCC)\n#pragma GCC diagnostic ignored \"-Wignored-attributes\"\n#endif\n\n#ifdef ASSERT\n#define JITASM_ASSERT ASSERT\n#else\n#include <assert.h>\n#define JITASM_ASSERT assert\n#endif\n\n//#define JITASM_DEBUG_DUMP\n#ifdef JITASM_DEBUG_DUMP\n\t#include <stdio.h>\n\t#if defined(JITASM_GCC)\n\t#define JITASM_TRACE\tprintf\n\t#else\n\t#define JITASM_TRACE\tjitasm::detail::Trace\n\t#endif\n#elif defined(JITASM_GCC)\n\t#define JITASM_TRACE(...)\t((void)0)\n#else\n\t#define JITASM_TRACE\t__noop\n#endif\n\nnamespace jitasm\n{\n\ntypedef signed char\t\t\tsint8;\ntypedef signed short\t\tsint16;\ntypedef signed int\t\t\tsint32;\ntypedef unsigned char\t\tuint8;\ntypedef unsigned short\t\tuint16;\ntypedef unsigned int\t\tuint32;\n#if defined(JITASM_GCC)\ntypedef signed long long\tsint64;\ntypedef unsigned long long\tuint64;\n#else\ntypedef signed __int64\t\tsint64;\ntypedef unsigned __int64\tuint64;\n#endif\n\ntemplate<typename T> inline void avoid_unused_warn(const T&) {}\n\nnamespace detail\n{\n#if defined(JITASM_GCC)\n\tinline long interlocked_increment(long *addend)\t\t\t\t{ return __sync_add_and_fetch(addend, 1); }\n\tinline long interlocked_decrement(long *addend)\t\t\t\t{ return __sync_sub_and_fetch(addend, 1); }\n\tinline long interlocked_exchange(long *target, long value)\t{ return __sync_lock_test_and_set(target, value); }\n#elif defined(JITASM_WIN)\n\tinline long interlocked_increment(long *addend)\t\t\t\t{ return _InterlockedIncrement(addend); }\n\tinline long interlocked_decrement(long *addend)\t\t\t\t{ return _InterlockedDecrement(addend); }\n\tinline long interlocked_exchange(long *target, long value)\t{ return _InterlockedExchange(target, value); }\n#endif\n}\t// namespace detail\n\n/// Physical register ID\nenum PhysicalRegID\n{\n\tINVALID=0x0FFFFFFF,\n\tEAX=0, ECX, EDX, EBX, ESP, EBP, ESI, EDI, R8D, R9D, R10D, R11D, R12D, R13D, R14D, R15D,\n\tAL=0, CL, DL, BL, AH, CH, DH, BH, R8B, R9B, R10B, R11B, R12B, R13B, R14B, R15B,\n\tAX=0, CX, DX, BX, SP, BP, SI, DI, R8W, R9W, R10W, R11W, R12W, R13W, R14W, R15W,\n\tRAX=0, RCX, RDX, RBX, RSP, RBP, RSI, RDI, R8, R9, R10, R11, R12, R13, R14, R15,\n\tST0=0, ST1, ST2, ST3, ST4, ST5, ST6, ST7,\n\tMM0=0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,\n\tXMM0=0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15,\n\tYMM0=0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7, YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15,\n};\n\nenum\n{\n\t/** \\var NUM_OF_PHYSICAL_REG\n\t * Number of physical register\n\t */\n\t/** \\var SIZE_OF_GP_REG\n\t * Size of general-purpose register\n\t */\n#ifdef JITASM64\n\tNUM_OF_PHYSICAL_REG = 16,\n\tSIZE_OF_GP_REG = 8\n#else\n\tNUM_OF_PHYSICAL_REG = 8,\n\tSIZE_OF_GP_REG = 4\n#endif\n};\n\n/// Register type\nenum RegType\n{\n\tR_TYPE_GP,\t\t\t\t///< General purpose register\n\tR_TYPE_MMX,\t\t\t\t///< MMX register\n\tR_TYPE_XMM,\t\t\t\t///< XMM register\n\tR_TYPE_YMM,\t\t\t\t///< YMM register\n\tR_TYPE_FPU,\t\t\t\t///< FPU register\n\tR_TYPE_SYMBOLIC_GP,\t\t///< Symbolic general purpose register\n\tR_TYPE_SYMBOLIC_MMX,\t///< Symbolic MMX register\n\tR_TYPE_SYMBOLIC_XMM,\t///< Symbolic XMM register\n\tR_TYPE_SYMBOLIC_YMM\t\t///< Symbolic YMM register\n};\n\n/// Register identifier\nstruct RegID\n{\n\tunsigned type : 4;\t// RegType\n\tunsigned id : 28;\t\t///< PhysicalRegID or symbolic register id\n\n\tbool operator==(const RegID& rhs) const {return type == rhs.type && id == rhs.id;}\n\tbool operator!=(const RegID& rhs) const {return !(*this == rhs);}\n\tbool operator<(const RegID& rhs) const {return type != rhs.type ? type < rhs.type : id < rhs.id;}\n\tbool IsInvalid() const\t{return type == R_TYPE_GP && id == INVALID;}\n\tbool IsSymbolic() const {return type == R_TYPE_SYMBOLIC_GP || type == R_TYPE_SYMBOLIC_MMX || type == R_TYPE_SYMBOLIC_XMM || type == R_TYPE_SYMBOLIC_YMM;}\n\tRegType GetType() const {return static_cast<RegType>(type);}\n\n\tstatic RegID Invalid() {\n\t\tRegID reg;\n\t\treg.type = R_TYPE_GP;\n\t\treg.id = INVALID;\n\t\treturn reg;\n\t}\n\tstatic RegID CreatePhysicalRegID(RegType type_, PhysicalRegID id_) {\n\t\tRegID reg;\n\t\treg.type = type_;\n\t\treg.id = id_;\n\t\treturn reg;\n\t}\n\tstatic RegID CreateSymbolicRegID(RegType type_) {\n\t\tstatic long s_id = 0;\n\t\tRegID reg;\n\t\treg.type = type_;\n\t\treg.id = static_cast<unsigned>(detail::interlocked_increment(&s_id));\n\t\treturn reg;\n\t}\n};\n\n/// Operand type\nenum OpdType\n{\n\tO_TYPE_NONE,\n\tO_TYPE_REG,\n\tO_TYPE_MEM,\n\tO_TYPE_IMM,\n\tO_TYPE_TYPE_MASK\t\t= 0x03,\n\n\tO_TYPE_DUMMY\t= 1 << 2,\t///< The operand which has this flag is not encoded. This is for register allocator.\n\tO_TYPE_READ\t\t= 1 << 3,\t///< The operand is used for reading.\n\tO_TYPE_WRITE\t= 1 << 4\t///< The operand is used for writing.\n};\n\n/// Operand size\nenum OpdSize\n{\n\tO_SIZE_8,\n\tO_SIZE_16,\n\tO_SIZE_32,\n\tO_SIZE_64,\n\tO_SIZE_80,\n\tO_SIZE_128,\n\tO_SIZE_224,\n\tO_SIZE_256,\n\tO_SIZE_864,\n\tO_SIZE_4096\n};\n\nnamespace detail\n{\n#pragma pack(push, 1)\n\n\t/// Operand base class\n\tstruct Opd\n\t{\n\t\tuint8 opdtype_;\t// OpdType\n\t\tuint8 opdsize_;\t// OpdSize\n\n\t\tunion {\n\t\t\t// REG\n\t\t\tstruct {\n\t\t\t\tRegID reg_;\n\t\t\t\tuint32 reg_assignable_;\n\t\t\t};\n\t\t\t// MEM\n\t\t\tstruct {\n\t\t\t\tRegID\tbase_;\n\t\t\t\tRegID\tindex_;\n\t\t\t\tsint64\tscale_;\n\t\t\t\tsint64\tdisp_;\n\t\t\t\tuint8\tbase_size_  : 4;\t\t// OpdSize\n\t\t\t\tuint8\tindex_size_ : 4;\t// OpdSize\n\t\t\t};\n\t\t\t// IMM\n\t\t\tsint64 imm_;\n\t\t};\n\n\t\t/// NONE\n\t\tOpd() : opdtype_(O_TYPE_NONE) {}\n\t\t/// REG\n\t\tOpd(OpdSize opdsize, const RegID& reg, uint32 reg_assignable = 0xFFFFFFFF) : opdtype_(O_TYPE_REG), opdsize_(static_cast<uint8>(opdsize)), reg_(reg), reg_assignable_(reg_assignable) {}\n\t\t/// MEM\n\t\tOpd(OpdSize opdsize, OpdSize base_size, OpdSize index_size, const RegID& base, const RegID& index, sint64 scale, sint64 disp)\n\t\t\t: opdtype_(O_TYPE_MEM), opdsize_(static_cast<uint8>(opdsize)), base_(base), index_(index), scale_(scale), disp_(disp), base_size_(static_cast<uint8>(base_size)), index_size_(static_cast<uint8>(index_size)) {}\n\tprotected:\n\t\t/// IMM\n\t\texplicit Opd(OpdSize opdsize, sint64 imm) : opdtype_(O_TYPE_IMM), opdsize_(static_cast<uint8>(opdsize)), imm_(imm) {}\n\n\tpublic:\n\t\tbool\tIsNone() const\t\t{return (opdtype_ & O_TYPE_TYPE_MASK) == O_TYPE_NONE;}\n\t\tbool\tIsReg() const\t\t{return (opdtype_ & O_TYPE_TYPE_MASK) == O_TYPE_REG;}\n\t\tbool\tIsGpReg() const\t\t{return IsReg() && (reg_.type == R_TYPE_GP || reg_.type == R_TYPE_SYMBOLIC_GP);}\n\t\tbool\tIsFpuReg() const\t{return IsReg() && reg_.type == R_TYPE_FPU;}\n\t\tbool\tIsMmxReg() const\t{return IsReg() && (reg_.type == R_TYPE_MMX || reg_.type == R_TYPE_SYMBOLIC_MMX);}\n\t\tbool\tIsXmmReg() const\t{return IsReg() && (reg_.type == R_TYPE_XMM || reg_.type == R_TYPE_SYMBOLIC_XMM);}\n\t\tbool\tIsYmmReg() const\t{return IsReg() && (reg_.type == R_TYPE_YMM || reg_.type == R_TYPE_SYMBOLIC_YMM);}\n\t\tbool\tIsMem() const\t\t{return (opdtype_ & O_TYPE_TYPE_MASK) == O_TYPE_MEM;}\n\t\tbool\tIsImm() const\t\t{return (opdtype_ & O_TYPE_TYPE_MASK) == O_TYPE_IMM;}\n\t\tbool\tIsDummy() const\t\t{return (opdtype_ & O_TYPE_DUMMY) != 0;}\n\t\tbool\tIsRead() const\t\t{return (opdtype_ & O_TYPE_READ) != 0;}\n\t\tbool\tIsWrite() const\t\t{return (opdtype_ & O_TYPE_WRITE) != 0;}\n\n\t\tOpdType GetType() const\t\t{return static_cast<OpdType>(opdtype_);}\n\t\tOpdSize\tGetSize() const\t\t{return static_cast<OpdSize>(opdsize_);}\n\t\tOpdSize\tGetAddressBaseSize() const\t{return static_cast<OpdSize>(base_size_);}\n\t\tOpdSize\tGetAddressIndexSize() const\t{return static_cast<OpdSize>(index_size_);}\n\t\tRegID\tGetReg() const\t\t{JITASM_ASSERT(IsReg()); return reg_;}\n\t\tRegID\tGetBase() const\t\t{JITASM_ASSERT(IsMem()); return base_;}\n\t\tRegID\tGetIndex() const\t{JITASM_ASSERT(IsMem()); return index_;}\n\t\tsint64\tGetScale() const\t{JITASM_ASSERT(IsMem()); return scale_;}\n\t\tsint64\tGetDisp() const\t\t{JITASM_ASSERT(IsMem()); return disp_;}\n\t\tsint64\tGetImm() const\t\t{JITASM_ASSERT(IsImm()); return imm_;}\n\n\t\tbool operator==(const Opd& rhs) const\n\t\t{\n\t\t\tif ((opdtype_ & O_TYPE_TYPE_MASK) != (rhs.opdtype_ & O_TYPE_TYPE_MASK) || opdsize_ != rhs.opdsize_) {return false;}\n\t\t\tif (IsReg()) {return reg_ == rhs.reg_ && reg_assignable_ == rhs.reg_assignable_;}\n\t\t\tif (IsMem()) {return base_ == rhs.base_ && index_ == rhs.index_ && scale_ == rhs.scale_ && disp_ == rhs.disp_ && base_size_ == rhs.base_size_ && index_size_ == rhs.index_size_;}\n\t\t\tif (IsImm()) {return imm_ == rhs.imm_;}\n\t\t\treturn true;\n\t\t}\n\t\tbool operator!=(const Opd& rhs) const {return !(*this == rhs);}\n\t};\n\n#pragma pack(pop)\n\n\t/// Add O_TYPE_DUMMY to the specified operand\n\tinline Opd Dummy(const Opd& opd)\n\t{\n\t\tOpd o(opd);\n\t\to.opdtype_ = static_cast<OpdType>(static_cast<int>(o.opdtype_) | O_TYPE_DUMMY);\n\t\treturn o;\n\t}\n\n\t/// Add O_TYPE_DUMMY to the specified operand and constraint of register assignment\n\tinline Opd Dummy(const Opd& opd, const Opd& constraint)\n\t{\n\t\tJITASM_ASSERT(opd.IsReg() && (opd.opdtype_ & O_TYPE_TYPE_MASK) == (constraint.opdtype_ & O_TYPE_TYPE_MASK) && !constraint.GetReg().IsSymbolic());\n\t\tOpd o(opd);\n\t\to.opdtype_ = static_cast<OpdType>(static_cast<int>(o.opdtype_) | O_TYPE_DUMMY);\n\t\to.reg_assignable_ = (1 << constraint.reg_.id);\n\t\treturn o;\n\t}\n\n\t/// Add O_TYPE_READ to the specified operand\n\tinline Opd R(const Opd& opd)\n\t{\n\t\tOpd o(opd);\n\t\to.opdtype_ = static_cast<OpdType>(static_cast<int>(o.opdtype_) | O_TYPE_READ);\n\t\treturn o;\n\t}\n\n\t/// Add O_TYPE_WRITE to the specified operand\n\tinline Opd W(const Opd& opd)\n\t{\n\t\tOpd o(opd);\n\t\to.opdtype_ = static_cast<OpdType>(static_cast<int>(o.opdtype_) | O_TYPE_WRITE);\n\t\treturn o;\n\t}\n\n\t/// Add O_TYPE_READ | O_TYPE_WRITE to the specified operand\n\tinline Opd RW(const Opd& opd)\n\t{\n\t\tOpd o(opd);\n\t\to.opdtype_ = static_cast<OpdType>(static_cast<int>(o.opdtype_) | O_TYPE_READ | O_TYPE_WRITE);\n\t\treturn o;\n\t}\n\n\ttemplate<int Size> inline OpdSize ToOpdSize();\n\ttemplate<> inline OpdSize ToOpdSize<8>() {return O_SIZE_8;}\n\ttemplate<> inline OpdSize ToOpdSize<16>() {return O_SIZE_16;}\n\ttemplate<> inline OpdSize ToOpdSize<32>() {return O_SIZE_32;}\n\ttemplate<> inline OpdSize ToOpdSize<64>() {return O_SIZE_64;}\n\ttemplate<> inline OpdSize ToOpdSize<80>() {return O_SIZE_80;}\n\ttemplate<> inline OpdSize ToOpdSize<128>() {return O_SIZE_128;}\n\ttemplate<> inline OpdSize ToOpdSize<224>() {return O_SIZE_224;}\n\ttemplate<> inline OpdSize ToOpdSize<256>() {return O_SIZE_256;}\n\ttemplate<> inline OpdSize ToOpdSize<864>() {return O_SIZE_864;}\n\ttemplate<> inline OpdSize ToOpdSize<4096>() {return O_SIZE_4096;}\n\n\ttemplate<int Size>\n\tstruct OpdT : Opd\n\t{\n\t\t/// NONE\n\t\tOpdT() : Opd() {}\n\t\t/// REG\n\t\texplicit OpdT(const RegID& reg, uint32 reg_assignable = 0xFFFFFFFF) : Opd(ToOpdSize<Size>(), reg, reg_assignable) {}\n\t\t/// MEM\n\t\tOpdT(OpdSize base_size, OpdSize index_size, const RegID& base, const RegID& index, sint64 scale, sint64 disp)\n\t\t\t: Opd(ToOpdSize<Size>(), base_size, index_size, base, index, scale, disp) {}\n\tprotected:\n\t\t/// IMM\n\t\tOpdT(sint64 imm) : Opd(ToOpdSize<Size>(), imm) {}\n\t};\n\n}\t// namespace detail\n\ntypedef detail::OpdT<8>\t\tOpd8;\ntypedef detail::OpdT<16>\tOpd16;\ntypedef detail::OpdT<32>\tOpd32;\ntypedef detail::OpdT<64>\tOpd64;\ntypedef detail::OpdT<80>\tOpd80;\ntypedef detail::OpdT<128>\tOpd128;\ntypedef detail::OpdT<224>\tOpd224;\t\t// FPU environment\ntypedef detail::OpdT<256>\tOpd256;\ntypedef detail::OpdT<864>\tOpd864;\t\t// FPU state\ntypedef detail::OpdT<4096>\tOpd4096;\t// FPU, MMX, XMM, MXCSR state\n\n/// 8bit general purpose register\nstruct Reg8 : Opd8 {\n\tReg8() : Opd8(RegID::CreateSymbolicRegID(R_TYPE_SYMBOLIC_GP), 0xFFFFFF0F) {}\n\texplicit Reg8(PhysicalRegID id) : Opd8(RegID::CreatePhysicalRegID(R_TYPE_GP, id)) {}\n};\n/// 16bit general purpose register\nstruct Reg16 : Opd16 {\n\tReg16() : Opd16(RegID::CreateSymbolicRegID(R_TYPE_SYMBOLIC_GP)) {}\n\texplicit Reg16(PhysicalRegID id) : Opd16(RegID::CreatePhysicalRegID(R_TYPE_GP, id)) {}\n};\n/// 32bit general purpose register\nstruct Reg32 : Opd32 {\n\tReg32() : Opd32(RegID::CreateSymbolicRegID(R_TYPE_SYMBOLIC_GP)) {}\n\texplicit Reg32(PhysicalRegID id) : Opd32(RegID::CreatePhysicalRegID(R_TYPE_GP, id)) {}\n};\n#ifdef JITASM64\n/// 64bit general purpose register\nstruct Reg64 : Opd64 {\n\tReg64() : Opd64(RegID::CreateSymbolicRegID(R_TYPE_SYMBOLIC_GP)) {}\n\texplicit Reg64(PhysicalRegID id) : Opd64(RegID::CreatePhysicalRegID(R_TYPE_GP, id)) {}\n\texplicit Reg64(RegID reg_id) : Opd64(reg_id) {} // VS2017 /permissive-\n};\ntypedef Reg64 Reg;\n#else\ntypedef Reg32 Reg;\n#endif\n/// FPU register\nstruct FpuReg : Opd80 {\n\texplicit FpuReg(PhysicalRegID id) : Opd80(RegID::CreatePhysicalRegID(R_TYPE_FPU, id)) {}\n};\n/// MMX register\nstruct MmxReg : Opd64 {\n\tMmxReg() : Opd64(RegID::CreateSymbolicRegID(R_TYPE_SYMBOLIC_MMX)) {}\n\texplicit MmxReg(PhysicalRegID id) : Opd64(RegID::CreatePhysicalRegID(R_TYPE_MMX, id)) {}\n};\n/// XMM register\nstruct XmmReg : Opd128 {\n\tXmmReg() : Opd128(RegID::CreateSymbolicRegID(R_TYPE_SYMBOLIC_XMM)) {}\n\texplicit XmmReg(PhysicalRegID id) : Opd128(RegID::CreatePhysicalRegID(R_TYPE_XMM, id)) {}\n\texplicit XmmReg(RegID reg_id) : Opd128(reg_id) {} // VS2017 /permissive-\n};\n/// YMM register\nstruct YmmReg : Opd256 {\n\tYmmReg() : Opd256(RegID::CreateSymbolicRegID(R_TYPE_SYMBOLIC_YMM)) {}\n\texplicit YmmReg(PhysicalRegID id) : Opd256(RegID::CreatePhysicalRegID(R_TYPE_YMM, id)) {}\n\tXmmReg as128() const {\n\t\tRegID id = reg_;\n\t\tid.type = R_TYPE_SYMBOLIC_XMM;\n\t\treturn XmmReg(id);\n\t}\n};\n\nstruct FpuReg_st0 : FpuReg {FpuReg_st0() : FpuReg(ST0) {}};\n\ntemplate<class OpdN>\nstruct MemT : OpdN\n{\n\tMemT(OpdSize base_size, OpdSize index_size, const RegID& base, const RegID& index, sint64 scale, sint64 disp) : OpdN(base_size, index_size, base, index, scale, disp) {}\n};\ntypedef MemT<Opd8>\t\tMem8;\ntypedef MemT<Opd16>\t\tMem16;\ntypedef MemT<Opd32>\t\tMem32;\ntypedef MemT<Opd64>\t\tMem64;\ntypedef MemT<Opd80>\t\tMem80;\ntypedef MemT<Opd128>\tMem128;\ntypedef MemT<Opd224>\tMem224;\t\t// FPU environment\ntypedef MemT<Opd256>\tMem256;\ntypedef MemT<Opd864>\tMem864;\t\t// FPU state\ntypedef MemT<Opd4096>\tMem4096;\t// FPU, MMX, XMM, MXCSR state\n\ntemplate<class OpdN, OpdSize IndexSize>\nstruct VecMemT : OpdN\n{\n\tVecMemT(OpdSize base_size, const RegID& base, const RegID& index, sint64 scale, sint64 disp) : OpdN(base_size, IndexSize, base, index, scale, disp) {}\n};\ntypedef VecMemT<Opd32, O_SIZE_128>\tMem32vxd;\ntypedef VecMemT<Opd32, O_SIZE_256>\tMem32vyd;\ntypedef VecMemT<Opd32, O_SIZE_128>\tMem64vxd;\ntypedef VecMemT<Opd32, O_SIZE_256>\tMem64vyd;\ntypedef VecMemT<Opd64, O_SIZE_128>\tMem32vxq;\ntypedef VecMemT<Opd64, O_SIZE_256>\tMem32vyq;\ntypedef VecMemT<Opd64, O_SIZE_128>\tMem64vxq;\ntypedef VecMemT<Opd64, O_SIZE_256>\tMem64vyq;\n\nstruct MemOffset64\n{\n\tsint64 offset_;\n\texplicit MemOffset64(sint64 offset) : offset_(offset) {}\n\tsint64 GetOffset() const {return offset_;}\n};\n\ntemplate<class OpdN, class U, class S>\nstruct ImmT : OpdN\n{\n\tImmT(U imm) : OpdN((S) imm) {}\n};\ntypedef ImmT<Opd8, uint8, sint8>\tImm8;\t///< 1 byte immediate\ntypedef ImmT<Opd16, uint16, sint16>\tImm16;\t///< 2 byte immediate\ntypedef ImmT<Opd32, uint32, sint32>\tImm32;\t///< 4 byte immediate\ntypedef ImmT<Opd64, uint64, sint64>\tImm64;\t///< 8 byte immediate\n\nnamespace detail\n{\n\tinline bool IsInt8(sint64 n) {return (sint8) n == n;}\n\tinline bool IsInt16(sint64 n) {return (sint16) n == n;}\n\tinline bool IsInt32(sint64 n) {return (sint32) n == n;}\n\tinline Opd ImmXor8(const Imm16& imm)\t{return IsInt8(imm.GetImm()) ? (Opd) Imm8((sint8) imm.GetImm()) : (Opd) imm;}\n\tinline Opd ImmXor8(const Imm32& imm)\t{return IsInt8(imm.GetImm()) ? (Opd) Imm8((sint8) imm.GetImm()) : (Opd) imm;}\n\tinline Opd ImmXor8(const Imm64& imm)\t{return IsInt8(imm.GetImm()) ? (Opd) Imm8((sint8) imm.GetImm()) : (Opd) imm;}\n}\t// namespace detail\n\n/// 32bit address (base, displacement)\nstruct Addr32\n{\n\tRegID reg_;\n\tsint64 disp_;\n\tAddr32(const Reg32& obj) : reg_(obj.reg_), disp_(0) {}\t// implicit\n\tAddr32(const RegID& reg, sint64 disp) : reg_(reg), disp_(disp) {}\n};\ninline Addr32 operator+(const Reg32& lhs, sint64 rhs) {return Addr32(lhs.reg_, rhs);}\ninline Addr32 operator+(sint64 lhs, const Reg32& rhs) {return rhs + lhs;}\ninline Addr32 operator-(const Reg32& lhs, sint64 rhs) {return lhs + -rhs;}\ninline Addr32 operator+(const Addr32& lhs, sint64 rhs) {return Addr32(lhs.reg_, lhs.disp_ + rhs);}\ninline Addr32 operator+(sint64 lhs, const Addr32& rhs) {return rhs + lhs;}\ninline Addr32 operator-(const Addr32& lhs, sint64 rhs) {return lhs + -rhs;}\n\n/// 32bit address (base, index, displacement)\nstruct Addr32BI\n{\n\tRegID base_;\n\tRegID index_;\n\tsint64 disp_;\n\tAddr32BI(const RegID& base, const RegID& index, sint64 disp) : base_(base), index_(index), disp_(disp) {}\n};\ninline Addr32BI operator+(const Addr32& lhs, const Addr32& rhs) {return Addr32BI(rhs.reg_, lhs.reg_, lhs.disp_ + rhs.disp_);}\ninline Addr32BI operator+(const Addr32BI& lhs, sint64 rhs) {return Addr32BI(lhs.base_, lhs.index_, lhs.disp_ + rhs);}\ninline Addr32BI operator+(sint64 lhs, const Addr32BI& rhs) {return rhs + lhs;}\ninline Addr32BI operator-(const Addr32BI& lhs, sint64 rhs) {return lhs + -rhs;}\n\n/// 32bit address (index, scale, displacement)\nstruct Addr32SI\n{\n\tRegID index_;\n\tsint64 scale_;\n\tsint64 disp_;\n\tAddr32SI(const RegID& index, sint64 scale, sint64 disp) : index_(index), scale_(scale), disp_(disp) {}\n};\ninline Addr32SI operator*(const Reg32& lhs, sint64 rhs) {return Addr32SI(lhs.reg_, rhs, 0);}\ninline Addr32SI operator*(sint64 lhs, const Reg32& rhs) {return rhs * lhs;}\ninline Addr32SI operator*(const Addr32SI& lhs, sint64 rhs) {return Addr32SI(lhs.index_, lhs.scale_ * rhs, lhs.disp_);}\ninline Addr32SI operator*(sint64 lhs, const Addr32SI& rhs) {return rhs * lhs;}\ninline Addr32SI operator+(const Addr32SI& lhs, sint64 rhs) {return Addr32SI(lhs.index_, lhs.scale_, lhs.disp_ + rhs);}\ninline Addr32SI operator+(sint64 lhs, const Addr32SI& rhs) {return rhs + lhs;}\ninline Addr32SI operator-(const Addr32SI& lhs, sint64 rhs) {return lhs + -rhs;}\n\n/// 32bit address (base, index, scale, displacement)\nstruct Addr32SIB\n{\n\tRegID base_;\n\tRegID index_;\n\tsint64 scale_;\n\tsint64 disp_;\n\tAddr32SIB(const RegID& base, const RegID& index, sint64 scale, sint64 disp) : base_(base), index_(index), scale_(scale), disp_(disp) {}\n};\ninline Addr32SIB operator+(const Addr32& lhs, const Addr32SI& rhs) {return Addr32SIB(lhs.reg_, rhs.index_, rhs.scale_, lhs.disp_ + rhs.disp_);}\ninline Addr32SIB operator+(const Addr32SI& lhs, const Addr32& rhs) {return rhs + lhs;}\ninline Addr32SIB operator+(const Addr32SIB& lhs, sint64 rhs) {return Addr32SIB(lhs.base_, lhs.index_, lhs.scale_, lhs.disp_ + rhs);}\ninline Addr32SIB operator+(sint64 lhs, const Addr32SIB& rhs) {return rhs + lhs;}\ninline Addr32SIB operator-(const Addr32SIB& lhs, sint64 rhs) {return lhs + -rhs;}\n\n/// Address (xmm index, scale, displacement)\nstruct AddrXmmSI\n{\n\tRegID index_;\n\tsint64 scale_;\n\tsint64 disp_;\n\tAddrXmmSI(const RegID& index, sint64 scale, sint64 disp) : index_(index), scale_(scale), disp_(disp) {}\n};\ninline AddrXmmSI operator*(const XmmReg& lhs, sint64 rhs) {return AddrXmmSI(lhs.reg_, rhs, 0);}\ninline AddrXmmSI operator*(sint64 lhs, const XmmReg& rhs) {return rhs * lhs;}\ninline AddrXmmSI operator*(const AddrXmmSI& lhs, sint64 rhs) {return AddrXmmSI(lhs.index_, lhs.scale_ * rhs, lhs.disp_);}\ninline AddrXmmSI operator*(sint64 lhs, const AddrXmmSI& rhs) {return rhs * lhs;}\ninline AddrXmmSI operator+(const AddrXmmSI& lhs, sint64 rhs) {return AddrXmmSI(lhs.index_, lhs.scale_, lhs.disp_ + rhs);}\ninline AddrXmmSI operator+(sint64 lhs, const AddrXmmSI& rhs) {return rhs + lhs;}\ninline AddrXmmSI operator-(const AddrXmmSI& lhs, sint64 rhs) {return lhs + -rhs;}\n\n/// 32bit address (base, xmm index, scale, displacement)\nstruct Addr32XmmSIB\n{\n\tRegID base_;\n\tRegID index_;\n\tsint64 scale_;\n\tsint64 disp_;\n\tAddr32XmmSIB(const RegID& base, const RegID& index, sint64 scale, sint64 disp) : base_(base), index_(index), scale_(scale), disp_(disp) {}\n};\ninline Addr32XmmSIB operator+(const Addr32& lhs, const AddrXmmSI& rhs) {return Addr32XmmSIB(lhs.reg_, rhs.index_, rhs.scale_, lhs.disp_ + rhs.disp_);}\ninline Addr32XmmSIB operator+(const AddrXmmSI& lhs, const Addr32& rhs) {return rhs + lhs;}\ninline Addr32XmmSIB operator+(const Addr32XmmSIB& lhs, sint64 rhs) {return Addr32XmmSIB(lhs.base_, lhs.index_, lhs.scale_, lhs.disp_ + rhs);}\ninline Addr32XmmSIB operator+(sint64 lhs, const Addr32XmmSIB& rhs) {return rhs + lhs;}\ninline Addr32XmmSIB operator-(const Addr32XmmSIB& lhs, sint64 rhs) {return lhs + -rhs;}\n\n/// Address (ymm index, scale, displacement)\nstruct AddrYmmSI\n{\n\tRegID index_;\n\tsint64 scale_;\n\tsint64 disp_;\n\tAddrYmmSI(const RegID& index, sint64 scale, sint64 disp) : index_(index), scale_(scale), disp_(disp) {}\n};\ninline AddrYmmSI operator*(const YmmReg& lhs, sint64 rhs) {return AddrYmmSI(lhs.reg_, rhs, 0);}\ninline AddrYmmSI operator*(sint64 lhs, const YmmReg& rhs) {return rhs * lhs;}\ninline AddrYmmSI operator*(const AddrYmmSI& lhs, sint64 rhs) {return AddrYmmSI(lhs.index_, lhs.scale_ * rhs, lhs.disp_);}\ninline AddrYmmSI operator*(sint64 lhs, const AddrYmmSI& rhs) {return rhs * lhs;}\ninline AddrYmmSI operator+(const AddrYmmSI& lhs, sint64 rhs) {return AddrYmmSI(lhs.index_, lhs.scale_, lhs.disp_ + rhs);}\ninline AddrYmmSI operator+(sint64 lhs, const AddrYmmSI& rhs) {return rhs + lhs;}\ninline AddrYmmSI operator-(const AddrYmmSI& lhs, sint64 rhs) {return lhs + -rhs;}\n\n/// 32bit address (base, ymm index, scale, displacement)\nstruct Addr32YmmSIB\n{\n\tRegID base_;\n\tRegID index_;\n\tsint64 scale_;\n\tsint64 disp_;\n\tAddr32YmmSIB(const RegID& base, const RegID& index, sint64 scale, sint64 disp) : base_(base), index_(index), scale_(scale), disp_(disp) {}\n};\ninline Addr32YmmSIB operator+(const Addr32& lhs, const AddrYmmSI& rhs) {return Addr32YmmSIB(lhs.reg_, rhs.index_, rhs.scale_, lhs.disp_ + rhs.disp_);}\ninline Addr32YmmSIB operator+(const AddrYmmSI& lhs, const Addr32& rhs) {return rhs + lhs;}\ninline Addr32YmmSIB operator+(const Addr32YmmSIB& lhs, sint64 rhs) {return Addr32YmmSIB(lhs.base_, lhs.index_, lhs.scale_, lhs.disp_ + rhs);}\ninline Addr32YmmSIB operator+(sint64 lhs, const Addr32YmmSIB& rhs) {return rhs + lhs;}\ninline Addr32YmmSIB operator-(const Addr32YmmSIB& lhs, sint64 rhs) {return lhs + -rhs;}\n\n#ifdef JITASM64\n/// 64bit address (base, displacement)\nstruct Addr64\n{\n\tRegID reg_;\n\tsint64 disp_;\n\tAddr64(const Reg64& obj) : reg_(obj.reg_), disp_(0) {}\t// implicit\n\tAddr64(const RegID& reg, sint64 disp) : reg_(reg), disp_(disp) {}\n};\ninline Addr64 operator+(const Reg64& lhs, sint64 rhs) {return Addr64(lhs.reg_, rhs);}\ninline Addr64 operator+(sint64 lhs, const Reg64& rhs) {return rhs + lhs;}\ninline Addr64 operator-(const Reg64& lhs, sint64 rhs) {return lhs + -rhs;}\ninline Addr64 operator+(const Addr64& lhs, sint64 rhs) {return Addr64(lhs.reg_, lhs.disp_ + rhs);}\ninline Addr64 operator+(sint64 lhs, const Addr64& rhs) {return rhs + lhs;}\ninline Addr64 operator-(const Addr64& lhs, sint64 rhs) {return lhs + -rhs;}\n\n/// 64bit address (base, index, displacement)\nstruct Addr64BI\n{\n\tRegID base_;\n\tRegID index_;\n\tsint64 disp_;\n\tAddr64BI(const RegID& base, const RegID& index, sint64 disp) : base_(base), index_(index), disp_(disp) {}\n};\ninline Addr64BI operator+(const Addr64& lhs, const Addr64& rhs) {return Addr64BI(rhs.reg_, lhs.reg_, lhs.disp_ + rhs.disp_);}\ninline Addr64BI operator+(const Addr64BI& lhs, sint64 rhs) {return Addr64BI(lhs.base_, lhs.index_, lhs.disp_ + rhs);}\ninline Addr64BI operator+(sint64 lhs, const Addr64BI& rhs) {return rhs + lhs;}\ninline Addr64BI operator-(const Addr64BI& lhs, sint64 rhs) {return lhs + -rhs;}\n\n/// 64bit address (index, scale, displacement)\nstruct Addr64SI\n{\n\tRegID index_;\n\tsint64 scale_;\n\tsint64 disp_;\n\tAddr64SI(const RegID& index, sint64 scale, sint64 disp) : index_(index), scale_(scale), disp_(disp) {}\n};\ninline Addr64SI operator*(const Reg64& lhs, sint64 rhs) {return Addr64SI(lhs.reg_, rhs, 0);}\ninline Addr64SI operator*(sint64 lhs, const Reg64& rhs) {return rhs * lhs;}\ninline Addr64SI operator*(const Addr64SI& lhs, sint64 rhs) {return Addr64SI(lhs.index_, lhs.scale_ * rhs, lhs.disp_);}\ninline Addr64SI operator*(sint64 lhs, const Addr64SI& rhs) {return rhs * lhs;}\ninline Addr64SI operator+(const Addr64SI& lhs, sint64 rhs) {return Addr64SI(lhs.index_, lhs.scale_, lhs.disp_ + rhs);}\ninline Addr64SI operator+(sint64 lhs, const Addr64SI& rhs) {return rhs + lhs;}\ninline Addr64SI operator-(const Addr64SI& lhs, sint64 rhs) {return lhs + -rhs;}\n\n/// 64bit address (base, index, scale, displacement)\nstruct Addr64SIB\n{\n\tRegID base_;\n\tRegID index_;\n\tsint64 scale_;\n\tsint64 disp_;\n\tAddr64SIB(const RegID& base, const RegID& index, sint64 scale, sint64 disp) : base_(base), index_(index), scale_(scale), disp_(disp) {}\n};\ninline Addr64SIB operator+(const Addr64& lhs, const Addr64SI& rhs) {return Addr64SIB(lhs.reg_, rhs.index_, rhs.scale_, lhs.disp_ + rhs.disp_);}\ninline Addr64SIB operator+(const Addr64SI& lhs, const Addr64& rhs) {return rhs + lhs;}\ninline Addr64SIB operator+(const Addr64SIB& lhs, sint64 rhs) {return Addr64SIB(lhs.base_, lhs.index_, lhs.scale_, lhs.disp_ + rhs);}\ninline Addr64SIB operator+(sint64 lhs, const Addr64SIB& rhs) {return rhs + lhs;}\ninline Addr64SIB operator-(const Addr64SIB& lhs, sint64 rhs) {return lhs + -rhs;}\n\n/// 64bit address (base, xmm index, scale, displacement)\nstruct Addr64XmmSIB\n{\n\tRegID base_;\n\tRegID index_;\n\tsint64 scale_;\n\tsint64 disp_;\n\tAddr64XmmSIB(const RegID& base, const RegID& index, sint64 scale, sint64 disp) : base_(base), index_(index), scale_(scale), disp_(disp) {}\n};\ninline Addr64XmmSIB operator+(const Addr64& lhs, const AddrXmmSI& rhs) {return Addr64XmmSIB(lhs.reg_, rhs.index_, rhs.scale_, lhs.disp_ + rhs.disp_);}\ninline Addr64XmmSIB operator+(const AddrXmmSI& lhs, const Addr64& rhs) {return rhs + lhs;}\ninline Addr64XmmSIB operator+(const Addr64XmmSIB& lhs, sint64 rhs) {return Addr64XmmSIB(lhs.base_, lhs.index_, lhs.scale_, lhs.disp_ + rhs);}\ninline Addr64XmmSIB operator+(sint64 lhs, const Addr64XmmSIB& rhs) {return rhs + lhs;}\ninline Addr64XmmSIB operator-(const Addr64XmmSIB& lhs, sint64 rhs) {return lhs + -rhs;}\n\n/// 64bit address (base, ymm index, scale, displacement)\nstruct Addr64YmmSIB\n{\n\tRegID base_;\n\tRegID index_;\n\tsint64 scale_;\n\tsint64 disp_;\n\tAddr64YmmSIB(const RegID& base, const RegID& index, sint64 scale, sint64 disp) : base_(base), index_(index), scale_(scale), disp_(disp) {}\n};\ninline Addr64YmmSIB operator+(const Addr64& lhs, const AddrYmmSI& rhs) {return Addr64YmmSIB(lhs.reg_, rhs.index_, rhs.scale_, lhs.disp_ + rhs.disp_);}\ninline Addr64YmmSIB operator+(const AddrYmmSI& lhs, const Addr64& rhs) {return rhs + lhs;}\ninline Addr64YmmSIB operator+(const Addr64YmmSIB& lhs, sint64 rhs) {return Addr64YmmSIB(lhs.base_, lhs.index_, lhs.scale_, lhs.disp_ + rhs);}\ninline Addr64YmmSIB operator+(sint64 lhs, const Addr64YmmSIB& rhs) {return rhs + lhs;}\ninline Addr64YmmSIB operator-(const Addr64YmmSIB& lhs, sint64 rhs) {return lhs + -rhs;}\n\ntypedef Addr64\t\tAddr;\ntypedef Addr64BI\tAddrBI;\ntypedef Addr64SI\tAddrSI;\ntypedef Addr64SIB\tAddrSIB;\n#else\ntypedef Addr32\t\tAddr;\ntypedef Addr32BI\tAddrBI;\ntypedef Addr32SI\tAddrSI;\ntypedef Addr32SIB\tAddrSIB;\n#endif\n\ntemplate<typename OpdN>\nstruct AddressingPtr\n{\n\t// 32bit-Addressing\n\tMemT<OpdN> operator[](const Addr32& obj)\t{return MemT<OpdN>(O_SIZE_32, O_SIZE_32, obj.reg_, RegID::Invalid(), 0, obj.disp_);}\n\tMemT<OpdN> operator[](const Addr32BI& obj)\t{return MemT<OpdN>(O_SIZE_32, O_SIZE_32, obj.base_, obj.index_, 0, obj.disp_);}\n\tMemT<OpdN> operator[](const Addr32SI& obj)\t{return MemT<OpdN>(O_SIZE_32, O_SIZE_32, RegID::Invalid(), obj.index_, obj.scale_, obj.disp_);}\n\tMemT<OpdN> operator[](const Addr32SIB& obj)\t{return MemT<OpdN>(O_SIZE_32, O_SIZE_32, obj.base_, obj.index_, obj.scale_, obj.disp_);}\n\tVecMemT<OpdN, O_SIZE_128> operator[](const Addr32XmmSIB& obj)\t{return VecMemT<OpdN, O_SIZE_128>(O_SIZE_32, obj.base_, obj.index_, obj.scale_, obj.disp_);}\n\tVecMemT<OpdN, O_SIZE_256> operator[](const Addr32YmmSIB& obj)\t{return VecMemT<OpdN, O_SIZE_256>(O_SIZE_32, obj.base_, obj.index_, obj.scale_, obj.disp_);}\n\n#ifdef JITASM64\n\t// 64bit-Addressing\n\tMemT<OpdN> operator[](const Addr64& obj)\t{return MemT<OpdN>(O_SIZE_64, O_SIZE_64, obj.reg_, RegID::Invalid(), 0, obj.disp_);}\n\tMemT<OpdN> operator[](const Addr64BI& obj)\t{return MemT<OpdN>(O_SIZE_64, O_SIZE_64, obj.base_, obj.index_, 0, obj.disp_);}\n\tMemT<OpdN> operator[](const Addr64SI& obj)\t{return MemT<OpdN>(O_SIZE_64, O_SIZE_64, RegID::Invalid(), obj.index_, obj.scale_, obj.disp_);}\n\tMemT<OpdN> operator[](const Addr64SIB& obj)\t{return MemT<OpdN>(O_SIZE_64, O_SIZE_64, obj.base_, obj.index_, obj.scale_, obj.disp_);}\n\tMemOffset64 operator[](sint64 offset)\t\t{return MemOffset64(offset);}\n\tMemOffset64 operator[](uint64 offset)\t\t{return MemOffset64((sint64) offset);}\n\tVecMemT<OpdN, O_SIZE_128> operator[](const Addr64XmmSIB& obj)\t{return VecMemT<OpdN, O_SIZE_128>(O_SIZE_64, obj.base_, obj.index_, obj.scale_, obj.disp_);}\n\tVecMemT<OpdN, O_SIZE_256> operator[](const Addr64YmmSIB& obj)\t{return VecMemT<OpdN, O_SIZE_256>(O_SIZE_64, obj.base_, obj.index_, obj.scale_, obj.disp_);}\n#endif\n\n#ifdef JITASM64\n\tMemT<OpdN> operator[](sint32 disp)\t\t\t{return MemT<OpdN>(O_SIZE_64, O_SIZE_64, RegID::Invalid(), RegID::Invalid(), 0, disp);}\n\tMemT<OpdN> operator[](uint32 disp)\t\t\t{return MemT<OpdN>(O_SIZE_64, O_SIZE_64, RegID::Invalid(), RegID::Invalid(), 0, (sint32) disp);}\n#else\n\tMemT<OpdN> operator[](sint32 disp)\t\t\t{return MemT<OpdN>(O_SIZE_32, O_SIZE_32, RegID::Invalid(), RegID::Invalid(), 0, disp);}\n\tMemT<OpdN> operator[](uint32 disp)\t\t\t{return MemT<OpdN>(O_SIZE_32, O_SIZE_32, RegID::Invalid(), RegID::Invalid(), 0, (sint32) disp);}\n#endif\n};\n\n/// Instruction ID\nenum InstrID\n{\n\tI_ADC, I_ADD, I_AND,\n\tI_BSF, I_BSR, I_BSWAP, I_BT, I_BTC, I_BTR, I_BTS,\n\tI_CALL, I_CBW, I_CLC, I_CLD, I_CLI, I_CLTS, I_CMC, I_CMOVCC, I_CMP, I_CMPS_B, I_CMPS_W, I_CMPS_D, I_CMPS_Q, I_CMPXCHG,\n\tI_CMPXCHG8B, I_CMPXCHG16B, I_CPUID, I_CWD, I_CDQ, I_CQO,\n\tI_DEC, I_DIV,\n\tI_ENTER,\n\tI_HLT,\n\tI_IDIV, I_IMUL, I_IN, I_INC, I_INS_B, I_INS_W, I_INS_D, I_INVD, I_INVLPG, I_INT3, I_INTN, I_INTO, I_IRET, I_IRETD, I_IRETQ,\n\tI_JMP, I_JCC,\n\tI_LAR, I_LEA, I_LEAVE, I_LLDT, I_LMSW, I_LSL, I_LTR, I_LODS_B, I_LODS_W, I_LODS_D, I_LODS_Q, I_LOOP,\n\tI_MOV, I_MOVBE, I_MOVS_B, I_MOVS_W, I_MOVS_D, I_MOVS_Q, I_MOVZX, I_MOVSX, I_MOVSXD,\tI_MUL,\n\tI_NEG, I_NOP, I_NOT,\n\tI_OR, I_OUT, I_OUTS_B, I_OUTS_W, I_OUTS_D,\n\tI_POP, I_POPAD, I_POPF, I_POPFD, I_POPFQ, I_PUSH, I_PUSHAD, I_PUSHF, I_PUSHFD, I_PUSHFQ,\n\tI_RDMSR, I_RDPMC, I_RDTSC, I_RET, I_RCL, I_RCR, I_ROL, I_ROR, I_RSM,\n\tI_SAR, I_SHL, I_SHR, I_SBB, I_SCAS_B, I_SCAS_W, I_SCAS_D, I_SCAS_Q, I_SETCC, I_SHLD, I_SHRD, I_SGDT, I_SIDT, I_SLDT, I_SMSW, I_STC, I_STD, I_STI,\n\tI_STOS_B, I_STOS_W, I_STOS_D, I_STOS_Q, I_SUB, I_SWAPGS, I_SYSCALL, I_SYSENTER, I_SYSEXIT, I_SYSRET,\n\tI_TEST,\n\tI_UD2,\n\tI_VERR, I_VERW,\n\tI_WAIT, I_WBINVD, I_WRMSR,\n\tI_XADD, I_XCHG, I_XGETBV, I_XLATB, I_XOR,\n\n\tI_F2XM1, I_FABS, I_FADD, I_FADDP, I_FIADD,\n\tI_FBLD, I_FBSTP, I_FCHS, I_FCLEX, I_FNCLEX, I_FCMOVCC, I_FCOM, I_FCOMP, I_FCOMPP, I_FCOMI, I_FCOMIP, I_FCOS,\n\tI_FDECSTP, I_FDIV, I_FDIVP, I_FIDIV, I_FDIVR, I_FDIVRP, I_FIDIVR,\n\tI_FFREE,\n\tI_FICOM, I_FICOMP, I_FILD, I_FINCSTP, I_FINIT, I_FNINIT, I_FIST, I_FISTP,\n\tI_FLD, I_FLD1, I_FLDCW, I_FLDENV, I_FLDL2E, I_FLDL2T, I_FLDLG2, I_FLDLN2, I_FLDPI, I_FLDZ,\n\tI_FMUL, I_FMULP, I_FIMUL,\n\tI_FNOP,\n\tI_FPATAN, I_FPREM, I_FPREM1, I_FPTAN,\n\tI_FRNDINT, I_FRSTOR,\n\tI_FSAVE, I_FNSAVE, I_FSCALE, I_FSIN, I_FSINCOS, I_FSQRT, I_FST, I_FSTP, I_FSTCW, I_FNSTCW, I_FSTENV, I_FNSTENV, I_FSTSW, I_FNSTSW,\n\tI_FSUB, I_FSUBP, I_FISUB, I_FSUBR, I_FSUBRP, I_FISUBR,\n\tI_FTST,\n\tI_FUCOM, I_FUCOMP, I_FUCOMPP, I_FUCOMI, I_FUCOMIP,\n\tI_FXAM, I_FXCH, I_FXRSTOR, I_FXSAVE, I_FXTRACT,\n\tI_FYL2X, I_FYL2XP1,\n\n\tI_ADDPS, I_ADDSS, I_ADDPD, I_ADDSD, I_ADDSUBPS, I_ADDSUBPD, I_ANDPS, I_ANDPD, I_ANDNPS, I_ANDNPD,\n\tI_BLENDPS, I_BLENDPD, I_BLENDVPS, I_BLENDVPD,\n\tI_CLFLUSH, I_CMPPS, I_CMPSS, I_CMPPD, I_CMPSD, I_COMISS, I_COMISD, I_CRC32,\n\tI_CVTDQ2PD, I_CVTDQ2PS, I_CVTPD2DQ, I_CVTPD2PI, I_CVTPD2PS, I_CVTPI2PD, I_CVTPI2PS, I_CVTPS2DQ, I_CVTPS2PD, I_CVTPS2PI, I_CVTSD2SI,\n\tI_CVTSD2SS, I_CVTSI2SD, I_CVTSI2SS, I_CVTSS2SD, I_CVTSS2SI, I_CVTTPD2DQ, I_CVTTPD2PI, I_CVTTPS2DQ, I_CVTTPS2PI, I_CVTTSD2SI, I_CVTTSS2SI,\n\tI_DIVPS, I_DIVSS, I_DIVPD, I_DIVSD, I_DPPS, I_DPPD,\n\tI_EMMS, I_EXTRACTPS,\n\tI_FISTTP,\n\tI_HADDPS, I_HADDPD, I_HSUBPS, I_HSUBPD,\n\tI_INSERTPS,\n\tI_LDDQU, I_LDMXCSR, I_LFENCE,\n\tI_MASKMOVDQU, I_MASKMOVQ, I_MAXPS, I_MAXSS, I_MAXPD, I_MAXSD, I_MFENCE, I_MINPS, I_MINSS, I_MINPD, I_MINSD, I_MONITOR,\n\tI_MOVAPD, I_MOVAPS, I_MOVD, I_MOVDDUP, I_MOVDQA, I_MOVDQU, I_MOVDQ2Q, I_MOVHLPS, I_MOVLHPS, I_MOVHPS, I_MOVHPD, I_MOVLPS, I_MOVLPD,\n\tI_MOVMSKPS, I_MOVMSKPD, I_MOVNTDQ, I_MOVNTDQA, I_MOVNTI, I_MOVNTPD, I_MOVNTPS, I_MOVNTQ, I_MOVQ, I_MOVQ2DQ, I_MOVSD, I_MOVSS,\n\tI_MOVSHDUP, I_MOVSLDUP, I_MOVUPS, I_MOVUPD, I_MPSADBW, I_MULPS, I_MULSS, I_MULPD, I_MULSD, I_MWAIT,\n\tI_ORPS, I_ORPD,\n\tI_PABSB, I_PABSD, I_PABSW, I_PACKSSDW, I_PACKSSWB, I_PACKUSDW, I_PACKUSWB, I_PADDB, I_PADDD, I_PADDQ, I_PADDSB, I_PADDSW, I_PADDUSB,\n\tI_PADDUSW, I_PADDW, I_PALIGNR, I_PAND, I_PANDN, I_PAUSE, I_PAVGB, I_PAVGW,\n\tI_PBLENDVB, I_PBLENDW,\n\tI_PCMPEQB, I_PCMPEQW, I_PCMPEQD, I_PCMPEQQ, I_PCMPESTRI, I_PCMPESTRM, I_PCMPISTRI, I_PCMPISTRM, I_PCMPGTB, I_PCMPGTW, I_PCMPGTD, I_PCMPGTQ,\n\tI_PEXTRB, I_PEXTRW, I_PEXTRD, I_PEXTRQ,\n\tI_PHADDW, I_PHADDD, I_PHADDSW, I_PHMINPOSUW, I_PHSUBW, I_PHSUBD, I_PHSUBSW,\n\tI_PINSRB, I_PINSRW, I_PINSRD, I_PINSRQ,\n\tI_PMADDUBSW, I_PMADDWD, I_PMAXSB, I_PMAXSW, I_PMAXSD, I_PMAXUB, I_PMAXUW, I_PMAXUD, I_PMINSB, I_PMINSW, I_PMINSD, I_PMINUB, I_PMINUW,\n\tI_PMINUD, I_PMOVMSKB, I_PMOVSXBW, I_PMOVSXBD, I_PMOVSXBQ, I_PMOVSXWD, I_PMOVSXWQ, I_PMOVSXDQ, I_PMOVZXBW, I_PMOVZXBD, I_PMOVZXBQ, I_PMOVZXWD,\n\tI_PMOVZXWQ, I_PMOVZXDQ, I_PMULDQ, I_PMULHRSW, I_PMULHUW, I_PMULHW, I_PMULLW, I_PMULLD, I_PMULUDQ,\n\tI_POPCNT, I_POR,\n\tI_PREFETCH,\n\tI_PSADBW, I_PSHUFB, I_PSHUFD, I_PSHUFHW, I_PSHUFLW, I_PSHUFW, I_PSIGNB, I_PSIGNW, I_PSIGND, I_PSLLW, I_PSLLD, I_PSLLQ, I_PSLLDQ, I_PSRAW,\n\tI_PSRAD, I_PSRLW, I_PSRLD, I_PSRLQ, I_PSRLDQ, I_PSUBB, I_PSUBW, I_PSUBD, I_PSUBQ, I_PSUBSB, I_PSUBSW, I_PSUBUSB, I_PSUBUSW,\n\tI_PTEST,\n\tI_PUNPCKHBW, I_PUNPCKHWD, I_PUNPCKHDQ, I_PUNPCKHQDQ, I_PUNPCKLBW, I_PUNPCKLWD, I_PUNPCKLDQ, I_PUNPCKLQDQ,\n\tI_PXOR,\n\tI_RCPPS, I_RCPSS, I_ROUNDPS, I_ROUNDPD, I_ROUNDSS, I_ROUNDSD, I_RSQRTPS, I_RSQRTSS,\n\tI_SFENCE, I_SHUFPS, I_SHUFPD, I_SQRTPS, I_SQRTSS, I_SQRTPD, I_SQRTSD, I_STMXCSR, I_SUBPS, I_SUBSS, I_SUBPD, I_SUBSD,\n\tI_UCOMISS, I_UCOMISD, I_UNPCKHPS, I_UNPCKHPD, I_UNPCKLPS, I_UNPCKLPD,\n\tI_XORPS, I_XORPD,\n\n\tI_VBROADCASTSS, I_VBROADCASTSD, I_VBROADCASTF128,\n\tI_VEXTRACTF128,\n\tI_VINSERTF128,\n\tI_VMASKMOVPS, I_VMASKMOVPD,\n\tI_VPERMILPD, I_VPERMILPS, I_VPERM2F128,\n\tI_VTESTPS, I_VTESTPD,\n\tI_VZEROALL, I_VZEROUPPER,\n\n\tI_AESENC, I_AESENCLAST, I_AESDEC, I_AESDECLAST, I_AESIMC, I_AESKEYGENASSIST,\n\tI_PCLMULQDQ,\n\n\t// FMA\n\tI_VFMADD132PD, I_VFMADD213PD, I_VFMADD231PD, I_VFMADD132PS, I_VFMADD213PS, I_VFMADD231PS,\n\tI_VFMADD132SD, I_VFMADD213SD, I_VFMADD231SD, I_VFMADD132SS, I_VFMADD213SS, I_VFMADD231SS,\n\tI_VFMADDSUB132PD, I_VFMADDSUB213PD, I_VFMADDSUB231PD, I_VFMADDSUB132PS, I_VFMADDSUB213PS, I_VFMADDSUB231PS,\n\tI_VFMSUBADD132PD, I_VFMSUBADD213PD, I_VFMSUBADD231PD, I_VFMSUBADD132PS, I_VFMSUBADD213PS, I_VFMSUBADD231PS,\n\tI_VFMSUB132PD, I_VFMSUB213PD, I_VFMSUB231PD, I_VFMSUB132PS, I_VFMSUB213PS, I_VFMSUB231PS,\n\tI_VFMSUB132SD, I_VFMSUB213SD, I_VFMSUB231SD, I_VFMSUB132SS, I_VFMSUB213SS, I_VFMSUB231SS,\n\tI_VFNMADD132PD, I_VFNMADD213PD, I_VFNMADD231PD, I_VFNMADD132PS, I_VFNMADD213PS, I_VFNMADD231PS,\n\tI_VFNMADD132SD, I_VFNMADD213SD, I_VFNMADD231SD, I_VFNMADD132SS, I_VFNMADD213SS, I_VFNMADD231SS,\n\tI_VFNMSUB132PD, I_VFNMSUB213PD, I_VFNMSUB231PD, I_VFNMSUB132PS, I_VFNMSUB213PS, I_VFNMSUB231PS,\n\tI_VFNMSUB132SD, I_VFNMSUB213SD, I_VFNMSUB231SD, I_VFNMSUB132SS, I_VFNMSUB213SS, I_VFNMSUB231SS,\n\n\t// F16C\n\tI_RDFSBASE, I_RDGSBASE, I_RDRAND, I_WRFSBASE, I_WRGSBASE, I_VCVTPH2PS, I_VCVTPS2PH,\n\n\t// BMI\n\tI_ANDN, I_BEXTR, I_BLSI, I_BLSMSK, I_BLSR, I_BZHI, I_LZCNT, I_MULX, I_PDEP, I_PEXT, I_RORX, I_SARX, I_SHLX, I_SHRX, I_TZCNT, I_INVPCID,\n\n\t// XOP\n\tI_VFRCZPD, I_VFRCZPS, I_VFRCZSD, I_VFRCZSS,\n\tI_VPCMOV, I_VPCOMB, I_VPCOMD, I_VPCOMQ, I_VPCOMUB, I_VPCOMUD, I_VPCOMUQ, I_VPCOMUW, I_VPCOMW, I_VPERMIL2PD, I_VPERMIL2PS,\n\tI_VPHADDBD, I_VPHADDBQ, I_VPHADDBW, I_VPHADDDQ, I_VPHADDUBD, I_VPHADDUBQ, I_VPHADDUBW, I_VPHADDUDQ, I_VPHADDUWD, I_VPHADDUWQ,\n\tI_VPHADDWD, I_VPHADDWQ, I_VPHSUBBW, I_VPHSUBDQ, I_VPHSUBWD,\n\tI_VPMACSDD, I_VPMACSDQH, I_VPMACSDQL, I_VPMACSSDD, I_VPMACSSDQH, I_VPMACSSDQL, I_VPMACSSWD, I_VPMACSSWW, I_VPMACSWD, I_VPMACSWW,\n\tI_VPMADCSSWD, I_VPMADCSWD,\n\tI_VPPERM, I_VPROTB, I_VPROTD, I_VPROTQ, I_VPROTW, I_VPSHAB, I_VPSHAD, I_VPSHAQ, I_VPSHAW, I_VPSHLB, I_VPSHLD, I_VPSHLQ, I_VPSHLW,\n\n\t// FMA4\n\tI_VFMADDPD, I_VFMADDPS, I_VFMADDSD, I_VFMADDSS,\n\tI_VFMADDSUBPD, I_VFMADDSUBPS,\n\tI_VFMSUBADDPD, I_VFMSUBADDPS,\n\tI_VFMSUBPD, I_VFMSUBPS, I_VFMSUBSD, I_VFMSUBSS,\n\tI_VFNMADDPD, I_VFNMADDPS, I_VFNMADDSD, I_VFNMADDSS,\n\tI_VFNMSUBPD, I_VFNMSUBPS, I_VFNMSUBSD, I_VFNMSUBSS,\n\n\t// AVX2\n\tI_VBROADCASTI128, I_VPBROADCASTB, I_VPBROADCASTW, I_VPBROADCASTD, I_VPBROADCASTQ,\n\tI_PBLENDD, I_VPERMD, I_VPERMQ, I_VPERMPS, I_VPERMPD, I_VPERM2I128,\n\tI_VEXTRACTI128, I_VINSERTI128, I_VMASKMOVD, I_VMASKMOVQ, I_VPSLLVD, I_VPSLLVQ, I_VPSRAVD, I_VPSRLVD, I_VPSRLVQ,\n\tI_VGATHERDPS, I_VGATHERQPS, I_VGATHERDPD, I_VGATHERQPD, I_VPGATHERDD, I_VPGATHERQD, I_VPGATHERDQ, I_VPGATHERQQ,\n\n\t// jitasm compiler instructions\n\tI_COMPILER_DECLARE_REG_ARG,\t\t///< Declare register argument\n\tI_COMPILER_DECLARE_STACK_ARG,\t///< Declare stack argument\n\tI_COMPILER_DECLARE_RESULT_REG,\t///< Declare result register (eax/rax/xmm0)\n\tI_COMPILER_PROLOG,\t\t\t\t///< Function prolog\n\tI_COMPILER_EPILOG\t\t\t\t///< Function epilog\n};\n\nenum JumpCondition\n{\n\tJCC_O, JCC_NO, JCC_B, JCC_AE, JCC_E, JCC_NE, JCC_BE, JCC_A, JCC_S, JCC_NS, JCC_P, JCC_NP, JCC_L, JCC_GE, JCC_LE, JCC_G,\n\tJCC_CXZ, JCC_ECXZ, JCC_RCXZ,\n};\n\nenum EncodingFlags\n{\n\tE_SPECIAL\t\t\t\t= 1 << 0,\n\tE_OPERAND_SIZE_PREFIX\t= 1 << 1,\t///< Operand-size override prefix\n\tE_REP_PREFIX\t\t\t= 1 << 2,\t///< REP prefix\n\tE_REXW_PREFIX\t\t\t= 1 << 3,\t///< REX.W\n\tE_MANDATORY_PREFIX_66\t= 1 << 4,\t///< Mandatory prefix 66\n\tE_MANDATORY_PREFIX_F2\t= 1 << 5,\t///< Mandatory prefix F2\n\tE_MANDATORY_PREFIX_F3\t= 1 << 6,\t///< Mandatory prefix F3\n\tE_VEX\t\t\t\t\t= 1 << 7,\n\tE_XOP\t\t\t\t\t= 1 << 8,\n\tE_VEX_L\t\t\t\t\t= 1 << 9,\n\tE_VEX_W\t\t\t\t\t= 1 << 10,\n\tE_VEX_MMMMM_SHIFT\t\t= 11,\n\tE_VEX_MMMMM_MASK\t\t= 0x1F << E_VEX_MMMMM_SHIFT,\n\tE_VEX_0F\t\t\t\t= 1 << E_VEX_MMMMM_SHIFT,\n\tE_VEX_0F38\t\t\t\t= 2 << E_VEX_MMMMM_SHIFT,\n\tE_VEX_0F3A\t\t\t\t= 3 << E_VEX_MMMMM_SHIFT,\n\tE_XOP_M00011\t\t\t= 3 << E_VEX_MMMMM_SHIFT,\n\tE_XOP_M01000\t\t\t= 8 << E_VEX_MMMMM_SHIFT,\n\tE_XOP_M01001\t\t\t= 9 << E_VEX_MMMMM_SHIFT,\n\tE_VEX_PP_SHIFT\t\t\t= 16,\n\tE_VEX_PP_MASK\t\t\t= 0x3 << E_VEX_PP_SHIFT,\n\tE_VEX_66\t\t\t\t= 1 << E_VEX_PP_SHIFT,\n\tE_VEX_F3\t\t\t\t= 2 << E_VEX_PP_SHIFT,\n\tE_VEX_F2\t\t\t\t= 3 << E_VEX_PP_SHIFT,\n\tE_XOP_P00\t\t\t\t= 0 << E_VEX_PP_SHIFT,\n\tE_XOP_P01\t\t\t\t= 1 << E_VEX_PP_SHIFT,\n\n\tE_VEX_128\t\t= E_VEX,\n\tE_VEX_256\t\t= E_VEX | E_VEX_L,\n\tE_VEX_LIG\t\t= E_VEX,\n\tE_VEX_LZ\t\t= E_VEX,\n\tE_VEX_66_0F\t\t= E_VEX_66 | E_VEX_0F,\n\tE_VEX_66_0F38\t= E_VEX_66 | E_VEX_0F38,\n\tE_VEX_66_0F3A\t= E_VEX_66 | E_VEX_0F3A,\n\tE_VEX_F2_0F\t\t= E_VEX_F2 | E_VEX_0F,\n\tE_VEX_F2_0F38\t= E_VEX_F2 | E_VEX_0F38,\n\tE_VEX_F2_0F3A\t= E_VEX_F2 | E_VEX_0F3A,\n\tE_VEX_F3_0F\t\t= E_VEX_F3 | E_VEX_0F,\n\tE_VEX_F3_0F38\t= E_VEX_F3 | E_VEX_0F38,\n\tE_VEX_F3_0F3A\t= E_VEX_F3 | E_VEX_0F3A,\n\tE_VEX_W0\t\t= 0,\n\tE_VEX_W1\t\t= E_VEX_W,\n\tE_VEX_WIG\t\t= 0,\n\tE_XOP_128\t\t= E_XOP,\n\tE_XOP_256\t\t= E_XOP | E_VEX_L,\n\tE_XOP_W0\t\t= 0,\n\tE_XOP_W1\t\t= E_VEX_W,\n\n\t// Aliases\n\tE_VEX_128_0F_WIG = E_VEX_128 | E_VEX_0F | E_VEX_WIG,\n\tE_VEX_256_0F_WIG = E_VEX_256 | E_VEX_0F | E_VEX_WIG,\n\tE_VEX_128_66_0F_WIG = E_VEX_128 | E_VEX_66_0F | E_VEX_WIG,\n\tE_VEX_256_66_0F_WIG = E_VEX_256 | E_VEX_66_0F | E_VEX_WIG,\n\tE_VEX_128_66_0F38_WIG = E_VEX_128 | E_VEX_66_0F38 | E_VEX_WIG,\n\tE_VEX_256_66_0F38_WIG = E_VEX_256 | E_VEX_66_0F38 | E_VEX_WIG,\n\tE_VEX_128_66_0F38_W0 = E_VEX_128 | E_VEX_66_0F38 | E_VEX_W0,\n\tE_VEX_256_66_0F38_W0 = E_VEX_256 | E_VEX_66_0F38 | E_VEX_W0,\n\tE_VEX_128_66_0F38_W1 = E_VEX_128 | E_VEX_66_0F38 | E_VEX_W1,\n\tE_VEX_256_66_0F38_W1 = E_VEX_256 | E_VEX_66_0F38 | E_VEX_W1,\n\tE_VEX_128_66_0F3A_W0 = E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0,\n\tE_VEX_256_66_0F3A_W0 = E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0,\n};\n\n/// Instruction\nstruct Instr\n{\n\tstatic const size_t MAX_OPERAND_COUNT = 6;\n\n\tInstrID\tid_;\t\t\t\t\t\t\t///< Instruction ID\n\tuint32  opcode_;\t\t\t\t\t\t///< Opcode\n\tuint32  encoding_flag_;\t\t\t\t\t///< EncodingFlags\n\tdetail::Opd\topd_[MAX_OPERAND_COUNT];\t///< Operands\n\n\tInstr(InstrID id, uint32 opcode, uint32 encoding_flag, const detail::Opd& opd1 = detail::Opd(), const detail::Opd& opd2 = detail::Opd(), const detail::Opd& opd3 = detail::Opd(), const detail::Opd& opd4 = detail::Opd(), const detail::Opd& opd5 = detail::Opd(), const detail::Opd& opd6 = detail::Opd())\n\t\t: id_(id), opcode_(opcode), encoding_flag_(encoding_flag) {opd_[0] = opd1, opd_[1] = opd2, opd_[2] = opd3, opd_[3] = opd4, opd_[4] = opd5, opd_[5] = opd6;}\n\n\tInstrID GetID() const {return id_;}\n\tconst detail::Opd& GetOpd(size_t index) const {return opd_[index];}\n\tdetail::Opd& GetOpd(size_t index) {return opd_[index];}\n};\n\n/// Assembler backend\nstruct Backend\n{\n\tuint8*\tpbuff_;\n\tsize_t\tbuffsize_;\n\tsize_t\tsize_;\n\n\tBackend(void* pbuff = NULL, size_t buffsize = 0) : pbuff_((uint8*) pbuff), buffsize_(buffsize), size_(0)\n\t{\n\t\tmemset(pbuff, 0xCC, buffsize);\t// INT3\n\t}\n\n\tsize_t GetSize() const\n\t{\n\t\treturn size_;\n\t}\n\n\tvoid put_bytes(void* p, size_t n)\n\t{\n\t\tuint8* pb = (uint8*) p;\n\t\twhile (n--) {\n\t\t\tif (pbuff_) {\n\t\t\t\tif (size_ == buffsize_) JITASM_ASSERT(0);\n\t\t\t\tpbuff_[size_] = *pb++;\n\t\t\t}\n\t\t\tsize_++;\n\t\t}\n\t}\n\tvoid db(uint64 b) {put_bytes(&b, 1);}\n\tvoid dw(uint64 w) {put_bytes(&w, 2);}\n\tvoid dd(uint64 d) {put_bytes(&d, 4);}\n\tvoid dq(uint64 q) {put_bytes(&q, 8);}\n\n\tuint8 GetWRXB(int w, const detail::Opd& reg, const detail::Opd& r_m)\n\t{\n\t\tuint8 wrxb = w ? 8 : 0;\n\t\tif (reg.IsReg()) {\n\t\t\tif (!reg.GetReg().IsInvalid() && reg.GetReg().id >= R8) wrxb |= 4;\n\t\t}\n\t\tif (r_m.IsReg()) {\n\t\t\tif (r_m.GetReg().id >= R8) wrxb |= 1;\n\t\t}\n\t\tif (r_m.IsMem()) {\n\t\t\tif (!r_m.GetIndex().IsInvalid() && r_m.GetIndex().id >= R8) wrxb |= 2;\n\t\t\tif (!r_m.GetBase().IsInvalid() && r_m.GetBase().id >= R8) wrxb |= 1;\n\t\t}\n\t\treturn wrxb;\n\t}\n\n\tvoid EncodePrefixes(uint32 flag, const detail::Opd& reg, const detail::Opd& r_m, const detail::Opd& vex)\n\t{\n\t\tif (flag & (E_VEX | E_XOP)) {\n\t\t\t// Encode VEX prefix\n#ifdef JITASM64\n\t\t\tif (r_m.IsMem() && r_m.GetAddressBaseSize() != O_SIZE_64) db(0x67);\n#endif\n\t\t\tuint8 vvvv = vex.IsReg() ? 0xF - (uint8) vex.GetReg().id : 0xF;\n\t\t\tuint8 mmmmm = (flag & E_VEX_MMMMM_MASK) >> E_VEX_MMMMM_SHIFT;\n\t\t\tuint8 pp = static_cast<uint8>((flag & E_VEX_PP_MASK) >> E_VEX_PP_SHIFT);\n\t\t\tuint8 wrxb = GetWRXB(flag & E_VEX_W, reg, r_m);\n\t\t\tif (flag & E_XOP) {\n\t\t\t\tdb(0x8F);\n\t\t\t\tdb((~wrxb & 7) << 5 | mmmmm);\n\t\t\t\tdb((wrxb & 8) << 4 | vvvv << 3 | (flag & E_VEX_L ? 4 : 0) | pp);\n\t\t\t} else if (wrxb & 0xB || (flag & E_VEX_MMMMM_MASK) == E_VEX_0F38 || (flag & E_VEX_MMMMM_MASK) == E_VEX_0F3A) {\n\t\t\t\tdb(0xC4);\n\t\t\t\tdb((~wrxb & 7) << 5 | mmmmm);\n\t\t\t\tdb((wrxb & 8) << 4 | vvvv << 3 | (flag & E_VEX_L ? 4 : 0) | pp);\n\t\t\t} else {\n\t\t\t\tdb(0xC5);\n\t\t\t\tdb((~wrxb & 4) << 5 | vvvv << 3 | (flag & E_VEX_L ? 4 : 0) | pp);\n\t\t\t}\n\t\t} else {\n\t\t\tuint8 wrxb = GetWRXB(flag & E_REXW_PREFIX, reg, r_m);\n\t\t\tif (wrxb) {\n\t\t\t\t// Encode REX prefix\n\t\t\t\tJITASM_ASSERT(!reg.IsReg() || reg.GetSize() != O_SIZE_8 || reg.GetReg().id < AH || reg.GetReg().id >= R8B);\t// AH, BH, CH, or DH may not be used with REX.\n\t\t\t\tJITASM_ASSERT(!r_m.IsReg() || r_m.GetSize() != O_SIZE_8 || r_m.GetReg().id < AH || r_m.GetReg().id >= R8B);\t// AH, BH, CH, or DH may not be used with REX.\n\n\t\t\t\tif (flag & E_REP_PREFIX) db(0xF3);\n#ifdef JITASM64\n\t\t\t\tif (r_m.IsMem() && r_m.GetAddressBaseSize() != O_SIZE_64) db(0x67);\n#endif\n\t\t\t\tif (flag & E_OPERAND_SIZE_PREFIX) db(0x66);\n\n\t\t\t\tif (flag & E_MANDATORY_PREFIX_66) db(0x66);\n\t\t\t\telse if (flag & E_MANDATORY_PREFIX_F2) db(0xF2);\n\t\t\t\telse if (flag & E_MANDATORY_PREFIX_F3) db(0xF3);\n\n\t\t\t\tdb(0x40 | wrxb);\n\t\t\t} else {\n\t\t\t\tif (flag & E_MANDATORY_PREFIX_66) db(0x66);\n\t\t\t\telse if (flag & E_MANDATORY_PREFIX_F2) db(0xF2);\n\t\t\t\telse if (flag & E_MANDATORY_PREFIX_F3) db(0xF3);\n\n\t\t\t\tif (flag & E_REP_PREFIX) db(0xF3);\n#ifdef JITASM64\n\t\t\t\tif (r_m.IsMem() && r_m.GetAddressBaseSize() != O_SIZE_64) db(0x67);\n#endif\n\t\t\t\tif (flag & E_OPERAND_SIZE_PREFIX) db(0x66);\n\t\t\t}\n\t\t}\n\t}\n\n\tvoid EncodeModRM(uint8 reg, const detail::Opd& r_m)\n\t{\n\t\treg &= 0x7;\n\n\t\tif (r_m.IsReg()) {\n\t\t\tdb(0xC0 | (reg << 3) | (r_m.GetReg().id & 0x7));\n\t\t} else if (r_m.IsMem()) {\n\t\t\tJITASM_ASSERT(r_m.GetBase().type == R_TYPE_GP && (r_m.GetIndex().type == R_TYPE_GP || r_m.GetIndex().type == R_TYPE_XMM || r_m.GetIndex().type == R_TYPE_YMM));\n\t\t\tint base = r_m.GetBase().id; if (base != INVALID) base &= 0x7;\n\t\t\tint index = r_m.GetIndex().id; if (index != INVALID) index &= 0x7;\n\n\t\t\tif (base == INVALID && index == INVALID) {\n#ifdef JITASM64\n\t\t\t\tdb(reg << 3 | 4);\n\t\t\t\tdb(0x25);\n#else\n\t\t\t\tdb(reg << 3 | 5);\n#endif\n\t\t\t\tdd(r_m.GetDisp());\n\t\t\t} else {\n\t\t\t\tJITASM_ASSERT(base != ESP || index != ESP);\n\t\t\t\tJITASM_ASSERT(index != ESP || r_m.GetScale() == 0);\n\n\t\t\t\tif (index == ESP) {\n\t\t\t\t\tindex = base;\n\t\t\t\t\tbase = ESP;\n\t\t\t\t}\n\t\t\t\tbool sib = index != INVALID || r_m.GetScale() || base == ESP;\n\n\t\t\t\t// ModR/M\n\t\t\t\tuint8 mod = 0;\n\t\t\t\tif (r_m.GetDisp() == 0 || (sib && base == INVALID)) mod = base != EBP ? 0 : 1;\n\t\t\t\telse if (detail::IsInt8(r_m.GetDisp())) mod = 1;\n\t\t\t\telse if (detail::IsInt32(r_m.GetDisp())) mod = 2;\n\t\t\t\telse JITASM_ASSERT(0);\n\t\t\t\tdb(mod << 6 | reg << 3 | (sib ? 4 : base));\n\n\t\t\t\t// SIB\n\t\t\t\tif (sib) {\n\t\t\t\t\tuint8 ss = 0;\n\t\t\t\t\tif (r_m.GetScale() == 0) ss = 0;\n\t\t\t\t\telse if (r_m.GetScale() == 2) ss = 1;\n\t\t\t\t\telse if (r_m.GetScale() == 4) ss = 2;\n\t\t\t\t\telse if (r_m.GetScale() == 8) ss = 3;\n\t\t\t\t\telse JITASM_ASSERT(0);\n\t\t\t\t\tif (index != INVALID && base != INVALID) {\n\t\t\t\t\t\tdb(ss << 6 | index << 3 | base);\n\t\t\t\t\t} else if (base != INVALID) {\n\t\t\t\t\t\tdb(ss << 6 | 4 << 3 | base);\n\t\t\t\t\t} else if (index != INVALID) {\n\t\t\t\t\t\tdb(ss << 6 | index << 3 | 5);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tJITASM_ASSERT(0);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Displacement\n\t\t\t\tif (mod == 0 && sib && base == INVALID) dd(r_m.GetDisp());\n\t\t\t\tif (mod == 1) db(r_m.GetDisp());\n\t\t\t\tif (mod == 2) dd(r_m.GetDisp());\n\t\t\t}\n\t\t} else {\n\t\t\tJITASM_ASSERT(0);\n\t\t}\n\t}\n\n\tvoid EncodeOpcode(uint32 opcode)\n\t{\n\t\tif (opcode & 0xFF000000) db((opcode >> 24) & 0xFF);\n\t\tif (opcode & 0xFFFF0000) db((opcode >> 16) & 0xFF);\n\t\tif (opcode & 0xFFFFFF00) db((opcode >> 8)  & 0xFF);\n\t\tdb(opcode & 0xFF);\n\t}\n\n\tvoid EncodeImm(const detail::Opd& imm)\n\t{\n\t\tconst OpdSize size = imm.GetSize();\n\t\tif (size == O_SIZE_8) db(imm.GetImm());\n\t\telse if (size == O_SIZE_16) dw(imm.GetImm());\n\t\telse if (size == O_SIZE_32) dd(imm.GetImm());\n\t\telse if (size == O_SIZE_64) dq(imm.GetImm());\n\t\telse JITASM_ASSERT(0);\n\t}\n\n\tvoid Encode(const Instr& instr)\n\t{\n\t\tuint32 opcode = instr.opcode_;\n\n\t\tconst detail::Opd& opd1 = instr.GetOpd(0).IsDummy() ? detail::Opd() : instr.GetOpd(0);\tJITASM_ASSERT(!(opd1.IsReg() && opd1.GetReg().IsSymbolic()));\n\t\tconst detail::Opd& opd2 = instr.GetOpd(1).IsDummy() ? detail::Opd() : instr.GetOpd(1);\tJITASM_ASSERT(!(opd2.IsReg() && opd2.GetReg().IsSymbolic()));\n\t\tconst detail::Opd& opd3 = instr.GetOpd(2).IsDummy() ? detail::Opd() : instr.GetOpd(2);\tJITASM_ASSERT(!(opd3.IsReg() && opd3.GetReg().IsSymbolic()));\n\t\tconst detail::Opd& opd4 = instr.GetOpd(3).IsDummy() ? detail::Opd() : instr.GetOpd(3);\tJITASM_ASSERT(!(opd4.IsReg() && opd4.GetReg().IsSymbolic()));\n\n\t\t// +rb, +rw, +rd, +ro\n\t\tif (opd1.IsReg() && (opd2.IsNone() || opd2.IsImm())) {\n\t\t\topcode += opd1.GetReg().id & 0x7;\n\t\t}\n\n\t\tif ((opd1.IsImm() || opd1.IsReg()) && (opd2.IsReg() || opd2.IsMem())) {\t// ModR/M\n\t\t\tconst detail::Opd& reg = opd1;\n\t\t\tconst detail::Opd& r_m = opd2;\n\t\t\tconst detail::Opd& vex = opd3;\n\t\t\tEncodePrefixes(instr.encoding_flag_, reg, r_m, vex);\n\t\t\tEncodeOpcode(opcode);\n\t\t\tEncodeModRM((uint8) (reg.IsImm() ? reg.GetImm() : reg.GetReg().id), r_m);\n\n\t\t\t// /is4\n\t\t\tif (opd4.IsReg()) {\n\t\t\t\tEncodeImm(Imm8(static_cast<uint8>(opd4.GetReg().id << 4)));\n\t\t\t}\n\t\t} else {\n\t\t\tconst detail::Opd& reg = detail::Opd();\n\t\t\tconst detail::Opd& r_m = opd1.IsReg() ? opd1 : detail::Opd();\n\t\t\tconst detail::Opd& vex = detail::Opd();\n\t\t\tEncodePrefixes(instr.encoding_flag_, reg, r_m, vex);\n\t\t\tEncodeOpcode(opcode);\n\t\t}\n\n\t\tif (opd1.IsImm() && !opd2.IsReg() && !opd2.IsMem())\tEncodeImm(opd1);\n\t\tif (opd2.IsImm())\tEncodeImm(opd2);\n\t\tif (opd3.IsImm())\tEncodeImm(opd3);\n\t\tif (opd4.IsImm())\tEncodeImm(opd4);\n\t}\n\n\tvoid EncodeALU(const Instr& instr, uint32 opcode)\n\t{\n\t\tconst detail::Opd& reg = instr.GetOpd(1);\n\t\tconst detail::Opd& imm = instr.GetOpd(2);\n\t\tJITASM_ASSERT(instr.GetOpd(0).IsImm() && reg.IsReg() && imm.IsImm());\n\n\t\tif (reg.GetReg().id == EAX && (reg.GetSize() == O_SIZE_8 || !detail::IsInt8(imm.GetImm()))) {\n\t\t\topcode |= (reg.GetSize() == O_SIZE_8 ? 0 : 1);\n\t\t\tEncode(Instr(instr.GetID(), opcode, instr.encoding_flag_, reg, imm));\n\t\t} else {\n\t\t\tEncode(instr);\n\t\t}\n\t}\n\n\tvoid EncodeJMP(const Instr& instr)\n\t{\n\t\tconst detail::Opd& imm = instr.GetOpd(0);\n\t\tif (instr.GetID() == I_JMP) {\n\t\t\tEncode(Instr(instr.GetID(), imm.GetSize() == O_SIZE_8 ? 0xEB : 0xE9, instr.encoding_flag_, imm));\n\t\t} else if (instr.GetID() == I_JCC) {\n#ifndef JITASM64\n\t\t\tuint32 tttn = instr.opcode_;\n\t\t\tif (tttn == JCC_CXZ)\t\tEncode(Instr(instr.GetID(), 0x67E3, instr.encoding_flag_, imm));\n\t\t\telse if (tttn == JCC_ECXZ)\tEncode(Instr(instr.GetID(), 0xE3, instr.encoding_flag_, imm));\n\t\t\telse Encode(Instr(instr.GetID(), (imm.GetSize() == O_SIZE_8 ? 0x70 : 0x0F80) | tttn, instr.encoding_flag_, imm));\n#else\n\t\t\tuint32 tttn = instr.opcode_;\n\t\t\tif (tttn == JCC_ECXZ)\t\tEncode(Instr(instr.GetID(), 0x67E3, instr.encoding_flag_, imm));\n\t\t\telse if (tttn == JCC_RCXZ)\tEncode(Instr(instr.GetID(), 0xE3, instr.encoding_flag_, imm));\n\t\t\telse Encode(Instr(instr.GetID(), (imm.GetSize() == O_SIZE_8 ? 0x70 : 0x0F80) | tttn, instr.encoding_flag_, imm));\n#endif\n\t\t} else if (instr.GetID() == I_LOOP) {\n\t\t\tEncode(Instr(instr.GetID(), instr.opcode_, instr.encoding_flag_, imm));\n\t\t} else {\n\t\t\tJITASM_ASSERT(0);\n\t\t}\n\t}\n\n\tvoid EncodeMOV(const Instr& instr)\n\t{\n#ifndef JITASM64\n\t\tconst detail::Opd& reg = instr.GetOpd(0);\n\t\tconst detail::Opd& mem = instr.GetOpd(1);\n\t\tJITASM_ASSERT(reg.IsReg() && mem.IsMem());\n\n\t\tif (reg.GetReg().id == EAX && mem.GetBase().IsInvalid() && mem.GetIndex().IsInvalid()) {\n\t\t\tuint32 opcode = 0xA0 | (~instr.opcode_ & 0x2) | (instr.opcode_ & 1);\n\t\t\tEncode(Instr(instr.GetID(), opcode, instr.encoding_flag_, Imm32((sint32) mem.GetDisp())));\n\t\t} else {\n\t\t\tEncode(instr);\n\t\t}\n#else\n\t\tEncode(instr);\n#endif\n\t}\n\n\tvoid EncodeTEST(const Instr& instr)\n\t{\n\t\tconst detail::Opd& reg = instr.GetOpd(1);\n\t\tconst detail::Opd& imm = instr.GetOpd(2);\n\t\tJITASM_ASSERT(instr.GetOpd(0).IsImm() && reg.IsReg() && imm.IsImm());\n\n\t\tif (reg.GetReg().id == EAX) {\n\t\t\tuint32 opcode = 0xA8 | (reg.GetSize() == O_SIZE_8 ? 0 : 1);\n\t\t\tEncode(Instr(instr.GetID(), opcode, instr.encoding_flag_, reg, imm));\n\t\t} else {\n\t\t\tEncode(instr);\n\t\t}\n\t}\n\n\tvoid EncodeXCHG(const Instr& instr)\n\t{\n\t\tconst detail::Opd& dst = instr.GetOpd(0);\n\t\tconst detail::Opd& src = instr.GetOpd(1);\n\t\tJITASM_ASSERT(dst.IsReg() && src.IsReg());\n\n\t\tif (dst.GetReg().id == EAX) {\n\t\t\tEncode(Instr(instr.GetID(), 0x90, instr.encoding_flag_, src));\n\t\t} else if (src.GetReg().id == EAX) {\n\t\t\tEncode(Instr(instr.GetID(), 0x90, instr.encoding_flag_, dst));\n\t\t} else {\n\t\t\tEncode(instr);\n\t\t}\n\t}\n\n\tvoid Assemble(const Instr& instr)\n\t{\n\t\tif (instr.encoding_flag_ & E_SPECIAL) {\n\t\t\tswitch (instr.GetID()) {\n\t\t\tcase I_ADD:\t\tEncodeALU(instr, 0x04); break;\n\t\t\tcase I_OR:\t\tEncodeALU(instr, 0x0C); break;\n\t\t\tcase I_ADC:\t\tEncodeALU(instr, 0x14); break;\n\t\t\tcase I_SBB:\t\tEncodeALU(instr, 0x1C); break;\n\t\t\tcase I_AND:\t\tEncodeALU(instr, 0x24); break;\n\t\t\tcase I_SUB:\t\tEncodeALU(instr, 0x2C); break;\n\t\t\tcase I_XOR:\t\tEncodeALU(instr, 0x34); break;\n\t\t\tcase I_CMP:\t\tEncodeALU(instr, 0x3C); break;\n\t\t\tcase I_JMP:\t\tEncodeJMP(instr); break;\n\t\t\tcase I_JCC:\t\tEncodeJMP(instr); break;\n\t\t\tcase I_LOOP:\tEncodeJMP(instr); break;\n\t\t\tcase I_MOV:\t\tEncodeMOV(instr); break;\n\t\t\tcase I_TEST:\tEncodeTEST(instr); break;\n\t\t\tcase I_XCHG:\tEncodeXCHG(instr); break;\n\t\t\tdefault:\t\tJITASM_ASSERT(0); break;\n\t\t\t}\n\t\t} else {\n\t\t\tEncode(instr);\n\t\t}\n\t}\n\n\tstatic size_t GetInstrCodeSize(const Instr& instr)\n\t{\n\t\tBackend backend;\n\t\tbackend.Assemble(instr);\n\t\treturn backend.GetSize();\n\t}\n};\n\nnamespace detail\n{\n\t/// Counting 1-Bits\n\tinline uint32 Count1Bits(uint32 x)\n\t{\n\t\tx = x - ((x >> 1) & 0x55555555);\n\t\tx = (x & 0x33333333) + ((x >> 2) & 0x33333333);\n\t\tx = (x + (x >> 4)) & 0x0F0F0F0F;\n\t\tx = x + (x >> 8);\n\t\tx = x + (x >> 16);\n\t\treturn x & 0x0000003F;\n\t}\n\n\t/// The bit position of the first bit 1.\n\tinline uint32 bit_scan_forward(uint32 x)\n\t{\n\t\tJITASM_ASSERT(x != 0);\n#if defined(JITASM_GCC)\n\t\treturn __builtin_ctz(x);\n#else\n\t\tunsigned long index;\n\t\t_BitScanForward(&index, x);\n\t\treturn index;\n#endif\n\t}\n\n\t/// The bit position of the last bit 1.\n\tinline uint32 bit_scan_reverse(uint32 x)\n\t{\n\t\tJITASM_ASSERT(x != 0);\n#if defined(JITASM_GCC)\n\t\treturn 31 - __builtin_clz(x);\n#else\n\t\tunsigned long index;\n\t\t_BitScanReverse(&index, x);\n\t\treturn index;\n#endif\n\t}\n\n\t/// Prior iterator\n\ttemplate<class It> It prior(const It &it) {\n\t\tIt i = it;\n\t\treturn --i;\n\t}\n\n\t/// Next iterator\n\ttemplate<class It> It next(const It &it) {\n\t\tIt i = it;\n\t\treturn ++i;\n\t}\n\n\t/// Iterator range\n\ttemplate<class T, class It = typename T::iterator> struct Range : std::pair<It, It> {\n\t\ttypedef It Iterator;\n\t\tRange() : std::pair<It, It>() {}\n\t\tRange(const It& f, const It& s) : std::pair<It, It>(f, s) {}\n\t\tRange(T& container) : std::pair<It, It>(container.begin(), container.end()) {}\n\t\tbool empty() const {return this->first == this->second;}\n\t\tsize_t size() const {return std::distance(this->first, this->second);}\n\t};\n\n\t/// Const iterator range\n\ttemplate<class T> struct ConstRange : Range<T, typename T::const_iterator> {\n\t\tConstRange() : Range<T, typename T::const_iterator>() {}\n\t\tConstRange(const typename T::const_iterator& f, const typename T::const_iterator& s) : Range<T, typename T::const_iterator>(f, s) {}\n\t\tConstRange(const T& container) : Range<T, typename T::const_iterator>(container.begin(), container.end()) {}\n\t};\n\n\tinline void append_num(std::string& str, size_t num)\n\t{\n\t\tif (num >= 10)\n\t\t\tappend_num(str, num / 10);\n\t\tstr.append(1, static_cast<char>('0' + num % 10));\n\t}\n\n#if defined(JITASM_DEBUG_DUMP) && defined(JITASM_WIN)\n\t/// Debug trace\n\tinline void Trace(const char *format, ...)\n\t{\n\t\tchar szBuf[256];\n\t\tva_list args;\n\t\tva_start(args, format);\n#if _MSC_VER >= 1400\t// VC8 or later\n\t\t_vsnprintf_s(szBuf, sizeof(szBuf) / sizeof(char), format, args);\n#else\n\t\tvsnprintf(szBuf, sizeof(szBuf) / sizeof(char), format, args);\n#endif\n\t\tva_end(args);\n\t\t::OutputDebugStringA(szBuf);\n\t}\n#endif\n\n\t/// Executable code buffer\n\tclass CodeBuffer\n\t{\n\t\tvoid*\tpbuff_;\n\t\tsize_t\tcodesize_;\n\t\tsize_t\tbuffsize_;\n\n\tpublic:\n\t\tCodeBuffer() : pbuff_(NULL), codesize_(0), buffsize_(0) {}\n\t\t~CodeBuffer() {Reset(0);}\n\n\t\tvoid* GetPointer() const {return pbuff_;}\n\t\tsize_t GetCodeSize() const {return codesize_;}\n\t\tsize_t GetBufferSize() const {return buffsize_;}\n\n\t\tbool Reset(size_t codesize)\n\t\t{\n\t\t\tif (pbuff_) {\n#if defined(JITASM_WIN)\n\t\t\t\t::VirtualFree(pbuff_, 0, MEM_RELEASE);\n#else\n\t\t\t\tmunmap(pbuff_, buffsize_);\n#endif\n\t\t\t\tpbuff_ = NULL;\n\t\t\t\tcodesize_ = 0;\n\t\t\t\tbuffsize_ = 0;\n\t\t\t}\n\t\t\tif (codesize) {\n#if defined(JITASM_WIN)\n\t\t\t\tvoid* pbuff = ::VirtualAlloc(NULL, codesize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);\n\t\t\t\tif (!pbuff) {\n\t\t\t\t\tJITASM_ASSERT(0);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tMEMORY_BASIC_INFORMATION info;\n\t\t\t\t::VirtualQuery(pbuff, &info, sizeof(info));\n\t\t\t\tbuffsize_ = info.RegionSize;\n#else\n\t\t\t\tint pagesize = getpagesize();\n\t\t\t\tsize_t buffsize = (codesize + pagesize - 1) / pagesize * pagesize;\n\t\t\t\tvoid* pbuff = mmap(NULL, buffsize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);\n\t\t\t\tif (!pbuff) {\n\t\t\t\t\tJITASM_ASSERT(0);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbuffsize_ = buffsize;\n#endif\n\n\t\t\t\tpbuff_ = pbuff;\n\t\t\t\tcodesize_ = codesize;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t};\n\n\t/// Stack manager\n\t/**\n\t * <b>Stack layout</b>\n\t * \\verbatim\n\t * +-----------------------+\n\t * | Caller return address |\n\t * +=======================+========\n\t * |       ebp (rbp)       |\n\t * +-----------------------+ <-- ebp (rbp)\n\t * |  Saved gp registers   |\n\t * +-----------------------+\n\t * | Padding for alignment |\n\t * +-----------------------+ <-- Stack base\n\t * |    Spill slots and    |\n\t * |    local variable     |\n\t * +-----------------------+ <-- esp (rsp)\n\t * \\endverbatim\n\t */\n\tclass StackManager\n\t{\n\tprivate:\n\t\tAddr stack_base_;\n\t\tuint32 stack_size_;\n\n\tpublic:\n\t\tStackManager() : stack_base_(RegID::CreatePhysicalRegID(R_TYPE_GP, EBX), 0), stack_size_(0) {}\n\n\t\t/// Get allocated stack size\n\t\tuint32 GetSize() const {return (stack_size_ + 15) / 16 * 16; /* 16 bytes aligned*/}\n\n\t\t/// Get stack base\n\t\tAddr GetStackBase() const {return stack_base_;}\n\n\t\t/// Set stack base\n\t\tvoid SetStackBase(const Addr& stack_base) {stack_base_ = stack_base;}\n\n\t\t/// Allocate stack\n\t\tAddr Alloc(uint32 size, uint32 alignment)\n\t\t{\n\t\t\tstack_size_ = (stack_size_ + alignment - 1) / alignment * alignment;\n\t\t\tstack_size_ += size;\n\t\t\treturn stack_base_ - stack_size_;\n\t\t}\n\t};\n\n\t/// Spin lock\n\tclass SpinLock\n\t{\n\t\tlong lock_;\n\tpublic:\n\t\tSpinLock() : lock_(0) {}\n\t\tvoid Lock() {while (interlocked_exchange(&lock_, 1));}\n\t\tvoid Unlock() {interlocked_exchange(&lock_, 0);}\n\t};\n\n\ttemplate<class Ty>\n\tclass ScopedLock\n\t{\n\t\tTy& lock_;\n\t\tScopedLock<Ty>& operator=(const ScopedLock<Ty>&);\n\tpublic:\n\t\tScopedLock(Ty& lock) : lock_(lock) {lock.Lock();}\n\t\t~ScopedLock() {lock_.Unlock();}\n\t};\n}\t// namespace detail\n\n// compiler prototype declaration\nstruct Frontend;\nnamespace compiler {\n\tvoid Compile(Frontend& f);\n}\n\n/// jitasm frontend\nstruct Frontend\n{\n\ttypedef jitasm::Addr\tAddr;\n\ttypedef jitasm::Reg\t\tReg;\n\ttypedef jitasm::Reg8\tReg8;\n\ttypedef jitasm::Reg16\tReg16;\n\ttypedef jitasm::Reg32\tReg32;\n#ifdef JITASM64\n\ttypedef jitasm::Reg64\tReg64;\n#endif\n\ttypedef jitasm::MmxReg\tMmxReg;\n\ttypedef jitasm::XmmReg\tXmmReg;\n\ttypedef jitasm::YmmReg\tYmmReg;\n\n\tstatic Reg8\t\t\tal, cl, dl, bl, ah, ch, dh, bh;\n\tstatic Reg16\t\tax, cx, dx, bx, sp, bp, si, di;\n\tstatic Reg32\t\teax, ecx, edx, ebx, esp, ebp, esi, edi;\n\tstatic FpuReg_st0\tst0;\n\tstatic FpuReg\t\tst1, st2, st3, st4, st5, st6, st7;\n\tstatic MmxReg\t\tmm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7;\n\tstatic XmmReg\t\txmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7;\n\tstatic YmmReg\t\tymm0, ymm1, ymm2, ymm3, ymm4, ymm5, ymm6, ymm7;\n#ifdef JITASM64\n\tstatic Reg8\t\t\tr8b, r9b, r10b, r11b, r12b, r13b, r14b, r15b;\n\tstatic Reg16\t\tr8w, r9w, r10w, r11w, r12w, r13w, r14w, r15w;\n\tstatic Reg32\t\tr8d, r9d, r10d, r11d, r12d, r13d, r14d, r15d;\n\tstatic Reg64\t\trax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15;\n\tstatic XmmReg\t\txmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15;\n\tstatic YmmReg\t\tymm8, ymm9, ymm10, ymm11, ymm12, ymm13, ymm14, ymm15;\n#endif\n\n\tAddressingPtr<Opd8>\t\tbyte_ptr;\n\tAddressingPtr<Opd16>\tword_ptr;\n\tAddressingPtr<Opd32>\tdword_ptr;\n\tAddressingPtr<Opd64>\tqword_ptr;\n\tAddressingPtr<Opd64>\tmmword_ptr;\n\tAddressingPtr<Opd128>\txmmword_ptr;\n\tAddressingPtr<Opd256>\tymmword_ptr;\n\tAddressingPtr<Opd32>\treal4_ptr;\n\tAddressingPtr<Opd64>\treal8_ptr;\n\tAddressingPtr<Opd80>\treal10_ptr;\n\tAddressingPtr<Opd16>\tm2byte_ptr;\n\tAddressingPtr<Opd224>\tm28byte_ptr;\n\tAddressingPtr<Opd864>\tm108byte_ptr;\n\tAddressingPtr<Opd4096>\tm512byte_ptr;\n\n\tstatic Reg\t\t\tzax, zcx, zdx, zbx, zsp, zbp, zsi, zdi;\n#ifdef JITASM64\n\tAddressingPtr<Opd64>\tptr;\n#else\n\tAddressingPtr<Opd32>\tptr;\n#endif\n\n\ttypedef std::vector<Instr> InstrList;\n\tInstrList\t\t\t\tinstrs_;\n\tbool\t\t\t\t\tassembled_;\n\tbool avx_epilog_; // PF AVS+: avoid AVX transition penalties\n\tdetail::CodeBuffer\t\tcodebuff_;\n\tdetail::SpinLock\t\tcodelock_;\n\tdetail::StackManager\tstack_manager_;\n\n\tstruct Label\n\t{\n\t\tstd::string\tname;\n\t\tsize_t\t\tinstr_number;\n\t\texplicit Label(const std::string& name_) : name(name_), instr_number(0) {}\n\t};\n\ttypedef std::deque<Label> LabelList;\n\tLabelList\tlabels_;\n\n\n\tFrontend() : assembled_(false) {}\n\tvirtual ~Frontend() {}\n\n\tvirtual void InternalMain() = 0;\n\n\t/// Declare variable of the function argument on register\n\tvoid DeclareRegArg(const detail::Opd& var, const detail::Opd& arg, const detail::Opd& spill_slot = detail::Opd())\n\t{\n\t\tJITASM_ASSERT(var.IsReg() && arg.IsReg());\n\t\t// Insert special instruction after Prolog\n\t\tInstrList::iterator it = instrs_.begin();\n\t\tif (!instrs_.empty() && instrs_[0].GetID() == I_COMPILER_PROLOG) ++it;\n\t\t// The arg is passed as register constraint of the var.\n\t\tinstrs_.insert(it, Instr(I_COMPILER_DECLARE_REG_ARG, 0, E_SPECIAL, Dummy(W(var), arg), spill_slot));\n\t}\n\n\t/// Declare variable of the function argument on stack\n\tvoid DeclareStackArg(const detail::Opd& var, const detail::Opd& arg)\n\t{\n\t\tJITASM_ASSERT(var.IsReg() && arg.IsMem());\n\t\t// Insert special instruction after Prolog\n\t\tInstrList::iterator it = instrs_.begin();\n\t\tif (!instrs_.empty() && instrs_[0].GetID() == I_COMPILER_PROLOG) ++it;\n\t\tinstrs_.insert(it, Instr(I_COMPILER_DECLARE_STACK_ARG, 0, E_SPECIAL, W(var), R(arg)));\n\t}\n\n\t/// Declare variable of the function result on register\n\tvoid DeclareResultReg(const detail::Opd& var)\n\t{\n\t\tJITASM_ASSERT(var.IsReg());\n\t\t// The result register is passed as register constraint of the var.\n\t\tif (var.IsGpReg()) {\n\t\t\tAppendInstr(I_COMPILER_DECLARE_RESULT_REG, 0, E_SPECIAL, Dummy(R(var), zax));\n\t\t} else if (var.IsMmxReg()) {\n\t\t\tAppendInstr(I_COMPILER_DECLARE_RESULT_REG, 0, E_SPECIAL, Dummy(R(var), mm0));\n\t\t} else if (var.IsXmmReg()) {\n\t\t\tAppendInstr(I_COMPILER_DECLARE_RESULT_REG, 0, E_SPECIAL, Dummy(R(var), xmm0));\n\t\t}\n\t}\n\n\t/// Function prolog\n\tvoid Prolog()\n\t{\n\t\tAppendInstr(I_COMPILER_PROLOG, 0, E_SPECIAL);\n\t}\n\n\t/// Function epilog\n\tvoid Epilog()\n\t{\n\t\tAppendInstr(I_COMPILER_EPILOG, 0, E_SPECIAL);\n\t}\n\n\tstatic bool IsJump(InstrID id)\n\t{\n\t\treturn id == I_JMP || id == I_JCC || id == I_LOOP;\n\t}\n\n\tsize_t GetJumpTo(const Instr& instr) const\n\t{\n\t\tsize_t label_id = (size_t) instr.GetOpd(0).GetImm();\n\t\tJITASM_ASSERT(labels_[label_id].instr_number != (size_t)-1);\t// invalid label\n\t\treturn labels_[label_id].instr_number;\n\t}\n\n\t// TODO: Return an error when there is no destination.\n\tvoid ResolveJump()\n\t{\n\t\t// Replace label indexes with instruncion numbers.\n\t\tfor (InstrList::iterator it = instrs_.begin(); it != instrs_.end(); ++it) {\n\t\t\tInstr& instr = *it;\n\t\t\tif (IsJump(instr.GetID())) {\n\t\t\t\tinstr = Instr(instr.GetID(), instr.opcode_, instr.encoding_flag_, Imm8(0x7F), Imm64(GetJumpTo(instr)));\t// Opd(0) = max value in sint8, Opd(1) = instruction number\n\t\t\t}\n\t\t}\n\n\t\t// Resolve operand sizes.\n\t\tstd::vector<int> offsets;\n\t\toffsets.reserve(instrs_.size() + 1);\n\t\tbool retry;\n\t\tdo {\n\t\t\toffsets.clear();\n\t\t\toffsets.push_back(0);\n\t\t\tBackend pre;\n\t\t\tfor (InstrList::const_iterator it = instrs_.begin(); it != instrs_.end(); ++it) {\n\t\t\t\tpre.Assemble(*it);\n\t\t\t\toffsets.push_back((int) pre.GetSize());\n\t\t\t}\n\n\t\t\tretry = false;\n\t\t\tfor (size_t i = 0; i < instrs_.size(); i++) {\n\t\t\t\tInstr& instr = instrs_[i];\n\t\t\t\tif (IsJump(instr.GetID())) {\n\t\t\t\t\tsize_t d = (size_t) instr.GetOpd(1).GetImm();\n\t\t\t\t\tint rel = (int) offsets[d] - offsets[i + 1];\n\t\t\t\t\tOpdSize size = instr.GetOpd(0).GetSize();\n\t\t\t\t\tif (size == O_SIZE_8) {\n\t\t\t\t\t\tif (!detail::IsInt8(rel)) {\n\t\t\t\t\t\t\t// jrcxz, jcxz, jecxz, loop, loope, loopne are only for short jump\n\t\t\t\t\t\t\tuint32 tttn = instr.opcode_;\n\t\t\t\t\t\t\tif (instr.GetID() == I_JCC && (tttn == JCC_CXZ || tttn == JCC_ECXZ || tttn == JCC_RCXZ)) JITASM_ASSERT(0);\n\t\t\t\t\t\t\tif (instr.GetID() == I_LOOP) JITASM_ASSERT(0);\n\n\t\t\t\t\t\t\t// Retry with immediate 32\n\t\t\t\t\t\t\tinstr = Instr(instr.GetID(), instr.opcode_, instr.encoding_flag_, Imm32(0x7FFFFFFF), Imm64(instr.GetOpd(1).GetImm()));\n\t\t\t\t\t\t\tretry = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (size == O_SIZE_32) {\n\t\t\t\t\t\tJITASM_ASSERT(detail::IsInt32(rel));\t// There is no jump instruction larger than immediate 32.\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} while (retry);\n\n\t\t// Resolve immediates\n\t\tfor (size_t i = 0; i < instrs_.size(); i++) {\n\t\t\tInstr& instr = instrs_[i];\n\t\t\tif (IsJump(instr.GetID())) {\n\t\t\t\tsize_t d = (size_t) instr.GetOpd(1).GetImm();\n\t\t\t\tint rel = (int) offsets[d] - offsets[i + 1];\n\t\t\t\tOpdSize size = instr.GetOpd(0).GetSize();\n\t\t\t\tif (size == O_SIZE_8) {\n\t\t\t\t\tJITASM_ASSERT(detail::IsInt8(rel));\n\t\t\t\t\tinstr = Instr(instr.GetID(), instr.opcode_, instr.encoding_flag_, Imm8((uint8) rel));\n\t\t\t\t} else if (size == O_SIZE_32) {\n\t\t\t\t\tJITASM_ASSERT(detail::IsInt32(rel));\n\t\t\t\t\tinstr = Instr(instr.GetID(), instr.opcode_, instr.encoding_flag_, Imm32((uint32) rel));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/// Assemble\n\tvoid Assemble()\n\t{\n\t\tdetail::ScopedLock<detail::SpinLock> lock(codelock_);\n\t\tif (assembled_) return;\n\n\t\tinstrs_.clear();\n\t\tlabels_.clear();\n\t\tinstrs_.reserve(128);\n\n\t\tInternalMain();\n\t\tcompiler::Compile(*this);\n\n\t\t// Resolve jump instructions\n\t\tif (!labels_.empty()) {\n\t\t\tResolveJump();\n\t\t}\n\n\t\t// Count total size of machine code\n\t\tBackend pre;\n\t\tfor (InstrList::const_iterator it = instrs_.begin(); it != instrs_.end(); ++it) {\n\t\t\tpre.Assemble(*it);\n\t\t}\n\t\tsize_t codesize = pre.GetSize();\n\n\t\t// Write machine code to the buffer\n\t\tcodebuff_.Reset(codesize);\n\t\tBackend backend(codebuff_.GetPointer(), codebuff_.GetBufferSize());\n\t\tfor (InstrList::const_iterator it = instrs_.begin(); it != instrs_.end(); ++it) {\n\t\t\tbackend.Assemble(*it);\n\t\t}\n\n\t\tInstrList().swap(instrs_);\n\t\tLabelList().swap(labels_);\n\t\tassembled_ = true;\n\t}\n\n\t/// Get assembled code\n\tvoid *GetCode(bool force_avx_epilog = false)\n\t{\n\t\tavx_epilog_ = force_avx_epilog; // PF AVS+: anti penalty\n\t\tif (!assembled_) {\n\t\t\tAssemble();\n\t\t}\n\t\treturn codebuff_.GetPointer();\n\t}\n\n\t/// Get total size of machine code\n\tsize_t GetCodeSize() const\n\t{\n\t\treturn codebuff_.GetCodeSize();\n\t}\n\n\tvoid AppendInstr(InstrID id, uint32 opcode, uint32 encoding_flag, const detail::Opd& opd1 = detail::Opd(), const detail::Opd& opd2 = detail::Opd(), const detail::Opd& opd3 = detail::Opd(), const detail::Opd& opd4 = detail::Opd(), const detail::Opd& opd5 = detail::Opd(), const detail::Opd& opd6 = detail::Opd())\n\t{\n\t\tinstrs_.push_back(Instr(id, opcode, encoding_flag, opd1, opd2, opd3, opd4, opd5, opd6));\n\t}\n\n\tvoid AppendJmp(size_t label_id)\n\t{\n\t\tAppendInstr(I_JMP, 0, E_SPECIAL, Imm64(label_id));\n\t}\n\n\tvoid AppendJcc(JumpCondition jcc, size_t label_id)\n\t{\n\t\tAppendInstr(I_JCC, jcc, E_SPECIAL, Imm64(label_id));\n\t}\n\n\t/// Change label id of jump instruction\n\tstatic void ChangeLabelID(Instr& instr, size_t label_id)\n\t{\n\t\tJITASM_ASSERT(IsJump(instr.id_) && instr.GetOpd(0).IsImm());\n\t\tinstr.GetOpd(0).imm_ = label_id;\n\t}\n\n\tsize_t NewLabelID(const std::string& label_name)\n\t{\n\t\tlabels_.push_back(Label(label_name));\n\t\treturn labels_.size() - 1;\n\t}\n\n\tsize_t GetLabelID(const std::string& label_name)\n\t{\n\t\tfor (size_t i = 0; i < labels_.size(); i++) {\n\t\t\tif (labels_[i].name == label_name) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn NewLabelID(label_name);\n\t}\n\n\tvoid L(size_t label_id)\n\t{\n\t\tlabels_[label_id].instr_number = instrs_.size();\t// Label current instruction\n\t}\n\n\t/// Label\n\tvoid L(const std::string& label_name)\n\t{\n\t\tJITASM_ASSERT(!label_name.empty());\n\t\tL(GetLabelID(label_name));\n\t}\n\n\t// General-Purpose Instructions\n\tvoid adc(const Reg8& dst, const Imm8& imm)\t\t{AppendInstr(I_ADC, 0x80, E_SPECIAL, Imm8(2), RW(dst), imm);}\n\tvoid adc(const Mem8& dst, const Imm8& imm)\t\t{AppendInstr(I_ADC, 0x80, 0, Imm8(2), RW(dst), imm);}\n\tvoid adc(const Reg16& dst, const Imm16& imm)\t{AppendInstr(I_ADC, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(2), RW(dst), detail::ImmXor8(imm));}\n\tvoid adc(const Mem16& dst, const Imm16& imm)\t{AppendInstr(I_ADC, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst), detail::ImmXor8(imm));}\n\tvoid adc(const Reg32& dst, const Imm32& imm)\t{AppendInstr(I_ADC, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_SPECIAL, Imm8(2), RW(dst), detail::ImmXor8(imm));}\n\tvoid adc(const Mem32& dst, const Imm32& imm)\t{AppendInstr(I_ADC, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, 0, Imm8(2), RW(dst), detail::ImmXor8(imm));}\n\tvoid adc(const Reg8& dst, const Reg8& src)\t\t{AppendInstr(I_ADC, 0x12, 0, RW(dst), R(src));}\n\tvoid adc(const Mem8& dst, const Reg8& src)\t\t{AppendInstr(I_ADC, 0x10, 0, R(src), RW(dst));}\n\tvoid adc(const Reg8& dst, const Mem8& src)\t\t{AppendInstr(I_ADC, 0x12, 0, RW(dst), R(src));}\n\tvoid adc(const Reg16& dst, const Reg16& src)\t{AppendInstr(I_ADC, 0x13, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid adc(const Mem16& dst, const Reg16& src)\t{AppendInstr(I_ADC, 0x11, E_OPERAND_SIZE_PREFIX, R(src), RW(dst));}\n\tvoid adc(const Reg16& dst, const Mem16& src)\t{AppendInstr(I_ADC, 0x13, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid adc(const Reg32& dst, const Reg32& src)\t{AppendInstr(I_ADC, 0x13, 0, RW(dst), R(src));}\n\tvoid adc(const Mem32& dst, const Reg32& src)\t{AppendInstr(I_ADC, 0x11, 0, R(src), RW(dst));}\n\tvoid adc(const Reg32& dst, const Mem32& src)\t{AppendInstr(I_ADC, 0x13, 0, RW(dst), R(src));}\n#ifdef JITASM64\n\tvoid adc(const Reg64& dst, const Imm32& imm)\t{AppendInstr(I_ADC, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX | E_SPECIAL, Imm8(2), RW(dst), detail::ImmXor8(imm));}\n\tvoid adc(const Mem64& dst, const Imm32& imm)\t{AppendInstr(I_ADC, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX, Imm8(2), RW(dst), detail::ImmXor8(imm));}\n\tvoid adc(const Reg64& dst, const Reg64& src)\t{AppendInstr(I_ADC, 0x13, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid adc(const Mem64& dst, const Reg64& src)\t{AppendInstr(I_ADC, 0x11, E_REXW_PREFIX, R(src), RW(dst));}\n\tvoid adc(const Reg64& dst, const Mem64& src)\t{AppendInstr(I_ADC, 0x13, E_REXW_PREFIX, RW(dst), R(src));}\n#endif\n\tvoid add(const Reg8& dst, const Imm8& imm)\t\t{AppendInstr(I_ADD, 0x80, E_SPECIAL, Imm8(0), RW(dst), imm);}\n\tvoid add(const Mem8& dst, const Imm8& imm)\t\t{AppendInstr(I_ADD, 0x80, 0, Imm8(0), RW(dst), imm);}\n\tvoid add(const Reg16& dst, const Imm16& imm)\t{AppendInstr(I_ADD, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(0), RW(dst), detail::ImmXor8(imm));}\n\tvoid add(const Mem16& dst, const Imm16& imm)\t{AppendInstr(I_ADD, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst), detail::ImmXor8(imm));}\n\tvoid add(const Reg32& dst, const Imm32& imm)\t{AppendInstr(I_ADD, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_SPECIAL, Imm8(0), RW(dst), detail::ImmXor8(imm));}\n\tvoid add(const Mem32& dst, const Imm32& imm)\t{AppendInstr(I_ADD, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, 0, Imm8(0), RW(dst), detail::ImmXor8(imm));}\n\tvoid add(const Reg8& dst, const Reg8& src)\t\t{AppendInstr(I_ADD, 0x02, 0, RW(dst), R(src));}\n\tvoid add(const Mem8& dst, const Reg8& src)\t\t{AppendInstr(I_ADD, 0x00, 0, R(src), RW(dst));}\n\tvoid add(const Reg8& dst, const Mem8& src)\t\t{AppendInstr(I_ADD, 0x02, 0, RW(dst), R(src));}\n\tvoid add(const Reg16& dst, const Reg16& src)\t{AppendInstr(I_ADD, 0x03, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid add(const Mem16& dst, const Reg16& src)\t{AppendInstr(I_ADD, 0x01, E_OPERAND_SIZE_PREFIX, R(src), RW(dst));}\n\tvoid add(const Reg16& dst, const Mem16& src)\t{AppendInstr(I_ADD, 0x03, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid add(const Reg32& dst, const Reg32& src)\t{AppendInstr(I_ADD, 0x03, 0, RW(dst), R(src));}\n\tvoid add(const Mem32& dst, const Reg32& src)\t{AppendInstr(I_ADD, 0x01, 0, R(src), RW(dst));}\n\tvoid add(const Reg32& dst, const Mem32& src)\t{AppendInstr(I_ADD, 0x03, 0, RW(dst), R(src));}\n#ifdef JITASM64\n\tvoid add(const Reg64& dst, const Imm32& imm)\t{AppendInstr(I_ADD, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX | E_SPECIAL, Imm8(0), RW(dst), detail::ImmXor8(imm));}\n\tvoid add(const Mem64& dst, const Imm32& imm)\t{AppendInstr(I_ADD, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX, Imm8(0), RW(dst), detail::ImmXor8(imm));}\n\tvoid add(const Reg64& dst, const Reg64& src)\t{AppendInstr(I_ADD, 0x03, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid add(const Mem64& dst, const Reg64& src)\t{AppendInstr(I_ADD, 0x01, E_REXW_PREFIX, R(src), RW(dst));}\n\tvoid add(const Reg64& dst, const Mem64& src)\t{AppendInstr(I_ADD, 0x03, E_REXW_PREFIX, RW(dst), R(src));}\n#endif\n\tvoid and_(const Reg8& dst, const Imm8& imm)\t\t{AppendInstr(I_AND, 0x80, E_SPECIAL, Imm8(4), RW(dst), imm);}\n\tvoid and_(const Mem8& dst, const Imm8& imm)\t\t{AppendInstr(I_AND, 0x80, 0, Imm8(4), RW(dst), imm);}\n\tvoid and_(const Reg16& dst, const Imm16& imm)\t{AppendInstr(I_AND, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(4), RW(dst), detail::ImmXor8(imm));}\n\tvoid and_(const Mem16& dst, const Imm16& imm)\t{AppendInstr(I_AND, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX, Imm8(4), RW(dst), detail::ImmXor8(imm));}\n\tvoid and_(const Reg32& dst, const Imm32& imm)\t{AppendInstr(I_AND, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_SPECIAL, Imm8(4), RW(dst), detail::ImmXor8(imm));}\n\tvoid and_(const Mem32& dst, const Imm32& imm)\t{AppendInstr(I_AND, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, 0, Imm8(4), RW(dst), detail::ImmXor8(imm));}\n\tvoid and_(const Reg8& dst, const Reg8& src)\t\t{AppendInstr(I_AND, 0x22, 0, RW(dst), R(src));}\n\tvoid and_(const Mem8& dst, const Reg8& src)\t\t{AppendInstr(I_AND, 0x20, 0, R(src), RW(dst));}\n\tvoid and_(const Reg8& dst, const Mem8& src)\t\t{AppendInstr(I_AND, 0x22, 0, RW(dst), R(src));}\n\tvoid and_(const Reg16& dst, const Reg16& src)\t{AppendInstr(I_AND, 0x23, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid and_(const Mem16& dst, const Reg16& src)\t{AppendInstr(I_AND, 0x21, E_OPERAND_SIZE_PREFIX, R(src), RW(dst));}\n\tvoid and_(const Reg16& dst, const Mem16& src)\t{AppendInstr(I_AND, 0x23, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid and_(const Reg32& dst, const Reg32& src)\t{AppendInstr(I_AND, 0x23, 0, RW(dst), R(src));}\n\tvoid and_(const Mem32& dst, const Reg32& src)\t{AppendInstr(I_AND, 0x21, 0, R(src), RW(dst));}\n\tvoid and_(const Reg32& dst, const Mem32& src)\t{AppendInstr(I_AND, 0x23, 0, RW(dst), R(src));}\n#ifdef JITASM64\n\t// and with Imm32 is sign extended\n\tvoid and_(const Reg64& dst, const Imm32& imm)\t{AppendInstr(I_AND, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX | E_SPECIAL, Imm8(4), RW(dst), detail::ImmXor8(imm));}\n\tvoid and_(const Mem64& dst, const Imm32& imm)\t{AppendInstr(I_AND, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX, Imm8(4), RW(dst), detail::ImmXor8(imm));}\n\tvoid and_(const Reg64& dst, const Reg64& src)\t{AppendInstr(I_AND, 0x23, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid and_(const Mem64& dst, const Reg64& src)\t{AppendInstr(I_AND, 0x21, E_REXW_PREFIX, R(src), RW(dst));}\n\tvoid and_(const Reg64& dst, const Mem64& src)\t{AppendInstr(I_AND, 0x23, E_REXW_PREFIX, RW(dst), R(src));}\n#endif\n\tvoid bsf(const Reg16& dst, const Reg16& src)\t{AppendInstr(I_BSF, 0x0FBC, E_OPERAND_SIZE_PREFIX, W(dst), R(src));}\n\tvoid bsf(const Reg16& dst, const Mem16& src)\t{AppendInstr(I_BSF, 0x0FBC, E_OPERAND_SIZE_PREFIX, W(dst), R(src));}\n\tvoid bsf(const Reg32& dst, const Reg32& src)\t{AppendInstr(I_BSF, 0x0FBC, 0, W(dst), R(src));}\n\tvoid bsf(const Reg32& dst, const Mem32& src)\t{AppendInstr(I_BSF, 0x0FBC, 0, W(dst), R(src));}\n#ifdef JITASM64\n\tvoid bsf(const Reg64& dst, const Reg64& src)\t{AppendInstr(I_BSF, 0x0FBC, E_REXW_PREFIX, W(dst), R(src));}\n\tvoid bsf(const Reg64& dst, const Mem64& src)\t{AppendInstr(I_BSF, 0x0FBC, E_REXW_PREFIX, W(dst), R(src));}\n#endif\n\tvoid bsr(const Reg16& dst, const Reg16& src)\t{AppendInstr(I_BSR, 0x0FBD, E_OPERAND_SIZE_PREFIX, W(dst), R(src));}\n\tvoid bsr(const Reg16& dst, const Mem16& src)\t{AppendInstr(I_BSR, 0x0FBD, E_OPERAND_SIZE_PREFIX, W(dst), R(src));}\n\tvoid bsr(const Reg32& dst, const Reg32& src)\t{AppendInstr(I_BSR, 0x0FBD, 0, W(dst), R(src));}\n\tvoid bsr(const Reg32& dst, const Mem32& src)\t{AppendInstr(I_BSR, 0x0FBD, 0, W(dst), R(src));}\n#ifdef JITASM64\n\tvoid bsr(const Reg64& dst, const Reg64& src)\t{AppendInstr(I_BSR, 0x0FBD, E_REXW_PREFIX, W(dst), R(src));}\n\tvoid bsr(const Reg64& dst, const Mem64& src)\t{AppendInstr(I_BSR, 0x0FBD, E_REXW_PREFIX, W(dst), R(src));}\n#endif\n\tvoid bswap(const Reg32& dst)\t{AppendInstr(I_BSWAP, 0x0FC8, 0, RW(dst));}\n#ifdef JITASM64\n\tvoid bswap(const Reg64& dst)\t{AppendInstr(I_BSWAP, 0x0FC8, E_REXW_PREFIX, RW(dst));}\n#endif\n\tvoid bt(const Reg16& bitbase, const Reg16& bitoffset)\t{AppendInstr(I_BT, 0x0FA3, E_OPERAND_SIZE_PREFIX, R(bitoffset), R(bitbase));}\n\tvoid bt(const Mem16& bitbase, const Reg16& bitoffset)\t{AppendInstr(I_BT, 0x0FA3, E_OPERAND_SIZE_PREFIX, R(bitoffset), R(bitbase));}\n\tvoid bt(const Reg32& bitbase, const Reg32& bitoffset)\t{AppendInstr(I_BT, 0x0FA3, 0, R(bitoffset), R(bitbase));}\n\tvoid bt(const Mem32& bitbase, const Reg32& bitoffset)\t{AppendInstr(I_BT, 0x0FA3, 0, R(bitoffset), R(bitbase));}\n\tvoid bt(const Reg16& bitbase, const Imm8& bitoffset)\t{AppendInstr(I_BT, 0x0FBA, E_OPERAND_SIZE_PREFIX, Imm8(4), R(bitbase), bitoffset);}\n\tvoid bt(const Mem16& bitbase, const Imm8& bitoffset)\t{AppendInstr(I_BT, 0x0FBA, E_OPERAND_SIZE_PREFIX, Imm8(4), R(bitbase), bitoffset);}\n\tvoid bt(const Reg32& bitbase, const Imm8& bitoffset)\t{AppendInstr(I_BT, 0x0FBA, 0, Imm8(4), R(bitbase), bitoffset);}\n\tvoid bt(const Mem32& bitbase, const Imm8& bitoffset)\t{AppendInstr(I_BT, 0x0FBA, 0, Imm8(4), R(bitbase), bitoffset);}\n#ifdef JITASM64\n\tvoid bt(const Reg64& bitbase, const Reg64& bitoffset)\t{AppendInstr(I_BT, 0x0FA3, E_REXW_PREFIX, R(bitoffset), R(bitbase));}\n\tvoid bt(const Mem64& bitbase, const Reg64& bitoffset)\t{AppendInstr(I_BT, 0x0FA3, E_REXW_PREFIX, R(bitoffset), R(bitbase));}\n\tvoid bt(const Reg64& bitbase, const Imm8& bitoffset)\t{AppendInstr(I_BT, 0x0FBA, E_REXW_PREFIX, Imm8(4), R(bitbase), bitoffset);}\n\tvoid bt(const Mem64& bitbase, const Imm8& bitoffset)\t{AppendInstr(I_BT, 0x0FBA, E_REXW_PREFIX, Imm8(4), R(bitbase), bitoffset);}\n#endif\n\tvoid btc(const Reg16& bitbase, const Reg16& bitoffset)\t{AppendInstr(I_BTC, 0x0FBB, E_OPERAND_SIZE_PREFIX, R(bitoffset), RW(bitbase));}\n\tvoid btc(const Mem16& bitbase, const Reg16& bitoffset)\t{AppendInstr(I_BTC, 0x0FBB, E_OPERAND_SIZE_PREFIX, R(bitoffset), RW(bitbase));}\n\tvoid btc(const Reg32& bitbase, const Reg32& bitoffset)\t{AppendInstr(I_BTC, 0x0FBB, 0, R(bitoffset), RW(bitbase));}\n\tvoid btc(const Mem32& bitbase, const Reg32& bitoffset)\t{AppendInstr(I_BTC, 0x0FBB, 0, R(bitoffset), RW(bitbase));}\n\tvoid btc(const Reg16& bitbase, const Imm8& bitoffset)\t{AppendInstr(I_BTC, 0x0FBA, E_OPERAND_SIZE_PREFIX, Imm8(7), RW(bitbase), bitoffset);}\n\tvoid btc(const Mem16& bitbase, const Imm8& bitoffset)\t{AppendInstr(I_BTC, 0x0FBA, E_OPERAND_SIZE_PREFIX, Imm8(7), RW(bitbase), bitoffset);}\n\tvoid btc(const Reg32& bitbase, const Imm8& bitoffset)\t{AppendInstr(I_BTC, 0x0FBA, 0, Imm8(7), RW(bitbase), bitoffset);}\n\tvoid btc(const Mem32& bitbase, const Imm8& bitoffset)\t{AppendInstr(I_BTC, 0x0FBA, 0, Imm8(7), RW(bitbase), bitoffset);}\n#ifdef JITASM64\n\tvoid btc(const Reg64& bitbase, const Reg64& bitoffset)\t{AppendInstr(I_BTC, 0x0FBB, E_REXW_PREFIX, R(bitoffset), RW(bitbase));}\n\tvoid btc(const Mem64& bitbase, const Reg64& bitoffset)\t{AppendInstr(I_BTC, 0x0FBB, E_REXW_PREFIX, R(bitoffset), RW(bitbase));}\n\tvoid btc(const Reg64& bitbase, const Imm8& bitoffset)\t{AppendInstr(I_BTC, 0x0FBA, E_REXW_PREFIX, Imm8(7), RW(bitbase), bitoffset);}\n\tvoid btc(const Mem64& bitbase, const Imm8& bitoffset)\t{AppendInstr(I_BTC, 0x0FBA, E_REXW_PREFIX, Imm8(7), RW(bitbase), bitoffset);}\n#endif\n\tvoid btr(const Reg16& bitbase, const Reg16& bitoffset)\t{AppendInstr(I_BTR, 0x0FB3, E_OPERAND_SIZE_PREFIX, R(bitoffset), RW(bitbase));}\n\tvoid btr(const Mem16& bitbase, const Reg16& bitoffset)\t{AppendInstr(I_BTR, 0x0FB3, E_OPERAND_SIZE_PREFIX, R(bitoffset), RW(bitbase));}\n\tvoid btr(const Reg32& bitbase, const Reg32& bitoffset)\t{AppendInstr(I_BTR, 0x0FB3, 0, R(bitoffset), RW(bitbase));}\n\tvoid btr(const Mem32& bitbase, const Reg32& bitoffset)\t{AppendInstr(I_BTR, 0x0FB3, 0, R(bitoffset), RW(bitbase));}\n\tvoid btr(const Reg16& bitbase, const Imm8& bitoffset)\t{AppendInstr(I_BTR, 0x0FBA, E_OPERAND_SIZE_PREFIX, Imm8(6), RW(bitbase), bitoffset);}\n\tvoid btr(const Mem16& bitbase, const Imm8& bitoffset)\t{AppendInstr(I_BTR, 0x0FBA, E_OPERAND_SIZE_PREFIX, Imm8(6), RW(bitbase), bitoffset);}\n\tvoid btr(const Reg32& bitbase, const Imm8& bitoffset)\t{AppendInstr(I_BTR, 0x0FBA, 0, Imm8(6), RW(bitbase), bitoffset);}\n\tvoid btr(const Mem32& bitbase, const Imm8& bitoffset)\t{AppendInstr(I_BTR, 0x0FBA, 0, Imm8(6), RW(bitbase), bitoffset);}\n#ifdef JITASM64\n\tvoid btr(const Reg64& bitbase, const Reg64& bitoffset)\t{AppendInstr(I_BTR, 0x0FB3, E_REXW_PREFIX, R(bitoffset), RW(bitbase));}\n\tvoid btr(const Mem64& bitbase, const Reg64& bitoffset)\t{AppendInstr(I_BTR, 0x0FB3, E_REXW_PREFIX, R(bitoffset), RW(bitbase));}\n\tvoid btr(const Reg64& bitbase, const Imm8& bitoffset)\t{AppendInstr(I_BTR, 0x0FBA, E_REXW_PREFIX, Imm8(6), RW(bitbase), bitoffset);}\n\tvoid btr(const Mem64& bitbase, const Imm8& bitoffset)\t{AppendInstr(I_BTR, 0x0FBA, E_REXW_PREFIX, Imm8(6), RW(bitbase), bitoffset);}\n#endif\n\tvoid bts(const Reg16& bitbase, const Reg16& bitoffset)\t{AppendInstr(I_BTS, 0x0FAB, E_OPERAND_SIZE_PREFIX, R(bitoffset), RW(bitbase));}\n\tvoid bts(const Mem16& bitbase, const Reg16& bitoffset)\t{AppendInstr(I_BTS, 0x0FAB, E_OPERAND_SIZE_PREFIX, R(bitoffset), RW(bitbase));}\n\tvoid bts(const Reg32& bitbase, const Reg32& bitoffset)\t{AppendInstr(I_BTS, 0x0FAB, 0, R(bitoffset), RW(bitbase));}\n\tvoid bts(const Mem32& bitbase, const Reg32& bitoffset)\t{AppendInstr(I_BTS, 0x0FAB, 0, R(bitoffset), RW(bitbase));}\n\tvoid bts(const Reg16& bitbase, const Imm8& bitoffset)\t{AppendInstr(I_BTS, 0x0FBA, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(bitbase), bitoffset);}\n\tvoid bts(const Mem16& bitbase, const Imm8& bitoffset)\t{AppendInstr(I_BTS, 0x0FBA, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(bitbase), bitoffset);}\n\tvoid bts(const Reg32& bitbase, const Imm8& bitoffset)\t{AppendInstr(I_BTS, 0x0FBA, 0, Imm8(5), RW(bitbase), bitoffset);}\n\tvoid bts(const Mem32& bitbase, const Imm8& bitoffset)\t{AppendInstr(I_BTS, 0x0FBA, 0, Imm8(5), RW(bitbase), bitoffset);}\n#ifdef JITASM64\n\tvoid bts(const Reg64& bitbase, const Reg64& bitoffset)\t{AppendInstr(I_BTS, 0x0FAB, E_REXW_PREFIX, R(bitoffset), RW(bitbase));}\n\tvoid bts(const Mem64& bitbase, const Reg64& bitoffset)\t{AppendInstr(I_BTS, 0x0FAB, E_REXW_PREFIX, R(bitoffset), RW(bitbase));}\n\tvoid bts(const Reg64& bitbase, const Imm8& bitoffset)\t{AppendInstr(I_BTS, 0x0FBA, E_REXW_PREFIX, Imm8(5), RW(bitbase), bitoffset);}\n\tvoid bts(const Mem64& bitbase, const Imm8& bitoffset)\t{AppendInstr(I_BTS, 0x0FBA, E_REXW_PREFIX, Imm8(5), RW(bitbase), bitoffset);}\n#endif\n#ifndef JITASM64\n\tvoid call(const Reg16& dst)\t{AppendInstr(I_CALL, 0xFF, E_OPERAND_SIZE_PREFIX, Imm8(2), R(dst));}\n\tvoid call(const Reg32& dst)\t{AppendInstr(I_CALL, 0xFF, 0, Imm8(2), R(dst));}\n#else\n\tvoid call(const Reg64& dst)\t{AppendInstr(I_CALL, 0xFF, 0, Imm8(2), R(dst));}\n#endif\n\tvoid cbw()\t{AppendInstr(I_CBW,\t0x98, E_OPERAND_SIZE_PREFIX, Dummy(RW(eax)));}\n\tvoid cwde()\t{AppendInstr(I_CBW,\t0x98, 0, Dummy(RW(eax)));}\n#ifdef JITASM64\n\tvoid cdqe()\t{AppendInstr(I_CBW,\t0x98, E_REXW_PREFIX, Dummy(RW(eax)));}\n#endif\n\tvoid clc()\t{AppendInstr(I_CLC,\t0xF8, 0);}\n\tvoid cld()\t{AppendInstr(I_CLD,\t0xFC, 0);}\n\tvoid cli()\t{AppendInstr(I_CLI,\t0xFA, 0);}\n#ifdef JITASM64\n\tvoid clts()\t{AppendInstr(I_CLTS,\t0x0F06, 0);}\n#endif\n\tvoid cmc()\t{AppendInstr(I_CMC,\t0xF5, 0);}\n\tvoid cmova(const Reg16& dst, const Reg16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F47, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmova(const Reg16& dst, const Mem16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F47, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovae(const Reg16& dst, const Reg16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F43, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovae(const Reg16& dst, const Mem16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F43, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovb(const Reg16& dst, const Reg16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F42, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovb(const Reg16& dst, const Mem16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F42, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovbe(const Reg16& dst, const Reg16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F46, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovbe(const Reg16& dst, const Mem16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F46, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovc(const Reg16& dst, const Reg16& src)\t\t{cmovb(dst, src);}\n\tvoid cmovc(const Reg16& dst, const Mem16& src)\t\t{cmovb(dst, src);}\n\tvoid cmove(const Reg16& dst, const Reg16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F44, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmove(const Reg16& dst, const Mem16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F44, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovg(const Reg16& dst, const Reg16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4F, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovg(const Reg16& dst, const Mem16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4F, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovge(const Reg16& dst, const Reg16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4D, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovge(const Reg16& dst, const Mem16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4D, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovl(const Reg16& dst, const Reg16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4C, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovl(const Reg16& dst, const Mem16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4C, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovle(const Reg16& dst, const Reg16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4E, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovle(const Reg16& dst, const Mem16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4E, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovna(const Reg16& dst, const Reg16& src)\t\t{cmovbe(dst, src);}\n\tvoid cmovna(const Reg16& dst, const Mem16& src)\t\t{cmovbe(dst, src);}\n\tvoid cmovnae(const Reg16& dst, const Reg16& src)\t{cmovb(dst, src);}\n\tvoid cmovnae(const Reg16& dst, const Mem16& src)\t{cmovb(dst, src);}\n\tvoid cmovnb(const Reg16& dst, const Reg16& src)\t\t{cmovae(dst, src);}\n\tvoid cmovnb(const Reg16& dst, const Mem16& src)\t\t{cmovae(dst, src);}\n\tvoid cmovnbe(const Reg16& dst, const Reg16& src)\t{cmova(dst, src);}\n\tvoid cmovnbe(const Reg16& dst, const Mem16& src)\t{cmova(dst, src);}\n\tvoid cmovnc(const Reg16& dst, const Reg16& src)\t\t{cmovae(dst, src);}\n\tvoid cmovnc(const Reg16& dst, const Mem16& src)\t\t{cmovae(dst, src);}\n\tvoid cmovne(const Reg16& dst, const Reg16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F45, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovne(const Reg16& dst, const Mem16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F45, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovng(const Reg16& dst, const Reg16& src)\t\t{cmovle(dst, src);}\n\tvoid cmovng(const Reg16& dst, const Mem16& src)\t\t{cmovle(dst, src);}\n\tvoid cmovnge(const Reg16& dst, const Reg16& src)\t{cmovl(dst, src);}\n\tvoid cmovnge(const Reg16& dst, const Mem16& src)\t{cmovl(dst, src);}\n\tvoid cmovnl(const Reg16& dst, const Reg16& src)\t\t{cmovge(dst, src);}\n\tvoid cmovnl(const Reg16& dst, const Mem16& src)\t\t{cmovge(dst, src);}\n\tvoid cmovnle(const Reg16& dst, const Reg16& src)\t{cmovg(dst, src);}\n\tvoid cmovnle(const Reg16& dst, const Mem16& src)\t{cmovg(dst, src);}\n\tvoid cmovno(const Reg16& dst, const Reg16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F41, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovno(const Reg16& dst, const Mem16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F41, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovnp(const Reg16& dst, const Reg16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4B, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovnp(const Reg16& dst, const Mem16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4B, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovns(const Reg16& dst, const Reg16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F49, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovns(const Reg16& dst, const Mem16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F49, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovnz(const Reg16& dst, const Reg16& src)\t\t{cmovne(dst, src);}\n\tvoid cmovnz(const Reg16& dst, const Mem16& src)\t\t{cmovne(dst, src);}\n\tvoid cmovo(const Reg16& dst, const Reg16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F40, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovo(const Reg16& dst, const Mem16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F40, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovp(const Reg16& dst, const Reg16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4A, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovp(const Reg16& dst, const Mem16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4A, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovpe(const Reg16& dst, const Reg16& src)\t\t{cmovp(dst, src);}\n\tvoid cmovpe(const Reg16& dst, const Mem16& src)\t\t{cmovp(dst, src);}\n\tvoid cmovpo(const Reg16& dst, const Reg16& src)\t\t{cmovnp(dst, src);}\n\tvoid cmovpo(const Reg16& dst, const Mem16& src)\t\t{cmovnp(dst, src);}\n\tvoid cmovs(const Reg16& dst, const Reg16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F48, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovs(const Reg16& dst, const Mem16& src)\t\t{AppendInstr(I_CMOVCC, 0x0F48, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid cmovz(const Reg16& dst, const Reg16& src)\t\t{cmove(dst, src);}\n\tvoid cmovz(const Reg16& dst, const Mem16& src)\t\t{cmove(dst, src);}\n\tvoid cmova(const Reg32& dst, const Reg32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F47, 0, RW(dst), R(src));}\n\tvoid cmova(const Reg32& dst, const Mem32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F47, 0, RW(dst), R(src));}\n\tvoid cmovae(const Reg32& dst, const Reg32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F43, 0, RW(dst), R(src));}\n\tvoid cmovae(const Reg32& dst, const Mem32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F43, 0, RW(dst), R(src));}\n\tvoid cmovb(const Reg32& dst, const Reg32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F42, 0, RW(dst), R(src));}\n\tvoid cmovb(const Reg32& dst, const Mem32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F42, 0, RW(dst), R(src));}\n\tvoid cmovbe(const Reg32& dst, const Reg32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F46, 0, RW(dst), R(src));}\n\tvoid cmovbe(const Reg32& dst, const Mem32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F46, 0, RW(dst), R(src));}\n\tvoid cmovc(const Reg32& dst, const Reg32& src)\t\t{cmovb(dst, src);}\n\tvoid cmovc(const Reg32& dst, const Mem32& src)\t\t{cmovb(dst, src);}\n\tvoid cmove(const Reg32& dst, const Reg32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F44, 0, RW(dst), R(src));}\n\tvoid cmove(const Reg32& dst, const Mem32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F44, 0, RW(dst), R(src));}\n\tvoid cmovg(const Reg32& dst, const Reg32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4F, 0, RW(dst), R(src));}\n\tvoid cmovg(const Reg32& dst, const Mem32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4F, 0, RW(dst), R(src));}\n\tvoid cmovge(const Reg32& dst, const Reg32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4D, 0, RW(dst), R(src));}\n\tvoid cmovge(const Reg32& dst, const Mem32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4D, 0, RW(dst), R(src));}\n\tvoid cmovl(const Reg32& dst, const Reg32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4C, 0, RW(dst), R(src));}\n\tvoid cmovl(const Reg32& dst, const Mem32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4C, 0, RW(dst), R(src));}\n\tvoid cmovle(const Reg32& dst, const Reg32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4E, 0, RW(dst), R(src));}\n\tvoid cmovle(const Reg32& dst, const Mem32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4E, 0, RW(dst), R(src));}\n\tvoid cmovna(const Reg32& dst, const Reg32& src)\t\t{cmovbe(dst, src);}\n\tvoid cmovna(const Reg32& dst, const Mem32& src)\t\t{cmovbe(dst, src);}\n\tvoid cmovnae(const Reg32& dst, const Reg32& src)\t{cmovb(dst, src);}\n\tvoid cmovnae(const Reg32& dst, const Mem32& src)\t{cmovb(dst, src);}\n\tvoid cmovnb(const Reg32& dst, const Reg32& src)\t\t{cmovae(dst, src);}\n\tvoid cmovnb(const Reg32& dst, const Mem32& src)\t\t{cmovae(dst, src);}\n\tvoid cmovnbe(const Reg32& dst, const Reg32& src)\t{cmova(dst, src);}\n\tvoid cmovnbe(const Reg32& dst, const Mem32& src)\t{cmova(dst, src);}\n\tvoid cmovnc(const Reg32& dst, const Reg32& src)\t\t{cmovae(dst, src);}\n\tvoid cmovnc(const Reg32& dst, const Mem32& src)\t\t{cmovae(dst, src);}\n\tvoid cmovne(const Reg32& dst, const Reg32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F45, 0, RW(dst), R(src));}\n\tvoid cmovne(const Reg32& dst, const Mem32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F45, 0, RW(dst), R(src));}\n\tvoid cmovng(const Reg32& dst, const Reg32& src)\t\t{cmovle(dst, src);}\n\tvoid cmovng(const Reg32& dst, const Mem32& src)\t\t{cmovle(dst, src);}\n\tvoid cmovnge(const Reg32& dst, const Reg32& src)\t{cmovl(dst, src);}\n\tvoid cmovnge(const Reg32& dst, const Mem32& src)\t{cmovl(dst, src);}\n\tvoid cmovnl(const Reg32& dst, const Reg32& src)\t\t{cmovge(dst, src);}\n\tvoid cmovnl(const Reg32& dst, const Mem32& src)\t\t{cmovge(dst, src);}\n\tvoid cmovnle(const Reg32& dst, const Reg32& src)\t{cmovg(dst, src);}\n\tvoid cmovnle(const Reg32& dst, const Mem32& src)\t{cmovg(dst, src);}\n\tvoid cmovno(const Reg32& dst, const Reg32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F41, 0, RW(dst), R(src));}\n\tvoid cmovno(const Reg32& dst, const Mem32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F41, 0, RW(dst), R(src));}\n\tvoid cmovnp(const Reg32& dst, const Reg32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4B, 0, RW(dst), R(src));}\n\tvoid cmovnp(const Reg32& dst, const Mem32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4B, 0, RW(dst), R(src));}\n\tvoid cmovns(const Reg32& dst, const Reg32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F49, 0, RW(dst), R(src));}\n\tvoid cmovns(const Reg32& dst, const Mem32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F49, 0, RW(dst), R(src));}\n\tvoid cmovnz(const Reg32& dst, const Reg32& src)\t\t{cmovne(dst, src);}\n\tvoid cmovnz(const Reg32& dst, const Mem32& src)\t\t{cmovne(dst, src);}\n\tvoid cmovo(const Reg32& dst, const Reg32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F40, 0, RW(dst), R(src));}\n\tvoid cmovo(const Reg32& dst, const Mem32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F40, 0, RW(dst), R(src));}\n\tvoid cmovp(const Reg32& dst, const Reg32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4A, 0, RW(dst), R(src));}\n\tvoid cmovp(const Reg32& dst, const Mem32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4A, 0, RW(dst), R(src));}\n\tvoid cmovpe(const Reg32& dst, const Reg32& src)\t\t{cmovp(dst, src);}\n\tvoid cmovpe(const Reg32& dst, const Mem32& src)\t\t{cmovp(dst, src);}\n\tvoid cmovpo(const Reg32& dst, const Reg32& src)\t\t{cmovnp(dst, src);}\n\tvoid cmovpo(const Reg32& dst, const Mem32& src)\t\t{cmovnp(dst, src);}\n\tvoid cmovs(const Reg32& dst, const Reg32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F48, 0, RW(dst), R(src));}\n\tvoid cmovs(const Reg32& dst, const Mem32& src)\t\t{AppendInstr(I_CMOVCC, 0x0F48, 0, RW(dst), R(src));}\n\tvoid cmovz(const Reg32& dst, const Reg32& src)\t\t{cmove(dst, src);}\n\tvoid cmovz(const Reg32& dst, const Mem32& src)\t\t{cmove(dst, src);}\n#ifdef JITASM64\n\tvoid cmova(const Reg64& dst, const Reg64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F47, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmova(const Reg64& dst, const Mem64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F47, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovae(const Reg64& dst, const Reg64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F43, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovae(const Reg64& dst, const Mem64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F43, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovb(const Reg64& dst, const Reg64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F42, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovb(const Reg64& dst, const Mem64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F42, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovbe(const Reg64& dst, const Reg64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F46, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovbe(const Reg64& dst, const Mem64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F46, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovc(const Reg64& dst, const Reg64& src)\t\t{cmovb(dst, src);}\n\tvoid cmovc(const Reg64& dst, const Mem64& src)\t\t{cmovb(dst, src);}\n\tvoid cmove(const Reg64& dst, const Reg64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F44, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmove(const Reg64& dst, const Mem64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F44, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovg(const Reg64& dst, const Reg64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4F, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovg(const Reg64& dst, const Mem64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4F, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovge(const Reg64& dst, const Reg64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4D, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovge(const Reg64& dst, const Mem64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4D, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovl(const Reg64& dst, const Reg64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4C, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovl(const Reg64& dst, const Mem64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4C, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovle(const Reg64& dst, const Reg64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4E, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovle(const Reg64& dst, const Mem64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4E, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovna(const Reg64& dst, const Reg64& src)\t\t{cmovbe(dst, src);}\n\tvoid cmovna(const Reg64& dst, const Mem64& src)\t\t{cmovbe(dst, src);}\n\tvoid cmovnae(const Reg64& dst, const Reg64& src)\t{cmovb(dst, src);}\n\tvoid cmovnae(const Reg64& dst, const Mem64& src)\t{cmovb(dst, src);}\n\tvoid cmovnb(const Reg64& dst, const Reg64& src)\t\t{cmovae(dst, src);}\n\tvoid cmovnb(const Reg64& dst, const Mem64& src)\t\t{cmovae(dst, src);}\n\tvoid cmovnbe(const Reg64& dst, const Reg64& src)\t{cmova(dst, src);}\n\tvoid cmovnbe(const Reg64& dst, const Mem64& src)\t{cmova(dst, src);}\n\tvoid cmovnc(const Reg64& dst, const Reg64& src)\t\t{cmovae(dst, src);}\n\tvoid cmovnc(const Reg64& dst, const Mem64& src)\t\t{cmovae(dst, src);}\n\tvoid cmovne(const Reg64& dst, const Reg64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F45, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovne(const Reg64& dst, const Mem64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F45, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovng(const Reg64& dst, const Reg64& src)\t\t{cmovle(dst, src);}\n\tvoid cmovng(const Reg64& dst, const Mem64& src)\t\t{cmovle(dst, src);}\n\tvoid cmovnge(const Reg64& dst, const Reg64& src)\t{cmovl(dst, src);}\n\tvoid cmovnge(const Reg64& dst, const Mem64& src)\t{cmovl(dst, src);}\n\tvoid cmovnl(const Reg64& dst, const Reg64& src)\t\t{cmovge(dst, src);}\n\tvoid cmovnl(const Reg64& dst, const Mem64& src)\t\t{cmovge(dst, src);}\n\tvoid cmovnle(const Reg64& dst, const Reg64& src)\t{cmovg(dst, src);}\n\tvoid cmovnle(const Reg64& dst, const Mem64& src)\t{cmovg(dst, src);}\n\tvoid cmovno(const Reg64& dst, const Reg64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F41, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovno(const Reg64& dst, const Mem64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F41, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovnp(const Reg64& dst, const Reg64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4B, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovnp(const Reg64& dst, const Mem64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4B, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovns(const Reg64& dst, const Reg64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F49, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovns(const Reg64& dst, const Mem64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F49, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovnz(const Reg64& dst, const Reg64& src)\t\t{cmovne(dst, src);}\n\tvoid cmovnz(const Reg64& dst, const Mem64& src)\t\t{cmovne(dst, src);}\n\tvoid cmovo(const Reg64& dst, const Reg64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F40, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovo(const Reg64& dst, const Mem64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F40, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovp(const Reg64& dst, const Reg64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4A, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovp(const Reg64& dst, const Mem64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F4A, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovpe(const Reg64& dst, const Reg64& src)\t\t{cmovp(dst, src);}\n\tvoid cmovpe(const Reg64& dst, const Mem64& src)\t\t{cmovp(dst, src);}\n\tvoid cmovpo(const Reg64& dst, const Reg64& src)\t\t{cmovnp(dst, src);}\n\tvoid cmovpo(const Reg64& dst, const Mem64& src)\t\t{cmovnp(dst, src);}\n\tvoid cmovs(const Reg64& dst, const Reg64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F48, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovs(const Reg64& dst, const Mem64& src)\t\t{AppendInstr(I_CMOVCC, 0x0F48, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cmovz(const Reg64& dst, const Reg64& src)\t\t{cmove(dst, src);}\n\tvoid cmovz(const Reg64& dst, const Mem64& src)\t\t{cmove(dst, src);}\n#endif\n\tvoid cmp(const Reg8& lhs, const Imm8& imm)\t\t{AppendInstr(I_CMP, 0x80, E_SPECIAL, Imm8(7), R(lhs), imm);}\n\tvoid cmp(const Mem8& lhs, const Imm8& imm)\t\t{AppendInstr(I_CMP, 0x80, 0, Imm8(7), R(lhs), imm);}\n\tvoid cmp(const Reg16& lhs, const Imm16& imm)\t{AppendInstr(I_CMP, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(7), R(lhs), detail::ImmXor8(imm));}\n\tvoid cmp(const Mem16& lhs, const Imm16& imm)\t{AppendInstr(I_CMP, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX, Imm8(7), R(lhs), detail::ImmXor8(imm));}\n\tvoid cmp(const Reg32& lhs, const Imm32& imm)\t{AppendInstr(I_CMP, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_SPECIAL, Imm8(7), R(lhs), detail::ImmXor8(imm));}\n\tvoid cmp(const Mem32& lhs, const Imm32& imm)\t{AppendInstr(I_CMP, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, 0, Imm8(7), R(lhs), detail::ImmXor8(imm));}\n\tvoid cmp(const Reg8& lhs, const Reg8& rhs)\t\t{AppendInstr(I_CMP, 0x3A, 0, R(lhs), R(rhs));}\n\tvoid cmp(const Mem8& lhs, const Reg8& rhs)\t\t{AppendInstr(I_CMP, 0x38, 0, R(rhs), R(lhs));}\n\tvoid cmp(const Reg8& lhs, const Mem8& rhs)\t\t{AppendInstr(I_CMP, 0x3A, 0, R(lhs), R(rhs));}\n\tvoid cmp(const Reg16& lhs, const Reg16& rhs)\t{AppendInstr(I_CMP, 0x3B, E_OPERAND_SIZE_PREFIX, R(lhs), R(rhs));}\n\tvoid cmp(const Mem16& lhs, const Reg16& rhs)\t{AppendInstr(I_CMP, 0x39, E_OPERAND_SIZE_PREFIX, R(rhs), R(lhs));}\n\tvoid cmp(const Reg16& lhs, const Mem16& rhs)\t{AppendInstr(I_CMP, 0x3B, E_OPERAND_SIZE_PREFIX, R(lhs), R(rhs));}\n\tvoid cmp(const Reg32& lhs, const Reg32& rhs)\t{AppendInstr(I_CMP, 0x3B, 0, R(lhs), R(rhs));}\n\tvoid cmp(const Mem32& lhs, const Reg32& rhs)\t{AppendInstr(I_CMP, 0x39, 0, R(rhs), R(lhs));}\n\tvoid cmp(const Reg32& lhs, const Mem32& rhs)\t{AppendInstr(I_CMP, 0x3B, 0, R(lhs), R(rhs));}\n#ifdef JITASM64\n\tvoid cmp(const Reg64& lhs, const Imm32& imm)\t{AppendInstr(I_CMP, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX | E_SPECIAL, Imm8(7), R(lhs), detail::ImmXor8(imm));}\n\tvoid cmp(const Mem64& lhs, const Imm32& imm)\t{AppendInstr(I_CMP, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX, Imm8(7), R(lhs), detail::ImmXor8(imm));}\n\tvoid cmp(const Reg64& lhs, const Reg64& rhs)\t{AppendInstr(I_CMP, 0x3B, E_REXW_PREFIX, R(lhs), R(rhs));}\n\tvoid cmp(const Mem64& lhs, const Reg64& rhs)\t{AppendInstr(I_CMP, 0x39, E_REXW_PREFIX, R(rhs), R(lhs));}\n\tvoid cmp(const Reg64& lhs, const Mem64& rhs)\t{AppendInstr(I_CMP, 0x3B, E_REXW_PREFIX, R(lhs), R(rhs));}\n#endif\n\tvoid cmpsb()\t\t{AppendInstr(I_CMPS_B, 0xA6, 0, Dummy(RW(edi)), Dummy(RW(esi)));}\n\tvoid cmpsw()\t\t{AppendInstr(I_CMPS_W, 0xA7, E_OPERAND_SIZE_PREFIX, Dummy(RW(edi)), Dummy(RW(esi)));}\n\tvoid cmpsd()\t\t{AppendInstr(I_CMPS_D, 0xA7, 0, Dummy(RW(edi)), Dummy(RW(esi)));}\n#ifdef JITASM64\n\tvoid cmpsq()\t\t{AppendInstr(I_CMPS_Q, 0xA7, E_REXW_PREFIX, Dummy(RW(rdi)), Dummy(RW(rsi)));}\n#endif\n\tvoid cmpxchg(const Reg8& dst, const Reg8& src, const Reg8& cmpx)\t{AppendInstr(I_CMPXCHG, 0x0FB0, 0, R(src), RW(dst), Dummy(RW(cmpx),al));}\n\tvoid cmpxchg(const Mem8& dst, const Reg8& src, const Reg8& cmpx)\t{AppendInstr(I_CMPXCHG, 0x0FB0, 0, R(src), RW(dst), Dummy(RW(cmpx),al));}\n\tvoid cmpxchg(const Reg16& dst, const Reg16& src, const Reg16& cmpx)\t{AppendInstr(I_CMPXCHG, 0x0FB1, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), Dummy(RW(cmpx),ax));}\n\tvoid cmpxchg(const Mem16& dst, const Reg16& src, const Reg16& cmpx)\t{AppendInstr(I_CMPXCHG, 0x0FB1, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), Dummy(RW(cmpx),ax));}\n\tvoid cmpxchg(const Reg32& dst, const Reg32& src, const Reg32& cmpx)\t{AppendInstr(I_CMPXCHG, 0x0FB1, 0, R(src), RW(dst), Dummy(RW(cmpx),eax));}\n\tvoid cmpxchg(const Mem32& dst, const Reg32& src, const Reg32& cmpx)\t{AppendInstr(I_CMPXCHG, 0x0FB1, 0, R(src), RW(dst), Dummy(RW(cmpx),eax));}\n#ifdef JITASM64\n\tvoid cmpxchg(const Reg64& dst, const Reg64& src, const Reg64& cmpx)\t{AppendInstr(I_CMPXCHG, 0x0FB1, E_REXW_PREFIX, R(src), RW(dst), Dummy(RW(cmpx),rax));}\n\tvoid cmpxchg(const Mem64& dst, const Reg64& src, const Reg64& cmpx)\t{AppendInstr(I_CMPXCHG, 0x0FB1, E_REXW_PREFIX, R(src), RW(dst), Dummy(RW(cmpx),rax));}\n#endif\n\tvoid cmpxchg8b(const Mem64& dst)\t{AppendInstr(I_CMPXCHG8B, 0x0FC7, 0, Imm8(1), RW(dst), Dummy(RW(edx)), Dummy(RW(eax)), Dummy(R(ecx)), Dummy(R(ebx)));}\n#ifdef JITASM64\n\tvoid cmpxchg16b(const Mem128& dst)\t{AppendInstr(I_CMPXCHG16B, 0x0FC7, E_REXW_PREFIX, Imm8(1), RW(dst), Dummy(RW(rdx)), Dummy(RW(rax)), Dummy(R(rcx)), Dummy(R(rbx)));}\n#endif\n\tvoid cpuid()\t{AppendInstr(I_CPUID, 0x0FA2, 0, Dummy(RW(eax)), Dummy(RW(ecx)), Dummy(W(ebx)), Dummy(W(edx)));}\n\tvoid cwd()\t\t{AppendInstr(I_CWD, 0x99, E_OPERAND_SIZE_PREFIX, Dummy(W(dx)), Dummy(R(ax)));}\n\tvoid cdq()\t\t{AppendInstr(I_CDQ, 0x99, 0, Dummy(W(edx)), Dummy(R(eax)));}\n#ifdef JITASM64\n\tvoid cqo()\t\t{AppendInstr(I_CQO, 0x99, E_REXW_PREFIX, Dummy(W(rdx)), Dummy(R(rax)));}\n#endif\n\tvoid dec(const Reg8& dst)\t{AppendInstr(I_DEC, 0xFE, 0, Imm8(1), RW(dst));}\n\tvoid dec(const Mem8& dst)\t{AppendInstr(I_DEC, 0xFE, 0, Imm8(1), RW(dst));}\n\tvoid dec(const Mem16& dst)\t{AppendInstr(I_DEC, 0xFF, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst));}\n\tvoid dec(const Mem32& dst)\t{AppendInstr(I_DEC, 0xFF, 0, Imm8(1), RW(dst));}\n#ifndef JITASM64\n\tvoid dec(const Reg16& dst)\t{AppendInstr(I_DEC, 0x48, E_OPERAND_SIZE_PREFIX, RW(dst));}\n\tvoid dec(const Reg32& dst)\t{AppendInstr(I_DEC, 0x48, 0, RW(dst));}\n#else\n\tvoid dec(const Reg16& dst)\t{AppendInstr(I_DEC, 0xFF, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst));}\n\tvoid dec(const Reg32& dst)\t{AppendInstr(I_DEC, 0xFF, 0, Imm8(1), RW(dst));}\n\tvoid dec(const Reg64& dst)\t{AppendInstr(I_DEC, 0xFF, E_REXW_PREFIX, Imm8(1), RW(dst));}\n\tvoid dec(const Mem64& dst)\t{AppendInstr(I_DEC, 0xFF, E_REXW_PREFIX, Imm8(1), RW(dst));}\n#endif\n\tvoid div(const Reg8& src)\t{AppendInstr(I_DIV, 0xF6, 0, Imm8(6), R(src), Dummy(RW(ax)));}\n\tvoid div(const Mem8& src)\t{AppendInstr(I_DIV, 0xF6, 0, Imm8(6), R(src), Dummy(RW(ax)));}\n\tvoid div(const Reg16& src)\t{AppendInstr(I_DIV, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(6), R(src), Dummy(RW(ax)), Dummy(RW(dx)));}\n\tvoid div(const Mem16& src)\t{AppendInstr(I_DIV, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(6), R(src), Dummy(RW(ax)), Dummy(RW(dx)));}\n\tvoid div(const Reg32& src)\t{AppendInstr(I_DIV, 0xF7, 0, Imm8(6), R(src), Dummy(RW(eax)), Dummy(RW(edx)));}\n\tvoid div(const Mem32& src)\t{AppendInstr(I_DIV, 0xF7, 0, Imm8(6), R(src), Dummy(RW(eax)), Dummy(RW(edx)));}\n#ifdef JITASM64\n\tvoid div(const Reg64& src)\t{AppendInstr(I_DIV, 0xF7, E_REXW_PREFIX, Imm8(6), R(src), Dummy(RW(rax)), Dummy(RW(rdx)));}\n\tvoid div(const Mem64& src)\t{AppendInstr(I_DIV, 0xF7, E_REXW_PREFIX, Imm8(6), R(src), Dummy(RW(rax)), Dummy(RW(rdx)));}\n#endif\n\tvoid enter(const Imm16& imm16, const Imm8& imm8) {AppendInstr(I_ENTER, 0xC8, 0, imm16, imm8, Dummy(RW(esp)), Dummy(RW(ebp)));}\n\tvoid hlt()\t{AppendInstr(I_HLT, 0xF4, 0);}\n\tvoid idiv(const Reg8& src)\t{AppendInstr(I_IDIV, 0xF6, 0, Imm8(7), R(src), Dummy(RW(ax)));}\n\tvoid idiv(const Mem8& src)\t{AppendInstr(I_IDIV, 0xF6, 0, Imm8(7), R(src), Dummy(RW(ax)));}\n\tvoid idiv(const Reg16& src)\t{AppendInstr(I_IDIV, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(7), R(src), Dummy(RW(ax)), Dummy(RW(dx)));}\n\tvoid idiv(const Mem16& src)\t{AppendInstr(I_IDIV, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(7), R(src), Dummy(RW(ax)), Dummy(RW(dx)));}\n\tvoid idiv(const Reg32& src)\t{AppendInstr(I_IDIV, 0xF7, 0, Imm8(7), R(src), Dummy(RW(eax)), Dummy(RW(edx)));}\n\tvoid idiv(const Mem32& src)\t{AppendInstr(I_IDIV, 0xF7, 0, Imm8(7), R(src), Dummy(RW(eax)), Dummy(RW(edx)));}\n#ifdef JITASM64\n\tvoid idiv(const Reg64& src)\t{AppendInstr(I_IDIV, 0xF7, E_REXW_PREFIX, Imm8(7), R(src), Dummy(RW(rax)), Dummy(RW(rdx)));}\n\tvoid idiv(const Mem64& src)\t{AppendInstr(I_IDIV, 0xF7, E_REXW_PREFIX, Imm8(7), R(src), Dummy(RW(rax)), Dummy(RW(rdx)));}\n#endif\n\tvoid imul(const Reg8& src)\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_IMUL, 0xF6, 0, Imm8(5), R(src), Dummy(RW(ax)));}\n\tvoid imul(const Mem8& src)\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_IMUL, 0xF6, 0, Imm8(5), R(src), Dummy(RW(ax)));}\n\tvoid imul(const Reg16& src)\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_IMUL, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(5), R(src), Dummy(RW(ax)), Dummy(W(dx)));}\n\tvoid imul(const Mem16& src)\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_IMUL, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(5), R(src), Dummy(RW(ax)), Dummy(W(dx)));}\n\tvoid imul(const Reg32& src)\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_IMUL, 0xF7, 0, Imm8(5), R(src), Dummy(RW(eax)), Dummy(W(edx)));}\n\tvoid imul(const Mem32& src)\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_IMUL, 0xF7, 0, Imm8(5), R(src), Dummy(RW(eax)), Dummy(W(edx)));}\n\tvoid imul(const Reg16& dst, const Reg16& src)\t\t\t\t\t{AppendInstr(I_IMUL, 0x0FAF, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid imul(const Reg16& dst, const Mem16& src)\t\t\t\t\t{AppendInstr(I_IMUL, 0x0FAF, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid imul(const Reg32& dst, const Reg32& src)\t\t\t\t\t{AppendInstr(I_IMUL, 0x0FAF, 0, RW(dst), R(src));}\n\tvoid imul(const Reg32& dst, const Mem32& src)\t\t\t\t\t{AppendInstr(I_IMUL, 0x0FAF, 0, RW(dst), R(src));}\n\tvoid imul(const Reg16& dst, const Reg16& src, const Imm16& imm)\t{AppendInstr(I_IMUL, detail::IsInt8(imm.GetImm()) ? 0x6B : 0x69, E_OPERAND_SIZE_PREFIX, W(dst), R(src), detail::ImmXor8(imm));}\n\tvoid imul(const Reg16& dst, const Mem16& src, const Imm16& imm)\t{AppendInstr(I_IMUL, detail::IsInt8(imm.GetImm()) ? 0x6B : 0x69, E_OPERAND_SIZE_PREFIX, W(dst), R(src), detail::ImmXor8(imm));}\n\tvoid imul(const Reg32& dst, const Reg32& src, const Imm32& imm)\t{AppendInstr(I_IMUL, detail::IsInt8(imm.GetImm()) ? 0x6B : 0x69, 0, W(dst), R(src), detail::ImmXor8(imm));}\n\tvoid imul(const Reg32& dst, const Mem32& src, const Imm32& imm)\t{AppendInstr(I_IMUL, detail::IsInt8(imm.GetImm()) ? 0x6B : 0x69, 0, W(dst), R(src), detail::ImmXor8(imm));}\n\tvoid imul(const Reg16& dst, const Imm16& imm)\t\t\t\t\t{imul(dst, dst, imm);}\n\tvoid imul(const Reg32& dst, const Imm32& imm)\t\t\t\t\t{imul(dst, dst, imm);}\n#ifdef JITASM64\n\tvoid imul(const Reg64& src)\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_IMUL, 0xF7, E_REXW_PREFIX, Imm8(5), R(src), Dummy(RW(rax)), Dummy(W(rdx)));}\n\tvoid imul(const Mem64& src)\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_IMUL, 0xF7, E_REXW_PREFIX, Imm8(5), R(src), Dummy(RW(rax)), Dummy(W(rdx)));}\n\tvoid imul(const Reg64& dst, const Reg64& src)\t\t\t\t\t{AppendInstr(I_IMUL, 0x0FAF, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid imul(const Reg64& dst, const Mem64& src)\t\t\t\t\t{AppendInstr(I_IMUL, 0x0FAF, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid imul(const Reg64& dst, const Reg64& src, const Imm32& imm)\t{AppendInstr(I_IMUL, detail::IsInt8(imm.GetImm()) ? 0x6B : 0x69, E_REXW_PREFIX, W(dst), R(src), detail::ImmXor8(imm));}\n\tvoid imul(const Reg64& dst, const Mem64& src, const Imm32& imm)\t{AppendInstr(I_IMUL, detail::IsInt8(imm.GetImm()) ? 0x6B : 0x69, E_REXW_PREFIX, W(dst), R(src), detail::ImmXor8(imm));}\n\tvoid imul(const Reg64& dst, const Imm32& imm)\t\t\t\t\t{imul(dst, dst, imm);}\n#endif\n\tvoid in(const Reg8& dst, const Imm8& src)\t\t{AppendInstr(I_IN, 0xE4, 0, src, Dummy(W(dst),al));}\n\tvoid in(const Reg16& dst, const Imm8& src)\t\t{AppendInstr(I_IN, 0xE5, E_OPERAND_SIZE_PREFIX, src, Dummy(W(dst),ax));}\n\tvoid in(const Reg32& dst, const Imm8& src)\t\t{AppendInstr(I_IN, 0xE5, 0, src, Dummy(W(dst),eax));}\n\tvoid in(const Reg8& dst, const Reg16& src)\t{AppendInstr(I_IN, 0xEC, 0, Dummy(R(src),dx), Dummy(W(dst),al));}\n\tvoid in(const Reg16& dst, const Reg16& src)\t{AppendInstr(I_IN, 0xED, E_OPERAND_SIZE_PREFIX, Dummy(R(src),dx), Dummy(W(dst),ax));}\n\tvoid in(const Reg32& dst, const Reg16& src)\t{AppendInstr(I_IN, 0xED, 0, Dummy(R(src),dx), Dummy(W(dst),eax));}\n\tvoid inc(const Reg8& dst)\t{AppendInstr(I_INC, 0xFE, 0, Imm8(0), RW(dst));}\n\tvoid inc(const Mem8& dst)\t{AppendInstr(I_INC, 0xFE, 0, Imm8(0), RW(dst));}\n\tvoid inc(const Mem16& dst)\t{AppendInstr(I_INC, 0xFF, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst));}\n\tvoid inc(const Mem32& dst)\t{AppendInstr(I_INC, 0xFF, 0, Imm8(0), RW(dst));}\n#ifndef JITASM64\n\tvoid inc(const Reg16& dst)\t{AppendInstr(I_INC, 0x40, E_OPERAND_SIZE_PREFIX, RW(dst));}\n\tvoid inc(const Reg32& dst)\t{AppendInstr(I_INC, 0x40, 0, RW(dst));}\n#else\n\tvoid inc(const Reg16& dst)\t{AppendInstr(I_INC, 0xFF, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst));}\n\tvoid inc(const Reg32& dst)\t{AppendInstr(I_INC, 0xFF, 0, Imm8(0), RW(dst));}\n\tvoid inc(const Reg64& dst)\t{AppendInstr(I_INC, 0xFF, E_REXW_PREFIX, Imm8(0), RW(dst));}\n\tvoid inc(const Mem64& dst)\t{AppendInstr(I_INC, 0xFF, E_REXW_PREFIX, Imm8(0), RW(dst));}\n#endif\n\tvoid insb(const Reg& dst, const Reg16& src)\t\t\t\t\t{AppendInstr(I_INS_B, 0x6C, 0, Dummy(R(src),dx), Dummy(RW(dst),edi));}\n\tvoid insw(const Reg& dst, const Reg16& src)\t\t\t\t\t{AppendInstr(I_INS_W, 0x6D, E_OPERAND_SIZE_PREFIX, Dummy(R(src),dx), Dummy(RW(dst),edi));}\n\tvoid insd(const Reg& dst, const Reg16& src)\t\t\t\t\t{AppendInstr(I_INS_D, 0x6D, 0, Dummy(R(src),dx), Dummy(RW(dst),edi));}\n\tvoid rep_insb(const Reg& dst, const Reg16& src, const Reg& count)\t{AppendInstr(I_INS_B, 0x6C, E_REP_PREFIX, Dummy(R(src),dx), Dummy(RW(dst),edi), Dummy(RW(count),ecx));}\n\tvoid rep_insw(const Reg& dst, const Reg16& src, const Reg& count)\t{AppendInstr(I_INS_W, 0x6D, E_REP_PREFIX | E_OPERAND_SIZE_PREFIX, Dummy(R(src),dx), Dummy(RW(dst),edi), Dummy(RW(count),ecx));}\n\tvoid rep_insd(const Reg& dst, const Reg16& src, const Reg& count)\t{AppendInstr(I_INS_D, 0x6D, E_REP_PREFIX, Dummy(R(src),dx), Dummy(RW(dst),edi), Dummy(RW(count),ecx));}\n\tvoid int3()\t\t\t\t\t{AppendInstr(I_INT3, 0xCC, 0);}\n\tvoid intn(const Imm8& n)\t{AppendInstr(I_INTN, 0xCD, 0, n);}\n#ifndef JITASM64\n\tvoid into()\t\t\t\t\t{AppendInstr(I_INTO, 0xCE, 0);}\n#endif\n\tvoid invd()\t\t\t\t\t{AppendInstr(I_INVD, 0x0F08, 0);}\n\ttemplate<class Ty> void invlpg(const MemT<Ty>& dst)\t{AppendInstr(I_INVLPG, 0x0F01, 0, Imm8(7), R(dst));}\n\tvoid iret()\t\t{AppendInstr(I_IRET, 0xCF, E_OPERAND_SIZE_PREFIX);}\n\tvoid iretd()\t{AppendInstr(I_IRETD, 0xCF, 0);}\n#ifdef JITASM64\n\tvoid iretq()\t{AppendInstr(I_IRETQ, 0xCF, E_REXW_PREFIX);}\n#endif\n\tvoid jmp(const std::string& label_name)\t\t{AppendJmp(GetLabelID(label_name));}\n\tvoid ja(const std::string& label_name)\t\t{AppendJcc(JCC_A, GetLabelID(label_name));}\n\tvoid jae(const std::string& label_name)\t\t{AppendJcc(JCC_AE, GetLabelID(label_name));}\n\tvoid jb(const std::string& label_name)\t\t{AppendJcc(JCC_B, GetLabelID(label_name));}\n\tvoid jbe(const std::string& label_name)\t\t{AppendJcc(JCC_BE, GetLabelID(label_name));}\n\tvoid jc(const std::string& label_name)\t\t{jb(label_name);}\n#ifdef JITASM64\n\tvoid jecxz(const std::string& label_name)\t{AppendJcc(JCC_ECXZ, GetLabelID(label_name));}\t// short jump only\n\tvoid jrcxz (const std::string& label_name)\t{AppendJcc(JCC_RCXZ, GetLabelID(label_name));}\t// short jump only\n#else\n\tvoid jcxz(const std::string& label_name)\t{AppendJcc(JCC_CXZ, GetLabelID(label_name));}\t// short jump only\n\tvoid jecxz(const std::string& label_name)\t{AppendJcc(JCC_ECXZ, GetLabelID(label_name));}\t// short jump only\n#endif\n\tvoid je(const std::string& label_name)\t\t{AppendJcc(JCC_E, GetLabelID(label_name));}\n\tvoid jg(const std::string& label_name)\t\t{AppendJcc(JCC_G, GetLabelID(label_name));}\n\tvoid jge(const std::string& label_name)\t\t{AppendJcc(JCC_GE, GetLabelID(label_name));}\n\tvoid jl(const std::string& label_name)\t\t{AppendJcc(JCC_L, GetLabelID(label_name));}\n\tvoid jle(const std::string& label_name)\t\t{AppendJcc(JCC_LE, GetLabelID(label_name));}\n\tvoid jna(const std::string& label_name)\t\t{jbe(label_name);}\n\tvoid jnae(const std::string& label_name)\t{jb(label_name);}\n\tvoid jnb(const std::string& label_name)\t\t{jae(label_name);}\n\tvoid jnbe(const std::string& label_name)\t{ja(label_name);}\n\tvoid jnc(const std::string& label_name)\t\t{jae(label_name);}\n\tvoid jne(const std::string& label_name)\t\t{AppendJcc(JCC_NE, GetLabelID(label_name));}\n\tvoid jng(const std::string& label_name)\t\t{jle(label_name);}\n\tvoid jnge(const std::string& label_name)\t{jl(label_name);}\n\tvoid jnl(const std::string& label_name)\t\t{jge(label_name);}\n\tvoid jnle(const std::string& label_name)\t{jg(label_name);}\n\tvoid jno(const std::string& label_name)\t\t{AppendJcc(JCC_NO, GetLabelID(label_name));}\n\tvoid jnp(const std::string& label_name)\t\t{AppendJcc(JCC_NP, GetLabelID(label_name));}\n\tvoid jns(const std::string& label_name)\t\t{AppendJcc(JCC_NS, GetLabelID(label_name));}\n\tvoid jnz(const std::string& label_name)\t\t{jne(label_name);}\n\tvoid jo(const std::string& label_name)\t\t{AppendJcc(JCC_O, GetLabelID(label_name));}\n\tvoid jp(const std::string& label_name)\t\t{AppendJcc(JCC_P, GetLabelID(label_name));}\n\tvoid jpe(const std::string& label_name)\t\t{jp(label_name);}\n\tvoid jpo(const std::string& label_name)\t\t{jnp(label_name);}\n\tvoid js(const std::string& label_name)\t\t{AppendJcc(JCC_S, GetLabelID(label_name));}\n\tvoid jz(const std::string& label_name)\t\t{je(label_name);}\n\tvoid lar(const Reg16& dst, const Reg16& src)\t{AppendInstr(I_LAR, 0x0F02, E_OPERAND_SIZE_PREFIX, W(dst), R(src));}\n\tvoid lar(const Reg16& dst, const Mem16& src)\t{AppendInstr(I_LAR, 0x0F02, E_OPERAND_SIZE_PREFIX, W(dst), R(src));}\n\tvoid lar(const Reg32& dst, const Reg32& src)\t{AppendInstr(I_LAR, 0x0F02, 0, W(dst), R(src));}\n\tvoid lar(const Reg32& dst, const Mem16& src)\t{AppendInstr(I_LAR, 0x0F02, 0, W(dst), R(src));}\n#ifdef JITASM64\n\tvoid lar(const Reg64& dst, const Reg64& src)\t{AppendInstr(I_LAR, 0x0F02, E_REXW_PREFIX, W(dst), R(src));}\n\tvoid lar(const Reg64& dst, const Mem16& src)\t{AppendInstr(I_LAR, 0x0F02, E_REXW_PREFIX, W(dst), R(src));}\n#endif\n\ttemplate<class Ty> void lea(const Reg16& dst, const MemT<Ty>& src)\t{AppendInstr(I_LEA, 0x8D, E_OPERAND_SIZE_PREFIX, W(dst), R(src));}\n\ttemplate<class Ty> void lea(const Reg32& dst, const MemT<Ty>& src)\t{AppendInstr(I_LEA, 0x8D, 0, W(dst), R(src));}\n#ifdef JITASM64\n\ttemplate<class Ty> void lea(const Reg64& dst, const MemT<Ty>& src)\t{AppendInstr(I_LEA, 0x8D, E_REXW_PREFIX, W(dst), R(src));}\n#endif\n\tvoid leave()\t\t{AppendInstr(I_LEAVE, 0xC9, 0, Dummy(W(esp)), Dummy(RW(ebp)));}\n\t//lgdt\n\t//lidt\n\tvoid lldt(const Reg16& src)\t{AppendInstr(I_LLDT, 0x0F00, 0, Imm8(2), R(src));}\n\tvoid lldt(const Mem16& src)\t{AppendInstr(I_LLDT, 0x0F00, 0, Imm8(2), R(src));}\n\tvoid lmsw(const Reg16& src)\t{AppendInstr(I_LMSW, 0x0F01, 0, Imm8(6), R(src));}\n\tvoid lmsw(const Mem16& src)\t{AppendInstr(I_LMSW, 0x0F01, 0, Imm8(6), R(src));}\n\tvoid lodsb(const Reg8& dst, const Reg& src)\t\t{AppendInstr(I_LODS_B, 0xAC, 0, Dummy(W(dst),al), Dummy(RW(src),zsi));}\n\tvoid lodsw(const Reg16& dst, const Reg& src)\t{AppendInstr(I_LODS_W, 0xAD, E_OPERAND_SIZE_PREFIX, Dummy(W(dst),ax), Dummy(RW(src),zsi));}\n\tvoid lodsd(const Reg32& dst, const Reg& src)\t{AppendInstr(I_LODS_D, 0xAD, 0, Dummy(W(dst),eax), Dummy(RW(src),zsi));}\n#ifdef JITASM64\n\tvoid lodsq(const Reg64& dst, const Reg& src)\t{AppendInstr(I_LODS_Q, 0xAD, E_REXW_PREFIX, Dummy(W(dst),rax), Dummy(RW(src),rsi));}\n#endif\n\tvoid rep_lodsb(const Reg8& dst, const Reg& src, const Reg& count)\t{AppendInstr(I_LODS_B, 0xAC, E_REP_PREFIX, Dummy(RW(dst),al), Dummy(RW(src),zsi), Dummy(RW(count),zcx));}\t\t\t\t\t\t\t// dst is RW because of ecx == 0\n\tvoid rep_lodsw(const Reg16& dst, const Reg& src, const Reg& count)\t{AppendInstr(I_LODS_W, 0xAD, E_REP_PREFIX | E_OPERAND_SIZE_PREFIX, Dummy(RW(dst),ax), Dummy(RW(src),zsi), Dummy(RW(count),zcx));}\t// dst is RW because of ecx == 0\n\tvoid rep_lodsd(const Reg32& dst, const Reg& src, const Reg& count)\t{AppendInstr(I_LODS_D, 0xAD, E_REP_PREFIX, Dummy(RW(dst),eax), Dummy(RW(src),zsi), Dummy(RW(count),zcx));}\t\t\t\t\t\t\t// dst is RW because of ecx == 0\n#ifdef JITASM64\n\tvoid rep_lodsq(const Reg64& dst, const Reg& src, const Reg& count)\t{AppendInstr(I_LODS_Q, 0xAD, E_REP_PREFIX | E_REXW_PREFIX, Dummy(RW(dst),rax), Dummy(RW(src),rsi), Dummy(RW(count),rcx));}\t\t\t// dst is RW because of ecx == 0\n#endif\n\tvoid loop(const std::string& label_name)\t\t{AppendInstr(I_LOOP, 0xE2, E_SPECIAL, Imm64(GetLabelID(label_name)), Dummy(RW(zcx)));}\t// short jump only\n\tvoid loope(const std::string& label_name)\t\t{AppendInstr(I_LOOP, 0xE1, E_SPECIAL, Imm64(GetLabelID(label_name)), Dummy(RW(zcx)));}\t// short jump only\n\tvoid loopne(const std::string& label_name)\t\t{AppendInstr(I_LOOP, 0xE0, E_SPECIAL, Imm64(GetLabelID(label_name)), Dummy(RW(zcx)));}\t// short jump only\n\tvoid lsl(const Reg16& dst, const Reg16& src)\t{AppendInstr(I_LSL, 0x0F03, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid lsl(const Reg16& dst, const Mem16& src)\t{AppendInstr(I_LSL, 0x0F03, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid lsl(const Reg32& dst, const Reg32& src)\t{AppendInstr(I_LSL, 0x0F03, 0, RW(dst), R(src));}\n\tvoid lsl(const Reg32& dst, const Mem16& src)\t{AppendInstr(I_LSL, 0x0F03, 0, RW(dst), R(src));}\n#ifdef JITASM64\n\tvoid lsl(const Reg64& dst, const Reg32& src)\t{AppendInstr(I_LSL, 0x0F03, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid lsl(const Reg64& dst, const Mem16& src)\t{AppendInstr(I_LSL, 0x0F03, E_REXW_PREFIX, RW(dst), R(src));}\n#endif\n\tvoid ltr(const Reg16& src)\t{AppendInstr(I_LTR, 0x0F00, 0, Imm8(3), R(src));}\n\tvoid ltr(const Mem16& src)\t{AppendInstr(I_LTR, 0x0F00, 0, Imm8(3), R(src));}\n\tvoid mov(const Reg8& dst, const Reg8& src)\t\t{AppendInstr(I_MOV, 0x8A, 0, W(dst), R(src));}\n\tvoid mov(const Mem8& dst, const Reg8& src)\t\t{AppendInstr(I_MOV, 0x88, E_SPECIAL, R(src), W(dst));}\n\tvoid mov(const Reg16& dst, const Reg16& src)\t{AppendInstr(I_MOV, 0x8B, E_OPERAND_SIZE_PREFIX, W(dst), R(src));}\n\tvoid mov(const Mem16& dst, const Reg16& src)\t{AppendInstr(I_MOV, 0x89, E_OPERAND_SIZE_PREFIX | E_SPECIAL, R(src), W(dst));}\n\tvoid mov(const Reg32& dst, const Reg32& src)\t{AppendInstr(I_MOV, 0x8B, 0, W(dst), R(src));}\n\tvoid mov(const Mem32& dst, const Reg32& src)\t{AppendInstr(I_MOV, 0x89, E_SPECIAL, R(src), W(dst));}\n\tvoid mov(const Reg8& dst, const Mem8& src)\t\t{AppendInstr(I_MOV, 0x8A, E_SPECIAL, W(dst), R(src));}\n\tvoid mov(const Reg16& dst, const Mem16& src)\t{AppendInstr(I_MOV, 0x8B, E_OPERAND_SIZE_PREFIX | E_SPECIAL, W(dst), R(src));}\n\tvoid mov(const Reg32& dst, const Mem32& src)\t{AppendInstr(I_MOV, 0x8B, E_SPECIAL, W(dst), R(src));}\n\tvoid mov(const Reg8& dst, const Imm8& imm)\t\t{AppendInstr(I_MOV, 0xB0, 0, W(dst), imm);}\n\tvoid mov(const Reg16& dst, const Imm16& imm)\t{AppendInstr(I_MOV, 0xB8, E_OPERAND_SIZE_PREFIX, W(dst), imm);}\n\tvoid mov(const Reg32& dst, const Imm32& imm)\t{AppendInstr(I_MOV, 0xB8, 0, W(dst), imm);}\n\tvoid mov(const Mem8& dst, const Imm8& imm)\t\t{AppendInstr(I_MOV, 0xC6, 0, Imm8(0), W(dst), imm);}\n\tvoid mov(const Mem16& dst, const Imm16& imm)\t{AppendInstr(I_MOV, 0xC7, E_OPERAND_SIZE_PREFIX, Imm8(0), W(dst), imm);}\n\tvoid mov(const Mem32& dst, const Imm32& imm)\t{AppendInstr(I_MOV, 0xC7, 0, Imm8(0), W(dst), imm);}\n#ifdef JITASM64\n\tvoid mov(const Reg64& dst, const Reg64& src)\t{AppendInstr(I_MOV, 0x8B, E_REXW_PREFIX, W(dst), R(src));}\n\tvoid mov(const Mem64& dst, const Reg64& src)\t{AppendInstr(I_MOV, 0x89, E_REXW_PREFIX, R(src), W(dst));}\n\tvoid mov(const Reg64& dst, const Mem64& src)\t{AppendInstr(I_MOV, 0x8B, E_REXW_PREFIX, W(dst), R(src));}\n\tvoid mov(const Reg64& dst, const Imm64& imm)\t{detail::IsInt32(imm.GetImm()) ? AppendInstr(I_MOV, 0xC7, E_REXW_PREFIX, Imm8(0), W(dst), Imm32((sint32) imm.GetImm())) : AppendInstr(I_MOV, 0xB8, E_REXW_PREFIX, W(dst), imm);}\n\tvoid mov(const Mem64& dst, const Imm32& imm)\t{AppendInstr(I_MOV, 0xC7, E_REXW_PREFIX, Imm8(0), W(dst), imm);}\n\tvoid mov(const Reg64& dst, const MemOffset64& src)\t{AppendInstr(I_MOV, 0xA1, E_REXW_PREFIX, Imm64(src.GetOffset()), Dummy(W(dst), rax));}\n\tvoid mov(const MemOffset64& dst, const Reg64& src)\t{AppendInstr(I_MOV, 0xA3, E_REXW_PREFIX, Imm64(dst.GetOffset()), Dummy(R(src), rax));}\n#endif\n\tvoid movbe(const Reg16& dst, const Mem16& src)\t{AppendInstr(I_MOVBE, 0x0F38F0, E_OPERAND_SIZE_PREFIX, W(dst), R(src));}\n\tvoid movbe(const Reg32& dst, const Mem32& src)\t{AppendInstr(I_MOVBE, 0x0F38F0, 0, W(dst), R(src));}\n\tvoid movbe(const Mem16& dst, const Reg16& src)\t{AppendInstr(I_MOVBE, 0x0F38F1, E_OPERAND_SIZE_PREFIX, R(src), W(dst));}\n\tvoid movbe(const Mem32& dst, const Reg32& src)\t{AppendInstr(I_MOVBE, 0x0F38F1, 0, R(src), W(dst));}\n#ifdef JITASM64\n\tvoid movbe(const Reg64& dst, const Mem64& src)\t{AppendInstr(I_MOVBE, 0x0F38F0, E_REXW_PREFIX, W(dst), R(src));}\n\tvoid movbe(const Mem64& dst, const Reg64& src)\t{AppendInstr(I_MOVBE, 0x0F38F1, E_REXW_PREFIX, R(src), W(dst));}\n#endif\n\tvoid movsb(const Reg& dst, const Reg& src)\t\t{AppendInstr(I_MOVS_B, 0xA4, 0, Dummy(RW(dst), zdi), Dummy(RW(src), zsi));}\n\tvoid movsw(const Reg& dst, const Reg& src)\t\t{AppendInstr(I_MOVS_W, 0xA5, E_OPERAND_SIZE_PREFIX, Dummy(RW(dst), zdi), Dummy(RW(src), zsi));}\n\tvoid movsd(const Reg& dst, const Reg& src)\t\t{AppendInstr(I_MOVS_D, 0xA5, 0, Dummy(RW(dst), zdi), Dummy(RW(src), zsi));}\n#ifdef JITASM64\n\tvoid movsq(const Reg& dst, const Reg& src)\t\t{AppendInstr(I_MOVS_Q, 0xA5, E_REXW_PREFIX, Dummy(RW(dst), rdi), Dummy(RW(src), rsi));}\n#endif\n\tvoid rep_movsb()\t{rep_movsb(zdi, zsi, zcx);}\n\tvoid rep_movsw()\t{rep_movsw(zdi, zsi, zcx);}\n\tvoid rep_movsd()\t{rep_movsd(zdi, zsi, zcx);}\n\tvoid rep_movsb(const Reg& dst, const Reg& src, const Reg& count)\t{AppendInstr(I_MOVS_B, 0xA4, E_REP_PREFIX, Dummy(RW(dst), zdi), Dummy(RW(src), zsi), Dummy(RW(count), ecx));}\n\tvoid rep_movsw(const Reg& dst, const Reg& src, const Reg& count)\t{AppendInstr(I_MOVS_W, 0xA5, E_REP_PREFIX | E_OPERAND_SIZE_PREFIX, Dummy(RW(dst), zdi), Dummy(RW(src), zsi), Dummy(RW(count), ecx));}\n\tvoid rep_movsd(const Reg& dst, const Reg& src, const Reg& count)\t{AppendInstr(I_MOVS_D, 0xA5, E_REP_PREFIX, Dummy(RW(dst), zdi), Dummy(RW(src), zsi), Dummy(RW(count), ecx));}\n#ifdef JITASM64\n\tvoid rep_movsq()\t{rep_movsq(rdi, rsi, rcx);}\n\tvoid rep_movsq(const Reg64& dst, const Reg64& src, const Reg64& count)\t{AppendInstr(I_MOVS_Q, 0xA5, E_REP_PREFIX | E_REXW_PREFIX, Dummy(RW(dst), rdi), Dummy(RW(src), rsi), Dummy(RW(count), rcx));}\n#endif\n\tvoid movsx(const Reg16& dst, const Reg8& src)\t{AppendInstr(I_MOVSX, 0x0FBE, E_OPERAND_SIZE_PREFIX, W(dst), R(src));}\n\tvoid movsx(const Reg16& dst, const Mem8& src)\t{AppendInstr(I_MOVSX, 0x0FBE, E_OPERAND_SIZE_PREFIX, W(dst), R(src));}\n\tvoid movsx(const Reg32& dst, const Reg8& src)\t{AppendInstr(I_MOVSX, 0x0FBE, 0, W(dst), R(src));}\n\tvoid movsx(const Reg32& dst, const Mem8& src)\t{AppendInstr(I_MOVSX, 0x0FBE, 0, W(dst), R(src));}\n\tvoid movsx(const Reg32& dst, const Reg16& src)\t{AppendInstr(I_MOVSX, 0x0FBF, 0, W(dst), R(src));}\n\tvoid movsx(const Reg32& dst, const Mem16& src)\t{AppendInstr(I_MOVSX, 0x0FBF, 0, W(dst), R(src));}\n#ifdef JITASM64\n\tvoid movsx(const Reg64& dst, const Reg8& src)\t{AppendInstr(I_MOVSX, 0x0FBE, E_REXW_PREFIX, W(dst), R(src));}\n\tvoid movsx(const Reg64& dst, const Mem8& src)\t{AppendInstr(I_MOVSX, 0x0FBE, E_REXW_PREFIX, W(dst), R(src));}\n\tvoid movsx(const Reg64& dst, const Reg16& src)\t{AppendInstr(I_MOVSX, 0x0FBF, E_REXW_PREFIX, W(dst), R(src));}\n\tvoid movsx(const Reg64& dst, const Mem16& src)\t{AppendInstr(I_MOVSX, 0x0FBF, E_REXW_PREFIX, W(dst), R(src));}\n\tvoid movsxd(const Reg64& dst, const Reg32& src)\t{AppendInstr(I_MOVSXD, 0x63, E_REXW_PREFIX, W(dst), R(src));}\n\tvoid movsxd(const Reg64& dst, const Mem32& src)\t{AppendInstr(I_MOVSXD, 0x63, E_REXW_PREFIX, W(dst), R(src));}\n#endif\n\tvoid movzx(const Reg16& dst, const Reg8& src)\t{AppendInstr(I_MOVZX, 0x0FB6, E_OPERAND_SIZE_PREFIX, W(dst), R(src));}\n\tvoid movzx(const Reg16& dst, const Mem8& src)\t{AppendInstr(I_MOVZX, 0x0FB6, E_OPERAND_SIZE_PREFIX, W(dst), R(src));}\n\tvoid movzx(const Reg32& dst, const Reg8& src)\t{AppendInstr(I_MOVZX, 0x0FB6, 0, W(dst), R(src));}\n\tvoid movzx(const Reg32& dst, const Mem8& src)\t{AppendInstr(I_MOVZX, 0x0FB6, 0, W(dst), R(src));}\n\tvoid movzx(const Reg32& dst, const Reg16& src)\t{AppendInstr(I_MOVZX, 0x0FB7, 0, W(dst), R(src));}\n\tvoid movzx(const Reg32& dst, const Mem16& src)\t{AppendInstr(I_MOVZX, 0x0FB7, 0, W(dst), R(src));}\n#ifdef JITASM64\n\tvoid movzx(const Reg64& dst, const Reg8& src)\t{AppendInstr(I_MOVZX, 0x0FB6, E_REXW_PREFIX, W(dst), R(src));}\n\tvoid movzx(const Reg64& dst, const Mem8& src)\t{AppendInstr(I_MOVZX, 0x0FB6, E_REXW_PREFIX, W(dst), R(src));}\n\tvoid movzx(const Reg64& dst, const Reg16& src)\t{AppendInstr(I_MOVZX, 0x0FB7, E_REXW_PREFIX, W(dst), R(src));}\n\tvoid movzx(const Reg64& dst, const Mem16& src)\t{AppendInstr(I_MOVZX, 0x0FB7, E_REXW_PREFIX, W(dst), R(src));}\n#endif\n\tvoid mul(const Reg8& src)\t{AppendInstr(I_MUL, 0xF6, 0, Imm8(4), R(src), Dummy(RW(ax)));}\n\tvoid mul(const Mem8& src)\t{AppendInstr(I_MUL, 0xF6, 0, Imm8(4), R(src), Dummy(RW(ax)));}\n\tvoid mul(const Reg16& src)\t{AppendInstr(I_MUL, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(4), R(src), Dummy(RW(ax)), Dummy(W(dx)));}\n\tvoid mul(const Mem16& src)\t{AppendInstr(I_MUL, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(4), R(src), Dummy(RW(ax)), Dummy(W(dx)));}\n\tvoid mul(const Reg32& src)\t{AppendInstr(I_MUL, 0xF7, 0, Imm8(4), R(src), Dummy(RW(eax)), Dummy(W(edx)));}\n\tvoid mul(const Mem32& src)\t{AppendInstr(I_MUL, 0xF7, 0, Imm8(4), R(src), Dummy(RW(eax)), Dummy(W(edx)));}\n#ifdef JITASM64\n\tvoid mul(const Reg64& src)\t{AppendInstr(I_MUL, 0xF7, E_REXW_PREFIX, Imm8(4), R(src), Dummy(RW(rax)), Dummy(W(rdx)));}\n\tvoid mul(const Mem64& src)\t{AppendInstr(I_MUL, 0xF7, E_REXW_PREFIX, Imm8(4), R(src), Dummy(RW(rax)), Dummy(W(rdx)));}\n#endif\n\tvoid neg(const Reg8& dst)\t{AppendInstr(I_NEG, 0xF6, 0, Imm8(3), RW(dst));}\n\tvoid neg(const Mem8& dst)\t{AppendInstr(I_NEG, 0xF6, 0, Imm8(3), RW(dst));}\n\tvoid neg(const Reg16& dst)\t{AppendInstr(I_NEG, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst));}\n\tvoid neg(const Mem16& dst)\t{AppendInstr(I_NEG, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst));}\n\tvoid neg(const Reg32& dst)\t{AppendInstr(I_NEG, 0xF7, 0, Imm8(3), RW(dst));}\n\tvoid neg(const Mem32& dst)\t{AppendInstr(I_NEG, 0xF7, 0, Imm8(3), RW(dst));}\n#ifdef JITASM64\n\tvoid neg(const Reg64& dst)\t{AppendInstr(I_NEG, 0xF7, E_REXW_PREFIX, Imm8(3), RW(dst));}\n\tvoid neg(const Mem64& dst)\t{AppendInstr(I_NEG, 0xF7, E_REXW_PREFIX, Imm8(3), RW(dst));}\n#endif\n\tvoid nop()\t{AppendInstr(I_NOP, 0x90, 0);}\n\tvoid not_(const Reg8& dst)\t{AppendInstr(I_NOT, 0xF6, 0, Imm8(2), RW(dst));}\n\tvoid not_(const Mem8& dst)\t{AppendInstr(I_NOT, 0xF6, 0, Imm8(2), RW(dst));}\n\tvoid not_(const Reg16& dst)\t{AppendInstr(I_NOT, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst));}\n\tvoid not_(const Mem16& dst)\t{AppendInstr(I_NOT, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst));}\n\tvoid not_(const Reg32& dst)\t{AppendInstr(I_NOT, 0xF7, 0, Imm8(2), RW(dst));}\n\tvoid not_(const Mem32& dst)\t{AppendInstr(I_NOT, 0xF7, 0, Imm8(2), RW(dst));}\n#ifdef JITASM64\n\tvoid not_(const Reg64& dst)\t{AppendInstr(I_NOT, 0xF7, E_REXW_PREFIX, Imm8(2), RW(dst));}\n\tvoid not_(const Mem64& dst)\t{AppendInstr(I_NOT, 0xF7, E_REXW_PREFIX, Imm8(2), RW(dst));}\n#endif\n\tvoid or_(const Reg8& dst, const Imm8& imm)\t{AppendInstr(I_OR, 0x80, E_SPECIAL, Imm8(1), RW(dst), imm);}\n\tvoid or_(const Mem8& dst, const Imm8& imm)\t{AppendInstr(I_OR, 0x80, 0, Imm8(1), RW(dst), imm);}\n\tvoid or_(const Reg16& dst, const Imm16& imm)\t{AppendInstr(I_OR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(1), RW(dst), detail::ImmXor8(imm));}\n\tvoid or_(const Mem16& dst, const Imm16& imm)\t{AppendInstr(I_OR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst), detail::ImmXor8(imm));}\n\tvoid or_(const Reg32& dst, const Imm32& imm)\t{AppendInstr(I_OR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_SPECIAL, Imm8(1), RW(dst), detail::ImmXor8(imm));}\n\tvoid or_(const Mem32& dst, const Imm32& imm)\t{AppendInstr(I_OR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, 0, Imm8(1), RW(dst), detail::ImmXor8(imm));}\n\tvoid or_(const Reg8& dst, const Reg8& src)\t{AppendInstr(I_OR, 0x0A, 0, RW(dst), R(src));}\n\tvoid or_(const Mem8& dst, const Reg8& src)\t{AppendInstr(I_OR, 0x08, 0, R(src), RW(dst));}\n\tvoid or_(const Reg8& dst, const Mem8& src)\t{AppendInstr(I_OR, 0x0A, 0, RW(dst), R(src));}\n\tvoid or_(const Reg16& dst, const Reg16& src)\t{AppendInstr(I_OR, 0x0B, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid or_(const Mem16& dst, const Reg16& src)\t{AppendInstr(I_OR, 0x09, E_OPERAND_SIZE_PREFIX, R(src), RW(dst));}\n\tvoid or_(const Reg16& dst, const Mem16& src)\t{AppendInstr(I_OR, 0x0B, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid or_(const Reg32& dst, const Reg32& src)\t{AppendInstr(I_OR, 0x0B, 0, RW(dst), R(src));}\n\tvoid or_(const Mem32& dst, const Reg32& src)\t{AppendInstr(I_OR, 0x09, 0, R(src), RW(dst));}\n\tvoid or_(const Reg32& dst, const Mem32& src)\t{AppendInstr(I_OR, 0x0B, 0, RW(dst), R(src));}\n#ifdef JITASM64\n\tvoid or_(const Reg64& dst, const Imm32& imm)\t{AppendInstr(I_OR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX | E_SPECIAL, Imm8(1), RW(dst), detail::ImmXor8(imm));}\n\tvoid or_(const Mem64& dst, const Imm32& imm)\t{AppendInstr(I_OR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX, Imm8(1), RW(dst), detail::ImmXor8(imm));}\n\tvoid or_(const Reg64& dst, const Reg64& src)\t{AppendInstr(I_OR, 0x0B, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid or_(const Mem64& dst, const Reg64& src)\t{AppendInstr(I_OR, 0x09, E_REXW_PREFIX, R(src), RW(dst));}\n\tvoid or_(const Reg64& dst, const Mem64& src)\t{AppendInstr(I_OR, 0x0B, E_REXW_PREFIX, RW(dst), R(src));}\n#endif\n\tvoid out(const Imm8& dst, const Reg8& src)\t\t\t{AppendInstr(I_OUT, 0xE6, 0, dst, Dummy(R(src),al));}\n\tvoid out(const Imm8& dst, const Reg16& src)\t\t\t{AppendInstr(I_OUT, 0xE7, E_OPERAND_SIZE_PREFIX, dst, Dummy(R(src),ax));}\n\tvoid out(const Imm8& dst, const Reg32& src)\t\t\t{AppendInstr(I_OUT, 0xE7, 0, dst, Dummy(R(src),eax));}\n\tvoid out(const Reg16& dst, const Reg8& src)\t\t\t{AppendInstr(I_OUT, 0xEE, 0, Dummy(R(dst),dx), Dummy(R(src),al));}\n\tvoid out(const Reg16& dst, const Reg16& src)\t\t{AppendInstr(I_OUT, 0xEF, E_OPERAND_SIZE_PREFIX, Dummy(R(dst),dx), Dummy(R(src),ax));}\n\tvoid out(const Reg16& dst, const Reg32& src)\t\t{AppendInstr(I_OUT, 0xEF, 0, Dummy(R(dst),dx), Dummy(R(src),eax));}\n\tvoid outsb(const Reg16& dst, const Reg& src)\t\t{AppendInstr(I_OUTS_B, 0x6E, 0, Dummy(RW(src),esi), Dummy(R(dst),dx));}\n\tvoid outsw(const Reg16& dst, const Reg& src)\t\t{AppendInstr(I_OUTS_W, 0x6F, E_OPERAND_SIZE_PREFIX, Dummy(RW(src),esi), Dummy(R(dst),dx));}\n\tvoid outsd(const Reg16& dst, const Reg& src)\t\t{AppendInstr(I_OUTS_D, 0x6F, 0, Dummy(RW(src),esi), Dummy(R(dst),dx));}\n\tvoid rep_outsb(const Reg16& dst, const Reg& src, const Reg& count)\t{AppendInstr(I_OUTS_B, 0x6E, E_REP_PREFIX, Dummy(RW(src),esi), Dummy(R(dst),dx), Dummy(RW(count),ecx));}\n\tvoid rep_outsw(const Reg16& dst, const Reg& src, const Reg& count)\t{AppendInstr(I_OUTS_W, 0x6F, E_REP_PREFIX | E_OPERAND_SIZE_PREFIX, Dummy(RW(src),esi), Dummy(R(dst),dx), Dummy(RW(count),ecx));}\n\tvoid rep_outsd(const Reg16& dst, const Reg& src, const Reg& count)\t{AppendInstr(I_OUTS_D, 0x6F, E_REP_PREFIX, Dummy(RW(src),esi), Dummy(R(dst),dx), Dummy(RW(count),ecx));}\n\tvoid pop(const Reg16& dst)\t{AppendInstr(I_POP, 0x58, E_OPERAND_SIZE_PREFIX, W(dst));}\n\tvoid pop(const Mem16& dst)\t{AppendInstr(I_POP, 0x8F, E_OPERAND_SIZE_PREFIX, Imm8(0), W(dst));}\n#ifndef JITASM64\n\tvoid pop(const Reg32& dst)\t{AppendInstr(I_POP, 0x58, 0, W(dst), Dummy(RW(esp)));}\n\tvoid pop(const Mem32& dst)\t{AppendInstr(I_POP, 0x8F, 0, Imm8(0), W(dst), Dummy(RW(esp)));}\n#else\n\tvoid pop(const Reg64& dst)\t{AppendInstr(I_POP, 0x58, 0, W(dst), Dummy(RW(esp)));}\n\tvoid pop(const Mem64& dst)\t{AppendInstr(I_POP, 0x8F, 0, Imm8(0), W(dst), Dummy(RW(esp)));}\n#endif\n#ifndef JITASM64\n\tvoid popa()\t\t{popad();}\n\tvoid popad()\t{AppendInstr(I_POPAD, 0x61, 0, Dummy(RW(esp)));}\n#endif\n#ifndef JITASM64\n\tvoid popf()\t\t{AppendInstr(I_POPF, 0x9D, E_OPERAND_SIZE_PREFIX, Dummy(RW(esp)));}\n\tvoid popfd()\t{AppendInstr(I_POPFD, 0x9D, 0, Dummy(RW(esp)));}\n#else\n\tvoid popf()\t\t{AppendInstr(I_POPF, 0x9D, E_OPERAND_SIZE_PREFIX, Dummy(RW(esp)));}\n\tvoid popfq()\t{AppendInstr(I_POPFQ, 0x9D, 0, Dummy(RW(esp)));}\n#endif\n\tvoid push(const Reg16& src)\t{AppendInstr(I_PUSH, 0x50, E_OPERAND_SIZE_PREFIX, R(src), Dummy(RW(esp)));}\n\tvoid push(const Mem16& src)\t{AppendInstr(I_PUSH, 0xFF, E_OPERAND_SIZE_PREFIX, Imm8(6), R(src), Dummy(RW(esp)));}\n#ifndef JITASM64\n\tvoid push(const Reg32& src)\t{AppendInstr(I_PUSH, 0x50, 0, R(src), Dummy(RW(esp)));}\n\tvoid push(const Mem32& src)\t{AppendInstr(I_PUSH, 0xFF, 0, Imm8(6), R(src), Dummy(RW(esp)));}\n#else\n\tvoid push(const Reg64& src)\t{AppendInstr(I_PUSH, 0x50, 0, R(src), Dummy(RW(esp)));}\n\tvoid push(const Mem64& src)\t{AppendInstr(I_PUSH, 0xFF, 0, Imm8(6), R(src), Dummy(RW(esp)));}\n#endif\n\tvoid push(const Imm32& imm)\t{AppendInstr(I_PUSH, detail::IsInt8(imm.GetImm()) ? 0x6A : 0x68, 0, detail::ImmXor8(imm), Dummy(RW(esp)));}\n#ifndef JITASM64\n\tvoid pusha()\t{pushad();}\n\tvoid pushad()\t{AppendInstr(I_PUSHAD, 0x60, 0, Dummy(RW(esp)));}\n#endif\n\tvoid pushf()\t{AppendInstr(I_PUSHF, 0x9C, E_OPERAND_SIZE_PREFIX, Dummy(RW(esp)));}\n#ifndef JITASM64\n\tvoid pushfd()\t{AppendInstr(I_PUSHFD, 0x9C, 0, Dummy(RW(esp)));}\n#else\n\tvoid pushfq()\t{AppendInstr(I_PUSHFQ, 0x9C, 0, Dummy(RW(esp)));}\n#endif\n\tvoid rcl(const Reg8& dst, const Reg8& shift)\t{AppendInstr(I_RCL, 0xD2, 0, Imm8(2), RW(dst), Dummy(R(shift),cl));}\n\tvoid rcl(const Mem8& dst, const Reg8& shift)\t{AppendInstr(I_RCL, 0xD2, 0, Imm8(2), RW(dst), Dummy(R(shift),cl));}\n\tvoid rcl(const Reg8& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_RCL, 0xD0, 0, Imm8(2), RW(dst)) : AppendInstr(I_RCL, 0xC0, 0, Imm8(2), RW(dst), shift);}\n\tvoid rcl(const Mem8& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_RCL, 0xD0, 0, Imm8(2), RW(dst)) : AppendInstr(I_RCL, 0xC0, 0, Imm8(2), RW(dst), shift);}\n\tvoid rcr(const Reg8& dst, const Reg8& shift)\t{AppendInstr(I_RCR, 0xD2, 0, Imm8(3), RW(dst), Dummy(R(shift),cl));}\n\tvoid rcr(const Mem8& dst, const Reg8& shift)\t{AppendInstr(I_RCR, 0xD2, 0, Imm8(3), RW(dst), Dummy(R(shift),cl));}\n\tvoid rcr(const Reg8& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_RCR, 0xD0, 0, Imm8(3), RW(dst)) : AppendInstr(I_RCR, 0xC0, 0, Imm8(3), RW(dst), shift);}\n\tvoid rcr(const Mem8& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_RCR, 0xD0, 0, Imm8(3), RW(dst)) : AppendInstr(I_RCR, 0xC0, 0, Imm8(3), RW(dst), shift);}\n\tvoid rol(const Reg8& dst, const Reg8& shift)\t{AppendInstr(I_ROL, 0xD2, 0, Imm8(0), RW(dst), Dummy(R(shift),cl));}\n\tvoid rol(const Mem8& dst, const Reg8& shift)\t{AppendInstr(I_ROL, 0xD2, 0, Imm8(0), RW(dst), Dummy(R(shift),cl));}\n\tvoid rol(const Reg8& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_ROL, 0xD0, 0, Imm8(0), RW(dst)) : AppendInstr(I_ROL, 0xC0, 0, Imm8(0), RW(dst), shift);}\n\tvoid rol(const Mem8& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_ROL, 0xD0, 0, Imm8(0), RW(dst)) : AppendInstr(I_ROL, 0xC0, 0, Imm8(0), RW(dst), shift);}\n\tvoid ror(const Reg8& dst, const Reg8& shift)\t{AppendInstr(I_ROR, 0xD2, 0, Imm8(1), RW(dst), Dummy(R(shift),cl));}\n\tvoid ror(const Mem8& dst, const Reg8& shift)\t{AppendInstr(I_ROR, 0xD2, 0, Imm8(1), RW(dst), Dummy(R(shift),cl));}\n\tvoid ror(const Reg8& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_ROR, 0xD0, 0, Imm8(1), RW(dst)) : AppendInstr(I_ROR, 0xC0, 0, Imm8(1), RW(dst), shift);}\n\tvoid ror(const Mem8& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_ROR, 0xD0, 0, Imm8(1), RW(dst)) : AppendInstr(I_ROR, 0xC0, 0, Imm8(1), RW(dst), shift);}\n\tvoid rcl(const Reg16& dst, const Reg8& shift)\t{AppendInstr(I_RCL, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst), Dummy(R(shift),cl));}\n\tvoid rcl(const Mem16& dst, const Reg8& shift)\t{AppendInstr(I_RCL, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst), Dummy(R(shift),cl));}\n\tvoid rcl(const Reg16& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_RCL, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst)) : AppendInstr(I_RCL, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst), shift);}\n\tvoid rcl(const Mem16& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_RCL, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst)) : AppendInstr(I_RCL, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(2), RW(dst), shift);}\n\tvoid rcr(const Reg16& dst, const Reg8& shift)\t{AppendInstr(I_RCR, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst), Dummy(R(shift),cl));}\n\tvoid rcr(const Mem16& dst, const Reg8& shift)\t{AppendInstr(I_RCR, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst), Dummy(R(shift),cl));}\n\tvoid rcr(const Reg16& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_RCR, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst)) : AppendInstr(I_RCR, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst), shift);}\n\tvoid rcr(const Mem16& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_RCR, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst)) : AppendInstr(I_RCR, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst), shift);}\n\tvoid rol(const Reg16& dst, const Reg8& shift)\t{AppendInstr(I_ROL, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst), Dummy(R(shift),cl));}\n\tvoid rol(const Mem16& dst, const Reg8& shift)\t{AppendInstr(I_ROL, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst), Dummy(R(shift),cl));}\n\tvoid rol(const Reg16& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_ROL, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst)) : AppendInstr(I_ROL, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst), shift);}\n\tvoid rol(const Mem16& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_ROL, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst)) : AppendInstr(I_ROL, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(0), RW(dst), shift);}\n\tvoid ror(const Reg16& dst, const Reg8& shift)\t{AppendInstr(I_ROR, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst), Dummy(R(shift),cl));}\n\tvoid ror(const Mem16& dst, const Reg8& shift)\t{AppendInstr(I_ROR, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst), Dummy(R(shift),cl));}\n\tvoid ror(const Reg16& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_ROR, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst)) : AppendInstr(I_ROR, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst), shift);}\n\tvoid ror(const Mem16& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_ROR, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst)) : AppendInstr(I_ROR, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(1), RW(dst), shift);}\n\tvoid rcl(const Reg32& dst, const Reg8& shift)\t{AppendInstr(I_RCL, 0xD3, 0, Imm8(2), RW(dst), Dummy(R(shift),cl));}\n\tvoid rcl(const Mem32& dst, const Reg8& shift)\t{AppendInstr(I_RCL, 0xD3, 0, Imm8(2), RW(dst), Dummy(R(shift),cl));}\n\tvoid rcl(const Reg32& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_RCL, 0xD1, 0, Imm8(2), RW(dst)) : AppendInstr(I_RCL, 0xC1, 0, Imm8(2), RW(dst), shift);}\n\tvoid rcl(const Mem32& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_RCL, 0xD1, 0, Imm8(2), RW(dst)) : AppendInstr(I_RCL, 0xC1, 0, Imm8(2), RW(dst), shift);}\n\tvoid rcr(const Reg32& dst, const Reg8& shift)\t{AppendInstr(I_RCR, 0xD3, 0, Imm8(3), RW(dst), Dummy(R(shift),cl));}\n\tvoid rcr(const Mem32& dst, const Reg8& shift)\t{AppendInstr(I_RCR, 0xD3, 0, Imm8(3), RW(dst), Dummy(R(shift),cl));}\n\tvoid rcr(const Reg32& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_RCR, 0xD1, 0, Imm8(3), RW(dst)) : AppendInstr(I_RCR, 0xC1, 0, Imm8(3), RW(dst), shift);}\n\tvoid rcr(const Mem32& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_RCR, 0xD1, 0, Imm8(3), RW(dst)) : AppendInstr(I_RCR, 0xC1, 0, Imm8(3), RW(dst), shift);}\n\tvoid rol(const Reg32& dst, const Reg8& shift)\t{AppendInstr(I_ROL, 0xD3, 0, Imm8(0), RW(dst), Dummy(R(shift),cl));}\n\tvoid rol(const Mem32& dst, const Reg8& shift)\t{AppendInstr(I_ROL, 0xD3, 0, Imm8(0), RW(dst), Dummy(R(shift),cl));}\n\tvoid rol(const Reg32& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_ROL, 0xD1, 0, Imm8(0), RW(dst)) : AppendInstr(I_ROL, 0xC1, 0, Imm8(0), RW(dst), shift);}\n\tvoid rol(const Mem32& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_ROL, 0xD1, 0, Imm8(0), RW(dst)) : AppendInstr(I_ROL, 0xC1, 0, Imm8(0), RW(dst), shift);}\n\tvoid ror(const Reg32& dst, const Reg8& shift)\t{AppendInstr(I_ROR, 0xD3, 0, Imm8(1), RW(dst), Dummy(R(shift),cl));}\n\tvoid ror(const Mem32& dst, const Reg8& shift)\t{AppendInstr(I_ROR, 0xD3, 0, Imm8(1), RW(dst), Dummy(R(shift),cl));}\n\tvoid ror(const Reg32& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_ROR, 0xD1, 0, Imm8(1), RW(dst)) : AppendInstr(I_ROR, 0xC1, 0, Imm8(1), RW(dst), shift);}\n\tvoid ror(const Mem32& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_ROR, 0xD1, 0, Imm8(1), RW(dst)) : AppendInstr(I_ROR, 0xC1, 0, Imm8(1), RW(dst), shift);}\n#ifdef JITASM64\n\tvoid rcl(const Reg64& dst, const Reg8& shift)\t{AppendInstr(I_RCL, 0xD3, E_REXW_PREFIX, Imm8(2), RW(dst), Dummy(R(shift),cl));}\n\tvoid rcl(const Mem64& dst, const Reg8& shift)\t{AppendInstr(I_RCL, 0xD3, E_REXW_PREFIX, Imm8(2), RW(dst), Dummy(R(shift),cl));}\n\tvoid rcl(const Reg64& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_RCL, 0xD1, E_REXW_PREFIX, Imm8(2), RW(dst)) : AppendInstr(I_RCL, 0xC1, E_REXW_PREFIX, Imm8(2), RW(dst), shift);}\n\tvoid rcl(const Mem64& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_RCL, 0xD1, E_REXW_PREFIX, Imm8(2), RW(dst)) : AppendInstr(I_RCL, 0xC1, E_REXW_PREFIX, Imm8(2), RW(dst), shift);}\n\tvoid rcr(const Reg64& dst, const Reg8& shift)\t{AppendInstr(I_RCR, 0xD3, E_REXW_PREFIX, Imm8(3), RW(dst), Dummy(R(shift),cl));}\n\tvoid rcr(const Mem64& dst, const Reg8& shift)\t{AppendInstr(I_RCR, 0xD3, E_REXW_PREFIX, Imm8(3), RW(dst), Dummy(R(shift),cl));}\n\tvoid rcr(const Reg64& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_RCR, 0xD1, E_REXW_PREFIX, Imm8(3), RW(dst)) : AppendInstr(I_RCR, 0xC1, E_REXW_PREFIX, Imm8(3), RW(dst), shift);}\n\tvoid rcr(const Mem64& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_RCR, 0xD1, E_REXW_PREFIX, Imm8(3), RW(dst)) : AppendInstr(I_RCR, 0xC1, E_REXW_PREFIX, Imm8(3), RW(dst), shift);}\n\tvoid rol(const Reg64& dst, const Reg8& shift)\t{AppendInstr(I_ROL, 0xD3, E_REXW_PREFIX, Imm8(0), RW(dst), Dummy(R(shift),cl));}\n\tvoid rol(const Mem64& dst, const Reg8& shift)\t{AppendInstr(I_ROL, 0xD3, E_REXW_PREFIX, Imm8(0), RW(dst), Dummy(R(shift),cl));}\n\tvoid rol(const Reg64& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_ROL, 0xD1, E_REXW_PREFIX, Imm8(0), RW(dst)) : AppendInstr(I_ROL, 0xC1, E_REXW_PREFIX, Imm8(0), RW(dst), shift);}\n\tvoid rol(const Mem64& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_ROL, 0xD1, E_REXW_PREFIX, Imm8(0), RW(dst)) : AppendInstr(I_ROL, 0xC1, E_REXW_PREFIX, Imm8(0), RW(dst), shift);}\n\tvoid ror(const Reg64& dst, const Reg8& shift)\t{AppendInstr(I_ROR, 0xD3, E_REXW_PREFIX, Imm8(1), RW(dst), Dummy(R(shift),cl));}\n\tvoid ror(const Mem64& dst, const Reg8& shift)\t{AppendInstr(I_ROR, 0xD3, E_REXW_PREFIX, Imm8(1), RW(dst), Dummy(R(shift),cl));}\n\tvoid ror(const Reg64& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_ROR, 0xD1, E_REXW_PREFIX, Imm8(1), RW(dst)) : AppendInstr(I_ROR, 0xC1, E_REXW_PREFIX, Imm8(1), RW(dst), shift);}\n\tvoid ror(const Mem64& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_ROR, 0xD1, E_REXW_PREFIX, Imm8(1), RW(dst)) : AppendInstr(I_ROR, 0xC1, E_REXW_PREFIX, Imm8(1), RW(dst), shift);}\n#endif\n\tvoid rdmsr()\t\t\t\t{AppendInstr(I_RDMSR, 0x0F32, 0, Dummy(R(ecx)), Dummy(W(edx)), Dummy(W(eax)));}\n\tvoid rdpmc()\t\t\t\t{AppendInstr(I_RDMSR, 0x0F33, 0, Dummy(R(ecx)), Dummy(W(edx)), Dummy(W(eax)));}\n\tvoid rdtsc()\t\t\t\t{AppendInstr(I_RDPMC, 0x0F31, 0, Dummy(W(edx)), Dummy(W(eax)), Dummy(W(ecx)));}\n\tvoid ret()\t\t\t\t\t{AppendInstr(I_RET, 0xC3, 0, Dummy(RW(esp)));}\n\tvoid ret(const Imm16& imm)\t{AppendInstr(I_RET, 0xC2, 0, imm, Dummy(RW(esp)));}\n\tvoid rsm()\t\t\t\t\t{AppendInstr(I_RSM, 0x0FAA, 0);}\n\tvoid sal(const Reg8& dst, const Reg8& shift)\t{shl(dst, shift);}\n\tvoid sal(const Mem8& dst, const Reg8& shift)\t{shl(dst, shift);}\n\tvoid sal(const Reg8& dst, const Imm8& shift)\t{shl(dst, shift);}\n\tvoid sal(const Mem8& dst, const Imm8& shift)\t{shl(dst, shift);}\n\tvoid sar(const Reg8& dst, const Reg8& shift)\t{AppendInstr(I_SAR, 0xD2, 0, Imm8(7), RW(dst), Dummy(R(shift),cl));}\n\tvoid sar(const Mem8& dst, const Reg8& shift)\t{AppendInstr(I_SAR, 0xD2, 0, Imm8(7), RW(dst), Dummy(R(shift),cl));}\n\tvoid sar(const Reg8& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_SAR, 0xD0, 0, Imm8(7), RW(dst)) : AppendInstr(I_SAR, 0xC0, 0, Imm8(7), RW(dst), shift);}\n\tvoid sar(const Mem8& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_SAR, 0xD0, 0, Imm8(7), RW(dst)) : AppendInstr(I_SAR, 0xC0, 0, Imm8(7), RW(dst), shift);}\n\tvoid shl(const Reg8& dst, const Reg8& shift)\t{AppendInstr(I_SHL, 0xD2, 0, Imm8(4), RW(dst), Dummy(R(shift),cl));}\n\tvoid shl(const Mem8& dst, const Reg8& shift)\t{AppendInstr(I_SHL, 0xD2, 0, Imm8(4), RW(dst), Dummy(R(shift),cl));}\n\tvoid shl(const Reg8& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_SHL, 0xD0, 0, Imm8(4), RW(dst)) : AppendInstr(I_SHL, 0xC0, 0, Imm8(4), RW(dst), shift);}\n\tvoid shl(const Mem8& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_SHL, 0xD0, 0, Imm8(4), RW(dst)) : AppendInstr(I_SHL, 0xC0, 0, Imm8(4), RW(dst), shift);}\n\tvoid shr(const Reg8& dst, const Reg8& shift)\t{AppendInstr(I_SHR, 0xD2, 0, Imm8(5), RW(dst), Dummy(R(shift),cl));}\n\tvoid shr(const Mem8& dst, const Reg8& shift)\t{AppendInstr(I_SHR, 0xD2, 0, Imm8(5), RW(dst), Dummy(R(shift),cl));}\n\tvoid shr(const Reg8& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_SHR, 0xD0, 0, Imm8(5), RW(dst)) : AppendInstr(I_SHR, 0xC0, 0, Imm8(5), RW(dst), shift);}\n\tvoid shr(const Mem8& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_SHR, 0xD0, 0, Imm8(5), RW(dst)) : AppendInstr(I_SHR, 0xC0, 0, Imm8(5), RW(dst), shift);}\n\tvoid sal(const Reg16& dst, const Reg8& shift)\t{shl(dst, shift);}\n\tvoid sal(const Mem16& dst, const Reg8& shift)\t{shl(dst, shift);}\n\tvoid sal(const Reg16& dst, const Imm8& shift)\t{shl(dst, shift);}\n\tvoid sal(const Mem16& dst, const Imm8& shift)\t{shl(dst, shift);}\n\tvoid sar(const Reg16& dst, const Reg8& shift)\t{AppendInstr(I_SAR, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(7), RW(dst), Dummy(R(shift),cl));}\n\tvoid sar(const Mem16& dst, const Reg8& shift)\t{AppendInstr(I_SAR, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(7), RW(dst), Dummy(R(shift),cl));}\n\tvoid sar(const Reg16& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_SAR, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(7), RW(dst)) : AppendInstr(I_SAR, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(7), RW(dst), shift);}\n\tvoid sar(const Mem16& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_SAR, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(7), RW(dst)) : AppendInstr(I_SAR, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(7), RW(dst), shift);}\n\tvoid shl(const Reg16& dst, const Reg8& shift)\t{AppendInstr(I_SHL, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(4), RW(dst), Dummy(R(shift),cl));}\n\tvoid shl(const Mem16& dst, const Reg8& shift)\t{AppendInstr(I_SHL, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(4), RW(dst), Dummy(R(shift),cl));}\n\tvoid shl(const Reg16& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_SHL, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(4), RW(dst)) : AppendInstr(I_SHL, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(4), RW(dst), shift);}\n\tvoid shl(const Mem16& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_SHL, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(4), RW(dst)) : AppendInstr(I_SHL, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(4), RW(dst), shift);}\n\tvoid shr(const Reg16& dst, const Reg8& shift)\t{AppendInstr(I_SHR, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(dst), Dummy(R(shift),cl));}\n\tvoid shr(const Mem16& dst, const Reg8& shift)\t{AppendInstr(I_SHR, 0xD3, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(dst), Dummy(R(shift),cl));}\n\tvoid shr(const Reg16& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_SHR, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(dst)) : AppendInstr(I_SHR, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(dst), shift);}\n\tvoid shr(const Mem16& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_SHR, 0xD1, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(dst)) : AppendInstr(I_SHR, 0xC1, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(dst), shift);}\n\tvoid sal(const Reg32& dst, const Reg8& shift)\t{shl(dst, shift);}\n\tvoid sal(const Mem32& dst, const Reg8& shift)\t{shl(dst, shift);}\n\tvoid sal(const Reg32& dst, const Imm8& shift)\t{shl(dst, shift);}\n\tvoid sal(const Mem32& dst, const Imm8& shift)\t{shl(dst, shift);}\n\tvoid sar(const Reg32& dst, const Reg8& shift)\t{AppendInstr(I_SAR, 0xD3, 0, Imm8(7), RW(dst), Dummy(R(shift),cl));}\n\tvoid sar(const Mem32& dst, const Reg8& shift)\t{AppendInstr(I_SAR, 0xD3, 0, Imm8(7), RW(dst), Dummy(R(shift),cl));}\n\tvoid sar(const Reg32& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_SAR, 0xD1, 0, Imm8(7), RW(dst)) : AppendInstr(I_SAR, 0xC1, 0, Imm8(7), RW(dst), shift);}\n\tvoid sar(const Mem32& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_SAR, 0xD1, 0, Imm8(7), RW(dst)) : AppendInstr(I_SAR, 0xC1, 0, Imm8(7), RW(dst), shift);}\n\tvoid shl(const Reg32& dst, const Reg8& shift)\t{AppendInstr(I_SHL, 0xD3, 0, Imm8(4), RW(dst), Dummy(R(shift),cl));}\n\tvoid shl(const Mem32& dst, const Reg8& shift)\t{AppendInstr(I_SHL, 0xD3, 0, Imm8(4), RW(dst), Dummy(R(shift),cl));}\n\tvoid shl(const Reg32& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_SHL, 0xD1, 0, Imm8(4), RW(dst)) : AppendInstr(I_SHL, 0xC1, 0, Imm8(4), RW(dst), shift);}\n\tvoid shl(const Mem32& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_SHL, 0xD1, 0, Imm8(4), RW(dst)) : AppendInstr(I_SHL, 0xC1, 0, Imm8(4), RW(dst), shift);}\n\tvoid shr(const Reg32& dst, const Reg8& shift)\t{AppendInstr(I_SHR, 0xD3, 0, Imm8(5), RW(dst), Dummy(R(shift),cl));}\n\tvoid shr(const Mem32& dst, const Reg8& shift)\t{AppendInstr(I_SHR, 0xD3, 0, Imm8(5), RW(dst), Dummy(R(shift),cl));}\n\tvoid shr(const Reg32& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_SHR, 0xD1, 0, Imm8(5), RW(dst)) : AppendInstr(I_SHR, 0xC1, 0, Imm8(5), RW(dst), shift);}\n\tvoid shr(const Mem32& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_SHR, 0xD1, 0, Imm8(5), RW(dst)) : AppendInstr(I_SHR, 0xC1, 0, Imm8(5), RW(dst), shift);}\n#ifdef JITASM64\n\tvoid sal(const Reg64& dst, const Reg8& shift)\t{shl(dst, shift);}\n\tvoid sal(const Mem64& dst, const Reg8& shift)\t{shl(dst, shift);}\n\tvoid sal(const Reg64& dst, const Imm8& shift)\t{shl(dst, shift);}\n\tvoid sal(const Mem64& dst, const Imm8& shift)\t{shl(dst, shift);}\n\tvoid sar(const Reg64& dst, const Reg8& shift)\t{AppendInstr(I_SAR, 0xD3, E_REXW_PREFIX, Imm8(7), RW(dst), Dummy(R(shift),cl));}\n\tvoid sar(const Mem64& dst, const Reg8& shift)\t{AppendInstr(I_SAR, 0xD3, E_REXW_PREFIX, Imm8(7), RW(dst), Dummy(R(shift),cl));}\n\tvoid sar(const Reg64& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_SAR, 0xD1, E_REXW_PREFIX, Imm8(7), RW(dst)) : AppendInstr(I_SAR, 0xC1, E_REXW_PREFIX, Imm8(7), RW(dst), shift);}\n\tvoid sar(const Mem64& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_SAR, 0xD1, E_REXW_PREFIX, Imm8(7), RW(dst)) : AppendInstr(I_SAR, 0xC1, E_REXW_PREFIX, Imm8(7), RW(dst), shift);}\n\tvoid shl(const Reg64& dst, const Reg8& shift)\t{AppendInstr(I_SHL, 0xD3, E_REXW_PREFIX, Imm8(4), RW(dst), Dummy(R(shift),cl));}\n\tvoid shl(const Mem64& dst, const Reg8& shift)\t{AppendInstr(I_SHL, 0xD3, E_REXW_PREFIX, Imm8(4), RW(dst), Dummy(R(shift),cl));}\n\tvoid shl(const Reg64& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_SHL, 0xD1, E_REXW_PREFIX, Imm8(4), RW(dst)) : AppendInstr(I_SHL, 0xC1, E_REXW_PREFIX, Imm8(4), RW(dst), shift);}\n\tvoid shl(const Mem64& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_SHL, 0xD1, E_REXW_PREFIX, Imm8(4), RW(dst)) : AppendInstr(I_SHL, 0xC1, E_REXW_PREFIX, Imm8(4), RW(dst), shift);}\n\tvoid shr(const Reg64& dst, const Reg8& shift)\t{AppendInstr(I_SHR, 0xD3, E_REXW_PREFIX, Imm8(5), RW(dst), Dummy(R(shift),cl));}\n\tvoid shr(const Mem64& dst, const Reg8& shift)\t{AppendInstr(I_SHR, 0xD3, E_REXW_PREFIX, Imm8(5), RW(dst), Dummy(R(shift),cl));}\n\tvoid shr(const Reg64& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_SHR, 0xD1, E_REXW_PREFIX, Imm8(5), RW(dst)) : AppendInstr(I_SHR, 0xC1, E_REXW_PREFIX, Imm8(5), RW(dst), shift);}\n\tvoid shr(const Mem64& dst, const Imm8& shift)\t{shift.GetImm() == 1 ? AppendInstr(I_SHR, 0xD1, E_REXW_PREFIX, Imm8(5), RW(dst)) : AppendInstr(I_SHR, 0xC1, E_REXW_PREFIX, Imm8(5), RW(dst), shift);}\n#endif\n\tvoid sbb(const Reg8& dst, const Imm8& imm)\t\t{AppendInstr(I_SBB, 0x80, E_SPECIAL, Imm8(3), RW(dst), imm);}\n\tvoid sbb(const Mem8& dst, const Imm8& imm)\t\t{AppendInstr(I_SBB, 0x80, 0, Imm8(3), RW(dst), imm);}\n\tvoid sbb(const Reg16& dst, const Imm16& imm)\t{AppendInstr(I_SBB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(3), RW(dst), detail::ImmXor8(imm));}\n\tvoid sbb(const Mem16& dst, const Imm16& imm)\t{AppendInstr(I_SBB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX, Imm8(3), RW(dst), detail::ImmXor8(imm));}\n\tvoid sbb(const Reg32& dst, const Imm32& imm)\t{AppendInstr(I_SBB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_SPECIAL, Imm8(3), RW(dst), detail::ImmXor8(imm));}\n\tvoid sbb(const Mem32& dst, const Imm32& imm)\t{AppendInstr(I_SBB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, 0, Imm8(3), RW(dst), detail::ImmXor8(imm));}\n\tvoid sbb(const Reg8& dst, const Reg8& src)\t\t{AppendInstr(I_SBB, 0x1A, 0, RW(dst), R(src));}\n\tvoid sbb(const Mem8& dst, const Reg8& src)\t\t{AppendInstr(I_SBB, 0x18, 0, R(src), RW(dst));}\n\tvoid sbb(const Reg8& dst, const Mem8& src)\t\t{AppendInstr(I_SBB, 0x1A, 0, RW(dst), R(src));}\n\tvoid sbb(const Reg16& dst, const Reg16& src)\t{AppendInstr(I_SBB, 0x1B, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid sbb(const Mem16& dst, const Reg16& src)\t{AppendInstr(I_SBB, 0x19, E_OPERAND_SIZE_PREFIX, R(src), RW(dst));}\n\tvoid sbb(const Reg16& dst, const Mem16& src)\t{AppendInstr(I_SBB, 0x1B, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid sbb(const Reg32& dst, const Reg32& src)\t{AppendInstr(I_SBB, 0x1B, 0, RW(dst), R(src));}\n\tvoid sbb(const Mem32& dst, const Reg32& src)\t{AppendInstr(I_SBB, 0x19, 0, R(src), RW(dst));}\n\tvoid sbb(const Reg32& dst, const Mem32& src)\t{AppendInstr(I_SBB, 0x1B, 0, RW(dst), R(src));}\n#ifdef JITASM64\n\tvoid sbb(const Reg64& dst, const Imm32& imm)\t{AppendInstr(I_SBB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX | E_SPECIAL, Imm8(3), RW(dst), detail::ImmXor8(imm));}\n\tvoid sbb(const Mem64& dst, const Imm32& imm)\t{AppendInstr(I_SBB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX, Imm8(3), RW(dst), detail::ImmXor8(imm));}\n\tvoid sbb(const Reg64& dst, const Reg64& src)\t{AppendInstr(I_SBB, 0x1B, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid sbb(const Mem64& dst, const Reg64& src)\t{AppendInstr(I_SBB, 0x19, E_REXW_PREFIX, R(src), RW(dst));}\n\tvoid sbb(const Reg64& dst, const Mem64& src)\t{AppendInstr(I_SBB, 0x1B, E_REXW_PREFIX, RW(dst), R(src));}\n#endif\n\tvoid scasb()\t\t{AppendInstr(I_SCAS_B, 0xAE, 0, Dummy(R(al)), Dummy(RW(edi)));}\n\tvoid scasw()\t\t{AppendInstr(I_SCAS_W, 0xAF, E_OPERAND_SIZE_PREFIX, Dummy(R(ax)), Dummy(RW(edi)));}\n\tvoid scasd()\t\t{AppendInstr(I_SCAS_D, 0xAF, 0, Dummy(R(eax)), Dummy(RW(edi)));}\n#ifdef JITASM64\n\tvoid scasq()\t\t{AppendInstr(I_SCAS_Q, 0xAF, E_REXW_PREFIX, Dummy(R(rax)), Dummy(RW(rdi)));}\n#endif\n\tvoid seta(const Reg8& dst)\t\t{AppendInstr(I_SETCC, 0x0F97, 0, Imm8(0), W(dst));}\n\tvoid seta(const Mem8& dst)\t\t{AppendInstr(I_SETCC, 0x0F97, 0, Imm8(0), W(dst));}\n\tvoid setae(const Reg8& dst)\t\t{AppendInstr(I_SETCC, 0x0F93, 0, Imm8(0), W(dst));}\n\tvoid setae(const Mem8& dst)\t\t{AppendInstr(I_SETCC, 0x0F93, 0, Imm8(0), W(dst));}\n\tvoid setb(const Reg8& dst)\t\t{AppendInstr(I_SETCC, 0x0F92, 0, Imm8(0), W(dst));}\n\tvoid setb(const Mem8& dst)\t\t{AppendInstr(I_SETCC, 0x0F92, 0, Imm8(0), W(dst));}\n\tvoid setbe(const Reg8& dst)\t\t{AppendInstr(I_SETCC, 0x0F96, 0, Imm8(0), W(dst));}\n\tvoid setbe(const Mem8& dst)\t\t{AppendInstr(I_SETCC, 0x0F96, 0, Imm8(0), W(dst));}\n\tvoid setc(const Reg8& dst)\t\t{setb(dst);}\n\tvoid setc(const Mem8& dst)\t\t{setb(dst);}\n\tvoid sete(const Reg8& dst)\t\t{AppendInstr(I_SETCC, 0x0F94, 0, Imm8(0), W(dst));}\n\tvoid sete(const Mem8& dst)\t\t{AppendInstr(I_SETCC, 0x0F94, 0, Imm8(0), W(dst));}\n\tvoid setg(const Reg8& dst)\t\t{AppendInstr(I_SETCC, 0x0F9F, 0, Imm8(0), W(dst));}\n\tvoid setg(const Mem8& dst)\t\t{AppendInstr(I_SETCC, 0x0F9F, 0, Imm8(0), W(dst));}\n\tvoid setge(const Reg8& dst)\t\t{AppendInstr(I_SETCC, 0x0F9D, 0, Imm8(0), W(dst));}\n\tvoid setge(const Mem8& dst)\t\t{AppendInstr(I_SETCC, 0x0F9D, 0, Imm8(0), W(dst));}\n\tvoid setl(const Reg8& dst)\t\t{AppendInstr(I_SETCC, 0x0F9C, 0, Imm8(0), W(dst));}\n\tvoid setl(const Mem8& dst)\t\t{AppendInstr(I_SETCC, 0x0F9C, 0, Imm8(0), W(dst));}\n\tvoid setle(const Reg8& dst)\t\t{AppendInstr(I_SETCC, 0x0F9E, 0, Imm8(0), W(dst));}\n\tvoid setle(const Mem8& dst)\t\t{AppendInstr(I_SETCC, 0x0F9E, 0, Imm8(0), W(dst));}\n\tvoid setna(const Reg8& dst)\t\t{setbe(dst);}\n\tvoid setna(const Mem8& dst)\t\t{setbe(dst);}\n\tvoid setnae(const Reg8& dst)\t{setb(dst);}\n\tvoid setnae(const Mem8& dst)\t{setb(dst);}\n\tvoid setnb(const Reg8& dst)\t\t{setae(dst);}\n\tvoid setnb(const Mem8& dst)\t\t{setae(dst);}\n\tvoid setnbe(const Reg8& dst)\t{seta(dst);}\n\tvoid setnbe(const Mem8& dst)\t{seta(dst);}\n\tvoid setnc(const Reg8& dst)\t\t{setae(dst);}\n\tvoid setnc(const Mem8& dst)\t\t{setae(dst);}\n\tvoid setne(const Reg8& dst)\t\t{AppendInstr(I_SETCC, 0x0F95, 0, Imm8(0), W(dst));}\n\tvoid setne(const Mem8& dst)\t\t{AppendInstr(I_SETCC, 0x0F95, 0, Imm8(0), W(dst));}\n\tvoid setng(const Reg8& dst)\t\t{setle(dst);}\n\tvoid setng(const Mem8& dst)\t\t{setle(dst);}\n\tvoid setnge(const Reg8& dst)\t{setl(dst);}\n\tvoid setnge(const Mem8& dst)\t{setl(dst);}\n\tvoid setnl(const Reg8& dst)\t\t{setge(dst);}\n\tvoid setnl(const Mem8& dst)\t\t{setge(dst);}\n\tvoid setnle(const Reg8& dst)\t{setg(dst);}\n\tvoid setnle(const Mem8& dst)\t{setg(dst);}\n\tvoid setno(const Reg8& dst)\t\t{AppendInstr(I_SETCC, 0x0F91, 0, Imm8(0), W(dst));}\n\tvoid setno(const Mem8& dst)\t\t{AppendInstr(I_SETCC, 0x0F91, 0, Imm8(0), W(dst));}\n\tvoid setnp(const Reg8& dst)\t\t{AppendInstr(I_SETCC, 0x0F9B, 0, Imm8(0), W(dst));}\n\tvoid setnp(const Mem8& dst)\t\t{AppendInstr(I_SETCC, 0x0F9B, 0, Imm8(0), W(dst));}\n\tvoid setns(const Reg8& dst)\t\t{AppendInstr(I_SETCC, 0x0F99, 0, Imm8(0), W(dst));}\n\tvoid setns(const Mem8& dst)\t\t{AppendInstr(I_SETCC, 0x0F99, 0, Imm8(0), W(dst));}\n\tvoid setnz(const Reg8& dst)\t\t{setne(dst);}\n\tvoid setnz(const Mem8& dst)\t\t{setne(dst);}\n\tvoid seto(const Reg8& dst)\t\t{AppendInstr(I_SETCC, 0x0F90, 0, Imm8(0), W(dst));}\n\tvoid seto(const Mem8& dst)\t\t{AppendInstr(I_SETCC, 0x0F90, 0, Imm8(0), W(dst));}\n\tvoid setp(const Reg8& dst)\t\t{AppendInstr(I_SETCC, 0x0F9A, 0, Imm8(0), W(dst));}\n\tvoid setp(const Mem8& dst)\t\t{AppendInstr(I_SETCC, 0x0F9A, 0, Imm8(0), W(dst));}\n\tvoid setpe(const Reg8& dst)\t\t{setp(dst);}\n\tvoid setpe(const Mem8& dst)\t\t{setp(dst);}\n\tvoid setpo(const Reg8& dst)\t\t{setnp(dst);}\n\tvoid setpo(const Mem8& dst)\t\t{setnp(dst);}\n\tvoid sets(const Reg8& dst)\t\t{AppendInstr(I_SETCC, 0x0F98, 0, Imm8(0), W(dst));}\n\tvoid sets(const Mem8& dst)\t\t{AppendInstr(I_SETCC, 0x0F98, 0, Imm8(0), W(dst));}\n\tvoid setz(const Reg8& dst)\t\t{sete(dst);}\n\tvoid setz(const Mem8& dst)\t\t{sete(dst);}\n\tvoid shld(const Reg16& dst, const Reg16& src, const Imm8& place)\t{AppendInstr(I_SHLD, 0x0FA4, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), place);}\n\tvoid shld(const Mem16& dst, const Reg16& src, const Imm8& place)\t{AppendInstr(I_SHLD, 0x0FA4, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), place);}\n\tvoid shld(const Reg16& dst, const Reg16& src, const Reg8& place)\t{AppendInstr(I_SHLD, 0x0FA5, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), Dummy(R(place),cl));}\n\tvoid shld(const Mem16& dst, const Reg16& src, const Reg8& place)\t{AppendInstr(I_SHLD, 0x0FA5, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), Dummy(R(place),cl));}\n\tvoid shld(const Reg32& dst, const Reg32& src, const Imm8& place)\t{AppendInstr(I_SHLD, 0x0FA4, 0, R(src), RW(dst), place);}\n\tvoid shld(const Mem32& dst, const Reg32& src, const Imm8& place)\t{AppendInstr(I_SHLD, 0x0FA4, 0, R(src), RW(dst), place);}\n\tvoid shld(const Reg32& dst, const Reg32& src, const Reg8& place)\t{AppendInstr(I_SHLD, 0x0FA5, 0, R(src), RW(dst), Dummy(R(place),cl));}\n\tvoid shld(const Mem32& dst, const Reg32& src, const Reg8& place)\t{AppendInstr(I_SHLD, 0x0FA5, 0, R(src), RW(dst), Dummy(R(place),cl));}\n#ifdef JITASM64\n\tvoid shld(const Reg64& dst, const Reg64& src, const Imm8& place)\t{AppendInstr(I_SHLD, 0x0FA4, E_REXW_PREFIX, R(src), RW(dst), place);}\n\tvoid shld(const Mem64& dst, const Reg64& src, const Imm8& place)\t{AppendInstr(I_SHLD, 0x0FA4, E_REXW_PREFIX, R(src), RW(dst), place);}\n\tvoid shld(const Reg64& dst, const Reg64& src, const Reg8& place)\t{AppendInstr(I_SHLD, 0x0FA5, E_REXW_PREFIX, R(src), RW(dst), Dummy(R(place),cl));}\n\tvoid shld(const Mem64& dst, const Reg64& src, const Reg8& place)\t{AppendInstr(I_SHLD, 0x0FA5, E_REXW_PREFIX, R(src), RW(dst), Dummy(R(place),cl));}\n#endif\n\tvoid shrd(const Reg16& dst, const Reg16& src, const Imm8& place)\t{AppendInstr(I_SHRD, 0x0FAC, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), place);}\n\tvoid shrd(const Mem16& dst, const Reg16& src, const Imm8& place)\t{AppendInstr(I_SHRD, 0x0FAC, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), place);}\n\tvoid shrd(const Reg16& dst, const Reg16& src, const Reg8& place)\t{AppendInstr(I_SHRD, 0x0FAD, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), Dummy(R(place),cl));}\n\tvoid shrd(const Mem16& dst, const Reg16& src, const Reg8& place)\t{AppendInstr(I_SHRD, 0x0FAD, E_OPERAND_SIZE_PREFIX, R(src), RW(dst), Dummy(R(place),cl));}\n\tvoid shrd(const Reg32& dst, const Reg32& src, const Imm8& place)\t{AppendInstr(I_SHRD, 0x0FAC, 0, R(src), RW(dst), place);}\n\tvoid shrd(const Mem32& dst, const Reg32& src, const Imm8& place)\t{AppendInstr(I_SHRD, 0x0FAC, 0, R(src), RW(dst), place);}\n\tvoid shrd(const Reg32& dst, const Reg32& src, const Reg8& place)\t{AppendInstr(I_SHRD, 0x0FAD, 0, R(src), RW(dst), Dummy(R(place),cl));}\n\tvoid shrd(const Mem32& dst, const Reg32& src, const Reg8& place)\t{AppendInstr(I_SHRD, 0x0FAD, 0, R(src), RW(dst), Dummy(R(place),cl));}\n#ifdef JITASM64\n\tvoid shrd(const Reg64& dst, const Reg64& src, const Imm8& place)\t{AppendInstr(I_SHRD, 0x0FAC, E_REXW_PREFIX, R(src), RW(dst), place);}\n\tvoid shrd(const Mem64& dst, const Reg64& src, const Imm8& place)\t{AppendInstr(I_SHRD, 0x0FAC, E_REXW_PREFIX, R(src), RW(dst), place);}\n\tvoid shrd(const Reg64& dst, const Reg64& src, const Reg8& place)\t{AppendInstr(I_SHRD, 0x0FAD, E_REXW_PREFIX, R(src), RW(dst), Dummy(R(place),cl));}\n\tvoid shrd(const Mem64& dst, const Reg64& src, const Reg8& place)\t{AppendInstr(I_SHRD, 0x0FAD, E_REXW_PREFIX, R(src), RW(dst), Dummy(R(place),cl));}\n#endif\n\ttemplate<class Ty> void sgdt(const MemT<Ty>& dst)\t{AppendInstr(I_SGDT, 0x0F01, 0, Imm8(0), W(dst));}\n\ttemplate<class Ty> void sidt(const MemT<Ty>& dst)\t{AppendInstr(I_SIDT, 0x0F01, 0, Imm8(1), W(dst));}\n\tvoid sldt(const Reg16& dst)\t{AppendInstr(I_SLDT, 0x0F00, E_OPERAND_SIZE_PREFIX, Imm8(0), W(dst));}\n\tvoid sldt(const Mem16& dst)\t{AppendInstr(I_SLDT, 0x0F00, 0, Imm8(0), W(dst));}\n#ifdef JITASM64\n\tvoid sldt(const Reg64& dst)\t{AppendInstr(I_SLDT, 0x0F00, E_REXW_PREFIX, Imm8(0), W(dst));}\n#endif\n\tvoid smsw(const Reg16& dst)\t{AppendInstr(I_SMSW, 0x0F01, E_OPERAND_SIZE_PREFIX, Imm8(4), W(dst));}\n\tvoid smsw(const Mem16& dst)\t{AppendInstr(I_SMSW, 0x0F01, 0, Imm8(4), W(dst));}\n#ifdef JITASM64\n\tvoid smsw(const Reg64& dst)\t{AppendInstr(I_SMSW, 0x0F01, E_REXW_PREFIX, Imm8(4), W(dst));}\n#endif\n\tvoid stc()\t\t\t{AppendInstr(I_STC, 0xF9, 0);}\n\tvoid std()\t\t\t{AppendInstr(I_STD, 0xFD, 0);}\n\tvoid sti()\t\t\t{AppendInstr(I_STI, 0xFB, 0);}\n\tvoid stosb(const Reg& dst, const Reg8& src)\t\t{AppendInstr(I_STOS_B, 0xAA, 0, Dummy(R(src),al), Dummy(RW(dst),zdi));}\n\tvoid stosw(const Reg& dst, const Reg16& src)\t{AppendInstr(I_STOS_W, 0xAB, E_OPERAND_SIZE_PREFIX, Dummy(R(src),ax), Dummy(RW(dst),zdi));}\n\tvoid stosd(const Reg& dst, const Reg32& src)\t{AppendInstr(I_STOS_D, 0xAB, 0, Dummy(R(src),eax), Dummy(RW(dst),zdi));}\n#ifdef JITASM64\n\tvoid stosq(const Reg& dst, const Reg64& src)\t{AppendInstr(I_STOS_Q, 0xAB, E_REXW_PREFIX, Dummy(R(src),rax), Dummy(RW(dst),zdi));}\n#endif\n\tvoid rep_stosb(const Reg& dst, const Reg8& src, const Reg& count)\t{AppendInstr(I_STOS_B, 0xAA, E_REP_PREFIX, Dummy(R(src),al), Dummy(RW(dst),zdi), Dummy(RW(count),zcx));}\n\tvoid rep_stosw(const Reg& dst, const Reg16& src, const Reg& count)\t{AppendInstr(I_STOS_W, 0xAB, E_REP_PREFIX | E_OPERAND_SIZE_PREFIX, Dummy(R(src),ax), Dummy(RW(dst),zdi), Dummy(RW(count),zcx));}\n\tvoid rep_stosd(const Reg& dst, const Reg32& src, const Reg& count)\t{AppendInstr(I_STOS_D, 0xAB, E_REP_PREFIX, Dummy(R(src),eax), Dummy(RW(dst),zdi), Dummy(RW(count),zcx));}\n#ifdef JITASM64\n\tvoid rep_stosq(const Reg& dst, const Reg64& src, const Reg& count)\t{AppendInstr(I_STOS_Q, 0xAB, E_REP_PREFIX | E_REXW_PREFIX, Dummy(R(src),rax), Dummy(RW(dst),zdi), Dummy(RW(count),zcx));}\n#endif\n\tvoid sub(const Reg8& dst, const Imm8& imm)\t\t{AppendInstr(I_SUB, 0x80, E_SPECIAL, Imm8(5), RW(dst), imm);}\n\tvoid sub(const Mem8& dst, const Imm8& imm)\t\t{AppendInstr(I_SUB, 0x80, 0, Imm8(5), RW(dst), imm);}\n\tvoid sub(const Reg16& dst, const Imm16& imm)\t{AppendInstr(I_SUB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(5), RW(dst), detail::ImmXor8(imm));}\n\tvoid sub(const Mem16& dst, const Imm16& imm)\t{AppendInstr(I_SUB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX, Imm8(5), RW(dst), detail::ImmXor8(imm));}\n\tvoid sub(const Reg32& dst, const Imm32& imm)\t{AppendInstr(I_SUB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_SPECIAL, Imm8(5), RW(dst), detail::ImmXor8(imm));}\n\tvoid sub(const Mem32& dst, const Imm32& imm)\t{AppendInstr(I_SUB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, 0, Imm8(5), RW(dst), detail::ImmXor8(imm));}\n\tvoid sub(const Reg8& dst, const Reg8& src)\t\t{AppendInstr(I_SUB, 0x2A, 0, RW(dst), R(src));}\n\tvoid sub(const Mem8& dst, const Reg8& src)\t\t{AppendInstr(I_SUB, 0x28, 0, R(src), RW(dst));}\n\tvoid sub(const Reg8& dst, const Mem8& src)\t\t{AppendInstr(I_SUB, 0x2A, 0, RW(dst), R(src));}\n\tvoid sub(const Reg16& dst, const Reg16& src)\t{AppendInstr(I_SUB, 0x2B, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid sub(const Mem16& dst, const Reg16& src)\t{AppendInstr(I_SUB, 0x29, E_OPERAND_SIZE_PREFIX, R(src), RW(dst));}\n\tvoid sub(const Reg16& dst, const Mem16& src)\t{AppendInstr(I_SUB, 0x2B, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid sub(const Reg32& dst, const Reg32& src)\t{AppendInstr(I_SUB, 0x2B, 0, RW(dst), R(src));}\n\tvoid sub(const Mem32& dst, const Reg32& src)\t{AppendInstr(I_SUB, 0x29, 0, R(src), RW(dst));}\n\tvoid sub(const Reg32& dst, const Mem32& src)\t{AppendInstr(I_SUB, 0x2B, 0, RW(dst), R(src));}\n#ifdef JITASM64\n\tvoid sub(const Reg64& dst, const Imm32& imm)\t{AppendInstr(I_SUB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX | E_SPECIAL, Imm8(5), RW(dst), detail::ImmXor8(imm));}\n\tvoid sub(const Mem64& dst, const Imm32& imm)\t{AppendInstr(I_SUB, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX, Imm8(5), RW(dst), detail::ImmXor8(imm));}\n\tvoid sub(const Reg64& dst, const Reg64& src)\t{AppendInstr(I_SUB, 0x2B, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid sub(const Mem64& dst, const Reg64& src)\t{AppendInstr(I_SUB, 0x29, E_REXW_PREFIX, R(src), RW(dst));}\n\tvoid sub(const Reg64& dst, const Mem64& src)\t{AppendInstr(I_SUB, 0x2B, E_REXW_PREFIX, RW(dst), R(src));}\n#endif\n#ifndef JITASM64\n\tvoid sysenter()\t{AppendInstr(I_SYSENTER, 0x0F34, 0);}\n\tvoid sysexit()\t{AppendInstr(I_SYSEXIT, 0x0F35, 0);}\n#else\n\tvoid swapgs()\t{AppendInstr(I_SWAPGS, 0x0F01F8, 0);}\t// 0F 01 /7\n\tvoid syscall()\t{AppendInstr(I_SYSCALL, 0x0F05, 0);}\n\tvoid sysret()\t{AppendInstr(I_SYSRET, 0x0F07, 0);}\n#endif\n\tvoid test(const Reg8& src1, const Imm8& src2)\t{AppendInstr(I_TEST, 0xF6, E_SPECIAL, Imm8(0), R(src1), R(src2));}\n\tvoid test(const Mem8& src1, const Imm8& src2)\t{AppendInstr(I_TEST, 0xF6, 0, Imm8(0), R(src1), R(src2));}\n\tvoid test(const Reg16& src1, const Imm16& src2)\t{AppendInstr(I_TEST, 0xF7, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(0), R(src1), R(src2));}\n\tvoid test(const Mem16& src1, const Imm16& src2)\t{AppendInstr(I_TEST, 0xF7, E_OPERAND_SIZE_PREFIX, Imm8(0), R(src1), R(src2));}\n\tvoid test(const Reg32& src1, const Imm32& src2)\t{AppendInstr(I_TEST, 0xF7, E_SPECIAL, Imm8(0), R(src1), R(src2));}\n\tvoid test(const Mem32& src1, const Imm32& src2)\t{AppendInstr(I_TEST, 0xF7, 0, Imm8(0), R(src1), R(src2));}\n\tvoid test(const Reg8& src1, const Reg8& src2)\t{AppendInstr(I_TEST, 0x84, 0, R(src1), R(src2));}\n\tvoid test(const Mem8& src1, const Reg8& src2)\t{AppendInstr(I_TEST, 0x84, 0, R(src2), R(src1));}\n\tvoid test(const Reg16& src1, const Reg16& src2)\t{AppendInstr(I_TEST, 0x85, E_OPERAND_SIZE_PREFIX, R(src1), R(src2));}\n\tvoid test(const Mem16& src1, const Reg16& src2)\t{AppendInstr(I_TEST, 0x85, E_OPERAND_SIZE_PREFIX, R(src2), R(src1));}\n\tvoid test(const Reg32& src1, const Reg32& src2)\t{AppendInstr(I_TEST, 0x85, 0, R(src1), R(src2));}\n\tvoid test(const Mem32& src1, const Reg32& src2)\t{AppendInstr(I_TEST, 0x85, 0, R(src2), R(src1));}\n#ifdef JITASM64\n\tvoid test(const Reg64& src1, const Imm32& src2)\t{AppendInstr(I_TEST, 0xF7, E_REXW_PREFIX | E_SPECIAL, Imm8(0), R(src1), R(src2));}\n\tvoid test(const Mem64& src1, const Imm32& src2)\t{AppendInstr(I_TEST, 0xF7, E_REXW_PREFIX, Imm8(0), R(src1), R(src2));}\n\tvoid test(const Reg64& src1, const Reg64& src2)\t{AppendInstr(I_TEST, 0x85, E_REXW_PREFIX, R(src1), R(src2));}\n\tvoid test(const Mem64& src1, const Reg64& src2)\t{AppendInstr(I_TEST, 0x85, E_REXW_PREFIX, R(src2), R(src1));}\n#endif\n\tvoid ud2()\t\t\t\t\t{AppendInstr(I_UD2, 0x0F0B, 0);}\n\tvoid verr(const Reg16& src)\t{AppendInstr(I_VERR, 0x0F00, 0, Imm8(4), R(src));}\n\tvoid verr(const Mem16& src)\t{AppendInstr(I_VERR, 0x0F00, 0, Imm8(4), R(src));}\n\tvoid verw(const Reg16& src)\t{AppendInstr(I_VERW, 0x0F00, 0, Imm8(5), R(src));}\n\tvoid verw(const Mem16& src)\t{AppendInstr(I_VERW, 0x0F00, 0, Imm8(5), R(src));}\n\tvoid wait()\t\t\t\t\t{AppendInstr(I_WAIT, 0x9B, 0);}\n\tvoid wbinvd()\t\t\t\t{AppendInstr(I_WBINVD, 0x0F09, 0);}\n\tvoid wrmsr()\t\t\t\t{AppendInstr(I_WRMSR, 0x0F30, 0, Dummy(R(ecx)), Dummy(R(edx)), Dummy(R(eax)));}\n\tvoid xadd(const Reg8& dst, const Reg8& src)\t\t{AppendInstr(I_XADD, 0x0FC0, 0, RW(src), RW(dst));}\n\tvoid xadd(const Mem8& dst, const Reg8& src)\t\t{AppendInstr(I_XADD, 0x0FC0, 0, RW(src), RW(dst));}\n\tvoid xadd(const Reg16& dst, const Reg16& src)\t{AppendInstr(I_XADD, 0x0FC1, E_OPERAND_SIZE_PREFIX, RW(src), RW(dst));}\n\tvoid xadd(const Mem16& dst, const Reg16& src)\t{AppendInstr(I_XADD, 0x0FC1, E_OPERAND_SIZE_PREFIX, RW(src), RW(dst));}\n\tvoid xadd(const Reg32& dst, const Reg32& src)\t{AppendInstr(I_XADD, 0x0FC1, 0, RW(src), RW(dst));}\n\tvoid xadd(const Mem32& dst, const Reg32& src)\t{AppendInstr(I_XADD, 0x0FC1, 0, RW(src), RW(dst));}\n#ifdef JITASM64\n\tvoid xadd(const Reg64& dst, const Reg64& src)\t{AppendInstr(I_XADD, 0x0FC1, E_REXW_PREFIX, RW(src), RW(dst));}\n\tvoid xadd(const Mem64& dst, const Reg64& src)\t{AppendInstr(I_XADD, 0x0FC1, E_REXW_PREFIX, RW(src), RW(dst));}\n#endif\n\tvoid xchg(const Reg8& dst, const Reg8& src)\t\t{AppendInstr(I_XCHG, 0x86, 0, RW(dst), RW(src));}\n\tvoid xchg(const Mem8& dst, const Reg8& src)\t\t{AppendInstr(I_XCHG, 0x86, 0, RW(src), RW(dst));}\n\tvoid xchg(const Reg8& dst, const Mem8& src)\t\t{AppendInstr(I_XCHG, 0x86, 0, RW(dst), RW(src));}\n\tvoid xchg(const Reg16& dst, const Reg16& src)\t{AppendInstr(I_XCHG, 0x87, E_OPERAND_SIZE_PREFIX | E_SPECIAL, RW(dst), RW(src));}\n\tvoid xchg(const Mem16& dst, const Reg16& src)\t{AppendInstr(I_XCHG, 0x87, E_OPERAND_SIZE_PREFIX, RW(src), RW(dst));}\n\tvoid xchg(const Reg16& dst, const Mem16& src)\t{AppendInstr(I_XCHG, 0x87, E_OPERAND_SIZE_PREFIX, RW(dst), RW(src));}\n\tvoid xchg(const Reg32& dst, const Reg32& src)\t{AppendInstr(I_XCHG, 0x87, E_SPECIAL, RW(dst), RW(src));}\n\tvoid xchg(const Mem32& dst, const Reg32& src)\t{AppendInstr(I_XCHG, 0x87, 0, RW(src), RW(dst));}\n\tvoid xchg(const Reg32& dst, const Mem32& src)\t{AppendInstr(I_XCHG, 0x87, 0, RW(dst), RW(src));}\n#ifdef JITASM64\n\tvoid xchg(const Reg64& dst, const Reg64& src)\t{AppendInstr(I_XCHG, 0x87, E_REXW_PREFIX | E_SPECIAL, RW(dst), RW(src));}\n\tvoid xchg(const Mem64& dst, const Reg64& src)\t{AppendInstr(I_XCHG, 0x87, E_REXW_PREFIX, RW(src), RW(dst));}\n\tvoid xchg(const Reg64& dst, const Mem64& src)\t{AppendInstr(I_XCHG, 0x87, E_REXW_PREFIX, RW(dst), RW(src));}\n#endif\n\tvoid xgetbv()\t\t\t\t\t\t\t\t\t{AppendInstr(I_XGETBV, 0x0F01D0, 0, Dummy(R(ecx)), Dummy(W(edx)), Dummy(W(eax)));}\n\tvoid xlatb()\t\t\t\t\t\t\t\t\t{AppendInstr(I_XLATB, 0xD7, 0, Dummy(RW(al)), Dummy(R(ebx)));}\n\tvoid xor_(const Reg8& dst, const Imm8& imm)\t\t{AppendInstr(I_XOR, 0x80, E_SPECIAL, Imm8(6), RW(dst), imm);}\n\tvoid xor_(const Mem8& dst, const Imm8& imm)\t\t{AppendInstr(I_XOR, 0x80, 0, Imm8(6), RW(dst), imm);}\n\tvoid xor_(const Reg16& dst, const Imm16& imm)\t{AppendInstr(I_XOR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX | E_SPECIAL, Imm8(6), RW(dst), detail::ImmXor8(imm));}\n\tvoid xor_(const Mem16& dst, const Imm16& imm)\t{AppendInstr(I_XOR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_OPERAND_SIZE_PREFIX, Imm8(6), RW(dst), detail::ImmXor8(imm));}\n\tvoid xor_(const Reg32& dst, const Imm32& imm)\t{AppendInstr(I_XOR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_SPECIAL, Imm8(6), RW(dst), detail::ImmXor8(imm));}\n\tvoid xor_(const Mem32& dst, const Imm32& imm)\t{AppendInstr(I_XOR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, 0, Imm8(6), RW(dst), detail::ImmXor8(imm));}\n\tvoid xor_(const Reg8& dst, const Reg8& src)\t\t{AppendInstr(I_XOR, 0x32, 0, RW(dst), R(src));}\n\tvoid xor_(const Mem8& dst, const Reg8& src)\t\t{AppendInstr(I_XOR, 0x30, 0, R(src), RW(dst));}\n\tvoid xor_(const Reg8& dst, const Mem8& src)\t\t{AppendInstr(I_XOR, 0x32, 0, RW(dst), R(src));}\n\tvoid xor_(const Reg16& dst, const Reg16& src)\t{AppendInstr(I_XOR, 0x33, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid xor_(const Mem16& dst, const Reg16& src)\t{AppendInstr(I_XOR, 0x31, E_OPERAND_SIZE_PREFIX, R(src), RW(dst));}\n\tvoid xor_(const Reg16& dst, const Mem16& src)\t{AppendInstr(I_XOR, 0x33, E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid xor_(const Reg32& dst, const Reg32& src)\t{AppendInstr(I_XOR, 0x33, 0, RW(dst), R(src));}\n\tvoid xor_(const Mem32& dst, const Reg32& src)\t{AppendInstr(I_XOR, 0x31, 0, R(src), RW(dst));}\n\tvoid xor_(const Reg32& dst, const Mem32& src)\t{AppendInstr(I_XOR, 0x33, 0, RW(dst), R(src));}\n#ifdef JITASM64\n\tvoid xor_(const Reg64& dst, const Imm32& imm)\t{AppendInstr(I_XOR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX | E_SPECIAL, Imm8(6), RW(dst), detail::ImmXor8(imm));}\n\tvoid xor_(const Mem64& dst, const Imm32& imm)\t{AppendInstr(I_XOR, detail::IsInt8(imm.GetImm()) ? 0x83 : 0x81, E_REXW_PREFIX, Imm8(6), RW(dst), detail::ImmXor8(imm));}\n\tvoid xor_(const Reg64& dst, const Reg64& src)\t{AppendInstr(I_XOR, 0x33, E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid xor_(const Mem64& dst, const Reg64& src)\t{AppendInstr(I_XOR, 0x31, E_REXW_PREFIX, R(src), RW(dst));}\n\tvoid xor_(const Reg64& dst, const Mem64& src)\t{AppendInstr(I_XOR, 0x33, E_REXW_PREFIX, RW(dst), R(src));}\n#endif\n\n\t// x87 Floating-Point Instructions\n\tvoid f2xm1()\t{AppendInstr(I_F2XM1, 0xD9F0, 0);}\n\tvoid fabs()\t\t{AppendInstr(I_FABS, 0xD9E1, 0);}\n\tvoid fadd(const FpuReg_st0& dst, const FpuReg& src)\t\t{AppendInstr(I_FADD, 0xD8C0, 0, src); avoid_unused_warn(dst);}\n\tvoid fadd(const FpuReg& dst, const FpuReg_st0& src)\t\t{AppendInstr(I_FADD, 0xDCC0, 0, dst); avoid_unused_warn(src);}\n\tvoid fadd(const Mem32& dst)\t\t\t\t\t\t\t\t{AppendInstr(I_FADD, 0xD8, 0, Imm8(0), dst);}\n\tvoid fadd(const Mem64& dst)\t\t\t\t\t\t\t\t{AppendInstr(I_FADD, 0xDC, 0, Imm8(0), dst);}\n\tvoid faddp()\t\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_FADDP, 0xDEC1, 0);}\n\tvoid faddp(const FpuReg& dst, const FpuReg_st0& src)\t{AppendInstr(I_FADDP, 0xDEC0, 0, dst);  avoid_unused_warn(src);}\n\tvoid fiadd(const Mem16& dst)\t\t\t\t\t\t\t{AppendInstr(I_FIADD, 0xDE, 0, Imm8(0), dst);}\n\tvoid fiadd(const Mem32& dst)\t\t\t\t\t\t\t{AppendInstr(I_FIADD, 0xDA, 0, Imm8(0), dst);}\n\tvoid fbld(const Mem80& dst)\t\t{AppendInstr(I_FBLD, 0xDF, 0, Imm8(4), dst);}\n\tvoid fbstp(const Mem80& dst)\t{AppendInstr(I_FBSTP, 0xDF, 0, Imm8(6), dst);}\n\tvoid fchs()\t\t{AppendInstr(I_FCHS, 0xD9E0, 0);}\n\tvoid fclex()\t{AppendInstr(I_FCLEX, 0x9BDBE2, 0);}\n\tvoid fnclex()\t{AppendInstr(I_FNCLEX, 0xDBE2, 0);}\n\tvoid fcmovb(const FpuReg_st0& dst, const FpuReg& src)\t{AppendInstr(I_FCMOVCC, 0xDAC0, 0, src); avoid_unused_warn(dst);}\n\tvoid fcmovbe(const FpuReg_st0& dst, const FpuReg& src)\t{AppendInstr(I_FCMOVCC, 0xDAD0, 0, src); avoid_unused_warn(dst);}\n\tvoid fcmove(const FpuReg_st0& dst, const FpuReg& src)\t{AppendInstr(I_FCMOVCC, 0xDAC8, 0, src); avoid_unused_warn(dst);}\n\tvoid fcmovnb(const FpuReg_st0& dst, const FpuReg& src)\t{AppendInstr(I_FCMOVCC, 0xDBC0, 0, src); avoid_unused_warn(dst);}\n\tvoid fcmovnbe(const FpuReg_st0& dst, const FpuReg& src)\t{AppendInstr(I_FCMOVCC, 0xDBD0, 0, src); avoid_unused_warn(dst);}\n\tvoid fcmovne(const FpuReg_st0& dst, const FpuReg& src)\t{AppendInstr(I_FCMOVCC, 0xDBC8, 0, src); avoid_unused_warn(dst);}\n\tvoid fcmovnu(const FpuReg_st0& dst, const FpuReg& src)\t{AppendInstr(I_FCMOVCC, 0xDBD8, 0, src); avoid_unused_warn(dst);}\n\tvoid fcmovu(const FpuReg_st0& dst, const FpuReg& src)\t{AppendInstr(I_FCMOVCC, 0xDAD8, 0, src); avoid_unused_warn(dst);}\n\tvoid fcom()\t\t\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_FCOM, 0xD8D1, 0);}\n\tvoid fcom(const FpuReg& dst)\t\t\t\t\t\t\t{AppendInstr(I_FCOM, 0xD8D0, 0, dst);}\n\tvoid fcom(const Mem32& dst)\t\t\t\t\t\t\t\t{AppendInstr(I_FCOM, 0xD8, 0, Imm8(2), dst);}\n\tvoid fcom(const Mem64& dst)\t\t\t\t\t\t\t\t{AppendInstr(I_FCOM, 0xDC, 0, Imm8(2), dst);}\n\tvoid fcomp()\t\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_FCOMP, 0xD8D9, 0);}\n\tvoid fcomp(const FpuReg& dst)\t\t\t\t\t\t\t{AppendInstr(I_FCOMP, 0xD8D8, 0, dst);}\n\tvoid fcomp(const Mem32& dst)\t\t\t\t\t\t\t{AppendInstr(I_FCOMP, 0xD8, 0, Imm8(3), dst);}\n\tvoid fcomp(const Mem64& dst)\t\t\t\t\t\t\t{AppendInstr(I_FCOMP, 0xDC, 0, Imm8(3), dst);}\n\tvoid fcompp()\t\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_FCOMPP, 0xDED9, 0);}\n\tvoid fcomi(const FpuReg_st0& dst, const FpuReg& src)\t{AppendInstr(I_FCOMI, 0xDBF0, 0, src); avoid_unused_warn(dst);}\n\tvoid fcomip(const FpuReg_st0& dst, const FpuReg& src)\t{AppendInstr(I_FCOMIP, 0xDFF0, 0, src); avoid_unused_warn(dst);}\n\tvoid fcos()\t\t{AppendInstr(I_FCOS, 0xD9FF, 0);}\n\tvoid fdecstp()\t{AppendInstr(I_FDECSTP, 0xD9F6, 0);}\n\tvoid fdiv(const FpuReg_st0& dst, const FpuReg& src)\t\t{AppendInstr(I_FDIV, 0xD8F0, 0, src); avoid_unused_warn(dst);}\n\tvoid fdiv(const FpuReg& dst, const FpuReg_st0& src)\t\t{AppendInstr(I_FDIV, 0xDCF8, 0, dst); avoid_unused_warn(src);}\n\tvoid fdiv(const Mem32& dst)\t\t\t\t\t\t\t\t{AppendInstr(I_FDIV, 0xD8, 0, Imm8(6), dst);}\n\tvoid fdiv(const Mem64& dst)\t\t\t\t\t\t\t\t{AppendInstr(I_FDIV, 0xDC, 0, Imm8(6), dst);}\n\tvoid fdivp()\t\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_FDIVP, 0xDEF9, 0);}\n\tvoid fdivp(const FpuReg& dst, const FpuReg_st0& src)\t{AppendInstr(I_FDIVP, 0xDEF8, 0, dst); avoid_unused_warn(src);}\n\tvoid fidiv(const Mem16& dst)\t\t\t\t\t\t\t{AppendInstr(I_FIDIV, 0xDE, 0, Imm8(6), dst);}\n\tvoid fidiv(const Mem32& dst)\t\t\t\t\t\t\t{AppendInstr(I_FIDIV, 0xDA, 0, Imm8(6), dst);}\n\tvoid fdivr(const FpuReg_st0& dst, const FpuReg& src)\t{AppendInstr(I_FDIVR, 0xD8F8, 0, src); avoid_unused_warn(dst);}\n\tvoid fdivr(const FpuReg& dst, const FpuReg_st0& src)\t{AppendInstr(I_FDIVR, 0xDCF0, 0, dst); avoid_unused_warn(src);}\n\tvoid fdivr(const Mem32& dst)\t\t\t\t\t\t\t{AppendInstr(I_FDIVR, 0xD8, 0, Imm8(7), dst);}\n\tvoid fdivr(const Mem64& dst)\t\t\t\t\t\t\t{AppendInstr(I_FDIVR, 0xDC, 0, Imm8(7), dst);}\n\tvoid fdivrp()\t\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_FDIVRP, 0xDEF1, 0);}\n\tvoid fdivrp(const FpuReg& dst, const FpuReg_st0& src)\t{AppendInstr(I_FDIVRP, 0xDEF0, 0, dst); avoid_unused_warn(src);}\n\tvoid fidivr(const Mem16& dst)\t\t\t\t\t\t\t{AppendInstr(I_FIDIVR, 0xDE, 0, Imm8(7), dst);}\n\tvoid fidivr(const Mem32& dst)\t\t\t\t\t\t\t{AppendInstr(I_FIDIVR, 0xDA, 0, Imm8(7), dst);}\n\tvoid ffree(const FpuReg& dst)\t{AppendInstr(I_FFREE, 0xDDC0, 0, dst);}\n\tvoid ficom(const Mem16& dst)\t{AppendInstr(I_FICOM, 0xDE, 0, Imm8(2), dst);}\n\tvoid ficom(const Mem32& dst)\t{AppendInstr(I_FICOM, 0xDA, 0, Imm8(2), dst);}\n\tvoid ficomp(const Mem16& dst)\t{AppendInstr(I_FICOMP, 0xDE, 0, Imm8(3), dst);}\n\tvoid ficomp(const Mem32& dst)\t{AppendInstr(I_FICOMP, 0xDA, 0, Imm8(3), dst);}\n\tvoid fild(const Mem16& dst)\t\t{AppendInstr(I_FILD, 0xDF, 0, Imm8(0), dst);}\n\tvoid fild(const Mem32& dst)\t\t{AppendInstr(I_FILD, 0xDB, 0, Imm8(0), dst);}\n\tvoid fild(const Mem64& dst)\t\t{AppendInstr(I_FILD, 0xDF, 0, Imm8(5), dst);}\n\tvoid fincstp()\t{AppendInstr(I_FINCSTP, 0xD9F7, 0);}\n\tvoid finit()\t{AppendInstr(I_FINIT, 0x9BDBE3, 0);}\n\tvoid fninit()\t{AppendInstr(I_FNINIT, 0xDBE3, 0);}\n\tvoid fist(const Mem16& dst)\t\t{AppendInstr(I_FIST, 0xDF, 0, Imm8(2), dst);}\n\tvoid fist(const Mem32& dst)\t\t{AppendInstr(I_FIST, 0xDB, 0, Imm8(2), dst);}\n\tvoid fistp(const Mem16& dst)\t{AppendInstr(I_FISTP, 0xDF, 0, Imm8(3), dst);}\n\tvoid fistp(const Mem32& dst)\t{AppendInstr(I_FISTP, 0xDB, 0, Imm8(3), dst);}\n\tvoid fistp(const Mem64& dst)\t{AppendInstr(I_FISTP, 0xDF, 0, Imm8(7), dst);}\n\tvoid fisttp(const Mem16& dst)\t{AppendInstr(I_FISTP, 0xDF, 0, Imm8(1), dst);}\n\tvoid fisttp(const Mem32& dst)\t{AppendInstr(I_FISTP, 0xDB, 0, Imm8(1), dst);}\n\tvoid fisttp(const Mem64& dst)\t{AppendInstr(I_FISTP, 0xDD, 0, Imm8(1), dst);}\n\tvoid fld(const Mem32& src)\t\t{AppendInstr(I_FLD, 0xD9, 0, Imm8(0), src);}\n\tvoid fld(const Mem64& src)\t\t{AppendInstr(I_FLD, 0xDD, 0, Imm8(0), src);}\n\tvoid fld(const Mem80& src)\t\t{AppendInstr(I_FLD, 0xDB, 0, Imm8(5), src);}\n\tvoid fld(const FpuReg& src)\t\t{AppendInstr(I_FLD, 0xD9C0, 0, src);}\n\tvoid fld1()\t\t{AppendInstr(I_FLD1, 0xD9E8, 0);}\n\tvoid fldcw(const Mem16& src)\t{AppendInstr(I_FLDCW, 0xD9, 0, Imm8(5), src);}\n\tvoid fldenv(const Mem224& src)\t{AppendInstr(I_FLDENV, 0xD9, 0, Imm8(4), src);}\n\tvoid fldl2e()\t{AppendInstr(I_FLDL2E, 0xD9EA, 0);}\n\tvoid fldl2t()\t{AppendInstr(I_FLDL2T, 0xD9E9, 0);}\n\tvoid fldlg2()\t{AppendInstr(I_FLDLG2, 0xD9EC, 0);}\n\tvoid fldln2()\t{AppendInstr(I_FLDLN2, 0xD9ED, 0);}\n\tvoid fldpi()\t{AppendInstr(I_FLDPI, 0xD9EB, 0);}\n\tvoid fldz()\t\t{AppendInstr(I_FLDZ, 0xD9EE, 0);}\n\tvoid fmul(const FpuReg_st0& dst, const FpuReg& src)\t\t{AppendInstr(I_FMUL, 0xD8C8, 0, src); avoid_unused_warn(dst);}\n\tvoid fmul(const FpuReg& dst, const FpuReg_st0& src)\t\t{AppendInstr(I_FMUL, 0xDCC8, 0, dst); avoid_unused_warn(src);}\n\tvoid fmul(const Mem32& dst)\t\t\t\t\t\t\t\t{AppendInstr(I_FMUL, 0xD8, 0, Imm8(1), dst);}\n\tvoid fmul(const Mem64& dst)\t\t\t\t\t\t\t\t{AppendInstr(I_FMUL, 0xDC, 0, Imm8(1), dst);}\n\tvoid fmulp()\t\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_FMULP, 0xDEC9, 0);}\n\tvoid fmulp(const FpuReg& dst, const FpuReg_st0& src)\t{AppendInstr(I_FMULP, 0xDEC8, 0, dst); avoid_unused_warn(src);}\n\tvoid fimul(const Mem16& dst)\t\t\t\t\t\t\t{AppendInstr(I_FIMUL, 0xDE, 0, Imm8(1), dst);}\n\tvoid fimul(const Mem32& dst)\t\t\t\t\t\t\t{AppendInstr(I_FIMUL, 0xDA, 0, Imm8(1), dst);}\n\tvoid fnop()\t\t{AppendInstr(I_FNOP, 0xD9D0, 0);}\n\tvoid fpatan()\t{AppendInstr(I_FPATAN, 0xD9F3, 0);}\n\tvoid fprem()\t{AppendInstr(I_FPREM, 0xD9F8, 0);}\n\tvoid fprem1()\t{AppendInstr(I_FPREM1, 0xD9F5, 0);}\n\tvoid fptan()\t{AppendInstr(I_FPTAN, 0xD9F2, 0);}\n\tvoid frndint()\t{AppendInstr(I_FRNDINT, 0xD9FC, 0);}\n\tvoid frstor(const Mem864& src)\t{AppendInstr(I_FRSTOR, 0xDD, 0, Imm8(4), src);}\n\tvoid fsave(const Mem864& dst)\t{AppendInstr(I_FSAVE, 0x9BDD, 0, Imm8(6), dst);}\n\tvoid fnsave(const Mem864& dst)\t{AppendInstr(I_FNSAVE, 0xDD, 0, Imm8(6), dst);}\n\tvoid fscale()\t{AppendInstr(I_FSCALE, 0xD9FD, 0);}\n\tvoid fsin()\t\t{AppendInstr(I_FSIN, 0xD9FE, 0);}\n\tvoid fsincos()\t{AppendInstr(I_FSINCOS, 0xD9FB, 0);}\n\tvoid fsqrt()\t{AppendInstr(I_FSQRT, 0xD9FA, 0);}\n\tvoid fst(const Mem32& dst)\t\t{AppendInstr(I_FST,\t0xD9, 0, Imm8(2), dst);}\n\tvoid fst(const Mem64& dst)\t\t{AppendInstr(I_FST,\t0xDD, 0, Imm8(2), dst);}\n\tvoid fst(const FpuReg& dst)\t\t{AppendInstr(I_FST,\t0xDDD0, 0, dst);}\n\tvoid fstp(const FpuReg& dst)\t{AppendInstr(I_FSTP, 0xDDD8, 0, dst);}\n\tvoid fstp(const Mem32& dst)\t\t{AppendInstr(I_FSTP, 0xD9, 0, Imm8(3), dst);}\n\tvoid fstp(const Mem64& dst)\t\t{AppendInstr(I_FSTP, 0xDD, 0, Imm8(3), dst);}\n\tvoid fstp(const Mem80& dst)\t\t{AppendInstr(I_FSTP, 0xDB, 0, Imm8(7), dst);}\n\tvoid fstcw(const Mem16& dst)\t{AppendInstr(I_FSTCW, 0x9BD9, 0, Imm8(7), dst);}\n\tvoid fnstcw(const Mem16& dst)\t{AppendInstr(I_FNSTCW, 0xD9, 0, Imm8(7), dst);}\n\tvoid fstenv(const Mem224& dst)\t{AppendInstr(I_FSTENV, 0x9BD9, 0, Imm8(6), dst);}\n\tvoid fnstenv(const Mem224& dst)\t{AppendInstr(I_FNSTENV, 0xD9, 0, Imm8(6), dst);}\n\tvoid fstsw(const Mem16& dst)\t\t{AppendInstr(I_FSTSW, 0x9BDD, 0, Imm8(7), dst);}\n\tvoid fstsw(const Reg16& dst)\t\t{AppendInstr(I_FSTSW, 0x9BDFE0, 0, Dummy(W(dst), ax));}\n\tvoid fnstsw(const Mem16& dst)\t\t{AppendInstr(I_FNSTSW, 0xDD, 0, Imm8(7), dst);}\n\tvoid fnstsw(const Reg16& dst)\t{AppendInstr(I_FNSTSW, 0xDFE0, 0, Dummy(W(dst), ax));}\n\tvoid fsub(const FpuReg_st0& dst, const FpuReg& src)\t\t{AppendInstr(I_FSUB, 0xD8E0, 0, src); avoid_unused_warn(dst);}\n\tvoid fsub(const FpuReg& dst, const FpuReg_st0& src)\t\t{AppendInstr(I_FSUB, 0xDCE8, 0, dst); avoid_unused_warn(src);}\n\tvoid fsub(const Mem32& dst)\t\t\t\t\t\t\t\t{AppendInstr(I_FSUB, 0xD8, 0, Imm8(4), dst);}\n\tvoid fsub(const Mem64& dst)\t\t\t\t\t\t\t\t{AppendInstr(I_FSUB, 0xDC, 0, Imm8(4), dst);}\n\tvoid fsubp()\t\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_FSUBP, 0xDEE9, 0);}\n\tvoid fsubp(const FpuReg& dst, const FpuReg_st0& src)\t{AppendInstr(I_FSUBP, 0xDEE8, 0, dst); avoid_unused_warn(src);}\n\tvoid fisub(const Mem16& dst)\t\t\t\t\t\t\t{AppendInstr(I_FISUB, 0xDE, 0, Imm8(4), dst);}\n\tvoid fisub(const Mem32& dst)\t\t\t\t\t\t\t{AppendInstr(I_FISUB, 0xDA, 0, Imm8(4), dst);}\n\tvoid fsubr(const FpuReg_st0& dst, const FpuReg& src)\t{AppendInstr(I_FSUBR, 0xD8E8, 0, src); avoid_unused_warn(dst);}\n\tvoid fsubr(const FpuReg& dst, const FpuReg_st0& src)\t{AppendInstr(I_FSUBR, 0xDCE0, 0, dst); avoid_unused_warn(src);}\n\tvoid fsubr(const Mem32& dst)\t\t\t\t\t\t\t{AppendInstr(I_FSUBR, 0xD8, 0, Imm8(5), dst);}\n\tvoid fsubr(const Mem64& dst)\t\t\t\t\t\t\t{AppendInstr(I_FSUBR, 0xDC, 0, Imm8(5), dst);}\n\tvoid fsubrp()\t\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_FSUBRP, 0xDEE1, 0);}\n\tvoid fsubrp(const FpuReg& dst, const FpuReg_st0& src)\t{AppendInstr(I_FSUBRP, 0xDEE0, 0, dst); avoid_unused_warn(src);}\n\tvoid fisubr(const Mem16& dst)\t\t\t\t\t\t\t{AppendInstr(I_FISUBR, 0xDE, 0, Imm8(5), dst);}\n\tvoid fisubr(const Mem32& dst)\t\t\t\t\t\t\t{AppendInstr(I_FISUBR, 0xDA, 0, Imm8(5), dst);}\n\tvoid ftst()\t\t{AppendInstr(I_FTST, 0xD9E4, 0);}\n\tvoid fucom()\t\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_FUCOM, 0xDDE1, 0);}\n\tvoid fucom(const FpuReg& dst)\t\t\t\t\t\t\t{AppendInstr(I_FUCOM, 0xDDE0, 0, dst);}\n\tvoid fucomp()\t\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_FUCOMP, 0xDDE9, 0);}\n\tvoid fucomp(const FpuReg& dst)\t\t\t\t\t\t\t{AppendInstr(I_FUCOMP, 0xDDE8, 0, dst);}\n\tvoid fucompp()\t\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_FUCOMPP, 0xDAE9, 0);}\n\tvoid fucomi(const FpuReg_st0& dst, const FpuReg& src)\t{AppendInstr(I_FUCOMI, 0xDBE8, 0, src); avoid_unused_warn(dst);}\n\tvoid fucomip(const FpuReg_st0& dst, const FpuReg& src)\t{AppendInstr(I_FUCOMIP, 0xDFE8, 0, src); avoid_unused_warn(dst);}\n\tvoid fwait()\t{wait();}\n\tvoid fxam()\t\t{AppendInstr(I_FXAM, 0xD9E5, 0);}\n\tvoid fxch()\t\t\t\t\t\t{AppendInstr(I_FXCH, 0xD9C9, 0);}\n\tvoid fxch(const FpuReg& dst)\t{AppendInstr(I_FXCH, 0xD9C8, 0, dst);}\n\tvoid fxrstor(const Mem4096& src)\t{AppendInstr(I_FXRSTOR, 0x0FAE, 0, Imm8(1), src);}\n\tvoid fxsave(const Mem4096& dst)\t\t{AppendInstr(I_FXSAVE, 0x0FAE, 0, Imm8(0), dst);}\n\tvoid fxtract()\t{AppendInstr(I_FXTRACT, 0xD9F4, 0);}\n\tvoid fyl2x()\t{AppendInstr(I_FYL2X, 0xD9F1, 0);}\n\tvoid fyl2xp1()\t{AppendInstr(I_FYL2XP1, 0xD9F9, 0);}\n\n\t// MMX\n\tvoid emms() {AppendInstr(I_EMMS, 0x0F77, 0);}\n\tvoid movd(const MmxReg& dst, const Reg32& src)\t{AppendInstr(I_MOVD, 0x0F6E, 0, W(dst), R(src));}\n\tvoid movd(const MmxReg& dst, const Mem32& src)\t{AppendInstr(I_MOVD, 0x0F6E, 0, W(dst), R(src));}\n\tvoid movd(const Reg32& dst, const MmxReg& src)\t{AppendInstr(I_MOVD, 0x0F7E, 0, R(src), W(dst));}\n\tvoid movd(const Mem32& dst, const MmxReg& src)\t{AppendInstr(I_MOVD, 0x0F7E, 0, R(src), W(dst));}\n#ifdef JITASM64\n\tvoid movd(const MmxReg& dst, const Reg64& src)\t{AppendInstr(I_MOVD, 0x0F6E, E_REXW_PREFIX, W(dst), R(src));}\n\tvoid movd(const Reg64& dst, const MmxReg& src)\t{AppendInstr(I_MOVD, 0x0F7E, E_REXW_PREFIX, R(src), W(dst));}\n#endif\n\tvoid movq(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_MOVQ, 0x0F6F, 0, W(dst), R(src));}\n\tvoid movq(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_MOVQ, 0x0F7F, 0, R(src), W(dst));}\n\tvoid movq(const Mem64& dst, const MmxReg& src)\t{AppendInstr(I_MOVQ, 0x0F7F, 0, R(src), W(dst));}\n#ifdef JITASM64\n\tvoid movq(const MmxReg& dst, const Reg64& src)\t{movd(dst, src);}\n\tvoid movq(const Reg64& dst, const MmxReg& src)\t{movd(dst, src);}\n#endif\n\tvoid packsswb(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PACKSSWB, 0x0F63, 0, RW(dst), R(src));}\n\tvoid packsswb(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PACKSSWB, 0x0F63, 0, RW(dst), R(src));}\n\tvoid packssdw(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PACKSSDW, 0x0F6B, 0, RW(dst), R(src));}\n\tvoid packssdw(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PACKSSDW, 0x0F6B, 0, RW(dst), R(src));}\n\tvoid packuswb(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PACKUSWB, 0x0F67, 0, RW(dst), R(src));}\n\tvoid packuswb(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PACKUSWB, 0x0F67, 0, RW(dst), R(src));}\n\tvoid paddb(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PADDB,\t0x0FFC, 0, RW(dst), R(src));}\n\tvoid paddb(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PADDB,\t0x0FFC, 0, RW(dst), R(src));}\n\tvoid paddw(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PADDW,\t0x0FFD, 0, RW(dst), R(src));}\n\tvoid paddw(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PADDW,\t0x0FFD, 0, RW(dst), R(src));}\n\tvoid paddd(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PADDD,\t0x0FFE, 0, RW(dst), R(src));}\n\tvoid paddd(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PADDD,\t0x0FFE, 0, RW(dst), R(src));}\n\tvoid paddsb(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PADDSB,\t0x0FEC, 0, RW(dst), R(src));}\n\tvoid paddsb(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PADDSB,\t0x0FEC, 0, RW(dst), R(src));}\n\tvoid paddsw(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PADDSW,\t0x0FED, 0, RW(dst), R(src));}\n\tvoid paddsw(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PADDSW,\t0x0FED, 0, RW(dst), R(src));}\n\tvoid paddusb(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PADDUSB,\t0x0FDC, 0, RW(dst), R(src));}\n\tvoid paddusb(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PADDUSB,\t0x0FDC, 0, RW(dst), R(src));}\n\tvoid paddusw(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PADDUSW,\t0x0FDD, 0, RW(dst), R(src));}\n\tvoid paddusw(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PADDUSW,\t0x0FDD, 0, RW(dst), R(src));}\n\tvoid pand(const MmxReg& dst, const MmxReg& src)\t\t{AppendInstr(I_PAND,\t0x0FDB, 0, RW(dst), R(src));}\n\tvoid pand(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PAND,\t0x0FDB, 0, RW(dst), R(src));}\n\tvoid pandn(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PANDN,\t0x0FDF, 0, RW(dst), R(src));}\n\tvoid pandn(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PANDN,\t0x0FDF, 0, RW(dst), R(src));}\n\tvoid pcmpeqb(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PCMPEQB,\t0x0F74, 0, RW(dst), R(src));}\n\tvoid pcmpeqb(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PCMPEQB,\t0x0F74, 0, RW(dst), R(src));}\n\tvoid pcmpeqw(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PCMPEQW,\t0x0F75, 0, RW(dst), R(src));}\n\tvoid pcmpeqw(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PCMPEQW,\t0x0F75, 0, RW(dst), R(src));}\n\tvoid pcmpeqd(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PCMPEQD,\t0x0F76, 0, RW(dst), R(src));}\n\tvoid pcmpeqd(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PCMPEQD,\t0x0F76, 0, RW(dst), R(src));}\n\tvoid pcmpgtb(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PCMPGTB,\t0x0F64, 0, RW(dst), R(src));}\n\tvoid pcmpgtb(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PCMPGTB,\t0x0F64, 0, RW(dst), R(src));}\n\tvoid pcmpgtw(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PCMPGTW,\t0x0F65, 0, RW(dst), R(src));}\n\tvoid pcmpgtw(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PCMPGTW,\t0x0F65, 0, RW(dst), R(src));}\n\tvoid pcmpgtd(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PCMPGTD,\t0x0F66, 0, RW(dst), R(src));}\n\tvoid pcmpgtd(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PCMPGTD,\t0x0F66, 0, RW(dst), R(src));}\n\tvoid pmaddwd(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PMADDWD,\t0x0FF5, 0, RW(dst), R(src));}\n\tvoid pmaddwd(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PMADDWD,\t0x0FF5, 0, RW(dst), R(src));}\n\tvoid pmulhw(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PMULHW,\t0x0FE5, 0, RW(dst), R(src));}\n\tvoid pmulhw(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PMULHW,\t0x0FE5, 0, RW(dst), R(src));}\n\tvoid pmullw(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PMULLW,\t0x0FD5, 0, RW(dst), R(src));}\n\tvoid pmullw(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PMULLW,\t0x0FD5, 0, RW(dst), R(src));}\n\tvoid por(const MmxReg& dst, const MmxReg& src)\t\t{AppendInstr(I_POR,\t\t0x0FEB, 0, RW(dst), R(src));}\n\tvoid por(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_POR,\t\t0x0FEB, 0, RW(dst), R(src));}\n\tvoid psllw(const MmxReg& dst, const MmxReg& count)\t{AppendInstr(I_PSLLW,\t0x0FF1, 0, RW(dst), R(count));}\n\tvoid psllw(const MmxReg& dst, const Mem64& count)\t{AppendInstr(I_PSLLW,\t0x0FF1, 0, RW(dst), R(count));}\n\tvoid psllw(const MmxReg& dst, const Imm8& count)\t{AppendInstr(I_PSLLW,\t0x0F71, 0, Imm8(6), RW(dst), count);}\n\tvoid pslld(const MmxReg& dst, const MmxReg& count)\t{AppendInstr(I_PSLLD,\t0x0FF2, 0, RW(dst), R(count));}\n\tvoid pslld(const MmxReg& dst, const Mem64& count)\t{AppendInstr(I_PSLLD,\t0x0FF2, 0, RW(dst), R(count));}\n\tvoid pslld(const MmxReg& dst, const Imm8& count)\t{AppendInstr(I_PSLLD,\t0x0F72, 0, Imm8(6), RW(dst), count);}\n\tvoid psllq(const MmxReg& dst, const MmxReg& count)\t{AppendInstr(I_PSLLQ,\t0x0FF3, 0, RW(dst), R(count));}\n\tvoid psllq(const MmxReg& dst, const Mem64& count)\t{AppendInstr(I_PSLLQ,\t0x0FF3, 0, RW(dst), R(count));}\n\tvoid psllq(const MmxReg& dst, const Imm8& count)\t{AppendInstr(I_PSLLQ,\t0x0F73, 0, Imm8(6), RW(dst), count);}\n\tvoid psraw(const MmxReg& dst, const MmxReg& count)\t{AppendInstr(I_PSRAW,\t0x0FE1, 0, RW(dst), R(count));}\n\tvoid psraw(const MmxReg& dst, const Mem64& count)\t{AppendInstr(I_PSRAW,\t0x0FE1, 0, RW(dst), R(count));}\n\tvoid psraw(const MmxReg& dst, const Imm8& count)\t{AppendInstr(I_PSRAW,\t0x0F71, 0, Imm8(4), RW(dst), count);}\n\tvoid psrad(const MmxReg& dst, const MmxReg& count)\t{AppendInstr(I_PSRAD,\t0x0FE2, 0, RW(dst), R(count));}\n\tvoid psrad(const MmxReg& dst, const Mem64& count)\t{AppendInstr(I_PSRAD,\t0x0FE2, 0, RW(dst), R(count));}\n\tvoid psrad(const MmxReg& dst, const Imm8& count)\t{AppendInstr(I_PSRAD,\t0x0F72, 0, Imm8(4), RW(dst), count);}\n\tvoid psrlw(const MmxReg& dst, const MmxReg& count)\t{AppendInstr(I_PSRLW,\t0x0FD1, 0, RW(dst), R(count));}\n\tvoid psrlw(const MmxReg& dst, const Mem64& count)\t{AppendInstr(I_PSRLW,\t0x0FD1, 0, RW(dst), R(count));}\n\tvoid psrlw(const MmxReg& dst, const Imm8& count)\t{AppendInstr(I_PSRLW,\t0x0F71, 0, Imm8(2), RW(dst), count);}\n\tvoid psrld(const MmxReg& dst, const MmxReg& count)\t{AppendInstr(I_PSRLD,\t0x0FD2, 0, RW(dst), R(count));}\n\tvoid psrld(const MmxReg& dst, const Mem64& count)\t{AppendInstr(I_PSRLD,\t0x0FD2, 0, RW(dst), R(count));}\n\tvoid psrld(const MmxReg& dst, const Imm8& count)\t{AppendInstr(I_PSRLD,\t0x0F72, 0, Imm8(2), RW(dst), count);}\n\tvoid psrlq(const MmxReg& dst, const MmxReg& count)\t{AppendInstr(I_PSRLQ,\t0x0FD3, 0, RW(dst), R(count));}\n\tvoid psrlq(const MmxReg& dst, const Mem64& count)\t{AppendInstr(I_PSRLQ,\t0x0FD3, 0, RW(dst), R(count));}\n\tvoid psrlq(const MmxReg& dst, const Imm8& count)\t{AppendInstr(I_PSRLQ,\t0x0F73, 0, Imm8(2), RW(dst), count);}\n\tvoid psubb(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PSUBB,\t0x0FF8, 0, RW(dst), R(src));}\n\tvoid psubb(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PSUBB,\t0x0FF8, 0, RW(dst), R(src));}\n\tvoid psubw(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PSUBW,\t0x0FF9, 0, RW(dst), R(src));}\n\tvoid psubw(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PSUBW,\t0x0FF9, 0, RW(dst), R(src));}\n\tvoid psubd(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PSUBD,\t0x0FFA, 0, RW(dst), R(src));}\n\tvoid psubd(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PSUBD,\t0x0FFA, 0, RW(dst), R(src));}\n\tvoid psubsb(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PSUBSB,\t0x0FE8, 0, RW(dst), R(src));}\n\tvoid psubsb(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PSUBSB,\t0x0FE8, 0, RW(dst), R(src));}\n\tvoid psubsw(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PSUBSW,\t0x0FE9, 0, RW(dst), R(src));}\n\tvoid psubsw(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PSUBSW,\t0x0FE9, 0, RW(dst), R(src));}\n\tvoid psubusb(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PSUBUSB,\t0x0FD8, 0, RW(dst), R(src));}\n\tvoid psubusb(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PSUBUSB,\t0x0FD8, 0, RW(dst), R(src));}\n\tvoid psubusw(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PSUBUSW,\t0x0FD9, 0, RW(dst), R(src));}\n\tvoid psubusw(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PSUBUSW,\t0x0FD9, 0, RW(dst), R(src));}\n\tvoid punpckhbw(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PUNPCKHBW, 0x0F68, 0, RW(dst), R(src));}\n\tvoid punpckhbw(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PUNPCKHBW, 0x0F68, 0, RW(dst), R(src));}\n\tvoid punpckhwd(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PUNPCKHWD, 0x0F69, 0, RW(dst), R(src));}\n\tvoid punpckhwd(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PUNPCKHWD, 0x0F69, 0, RW(dst), R(src));}\n\tvoid punpckhdq(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PUNPCKHDQ, 0x0F6A, 0, RW(dst), R(src));}\n\tvoid punpckhdq(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PUNPCKHDQ, 0x0F6A, 0, RW(dst), R(src));}\n\tvoid punpcklbw(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PUNPCKLBW, 0x0F60, 0, RW(dst), R(src));}\n\tvoid punpcklbw(const MmxReg& dst, const Mem32& src)\t\t{AppendInstr(I_PUNPCKLBW, 0x0F60, 0, RW(dst), R(src));}\n\tvoid punpcklwd(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PUNPCKLWD, 0x0F61, 0, RW(dst), R(src));}\n\tvoid punpcklwd(const MmxReg& dst, const Mem32& src)\t\t{AppendInstr(I_PUNPCKLWD, 0x0F61, 0, RW(dst), R(src));}\n\tvoid punpckldq(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PUNPCKLDQ, 0x0F62, 0, RW(dst), R(src));}\n\tvoid punpckldq(const MmxReg& dst, const Mem32& src)\t\t{AppendInstr(I_PUNPCKLDQ, 0x0F62, 0, RW(dst), R(src));}\n\tvoid pxor(const MmxReg& dst, const MmxReg& src)\t\t{AppendInstr(I_PXOR, 0x0FEF, 0, RW(dst), R(src));}\n\tvoid pxor(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PXOR, 0x0FEF, 0, RW(dst), R(src));}\n\n\t// MMX2\n\tvoid pavgb(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PAVGB, 0x0FE0, 0, RW(dst), R(src));}\n\tvoid pavgb(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PAVGB, 0x0FE0, 0, RW(dst), R(src));}\n\tvoid pavgw(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PAVGW, 0x0FE3, 0, RW(dst), R(src));}\n\tvoid pavgw(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PAVGW, 0x0FE3, 0, RW(dst), R(src));}\n\tvoid pextrw(const Reg32& dst, const MmxReg& src, const Imm8& i)\t{AppendInstr(I_PEXTRW, 0x0FC5, 0, W(dst), R(src), i);}\n#ifdef JITASM64\n\tvoid pextrw(const Reg64& dst, const MmxReg& src, const Imm8& i)\t{AppendInstr(I_PEXTRW, 0x0FC5, E_REXW_PREFIX, W(dst), R(src), i);}\n#endif\n\tvoid pinsrw(const MmxReg& dst, const Reg32& src, const Imm8& i)\t{AppendInstr(I_PINSRW, 0x0FC4, 0, RW(dst), R(src), i);}\n\tvoid pinsrw(const MmxReg& dst, const Mem16& src, const Imm8& i)\t{AppendInstr(I_PINSRW, 0x0FC4, 0, RW(dst), R(src), i);}\n#ifdef JITASM64\n\tvoid pinsrw(const MmxReg& dst, const Reg64& src, const Imm8& i)\t{AppendInstr(I_PINSRW, 0x0FC4, E_REXW_PREFIX, RW(dst), R(src), i);}\n#endif\n\tvoid pmaxsw(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PMAXSW,\t0x0FEE, 0, RW(dst), R(src));}\n\tvoid pmaxsw(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PMAXSW,\t0x0FEE, 0, RW(dst), R(src));}\n\tvoid pmaxub(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PMAXUB,\t0x0FDE, 0, RW(dst), R(src));}\n\tvoid pmaxub(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PMAXUB,\t0x0FDE, 0, RW(dst), R(src));}\n\tvoid pminsw(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PMINSW,\t0x0FEA, 0, RW(dst), R(src));}\n\tvoid pminsw(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PMINSW,\t0x0FEA, 0, RW(dst), R(src));}\n\tvoid pminub(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PMINUB,\t0x0FDA, 0, RW(dst), R(src));}\n\tvoid pminub(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PMINUB,\t0x0FDA, 0, RW(dst), R(src));}\n\tvoid pmovmskb(const Reg32& dst, const MmxReg& src)\t{AppendInstr(I_PMOVMSKB, 0x0FD7, 0, W(dst), R(src));}\n#ifdef JITASM64\n\tvoid pmovmskb(const Reg64& dst, const MmxReg& src)\t{AppendInstr(I_PMOVMSKB, 0x0FD7, E_REXW_PREFIX, W(dst), R(src));}\n#endif\n\tvoid pmulhuw(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PMULHUW,\t0x0FE4, 0, RW(dst), R(src));}\n\tvoid pmulhuw(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PMULHUW,\t0x0FE4, 0, RW(dst), R(src));}\n\tvoid psadbw(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PSADBW,\t0x0FF6, 0, RW(dst), R(src));}\n\tvoid psadbw(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PSADBW,\t0x0FF6, 0, RW(dst), R(src));}\n\tvoid pshufw(const MmxReg& dst, const MmxReg& src, const Imm8& order)\t{AppendInstr(I_PSHUFW, 0x0F70, 0, RW(dst), R(src), order);}\n\tvoid pshufw(const MmxReg& dst, const Mem64& src, const Imm8& order)\t\t{AppendInstr(I_PSHUFW, 0x0F70, 0, RW(dst), R(src), order);}\n\n\t// SSE\n\tvoid addps(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_ADDPS,\t0x0F58, 0, RW(dst), R(src));}\n\tvoid addps(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_ADDPS,\t0x0F58, 0, RW(dst), R(src));}\n\tvoid addss(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_ADDSS,\t0x0F58, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}\n\tvoid addss(const XmmReg& dst, const Mem32& src)\t\t{AppendInstr(I_ADDSS,\t0x0F58, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}\n\tvoid andps(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_ANDPS,\t0x0F54, 0, RW(dst), R(src));}\n\tvoid andps(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_ANDPS,\t0x0F54, 0, RW(dst), R(src));}\n\tvoid andnps(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_ANDNPS,\t0x0F55, 0, RW(dst), R(src));}\n\tvoid andnps(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_ANDNPS,\t0x0F55, 0, RW(dst), R(src));}\n\tvoid cmpps(const XmmReg& dst, const XmmReg& src, const Imm8& opd3)\t{AppendInstr(I_CMPPS, 0x0FC2, 0, RW(dst), R(src), opd3);}\n\tvoid cmpps(const XmmReg& dst, const Mem128& src, const Imm8& opd3)\t{AppendInstr(I_CMPPS, 0x0FC2, 0, RW(dst), R(src), opd3);}\n\tvoid cmpeqps(const XmmReg& dst, const XmmReg& src)\t\t{cmpps(dst, src, 0);}\n\tvoid cmpeqps(const XmmReg& dst, const Mem128& src)\t\t{cmpps(dst, src, 0);}\n\tvoid cmpltps(const XmmReg& dst, const XmmReg& src)\t\t{cmpps(dst, src, 1);}\n\tvoid cmpltps(const XmmReg& dst, const Mem128& src)\t\t{cmpps(dst, src, 1);}\n\tvoid cmpleps(const XmmReg& dst, const XmmReg& src)\t\t{cmpps(dst, src, 2);}\n\tvoid cmpleps(const XmmReg& dst, const Mem128& src)\t\t{cmpps(dst, src, 2);}\n\tvoid cmpunordps(const XmmReg& dst, const XmmReg& src)\t{cmpps(dst, src, 3);}\n\tvoid cmpunordps(const XmmReg& dst, const Mem128& src)\t{cmpps(dst, src, 3);}\n\tvoid cmpneqps(const XmmReg& dst, const XmmReg& src)\t\t{cmpps(dst, src, 4);}\n\tvoid cmpneqps(const XmmReg& dst, const Mem128& src)\t\t{cmpps(dst, src, 4);}\n\tvoid cmpnltps(const XmmReg& dst, const XmmReg& src)\t\t{cmpps(dst, src, 5);}\n\tvoid cmpnltps(const XmmReg& dst, const Mem128& src)\t\t{cmpps(dst, src, 5);}\n\tvoid cmpnleps(const XmmReg& dst, const XmmReg& src)\t\t{cmpps(dst, src, 6);}\n\tvoid cmpnleps(const XmmReg& dst, const Mem128& src)\t\t{cmpps(dst, src, 6);}\n\tvoid cmpordps(const XmmReg& dst, const XmmReg& src)\t\t{cmpps(dst, src, 7);}\n\tvoid cmpordps(const XmmReg& dst, const Mem128& src)\t\t{cmpps(dst, src, 7);}\n\tvoid cmpss(const XmmReg& dst, const XmmReg& src, const Imm8& opd3)\t{AppendInstr(I_CMPSS, 0x0FC2, E_MANDATORY_PREFIX_F3, RW(dst), R(src), opd3);}\n\tvoid cmpss(const XmmReg& dst, const Mem32& src, const Imm8& opd3)\t{AppendInstr(I_CMPSS, 0x0FC2, E_MANDATORY_PREFIX_F3, RW(dst), R(src), opd3);}\n\tvoid cmpeqss(const XmmReg& dst, const XmmReg& src)\t\t{cmpss(dst, src, 0);}\n\tvoid cmpeqss(const XmmReg& dst, const Mem32& src)\t\t{cmpss(dst, src, 0);}\n\tvoid cmpltss(const XmmReg& dst, const XmmReg& src)\t\t{cmpss(dst, src, 1);}\n\tvoid cmpltss(const XmmReg& dst, const Mem32& src)\t\t{cmpss(dst, src, 1);}\n\tvoid cmpless(const XmmReg& dst, const XmmReg& src)\t\t{cmpss(dst, src, 2);}\n\tvoid cmpless(const XmmReg& dst, const Mem32& src)\t\t{cmpss(dst, src, 2);}\n\tvoid cmpunordss(const XmmReg& dst, const XmmReg& src)\t{cmpss(dst, src, 3);}\n\tvoid cmpunordss(const XmmReg& dst, const Mem32& src)\t{cmpss(dst, src, 3);}\n\tvoid cmpneqss(const XmmReg& dst, const XmmReg& src)\t\t{cmpss(dst, src, 4);}\n\tvoid cmpneqss(const XmmReg& dst, const Mem32& src)\t\t{cmpss(dst, src, 4);}\n\tvoid cmpnltss(const XmmReg& dst, const XmmReg& src)\t\t{cmpss(dst, src, 5);}\n\tvoid cmpnltss(const XmmReg& dst, const Mem32& src)\t\t{cmpss(dst, src, 5);}\n\tvoid cmpnless(const XmmReg& dst, const XmmReg& src)\t\t{cmpss(dst, src, 6);}\n\tvoid cmpnless(const XmmReg& dst, const Mem32& src)\t\t{cmpss(dst, src, 6);}\n\tvoid cmpordss(const XmmReg& dst, const XmmReg& src)\t\t{cmpss(dst, src, 7);}\n\tvoid cmpordss(const XmmReg& dst, const Mem32& src)\t\t{cmpss(dst, src, 7);}\n\tvoid comiss(const XmmReg& src1, const XmmReg& src2)\t\t{AppendInstr(I_COMISS,\t0x0F2F, 0, R(src1), R(src2));}\n\tvoid comiss(const XmmReg& src1, const Mem32& src2)\t\t{AppendInstr(I_COMISS,\t0x0F2F, 0, R(src1), R(src2));}\n\tvoid cvtpi2ps(const XmmReg& dst, const MmxReg& src)\t\t{AppendInstr(I_CVTPI2PS, 0x0F2A, 0, RW(dst), R(src));}\n\tvoid cvtpi2ps(const XmmReg& dst, const Mem64& src)\t\t{AppendInstr(I_CVTPI2PS, 0x0F2A, 0, RW(dst), R(src));}\n\tvoid cvtps2pi(const MmxReg& dst, const XmmReg& src)\t\t{AppendInstr(I_CVTPS2PI, 0x0F2D, 0, W(dst), R(src));}\n\tvoid cvtps2pi(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_CVTPS2PI, 0x0F2D, 0, W(dst), R(src));}\n\tvoid cvtsi2ss(const XmmReg& dst, const Reg32& src)\t\t{AppendInstr(I_CVTSI2SS, 0x0F2A, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}\n\tvoid cvtsi2ss(const XmmReg& dst, const Mem32& src)\t\t{AppendInstr(I_CVTSI2SS, 0x0F2A, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}\n\tvoid cvtss2si(const Reg32& dst, const XmmReg& src)\t\t{AppendInstr(I_CVTSS2SI, 0x0F2D, E_MANDATORY_PREFIX_F3, W(dst), R(src));}\n\tvoid cvtss2si(const Reg32& dst, const Mem32& src)\t\t{AppendInstr(I_CVTSS2SI, 0x0F2D, E_MANDATORY_PREFIX_F3, W(dst), R(src));}\n\tvoid cvttps2pi(const MmxReg& dst, const XmmReg& src)\t{AppendInstr(I_CVTTPS2PI, 0x0F2C, 0, W(dst), R(src));}\n\tvoid cvttps2pi(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_CVTTPS2PI, 0x0F2C, 0, W(dst), R(src));}\n\tvoid cvttss2si(const Reg32& dst, const XmmReg& src)\t\t{AppendInstr(I_CVTTSS2SI, 0x0F2C, E_MANDATORY_PREFIX_F3, W(dst), R(src));}\n\tvoid cvttss2si(const Reg32& dst, const Mem32& src)\t\t{AppendInstr(I_CVTTSS2SI, 0x0F2C, E_MANDATORY_PREFIX_F3, W(dst), R(src));}\n#ifdef JITASM64\n\tvoid cvtsi2ss(const XmmReg& dst, const Reg64& src)\t\t{AppendInstr(I_CVTSI2SS, 0x0F2A, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cvtsi2ss(const XmmReg& dst, const Mem64& src)\t\t{AppendInstr(I_CVTSI2SS, 0x0F2A, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cvtss2si(const Reg64& dst, const XmmReg& src)\t\t{AppendInstr(I_CVTSS2SI, 0x0F2D, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));}\n\tvoid cvtss2si(const Reg64& dst, const Mem32& src)\t\t{AppendInstr(I_CVTSS2SI, 0x0F2D, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));}\n\tvoid cvttss2si(const Reg64& dst, const XmmReg& src)\t\t{AppendInstr(I_CVTTSS2SI, 0x0F2C, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));}\n\tvoid cvttss2si(const Reg64& dst, const Mem32& src)\t\t{AppendInstr(I_CVTTSS2SI, 0x0F2C, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));}\n#endif\n\tvoid divps(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_DIVPS,\t0x0F5E, 0, RW(dst), R(src));}\n\tvoid divps(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_DIVPS,\t0x0F5E, 0, RW(dst), R(src));}\n\tvoid divss(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_DIVSS,\t0x0F5E, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}\n\tvoid divss(const XmmReg& dst, const Mem32& src)\t\t{AppendInstr(I_DIVSS,\t0x0F5E, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}\n\tvoid ldmxcsr(const Mem32& src)\t\t\t\t\t\t{AppendInstr(I_LDMXCSR,\t0x0FAE, 0, Imm8(2), R(src));}\n\tvoid maskmovq(const MmxReg& src, const MmxReg& mask, const Reg& dstptr)\t{AppendInstr(I_MASKMOVQ, 0x0FF7, 0, R(src), R(mask), Dummy(R(dstptr),zdi));}\n\tvoid maxps(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MAXPS,\t0x0F5F, 0, RW(dst), R(src));}\n\tvoid maxps(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_MAXPS,\t0x0F5F, 0, RW(dst), R(src));}\n\tvoid maxss(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MAXSS,\t0x0F5F, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}\n\tvoid maxss(const XmmReg& dst, const Mem32& src)\t\t{AppendInstr(I_MAXSS,\t0x0F5F, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}\n\tvoid minps(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MINPS,\t0x0F5D, 0, RW(dst), R(src));}\n\tvoid minps(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_MINPS,\t0x0F5D, 0, RW(dst), R(src));}\n\tvoid minss(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MINSS,\t0x0F5D, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}\n\tvoid minss(const XmmReg& dst, const Mem32& src)\t\t{AppendInstr(I_MINSS,\t0x0F5D, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}\n\tvoid movaps(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MOVAPS,\t0x0F28, 0, W(dst), R(src));}\n\tvoid movaps(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_MOVAPS,\t0x0F28, 0, W(dst), R(src));}\n\tvoid movaps(const Mem128& dst, const XmmReg& src)\t{AppendInstr(I_MOVAPS,\t0x0F29, 0, R(src), W(dst));}\n\tvoid movhlps(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MOVHLPS,\t0x0F12, 0, RW(dst), R(src));}\n\tvoid movhps(const XmmReg& dst, const Mem64& src)\t{AppendInstr(I_MOVHPS,\t0x0F16, 0, RW(dst), R(src));}\n\tvoid movhps(const Mem64& dst, const XmmReg& src)\t{AppendInstr(I_MOVHPS,\t0x0F17, 0, R(src), W(dst));}\n\tvoid movlhps(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MOVLHPS,\t0x0F16, 0, RW(dst), R(src));}\n\tvoid movlps(const XmmReg& dst, const Mem64& src)\t{AppendInstr(I_MOVLPS,\t0x0F12, 0, RW(dst), R(src));}\n\tvoid movlps(const Mem64& dst, const XmmReg& src)\t{AppendInstr(I_MOVLPS,\t0x0F13, 0, R(src), W(dst));}\n\tvoid movmskps(const Reg32& dst, const XmmReg& src)\t{AppendInstr(I_MOVMSKPS, 0x0F50, 0, W(dst), R(src));}\n#ifdef JITASM64\n\tvoid movmskps(const Reg64& dst, const XmmReg& src)\t{AppendInstr(I_MOVMSKPS, 0x0F50, E_REXW_PREFIX, W(dst), R(src));}\n#endif\n\tvoid movntps(const Mem128& dst, const XmmReg& src)\t{AppendInstr(I_MOVNTPS,\t0x0F2B, 0, R(src), W(dst));}\n\tvoid movntq(const Mem64& dst, const MmxReg& src)\t{AppendInstr(I_MOVNTQ,\t0x0FE7, 0, R(src), W(dst));}\n\tvoid movss(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MOVSS,\t0x0F10, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}\n\tvoid movss(const XmmReg& dst, const Mem32& src)\t\t{AppendInstr(I_MOVSS,\t0x0F10, E_MANDATORY_PREFIX_F3, W(dst), R(src));}\n\tvoid movss(const Mem32& dst, const XmmReg& src)\t\t{AppendInstr(I_MOVSS,\t0x0F11, E_MANDATORY_PREFIX_F3, R(src), W(dst));}\n\tvoid movups(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MOVUPS,\t0x0F10, 0, W(dst), R(src));}\n\tvoid movups(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_MOVUPS,\t0x0F10, 0, W(dst), R(src));}\n\tvoid movups(const Mem128& dst, const XmmReg& src)\t{AppendInstr(I_MOVUPS,\t0x0F11, 0, R(src), W(dst));}\n\tvoid mulps(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MULPS,\t0x0F59, 0, RW(dst), R(src));}\n\tvoid mulps(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_MULPS,\t0x0F59, 0, RW(dst), R(src));}\n\tvoid mulss(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MULSS,\t0x0F59, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}\n\tvoid mulss(const XmmReg& dst, const Mem32& src)\t\t{AppendInstr(I_MULSS,\t0x0F59, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}\n\tvoid orps(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_ORPS,\t\t0x0F56, 0, RW(dst), R(src));}\n\tvoid orps(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_ORPS,\t\t0x0F56, 0, RW(dst), R(src));}\n\tvoid prefetcht0(const Mem8& mem)\t\t\t\t\t{AppendInstr(I_PREFETCH,\t0x0F18, 0, Imm8(1), R(mem));}\n\tvoid prefetcht1(const Mem8& mem)\t\t\t\t\t{AppendInstr(I_PREFETCH,\t0x0F18, 0, Imm8(2), R(mem));}\n\tvoid prefetcht2(const Mem8& mem)\t\t\t\t\t{AppendInstr(I_PREFETCH,\t0x0F18, 0, Imm8(3), R(mem));}\n\tvoid prefetchnta(const Mem8& mem)\t\t\t\t\t{AppendInstr(I_PREFETCH,\t0x0F18, 0, Imm8(0), R(mem));}\n\tvoid rcpps(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_RCPPS,\t0x0F53, 0, W(dst), R(src));}\n\tvoid rcpps(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_RCPPS,\t0x0F53, 0, W(dst), R(src));}\n\tvoid rcpss(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_RCPSS,\t0x0F53, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}\n\tvoid rcpss(const XmmReg& dst, const Mem32& src)\t\t{AppendInstr(I_RCPSS,\t0x0F53, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}\n\tvoid rsqrtps(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_RSQRTPS,\t0x0F52, 0, W(dst), R(src));}\n\tvoid rsqrtps(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_RSQRTPS,\t0x0F52, 0, W(dst), R(src));}\n\tvoid rsqrtss(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_RSQRTSS,\t0x0F52, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}\n\tvoid rsqrtss(const XmmReg& dst, const Mem32& src)\t{AppendInstr(I_RSQRTSS,\t0x0F52, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}\n\tvoid sfence()\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_SFENCE,\t0x0FAEF8, 0);}\n\tvoid shufps(const XmmReg& dst, const XmmReg& src, const Imm8& sel)\t{AppendInstr(I_SHUFPS, 0x0FC6, 0, RW(dst), R(src), sel);}\n\tvoid shufps(const XmmReg& dst, const Mem128& src, const Imm8& sel)\t{AppendInstr(I_SHUFPS, 0x0FC6, 0, RW(dst), R(src), sel);}\n\tvoid sqrtps(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_SQRTPS,\t0x0F51, 0, W(dst), R(src));}\n\tvoid sqrtps(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_SQRTPS,\t0x0F51, 0, W(dst), R(src));}\n\tvoid sqrtss(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_SQRTSS,\t0x0F51, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}\n\tvoid sqrtss(const XmmReg& dst, const Mem32& src)\t{AppendInstr(I_SQRTSS,\t0x0F51, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}\n\tvoid stmxcsr(const Mem32& dst)\t\t\t\t\t\t{AppendInstr(I_STMXCSR,\t0x0FAE, 0, Imm8(3), W(dst));}\n\tvoid subps(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_SUBPS,\t0x0F5C, 0, RW(dst), R(src));}\n\tvoid subps(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_SUBPS,\t0x0F5C, 0, RW(dst), R(src));}\n\tvoid subss(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_SUBSS,\t0x0F5C, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}\n\tvoid subss(const XmmReg& dst, const Mem32& src)\t\t{AppendInstr(I_SUBSS,\t0x0F5C, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}\n\tvoid ucomiss(const XmmReg& src1, const XmmReg& src2){AppendInstr(I_UCOMISS,\t0x0F2E, 0, R(src1), R(src2));}\n\tvoid ucomiss(const XmmReg& src1, const Mem32& src2)\t{AppendInstr(I_UCOMISS,\t0x0F2E, 0, R(src1), R(src2));}\n\tvoid unpckhps(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_UNPCKHPS, 0x0F15, 0, RW(dst), R(src));}\n\tvoid unpckhps(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_UNPCKHPS, 0x0F15, 0, RW(dst), R(src));}\n\tvoid unpcklps(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_UNPCKLPS, 0x0F14, 0, RW(dst), R(src));}\n\tvoid unpcklps(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_UNPCKLPS, 0x0F14, 0, RW(dst), R(src));}\n\tvoid xorps(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_XORPS,\t0x0F57, 0, RW(dst), R(src));}\n\tvoid xorps(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_XORPS,\t0x0F57, 0, RW(dst), R(src));}\n\n\t// SSE2\n\tvoid addpd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_ADDPD,\t0x0F58, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid addpd(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_ADDPD,\t0x0F58, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid addsd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_ADDSD,\t0x0F58, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n\tvoid addsd(const XmmReg& dst, const Mem64& src)\t\t{AppendInstr(I_ADDSD,\t0x0F58, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n\tvoid andpd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_ANDPD,\t0x0F54, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid andpd(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_ANDPD,\t0x0F54, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid andnpd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_ANDNPD,\t0x0F55, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid andnpd(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_ANDNPD,\t0x0F55, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid clflush(const Mem8& src) {AppendInstr(I_CLFLUSH, 0x0FAE, 0, Imm8(7), R(src));}\n\tvoid cmppd(const XmmReg& dst, const XmmReg& src, const Imm8& opd3)\t{AppendInstr(I_CMPPD, 0x0FC2, E_MANDATORY_PREFIX_66, RW(dst), R(src), opd3);}\n\tvoid cmppd(const XmmReg& dst, const Mem128& src, const Imm8& opd3)\t{AppendInstr(I_CMPPD, 0x0FC2, E_MANDATORY_PREFIX_66, RW(dst), R(src), opd3);}\n\tvoid cmpeqpd(const XmmReg& dst, const XmmReg& src)\t\t{cmppd(dst, src, 0);}\n\tvoid cmpeqpd(const XmmReg& dst, const Mem128& src)\t\t{cmppd(dst, src, 0);}\n\tvoid cmpltpd(const XmmReg& dst, const XmmReg& src)\t\t{cmppd(dst, src, 1);}\n\tvoid cmpltpd(const XmmReg& dst, const Mem128& src)\t\t{cmppd(dst, src, 1);}\n\tvoid cmplepd(const XmmReg& dst, const XmmReg& src)\t\t{cmppd(dst, src, 2);}\n\tvoid cmplepd(const XmmReg& dst, const Mem128& src)\t\t{cmppd(dst, src, 2);}\n\tvoid cmpunordpd(const XmmReg& dst, const XmmReg& src)\t{cmppd(dst, src, 3);}\n\tvoid cmpunordpd(const XmmReg& dst, const Mem128& src)\t{cmppd(dst, src, 3);}\n\tvoid cmpneqpd(const XmmReg& dst, const XmmReg& src)\t\t{cmppd(dst, src, 4);}\n\tvoid cmpneqpd(const XmmReg& dst, const Mem128& src)\t\t{cmppd(dst, src, 4);}\n\tvoid cmpnltpd(const XmmReg& dst, const XmmReg& src)\t\t{cmppd(dst, src, 5);}\n\tvoid cmpnltpd(const XmmReg& dst, const Mem128& src)\t\t{cmppd(dst, src, 5);}\n\tvoid cmpnlepd(const XmmReg& dst, const XmmReg& src)\t\t{cmppd(dst, src, 6);}\n\tvoid cmpnlepd(const XmmReg& dst, const Mem128& src)\t\t{cmppd(dst, src, 6);}\n\tvoid cmpordpd(const XmmReg& dst, const XmmReg& src)\t\t{cmppd(dst, src, 7);}\n\tvoid cmpordpd(const XmmReg& dst, const Mem128& src)\t\t{cmppd(dst, src, 7);}\n\tvoid cmpsd(const XmmReg& dst, const XmmReg& src, const Imm8& opd3)\t{AppendInstr(I_CMPSD, 0x0FC2, E_MANDATORY_PREFIX_F2, RW(dst), R(src), opd3);}\n\tvoid cmpsd(const XmmReg& dst, const Mem64& src, const Imm8& opd3)\t{AppendInstr(I_CMPSD, 0x0FC2, E_MANDATORY_PREFIX_F2, RW(dst), R(src), opd3);}\n\tvoid cmpeqsd(const XmmReg& dst, const XmmReg& src)\t\t{cmpsd(dst, src, 0);}\n\tvoid cmpeqsd(const XmmReg& dst, const Mem64& src)\t\t{cmpsd(dst, src, 0);}\n\tvoid cmpltsd(const XmmReg& dst, const XmmReg& src)\t\t{cmpsd(dst, src, 1);}\n\tvoid cmpltsd(const XmmReg& dst, const Mem64& src)\t\t{cmpsd(dst, src, 1);}\n\tvoid cmplesd(const XmmReg& dst, const XmmReg& src)\t\t{cmpsd(dst, src, 2);}\n\tvoid cmplesd(const XmmReg& dst, const Mem64& src)\t\t{cmpsd(dst, src, 2);}\n\tvoid cmpunordsd(const XmmReg& dst, const XmmReg& src)\t{cmpsd(dst, src, 3);}\n\tvoid cmpunordsd(const XmmReg& dst, const Mem64& src)\t{cmpsd(dst, src, 3);}\n\tvoid cmpneqsd(const XmmReg& dst, const XmmReg& src)\t\t{cmpsd(dst, src, 4);}\n\tvoid cmpneqsd(const XmmReg& dst, const Mem64& src)\t\t{cmpsd(dst, src, 4);}\n\tvoid cmpnltsd(const XmmReg& dst, const XmmReg& src)\t\t{cmpsd(dst, src, 5);}\n\tvoid cmpnltsd(const XmmReg& dst, const Mem64& src)\t\t{cmpsd(dst, src, 5);}\n\tvoid cmpnlesd(const XmmReg& dst, const XmmReg& src)\t\t{cmpsd(dst, src, 6);}\n\tvoid cmpnlesd(const XmmReg& dst, const Mem64& src)\t\t{cmpsd(dst, src, 6);}\n\tvoid cmpordsd(const XmmReg& dst, const XmmReg& src)\t\t{cmpsd(dst, src, 7);}\n\tvoid cmpordsd(const XmmReg& dst, const Mem64& src)\t\t{cmpsd(dst, src, 7);}\n\tvoid comisd(const XmmReg& src1, const XmmReg& src2)\t\t{AppendInstr(I_COMISD,\t0x0F2F, E_MANDATORY_PREFIX_66, R(src1), R(src2));}\n\tvoid comisd(const XmmReg& src1, const Mem64& src2)\t\t{AppendInstr(I_COMISD,\t0x0F2F, E_MANDATORY_PREFIX_66, R(src1), R(src2));}\n\tvoid cvtdq2pd(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_CVTDQ2PD, 0x0FE6, E_MANDATORY_PREFIX_F3, W(dst), R(src));}\n\tvoid cvtdq2pd(const XmmReg& dst, const Mem64& src)\t\t{AppendInstr(I_CVTDQ2PD, 0x0FE6, E_MANDATORY_PREFIX_F3, W(dst), R(src));}\n\tvoid cvtpd2dq(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_CVTPD2DQ, 0x0FE6, E_MANDATORY_PREFIX_F2, W(dst), R(src));}\n\tvoid cvtpd2dq(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_CVTPD2DQ, 0x0FE6, E_MANDATORY_PREFIX_F2, W(dst), R(src));}\n\tvoid cvtpd2pi(const MmxReg& dst, const XmmReg& src)\t\t{AppendInstr(I_CVTPD2PI, 0x0F2D, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid cvtpd2pi(const MmxReg& dst, const Mem128& src)\t\t{AppendInstr(I_CVTPD2PI, 0x0F2D, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid cvtpd2ps(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_CVTPD2PS, 0x0F5A, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid cvtpd2ps(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_CVTPD2PS, 0x0F5A, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid cvtpi2pd(const XmmReg& dst, const MmxReg& src)\t\t{AppendInstr(I_CVTPI2PD, 0x0F2A, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid cvtpi2pd(const XmmReg& dst, const Mem64& src)\t\t{AppendInstr(I_CVTPI2PD, 0x0F2A, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid cvtps2dq(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_CVTPS2DQ, 0x0F5B, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid cvtps2dq(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_CVTPS2DQ, 0x0F5B, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid cvtdq2ps(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_CVTDQ2PS, 0x0F5B, 0, W(dst), R(src));}\n\tvoid cvtdq2ps(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_CVTDQ2PS, 0x0F5B, 0, W(dst), R(src));}\n\tvoid cvtps2pd(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_CVTPS2PD, 0x0F5A, 0, W(dst), R(src));}\n\tvoid cvtps2pd(const XmmReg& dst, const Mem64& src)\t\t{AppendInstr(I_CVTPS2PD, 0x0F5A, 0, W(dst), R(src));}\n\tvoid cvtsd2si(const Reg32& dst, const XmmReg& src)\t\t{AppendInstr(I_CVTSD2SI, 0x0F2D, E_MANDATORY_PREFIX_F2, W(dst), R(src));}\n\tvoid cvtsd2si(const Reg32& dst, const Mem64& src)\t\t{AppendInstr(I_CVTSD2SI, 0x0F2D, E_MANDATORY_PREFIX_F2, W(dst), R(src));}\n#ifdef JITASM64\n\tvoid cvtsd2si(const Reg64& dst, const XmmReg& src)\t\t{AppendInstr(I_CVTSD2SI, 0x0F2D, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, W(dst), R(src));}\n\tvoid cvtsd2si(const Reg64& dst, const Mem64& src)\t\t{AppendInstr(I_CVTSD2SI, 0x0F2D, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, W(dst), R(src));}\n#endif\n\tvoid cvtsd2ss(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_CVTSD2SS, 0x0F5A, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n\tvoid cvtsd2ss(const XmmReg& dst, const Mem64& src)\t\t{AppendInstr(I_CVTSD2SS, 0x0F5A, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n\tvoid cvtsi2sd(const XmmReg& dst, const Reg32& src)\t\t{AppendInstr(I_CVTSI2SD, 0x0F2A, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n\tvoid cvtsi2sd(const XmmReg& dst, const Mem32& src)\t\t{AppendInstr(I_CVTSI2SD, 0x0F2A, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n#ifdef JITASM64\n\tvoid cvtsi2sd(const XmmReg& dst, const Reg64& src)\t\t{AppendInstr(I_CVTSI2SD, 0x0F2A, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid cvtsi2sd(const XmmReg& dst, const Mem64& src)\t\t{AppendInstr(I_CVTSI2SD, 0x0F2A, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, RW(dst), R(src));}\n#endif\n\tvoid cvtss2sd(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_CVTSS2SD,  0x0F5A, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}\n\tvoid cvtss2sd(const XmmReg& dst, const Mem32& src)\t\t{AppendInstr(I_CVTSS2SD,  0x0F5A, E_MANDATORY_PREFIX_F3, RW(dst), R(src));}\n\tvoid cvttpd2dq(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_CVTTPD2DQ, 0x0FE6, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid cvttpd2dq(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_CVTTPD2DQ, 0x0FE6, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid cvttpd2pi(const MmxReg& dst, const XmmReg& src)\t{AppendInstr(I_CVTTPD2PI, 0x0F2C, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid cvttpd2pi(const MmxReg& dst, const Mem128& src)\t{AppendInstr(I_CVTTPD2PI, 0x0F2C, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid cvttps2dq(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_CVTTPS2DQ, 0x0F5B, E_MANDATORY_PREFIX_F3, W(dst), R(src));}\n\tvoid cvttps2dq(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_CVTTPS2DQ, 0x0F5B, E_MANDATORY_PREFIX_F3, W(dst), R(src));}\n\tvoid cvttsd2si(const Reg32& dst, const XmmReg& src)\t\t{AppendInstr(I_CVTTSD2SI, 0x0F2C, E_MANDATORY_PREFIX_F2, W(dst), R(src));}\n\tvoid cvttsd2si(const Reg32& dst, const Mem64& src)\t\t{AppendInstr(I_CVTTSD2SI, 0x0F2C, E_MANDATORY_PREFIX_F2, W(dst), R(src));}\n#ifdef JITASM64\n\tvoid cvttsd2si(const Reg64& dst, const XmmReg& src)\t\t{AppendInstr(I_CVTTSD2SI, 0x0F2C, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, W(dst), R(src));}\n\tvoid cvttsd2si(const Reg64& dst, const Mem64& src)\t\t{AppendInstr(I_CVTTSD2SI, 0x0F2C, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, W(dst), R(src));}\n#endif\n\tvoid divpd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_DIVPD,\t0x0F5E, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid divpd(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_DIVPD,\t0x0F5E, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid divsd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_DIVSD,\t0x0F5E, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n\tvoid divsd(const XmmReg& dst, const Mem64& src)\t\t{AppendInstr(I_DIVSD,\t0x0F5E, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n\tvoid lfence()\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_LFENCE,\t0x0FAEE8, 0);}\n\tvoid maskmovdqu(const XmmReg& src, const XmmReg& mask, const Reg& dstptr)\t{AppendInstr(I_MASKMOVDQU, 0x0FF7, E_MANDATORY_PREFIX_66, R(src), R(mask), Dummy(R(dstptr), zdi));}\n\tvoid maxpd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MAXPD,\t0x0F5F, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid maxpd(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_MAXPD,\t0x0F5F, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid maxsd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MAXSD,\t0x0F5F, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n\tvoid maxsd(const XmmReg& dst, const Mem64& src)\t\t{AppendInstr(I_MAXSD,\t0x0F5F, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n\tvoid mfence()\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_MFENCE,\t0x0FAEF0, 0);}\n\tvoid minpd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MINPD,\t0x0F5D, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid minpd(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_MINPD,\t0x0F5D, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid minsd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MINSD,\t0x0F5D, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n\tvoid minsd(const XmmReg& dst, const Mem64& src)\t\t{AppendInstr(I_MINSD,\t0x0F5D, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n\tvoid movapd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MOVAPD,\t0x0F28, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid movapd(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_MOVAPD,\t0x0F28, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid movapd(const Mem128& dst, const XmmReg& src)\t{AppendInstr(I_MOVAPD,\t0x0F29, E_MANDATORY_PREFIX_66, R(src), W(dst));}\n\tvoid movd(const XmmReg& dst, const Reg32& src)\t\t{AppendInstr(I_MOVD,\t0x0F6E, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid movd(const XmmReg& dst, const Mem32& src)\t\t{AppendInstr(I_MOVD,\t0x0F6E, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid movd(const Reg32& dst, const XmmReg& src)\t\t{AppendInstr(I_MOVD,\t0x0F7E, E_MANDATORY_PREFIX_66, R(src), W(dst));}\n\tvoid movd(const Mem32& dst, const XmmReg& src)\t\t{AppendInstr(I_MOVD,\t0x0F7E, E_MANDATORY_PREFIX_66, R(src), W(dst));}\n#ifdef JITASM64\n\tvoid movd(const XmmReg& dst, const Reg64& src)\t\t{AppendInstr(I_MOVD,\t0x0F6E, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, W(dst), R(src));}\n\tvoid movd(const Reg64& dst, const XmmReg& src)\t\t{AppendInstr(I_MOVD,\t0x0F7E, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, R(src), W(dst));}\n#endif\n\tvoid movdqa(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MOVDQA,\t0x0F6F, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid movdqa(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_MOVDQA,\t0x0F6F, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid movdqa(const Mem128& dst, const XmmReg& src)\t{AppendInstr(I_MOVDQA,\t0x0F7F, E_MANDATORY_PREFIX_66, R(src), W(dst));}\n\tvoid movdqu(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MOVDQU,\t0x0F6F, E_MANDATORY_PREFIX_F3, W(dst), R(src));}\n\tvoid movdqu(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_MOVDQU,\t0x0F6F, E_MANDATORY_PREFIX_F3, W(dst), R(src));}\n\tvoid movdqu(const Mem128& dst, const XmmReg& src)\t{AppendInstr(I_MOVDQU,\t0x0F7F, E_MANDATORY_PREFIX_F3, R(src), W(dst));}\n\tvoid movdq2q(const MmxReg& dst, const XmmReg& src)\t{AppendInstr(I_MOVDQ2Q,\t0x0FD6, E_MANDATORY_PREFIX_F2, W(dst), R(src));}\n\tvoid movhpd(const XmmReg& dst, const Mem64& src)\t{AppendInstr(I_MOVHPD,\t0x0F16, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid movhpd(const Mem64& dst, const XmmReg& src)\t{AppendInstr(I_MOVHPD,\t0x0F17, E_MANDATORY_PREFIX_66, R(src), W(dst));}\n\tvoid movlpd(const XmmReg& dst, const Mem64& src)\t{AppendInstr(I_MOVLPD,\t0x0F12, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid movlpd(const Mem64& dst, const XmmReg& src)\t{AppendInstr(I_MOVLPD,\t0x0F13, E_MANDATORY_PREFIX_66, R(src), W(dst));}\n\tvoid movmskpd(const Reg32& dst, XmmReg& src)\t\t{AppendInstr(I_MOVMSKPD, 0x0F50, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n#ifdef JITASM64\n\tvoid movmskpd(const Reg64& dst, XmmReg& src)\t\t{AppendInstr(I_MOVMSKPD, 0x0F50, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, W(dst), R(src));}\n#endif\n\tvoid movntdq(const Mem128& dst, const XmmReg& src)\t{AppendInstr(I_MOVNTDQ,\t0x0FE7, E_MANDATORY_PREFIX_66, R(src), W(dst));}\n\tvoid movnti(const Mem32& dst, const Reg32& src)\t\t{AppendInstr(I_MOVNTI,\t0x0FC3, 0, R(src), W(dst));}\n#ifdef JITASM64\n\tvoid movnti(const Mem64& dst, const Reg64& src)\t\t{AppendInstr(I_MOVNTI,\t0x0FC3, E_REXW_PREFIX, R(src), W(dst));}\n#endif\n\tvoid movntpd(const Mem128& dst, const XmmReg& src)\t{AppendInstr(I_MOVNTPD,\t0x0F2B, E_MANDATORY_PREFIX_66, R(src), W(dst));}\n\tvoid movq(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_MOVQ,\t0x0F7E, E_MANDATORY_PREFIX_F3, W(dst), R(src));}\n\tvoid movq(const XmmReg& dst, const Mem64& src)\t\t{AppendInstr(I_MOVQ,\t0x0F7E, E_MANDATORY_PREFIX_F3, W(dst), R(src));}\n\tvoid movq(const Mem64& dst, const XmmReg& src)\t\t{AppendInstr(I_MOVQ,\t0x0FD6, E_MANDATORY_PREFIX_66, R(src), W(dst));}\n#ifdef JITASM64\n\tvoid movq(const XmmReg& dst, const Reg64& src)\t\t{movd(dst, src);}\n\tvoid movq(const Reg64& dst, const XmmReg& src)\t\t{movd(dst, src);}\n#endif\n\tvoid movq2dq(const XmmReg& dst, const MmxReg& src)\t{AppendInstr(I_MOVQ2DQ,\t0x0FD6, E_MANDATORY_PREFIX_F3, W(dst), R(src));}\n\tvoid movsd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MOVSD,\t0x0F10, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\t// 64~127bits are unchanged\n\tvoid movsd(const XmmReg& dst, const Mem64& src)\t\t{AppendInstr(I_MOVSD,\t0x0F10, E_MANDATORY_PREFIX_F2, W(dst), R(src));}\n\tvoid movsd(const Mem64& dst, const XmmReg& src)\t\t{AppendInstr(I_MOVSD,\t0x0F11, E_MANDATORY_PREFIX_F2, R(src), W(dst));}\n\tvoid movupd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MOVUPD,\t0x0F10, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid movupd(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_MOVUPD,\t0x0F10, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid movupd(const Mem128& dst, const XmmReg& src)\t{AppendInstr(I_MOVUPD,\t0x0F11, E_MANDATORY_PREFIX_66, R(src), W(dst));}\n\tvoid mulpd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MULPD,\t0x0F59, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid mulpd(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_MULPD,\t0x0F59, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid mulsd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MULSD,\t0x0F59, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n\tvoid mulsd(const XmmReg& dst, const Mem64& src)\t\t{AppendInstr(I_MULSD,\t0x0F59, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n\tvoid orpd(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_ORPD,\t0x0F56, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid orpd(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_ORPD,\t0x0F56, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid packsswb(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PACKSSWB, 0x0F63, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid packsswb(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PACKSSWB, 0x0F63, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid packssdw(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PACKSSDW, 0x0F6B, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid packssdw(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PACKSSDW, 0x0F6B, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid packuswb(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PACKUSWB, 0x0F67, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid packuswb(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PACKUSWB, 0x0F67, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid paddb(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PADDB,\t0x0FFC, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid paddb(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PADDB,\t0x0FFC, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid paddw(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PADDW,\t0x0FFD, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid paddw(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PADDW,\t0x0FFD, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid paddd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PADDD,\t0x0FFE, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid paddd(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PADDD,\t0x0FFE, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid paddq(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PADDQ,\t0x0FD4, 0, RW(dst), R(src));}\n\tvoid paddq(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PADDQ,\t0x0FD4, 0, RW(dst), R(src));}\n\tvoid paddq(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PADDQ,\t0x0FD4, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid paddq(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PADDQ,\t0x0FD4, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid paddsb(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PADDSB,\t0x0FEC, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid paddsb(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PADDSB,\t0x0FEC, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid paddsw(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PADDSW,\t0x0FED, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid paddsw(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PADDSW,\t0x0FED, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid paddusb(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PADDUSB,\t0x0FDC, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid paddusb(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PADDUSB,\t0x0FDC, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid paddusw(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PADDUSW,\t0x0FDD, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid paddusw(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PADDUSW,\t0x0FDD, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pand(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_PAND,\t\t0x0FDB, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pand(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_PAND,\t\t0x0FDB, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pandn(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PANDN,\t0x0FDF, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pandn(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PANDN,\t0x0FDF, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pause()\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_PAUSE,\t0xF390,\t0);}\n\tvoid pavgb(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PAVGB,\t0x0FE0, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pavgb(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PAVGB,\t0x0FE0, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pavgw(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PAVGW,\t0x0FE3, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pavgw(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PAVGW,\t0x0FE3, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pcmpeqb(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PCMPEQB,\t0x0F74, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pcmpeqb(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PCMPEQB,\t0x0F74, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pcmpeqw(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PCMPEQW,\t0x0F75, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pcmpeqw(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PCMPEQW,\t0x0F75, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pcmpeqd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PCMPEQD,\t0x0F76, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pcmpeqd(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PCMPEQD,\t0x0F76, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pcmpgtb(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PCMPGTB,\t0x0F64, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pcmpgtb(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PCMPGTB,\t0x0F64, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pcmpgtw(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PCMPGTW,\t0x0F65, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pcmpgtw(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PCMPGTW,\t0x0F65, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pcmpgtd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PCMPGTD,\t0x0F66, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pcmpgtd(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PCMPGTD,\t0x0F66, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pextrw(const Reg32& dst, const XmmReg& src, const Imm8& i)\t{AppendInstr(I_PEXTRW, 0x0FC5, E_MANDATORY_PREFIX_66, W(dst), R(src), i);}\n#ifdef JITASM64\n\tvoid pextrw(const Reg64& dst, const XmmReg& src, const Imm8& i)\t{AppendInstr(I_PEXTRW, 0x0FC5, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, W(dst), R(src), i);}\n#endif\n\tvoid pinsrw(const XmmReg& dst, const Reg32& src, const Imm8& i)\t{AppendInstr(I_PINSRW, 0x0FC4, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);}\n\tvoid pinsrw(const XmmReg& dst, const Mem16& src, const Imm8& i)\t{AppendInstr(I_PINSRW, 0x0FC4, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);}\n#ifdef JITASM64\n\tvoid pinsrw(const XmmReg& dst, const Reg64& src, const Imm8& i)\t{AppendInstr(I_PINSRW, 0x0FC4, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, RW(dst), R(src), i);}\n#endif\n\tvoid pmaddwd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PMADDWD,\t0x0FF5, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmaddwd(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PMADDWD,\t0x0FF5, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmaxsw(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PMAXSW,\t0x0FEE, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmaxsw(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PMAXSW,\t0x0FEE, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmaxub(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PMAXUB,\t0x0FDE, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmaxub(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PMAXUB,\t0x0FDE, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pminsw(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PMINSW,\t0x0FEA, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pminsw(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PMINSW,\t0x0FEA, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pminub(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PMINUB,\t0x0FDA, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pminub(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PMINUB,\t0x0FDA, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmovmskb(const Reg32& dst, const XmmReg& src)\t{AppendInstr(I_PMOVMSKB, 0x0FD7, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n#ifdef JITASM64\n\tvoid pmovmskb(const Reg64& dst, const XmmReg& src)\t{AppendInstr(I_PMOVMSKB, 0x0FD7, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, W(dst), R(src));}\n#endif\n\tvoid pmulhuw(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PMULHUW,\t0x0FE4, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmulhuw(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PMULHUW,\t0x0FE4, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmulhw(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PMULHW,\t0x0FE5, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmulhw(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PMULHW,\t0x0FE5, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmullw(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PMULLW,\t0x0FD5, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmullw(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PMULLW,\t0x0FD5, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmuludq(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PMULUDQ,\t0x0FF4, 0, RW(dst), R(src));}\n\tvoid pmuludq(const MmxReg& dst, const Mem64& src)\t{AppendInstr(I_PMULUDQ,\t0x0FF4, 0, RW(dst), R(src));}\n\tvoid pmuludq(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PMULUDQ,\t0x0FF4, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmuludq(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PMULUDQ,\t0x0FF4, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid por(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_POR,\t\t0x0FEB, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid por(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_POR,\t\t0x0FEB, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid psadbw(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PSADBW,\t0x0FF6, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid psadbw(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PSADBW,\t0x0FF6, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pshufd(const XmmReg& dst, const XmmReg& src, const Imm8& order)\t{AppendInstr(I_PSHUFD,\t0x0F70, E_MANDATORY_PREFIX_66, W(dst), R(src), order);}\n\tvoid pshufd(const XmmReg& dst, const Mem128& src, const Imm8& order)\t{AppendInstr(I_PSHUFD,\t0x0F70, E_MANDATORY_PREFIX_66, W(dst), R(src), order);}\n\tvoid pshufhw(const XmmReg& dst, const XmmReg& src, const Imm8& order)\t{AppendInstr(I_PSHUFHW,\t0x0F70, E_MANDATORY_PREFIX_F3, W(dst), R(src), order);}\n\tvoid pshufhw(const XmmReg& dst, const Mem128& src, const Imm8& order)\t{AppendInstr(I_PSHUFHW,\t0x0F70, E_MANDATORY_PREFIX_F3, W(dst), R(src), order);}\n\tvoid pshuflw(const XmmReg& dst, const XmmReg& src, const Imm8& order)\t{AppendInstr(I_PSHUFLW,\t0x0F70, E_MANDATORY_PREFIX_F2, W(dst), R(src), order);}\n\tvoid pshuflw(const XmmReg& dst, const Mem128& src, const Imm8& order)\t{AppendInstr(I_PSHUFLW,\t0x0F70, E_MANDATORY_PREFIX_F2, W(dst), R(src), order);}\n\tvoid psllw(const XmmReg& dst, const XmmReg& count)\t{AppendInstr(I_PSLLW,\t0x0FF1, E_MANDATORY_PREFIX_66, RW(dst), R(count));}\n\tvoid psllw(const XmmReg& dst, const Mem128& count)\t{AppendInstr(I_PSLLW,\t0x0FF1, E_MANDATORY_PREFIX_66, RW(dst), R(count));}\n\tvoid psllw(const XmmReg& dst, const Imm8& count)\t{AppendInstr(I_PSLLW,\t0x0F71, E_MANDATORY_PREFIX_66, Imm8(6), RW(dst), count);}\n\tvoid pslld(const XmmReg& dst, const XmmReg& count)\t{AppendInstr(I_PSLLD,\t0x0FF2, E_MANDATORY_PREFIX_66, RW(dst), R(count));}\n\tvoid pslld(const XmmReg& dst, const Mem128& count)\t{AppendInstr(I_PSLLD,\t0x0FF2, E_MANDATORY_PREFIX_66, RW(dst), R(count));}\n\tvoid pslld(const XmmReg& dst, const Imm8& count)\t{AppendInstr(I_PSLLD,\t0x0F72, E_MANDATORY_PREFIX_66, Imm8(6), RW(dst), count);}\n\tvoid psllq(const XmmReg& dst, const XmmReg& count)\t{AppendInstr(I_PSLLQ,\t0x0FF3, E_MANDATORY_PREFIX_66, RW(dst), R(count));}\n\tvoid psllq(const XmmReg& dst, const Mem128& count)\t{AppendInstr(I_PSLLQ,\t0x0FF3, E_MANDATORY_PREFIX_66, RW(dst), R(count));}\n\tvoid psllq(const XmmReg& dst, const Imm8& count)\t{AppendInstr(I_PSLLQ,\t0x0F73, E_MANDATORY_PREFIX_66, Imm8(6), RW(dst), count);}\n\tvoid pslldq(const XmmReg& dst, const Imm8& count)\t{AppendInstr(I_PSLLDQ,\t0x0F73, E_MANDATORY_PREFIX_66, Imm8(7), RW(dst), count);}\n\tvoid psraw(const XmmReg& dst, const XmmReg& count)\t{AppendInstr(I_PSRAW,\t0x0FE1, E_MANDATORY_PREFIX_66, RW(dst), R(count));}\n\tvoid psraw(const XmmReg& dst, const Mem128& count)\t{AppendInstr(I_PSRAW,\t0x0FE1, E_MANDATORY_PREFIX_66, RW(dst), R(count));}\n\tvoid psraw(const XmmReg& dst, const Imm8& count)\t{AppendInstr(I_PSRAW,\t0x0F71, E_MANDATORY_PREFIX_66, Imm8(4), RW(dst), count);}\n\tvoid psrad(const XmmReg& dst, const XmmReg& count)\t{AppendInstr(I_PSRAD,\t0x0FE2, E_MANDATORY_PREFIX_66, RW(dst), R(count));}\n\tvoid psrad(const XmmReg& dst, const Mem128& count)\t{AppendInstr(I_PSRAD,\t0x0FE2, E_MANDATORY_PREFIX_66, RW(dst), R(count));}\n\tvoid psrad(const XmmReg& dst, const Imm8& count)\t{AppendInstr(I_PSRAD,\t0x0F72, E_MANDATORY_PREFIX_66, Imm8(4), RW(dst), count);}\n\tvoid psrlw(const XmmReg& dst, const XmmReg& count)\t{AppendInstr(I_PSRLW,\t0x0FD1, E_MANDATORY_PREFIX_66, RW(dst), R(count));}\n\tvoid psrlw(const XmmReg& dst, const Mem128& count)\t{AppendInstr(I_PSRLW,\t0x0FD1, E_MANDATORY_PREFIX_66, RW(dst), R(count));}\n\tvoid psrlw(const XmmReg& dst, const Imm8& count)\t{AppendInstr(I_PSRLW,\t0x0F71, E_MANDATORY_PREFIX_66, Imm8(2), RW(dst), count);}\n\tvoid psrld(const XmmReg& dst, const XmmReg& count)\t{AppendInstr(I_PSRLD,\t0x0FD2, E_MANDATORY_PREFIX_66, RW(dst), R(count));}\n\tvoid psrld(const XmmReg& dst, const Mem128& count)\t{AppendInstr(I_PSRLD,\t0x0FD2, E_MANDATORY_PREFIX_66, RW(dst), R(count));}\n\tvoid psrld(const XmmReg& dst, const Imm8& count)\t{AppendInstr(I_PSRLD,\t0x0F72, E_MANDATORY_PREFIX_66, Imm8(2), RW(dst), count);}\n\tvoid psrlq(const XmmReg& dst, const XmmReg& count)\t{AppendInstr(I_PSRLQ,\t0x0FD3, E_MANDATORY_PREFIX_66, RW(dst), R(count));}\n\tvoid psrlq(const XmmReg& dst, const Mem128& count)\t{AppendInstr(I_PSRLQ,\t0x0FD3, E_MANDATORY_PREFIX_66, RW(dst), R(count));}\n\tvoid psrlq(const XmmReg& dst, const Imm8& count)\t{AppendInstr(I_PSRLQ,\t0x0F73, E_MANDATORY_PREFIX_66, Imm8(2), RW(dst), count);}\n\tvoid psrldq(const XmmReg& dst, const Imm8& count)\t{AppendInstr(I_PSRLDQ,\t0x0F73, E_MANDATORY_PREFIX_66, Imm8(3), RW(dst), count);}\n\tvoid psubb(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PSUBB,\t0x0FF8, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid psubb(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PSUBB,\t0x0FF8, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid psubw(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PSUBW,\t0x0FF9, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid psubw(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PSUBW,\t0x0FF9, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid psubd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PSUBD,\t0x0FFA, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid psubd(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PSUBD,\t0x0FFA, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid psubq(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PSUBQ,\t0x0FFB, 0, RW(dst), R(src));}\n\tvoid psubq(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PSUBQ,\t0x0FFB, 0, RW(dst), R(src));}\n\tvoid psubq(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PSUBQ,\t0x0FFB, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid psubq(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PSUBQ,\t0x0FFB, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid psubsb(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PSUBSB,\t0x0FE8, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid psubsb(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PSUBSB,\t0x0FE8, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid psubsw(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PSUBSW,\t0x0FE9, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid psubsw(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PSUBSW,\t0x0FE9, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid psubusb(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PSUBUSB,\t0x0FD8, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid psubusb(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PSUBUSB,\t0x0FD8, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid psubusw(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PSUBUSW,\t0x0FD9, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid psubusw(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PSUBUSW,\t0x0FD9, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid punpckhbw(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PUNPCKHBW,\t0x0F68, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid punpckhbw(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PUNPCKHBW,\t0x0F68, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid punpckhwd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PUNPCKHWD,\t0x0F69, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid punpckhwd(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PUNPCKHWD,\t0x0F69, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid punpckhdq(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PUNPCKHDQ,\t0x0F6A, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid punpckhdq(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PUNPCKHDQ,\t0x0F6A, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid punpckhqdq(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PUNPCKHQDQ,\t0x0F6D, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid punpckhqdq(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PUNPCKHQDQ,\t0x0F6D, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid punpcklbw(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PUNPCKLBW,\t0x0F60, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid punpcklbw(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PUNPCKLBW,\t0x0F60, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid punpcklwd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PUNPCKLWD,\t0x0F61, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid punpcklwd(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PUNPCKLWD,\t0x0F61, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid punpckldq(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PUNPCKLDQ,\t0x0F62, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid punpckldq(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PUNPCKLDQ,\t0x0F62, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid punpcklqdq(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PUNPCKLQDQ,\t0x0F6C, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid punpcklqdq(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PUNPCKLQDQ,\t0x0F6C, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pxor(const XmmReg& dst, const XmmReg& src)\t\t\t{AppendInstr(I_PXOR,\t\t0x0FEF, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pxor(const XmmReg& dst, const Mem128& src)\t\t\t{AppendInstr(I_PXOR,\t\t0x0FEF, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid shufpd(const XmmReg& dst, const XmmReg& src, const Imm8& sel)\t{AppendInstr(I_SHUFPD, 0x0FC6, E_MANDATORY_PREFIX_66, RW(dst), R(src), sel);}\n\tvoid shufpd(const XmmReg& dst, const Mem128& src, const Imm8& sel)\t{AppendInstr(I_SHUFPD, 0x0FC6, E_MANDATORY_PREFIX_66, RW(dst), R(src), sel);}\n\tvoid sqrtpd(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_SQRTPD,\t0x0F51, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid sqrtpd(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_SQRTPD,\t0x0F51, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid sqrtsd(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_SQRTSD,\t0x0F51, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n\tvoid sqrtsd(const XmmReg& dst, const Mem64& src)\t\t{AppendInstr(I_SQRTSD,\t0x0F51, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n\tvoid subpd(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_SUBPD,\t0x0F5C, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid subpd(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_SUBPD,\t0x0F5C, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid subsd(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_SUBSD,\t0x0F5C, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n\tvoid subsd(const XmmReg& dst, const Mem64& src)\t\t\t{AppendInstr(I_SUBSD,\t0x0F5C, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n\tvoid ucomisd(const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_UCOMISD,\t0x0F2E, E_MANDATORY_PREFIX_66, R(src1), R(src2));}\n\tvoid ucomisd(const XmmReg& src1, const Mem64& src2)\t\t{AppendInstr(I_UCOMISD,\t0x0F2E, E_MANDATORY_PREFIX_66, R(src1), R(src2));}\n\tvoid unpckhpd(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_UNPCKHPD, 0x0F15, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid unpckhpd(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_UNPCKHPD, 0x0F15, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid unpcklpd(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_UNPCKLPD, 0x0F14, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid unpcklpd(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_UNPCKLPD, 0x0F14, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid xorpd(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_XORPD,\t0x0F57, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid xorpd(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_XORPD,\t0x0F57, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\n\t// SSE3\n\tvoid addsubps(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_ADDSUBPS, 0x0FD0, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n\tvoid addsubps(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_ADDSUBPS, 0x0FD0, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n\tvoid addsubpd(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_ADDSUBPD, 0x0FD0, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid addsubpd(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_ADDSUBPD, 0x0FD0, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid haddps(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_HADDPS,\t 0x0F7C, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n\tvoid haddps(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_HADDPS,\t 0x0F7C, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n\tvoid haddpd(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_HADDPD,\t 0x0F7C, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid haddpd(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_HADDPD,\t 0x0F7C, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid hsubps(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_HSUBPS,\t 0x0F7D, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n\tvoid hsubps(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_HSUBPS,\t 0x0F7D, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n\tvoid hsubpd(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_HSUBPD,\t 0x0F7D, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid hsubpd(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_HSUBPD,\t 0x0F7D, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid lddqu(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_LDDQU,\t 0x0FF0, E_MANDATORY_PREFIX_F2, W(dst), R(src));}\n\tvoid monitor()\t\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_MONITOR,\t 0x0F01C8, 0);}\n\tvoid movddup(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_MOVDDUP,\t 0x0F12, E_MANDATORY_PREFIX_F2, W(dst), R(src));}\n\tvoid movddup(const XmmReg& dst, const Mem64& src)\t\t{AppendInstr(I_MOVDDUP,\t 0x0F12, E_MANDATORY_PREFIX_F2, W(dst), R(src));}\n\tvoid movshdup(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_MOVSHDUP, 0x0F16, E_MANDATORY_PREFIX_F3, W(dst), R(src));}\n\tvoid movshdup(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_MOVSHDUP, 0x0F16, E_MANDATORY_PREFIX_F3, W(dst), R(src));}\n\tvoid movsldup(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_MOVSLDUP, 0x0F12, E_MANDATORY_PREFIX_F3, W(dst), R(src));}\n\tvoid movsldup(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_MOVSLDUP, 0x0F12, E_MANDATORY_PREFIX_F3, W(dst), R(src));}\n\tvoid mwait()\t\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_MWAIT,\t 0x0F01C9, 0);}\n\n\t// SSSE3\n\tvoid pabsb(const MmxReg& dst, const MmxReg& src)\t\t{AppendInstr(I_PABSB,\t0x0F381C, 0, RW(dst), R(src));}\n\tvoid pabsb(const MmxReg& dst, const Mem64& src)\t\t\t{AppendInstr(I_PABSB,\t0x0F381C, 0, RW(dst), R(src));}\n\tvoid pabsb(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_PABSB,\t0x0F381C, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pabsb(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_PABSB,\t0x0F381C, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pabsw(const MmxReg& dst, const MmxReg& src)\t\t{AppendInstr(I_PABSW,\t0x0F381D, 0, RW(dst), R(src));}\n\tvoid pabsw(const MmxReg& dst, const Mem64& src)\t\t\t{AppendInstr(I_PABSW,\t0x0F381D, 0, RW(dst), R(src));}\n\tvoid pabsw(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_PABSW,\t0x0F381D, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pabsw(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_PABSW,\t0x0F381D, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pabsd(const MmxReg& dst, const MmxReg& src)\t\t{AppendInstr(I_PABSD,\t0x0F381E, 0, RW(dst), R(src));}\n\tvoid pabsd(const MmxReg& dst, const Mem64& src)\t\t\t{AppendInstr(I_PABSD,\t0x0F381E, 0, RW(dst), R(src));}\n\tvoid pabsd(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_PABSD,\t0x0F381E, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pabsd(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_PABSD,\t0x0F381E, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid palignr(const MmxReg& dst, const MmxReg& src, const Imm8& n)\t{AppendInstr(I_PALIGNR, 0x0F3A0F, 0, RW(dst), R(src), n);}\n\tvoid palignr(const MmxReg& dst, const Mem64& src, const Imm8& n)\t{AppendInstr(I_PALIGNR, 0x0F3A0F, 0, RW(dst), R(src), n);}\n\tvoid palignr(const XmmReg& dst, const XmmReg& src, const Imm8& n)\t{AppendInstr(I_PALIGNR, 0x0F3A0F, E_MANDATORY_PREFIX_66, RW(dst), R(src), n);}\n\tvoid palignr(const XmmReg& dst, const Mem128& src, const Imm8& n)\t{AppendInstr(I_PALIGNR, 0x0F3A0F, E_MANDATORY_PREFIX_66, RW(dst), R(src), n);}\n\tvoid phaddw(const MmxReg& dst, const MmxReg& src)\t\t{AppendInstr(I_PHADDW,\t0x0F3801, 0, RW(dst), R(src));}\n\tvoid phaddw(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PHADDW,\t0x0F3801, 0, RW(dst), R(src));}\n\tvoid phaddw(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_PHADDW,\t0x0F3801, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid phaddw(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_PHADDW,\t0x0F3801, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid phaddd(const MmxReg& dst, const MmxReg& src)\t\t{AppendInstr(I_PHADDD,\t0x0F3802, 0, RW(dst), R(src));}\n\tvoid phaddd(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PHADDD,\t0x0F3802, 0, RW(dst), R(src));}\n\tvoid phaddd(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_PHADDD,\t0x0F3802, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid phaddd(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_PHADDD,\t0x0F3802, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid phaddsw(const MmxReg& dst, const MmxReg& src)\t\t{AppendInstr(I_PHADDSW,\t0x0F3803, 0, RW(dst), R(src));}\n\tvoid phaddsw(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PHADDSW,\t0x0F3803, 0, RW(dst), R(src));}\n\tvoid phaddsw(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_PHADDSW,\t0x0F3803, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid phaddsw(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_PHADDSW,\t0x0F3803, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid phsubw(const MmxReg& dst, const MmxReg& src)\t\t{AppendInstr(I_PHSUBW,\t0x0F3805, 0, RW(dst), R(src));}\n\tvoid phsubw(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PHSUBW,\t0x0F3805, 0, RW(dst), R(src));}\n\tvoid phsubw(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_PHSUBW,\t0x0F3805, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid phsubw(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_PHSUBW,\t0x0F3805, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid phsubd(const MmxReg& dst, const MmxReg& src)\t\t{AppendInstr(I_PHSUBD,\t0x0F3806, 0, RW(dst), R(src));}\n\tvoid phsubd(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PHSUBD,\t0x0F3806, 0, RW(dst), R(src));}\n\tvoid phsubd(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_PHSUBD,\t0x0F3806, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid phsubd(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_PHSUBD,\t0x0F3806, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid phsubsw(const MmxReg& dst, const MmxReg& src)\t\t{AppendInstr(I_PHSUBSW,\t0x0F3807, 0, RW(dst), R(src));}\n\tvoid phsubsw(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PHSUBSW,\t0x0F3807, 0, RW(dst), R(src));}\n\tvoid phsubsw(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_PHSUBSW,\t0x0F3807, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid phsubsw(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_PHSUBSW,\t0x0F3807, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmaddubsw(const MmxReg& dst, const MmxReg& src)\t{AppendInstr(I_PMADDUBSW,0x0F3804, 0, RW(dst), R(src));}\n\tvoid pmaddubsw(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PMADDUBSW,0x0F3804, 0, RW(dst), R(src));}\n\tvoid pmaddubsw(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PMADDUBSW,0x0F3804, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmaddubsw(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PMADDUBSW,0x0F3804, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmulhrsw(const MmxReg& dst, const MmxReg& src)\t\t{AppendInstr(I_PMULHRSW,\t0x0F380B, 0, RW(dst), R(src));}\n\tvoid pmulhrsw(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PMULHRSW,\t0x0F380B, 0, RW(dst), R(src));}\n\tvoid pmulhrsw(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_PMULHRSW,\t0x0F380B, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmulhrsw(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_PMULHRSW,\t0x0F380B, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pshufb(const MmxReg& dst, const MmxReg& src)\t\t{AppendInstr(I_PSHUFB,\t0x0F3800, 0, RW(dst), R(src));}\n\tvoid pshufb(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PSHUFB,\t0x0F3800, 0, RW(dst), R(src));}\n\tvoid pshufb(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_PSHUFB,\t0x0F3800, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pshufb(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_PSHUFB,\t0x0F3800, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid psignb(const MmxReg& dst, const MmxReg& src)\t\t{AppendInstr(I_PSIGNB,\t0x0F3808, 0, RW(dst), R(src));}\n\tvoid psignb(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PSIGNB,\t0x0F3808, 0, RW(dst), R(src));}\n\tvoid psignb(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_PSIGNB,\t0x0F3808, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid psignb(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_PSIGNB,\t0x0F3808, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid psignw(const MmxReg& dst, const MmxReg& src)\t\t{AppendInstr(I_PSIGNW,\t0x0F3809, 0, RW(dst), R(src));}\n\tvoid psignw(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PSIGNW,\t0x0F3809, 0, RW(dst), R(src));}\n\tvoid psignw(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_PSIGNW,\t0x0F3809, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid psignw(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_PSIGNW,\t0x0F3809, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid psignd(const MmxReg& dst, const MmxReg& src)\t\t{AppendInstr(I_PSIGND,\t0x0F380A, 0, RW(dst), R(src));}\n\tvoid psignd(const MmxReg& dst, const Mem64& src)\t\t{AppendInstr(I_PSIGND,\t0x0F380A, 0, RW(dst), R(src));}\n\tvoid psignd(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_PSIGND,\t0x0F380A, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid psignd(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_PSIGND,\t0x0F380A, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\n\t// SSE4.1\n\tvoid blendps(const XmmReg& dst, const XmmReg& src, const Imm8& mask)\t{AppendInstr(I_BLENDPS,\t 0x0F3A0C, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);}\n\tvoid blendps(const XmmReg& dst, const Mem128& src, const Imm8& mask)\t{AppendInstr(I_BLENDPS,\t 0x0F3A0C, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);}\n\tvoid blendpd(const XmmReg& dst, const XmmReg& src, const Imm8& mask)\t{AppendInstr(I_BLENDPD,\t 0x0F3A0D, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);}\n\tvoid blendpd(const XmmReg& dst, const Mem128& src, const Imm8& mask)\t{AppendInstr(I_BLENDPD,\t 0x0F3A0D, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);}\n\tvoid blendvps(const XmmReg& dst, const XmmReg& src, const XmmReg& mask)\t{AppendInstr(I_BLENDVPS, 0x0F3814, E_MANDATORY_PREFIX_66, RW(dst), R(src), Dummy(R(mask), xmm0));}\n\tvoid blendvps(const XmmReg& dst, const Mem128& src, const XmmReg& mask)\t{AppendInstr(I_BLENDVPS, 0x0F3814, E_MANDATORY_PREFIX_66, RW(dst), R(src), Dummy(R(mask), xmm0));}\n\tvoid blendvpd(const XmmReg& dst, const XmmReg& src, const XmmReg& mask)\t{AppendInstr(I_BLENDVPD, 0x0F3815, E_MANDATORY_PREFIX_66, RW(dst), R(src), Dummy(R(mask), xmm0));}\n\tvoid blendvpd(const XmmReg& dst, const Mem128& src, const XmmReg& mask)\t{AppendInstr(I_BLENDVPD, 0x0F3815, E_MANDATORY_PREFIX_66, RW(dst), R(src), Dummy(R(mask), xmm0));}\n\tvoid dpps(const XmmReg& dst, const XmmReg& src, const Imm8& mask)\t\t{AppendInstr(I_DPPS,\t 0x0F3A40, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);}\n\tvoid dpps(const XmmReg& dst, const Mem128& src, const Imm8& mask)\t\t{AppendInstr(I_DPPS,\t 0x0F3A40, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);}\n\tvoid dppd(const XmmReg& dst, const XmmReg& src, const Imm8& mask)\t\t{AppendInstr(I_DPPD,\t 0x0F3A41, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);}\n\tvoid dppd(const XmmReg& dst, const Mem128& src, const Imm8& mask)\t\t{AppendInstr(I_DPPD,\t 0x0F3A41, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);}\n\tvoid extractps(const Reg32& dst, const XmmReg& src, const Imm8& i)\t\t{AppendInstr(I_EXTRACTPS,0x0F3A17, E_MANDATORY_PREFIX_66, R(src), W(dst), i);}\n\tvoid extractps(const Mem32& dst, const XmmReg& src, const Imm8& i)\t\t{AppendInstr(I_EXTRACTPS,0x0F3A17, E_MANDATORY_PREFIX_66, R(src), W(dst), i);}\n#ifdef JITASM64\n\tvoid extractps(const Reg64& dst, const XmmReg& src, const Imm8& i)\t\t{AppendInstr(I_EXTRACTPS,0x0F3A17, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, R(src), W(dst), i);}\n#endif\n\tvoid insertps(const XmmReg& dst, const XmmReg& src, const Imm8& i)\t\t{AppendInstr(I_INSERTPS, 0x0F3A21, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);}\n\tvoid insertps(const XmmReg& dst, const Mem32& src, const Imm8& i)\t\t{AppendInstr(I_INSERTPS, 0x0F3A21, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);}\n\tvoid movntdqa(const XmmReg& dst, const Mem128& src)\t\t\t\t\t\t{AppendInstr(I_MOVNTDQA, 0x0F382A, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid mpsadbw(const XmmReg& dst, const XmmReg& src, const Imm8& offsets)\t{AppendInstr(I_MPSADBW,\t 0x0F3A42, E_MANDATORY_PREFIX_66, RW(dst), R(src), offsets);}\n\tvoid mpsadbw(const XmmReg& dst, const Mem128& src, const Imm8& offsets)\t{AppendInstr(I_MPSADBW,\t 0x0F3A42, E_MANDATORY_PREFIX_66, RW(dst), R(src), offsets);}\n\tvoid packusdw(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PACKUSDW, 0x0F382B, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid packusdw(const XmmReg& dst, const Mem128& src)\t\t\t\t\t\t{AppendInstr(I_PACKUSDW, 0x0F382B, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pblendvb(const XmmReg& dst, const XmmReg& src, const XmmReg& mask)\t{AppendInstr(I_PBLENDVB, 0x0F3810, E_MANDATORY_PREFIX_66, RW(dst), R(src), Dummy(R(mask), xmm0));}\n\tvoid pblendvb(const XmmReg& dst, const Mem128& src, const XmmReg& mask)\t{AppendInstr(I_PBLENDVB, 0x0F3810, E_MANDATORY_PREFIX_66, RW(dst), R(src), Dummy(R(mask), xmm0));}\n\tvoid pblendw(const XmmReg& dst, const XmmReg& src, const Imm8& mask)\t{AppendInstr(I_PBLENDW,\t 0x0F3A0E, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);}\n\tvoid pblendw(const XmmReg& dst, const Mem128& src, const Imm8& mask)\t{AppendInstr(I_PBLENDW,\t 0x0F3A0E, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);}\n\tvoid pcmpeqq(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PCMPEQQ,\t 0x0F3829, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pcmpeqq(const XmmReg& dst, const Mem128& src)\t\t\t\t\t\t{AppendInstr(I_PCMPEQQ,\t 0x0F3829, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pextrb(const Reg32& dst, const XmmReg& src, const Imm8& i)\t\t\t{AppendInstr(I_PEXTRB,\t 0x0F3A14, E_MANDATORY_PREFIX_66, R(src), W(dst), i);}\n\tvoid pextrb(const Mem8& dst, const XmmReg& src, const Imm8& i)\t\t\t{AppendInstr(I_PEXTRB,\t 0x0F3A14, E_MANDATORY_PREFIX_66, R(src), W(dst), i);}\n\tvoid pextrw(const Mem16& dst, const XmmReg& src, const Imm8& i)\t\t\t{AppendInstr(I_PEXTRW,\t 0x0F3A15, E_MANDATORY_PREFIX_66, R(src), W(dst), i);}\n\tvoid pextrd(const Reg32& dst, const XmmReg& src, const Imm8& i)\t\t\t{AppendInstr(I_PEXTRD,\t 0x0F3A16, E_MANDATORY_PREFIX_66, R(src), W(dst), i);}\n\tvoid pextrd(const Mem32& dst, const XmmReg& src, const Imm8& i)\t\t\t{AppendInstr(I_PEXTRD,\t 0x0F3A16, E_MANDATORY_PREFIX_66, R(src), W(dst), i);}\n#ifdef JITASM64\n\tvoid pextrb(const Reg64& dst, const XmmReg& src, const Imm8& i)\t\t\t{AppendInstr(I_PEXTRB,\t0x0F3A14, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, R(src), W(dst), i);}\n\tvoid pextrd(const Reg64& dst, const XmmReg& src, const Imm8& i)\t\t\t{AppendInstr(I_PEXTRD,\t0x0F3A16, E_MANDATORY_PREFIX_66, R(src), W(dst), i);}\n\tvoid pextrq(const Reg64& dst, const XmmReg& src, const Imm8& i)\t\t\t{AppendInstr(I_PEXTRQ,\t0x0F3A16, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, R(src), W(dst), i);}\n\tvoid pextrq(const Mem64& dst, const XmmReg& src, const Imm8& i)\t\t\t{AppendInstr(I_PEXTRQ,\t0x0F3A16, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, R(src), W(dst), i);}\n#endif\n\tvoid phminposuw(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t{AppendInstr(I_PHMINPOSUW, 0x0F3841, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid phminposuw(const XmmReg& dst, const Mem128& src)\t\t\t\t\t{AppendInstr(I_PHMINPOSUW, 0x0F3841, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pinsrb(const XmmReg& dst, const Reg32& src, const Imm8& i)\t\t\t{AppendInstr(I_PINSRB, 0x0F3A20, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);}\n\tvoid pinsrb(const XmmReg& dst, const Mem8& src, const Imm8& i)\t\t\t{AppendInstr(I_PINSRB, 0x0F3A20, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);}\n\tvoid pinsrd(const XmmReg& dst, const Reg32& src, const Imm8& i)\t\t\t{AppendInstr(I_PINSRD, 0x0F3A22, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);}\n\tvoid pinsrd(const XmmReg& dst, const Mem32& src, const Imm8& i)\t\t\t{AppendInstr(I_PINSRD, 0x0F3A22, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);}\n#ifdef JITASM64\n\tvoid pinsrb(const XmmReg& dst, const Reg64& src, const Imm8& i)\t\t\t{AppendInstr(I_PINSRB, 0x0F3A20, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);}\n\tvoid pinsrd(const XmmReg& dst, const Reg64& src, const Imm8& i)\t\t\t{AppendInstr(I_PINSRD, 0x0F3A22, E_MANDATORY_PREFIX_66, RW(dst), R(src), i);}\n\tvoid pinsrq(const XmmReg& dst, const Reg64& src, const Imm8& i)\t\t\t{AppendInstr(I_PINSRQ, 0x0F3A22, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, RW(dst), R(src), i);}\n\tvoid pinsrq(const XmmReg& dst, const Mem64& src, const Imm8& i)\t\t\t{AppendInstr(I_PINSRQ, 0x0F3A22, E_MANDATORY_PREFIX_66 | E_REXW_PREFIX, RW(dst), R(src), i);}\n#endif\n\tvoid pmaxsb(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMAXSB, 0x0F383C, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmaxsb(const XmmReg& dst, const Mem128& src)\t\t\t\t\t\t{AppendInstr(I_PMAXSB, 0x0F383C, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmaxsd(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMAXSD, 0x0F383D, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmaxsd(const XmmReg& dst, const Mem128& src)\t\t\t\t\t\t{AppendInstr(I_PMAXSD, 0x0F383D, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmaxuw(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMAXUW, 0x0F383E, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmaxuw(const XmmReg& dst, const Mem128& src)\t\t\t\t\t\t{AppendInstr(I_PMAXUW, 0x0F383E, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmaxud(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMAXUD, 0x0F383F, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmaxud(const XmmReg& dst, const Mem128& src)\t\t\t\t\t\t{AppendInstr(I_PMAXUD, 0x0F383F, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pminsb(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMINSB, 0x0F3838, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pminsb(const XmmReg& dst, const Mem128& src)\t\t\t\t\t\t{AppendInstr(I_PMINSB, 0x0F3838, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pminsd(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMINSD, 0x0F3839, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pminsd(const XmmReg& dst, const Mem128& src)\t\t\t\t\t\t{AppendInstr(I_PMINSD, 0x0F3839, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pminuw(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMINUW, 0x0F383A, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pminuw(const XmmReg& dst, const Mem128& src)\t\t\t\t\t\t{AppendInstr(I_PMINUW, 0x0F383A, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pminud(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMINUD, 0x0F383B, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pminud(const XmmReg& dst, const Mem128& src)\t\t\t\t\t\t{AppendInstr(I_PMINUD, 0x0F383B, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmovsxbw(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXBW, 0x0F3820, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid pmovsxbw(const XmmReg& dst, const Mem64& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXBW, 0x0F3820, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid pmovsxbd(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXBD, 0x0F3821, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid pmovsxbd(const XmmReg& dst, const Mem32& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXBD, 0x0F3821, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid pmovsxbq(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXBQ, 0x0F3822, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid pmovsxbq(const XmmReg& dst, const Mem16& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXBQ, 0x0F3822, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid pmovsxwd(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXWD, 0x0F3823, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid pmovsxwd(const XmmReg& dst, const Mem64& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXWD, 0x0F3823, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid pmovsxwq(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXWQ, 0x0F3824, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid pmovsxwq(const XmmReg& dst, const Mem32& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXWQ, 0x0F3824, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid pmovsxdq(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXDQ, 0x0F3825, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid pmovsxdq(const XmmReg& dst, const Mem64& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXDQ, 0x0F3825, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid pmovzxbw(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXBW, 0x0F3830, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid pmovzxbw(const XmmReg& dst, const Mem64& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXBW, 0x0F3830, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid pmovzxbd(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXBD, 0x0F3831, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid pmovzxbd(const XmmReg& dst, const Mem32& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXBD, 0x0F3831, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid pmovzxbq(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXBQ, 0x0F3832, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid pmovzxbq(const XmmReg& dst, const Mem16& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXBQ, 0x0F3832, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid pmovzxwd(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXWD, 0x0F3833, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid pmovzxwd(const XmmReg& dst, const Mem64& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXWD, 0x0F3833, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid pmovzxwq(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXWQ, 0x0F3834, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid pmovzxwq(const XmmReg& dst, const Mem32& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXWQ, 0x0F3834, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid pmovzxdq(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXDQ, 0x0F3835, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid pmovzxdq(const XmmReg& dst, const Mem64& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXDQ, 0x0F3835, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid pmuldq(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMULDQ,\t0x0F3828, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmuldq(const XmmReg& dst, const Mem128& src)\t\t\t\t\t\t{AppendInstr(I_PMULDQ,\t0x0F3828, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmulld(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMULLD,\t0x0F3840, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pmulld(const XmmReg& dst, const Mem128& src)\t\t\t\t\t\t{AppendInstr(I_PMULLD,\t0x0F3840, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid ptest(const XmmReg& src1, const XmmReg& src2)\t\t\t\t\t\t{AppendInstr(I_PTEST,\t0x0F3817, E_MANDATORY_PREFIX_66, R(src1), R(src2));}\n\tvoid ptest(const XmmReg& src1, const Mem128& src2)\t\t\t\t\t\t{AppendInstr(I_PTEST,\t0x0F3817, E_MANDATORY_PREFIX_66, R(src1), R(src2));}\n\tvoid roundps(const XmmReg& dst, const XmmReg& src, const Imm8& mode)\t{AppendInstr(I_ROUNDPS,\t0x0F3A08, E_MANDATORY_PREFIX_66, W(dst), R(src), mode);}\n\tvoid roundps(const XmmReg& dst, const Mem128& src, const Imm8& mode)\t{AppendInstr(I_ROUNDPS,\t0x0F3A08, E_MANDATORY_PREFIX_66, W(dst), R(src), mode);}\n\tvoid roundpd(const XmmReg& dst, const XmmReg& src, const Imm8& mode)\t{AppendInstr(I_ROUNDPD,\t0x0F3A09, E_MANDATORY_PREFIX_66, W(dst), R(src), mode);}\n\tvoid roundpd(const XmmReg& dst, const Mem128& src, const Imm8& mode)\t{AppendInstr(I_ROUNDPD,\t0x0F3A09, E_MANDATORY_PREFIX_66, W(dst), R(src), mode);}\n\tvoid roundss(const XmmReg& dst, const XmmReg& src, const Imm8& mode)\t{AppendInstr(I_ROUNDSS,\t0x0F3A0A, E_MANDATORY_PREFIX_66, RW(dst), R(src), mode);}\n\tvoid roundss(const XmmReg& dst, const Mem32& src, const Imm8& mode)\t\t{AppendInstr(I_ROUNDSS,\t0x0F3A0A, E_MANDATORY_PREFIX_66, RW(dst), R(src), mode);}\n\tvoid roundsd(const XmmReg& dst, const XmmReg& src, const Imm8& mode)\t{AppendInstr(I_ROUNDSD,\t0x0F3A0B, E_MANDATORY_PREFIX_66, RW(dst), R(src), mode);}\n\tvoid roundsd(const XmmReg& dst, const Mem64& src, const Imm8& mode)\t\t{AppendInstr(I_ROUNDSD,\t0x0F3A0B, E_MANDATORY_PREFIX_66, RW(dst), R(src), mode);}\n\n\t// SSE4.2\n\tvoid crc32(const Reg32& dst, const Reg8& src)\t\t\t\t\t\t\t{AppendInstr(I_CRC32,\t\t0x0F38F0, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n\tvoid crc32(const Reg32& dst, const Mem8& src)\t\t\t\t\t\t\t{AppendInstr(I_CRC32,\t\t0x0F38F0, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n\tvoid crc32(const Reg32& dst, const Reg16& src)\t\t\t\t\t\t\t{AppendInstr(I_CRC32,\t\t0x0F38F1, E_MANDATORY_PREFIX_F2 | E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid crc32(const Reg32& dst, const Mem16& src)\t\t\t\t\t\t\t{AppendInstr(I_CRC32,\t\t0x0F38F1, E_MANDATORY_PREFIX_F2 | E_OPERAND_SIZE_PREFIX, RW(dst), R(src));}\n\tvoid crc32(const Reg32& dst, const Reg32& src)\t\t\t\t\t\t\t{AppendInstr(I_CRC32,\t\t0x0F38F1, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n\tvoid crc32(const Reg32& dst, const Mem32& src)\t\t\t\t\t\t\t{AppendInstr(I_CRC32,\t\t0x0F38F1, E_MANDATORY_PREFIX_F2, RW(dst), R(src));}\n#ifdef JITASM64\n\tvoid crc32(const Reg64& dst, const Reg8& src)\t\t\t\t\t\t\t{AppendInstr(I_CRC32,\t\t0x0F38F0, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid crc32(const Reg64& dst, const Mem8& src)\t\t\t\t\t\t\t{AppendInstr(I_CRC32,\t\t0x0F38F0, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid crc32(const Reg64& dst, const Reg64& src)\t\t\t\t\t\t\t{AppendInstr(I_CRC32,\t\t0x0F38F1, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, RW(dst), R(src));}\n\tvoid crc32(const Reg64& dst, const Mem64& src)\t\t\t\t\t\t\t{AppendInstr(I_CRC32,\t\t0x0F38F1, E_MANDATORY_PREFIX_F2 | E_REXW_PREFIX, RW(dst), R(src));}\n#endif\n\tvoid pcmpestri(const Reg& result, const XmmReg& src1, const Reg& len1, const XmmReg& src2, const Reg& len2, const Imm8& mode)\t{AppendInstr(I_PCMPESTRI,\t0x0F3A61, E_MANDATORY_PREFIX_66, R(src1), R(src2), mode, Dummy(W(result), ecx), Dummy(R(len1), eax), Dummy(R(len2), edx));}\n\tvoid pcmpestri(const Reg& result, const XmmReg& src1, const Reg& len1, const Mem128& src2, const Reg& len2, const Imm8& mode)\t{AppendInstr(I_PCMPESTRI,\t0x0F3A61, E_MANDATORY_PREFIX_66, R(src1), R(src2), mode, Dummy(W(result), ecx), Dummy(R(len1), eax), Dummy(R(len2), edx));}\n\tvoid pcmpestrm(const XmmReg& result, const XmmReg& src1, const Reg& len1, const XmmReg& src2, const Reg& len2, const Imm8& mode){AppendInstr(I_PCMPESTRM,\t0x0F3A60, E_MANDATORY_PREFIX_66, R(src1), R(src2), mode, Dummy(W(result), xmm0), Dummy(R(len1), eax), Dummy(R(len2), edx));}\n\tvoid pcmpestrm(const XmmReg& result, const XmmReg& src1, const Reg& len1, const Mem128& src2, const Reg& len2, const Imm8& mode){AppendInstr(I_PCMPESTRM,\t0x0F3A60, E_MANDATORY_PREFIX_66, R(src1), R(src2), mode, Dummy(W(result), xmm0), Dummy(R(len1), eax), Dummy(R(len2), edx));}\n\tvoid pcmpistri(const Reg& result, const XmmReg& src1, const XmmReg& src2, const Imm8& mode)\t\t{AppendInstr(I_PCMPISTRI, 0x0F3A63, E_MANDATORY_PREFIX_66, R(src1), R(src2), mode, Dummy(W(result), ecx));}\n\tvoid pcmpistri(const Reg& result, const XmmReg& src1, const Mem128& src2, const Imm8& mode)\t\t{AppendInstr(I_PCMPISTRI, 0x0F3A63, E_MANDATORY_PREFIX_66, R(src1), R(src2), mode, Dummy(W(result), ecx));}\n\tvoid pcmpistrm(const XmmReg& result, const XmmReg& src1, const XmmReg& src2, const Imm8& mode)\t{AppendInstr(I_PCMPISTRM, 0x0F3A62, E_MANDATORY_PREFIX_66, R(src1), R(src2), mode, Dummy(W(result), xmm0));}\n\tvoid pcmpistrm(const XmmReg& result, const XmmReg& src1, const Mem128& src2, const Imm8& mode)\t{AppendInstr(I_PCMPISTRM, 0x0F3A62, E_MANDATORY_PREFIX_66, R(src1), R(src2), mode, Dummy(W(result), xmm0));}\n\tvoid pcmpgtq(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PCMPGTQ,\t\t0x0F3837, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid pcmpgtq(const XmmReg& dst, const Mem128& src)\t\t\t\t\t\t{AppendInstr(I_PCMPGTQ,\t\t0x0F3837, E_MANDATORY_PREFIX_66, RW(dst), R(src));}\n\tvoid popcnt(const Reg16& dst, const Reg16& src)\t\t\t\t\t\t\t{AppendInstr(I_POPCNT,\t\t0x0FB8, E_MANDATORY_PREFIX_F3 | E_OPERAND_SIZE_PREFIX, W(dst), R(src));}\n\tvoid popcnt(const Reg16& dst, const Mem16& src)\t\t\t\t\t\t\t{AppendInstr(I_POPCNT,\t\t0x0FB8, E_MANDATORY_PREFIX_F3 | E_OPERAND_SIZE_PREFIX, W(dst), R(src));}\n\tvoid popcnt(const Reg32& dst, const Reg32& src)\t\t\t\t\t\t\t{AppendInstr(I_POPCNT,\t\t0x0FB8, E_MANDATORY_PREFIX_F3, W(dst), R(src));}\n\tvoid popcnt(const Reg32& dst, const Mem32& src)\t\t\t\t\t\t\t{AppendInstr(I_POPCNT,\t\t0x0FB8, E_MANDATORY_PREFIX_F3, W(dst), R(src));}\n#ifdef JITASM64\n\tvoid popcnt(const Reg64& dst, const Reg64& src)\t\t\t\t\t\t\t{AppendInstr(I_POPCNT, 0x0FB8, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));}\n\tvoid popcnt(const Reg64& dst, const Mem64& src)\t\t\t\t\t\t\t{AppendInstr(I_POPCNT, 0x0FB8, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));}\n#endif\n\n\t// AVX\n\tvoid vaddpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_ADDPD, 0x58, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vaddpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_ADDPD, 0x58, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vaddpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_ADDPD, 0x58, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vaddpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_ADDPD, 0x58, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vaddps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_ADDPS, 0x58, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vaddps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_ADDPS, 0x58, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vaddps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_ADDPS, 0x58, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vaddps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_ADDPS, 0x58, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vaddsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_ADDSD, 0x58, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}\n\tvoid vaddsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t{AppendInstr(I_ADDSD, 0x58, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}\n\tvoid vaddss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_ADDSS, 0x58, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));}\n\tvoid vaddss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2)\t{AppendInstr(I_ADDSS, 0x58, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));}\n\tvoid vaddsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_ADDSUBPD, 0xD0, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vaddsubpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_ADDSUBPD, 0xD0, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vaddsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_ADDSUBPD, 0xD0, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vaddsubpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_ADDSUBPD, 0xD0, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vaddsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_ADDSUBPS, 0xD0, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}\n\tvoid vaddsubps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_ADDSUBPS, 0xD0, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}\n\tvoid vaddsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_ADDSUBPS, 0xD0, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}\n\tvoid vaddsubps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_ADDSUBPS, 0xD0, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}\n\tvoid aesenc(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t\t{AppendInstr(I_AESENC, 0x0F38DC, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid aesenc(const XmmReg& dst, const Mem128& src)\t\t\t\t\t\t\t{AppendInstr(I_AESENC, 0x0F38DC, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid vaesenc(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t\t{AppendInstr(I_AESENC, 0xDC, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vaesenc(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t\t{AppendInstr(I_AESENC, 0xDC, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid aesenclast(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_AESENCLAST, 0x0F38DD, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid aesenclast(const XmmReg& dst, const Mem128& src)\t\t\t\t\t\t{AppendInstr(I_AESENCLAST, 0x0F38DD, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid vaesenclast(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_AESENCLAST, 0xDD, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vaesenclast(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_AESENCLAST, 0xDD, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid aesdec(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t\t{AppendInstr(I_AESDEC, 0x0F38DE, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid aesdec(const XmmReg& dst, const Mem128& src)\t\t\t\t\t\t\t{AppendInstr(I_AESDEC, 0x0F38DE, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid vaesdec(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t\t{AppendInstr(I_AESDEC, 0xDE, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vaesdec(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t\t{AppendInstr(I_AESDEC, 0xDE, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid aesdeclast(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_AESDECLAST, 0x0F38DF, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid aesdeclast(const XmmReg& dst, const Mem128& src)\t\t\t\t\t\t{AppendInstr(I_AESDECLAST, 0x0F38DF, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid vaesdeclast(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_AESDECLAST, 0xDF, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vaesdeclast(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_AESDECLAST, 0xDF, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid aesimc(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_AESIMC, 0x0F38DB, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid aesimc(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_AESIMC, 0x0F38DB, E_MANDATORY_PREFIX_66, W(dst), R(src));}\n\tvoid vaesimc(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_AESIMC, 0xDB, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vaesimc(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_AESIMC, 0xDB, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid aeskeygenassist(const XmmReg& dst, const XmmReg& src, const Imm8& imm)\t\t{AppendInstr(I_AESKEYGENASSIST, 0x0F3ADF, E_MANDATORY_PREFIX_66, W(dst), R(src), imm);}\n\tvoid aeskeygenassist(const XmmReg& dst, const Mem128& src, const Imm8& imm)\t\t{AppendInstr(I_AESKEYGENASSIST, 0x0F3ADF, E_MANDATORY_PREFIX_66, W(dst), R(src), imm);}\n\tvoid vaeskeygenassist(const XmmReg& dst, const XmmReg& src, const Imm8& imm)\t{AppendInstr(I_AESKEYGENASSIST, 0xDF, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src), imm);}\n\tvoid vaeskeygenassist(const XmmReg& dst, const Mem128& src, const Imm8& imm)\t{AppendInstr(I_AESKEYGENASSIST, 0xDF, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src), imm);}\n\tvoid vandpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_ANDPD, 0x54, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vandpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_ANDPD, 0x54, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vandpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_ANDPD, 0x54, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vandpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_ANDPD, 0x54, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vandps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_ANDPS, 0x54, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vandps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_ANDPS, 0x54, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vandps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_ANDPS, 0x54, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vandps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_ANDPS, 0x54, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vandnpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_ANDNPD, 0x55, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vandnpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_ANDNPD, 0x55, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vandnpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_ANDNPD, 0x55, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vandnpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_ANDNPD, 0x55, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vandnps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_ANDNPS, 0x55, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vandnps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_ANDNPS, 0x55, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vandnps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_ANDNPS, 0x55, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vandnps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_ANDNPS, 0x55, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vblendpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mask)\t{AppendInstr(I_BLENDPD, 0x0D, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}\n\tvoid vblendpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& mask)\t{AppendInstr(I_BLENDPD, 0x0D, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}\n\tvoid vblendpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& mask)\t{AppendInstr(I_BLENDPD, 0x0D, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}\n\tvoid vblendpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& mask)\t{AppendInstr(I_BLENDPD, 0x0D, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}\n\tvoid vblendps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mask)\t{AppendInstr(I_BLENDPS, 0x0C, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}\n\tvoid vblendps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& mask)\t{AppendInstr(I_BLENDPS, 0x0C, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}\n\tvoid vblendps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& mask)\t{AppendInstr(I_BLENDPS, 0x0C, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}\n\tvoid vblendps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& mask)\t{AppendInstr(I_BLENDPS, 0x0C, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}\n\tvoid vblendvpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& mask)\t{AppendInstr(I_BLENDVPD, 0x4B, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), R(mask));}\n\tvoid vblendvpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& mask)\t{AppendInstr(I_BLENDVPD, 0x4B, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), R(mask));}\n\tvoid vblendvpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& mask)\t{AppendInstr(I_BLENDVPD, 0x4B, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), R(mask));}\n\tvoid vblendvpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& mask)\t{AppendInstr(I_BLENDVPD, 0x4B, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), R(mask));}\n\tvoid vblendvps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& mask)\t{AppendInstr(I_BLENDVPS, 0x4A, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), R(mask));}\n\tvoid vblendvps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& mask)\t{AppendInstr(I_BLENDVPS, 0x4A, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), R(mask));}\n\tvoid vblendvps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& mask)\t{AppendInstr(I_BLENDVPS, 0x4A, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), R(mask));}\n\tvoid vblendvps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& mask)\t{AppendInstr(I_BLENDVPS, 0x4A, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), R(mask));}\n\tvoid vbroadcastss(const XmmReg& dst, const Mem32& src)\t{AppendInstr(I_VBROADCASTSS, 0x18, E_VEX_128_66_0F38_W0, W(dst), R(src));}\n\tvoid vbroadcastss(const YmmReg& dst, const Mem32& src)\t{AppendInstr(I_VBROADCASTSS, 0x18, E_VEX_256_66_0F38_W0, W(dst), R(src));}\n\tvoid vbroadcastsd(const YmmReg& dst, const Mem64 src)\t{AppendInstr(I_VBROADCASTSD, 0x19, E_VEX_256_66_0F38_W0, W(dst), R(src));}\n\tvoid vbroadcastf128(const YmmReg& dst, const Mem128& src)\t{AppendInstr(I_VBROADCASTF128, 0x1A, E_VEX_256_66_0F38_W0, W(dst), R(src));}\n\tvoid vcmppd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& imm)\t{AppendInstr(I_CMPPD, 0xC2, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1), imm);}\n\tvoid vcmppd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& imm)\t{AppendInstr(I_CMPPD, 0xC2, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1), imm);}\n\tvoid vcmppd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& imm)\t{AppendInstr(I_CMPPD, 0xC2, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1), imm);}\n\tvoid vcmppd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& imm)\t{AppendInstr(I_CMPPD, 0xC2, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1), imm);}\n\tvoid vcmpps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& imm)\t{AppendInstr(I_CMPPS, 0xC2, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1), imm);}\n\tvoid vcmpps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& imm)\t{AppendInstr(I_CMPPS, 0xC2, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1), imm);}\n\tvoid vcmpps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& imm)\t{AppendInstr(I_CMPPS, 0xC2, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1), imm);}\n\tvoid vcmpps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& imm)\t{AppendInstr(I_CMPPS, 0xC2, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1), imm);}\n\tvoid vcmpsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& imm)\t{AppendInstr(I_CMPSD, 0xC2, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1), imm);}\n\tvoid vcmpsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2, const Imm8& imm)\t{AppendInstr(I_CMPSD, 0xC2, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1), imm);}\n\tvoid vcmpss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& imm)\t{AppendInstr(I_CMPSS, 0xC2, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1), imm);}\n\tvoid vcmpss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2, const Imm8& imm)\t{AppendInstr(I_CMPSS, 0xC2, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1), imm);}\n\tvoid vcomisd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_COMISD, 0x2F, E_VEX_128_66_0F_WIG, W(dst), R(src));}\n\tvoid vcomisd(const XmmReg& dst, const Mem64& src)\t{AppendInstr(I_COMISD, 0x2F, E_VEX_128_66_0F_WIG, W(dst), R(src));}\n\tvoid vcomiss(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_COMISS, 0x2F, E_VEX_LIG | E_VEX_0F | E_VEX_WIG, W(dst), R(src));}\n\tvoid vcomiss(const XmmReg& dst, const Mem32& src)\t{AppendInstr(I_COMISS, 0x2F, E_VEX_LIG | E_VEX_0F | E_VEX_WIG, W(dst), R(src));}\n\tvoid vcvtdq2pd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_CVTDQ2PD, 0xE6, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src));}\n\tvoid vcvtdq2pd(const XmmReg& dst, const Mem64& src)\t\t{AppendInstr(I_CVTDQ2PD, 0xE6, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src));}\n\tvoid vcvtdq2pd(const YmmReg& dst, const XmmReg& src)\t{AppendInstr(I_CVTDQ2PD, 0xE6, E_VEX_256 | E_VEX_F3_0F, W(dst), R(src));}\n\tvoid vcvtdq2pd(const YmmReg& dst, const Mem128& src)\t{AppendInstr(I_CVTDQ2PD, 0xE6, E_VEX_256 | E_VEX_F3_0F, W(dst), R(src));}\n\tvoid vcvtdq2ps(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_CVTDQ2PS, 0x5B, E_VEX_128_0F_WIG, W(dst), R(src));}\n\tvoid vcvtdq2ps(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_CVTDQ2PS, 0x5B, E_VEX_128_0F_WIG, W(dst), R(src));}\n\tvoid vcvtdq2ps(const YmmReg& dst, const YmmReg& src)\t{AppendInstr(I_CVTDQ2PS, 0x5B, E_VEX_256_0F_WIG, W(dst), R(src));}\n\tvoid vcvtdq2ps(const YmmReg& dst, const Mem256& src)\t{AppendInstr(I_CVTDQ2PS, 0x5B, E_VEX_256_0F_WIG, W(dst), R(src));}\n\tvoid vcvtpd2dq(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_CVTPD2DQ, 0xE6, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src));}\n\tvoid vcvtpd2dq(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_CVTPD2DQ, 0xE6, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src));}\n\tvoid vcvtpd2dq(const XmmReg& dst, const YmmReg& src)\t{AppendInstr(I_CVTPD2DQ, 0xE6, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src));}\n\tvoid vcvtpd2dq(const XmmReg& dst, const Mem256& src)\t{AppendInstr(I_CVTPD2DQ, 0xE6, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src));}\n\tvoid vcvtpd2ps(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_CVTPD2PS, 0x5A, E_VEX_128_66_0F_WIG, W(dst), R(src));}\n\tvoid vcvtpd2ps(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_CVTPD2PS, 0x5A, E_VEX_128_66_0F_WIG, W(dst), R(src));}\n\tvoid vcvtpd2ps(const XmmReg& dst, const YmmReg& src)\t{AppendInstr(I_CVTPD2PS, 0x5A, E_VEX_256_66_0F_WIG, W(dst), R(src));}\n\tvoid vcvtpd2ps(const XmmReg& dst, const Mem256& src)\t{AppendInstr(I_CVTPD2PS, 0x5A, E_VEX_256_66_0F_WIG, W(dst), R(src));}\n\tvoid vcvtps2dq(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_CVTPS2DQ, 0x5B, E_VEX_128_66_0F_WIG, W(dst), R(src));}\n\tvoid vcvtps2dq(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_CVTPS2DQ, 0x5B, E_VEX_128_66_0F_WIG, W(dst), R(src));}\n\tvoid vcvtps2dq(const YmmReg& dst, const YmmReg& src)\t{AppendInstr(I_CVTPS2DQ, 0x5B, E_VEX_256_66_0F_WIG, W(dst), R(src));}\n\tvoid vcvtps2dq(const YmmReg& dst, const Mem256& src)\t{AppendInstr(I_CVTPS2DQ, 0x5B, E_VEX_256_66_0F_WIG, W(dst), R(src));}\n\tvoid vcvtps2pd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_CVTPS2PD, 0x5A, E_VEX_128_0F_WIG, W(dst), R(src));}\n\tvoid vcvtps2pd(const XmmReg& dst, const Mem64& src)\t\t{AppendInstr(I_CVTPS2PD, 0x5A, E_VEX_128_0F_WIG, W(dst), R(src));}\n\tvoid vcvtps2pd(const YmmReg& dst, const XmmReg& src)\t{AppendInstr(I_CVTPS2PD, 0x5A, E_VEX_256_0F_WIG, W(dst), R(src));}\n\tvoid vcvtps2pd(const YmmReg& dst, const Mem128& src)\t{AppendInstr(I_CVTPS2PD, 0x5A, E_VEX_256_0F_WIG, W(dst), R(src));}\n\tvoid vcvtsd2si(const Reg32 dst, const XmmReg& src)\t{AppendInstr(I_CVTSD2SI, 0x2D, E_VEX_128 | E_VEX_F2_0F | E_VEX_W0, W(dst), R(src));}\n\tvoid vcvtsd2si(const Reg32 dst, const Mem64& src)\t{AppendInstr(I_CVTSD2SI, 0x2D, E_VEX_128 | E_VEX_F2_0F | E_VEX_W0, W(dst), R(src));}\n#ifdef JITASM64\n\tvoid vcvtsd2si(const Reg64 dst, const XmmReg& src)\t{AppendInstr(I_CVTSD2SI, 0x2D, E_VEX_128 | E_VEX_F2_0F | E_VEX_W1, W(dst), R(src));}\n\tvoid vcvtsd2si(const Reg64 dst, const Mem64& src)\t{AppendInstr(I_CVTSD2SI, 0x2D, E_VEX_128 | E_VEX_F2_0F | E_VEX_W1, W(dst), R(src));}\n#endif\n\tvoid vcvtsd2ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_CVTSD2SS, 0x5A, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}\n\tvoid vcvtsd2ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t{AppendInstr(I_CVTSD2SS, 0x5A, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}\n\tvoid vcvtsi2sd(const XmmReg& dst, const XmmReg& src1, const Reg32& src2)\t{AppendInstr(I_CVTSI2SD, 0x2A, E_VEX_128 | E_VEX_F2_0F | E_VEX_W0, W(dst), R(src2), R(src1));}\n\tvoid vcvtsi2sd(const XmmReg& dst, const XmmReg& src1, const Mem32& src2)\t{AppendInstr(I_CVTSI2SD, 0x2A, E_VEX_128 | E_VEX_F2_0F | E_VEX_W0, W(dst), R(src2), R(src1));}\n#ifdef JITASM64\n\tvoid vcvtsi2sd(const XmmReg& dst, const XmmReg& src1, const Reg64& src2)\t{AppendInstr(I_CVTSI2SD, 0x2A, E_VEX_128 | E_VEX_F2_0F | E_VEX_W1, W(dst), R(src2), R(src1));}\n\tvoid vcvtsi2sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t{AppendInstr(I_CVTSI2SD, 0x2A, E_VEX_128 | E_VEX_F2_0F | E_VEX_W1, W(dst), R(src2), R(src1));}\n#endif\n\tvoid vcvtsi2ss(const XmmReg& dst, const XmmReg& src1, const Reg32& src2)\t{AppendInstr(I_CVTSI2SS, 0x2A, E_VEX_128 | E_VEX_F3_0F | E_VEX_W0, W(dst), R(src2), R(src1));}\n\tvoid vcvtsi2ss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2)\t{AppendInstr(I_CVTSI2SS, 0x2A, E_VEX_128 | E_VEX_F3_0F | E_VEX_W0, W(dst), R(src2), R(src1));}\n#ifdef JITASM64\n\tvoid vcvtsi2ss(const XmmReg& dst, const XmmReg& src1, const Reg64& src2)\t{AppendInstr(I_CVTSI2SS, 0x2A, E_VEX_128 | E_VEX_F3_0F | E_VEX_W1, W(dst), R(src2), R(src1));}\n\tvoid vcvtsi2ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t{AppendInstr(I_CVTSI2SS, 0x2A, E_VEX_128 | E_VEX_F3_0F | E_VEX_W1, W(dst), R(src2), R(src1));}\n#endif\n\tvoid vcvtss2sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_CVTSS2SD, 0x5A, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));}\n\tvoid vcvtss2sd(const XmmReg& dst, const XmmReg& src1, const Mem32& src2)\t{AppendInstr(I_CVTSS2SD, 0x5A, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));}\n\tvoid vcvtss2si(const Reg32& dst, const XmmReg& src)\t{AppendInstr(I_CVTSS2SI, 0x2D, E_VEX_128 | E_VEX_F3_0F | E_VEX_W0, W(dst), R(src));}\n\tvoid vcvtss2si(const Reg32& dst, const Mem32& src)\t{AppendInstr(I_CVTSS2SI, 0x2D, E_VEX_128 | E_VEX_F3_0F | E_VEX_W0, W(dst), R(src));}\n#ifdef JITASM64\n\tvoid vcvtss2si(const Reg64& dst, const XmmReg& src)\t{AppendInstr(I_CVTSS2SI, 0x2D, E_VEX_128 | E_VEX_F3_0F | E_VEX_W1, W(dst), R(src));}\n\tvoid vcvtss2si(const Reg64& dst, const Mem32& src)\t{AppendInstr(I_CVTSS2SI, 0x2D, E_VEX_128 | E_VEX_F3_0F | E_VEX_W1, W(dst), R(src));}\n#endif\n\tvoid vcvttpd2dq(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_CVTTPD2DQ, 0xE6, E_VEX_128_66_0F_WIG, W(dst), R(src));}\n\tvoid vcvttpd2dq(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_CVTTPD2DQ, 0xE6, E_VEX_128_66_0F_WIG, W(dst), R(src));}\n\tvoid vcvttpd2dq(const XmmReg& dst, const YmmReg& src)\t{AppendInstr(I_CVTTPD2DQ, 0xE6, E_VEX_256_66_0F_WIG, W(dst), R(src));}\n\tvoid vcvttpd2dq(const XmmReg& dst, const Mem256& src)\t{AppendInstr(I_CVTTPD2DQ, 0xE6, E_VEX_256_66_0F_WIG, W(dst), R(src));}\n\tvoid vcvttps2dq(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_CVTTPS2DQ, 0x5B, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src));}\n\tvoid vcvttps2dq(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_CVTTPS2DQ, 0x5B, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src));}\n\tvoid vcvttps2dq(const YmmReg& dst, const YmmReg& src)\t{AppendInstr(I_CVTTPS2DQ, 0x5B, E_VEX_256 | E_VEX_F3_0F, W(dst), R(src));}\n\tvoid vcvttps2dq(const YmmReg& dst, const Mem256& src)\t{AppendInstr(I_CVTTPS2DQ, 0x5B, E_VEX_256 | E_VEX_F3_0F, W(dst), R(src));}\n\tvoid vcvttsd2si(const Reg32& dst, const XmmReg& src)\t{AppendInstr(I_CVTSD2SI, 0x2C, E_VEX_128 | E_VEX_F2_0F | E_VEX_W0, W(dst), R(src));}\n\tvoid vcvttsd2si(const Reg32& dst, const Mem64& src)\t\t{AppendInstr(I_CVTSD2SI, 0x2C, E_VEX_128 | E_VEX_F2_0F | E_VEX_W0, W(dst), R(src));}\n#ifdef JITASM64\n\tvoid vcvttsd2si(const Reg64& dst, const XmmReg& src)\t{AppendInstr(I_CVTSD2SI, 0x2C, E_VEX_128 | E_VEX_F2_0F | E_VEX_W1, W(dst), R(src));}\n\tvoid vcvttsd2si(const Reg64& dst, const Mem64& src)\t\t{AppendInstr(I_CVTSD2SI, 0x2C, E_VEX_128 | E_VEX_F2_0F | E_VEX_W1, W(dst), R(src));}\n#endif\n\tvoid vcvttss2si(const Reg32& dst, const XmmReg& src)\t{AppendInstr(I_CVTSS2SI, 0x2C, E_VEX_128 | E_VEX_F3_0F | E_VEX_W0, W(dst), R(src));}\n\tvoid vcvttss2si(const Reg32& dst, const Mem32& src)\t\t{AppendInstr(I_CVTSS2SI, 0x2C, E_VEX_128 | E_VEX_F3_0F | E_VEX_W0, W(dst), R(src));}\n#ifdef JITASM64\n\tvoid vcvttss2si(const Reg64& dst, const XmmReg& src)\t{AppendInstr(I_CVTSS2SI, 0x2C, E_VEX_128 | E_VEX_F3_0F | E_VEX_W1, W(dst), R(src));}\n\tvoid vcvttss2si(const Reg64& dst, const Mem32& src)\t\t{AppendInstr(I_CVTSS2SI, 0x2C, E_VEX_128 | E_VEX_F3_0F | E_VEX_W1, W(dst), R(src));}\n#endif\n\tvoid vdivpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_DIVPD, 0x5E, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vdivpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_DIVPD, 0x5E, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vdivpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_DIVPD, 0x5E, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vdivpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_DIVPD, 0x5E, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vdivps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_DIVPS, 0x5E, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vdivps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_DIVPS, 0x5E, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vdivps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_DIVPS, 0x5E, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vdivps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_DIVPS, 0x5E, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vdivsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_DIVSD, 0x5E, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}\n\tvoid vdivsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t{AppendInstr(I_DIVSD, 0x5E, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}\n\tvoid vdivss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_DIVSS, 0x5E, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));}\n\tvoid vdivss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2)\t{AppendInstr(I_DIVSS, 0x5E, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));}\n\tvoid vdppd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mask)\t{AppendInstr(I_DPPD, 0x41, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}\n\tvoid vdppd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& mask)\t{AppendInstr(I_DPPD, 0x41, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}\n\tvoid vdpps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mask)\t{AppendInstr(I_DPPS, 0x40, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}\n\tvoid vdpps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& mask)\t{AppendInstr(I_DPPS, 0x40, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}\n\tvoid vdpps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& mask)\t{AppendInstr(I_DPPS, 0x40, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}\n\tvoid vdpps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& mask)\t{AppendInstr(I_DPPS, 0x40, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}\n\tvoid vextractf128(const XmmReg& dst, const YmmReg& src, const Imm8& i)\t{AppendInstr(I_VEXTRACTF128, 0x19, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);}\n\tvoid vextractf128(const Mem128& dst, const YmmReg& src, const Imm8& i)\t{AppendInstr(I_VEXTRACTF128, 0x19, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);}\n\tvoid vextractps(const Reg32& dst, const XmmReg& src, const Imm8& i)\t\t{AppendInstr(I_EXTRACTPS, 0x17, E_VEX_128 | E_VEX_66_0F3A, R(src), W(dst), i);}\n\tvoid vextractps(const Mem32& dst, const XmmReg& src, const Imm8& i)\t\t{AppendInstr(I_EXTRACTPS, 0x17, E_VEX_128 | E_VEX_66_0F3A, R(src), W(dst), i);}\n\tvoid vhaddpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_HADDPD, 0x7C, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vhaddpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_HADDPD, 0x7C, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vhaddpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_HADDPD, 0x7C, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vhaddpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_HADDPD, 0x7C, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vhaddps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_HADDPD, 0x7C, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}\n\tvoid vhaddps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_HADDPD, 0x7C, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}\n\tvoid vhaddps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_HADDPD, 0x7C, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}\n\tvoid vhaddps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_HADDPD, 0x7C, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}\n\tvoid vhsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_HSUBPD, 0x7D, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vhsubpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_HSUBPD, 0x7D, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vhsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_HSUBPD, 0x7D, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vhsubpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_HSUBPD, 0x7D, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vhsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_HSUBPD, 0x7D, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}\n\tvoid vhsubps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_HSUBPD, 0x7D, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}\n\tvoid vhsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_HSUBPD, 0x7D, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}\n\tvoid vhsubps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_HSUBPD, 0x7D, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}\n\tvoid vinsertf128(const YmmReg& dst, const YmmReg& src1, const XmmReg& src2, const Imm8& i)\t{AppendInstr(I_VINSERTF128, 0x18, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), i);}\n\tvoid vinsertf128(const YmmReg& dst, const YmmReg& src1, const Mem128& src2, const Imm8& i)\t{AppendInstr(I_VINSERTF128, 0x18, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), i);}\n\tvoid vinsertps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& i)\t{AppendInstr(I_INSERTPS, 0x21, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), i);}\n\tvoid vinsertps(const XmmReg& dst, const XmmReg& src1, const Mem32& src2, const Imm8& i)\t\t{AppendInstr(I_INSERTPS, 0x21, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), i);}\n\tvoid vlddqu(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_LDDQU, 0xF0, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src));}\n\tvoid vlddqu(const YmmReg& dst, const Mem256& src)\t{AppendInstr(I_LDDQU, 0xF0, E_VEX_256 | E_VEX_F2_0F, W(dst), R(src));}\n\tvoid vldmxcsr(const Mem32& src)\t{AppendInstr(I_LDMXCSR, 0xAE, E_VEX_LZ | E_VEX_0F | E_VEX_WIG, Imm8(2), R(src));}\n\tvoid vmaskmovdqu(const XmmReg& src, const XmmReg& mask, const Reg& dstptr)\t{AppendInstr(I_MASKMOVDQU, 0xF7, E_VEX_128_66_0F_WIG, R(src), R(mask), Dummy(R(dstptr), zdi));}\n\tvoid vmaskmovps(const XmmReg& dst, const XmmReg& mask, const Mem128& src)\t{AppendInstr(I_VMASKMOVPS, 0x2C, E_VEX_128_66_0F38_W0, W(dst), R(src), R(mask));}\n\tvoid vmaskmovps(const YmmReg& dst, const YmmReg& mask, const Mem256& src)\t{AppendInstr(I_VMASKMOVPS, 0x2C, E_VEX_256_66_0F38_W0, W(dst), R(src), R(mask));}\n\tvoid vmaskmovpd(const XmmReg& dst, const XmmReg& mask, const Mem128& src)\t{AppendInstr(I_VMASKMOVPD, 0x2D, E_VEX_128_66_0F38_W0, W(dst), R(src), R(mask));}\n\tvoid vmaskmovpd(const YmmReg& dst, const YmmReg& mask, const Mem256& src)\t{AppendInstr(I_VMASKMOVPD, 0x2D, E_VEX_256_66_0F38_W0, W(dst), R(src), R(mask));}\n\tvoid vmaskmovps(const Mem128& dst, const XmmReg& mask, const XmmReg& src)\t{AppendInstr(I_VMASKMOVPS, 0x2E, E_VEX_128_66_0F38_W0, R(src), W(dst), R(mask));}\n\tvoid vmaskmovps(const Mem256& dst, const YmmReg& mask, const YmmReg& src)\t{AppendInstr(I_VMASKMOVPS, 0x2E, E_VEX_256_66_0F38_W0, R(src), W(dst), R(mask));}\n\tvoid vmaskmovpd(const Mem128& dst, const XmmReg& mask, const XmmReg& src)\t{AppendInstr(I_VMASKMOVPD, 0x2F, E_VEX_128_66_0F38_W0, R(src), W(dst), R(mask));}\n\tvoid vmaskmovpd(const Mem256& dst, const YmmReg& mask, const YmmReg& src)\t{AppendInstr(I_VMASKMOVPD, 0x2F, E_VEX_256_66_0F38_W0, R(src), W(dst), R(mask));}\n\tvoid vmaxpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_MAXPD, 0x5F, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmaxpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_MAXPD, 0x5F, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmaxpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_MAXPD, 0x5F, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmaxpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_MAXPD, 0x5F, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmaxps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_MAXPS, 0x5F, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmaxps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_MAXPS, 0x5F, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmaxps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_MAXPS, 0x5F, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmaxps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_MAXPS, 0x5F, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmaxsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_MAXSD, 0x5F, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}\n\tvoid vmaxsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t{AppendInstr(I_MAXSD, 0x5F, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}\n\tvoid vmaxss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_MAXSS, 0x5F, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));}\n\tvoid vmaxss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2)\t{AppendInstr(I_MAXSS, 0x5F, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));}\n\tvoid vminpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_MINPD, 0x5D, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vminpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_MINPD, 0x5D, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vminpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_MINPD, 0x5D, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vminpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_MINPD, 0x5D, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vminps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_MINPS, 0x5D, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vminps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_MINPS, 0x5D, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vminps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_MINPS, 0x5D, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vminps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_MINPS, 0x5D, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vminsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_MINSD, 0x5D, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}\n\tvoid vminsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t{AppendInstr(I_MINSD, 0x5D, E_VEX_128 | E_VEX_F2_0F, W(dst), R(src2), R(src1));}\n\tvoid vminss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_MINSS, 0x5D, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));}\n\tvoid vminss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2)\t{AppendInstr(I_MINSS, 0x5D, E_VEX_128 | E_VEX_F3_0F, W(dst), R(src2), R(src1));}\n\tvoid vmovapd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MOVAPD, 0x28, E_VEX_128_66_0F_WIG, W(dst), R(src));}\n\tvoid vmovapd(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_MOVAPD, 0x28, E_VEX_128_66_0F_WIG, W(dst), R(src));}\n\tvoid vmovapd(const Mem128& dst, const XmmReg& src)\t{AppendInstr(I_MOVAPD, 0x29, E_VEX_128_66_0F_WIG, R(src), W(dst));}\n\tvoid vmovapd(const YmmReg& dst, const YmmReg& src)\t{AppendInstr(I_MOVAPD, 0x28, E_VEX_256_66_0F_WIG, W(dst), R(src));}\n\tvoid vmovapd(const YmmReg& dst, const Mem256& src)\t{AppendInstr(I_MOVAPD, 0x28, E_VEX_256_66_0F_WIG, W(dst), R(src));}\n\tvoid vmovapd(const Mem256& dst, const YmmReg& src)\t{AppendInstr(I_MOVAPD, 0x29, E_VEX_256_66_0F_WIG, R(src), W(dst));}\n\tvoid vmovaps(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MOVAPS, 0x28, E_VEX_128_0F_WIG, W(dst), R(src));}\n\tvoid vmovaps(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_MOVAPS, 0x28, E_VEX_128_0F_WIG, W(dst), R(src));}\n\tvoid vmovaps(const Mem128& dst, const XmmReg& src)\t{AppendInstr(I_MOVAPS, 0x29, E_VEX_128_0F_WIG, R(src), W(dst));}\n\tvoid vmovaps(const YmmReg& dst, const YmmReg& src)\t{AppendInstr(I_MOVAPS, 0x28, E_VEX_256_0F_WIG, W(dst), R(src));}\n\tvoid vmovaps(const YmmReg& dst, const Mem256& src)\t{AppendInstr(I_MOVAPS, 0x28, E_VEX_256_0F_WIG, W(dst), R(src));}\n\tvoid vmovaps(const Mem256& dst, const YmmReg& src)\t{AppendInstr(I_MOVAPS, 0x29, E_VEX_256_0F_WIG, R(src), W(dst));}\n\tvoid vmovd(const XmmReg& dst, const Reg32& src)\t\t{AppendInstr(I_MOVD, 0x6E, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, W(dst), R(src));}\n\tvoid vmovd(const XmmReg& dst, const Mem32& src)\t\t{AppendInstr(I_MOVD, 0x6E, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, W(dst), R(src));}\n\tvoid vmovd(const Reg32& dst, const XmmReg& src)\t\t{AppendInstr(I_MOVD, 0x7E, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, R(src), W(dst));}\n\tvoid vmovd(const Mem32& dst, const XmmReg& src)\t\t{AppendInstr(I_MOVD, 0x7E, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, R(src), W(dst));}\n\tvoid vmovq(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MOVQ, 0x7E, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}\n\tvoid vmovq(const XmmReg& dst, const Mem64& src)\t\t{AppendInstr(I_MOVQ, 0x7E, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}\n\tvoid vmovq(const Mem64& dst, const XmmReg& src)\t\t{AppendInstr(I_MOVQ, 0xD6, E_VEX_128_66_0F_WIG, R(src), W(dst));}\n#ifdef JITASM64\n\tvoid vmovq(const XmmReg& dst, const Reg64& src)\t\t{AppendInstr(I_MOVQ, 0x6E, E_VEX_128 | E_VEX_66_0F | E_VEX_W1, W(dst), R(src));}\n\tvoid vmovq(const Reg64& dst, const XmmReg& src)\t\t{AppendInstr(I_MOVQ, 0x7E, E_VEX_128 | E_VEX_66_0F | E_VEX_W1, R(src), W(dst));}\n#endif\n\tvoid vmovddup(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MOVDDUP, 0x12, E_VEX_128 | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src));}\n\tvoid vmovddup(const XmmReg& dst, const Mem64& src)\t{AppendInstr(I_MOVDDUP, 0x12, E_VEX_128 | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src));}\n\tvoid vmovddup(const YmmReg& dst, const YmmReg& src)\t{AppendInstr(I_MOVDDUP, 0x12, E_VEX_256 | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src));}\n\tvoid vmovddup(const YmmReg& dst, const Mem256& src)\t{AppendInstr(I_MOVDDUP, 0x12, E_VEX_256 | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src));}\n\tvoid vmovdqa(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MOVDQA, 0x6F, E_VEX_128_66_0F_WIG, W(dst), R(src));}\n\tvoid vmovdqa(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_MOVDQA, 0x6F, E_VEX_128_66_0F_WIG, W(dst), R(src));}\n\tvoid vmovdqa(const Mem128& dst, const XmmReg& src)\t{AppendInstr(I_MOVDQA, 0x7F, E_VEX_128_66_0F_WIG, R(src), W(dst));}\n\tvoid vmovdqa(const YmmReg& dst, const YmmReg& src)\t{AppendInstr(I_MOVDQA, 0x6F, E_VEX_256_66_0F_WIG, W(dst), R(src));}\n\tvoid vmovdqa(const YmmReg& dst, const Mem256& src)\t{AppendInstr(I_MOVDQA, 0x6F, E_VEX_256_66_0F_WIG, W(dst), R(src));}\n\tvoid vmovdqa(const Mem256& dst, const YmmReg& src)\t{AppendInstr(I_MOVDQA, 0x7F, E_VEX_256_66_0F_WIG, R(src), W(dst));}\n\tvoid vmovdqu(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MOVDQU, 0x6F, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}\n\tvoid vmovdqu(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_MOVDQU, 0x6F, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}\n\tvoid vmovdqu(const Mem128& dst, const XmmReg& src)\t{AppendInstr(I_MOVDQU, 0x7F, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, R(src), W(dst));}\n\tvoid vmovdqu(const YmmReg& dst, const YmmReg& src)\t{AppendInstr(I_MOVDQU, 0x6F, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}\n\tvoid vmovdqu(const YmmReg& dst, const Mem256& src)\t{AppendInstr(I_MOVDQU, 0x6F, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}\n\tvoid vmovdqu(const Mem256& dst, const YmmReg& src)\t{AppendInstr(I_MOVDQU, 0x7F, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, R(src), W(dst));}\n\tvoid vmovhlps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_MOVHLPS, 0x12, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmovhpd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t\t{AppendInstr(I_MOVHPD, 0x16, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmovhpd(const Mem64& dst, const XmmReg& src)\t\t\t\t\t\t\t{AppendInstr(I_MOVHPD, 0x17, E_VEX_128_66_0F_WIG, R(src), W(dst));}\n\tvoid vmovhps(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t\t{AppendInstr(I_MOVHPS, 0x16, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmovhps(const Mem64& dst, const XmmReg& src)\t\t\t\t\t\t\t{AppendInstr(I_MOVHPS, 0x17, E_VEX_128_0F_WIG, R(src), W(dst));}\n\tvoid vmovlhps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_MOVHLPS, 0x16, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmovlpd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t\t{AppendInstr(I_MOVLPD, 0x12, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmovlpd(const Mem64& dst, const XmmReg& src)\t\t\t\t\t\t\t{AppendInstr(I_MOVLPD, 0x13, E_VEX_128_66_0F_WIG, R(src), W(dst));}\n\tvoid vmovlps(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t\t{AppendInstr(I_MOVLPS, 0x12, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmovlps(const Mem64& dst, const XmmReg& src)\t\t\t\t\t\t\t{AppendInstr(I_MOVLPS, 0x13, E_VEX_128_0F_WIG, R(src), W(dst));}\n\tvoid vmovmskpd(const Reg32& dst, const XmmReg& src)\t{AppendInstr(I_MOVMSKPD, 0x50, E_VEX_128_66_0F_WIG, W(dst), R(src));}\n\tvoid vmovmskpd(const Reg32& dst, const YmmReg& src)\t{AppendInstr(I_MOVMSKPD, 0x50, E_VEX_256_66_0F_WIG, W(dst), R(src));}\n#ifdef JITASM64\n\tvoid vmovmskpd(const Reg64& dst, const XmmReg& src)\t{AppendInstr(I_MOVMSKPD, 0x50, E_VEX_128_66_0F_WIG, W(dst), R(src));}\n\tvoid vmovmskpd(const Reg64& dst, const YmmReg& src)\t{AppendInstr(I_MOVMSKPD, 0x50, E_VEX_256_66_0F_WIG, W(dst), R(src));}\n#endif\n\tvoid vmovmskps(const Reg32& dst, const XmmReg& src)\t{AppendInstr(I_MOVMSKPS, 0x50, E_VEX_128_0F_WIG, W(dst), R(src));}\n\tvoid vmovmskps(const Reg32& dst, const YmmReg& src)\t{AppendInstr(I_MOVMSKPS, 0x50, E_VEX_256_0F_WIG, W(dst), R(src));}\n#ifdef JITASM64\n\tvoid vmovmskps(const Reg64& dst, const XmmReg& src)\t{AppendInstr(I_MOVMSKPS, 0x50, E_VEX_128_0F_WIG, W(dst), R(src));}\n\tvoid vmovmskps(const Reg64& dst, const YmmReg& src)\t{AppendInstr(I_MOVMSKPS, 0x50, E_VEX_256_0F_WIG, W(dst), R(src));}\n#endif\n\tvoid vmovntdq(const Mem128& dst, const XmmReg& src)\t\t{AppendInstr(I_MOVNTDQ, 0xE7, E_VEX_128_66_0F_WIG, R(src), W(dst));}\n\tvoid vmovntdq(const Mem256& dst, const YmmReg& src)\t\t{AppendInstr(I_MOVNTDQ, 0xE7, E_VEX_256_66_0F_WIG, R(src), W(dst));}\n\tvoid vmovntdqa(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_MOVNTDQA, 0x2A, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vmovntpd(const Mem128& dst, const XmmReg& src)\t\t{AppendInstr(I_MOVNTPD, 0x2B, E_VEX_128_66_0F_WIG, R(src), W(dst));}\n\tvoid vmovntpd(const Mem256& dst, const YmmReg& src)\t\t{AppendInstr(I_MOVNTPD, 0x2B, E_VEX_256_66_0F_WIG, R(src), W(dst));}\n\tvoid vmovntps(const Mem128& dst, const XmmReg& src)\t\t{AppendInstr(I_MOVNTPS, 0x2B, E_VEX_128_0F_WIG, R(src), W(dst));}\n\tvoid vmovntps(const Mem256& dst, const YmmReg& src)\t\t{AppendInstr(I_MOVNTPS, 0x2B, E_VEX_256_0F_WIG, R(src), W(dst));}\n\tvoid vmovsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_MOVSD, 0x10, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmovsd(const XmmReg& dst, const Mem64& src)\t\t\t\t\t\t{AppendInstr(I_MOVSD, 0x10, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src));}\n\tvoid vmovsd(const Mem64& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_MOVSD, 0x11, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, R(src), W(dst));}\n\tvoid vmovshdup(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MOVSHDUP, 0x16, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}\n\tvoid vmovshdup(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_MOVSHDUP, 0x16, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}\n\tvoid vmovshdup(const YmmReg& dst, const YmmReg& src)\t{AppendInstr(I_MOVSHDUP, 0x16, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}\n\tvoid vmovshdup(const YmmReg& dst, const Mem256& src)\t{AppendInstr(I_MOVSHDUP, 0x16, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}\n\tvoid vmovsldup(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MOVSLDUP, 0x12, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}\n\tvoid vmovsldup(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_MOVSLDUP, 0x12, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}\n\tvoid vmovsldup(const YmmReg& dst, const YmmReg& src)\t{AppendInstr(I_MOVSLDUP, 0x12, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}\n\tvoid vmovsldup(const YmmReg& dst, const Mem256& src)\t{AppendInstr(I_MOVSLDUP, 0x12, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}\n\tvoid vmovss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_MOVSS, 0x10, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmovss(const XmmReg& dst, const Mem32& src)\t\t\t\t\t\t{AppendInstr(I_MOVSS, 0x10, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src));}\n\tvoid vmovss(const Mem32& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_MOVSS, 0x11, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, R(src), W(dst));}\n\tvoid vmovupd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MOVUPD, 0x10, E_VEX_128_66_0F_WIG, W(dst), R(src));}\n\tvoid vmovupd(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_MOVUPD, 0x10, E_VEX_128_66_0F_WIG, W(dst), R(src));}\n\tvoid vmovupd(const Mem128& dst, const XmmReg& src)\t{AppendInstr(I_MOVUPD, 0x11, E_VEX_128_66_0F_WIG, R(src), W(dst));}\n\tvoid vmovupd(const YmmReg& dst, const YmmReg& src)\t{AppendInstr(I_MOVUPD, 0x10, E_VEX_256_66_0F_WIG, W(dst), R(src));}\n\tvoid vmovupd(const YmmReg& dst, const Mem256& src)\t{AppendInstr(I_MOVUPD, 0x10, E_VEX_256_66_0F_WIG, W(dst), R(src));}\n\tvoid vmovupd(const Mem256& dst, const YmmReg& src)\t{AppendInstr(I_MOVUPD, 0x11, E_VEX_256_66_0F_WIG, R(src), W(dst));}\n\tvoid vmovups(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_MOVUPS, 0x10, E_VEX_128_0F_WIG, W(dst), R(src));}\n\tvoid vmovups(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_MOVUPS, 0x10, E_VEX_128_0F_WIG, W(dst), R(src));}\n\tvoid vmovups(const Mem128& dst, const XmmReg& src)\t{AppendInstr(I_MOVUPS, 0x11, E_VEX_128_0F_WIG, R(src), W(dst));}\n\tvoid vmovups(const YmmReg& dst, const YmmReg& src)\t{AppendInstr(I_MOVUPS, 0x10, E_VEX_256_0F_WIG, W(dst), R(src));}\n\tvoid vmovups(const YmmReg& dst, const Mem256& src)\t{AppendInstr(I_MOVUPS, 0x10, E_VEX_256_0F_WIG, W(dst), R(src));}\n\tvoid vmovups(const Mem256& dst, const YmmReg& src)\t{AppendInstr(I_MOVUPS, 0x11, E_VEX_256_0F_WIG, R(src), W(dst));}\n\tvoid vmpsadbw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& i)\t{AppendInstr(I_MPSADBW, 0x42, E_VEX_128 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src2), R(src1), i);}\n\tvoid vmpsadbw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& i)\t{AppendInstr(I_MPSADBW, 0x42, E_VEX_128 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src2), R(src1), i);}\n\tvoid vmulpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_MULPD, 0x59, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmulpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_MULPD, 0x59, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmulpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_MULPD, 0x59, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmulpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_MULPD, 0x59, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmulps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_MULPS, 0x59, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmulps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_MULPS, 0x59, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmulps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_MULPS, 0x59, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmulps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_MULPS, 0x59, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmulsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_MULSD, 0x59, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmulsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t{AppendInstr(I_MULSD, 0x59, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmulss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_MULSS, 0x59, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}\n\tvoid vmulss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2)\t{AppendInstr(I_MULSS, 0x59, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}\n\tvoid vorpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_ORPD, 0x56, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vorpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_ORPD, 0x56, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vorpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_ORPD, 0x56, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vorpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_ORPD, 0x56, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vorps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_ORPS, 0x56, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vorps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_ORPS, 0x56, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vorps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_ORPS, 0x56, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vorps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_ORPS, 0x56, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpabsb(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PABSB, 0x1C, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpabsb(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PABSB, 0x1C, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpabsw(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PABSW, 0x1D, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpabsw(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PABSW, 0x1D, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpabsd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_PABSD, 0x1E, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpabsd(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_PABSD, 0x1E, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpacksswb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PACKSSWB, 0x63, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpacksswb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PACKSSWB, 0x63, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpackssdw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PACKSSDW, 0x6B, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpackssdw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PACKSSDW, 0x6B, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpackuswb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PACKUSWB, 0x67, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpackuswb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PACKUSWB, 0x67, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpackusdw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PACKUSDW, 0x2B, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpackusdw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PACKUSDW, 0x2B, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t\t{AppendInstr(I_PADDB, 0xFC, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t\t{AppendInstr(I_PADDB, 0xFC, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t\t{AppendInstr(I_PADDW, 0xFD, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t\t{AppendInstr(I_PADDW, 0xFD, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t\t{AppendInstr(I_PADDD, 0xFE, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t\t{AppendInstr(I_PADDD, 0xFE, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t\t{AppendInstr(I_PADDQ, 0xD4, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t\t{AppendInstr(I_PADDQ, 0xD4, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddsb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t\t{AppendInstr(I_PADDSB, 0xEC, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddsb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t\t{AppendInstr(I_PADDSB, 0xEC, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddsw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t\t{AppendInstr(I_PADDSW, 0xED, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddsw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t\t{AppendInstr(I_PADDSW, 0xED, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddusb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PADDUSB, 0xDC, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddusb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PADDUSB, 0xDC, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddusw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PADDUSW, 0xDD, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddusw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PADDUSW, 0xDD, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpalignr(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& i) {AppendInstr(I_PALIGNR, 0x0F, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), i);}\n\tvoid vpalignr(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& i) {AppendInstr(I_PALIGNR, 0x0F, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), i);}\n\tvoid vpand(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) \t{AppendInstr(I_PAND, 0xDB, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpand(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) \t{AppendInstr(I_PAND, 0xDB, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpandn(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) \t{AppendInstr(I_PANDN, 0xDF, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpandn(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) \t{AppendInstr(I_PANDN, 0xDF, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpavgb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) \t{AppendInstr(I_PAVGB, 0xE0, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpavgb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) \t{AppendInstr(I_PAVGB, 0xE0, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpavgw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2) \t{AppendInstr(I_PAVGW, 0xE3, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpavgw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2) \t{AppendInstr(I_PAVGW, 0xE3, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpblendvb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& mask) \t{AppendInstr(I_PBLENDVB, 0x4C, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src2), R(src1), R(mask));}\n\tvoid vpblendvb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& mask) \t{AppendInstr(I_PBLENDVB, 0x4C, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src2), R(src1), R(mask));}\n\tvoid vpblendw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mask) \t\t{AppendInstr(I_PBLENDW, 0x0E, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}\n\tvoid vpblendw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& mask) \t\t{AppendInstr(I_PBLENDW, 0x0E, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}\n\tvoid pclmulqdq(const XmmReg& dst, const XmmReg& src, const Imm8& mask)\t\t\t\t\t\t\t{AppendInstr(I_PCLMULQDQ, 0x0F3A44, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);}\n\tvoid pclmulqdq(const XmmReg& dst, const Mem128& src, const Imm8& mask)\t\t\t\t\t\t\t{AppendInstr(I_PCLMULQDQ, 0x0F3A44, E_MANDATORY_PREFIX_66, RW(dst), R(src), mask);}\n\tvoid vpclmulqdq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mask) \t{AppendInstr(I_PCLMULQDQ, 0x44, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}\n\tvoid vpclmulqdq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& mask) \t{AppendInstr(I_PCLMULQDQ, 0x44, E_VEX_128 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}\n\tvoid vpcmpeqb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PCMPEQB,\t0x74, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpeqb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PCMPEQB,\t0x74, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpeqw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PCMPEQW,\t0x75, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpeqw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PCMPEQW,\t0x75, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpeqd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PCMPEQD,\t0x76, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpeqd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PCMPEQD,\t0x76, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpeqq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PCMPEQQ,\t0x29, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpeqq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PCMPEQQ,\t0x29, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpgtb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PCMPGTB,\t0x64, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpgtb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PCMPGTB,\t0x64, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpgtw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PCMPGTW,\t0x65, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpgtw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PCMPGTW,\t0x65, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpgtd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PCMPGTD,\t0x66, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpgtd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PCMPGTD,\t0x66, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpgtq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PCMPGTQ,\t0x37, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpgtq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PCMPGTQ,\t0x37, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpestri(const Reg& result, const XmmReg& src1, const Reg& len1, const XmmReg& src2, const Reg& len2, const Imm8& mode)\t\t{AppendInstr(I_PCMPESTRI, 0x61, E_VEX_128 | E_VEX_66_0F3A, R(src1), R(src2), mode, Dummy(W(result), ecx), Dummy(R(len1), eax), Dummy(R(len2), edx));}\n\tvoid vpcmpestri(const Reg& result, const XmmReg& src1, const Reg& len1, const Mem128& src2, const Reg& len2, const Imm8& mode)\t\t{AppendInstr(I_PCMPESTRI, 0x61, E_VEX_128 | E_VEX_66_0F3A, R(src1), R(src2), mode, Dummy(W(result), ecx), Dummy(R(len1), eax), Dummy(R(len2), edx));}\n\tvoid vpcmpestrm(const XmmReg& result, const XmmReg& src1, const Reg& len1, const XmmReg& src2, const Reg& len2, const Imm8& mode)\t{AppendInstr(I_PCMPESTRM, 0x60, E_VEX_128 | E_VEX_66_0F3A, R(src1), R(src2), mode, Dummy(W(result), xmm0), Dummy(R(len1), eax), Dummy(R(len2), edx));}\n\tvoid vpcmpestrm(const XmmReg& result, const XmmReg& src1, const Reg& len1, const Mem128& src2, const Reg& len2, const Imm8& mode)\t{AppendInstr(I_PCMPESTRM, 0x60, E_VEX_128 | E_VEX_66_0F3A, R(src1), R(src2), mode, Dummy(W(result), xmm0), Dummy(R(len1), eax), Dummy(R(len2), edx));}\n\tvoid vpcmpistri(const Reg& result, const XmmReg& src1, const XmmReg& src2, const Imm8& mode)\t{AppendInstr(I_PCMPISTRI, 0x63, E_VEX_128 | E_VEX_66_0F3A, R(src1), R(src2), mode, Dummy(W(result), ecx));}\n\tvoid vpcmpistri(const Reg& result, const XmmReg& src1, const Mem128& src2, const Imm8& mode)\t{AppendInstr(I_PCMPISTRI, 0x63, E_VEX_128 | E_VEX_66_0F3A, R(src1), R(src2), mode, Dummy(W(result), ecx));}\n\tvoid vpcmpistrm(const XmmReg& result, const XmmReg& src1, const XmmReg& src2, const Imm8& mode)\t{AppendInstr(I_PCMPISTRM, 0x62, E_VEX_128 | E_VEX_66_0F3A, R(src1), R(src2), mode, Dummy(W(result), xmm0));}\n\tvoid vpcmpistrm(const XmmReg& result, const XmmReg& src1, const Mem128& src2, const Imm8& mode)\t{AppendInstr(I_PCMPISTRM, 0x62, E_VEX_128 | E_VEX_66_0F3A, R(src1), R(src2), mode, Dummy(W(result), xmm0));}\n\tvoid vpermilpd(const XmmReg& dst, const XmmReg& src, const XmmReg& ctrl)\t{AppendInstr(I_VPERMILPD, 0x0D, E_VEX_128_66_0F38_W0, W(dst), R(ctrl), R(src));}\n\tvoid vpermilpd(const XmmReg& dst, const XmmReg& src, const Mem128& ctrl)\t{AppendInstr(I_VPERMILPD, 0x0D, E_VEX_128_66_0F38_W0, W(dst), R(ctrl), R(src));}\n\tvoid vpermilpd(const YmmReg& dst, const YmmReg& src, const YmmReg& ctrl)\t{AppendInstr(I_VPERMILPD, 0x0D, E_VEX_256_66_0F38_W0, W(dst), R(ctrl), R(src));}\n\tvoid vpermilpd(const YmmReg& dst, const YmmReg& src, const Mem256& ctrl)\t{AppendInstr(I_VPERMILPD, 0x0D, E_VEX_256_66_0F38_W0, W(dst), R(ctrl), R(src));}\n\tvoid vpermilpd(const XmmReg& dst, const XmmReg& src, const Imm8& ctrl)\t\t{AppendInstr(I_VPERMILPD, 0x05, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src), ctrl);}\n\tvoid vpermilpd(const XmmReg& dst, const Mem128& src, const Imm8& ctrl)\t\t{AppendInstr(I_VPERMILPD, 0x05, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src), ctrl);}\n\tvoid vpermilpd(const YmmReg& dst, const YmmReg& src, const Imm8& ctrl)\t\t{AppendInstr(I_VPERMILPD, 0x05, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src), ctrl);}\n\tvoid vpermilpd(const YmmReg& dst, const Mem256& src, const Imm8& ctrl)\t\t{AppendInstr(I_VPERMILPD, 0x05, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src), ctrl);}\n\tvoid vpermilps(const XmmReg& dst, const XmmReg& src, const XmmReg& ctrl)\t{AppendInstr(I_VPERMILPS, 0x0C, E_VEX_128_66_0F38_W0, W(dst), R(ctrl), R(src));}\n\tvoid vpermilps(const XmmReg& dst, const XmmReg& src, const Mem128& ctrl)\t{AppendInstr(I_VPERMILPS, 0x0C, E_VEX_128_66_0F38_W0, W(dst), R(ctrl), R(src));}\n\tvoid vpermilps(const YmmReg& dst, const YmmReg& src, const YmmReg& ctrl)\t{AppendInstr(I_VPERMILPS, 0x0C, E_VEX_256_66_0F38_W0, W(dst), R(ctrl), R(src));}\n\tvoid vpermilps(const YmmReg& dst, const YmmReg& src, const Mem256& ctrl)\t{AppendInstr(I_VPERMILPS, 0x0C, E_VEX_256_66_0F38_W0, W(dst), R(ctrl), R(src));}\n\tvoid vpermilps(const XmmReg& dst, const XmmReg& src, const Imm8& ctrl)\t\t{AppendInstr(I_VPERMILPS, 0x04, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src), ctrl);}\n\tvoid vpermilps(const XmmReg& dst, const Mem128& src, const Imm8& ctrl)\t\t{AppendInstr(I_VPERMILPS, 0x04, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src), ctrl);}\n\tvoid vpermilps(const YmmReg& dst, const YmmReg& src, const Imm8& ctrl)\t\t{AppendInstr(I_VPERMILPS, 0x04, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src), ctrl);}\n\tvoid vpermilps(const YmmReg& dst, const Mem256& src, const Imm8& ctrl)\t\t{AppendInstr(I_VPERMILPS, 0x04, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src), ctrl);}\n\tvoid vperm2f128(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& ctrl)\t{AppendInstr(I_VPERM2F128, 0x06, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src2), R(src1), ctrl);}\n\tvoid vperm2f128(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& ctrl)\t{AppendInstr(I_VPERM2F128, 0x06, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src2), R(src1), ctrl);}\n\tvoid vpextrb(const Reg32& dst, const XmmReg& src, const Imm8& i)\t\t\t{AppendInstr(I_PEXTRB,\t0x14, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);}\n\tvoid vpextrb(const Mem8& dst, const XmmReg& src, const Imm8& i)\t\t\t\t{AppendInstr(I_PEXTRB,\t0x14, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);}\n\tvoid vpextrw(const Reg32& dst, const XmmReg& src, const Imm8& i)\t\t\t{AppendInstr(I_PEXTRW,\t0xC5, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, W(dst), R(src), i);}\n\tvoid vpextrw(const Mem16& dst, const XmmReg& src, const Imm8& i)\t\t\t{AppendInstr(I_PEXTRW,\t0x15, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);}\n\tvoid vpextrd(const Reg32& dst, const XmmReg& src, const Imm8& i)\t\t\t{AppendInstr(I_PEXTRD,\t0x16, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);}\n\tvoid vpextrd(const Mem32& dst, const XmmReg& src, const Imm8& i)\t\t\t{AppendInstr(I_PEXTRD,\t0x16, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);}\n#ifdef JITASM64\n\tvoid vpextrb(const Reg64& dst, const XmmReg& src, const Imm8& i)\t\t\t{AppendInstr(I_PEXTRB,\t0x14, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);}\n\tvoid vpextrw(const Reg64& dst, const XmmReg& src, const Imm8& i)\t\t\t{AppendInstr(I_PEXTRW,\t0xC5, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, W(dst), R(src), i);}\n\tvoid vpextrd(const Reg64& dst, const XmmReg& src, const Imm8& i)\t\t\t{AppendInstr(I_PEXTRD,\t0x16, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, R(src), W(dst), i);}\n\tvoid vpextrq(const Reg64& dst, const XmmReg& src, const Imm8& i)\t\t\t{AppendInstr(I_PEXTRQ,\t0x16, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W1, R(src), W(dst), i);}\n\tvoid vpextrq(const Mem64& dst, const XmmReg& src, const Imm8& i)\t\t\t{AppendInstr(I_PEXTRQ,\t0x16, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W1, R(src), W(dst), i);}\n#endif\n\tvoid vphaddw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t\t{AppendInstr(I_PHADDW,\t0x01, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vphaddw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t\t{AppendInstr(I_PHADDW,\t0x01, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vphaddd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t\t{AppendInstr(I_PHADDD,\t0x02, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vphaddd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t\t{AppendInstr(I_PHADDD,\t0x02, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vphaddsw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PHADDSW,\t0x03, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vphaddsw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PHADDSW,\t0x03, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vphminposuw(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PHMINPOSUW, 0x41, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vphminposuw(const XmmReg& dst, const Mem128& src)\t\t\t\t\t\t{AppendInstr(I_PHMINPOSUW, 0x41, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vphsubw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t\t{AppendInstr(I_PHSUBW,\t0x05, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vphsubw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t\t{AppendInstr(I_PHSUBW,\t0x05, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vphsubd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t\t{AppendInstr(I_PHSUBD,\t0x06, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vphsubd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t\t{AppendInstr(I_PHSUBD,\t0x06, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vphsubsw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PHSUBSW,\t0x07, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vphsubsw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PHSUBSW,\t0x07, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpinsrb(const XmmReg& dst, const XmmReg& src, const Reg32& val, const Imm8& i)\t{AppendInstr(I_PINSRB, 0x20, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(val), R(src), i);}\n\tvoid vpinsrb(const XmmReg& dst, const XmmReg& src, const Mem8& val, const Imm8& i)\t{AppendInstr(I_PINSRB, 0x20, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(val), R(src), i);}\n\tvoid vpinsrw(const XmmReg& dst, const XmmReg& src, const Reg32& val, const Imm8& i)\t{AppendInstr(I_PINSRW, 0xC4, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, W(dst), R(val), R(src), i);}\n\tvoid vpinsrw(const XmmReg& dst, const XmmReg& src, const Mem16& val, const Imm8& i)\t{AppendInstr(I_PINSRW, 0xC4, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, W(dst), R(val), R(src), i);}\n\tvoid vpinsrd(const XmmReg& dst, const XmmReg& src, const Reg32& val, const Imm8& i)\t{AppendInstr(I_PINSRD, 0x22, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(val), R(src), i);}\n\tvoid vpinsrd(const XmmReg& dst, const XmmReg& src, const Mem32& val, const Imm8& i)\t{AppendInstr(I_PINSRD, 0x22, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(val), R(src), i);}\n#ifdef JITASM64\n\tvoid vpinsrb(const XmmReg& dst, const XmmReg& src, const Reg64& val, const Imm8& i)\t{AppendInstr(I_PINSRB, 0x20, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(val), R(src), i);}\n\tvoid vpinsrw(const XmmReg& dst, const XmmReg& src, const Reg64& val, const Imm8& i)\t{AppendInstr(I_PINSRW, 0xC4, E_VEX_128 | E_VEX_66_0F | E_VEX_W0, W(dst), R(val), R(src), i);}\n\tvoid vpinsrd(const XmmReg& dst, const XmmReg& src, const Reg64& val, const Imm8& i)\t{AppendInstr(I_PINSRD, 0x22, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(val), R(src), i);}\n\tvoid vpinsrq(const XmmReg& dst, const XmmReg& src, const Reg64& val, const Imm8& i)\t{AppendInstr(I_PINSRQ, 0x22, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W1, W(dst), R(val), R(src), i);}\n\tvoid vpinsrq(const XmmReg& dst, const XmmReg& src, const Mem64& val, const Imm8& i)\t{AppendInstr(I_PINSRQ, 0x22, E_VEX_128 | E_VEX_66_0F3A | E_VEX_W1, W(dst), R(val), R(src), i);}\n#endif\n\tvoid vpmaddwd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PMADDWD,\t0xF5, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaddwd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PMADDWD,\t0xF5, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaddubsw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PMADDUBSW,0x04, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaddubsw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PMADDUBSW,0x04, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaxsb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PMAXSB, 0x3C, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaxsb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PMAXSB, 0x3C, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaxsw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PMAXSW, 0xEE, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaxsw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PMAXSW, 0xEE, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaxsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PMAXSD, 0x3D, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaxsd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PMAXSD, 0x3D, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaxub(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PMAXUB, 0xDE, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaxub(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PMAXUB, 0xDE, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaxuw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PMAXUW, 0x3E, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaxuw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PMAXUW, 0x3E, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaxud(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PMAXUD, 0x3F, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaxud(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PMAXUD, 0x3F, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpminsb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PMINSB, 0x38, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpminsb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PMINSB, 0x38, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpminsw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PMINSW, 0xEA, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpminsw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PMINSW, 0xEA, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpminsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PMINSD, 0x39, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpminsd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PMINSD, 0x39, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpminub(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PMINUB, 0xDA, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpminub(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PMINUB, 0xDA, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpminuw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PMINUW, 0x3A, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpminuw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PMINUW, 0x3A, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpminud(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PMINUD, 0x3B, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpminud(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PMINUD, 0x3B, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmovmskb(const Reg32& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMOVMSKB, 0xD7, E_VEX_128_66_0F_WIG, W(dst), R(src));}\n#ifdef JITASM64\n\tvoid vpmovmskb(const Reg64& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMOVMSKB, 0xD7, E_VEX_128_66_0F_WIG, W(dst), R(src));}\n#endif\n\tvoid vpmovsxbw(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t{AppendInstr(I_PMOVSXBW, 0x20, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovsxbw(const XmmReg& dst, const Mem64& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXBW, 0x20, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovsxbd(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t{AppendInstr(I_PMOVSXBD, 0x21, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovsxbd(const XmmReg& dst, const Mem32& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXBD, 0x21, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovsxbq(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t{AppendInstr(I_PMOVSXBQ, 0x22, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovsxbq(const XmmReg& dst, const Mem16& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXBQ, 0x22, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovsxwd(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t{AppendInstr(I_PMOVSXWD, 0x23, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovsxwd(const XmmReg& dst, const Mem64& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXWD, 0x23, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovsxwq(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t{AppendInstr(I_PMOVSXWQ, 0x24, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovsxwq(const XmmReg& dst, const Mem32& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXWQ, 0x24, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovsxdq(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t{AppendInstr(I_PMOVSXDQ, 0x25, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovsxdq(const XmmReg& dst, const Mem64& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXDQ, 0x25, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovzxbw(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t{AppendInstr(I_PMOVZXBW, 0x30, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovzxbw(const XmmReg& dst, const Mem64& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXBW, 0x30, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovzxbd(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t{AppendInstr(I_PMOVZXBD, 0x31, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovzxbd(const XmmReg& dst, const Mem32& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXBD, 0x31, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovzxbq(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t{AppendInstr(I_PMOVZXBQ, 0x32, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovzxbq(const XmmReg& dst, const Mem16& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXBQ, 0x32, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovzxwd(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t{AppendInstr(I_PMOVZXWD, 0x33, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovzxwd(const XmmReg& dst, const Mem64& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXWD, 0x33, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovzxwq(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t{AppendInstr(I_PMOVZXWQ, 0x34, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovzxwq(const XmmReg& dst, const Mem32& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXWQ, 0x34, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovzxdq(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t{AppendInstr(I_PMOVZXDQ, 0x35, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovzxdq(const XmmReg& dst, const Mem64& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXDQ, 0x35, E_VEX_128_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmulhuw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2){AppendInstr(I_PMULHUW,\t0xE4, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmulhuw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2){AppendInstr(I_PMULHUW,\t0xE4, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmulhrsw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2){AppendInstr(I_PMULHRSW, 0x0B, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmulhrsw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2){AppendInstr(I_PMULHRSW, 0x0B, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmulhw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PMULHW,\t0xE5, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmulhw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PMULHW,\t0xE5, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmullw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PMULLW,\t0xD5, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmullw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PMULLW,\t0xD5, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmulld(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PMULLD,\t0x40, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmulld(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PMULLD,\t0x40, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmuludq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2){AppendInstr(I_PMULUDQ,\t0xF4, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmuludq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2){AppendInstr(I_PMULUDQ,\t0xF4, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmuldq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PMULDQ,\t0x28, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmuldq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PMULDQ,\t0x28, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpor(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_POR,\t\t0xEB, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpor(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_POR,\t\t0xEB, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsadbw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PSADBW,\t0xF6, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsadbw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PSADBW,\t0xF6, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpshufb(const XmmReg& dst, const XmmReg& src, const XmmReg& order)\t{AppendInstr(I_PSHUFB,\t0x00, E_VEX_128_66_0F38_WIG, W(dst), R(order), R(src));}\n\tvoid vpshufb(const XmmReg& dst, const XmmReg& src, const Mem128& order)\t{AppendInstr(I_PSHUFB,\t0x00, E_VEX_128_66_0F38_WIG, W(dst), R(order), R(src));}\n\tvoid vpshufd(const XmmReg& dst, const XmmReg& src, const Imm8& order)\t{AppendInstr(I_PSHUFD,\t0x70, E_VEX_128_66_0F_WIG, W(dst), R(src), order);}\n\tvoid vpshufd(const XmmReg& dst, const Mem128& src, const Imm8& order)\t{AppendInstr(I_PSHUFD,\t0x70, E_VEX_128_66_0F_WIG, W(dst), R(src), order);}\n\tvoid vpshufhw(const XmmReg& dst, const XmmReg& src, const Imm8& order)\t{AppendInstr(I_PSHUFHW,\t0x70, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src), order);}\n\tvoid vpshufhw(const XmmReg& dst, const Mem128& src, const Imm8& order)\t{AppendInstr(I_PSHUFHW,\t0x70, E_VEX_128 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src), order);}\n\tvoid vpshuflw(const XmmReg& dst, const XmmReg& src, const Imm8& order)\t{AppendInstr(I_PSHUFLW,\t0x70, E_VEX_128 | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src), order);}\n\tvoid vpshuflw(const XmmReg& dst, const Mem128& src, const Imm8& order)\t{AppendInstr(I_PSHUFLW,\t0x70, E_VEX_128 | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src), order);}\n\tvoid vpsignb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PSIGNB,\t0x08, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsignb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PSIGNB,\t0x08, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsignw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PSIGNW,\t0x09, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsignw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PSIGNW,\t0x09, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsignd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PSIGND,\t0x0A, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsignd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PSIGND,\t0x0A, E_VEX_128_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsllw(const XmmReg& dst, const XmmReg& src, const XmmReg& count)\t{AppendInstr(I_PSLLW,\t0xF1, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsllw(const XmmReg& dst, const XmmReg& src, const Mem128& count)\t{AppendInstr(I_PSLLW,\t0xF1, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsllw(const XmmReg& dst, const XmmReg& src, const Imm8& count)\t{AppendInstr(I_PSLLW,\t0x71, E_VEX_128_66_0F_WIG, Imm8(6), R(src), W(dst), count);}\n\tvoid vpslld(const XmmReg& dst, const XmmReg& src, const XmmReg& count)\t{AppendInstr(I_PSLLD,\t0xF2, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpslld(const XmmReg& dst, const XmmReg& src, const Mem128& count)\t{AppendInstr(I_PSLLD,\t0xF2, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpslld(const XmmReg& dst, const XmmReg& src, const Imm8& count)\t{AppendInstr(I_PSLLD,\t0x72, E_VEX_128_66_0F_WIG, Imm8(6), R(src), W(dst), count);}\n\tvoid vpsllq(const XmmReg& dst, const XmmReg& src, const XmmReg& count)\t{AppendInstr(I_PSLLQ,\t0xF3, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsllq(const XmmReg& dst, const XmmReg& src, const Mem128& count)\t{AppendInstr(I_PSLLQ,\t0xF3, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsllq(const XmmReg& dst, const XmmReg& src, const Imm8& count)\t{AppendInstr(I_PSLLQ,\t0x73, E_VEX_128_66_0F_WIG, Imm8(6), R(src), W(dst), count);}\n\tvoid vpslldq(const XmmReg& dst, const XmmReg& src, const Imm8& count)\t{AppendInstr(I_PSLLDQ,\t0x73, E_VEX_128_66_0F_WIG, Imm8(7), R(src), W(dst), count);}\n\tvoid vpsraw(const XmmReg& dst, const XmmReg& src, const XmmReg& count)\t{AppendInstr(I_PSRAW,\t0xE1, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsraw(const XmmReg& dst, const XmmReg& src, const Mem128& count)\t{AppendInstr(I_PSRAW,\t0xE1, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsraw(const XmmReg& dst, const XmmReg& src, const Imm8& count)\t{AppendInstr(I_PSRAW,\t0x71, E_VEX_128_66_0F_WIG, Imm8(4), R(src), W(dst), count);}\n\tvoid vpsrad(const XmmReg& dst, const XmmReg& src, const XmmReg& count)\t{AppendInstr(I_PSRAD,\t0xE2, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsrad(const XmmReg& dst, const XmmReg& src, const Mem128& count)\t{AppendInstr(I_PSRAD,\t0xE2, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsrad(const XmmReg& dst, const XmmReg& src, const Imm8& count)\t{AppendInstr(I_PSRAD,\t0x72, E_VEX_128_66_0F_WIG, Imm8(4), R(src), W(dst), count);}\n\tvoid vpsrlw(const XmmReg& dst, const XmmReg& src, const XmmReg& count)\t{AppendInstr(I_PSRLW,\t0xD1, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsrlw(const XmmReg& dst, const XmmReg& src, const Mem128& count)\t{AppendInstr(I_PSRLW,\t0xD1, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsrlw(const XmmReg& dst, const XmmReg& src, const Imm8& count)\t{AppendInstr(I_PSRLW,\t0x71, E_VEX_128_66_0F_WIG, Imm8(2), R(src), W(dst), count);}\n\tvoid vpsrld(const XmmReg& dst, const XmmReg& src, const XmmReg& count)\t{AppendInstr(I_PSRLD,\t0xD2, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsrld(const XmmReg& dst, const XmmReg& src, const Mem128& count)\t{AppendInstr(I_PSRLD,\t0xD2, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsrld(const XmmReg& dst, const XmmReg& src, const Imm8& count)\t{AppendInstr(I_PSRLD,\t0x72, E_VEX_128_66_0F_WIG, Imm8(2), R(src), W(dst), count);}\n\tvoid vpsrlq(const XmmReg& dst, const XmmReg& src, const XmmReg& count)\t{AppendInstr(I_PSRLQ,\t0xD3, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsrlq(const XmmReg& dst, const XmmReg& src, const Mem128& count)\t{AppendInstr(I_PSRLQ,\t0xD3, E_VEX_128_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsrlq(const XmmReg& dst, const XmmReg& src, const Imm8& count)\t{AppendInstr(I_PSRLQ,\t0x73, E_VEX_128_66_0F_WIG, Imm8(2), R(src), W(dst), count);}\n\tvoid vpsrldq(const XmmReg& dst, const XmmReg& src, const Imm8& count)\t{AppendInstr(I_PSRLDQ,\t0x73, E_VEX_128_66_0F_WIG, Imm8(3), R(src), W(dst), count);}\n\tvoid vptest(const XmmReg& src1, const XmmReg& src2)\t\t\t\t\t\t{AppendInstr(I_PTEST,\t0x17, E_VEX_128_66_0F38_WIG, R(src1), R(src2));}\n\tvoid vptest(const XmmReg& src1, const Mem128& src2)\t\t\t\t\t\t{AppendInstr(I_PTEST,\t0x17, E_VEX_128_66_0F38_WIG, R(src1), R(src2));}\n\tvoid vptest(const YmmReg& src1, const YmmReg& src2)\t\t\t\t\t\t{AppendInstr(I_PTEST,\t0x17, E_VEX_256_66_0F38_WIG, R(src1), R(src2));}\n\tvoid vptest(const YmmReg& src1, const Mem256& src2)\t\t\t\t\t\t{AppendInstr(I_PTEST,\t0x17, E_VEX_256_66_0F38_WIG, R(src1), R(src2));}\n\tvoid vtestps(const XmmReg& src1, const XmmReg& src2)\t\t\t\t\t{AppendInstr(I_VTESTPS,\t0x0E, E_VEX_128_66_0F38_W0, R(src1), R(src2));}\n\tvoid vtestps(const XmmReg& src1, const Mem128& src2)\t\t\t\t\t{AppendInstr(I_VTESTPS,\t0x0E, E_VEX_128_66_0F38_W0, R(src1), R(src2));}\n\tvoid vtestps(const YmmReg& src1, const YmmReg& src2)\t\t\t\t\t{AppendInstr(I_VTESTPS,\t0x0E, E_VEX_256_66_0F38_W0, R(src1), R(src2));}\n\tvoid vtestps(const YmmReg& src1, const Mem256& src2)\t\t\t\t\t{AppendInstr(I_VTESTPS,\t0x0E, E_VEX_256_66_0F38_W0, R(src1), R(src2));}\n\tvoid vtestpd(const XmmReg& src1, const XmmReg& src2)\t\t\t\t\t{AppendInstr(I_VTESTPD,\t0x0F, E_VEX_128_66_0F38_W0, R(src1), R(src2));}\n\tvoid vtestpd(const XmmReg& src1, const Mem128& src2)\t\t\t\t\t{AppendInstr(I_VTESTPD,\t0x0F, E_VEX_128_66_0F38_W0, R(src1), R(src2));}\n\tvoid vtestpd(const YmmReg& src1, const YmmReg& src2)\t\t\t\t\t{AppendInstr(I_VTESTPD,\t0x0F, E_VEX_256_66_0F38_W0, R(src1), R(src2));}\n\tvoid vtestpd(const YmmReg& src1, const Mem256& src2)\t\t\t\t\t{AppendInstr(I_VTESTPD,\t0x0F, E_VEX_256_66_0F38_W0, R(src1), R(src2));}\n\tvoid vpsubb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PSUBB,\t0xF8, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PSUBB,\t0xF8, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PSUBW,\t0xF9, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PSUBW,\t0xF9, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PSUBD,\t0xFA, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PSUBD,\t0xFA, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PSUBQ,\t0xFB, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PSUBQ,\t0xFB, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubsb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PSUBSB,\t0xE8, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubsb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PSUBSB,\t0xE8, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubsw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PSUBSW,\t0xE9, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubsw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PSUBSW,\t0xE9, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubusb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PSUBUSB,\t\t0xD8, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubusb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PSUBUSB,\t\t0xD8, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubusw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PSUBUSW,\t\t0xD9, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubusw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PSUBUSW,\t\t0xD9, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpckhbw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PUNPCKHBW,\t0x68, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpckhbw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PUNPCKHBW,\t0x68, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpckhwd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PUNPCKHWD,\t0x69, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpckhwd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PUNPCKHWD,\t0x69, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpckhdq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PUNPCKHDQ,\t0x6A, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpckhdq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PUNPCKHDQ,\t0x6A, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpckhqdq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PUNPCKHQDQ,\t0x6D, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpckhqdq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PUNPCKHQDQ,\t0x6D, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpcklbw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PUNPCKLBW,\t0x60, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpcklbw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PUNPCKLBW,\t0x60, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpcklwd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PUNPCKLWD,\t0x61, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpcklwd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PUNPCKLWD,\t0x61, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpckldq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PUNPCKLDQ,\t0x62, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpckldq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PUNPCKLDQ,\t0x62, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpcklqdq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PUNPCKLQDQ,\t0x6C, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpcklqdq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PUNPCKLQDQ,\t0x6C, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpxor(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_PXOR,\t0xEF, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpxor(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_PXOR,\t0xEF, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vrcpps(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_RCPPS,\t0x53, E_VEX_128_0F_WIG, W(dst), R(src));}\n\tvoid vrcpps(const XmmReg& dst, const Mem128& src)\t\t\t\t\t\t{AppendInstr(I_RCPPS,\t0x53, E_VEX_128_0F_WIG, W(dst), R(src));}\n\tvoid vrcpps(const YmmReg& dst, const YmmReg& src)\t\t\t\t\t\t{AppendInstr(I_RCPPS,\t0x53, E_VEX_256_0F_WIG, W(dst), R(src));}\n\tvoid vrcpps(const YmmReg& dst, const Mem256& src)\t\t\t\t\t\t{AppendInstr(I_RCPPS,\t0x53, E_VEX_256_0F_WIG, W(dst), R(src));}\n\tvoid vrcpss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_RCPSS,\t0x53, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}\n\tvoid vrcpss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2)\t{AppendInstr(I_RCPSS,\t0x53, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}\n\tvoid vrsqrtps(const XmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_RSQRTPS,\t0x52, E_VEX_128_0F_WIG, W(dst), R(src));}\n\tvoid vrsqrtps(const XmmReg& dst, const Mem128& src)\t\t\t\t\t\t{AppendInstr(I_RSQRTPS,\t0x52, E_VEX_128_0F_WIG, W(dst), R(src));}\n\tvoid vrsqrtps(const YmmReg& dst, const YmmReg& src)\t\t\t\t\t\t{AppendInstr(I_RSQRTPS,\t0x52, E_VEX_256_0F_WIG, W(dst), R(src));}\n\tvoid vrsqrtps(const YmmReg& dst, const Mem256& src)\t\t\t\t\t\t{AppendInstr(I_RSQRTPS,\t0x52, E_VEX_256_0F_WIG, W(dst), R(src));}\n\tvoid vrsqrtss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2){AppendInstr(I_RSQRTSS,\t0x52, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}\n\tvoid vrsqrtss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2)\t{AppendInstr(I_RSQRTSS,\t0x52, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}\n\tvoid vroundpd(const XmmReg& dst, const XmmReg& src, const Imm8& mode)\t{AppendInstr(I_ROUNDPD,\t0x09, E_VEX_128 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src), mode);}\n\tvoid vroundpd(const XmmReg& dst, const Mem128& src, const Imm8& mode)\t{AppendInstr(I_ROUNDPD,\t0x09, E_VEX_128 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src), mode);}\n\tvoid vroundpd(const YmmReg& dst, const YmmReg& src, const Imm8& mode)\t{AppendInstr(I_ROUNDPD,\t0x09, E_VEX_256 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src), mode);}\n\tvoid vroundpd(const YmmReg& dst, const Mem256& src, const Imm8& mode)\t{AppendInstr(I_ROUNDPD,\t0x09, E_VEX_256 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src), mode);}\n\tvoid vroundps(const XmmReg& dst, const XmmReg& src, const Imm8& mode)\t{AppendInstr(I_ROUNDPS,\t0x08, E_VEX_128 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src), mode);}\n\tvoid vroundps(const XmmReg& dst, const Mem128& src, const Imm8& mode)\t{AppendInstr(I_ROUNDPS,\t0x08, E_VEX_128 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src), mode);}\n\tvoid vroundps(const YmmReg& dst, const YmmReg& src, const Imm8& mode)\t{AppendInstr(I_ROUNDPS,\t0x08, E_VEX_256 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src), mode);}\n\tvoid vroundps(const YmmReg& dst, const Mem256& src, const Imm8& mode)\t{AppendInstr(I_ROUNDPS,\t0x08, E_VEX_256 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src), mode);}\n\tvoid vroundsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mode)\t{AppendInstr(I_ROUNDSD,\t0x0B, E_VEX_LIG | E_VEX_66_0F3A | E_VEX_WIG, RW(dst), R(src2), R(src1), mode);}\n\tvoid vroundsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2, const Imm8& mode)\t{AppendInstr(I_ROUNDSD,\t0x0B, E_VEX_LIG | E_VEX_66_0F3A | E_VEX_WIG, RW(dst), R(src2), R(src1), mode);}\n\tvoid vroundss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mode)\t{AppendInstr(I_ROUNDSS,\t0x0A, E_VEX_LIG | E_VEX_66_0F3A | E_VEX_WIG, RW(dst), R(src2), R(src1), mode);}\n\tvoid vroundss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2, const Imm8& mode)\t{AppendInstr(I_ROUNDSS,\t0x0A, E_VEX_LIG | E_VEX_66_0F3A | E_VEX_WIG, RW(dst), R(src2), R(src1), mode);}\n\tvoid vshufpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& sel)\t{AppendInstr(I_SHUFPD, 0xC6, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1), sel);}\n\tvoid vshufpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& sel)\t{AppendInstr(I_SHUFPD, 0xC6, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1), sel);}\n\tvoid vshufpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& sel)\t{AppendInstr(I_SHUFPD, 0xC6, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1), sel);}\n\tvoid vshufpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& sel)\t{AppendInstr(I_SHUFPD, 0xC6, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1), sel);}\n\tvoid vshufps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& sel)\t{AppendInstr(I_SHUFPS, 0xC6, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1), sel);}\n\tvoid vshufps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& sel)\t{AppendInstr(I_SHUFPS, 0xC6, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1), sel);}\n\tvoid vshufps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& sel)\t{AppendInstr(I_SHUFPS, 0xC6, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1), sel);}\n\tvoid vshufps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& sel)\t{AppendInstr(I_SHUFPS, 0xC6, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1), sel);}\n\tvoid vsqrtpd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_SQRTPD, 0x51, E_VEX_128_66_0F_WIG, W(dst), R(src));}\n\tvoid vsqrtpd(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_SQRTPD, 0x51, E_VEX_128_66_0F_WIG, W(dst), R(src));}\n\tvoid vsqrtpd(const YmmReg& dst, const YmmReg& src)\t{AppendInstr(I_SQRTPD, 0x51, E_VEX_256_66_0F_WIG, W(dst), R(src));}\n\tvoid vsqrtpd(const YmmReg& dst, const Mem256& src)\t{AppendInstr(I_SQRTPD, 0x51, E_VEX_256_66_0F_WIG, W(dst), R(src));}\n\tvoid vsqrtps(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_SQRTPS, 0x51, E_VEX_128_0F_WIG, W(dst), R(src));}\n\tvoid vsqrtps(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_SQRTPS, 0x51, E_VEX_128_0F_WIG, W(dst), R(src));}\n\tvoid vsqrtps(const YmmReg& dst, const YmmReg& src)\t{AppendInstr(I_SQRTPS, 0x51, E_VEX_256_0F_WIG, W(dst), R(src));}\n\tvoid vsqrtps(const YmmReg& dst, const Mem256& src)\t{AppendInstr(I_SQRTPS, 0x51, E_VEX_256_0F_WIG, W(dst), R(src));}\n\tvoid vsqrtsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_SQRTSD, 0x51, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}\n\tvoid vsqrtsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t{AppendInstr(I_SQRTSD, 0x51, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}\n\tvoid vsqrtss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_SQRTSS, 0x51, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}\n\tvoid vsqrtss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2)\t{AppendInstr(I_SQRTSS, 0x51, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}\n\tvoid vstmxcsr(const Mem32& dst)\t\t\t\t\t\t\t\t\t\t\t{AppendInstr(I_STMXCSR,\t0xAE, E_VEX_LZ | E_VEX_0F | E_VEX_WIG, Imm8(3), W(dst));}\n\tvoid vsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_SUBPD, 0x5C, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vsubpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_SUBPD, 0x5C, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_SUBPD, 0x5C, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vsubpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_SUBPD, 0x5C, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_SUBPS, 0x5C, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vsubps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_SUBPS, 0x5C, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_SUBPS, 0x5C, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vsubps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_SUBPS, 0x5C, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vsubsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_SUBSD, 0x5C, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}\n\tvoid vsubsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t{AppendInstr(I_SUBSD, 0x5C, E_VEX_LIG | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}\n\tvoid vsubss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_SUBSS, 0x5C, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}\n\tvoid vsubss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2)\t{AppendInstr(I_SUBSS, 0x5C, E_VEX_LIG | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src2), R(src1));}\n\tvoid vucomisd(const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_UCOMISD, 0x2E, E_VEX_LIG | E_VEX_66_0F | E_VEX_WIG, R(src1), R(src2));}\n\tvoid vucomisd(const XmmReg& src1, const Mem64& src2)\t{AppendInstr(I_UCOMISD, 0x2E, E_VEX_LIG | E_VEX_66_0F | E_VEX_WIG, R(src1), R(src2));}\n\tvoid vucomiss(const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_UCOMISS, 0x2E, E_VEX_LIG | E_VEX_0F | E_VEX_WIG, R(src1), R(src2));}\n\tvoid vucomiss(const XmmReg& src1, const Mem32& src2)\t{AppendInstr(I_UCOMISS, 0x2E, E_VEX_LIG | E_VEX_0F | E_VEX_WIG, R(src1), R(src2));}\n\tvoid vunpckhpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_UNPCKHPD, 0x15, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vunpckhpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_UNPCKHPD, 0x15, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vunpckhpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_UNPCKHPD, 0x15, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vunpckhpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_UNPCKHPD, 0x15, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vunpckhps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_UNPCKHPS, 0x15, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vunpckhps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_UNPCKHPS, 0x15, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vunpckhps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_UNPCKHPS, 0x15, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vunpckhps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_UNPCKHPS, 0x15, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vunpcklpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_UNPCKLPD, 0x14, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vunpcklpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_UNPCKLPD, 0x14, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vunpcklpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_UNPCKLPD, 0x14, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vunpcklpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_UNPCKLPD, 0x14, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vunpcklps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_UNPCKLPS, 0x14, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vunpcklps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_UNPCKLPS, 0x14, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vunpcklps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_UNPCKLPS, 0x14, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vunpcklps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_UNPCKLPS, 0x14, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vxorpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_XORPD, 0x57, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vxorpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_XORPD, 0x57, E_VEX_128_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vxorpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_XORPD, 0x57, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vxorpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_XORPD, 0x57, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vxorps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_XORPS, 0x57, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vxorps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_XORPS, 0x57, E_VEX_128_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vxorps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_XORPS, 0x57, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vxorps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_XORPS, 0x57, E_VEX_256_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vzeroall()\t\t{AppendInstr(I_VZEROUPPER, 0x77, E_VEX_256_0F_WIG);}\n\tvoid vzeroupper()\t{AppendInstr(I_VZEROUPPER, 0x77, E_VEX_128_0F_WIG);}\n\n\t// FMA\n\tvoid vfmadd132pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMADD132PD, 0x98, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd132pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFMADD132PD, 0x98, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd132pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFMADD132PD, 0x98, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd132pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFMADD132PD, 0x98, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd213pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMADD213PD, 0xA8, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd213pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFMADD213PD, 0xA8, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd213pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFMADD213PD, 0xA8, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd213pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFMADD213PD, 0xA8, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd231pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMADD231PD, 0xB8, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd231pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFMADD231PD, 0xB8, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd231pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFMADD231PD, 0xB8, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd231pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFMADD231PD, 0xB8, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd132ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMADD132PS, 0x98, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd132ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFMADD132PS, 0x98, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd132ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFMADD132PS, 0x98, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd132ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFMADD132PS, 0x98, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd213ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMADD213PS, 0xA8, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd213ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFMADD213PS, 0xA8, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd213ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFMADD213PS, 0xA8, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd213ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFMADD213PS, 0xA8, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd231ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMADD231PS, 0xB8, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd231ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFMADD231PS, 0xB8, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd231ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFMADD231PS, 0xB8, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd231ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFMADD231PS, 0xB8, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd132sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMADD132SD, 0x99, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd132sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t{AppendInstr(I_VFMADD132SD, 0x99, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd213sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMADD213SD, 0xA9, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd213sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t{AppendInstr(I_VFMADD213SD, 0xA9, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd231sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMADD231SD, 0xB9, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd231sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t{AppendInstr(I_VFMADD231SD, 0xB9, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd132ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMADD132SS, 0x99, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd132ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t{AppendInstr(I_VFMADD132SS, 0x99, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd213ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMADD213SS, 0xA9, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd213ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t{AppendInstr(I_VFMADD213SS, 0xA9, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd231ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMADD231SS, 0xB9, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmadd231ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t{AppendInstr(I_VFMADD231SS, 0xB9, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmaddsub132pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMADDSUB132PD, 0x96, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmaddsub132pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFMADDSUB132PD, 0x96, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmaddsub132pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFMADDSUB132PD, 0x96, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmaddsub132pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFMADDSUB132PD, 0x96, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmaddsub213pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMADDSUB213PD, 0xA6, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmaddsub213pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFMADDSUB213PD, 0xA6, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmaddsub213pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFMADDSUB213PD, 0xA6, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmaddsub213pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFMADDSUB213PD, 0xA6, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmaddsub231pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMADDSUB231PD, 0xB6, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmaddsub231pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFMADDSUB231PD, 0xB6, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmaddsub231pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFMADDSUB231PD, 0xB6, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmaddsub231pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFMADDSUB231PD, 0xB6, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmaddsub132ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMADDSUB132PS, 0x96, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmaddsub132ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFMADDSUB132PS, 0x96, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmaddsub132ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFMADDSUB132PS, 0x96, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmaddsub132ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFMADDSUB132PS, 0x96, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmaddsub213ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMADDSUB213PS, 0xA6, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmaddsub213ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFMADDSUB213PS, 0xA6, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmaddsub213ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFMADDSUB213PS, 0xA6, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmaddsub213ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFMADDSUB213PS, 0xA6, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmaddsub231ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMADDSUB231PS, 0xB6, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmaddsub231ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFMADDSUB231PS, 0xB6, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmaddsub231ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFMADDSUB231PS, 0xB6, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmaddsub231ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFMADDSUB231PS, 0xB6, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsubadd132pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMSUBADD132PD, 0x97, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsubadd132pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFMSUBADD132PD, 0x97, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsubadd132pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFMSUBADD132PD, 0x97, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsubadd132pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFMSUBADD132PD, 0x97, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsubadd213pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMSUBADD213PD, 0xA7, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsubadd213pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFMSUBADD213PD, 0xA7, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsubadd213pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFMSUBADD213PD, 0xA7, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsubadd213pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFMSUBADD213PD, 0xA7, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsubadd231pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMSUBADD231PD, 0xB7, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsubadd231pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFMSUBADD231PD, 0xB7, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsubadd231pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFMSUBADD231PD, 0xB7, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsubadd231pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFMSUBADD231PD, 0xB7, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsubadd132ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMSUBADD132PS, 0x97, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsubadd132ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFMSUBADD132PS, 0x97, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsubadd132ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFMSUBADD132PS, 0x97, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsubadd132ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFMSUBADD132PS, 0x97, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsubadd213ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMSUBADD213PS, 0xA7, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsubadd213ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFMSUBADD213PS, 0xA7, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsubadd213ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFMSUBADD213PS, 0xA7, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsubadd213ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFMSUBADD213PS, 0xA7, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsubadd231ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMSUBADD231PS, 0xB7, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsubadd231ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFMSUBADD231PS, 0xB7, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsubadd231ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFMSUBADD231PS, 0xB7, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsubadd231ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFMSUBADD231PS, 0xB7, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub132pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMSUB132PD, 0x9A, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub132pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFMSUB132PD, 0x9A, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub132pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFMSUB132PD, 0x9A, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub132pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFMSUB132PD, 0x9A, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub213pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMSUB213PD, 0xAA, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub213pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFMSUB213PD, 0xAA, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub213pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFMSUB213PD, 0xAA, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub213pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFMSUB213PD, 0xAA, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub231pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMSUB231PD, 0xBA, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub231pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFMSUB231PD, 0xBA, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub231pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFMSUB231PD, 0xBA, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub231pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFMSUB231PD, 0xBA, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub132ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMSUB132PS, 0x9A, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub132ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFMSUB132PS, 0x9A, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub132ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFMSUB132PS, 0x9A, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub132ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFMSUB132PS, 0x9A, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub213ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMSUB213PS, 0xAA, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub213ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFMSUB213PS, 0xAA, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub213ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFMSUB213PS, 0xAA, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub213ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFMSUB213PS, 0xAA, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub231ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMSUB231PS, 0xBA, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub231ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFMSUB231PS, 0xBA, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub231ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFMSUB231PS, 0xBA, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub231ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFMSUB231PS, 0xBA, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub132sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMSUB132SD, 0x9B, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub132sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t{AppendInstr(I_VFMSUB132SD, 0x9B, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub213sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMSUB213SD, 0xAB, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub213sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t{AppendInstr(I_VFMSUB213SD, 0xAB, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub231sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMSUB231SD, 0xBB, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub231sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t{AppendInstr(I_VFMSUB231SD, 0xBB, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub132ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMSUB132SS, 0x9B, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub132ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t{AppendInstr(I_VFMSUB132SS, 0x9B, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub213ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMSUB213SS, 0xAB, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub213ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t{AppendInstr(I_VFMSUB213SS, 0xAB, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub231ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFMSUB231SS, 0xBB, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfmsub231ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t{AppendInstr(I_VFMSUB231SS, 0xBB, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd132pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFNMADD132PD, 0x9C, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd132pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFNMADD132PD, 0x9C, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd132pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFNMADD132PD, 0x9C, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd132pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFNMADD132PD, 0x9C, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd213pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFNMADD213PD, 0xAC, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd213pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFNMADD213PD, 0xAC, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd213pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFNMADD213PD, 0xAC, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd213pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFNMADD213PD, 0xAC, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd231pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFNMADD231PD, 0xBC, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd231pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFNMADD231PD, 0xBC, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd231pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFNMADD231PD, 0xBC, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd231pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFNMADD231PD, 0xBC, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd132ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFNMADD132PS, 0x9C, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd132ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFNMADD132PS, 0x9C, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd132ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFNMADD132PS, 0x9C, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd132ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFNMADD132PS, 0x9C, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd213ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFNMADD213PS, 0xAC, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd213ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFNMADD213PS, 0xAC, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd213ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFNMADD213PS, 0xAC, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd213ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFNMADD213PS, 0xAC, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd231ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFNMADD231PS, 0xBC, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd231ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFNMADD231PS, 0xBC, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd231ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFNMADD231PS, 0xBC, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd231ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFNMADD231PS, 0xBC, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd132sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFNMADD132SD, 0x9D, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd132sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t\t{AppendInstr(I_VFNMADD132SD, 0x9D, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd213sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFNMADD213SD, 0xAD, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd213sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t\t{AppendInstr(I_VFNMADD213SD, 0xAD, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd231sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFNMADD231SD, 0xBD, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd231sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t\t{AppendInstr(I_VFNMADD231SD, 0xBD, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd132ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFNMADD132SS, 0x9D, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd132ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t\t{AppendInstr(I_VFNMADD132SS, 0x9D, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd213ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFNMADD213SS, 0xAD, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd213ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t\t{AppendInstr(I_VFNMADD213SS, 0xAD, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd231ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFNMADD231SS, 0xBD, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmadd231ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t\t{AppendInstr(I_VFNMADD231SS, 0xBD, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub132pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFNMSUB132PD, 0x9E, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub132pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFNMSUB132PD, 0x9E, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub132pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFNMSUB132PD, 0x9E, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub132pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFNMSUB132PD, 0x9E, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub213pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFNMSUB213PD, 0xAE, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub213pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFNMSUB213PD, 0xAE, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub213pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFNMSUB213PD, 0xAE, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub213pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFNMSUB213PD, 0xAE, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub231pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFNMSUB231PD, 0xBE, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub231pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFNMSUB231PD, 0xBE, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub231pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFNMSUB231PD, 0xBE, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub231pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFNMSUB231PD, 0xBE, E_VEX_256_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub132ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFNMSUB132PS, 0x9E, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub132ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFNMSUB132PS, 0x9E, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub132ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFNMSUB132PS, 0x9E, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub132ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFNMSUB132PS, 0x9E, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub213ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFNMSUB213PS, 0xAE, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub213ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFNMSUB213PS, 0xAE, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub213ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFNMSUB213PS, 0xAE, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub213ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFNMSUB213PS, 0xAE, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub231ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFNMSUB231PS, 0xBE, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub231ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2)\t{AppendInstr(I_VFNMSUB231PS, 0xBE, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub231ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_VFNMSUB231PS, 0xBE, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub231ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_VFNMSUB231PS, 0xBE, E_VEX_256_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub132sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFNMSUB132SD, 0x9F, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub132sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t\t{AppendInstr(I_VFNMSUB132SD, 0x9F, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub213sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFNMSUB213SD, 0xAF, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub213sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t\t{AppendInstr(I_VFNMSUB213SD, 0xAF, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub231sd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFNMSUB231SD, 0xBF, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub231sd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t\t{AppendInstr(I_VFNMSUB231SD, 0xBF, E_VEX_128_66_0F38_W1, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub132ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFNMSUB132SS, 0x9F, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub132ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t\t{AppendInstr(I_VFNMSUB132SS, 0x9F, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub213ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFNMSUB213SS, 0xAF, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub213ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t\t{AppendInstr(I_VFNMSUB213SS, 0xAF, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub231ss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2)\t{AppendInstr(I_VFNMSUB231SS, 0xBF, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\tvoid vfnmsub231ss(const XmmReg& dst, const XmmReg& src1, const Mem64& src2)\t\t{AppendInstr(I_VFNMSUB231SS, 0xBF, E_VEX_128_66_0F38_W0, RW(dst), R(src2), R(src1));}\n\n\t// F16C\n#ifdef JITASM64\n\tvoid rdfsbase(const Reg32& dst)\t{AppendInstr(I_RDFSBASE, 0x0FAE, E_MANDATORY_PREFIX_F3, Imm8(0), W(dst));}\n\tvoid rdfsbase(const Reg64& dst)\t{AppendInstr(I_RDFSBASE, 0x0FAE, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, Imm8(0), W(dst));}\n\tvoid rdgsbase(const Reg32& dst)\t{AppendInstr(I_RDGSBASE, 0x0FAE, E_MANDATORY_PREFIX_F3, Imm8(1), W(dst));}\n\tvoid rdgsbase(const Reg64& dst)\t{AppendInstr(I_RDGSBASE, 0x0FAE, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, Imm8(1), W(dst));}\n#endif\n\tvoid rdrand(const Reg16& dst)\t{AppendInstr(I_RDRAND, 0x0FC7, E_OPERAND_SIZE_PREFIX, Imm8(6), W(dst));}\n\tvoid rdrand(const Reg32& dst)\t{AppendInstr(I_RDRAND, 0x0FC7, 0, Imm8(6), W(dst));}\n#ifdef JITASM64\n\tvoid rdrand(const Reg64& dst)\t{AppendInstr(I_RDRAND, 0x0FC7, E_REXW_PREFIX, Imm8(6), W(dst));}\n#endif\n#ifdef JITASM64\n\tvoid wrfsbase(const Reg32& src)\t{AppendInstr(I_WRFSBASE, 0x0FAE, E_MANDATORY_PREFIX_F3, Imm8(2), R(src));}\n\tvoid wrfsbase(const Reg64& src)\t{AppendInstr(I_WRFSBASE, 0x0FAE, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, Imm8(2), R(src));}\n\tvoid wrgsbase(const Reg32& src)\t{AppendInstr(I_WRGSBASE, 0x0FAE, E_MANDATORY_PREFIX_F3, Imm8(3), R(src));}\n\tvoid wrgsbase(const Reg64& src)\t{AppendInstr(I_WRGSBASE, 0x0FAE, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, Imm8(3), R(src));}\n#endif\n\tvoid vcvtph2ps(const YmmReg& dst, const XmmReg& src)\t{AppendInstr(I_VCVTPH2PS, 0x13, E_VEX_256_66_0F38_W0, W(dst), R(src));}\n\tvoid vcvtph2ps(const YmmReg& dst, const Mem128& src)\t{AppendInstr(I_VCVTPH2PS, 0x13, E_VEX_256_66_0F38_W0, W(dst), R(src));}\n\tvoid vcvtph2ps(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_VCVTPH2PS, 0x13, E_VEX_128_66_0F38_W0, W(dst), R(src));}\n\tvoid vcvtph2ps(const XmmReg& dst, const Mem64& src)\t\t{AppendInstr(I_VCVTPH2PS, 0x13, E_VEX_128_66_0F38_W0, W(dst), R(src));}\n\tvoid vcvtps2ph(const XmmReg& dst, const YmmReg& src, const Imm8& rc)\t{AppendInstr(I_VCVTPS2PH, 0x1D, E_VEX_256_66_0F3A_W0, R(src), W(dst), rc);}\n\tvoid vcvtps2ph(const Mem128& dst, const YmmReg& src, const Imm8& rc)\t{AppendInstr(I_VCVTPS2PH, 0x1D, E_VEX_256_66_0F3A_W0, R(src), W(dst), rc);}\n\tvoid vcvtps2ph(const XmmReg& dst, const XmmReg& src, const Imm8& rc)\t{AppendInstr(I_VCVTPS2PH, 0x1D, E_VEX_128_66_0F3A_W0, R(src), W(dst), rc);}\n\tvoid vcvtps2ph(const Mem64& dst, const XmmReg& src, const Imm8& rc)\t\t{AppendInstr(I_VCVTPS2PH, 0x1D, E_VEX_128_66_0F3A_W0, R(src), W(dst), rc);}\n\n\t// BMI2\n\tvoid andn(const Reg32& dst, const Reg32& src1, const Reg32& src2)\t{AppendInstr(I_ANDN, 0xF2, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, W(dst), R(src2), R(src1));}\n\tvoid andn(const Reg32& dst, const Reg32& src1, const Mem32& src2)\t{AppendInstr(I_ANDN, 0xF2, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, W(dst), R(src2), R(src1));}\n#ifdef JITASM64\n\tvoid andn(const Reg64& dst, const Reg64& src1, const Reg64& src2)\t{AppendInstr(I_ANDN, 0xF2, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, W(dst), R(src2), R(src1));}\n\tvoid andn(const Reg64& dst, const Reg64& src1, const Mem64& src2)\t{AppendInstr(I_ANDN, 0xF2, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, W(dst), R(src2), R(src1));}\n#endif\n\tvoid bextr(const Reg32& dst, const Reg32& src1, const Reg32& src2)\t{AppendInstr(I_BEXTR, 0xF7, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));}\n\tvoid bextr(const Reg32& dst, const Mem32& src1, const Reg32& src2)\t{AppendInstr(I_BEXTR, 0xF7, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));}\n#ifdef JITASM64\n\tvoid bextr(const Reg64& dst, const Reg64& src1, const Reg64& src2)\t{AppendInstr(I_BEXTR, 0xF7, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));}\n\tvoid bextr(const Reg64& dst, const Mem64& src1, const Reg64& src2)\t{AppendInstr(I_BEXTR, 0xF7, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));}\n#endif\n\tvoid blsi(const Reg32& dst, const Reg32& src)\t{AppendInstr(I_BLSI, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, Imm8(3), R(src), W(dst));}\n\tvoid blsi(const Reg32& dst, const Mem32& src)\t{AppendInstr(I_BLSI, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, Imm8(3), R(src), W(dst));}\n#ifdef JITASM64\n\tvoid blsi(const Reg64& dst, const Reg64& src)\t{AppendInstr(I_BLSI, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, Imm8(3), R(src), W(dst));}\n\tvoid blsi(const Reg64& dst, const Mem64& src)\t{AppendInstr(I_BLSI, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, Imm8(3), R(src), W(dst));}\n#endif\n\tvoid blsmsk(const Reg32& dst, const Reg32& src)\t{AppendInstr(I_BLSMSK, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, Imm8(2), R(src), W(dst));}\n\tvoid blsmsk(const Reg32& dst, const Mem32& src)\t{AppendInstr(I_BLSMSK, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, Imm8(2), R(src), W(dst));}\n#ifdef JITASM64\n\tvoid blsmsk(const Reg64& dst, const Reg64& src)\t{AppendInstr(I_BLSMSK, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, Imm8(2), R(src), W(dst));}\n\tvoid blsmsk(const Reg64& dst, const Mem64& src)\t{AppendInstr(I_BLSMSK, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, Imm8(2), R(src), W(dst));}\n#endif\n\tvoid blsr(const Reg32& dst, const Reg32& src)\t{AppendInstr(I_BLSR, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, Imm8(1), R(src), W(dst));}\n\tvoid blsr(const Reg32& dst, const Mem32& src)\t{AppendInstr(I_BLSR, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, Imm8(1), R(src), W(dst));}\n#ifdef JITASM64\n\tvoid blsr(const Reg64& dst, const Reg64& src)\t{AppendInstr(I_BLSR, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, Imm8(1), R(src), W(dst));}\n\tvoid blsr(const Reg64& dst, const Mem64& src)\t{AppendInstr(I_BLSR, 0xF3, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, Imm8(1), R(src), W(dst));}\n#endif\n\tvoid bzhi(const Reg32& dst, const Reg32& src1, const Reg32& src2)\t{AppendInstr(I_BZHI, 0xF5, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));}\n\tvoid bzhi(const Reg32& dst, const Mem32& src1, const Reg32& src2)\t{AppendInstr(I_BZHI, 0xF5, E_VEX_LZ | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));}\n#ifdef JITASM64\n\tvoid bzhi(const Reg64& dst, const Reg64& src1, const Reg64& src2)\t{AppendInstr(I_BZHI, 0xF5, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));}\n\tvoid bzhi(const Reg64& dst, const Mem64& src1, const Reg64& src2)\t{AppendInstr(I_BZHI, 0xF5, E_VEX_LZ | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));}\n#endif\n\tvoid lzcnt(const Reg16& dst, const Reg16& src)\t{AppendInstr(I_LZCNT, 0x0FBD, E_MANDATORY_PREFIX_F3 | E_OPERAND_SIZE_PREFIX, W(dst), R(src));}\n\tvoid lzcnt(const Reg16& dst, const Mem16& src)\t{AppendInstr(I_LZCNT, 0x0FBD, E_MANDATORY_PREFIX_F3 | E_OPERAND_SIZE_PREFIX, W(dst), R(src));}\n\tvoid lzcnt(const Reg32& dst, const Reg32& src)\t{AppendInstr(I_LZCNT, 0x0FBD, E_MANDATORY_PREFIX_F3, W(dst), R(src));}\n\tvoid lzcnt(const Reg32& dst, const Mem32& src)\t{AppendInstr(I_LZCNT, 0x0FBD, E_MANDATORY_PREFIX_F3, W(dst), R(src));}\n#ifdef JITASM64\n\tvoid lzcnt(const Reg64& dst, const Reg64& src)\t{AppendInstr(I_LZCNT, 0x0FBD, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));}\n\tvoid lzcnt(const Reg64& dst, const Mem64& src)\t{AppendInstr(I_LZCNT, 0x0FBD, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));}\n#endif\n\tvoid mulx(const Reg32& dst1, const Reg32& dst2, const Reg32& src1, const Reg32& src2)\t{AppendInstr(I_MULX, 0xF6, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W0, W(dst1), R(src2), W(dst2), Dummy(R(src1), edx));}\n\tvoid mulx(const Reg32& dst1, const Reg32& dst2, const Reg32& src1, const Mem32& src2)\t{AppendInstr(I_MULX, 0xF6, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W0, W(dst1), R(src2), W(dst2), Dummy(R(src1), edx));}\n#ifdef JITASM64\n\tvoid mulx(const Reg64& dst1, const Reg64& dst2, const Reg64& src1, const Reg64& src2)\t{AppendInstr(I_MULX, 0xF6, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W1, W(dst1), R(src2), W(dst2), Dummy(R(src1), rdx));}\n\tvoid mulx(const Reg64& dst1, const Reg64& dst2, const Reg64& src1, const Mem64& src2)\t{AppendInstr(I_MULX, 0xF6, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W1, W(dst1), R(src2), W(dst2), Dummy(R(src1), rdx));}\n#endif\n\tvoid pdep(const Reg32& dst, const Reg32& src1, const Reg32& src2)\t{AppendInstr(I_PDEP, 0xF5, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src2), R(src1));}\n\tvoid pdep(const Reg32& dst, const Reg32& src1, const Mem32& src2)\t{AppendInstr(I_PDEP, 0xF5, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src2), R(src1));}\n#ifdef JITASM64\n\tvoid pdep(const Reg64& dst, const Reg64& src1, const Reg64& src2)\t{AppendInstr(I_PDEP, 0xF5, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src2), R(src1));}\n\tvoid pdep(const Reg64& dst, const Reg64& src1, const Mem64& src2)\t{AppendInstr(I_PDEP, 0xF5, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src2), R(src1));}\n#endif\n\tvoid pext(const Reg32& dst, const Reg32& src1, const Reg32& src2)\t{AppendInstr(I_PEXT, 0xF5, E_VEX_LZ | E_VEX_F3 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src2), R(src1));}\n\tvoid pext(const Reg32& dst, const Reg32& src1, const Mem32& src2)\t{AppendInstr(I_PEXT, 0xF5, E_VEX_LZ | E_VEX_F3 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src2), R(src1));}\n#ifdef JITASM64\n\tvoid pext(const Reg64& dst, const Reg64& src1, const Reg64& src2)\t{AppendInstr(I_PEXT, 0xF5, E_VEX_LZ | E_VEX_F3 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src2), R(src1));}\n\tvoid pext(const Reg64& dst, const Reg64& src1, const Mem64& src2)\t{AppendInstr(I_PEXT, 0xF5, E_VEX_LZ | E_VEX_F3 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src2), R(src1));}\n#endif\n\tvoid rorx(const Reg32& dst, const Reg32& src, const Imm8& shift)\t{AppendInstr(I_RORX, 0xF0, E_VEX_LZ | E_VEX_F2 | E_VEX_0F3A | E_VEX_W0, W(dst), R(src), shift);}\n\tvoid rorx(const Reg32& dst, const Mem32& src, const Imm8& shift)\t{AppendInstr(I_RORX, 0xF0, E_VEX_LZ | E_VEX_F2 | E_VEX_0F3A | E_VEX_W0, W(dst), R(src), shift);}\n#ifdef JITASM64\n\tvoid rorx(const Reg64& dst, const Reg64& src, const Imm8& shift)\t{AppendInstr(I_RORX, 0xF0, E_VEX_LZ | E_VEX_F2 | E_VEX_0F3A | E_VEX_W1, W(dst), R(src), shift);}\n\tvoid rorx(const Reg64& dst, const Mem64& src, const Imm8& shift)\t{AppendInstr(I_RORX, 0xF0, E_VEX_LZ | E_VEX_F2 | E_VEX_0F3A | E_VEX_W1, W(dst), R(src), shift);}\n#endif\n\tvoid sarx(const Reg32& dst, const Reg32& src1, const Reg32& src2)\t{AppendInstr(I_SARX, 0xF7, E_VEX_LZ | E_VEX_F3 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));}\n\tvoid sarx(const Reg32& dst, const Mem32& src1, const Reg32& src2)\t{AppendInstr(I_SARX, 0xF7, E_VEX_LZ | E_VEX_F3 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));}\n#ifdef JITASM64\n\tvoid sarx(const Reg64& dst, const Reg64& src1, const Reg64& src2)\t{AppendInstr(I_SARX, 0xF7, E_VEX_LZ | E_VEX_F3 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));}\n\tvoid sarx(const Reg64& dst, const Mem64& src1, const Reg64& src2)\t{AppendInstr(I_SARX, 0xF7, E_VEX_LZ | E_VEX_F3 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));}\n#endif\n\tvoid shlx(const Reg32& dst, const Reg32& src1, const Reg32& src2)\t{AppendInstr(I_SHLX, 0xF7, E_VEX_LZ | E_VEX_66 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));}\n\tvoid shlx(const Reg32& dst, const Mem32& src1, const Reg32& src2)\t{AppendInstr(I_SHLX, 0xF7, E_VEX_LZ | E_VEX_66 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));}\n#ifdef JITASM64\n\tvoid shlx(const Reg64& dst, const Reg64& src1, const Reg64& src2)\t{AppendInstr(I_SHLX, 0xF7, E_VEX_LZ | E_VEX_66 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));}\n\tvoid shlx(const Reg64& dst, const Mem64& src1, const Reg64& src2)\t{AppendInstr(I_SHLX, 0xF7, E_VEX_LZ | E_VEX_66 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));}\n#endif\n\tvoid shrx(const Reg32& dst, const Reg32& src1, const Reg32& src2)\t{AppendInstr(I_SHRX, 0xF7, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));}\n\tvoid shrx(const Reg32& dst, const Mem32& src1, const Reg32& src2)\t{AppendInstr(I_SHRX, 0xF7, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W0, W(dst), R(src1), R(src2));}\n#ifdef JITASM64\n\tvoid shrx(const Reg64& dst, const Reg64& src1, const Reg64& src2)\t{AppendInstr(I_SHRX, 0xF7, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));}\n\tvoid shrx(const Reg64& dst, const Mem64& src1, const Reg64& src2)\t{AppendInstr(I_SHRX, 0xF7, E_VEX_LZ | E_VEX_F2 | E_VEX_0F38 | E_VEX_W1, W(dst), R(src1), R(src2));}\n#endif\n\tvoid tzcnt(const Reg16& dst, const Reg16& src)\t{AppendInstr(I_TZCNT, 0x0FBC, E_MANDATORY_PREFIX_F3 | E_OPERAND_SIZE_PREFIX, W(dst), R(src));}\n\tvoid tzcnt(const Reg16& dst, const Mem16& src)\t{AppendInstr(I_TZCNT, 0x0FBC, E_MANDATORY_PREFIX_F3 | E_OPERAND_SIZE_PREFIX, W(dst), R(src));}\n\tvoid tzcnt(const Reg32& dst, const Reg32& src)\t{AppendInstr(I_TZCNT, 0x0FBC, E_MANDATORY_PREFIX_F3, W(dst), R(src));}\n\tvoid tzcnt(const Reg32& dst, const Mem32& src)\t{AppendInstr(I_TZCNT, 0x0FBC, E_MANDATORY_PREFIX_F3, W(dst), R(src));}\n#ifdef JITASM64\n\tvoid tzcnt(const Reg64& dst, const Reg64& src)\t{AppendInstr(I_TZCNT, 0x0FBC, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));}\n\tvoid tzcnt(const Reg64& dst, const Mem64& src)\t{AppendInstr(I_TZCNT, 0x0FBC, E_MANDATORY_PREFIX_F3 | E_REXW_PREFIX, W(dst), R(src));}\n#endif\n#ifndef JITASM64\n\tvoid invpcid(const Reg32& type, const Mem128& desc)\t{AppendInstr(I_INVPCID, 0x0F3882, E_MANDATORY_PREFIX_66, W(type), R(desc));}\n#else\n\tvoid invpcid(const Reg64& type, const Mem128& desc)\t{AppendInstr(I_INVPCID, 0x0F3882, E_MANDATORY_PREFIX_66, W(type), R(desc));}\n#endif\n\n\t// XOP\n\tvoid vfrczpd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_VFRCZPD, 0x81, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vfrczpd(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_VFRCZPD, 0x81, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vfrczpd(const YmmReg& dst, const YmmReg& src)\t{AppendInstr(I_VFRCZPD, 0x81, E_XOP_256 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vfrczpd(const YmmReg& dst, const Mem256& src)\t{AppendInstr(I_VFRCZPD, 0x81, E_XOP_256 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vfrczps(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_VFRCZPS, 0x80, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vfrczps(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_VFRCZPS, 0x80, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vfrczps(const YmmReg& dst, const YmmReg& src)\t{AppendInstr(I_VFRCZPS, 0x80, E_XOP_256 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vfrczps(const YmmReg& dst, const Mem256& src)\t{AppendInstr(I_VFRCZPS, 0x80, E_XOP_256 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vfrczsd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_VFRCZSD, 0x83, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vfrczsd(const XmmReg& dst, const Mem64& src)\t{AppendInstr(I_VFRCZSD, 0x83, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vfrczss(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_VFRCZSS, 0x82, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vfrczss(const XmmReg& dst, const Mem32& src)\t{AppendInstr(I_VFRCZSS, 0x82, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vpcmov(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VPCMOV, 0xA2, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpcmov(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VPCMOV, 0xA2, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpcmov(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3)\t{AppendInstr(I_VPCMOV, 0xA2, E_XOP_128 | E_XOP_M01000 | E_XOP_W1 | E_XOP_P00, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vpcmov(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3)\t{AppendInstr(I_VPCMOV, 0xA2, E_XOP_256 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpcmov(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3)\t{AppendInstr(I_VPCMOV, 0xA2, E_XOP_256 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpcmov(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3)\t{AppendInstr(I_VPCMOV, 0xA2, E_XOP_256 | E_XOP_M01000 | E_XOP_W1 | E_XOP_P00, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vpcomb(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& type)\t{AppendInstr(I_VPCOMB, 0xCC, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}\n\tvoid vpcomb(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& type)\t{AppendInstr(I_VPCOMB, 0xCC, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}\n\tvoid vpcomd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& type)\t{AppendInstr(I_VPCOMD, 0xCE, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}\n\tvoid vpcomd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& type)\t{AppendInstr(I_VPCOMD, 0xCE, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}\n\tvoid vpcomq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& type)\t{AppendInstr(I_VPCOMQ, 0xCF, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}\n\tvoid vpcomq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& type)\t{AppendInstr(I_VPCOMQ, 0xCF, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}\n\t//void vpcomub(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& type)\t{AppendInstr(I_VPCOMUB, 0x6C, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}\n\t//void vpcomub(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& type)\t{AppendInstr(I_VPCOMUB, 0x6C, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}\n\t//void vpcomud(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& type)\t{AppendInstr(I_VPCOMUD, 0x6E, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}\n\t//void vpcomud(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& type)\t{AppendInstr(I_VPCOMUD, 0x6E, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}\n\t//void vpcomuq(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& type)\t{AppendInstr(I_VPCOMUQ, 0x6F, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}\n\t//void vpcomuq(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& type)\t{AppendInstr(I_VPCOMUQ, 0x6F, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}\n\t//void vpcomuw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& type)\t{AppendInstr(I_VPCOMUW, 0x6D, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}\n\t//void vpcomuw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& type)\t{AppendInstr(I_VPCOMUW, 0x6D, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}\n\t//void vpcomw(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& type)\t{AppendInstr(I_VPCOMW, 0xCD, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}\n\t//void vpcomw(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& type)\t{AppendInstr(I_VPCOMW, 0xCD, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), type);}\n\t//void vpermil2pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VPERMIL2PD, 0x49, E_XOP_128 | E_XOP_M00011 | E_XOP_W0 | E_XOP_P01, W(dst), R(src2), R(src1), R(src3));}\n\t//void vpermil2pd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VPERMIL2PD, 0x49, E_XOP_128 | E_XOP_M00011 | E_XOP_W0 | E_XOP_P01, W(dst), R(src2), R(src1), R(src3));}\n\t//void vpermil2pd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3)\t{AppendInstr(I_VPERMIL2PD, 0x49, E_XOP_128 | E_XOP_M00011 | E_XOP_W1 | E_XOP_P01, W(dst), R(src3), R(src1), R(src2));}\n\t//void vpermil2pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3)\t{AppendInstr(I_VPERMIL2PD, 0x49, E_XOP_256 | E_XOP_M00011 | E_XOP_W0 | E_XOP_P01, W(dst), R(src2), R(src1), R(src3));}\n\t//void vpermil2pd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3)\t{AppendInstr(I_VPERMIL2PD, 0x49, E_XOP_256 | E_XOP_M00011 | E_XOP_W0 | E_XOP_P01, W(dst), R(src2), R(src1), R(src3));}\n\t//void vpermil2pd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3)\t{AppendInstr(I_VPERMIL2PD, 0x49, E_XOP_256 | E_XOP_M00011 | E_XOP_W1 | E_XOP_P01, W(dst), R(src3), R(src1), R(src2));}\n\t//void vpermil2ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VPERMIL2PS, 0x48, E_XOP_128 | E_XOP_M00011 | E_XOP_W0 | E_XOP_P01, W(dst), R(src2), R(src1), R(src3));}\n\t//void vpermil2ps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VPERMIL2PS, 0x48, E_XOP_128 | E_XOP_M00011 | E_XOP_W0 | E_XOP_P01, W(dst), R(src2), R(src1), R(src3));}\n\t//void vpermil2ps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3)\t{AppendInstr(I_VPERMIL2PS, 0x48, E_XOP_128 | E_XOP_M00011 | E_XOP_W1 | E_XOP_P01, W(dst), R(src3), R(src1), R(src2));}\n\t//void vpermil2ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3)\t{AppendInstr(I_VPERMIL2PS, 0x48, E_XOP_256 | E_XOP_M00011 | E_XOP_W0 | E_XOP_P01, W(dst), R(src2), R(src1), R(src3));}\n\t//void vpermil2ps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3)\t{AppendInstr(I_VPERMIL2PS, 0x48, E_XOP_256 | E_XOP_M00011 | E_XOP_W0 | E_XOP_P01, W(dst), R(src2), R(src1), R(src3));}\n\t//void vpermil2ps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3)\t{AppendInstr(I_VPERMIL2PS, 0x48, E_XOP_256 | E_XOP_M00011 | E_XOP_W1 | E_XOP_P01, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vphaddbd(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_VPHADDBD, 0xC2, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vphaddbd(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_VPHADDBD, 0xC2, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vphaddbq(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_VPHADDBQ, 0xC3, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vphaddbq(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_VPHADDBQ, 0xC3, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vphaddbw(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_VPHADDBW, 0xC1, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vphaddbw(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_VPHADDBW, 0xC1, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vphadddq(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_VPHADDDQ, 0xCB, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vphadddq(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_VPHADDDQ, 0xCB, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vphaddubd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_VPHADDUBD, 0xD2, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vphaddubd(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_VPHADDUBD, 0xD2, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vphaddubq(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_VPHADDUBQ, 0xD3, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vphaddubq(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_VPHADDUBQ, 0xD3, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vphaddubw(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_VPHADDUBW, 0xD1, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vphaddubw(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_VPHADDUBW, 0xD1, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\t//void vphaddudq(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_VPHADDUDQ, 0xDB, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\t//void vphaddudq(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_VPHADDUDQ, 0xDB, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vphadduwd(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_VPHADDUWD, 0xD6, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vphadduwd(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_VPHADDUWD, 0xD6, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vphadduwq(const XmmReg& dst, const XmmReg& src)\t{AppendInstr(I_VPHADDUWQ, 0xD7, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vphadduwq(const XmmReg& dst, const Mem128& src)\t{AppendInstr(I_VPHADDUWQ, 0xD7, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vphaddwd(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_VPHADDUWD, 0xC6, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vphaddwd(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_VPHADDUWD, 0xC6, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vphaddwq(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_VPHADDWQ, 0xC7, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vphaddwq(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_VPHADDWQ, 0xC7, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vphsubbw(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_VPHSUBBW, 0xE1, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vphsubbw(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_VPHSUBBW, 0xE1, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\t//void vphsubdq(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_VPHSUBDQ, 0xDB, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\t//void vphsubdq(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_VPHSUBDQ, 0xDB, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vphsubwd(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_VPHSUBWD, 0xE2, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vphsubwd(const XmmReg& dst, const Mem128& src)\t\t{AppendInstr(I_VPHSUBWD, 0xE2, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src));}\n\tvoid vpmacsdd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VPMACSDD, 0x9E, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpmacsdd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VPMACSDD, 0x9E, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpmacsdqh(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VPMACSDQH, 0x9F, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpmacsdqh(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VPMACSDQH, 0x9F, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpmacsdql(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VPMACSDQL, 0x97, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpmacsdql(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VPMACSDQL, 0x97, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpmacssdd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VPMACSSDD, 0x8E, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpmacssdd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VPMACSSDD, 0x8E, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpmacssdqh(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VPMACSSDQH, 0x8F, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpmacssdqh(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VPMACSSDQH, 0x8F, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpmacssdql(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VPMACSSDQL, 0x87, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpmacssdql(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VPMACSSDQL, 0x87, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpmacsswd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VPMACSSWD, 0x86, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpmacsswd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VPMACSSWD, 0x86, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpmacssww(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VPMACSSWW, 0x85, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpmacssww(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VPMACSSWW, 0x85, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpmacswd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VPMACSWD, 0x96, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpmacswd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VPMACSWD, 0x96, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpmacsww(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VPMACSWW, 0x95, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpmacsww(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VPMACSWW, 0x95, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpmadcsswd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VPMADCSSWD, 0xA6, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpmadcsswd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VPMADCSSWD, 0xA6, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpmadcswd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VPMADCSWD, 0xB6, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpmadcswd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VPMADCSWD, 0xB6, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpperm(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VPPERM, 0xA3, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpperm(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VPPERM, 0xA3, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vpperm(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3)\t{AppendInstr(I_VPPERM, 0xA3, E_XOP_128 | E_XOP_M01000 | E_XOP_W1 | E_XOP_P00, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vprotb(const XmmReg& dst, const XmmReg& src1, const XmmReg& count)\t{AppendInstr(I_VPROTB, 0x90, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}\n\tvoid vprotb(const XmmReg& dst, const Mem128& src1, const XmmReg& count)\t{AppendInstr(I_VPROTB, 0x90, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}\n\tvoid vprotb(const XmmReg& dst, const XmmReg& src1, const Mem128& count)\t{AppendInstr(I_VPROTB, 0x90, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));}\n\tvoid vprotb(const XmmReg& dst, const XmmReg& src1, const Imm8& count)\t{AppendInstr(I_VPROTB, 0xC0, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), count);}\n\tvoid vprotb(const XmmReg& dst, const Mem128& src1, const Imm8& count)\t{AppendInstr(I_VPROTB, 0xC0, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), count);}\n\tvoid vprotd(const XmmReg& dst, const XmmReg& src1, const XmmReg& count)\t{AppendInstr(I_VPROTD, 0x92, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}\n\tvoid vprotd(const XmmReg& dst, const Mem128& src1, const XmmReg& count)\t{AppendInstr(I_VPROTD, 0x92, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}\n\tvoid vprotd(const XmmReg& dst, const XmmReg& src1, const Mem128& count)\t{AppendInstr(I_VPROTD, 0x92, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));}\n\tvoid vprotd(const XmmReg& dst, const XmmReg& src1, const Imm8& count)\t{AppendInstr(I_VPROTD, 0xC2, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), count);}\n\tvoid vprotd(const XmmReg& dst, const Mem128& src1, const Imm8& count)\t{AppendInstr(I_VPROTD, 0xC2, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), count);}\n\tvoid vprotq(const XmmReg& dst, const XmmReg& src1, const XmmReg& count)\t{AppendInstr(I_VPROTQ, 0x93, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}\n\tvoid vprotq(const XmmReg& dst, const Mem128& src1, const XmmReg& count)\t{AppendInstr(I_VPROTQ, 0x93, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}\n\tvoid vprotq(const XmmReg& dst, const XmmReg& src1, const Mem128& count)\t{AppendInstr(I_VPROTQ, 0x93, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));}\n\tvoid vprotq(const XmmReg& dst, const XmmReg& src1, const Imm8& count)\t{AppendInstr(I_VPROTQ, 0xC3, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), count);}\n\tvoid vprotq(const XmmReg& dst, const Mem128& src1, const Imm8& count)\t{AppendInstr(I_VPROTQ, 0xC3, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), count);}\n\tvoid vprotw(const XmmReg& dst, const XmmReg& src1, const XmmReg& count)\t{AppendInstr(I_VPROTW, 0x91, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}\n\tvoid vprotw(const XmmReg& dst, const Mem128& src1, const XmmReg& count)\t{AppendInstr(I_VPROTW, 0x91, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}\n\tvoid vprotw(const XmmReg& dst, const XmmReg& src1, const Mem128& count)\t{AppendInstr(I_VPROTW, 0x91, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));}\n\tvoid vprotw(const XmmReg& dst, const XmmReg& src1, const Imm8& count)\t{AppendInstr(I_VPROTW, 0xC1, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), count);}\n\tvoid vprotw(const XmmReg& dst, const Mem128& src1, const Imm8& count)\t{AppendInstr(I_VPROTW, 0xC1, E_XOP_128 | E_XOP_M01000 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), count);}\n\tvoid vpshab(const XmmReg& dst, const XmmReg& src1, const XmmReg& count)\t{AppendInstr(I_VPSHAB, 0x98, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}\n\tvoid vpshab(const XmmReg& dst, const Mem128& src1, const XmmReg& count)\t{AppendInstr(I_VPSHAB, 0x98, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}\n\tvoid vpshab(const XmmReg& dst, const XmmReg& src1, const Mem128& count)\t{AppendInstr(I_VPSHAB, 0x98, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));}\n\tvoid vpshad(const XmmReg& dst, const XmmReg& src1, const XmmReg& count)\t{AppendInstr(I_VPSHAD, 0x9A, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}\n\tvoid vpshad(const XmmReg& dst, const Mem128& src1, const XmmReg& count)\t{AppendInstr(I_VPSHAD, 0x9A, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}\n\tvoid vpshad(const XmmReg& dst, const XmmReg& src1, const Mem128& count)\t{AppendInstr(I_VPSHAD, 0x9A, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));}\n\tvoid vpshaq(const XmmReg& dst, const XmmReg& src1, const XmmReg& count)\t{AppendInstr(I_VPSHAQ, 0x9B, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}\n\tvoid vpshaq(const XmmReg& dst, const Mem128& src1, const XmmReg& count)\t{AppendInstr(I_VPSHAQ, 0x9B, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}\n\tvoid vpshaq(const XmmReg& dst, const XmmReg& src1, const Mem128& count)\t{AppendInstr(I_VPSHAQ, 0x9B, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));}\n\tvoid vpshaw(const XmmReg& dst, const XmmReg& src1, const XmmReg& count)\t{AppendInstr(I_VPSHAW, 0x99, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}\n\tvoid vpshaw(const XmmReg& dst, const Mem128& src1, const XmmReg& count)\t{AppendInstr(I_VPSHAW, 0x99, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}\n\tvoid vpshaw(const XmmReg& dst, const XmmReg& src1, const Mem128& count)\t{AppendInstr(I_VPSHAW, 0x99, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));}\n\tvoid vpshlb(const XmmReg& dst, const XmmReg& src1, const XmmReg& count)\t{AppendInstr(I_VPSHLB, 0x94, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}\n\tvoid vpshlb(const XmmReg& dst, const Mem128& src1, const XmmReg& count)\t{AppendInstr(I_VPSHLB, 0x94, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}\n\tvoid vpshlb(const XmmReg& dst, const XmmReg& src1, const Mem128& count)\t{AppendInstr(I_VPSHLB, 0x94, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));}\n\tvoid vpshld(const XmmReg& dst, const XmmReg& src1, const XmmReg& count)\t{AppendInstr(I_VPSHLD, 0x96, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}\n\tvoid vpshld(const XmmReg& dst, const Mem128& src1, const XmmReg& count)\t{AppendInstr(I_VPSHLD, 0x96, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}\n\tvoid vpshld(const XmmReg& dst, const XmmReg& src1, const Mem128& count)\t{AppendInstr(I_VPSHLD, 0x96, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));}\n\tvoid vpshlq(const XmmReg& dst, const XmmReg& src1, const XmmReg& count)\t{AppendInstr(I_VPSHLQ, 0x97, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}\n\tvoid vpshlq(const XmmReg& dst, const Mem128& src1, const XmmReg& count)\t{AppendInstr(I_VPSHLQ, 0x97, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}\n\tvoid vpshlq(const XmmReg& dst, const XmmReg& src1, const Mem128& count)\t{AppendInstr(I_VPSHLQ, 0x97, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));}\n\tvoid vpshlw(const XmmReg& dst, const XmmReg& src1, const XmmReg& count)\t{AppendInstr(I_VPSHLW, 0x95, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}\n\tvoid vpshlw(const XmmReg& dst, const Mem128& src1, const XmmReg& count)\t{AppendInstr(I_VPSHLW, 0x95, E_XOP_128 | E_XOP_M01001 | E_XOP_W0 | E_XOP_P00, W(dst), R(src1), R(count));}\n\tvoid vpshlw(const XmmReg& dst, const XmmReg& src1, const Mem128& count)\t{AppendInstr(I_VPSHLW, 0x95, E_XOP_128 | E_XOP_M01001 | E_XOP_W1 | E_XOP_P00, W(dst), R(count), R(src1));}\n\n\t// FMA4\n\tvoid vfmaddpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VFMADDPD, 0x69, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmaddpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VFMADDPD, 0x69, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmaddpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3)\t{AppendInstr(I_VFMADDPD, 0x69, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfmaddpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3)\t{AppendInstr(I_VFMADDPD, 0x69, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmaddpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3)\t{AppendInstr(I_VFMADDPD, 0x69, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmaddpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3)\t{AppendInstr(I_VFMADDPD, 0x69, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfmaddps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VFMADDPS, 0x68, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmaddps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VFMADDPS, 0x68, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmaddps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3)\t{AppendInstr(I_VFMADDPS, 0x68, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfmaddps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3)\t{AppendInstr(I_VFMADDPS, 0x68, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmaddps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3)\t{AppendInstr(I_VFMADDPS, 0x68, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmaddps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3)\t{AppendInstr(I_VFMADDPS, 0x68, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfmaddsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VFMADDSD, 0x6B, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmaddsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2, const XmmReg& src3)\t\t{AppendInstr(I_VFMADDSD, 0x6B, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmaddsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem64& src3)\t\t{AppendInstr(I_VFMADDSD, 0x6B, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfmaddss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VFMADDSS, 0x6A, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmaddss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2, const XmmReg& src3)\t\t{AppendInstr(I_VFMADDSS, 0x6A, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmaddss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem32& src3)\t\t{AppendInstr(I_VFMADDSS, 0x6A, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfmaddsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VFMADDSUBPD, 0x5D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmaddsubpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VFMADDSUBPD, 0x5D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmaddsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3)\t{AppendInstr(I_VFMADDSUBPD, 0x5D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfmaddsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3)\t{AppendInstr(I_VFMADDSUBPD, 0x5D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmaddsubpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3)\t{AppendInstr(I_VFMADDSUBPD, 0x5D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmaddsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3)\t{AppendInstr(I_VFMADDSUBPD, 0x5D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfmaddsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VFMADDSUBPS, 0x5C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmaddsubps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VFMADDSUBPS, 0x5C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmaddsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3)\t{AppendInstr(I_VFMADDSUBPS, 0x5C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfmaddsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3)\t{AppendInstr(I_VFMADDSUBPS, 0x5C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmaddsubps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3)\t{AppendInstr(I_VFMADDSUBPS, 0x5C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmaddsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3)\t{AppendInstr(I_VFMADDSUBPS, 0x5C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfmsubaddpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VFMSUBADDPD, 0x5F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmsubaddpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VFMSUBADDPD, 0x5F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmsubaddpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3)\t{AppendInstr(I_VFMSUBADDPD, 0x5F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfmsubaddpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3)\t{AppendInstr(I_VFMSUBADDPD, 0x5F, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmsubaddpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3)\t{AppendInstr(I_VFMSUBADDPD, 0x5F, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmsubaddpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3)\t{AppendInstr(I_VFMSUBADDPD, 0x5F, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfmsubaddps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VFMSUBADDPS, 0x5E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmsubaddps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VFMSUBADDPS, 0x5E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmsubaddps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3)\t{AppendInstr(I_VFMSUBADDPS, 0x5E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfmsubaddps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3)\t{AppendInstr(I_VFMSUBADDPS, 0x5E, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmsubaddps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3)\t{AppendInstr(I_VFMSUBADDPS, 0x5E, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmsubaddps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3)\t{AppendInstr(I_VFMSUBADDPS, 0x5E, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfmsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VFMSUBPD, 0x6D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmsubpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VFMSUBPD, 0x6D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3)\t{AppendInstr(I_VFMSUBPD, 0x6D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfmsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3)\t{AppendInstr(I_VFMSUBPD, 0x6D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmsubpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3)\t{AppendInstr(I_VFMSUBPD, 0x6D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3)\t{AppendInstr(I_VFMSUBPD, 0x6D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfmsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VFMSUBPS, 0x6C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmsubps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VFMSUBPS, 0x6C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3)\t{AppendInstr(I_VFMSUBPS, 0x6C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfmsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3)\t{AppendInstr(I_VFMSUBPS, 0x6C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmsubps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3)\t{AppendInstr(I_VFMSUBPS, 0x6C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3)\t{AppendInstr(I_VFMSUBPS, 0x6C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfmsubsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VFMSUBSD, 0x6F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmsubsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2, const XmmReg& src3)\t\t{AppendInstr(I_VFMSUBSD, 0x6F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmsubsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem64& src3)\t\t{AppendInstr(I_VFMSUBSD, 0x6F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfmsubss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VFMSUBSS, 0x6E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmsubss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2, const XmmReg& src3)\t\t{AppendInstr(I_VFMSUBSS, 0x6E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfmsubss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem32& src3)\t\t{AppendInstr(I_VFMSUBSS, 0x6E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfnmaddpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VFNMADDPD, 0x79, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfnmaddpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VFNMADDPD, 0x79, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfnmaddpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3)\t{AppendInstr(I_VFNMADDPD, 0x79, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfnmaddpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3)\t{AppendInstr(I_VFNMADDPD, 0x79, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfnmaddpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3)\t{AppendInstr(I_VFNMADDPD, 0x79, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfnmaddpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3)\t{AppendInstr(I_VFNMADDPD, 0x79, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfnmaddps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VFNMADDPS, 0x78, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfnmaddps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VFNMADDPS, 0x78, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfnmaddps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3)\t{AppendInstr(I_VFNMADDPS, 0x78, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfnmaddps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3)\t{AppendInstr(I_VFNMADDPS, 0x78, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfnmaddps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3)\t{AppendInstr(I_VFNMADDPS, 0x78, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfnmaddps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3)\t{AppendInstr(I_VFNMADDPS, 0x78, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfnmaddsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VFNMADDSD, 0x7B, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfnmaddsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2, const XmmReg& src3)\t{AppendInstr(I_VFNMADDSD, 0x7B, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfnmaddsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem64& src3)\t{AppendInstr(I_VFNMADDSD, 0x7B, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfnmaddss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VFNMADDSS, 0x7A, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfnmaddss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2, const XmmReg& src3)\t{AppendInstr(I_VFNMADDSS, 0x7A, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfnmaddss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem32& src3)\t{AppendInstr(I_VFNMADDSS, 0x7A, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfnmsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VFNMSUBPD, 0x7D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfnmsubpd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VFNMSUBPD, 0x7D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfnmsubpd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3)\t{AppendInstr(I_VFNMSUBPD, 0x7D, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfnmsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3)\t{AppendInstr(I_VFNMSUBPD, 0x7D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfnmsubpd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3)\t{AppendInstr(I_VFNMSUBPD, 0x7D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfnmsubpd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3)\t{AppendInstr(I_VFNMSUBPD, 0x7D, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfnmsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VFNMSUBPS, 0x7C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfnmsubps(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const XmmReg& src3)\t{AppendInstr(I_VFNMSUBPS, 0x7C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfnmsubps(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem128& src3)\t{AppendInstr(I_VFNMSUBPS, 0x7C, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfnmsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& src3)\t{AppendInstr(I_VFNMSUBPS, 0x7C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfnmsubps(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& src3)\t{AppendInstr(I_VFNMSUBPS, 0x7C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfnmsubps(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Mem256& src3)\t{AppendInstr(I_VFNMSUBPS, 0x7C, E_VEX_256 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfnmsubsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VFNMSUBSD, 0x7F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfnmsubsd(const XmmReg& dst, const XmmReg& src1, const Mem64& src2, const XmmReg& src3)\t{AppendInstr(I_VFNMSUBSD, 0x7F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfnmsubsd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem64& src3)\t{AppendInstr(I_VFNMSUBSD, 0x7F, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\tvoid vfnmsubss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const XmmReg& src3)\t{AppendInstr(I_VFNMSUBSS, 0x7E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfnmsubss(const XmmReg& dst, const XmmReg& src1, const Mem32& src2, const XmmReg& src3)\t{AppendInstr(I_VFNMSUBSS, 0x7E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W0, W(dst), R(src2), R(src1), R(src3));}\n\tvoid vfnmsubss(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Mem32& src3)\t{AppendInstr(I_VFNMSUBSS, 0x7E, E_VEX_128 | E_VEX_0F3A | E_VEX_66 | E_VEX_W1, W(dst), R(src3), R(src1), R(src2));}\n\n\t// AVX2\n\tvoid vbroadcastss(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_VBROADCASTSS, 0x18, E_VEX_128_66_0F38_W0, W(dst), R(src));}\n\tvoid vbroadcastss(const YmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_VBROADCASTSS, 0x18, E_VEX_256_66_0F38_W0, W(dst), R(src));}\n\tvoid vbroadcastsd(const YmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_VBROADCASTSD, 0x19, E_VEX_256_66_0F38_W0, W(dst), R(src));}\n\tvoid vbroadcasti128(const YmmReg& dst, const Mem128& src)\t{AppendInstr(I_VBROADCASTI128, 0x5A, E_VEX_256_66_0F38_W0, W(dst), R(src));}\n\tvoid vextracti128(const XmmReg& dst, const YmmReg& src, const Imm8& offset)\t{AppendInstr(I_VEXTRACTI128, 0x39, E_VEX_256_66_0F3A_W0, R(src), W(dst), offset);}\n\tvoid vextracti128(const Mem128& dst, const YmmReg& src, const Imm8& offset)\t{AppendInstr(I_VEXTRACTI128, 0x39, E_VEX_256_66_0F3A_W0, R(src), W(dst), offset);}\n\tvoid vgatherdps(const XmmReg& dst, const Mem32vxd& src, const XmmReg& mask)\t{AppendInstr(I_VGATHERDPS, 0x92, E_VEX_128_66_0F38_W0, RW(dst), R(src), R(mask));}\n\tvoid vgatherdps(const YmmReg& dst, const Mem32vyd& src, const YmmReg& mask)\t{AppendInstr(I_VGATHERDPS, 0x92, E_VEX_256_66_0F38_W0, RW(dst), R(src), R(mask));}\n\tvoid vgatherqps(const XmmReg& dst, const Mem64vxd& src, const XmmReg& mask)\t{AppendInstr(I_VGATHERQPS, 0x93, E_VEX_128_66_0F38_W0, RW(dst), R(src), R(mask));}\n\tvoid vgatherqps(const XmmReg& dst, const Mem64vyd& src, const XmmReg& mask)\t{AppendInstr(I_VGATHERQPS, 0x93, E_VEX_256_66_0F38_W0, RW(dst), R(src), R(mask));}\n\tvoid vgatherdpd(const XmmReg& dst, const Mem32vxq& src, const XmmReg& mask)\t{AppendInstr(I_VGATHERDPD, 0x92, E_VEX_128_66_0F38_W1, RW(dst), R(src), R(mask));}\n\tvoid vgatherdpd(const YmmReg& dst, const Mem32vxq& src, const YmmReg& mask)\t{AppendInstr(I_VGATHERDPD, 0x92, E_VEX_256_66_0F38_W1, RW(dst), R(src), R(mask));}\n\tvoid vgatherqpd(const XmmReg& dst, const Mem64vxq& src, const XmmReg& mask)\t{AppendInstr(I_VGATHERQPD, 0x93, E_VEX_128_66_0F38_W1, RW(dst), R(src), R(mask));}\n\tvoid vgatherqpd(const YmmReg& dst, const Mem64vyq& src, const YmmReg& mask)\t{AppendInstr(I_VGATHERQPD, 0x93, E_VEX_256_66_0F38_W1, RW(dst), R(src), R(mask));}\n\tvoid vinserti128(const YmmReg& dst, const YmmReg& src1, const XmmReg& src2, const Imm8& offset)\t{AppendInstr(I_VINSERTI128, 0x38, E_VEX_256_66_0F3A_W0, W(dst), R(src2), R(src1), offset);}\n\tvoid vinserti128(const YmmReg& dst, const YmmReg& src1, const Mem128& src2, const Imm8& offset)\t{AppendInstr(I_VINSERTI128, 0x38, E_VEX_256_66_0F3A_W0, W(dst), R(src2), R(src1), offset);}\n\tvoid vmovntdqa(const YmmReg& dst, const Mem256& src)\t\t\t\t\t\t{AppendInstr(I_MOVNTDQA, 0x2A, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vmpsadbw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& i)\t{AppendInstr(I_MPSADBW, 0x42, E_VEX_256 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src2), R(src1), i);}\n\tvoid vmpsadbw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& i)\t{AppendInstr(I_MPSADBW, 0x42, E_VEX_256 | E_VEX_66_0F3A | E_VEX_WIG, W(dst), R(src2), R(src1), i);}\n\tvoid vpabsb(const YmmReg& dst, const YmmReg& src)\t{AppendInstr(I_PABSB, 0x1C, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpabsb(const YmmReg& dst, const Mem256& src)\t{AppendInstr(I_PABSB, 0x1C, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpabsw(const YmmReg& dst, const YmmReg& src)\t{AppendInstr(I_PABSW, 0x1D, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpabsw(const YmmReg& dst, const Mem256& src)\t{AppendInstr(I_PABSW, 0x1D, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpabsd(const YmmReg& dst, const YmmReg& src)\t{AppendInstr(I_PABSD, 0x1E, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpabsd(const YmmReg& dst, const Mem256& src)\t{AppendInstr(I_PABSD, 0x1E, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpacksswb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PACKSSWB, 0x63, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpacksswb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PACKSSWB, 0x63, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpackssdw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PACKSSDW, 0x6B, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpackssdw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PACKSSDW, 0x6B, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpackuswb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PACKUSWB, 0x67, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpackuswb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PACKUSWB, 0x67, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpackusdw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PACKUSDW, 0x2B, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpackusdw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PACKUSDW, 0x2B, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PADDB, 0xFC, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PADDB, 0xFC, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PADDW, 0xFD, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PADDW, 0xFD, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PADDD, 0xFE, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PADDD, 0xFE, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PADDQ, 0xD4, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PADDQ, 0xD4, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddsb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PADDSB, 0xEC, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddsb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PADDSB, 0xEC, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddsw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PADDSW, 0xED, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddsw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PADDSW, 0xED, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddusb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PADDUSB, 0xDC, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddusb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PADDUSB, 0xDC, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddusw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PADDUSW, 0xDD, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpaddusw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PADDUSW, 0xDD, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpalignr(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& i) {AppendInstr(I_PALIGNR, 0x0F, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), i);}\n\tvoid vpalignr(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& i) {AppendInstr(I_PALIGNR, 0x0F, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), i);}\n\tvoid vpand(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) \t{AppendInstr(I_PAND, 0xDB, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpand(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) \t{AppendInstr(I_PAND, 0xDB, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpandn(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) \t{AppendInstr(I_PANDN, 0xDF, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpandn(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) \t{AppendInstr(I_PANDN, 0xDF, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpavgb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) \t{AppendInstr(I_PAVGB, 0xE0, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpavgb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) \t{AppendInstr(I_PAVGB, 0xE0, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpavgw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2) \t{AppendInstr(I_PAVGW, 0xE3, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpavgw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2) \t{AppendInstr(I_PAVGW, 0xE3, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpblendvb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const YmmReg& mask) \t{AppendInstr(I_PBLENDVB, 0x4C, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src2), R(src1), R(mask));}\n\tvoid vpblendvb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const YmmReg& mask) \t{AppendInstr(I_PBLENDVB, 0x4C, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W0, W(dst), R(src2), R(src1), R(mask));}\n\tvoid vpblendw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& mask) \t\t{AppendInstr(I_PBLENDW, 0x0E, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}\n\tvoid vpblendw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& mask) \t\t{AppendInstr(I_PBLENDW, 0x0E, E_VEX_256 | E_VEX_66_0F3A, W(dst), R(src2), R(src1), mask);}\n\tvoid vpblendd(const XmmReg& dst, const XmmReg& src1, const XmmReg& src2, const Imm8& mask)\t\t{AppendInstr(I_PBLENDD, 0x02, E_VEX_128_66_0F3A_W0, W(dst), R(src2), R(src1), mask);}\n\tvoid vpblendd(const XmmReg& dst, const XmmReg& src1, const Mem128& src2, const Imm8& mask)\t\t{AppendInstr(I_PBLENDD, 0x02, E_VEX_128_66_0F3A_W0, W(dst), R(src2), R(src1), mask);}\n\tvoid vpblendd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& mask)\t\t{AppendInstr(I_PBLENDD, 0x02, E_VEX_256_66_0F3A_W0, W(dst), R(src2), R(src1), mask);}\n\tvoid vpblendd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& mask)\t\t{AppendInstr(I_PBLENDD, 0x02, E_VEX_256_66_0F3A_W0, W(dst), R(src2), R(src1), mask);}\n\tvoid vpbroadcastb(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_VPBROADCASTB, 0x78, E_VEX_128_66_0F38_W0, W(dst), R(src));}\n\tvoid vpbroadcastb(const XmmReg& dst, const Mem8& src)\t\t{AppendInstr(I_VPBROADCASTB, 0x78, E_VEX_128_66_0F38_W0, W(dst), R(src));}\n\tvoid vpbroadcastb(const YmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_VPBROADCASTB, 0x78, E_VEX_256_66_0F38_W0, W(dst), R(src));}\n\tvoid vpbroadcastb(const YmmReg& dst, const Mem8& src)\t\t{AppendInstr(I_VPBROADCASTB, 0x78, E_VEX_256_66_0F38_W0, W(dst), R(src));}\n\tvoid vpbroadcastw(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_VPBROADCASTW, 0x79, E_VEX_128_66_0F38_W0, W(dst), R(src));}\n\tvoid vpbroadcastw(const XmmReg& dst, const Mem16& src)\t\t{AppendInstr(I_VPBROADCASTW, 0x79, E_VEX_128_66_0F38_W0, W(dst), R(src));}\n\tvoid vpbroadcastw(const YmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_VPBROADCASTW, 0x79, E_VEX_256_66_0F38_W0, W(dst), R(src));}\n\tvoid vpbroadcastw(const YmmReg& dst, const Mem16& src)\t\t{AppendInstr(I_VPBROADCASTW, 0x79, E_VEX_256_66_0F38_W0, W(dst), R(src));}\n\tvoid vpbroadcastd(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_VPBROADCASTD, 0x58, E_VEX_128_66_0F38_W0, W(dst), R(src));}\n\tvoid vpbroadcastd(const XmmReg& dst, const Mem32& src)\t\t{AppendInstr(I_VPBROADCASTD, 0x58, E_VEX_128_66_0F38_W0, W(dst), R(src));}\n\tvoid vpbroadcastd(const YmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_VPBROADCASTD, 0x58, E_VEX_256_66_0F38_W0, W(dst), R(src));}\n\tvoid vpbroadcastd(const YmmReg& dst, const Mem32& src)\t\t{AppendInstr(I_VPBROADCASTD, 0x58, E_VEX_256_66_0F38_W0, W(dst), R(src));}\n\tvoid vpbroadcastq(const XmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_VPBROADCASTQ, 0x59, E_VEX_128_66_0F38_W0, W(dst), R(src));}\n\tvoid vpbroadcastq(const XmmReg& dst, const Mem64& src)\t\t{AppendInstr(I_VPBROADCASTQ, 0x59, E_VEX_128_66_0F38_W0, W(dst), R(src));}\n\tvoid vpbroadcastq(const YmmReg& dst, const XmmReg& src)\t\t{AppendInstr(I_VPBROADCASTQ, 0x59, E_VEX_256_66_0F38_W0, W(dst), R(src));}\n\tvoid vpbroadcastq(const YmmReg& dst, const Mem64& src)\t\t{AppendInstr(I_VPBROADCASTQ, 0x59, E_VEX_256_66_0F38_W0, W(dst), R(src));}\n\tvoid vpcmpeqb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PCMPEQB,\t0x74, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpeqb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PCMPEQB,\t0x74, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpeqw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PCMPEQW,\t0x75, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpeqw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PCMPEQW,\t0x75, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpeqd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PCMPEQD,\t0x76, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpeqd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PCMPEQD,\t0x76, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpeqq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PCMPEQQ,\t0x29, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpeqq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PCMPEQQ,\t0x29, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpgtb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PCMPGTB,\t0x64, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpgtb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PCMPGTB,\t0x64, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpgtw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PCMPGTW,\t0x65, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpgtw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PCMPGTW,\t0x65, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpgtd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PCMPGTD,\t0x66, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpgtd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PCMPGTD,\t0x66, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpgtq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PCMPGTQ,\t0x37, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpcmpgtq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PCMPGTQ,\t0x37, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpermd(const YmmReg& dst, const YmmReg& offsets, const YmmReg& src)\t{AppendInstr(I_VPERMD,\t0x36, E_VEX_256_66_0F38_W0, W(dst), R(src), R(offsets));}\n\tvoid vpermd(const YmmReg& dst, const YmmReg& offsets, const Mem256& src)\t{AppendInstr(I_VPERMD,\t0x36, E_VEX_256_66_0F38_W0, W(dst), R(src), R(offsets));}\n\tvoid vpermq(const YmmReg& dst, const YmmReg& src, const Imm8& control)\t\t{AppendInstr(I_VPERMQ,\t0x00, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W1, W(dst), R(src), control);}\n\tvoid vpermq(const YmmReg& dst, const Mem256& src, const Imm8& control)\t\t{AppendInstr(I_VPERMQ,\t0x00, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W1, W(dst), R(src), control);}\n\tvoid vpermps(const YmmReg& dst, const YmmReg& offsets, const YmmReg& src)\t{AppendInstr(I_VPERMPS,\t0x16, E_VEX_256_66_0F38_W0, W(dst), R(src), R(offsets));}\n\tvoid vpermps(const YmmReg& dst, const YmmReg& offsets, const Mem256& src)\t{AppendInstr(I_VPERMPS,\t0x16, E_VEX_256_66_0F38_W0, W(dst), R(src), R(offsets));}\n\tvoid vpermpd(const YmmReg& dst, const YmmReg& src, const Imm8& control)\t\t{AppendInstr(I_VPERMPD,\t0x01, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W1, W(dst), R(src), control);}\n\tvoid vpermpd(const YmmReg& dst, const Mem256& src, const Imm8& control)\t\t{AppendInstr(I_VPERMPD,\t0x01, E_VEX_256 | E_VEX_66_0F3A | E_VEX_W1, W(dst), R(src), control);}\n\tvoid vperm2i128(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2, const Imm8& control)\t{AppendInstr(I_VPERM2I128, 0x46, E_VEX_256_66_0F3A_W0, W(dst), R(src2), R(src1), control);}\n\tvoid vperm2i128(const YmmReg& dst, const YmmReg& src1, const Mem256& src2, const Imm8& control)\t{AppendInstr(I_VPERM2I128, 0x46, E_VEX_256_66_0F3A_W0, W(dst), R(src2), R(src1), control);}\n\tvoid vpgatherdd(const XmmReg& dst, const Mem32vxd& src, const XmmReg& mask)\t{AppendInstr(I_VPGATHERDD, 0x90, E_VEX_128_66_0F38_W0, RW(dst), R(src), R(mask));}\n\tvoid vpgatherdd(const YmmReg& dst, const Mem32vyd& src, const YmmReg& mask)\t{AppendInstr(I_VPGATHERDD, 0x90, E_VEX_256_66_0F38_W0, RW(dst), R(src), R(mask));}\n\tvoid vpgatherqd(const XmmReg& dst, const Mem64vxd& src, const XmmReg& mask)\t{AppendInstr(I_VPGATHERQD, 0x91, E_VEX_128_66_0F38_W0, RW(dst), R(src), R(mask));}\n\tvoid vpgatherqd(const XmmReg& dst, const Mem64vyd& src, const XmmReg& mask)\t{AppendInstr(I_VPGATHERQD, 0x91, E_VEX_256_66_0F38_W0, RW(dst), R(src), R(mask));}\n\tvoid vpgatherdq(const XmmReg& dst, const Mem32vxq& src, const XmmReg& mask)\t{AppendInstr(I_VPGATHERDQ, 0x90, E_VEX_128_66_0F38_W1, RW(dst), R(src), R(mask));}\n\tvoid vpgatherdq(const YmmReg& dst, const Mem32vxq& src, const YmmReg& mask)\t{AppendInstr(I_VPGATHERDQ, 0x90, E_VEX_256_66_0F38_W1, RW(dst), R(src), R(mask));}\n\tvoid vpgatherqq(const XmmReg& dst, const Mem64vxq& src, const XmmReg& mask)\t{AppendInstr(I_VPGATHERQQ, 0x91, E_VEX_128_66_0F38_W1, RW(dst), R(src), R(mask));}\n\tvoid vpgatherqq(const YmmReg& dst, const Mem64vyq& src, const YmmReg& mask)\t{AppendInstr(I_VPGATHERQQ, 0x91, E_VEX_256_66_0F38_W1, RW(dst), R(src), R(mask));}\n\tvoid vphaddw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PHADDW,\t0x01, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vphaddw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PHADDW,\t0x01, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vphaddd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PHADDD,\t0x02, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vphaddd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PHADDD,\t0x02, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vphaddsw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PHADDSW,\t0x03, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vphaddsw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PHADDSW,\t0x03, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vphsubw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PHSUBW,\t0x05, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vphsubw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PHSUBW,\t0x05, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vphsubd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PHSUBD,\t0x06, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vphsubd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PHSUBD,\t0x06, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vphsubsw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PHSUBSW,\t0x07, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vphsubsw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PHSUBSW,\t0x07, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaddwd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PMADDWD,\t0xF5, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaddwd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PMADDWD,\t0xF5, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaddubsw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PMADDUBSW,0x04, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaddubsw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PMADDUBSW,0x04, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaskmovd(const XmmReg& dst, const XmmReg& mask, const Mem128& src)\t{AppendInstr(I_VMASKMOVD, 0x8C, E_VEX_128_66_0F38_W0, W(dst), R(src), R(mask));}\n\tvoid vpmaskmovd(const YmmReg& dst, const YmmReg& mask, const Mem256& src)\t{AppendInstr(I_VMASKMOVD, 0x8C, E_VEX_256_66_0F38_W0, W(dst), R(src), R(mask));}\n\tvoid vpmaskmovq(const XmmReg& dst, const XmmReg& mask, const Mem128& src)\t{AppendInstr(I_VMASKMOVQ, 0x8C, E_VEX_128_66_0F38_W1, W(dst), R(src), R(mask));}\n\tvoid vpmaskmovq(const YmmReg& dst, const YmmReg& mask, const Mem256& src)\t{AppendInstr(I_VMASKMOVQ, 0x8C, E_VEX_256_66_0F38_W1, W(dst), R(src), R(mask));}\n\tvoid vpmaskmovd(const Mem128& dst, const XmmReg& mask, const XmmReg& src)\t{AppendInstr(I_VMASKMOVD, 0x8E, E_VEX_128_66_0F38_W0, R(src), W(dst), R(mask));}\n\tvoid vpmaskmovd(const Mem256& dst, const YmmReg& mask, const YmmReg& src)\t{AppendInstr(I_VMASKMOVD, 0x8E, E_VEX_256_66_0F38_W0, R(src), W(dst), R(mask));}\n\tvoid vpmaskmovq(const Mem128& dst, const XmmReg& mask, const XmmReg& src)\t{AppendInstr(I_VMASKMOVQ, 0x8E, E_VEX_128_66_0F38_W1, R(src), W(dst), R(mask));}\n\tvoid vpmaskmovq(const Mem256& dst, const YmmReg& mask, const YmmReg& src)\t{AppendInstr(I_VMASKMOVQ, 0x8E, E_VEX_256_66_0F38_W1, R(src), W(dst), R(mask));}\n\tvoid vpmaxsb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PMAXSB, 0x3C, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaxsb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PMAXSB, 0x3C, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaxsw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PMAXSW, 0xEE, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaxsw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PMAXSW, 0xEE, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaxsd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PMAXSD, 0x3D, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaxsd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PMAXSD, 0x3D, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaxub(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PMAXUB, 0xDE, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaxub(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PMAXUB, 0xDE, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaxuw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PMAXUW, 0x3E, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaxuw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PMAXUW, 0x3E, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaxud(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PMAXUD, 0x3F, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmaxud(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PMAXUD, 0x3F, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpminsb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PMINSB, 0x38, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpminsb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PMINSB, 0x38, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpminsw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PMINSW, 0xEA, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpminsw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PMINSW, 0xEA, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpminsd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PMINSD, 0x39, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpminsd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PMINSD, 0x39, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpminub(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PMINUB, 0xDA, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpminub(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PMINUB, 0xDA, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpminuw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PMINUW, 0x3A, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpminuw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PMINUW, 0x3A, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpminud(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PMINUD, 0x3B, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpminud(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PMINUD, 0x3B, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmovmskb(const Reg32& dst, const YmmReg& src)\t\t\t\t\t\t\t{AppendInstr(I_PMOVMSKB, 0xD7, E_VEX_256_66_0F_WIG, W(dst), R(src));}\n#ifdef JITASM64\n\tvoid vpmovmskb(const Reg64& dst, const YmmReg& src)\t\t\t\t\t\t\t{AppendInstr(I_PMOVMSKB, 0xD7, E_VEX_256_66_0F_WIG, W(dst), R(src));}\n#endif\n\tvoid vpmovsxbw(const YmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXBW, 0x20, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovsxbw(const YmmReg& dst, const Mem128& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXBW, 0x20, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovsxbd(const YmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXBD, 0x21, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovsxbd(const YmmReg& dst, const Mem64& src)\t\t\t\t\t\t\t{AppendInstr(I_PMOVSXBD, 0x21, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovsxbq(const YmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXBQ, 0x22, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovsxbq(const YmmReg& dst, const Mem32& src)\t\t\t\t\t\t\t{AppendInstr(I_PMOVSXBQ, 0x22, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovsxwd(const YmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXWD, 0x23, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovsxwd(const YmmReg& dst, const Mem128& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXWD, 0x23, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovsxwq(const YmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXWQ, 0x24, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovsxwq(const YmmReg& dst, const Mem64& src)\t\t\t\t\t\t\t{AppendInstr(I_PMOVSXWQ, 0x24, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovsxdq(const YmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXDQ, 0x25, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovsxdq(const YmmReg& dst, const Mem128& src)\t\t\t\t\t\t{AppendInstr(I_PMOVSXDQ, 0x25, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovzxbw(const YmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXBW, 0x30, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovzxbw(const YmmReg& dst, const Mem128& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXBW, 0x30, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovzxbd(const YmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXBD, 0x31, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovzxbd(const YmmReg& dst, const Mem64& src)\t\t\t\t\t\t\t{AppendInstr(I_PMOVZXBD, 0x31, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovzxbq(const YmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXBQ, 0x32, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovzxbq(const YmmReg& dst, const Mem32& src)\t\t\t\t\t\t\t{AppendInstr(I_PMOVZXBQ, 0x32, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovzxwd(const YmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXWD, 0x33, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovzxwd(const YmmReg& dst, const Mem128& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXWD, 0x33, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovzxwq(const YmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXWQ, 0x34, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovzxwq(const YmmReg& dst, const Mem64& src)\t\t\t\t\t\t\t{AppendInstr(I_PMOVZXWQ, 0x34, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovzxdq(const YmmReg& dst, const XmmReg& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXDQ, 0x35, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmovzxdq(const YmmReg& dst, const Mem128& src)\t\t\t\t\t\t{AppendInstr(I_PMOVZXDQ, 0x35, E_VEX_256_66_0F38_WIG, W(dst), R(src));}\n\tvoid vpmulhuw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PMULHUW,\t0xE4, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmulhuw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PMULHUW,\t0xE4, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmulhrsw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PMULHRSW, 0x0B, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmulhrsw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PMULHRSW, 0x0B, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmulhw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PMULHW,\t0xE5, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmulhw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PMULHW,\t0xE5, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmullw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PMULLW,\t0xD5, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmullw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PMULLW,\t0xD5, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmulld(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PMULLD,\t0x40, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmulld(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PMULLD,\t0x40, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmuludq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PMULUDQ,\t0xF4, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmuludq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PMULUDQ,\t0xF4, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmuldq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PMULDQ,\t0x28, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpmuldq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PMULDQ,\t0x28, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpor(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_POR,\t\t0xEB, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpor(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_POR,\t\t0xEB, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsadbw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PSADBW,\t0xF6, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsadbw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PSADBW,\t0xF6, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpshufb(const YmmReg& dst, const YmmReg& src, const YmmReg& order)\t\t{AppendInstr(I_PSHUFB,\t0x00, E_VEX_256_66_0F38_WIG, W(dst), R(order), R(src));}\n\tvoid vpshufb(const YmmReg& dst, const YmmReg& src, const Mem256& order)\t\t{AppendInstr(I_PSHUFB,\t0x00, E_VEX_256_66_0F38_WIG, W(dst), R(order), R(src));}\n\tvoid vpshufd(const YmmReg& dst, const YmmReg& src, const Imm8& order)\t\t{AppendInstr(I_PSHUFD,\t0x70, E_VEX_256_66_0F_WIG, W(dst), R(src), order);}\n\tvoid vpshufd(const YmmReg& dst, const Mem256& src, const Imm8& order)\t\t{AppendInstr(I_PSHUFD,\t0x70, E_VEX_256_66_0F_WIG, W(dst), R(src), order);}\n\tvoid vpshufhw(const YmmReg& dst, const YmmReg& src, const Imm8& order)\t\t{AppendInstr(I_PSHUFHW,\t0x70, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src), order);}\n\tvoid vpshufhw(const YmmReg& dst, const Mem256& src, const Imm8& order)\t\t{AppendInstr(I_PSHUFHW,\t0x70, E_VEX_256 | E_VEX_F3_0F | E_VEX_WIG, W(dst), R(src), order);}\n\tvoid vpshuflw(const YmmReg& dst, const YmmReg& src, const Imm8& order)\t\t{AppendInstr(I_PSHUFLW,\t0x70, E_VEX_256 | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src), order);}\n\tvoid vpshuflw(const YmmReg& dst, const Mem256& src, const Imm8& order)\t\t{AppendInstr(I_PSHUFLW,\t0x70, E_VEX_256 | E_VEX_F2_0F | E_VEX_WIG, W(dst), R(src), order);}\n\tvoid vpsignb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PSIGNB,\t0x08, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsignb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PSIGNB,\t0x08, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsignw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PSIGNW,\t0x09, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsignw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PSIGNW,\t0x09, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsignd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PSIGND,\t0x0A, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsignd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PSIGND,\t0x0A, E_VEX_256_66_0F38_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsllw(const YmmReg& dst, const YmmReg& src, const XmmReg& count)\t\t{AppendInstr(I_PSLLW,\t0xF1, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsllw(const YmmReg& dst, const YmmReg& src, const Mem128& count)\t\t{AppendInstr(I_PSLLW,\t0xF1, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsllw(const YmmReg& dst, const YmmReg& src, const Imm8& count)\t\t{AppendInstr(I_PSLLW,\t0x71, E_VEX_256_66_0F_WIG, Imm8(6), R(src), W(dst), count);}\n\tvoid vpslld(const YmmReg& dst, const YmmReg& src, const XmmReg& count)\t\t{AppendInstr(I_PSLLD,\t0xF2, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpslld(const YmmReg& dst, const YmmReg& src, const Mem128& count)\t\t{AppendInstr(I_PSLLD,\t0xF2, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpslld(const YmmReg& dst, const YmmReg& src, const Imm8& count)\t\t{AppendInstr(I_PSLLD,\t0x72, E_VEX_256_66_0F_WIG, Imm8(6), R(src), W(dst), count);}\n\tvoid vpsllq(const YmmReg& dst, const YmmReg& src, const XmmReg& count)\t\t{AppendInstr(I_PSLLQ,\t0xF3, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsllq(const YmmReg& dst, const YmmReg& src, const Mem128& count)\t\t{AppendInstr(I_PSLLQ,\t0xF3, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsllq(const YmmReg& dst, const YmmReg& src, const Imm8& count)\t\t{AppendInstr(I_PSLLQ,\t0x73, E_VEX_256_66_0F_WIG, Imm8(6), R(src), W(dst), count);}\n\tvoid vpslldq(const YmmReg& dst, const YmmReg& src, const Imm8& count)\t\t{AppendInstr(I_PSLLDQ,\t0x73, E_VEX_256_66_0F_WIG, Imm8(7), R(src), W(dst), count);}\n\tvoid vpsllvd(const XmmReg& dst, const XmmReg& count, const XmmReg& src)\t\t{AppendInstr(I_VPSLLVD,\t0x47, E_VEX_128_66_0F38_W0, W(dst), R(src), R(count));}\n\tvoid vpsllvd(const XmmReg& dst, const XmmReg& count, const Mem128& src)\t\t{AppendInstr(I_VPSLLVD,\t0x47, E_VEX_128_66_0F38_W0, W(dst), R(src), R(count));}\n\tvoid vpsllvd(const YmmReg& dst, const YmmReg& count, const YmmReg& src)\t\t{AppendInstr(I_VPSLLVD,\t0x47, E_VEX_256_66_0F38_W0, W(dst), R(src), R(count));}\n\tvoid vpsllvd(const YmmReg& dst, const YmmReg& count, const Mem256& src)\t\t{AppendInstr(I_VPSLLVD,\t0x47, E_VEX_256_66_0F38_W0, W(dst), R(src), R(count));}\n\tvoid vpsllvq(const XmmReg& dst, const XmmReg& count, const XmmReg& src)\t\t{AppendInstr(I_VPSLLVQ,\t0x47, E_VEX_128_66_0F38_W1, W(dst), R(src), R(count));}\n\tvoid vpsllvq(const XmmReg& dst, const XmmReg& count, const Mem128& src)\t\t{AppendInstr(I_VPSLLVQ,\t0x47, E_VEX_128_66_0F38_W1, W(dst), R(src), R(count));}\n\tvoid vpsllvq(const YmmReg& dst, const YmmReg& count, const YmmReg& src)\t\t{AppendInstr(I_VPSLLVQ,\t0x47, E_VEX_256_66_0F38_W1, W(dst), R(src), R(count));}\n\tvoid vpsllvq(const YmmReg& dst, const YmmReg& count, const Mem256& src)\t\t{AppendInstr(I_VPSLLVQ,\t0x47, E_VEX_256_66_0F38_W1, W(dst), R(src), R(count));}\n\tvoid vpsraw(const YmmReg& dst, const YmmReg& src, const XmmReg& count)\t\t{AppendInstr(I_PSRAW,\t0xE1, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsraw(const YmmReg& dst, const YmmReg& src, const Mem128& count)\t\t{AppendInstr(I_PSRAW,\t0xE1, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsraw(const YmmReg& dst, const YmmReg& src, const Imm8& count)\t\t{AppendInstr(I_PSRAW,\t0x71, E_VEX_256_66_0F_WIG, Imm8(4), R(src), W(dst), count);}\n\tvoid vpsrad(const YmmReg& dst, const YmmReg& src, const XmmReg& count)\t\t{AppendInstr(I_PSRAD,\t0xE2, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsrad(const YmmReg& dst, const YmmReg& src, const Mem128& count)\t\t{AppendInstr(I_PSRAD,\t0xE2, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsrad(const YmmReg& dst, const YmmReg& src, const Imm8& count)\t\t{AppendInstr(I_PSRAD,\t0x72, E_VEX_256_66_0F_WIG, Imm8(4), R(src), W(dst), count);}\n\tvoid vpsravd(const XmmReg& dst, const XmmReg& count, const XmmReg& src)\t\t{AppendInstr(I_VPSRAVD,\t0x46, E_VEX_128_66_0F38_W0, W(dst), R(src), R(count));}\n\tvoid vpsravd(const XmmReg& dst, const XmmReg& count, const Mem128& src)\t\t{AppendInstr(I_VPSRAVD,\t0x46, E_VEX_128_66_0F38_W0, W(dst), R(src), R(count));}\n\tvoid vpsravd(const YmmReg& dst, const YmmReg& count, const YmmReg& src)\t\t{AppendInstr(I_VPSRAVD,\t0x46, E_VEX_256_66_0F38_W0, W(dst), R(src), R(count));}\n\tvoid vpsravd(const YmmReg& dst, const YmmReg& count, const Mem256& src)\t\t{AppendInstr(I_VPSRAVD,\t0x46, E_VEX_256_66_0F38_W0, W(dst), R(src), R(count));}\n\tvoid vpsrlw(const YmmReg& dst, const YmmReg& src, const XmmReg& count)\t\t{AppendInstr(I_PSRLW,\t0xD1, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsrlw(const YmmReg& dst, const YmmReg& src, const Mem128& count)\t\t{AppendInstr(I_PSRLW,\t0xD1, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsrlw(const YmmReg& dst, const YmmReg& src, const Imm8& count)\t\t{AppendInstr(I_PSRLW,\t0x71, E_VEX_256_66_0F_WIG, Imm8(2), R(src), W(dst), count);}\n\tvoid vpsrld(const YmmReg& dst, const YmmReg& src, const XmmReg& count)\t\t{AppendInstr(I_PSRLD,\t0xD2, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsrld(const YmmReg& dst, const YmmReg& src, const Mem128& count)\t\t{AppendInstr(I_PSRLD,\t0xD2, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsrld(const YmmReg& dst, const YmmReg& src, const Imm8& count)\t\t{AppendInstr(I_PSRLD,\t0x72, E_VEX_256_66_0F_WIG, Imm8(2), R(src), W(dst), count);}\n\tvoid vpsrlq(const YmmReg& dst, const YmmReg& src, const XmmReg& count)\t\t{AppendInstr(I_PSRLQ,\t0xD3, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsrlq(const YmmReg& dst, const YmmReg& src, const Mem128& count)\t\t{AppendInstr(I_PSRLQ,\t0xD3, E_VEX_256_66_0F_WIG, W(dst), R(count), R(src));}\n\tvoid vpsrlq(const YmmReg& dst, const YmmReg& src, const Imm8& count)\t\t{AppendInstr(I_PSRLQ,\t0x73, E_VEX_256_66_0F_WIG, Imm8(2), R(src), W(dst), count);}\n\tvoid vpsrldq(const YmmReg& dst, const YmmReg& src, const Imm8& count)\t\t{AppendInstr(I_PSRLDQ,\t0x73, E_VEX_256_66_0F_WIG, Imm8(3), R(src), W(dst), count);}\n\tvoid vpsrlvd(const XmmReg& dst, const XmmReg& count, const XmmReg& src)\t\t{AppendInstr(I_VPSRLVD,\t0x45, E_VEX_128_66_0F38_W0, W(dst), R(src), R(count));}\n\tvoid vpsrlvd(const XmmReg& dst, const XmmReg& count, const Mem128& src)\t\t{AppendInstr(I_VPSRLVD,\t0x45, E_VEX_128_66_0F38_W0, W(dst), R(src), R(count));}\n\tvoid vpsrlvd(const YmmReg& dst, const YmmReg& count, const YmmReg& src)\t\t{AppendInstr(I_VPSRLVD,\t0x45, E_VEX_256_66_0F38_W0, W(dst), R(src), R(count));}\n\tvoid vpsrlvd(const YmmReg& dst, const YmmReg& count, const Mem256& src)\t\t{AppendInstr(I_VPSRLVD,\t0x45, E_VEX_256_66_0F38_W0, W(dst), R(src), R(count));}\n\tvoid vpsrlvq(const XmmReg& dst, const XmmReg& count, const XmmReg& src)\t\t{AppendInstr(I_VPSRLVQ,\t0x45, E_VEX_128_66_0F38_W1, W(dst), R(src), R(count));}\n\tvoid vpsrlvq(const XmmReg& dst, const XmmReg& count, const Mem128& src)\t\t{AppendInstr(I_VPSRLVQ,\t0x45, E_VEX_128_66_0F38_W1, W(dst), R(src), R(count));}\n\tvoid vpsrlvq(const YmmReg& dst, const YmmReg& count, const YmmReg& src)\t\t{AppendInstr(I_VPSRLVQ,\t0x45, E_VEX_256_66_0F38_W1, W(dst), R(src), R(count));}\n\tvoid vpsrlvq(const YmmReg& dst, const YmmReg& count, const Mem256& src)\t\t{AppendInstr(I_VPSRLVQ,\t0x45, E_VEX_256_66_0F38_W1, W(dst), R(src), R(count));}\n\tvoid vpsubb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PSUBB,\t0xF8, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PSUBB,\t0xF8, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PSUBW,\t0xF9, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PSUBW,\t0xF9, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PSUBD,\t0xFA, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PSUBD,\t0xFA, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PSUBQ,\t0xFB, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PSUBQ,\t0xFB, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubsb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PSUBSB,\t0xE8, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubsb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PSUBSB,\t0xE8, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubsw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PSUBSW,\t0xE9, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubsw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PSUBSW,\t0xE9, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubusb(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PSUBUSB,\t\t0xD8, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubusb(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PSUBUSB,\t\t0xD8, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubusw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PSUBUSW,\t\t0xD9, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpsubusw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PSUBUSW,\t\t0xD9, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpckhbw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PUNPCKHBW,\t0x68, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpckhbw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PUNPCKHBW,\t0x68, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpckhwd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PUNPCKHWD,\t0x69, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpckhwd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PUNPCKHWD,\t0x69, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpckhdq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PUNPCKHDQ,\t0x6A, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpckhdq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PUNPCKHDQ,\t0x6A, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpckhqdq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PUNPCKHQDQ,\t0x6D, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpckhqdq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PUNPCKHQDQ,\t0x6D, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpcklbw(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PUNPCKLBW,\t0x60, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpcklbw(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PUNPCKLBW,\t0x60, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpcklwd(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PUNPCKLWD,\t0x61, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpcklwd(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PUNPCKLWD,\t0x61, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpckldq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PUNPCKLDQ,\t0x62, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpckldq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PUNPCKLDQ,\t0x62, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpcklqdq(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t{AppendInstr(I_PUNPCKLQDQ,\t0x6C, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpunpcklqdq(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t{AppendInstr(I_PUNPCKLQDQ,\t0x6C, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpxor(const YmmReg& dst, const YmmReg& src1, const YmmReg& src2)\t\t{AppendInstr(I_PXOR,\t0xEF, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\tvoid vpxor(const YmmReg& dst, const YmmReg& src1, const Mem256& src2)\t\t{AppendInstr(I_PXOR,\t0xEF, E_VEX_256_66_0F_WIG, W(dst), R(src2), R(src1));}\n\n\n\tstruct ControlState\n\t{\n\t\tsize_t label1;\n\t\tsize_t label2;\n\t};\n\tControlState ctrl_state_;\n\tstd::deque<ControlState> ctrl_state_stack_;\n\n\t// Repeat, Until\n\tvoid Repeat()\n\t{\n\t\tctrl_state_stack_.push_back(ctrl_state_);\n\t\tctrl_state_.label1 = NewLabelID(\"\");\t// begin\n\t\tctrl_state_.label2 = 0;\n\n\t\tL(ctrl_state_.label1);\n\t}\n\ttemplate<class Ty>\n\tvoid Until(const Ty& expr)\n\t{\n\t\tsize_t label = NewLabelID(\"\");\n\t\texpr(*this, ctrl_state_.label1, label);\n\t\tL(label);\n\n\t\tctrl_state_ = *ctrl_state_stack_.rbegin();\n\t\tctrl_state_stack_.pop_back();\n\t}\n\n\t// While, EndW\n\ttemplate<class Ty>\n\tvoid While(const Ty& expr)\n\t{\n\t\tctrl_state_stack_.push_back(ctrl_state_);\n\t\tctrl_state_.label1 = NewLabelID(\"\");\t// begin\n\t\tctrl_state_.label2 = NewLabelID(\"\");\t// end\n\n\t\tsize_t label = NewLabelID(\"\");\n\t\tL(ctrl_state_.label1);\n\t\texpr(*this, label, ctrl_state_.label2);\n\t\tL(label);\n\t}\n\tvoid EndW()\n\t{\n\t\tAppendJmp(ctrl_state_.label1);\n\t\tL(ctrl_state_.label2);\n\n\t\tctrl_state_ = *ctrl_state_stack_.rbegin();\n\t\tctrl_state_stack_.pop_back();\n\t}\n\n\t// If, ElseIf, Else, EndIf\n\ttemplate<class Ty>\n\tvoid If(const Ty& expr)\n\t{\n\t\tctrl_state_stack_.push_back(ctrl_state_);\n\t\tctrl_state_.label1 = NewLabelID(\"\");\t// else\n\t\tctrl_state_.label2 = NewLabelID(\"\");\t// end\n\n\t\tsize_t label = NewLabelID(\"\");\n\t\texpr(*this, label, ctrl_state_.label1);\n\t\tL(label);\n\t}\n\ttemplate<class Ty>\n\tvoid ElseIf(const Ty& expr)\n\t{\n\t\tElse();\n\n\t\tsize_t label = NewLabelID(\"\");\n\t\texpr(*this, label, ctrl_state_.label1);\n\t\tL(label);\n\t}\n\tvoid Else()\n\t{\n\t\tAppendJmp(ctrl_state_.label2);\n\t\tL(ctrl_state_.label1);\n\t\tctrl_state_.label1 = NewLabelID(\"\");\n\t}\n\tvoid EndIf()\n\t{\n\t\tL(ctrl_state_.label1);\n\t\tL(ctrl_state_.label2);\n\n\t\tctrl_state_ = *ctrl_state_stack_.rbegin();\n\t\tctrl_state_stack_.pop_back();\n\t}\n};\n\nReg8 JITASM_ATTRIBUTE_WEAK Frontend::al = Reg8(AL);\nReg8 JITASM_ATTRIBUTE_WEAK Frontend::cl = Reg8(CL);\nReg8 JITASM_ATTRIBUTE_WEAK Frontend::dl = Reg8(DL);\nReg8 JITASM_ATTRIBUTE_WEAK Frontend::bl = Reg8(BL);\nReg8 JITASM_ATTRIBUTE_WEAK Frontend::ah = Reg8(AH);\nReg8 JITASM_ATTRIBUTE_WEAK Frontend::ch = Reg8(CH);\nReg8 JITASM_ATTRIBUTE_WEAK Frontend::dh = Reg8(DH);\nReg8 JITASM_ATTRIBUTE_WEAK Frontend::bh = Reg8(BH);\nReg16 JITASM_ATTRIBUTE_WEAK Frontend::ax = Reg16(AX);\nReg16 JITASM_ATTRIBUTE_WEAK Frontend::cx = Reg16(CX);\nReg16 JITASM_ATTRIBUTE_WEAK Frontend::dx = Reg16(DX);\nReg16 JITASM_ATTRIBUTE_WEAK Frontend::bx = Reg16(BX);\nReg16 JITASM_ATTRIBUTE_WEAK Frontend::sp = Reg16(SP);\nReg16 JITASM_ATTRIBUTE_WEAK Frontend::bp = Reg16(BP);\nReg16 JITASM_ATTRIBUTE_WEAK Frontend::si = Reg16(SI);\nReg16 JITASM_ATTRIBUTE_WEAK Frontend::di = Reg16(DI);\nReg32 JITASM_ATTRIBUTE_WEAK Frontend::eax = Reg32(EAX);\nReg32 JITASM_ATTRIBUTE_WEAK Frontend::ecx = Reg32(ECX);\nReg32 JITASM_ATTRIBUTE_WEAK Frontend::edx = Reg32(EDX);\nReg32 JITASM_ATTRIBUTE_WEAK Frontend::ebx = Reg32(EBX);\nReg32 JITASM_ATTRIBUTE_WEAK Frontend::esp = Reg32(ESP);\nReg32 JITASM_ATTRIBUTE_WEAK Frontend::ebp = Reg32(EBP);\nReg32 JITASM_ATTRIBUTE_WEAK Frontend::esi = Reg32(ESI);\nReg32 JITASM_ATTRIBUTE_WEAK Frontend::edi = Reg32(EDI);\nFpuReg_st0 JITASM_ATTRIBUTE_WEAK Frontend::st0;\nFpuReg JITASM_ATTRIBUTE_WEAK Frontend::st1 = FpuReg(ST1);\nFpuReg JITASM_ATTRIBUTE_WEAK Frontend::st2 = FpuReg(ST2);\nFpuReg JITASM_ATTRIBUTE_WEAK Frontend::st3 = FpuReg(ST3);\nFpuReg JITASM_ATTRIBUTE_WEAK Frontend::st4 = FpuReg(ST4);\nFpuReg JITASM_ATTRIBUTE_WEAK Frontend::st5 = FpuReg(ST5);\nFpuReg JITASM_ATTRIBUTE_WEAK Frontend::st6 = FpuReg(ST6);\nFpuReg JITASM_ATTRIBUTE_WEAK Frontend::st7 = FpuReg(ST7);\nMmxReg JITASM_ATTRIBUTE_WEAK Frontend::mm0 = MmxReg(MM0);\nMmxReg JITASM_ATTRIBUTE_WEAK Frontend::mm1 = MmxReg(MM1);\nMmxReg JITASM_ATTRIBUTE_WEAK Frontend::mm2 = MmxReg(MM2);\nMmxReg JITASM_ATTRIBUTE_WEAK Frontend::mm3 = MmxReg(MM3);\nMmxReg JITASM_ATTRIBUTE_WEAK Frontend::mm4 = MmxReg(MM4);\nMmxReg JITASM_ATTRIBUTE_WEAK Frontend::mm5 = MmxReg(MM5);\nMmxReg JITASM_ATTRIBUTE_WEAK Frontend::mm6 = MmxReg(MM6);\nMmxReg JITASM_ATTRIBUTE_WEAK Frontend::mm7 = MmxReg(MM7);\nXmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm0 = XmmReg(XMM0);\nXmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm1 = XmmReg(XMM1);\nXmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm2 = XmmReg(XMM2);\nXmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm3 = XmmReg(XMM3);\nXmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm4 = XmmReg(XMM4);\nXmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm5 = XmmReg(XMM5);\nXmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm6 = XmmReg(XMM6);\nXmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm7 = XmmReg(XMM7);\nYmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm0 = YmmReg(YMM0);\nYmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm1 = YmmReg(YMM1);\nYmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm2 = YmmReg(YMM2);\nYmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm3 = YmmReg(YMM3);\nYmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm4 = YmmReg(YMM4);\nYmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm5 = YmmReg(YMM5);\nYmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm6 = YmmReg(YMM6);\nYmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm7 = YmmReg(YMM7);\n#ifdef JITASM64\nReg8 JITASM_ATTRIBUTE_WEAK Frontend::r8b  = Reg8(R8B);\nReg8 JITASM_ATTRIBUTE_WEAK Frontend::r9b  = Reg8(R9B);\nReg8 JITASM_ATTRIBUTE_WEAK Frontend::r10b = Reg8(R10B);\nReg8 JITASM_ATTRIBUTE_WEAK Frontend::r11b = Reg8(R11B);\nReg8 JITASM_ATTRIBUTE_WEAK Frontend::r12b = Reg8(R12B);\nReg8 JITASM_ATTRIBUTE_WEAK Frontend::r13b = Reg8(R13B);\nReg8 JITASM_ATTRIBUTE_WEAK Frontend::r14b = Reg8(R14B);\nReg8 JITASM_ATTRIBUTE_WEAK Frontend::r15b = Reg8(R15B);\nReg16 JITASM_ATTRIBUTE_WEAK Frontend::r8w  = Reg16(R8W);\nReg16 JITASM_ATTRIBUTE_WEAK Frontend::r9w  = Reg16(R9W);\nReg16 JITASM_ATTRIBUTE_WEAK Frontend::r10w = Reg16(R10W);\nReg16 JITASM_ATTRIBUTE_WEAK Frontend::r11w = Reg16(R11W);\nReg16 JITASM_ATTRIBUTE_WEAK Frontend::r12w = Reg16(R12W);\nReg16 JITASM_ATTRIBUTE_WEAK Frontend::r13w = Reg16(R13W);\nReg16 JITASM_ATTRIBUTE_WEAK Frontend::r14w = Reg16(R14W);\nReg16 JITASM_ATTRIBUTE_WEAK Frontend::r15w = Reg16(R15W);\nReg32 JITASM_ATTRIBUTE_WEAK Frontend::r8d  = Reg32(R8D);\nReg32 JITASM_ATTRIBUTE_WEAK Frontend::r9d  = Reg32(R9D);\nReg32 JITASM_ATTRIBUTE_WEAK Frontend::r10d = Reg32(R10D);\nReg32 JITASM_ATTRIBUTE_WEAK Frontend::r11d = Reg32(R11D);\nReg32 JITASM_ATTRIBUTE_WEAK Frontend::r12d = Reg32(R12D);\nReg32 JITASM_ATTRIBUTE_WEAK Frontend::r13d = Reg32(R13D);\nReg32 JITASM_ATTRIBUTE_WEAK Frontend::r14d = Reg32(R14D);\nReg32 JITASM_ATTRIBUTE_WEAK Frontend::r15d = Reg32(R15D);\nReg64 JITASM_ATTRIBUTE_WEAK Frontend::rax = Reg64(RAX);\nReg64 JITASM_ATTRIBUTE_WEAK Frontend::rcx = Reg64(RCX);\nReg64 JITASM_ATTRIBUTE_WEAK Frontend::rdx = Reg64(RDX);\nReg64 JITASM_ATTRIBUTE_WEAK Frontend::rbx = Reg64(RBX);\nReg64 JITASM_ATTRIBUTE_WEAK Frontend::rsp = Reg64(RSP);\nReg64 JITASM_ATTRIBUTE_WEAK Frontend::rbp = Reg64(RBP);\nReg64 JITASM_ATTRIBUTE_WEAK Frontend::rsi = Reg64(RSI);\nReg64 JITASM_ATTRIBUTE_WEAK Frontend::rdi = Reg64(RDI);\nReg64 JITASM_ATTRIBUTE_WEAK Frontend::r8  = Reg64(R8);\nReg64 JITASM_ATTRIBUTE_WEAK Frontend::r9  = Reg64(R9);\nReg64 JITASM_ATTRIBUTE_WEAK Frontend::r10 = Reg64(R10);\nReg64 JITASM_ATTRIBUTE_WEAK Frontend::r11 = Reg64(R11);\nReg64 JITASM_ATTRIBUTE_WEAK Frontend::r12 = Reg64(R12);\nReg64 JITASM_ATTRIBUTE_WEAK Frontend::r13 = Reg64(R13);\nReg64 JITASM_ATTRIBUTE_WEAK Frontend::r14 = Reg64(R14);\nReg64 JITASM_ATTRIBUTE_WEAK Frontend::r15 = Reg64(R15);\nXmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm8  = XmmReg(XMM8);\nXmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm9  = XmmReg(XMM9);\nXmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm10 = XmmReg(XMM10);\nXmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm11 = XmmReg(XMM11);\nXmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm12 = XmmReg(XMM12);\nXmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm13 = XmmReg(XMM13);\nXmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm14 = XmmReg(XMM14);\nXmmReg JITASM_ATTRIBUTE_WEAK Frontend::xmm15 = XmmReg(XMM15);\nYmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm8  = YmmReg(YMM8);\nYmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm9  = YmmReg(YMM9);\nYmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm10 = YmmReg(YMM10);\nYmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm11 = YmmReg(YMM11);\nYmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm12 = YmmReg(YMM12);\nYmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm13 = YmmReg(YMM13);\nYmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm14 = YmmReg(YMM14);\nYmmReg JITASM_ATTRIBUTE_WEAK Frontend::ymm15 = YmmReg(YMM15);\nReg64 JITASM_ATTRIBUTE_WEAK Frontend::zax = Reg64(RAX);\nReg64 JITASM_ATTRIBUTE_WEAK Frontend::zcx = Reg64(RCX);\nReg64 JITASM_ATTRIBUTE_WEAK Frontend::zdx = Reg64(RDX);\nReg64 JITASM_ATTRIBUTE_WEAK Frontend::zbx = Reg64(RBX);\nReg64 JITASM_ATTRIBUTE_WEAK Frontend::zsp = Reg64(RSP);\nReg64 JITASM_ATTRIBUTE_WEAK Frontend::zbp = Reg64(RBP);\nReg64 JITASM_ATTRIBUTE_WEAK Frontend::zsi = Reg64(RSI);\nReg64 JITASM_ATTRIBUTE_WEAK Frontend::zdi = Reg64(RDI);\n#else\nReg32 JITASM_ATTRIBUTE_WEAK Frontend::zax = Reg32(EAX);\nReg32 JITASM_ATTRIBUTE_WEAK Frontend::zcx = Reg32(ECX);\nReg32 JITASM_ATTRIBUTE_WEAK Frontend::zdx = Reg32(EDX);\nReg32 JITASM_ATTRIBUTE_WEAK Frontend::zbx = Reg32(EBX);\nReg32 JITASM_ATTRIBUTE_WEAK Frontend::zsp = Reg32(ESP);\nReg32 JITASM_ATTRIBUTE_WEAK Frontend::zbp = Reg32(EBP);\nReg32 JITASM_ATTRIBUTE_WEAK Frontend::zsi = Reg32(ESI);\nReg32 JITASM_ATTRIBUTE_WEAK Frontend::zdi = Reg32(EDI);\n#endif\n\n\nnamespace compiler\n{\n\tstruct BitVector : std::vector<uint32>\n\t{\n\t\tsize_t size_bit() const { return size() * 32; }\n\n\t\tbool get_bit(size_t idx) const\n\t\t{\n\t\t\tconst size_t i = idx / 32;\n\t\t\treturn i < size() && (at(i) & (1 << (idx % 32))) != 0;\n\t\t}\n\n\t\tvoid set_bit(size_t idx, bool b)\n\t\t{\n\t\t\tconst size_t i = idx / 32;\n\t\t\tconst uint32 mask = (1 << (idx % 32));\n\t\t\tif (i >= size()) resize(i + 1);\n\t\t\tif (b)\tat(i) |= mask;\n\t\t\telse\tat(i) &= ~mask;\n\t\t}\n\n\t\tbool is_equal(const BitVector& rhs) const\n\t\t{\n\t\t\tconst size_t min_size = size() < rhs.size() ? size() : rhs.size();\n\t\t\tfor (size_t i = 0; i < min_size; ++i) {\n\t\t\t\tif (at(i) != rhs[i]) return false;\n\t\t\t}\n\n\t\t\tconst BitVector& larger = size() < rhs.size() ? rhs : *this;\n\t\t\tfor (size_t i = min_size; i < larger.size(); ++i) {\n\t\t\t\tif (larger[i] != 0) return false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\tsize_t count_bit() const\n\t\t{\n\t\t\tsize_t count = 0;\n\t\t\tfor (size_t i = 0; i < size(); ++i) {\n\t\t\t\tcount += detail::Count1Bits(at(i));\n\t\t\t}\n\t\t\treturn count;\n\t\t}\n\n\t\tvoid get_bit_indexes(std::vector<size_t>& indexes) const\n\t\t{\n\t\t\tindexes.clear();\n\t\t\tfor (size_t i = 0; i < size(); ++i) {\n\t\t\t\tuint32 m = at(i);\n\t\t\t\twhile (m != 0) {\n\t\t\t\t\tuint32 index = detail::bit_scan_forward(m);\n\t\t\t\t\tindexes.push_back(static_cast<uint32>(i * 32) + index);\n\t\t\t\t\tm &= ~(1 << index);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttemplate<class Fn>\n\t\tvoid query_bit_indexes(Fn& fn) const\n\t\t{\n\t\t\tfor (size_t i = 0; i < size(); ++i) {\n\t\t\t\tuint32 m = at(i);\n\t\t\t\twhile (m != 0) {\n\t\t\t\t\tuint32 index = detail::bit_scan_forward(m);\n\t\t\t\t\tfn(i * 32 + index);\n\t\t\t\t\tm &= ~(1 << index);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid set_union(const BitVector& rhs)\n\t\t{\n\t\t\tif (size() < rhs.size()) resize(rhs.size());\n\t\t\tfor (size_t i = 0; i < rhs.size(); ++i) {\n\t\t\t\tat(i) |= rhs[i];\n\t\t\t}\n\t\t}\n\n\t\tvoid set_subtract(const BitVector& rhs)\n\t\t{\n\t\t\tconst size_t min_size = size() < rhs.size() ? size() : rhs.size();\n\t\t\tfor (size_t i = 0; i < min_size; ++i) {\n\t\t\t\tat(i) &= ~rhs[i];\n\t\t\t}\n\t\t}\n\t};\n\n\ttemplate<class T, size_t N>\n\tclass FixedArray\n\t{\n\tprivate:\n\t\tT data_[N];\n\t\tsize_t size_;\n\n\tpublic:\n\t\tFixedArray() : size_(0) {}\n\t\tbool empty() const {return size_ == 0;}\n\t\tsize_t size() const {return size_;}\n\t\tvoid clear() {size_ = 0;}\n\n\t\tvoid push_back(const T& v) {data_[size_++] = v;}\n\t\tvoid pop_back() {--size_;}\n\n\t\tconst T& operator[](size_t i) const {return data_[i];}\n\t\tT& operator[](size_t i) {return data_[i];}\n\n\t\tconst T& back() const {return data_[size_ - 1];}\n\t\tT& back() {return data_[size_ - 1];}\n\t};\n\n\t/// Register family\n\tinline size_t GetRegFamily(RegType type)\n\t{\n\t\tswitch (type) {\n\t\t\tcase R_TYPE_GP:\t\t\t\treturn 0;\n\t\t\tcase R_TYPE_MMX:\t\t\treturn 1;\n\t\t\tcase R_TYPE_XMM:\t\t\treturn 2;\n\t\t\tcase R_TYPE_YMM:\t\t\treturn 2;\n\t\t\tcase R_TYPE_SYMBOLIC_GP:\treturn 0;\n\t\t\tcase R_TYPE_SYMBOLIC_MMX:\treturn 1;\n\t\t\tcase R_TYPE_SYMBOLIC_XMM:\treturn 2;\n\t\t\tcase R_TYPE_SYMBOLIC_YMM:\treturn 2;\n\t\t\tcase R_TYPE_FPU:\n\t\t\tdefault:\n\t\t\t\tJITASM_ASSERT(0);\n\t\t\t\treturn 0x7FFFFFFF;\n\t\t}\n\t}\n\n\tinline std::string GetRegName(RegType type, size_t reg_idx)\n\t{\n#ifdef JITASM64\n\t\tconst static std::string s_gp_reg_name[] = {\"rax\", \"rcx\", \"rdx\", \"rbx\", \"rsp\", \"rbp\", \"rsi\", \"rdi\", \"r8\", \"r9\", \"r10\", \"r11\", \"r12\", \"r13\", \"r14\", \"r15\"};\n#else\n\t\tconst static std::string s_gp_reg_name[] = {\"eax\", \"ecx\", \"edx\", \"ebx\", \"esp\", \"ebp\", \"esi\", \"edi\"};\n#endif\n\t\tstd::string name;\n\t\tif (type == R_TYPE_GP)\t\t\t\t\t{return s_gp_reg_name[reg_idx];}\n\t\telse if (type == R_TYPE_MMX)\t\t\t{name.assign(\"mm\");}\n\t\telse if (type == R_TYPE_XMM)\t\t\t{name.assign(\"xmm\");}\n\t\telse if (type == R_TYPE_YMM)\t\t\t{name.assign(\"ymm\");}\n\t\telse if (type == R_TYPE_SYMBOLIC_GP)\t{name.assign(\"gpsym\"); reg_idx -= NUM_OF_PHYSICAL_REG;}\n\t\telse if (type == R_TYPE_SYMBOLIC_MMX)\t{name.assign(\"mmsym\"); reg_idx -= NUM_OF_PHYSICAL_REG;}\n\t\telse if (type == R_TYPE_SYMBOLIC_XMM)\t{name.assign(\"xmmsym\"); reg_idx -= NUM_OF_PHYSICAL_REG;}\n\t\telse if (type == R_TYPE_SYMBOLIC_YMM)\t{name.assign(\"ymmsym\"); reg_idx -= NUM_OF_PHYSICAL_REG;}\n\t\tdetail::append_num(name, reg_idx);\n\t\treturn name;\n\t}\n\n\t/// Variable attribute\n\tstruct VarAttribute\n\t{\n\t\tunsigned size : 7;\t// OpdSize\n\t\tunsigned spill : 1;\t// bool\n\t\tAddr stack_slot;\n\t\tVarAttribute() : size(0), spill(0/*false*/), stack_slot(RegID::Invalid(), 0) {}\n\t};\n\n\t/// Variable manager\n\tclass VariableManager\n\t{\n\tprivate:\n\t\tstd::vector<VarAttribute> attributes_[3];\t// GP, MMX, XMM/YMM\n\n\tpublic:\n\t\tstd::vector<VarAttribute>& GetAttributes(size_t reg_family) {return attributes_[reg_family];}\n\t\tconst std::vector<VarAttribute>& GetAttributes(size_t reg_family) const {return attributes_[reg_family];}\n\n\t\t/// Get variable size\n\t\tOpdSize GetVarSize(size_t reg_family, int var) const\n\t\t{\n\t\t\treturn static_cast<OpdSize>(attributes_[reg_family][var].size);\n\t\t}\n\n\t\t/// Update variable size\n\t\tvoid UpdateVarSize(RegType reg_type, int var, OpdSize size)\n\t\t{\n\t\t\tconst size_t reg_family = GetRegFamily(reg_type);\n\t\t\tif (static_cast<size_t>(var) >= attributes_[reg_family].size()) {\n\t\t\t\tattributes_[reg_family].resize(var + 1);\n\t\t\t}\n\n\t\t\tif (attributes_[reg_family][var].size < static_cast<unsigned>(size)) {\n\t\t\t\tattributes_[reg_family][var].size = static_cast<unsigned>(size);\n\t\t\t}\n\t\t}\n\n\t\t/// Get stack slot for spill register\n\t\tAddr GetSpillSlot(size_t reg_family, int var) const\n\t\t{\n\t\t\treturn attributes_[reg_family][var].stack_slot;\n\t\t}\n\n\t\t/// Set stack slot for spill register\n\t\tvoid SetSpillSlot(RegType reg_type, int var, const Addr& stack_slot)\n\t\t{\n\t\t\tconst size_t reg_family = GetRegFamily(reg_type);\n\t\t\tif (static_cast<size_t>(var) >= attributes_[reg_family].size()) {\n\t\t\t\tattributes_[reg_family].resize(var + 1);\n\t\t\t}\n\t\t\tattributes_[reg_family][var].stack_slot = stack_slot;\n\t\t}\n\n\t\t/// Allocate stack of spill slots\n\t\tvoid AllocSpillSlots(detail::StackManager& stack_manager)\n\t\t{\n\t\t\t// YMM\n\t\t\tfor (size_t i = 0; i < attributes_[2].size(); ++i) {\n\t\t\t\tif (attributes_[2][i].spill && attributes_[2][i].size == O_SIZE_256 && attributes_[2][i].stack_slot.reg_.IsInvalid()) {\n\t\t\t\t\tattributes_[2][i].stack_slot = stack_manager.Alloc(256 / 8, 32); // 32 bytes aligned! 16->32 171108\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// XMM\n\t\t\tfor (size_t i = 0; i < attributes_[2].size(); ++i) {\n\t\t\t\tif (attributes_[2][i].spill && attributes_[2][i].size == O_SIZE_128 && attributes_[2][i].stack_slot.reg_.IsInvalid()) {\n\t\t\t\t\tattributes_[2][i].stack_slot = stack_manager.Alloc(128 / 8, 16);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// MMX\n\t\t\tfor (size_t i = 0; i < attributes_[1].size(); ++i) {\n\t\t\t\tif (attributes_[1][i].spill && attributes_[1][i].stack_slot.reg_.IsInvalid()) {\n\t\t\t\t\tattributes_[1][i].stack_slot = stack_manager.Alloc(64 / 8, 8);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// GP\n\t\t\tfor (size_t i = 0; i < attributes_[0].size(); ++i) {\n\t\t\t\tif (attributes_[0][i].spill && attributes_[0][i].stack_slot.reg_.IsInvalid()) {\n#ifdef JITASM64\n\t\t\t\t\tattributes_[0][i].stack_slot = stack_manager.Alloc(64 / 8, 8);\n#else\n\t\t\t\t\tattributes_[0][i].stack_slot = stack_manager.Alloc(32 / 8, 4);\n#endif\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t/// Register use point\n\tstruct RegUsePoint\n\t{\n\t\tsize_t instr_idx;\t\t///< Instruction index offset from basic block start point\n\t\tOpdType type;\t\t\t///< Operand type\n\t\tuint32 reg_assignable;\t///< Register assignment constraint\n\n\t\tRegUsePoint(size_t idx, OpdType t, uint32 assignable) : instr_idx(idx), type(t), reg_assignable(assignable) {}\n\n\t\tbool operator<(const RegUsePoint& rhs) const {\n\t\t\tif (instr_idx == rhs.instr_idx) {\n\t\t\t\t// R < RW < W\n\t\t\t\tconst int lhs_type = (type & O_TYPE_READ ? -1 : 0) + (type & O_TYPE_WRITE ? 1 : 0);\n\t\t\t\tconst int rhs_type = (rhs.type & O_TYPE_READ ? -1 : 0) + (rhs.type & O_TYPE_WRITE ? 1 : 0);\n\t\t\t\treturn lhs_type < rhs_type;\n\t\t\t}\n\t\t\treturn instr_idx < rhs.instr_idx;\n\t\t}\n\t};\n\n\t/// Variable lifetime\n\tstruct Lifetime\n\t{\n\t\ttypedef detail::Range< std::vector<RegUsePoint> >\t\tRegUsePointRange;\n\t\ttypedef detail::ConstRange< std::vector<RegUsePoint> >\tConstRegUsePointRange;\n\n\t\tstruct Interval\n\t\t{\n\t\t\tsize_t instr_idx_offset;\t\t\t\t///< Instruction index offset from basic block start point\n\t\t\tBitVector liveness;\t\t\t\t\t\t///< The set of live variables\n\t\t\tBitVector use;\t\t\t\t\t\t\t///< The set of used variables in this interval\n\t\t\tBitVector spill;\t\t\t\t\t\t///< The set of spilled variables\n\t\t\tstd::vector<uint32> reg_assignables;\t///< The constraints of register allocation\n\t\t\tstd::vector<int> assignment_table;\t\t///< Register assignment table\n\n\t\t\tInterval(size_t instr_idx, const std::vector<uint32>& assignables) : instr_idx_offset(instr_idx), reg_assignables(assignables) {}\n\t\t\tInterval(size_t instr_idx, const BitVector& l, const BitVector& s, const std::vector<uint32>& assignables) : instr_idx_offset(instr_idx), liveness(l), spill(s), reg_assignables(assignables) {}\n\n\t\t\tvoid UpdateUse(size_t var, RegUsePointRange& range, const Interval *next_interval)\n\t\t\t{\n\t\t\t\t// step range\n\t\t\t\twhile (!range.empty() && range.first->instr_idx < instr_idx_offset) {++range.first;}\n\n\t\t\t\t// check if variables used in this interval\n\t\t\t\tconst bool used = !range.empty() && (!next_interval || range.first->instr_idx < next_interval->instr_idx_offset);\n\t\t\t\tuse.set_bit(var, used);\n\t\t\t}\n\n\t\t\tvoid Dump(bool dump_assigned_reg) const\n\t\t\t{\n\t\t\t\tstd::vector<char> liveness_str;\n\t\t\t\tfor (size_t v = 0; v < liveness.size_bit(); ++v) {\n\t\t\t\t\tif (liveness.get_bit(v)) {\n\t\t\t\t\t\tconst bool used = use.get_bit(v);\n\t\t\t\t\t\tchar c;\n\t\t\t\t\t\tif (spill.get_bit(v))\t{\n\t\t\t\t\t\t\tc = used ? 'S' : 's';\n\t\t\t\t\t\t} else if (dump_assigned_reg) {\n\t\t\t\t\t\t\tint reg = assignment_table[v];\n\t\t\t\t\t\t\tc = static_cast<char>(reg < 0xA ? '0' + reg : 'A' + reg);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tc = used ? 'R' : 'r';\n\t\t\t\t\t\t}\n\t\t\t\t\t\tliveness_str.push_back(c);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tliveness_str.push_back('.');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tliveness_str.push_back('\\0');\n\t\t\t\tJITASM_TRACE(\"[%03d] %s\\n\", instr_idx_offset, &liveness_str[0]);\n\t\t\t}\n\t\t};\n\n\t\t// 0 ~ NUM_OF_PHYSICAL_REG-1 : Physical register\n\t\t// NUM_OF_PHYSICAL_REG ~     : Symbolic register\n\t\tstd::vector< std::vector<RegUsePoint> > use_points;\n\t\tBitVector gen;\t\t\t\t\t\t\t///< The set of variables used before any assignment\n\t\tBitVector kill;\t\t\t\t\t\t\t///< The set of variables assigned a value before any use\n\t\tBitVector live_in;\t\t\t\t\t\t///< The set of live variables at the start of this block\n\t\tBitVector live_out;\t\t\t\t\t\t///< The set of live variables at the end of this block\n\t\tbool dirty_live_out;\t\t\t\t\t///< The dirty flag of live_out\n\t\tstd::vector<Interval> intervals;\t\t///< Lifetime intervals\n\n\t\tstatic const int SpillCost_Read = 2;\n\t\tstatic const int SpillCost_Write = 3;\n\n\t\tLifetime() : use_points(NUM_OF_PHYSICAL_REG), dirty_live_out(true) {}\n\n\t\t/// Add register use point\n\t\tvoid AddUsePoint(size_t instr_idx, const RegID& reg, OpdType opd_type, OpdSize opd_size, uint32 reg_assignable)\n\t\t{\n\t\t\tif (use_points.size() <= static_cast<size_t>(reg.id)) {\n\t\t\t\tuse_points.resize(reg.id + 1);\n\t\t\t}\n\n\t\t\t// add read attribute when writing to 8/16bit register because it is partial write\n\t\t\tif ((opd_type & O_TYPE_WRITE) && (opd_size == O_SIZE_8 || opd_size == O_SIZE_16)) {\n\t\t\t\topd_type = static_cast<OpdType>(static_cast<int>(opd_type) | O_TYPE_READ);\n\t\t\t}\n\n\t\t\tRegUsePoint use_point(instr_idx, opd_type, reg_assignable);\n\t\t\tstd::vector<RegUsePoint>::reverse_iterator it = use_points[reg.id].rbegin();\n\t\t\twhile (it != use_points[reg.id].rend() && use_point < *it) {++it;}\n\t\t\tuse_points[reg.id].insert(it.base(), use_point);\n\t\t}\n\n\t\tvoid GetSpillCost(int freq, std::vector<int>& spill_cost) const\n\t\t{\n\t\t\tif (spill_cost.size() < use_points.size()) {\n\t\t\t\tspill_cost.resize(use_points.size());\t// expand\n\t\t\t}\n\t\t\tfor(size_t i = 0; i < use_points.size(); ++i) {\n\t\t\t\tint cost = 0;\n\t\t\t\tfor (std::vector<RegUsePoint>::const_iterator it = use_points[i].begin(); it != use_points[i].end(); ++it) {\n\t\t\t\t\tif (it->type & O_TYPE_READ)  cost += SpillCost_Read;\n\t\t\t\t\tif (it->type & O_TYPE_WRITE) cost += SpillCost_Write;\n\t\t\t\t}\n\t\t\t\tspill_cost[i] += cost * freq;\n\t\t\t}\n\t\t}\n\n\t\tvoid BuildIntervals()\n\t\t{\n\t\t\t// initialize use_points ranges\n\t\t\tstd::vector<RegUsePointRange> use_points_ranges;\n\t\t\tuse_points_ranges.reserve(use_points.size());\n\t\t\tfor (size_t i = 0; i < use_points.size(); ++i) {\n\t\t\t\tuse_points_ranges.push_back(RegUsePointRange(use_points[i]));\n\t\t\t}\n\n\t\t\t// build interval\n\t\t\tBitVector *last_liveness = NULL;\n\t\t\tstd::vector<uint32> reg_assignables;\n\t\t\tbool last_reg_constraints = false;\n\t\t\tbool last_stack_vars = false;\n\t\t\tconst size_t num_of_variables = live_in.size_bit() < use_points.size() ? use_points.size() : live_in.size_bit();\n\t\t\tsize_t instr_idx = 0;\n\t\t\tsize_t end_count;\n\t\t\tdo {\n\t\t\t\tBitVector liveness = live_in;\n\t\t\t\tBitVector stack_vars;\n\t\t\t\tend_count = 0;\n\t\t\t\treg_assignables.clear();\n\t\t\t\tsize_t min_instr_idx = (size_t)-1;\n\t\t\t\tfor (size_t i = 0; i < use_points_ranges.size(); ++i) {\n\t\t\t\t\tif (use_points_ranges[i].empty()) {\n\t\t\t\t\t\tliveness.set_bit(i, live_out.get_bit(i));\n\t\t\t\t\t\t++end_count;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (use_points_ranges[i].first->instr_idx < min_instr_idx) {\n\t\t\t\t\t\t\tmin_instr_idx = use_points_ranges[i].first->instr_idx;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (use_points_ranges[i].first->instr_idx == instr_idx) {\n\t\t\t\t\t\t\tfor (; !use_points_ranges[i].empty() && use_points_ranges[i].first->instr_idx == instr_idx; ++use_points_ranges[i].first) {\n\t\t\t\t\t\t\t\t// Check the constraints of register allocation\n\t\t\t\t\t\t\t\tif (use_points_ranges[i].first->reg_assignable != 0xFFFFFFFF) {\n\t\t\t\t\t\t\t\t\treg_assignables.resize(num_of_variables, 0xFFFFFFFF);\n\t\t\t\t\t\t\t\t\treg_assignables[i] &= use_points_ranges[i].first->reg_assignable;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Check the stack variable\n\t\t\t\t\t\t\t\tif (use_points_ranges[i].first->type & O_TYPE_MEM) {\n\t\t\t\t\t\t\t\t\tstack_vars.set_bit(i, true);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tliveness.set_bit(i, true);\n\t\t\t\t\t\t} else if (use_points_ranges[i].first->type & O_TYPE_READ) {\n\t\t\t\t\t\t\tliveness.set_bit(i, true);\n\t\t\t\t\t\t} else if (use_points_ranges[i].first->type & O_TYPE_WRITE) {\n\t\t\t\t\t\t\tliveness.set_bit(i, false);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tJITASM_ASSERT(0);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Split interval in the following case:\n\t\t\t\t// - The liveness is changed.\n\t\t\t\t// - Current or last instruction has any constraints of register allocation.\n\t\t\t\t// - Last instruction is I_COMPILER_DECLARE_STACK_ARG\n\t\t\t\tif (!reg_assignables.empty() || last_reg_constraints || last_stack_vars || !last_liveness || !last_liveness->is_equal(liveness)) {\n\t\t\t\t\tintervals.push_back(Interval(instr_idx, liveness, stack_vars, reg_assignables));\n\t\t\t\t\tlast_liveness = &intervals.back().liveness;\n\t\t\t\t}\n\n\t\t\t\tlast_reg_constraints = !reg_assignables.empty();\n\t\t\t\tlast_stack_vars = !stack_vars.empty();\n\t\t\t\tinstr_idx = min_instr_idx == instr_idx ? instr_idx + 1 : min_instr_idx;\n\t\t\t} while (end_count < use_points_ranges.size());\n\n\t\t\t// check use\n\t\t\tfor (size_t v = 0; v < use_points.size(); ++v) {\n\t\t\t\tRegUsePointRange range(use_points[v]);\n\t\t\t\tfor (size_t i = 0; i < intervals.size(); ++i) {\n\t\t\t\t\tconst Interval *next_interval  = i + 1 < intervals.size() ? &intervals[i + 1] : NULL;\n\t\t\t\t\tintervals[i].UpdateUse(v, range, next_interval);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// Split interval\n\t\tvoid SplitInterval(size_t instr_idx, size_t interval_idx)\n\t\t{\n\t\t\tstd::vector<Interval>::iterator it = intervals.insert(intervals.begin() + interval_idx + 1, intervals[interval_idx]);\n\t\t\tit->instr_idx_offset = instr_idx;\n\n\t\t\t// update use\n\t\t\tfor (size_t v = 0; v < use_points.size(); ++v) {\n\t\t\t\tRegUsePointRange range(use_points[v]);\n\t\t\t\tfor (size_t i = interval_idx; i < interval_idx + 2; ++i) {\n\t\t\t\t\tconst Interval *next_interval  = i + 1 < intervals.size() ? &intervals[i + 1] : NULL;\n\t\t\t\t\tintervals[i].UpdateUse(v, range, next_interval);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstruct LessCost {\n\t\t\tconst std::vector<int> *cost_;\n\t\t\tLessCost(const std::vector<int> *cost) : cost_(cost) {}\n\t\t\tint get_cost(size_t i) const {return i < cost_->size() ? cost_->at(i) : 0;}\n\t\t\tbool operator()(size_t lhs, size_t rhs) const {return get_cost(lhs) < get_cost(rhs);}\n\t\t};\n\n\t\t/// Spill identification\n\t\tvoid SpillIdentification(uint32 available_reg_count, const std::vector<int>& total_spill_cost, int freq, const Interval *last_interval, std::vector<VarAttribute>& var_attrs)\n\t\t{\n\t\t\t// initialize use_points ranges\n\t\t\tstd::vector<RegUsePointRange> interval_use_points;\n\t\t\tinterval_use_points.reserve(use_points.size());\n\t\t\tfor (size_t i = 0; i < use_points.size(); ++i) {\n\t\t\t\tinterval_use_points.push_back(RegUsePointRange(use_points[i]));\n\t\t\t}\n\n\t\t\tstd::vector<size_t> live_vars;\n\t\t\tstd::vector<int> cur_spill_cost;\n\t\t\tfor (size_t interval_idx = 0; interval_idx < intervals.size(); ++interval_idx) {\n\t\t\t\tconst Interval *prior_interval = interval_idx > 0 ? &intervals[interval_idx - 1] : last_interval;\n\t\t\t\tInterval *cur_interval = &intervals[interval_idx];\n\n\t\t\t\tif (cur_interval->liveness.count_bit() > available_reg_count) {\n\t\t\t\t\tcur_interval->liveness.get_bit_indexes(live_vars);\n\n\t\t\t\t\tconst size_t max_var = live_vars.back();\n\t\t\t\t\tif (var_attrs.size() < max_var + 1) {\n\t\t\t\t\t\tvar_attrs.resize(max_var + 1);\t\t// expand var_attrs\n\t\t\t\t\t}\n\n\t\t\t\t\tcur_spill_cost.resize(max_var + 1);\n\t\t\t\t\tfor (size_t i = 0; i < live_vars.size(); ++i) {\n\t\t\t\t\t\tconst size_t var = live_vars[i];\n\n\t\t\t\t\t\t// step interval_use_points\n\t\t\t\t\t\tif (var < interval_use_points.size()) {\n\t\t\t\t\t\t\twhile (!interval_use_points[var].empty() && interval_use_points[var].first->instr_idx < cur_interval->instr_idx_offset) {++interval_use_points[var].first;}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// calculate spill cost of this interval\n\t\t\t\t\t\tif (cur_interval->use.get_bit(var) && (interval_use_points[var].first->type & O_TYPE_MEM)) {\n\t\t\t\t\t\t\t// special low spill cost if this variable on stack (function arguemnt)\n\t\t\t\t\t\t\tcur_spill_cost[var] = -1;\n\t\t\t\t\t\t} else if (cur_interval->use.get_bit(var) && interval_use_points[var].first->instr_idx == cur_interval->instr_idx_offset) {\n\t\t\t\t\t\t\t// special high spill cost if this variable is used at first instruction of this interval\n\t\t\t\t\t\t\t// because it must not be spilled.\n\t\t\t\t\t\t\tcur_spill_cost[var] = 0x7FFFFFFF;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcur_spill_cost[var] = total_spill_cost[var];\n\t\t\t\t\t\t\tif (prior_interval && !prior_interval->spill.get_bit(var)) {\n\t\t\t\t\t\t\t\tcur_spill_cost[var] += (SpillCost_Read + SpillCost_Write) * freq;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Spill from the smallest cost\n\t\t\t\t\tstd::sort(live_vars.begin(), live_vars.end(), LessCost(&cur_spill_cost));\n\n\t\t\t\t\t// Mark spilled variable.\n\t\t\t\t\t// Split interval if spilled variable is used in this interval.\n\t\t\t\t\t// Find first instruction index using the spilled variable.\n\t\t\t\t\tsize_t split_interval_instr = (size_t)-1;\n\t\t\t\t\tfor (size_t i = 0; i < live_vars.size(); ++i) {\n\t\t\t\t\t\tconst size_t var = live_vars[i];\n\t\t\t\t\t\tconst bool stack_var = (cur_spill_cost[var] < 0);\t\t// It may be function argument on stack\n\t\t\t\t\t\tconst bool spill = (i + available_reg_count < live_vars.size() || stack_var);\n\t\t\t\t\t\tcur_interval->spill.set_bit(var, spill);\n\t\t\t\t\t\tif (spill) {\n\t\t\t\t\t\t\tvar_attrs[var].spill = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (stack_var) {\n\t\t\t\t\t\t\t// Split at next of using stack variable\n\t\t\t\t\t\t\tif (interval_use_points[var].first->instr_idx + 1 < split_interval_instr) {\n\t\t\t\t\t\t\t\tsplit_interval_instr = interval_use_points[var].first->instr_idx + 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (spill && cur_interval->use.get_bit(var)) {\n\t\t\t\t\t\t\t// Split if spilled variable is used in this interval.\n\t\t\t\t\t\t\tif (interval_use_points[var].first->instr_idx < split_interval_instr) {\n\t\t\t\t\t\t\t\tsplit_interval_instr = interval_use_points[var].first->instr_idx;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (split_interval_instr != (size_t)-1) {\n\t\t\t\t\t\tSplitInterval(split_interval_instr, interval_idx);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstruct LessAssignOrder {\n\t\t\tInterval *interval;\n\t\t\tconst Interval *prior_interval;\n\t\t\tLessAssignOrder(Interval *cur, const Interval *prior) : interval(cur), prior_interval(prior) {}\n\t\t\tbool has_constraints(size_t v) const {return v < interval->reg_assignables.size() ? interval->reg_assignables[v] != 0xFFFFFFFF : false;}\n\t\t\tuint32 num_of_assignable(size_t v) const {return v < interval->reg_assignables.size() ? detail::Count1Bits(interval->reg_assignables[v]) : 32;}\n\t\t\tbool operator()(size_t lhs, size_t rhs) const {\n\t\t\t\t// is there any register constraints or not\n\t\t\t\tconst bool lhs_has_constraints = has_constraints(lhs);\n\t\t\t\tconst bool rhs_has_constraints = has_constraints(rhs);\n\t\t\t\tif (lhs_has_constraints != rhs_has_constraints) {\n\t\t\t\t\treturn lhs_has_constraints;\n\t\t\t\t}\n\n\t\t\t\tif (lhs_has_constraints) {\n\t\t\t\t\t// is the register which has constraints used in this interval or not\n\t\t\t\t\tconst bool lhs_used = interval->use.get_bit(lhs);\n\t\t\t\t\tconst bool rhs_used = interval->use.get_bit(rhs);\n\t\t\t\t\tif (lhs_used != rhs_used) {\n\t\t\t\t\t\treturn lhs_used;\n\t\t\t\t\t}\n\n\t\t\t\t\t// compare number of assignable registers\n\t\t\t\t\tconst uint32 lhs_num_of_assignable = num_of_assignable(lhs);\n\t\t\t\t\tconst uint32 rhs_num_of_assignable = num_of_assignable(rhs);\n\t\t\t\t\tif (lhs_num_of_assignable != rhs_num_of_assignable) {\n\t\t\t\t\t\treturn lhs_num_of_assignable < rhs_num_of_assignable;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// physical register or symbolic register\n\t\t\t\tconst int lhs_sym_reg = (lhs < NUM_OF_PHYSICAL_REG ? 0 : 1);\n\t\t\t\tconst int rhs_sym_reg = (rhs < NUM_OF_PHYSICAL_REG ? 0 : 1);\n\t\t\t\tif (lhs_sym_reg != rhs_sym_reg) {\n\t\t\t\t\treturn lhs_sym_reg < rhs_sym_reg;\n\t\t\t\t}\n\n\t\t\t\tif (prior_interval) {\n\t\t\t\t\t// is the variable assigned register in prior interval or not\n\t\t\t\t\tconst bool lhs_prior_reg = !prior_interval->spill.get_bit(lhs) && prior_interval->liveness.get_bit(lhs);\n\t\t\t\t\tconst bool rhs_prior_reg = !prior_interval->spill.get_bit(rhs) && prior_interval->liveness.get_bit(rhs);\n\t\t\t\t\tif (lhs_prior_reg != rhs_prior_reg) {\n\t\t\t\t\t\treturn lhs_prior_reg;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// compare register id\n\t\t\t\treturn lhs < rhs;\n\t\t\t}\n\t\t};\n\n\t\t/// Assign register in basic block\n\t\t/**\n\t\t * \\param[in] available_reg\tAvailable physical register mask\n\t\t * \\param[in] last_interval\tLast Interval as the hint of assignment\n\t\t * \\return Used physical register mask\n\t\t */\n\t\tuint32 AssignRegister(uint32 available_reg, const Interval *last_interval)\n\t\t{\n\t\t\tuint32 used_reg = 0;\n\t\t\tstd::vector<size_t> live_vars;\n\t\t\tfor (size_t interval_idx = 0; interval_idx < intervals.size(); ++interval_idx) {\n\t\t\t\tconst Interval *prior_interval = interval_idx > 0 ? &intervals[interval_idx - 1] : last_interval;\n\t\t\t\tInterval *cur_interval = &intervals[interval_idx];\n\n\t\t\t\t// enum variables to assign register\n\t\t\t\tlive_vars.clear();\n\t\t\t\tfor (size_t i = 0; i < cur_interval->liveness.size(); ++i) {\n\t\t\t\t\tuint32 s = i < cur_interval->spill.size() ? cur_interval->spill[i] : 0;\n\t\t\t\t\tuint32 l = cur_interval->liveness[i] & ~s;\n\t\t\t\t\twhile (l != 0) {\n\t\t\t\t\t\tuint32 index = detail::bit_scan_forward(l);\n\t\t\t\t\t\tlive_vars.push_back(static_cast<uint32>(i * 32) + index);\n\t\t\t\t\t\tl &= ~(1 << index);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!live_vars.empty()) {\n\t\t\t\t\tcur_interval->assignment_table.resize(live_vars.back() + 1, -1);\n\n\t\t\t\t\t// sort into assignment order\n\t\t\t\t\tstd::sort(live_vars.begin(), live_vars.end(), LessAssignOrder(cur_interval, prior_interval));\n\t\t\t\t}\n\n\t\t\t\t// Assign register\n\t\t\t\tuint32 cur_avail = available_reg;\n\t\t\t\tconst size_t num_of_live_vars = live_vars.size();\n\t\t\t\tfor (size_t i = 0; i < live_vars.size(); ++i) {\n\t\t\t\t\tconst size_t var = live_vars[i];\n\t\t\t\t\tconst bool first_try = (i < num_of_live_vars);\t// Try to assign for the first time\n\t\t\t\t\tconst uint32 reg_assignable = first_try && var < cur_interval->reg_assignables.size() ? cur_interval->reg_assignables[var] : 0xFFFFFFFF;\t// Ignore constraint if it is retried\n\t\t\t\t\tJITASM_ASSERT((cur_avail & reg_assignable) != 0);\n\t\t\t\t\tint assigned_reg = -1;\n\t\t\t\t\tif (var < NUM_OF_PHYSICAL_REG && first_try) {\n\t\t\t\t\t\t// Physical register\n\t\t\t\t\t\tif (cur_avail & reg_assignable & (1 << var)) {\n\t\t\t\t\t\t\tassigned_reg = static_cast<int>(var);\n\t\t\t\t\t\t} else if (((1 << var) & available_reg) && !cur_interval->use.get_bit(var)) {\n\t\t\t\t\t\t\t// Try to assign another physical register if it is not used in this interval. But assign later.\n\t\t\t\t\t\t\tlive_vars.push_back(var);\n\t\t\t\t\t\t} else if (reg_assignable != 0xFFFFFFFF && (cur_avail & reg_assignable) && cur_interval->use.get_bit(var)) {\n\t\t\t\t\t\t\t// This physical register violates the register constraint.\n\t\t\t\t\t\t\t// Assign another physical register which satisfy the constraint.\n\t\t\t\t\t\t\tassigned_reg = detail::bit_scan_forward(cur_avail & reg_assignable);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// This may be out of assignment register (ESP, EBP and so on...)\n\t\t\t\t\t\t\tJITASM_ASSERT(((1 << var) & available_reg) == 0);\t\t// false assignment!?\n\t\t\t\t\t\t\tassigned_reg = static_cast<int>(var);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Symbolic register or retried physical register\n\t\t\t\t\t\tconst int last_assigned = prior_interval && var < prior_interval->assignment_table.size() ? prior_interval->assignment_table[var] : -1;\n\t\t\t\t\t\tif (last_assigned != -1 && (cur_avail & reg_assignable & (1 << last_assigned))) {\n\t\t\t\t\t\t\t// select last assigned register\n\t\t\t\t\t\t\tassigned_reg = last_assigned;\n\t\t\t\t\t\t} else if (cur_avail & reg_assignable) {\n\t\t\t\t\t\t\tassigned_reg = detail::bit_scan_forward(cur_avail & reg_assignable);\n\t\t\t\t\t\t} else if (reg_assignable != 0xFFFFFFFF && !cur_interval->use.get_bit(var)) {\n\t\t\t\t\t\t\t// Try to assign register ignoring constraint if it is not used in this interval. But assign later.\n\t\t\t\t\t\t\tlive_vars.push_back(var);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tJITASM_ASSERT(0);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (assigned_reg >= 0) {\n\t\t\t\t\t\tcur_interval->assignment_table[var] = assigned_reg;\n\t\t\t\t\t\tcur_avail &= ~(1 << assigned_reg);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tused_reg |= ~cur_avail & available_reg;\n\t\t\t}\n\n\t\t\treturn used_reg;\n\t\t}\n\n\t\tvoid DumpIntervals(size_t block_id, bool dump_assigned_reg) const\n\t\t{\n\t\t\tavoid_unused_warn(block_id);\n\t\t\tJITASM_TRACE(\"---- Block%d ----\\n\", block_id);\n\t\t\tfor (size_t i = 0; i < intervals.size(); ++i) {\n\t\t\t\tintervals[i].Dump(dump_assigned_reg);\n\t\t\t}\n\t\t}\n\t};\n\n\t/// Basic block\n\tstruct BasicBlock\n\t{\n\t\tBasicBlock *successor[2];\n\t\tstd::vector<BasicBlock *> predecessor;\n\t\tsize_t instr_begin;\t\t\t\t\t///< Begin instruction index of the basic block (inclusive)\n\t\tsize_t instr_end;\t\t\t\t\t///< End instruction index of the basic block (exclusive)\n\t\tsize_t depth;\t\t\t\t\t\t///< Depth-first order of Control flow\n\t\tBasicBlock *dfs_parent;\t\t\t\t///< Depth-first search tree parent\n\t\tBasicBlock *immediate_dominator;\t///< Immediate dominator\n\t\tsize_t loop_depth;\t\t\t\t\t///< Loop nesting depth\n\t\tLifetime lifetime[3];\t\t\t\t///< Variable lifetime (0: GP, 1: MMX, 2: XMM/YMM)\n\n\t\tBasicBlock(size_t instr_begin_, size_t instr_end_, BasicBlock *successor0 = NULL, BasicBlock *successor1 = NULL) : instr_begin(instr_begin_), instr_end(instr_end_), depth((size_t)-1), dfs_parent(NULL), immediate_dominator(NULL), loop_depth(0) {\n\t\t\tsuccessor[0] = successor0;\n\t\t\tsuccessor[1] = successor1;\n\t\t}\n\n\t\tbool operator<(const BasicBlock& rhs) const { return instr_begin < rhs.instr_begin; }\n\n\t\t/// Remove predecessor\n\t\tvoid RemovePredecessor(BasicBlock *block) {\n\t\t\tstd::vector<BasicBlock *>::iterator it = std::find(predecessor.begin(), predecessor.end(), block);\n\t\t\tif (it != predecessor.end()) {\n\t\t\t\tpredecessor.erase(it);\n\t\t\t}\n\t\t}\n\n\t\t/// Replace predecessor\n\t\tbool ReplacePredecessor(BasicBlock *old_pred, BasicBlock *new_pred) {\n\t\t\tstd::vector<BasicBlock *>::iterator it = std::find(predecessor.begin(), predecessor.end(), old_pred);\n\t\t\tif (it != predecessor.end()) {\n\t\t\t\t*it = new_pred;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t/// Check if the specified block is dominator of this block\n\t\tbool IsDominated(BasicBlock *block) const {\n\t\t\tif (block == this) {return true;}\n\t\t\treturn immediate_dominator ? immediate_dominator->IsDominated(block) : false;\n\t\t}\n\n\t\t/// Get estimated frequency of basic block\n\t\tint GetFrequency() const {\n\t\t\tconst static int freq[] = {1, 100, 10000, 40000, 160000, 640000};\n\t\t\treturn freq[loop_depth < sizeof(freq) / sizeof(int) ? loop_depth : sizeof(freq) / sizeof(int) - 1];\n\t\t}\n\n\t\t/// Get variable lifetime\n\t\tLifetime& GetLifetime(RegType type) {return lifetime[GetRegFamily(type)];}\n\t\t/// Get variable lifetime\n\t\tconst Lifetime& GetLifetime(RegType type) const {return lifetime[GetRegFamily(type)];}\n\n\t\tstruct less\n\t\t{\n\t\t\tbool operator()(BasicBlock *lhs, BasicBlock *rhs) { return lhs->instr_begin < rhs->instr_begin; }\n\t\t\tbool operator()(BasicBlock *lhs, size_t rhs) { return lhs->instr_begin < rhs; }\n\t\t\tbool operator()(size_t lhs, BasicBlock *rhs) { return lhs < rhs->instr_begin; }\n\t\t};\n\t};\n\n\t/**\n\t * The Lengauer-Tarjan algorithm\n\t */\n\tclass DominatorFinder\n\t{\n\tprivate:\n\t\tstd::vector<size_t> sdom_;\t\t\t// semidominator\n\t\tstd::vector<size_t> ancestor_;\n\t\tstd::vector<size_t> best_;\n\n\t\tvoid Link(size_t v, size_t w)\n\t\t{\n\t\t\tancestor_[w] = v;\n\t\t}\n\n\t\tsize_t Eval(size_t v)\n\t\t{\n\t\t\tif (ancestor_[v] == 0) return v;\n\t\t\tCompress(v);\n\t\t\treturn best_[v];\n\t\t}\n\n\t\tvoid Compress(size_t v)\n\t\t{\n\t\t\tsize_t a = ancestor_[v];\n\t\t\tif (ancestor_[a] == 0)\n\t\t\t\treturn;\n\n\t\t\tCompress(a);\n\n\t\t\tif (sdom_[best_[v]] > sdom_[best_[a]])\n\t\t\t\tbest_[v] = best_[a];\n\n\t\t\tancestor_[v] = ancestor_[a];\n\t\t}\n\n\tpublic:\n\t\tvoid operator()(std::deque<BasicBlock *>& depth_first_blocks)\n\t\t{\n\t\t\tconst size_t num_of_nodes = depth_first_blocks.size();\n\t\t\tif (num_of_nodes == 0) return;\n\n\t\t\t// initialize\n\t\t\tsdom_.resize(num_of_nodes);\t\t\t// semidominator\n\t\t\tancestor_.clear();\n\t\t\tancestor_.resize(num_of_nodes);\n\t\t\tbest_.resize(num_of_nodes);\n\t\t\tstd::vector< std::vector<size_t> > bucket(num_of_nodes);\n\t\t\tstd::vector<size_t> dom(num_of_nodes);\n\t\t\tfor (size_t i = 0; i < num_of_nodes; ++i) {\n\t\t\t\tsdom_[i] = i;\n\t\t\t\tbest_[i] = i;\n\t\t\t}\n\n\t\t\tfor (size_t w = num_of_nodes - 1; w > 0; --w) {\n\t\t\t\tBasicBlock *wb = depth_first_blocks[w];\n\t\t\t\tsize_t p = wb->dfs_parent->depth;\n\n\t\t\t\t// Compute the semidominator\n\t\t\t\tfor (std::vector<BasicBlock *>::iterator v = wb->predecessor.begin(); v != wb->predecessor.end(); ++v) {\n\t\t\t\t\tif ((*v)->depth != (size_t)-1) {\t// skip out of DFS tree\n\t\t\t\t\t\tsize_t u = Eval((*v)->depth);\n\t\t\t\t\t\tif (sdom_[u] < sdom_[w])\n\t\t\t\t\t\t\tsdom_[w] = sdom_[u];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbucket[sdom_[w]].push_back(w);\n\t\t\t\tLink(p, w);\n\n\t\t\t\t// Implicity compute immediate dominator\n\t\t\t\tfor (std::vector<size_t>::iterator v = bucket[p].begin(); v != bucket[p].end(); ++v) {\n\t\t\t\t\tsize_t u = Eval(*v);\n\t\t\t\t\tdom[*v] = sdom_[u] < sdom_[*v] ? u : p;\n\t\t\t\t}\n\t\t\t\tbucket[p].clear();\n\t\t\t}\n\n\t\t\t// Explicity compute immediate dominator\n\t\t\tfor (size_t w = 1; w < num_of_nodes; ++w) {\n\t\t\t\tif (dom[w] != sdom_[w])\n\t\t\t\t\tdom[w] = dom[dom[w]];\n\t\t\t\tdepth_first_blocks[w]->immediate_dominator = depth_first_blocks[dom[w]];\n\t\t\t}\n\t\t\tdepth_first_blocks[0]->immediate_dominator = NULL;\n\t\t}\n\t};\n\n\t/// Control flow graph\n\tclass ControlFlowGraph\n\t{\n\tpublic:\n\t\ttypedef std::deque<BasicBlock *> BlockList;\n\n\tprivate:\n\t\tBlockList blocks_;\n\t\tBlockList depth_first_blocks_;\n\n\t\tvoid MakeDepthFirstBlocks(BasicBlock *block)\n\t\t{\n\t\t\tblock->depth = 0;\t// mark \"visited\"\n\t\t\tfor (size_t i = 0; i < 2; ++i) {\n\t\t\t\tBasicBlock *s = block->successor[i];\n\t\t\t\tif (s && s->depth != 0) {\n\t\t\t\t\ts->dfs_parent = block;\n\t\t\t\t\tMakeDepthFirstBlocks(s);\n\t\t\t\t}\n\t\t\t}\n\t\t\tdepth_first_blocks_.push_front(block);\n\t\t}\n\n\t\tstruct sort_backedge {\n\t\t\tbool operator()(const std::pair<size_t, size_t>& lhs, const std::pair<size_t, size_t>& rhs) const {\n\t\t\t\tif (lhs.second < rhs.second) return true;\t\t\t\t\t\t// smaller depth loop header first\n\t\t\t\tif (lhs.second == rhs.second) return lhs.first > rhs.first;\t\t// larger depth of end of loop first if same loop header\n\t\t\t\treturn false;\n\t\t\t}\n\t\t};\n\n\t\tvoid DetectLoops()\n\t\t{\n\t\t\t// Make dominator tree\n\t\t\tDominatorFinder dom_finder;\n\t\t\tdom_finder(depth_first_blocks_);\n\n\t\t\t// Identify backedges\n\t\t\tstd::vector< std::pair<size_t, size_t> > backedges;\n\t\t\tfor (size_t i = 0; i < depth_first_blocks_.size(); ++i) {\n\t\t\t\tBasicBlock *block = depth_first_blocks_[i];\n\t\t\t\tfor (size_t j = 0; j < 2; ++j) {\n\t\t\t\t\tif (block->successor[j] && block->depth >= block->successor[j]->depth) {\t\t// retreating edge\n\t\t\t\t\t\tif (block->IsDominated(block->successor[j])) {\n\t\t\t\t\t\t\tbackedges.push_back(std::make_pair(block->depth, block->successor[j]->depth));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Merge loops with the same loop header\n\t\t\tstd::sort(backedges.begin(), backedges.end(), sort_backedge());\n\t\t\tif (backedges.size() >= 2) {\n\t\t\t\tstd::vector< std::pair<size_t, size_t> >::iterator it = backedges.begin() + 1;\n\t\t\t\twhile (it != backedges.end()) {\n\t\t\t\t\tif (detail::prior(it)->second == it->second) {\n\t\t\t\t\t\t// erase backedge of smaller loop\n\t\t\t\t\t\tit = backedges.erase(it);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t++it;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set loop depth\n\t\t\tfor (std::vector< std::pair<size_t, size_t> >::iterator it = backedges.begin(); it != backedges.end(); ++it) {\n\t\t\t\tfor (size_t i = it->second; i <= it->first; ++i) {\n\t\t\t\t\tdepth_first_blocks_[i]->loop_depth++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tBlockList::iterator initialize(size_t num_of_instructions) {\n\t\t\tclear();\n\t\t\tblocks_.resize(num_of_instructions > 0 ? 2 : 1);\n\t\t\tBasicBlock *enter_block = new BasicBlock(0, num_of_instructions);\n\t\t\tblocks_[0] = enter_block;\n\t\t\tif (num_of_instructions > 0) {\n\t\t\t\t// exit block\n\t\t\t\tBasicBlock *exit_block = new BasicBlock(num_of_instructions, num_of_instructions);\n\t\t\t\tblocks_[1] = exit_block;\n\t\t\t\tenter_block->successor[0] = exit_block;\n\t\t\t\texit_block->predecessor.push_back(enter_block);\n\t\t\t}\n\t\t\treturn blocks_.begin();\n\t\t}\n\n\t\t/// Split basic block\n\t\tBlockList::iterator split(BlockList::iterator target_block_it, size_t instr_idx) {\n\t\t\tBasicBlock *target_block = *target_block_it;\n\t\t\tif (target_block->instr_begin == instr_idx)\n\t\t\t\treturn target_block_it;\n\n\t\t\tBasicBlock *new_block = new BasicBlock(instr_idx, target_block->instr_end);\n\t\t\tnew_block->successor[0] = target_block->successor[0];\n\t\t\tnew_block->successor[1] = target_block->successor[1];\n\t\t\tnew_block->predecessor.push_back(target_block);\n\t\t\ttarget_block->successor[0] = new_block;\n\t\t\ttarget_block->successor[1] = NULL;\n\t\t\ttarget_block->instr_end = instr_idx;\n\n\t\t\t// replace predecessor of successors\n\t\t\tif (new_block->successor[0]) new_block->successor[0]->ReplacePredecessor(target_block, new_block);\n\t\t\tif (new_block->successor[1]) new_block->successor[1]->ReplacePredecessor(target_block, new_block);\n\n\t\t\treturn blocks_.insert(detail::next(target_block_it), new_block);\n\t\t}\n\n\tpublic:\n\t\t~ControlFlowGraph()\n\t\t{\n\t\t\tclear();\n\t\t}\n\n\t\tBlockList::iterator get_block(size_t instr_idx) {\n\t\t\tBlockList::iterator it = std::upper_bound(blocks_.begin(), blocks_.end(), instr_idx, BasicBlock::less());\n\t\t\treturn it != blocks_.begin() ? --it : blocks_.end();\n\t\t}\n\n\t\tBlockList::iterator get_exit_block() {\n\t\t\treturn detail::prior(blocks_.end());\n\t\t}\n\n\t\tsize_t size() { return blocks_.size(); }\n\n\t\tvoid clear()\n\t\t{\n\t\t\tfor (BlockList::iterator it = blocks_.begin(); it != blocks_.end(); ++it) {\n\t\t\t\tdelete *it;\n\t\t\t}\n\t\t\tblocks_.clear();\n\t\t\tdepth_first_blocks_.clear();\n\t\t}\n\n\t\tBlockList::iterator begin() { return blocks_.begin(); }\n\t\tBlockList::iterator end() { return blocks_.end(); }\n\t\tBlockList::const_iterator begin() const { return blocks_.begin(); }\n\t\tBlockList::const_iterator end() const { return blocks_.end(); }\n\t\tBlockList::iterator dfs_begin() { return depth_first_blocks_.begin(); }\n\t\tBlockList::iterator dfs_end() { return depth_first_blocks_.end(); }\n\n\t\tvoid DumpDot() const\n\t\t{\n\t\t\tJITASM_TRACE(\"digraph CFG {\\n\");\n\t\t\tJITASM_TRACE(\"\\tnode[shape=box];\\n\");\n\t\t\tfor (BlockList::const_iterator it = blocks_.begin(); it != blocks_.end(); ++it) {\n\t\t\t\tBasicBlock *block = *it;\n\t\t\t\tstd::string live_in = \"live in:\";\n\t\t\t\tstd::string live_out = \"live out:\";\n\t\t\t\tfor (size_t reg_family = 0; reg_family < 3; ++reg_family) {\n\t\t\t\t\tfor (size_t i = 0; i < block->lifetime[reg_family].live_in.size_bit(); ++i) {\n\t\t\t\t\t\tif (block->lifetime[reg_family].live_in.get_bit(i)) {\n\t\t\t\t\t\t\tlive_in.append(\" \");\n\t\t\t\t\t\t\tlive_in.append(GetRegName(static_cast<RegType>(reg_family + (i < NUM_OF_PHYSICAL_REG ? R_TYPE_GP : R_TYPE_SYMBOLIC_GP)), i));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfor (size_t i = 0; i < block->lifetime[reg_family].live_out.size_bit(); ++i) {\n\t\t\t\t\t\tif (block->lifetime[reg_family].live_out.get_bit(i)) {\n\t\t\t\t\t\t\tlive_out.append(\" \");\n\t\t\t\t\t\t\tlive_out.append(GetRegName(static_cast<RegType>(reg_family + (i < NUM_OF_PHYSICAL_REG ? R_TYPE_GP : R_TYPE_SYMBOLIC_GP)), i));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tJITASM_TRACE(\"\\tnode%d[label=\\\"Block%d\\\\ninstruction %d - %d\\\\nloop depth %d\\\\n%s\\\\n%s\\\"];\\n\", block->instr_begin, block->depth, block->instr_begin, block->instr_end - 1, block->loop_depth, live_in.c_str(), live_out.c_str());\n\t\t\t\tint constraint = 0; avoid_unused_warn(constraint);\n\t\t\t\tif (block->successor[0]) JITASM_TRACE(\"\\t\\\"node%d\\\" -> \\\"node%d\\\" [constraint=%s];\\n\", block->instr_begin, block->successor[0]->instr_begin, constraint == 0 ? \"true\" : \"false\");\n\t\t\t\tif (block->successor[1]) JITASM_TRACE(\"\\t\\\"node%d\\\" -> \\\"node%d\\\" [constraint=%s];\\n\", block->instr_begin, block->successor[1]->instr_begin, constraint == 0 ? \"true\" : \"false\");\n\t\t\t\t//if (block->dfs_parent) JITASM_TRACE(\"\\t\\\"node%d\\\" -> \\\"node%d\\\" [color=\\\"#ff0000\\\"];\\n\", block->instr_begin, block->dfs_parent->instr_begin);\n\t\t\t\t//if (block->immediate_dominator) JITASM_TRACE(\"\\t\\\"node%d\\\" -> \\\"node%d\\\" [constraint=false, color=\\\"#0000ff\\\"];\\n\", block->instr_begin, block->immediate_dominator->instr_begin);\n\t\t\t\t//for (size_t i = 0; i < block->predecessor.size(); ++i) {\n\t\t\t\t//\tJITASM_TRACE(\"\\t\\\"node%d\\\" -> \\\"node%d\\\" [constraint=false, color=\\\"#808080\\\"];\\n\", block->instr_begin, block->predecessor[i]->instr_begin);\n\t\t\t\t//}\n\t\t\t}\n\t\t\tJITASM_TRACE(\"}\\n\");\n\t\t}\n\n\t\t/// Build control flow graph from instruction list\n\t\tvoid Build(const Frontend& f)\n\t\t{\n\t\t\tinitialize(f.instrs_.size());\n\t\t\tsize_t block_idx = 0;\n\t\t\tfor (size_t instr_idx = 0; instr_idx < f.instrs_.size(); ++instr_idx) {\n\t\t\t\tInstrID instr_id = f.instrs_[instr_idx].GetID();\n\t\t\t\tif (Frontend::IsJump(instr_id) || instr_id == I_RET || instr_id == I_IRET) {\n\t\t\t\t\twhile (blocks_[block_idx]->instr_end <= instr_idx) {\n\t\t\t\t\t\t++block_idx;\n\t\t\t\t\t}\n\t\t\t\t\tBasicBlock *cur_block = blocks_[block_idx];\n\t\t\t\t\tJITASM_ASSERT(block_idx == std::distance(blocks_.begin(), get_block(instr_idx)));\n\n\t\t\t\t\t// Jump instruction always terminate basic block\n\t\t\t\t\tif (instr_idx + 1 < cur_block->instr_end) {\n\t\t\t\t\t\t// Split basic block\n\t\t\t\t\t\tsplit(blocks_.begin() + block_idx, instr_idx + 1);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Set successors of current block\n\t\t\t\t\tif (instr_id == I_RET || instr_id == I_IRET) {\n\t\t\t\t\t\tif (cur_block->successor[0])\n\t\t\t\t\t\t\tcur_block->successor[0]->RemovePredecessor(cur_block);\n\t\t\t\t\t\tcur_block->successor[0] = *get_exit_block();\n\t\t\t\t\t\t(*get_exit_block())->predecessor.push_back(cur_block);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst size_t jump_to = f.GetJumpTo(f.instrs_[instr_idx]);\t// jump target instruction index\n\t\t\t\t\t\tBasicBlock *jump_target = *split(get_block(jump_to), jump_to);\n\n\t\t\t\t\t\t// Update cur_block if split cur_block\n\t\t\t\t\t\tif (jump_target->instr_begin <= instr_idx && instr_idx < jump_target->instr_end) {\n\t\t\t\t\t\t\tcur_block = jump_target;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (instr_id == I_JMP) {\n\t\t\t\t\t\t\tif (cur_block->successor[0])\n\t\t\t\t\t\t\t\tcur_block->successor[0]->RemovePredecessor(cur_block);\n\t\t\t\t\t\t\tcur_block->successor[0] = jump_target;\n\t\t\t\t\t\t\tjump_target->predecessor.push_back(cur_block);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tJITASM_ASSERT(instr_id == I_JCC || instr_id == I_LOOP);\n\t\t\t\t\t\t\tif (cur_block->successor[1])\n\t\t\t\t\t\t\t\tcur_block->successor[1]->RemovePredecessor(cur_block);\n\t\t\t\t\t\t\tcur_block->successor[1] = jump_target;\n\t\t\t\t\t\t\tjump_target->predecessor.push_back(cur_block);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Make depth first orderd list\n\t\t\tMakeDepthFirstBlocks(*get_block(0));\n\n\t\t\t// Numbering depth\n\t\t\tfor (size_t i = 0; i < depth_first_blocks_.size(); ++i) {\n\t\t\t\tdepth_first_blocks_[i]->depth = i;\n\t\t\t}\n\n\t\t\t// Detect loops\n\t\t\tDetectLoops();\n\t\t}\n\n\t\t/// Build dummy control flow graph which has enter and exit blocks.\n\t\tvoid BuildDummy(const Frontend& f)\n\t\t{\n\t\t\tBasicBlock *enter_block = *initialize(f.instrs_.size());\n\t\t\tBasicBlock *exit_block = enter_block->successor[0];\n\n\t\t\tenter_block->depth = 0;\n\t\t\tdepth_first_blocks_.push_back(enter_block);\n\t\t\tif (exit_block) {\n\t\t\t\texit_block->depth = 1;\n\t\t\t\texit_block->dfs_parent = enter_block;\n\t\t\t\texit_block->immediate_dominator = enter_block;\n\t\t\t\tdepth_first_blocks_.push_back(exit_block);\n\t\t\t}\n\t\t}\n\t};\n\n\t/// Prepare compile\n\t/**\n\t * - Re-number symbolic register ID.\n\t * - Check if register allocation is needed or not.\n\t * - Look over physical register use.\n\t *\n\t * \\param[in,out]  instrs\t\t\t\t\tInstruction list\n\t * \\param[out]     modified_physical_reg\tModified physical register mask\n\t * \\param[out]     need_reg_alloc\t\t\tRegister allocation is needed or not\n\t * \\return There is any compile process if it is true.\n\t */\n\tinline bool PrepareCompile(Frontend::InstrList& instrs, uint32 (&modified_physical_reg)[3], bool (&need_reg_alloc)[3])\n\t{\n\t\tstruct RegIDMap {\n\t\t\tint next_id_;\n\t\t\tstd::map<int, int> id_map_;\n\t\t\tRegIDMap() : next_id_(NUM_OF_PHYSICAL_REG) {}\n\t\t\tint GetNormalizedID(int id) {\n\t\t\t\tstd::map<int, int>::iterator it = id_map_.find(id);\n\t\t\t\tif (it != id_map_.end()) {return it->second;}\n\t\t\t\tint new_id = next_id_++;\n\t\t\t\tid_map_.insert(std::pair<int, int>(id, new_id));\n\t\t\t\treturn new_id;\n\t\t\t}\n\t\t};\n\t\tRegIDMap reg_id_map[3];\t\t// GP, MMX, XMM/YMM\n\t\tmodified_physical_reg[0] = modified_physical_reg[1] = modified_physical_reg[2] = 0;\n\t\tneed_reg_alloc[0] = need_reg_alloc[1] = need_reg_alloc[2] = false;\n\t\tbool compile_process = false;\n\n\t\tfor (Frontend::InstrList::iterator it = instrs.begin(); it != instrs.end(); ++it) {\n\t\t\tconst InstrID instr_id = it->GetID();\n\t\t\tif (instr_id == I_COMPILER_DECLARE_REG_ARG || instr_id == I_COMPILER_DECLARE_STACK_ARG || instr_id == I_COMPILER_DECLARE_RESULT_REG || instr_id == I_COMPILER_PROLOG || instr_id == I_COMPILER_EPILOG) {\n\t\t\t\tcompile_process = true;\n\t\t\t}\n\n\t\t\tfor (size_t i = 0; i < Instr::MAX_OPERAND_COUNT; ++i) {\n\t\t\t\tdetail::Opd& opd = it->GetOpd(i);\n\t\t\t\tif (opd.IsReg() && !opd.IsFpuReg()) {\n\t\t\t\t\tconst RegID& reg = opd.GetReg();\n\t\t\t\t\tconst size_t reg_family = GetRegFamily(reg.GetType());\n\t\t\t\t\tif (reg.IsSymbolic()) {\n\t\t\t\t\t\topd.reg_.id = reg_id_map[reg_family].GetNormalizedID(reg.id);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (opd.IsWrite()) {\n\t\t\t\t\t\t\t// This physical register is modified\n\t\t\t\t\t\t\tmodified_physical_reg[reg_family] |= (1 << reg.id);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ((opd.reg_assignable_ & (1 << reg.id)) == 0) {\n\t\t\t\t\t\t\t// Specified physical register does not fit the instruction.\n\t\t\t\t\t\t\t// Let's try to assign optimal physical register by register allocation.\n\t\t\t\t\t\t\tneed_reg_alloc[reg_family] = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (opd.IsMem()) {\n\t\t\t\t\tconst RegID& base = opd.GetBase();\n\t\t\t\t\tif (base.IsSymbolic()) {\n\t\t\t\t\t\topd.base_.id = reg_id_map[0].GetNormalizedID(base.id);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst RegID& index = opd.GetIndex();\n\t\t\t\t\tif (index.IsSymbolic()) {\n\t\t\t\t\t\topd.index_.id = reg_id_map[GetRegFamily(index.GetType())].GetNormalizedID(index.id);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (size_t i = 0; i < 3; ++i) {\n\t\t\tif (!need_reg_alloc[i] && reg_id_map[i].next_id_ > NUM_OF_PHYSICAL_REG) {\n\t\t\t\tneed_reg_alloc[i] = true;\n\t\t\t}\n\t\t}\n\n\t\treturn compile_process || need_reg_alloc[0] || need_reg_alloc[1] || need_reg_alloc[2];\n\t}\n\n\t/// Check the instruction if it break register dependence\n\tinline bool IsBreakDependenceInstr(const Instr& instr)\n\t{\n\t\t// Instructions\n\t\t// SUB, SBB, XOR, PXOR, XORPS, XORPD, PANDN, PSUBxx, PCMPxx\n\t\tconst InstrID id = instr.GetID();\n\t\tif (id == I_SUB || id == I_SBB || id == I_XOR || id == I_PXOR || id == I_XORPS || id == I_XORPD || id == I_PANDN ||\n\t\t\tid == I_PSUBB || id == I_PSUBW || id == I_PSUBD || id == I_PSUBQ || id == I_PSUBSB || id == I_PSUBSW || id == I_PSUBUSB || id == I_PSUBUSW ||\n\t\t\tid == I_PCMPEQB || id == I_PCMPEQW || id == I_PCMPEQD || id == I_PCMPEQQ || id == I_PCMPGTB || id == I_PCMPGTW || id == I_PCMPGTD || id == I_PCMPGTQ) {\n\t\t\t// source and destination operands are the same register.\n\t\t\t// 8bit or 16bit register cannot break dependence.\n\t\t\tconst detail::Opd& opd0 = instr.GetOpd(0);\n\t\t\tconst detail::Opd& opd1 = instr.GetOpd(1);\n\t\t\tconst OpdSize opdsize = opd0.GetSize();\n\t\t\tif (opd0 == opd1 && opd0.IsReg() && opdsize != O_SIZE_8 && opdsize != O_SIZE_16) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t/// Live Variable Analysis\n\tinline void LiveVariableAnalysis(const Frontend& f, ControlFlowGraph& cfg, VariableManager& var_manager)\n\t{\n\t\tstd::vector<BasicBlock *> update_target;\n\t\tupdate_target.reserve(cfg.size());\n\n\t\tfor (ControlFlowGraph::BlockList::iterator it = cfg.begin(); it != cfg.end(); ++it) {\n\t\t\tBasicBlock *block = *it;\n\t\t\t// Scanning instructions of basic block and make register lifetime table\n\t\t\tfor (size_t i = block->instr_begin; i != block->instr_end; ++i) {\n\t\t\t\tconst size_t instr_offset = i - block->instr_begin;\n\t\t\t\tconst Instr& instr = f.instrs_[i];\n\t\t\t\tif (instr.GetID() == I_COMPILER_DECLARE_REG_ARG) {\n\t\t\t\t\t// Declare function argument on register\n\t\t\t\t\tconst detail::Opd& opd0 = instr.GetOpd(0);\n\t\t\t\t\tconst RegID& reg = opd0.GetReg();\n\t\t\t\t\t// Avoid passing operand size 8 or 16 to AddUsePoint\n\t\t\t\t\t// because they are treated as partial access register and cause miss assignment of register.\n\t\t\t\t\tOpdSize opd_size = opd0.GetSize();\n\t\t\t\t\tif (opd_size == O_SIZE_8 || opd_size == O_SIZE_16) {\n\t\t\t\t\t\topd_size = O_SIZE_32;\n\t\t\t\t\t}\n\t\t\t\t\tconst detail::Opd& opd1 = instr.GetOpd(1);\n\t\t\t\t\tblock->GetLifetime(reg.GetType()).AddUsePoint(instr_offset, reg, opd0.GetType(), opd_size, opd0.reg_assignable_);\n\t\t\t\t\tif (opd1.IsMem()) {\n\t\t\t\t\t\tvar_manager.SetSpillSlot(reg.GetType(), reg.id, Addr(opd1.GetBase(), opd1.GetDisp()));\n\t\t\t\t\t}\n\t\t\t\t} else if (instr.GetID() == I_COMPILER_DECLARE_STACK_ARG) {\n\t\t\t\t\t// Declare function argument on stack\n\t\t\t\t\t// The register variable starts \"spill\" state by O_TYPE_MEM of AddUsePoint\n\t\t\t\t\tconst detail::Opd& opd0 = instr.GetOpd(0);\t// Register variable.\n\t\t\t\t\tconst RegID& reg = opd0.GetReg();\n\t\t\t\t\t// Avoid passing operand size 8 or 16 to AddUsePoint\n\t\t\t\t\t// because they are treated as partial access register and cause miss assignment of register.\n\t\t\t\t\tOpdSize opd_size = opd0.GetSize();\n\t\t\t\t\tif (opd_size == O_SIZE_8 || opd_size == O_SIZE_16) {\n\t\t\t\t\t\topd_size = O_SIZE_32;\n\t\t\t\t\t}\n\t\t\t\t\tconst detail::Opd& opd1 = instr.GetOpd(1);\t// Argument\n\t\t\t\t\tblock->GetLifetime(reg.GetType()).AddUsePoint(instr_offset, reg, static_cast<OpdType>(O_TYPE_MEM | O_TYPE_WRITE), opd_size, opd0.reg_assignable_);\n\t\t\t\t\tvar_manager.SetSpillSlot(reg.GetType(), reg.id, Addr(opd1.GetBase(), opd1.GetDisp()));\n\t\t\t\t} else if (instr.GetID() == I_COMPILER_DECLARE_RESULT_REG) {\n\t\t\t\t\t// Declare function result on register\n\t\t\t\t\tconst detail::Opd& opd0 = instr.GetOpd(0);\n\t\t\t\t\tconst RegID& reg = opd0.GetReg();\n\t\t\t\t\tblock->GetLifetime(reg.GetType()).AddUsePoint(instr_offset, reg, opd0.GetType(), opd0.GetSize(), opd0.reg_assignable_);\n\t\t\t\t} else if (IsBreakDependenceInstr(instr)) {\n\t\t\t\t\t// Add only 1 use point if the instruction that break register dependence\n\t\t\t\t\tconst detail::Opd& opd = instr.GetOpd(0);\n\t\t\t\t\tconst RegID& reg = opd.GetReg();\n\t\t\t\t\tblock->GetLifetime(reg.GetType()).AddUsePoint(instr_offset, reg, static_cast<OpdType>(O_TYPE_REG | O_TYPE_WRITE), opd.GetSize(), opd.reg_assignable_);\n\t\t\t\t\tvar_manager.UpdateVarSize(reg.GetType(), reg.id, opd.GetSize());\n\t\t\t\t} else if (instr.GetID() == I_PUSHAD || instr.GetID() == I_POPAD) {\n\t\t\t\t\t// Add use point of pushad/popad\n\t\t\t\t\tconst OpdType type = static_cast<OpdType>(O_TYPE_REG | (instr.GetID() == I_PUSHAD ? O_TYPE_READ : O_TYPE_WRITE));\n\t\t\t\t\tblock->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_GP, EAX), type, O_SIZE_32, 0xFFFFFFFF);\n\t\t\t\t\tblock->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_GP, ECX), type, O_SIZE_32, 0xFFFFFFFF);\n\t\t\t\t\tblock->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_GP, EDX), type, O_SIZE_32, 0xFFFFFFFF);\n\t\t\t\t\tblock->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_GP, EBX), type, O_SIZE_32, 0xFFFFFFFF);\n\t\t\t\t\tblock->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_GP, EBP), type, O_SIZE_32, 0xFFFFFFFF);\n\t\t\t\t\tblock->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_GP, ESI), type, O_SIZE_32, 0xFFFFFFFF);\n\t\t\t\t\tblock->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_GP, EDI), type, O_SIZE_32, 0xFFFFFFFF);\n\t\t\t\t\tblock->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_GP, ESP), static_cast<OpdType>(O_TYPE_REG | O_TYPE_READ | O_TYPE_WRITE), O_SIZE_32, 0xFFFFFFFF);\n\t\t\t\t} else if (instr.GetID() == I_VZEROALL || instr.GetID() == I_VZEROUPPER) {\n\t\t\t\t\t// Add use point of vzeroall/vzeroupper\n\t\t\t\t\tconst OpdType type = static_cast<OpdType>(O_TYPE_REG | (instr.GetID() == I_VZEROALL ? O_TYPE_WRITE : O_TYPE_READ | O_TYPE_WRITE));\n\t\t\t\t\tfor (int j = 0; j < NUM_OF_PHYSICAL_REG; ++j) {\n\t\t\t\t\t\tblock->GetLifetime(R_TYPE_YMM).AddUsePoint(instr_offset, RegID::CreatePhysicalRegID(R_TYPE_YMM, static_cast<PhysicalRegID>(YMM0 + j)), type, O_SIZE_256, 0xFFFFFFFF);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Add each use point of all operands\n\t\t\t\t\tfor (size_t j = 0; j < Instr::MAX_OPERAND_COUNT; ++j) {\n\t\t\t\t\t\tconst detail::Opd& opd = instr.GetOpd(j);\n\t\t\t\t\t\tif (opd.IsGpReg() || opd.IsMmxReg() || opd.IsXmmReg() || opd.IsYmmReg()) {\n\t\t\t\t\t\t\t// Register operand\n\t\t\t\t\t\t\tconst RegID& reg = opd.GetReg();\n\t\t\t\t\t\t\tblock->GetLifetime(reg.GetType()).AddUsePoint(instr_offset, reg, opd.GetType(), opd.GetSize(), opd.reg_assignable_);\n\t\t\t\t\t\t\tvar_manager.UpdateVarSize(reg.GetType(), reg.id, opd.GetSize());\n\t\t\t\t\t\t} else if (opd.IsMem()) {\n\t\t\t\t\t\t\t// Memory operand\n\t\t\t\t\t\t\tconst RegID& base = opd.GetBase();\n\t\t\t\t\t\t\tif (!base.IsInvalid()) {\n\t\t\t\t\t\t\t\tblock->GetLifetime(R_TYPE_GP).AddUsePoint(instr_offset, base, static_cast<OpdType>(O_TYPE_REG | O_TYPE_READ), opd.GetAddressBaseSize(), 0xFFFFFFFF);\n\t\t\t\t\t\t\t\tvar_manager.UpdateVarSize(R_TYPE_GP, base.id, opd.GetAddressBaseSize());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst RegID& index = opd.GetIndex();\n\t\t\t\t\t\t\tif (!index.IsInvalid()) {\n\t\t\t\t\t\t\t\tblock->GetLifetime(index.GetType()).AddUsePoint(instr_offset, index, static_cast<OpdType>(O_TYPE_REG | O_TYPE_READ), opd.GetAddressIndexSize(), 0xFFFFFFFF);\n\t\t\t\t\t\t\t\tvar_manager.UpdateVarSize(index.GetType(), index.id, opd.GetAddressIndexSize());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Make GEN and KILL set\n\t\t\tfor (size_t reg_family = 0; reg_family < 3; ++reg_family) {\n\t\t\t\tLifetime& lifetime = block->lifetime[reg_family];\n\t\t\t\tconst size_t num_of_used_reg = lifetime.use_points.size();\n\t\t\t\tfor (size_t i = 0; i < num_of_used_reg; ++i) {\n\t\t\t\t\tif (!lifetime.use_points[i].empty()) {\n\t\t\t\t\t\tOpdType type = lifetime.use_points[i][0].type;\n\t\t\t\t\t\tif (type & O_TYPE_READ) {\n\t\t\t\t\t\t\tlifetime.gen.set_bit(i, true);\t// GEN\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tJITASM_ASSERT(type & O_TYPE_WRITE);\n\t\t\t\t\t\t\tlifetime.kill.set_bit(i, true);\t// KILL\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tupdate_target.push_back(block);\n\t\t}\n\n\t\twhile (!update_target.empty()) {\n\t\t\tBasicBlock *block = update_target.back();\n\t\t\tupdate_target.pop_back();\n\t\t\tfor (size_t reg_family = 0; reg_family < 3; ++reg_family) {\n\t\t\t\tLifetime& lifetime = block->lifetime[reg_family];\n\t\t\t\tif (lifetime.dirty_live_out) {\n\t\t\t\t\t// live_out is the union of the live_in of the successors\n\t\t\t\t\tfor (size_t i = 0; i < 2; ++i) {\n\t\t\t\t\t\tif (block->successor[i]) {\n\t\t\t\t\t\t\tlifetime.live_out.set_union(block->successor[i]->lifetime[reg_family].live_in);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tlifetime.dirty_live_out = false;\n\n\t\t\t\t\t// live_in = gen OR (live_out - kill)\n\t\t\t\t\tBitVector new_live_in = lifetime.live_out;\n\t\t\t\t\tnew_live_in.set_subtract(lifetime.kill);\n\t\t\t\t\tnew_live_in.set_union(lifetime.gen);\n\n\t\t\t\t\tif (!lifetime.live_in.is_equal(new_live_in)) {\n\t\t\t\t\t\tlifetime.live_in.swap(new_live_in);\n\n\t\t\t\t\t\tfor (size_t i = 0; i < block->predecessor.size(); ++i) {\n\t\t\t\t\t\t\tblock->predecessor[i]->lifetime[reg_family].dirty_live_out = true;\n\t\t\t\t\t\t\tupdate_target.push_back(block->predecessor[i]);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/// Linear scan register allocation\n\t/**\n\t * \\param[in,out] cfg\t\t\tControl flow graph and additional information\n\t * \\param[in]     reg_family\tRegister family\n\t * \\param[in]     available_reg\tAvailable physical register mask\n\t * \\param[out]    var_attrs\t\tVariable attributes\n\t * \\return\tUsed physical register mask\n\t */\n\tinline uint32 LinearScanRegisterAlloc(ControlFlowGraph& cfg, size_t reg_family, uint32 available_reg, std::vector<VarAttribute>& var_attrs)\n\t{\n\t\tconst uint32 available_reg_count = detail::Count1Bits(available_reg);\n\n\t\tstd::vector<int> total_spill_cost;\n\t\tfor (ControlFlowGraph::BlockList::iterator block = cfg.begin(); block != cfg.end(); ++block) {\n\t\t\t(*block)->lifetime[reg_family].BuildIntervals();\n\t\t\t(*block)->lifetime[reg_family].GetSpillCost((*block)->GetFrequency(), total_spill_cost);\n\t\t}\n\n\t\tuint32 used_reg = 0;\n\t\tconst Lifetime::Interval *last_interval = NULL;\n\t\tsize_t last_loop_depth = 0;\n\t\tfor (ControlFlowGraph::BlockList::iterator block = cfg.dfs_begin(); block != cfg.dfs_end(); ++block) {\n\t\t\tLifetime& lifetime = (*block)->lifetime[reg_family];\n\t\t\tconst size_t loop_depth = (*block)->loop_depth;\n\n\t\t\t// Spill identification\n\t\t\tlifetime.SpillIdentification(available_reg_count, total_spill_cost, (*block)->GetFrequency(), last_loop_depth == loop_depth ? last_interval : NULL, var_attrs);\n\n\t\t\t// Register assignment\n\t\t\tused_reg |= lifetime.AssignRegister(available_reg, last_interval);\n\n#ifdef JITASM_DEBUG_DUMP\n\t\t\tlifetime.DumpIntervals((*block)->depth, true);\n#endif\n\t\t\tif (!lifetime.intervals.empty()) {\n\t\t\t\tlast_interval = &lifetime.intervals.back();\n\t\t\t\tlast_loop_depth = loop_depth;\n\t\t\t}\n\t\t}\n\n\t\treturn used_reg;\n\t}\n\n\t/// General purpose register operator\n\tstruct GpRegOperator\n\t{\n\t\tFrontend *f_;\n\t\tconst VariableManager *var_manager_;\n\n\t\tGpRegOperator(Frontend *f, const VariableManager *var_manager) : f_(f), var_manager_(var_manager) {}\n\n\t\tvoid Move(PhysicalRegID dst_reg, PhysicalRegID src_reg, OpdSize /*size*/)\n\t\t{\n\t\t\tf_->mov(Reg(dst_reg), Reg(src_reg));\n\t\t}\n\n\t\tvoid Swap(PhysicalRegID reg1, PhysicalRegID reg2, OpdSize /*size*/)\n\t\t{\n\t\t\tf_->xchg(Reg(reg1), Reg(reg2));\n\t\t}\n\n\t\tvoid Load(PhysicalRegID dst_reg, int var)\n\t\t{\n\t\t\tf_->mov(Reg(dst_reg), f_->ptr[var_manager_->GetSpillSlot(0, var)]);\n\t\t}\n\n\t\tvoid Store(int var, PhysicalRegID src_reg)\n\t\t{\n\t\t\tf_->mov(f_->ptr[var_manager_->GetSpillSlot(0, var)], Reg(src_reg));\n\t\t}\n\t};\n\n\t/// MMX register operator\n\tstruct MmxRegOperator\n\t{\n\t\tFrontend *f_;\n\t\tconst VariableManager *var_manager_;\n\n\t\tMmxRegOperator(Frontend *f, const VariableManager *var_manager) : f_(f), var_manager_(var_manager) {}\n\n\t\tvoid Move(PhysicalRegID dst_reg, PhysicalRegID src_reg, OpdSize /*size*/)\n\t\t{\n\t\t\tf_->movq(MmxReg(dst_reg), MmxReg(src_reg));\n\t\t}\n\n\t\tvoid Swap(PhysicalRegID reg1, PhysicalRegID reg2, OpdSize /*size*/)\n\t\t{\n\t\t\tf_->pxor(MmxReg(reg1), MmxReg(reg2));\n\t\t\tf_->pxor(MmxReg(reg2), MmxReg(reg1));\n\t\t\tf_->pxor(MmxReg(reg1), MmxReg(reg2));\n\t\t}\n\n\t\tvoid Load(PhysicalRegID dst_reg, int var)\n\t\t{\n\t\t\tf_->movq(MmxReg(dst_reg), f_->mmword_ptr[var_manager_->GetSpillSlot(1, var)]);\n\t\t}\n\n\t\tvoid Store(int var, PhysicalRegID src_reg)\n\t\t{\n\t\t\tf_->movq(f_->mmword_ptr[var_manager_->GetSpillSlot(1, var)], MmxReg(src_reg));\n\t\t}\n\t};\n\n\t/// XMM/YMM register operator\n\tstruct XmmRegOperator\n\t{\n\t\tFrontend *f_;\n\t\tconst VariableManager *var_manager_;\n\n\t\tXmmRegOperator(Frontend *f, const VariableManager *var_manager) : f_(f), var_manager_(var_manager) {}\n\n\t\tvoid Move(PhysicalRegID dst_reg, PhysicalRegID src_reg, OpdSize size)\n\t\t{\n\t\t\tif (size == O_SIZE_128) {\n\t\t\t\tif (f_->avx_epilog_) // PF AVS+ anti AVX-SSE2 penalty\n\t\t\t\t\tf_->vmovaps(XmmReg(dst_reg), XmmReg(src_reg));\n\t\t\t\telse\n\t\t\t\t\tf_->movaps(XmmReg(dst_reg), XmmReg(src_reg));\n\t\t\t} else if (size == O_SIZE_256) {\n\t\t\t\tf_->vmovaps(YmmReg(dst_reg), YmmReg(src_reg));\n\t\t\t} else {\n\t\t\t\tJITASM_ASSERT(0);\n\t\t\t}\n\t\t}\n\n\t\tvoid Swap(PhysicalRegID reg1, PhysicalRegID reg2, OpdSize size)\n\t\t{\n\t\t\tif (size == O_SIZE_128) {\n\t\t\t\tif (f_->avx_epilog_) { // PF AVS+ anti AVX-SSE2 penalty\n\t\t\t\t\tf_->vxorps(XmmReg(reg1), XmmReg(reg1), XmmReg(reg2));\n\t\t\t\t\tf_->vxorps(XmmReg(reg2), XmmReg(reg2), XmmReg(reg1));\n\t\t\t\t\tf_->vxorps(XmmReg(reg1), XmmReg(reg1), XmmReg(reg2));\n\t\t\t\t} else {\n\t\t\t\t\tf_->xorps(XmmReg(reg1), XmmReg(reg2));\n\t\t\t\t\tf_->xorps(XmmReg(reg2), XmmReg(reg1));\n\t\t\t\t\tf_->xorps(XmmReg(reg1), XmmReg(reg2));\n\t\t\t\t}\n\t\t\t} else if (size == O_SIZE_256) {\n\t\t\t\tf_->vxorps(YmmReg(reg1), YmmReg(reg1), YmmReg(reg2));\n\t\t\t\tf_->vxorps(YmmReg(reg2), YmmReg(reg1), YmmReg(reg2));\n\t\t\t\tf_->vxorps(YmmReg(reg1), YmmReg(reg1), YmmReg(reg2));\n\t\t\t} else {\n\t\t\t\tJITASM_ASSERT(0);\n\t\t\t}\n\t\t}\n\n\t\tvoid Load(PhysicalRegID dst_reg, int var)\n\t\t{\n\t\t\tconst OpdSize size = var_manager_->GetVarSize(2, var);\n\t\t\tif (size == O_SIZE_128) {\n\t\t\t\tif (f_->avx_epilog_) // PF AVS+ anti AVX-SSE2 penalty\n\t\t\t\t\tf_->vmovaps(XmmReg(dst_reg), f_->xmmword_ptr[var_manager_->GetSpillSlot(2, var)]);\n\t\t\t\telse\n\t\t\t\t\tf_->movaps(XmmReg(dst_reg), f_->xmmword_ptr[var_manager_->GetSpillSlot(2, var)]);\n\t\t\t} else if (size == O_SIZE_256) {\n\t\t\t\tf_->vmovaps(YmmReg(dst_reg), f_->ymmword_ptr[var_manager_->GetSpillSlot(2, var)]);\n\t\t\t} else {\n\t\t\t\tJITASM_ASSERT(0);\n\t\t\t}\n\t\t}\n\n\t\tvoid Store(int var, PhysicalRegID src_reg)\n\t\t{\n\t\t\tconst OpdSize size = var_manager_->GetVarSize(2, var);\n\t\t\tif (size == O_SIZE_128) {\n\t\t\t\tif (f_->avx_epilog_) // PF AVS+ anti AVX-SSE2 penalty\n\t\t\t\t\tf_->vmovaps(f_->xmmword_ptr[var_manager_->GetSpillSlot(2, var)], XmmReg(src_reg));\n\t\t\t\telse\n\t\t\t\t\tf_->movaps(f_->xmmword_ptr[var_manager_->GetSpillSlot(2, var)], XmmReg(src_reg));\n\t\t\t} else if (size == O_SIZE_256) {\n\t\t\t\tf_->vmovaps(f_->ymmword_ptr[var_manager_->GetSpillSlot(2, var)], YmmReg(src_reg));\n\t\t\t} else {\n\t\t\t\tJITASM_ASSERT(0);\n\t\t\t}\n\t\t}\n\t};\n\n\t/// Strongly connected components finder\n\t/**\n\t * Tarjan's algorithm\n\t */\n\tclass SCCFinder {\n\tprivate:\n\t\tstruct Node {\n\t\t\tint index;\n\t\t\tint lowlink;\n\t\t\tNode() : index(-1) {}\n\t\t};\n\t\tNode nodes_[NUM_OF_PHYSICAL_REG];\n\t\tint *successors_;\n\t\tint index;\n\t\tFixedArray<int, NUM_OF_PHYSICAL_REG> scc_;\n\n\t\t/// Is v in scc_?\n\t\tbool IsInsideSCC(int v) const\n\t\t{\n\t\t\tfor (size_t i = 0; i < scc_.size(); ++i) {\n\t\t\t\tif (scc_[i] == v) {return true;}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\ttemplate<class Fn> void Find(int v, Fn& fn)\n\t\t{\n\t\t\tnodes_[v].index = index;\n\t\t\tnodes_[v].lowlink = index;\n\t\t\t++index;\n\t\t\tscc_.push_back(v);\n\t\t\tconst int w = successors_[v];\n\t\t\tif (w != -1) {\n\t\t\t\tif (nodes_[w].index == -1) {\n\t\t\t\t\t// successor w has not been visited yet\n\t\t\t\t\tFind(w, fn);\n\t\t\t\t\tif (nodes_[w].lowlink < nodes_[v].lowlink) {\n\t\t\t\t\t\tnodes_[v].lowlink = nodes_[w].lowlink;\n\t\t\t\t\t}\n\t\t\t\t} else if (IsInsideSCC(w)) {\n\t\t\t\t\t// successor w is in scc_\n\t\t\t\t\tif (nodes_[w].index < nodes_[v].lowlink) {\n\t\t\t\t\t\tnodes_[v].lowlink = nodes_[w].index;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (nodes_[v].lowlink == nodes_[v].index && !scc_.empty()) {\n\t\t\t\t// v is the root of scc_\n\t\t\t\tsize_t i = 0;\n\t\t\t\twhile (scc_[i] != v) {++i;}\n\t\t\t\tfn(&scc_[i], scc_.size() - i);\n\t\t\t\twhile (i < scc_.size()) {scc_.pop_back();}\n\t\t\t}\n\t\t}\n\n\tpublic:\n\t\tSCCFinder(int *successors) : successors_(successors), index(0) {}\n\n\t\ttemplate<class Fn> void operator()(Fn fn)\n\t\t{\n\t\t\tfor (int v = 0; v < NUM_OF_PHYSICAL_REG; ++v) {\n\t\t\t\tif (successors_[v] != -1 && nodes_[v].index == -1) {\n\t\t\t\t\tFind(v, fn);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tstruct Operations {\n\t\tint move[NUM_OF_PHYSICAL_REG];\n\t\tint load[NUM_OF_PHYSICAL_REG];\n\t\tint store[NUM_OF_PHYSICAL_REG];\n\t\tOpdSize size[NUM_OF_PHYSICAL_REG];\n\t\tstd::pair<const Lifetime::Interval *, const Lifetime::Interval *> interval;\n\t\tconst std::vector<VarAttribute> *var_attrs;\n\n\t\tOperations(const Lifetime::Interval *first, const Lifetime::Interval *second, const std::vector<VarAttribute> *vattrs) : interval(first, second), var_attrs(vattrs) {\n\t\t\tfor (size_t i = 0; i < NUM_OF_PHYSICAL_REG; ++i) {move[i] = load[i] = store[i] = -1;}\n\t\t}\n\n\t\tvoid operator()(size_t var) {\n\t\t\tif (interval.second->liveness.get_bit(var)) {\n\t\t\t\tconst bool first_spill = interval.first->spill.get_bit(var);\n\t\t\t\tconst bool second_spill = interval.second->spill.get_bit(var);\n\t\t\t\tif (!first_spill) {\n\t\t\t\t\tconst int first_reg = interval.first->assignment_table[var];\n\t\t\t\t\tif (!second_spill) {\n\t\t\t\t\t\t// register -> register\n\t\t\t\t\t\tmove[first_reg] = interval.second->assignment_table[var];\n\t\t\t\t\t\tsize[first_reg] = static_cast<OpdSize>(var_attrs->at(var).size);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// register -> stack\n\t\t\t\t\t\tstore[first_reg] = static_cast<int>(var);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (!second_spill) {\n\t\t\t\t\t\t// stack -> register\n\t\t\t\t\t\tload[interval.second->assignment_table[var]] = static_cast<int>(var);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// stack -> stack\n\t\t\t\t\t\t// do nothing\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\n\ttemplate<class RegOp>\n\tstruct MoveGenerator {\n\t\tint *moves_;\n\t\tOpdSize *sizes_;\n\t\tRegOp *reg_operator_;\n\t\tMoveGenerator(int *moves, OpdSize *sizes, RegOp *reg_operator) : moves_(moves), sizes_(sizes), reg_operator_(reg_operator) {}\n\t\tvoid operator()(const int *scc, size_t count) {\n\t\t\tif (count > 1) {\n\t\t\t\tstd::vector<std::pair<int, int>> real_moves; // PF 20171210 track real register usage\n\t\t\t\tfor (size_t i = 0; i < count - 1; ++i) {\n\t\t\t\t\tconst int r = scc[i];\n\t\t\t\t\tJITASM_ASSERT(r != moves_[r] && moves_[r] != -1); // sanity check: cannot move to itself, cannot move to undefined\n\t\t\t\t\t/*\n\t\t\t\t\tPF 20171210 track real register usage\n\t\t\t\t\tOld: reg_operator_->Swap(static_cast<PhysicalRegID>(moves_[r]), static_cast<PhysicalRegID>(r), sizes_[r]);\n\t\t\t\t\tresults in wrong code for multiple xchg: does not take into account previous exchanges\n\t\t\t\t\txchg        edi, ecx\n\t\t\t\t\txchg        esi, edi\n\t\t\t\t\txchg        edx, esi\n\t\t\t\t\tnew code:\n\t\t\t\t\txchg        edi,ecx (-> edi = _ecx, ecx = _edi)\n\t\t\t\t\txchg        esi,ecx (-> esi = ecx (esi = _edi), ecx = _esi)\n\t\t\t\t\txchg        edx,ecx (-> edx = ecx (edx = _esi), ecx = _edx)\n\t\t\t\t\t*/\n\n\t\t\t\t\t// When swapping registers, all register exchanges which took role in swap should be renamed\n\t\t\t\t\tint _this1 = moves_[r];\n\t\t\t\t\tint _this2 = r;\n\t\t\t\t\tfor (size_t j = 0; j < real_moves.size(); j++) {\n\t\t\t\t\tint _test_this1 = real_moves[j].first;\n\t\t\t\t\tint _test_this2 = real_moves[j].second;\n\t\t\t\t\tif (_this1 == _test_this1)\n\t\t\t\t\t\t_this1 = _test_this2;\n\t\t\t\t\telse if (_this1 == _test_this2)\n\t\t\t\t\t\t_this1 = _test_this1;\n\t\t\t\t\tif (_this2 == _test_this1)\n\t\t\t\t\t\t_this2 = _test_this2;\n\t\t\t\t\telse if (_this2 == _test_this2)\n\t\t\t\t\t\t_this2 = _test_this1;\n\t\t\t\t\t}\n\t\t\t\t\treal_moves.push_back(std::make_pair(_this1, _this2));\n\t\t\t\t\treg_operator_->Swap(static_cast<PhysicalRegID>(_this1), static_cast<PhysicalRegID>(_this2), sizes_[_this2]);\n\n\t\t\t\t\tJITASM_TRACE(\"Swap%d %d <-> %d\\n\", sizes_[r], moves_[r], r);\n\t\t\t\t}\n\t\t\t} else if (moves_[scc[0]] != scc[0] && moves_[scc[0]] != -1) {\n\t\t\t\tconst int r = scc[0];\n\t\t\t\treg_operator_->Move(static_cast<PhysicalRegID>(moves_[r]), static_cast<PhysicalRegID>(r), sizes_[r]);\n\t\t\t\tJITASM_TRACE(\"Move%d %d -> %d\\n\", sizes_[r], r, moves_[r]);\n\t\t\t}\n\t\t}\n\t};\n\n\t/// Generate inter-interval instructions\n\t/**\n\t * - Move register\n\t * - Load from stack slot\n\t * - Store to stack slot\n\t */\n\ttemplate<class RegOp>\n\tinline void GenerateInterIntervalInstr(const Lifetime::Interval& first_interval, const Lifetime::Interval& second_interval, const std::vector<VarAttribute>& var_attrs, RegOp reg_operator)\n\t{\n#ifdef JITASM_DEBUG_DUMP\n\t\tfirst_interval.Dump(true);\n#endif\n\n\t\tOperations ops(&first_interval, &second_interval, &var_attrs);\n\t\tfirst_interval.liveness.query_bit_indexes(ops);\n\n\t\t// Store instructions\n\t\tfor (size_t r = 0; r < NUM_OF_PHYSICAL_REG; ++r) {\n\t\t\tif (ops.store[r] != -1) {\n\t\t\t\treg_operator.Store(ops.store[r], static_cast<PhysicalRegID>(r));\n\t\t\t\tJITASM_TRACE(\"Store %d (physical reg %d)\\n\", ops.store[r], r);\n\t\t\t}\n\t\t}\n\n\t\t// Move instructions\n\t\tSCCFinder scc_finder(ops.move);\n\t\tscc_finder(MoveGenerator<RegOp>(ops.move, ops.size, &reg_operator));\n\n\t\t// Load instructions\n\t\tfor (size_t r = 0; r < NUM_OF_PHYSICAL_REG; ++r) {\n\t\t\tif (ops.load[r] != -1) {\n\t\t\t\treg_operator.Load(static_cast<PhysicalRegID>(r), ops.load[r]);\n\t\t\t\tJITASM_TRACE(\"Load %d (physical reg %d)\\n\", ops.load[r], r);\n\t\t\t}\n\t\t}\n\n#ifdef JITASM_DEBUG_DUMP\n\t\tsecond_interval.Dump(true);\n#endif\n\t}\n\n\t/// Generate inter-block instructions\n\tinline void GenerateInterBlockInstr(const BasicBlock *first_block, const BasicBlock *second_block, Frontend& f, const VariableManager& var_manager)\n\t{\n\t\tif (!first_block->lifetime[0].intervals.empty() && !second_block->lifetime[0].intervals.empty()) {\n\t\t\tJITASM_TRACE(\"---- General purpose register ----\\n\");\n\t\t\tGenerateInterIntervalInstr(first_block->lifetime[0].intervals.back(), second_block->lifetime[0].intervals.front(), var_manager.GetAttributes(0), GpRegOperator(&f, &var_manager));\n\t\t}\n\t\tif (!first_block->lifetime[1].intervals.empty() && !second_block->lifetime[1].intervals.empty()) {\n\t\t\tJITASM_TRACE(\"---- MMX register ----\\n\");\n\t\t\tGenerateInterIntervalInstr(first_block->lifetime[1].intervals.back(), second_block->lifetime[1].intervals.front(), var_manager.GetAttributes(1), MmxRegOperator(&f, &var_manager));\n\t\t}\n\t\tif (!first_block->lifetime[2].intervals.empty() && !second_block->lifetime[2].intervals.empty()) {\n\t\t\tJITASM_TRACE(\"---- XMM/YMM register ----\\n\");\n\t\t\tGenerateInterIntervalInstr(first_block->lifetime[2].intervals.back(), second_block->lifetime[2].intervals.front(), var_manager.GetAttributes(2), XmmRegOperator(&f, &var_manager));\n\t\t}\n\t}\n\n\t/// Generate prolog instructions\n\tinline void GenerateProlog(Frontend& f, const uint32 (&preserved_reg)[3], const Addr& preserved_reg_stack)\n\t{\n\t\tavoid_unused_warn(preserved_reg_stack);\n\n\t\t// Save & Make frame pointer\n\t\tf.push(f.zbp);\n\t\tf.mov(f.zbp, f.zsp);\n\n\t\tsize_t stack_size = f.stack_manager_.GetSize();\n\n\t\t// Save general-purpose registers\n\t\tsize_t num_of_preserved_gp_reg = 0;\n\t\tfor (uint32 reg_mask = preserved_reg[0]; reg_mask != 0; ++num_of_preserved_gp_reg) {\n\t\t\tuint32 reg_id = detail::bit_scan_forward(reg_mask);\n\t\t\tf.push(Reg(static_cast<PhysicalRegID>(reg_id)));\n\t\t\treg_mask &= ~(1 << reg_id);\n\t\t}\n\n#ifdef JITASM64\n\t\t// rsp is 16 bytes aligned in Windows x64\n\n\t\t// Stack base\n\t\tif (stack_size > 0) {\n\t\t\t// do the same stack_size adjust in epilog\n\t\t\tif (f.avx_epilog_) {\n\t\t\t\t// general purpose registers are saved already, num_of_preserved_gp_reg*8 bytes\n\t\t\t\t// number of general purpose registers:\n\t\t\t\t// even -> rsp 16 byte aligned\n\t\t\t\t// odd  -> rsp 8 byte aligned\n\t\t\t\tf.mov(f.rbx, f.rsp);\n\t\t\t\t// Now rbx becomes the pointer for saving spilled XMM6-15 (x64-compulsory) and\n\t\t\t\t// temporary storage for the local variables (reg, xmm, ymm)\n\t\t\t\t// Because we use vmovaps (aligned store/load) for ymm, 32 byte alignment needed for base\n\t\t\t\t// like and rbx, -32; ffffffffffffffe0H (r64 with imm32: sign extended)\n\t\t\t\tf.and_(f.rbx, -32); // align 32 bytes\n\n\t\t\t\t// padding for keep alignment (16 bytes for rsp)\n\t\t\t\tif (num_of_preserved_gp_reg & 1)\n\t\t\t\t\tstack_size += 16+8; // 8 or 24. Worst case.\n\t\t\t\telse\n\t\t\t\t\tstack_size += 16; // 0 or 16 Worst case.\n\t\t\t} else if (num_of_preserved_gp_reg & 1) {\n\t\t\t\t// Copy with alignment\n\t\t\t\tf.lea(f.rbx, f.ptr[f.rsp - 8]);\n\t\t\t\tstack_size += 8;\t// padding for keep alignment\n\t\t\t} else {\n\t\t\t\tf.mov(f.rbx, f.rsp);\n\t\t\t}\n\t\t}\n#else\n\t\tif (stack_size > 0) {\n\t\t\t// Align stack pointer\n\t\t\tif (f.avx_epilog_)\n\t\t\t\tf.and_(f.esp, 0xFFFFFFE0); // 32 byte alignment for aligned local ymm spill register storage\n\t\t\telse\n\t\t\t\tf.and_(f.esp, 0xFFFFFFF0); // 16 byte alignment\n\t\t\t// in x86 we don't adjust stack_size here, esp is restored by ebp\n\t\t\t// Stack base\n\t\t\tf.mov(f.ebx, f.esp);\n\t\t}\n#endif\n\n\t\t// Move stack pointer\n\t\tif (stack_size > 0) {\n\t\t\tf.sub(f.zsp, static_cast<uint32>(stack_size));\n\t\t}\n\n#ifdef JITASM64\n\t\t// Save xmm registers\n\t\tuint32 xmm_reg_mask = preserved_reg[2];\n\t\tfor (size_t i = 0; xmm_reg_mask != 0; ++i) {\n\t\t\tuint32 reg_id = detail::bit_scan_forward(xmm_reg_mask);\n\t\t\tif (f.avx_epilog_) // PF AVS+ anti AVX->SSE2 penalty\n\t\t\t\tf.vmovaps(f.xmmword_ptr[preserved_reg_stack + 16 * i], XmmReg(static_cast<PhysicalRegID>(reg_id)));\n\t\t\telse\n\t\t\t\tf.movaps(f.xmmword_ptr[preserved_reg_stack + 16 * i], XmmReg(static_cast<PhysicalRegID>(reg_id)));\n\t\t\txmm_reg_mask &= ~(1 << reg_id);\n\t\t}\n#endif\n\t}\n\n\t/// Generate epilog instructions\n\tinline void GenerateEpilog(Frontend& f, const uint32 (&preserved_reg)[3], const Addr& preserved_reg_stack)\n\t{\n\t\tavoid_unused_warn(preserved_reg_stack);\n\n\t\tsize_t stack_size = f.stack_manager_.GetSize();\n\t\tconst size_t num_of_preserved_gp_reg = detail::Count1Bits(preserved_reg[0]);\n\n#ifdef JITASM64\n\t\t// Restore xmm registers\n\t\t// Push the register id and index by saved order\n\t\tFixedArray<uint32, 16> regs;\n\t\tfor (uint32 reg_mask = preserved_reg[2]; reg_mask != 0; ) {\n\t\t\tuint32 reg_id = detail::bit_scan_forward(reg_mask);\n\t\t\tregs.push_back(reg_id);\n\t\t\treg_mask &= ~(1 << reg_id);\n\t\t}\n\n\t\t// Insert restore instruction by inverse order\n\t\twhile (!regs.empty()) {\n\t\t\t// PF AVS+: generate vmovaps to avoid AVX->SSE2 penalty\n\t\t\tif (f.avx_epilog_)\n\t\t\t\tf.vmovaps(XmmReg(static_cast<PhysicalRegID>(regs.back())), f.xmmword_ptr[preserved_reg_stack + 16 * (regs.size() - 1)]);\n\t\t\telse\n\t\t\t\tf.movaps(XmmReg(static_cast<PhysicalRegID>(regs.back())), f.xmmword_ptr[preserved_reg_stack + 16 * (regs.size() - 1)]);\n\t\t\tregs.pop_back();\n\t\t}\n\n\t\t// Move stack pointer\n\t\tif (stack_size > 0) {\n\t\t\t// same calculation like in prolog\n\t\t\tif (f.avx_epilog_) {\n\t\t\t\tif (num_of_preserved_gp_reg & 1)\n\t\t\t\t\tstack_size += 16 + 8; // 8 or 24. Worst case.\n\t\t\t\telse\n\t\t\t\t\tstack_size += 16; // 0 or 16 Worst case.\n\t\t\t} else if (num_of_preserved_gp_reg & 1) {\n\t\t\t\tstack_size += 8;\t// padding for keep alignment\n\t\t\t}\n\t\t\tf.add(f.zsp, static_cast<uint32>(stack_size));\n\t\t}\n#else\n\t\t// Move stack pointer\n\t\tif (stack_size > 0) {\n\t\t\tf.lea(f.zsp, f.ptr[f.zbp - num_of_preserved_gp_reg * 4]);\n\t\t}\n#endif\n\n\t\t// Restore general-purpose registers\n\t\tfor (uint32 reg_mask = preserved_reg[0]; reg_mask != 0; ) {\n\t\t\tuint32 reg_id = detail::bit_scan_reverse(reg_mask);\n\t\t\tf.pop(Reg(static_cast<PhysicalRegID>(reg_id)));\n\t\t\treg_mask &= ~(1 << reg_id);\n\t\t}\n\n\t\t// Restore frame pointer\n\t\tf.pop(f.zbp);\n\t\t// PF AVS+: avoid AVX->SSE2 penalty\n\t\tif(f.avx_epilog_)\n\t\t\tf.vzeroupper();\n\t\tf.ret();\n\t}\n\n\tstruct OrderedLabel {\n\t\tsize_t id;\n\t\tsize_t instr_idx;\n\t\tOrderedLabel(size_t id_, size_t instr_idx_) : id(id_), instr_idx(instr_idx_) {}\n\t\tbool operator<(const OrderedLabel& rhs) const {return instr_idx < rhs.instr_idx;}\n\t};\n\n\t/// Rewrite instructions\n\t/**\n\t * - Replace symbolic register to physical register\n\t * - Generate instructions for register move and spill\n\t * - Generate function prolog and epilog\n\t */\n\tinline void RewriteInstructions(Frontend& f, const ControlFlowGraph& cfg, const VariableManager& var_manager, const uint32 (&preserved_reg)[3], const Addr& preserved_reg_stack)\n\t{\n\t\t// Prepare instruction number ordered labels for adjusting label position\n\t\tstd::vector<OrderedLabel> orderd_labels;\t// instruction number order\n\t\torderd_labels.reserve(f.labels_.size());\n\t\tfor (size_t i = 0; i < f.labels_.size(); ++i) {\n\t\t\torderd_labels.push_back(OrderedLabel(i, f.labels_[i].instr_number));\n\t\t}\n\t\tstd::sort(orderd_labels.begin(), orderd_labels.end());\n\t\tstd::vector<OrderedLabel>::iterator cur_label = orderd_labels.begin();\n\n\t\t// Move original instruction list\n\t\t// Now the instruction list in Frontend is empty!\n\t\tFrontend::InstrList org_instrs;\n\t\torg_instrs.swap(f.instrs_);\n\t\tf.instrs_.reserve(org_instrs.size());\n\n\t\tfor (ControlFlowGraph::BlockList::const_iterator it = cfg.begin(); it != cfg.end(); ++it) {\n\t\t\tconst BasicBlock *block = *it;\n\t\t\tJITASM_TRACE(\"\\n==== Block%d ====\\n\", block->depth);\n\t\t\tif (block->depth == (size_t)-1) {\n\t\t\t\t// Eliminate unreachable code block\n\t\t\t\tJITASM_TRACE(\"Unreachable block!\\n\");\n\n\t\t\t\t// Invalidate labels in this block\n\t\t\t\twhile (cur_label != orderd_labels.end() && cur_label->instr_idx < block->instr_end) {\n\t\t\t\t\tf.labels_[cur_label->id].instr_number = (size_t)-1;\n\t\t\t\t\t++cur_label;\n\t\t\t\t}\n\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Initialize interval_range\n\t\t\tdetail::ConstRange< std::vector<Lifetime::Interval> > interval_range[3];\n\t\t\tfor (size_t reg_family = 0; reg_family < 3; ++reg_family) {\n\t\t\t\tinterval_range[reg_family].first = block->lifetime[reg_family].intervals.begin();\n\t\t\t\tinterval_range[reg_family].second = block->lifetime[reg_family].intervals.end();\n\t\t\t}\n\n\t\t\tconst size_t instr_size = block->instr_end - block->instr_begin;\n\t\t\tfor (size_t instr_offset = 0; instr_offset < instr_size; ++instr_offset) {\n\t\t\t\tconst size_t org_instr_index = block->instr_begin + instr_offset;\n\n\t\t\t\t// Step each intervals and insert inter-interval instructions\n\t\t\t\tif (interval_range[0].size() > 1 && detail::next(interval_range[0].first)->instr_idx_offset == instr_offset) {\n\t\t\t\t\tJITASM_TRACE(\"---- General purpose register ----\\n\");\n\t\t\t\t\tconst Lifetime::Interval& first_interval = *interval_range[0].first;\n\t\t\t\t\tGenerateInterIntervalInstr(first_interval, *++interval_range[0].first, var_manager.GetAttributes(0), GpRegOperator(&f, &var_manager));\n\t\t\t\t}\n\t\t\t\tif (interval_range[1].size() > 1 && detail::next(interval_range[1].first)->instr_idx_offset == instr_offset) {\n\t\t\t\t\tJITASM_TRACE(\"---- MMX register ----\\n\");\n\t\t\t\t\tconst Lifetime::Interval& first_interval = *interval_range[1].first;\n\t\t\t\t\tGenerateInterIntervalInstr(first_interval, *++interval_range[1].first, var_manager.GetAttributes(1), MmxRegOperator(&f, &var_manager));\n\t\t\t\t}\n\t\t\t\tif (interval_range[2].size() > 1 && detail::next(interval_range[2].first)->instr_idx_offset == instr_offset) {\n\t\t\t\t\tJITASM_TRACE(\"---- XMM/YMM register ----\\n\");\n\t\t\t\t\tconst Lifetime::Interval& first_interval = *interval_range[2].first;\n\t\t\t\t\tGenerateInterIntervalInstr(first_interval, *++interval_range[2].first, var_manager.GetAttributes(2), XmmRegOperator(&f, &var_manager));\n\t\t\t\t}\n\n\t\t\t\tconst size_t cur_instr_index = f.instrs_.size();\n\t\t\t\tconst InstrID instr_id = org_instrs[org_instr_index].GetID();\n\t\t\t\tif (instr_id == I_COMPILER_DECLARE_REG_ARG || instr_id == I_COMPILER_DECLARE_STACK_ARG || instr_id == I_COMPILER_DECLARE_RESULT_REG) {\n\t\t\t\t\t// No actual machine code\n\t\t\t\t} else if (instr_id == I_COMPILER_PROLOG) {\n\t\t\t\t\t// Generate function prolog\n\t\t\t\t\tGenerateProlog(f, preserved_reg, preserved_reg_stack);\n\t\t\t\t} else if (instr_id == I_COMPILER_EPILOG) {\n\t\t\t\t\t// Generate function epilog\n\t\t\t\t\tGenerateEpilog(f, preserved_reg, preserved_reg_stack);\n\t\t\t\t} else {\n\t\t\t\t\t// Copy instruction\n\t\t\t\t\tf.instrs_.push_back(org_instrs[org_instr_index]);\n\t\t\t\t\tInstr &instr = f.instrs_.back();\n\n\t\t\t\t\t// Replace symbolic register to physical register\n\t\t\t\t\tfor (size_t i = 0; i < Instr::MAX_OPERAND_COUNT; ++i) {\n\t\t\t\t\t\tdetail::Opd& opd = instr.GetOpd(i);\n\t\t\t\t\t\tif (opd.IsReg()) {\n\t\t\t\t\t\t\tif (opd.reg_.IsSymbolic()) {\n\t\t\t\t\t\t\t\topd.reg_.type = static_cast<RegType>(opd.reg_.type - R_TYPE_SYMBOLIC_GP);\n\t\t\t\t\t\t\t\topd.reg_.id = interval_range[GetRegFamily(opd.reg_.GetType())].first->assignment_table[opd.reg_.id];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (opd.IsMem()) {\n\t\t\t\t\t\t\tif (opd.base_.IsSymbolic()) {\n\t\t\t\t\t\t\t\topd.base_.type = R_TYPE_GP;\n\t\t\t\t\t\t\t\topd.base_.id = interval_range[0].first->assignment_table[opd.base_.id];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (opd.index_.IsSymbolic()) {\n\t\t\t\t\t\t\t\tif (opd.index_.type == R_TYPE_SYMBOLIC_GP)\t\t\t\t\t\topd.index_.type = R_TYPE_GP;\n\t\t\t\t\t\t\t\telse if (opd.index_.type == R_TYPE_SYMBOLIC_XMM)\t\t\t\topd.index_.type = R_TYPE_XMM;\n\t\t\t\t\t\t\t\telse { JITASM_ASSERT(opd.index_.type == R_TYPE_SYMBOLIC_YMM);\topd.index_.type = R_TYPE_YMM; }\n\t\t\t\t\t\t\t\topd.index_.id = interval_range[GetRegFamily(opd.index_.GetType())].first->assignment_table[opd.index_.id];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Adjust label position\n\t\t\t\twhile (cur_label != orderd_labels.end() && cur_label->instr_idx == org_instr_index) {\n\t\t\t\t\tf.labels_[cur_label->id].instr_number += cur_instr_index - org_instr_index;\n\t\t\t\t\t++cur_label;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Generate inter-block instructions\n\t\t\tJITASM_ASSERT(!(!block->successor[0] && block->successor[1]));\n\t\t\tif (block->successor[0] && !block->successor[1]) {\n\t\t\t\t// 1 successor\n\n\t\t\t\t// Remove last instruction if it is jump\n\t\t\t\tInstr jump_instr(I_NOP, 0, 0);\n\t\t\t\tif (Frontend::IsJump(f.instrs_.back().GetID())) {\n\t\t\t\t\tjump_instr = f.instrs_.back();\n\t\t\t\t\tf.instrs_.pop_back();\n\t\t\t\t}\n\n\t\t\t\tJITASM_TRACE(\"==== Edge to Block%d\\n\", block->successor[0]->depth);\n\t\t\t\tGenerateInterBlockInstr(block, block->successor[0], f, var_manager);\n\n\t\t\t\t// Add last instruction if it is jump\n\t\t\t\tif (Frontend::IsJump(jump_instr.GetID())) {\n\t\t\t\t\tf.instrs_.push_back(jump_instr);\n\t\t\t\t}\n\t\t\t} else if (block->successor[0] && block->successor[1]) {\n\t\t\t\t// 2 successors\n\t\t\t\tJITASM_ASSERT(Frontend::IsJump(f.instrs_.back().GetID()) && f.instrs_.back().GetOpd(0).IsImm());\t// the last instruction must be jump\n\t\t\t\tconst size_t jump_instr_idx = f.instrs_.size() - 1;\n\t\t\t\tconst size_t label_successor1 = static_cast<size_t>(f.instrs_.back().GetOpd(0).GetImm());\n\n\t\t\t\t// Generate inter-block instructions between current block and successor 1 separately\n\t\t\t\tFrontend::InstrList temp_instrs;\n\t\t\t\ttemp_instrs.swap(f.instrs_);\n\t\t\t\tJITASM_TRACE(\"==== Edge to Block%d\\n\", block->successor[1]->depth);\n\t\t\t\tGenerateInterBlockInstr(block, block->successor[1], f, var_manager);\n\t\t\t\ttemp_instrs.swap(f.instrs_);\n\n\t\t\t\t// Insert inter-block instructions between current block and successor 0\n\t\t\t\tJITASM_TRACE(\"==== Edge to Block%d\\n\", block->successor[0]->depth);\n\t\t\t\tGenerateInterBlockInstr(block, block->successor[0], f, var_manager);\n\n\t\t\t\tif (!temp_instrs.empty()) {\n\t\t\t\t\t// Insert inter-block instructions between current block and successor 1 and change jump flow\n\n\t\t\t\t\t// Jump to successor0\n\t\t\t\t\tconst size_t label_successor0 = f.NewLabelID(\"\");\n\t\t\t\t\tf.AppendJmp(label_successor0);\n\n\t\t\t\t\t// Change conditional jump to successor1_edge instead of successor1\n\t\t\t\t\tconst size_t label_successor1_edge = f.NewLabelID(\"\");\n\t\t\t\t\tf.L(label_successor1_edge);\n\t\t\t\t\tFrontend::ChangeLabelID(f.instrs_[jump_instr_idx], label_successor1_edge);\n\n\t\t\t\t\t// Insert instructions\n\t\t\t\t\tf.instrs_.insert(f.instrs_.end(), temp_instrs.begin(), temp_instrs.end());\n\t\t\t\t\tf.AppendJmp(label_successor1);\n\n\t\t\t\t\t// Label of successor0 block\n\t\t\t\t\tf.L(label_successor0);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/// Compile\n\tinline void Compile(Frontend& f)\n\t{\n#ifdef JITASM64\n\t\t// Available registers : rax, rcx, rdx, rsi, rdi, r8 ~ r15, mm0 ~ mm7, xmm0/ymm0 ~ xmm15/ymm15\n\t\tconst uint32 available_reg[3] = {0xFFC7, 0xFF, 0xFFFF};\n\n#ifdef JITASM_WIN\n\t\t// Win64 preserved registers : rbx, rsi, rdi, r12 ~ r15, xmm6 ~ xmm15\n\t\tuint32 preserved_reg[3] = {(1<<RBX)|(1<<RSI)|(1<<RDI)|(1<<R12)|(1<<R13)|(1<<R14)|(1<<R15), 0, 0xFFC0};\n#else\n\t\t// x64 Linux preserved registers : rbx, r12 ~ r15, xmm6 ~ xmm15\n\t\tuint32 preserved_reg[3] = {(1<<RBX)|(1<<R12)|(1<<R13)|(1<<R14)|(1<<R15), 0, 0xFFC0};\n#endif\n#else\n\t\t// Available registers : eax, ecx, edx, esi, edi, mm0 ~ mm7, xmm0/ymm0 ~ xmm7/ymm7\n\t\tconst uint32 available_reg[3] = {(1<<EAX)|(1<<ECX)|(1<<EDX)|(1<<ESI)|(1<<EDI), 0xFF, 0xFF};\n\n\t\t// Preserved registers : ebx, esi, edi\n\t\tuint32 preserved_reg[3] = {(1<<EBX)|(1<<ESI)|(1<<EDI), 0, 0};\n#endif\n\n\t\tuint32 used_physical_reg[3];\n\t\tbool need_reg_alloc[3];\n\t\tif (!PrepareCompile(f.instrs_, used_physical_reg, need_reg_alloc)) {\n\t\t\t// No compile process\n\t\t\treturn;\n\t\t}\n\n\t\tVariableManager var_manager;\n\t\tControlFlowGraph cfg;\n\n\t\tif (need_reg_alloc[0] || need_reg_alloc[1] || need_reg_alloc[2]) {\n\t\t\t// Register allocation process\n\n\t\t\t// Build CFG including loop detection\n\t\t\tcfg.Build(f);\n\n\t\t\t// Live variable analysis\n\t\t\tLiveVariableAnalysis(f, cfg, var_manager);\n\n\t\t\t// Linear scan register allocation\n\t\t\tfor (size_t reg_family = 0; reg_family < 3; ++reg_family) {\n\t\t\t\tif (need_reg_alloc[reg_family]) {\n\t\t\t\t\tused_physical_reg[reg_family] = LinearScanRegisterAlloc(cfg, reg_family, available_reg[reg_family], var_manager.GetAttributes(reg_family));\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// No register allocation\n\t\t\t// Build dummy CFG\n\t\t\tcfg.BuildDummy(f);\n\t\t}\n\n#ifdef JITASM_DEBUG_DUMP\n\t\tcfg.DumpDot();\n#endif\n\n\t\t// Identify saving registers\n\t\tpreserved_reg[0] &= used_physical_reg[0];\n\t\tpreserved_reg[1] &= used_physical_reg[1];\n\t\tpreserved_reg[2] &= used_physical_reg[2];\n\n\t\t// Reserve stack for saving xmm register\n\t\tAddr preserved_reg_stack(RegID::Invalid(), 0);\n\t\tif (preserved_reg[2] != 0) {\n\t\t\t// For saving xmm registers\n\t\t\tpreserved_reg_stack = f.stack_manager_.Alloc(detail::Count1Bits(preserved_reg[2]) * 16, 16);\n\t\t}\n\n\t\t// Allocate stack for spill variable\n\t\tvar_manager.AllocSpillSlots(f.stack_manager_);\n\n\t\t// ebx(rbx) does not include in used_physical_reg\n\t\t// because ebx(rbx) is going to be modified in prolog.\n\t\tif (f.stack_manager_.GetSize() > 0) {\n\t\t\tpreserved_reg[0] |= (1 << EBX);\n\t\t}\n\n\t\tRewriteInstructions(f, cfg, var_manager, preserved_reg, preserved_reg_stack);\n\t}\n\n}\t// namespace compiler\n\nnamespace detail\n{\n\tstruct CondExpr {\n\t\tvirtual void operator()(Frontend& f, size_t beg, size_t end) const = 0;\n\t\tvirtual ~CondExpr() {}\n\t};\n\n\t// &&\n\tstruct CondExpr_ExprAnd : CondExpr {\n\t\tconst CondExpr&\tlhs_;\n\t\tconst CondExpr&\trhs_;\n\t\tCondExpr_ExprAnd(const CondExpr& lhs, const CondExpr& rhs) : lhs_(lhs), rhs_(rhs) {}\n\t\tvoid operator()(Frontend& f, size_t beg, size_t end) const {\n\t\t\tsize_t label = f.NewLabelID(\"\");\n\t\t\tlhs_(f, label, end);\n\t\t\tf.L(label);\n\t\t\trhs_(f, beg, end);\n\t\t}\n\t\tCondExpr_ExprAnd& operator=(const CondExpr_ExprAnd&);\n\t};\n\n\t// ||\n\tstruct CondExpr_ExprOr : CondExpr {\n\t\tconst CondExpr&\tlhs_;\n\t\tconst CondExpr&\trhs_;\n\t\tCondExpr_ExprOr(const CondExpr& lhs, const CondExpr& rhs) : lhs_(lhs), rhs_(rhs) {}\n\t\tvoid operator()(Frontend& f, size_t beg, size_t end) const {\n\t\t\tsize_t label = f.NewLabelID(\"\");\n\t\t\tlhs_(f, beg, label);\n\t\t\tf.L(label);\n\t\t\trhs_(f, beg, end);\n\t\t}\n\t\tCondExpr_ExprOr& operator=(const CondExpr_ExprOr&);\n\t};\n\n\t// cmp\n\ttemplate<class L, class R, JumpCondition Jcc>\n\tstruct CondExpr_Cmp : CondExpr {\n\t\tL\tlhs_;\n\t\tR\trhs_;\n\t\tCondExpr_Cmp(const L& lhs, const R& rhs) : lhs_(lhs), rhs_(rhs) {}\n\t\tvoid operator()(Frontend& f, size_t beg, size_t end) const {\n\t\t\tf.cmp(lhs_, rhs_);\n\t\t\tf.AppendJcc(Jcc, beg);\n\t\t\tf.AppendJmp(end);\n\t\t}\n\t};\n\n\t// or\n\ttemplate<class L, class R, JumpCondition Jcc>\n\tstruct CondExpr_Or : CondExpr {\n\t\tL\tlhs_;\n\t\tR\trhs_;\n\t\tCondExpr_Or(const L& lhs, const R& rhs) : lhs_(lhs), rhs_(rhs) {}\n\t\tvoid operator()(Frontend& f, size_t beg, size_t end) const {\n\t\t\tf.or_(lhs_, rhs_);\n\t\t\tf.AppendJcc(Jcc, beg);\n\t\t\tf.AppendJmp(end);\n\t\t}\n\t};\n}\n\n// &&\ninline detail::CondExpr_ExprAnd\toperator&&(const detail::CondExpr& lhs, const detail::CondExpr& rhs)\t{return detail::CondExpr_ExprAnd(lhs, rhs);}\n// ||\ninline detail::CondExpr_ExprOr\toperator||(const detail::CondExpr& lhs, const detail::CondExpr& rhs)\t{return detail::CondExpr_ExprOr(lhs, rhs);}\n\n// !\ninline detail::CondExpr_Or<Reg8, Reg8, JCC_E>\t\toperator!(const Reg8& lhs)\t\t{return detail::CondExpr_Or<Reg8, Reg8, JCC_E>(lhs, lhs);}\ninline detail::CondExpr_Or<Reg16, Reg16, JCC_E>\t\toperator!(const Reg16& lhs)\t\t{return detail::CondExpr_Or<Reg16, Reg16, JCC_E>(lhs, lhs);}\ninline detail::CondExpr_Or<Reg32, Reg32, JCC_E>\t\toperator!(const Reg32& lhs)\t\t{return detail::CondExpr_Or<Reg32, Reg32, JCC_E>(lhs, lhs);}\n#ifdef JITASM64\ninline detail::CondExpr_Or<Reg64, Reg64, JCC_E>\t\toperator!(const Reg64& lhs)\t\t{return detail::CondExpr_Or<Reg64, Reg64, JCC_E>(lhs, lhs);}\n#endif\ninline detail::CondExpr_Cmp<Mem8, Imm8, JCC_E>\t\toperator!(const Mem8& lhs)\t\t{return detail::CondExpr_Cmp<Mem8, Imm8, JCC_E>(lhs, 0);}\ninline detail::CondExpr_Cmp<Mem16, Imm16, JCC_E>\toperator!(const Mem16& lhs)\t\t{return detail::CondExpr_Cmp<Mem16, Imm16, JCC_E>(lhs, 0);}\ninline detail::CondExpr_Cmp<Mem32, Imm32, JCC_E>\toperator!(const Mem32& lhs)\t\t{return detail::CondExpr_Cmp<Mem32, Imm32, JCC_E>(lhs, 0);}\n#ifdef JITASM64\ninline detail::CondExpr_Cmp<Mem64, Imm32, JCC_E>\toperator!(const Mem64& lhs)\t\t{return detail::CondExpr_Cmp<Mem64, Imm32, JCC_E>(lhs, 0);}\n#endif\n\n// <\ntemplate<class R> detail::CondExpr_Cmp<Reg8, R, JCC_B>\t\toperator<(const Reg8& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Reg8, R, JCC_B>(lhs, rhs);}\ntemplate<class R> detail::CondExpr_Cmp<Reg16, R, JCC_B>\t\toperator<(const Reg16& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Reg16, R, JCC_B>(lhs, rhs);}\ntemplate<class R> detail::CondExpr_Cmp<Reg32, R, JCC_B>\t\toperator<(const Reg32& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Reg32, R, JCC_B>(lhs, rhs);}\n#ifdef JITASM64\ntemplate<class R> detail::CondExpr_Cmp<Reg64, R, JCC_B>\t\toperator<(const Reg64& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Reg64, R, JCC_B>(lhs, rhs);}\n#endif\ntemplate<class R> detail::CondExpr_Cmp<Mem8, R, JCC_B>\t\toperator<(const Mem8& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Mem8, R, JCC_B>(lhs, rhs);}\ntemplate<class R> detail::CondExpr_Cmp<Mem16, R, JCC_B>\t\toperator<(const Mem16& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Mem16, R, JCC_B>(lhs, rhs);}\ntemplate<class R> detail::CondExpr_Cmp<Mem32, R, JCC_B>\t\toperator<(const Mem32& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Mem32, R, JCC_B>(lhs, rhs);}\n#ifdef JITASM64\ntemplate<class R> detail::CondExpr_Cmp<Mem64, R, JCC_B>\t\toperator<(const Mem64& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Mem64, R, JCC_B>(lhs, rhs);}\n#endif\n\n// >\ntemplate<class R> detail::CondExpr_Cmp<Reg8, R, JCC_A>\t\toperator>(const Reg8& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Reg8, R, JCC_A>(lhs, rhs);}\ntemplate<class R> detail::CondExpr_Cmp<Reg16, R, JCC_A>\t\toperator>(const Reg16& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Reg16, R, JCC_A>(lhs, rhs);}\ntemplate<class R> detail::CondExpr_Cmp<Reg32, R, JCC_A>\t\toperator>(const Reg32& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Reg32, R, JCC_A>(lhs, rhs);}\n#ifdef JITASM64\ntemplate<class R> detail::CondExpr_Cmp<Reg64, R, JCC_A>\t\toperator>(const Reg64& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Reg64, R, JCC_A>(lhs, rhs);}\n#endif\ntemplate<class R> detail::CondExpr_Cmp<Mem8, R, JCC_A>\t\toperator>(const Mem8& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Mem8, R, JCC_A>(lhs, rhs);}\ntemplate<class R> detail::CondExpr_Cmp<Mem16, R, JCC_A>\t\toperator>(const Mem16& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Mem16, R, JCC_A>(lhs, rhs);}\ntemplate<class R> detail::CondExpr_Cmp<Mem32, R, JCC_A>\t\toperator>(const Mem32& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Mem32, R, JCC_A>(lhs, rhs);}\n#ifdef JITASM64\ntemplate<class R> detail::CondExpr_Cmp<Mem64, R, JCC_A>\t\toperator>(const Mem64& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Mem64, R, JCC_A>(lhs, rhs);}\n#endif\n\n// <=\ntemplate<class R> detail::CondExpr_Cmp<Reg8, R, JCC_BE>\t\toperator<=(const Reg8& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Reg8, R, JCC_BE>(lhs, rhs);}\ntemplate<class R> detail::CondExpr_Cmp<Reg16, R, JCC_BE>\toperator<=(const Reg16& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Reg16, R, JCC_BE>(lhs, rhs);}\ntemplate<class R> detail::CondExpr_Cmp<Reg32, R, JCC_BE>\toperator<=(const Reg32& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Reg32, R, JCC_BE>(lhs, rhs);}\n#ifdef JITASM64\ntemplate<class R> detail::CondExpr_Cmp<Reg64, R, JCC_BE>\toperator<=(const Reg64& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Reg64, R, JCC_BE>(lhs, rhs);}\n#endif\ntemplate<class R> detail::CondExpr_Cmp<Mem8, R, JCC_BE>\t\toperator<=(const Mem8& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Mem8, R, JCC_BE>(lhs, rhs);}\ntemplate<class R> detail::CondExpr_Cmp<Mem16, R, JCC_BE>\toperator<=(const Mem16& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Mem16, R, JCC_BE>(lhs, rhs);}\ntemplate<class R> detail::CondExpr_Cmp<Mem32, R, JCC_BE>\toperator<=(const Mem32& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Mem32, R, JCC_BE>(lhs, rhs);}\n#ifdef JITASM64\ntemplate<class R> detail::CondExpr_Cmp<Mem64, R, JCC_BE>\toperator<=(const Mem64& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Mem64, R, JCC_BE>(lhs, rhs);}\n#endif\n\n// >=\ntemplate<class R> detail::CondExpr_Cmp<Reg8, R, JCC_AE>\t\toperator>=(const Reg8& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Reg8, R, JCC_AE>(lhs, rhs);}\ntemplate<class R> detail::CondExpr_Cmp<Reg16, R, JCC_AE>\toperator>=(const Reg16& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Reg16, R, JCC_AE>(lhs, rhs);}\ntemplate<class R> detail::CondExpr_Cmp<Reg32, R, JCC_AE>\toperator>=(const Reg32& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Reg32, R, JCC_AE>(lhs, rhs);}\n#ifdef JITASM64\ntemplate<class R> detail::CondExpr_Cmp<Reg64, R, JCC_AE>\toperator>=(const Reg64& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Reg64, R, JCC_AE>(lhs, rhs);}\n#endif\ntemplate<class R> detail::CondExpr_Cmp<Mem8, R, JCC_AE>\t\toperator>=(const Mem8& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Mem8, R, JCC_AE>(lhs, rhs);}\ntemplate<class R> detail::CondExpr_Cmp<Mem16, R, JCC_AE>\toperator>=(const Mem16& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Mem16, R, JCC_AE>(lhs, rhs);}\ntemplate<class R> detail::CondExpr_Cmp<Mem32, R, JCC_AE>\toperator>=(const Mem32& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Mem32, R, JCC_AE>(lhs, rhs);}\n#ifdef JITASM64\ntemplate<class R> detail::CondExpr_Cmp<Mem64, R, JCC_AE>\toperator>=(const Mem64& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Mem64, R, JCC_AE>(lhs, rhs);}\n#endif\n\n// ==\ntemplate<class R> detail::CondExpr_Cmp<Reg8, R, JCC_E>\t\toperator==(const Reg8& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Reg8, R, JCC_E>(lhs, rhs);}\ntemplate<class R> detail::CondExpr_Cmp<Reg16, R, JCC_E>\t\toperator==(const Reg16& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Reg16, R, JCC_E>(lhs, rhs);}\ntemplate<class R> detail::CondExpr_Cmp<Reg32, R, JCC_E>\t\toperator==(const Reg32& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Reg32, R, JCC_E>(lhs, rhs);}\n#ifdef JITASM64\ntemplate<class R> detail::CondExpr_Cmp<Reg64, R, JCC_E>\t\toperator==(const Reg64& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Reg64, R, JCC_E>(lhs, rhs);}\n#endif\ntemplate<class R> detail::CondExpr_Cmp<Mem8, R, JCC_E>\t\toperator==(const Mem8& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Mem8, R, JCC_E>(lhs, rhs);}\ntemplate<class R> detail::CondExpr_Cmp<Mem16, R, JCC_E>\t\toperator==(const Mem16& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Mem16, R, JCC_E>(lhs, rhs);}\ntemplate<class R> detail::CondExpr_Cmp<Mem32, R, JCC_E>\t\toperator==(const Mem32& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Mem32, R, JCC_E>(lhs, rhs);}\n#ifdef JITASM64\ntemplate<class R> detail::CondExpr_Cmp<Mem64, R, JCC_E>\t\toperator==(const Mem64& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Mem64, R, JCC_E>(lhs, rhs);}\n#endif\n\n// !=\ntemplate<class R> detail::CondExpr_Cmp<Reg8, R, JCC_NE>\t\toperator!=(const Reg8& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Reg8, R, JCC_NE>(lhs, rhs);}\ntemplate<class R> detail::CondExpr_Cmp<Reg16, R, JCC_NE>\toperator!=(const Reg16& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Reg16, R, JCC_NE>(lhs, rhs);}\ntemplate<class R> detail::CondExpr_Cmp<Reg32, R, JCC_NE>\toperator!=(const Reg32& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Reg32, R, JCC_NE>(lhs, rhs);}\n#ifdef JITASM64\ntemplate<class R> detail::CondExpr_Cmp<Reg64, R, JCC_NE>\toperator!=(const Reg64& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Reg64, R, JCC_NE>(lhs, rhs);}\n#endif\ntemplate<class R> detail::CondExpr_Cmp<Mem8, R, JCC_NE>\t\toperator!=(const Mem8& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Mem8, R, JCC_NE>(lhs, rhs);}\ntemplate<class R> detail::CondExpr_Cmp<Mem16, R, JCC_NE>\toperator!=(const Mem16& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Mem16, R, JCC_NE>(lhs, rhs);}\ntemplate<class R> detail::CondExpr_Cmp<Mem32, R, JCC_NE>\toperator!=(const Mem32& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Mem32, R, JCC_NE>(lhs, rhs);}\n#ifdef JITASM64\ntemplate<class R> detail::CondExpr_Cmp<Mem64, R, JCC_NE>\toperator!=(const Mem64& lhs, const R& rhs)\t{return detail::CondExpr_Cmp<Mem64, R, JCC_NE>(lhs, rhs);}\n#endif\n\nnamespace detail {\n\t// Flags for ArgumentTraits\n\tenum {\n\t\tARG_IN_REG\t\t= (1<<0),\t///< Argument is stored in general purpose register.\n\t\tARG_IN_STACK\t= (1<<1),\t///< Argument is stored on stack.\n\t\tARG_IN_MMX\t\t= (1<<2),\t///< Argument is stored in mmx register.\n\t\tARG_IN_XMM_SP\t= (1<<3),\t///< Argument is stored in xmm register as single precision.\n\t\tARG_IN_XMM_DP\t= (1<<4),\t///< Argument is stored in xmm register as double precision.\n\t\tARG_IN_XMM_INT\t= (1<<5),\t///< Argument is stored in xmm register as integer.\n\t\tARG_TYPE_VALUE\t= (1<<6),\t///< Argument is value which is passed.\n\t\tARG_TYPE_PTR\t= (1<<7)\t///< Argument is pointer which is passed to.\n\t};\n\n\t/// cdecl argument type traits\n\ttemplate<int N, class T, int Size = sizeof(T)>\n\tstruct ArgTraits_cdecl {\n\t\tenum {\n\t\t\tstack_size = (Size + 4 - 1) / 4 * 4,\n\t\t\tflag = ARG_IN_STACK | ARG_TYPE_VALUE,\n\t\t\treg_id = INVALID\n\t\t};\n\t};\n\n#if JITASM_MMINTRIN\n\t// specialization for __m64\n\ttemplate<int N> struct ArgTraits_cdecl<N, __m64, 8> {enum {stack_size = 0, flag = ARG_IN_MMX | ARG_TYPE_VALUE, reg_id = MM0};};\n#endif\n\n#if JITASM_XMMINTRIN\n\t// specialization for __m128\n\ttemplate<int N> struct ArgTraits_cdecl<N, __m128, 16> {enum {stack_size = 0, flag = ARG_IN_XMM_SP | ARG_TYPE_VALUE, reg_id = XMM0};};\n#endif\n\n#if JITASM_EMMINTRIN\n\t// specialization for __m128d\n\ttemplate<int N> struct ArgTraits_cdecl<N, __m128d, 16> {enum {stack_size = 0, flag = ARG_IN_XMM_DP | ARG_TYPE_VALUE, reg_id = XMM0};};\n\n\t// specialization for __m128i\n\ttemplate<int N> struct ArgTraits_cdecl<N, __m128i, 16> {enum {stack_size = 0, flag = ARG_IN_XMM_INT | ARG_TYPE_VALUE, reg_id = XMM0};};\n#endif\n\n\n\t/// Microsoft x64 fastcall argument type traits\n\ttemplate<int N, class T, int Size = sizeof(T)>\n\tstruct ArgTraits_win64 {\n\t\tenum {\n\t\t\tstack_size = 8,\n\t\t\tflag = ARG_IN_STACK | (Size == 1 || Size == 2 || Size == 4 || Size == 8 ? ARG_TYPE_VALUE : ARG_TYPE_PTR),\n\t\t\treg_id = INVALID\n\t\t};\n\t};\n\n\t/**\n\t * Base class for argument which is stored in general purpose register.\n\t */\n\ttemplate<int RegID, int Flag> struct ArgTraits_win64_reg {\n\t\tenum {\n\t\t\tstack_size = 8,\n\t\t\tflag = Flag,\n\t\t\treg_id = RegID\n\t\t};\n\t};\n\n\t// specialization for argument pointer stored in register\n\ttemplate<class T, int Size> struct ArgTraits_win64<0, T, Size> : ArgTraits_win64_reg<RCX, ARG_IN_REG | ARG_TYPE_PTR> {};\n\ttemplate<class T, int Size> struct ArgTraits_win64<1, T, Size> : ArgTraits_win64_reg<RDX, ARG_IN_REG | ARG_TYPE_PTR> {};\n\ttemplate<class T, int Size> struct ArgTraits_win64<2, T, Size> : ArgTraits_win64_reg<R8, ARG_IN_REG | ARG_TYPE_PTR> {};\n\ttemplate<class T, int Size> struct ArgTraits_win64<3, T, Size> : ArgTraits_win64_reg<R9, ARG_IN_REG | ARG_TYPE_PTR> {};\n\n\t// specialization for 1 byte type\n\ttemplate<class T> struct ArgTraits_win64<0, T, 1> : ArgTraits_win64_reg<RCX, ARG_IN_REG | ARG_TYPE_VALUE> {};\n\ttemplate<class T> struct ArgTraits_win64<1, T, 1> : ArgTraits_win64_reg<RDX, ARG_IN_REG | ARG_TYPE_VALUE> {};\n\ttemplate<class T> struct ArgTraits_win64<2, T, 1> : ArgTraits_win64_reg<R8, ARG_IN_REG | ARG_TYPE_VALUE> {};\n\ttemplate<class T> struct ArgTraits_win64<3, T, 1> : ArgTraits_win64_reg<R9, ARG_IN_REG | ARG_TYPE_VALUE> {};\n\n\t// specialization for 2 bytes type\n\ttemplate<class T> struct ArgTraits_win64<0, T, 2> : ArgTraits_win64_reg<RCX, ARG_IN_REG | ARG_TYPE_VALUE> {};\n\ttemplate<class T> struct ArgTraits_win64<1, T, 2> : ArgTraits_win64_reg<RDX, ARG_IN_REG | ARG_TYPE_VALUE> {};\n\ttemplate<class T> struct ArgTraits_win64<2, T, 2> : ArgTraits_win64_reg<R8, ARG_IN_REG | ARG_TYPE_VALUE> {};\n\ttemplate<class T> struct ArgTraits_win64<3, T, 2> : ArgTraits_win64_reg<R9, ARG_IN_REG | ARG_TYPE_VALUE> {};\n\n\t// specialization for 4 bytes type\n\ttemplate<class T> struct ArgTraits_win64<0, T, 4> : ArgTraits_win64_reg<RCX, ARG_IN_REG | ARG_TYPE_VALUE> {};\n\ttemplate<class T> struct ArgTraits_win64<1, T, 4> : ArgTraits_win64_reg<RDX, ARG_IN_REG | ARG_TYPE_VALUE> {};\n\ttemplate<class T> struct ArgTraits_win64<2, T, 4> : ArgTraits_win64_reg<R8, ARG_IN_REG | ARG_TYPE_VALUE> {};\n\ttemplate<class T> struct ArgTraits_win64<3, T, 4> : ArgTraits_win64_reg<R9, ARG_IN_REG | ARG_TYPE_VALUE> {};\n\n\t// specialization for 8 bytes type\n\ttemplate<class T> struct ArgTraits_win64<0, T, 8> : ArgTraits_win64_reg<RCX, ARG_IN_REG | ARG_TYPE_VALUE> {};\n\ttemplate<class T> struct ArgTraits_win64<1, T, 8> : ArgTraits_win64_reg<RDX, ARG_IN_REG | ARG_TYPE_VALUE> {};\n\ttemplate<class T> struct ArgTraits_win64<2, T, 8> : ArgTraits_win64_reg<R8, ARG_IN_REG | ARG_TYPE_VALUE> {};\n\ttemplate<class T> struct ArgTraits_win64<3, T, 8> : ArgTraits_win64_reg<R9, ARG_IN_REG | ARG_TYPE_VALUE> {};\n\n#if JITASM_MMINTRIN\n\t// specialization for __m64\n\ttemplate<> struct ArgTraits_win64<0, __m64, 8> : ArgTraits_win64_reg<RCX, ARG_IN_REG | ARG_TYPE_VALUE> {};\n\ttemplate<> struct ArgTraits_win64<1, __m64, 8> : ArgTraits_win64_reg<RDX, ARG_IN_REG | ARG_TYPE_VALUE> {};\n\ttemplate<> struct ArgTraits_win64<2, __m64, 8> : ArgTraits_win64_reg<R8, ARG_IN_REG | ARG_TYPE_VALUE> {};\n\ttemplate<> struct ArgTraits_win64<3, __m64, 8> : ArgTraits_win64_reg<R9, ARG_IN_REG | ARG_TYPE_VALUE> {};\n#endif\n\n\t// specialization for float\n\ttemplate<> struct ArgTraits_win64<0, float, 4> : ArgTraits_win64_reg<XMM0, ARG_IN_XMM_SP | ARG_TYPE_VALUE> {};\n\ttemplate<> struct ArgTraits_win64<1, float, 4> : ArgTraits_win64_reg<XMM1, ARG_IN_XMM_SP | ARG_TYPE_VALUE> {};\n\ttemplate<> struct ArgTraits_win64<2, float, 4> : ArgTraits_win64_reg<XMM2, ARG_IN_XMM_SP | ARG_TYPE_VALUE> {};\n\ttemplate<> struct ArgTraits_win64<3, float, 4> : ArgTraits_win64_reg<XMM3, ARG_IN_XMM_SP | ARG_TYPE_VALUE> {};\n\n\t// specialization for double\n\ttemplate<> struct ArgTraits_win64<0, double, 8> : ArgTraits_win64_reg<XMM0, ARG_IN_XMM_DP | ARG_TYPE_VALUE> {};\n\ttemplate<> struct ArgTraits_win64<1, double, 8> : ArgTraits_win64_reg<XMM1, ARG_IN_XMM_DP | ARG_TYPE_VALUE> {};\n\ttemplate<> struct ArgTraits_win64<2, double, 8> : ArgTraits_win64_reg<XMM2, ARG_IN_XMM_DP | ARG_TYPE_VALUE> {};\n\ttemplate<> struct ArgTraits_win64<3, double, 8> : ArgTraits_win64_reg<XMM3, ARG_IN_XMM_DP | ARG_TYPE_VALUE> {};\n\n\n\t/// System V ABI AMD64 argument type traits\n\ttemplate<int N, class T, int Size = sizeof(T)>\n\tstruct ArgTraits_linux64 {\n\t\tenum {\n\t\t\tstack_size = (Size + 8 - 1) / 8 * 8,\n\t\t\tflag = ARG_IN_STACK | ARG_TYPE_VALUE,\n\t\t\treg_id = INVALID\n\t\t};\n\t};\n\n\t// INTEGER class\n\tstruct ArgTraits_linux64_integer {\n\t\tenum {\n\t\t\tstack_size = 0,\n\t\t\tflag = ARG_IN_REG | ARG_TYPE_VALUE,\n\t\t\treg_id = RDI\n\t\t};\n\t};\n\n\ttemplate<int N> struct ArgTraits_linux64<N, bool,\t\t\t\tsizeof(bool)\t\t\t  > : ArgTraits_linux64_integer {};\n\ttemplate<int N> struct ArgTraits_linux64<N, char,\t\t\t\tsizeof(char)\t\t\t  > : ArgTraits_linux64_integer {};\n\ttemplate<int N> struct ArgTraits_linux64<N, unsigned char,\t\tsizeof(unsigned char)\t  > : ArgTraits_linux64_integer {};\n\ttemplate<int N> struct ArgTraits_linux64<N, short,\t\t\t\tsizeof(short)\t\t\t  > : ArgTraits_linux64_integer {};\n\ttemplate<int N> struct ArgTraits_linux64<N, unsigned short,\t\tsizeof(unsigned short)\t  > : ArgTraits_linux64_integer {};\n\ttemplate<int N> struct ArgTraits_linux64<N, int,\t\t\t\tsizeof(int)\t\t\t\t  > : ArgTraits_linux64_integer {};\n\ttemplate<int N> struct ArgTraits_linux64<N, unsigned int,\t\tsizeof(unsigned int)\t  > : ArgTraits_linux64_integer {};\n\ttemplate<int N> struct ArgTraits_linux64<N, long,\t\t\t\tsizeof(long)\t\t\t  > : ArgTraits_linux64_integer {};\n\ttemplate<int N> struct ArgTraits_linux64<N, unsigned long,\t\tsizeof(unsigned long)\t  > : ArgTraits_linux64_integer {};\n\ttemplate<int N> struct ArgTraits_linux64<N, long long,\t\t\tsizeof(long long)\t\t  > : ArgTraits_linux64_integer {};\n\ttemplate<int N> struct ArgTraits_linux64<N, unsigned long long,\tsizeof(unsigned long long)> : ArgTraits_linux64_integer {};\n\ttemplate<int N, class T> struct ArgTraits_linux64<N, T *,\t\t8\t\t\t\t\t\t  > : ArgTraits_linux64_integer {};\n\n\t// SSE class\n\ttemplate<int Flag> struct ArgTraits_linux64_sse {\n\t\tenum {\n\t\t\tstack_size = 0,\n\t\t\tflag = Flag,\n\t\t\treg_id = XMM0\n\t\t};\n\t};\n\n\ttemplate<int N> struct ArgTraits_linux64<N, float,\t sizeof(float)>   : ArgTraits_linux64_sse<ARG_IN_XMM_SP | ARG_TYPE_VALUE> {};\n\ttemplate<int N> struct ArgTraits_linux64<N, double,  sizeof(double)>  : ArgTraits_linux64_sse<ARG_IN_XMM_DP | ARG_TYPE_VALUE> {};\n#if JITASM_MMINTRIN\n\ttemplate<int N> struct ArgTraits_linux64<N, __m64,\t sizeof(__m64)>   : ArgTraits_linux64_sse<ARG_IN_XMM_INT | ARG_TYPE_VALUE> {};\n#endif\n#if JITASM_XMMINTRIN\n\ttemplate<int N> struct ArgTraits_linux64<N, __m128,\t sizeof(__m128)>  : ArgTraits_linux64_sse<ARG_IN_XMM_SP | ARG_TYPE_VALUE> {};\n#endif\n#if JITASM_EMMINTRIN\n\ttemplate<int N> struct ArgTraits_linux64<N, __m128d, sizeof(__m128d)> : ArgTraits_linux64_sse<ARG_IN_XMM_DP | ARG_TYPE_VALUE> {};\n\ttemplate<int N> struct ArgTraits_linux64<N, __m128i, sizeof(__m128i)> : ArgTraits_linux64_sse<ARG_IN_XMM_INT | ARG_TYPE_VALUE> {};\n#endif\n\n\n\t/// Special argument type\n\tstruct ArgNone {};\n\n\t/// Argument information\n\tstruct ArgInfo\n\t{\n\t\tAddr addr;\n\t\tPhysicalRegID reg_id;\n\t\tuint32 flag;\n\t\tuint32 index_gp;\n\t\tuint32 index_mmx;\n\t\tuint32 index_xmm;\n\n\t\tArgInfo(const Addr& addr_, PhysicalRegID reg_id_, uint32 flg, uint32 idx_gp = 0, uint32 idx_mmx = 0, uint32 idx_xmm_ = 0) : addr(addr_), reg_id(reg_id_), flag(flg), index_gp(idx_gp), index_mmx(idx_mmx), index_xmm(idx_xmm_) {}\n\n\t\ttemplate<class CurArgTraits, class NextArgTraits> ArgInfo Next() const {\n\t\t\tArgInfo next_arg_info(addr + CurArgTraits::stack_size, static_cast<PhysicalRegID>(NextArgTraits::reg_id), NextArgTraits::flag, index_gp, index_mmx, index_xmm);\n\t\t\tif (CurArgTraits::flag & ARG_IN_REG) next_arg_info.index_gp++;\n\t\t\tif (CurArgTraits::flag & ARG_IN_MMX) next_arg_info.index_mmx++;\n\t\t\tif (CurArgTraits::flag & (ARG_IN_XMM_SP | ARG_IN_XMM_DP | ARG_IN_XMM_INT)) next_arg_info.index_xmm++;\n\n#ifdef JITASM64\n#ifdef JITASM_WIN\n\t\t\t// for Win64\n#else\n\t\t\t// for x64 Linux\n\t\t\tif (NextArgTraits::flag & ARG_IN_REG) {\n\t\t\t\tconst PhysicalRegID gp_regs[] = {RDI, RSI, RDX, RCX, R8, R9};\n\t\t\t\tnext_arg_info.reg_id = next_arg_info.index_gp < 6 ? gp_regs[next_arg_info.index_gp] : INVALID;\n\t\t\t}\n\t\t\tif (CurArgTraits::flag & ARG_IN_REG) {\n\t\t\t\tif (reg_id == INVALID) {\n\t\t\t\t\t// This register argument is passed on stack\n\t\t\t\t\tnext_arg_info.addr = next_arg_info.addr + 8;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// __m128/__m128d/__m128i\n\t\t\tif (NextArgTraits::flag & (ARG_IN_XMM_SP | ARG_IN_XMM_DP | ARG_IN_XMM_INT)) {\n\t\t\t\tif (next_arg_info.index_xmm < 8) {\n\t\t\t\t\tnext_arg_info.reg_id = static_cast<PhysicalRegID>(next_arg_info.reg_id + next_arg_info.index_xmm);\n\t\t\t\t} else {\n\t\t\t\t\tnext_arg_info.reg_id = INVALID;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (CurArgTraits::flag & (ARG_IN_XMM_SP | ARG_IN_XMM_DP | ARG_IN_XMM_INT)) {\n\t\t\t\tif (reg_id == INVALID) {\n\t\t\t\t\t// This __m128/__m128d/__m128i argument is passed on stack\n\t\t\t\t\tnext_arg_info.addr = next_arg_info.addr + 16;\n\t\t\t\t}\n\t\t\t}\n#endif\n#else\n\t\t\t// for x86 Win/Linux\n\n\t\t\t// __m64\n\t\t\tif (NextArgTraits::flag & ARG_IN_MMX) {\n\t\t\t\tif (next_arg_info.index_mmx < 3) {\n\t\t\t\t\tnext_arg_info.reg_id = static_cast<PhysicalRegID>(next_arg_info.reg_id + next_arg_info.index_mmx);\n\t\t\t\t} else {\n\t\t\t\t\tnext_arg_info.reg_id = INVALID;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (CurArgTraits::flag & ARG_IN_MMX) {\n\t\t\t\tif (reg_id == INVALID) {\n\t\t\t\t\t// This __m64 argument is passed on stack\n\t\t\t\t\tnext_arg_info.addr = next_arg_info.addr + 8;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// __m128/__m128d/__m128i\n\t\t\tif (NextArgTraits::flag & (ARG_IN_XMM_SP | ARG_IN_XMM_DP | ARG_IN_XMM_INT)) {\n\t\t\t\tif (next_arg_info.index_xmm < 3) {\n\t\t\t\t\tnext_arg_info.reg_id = static_cast<PhysicalRegID>(next_arg_info.reg_id + next_arg_info.index_xmm);\n\t\t\t\t} else {\n\t\t\t\t\tnext_arg_info.reg_id = INVALID;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (CurArgTraits::flag & (ARG_IN_XMM_SP | ARG_IN_XMM_DP | ARG_IN_XMM_INT)) {\n\t\t\t\tif (reg_id == INVALID) {\n\t\t\t\t\t// This __m128/__m128d/__m128i argument is passed on stack\n\t\t\t\t\tnext_arg_info.addr = next_arg_info.addr + 16;\n\t\t\t\t}\n\t\t\t}\n#endif\n\n\t\t\treturn next_arg_info;\n\t\t}\n\t};\n\n\t/// Result type traits\n\ttemplate<class T>\n\tstruct ResultTraits {\n\t\tenum { size = sizeof(T) };\n\t\ttypedef OpdT<sizeof(T) * 8>\tOpdR;\n\t\ttypedef AddressingPtr<OpdR>\tResultPtr;\n\t};\n\n\t// specialization for void\n\ttemplate<>\n\tstruct ResultTraits<void> {\n\t\tenum { size = 0 };\n\t\tstruct OpdR {};\n\t\tstruct ResultPtr {};\n\t};\n\n\t/// Result store destination\n\tstruct ResultDest {\n\t\tReg ptr;\n\t\tResultDest(Frontend& f, const ArgInfo& dest)\n\t\t{\n\t\t\tif (dest.reg_id != INVALID) {\n\t\t\t\t// result pointer on register\n\t\t\t\tf.DeclareRegArg(ptr, Reg(dest.reg_id), !dest.addr.reg_.IsInvalid() ? f.ptr[dest.addr] : Opd());\n\t\t\t} else if (!dest.addr.reg_.IsInvalid()) {\n\t\t\t\t// result pointer on stack\n\t\t\t\tf.DeclareStackArg(ptr, f.ptr[dest.addr]);\n\t\t\t}\n\t\t}\n\t};\n\n\t/// Function result\n\ttemplate<class T, int Size = ResultTraits<T>::size>\n\tstruct ResultT {\n\t\tenum { ArgR = 1 /* First (hidden) argument is pointer for copying result. */};\n\t\ttypedef typename ResultTraits<T>::OpdR OpdR;\n\t\tOpdR val_;\n\t\tResultT() {}\n\t\tResultT(const MemT<OpdR>& val) : val_(val) {}\n\t\tvoid StoreResult(Frontend& f, const ResultDest& dst)\n\t\t{\n\t\t\tif (val_.IsMem()) {\n\t\t\t\tf.lea(f.zsi, static_cast<MemT<OpdR>&>(val_));\n\t\t\t\tf.mov(f.zcx, Size);\n\t\t\t\tf.rep_movsb(dst.ptr, f.zsi, f.zcx);\n\t\t\t\tf.DeclareResultReg(dst.ptr);\n\t\t\t}\n\t\t}\n\t};\n\n\t// specialization for void\n\ttemplate<>\n\tstruct ResultT<void, 0> {\n\t\tenum { ArgR = 0 };\n\t\tResultT();\n\t};\n\n\t// specialization for 1byte type\n\ttemplate<class T>\n\tstruct ResultT<T, 1> {\n\t\tenum { ArgR = 0 };\n\t\tOpd8 val_;\n\t\tResultT() {}\n\t\tResultT(const Opd8& val) : val_(val) {}\n\t\tResultT(uint8 imm) : val_(Imm8(imm)) {}\n\t\tvoid StoreResult(Frontend& f, const ResultDest& /*dst*/)\n\t\t{\n\t\t\tif (val_.IsGpReg()) {\n\t\t\t\tif (val_.GetReg().IsSymbolic()) {\n\t\t\t\t\tf.DeclareResultReg(val_);\n\t\t\t\t} else if (val_.GetReg().id != AL) {\n\t\t\t\t\tf.mov(f.al, static_cast<Reg8&>(val_));\n\t\t\t\t}\n\t\t\t} else if (val_.IsMem()) {\n\t\t\t\tf.mov(f.al, static_cast<Mem8&>(val_));\n\t\t\t} else if (val_.IsImm()) {\n\t\t\t\tf.mov(f.al, static_cast<Imm8&>(val_));\n\t\t\t}\n\t\t}\n\t};\n\n\t// specialization for 2bytes type\n\ttemplate<class T>\n\tstruct ResultT<T, 2> {\n\t\tenum { ArgR = 0 };\n\t\tOpd16 val_;\n\t\tResultT() {}\n\t\tResultT(const Opd16& val) : val_(val) {}\n\t\tResultT(uint16 imm) : val_(Imm16(imm)) {}\n\t\tvoid StoreResult(Frontend& f, const ResultDest& /*dst*/)\n\t\t{\n\t\t\tif (val_.IsGpReg()) {\n\t\t\t\tif (val_.GetReg().IsSymbolic()) {\n\t\t\t\t\tf.DeclareResultReg(val_);\n\t\t\t\t} else if (val_.GetReg().id != AX) {\n\t\t\t\t\tf.mov(f.ax, static_cast<Reg16&>(val_));\n\t\t\t\t}\n\t\t\t} else if (val_.IsMem()) {\n\t\t\t\tf.mov(f.ax, static_cast<Mem16&>(val_));\n\t\t\t} else if (val_.IsImm()) {\n\t\t\t\tf.mov(f.ax, static_cast<Imm16&>(val_));\n\t\t\t}\n\t\t}\n\t};\n\n\t// specialization for 4bytes type\n\ttemplate<class T>\n\tstruct ResultT<T, 4> {\n\t\tenum { ArgR = 0 };\n\t\tOpd32 val_;\n\t\tResultT() {}\n\t\tResultT(const Opd32& val) : val_(val) {}\n\t\tResultT(uint32 imm) : val_(Imm32(imm)) {}\n\t\tvoid StoreResult(Frontend& f, const ResultDest& /*dst*/)\n\t\t{\n\t\t\tif (val_.IsGpReg()) {\n\t\t\t\tif (val_.GetReg().IsSymbolic()) {\n\t\t\t\t\tf.DeclareResultReg(val_);\n\t\t\t\t} else if (val_.GetReg().id != EAX) {\n\t\t\t\t\tf.mov(f.eax, static_cast<Reg32&>(val_));\n\t\t\t\t}\n\t\t\t} else if (val_.IsMem()) {\n\t\t\t\tf.mov(f.eax, static_cast<Mem32&>(val_));\n\t\t\t} else if (val_.IsImm()) {\n\t\t\t\tf.mov(f.eax, static_cast<Imm32&>(val_));\n\t\t\t}\n\t\t}\n\t};\n\n\t// specialization for 8bytes type\n\ttemplate<class T>\n\tstruct ResultT<T, 8> {\n\t\tenum { ArgR = 0 };\n\t\tOpd64 val_;\n\t\tResultT() {}\n\t\tResultT(const Opd64& val) : val_(val) {}\n\t\tResultT(uint64 imm) : val_(Imm64(imm)) {}\n\t\tvoid StoreResult(Frontend& f, const ResultDest& /*dst*/)\n\t\t{\n#ifdef JITASM64\n\t\t\tif (val_.IsGpReg()) {\n\t\t\t\tif (val_.GetReg().IsSymbolic()) {\n\t\t\t\t\tf.DeclareResultReg(val_);\n\t\t\t\t} else if (val_.GetReg().id != RAX) {\n\t\t\t\t\tf.mov(f.rax, static_cast<Reg64&>(val_));\n\t\t\t\t}\n\t\t\t} else if (val_.IsMem()) {\n\t\t\t\tf.mov(f.rax, static_cast<Mem64&>(val_));\n\t\t\t} else if (val_.IsImm()) {\n\t\t\t\tf.mov(f.rax, static_cast<Imm64&>(val_));\n\t\t\t} else if (val_.IsMmxReg()) {\n\t\t\t\tf.movq(f.rax, static_cast<MmxReg&>(val_));\n\t\t\t}\n#else\n\t\t\tif (val_.IsMem()) {\n        // from memory\n        Mem32 lo(val_.GetAddressBaseSize(), val_.GetAddressIndexSize(), val_.GetBase(), val_.GetIndex(), val_.GetScale(), val_.GetDisp());\n\t\t\t\tMem32 hi(val_.GetAddressBaseSize(), val_.GetAddressIndexSize(), val_.GetBase(), val_.GetIndex(), val_.GetScale(), val_.GetDisp() + 4);\n\t\t\t\tf.mov(f.eax, lo);\n\t\t\t\tf.mov(f.edx, hi);\n\t\t\t} else if (val_.IsImm()) {\n\t\t\t\t// from immediate\n\t\t\t\tf.mov(f.eax, static_cast<sint32>(val_.GetImm()));\n\t\t\t\tf.mov(f.edx, static_cast<sint32>(val_.GetImm() >> 32));\n\t\t\t}\n#endif\n\t\t}\n\t};\n\n\t// specialization for float\n\ttemplate<>\n\tstruct ResultT<float, 4> {\n\t\tenum { ArgR = 0 };\n\t\tdetail::Opd val_;\n\t\tResultT() {}\n\t\tResultT(const FpuReg& fpu) : val_(fpu) {}\n\t\tResultT(const Mem32& mem) : val_(mem) {}\n\t\tResultT(const XmmReg& xmm) : val_(xmm) {}\n\t\tResultT(const float imm) : val_(Imm32(*(uint32*)&imm)) {}\n\t\tvoid StoreResult(Frontend& f, const ResultDest& /*dst*/)\n\t\t{\n#ifdef JITASM64\n\t\t\tif (val_.IsFpuReg()) {\n\t\t\t\t// from FPU register\n\t\t\t\tf.fstp(f.real4_ptr[f.rsp - 4]);\n\t\t\t\tf.movss(f.xmm0, f.dword_ptr[f.rsp - 4]);\n\t\t\t} else if (val_.IsMem() && val_.GetSize() == O_SIZE_32) {\n\t\t\t\t// from memory\n\t\t\t\tf.movss(f.xmm0, static_cast<Mem32&>(val_));\n\t\t\t} else if (val_.IsXmmReg()) {\n\t\t\t\t// from XMM register\n\t\t\t\tif (val_.GetReg().IsSymbolic()) {\n\t\t\t\t\tf.DeclareResultReg(val_);\n\t\t\t\t} else if (val_.GetReg().id != XMM0) {\n\t\t\t\t\tf.movss(f.xmm0, static_cast<XmmReg&>(val_));\n\t\t\t\t}\n\t\t\t} else if (val_.IsImm()) {\n\t\t\t\t// from float immediate\n\t\t\t\tf.mov(f.dword_ptr[f.rsp - 4], static_cast<Imm32&>(val_));\n\t\t\t\tf.movss(f.xmm0, f.dword_ptr[f.rsp - 4]);\n\t\t\t}\n#else\n\t\t\tif (val_.IsFpuReg()) {\n\t\t\t\t// from FPU register\n\t\t\t\tif (val_.GetReg().id != ST0) {\n\t\t\t\t\tf.fld(static_cast<FpuReg&>(val_));\n\t\t\t\t}\n\t\t\t} else if (val_.IsMem() && val_.GetSize() == O_SIZE_32) {\n\t\t\t\t// from memory\n\t\t\t\tf.fld(static_cast<Mem32&>(val_));\n\t\t\t} else if (val_.IsXmmReg()) {\n\t\t\t\t// from XMM register\n\t\t\t\tf.movss(f.dword_ptr[f.esp - 4], static_cast<XmmReg&>(val_));\n\t\t\t\tf.fld(f.real4_ptr[f.esp - 4]);\n\t\t\t} else if (val_.IsImm()) {\n\t\t\t\t// from float immediate\n\t\t\t\tf.mov(f.dword_ptr[f.esp - 4], static_cast<Imm32&>(val_));\n\t\t\t\tf.fld(f.real4_ptr[f.esp - 4]);\n\t\t\t}\n#endif\n\t\t}\n\t};\n\n\t// specialization for double\n\ttemplate<>\n\tstruct ResultT<double, 8> {\n\t\tenum { ArgR = 0 };\n\t\tdetail::Opd val_;\n\t\tdouble imm_;\n\t\tResultT() {}\n\t\tResultT(const FpuReg& fpu) : val_(fpu) {}\n\t\tResultT(const Mem64& mem) : val_(mem) {}\n\t\tResultT(const XmmReg& xmm) : val_(xmm) {}\n\t\tResultT(const double imm) : val_(Imm32(0)), imm_(imm) {}\n\t\tvoid StoreResult(Frontend& f, const ResultDest& /*dst*/)\n\t\t{\n#ifdef JITASM64\n\t\t\tif (val_.IsFpuReg()) {\n\t\t\t\t// from FPU register\n\t\t\t\tf.fstp(f.real8_ptr[f.rsp - 8]);\n\t\t\t\tf.movsd(f.xmm0, f.qword_ptr[f.rsp - 8]);\n\t\t\t} else if (val_.IsMem() && val_.GetSize() == O_SIZE_64) {\n\t\t\t\t// from memory\n\t\t\t\tf.movsd(f.xmm0, static_cast<Mem64&>(val_));\n\t\t\t} else if (val_.IsXmmReg()) {\n\t\t\t\t// from XMM register\n\t\t\t\tif (val_.GetReg().IsSymbolic()) {\n\t\t\t\t\tf.DeclareResultReg(val_);\n\t\t\t\t} else if (val_.GetReg().id != XMM0) {\n\t\t\t\t\tf.movsd(f.xmm0, static_cast<XmmReg&>(val_));\n\t\t\t\t}\n\t\t\t} else if (val_.IsImm()) {\n\t\t\t\t// from float immediate\n\t\t\t\tf.mov(f.dword_ptr[f.rsp - 8], *reinterpret_cast<uint32*>(&imm_));\n\t\t\t\tf.mov(f.dword_ptr[f.rsp - 4], *(reinterpret_cast<uint32*>(&imm_) + 1));\n\t\t\t\tf.movsd(f.xmm0, f.qword_ptr[f.rsp - 8]);\n\t\t\t}\n#else\n\t\t\tif (val_.IsFpuReg()) {\n\t\t\t\t// from FPU register\n\t\t\t\tif (val_.GetReg().id != ST0) {\n\t\t\t\t\tf.fld(static_cast<FpuReg&>(val_));\n\t\t\t\t}\n\t\t\t} else if (val_.IsMem() && val_.GetSize() == O_SIZE_64) {\n\t\t\t\t// from memory\n\t\t\t\tf.fld(static_cast<Mem64&>(val_));\n\t\t\t} else if (val_.IsXmmReg()) {\n\t\t\t\t// from XMM register\n\t\t\t\tf.movsd(f.qword_ptr[f.esp - 8], static_cast<XmmReg&>(val_));\n\t\t\t\tf.fld(f.real8_ptr[f.esp - 8]);\n\t\t\t} else if (val_.IsImm()) {\t// val_ is immediate 0\n\t\t\t\t// from double immediate\n\t\t\t\tf.mov(f.dword_ptr[f.esp - 8], *reinterpret_cast<uint32*>(&imm_));\n\t\t\t\tf.mov(f.dword_ptr[f.esp - 4], *(reinterpret_cast<uint32*>(&imm_) + 1));\n\t\t\t\tf.fld(f.real8_ptr[f.esp - 8]);\n\t\t\t}\n#endif\n\t\t}\n\t};\n\n\n#if JITASM_MMINTRIN\n\t// specialization for __m64\n\ttemplate<>\n\tstruct ResultT<__m64, 8> {\n\t\tenum { ArgR = 0 };\n\t\tOpd64 val_;\n\t\tResultT() {}\n\t\tResultT(const MmxReg& mm) : val_(mm) {}\n\t\tResultT(const Mem64& mem) : val_(mem) {}\n\t\tvoid StoreResult(Frontend& f, const ResultDest& /*dst*/)\n\t\t{\n#if defined(JITASM64) && !defined(JITASM_WIN)\n\t\t\tif (val_.IsMmxReg()) {\n\t\t\t\tf.movq2dq(f.xmm0, static_cast<const MmxReg&>(val_));\n\t\t\t} else if (val_.IsMem()) {\n\t\t\t\tf.movq(f.xmm0, static_cast<const Mem64&>(val_));\n\t\t\t}\n#else\n\t\t\tif (val_.IsMmxReg()) {\n\t\t\t\tif (val_.GetReg().IsSymbolic()) {\n\t\t\t\t\tf.DeclareResultReg(val_);\n\t\t\t\t} else if (val_.GetReg().id != MM0) {\n\t\t\t\t\tf.movq(f.mm0, static_cast<const MmxReg&>(val_));\n\t\t\t\t}\n\t\t\t} else if (val_.IsMem()) {\n\t\t\t\tf.movq(f.mm0, static_cast<const Mem64&>(val_));\n\t\t\t}\n#endif\n\t\t}\n\t};\n#endif\t// JITASM_MMINTRIN\n\n#if JITASM_XMMINTRIN\n\t// specialization for __m128\n\ttemplate<>\n\tstruct ResultT<__m128, 16> {\n\t\tenum { ArgR = 0 };\n\t\tOpd128 val_;\n\t\tResultT() {}\n\t\tResultT(const XmmReg& xmm) : val_(xmm) {}\n\t\tResultT(const Mem128& mem) : val_(mem) {}\n\t\tvoid StoreResult(Frontend& f, const ResultDest& /*dst*/)\n\t\t{\n\t\t\tif (val_.IsXmmReg()) {\n\t\t\t\tif (val_.GetReg().IsSymbolic()) {\n\t\t\t\t\tf.DeclareResultReg(val_);\n\t\t\t\t} else if (val_.GetReg().id != XMM0) {\n\t\t\t\t\tf.movaps(f.xmm0, static_cast<const XmmReg&>(val_));\n\t\t\t\t}\n\t\t\t} else if (val_.IsMem()) {\n\t\t\t\tf.movaps(f.xmm0, static_cast<const Mem128&>(val_));\n\t\t\t}\n\t\t}\n\t};\n#endif\t// JITASM_XMMINTRIN\n\n#if JITASM_EMMINTRIN\n\t// specialization for __m128d\n\ttemplate<>\n\tstruct ResultT<__m128d, 16> {\n\t\tenum { ArgR = 0 };\n\t\tOpd128 val_;\n\t\tResultT() {}\n\t\tResultT(const XmmReg& xmm) : val_(xmm) {}\n\t\tResultT(const Mem128& mem) : val_(mem) {}\n\t\tvoid StoreResult(Frontend& f, const ResultDest& /*dst*/)\n\t\t{\n\t\t\tif (val_.IsXmmReg()) {\n\t\t\t\tif (val_.GetReg().IsSymbolic()) {\n\t\t\t\t\tf.DeclareResultReg(val_);\n\t\t\t\t} else if (val_.GetReg().id != XMM0) {\n\t\t\t\t\tf.movapd(f.xmm0, static_cast<const XmmReg&>(val_));\n\t\t\t\t}\n\t\t\t} else if (val_.IsMem()) {\n\t\t\t\tf.movapd(f.xmm0, static_cast<const Mem128&>(val_));\n\t\t\t}\n\t\t}\n\t};\n\n\t// specialization for __m128i\n\ttemplate<>\n\tstruct ResultT<__m128i, 16> {\n\t\tenum { ArgR = 0 };\n\t\tOpd128 val_;\n\t\tResultT() {}\n\t\tResultT(const XmmReg& xmm) : val_(xmm) {}\n\t\tResultT(const Mem128& mem) : val_(mem) {}\n\t\tvoid StoreResult(Frontend& f, const ResultDest& /*dst*/)\n\t\t{\n\t\t\tif (val_.IsXmmReg()) {\n\t\t\t\tif (val_.GetReg().IsSymbolic()) {\n\t\t\t\t\tf.DeclareResultReg(val_);\n\t\t\t\t} else if (val_.GetReg().id != XMM0) {\n\t\t\t\t\tf.movdqa(f.xmm0, static_cast<const XmmReg&>(val_));\n\t\t\t\t}\n\t\t\t} else if (val_.IsMem()) {\n\t\t\t\tf.movdqa(f.xmm0, static_cast<const Mem128&>(val_));\n\t\t\t}\n\t\t}\n\t};\n#endif\t// JITASM_EMMINTRIN\n\n\n\tnamespace calling_convention_cdecl\n\t{\n#ifdef JITASM64\n#ifdef JITASM_WIN\n\t\ttemplate<int N, class T, int Size = sizeof(T)> struct ArgTraits : ArgTraits_win64<N, T, Size> {};\n#else\n\t\ttemplate<int N, class T, int Size = sizeof(T)> struct ArgTraits : ArgTraits_linux64<N, T, Size> {};\n#endif\n#else\n\t\ttemplate<int N, class T, int Size = sizeof(T)> struct ArgTraits : ArgTraits_cdecl<N, T, Size> {};\n#endif\n\n\t\ttemplate<class R>\n\t\tArgInfo ResultInfo()\n\t\t{\n\t\t\tif (ResultT<R>::ArgR) {\n#ifdef JITASM64\n\t\t\t\treturn ArgInfo(Addr(RegID::CreatePhysicalRegID(R_TYPE_GP, RBP), SIZE_OF_GP_REG * 2), RCX, ARG_IN_REG | ARG_TYPE_PTR);\n#else\n\t\t\t\treturn ArgInfo(Addr(RegID::CreatePhysicalRegID(R_TYPE_GP, EBP), SIZE_OF_GP_REG * 2), INVALID, ARG_IN_STACK | ARG_TYPE_PTR);\n#endif\n\t\t\t} else {\n\t\t\t\treturn ArgInfo(Addr(RegID::Invalid(), 0), INVALID, 0);\n\t\t\t}\n\t\t}\n\n\t\ttemplate<class R, class A1>\n\t\tArgInfo ArgInfo1()\t{ return ArgInfo(Addr(RegID::CreatePhysicalRegID(R_TYPE_GP, EBP), SIZE_OF_GP_REG * (2 + ResultT<R>::ArgR)), static_cast<PhysicalRegID>(ArgTraits<ResultT<R>::ArgR + 0, A1>::reg_id), ArgTraits<ResultT<R>::ArgR + 0, A1>::flag); }\n\t\ttemplate<class R, class A1, class A2>\n\t\tArgInfo ArgInfo2()\t{ return ArgInfo(ArgInfo1<R, A1>()).Next< ArgTraits<ResultT<R>::ArgR + 0, A1>, ArgTraits<ResultT<R>::ArgR + 1, A2> >(); }\n\t\ttemplate<class R, class A1, class A2, class A3>\n\t\tArgInfo ArgInfo3()\t{ return ArgInfo(ArgInfo2<R, A1, A2>()).Next< ArgTraits<ResultT<R>::ArgR + 1, A2>, ArgTraits<ResultT<R>::ArgR + 2, A3> >(); }\n\t\ttemplate<class R, class A1, class A2, class A3, class A4>\n\t\tArgInfo ArgInfo4()\t{ return ArgInfo(ArgInfo3<R, A1, A2, A3>()).Next< ArgTraits<ResultT<R>::ArgR + 2, A3>, ArgTraits<ResultT<R>::ArgR + 3, A4> >(); }\n\t\ttemplate<class R, class A1, class A2, class A3, class A4, class A5>\n\t\tArgInfo ArgInfo5()\t{ return ArgInfo(ArgInfo4<R, A1, A2, A3, A4>()).Next< ArgTraits<ResultT<R>::ArgR + 3, A4>, ArgTraits<ResultT<R>::ArgR + 4, A5> >(); }\n\t\ttemplate<class R, class A1, class A2, class A3, class A4, class A5, class A6>\n\t\tArgInfo ArgInfo6()\t{ return ArgInfo(ArgInfo5<R, A1, A2, A3, A4, A5>()).Next< ArgTraits<ResultT<R>::ArgR + 4, A5>, ArgTraits<ResultT<R>::ArgR + 5, A6> >(); }\n\t\ttemplate<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>\n\t\tArgInfo ArgInfo7()\t{ return ArgInfo(ArgInfo6<R, A1, A2, A3, A4, A5, A6>()).Next< ArgTraits<ResultT<R>::ArgR + 5, A6>, ArgTraits<ResultT<R>::ArgR + 6, A7> >(); }\n\t\ttemplate<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>\n\t\tArgInfo ArgInfo8()\t{ return ArgInfo(ArgInfo7<R, A1, A2, A3, A4, A5, A6, A7>()).Next< ArgTraits<ResultT<R>::ArgR + 6, A7>, ArgTraits<ResultT<R>::ArgR + 7, A8> >(); }\n\t\ttemplate<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>\n\t\tArgInfo ArgInfo9()\t{ return ArgInfo(ArgInfo8<R, A1, A2, A3, A4, A5, A6, A7, A8>()).Next< ArgTraits<ResultT<R>::ArgR + 7, A8>, ArgTraits<ResultT<R>::ArgR + 8, A9> >(); }\n\t\ttemplate<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>\n\t\tArgInfo ArgInfo10()\t{ return ArgInfo(ArgInfo9<R, A1, A2, A3, A4, A5, A6, A7, A8, A9>()).Next< ArgTraits<ResultT<R>::ArgR + 8, A9>, ArgTraits<ResultT<R>::ArgR + 9, A10> >(); }\n\n\t\t/// Function argument\n\t\ttemplate<class T, size_t Size = sizeof(T)>\n\t\tstruct Arg\n\t\t{\n\t\t\tAddr addr_;\n#ifdef JITASM64\n\t\t\tArg(Frontend& f, const ArgInfo& arg_info) : addr_(Reg()) {\n\t\t\t\tif (arg_info.reg_id != INVALID) {\n\t\t\t\t\tf.DeclareRegArg(Reg(addr_.reg_), Reg(arg_info.reg_id), f.ptr[arg_info.addr]);\n\t\t\t\t} else {\n\t\t\t\t\tf.DeclareStackArg(Reg(addr_.reg_), f.ptr[arg_info.addr]);\n\t\t\t\t}\n\t\t\t}\n#else\n\t\t\tArg(Frontend& f, const ArgInfo& arg_info) : addr_(arg_info.addr) {}\n#endif\n\t\t\toperator Addr () {return addr_;}\n\t\t};\n\n\t\t// specialization for 1byte type\n\t\ttemplate<class T>\n\t\tstruct Arg<T, 1>\n\t\t{\n\t\t\tFrontend *f_;\n\t\t\tArgInfo arg_info_;\n\n\t\t\tArg(Frontend& f, const ArgInfo& arg_info) : f_(&f), arg_info_(arg_info) {}\n\t\t\toperator Addr () {\n#ifdef JITASM64\n\t\t\t\t// Dump to shadow space when x64 argument on register\n\t\t\t\tif (arg_info_.reg_id != INVALID) {\n\t\t\t\t\tf_->movzx(Reg64(arg_info_.reg_id), Reg8(arg_info_.reg_id));\n\t\t\t\t\tf_->mov(f_->qword_ptr[arg_info_.addr], Reg64(arg_info_.reg_id));\n\t\t\t\t}\n#endif\n\t\t\t\treturn arg_info_.addr;\n\t\t\t}\n\t\t\toperator Reg8 () {\n\t\t\t\tReg8 reg;\n\t\t\t\tif (arg_info_.reg_id == INVALID) {\n\t\t\t\t\tf_->DeclareStackArg(reg, f_->byte_ptr[arg_info_.addr]);\t\t\t\t\t// argument on stack\n\t\t\t\t} else {\n\t\t\t\t\tf_->DeclareRegArg(reg, Reg8(arg_info_.reg_id), f_->byte_ptr[arg_info_.addr]);\t// argument on register\n\t\t\t\t}\n\t\t\t\treturn reg;\n\t\t\t}\n\t\t};\n\n\t\t// specialization for 2byte type\n\t\ttemplate<class T>\n\t\tstruct Arg<T, 2>\n\t\t{\n\t\t\tFrontend *f_;\n\t\t\tArgInfo arg_info_;\n\n\t\t\tArg(Frontend& f, const ArgInfo& arg_info) : f_(&f), arg_info_(arg_info) {}\n\t\t\toperator Addr () {\n#ifdef JITASM64\n\t\t\t\t// Dump to shadow space when x64 argument on register\n\t\t\t\tif (arg_info_.reg_id != INVALID) {\n\t\t\t\t\tf_->movzx(Reg64(arg_info_.reg_id), Reg16(arg_info_.reg_id));\n\t\t\t\t\tf_->mov(f_->qword_ptr[arg_info_.addr], Reg64(arg_info_.reg_id));\n\t\t\t\t}\n#endif\n\t\t\t\treturn arg_info_.addr;\n\t\t\t}\n\t\t\toperator Reg16 () {\n\t\t\t\tReg16 reg;\n\t\t\t\tif (arg_info_.reg_id == INVALID) {\n\t\t\t\t\tf_->DeclareStackArg(reg, f_->word_ptr[arg_info_.addr]);\t\t\t\t\t// argument on stack\n\t\t\t\t} else {\n\t\t\t\t\tf_->DeclareRegArg(reg, Reg16(arg_info_.reg_id), f_->word_ptr[arg_info_.addr]);\t// argument on register\n\t\t\t\t}\n\t\t\t\treturn reg;\n\t\t\t}\n\t\t};\n\n\t\t// specialization for 4byte type\n\t\ttemplate<class T>\n\t\tstruct Arg<T, 4>\n\t\t{\n\t\t\tFrontend *f_;\n\t\t\tArgInfo arg_info_;\n\n\t\t\tArg(Frontend& f, const ArgInfo& arg_info) : f_(&f), arg_info_(arg_info) {}\n\t\t\toperator Addr () {\n#ifdef JITASM64\n\t\t\t\t// Dump to shadow space when x64 argument on register\n\t\t\t\tif (arg_info_.reg_id != INVALID) {\n\t\t\t\t\tf_->mov(f_->qword_ptr[arg_info_.addr], Reg64(arg_info_.reg_id));\n\t\t\t\t}\n#endif\n\t\t\t\treturn arg_info_.addr;\n\t\t\t}\n\t\t\toperator Reg32 () {\n\t\t\t\tReg32 reg;\n\t\t\t\tif (arg_info_.reg_id == INVALID) {\n\t\t\t\t\tf_->DeclareStackArg(reg, f_->dword_ptr[arg_info_.addr]);\t\t\t\t\t// argument on stack\n\t\t\t\t} else {\n\t\t\t\t\tf_->DeclareRegArg(reg, Reg32(arg_info_.reg_id), f_->dword_ptr[arg_info_.addr]);\t// argument on register\n\t\t\t\t}\n\t\t\t\treturn reg;\n\t\t\t}\n\t\t};\n\n#ifdef JITASM64\n\t\t// specialization for 8byte type\n\t\ttemplate<class T>\n\t\tstruct Arg<T, 8>\n\t\t{\n\t\t\tFrontend *f_;\n\t\t\tArgInfo arg_info_;\n\n\t\t\tArg(Frontend& f, const ArgInfo& arg_info) : f_(&f), arg_info_(arg_info) {}\n\t\t\toperator Addr () {\n\t\t\t\t// Dump to shadow space when x64 argument on register\n\t\t\t\tif (arg_info_.reg_id != INVALID) {\n\t\t\t\t\tf_->mov(f_->qword_ptr[arg_info_.addr], Reg64(arg_info_.reg_id));\n\t\t\t\t}\n\t\t\t\treturn arg_info_.addr;\n\t\t\t}\n\t\t\toperator Reg64 () {\n\t\t\t\tReg64 reg;\n\t\t\t\tif (arg_info_.reg_id == INVALID) {\n\t\t\t\t\tf_->DeclareStackArg(reg, f_->qword_ptr[arg_info_.addr]);\t\t\t\t\t// argument on stack\n\t\t\t\t} else {\n\t\t\t\t\tf_->DeclareRegArg(reg, Reg64(arg_info_.reg_id), f_->qword_ptr[arg_info_.addr]);\t// argument on register\n\t\t\t\t}\n\t\t\t\treturn reg;\n\t\t\t}\n\t\t};\n#endif\n\n\t\t// specialization for float\n\t\ttemplate<>\n\t\tstruct Arg<float, 4>\n\t\t{\n\t\t\tFrontend *f_;\n\t\t\tArgInfo arg_info_;\n\n\t\t\tArg(Frontend& f, const ArgInfo& arg_info) : f_(&f), arg_info_(arg_info) {}\n\t\t\toperator Addr () {\n#ifdef JITASM64\n\t\t\t\t// Dump to shadow space when x64 argument on register\n\t\t\t\tif (arg_info_.reg_id != INVALID) {\n\t\t\t\t\tf_->movss(f_->dword_ptr[arg_info_.addr], XmmReg(arg_info_.reg_id));\n\t\t\t\t}\n#endif\n\t\t\t\treturn arg_info_.addr;\n\t\t\t}\n\t\t\toperator XmmReg () {\n\t\t\t\tXmmReg reg;\n\t\t\t\tif (arg_info_.reg_id == INVALID) {\n\t\t\t\t\tf_->DeclareStackArg(reg, f_->dword_ptr[arg_info_.addr]);\t// argument on stack\n\t\t\t\t} else {\n\t\t\t\t\tf_->DeclareRegArg(reg, XmmReg(arg_info_.reg_id));\t\t// argument on register\n\t\t\t\t}\n\t\t\t\treturn reg;\n\t\t\t}\n\t\t};\n\n\t\t// specialization for double\n\t\ttemplate<>\n\t\tstruct Arg<double, 8>\n\t\t{\n\t\t\tFrontend *f_;\n\t\t\tArgInfo arg_info_;\n\n\t\t\tArg(Frontend& f, const ArgInfo& arg_info) : f_(&f), arg_info_(arg_info) {}\n\t\t\toperator Addr () {\n#ifdef JITASM64\n\t\t\t\t// Dump to shadow space when x64 argument on register\n\t\t\t\tif (arg_info_.reg_id != INVALID) {\n\t\t\t\t\tf_->movsd(f_->qword_ptr[arg_info_.addr], XmmReg(arg_info_.reg_id));\n\t\t\t\t}\n#endif\n\t\t\t\treturn arg_info_.addr;\n\t\t\t}\n\t\t\toperator XmmReg () {\n\t\t\t\tXmmReg reg;\n\t\t\t\tif (arg_info_.reg_id == INVALID) {\n\t\t\t\t\tf_->DeclareStackArg(reg, f_->qword_ptr[arg_info_.addr]);\t// argument on stack\n\t\t\t\t} else {\n\t\t\t\t\tf_->DeclareRegArg(reg, XmmReg(arg_info_.reg_id));\t\t// argument on register\n\t\t\t\t}\n\t\t\t\treturn reg;\n\t\t\t}\n\t\t};\n\n#if JITASM_MMINTRIN\n\t\t// specialization for __m64\n\t\ttemplate<>\n\t\tstruct Arg<__m64, 8>\n\t\t{\n\t\t\tFrontend *f_;\n\t\t\tArgInfo arg_info_;\n\n\t\t\tArg(Frontend& f, const ArgInfo& arg_info) : f_(&f), arg_info_(arg_info) {}\n\t\t\toperator Addr () {\n\t\t\t\tif (arg_info_.reg_id != INVALID) {\n\t\t\t\t\t// Passed by mmx register\n\t\t\t\t\tif (arg_info_.flag & ARG_IN_REG) {\n\t\t\t\t\t\t// Win64\n#ifdef JITASM64\n\t\t\t\t\t\t// Dump to shadow space when Win64 argument on register\n\t\t\t\t\t\tReg64 arg;\n\t\t\t\t\t\tf_->DeclareRegArg(arg, Reg64(arg_info_.reg_id));\n\t\t\t\t\t\tf_->mov(f_->qword_ptr[arg_info_.addr], arg);\n#endif\n\t\t\t\t\t\treturn arg_info_.addr;\n\t\t\t\t\t} else if (arg_info_.flag & ARG_IN_XMM_INT) {\n\t\t\t\t\t\t// x64 Linux\n\t\t\t\t\t\tXmmReg arg;\n\t\t\t\t\t\tf_->DeclareRegArg(arg, XmmReg(arg_info_.reg_id));\n\t\t\t\t\t\tAddr addr = f_->stack_manager_.Alloc(8, 8);\n\t\t\t\t\t\tf_->movq(f_->qword_ptr[addr], arg);\n\t\t\t\t\t\treturn addr;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tMmxReg arg;\n\t\t\t\t\t\tf_->DeclareRegArg(arg, MmxReg(arg_info_.reg_id));\n\t\t\t\t\t\tAddr addr = f_->stack_manager_.Alloc(8, 8);\n\t\t\t\t\t\tf_->movq(f_->qword_ptr[addr], arg);\n\t\t\t\t\t\treturn addr;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Passed by stack\n\t\t\t\t\treturn arg_info_.addr;\n\t\t\t\t}\n\t\t\t}\n\t\t\toperator MmxReg () {\n\t\t\t\tMmxReg reg;\n\t\t\t\tif (arg_info_.reg_id != INVALID) {\n\t\t\t\t\t// Passed by register\n\t\t\t\t\tif (arg_info_.flag & ARG_IN_REG) {\n\t\t\t\t\t\t// Win64\n#ifdef JITASM64\n\t\t\t\t\t\tReg64 arg;\n\t\t\t\t\t\tf_->DeclareRegArg(arg, Reg64(arg_info_.reg_id));\n\t\t\t\t\t\tf_->movq(reg, arg);\n#endif\n\t\t\t\t\t} else if(arg_info_.flag & ARG_IN_XMM_INT) {\n\t\t\t\t\t\t// x64 Linux\n\t\t\t\t\t\tXmmReg arg;\n\t\t\t\t\t\tf_->DeclareRegArg(arg, XmmReg(arg_info_.reg_id));\n\t\t\t\t\t\tf_->movdq2q(reg, arg);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tf_->DeclareRegArg(reg, MmxReg(arg_info_.reg_id));\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Passed by stack\n\t\t\t\t\tf_->DeclareStackArg(reg, f_->qword_ptr[arg_info_.addr]);\n\t\t\t\t}\n\t\t\t\treturn reg;\n\t\t\t}\n\t\t};\n#endif\t// JITASM_MMINTRIN\n\n#if JITASM_XMMINTRIN\n\t\t// specialization for __m128\n\t\ttemplate<>\n\t\tstruct Arg<__m128, 16>\n\t\t{\n\t\t\tFrontend *f_;\n\t\t\tArgInfo arg_info_;\n\n\t\t\tArg(Frontend& f, const ArgInfo& arg_info) : f_(&f), arg_info_(arg_info) {}\n\t\t\toperator Addr () {\n\t\t\t\tif (arg_info_.flag & ARG_TYPE_PTR) {\n\t\t\t\t\tReg ptr;\n\t\t\t\t\tif (arg_info_.reg_id != INVALID) {\n\t\t\t\t\t\tf_->DeclareRegArg(ptr, Reg(arg_info_.reg_id));\t\t// argument on register\n\t\t\t\t\t} else {\n\t\t\t\t\t\tf_->mov(ptr, f_->ptr[arg_info_.addr]);\n\t\t\t\t\t}\n\t\t\t\t\treturn ptr;\n\t\t\t\t} else if (arg_info_.reg_id != INVALID) {\n\t\t\t\t\tAddr addr = f_->stack_manager_.Alloc(16, 16);\n\t\t\t\t\tf_->movdqa(f_->xmmword_ptr[addr], XmmReg(arg_info_.reg_id));\n\t\t\t\t\treturn addr;\n\t\t\t\t} else {\n\t\t\t\t\treturn arg_info_.addr;\n\t\t\t\t}\n\t\t\t}\n\t\t\toperator XmmReg () {\n\t\t\t\tXmmReg reg;\n\t\t\t\tif (arg_info_.flag & ARG_TYPE_PTR) {\n\t\t\t\t\t// Passed by pointer\n\t\t\t\t\tif (arg_info_.reg_id != INVALID) {\n\t\t\t\t\t\t// argument pointer on register\n\t\t\t\t\t\tf_->movdqa(reg, f_->xmmword_ptr[Reg(arg_info_.reg_id)]);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// argument pointer on stack\n\t\t\t\t\t\tReg ptr;\n\t\t\t\t\t\tf_->mov(ptr, f_->ptr[arg_info_.addr]);\n\t\t\t\t\t\tf_->movdqa(reg, f_->xmmword_ptr[ptr]);\n\t\t\t\t\t}\n\t\t\t\t} else if (arg_info_.reg_id != INVALID) {\n\t\t\t\t\t// Passed by xmm register\n\t\t\t\t\tf_->DeclareRegArg(reg, XmmReg(arg_info_.reg_id));\n\t\t\t\t} else {\n\t\t\t\t\t// Passed by stack\n\t\t\t\t\tf_->DeclareStackArg(reg, f_->xmmword_ptr[arg_info_.addr]);\n\t\t\t\t}\n\t\t\t\treturn reg;\n\t\t\t}\n\t\t};\n#endif\t// JITASM_XMMINTRIN\n\n#if JITASM_EMMINTRIN\n\t\t// specialization for __m128d, __m128i\n\t\ttemplate<> struct Arg<__m128d, 16> : Arg<__m128, 16> {\n\t\t\tArg(Frontend& f, const ArgInfo& arg_info) : Arg<__m128, 16>(f, arg_info) {}\n\t\t};\n\n\t\ttemplate<> struct Arg<__m128i, 16> : Arg<__m128, 16> {\n\t\t\tArg(Frontend& f, const ArgInfo& arg_info) : Arg<__m128, 16>(f, arg_info) {}\n\t\t};\n#endif\t// JITASM_EMMINTRIN\n\t}\t// namespace calling_convention_cdecl\n\n}\t// namespace detail\n\n/// cdecl function\ntemplate<\n\tclass R,\n\tclass Derived,\n\tclass A1 = detail::ArgNone,\n\tclass A2 = detail::ArgNone,\n\tclass A3 = detail::ArgNone,\n\tclass A4 = detail::ArgNone,\n\tclass A5 = detail::ArgNone,\n\tclass A6 = detail::ArgNone,\n\tclass A7 = detail::ArgNone,\n\tclass A8 = detail::ArgNone,\n\tclass A9 = detail::ArgNone,\n\tclass A10 = detail::ArgNone>\nstruct function_cdecl : Frontend\n{\n\ttypedef R (*FuncPtr)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);\n\ttypedef detail::ResultT<R> Result;\t///< main function result type\n\ttypename detail::ResultTraits<R>::ResultPtr result_ptr;\n\n\toperator FuncPtr() { return (FuncPtr)GetCode(); }\n\tvoid InternalMain() {static_cast<Derived *>(this)->naked_main();}\n\tvoid naked_main() {\n\t\tusing namespace detail::calling_convention_cdecl;\n\t\tProlog();\n\t\tdetail::ResultDest result_dst(*this, ResultInfo<R>());\n\t\tstatic_cast<Derived *>(this)->main(\n\t\t\tArg<A1>(*this, ArgInfo1<R,A1>()),\n\t\t\tArg<A2>(*this, ArgInfo2<R,A1,A2>()),\n\t\t\tArg<A3>(*this, ArgInfo3<R,A1,A2,A3>()),\n\t\t\tArg<A4>(*this, ArgInfo4<R,A1,A2,A3,A4>()),\n\t\t\tArg<A5>(*this, ArgInfo5<R,A1,A2,A3,A4,A5>()),\n\t\t\tArg<A6>(*this, ArgInfo6<R,A1,A2,A3,A4,A5,A6>()),\n\t\t\tArg<A7>(*this, ArgInfo7<R,A1,A2,A3,A4,A5,A6,A7>()),\n\t\t\tArg<A8>(*this, ArgInfo8<R,A1,A2,A3,A4,A5,A6,A7,A8>()),\n\t\t\tArg<A9>(*this, ArgInfo9<R,A1,A2,A3,A4,A5,A6,A7,A8,A9>()),\n\t\t\tArg<A10>(*this, ArgInfo10<R,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10>())\n\t\t\t).StoreResult(*this, result_dst);\n\t\tEpilog();\n\t}\n};\n\n// specialization for 10 arguments and no result\ntemplate<class Derived, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>\nstruct function_cdecl<void, Derived, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10> : Frontend\n{\n\ttypedef void (*FuncPtr)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);\n\toperator FuncPtr() { return (FuncPtr)GetCode(); }\n\tvoid InternalMain() {static_cast<Derived *>(this)->naked_main();}\n\tvoid naked_main() {\n\t\tusing namespace detail::calling_convention_cdecl;\n\t\tProlog();\n\t\tstatic_cast<Derived *>(this)->main(\n\t\t\tArg<A1>(*this, ArgInfo1<void,A1>()),\n\t\t\tArg<A2>(*this, ArgInfo2<void,A1,A2>()),\n\t\t\tArg<A3>(*this, ArgInfo3<void,A1,A2,A3>()),\n\t\t\tArg<A4>(*this, ArgInfo4<void,A1,A2,A3,A4>()),\n\t\t\tArg<A5>(*this, ArgInfo5<void,A1,A2,A3,A4,A5>()),\n\t\t\tArg<A6>(*this, ArgInfo6<void,A1,A2,A3,A4,A5,A6>()),\n\t\t\tArg<A7>(*this, ArgInfo7<void,A1,A2,A3,A4,A5,A6,A7>()),\n\t\t\tArg<A8>(*this, ArgInfo8<void,A1,A2,A3,A4,A5,A6,A7,A8>()),\n\t\t\tArg<A9>(*this, ArgInfo9<void,A1,A2,A3,A4,A5,A6,A7,A8,A9>()),\n\t\t\tArg<A10>(*this, ArgInfo10<void,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10>()));\n\t\tEpilog();\n\t}\n};\n\n// specialization for 9 arguments\ntemplate<class R, class Derived, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>\nstruct function_cdecl<R, Derived, A1, A2, A3, A4, A5, A6, A7, A8, A9, detail::ArgNone> : Frontend\n{\n\ttypedef R (*FuncPtr)(A1, A2, A3, A4, A5, A6, A7, A8, A9);\n\ttypedef detail::ResultT<R> Result;\t///< main function result type\n\ttypename detail::ResultTraits<R>::ResultPtr result_ptr;\n\toperator FuncPtr() { return (FuncPtr)GetCode(); }\n\tvoid InternalMain() {static_cast<Derived *>(this)->naked_main();}\n\tvoid naked_main() {\n\t\tusing namespace detail::calling_convention_cdecl;\n\t\tProlog();\n\t\tdetail::ResultDest result_dst(*this, ResultInfo<R>());\n\t\tstatic_cast<Derived *>(this)->main(\n\t\t\tArg<A1>(*this, ArgInfo1<R,A1>()),\n\t\t\tArg<A2>(*this, ArgInfo2<R,A1,A2>()),\n\t\t\tArg<A3>(*this, ArgInfo3<R,A1,A2,A3>()),\n\t\t\tArg<A4>(*this, ArgInfo4<R,A1,A2,A3,A4>()),\n\t\t\tArg<A5>(*this, ArgInfo5<R,A1,A2,A3,A4,A5>()),\n\t\t\tArg<A6>(*this, ArgInfo6<R,A1,A2,A3,A4,A5,A6>()),\n\t\t\tArg<A7>(*this, ArgInfo7<R,A1,A2,A3,A4,A5,A6,A7>()),\n\t\t\tArg<A8>(*this, ArgInfo8<R,A1,A2,A3,A4,A5,A6,A7,A8>()),\n\t\t\tArg<A9>(*this, ArgInfo9<R,A1,A2,A3,A4,A5,A6,A7,A8,A9>())\n\t\t\t).StoreResult(*this, result_dst);\n\t\tEpilog();\n\t}\n};\n\n// specialization for 9 arguments and no result\ntemplate<class Derived, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>\nstruct function_cdecl<void, Derived, A1, A2, A3, A4, A5, A6, A7, A8, A9, detail::ArgNone> : Frontend\n{\n\ttypedef void (*FuncPtr)(A1, A2, A3, A4, A5, A6, A7, A8, A9);\n\toperator FuncPtr() { return (FuncPtr)GetCode(); }\n\tvoid InternalMain() {static_cast<Derived *>(this)->naked_main();}\n\tvoid naked_main() {\n\t\tusing namespace detail::calling_convention_cdecl;\n\t\tProlog();\n\t\tstatic_cast<Derived *>(this)->main(\n\t\t\tArg<A1>(*this, ArgInfo1<void,A1>()),\n\t\t\tArg<A2>(*this, ArgInfo2<void,A1,A2>()),\n\t\t\tArg<A3>(*this, ArgInfo3<void,A1,A2,A3>()),\n\t\t\tArg<A4>(*this, ArgInfo4<void,A1,A2,A3,A4>()),\n\t\t\tArg<A5>(*this, ArgInfo5<void,A1,A2,A3,A4,A5>()),\n\t\t\tArg<A6>(*this, ArgInfo6<void,A1,A2,A3,A4,A5,A6>()),\n\t\t\tArg<A7>(*this, ArgInfo7<void,A1,A2,A3,A4,A5,A6,A7>()),\n\t\t\tArg<A8>(*this, ArgInfo8<void,A1,A2,A3,A4,A5,A6,A7,A8>()),\n\t\t\tArg<A9>(*this, ArgInfo9<void,A1,A2,A3,A4,A5,A6,A7,A8,A9>()));\n\t\tEpilog();\n\t}\n};\n\n// specialization for 8 arguments\ntemplate<class R, class Derived, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>\nstruct function_cdecl<R, Derived, A1, A2, A3, A4, A5, A6, A7, A8, detail::ArgNone, detail::ArgNone> : Frontend\n{\n\ttypedef R (*FuncPtr)(A1, A2, A3, A4, A5, A6, A7, A8);\n\ttypedef detail::ResultT<R> Result;\t///< main function result type\n\ttypename detail::ResultTraits<R>::ResultPtr result_ptr;\n\toperator FuncPtr() { return (FuncPtr)GetCode(); }\n\tvoid InternalMain() {static_cast<Derived *>(this)->naked_main();}\n\tvoid naked_main() {\n\t\tusing namespace detail::calling_convention_cdecl;\n\t\tProlog();\n\t\tdetail::ResultDest result_dst(*this, ResultInfo<R>());\n\t\tstatic_cast<Derived *>(this)->main(\n\t\t\tArg<A1>(*this, ArgInfo1<R,A1>()),\n\t\t\tArg<A2>(*this, ArgInfo2<R,A1,A2>()),\n\t\t\tArg<A3>(*this, ArgInfo3<R,A1,A2,A3>()),\n\t\t\tArg<A4>(*this, ArgInfo4<R,A1,A2,A3,A4>()),\n\t\t\tArg<A5>(*this, ArgInfo5<R,A1,A2,A3,A4,A5>()),\n\t\t\tArg<A6>(*this, ArgInfo6<R,A1,A2,A3,A4,A5,A6>()),\n\t\t\tArg<A7>(*this, ArgInfo7<R,A1,A2,A3,A4,A5,A6,A7>()),\n\t\t\tArg<A8>(*this, ArgInfo8<R,A1,A2,A3,A4,A5,A6,A7,A8>())\n\t\t\t).StoreResult(*this, result_dst);\n\t\tEpilog();\n\t}\n};\n\n// specialization for 8 arguments and no result\ntemplate<class Derived, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>\nstruct function_cdecl<void, Derived, A1, A2, A3, A4, A5, A6, A7, A8, detail::ArgNone, detail::ArgNone> : Frontend\n{\n\ttypedef void (*FuncPtr)(A1, A2, A3, A4, A5, A6, A7, A8);\n\toperator FuncPtr() { return (FuncPtr)GetCode(); }\n\tvoid InternalMain() {static_cast<Derived *>(this)->naked_main();}\n\tvoid naked_main() {\n\t\tusing namespace detail::calling_convention_cdecl;\n\t\tProlog();\n\t\tstatic_cast<Derived *>(this)->main(\n\t\t\tArg<A1>(*this, ArgInfo1<void,A1>()),\n\t\t\tArg<A2>(*this, ArgInfo2<void,A1,A2>()),\n\t\t\tArg<A3>(*this, ArgInfo3<void,A1,A2,A3>()),\n\t\t\tArg<A4>(*this, ArgInfo4<void,A1,A2,A3,A4>()),\n\t\t\tArg<A5>(*this, ArgInfo5<void,A1,A2,A3,A4,A5>()),\n\t\t\tArg<A6>(*this, ArgInfo6<void,A1,A2,A3,A4,A5,A6>()),\n\t\t\tArg<A7>(*this, ArgInfo7<void,A1,A2,A3,A4,A5,A6,A7>()),\n\t\t\tArg<A8>(*this, ArgInfo8<void,A1,A2,A3,A4,A5,A6,A7,A8>()));\n\t\tEpilog();\n\t}\n};\n\n// specialization for 7 arguments\ntemplate<class R, class Derived, class A1, class A2, class A3, class A4, class A5, class A6, class A7>\nstruct function_cdecl<R, Derived, A1, A2, A3, A4, A5, A6, A7, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend\n{\n\ttypedef R (*FuncPtr)(A1, A2, A3, A4, A5, A6, A7);\n\ttypedef detail::ResultT<R> Result;\t///< main function result type\n\ttypename detail::ResultTraits<R>::ResultPtr result_ptr;\n\toperator FuncPtr() { return (FuncPtr)GetCode(); }\n\tvoid InternalMain() {static_cast<Derived *>(this)->naked_main();}\n\tvoid naked_main() {\n\t\tusing namespace detail::calling_convention_cdecl;\n\t\tProlog();\n\t\tdetail::ResultDest result_dst(*this, ResultInfo<R>());\n\t\tstatic_cast<Derived *>(this)->main(\n\t\t\tArg<A1>(*this, ArgInfo1<R,A1>()),\n\t\t\tArg<A2>(*this, ArgInfo2<R,A1,A2>()),\n\t\t\tArg<A3>(*this, ArgInfo3<R,A1,A2,A3>()),\n\t\t\tArg<A4>(*this, ArgInfo4<R,A1,A2,A3,A4>()),\n\t\t\tArg<A5>(*this, ArgInfo5<R,A1,A2,A3,A4,A5>()),\n\t\t\tArg<A6>(*this, ArgInfo6<R,A1,A2,A3,A4,A5,A6>()),\n\t\t\tArg<A7>(*this, ArgInfo7<R,A1,A2,A3,A4,A5,A6,A7>())\n\t\t\t).StoreResult(*this, result_dst);\n\t\tEpilog();\n\t}\n};\n\n// specialization for 7 arguments and no result\ntemplate<class Derived, class A1, class A2, class A3, class A4, class A5, class A6, class A7>\nstruct function_cdecl<void, Derived, A1, A2, A3, A4, A5, A6, A7, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend\n{\n\ttypedef void (*FuncPtr)(A1, A2, A3, A4, A5, A6, A7);\n\toperator FuncPtr() { return (FuncPtr)GetCode(); }\n\tvoid InternalMain() {static_cast<Derived *>(this)->naked_main();}\n\tvoid naked_main() {\n\t\tusing namespace detail::calling_convention_cdecl;\n\t\tProlog();\n\t\tstatic_cast<Derived *>(this)->main(\n\t\t\tArg<A1>(*this, ArgInfo1<void,A1>()),\n\t\t\tArg<A2>(*this, ArgInfo2<void,A1,A2>()),\n\t\t\tArg<A3>(*this, ArgInfo3<void,A1,A2,A3>()),\n\t\t\tArg<A4>(*this, ArgInfo4<void,A1,A2,A3,A4>()),\n\t\t\tArg<A5>(*this, ArgInfo5<void,A1,A2,A3,A4,A5>()),\n\t\t\tArg<A6>(*this, ArgInfo6<void,A1,A2,A3,A4,A5,A6>()),\n\t\t\tArg<A7>(*this, ArgInfo7<void,A1,A2,A3,A4,A5,A6,A7>()));\n\t\tEpilog();\n\t}\n};\n\n// specialization for 6 arguments\ntemplate<class R, class Derived, class A1, class A2, class A3, class A4, class A5, class A6>\nstruct function_cdecl<R, Derived, A1, A2, A3, A4, A5, A6, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend\n{\n\ttypedef R (*FuncPtr)(A1, A2, A3, A4, A5, A6);\n\ttypedef detail::ResultT<R> Result;\t///< main function result type\n\ttypename detail::ResultTraits<R>::ResultPtr result_ptr;\n\toperator FuncPtr() { return (FuncPtr)GetCode(); }\n\tvoid InternalMain() {static_cast<Derived *>(this)->naked_main();}\n\tvoid naked_main() {\n\t\tusing namespace detail::calling_convention_cdecl;\n\t\tProlog();\n\t\tdetail::ResultDest result_dst(*this, ResultInfo<R>());\n\t\tstatic_cast<Derived *>(this)->main(\n\t\t\tArg<A1>(*this, ArgInfo1<R,A1>()),\n\t\t\tArg<A2>(*this, ArgInfo2<R,A1,A2>()),\n\t\t\tArg<A3>(*this, ArgInfo3<R,A1,A2,A3>()),\n\t\t\tArg<A4>(*this, ArgInfo4<R,A1,A2,A3,A4>()),\n\t\t\tArg<A5>(*this, ArgInfo5<R,A1,A2,A3,A4,A5>()),\n\t\t\tArg<A6>(*this, ArgInfo6<R,A1,A2,A3,A4,A5,A6>())\n\t\t\t).StoreResult(*this, result_dst);\n\t\tEpilog();\n\t}\n};\n\n// specialization for 6 arguments and no result\ntemplate<class Derived, class A1, class A2, class A3, class A4, class A5, class A6>\nstruct function_cdecl<void, Derived, A1, A2, A3, A4, A5, A6, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend\n{\n\ttypedef void (*FuncPtr)(A1, A2, A3, A4, A5, A6);\n\toperator FuncPtr() { return (FuncPtr)GetCode(); }\n\tvoid InternalMain() {static_cast<Derived *>(this)->naked_main();}\n\tvoid naked_main() {\n\t\tusing namespace detail::calling_convention_cdecl;\n\t\tProlog();\n\t\tstatic_cast<Derived *>(this)->main(\n\t\t\tArg<A1>(*this, ArgInfo1<void,A1>()),\n\t\t\tArg<A2>(*this, ArgInfo2<void,A1,A2>()),\n\t\t\tArg<A3>(*this, ArgInfo3<void,A1,A2,A3>()),\n\t\t\tArg<A4>(*this, ArgInfo4<void,A1,A2,A3,A4>()),\n\t\t\tArg<A5>(*this, ArgInfo5<void,A1,A2,A3,A4,A5>()),\n\t\t\tArg<A6>(*this, ArgInfo6<void,A1,A2,A3,A4,A5,A6>()));\n\t\tEpilog();\n\t}\n};\n\n// specialization for 5 arguments\ntemplate<class R, class Derived, class A1, class A2, class A3, class A4, class A5>\nstruct function_cdecl<R, Derived, A1, A2, A3, A4, A5, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend\n{\n\ttypedef R (*FuncPtr)(A1, A2, A3, A4, A5);\n\ttypedef detail::ResultT<R> Result;\t///< main function result type\n\ttypename detail::ResultTraits<R>::ResultPtr result_ptr;\n\toperator FuncPtr() { return (FuncPtr)GetCode(); }\n\tvoid InternalMain() {static_cast<Derived *>(this)->naked_main();}\n\tvoid naked_main() {\n\t\tusing namespace detail::calling_convention_cdecl;\n\t\tProlog();\n\t\tdetail::ResultDest result_dst(*this, ResultInfo<R>());\n\t\tstatic_cast<Derived *>(this)->main(\n\t\t\tArg<A1>(*this, ArgInfo1<R,A1>()),\n\t\t\tArg<A2>(*this, ArgInfo2<R,A1,A2>()),\n\t\t\tArg<A3>(*this, ArgInfo3<R,A1,A2,A3>()),\n\t\t\tArg<A4>(*this, ArgInfo4<R,A1,A2,A3,A4>()),\n\t\t\tArg<A5>(*this, ArgInfo5<R,A1,A2,A3,A4,A5>())\n\t\t\t).StoreResult(*this, result_dst);\n\t\tEpilog();\n\t}\n};\n\n// specialization for 5 arguments and no result\ntemplate<class Derived, class A1, class A2, class A3, class A4, class A5>\nstruct function_cdecl<void, Derived, A1, A2, A3, A4, A5, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend\n{\n\ttypedef void (*FuncPtr)(A1, A2, A3, A4, A5);\n\toperator FuncPtr() { return (FuncPtr)GetCode(); }\n\tvoid InternalMain() {static_cast<Derived *>(this)->naked_main();}\n\tvoid naked_main() {\n\t\tusing namespace detail::calling_convention_cdecl;\n\t\tProlog();\n\t\tstatic_cast<Derived *>(this)->main(\n\t\t\tArg<A1>(*this, ArgInfo1<void,A1>()),\n\t\t\tArg<A2>(*this, ArgInfo2<void,A1,A2>()),\n\t\t\tArg<A3>(*this, ArgInfo3<void,A1,A2,A3>()),\n\t\t\tArg<A4>(*this, ArgInfo4<void,A1,A2,A3,A4>()),\n\t\t\tArg<A5>(*this, ArgInfo5<void,A1,A2,A3,A4,A5>()));\n\t\tEpilog();\n\t}\n};\n\n// specialization for 4 arguments\ntemplate<class R, class Derived, class A1, class A2, class A3, class A4>\nstruct function_cdecl<R, Derived, A1, A2, A3, A4, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend\n{\n\ttypedef R (*FuncPtr)(A1, A2, A3, A4);\n\ttypedef detail::ResultT<R> Result;\t///< main function result type\n\ttypename detail::ResultTraits<R>::ResultPtr result_ptr;\n\toperator FuncPtr() { return (FuncPtr)GetCode(); }\n\tvoid InternalMain() {static_cast<Derived *>(this)->naked_main();}\n\tvoid naked_main() {\n\t\tusing namespace detail::calling_convention_cdecl;\n\t\tProlog();\n\t\tdetail::ResultDest result_dst(*this, ResultInfo<R>());\n\t\tstatic_cast<Derived *>(this)->main(\n\t\t\tArg<A1>(*this, ArgInfo1<R,A1>()),\n\t\t\tArg<A2>(*this, ArgInfo2<R,A1,A2>()),\n\t\t\tArg<A3>(*this, ArgInfo3<R,A1,A2,A3>()),\n\t\t\tArg<A4>(*this, ArgInfo4<R,A1,A2,A3,A4>())\n\t\t\t).StoreResult(*this, result_dst);\n\t\tEpilog();\n\t}\n};\n\n// specialization for 4 arguments and no result\ntemplate<class Derived, class A1, class A2, class A3, class A4>\nstruct function_cdecl<void, Derived, A1, A2, A3, A4, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend\n{\n\ttypedef void (*FuncPtr)(A1, A2, A3, A4);\n\toperator FuncPtr() { return (FuncPtr)GetCode(); }\n\tvoid InternalMain() {static_cast<Derived *>(this)->naked_main();}\n\tvoid naked_main() {\n\t\tusing namespace detail::calling_convention_cdecl;\n\t\tProlog();\n\t\tstatic_cast<Derived *>(this)->main(\n\t\t\tArg<A1>(*this, ArgInfo1<void,A1>()),\n\t\t\tArg<A2>(*this, ArgInfo2<void,A1,A2>()),\n\t\t\tArg<A3>(*this, ArgInfo3<void,A1,A2,A3>()),\n\t\t\tArg<A4>(*this, ArgInfo4<void,A1,A2,A3,A4>()));\n\t\tEpilog();\n\t}\n};\n\n// specialization for 3 arguments\ntemplate<class R, class Derived, class A1, class A2, class A3>\nstruct function_cdecl<R, Derived, A1, A2, A3, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend\n{\n\ttypedef R (*FuncPtr)(A1, A2, A3);\n\ttypedef detail::ResultT<R> Result;\t///< main function result type\n\ttypename detail::ResultTraits<R>::ResultPtr result_ptr;\n\toperator FuncPtr() { return (FuncPtr)GetCode(); }\n\tvoid InternalMain() {static_cast<Derived *>(this)->naked_main();}\n\tvoid naked_main() {\n\t\tusing namespace detail::calling_convention_cdecl;\n\t\tProlog();\n\t\tdetail::ResultDest result_dst(*this, ResultInfo<R>());\n\t\tstatic_cast<Derived *>(this)->main(\n\t\t\tArg<A1>(*this, ArgInfo1<R,A1>()),\n\t\t\tArg<A2>(*this, ArgInfo2<R,A1,A2>()),\n\t\t\tArg<A3>(*this, ArgInfo3<R,A1,A2,A3>())\n\t\t\t).StoreResult(*this, result_dst);\n\t\tEpilog();\n\t}\n};\n\n// specialization for 3 arguments and no result\ntemplate<class Derived, class A1, class A2, class A3>\nstruct function_cdecl<void, Derived, A1, A2, A3, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend\n{\n\ttypedef void (*FuncPtr)(A1, A2, A3);\n\toperator FuncPtr() { return (FuncPtr)GetCode(); }\n\tvoid InternalMain() {static_cast<Derived *>(this)->naked_main();}\n\tvoid naked_main() {\n\t\tusing namespace detail::calling_convention_cdecl;\n\t\tProlog();\n\t\tstatic_cast<Derived *>(this)->main(\n\t\t\tArg<A1>(*this, ArgInfo1<void,A1>()),\n\t\t\tArg<A2>(*this, ArgInfo2<void,A1,A2>()),\n\t\t\tArg<A3>(*this, ArgInfo3<void,A1,A2,A3>()));\n\t\tEpilog();\n\t}\n};\n\n// specialization for 2 arguments\ntemplate<class R, class Derived, class A1, class A2>\nstruct function_cdecl<R, Derived, A1, A2, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend\n{\n\ttypedef R (*FuncPtr)(A1, A2);\n\ttypedef detail::ResultT<R> Result;\t///< main function result type\n\ttypename detail::ResultTraits<R>::ResultPtr result_ptr;\n\toperator FuncPtr() { return (FuncPtr)GetCode(); }\n\tvoid InternalMain() {static_cast<Derived *>(this)->naked_main();}\n\tvoid naked_main() {\n\t\tusing namespace detail::calling_convention_cdecl;\n\t\tProlog();\n\t\tdetail::ResultDest result_dst(*this, ResultInfo<R>());\n\t\tstatic_cast<Derived *>(this)->main(\n\t\t\tArg<A1>(*this, ArgInfo1<R,A1>()),\n\t\t\tArg<A2>(*this, ArgInfo2<R,A1,A2>())\n\t\t\t).StoreResult(*this, result_dst);\n\t\tEpilog();\n\t}\n};\n\n// specialization for 2 arguments and no result\ntemplate<class Derived, class A1, class A2>\nstruct function_cdecl<void, Derived, A1, A2, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend\n{\n\ttypedef void (*FuncPtr)(A1, A2);\n\toperator FuncPtr() { return (FuncPtr)GetCode(); }\n\tvoid InternalMain() {static_cast<Derived *>(this)->naked_main();}\n\tvoid naked_main() {\n\t\tusing namespace detail::calling_convention_cdecl;\n\t\tProlog();\n\t\tstatic_cast<Derived *>(this)->main(\n\t\t\tArg<A1>(*this, ArgInfo1<void,A1>()),\n\t\t\tArg<A2>(*this, ArgInfo2<void,A1,A2>()));\n\t\tEpilog();\n\t}\n};\n\n// specialization for 1 argument\ntemplate<class R, class Derived, class A1>\nstruct function_cdecl<R, Derived, A1, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend\n{\n\ttypedef R (*FuncPtr)(A1);\n\ttypedef detail::ResultT<R> Result;\t///< main function result type\n\ttypename detail::ResultTraits<R>::ResultPtr result_ptr;\n\toperator FuncPtr() { return (FuncPtr)GetCode(); }\n\tvoid InternalMain() {static_cast<Derived *>(this)->naked_main();}\n\tvoid naked_main() {\n\t\tusing namespace detail::calling_convention_cdecl;\n\t\tProlog();\n\t\tdetail::ResultDest result_dst(*this, ResultInfo<R>());\n\t\tstatic_cast<Derived *>(this)->main(Arg<A1>(*this, ArgInfo1<R,A1>())).StoreResult(*this, result_dst);\n\t\tEpilog();\n\t}\n};\n\n// specialization for 1 argument and no result\ntemplate<class Derived, class A1>\nstruct function_cdecl<void, Derived, A1, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend\n{\n\ttypedef void (*FuncPtr)(A1);\n\toperator FuncPtr() { return (FuncPtr)GetCode(); }\n\tvoid InternalMain() {static_cast<Derived *>(this)->naked_main();}\n\tvoid naked_main() {\n\t\tusing namespace detail::calling_convention_cdecl;\n\t\tProlog();\n\t\tstatic_cast<Derived *>(this)->main(Arg<A1>(*this, ArgInfo1<void,A1>()));\n\t\tEpilog();\n\t}\n};\n\n// specialization for no arguments\ntemplate<class R, class Derived>\nstruct function_cdecl<R, Derived, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend\n{\n\ttypedef R (*FuncPtr)();\n\ttypedef detail::ResultT<R> Result;\t///< main function result type\n\ttypename detail::ResultTraits<R>::ResultPtr result_ptr;\n\toperator FuncPtr() { return (FuncPtr)GetCode(); }\n\tvoid InternalMain() {static_cast<Derived *>(this)->naked_main();}\n\tvoid naked_main() {\n\t\tProlog();\n\t\tdetail::ResultDest result_dst(*this, detail::calling_convention_cdecl::ResultInfo<R>());\n\t\tstatic_cast<Derived *>(this)->main().StoreResult(*this, result_dst);\n\t\tEpilog();\n\t}\n};\n\n// specialization for no arguments and no result\ntemplate<class Derived>\nstruct function_cdecl<void, Derived, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone, detail::ArgNone> : Frontend\n{\n\ttypedef void (*FuncPtr)();\n\toperator FuncPtr() { return (FuncPtr)GetCode(); }\n\tvoid InternalMain() {static_cast<Derived *>(this)->naked_main();}\n\tvoid naked_main() {\n\t\tProlog();\n\t\tstatic_cast<Derived *>(this)->main();\n\t\tEpilog();\n\t}\n};\n\n\n/// function\ntemplate<\n\tclass R,\n\tclass Derived,\n\tclass A1 = detail::ArgNone,\n\tclass A2 = detail::ArgNone,\n\tclass A3 = detail::ArgNone,\n\tclass A4 = detail::ArgNone,\n\tclass A5 = detail::ArgNone,\n\tclass A6 = detail::ArgNone,\n\tclass A7 = detail::ArgNone,\n\tclass A8 = detail::ArgNone,\n\tclass A9 = detail::ArgNone,\n\tclass A10 = detail::ArgNone>\nstruct function : function_cdecl<R, Derived, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10> {};\n\n}\t// namespace jitasm\n\n#if defined(_MSC_VER)\n#pragma warning( pop )\n#endif\n\n#endif\t// #ifndef JITASM_H\n"
  },
  {
    "path": "avs_core/filters/field.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include \"field.h\"\n#ifdef INTEL_INTRINSICS\n#include \"intel/resample_sse.h\"\n#else\n#include \"resample.h\"\n#endif\n#include <avs/minmax.h>\n#include \"../core/internal.h\"\n#include \"../convert/convert_helper.h\"\n#include <vector>\n\n\n/**** Factory methods ****/\n\nstatic AVSValue __cdecl Create_DoubleWeave(AVSValue args, void*, IScriptEnvironment* env);\nstatic AVSValue __cdecl Create_Weave(AVSValue args, void*, IScriptEnvironment* env);\nstatic AVSValue __cdecl Create_Pulldown(AVSValue args, void*, IScriptEnvironment* env);\nstatic AVSValue __cdecl Create_SwapFields(AVSValue args, void*, IScriptEnvironment* env);\nstatic AVSValue __cdecl Create_Bob(AVSValue args, void*, IScriptEnvironment* env);\n\n\n/********************************************************************\n***** Declare index of new filters for Avisynth's filter engine *****\n********************************************************************/\n\nextern const AVSFunction Field_filters[] = {\n  { \"ComplementParity\", BUILTIN_FUNC_PREFIX, \"c\", ComplementParity::Create },\n  { \"AssumeTFF\",        BUILTIN_FUNC_PREFIX, \"c\", AssumeParity::Create, (void*)true },\n  { \"AssumeBFF\",        BUILTIN_FUNC_PREFIX, \"c\", AssumeParity::Create, (void*)false },\n  { \"AssumeFieldBased\", BUILTIN_FUNC_PREFIX, \"c\", AssumeFieldBased::Create },\n  { \"AssumeFrameBased\", BUILTIN_FUNC_PREFIX, \"c\", AssumeFrameBased::Create },\n  { \"SeparateColumns\",  BUILTIN_FUNC_PREFIX, \"ci\", SeparateColumns::Create },\n  { \"WeaveColumns\",     BUILTIN_FUNC_PREFIX, \"ci\", WeaveColumns::Create },\n  { \"SeparateRows\",     BUILTIN_FUNC_PREFIX, \"ci\", SeparateRows::Create },\n  { \"WeaveRows\",        BUILTIN_FUNC_PREFIX, \"ci\", WeaveRows::Create },\n  { \"SeparateFields\",   BUILTIN_FUNC_PREFIX, \"c\", SeparateFields::Create },\n  { \"Weave\",            BUILTIN_FUNC_PREFIX, \"c\", Create_Weave },\n  { \"DoubleWeave\",      BUILTIN_FUNC_PREFIX, \"c\", Create_DoubleWeave },\n  { \"Pulldown\",         BUILTIN_FUNC_PREFIX, \"cii\", Create_Pulldown },\n  { \"SelectEvery\",      BUILTIN_FUNC_PREFIX, \"cii*\", SelectEvery::Create },\n  { \"SelectEven\",       BUILTIN_FUNC_PREFIX, \"c\", SelectEvery::Create_SelectEven },\n  { \"SelectOdd\",        BUILTIN_FUNC_PREFIX, \"c\", SelectEvery::Create_SelectOdd },\n  { \"Interleave\",       BUILTIN_FUNC_PREFIX, \"c+\", Interleave::Create },\n  { \"SwapFields\",       BUILTIN_FUNC_PREFIX, \"c\", Create_SwapFields },\n  { \"Bob\",              BUILTIN_FUNC_PREFIX, \"c[b]f[c]f[height]i\", Create_Bob },\n  { \"SelectRangeEvery\", BUILTIN_FUNC_PREFIX, \"c[every]i[length]i[offset]i[audio]b\", SelectRangeEvery::Create},\n  { NULL }\n};\n\n\n\n\n\n/*********************************\n *******   SeparateColumns  ******\n *********************************/\n\nSeparateColumns::SeparateColumns(PClip _child, int _interval, IScriptEnvironment* env)\n : GenericVideoFilter(_child), interval(_interval)\n{\n  if (_interval <= 0)\n    env->ThrowError(\"SeparateColumns: interval must be greater than zero.\");\n\n  if (_interval > vi.width)\n    env->ThrowError(\"SeparateColumns: interval must be less than or equal width.\");\n\n  if (vi.width % _interval)\n    env->ThrowError(\"SeparateColumns: width must be mod %d.\", _interval);\n\n  vi.width /= _interval;\n  vi.MulDivFPS(_interval, 1);\n  vi.num_frames *= _interval;\n\n  if (vi.num_frames < 0)\n    env->ThrowError(\"SeparateColumns: Maximum number of frames exceeded.\");\n\n\n  if (vi.IsYUY2() && vi.width & 1)\n    env->ThrowError(\"SeparateColumns: YUY2 output width must be even.\");\n  if (vi.Is420() && vi.width & 1)\n    env->ThrowError(\"SeparateColumns: YUV420 output width must be even.\");\n  if (vi.Is422() && vi.width & 1)\n    env->ThrowError(\"SeparateColumns: YUV422 output width must be even.\");\n  if (vi.IsYV411() && vi.width & 3)\n    env->ThrowError(\"SeparateColumns: YV411 output width must be mod 4.\");\n}\n\n\nPVideoFrame SeparateColumns::GetFrame(int n, IScriptEnvironment* env)\n{\n  const int m = n%interval;\n  const int f = n/interval;\n\n  PVideoFrame src = child->GetFrame(f, env);\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n\n  if (vi.IsPlanar()) {\n    int planes_y[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };\n    int planes_r[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A };\n    int *planes = (vi.IsYUV() || vi.IsYUVA()) ? planes_y : planes_r;\n    for (int p = 0; p < vi.NumComponents(); ++p) {\n      int plane = planes[p];\n      const int srcpitch = src->GetPitch(plane);\n      const int dstpitch = dst->GetPitch(plane);\n      const int height = dst->GetHeight(plane);\n      const int rowsize_pixels = dst->GetRowSize(plane) / vi.ComponentSize();\n\n      const BYTE* srcp = src->GetReadPtr(plane);\n      BYTE* dstp = dst->GetWritePtr(plane);\n\n      switch (vi.ComponentSize()) {\n      case 1:\n        for (int y = 0; y < height; y++) {\n          for (int i = m, j = 0; j < rowsize_pixels; i += interval, j += 1) {\n            dstp[j] = srcp[i];\n          }\n          srcp += srcpitch;\n          dstp += dstpitch;\n        }\n        break;\n      case 2:\n        for (int y = 0; y < height; y++) {\n          for (int i = m, j = 0; j < rowsize_pixels; i += interval, j += 1) {\n            reinterpret_cast<uint16_t *>(dstp)[j] = reinterpret_cast<const uint16_t *>(srcp)[i];\n          }\n          srcp += srcpitch;\n          dstp += dstpitch;\n        }\n        break;\n      case 4:\n        for (int y = 0; y < height; y++) {\n          for (int i = m, j = 0; j < rowsize_pixels; i += interval, j += 1) {\n            reinterpret_cast<float *>(dstp)[j] = reinterpret_cast<const float *>(srcp)[i];\n          }\n          srcp += srcpitch;\n          dstp += dstpitch;\n        }\n        break;\n      }\n    }\n  }\n  else if (vi.IsYUY2()) {\n    const int srcpitch = src->GetPitch();\n    const int dstpitch = dst->GetPitch();\n    const int height = dst->GetHeight();\n    const int rowsize = dst->GetRowSize();\n\n    const BYTE* srcp = src->GetReadPtr();\n    BYTE* dstp = dst->GetWritePtr();\n\n    const int m2 = m*2;\n    const int interval2 = interval*2;\n    const int interval4 = interval*4;\n\n    for (int y=0; y<height; y+=1) {\n      for (int i=m2, j=0; j<rowsize; i+=interval4, j+=4) {\n        // Luma\n        dstp[j+0] = srcp[i+0];\n        dstp[j+2] = srcp[i+interval2];\n        // Chroma\n        dstp[j+1] = srcp[i+m2+1];\n        dstp[j+3] = srcp[i+m2+3];\n      }\n      srcp += srcpitch;\n      dstp += dstpitch;\n    }\n  }\n  else if (vi.IsRGB24() || vi.IsRGB48()) {\n    const int srcpitch = src->GetPitch();\n    const int dstpitch = dst->GetPitch();\n    const int height = dst->GetHeight();\n    const int rowsize_pixels = dst->GetRowSize() / vi.ComponentSize();\n\n    const BYTE* srcp = src->GetReadPtr();\n    BYTE* dstp = dst->GetWritePtr();\n\n    const int m3 = m * 3;\n    const int interval3 = interval * 3;\n\n    if (vi.IsRGB24())\n    {\n      for (int y = 0; y < height; y += 1) {\n        for (int i = m3, j = 0; j < rowsize_pixels; i += interval3, j += 3) {\n          dstp[j + 0] = srcp[i + 0];\n          dstp[j + 1] = srcp[i + 1];\n          dstp[j + 2] = srcp[i + 2];\n        }\n        srcp += srcpitch;\n        dstp += dstpitch;\n      }\n    }\n    else {\n      // RGB48\n      for (int y = 0; y < height; y += 1) {\n        for (int i = m3, j = 0; j < rowsize_pixels; i += interval3, j += 3) {\n          reinterpret_cast<uint16_t *>(dstp)[j + 0] = reinterpret_cast<const uint16_t *>(srcp)[i + 0];\n          reinterpret_cast<uint16_t *>(dstp)[j + 1] = reinterpret_cast<const uint16_t *>(srcp)[i + 1];\n          reinterpret_cast<uint16_t *>(dstp)[j + 2] = reinterpret_cast<const uint16_t *>(srcp)[i + 2];\n        }\n        srcp += srcpitch;\n        dstp += dstpitch;\n      }\n    }\n  }\n  else if (vi.IsRGB32()) {\n    const int srcpitch4 = src->GetPitch()>>2;\n    const int dstpitch4 = dst->GetPitch()>>2;\n    const int height = dst->GetHeight();\n    const int rowsize4 = dst->GetRowSize()>>2;\n\n    const int* srcp4 = (const int*)src->GetReadPtr();\n    int* dstp4 = (int*)dst->GetWritePtr();\n\n    for (int y=0; y<height; y+=1) {\n      for (int i=m, j=0; j<rowsize4; i+=interval, j+=1) {\n        dstp4[j] = srcp4[i];\n      }\n      srcp4 += srcpitch4;\n      dstp4 += dstpitch4;\n    }\n  }\n  else if (vi.IsRGB64()) {\n    const int srcpitch8 = src->GetPitch()>>3;\n    const int dstpitch8 = dst->GetPitch()>>3;\n    const int height = dst->GetHeight();\n    const int rowsize8 = dst->GetRowSize()>>3;\n\n    const uint64_t* srcp8 = (const uint64_t*)src->GetReadPtr();\n    uint64_t* dstp8 = (uint64_t*)dst->GetWritePtr();\n\n    for (int y=0; y<height; y+=1) {\n      for (int i=m, j=0; j<rowsize8; i+=interval, j+=1) {\n        dstp8[j] = srcp8[i];\n      }\n      srcp8 += srcpitch8;\n      dstp8 += dstpitch8;\n    }\n  }\n  return dst;\n}\n\n\nAVSValue __cdecl SeparateColumns::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  if (args[1].AsInt() == 1)\n    return args[0];\n\n  return new SeparateColumns(args[0].AsClip(), args[1].AsInt(), env);\n}\n\n\n\n\n\n\n\n/*******************************\n *******   WeaveColumns   ******\n *******************************/\n\nWeaveColumns::WeaveColumns(PClip _child, int _period, IScriptEnvironment* env)\n : GenericVideoFilter(_child), period(_period), inframes(vi.num_frames)\n{\n  if (_period <= 0)\n    env->ThrowError(\"WeaveColumns: period must be greater than zero.\");\n\n  vi.width *= _period;\n  vi.MulDivFPS(1, _period);\n  vi.num_frames += _period-1; // Ceil!\n  vi.num_frames /= _period;\n}\n\n\nPVideoFrame WeaveColumns::GetFrame(int n, IScriptEnvironment* env)\n{\n  const int b = n * period;\n\n  PVideoFrame dst = env->NewVideoFrame(vi);\n\n  for (int m=0; m<period; m++) {\n    const int f = b+m < inframes ? b+m : inframes-1;\n    PVideoFrame src = child->GetFrame(f, env);\n    if(0 == m)\n     env->copyFrameProps(src, dst);\n\n    if (vi.IsPlanar()) {\n      int planes_y[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };\n      int planes_r[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A };\n      int *planes = (vi.IsYUV() || vi.IsYUVA()) ? planes_y : planes_r;\n      for (int p = 0; p < vi.NumComponents(); ++p) {\n        int plane = planes[p];\n        BYTE *_dstp = dst->GetWritePtr(plane);\n        const int srcpitch = src->GetPitch(plane);\n        const int dstpitch = dst->GetPitch(plane);\n        const int height = src->GetHeight(plane);\n        const int rowsize_pixels = src->GetRowSize(plane) / vi.ComponentSize();\n\n        const BYTE* srcp = src->GetReadPtr(plane);\n        BYTE* dstp = _dstp;\n        switch (vi.ComponentSize()) {\n        case 1:\n          for (int y = 0; y < height; y++) {\n            for (int i = m, j = 0; j < rowsize_pixels; i += period, j += 1) {\n              dstp[i] = srcp[j];\n            }\n            srcp += srcpitch;\n            dstp += dstpitch;\n          }\n          break;\n        case 2:\n          for (int y = 0; y < height; y++) {\n            for (int i = m, j = 0; j < rowsize_pixels; i += period, j += 1) {\n              reinterpret_cast<uint16_t *>(dstp)[i] = reinterpret_cast<const uint16_t *>(srcp)[j];\n            }\n            srcp += srcpitch;\n            dstp += dstpitch;\n          }\n          break;\n        case 4:\n          for (int y = 0; y < height; y++) {\n            for (int i = m, j = 0; j < rowsize_pixels; i += period, j += 1) {\n              reinterpret_cast<float *>(dstp)[i] = reinterpret_cast<const float *>(srcp)[j];\n            }\n            srcp += srcpitch;\n            dstp += dstpitch;\n          }\n          break;\n        }\n      }\n    }\n    else if (vi.IsYUY2()) {\n      BYTE *_dstp = dst->GetWritePtr();\n      const int dstpitch = dst->GetPitch();\n\n      const int srcpitch = src->GetPitch();\n      const int height = src->GetHeight();\n      const int rowsize = src->GetRowSize();\n      const BYTE* srcp = src->GetReadPtr();\n      BYTE* dstp = _dstp;\n      const int m2 = m*2;\n      const int period2 = period*2;\n      const int period4 = period*4;\n\n      for (int y=0; y<height; y+=1) {\n        for (int i=m2, j=0; j<rowsize; i+=period4, j+=4) {\n          // Luma\n          dstp[i+0]       = srcp[j+0];\n          dstp[i+period2] = srcp[j+2];\n          // Chroma\n          dstp[i+m2+1]    = srcp[j+1];\n          dstp[i+m2+3]    = srcp[j+3];\n        }\n        srcp += srcpitch;\n        dstp += dstpitch;\n      }\n    }\n    else if (vi.IsRGB24() || vi.IsRGB48()) {\n      BYTE *_dstp = dst->GetWritePtr();\n      const int dstpitch = dst->GetPitch();\n\n      const int srcpitch = src->GetPitch();\n      const int height = src->GetHeight();\n      const int rowsize_pixels = src->GetRowSize() / vi.ComponentSize();\n      const BYTE* srcp = src->GetReadPtr();\n      BYTE* dstp = _dstp;\n      const int m3 = m*3;\n      const int period3 = period*3;\n      if (vi.IsRGB24()) {\n        for (int y = 0; y < height; y += 1) {\n          for (int i = m3, j = 0; j < rowsize_pixels; i += period3, j += 3) {\n            dstp[i + 0] = srcp[j + 0];\n            dstp[i + 1] = srcp[j + 1];\n            dstp[i + 2] = srcp[j + 2];\n          }\n          srcp += srcpitch;\n          dstp += dstpitch;\n        }\n      }\n      else {\n        // RGB48\n        for (int y = 0; y < height; y += 1) {\n          for (int i = m3, j = 0; j < rowsize_pixels; i += period3, j += 3) {\n            reinterpret_cast<uint16_t *>(dstp)[i + 0] = reinterpret_cast<const uint16_t *>(srcp)[j + 0];\n            reinterpret_cast<uint16_t *>(dstp)[i + 1] = reinterpret_cast<const uint16_t *>(srcp)[j + 1];\n            reinterpret_cast<uint16_t *>(dstp)[i + 2] = reinterpret_cast<const uint16_t *>(srcp)[j + 2];\n          }\n          srcp += srcpitch;\n          dstp += dstpitch;\n        }\n      }\n    }\n    else if (vi.IsRGB32()) {\n      BYTE *_dstp = dst->GetWritePtr();\n      const int dstpitch = dst->GetPitch();\n\n      const int srcpitch4 = src->GetPitch()>>2;\n      const int dstpitch4 = dstpitch>>2;\n      const int height = src->GetHeight();\n      const int rowsize4 = src->GetRowSize()>>2;\n      const int* srcp4 = (const int*)src->GetReadPtr();\n      int* dstp4 = (int*)_dstp;\n\n      for (int y=0; y<height; y+=1) {\n        for (int i=m, j=0; j<rowsize4; i+=period, j+=1) {\n          dstp4[i] = srcp4[j];\n        }\n        srcp4 += srcpitch4;\n        dstp4 += dstpitch4;\n      }\n    }\n    else if (vi.IsRGB64()) {\n      BYTE *_dstp = dst->GetWritePtr();\n      const int dstpitch = dst->GetPitch();\n\n      const int srcpitch8 = src->GetPitch()>>3;\n      const int dstpitch8 = dstpitch>>3;\n      const int height = src->GetHeight();\n      const int rowsize8 = src->GetRowSize()>>3;\n      const uint64_t* srcp8 = (const uint64_t*)src->GetReadPtr();\n      uint64_t* dstp8 = (uint64_t*)_dstp;\n\n      for (int y=0; y<height; y+=1) {\n        for (int i=m, j=0; j<rowsize8; i+=period, j+=1) {\n          dstp8[i] = srcp8[j];\n        }\n        srcp8 += srcpitch8;\n        dstp8 += dstpitch8;\n      }\n    }\n  }\n  return dst;\n}\n\n\nAVSValue __cdecl WeaveColumns::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  if (args[1].AsInt() == 1)\n    return args[0];\n\n  return new WeaveColumns(args[0].AsClip(), args[1].AsInt(), env);\n}\n\n\n\n\n\n\n\n/*********************************\n *******   SeparateRows   ******\n *********************************/\n\nSeparateRows::SeparateRows(PClip _child, int _interval, IScriptEnvironment* env)\n : NonCachedGenericVideoFilter(_child), interval(_interval)\n{\n  if (_interval <= 0)\n    env->ThrowError(\"SeparateRows: interval must be greater than zero.\");\n\n  if (_interval > vi.height)\n    env->ThrowError(\"SeparateRows: interval must be less than or equal height.\");\n\n  if (vi.height % _interval)\n    env->ThrowError(\"SeparateRows: height must be mod %d.\", _interval);\n\n  vi.height /= _interval;\n  vi.MulDivFPS(_interval, 1);\n  vi.num_frames *= _interval;\n\n  if (vi.num_frames < 0)\n    env->ThrowError(\"SeparateRows: Maximum number of frames exceeded.\");\n\n  if (vi.Is420() && vi.height & 1)\n    env->ThrowError(\"SeparateRows: YUV420 output height must be even.\");\n}\n\n\nPVideoFrame SeparateRows::GetFrame(int n, IScriptEnvironment* env)\n{\n  const int m = (vi.IsRGB() && !vi.IsPlanar())? interval-1 - n%interval : n%interval; // RGB upside-down\n  const int f = n/interval;\n\n  PVideoFrame frame = child->GetFrame(f, env);\n\n  if (vi.IsPlanar() && !vi.IsY()) {\n    int plane0 = vi.IsRGB() ? PLANAR_G : PLANAR_Y;\n    int plane1 = vi.IsRGB() ? PLANAR_B : PLANAR_U;\n    const int Ypitch   = frame->GetPitch(plane0);\n    const int UVpitch  = frame->GetPitch(plane1);\n    const int Yoffset  = Ypitch  * m;\n    const int UVoffset = UVpitch * m;\n\n    if (vi.NumComponents() == 4) {\n      int Aoffset = frame->GetPitch(PLANAR_A) * m;\n\n      return env->SubframePlanarA(frame, Yoffset, Ypitch * interval,\n        frame->GetRowSize(plane0), vi.height,\n        UVoffset, UVoffset, UVpitch * interval, Aoffset);\n    }\n    else {\n      return env->SubframePlanar(frame, Yoffset, Ypitch * interval,\n        frame->GetRowSize(plane0), vi.height,\n        UVoffset, UVoffset, UVpitch * interval);\n    }\n  }\n  const int pitch = frame->GetPitch();\n  return env->Subframe(frame, pitch * m, pitch * interval, frame->GetRowSize(), vi.height);\n}\n\n\nAVSValue __cdecl SeparateRows::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  if (args[1].AsInt() == 1)\n    return args[0];\n\n  return new SeparateRows(args[0].AsClip(), args[1].AsInt(), env);\n}\n\n\n\n\n\n\n\n/****************************\n *******   WeaveRows   ******\n ****************************/\n\nWeaveRows::WeaveRows(PClip _child, int _period, IScriptEnvironment* env)\n : GenericVideoFilter(_child), period(_period), inframes(vi.num_frames)\n{\n  if (_period <= 0)\n    env->ThrowError(\"WeaveRows: period must be greater than zero.\");\n\n  vi.height *= _period;\n  vi.MulDivFPS(1, _period);\n  vi.num_frames += _period-1; // Ceil!\n  vi.num_frames /= _period;\n}\n\n\nPVideoFrame WeaveRows::GetFrame(int n, IScriptEnvironment* env)\n{\n  const int b = n * period;\n  const int e = b + period;\n\n  PVideoFrame dst = env->NewVideoFrame(vi);\n  BYTE *dstp = dst->GetWritePtr();\n  const int dstpitch = dst->GetPitch();\n\n  if (vi.IsRGB() && !vi.IsPlanar()) { // RGB upsidedown\n    dstp += dstpitch * period;\n    for (int i=b; i<e; i++) {\n      dstp -= dstpitch;\n      const int j = i < inframes ? i : inframes-1;\n      PVideoFrame src = child->GetFrame(j, env);\n      if(i==b) // very first\n        env->copyFrameProps(src, dst);\n\n      env->BitBlt( dstp,              dstpitch * period,\n              src->GetReadPtr(), src->GetPitch(),\n              src->GetRowSize(), src->GetHeight() );\n    }\n  }\n  else {\n    int planes_y[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };\n    int planes_r[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A };\n    int *planes = (vi.IsYUV() || vi.IsYUVA()) ? planes_y : planes_r;\n    bool isYUY2 = vi.IsYUY2();\n    int dstpitch[4];\n    BYTE *dstp[4];\n    for (int p = 0; p < (isYUY2 ? 1 : vi.NumComponents()); ++p) {\n      int plane = planes[p];\n      dstpitch[p] = dst->GetPitch(plane);\n      dstp[p] = dst->GetWritePtr(plane);\n    }\n\n    for (int i=b; i<e; i++) {\n      const int j = i < inframes ? i : inframes-1;\n      PVideoFrame src = child->GetFrame(j, env);\n      if (i == b)  // very first\n        env->copyFrameProps(src, dst);\n      for (int p = 0; p < (isYUY2 ? 1 : vi.NumComponents()); ++p) {\n        int plane = planes[p];\n        env->BitBlt(dstp[p], dstpitch[p] * period,\n          src->GetReadPtr(plane), src->GetPitch(plane),\n          src->GetRowSize(plane), src->GetHeight(plane) );\n        dstp[p] += dstpitch[p];\n      }\n    }\n  }\n  return dst;\n}\n\n\nAVSValue __cdecl WeaveRows::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  if (args[1].AsInt() == 1)\n    return args[0];\n\n  return new WeaveRows(args[0].AsClip(), args[1].AsInt(), env);\n}\n\n\n\n\n\n\n\n/*********************************\n *******   SeparateFields   ******\n *********************************/\n\nSeparateFields::SeparateFields(PClip _child, IScriptEnvironment* env)\n : NonCachedGenericVideoFilter(_child)\n{\n  if (vi.height & 1)\n    env->ThrowError(\"SeparateFields: height must be even\");\n  if (vi.Is420() && vi.height & 3)\n    env->ThrowError(\"SeparateFields: YUV420 height must be multiple of 4\");\n  vi.height >>= 1;\n  vi.MulDivFPS(2, 1);\n  vi.num_frames *= 2;\n\n  if (vi.num_frames < 0)\n    env->ThrowError(\"SeparateFields: Maximum number of frames exceeded.\");\n\n  vi.SetFieldBased(true);\n}\n\n\nPVideoFrame SeparateFields::GetFrame(int n, IScriptEnvironment* env)\n{\n#ifdef CACHE_GROWTH_INFINITELY_TEST\n  // FIXME: debug for Issue #270\n  // See other occurencies of this define\n  // When filter is combined with non-SeparateFielded frames\n  // the cache can grow infinitely, behaves like a memory leak.\n  // Tried putting n or (n-1) or (n*2) instead of n >> 1 then the problem does not occur.\n  _RPT2(0, \"SeparateFields::GetFrame before %d, >>1: %d\\n\", n, n >> 1);\n#endif\n  PVideoFrame frame = child->GetFrame(n>>1, env);\n#ifdef CACHE_GROWTH_INFINITELY_TEST\n  _RPT2(0, \"SeparateFields::GetFrame after %d, >>1: %d\\n\", n, n >> 1);\n#endif\n  if (vi.IsPlanar()) {\n    const bool topfield = GetParity(n);\n\n    int plane0 = vi.IsRGB() ? PLANAR_G : PLANAR_Y;\n    int plane1 = vi.IsRGB() ? PLANAR_B : PLANAR_U;\n    const int Ypitch   = frame->GetPitch(plane0);\n    const int UVpitch  = frame->GetPitch(plane1);\n    const int UVoffset = !topfield ? UVpitch : 0;\n    const int Yoffset = !topfield ? Ypitch : 0;\n\n    if (vi.NumComponents() == 4) {\n      int Aoffset = !topfield ? frame->GetPitch(PLANAR_A) : 0;\n\n      return env->SubframePlanarA(frame, Yoffset, frame->GetPitch() * 2, frame->GetRowSize(), frame->GetHeight() >> 1,\n        UVoffset, UVoffset, frame->GetPitch(PLANAR_U) * 2, Aoffset);\n    }\n    else {\n      return env->SubframePlanar(frame, Yoffset, frame->GetPitch() * 2, frame->GetRowSize(), frame->GetHeight() >> 1,\n        UVoffset, UVoffset, frame->GetPitch(PLANAR_U) * 2);\n    }\n  }\n  return env->Subframe(frame,(GetParity(n) ^ vi.IsYUY2()) ? frame->GetPitch() : 0,\n                         frame->GetPitch()*2, frame->GetRowSize(), frame->GetHeight()>>1);\n}\n\n\nAVSValue __cdecl SeparateFields::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  PClip clip = args[0].AsClip();\n  if (clip->GetVideoInfo().IsFieldBased())\n    env->ThrowError(\"SeparateFields: SeparateFields should be applied on frame-based material: use AssumeFrameBased() beforehand\");\n\n  return new SeparateFields(clip, env);\n}\n\n\n\n\n\n\n\n/******************************\n *******   Interleave   *******\n ******************************/\n\nInterleave::Interleave(const std::vector<PClip>&& _child_array, IScriptEnvironment* env)\n  : num_children((int)_child_array.size()), child_array(std::move(_child_array))\n{\n  vi = child_array[0]->GetVideoInfo();\n  vi.MulDivFPS(num_children, 1);\n  vi.num_frames = (vi.num_frames - 1) * num_children + 1;\n  child_devs = GetDeviceTypes(child_array[0]);\n  for (int i=1; i<num_children; ++i)\n  {\n    const VideoInfo& vi2 = child_array[i]->GetVideoInfo();\n    if (vi.width != vi2.width || vi.height != vi2.height)\n      env->ThrowError(\"Interleave: videos must be of the same size.\");\n    if (!vi.IsSameColorspace(vi2))\n      env->ThrowError(\"Interleave: video formats don't match\");\n\n    vi.num_frames = max(vi.num_frames, (vi2.num_frames - 1) * num_children + i + 1);\n\n    child_devs &= GetDeviceTypes(child_array[i]);\n    if (child_devs == 0)\n      env->ThrowError(\"Interleave: device types don't match\");\n  }\n  if (vi.num_frames < 0)\n    env->ThrowError(\"Interleave: Maximum number of frames exceeded.\");\n\n}\n\nint __stdcall Interleave::SetCacheHints(int cachehints,int frame_range)\n{\n  AVS_UNUSED(frame_range);\n  switch (cachehints)\n  {\n  case CACHE_DONT_CACHE_ME:\n    return 1;\n  case CACHE_GET_MTMODE:\n    return MT_NICE_FILTER;\n  case CACHE_GET_DEV_TYPE:\n    return child_devs;\n  default:\n    return 0;\n  }\n}\n\nAVSValue __cdecl Interleave::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  args = args[0];\n  const int num_args = args.ArraySize();\n  if (num_args == 1)\n    return args[0];\n\n  std::vector<PClip> children(num_args);\n\n  for (int i = 0; i < (int)children.size(); ++i)\n    children[i] = args[i].AsClip();\n\n  return new Interleave(std::move(children), env);\n}\n\n\n\n\n\n\n/*********************************\n ********   SelectEvery    *******\n *********************************/\n\n\nSelectEvery::SelectEvery(PClip _child, int _every, int _from, IScriptEnvironment* env)\n: NonCachedGenericVideoFilter(_child), every(_every), from(_from)\n{\n  if (_every == 0)\n    env->ThrowError(\"Parameter 'every' of SelectEvery cannot be zero.\");\n\n  vi.MulDivFPS(1, every);\n  vi.num_frames = (vi.num_frames-1-from) / every + 1;\n}\n\n\nAVSValue __cdecl SelectEvery::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  const int num_vals = args[2].ArraySize();\n  if (num_vals <= 1)\n  return new SelectEvery(args[0].AsClip(), args[1].AsInt(), num_vals>0 ? args[2][0].AsInt() : 0, env);\n  else {\n    std::vector<PClip> children(num_vals);\n\n    for (int i = 0; i < (int)children.size(); ++i)\n      children[i] = new SelectEvery(args[0].AsClip(), args[1].AsInt(), args[2][i].AsInt(), env);\n\n    return new Interleave(std::move(children), env);\n  }\n}\n\n\n\n\n\n\n\n\n/**************************************\n ********   DoubleWeaveFields   *******\n *************************************/\n\nDoubleWeaveFields::DoubleWeaveFields(PClip _child)\n  : GenericVideoFilter(_child)\n{\n  vi.height *= 2;\n  vi.SetFieldBased(false);\n}\n\n\nvoid copy_field(const PVideoFrame& dst, const PVideoFrame& src, bool yuv, bool planarRGB, bool parity, IScriptEnvironment* env)\n{\n  bool noTopBottom = yuv || planarRGB;\n\n  int plane1 = planarRGB ? PLANAR_B : PLANAR_U;\n  int plane2 = planarRGB ? PLANAR_R : PLANAR_V;\n\n  const int add_pitch = dst->GetPitch() * (parity ^ noTopBottom);\n  const int add_pitchUV = dst->GetPitch(plane1) * (parity ^ noTopBottom);\n  const int add_pitchA = dst->GetPitch(PLANAR_A) * (parity ^ noTopBottom);\n\n  env->BitBlt(dst->GetWritePtr()         + add_pitch, dst->GetPitch()*2,\n    src->GetReadPtr(), src->GetPitch(),\n    src->GetRowSize(), src->GetHeight());\n\n  env->BitBlt(dst->GetWritePtr(plane1) + add_pitchUV, dst->GetPitch(plane1)*2,\n    src->GetReadPtr(plane1), src->GetPitch(plane1),\n    src->GetRowSize(plane1), src->GetHeight(plane1));\n\n  env->BitBlt(dst->GetWritePtr(plane2) + add_pitchUV, dst->GetPitch(plane2)*2,\n    src->GetReadPtr(plane2), src->GetPitch(plane2),\n    src->GetRowSize(plane2), src->GetHeight(plane2));\n\n  env->BitBlt(dst->GetWritePtr(PLANAR_A) + add_pitchA, dst->GetPitch(PLANAR_A)*2,\n    src->GetReadPtr(PLANAR_A), src->GetPitch(PLANAR_A),\n    src->GetRowSize(PLANAR_A), src->GetHeight(PLANAR_A));\n}\n\n\nPVideoFrame DoubleWeaveFields::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame a = child->GetFrame(n, env);\n  PVideoFrame b = child->GetFrame(n+1, env);\n\n  PVideoFrame result = env->NewVideoFrameP(vi, &a);\n\n  const bool parity = child->GetParity(n);\n\n  copy_field(result, a, vi.IsYUV() || vi.IsYUVA(), vi.IsPlanarRGB() || vi.IsPlanarRGBA(), parity, env);\n  copy_field(result, b, vi.IsYUV() || vi.IsYUVA(), vi.IsPlanarRGB() || vi.IsPlanarRGBA(), !parity, env);\n\n  return result;\n}\n\n\n\n/**************************************\n ********   DoubleWeaveFrames   *******\n *************************************/\n\nDoubleWeaveFrames::DoubleWeaveFrames(PClip _child)\n  : GenericVideoFilter(_child)\n{\n  vi.num_frames *= 2;\n  if (vi.num_frames < 0)\n    vi.num_frames = 0x7FFFFFFF; // MAXINT\n\n  vi.MulDivFPS(2, 1);\n}\n\nvoid copy_alternate_lines(const PVideoFrame& dst, const PVideoFrame& src, bool yuv, bool planarRGB, bool parity, IScriptEnvironment* env)\n{\n  bool noTopBottom = yuv || planarRGB;\n\n  int plane1 = planarRGB ? PLANAR_B : PLANAR_U;\n  int plane2 = planarRGB ? PLANAR_R : PLANAR_V;\n\n  const int src_add_pitch = src->GetPitch()         * (parity ^ noTopBottom);\n  const int src_add_pitchUV = src->GetPitch(plane1) * (parity ^ noTopBottom);\n  const int src_add_pitchA = src->GetPitch(PLANAR_A) * (parity ^ noTopBottom);\n\n  const int dst_add_pitch = dst->GetPitch()         * (parity ^ noTopBottom);\n  const int dst_add_pitchUV = dst->GetPitch(plane1) * (parity ^ noTopBottom);\n  const int dst_add_pitchA = dst->GetPitch(PLANAR_A) * (parity ^ noTopBottom);\n\n  env->BitBlt(dst->GetWritePtr()         + dst_add_pitch, dst->GetPitch()*2,\n    src->GetReadPtr()          + src_add_pitch, src->GetPitch()*2,\n    src->GetRowSize(), src->GetHeight()>>1);\n\n  env->BitBlt(dst->GetWritePtr(plane1) + dst_add_pitchUV, dst->GetPitch(plane1)*2,\n    src->GetReadPtr(plane1)  + src_add_pitchUV, src->GetPitch(plane1)*2,\n    src->GetRowSize(plane1), src->GetHeight(plane1)>>1);\n\n  env->BitBlt(dst->GetWritePtr(plane2) + dst_add_pitchUV, dst->GetPitch(plane2)*2,\n    src->GetReadPtr(plane2)  + src_add_pitchUV, src->GetPitch(plane2)*2,\n    src->GetRowSize(plane2), src->GetHeight(plane2)>>1);\n\n  env->BitBlt(dst->GetWritePtr(PLANAR_A) + dst_add_pitchA, dst->GetPitch(PLANAR_A)*2,\n    src->GetReadPtr(PLANAR_A)  + src_add_pitchA, src->GetPitch(PLANAR_A)*2,\n    src->GetRowSize(PLANAR_A), src->GetHeight(PLANAR_A)>>1);\n}\n\n\nPVideoFrame DoubleWeaveFrames::GetFrame(int n, IScriptEnvironment* env)\n{\n  if (!(n&1))\n  {\n    return child->GetFrame(n>>1, env);\n  }\n  else {\n    PVideoFrame a = child->GetFrame(n>>1, env);\n    PVideoFrame b = child->GetFrame((n+1)>>1, env);\n    bool parity = this->GetParity(n);\n\n    if (a->IsWritable()) {\n      copy_alternate_lines(a, b,  vi.IsYUV() || vi.IsYUVA(), vi.IsPlanarRGB() || vi.IsPlanarRGBA(), !parity, env);\n      return a;\n    }\n    else if (b->IsWritable()) {\n      copy_alternate_lines(b, a,  vi.IsYUV() || vi.IsYUVA(), vi.IsPlanarRGB() || vi.IsPlanarRGBA(), parity, env);\n      return b;\n    }\n    else {\n      PVideoFrame result = env->NewVideoFrameP(vi, &a);\n      copy_alternate_lines(result, a, vi.IsYUV() || vi.IsYUVA(), vi.IsPlanarRGB() || vi.IsPlanarRGBA(), parity, env);\n      copy_alternate_lines(result, b, vi.IsYUV() || vi.IsYUVA(), vi.IsPlanarRGB() || vi.IsPlanarRGBA(), !parity, env);\n      return result;\n    }\n  }\n}\n\n\n\n\n\n/*******************************\n ********   Bob Filter   *******\n *******************************/\n\nFieldwise::Fieldwise(PClip _child1, PClip _child2)\n: NonCachedGenericVideoFilter(_child1), child2(_child2)\n  { vi.SetFieldBased(false); } // Make FrameBased, leave IT_BFF and IT_TFF alone\n\n\nPVideoFrame __stdcall Fieldwise::GetFrame(int n, IScriptEnvironment* env)\n{\n  return (child->GetParity(n) ? child2 : child)->GetFrame(n, env);\n}\n\n\nbool __stdcall Fieldwise::GetParity(int n)\n{\n  return child->GetParity(n) ^ (n&1); // ^ = XOR\n}\n\n\n\n\n\n\n\n/************************************\n ********   Factory Methods   *******\n ***********************************/\n\nstatic AVSValue __cdecl Create_DoubleWeave(AVSValue args, void*, IScriptEnvironment* env)\n{\n  AVS_UNUSED(env);\n  PClip clip = args[0].AsClip();\n  if (clip->GetVideoInfo().IsFieldBased())\n    return new DoubleWeaveFields(clip);\n  else\n    return new DoubleWeaveFrames(clip);\n}\n\n\nstatic AVSValue __cdecl Create_Weave(AVSValue args, void*, IScriptEnvironment* env)\n{\n  PClip clip = args[0].AsClip();\n  if (!clip->GetVideoInfo().IsFieldBased())\n    env->ThrowError(\"Weave: Weave should be applied on field-based material: use AssumeFieldBased() beforehand\");\n  return new SelectEvery(Create_DoubleWeave(args, 0, env).AsClip(), 2, 0, env);\n}\n\n\nstatic AVSValue __cdecl Create_Pulldown(AVSValue args, void*, IScriptEnvironment* env)\n{\n  PClip clip = args[0].AsClip();\n  std::vector<PClip> children(2);\n  children[0] = new SelectEvery(clip, 5, args[1].AsInt() % 5, env);\n  children[1] = new SelectEvery(clip, 5, args[2].AsInt() % 5, env);\n  return new AssumeFrameBased(new Interleave(std::move(children), env));\n}\n\n\nstatic AVSValue __cdecl Create_SwapFields(AVSValue args, void*, IScriptEnvironment* env)\n{\n  return new SelectEvery(new DoubleWeaveFields(new ComplementParity(\n    new SeparateFields(args[0].AsClip(), env))), 2, 0, env);\n}\n\n\nstatic AVSValue __cdecl Create_Bob(AVSValue args, void*, IScriptEnvironment* env)\n{\n  PClip clip = args[0].AsClip();\n  if (!clip->GetVideoInfo().IsFieldBased())\n    clip = new SeparateFields(clip, env);\n\n  const VideoInfo& vi = clip->GetVideoInfo();\n\n  bool preserve_center = true; // default Avisynth\n  int chroma_placement = ChromaLocation_e::AVS_CHROMA_UNUSED; // default\n\n  const double b = args[1].AsDblDef(1./3.);\n  const double c = args[2].AsDblDef(1./3.);\n  const int new_height = args[3].AsInt(vi.height*2);\n  MitchellNetravaliFilter filter(b, c);\n  return new Fieldwise(new FilteredResizeV(clip, -0.25, vi.height,\n                                           new_height, &filter, preserve_center, chroma_placement, env),\n                       new FilteredResizeV(clip, +0.25, vi.height,\n                                           new_height, &filter, preserve_center, chroma_placement, env));\n}\n\n\nSelectRangeEvery::SelectRangeEvery(PClip _child, int _every, int _length, int _offset, bool _audio, IScriptEnvironment* env)\n: NonCachedGenericVideoFilter(_child), audio(_audio), achild(_child)\n{\n  const int64_t num_audio_samples = vi.num_audio_samples;\n\n  AVSValue trimargs[3] = { _child, _offset, 0};\n  PClip c = env->Invoke(\"Trim\",AVSValue(trimargs,3)).AsClip();\n  child = c;\n  vi = c->GetVideoInfo();\n\n  every = clamp(_every,1,vi.num_frames);\n  length = clamp(_length,1,every);\n\n  const int n = vi.num_frames;\n  vi.num_frames = (n/every)*length+(n%every<length?n%every:length);\n\n  if (audio && vi.HasAudio()) {\n    vi.num_audio_samples = vi.AudioSamplesFromFrames(vi.num_frames);\n  } else {\n    vi.num_audio_samples = num_audio_samples; // Undo Trim's work!\n  }\n}\n\n\nPVideoFrame __stdcall SelectRangeEvery::GetFrame(int n, IScriptEnvironment* env)\n{\n  return child->GetFrame((n/length)*every+(n%length), env);\n}\n\n\nbool __stdcall SelectRangeEvery::GetParity(int n)\n{\n  return child->GetParity((n/length)*every+(n%length));\n}\n\n\nvoid __stdcall SelectRangeEvery::GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env)\n{\n  if (!audio) {\n  // Use original unTrim'd child\n    achild->GetAudio(buf, start, count, env);\n    return;\n  }\n\n  int64_t samples_filled = 0;\n  BYTE* samples = (BYTE*)buf;\n  const int bps = vi.BytesPerAudioSample();\n  int startframe = vi.FramesFromAudioSamples(start);\n  int64_t general_offset = start - vi.AudioSamplesFromFrames(startframe);  // General compensation for startframe rounding.\n\n  while (samples_filled < count) {\n    const int iteration = startframe / length;                    // Which iteration is this.\n    const int iteration_into = startframe % length;               // How far, in frames are we into this iteration.\n    const int iteration_left = length - iteration_into;           // How many frames is left of this iteration.\n\n    const int64_t iteration_left_samples = vi.AudioSamplesFromFrames(iteration_left);\n    // This is the number of samples we can get without either having to skip, or being finished.\n    const int64_t getsamples = min(iteration_left_samples, count-samples_filled);\n    const int64_t start_offset = vi.AudioSamplesFromFrames(iteration * every + iteration_into) + general_offset;\n\n    child->GetAudio(&samples[samples_filled*bps], start_offset, getsamples, env);\n    samples_filled += getsamples;\n    startframe = (iteration+1) * length;\n    general_offset = 0; // On the following loops, general offset should be 0, as we are either skipping.\n  }\n}\n\nAVSValue __cdecl SelectRangeEvery::Create(AVSValue args, void* user_data, IScriptEnvironment* env) {\n  AVS_UNUSED(user_data);\n  return new SelectRangeEvery(args[0].AsClip(), args[1].AsInt(1500), args[2].AsInt(50), args[3].AsInt(0), args[4].AsBool(true), env);\n}\n"
  },
  {
    "path": "avs_core/filters/field.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Field_H__\n#define __Field_H__\n\n#include <avisynth.h>\n#include \"../core/internal.h\"\n#include <vector>\n\n\n/**********************************************************************\n * Reverse Engineering GetParity\n * -----------------------------\n * Notes for self - and hopefully useful to others.\n *\n * AviSynth is capable of dealing with both progressive and interlaced\n * material. The main problem is, that it often doesn't know what it\n * recieves from source filters.\n *\n * The fieldbased property in VideoInfo is made to give guides to\n * AviSynth on what to expect - unfortunately it is not that easy.\n *\n * GetParity is made to distinguish TFF and BFF. When a given frame is\n * returning true, it means that this frame should be considered\n * top field.\n * So an interlaced image always returning true must be interpreted as\n * TFF.\n *\n * SeparateFields splits out Top and Bottom frames. It returns true on\n * GetParity for Top fields and false for Bottom fields.\n *\n **********************************************************************/\n\n\nclass ComplementParity : public NonCachedGenericVideoFilter\n  /**\n    * Class to switch field precedence\n    **/\n{\npublic:\n  ComplementParity(PClip _child) : NonCachedGenericVideoFilter(_child) {\n    if (vi.IsBFF() && !vi.IsTFF()) {\n      vi.Clear(VideoInfo::IT_BFF);\n      vi.Set(VideoInfo::IT_TFF);\n    } else if (!vi.IsBFF() && vi.IsTFF()) {\n      vi.Set(VideoInfo::IT_BFF);\n      vi.Clear(VideoInfo::IT_TFF);\n    }\n    //  else both were set (illegal state) or both were unset (parity unknown)\n  }\n\n  inline bool __stdcall GetParity(int n) {\n    return !child->GetParity(n);\n  }\n\n  inline static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env) {\n    AVS_UNUSED(env);\n    return new ComplementParity(args[0].AsClip());\n  }\n\n};\n\n\nclass AssumeParity : public NonCachedGenericVideoFilter\n  /**\n    * Class to assume field precedence, AssumeTFF() & AssumeBFF()\n    **/\n{\npublic:\n  AssumeParity(PClip _child, bool _parity) : NonCachedGenericVideoFilter(_child), parity(_parity) {\n    if (parity) {\n      vi.Clear(VideoInfo::IT_BFF);\n      vi.Set(VideoInfo::IT_TFF);\n    } else {\n      vi.Set(VideoInfo::IT_BFF);\n      vi.Clear(VideoInfo::IT_TFF);\n    }\n  }\n\n  inline bool __stdcall GetParity(int n) {\n    return parity ^ (vi.IsFieldBased() && (n & 1));\n  }\n\n  inline static AVSValue __cdecl Create(AVSValue args, void* user_data, IScriptEnvironment* env) {\n    AVS_UNUSED(env);\n    return new AssumeParity(args[0].AsClip(), user_data!=0);\n  }\n\nprivate:\n  bool parity;\n};\n\nclass AssumeFieldBased : public NonCachedGenericVideoFilter\n  /**\n    * Class to assume field-based video\n    **/\n{\npublic:\n  AssumeFieldBased(PClip _child) : NonCachedGenericVideoFilter(_child)\n  {\n    vi.SetFieldBased(true); vi.Clear(VideoInfo::IT_BFF); vi.Clear(VideoInfo::IT_TFF);\n  }\n\n  inline bool __stdcall GetParity(int n) {\n    return n&1;\n  }\n\n  inline static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env) {\n    AVS_UNUSED(env);\n    return new AssumeFieldBased(args[0].AsClip());\n  }\n\n};\n\n\nclass AssumeFrameBased : public NonCachedGenericVideoFilter\n  /**\n    * Class to assume frame-based video\n    **/\n{\npublic:\n  AssumeFrameBased(PClip _child) : NonCachedGenericVideoFilter(_child)\n  {\n    vi.SetFieldBased(false); vi.Clear(VideoInfo::IT_BFF); vi.Clear(VideoInfo::IT_TFF);\n  }\n\n  inline bool __stdcall GetParity(int n) {\n    AVS_UNUSED(n);\n    return false;\n  }\n\n  inline static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env) {\n    AVS_UNUSED(env);\n    return new AssumeFrameBased(args[0].AsClip());\n  }\n};\n\n\nclass SeparateColumns : public GenericVideoFilter\n  /**\n    * Class to separate columns of video\n    **/\n{\nprivate:\n  const int interval;\n\npublic:\n  SeparateColumns(PClip _child, int _interval, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  inline bool __stdcall GetParity(int n) override {\n    return child->GetParity(n/interval);\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n};\n\n\nclass WeaveColumns : public GenericVideoFilter\n  /**\n    * Class to weave columns of video\n    **/\n{\nprivate:\n  const int period;\n  const int inframes;\n\npublic:\n  WeaveColumns(PClip _child, int _period, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  inline bool __stdcall GetParity(int n) override {\n    return child->GetParity(n*period);\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n};\n\n\nclass SeparateRows : public NonCachedGenericVideoFilter\n  /**\n    * Class to separate lines of video\n    **/\n{\nprivate:\n  const int interval;\n\npublic:\n  SeparateRows(PClip _child, int _interval, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n\n  inline bool __stdcall GetParity(int n) {\n    return child->GetParity(n/interval);\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n};\n\n\nclass WeaveRows : public GenericVideoFilter\n  /**\n    * Class to weave lines of video\n    **/\n{\nprivate:\n  const int period;\n  const int inframes;\n\npublic:\n  WeaveRows(PClip _child, int _period, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  inline bool __stdcall GetParity(int n) override{\n    return child->GetParity(n*period);\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n};\n\n\nclass SeparateFields : public NonCachedGenericVideoFilter\n  /**\n    * Class to separate fields of interlaced video\n    **/\n{\npublic:\n  SeparateFields(PClip _child, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n\n  inline bool __stdcall GetParity(int n) {\n    return child->GetParity(n>>1) ^ (n&1);\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n};\n\n\nclass DoubleWeaveFields : public GenericVideoFilter\n  /**\n    * Class to weave fields into an equal number of frames\n    **/\n{\npublic:\n  DoubleWeaveFields(PClip _child);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n};\n\n\nclass DoubleWeaveFrames : public GenericVideoFilter\n  /**\n    * Class to double-weave frames\n    **/\n{\npublic:\n  DoubleWeaveFrames(PClip _child);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  inline bool __stdcall GetParity(int n) override {\n    return child->GetParity(n>>1) ^ (n&1);\n  }\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n};\n\ninline int congmod(int a, int b) {\t// congruent modulus\n  return ((a % b) + b) % b;\n}\n\nclass Interleave : public IClip\n  /**\n    * Class to interleave several clips frame-by-frame\n    **/\n{\npublic:\n  Interleave(const std::vector<PClip>&& _child_array, IScriptEnvironment* env);\n\n  const VideoInfo& __stdcall GetVideoInfo() override {\n    return vi;\n  }\n\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override {\n  return child_array[congmod(n, num_children)]->GetFrame(n / num_children, env);\n  }\n\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) override {\n    child_array[0]->GetAudio(buf, start, count, env);\n  }\n\n  bool __stdcall GetParity(int n) override {\n    return child_array[n % num_children]->GetParity(n / num_children);\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override;\n\nprivate:\n  const int num_children;\n  std::vector<PClip> child_array;\n  VideoInfo vi;\n  int child_devs;\n};\n\n\nclass SelectEvery : public NonCachedGenericVideoFilter\n  /**\n    * Class to perform generalized pulldown (patterned frame removal)\n    **/\n{\npublic:\n  SelectEvery(PClip _child, int _every, int _from, IScriptEnvironment* env);\n\n  inline PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) {\n    return child->GetFrame(n*every+from, env);\n  }\n\n  inline bool __stdcall GetParity(int n) {\n    return child->GetParity(n*every+from);\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\n  inline static AVSValue __cdecl Create_SelectEven(AVSValue args, void*, IScriptEnvironment* env) {\n    return new SelectEvery(args[0].AsClip(), 2, 0, env);\n  }\n\n  inline static AVSValue __cdecl Create_SelectOdd(AVSValue args, void*, IScriptEnvironment* env) {\n    return new SelectEvery(args[0].AsClip(), 2, 1, env);\n  }\n\nprivate:\n  const int every, from;\n};\n\n\n\nclass Fieldwise : public NonCachedGenericVideoFilter\n/**\n  * Helper class for Bob filter\n **/\n{\npublic:\n  Fieldwise(PClip _child1, PClip _child2);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n  bool __stdcall GetParity(int n);\n\nprivate:\n  PClip child2;\n};\n\nclass SelectRangeEvery : public NonCachedGenericVideoFilter {\n  int every, length;\n  bool audio;\n  PClip achild;\npublic:\n  SelectRangeEvery(PClip _child, int _every, int _length, int _offset, bool _audio, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n  bool __stdcall GetParity(int n);\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env);\n\n};\n\n\n#endif  // __Field_H__\n"
  },
  {
    "path": "avs_core/filters/focus.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include \"focus.h\"\n#ifdef INTEL_INTRINSICS\n#include \"intel/focus_sse.h\"\n#include \"intel/focus_avx2.h\"\n#endif\n#include <cmath>\n#include <vector>\n#include <avs/alignment.h>\n#include <avs/minmax.h>\n#include \"../core/internal.h\"\n#include <stdint.h>\n\n\n/********************************************************************\n***** Declare index of new filters for Avisynth's filter engine *****\n********************************************************************/\n\nextern const AVSFunction Focus_filters[] = {\n  { \"Blur\",           BUILTIN_FUNC_PREFIX, \"cf[]f[mmx]b\", Create_Blur },                     // amount [-1.0 - 1.5849625] -- log2(3)\n  { \"Sharpen\",        BUILTIN_FUNC_PREFIX, \"cf[]f[mmx]b\", Create_Sharpen },               // amount [-1.5849625 - 1.0]\n  { \"TemporalSoften\", BUILTIN_FUNC_PREFIX, \"ciii[scenechange]i[mode]i\", TemporalSoften::Create }, // radius, luma_threshold, chroma_threshold\n  { \"SpatialSoften\",  BUILTIN_FUNC_PREFIX, \"ciii\", SpatialSoften::Create },   // radius, luma_threshold, chroma_threshold\n  { 0 }\n};\n\n\n\n\n\n/****************************************\n ***  AdjustFocus helper classes     ***\n ***  Originally by Ben R.G.         ***\n ***  MMX code by Marc FD            ***\n ***  Adaptation and bugfixes sh0dan ***\n ***  Code actually requires ISSE!   ***\n ***  Not anymore - pure MMX    IanB ***\n ***  Implement boundary proc.  IanB ***\n ***  Impl. full 8bit MMX proc. IanB ***\n ***************************************/\n\nAdjustFocusV::AdjustFocusV(double _amount, PClip _child)\n: GenericVideoFilter(_child), amountd(pow(2.0, _amount)) {\n    half_amount = int(32768 * amountd + 0.5);\n}\n\ntemplate<typename pixel_t>\nstatic void af_vertical_c(BYTE* line_buf8, BYTE* dstp8, const int height, const int pitch8, const int width, const int half_amount, int bits_per_pixel) {\n  typedef typename std::conditional < sizeof(pixel_t) == 1, int, int64_t>::type weight_t;\n  // kernel:[(1-1/2^_amount)/2, 1/2^_amount, (1-1/2^_amount)/2]\n  weight_t center_weight = half_amount*2;    // *2: 16 bit scaled arithmetic, but the converted amount parameter scaled is only 15 bits\n  weight_t outer_weight = 32768-half_amount; // (1-1/2^_amount)/2  32768 = 0.5\n  int max_pixel_value = (1 << bits_per_pixel) - 1;\n\n  pixel_t * dstp = reinterpret_cast<pixel_t *>(dstp8);\n  pixel_t * line_buf = reinterpret_cast<pixel_t *>(line_buf8);\n  int pitch = pitch8 / sizeof(pixel_t);\n\n  for (int y = height-1; y>0; --y) {\n    for (int x = 0; x < width; ++x) {\n      pixel_t a;\n      // Note: ScaledPixelClip is overloaded. With int64_t parameter and uint16_t result works for 16 bit\n      if constexpr(sizeof(pixel_t) == 1)\n        a = ScaledPixelClip((weight_t)(dstp[x] * center_weight + (line_buf[x] + dstp[x+pitch]) * outer_weight));\n      else\n        a = (pixel_t)ScaledPixelClipEx((weight_t)(dstp[x] * center_weight + (line_buf[x] + dstp[x+pitch]) * outer_weight), max_pixel_value);\n      line_buf[x] = dstp[x];\n      dstp[x] = a;\n    }\n    dstp += pitch;\n  }\n  for (int x = 0; x < width; ++x) { // Last row - map centre as lower\n    if constexpr(sizeof(pixel_t) == 1)\n      dstp[x] = ScaledPixelClip((weight_t)(dstp[x] * center_weight + (line_buf[x] + dstp[x]) * outer_weight));\n    else\n      dstp[x] = (pixel_t)ScaledPixelClipEx((weight_t)(dstp[x] * center_weight + (line_buf[x] + dstp[x]) * outer_weight), max_pixel_value);\n  }\n}\n\nstatic void af_vertical_c_float(BYTE* line_buf8, BYTE* dstp8, const int height, const int pitch8, const int width, const float amount) {\n    float *dstp = reinterpret_cast<float *>(dstp8);\n    float *line_buf = reinterpret_cast<float *>(line_buf8);\n    int pitch = pitch8 / sizeof(float);\n\n    const float center_weight = amount;\n    const float outer_weight = (1.0f - amount) / 2.0f;\n\n    for (int y = height-1; y>0; --y) {\n        for (int x = 0; x < width; ++x) {\n            float a = dstp[x] * center_weight + (line_buf[x] + dstp[x+pitch]) * outer_weight;\n            line_buf[x] = dstp[x];\n            dstp[x] = a;\n        }\n        dstp += pitch;\n    }\n    for (int x = 0; x < width; ++x) { // Last row - map centre as lower\n        dstp[x] = dstp[x] * center_weight + (line_buf[x] + dstp[x]) * outer_weight;\n    }\n}\n\ntemplate<typename pixel_t>\nstatic void af_vertical_process(BYTE* line_buf, BYTE* dstp, size_t height, size_t pitch, size_t row_size, int half_amount, int bits_per_pixel, IScriptEnvironment* env) {\n  size_t width = row_size / sizeof(pixel_t);\n  // only for 8/16 bit, float separated\n#ifdef INTEL_INTRINSICS\n  if (sizeof(pixel_t) == 1 && (env->GetCPUFlags() & CPUF_AVX2) && width >= 32) {\n    //pitch of aligned frames is always >= 32 so we'll just process some garbage if width is not mod32\n    af_vertical_avx2(line_buf, dstp, (int)height, (int)pitch, (int)width, half_amount);\n  }\n  else\n  if (sizeof(pixel_t) == 1 && (env->GetCPUFlags() & CPUF_SSE2) && width >= 16) {\n    //pitch of aligned frames is always >= 16 so we'll just process some garbage if width is not mod16\n    af_vertical_sse2(line_buf, dstp, (int)height, (int)pitch, (int)width, half_amount);\n  }\n  else if (sizeof(pixel_t) == 2 && (env->GetCPUFlags() & CPUF_AVX2) && row_size >= 32) {\n    af_vertical_uint16_t_avx2(line_buf, dstp, (int)height, (int)pitch, (int)row_size, half_amount);\n  }\n  else if (sizeof(pixel_t) == 2 && (env->GetCPUFlags() & CPUF_SSE4_1) && row_size >= 16) {\n    af_vertical_uint16_t_sse41(line_buf, dstp, (int)height, (int)pitch, (int)row_size, half_amount);\n  }\n  else if (sizeof(pixel_t) == 2 && (env->GetCPUFlags() & CPUF_SSE2) && row_size >= 16) {\n    af_vertical_uint16_t_sse2(line_buf, dstp, (int)height, (int)pitch, (int)row_size, half_amount);\n  }\n  else\n#ifdef X86_32\n  if (sizeof(pixel_t) == 1 && (env->GetCPUFlags() & CPUF_MMX) && width >= 8)\n  {\n    size_t mod8_width = width / 8 * 8;\n    af_vertical_mmx(line_buf, dstp, height, pitch, mod8_width, half_amount);\n    if (mod8_width != width) {\n      //yes, this is bad for caching. MMX shouldn't be used these days anyway\n      af_vertical_c<uint8_t>(line_buf, dstp + mod8_width, height, pitch, width - mod8_width, half_amount, bits_per_pixel);\n    }\n  } else\n#endif\n#endif\n  {\n    af_vertical_c<pixel_t>(line_buf, dstp, (int)height, (int)pitch, (int)width, half_amount, bits_per_pixel);\n  }\n}\n\nstatic void af_vertical_process_float(BYTE* line_buf, BYTE* dstp, size_t height, size_t pitch, size_t row_size, double amountd, IScriptEnvironment* env) {\n    size_t width = row_size / sizeof(float);\n#ifdef INTEL_INTRINSICS\n    if ((env->GetCPUFlags() & CPUF_SSE2) && width >= 16) {\n        //pitch of aligned frames is always >= 16 so we'll just process some garbage if width is not mod16\n        af_vertical_sse2_float(line_buf, dstp, (int)height, (int)pitch, (int)row_size, (float)amountd);\n    } \n    else\n#endif\n    {\n      af_vertical_c_float(line_buf, dstp, (int)height, (int)pitch, (int)width, (float)amountd);\n    }\n}\n\n// --------------------------------\n// Vertical Blur/Sharpen\n// --------------------------------\n\nPVideoFrame __stdcall AdjustFocusV::GetFrame(int n, IScriptEnvironment* env)\n{\n    PVideoFrame src = child->GetFrame(n, env);\n\n    env->MakeWritable(&src);\n\n    BYTE* line_buf = reinterpret_cast<BYTE*>(env->Allocate(AlignNumber(src->GetRowSize(), FRAME_ALIGN), FRAME_ALIGN, AVS_POOLED_ALLOC));\n    if (!line_buf) {\n        env->ThrowError(\"AdjustFocusV: Could not reserve memory.\");\n    }\n\n    int pixelsize = vi.ComponentSize();\n    int bits_per_pixel = vi.BitsPerComponent();\n\n    if (vi.IsPlanar()) {\n      const int planesYUV[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A};\n      const int planesRGB[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A};\n      const int *planes = vi.IsYUV() || vi.IsYUVA() ? planesYUV : planesRGB;\n\n      for (int cplane = 0; cplane < 3; cplane++) {\n            int plane = planes[cplane];\n            BYTE* dstp = src->GetWritePtr(plane);\n            int pitch = src->GetPitch(plane);\n            int row_size = src->GetRowSize(plane);\n            int height = src->GetHeight(plane);\n            memcpy(line_buf, dstp, row_size); // First row - map centre as upper\n\n            switch (pixelsize) {\n            case 1: af_vertical_process<uint8_t>(line_buf, dstp, height, pitch, row_size, half_amount, bits_per_pixel, env); break;\n            case 2: af_vertical_process<uint16_t>(line_buf, dstp, height, pitch, row_size, half_amount, bits_per_pixel, env); break;\n            default: // 4: float\n                af_vertical_process_float(line_buf, dstp, height, pitch, row_size, amountd, env); break;\n            }\n        }\n    }\n    else {\n        BYTE* dstp = src->GetWritePtr();\n        int pitch = src->GetPitch();\n        int row_size = vi.RowSize();\n        int height = vi.height;\n        memcpy(line_buf, dstp, row_size); // First row - map centre as upper\n        if (pixelsize == 1)\n          af_vertical_process<uint8_t>(line_buf, dstp, height, pitch, row_size, half_amount, bits_per_pixel, env);\n        else\n          af_vertical_process<uint16_t>(line_buf, dstp, height, pitch, row_size, half_amount, bits_per_pixel, env);\n    }\n\n    env->Free(line_buf);\n    return src;\n}\n\n\nAdjustFocusH::AdjustFocusH(double _amount, PClip _child)\n: GenericVideoFilter(_child), amountd(pow(2.0, _amount)) {\n    half_amount = int(32768 * amountd + 0.5);\n}\n\n\n// --------------------------------------\n// Blur/Sharpen Horizontal RGB32 C++ Code\n// --------------------------------------\n\ntemplate<typename pixel_t, typename weight_t>\nstatic AVS_FORCEINLINE void af_horizontal_rgb32_process_line_c(pixel_t b_left, pixel_t g_left, pixel_t r_left, pixel_t a_left, pixel_t *dstp, size_t width, weight_t center_weight, weight_t outer_weight) {\n  size_t x;\n  for (x = 0; x < width-1; ++x)\n  {\n    pixel_t b = ScaledPixelClip((weight_t)(dstp[x*4+0] * center_weight + (b_left + dstp[x*4+4]) * outer_weight));\n    b_left = dstp[x*4+0];\n    dstp[x*4+0] = b;\n    pixel_t g = ScaledPixelClip((weight_t)(dstp[x*4+1] * center_weight + (g_left + dstp[x*4+5]) * outer_weight));\n    g_left = dstp[x*4+1];\n    dstp[x*4+1] = g;\n    pixel_t r = ScaledPixelClip((weight_t)(dstp[x*4+2] * center_weight + (r_left + dstp[x*4+6]) * outer_weight));\n    r_left = dstp[x*4+2];\n    dstp[x*4+2] = r;\n    pixel_t a = ScaledPixelClip((weight_t)(dstp[x*4+3] * center_weight + (a_left + dstp[x*4+7]) * outer_weight));\n    a_left = dstp[x*4+3];\n    dstp[x*4+3] = a;\n  }\n  dstp[x*4+0] = ScaledPixelClip((weight_t)(dstp[x*4+0] * center_weight + (b_left + dstp[x*4+0]) * outer_weight));\n  dstp[x*4+1] = ScaledPixelClip((weight_t)(dstp[x*4+1] * center_weight + (g_left + dstp[x*4+1]) * outer_weight));\n  dstp[x*4+2] = ScaledPixelClip((weight_t)(dstp[x*4+2] * center_weight + (r_left + dstp[x*4+2]) * outer_weight));\n  dstp[x*4+3] = ScaledPixelClip((weight_t)(dstp[x*4+3] * center_weight + (a_left + dstp[x*4+3]) * outer_weight));\n}\n\ntemplate<typename pixel_t>\nstatic void af_horizontal_rgb32_64_c(BYTE* dstp8, size_t height, size_t pitch8, size_t width, int half_amount) {\n  typedef typename std::conditional < sizeof(pixel_t) == 1, int, int64_t>::type weight_t;\n  // kernel:[(1-1/2^_amount)/2, 1/2^_amount, (1-1/2^_amount)/2]\n  weight_t center_weight = half_amount*2;    // *2: 16 bit scaled arithmetic, but the converted amount parameter scaled is only 15 bits\n  weight_t outer_weight = 32768-half_amount; // (1-1/2^_amount)/2  32768 = 0.5\n\n  pixel_t* dstp = reinterpret_cast<pixel_t *>(dstp8);\n  size_t pitch = pitch8 / sizeof(pixel_t);\n\n  for (size_t y = height; y>0; --y)\n  {\n    pixel_t b_left = dstp[0];\n    pixel_t g_left = dstp[1];\n    pixel_t r_left = dstp[2];\n    pixel_t a_left = dstp[3];\n    af_horizontal_rgb32_process_line_c<pixel_t, weight_t>(b_left, g_left, r_left, a_left, dstp, width, center_weight, outer_weight);\n    dstp += pitch;\n  }\n\n}\n\n\n// -------------------------------------\n// Blur/Sharpen Horizontal YUY2 C++ Code\n// -------------------------------------\n\nstatic void af_horizontal_yuy2_c(BYTE* p, int height, int pitch, int width, int amount) {\n  const int center_weight = amount*2;\n  const int outer_weight = 32768-amount;\n  for (int y0 = height; y0>0; --y0)\n  {\n    BYTE yy = p[0];\n    BYTE uv = p[1];\n    BYTE vu = p[3];\n    int x;\n    for (x = 0; x < width-2; ++x)\n    {\n      BYTE y = ScaledPixelClip(p[x*2+0] * center_weight + (yy + p[x*2+2]) * outer_weight);\n      yy   = p[x*2+0];\n      p[x*2+0] = y;\n      BYTE w = ScaledPixelClip(p[x*2+1] * center_weight + (uv + p[x*2+5]) * outer_weight);\n      uv   = vu;\n      vu   = p[x*2+1];\n      p[x*2+1] = w;\n    }\n    BYTE y     = ScaledPixelClip(p[x*2+0] * center_weight + (yy + p[x*2+2]) * outer_weight);\n    yy       = p[x*2+0];\n    p[x*2+0] = y;\n    p[x*2+1] = ScaledPixelClip(p[x*2+1] * center_weight + (uv + p[x*2+1]) * outer_weight);\n    p[x*2+2] = ScaledPixelClip(p[x*2+2] * center_weight + (yy + p[x*2+2]) * outer_weight);\n    p[x*2+3] = ScaledPixelClip(p[x*2+3] * center_weight + (vu + p[x*2+3]) * outer_weight);\n\n    p += pitch;\n  }\n}\n\n\n// --------------------------------------\n// Blur/Sharpen Horizontal RGB24 C++ Code\n// --------------------------------------\n\ntemplate<typename pixel_t>\nstatic void af_horizontal_rgb24_48_c(BYTE* dstp8, int height, int pitch8, int width, int half_amount) {\n  typedef typename std::conditional < sizeof(pixel_t) == 1, int, int64_t>::type weight_t;\n  // kernel:[(1-1/2^_amount)/2, 1/2^_amount, (1-1/2^_amount)/2]\n  weight_t center_weight = half_amount*2;    // *2: 16 bit scaled arithmetic, but the converted amount parameter scaled is only 15 bits\n  weight_t outer_weight = 32768-half_amount; // (1-1/2^_amount)/2  32768 = 0.5\n\n  pixel_t *dstp = reinterpret_cast<pixel_t *>(dstp8);\n  int pitch = pitch8 / sizeof(pixel_t);\n  for (int y = height; y>0; --y)\n  {\n    pixel_t bb = dstp[0];\n    pixel_t gg = dstp[1];\n    pixel_t rr = dstp[2];\n    int x;\n    for (x = 0; x < width-1; ++x)\n    {\n      // ScaledPixelClip has 2 overloads: BYTE/uint16_t (int/int64 i)\n      pixel_t b = ScaledPixelClip((weight_t)(dstp[x*3+0] * center_weight + (bb + dstp[x*3+3]) * outer_weight));\n      bb = dstp[x*3+0]; dstp[x*3+0] = b;\n      pixel_t g = ScaledPixelClip((weight_t)(dstp[x*3+1] * center_weight + (gg + dstp[x*3+4]) * outer_weight));\n      gg = dstp[x*3+1]; dstp[x*3+1] = g;\n      pixel_t r = ScaledPixelClip((weight_t)(dstp[x*3+2] * center_weight + (rr + dstp[x*3+5]) * outer_weight));\n      rr = dstp[x*3+2]; dstp[x*3+2] = r;\n    }\n    dstp[x*3+0] = ScaledPixelClip((weight_t)(dstp[x*3+0] * center_weight + (bb + dstp[x*3+0]) * outer_weight));\n    dstp[x*3+1] = ScaledPixelClip((weight_t)(dstp[x*3+1] * center_weight + (gg + dstp[x*3+1]) * outer_weight));\n    dstp[x*3+2] = ScaledPixelClip((weight_t)(dstp[x*3+2] * center_weight + (rr + dstp[x*3+2]) * outer_weight));\n    dstp += pitch;\n  }\n}\n\n// -------------------------------------\n// Blur/Sharpen Horizontal YV12 C++ Code\n// -------------------------------------\n\n// for linker reasons these forceinlined functions appear in C, intel sse2 and avx2 source as well\ntemplate<typename pixel_t>\nstatic AVS_FORCEINLINE void af_horizontal_planar_process_line_c(pixel_t left, BYTE *dstp8, size_t row_size, int center_weight, int outer_weight) {\n  size_t x;\n  pixel_t* dstp = reinterpret_cast<pixel_t *>(dstp8);\n  typedef typename std::conditional < sizeof(pixel_t) == 1, int, int64_t>::type weight_t; // for calling the right ScaledPixelClip()\n  size_t width = row_size / sizeof(pixel_t);\n  for (x = 0; x < width-1; ++x) {\n    pixel_t temp = ScaledPixelClip((weight_t)(dstp[x] * (weight_t)center_weight + (left + dstp[x+1]) * (weight_t)outer_weight));\n    left = dstp[x];\n    dstp[x] = temp;\n  }\n  // ScaledPixelClip has 2 overloads: BYTE/uint16_t (int/int64 i)\n  dstp[x] = ScaledPixelClip((weight_t)(dstp[x] * (weight_t)center_weight + (left + dstp[x]) * (weight_t)outer_weight));\n}\n\nstatic AVS_FORCEINLINE void af_horizontal_planar_process_line_uint16_c(uint16_t left, BYTE *dstp8, size_t row_size, int center_weight, int outer_weight, int bits_per_pixel) {\n  size_t x;\n  typedef uint16_t pixel_t;\n  pixel_t* dstp = reinterpret_cast<pixel_t *>(dstp8);\n  const int max_pixel_value = (1 << bits_per_pixel) - 1; // clamping on 10-12-14-16 bitdepth\n  typedef std::conditional < sizeof(pixel_t) == 1, int, int64_t>::type weight_t; // for calling the right ScaledPixelClip()\n  size_t width = row_size / sizeof(pixel_t);\n  for (x = 0; x < width-1; ++x) {\n    pixel_t temp = (pixel_t)ScaledPixelClipEx((weight_t)(dstp[x] * (weight_t)center_weight + (left + dstp[x+1]) * (weight_t)outer_weight), max_pixel_value);\n    left = dstp[x];\n    dstp[x] = temp;\n  }\n  // ScaledPixelClip has 2 overloads: BYTE/uint16_t (int/int64 i)\n  dstp[x] = ScaledPixelClipEx((weight_t)(dstp[x] * (weight_t)center_weight + (left + dstp[x]) * (weight_t)outer_weight), max_pixel_value);\n}\n\nstatic AVS_FORCEINLINE void af_horizontal_planar_process_line_float_c(float left, float* dstp, size_t row_size, float center_weight, float outer_weight) {\n  size_t x;\n  size_t width = row_size / sizeof(float);\n  for (x = 0; x < width - 1; ++x) {\n    float temp = dstp[x] * center_weight + (left + dstp[x + 1]) * outer_weight;\n    left = dstp[x];\n    dstp[x] = temp;\n  }\n  dstp[x] = dstp[x] * center_weight + (left + dstp[x]) * outer_weight;\n}\n\ntemplate<typename pixel_t>\nstatic void af_horizontal_planar_c(BYTE* dstp8, size_t height, size_t pitch8, size_t row_size, size_t half_amount, int bits_per_pixel)\n{\n    pixel_t* dstp = reinterpret_cast<pixel_t *>(dstp8);\n    size_t pitch = pitch8 / sizeof(pixel_t);\n    int center_weight = int(half_amount*2);\n    int outer_weight = int(32768-half_amount);\n    pixel_t left;\n    for (size_t y = height; y>0; --y) {\n        left = dstp[0];\n        if constexpr(sizeof(pixel_t) == 1)\n          af_horizontal_planar_process_line_c<pixel_t>(left, (BYTE *)dstp, row_size, center_weight, outer_weight);\n        else\n          af_horizontal_planar_process_line_uint16_c(left, (BYTE *)dstp, row_size, center_weight, outer_weight, bits_per_pixel);\n        dstp += pitch;\n    }\n}\n\nstatic void af_horizontal_planar_float_c(BYTE* dstp8, size_t height, size_t pitch8, size_t row_size, float amount)\n{\n    float* dstp = reinterpret_cast<float *>(dstp8);\n    size_t pitch = pitch8 / sizeof(float);\n    float center_weight = amount;\n    float outer_weight = (1.0f - amount) / 2.0f;\n    float left;\n    for (size_t y = height; y>0; --y) {\n        left = dstp[0];\n        af_horizontal_planar_process_line_float_c(left, dstp, row_size, center_weight, outer_weight);\n        dstp += pitch;\n    }\n}\n\nstatic void copy_frame(const PVideoFrame &src, PVideoFrame &dst, IScriptEnvironment *env, const int *planes, int plane_count) {\n  for (int p = 0; p < plane_count; p++) {\n    int plane = planes[p];\n    env->BitBlt(dst->GetWritePtr(plane), dst->GetPitch(plane), src->GetReadPtr(plane),\n      src->GetPitch(plane), src->GetRowSize(plane), src->GetHeight(plane));\n  }\n}\n\n// ----------------------------------\n// Blur/Sharpen Horizontal GetFrame()\n// ----------------------------------\n\nPVideoFrame __stdcall AdjustFocusH::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame src = child->GetFrame(n, env);\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n\n  const int planesYUV[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A};\n  const int planesRGB[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A};\n  const int *planes = vi.IsYUV() || vi.IsYUVA() ? planesYUV : planesRGB;\n\n  int pixelsize = vi.ComponentSize();\n\n  if (vi.IsPlanar()) {\n    copy_frame(src, dst, env, planes, vi.NumComponents() ); //planar processing is always in-place\n    int bits_per_pixel = vi.BitsPerComponent();\n    for(int cplane=0;cplane<3;cplane++) {\n      int plane = planes[cplane];\n      int row_size = dst->GetRowSize(plane);\n      BYTE* q = dst->GetWritePtr(plane);\n      int pitch = dst->GetPitch(plane);\n      int height = dst->GetHeight(plane);\n#ifdef INTEL_INTRINSICS\n      if (pixelsize == 1 && (env->GetCPUFlags() & CPUF_AVX2) && row_size > 32) {\n        af_horizontal_planar_avx2(q, height, pitch, row_size, half_amount);\n      }\n      else\n        if (pixelsize==1 && (env->GetCPUFlags() & CPUF_SSE2) && row_size > 16) {\n        af_horizontal_planar_sse2(q, height, pitch, row_size, half_amount);\n      } else\n#ifdef X86_32\n        if (pixelsize == 1 && (env->GetCPUFlags() & CPUF_MMX) && row_size > 8) {\n          af_horizontal_planar_mmx(q,height,pitch,row_size,half_amount);\n        } else\n#endif\n        if (pixelsize == 2 && (env->GetCPUFlags() & CPUF_AVX2) && row_size > 32) {\n          af_horizontal_planar_uint16_t_avx2(q, height, pitch, row_size, half_amount, bits_per_pixel);\n        }\n        else if (pixelsize == 2 && (env->GetCPUFlags() & CPUF_SSE4_1) && row_size > 16) {\n          af_horizontal_planar_uint16_t_sse41(q, height, pitch, row_size, half_amount, bits_per_pixel);\n        }\n        else if (pixelsize == 2 && (env->GetCPUFlags() & CPUF_SSE2) && row_size > 16) {\n          af_horizontal_planar_uint16_t_sse2(q, height, pitch, row_size, half_amount, bits_per_pixel);\n        }\n        else if (pixelsize == 4 && (env->GetCPUFlags() & CPUF_SSE2) && row_size > 16) {\n          af_horizontal_planar_float_sse2(q, height, pitch, row_size, (float)amountd);\n        }\n        else\n#endif\n        {\n          switch (pixelsize) {\n          case 1: af_horizontal_planar_c<uint8_t>(q, height, pitch, row_size, half_amount, bits_per_pixel); break;\n          case 2: af_horizontal_planar_c<uint16_t>(q, height, pitch, row_size, half_amount, bits_per_pixel); break;\n          default: // 4: float\n            af_horizontal_planar_float_c(q, height, pitch, row_size, (float)amountd); break;\n          }\n        }\n    }\n  } else {\n    if (vi.IsYUY2()) {\n      BYTE* q = dst->GetWritePtr();\n      const int pitch = dst->GetPitch();\n#ifdef INTEL_INTRINSICS\n      if ((env->GetCPUFlags() & CPUF_SSE2) && vi.width>8) {\n        af_horizontal_yuy2_sse2(dst->GetWritePtr(), src->GetReadPtr(), dst->GetPitch(), src->GetPitch(), vi.height, vi.width, half_amount);\n      } else\n#ifdef X86_32\n      if ((env->GetCPUFlags() & CPUF_MMX) && vi.width>8) {\n        af_horizontal_yuy2_mmx(dst->GetWritePtr(), src->GetReadPtr(), dst->GetPitch(), src->GetPitch(), vi.height, vi.width, half_amount);\n      } else\n#endif\n#endif\n      {\n        copy_frame(src, dst, env, planesYUV, 1); //in-place\n        af_horizontal_yuy2_c(q,vi.height,pitch,vi.width,half_amount);\n      }\n    }\n    else if (vi.IsRGB32() || vi.IsRGB64()) {\n#ifdef INTEL_INTRINSICS\n      if ((pixelsize==1) && (env->GetCPUFlags() & CPUF_SSE2) && vi.width>4) {\n        //this one is NOT in-place\n        af_horizontal_rgb32_sse2(dst->GetWritePtr(), src->GetReadPtr(), dst->GetPitch(), src->GetPitch(), vi.height, vi.width, half_amount);\n      }\n      else if ((pixelsize == 2) && (env->GetCPUFlags() & CPUF_SSE4_1) && vi.width > 2) {\n        //this one is NOT in-place\n        af_horizontal_rgb64_sse41(dst->GetWritePtr(), src->GetReadPtr(), dst->GetPitch(), src->GetPitch(), vi.height, vi.width, half_amount); // really width\n      }\n      else if ((pixelsize == 2) && (env->GetCPUFlags() & CPUF_SSE2) && vi.width > 2) {\n        //this one is NOT in-place\n        af_horizontal_rgb64_sse2(dst->GetWritePtr(), src->GetReadPtr(), dst->GetPitch(), src->GetPitch(), vi.height, vi.width, half_amount); // really width\n      }\n      else\n#ifdef X86_32\n      if ((pixelsize==1) && (env->GetCPUFlags() & CPUF_MMX) && vi.width > 2)\n      { //so as this one\n        af_horizontal_rgb32_mmx(dst->GetWritePtr(), src->GetReadPtr(), dst->GetPitch(), src->GetPitch(), vi.height, vi.width, half_amount);\n      } else\n#endif\n#endif\n      {\n        copy_frame(src, dst, env, planesYUV, 1);\n        if(pixelsize==1)\n          af_horizontal_rgb32_64_c<uint8_t>(dst->GetWritePtr(), vi.height, dst->GetPitch(), vi.width, half_amount);\n        else\n          af_horizontal_rgb32_64_c<uint16_t>(dst->GetWritePtr(), vi.height, dst->GetPitch(), vi.width, half_amount);\n      }\n    } else if (vi.IsRGB24() || vi.IsRGB48()) {\n      copy_frame(src, dst, env, planesYUV, 1);\n      if(pixelsize==1)\n        af_horizontal_rgb24_48_c<uint8_t>(dst->GetWritePtr(), vi.height, dst->GetPitch(), vi.width, half_amount);\n      else\n        af_horizontal_rgb24_48_c<uint16_t>(dst->GetWritePtr(), vi.height, dst->GetPitch(), vi.width, half_amount);\n    }\n  }\n\n  return dst;\n}\n\n\n/************************************************\n *******   Sharpen/Blur Factory Methods   *******\n ***********************************************/\n\nAVSValue __cdecl Create_Sharpen(AVSValue args, void*, IScriptEnvironment* env)\n{\n  const double amountH = args[1].AsFloat(), amountV = args[2].AsDblDef(amountH);\n\n  if (amountH < -1.5849625 || amountH > 1.0 || amountV < -1.5849625 || amountV > 1.0) // log2(3)\n    env->ThrowError(\"Sharpen: arguments must be in the range -1.58 to 1.0\");\n\n  if (fabs(amountH) < 0.00002201361136) { // log2(1+1/65536)\n    if (fabs(amountV) < 0.00002201361136) {\n      return args[0].AsClip();\n    }\n    else {\n      return new AdjustFocusV(amountV, args[0].AsClip());\n    }\n  }\n  else {\n    if (fabs(amountV) < 0.00002201361136) {\n      return new AdjustFocusH(amountH, args[0].AsClip());\n    }\n    else {\n      return new AdjustFocusH(amountH, new AdjustFocusV(amountV, args[0].AsClip()));\n    }\n  }\n}\n\nAVSValue __cdecl Create_Blur(AVSValue args, void*, IScriptEnvironment* env)\n{\n  const double amountH = args[1].AsFloat(), amountV = args[2].AsDblDef(amountH);\n\n  if (amountH < -1.0 || amountH > 1.5849625 || amountV < -1.0 || amountV > 1.5849625) // log2(3)\n    env->ThrowError(\"Blur: arguments must be in the range -1.0 to 1.58\");\n\n  if (fabs(amountH) < 0.00002201361136) { // log2(1+1/65536)\n    if (fabs(amountV) < 0.00002201361136) {\n      return args[0].AsClip();\n    }\n    else {\n      return new AdjustFocusV(-amountV, args[0].AsClip());\n    }\n  }\n  else {\n    if (fabs(amountV) < 0.00002201361136) {\n      return new AdjustFocusH(-amountH, args[0].AsClip());\n    }\n    else {\n      return new AdjustFocusH(-amountH, new AdjustFocusV(-amountV, args[0].AsClip()));\n    }\n  }\n}\n\n\n\n\n/***************************\n ****  TemporalSoften  *****\n **************************/\n\nTemporalSoften::TemporalSoften( PClip _child, unsigned radius, unsigned luma_thresh,\n                                unsigned chroma_thresh, int _scenechange, IScriptEnvironment* env )\n  : GenericVideoFilter(_child),\n  scenechange(_scenechange),\n  luma_threshold(min(luma_thresh, 255u)),\n  chroma_threshold(min(chroma_thresh, 255u)),\n  kernel(2 * min(radius, (unsigned int)MAX_RADIUS) + 1)\n{\n\n  child->SetCacheHints(CACHE_WINDOW,kernel);\n\n  if (vi.IsRGB24() || vi.IsRGB48()) {\n    env->ThrowError(\"TemporalSoften: RGB24/48 Not supported, use ConvertToRGB32/48().\");\n  }\n\n  if ((vi.IsRGB32() || vi.IsRGB64()) && (vi.width&1)) {\n    env->ThrowError(\"TemporalSoften: RGB32/64 source must be multiple of 2 in width.\");\n  }\n\n  if ((vi.IsYUY2()) && (vi.width&3)) {\n    env->ThrowError(\"TemporalSoften: YUY2 source must be multiple of 4 in width.\");\n  }\n\n  if (scenechange >= 255) {\n    scenechange = 0;\n  }\n\n  if (scenechange>0 && (vi.IsRGB32() || vi.IsRGB64())) {\n      env->ThrowError(\"TemporalSoften: Scenechange not available on RGB32/64\");\n  }\n\n  pixelsize = vi.ComponentSize();\n  bits_per_pixel = vi.BitsPerComponent();\n\n  // original scenechange parameter always 0-255\n  int factor;\n  if (vi.IsPlanar()) // Y/YUV, no Planar RGB here\n    factor = 1; // bitdepth independent. sad normalizes\n  else\n    factor = vi.BytesFromPixels(1) / pixelsize; // /pixelsize: correction for packed 16 bit rgb\n  scenechange *= ((vi.width/32)*32)*vi.height*factor; // why /*32?\n\n\n  int c = 0;\n  if (vi.IsPlanar() && (vi.IsYUV() || vi.IsYUVA())) {\n    if (luma_thresh>0) {\n      planes[c].planeId = PLANAR_Y;\n      planes[c++].threshold = luma_thresh;\n    }\n    if (chroma_thresh>0) {\n      planes[c].planeId = PLANAR_V;\n      planes[c++].threshold =chroma_thresh;\n      planes[c].planeId = PLANAR_U;\n      planes[c++].threshold = chroma_thresh;\n    }\n  } else if (vi.IsYUY2()) {\n    planes[c].planeId=0;\n    planes[c++].threshold=luma_thresh|(chroma_thresh<<8);\n  } else if (vi.IsRGB()) {  // For RGB We use Luma.\n    if (vi.IsPlanar()) {\n      planes[c].planeId = PLANAR_G;\n      planes[c++].threshold = luma_thresh;\n      planes[c].planeId = PLANAR_B;\n      planes[c++].threshold = luma_thresh;\n      planes[c].planeId = PLANAR_R;\n      planes[c++].threshold = luma_thresh;\n    }\n    else { // packed RGB\n      planes[c].planeId = 0;\n      planes[c++].threshold = luma_thresh;\n    }\n  }\n  planes[c].planeId=0;\n}\n\n//offset is the initial value of x. Used when C routine processes only parts of frames after SSE/MMX paths do their job.\ntemplate<typename pixel_t, bool maxThreshold>\nstatic void accumulate_line_c(BYTE* _c_plane, const BYTE** planeP, int planes, int offset, size_t rowsize, BYTE _threshold, int div, int bits_per_pixel) {\n  pixel_t *c_plane = reinterpret_cast<pixel_t *>(_c_plane);\n\n  typedef typename std::conditional < sizeof(pixel_t) <= 2, int, float>::type sum_t;\n  typedef typename std::conditional < sizeof(pixel_t) == 1, int, int64_t>::type bigsum_t;\n  typedef typename std::conditional < std::is_floating_point<pixel_t>::value, float, int>::type threshold_t;\n\n  size_t width = rowsize / sizeof(pixel_t);\n\n  threshold_t threshold = _threshold; // parameter 0..255\n  if (std::is_floating_point<pixel_t>::value)\n    threshold = (threshold_t)(threshold / 255.0f); // float\n  else if constexpr(sizeof(pixel_t) == 2) {\n    threshold = threshold * (uint16_t)(1 << (bits_per_pixel - 8)); // uint16_t, 10 bit: *4 16bit: *256\n  }\n\n  for (size_t x = offset; x < width; ++x) {\n    pixel_t current = c_plane[x];\n    sum_t sum = current;\n\n    for (int plane = planes - 1; plane >= 0; plane--) {\n      pixel_t p = reinterpret_cast<const pixel_t *>(planeP[plane])[x];\n      if (maxThreshold) {\n        sum += p; // simple frame average mode\n      }\n      else {\n        sum_t absdiff = std::abs(current - p);\n\n        if (absdiff <= threshold) {\n          sum += p;\n        }\n        else {\n          sum += current;\n        }\n      }\n    }\n    if (std::is_floating_point<pixel_t>::value)\n      c_plane[x] = (pixel_t)(sum / (planes + 1)); // float: simple average\n    else\n      c_plane[x] = (pixel_t)(((bigsum_t)sum * div + 16384) >> 15); // div = 32768/(planes+1) for integer arithmetic\n  }\n}\n\nstatic void accumulate_line_yuy2_c(BYTE* c_plane, const BYTE** planeP, int planes, size_t width, BYTE threshold_luma, BYTE threshold_chroma, int div) {\n  for (size_t x = 0; x < width; x+=2) {\n    BYTE current_y = c_plane[x];\n    BYTE current_c = c_plane[x+1];\n    size_t sum_y = current_y;\n    size_t sum_c = current_c;\n\n    for (int plane = planes - 1; plane >= 0; plane--) {\n      BYTE p_y = planeP[plane][x];\n      BYTE p_c = planeP[plane][x+1];\n      size_t absdiff_y = std::abs(current_y - p_y);\n      size_t absdiff_c = std::abs(current_c - p_c);\n\n      if (absdiff_y <= threshold_luma) {\n        sum_y += p_y;\n      } else {\n        sum_y += current_y;\n      }\n\n      if (absdiff_c <= threshold_chroma) {\n        sum_c += p_c;\n      } else {\n        sum_c += current_c;\n      }\n    }\n\n    c_plane[x] = (BYTE)((sum_y * div + 16384) >> 15);\n    c_plane[x+1] = (BYTE)((sum_c * div + 16384) >> 15);\n  }\n}\n\nstatic void accumulate_line_yuy2(BYTE* c_plane, const BYTE** planeP, int planes, size_t width, BYTE threshold_luma, BYTE threshold_chroma, int div, IScriptEnvironment* env)\n{\n#ifdef INTEL_INTRINSICS\n  if ((env->GetCPUFlags() & CPUF_SSE2) && width >= 16) {\n    accumulate_line_sse2<false>(c_plane, planeP, planes, width, threshold_luma | (threshold_chroma << 8), div);\n  } else\n#ifdef X86_32\n  if ((env->GetCPUFlags() & CPUF_MMX) && width >= 8) {\n    accumulate_line_mmx(c_plane, planeP, planes, width, threshold_luma | (threshold_chroma << 8), div); //yuy2 is always at least mod8\n  } else\n#endif\n#endif\n    accumulate_line_yuy2_c(c_plane, planeP, planes, width, threshold_luma, threshold_chroma, div);\n}\n\nstatic void accumulate_line(BYTE* c_plane, const BYTE** planeP, int planes, size_t rowsize, BYTE threshold, int div, int pixelsize, int bits_per_pixel, IScriptEnvironment* env) {\n  // threshold == 255: simple average\n  bool maxThreshold = (threshold == 255);\n#ifdef INTEL_INTRINSICS\n  if ((pixelsize == 2) && (env->GetCPUFlags() & CPUF_SSE4) && rowsize >= 16) {\n    // <maxThreshold, lessThan16bit>\n    if(maxThreshold) {\n      if(bits_per_pixel < 16)\n        accumulate_line_16_sse41<true, true>(c_plane, planeP, planes, rowsize, threshold << (bits_per_pixel - 8), div, bits_per_pixel);\n      else\n        accumulate_line_16_sse41<true, false>(c_plane, planeP, planes, rowsize, threshold << (bits_per_pixel - 8), div, bits_per_pixel);\n    }\n    else {\n      if (bits_per_pixel < 16)\n        accumulate_line_16_sse41<false, true>(c_plane, planeP, planes, rowsize, threshold << (bits_per_pixel - 8), div, bits_per_pixel);\n      else\n        accumulate_line_16_sse41<false, false>(c_plane, planeP, planes, rowsize, threshold << (bits_per_pixel - 8), div, bits_per_pixel);\n    }\n  } else if ((pixelsize == 2) && (env->GetCPUFlags() & CPUF_SSE2) && rowsize >= 16) {\n    // <maxThreshold, lessThan16bit>\n    if(maxThreshold) {\n      if(bits_per_pixel < 16)\n        accumulate_line_16_sse2<true, true>(c_plane, planeP, planes, rowsize, threshold << (bits_per_pixel - 8), div, bits_per_pixel);\n      else\n        accumulate_line_16_sse2<true, false>(c_plane, planeP, planes, rowsize, threshold << (bits_per_pixel - 8), div, bits_per_pixel);\n    }\n    else {\n      if (bits_per_pixel < 16)\n        accumulate_line_16_sse2<false, true>(c_plane, planeP, planes, rowsize, threshold << (bits_per_pixel - 8), div, bits_per_pixel);\n      else\n        accumulate_line_16_sse2<false, false>(c_plane, planeP, planes, rowsize, threshold << (bits_per_pixel - 8), div, bits_per_pixel);\n    }\n  }\n  else if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_SSSE3) && rowsize >= 16) {\n    if (maxThreshold) // <maxThreshold\n      accumulate_line_ssse3<true>(c_plane, planeP, planes, rowsize, threshold | (threshold << 8), div);\n    else\n      accumulate_line_ssse3<false>(c_plane, planeP, planes, rowsize, threshold | (threshold << 8), div);\n  } else if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_SSE2) && rowsize >= 16) {\n    if (maxThreshold)\n      accumulate_line_sse2<true>(c_plane, planeP, planes, rowsize, threshold | (threshold << 8), div);\n    else\n      accumulate_line_sse2<false>(c_plane, planeP, planes, rowsize, threshold | (threshold << 8), div);\n  }\n  else\n#ifdef X86_32\n  if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_MMX) && rowsize >= 8) {\n    size_t mod8_width = rowsize / 8 * 8;\n    accumulate_line_mmx(c_plane, planeP, planes, rowsize, threshold | (threshold << 8), div);\n\n    if (mod8_width != rowsize) {\n      accumulate_line_c<uint8_t, false>(c_plane, planeP, planes, mod8_width, rowsize - mod8_width, threshold, div, bits_per_pixel);\n    }\n  } else\n#endif\n#endif\n\n    {\n    switch(pixelsize) {\n    case 1:\n      if (maxThreshold)\n        accumulate_line_c<uint8_t, true>(c_plane, planeP, planes, 0, rowsize, threshold, div, bits_per_pixel);\n      else\n        accumulate_line_c<uint8_t, false>(c_plane, planeP, planes, 0, rowsize, threshold, div, bits_per_pixel);\n      break;\n    case 2:\n      if (maxThreshold)\n        accumulate_line_c<uint16_t, true>(c_plane, planeP, planes, 0, rowsize, threshold, div, bits_per_pixel);\n      else\n        accumulate_line_c<uint16_t, false>(c_plane, planeP, planes, 0, rowsize, threshold, div, bits_per_pixel);\n      break;\n    case 4:\n      if (maxThreshold)\n        accumulate_line_c<float, true>(c_plane, planeP, planes, 0, rowsize, threshold, div, bits_per_pixel);\n      else\n        accumulate_line_c<float, false>(c_plane, planeP, planes, 0, rowsize, threshold, div, bits_per_pixel);\n      break;\n    }\n   }\n}\n\ntemplate<typename pixel_t>\nstatic int64_t calculate_sad_c(const BYTE* cur_ptr, const BYTE* other_ptr, int cur_pitch, int other_pitch, size_t rowsize, size_t height)\n{\n  const pixel_t *ptr1 = reinterpret_cast<const pixel_t *>(cur_ptr);\n  const pixel_t *ptr2 = reinterpret_cast<const pixel_t *>(other_ptr);\n  size_t width = rowsize / sizeof(pixel_t);\n  cur_pitch /= sizeof(pixel_t);\n  other_pitch /= sizeof(pixel_t);\n\n  // for fullframe float may loose precision\n  typedef typename std::conditional < std::is_floating_point<pixel_t>::value, double, int64_t>::type sum_t;\n  // for one row int is enough and faster than int64\n  typedef typename std::conditional < std::is_floating_point<pixel_t>::value, float, int>::type sumrow_t;\n  sum_t sum = 0;\n\n  for (size_t y = 0; y < height; ++y) {\n    sumrow_t sumrow = 0;\n    for (size_t x = 0; x < width; ++x) {\n      sumrow += std::abs(ptr1[x] - ptr2[x]);\n    }\n    sum += sumrow;\n    ptr1 += cur_pitch;\n    ptr2 += other_pitch;\n  }\n  if (std::is_floating_point<pixel_t>::value)\n    return (int64_t)(sum * 255); // scale 0..1 based sum to 8 bit range\n  else\n    return (int64_t)sum; // for int, scaling to 8 bit range is done outside\n}\n\n// sum of byte-diffs.\nstatic int64_t calculate_sad(const BYTE* cur_ptr, const BYTE* other_ptr, int cur_pitch, int other_pitch, size_t rowsize, size_t height, int pixelsize, int bits_per_pixel, IScriptEnvironment* env) {\n#ifdef INTEL_INTRINSICS\n  // todo: sse for float\n  if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_SSE2) && rowsize >= 16) {\n    return (int64_t)calculate_sad_sse2<false>(cur_ptr, other_ptr, cur_pitch, other_pitch, rowsize, height);\n  }\n#ifdef X86_32\n  if ((pixelsize ==1 ) && (env->GetCPUFlags() & CPUF_INTEGER_SSE) && rowsize >= 8) {\n    return (int64_t)calculate_sad_isse(cur_ptr, other_ptr, cur_pitch, other_pitch, rowsize, height);\n  }\n#endif\n  // sse2 uint16_t\n  if ((pixelsize == 2) && (env->GetCPUFlags() & CPUF_SSE2) && rowsize >= 16) {\n    return calculate_sad_8_or_16_sse2<uint16_t, false>(cur_ptr, other_ptr, cur_pitch, other_pitch, rowsize, height) >> (bits_per_pixel-8);\n  }\n#endif\n\n  switch(pixelsize) {\n  case 1: return calculate_sad_c<uint8_t>(cur_ptr, other_ptr, cur_pitch, other_pitch, rowsize, height);\n  case 2: return calculate_sad_c<uint16_t>(cur_ptr, other_ptr, cur_pitch, other_pitch, rowsize, height) >> (bits_per_pixel-8); // scale back to 8 bit range;\n  default: // case 4\n    return calculate_sad_c<float>(cur_ptr, other_ptr, cur_pitch, other_pitch, rowsize, height);\n  }\n}\n\nPVideoFrame TemporalSoften::GetFrame(int n, IScriptEnvironment* env)\n{\n  int radius = (kernel-1) / 2;\n  int c = 0;\n\n  // Just skip if silly settings\n\n  if ((!luma_threshold && !chroma_threshold) || !radius)\n  {\n    PVideoFrame ret = child->GetFrame(n, env); // P.F.\n    return ret;\n  }\n\n  bool planeDisabled[16];\n\n  for (int p = 0; p<16; p++) {\n    planeDisabled[p] = false;\n  }\n\n  std::vector<PVideoFrame> frames;\n  frames.reserve(kernel);\n\n  for (int p = n - radius; p <= n + radius; ++p) {\n    frames.emplace_back(child->GetFrame(clamp(p, 0, vi.num_frames - 1), env));\n  }\n\n  // P.F. 16.04.06 leak fix r1841 after 8 days of bug chasing:\n  // Reason #1 of the random QTGMC memory leaks (stuck frame refcounts)\n  // MakeWritable alters the pointer if it is not yet writeable, thus the original PVideoFrame won't be freed (refcount decremented)\n  // To fix this, we leave the frame[] array in its place and copy frame[radius] to CenterFrame and make further write operations on this new frame.\n  // env->MakeWritable(&frames[radius]); // old culprit line. if not yet writeable -> gives another pointer\n  PVideoFrame CenterFrame = frames[radius];\n  env->MakeWritable(&CenterFrame);\n\n  do {\n    const BYTE* planeP[16];\n    const BYTE* planeP2[16];\n    int planePitch[16];\n    int planePitch2[16];\n\n    int current_thresh = planes[c].threshold;  // Threshold for current plane.\n    int d = 0;\n    for (int i = 0; i<radius; i++) { // Fetch all planes sequencially\n      planePitch[d] = frames[i]->GetPitch(planes[c].planeId);\n      planeP[d++] = frames[i]->GetReadPtr(planes[c].planeId);\n    }\n\n//    BYTE* c_plane = frames[radius]->GetWritePtr(planes[c]);\n    BYTE* c_plane = CenterFrame->GetWritePtr(planes[c].planeId); // P.F. using CenterFrame for write access\n\n    for (int i = 1; i<=radius; i++) { // Fetch all planes sequencially\n      planePitch[d] = frames[radius+i]->GetPitch(planes[c].planeId);\n      planeP[d++] = frames[radius+i]->GetReadPtr(planes[c].planeId);\n    }\n\n    int rowsize = CenterFrame->GetRowSize(planes[c].planeId|PLANAR_ALIGNED);\n    int h = CenterFrame->GetHeight(planes[c].planeId);\n    int pitch = CenterFrame->GetPitch(planes[c].planeId);\n\n    if (scenechange>0) {\n      int d2 = 0;\n      bool skiprest = false;\n      for (int i = radius-1; i>=0; i--) { // Check frames backwards\n        if ((!skiprest) && (!planeDisabled[i])) {\n          int sad = (int)calculate_sad(c_plane, planeP[i], pitch, planePitch[i], CenterFrame->GetRowSize(planes[c].planeId), h, pixelsize, bits_per_pixel, env);\n          if (sad < scenechange) {\n            planePitch2[d2] = planePitch[i];\n            planeP2[d2++] = planeP[i];\n          } else {\n            skiprest = true;\n          }\n          planeDisabled[i] = skiprest;  // Disable this frame on next plane (so that Y can affect UV)\n        } else {\n          planeDisabled[i] = true;\n        }\n      }\n      skiprest = false;\n      for (int i = radius; i < 2*radius; i++) { // Check forward frames\n        if ((!skiprest)  && (!planeDisabled[i])) {   // Disable this frame on next plane (so that Y can affect UV)\n          int sad = (int)calculate_sad(c_plane, planeP[i], pitch, planePitch[i], CenterFrame->GetRowSize(planes[c].planeId), h, pixelsize, bits_per_pixel, env);\n          if (sad < scenechange) {\n            planePitch2[d2] = planePitch[i];\n            planeP2[d2++] = planeP[i];\n          } else {\n            skiprest = true;\n          }\n          planeDisabled[i] = skiprest;\n        } else {\n          planeDisabled[i] = true;\n        }\n      }\n\n      //Copy back\n      for (int i = 0; i<d2; i++) {\n        planeP[i] = planeP2[i];\n        planePitch[i] = planePitch2[i];\n      }\n      d = d2;\n    }\n\n    if (d < 1)\n    {\n      // Memory leak reason #2 r1841: this wasn't here before return\n      for (int i = 0; i < kernel; ++i)\n        frames[i] = nullptr;\n      // return frames[radius];\n      return CenterFrame; // return the modified frame\n    }\n\n    int c_div = 32768/(d+1);  // We also have the tetplane included, thus d+1.\n    if (current_thresh) {\n      // for threshold==255 -> simple average\n      for (int y = 0; y<h; y++) { // One line at the time\n        if (vi.IsYUY2()) {\n          accumulate_line_yuy2(c_plane, planeP, d, rowsize, luma_threshold, chroma_threshold, c_div, env);\n        } else {\n          accumulate_line(c_plane, planeP, d, rowsize, current_thresh, c_div, pixelsize, bits_per_pixel, env);\n        }\n        for (int p = 0; p<d; p++)\n          planeP[p] += planePitch[p];\n        c_plane += pitch;\n      }\n    } else { // Just maintain the plane\n    }\n    c++;\n  } while (planes[c].planeId);\n\n  //  PVideoFrame result = frames[radius]; // we are using CenterFrame instead\n  //  return result;\n  return CenterFrame;\n}\n\n\nAVSValue __cdecl TemporalSoften::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  return new TemporalSoften( args[0].AsClip(), args[1].AsInt(), args[2].AsInt(),\n                             args[3].AsInt(), args[4].AsInt(0),/*args[5].AsInt(1),*/env ); //ignore mode parameter\n}\n\n\n\n/****************************\n ****  Spatial Soften   *****\n ***************************/\n\nSpatialSoften::SpatialSoften( PClip _child, int _radius, unsigned _luma_threshold,\n                              unsigned _chroma_threshold, IScriptEnvironment* env )\n  : GenericVideoFilter(_child),\n    luma_threshold(_luma_threshold), chroma_threshold(_chroma_threshold),\n    diameter(_radius * 2 + 1)\n{\n  if (!vi.IsYUY2())\n    env->ThrowError(\"SpatialSoften: requires YUY2 input\");\n}\n\n\nPVideoFrame SpatialSoften::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame src = child->GetFrame(n, env);\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n\n  const BYTE* srcp = src->GetReadPtr();\n  BYTE* dstp = dst->GetWritePtr();\n  int src_pitch = src->GetPitch();\n  int dst_pitch = dst->GetPitch();\n  int row_size = src->GetRowSize();\n\n  for (int y=0; y<vi.height; ++y)\n  {\n    const BYTE* line[65];    // better not make diameter bigger than this...\n    for (int h=0; h<diameter; ++h)\n      line[h] = &srcp[src_pitch * clamp(y+h-(diameter>>1), 0, vi.height-1)];\n    int x;\n\n    int edge = (diameter+1) & -4;\n    for (x=0; x<edge; ++x)  // diameter-1 == (diameter>>1) * 2\n      dstp[y*dst_pitch + x] = srcp[y*src_pitch + x];\n    for (; x < row_size - edge; x+=2)\n    {\n      int cnt=0, _y=0, _u=0, _v=0;\n      int xx = x | 3;\n      int Y = srcp[y*src_pitch + x], U = srcp[y*src_pitch + xx - 2], V = srcp[y*src_pitch + xx];\n      for (int h=0; h<diameter; ++h)\n      {\n        for (int w = -diameter+1; w < diameter; w += 2)\n        {\n          int xw = (x+w) | 3;\n          if (IsClose(line[h][x+w], Y, luma_threshold) && IsClose(line[h][xw-2], U,\n                      chroma_threshold) && IsClose(line[h][xw], V, chroma_threshold))\n          {\n            ++cnt; _y += line[h][x+w]; _u += line[h][xw-2]; _v += line[h][xw];\n          }\n        }\n      }\n      dstp[y*dst_pitch + x] = (_y + (cnt>>1)) / cnt;\n      if (!(x&3)) {\n        dstp[y*dst_pitch + x+1] = (_u + (cnt>>1)) / cnt;\n        dstp[y*dst_pitch + x+3] = (_v + (cnt>>1)) / cnt;\n      }\n    }\n    for (; x<row_size; ++x)\n      dstp[y*dst_pitch + x] = srcp[y*src_pitch + x];\n  }\n\n  return dst;\n}\n\n\nAVSValue __cdecl SpatialSoften::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  return new SpatialSoften( args[0].AsClip(), args[1].AsInt(), args[2].AsInt(),\n                            args[3].AsInt(), env );\n}\n"
  },
  {
    "path": "avs_core/filters/focus.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Focus_H__\n#define __Focus_H__\n\n#include <avisynth.h>\n\ntemplate<bool packedRGB3264>\nint calculate_sad_sse2(const BYTE* cur_ptr, const BYTE* other_ptr, int cur_pitch, int other_pitch, size_t rowsize, size_t height);\ntemplate<typename pixel_t, bool packedRGB3264>\nint64_t calculate_sad_8_or_16_sse2(const BYTE* cur_ptr, const BYTE* other_ptr, int cur_pitch, int other_pitch, size_t rowsize, size_t height);\n\nclass AdjustFocusV : public GenericVideoFilter\n/**\n  * Class to adjust focus in the vertical direction, helper for sharpen/blue\n **/\n{\npublic:\n  AdjustFocusV(double _amount, PClip _child);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\nprivate:\n  const double amountd;\n  int half_amount;\n};\n\n\nclass AdjustFocusH : public GenericVideoFilter\n/**\n  * Class to adjust focus in the horizontal direction, helper for sharpen/blue\n **/\n{\npublic:\n  AdjustFocusH(double _amount, PClip _child);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\nprivate:\n  const double amountd;\n  int half_amount;\n};\n\nAVSValue __cdecl Create_Sharpen(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue __cdecl Create_Blur(AVSValue args, void*, IScriptEnvironment* env);\n\n\n/*** Soften classes ***/\n\nclass TemporalSoften : public GenericVideoFilter\n/**\n  * Class to soften the focus on the temporal axis\n **/\n{\npublic:\n  TemporalSoften( PClip _child, unsigned radius, unsigned luma_thresh, unsigned chroma_thresh,int _scenechange, IScriptEnvironment* env );\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\nprivate:\n    typedef struct {\n      int planeId;\n      int threshold;\n    } planeInfo;\n    planeInfo planes[4];\n    int scenechange;\n    int pixelsize;\n    int bits_per_pixel;\n\n// YUY2:\n  const unsigned luma_threshold, chroma_threshold;\n  const int kernel;\n\n  enum { MAX_RADIUS=7 };\n};\n\n\nclass SpatialSoften : public GenericVideoFilter\n/**\n  * Class to soften the focus on the spatial axis\n **/\n{\npublic:\n  SpatialSoften(PClip _child, int _radius, unsigned _luma_threshold, unsigned _chroma_threshold, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\nprivate:\n  const unsigned luma_threshold, chroma_threshold;\n  const int diameter;\n\n};\n\n#endif  // __Focus_H__\n"
  },
  {
    "path": "avs_core/filters/fps.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include \"fps.h\"\n\n#ifdef AVS_WINDOWS\n    #include <avs/win.h>\n#else\n    #include <avs/posix.h>\n#endif\n\n#include <avs/minmax.h>\n#include \"../core/bitblt.h\"\n#include \"../core/internal.h\"\n#include \"merge.h\"\n#include <cmath>\n\n\n\n/********************************************************************\n***** Declare index of new filters for Avisynth's filter engine *****\n********************************************************************/\n\nextern const AVSFunction Fps_filters[] = {\n  { \"AssumeScaledFPS\", BUILTIN_FUNC_PREFIX, \"c[multiplier]i[divisor]i[sync_audio]b\", AssumeScaledFPS::Create },\n\n  { \"AssumeFPS\", BUILTIN_FUNC_PREFIX, \"ci[]i[sync_audio]b\", AssumeFPS::Create },      // dst framerate, sync audio?\n  { \"AssumeFPS\", BUILTIN_FUNC_PREFIX, \"cf[sync_audio]b\", AssumeFPS::CreateFloat },    // dst framerate, sync audio?\n  { \"AssumeFPS\", BUILTIN_FUNC_PREFIX, \"cs[sync_audio]b\", AssumeFPS::CreatePreset }, // dst framerate, sync audio?\n  { \"AssumeFPS\", BUILTIN_FUNC_PREFIX, \"cc[sync_audio]b\", AssumeFPS::CreateFromClip }, // clip with dst framerate, sync audio?\n\n  { \"ChangeFPS\", BUILTIN_FUNC_PREFIX, \"ci[]i[linear]b\", ChangeFPS::Create },     // dst framerate, fetch all frames\n  { \"ChangeFPS\", BUILTIN_FUNC_PREFIX, \"cf[linear]b\", ChangeFPS::CreateFloat },   // dst framerate, fetch all frames\n  { \"ChangeFPS\", BUILTIN_FUNC_PREFIX, \"cs[linear]b\", ChangeFPS::CreatePreset }, // dst framerate, fetch all frames\n  { \"ChangeFPS\", BUILTIN_FUNC_PREFIX, \"cc[linear]b\", ChangeFPS::CreateFromClip },// clip with dst framerate, fetch all frames\n\n  { \"ConvertFPS\", BUILTIN_FUNC_PREFIX, \"ci[]i[zone]i[vbi]i\", ConvertFPS::Create },      // dst framerate, zone lines, vbi lines\n  { \"ConvertFPS\", BUILTIN_FUNC_PREFIX, \"cf[zone]i[vbi]i\", ConvertFPS::CreateFloat },    // dst framerate, zone lines, vbi lines\n  { \"ConvertFPS\", BUILTIN_FUNC_PREFIX, \"cs[zone]i[vbi]i\", ConvertFPS::CreatePreset }, // dst framerate, zone lines, vbi lines\n  { \"ConvertFPS\", BUILTIN_FUNC_PREFIX, \"cc[zone]i[vbi]i\", ConvertFPS::CreateFromClip }, // clip with dst framerate, zone lines, vbi lines\n\n  { \"ContinuedDenominator\", BUILTIN_FUNC_PREFIX, \"f[]i[limit]i\", ContinuedCreate, (void*)0 },\n  { \"ContinuedNumerator\",   BUILTIN_FUNC_PREFIX, \"f[]i[limit]i\", ContinuedCreate, (void*)1 },\n\n  { NULL }\n};\n\n\n\n/*********************************************\n ******    Float and Rational utility   ******\n *********************************************\n\n *********************************************\n ******  Thanks to RAYMOD2 for his help  *****\n ******  in beating continued fractions  *****\n ******  into a usable form.       IanB  *****\n *********************************************/\n\n// This function converts a 32-bit IEEE float into a fraction.  This\n// process is lossless but it may fail for very large or very small\n// floats.  It also discards the sign bit.  Since the denominator will\n// always be a power of 2 and the numerator will always be odd (except\n// when the denominator is 1) the fraction will already be reduced\n// to its lowest terms. output range (2^32-2^(32-24))/1 -- (1/2^31)\n// i.e. 4294967040/1 -- 1/2147483648 (4.65661287307e-10)\n// returns true if input is out of range\n\nstatic bool float_to_frac(float input, unsigned &num, unsigned &den)\n{\n  union { float f; unsigned i; } value;\n  uint32_t mantissa;\n  int exponent;\n\n  // Bit strip the float\n  value.f = input;\n  mantissa = (value.i & 0x7FFFFF) + 0x800000;  // add implicit bit on the left\n  exponent = ((value.i & 0x7F800000) >> 23) - 127 - 23;  // remove decimal pt\n\n  // minimize the mantissa by removing any trailing 0's\n  while (!(mantissa & 1)) { mantissa >>= 1; exponent += 1; }\n\n  // if too small try to pull result from the reciprocal\n  if (exponent < -31) {\n    return float_to_frac((float)(1.0/input), den, num);\n  }\n\n  // if exponent is too large try removing leading 0's of mantissa\n  while( (exponent > 0) && !(mantissa & 0x80000000) ) {\n     mantissa <<= 1; exponent -= 1;\n  }\n  if (exponent > 0) {  // number too large\n    num = 0xffffffff;\n    den = 1;\n    return true; // Out of range!\n  }\n  num = mantissa;\n  den = 1 << (-exponent);\n\n  return false;\n}\n\n\n// This function uses continued fractions to find the rational\n// approximation such that the result truncated to a float is\n// equal to value. The semiconvergents for the smallest such\n// rational pair is then returned. The algorithm is modified\n// from Wikipedia, Continued Fractions.\n\nstatic bool reduce_float(float value, unsigned &num, unsigned &den)\n{\n  if (float_to_frac(value, num, den)) {\n    return true;\n  }\n\n  uint32_t n0 = 0, n1 = 1, n2, nx = num;  // numerators\n  uint32_t d0 = 1, d1 = 0, d2, dx = den;  // denominators\n  uint32_t a2, ax, amin;  // integer parts of quotients\n  uint32_t f1 = 0, f2;    // fractional parts of quotients\n\n  for (;;)  // calculate convergents\n  {\n    a2 = nx / dx;\n    f2 = nx % dx;\n    n2 = n0 + n1 * a2;\n    d2 = d0 + d1 * a2;\n\n    if (f2 == 0) break;  // no more convergents (n2 / d2 == input)\n\n    // Damn compiler does not correctly cast\n    // to intermediate results to float\n    float f = (float)((double)n2/d2);\n    if (f == value) break;\n\n    n0 = n1; n1 = n2;\n    d0 = d1; d1 = d2;\n    nx = dx; dx = f1 = f2;\n  }\n  if (d2 == 1)\n  {\n    num = n2;\n    den = d2;\n  }\n  else { // we have been through the loop at least twice\n\n    if ((a2 % 2 == 0) && (d0 * f1 > f2 * d1))\n       amin = a2 / 2;  // passed 1/2 a_k admissibility test\n    else\n       amin = a2 / 2 + 1;\n\n// find the sign of the error (actual + error = n2/d2) and then\n// set (n2/d2) = (num/den + sign * epsilon) = R2 and solve for ax\n//--------------------\n//   n2 = n0 + n1 * ax\n//   d2 = d0 + d1 * ax\n//-----------------------------------------------\n//   (n2/d2)       = R2     = (n0 + n1 * ax)/(d0 + d1 * ax)\n//   n0 + n1 * ax           = R2 * (d0 + d1 * ax)\n//   n0 + n1 * ax           = R2 * d0 + R2 * d1 * ax\n//   R2 * d1 * ax - n1 * ax = n0 - R2 * d0\n//   (R2 * d1 - n1) * ax    = n0 - R2 * d0\n//   ax                     = (n0 - R2 * d0)/(R2 * d1 - n1)\n\n    // bump float to adjacent float value\n    union { float f; uint32_t i; } eps; eps.f = value;\n    if (UInt32x32To64(n1, den) > UInt32x32To64(num, d1)) {\n      eps.i -= 1;\n    } else {\n      eps.i += 1;\n    }\n    double r2 = eps.f;\n    r2 += value;\n    r2 /= 2;\n\n    double yn = n0 - r2*d0;\n    double yd = r2*d1 - n1;\n    ax = (uint32_t)((yn + yd)/yd); // ceiling value\n\n    if (ax < amin) ax = amin;\n\n    // calculate nicest semiconvergent\n    num = n0 + n1 * ax;\n    den = d0 + d1 * ax;\n  }\n  return false;\n}\n\n\n// This function uses continued fractions to find the best rational\n// approximation that satisfies (denom <= limit).  The algorithm\n// is from Wikipedia, Continued Fractions.\n//\nstatic void reduce_frac(uint32_t &num, uint32_t &den, uint32_t limit)\n{\n  uint32_t n0 = 0, n1 = 1, n2, nx = num;    // numerators\n  uint32_t d0 = 1, d1 = 0, d2, dx = den;  // denominators\n  uint32_t a2, ax, amin;  // integer parts of quotients\n  uint32_t f1 = 0, f2;        // fractional parts of quotients\n  int i = 0;  // number of loop iterations\n\n  for (;;) { // calculate convergents\n    a2 = nx / dx;\n    f2 = nx % dx;\n    n2 = n0 + n1 * a2;\n    d2 = d0 + d1 * a2;\n\n    if (f2 == 0) break;\n    if ((i++) && (d2 >= limit)) break;\n\n    n0 = n1; n1 = n2;\n    d0 = d1; d1 = d2;\n    nx = dx; dx = f1 = f2;\n  }\n  if (d2 <= limit)\n  {\n    num = n2; den = d2;  // use last convergent\n  }\n  else { // (d2 > limit)\n    // d2 = d0 + d1 * ax\n    // d1 * ax = d2 - d1\n    ax = (limit - d0) / d1;  // set d2 = limit and solve for a2\n\n    if ((a2 % 2 == 0) && (d0 * f1 > f2 * d1))\n      amin = a2 / 2;  // passed 1/2 a_k admissibility test\n    else\n      amin = a2 / 2 + 1;\n\n    if (ax < amin) {\n      // use previous convergent\n      num = n1;\n      den = d1;\n    }\n    else {\n      // calculate best semiconvergent\n      num = n0 + n1 * ax;\n      den = d0 + d1 * ax;\n    }\n  }\n}\n\n\nAVSValue __cdecl ContinuedCreate(AVSValue args, void* key, IScriptEnvironment* env)\n{\n  uint32_t num, den;\n\n  if (args[1].IsInt()) { // num, den[, limit] form\n    if (args[0].IsInt()) {\n      num = args[0].AsInt();\n    } else { // IsFloat\n      num = (uint32_t)args[0].AsFloat();\n      if ((float)num != args[0].AsFloatf()) {\n        env->ThrowError(\"ContinuedFraction: Numerator must be an integer.\\n\");\n      }\n    }\n    den = args[1].AsInt();\n    reduce_frac(num, den, (uint32_t)args[2].AsInt(1001));\n  } else { // float[, limit] form\n    if (args[2].IsInt()) {\n      if (float_to_frac(args[0].AsFloatf(), num, den)) {\n        env->ThrowError(\"ContinuedFraction: Float value out of range for rational pair.\\n\");\n      }\n      reduce_frac(num, den, (uint32_t)args[2].AsInt());\n    } else {\n      if (reduce_float(args[0].AsFloatf(), num, den)) {\n        env->ThrowError(\"ContinuedFraction: Float value out of range for rational pair.\\n\");\n      }\n    }\n  }\n  return AVSValue((int)(key ? num : den));\n}\n\n\n/***************************************\n *******   Float to FPS utility   ******\n ***************************************/\n\nvoid FloatToFPS(const char *name, float n, uint32_t &num, uint32_t &den, IScriptEnvironment* env)\n{\n  if (n <= 0)\n    env->ThrowError(\"%s: FPS must be greater then 0.\\n\", name);\n\n  float x;\n  uint32_t u = (uint32_t)(n*1001+0.5);\n\n  // Check for the 30000/1001 multiples\n  x = (float)((u/30000*30000)/1001.0);\n  if (x == n) { num = u; den= 1001; return; }\n\n  // Check for the 24000/1001 multiples\n  x = (float)((u/24000*24000)/1001.0);\n  if (x == n) { num = u; den= 1001; return; }\n\n  if (n < 14.986) {\n    // Check for the 30000/1001 factors\n    u = (uint32_t)(30000/n+0.5);\n    x = (float)(30000.0/(u/1001*1001));\n    if (x == n) { num = 30000; den= u; return; }\n\n    // Check for the 24000/1001 factors\n    u = (uint32_t)(24000/n+0.5);\n    x = (float)(24000.0/(u/1001*1001));\n    if (x == n) { num = 24000; den= u; return; }\n  }\n\n  // Find the rational pair with the smallest denominator\n  // that is equal to n within the accuracy of an IEEE float.\n  if (reduce_float(n, num, den))\n    env->ThrowError(\"%s: FPS value is out of range.\\n\", name);\n\n}\n\n\n/****************************************\n *******   Preset to FPS utility   ****** -- Tritcal, IanB Jan 2006\n ****************************************/\n\nvoid PresetToFPS(const char *name, const char *p, uint32_t &num, uint32_t &den, IScriptEnvironment* env)\n{\n  if (lstrcmpi(p, \"ntsc_film\"        ) == 0) { num = 24000; den = 1001; }\n  else if (lstrcmpi(p, \"ntsc_video\"       ) == 0) { num = 30000; den = 1001; }\n  else if (lstrcmpi(p, \"ntsc_double\"      ) == 0) { num = 60000; den = 1001; }\n  else if (lstrcmpi(p, \"ntsc_quad\"        ) == 0) { num =120000; den = 1001; }\n\n  else if (lstrcmpi(p, \"ntsc_round_film\"  ) == 0) { num =  2997; den =  125; }\n  else if (lstrcmpi(p, \"ntsc_round_video\" ) == 0) { num =  2997; den =  100; }\n  else if (lstrcmpi(p, \"ntsc_round_double\") == 0) { num =  2997; den =   50; }\n  else if (lstrcmpi(p, \"ntsc_round_quad\"  ) == 0) { num =  2997; den =   25; }\n\n  else if (lstrcmpi(p, \"film\"             ) == 0) { num =    24; den =    1; }\n\n  else if (lstrcmpi(p, \"pal_film\"         ) == 0) { num =    25; den =    1; }\n  else if (lstrcmpi(p, \"pal_video\"        ) == 0) { num =    25; den =    1; }\n  else if (lstrcmpi(p, \"pal_double\"       ) == 0) { num =    50; den =    1; }\n  else if (lstrcmpi(p, \"pal_quad\"         ) == 0) { num =   100; den =    1; }\n\n  else if (lstrcmpi(p, \"drop24\"           ) == 0) { num = 24000; den = 1001; }\n  else if (lstrcmpi(p, \"drop30\"           ) == 0) { num = 30000; den = 1001; }\n  else if (lstrcmpi(p, \"drop60\"           ) == 0) { num = 60000; den = 1001; }\n  else if (lstrcmpi(p, \"drop120\"          ) == 0) { num =120000; den = 1001; }\n/*\n  else if (lstrcmpi(p, \"drop25\"           ) == 0) { num = 25000; den = 1001; }\n  else if (lstrcmpi(p, \"drop50\"           ) == 0) { num = 50000; den = 1001; }\n  else if (lstrcmpi(p, \"drop100\"          ) == 0) { num =100000; den = 1001; }\n\n  else if (lstrcmpi(p, \"nondrop24\"        ) == 0) { num =    24; den =    1; }\n  else if (lstrcmpi(p, \"nondrop25\"        ) == 0) { num =    25; den =    1; }\n  else if (lstrcmpi(p, \"nondrop30\"        ) == 0) { num =    30; den =    1; }\n  else if (lstrcmpi(p, \"nondrop50\"        ) == 0) { num =    50; den =    1; }\n  else if (lstrcmpi(p, \"nondrop60\"        ) == 0) { num =    60; den =    1; }\n  else if (lstrcmpi(p, \"nondrop100\"       ) == 0) { num =   100; den =    1; }\n  else if (lstrcmpi(p, \"nondrop120\"       ) == 0) { num =   120; den =    1; }\n\n  else if (lstrcmpi(p, \"23.976\"           ) == 0) { num = 24000; den = 1001; }\n  else if (lstrcmpi(p, \"23.976!\"          ) == 0) { num =  2997; den =  125; }\n  else if (lstrcmpi(p, \"24.0\"             ) == 0) { num =    24; den =    1; }\n  else if (lstrcmpi(p, \"25.0\"             ) == 0) { num =    25; den =    1; }\n  else if (lstrcmpi(p, \"29.97\"            ) == 0) { num = 30000; den = 1001; }\n  else if (lstrcmpi(p, \"29.97!\"           ) == 0) { num =  2997; den =  100; }\n  else if (lstrcmpi(p, \"30.0\"             ) == 0) { num =    30; den =    1; }\n  else if (lstrcmpi(p, \"59.94\"            ) == 0) { num = 60000; den = 1001; }\n  else if (lstrcmpi(p, \"59.94!\"           ) == 0) { num =  2997; den =   50; }\n  else if (lstrcmpi(p, \"60.0\"             ) == 0) { num =    60; den =    1; }\n  else if (lstrcmpi(p, \"100.0\"            ) == 0) { num =   100; den =    1; }\n  else if (lstrcmpi(p, \"119.88\"           ) == 0) { num =120000; den = 1001; }\n  else if (lstrcmpi(p, \"119.88!\"          ) == 0) { num =  2997; den =   25; }\n  else if (lstrcmpi(p, \"120.0\"            ) == 0) { num =   120; den =    1; }\n*/\n  else {\n    env->ThrowError(\"%s: invalid preset value used.\\n\", name);\n  }\n}\n\n\n\n/******************************************\n *******   AssumeScaledFPS Filters   ******\n ******************************************/\n\nAssumeScaledFPS::AssumeScaledFPS(PClip _child, int multiplier, int divisor, bool sync_audio, IScriptEnvironment* env)\n : NonCachedGenericVideoFilter(_child)\n{\n  if (divisor <= 0)\n    env->ThrowError(\"AssumeScaledFPS: Divisor must be positive.\");\n\n  if (multiplier <= 0)\n    env->ThrowError(\"AssumeScaledFPS: Multiplier must be positive.\");\n\n  if (sync_audio)\n  {\n    vi.audio_samples_per_second = MulDiv(vi.audio_samples_per_second, multiplier, divisor);\n  }\n  vi.MulDivFPS((uint32_t)multiplier, (uint32_t)divisor);\n}\n\n\nAVSValue __cdecl AssumeScaledFPS::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  return new AssumeScaledFPS( args[0].AsClip(), args[1].AsInt(1),\n                        args[2].AsInt(1), args[3].AsBool(false), env );\n}\n\n\n\n\n/************************************\n *******   AssumeFPS Filters   ******\n ************************************/\n\nAssumeFPS::AssumeFPS(PClip _child, unsigned numerator, unsigned denominator, bool sync_audio, IScriptEnvironment* env)\n : NonCachedGenericVideoFilter(_child)\n{\n  if (denominator == 0)\n    env->ThrowError(\"AssumeFPS: Denominator cannot be 0 (zero).\");\n\n  if (sync_audio)\n  {\n    int64_t a = int64_t(vi.fps_numerator) * denominator;\n    int64_t b = int64_t(vi.fps_denominator) * numerator;\n    vi.audio_samples_per_second = int((vi.audio_samples_per_second * b + (a>>1)) / a);\n  }\n  vi.SetFPS(numerator, denominator);\n}\n\n\nAVSValue __cdecl AssumeFPS::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  return new AssumeFPS( args[0].AsClip(), args[1].AsInt(),\n                        args[2].AsInt(1), args[3].AsBool(false), env );\n}\n\n\nAVSValue __cdecl AssumeFPS::CreateFloat(AVSValue args, void*, IScriptEnvironment* env)\n{\n  uint32_t num, den;\n\n  FloatToFPS(\"AssumeFPS\", args[1].AsFloatf(), num, den, env);\n  return new AssumeFPS(args[0].AsClip(), num, den, args[2].AsBool(false), env);\n}\n\n// Tritical Jan 2006\nAVSValue __cdecl AssumeFPS::CreatePreset(AVSValue args, void*, IScriptEnvironment* env)\n{\n  uint32_t num, den;\n\n  PresetToFPS(\"AssumeFPS\", args[1].AsString(), num, den, env);\n  return new AssumeFPS(args[0].AsClip(), num, den, args[2].AsBool(false), env);\n}\n\nAVSValue __cdecl AssumeFPS::CreateFromClip(AVSValue args, void*, IScriptEnvironment* env)\n{\n  const VideoInfo& vi = args[1].AsClip()->GetVideoInfo();\n\n  if (!vi.HasVideo()) {\n    env->ThrowError(\"AssumeFPS: The clip supplied to get the FPS from must contain video.\");\n  }\n\n  return new AssumeFPS( args[0].AsClip(), vi.fps_numerator,\n                        vi.fps_denominator, args[2].AsBool(false), env );\n}\n\n\n\n\n\n/************************************\n *******   ChangeFPS Filters   ******\n ************************************/\n\n\nChangeFPS::ChangeFPS(PClip _child, unsigned new_numerator, unsigned new_denominator, bool _linear, IScriptEnvironment* env)\n  : GenericVideoFilter(_child), linear(_linear)\n{\n  if (new_denominator == 0)\n    env->ThrowError(\"ChangeFPS: Denominator cannot be 0 (zero).\");\n\n  a = int64_t(vi.fps_numerator) * new_denominator;\n  b = int64_t(vi.fps_denominator) * new_numerator;\n  if (linear && (a + (b>>1))/b > 10)\n    env->ThrowError(\"ChangeFPS: Ratio must be less than 10 for linear access. Set LINEAR=False.\");\n\n  vi.SetFPS(new_numerator, new_denominator);\n  const int64_t num_frames = (vi.num_frames * b + (a >> 1)) / a;\n  if (num_frames > 0x7FFFFFFF)  // MAXINT\n    env->ThrowError(\"ChangeFPS: Maximum number of frames exceeded.\");\n\n  vi.num_frames = int(num_frames);\n  lastframe = -1;\n}\n\n\nPVideoFrame __stdcall ChangeFPS::GetFrame(int n, IScriptEnvironment* env)\n{\n  int getframe = int((n * a) / b); // Use Floor! - Which frame to get next?\n\n  if (linear) {\n    if ((lastframe < (getframe-1)) && (getframe - lastframe < 10)) {  // Do not decode more than 10 frames\n      while (lastframe < (getframe-1)) {\n        lastframe++;\n        PVideoFrame p = child->GetFrame(lastframe, env);  // If MSVC optimizes this I'll kill it ;)\n      }\n    }\n  }\n\n  lastframe = getframe;\n  return child->GetFrame(getframe , env );\n}\n\n\nbool __stdcall ChangeFPS::GetParity(int n)\n{\n  return child->GetParity(int((n * a) / b)); // Use Floor!\n}\n\n\nAVSValue __cdecl ChangeFPS::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  return new ChangeFPS(args[0].AsClip(), args[1].AsInt(), args[2].AsInt(1), args[3].AsBool(true), env);\n}\n\n\nAVSValue __cdecl ChangeFPS::CreateFloat(AVSValue args, void*, IScriptEnvironment* env)\n{\n  uint32_t num, den;\n\n  FloatToFPS(\"ChangeFPS\", args[1].AsFloatf(), num, den, env);\n  return new ChangeFPS(args[0].AsClip(), num, den, args[2].AsBool(true), env);\n}\n\n// Tritical Jan 2006\nAVSValue __cdecl ChangeFPS::CreatePreset(AVSValue args, void*, IScriptEnvironment* env)\n{\n  uint32_t num, den;\n\n  PresetToFPS(\"ChangeFPS\", args[1].AsString(), num, den, env);\n  return new ChangeFPS(args[0].AsClip(), num, den, args[2].AsBool(true), env);\n}\n\nAVSValue __cdecl ChangeFPS::CreateFromClip(AVSValue args, void*, IScriptEnvironment* env)\n{\n  const VideoInfo& vi = args[1].AsClip()->GetVideoInfo();\n\n  if (!vi.HasVideo()) {\n    env->ThrowError(\"ChangeFPS: The clip supplied to get the FPS from must contain video.\");\n  }\n\n  return new ChangeFPS(args[0].AsClip(), vi.fps_numerator, vi.fps_denominator,\n    args[2].AsBool(true), env);\n}\n\n\n\n\n\n\n\n/*************************************\n *******   ConvertFPS Filters   ******\n *************************************/\n\nConvertFPS::ConvertFPS(PClip _child, unsigned new_numerator, unsigned new_denominator, int _zone,\n  int _vbi, IScriptEnvironment* env)\n  : GenericVideoFilter(_child), zone(_zone), vbi(_vbi), lps(0)\n{\n  if (zone >= 0 && !vi.IsYUY2()) // Tritical Jan 2006\n    env->ThrowError(\"ConvertFPS: zone >= 0 requires YUY2 input\");\n\n  fa = int64_t(vi.fps_numerator) * new_denominator;\n  fb = int64_t(vi.fps_denominator) * new_numerator;\n  if (zone >= 0)\n  {\n    if (vbi < 0) vbi = 0;\n    if (vbi > vi.height) vbi = vi.height;\n    lps = int((vi.height + vbi) * fb / fa);\n    if (zone > lps)\n      env->ThrowError(\"ConvertFPS: 'zone' too large. Maximum allowed %d\", lps);\n  }\n  else if (3 * fb < (fa << 1)) {\n    int dec = MulDiv(vi.fps_numerator, 20000, vi.fps_denominator);\n    env->ThrowError(\"ConvertFPS: New frame rate too small. Must be greater than %d.%04d \"\n      \"Increase or use 'zone='\", dec / 30000, (dec / 3) % 10000);\n  }\n  vi.SetFPS(new_numerator, new_denominator);\n  const int64_t num_frames = (vi.num_frames * fb + (fa >> 1)) / fa;\n  if (num_frames > 0x7FFFFFFF)  // MAXINT\n    env->ThrowError(\"ConvertFPS: Maximum number of frames exceeded.\");\n\n  vi.num_frames = int(num_frames);\n}\n\n\nPVideoFrame __stdcall ConvertFPS::GetFrame(int n, IScriptEnvironment* env)\n{\n  // Using int64 modulo instead of modf, for double holds only 53 bits\n  // n*fa worst-like case: (60000/1001 <> 30000/1001)\n  // n = 0x7FFFFFFF; // 31 bits\n  // fa = 1001 * 60000ULL // 26 bits\n  // summa 57 bits, too much, modf((double)n * fa / fb, &nsrc_f); is not enough\n  int64_t modulo = (n * fa) % fb;\n  double frac_f = (double)modulo / fb;\n  int nsrc = int(n * fa / fb);\n\n  if (zone < 0) {\n\n    // Mode 1: Blend full frames\n\n    constexpr double threshold_f = 1.0 / 16.0;\n    // was: 1 << (resolution - 4); // 64/1024\n\n    // Don't bother if the blend ratio is small\n    if (frac_f < threshold_f)\n      return child->GetFrame(nsrc, env);\n\n    if (frac_f > 1.0 - threshold_f)\n      return child->GetFrame(nsrc + 1, env);\n\n    PVideoFrame a = child->GetFrame(nsrc, env);\n    PVideoFrame b = child->GetFrame(nsrc + 1, env);\n\n    env->MakeWritable(&a);\n\n    const int planes_y[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };\n    const int planes_r[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A };\n    const int *planes;\n\n    int planeCount;\n    planeCount = vi.IsPlanar() ? vi.NumComponents() : 1;\n    planes = (!vi.IsPlanar() || vi.IsYUV() || vi.IsYUVA()) ? planes_y : planes_r;\n\n    const int bits_per_pixel = vi.BitsPerComponent();\n    for (int j = 0; j < planeCount; ++j)\n    {\n      const int plane = planes[j];\n      const BYTE*  b_data = b->GetReadPtr(plane);\n      int          b_pitch = b->GetPitch(plane);\n      BYTE*        a_data = a->GetWritePtr(plane);\n      int          a_pitch = a->GetPitch(plane);\n      int          row_size = a->GetRowSize(plane);\n      int          height = a->GetHeight(plane);\n\n      int weight_i;\n      int invweight_i;\n      float weight = (float)frac_f; // between 0 and 1.0\n\n#ifdef INTEL_INTRINSICS\n      MergeFuncPtr weighted_merge_planar = getMergeFunc(bits_per_pixel, env->GetCPUFlags(), a_data, b_data, weight, /*out*/weight_i, /*out*/invweight_i);\n#else\n      MergeFuncPtr weighted_merge_planar = getMergeFunc(bits_per_pixel, a_data, b_data, weight, /*out*/weight_i, /*out*/invweight_i);\n#endif\n      weighted_merge_planar(a_data, b_data, a_pitch, b_pitch, row_size, height, weight, weight_i, invweight_i);\n    }\n\n    return a;\n\n  }\n  else {\n  // Mode 2: Switch to next frame at the scan line corresponding to the source frame's timing.\n  // If zone > 0, perform a gradual transition, i.e. blend one frame into the next\n  // over the given number of lines.\n\n    PVideoFrame a = child->GetFrame(nsrc, env);\n    PVideoFrame b = child->GetFrame(nsrc+1, env);\n    const BYTE*  b_data   = b->GetReadPtr();\n    int          b_pitch  = b->GetPitch();\n    const int    row_size = a->GetRowSize();\n    const int    height   = a->GetHeight();\n\n\n    BYTE *pd;\n    const BYTE *pa, *pb, *a_data = a->GetReadPtr();\n    int   a_pitch = a->GetPitch();\n\n    int switch_line = (int)(lps * (1.0 - frac_f));\n    int top = switch_line - (zone>>1);\n    int bottom = switch_line + (zone>>1) - lps;\n    if( bottom > 0 && nsrc > 0 ) {\n    // Finish the transition from the previous frame\n      switch_line -= lps;\n      top -= lps;\n      nsrc--;\n      b = a;\n      a = child->GetFrame( nsrc, env );\n      b_pitch = a_pitch;\n      b_data  = a_data;\n      a_data  = a->GetReadPtr();\n      a_pitch = a->GetPitch();\n    } else if( top >= height )\n      return a;\n\n    // Result goes into a new buffer since it can be made up of a number of source frames\n    PVideoFrame d = env->NewVideoFrameP(vi, &a);\n    BYTE* data   = d->GetWritePtr();\n    const int      pitch  = d->GetPitch();\n    if( top > 0 )\n      env->BitBlt( data, pitch, a_data, a_pitch, row_size, top );\nloop:\n    bottom = min( switch_line + (zone>>1), height );\n    int safe_top = max(top,0);\n    pd = data   + safe_top * pitch;\n    pa = a_data + safe_top * a_pitch;\n    pb = b_data + safe_top * b_pitch;\n    for( int y = safe_top; y < bottom; y++ ) {\n      int scale = y - top;\n      for( int x = 0; x < row_size; x++ )\n        pd[x] = BYTE(pa[x] + ((pb[x] - pa[x]) * scale + (zone>>1)) / zone);\n      pd += pitch;\n      pa += a_pitch;\n      pb += b_pitch;\n    }\n    switch_line += lps;\n    top = switch_line - (zone>>1);\n    int limit = min(height,top);\n    if( bottom < limit ) {\n      pd = data   + bottom * pitch;\n      pb = b_data + bottom * b_pitch;\n      env->BitBlt( pd, pitch, pb, b_pitch, row_size, limit-bottom );\n    }\n    if( top < height ) {\n      nsrc++;\n      a = b;\n      b = child->GetFrame(nsrc+1, env);\n      a_pitch = b_pitch;\n      b_pitch = b->GetPitch();\n      a_data  = b_data;\n      b_data  = b->GetReadPtr();\n      goto loop;\n    }\n    return d;\n  }\n}\n\n\nbool __stdcall ConvertFPS::GetParity(int n)\n{\n  if( vi.IsFieldBased())\n    return child->GetParity(0) ^ (n&1);\n  else\n    return child->GetParity(0);\n}\n\nAVSValue __cdecl ConvertFPS::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  return new ConvertFPS( args[0].AsClip(), args[1].AsInt(), args[2].AsInt(1),\n                         args[3].AsInt(-1), args[4].AsInt(0), env );\n}\n\n\nAVSValue __cdecl ConvertFPS::CreateFloat(AVSValue args, void*, IScriptEnvironment* env)\n{\n  uint32_t num, den;\n\n  FloatToFPS(\"ConvertFPS\", (float)args[1].AsFloat(), num, den, env);\n  return new ConvertFPS( args[0].AsClip(), num, den, args[2].AsInt(-1), args[3].AsInt(0), env );\n}\n\n// Tritical Jan 2006\nAVSValue __cdecl ConvertFPS::CreatePreset(AVSValue args, void*, IScriptEnvironment* env)\n{\n  uint32_t num, den;\n\n  PresetToFPS(\"ConvertFPS\", args[1].AsString(), num, den, env);\n  return new ConvertFPS(args[0].AsClip(), num, den, args[2].AsInt(-1), args[3].AsInt(0), env);\n}\n\nAVSValue __cdecl ConvertFPS::CreateFromClip(AVSValue args, void*, IScriptEnvironment* env)\n{\n  const VideoInfo& vi = args[1].AsClip()->GetVideoInfo();\n\n  if (!vi.HasVideo()) {\n    env->ThrowError(\"ConvertFPS: The clip supplied to get the FPS from must contain video.\");\n  }\n\n  return new ConvertFPS( args[0].AsClip(), vi.fps_numerator, vi.fps_denominator,\n                         args[2].AsInt(-1), args[3].AsInt(0), env );\n}\n"
  },
  {
    "path": "avs_core/filters/fps.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n#ifndef __FPS_H__\n#define __FPS_H__\n\n#include <stdint.h>\n#include <avisynth.h>\n#include \"../core/internal.h\"\n\n/********************************************************************\n********************************************************************/\n\nAVSValue __cdecl ContinuedCreate(AVSValue args, void* key, IScriptEnvironment* env);\n\nvoid FloatToFPS(const char *name, float n, unsigned &num, unsigned &den, IScriptEnvironment* env);\n\nvoid PresetToFPS(const char *name, const char *p, unsigned &num, unsigned &den, IScriptEnvironment* env);\n\nclass AssumeScaledFPS : public NonCachedGenericVideoFilter\n/**\n  * Class to change the framerate without changing the frame count\n **/\n{\npublic:\n  AssumeScaledFPS(PClip _child, int multiplier, int divisor, bool sync_audio, IScriptEnvironment* env);\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n};\n\n\nclass AssumeFPS : public NonCachedGenericVideoFilter\n/**\n  * Class to change the framerate without changing the frame count\n **/\n{\npublic:\n  AssumeFPS(PClip _child, unsigned numerator, unsigned denominator, bool sync_audio, IScriptEnvironment* env);\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n  static AVSValue __cdecl CreateFloat(AVSValue args, void*, IScriptEnvironment* env);\n  static AVSValue __cdecl CreatePreset(AVSValue args, void*, IScriptEnvironment* env);\n  static AVSValue __cdecl CreateFromClip(AVSValue args, void*, IScriptEnvironment* env);\n};\n\n\nclass ChangeFPS : public GenericVideoFilter\n/**\n  * Class to change the framerate, deleting or adding frames as necessary\n **/\n{\npublic:\n  ChangeFPS(PClip _child, unsigned new_numerator, unsigned new_denominator, bool linear, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n  bool __stdcall GetParity(int n) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    //todo: not really sure if it has to be serialized or can do with multiple instances\n    return cachehints == CACHE_GET_MTMODE ? MT_SERIALIZED : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n  static AVSValue __cdecl CreateFloat(AVSValue args, void*, IScriptEnvironment* env);\n  static AVSValue __cdecl CreatePreset(AVSValue args, void*, IScriptEnvironment* env);\n  static AVSValue __cdecl CreateFromClip(AVSValue args, void*, IScriptEnvironment* env);\n\nprivate:\n  int64_t a, b;\n  bool linear;\n  int lastframe;\n};\n\n\n\nclass ConvertFPS : public GenericVideoFilter\n/**\n  * Class to change the framerate, attempting to smooth the transitions\n **/\n{\npublic:\n  ConvertFPS( PClip _child, unsigned new_numerator, unsigned new_denominator, int _zone,\n              int _vbi, IScriptEnvironment* env );\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n  bool __stdcall GetParity(int n) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n  static AVSValue __cdecl CreateFloat(AVSValue args, void*, IScriptEnvironment* env);\n  static AVSValue __cdecl CreatePreset(AVSValue args, void*, IScriptEnvironment* env);\n  static AVSValue __cdecl CreateFromClip(AVSValue args, void*, IScriptEnvironment* env);\n\nprivate:\n  int64_t fa, fb;\n  int zone;\n//Variables used in switch mode only\n  int vbi;    //Vertical Blanking Interval (lines)\n  int lps;    //Lines per source frame\n};\n\n\n#endif  // __FPS_H_\n"
  },
  {
    "path": "avs_core/filters/greyscale.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include \"greyscale.h\"\n#ifdef INTEL_INTRINSICS\n#include \"intel/greyscale_sse.h\"\n#endif\n#include \"../core/internal.h\"\n#include <avs/alignment.h>\n#include <avs/minmax.h>\n\n#ifdef AVS_WINDOWS\n    #include <avs/win.h>\n#else\n    #include <avs/posix.h>\n#endif\n\n#include <stdint.h>\n#include \"../convert/convert_planar.h\"\n#include \"../convert/convert.h\"\n#include \"../convert/convert_helper.h\"\n\n\n/*************************************\n *******   Convert to Greyscale ******\n ************************************/\n\nextern const AVSFunction Greyscale_filters[] = {\n  { \"Greyscale\", BUILTIN_FUNC_PREFIX, \"c[matrix]s\", Greyscale::Create },       // matrix can be \"rec601\", \"rec709\" or \"Average\" or \"rec2020\"\n  { \"Grayscale\", BUILTIN_FUNC_PREFIX, \"c[matrix]s\", Greyscale::Create },\n  { 0 }\n};\n\nGreyscale::Greyscale(PClip _child, const char* matrix_name, IScriptEnvironment* env)\n  : GenericVideoFilter(_child), coeff_int16_overflow(false)\n{\n  if (matrix_name && !vi.IsRGB())\n    env->ThrowError(\"GreyScale: invalid \\\"matrix\\\" parameter (RGB data only)\");\n\n  // originally there was no PC range here\n  pixelsize = vi.ComponentSize();\n  bits_per_pixel = vi.BitsPerComponent();\n\n  // In all cases, Luma range is not changed(0-255 in -> 0-255 out; 16-235 in -> 16-235 out)\n\n  if (vi.IsRGB()) {\n    auto frame0 = _child->GetFrame(0, env);\n    const AVSMap* props = env->getFramePropsRO(frame0);\n    // input _ColorRange frame property can appear for RGB source (studio range limited rgb)\n    matrix_parse_merge_with_props(true /*in rgb*/, true /*out rgb, same range*/, matrix_name, props, theMatrix, theColorRange, theOutColorRange, env);\n    /*if (theColorRange == ColorRange_Compat_e::AVS_COLORRANGE_FULL && theMatrix != Matrix_e::AVS_MATRIX_AVERAGE)\n      env->ThrowError(\"GreyScale: only limited range matrix definition or \\\"Average\\\" is allowed.\");\n    */\n\n    const int shift = 15; // internally 15 bits precision, still no overflow in calculations\n    // From the matrix, only Y (luma) coefficients are used.\n    // Upscaled coeffs will have to fit into the signed 16 bit range (SSE2 SIMD code MADD!), so all Y coeffs must be < 1.0.\n    // Even 1.0 will overflow, when upscaled by 2^15.\n\n    // input _ColorRange frame property can appear for RGB source (studio range limited rgb)\n    if (!do_BuildMatrix_Rgb2Yuv(theMatrix, theColorRange, theOutColorRange, shift, bits_per_pixel, /*ref*/greyMatrix))\n      env->ThrowError(\"GreyScale: Unknown matrix.\");\n    if (bits_per_pixel <= 16) {\n      // all y coeffs must be [-1.0;1.0) to fit into signed 16 bit when upscaled by 2^15,\n      // in order to use int16 arithmetic for the conversion.\n      // The only suspicious case is AVS_MATRIX_RGB which returns G for Y in greyscale (RGB is otherwise the IDENTITY matrix)\n      // Greyscale SSE2 SIMD must work with valid coefficients\n      const int max_coeff = (1 << shift) - 1; // 32767 in 15 bit fixed point, maximum positive\n      const int min_coeff = -(1 << shift);    // -32768\n      if (greyMatrix.y_r > max_coeff || greyMatrix.y_r < min_coeff ||\n        greyMatrix.y_g > max_coeff || greyMatrix.y_g < min_coeff ||\n        greyMatrix.y_b > max_coeff || greyMatrix.y_b < min_coeff)\n      {\n        coeff_int16_overflow = true;\n        // env->ThrowError(\"GreyScale: one ore more matrix coefficient is out of valid range for GreyScale filter.\");\n      }\n    }\n\n  }\n  // greyscale does not change color space, rgb remains rgb\n  // Leave matrix and range frame properties as is.\n}\n\ntemplate<typename pixel_t, int pixel_step>\nstatic void greyscale_packed_rgb_c(BYTE *srcp8, int src_pitch, int width, int height, ConversionMatrix& m) {\n  const bool has_offset_rgb = 0 != m.offset_rgb;\n\n  pixel_t *srcp = reinterpret_cast<pixel_t *>(srcp8);\n  src_pitch /= sizeof(pixel_t);\n\n  // .15 bit frac integer arithmetic\n  const int rounder_and_luma_offset = (1 << 14) + (m.offset_y << 15);\n  // greyscale RGB is putting pack the calculated pixels to rgb\n  // Limited range input remains limited range output (-offset_rgb is the same as offset_y)\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; ++x) {\n      int b = srcp[x * pixel_step + 0];\n      int g = srcp[x * pixel_step + 1];\n      int r = srcp[x * pixel_step + 2];\n      if (has_offset_rgb) {\n        b = b + m.offset_rgb;\n        g = g + m.offset_rgb;\n        r = r + m.offset_rgb;\n      }\n      srcp[x * pixel_step + 0] = srcp[x * pixel_step + 1] = srcp[x * pixel_step + 2] =\n        (m.y_b * b + m.y_g * g + m.y_r * r + rounder_and_luma_offset) >> 15;\n    }\n    srcp += src_pitch;\n  }\n}\n\ntemplate<typename pixel_t>\nstatic void greyscale_planar_rgb_c(BYTE *srcp_r8, BYTE *srcp_g8, BYTE *srcp_b8, int src_pitch, int width, int height, ConversionMatrix& m) {\n  const bool has_offset_rgb = 0 != m.offset_rgb;\n\n  pixel_t *srcp_r = reinterpret_cast<pixel_t *>(srcp_r8);\n  pixel_t *srcp_g = reinterpret_cast<pixel_t *>(srcp_g8);\n  pixel_t *srcp_b = reinterpret_cast<pixel_t *>(srcp_b8);\n  src_pitch /= sizeof(pixel_t);\n\n  // .15 bit frac integer arithmetic\n  const int rounder_and_luma_offset = (1 << 14) + (m.offset_y << 15);\n  // greyscale RGB is putting pack the calculated pixels to rgb\n  // Limited range input remains limited range output (-offset_rgb is the same as offset_y)\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; ++x) {\n      int b = srcp_b[x];\n      int g = srcp_g[x];\n      int r = srcp_r[x];\n      if (has_offset_rgb) {\n        b = b + m.offset_rgb;\n        g = g + m.offset_rgb;\n        r = r + m.offset_rgb;\n      }\n\n      srcp_b[x] = srcp_g[x] = srcp_r[x] =\n        (m.y_b * b + m.y_g * g + m.y_r * r + rounder_and_luma_offset) >> 15;\n    }\n    srcp_r += src_pitch;\n    srcp_g += src_pitch;\n    srcp_b += src_pitch;\n  }\n}\n\nstatic void greyscale_planar_rgb_float_c(BYTE *srcp_r8, BYTE *srcp_g8, BYTE *srcp_b8, int src_pitch, int width, int height, ConversionMatrix& m) {\n  const bool has_offset_rgb = 0 != m.offset_rgb_f;\n\n  float *srcp_r = reinterpret_cast<float *>(srcp_r8);\n  float *srcp_g = reinterpret_cast<float *>(srcp_g8);\n  float *srcp_b = reinterpret_cast<float *>(srcp_b8);\n  src_pitch /= sizeof(float);\n\n  const float luma_offset = m.offset_y_f;\n  // greyscale RGB is putting pack the calculated pixels to rgb\n  // Limited range input remains limited range output (-offset_rgb is the same as offset_y)\n\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; ++x) {\n      float b = srcp_b[x];\n      float g = srcp_g[x];\n      float r = srcp_r[x];\n      if (has_offset_rgb) {\n        b = b + m.offset_rgb_f;\n        g = g + m.offset_rgb_f;\n        r = r + m.offset_rgb_f;\n      }\n      srcp_b[x] = srcp_g[x] = srcp_r[x] =\n        m.y_b_f * b + m.y_g_f * g + m.y_r_f * r + luma_offset;\n    }\n    srcp_r += src_pitch;\n    srcp_g += src_pitch;\n    srcp_b += src_pitch;\n  }\n}\n\n\nPVideoFrame Greyscale::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame frame = child->GetFrame(n, env);\n  if (vi.NumComponents() == 1)\n    return frame;\n\n  env->MakeWritable(&frame);\n  BYTE* srcp = frame->GetWritePtr();\n  int pitch = frame->GetPitch();\n  int height = vi.height;\n  int width = vi.width;\n\n  // greyscale does not change color space, rgb remains rgb\n  // Leave matrix and range frame properties as is.\n\n  if (vi.IsPlanar() && (vi.IsYUV() || vi.IsYUVA())) {\n    // planar YUV, set UV plane to neutral\n    BYTE* dstp_u = frame->GetWritePtr(PLANAR_U);\n    BYTE* dstp_v = frame->GetWritePtr(PLANAR_V);\n    const int height = frame->GetHeight(PLANAR_U);\n    const int rowsizeUV = frame->GetRowSize(PLANAR_U);\n    const int dst_pitch = frame->GetPitch(PLANAR_U);\n    switch (vi.ComponentSize())\n    {\n    case 1:\n      fill_chroma<BYTE>(dstp_u, dstp_v, height, rowsizeUV, dst_pitch, 0x80);\n      break;\n    case 2:\n      fill_chroma<uint16_t>(dstp_u, dstp_v, height, rowsizeUV, dst_pitch, 1 << (vi.BitsPerComponent() - 1));\n      break;\n    case 4:\n      const float shift = 0.0f;\n      fill_chroma<float>(dstp_u, dstp_v, height, rowsizeUV, dst_pitch, shift);\n      break;\n    }\n    return frame;\n  }\n\n  if (vi.IsYUY2()) {\n#ifdef INTEL_INTRINSICS\n    if ((env->GetCPUFlags() & CPUF_SSE2) && width > 4) {\n      greyscale_yuy2_sse2(srcp, width, height, pitch);\n    } else\n#ifdef X86_32\n      if ((env->GetCPUFlags() & CPUF_MMX) && width > 2) {\n        greyscale_yuy2_mmx(srcp, width, height, pitch);\n      } else\n#endif\n#endif\n      {\n        for (int y = 0; y<height; ++y)\n        {\n          for (int x = 0; x<width; x++)\n            srcp[x*2+1] = 128;\n          srcp += pitch;\n        }\n      }\n\n      return frame;\n  }\n#ifdef INTEL_INTRINSICS\n  if(vi.IsRGB64()) {\n    if (env->GetCPUFlags() & CPUF_SSE4_1) {\n      greyscale_rgb64_sse41(srcp, width, height, pitch, greyMatrix);\n      return frame;\n    }\n  }\n\n  if (vi.IsRGB32()) {\n    if (env->GetCPUFlags() & CPUF_SSE2) {\n      if (!coeff_int16_overflow) {\n        greyscale_rgb32_sse2(srcp, width, height, pitch, greyMatrix);\n        return frame;\n      }\n    }\n#ifdef X86_32\n    else if (env->GetCPUFlags() & CPUF_MMX) {\n      if (!coeff_int16_overflow) {\n        greyscale_rgb32_mmx(srcp, width, height, pitch, greyMatrix);\n        return frame;\n      }\n    }\n#endif\n  }\n#endif\n\n  if (vi.IsRGB())\n  {  // RGB C.\n    if (vi.IsPlanarRGB() || vi.IsPlanarRGBA())\n    {\n      BYTE* srcp_g = frame->GetWritePtr(PLANAR_G);\n      BYTE* srcp_b = frame->GetWritePtr(PLANAR_B);\n      BYTE* srcp_r = frame->GetWritePtr(PLANAR_R);\n\n      const int src_pitch = frame->GetPitch(); // same for all planes\n\n      if (pixelsize == 1)\n        greyscale_planar_rgb_c<uint8_t>(srcp_r, srcp_g, srcp_b, src_pitch, vi.width, vi.height, greyMatrix);\n      else if (pixelsize == 2)\n        greyscale_planar_rgb_c<uint16_t>(srcp_r, srcp_g, srcp_b, src_pitch, vi.width, vi.height, greyMatrix);\n      else\n        greyscale_planar_rgb_float_c(srcp_r, srcp_g, srcp_b, src_pitch, vi.width, vi.height, greyMatrix);\n\n      return frame;\n    }\n    // packed RGB\n\n    const int rgb_inc = vi.IsRGB32() || vi.IsRGB64() ? 4 : 3;\n\n    if (pixelsize == 1) { // rgb24/32\n      if (rgb_inc == 3)\n        greyscale_packed_rgb_c<uint8_t, 3>(srcp, pitch, vi.width, vi.height, greyMatrix);\n      else\n        greyscale_packed_rgb_c<uint8_t, 4>(srcp, pitch, vi.width, vi.height, greyMatrix);\n    }\n    else { // rgb48/64\n      if (rgb_inc == 3)\n        greyscale_packed_rgb_c<uint16_t, 3>(srcp, pitch, vi.width, vi.height, greyMatrix);\n      else\n        greyscale_packed_rgb_c<uint16_t, 4>(srcp, pitch, vi.width, vi.height, greyMatrix);\n    }\n\n  }\n  return frame;\n}\n\n\nAVSValue __cdecl Greyscale::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  PClip clip = args[0].AsClip();\n  const VideoInfo& vi = clip->GetVideoInfo();\n\n  if (vi.NumComponents() == 1)\n    return clip;\n\n  return new Greyscale(clip, args[1].AsString(0), env);\n}\n"
  },
  {
    "path": "avs_core/filters/greyscale.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Greyscale_H__\n#define __Greyscale_H__\n\n#include <avisynth.h>\n#include \"../convert/convert_planar.h\"\n\nclass Greyscale : public GenericVideoFilter\n/**\n  * Class to convert video to greyscale\n **/\n{\npublic:\n  Greyscale(PClip _child, const char* matrix, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\nprivate:\n  ConversionMatrix greyMatrix;\n  int theMatrix;\n  int theColorRange;\n  int theOutColorRange;\n  int pixelsize;\n  int bits_per_pixel;\n  bool coeff_int16_overflow;\n\n};\n\n\n\n\n#endif  // __Greyscale_H__\n"
  },
  {
    "path": "avs_core/filters/histogram.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// FIXME: in general: how to display 32 bit floats?\n// Do we have to assume it as if it is used after a limited -> full scale conversion? (preferred - everywhere!)\n// Or with values simply: pixel_8bit / 255.0?\n// Latter logic converts U=240 to (240-128)/255 instead of (240-128)/226 (=0.5)\n// and Y=235 to 235/255 instead of (235-16)/219 (=1.0)\n\n#include \"histogram.h\"\n#include \"../core/info.h\"\n#include \"../core/internal.h\"\n#include \"../convert/convert_planar.h\"\n#include \"../convert/convert_audio.h\"\n#include \"../convert/convert_helper.h\"\n#include \"../convert/convert_matrix.h\"\n#include \"colorbars_const.h\"\n\n#ifdef AVS_WINDOWS\n    #include <avs/win.h>\n#else\n    #include <avs/posix.h>\n#endif\n\n#include <memory>\n#include <avs/minmax.h>\n#include <cstdio>\n#include <cmath>\n#include <stdint.h>\n#include <vector>\n\n\nconstexpr double PI = 3.14159265358979323846; \n// until c++20 <numbers> std::numbers::pi\n\n/********************************************************************\n***** Declare index of new filters for Avisynth's filter engine *****\n********************************************************************/\nextern const AVSFunction Histogram_filters[] = {\n  { \"Histogram\", BUILTIN_FUNC_PREFIX, \"c[mode]s[factor]f[bits]i[keepsource]b[markers]b[matrix]s[graticule]s[targets]b[axes]b[iq]b[iq_lines]b[circle]b[targets100]b\", Histogram::Create },\n  { 0 }\n};\n\n/***********************************\n *******   Histogram Filter   ******\n **********************************/\n\nHistogram::Histogram(PClip _child, Mode _mode, AVSValue _option, int _show_bits, bool _keepsource, bool _markers, const char* _matrix_name, histogram_color2_params _color2_params, IScriptEnvironment* env)\n  : GenericVideoFilter(_child), mode(_mode), option(_option), show_bits(_show_bits), keepsource(_keepsource), markers(_markers), color2_params(_color2_params)\n{\n  bool optionValid = false;\n\n  pixelsize = vi.ComponentSize();\n  bits_per_pixel = vi.BitsPerComponent();\n\n  if(show_bits < 8 || show_bits>12)\n    env->ThrowError(\"Histogram: bits parameter can only be 8, 9 .. 12\");\n\n  // until all histogram is ported\n  bool non8bit = show_bits != 8 || bits_per_pixel != 8;\n\n  if (non8bit && mode != ModeClassic && mode != ModeLevels && mode != ModeColor && mode != ModeColor2 && mode != ModeLuma)\n  {\n    env->ThrowError(\"Histogram: this histogram type is available only for 8 bit formats and parameters\");\n  }\n\n  // Obtain matrix (for YUV) and video range\n  auto frame0 = child->GetFrame(0, env);\n  const AVSMap* props = env->getFramePropsRO(frame0);\n  // default YUV matrix AVS_MATRIX_ST170_M (BT 601)\n  const bool rgb_in = vi.IsRGB();\n  matrix_parse_merge_with_props(rgb_in, rgb_in /* rgb_out n/a */ , _matrix_name, props, theMatrix, theColorRange, theOutColorRange, env);\n\n  // theColorRange is either inherited\n  // - from defaults (RGB full YUV limited) or\n  // - _ColorRange frame property or\n  // - manual override from \"matrix\" param \":f\" or \":l\" designator\n  // theOutColorRange is only used in yuv-rgb converters\n  full_range = theColorRange == ColorRange_Compat_e::AVS_COLORRANGE_FULL;\n  // Full range or limited?\n  // VectorScope modes (color, color2) require full range to\n  // - properly place the color boxes\n  // - When the histogram's virtual bit-size is different from the real video bit-depth\n  //   then video-bit depth must be converted to the histogram's bit-depth either by\n  //   limited (shift) or full range (stretch) method.\n\n  const int shift = 13; // not used here, we only get the floating point matrix\n  // use matrix coeffs in color/color2 for positioning RGB color boxes for the actual YUV matrix.\n  // Detected input color range is theColorRange, detected matrix is theMatrix.\n  if (!do_BuildMatrix_Rgb2Yuv(theMatrix, theColorRange, theOutColorRange, shift, 32, /*ref*/matrix))\n    env->ThrowError(\"Histogram: Unsupported matrix.\");\n\n  origwidth = vi.width;\n  origheight = vi.height;\n\n  if (mode == ModeClassic) {\n    if (!vi.IsYUV() && !vi.IsYUVA())\n      env->ThrowError(\"Histogram: YUV(A) data only\");\n    if(keepsource)\n      vi.width += (1 << show_bits);\n    else\n      vi.width = (1 << show_bits);\n    ClassicLUTInit();\n  }\n\n  if (mode == ModeLevels) {\n    if (!vi.IsPlanar()) {\n      env->ThrowError(\"Histogram: Levels mode only available in PLANAR.\");\n    }\n    optionValid = option.IsFloat();\n    const double factor = option.AsDblDef(100.0); // Population limit % factor\n    if (factor < 0.0 || factor > 100.0) {\n      env->ThrowError(\"Histogram: Levels population clamping must be between 0 and 100%\");\n    }\n    // put diagram on the right side\n    if (keepsource) {\n      vi.width += (1 << show_bits); // 256 for 8 bit\n      vi.height = max(256, vi.height);\n    }\n    else { // or keep it alone\n      vi.width = (1 << show_bits);\n      vi.height = 256; // only 224+1 (3*64 + 2*16 + 1) is used\n    }\n  }\n\n  if (mode == ModeColor || mode == ModeColor2) {\n    if (vi.IsRGB()) {\n      env->ThrowError(\"Histogram: VectorScope modes (color, color2) are not available in RGB.\");\n    }\n    if (!vi.IsPlanar()) {\n      env->ThrowError(\"Histogram: VectorScope modes (color, color2) only available in PLANAR.\");\n    }\n    if (vi.IsY()) {\n      env->ThrowError(\"Histogram: VectorScope modes (color, color2) are not available in greyscale.\");\n    }\n    // put diagram on the right side\n    if (keepsource) {\n      vi.width += (1 << show_bits); // 256 for 8 bit\n      vi.height = max(1 << show_bits, vi.height);\n    }\n    else {\n      vi.width = (1 << show_bits); // 256 for 8 bit\n      vi.height = 1 << show_bits;\n    }\n\n    // for params.circle == true\n    // precalculate 15 degree marker dots\n    if (color2_params.circle) {\n      const int half = (1 << (show_bits - 1)) - 1; // 127\n      // dots are placed somewhat inside to the colorful circle, which is thicker for higher show_bits\n      color2_innerF = 124.9;  // .9 is for better visuals in subsampled mode\n      int R = (int)(1 + color2_innerF * (1 << (show_bits - 8)) + 0.5); // 126 for 8 bits\n\n      for (int y = 0; y < 24; y++) { // just inside the big circle\n        deg15c[y] = (int)(R * cos(y * PI / 12.) + 0.5) + half;\n        deg15s[y] = (int)(-R * sin(y * PI / 12.) + 0.5) + half;\n      }\n    }\n  }\n\n  if (mode == ModeLuma && !vi.IsYUV() && !vi.IsYUVA()) {\n      env->ThrowError(\"Histogram: Luma mode only available in YUV(A).\");\n  }\n\n  if ((mode == ModeStereoY8)||(mode == ModeStereo)||(mode == ModeOverlay)) {\n\n    child->SetCacheHints(CACHE_AUDIO,4096*1024);\n\n    if (!vi.HasVideo()) {\n      mode = ModeStereo; // force mode to ModeStereo.\n      vi.fps_numerator = 25;\n      vi.fps_denominator = 1;\n      vi.num_frames = vi.FramesFromAudioSamples(vi.num_audio_samples);\n    }\n    if (mode == ModeOverlay)  {\n      if (keepsource) {\n        vi.height = max(512, vi.height);\n        vi.width = max(512, vi.width);\n      }\n      else {\n        vi.height = 512;\n        vi.width = 512;\n      }\n      if (vi.IsRGB()) {\n        env->ThrowError(\"Histogram: StereoOverlay mode is not available in RGB.\");\n      }\n      if (!vi.IsPlanar()) {\n        env->ThrowError(\"Histogram: StereoOverlay only available in Y or YUV(A).\");\n      }\n    } else if (mode == ModeStereoY8) {\n      vi.pixel_type = VideoInfo::CS_Y8;\n      vi.height = 512;\n      vi.width = 512;\n    } else {\n      vi.pixel_type = VideoInfo::CS_YV12;\n      vi.height = 512;\n      vi.width = 512;\n    }\n    if (!vi.HasAudio()) {\n      env->ThrowError(\"Histogram: Stereo mode requires samples!\");\n    }\n    if (vi.AudioChannels() != 2) {\n      env->ThrowError(\"Histogram: Stereo mode only works on two audio channels.\");\n    }\n\n     aud_clip = ConvertAudio::Create(child,SAMPLE_INT16,SAMPLE_INT16);\n  }\n\n  if (mode == ModeAudioLevels) {\n    child->SetCacheHints(CACHE_AUDIO, 4096*1024);\n    if (vi.IsRGB()) {\n      env->ThrowError(\"Histogram: Audiolevels mode is not available in RGB.\");\n    }\n    if (!vi.IsPlanar()) {\n      env->ThrowError(\"Histogram: Audiolevels mode only available in planar YUV.\");\n    }\n    if (vi.IsY8()) {\n      env->ThrowError(\"Histogram: AudioLevels mode not available in Y8.\");\n    }\n\n    aud_clip = ConvertAudio::Create(child, SAMPLE_INT16, SAMPLE_INT16);\n  }\n\n  if (!optionValid && option.Defined())\n    env->ThrowError(\"Histogram: Unknown optional value.\");\n}\n\nPVideoFrame __stdcall Histogram::GetFrame(int n, IScriptEnvironment* env)\n{\n  switch (mode) {\n  case ModeClassic:\n    return DrawModeClassic(n, env);\n  case ModeLevels:\n    return DrawModeLevels(n, env);\n  case ModeColor:\n    return DrawModeColor(n, env);\n  case ModeColor2:\n    return DrawModeColor2(n, env);\n  case ModeLuma:\n    return DrawModeLuma(n, env);\n  case ModeStereoY8:\n  case ModeStereo:\n    return DrawModeStereo(n, env);\n  case ModeOverlay:\n    return DrawModeOverlay(n, env);\n  case ModeAudioLevels:\n    return DrawModeAudioLevels(n, env);\n  }\n  return DrawModeClassic(n, env);\n}\n\ninline void MixLuma(BYTE &src, int value, int alpha) {\n  src = src + BYTE(((value - (int)src) * alpha) >> 8);\n}\n\nPVideoFrame Histogram::DrawModeAudioLevels(int n, IScriptEnvironment* env) {\n  PVideoFrame src = child->GetFrame(n, env);\n  env->MakeWritable(&src);\n  const int w = src->GetRowSize();\n  const int channels = vi.AudioChannels();\n\n  constexpr int TEXT_HEIGHT = 20; // for DrawString\n  int bar_w = 60;  // Must be divideable by 4 (for subsampling)\n  int total_width = (1+channels*2)*bar_w; // Total width in pixels.\n\n  if (total_width > w) {\n    bar_w = ((w / (1+channels*2)) / 4)* 4;\n  }\n  total_width = (1+channels*2)*bar_w; // Total width in pixels.\n  int bar_h = vi.height;\n\n  // Get audio for current frame.\n  const int64_t start = vi.AudioSamplesFromFrames(n);\n  const int count = (int)(vi.AudioSamplesFromFrames(1));\n  signed short* samples = static_cast<signed short*>(_alloca(sizeof(signed short)* count * channels));\n\n  aud_clip->GetAudio(samples, max((int64_t)0ll,start), count, env);\n\n  // Find maximum volume and rms.\n  int*     channel_max = static_cast<int*>(_alloca(channels * sizeof(int)));\n  int64_t* channel_rms = static_cast<int64_t*>(_alloca(channels * sizeof(int64_t)));;\n\n  const int c = count*channels;\n  for (int ch = 0; ch<channels; ch++) {\n    int max_vol = 0;\n    int64_t rms_vol = 0;\n\n    for (int i = ch; i < c; i += channels) {\n      int sample = samples[i];\n      sample *= sample;\n      rms_vol += sample;\n      max_vol = max(max_vol, sample);\n    }\n    channel_max[ch] = max_vol;\n    channel_rms[ch] = rms_vol;\n  }\n\n  // Draw bars\n  BYTE* srcpY = src->GetWritePtr(PLANAR_Y);\n  int Ypitch = src->GetPitch(PLANAR_Y);\n  BYTE* srcpU = src->GetWritePtr(PLANAR_U);\n  BYTE* srcpV = src->GetWritePtr(PLANAR_V);\n  int UVpitch = src->GetPitch(PLANAR_U);\n  int xSubS = vi.GetPlaneWidthSubsampling(PLANAR_U);\n  int ySubS = vi.GetPlaneHeightSubsampling(PLANAR_U);\n\n  // Draw Dotted lines\n  const int lines = 16;  // Line every 6dB  (96/6)\n  int lines_y[lines];\n  float line_every = (float)bar_h / (float)lines;\n  char text[32];\n  for (int i=0; i<lines; i++) {\n    lines_y[i] = (int)(line_every*i);\n    if (!(i&1)) {\n      snprintf(text, sizeof(text), \"%3ddB\", -i*6);\n      DrawStringPlanar(vi, src, 0, i ? lines_y[i] : TEXT_HEIGHT / 2, text);\n    }\n  }\n  for (int x=bar_w-16; x<total_width-bar_w+16; x++) {\n    if (!(x&12)) {\n      for (int i=0; i<lines; i++) {\n        srcpY[x+lines_y[i]*Ypitch] = 200;\n      }\n    }\n  }\n\n  for (int ch = 0; ch<channels; ch++) {\n    int max = channel_max[ch];\n    double ch_db = 96;\n    if (max > 0) {\n      ch_db = -8.685889638/2.0 * log((double)max/(32768.0*32768.0));\n    }\n\n    int64_t rms = channel_rms[ch] / count;\n    double ch_rms = 96;\n    if (rms > 0) {\n      ch_rms = -8.685889638/2.0 * log((double)rms/(32768.0*32768.0));\n    }\n\n    int x_pos = ((ch*2)+1)*bar_w+8;\n    int x_end = x_pos+bar_w-8;\n    int y_pos = (int)(((double)bar_h*ch_db) / 96.0);\n    int y_mid = (int)(((double)bar_h*ch_rms) / 96.0);\n    int y_end = src->GetHeight(PLANAR_Y);\n    // Luma                          Red   Blue\n    int y_val = (max>=32767*32767) ? 78 : 90;\n    int a_val = (max>=32767*32767) ? 96 : 128;\n    for (int y = y_pos; y<y_mid; y++) {\n      for (int x = x_pos; x < x_end; x++) {\n        MixLuma(srcpY[x+y*Ypitch], y_val, a_val);\n      }\n    } //                      Yellow Green\n    y_val = (max>=32767*32767) ? 216 : 137;\n    a_val = (max>=32767*32767) ? 160 : 128;\n    for (int y = y_mid; y<y_end; y++) {\n      for (int x = x_pos; x < x_end; x++) {\n        MixLuma(srcpY[x+y*Ypitch], y_val, a_val);\n      }\n    }\n    // Chroma\n    x_pos >>= xSubS;\n    x_end >>= xSubS;\n    y_pos >>= ySubS;\n    y_mid >>= ySubS;\n    y_end = src->GetHeight(PLANAR_U);//Red  Blue\n    BYTE u_val = (max>=32767*32767) ? 92 : 212;\n    BYTE v_val = (max>=32767*32767) ? 233 : 114;\n    for (int y = y_pos; y<y_mid; y++) {\n      for (int x = x_pos; x < x_end; x++) {\n        srcpU[x+y*UVpitch] = u_val;\n        srcpV[x+y*UVpitch] = v_val;\n      }\n    } //                      Yellow Green\n    u_val = (max>=32767*32767) ? 44 : 58;\n    v_val = (max>=32767*32767) ? 142 : 40;\n    for (int y = y_mid; y<y_end; y++) {\n      for (int x = x_pos; x < x_end; x++) {\n        srcpU[x+y*UVpitch] = u_val;\n        srcpV[x+y*UVpitch] = v_val;\n      }\n    }\n    // Draw text\n    snprintf(text, sizeof(text), \"%6.2fdB\", (float)-ch_db);\n    DrawStringPlanar(vi, src, ((ch*2)+1)*bar_w, vi.height- 2 * TEXT_HEIGHT + TEXT_HEIGHT / 2, text);\n    snprintf(text, sizeof(text), \"%6.2fdB\", (float)-ch_rms);\n    DrawStringPlanar(vi, src, ((ch*2)+1)*bar_w, vi.height- 1 * TEXT_HEIGHT + TEXT_HEIGHT / 2, text);\n\n  }\n\n  return src;\n}\n\nPVideoFrame Histogram::DrawModeOverlay(int n, IScriptEnvironment* env) {\n  PVideoFrame src = child->GetFrame(n, env);\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n\n  int64_t start = vi.AudioSamplesFromFrames(n);\n  int64_t end = vi.AudioSamplesFromFrames(n+1);\n  int64_t count = end-start;\n  signed short* samples = static_cast<signed short*>(\n    env->Allocate((int)count * vi.AudioChannels() * sizeof(unsigned short), 8, AVS_POOLED_ALLOC)\n  );\n  if (!samples) {\n    env->ThrowError(\"Histogram: Could not reserve memory.\");\n  }\n\n  int h = dst->GetHeight();\n  int imgSize = h*dst->GetPitch();\n  BYTE* dstp = dst->GetWritePtr();\n  int p = dst->GetPitch(PLANAR_Y);\n\n  if ((src->GetHeight()<dst->GetHeight()) || (src->GetRowSize() < dst->GetRowSize())) {\n    memset(dstp, 16, imgSize);\n    int imgSizeU = dst->GetHeight(PLANAR_U) * dst->GetPitch(PLANAR_U);\n    if (imgSizeU) {\n      memset(dst->GetWritePtr(PLANAR_U), 128, imgSizeU);\n      memset(dst->GetWritePtr(PLANAR_V), 128, imgSizeU);\n    }\n  }\n\n  env->BitBlt(dstp, dst->GetPitch(), src->GetReadPtr(), src->GetPitch(), src->GetRowSize(), src->GetHeight());\n  env->BitBlt(dst->GetWritePtr(PLANAR_U), dst->GetPitch(PLANAR_U), src->GetReadPtr(PLANAR_U), src->GetPitch(PLANAR_U), src->GetRowSize(PLANAR_U), src->GetHeight(PLANAR_U));\n  env->BitBlt(dst->GetWritePtr(PLANAR_V), dst->GetPitch(PLANAR_V), src->GetReadPtr(PLANAR_V), src->GetPitch(PLANAR_V), src->GetRowSize(PLANAR_V), src->GetHeight(PLANAR_V));\n\n  BYTE* _dstp = dstp;\n  for (int iY = 0; iY<512; iY++) {\n    for (int iX = 0; iX<512; iX++) {\n      _dstp[iX] >>= 1;\n    }\n    _dstp+=p;\n  }\n\n  aud_clip->GetAudio(samples, max((int64_t)0ll,start), count, env);\n\n  int c = (int)count;\n  for (int i=1; i < c;i++) {\n    int l1 = samples[i*2-2];\n    int r1 = samples[i*2-1];\n    int l2 = samples[i*2];\n    int r2 = samples[i*2+1];\n    for (int s = 0 ; s < 8; s++) {  // 8 times supersampling (linear)\n      int l = (l1*s) + (l2*(8-s));\n      int r = (r1*s) + (r2*(8-s));\n      int y = 256+((l+r)>>11);\n      int x = 256+((l-r)>>11);\n      BYTE v = dstp[x+y*p]+48;\n      dstp[x+y*p] = min(v,(BYTE)235);\n    }\n  }\n\n  int y_off = p*256;\n  for (int x = 0; x < 512; x+=16)\n    dstp[y_off + x] = (dstp[y_off + x] > 127) ? 16 : 235;\n\n  for (int y = 0; y < 512;y+=16)\n    dstp[y*p+256] = (dstp[y*p+256]>127) ? 16 : 235 ;\n\n  env->Free(samples);\n  return dst;\n}\n\n\nPVideoFrame Histogram::DrawModeStereo(int n, IScriptEnvironment* env) {\n  PVideoFrame src = env->NewVideoFrame(vi);\n  int64_t start = vi.AudioSamplesFromFrames(n);\n  int64_t end = vi.AudioSamplesFromFrames(n+1);\n  int64_t count = end-start;\n  signed short* samples = static_cast<signed short*>(\n    env->Allocate((int)count * vi.AudioChannels() * sizeof(unsigned short), 8, AVS_POOLED_ALLOC)\n  );\n  if (!samples) {\n    env->ThrowError(\"Histogram: Could not reserve memory.\");\n  }\n\n  int h = src->GetHeight();\n  int imgSize = h*src->GetPitch();\n  BYTE* srcp = src->GetWritePtr();\n  memset(srcp, 16, imgSize);\n  int p = src->GetPitch();\n\n  aud_clip->GetAudio(samples, max((int64_t)0ll,start), count, env);\n\n  int c = (int)count;\n  for (int i=1; i < c;i++) {\n    int l1 = samples[i*2-2];\n    int r1 = samples[i*2-1];\n    int l2 = samples[i*2];\n    int r2 = samples[i*2+1];\n    for (int s = 0 ; s < 8; s++) {  // 8 times supersampling (linear)\n      int l = (l1*s) + (l2*(8-s));\n      int r = (r1*s) + (r2*(8-s));\n      int y = 256+((l+r)>>11);\n      int x = 256+((l-r)>>11);\n      BYTE v = srcp[x+y*512]+48;\n      srcp[x+y*512] = min(v, (BYTE)235);\n    }\n  }\n\n  int y_off = p*256;\n  for (int x = 0; x < 512; x+=16)\n    srcp[y_off + x] = (srcp[y_off + x] > 127) ? 16 : 235;\n\n  for (int y = 0; y < 512;y+=16)\n    srcp[y*p+256] = (srcp[y*p+256]>127) ? 16 : 235 ;\n\n  if (vi.IsYV12()) {\n    srcp = src->GetWritePtr(PLANAR_U);\n    imgSize = src->GetHeight(PLANAR_U) * src->GetPitch(PLANAR_U);\n    memset(srcp, 128, imgSize);\n    srcp = src->GetWritePtr(PLANAR_V);\n    memset(srcp, 128, imgSize);\n  }\n\n  env->Free(samples);\n  return src;\n}\n\n\nPVideoFrame Histogram::DrawModeLuma(int n, IScriptEnvironment* env) {\n  // amplify luminance.\n  // In this mode a 1 pixel luminance difference (8 bits world) will show as \n  // a 16 pixel luminance, thus seriously enhancing small flaws\n  PVideoFrame src = child->GetFrame(n, env);\n  env->MakeWritable(&src);\n  const int h = src->GetHeight();\n  BYTE* srcp = src->GetWritePtr();\n  if (vi.IsYUY2()) {\n    int imgsize = h * src->GetPitch();\n    for (int i=0; i<imgsize; i+=2) {\n      int p = srcp[i];\n      p<<=4;\n      srcp[i+1] = 128;\n      srcp[i] = BYTE((p&256) ? (255-(p&0xff)) : p&0xff);\n    }\n  } else {\n    const int w = vi.width;\n    const int pitch = src->GetPitch();\n    if (bits_per_pixel == 8) {\n      for (int y = 0; y < h; y++) {\n        for (int x = 0; x < w; x++) {\n          const int pixel = srcp[x] << 4; // *16\n          srcp[x] = BYTE((pixel & 256) ? (255 - (pixel & 0xff)) : pixel & 0xff);\n        }\n        srcp += pitch;\n      }\n    }\n    else if (bits_per_pixel <= 16) {\n      const int overlimit = (1 << bits_per_pixel);\n      const int max_pixel_value = (1 << bits_per_pixel) - 1;\n      for (int y = 0; y < h; y++) {\n        for (int x = 0; x < w; x++) {\n          const int pixel = reinterpret_cast<uint16_t*>(srcp)[x] << 4;\n          reinterpret_cast<uint16_t*>(srcp)[x] = (uint16_t)((pixel & overlimit) ? (max_pixel_value - (pixel & max_pixel_value)) : pixel & max_pixel_value);\n        }\n        srcp += pitch;\n      }\n    }\n    else {\n      // 32 bit float\n      // just simulated by converting to 8 bits\n      for (int y = 0; y < h; y++) {\n        for (int x = 0; x < w; x++) {\n          const float pixel_f = reinterpret_cast<float*>(srcp)[x];\n          const int pixel_i = (int)(pixel_f * 255.0f + 0.5f);\n          const int pixel = pixel_i << 4; // *16\n          int pixel_out = BYTE((pixel & 256) ? (255 - (pixel & 0xff)) : pixel & 0xff);\n          const float pixel_out_f = pixel_out / 255.0f;\n          reinterpret_cast<float*>(srcp)[x] = pixel_out_f;\n        }\n        srcp += pitch;\n      }\n    }\n    \n    if (vi.NumComponents() >= 3) {\n      auto dstp_u = src->GetWritePtr(PLANAR_U);\n      auto dstp_v = src->GetWritePtr(PLANAR_V);\n      auto height_uv = src->GetHeight(PLANAR_U);\n      auto rowsize_uv = src->GetRowSize(PLANAR_U);\n      auto pitch_uv = src->GetPitch(PLANAR_U);\n      if (bits_per_pixel == 8)\n        fill_chroma<uint8_t>(dstp_u, dstp_v, height_uv, rowsize_uv, pitch_uv, 128);\n      else if (bits_per_pixel <= 16)\n        fill_chroma<uint16_t>(dstp_u, dstp_v, height_uv, rowsize_uv, pitch_uv, 128 << (bits_per_pixel - 8));\n      else // 32)\n        fill_chroma<float>(dstp_u, dstp_v, height_uv, rowsize_uv, pitch_uv, 0.0f);\n\n      // alpha\n      if (vi.NumComponents() == 4) {\n        auto dstp_a = src->GetWritePtr(PLANAR_A);\n        auto height_a = src->GetHeight(PLANAR_A);\n        auto rowsize_a = src->GetRowSize(PLANAR_A);\n        auto pitch_a = src->GetPitch(PLANAR_A);\n        if (bits_per_pixel == 8)\n          fill_plane<uint8_t>(dstp_a, height_a, rowsize_a, pitch_a, 255);\n        else if (bits_per_pixel <= 16)\n          fill_plane<uint16_t>(dstp_a, height_a, rowsize_a, pitch_a, (1 << bits_per_pixel) -  1);\n        else // 32)\n          fill_plane<float>(dstp_a, height_a, rowsize_a, pitch_a, 1.0f);\n      }\n    }\n  }\n  return src;\n}\n\ntemplate<typename pixel_t>\nstatic void DrawModeColor2_DrawRect(\n  pixel_t* dstp, int pitch,\n  pixel_t* dstpU, pixel_t* dstpV, int pitchUV,\n  int cx, int cy,          // center in luma coords\n  int half_w, int half_h,  // half-size in luma coords\n  int swidth, int sheight,\n  pixel_t luma_val,\n  pixel_t u_val, pixel_t v_val,\n  int limit_showwidth // bounds check\n)\n{\n  // Draw horizontal top/bottom edges (luma)\n  for (int x = cx - half_w; x <= cx + half_w; x++) {\n    if (x < 0 || x >= limit_showwidth) continue;\n    int y_top = cy - half_h;\n    int y_bot = cy + half_h;\n    if (y_top >= 0 && y_top < limit_showwidth)\n      dstp[x + y_top * pitch] = luma_val;\n    if (y_bot >= 0 && y_bot < limit_showwidth)\n      dstp[x + y_bot * pitch] = luma_val;\n  }\n\n  // Draw vertical left/right edges (luma)\n  for (int y = cy - half_h; y <= cy + half_h; y++) {\n    if (y < 0 || y >= limit_showwidth) continue;\n    int x_l = cx - half_w;\n    int x_r = cx + half_w;\n    if (x_l >= 0 && x_l < limit_showwidth)\n      dstp[x_l + y * pitch] = luma_val;\n    if (x_r >= 0 && x_r < limit_showwidth)\n      dstp[x_r + y * pitch] = luma_val;\n  }\n\n  // Chroma planes (subsampled)\n  const int limit_showwidth_uv = limit_showwidth >> swidth;\n  const int limit_showheight_uv = limit_showwidth >> sheight;\n\n  // Convert luma coordinates to chroma coordinates\n  const int cx_uv = cx >> swidth;\n  const int cy_uv = cy >> sheight;\n  const int half_w_uv = half_w >> swidth;\n  const int half_h_uv = half_h >> sheight;\n\n  // Draw horizontal top/bottom edges (chroma)\n  for (int x = cx_uv - half_w_uv; x <= cx_uv + half_w_uv; x++) {\n    if (x < 0 || x >= limit_showwidth_uv) continue;\n    int y_top = cy_uv - half_h_uv;\n    int y_bot = cy_uv + half_h_uv;\n    if (y_top >= 0 && y_top < limit_showheight_uv) {\n      dstpU[x + y_top * pitchUV] = u_val;\n      dstpV[x + y_top * pitchUV] = v_val;\n    }\n    if (y_bot >= 0 && y_bot < limit_showheight_uv) {\n      dstpU[x + y_bot * pitchUV] = u_val;\n      dstpV[x + y_bot * pitchUV] = v_val;\n    }\n  }\n\n  // Draw vertical left/right edges (chroma)\n  for (int y = cy_uv - half_h_uv; y <= cy_uv + half_h_uv; y++) {\n    if (y < 0 || y >= limit_showheight_uv) continue;\n    int x_l = cx_uv - half_w_uv;\n    int x_r = cx_uv + half_w_uv;\n    if (x_l >= 0 && x_l < limit_showwidth_uv) {\n      dstpU[x_l + y * pitchUV] = u_val;\n      dstpV[x_l + y * pitchUV] = v_val;\n    }\n    if (x_r >= 0 && x_r < limit_showwidth_uv) {\n      dstpU[x_r + y * pitchUV] = u_val;\n      dstpV[x_r + y * pitchUV] = v_val;\n    }\n  }\n}\n\n\n// This draws only on luma\ntemplate<typename pixel_t>\nstatic void DrawRadialLine(pixel_t* dstp, int pitch, int limit, int show_bit_shift,\n  double angle_deg, pixel_t val)\n{\n  double angle_rad = angle_deg * M_PI / 180.0;\n  double R = 124.9 * (1 << show_bit_shift); // same as innerF * scale\n  // Step along the radius\n  int steps = (int)(R * 1.5);\n  for (int s = 0; s < steps; s++) {\n    double t = (double)s / steps;\n    int x = (int)(limit + t * R * cos(angle_rad) + 0.5);\n    int y = (int)(limit - t * R * sin(angle_rad) + 0.5); // V is flipped\n    if (x >= 0 && x <= 2 * limit && y >= 0 && y <= 2 * limit)\n      dstp[x + y * pitch] = val;\n  }\n}\n\n// Set to black, alpha to 0.\ntemplate<typename pixel_t>\nstatic void ClearArea(\n  uint8_t* dstp, uint8_t* dstp_u, uint8_t* dstp_v, uint8_t* dstp_a,\n  int width, int widthUV,\n  int pitch, int pitchUV, int pitchA,\n  int height, int heightUV, int heightA,\n  int bits_per_pixel, bool full_range)\n{\n  pixel_t black, middle_chroma, alpha;\n  if constexpr (std::is_integral<pixel_t>::value) {\n    black = full_range ? 0 : (pixel_t)(16 << (bits_per_pixel - 8));\n    middle_chroma = (pixel_t)(128 << (bits_per_pixel - 8));\n    alpha = 0;\n  }\n  else {\n    black = full_range ? 0.0f : 16.0f / 255.0f;\n    middle_chroma = 0.0f;\n    alpha = 0.0f;\n  }\n\n  // Y\n  for (int y = 0; y < height; y++) {\n    std::fill_n((pixel_t*)(dstp + y * pitch), width, black);\n  }\n  // UV\n  for (int y = 0; y < heightUV; y++) {\n    std::fill_n((pixel_t*)(dstp_u + y * pitchUV), widthUV, middle_chroma);\n    std::fill_n((pixel_t*)(dstp_v + y * pitchUV), widthUV, middle_chroma);\n  }\n  // Alpha, dimensions same as luma\n  // heightA is zero if no alpha plane\n  for (int y = 0; y < heightA; y++) {\n    std::fill_n((pixel_t*)(dstp_a + y * pitchA), width, alpha);\n  }\n}\n\n// Common prelude for Color and Color2 modes.\n// Allocates dst, optionally clears the below-source area, copies source planes.\n// Returns the allocated dst frame; populates panel pointer offsets.ű\n// Full_range flag is filled in constructor, not per frame\nPVideoFrame Histogram::VectorscopePrelude(\n  int n, IScriptEnvironment* env,\n  PVideoFrame& src,\n  // outputs:\n  int& dst_pitch, int& dst_height,\n  int& dst_pitchUV, int& dst_heightUV,\n  int& dst_pitchA, int& dst_heightA,\n  BYTE*& panel, BYTE*& panelU, BYTE*& panelV, BYTE*& panelA)\n{\n  src = child->GetFrame(n, env);\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n\n  BYTE *pdst = dst->GetWritePtr();\n  BYTE *pdstU = dst->GetWritePtr(PLANAR_U);\n  BYTE *pdstV = dst->GetWritePtr(PLANAR_V);\n  BYTE *pdstA = dst->GetWritePtr(PLANAR_A);\n\n  dst_pitch = dst->GetPitch();\n  dst_pitchUV = dst->GetPitch(PLANAR_U);\n  dst_pitchA = dst->GetPitch(PLANAR_A);\n  dst_height = dst->GetHeight();\n  dst_heightUV = dst->GetHeight(PLANAR_U);\n  dst_heightA = dst->GetHeight(PLANAR_A);\n\n  const bool has_alpha = dst_heightA > 0;\n\n  const int src_width = src->GetRowSize() / pixelsize;\n  const int src_widthUV = src->GetRowSize(PLANAR_U) / pixelsize;\n  const int src_height = src->GetHeight();\n  const int src_heightUV = src->GetHeight(PLANAR_U);\n\n  const int show_size = 1 << show_bits;\n  const int show_size_w_uv = show_size >> vi.GetPlaneWidthSubsampling(PLANAR_U);\n  const int show_size_h_uv = show_size >> vi.GetPlaneHeightSubsampling(PLANAR_U);\n\n  if (keepsource) {\n\n    if (src_height < dst_height) {\n      // in case of Histogram area is higher than source, clear the area below source copy to black + A=0\n      auto pdst_start = pdst + src_height * dst_pitch;\n      auto pdstU_start = pdstU + src_heightUV * dst_pitchUV;\n      auto pdstV_start = pdstV + src_heightUV * dst_pitchUV;\n      auto pdstA_start = pdstA + src_height * dst_pitchA;\n      const int new_height = dst_height - src_height;\n      const int new_height_uv = dst_heightUV - src_heightUV;\n      const int new_height_a = has_alpha ? new_height : 0;\n\n      if (bits_per_pixel == 8)\n        ClearArea<uint8_t>(pdst_start, pdstU_start, pdstV_start, pdstA_start,\n          src_width, src_widthUV,\n          dst_pitch, dst_pitchUV, dst_pitchA,\n          new_height, new_height_uv, new_height_a,\n          bits_per_pixel, full_range);\n      else if (bits_per_pixel <= 16)\n        ClearArea<uint16_t>(pdst_start, pdstU_start, pdstV_start, pdstA_start,\n          src_width, src_widthUV,\n          dst_pitch, dst_pitchUV, dst_pitchA,\n          new_height, new_height_uv, new_height_a,\n          bits_per_pixel, full_range);\n      else\n        ClearArea<float>(pdst_start, pdstU_start, pdstV_start, pdstA_start,\n          src_width, src_widthUV,\n          dst_pitch, dst_pitchUV, dst_pitchA,\n          new_height, new_height_uv, new_height_a,\n          bits_per_pixel, full_range);\n    }\n    // copy source\n    env->BitBlt(pdst, dst_pitch, src->GetReadPtr(), src->GetPitch(), src->GetRowSize(), src->GetHeight());\n    env->BitBlt(pdstU, dst_pitchUV, src->GetReadPtr(PLANAR_U), src->GetPitch(PLANAR_U), src->GetRowSize(PLANAR_U), src->GetHeight(PLANAR_U));\n    env->BitBlt(pdstV, dst_pitchUV, src->GetReadPtr(PLANAR_V), src->GetPitch(PLANAR_V), src->GetRowSize(PLANAR_V), src->GetHeight(PLANAR_V));\n    if (has_alpha)\n      env->BitBlt(pdstA, dst_pitchA, src->GetReadPtr(PLANAR_A), src->GetPitch(PLANAR_A), src->GetRowSize(PLANAR_A), src->GetHeight(PLANAR_A));\n  }\n\n  // panel is with the offset into the histogram panel area (past the source copy)\n  panel = pdst + (keepsource ? src->GetRowSize() : 0);\n  panelU = pdstU + (keepsource ? src->GetRowSize(PLANAR_U) : 0);\n  panelV = pdstV + (keepsource ? src->GetRowSize(PLANAR_V) : 0);\n  panelA = (pdstA && src->GetReadPtr(PLANAR_A)) ? (pdstA + (keepsource ? src->GetRowSize(PLANAR_A) : 0)) : nullptr;\n\n  // Clear below the histogram area (bottom right), if source is higher than histogram area.\n  if (src_height > show_size) {\n    auto pdst_start = panel + show_size * dst_pitch;\n    auto pdstU_start = panelU + show_size_h_uv * dst_pitchUV;\n    auto pdstV_start = panelV + show_size_h_uv * dst_pitchUV;\n    auto pdstA_start = has_alpha ? panelA + show_size * dst_pitchA : nullptr;\n    const int new_height = dst_height - show_size;\n    const int new_height_uv = dst_heightUV - show_size_h_uv;\n    const int new_height_a = has_alpha ? new_height : 0;\n\n    if (bits_per_pixel == 8)\n      ClearArea<uint8_t>(pdst_start, pdstU_start, pdstV_start, pdstA_start,\n        show_size, show_size_w_uv,\n        dst_pitch, dst_pitchUV, dst_pitchA,\n        new_height, new_height_uv, new_height_a,\n        bits_per_pixel, full_range);\n    else if (bits_per_pixel <= 16)\n      ClearArea<uint16_t>(pdst_start, pdstU_start, pdstV_start, pdstA_start,\n        show_size, show_size_w_uv,\n        dst_pitch, dst_pitchUV, dst_pitchA,\n        new_height, new_height_uv, new_height_a,\n        bits_per_pixel, full_range);\n    else\n      ClearArea<float>(pdst_start, pdstU_start, pdstV_start, pdstA_start,\n        show_size, show_size_w_uv,\n        dst_pitch, dst_pitchUV, dst_pitchA,\n        new_height, new_height_uv, new_height_a,\n        bits_per_pixel, full_range);\n  }\n\n  return dst;\n}\n\nstatic void GetYUVFromMatrix(\n  int matrix,                          // AVS_MATRIX_* enum value\n  double R, double G, double B,\n  double& dY, double& dU, double& dV)\n{\n  double Kr, Kb;\n  if (!GetKrKb(matrix, Kr, Kb)) {\n    // fallback to BT.601\n    Kr = 0.299; Kb = 0.114;\n  }\n  double Kg = 1.0 - Kr - Kb;\n  dY = Kr * R + Kg * G + Kb * B;\n  dU = (B - dY) / (2.0 * (1.0 - Kb));\n  dV = (R - dY) / (2.0 * (1.0 - Kr));\n}\n\ntemplate<typename pixel_t>\nstatic void DrawModeColor2_ClearVectorscopeArea(int bits_per_pixel,\n  uint8_t* dstp8, uint8_t* dstp8_u, uint8_t* dstp8_v, uint8_t* dstp8_a,\n  int pitch, int pitchUV, int pitchA,\n  int height, int heightUV, int heightA,\n  int show_bits, int swidth, int sheight,\n  bool full_range\n)\n{\n  const int show_size = (1 << show_bits);\n  const int show_size_w_uv = show_size >> swidth;\n  const int show_size_h_uv = show_size >> sheight;\n  const bool has_alpha = heightA > 0;\n  const int show_size_a = has_alpha ? show_size : 0;\n\n  // Clear vectorscope area\n\n  if (bits_per_pixel == 8)\n    ClearArea<uint8_t>(dstp8, dstp8_u, dstp8_v, dstp8_a,\n      show_size, show_size_w_uv, // width\n      pitch, pitchUV, pitchA,\n      show_size, show_size_h_uv, show_size_a, // height\n      bits_per_pixel, full_range);\n  else if (bits_per_pixel <= 16)\n    ClearArea<uint16_t>(dstp8, dstp8_u, dstp8_v, dstp8_a,\n      show_size, show_size_w_uv, // width\n      pitch, pitchUV, pitchA,\n      show_size, show_size_h_uv, show_size_a, // height\n      bits_per_pixel, full_range);\n  else\n    ClearArea<float>(dstp8, dstp8_u, dstp8_v, dstp8_a,\n      show_size, show_size_w_uv, // width\n      pitch, pitchUV, pitchA,\n      show_size, show_size_h_uv, show_size_a, // height\n      bits_per_pixel, full_range);\n}\n\ntemplate<typename pixel_t>\nstatic void DrawModeColor2_draw_graticule(int bits_per_pixel, uint8_t* dstp8, int pitch, int height, int show_bits) {\n\n  pitch /= sizeof(pixel_t);\n  pixel_t* dstp = reinterpret_cast<pixel_t*>(dstp8);\n\n  pixel_t luma128;\n\n  if constexpr (std::is_integral<pixel_t>::value) {\n    luma128 = (pixel_t)(128 << (bits_per_pixel - 8));\n  }\n  else {\n    luma128 = c8tof(128);\n  }\n\n  const int show_bit_shift = show_bits - 8;\n\n  //    16       240\n  // 16  +---------+\n  // 17  |         |\n  // ..  |         |\n  // 239 |         |\n  // 240 +---------+\n\n  // plot valid grey ccir601 square\n  const int size = 1 + ((240 - 16) << show_bit_shift); // original 8 bit: 225 0+/-112\n  std::fill_n(&dstp[(16 << show_bit_shift) * pitch + (16 << show_bit_shift)], size, luma128);\n  std::fill_n(&dstp[(240 << show_bit_shift) * pitch + (16 << show_bit_shift)], size, luma128);\n\n  // vertical lines left and right side\n  for (int y = 1 + (16 << show_bit_shift); y < 240 << show_bit_shift; y++) {\n    dstp[(16 << show_bit_shift) + y * pitch] = luma128;\n    dstp[(240 << show_bit_shift) + y * pitch] = luma128;\n  }\n}\n\ntemplate<typename pixel_t>\nstatic void DrawModeColor2_draw_circle(int bits_per_pixel, uint8_t* dstp8, uint8_t* dstp8_u, uint8_t* dstp8_v,\n  int pitch, int pitchUV, int height, int heightUV, double innerF,\n  int show_bits, int swidth, int sheight, int* deg15c, int* deg15s // precalculated array\n)\n{\n\n  pitch /= sizeof(pixel_t);\n  pitchUV /= sizeof(pixel_t);\n  pixel_t* dstp = reinterpret_cast<pixel_t*>(dstp8);\n  pixel_t* dstp_u = reinterpret_cast<pixel_t*>(dstp8_u);\n  pixel_t* dstp_v = reinterpret_cast<pixel_t*>(dstp8_v);\n\n  // possible to display >8 bit data stuffed into 8 bit size\n  const int show_bit_shift = show_bits - 8;\n\n  // plot circles\n\n  // here we do not bother with matrix-correct color representation.\n\n  // six hues in the color-wheel:\n  // LC[3j,3j+1,3j+2], RC[3j,3j+1,3j+2] in YRange[j]+1 and YRange[j+1]\n  int YRange[8] = { -1, 26, 104, 127, 191, 197, 248, 256 };\n  // 2x green, 2x yellow, 3x red\n  int LC[21] = {\n    145, 54, 34,\n    145, 54, 34,\n    210, 16, 146,\n    210, 16, 146,\n    81, 90, 240,\n    81, 90, 240,\n    81, 90, 240\n  };\n  // cyan, 4x blue, magenta, red:\n  int RC[21] = {\n    170, 166, 16,\n    41, 240, 110,\n    41, 240, 110,\n    41, 240, 110,\n    41, 240, 110,\n    106, 202, 222,\n    81, 90, 240\n  };\n  float LC_f[21] = {\n    c8tof(145), uv8tof(54), uv8tof(34),\n    c8tof(145), uv8tof(54), uv8tof(34),\n    c8tof(210), uv8tof(16), uv8tof(146),\n    c8tof(210), uv8tof(16), uv8tof(146),\n    c8tof(81), uv8tof(90), uv8tof(240),\n    c8tof(81), uv8tof(90), uv8tof(240),\n    c8tof(81), uv8tof(90), uv8tof(240)\n  };\n  // cyan, 4x blue, magenta, red:\n  float RC_f[21] = {\n    c8tof(170), uv8tof(166), uv8tof(16),\n    c8tof(41), uv8tof(240), uv8tof(110),\n    c8tof(41), uv8tof(240), uv8tof(110),\n    c8tof(41), uv8tof(240), uv8tof(110),\n    c8tof(41), uv8tof(240), uv8tof(110),\n    c8tof(106), uv8tof(202), uv8tof(222),\n    c8tof(81), uv8tof(90), uv8tof(240)\n  };\n\n  // example boundary of cyan and blue:\n  // red = min(r,g,b), blue if g < 2/3 b, green if b < 2/3 g.\n  // cyan between green and blue.\n  // thus boundary of cyan and blue at (r,g,b) = (0,170,255), since 2/3*255 = 170.\n  // => yuv = (127,190,47); hue = -52 degr; sat = 103\n  // => u'v' = (207,27) (same hue, sat=128)\n  // similar for the other hues.\n  // luma\n\n  // innerF is used for 15 degree markers as well\n  double thicknessF = 1.5;\n  double oneOverThicknessF = 1.0 / thicknessF;\n  double outerF = innerF + thicknessF * 2.0;\n  double centerF = innerF + thicknessF;\n  int64_t innerSq = (int64_t)(innerF * innerF * (1 << (show_bit_shift * 2)));\n  int64_t outerSq = (int64_t)(outerF * outerF * (1 << (show_bit_shift * 2)));\n  int activeY = 0;\n  int xRounder = (1 << swidth) / 2;\n  int yRounder = (1 << sheight) / 2;\n\n  const int limit = (1 << (show_bits - 1)) - 1;\n  const int limit_showwidth = (1 << show_bits) - 1;\n  for (int y = -limit; y < limit + 1; y++) {\n    if (y + limit > YRange[activeY + 1] << show_bit_shift)\n      activeY++;\n    for (int x = -limit; x <= 0; x++) {\n      int64_t distSq = x * x + y * y;\n      if (distSq <= outerSq && distSq >= innerSq) {\n\n        if constexpr (std::is_integral<pixel_t>::value) {\n          const int factorshift = (bits_per_pixel - 8);\n          const int MAXINTERP = 256;\n          double dist = fabs(sqrt((double)distSq * (1.0 / (1 << (2 * show_bit_shift)))) - centerF);\n          int interp = (int)(256.0f - (255.9f * (oneOverThicknessF * dist)));\n          // 255.9 is to account for float inprecision, which could cause underflow.\n\n          int xP = limit + x;\n          int yP = limit + y;\n\n          dstp[xP + yP * pitch] =\n            (pixel_t)((interp * (LC[3 * activeY] << factorshift)) >> 8); // left upper half\n\n          dstp[limit_showwidth - xP + yP * pitch] =\n            (pixel_t)((interp * (RC[3 * activeY] << factorshift)) >> 8); // right upper half\n\n          xP = (xP + xRounder) >> swidth;\n          yP = (yP + yRounder) >> sheight;\n\n          interp = min(MAXINTERP, interp);\n          int invInt = (MAXINTERP - interp);\n\n          int p_uv;\n          p_uv = xP + yP * pitchUV;\n          dstp_u[p_uv] = (pixel_t)((dstp_u[p_uv] * invInt + interp * (LC[3 * activeY + 1] << factorshift)) >> 8); // left half\n          dstp_v[p_uv] = (pixel_t)((dstp_v[p_uv] * invInt + interp * (LC[3 * activeY + 2] << factorshift)) >> 8); // left half\n\n          xP = ((limit_showwidth) >> swidth) - xP;\n          p_uv = xP + yP * pitchUV;\n\n          dstp_u[p_uv] = (pixel_t)((dstp_u[p_uv] * invInt + interp * (RC[3 * activeY + 1] << factorshift)) >> 8); // right half\n          dstp_v[p_uv] = (pixel_t)((dstp_v[p_uv] * invInt + interp * (RC[3 * activeY + 2] << factorshift)) >> 8); // right half\n        }\n        else {\n          // 32 bit float\n          const float MAXINTERP = 1.0f;\n          double dist = fabs(sqrt((double)distSq * (1.0 / (1 << (2 * show_bit_shift)))) - centerF);\n          float interp = (float)(1.0 - 0.9999 * (oneOverThicknessF * dist));\n          // 255.9 is to account for float inprecision, which could cause underflow.\n\n          int xP = limit + x;\n          int yP = limit + y;\n\n          dstp[xP + yP * pitch] =\n            (pixel_t)(interp * LC_f[3 * activeY]); // left upper half\n\n          dstp[limit_showwidth - xP + yP * pitch] =\n            (pixel_t)(interp * RC_f[3 * activeY]); // right upper half\n\n          xP = (xP + xRounder) >> swidth;\n          yP = (yP + yRounder) >> sheight;\n\n          interp = min(MAXINTERP, interp);\n          float invInt = (MAXINTERP - interp);\n\n          int p_uv;\n          p_uv = xP + yP * pitchUV;\n          dstp_u[p_uv] = (pixel_t)(dstp_u[p_uv] * invInt + interp * LC_f[3 * activeY + 1]); // left half\n          dstp_v[p_uv] = (pixel_t)(dstp_v[p_uv] * invInt + interp * LC_f[3 * activeY + 2]); // left half\n\n          xP = ((limit_showwidth) >> swidth) - xP;\n\n          p_uv = xP + yP * pitchUV;\n          dstp_u[p_uv] = (pixel_t)(dstp_u[p_uv] * invInt + interp * RC_f[3 * activeY + 1]); // right half\n          dstp_v[p_uv] = (pixel_t)(dstp_v[p_uv] * invInt + interp * RC_f[3 * activeY + 2]); // right half\n        }\n      }\n    }\n  }\n\n  // and the 15 degree markers (same as innerF)\n  // plot white 15 degree marks\n  for (int i = 0; i < 24; i++) {\n    if constexpr (sizeof(pixel_t) == 1)\n      dstp[deg15c[i] + deg15s[i] * pitch] = 235; // 235: Y-maxluma\n    else if constexpr (sizeof(pixel_t) == 2)\n      dstp[deg15c[i] + deg15s[i] * pitch] = 235 << (bits_per_pixel - 8); // 235: Y-maxluma\n    else // if constexpr (sizeof(pixel_t) == 4)\n      dstp[deg15c[i] + deg15s[i] * pitch] = c8tof(235); // 235: Y-maxluma\n  }\n\n}\n\n\ntemplate<typename pixel_t>\nstatic void do_vectorscope_color2(\n  pixel_t* pdstb, pixel_t* pdstbU, pixel_t* pdstbV,\n  const pixel_t* pY, const pixel_t* pU, const pixel_t* pV,\n  int dst_pitch, int dst_pitchUV,\n  int src_pitch, int src_pitchUV,\n  int src_widthUV, int src_heightUV,\n  int swidth, int sheight,\n  int show_bits,\n  int bits_per_pixel,\n  bits_conv_constants& d_chroma,\n  bool full_range\n)\n{\n  // 32 bit float Vectorscope is simulated after a 16 bit conversion\n  const int shift = bits_per_pixel == 32 ? (16 - show_bits) /*n/a*/ : (bits_per_pixel - show_bits);\n  const int max_pos = (1 << show_bits) - 1;\n  auto src_pitchY_chromacorr = (src_pitch << sheight);\n\n  if constexpr (sizeof(pixel_t) == 4) {\n    // ===== FLOAT PATH =====\n    const float mul_factor = d_chroma.mul_factor;\n    const float dst_offset = d_chroma.dst_offset;\n\n    for (int y = 0; y < src_heightUV; y++) {\n      for (int x = 0; x < src_widthUV; x++) {\n        const float uval_f = max(-0.5f, min(0.5f, pU[x]));\n        const float vval_f = max(-0.5f, min(0.5f, pV[x]));\n\n        int uval_posindex = (int)(uval_f * mul_factor + dst_offset + 0.5f);\n        int vval_posindex = (int)(vval_f * mul_factor + dst_offset + 0.5f);\n        uval_posindex = max(0, min(max_pos, uval_posindex));\n        vval_posindex = max(0, min(max_pos, vval_posindex));\n\n        pdstb[uval_posindex + vval_posindex * dst_pitch] = pY[x << swidth];\n        pdstbU[(uval_posindex >> swidth) + (vval_posindex >> sheight) * dst_pitchUV] = uval_f;\n        pdstbV[(uval_posindex >> swidth) + (vval_posindex >> sheight) * dst_pitchUV] = vval_f;\n      }\n      pY += src_pitchY_chromacorr;\n      pU += src_pitchUV;\n      pV += src_pitchUV;\n    }\n  }\n  else {\n    // ===== INTEGER PATH =====\n    const int max_value = (1 << bits_per_pixel) - 1;\n\n    // Split into 3 optimized paths based on shift and range\n    // When shift != 0, that is the dispay bit depth is different from source bit depth, we do conversion\n    // - full range: use conversion constants\n    // - limited range: either by downshifting or upshifting.\n    // E.g. displaying 10 bit data on a 8 bit grid, or displaying 8 bit data on a 10 bit grid.\n    // We need to convert the chroma values to the display bit depth, taking into account the limited/full range and the shift.\n\n    if (shift == 0) {\n      // ===== FAST PATH: No scaling needed =====\n      for (int y = 0; y < src_heightUV; y++) {\n        for (int x = 0; x < src_widthUV; x++) {\n          const int uval = max(0, min(max_value, (int)pU[x]));\n          const int vval = max(0, min(max_value, (int)pV[x]));\n\n          pdstb[uval + vval * dst_pitch] = pY[x << swidth];\n          pdstbU[(uval >> swidth) + (vval >> sheight) * dst_pitchUV] = (pixel_t)uval;\n          pdstbV[(uval >> swidth) + (vval >> sheight) * dst_pitchUV] = (pixel_t)vval;\n        }\n        pY += src_pitchY_chromacorr;\n        pU += src_pitchUV;\n        pV += src_pitchUV;\n      }\n    }\n    else if (full_range) {\n      // ===== FULL RANGE PATH: Use conversion constants =====\n      const float mul_factor = d_chroma.mul_factor;\n      const int src_offset_i = d_chroma.src_offset_i;\n      const float dst_offset = d_chroma.dst_offset;\n\n      for (int y = 0; y < src_heightUV; y++) {\n        for (int x = 0; x < src_widthUV; x++) {\n          const int uval = max(0, min(max_value, (int)pU[x]));\n          const int vval = max(0, min(max_value, (int)pV[x]));\n\n          int uval_posindex = (int)((uval - src_offset_i) * mul_factor + dst_offset + 0.5f);\n          int vval_posindex = (int)((vval - src_offset_i) * mul_factor + dst_offset + 0.5f);\n          uval_posindex = max(0, min(max_pos, uval_posindex));\n          vval_posindex = max(0, min(max_pos, vval_posindex));\n\n          pdstb[uval_posindex + vval_posindex * dst_pitch] = pY[x << swidth];\n          pdstbU[(uval_posindex >> swidth) + (vval_posindex >> sheight) * dst_pitchUV] = (pixel_t)uval;\n          pdstbV[(uval_posindex >> swidth) + (vval_posindex >> sheight) * dst_pitchUV] = (pixel_t)vval;\n        }\n        pY += src_pitchY_chromacorr;\n        pU += src_pitchUV;\n        pV += src_pitchUV;\n      }\n    }\n    else {\n      // ===== LIMITED RANGE PATH: Simple bit shift =====\n      if (shift > 0) {\n        // Downshift (e.g., 10-bit -> 8-bit display)\n        const int rounder = 1 << (shift - 1);\n        for (int y = 0; y < src_heightUV; y++) {\n          for (int x = 0; x < src_widthUV; x++) {\n            const int uval = max(0, min(max_value, (int)pU[x]));\n            const int vval = max(0, min(max_value, (int)pV[x]));\n\n            const int uval_posindex = (uval + rounder) >> shift;\n            const int vval_posindex = (vval + rounder) >> shift;\n\n            pdstb[uval_posindex + vval_posindex * dst_pitch] = pY[x << swidth];\n            pdstbU[(uval_posindex >> swidth) + (vval_posindex >> sheight) * dst_pitchUV] = (pixel_t)uval;\n            pdstbV[(uval_posindex >> swidth) + (vval_posindex >> sheight) * dst_pitchUV] = (pixel_t)vval;\n          }\n          pY += src_pitchY_chromacorr;\n          pU += src_pitchUV;\n          pV += src_pitchUV;\n        }\n      }\n      else {\n        // Upshift (e.g., 8-bit -> 10-bit display)\n        const int neg_shift = -shift;\n        for (int y = 0; y < src_heightUV; y++) {\n          for (int x = 0; x < src_widthUV; x++) {\n            const int uval = max(0, min(max_value, (int)pU[x]));\n            const int vval = max(0, min(max_value, (int)pV[x]));\n\n            const int uval_posindex = uval << neg_shift;\n            const int vval_posindex = vval << neg_shift;\n\n            pdstb[uval_posindex + vval_posindex * dst_pitch] = pY[x << swidth];\n            pdstbU[(uval_posindex >> swidth) + (vval_posindex >> sheight) * dst_pitchUV] = (pixel_t)uval;\n            pdstbV[(uval_posindex >> swidth) + (vval_posindex >> sheight) * dst_pitchUV] = (pixel_t)vval;\n          }\n          pY += src_pitchY_chromacorr;\n          pU += src_pitchUV;\n          pV += src_pitchUV;\n        }\n      }\n    }\n  }\n}\n\ntemplate<typename pixel_t>\nstatic void Draw_VectorScope_circle_targets_axes(int bits_per_pixel,\n  uint8_t* dstp8, uint8_t* dstp8_u, uint8_t* dstp8_v, int pitch, int pitchUV, int height, int heightUV,\n  double innerF,\n  int show_bits, int swidth, int sheight,\n  histogram_color2_params& params,\n  ConversionMatrix& conv_matrix,\n  int matrix, // AVS_MATRIX_* enum value\n  bits_conv_constants& conv_consts,\n  bool full_range, int* deg15c, int* deg15s)\n{\n\n  if (params.circle) {\n    // also the 15 deg marks points\n    DrawModeColor2_draw_circle<pixel_t>(bits_per_pixel,\n      dstp8, dstp8_u, dstp8_v,\n      pitch, pitchUV,\n      height, heightUV,\n      innerF,\n      show_bits, swidth, sheight,\n      deg15c, deg15s\n    );\n  }\n\n  // Used for the colorUV square positions, calculated from linear RGB\n  bits_conv_constants conv_consts_fullrange_float_origin;\n  get_bits_conv_constants(conv_consts_fullrange_float_origin, /*use_chroma=*/true,\n    /*fulls=*/true, full_range,\n    /*srcBitDepth=*/32, /*dstBitDepth=*/show_bits);\n\n  const int limit_showwidth = (1 << show_bits) - 1;\n\n  pitch /= sizeof(pixel_t);\n  pitchUV /= sizeof(pixel_t);\n  pixel_t* dstp = reinterpret_cast<pixel_t*>(dstp8);\n  pixel_t* dstp_u = reinterpret_cast<pixel_t*>(dstp8_u);\n  pixel_t* dstp_v = reinterpret_cast<pixel_t*>(dstp8_v);\n\n  // ===== -I AND +Q SIGNAL RGB VALUES FOR VECTORSCOPE GRATICULE =====\n  // These feed through the same matrix-aware make_yuv path as the color bar patches,\n  // giving correct UV pixel coordinates for any matrix and any bit depth.\n  // \n  // Note: -I and +Q are analog NTSC test signals that don't map cleanly to digital RGB/YUV.\n  // We maintain two separate specifications for backward compatibility:\n  //\n  // RGB-NATIVE: Lifted to studio black (code 16), broadcast-safe\n  //   Used when vectorscope processes RGB sources or when drawing RGB graticules\n  //   -I: RGB(16, 90, 130) at 8-bit → produces Y≈77 after matrix conversion\n  //   +Q: RGB(92, 16, 143) at 8-bit → produces Y≈63 after matrix conversion\n  //\n  // YUV-TARGETED: Zero-luma pure chroma definition  \n  //   Used when vectorscope processes YUV sources\n  //   -I: Converts to Y=16, Cb=158, Cr=95 (legacy ColorBars YUV output)\n  //   +Q: Converts to Y=16, Cb=174, Cr=149 (legacy ColorBars YUV output)\n  //   Contains out-of-range RGB components (super-blacks)\n  //\n  // Note 2: These will not lay exactly on UV's 33° and 123° degree lines, since those \n  // angles are defined in the original NTSC YIQ color space, which differs from the YUV \n  // space produced by BT.601/BT.709 matrix conversions.\n\n  // this one is not used, this is YUV vectorscope, we cannot determine that the YUV was converted from\n  // an RGB ColorBars.\n  /*\n  static const RGBEntry iq_rgb_native[] = {\n      { \"-I\", MINUS_I_R,     MINUS_I_G,     MINUS_I_B     }, // RGB-native (studio black lift)\n      { \"+Q\", PLUS_Q_R,      PLUS_Q_G,      PLUS_Q_B      }, // RGB-native (studio black lift)\n      { \"+I\", PLUS_I_R,      PLUS_I_G,      PLUS_I_B      }, // n/a ColorBarsHD only, which is YUV-only\n  };\n  */\n\n  // ColorBars ground truth linear RGB (0.75 amplitude, Rec. BT.801-1)\n  // Top 2/3 bars: LtGrey, Yellow, Cyan, Green, Magenta, Red, Blue\n  // (White/LtGrey sits at UV center, not a useful vectorscope target)\n  struct RGBEntry { const char* name; double r, g, b; };\n  static const RGBEntry bar_rgb[] = {\n      { \"Yellow\",  0.75, 0.75, 0.0  },\n      { \"Cyan\",    0.0,  0.75, 0.75 },\n      { \"Green\",   0.0,  0.75, 0.0  },\n      { \"Magenta\", 0.75, 0.0,  0.75 },\n      { \"Red\",     0.75, 0.0,  0.0  },\n      { \"Blue\",    0.0,  0.0,  0.75 },\n  };\n  static const RGBEntry bar100_rgb[] = {\n      { \"Yellow\",  1.0, 1.0, 0.0  },\n      { \"Cyan\",    0.0, 1.0, 1.0 },\n      { \"Green\",   0.0, 1.0, 0.0  },\n      { \"Magenta\", 1.0, 0.0, 1.0 },\n      { \"Red\",     1.0, 0.0, 0.0  },\n      { \"Blue\",    0.0, 0.0, 1.0 },\n  };\n\n  static const RGBEntry iq_rgb_yuv_targeted[] = {\n      { \"-I\", MINUS_I_R_YUV, MINUS_I_G_YUV, MINUS_I_B_YUV }, // YUV-targeted (zero-luma)\n      { \"+Q\", PLUS_Q_R_YUV,  PLUS_Q_G_YUV,  PLUS_Q_B_YUV  }, // YUV-targeted (zero-luma)\n      { \"+I\", PLUS_I_R_YUV,  PLUS_I_G_YUV,  PLUS_I_B_YUV }, // ColorBarsHD only (same for both)\n  };\n\n  const int half_box = 4 * (1 << (show_bits - 8));\n\n  // ---- Pixel position helper ----\n  // Converts normalised chroma [-0.5..0.5] to vectorscope pixel coordinate.\n  // Always from full range float, since the YUV squares are obtained from the linear RGB values.\n  // Target is limited/full range aware.\n  auto uv_to_px_float = [&](double uv_norm) -> int {\n    return clamp(\n      (int)((float)uv_norm * conv_consts_fullrange_float_origin.mul_factor + conv_consts_fullrange_float_origin.dst_offset + 0.5f),\n      0, (1 << show_bits) - 1);\n    };\n\n  // Box color (brownish, visible on the wheel background) ----\n  pixel_t box_luma, box_u, box_v;\n  if constexpr (std::is_integral<pixel_t>::value) {\n    // Tan/beige: Y=80, slightly orange/brown tint\n    box_luma = (pixel_t)(80 << (bits_per_pixel - 8));\n    box_u = (pixel_t)(140 << (bits_per_pixel - 8));\n    box_v = (pixel_t)(120 << (bits_per_pixel - 8));\n  }\n  else {\n    box_luma = c8tof(80);\n    box_u = uv8tof(140);\n    box_v = uv8tof(120);\n  }\n\n  if (params.targets) {\n\n    // ---- Draw colorbar target boxes ----\n    for (auto& e : bar_rgb) {\n      double dY, dU, dV;\n      GetYUVFromMatrix(matrix, e.r, e.g, e.b, dY, dU, dV);\n      int cx;\n      int cy;\n      if constexpr (std::is_integral<pixel_t>::value) {\n        cx = uv_to_px_float(dU);\n        cy = uv_to_px_float(dV);\n      }\n      else {\n        cx = uv_to_px_float(dU);\n        cy = uv_to_px_float(dV);\n      }\n\n      DrawModeColor2_DrawRect<pixel_t>(\n        dstp, pitch, dstp_u, dstp_v, pitchUV,\n        cx, cy, half_box, half_box,\n        swidth, sheight,\n        box_luma, box_u, box_v,\n        limit_showwidth);\n\n    }\n  }\n\n  if (params.targets100) {\n\n    // ---- Draw colorbar target boxes ----\n    for (auto& e : bar100_rgb) {\n      double dY, dU, dV;\n      GetYUVFromMatrix(matrix, e.r, e.g, e.b, dY, dU, dV);\n      int cx;\n      int cy;\n      if constexpr (std::is_integral<pixel_t>::value) {\n        cx = uv_to_px_float(dU);\n        cy = uv_to_px_float(dV);\n      }\n      else {\n        cx = uv_to_px_float(dU);\n        cy = uv_to_px_float(dV);\n      }\n\n      DrawModeColor2_DrawRect<pixel_t>(\n        dstp, pitch, dstp_u, dstp_v, pitchUV,\n        cx, cy, half_box, half_box,\n        swidth, sheight,\n        box_luma, box_u, box_v,\n        limit_showwidth);\n\n    }\n  }\n\n  if (params.iq) {\n    // ---- Draw +Q and -I target boxes ----\n    // These are matrix-independent (they are phase references, not primaries),\n    // but still need the same pixel-coordinate conversion.\n    for (auto& e : iq_rgb_yuv_targeted) {\n      double dY, dU, dV;\n      GetYUVFromMatrix(matrix, e.r, e.g, e.b, dY, dU, dV);\n      int cx = uv_to_px_float(dU);\n      int cy = uv_to_px_float(dV);\n      // yuv.u and yuv.v are already the correct pixel_t values at the virtual target\n      // (show) bit depth.\n\n      DrawModeColor2_DrawRect<pixel_t>(\n        dstp, pitch, dstp_u, dstp_v, pitchUV,\n        cx, cy, half_box, half_box,\n        swidth, sheight,\n        box_luma, box_u, box_v,\n        limit_showwidth);\n\n    }\n  }\n\n  // ---- Radial lines ----\n  pixel_t line_luma;\n  if constexpr (std::is_integral<pixel_t>::value)\n    line_luma = (pixel_t)(120 << (bits_per_pixel - 8));\n  else\n    line_luma = c8tof(120);\n\n  // Angles to draw(matching PPro vectorscope) :\n  // 0°, 90°, 180°, 270° — the axis cross\n  // 33°, 123°, 213°, 303° — the ±I/±Q diagonals\n  // knowing that in UV space these are not exactly at 33° and 123°\n\n  if (params.axes) {\n    const double angles90[] = {\n        0.0, 90.0, 180.0, 270.0\n    };\n    const int limit = (1 << (show_bits - 1)) - 1;\n    const int show_bit_shift = show_bits - 8;\n    for (double ang : angles90)\n      DrawRadialLine<pixel_t>(dstp, pitch,\n        limit, show_bit_shift, ang, line_luma);\n  }\n\n  if (params.iq_lines) {\n    const double anglesIQ[] = {\n        33.0, 123.0, 213.0, 303.0\n    };\n    const int limit = (1 << (show_bits - 1)) - 1;\n    const int show_bit_shift = show_bits - 8;\n    for (double ang : anglesIQ)\n      DrawRadialLine<pixel_t>(dstp, pitch,\n        limit, show_bit_shift, ang, line_luma);\n  }\n}\n\n\nPVideoFrame Histogram::DrawModeColor2(int n, IScriptEnvironment* env) {\n\n  // all these will get filled by VectorscopePrelude, common for color and color2 modes\n  PVideoFrame src;\n  BYTE* panel, * panelU, * panelV, * panelA;\n  int dst_pitch, dst_pitchUV, dst_pitchA, dst_height, dst_heightUV, dst_heightA;\n\n  PVideoFrame dst = VectorscopePrelude(n, env,\n    // outputs\n    src,\n    dst_pitch, dst_height,\n    dst_pitchUV, dst_heightUV,\n    dst_pitchA, dst_heightA,\n    panel, panelU, panelV, panelA);\n\n  bits_conv_constants d_chroma;\n  get_bits_conv_constants(d_chroma, /*use_chroma=*/true,\n    full_range, full_range,\n    bits_per_pixel, /*dstBitDepth=*/show_bits);\n  // d_chroma.mul_factor and d_chroma.dst_offset are now correct for\n  // limited-limited or full-full depending on _ColorRange frame property.\n\n  int swidth = vi.GetPlaneWidthSubsampling(PLANAR_U);\n  int sheight = vi.GetPlaneHeightSubsampling(PLANAR_U);\n\n  // Clear Vectorscope area (black background, init Alpha to 0 if present)\n  if (bits_per_pixel == 8)\n    DrawModeColor2_ClearVectorscopeArea<uint8_t>(bits_per_pixel,\n      panel, panelU, panelV, panelA,\n      dst_pitch, dst_pitchUV, dst_pitchA,\n      dst_height, dst_heightUV, dst_heightA,\n      show_bits, swidth, sheight,\n      full_range\n    );\n  else if (bits_per_pixel <= 16)\n    DrawModeColor2_ClearVectorscopeArea<uint16_t>(bits_per_pixel,\n      panel, panelU, panelV, panelA,\n      dst_pitch, dst_pitchUV, dst_pitchA,\n      dst_height, dst_heightUV, dst_heightA,\n      show_bits, swidth, sheight,\n      full_range\n    );\n  else\n    DrawModeColor2_ClearVectorscopeArea<float>(bits_per_pixel,\n      panel, panelU, panelV, panelA,\n      dst_pitch, dst_pitchUV, dst_pitchA,\n      dst_height, dst_heightUV, dst_heightA,\n      show_bits, swidth, sheight,\n      full_range\n    );\n\n  // graticule\n  // Valid chroma boundary square\n  // always/never/only-when-limited\n  // \"color\" mode's graticule is used for highlight danger zone.\n  // \"color2\" mode's graticule is used for drawing chroma boundary rectangle.\n  // \"on\" or \"auto\"+limited range\n  const bool need_graticule = color2_params.graticule_type == histogram_color2_params::GRATICULE_ON ||\n    (color2_params.graticule_type == histogram_color2_params::GRATICULE_AUTO && !full_range);\n\n  if (need_graticule) {\n    if (bits_per_pixel == 8)\n      DrawModeColor2_draw_graticule<uint8_t>(bits_per_pixel, panel, dst_pitch, dst_height, show_bits);\n    else if (bits_per_pixel <= 16)\n      DrawModeColor2_draw_graticule<uint16_t>(bits_per_pixel, panel, dst_pitch, dst_height, show_bits);\n    else\n      DrawModeColor2_draw_graticule<float>(bits_per_pixel, panel, dst_pitch, dst_height, show_bits);\n  }\n\n  // others: 75% RGB and IQ targets, 15 degree marks, etc.\n  if (bits_per_pixel == 8)\n    Draw_VectorScope_circle_targets_axes<uint8_t>(bits_per_pixel,\n      panel, panelU, panelV,\n      dst_pitch, dst_pitchUV,\n      dst_height, dst_heightUV,\n      color2_innerF,\n      show_bits, swidth, sheight,\n      color2_params, matrix, theMatrix, d_chroma, full_range,\n      deg15c, deg15s\n      );\n  else if (bits_per_pixel <= 16)\n    Draw_VectorScope_circle_targets_axes<uint16_t>(bits_per_pixel,\n      panel, panelU, panelV,\n      dst_pitch, dst_pitchUV,\n      dst_height, dst_heightUV,\n      color2_innerF,\n      show_bits, swidth, sheight,\n      color2_params, matrix, theMatrix, d_chroma, full_range,\n      deg15c, deg15s\n      );\n  else\n    Draw_VectorScope_circle_targets_axes<float>(bits_per_pixel,\n      panel, panelU, panelV,\n      dst_pitch, dst_pitchUV,\n      dst_height, dst_heightUV,\n      color2_innerF,\n      show_bits, swidth, sheight,\n      color2_params, matrix, theMatrix, d_chroma, full_range,\n      deg15c, deg15s\n      );\n\n  // plot vectorscope\n  const int src_pitch = src->GetPitch(PLANAR_Y) / pixelsize;\n  const int src_pitchUV = src->GetPitch(PLANAR_U) / pixelsize;\n  const int src_widthUV = src->GetRowSize(PLANAR_U) / pixelsize;\n  const int src_heightUV = src->GetHeight(PLANAR_U);\n\n  const BYTE* pY = src->GetReadPtr(PLANAR_Y);\n  const BYTE* pU = src->GetReadPtr(PLANAR_U);\n  const BYTE* pV = src->GetReadPtr(PLANAR_V);\n\n  dst_pitch /= pixelsize;\n  dst_pitchUV /= pixelsize;\n\n  if(bits_per_pixel == 8)\n    do_vectorscope_color2<uint8_t>(\n      panel, panelU, panelV,\n      pY, pU, pV,\n      dst_pitch, dst_pitchUV,\n      src_pitch, src_pitchUV,\n      src_widthUV, src_heightUV,\n      swidth, sheight,\n      show_bits, bits_per_pixel, d_chroma, full_range);\n  else if (bits_per_pixel <= 16)\n    do_vectorscope_color2<uint16_t>(\n      (uint16_t *)panel, (uint16_t*)panelU, (uint16_t*)panelV,\n      (uint16_t*)pY, (uint16_t*)pU, (uint16_t*)pV,\n      dst_pitch, dst_pitchUV,\n      src_pitch, src_pitchUV,\n      src_widthUV, src_heightUV,\n      swidth, sheight,\n      show_bits, bits_per_pixel, d_chroma, full_range);\n  else\n    do_vectorscope_color2<float>(\n      (float*)panel, (float*)panelU, (float*)panelV,\n      (float*)pY, (float*)pU, (float*)pV,\n      dst_pitch, dst_pitchUV,\n      src_pitch, src_pitchUV,\n      src_widthUV, src_heightUV,\n      swidth, sheight,\n      show_bits, bits_per_pixel, d_chroma, full_range);\n\n  return dst;\n}\n\ntemplate<typename pixel_t, bool chroma_danger>\nstatic void DrawModeColor_PlotHistogram_inner(\n  uint8_t* panel_y, int dstpitch,\n  const int* histUV,\n  int show_size, int show_bits,\n  int bits_per_pixel,\n  int maxval)\n{\n  const int limit16 = 16 << (show_bits - 8);\n  const int limit240 = 240 << (show_bits - 8);\n  int limit16_pixel, luma235;\n  if constexpr (std::is_same_v<pixel_t, float>) {\n    limit16_pixel = 16;\n    luma235 = 235;\n  }\n  else {\n    limit16_pixel = 16 << (bits_per_pixel - 8);\n    luma235 = 235 << (bits_per_pixel - 8);\n  }\n  const int scale = std::is_same_v<pixel_t, float> ? 1 : (1 << (bits_per_pixel - 8));\n\n  for (int y = 0; y < show_size; y++) {\n    // ylimited: compile-time eliminated when chroma_danger==false\n    const bool ylimited = chroma_danger && (y < limit16 || y > limit240);\n    auto row = reinterpret_cast<pixel_t*>(panel_y);\n    const int* histRow = histUV + y * show_size;\n    for (int x = 0; x < show_size; x++) {\n      int disp_val = (histRow[x] * scale) / maxval;\n      // x danger check: compile-time eliminated when chroma_danger==false\n      if constexpr (chroma_danger) {\n        if (ylimited || x < limit16 || x > limit240)\n          disp_val -= limit16_pixel;\n      }\n      int out = min(luma235, limit16_pixel + disp_val);\n      if constexpr (std::is_same_v<pixel_t, float>)\n        row[x] = (float)out / 255.0f;\n      else\n        row[x] = (pixel_t)out;\n    }\n    panel_y += dstpitch;\n  }\n}\n\ntemplate<typename pixel_t>\nstatic void DrawModeColor_PlotHistogram_dispatch(\n  bool show_chroma_danger_zone,\n  uint8_t* panel_y, int dstpitch,\n  const int* histUV,\n  int show_size, int show_bits,\n  int bits_per_pixel,\n  int maxval)\n{\n  if (show_chroma_danger_zone)\n    DrawModeColor_PlotHistogram_inner<pixel_t, true>(panel_y, dstpitch, histUV, show_size, show_bits, bits_per_pixel, maxval);\n  else\n    DrawModeColor_PlotHistogram_inner<pixel_t, false>(panel_y, dstpitch, histUV, show_size, show_bits, bits_per_pixel, maxval);\n}\n\n\n\nPVideoFrame Histogram::DrawModeColor(int n, IScriptEnvironment* env) {\n\n  // all these will get filled by VectorscopePrelude, common for color and color2 modes\n  PVideoFrame src;\n  BYTE* panel, * panelU, * panelV, * panelA;\n  int dst_pitch, dst_pitchUV, dst_pitchA, dst_height, dst_heightUV, dst_heightA;\n\n  PVideoFrame dst = VectorscopePrelude(n, env,\n    // outputs\n    src,\n    dst_pitch, dst_height,\n    dst_pitchUV, dst_heightUV,\n    dst_pitchA, dst_heightA,\n    panel, panelU, panelV, panelA);\n\n  // always planar\n\n  int show_size = 1 << show_bits; // 256 for 8 bits, max 1024x1024 (10 bit resolution) found\n\n  bits_conv_constants d_chroma;\n  get_bits_conv_constants(d_chroma, /*use_chroma=*/true,\n    full_range, full_range,\n    bits_per_pixel, /*dstBitDepth=*/show_bits);\n  // d_chroma.mul_factor and d_chroma.dst_offset are now correct for\n  // limited-limited or full-full depending on _ColorRange frame property.\n\n  // Allocate histogram array, can be huge for 12 bits (4096x4096 = 16 million ints), so use nothrow and check for failure.\n  int* histUV = new(std::nothrow) int[show_size * show_size];\n  if (!histUV)\n    env->ThrowError(\"Histogram: malloc failure!\");\n\n  memset(histUV, 0, sizeof(int) * show_size * show_size);\n\n  // Create histogram from the original src frame's U and V planes.\n  // We need to take into account the bit depth and the show_bits, as well as the limited/full range\n  // for scaling to show_bits correctly.\n  const BYTE* pU = src->GetReadPtr(PLANAR_U);\n  const BYTE* pV = src->GetReadPtr(PLANAR_V);\n\n  int w = origwidth >> vi.GetPlaneWidthSubsampling(PLANAR_U);\n  int h = src->GetHeight(PLANAR_U);\n  int p = src->GetPitch(PLANAR_U) / pixelsize;\n\n  const int max_pos = (1 << show_bits) - 1;\n  const float mul_factor = d_chroma.mul_factor;\n  const float dst_offset = d_chroma.dst_offset;\n  const int src_offset_i = d_chroma.src_offset_i;\n\n  if (pixelsize == 1) {\n    if (show_bits == bits_per_pixel) {\n      // quick case: no bit depth conversion needed\n      for (int y = 0; y < h; y++) {\n        for (int x = 0; x < w; x++) {\n          int u = pU[y * p + x];\n          int v = pV[y * p + x];\n          histUV[(v << 8) + u]++;\n        }\n      }\n    }\n    else {\n      // 8 bit data on 10 bit sized screen\n      // works for both limited and full range, since the conversion is the same for 8 bit source\n      // (10 bit limited case: mul_factor = 4, dst_offset = 0 for full, dst_offset = 16 for limited)\n      for (int y = 0; y < h; y++) {\n        for (int x = 0; x < w; x++) {\n          const int uval = reinterpret_cast<const uint8_t*>(pU)[y * p + x];\n          const int vval = reinterpret_cast<const uint8_t*>(pV)[y * p + x];\n          int uval_posindex = (int)((uval - src_offset_i) * mul_factor + dst_offset + 0.5f);\n          int vval_posindex = (int)((vval - src_offset_i) * mul_factor + dst_offset + 0.5f);\n          uval_posindex = max(0, min(max_pos, uval_posindex));\n          vval_posindex = max(0, min(max_pos, vval_posindex));\n          histUV[(vval_posindex << show_bits) + uval_posindex]++;\n        }\n      }\n    }\n  }\n  else if (pixelsize == 2) {\n    if (show_bits == bits_per_pixel) {\n      // quick case: no bit depth conversion needed\n      for (int y = 0; y < h; y++) {\n        for (int x = 0; x < w; x++) {\n          int u = reinterpret_cast<const uint16_t*>(pU)[y * p + x];\n          int v = reinterpret_cast<const uint16_t*>(pV)[y * p + x];\n          histUV[(v << show_bits) + u]++;\n        }\n      }\n    }\n    else {\n      // works for both limited and full range, since the conversion is the same for 16 bit source (mul_factor = 4, dst_offset = 0 for full, dst_offset = 16 for limited)\n      for (int y = 0; y < h; y++) {\n        for (int x = 0; x < w; x++) {\n          const int uval = reinterpret_cast<const uint16_t*>(pU)[y * p + x];\n          const int vval = reinterpret_cast<const uint16_t*>(pV)[y * p + x];\n          int uval_posindex = (int)((uval - src_offset_i) * mul_factor + dst_offset + 0.5f);\n          int vval_posindex = (int)((vval - src_offset_i) * mul_factor + dst_offset + 0.5f);\n          uval_posindex = max(0, min(max_pos, uval_posindex));\n          vval_posindex = max(0, min(max_pos, vval_posindex));\n          histUV[(vval_posindex << show_bits) + uval_posindex]++;\n        }\n      }\n    }\n  }\n  else { // float\n    // 32 bit data on show_bits bit sized screen\n    for (int y = 0; y < h; y++) {\n      for (int x = 0; x < w; x++) {\n        const float uval_f = max(-0.5f, min(0.5f, reinterpret_cast<const float*>(pU)[y * p + x]));\n        const float vval_f = max(-0.5f, min(0.5f, reinterpret_cast<const float*>(pV)[y * p + x]));\n        int uval_posindex = (int)(uval_f * mul_factor + dst_offset + 0.5f);\n        int vval_posindex = (int)(vval_f * mul_factor + dst_offset + 0.5f);\n        uval_posindex = max(0, min(max_pos, uval_posindex));\n        vval_posindex = max(0, min(max_pos, vval_posindex));\n        histUV[(vval_posindex << show_bits) + uval_posindex]++;\n      }\n    }\n  }\n  // End of histogram creation.\n\n  const bool show_chroma_danger_zone = color2_params.graticule_type == histogram_color2_params::GRATICULE_ON ||\n    (color2_params.graticule_type == histogram_color2_params::GRATICULE_AUTO && !full_range);\n\n  // Plot Histogram on Y.\n  int maxval = 1;\n  // Should we adjust the divisor (maxval)??\n  if (pixelsize == 1)\n    DrawModeColor_PlotHistogram_dispatch<uint8_t>(show_chroma_danger_zone, panel, dst_pitch, histUV, show_size, show_bits, bits_per_pixel, maxval);\n  else if (pixelsize == 2)\n    DrawModeColor_PlotHistogram_dispatch<uint16_t>(show_chroma_danger_zone, panel, dst_pitch, histUV, show_size, show_bits, bits_per_pixel, maxval);\n  else\n    DrawModeColor_PlotHistogram_dispatch<float>(show_chroma_danger_zone, panel, dst_pitch, histUV, show_size, show_bits, bits_per_pixel, maxval);\n\n  // Draw colors - U gradient (x-driven) and V gradient (y-driven)\n  const int swidth = vi.GetPlaneWidthSubsampling(PLANAR_U);\n  const int sheight = vi.GetPlaneHeightSubsampling(PLANAR_U);\n  const int uvWidth = show_size >> swidth;\n  const int uvHeight = show_size >> sheight;\n  const int shiftCount = show_bits - bits_per_pixel; // for int types\n  const int rounder = shiftCount > 0 ? (1 << (shiftCount - 1)) : 0; // for int types when downshifting\n  const int shiftCount_f = show_bits - 8; // ? Why\n\n  // U: value depends only on x -> precompute one row, memcpy for all y\n  // V: value depends only on y -> compute once per row, fill entire row\n\n  if (pixelsize == 1) {\n    // --- U ---\n    // Precompute one row\n    std::vector<uint8_t> uRow(uvWidth);\n    for (int x = 0; x < uvWidth; x++)\n      uRow[x] = (uint8_t)((x << swidth) >> shiftCount);\n    auto p = panelU;\n    for (int y = 0; y < uvHeight; y++, p += dst_pitchUV)\n      memcpy(p, uRow.data(), uvWidth);\n    // --- V ---\n    p = panelV;\n    for (int y = 0; y < uvHeight; y++, p += dst_pitchUV) {\n      uint8_t vval = (uint8_t)(((y << sheight) + rounder) >> shiftCount);\n      memset(p, vval, uvWidth);\n    }\n  }\n  else if (pixelsize == 2) {\n    // --- U ---\n    std::vector<uint16_t> uRow(uvWidth);\n    if (shiftCount >= 0) {\n      for (int x = 0; x < uvWidth; x++)\n        uRow[x] = (uint16_t)(((x << swidth) + rounder) >> shiftCount);\n    }\n    else {\n      for (int x = 0; x < uvWidth; x++)\n        uRow[x] = (uint16_t)((x << swidth) << -shiftCount);\n    }\n    auto p = panelU;\n    for (int y = 0; y < uvHeight; y++, p += dst_pitchUV)\n      memcpy(p, uRow.data(), uvWidth * sizeof(uint16_t));\n\n    // --- V ---\n    p = panelV;\n    if (shiftCount >= 0) {\n      for (int y = 0; y < uvHeight; y++, p += dst_pitchUV) {\n        uint16_t vval = (uint16_t)(((y << sheight) + rounder) >> shiftCount);\n        std::fill_n(reinterpret_cast<uint16_t*>(p), uvWidth, vval);\n      }\n    }\n    else {\n      for (int y = 0; y < uvHeight; y++, p += dst_pitchUV) {\n        uint16_t vval = (uint16_t)((y << sheight) << -shiftCount);\n        std::fill_n(reinterpret_cast<uint16_t*>(p), uvWidth, vval);\n      }\n    }\n  }\n  else { // float\n    // --- U ---\n    std::vector<float> uRow(uvWidth);\n    for (int x = 0; x < uvWidth; x++)\n      uRow[x] = uv8tof((x << swidth) >> shiftCount_f);\n    auto p = panelU;\n    for (int y = 0; y < uvHeight; y++, p += dst_pitchUV)\n      memcpy(p, uRow.data(), uvWidth * sizeof(float));\n    // --- V ---\n    p = panelV;\n    for (int y = 0; y < uvHeight; y++, p += dst_pitchUV) {\n      float vval = uv8tof((y << sheight) >> shiftCount_f);\n      std::fill_n(reinterpret_cast<float*>(p), uvWidth, vval);\n    }\n  }\n\n  delete[] histUV;\n\n  // others: RGB and IQ targets, 15 degree marks, etc\n  if (bits_per_pixel == 8)\n    Draw_VectorScope_circle_targets_axes<uint8_t>(bits_per_pixel,\n      panel, panelU, panelV,\n      dst_pitch, dst_pitchUV,\n      dst_height, dst_heightUV,\n      color2_innerF,\n      show_bits, swidth, sheight,\n      color2_params, matrix, theMatrix, d_chroma, full_range,\n      deg15c, deg15s\n    );\n  else if (bits_per_pixel <= 16)\n    Draw_VectorScope_circle_targets_axes<uint16_t>(bits_per_pixel,\n      panel, panelU, panelV,\n      dst_pitch, dst_pitchUV,\n      dst_height, dst_heightUV,\n      color2_innerF,\n      show_bits, swidth, sheight,\n      color2_params, matrix, theMatrix, d_chroma, full_range,\n      deg15c, deg15s\n    );\n  else\n    Draw_VectorScope_circle_targets_axes<float>(bits_per_pixel,\n      panel, panelU, panelV,\n      dst_pitch, dst_pitchUV,\n      dst_height, dst_heightUV,\n      color2_innerF,\n      show_bits, swidth, sheight,\n      color2_params, matrix, theMatrix, d_chroma, full_range,\n      deg15c, deg15s\n    );\n\n  return dst;\n}\n\n\nPVideoFrame Histogram::DrawModeLevels(int n, IScriptEnvironment* env) {\n  PVideoFrame src = child->GetFrame(n, env);\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n  BYTE* dstp = dst->GetWritePtr();\n\n  // Note: drawing colors are of limited range independently from clip range\n  // bool full_range is filled in ctor.\n\n  int show_size = 1 << show_bits;\n\n  const bool isGrey = vi.IsY();\n  const int planecount = isGrey ? 1 : 3;\n  const bool RGB = vi.IsRGB();\n  const bool isFloat = (bits_per_pixel == 32);\n  const int color_shift =  isFloat ? 0 : (bits_per_pixel - 8);\n  const int max_pixel_value = bits_per_pixel <= 16 ? (1 << bits_per_pixel) - 1 : 0; // float: n/a\n  const float color_shift_factor = isFloat ? 1.0f / 255.0f : max_pixel_value / 255.0f;\n\n  int plane_default_black[3] = {\n    RGB ? 0 : (16 << color_shift),\n    RGB ? 0 : (128 << color_shift),\n    RGB ? 0 : (128 << color_shift)\n  };\n  float plane_default_black_f[3] = {\n    RGB ? 0 : 16 / 255.0f,\n    RGB ? 0 : 0.0f,\n    RGB ? 0 : 0.0f\n  };\n\n  const int planesYUV[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A};\n  const int planesRGB[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A};\n  const int *planes = vi.IsYUV() || vi.IsYUVA() ? planesYUV : planesRGB;\n\n  if (keepsource) {\n    if (src->GetHeight() < dst->GetHeight()) {\n      // fill empty area in the right bottom part\n      const int fillSize = (dst->GetHeight() - src->GetHeight()) * dst->GetPitch();\n      const int fillStart = src->GetHeight() * dst->GetPitch();\n\n      switch (pixelsize) {\n      case 1: memset(dstp + fillStart, plane_default_black[0], fillSize); break;\n      case 2: std::fill_n((uint16_t *)(dstp + fillStart), fillSize / sizeof(uint16_t), plane_default_black[0]); break;\n      case 4: std::fill_n((float *)(dstp + fillStart), fillSize / sizeof(float), plane_default_black_f[0]); break;\n      }\n\n      // first plane is already processed\n      // dont't touch Alpha\n      for (int p = 1; p < planecount; p++) {\n        const int plane = planes[p];\n        BYTE* ptr = dst->GetWritePtr(plane);\n\n        const int fillSize = (dst->GetHeight(plane) - src->GetHeight(plane)) * dst->GetPitch(plane);\n        const int fillStart = src->GetHeight(plane) * dst->GetPitch(plane);\n        switch (pixelsize) {\n        case 1: memset(ptr + fillStart, RGB ? 0 : plane_default_black[p], fillSize); break;\n        case 2: std::fill_n((uint16_t*)(ptr + fillStart), fillSize / sizeof(uint16_t), plane_default_black[p]); break;\n        case 4: std::fill_n((float*)(ptr + fillStart), fillSize / sizeof(float), plane_default_black_f[p]); break;\n        }\n      }\n    }\n  }\n\n  // counters\n  int bufsize = sizeof(uint32_t)*show_size;\n  uint32_t *histPlane1 = static_cast<uint32_t*>(env->Allocate(bufsize * planecount, 16, AVS_NORMAL_ALLOC));\n  if (!histPlane1)\n    env->ThrowError(\"Histogram: Could not reserve memory.\");\n  uint32_t *histPlanes[3] = {\n    histPlane1, \n    planecount == 1 ? nullptr : histPlane1 + show_size, \n    planecount == 1 ? nullptr : histPlane1 + 2 * show_size\n  };\n  std::fill_n(histPlane1, show_size * planecount, 0);\n\n  const int xstart = keepsource ? origwidth : 0; // drawing starts at this column\n\n  // copy planes\n  // luma or G\n  if (keepsource) {\n    env->BitBlt(dstp, dst->GetPitch(), src->GetReadPtr(), src->GetPitch(), src->GetRowSize(), src->GetHeight());\n  }\n  if (vi.IsPlanar()) {\n    // copy rest planes\n    if (keepsource) {\n      for (int p = 1; p < vi.NumComponents(); p++) {\n        const int plane = planes[p];\n        env->BitBlt(dst->GetWritePtr(plane), dst->GetPitch(plane), src->GetReadPtr(plane), src->GetPitch(plane), src->GetRowSize(plane), src->GetHeight(plane));\n      }\n    }\n\n    const int max_show_pixel_value = show_size - 1;\n\n    // ---------------------------------------------------\n    // accumulate population: fill histogram array from pixels\n    for (int p = 0; p < planecount; p++) {\n      const int plane = planes[p];\n      const bool chroma = (plane == PLANAR_U || plane == PLANAR_V);\n      const BYTE* srcp = src->GetReadPtr(plane);\n\n      const int w = src->GetRowSize(plane) / pixelsize;\n      const int h = src->GetHeight(plane);\n      const int pitch = src->GetPitch(plane) / pixelsize;\n\n      // accumulator of current plane\n      // size: show_size (256 or 1024)\n      uint32_t *hist = histPlanes[p];\n\n      bits_conv_constants d;\n      get_bits_conv_constants(d, chroma, full_range, full_range, bits_per_pixel/*source_bitdepth*/, show_bits /*target_bitdepth*/);\n\n      if(pixelsize==1) {\n        const uint8_t *srcp8 = reinterpret_cast<const uint8_t *>(srcp);\n        if (show_bits == bits_per_pixel) {\n          // Exact. 8 bit clip into 8 bit histogram\n          for (int y = 0; y < h; y++) {\n            for (int x = 0; x < w; x++) {\n              hist[srcp8[x]]++;\n            }\n            srcp8 += pitch;\n          }\n        }\n        else {\n          // 8 bit clip into 8,9,... bit histogram\n          if (full_range) {\n            // full range: stretch\n            if (chroma) {\n              const float dst_offset_plus_round = d.dst_offset + 0.5f;\n              for (int y = 0; y < h; y++) {\n                for (int x = 0; x < w; x++) {\n                  hist[clamp((int)((srcp8[x] - d.src_offset_i) * d.mul_factor + dst_offset_plus_round), 0, max_show_pixel_value)]++;\n                }\n                srcp8 += pitch;\n              }\n            }\n            else {\n              // src_offset and dst_offset is 0\n              for (int y = 0; y < h; y++) {\n                for (int x = 0; x < w; x++) {\n                  hist[min((int)(srcp8[x] * d.mul_factor + 0.5f), max_show_pixel_value)]++;\n                }\n                srcp8 += pitch;\n              }\n            }\n          }\n          else {\n            const int invshift = show_bits - bits_per_pixel;\n            // limited range: shift\n            for (int y = 0; y < h; y++) {\n              for (int x = 0; x < w; x++) {\n                hist[(int)srcp8[x] << invshift]++;\n              }\n              srcp8 += pitch;\n            }\n          }\n        }\n      }\n      else if (pixelsize == 2) {\n        const uint16_t* srcp16 = reinterpret_cast<const uint16_t*>(srcp);\n        if (show_bits == bits_per_pixel) {\n          // Exact. e.g. 10 bit clip into 10 bit histogram\n          for (int y = 0; y < h; y++) {\n            for (int x = 0; x < w; x++) {\n              hist[min((int)srcp16[x], max_show_pixel_value)]++;\n            }\n            srcp16 += pitch;\n          }\n        }\n        else {\n          // 10 bit clip into 8,9,10,11,12,... bit histogram\n          if (full_range) {\n            // full range: stretch\n            if (chroma) {\n              const float dst_offset_plus_round = d.dst_offset + 0.5f;\n              for (int y = 0; y < h; y++) {\n                for (int x = 0; x < w; x++) {\n                  hist[clamp((int)((srcp16[x] - d.src_offset_i) * d.mul_factor + dst_offset_plus_round), 0, max_show_pixel_value)]++;\n                }\n                srcp16 += pitch;\n              }\n            }\n            else {\n              // src_offset and dst_offset is 0\n              for (int y = 0; y < h; y++) {\n                for (int x = 0; x < w; x++) {\n                  hist[min((int)(srcp16[x] * d.mul_factor + 0.5f), max_show_pixel_value)]++;\n                }\n                srcp16 += pitch;\n              }\n            }\n          }\n          else {\n            // limited range: shift. Up or down\n            const int shift = bits_per_pixel - show_bits;\n            if (shift < 0) {\n              // 10 bit clip into 11 bit histogram\n              int invshift = -shift;\n              for (int y = 0; y < h; y++) {\n                for (int x = 0; x < w; x++) {\n                  hist[min(srcp16[x] << invshift, max_show_pixel_value)]++;\n                }\n                srcp16 += pitch;\n              }\n            }\n            else {\n              // e.g.10 bit clip into 8-9 bit histogram\n              const int round = 1 << (shift - 1);\n              for (int y = 0; y < h; y++) {\n                for (int x = 0; x < w; x++) {\n                  hist[min((srcp16[x] + round) >> shift, max_show_pixel_value)]++;\n                }\n                srcp16 += pitch;\n              }\n            }\n          }\n        }\n      }\n      else {\n        // create fake Histogram 32 bit float\n        const float *srcp32 = reinterpret_cast<const float *>(srcp);\n        const float dst_offset_plus_round = d.dst_offset + 0.5f;\n        for (int y = 0; y < h; y++) {\n          for (int x = 0; x < w; x++) {\n            hist[clamp((int)(srcp32[x] * d.mul_factor + dst_offset_plus_round), 0, max_show_pixel_value)]++;\n          }\n          srcp32 += pitch;\n        }\n      }\n    }\n    // accumulate end\n    // ---------------------------------------------------\n\n    int pos_shift = (show_bits - 8);\n    int show_middle_pos = (128 << pos_shift);\n    // draw planes\n    for (int p = 0; p < planecount; p++) {\n      const int plane = planes[p];\n\n      int swidth = vi.GetPlaneWidthSubsampling(plane);\n      int sheight = vi.GetPlaneHeightSubsampling(plane);\n\n      // Draw Unsafe zone (UV-graph)\n\n      unsigned char* pdstb = dst->GetWritePtr(plane);\n      pdstb += (xstart*pixelsize) >> swidth; // next to the source image if kept\n\n      const int dstPitch = dst->GetPitch(plane);\n\n      // Clear Y/U/V or B, R G\n      BYTE *ptr = pdstb;\n      for (int y = 0; y < dst->GetHeight() >> sheight; y++) {\n        switch (pixelsize) {\n        case 1: memset(ptr, plane_default_black[p], show_size >> swidth); break;\n        case 2: std::fill_n((uint16_t *)(ptr), show_size >> swidth, plane_default_black[p]); break;\n        case 4: std::fill_n((float *)(ptr), show_size >> swidth, plane_default_black_f[p]); break;\n        }\n        ptr += dstPitch;\n      }\n\n      if (!RGB && markers) {\n        // Draw Unsafe zone (Y-graph)\n        const int color_unsafeZones[3] = { 32, 16, 160 };\n        const float color_unsafeZones_f[3] = { c8tof(32), uv8tof(16), uv8tof(160) };\n        int color_usz = color_unsafeZones[p];\n        int color_i = color_usz << color_shift;\n        float color_f = color_unsafeZones_f[p];\n        ptr = pdstb + 0 * dstPitch;;\n\n        for (int y = 0; y <= 64 >> sheight; y++) {\n          int x = 0;\n          for (; x < (16 << pos_shift) >> swidth; x++) {\n            if (pixelsize == 1)\n              ptr[x] = color_i;\n            else if (pixelsize == 2)\n              reinterpret_cast<uint16_t *>(ptr)[x] = color_i;\n            else\n              reinterpret_cast<float *>(ptr)[x] = color_f;\n          }\n          for (x = (236 << pos_shift) >> swidth; x < (show_size >> swidth); x++) { // or (235 << pos_shift) + 1?\n            if (pixelsize == 1)\n              ptr[x] = color_i;\n            else if (pixelsize == 2)\n              reinterpret_cast<uint16_t *>(ptr)[x] = color_i;\n            else\n              reinterpret_cast<float *>(ptr)[x] = color_f;\n          }\n          ptr += dstPitch;\n        }\n      }\n\n      if (markers) {\n        if (RGB) {\n          // nice gradients\n          int StartY;\n          switch (plane) {\n          case PLANAR_R: StartY = 0 + 0; break;\n          case PLANAR_G: StartY = 64 + 16; break;\n          case PLANAR_B: StartY = 64 + 16 + 64 + 16; break;\n          }\n          ptr = pdstb + ((StartY) >> sheight) * dstPitch;\n          for (int y = (StartY) >> sheight; y <= (StartY + 64) >> sheight; y++) {\n            if (pixelsize == 1) {\n              for (int x = 0; x < (show_size >> swidth); x++) {\n                int color = x >> pos_shift;\n                int color_i = color << color_shift;\n                ptr[x] = color_i;\n              }\n            }\n            else if (pixelsize == 2) {\n              for (int x = 0; x < (show_size >> swidth); x++) {\n                int color = x >> pos_shift;\n                int color_i = color << color_shift;\n                reinterpret_cast<uint16_t *>(ptr)[x] = color_i;\n              }\n            }\n            else { // pixelsize == 4 float\n              for (int x = 0; x < (show_size >> swidth); x++) {\n                int color = x >> pos_shift;\n                float color_f = color / 255.0f;\n                reinterpret_cast<float *>(ptr)[x] = color_f;\n              }\n            }\n            ptr += dstPitch;\n          }\n        }\n        else {\n          if (!isGrey) {\n            // UV gradients plus danger zones\n            for (int gradient_upper_lower = 0; gradient_upper_lower < 2; gradient_upper_lower++)\n            {\n              // Draw upper and lower gradient\n            // upper: x=0-16, R=G=255, B=0; x=128, R=G=B=0; x=240-255, R=G=0, B=255\n            // lower: x=0-16, R=0, G=B=255; x=128, R=G=B=0; x=240-255, R=255, G=B=0\n              const int color1_upper_lower_gradient[2][3] = { { 210 / 2, 16 + 112 / 2, 128 },{ 170 / 2, 128, 16 + 112 / 2 } };\n              const int color2_upper_lower_gradient[2][3] = { { 41 / 2, 240 - 112 / 2, 128 },{ 81 / 2, 128, 240 - 112 / 2 } };\n              float color1_upper_lower_gradient_f[2][3] = { { c8tof(210 / 2), uv8tof(16 + 112 / 2), uv8tof(128) },{ c8tof(170 / 2), uv8tof(128), uv8tof(16 + 112 / 2) } };\n              float color2_upper_lower_gradient_f[2][3] = { { c8tof(41 / 2), uv8tof(240 - 112 / 2), uv8tof(128) },{ c8tof(81 / 2), uv8tof(128), uv8tof(240 - 112 / 2) } };\n              int color = color1_upper_lower_gradient[gradient_upper_lower][p];\n              int color_i = color << color_shift;\n              float color_f = color1_upper_lower_gradient_f[gradient_upper_lower][p];\n\n              int color2 = color2_upper_lower_gradient[gradient_upper_lower][p];\n              int color2_i = color2 << color_shift;\n              float color2_f = color2_upper_lower_gradient_f[gradient_upper_lower][p];;\n\n              // upper only for planar U and Y\n              if (plane == PLANAR_V && gradient_upper_lower == 0)\n                continue;\n              // lower only for planar V and Y\n              if (plane == PLANAR_U && gradient_upper_lower == 1)\n                continue;\n              int StartY = gradient_upper_lower == 0 ? 64 + 16 : 128 + 32;\n              ptr = pdstb + ((StartY) >> sheight) * dstPitch;\n              // we are drawing at the 64th relative line as well.\n              for (int y = (StartY) >> sheight; y <= (StartY + 64) >> sheight; y++) {\n                int x = 0;\n                // 0..15, (scaled) left danger area\n                const int left_limit = ((16 << pos_shift) >> swidth) - 1;\n                if (pixelsize == 1) {\n                  for (; x < left_limit; x++)\n                    ptr[x] = color_i;\n                }\n                else if (pixelsize == 2) {\n                  for (; x < left_limit; x++)\n                    reinterpret_cast<uint16_t*>(ptr)[x] = color_i;\n                }\n                else { // float\n                  for (; x < left_limit; x++)\n                    reinterpret_cast<float*>(ptr)[x] = color_f;\n                }\n\n                if (plane == PLANAR_Y) {\n                  // from 16 to middle point\n                  if (pixelsize == 1) {\n                    for (; x <= show_middle_pos; x++) {\n                      int color3 =\n                        (gradient_upper_lower == 0) ?\n                        (((show_middle_pos - x) * 15) >> 3) >> pos_shift : // *1.875\n                        ((show_middle_pos - x) * 99515) >> 16 >> pos_shift; // *1.518\n                      int color3_i = color3 << color_shift;\n                      ptr[x] = color3_i;\n                    }\n                  }\n                  else if (pixelsize == 2) {\n                    for (; x <= show_middle_pos; x++) {\n                      int color3 =\n                        (gradient_upper_lower == 0) ?\n                        (((show_middle_pos - x) * 15) >> 3) >> pos_shift : // *1.875\n                        ((show_middle_pos - x) * 99515) >> 16 >> pos_shift; // *1.518\n                      int color3_i = color3 << color_shift;\n                      reinterpret_cast<uint16_t*>(ptr)[x] = color3_i;\n                    }\n                  }\n                  else { // float\n                    for (; x <= show_middle_pos; x++) {\n                      int color3 =\n                        (gradient_upper_lower == 0) ?\n                        (((show_middle_pos - x) * 15) >> 3) >> pos_shift : // *1.875\n                        ((show_middle_pos - x) * 99515) >> 16 >> pos_shift; // *1.518\n                      float color3_f = color3 / 255.0f; // no shift this is Y\n                      reinterpret_cast<float*>(ptr)[x] = color3_f;\n                    }\n                  }\n                }\n\n                // Y: from middle point to white point\n                // other plane: gradient\n                if (plane == PLANAR_Y) {\n                  if (pixelsize == 1) {\n                    for (; x <= (240 << pos_shift) >> swidth; x++) {\n                      int color4 =\n                        (gradient_upper_lower == 0) ?\n                        ((x - show_middle_pos) * 24001) >> 16 >> pos_shift :  // *0.366\n                        ((x - show_middle_pos) * 47397) >> 16 >> pos_shift; // *0.723\n                      int color4_i = color4 << color_shift;\n                      ptr[x] = color4_i;\n                    }\n                  }\n                  else if (pixelsize == 2) {\n                    for (; x <= (240 << pos_shift) >> swidth; x++) {\n                      int color4 =\n                        (gradient_upper_lower == 0) ?\n                        ((x - show_middle_pos) * 24001) >> 16 >> pos_shift :  // *0.366\n                        ((x - show_middle_pos) * 47397) >> 16 >> pos_shift; // *0.723\n                      int color4_i = color4 << color_shift;\n                      reinterpret_cast<uint16_t*>(ptr)[x] = color4_i;\n                    }\n                  }\n                  else { // float\n                    for (; x <= (240 << pos_shift) >> swidth; x++) {\n                      int color4 =\n                        (gradient_upper_lower == 0) ?\n                        ((x - show_middle_pos) * 24001) >> 16 >> pos_shift :  // *0.366\n                        ((x - show_middle_pos) * 47397) >> 16 >> pos_shift; // *0.723\n                      float color4_f = color4 / 255.0f; // no shift, this is Y\n                      reinterpret_cast<float*>(ptr)[x] = color4_f;\n                    }\n                  }\n                }\n                else {\n                  // plane == U or V\n                  if (pixelsize == 1) {\n                    for (; x <= (240 << pos_shift) >> swidth; x++) {\n                      int color4 = (x << swidth) >> pos_shift;\n                      int color4_i = color4 << color_shift;\n                      ptr[x] = color4_i;\n                    }\n                  }\n                  else if (pixelsize == 2) {\n                    for (; x <= (240 << pos_shift) >> swidth; x++) {\n                      int color4 = (x << swidth) >> pos_shift;\n                      int color4_i = color4 << color_shift;\n                      reinterpret_cast<uint16_t*>(ptr)[x] = color4_i;\n                    }\n                  }\n                  else { // float\n                    for (; x <= (240 << pos_shift) >> swidth; x++) {\n                      int color4 = (x << swidth) >> pos_shift;\n                      reinterpret_cast<float*>(ptr)[x] = uv8tof(color4);\n                    }\n                  }\n                }\n\n                if (pixelsize == 1) {\n                  for (; x < (show_size >> swidth); x++)\n                    ptr[x] = color2_i;\n                }\n                else if (pixelsize == 2) {\n                  for (; x < (show_size >> swidth); x++)\n                    reinterpret_cast<uint16_t*>(ptr)[x] = color2_i;\n                }\n                else { // float\n                  for (; x < (show_size >> swidth); x++)\n                    reinterpret_cast<float*>(ptr)[x] = color2_f;\n                }\n\n                ptr += dstPitch;\n              } // for y gradient draw\n            } // gradient for upper lower\n          }\n        } // gradients for RGB/UV\n      } // if markers\n    } // planes for\n\n    // Draw dotted centerline\n    // YUV: only 1 plane (PLANAR_Y)\n    for (int p = 0; p < (RGB ? 3 : 1); p++) {\n      const int plane = planes[p];\n\n      int color = 128; // also good for RGB\n      int color_i = color << color_shift;\n      float color_f = 0.5f;\n\n      const int dstPitch = dst->GetPitch(plane);\n\n      unsigned char* pdstb = dst->GetWritePtr(plane);\n      pdstb += (xstart * pixelsize); // next to the original clip (if kept), working only on Y plane: no \">> swidth\" needed\n      BYTE* ptr = pdstb;\n\n      if (markers) {\n        // omit centerline if markers == false\n        // height of 64, 16 pixels between\n        // we are drawing at the 64th/224th relative line as well.\n        for (int y = 0; y <= 64 + (planecount - 1) * (16 + 64); y++) {\n          if ((y & 3) > 1) {\n            if (pixelsize == 1)       ptr[show_middle_pos] = color_i;\n            else if (pixelsize == 2)  reinterpret_cast<uint16_t*>(ptr)[show_middle_pos] = color_i;\n            else                   reinterpret_cast<float*>(ptr)[show_middle_pos] = color_f;\n\n          }\n          ptr += dstPitch;\n        }\n      }\n    }\n\n    for (int p = 0; p < (RGB ? 3 : 1); p++) {\n      const int plane = planes[p];\n\n      const int dstPitch = dst->GetPitch(plane);\n\n      unsigned char* pdstb = dst->GetWritePtr(plane);\n      pdstb += (xstart * pixelsize); // next to the original clip (if kept), working only on Y plane: no \">> swidth\" needed\n\n      // have to draw up to three parts: Y or Y,U,V or R,G,B\n      for (int n = 0; n < planecount; n++) {\n\n        // Draw histograms\n\n        // total pixel count must be divided by subsampling factors for U and V\n        int src_width = src->GetRowSize(planes[n]) / pixelsize;\n        int src_height = src->GetHeight(planes[n]);\n\n        const uint32_t clampval = (int)((src_width*src_height)*option.AsDblDef(100.0) / 100.0); // Population limit % factor\n        uint32_t maxval = 0;\n        uint32_t *hist;\n\n        hist = histPlanes[n];\n        for (int i = 0; i < show_size; i++) {\n          if (hist[i] > clampval) hist[i] = clampval;\n          maxval = max(hist[i], maxval);\n        }\n\n        // factor 0%: maxval may stay at 0.\n        float scale = maxval == 0 ? 64.0f : float(64.0 / maxval);\n\n        int color = RGB ? 255 : 235; // also good for RGB\n        int color_i = RGB ? (int)(color * color_shift_factor + 0.5f) :  color << color_shift;\n        float color_f = color / 255.0f;\n\n        int Y_pos;\n        switch (n) { // n: YUV 012, GBR 012\n        case 0: Y_pos = RGB ? 128 + 16 :  64 + 0; break;  // Y or G\n        case 1: Y_pos = RGB ? 192 + 32 : 128 + 16; break; // U or B\n        case 2: Y_pos = RGB ?  64 +  0 : 192 + 32; break; // V or R\n        }\n\n        for (int x = 0; x < show_size; x++) {\n          float scaled_h = (float)hist[x] * scale;\n          int h = Y_pos - min((int)scaled_h, 64) + 1;\n\n          uint8_t *ptr = pdstb + (Y_pos + 1) * dstPitch;\n\n          // Start from below the baseline\n          for (int y = Y_pos + 1; y > h; y--) {\n            if (pixelsize == 1)       ptr[x] = color_i;\n            else if (pixelsize == 2)  reinterpret_cast<uint16_t *>(ptr)[x] = color_i;\n            else                   reinterpret_cast<float *>(ptr)[x] = color_f;\n            ptr -= dstPitch;\n          }\n\n        }\n      }\n    }\n  }\n\n  env->Free(histPlane1);\n\n  return dst;\n}\n\n\nvoid Histogram::ClassicLUTInit()\n{\n  int internal_bits_per_pixel = (pixelsize == 4) ? 16 : bits_per_pixel; // 16bit histogram simulation for float\n\n  int tv_range_low = 16 << (internal_bits_per_pixel - 8); // 16\n  int tv_range_hi_luma = 235 << (internal_bits_per_pixel - 8); // 16-235\n  int range_luma = tv_range_hi_luma - tv_range_low; // 219\n  // exptab: population count within a line -> brigtness mapping\n  // exptab index (population) is maximized at 255 during the actual drawing\n  exptab.resize(256);\n  const double K = log(0.5 / 219) / 255.0; // approx -1/42\n  const int limit68 = 68 << (internal_bits_per_pixel - 8);\n  // exptab: pixel values for final drawing\n  exptab[0] = tv_range_low;\n  for (int i = 1; i < 255; i++) {\n    exptab[i] = uint16_t(tv_range_low + 0.5 + range_luma * (1 - exp(i*K))); // 16.5 + 219*\n    if (exptab[i] <= tv_range_hi_luma - limit68)\n      E167 = i; // index of last value less than...  for drawing lower extremes\n  }\n  exptab[255] = tv_range_hi_luma;\n}\n\nPVideoFrame Histogram::DrawModeClassic(int n, IScriptEnvironment* env)\n{\n\n  int show_size = 1 << show_bits;\n\n  int hist_tv_range_low = 16 << (show_bits - 8); // 16\n  int hist_tv_range_hi_luma = 235 << (show_bits - 8); // 16-235\n  int hist_range_luma = hist_tv_range_hi_luma - hist_tv_range_low; // 219\n  int hist_mid_range_luma = (hist_range_luma + 1) / 2 + hist_tv_range_low - 1; // in Classic Avisynth somehow 124 was fixed for this\n  // 235-16 = 219 / 2 => 110; 110 + 16 - 1 = 125.0\n\n  int internal_bits_per_pixel = (pixelsize == 4) ? 16 : bits_per_pixel; // 16bit histogram simulation for float\n\n  int middle_chroma = 1 << (internal_bits_per_pixel - 1); // 128\n\n  const int source_width = origwidth;\n  const int xstart = keepsource ? origwidth : 0; // drawing starts at this column\n\n  PVideoFrame src = child->GetFrame(n, env);\n  const BYTE* srcp = src->GetReadPtr();\n  const int srcpitch = src->GetPitch();\n\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n  BYTE* pdst = dst->GetWritePtr();\n  const int dstpitch = dst->GetPitch();\n\n  if (keepsource) {\n    env->BitBlt(pdst, dst->GetPitch(), src->GetReadPtr(), src->GetPitch(), src->GetRowSize(), src->GetHeight());\n  }\n  if (vi.IsPlanar()) {\n    if (keepsource) {\n      env->BitBlt(dst->GetWritePtr(PLANAR_U), dst->GetPitch(PLANAR_U), src->GetReadPtr(PLANAR_U), src->GetPitch(PLANAR_U), src->GetRowSize(PLANAR_U), src->GetHeight(PLANAR_U));\n      env->BitBlt(dst->GetWritePtr(PLANAR_V), dst->GetPitch(PLANAR_V), src->GetReadPtr(PLANAR_V), src->GetPitch(PLANAR_V), src->GetRowSize(PLANAR_V), src->GetHeight(PLANAR_V));\n    }\n\n    // luma\n    const int height = src->GetHeight(PLANAR_Y);\n\n    std::vector<int> hist;\n    hist.resize(1ULL << show_bits);\n\n    for (int y = 0; y<height; ++y) {\n      std::fill(hist.begin(), hist.end(), 0);\n      // accumulate line population\n      if(pixelsize==1) {\n        // 8 bit clip into 8,9,... bit histogram\n        int invshift = show_bits - 8;\n        for (int x = 0; x<source_width; ++x) {\n          hist[srcp[x] << invshift]++;\n        }\n      }\n      else if (pixelsize == 2) {\n        const uint16_t *srcp16 = reinterpret_cast<const uint16_t *>(srcp);\n        int shift = bits_per_pixel - show_bits;\n        int max_show_pixel_value = show_size - 1;\n        if (shift < 0) {\n          // 10 bit clip into 11 bit histogram\n          int invshift = -shift;\n          for (int x = 0; x < source_width; x++) {\n            hist[min(srcp16[x] << invshift, max_show_pixel_value)]++;\n          }\n        } else {\n          // e.g.10 bit clip into 8-9-10 bit histogram\n          for (int x = 0; x < source_width; x++) {\n            hist[min(srcp16[x] >> shift, max_show_pixel_value)]++;\n          }\n        }\n      }\n      else // pixelsize == 4\n      {\n        // float\n        const float *srcp32 = reinterpret_cast<const float *>(srcp);\n        const float multiplier = (float)(show_size - 1);\n        for (int x = 0; x < source_width; x++) {\n          hist[(intptr_t)(clamp(srcp32[x], 0.0f, 1.0f)*multiplier + 0.5f)]++; // luma, no shift needed\n        }\n      }\n      // accumulate end\n      BYTE* const q = pdst + xstart * pixelsize; // write to frame\n      if (markers) {\n        if (pixelsize == 1) {\n          for (int x = 0; x < show_size; ++x) {\n            if (x<hist_tv_range_low || x == hist_mid_range_luma || x>hist_tv_range_hi_luma) {\n              q[x] = (BYTE)exptab[min(E167, hist[x])] + 68; // brighter danger zone\n            }\n            else {\n              q[x] = (BYTE)exptab[min(255, hist[x])];\n            }\n          }\n        }\n        else if (pixelsize == 2) {\n          uint16_t *dstp16 = reinterpret_cast<uint16_t *>(q);\n          for (int x = 0; x < show_size; ++x) {\n            int h = hist[x];\n            if (x<hist_tv_range_low || x == hist_mid_range_luma || x>hist_tv_range_hi_luma) {\n              dstp16[x] = exptab[min(E167, h)] + (68 << (bits_per_pixel - 8));\n            }\n            else {\n              dstp16[x] = exptab[min(255, h)];\n            }\n          }\n        }\n        else { // pixelsize == 4\n          float *dstp32 = reinterpret_cast<float *>(q);\n          for (int x = 0; x < show_size; ++x) {\n            int h = hist[x];\n            if (x<hist_tv_range_low || x == hist_mid_range_luma || x>hist_tv_range_hi_luma) {\n              dstp32[x] = (exptab[min(E167, h)] + (68 << (internal_bits_per_pixel - 8))) / 65535.0f; // fake 0..65535 to 0..1.0\n            }\n            else {\n              dstp32[x] = exptab[min(255, h)] / 65535.0f;\n            }\n          }\n        }\n      }\n      else {\n        if (pixelsize == 1) {\n          for (int x = 0; x < show_size; ++x)\n            q[x] = (BYTE)exptab[min(255, hist[x])];\n        }\n        else if (pixelsize == 2) {\n          uint16_t *dstp16 = reinterpret_cast<uint16_t *>(q);\n          for (int x = 0; x < show_size; ++x) {\n            int h = hist[x];\n            dstp16[x] = exptab[min(255, h)];\n          }\n        }\n        else { // pixelsize == 4\n          float *dstp32 = reinterpret_cast<float *>(q);\n          for (int x = 0; x < show_size; ++x) {\n            int h = hist[x];\n            dstp32[x] = exptab[min(255, h)] / 65535.0f; // fake 0..65535 to 0..1.0\n          }\n        }\n      }\n      srcp += srcpitch;\n      pdst += dstpitch;\n    } // end of pixel accumulation + luma\n\n    // chroma\n    const int pitchUV = dst->GetPitch(PLANAR_U);\n\n    if (pitchUV != 0) {\n      const int subs = vi.GetPlaneWidthSubsampling(PLANAR_U);\n      const int fact = 1<<subs;\n\n      BYTE* p2 = dst->GetWritePtr(PLANAR_U) + ((xstart*pixelsize) >> subs); // put it on the right\n      BYTE* p3 = dst->GetWritePtr(PLANAR_V) + ((xstart*pixelsize) >> subs); // put it on the right\n\n      // if markers==false parameter, keep neutral coloring\n      const uint16_t color_u_offlimit8 = markers ? 16 : 128;\n      const uint16_t color_v_offlimit8 = markers ? 160 : 128;\n      const uint16_t color_u_centermark8 = markers ? 160 : 128;\n      const uint16_t color_v_centermark8 = markers ? 16 : 128;\n\n      const uint16_t color_u_offlimit = color_u_offlimit8 << (internal_bits_per_pixel - 8);\n      const uint16_t color_v_offlimit = color_v_offlimit8 << (internal_bits_per_pixel - 8);\n      const uint16_t color_u_centermark = color_u_centermark8 << (internal_bits_per_pixel - 8);\n      const uint16_t color_v_centermark = color_v_centermark8 << (internal_bits_per_pixel - 8);\n\n      const float color_u_offlimit_f = uv8tof(color_u_offlimit8);\n      const float color_v_offlimit_f = uv8tof(color_v_offlimit8);\n      const float color_u_centermark_f = uv8tof(color_u_centermark8);\n      const float color_v_centermark_f = uv8tof(color_v_centermark8);\n      const float middle_chroma_f = uv8tof(128);\n\n      const int height = src->GetHeight(PLANAR_U);\n      for (int y2 = 0; y2<height; ++y2) {\n        if(pixelsize==1) {\n          for (int x = 0; x<show_size; x += fact) {\n            if (x<hist_tv_range_low || x>hist_tv_range_hi_luma) {\n              p2[x >> subs] = (BYTE)color_u_offlimit8;\n              p3[x >> subs] = (BYTE)color_v_offlimit8;\n            } else if (x==hist_mid_range_luma) {\n              p2[x >> subs] = (BYTE)color_u_centermark8;\n              p3[x >> subs] = (BYTE)color_v_centermark8;\n            } else {\n              p2[x >> subs] = 128;\n              p3[x >> subs] = 128;\n            }\n          }\n        }\n        else if (pixelsize == 2) {\n          for (int x = 0; x<show_size; x += fact) {\n            if (x<hist_tv_range_low || x>hist_tv_range_hi_luma) {\n              reinterpret_cast<uint16_t *>(p2)[x >> subs] = color_u_offlimit;\n              reinterpret_cast<uint16_t *>(p3)[x >> subs] = color_v_offlimit;\n            } else if (x==hist_mid_range_luma) {\n              reinterpret_cast<uint16_t *>(p2)[x >> subs] = color_u_centermark;\n              reinterpret_cast<uint16_t *>(p3)[x >> subs] = color_v_centermark;\n            } else {\n              reinterpret_cast<uint16_t *>(p2)[x >> subs] = middle_chroma;\n              reinterpret_cast<uint16_t *>(p3)[x >> subs] = middle_chroma;\n            }\n          }\n        } else { // pixelsize==4\n          for (int x = 0; x<show_size; x += fact) {\n            if (x<hist_tv_range_low || x>hist_tv_range_hi_luma) {\n              reinterpret_cast<float *>(p2)[x >> subs] = color_u_offlimit_f;\n              reinterpret_cast<float *>(p3)[x >> subs] = color_v_offlimit_f;\n            } else if (x==hist_mid_range_luma) {\n              reinterpret_cast<float *>(p2)[x >> subs] = color_u_centermark_f;\n              reinterpret_cast<float *>(p3)[x >> subs] = color_v_centermark_f;\n            } else {\n              reinterpret_cast<float *>(p2)[x >> subs] = middle_chroma_f;\n              reinterpret_cast<float *>(p3)[x >> subs] = middle_chroma_f;\n            }\n          }\n\n        }\n        p2 += pitchUV;\n        p3 += pitchUV;\n      }\n    }\n  } else {\n    const int pitch = dst->GetPitch();\n    for (int y = 0; y<src->GetHeight(); ++y) { // YUY2\n      int hist[256] = { 0 };\n      for (int x = 0; x<source_width; ++x) {\n        hist[srcp[x*2]]++;\n      }\n      BYTE* const q = pdst + xstart*2;\n      if (markers) {\n        for (int x = 0; x < 256; x += 2) {\n          if (x < 16 || x>235) {\n            q[x * 2 + 0] = (BYTE)exptab[min(E167, hist[x])] + 68;\n            q[x * 2 + 1] = 16;\n            q[x * 2 + 2] = (BYTE)exptab[min(E167, hist[x + 1])] + 68;\n            q[x * 2 + 3] = 160;\n          }\n          else if (x == 124) {\n            q[x * 2 + 0] = (BYTE)exptab[min(E167, hist[x])] + 68;\n            q[x * 2 + 1] = 160;\n            q[x * 2 + 2] = (BYTE)exptab[min(255, hist[x + 1])];\n            q[x * 2 + 3] = 16;\n          }\n          else {\n            q[x * 2 + 0] = (BYTE)exptab[min(255, hist[x])];\n            q[x * 2 + 1] = 128;\n            q[x * 2 + 2] = (BYTE)exptab[min(255, hist[x + 1])];\n            q[x * 2 + 3] = 128;\n          }\n        }\n      }\n      else {\n        for (int x = 0; x < 256; x += 2) {\n          q[x * 2 + 0] = (BYTE)exptab[min(255, hist[x])];\n          q[x * 2 + 1] = 128;\n          q[x * 2 + 2] = (BYTE)exptab[min(255, hist[x + 1])];\n          q[x * 2 + 3] = 128;\n        }\n      }\n      pdst += pitch;\n      srcp += srcpitch;\n    }\n  }\n  return dst;\n}\n\n\nAVSValue __cdecl Histogram::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  const char* st_m = args[1].AsString(\"classic\");\n\n  Mode mode = ModeClassic;\n\n  if (!lstrcmpi(st_m, \"classic\"))\n    mode = ModeClassic;\n\n  if (!lstrcmpi(st_m, \"levels\"))\n    mode = ModeLevels;\n\n  if (!lstrcmpi(st_m, \"color\"))\n    mode = ModeColor;\n\n  if (!lstrcmpi(st_m, \"color2\"))\n    mode = ModeColor2;\n\n  if (!lstrcmpi(st_m, \"luma\"))\n    mode = ModeLuma;\n\n  if (!lstrcmpi(st_m, \"stereoY8\"))\n    mode = ModeStereoY8;\n\n  if (!lstrcmpi(st_m, \"stereo\"))\n    mode = ModeStereo;\n\n  if (!lstrcmpi(st_m, \"stereooverlay\"))\n    mode = ModeOverlay;\n\n  if (!lstrcmpi(st_m, \"audiolevels\"))\n    mode = ModeAudioLevels;\n\n  const VideoInfo& vi_orig = args[0].AsClip()->GetVideoInfo();\n\n  histogram_color2_params color2_params;\n  const char *graticule_str = args[7].AsString(\"on\"); // ON: old vectorscopes always drew limits/danger zones\n\n  // Use the lstrcmpi macro from your compatibility header\n  if (lstrcmpi(graticule_str, \"auto\") == 0) {\n    color2_params.graticule_type = histogram_color2_params::GRATICULE_AUTO;\n  }\n  else if (lstrcmpi(graticule_str, \"on\") == 0) {\n    color2_params.graticule_type = histogram_color2_params::GRATICULE_ON;\n  }\n  else if (lstrcmpi(graticule_str, \"off\") == 0) {\n    color2_params.graticule_type = histogram_color2_params::GRATICULE_OFF;\n  }\n  else {\n    env->ThrowError(\"Histogram: 'graticule' must be \\\"on\\\", \\\"off\\\", or \\\"auto\\\".\");\n  }\n\n  color2_params.targets = args[8].AsBool(false); // The 6 75% RGB squares\n  color2_params.axes = args[9].AsBool(false); // horizontal and vertical axes\n  color2_params.iq = args[10].AsBool(false); // +/-I and +Q targets\n  color2_params.iq_lines = args[11].AsBool(false); // 33 and 123 degree lines in the color2 mode\n  color2_params.circle = args[12].AsBool(mode == ModeColor2 ? true : false); // circle in the color2 mode default\n  color2_params.targets100 = args[13].AsBool(false); // The 6 100% RGB squares\n\n  if (mode == ModeLevels && vi_orig.IsRGB() && !vi_orig.IsPlanar()) {\n    // as Levels can work for PlanarRGB, convert packed RGB to planar, then back\n    // better that nothing\n    AVSValue new_args[1] = { args[0].AsClip() };\n    PClip clip;\n    if (vi_orig.IsRGB24() || vi_orig.IsRGB48()) {\n      clip = env->Invoke(\"ConvertToPlanarRGB\", AVSValue(new_args, 1)).AsClip();\n    }\n    else if (vi_orig.IsRGB32() || vi_orig.IsRGB64()) {\n      clip = env->Invoke(\"ConvertToPlanarRGBA\", AVSValue(new_args, 1)).AsClip();\n    }\n\n    Histogram* Result = new Histogram(clip, mode, args[2], args[3].AsInt(8), args[4].AsBool(true),\n      args[5].AsBool(true),\n      args[6].AsString(\"\"), // matrix_name\n      color2_params,\n      env);\n\n    AVSValue new_args2[1] = { Result };\n    if (vi_orig.IsRGB24()) {\n      return env->Invoke(\"ConvertToRGB24\", AVSValue(new_args2, 1)).AsClip();\n    }\n    else if (vi_orig.IsRGB48()) {\n      return env->Invoke(\"ConvertToRGB48\", AVSValue(new_args2, 1)).AsClip();\n    }\n    else if (vi_orig.IsRGB32()) {\n      return env->Invoke(\"ConvertToRGB32\", AVSValue(new_args2, 1)).AsClip();\n    }\n    else { // if (vi_orig.IsRGB64())\n      return env->Invoke(\"ConvertToRGB64\", AVSValue(new_args2, 1)).AsClip();\n    }\n  }\n  else {\n    return new Histogram(args[0].AsClip(), mode, args[2], args[3].AsInt(8), args[4].AsBool(true),\n      args[5].AsBool(true), // markers\n      args[6].AsString(\"\"), // matrix_name\n      color2_params,\n      env);\n  }\n}\n"
  },
  {
    "path": "avs_core/filters/histogram.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n#ifndef __Histogram_H__\n#define __Histogram_H__\n\n#include <avisynth.h>\n#include <vector>\n#include \"stdint.h\"\n#include \"../convert/convert_matrix.h\"\n#include <string>\n\n/********************************************************************\n********************************************************************/\n\nstruct histogram_color2_params {\n  enum GraticuleType {\n    GRATICULE_OFF=0,\n    GRATICULE_ON,\n    GRATICULE_AUTO\n  };\n  GraticuleType graticule_type; // paint graticule on histogram on off auto\n  bool targets; // the 6 color bar boxes\n  bool axes; // paint axes horizontal + vertical cross\n  bool iq; // paint +-I/+Q boxes on histogram\n  bool iq_lines; // paint I/Q diagonal lines on histogram\n  bool circle; // paint circle on histogram, originally only at \"color2\"\n  bool targets100; // the 6 color bar boxes at 100%\n};\n\nclass Histogram : public GenericVideoFilter\n/**\n  * Class to display histogram based on video input\n **/\n{\npublic:\n  enum Mode {\n    ModeClassic=0,\n\tModeLevels,\n\tModeColor,\n\tModeColor2,\n\tModeLuma,\n\tModeStereoY8,\n\tModeStereo,\n\tModeOverlay,\n\tModeAudioLevels\n  };\n\n  Histogram(PClip _child, Mode _mode, AVSValue _option, int _show_bits, bool _keepsource, bool _markers, const char* _matrix_name, histogram_color2_params _color2_params, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n  PVideoFrame DrawModeClassic    (int n, IScriptEnvironment* env);\n  PVideoFrame DrawModeLevels     (int n, IScriptEnvironment* env);\n  PVideoFrame DrawModeColor      (int n, IScriptEnvironment* env);\n  PVideoFrame DrawModeColor2     (int n, IScriptEnvironment* env);\n  PVideoFrame DrawModeLuma       (int n, IScriptEnvironment* env);\n  PVideoFrame DrawModeStereo     (int n, IScriptEnvironment* env);\n  PVideoFrame DrawModeOverlay    (int n, IScriptEnvironment* env);\n  PVideoFrame DrawModeAudioLevels(int n, IScriptEnvironment* env);\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\nprivate:\n  Mode mode;\n  int deg15c[24], deg15s[24];\n  double color2_innerF;\n  PClip aud_clip;\n  AVSValue option;\n  int pixelsize;\n  int bits_per_pixel;\n  int show_bits; // e.g. levels for 10 bits\n  bool keepsource; // return only the Histogram drawing\n  bool markers; // paint hazardous YUV area \"levels\": draw unsafe zone, \"classic\"\n\n  histogram_color2_params color2_params;\n\n  int origwidth;\n  int origheight;\n\n  // read from defaults/props/matrix overrides\n  int theMatrix;\n  int theColorRange;\n  bool full_range;\n  // separate out set for rgb target\n  int theOutColorRange;\n  ConversionMatrix matrix;\n\n  int E167;\n  std::vector<uint16_t> exptab;\n  void ClassicLUTInit();\n  PVideoFrame VectorscopePrelude(\n    int n, IScriptEnvironment* env,\n    PVideoFrame& src,\n    // out:\n    int& dst_pitch, int& dst_height,\n    int& dst_pitchUV, int& dst_heightUV,\n    int& dst_pitchA, int& dst_heightA,\n    BYTE*& panel, BYTE*& panelU, BYTE*& panelV, BYTE*& panelA);\n};\n\n\n#endif  // __Histogram_H__\n"
  },
  {
    "path": "avs_core/filters/intel/check_avx512.h",
    "content": "// Avisynth+\n// https://avs-plus.net\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __CHECK_AVX512_H__\n#define __CHECK_AVX512_H__\n\n// Important note: do not include this header from non-avx512 cpp files.\n\n#include <immintrin.h> // includes all intel intrinsics headers\n// GCC/clang compiler flags for matching CPUF_AVX512_FAST:\n// \" -mfma -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl -mavx512vnni -mavx512vbmi -mavx512vbmi2 -mavx512bitalg -mavx512vpopcntdq \"\n\n// Compiler feature checks and error handling\n// Here we only check for F and BW as sanity check, Avisynth's CMakeLists.txt should ensure proper flags are set.\n#if defined(__clang__) && !defined(_MSC_VER)\n#if !defined(__AVX512F__) || !defined(__AVX512BW__)\n#error \"This code requires a compiler that supports AVX-512F and AVX-512BW.  Use compiler flags -mavx512f -mavx512bw.\"\n#endif\n#elif defined(__GNUC__)\n#if !defined(__AVX512F__) || !defined(__AVX512BW__)\n#error \"This code requires a compiler that supports AVX-512F and AVX-512BW.  Use compiler flags -mavx512f -mavx512bw.\"\n#endif\n#elif defined(_MSC_VER)\n  #if !defined(_M_X64) && !defined(_M_AMD64) && !defined(_M_ARM64)\n  #error \"AVX-512 is only supported on x64 and ARM64 architectures.\"\n  #endif\n  // MSVC's <immintrin.h> provides AVX-512 support when /arch:AVX512 is used.\n  // However, MSVC may not define __AVX512F__ or __AVX512BW__ consistently.\n  // We rely on /arch:AVX512 having been set, and assume that if the user is\n  // including this header, they intend to use AVX-512.\n#else\n  #error \"Unsupported compiler. This code requires a compiler that supports AVX-512F and AVX-512BW (GCC, Clang, or MSVC).\"\n#endif\n\n#if !defined(__FMA__)\n// Assume that all processors that have AVX2/AVX512 also have FMA3\n#if defined (__GNUC__) && ! defined (__INTEL_COMPILER) && ! defined (__clang__)\n// Prevent error message in g++ when using FMA intrinsics with avx2:\n#pragma message \"It is recommended to specify also option -mfma when using -mavx2 or higher\"\n#else\n#define __FMA__  1\n#endif\n#endif\n// FMA3 instruction set\n#if defined (__FMA__) && (defined(__GNUC__) || defined(__clang__))  && ! defined (__INTEL_COMPILER)\n#include <fmaintrin.h>\n#endif // __FMA__\n\n// MSVC Missing Intrinsics (Workaround for older MSVC versions)\n#if defined(_MSC_VER) && !defined(__clang__)\n#if _MSC_VER < 1922 // Check for MSVC version less than 16.2 (VS 2019 16.2)\n  // Define missing AVX-512BW mask intrinsics for older MSVC.\n  // inline functions that perform the mask operations directly.\n  // Since this is MSVC only, using specific __forceinline.\n__forceinline __mmask64 _kand_mask64(__mmask64 a, __mmask64 b) { return a & b; }\n__forceinline __mmask64 _kor_mask64(__mmask64 a, __mmask64 b) { return a | b; }\n__forceinline __mmask32 _kand_mask32(__mmask32 a, __mmask32 b) { return a & b; }\n__forceinline __mmask32 _kor_mask32(__mmask32 a, __mmask32 b) { return a | b; }\n#endif\n#endif\n\n#endif // __CHECK_AVX512_H__\n"
  },
  {
    "path": "avs_core/filters/intel/focus_avx2.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include <avs/config.h>\n#include <avs/types.h>\n#include <cstdint>\n#include <type_traits>\n#include \"../core/internal.h\"\n\n// Intrinsics base header + really required extension headers\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n#include <immintrin.h>\n\n#if !defined(__FMA__)\n// Assume that all processors that have AVX2 also have FMA3\n#if defined (__GNUC__) && ! defined (__INTEL_COMPILER) && ! defined (__clang__)\n// Prevent error message in g++ when using FMA intrinsics with avx2:\n#pragma message \"It is recommended to specify also option -mfma when using -mavx2 or higher\"\n#else\n#define __FMA__  1\n#endif\n#endif\n// FMA3 instruction set\n#if defined (__FMA__) && (defined(__GNUC__) || defined(__clang__))  && ! defined (__INTEL_COMPILER)\n#include <fmaintrin.h>\n#endif // __FMA__\n\n\n#ifndef _mm256_set_m128i\n#define _mm256_set_m128i(v0, v1) _mm256_insertf128_si256(_mm256_castsi128_si256(v1), (v0), 1)\n#endif\n\n#ifndef _mm256_set_m128\n#define _mm256_set_m128(v0, v1) _mm256_insertf128_ps(_mm256_castps128_ps256(v1), (v0), 1)\n#endif\n\n#ifndef _mm256_cvtsi256_si32\n// int _mm256_cvtsi256_si32 (__m256i a)\n#define _mm256_cvtsi256_si32(a) (_mm_cvtsi128_si32(_mm256_castsi256_si128(a)))\n#endif\n\nstatic AVS_FORCEINLINE __m256i af_blend_avx2(__m256i &upper, __m256i &center, __m256i &lower, __m256i &center_weight, __m256i &outer_weight, __m256i &round_mask) {\n  __m256i outer_tmp = _mm256_add_epi16(upper, lower);\n  __m256i center_tmp = _mm256_mullo_epi16(center, center_weight);\n\n  outer_tmp = _mm256_mullo_epi16(outer_tmp, outer_weight);\n\n  __m256i result = _mm256_adds_epi16(center_tmp, outer_tmp);\n  result = _mm256_adds_epi16(result, center_tmp);\n  result = _mm256_adds_epi16(result, round_mask);\n  return _mm256_srai_epi16(result, 7);\n}\n\nstatic AVS_FORCEINLINE __m256i af_blend_uint16_t_avx2(__m256i &upper, __m256i &center, __m256i &lower, __m256i &center_weight, __m256i &outer_weight, __m256i &round_mask) {\n  __m256i outer_tmp = _mm256_add_epi32(upper, lower);\n  __m256i center_tmp;\n  center_tmp = _mm256_mullo_epi32(center, center_weight);\n  outer_tmp = _mm256_mullo_epi32(outer_tmp, outer_weight);\n\n  __m256i result = _mm256_add_epi32(center_tmp, outer_tmp);\n  result = _mm256_add_epi32(result, center_tmp);\n  result = _mm256_add_epi32(result, round_mask);\n  return _mm256_srai_epi32(result, 7);\n}\n\nstatic AVS_FORCEINLINE __m256i af_unpack_blend_avx2(__m256i &left, __m256i &center, __m256i &right, __m256i &center_weight, __m256i &outer_weight, __m256i &round_mask, __m256i &zero) {\n  __m256i left_lo = _mm256_unpacklo_epi8(left, zero);\n  __m256i left_hi = _mm256_unpackhi_epi8(left, zero);\n  __m256i center_lo = _mm256_unpacklo_epi8(center, zero);\n  __m256i center_hi = _mm256_unpackhi_epi8(center, zero);\n  __m256i right_lo = _mm256_unpacklo_epi8(right, zero);\n  __m256i right_hi = _mm256_unpackhi_epi8(right, zero);\n\n  __m256i result_lo = af_blend_avx2(left_lo, center_lo, right_lo, center_weight, outer_weight, round_mask);\n  __m256i result_hi = af_blend_avx2(left_hi, center_hi, right_hi, center_weight, outer_weight, round_mask);\n\n  return _mm256_packus_epi16(result_lo, result_hi);\n}\n\nstatic AVS_FORCEINLINE __m256i af_unpack_blend_uint16_t_avx2(__m256i &left, __m256i &center, __m256i &right, __m256i &center_weight, __m256i &outer_weight, __m256i &round_mask, __m256i &zero) {\n  __m256i left_lo = _mm256_unpacklo_epi16(left, zero);\n  __m256i left_hi = _mm256_unpackhi_epi16(left, zero);\n  __m256i center_lo = _mm256_unpacklo_epi16(center, zero);\n  __m256i center_hi = _mm256_unpackhi_epi16(center, zero);\n  __m256i right_lo = _mm256_unpacklo_epi16(right, zero);\n  __m256i right_hi = _mm256_unpackhi_epi16(right, zero);\n\n  __m256i result_lo = af_blend_uint16_t_avx2(left_lo, center_lo, right_lo, center_weight, outer_weight, round_mask);\n  __m256i result_hi = af_blend_uint16_t_avx2(left_hi, center_hi, right_hi, center_weight, outer_weight, round_mask);\n  return _mm256_packus_epi32(result_lo, result_hi);\n}\n\nvoid af_vertical_uint16_t_avx2(BYTE* line_buf, BYTE* dstp, int height, int pitch, int row_size, int amount) {\n  // amount was: half_amount (32768). Full: 65536 (2**16)\n  // now it becomes 2**(16-9)=2**7 scale\n  int t = (amount + 256) >> 9; // 16-9 = 7 -> shift in\n  __m256i center_weight = _mm256_set1_epi32(t);\n  __m256i outer_weight = _mm256_set1_epi32(64 - t);\n  __m256i round_mask = _mm256_set1_epi32(0x40);\n  __m256i zero = _mm256_setzero_si256();\n\n  for (int y = 0; y < height - 1; ++y) {\n    for (int x = 0; x < row_size; x += 32) {\n      __m256i upper = _mm256_load_si256(reinterpret_cast<const __m256i*>(line_buf + x));\n      __m256i center = _mm256_load_si256(reinterpret_cast<const __m256i*>(dstp + x));\n      __m256i lower = _mm256_load_si256(reinterpret_cast<const __m256i*>(dstp + pitch + x));\n      _mm256_store_si256(reinterpret_cast<__m256i*>(line_buf + x), center);\n\n      __m256i upper_lo = _mm256_unpacklo_epi16(upper, zero);\n      __m256i upper_hi = _mm256_unpackhi_epi16(upper, zero);\n      __m256i center_lo = _mm256_unpacklo_epi16(center, zero);\n      __m256i center_hi = _mm256_unpackhi_epi16(center, zero);\n      __m256i lower_lo = _mm256_unpacklo_epi16(lower, zero);\n      __m256i lower_hi = _mm256_unpackhi_epi16(lower, zero);\n\n      __m256i result_lo = af_blend_uint16_t_avx2(upper_lo, center_lo, lower_lo, center_weight, outer_weight, round_mask);\n      __m256i result_hi = af_blend_uint16_t_avx2(upper_hi, center_hi, lower_hi, center_weight, outer_weight, round_mask);\n\n      __m256i result = _mm256_packus_epi32(result_lo, result_hi);\n\n      _mm256_store_si256(reinterpret_cast<__m256i*>(dstp + x), result);\n    }\n    dstp += pitch;\n  }\n\n  //last line\n  for (int x = 0; x < row_size; x += 32) {\n    __m256i upper = _mm256_load_si256(reinterpret_cast<const __m256i*>(line_buf + x));\n    __m256i center = _mm256_load_si256(reinterpret_cast<const __m256i*>(dstp + x));\n\n    __m256i upper_lo = _mm256_unpacklo_epi16(upper, zero);\n    __m256i upper_hi = _mm256_unpackhi_epi16(upper, zero);\n    __m256i center_lo = _mm256_unpacklo_epi16(center, zero);\n    __m256i center_hi = _mm256_unpackhi_epi16(center, zero);\n\n    __m256i result_lo = af_blend_uint16_t_avx2(upper_lo, center_lo, center_lo, center_weight, outer_weight, round_mask);\n    __m256i result_hi = af_blend_uint16_t_avx2(upper_hi, center_hi, center_hi, center_weight, outer_weight, round_mask);\n\n    __m256i result;\n    result = _mm256_packus_epi32(result_lo, result_hi);\n\n    _mm256_store_si256(reinterpret_cast<__m256i*>(dstp + x), result);\n  }\n}\n\nvoid af_vertical_avx2(BYTE* line_buf, BYTE* dstp, int height, int pitch, int width, int amount) {\n  short t = (amount + 256) >> 9;\n  __m256i center_weight = _mm256_set1_epi16(t);\n  __m256i outer_weight = _mm256_set1_epi16(64 - t);\n  __m256i round_mask = _mm256_set1_epi16(0x40);\n  __m256i zero = _mm256_setzero_si256();\n\n  for (int y = 0; y < height - 1; ++y) {\n    for (int x = 0; x < width; x += 32) {\n      __m256i upper = _mm256_load_si256(reinterpret_cast<const __m256i*>(line_buf + x));\n      __m256i center = _mm256_load_si256(reinterpret_cast<const __m256i*>(dstp + x));\n      __m256i lower = _mm256_load_si256(reinterpret_cast<const __m256i*>(dstp + pitch + x));\n      _mm256_store_si256(reinterpret_cast<__m256i*>(line_buf + x), center);\n\n      __m256i upper_lo = _mm256_unpacklo_epi8(upper, zero);\n      __m256i upper_hi = _mm256_unpackhi_epi8(upper, zero);\n      __m256i center_lo = _mm256_unpacklo_epi8(center, zero);\n      __m256i center_hi = _mm256_unpackhi_epi8(center, zero);\n      __m256i lower_lo = _mm256_unpacklo_epi8(lower, zero);\n      __m256i lower_hi = _mm256_unpackhi_epi8(lower, zero);\n\n      __m256i result_lo = af_blend_avx2(upper_lo, center_lo, lower_lo, center_weight, outer_weight, round_mask);\n      __m256i result_hi = af_blend_avx2(upper_hi, center_hi, lower_hi, center_weight, outer_weight, round_mask);\n\n      __m256i result = _mm256_packus_epi16(result_lo, result_hi);\n\n      _mm256_store_si256(reinterpret_cast<__m256i*>(dstp + x), result);\n    }\n    dstp += pitch;\n  }\n\n  //last line\n  for (int x = 0; x < width; x += 32) {\n    __m256i upper = _mm256_load_si256(reinterpret_cast<const __m256i*>(line_buf + x));\n    __m256i center = _mm256_load_si256(reinterpret_cast<const __m256i*>(dstp + x));\n\n    __m256i upper_lo = _mm256_unpacklo_epi8(upper, zero);\n    __m256i upper_hi = _mm256_unpackhi_epi8(upper, zero);\n    __m256i center_lo = _mm256_unpacklo_epi8(center, zero);\n    __m256i center_hi = _mm256_unpackhi_epi8(center, zero);\n\n    __m256i result_lo = af_blend_avx2(upper_lo, center_lo, center_lo, center_weight, outer_weight, round_mask);\n    __m256i result_hi = af_blend_avx2(upper_hi, center_hi, center_hi, center_weight, outer_weight, round_mask);\n\n    __m256i result = _mm256_packus_epi16(result_lo, result_hi);\n\n    _mm256_store_si256(reinterpret_cast<__m256i*>(dstp + x), result);\n  }\n}\n\n// -------------------------------------\n// Blur/Sharpen Horizontal YV12 C++ Code\n// -------------------------------------\n\ntemplate<typename pixel_t>\nstatic AVS_FORCEINLINE void af_horizontal_planar_process_line_c(pixel_t left, BYTE *dstp8, size_t row_size, int center_weight, int outer_weight) {\n  size_t x;\n  pixel_t* dstp = reinterpret_cast<pixel_t *>(dstp8);\n  typedef typename std::conditional < sizeof(pixel_t) == 1, int, int64_t>::type weight_t; // for calling the right ScaledPixelClip()\n  size_t width = row_size / sizeof(pixel_t);\n  for (x = 0; x < width-1; ++x) {\n    pixel_t temp = ScaledPixelClip((weight_t)(dstp[x] * (weight_t)center_weight + (left + dstp[x+1]) * (weight_t)outer_weight));\n    left = dstp[x];\n    dstp[x] = temp;\n  }\n  // ScaledPixelClip has 2 overloads: BYTE/uint16_t (int/int64 i)\n  dstp[x] = ScaledPixelClip((weight_t)(dstp[x] * (weight_t)center_weight + (left + dstp[x]) * (weight_t)outer_weight));\n}\n\nstatic AVS_FORCEINLINE void af_horizontal_planar_process_line_uint16_c(uint16_t left, BYTE *dstp8, size_t row_size, int center_weight, int outer_weight, int bits_per_pixel) {\n  size_t x;\n  typedef uint16_t pixel_t;\n  pixel_t* dstp = reinterpret_cast<pixel_t *>(dstp8);\n  const int max_pixel_value = (1 << bits_per_pixel) - 1; // clamping on 10-12-14-16 bitdepth\n  typedef std::conditional < sizeof(pixel_t) == 1, int, int64_t>::type weight_t; // for calling the right ScaledPixelClip()\n  size_t width = row_size / sizeof(pixel_t);\n  for (x = 0; x < width-1; ++x) {\n    pixel_t temp = (pixel_t)ScaledPixelClipEx((weight_t)(dstp[x] * (weight_t)center_weight + (left + dstp[x+1]) * (weight_t)outer_weight), max_pixel_value);\n    left = dstp[x];\n    dstp[x] = temp;\n  }\n  // ScaledPixelClip has 2 overloads: BYTE/uint16_t (int/int64 i)\n  dstp[x] = ScaledPixelClipEx((weight_t)(dstp[x] * (weight_t)center_weight + (left + dstp[x]) * (weight_t)outer_weight), max_pixel_value);\n}\n\nvoid af_horizontal_planar_avx2(BYTE* dstp, size_t height, size_t pitch, size_t width, size_t amount) {\n  size_t mod32_width = (width / 32) * 32;\n  size_t sse_loop_limit = width == mod32_width ? mod32_width - 32 : mod32_width;\n  int center_weight_c = int(amount*2);\n  int outer_weight_c = int(32768-amount);\n\n  short t = short((amount + 256) >> 9);\n  __m256i center_weight = _mm256_set1_epi16(t);\n  __m256i outer_weight = _mm256_set1_epi16(64 - t);\n  __m256i round_mask = _mm256_set1_epi16(0x40);\n  __m256i zero = _mm256_setzero_si256();\n\n  __m128i left_mask_128 = _mm_set_epi32(0, 0, 0, 0xFF);\n  __m128i right_mask_128 = _mm_set_epi8((char)0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);\n\n  __m256i left;\n\n  for (size_t y = 0; y < height; ++y) {\n    //left border\n    __m256i center = _mm256_load_si256(reinterpret_cast<const __m256i*>(dstp));\n    __m256i right = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(dstp+1));\n    __m128i center_lo128 = _mm256_extractf128_si256(center, 0);\n    __m128i left_lo128 = _mm_or_si128(_mm_and_si128(center_lo128, left_mask_128), _mm_slli_si128(center_lo128, 1));\n    __m128i left_hi128 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(dstp + 16 - 1));\n    left = _mm256_set_m128i(left_hi128, left_lo128);\n\n    __m256i result = af_unpack_blend_avx2(left, center, right, center_weight, outer_weight, round_mask, zero);\n    left = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(dstp+32-1));\n    _mm256_store_si256(reinterpret_cast<__m256i*>(dstp), result);\n\n    //main processing loop\n    for (size_t x = 32; x < sse_loop_limit; x+= 32) {\n      center = _mm256_load_si256(reinterpret_cast<const __m256i*>(dstp+x));\n      right = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(dstp+x+1));\n\n      result = af_unpack_blend_avx2(left, center, right, center_weight, outer_weight, round_mask, zero);\n\n      left = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(dstp+x+32-1)); // read ahead to prevent overwrite\n\n      _mm256_store_si256(reinterpret_cast<__m256i*>(dstp+x), result);\n    }\n\n    //right border\n    if(mod32_width == width) { //width is mod32, process with simd\n      center = _mm256_load_si256(reinterpret_cast<const __m256i*>(dstp + mod32_width - 32));\n\n      __m128i right_lo128 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(dstp + mod32_width - 32 + 1));\n      __m128i center_hi128 = _mm256_extractf128_si256(center, 1); // get high 128bit, really right! ptr+16\n      __m128i right_hi128 = _mm_or_si128(_mm_and_si128(center_hi128, right_mask_128), _mm_srli_si128(center_hi128, 1));\n      right = _mm256_set_m128i(right_hi128, right_lo128);\n\n      result = af_unpack_blend_avx2(left, center, right, center_weight, outer_weight, round_mask, zero);\n\n      _mm256_store_si256(reinterpret_cast<__m256i*>(dstp+mod32_width-32), result);\n    } else { //some stuff left\n      BYTE l = _mm256_cvtsi256_si32(left) & 0xFF;\n      af_horizontal_planar_process_line_c<uint8_t>(l, dstp+mod32_width, width-mod32_width, center_weight_c, outer_weight_c);\n\n    }\n\n    dstp += pitch;\n  }\n}\n\nvoid af_horizontal_planar_uint16_t_avx2(BYTE* dstp, size_t height, size_t pitch, size_t row_size, size_t amount, int bits_per_pixel) {\n  size_t mod32_width = (row_size / 32) * 32;\n  size_t sse_loop_limit = row_size == mod32_width ? mod32_width - 32 : mod32_width;\n  int center_weight_c = int(amount * 2);\n  int outer_weight_c = int(32768 - amount);\n\n  int t = int((amount + 256) >> 9);\n  __m256i center_weight = _mm256_set1_epi32(t);\n  __m256i outer_weight = _mm256_set1_epi32(64 - t);\n  __m256i round_mask = _mm256_set1_epi32(0x40);\n  __m256i zero = _mm256_setzero_si256();\n\n  __m128i left_mask_128 = _mm_set_epi16(0, 0, 0, 0, 0, 0, 0, (short)0xFFFF); // 0, 0, 0, 0, 0, 0, 0, FFFF\n  __m128i right_mask_128 = _mm_set_epi16((short)0xFFFF, 0, 0, 0, 0, 0, 0, 0);\n\n  __m256i left;\n\n  for (size_t y = 0; y < height; ++y) {\n    //left border\n    __m256i center = _mm256_load_si256(reinterpret_cast<const __m256i*>(dstp));\n    __m256i right = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(dstp + sizeof(uint16_t)));\n    __m128i center_lo128 = _mm256_extractf128_si256(center, 0);\n    __m128i left_lo128 = _mm_or_si128(_mm_and_si128(center_lo128, left_mask_128), _mm_slli_si128(center_lo128, sizeof(uint16_t)));\n    __m128i left_hi128 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(dstp + 16 - sizeof(uint16_t)));\n    left = _mm256_set_m128i(left_hi128, left_lo128);\n\n    __m256i result = af_unpack_blend_uint16_t_avx2(left, center, right, center_weight, outer_weight, round_mask, zero);\n    left = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(dstp + (32 - sizeof(uint16_t))));\n    _mm256_store_si256(reinterpret_cast<__m256i*>(dstp), result);\n\n    //main processing loop\n    for (size_t x = 32; x < sse_loop_limit; x += 32) {\n      center = _mm256_load_si256(reinterpret_cast<const __m256i*>(dstp + x));\n      right = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(dstp + x + sizeof(uint16_t)));\n\n      result = af_unpack_blend_uint16_t_avx2(left, center, right, center_weight, outer_weight, round_mask, zero);\n\n      left = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(dstp + x + (32 - sizeof(uint16_t)))); // read ahead to prevent overwrite\n\n      _mm256_store_si256(reinterpret_cast<__m256i*>(dstp + x), result);\n    }\n\n    //right border\n    if (mod32_width == row_size) { //width is mod32, process with simd\n      center = _mm256_load_si256(reinterpret_cast<const __m256i*>(dstp + mod32_width - 32));\n      __m128i right_lo128 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(dstp + mod32_width - 32 + sizeof(uint16_t)));\n      __m128i center_hi128 = _mm256_extractf128_si256(center, 1); // get high 128bit, really right! ptr+16\n      __m128i right_hi128 = _mm_or_si128(_mm_and_si128(center_hi128, right_mask_128), _mm_srli_si128(center_hi128, sizeof(uint16_t)));\n      right = _mm256_set_m128i(right_hi128, right_lo128);\n\n      result = af_unpack_blend_uint16_t_avx2(left, center, right, center_weight, outer_weight, round_mask, zero);\n\n      _mm256_store_si256(reinterpret_cast<__m256i*>(dstp + mod32_width - 32), result);\n    }\n    else { //some stuff left\n      uint16_t l = _mm256_cvtsi256_si32(left) & 0xFFFF;\n      af_horizontal_planar_process_line_uint16_c(l, dstp + mod32_width, row_size - mod32_width, center_weight_c, outer_weight_c, bits_per_pixel);\n    }\n\n    dstp += pitch;\n  }\n}\n"
  },
  {
    "path": "avs_core/filters/intel/focus_avx2.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Focus_AVX2_H__\n#define __Focus_AVX2_H__\n\n#include <avisynth.h>\n\nvoid af_horizontal_planar_uint16_t_avx2(BYTE* dstp, size_t height, size_t pitch, size_t row_size, size_t amount, int bits_per_pixel);\nvoid af_horizontal_planar_avx2(BYTE* dstp, size_t height, size_t pitch, size_t width, size_t amount);\nvoid af_vertical_avx2(BYTE* line_buf, BYTE* dstp, int height, int pitch, int width, int amount);\nvoid af_vertical_uint16_t_avx2(BYTE* line_buf, BYTE* dstp, int height, int pitch, int row_size, int amount);\n\n#endif  // __Focus_AVX2_H__\n"
  },
  {
    "path": "avs_core/filters/intel/focus_sse.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include <avisynth.h>\n#include \"../focus.h\"\n\n// Intrinsics base header + really required extension headers\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n#include <smmintrin.h> // SSE4.1\n\n#include \"../core/internal.h\"\n#include <stdint.h>\n\n/****************************************\n ***  AdjustFocus helper classes     ***\n ***  Originally by Ben R.G.         ***\n ***  MMX code by Marc FD            ***\n ***  Adaptation and bugfixes sh0dan ***\n ***  Code actually requires ISSE!   ***\n ***  Not anymore - pure MMX    IanB ***\n ***  Implement boundary proc.  IanB ***\n ***  Impl. full 8bit MMX proc. IanB ***\n ***************************************/\n\n // for linker reasons these forceinlined functions appear in C, intel sse2 and avx2 source as well\ntemplate<typename pixel_t>\nstatic AVS_FORCEINLINE void af_horizontal_planar_process_line_c(pixel_t left, BYTE* dstp8, size_t row_size, int center_weight, int outer_weight) {\n  size_t x;\n  pixel_t* dstp = reinterpret_cast<pixel_t*>(dstp8);\n  typedef typename std::conditional < sizeof(pixel_t) == 1, int, int64_t>::type weight_t; // for calling the right ScaledPixelClip()\n  size_t width = row_size / sizeof(pixel_t);\n  for (x = 0; x < width - 1; ++x) {\n    pixel_t temp = ScaledPixelClip((weight_t)(dstp[x] * (weight_t)center_weight + (left + dstp[x + 1]) * (weight_t)outer_weight));\n    left = dstp[x];\n    dstp[x] = temp;\n  }\n  // ScaledPixelClip has 2 overloads: BYTE/uint16_t (int/int64 i)\n  dstp[x] = ScaledPixelClip((weight_t)(dstp[x] * (weight_t)center_weight + (left + dstp[x]) * (weight_t)outer_weight));\n}\n\nstatic AVS_FORCEINLINE void af_horizontal_planar_process_line_uint16_c(uint16_t left, BYTE* dstp8, size_t row_size, int center_weight, int outer_weight, int bits_per_pixel) {\n  size_t x;\n  typedef uint16_t pixel_t;\n  pixel_t* dstp = reinterpret_cast<pixel_t*>(dstp8);\n  const int max_pixel_value = (1 << bits_per_pixel) - 1; // clamping on 10-12-14-16 bitdepth\n  typedef std::conditional < sizeof(pixel_t) == 1, int, int64_t>::type weight_t; // for calling the right ScaledPixelClip()\n  size_t width = row_size / sizeof(pixel_t);\n  for (x = 0; x < width - 1; ++x) {\n    pixel_t temp = (pixel_t)ScaledPixelClipEx((weight_t)(dstp[x] * (weight_t)center_weight + (left + dstp[x + 1]) * (weight_t)outer_weight), max_pixel_value);\n    left = dstp[x];\n    dstp[x] = temp;\n  }\n  // ScaledPixelClip has 2 overloads: BYTE/uint16_t (int/int64 i)\n  dstp[x] = ScaledPixelClipEx((weight_t)(dstp[x] * (weight_t)center_weight + (left + dstp[x]) * (weight_t)outer_weight), max_pixel_value);\n}\n\nstatic AVS_FORCEINLINE void af_horizontal_planar_process_line_float_c(float left, float* dstp, size_t row_size, float center_weight, float outer_weight) {\n  size_t x;\n  size_t width = row_size / sizeof(float);\n  for (x = 0; x < width - 1; ++x) {\n    float temp = dstp[x] * center_weight + (left + dstp[x + 1]) * outer_weight;\n    left = dstp[x];\n    dstp[x] = temp;\n  }\n  dstp[x] = dstp[x] * center_weight + (left + dstp[x]) * outer_weight;\n}\n\nvoid af_vertical_sse2_float(BYTE* line_buf, BYTE* dstp, const int height, const int pitch, const int row_size, const float amount) {\n\n  const float center_weight = amount;\n  const float outer_weight = (1.0f - amount) / 2.0f;\n\n  __m128 center_weight_simd = _mm_set1_ps(center_weight);\n  __m128 outer_weight_simd = _mm_set1_ps(outer_weight);\n\n  for (int y = 0; y < height - 1; ++y) {\n    for (int x = 0; x < row_size; x += 16) {\n      __m128 upper = _mm_load_ps(reinterpret_cast<const float*>(line_buf + x));\n      __m128 center = _mm_load_ps(reinterpret_cast<const float*>(dstp + x));\n      __m128 lower = _mm_load_ps(reinterpret_cast<const float*>(dstp + pitch + x));\n      _mm_store_ps(reinterpret_cast<float*>(line_buf + x), center);\n\n      __m128 tmp1 = _mm_mul_ps(center, center_weight_simd);\n      __m128 tmp2 = _mm_mul_ps(_mm_add_ps(upper, lower), outer_weight_simd);\n      __m128 result = _mm_add_ps(tmp1, tmp2);\n\n      _mm_store_ps(reinterpret_cast<float*>(dstp + x), result);\n    }\n    dstp += pitch;\n  }\n\n  //last line\n  for (int x = 0; x < row_size; x += 16) {\n    __m128 upper = _mm_load_ps(reinterpret_cast<const float*>(line_buf + x));\n    __m128 center = _mm_load_ps(reinterpret_cast<const float*>(dstp + x));\n\n    __m128 tmp1 = _mm_mul_ps(center, center_weight_simd);\n    __m128 tmp2 = _mm_mul_ps(_mm_add_ps(upper, center), outer_weight_simd); // last line: center instead of lower\n    __m128 result = _mm_add_ps(tmp1, tmp2);\n\n    _mm_store_ps(reinterpret_cast<float*>(dstp + x), result);\n  }\n}\n\n\nstatic AVS_FORCEINLINE __m128i af_blend_sse2(__m128i &upper, __m128i &center, __m128i &lower, __m128i &center_weight, __m128i &outer_weight, __m128i &round_mask) {\n  __m128i outer_tmp = _mm_add_epi16(upper, lower);\n  __m128i center_tmp = _mm_mullo_epi16(center, center_weight);\n\n  outer_tmp = _mm_mullo_epi16(outer_tmp, outer_weight);\n\n  __m128i result = _mm_adds_epi16(center_tmp, outer_tmp);\n  result = _mm_adds_epi16(result, center_tmp);\n  result = _mm_adds_epi16(result, round_mask);\n  return _mm_srai_epi16(result, 7);\n}\n\nstatic AVS_FORCEINLINE __m128i af_blend_uint16_t_sse2(__m128i &upper, __m128i &center, __m128i &lower, __m128i &center_weight, __m128i &outer_weight, __m128i &round_mask) {\n  __m128i outer_tmp = _mm_add_epi32(upper, lower);\n  __m128i center_tmp = _MM_MULLO_EPI32(center, center_weight); // sse2: mullo simulation\n  outer_tmp = _MM_MULLO_EPI32(outer_tmp, outer_weight);\n\n  __m128i result = _mm_add_epi32(center_tmp, outer_tmp);\n  result = _mm_add_epi32(result, center_tmp);\n  result = _mm_add_epi32(result, round_mask);\n  return _mm_srai_epi32(result, 7);\n}\n\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nstatic AVS_FORCEINLINE __m128i af_blend_uint16_t_sse41(__m128i &upper, __m128i &center, __m128i &lower, __m128i &center_weight, __m128i &outer_weight, __m128i &round_mask)\n{\n  __m128i outer_tmp = _mm_add_epi32(upper, lower);\n  __m128i center_tmp = _mm_mullo_epi32(center, center_weight);\n  outer_tmp = _mm_mullo_epi32(outer_tmp, outer_weight);\n\n  __m128i result = _mm_add_epi32(center_tmp, outer_tmp);\n  result = _mm_add_epi32(result, center_tmp);\n  result = _mm_add_epi32(result, round_mask);\n  return _mm_srai_epi32(result, 7);\n}\n\nstatic AVS_FORCEINLINE __m128 af_blend_float_sse2(__m128 &upper, __m128 &center, __m128 &lower, __m128 &center_weight, __m128 &outer_weight) {\n  __m128 tmp1 = _mm_mul_ps(center, center_weight);\n  __m128 tmp2 = _mm_mul_ps(_mm_add_ps(upper, lower), outer_weight);\n  return _mm_add_ps(tmp1, tmp2);\n}\n\n\nstatic AVS_FORCEINLINE __m128i af_unpack_blend_sse2(__m128i &left, __m128i &center, __m128i &right, __m128i &center_weight, __m128i &outer_weight, __m128i &round_mask, __m128i &zero) {\n  __m128i left_lo = _mm_unpacklo_epi8(left, zero);\n  __m128i left_hi = _mm_unpackhi_epi8(left, zero);\n  __m128i center_lo = _mm_unpacklo_epi8(center, zero);\n  __m128i center_hi = _mm_unpackhi_epi8(center, zero);\n  __m128i right_lo = _mm_unpacklo_epi8(right, zero);\n  __m128i right_hi = _mm_unpackhi_epi8(right, zero);\n\n  __m128i result_lo = af_blend_sse2(left_lo, center_lo, right_lo, center_weight, outer_weight, round_mask);\n  __m128i result_hi = af_blend_sse2(left_hi, center_hi, right_hi, center_weight, outer_weight, round_mask);\n\n  return _mm_packus_epi16(result_lo, result_hi);\n}\n\nstatic AVS_FORCEINLINE __m128i af_unpack_blend_uint16_t_sse2(__m128i &left, __m128i &center, __m128i &right, __m128i &center_weight, __m128i &outer_weight, __m128i &round_mask, __m128i &zero) {\n  __m128i left_lo = _mm_unpacklo_epi16(left, zero);\n  __m128i left_hi = _mm_unpackhi_epi16(left, zero);\n  __m128i center_lo = _mm_unpacklo_epi16(center, zero);\n  __m128i center_hi = _mm_unpackhi_epi16(center, zero);\n  __m128i right_lo = _mm_unpacklo_epi16(right, zero);\n  __m128i right_hi = _mm_unpackhi_epi16(right, zero);\n\n  __m128i result_lo = af_blend_uint16_t_sse2(left_lo, center_lo, right_lo, center_weight, outer_weight, round_mask);\n  __m128i result_hi = af_blend_uint16_t_sse2(left_hi, center_hi, right_hi, center_weight, outer_weight, round_mask);\n  return _MM_PACKUS_EPI32(result_lo, result_hi); // sse4.1 simul\n}\n\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nstatic AVS_FORCEINLINE __m128i af_unpack_blend_uint16_t_sse41(__m128i &left, __m128i &center, __m128i &right, __m128i &center_weight, __m128i &outer_weight, __m128i &round_mask, __m128i &zero)\n{\n  __m128i left_lo = _mm_unpacklo_epi16(left, zero);\n  __m128i left_hi = _mm_unpackhi_epi16(left, zero);\n  __m128i center_lo = _mm_unpacklo_epi16(center, zero);\n  __m128i center_hi = _mm_unpackhi_epi16(center, zero);\n  __m128i right_lo = _mm_unpacklo_epi16(right, zero);\n  __m128i right_hi = _mm_unpackhi_epi16(right, zero);\n\n  __m128i result_lo = af_blend_uint16_t_sse41(left_lo, center_lo, right_lo, center_weight, outer_weight, round_mask);\n  __m128i result_hi = af_blend_uint16_t_sse41(left_hi, center_hi, right_hi, center_weight, outer_weight, round_mask);\n  return _mm_packus_epi32(result_lo, result_hi);\n}\n\n\nvoid af_vertical_uint16_t_sse2(BYTE* line_buf, BYTE* dstp, int height, int pitch, int row_size, int amount) {\n  // amount was: half_amount (32768). Full: 65536 (2**16)\n  // now it becomes 2**(16-9)=2**7 scale\n  int t = (amount + 256) >> 9; // 16-9 = 7 -> shift in\n  __m128i center_weight = _mm_set1_epi32(t);\n  __m128i outer_weight = _mm_set1_epi32(64 - t);\n  __m128i round_mask = _mm_set1_epi32(0x40);\n  __m128i zero = _mm_setzero_si128();\n\n  for (int y = 0; y < height - 1; ++y) {\n    for (int x = 0; x < row_size; x += 16) {\n      __m128i upper = _mm_load_si128(reinterpret_cast<const __m128i*>(line_buf + x));\n      __m128i center = _mm_load_si128(reinterpret_cast<const __m128i*>(dstp + x));\n      __m128i lower = _mm_load_si128(reinterpret_cast<const __m128i*>(dstp + pitch + x));\n      _mm_store_si128(reinterpret_cast<__m128i*>(line_buf + x), center);\n\n      __m128i upper_lo = _mm_unpacklo_epi16(upper, zero);\n      __m128i upper_hi = _mm_unpackhi_epi16(upper, zero);\n      __m128i center_lo = _mm_unpacklo_epi16(center, zero);\n      __m128i center_hi = _mm_unpackhi_epi16(center, zero);\n      __m128i lower_lo = _mm_unpacklo_epi16(lower, zero);\n      __m128i lower_hi = _mm_unpackhi_epi16(lower, zero);\n\n      __m128i result_lo = af_blend_uint16_t_sse2(upper_lo, center_lo, lower_lo, center_weight, outer_weight, round_mask);\n      __m128i result_hi = af_blend_uint16_t_sse2(upper_hi, center_hi, lower_hi, center_weight, outer_weight, round_mask);\n\n      __m128i result = _MM_PACKUS_EPI32(result_lo, result_hi); // sse4.1 simul\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x), result);\n    }\n    dstp += pitch;\n  }\n\n  //last line\n  for (int x = 0; x < row_size; x += 16) {\n    __m128i upper = _mm_load_si128(reinterpret_cast<const __m128i*>(line_buf + x));\n    __m128i center = _mm_load_si128(reinterpret_cast<const __m128i*>(dstp + x));\n\n    __m128i upper_lo = _mm_unpacklo_epi16(upper, zero);\n    __m128i upper_hi = _mm_unpackhi_epi16(upper, zero);\n    __m128i center_lo = _mm_unpacklo_epi16(center, zero);\n    __m128i center_hi = _mm_unpackhi_epi16(center, zero);\n\n    __m128i result_lo = af_blend_uint16_t_sse2(upper_lo, center_lo, center_lo, center_weight, outer_weight, round_mask);\n    __m128i result_hi = af_blend_uint16_t_sse2(upper_hi, center_hi, center_hi, center_weight, outer_weight, round_mask);\n\n    __m128i result = _MM_PACKUS_EPI32(result_lo, result_hi); // sse4.1 simul\n\n    _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x), result);\n  }\n}\n\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid af_vertical_uint16_t_sse41(BYTE* line_buf, BYTE* dstp, int height, int pitch, int row_size, int amount)\n{\n  // amount was: half_amount (32768). Full: 65536 (2**16)\n  // now it becomes 2**(16-9)=2**7 scale\n  int t = (amount + 256) >> 9; // 16-9 = 7 -> shift in\n  __m128i center_weight = _mm_set1_epi32(t);\n  __m128i outer_weight = _mm_set1_epi32(64 - t);\n  __m128i round_mask = _mm_set1_epi32(0x40);\n  __m128i zero = _mm_setzero_si128();\n\n  for (int y = 0; y < height - 1; ++y) {\n    for (int x = 0; x < row_size; x += 16) {\n      __m128i upper = _mm_load_si128(reinterpret_cast<const __m128i*>(line_buf + x));\n      __m128i center = _mm_load_si128(reinterpret_cast<const __m128i*>(dstp + x));\n      __m128i lower = _mm_load_si128(reinterpret_cast<const __m128i*>(dstp + pitch + x));\n      _mm_store_si128(reinterpret_cast<__m128i*>(line_buf + x), center);\n\n      __m128i upper_lo = _mm_unpacklo_epi16(upper, zero);\n      __m128i upper_hi = _mm_unpackhi_epi16(upper, zero);\n      __m128i center_lo = _mm_unpacklo_epi16(center, zero);\n      __m128i center_hi = _mm_unpackhi_epi16(center, zero);\n      __m128i lower_lo = _mm_unpacklo_epi16(lower, zero);\n      __m128i lower_hi = _mm_unpackhi_epi16(lower, zero);\n\n      __m128i result_lo = af_blend_uint16_t_sse41(upper_lo, center_lo, lower_lo, center_weight, outer_weight, round_mask);\n      __m128i result_hi = af_blend_uint16_t_sse41(upper_hi, center_hi, lower_hi, center_weight, outer_weight, round_mask);\n\n      __m128i result = _mm_packus_epi32(result_lo, result_hi);\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x), result);\n    }\n    dstp += pitch;\n  }\n\n  //last line\n  for (int x = 0; x < row_size; x += 16) {\n    __m128i upper = _mm_load_si128(reinterpret_cast<const __m128i*>(line_buf + x));\n    __m128i center = _mm_load_si128(reinterpret_cast<const __m128i*>(dstp + x));\n\n    __m128i upper_lo = _mm_unpacklo_epi16(upper, zero);\n    __m128i upper_hi = _mm_unpackhi_epi16(upper, zero);\n    __m128i center_lo = _mm_unpacklo_epi16(center, zero);\n    __m128i center_hi = _mm_unpackhi_epi16(center, zero);\n\n    __m128i result_lo = af_blend_uint16_t_sse41(upper_lo, center_lo, center_lo, center_weight, outer_weight, round_mask);\n    __m128i result_hi = af_blend_uint16_t_sse41(upper_hi, center_hi, center_hi, center_weight, outer_weight, round_mask);\n\n    __m128i result = _mm_packus_epi32(result_lo, result_hi);\n\n    _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x), result);\n  }\n}\n\nvoid af_vertical_sse2(BYTE* line_buf, BYTE* dstp, int height, int pitch, int width, int amount) {\n  short t = (amount + 256) >> 9;\n  __m128i center_weight = _mm_set1_epi16(t);\n  __m128i outer_weight = _mm_set1_epi16(64 - t);\n  __m128i round_mask = _mm_set1_epi16(0x40);\n  __m128i zero = _mm_setzero_si128();\n\n  for (int y = 0; y < height-1; ++y) {\n    for (int x = 0; x < width; x+= 16) {\n      __m128i upper = _mm_load_si128(reinterpret_cast<const __m128i*>(line_buf+x));\n      __m128i center = _mm_load_si128(reinterpret_cast<const __m128i*>(dstp+x));\n      __m128i lower = _mm_load_si128(reinterpret_cast<const __m128i*>(dstp+pitch+x));\n      _mm_store_si128(reinterpret_cast<__m128i*>(line_buf+x), center);\n\n      __m128i upper_lo = _mm_unpacklo_epi8(upper, zero);\n      __m128i upper_hi = _mm_unpackhi_epi8(upper, zero);\n      __m128i center_lo = _mm_unpacklo_epi8(center, zero);\n      __m128i center_hi = _mm_unpackhi_epi8(center, zero);\n      __m128i lower_lo = _mm_unpacklo_epi8(lower, zero);\n      __m128i lower_hi = _mm_unpackhi_epi8(lower, zero);\n\n      __m128i result_lo = af_blend_sse2(upper_lo, center_lo, lower_lo, center_weight, outer_weight, round_mask);\n      __m128i result_hi = af_blend_sse2(upper_hi, center_hi, lower_hi, center_weight, outer_weight, round_mask);\n\n      __m128i result = _mm_packus_epi16(result_lo, result_hi);\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp+x), result);\n    }\n    dstp += pitch;\n  }\n\n  //last line\n  for (int x = 0; x < width; x+= 16) {\n    __m128i upper = _mm_load_si128(reinterpret_cast<const __m128i*>(line_buf+x));\n    __m128i center = _mm_load_si128(reinterpret_cast<const __m128i*>(dstp+x));\n\n    __m128i upper_lo = _mm_unpacklo_epi8(upper, zero);\n    __m128i upper_hi = _mm_unpackhi_epi8(upper, zero);\n    __m128i center_lo = _mm_unpacklo_epi8(center, zero);\n    __m128i center_hi = _mm_unpackhi_epi8(center, zero);\n\n    __m128i result_lo = af_blend_sse2(upper_lo, center_lo, center_lo, center_weight, outer_weight, round_mask);\n    __m128i result_hi = af_blend_sse2(upper_hi, center_hi, center_hi, center_weight, outer_weight, round_mask);\n\n    __m128i result = _mm_packus_epi16(result_lo, result_hi);\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp+x), result);\n  }\n}\n\n#ifdef X86_32\n\nstatic AVS_FORCEINLINE __m64 af_blend_mmx(__m64 &upper, __m64 &center, __m64 &lower, __m64 &center_weight, __m64 &outer_weight, __m64 &round_mask) {\n  __m64 outer_tmp = _mm_add_pi16(upper, lower);\n  __m64 center_tmp = _mm_mullo_pi16(center, center_weight);\n\n  outer_tmp = _mm_mullo_pi16(outer_tmp, outer_weight);\n\n  __m64 result = _mm_adds_pi16(center_tmp, outer_tmp);\n  result = _mm_adds_pi16(result, center_tmp);\n  result = _mm_adds_pi16(result, round_mask);\n  return _mm_srai_pi16(result, 7);\n}\n\nstatic AVS_FORCEINLINE __m64 af_unpack_blend_mmx(__m64 &left, __m64 &center, __m64 &right, __m64 &center_weight, __m64 &outer_weight, __m64 &round_mask, __m64 &zero) {\n  __m64 left_lo = _mm_unpacklo_pi8(left, zero);\n  __m64 left_hi = _mm_unpackhi_pi8(left, zero);\n  __m64 center_lo = _mm_unpacklo_pi8(center, zero);\n  __m64 center_hi = _mm_unpackhi_pi8(center, zero);\n  __m64 right_lo = _mm_unpacklo_pi8(right, zero);\n  __m64 right_hi = _mm_unpackhi_pi8(right, zero);\n\n  __m64 result_lo = af_blend_mmx(left_lo, center_lo, right_lo, center_weight, outer_weight, round_mask);\n  __m64 result_hi = af_blend_mmx(left_hi, center_hi, right_hi, center_weight, outer_weight, round_mask);\n\n  return _mm_packs_pu16(result_lo, result_hi);\n}\n\nvoid af_vertical_mmx(BYTE* line_buf, BYTE* dstp, int height, int pitch, int width, int amount) {\n  short t = (amount + 256) >> 9;\n  __m64 center_weight = _mm_set1_pi16(t);\n  __m64 outer_weight = _mm_set1_pi16(64 - t);\n  __m64 round_mask = _mm_set1_pi16(0x40);\n  __m64 zero = _mm_setzero_si64();\n\n  for (int y = 0; y < height-1; ++y) {\n    for (int x = 0; x < width; x+= 8) {\n      __m64 upper = *reinterpret_cast<const __m64*>(line_buf+x);\n      __m64 center = *reinterpret_cast<const __m64*>(dstp+x);\n      __m64 lower = *reinterpret_cast<const __m64*>(dstp+pitch+x);\n      *reinterpret_cast<__m64*>(line_buf+x) = center;\n\n      __m64 result = af_unpack_blend_mmx(upper, center, lower, center_weight, outer_weight, round_mask, zero);\n\n      *reinterpret_cast<__m64*>(dstp+x) = result;\n    }\n    dstp += pitch;\n  }\n\n  //last line\n  for (int x = 0; x < width; x+= 8) {\n    __m64 upper = *reinterpret_cast<const __m64*>(line_buf+x);\n    __m64 center = *reinterpret_cast<const __m64*>(dstp+x);\n\n    __m64 upper_lo = _mm_unpacklo_pi8(upper, zero);\n    __m64 upper_hi = _mm_unpackhi_pi8(upper, zero);\n    __m64 center_lo = _mm_unpacklo_pi8(center, zero);\n    __m64 center_hi = _mm_unpackhi_pi8(center, zero);\n\n    __m64 result_lo = af_blend_mmx(upper_lo, center_lo, center_lo, center_weight, outer_weight, round_mask);\n    __m64 result_hi = af_blend_mmx(upper_hi, center_hi, center_hi, center_weight, outer_weight, round_mask);\n\n    __m64 result = _mm_packs_pu16(result_lo, result_hi);\n\n    *reinterpret_cast<__m64*>(dstp+x) = result;\n  }\n  _mm_empty();\n}\n\n#endif\n\n\n// --------------------------------------\n\n\n//implementation is not in-place. Unaligned reads will be slow on older intels but who cares\nvoid af_horizontal_rgb32_sse2(BYTE* dstp, const BYTE* srcp, size_t dst_pitch, size_t src_pitch, size_t height, size_t width, size_t amount) {\n  size_t width_bytes = width * 4;\n  size_t loop_limit = width_bytes - 16;\n  //int center_weight_c = int(amount*2);\n  //int outer_weight_c = int(32768-amount);\n\n  short t = short((amount + 256) >> 9);\n  __m128i center_weight = _mm_set1_epi16(t);\n  __m128i outer_weight = _mm_set1_epi16(64 - t);\n  __m128i round_mask = _mm_set1_epi16(0x40);\n  __m128i zero = _mm_setzero_si128();\n  __m128i left_mask = _mm_set_epi32(0, 0, 0, 0xFFFFFFFF);\n  __m128i right_mask = _mm_set_epi32(0xFFFFFFFF, 0, 0, 0);\n\n  __m128i center, right, left, result;\n\n  for (size_t y = 0; y < height; ++y) {\n    center = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp));\n    right = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + 4));\n    left = _mm_or_si128(_mm_and_si128(center, left_mask), _mm_slli_si128(center, 4));\n\n    result = af_unpack_blend_sse2(left, center, right, center_weight, outer_weight, round_mask, zero);\n\n    _mm_store_si128(reinterpret_cast< __m128i*>(dstp), result);\n\n    for (size_t x = 16; x < loop_limit; x+=16) {\n      left = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + x - 4));\n      center = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x));\n      right = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + x + 4));\n\n      result = af_unpack_blend_sse2(left, center, right, center_weight, outer_weight, round_mask, zero);\n\n      _mm_store_si128(reinterpret_cast< __m128i*>(dstp+x), result);\n    }\n\n    left = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + loop_limit - 4));\n    center = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + loop_limit));\n    right = _mm_or_si128(_mm_and_si128(center, right_mask), _mm_srli_si128(center, 4));\n\n    result = af_unpack_blend_sse2(left, center, right, center_weight, outer_weight, round_mask, zero);\n\n    _mm_storeu_si128(reinterpret_cast< __m128i*>(dstp + loop_limit), result);\n\n\n    dstp += dst_pitch;\n    srcp += src_pitch;\n  }\n}\n\nvoid af_horizontal_rgb64_sse2(BYTE* dstp, const BYTE* srcp, size_t dst_pitch, size_t src_pitch, size_t height, size_t width, size_t amount) {\n  // width is really width\n  size_t width_bytes = width * 4 * sizeof(uint16_t);\n  size_t loop_limit = width_bytes - 16;\n\n  short t = short((amount + 256) >> 9);\n  __m128i center_weight = _mm_set1_epi32(t);\n  __m128i outer_weight = _mm_set1_epi32(64 - t);\n  __m128i round_mask = _mm_set1_epi32(0x40);\n  __m128i zero = _mm_setzero_si128();\n  __m128i left_mask = _mm_set_epi32(0, 0, 0xFFFFFFFF, 0xFFFFFFFF);\n  __m128i right_mask = _mm_set_epi32(0xFFFFFFFF, 0xFFFFFFFF, 0, 0);\n\n  __m128i center, right, left, result;\n\n  for (size_t y = 0; y < height; ++y) {\n    center = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp));\n    right = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + 4*sizeof(uint16_t))); // move right by one 4*uint16_t pixelblock\n    left = _mm_or_si128(_mm_and_si128(center, left_mask), _mm_slli_si128(center, 8));\n\n    result = af_unpack_blend_uint16_t_sse2(left, center, right, center_weight, outer_weight, round_mask, zero);\n\n    _mm_store_si128(reinterpret_cast< __m128i*>(dstp), result);\n\n    for (size_t x = 16; x < loop_limit; x += 16) {\n      left = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + x - 4 * sizeof(uint16_t)));\n      center = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x));\n      right = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + x + 4 * sizeof(uint16_t)));\n\n      result = af_unpack_blend_uint16_t_sse2(left, center, right, center_weight, outer_weight, round_mask, zero);\n\n      _mm_store_si128(reinterpret_cast< __m128i*>(dstp + x), result);\n    }\n\n    left = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + loop_limit - 4 * sizeof(uint16_t)));\n    center = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + loop_limit));\n    right = _mm_or_si128(_mm_and_si128(center, right_mask), _mm_srli_si128(center, 4 * sizeof(uint16_t)));\n\n    result = af_unpack_blend_uint16_t_sse2(left, center, right, center_weight, outer_weight, round_mask, zero);\n\n    _mm_storeu_si128(reinterpret_cast< __m128i*>(dstp + loop_limit), result);\n\n\n    dstp += dst_pitch;\n    srcp += src_pitch;\n  }\n}\n\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid af_horizontal_rgb64_sse41(BYTE* dstp, const BYTE* srcp, size_t dst_pitch, size_t src_pitch, size_t height, size_t width, size_t amount)\n{\n  // width is really width\n  size_t width_bytes = width * 4 * sizeof(uint16_t);\n  size_t loop_limit = width_bytes - 16;\n\n  short t = short((amount + 256) >> 9);\n  __m128i center_weight = _mm_set1_epi32(t);\n  __m128i outer_weight = _mm_set1_epi32(64 - t);\n  __m128i round_mask = _mm_set1_epi32(0x40);\n  __m128i zero = _mm_setzero_si128();\n  __m128i left_mask = _mm_set_epi32(0, 0, 0xFFFFFFFF, 0xFFFFFFFF);\n  __m128i right_mask = _mm_set_epi32(0xFFFFFFFF, 0xFFFFFFFF, 0, 0);\n\n  __m128i center, right, left, result;\n\n  for (size_t y = 0; y < height; ++y) {\n    center = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp));\n    right = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + 4 * sizeof(uint16_t))); // move right by one 4*uint16_t pixelblock\n    left = _mm_or_si128(_mm_and_si128(center, left_mask), _mm_slli_si128(center, 8));\n\n    result = af_unpack_blend_uint16_t_sse41(left, center, right, center_weight, outer_weight, round_mask, zero);\n\n    _mm_store_si128(reinterpret_cast<__m128i*>(dstp), result);\n\n    for (size_t x = 16; x < loop_limit; x += 16) {\n      left = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + x - 4 * sizeof(uint16_t)));\n      center = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x));\n      right = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + x + 4 * sizeof(uint16_t)));\n\n      result = af_unpack_blend_uint16_t_sse41(left, center, right, center_weight, outer_weight, round_mask, zero);\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x), result);\n    }\n\n    left = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + loop_limit - 4 * sizeof(uint16_t)));\n    center = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + loop_limit));\n    right = _mm_or_si128(_mm_and_si128(center, right_mask), _mm_srli_si128(center, 4 * sizeof(uint16_t)));\n\n    result = af_unpack_blend_uint16_t_sse41(left, center, right, center_weight, outer_weight, round_mask, zero);\n\n    _mm_storeu_si128(reinterpret_cast<__m128i*>(dstp + loop_limit), result);\n\n\n    dstp += dst_pitch;\n    srcp += src_pitch;\n  }\n}\n\n#ifdef X86_32\n\nvoid af_horizontal_rgb32_mmx(BYTE* dstp, const BYTE* srcp, size_t dst_pitch, size_t src_pitch, size_t height, size_t width, size_t amount) {\n  size_t width_bytes = width * 4;\n  size_t loop_limit = width_bytes - 8;\n  int center_weight_c = amount*2;\n  int outer_weight_c = 32768-amount;\n\n  short t = short((amount + 256) >> 9);\n  __m64 center_weight = _mm_set1_pi16(t);\n  __m64 outer_weight = _mm_set1_pi16(64 - t);\n  __m64 round_mask = _mm_set1_pi16(0x40);\n  __m64 zero = _mm_setzero_si64();\n  __m64 left_mask = _mm_set_pi32(0, 0xFFFFFFFF);\n  __m64 right_mask = _mm_set_pi32(0xFFFFFFFF, 0);\n\n  __m64 center, right, left, result;\n\n  for (size_t y = 0; y < height; ++y) {\n    center = *reinterpret_cast<const __m64*>(srcp);\n    right = *reinterpret_cast<const __m64*>(srcp + 4);\n    left = _mm_or_si64(_mm_and_si64(center, left_mask), _mm_slli_si64(center, 32));\n\n    result = af_unpack_blend_mmx(left, center, right, center_weight, outer_weight, round_mask, zero);\n\n    *reinterpret_cast< __m64*>(dstp) = result;\n\n    for (size_t x = 8; x < loop_limit; x+=8) {\n      left = *reinterpret_cast<const __m64*>(srcp + x - 4);\n      center = *reinterpret_cast<const __m64*>(srcp + x);\n      right = *reinterpret_cast<const __m64*>(srcp + x + 4);\n\n      result = af_unpack_blend_mmx(left, center, right, center_weight, outer_weight, round_mask, zero);\n\n      *reinterpret_cast< __m64*>(dstp+x) = result;\n    }\n\n    left = *reinterpret_cast<const __m64*>(srcp + loop_limit - 4);\n    center = *reinterpret_cast<const __m64*>(srcp + loop_limit);\n    right = _mm_or_si64(_mm_and_si64(center, right_mask), _mm_srli_si64(center, 32));\n\n    result = af_unpack_blend_mmx(left, center, right, center_weight, outer_weight, round_mask, zero);\n\n    *reinterpret_cast< __m64*>(dstp + loop_limit) = result;\n\n    dstp += dst_pitch;\n    srcp += src_pitch;\n  }\n  _mm_empty();\n}\n\n#endif\n\n\n\nstatic AVS_FORCEINLINE __m128i af_blend_yuy2_sse2(__m128i &left, __m128i &center, __m128i &right, __m128i &luma_mask,\n                                             __m128i &center_weight, __m128i &outer_weight, __m128i &round_mask) {\n  __m128i left_luma = _mm_and_si128(left, luma_mask); //0 Y5 0 Y4 0 Y3 0 Y2 0 Y1 0 Y0 0 Y-1 0 Y-2\n  __m128i center_luma = _mm_and_si128(center, luma_mask); //0 Y7 0 Y6 0 Y5 0 Y4 0 Y3 0 Y2 0 Y1 0 Y0\n  __m128i right_luma = _mm_and_si128(right, luma_mask); //0 Y9 0 Y8 0 Y7 0 Y6 0 Y5 0 Y4 0 Y3 0 Y2\n\n  left_luma = _mm_or_si128(\n    _mm_srli_si128(left_luma, 2), // 0  0 0 Y5 0 Y4 0 Y3 0 Y2 0 Y1 0 Y0 0 Y-1\n    _mm_slli_si128(right_luma, 6) // 0 Y6 0 Y5 0 Y4 0 Y3 0 Y2 0  0 0  0 0  0\n    ); // Y6..Y0 (Y-1)\n\n  right_luma = _mm_or_si128(\n    _mm_srli_si128(center_luma, 2),//0 0  0 Y7 0 Y6 0 Y5 0 Y4 0 Y3 0 Y2 0 Y1\n    _mm_slli_si128(right_luma, 2)  //0 Y8 0 Y7 0 Y6 0 Y5 0 Y4 0 Y3 0 Y2 0 0\n    ); // Y8..Y1\n\n  __m128i result_luma = af_blend_sse2(left_luma, center_luma, right_luma, center_weight, outer_weight, round_mask);\n\n  __m128i left_chroma = _mm_srli_epi16(left, 8); //0 V 0 U 0 V 0 U\n  __m128i center_chroma = _mm_srli_epi16(center, 8); //0 V 0 U 0 V 0 U\n  __m128i right_chroma = _mm_srli_epi16(right, 8); //0 V 0 U 0 V 0 U\n\n  __m128i result_chroma = af_blend_sse2(left_chroma, center_chroma, right_chroma, center_weight, outer_weight, round_mask);\n\n  __m128i lo_lu_hi_co = _mm_packus_epi16(result_luma, result_chroma); // U3 V3 U2 V2 U1 V1 U0 V0 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0\n  __m128i result = _mm_unpacklo_epi8(lo_lu_hi_co, _mm_srli_si128(lo_lu_hi_co, 8)); // U3 Y7 V3 Y6 U2 Y5 V2 Y4 U1 Y3 V1 Y2 U0 Y1 V0 Y0\n  return result;\n}\n\n\nvoid af_horizontal_yuy2_sse2(BYTE* dstp, const BYTE* srcp, size_t dst_pitch, size_t src_pitch, size_t height, size_t width, size_t amount) {\n  size_t width_bytes = width * 2;\n  size_t loop_limit = width_bytes - 16;\n\n  short t = short((amount + 256) >> 9);\n  __m128i center_weight = _mm_set1_epi16(t);\n  __m128i outer_weight = _mm_set1_epi16(64 - t);\n  __m128i round_mask = _mm_set1_epi16(0x40);\n  __m128i left_mask = _mm_set_epi32(0, 0, 0, 0xFFFFFFFF);\n  __m128i right_mask = _mm_set_epi32(0xFFFFFFFF, 0, 0, 0);\n  __m128i left_mask_small = _mm_set_epi16(0, 0, 0, 0, 0, 0, 0x00FF, 0);\n  __m128i right_mask_small = _mm_set_epi16(0, 0x00FF, 0, 0, 0, 0, 0, 0);\n  __m128i luma_mask = _mm_set1_epi16(0xFF);\n\n  __m128i center, right, left, result;\n\n  for (size_t y = 0; y < height; ++y) {\n    center = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp));//V1 Y3 U1 Y2 V0 Y1 U0 Y0\n    right = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + 4));//V2 Y5 U2 Y4 V1 Y3 U1 Y2\n\n    //todo: now this is dumb\n    left = _mm_or_si128(\n      _mm_and_si128(center, left_mask),\n      _mm_slli_si128(center, 4)\n      );//V0 Y1 U0 Y0 V0 Y1 U0 Y0\n    left = _mm_or_si128(\n      _mm_andnot_si128(left_mask_small, left),\n      _mm_and_si128(_mm_slli_si128(center, 2), left_mask_small)\n      );//V0 Y1 U0 Y0 V0 Y0 U0 Y0\n\n    result = af_blend_yuy2_sse2(left, center, right, luma_mask, center_weight, outer_weight, round_mask);\n\n    _mm_store_si128(reinterpret_cast< __m128i*>(dstp), result);\n\n    for (size_t x = 16; x < loop_limit; x+=16) {\n      left = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + x - 4));//V0 Y1 U0 Y0 V-1 Y-1 U-1 Y-2\n      center = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x)); //V1 Y3 U1 Y2 V0 Y1 U0 Y0\n      right = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + x + 4));//V2 Y5 U2 Y4 V1 Y3 U1 Y2\n\n      result = af_blend_yuy2_sse2(left, center, right, luma_mask, center_weight, outer_weight, round_mask);\n\n      _mm_store_si128(reinterpret_cast< __m128i*>(dstp+x), result);\n    }\n\n    left = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + loop_limit - 4));\n    center = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + loop_limit));  //V1 Y3 U1 Y2 V0 Y1 U0 Y0\n\n    //todo: now this is dumb2\n    right = _mm_or_si128(\n      _mm_and_si128(center, right_mask),\n      _mm_srli_si128(center, 4)\n      );//V1 Y3 U1 Y2 V1 Y3 U1 Y2\n\n    right = _mm_or_si128(\n      _mm_andnot_si128(right_mask_small, right),\n      _mm_and_si128(_mm_srli_si128(center, 2), right_mask_small)\n      );//V1 Y3 U1 Y3 V1 Y3 U1 Y2\n\n    result = af_blend_yuy2_sse2(left, center, right, luma_mask, center_weight, outer_weight, round_mask);\n\n    _mm_storeu_si128(reinterpret_cast< __m128i*>(dstp + loop_limit), result);\n\n    dstp += dst_pitch;\n    srcp += src_pitch;\n  }\n}\n\n\n\n#ifdef X86_32\n// -------------------------------------\n// Blur/Sharpen Horizontal YUY2 MMX Code\n// -------------------------------------\n//\nstatic AVS_FORCEINLINE __m64 af_blend_yuy2_mmx(__m64 &left, __m64 &center, __m64 &right, __m64 &luma_mask,\n                           __m64 &center_weight, __m64 &outer_weight, __m64 &round_mask) {\n  __m64 left_luma = _mm_and_si64(left, luma_mask); //0 Y1 0 Y0 0 Y-1 0 Y-2\n  __m64 center_luma = _mm_and_si64(center, luma_mask); //0 Y3 0 Y2 0 Y1 0 Y0\n  __m64 right_luma = _mm_and_si64(right, luma_mask); //0 Y5 0 Y4 0 Y3 0 Y2\n\n  left_luma = _mm_or_si64(\n    _mm_srli_si64(left_luma, 16), // 0 0 0 Y1 0 Y0 0 Y-1\n    _mm_slli_si64(right_luma, 48) // 0 Y2 0 0 0 0 0 0\n    );\n\n  right_luma = _mm_or_si64(\n    _mm_srli_si64(center_luma, 16),//0 0 0 Y3 0 Y2 0 Y1\n    _mm_slli_si64(right_luma, 16)//0 Y4 0 Y3 0 Y2 0 0\n    );\n\n  __m64 result_luma = af_blend_mmx(left_luma, center_luma, right_luma, center_weight, outer_weight, round_mask);\n\n  __m64 left_chroma = _mm_srli_pi16(left, 8); //0 V 0 U 0 V 0 U\n  __m64 center_chroma = _mm_srli_pi16(center, 8); //0 V 0 U 0 V 0 U\n  __m64 right_chroma = _mm_srli_pi16(right, 8); //0 V 0 U 0 V 0 U\n\n  __m64 result_chroma = af_blend_mmx(left_chroma, center_chroma, right_chroma, center_weight, outer_weight, round_mask);\n\n  __m64 lo_lu_hi_co = _m_packuswb(result_luma, result_chroma); // U1 V1 U0 V0 Y3 Y2 Y1 Y0\n  __m64 result = _mm_unpacklo_pi8(lo_lu_hi_co, _mm_srli_si64(lo_lu_hi_co, 32)); // U1 Y3 V1 Y2 U0 Y1 V0 Y0\n  return result;\n}\n\n\nvoid af_horizontal_yuy2_mmx(BYTE* dstp, const BYTE* srcp, size_t dst_pitch, size_t src_pitch, size_t height, size_t width, size_t amount) {\n  size_t width_bytes = width * 2;\n  size_t loop_limit = width_bytes - 8;\n\n  short t = short((amount + 256) >> 9);\n  __m64 center_weight = _mm_set1_pi16(t);\n  __m64 outer_weight = _mm_set1_pi16(64 - t);\n  __m64 round_mask = _mm_set1_pi16(0x40);\n  __m64 left_mask = _mm_set_pi32(0, 0xFFFFFFFF);\n  __m64 right_mask = _mm_set_pi32(0xFFFFFFFF, 0);\n  __m64 left_mask_small = _mm_set_pi16(0, 0, 0x00FF, 0);\n  __m64 right_mask_small = _mm_set_pi16(0, 0x00FF, 0, 0);\n  __m64 luma_mask = _mm_set1_pi16(0xFF);\n\n  __m64 center, right, left, result;\n\n  for (size_t y = 0; y < height; ++y) {\n    center = *reinterpret_cast<const __m64*>(srcp);//V1 Y3 U1 Y2 V0 Y1 U0 Y0\n    right = *reinterpret_cast<const __m64*>(srcp + 4);//V2 Y5 U2 Y4 V1 Y3 U1 Y2\n\n    //todo: now this is dumb\n    left = _mm_or_si64(\n      _mm_and_si64(center, left_mask),\n      _mm_slli_si64(center, 32)\n      );//V0 Y1 U0 Y0 V0 Y1 U0 Y0\n    left = _mm_or_si64(\n      _mm_andnot_si64(left_mask_small, left),\n      _mm_and_si64(_mm_slli_si64(center, 16), left_mask_small)\n      );//V0 Y1 U0 Y0 V0 Y0 U0 Y0\n\n    result = af_blend_yuy2_mmx(left, center, right, luma_mask, center_weight, outer_weight, round_mask);\n\n    *reinterpret_cast< __m64*>(dstp) = result;\n\n    for (size_t x = 8; x < loop_limit; x+=8) {\n      left = *reinterpret_cast<const __m64*>(srcp + x - 4);//V0 Y1 U0 Y0 V-1 Y-1 U-1 Y-2\n      center = *reinterpret_cast<const __m64*>(srcp + x); //V1 Y3 U1 Y2 V0 Y1 U0 Y0\n      right = *reinterpret_cast<const __m64*>(srcp + x + 4);//V2 Y5 U2 Y4 V1 Y3 U1 Y2\n\n      __m64 result = af_blend_yuy2_mmx(left, center, right, luma_mask, center_weight, outer_weight, round_mask);\n\n      *reinterpret_cast< __m64*>(dstp+x) = result;\n    }\n\n    left = *reinterpret_cast<const __m64*>(srcp + loop_limit - 4);\n    center = *reinterpret_cast<const __m64*>(srcp + loop_limit);  //V1 Y3 U1 Y2 V0 Y1 U0 Y0\n\n    //todo: now this is dumb2\n    right = _mm_or_si64(\n      _mm_and_si64(center, right_mask),\n      _mm_srli_si64(center, 32)\n      );//V1 Y3 U1 Y2 V1 Y3 U1 Y2\n    right = _mm_or_si64(\n      _mm_andnot_si64(right_mask_small, right),\n      _mm_and_si64(_mm_srli_si64(center, 16), right_mask_small)\n      );//V1 Y3 U1 Y3 V1 Y3 U1 Y2\n\n    result = af_blend_yuy2_mmx(left, center, right, luma_mask, center_weight, outer_weight, round_mask);\n\n    *reinterpret_cast< __m64*>(dstp + loop_limit) = result;\n\n    dstp += dst_pitch;\n    srcp += src_pitch;\n  }\n  _mm_empty();\n}\n\n\n#endif\n\n\nvoid af_horizontal_planar_sse2(BYTE* dstp, size_t height, size_t pitch, size_t width, size_t amount) {\n  size_t mod16_width = (width / 16) * 16;\n  size_t sse_loop_limit = width == mod16_width ? mod16_width - 16 : mod16_width;\n  int center_weight_c = int(amount*2);\n  int outer_weight_c = int(32768-amount);\n\n  short t = short((amount + 256) >> 9);\n  __m128i center_weight = _mm_set1_epi16(t);\n  __m128i outer_weight = _mm_set1_epi16(64 - t);\n  __m128i round_mask = _mm_set1_epi16(0x40);\n  __m128i zero = _mm_setzero_si128();\n  __m128i left_mask = _mm_set_epi32(0, 0, 0, 0xFF);\n  __m128i right_mask = _mm_set_epi8((char)0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);\n\n  __m128i left;\n\n  for (size_t y = 0; y < height; ++y) {\n    //left border\n    __m128i center = _mm_load_si128(reinterpret_cast<const __m128i*>(dstp));\n    __m128i right = _mm_loadu_si128(reinterpret_cast<const __m128i*>(dstp+1));\n    left = _mm_or_si128(_mm_and_si128(center, left_mask),  _mm_slli_si128(center, 1));\n\n    __m128i result = af_unpack_blend_sse2(left, center, right, center_weight, outer_weight, round_mask, zero);\n    left = _mm_loadu_si128(reinterpret_cast<const __m128i*>(dstp+15));\n    _mm_store_si128(reinterpret_cast<__m128i*>(dstp), result);\n\n    //main processing loop\n    for (size_t x = 16; x < sse_loop_limit; x+= 16) {\n      center = _mm_load_si128(reinterpret_cast<const __m128i*>(dstp+x));\n      right = _mm_loadu_si128(reinterpret_cast<const __m128i*>(dstp+x+1));\n\n      result = af_unpack_blend_sse2(left, center, right, center_weight, outer_weight, round_mask, zero);\n\n      left = _mm_loadu_si128(reinterpret_cast<const __m128i*>(dstp+x+15));\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp+x), result);\n    }\n\n    //right border\n    if(mod16_width == width) { //width is mod8, process with mmx\n      center = _mm_load_si128(reinterpret_cast<const __m128i*>(dstp+mod16_width-16));\n      right = _mm_or_si128(_mm_and_si128(center, right_mask),  _mm_srli_si128(center, 1));\n\n      result = af_unpack_blend_sse2(left, center, right, center_weight, outer_weight, round_mask, zero);\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp+mod16_width-16), result);\n    } else { //some stuff left\n      BYTE l = _mm_cvtsi128_si32(left) & 0xFF;\n      af_horizontal_planar_process_line_c<uint8_t>(l, dstp+mod16_width, width-mod16_width, center_weight_c, outer_weight_c);\n\n    }\n\n    dstp += pitch;\n  }\n}\n\nvoid af_horizontal_planar_uint16_t_sse2(BYTE* dstp, size_t height, size_t pitch, size_t row_size, size_t amount, int bits_per_pixel) {\n  size_t mod16_width = (row_size / 16) * 16;\n  size_t sse_loop_limit = row_size == mod16_width ? mod16_width - 16 : mod16_width;\n  int center_weight_c = int(amount * 2);\n  int outer_weight_c = int(32768 - amount);\n\n  int t = int((amount + 256) >> 9);\n  __m128i center_weight = _mm_set1_epi32(t);\n  __m128i outer_weight = _mm_set1_epi32(64 - t);\n  __m128i round_mask = _mm_set1_epi32(0x40);\n  __m128i zero = _mm_setzero_si128();\n  __m128i left_mask = _mm_set_epi16(0, 0, 0, 0, 0, 0, 0, (short)0xFFFF); // 0, 0, 0, 0, 0, 0, 0, FFFF\n  __m128i right_mask = _mm_set_epi16((short)0xFFFF, 0, 0, 0, 0, 0, 0, 0);\n\n  __m128i left;\n\n  for (size_t y = 0; y < height; ++y) {\n    //left border\n    __m128i center = _mm_load_si128(reinterpret_cast<const __m128i*>(dstp));\n    __m128i right = _mm_loadu_si128(reinterpret_cast<const __m128i*>(dstp + 2));\n    left = _mm_or_si128(_mm_and_si128(center, left_mask), _mm_slli_si128(center, 2));\n\n    __m128i result = af_unpack_blend_uint16_t_sse2(left, center, right, center_weight, outer_weight, round_mask, zero);\n    left = _mm_loadu_si128(reinterpret_cast<const __m128i*>(dstp + (16 - 2)));\n    _mm_store_si128(reinterpret_cast<__m128i*>(dstp), result);\n\n    //main processing loop\n    for (size_t x = 16; x < sse_loop_limit; x += 16) {\n      center = _mm_load_si128(reinterpret_cast<const __m128i*>(dstp + x));\n      right = _mm_loadu_si128(reinterpret_cast<const __m128i*>(dstp + x + 2));\n\n      result = af_unpack_blend_uint16_t_sse2(left, center, right, center_weight, outer_weight, round_mask, zero);\n\n      left = _mm_loadu_si128(reinterpret_cast<const __m128i*>(dstp + x + (16 - 2)));\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x), result);\n    }\n\n    //right border\n    if (mod16_width == row_size) { //width is mod8, process with mmx\n      center = _mm_load_si128(reinterpret_cast<const __m128i*>(dstp + mod16_width - 16));\n      right = _mm_or_si128(_mm_and_si128(center, right_mask), _mm_srli_si128(center, 2));\n\n      result = af_unpack_blend_uint16_t_sse2(left, center, right, center_weight, outer_weight, round_mask, zero);\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp + mod16_width - 16), result);\n    }\n    else { //some stuff left\n      uint16_t l = _mm_cvtsi128_si32(left) & 0xFFFF;\n      af_horizontal_planar_process_line_uint16_c(l, dstp + mod16_width, row_size - mod16_width, center_weight_c, outer_weight_c, bits_per_pixel);\n    }\n\n    dstp += pitch;\n  }\n}\n\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid af_horizontal_planar_uint16_t_sse41(BYTE* dstp, size_t height, size_t pitch, size_t row_size, size_t amount, int bits_per_pixel)\n{\n  size_t mod16_width = (row_size / 16) * 16;\n  size_t sse_loop_limit = row_size == mod16_width ? mod16_width - 16 : mod16_width;\n  int center_weight_c = int(amount * 2);\n  int outer_weight_c = int(32768 - amount);\n\n  int t = int((amount + 256) >> 9);\n  __m128i center_weight = _mm_set1_epi32(t);\n  __m128i outer_weight = _mm_set1_epi32(64 - t);\n  __m128i round_mask = _mm_set1_epi32(0x40);\n  __m128i zero = _mm_setzero_si128();\n  __m128i left_mask = _mm_set_epi16(0, 0, 0, 0, 0, 0, 0, (short)0xFFFF); // 0, 0, 0, 0, 0, 0, 0, FFFF\n  __m128i right_mask = _mm_set_epi16((short)0xFFFF, 0, 0, 0, 0, 0, 0, 0);\n\n  __m128i left;\n\n  for (size_t y = 0; y < height; ++y) {\n    //left border\n    __m128i center = _mm_load_si128(reinterpret_cast<const __m128i*>(dstp));\n    __m128i right = _mm_loadu_si128(reinterpret_cast<const __m128i*>(dstp + 2));\n    left = _mm_or_si128(_mm_and_si128(center, left_mask), _mm_slli_si128(center, 2));\n\n    __m128i result = af_unpack_blend_uint16_t_sse41(left, center, right, center_weight, outer_weight, round_mask, zero);\n    left = _mm_loadu_si128(reinterpret_cast<const __m128i*>(dstp + (16 - 2)));\n    _mm_store_si128(reinterpret_cast<__m128i*>(dstp), result);\n\n    //main processing loop\n    for (size_t x = 16; x < sse_loop_limit; x += 16) {\n      center = _mm_load_si128(reinterpret_cast<const __m128i*>(dstp + x));\n      right = _mm_loadu_si128(reinterpret_cast<const __m128i*>(dstp + x + 2));\n\n      result = af_unpack_blend_uint16_t_sse41(left, center, right, center_weight, outer_weight, round_mask, zero);\n\n      left = _mm_loadu_si128(reinterpret_cast<const __m128i*>(dstp + x + (16 - 2)));\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x), result);\n    }\n\n    //right border\n    if (mod16_width == row_size) { //width is mod8, process with mmx\n      center = _mm_load_si128(reinterpret_cast<const __m128i*>(dstp + mod16_width - 16));\n      right = _mm_or_si128(_mm_and_si128(center, right_mask), _mm_srli_si128(center, 2));\n\n      result = af_unpack_blend_uint16_t_sse41(left, center, right, center_weight, outer_weight, round_mask, zero);\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp + mod16_width - 16), result);\n    }\n    else { //some stuff left\n      uint16_t l = _mm_cvtsi128_si32(left) & 0xFFFF;\n      af_horizontal_planar_process_line_uint16_c(l, dstp + mod16_width, row_size - mod16_width, center_weight_c, outer_weight_c, bits_per_pixel);\n    }\n\n    dstp += pitch;\n  }\n}\n\nvoid af_horizontal_planar_float_sse2(BYTE* dstp, size_t height, size_t pitch, size_t row_size, float amount) {\n  const float center_weight = amount;\n  const float outer_weight = (1.0f - amount) / 2.0f;\n\n  __m128 center_weight_simd = _mm_set1_ps(center_weight);\n  __m128 outer_weight_simd = _mm_set1_ps(outer_weight);\n\n  size_t mod16_width = (row_size / 16) * 16;\n  size_t sse_loop_limit = row_size == mod16_width ? mod16_width - 16 : mod16_width;\n\n  __m128i left_mask = _mm_set_epi32(0, 0, 0, 0xFFFFFFFF);\n  __m128i right_mask = _mm_set_epi32(0xFFFFFFFF, 0, 0, 0);\n\n  __m128 left;\n\n  for (size_t y = 0; y < height; ++y) {\n    //left border\n    __m128 center = _mm_load_ps(reinterpret_cast<const float*>(dstp));\n    __m128 right = _mm_loadu_ps(reinterpret_cast<const float*>(dstp + sizeof(float)));\n    left = _mm_castsi128_ps(_mm_or_si128(_mm_and_si128(_mm_castps_si128(center), left_mask), _mm_slli_si128(_mm_castps_si128(center), sizeof(float))));\n\n    __m128 result = af_blend_float_sse2(left, center, right, center_weight_simd, outer_weight_simd);\n    left = _mm_loadu_ps(reinterpret_cast<const float*>(dstp + (16 - sizeof(float))));\n    _mm_store_ps(reinterpret_cast<float*>(dstp), result);\n\n    //main processing loop\n    for (size_t x = 16; x < sse_loop_limit; x += 16) {\n      center = _mm_load_ps(reinterpret_cast<const float*>(dstp + x));\n      right = _mm_loadu_ps(reinterpret_cast<const float*>(dstp + x + sizeof(float)));\n\n      result = af_blend_float_sse2(left, center, right, center_weight_simd, outer_weight_simd);\n\n      left = _mm_loadu_ps(reinterpret_cast<const float*>(dstp + x + (16 - sizeof(float))));\n\n      _mm_store_ps(reinterpret_cast<float*>(dstp + x), result);\n    }\n\n    //right border\n    if (mod16_width == row_size) { //width is mod8, process with mmx\n      center = _mm_load_ps(reinterpret_cast<const float*>(dstp + mod16_width - 16));\n      right = _mm_castsi128_ps(_mm_or_si128(_mm_and_si128(_mm_castps_si128(center), right_mask), _mm_srli_si128(_mm_castps_si128(center), sizeof(float))));\n\n      result = af_blend_float_sse2(left, center, right, center_weight_simd, outer_weight_simd);\n\n      _mm_store_ps(reinterpret_cast<float*>(dstp + mod16_width - 16), result);\n    }\n    else { //some stuff left\n      float l = _mm_cvtss_f32(left);\n      af_horizontal_planar_process_line_float_c(l, (float *)(dstp + mod16_width), row_size - mod16_width, center_weight, outer_weight);\n    }\n\n    dstp += pitch;\n  }\n}\n\n\n#ifdef X86_32\n\nvoid af_horizontal_planar_mmx(BYTE* dstp, size_t height, size_t pitch, size_t width, size_t amount) {\n  size_t mod8_width = (width / 8) * 8;\n  size_t mmx_loop_limit = width == mod8_width ? mod8_width - 8 : mod8_width;\n  int center_weight_c = amount*2;\n  int outer_weight_c = 32768-amount;\n\n  short t = short((amount + 256) >> 9);\n  __m64 center_weight = _mm_set1_pi16(t);\n  __m64 outer_weight = _mm_set1_pi16(64 - t);\n  __m64 round_mask = _mm_set1_pi16(0x40);\n  __m64 zero = _mm_setzero_si64();\n  __m64 left_mask = _mm_set_pi8(0, 0, 0, 0, 0, 0, 0, (char)0xFF);\n  __m64 right_mask = _mm_set_pi8((char)0xFF, 0, 0, 0, 0, 0, 0, 0);\n\n  __m64 left;\n\n  for (size_t y = 0; y < height; ++y) {\n    //left border\n    __m64 center = *reinterpret_cast<const __m64*>(dstp);\n    __m64 right = *reinterpret_cast<const __m64*>(dstp+1);\n    left = _mm_or_si64(_mm_and_si64(center, left_mask),  _mm_slli_si64(center, 8));\n\n    __m64 result = af_unpack_blend_mmx(left, center, right, center_weight, outer_weight, round_mask, zero);\n    left = *reinterpret_cast<const __m64*>(dstp+7);\n    *reinterpret_cast<__m64*>(dstp) = result;\n\n    //main processing loop\n    for (size_t x = 8; x < mmx_loop_limit; x+= 8) {\n      center = *reinterpret_cast<const __m64*>(dstp+x);\n      right = *reinterpret_cast<const __m64*>(dstp+x+1);\n\n      result = af_unpack_blend_mmx(left, center, right, center_weight, outer_weight, round_mask, zero);\n      left = *reinterpret_cast<const __m64*>(dstp+x+7);\n\n      *reinterpret_cast<__m64*>(dstp+x) = result;\n    }\n\n    //right border\n    if(mod8_width == width) { //width is mod8, process with mmx\n      center = *reinterpret_cast<const __m64*>(dstp+mod8_width-8);\n      right = _mm_or_si64(_mm_and_si64(center, right_mask),  _mm_srli_si64(center, 8));\n\n      result = af_unpack_blend_mmx(left, center, right, center_weight, outer_weight, round_mask, zero);\n\n      *reinterpret_cast<__m64*>(dstp+mod8_width-8) = result;\n    } else { //some stuff left\n      BYTE l = _mm_cvtsi64_si32(left) & 0xFF;\n      af_horizontal_planar_process_line_c<uint8_t>(l, dstp+mod8_width, width-mod8_width, center_weight_c, outer_weight_c);\n    }\n\n    dstp += pitch;\n  }\n  _mm_empty();\n}\n\n\n#endif\n\n\n\n\n\n\n\n\n\nstatic inline __m128i _mm_cmple_epu8(__m128i x, __m128i y)\n{\n  // Returns 0xFF where x <= y:\n  return _mm_cmpeq_epi8(_mm_min_epu8(x, y), x);\n}\n\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nstatic inline __m128i _mm_cmple_epu16_sse41(__m128i x, __m128i y)\n{\n  // Returns 0xFFFF where x <= y:\n  return _mm_cmpeq_epi16(_mm_min_epu16(x, y), x);\n}\n\nstatic inline __m128i _mm_cmple_epu16_sse2(__m128i x, __m128i y)\n{\n  // Returns 0xFFFF where x <= y:\n  return _mm_cmpeq_epi16(_mm_subs_epu16(x, y), _mm_setzero_si128());\n}\n\n// fast: maxThreshold (255) simple accumulate for average\ntemplate<bool maxThreshold>\nvoid accumulate_line_sse2(BYTE* c_plane, const BYTE** planeP, int planes, size_t width, int threshold, int div) {\n  // threshold: 8 bits: 2 bytes in a word. for YUY2: luma<<8 | chroma\n  // 16 bits: 16 bit value (orig threshold scaled by bits_per_pixel)\n  __m128i halfdiv_vector = _mm_set1_epi16(1); // High16(0x10000)\n  __m128i div_vector = _mm_set1_epi16(65536 / (planes + 1)); // mulhi\n  __m128i thresh = _mm_set1_epi16(threshold);\n\n  for (size_t x = 0; x < width; x+=16) {\n    __m128i current = _mm_load_si128(reinterpret_cast<const __m128i*>(c_plane+x));\n    __m128i zero = _mm_setzero_si128();\n     __m128i low = _mm_unpacklo_epi8(current, zero);\n     __m128i high = _mm_unpackhi_epi8(current, zero);\n\n    for (int plane = planes - 1; plane >= 0; --plane) {\n      __m128i p = _mm_load_si128(reinterpret_cast<const __m128i*>(planeP[plane] + x));\n\n      __m128i add_low, add_high;\n      if (maxThreshold) {\n        // fast: simple accumulate for average\n        add_low = _mm_unpacklo_epi8(p, zero);\n        add_high = _mm_unpackhi_epi8(p, zero);\n      } else {\n        auto pc = _mm_subs_epu8(p, current); // r2507-\n        auto cp = _mm_subs_epu8(current, p);\n        auto abs_cp = _mm_or_si128(pc, cp);\n        auto leq_thresh = _mm_cmple_epu8(abs_cp, thresh);\n\n        __m128i andop = _mm_and_si128(leq_thresh, p);\n        __m128i andnop = _mm_andnot_si128(leq_thresh, current);\n        __m128i blended = _mm_or_si128(andop, andnop); //abs(p-c) <= thresh ? p : c\n        add_low = _mm_unpacklo_epi8(blended, zero);\n        add_high = _mm_unpackhi_epi8(blended, zero);\n      }\n\n      low = _mm_adds_epu16(low, add_low);\n      high = _mm_adds_epu16(high, add_high);\n    }\n\n    // non SSSE3, no _mm_mulhrs_epi16\n    // (x*2 * 65536/N + 65536) / 65536 / 2\n    // Hi16(x*2 * 65536/N + 1) >> 1\n    low = _mm_mulhi_epu16(_mm_slli_epi16(low, 1), div_vector);\n    low = _mm_adds_epu16(low, halfdiv_vector);\n    low = _mm_srli_epi16(low, 1);\n    high = _mm_mulhi_epu16(_mm_slli_epi16(high, 1), div_vector);\n    high = _mm_adds_epu16(high, halfdiv_vector);\n    high = _mm_srli_epi16(high, 1);\n    __m128i acc = _mm_packus_epi16(low, high);\n\n    _mm_store_si128(reinterpret_cast<__m128i*>(c_plane+x), acc);\n  }\n}\n\n// instantiate\ntemplate void accumulate_line_sse2<false>(BYTE* c_plane, const BYTE** planeP, int planes, size_t width, int threshold, int div);\ntemplate void accumulate_line_sse2<true>(BYTE* c_plane, const BYTE** planeP, int planes, size_t width, int threshold, int div);\n\n\ntemplate<bool maxThreshold>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nvoid accumulate_line_ssse3(BYTE* c_plane, const BYTE** planeP, int planes, size_t width, int threshold, int div)\n{\n  // threshold: 8 bits: 2 bytes in a word. for YUY2: luma<<8 | chroma\n  // 16 bits: 16 bit value (orig threshold scaled by bits_per_pixel)\n  __m128i div_vector = _mm_set1_epi16(div);\n\n  __m128i thresh = _mm_set1_epi16(threshold);\n\n  for (size_t x = 0; x < width; x += 16) {\n    __m128i current = _mm_load_si128(reinterpret_cast<const __m128i*>(c_plane + x));\n    __m128i zero = _mm_setzero_si128();\n    __m128i low = _mm_unpacklo_epi8(current, zero);\n    __m128i high = _mm_unpackhi_epi8(current, zero);\n\n    for (int plane = planes - 1; plane >= 0; --plane) {\n      __m128i p = _mm_load_si128(reinterpret_cast<const __m128i*>(planeP[plane] + x));\n\n      __m128i add_low, add_high;\n      if (maxThreshold) {\n        // fast: simple accumulate for average\n        add_low = _mm_unpacklo_epi8(p, zero);\n        add_high = _mm_unpackhi_epi8(p, zero);\n      }\n      else {\n        auto pc = _mm_subs_epu8(p, current); // r2507-\n        auto cp = _mm_subs_epu8(current, p);\n        auto abs_cp = _mm_or_si128(pc, cp);\n        auto leq_thresh = _mm_cmple_epu8(abs_cp, thresh);\n\n        __m128i andop = _mm_and_si128(leq_thresh, p);\n        __m128i andnop = _mm_andnot_si128(leq_thresh, current);\n        __m128i blended = _mm_or_si128(andop, andnop); //abs(p-c) <= thresh ? p : c\n        add_low = _mm_unpacklo_epi8(blended, zero);\n        add_high = _mm_unpackhi_epi8(blended, zero);\n      }\n\n      low = _mm_adds_epu16(low, add_low);\n      high = _mm_adds_epu16(high, add_high);\n    }\n\n      // SSSE3: _mm_mulhrs_epi16: r0 := INT16(((a0 * b0) + 0x4000) >> 15)\n    low = _mm_mulhrs_epi16(low, div_vector);\n    high = _mm_mulhrs_epi16(high, div_vector);\n    __m128i acc = _mm_packus_epi16(low, high);\n\n    _mm_store_si128(reinterpret_cast<__m128i*>(c_plane + x), acc);\n  }\n}\n\n// instantiate\ntemplate void accumulate_line_ssse3<false>(BYTE* c_plane, const BYTE** planeP, int planes, size_t width, int threshold, int div);\ntemplate void accumulate_line_ssse3<true>(BYTE* c_plane, const BYTE** planeP, int planes, size_t width, int threshold, int div);\n\n\n// fast: maxThreshold (255) simple accumulate for average\ntemplate<bool maxThreshold, bool lessThan16bit>\nvoid accumulate_line_16_sse2(BYTE* c_plane, const BYTE** planeP, int planes, size_t rowsize, int threshold, int div, int bits_per_pixel) {\n  // threshold:\n  // 10-16 bits: orig threshold scaled by (bits_per_pixel-8)\n  int max_pixel_value = (1 << bits_per_pixel) - 1;\n  __m128i limit = _mm_set1_epi16(max_pixel_value); //used for clamping when 10-14 bits\n  __m128 div_vector = _mm_set1_ps(1.0f / (planes + 1));\n  __m128i thresh = _mm_set1_epi16(threshold);\n\n\n  for (size_t x = 0; x < rowsize; x+=16) {\n    __m128i current = _mm_load_si128(reinterpret_cast<const __m128i*>(c_plane+x));\n    __m128i zero = _mm_setzero_si128();\n    __m128i low, high;\n    low = _mm_unpacklo_epi16(current, zero);\n    high = _mm_unpackhi_epi16(current, zero);\n\n    for (int plane = planes - 1; plane >= 0; --plane) {\n      __m128i p = _mm_load_si128(reinterpret_cast<const __m128i*>(planeP[plane] + x));\n\n      __m128i add_low, add_high;\n      if (maxThreshold) {\n        // fast: simple accumulate for average\n        add_low = _mm_unpacklo_epi16(p, zero);\n        add_high = _mm_unpackhi_epi16(p, zero);\n      } else {\n        auto pc = _mm_subs_epu16(p, current); // r2507-\n        auto cp = _mm_subs_epu16(current, p);\n        auto abs_cp = _mm_or_si128(pc, cp);\n        auto leq_thresh = _mm_cmple_epu16_sse2(abs_cp, thresh);\n        /*\n        __m128i p_greater_t = _mm_subs_epu16(p, thresh);\n        __m128i c_greater_t = _mm_subs_epu16(current, thresh);\n        __m128i over_thresh = _mm_or_si128(p_greater_t, c_greater_t); //abs(p-c) - t == (satsub(p,c) | satsub(c,p)) - t =kinda= satsub(p,t) | satsub(c,t)\n\n        __m128i leq_thresh = _mm_cmpeq_epi16(over_thresh, zero); //abs diff lower or equal to threshold\n        */\n\n        __m128i andop = _mm_and_si128(leq_thresh, p);\n        __m128i andnop = _mm_andnot_si128(leq_thresh, current);\n        __m128i blended = _mm_or_si128(andop, andnop); //abs(p-c) <= thresh ? p : c\n\n        add_low = _mm_unpacklo_epi16(blended, zero);\n        add_high = _mm_unpackhi_epi16(blended, zero);\n      }\n      low = _mm_add_epi32(low, add_low);\n      high = _mm_add_epi32(high, add_high);\n    }\n\n    __m128i acc;\n    //__m128 half = _mm_set1_ps(0.5f); // no need rounder, _mm_cvtps_epi32 default is round-to-nearest, unless we use _mm_cvttps_epi32 which truncates\n    low = _mm_cvtps_epi32(_mm_mul_ps(_mm_cvtepi32_ps(low), div_vector));\n    high = _mm_cvtps_epi32(_mm_mul_ps(_mm_cvtepi32_ps(high), div_vector));\n    acc = _MM_PACKUS_EPI32(low, high); // sse4.1 simul\n    if (lessThan16bit)\n      acc = _MM_MIN_EPU16(acc, limit); // sse4.1 simul\n\n    _mm_store_si128(reinterpret_cast<__m128i*>(c_plane+x), acc);\n  }\n}\n\n\n// instantiate\ntemplate void accumulate_line_16_sse2<false, false>(BYTE* c_plane, const BYTE** planeP, int planes, size_t rowsize, int threshold, int div, int bits_per_pixel);\ntemplate void accumulate_line_16_sse2<false, true>(BYTE* c_plane, const BYTE** planeP, int planes, size_t rowsize, int threshold, int div, int bits_per_pixel);\ntemplate void accumulate_line_16_sse2<true, false>(BYTE* c_plane, const BYTE** planeP, int planes, size_t rowsize, int threshold, int div, int bits_per_pixel);\ntemplate void accumulate_line_16_sse2<true, true>(BYTE* c_plane, const BYTE** planeP, int planes, size_t rowsize, int threshold, int div, int bits_per_pixel);\n\n\n// fast: maxThreshold (255) simple accumulate for average\ntemplate<bool maxThreshold, bool lessThan16bit>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid accumulate_line_16_sse41(BYTE* c_plane, const BYTE** planeP, int planes, size_t rowsize, int threshold, int div, int bits_per_pixel)\n{\n  // threshold:\n  // 10-16 bits: orig threshold scaled by (bits_per_pixel-8)\n  int max_pixel_value = (1 << bits_per_pixel) - 1;\n  __m128i limit = _mm_set1_epi16(max_pixel_value); //used for clamping when 10-14 bits\n  // halfdiv_vector = _mm_set1_epi32(1); // n/a\n  __m128 div_vector = _mm_set1_ps(1.0f / (planes + 1));\n  __m128i thresh = _mm_set1_epi16(threshold);\n\n\n  for (size_t x = 0; x < rowsize; x += 16) {\n    __m128i current = _mm_load_si128(reinterpret_cast<const __m128i*>(c_plane + x));\n    __m128i zero = _mm_setzero_si128();\n    __m128i low, high;\n    low = _mm_unpacklo_epi16(current, zero);\n    high = _mm_unpackhi_epi16(current, zero);\n\n    for (int plane = planes - 1; plane >= 0; --plane) {\n      __m128i p = _mm_load_si128(reinterpret_cast<const __m128i*>(planeP[plane] + x));\n\n      __m128i add_low, add_high;\n      if (maxThreshold) {\n        // fast: simple accumulate for average\n        add_low = _mm_unpacklo_epi16(p, zero);\n        add_high = _mm_unpackhi_epi16(p, zero);\n      }\n      else {\n        auto pc = _mm_subs_epu16(p, current); // r2507-\n        auto cp = _mm_subs_epu16(current, p);\n        auto abs_cp = _mm_or_si128(pc, cp);\n        auto leq_thresh = _mm_cmple_epu16_sse41(abs_cp, thresh);\n        /*\n        __m128i p_greater_t = _mm_subs_epu16(p, thresh);\n        __m128i c_greater_t = _mm_subs_epu16(current, thresh);\n        __m128i over_thresh = _mm_or_si128(p_greater_t, c_greater_t); //abs(p-c) - t == (satsub(p,c) | satsub(c,p)) - t =kinda= satsub(p,t) | satsub(c,t)\n\n        __m128i leq_thresh = _mm_cmpeq_epi16(over_thresh, zero); //abs diff lower or equal to threshold\n        */\n\n        __m128i andop = _mm_and_si128(leq_thresh, p);\n        __m128i andnop = _mm_andnot_si128(leq_thresh, current);\n        __m128i blended = _mm_or_si128(andop, andnop); //abs(p-c) <= thresh ? p : c\n\n        add_low = _mm_unpacklo_epi16(blended, zero);\n        add_high = _mm_unpackhi_epi16(blended, zero);\n      }\n      low = _mm_add_epi32(low, add_low);\n      high = _mm_add_epi32(high, add_high);\n    }\n\n    __m128i acc;\n    //__m128 half = _mm_set1_ps(0.5f); // no need rounder, _mm_cvtps_epi32 default is round-to-nearest, unless we use _mm_cvttps_epi32 which truncates\n    low = _mm_cvtps_epi32(_mm_mul_ps(_mm_cvtepi32_ps(low), div_vector));\n    high = _mm_cvtps_epi32(_mm_mul_ps(_mm_cvtepi32_ps(high), div_vector));\n    acc = _mm_packus_epi32(low, high); // sse41\n    if (lessThan16bit)\n      acc = _mm_min_epu16(acc, limit); // sse41\n\n    _mm_store_si128(reinterpret_cast<__m128i*>(c_plane + x), acc);\n  }\n}\n\n// instantiate\n// fast: maxThreshold (255) simple accumulate for average\ntemplate void accumulate_line_16_sse41<false, false>(BYTE* c_plane, const BYTE** planeP, int planes, size_t rowsize, int threshold, int div, int bits_per_pixel);\ntemplate void accumulate_line_16_sse41<false, true>(BYTE* c_plane, const BYTE** planeP, int planes, size_t rowsize, int threshold, int div, int bits_per_pixel);\ntemplate void accumulate_line_16_sse41<true, false>(BYTE* c_plane, const BYTE** planeP, int planes, size_t rowsize, int threshold, int div, int bits_per_pixel);\ntemplate void accumulate_line_16_sse41<true, true>(BYTE* c_plane, const BYTE** planeP, int planes, size_t rowsize, int threshold, int div, int bits_per_pixel);\n\n\n#ifdef X86_32\n\nstatic AVS_FORCEINLINE __m64 ts_multiply_repack_mmx(const __m64 &src, const __m64 &div, __m64 &halfdiv, __m64 &zero) {\n  __m64 acc = _mm_madd_pi16(src, div);\n  acc = _mm_add_pi32(acc, halfdiv);\n  acc = _mm_srli_pi32(acc, 15);\n  acc = _mm_packs_pi32(acc, acc);\n  return _mm_packs_pu16(acc, zero);\n}\n\n//thresh and div must always be 16-bit integers. Thresh is 2 packed bytes and div is a single 16-bit number\nvoid accumulate_line_mmx(BYTE* c_plane, const BYTE** planeP, int planes, size_t width, int threshold, int div) {\n  __m64 halfdiv_vector = _mm_set1_pi32(16384);\n  __m64 div_vector = _mm_set1_pi16(div);\n\n  for (size_t x = 0; x < width; x+=8) {\n    __m64 current = *reinterpret_cast<const __m64*>(c_plane+x);\n    __m64 zero = _mm_setzero_si64();\n    __m64 low = _mm_unpacklo_pi8(current, zero);\n    __m64 high = _mm_unpackhi_pi8(current, zero);\n    __m64 thresh = _mm_set1_pi16(threshold);\n\n    for(int plane = planes-1; plane >= 0; --plane) {\n      __m64 p = *reinterpret_cast<const __m64*>(planeP[plane]+x);\n\n      __m64 p_greater_t = _mm_subs_pu8(p, thresh);\n      __m64 c_greater_t = _mm_subs_pu8(current, thresh);\n      __m64 over_thresh = _mm_or_si64(p_greater_t, c_greater_t); //abs(p-c) - t == (satsub(p,c) | satsub(c,p)) - t =kinda= satsub(p,t) | satsub(c,t)\n\n      __m64 leq_thresh = _mm_cmpeq_pi8(over_thresh, zero); //abs diff lower or equal to threshold\n\n      __m64 andop = _mm_and_si64(leq_thresh, p);\n      __m64 andnop = _mm_andnot_si64(leq_thresh, current);\n      __m64 blended = _mm_or_si64(andop, andnop); //abs(p-c) <= thresh ? p : c\n\n      __m64 add_low = _mm_unpacklo_pi8(blended, zero);\n      __m64 add_high = _mm_unpackhi_pi8(blended, zero);\n\n      low = _mm_adds_pu16(low, add_low);\n      high = _mm_adds_pu16(high, add_high);\n    }\n\n    __m64 low_low   = ts_multiply_repack_mmx(_mm_unpacklo_pi16(low, zero), div_vector, halfdiv_vector, zero);\n    __m64 low_high  = ts_multiply_repack_mmx(_mm_unpackhi_pi16(low, zero), div_vector, halfdiv_vector, zero);\n    __m64 high_low  = ts_multiply_repack_mmx(_mm_unpacklo_pi16(high, zero), div_vector, halfdiv_vector, zero);\n    __m64 high_high = ts_multiply_repack_mmx(_mm_unpackhi_pi16(high, zero), div_vector, halfdiv_vector, zero);\n\n    low = _mm_unpacklo_pi16(low_low, low_high);\n    high = _mm_unpacklo_pi16(high_low, high_high);\n\n   __m64 acc = _mm_unpacklo_pi32(low, high);\n\n    *reinterpret_cast<__m64*>(c_plane+x) = acc;\n  }\n  _mm_empty();\n}\n\n#endif\n\n\n\n// may also used from conditionalfunctions\n// packed rgb template masks out alpha plane for RGB32\ntemplate<bool packedRGB3264>\nint calculate_sad_sse2(const BYTE* cur_ptr, const BYTE* other_ptr, int cur_pitch, int other_pitch, size_t rowsize, size_t height)\n{\n  size_t mod16_width = rowsize / 16 * 16;\n  int result = 0;\n  __m128i sum = _mm_setzero_si128();\n\n  __m128i rgb_mask;\n  if (packedRGB3264) {\n    rgb_mask = _mm_set1_epi32(0x00FFFFFF);\n  }\n\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < mod16_width; x+=16) {\n      __m128i cur = _mm_load_si128(reinterpret_cast<const __m128i*>(cur_ptr + x));\n      __m128i other = _mm_load_si128(reinterpret_cast<const __m128i*>(other_ptr + x));\n      if (packedRGB3264) {\n        cur = _mm_and_si128(cur, rgb_mask);  // mask out A channel\n        other = _mm_and_si128(other, rgb_mask);\n      }\n      __m128i sad = _mm_sad_epu8(cur, other);\n      sum = _mm_add_epi32(sum, sad);\n    }\n    if (mod16_width != rowsize) {\n      if (packedRGB3264)\n        for (size_t x = mod16_width / 4; x < rowsize / 4; x += 4) {\n          result += std::abs(cur_ptr[x*4+0] - other_ptr[x*4+0]) +\n            std::abs(cur_ptr[x*4+1] - other_ptr[x*4+1]) +\n            std::abs(cur_ptr[x*4+2] - other_ptr[x*4+2]);\n          // no alpha\n        }\n      else\n        for (size_t x = mod16_width; x < rowsize; ++x) {\n          result += std::abs(cur_ptr[x] - other_ptr[x]);\n        }\n    }\n    cur_ptr += cur_pitch;\n    other_ptr += other_pitch;\n  }\n  __m128i upper = _mm_castps_si128(_mm_movehl_ps(_mm_setzero_ps(), _mm_castsi128_ps(sum)));\n  sum = _mm_add_epi32(sum, upper);\n  result += _mm_cvtsi128_si32(sum);\n  return result;\n}\n\n// instantiate\ntemplate int calculate_sad_sse2<false>(const BYTE* cur_ptr, const BYTE* other_ptr, int cur_pitch, int other_pitch, size_t rowsize, size_t height);\ntemplate int calculate_sad_sse2<true>(const BYTE* cur_ptr, const BYTE* other_ptr, int cur_pitch, int other_pitch, size_t rowsize, size_t height);\n\n\n// works for uint8_t, but there is a specific, bit faster function above\n// also used from conditionalfunctions\n// packed rgb template masks out alpha plane for RGB32/RGB64\ntemplate<typename pixel_t, bool packedRGB3264>\nint64_t calculate_sad_8_or_16_sse2(const BYTE* cur_ptr, const BYTE* other_ptr, int cur_pitch, int other_pitch, size_t rowsize, size_t height)\n{\n  size_t mod16_width = rowsize / 16 * 16;\n\n  __m128i zero = _mm_setzero_si128();\n  int64_t totalsum = 0; // fullframe SAD exceeds int32 at 8+ bit\n\n  __m128i rgb_mask;\n  if (packedRGB3264) {\n    if constexpr(sizeof(pixel_t) == 1)\n      rgb_mask = _mm_set1_epi32(0x00FFFFFF);\n    else\n      rgb_mask = _mm_set_epi32(0x0000FFFF,0xFFFFFFFF,0x0000FFFF,0xFFFFFFFF);\n  }\n\n  for ( size_t y = 0; y < height; y++ )\n  {\n    __m128i sum = _mm_setzero_si128(); // for one row int is enough\n    for ( size_t x = 0; x < mod16_width; x+=16 )\n    {\n      __m128i src1, src2;\n      src1 = _mm_load_si128((__m128i *) (cur_ptr + x));   // 16 bytes or 8 words\n      src2 = _mm_load_si128((__m128i *) (other_ptr + x));\n      if (packedRGB3264) {\n        src1 = _mm_and_si128(src1, rgb_mask); // mask out A channel\n        src2 = _mm_and_si128(src2, rgb_mask);\n      }\n      if constexpr(sizeof(pixel_t) == 1) {\n        // this is uint_16 specific, but leave here for sample\n        sum = _mm_add_epi32(sum, _mm_sad_epu8(src1, src2)); // sum0_32, 0, sum1_32, 0\n      }\n      else if constexpr(sizeof(pixel_t) == 2) {\n        __m128i greater_t = _mm_subs_epu16(src1, src2); // unsigned sub with saturation\n        __m128i smaller_t = _mm_subs_epu16(src2, src1);\n        __m128i absdiff = _mm_or_si128(greater_t, smaller_t); //abs(s1-s2)  == (satsub(s1,s2) | satsub(s2,s1))\n        // 8 x uint16 absolute differences\n        sum = _mm_add_epi32(sum, _mm_unpacklo_epi16(absdiff, zero));\n        sum = _mm_add_epi32(sum, _mm_unpackhi_epi16(absdiff, zero));\n        // sum0_32, sum1_32, sum2_32, sum3_32\n      }\n    }\n    // summing up partial sums\n    if constexpr(sizeof(pixel_t) == 2) {\n      // at 16 bits: we have 4 integers for sum: a0 a1 a2 a3\n      __m128i a0_a1 = _mm_unpacklo_epi32(sum, zero); // a0 0 a1 0\n      __m128i a2_a3 = _mm_unpackhi_epi32(sum, zero); // a2 0 a3 0\n      sum = _mm_add_epi32( a0_a1, a2_a3 ); // a0+a2, 0, a1+a3, 0\n      /* SSSE3: told to be not too fast\n      sum = _mm_hadd_epi32(sum, zero);  // A1+A2, B1+B2, 0+0, 0+0\n      sum = _mm_hadd_epi32(sum, zero);  // A1+A2+B1+B2, 0+0+0+0, 0+0+0+0, 0+0+0+0\n      */\n    }\n\n    // sum here: two 32 bit partial result: sum1 0 sum2 0\n    __m128i sum_hi = _mm_unpackhi_epi64(sum, zero);\n    // or: __m128i sum_hi = _mm_castps_si128(_mm_movehl_ps(_mm_setzero_ps(), _mm_castsi128_ps(sum)));\n    sum = _mm_add_epi32(sum, sum_hi);\n    int rowsum = _mm_cvtsi128_si32(sum);\n\n    // rest\n    if (mod16_width != rowsize) {\n      if (packedRGB3264)\n        for (size_t x = mod16_width / sizeof(pixel_t) / 4; x < rowsize / sizeof(pixel_t) / 4; x += 4) {\n          rowsum += std::abs(reinterpret_cast<const pixel_t *>(cur_ptr)[x*4+0] - reinterpret_cast<const pixel_t *>(other_ptr)[x*4+0]) +\n            std::abs(reinterpret_cast<const pixel_t *>(cur_ptr)[x*4+1] - reinterpret_cast<const pixel_t *>(other_ptr)[x*4+1]) +\n            std::abs(reinterpret_cast<const pixel_t *>(cur_ptr)[x*4+2] - reinterpret_cast<const pixel_t *>(other_ptr)[x*4+2]);\n          // no alpha\n        }\n      else\n        for (size_t x = mod16_width / sizeof(pixel_t); x < rowsize / sizeof(pixel_t); ++x) {\n          rowsum += std::abs(reinterpret_cast<const pixel_t *>(cur_ptr)[x] - reinterpret_cast<const pixel_t *>(other_ptr)[x]);\n        }\n    }\n\n    totalsum += rowsum;\n\n    cur_ptr += cur_pitch;\n    other_ptr += other_pitch;\n  }\n  return totalsum;\n}\n\n// instantiate\ntemplate int64_t calculate_sad_8_or_16_sse2<uint8_t, false>(const BYTE* cur_ptr, const BYTE* other_ptr, int cur_pitch, int other_pitch, size_t rowsize, size_t height);\ntemplate int64_t calculate_sad_8_or_16_sse2<uint8_t, true>(const BYTE* cur_ptr, const BYTE* other_ptr, int cur_pitch, int other_pitch, size_t rowsize, size_t height);\ntemplate int64_t calculate_sad_8_or_16_sse2<uint16_t, false>(const BYTE* cur_ptr, const BYTE* other_ptr, int cur_pitch, int other_pitch, size_t rowsize, size_t height);\ntemplate int64_t calculate_sad_8_or_16_sse2<uint16_t, true>(const BYTE* cur_ptr, const BYTE* other_ptr, int cur_pitch, int other_pitch, size_t rowsize, size_t height);\n\n\n#ifdef X86_32\nint calculate_sad_isse(const BYTE* cur_ptr, const BYTE* other_ptr, int cur_pitch, int other_pitch, size_t rowsize, size_t height)\n{\n  size_t mod8_width = rowsize / 8 * 8;\n  int result = 0;\n  __m64 sum = _mm_setzero_si64();\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < mod8_width; x+=8) {\n      __m64 cur = *reinterpret_cast<const __m64*>(cur_ptr + x);\n      __m64 other = *reinterpret_cast<const __m64*>(other_ptr + x);\n      __m64 sad = _mm_sad_pu8(cur, other);\n      sum = _mm_add_pi32(sum, sad);\n    }\n    if (mod8_width != rowsize) {\n      for (size_t x = mod8_width; x < rowsize; ++x) {\n        result += std::abs(cur_ptr[x] - other_ptr[x]);\n      }\n    }\n\n    cur_ptr += cur_pitch;\n    other_ptr += other_pitch;\n  }\n  result += _mm_cvtsi64_si32(sum);\n  _mm_empty();\n  return result;\n}\n#endif\n\n\n\n\n\n\n\n"
  },
  {
    "path": "avs_core/filters/intel/focus_sse.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Focus_SSE_H__\n#define __Focus_SSE_H__\n\n#include <avs/config.h>\n#include <avs/types.h>\n#include <cstdint>\n\n#ifdef X86_32\nvoid af_vertical_mmx(BYTE* line_buf, BYTE* dstp, int height, int pitch, int width, int amount);\n#endif\nvoid af_vertical_sse2(BYTE* line_buf, BYTE* dstp, int height, int pitch, int width, int amount);\nvoid af_vertical_uint16_t_sse2(BYTE* line_buf, BYTE* dstp, int height, int pitch, int row_size, int amount);\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid af_vertical_uint16_t_sse41(BYTE* line_buf, BYTE* dstp, int height, int pitch, int row_size, int amount);\nvoid af_vertical_sse2_float(BYTE * line_buf, BYTE * dstp, const int height, const int pitch, const int row_size, const float amount);\n\n\n#ifdef X86_32\nvoid af_horizontal_planar_mmx(BYTE* dstp, size_t height, size_t pitch, size_t width, size_t amount);\n#endif\nvoid af_horizontal_planar_sse2(BYTE* dstp, size_t height, size_t pitch, size_t width, size_t amount);\nvoid af_horizontal_planar_uint16_t_sse2(BYTE* dstp, size_t height, size_t pitch, size_t row_size, size_t amount, int bits_per_pixel);\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid af_horizontal_planar_uint16_t_sse41(BYTE* dstp, size_t height, size_t pitch, size_t row_size, size_t amount, int bits_per_pixel);\nvoid af_horizontal_planar_float_sse2(BYTE* dstp, size_t height, size_t pitch, size_t row_size, float amount);\n\n\n#ifdef X86_32\nvoid af_horizontal_yuy2_mmx(BYTE* dstp, const BYTE* srcp, size_t dst_pitch, size_t src_pitch, size_t height, size_t width, size_t amount);\n#endif\nvoid af_horizontal_yuy2_sse2(BYTE* dstp, const BYTE* srcp, size_t dst_pitch, size_t src_pitch, size_t height, size_t width, size_t amount);\n\n#ifdef X86_32\nvoid af_horizontal_rgb32_mmx(BYTE* dstp, const BYTE* srcp, size_t dst_pitch, size_t src_pitch, size_t height, size_t width, size_t amount);\n#endif\nvoid af_horizontal_rgb32_sse2(BYTE* dstp, const BYTE* srcp, size_t dst_pitch, size_t src_pitch, size_t height, size_t width, size_t amount);\n\nvoid af_horizontal_rgb64_sse2(BYTE* dstp, const BYTE* srcp, size_t dst_pitch, size_t src_pitch, size_t height, size_t width, size_t amount);\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid af_horizontal_rgb64_sse41(BYTE* dstp, const BYTE* srcp, size_t dst_pitch, size_t src_pitch, size_t height, size_t width, size_t amount);\n\n\n\n#ifdef X86_32\nvoid accumulate_line_mmx(BYTE* c_plane, const BYTE** planeP, int planes, size_t width, int threshold, int div);\n#endif\ntemplate<bool maxThreshold>\nvoid accumulate_line_sse2(BYTE* c_plane, const BYTE** planeP, int planes, size_t width, int threshold, int div);\ntemplate<bool maxThreshold>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nvoid accumulate_line_ssse3(BYTE* c_plane, const BYTE** planeP, int planes, size_t width, int threshold, int div);\ntemplate<bool maxThreshold, bool lessThan16bit>\nvoid accumulate_line_16_sse2(BYTE* c_plane, const BYTE** planeP, int planes, size_t rowsize, int threshold, int div, int bits_per_pixel);\ntemplate<bool maxThreshold, bool lessThan16bit>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid accumulate_line_16_sse41(BYTE* c_plane, const BYTE** planeP, int planes, size_t rowsize, int threshold, int div, int bits_per_pixel);\n\n#ifdef X86_32\nint calculate_sad_isse(const BYTE* cur_ptr, const BYTE* other_ptr, int cur_pitch, int other_pitch, size_t rowsize, size_t height);\n#endif\ntemplate<bool packedRGB3264>\nint calculate_sad_sse2(const BYTE* cur_ptr, const BYTE* other_ptr, int cur_pitch, int other_pitch, size_t rowsize, size_t height);\ntemplate<typename pixel_t, bool packedRGB3264>\nint64_t calculate_sad_8_or_16_sse2(const BYTE* cur_ptr, const BYTE* other_ptr, int cur_pitch, int other_pitch, size_t rowsize, size_t height);\n\n#endif  // __Focus_SSE_H__\n"
  },
  {
    "path": "avs_core/filters/intel/greyscale_sse.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n\n#include \"greyscale_sse.h\"\n#include \"../convert/convert_matrix.h\"\n\n// Intrinsics base header + really required extension headers\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n#include <smmintrin.h> // SSE4.1\n\n#include <avs/config.h>\n#include <avs/types.h>\n#include \"avs/minmax.h\"\n\nvoid greyscale_yuy2_sse2(BYTE *srcp, size_t /*width*/, size_t height, size_t pitch) {\n  __m128i luma_mask = _mm_set1_epi16(0x00FF);\n  __m128i chroma_value = _mm_set1_epi16((short)0x8000);\n  BYTE* end_point = srcp + pitch * height;\n\n  while(srcp < end_point) {\n    __m128i src = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp));\n    src = _mm_and_si128(src, luma_mask);\n    src = _mm_or_si128(src, chroma_value);\n    _mm_store_si128(reinterpret_cast<__m128i*>(srcp), src);\n\n    srcp += 16;\n  }\n}\n\nvoid greyscale_rgb32_sse2(BYTE *srcp, size_t /*width*/, size_t height, size_t pitch, ConversionMatrix &m) {\n  const bool has_offset_rgb = 0 != m.offset_rgb;\n  // greyscale RGB is putting pack the calculated pixels to rgb\n  // Limited range input remains limited range output (-offset_rgb is the same as offset_y)\n\n  __m128i matrix = _mm_set_epi16(0, m.y_r, m.y_g, m.y_b, 0, m.y_r, m.y_g, m.y_b);\n  __m128i zero = _mm_setzero_si128();\n  // .15 frac bit integer arithmetic\n  int round_mask_and_luma_offset_i = (1 << 14) + (m.offset_y << 15);\n  __m128i round_mask_and_luma_offset = _mm_set1_epi32(round_mask_and_luma_offset_i); // four pixels at a time\n  __m128i alpha_mask = _mm_set1_epi32(0xFF000000);\n\n  __m128i offset_rgb = _mm_set_epi16(0, m.offset_rgb, m.offset_rgb, m.offset_rgb, 0, m.offset_rgb, m.offset_rgb, m.offset_rgb);\n\n  BYTE* end_point = srcp + pitch * height;\n\n  while(srcp < end_point) {\n    __m128i src = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp));\n    __m128i alpha = _mm_and_si128(src, alpha_mask);\n    __m128i pixel01 = _mm_unpacklo_epi8(src, zero);\n    __m128i pixel23 = _mm_unpackhi_epi8(src, zero);\n\n    if (has_offset_rgb) {\n      pixel01 = _mm_add_epi16(pixel01, offset_rgb);\n      pixel23 = _mm_add_epi16(pixel23, offset_rgb);\n    }\n\n    pixel01 = _mm_madd_epi16(pixel01, matrix);\n    pixel23 = _mm_madd_epi16(pixel23, matrix);\n\n    __m128i tmp = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(pixel01), _mm_castsi128_ps(pixel23), _MM_SHUFFLE(3, 1, 3, 1))); // r3*cyr | r2*cyr | r1*cyr | r0*cyr\n    __m128i tmp2 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(pixel01), _mm_castsi128_ps(pixel23), _MM_SHUFFLE(2, 0, 2, 0)));\n\n    tmp = _mm_add_epi32(tmp, tmp2);\n    tmp = _mm_add_epi32(tmp, round_mask_and_luma_offset);\n    tmp = _mm_srli_epi32(tmp, 15); // 0 0 0 p3 | 0 0 0 p2 | 0 0 0 p1 | 0 0 0 p0  the grey scale byte itself\n\n    // make r=g=b\n\n    __m128i result = _mm_or_si128(tmp, _mm_slli_si128(tmp, 1)); // 0 0 p3 p3 | 0 0 p2 p2 | 0 0 p1 p1 | 0 0 p0 p0\n    result = _mm_or_si128(result, _mm_slli_si128(tmp, 2)); // 0 p3 p3 p3 | 0 p2 p2 p2 | 0 p1 p1 p1 | 0 p0 p0 p0\n    result = _mm_or_si128(alpha, result);\n\n    _mm_store_si128(reinterpret_cast<__m128i*>(srcp), result);\n\n    srcp += 16;\n  }\n}\n\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid greyscale_rgb64_sse41(BYTE *srcp, size_t /*width*/, size_t height, size_t pitch, ConversionMatrix &m)\n{\n  const bool has_offset_rgb = 0 != m.offset_rgb;\n  // greyscale RGB is putting pack the calculated pixels to rgb\n  // Limited range input remains limited range output (-offset_rgb is the same as offset_y)\n\n  __m128i matrix = _mm_set_epi32(0, m.y_r, m.y_g, m.y_b);\n  __m128i zero = _mm_setzero_si128();\n  // .15 frac bit integer arithmetic\n  int round_mask_and_luma_offset_i = (1 << 14) + (m.offset_y << 15);\n  __m128i round_mask_and_luma_offset = _mm_set_epi32(0, round_mask_and_luma_offset_i, round_mask_and_luma_offset_i, round_mask_and_luma_offset_i);\n  uint64_t mask64 = 0xFFFF000000000000ull;\n  __m128i alpha_mask  = _mm_set_epi32((uint32_t)(mask64 >> 32),(uint32_t)mask64,(uint32_t)(mask64 >> 32),(uint32_t)mask64);\n\n  __m128i offset_rgb = _mm_set_epi32(0, m.offset_rgb, m.offset_rgb, m.offset_rgb); // signed (e.g. -16) if exists, for addition\n\n  BYTE* end_point = srcp + pitch * height;\n\n  while(srcp < end_point) {\n    __m128i src = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp)); // 2x64bit pixels\n\n    __m128i srclo = _mm_unpacklo_epi16(src, zero); // pixel1\n    if(has_offset_rgb)\n      srclo = _mm_add_epi32(srclo, offset_rgb);\n    __m128i mullo = _mm_mullo_epi32(srclo, matrix); // 0, mul_r1, mul_g1, mul_b1 // sse41\n\n    __m128i srchi = _mm_unpackhi_epi16(src, zero); // pixel2\n    if(has_offset_rgb)\n      srchi = _mm_add_epi32(srchi, offset_rgb);\n    __m128i mulhi = _mm_mullo_epi32(srchi, matrix); // 0, mul_r2, mul_g2, mul_b2 // sse41\n\n    __m128i alpha = _mm_and_si128(src, alpha_mask); // put back later\n\n    // ssse3\n    __m128i result = _mm_hadd_epi32(mullo, mulhi);  // 0+mul_r1 | mul_g1+mul_b1 | 0+mul_r2 | mul_g2+mul_b2\n    result = _mm_hadd_epi32(result, zero);  // 0+mul_r1+mul_g1+mul_b1 | 0+mul_r2+mul_g2+mul_b2 | 0 | 0\n\n    result = _mm_add_epi32(result, round_mask_and_luma_offset);\n    result = _mm_srli_epi32(result, 15);\n    // we have the greyscale value of two pixels as int32  0 0 | 0 0 | 0 p1 | 0 p0\n    // we need 0 p1 p1 p1 0 p0 p0 p0\n\n    __m128i result1 = _mm_or_si128(_mm_slli_si128(result, 2), result);\n    // 0 0  | 0 0   | p1 p1 | p0 p0\n    result = _mm_unpacklo_epi32(result1, result);\n    // 0 p1 | p1 p1 | 0  p0 | p0 p0\n\n    result = _mm_or_si128(alpha, result); // put back initial alpha\n\n    _mm_store_si128(reinterpret_cast<__m128i*>(srcp), result);\n\n    srcp += 16;\n  }\n}\n\n#ifdef X86_32\nvoid greyscale_yuy2_mmx(BYTE *srcp, size_t width, size_t height, size_t pitch) {\n  bool not_mod8 = false;\n  size_t loop_limit = min((pitch / 8) * 8, ((width*4 + 7) / 8) * 8);\n\n  __m64 luma_mask = _mm_set1_pi16(0x00FF);\n  __m64 chroma_value = _mm_set1_pi16((short)0x8000);\n\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < loop_limit; x+=8) {\n     __m64 src = *reinterpret_cast<const __m64*>(srcp+x);\n     src = _mm_and_si64(src, luma_mask);\n     src = _mm_or_si64(src, chroma_value);\n     *reinterpret_cast<__m64*>(srcp+x) = src;\n    }\n\n    if (loop_limit < width) {\n      __m64 src = *reinterpret_cast<const __m64*>(srcp+width-8);\n      src = _mm_and_si64(src, luma_mask);\n      src = _mm_or_si64(src, chroma_value);\n      *reinterpret_cast<__m64*>(srcp+width-8) = src;\n    }\n\n    srcp += pitch;\n  }\n _mm_empty();\n}\n\nstatic AVS_FORCEINLINE __m64 greyscale_rgb32_core_mmx(__m64& src, __m64& alpha_mask, __m64& zero, __m64& matrix, __m64& rgb_offset, __m64& round_mask_and_luma_offset, bool has_offset_rgb) {\n  __m64 alpha = _mm_and_si64(src, alpha_mask);\n  __m64 pixel0 = _mm_unpacklo_pi8(src, zero);\n  __m64 pixel1 = _mm_unpackhi_pi8(src, zero);\n\n  if (has_offset_rgb) {\n    pixel0 = _mm_add_pi16(pixel0, rgb_offset); // single pixel 4x16 bit \n    pixel1 = _mm_add_pi16(pixel1, rgb_offset); // single pixel 4x16 bit \n  }\n\n  pixel0 = _mm_madd_pi16(pixel0, matrix); //a0*0 + r0*cyr | g0*cyg + b0*cyb\n  pixel1 = _mm_madd_pi16(pixel1, matrix); //a1*0 + r1*cyr | g1*cyg + b1*cyb\n\n  __m64 tmp = _mm_unpackhi_pi32(pixel0, pixel1); // r1*cyr | r0*cyr\n  __m64 tmp2 = _mm_unpacklo_pi32(pixel0, pixel1); // g1*cyg + b1*cyb | g0*cyg + b0*cyb\n\n  tmp = _mm_add_pi32(tmp, tmp2); // r1*cyr + g1*cyg + b1*cyb | r0*cyr + g0*cyg + b0*cyb\n  tmp = _mm_add_pi32(tmp, round_mask_and_luma_offset); // r1*cyr + g1*cyg + b1*cyb + 32768 | r0*cyr + g0*cyg + b0*cyb + 32768\n  tmp = _mm_srli_pi32(tmp, 15); // 0 0 0 p2 | 0 0 0 p1\n\n  __m64 shifted = _mm_slli_si64(tmp, 8);\n  tmp = _mm_or_si64(tmp, shifted); // 0 0 p2 p2 | 0 0 p1 p1\n  tmp = _mm_or_si64(tmp, _mm_slli_si64(shifted, 8)); // 0 p2 p2 p2 | 0 p1 p1 p1\n  return _mm_or_si64(tmp, alpha);\n}\n\nvoid greyscale_rgb32_mmx(BYTE *srcp, size_t width, size_t height, size_t pitch, ConversionMatrix &m) {\n  const bool has_offset_rgb = 0 != m.offset_rgb;\n\n  __m64 matrix = _mm_set_pi16(0, m.y_r, m.y_g, m.y_b);\n  __m64 zero = _mm_setzero_si64();\n  // .15 frac bit integer arithmetic\n  __m64 round_mask_and_luma_offset = _mm_set1_pi32((1 << 14) + (m.offset_y << 15)); // two pixels at a time\n  __m64 alpha_mask = _mm_set1_pi32(0xFF000000);\n\n  __m64 offset_rgb = _mm_set_pi16(0, m.offset_rgb, m.offset_rgb, m.offset_rgb); // omit alpha. signed (e.g. -16) if exists, for addition\n\n  size_t loop_limit = min((pitch / 8) * 8, ((width*4 + 7) / 8) * 8);\n\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < loop_limit; x+=8) {\n      __m64 src = *reinterpret_cast<const __m64*>(srcp+x); //pixels 0 and 1\n      __m64 result = greyscale_rgb32_core_mmx(src, alpha_mask, zero, matrix, offset_rgb, round_mask_and_luma_offset, has_offset_rgb);\n\n      *reinterpret_cast<__m64*>(srcp+x) = result;\n    }\n\n    if (loop_limit < width) {\n      __m64 src = *reinterpret_cast<const __m64*>(srcp+width-8); //pixels 0 and 1\n      __m64 result = greyscale_rgb32_core_mmx(src, alpha_mask, zero, matrix, offset_rgb, round_mask_and_luma_offset, has_offset_rgb);\n\n      *reinterpret_cast<__m64*>(srcp+width-8) = result;\n    }\n\n    srcp += pitch;\n  }\n  _mm_empty();\n}\n#endif\n\n\n"
  },
  {
    "path": "avs_core/filters/intel/greyscale_sse.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Greyscale_sse_H__\n#define __Greyscale_sse_H__\n\n#include <avisynth.h>\n#include \"../convert/convert_matrix.h\"\n\nvoid greyscale_yuy2_sse2(BYTE *srcp, size_t /*width*/, size_t height, size_t pitch);\nvoid greyscale_rgb32_sse2(BYTE *srcp, size_t /*width*/, size_t height, size_t pitch, ConversionMatrix& m);\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid greyscale_rgb64_sse41(BYTE *srcp, size_t /*width*/, size_t height, size_t pitch, ConversionMatrix& m);\n#ifdef X86_32\nvoid greyscale_rgb32_mmx(BYTE* srcp, size_t width, size_t height, size_t pitch, ConversionMatrix& m);\nvoid greyscale_yuy2_mmx(BYTE *srcp, size_t width, size_t height, size_t pitch);\n#endif\n\n#endif  // __Greyscale_sse_H__\n"
  },
  {
    "path": "avs_core/filters/intel/layer_avx2.cpp",
    "content": "// AviSynth+.  Copyright 2026- AviSynth+ Project\n// https://avs-plus.net\n// http://avisynth.nl\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include \"../layer.h\"\n#include \"layer_avx2.h\"\n\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n#include <immintrin.h>\n\n#include <cstdint>\n\n#include <avs/minmax.h>\n#include <avs/alignment.h>\n#include \"../core/internal.h\"\n\n#include \"../convert/convert_planar.h\"\n#include <algorithm>\n#include <vector>\n\n// Mostly RGB32 stuff, unaligned addresses, pixels grouped by 4\n\nstatic AVS_FORCEINLINE __m128i mask_core_avx2(__m128i& src, __m128i& alpha, __m128i& not_alpha_mask, __m128i& zero, __m128i& matrix, __m128i& round_mask) {\n  __m128i not_alpha = _mm_and_si128(src, not_alpha_mask);\n\n  __m128i pixel0 = _mm_unpacklo_epi8(alpha, zero);\n  __m128i pixel1 = _mm_unpackhi_epi8(alpha, zero);\n\n  pixel0 = _mm_madd_epi16(pixel0, matrix);\n  pixel1 = _mm_madd_epi16(pixel1, matrix);\n\n  __m128i tmp = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(pixel0), _mm_castsi128_ps(pixel1), _MM_SHUFFLE(3, 1, 3, 1)));\n  __m128i tmp2 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(pixel0), _mm_castsi128_ps(pixel1), _MM_SHUFFLE(2, 0, 2, 0)));\n\n  tmp = _mm_add_epi32(tmp, tmp2);\n  tmp = _mm_add_epi32(tmp, round_mask);\n  tmp = _mm_srli_epi32(tmp, 15);\n  __m128i result_alpha = _mm_slli_epi32(tmp, 24);\n\n  return _mm_or_si128(result_alpha, not_alpha);\n}\n\n// called for RGB32\nvoid mask_avx2(BYTE* srcp, const BYTE* alphap, int src_pitch, int alpha_pitch, size_t width, size_t height) {\n  __m128i matrix = _mm_set_epi16(0, cyr, cyg, cyb, 0, cyr, cyg, cyb);\n  __m128i zero = _mm_setzero_si128();\n  __m128i round_mask = _mm_set1_epi32(16384);\n  __m128i not_alpha_mask = _mm_set1_epi32(0x00FFFFFF);\n\n  size_t width_bytes = width * 4;\n  size_t width_mod16 = width_bytes / 16 * 16;\n\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < width_mod16; x += 16) {\n      __m128i src = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x));\n      __m128i alpha = _mm_load_si128(reinterpret_cast<const __m128i*>(alphap + x));\n      __m128i result = mask_core_avx2(src, alpha, not_alpha_mask, zero, matrix, round_mask);\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(srcp + x), result);\n    }\n\n    if (width_mod16 < width_bytes) {\n      __m128i src = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + width_bytes - 16));\n      __m128i alpha = _mm_loadu_si128(reinterpret_cast<const __m128i*>(alphap + width_bytes - 16));\n      __m128i result = mask_core_avx2(src, alpha, not_alpha_mask, zero, matrix, round_mask);\n\n      _mm_storeu_si128(reinterpret_cast<__m128i*>(srcp + width_bytes - 16), result);\n    }\n\n    srcp += src_pitch;\n    alphap += alpha_pitch;\n  }\n}\n\nvoid colorkeymask_avx2(BYTE* pf, int pitch, int color, int height, int width, int tolB, int tolG, int tolR) {\n  unsigned int t = 0xFF000000 | (tolR << 16) | (tolG << 8) | tolB;\n  __m128i tolerance = _mm_set1_epi32(t);\n  __m128i colorv = _mm_set1_epi32(color);\n  __m128i zero = _mm_setzero_si128();\n\n  BYTE* endp = pf + pitch * height;\n\n  while (pf < endp)\n  {\n    __m128i src = _mm_load_si128(reinterpret_cast<const __m128i*>(pf));\n    __m128i gt = _mm_subs_epu8(colorv, src);\n    __m128i lt = _mm_subs_epu8(src, colorv);\n    __m128i absdiff = _mm_or_si128(gt, lt); //abs(color - src)\n\n    __m128i not_passed = _mm_subs_epu8(absdiff, tolerance);\n    __m128i passed = _mm_cmpeq_epi32(not_passed, zero);\n    passed = _mm_slli_epi32(passed, 24);\n    __m128i result = _mm_andnot_si128(passed, src);\n\n    _mm_store_si128(reinterpret_cast<__m128i*>(pf), result);\n\n    pf += 16;\n  }\n}\n\n// by 4 bytes, when rgba mask can be separate FF bytes, for plane FF FF FF FF\n// to simple, even C is identical speed\nvoid invert_frame_inplace_avx2(BYTE* frame, int pitch, int width, int height, int mask) {\n  __m256i maskv = _mm256_set1_epi32(mask);\n\n  BYTE* endp = frame + pitch * height;\n  // geee, no y loop\n  while (frame < endp) {\n    __m256i src = _mm256_load_si256(reinterpret_cast<const __m256i*>(frame));\n    __m256i inv = _mm256_xor_si256(src, maskv);\n    _mm256_store_si256(reinterpret_cast<__m256i*>(frame), inv);\n    frame += 32;\n  }\n}\n\n// to simple, even C is identical speed\nvoid invert_frame_uint16_inplace_avx2(BYTE* frame, int pitch, int width, int height, uint64_t mask64) {\n  __m256i maskv = _mm256_set_epi32(\n    (uint32_t)(mask64 >> 32), (uint32_t)mask64, (uint32_t)(mask64 >> 32), (uint32_t)mask64,\n    (uint32_t)(mask64 >> 32), (uint32_t)mask64, (uint32_t)(mask64 >> 32), (uint32_t)mask64);\n\n  BYTE* endp = frame + pitch * height;\n  // geee, no y loop\n  while (frame < endp) {\n    __m256i src = _mm256_load_si256(reinterpret_cast<const __m256i*>(frame));\n    __m256i inv = _mm256_xor_si256(src, maskv);\n    _mm256_store_si256(reinterpret_cast<__m256i*>(frame), inv);\n    frame += 32;\n  }\n}\n\n// called for uint8_t, uint16_t and float planar, chroma planes are inverted differently than luma plane\n// R G B are treated the same way as luma.\n// We assume full-range.\n// 3.7.6 minor change: chroma: uint8_t, uint16_t: pivot around half and not xor FF/FFFF for chroma\n// Note: this filter is so simple that it is optimized from C to same speed as SIMD in release\n// Also, it is memory-bound AVX2 is not quicker than SSE2.\n// lessthan16bits helps optimizing the exact 16 bit case.\n// We use this very same C source for AVX2, where it is optimized even with 2x256 bit paths\ntemplate<typename pixel_t, bool lessthan16bits, bool chroma>\nvoid invert_plane_c_avx2(uint8_t* dstp, const uint8_t* srcp, int src_pitch, int dst_pitch, int width, int height, int bits_per_pixel) {\n  if constexpr (std::is_same_v<pixel_t, float>) {\n    if constexpr (chroma) {\n      // For chroma planes, invert around 0.0 -> negate\n      for (int y = 0; y < height; ++y) {\n        for (int x = 0; x < width; ++x) {\n          reinterpret_cast<float*>(dstp)[x] = -reinterpret_cast<const float*>(srcp)[x];\n        }\n        srcp += src_pitch;\n        dstp += dst_pitch;\n      }\n    }\n    else {\n      // For luma plane, invert around 1.0 -> 1.0 - value\n      for (int y = 0; y < height; ++y) {\n        for (int x = 0; x < width; ++x) {\n          reinterpret_cast<float*>(dstp)[x] = 1.0f - reinterpret_cast<const float*>(srcp)[x];\n        }\n        srcp += src_pitch;\n        dstp += dst_pitch;\n      }\n    }\n    return;\n  }\n  // 8 bit\n  if constexpr (std::is_same_v<pixel_t, uint8_t>) {\n    constexpr int max_pixel_value = 255;\n    if constexpr (chroma) {\n      constexpr int half = 128;\n      // For chroma planes, invert around 128 -> negate\n      for (int y = 0; y < height; ++y) {\n        for (int x = 0; x < width; ++x) {\n          reinterpret_cast<uint8_t*>(dstp)[x] = std::min(2 * half - reinterpret_cast<const uint8_t*>(srcp)[x], max_pixel_value);\n          // chroma invert: -(srcp[x] - half) + half\n          // = 2*half - srcp[x] = (1 << bits_per_pixel) - srcp[x]\n          // Watch for src==0, must top at max_pixel_value\n        }\n        srcp += src_pitch;\n        dstp += dst_pitch;\n      }\n    }\n    else {\n      // For luma plane, 255-x which is xor 0xff\n      for (int y = 0; y < height; ++y) {\n        for (int x = 0; x < width; ++x) {\n          reinterpret_cast<uint8_t*>(dstp)[x] = max_pixel_value - reinterpret_cast<const uint8_t*>(srcp)[x];\n        }\n        srcp += src_pitch;\n        dstp += dst_pitch;\n      }\n    }\n    return;\n  }\n  // 10-16 bit uint16_t, luma: max_pixel_value - x which is xor with max_pixel_value, chroma: half - x\n  if constexpr (std::is_same_v<pixel_t, uint16_t>) {\n    if constexpr (!lessthan16bits)\n      bits_per_pixel = 16; // quasi constexpr for optimization\n    const int max_pixel_value = (1 << bits_per_pixel) - 1;\n    if constexpr (chroma) {\n      const int half = 1 << (bits_per_pixel - 1);\n      // For chroma planes, invert around mid-point (2^(bits-1))\n      for (int y = 0; y < height; ++y) {\n        for (int x = 0; x < width; ++x) {\n          reinterpret_cast<uint16_t*>(dstp)[x] = std::min(2 * half - reinterpret_cast<const uint16_t*>(srcp)[x], max_pixel_value);\n          // chroma invert: -(srcp[x] - half) + half\n          // = 2*half - srcp[x] = (1 << bits_per_pixel) - srcp[x]\n          // Watch for src==0, must top at max_pixel_value\n        }\n        srcp += src_pitch;\n        dstp += dst_pitch;\n      }\n    }\n    else {\n      // For luma plane, max_pixel_value - x\n      for (int y = 0; y < height; ++y) {\n        for (int x = 0; x < width; ++x) {\n          reinterpret_cast<uint16_t*>(dstp)[x] = max_pixel_value - reinterpret_cast<const uint16_t*>(srcp)[x];\n        }\n        srcp += src_pitch;\n        dstp += dst_pitch;\n      }\n    }\n  }\n}\n\n// Instantiate all AVX2 combinations\ntemplate void invert_plane_c_avx2<uint8_t, true /*n/a*/, false>(uint8_t*, const uint8_t*, int, int, int, int, int);\ntemplate void invert_plane_c_avx2<uint8_t, true /*n/a*/, true>(uint8_t*, const uint8_t*, int, int, int, int, int);\n\ntemplate void invert_plane_c_avx2<uint16_t, true, false>(uint8_t*, const uint8_t*, int, int, int, int, int);\ntemplate void invert_plane_c_avx2<uint16_t, true, true>(uint8_t*, const uint8_t*, int, int, int, int, int);\n\ntemplate void invert_plane_c_avx2<uint16_t, false, false>(uint8_t*, const uint8_t*, int, int, int, int, int);\ntemplate void invert_plane_c_avx2<uint16_t, false, true>(uint8_t*, const uint8_t*, int, int, int, int, int);\n\ntemplate void invert_plane_c_avx2<float, false /*n/a*/, false>(uint8_t*, const uint8_t*, int, int, int, int, int);\ntemplate void invert_plane_c_avx2<float, false /*n/a*/, true>(uint8_t*, const uint8_t*, int, int, int, int, int);\n\n\n/*******************************\n *******   Layer Filter   ******\n *******************************/\n\n // chroma placement to mask helpers\n // yuv add, subtract, mul, lighten, darken\n // included in base and the avx2 source module, to get different optimizations\n#include \"../layer.hpp\"\n\n\n// Wrapper function that calls the local scoped get_layer_yuv_mul_functions\n// This ensures the AVX2-compiled versions of the functions are selected\nvoid get_layer_yuv_mul_functions_avx2(\n  bool is_chroma, bool use_chroma, bool hasAlpha,\n  int placement, VideoInfo& vi, int bits_per_pixel,\n  /*out*/layer_yuv_mul_c_t** layer_fn,\n  /*out*/layer_yuv_mul_f_c_t** layer_f_fn)\n{\n  get_layer_yuv_mul_functions(is_chroma, use_chroma, hasAlpha, placement, vi, bits_per_pixel, layer_fn, layer_f_fn);\n}\n\n// Template wrapper for add/subtract\ntemplate<bool is_subtract>\nvoid get_layer_yuv_add_subtract_functions_avx2(\n  bool is_chroma, bool use_chroma, bool hasAlpha,\n  int placement, VideoInfo& vi, int bits_per_pixel,\n  /*out*/layer_yuv_add_subtract_c_t** layer_fn,\n  /*out*/layer_yuv_add_subtract_f_c_t** layer_f_fn)\n{\n  get_layer_yuv_add_subtract_functions<is_subtract>(is_chroma, use_chroma, hasAlpha, placement, vi, bits_per_pixel, layer_fn, layer_f_fn);\n}\n\n// Explicit template instantiations - forces the linker to generate both versions\ntemplate void get_layer_yuv_add_subtract_functions_avx2<false>(\n  bool is_chroma, bool use_chroma, bool hasAlpha,\n  int placement, VideoInfo& vi, int bits_per_pixel,\n  layer_yuv_add_subtract_c_t** layer_fn,\n  layer_yuv_add_subtract_f_c_t** layer_f_fn);\n\ntemplate void get_layer_yuv_add_subtract_functions_avx2<true>(\n  bool is_chroma, bool use_chroma, bool hasAlpha,\n  int placement, VideoInfo& vi, int bits_per_pixel,\n  layer_yuv_add_subtract_c_t** layer_fn,\n  layer_yuv_add_subtract_f_c_t** layer_f_fn);\n\n\nvoid get_layer_planarrgb_lighten_darken_functions_avx2(bool isLighten, bool hasAlpha, int bits_per_pixel, /*out*/layer_planarrgb_lighten_darken_c_t** layer_fn, /*out*/layer_planarrgb_lighten_darken_f_c_t** layer_f_fn) {\n  get_layer_planarrgb_lighten_darken_functions(isLighten, hasAlpha, bits_per_pixel, layer_fn, layer_f_fn);\n}\n\n\n// In layer_avx2.cpp\ntemplate<bool is_subtract>\nvoid get_layer_planarrgb_add_subtract_functions_avx2(\n  bool chroma, bool hasAlpha, int bits_per_pixel,\n  /*out*/layer_planarrgb_add_subtract_c_t** layer_fn,\n  /*out*/layer_planarrgb_add_subtract_f_c_t** layer_f_fn)\n{\n  get_layer_planarrgb_add_subtract_functions<is_subtract>(chroma, hasAlpha, bits_per_pixel, layer_fn, layer_f_fn);\n}\n\n// Explicit instantiations\ntemplate void get_layer_planarrgb_add_subtract_functions_avx2<false>(\n  bool chroma, bool hasAlpha, int bits_per_pixel,\n  layer_planarrgb_add_subtract_c_t** layer_fn,\n  layer_planarrgb_add_subtract_f_c_t** layer_f_fn);\n\ntemplate void get_layer_planarrgb_add_subtract_functions_avx2<true>(\n  bool chroma, bool hasAlpha, int bits_per_pixel,\n  layer_planarrgb_add_subtract_c_t** layer_fn,\n  layer_planarrgb_add_subtract_f_c_t** layer_f_fn);\n\n\nvoid get_layer_planarrgb_mul_functions_avx2(\n  bool chroma, bool hasAlpha, int bits_per_pixel,\n  /*out*/layer_planarrgb_mul_c_t** layer_fn,\n  /*out*/layer_planarrgb_mul_f_c_t** layer_f_fn)\n{\n  get_layer_planarrgb_mul_functions(chroma, hasAlpha, bits_per_pixel, layer_fn, layer_f_fn);\n}\n\n\n\n\n\n\n// \"fast\" blend is simple averaging\ntemplate<typename pixel_t>\nvoid layer_genericplane_fast_avx2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level) {\n  AVS_UNUSED(level);\n  int width_bytes = width * sizeof(pixel_t);\n  int width_mod32 = width_bytes / 32 * 32;\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width_mod32; x += 32) {\n      __m256i src = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(dstp + x));\n      __m256i ovr = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(ovrp + x));\n      if constexpr (sizeof(pixel_t) == 1)\n        _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + x), _mm256_avg_epu8(src, ovr));\n      else\n        _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + x), _mm256_avg_epu16(src, ovr));\n    }\n\n    for (int x = width_mod32 / sizeof(pixel_t); x < width; ++x) {\n      reinterpret_cast<pixel_t*>(dstp)[x] = (reinterpret_cast<pixel_t*>(dstp)[x] + reinterpret_cast<const pixel_t*>(ovrp)[x] + 1) / 2;\n    }\n\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n  }\n}\n\n// instantiate\ntemplate void layer_genericplane_fast_avx2<uint8_t>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\ntemplate void layer_genericplane_fast_avx2<uint16_t>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\n\n/* RGB32 */\n\n//src format: xx xx xx xx | xx xx xx xx | a1 xx xx xx | a0 xx xx xx\n//level_vector and one should be vectors of 32bit packed integers\nstatic AVS_FORCEINLINE __m128i calculate_monochrome_alpha_avx2(const __m128i& src, const __m128i& level_vector, const __m128i& one) {\n  __m128i alpha = _mm_srli_epi32(src, 24);\n  alpha = _mm_mullo_epi16(alpha, level_vector);\n  alpha = _mm_add_epi32(alpha, one);\n  alpha = _mm_srli_epi32(alpha, 8);\n  alpha = _mm_shufflelo_epi16(alpha, _MM_SHUFFLE(2, 2, 0, 0));\n  return _mm_shuffle_epi32(alpha, _MM_SHUFFLE(1, 1, 0, 0));\n}\n\nstatic AVS_FORCEINLINE __m128i calculate_luma_avx2(const __m128i& src, const __m128i& rgb_coeffs, const __m128i& zero) {\n  AVS_UNUSED(zero);\n  __m128i temp = _mm_madd_epi16(src, rgb_coeffs);\n  __m128i low = _mm_shuffle_epi32(temp, _MM_SHUFFLE(3, 3, 1, 1));\n  temp = _mm_add_epi32(low, temp);\n  temp = _mm_srli_epi32(temp, 15);\n  __m128i result = _mm_shufflelo_epi16(temp, _MM_SHUFFLE(0, 0, 0, 0));\n  return _mm_shufflehi_epi16(result, _MM_SHUFFLE(0, 0, 0, 0));\n}\n\n// must be unaligned load/store\ntemplate<bool use_chroma>\nvoid layer_rgb32_mul_avx2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level) {\n  int mod2_width = width / 2 * 2;\n\n  __m128i zero = _mm_setzero_si128();\n  __m128i level_vector = _mm_set1_epi32(level);\n  __m128i one = _mm_set1_epi32(1);\n  __m128i rgb_coeffs = _mm_set_epi16(0, cyr, cyg, cyb, 0, cyr, cyg, cyb);\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < mod2_width; x += 2) {\n      __m128i src = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(dstp + x * 4));\n      __m128i ovr = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(ovrp + x * 4));\n\n      __m128i alpha = calculate_monochrome_alpha_avx2(ovr, level_vector, one);\n\n      src = _mm_unpacklo_epi8(src, zero);\n      ovr = _mm_unpacklo_epi8(ovr, zero);\n\n      __m128i luma;\n      if (use_chroma) {\n        luma = ovr;\n      }\n      else {\n        luma = calculate_luma_avx2(ovr, rgb_coeffs, zero);\n      }\n\n      __m128i dst = _mm_mullo_epi16(luma, src);\n      dst = _mm_srli_epi16(dst, 8);\n      dst = _mm_subs_epi16(dst, src);\n      dst = _mm_mullo_epi16(dst, alpha);\n      dst = _mm_srli_epi16(dst, 8);\n      dst = _mm_add_epi8(src, dst);\n\n      dst = _mm_packus_epi16(dst, zero);\n\n      _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + x * 4), dst);\n    }\n\n    if (width != mod2_width) {\n      int x = mod2_width;\n      int alpha = (ovrp[x * 4 + 3] * level + 1) >> 8;\n\n      if (use_chroma) {\n        dstp[x * 4] = dstp[x * 4] + (((((ovrp[x * 4] * dstp[x * 4]) >> 8) - dstp[x * 4]) * alpha) >> 8);\n        dstp[x * 4 + 1] = dstp[x * 4 + 1] + (((((ovrp[x * 4 + 1] * dstp[x * 4 + 1]) >> 8) - dstp[x * 4 + 1]) * alpha) >> 8);\n        dstp[x * 4 + 2] = dstp[x * 4 + 2] + (((((ovrp[x * 4 + 2] * dstp[x * 4 + 2]) >> 8) - dstp[x * 4 + 2]) * alpha) >> 8);\n        dstp[x * 4 + 3] = dstp[x * 4 + 3] + (((((ovrp[x * 4 + 3] * dstp[x * 4 + 3]) >> 8) - dstp[x * 4 + 3]) * alpha) >> 8);\n      }\n      else {\n        int luma = (cyb * ovrp[x * 4] + cyg * ovrp[x * 4 + 1] + cyr * ovrp[x * 4 + 2]) >> 15;\n\n        dstp[x * 4] = dstp[x * 4] + (((((luma * dstp[x * 4]) >> 8) - dstp[x * 4]) * alpha) >> 8);\n        dstp[x * 4 + 1] = dstp[x * 4 + 1] + (((((luma * dstp[x * 4 + 1]) >> 8) - dstp[x * 4 + 1]) * alpha) >> 8);\n        dstp[x * 4 + 2] = dstp[x * 4 + 2] + (((((luma * dstp[x * 4 + 2]) >> 8) - dstp[x * 4 + 2]) * alpha) >> 8);\n        dstp[x * 4 + 3] = dstp[x * 4 + 3] + (((((luma * dstp[x * 4 + 3]) >> 8) - dstp[x * 4 + 3]) * alpha) >> 8);\n      }\n    }\n\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n  }\n}\n\n// instantiate\ntemplate void layer_rgb32_mul_avx2<false>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\ntemplate void layer_rgb32_mul_avx2<true>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\n\n\n// must be unaligned load/store\ntemplate<bool use_chroma>\nvoid layer_rgb32_add_avx2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level) {\n  int mod2_width = width / 2 * 2;\n\n  __m128i zero = _mm_setzero_si128();\n  __m128i level_vector = _mm_set1_epi32(level);\n  __m128i one = _mm_set1_epi32(1);\n  __m128i rgb_coeffs = _mm_set_epi16(0, cyr, cyg, cyb, 0, cyr, cyg, cyb);\n\n  constexpr int rounder = 128;\n  const __m128i rounder_simd = _mm_set1_epi16(rounder);\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < mod2_width; x += 2) {\n      __m128i src = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(dstp + x * 4));\n      __m128i ovr = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(ovrp + x * 4));\n\n      __m128i alpha = calculate_monochrome_alpha_avx2(ovr, level_vector, one);\n\n      src = _mm_unpacklo_epi8(src, zero);\n      ovr = _mm_unpacklo_epi8(ovr, zero);\n\n      __m128i luma;\n      if (use_chroma) {\n        luma = ovr;\n      }\n      else {\n        luma = calculate_luma_avx2(ovr, rgb_coeffs, zero);\n      }\n\n      __m128i dst = _mm_subs_epi16(luma, src);\n      dst = _mm_mullo_epi16(dst, alpha);\n      dst = _mm_add_epi16(dst, rounder_simd);\n      dst = _mm_srli_epi16(dst, 8);\n      dst = _mm_add_epi8(src, dst);\n\n      dst = _mm_packus_epi16(dst, zero);\n\n      _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + x * 4), dst);\n    }\n\n    if (width != mod2_width) {\n      int x = mod2_width;\n      int alpha = (ovrp[x * 4 + 3] * level + 1) >> 8;\n\n      if (use_chroma) {\n        dstp[x * 4] = dstp[x * 4] + (((ovrp[x * 4] - dstp[x * 4]) * alpha + rounder) >> 8);\n        dstp[x * 4 + 1] = dstp[x * 4 + 1] + (((ovrp[x * 4 + 1] - dstp[x * 4 + 1]) * alpha + rounder) >> 8);\n        dstp[x * 4 + 2] = dstp[x * 4 + 2] + (((ovrp[x * 4 + 2] - dstp[x * 4 + 2]) * alpha + rounder) >> 8);\n        dstp[x * 4 + 3] = dstp[x * 4 + 3] + (((ovrp[x * 4 + 3] - dstp[x * 4 + 3]) * alpha + rounder) >> 8);\n      }\n      else {\n        int luma = (cyb * ovrp[x * 4] + cyg * ovrp[x * 4 + 1] + cyr * ovrp[x * 4 + 2]) >> 15;\n\n        dstp[x * 4] = dstp[x * 4] + (((luma - dstp[x * 4]) * alpha + rounder) >> 8);\n        dstp[x * 4 + 1] = dstp[x * 4 + 1] + (((luma - dstp[x * 4 + 1]) * alpha + rounder) >> 8);\n        dstp[x * 4 + 2] = dstp[x * 4 + 2] + (((luma - dstp[x * 4 + 2]) * alpha + rounder) >> 8);\n        dstp[x * 4 + 3] = dstp[x * 4 + 3] + (((luma - dstp[x * 4 + 3]) * alpha + rounder) >> 8);\n      }\n    }\n\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n  }\n}\n\n// instantiate\ntemplate void layer_rgb32_add_avx2<false>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\ntemplate void layer_rgb32_add_avx2<true>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\n\n// unlike sse2 alignment is not required. avx2 has no such big penalty\nvoid layer_yuy2_or_rgb32_fast_avx2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level) {\n  AVS_UNUSED(level);\n  int width_bytes = width * 2;\n  int width_mod32 = width_bytes / 32 * 32;\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width_mod32; x += 32) {\n      __m256i src = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(dstp + x));\n      __m256i ovr = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(ovrp + x));\n\n      _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + x), _mm256_avg_epu8(src, ovr));\n    }\n\n    for (int x = width_mod32; x < width_bytes; ++x) {\n      dstp[x] = (dstp[x] + ovrp[x] + 1) / 2;\n    }\n\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n  }\n}\n\n// aligned ptr not required\nvoid layer_rgb32_fast_avx2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level) {\n  layer_yuy2_or_rgb32_fast_avx2(dstp, ovrp, dst_pitch, overlay_pitch, width * 2, height, level);\n}\n\n// unaligned addresses\ntemplate<bool use_chroma>\nvoid layer_rgb32_subtract_avx2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level) {\n  int mod2_width = width / 2 * 2;\n\n  __m128i zero = _mm_setzero_si128();\n  __m128i level_vector = _mm_set1_epi32(level);\n  __m128i one = _mm_set1_epi32(1);\n  __m128i rgb_coeffs = _mm_set_epi16(0, cyr, cyg, cyb, 0, cyr, cyg, cyb);\n  __m128i ff = _mm_set1_epi16(0x00FF);\n\n  constexpr int rounder = 128;\n  const __m128i rounder_simd = _mm_set1_epi16(rounder);\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < mod2_width; x += 2) {\n      __m128i src = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(dstp + x * 4));\n      __m128i ovr = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(ovrp + x * 4));\n\n      __m128i alpha = calculate_monochrome_alpha_avx2(ovr, level_vector, one);\n\n      src = _mm_unpacklo_epi8(src, zero);\n      ovr = _mm_unpacklo_epi8(ovr, zero);\n\n      __m128i luma;\n      if (use_chroma) {\n        luma = _mm_subs_epi16(ff, ovr);\n      }\n      else {\n        luma = calculate_luma_avx2(_mm_andnot_si128(ovr, ff), rgb_coeffs, zero);\n      }\n\n      __m128i dst = _mm_subs_epi16(luma, src);\n      dst = _mm_mullo_epi16(dst, alpha);\n      dst = _mm_add_epi16(dst, rounder_simd);\n      dst = _mm_srli_epi16(dst, 8);\n      dst = _mm_add_epi8(src, dst);\n\n      dst = _mm_packus_epi16(dst, zero);\n\n      _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + x * 4), dst);\n    }\n\n    if (width != mod2_width) {\n      int x = mod2_width;\n      int alpha = (ovrp[x * 4 + 3] * level + 1) >> 8;\n\n      if (use_chroma) {\n        dstp[x * 4] = dstp[x * 4] + (((255 - ovrp[x * 4] - dstp[x * 4]) * alpha + rounder) >> 8);\n        dstp[x * 4 + 1] = dstp[x * 4 + 1] + (((255 - ovrp[x * 4 + 1] - dstp[x * 4 + 1]) * alpha + rounder) >> 8);\n        dstp[x * 4 + 2] = dstp[x * 4 + 2] + (((255 - ovrp[x * 4 + 2] - dstp[x * 4 + 2]) * alpha + rounder) >> 8);\n        dstp[x * 4 + 3] = dstp[x * 4 + 3] + (((255 - ovrp[x * 4 + 3] - dstp[x * 4 + 3]) * alpha + rounder) >> 8);\n      }\n      else {\n        int luma = (cyb * (255 - ovrp[x * 4]) + cyg * (255 - ovrp[x * 4 + 1]) + cyr * (255 - ovrp[x * 4 + 2])) >> 15;\n\n        dstp[x * 4] = dstp[x * 4] + (((luma - dstp[x * 4]) * alpha + rounder) >> 8);\n        dstp[x * 4 + 1] = dstp[x * 4 + 1] + (((luma - dstp[x * 4 + 1]) * alpha + rounder) >> 8);\n        dstp[x * 4 + 2] = dstp[x * 4 + 2] + (((luma - dstp[x * 4 + 2]) * alpha + rounder) >> 8);\n        dstp[x * 4 + 3] = dstp[x * 4 + 3] + (((luma - dstp[x * 4 + 3]) * alpha + rounder) >> 8);\n      }\n    }\n\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n  }\n}\n\n// instantiate\ntemplate void layer_rgb32_subtract_avx2<false>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\ntemplate void layer_rgb32_subtract_avx2<true>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\n\n// unaligned adresses\ntemplate<int mode>\nvoid layer_rgb32_lighten_darken_avx2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level, int thresh) {\n  int mod2_width = width / 2 * 2;\n\n  __m128i zero = _mm_setzero_si128();\n  __m128i level_vector = _mm_set1_epi32(level);\n  __m128i one = _mm_set1_epi32(1);\n  __m128i rgb_coeffs = _mm_set_epi16(0, cyr, cyg, cyb, 0, cyr, cyg, cyb);\n  __m128i threshold = _mm_set1_epi16(thresh);\n\n  constexpr int rounder = 128;\n  const __m128i rounder_simd = _mm_set1_epi16(rounder);\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < mod2_width; x += 2) {\n      __m128i src = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(dstp + x * 4));\n      __m128i ovr = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(ovrp + x * 4));\n\n      __m128i alpha = calculate_monochrome_alpha_avx2(ovr, level_vector, one);\n\n      src = _mm_unpacklo_epi8(src, zero);\n      ovr = _mm_unpacklo_epi8(ovr, zero);\n\n      __m128i luma_ovr = calculate_luma_avx2(ovr, rgb_coeffs, zero);\n      __m128i luma_src = calculate_luma_avx2(src, rgb_coeffs, zero);\n\n      __m128i mask;\n      if constexpr (mode == LIGHTEN) {\n        __m128i tmp = _mm_add_epi16(luma_src, threshold);\n        mask = _mm_cmpgt_epi16(luma_ovr, tmp);\n      }\n      else {\n        __m128i tmp = _mm_sub_epi16(luma_src, threshold);\n        mask = _mm_cmpgt_epi16(tmp, luma_ovr);\n      }\n\n      alpha = _mm_and_si128(alpha, mask);\n\n      __m128i dst = _mm_subs_epi16(ovr, src);\n      dst = _mm_mullo_epi16(dst, alpha);\n      dst = _mm_add_epi16(dst, rounder_simd);\n      dst = _mm_srli_epi16(dst, 8);\n      dst = _mm_add_epi8(src, dst);\n\n      dst = _mm_packus_epi16(dst, zero);\n\n      _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + x * 4), dst);\n    }\n\n    if (width != mod2_width) {\n      int x = mod2_width;\n      int alpha = (ovrp[x * 4 + 3] * level + 1) >> 8;\n      int luma_ovr = (cyb * ovrp[x * 4] + cyg * ovrp[x * 4 + 1] + cyr * ovrp[x * 4 + 2]) >> 15;\n      int luma_src = (cyb * dstp[x * 4] + cyg * dstp[x * 4 + 1] + cyr * dstp[x * 4 + 2]) >> 15;\n\n      if constexpr (mode == LIGHTEN)\n        alpha = luma_ovr > luma_src + thresh ? alpha : 0;\n      else // DARKEN\n        alpha = luma_ovr < luma_src - thresh ? alpha : 0;\n\n      dstp[x * 4] = dstp[x * 4] + (((ovrp[x * 4] - dstp[x * 4]) * alpha + rounder) >> 8);\n      dstp[x * 4 + 1] = dstp[x * 4 + 1] + (((ovrp[x * 4 + 1] - dstp[x * 4 + 1]) * alpha + rounder) >> 8);\n      dstp[x * 4 + 2] = dstp[x * 4 + 2] + (((ovrp[x * 4 + 2] - dstp[x * 4 + 2]) * alpha + rounder) >> 8);\n      dstp[x * 4 + 3] = dstp[x * 4 + 3] + (((ovrp[x * 4 + 3] - dstp[x * 4 + 3]) * alpha + rounder) >> 8);\n    }\n\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n  }\n}\n\n// instantiate\ntemplate void layer_rgb32_lighten_darken_avx2<LIGHTEN>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level, int thresh);\ntemplate void layer_rgb32_lighten_darken_avx2<DARKEN>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level, int thresh);\n\n"
  },
  {
    "path": "avs_core/filters/intel/layer_avx2.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Layer_AVX2_H__\n#define __Layer_AVX2_H__\n\n#include <avisynth.h>\n#include <stdint.h>\n#include \"../layer.h\"\n\nvoid mask_avx2(BYTE* srcp, const BYTE* alphap, int src_pitch, int alpha_pitch, size_t width, size_t height);\nvoid colorkeymask_avx2(BYTE* pf, int pitch, int color, int height, int width, int tolB, int tolG, int tolR);\nvoid invert_frame_inplace_avx2(BYTE* frame, int pitch, int width, int height, int mask);\nvoid invert_frame_uint16_inplace_avx2(BYTE* frame, int pitch, int width, int height, uint64_t mask64);\ntemplate<typename pixel_t, bool lessthan16bits, bool chroma>\nvoid invert_plane_c_avx2(uint8_t* dstp, const uint8_t* srcp, int src_pitch, int dst_pitch, int width, int height, int bits_per_pixel);\n\nvoid layer_yuy2_or_rgb32_fast_avx2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\ntemplate<typename pixel_t>\nvoid layer_genericplane_fast_avx2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\n\ntemplate<bool use_chroma>\nvoid layer_rgb32_mul_avx2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\ntemplate<bool use_chroma>\nvoid layer_rgb32_add_avx2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\nvoid layer_rgb32_fast_avx2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\ntemplate<bool use_chroma>\nvoid layer_rgb32_subtract_avx2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\ntemplate<int mode>\nvoid layer_rgb32_lighten_darken_avx2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level, int thresh);\n\nvoid get_layer_yuv_mul_functions_avx2(\n  bool is_chroma, bool use_chroma, bool hasAlpha,\n  int placement, VideoInfo& vi, int bits_per_pixel,\n  layer_yuv_mul_c_t** layer_fn,\n  layer_yuv_mul_f_c_t** layer_f_fn);\n\ntemplate<bool is_subtract>\nvoid get_layer_yuv_add_subtract_functions_avx2(\n  bool is_chroma, bool use_chroma, bool hasAlpha,\n  int placement, VideoInfo& vi, int bits_per_pixel,\n  layer_yuv_add_subtract_c_t** layer_fn,\n  layer_yuv_add_subtract_f_c_t** layer_f_fn);\n\nvoid get_layer_planarrgb_lighten_darken_functions_avx2(bool isLighten, bool hasAlpha, int bits_per_pixel, /*out*/layer_planarrgb_lighten_darken_c_t** layer_fn, /*out*/layer_planarrgb_lighten_darken_f_c_t** layer_f_fn);\n\ntemplate<bool is_subtract>\nvoid get_layer_planarrgb_add_subtract_functions_avx2(\n  bool chroma, bool hasAlpha, int bits_per_pixel,\n  /*out*/layer_planarrgb_add_subtract_c_t** layer_fn,\n  /*out*/layer_planarrgb_add_subtract_f_c_t** layer_f_fn);\n\nvoid get_layer_planarrgb_mul_functions_avx2(\n  bool chroma, bool hasAlpha, int bits_per_pixel,\n  layer_planarrgb_mul_c_t** layer_fn,\n  layer_planarrgb_mul_f_c_t** layer_f_fn);\n\n#endif  // __Layer_SSE_H__\n"
  },
  {
    "path": "avs_core/filters/intel/layer_sse.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n\n// Avisynth filter: Layer\n// by \"poptones\" (poptones@myrealbox.com)\n\n#include \"layer_sse.h\"\n#include \"../layer.h\"\n\n#ifdef AVS_WINDOWS\n#include <avs/win.h>\n#else\n#include <avs/posix.h>\n#endif\n\n#include <avs/minmax.h>\n#include <avs/alignment.h>\n#include \"../core/internal.h\"\n\n// Intrinsics base header + really required extension headers\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n\n#include \"../convert/convert_planar.h\"\n#include <algorithm>\n\n\nstatic AVS_FORCEINLINE __m128i mask_core_sse2(__m128i& src, __m128i& alpha, __m128i& not_alpha_mask, __m128i& zero, __m128i& matrix, __m128i& round_mask) {\n  __m128i not_alpha = _mm_and_si128(src, not_alpha_mask);\n\n  __m128i pixel0 = _mm_unpacklo_epi8(alpha, zero);\n  __m128i pixel1 = _mm_unpackhi_epi8(alpha, zero);\n\n  pixel0 = _mm_madd_epi16(pixel0, matrix);\n  pixel1 = _mm_madd_epi16(pixel1, matrix);\n\n  __m128i tmp = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(pixel0), _mm_castsi128_ps(pixel1), _MM_SHUFFLE(3, 1, 3, 1)));\n  __m128i tmp2 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(pixel0), _mm_castsi128_ps(pixel1), _MM_SHUFFLE(2, 0, 2, 0)));\n\n  tmp = _mm_add_epi32(tmp, tmp2);\n  tmp = _mm_add_epi32(tmp, round_mask);\n  tmp = _mm_srli_epi32(tmp, 15);\n  __m128i result_alpha = _mm_slli_epi32(tmp, 24);\n\n  return _mm_or_si128(result_alpha, not_alpha);\n}\n\nvoid mask_sse2(BYTE* srcp, const BYTE* alphap, int src_pitch, int alpha_pitch, size_t width, size_t height) {\n  __m128i matrix = _mm_set_epi16(0, cyr, cyg, cyb, 0, cyr, cyg, cyb);\n  __m128i zero = _mm_setzero_si128();\n  __m128i round_mask = _mm_set1_epi32(16384);\n  __m128i not_alpha_mask = _mm_set1_epi32(0x00FFFFFF);\n\n  size_t width_bytes = width * 4;\n  size_t width_mod16 = width_bytes / 16 * 16;\n\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < width_mod16; x += 16) {\n      __m128i src = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x));\n      __m128i alpha = _mm_load_si128(reinterpret_cast<const __m128i*>(alphap + x));\n      __m128i result = mask_core_sse2(src, alpha, not_alpha_mask, zero, matrix, round_mask);\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(srcp + x), result);\n    }\n\n    if (width_mod16 < width_bytes) {\n      __m128i src = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + width_bytes - 16));\n      __m128i alpha = _mm_loadu_si128(reinterpret_cast<const __m128i*>(alphap + width_bytes - 16));\n      __m128i result = mask_core_sse2(src, alpha, not_alpha_mask, zero, matrix, round_mask);\n\n      _mm_storeu_si128(reinterpret_cast<__m128i*>(srcp + width_bytes - 16), result);\n    }\n\n    srcp += src_pitch;\n    alphap += alpha_pitch;\n  }\n}\n\n#ifdef X86_32\n\nstatic AVS_FORCEINLINE __m64 mask_core_mmx(__m64& src, __m64& alpha, __m64& not_alpha_mask, __m64& zero, __m64& matrix, __m64& round_mask) {\n  __m64 not_alpha = _mm_and_si64(src, not_alpha_mask);\n\n  __m64 pixel0 = _mm_unpacklo_pi8(alpha, zero);\n  __m64 pixel1 = _mm_unpackhi_pi8(alpha, zero);\n\n  pixel0 = _mm_madd_pi16(pixel0, matrix); //a0*0 + r0*cyr | g0*cyg + b0*cyb\n  pixel1 = _mm_madd_pi16(pixel1, matrix); //a1*0 + r1*cyr | g1*cyg + b1*cyb\n\n  __m64 tmp = _mm_unpackhi_pi32(pixel0, pixel1); // r1*cyr | r0*cyr\n  __m64 tmp2 = _mm_unpacklo_pi32(pixel0, pixel1); // g1*cyg + b1*cyb | g0*cyg + b0*cyb\n\n  tmp = _mm_add_pi32(tmp, tmp2); // r1*cyr + g1*cyg + b1*cyb | r0*cyr + g0*cyg + b0*cyb\n  tmp = _mm_add_pi32(tmp, round_mask); // r1*cyr + g1*cyg + b1*cyb + 16384 | r0*cyr + g0*cyg + b0*cyb + 16384\n  tmp = _mm_srli_pi32(tmp, 15); // 0 0 0 p2 | 0 0 0 p1\n  __m64 result_alpha = _mm_slli_pi32(tmp, 24);\n\n  return _mm_or_si64(result_alpha, not_alpha);\n}\n\nvoid mask_mmx(BYTE* srcp, const BYTE* alphap, int src_pitch, int alpha_pitch, size_t width, size_t height) {\n  __m64 matrix = _mm_set_pi16(0, cyr, cyg, cyb);\n  __m64 zero = _mm_setzero_si64();\n  __m64 round_mask = _mm_set1_pi32(16384);\n  __m64 not_alpha_mask = _mm_set1_pi32(0x00FFFFFF);\n\n  size_t width_bytes = width * 4;\n  size_t width_mod8 = width_bytes / 8 * 8;\n\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < width_mod8; x += 8) {\n      __m64 src = *reinterpret_cast<const __m64*>(srcp + x); //pixels 0 and 1\n      __m64 alpha = *reinterpret_cast<const __m64*>(alphap + x);\n      __m64 result = mask_core_mmx(src, alpha, not_alpha_mask, zero, matrix, round_mask);\n\n      *reinterpret_cast<__m64*>(srcp + x) = result;\n    }\n\n    if (width_mod8 < width_bytes) {\n      __m64 src = _mm_cvtsi32_si64(*reinterpret_cast<const int*>(srcp + width_bytes - 4));\n      __m64 alpha = _mm_cvtsi32_si64(*reinterpret_cast<const int*>(alphap + width_bytes - 4));\n\n      __m64 result = mask_core_mmx(src, alpha, not_alpha_mask, zero, matrix, round_mask);\n\n      *reinterpret_cast<int*>(srcp + width_bytes - 4) = _mm_cvtsi64_si32(result);\n    }\n\n    srcp += src_pitch;\n    alphap += alpha_pitch;\n  }\n  _mm_empty();\n}\n\n#endif\n\n\n\nvoid colorkeymask_sse2(BYTE* pf, int pitch, int color, int height, int width, int tolB, int tolG, int tolR) {\n  unsigned int t = 0xFF000000 | (tolR << 16) | (tolG << 8) | tolB;\n  __m128i tolerance = _mm_set1_epi32(t);\n  __m128i colorv = _mm_set1_epi32(color);\n  __m128i zero = _mm_setzero_si128();\n\n  BYTE* endp = pf + pitch * height;\n\n  while (pf < endp)\n  {\n    __m128i src = _mm_load_si128(reinterpret_cast<const __m128i*>(pf));\n    __m128i gt = _mm_subs_epu8(colorv, src);\n    __m128i lt = _mm_subs_epu8(src, colorv);\n    __m128i absdiff = _mm_or_si128(gt, lt); //abs(color - src)\n\n    __m128i not_passed = _mm_subs_epu8(absdiff, tolerance);\n    __m128i passed = _mm_cmpeq_epi32(not_passed, zero);\n    passed = _mm_slli_epi32(passed, 24);\n    __m128i result = _mm_andnot_si128(passed, src);\n\n    _mm_store_si128(reinterpret_cast<__m128i*>(pf), result);\n\n    pf += 16;\n  }\n}\n\n#ifdef X86_32\n\nstatic AVS_FORCEINLINE __m64 colorkeymask_core_mmx(const __m64& src, const __m64& colorv, const __m64& tolerance, const __m64& zero) {\n  __m64 gt = _mm_subs_pu8(colorv, src);\n  __m64 lt = _mm_subs_pu8(src, colorv);\n  __m64 absdiff = _mm_or_si64(gt, lt); //abs(color - src)\n\n  __m64 not_passed = _mm_subs_pu8(absdiff, tolerance);\n  __m64 passed = _mm_cmpeq_pi32(not_passed, zero);\n  passed = _mm_slli_pi32(passed, 24);\n  return _mm_andnot_si64(passed, src);\n}\n\nvoid colorkeymask_mmx(BYTE* srcp, int pitch, int color, int height, int width, int tolB, int tolG, int tolR) {\n  __m64 tolerance = _mm_set_pi8((char)0xFF, tolR, tolG, tolB, (char)0xFF, tolR, tolG, tolB);\n  __m64 colorv = _mm_set1_pi32(color);\n  __m64 zero = _mm_setzero_si64();\n\n  int mod8_width = width / 8 * 8;\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < mod8_width; x += 8) {\n      __m64 src = *reinterpret_cast<const __m64*>(srcp + x);\n      __m64 result = colorkeymask_core_mmx(src, colorv, tolerance, zero);\n      *reinterpret_cast<__m64*>(srcp + x) = result;\n    }\n\n    if (mod8_width != width) {\n      __m64 src = _mm_cvtsi32_si64(*reinterpret_cast<const int*>(srcp + width - 4));\n      __m64 result = colorkeymask_core_mmx(src, colorv, tolerance, zero);\n      *reinterpret_cast<int*>(srcp + width - 4) = _mm_cvtsi64_si32(result);\n    }\n\n    srcp += pitch;\n  }\n\n  _mm_empty();\n}\n\n#endif\n\n\nvoid invert_frame_inplace_sse2(BYTE* frame, int pitch, int width, int height, int mask) {\n  __m128i maskv = _mm_set1_epi32(mask);\n\n  BYTE* endp = frame + pitch * height;\n\n  while (frame < endp) {\n    __m128i src = _mm_load_si128(reinterpret_cast<const __m128i*>(frame));\n    __m128i inv = _mm_xor_si128(src, maskv);\n    _mm_store_si128(reinterpret_cast<__m128i*>(frame), inv);\n    frame += 16;\n  }\n}\n\nvoid invert_frame_uint16_inplace_sse2(BYTE* frame, int pitch, int width, int height, uint64_t mask64) {\n  __m128i maskv = _mm_set_epi32((uint32_t)(mask64 >> 32), (uint32_t)mask64, (uint32_t)(mask64 >> 32), (uint32_t)mask64);\n\n  BYTE* endp = frame + pitch * height;\n\n  while (frame < endp) {\n    __m128i src = _mm_load_si128(reinterpret_cast<const __m128i*>(frame));\n    __m128i inv = _mm_xor_si128(src, maskv);\n    _mm_store_si128(reinterpret_cast<__m128i*>(frame), inv);\n    frame += 16;\n  }\n}\n\n/*******************************\n *******   Layer Filter   ******\n *******************************/\n\nvoid layer_yuy2_or_rgb32_fast_sse2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level) {\n  AVS_UNUSED(level);\n  int width_bytes = width * 2;\n  int width_mod16 = width_bytes / 16 * 16;\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width_mod16; x += 16) {\n      __m128i src = _mm_load_si128(reinterpret_cast<const __m128i*>(dstp + x));\n      __m128i ovr = _mm_load_si128(reinterpret_cast<const __m128i*>(ovrp + x));\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x), _mm_avg_epu8(src, ovr));\n    }\n\n    for (int x = width_mod16; x < width_bytes; ++x) {\n      dstp[x] = (dstp[x] + ovrp[x] + 1) / 2;\n    }\n\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n  }\n}\n\n\ntemplate<typename pixel_t>\nvoid layer_genericplane_fast_sse2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level) {\n  AVS_UNUSED(level);\n  int width_bytes = width * sizeof(pixel_t);\n  int width_mod16 = width_bytes / 16 * 16;\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width_mod16; x += 16) {\n      __m128i src = _mm_loadu_si128(reinterpret_cast<const __m128i*>(dstp + x));\n      __m128i ovr = _mm_loadu_si128(reinterpret_cast<const __m128i*>(ovrp + x));\n      if constexpr (sizeof(pixel_t) == 1)\n        _mm_storeu_si128(reinterpret_cast<__m128i*>(dstp + x), _mm_avg_epu8(src, ovr));\n      else\n        _mm_storeu_si128(reinterpret_cast<__m128i*>(dstp + x), _mm_avg_epu16(src, ovr));\n    }\n\n    for (int x = width_mod16 / sizeof(pixel_t); x < width; ++x) {\n      reinterpret_cast<pixel_t*>(dstp)[x] = (reinterpret_cast<pixel_t*>(dstp)[x] + reinterpret_cast<const pixel_t*>(ovrp)[x] + 1) / 2;\n    }\n\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n  }\n}\n\n// instantiate\ntemplate void layer_genericplane_fast_sse2<uint8_t>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\ntemplate void layer_genericplane_fast_sse2<uint16_t>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\n\n/* RGB32 */\n\n//src format: xx xx xx xx | xx xx xx xx | a1 xx xx xx | a0 xx xx xx\n//level_vector and one should be vectors of 32bit packed integers\nstatic AVS_FORCEINLINE __m128i calculate_monochrome_alpha_sse2(const __m128i& src, const __m128i& level_vector, const __m128i& one) {\n  __m128i alpha = _mm_srli_epi32(src, 24);\n  alpha = _mm_mullo_epi16(alpha, level_vector);\n  alpha = _mm_add_epi32(alpha, one);\n  alpha = _mm_srli_epi32(alpha, 8);\n  alpha = _mm_shufflelo_epi16(alpha, _MM_SHUFFLE(2, 2, 0, 0));\n  return _mm_shuffle_epi32(alpha, _MM_SHUFFLE(1, 1, 0, 0));\n}\n\nstatic AVS_FORCEINLINE __m128i calculate_luma_sse2(const __m128i& src, const __m128i& rgb_coeffs, const __m128i& zero) {\n  AVS_UNUSED(zero);\n  __m128i temp = _mm_madd_epi16(src, rgb_coeffs);\n  __m128i low = _mm_shuffle_epi32(temp, _MM_SHUFFLE(3, 3, 1, 1));\n  temp = _mm_add_epi32(low, temp);\n  temp = _mm_srli_epi32(temp, 15);\n  __m128i result = _mm_shufflelo_epi16(temp, _MM_SHUFFLE(0, 0, 0, 0));\n  return _mm_shufflehi_epi16(result, _MM_SHUFFLE(0, 0, 0, 0));\n}\n\n#ifdef X86_32\nstatic AVS_FORCEINLINE __m64 calculate_luma_isse(const __m64& src, const __m64& rgb_coeffs, const __m64& zero) {\n  __m64 temp = _mm_madd_pi16(src, rgb_coeffs);\n  __m64 low = _mm_unpackhi_pi32(temp, zero);\n  temp = _mm_add_pi32(low, temp);\n  temp = _mm_srli_pi32(temp, 15);\n  return _mm_shuffle_pi16(temp, _MM_SHUFFLE(0, 0, 0, 0));\n}\n#endif\n\n// must be unaligned load/store\ntemplate<bool use_chroma>\nvoid layer_rgb32_mul_sse2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level) {\n  int mod2_width = width / 2 * 2;\n\n  __m128i zero = _mm_setzero_si128();\n  __m128i level_vector = _mm_set1_epi32(level);\n  __m128i one = _mm_set1_epi32(1);\n  __m128i rgb_coeffs = _mm_set_epi16(0, cyr, cyg, cyb, 0, cyr, cyg, cyb);\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < mod2_width; x += 2) {\n      __m128i src = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(dstp + x * 4));\n      __m128i ovr = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(ovrp + x * 4));\n\n      __m128i alpha = calculate_monochrome_alpha_sse2(ovr, level_vector, one);\n\n      src = _mm_unpacklo_epi8(src, zero);\n      ovr = _mm_unpacklo_epi8(ovr, zero);\n\n      __m128i luma;\n      if (use_chroma) {\n        luma = ovr;\n      }\n      else {\n        luma = calculate_luma_sse2(ovr, rgb_coeffs, zero);\n      }\n\n      __m128i dst = _mm_mullo_epi16(luma, src);\n      dst = _mm_srli_epi16(dst, 8);\n      dst = _mm_subs_epi16(dst, src);\n      dst = _mm_mullo_epi16(dst, alpha);\n      dst = _mm_srli_epi16(dst, 8);\n      dst = _mm_add_epi8(src, dst);\n\n      dst = _mm_packus_epi16(dst, zero);\n\n      _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + x * 4), dst);\n    }\n\n    if (width != mod2_width) {\n      int x = mod2_width;\n      int alpha = (ovrp[x * 4 + 3] * level + 1) >> 8;\n\n      if (use_chroma) {\n        dstp[x * 4] = dstp[x * 4] + (((((ovrp[x * 4] * dstp[x * 4]) >> 8) - dstp[x * 4]) * alpha) >> 8);\n        dstp[x * 4 + 1] = dstp[x * 4 + 1] + (((((ovrp[x * 4 + 1] * dstp[x * 4 + 1]) >> 8) - dstp[x * 4 + 1]) * alpha) >> 8);\n        dstp[x * 4 + 2] = dstp[x * 4 + 2] + (((((ovrp[x * 4 + 2] * dstp[x * 4 + 2]) >> 8) - dstp[x * 4 + 2]) * alpha) >> 8);\n        dstp[x * 4 + 3] = dstp[x * 4 + 3] + (((((ovrp[x * 4 + 3] * dstp[x * 4 + 3]) >> 8) - dstp[x * 4 + 3]) * alpha) >> 8);\n      }\n      else {\n        int luma = (cyb * ovrp[x * 4] + cyg * ovrp[x * 4 + 1] + cyr * ovrp[x * 4 + 2]) >> 15;\n\n        dstp[x * 4] = dstp[x * 4] + (((((luma * dstp[x * 4]) >> 8) - dstp[x * 4]) * alpha) >> 8);\n        dstp[x * 4 + 1] = dstp[x * 4 + 1] + (((((luma * dstp[x * 4 + 1]) >> 8) - dstp[x * 4 + 1]) * alpha) >> 8);\n        dstp[x * 4 + 2] = dstp[x * 4 + 2] + (((((luma * dstp[x * 4 + 2]) >> 8) - dstp[x * 4 + 2]) * alpha) >> 8);\n        dstp[x * 4 + 3] = dstp[x * 4 + 3] + (((((luma * dstp[x * 4 + 3]) >> 8) - dstp[x * 4 + 3]) * alpha) >> 8);\n      }\n    }\n\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n  }\n}\n\n// instantiate\ntemplate void layer_rgb32_mul_sse2<false>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\ntemplate void layer_rgb32_mul_sse2<true>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\n\n\n#ifdef X86_32\ntemplate<bool use_chroma>\nvoid layer_rgb32_mul_isse(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level) {\n  __m64 zero = _mm_setzero_si64();\n  __m64 rgb_coeffs = _mm_set_pi16(0, cyr, cyg, cyb);\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; ++x) {\n      __m64 src = _mm_cvtsi32_si64(*reinterpret_cast<const int*>(dstp + x * 4));\n      __m64 ovr = _mm_cvtsi32_si64(*reinterpret_cast<const int*>(ovrp + x * 4));\n\n      __m64 alpha = _mm_cvtsi32_si64((ovrp[x * 4 + 3] * level + 1) >> 8);\n      alpha = _mm_shuffle_pi16(alpha, _MM_SHUFFLE(0, 0, 0, 0));\n\n      src = _mm_unpacklo_pi8(src, zero);\n      ovr = _mm_unpacklo_pi8(ovr, zero);\n\n      __m64 luma;\n      if (use_chroma) {\n        luma = ovr;\n      }\n      else {\n        luma = calculate_luma_isse(ovr, rgb_coeffs, zero);\n      }\n\n      __m64 dst = _mm_mullo_pi16(luma, src);\n      dst = _mm_srli_pi16(dst, 8);\n      dst = _mm_subs_pi16(dst, src);\n      dst = _mm_mullo_pi16(dst, alpha);\n      dst = _mm_srli_pi16(dst, 8);\n      dst = _mm_add_pi8(src, dst);\n\n      dst = _mm_packs_pu16(dst, zero);\n\n      *reinterpret_cast<int*>(dstp + x * 4) = _mm_cvtsi64_si32(dst);\n    }\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n  }\n  _mm_empty();\n}\n\n// instantiate\ntemplate void layer_rgb32_mul_isse<false>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\ntemplate void layer_rgb32_mul_isse<true>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\n\n#endif\n\n\n// must be unaligned load/store\ntemplate<bool use_chroma>\nvoid layer_rgb32_add_sse2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level) {\n  int mod2_width = width / 2 * 2;\n\n  __m128i zero = _mm_setzero_si128();\n  __m128i level_vector = _mm_set1_epi32(level);\n  __m128i one = _mm_set1_epi32(1);\n  __m128i rgb_coeffs = _mm_set_epi16(0, cyr, cyg, cyb, 0, cyr, cyg, cyb);\n\n  constexpr int rounder = 128;\n  const __m128i rounder_simd = _mm_set1_epi16(rounder);\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < mod2_width; x += 2) {\n      __m128i src = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(dstp + x * 4));\n      __m128i ovr = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(ovrp + x * 4));\n\n      __m128i alpha = calculate_monochrome_alpha_sse2(ovr, level_vector, one);\n\n      src = _mm_unpacklo_epi8(src, zero);\n      ovr = _mm_unpacklo_epi8(ovr, zero);\n\n      __m128i luma;\n      if (use_chroma) {\n        luma = ovr;\n      }\n      else {\n        luma = calculate_luma_sse2(ovr, rgb_coeffs, zero);\n      }\n\n      __m128i dst = _mm_subs_epi16(luma, src);\n      dst = _mm_mullo_epi16(dst, alpha);\n      dst = _mm_add_epi16(dst, rounder_simd);\n      dst = _mm_srli_epi16(dst, 8);\n      dst = _mm_add_epi8(src, dst);\n\n      dst = _mm_packus_epi16(dst, zero);\n\n      _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + x * 4), dst);\n    }\n\n    if (width != mod2_width) {\n      int x = mod2_width;\n      int alpha = (ovrp[x * 4 + 3] * level + 1) >> 8;\n\n      if (use_chroma) {\n        dstp[x * 4] = dstp[x * 4] + (((ovrp[x * 4] - dstp[x * 4]) * alpha + rounder) >> 8);\n        dstp[x * 4 + 1] = dstp[x * 4 + 1] + (((ovrp[x * 4 + 1] - dstp[x * 4 + 1]) * alpha + rounder) >> 8);\n        dstp[x * 4 + 2] = dstp[x * 4 + 2] + (((ovrp[x * 4 + 2] - dstp[x * 4 + 2]) * alpha + rounder) >> 8);\n        dstp[x * 4 + 3] = dstp[x * 4 + 3] + (((ovrp[x * 4 + 3] - dstp[x * 4 + 3]) * alpha + rounder) >> 8);\n      }\n      else {\n        int luma = (cyb * ovrp[x * 4] + cyg * ovrp[x * 4 + 1] + cyr * ovrp[x * 4 + 2]) >> 15;\n\n        dstp[x * 4] = dstp[x * 4] + (((luma - dstp[x * 4]) * alpha + rounder) >> 8);\n        dstp[x * 4 + 1] = dstp[x * 4 + 1] + (((luma - dstp[x * 4 + 1]) * alpha + rounder) >> 8);\n        dstp[x * 4 + 2] = dstp[x * 4 + 2] + (((luma - dstp[x * 4 + 2]) * alpha + rounder) >> 8);\n        dstp[x * 4 + 3] = dstp[x * 4 + 3] + (((luma - dstp[x * 4 + 3]) * alpha + rounder) >> 8);\n      }\n    }\n\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n  }\n}\n\n// instantiate\ntemplate void layer_rgb32_add_sse2<false>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\ntemplate void layer_rgb32_add_sse2<true>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\n\n#ifdef X86_32\ntemplate<bool use_chroma>\nvoid layer_rgb32_add_isse(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level) {\n  __m64 zero = _mm_setzero_si64();\n  __m64 rgb_coeffs = _mm_set_pi16(0, cyr, cyg, cyb);\n\n  constexpr int rounder = 128;\n  const __m64 rounder_simd = _mm_set1_pi16(rounder);\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; ++x) {\n      __m64 src = _mm_cvtsi32_si64(*reinterpret_cast<const int*>(dstp + x * 4));\n      __m64 ovr = _mm_cvtsi32_si64(*reinterpret_cast<const int*>(ovrp + x * 4));\n\n      __m64 alpha = _mm_cvtsi32_si64((ovrp[x * 4 + 3] * level + 1) >> 8);\n      alpha = _mm_shuffle_pi16(alpha, _MM_SHUFFLE(0, 0, 0, 0));\n\n      src = _mm_unpacklo_pi8(src, zero);\n      ovr = _mm_unpacklo_pi8(ovr, zero);\n\n      __m64 luma;\n      if (use_chroma) {\n        luma = ovr;\n      }\n      else {\n        luma = calculate_luma_isse(ovr, rgb_coeffs, zero);\n      }\n\n      __m64 dst = _mm_subs_pi16(luma, src);\n      dst = _mm_mullo_pi16(dst, alpha);\n      dst = _mm_add_pi16(dst, rounder_simd);\n      dst = _mm_srli_pi16(dst, 8);\n      dst = _mm_add_pi8(src, dst);\n\n      dst = _mm_packs_pu16(dst, zero);\n\n      *reinterpret_cast<int*>(dstp + x * 4) = _mm_cvtsi64_si32(dst);\n    }\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n  }\n  _mm_empty();\n}\n\n// instantiate\ntemplate void layer_rgb32_add_isse<false>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\ntemplate void layer_rgb32_add_isse<true>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\n#endif\n\n\n\nvoid layer_rgb32_fast_sse2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level) {\n  layer_yuy2_or_rgb32_fast_sse2(dstp, ovrp, dst_pitch, overlay_pitch, width * 2, height, level);\n}\n\n\ntemplate<bool use_chroma>\nvoid layer_rgb32_subtract_sse2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level) {\n  int mod2_width = width / 2 * 2;\n\n  __m128i zero = _mm_setzero_si128();\n  __m128i level_vector = _mm_set1_epi32(level);\n  __m128i one = _mm_set1_epi32(1);\n  __m128i rgb_coeffs = _mm_set_epi16(0, cyr, cyg, cyb, 0, cyr, cyg, cyb);\n  __m128i ff = _mm_set1_epi16(0x00FF);\n\n  constexpr int rounder = 128;\n  const __m128i rounder_simd = _mm_set1_epi16(rounder);\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < mod2_width; x += 2) {\n      __m128i src = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(dstp + x * 4));\n      __m128i ovr = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(ovrp + x * 4));\n\n      __m128i alpha = calculate_monochrome_alpha_sse2(ovr, level_vector, one);\n\n      src = _mm_unpacklo_epi8(src, zero);\n      ovr = _mm_unpacklo_epi8(ovr, zero);\n\n      __m128i luma;\n      if (use_chroma) {\n        luma = _mm_subs_epi16(ff, ovr);\n      }\n      else {\n        luma = calculate_luma_sse2(_mm_andnot_si128(ovr, ff), rgb_coeffs, zero);\n      }\n\n      __m128i dst = _mm_subs_epi16(luma, src);\n      dst = _mm_mullo_epi16(dst, alpha);\n      dst = _mm_add_epi16(dst, rounder_simd);\n      dst = _mm_srli_epi16(dst, 8);\n      dst = _mm_add_epi8(src, dst);\n\n      dst = _mm_packus_epi16(dst, zero);\n\n      _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + x * 4), dst);\n    }\n\n    if (width != mod2_width) {\n      int x = mod2_width;\n      int alpha = (ovrp[x * 4 + 3] * level + 1) >> 8;\n\n      if (use_chroma) {\n        dstp[x * 4] = dstp[x * 4] + (((255 - ovrp[x * 4] - dstp[x * 4]) * alpha + rounder) >> 8);\n        dstp[x * 4 + 1] = dstp[x * 4 + 1] + (((255 - ovrp[x * 4 + 1] - dstp[x * 4 + 1]) * alpha + rounder) >> 8);\n        dstp[x * 4 + 2] = dstp[x * 4 + 2] + (((255 - ovrp[x * 4 + 2] - dstp[x * 4 + 2]) * alpha + rounder) >> 8);\n        dstp[x * 4 + 3] = dstp[x * 4 + 3] + (((255 - ovrp[x * 4 + 3] - dstp[x * 4 + 3]) * alpha + rounder) >> 8);\n      }\n      else {\n        int luma = (cyb * (255 - ovrp[x * 4]) + cyg * (255 - ovrp[x * 4 + 1]) + cyr * (255 - ovrp[x * 4 + 2])) >> 15;\n\n        dstp[x * 4] = dstp[x * 4] + (((luma - dstp[x * 4]) * alpha + rounder) >> 8);\n        dstp[x * 4 + 1] = dstp[x * 4 + 1] + (((luma - dstp[x * 4 + 1]) * alpha + rounder) >> 8);\n        dstp[x * 4 + 2] = dstp[x * 4 + 2] + (((luma - dstp[x * 4 + 2]) * alpha + rounder) >> 8);\n        dstp[x * 4 + 3] = dstp[x * 4 + 3] + (((luma - dstp[x * 4 + 3]) * alpha + rounder) >> 8);\n      }\n    }\n\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n  }\n}\n\n// instantiate\ntemplate void layer_rgb32_subtract_sse2<false>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\ntemplate void layer_rgb32_subtract_sse2<true>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\n\n#ifdef X86_32\ntemplate<bool use_chroma>\nvoid layer_rgb32_subtract_isse(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level) {\n  __m64 zero = _mm_setzero_si64();\n  __m64 rgb_coeffs = _mm_set_pi16(0, cyr, cyg, cyb);\n  __m64 ff = _mm_set1_pi16(0x00FF);\n\n  constexpr int rounder = 128;\n  const __m64 rounder_simd = _mm_set1_pi16(rounder);\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; ++x) {\n      __m64 src = _mm_cvtsi32_si64(*reinterpret_cast<const int*>(dstp + x * 4));\n      __m64 ovr = _mm_cvtsi32_si64(*reinterpret_cast<const int*>(ovrp + x * 4));\n\n      __m64 alpha = _mm_cvtsi32_si64((ovrp[x * 4 + 3] * level + 1) >> 8);\n      alpha = _mm_shuffle_pi16(alpha, _MM_SHUFFLE(0, 0, 0, 0));\n\n      src = _mm_unpacklo_pi8(src, zero);\n      ovr = _mm_unpacklo_pi8(ovr, zero);\n\n      __m64 luma;\n      if (use_chroma) {\n        luma = _mm_subs_pi16(ff, ovr);\n      }\n      else {\n        luma = calculate_luma_isse(_mm_andnot_si64(ovr, ff), rgb_coeffs, zero);\n      }\n\n      __m64 dst = _mm_subs_pi16(luma, src);\n      dst = _mm_mullo_pi16(dst, alpha);\n      dst = _mm_add_pi16(dst, rounder_simd);\n      dst = _mm_srli_pi16(dst, 8);\n      dst = _mm_add_pi8(src, dst);\n\n      dst = _mm_packs_pu16(dst, zero);\n\n      *reinterpret_cast<int*>(dstp + x * 4) = _mm_cvtsi64_si32(dst);\n    }\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n  }\n  _mm_empty();\n}\n\n// instantiate\ntemplate void layer_rgb32_subtract_isse<false>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\ntemplate void layer_rgb32_subtract_isse<true>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\n\n#endif\n\n\n\ntemplate<int mode>\nvoid layer_rgb32_lighten_darken_sse2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level, int thresh) {\n  int mod2_width = width / 2 * 2;\n\n  __m128i zero = _mm_setzero_si128();\n  __m128i level_vector = _mm_set1_epi32(level);\n  __m128i one = _mm_set1_epi32(1);\n  __m128i rgb_coeffs = _mm_set_epi16(0, cyr, cyg, cyb, 0, cyr, cyg, cyb);\n  __m128i threshold = _mm_set1_epi16(thresh);\n\n  constexpr int rounder = 128;\n  const __m128i rounder_simd = _mm_set1_epi16(rounder);\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < mod2_width; x += 2) {\n      __m128i src = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(dstp + x * 4));\n      __m128i ovr = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(ovrp + x * 4));\n\n      __m128i alpha = calculate_monochrome_alpha_sse2(ovr, level_vector, one);\n\n      src = _mm_unpacklo_epi8(src, zero);\n      ovr = _mm_unpacklo_epi8(ovr, zero);\n\n      __m128i luma_ovr = calculate_luma_sse2(ovr, rgb_coeffs, zero);\n      __m128i luma_src = calculate_luma_sse2(src, rgb_coeffs, zero);\n\n      __m128i mask;\n      if constexpr (mode == LIGHTEN) {\n        __m128i tmp = _mm_add_epi16(luma_src, threshold);\n        mask = _mm_cmpgt_epi16(luma_ovr, tmp);\n      }\n      else {\n        __m128i tmp = _mm_sub_epi16(luma_src, threshold);\n        mask = _mm_cmpgt_epi16(tmp, luma_ovr);\n      }\n\n      alpha = _mm_and_si128(alpha, mask);\n\n      __m128i dst = _mm_subs_epi16(ovr, src);\n      dst = _mm_mullo_epi16(dst, alpha);\n      dst = _mm_add_epi16(dst, rounder_simd);\n      dst = _mm_srli_epi16(dst, 8);\n      dst = _mm_add_epi8(src, dst);\n\n      dst = _mm_packus_epi16(dst, zero);\n\n      _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + x * 4), dst);\n    }\n\n    if (width != mod2_width) {\n      int x = mod2_width;\n      int alpha = (ovrp[x * 4 + 3] * level + 1) >> 8;\n      int luma_ovr = (cyb * ovrp[x * 4] + cyg * ovrp[x * 4 + 1] + cyr * ovrp[x * 4 + 2]) >> 15;\n      int luma_src = (cyb * dstp[x * 4] + cyg * dstp[x * 4 + 1] + cyr * dstp[x * 4 + 2]) >> 15;\n\n      if constexpr (mode == LIGHTEN)\n        alpha = luma_ovr > luma_src + thresh ? alpha : 0;\n      else // DARKEN\n        alpha = luma_ovr < luma_src - thresh ? alpha : 0;\n\n      dstp[x * 4] = dstp[x * 4] + (((ovrp[x * 4] - dstp[x * 4]) * alpha + rounder) >> 8);\n      dstp[x * 4 + 1] = dstp[x * 4 + 1] + (((ovrp[x * 4 + 1] - dstp[x * 4 + 1]) * alpha + rounder) >> 8);\n      dstp[x * 4 + 2] = dstp[x * 4 + 2] + (((ovrp[x * 4 + 2] - dstp[x * 4 + 2]) * alpha + rounder) >> 8);\n      dstp[x * 4 + 3] = dstp[x * 4 + 3] + (((ovrp[x * 4 + 3] - dstp[x * 4 + 3]) * alpha + rounder) >> 8);\n    }\n\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n  }\n}\n\n// instantiate\ntemplate void layer_rgb32_lighten_darken_sse2<LIGHTEN>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level, int thresh);\ntemplate void layer_rgb32_lighten_darken_sse2<DARKEN>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level, int thresh);\n\n#ifdef X86_32\ntemplate<int mode>\nvoid layer_rgb32_lighten_darken_isse(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level, int thresh) {\n  __m64 zero = _mm_setzero_si64();\n  __m64 rgb_coeffs = _mm_set_pi16(0, cyr, cyg, cyb);\n  __m64 threshold = _mm_set1_pi16(thresh);\n\n  constexpr int rounder = 128;\n  const __m64 rounder_simd = _mm_set1_pi16(rounder);\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; ++x) {\n      __m64 src = _mm_cvtsi32_si64(*reinterpret_cast<const int*>(dstp + x * 4));\n      __m64 ovr = _mm_cvtsi32_si64(*reinterpret_cast<const int*>(ovrp + x * 4));\n\n      __m64 alpha = _mm_cvtsi32_si64((ovrp[x * 4 + 3] * level + 1) >> 8);\n      alpha = _mm_shuffle_pi16(alpha, _MM_SHUFFLE(0, 0, 0, 0));\n\n      src = _mm_unpacklo_pi8(src, zero);\n      ovr = _mm_unpacklo_pi8(ovr, zero);\n\n      __m64 luma_ovr = calculate_luma_isse(ovr, rgb_coeffs, zero);\n      __m64 luma_src = calculate_luma_isse(src, rgb_coeffs, zero);\n\n      /*\n      if constexpr (mode == LIGHTEN)\n        alpha = luma_ovr > luma_src + thresh ? alpha : 0;\n      else // DARKEN\n        alpha = luma_ovr < luma_src - thresh ? alpha : 0;\n      */\n\n      __m64 mask;\n      if (mode == LIGHTEN) {\n        __m64 tmp = _mm_add_pi16(luma_src, threshold);\n        mask = _mm_cmpgt_pi16(luma_ovr, tmp);\n      }\n      else {\n        __m64 tmp = _mm_sub_pi16(luma_src, threshold);\n        mask = _mm_cmpgt_pi16(tmp, luma_ovr);\n      }\n\n      alpha = _mm_and_si64(alpha, mask);\n\n      __m64 dst = _mm_subs_pi16(ovr, src);\n      dst = _mm_mullo_pi16(dst, alpha);\n      dst = _mm_add_pi16(dst, rounder_simd);\n      dst = _mm_srli_pi16(dst, 8);\n      dst = _mm_add_pi8(src, dst);\n\n      dst = _mm_packs_pu16(dst, zero);\n\n      *reinterpret_cast<int*>(dstp + x * 4) = _mm_cvtsi64_si32(dst);\n    }\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n  }\n  _mm_empty();\n}\n\n// instantiate\ntemplate void layer_rgb32_lighten_darken_isse<LIGHTEN>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level, int thresh);\ntemplate void layer_rgb32_lighten_darken_isse<DARKEN>(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level, int thresh);\n\n#endif\n\n"
  },
  {
    "path": "avs_core/filters/intel/layer_sse.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Layer_SSE_H__\n#define __Layer_SSE_H__\n\n#include <avisynth.h>\n#include <stdint.h>\n\nvoid mask_sse2(BYTE* srcp, const BYTE* alphap, int src_pitch, int alpha_pitch, size_t width, size_t height);\nvoid colorkeymask_sse2(BYTE* pf, int pitch, int color, int height, int width, int tolB, int tolG, int tolR);\nvoid invert_frame_inplace_sse2(BYTE* frame, int pitch, int width, int height, int mask);\nvoid invert_frame_uint16_inplace_sse2(BYTE* frame, int pitch, int width, int height, uint64_t mask64);\ntemplate<bool use_chroma>\nvoid layer_yuy2_or_rgb32_fast_sse2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\ntemplate<typename pixel_t>\nvoid layer_genericplane_fast_sse2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\ntemplate<bool use_chroma>\nvoid layer_rgb32_mul_sse2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\ntemplate<bool use_chroma>\nvoid layer_rgb32_add_sse2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\nvoid layer_rgb32_fast_sse2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\ntemplate<bool use_chroma>\nvoid layer_rgb32_subtract_sse2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\ntemplate<int mode>\nvoid layer_rgb32_lighten_darken_sse2(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level, int thresh);\n\n#ifdef X86_32 \nvoid mask_mmx(BYTE* srcp, const BYTE* alphap, int src_pitch, int alpha_pitch, size_t width, size_t height);\nvoid colorkeymask_mmx(BYTE* srcp, int pitch, int color, int height, int width, int tolB, int tolG, int tolR);\ntemplate<bool use_chroma>\nvoid layer_rgb32_mul_isse(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\ntemplate<bool use_chroma>\nvoid layer_rgb32_add_isse(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\ntemplate<bool use_chroma>\nvoid layer_rgb32_subtract_isse(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level);\ntemplate<int mode>\nvoid layer_rgb32_lighten_darken_isse(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level, int thresh);\n\n#endif\n\n#endif  // __Layer_SSE_H__\n"
  },
  {
    "path": "avs_core/filters/intel/limiter_sse.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include \"limiter_sse.h\"\n\n// Intrinsics base header + really required extension headers\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n#include <smmintrin.h> // SSE4.1\n\n#include \"../core/internal.h\"\n\n//min and max values are 16-bit integers either max_plane|max_plane for planar or max_luma|max_chroma for yuy2\nvoid limit_plane_sse2(BYTE *ptr, int min_value, int max_value, int pitch, int width, int height) {\n  __m128i min_vector = _mm_set1_epi16(min_value);\n  __m128i max_vector = _mm_set1_epi16(max_value);\n  BYTE* end_point = ptr + pitch * height;\n\n  while(ptr < end_point) {\n    __m128i src = _mm_load_si128(reinterpret_cast<const __m128i*>(ptr));\n    src = _mm_max_epu8(src, min_vector);\n    src = _mm_min_epu8(src, max_vector);\n    _mm_store_si128(reinterpret_cast<__m128i*>(ptr), src);\n    ptr += 16;\n  }\n}\n\n//min and max values are 16-bit unsigned integers\nvoid limit_plane_uint16_sse2(BYTE *ptr, unsigned int min_value, unsigned int max_value, int pitch, int height) {\n  __m128i min_vector = _mm_set1_epi16(min_value);\n  __m128i max_vector = _mm_set1_epi16(max_value);\n  BYTE* end_point = ptr + pitch * height;\n\n  while(ptr < end_point) {\n    __m128i src = _mm_load_si128(reinterpret_cast<const __m128i*>(ptr));\n    src = _MM_MAX_EPU16(src, min_vector);\n    src = _MM_MIN_EPU16(src, max_vector);\n    _mm_store_si128(reinterpret_cast<__m128i*>(ptr), src);\n    ptr += 16;\n  }\n}\n\n//min and max values are 16-bit unsigned integers\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid limit_plane_uint16_sse4(BYTE *ptr, unsigned int min_value, unsigned int max_value, int pitch, int height)\n{\n  __m128i min_vector = _mm_set1_epi16(min_value);\n  __m128i max_vector = _mm_set1_epi16(max_value);\n  BYTE* end_point = ptr + pitch * height;\n\n  while(ptr < end_point) {\n    __m128i src = _mm_load_si128(reinterpret_cast<const __m128i*>(ptr));\n    src = _mm_max_epu16(src, min_vector);\n    src = _mm_min_epu16(src, max_vector);\n    _mm_store_si128(reinterpret_cast<__m128i*>(ptr), src);\n    ptr += 16;\n  }\n}\n\n\n#ifdef X86_32\n\n//min and max values are 16-bit integers either max_plane|max_plane for planar or max_luma|max_chroma for yuy2\nvoid limit_plane_isse(BYTE *ptr, int min_value, int max_value, int pitch, int width, int height) {\n  __m64 min_vector = _mm_set1_pi16(min_value);\n  __m64 max_vector = _mm_set1_pi16(max_value);\n  int mod8_width = width / 8 * 8;\n\n  for(int y = 0; y < height; y++) {\n    for(int x = 0; x < mod8_width; x+=8) {\n      __m64 src = *reinterpret_cast<__m64*>(ptr+x);\n      src = _mm_max_pu8(src, min_vector);\n      src = _mm_min_pu8(src, max_vector);\n      *reinterpret_cast<__m64*>(ptr+x) = src;\n    }\n\n    if (mod8_width != width) {\n      int x = width - 8;\n      __m64 src = *reinterpret_cast<__m64*>(ptr+x);\n      src = _mm_max_pu8(src, min_vector);\n      src = _mm_min_pu8(src, max_vector);\n      *reinterpret_cast<__m64*>(ptr+x) = src;\n    }\n\n    ptr += pitch;\n  }\n  _mm_empty();\n}\n\n#endif\n\n\n\n"
  },
  {
    "path": "avs_core/filters/intel/limiter_sse.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Limiter_SSE_H__\n#define __Limiter_SSE_H__\n\n#include <avisynth.h>\n\nvoid limit_plane_sse2(BYTE *ptr, int min_value, int max_value, int pitch, int width, int height);\nvoid limit_plane_uint16_sse2(BYTE *ptr, unsigned int min_value, unsigned int max_value, int pitch, int height);\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid limit_plane_uint16_sse4(BYTE *ptr, unsigned int min_value, unsigned int max_value, int pitch, int height);\n#ifdef X86_32\nvoid limit_plane_isse(BYTE *ptr, int min_value, int max_value, int pitch, int width, int height);\n#endif\n\n#endif  // __Limiter_SSE_H__\n"
  },
  {
    "path": "avs_core/filters/intel/merge_avx2.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n// Avisynth filter: YUV merge / Swap planes\n// by Klaus Post (kp@interact.dk)\n// adapted by Richard Berg (avisynth-dev@richardberg.net)\n// iSSE code by Ian Brabham\n\n\n// Intrinsics base header + really required extension headers\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n#include <immintrin.h>\n\n\n#if !defined(__FMA__)\n// Assume that all processors that have AVX2 also have FMA3\n#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__)\n// Prevent error message in g++ when using FMA intrinsics with avx2:\n#pragma message \"It is recommended to specify also option -mfma when using -mavx2 or higher\"\n#else\n#define __FMA__  1\n#endif\n#endif\n// FMA3 instruction set\n#if defined(__FMA__) && (defined(__GNUC__) || defined(__clang__))  && !defined(__INTEL_COMPILER)\n#include <fmaintrin.h>\n#endif // __FMA__\n\n#include \"merge_avx2.h\"\n#include <avisynth.h>\n#include <avs/types.h>\n#include <cstdint>\n\n#ifndef _mm256_set_m128i\n#define _mm256_set_m128i(v0, v1) _mm256_insertf128_si256(_mm256_castsi128_si256(v1), (v0), 1)\n#endif\n\n#ifndef _mm256_set_m128\n#define _mm256_set_m128(v0, v1) _mm256_insertf128_ps(_mm256_castps128_ps256(v1), (v0), 1)\n#endif\n\n/* -----------------------------------\n *            average_plane\n * -----------------------------------\n */\n#define AVX2BUG_WORKAROUND\n// VS2017 15.5.1..2 optimizer generates illegal instructions for vmovntdqa\n// just a note, to be removed\ntemplate<typename pixel_t>\nvoid average_plane_avx2(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height) {\n  // width is RowSize here\n  int mod32_width = rowsize / 32 * 32;\n  int mod16_width = rowsize / 16 * 16;\n\n  for(int y = 0; y < height; y++) {\n    for(int x = 0; x < mod32_width; x+=32) {\n#ifdef AVX2BUG_WORKAROUND\n      __m256i src1 = _mm256_load_si256(reinterpret_cast<__m256i*>(p1 + x));\n#else\n      __m256i src1  = _mm256_stream_load_si256(reinterpret_cast<__m256i*>(p1+x));\n#endif\n      /*\n      00070\t8d 40 20\t lea\t eax, DWORD PTR [eax+32]\n\n      ; 70   :       __m256i src1  = _mm256_stream_load_si256(reinterpret_cast<__m256i*>(p1+x));\n\n      00073\tc5 fe 6f 40 e0\t vmovdqu ymm0, YMMWORD PTR [eax-32]\n      00078\tc4 e2 7d 2a c8\t vmovntdqa ymm1, ymm0            ****CRASH HERE! ILLEGAL INSTRUCTION VS15.5.1!!!****\n\n      ; 71   :       __m256i src2  = _mm256_stream_load_si256(const_cast<__m256i*>(reinterpret_cast<const __m256i*>(p2+x)));\n\n      0007d\tc5 fe 6f 44 02 e0\t\t vmovdqu ymm0, YMMWORD PTR [edx+eax-32]\n      00083\tc4 e2 7d 2a c0\t vmovntdqa ymm0, ymm0\n\n      */\n#ifdef AVX2BUG_WORKAROUND\n      __m256i src2  = _mm256_load_si256(const_cast<__m256i*>(reinterpret_cast<const __m256i*>(p2+x)));\n      #else\n      __m256i src2 = _mm256_stream_load_si256(const_cast<__m256i*>(reinterpret_cast<const __m256i*>(p2 + x)));\n      #endif\n      __m256i dst;\n      if constexpr(sizeof(pixel_t) == 1)\n        dst  = _mm256_avg_epu8(src1, src2); // 16 pixels\n      else // pixel_size == 2\n        dst = _mm256_avg_epu16(src1, src2); // 8 pixels\n\n      _mm256_store_si256(reinterpret_cast<__m256i*>(p1+x), dst);\n    }\n\n    for(int x = mod32_width; x < mod16_width; x+=16) {\n#ifdef AVX2BUG_WORKAROUND\n      __m128i src1 = _mm_load_si128(reinterpret_cast<__m128i*>(p1 + x));\n      __m128i src2 = _mm_load_si128(const_cast<__m128i*>(reinterpret_cast<const __m128i*>(p2 + x)));\n#else\n      __m128i src1  = _mm_stream_load_si128(reinterpret_cast<__m128i*>(p1+x));\n      __m128i src2  = _mm_stream_load_si128(const_cast<__m128i*>(reinterpret_cast<const __m128i*>(p2+x)));\n#endif\n      __m128i dst;\n      if constexpr(sizeof(pixel_t) == 1)\n        dst  = _mm_avg_epu8(src1, src2); // 8 pixels\n      else // pixel_size == 2\n        dst = _mm_avg_epu16(src1, src2); // 4 pixels\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(p1+x), dst);\n    }\n\n    if (mod16_width != rowsize) {\n      for (size_t x = mod16_width / sizeof(pixel_t); x < rowsize/sizeof(pixel_t); ++x) {\n        reinterpret_cast<pixel_t *>(p1)[x] = (int(reinterpret_cast<pixel_t *>(p1)[x]) + reinterpret_cast<const pixel_t *>(p2)[x] + 1) >> 1;\n      }\n    }\n    p1 += p1_pitch;\n    p2 += p2_pitch;\n  }\n}\n\n// instantiate to let them access from other modules\ntemplate void average_plane_avx2<uint8_t>(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height);\ntemplate void average_plane_avx2<uint16_t>(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height);\n\n\n/* -----------------------------------\n*       weighted_merge_planar\n* -----------------------------------\n*/\ntemplate<bool lessthan16bit>\nvoid weighted_merge_planar_uint16_avx2(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height, float weight_f, int weight_i, int invweight_i) {\n  AVS_UNUSED(weight_f);\n  __m128i mask_128 = _mm_set1_epi32( (weight_i << 16) + invweight_i);\n  __m256i mask = _mm256_set1_epi32((weight_i << 16) + invweight_i);\n\n  const __m128i signed_shifter_128 = _mm_set1_epi16(-32768);\n  const __m256i signed_shifter = _mm256_set1_epi16(-32768);\n\n  auto round_mask = _mm256_set1_epi32(0x4000);\n\n  auto round_mask_128 = _mm_set1_epi32(0x4000);\n\n  int wMod32 = (rowsize / 32) * 32;\n  int wMod16 = (rowsize / 16) * 16;\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wMod32; x += 32) {\n      __m256i px1, px2;\n      px1 = _mm256_load_si256(reinterpret_cast<const __m256i*>(p1 + x)); // y7 y6 y5 y4 y3 y2 y1 y0\n      px2 = _mm256_load_si256(reinterpret_cast<const __m256i*>(p2 + x)); // Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0\n\n      if constexpr (!lessthan16bit) {\n        px1 = _mm256_add_epi16(px1, signed_shifter);\n        px2 = _mm256_add_epi16(px2, signed_shifter);\n      }\n\n      auto p03 = _mm256_unpacklo_epi16(px1, px2); // Y11y11 Y10y10 Y9y9 Y8y8 Y3y3 Y2y2 Y1y1 Y0y0\n      auto p47 = _mm256_unpackhi_epi16(px1, px2); // Yy15-12 Yy7-4\n\n      p03 = _mm256_madd_epi16(p03, mask); // px1 * invweight + px2 * weight\n      p47 = _mm256_madd_epi16(p47, mask);\n\n      p03 = _mm256_add_epi32(p03, round_mask);\n      p47 = _mm256_add_epi32(p47, round_mask);\n\n      p03 = _mm256_srai_epi32(p03, 15);\n      p47 = _mm256_srai_epi32(p47, 15);\n\n      auto p07 = _mm256_packs_epi32(p03, p47);\n      if constexpr (!lessthan16bit) {\n        p07 = _mm256_add_epi16(p07, signed_shifter);\n      }\n\n      auto result = p07;\n      _mm256_store_si256(reinterpret_cast<__m256i*>(p1 + x), result);\n    }\n\n    for (int x = wMod32; x < wMod16; x += 16) {\n      __m128i px1, px2;\n      px1 = _mm_load_si128(reinterpret_cast<__m128i*>(p1 + x)); // y7 y6 y5 y4 y3 y2 y1 y0\n      px2 = _mm_load_si128(const_cast<__m128i*>(reinterpret_cast<const __m128i*>(p2 + x))); // Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0\n      if constexpr (!lessthan16bit) {\n        px1 = _mm_add_epi16(px1, signed_shifter_128);\n        px2 = _mm_add_epi16(px2, signed_shifter_128);\n      }\n\n      auto p03 = _mm_unpacklo_epi16(px1, px2); // Y11y11 Y10y10 Y9y9 Y8y8 Y3y3 Y2y2 Y1y1 Y0y0\n      auto p47 = _mm_unpackhi_epi16(px1, px2); // Yy15-12 Yy7-4\n\n      p03 = _mm_madd_epi16(p03, mask_128); // px1 * invweight + px2 * weight\n      p47 = _mm_madd_epi16(p47, mask_128);\n\n      p03 = _mm_add_epi32(p03, round_mask_128);\n      p47 = _mm_add_epi32(p47, round_mask_128);\n\n      p03 = _mm_srai_epi32(p03, 15);\n      p47 = _mm_srai_epi32(p47, 15);\n\n      auto p07 = _mm_packs_epi32(p03, p47);\n      if constexpr (!lessthan16bit) {\n        p07 = _mm_add_epi16(p07, signed_shifter_128);\n      }\n\n      auto result = p07;\n      _mm_stream_si128(reinterpret_cast<__m128i*>(p1 + x), result);\n    }\n\n    for (size_t x = wMod16 / sizeof(uint16_t); x < rowsize / sizeof(uint16_t); x++) {\n      reinterpret_cast<uint16_t *>(p1)[x] = (reinterpret_cast<uint16_t *>(p1)[x] * invweight_i + reinterpret_cast<const uint16_t *>(p2)[x] * weight_i + 16384) >> 15;\n    }\n\n    p1 += p1_pitch;\n    p2 += p2_pitch;\n  }\n}\n\n// instantiate to let them access from other modules\ntemplate void weighted_merge_planar_uint16_avx2<false>(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height, float weight_f, int weight_i, int invweight_i);\ntemplate void weighted_merge_planar_uint16_avx2<true>(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height, float weight_f, int weight_i, int invweight_i);\n\n\nvoid weighted_merge_planar_avx2(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height, float weight_f, int weight_i, int invweight_i) {\n  AVS_UNUSED(weight_f);\n  auto round_mask = _mm256_set1_epi32(0x4000);\n  auto zero = _mm256_setzero_si256();\n  auto mask = _mm256_set_epi16(weight_i, invweight_i, weight_i, invweight_i, weight_i, invweight_i, weight_i, invweight_i, weight_i, invweight_i, weight_i, invweight_i, weight_i, invweight_i, weight_i, invweight_i);\n\n  auto round_mask_128 = _mm_set1_epi32(0x4000);\n  auto zero_128 = _mm_setzero_si128();\n  auto mask_128 = _mm_set_epi16(weight_i, invweight_i, weight_i, invweight_i, weight_i, invweight_i, weight_i, invweight_i);\n\n  int wMod32 = (rowsize / 32) * 32;\n  int wMod16 = (rowsize / 16) * 16;\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wMod32; x += 32) {\n      auto px1 = _mm256_load_si256(reinterpret_cast<const __m256i*>(p1 + x)); // y15y14 ... y7y6 y5y4 y3y2 y1y0\n      auto px2 = _mm256_load_si256(reinterpret_cast<const __m256i*>(p2 + x)); // Y15Y14 ... Y7Y6 Y5Y4 Y3Y2 Y1Y0\n\n      auto p07 = _mm256_unpacklo_epi8(px1, px2); // Y7y7 ..  Y3y3   Y2y2  Y1y1 Y0y0\n      auto p815 = _mm256_unpackhi_epi8(px1, px2); //Y15y15 ..Y11y11 Y10y10 Y9y9 Y8y8\n\n      auto p03 = _mm256_unpacklo_epi8(p07, zero);  //00Y3 00y3 00Y2 00y2 00Y1 00y1 00Y0 00y0 8*short\n      auto p47 = _mm256_unpackhi_epi8(p07, zero);\n      auto p811 = _mm256_unpacklo_epi8(p815, zero);\n      auto p1215 = _mm256_unpackhi_epi8(p815, zero);\n\n      p03 = _mm256_madd_epi16(p03, mask);\n      p47 = _mm256_madd_epi16(p47, mask);\n      p811 = _mm256_madd_epi16(p811, mask);\n      p1215 = _mm256_madd_epi16(p1215, mask);\n\n      p03 = _mm256_add_epi32(p03, round_mask);\n      p47 = _mm256_add_epi32(p47, round_mask);\n      p811 = _mm256_add_epi32(p811, round_mask);\n      p1215 = _mm256_add_epi32(p1215, round_mask);\n\n      p03 = _mm256_srli_epi32(p03, 15);\n      p47 = _mm256_srli_epi32(p47, 15);\n      p811 = _mm256_srli_epi32(p811, 15);\n      p1215 = _mm256_srli_epi32(p1215, 15);\n\n      p07 = _mm256_packs_epi32(p03, p47);\n      p815 = _mm256_packs_epi32(p811, p1215);\n\n      __m256i result = _mm256_packus_epi16(p07, p815);\n\n      _mm256_store_si256(reinterpret_cast<__m256i*>(p1 + x), result);\n    }\n\n    for (int x = wMod32; x < wMod16; x += 16) {\n      __m128i px1 = _mm_load_si128(reinterpret_cast<const __m128i*>(p1 + x)); // y15y14 ... y7y6 y5y4 y3y2 y1y0\n      __m128i px2 = _mm_load_si128(reinterpret_cast<const __m128i*>(p2 + x)); // Y15Y14 ... Y7Y6 Y5Y4 Y3Y2 Y1Y0\n\n      __m128i p07 = _mm_unpacklo_epi8(px1, px2); // Y7y7 ..  Y3y3   Y2y2  Y1y1 Y0y0\n      __m128i p815 = _mm_unpackhi_epi8(px1, px2); //Y15y15 ..Y11y11 Y10y10 Y9y9 Y8y8\n\n      __m128i p03 = _mm_unpacklo_epi8(p07, zero_128);  //00Y3 00y3 00Y2 00y2 00Y1 00y1 00Y0 00y0 8*short\n      __m128i p47 = _mm_unpackhi_epi8(p07, zero_128);\n      __m128i p811 = _mm_unpacklo_epi8(p815, zero_128);\n      __m128i p1215 = _mm_unpackhi_epi8(p815, zero_128);\n\n      p03 = _mm_madd_epi16(p03, mask_128);\n      p47 = _mm_madd_epi16(p47, mask_128);\n      p811 = _mm_madd_epi16(p811, mask_128);\n      p1215 = _mm_madd_epi16(p1215, mask_128);\n\n      p03 = _mm_add_epi32(p03, round_mask_128);\n      p47 = _mm_add_epi32(p47, round_mask_128);\n      p811 = _mm_add_epi32(p811, round_mask_128);\n      p1215 = _mm_add_epi32(p1215, round_mask_128);\n\n      p03 = _mm_srli_epi32(p03, 15);\n      p47 = _mm_srli_epi32(p47, 15);\n      p811 = _mm_srli_epi32(p811, 15);\n      p1215 = _mm_srli_epi32(p1215, 15);\n\n      p07 = _mm_packs_epi32(p03, p47);\n      p815 = _mm_packs_epi32(p811, p1215);\n\n      __m128i result = _mm_packus_epi16(p07, p815);\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(p1 + x), result);\n    }\n\n    for (size_t x = wMod16 / sizeof(uint8_t); x < rowsize / sizeof(uint8_t); x++) {\n      reinterpret_cast<uint8_t *>(p1)[x] = (reinterpret_cast<uint8_t *>(p1)[x] * invweight_i + reinterpret_cast<const uint8_t *>(p2)[x] * weight_i + 16384) >> 15;\n    }\n\n    p1 += p1_pitch;\n    p2 += p2_pitch;\n  }\n}\n"
  },
  {
    "path": "avs_core/filters/intel/merge_avx2.h",
    "content": "#ifndef __Merge_AVX2_H__\n#define __Merge_AVX2_H__\n\n#include <avs/types.h>\n\ntemplate<typename pixel_t>\nvoid average_plane_avx2(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height);\n\ntemplate<bool lessthan16bit>\nvoid weighted_merge_planar_uint16_avx2(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int width, int height, float weight_f, int weight_i, int invweight_i);\nvoid weighted_merge_planar_avx2(BYTE *p1,const BYTE *p2, int p1_pitch, int p2_pitch,int rowsize, int height, float weight_f, int weight_i, int invweight_i);\n\n#endif  // __MergeAVX2_H__\n"
  },
  {
    "path": "avs_core/filters/intel/merge_sse.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n// Avisynth filter: YUV merge / Swap planes\n// by Klaus Post (kp@interact.dk)\n// adapted by Richard Berg (avisynth-dev@richardberg.net)\n// iSSE code by Ian Brabham\n\n\n#include \"../merge.h\"\n#include \"merge_sse.h\"\n#include \"merge_avx2.h\"\n#include \"../core/internal.h\"\n\n// Intrinsics base header + really required extension headers\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n\n#include \"avs/alignment.h\"\n#include <stdint.h>\n\n\n/* -----------------------------------\n *     weighted_merge_chroma_yuy2\n * -----------------------------------\n */\nvoid weighted_merge_chroma_yuy2_sse2(BYTE *src, const BYTE *chroma, int pitch, int chroma_pitch,int width, int height, int weight, int invweight )\n{\n  __m128i round_mask = _mm_set1_epi32(0x4000);\n  __m128i mask = _mm_set_epi16(weight, invweight, weight, invweight, weight, invweight, weight, invweight);\n  __m128i luma_mask = _mm_set1_epi16(0x00FF);\n\n  int wMod16 = (width/16) * 16;\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wMod16; x += 16) {\n      __m128i px1 = _mm_load_si128(reinterpret_cast<const __m128i*>(src+x));\n      __m128i px2 = _mm_load_si128(reinterpret_cast<const __m128i*>(chroma+x));\n\n      __m128i src_lo = _mm_unpacklo_epi16(px1, px2);\n      __m128i src_hi = _mm_unpackhi_epi16(px1, px2);\n\n      src_lo = _mm_srli_epi16(src_lo, 8);\n      src_hi = _mm_srli_epi16(src_hi, 8);\n\n      src_lo = _mm_madd_epi16(src_lo, mask);\n      src_hi = _mm_madd_epi16(src_hi, mask);\n\n      src_lo = _mm_add_epi32(src_lo, round_mask);\n      src_hi = _mm_add_epi32(src_hi, round_mask);\n\n      src_lo = _mm_srli_epi32(src_lo, 15);\n      src_hi = _mm_srli_epi32(src_hi, 15);\n\n      __m128i result_chroma = _mm_packs_epi32(src_lo, src_hi);\n      result_chroma = _mm_slli_epi16(result_chroma, 8);\n\n      __m128i result_luma = _mm_and_si128(px1, luma_mask);\n      __m128i result = _mm_or_si128(result_chroma, result_luma);\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(src+x), result);\n    }\n\n    for (int x = wMod16; x < width; x+=2) {\n      src[x+1] = (chroma[x+1] * weight + src[x+1] * invweight + 16384) >> 15;\n    }\n\n    src += pitch;\n    chroma += chroma_pitch;\n  }\n}\n\n#ifdef X86_32\nvoid weighted_merge_chroma_yuy2_mmx(BYTE *src, const BYTE *chroma, int pitch, int chroma_pitch,int width, int height, int weight, int invweight )\n{\n  __m64 round_mask = _mm_set1_pi32(0x4000);\n  __m64 mask = _mm_set_pi16(weight, invweight, weight, invweight);\n  __m64 luma_mask = _mm_set1_pi16(0x00FF);\n\n  int wMod8 = (width/8) * 8;\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wMod8; x += 8) {\n      __m64 px1 = *reinterpret_cast<const __m64*>(src+x); //V1 Y3 U1 Y2 V0 Y1 U0 Y0\n      __m64 px2 = *reinterpret_cast<const __m64*>(chroma+x); //v1 y3 u1 y2 v0 y1 u0 y0\n\n      __m64 src_lo = _mm_unpacklo_pi16(px1, px2); //v0 y1 V0 Y1 u0 y0 U0 Y0\n      __m64 src_hi = _mm_unpackhi_pi16(px1, px2);\n\n      src_lo = _mm_srli_pi16(src_lo, 8); //00 v0 00 V0 00 u0 00 U0\n      src_hi = _mm_srli_pi16(src_hi, 8);\n\n      src_lo = _mm_madd_pi16(src_lo, mask);\n      src_hi = _mm_madd_pi16(src_hi, mask);\n\n      src_lo = _mm_add_pi32(src_lo, round_mask);\n      src_hi = _mm_add_pi32(src_hi, round_mask);\n\n      src_lo = _mm_srli_pi32(src_lo, 15);\n      src_hi = _mm_srli_pi32(src_hi, 15);\n\n      __m64 result_chroma = _mm_packs_pi32(src_lo, src_hi);\n      result_chroma = _mm_slli_pi16(result_chroma, 8);\n\n      __m64 result_luma = _mm_and_si64(px1, luma_mask);\n      __m64 result = _mm_or_si64(result_chroma, result_luma);\n\n      *reinterpret_cast<__m64*>(src+x) = result;\n    }\n\n    for (int x = wMod8; x < width; x+=2) {\n      src[x+1] = (chroma[x+1] * weight + src[x+1] * invweight + 16384) >> 15;\n    }\n\n    src += pitch;\n    chroma += chroma_pitch;\n  }\n  _mm_empty();\n}\n#endif\n\n\n\n/* -----------------------------------\n *      weighted_merge_luma_yuy2\n * -----------------------------------\n */\nvoid weighted_merge_luma_yuy2_sse2(BYTE *src, const BYTE *luma, int pitch, int luma_pitch,int width, int height, int weight, int invweight)\n{\n  __m128i round_mask = _mm_set1_epi32(0x4000);\n  __m128i mask = _mm_set_epi16(weight, invweight, weight, invweight, weight, invweight, weight, invweight);\n  __m128i luma_mask = _mm_set1_epi16(0x00FF);\n  __m128i chroma_mask = _mm_set1_epi16((short)0xFF00);\n\n  int wMod16 = (width/16) * 16;\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wMod16; x += 16) {\n      __m128i px1 = _mm_load_si128(reinterpret_cast<const __m128i*>(src+x)); //V1 Y3 U1 Y2 V0 Y1 U0 Y0\n      __m128i px2 = _mm_load_si128(reinterpret_cast<const __m128i*>(luma+x)); //v1 y3 u1 y2 v0 y1 u0 y0\n\n      __m128i src_lo = _mm_unpacklo_epi16(px1, px2); //v0 y1 V0 Y1 u0 y0 U0 Y0\n      __m128i src_hi = _mm_unpackhi_epi16(px1, px2);\n\n      src_lo = _mm_and_si128(src_lo, luma_mask); //00 v0 00 V0 00 u0 00 U0\n      src_hi = _mm_and_si128(src_hi, luma_mask);\n\n      src_lo = _mm_madd_epi16(src_lo, mask);\n      src_hi = _mm_madd_epi16(src_hi, mask);\n\n      src_lo = _mm_add_epi32(src_lo, round_mask);\n      src_hi = _mm_add_epi32(src_hi, round_mask);\n\n      src_lo = _mm_srli_epi32(src_lo, 15);\n      src_hi = _mm_srli_epi32(src_hi, 15);\n\n      __m128i result_luma = _mm_packs_epi32(src_lo, src_hi);\n\n      __m128i result_chroma = _mm_and_si128(px1, chroma_mask);\n      __m128i result = _mm_or_si128(result_chroma, result_luma);\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(src+x), result);\n    }\n\n    for (int x = wMod16; x < width; x+=2) {\n      src[x] = (luma[x] * weight + src[x] * invweight + 16384) >> 15;\n    }\n\n    src += pitch;\n    luma += luma_pitch;\n  }\n}\n\n#ifdef X86_32\nvoid weighted_merge_luma_yuy2_mmx(BYTE *src, const BYTE *luma, int pitch, int luma_pitch,int width, int height, int weight, int invweight)\n{\n  __m64 round_mask = _mm_set1_pi32(0x4000);\n  __m64 mask = _mm_set_pi16(weight, invweight, weight, invweight);\n  __m64 luma_mask = _mm_set1_pi16(0x00FF);\n  __m64 chroma_mask = _mm_set1_pi16((short)0xFF00);\n\n  int wMod8 = (width/8) * 8;\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wMod8; x += 8) {\n      __m64 px1 = *reinterpret_cast<const __m64*>(src+x); //V1 Y3 U1 Y2 V0 Y1 U0 Y0\n      __m64 px2 = *reinterpret_cast<const __m64*>(luma+x); //v1 y3 u1 y2 v0 y1 u0 y0\n\n      __m64 src_lo = _mm_unpacklo_pi16(px1, px2); //v0 y1 V0 Y1 u0 y0 U0 Y0\n      __m64 src_hi = _mm_unpackhi_pi16(px1, px2);\n\n      src_lo = _mm_and_si64(src_lo, luma_mask); //00 v0 00 V0 00 u0 00 U0\n      src_hi = _mm_and_si64(src_hi, luma_mask);\n\n      src_lo = _mm_madd_pi16(src_lo, mask);\n      src_hi = _mm_madd_pi16(src_hi, mask);\n\n      src_lo = _mm_add_pi32(src_lo, round_mask);\n      src_hi = _mm_add_pi32(src_hi, round_mask);\n\n      src_lo = _mm_srli_pi32(src_lo, 15);\n      src_hi = _mm_srli_pi32(src_hi, 15);\n\n      __m64 result_luma = _mm_packs_pi32(src_lo, src_hi);\n\n      __m64 result_chroma = _mm_and_si64(px1, chroma_mask);\n      __m64 result = _mm_or_si64(result_chroma, result_luma);\n\n      *reinterpret_cast<__m64*>(src+x) = result;\n    }\n\n    for (int x = wMod8; x < width; x+=2) {\n      src[x] = (luma[x] * weight + src[x] * invweight + 16384) >> 15;\n    }\n\n    src += pitch;\n    luma += luma_pitch;\n  }\n  _mm_empty();\n}\n#endif\n\n\n/* -----------------------------------\n *          replace_luma_yuy2\n * -----------------------------------\n */\nvoid replace_luma_yuy2_sse2(BYTE *src, const BYTE *luma, int pitch, int luma_pitch,int width, int height)\n{\n  int mod16_width = width / 16 * 16;\n  __m128i luma_mask = _mm_set1_epi16(0x00FF);\n  __m128i chroma_mask = _mm_set1_epi16((short)0xFF00);\n\n  for(int y = 0; y < height; y++) {\n    for(int x = 0; x < mod16_width; x+=16) {\n      __m128i s = _mm_load_si128(reinterpret_cast<const __m128i*>(src+x));\n      __m128i l = _mm_load_si128(reinterpret_cast<const __m128i*>(luma+x));\n\n      __m128i s_chroma = _mm_and_si128(s, chroma_mask);\n      __m128i l_luma = _mm_and_si128(l, luma_mask);\n\n      __m128i result = _mm_or_si128(s_chroma, l_luma);\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(src+x), result);\n    }\n\n    for (int x = mod16_width; x < width; x+=2) {\n      src[x] = luma[x];\n    }\n    src += pitch;\n    luma += luma_pitch;\n  }\n}\n\n#ifdef X86_32\nvoid replace_luma_yuy2_mmx(BYTE *src, const BYTE *luma, int pitch, int luma_pitch,int width, int height)\n{\n  int mod8_width = width / 8 * 8;\n  __m64 luma_mask = _mm_set1_pi16(0x00FF);\n  __m64 chroma_mask = _mm_set1_pi16((short)0xFF00);\n\n  for(int y = 0; y < height; y++) {\n    for(int x = 0; x < mod8_width; x+=8) {\n      __m64 s = *reinterpret_cast<const __m64*>(src+x);\n      __m64 l = *reinterpret_cast<const __m64*>(luma+x);\n\n      __m64 s_chroma = _mm_and_si64(s, chroma_mask);\n      __m64 l_luma = _mm_and_si64(l, luma_mask);\n\n      __m64 result = _mm_or_si64(s_chroma, l_luma);\n\n      *reinterpret_cast<__m64*>(src+x) = result;\n    }\n\n    for (int x = mod8_width; x < width; x+=2) {\n      src[x] = luma[x];\n    }\n    src += pitch;\n    luma += luma_pitch;\n  }\n  _mm_empty();\n}\n#endif\n\n\n\n/* -----------------------------------\n *            average_plane\n * -----------------------------------\n */\ntemplate<typename pixel_t>\nvoid average_plane_sse2(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height) {\n  // width is RowSize here\n  int mod16_width = rowsize / 16 * 16;\n\n  for(int y = 0; y < height; y++) {\n    for(int x = 0; x < mod16_width; x+=16) {\n      __m128i src1  = _mm_load_si128(reinterpret_cast<const __m128i*>(p1+x));\n      __m128i src2  = _mm_load_si128(reinterpret_cast<const __m128i*>(p2+x));\n      __m128i dst;\n      if constexpr(sizeof(pixel_t) == 1)\n        dst  = _mm_avg_epu8(src1, src2); // 8 pixels\n      else // pixel_size == 2\n        dst = _mm_avg_epu16(src1, src2); // 4 pixels\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(p1+x), dst);\n    }\n\n    if (mod16_width != rowsize) {\n      for (size_t x = mod16_width / sizeof(pixel_t); x < rowsize/sizeof(pixel_t); ++x) {\n        reinterpret_cast<pixel_t *>(p1)[x] = (int(reinterpret_cast<pixel_t *>(p1)[x]) + reinterpret_cast<const pixel_t *>(p2)[x] + 1) >> 1;\n      }\n    }\n    p1 += p1_pitch;\n    p2 += p2_pitch;\n  }\n}\n\n// instantiate\ntemplate void average_plane_sse2<uint8_t>(BYTE* p1, const BYTE* p2, int p1_pitch, int p2_pitch, int rowsize, int height);\ntemplate void average_plane_sse2<uint16_t>(BYTE* p1, const BYTE* p2, int p1_pitch, int p2_pitch, int rowsize, int height);\n\n#ifdef X86_32\ntemplate<typename pixel_t>\nvoid average_plane_isse(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height) {\n  // width is RowSize here\n  int mod8_width = rowsize / 8 * 8;\n\n  for(int y = 0; y < height; y++) {\n    for(int x = 0; x < mod8_width; x+=8) {\n      __m64 src1 = *reinterpret_cast<const __m64*>(p1+x);\n      __m64 src2 = *reinterpret_cast<const __m64*>(p2+x);\n      __m64 dst;\n      if constexpr(sizeof(pixel_t) == 1)\n        dst = _mm_avg_pu8(src1, src2);  // 8 pixels\n      else // pixel_size == 2\n        dst = _mm_avg_pu16(src1, src2); // 4 pixels\n      *reinterpret_cast<__m64*>(p1+x) = dst;\n    }\n\n    if (mod8_width != rowsize) {\n      for (size_t x = mod8_width / sizeof(pixel_t); x < rowsize / sizeof(pixel_t); ++x) {\n        reinterpret_cast<pixel_t *>(p1)[x] = (int(reinterpret_cast<pixel_t *>(p1)[x]) + reinterpret_cast<const pixel_t *>(p2)[x] + 1) >> 1;\n      }\n    }\n    p1 += p1_pitch;\n    p2 += p2_pitch;\n  }\n  _mm_empty();\n}\n\ntemplate void average_plane_isse<uint8_t>(BYTE* p1, const BYTE* p2, int p1_pitch, int p2_pitch, int rowsize, int height);\ntemplate void average_plane_isse<uint16_t>(BYTE* p1, const BYTE* p2, int p1_pitch, int p2_pitch, int rowsize, int height);\n\n#endif\n\n\n\n/* -----------------------------------\n *       weighted_merge_planar\n * -----------------------------------\n */\n\ntemplate<bool lessthan16bit>\nvoid weighted_merge_planar_uint16_sse2(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height, float weight_f, int weight_i, int invweight_i) {\n  AVS_UNUSED(weight_f);\n  __m128i round_mask = _mm_set1_epi32(0x4000);\n  __m128i mask = _mm_set1_epi32((weight_i << 16) + invweight_i);\n\n  int wMod16 = (rowsize / 16) * 16;\n  const __m128i signed_shifter = _mm_set1_epi16(-32768);\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wMod16; x += 16) {\n      __m128i px1 = _mm_load_si128(reinterpret_cast<const __m128i*>(p1 + x)); // y7y6 y5y4 y3y2 y1y0\n      __m128i px2 = _mm_load_si128(reinterpret_cast<const __m128i*>(p2 + x)); // Y7Y6 Y5Y4 Y3Y2 Y1Y0\n\n      if constexpr (!lessthan16bit) {\n        px1 = _mm_add_epi16(px1, signed_shifter);\n        px2 = _mm_add_epi16(px2, signed_shifter);\n      }\n\n      __m128i p03 = _mm_unpacklo_epi16(px1, px2); // Y3y3 Y2y2 Y1y1 Y0y0\n      __m128i p47 = _mm_unpackhi_epi16(px1, px2); // Y7y7 Y6y6 Y5y5 Y4y4\n\n      p03 = _mm_madd_epi16(p03, mask); // px1 * invweight + px2 * weight\n      p47 = _mm_madd_epi16(p47, mask);\n\n      p03 = _mm_add_epi32(p03, round_mask);\n      p47 = _mm_add_epi32(p47, round_mask);\n\n      p03 = _mm_srai_epi32(p03, 15);\n      p47 = _mm_srai_epi32(p47, 15);\n\n      auto p07 = _mm_packs_epi32(p03, p47);\n      if constexpr (!lessthan16bit) {\n        p07 = _mm_add_epi16(p07, signed_shifter);\n      }\n\n      __m128i result = p07;\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(p1 + x), result);\n    }\n\n    for (size_t x = wMod16 / sizeof(uint16_t); x < rowsize / sizeof(uint16_t); x++) {\n      reinterpret_cast<uint16_t *>(p1)[x] = (reinterpret_cast<uint16_t *>(p1)[x] * invweight_i + reinterpret_cast<const uint16_t *>(p2)[x] * weight_i + 16384) >> 15;\n    }\n\n    p1 += p1_pitch;\n    p2 += p2_pitch;\n  }\n}\n\n// instantiate\ntemplate void weighted_merge_planar_uint16_sse2<false>(BYTE* p1, const BYTE* p2, int p1_pitch, int p2_pitch, int rowsize, int height, float weight_f, int weight_i, int invweight_i);\ntemplate void weighted_merge_planar_uint16_sse2<true>(BYTE* p1, const BYTE* p2, int p1_pitch, int p2_pitch, int rowsize, int height, float weight_f, int weight_i, int invweight_i);\n\n\nvoid weighted_merge_planar_sse2(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height, float weight_f, int weight_i, int invweight_i) {\n  AVS_UNUSED(weight_f);\n  // 8 bit only. SSE2 has weak support for unsigned 16 bit\n  __m128i round_mask = _mm_set1_epi32(0x4000);\n  __m128i zero = _mm_setzero_si128();\n  __m128i mask = _mm_set_epi16(weight_i, invweight_i, weight_i, invweight_i, weight_i, invweight_i, weight_i, invweight_i);\n\n  int wMod16 = (rowsize / 16) * 16;\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wMod16; x += 16) {\n      __m128i px1 = _mm_load_si128(reinterpret_cast<const __m128i*>(p1 + x)); // y15y14 ... y7y6 y5y4 y3y2 y1y0\n      __m128i px2 = _mm_load_si128(reinterpret_cast<const __m128i*>(p2 + x)); // Y15Y14 ... Y7Y6 Y5Y4 Y3Y2 Y1Y0\n\n      __m128i p07 = _mm_unpacklo_epi8(px1, px2); // Y7y7 ..  Y3y3   Y2y2  Y1y1 Y0y0\n      __m128i p815 = _mm_unpackhi_epi8(px1, px2); //Y15y15 ..Y11y11 Y10y10 Y9y9 Y8y8\n\n      __m128i p03 = _mm_unpacklo_epi8(p07, zero);  //00Y3 00y3 00Y2 00y2 00Y1 00y1 00Y0 00y0 8*short\n      __m128i p47 = _mm_unpackhi_epi8(p07, zero);\n      __m128i p811 = _mm_unpacklo_epi8(p815, zero);\n      __m128i p1215 = _mm_unpackhi_epi8(p815, zero);\n\n      p03 = _mm_madd_epi16(p03, mask);\n      p47 = _mm_madd_epi16(p47, mask);\n      p811 = _mm_madd_epi16(p811, mask);\n      p1215 = _mm_madd_epi16(p1215, mask);\n\n      p03 = _mm_add_epi32(p03, round_mask);\n      p47 = _mm_add_epi32(p47, round_mask);\n      p811 = _mm_add_epi32(p811, round_mask);\n      p1215 = _mm_add_epi32(p1215, round_mask);\n\n      p03 = _mm_srli_epi32(p03, 15);\n      p47 = _mm_srli_epi32(p47, 15);\n      p811 = _mm_srli_epi32(p811, 15);\n      p1215 = _mm_srli_epi32(p1215, 15);\n\n      p07 = _mm_packs_epi32(p03, p47);\n      p815 = _mm_packs_epi32(p811, p1215);\n\n      __m128i result = _mm_packus_epi16(p07, p815);\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(p1 + x), result);\n    }\n\n    for (size_t x = wMod16 / sizeof(uint8_t); x < rowsize / sizeof(uint8_t); x++) {\n      reinterpret_cast<uint8_t *>(p1)[x] = (reinterpret_cast<uint8_t *>(p1)[x] * invweight_i + reinterpret_cast<const uint8_t *>(p2)[x] * weight_i + 16384) >> 15;\n    }\n\n    p1 += p1_pitch;\n    p2 += p2_pitch;\n  }\n}\n\n\nvoid weighted_merge_planar_sse2_float(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height, float weight_f, int weight_i, int invweight_i) {\n  AVS_UNUSED(weight_i);\n  AVS_UNUSED(invweight_i);\n\n  float invweight_f = 1.0f - weight_f;\n  auto mask = _mm_set1_ps(weight_f);\n\n  int wMod16 = (rowsize / 16) * 16;\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wMod16; x += 16) {\n      auto px1 = _mm_load_ps(reinterpret_cast<const float*>(p1 + x));\n      auto px2 = _mm_load_ps(reinterpret_cast<const float*>(p2 + x));\n      // p1:dst p2:src\n      // ( 1- mask) * dst + mask * src =\n      // dst - dst * mask + src * mask =\n      // dst + mask * (src - dst)\n      auto diff = _mm_sub_ps(px2, px1);\n      auto tmp = _mm_mul_ps(diff, mask); // (p2-p1)*mask\n      auto result = _mm_add_ps(tmp, px1); // +dst\n\n      _mm_store_ps(reinterpret_cast<float *>(p1 + x), result);\n    }\n\n    for (size_t x = wMod16 / sizeof(float); x < rowsize / sizeof(float); x++) {\n      reinterpret_cast<float *>(p1)[x] = reinterpret_cast<float *>(p1)[x] * invweight_f + reinterpret_cast<const float *>(p2)[x] * weight_f;\n    }\n\n    p1 += p1_pitch;\n    p2 += p2_pitch;\n  }\n}\n\nvoid average_plane_sse2_float(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height) {\n  auto OneHalf = _mm_set1_ps(0.5f);\n\n  int wMod16 = (rowsize / 16) * 16;\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wMod16; x += 16) {\n      auto px1 = _mm_load_ps(reinterpret_cast<const float*>(p1 + x));\n      auto px2 = _mm_load_ps(reinterpret_cast<const float*>(p2 + x));\n\n      auto result = _mm_mul_ps(_mm_add_ps(px1, px2), OneHalf); //\n\n      _mm_store_ps(reinterpret_cast<float *>(p1 + x), result);\n    }\n\n    for (size_t x = wMod16 / sizeof(float); x < rowsize / sizeof(float); x++) {\n      reinterpret_cast<float *>(p1)[x] = (reinterpret_cast<float *>(p1)[x] + reinterpret_cast<const float *>(p2)[x]) * 0.5f;\n    }\n\n    p1 += p1_pitch;\n    p2 += p2_pitch;\n  }\n}\n\n#ifdef X86_32\nvoid weighted_merge_planar_mmx(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height, float weight_f, int weight_i, int invweight_i) {\n  __m64 round_mask = _mm_set1_pi32(0x4000);\n  __m64 zero = _mm_setzero_si64();\n  __m64 mask = _mm_set_pi16(weight_i, invweight_i, weight_i, invweight_i);\n\n  int wMod8 = (rowsize/8) * 8;\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wMod8; x += 8) {\n      __m64 px1 = *(reinterpret_cast<const __m64*>(p1+x)); //y7y6 y5y4 y3y2 y1y0\n      __m64 px2 = *(reinterpret_cast<const __m64*>(p2+x)); //Y7Y6 Y5Y4 Y3Y2 Y1Y0\n\n      __m64 p0123 = _mm_unpacklo_pi8(px1, px2); //Y3y3 Y2y2 Y1y1 Y0y0\n      __m64 p4567 = _mm_unpackhi_pi8(px1, px2); //Y7y7 Y6y6 Y5y5 Y4y4\n\n      __m64 p01 = _mm_unpacklo_pi8(p0123, zero); //00Y1 00y1 00Y0 00y0\n      __m64 p23 = _mm_unpackhi_pi8(p0123, zero); //00Y3 00y3 00Y2 00y2\n      __m64 p45 = _mm_unpacklo_pi8(p4567, zero); //00Y5 00y5 00Y4 00y4\n      __m64 p67 = _mm_unpackhi_pi8(p4567, zero); //00Y7 00y7 00Y6 00y6\n\n      p01 = _mm_madd_pi16(p01, mask);\n      p23 = _mm_madd_pi16(p23, mask);\n      p45 = _mm_madd_pi16(p45, mask);\n      p67 = _mm_madd_pi16(p67, mask);\n\n      p01 = _mm_add_pi32(p01, round_mask);\n      p23 = _mm_add_pi32(p23, round_mask);\n      p45 = _mm_add_pi32(p45, round_mask);\n      p67 = _mm_add_pi32(p67, round_mask);\n\n      p01 = _mm_srli_pi32(p01, 15);\n      p23 = _mm_srli_pi32(p23, 15);\n      p45 = _mm_srli_pi32(p45, 15);\n      p67 = _mm_srli_pi32(p67, 15);\n\n      p0123 = _mm_packs_pi32(p01, p23);\n      p4567 = _mm_packs_pi32(p45, p67);\n\n      __m64 result = _mm_packs_pu16(p0123, p4567);\n\n      *reinterpret_cast<__m64*>(p1+x) = result;\n    }\n\n    for (int x = wMod8; x < rowsize; x++) {\n      p1[x] = (p1[x]*invweight_i + p2[x]*weight_i + 16384) >> 15;\n    }\n\n    p1 += p1_pitch;\n    p2 += p2_pitch;\n  }\n  _mm_empty();\n}\n#endif\n"
  },
  {
    "path": "avs_core/filters/intel/merge_sse.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n// Avisynth filter: YUV merge\n// by Klaus Post\n// adapted by Richard Berg (avisynth-dev@richardberg.net)\n\n\n#ifndef __Merge_SSE_H__\n#define __Merge_SSE_H__\n\n#include <avisynth.h>\n\ntemplate<bool lessthan16bit>\nvoid weighted_merge_planar_uint16_sse2(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height, float weight_f, int weight_i, int invweight_i);\n\nvoid weighted_merge_planar_sse2(BYTE *p1,const BYTE *p2, int p1_pitch, int p2_pitch,int rowsize, int height, float weight_f, int weight_i, int invweight_i);\n\n#ifdef X86_32\nvoid weighted_merge_planar_mmx(BYTE *p1,const BYTE *p2, int p1_pitch, int p2_pitch,int rowsize, int height, float weight_f, int weight_i, int invweight_i);\n#endif\nvoid weighted_merge_planar_sse2_float(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height, float weight_f, int weight_i, int invweight_i);\n\n#ifdef X86_32\nvoid weighted_merge_chroma_yuy2_mmx(BYTE* src, const BYTE* chroma, int pitch, int chroma_pitch, int width, int height, int weight, int invweight);\n#endif\nvoid weighted_merge_chroma_yuy2_sse2(BYTE* src, const BYTE* chroma, int pitch, int chroma_pitch, int width, int height, int weight, int invweight);\n#ifdef X86_32\nvoid weighted_merge_luma_yuy2_mmx(BYTE* src, const BYTE* luma, int pitch, int luma_pitch, int width, int height, int weight, int invweight);\n#endif\nvoid weighted_merge_luma_yuy2_sse2(BYTE* src, const BYTE* luma, int pitch, int luma_pitch, int width, int height, int weight, int invweight);\n\n#ifdef X86_32\nvoid replace_luma_yuy2_mmx(BYTE* src, const BYTE* luma, int pitch, int luma_pitch, int width, int height);\n#endif\nvoid replace_luma_yuy2_sse2(BYTE* src, const BYTE* luma, int pitch, int luma_pitch, int width, int height);\n\n#ifdef X86_32\ntemplate<typename pixel_t>\nvoid average_plane_isse(BYTE* p1, const BYTE* p2, int p1_pitch, int p2_pitch, int rowsize, int height);\n#endif\ntemplate<typename pixel_t>\nvoid average_plane_sse2(BYTE* p1, const BYTE* p2, int p1_pitch, int p2_pitch, int rowsize, int height);\nvoid average_plane_sse2_float(BYTE* p1, const BYTE* p2, int p1_pitch, int p2_pitch, int rowsize, int height);\n\n#endif  // __Merge_SSE_H__\n"
  },
  {
    "path": "avs_core/filters/intel/planeswap_sse.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n// Avisynth filter:  Swap planes\n// by Klaus Post\n// adapted by Richard Berg (avisynth-dev@richardberg.net)\n// iSSE code by Ian Brabham\n\n#include <avs/config.h>\n#ifdef AVS_WINDOWS\n#include <avs/win.h>\n#else\n#include <avs/posix.h>\n#endif\n#include \"planeswap_sse.h\"\n\n// Intrinsics base header + really required extension headers\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n#include <tmmintrin.h> // SSSE3\n\n#include \"stdint.h\"\n\n\n\n/**************************************\n *  Swap - swaps UV on planar maps\n **************************************/\n\nvoid yuy2_swap_sse2(const BYTE* srcp, BYTE* dstp, int src_pitch, int dst_pitch, int width, int height)\n{\n  const __m128i mask = _mm_set1_epi16(0x00FF);\n\n  for (int y = 0; y < height; ++y ) {\n    for (int x = 0; x < width; x += 16) {\n      __m128i src = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x));\n      __m128i swapped = _mm_shufflelo_epi16(src, _MM_SHUFFLE(2, 3, 0, 1));\n      swapped = _mm_shufflehi_epi16(swapped, _MM_SHUFFLE(2, 3, 0, 1));\n      swapped = _mm_or_si128(_mm_and_si128(mask, src), _mm_andnot_si128(mask, swapped));\n      _mm_stream_si128(reinterpret_cast<__m128i*>(dstp + x), swapped);\n    }\n\n    dstp += dst_pitch;\n    srcp += src_pitch;\n  }\n}\n\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nvoid yuy2_swap_ssse3(const BYTE* srcp, BYTE* dstp, int src_pitch, int dst_pitch, int width, int height)\n{\n  const __m128i mask = _mm_set_epi8(13, 14, 15, 12, 9, 10, 11, 8, 5, 6, 7, 4, 1, 2, 3, 0);\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; x += 16) {\n      __m128i src = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x));\n      __m128i dst = _mm_shuffle_epi8(src, mask);\n      _mm_stream_si128(reinterpret_cast<__m128i*>(dstp + x), dst);\n    }\n\n    dstp += dst_pitch;\n    srcp += src_pitch;\n  }\n}\n\n#ifdef X86_32\nvoid yuy2_swap_isse(const BYTE* srcp, BYTE* dstp, int src_pitch, int dst_pitch, int width, int height)\n{\n  __m64 mask = _mm_set1_pi16(0x00FF);\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; x+= 8) {\n      __m64 src = *reinterpret_cast<const __m64*>(srcp+x);\n      __m64 swapped = _mm_shuffle_pi16(src, _MM_SHUFFLE(2, 3, 0, 1));\n      swapped = _mm_or_si64(_mm_and_si64(mask, src), _mm_andnot_si64(mask, swapped));\n      *reinterpret_cast<__m64*>(dstp + x) = swapped;\n    }\n\n    dstp += dst_pitch;\n    srcp += src_pitch;\n  }\n  _mm_empty();\n}\n#endif\n\nvoid yuy2_uvtoy_sse2(const BYTE* srcp, BYTE* dstp, int src_pitch, int dst_pitch, int dst_width, int height, int pos)\n{\n  const __m128i chroma = _mm_set1_epi32(0x80008000);\n  const __m128i mask = _mm_set1_epi32(0x000000FF);\n  pos *= 8;\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < dst_width; x += 16) {\n      __m128i s0 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + 2 * x));\n      __m128i s1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + 2 * x + 16));\n      s0 = _mm_and_si128(mask, _mm_srli_epi32(s0, pos));\n      s1 = _mm_and_si128(mask, _mm_srli_epi32(s1, pos));\n      s0 = _mm_packs_epi32(s0, s1);\n      s0 = _mm_or_si128(s0, chroma);\n      _mm_stream_si128(reinterpret_cast<__m128i*>(dstp + x), s0);\n    }\n    srcp += src_pitch;\n    dstp += dst_pitch;\n  }\n}\n\nvoid yuy2_uvtoy8_sse2(const BYTE* srcp, BYTE* dstp, int src_pitch, int dst_pitch, int dst_width, int height, int pos)\n{\n  const __m128i mask = _mm_set1_epi32(0x000000FF);\n  pos *= 8;\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < dst_width; x += 8) {\n      __m128i s0 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + 4 * x));\n      __m128i s1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + 4 * x + 16));\n      s0 = _mm_and_si128(mask, _mm_srli_epi32(s0, pos));\n      s1 = _mm_and_si128(mask, _mm_srli_epi32(s1, pos));\n      s0 = _mm_packs_epi32(s0, s1);\n      s0 = _mm_packus_epi16(s0, s0);\n      _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + x), s0);\n    }\n    srcp += src_pitch;\n    dstp += dst_pitch;\n  }\n}\n\ntemplate <bool has_clipY>\nvoid yuy2_ytouv_sse2(const BYTE* srcp_y, const BYTE* srcp_u, const BYTE* srcp_v, BYTE* dstp, int pitch_y, int pitch_u, int pitch_v, int dst_pitch, int dst_rowsize, int height)\n{\n  const __m128i mask = _mm_set1_epi16(0x00FF);\n  const __m128i zero = _mm_setzero_si128();\n  const __m128i fill = _mm_set1_epi16(0x007e);\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < dst_rowsize; x += 32) {\n      __m128i u = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp_u + x / 2));\n      __m128i v = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp_v + x / 2));\n      __m128i uv = _mm_or_si128(_mm_and_si128(u, mask), _mm_slli_epi16(v, 8));\n      __m128i uv_lo = _mm_unpacklo_epi8(zero, uv);\n      __m128i uv_hi = _mm_unpackhi_epi8(zero, uv);\n      if (has_clipY) {\n        __m128i y_lo = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp_y + x));\n        __m128i y_hi = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp_y + x + 16));\n        uv_lo = _mm_or_si128(uv_lo, _mm_and_si128(y_lo, mask));\n        uv_hi = _mm_or_si128(uv_hi, _mm_and_si128(y_hi, mask));\n      }\n      else {\n        uv_lo = _mm_or_si128(uv_lo, fill);\n        uv_hi = _mm_or_si128(uv_hi, fill);\n      }\n      _mm_stream_si128(reinterpret_cast<__m128i*>(dstp + x), uv_lo);\n      _mm_stream_si128(reinterpret_cast<__m128i*>(dstp + x + 16), uv_hi);\n    }\n    srcp_y += pitch_y;\n    srcp_u += pitch_u;\n    srcp_v += pitch_v;\n    dstp += dst_pitch;\n  }\n}\n\ntemplate void yuy2_ytouv_sse2<false>(const BYTE* srcp_y, const BYTE* srcp_u, const BYTE* srcp_v, BYTE* dstp, int pitch_y, int pitch_u, int pitch_v, int dst_pitch, int dst_rowsize, int height);\ntemplate void yuy2_ytouv_sse2<true>(const BYTE* srcp_y, const BYTE* srcp_u, const BYTE* srcp_v, BYTE* dstp, int pitch_y, int pitch_u, int pitch_v, int dst_pitch, int dst_rowsize, int height);\n"
  },
  {
    "path": "avs_core/filters/intel/planeswap_sse.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n// Avisynth filter: Plane Swap\n// by Klaus Post\n\n\n\n#ifndef __Planeswap_SSE_H__\n#define __Planeswap_SSE_H__\n\n#include <avisynth.h>\n\n#ifdef X86_32\nvoid yuy2_swap_isse(const BYTE* srcp, BYTE* dstp, int src_pitch, int dst_pitch, int width, int height);\n#endif\nvoid yuy2_swap_sse2(const BYTE* srcp, BYTE* dstp, int src_pitch, int dst_pitch, int width, int height);\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nvoid yuy2_swap_ssse3(const BYTE* srcp, BYTE* dstp, int src_pitch, int dst_pitch, int width, int height);\n\nvoid yuy2_uvtoy_sse2(const BYTE* srcp, BYTE* dstp, int src_pitch, int dst_pitch, int dst_width, int height, int pos);\nvoid yuy2_uvtoy8_sse2(const BYTE* srcp, BYTE* dstp, int src_pitch, int dst_pitch, int dst_width, int height, int pos);\n\ntemplate <bool has_clipY>\nvoid yuy2_ytouv_sse2(const BYTE* srcp_y, const BYTE* srcp_u, const BYTE* srcp_v, BYTE* dstp, int pitch_y, int pitch_u, int pitch_v, int dst_pitch, int dst_rowsize, int height);\n\n#endif  // __Planeswap_SSE_H__\n"
  },
  {
    "path": "avs_core/filters/intel/resample_avx2.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// Intrinsics base header + really required extension headers\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n\n#include <vector>\n#include <avisynth.h>\n#include <avs/config.h>\n#include <avs/types.h>\n#include <cstdint>\n#include \"../resample_functions.h\"\n#include <cassert>\n#include <type_traits>\n#include <algorithm>\n\n#if !defined(__FMA__)\n// Assume that all processors that have AVX2 also have FMA3\n#if defined (__GNUC__) && ! defined (__INTEL_COMPILER) && ! defined (__clang__)\n// Prevent error message in g++ when using FMA intrinsics with avx2:\n#pragma message \"It is recommended to specify also option -mfma when using -mavx2 or higher\"\n#else\n#define __FMA__  1\n#endif\n#endif\n// FMA3 instruction set\n#if defined (__FMA__) && (defined(__GNUC__) || defined(__clang__))  && ! defined (__INTEL_COMPILER)\n#include <fmaintrin.h>\n#endif // __FMA__\n\n\n#include \"resample_avx2.h\"\n\n#ifndef _mm256_set_m128i\n#define _mm256_set_m128i(v0, v1) _mm256_insertf128_si256(_mm256_castsi128_si256(v1), (v0), 1)\n#endif\n\n#ifndef _mm256_set_m128\n#define _mm256_set_m128(v0, v1) _mm256_insertf128_ps(_mm256_castps128_ps256(v1), (v0), 1)\n#endif\n\n\n//-------- AVX2 Horizontals\n\n// Dual line processing (speed gain): 2x16 pixels of two consecutive offset entries.\n// Use aligned filtersize template until alignment and end conditions allow.\n// Aligned case uses full 16 pix/coeffs in one cycle.\n// Unsafe part starts with 16 pix/coeffs until safe, then 8, 4, 1.\n// Basically the only difference between 8 and 10-16 bit is the load and store.\n// Processing 8 bit pixels even has overhead:\n// - need upconverting to 16 bit short on load\n// - extra step when narrowing end results further down to 8 bits.\n// When processing uint16_t, the exact 16 bit size needs an unsigned -> signed 16 bit conversion\n// because multiple and add (madd) works in the signed 16 bit domain.\n\ntemplate<typename pixel_t, bool lessthan16bit, int filtersizealigned16>\nAVS_FORCEINLINE static void process_two_16pixels_h_uint8_16_core(const pixel_t* AVS_RESTRICT src, int begin1, int begin2, int i, const short* AVS_RESTRICT current_coeff, int filter_size, __m256i& result1, __m256i& result2,\n  __m256i& shifttosigned) {\n  filter_size = (filtersizealigned16 >= 1) ? filtersizealigned16 * 16 : filter_size;\n  // knowing a quasi-constexpr filter_size from template for commonly used sizes\n  // aligned_filter_size 16, 32, 48, 64, hugely helps compiler optimization\n\n  __m256i data_1, data_2;\n\n  if constexpr (sizeof(pixel_t) == 1) {\n    // pixel_t is uint8_t\n    data_1 = _mm256_cvtepu8_epi16(_mm_loadu_si128(reinterpret_cast<const __m128i*>(src + begin1 + i)));\n    data_2 = _mm256_cvtepu8_epi16(_mm_loadu_si128(reinterpret_cast<const __m128i*>(src + begin2 + i)));\n  }\n  else {\n    // pixel_t is uint16_t, at exact 16 bit size an unsigned -> signed 16 bit conversion needed\n    data_1 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(src + begin1 + i));\n    if constexpr (!lessthan16bit)\n      data_1 = _mm256_add_epi16(data_1, shifttosigned); // unsigned -> signed\n    data_2 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(src + begin2 + i));\n    if constexpr (!lessthan16bit)\n      data_2 = _mm256_add_epi16(data_2, shifttosigned); // unsigned -> signed\n  }\n  __m256i coeff_1 = _mm256_load_si256(reinterpret_cast<const __m256i*>(current_coeff)); // 16 coeffs\n  __m256i coeff_2 = _mm256_load_si256(reinterpret_cast<const __m256i*>(current_coeff + 1 * filter_size)); // 16x second pixel's coefficients\n  result1 = _mm256_add_epi32(result1, _mm256_madd_epi16(data_1, coeff_1));\n  result2 = _mm256_add_epi32(result2, _mm256_madd_epi16(data_2, coeff_2));\n}\n\n// filtersizealigned16: special: 1..4. Generic: -1\ntemplate<bool safe_aligned_mode, typename pixel_t, bool lessthan16bit, int filtersizealigned16>\nAVS_FORCEINLINE static void process_two_pixels_h_uint8_16(const pixel_t* AVS_RESTRICT src_ptr, int begin1, int begin2, const short* AVS_RESTRICT current_coeff, int filter_size, __m256i& result1, __m256i& result2, int kernel_size,\n  __m256i& shifttosigned) {\n\n  filter_size = (filtersizealigned16 >= 1) ? filtersizealigned16 * 16 : filter_size;\n  // knowing a quasi-constexpr filter_size from template for commonly used sizes\n  // aligned_filter_size 16, 32, 48, 64, hugely helps compiler optimization\n\n  int ksmod16;\n  if constexpr (safe_aligned_mode)\n    ksmod16 = filter_size / 16 * 16;\n  else\n    ksmod16 = kernel_size / 16 * 16; // danger zone, scanline overread possible. Use exact unaligned kernel_size\n  const pixel_t* src_ptr1 = src_ptr + begin1;\n  const pixel_t* src_ptr2 = src_ptr + begin2;\n  int i = 0;\n\n  // Process 16 elements at a time\n  for (; i < ksmod16; i += 16) {\n    process_two_16pixels_h_uint8_16_core<pixel_t, lessthan16bit, filtersizealigned16>(src_ptr, begin1, begin2, i, current_coeff + i, filter_size, result1, result2, shifttosigned);\n  }\n\n  if constexpr (!safe_aligned_mode) {\n    // working with the original, unaligned kernel_size\n    if (i == kernel_size) return;\n\n    const short* current_coeff2 = current_coeff + filter_size; // Points to second pixel's coefficients\n    const int ksmod8 = kernel_size / 8 * 8;\n    const int ksmod4 = kernel_size / 4 * 4;\n\n    // Process 8 elements if needed\n    if (i < ksmod8) {\n      // Process 8 elements for first pixel\n      __m128i data_1;\n      if constexpr (sizeof(pixel_t) == 1)\n        data_1 = _mm_cvtepu8_epi16(_mm_loadl_epi64(reinterpret_cast<const __m128i*>(src_ptr1 + i)));\n      else {\n        // uint16_t\n        data_1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src_ptr1 + i));\n        if constexpr (!lessthan16bit)\n          data_1 = _mm_add_epi16(data_1, _mm256_castsi256_si128(shifttosigned)); // unsigned -> signed\n      }\n\n      __m128i coeff_1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(current_coeff + i));\n      __m128i temp_result1 = _mm_madd_epi16(data_1, coeff_1);\n\n      // Process 8 elements for second pixel\n      __m128i data_2;\n      if constexpr (sizeof(pixel_t) == 1)\n        data_2 = _mm_cvtepu8_epi16(_mm_loadl_epi64(reinterpret_cast<const __m128i*>(src_ptr2 + i)));\n      else {\n        data_2 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src_ptr2 + i));\n        if constexpr (!lessthan16bit)\n          data_2 = _mm_add_epi16(data_2, _mm256_castsi256_si128(shifttosigned)); // unsigned -> signed\n      }\n      __m128i coeff_2 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(current_coeff2 + i));\n      __m128i temp_result2 = _mm_madd_epi16(data_2, coeff_2);\n\n      // update result vectors\n      __m256i temp1 = _mm256_setzero_si256();\n      __m256i temp2 = _mm256_setzero_si256();\n      temp1 = _mm256_insertf128_si256(temp1, temp_result1, 0);\n      temp2 = _mm256_insertf128_si256(temp2, temp_result2, 0);\n      result1 = _mm256_add_epi32(result1, temp1);\n      result2 = _mm256_add_epi32(result2, temp2);\n\n      i += 8;\n      if (i == kernel_size) return;\n    }\n\n    // Process 4 elements if needed\n    if (i < ksmod4) {\n      // Process 4 elements for first pixel\n      __m128i data_1;\n      if constexpr (sizeof(pixel_t) == 1)\n        data_1= _mm_cvtepu8_epi16(_mm_cvtsi32_si128(*reinterpret_cast<const int*>(src_ptr1 + i)));\n      else {\n        data_1 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(src_ptr1 + i));\n        if constexpr (!lessthan16bit)\n          data_1 = _mm_add_epi16(data_1, _mm256_castsi256_si128(shifttosigned)); // unsigned -> signed\n      }\n      __m128i coeff_1 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(current_coeff + i));\n      __m128i temp_result1 = _mm_madd_epi16(data_1, coeff_1);\n\n      // Process 4 elements for second pixel\n      __m128i data_2;\n      if constexpr (sizeof(pixel_t) == 1)\n        data_2 = _mm_cvtepu8_epi16(_mm_cvtsi32_si128(*reinterpret_cast<const int*>(src_ptr2 + i)));\n      else {\n        data_2 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(src_ptr2 + i));\n        if constexpr (!lessthan16bit)\n          data_2 = _mm_add_epi16(data_2, _mm256_castsi256_si128(shifttosigned)); // unsigned -> signed\n      }\n      __m128i coeff_2 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(current_coeff2 + i));\n      __m128i temp_result2 = _mm_madd_epi16(data_2, coeff_2);\n\n      // update result vectors\n      __m256i temp1 = _mm256_setzero_si256();\n      __m256i temp2 = _mm256_setzero_si256();\n      temp1 = _mm256_insertf128_si256(temp1, temp_result1, 0);\n      temp2 = _mm256_insertf128_si256(temp2, temp_result2, 0);\n      result1 = _mm256_add_epi32(result1, temp1);\n      result2 = _mm256_add_epi32(result2, temp2);\n\n      i += 4;\n      if (i == kernel_size) return;\n    }\n\n    // Process remaining elements with scalar operations\n    if (i < kernel_size) {\n      int scalar_sum1[4] = { 0, 0, 0, 0 }; // like an __m128i\n      int scalar_sum2[4] = { 0, 0, 0, 0 };\n\n\n      for (; i < kernel_size; i++) {\n        if constexpr (sizeof(pixel_t) == 1) {\n          scalar_sum1[i % 4] += src_ptr1[i] * current_coeff[i];\n          scalar_sum2[i % 4] += src_ptr2[i] * current_coeff2[i];\n        }\n        else {\n          uint16_t pix1 = src_ptr1[i];\n          uint16_t pix2 = src_ptr2[i];\n\n          if constexpr (!lessthan16bit) {\n            pix1 -= 32768;\n            pix2 -= 32768;\n          }\n\n          scalar_sum1[i % 4] += (short)pix1 * current_coeff[i];\n          scalar_sum2[i % 4] += (short)pix2 * current_coeff2[i];\n        }\n      }\n\n      // Convert scalar results to SIMD and add to result vectors\n      __m128i temp_result1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(scalar_sum1));\n      __m128i temp_result2 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(scalar_sum2));\n\n      __m256i temp1 = _mm256_setzero_si256();\n      __m256i temp2 = _mm256_setzero_si256();\n      temp1 = _mm256_insertf128_si256(temp1, temp_result1, 0);\n      temp2 = _mm256_insertf128_si256(temp2, temp_result2, 0);\n      result1 = _mm256_add_epi32(result1, temp1);\n      result2 = _mm256_add_epi32(result2, temp2);\n    }\n  }\n}\n\n// filtersizealigned16: special: 1..4. Generic: -1\ntemplate<bool is_safe, typename pixel_t, bool lessthan16bit, int filtersizealigned16>\nAVS_FORCEINLINE static void process_eight_pixels_h_uint8_16(const pixel_t* src, int x, const short* current_coeff_base, int filter_size,\n  __m256i& rounder256, __m256i& shifttosigned, __m128i& clamp_limit,\n  pixel_t* dst,\n  ResamplingProgram* program)\n{\n  assert(program->filter_size_alignment >= 16); // code assumes this\n\n  filter_size = (filtersizealigned16 >= 1) ? filtersizealigned16 * 16 : filter_size;\n  // knowing a quasi-constexpr filter_size from template for commonly used sizes\n  // aligned_filter_size 16, 32, 48, 64, hugely helps compiler optimization\n\n  const short* AVS_RESTRICT current_coeff = current_coeff_base + x * filter_size;\n  const int unaligned_kernel_size = program->filter_size_real;\n\n  // Unrolled processing of all 8 pixels\n\n  // 0 & 1\n  __m256i result0 = rounder256;\n  __m256i result1 = rounder256;\n  int begin0 = program->pixel_offset[x + 0];\n  int begin1 = program->pixel_offset[x + 1];\n  process_two_pixels_h_uint8_16<is_safe, pixel_t, lessthan16bit, filtersizealigned16>(src, begin0, begin1, current_coeff, filter_size, result0, result1, unaligned_kernel_size, shifttosigned);\n  current_coeff += 2 * filter_size;\n  __m256i sumQuad12 = _mm256_hadd_epi32(result0, result1);\n\n  // 2 & 3\n  result0 = rounder256;\n  result1 = rounder256;\n  begin0 = program->pixel_offset[x + 2];\n  begin1 = program->pixel_offset[x + 3];\n  process_two_pixels_h_uint8_16<is_safe, pixel_t, lessthan16bit, filtersizealigned16>(src, begin0, begin1, current_coeff, filter_size, result0, result1, unaligned_kernel_size, shifttosigned);\n  current_coeff += 2 * filter_size;\n  __m256i sumQuad1234 = _mm256_hadd_epi32(sumQuad12, _mm256_hadd_epi32(result0, result1));\n\n  // 4 & 5\n  result0 = rounder256;\n  result1 = rounder256;\n  begin0 = program->pixel_offset[x + 4];\n  begin1 = program->pixel_offset[x + 5];\n  process_two_pixels_h_uint8_16<is_safe, pixel_t, lessthan16bit, filtersizealigned16>(src, begin0, begin1, current_coeff, filter_size, result0, result1, unaligned_kernel_size, shifttosigned);\n  current_coeff += 2 * filter_size;\n  __m256i sumQuad56 = _mm256_hadd_epi32(result0, result1);\n\n  // 6 & 7\n  result0 = rounder256;\n  result1 = rounder256;\n  begin0 = program->pixel_offset[x + 6];\n  begin1 = program->pixel_offset[x + 7];\n  process_two_pixels_h_uint8_16<is_safe, pixel_t, lessthan16bit, filtersizealigned16>(src, begin0, begin1, current_coeff, filter_size, result0, result1, unaligned_kernel_size, shifttosigned);\n  //current_coeff += 2 * filter_size;\n  __m256i sumQuad5678 = _mm256_hadd_epi32(sumQuad56, _mm256_hadd_epi32(result0, result1));\n\n  __m128i pix1234 = _mm_add_epi32(_mm256_extractf128_si256(sumQuad1234, 0), _mm256_extractf128_si256(sumQuad1234, 1));\n  __m128i pix5678 = _mm_add_epi32(_mm256_extractf128_si256(sumQuad5678, 0), _mm256_extractf128_si256(sumQuad5678, 1));\n  __m256i result_8x_uint32 = _mm256_set_m128i(pix5678, pix1234);\n\n  // correct if signed, scale back, store\n  if constexpr (sizeof(pixel_t) == 2 && !lessthan16bit) {\n    const __m256i shiftfromsigned = _mm256_set1_epi32(+32768 << FPScale16bits); // yes, 32 bit data. for 16 bits only\n    result_8x_uint32 = _mm256_add_epi32(result_8x_uint32, shiftfromsigned);\n  }\n\n  const int current_fp_scale_bits = (sizeof(pixel_t) == 1) ? FPScale8bits : FPScale16bits;\n\n  // scale back, shuffle, store\n  __m256i result = _mm256_srai_epi32(result_8x_uint32, current_fp_scale_bits);\n  __m256i result_2x4x_uint16 = _mm256_packus_epi32(result, result /* n/a */);\n  __m128i result_2x4x_uint16_128 = _mm256_castsi256_si128(_mm256_permute4x64_epi64(result_2x4x_uint16, (0 << 0) | (2 << 2) | (0 << 4) | (0 << 6)));\n  if constexpr (sizeof(pixel_t) == 2 && lessthan16bit)\n    result_2x4x_uint16_128 = _mm_min_epu16(result_2x4x_uint16_128, clamp_limit); // extra clamp for 10-14 bits\n\n  if constexpr (sizeof(pixel_t) == 1) {\n    __m128i result_2x4x_uint8 = _mm_packus_epi16(result_2x4x_uint16_128, _mm_setzero_si128());\n    _mm_storel_epi64(reinterpret_cast<__m128i*>(dst + x), result_2x4x_uint8);\n  }\n  else {\n    _mm_stream_si128(reinterpret_cast<__m128i*>(dst + x), result_2x4x_uint16_128);\n  }\n}\n\n// filtersizealigned16: special: 1..4. Generic: -1\ntemplate<typename pixel_t, bool lessthan16bit, int filtersizealigned16>\nstatic void internal_resizer_h_avx2_generic_uint8_16_t(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  const int filter_size = (filtersizealigned16 >= 1) ? filtersizealigned16 * 16 : program->filter_size;\n  // knowing a quasi-constexpr filter_size from template for commonly used sizes\n  // aligned_filter_size 16, 32, 48, 64, hugely helps compiler optimization\n\n  __m256i shifttosigned = _mm256_set1_epi16(-32768); // for 16 bits only\n\n  const int current_fp_scale_bits = (sizeof(pixel_t) == 1) ? FPScale8bits : FPScale16bits;\n  __m256i rounder256 = _mm256_setr_epi32(1 << (current_fp_scale_bits - 1), 0, 0, 0, 0, 0, 0, 0);\n\n  __m128i clamp_limit = _mm_set1_epi16((short)((1 << bits_per_pixel) - 1)); // clamp limit for 8< <16 bits\n\n  const pixel_t* AVS_RESTRICT src = reinterpret_cast<const pixel_t*>(src8);\n  pixel_t* AVS_RESTRICT dst = reinterpret_cast<pixel_t*>(dst8);\n  dst_pitch /= sizeof(pixel_t);\n  src_pitch /= sizeof(pixel_t);\n\n  const int w_safe_mod8 = (program->safelimit_filter_size_aligned.overread_possible ? program->safelimit_filter_size_aligned.source_overread_beyond_targetx : width) / 8 * 8;\n\n  for (int y = 0; y < height; y++) {\n    const short* AVS_RESTRICT current_coeff_base = program->pixel_coefficient;\n\n    // Process safe aligned pixels\n    for (int x = 0; x < w_safe_mod8; x += 8) {\n      process_eight_pixels_h_uint8_16<true, pixel_t, lessthan16bit, filtersizealigned16>(src, x, current_coeff_base, filter_size, rounder256, shifttosigned, clamp_limit, dst, program);\n    }\n\n    // Process up to the actual kernel size instead of the aligned filter_size to prevent overreading beyond the last source pixel.\n    // We assume extra offset entries were added to the p->pixel_offset array (aligned to 8 during initialization).\n    // This may store 1-7 false pixels, but they are ignored since Avisynth will not read beyond the width.\n    for (int x = w_safe_mod8; x < width; x += 8) {\n      process_eight_pixels_h_uint8_16<false, pixel_t, lessthan16bit, filtersizealigned16>(src, x, current_coeff_base, filter_size, rounder256, shifttosigned, clamp_limit, dst, program);\n    }\n\n    dst += dst_pitch;\n    src += src_pitch;\n  }\n}\n\n// coeffs are safely padded/aligned to 16\n\n// 8 bit Horizontal\n\nvoid resizer_h_avx2_generic_uint8_t(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  AVS_UNUSED(bits_per_pixel);\n  const int filter_size = program->filter_size;\n  assert(program->filter_size_alignment == 16);\n\n  if (filter_size == 16)\n    internal_resizer_h_avx2_generic_uint8_16_t<uint8_t, true, 1>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else if (filter_size == 2*16)\n    internal_resizer_h_avx2_generic_uint8_16_t<uint8_t, true, 2>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else if (filter_size == 3*16)\n    internal_resizer_h_avx2_generic_uint8_16_t<uint8_t, true, 3>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else if (filter_size == 4*16)\n    internal_resizer_h_avx2_generic_uint8_16_t<uint8_t, true, 4>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else // -1: basic method, use program->filter_size\n    internal_resizer_h_avx2_generic_uint8_16_t<uint8_t, true, -1>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\n\n// 16 bit Horizontal\n\ntemplate<bool lessthan16bit>\nvoid resizer_h_avx2_generic_uint16_t(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  const int filter_size = program->filter_size;\n  assert(program->filter_size_alignment == 16);\n\n  if (filter_size== 16)\n    internal_resizer_h_avx2_generic_uint8_16_t<uint16_t, lessthan16bit, 1>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else if (filter_size == 2 * 16)\n    internal_resizer_h_avx2_generic_uint8_16_t<uint16_t, lessthan16bit, 2>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else if (filter_size == 3 * 16)\n    internal_resizer_h_avx2_generic_uint8_16_t<uint16_t, lessthan16bit, 3>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else if (filter_size == 4 * 16)\n    internal_resizer_h_avx2_generic_uint8_16_t<uint16_t, lessthan16bit, 4>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else // -1: basic method, use program->filter_size\n    internal_resizer_h_avx2_generic_uint8_16_t<uint16_t, lessthan16bit, -1>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\n\n// AVX2 Horizontal float\n\n// 2x8 pixels of two consecutive offset entries.\nAVS_FORCEINLINE static void process_pix2_coeff8_h_float_core(const float* src, int begin1, int begin2, int i, float* current_coeff, int filter_size, __m256& result1, __m256& result2) {\n  __m256 data_1 = _mm256_loadu_ps(src + begin1 + i);\n  __m256 data_2 = _mm256_loadu_ps(src + begin2 + i);\n  __m256 coeff_1 = _mm256_load_ps(current_coeff); // 8 coeffs\n  __m256 coeff_2 = _mm256_load_ps(current_coeff + 1 * filter_size); // 8x second pixel's coefficients\n  result1 = _mm256_fmadd_ps(data_1, coeff_1, result1); // a*b + c\n  result2 = _mm256_fmadd_ps(data_2, coeff_2, result2);\n}\n\ntemplate<bool safe_aligned_mode>\nAVS_FORCEINLINE static void process_two_pixels_h_float(const float* src_ptr, int begin1, int begin2, float* current_coeff, int filter_size, __m256& result1, __m256& result2, int kernel_size) {\n  int ksmod8;\n  // 32 bytes contain 8 floats\n  if constexpr (safe_aligned_mode)\n    ksmod8 = filter_size / 8 * 8;\n  else\n    ksmod8 = kernel_size / 8 * 8; // danger zone, scanline overread possible. Use exact unaligned kernel_size\n  const float* src_ptr1 = src_ptr + begin1;\n  const float* src_ptr2 = src_ptr + begin2;\n  int i = 0;\n\n  // Process 8 elements at a time\n  for (; i < ksmod8; i += 8) {\n    process_pix2_coeff8_h_float_core(src_ptr, begin1, begin2, i, current_coeff + i, filter_size, result1, result2);\n  }\n\n  if constexpr (!safe_aligned_mode) {\n    // working with the original, unaligned kernel_size\n    if (i == kernel_size) return;\n\n    float* current_coeff2 = current_coeff + filter_size; // Points to second pixel's coefficients\n    const int ksmod4 = kernel_size / 4 * 4;\n\n    // Process 4 elements if needed\n    if (i < ksmod4) {\n      // Process 4 elements for first pixel\n      __m128 data_1 = _mm_loadu_ps(src_ptr1 + i);\n      __m128 coeff_1 = _mm_load_ps(current_coeff + i);\n      __m128 temp_result1 = _mm_mul_ps(data_1, coeff_1);\n\n      // Process 4 elements for second pixel\n      __m128 data_2 = _mm_loadu_ps(src_ptr2 + i);\n      __m128 coeff_2 = _mm_load_ps(current_coeff2 + i);\n      __m128 temp_result2 = _mm_mul_ps(data_2, coeff_2);\n\n      // update result vectors\n      __m256 temp1 = _mm256_setzero_ps();\n      __m256 temp2 = _mm256_setzero_ps();\n      temp1 = _mm256_insertf128_ps(temp1, temp_result1, 0);\n      temp2 = _mm256_insertf128_ps(temp2, temp_result2, 0);\n      result1 = _mm256_add_ps(result1, temp1);\n      result2 = _mm256_add_ps(result2, temp2);\n\n      i += 4;\n      if (i == kernel_size) return;\n    }\n\n    // Process remaining elements with scalar operations\n    if (i < kernel_size) {\n      float scalar_sum1[4] = { 0, 0, 0, 0 }; // like an __m128\n      float scalar_sum2[4] = { 0, 0, 0, 0 };\n\n      for (; i < kernel_size; i++) {\n        scalar_sum1[i % 4] += src_ptr1[i] * current_coeff[i];\n        scalar_sum2[i % 4] += src_ptr2[i] * current_coeff2[i];\n      }\n\n      // Convert scalar results to SIMD and add to result vectors\n      __m128 temp_result1 = _mm_loadu_ps(scalar_sum1);\n      __m128 temp_result2 = _mm_loadu_ps(scalar_sum2);\n\n      __m256 temp1 = _mm256_setzero_ps();\n      __m256 temp2 = _mm256_setzero_ps();\n      temp1 = _mm256_insertf128_ps(temp1, temp_result1, 0);\n      temp2 = _mm256_insertf128_ps(temp2, temp_result2, 0);\n      result1 = _mm256_add_ps(result1, temp1);\n      result2 = _mm256_add_ps(result2, temp2);\n    }\n  }\n}\n\ntemplate<bool is_safe>\nAVS_FORCEINLINE static void process_eight_pixels_h_float(const float* src, int x, float* current_coeff_base, int filter_size,\n  __m128& zero128, __m256& zero256,\n  float* dst,\n  ResamplingProgram* program)\n{\n  assert(program->filter_size_alignment >= 8); // code assumes this\n\n  float* current_coeff = current_coeff_base + x * filter_size;\n  const int unaligned_kernel_size = program->filter_size_real;\n\n  // Unrolled processing of all 8 pixels\n\n  // 0 & 1\n  __m256 result0 = zero256;\n  __m256 result1 = zero256;\n  int begin0 = program->pixel_offset[x + 0];\n  int begin1 = program->pixel_offset[x + 1];\n  process_two_pixels_h_float<is_safe>(src, begin0, begin1, current_coeff, filter_size, result0, result1, unaligned_kernel_size);\n  current_coeff += 2 * filter_size;\n  __m256 sumQuad12 = _mm256_hadd_ps(result0, result1); // L1L1L1L1L1L1L1L1 + L2L2L2L2L2L2L2L2L2 = L1L1 L2L2 L1L1 L2L2\n\n  // 2 & 3\n  result0 = zero256;\n  result1 = zero256;\n  begin0 = program->pixel_offset[x + 2];\n  begin1 = program->pixel_offset[x + 3];\n  process_two_pixels_h_float<is_safe>(src, begin0, begin1, current_coeff, filter_size, result0, result1, unaligned_kernel_size);\n  current_coeff += 2 * filter_size;\n  __m256 sumQuad1234 = _mm256_hadd_ps(sumQuad12, _mm256_hadd_ps(result0, result1));\n\n  __m128 result_lo = _mm_add_ps(_mm256_castps256_ps128(sumQuad1234), _mm256_extractf128_ps(sumQuad1234, 1)); // L1 L2 L3 L4\n\n  // 4 & 5\n  result0 = zero256;\n  result1 = zero256;\n  begin0 = program->pixel_offset[x + 4];\n  begin1 = program->pixel_offset[x + 5];\n  process_two_pixels_h_float<is_safe>(src, begin0, begin1, current_coeff, filter_size, result0, result1, unaligned_kernel_size);\n  current_coeff += 2 * filter_size;\n  __m256 sumQuad56 = _mm256_hadd_ps(result0, result1); // L1L1L1L1L1L1L1L1 + L2L2L2L2L2L2L2L2L2 = L1L1 L2L2 L1L1 L2L2\n\n  // 6 & 7\n  result0 = zero256;\n  result1 = zero256;\n  begin0 = program->pixel_offset[x + 6];\n  begin1 = program->pixel_offset[x + 7];\n  process_two_pixels_h_float<is_safe>(src, begin0, begin1, current_coeff, filter_size, result0, result1, unaligned_kernel_size);\n  //current_coeff += 2 * filter_size;\n  __m256 sumQuad5678 = _mm256_hadd_ps(sumQuad56, _mm256_hadd_ps(result0, result1));\n\n  __m128 result_hi = _mm_add_ps(_mm256_castps256_ps128(sumQuad5678), _mm256_extractf128_ps(sumQuad5678, 1)); // L1 L2 L3 L4\n\n  __m256 result256 = _mm256_insertf128_ps(_mm256_castps128_ps256(result_lo), result_hi, 1); // merge result, result_hi\n\n  _mm256_stream_ps(reinterpret_cast<float*>(dst + x), result256); // 8 results at a time\n\n}\n\n// filtersizealigned8: special: 1..4. Generic: -1\ntemplate<int filtersizealigned8>\nstatic void internal_resizer_h_avx2_generic_float(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  AVS_UNUSED(bits_per_pixel);\n  const int filter_size = (filtersizealigned8 >= 1) ? filtersizealigned8 * 8 : program->filter_size;\n  // knowing a quasi-constexpr filter_size from template for commonly used sizes\n  // aligned_filter_size 8, 16, 24, 32 hugely helps compiler optimization\n\n  __m128 zero128 = _mm_setzero_ps();\n  __m256 zero256 = _mm256_setzero_ps();\n  \n  const float* src = (float*)src8;\n  float* dst = (float*)dst8;\n  dst_pitch = dst_pitch / sizeof(float);\n  src_pitch = src_pitch / sizeof(float);\n\n  const int w_safe_mod8 = (program->safelimit_8_pixels.overread_possible ? program->safelimit_8_pixels.source_overread_beyond_targetx : width) / 8 * 8;\n\n  for (int y = 0; y < height; y++) {\n    float* current_coeff_base = program->pixel_coefficient_float;\n\n    // Process safe aligned pixels\n    for (int x = 0; x < w_safe_mod8; x += 8) {\n      process_eight_pixels_h_float<true>(src, x, current_coeff_base, filter_size, zero128, zero256, dst, program);\n    }\n\n    // Process up to the actual kernel size instead of the aligned filter_size to prevent overreading beyond the last source pixel.\n    // We assume extra offset entries were added to the p->pixel_offset array (aligned to 8 during initialization).\n    // This may store 1-7 false pixels, but they are ignored since Avisynth will not read beyond the width.\n    for (int x = w_safe_mod8; x < width; x += 8) {\n      process_eight_pixels_h_float<false>(src, x, current_coeff_base, filter_size, zero128, zero256, dst, program);\n    }\n\n    dst += dst_pitch;\n    src += src_pitch;\n  }\n}\n\n// here we cover filter sizes up to 32 (4x8) efficiently through template specialization\nvoid resizer_h_avx2_generic_float(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  const int filter_size = program->filter_size;\n  assert(program->filter_size_alignment >= 8); // coeffs are float, 8x4 float can be aligned_loaded with AVX2\n\n  if (filter_size == 8)\n    internal_resizer_h_avx2_generic_float<1>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else if (filter_size == 2 * 8)\n    internal_resizer_h_avx2_generic_float<2>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else if (filter_size == 3 * 8)\n    internal_resizer_h_avx2_generic_float<3>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else if (filter_size == 4 * 8)\n    internal_resizer_h_avx2_generic_float<4>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else // -1: basic method, use program->filter_size\n    internal_resizer_h_avx2_generic_float< -1>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\n\n// end of H float\n\n//-------- 256 bit Verticals\n// On x86-32 keep the 1×16 (or 2-lane/16-pixel) kernel\n// On x86-64 use the 2×16 (4-lane/32-pixel) kernel.\n// On 32-bit fewer YMM registers are available, 2x16 kernel causes register pressure issues.\n// 10% performance loss on x86-32 with 2x16 kernel.\n\nstatic void resize_v_avx2_planar_uint8_pix16(BYTE* AVS_RESTRICT dst, const BYTE* src, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel)\n{\n  AVS_UNUSED(bits_per_pixel);\n  int filter_size = program->filter_size;\n  const short* AVS_RESTRICT current_coeff = program->pixel_coefficient;\n  __m256i rounder = _mm256_set1_epi32(1 << (FPScale8bits - 1));\n  __m256i zero = _mm256_setzero_si256();\n\n  const int kernel_size = program->filter_size_real; // not the aligned\n  const int kernel_size_mod2 = (kernel_size / 2) * 2;\n\n  for (int y = 0; y < target_height; y++) {\n    int offset = program->pixel_offset[y];\n    const BYTE* AVS_RESTRICT src_ptr = src + offset * src_pitch;\n\n    // 16 byte 16 pixel\n    // no need wmod16, alignment is safe at least 32\n    for (int x = 0; x < width; x += 16) {\n\n      __m256i result_single_lo = rounder;\n      __m256i result_single_hi = rounder;\n\n      const uint8_t* AVS_RESTRICT src2_ptr = src_ptr + x;\n\n      // Process pairs of rows for better efficiency (2 coeffs/cycle)\n      int i = 0;\n      for (; i < kernel_size_mod2; i += 2) {\n\n        // Load two coefficients as a single packed value and broadcast\n        __m256i coeff = _mm256_set1_epi32(*reinterpret_cast<const int*>(current_coeff + i)); // CO|co|CO|co|CO|co|CO|co   CO|co|CO|co|CO|co|CO|co\n\n        __m256i src_even = _mm256_cvtepu8_epi16(_mm_loadu_si128(reinterpret_cast<const __m128i*>(src2_ptr))); // 16x 8->16bit pixels\n        __m256i src_odd = _mm256_cvtepu8_epi16(_mm_loadu_si128(reinterpret_cast<const __m128i*>(src2_ptr + src_pitch)));  // 16x 8->16bit pixels\n        __m256i src_lo = _mm256_unpacklo_epi16(src_even, src_odd);\n        __m256i src_hi = _mm256_unpackhi_epi16(src_even, src_odd);\n\n        result_single_lo = _mm256_add_epi32(result_single_lo, _mm256_madd_epi16(src_lo, coeff)); // a*b + c\n        result_single_hi = _mm256_add_epi32(result_single_hi, _mm256_madd_epi16(src_hi, coeff)); // a*b + c\n        src2_ptr += 2 * src_pitch;\n      }\n\n      // Process the last odd row if needed\n      for (; i < kernel_size; i++) {\n        // Broadcast a single coefficients\n        __m256i coeff = _mm256_set1_epi16(*reinterpret_cast<const short*>(current_coeff + i)); // 0|co|0|co|0|co|0|co   0|co|0|co|0|co|0|co\n\n        __m256i src_even = _mm256_cvtepu8_epi16(_mm_loadu_si128(reinterpret_cast<const __m128i*>(src2_ptr))); // 16x 8->16bit pixels\n        __m256i src_lo = _mm256_unpacklo_epi16(src_even, zero);\n        __m256i src_hi = _mm256_unpackhi_epi16(src_even, zero);\n        result_single_lo = _mm256_add_epi32(result_single_lo, _mm256_madd_epi16(src_lo, coeff)); // a*b + c\n        result_single_hi = _mm256_add_epi32(result_single_hi, _mm256_madd_epi16(src_hi, coeff)); // a*b + c\n        src2_ptr += src_pitch;\n\n      }\n\n      // scale back, store\n      __m256i result_lo = result_single_lo;\n      __m256i result_hi = result_single_hi;\n      // shift back integer arithmetic 14 bits precision\n      result_lo = _mm256_srai_epi32(result_lo, FPScale8bits);\n      result_hi = _mm256_srai_epi32(result_hi, FPScale8bits);\n\n      __m256i result_2x8x_uint16 = _mm256_packus_epi32(result_lo, result_hi);\n\n      __m128i result128_lo = _mm256_castsi256_si128(result_2x8x_uint16);\n      __m128i result128_hi = _mm256_extractf128_si256(result_2x8x_uint16, 1);\n      __m128i result128 = _mm_packus_epi16(result128_lo, result128_hi);\n      _mm_stream_si128(reinterpret_cast<__m128i*>(dst + x), result128);\n\n    }\n    dst += dst_pitch;\n    current_coeff += filter_size;\n  }\n}\n\nstatic void resize_v_avx2_planar_uint8_pix32(BYTE* AVS_RESTRICT dst, const BYTE* src, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel)\n{\n    AVS_UNUSED(bits_per_pixel);\n    int filter_size = program->filter_size;\n    const short* AVS_RESTRICT current_coeff = program->pixel_coefficient;\n    __m256i rounder = _mm256_set1_epi32(1 << (FPScale8bits - 1));\n    __m256i zero = _mm256_setzero_si256();\n\n    const int kernel_size = program->filter_size_real; // not the aligned\n    const int kernel_size_mod2 = (kernel_size / 2) * 2;\n\n    for (int y = 0; y < target_height; y++) {\n        int offset = program->pixel_offset[y];\n        const BYTE* AVS_RESTRICT src_ptr = src + offset * src_pitch;\n\n        // 32 byte 32 pixel\n        // alignment is safe till 64\n        for (int x = 0; x < width; x += 32) {\n\n            __m256i result_single_lo = rounder;\n            __m256i result_single_hi = rounder;\n\n            __m256i result_single_lo2 = rounder;\n            __m256i result_single_hi2 = rounder;\n\n            const uint8_t* AVS_RESTRICT src2_ptr = src_ptr + x;\n\n            // Process pairs of rows for better efficiency (2 coeffs/cycle)\n            int i = 0;\n            for (; i < kernel_size_mod2; i += 2) {\n\n                // Load two coefficients as a single packed value and broadcast\n                __m256i coeff = _mm256_set1_epi32(*reinterpret_cast<const int*>(current_coeff + i)); // CO|co|CO|co|CO|co|CO|co   CO|co|CO|co|CO|co|CO|co\n\n                __m256i src_even = _mm256_cvtepu8_epi16(_mm_loadu_si128(reinterpret_cast<const __m128i*>(src2_ptr))); // 16x 8->16bit pixels\n                __m256i src_odd = _mm256_cvtepu8_epi16(_mm_loadu_si128(reinterpret_cast<const __m128i*>(src2_ptr + src_pitch)));  // 16x 8->16bit pixels\n\n                __m256i src_even2 = _mm256_cvtepu8_epi16(_mm_loadu_si128(reinterpret_cast<const __m128i*>(src2_ptr + 16))); // 16x 8->16bit pixels\n                __m256i src_odd2 = _mm256_cvtepu8_epi16(_mm_loadu_si128(reinterpret_cast<const __m128i*>(src2_ptr + src_pitch + 16)));  // 16x 8->16bit pixels\n\n\n                __m256i src_lo = _mm256_unpacklo_epi16(src_even, src_odd);\n                __m256i src_hi = _mm256_unpackhi_epi16(src_even, src_odd);\n\n                __m256i src_lo2 = _mm256_unpacklo_epi16(src_even2, src_odd2);\n                __m256i src_hi2 = _mm256_unpackhi_epi16(src_even2, src_odd2);\n\n\n                result_single_lo = _mm256_add_epi32(result_single_lo, _mm256_madd_epi16(src_lo, coeff)); // a*b + c\n                result_single_hi = _mm256_add_epi32(result_single_hi, _mm256_madd_epi16(src_hi, coeff)); // a*b + c\n\n                result_single_lo2 = _mm256_add_epi32(result_single_lo2, _mm256_madd_epi16(src_lo2, coeff)); // a*b + c\n                result_single_hi2 = _mm256_add_epi32(result_single_hi2, _mm256_madd_epi16(src_hi2, coeff)); // a*b + c\n\n                src2_ptr += 2 * src_pitch;\n            }\n\n            // Process the last odd row if needed\n            for (; i < kernel_size; i++) {\n                // Broadcast a single coefficients\n                __m256i coeff = _mm256_set1_epi16(*reinterpret_cast<const short*>(current_coeff + i)); // 0|co|0|co|0|co|0|co   0|co|0|co|0|co|0|co\n\n                __m256i src_even = _mm256_cvtepu8_epi16(_mm_loadu_si128(reinterpret_cast<const __m128i*>(src2_ptr))); // 16x 8->16bit pixels\n\n                __m256i src_even2 = _mm256_cvtepu8_epi16(_mm_loadu_si128(reinterpret_cast<const __m128i*>(src2_ptr + 16))); // 16x 8->16bit pixels\n\n                __m256i src_lo = _mm256_unpacklo_epi16(src_even, zero);\n                __m256i src_hi = _mm256_unpackhi_epi16(src_even, zero);\n\n                __m256i src_lo2 = _mm256_unpacklo_epi16(src_even2, zero);\n                __m256i src_hi2 = _mm256_unpackhi_epi16(src_even2, zero);\n\n                result_single_lo = _mm256_add_epi32(result_single_lo, _mm256_madd_epi16(src_lo, coeff)); // a*b + c\n                result_single_hi = _mm256_add_epi32(result_single_hi, _mm256_madd_epi16(src_hi, coeff)); // a*b + c\n\n                result_single_lo2 = _mm256_add_epi32(result_single_lo2, _mm256_madd_epi16(src_lo2, coeff)); // a*b + c\n                result_single_hi2 = _mm256_add_epi32(result_single_hi2, _mm256_madd_epi16(src_hi2, coeff)); // a*b + c\n\n                src2_ptr += src_pitch;\n\n            }\n\n            // scale back, store\n            __m256i result_lo = result_single_lo;\n            __m256i result_hi = result_single_hi;\n\n            __m256i result_lo2 = result_single_lo2;\n            __m256i result_hi2 = result_single_hi2;\n\n\n            // shift back integer arithmetic 14 bits precision\n            result_lo = _mm256_srai_epi32(result_lo, FPScale8bits);\n            result_hi = _mm256_srai_epi32(result_hi, FPScale8bits);\n\n            result_lo2 = _mm256_srai_epi32(result_lo2, FPScale8bits);\n            result_hi2 = _mm256_srai_epi32(result_hi2, FPScale8bits);\n\n            __m256i result_2x8x_uint16 = _mm256_packus_epi32(result_lo, result_hi);\n\n            __m256i result_2x8x_uint16_2 = _mm256_packus_epi32(result_lo2, result_hi2);\n\n            __m128i result128_lo = _mm256_castsi256_si128(result_2x8x_uint16);\n            __m128i result128_hi = _mm256_extractf128_si256(result_2x8x_uint16, 1);\n            __m128i result128 = _mm_packus_epi16(result128_lo, result128_hi);\n\n            __m128i result128_lo2 = _mm256_castsi256_si128(result_2x8x_uint16_2);\n            __m128i result128_hi2 = _mm256_extractf128_si256(result_2x8x_uint16_2, 1);\n            __m128i result128_2 = _mm_packus_epi16(result128_lo2, result128_hi2);\n\n\n            _mm_stream_si128(reinterpret_cast<__m128i*>(dst + x), result128);\n            _mm_stream_si128(reinterpret_cast<__m128i*>(dst + x + 16), result128_2);\n\n        }\n        dst += dst_pitch;\n        current_coeff += filter_size;\n    }\n}\n\n#if defined(X86_64)\nstatic void resize_v_avx2_planar_impl(BYTE* dst8, const BYTE* src, int dst_pitch, int src_pitch,\n  ResamplingProgram* program, int width, int target_height, int bits_per_pixel)\n{\n  resize_v_avx2_planar_uint8_pix32(dst8, src, dst_pitch, src_pitch, program, width, target_height, bits_per_pixel);\n}\n#elif defined(X86_32)\nstatic void resize_v_avx2_planar_impl(BYTE* dst8, const BYTE* src, int dst_pitch, int src_pitch,\n  ResamplingProgram* program, int width, int target_height, int bits_per_pixel)\n{\n  resize_v_avx2_planar_uint8_pix16(dst8, src, dst_pitch, src_pitch, program, width, target_height, bits_per_pixel);\n}\n#else\n#error Unsupported target for resize_v_avx2_planar_uint8_t\n#endif\n\nvoid resize_v_avx2_planar_uint8_t(BYTE* dst8, const BYTE* src, int dst_pitch, int src_pitch,\n  ResamplingProgram* program, int width, int target_height, int bits_per_pixel)\n{\n  resize_v_avx2_planar_impl(dst8, src, dst_pitch, src_pitch, program, width, target_height, bits_per_pixel);\n}\n\n\ntemplate<bool lessthan16bit>\nvoid resize_v_avx2_planar_uint16_t(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel)\n{\n  int filter_size = program->filter_size;\n  const short* AVS_RESTRICT current_coeff = program->pixel_coefficient;\n\n  const __m256i zero = _mm256_setzero_si256();\n\n  // for 16 bits only\n  const __m256i shifttosigned = _mm256_set1_epi16(-32768);\n  const __m256i shiftfromsigned = _mm256_set1_epi32(32768 << FPScale16bits);\n\n  const __m256i rounder = _mm256_set1_epi32(1 << (FPScale16bits - 1));\n\n  const uint16_t* src = (uint16_t*)src8;\n  uint16_t* AVS_RESTRICT dst = (uint16_t* AVS_RESTRICT)dst8;\n  dst_pitch = dst_pitch / sizeof(uint16_t);\n  src_pitch = src_pitch / sizeof(uint16_t);\n\n  const int kernel_size = program->filter_size_real; // not the aligned\n  const int kernel_size_mod2 = (kernel_size / 2) * 2;\n\n  const int limit = (1 << bits_per_pixel) - 1;\n  __m256i clamp_limit = _mm256_set1_epi16((short)limit); // clamp limit for <16 bits\n\n  for (int y = 0; y < target_height; y++) {\n    int offset = program->pixel_offset[y];\n    const uint16_t* src_ptr = src + offset * src_pitch;\n\n    // 32 byte 16 word\n    // no need wmod16, alignment is safe at least 32\n\n    for (int x = 0; x < width; x += 16) {\n\n      __m256i result_single_lo = rounder;\n      __m256i result_single_hi = rounder;\n\n      const uint16_t* AVS_RESTRICT src2_ptr = src_ptr + x;\n\n      // Process pairs of rows for better efficiency (2 coeffs/cycle)\n      int i = 0;\n      for (; i < kernel_size_mod2; i += 2) {\n        // Load two coefficients as a single packed value and broadcast\n        __m256i coeff = _mm256_set1_epi32(*reinterpret_cast<const int*>(current_coeff + i)); // CO|co|CO|co|CO|co|CO|co   CO|co|CO|co|CO|co|CO|co\n\n        __m256i src_even = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(src2_ptr)); // 16x 16bit pixels\n        __m256i src_odd = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(src2_ptr + src_pitch));  // 16x 16bit pixels\n        if constexpr (!lessthan16bit) {\n          src_even = _mm256_add_epi16(src_even, shifttosigned);\n          src_odd = _mm256_add_epi16(src_odd, shifttosigned);\n        }\n        __m256i src_lo = _mm256_unpacklo_epi16(src_even, src_odd);\n        __m256i src_hi = _mm256_unpackhi_epi16(src_even, src_odd);\n\n        result_single_lo = _mm256_add_epi32(result_single_lo, _mm256_madd_epi16(src_lo, coeff)); // a*b + c\n        result_single_hi = _mm256_add_epi32(result_single_hi, _mm256_madd_epi16(src_hi, coeff)); // a*b + c\n\n        src2_ptr += 2 * src_pitch;\n      }\n\n      // Process the last odd row if needed\n      for (; i < kernel_size; i++) {\n        // Broadcast a single coefficients\n        __m256i coeff = _mm256_set1_epi16(current_coeff[i]); // 0|co|0|co|0|co|0|co   0|co|0|co|0|co|0|co\n\n        __m256i src_even = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(src2_ptr)); // 16x 16bit pixels\n        if constexpr (!lessthan16bit) {\n          src_even = _mm256_add_epi16(src_even, shifttosigned);\n        }\n        __m256i src_lo = _mm256_unpacklo_epi16(src_even, zero);\n        __m256i src_hi = _mm256_unpackhi_epi16(src_even, zero);\n        result_single_lo = _mm256_add_epi32(result_single_lo, _mm256_madd_epi16(src_lo, coeff)); // a*b + c\n        result_single_hi = _mm256_add_epi32(result_single_hi, _mm256_madd_epi16(src_hi, coeff)); // a*b + c\n\n        src2_ptr += src_pitch;\n      }\n\n      // correct if signed, scale back, store\n      __m256i result_lo = result_single_lo;\n      __m256i result_hi = result_single_hi;\n      if constexpr (!lessthan16bit) {\n        result_lo = _mm256_add_epi32(result_lo, shiftfromsigned);\n        result_hi = _mm256_add_epi32(result_hi, shiftfromsigned);\n      }\n      // shift back integer arithmetic 13 bits precision\n      result_lo = _mm256_srai_epi32(result_lo, FPScale16bits);\n      result_hi = _mm256_srai_epi32(result_hi, FPScale16bits);\n\n      __m256i result_2x8x_uint16 = _mm256_packus_epi32(result_lo, result_hi);\n      if constexpr (lessthan16bit) {\n        result_2x8x_uint16 = _mm256_min_epu16(result_2x8x_uint16, clamp_limit); // extra clamp for 10-14 bit\n      }\n      _mm256_stream_si256(reinterpret_cast<__m256i*>(dst + x), result_2x8x_uint16);\n\n    }\n\n    dst += dst_pitch;\n    current_coeff += filter_size;\n  }\n}\n\n//-------- 256 bit float Verticals\n\nvoid resize_v_avx2_planar_float(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel)\n{\n  AVS_UNUSED(bits_per_pixel);\n\n  const int filter_size = program->filter_size;\n  const float* AVS_RESTRICT current_coeff = program->pixel_coefficient_float;\n\n  const float* src = (const float*)src8;\n  float* AVS_RESTRICT dst = (float*)dst8;\n  dst_pitch = dst_pitch / sizeof(float);\n  src_pitch = src_pitch / sizeof(float);\n\n  const int kernel_size = program->filter_size_real; // not the aligned\n  const int kernel_size_mod2 = (kernel_size / 2) * 2; // Process pairs of rows for better efficiency\n  const bool notMod2 = kernel_size_mod2 < kernel_size;\n\n  for (int y = 0; y < target_height; y++) {\n    int offset = program->pixel_offset[y];\n    const float* src_ptr = src + offset * src_pitch;\n\n    // 32 byte 8 floats (AVX2 register holds 8 floats)\n    // no need for wmod8, alignment is safe 32 bytes at least\n    for (int x = 0; x < width; x += 8) {\n      __m256 result_single = _mm256_setzero_ps();\n      __m256 result_single_2 = _mm256_setzero_ps();\n\n      const float* AVS_RESTRICT src2_ptr = src_ptr + x; // __restrict here\n\n      // Process pairs of rows for better efficiency (2 coeffs/cycle)\n      // two result variables for potential parallel operation\n      int i = 0;\n      for (; i < kernel_size_mod2; i += 2) {\n        __m256 coeff_even = _mm256_set1_ps(current_coeff[i]);\n        __m256 coeff_odd = _mm256_set1_ps(current_coeff[i + 1]);\n\n        __m256 src_even = _mm256_loadu_ps(src2_ptr);\n        __m256 src_odd = _mm256_loadu_ps(src2_ptr + src_pitch);\n\n        result_single = _mm256_fmadd_ps(src_even, coeff_even, result_single);\n        result_single_2 = _mm256_fmadd_ps(src_odd, coeff_odd, result_single_2);\n\n        src2_ptr += 2 * src_pitch;\n      }\n\n      result_single = _mm256_add_ps(result_single, result_single_2);\n\n      // Process the last odd row if needed\n      if (notMod2) {\n        __m256 coeff = _mm256_set1_ps(current_coeff[i]);\n        __m256 src_val = _mm256_loadu_ps(src2_ptr);\n        result_single = _mm256_fmadd_ps(src_val, coeff, result_single);\n      }\n\n      _mm256_stream_ps(dst + x, result_single);\n    }\n\n    dst += dst_pitch;\n    current_coeff += filter_size;\n  }\n}\n\n// Memory-transfer optimized version of resize_v_avx2_planar_float\nvoid resize_v_avx2_planar_float_w_sr(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel)\n{\n  AVS_UNUSED(bits_per_pixel);\n\n  const int filter_size = program->filter_size;\n  const float* AVS_RESTRICT current_coeff = program->pixel_coefficient_float;\n\n  const float* src = (const float*)src8;\n  float* AVS_RESTRICT dst = (float*)dst8;\n  dst_pitch = dst_pitch / sizeof(float);\n  src_pitch = src_pitch / sizeof(float);\n\n  const int kernel_size = program->filter_size_real; // not the aligned\n  const int kernel_size_mod2 = (kernel_size / 2) * 2; // Process pairs of rows for better efficiency\n  const bool notMod2 = kernel_size_mod2 < kernel_size;\n\n  const int width_mod32 = (width / 32) * 32;\n\n  for (int y = 0; y < target_height; y++) {\n    int offset = program->pixel_offset[y];\n    const float* src_ptr = src + offset * src_pitch;\n    // Part #1: process 32 floats at a time\n    // Optimize for memory throughput: process 32 floats (4x256bit) in parallel\n    // Process by 4x 256bit (8 x 8 floats) to make memory read/write linear streams\n    // longer, 16x256 bit registers in 64bit mode should be enough\n    for (int x = 0; x < width_mod32; x += 32) {\n      __m256 result_1 = _mm256_setzero_ps();\n      __m256 result_2 = _mm256_setzero_ps();\n      __m256 result_3 = _mm256_setzero_ps();\n      __m256 result_4 = _mm256_setzero_ps();\n\n      const float* AVS_RESTRICT src2_ptr = src_ptr + x; // __restrict here\n      // single coeffs/cycle, but 32 floats processed in parallel\n      for (int i = 0; i < kernel_size; i++) {\n        // coefs are equal for all H-samples\n        __m256 coeff = _mm256_set1_ps(current_coeff[i]);\n\n        // source always aligned in V-resizers\n        __m256 src_1 = _mm256_load_ps(src2_ptr);\n        __m256 src_2 = _mm256_load_ps(src2_ptr + 8);\n        __m256 src_3 = _mm256_load_ps(src2_ptr + 16);\n        __m256 src_4 = _mm256_load_ps(src2_ptr + 24);\n\n        result_1 = _mm256_fmadd_ps(src_1, coeff, result_1);\n        result_2 = _mm256_fmadd_ps(src_2, coeff, result_2);\n        result_3 = _mm256_fmadd_ps(src_3, coeff, result_3);\n        result_4 = _mm256_fmadd_ps(src_4, coeff, result_4);\n\n        src2_ptr += src_pitch;\n      }\n      // here we use stream instead of store; in multithreading stream is better;\n      // consider two templated versions if needed depending on actual MT usage\n      _mm256_stream_ps(dst + x, result_1);\n      _mm256_stream_ps(dst + x + 8, result_2);\n      _mm256_stream_ps(dst + x + 16, result_3);\n      _mm256_stream_ps(dst + x + 24, result_4);\n    } // width_mod32\n\n    // Part #2: process remaining. 32 byte 8 floats (AVX2 register holds 8 floats)\n    // From now on the old resize_v_avx2_planar_float, starting at width_mod32.\n\n    // No need for wmod8, scanline alignment is safe 32 bytes at least (really 64)\n    for (int x = width_mod32; x < width; x += 8) {\n      __m256 result_single = _mm256_setzero_ps();\n      __m256 result_single_2 = _mm256_setzero_ps();\n\n      const float* AVS_RESTRICT src2_ptr = src_ptr + x; // __restrict here\n\n      // Process pairs of rows for better efficiency (2 coeffs/cycle)\n      // two result variables for potential parallel operation\n      int i = 0;\n      for (; i < kernel_size_mod2; i += 2) {\n        __m256 coeff_even = _mm256_set1_ps(current_coeff[i]);\n        __m256 coeff_odd = _mm256_set1_ps(current_coeff[i + 1]);\n\n        __m256 src_even = _mm256_load_ps(src2_ptr);\n        __m256 src_odd = _mm256_load_ps(src2_ptr + src_pitch);\n\n        result_single = _mm256_fmadd_ps(src_even, coeff_even, result_single);\n        result_single_2 = _mm256_fmadd_ps(src_odd, coeff_odd, result_single_2);\n\n        src2_ptr += 2 * src_pitch;\n      }\n\n      result_single = _mm256_add_ps(result_single, result_single_2);\n\n      // Process the last odd row if needed\n      if (notMod2) {\n        __m256 coeff = _mm256_set1_ps(current_coeff[i]);\n        __m256 src_val = _mm256_load_ps(src2_ptr);\n        result_single = _mm256_fmadd_ps(src_val, coeff, result_single);\n      }\n\n      _mm256_stream_ps(dst + x, result_single);\n    }\n\n    dst += dst_pitch;\n    current_coeff += filter_size;\n  }\n}\n\n// avx2 16bit\ntemplate void resizer_h_avx2_generic_uint16_t<false>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n// avx2 10-14bit\ntemplate void resizer_h_avx2_generic_uint16_t<true>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\n\n\n// avx2 16\ntemplate void resize_v_avx2_planar_uint16_t<false>(BYTE* dst0, const BYTE* src0, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel);\n// avx2 10-14bit\ntemplate void resize_v_avx2_planar_uint16_t<true>(BYTE* dst0, const BYTE* src0, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel);\n\n\n\n// Helper for horizontal resampling 32 bit float\n// Safe dual lane partial load with AVX\n// Read exactly N pixels, avoiding\n// - reading beyond the end of the source buffer.\n// - avoid NaN contamination, since event with zero coefficients NaN * 0 = NaN\ntemplate <int Nmod4>\nAVS_FORCEINLINE static __m256 _mm256_load_partial_safe_2_m128(const float* src_ptr_offsetted1, const float* src_ptr_offsetted2) {\n  __m128 s1;\n  __m128 s2;\n  switch (Nmod4) {\n  case 1:\n    s1 = _mm_set_ps(0.0f, 0.0f, 0.0f, src_ptr_offsetted1[0]);\n    s2 = _mm_set_ps(0.0f, 0.0f, 0.0f, src_ptr_offsetted2[0]);\n    // ideally: movss\n    break;\n  case 2:\n    s1 = _mm_set_ps(0.0f, 0.0f, src_ptr_offsetted1[1], src_ptr_offsetted1[0]);\n    s2 = _mm_set_ps(0.0f, 0.0f, src_ptr_offsetted2[1], src_ptr_offsetted2[0]);\n    // ideally: movsd\n    break;\n  case 3:\n    s1 = _mm_set_ps(0.0f, src_ptr_offsetted1[2], src_ptr_offsetted1[1], src_ptr_offsetted1[0]);\n    s2 = _mm_set_ps(0.0f, src_ptr_offsetted2[2], src_ptr_offsetted2[1], src_ptr_offsetted2[0]);\n    // ideally: movss + movsd + shuffle or movsd + insert\n    break;\n  case 0:\n    s1 = _mm_set_ps(src_ptr_offsetted1[3], src_ptr_offsetted1[2], src_ptr_offsetted1[1], src_ptr_offsetted1[0]);\n    s2 = _mm_set_ps(src_ptr_offsetted2[3], src_ptr_offsetted2[2], src_ptr_offsetted2[1], src_ptr_offsetted2[0]);\n    // ideally: movups\n    break;\n  default:\n    s1 = _mm_setzero_ps(); // n/a cannot happen\n    s2 = _mm_setzero_ps();\n  }\n  return _mm256_set_m128(s2, s1);\n}\n\n\n// Processes a horizontal resampling kernel of up to four coefficients for float pixel types.\n// Supports BilinearResize, BicubicResize, or sinc with up to 2 taps (filter size <= 4).\n// Loads and processes four float coefficients and eight pixels simultaneously.\n// The 'filtersizemod4' template parameter (0-3) helps optimize for different filter sizes modulo 4.\n\n// this is a generic varsion for small kernels up to 4 taps, regardless of up or down scaling\n// Note: there is a further optimized version of ks4 resampler, which combines gather or permutex.\ntemplate<int filtersizemod4>\nvoid resize_h_planar_float_avx_transpose_vstripe_ks4(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  assert(filtersizemod4 >= 0 && filtersizemod4 <= 3);\n\n  const int filter_size = program->filter_size; // aligned, practically the coeff table stride\n\n  src_pitch /= sizeof(float);\n  dst_pitch /= sizeof(float);\n\n  float* src = (float*)src8;\n  float* dst = (float*)dst8;\n\n  const float* AVS_RESTRICT current_coeff = (const float* AVS_RESTRICT)program->pixel_coefficient_float;\n\n  constexpr int PIXELS_AT_A_TIME = 8; // Process eight pixels in parallel using AVX2 (2x4 using m128 lanes)\n\n  // 'source_overread_beyond_targetx' indicates if the filter kernel can read beyond the target width.\n  // Even if the filter alignment allows larger reads, our safety boundary for unaligned loads starts at 4 pixels back\n  // from the target width, as we load 4 floats at once with '_mm_loadu_ps'.\n  const int width_safe_mod = (program->safelimit_4_pixels.overread_possible ? program->safelimit_4_pixels.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  // Preconditions:\n  assert(program->filter_size_real <= 4); // We preload all relevant coefficients (up to 4) before the height loop.\n\n  // 'target_size_alignment' ensures we can safely access coefficients using offsets like\n  // 'filter_size * 7' when processing 8 H pixels at a time or\n  // 'filter_size * 15' when processing 16 H pixels at a time\n  assert(program->target_size_alignment >= 8);\n\n  // Ensure that coefficient loading beyond the valid target size is safe for 4x4 float loads.\n  assert(program->filter_size_alignment >= 4);\n\n  int x = 0;\n\n  // This 'auto' lambda construct replaces the need of templates\n  auto do_h_float_core = [&](auto partial_load) {\n    // Load up to 2x4 coefficients at once before the height loop.\n    // Pre-loading and transposing coefficients keeps register usage efficient.\n    // Assumes 'filter_size_aligned' is at least 4.\n\n    // Coefficients for the source pixel offset (for src_ptr + begin1 [0..3] and for src_ptr + begin5 [0..3] )\n    __m256 coef_1_coef_5 = _mm256_load_2_m128(current_coeff + filter_size * 0, current_coeff + filter_size * 4);\n    __m256 coef_2_coef_6 = _mm256_load_2_m128(current_coeff + filter_size * 1, current_coeff + filter_size * 5);\n    __m256 coef_3_coef_7 = _mm256_load_2_m128(current_coeff + filter_size * 2, current_coeff + filter_size * 6);\n    __m256 coef_4_coef_8 = _mm256_load_2_m128(current_coeff + filter_size * 3, current_coeff + filter_size * 7);\n\n    _MM_TRANSPOSE8_LANE4_PS(coef_1_coef_5, coef_2_coef_6, coef_3_coef_7, coef_4_coef_8);\n\n    float* AVS_RESTRICT dst_ptr = dst + x;\n    const float* src_ptr = src;\n\n    // Pixel offsets for the current target x-positions.\n    // Even for x >= width, these offsets are guaranteed to be within the allocated 'target_size_alignment'.\n    const int begin1 = program->pixel_offset[x + 0];\n    const int begin2 = program->pixel_offset[x + 1];\n    const int begin3 = program->pixel_offset[x + 2];\n    const int begin4 = program->pixel_offset[x + 3];\n    const int begin5 = program->pixel_offset[x + 4];\n    const int begin6 = program->pixel_offset[x + 5];\n    const int begin7 = program->pixel_offset[x + 6];\n    const int begin8 = program->pixel_offset[x + 7];\n\n    for (int y = 0; y < height; y++)\n    {\n      __m256 data_1_data_5;\n      __m256 data_2_data_6;\n      __m256 data_3_data_7;\n      __m256 data_4_data_8;\n\n      if constexpr (partial_load) {\n        // In the potentially unsafe zone (near the right edge of the image), we use a safe loading function\n        // to prevent reading beyond the allocated source scanline. This handles cases where loading 4 floats\n        // starting from 'src_ptr + beginX' might exceed the source buffer.\n\n        // Example of the unsafe scenario: If target width is 320, a naive load at src_ptr + 317\n        // would attempt to read floats at indices 317, 318, 319, and 320, potentially going out of bounds.\n\n        // Two main issues in the unsafe zone:\n        // 1.) Out-of-bounds memory access: Reading beyond the allocated memory for the source scanline can\n        //     lead to access violations and crashes. '_mm_loadu_ps' attempts to load 16 bytes, so even if\n        //     the starting address is within bounds, subsequent reads might not be.\n        // 2.) Garbage or NaN values: Even if a read doesn't cause a crash, accessing uninitialized or\n        //     out-of-bounds memory (especially for float types) can result in garbage data, including NaN.\n        //     Multiplying by a valid coefficient and accumulating this NaN can contaminate the final result.\n\n        // '_mm256_load_partial_safe_2_m128' safely loads up to 'filter_size_real' pixels and pads with zeros if needed,\n        // preventing out-of-bounds reads and ensuring predictable results even near the image edges.\n\n        data_1_data_5 = _mm256_load_partial_safe_2_m128<filtersizemod4>(src_ptr + begin1, src_ptr + begin5);\n        data_2_data_6 = _mm256_load_partial_safe_2_m128<filtersizemod4>(src_ptr + begin2, src_ptr + begin6);\n        data_3_data_7 = _mm256_load_partial_safe_2_m128<filtersizemod4>(src_ptr + begin3, src_ptr + begin7);\n        data_4_data_8 = _mm256_load_partial_safe_2_m128<filtersizemod4>(src_ptr + begin4, src_ptr + begin8);\n      }\n      else {\n        // In the safe zone, we can directly load 4 pixels at a time using unaligned loads.\n        data_1_data_5 = _mm256_loadu_2_m128(src_ptr + begin1, src_ptr + begin5);\n        data_2_data_6 = _mm256_loadu_2_m128(src_ptr + begin2, src_ptr + begin6);\n        data_3_data_7 = _mm256_loadu_2_m128(src_ptr + begin3, src_ptr + begin7);\n        data_4_data_8 = _mm256_loadu_2_m128(src_ptr + begin4, src_ptr + begin8);\n      }\n\n      _MM_TRANSPOSE8_LANE4_PS(data_1_data_5, data_2_data_6, data_3_data_7, data_4_data_8);\n\n      // two sets, hint for the compiler to allow parallel fma's\n      __m256 result_0 = _mm256_mul_ps(data_1_data_5, coef_1_coef_5);\n      __m256 result_1 = _mm256_mul_ps(data_2_data_6, coef_2_coef_6);\n      result_0 = _mm256_fmadd_ps(data_3_data_7, coef_3_coef_7, result_0);\n      result_1 = _mm256_fmadd_ps(data_4_data_8, coef_4_coef_8, result_1);\n\n      _mm256_stream_ps(dst_ptr, _mm256_add_ps(result_0, result_1));\n\n      dst_ptr += dst_pitch;\n      src_ptr += src_pitch;\n    } // y\n    current_coeff += filter_size * 8; // Move to the next set of coefficients for the next 8 output pixels\n    }; // end of lambda\n\n  // Process the 'safe zone' where direct full unaligned loads are acceptable.\n  for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)\n  {\n    do_h_float_core(std::false_type{}); // partial_load == false, use direct _mm_loadu_ps\n  }\n\n  // Process the potentially 'unsafe zone' near the image edge, using safe loading.\n  for (; x < width; x += PIXELS_AT_A_TIME)\n  {\n    do_h_float_core(std::true_type{}); // partial_load == true, use the safer '_mm256_load_partial_safe_2_m128'\n  }\n}\n\n// Instantiate them\ntemplate void resize_h_planar_float_avx_transpose_vstripe_ks4<0>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resize_h_planar_float_avx_transpose_vstripe_ks4<1>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resize_h_planar_float_avx_transpose_vstripe_ks4<2>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resize_h_planar_float_avx_transpose_vstripe_ks4<3>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\n\n/**\n * resize_h_planar_float_avx2_gather_permutex_vstripe_ks4 with per-frame check or\n * distinct checker, gather, permutex methods\n *\n * AVX2-optimized horizontal resampler for float planar images with small kernel sizes (filter_size_real <= 4).\n * Supports both upsampling and downsampling scenarios, automatically selecting the most efficient SIMD strategy.\n * (For larger kernels, use resizer_h_avx2_generic_float or other specialized functions.)\n *\n * Algorithm:\n *   - Analyzes the resampling program's pixel offset pattern to choose between two SIMD strategies.\n *     The upsampling scenario is divided into sub-cases, and the decision is made by analyzing the pixel offset pattern in the resampling program.\n *     The code checks, for each group of 8 output pixels, how far apart the corresponding source pixel offsets are.\n *\n *     If the span of source pixels (end_off - start_off) plus the kernel size (max filter_size_real - 1, that is 3)\n *     exceeds 8, it goes to gather based method: the required source pixels are not all within a single 8-float block.\n *\n *     If the span is <= 8, the function can use a single 8-float block load and permute (which is faster).\n *\n *     For \"high upsampling ratio\" (output much larger than input, so output pixels are close together in input),\n *     the offsets are usually contiguous, and the permute-transpose path is used.\n *\n *     1. Gather-based: For downsampling (or no-resize convolution) or non-contiguous pixel offsets, uses AVX2\n *        gather instructions to fetch each required source pixel.\n *     2. Permutex-based: For upsampling or contiguous pixel offsets, loads a block of 8 source floats and uses\n *        AVX2 permute instructions for fast access.\n *\n *   - Handles edge cases and buffer boundaries safely, using partial loads to avoid out-of-bounds memory access.\n *   - Processes 8 output pixels in parallel for high throughput.\n *\n * Assumes that resampling program provides sufficient alignment and padding for safe SIMD loads.\n *\n * Typical dispatcher usage:\n *   switch (program->filter_size_real) {\n *     case 1: return resize_h_planar_float_avx2_gather_permutex_vstripe_ks4<1>;\n *     case 2: return resize_h_planar_float_avx2_gather_permutex_vstripe_ks4<2>;\n *     case 3: return resize_h_planar_float_avx2_gather_permutex_vstripe_ks4<3>;\n *     case 4: return resize_h_planar_float_avx2_gather_permutex_vstripe_ks4<0>;\n *     default: return resizer_h_avx2_generic_float;\n *   }\n *\n * See also:\n * - resize_h_planar_float_avx2_transpose_vstripe_ks4\n * - resize_h_planar_float_avx2_permutex_vstripe_ks4\n * - resize_h_planar_float_avx_transpose_vstripe_ks4\n * - resizer_h_avx2_generic_float\n \n */\n\n// Test script for the ks<=4 gather/permutex horizontal, float resampler cases\n/*\nSetMaxCPU(\"AVX2\")\nBlankClip(width=640, height=480, pixel_type=\"YUV444PS\")\n#BlankClip(width=640-1, height=480, pixel_type=\"YUV444PS\") # -1 to -7 to test partial loads\nExpr(\"sx 2 % 1.0 * \", \"0\", \"0\") # vertical stripes\nBicubicResize(width*2,height) # permute, H kernel size 4\nor\nLanczosResize(width*2, height, taps=1) # permute, H kernel size 2\nor\nLanczosResize(int(width*0.5), height, taps=1) # gather, H kernel size 4\nor\nBilinearResize(int(width*0.97), height) # gather, H kernel size 3\n*/\n\n/*\n * Analyse input resampling program to select method of processing.\n * \n * This check determines whether the AVX2 permutex optimization is valid for a block of 8 output pixels.\n * In the permutex path, we load 8 consecutive source floats starting at program->pixel_offset[x + 0] ('begin1').\n * Each output pixel's convolution window is indexed using perm_0..perm_3, which are offsets relative to begin1.\n * These permutation indices span from begin1 (program->pixel_offset[x + 0]) up to begin8 + 3 (program->pixel_offset[x + 7] + 3).\n * For the permute to be safe, ALL indices accessed (from begin1 to begin8 + 3) must fit within the loaded 8-float block.\n * This is guaranteed if (program->pixel_offset[x + 7] + 3 - program->pixel_offset[x + 0]) < 8.\n * In order the check work for the right edge, pixel_offset entries padded till target_size_aligned must repeat the last\n * valid offset, and not 0 (see in resize_prepare_coeffs).\n * \n * If the span is not in the 0-7 range, some required source pixels for the convolution will fall outside\n * the loaded block, and the permutex method cannot be used; we must fall back to gather.\n * This logic relies on the assumption that pixel_offset[] is strictly increasing (or non-decreasing).\n * We check the maximum index accessed by the permutation logic, and since we use a fixed 4 coefficients\n * per output pixel, not just the filter_size_real, we add 3 to the last offset.\n * \n * It is ensured during the resampling program setup (resize_prepare_coeffs) that pixel_offsets will\n * not only contain valid source offsets, but so that (pixel_offsets[x] + filter_size_real - 1) still\n * indexes valid source pixels.\n * On the right side of the image, this means that the end-of-line coefficients are shifted leftwards\n * during the pre-calculation so that the filter kernel will never read beyond the coefficient array\n * nor past the source buffer.\n * Out of bounds target pixels coefficients are padded with zeros up to program->filter_size_alignment.\n*/\n\n// resize_h_planar_float_avx2_xxx_vstripe_ks4 method #1: gather-based\ntemplate<int filtersizemod4>\nvoid resize_h_planar_float_avx2_transpose_vstripe_ks4(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)\n{\n  assert(filtersizemod4 >= 0 && filtersizemod4 <= 3);\n\n  const int filter_size = program->filter_size; // aligned, practically the coeff table stride\n\n  src_pitch /= sizeof(float);\n  dst_pitch /= sizeof(float);\n\n  float* src = (float*)src8;\n  float* dst = (float*)dst8;\n\n  constexpr int PIXELS_AT_A_TIME = 8; // Process eight pixels in parallel using AVX2 (2x4 using m128 lanes)\n\n  // 'source_overread_beyond_targetx' indicates if the filter kernel can read beyond the target width.\n  // Even if the filter alignment allows larger reads, our safety boundary for unaligned loads starts at 4 pixels back\n  // from the target width, as we load 4 floats at once with '_mm_loadu_ps'.\n  // So contrary to the 8-pixel-at-a-time fact, we only require safety for 4 pixels at a time here.\n  const int width_safe_mod = (program->safelimit_4_pixels.overread_possible ? program->safelimit_4_pixels.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  // Preconditions:\n  assert(program->filter_size_real <= 4); // We preload all relevant coefficients (up to 4) before the height loop.\n  // this goes to filtersizemod4 template parameter from 0 to 3\n\n  // 'target_size_alignment' ensures we can safely access coefficients using offsets like\n  // 'filter_size * 7', and pixel_offsets[x to x + 7] when processing 8 H pixels at a time\n  assert(program->target_size_alignment >= 8);\n\n  // Ensure that coefficient loading beyond the valid target size is safe for 4x4 float loads.\n  assert(program->filter_size_alignment >= 4);\n\n  // Split to H-stripes to make better source data locality in L2 cache (if L2 present per core ?)\n  constexpr int STRIPE_ALIGN = 8;  // this must be multiple of PIXELS_AT_A_TIME \n\n  //max_scanlines = program->target_size; // test\n  int max_scanlines = program->max_scanlines / STRIPE_ALIGN * STRIPE_ALIGN;\n  if (max_scanlines < STRIPE_ALIGN) max_scanlines = STRIPE_ALIGN;\n\n  for (auto y_from = 0; y_from < height; y_from += max_scanlines) {\n    size_t y_to = std::min(y_from + max_scanlines, height);\n\n    // Reset current_coeff for the start of the stripe\n    const float* AVS_RESTRICT current_coeff = program->pixel_coefficient_float; // +iYstart * filter_size;\n\n    int x = 0;\n\n    // This 'auto' lambda construct replaces the need of templates\n    auto do_h_float_core = [&](auto partial_load) {\n      // Load up to 2x4 coefficients at once before the height loop.\n      // Pre-loading and transposing coefficients keeps register usage efficient.\n      // Assumes 'filter_size_aligned' is at least 4.\n\n      // Coefficients for the source pixel offset (for src_ptr + begin1 [0..3] and for src_ptr + begin5 [0..3] )\n      __m256 coef_1_coef_5 = _mm256_load_2_m128(current_coeff + filter_size * 0, current_coeff + filter_size * 4);\n      __m256 coef_2_coef_6 = _mm256_load_2_m128(current_coeff + filter_size * 1, current_coeff + filter_size * 5);\n      __m256 coef_3_coef_7 = _mm256_load_2_m128(current_coeff + filter_size * 2, current_coeff + filter_size * 6);\n      __m256 coef_4_coef_8 = _mm256_load_2_m128(current_coeff + filter_size * 3, current_coeff + filter_size * 7);\n\n      _MM_TRANSPOSE8_LANE4_PS(coef_1_coef_5, coef_2_coef_6, coef_3_coef_7, coef_4_coef_8);\n\n      // Pixel offsets for the current target x-positions.\n      // Even for x >= width, these offsets are guaranteed to be within the allocated 'target_size_alignment'.\n      const int begin1 = program->pixel_offset[x + 0];\n      const int begin2 = program->pixel_offset[x + 1];\n      const int begin3 = program->pixel_offset[x + 2];\n      const int begin4 = program->pixel_offset[x + 3];\n      const int begin5 = program->pixel_offset[x + 4];\n      const int begin6 = program->pixel_offset[x + 5];\n      const int begin7 = program->pixel_offset[x + 6];\n      const int begin8 = program->pixel_offset[x + 7];\n\n      size_t y = y_from;\n\n      float* AVS_RESTRICT dst_ptr = dst + y * dst_pitch + x;\n      const float* src_ptr = src + y * src_pitch;\n      for (; y < y_to; ++y) {\n        //float* AVS_RESTRICT dst_ptr = dst + y * dst_pitch + x;\n        //const float* src_ptr = src + y * src_pitch;\n\n        __m256 data_1_data_5;\n        __m256 data_2_data_6;\n        __m256 data_3_data_7;\n        __m256 data_4_data_8;\n\n        if constexpr (partial_load) {\n          // In the potentially unsafe zone (near the right edge of the image), we use a safe loading function\n          // to prevent reading beyond the allocated source scanline. This handles cases where loading 4 floats\n          // starting from 'src_ptr + beginX' might exceed the source buffer.\n\n          // Example of the unsafe scenario: If target width is 320, a load at src_ptr + 317\n          // would attempt to read floats at indices 317, 318, 319, and 320, potentially going out of bounds.\n\n          // Two main issues in the unsafe zone:\n          // 1.) Out-of-bounds memory access: Reading beyond the allocated memory for the source scanline can\n          //     lead to access violations and crashes. '_mm_loadu_ps' attempts to load 16 bytes, so even if\n          //     the starting address is within bounds, subsequent reads might not be.\n          // 2.) Garbage or NaN values: Even if a read doesn't cause a crash, accessing uninitialized or\n          //     out-of-bounds memory (especially for float types) can result in garbage data, including NaN.\n          //     Multiplying by a valid coefficient and accumulating this NaN can contaminate the final result.\n\n          // '_mm256_load_partial_safe_2_m128' safely loads up to 'filter_size_real' pixels and pads with zeros if needed,\n          // preventing out-of-bounds reads and ensuring predictable results even near the image edges.\n\n          data_1_data_5 = _mm256_load_partial_safe_2_m128<filtersizemod4>(src_ptr + begin1, src_ptr + begin5);\n          data_2_data_6 = _mm256_load_partial_safe_2_m128<filtersizemod4>(src_ptr + begin2, src_ptr + begin6);\n          data_3_data_7 = _mm256_load_partial_safe_2_m128<filtersizemod4>(src_ptr + begin3, src_ptr + begin7);\n          data_4_data_8 = _mm256_load_partial_safe_2_m128<filtersizemod4>(src_ptr + begin4, src_ptr + begin8);\n        }\n        else {\n          // In the safe zone, we can directly load 4 pixels at a time using unaligned loads.\n          data_1_data_5 = _mm256_loadu_2_m128(src_ptr + begin1, src_ptr + begin5);\n          data_2_data_6 = _mm256_loadu_2_m128(src_ptr + begin2, src_ptr + begin6);\n          data_3_data_7 = _mm256_loadu_2_m128(src_ptr + begin3, src_ptr + begin7);\n          data_4_data_8 = _mm256_loadu_2_m128(src_ptr + begin4, src_ptr + begin8);\n        }\n\n        _MM_TRANSPOSE8_LANE4_PS(data_1_data_5, data_2_data_6, data_3_data_7, data_4_data_8);\n\n        __m256 result = _mm256_mul_ps(data_1_data_5, coef_1_coef_5);\n        result = _mm256_fmadd_ps(data_2_data_6, coef_2_coef_6, result);\n        result = _mm256_fmadd_ps(data_3_data_7, coef_3_coef_7, result);\n        result = _mm256_fmadd_ps(data_4_data_8, coef_4_coef_8, result);\n\n        _mm256_stream_ps(dst_ptr, result);\n        dst_ptr += dst_pitch;\n        src_ptr += src_pitch;\n      } // y\n      current_coeff += filter_size * 8; // Move to the next set of coefficients for the next 8 output pixels\n      }; // end of lambda\n\n    // Process the 'safe zone' where direct full unaligned loads are acceptable.\n    for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)\n    {\n      do_h_float_core(std::false_type{}); // partial_load == false, use direct _mm256_loadu_ps\n    }\n\n    // Process the potentially 'unsafe zone' near the image edge, using safe loading.\n    for (; x < width; x += PIXELS_AT_A_TIME)\n    {\n      do_h_float_core(std::true_type{}); // partial_load == true, use the safer _mm256_load_partial_safe_2_m128\n    }\n  }\n}\n\n// Helper for permutex style horizontal resampling 32 bit float\n// Safe partial load for 1-7 floats, padding with zeros to avoid NaN contamination\nstatic __m256 _mm256_load_partial_safe(const float* src_ptr, int floats_to_load) {\n  if (floats_to_load == 1)\n    return _mm256_setr_ps(src_ptr[0], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);\n  if (floats_to_load == 2)\n    return _mm256_setr_ps(src_ptr[0], src_ptr[1], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);\n  if (floats_to_load == 3)\n    return _mm256_setr_ps(src_ptr[0], src_ptr[1], src_ptr[2], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);\n  if (floats_to_load == 4)\n    return _mm256_setr_ps(src_ptr[0], src_ptr[1], src_ptr[2], src_ptr[3], 0.0f, 0.0f, 0.0f, 0.0f);\n  if (floats_to_load == 5)\n    return _mm256_setr_ps(src_ptr[0], src_ptr[1], src_ptr[2], src_ptr[3], src_ptr[4], 0.0f, 0.0f, 0.0f);\n  if (floats_to_load == 6)\n    return _mm256_setr_ps(src_ptr[0], src_ptr[1], src_ptr[2], src_ptr[3], src_ptr[4], src_ptr[5], 0.0f, 0.0f);\n  if (floats_to_load == 7)\n    return _mm256_setr_ps(src_ptr[0], src_ptr[1], src_ptr[2], src_ptr[3], src_ptr[4], src_ptr[5], src_ptr[6], 0.0f);\n  if (floats_to_load == 8)\n    return _mm256_loadu_ps(src_ptr); // n/a cannot happen\n  else\n    return _mm256_setzero_ps(); // n/a cannot happen\n}\n\n\n// resize_h_planar_float_avx2_xxx_vstripe_ks4 method #2: permutex-based\nvoid resize_h_planar_float_avx2_permutex_vstripe_ks4(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)\n{\n  const int filter_size = program->filter_size; // aligned, practically the coeff table stride\n\n  src_pitch /= sizeof(float);\n  dst_pitch /= sizeof(float);\n\n  float* src = (float*)src8;\n  float* dst = (float*)dst8;\n\n  constexpr int PIXELS_AT_A_TIME = 8; // Process eight pixels in parallel in AVX2\n\n  // Pre-checked for permutex-based upsampling: the source pixels will surely fit within single 8 float loads\n  // The right edge handling will be done via safe partial loads when needed, loading 8 pixels at once\n  // may not be safe there.\n\n  // 'source_overread_beyond_targetx' marks the x position in the target (output) scanline where,\n  // if we process N pixels at a time (e.g., 8 for AVX2), the filter kernel may overread the source\n  // buffer near the right edge due to kernel size and pixel offsets. Beyond this value, it is no\n  // longer safe to read N source pixels at once from pixel_offset[].\n\n  // For x positions < source_overread_beyond_targetx, it is safe to load N source pixels at once.\n  // For x positions >= source_overread_beyond_targetx, we must use a safer loading method (e.g.,\n  // partial loads with padding) to avoid out-of-bounds memory access.\n\n  // permutex is even more special: the safety analysis is performed only for the beginning of each\n  // block of 8 pixels processed at a time, so only the source loads for the offset position of\n  // every 8th target pixel are considered. This is 'safelimit_8_pixels_each8th_target'.\n  // The program's safe limits are pre-calculated during program setup.\n\n  const int width_safe_mod = (program->safelimit_8_pixels_each8th_target.overread_possible ? program->safelimit_8_pixels_each8th_target.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  // Preconditions:\n  assert(program->filter_size_real <= 4); // We preload all relevant coefficients (up to 4) before the height loop.\n\n  // 'target_size_alignment' ensures we can safely access coefficients using offsets like\n  // coeff + filter_size*0 to filter_size*7 when processing 8 H pixels at a time\n  assert(program->target_size_alignment >= 8);\n\n  // Ensure that coefficient loading is safe for 4 float loads,\n  // if less than 4, padded with zeros till filter_size_alignment.\n  assert(program->filter_size_alignment >= 4);\n\n  const int max_scanlines =  program->max_scanlines;\n\n  for (int y_from = 0; y_from < height; y_from += max_scanlines) {\n    int y_to = std::min(y_from + max_scanlines, height);\n    // Reset current_coeff for the start of the stripe\n    const float* AVS_RESTRICT current_coeff = program->pixel_coefficient_float; // +iYstart * filter_size;\n\n    int x = 0;\n\n    // This 'auto' lambda construct replaces the need of templates\n    auto do_h_float_core = [&](auto partial_load) {\n      // Assumes 'filter_size_alignment' <= 4, 'target_size_alignment' >= 8\n      // Prepare 4 coefs per pixel for 8 pixels in transposed V-form at once before the height loop.\n      __m256 coef_0 = _mm256_load_2_m128(current_coeff + filter_size * 0, current_coeff + filter_size * 4);\n      __m256 coef_1 = _mm256_load_2_m128(current_coeff + filter_size * 1, current_coeff + filter_size * 5);\n      __m256 coef_2 = _mm256_load_2_m128(current_coeff + filter_size * 2, current_coeff + filter_size * 6);\n      __m256 coef_3 = _mm256_load_2_m128(current_coeff + filter_size * 3, current_coeff + filter_size * 7);\n\n      _MM_TRANSPOSE8_LANE4_PS(coef_0, coef_1, coef_2, coef_3);\n\n      // convert resampling program in H-form into permuting indexes for src transposition in V-form\n      __m256i perm_0 = _mm256_loadu_si256((__m256i*)(&program->pixel_offset[x]));\n      int iStart = program->pixel_offset[x];\n      perm_0 = _mm256_sub_epi32(perm_0, _mm256_set1_epi32(iStart));\n      /* like this:\n      __m256i perm_0 = _mm512_set_epi32(\n        program->pixel_offset[x + 7] - iStart,\n        ...\n        program->pixel_offset[x + 0] - iStart);\n      */\n\n      __m256i one_epi32 = _mm256_set1_epi32(1);\n      __m256i perm_1 = _mm256_add_epi32(perm_0, one_epi32); // begin8_rel+1, begin7_rel+1, ... begin2_rel+1, begin1_rel+1\n      __m256i perm_2 = _mm256_add_epi32(perm_1, one_epi32); // begin8_rel+2, begin7_rel+2, ... begin2_rel+2, begin1_rel+2\n      __m256i perm_3 = _mm256_add_epi32(perm_2, one_epi32); // begin8_rel+3, begin7_rel+3, ... begin2_rel+3, begin1_rel+3\n      // These indexes are guaranteed to be 0..7 due to the earlier analysis,\n      // and can be used for the indexing parameter in _mm256_permutevar8x32_ps\n      float* AVS_RESTRICT dst_ptr = dst + x + y_from * dst_pitch;\n      const float* src_ptr = src + iStart + y_from * src_pitch;\n\n      // for partial_load only\n      const int remaining = program->source_size - iStart;\n      const int floats_to_load = remaining >= 8 ? 8 : remaining;\n\n      for (int y = y_from; y < y_to; ++y) {\n\n        // process scanline y\n        __m256 data_src;\n        // We'll need exactly 8 floats starting from src+iStart\n        if constexpr (partial_load) {\n          // In the potentially unsafe zone (near the right edge of the image), we use a safe loading function\n          // to prevent reading beyond the allocated source scanline. This handles cases where loading 8 floats\n          // starting from 'src_ptr + beginX' might exceed the source buffer.\n          data_src = _mm256_load_partial_safe(src_ptr, floats_to_load);\n        }\n        else {\n          data_src = _mm256_loadu_ps(src_ptr); // load 8 source pixels, can contain garbage beyond the right edge in the last loop\n        }\n\n        // After we load 8 source pixels starting from begin1, we can be sure, that pixel_offset[x+0] .. pixel_offset[x+7] + 3 is\n        // within valid source range. Pre-check chooses permutex method only if all needed pixels fit within these 8 loaded pixels.\n\n        // perm_0 .. perm_3 contain the indexes to permute data_src into the correct order\n        // for each of the 8 output pixels so they index into 0..7 (guaranteed) range of the source data loaded above\n        __m256 data_0 = _mm256_permutevar8x32_ps(data_src, perm_0);\n        __m256 data_1 = _mm256_permutevar8x32_ps(data_src, perm_1);\n        __m256 data_2 = _mm256_permutevar8x32_ps(data_src, perm_2);\n        __m256 data_3 = _mm256_permutevar8x32_ps(data_src, perm_3);\n\n        __m256 result0 = _mm256_mul_ps(data_0, coef_0);\n        __m256 result1 = _mm256_mul_ps(data_2, coef_2);\n\n        result0 = _mm256_fmadd_ps(data_1, coef_1, result0);\n        result1 = _mm256_fmadd_ps(data_3, coef_3, result1);\n\n        // this must be stream until partial tile interface done\n        _mm256_stream_ps(dst_ptr, _mm256_add_ps(result0, result1));\n\n        dst_ptr += dst_pitch;\n        src_ptr += src_pitch;\n      }\n      current_coeff += filter_size * 8;\n      }; // end of lambda\n\n    // Process the 'safe zone' where direct full unaligned loads are acceptable.\n    for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)\n    {\n      do_h_float_core(std::false_type{}); // partial_load == false, use direct _mm_loadu_ps\n    }\n\n    // Process the potentially 'unsafe zone' near the image edge, using safe loading.\n    for (; x < width; x += PIXELS_AT_A_TIME)\n    {\n      do_h_float_core(std::true_type{}); // partial_load == true, use the safer '_mm256_load_partial_safe'\n    }\n  }\n}\n\n\n// Simulating the AVX512 case, where 16-way permutes are possible.\n// H, kernel size 4, 2x8 pix version, 16 output pixels.\n// Same as plain ks4, but 2x8 pixels instead of 1x8 pixels at a time.\n// Since AVX2 only supports 256 bit and 8xfloat permute, we have to simulate 16 pixel permute, with\n// handling cross-lane indices 0..15, but since the intrinsic support is only for 0..7 we have to use\n// two separate permutes, masks and then blend the results together.\n\n// Structure to hold all precalculated vectors for ONE set of coefficients/taps (e.g., perm_0)\n// Since we have 4 taps (perm_0 to perm_3), you would need 4 instances of this structure.\ntypedef struct {\n  // Permutation Indices (4 __m256i vectors)\n  __m256i PL_A; // Low output half, source A indices (0-7)\n  __m256i PL_B; // Low output half, source B indices (0-7)\n  __m256i PH_A; // High output half, source A indices (0-7)\n  __m256i PH_B; // High output half, source B indices (0-7)\n\n  // Mask Vectors (2 __m256 vectors for blendv_ps)\n  __m256 ML_B; // Low output half mask (1s select B, 0s select A)\n  __m256 MH_B; // High output half mask (1s select B, 0s select A)\n} PermuteVectors_AVX2;\n\nstatic void precalculate_cross_perm_avx2(\n  const int* pixel_offset,\n  int x,\n  PermuteVectors_AVX2* tap_vectors[4])\n{\n  // The base offset for the first loaded register A is pixel_offset[x + 0]\n  const int begin1 = pixel_offset[x + 0];\n\n  // Broadcast the constant 8 and the base offset 'begin1'\n  const __m256i v_8 = _mm256_set1_epi32(8);\n  const __m256i v_begin1 = _mm256_set1_epi32(begin1);\n\n  // A constant 0 for index in the ignored lane\n  const __m256i v_zero = _mm256_setzero_si256();\n\n  // Loop through all 4 taps independently\n  for (int tap = 0; tap < 4; ++tap) {\n\n    // 1. Prepare the 16 absolute indices (I_k) by adding 'tap'\n    // This still requires a temporary array or two separate loads/SIMD additions\n\n    // Use temporary arrays of 8 elements for simplicity, but could be done directly in SIMD\n    int I_k_low[8];\n    int I_k_high[8];\n    for (int k = 0; k < 8; ++k) {\n      I_k_low[k] = pixel_offset[x + k] + tap;\n      I_k_high[k] = pixel_offset[x + k + 8] + tap;\n    }\n\n    // Load the 16 absolute indices, split into two __m256i vectors\n    __m256i v_I_low = _mm256_loadu_si256((const __m256i*)I_k_low);\n    __m256i v_I_high = _mm256_loadu_si256((const __m256i*)I_k_high);\n\n    // --- Calculate Relative Indices (J_k = I_k - begin1) ---\n\n    __m256i v_J_low = _mm256_sub_epi32(v_I_low, v_begin1);\n    __m256i v_J_high = _mm256_sub_epi32(v_I_high, v_begin1);\n\n    // --- Calculate Mask B (ML_B and MH_B) ---\n    // Mask: 0xFFFFFFFF if J_k >= 8, 0x00000000 if J_k < 8\n    // _mm256_cmpgt_epi32(a, b) computes a > b. We want J_k >= 8, so we use J_k > 7.\n    const __m256i v_7 = _mm256_set1_epi32(7);\n\n    __m256i v_Mask_low = _mm256_cmpgt_epi32(v_J_low, v_7);\n    __m256i v_Mask_high = _mm256_cmpgt_epi32(v_J_high, v_7);\n\n    // Store the float mask vectors (Mask B)\n    tap_vectors[tap]->ML_B = _mm256_castsi256_ps(v_Mask_low);\n    tap_vectors[tap]->MH_B = _mm256_castsi256_ps(v_Mask_high);\n\n    // --- Calculate Permutation Indices for Source B (PH_B and PL_B) ---\n    // Index B is J_k - 8 (only for elements where J_k >= 8)\n    __m256i v_Jm8_low = _mm256_sub_epi32(v_J_low, v_8);\n    __m256i v_Jm8_high = _mm256_sub_epi32(v_J_high, v_8);\n\n    // Select: (Mask B) ? (J_k - 8) : 0\n    // _mm256_blendv_epi8 can be used as a general purpose blend for 32-bit integers\n    // Note: The index '0' for the ignored lane doesn't matter, as the corresponding\n    // output element will be selected from Source A, not B.\n    tap_vectors[tap]->PL_B = _mm256_blendv_epi8(v_zero, v_Jm8_low, v_Mask_low);\n    tap_vectors[tap]->PH_B = _mm256_blendv_epi8(v_zero, v_Jm8_high, v_Mask_high);\n\n    // --- Calculate Permutation Indices for Source A (PH_A and PL_A) ---\n    // Index A is J_k (only for elements where J_k < 8)\n    // Select: (Mask B) ? 0 : J_k\n    // The inverse mask can be created by NOTting the mask (using XOR with all ones, or NOT equivalent)\n    // Since we want NOT Mask B to select J_k, we use the original mask to select 0.\n\n    // A simpler way: J_k already contains the correct index (0-7). We just need to zero it out\n    // where it's NOT needed (i.e., where Mask B is set).\n\n    // Inverse Mask: 0xFFFFFFFF if J_k < 8, 0x00000000 if J_k >= 8\n    __m256i v_InvMask_low = _mm256_xor_si256(v_Mask_low, _mm256_set1_epi32(0xFFFFFFFF));\n    __m256i v_InvMask_high = _mm256_xor_si256(v_Mask_high, _mm256_set1_epi32(0xFFFFFFFF));\n\n    // Select: (Inv Mask) ? J_k : 0 \n    tap_vectors[tap]->PL_A = _mm256_blendv_epi8(v_zero, v_J_low, v_InvMask_low);\n    tap_vectors[tap]->PH_A = _mm256_blendv_epi8(v_zero, v_J_high, v_InvMask_high);\n  }\n}\n\n// Helper for permutex style horizontal resampling 32 bit float\n// Safe partial load for 1-15 floats, padding with zeros to avoid NaN contamination\n// Using jump tables instead of multiple if-else, each case is extremely\n// optimized looking at the generated assembly..\nstatic void _mm256_load_512_partial_safe(__m256 &A, __m256 &B, const float* src_ptr, int floats_to_load) {\n  if (floats_to_load == 1) {\n    A = _mm256_setr_ps(src_ptr[0], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);\n    B = _mm256_setzero_ps();\n  }\n  else if (floats_to_load == 2) {\n    A = _mm256_setr_ps(src_ptr[0], src_ptr[1], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);\n    B = _mm256_setzero_ps();\n  }\n  else if (floats_to_load == 3) {\n    A = _mm256_setr_ps(src_ptr[0], src_ptr[1], src_ptr[2], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);\n    B = _mm256_setzero_ps();\n  }\n  else if (floats_to_load == 4) {\n    A = _mm256_setr_ps(src_ptr[0], src_ptr[1], src_ptr[2], src_ptr[3], 0.0f, 0.0f, 0.0f, 0.0f);\n    B = _mm256_setzero_ps();\n  }\n  else if (floats_to_load == 5) {\n    A = _mm256_setr_ps(src_ptr[0], src_ptr[1], src_ptr[2], src_ptr[3], src_ptr[4], 0.0f, 0.0f, 0.0f);\n    B = _mm256_setzero_ps();\n  }\n  else if (floats_to_load == 6) {\n    A = _mm256_setr_ps(src_ptr[0], src_ptr[1], src_ptr[2], src_ptr[3], src_ptr[4], src_ptr[5], 0.0f, 0.0f);\n    B = _mm256_setzero_ps();\n  }\n  else if (floats_to_load == 7) {\n    A = _mm256_setr_ps(src_ptr[0], src_ptr[1], src_ptr[2], src_ptr[3], src_ptr[4], src_ptr[5], src_ptr[6], 0.0f);\n    B = _mm256_setzero_ps();\n  }\n  else if (floats_to_load == 8) {\n    A = _mm256_loadu_ps(src_ptr);\n    B = _mm256_setzero_ps();\n  }\n  else if (floats_to_load == 9) {\n    A = _mm256_loadu_ps(src_ptr);\n    B = _mm256_setr_ps(src_ptr[8], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);\n  }\n  else if (floats_to_load == 10) {\n    A = _mm256_loadu_ps(src_ptr);\n    B = _mm256_setr_ps(src_ptr[8], src_ptr[9], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);\n  }\n  else if (floats_to_load == 11) {\n    A = _mm256_loadu_ps(src_ptr);\n    B = _mm256_setr_ps(src_ptr[8], src_ptr[9], src_ptr[10], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);\n  }\n  else if (floats_to_load == 12) {\n    A = _mm256_loadu_ps(src_ptr);\n    B = _mm256_setr_ps(src_ptr[8], src_ptr[9], src_ptr[10], src_ptr[11], 0.0f, 0.0f, 0.0f, 0.0f);\n  }\n  else if (floats_to_load == 13) {\n    A = _mm256_loadu_ps(src_ptr);\n    B = _mm256_setr_ps(src_ptr[8], src_ptr[9], src_ptr[10], src_ptr[11], src_ptr[12], 0.0f, 0.0f, 0.0f);\n  }\n  else if (floats_to_load == 14) {\n    A = _mm256_loadu_ps(src_ptr);\n    B = _mm256_setr_ps(src_ptr[8], src_ptr[9], src_ptr[10], src_ptr[11], src_ptr[12], src_ptr[13], 0.0f, 0.0f);\n  }\n  else if (floats_to_load == 15) {\n    A = _mm256_loadu_ps(src_ptr);\n    B = _mm256_setr_ps(src_ptr[8], src_ptr[9], src_ptr[10], src_ptr[11], src_ptr[12], src_ptr[13], src_ptr[14], 0.0f);\n  }\n  else if (floats_to_load == 16) { // cannot happen\n    A = _mm256_loadu_ps(src_ptr);\n    B = _mm256_loadu_ps(src_ptr + 8);\n  }\n  else {\n    A = _mm256_setzero_ps(); // n/a cannot happen\n    B = _mm256_setzero_ps(); // n/a cannot happen\n  }\n}\n\n\n// resize_h_planar_float_avx2_xxx_vstripe_ks4 method #2: permutex-based, 16 pixel test version\n// like resize_h_planar_float_avx512_permutex_vstripe_ks4\nvoid resize_h_planar_float_avx2_permutex_vstripe_ks4_pix16(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)\n{\n  const int filter_size = program->filter_size; // aligned, practically the coeff table stride\n\n  src_pitch /= sizeof(float);\n  dst_pitch /= sizeof(float);\n\n  float* src = (float*)src8;\n  float* dst = (float*)dst8;\n\n  constexpr int PIXELS_AT_A_TIME = 2 * 8; // Process eight pixels in parallel in AVX2\n\n  // Pre-checked for permutex-based upsampling: the source pixels will surely fit within single 2x8 float loads\n  // The right edge handling will be done via safe partial loads when needed, loading 2x8 pixels at once\n  // may not be safe there.\n\n  // 'source_overread_beyond_targetx' marks the x position in the target (output) scanline where,\n  // if we process N pixels at a time (e.g., 8 for AVX2), the filter kernel may overread the source\n  // buffer near the right edge due to kernel size and pixel offsets. Beyond this value, it is no\n  // longer safe to read N source pixels at once from pixel_offset[].\n\n  // For x positions < source_overread_beyond_targetx, it is safe to load N source pixels at once.\n  // For x positions >= source_overread_beyond_targetx, we must use a safer loading method (e.g.,\n  // partial loads with padding) to avoid out-of-bounds memory access.\n\n  // permutex is even more special: the safety analysis is performed only for the beginning of each\n  // block of 16 pixels processed at a time, so only the source loads for the offset position of\n  // every 16th target pixel are considered. This is 'safelimit_16_pixels_each16th_target'.\n  // The program's safe limits are pre-calculated during program setup.\n\n  const int width_safe_mod = (program->safelimit_16_pixels_each16th_target.overread_possible ? program->safelimit_16_pixels_each16th_target.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  // Preconditions:\n  assert(program->filter_size_real <= 4); // We preload all relevant coefficients (up to 4) before the height loop.\n\n  // 'target_size_alignment' ensures we can safely access coefficients using offsets like\n  // coeff + filter_size*0 to filter_size*7 when processing 16 H pixels at a time\n  assert(program->target_size_alignment >= 16);\n\n  // Ensure that coefficient loading is safe for 4 float loads,\n  // if less than 4, padded with zeros till filter_size_alignment.\n  assert(program->filter_size_alignment >= 4);\n\n  const int max_scanlines = program->max_scanlines;\n\n  // Example setup before the main loop (assuming memory allocation for 4 instances)\n  PermuteVectors_AVX2 taps[4];\n  PermuteVectors_AVX2* tap_pointers[4] = { &taps[0], &taps[1], &taps[2], &taps[3] };\n\n  for (int y_from = 0; y_from < height; y_from += max_scanlines) {\n    int y_to = std::min((int)(y_from + max_scanlines), height);\n    // Reset current_coeff for the start of the stripe\n    const float* AVS_RESTRICT current_coeff = program->pixel_coefficient_float; // +iYstart * filter_size;\n\n    int x = 0;\n\n    // This 'auto' lambda construct replaces the need of templates\n    auto do_h_float_core = [&](auto partial_load) {\n\n      // Call precalculation once per x position\n      precalculate_cross_perm_avx2(program->pixel_offset.data(), x, tap_pointers);\n\n      // Assumes 'filter_size_alignment' <= 4, 'target_size_alignment' >= 16\n      // Prepare 4 coefs per pixel for 16 pixels in transposed V-form at once before the height loop.\n\n      // ---------------------------------------------------------------------------\n      // 1. Load Coefficients\n      // ---------------------------------------------------------------------------\n      // We process 16 pixels total.\n      // Low Group (Pixels 0-7): Loaded into coef_0..coef_3\n      // High Group (Pixels 8-15): Loaded into coef_4..coef_7\n\n      // filter_size is typically the stride in floats (e.g., 4)\n\n      // -- Load Low Group (Pixels 0,1,2,3 and 4,5,6,7 interleaved for Transpose macro) --\n      __m256 coef_0 = _mm256_load_2_m128(current_coeff + filter_size * 0, current_coeff + filter_size * 4);\n      __m256 coef_1 = _mm256_load_2_m128(current_coeff + filter_size * 1, current_coeff + filter_size * 5);\n      __m256 coef_2 = _mm256_load_2_m128(current_coeff + filter_size * 2, current_coeff + filter_size * 6);\n      __m256 coef_3 = _mm256_load_2_m128(current_coeff + filter_size * 3, current_coeff + filter_size * 7);\n\n      // -- Load High Group (Pixels 8,9,10,11 and 12,13,14,15 interleaved) --\n      // Note: Offsets are shifted by 8 relative to the Low Group\n      __m256 coef_4 = _mm256_load_2_m128(current_coeff + filter_size * 8, current_coeff + filter_size * 12);\n      __m256 coef_5 = _mm256_load_2_m128(current_coeff + filter_size * 9, current_coeff + filter_size * 13);\n      __m256 coef_6 = _mm256_load_2_m128(current_coeff + filter_size * 10, current_coeff + filter_size * 14);\n      __m256 coef_7 = _mm256_load_2_m128(current_coeff + filter_size * 11, current_coeff + filter_size * 15);\n\n      // ---------------------------------------------------------------------------\n      // 2. Transpose\n      // ---------------------------------------------------------------------------\n      // After transpose:\n      // coef_0 -> Tap 0 for Pixels 0-7\n      // coef_1 -> Tap 1 for Pixels 0-7 ... etc\n      _MM_TRANSPOSE8_LANE4_PS(coef_0, coef_1, coef_2, coef_3);\n\n      // coef_4 -> Tap 0 for Pixels 8-15\n      // coef_5 -> Tap 1 for Pixels 8-15 ... etc\n      _MM_TRANSPOSE8_LANE4_PS(coef_4, coef_5, coef_6, coef_7);\n\n      const int begin1 = program->pixel_offset[x + 0];\n      // These indexes are guaranteed to be 0..15 due to the earlier analysis,\n      // and can be used for the indexing parameter in combiner blendm mask, _mm256_permutevar8x32_ps\n      float* AVS_RESTRICT dst_ptr = dst + x + y_from * dst_pitch;\n      const float* src_ptr = src + begin1 + y_from * src_pitch;\n\n      // for partial_load only\n      const int remaining = program->source_size - begin1;\n      const int floats_to_load = remaining >= 16 ? 16 : remaining;\n\n      for (int y = y_from; y < y_to; ++y) {\n\n        // process scanline y\n        __m256 A;\n        __m256 B;\n\n        //__m256 data_src;\n        // We'll need exactly 2x8 floats starting from src+begin1\n        if constexpr (partial_load) {\n          // In the potentially unsafe zone (near the right edge of the image), we use a safe loading function\n          // to prevent reading beyond the allocated source scanline. This handles cases where loading 8 floats\n          // starting from 'src_ptr + beginX' might exceed the source buffer.\n          _mm256_load_512_partial_safe(/*ref*/A, /*ref*/B, src_ptr, floats_to_load);\n        }\n        else {\n          A = _mm256_loadu_ps(src_ptr);\n          B = _mm256_loadu_ps(src_ptr + 8);\n          // data_src = _mm256_loadu_ps(src_ptr); // load 8 source pixels, can contain garbage beyond the right edge in the last loop\n        }\n\n        // After we load 2x8 source pixels starting from begin1, we can be sure, that pixel_offset[x+0] .. pixel_offset[x+15] + 3 is\n        // within valid source range. Pre-check chooses permutex method only if all needed pixels fit within these 16 loaded pixels.\n\n        // Permute and Blend for Tap 0 (data_0)\n        __m256 A_perm_0L = _mm256_permutevar8x32_ps(A, taps[0].PL_A);\n        __m256 B_perm_0L = _mm256_permutevar8x32_ps(B, taps[0].PL_B);\n        __m256 data_0L = _mm256_blendv_ps(A_perm_0L, B_perm_0L, taps[0].ML_B); // Result: dst[x+0]..dst[x+7]\n\n        __m256 A_perm_0H = _mm256_permutevar8x32_ps(A, taps[0].PH_A);\n        __m256 B_perm_0H = _mm256_permutevar8x32_ps(B, taps[0].PH_B);\n        __m256 data_0H = _mm256_blendv_ps(A_perm_0H, B_perm_0H, taps[0].MH_B); // Result: dst[x+8]..dst[x+15]\n\n        // Repeat for data_1, data_2, data_3...\n        // Permute and Blend for Tap 1 (data_1)\n        __m256 A_perm_1L = _mm256_permutevar8x32_ps(A, taps[1].PL_A);\n        __m256 B_perm_1L = _mm256_permutevar8x32_ps(B, taps[1].PL_B);\n        __m256 data_1L = _mm256_blendv_ps(A_perm_1L, B_perm_1L, taps[1].ML_B); // Result: dst[x+0]..dst[x+7]\n\n        __m256 A_perm_1H = _mm256_permutevar8x32_ps(A, taps[1].PH_A);\n        __m256 B_perm_1H = _mm256_permutevar8x32_ps(B, taps[1].PH_B);\n        __m256 data_1H = _mm256_blendv_ps(A_perm_1H, B_perm_1H, taps[1].MH_B); // Result: dst[x+8]..dst[x+15]\n        // Permute and Blend for Tap 2 (data_2)\n        __m256 A_perm_2L = _mm256_permutevar8x32_ps(A, taps[2].PL_A);\n        __m256 B_perm_2L = _mm256_permutevar8x32_ps(B, taps[2].PL_B);\n        __m256 data_2L = _mm256_blendv_ps(A_perm_2L, B_perm_2L, taps[2].ML_B); // Result: dst[x+0]..dst[x+7]\n\n        __m256 A_perm_2H = _mm256_permutevar8x32_ps(A, taps[2].PH_A);\n        __m256 B_perm_2H = _mm256_permutevar8x32_ps(B, taps[2].PH_B);\n        __m256 data_2H = _mm256_blendv_ps(A_perm_2H, B_perm_2H, taps[2].MH_B); // Result: dst[x+8]..dst[x+15]\n        // Permute and Blend for Tap 3 (data_3)\n        __m256 A_perm_3L = _mm256_permutevar8x32_ps(A, taps[3].PL_A);\n        __m256 B_perm_3L = _mm256_permutevar8x32_ps(B, taps[3].PL_B);\n        __m256 data_3L = _mm256_blendv_ps(A_perm_3L, B_perm_3L, taps[3].ML_B); // Result: dst[x+0]..dst[x+7]\n\n        __m256 A_perm_3H = _mm256_permutevar8x32_ps(A, taps[3].PH_A);\n        __m256 B_perm_3H = _mm256_permutevar8x32_ps(B, taps[3].PH_B);\n        __m256 data_3H = _mm256_blendv_ps(A_perm_3H, B_perm_3H, taps[3].MH_B); // Result: dst[x+8]..dst[x+15]\n\n        // perm_0 .. perm_3 lo and hi contain the indexes to permute data_src into the correct order\n        // for each of the 16 output pixels so they index into 0..15 (guaranteed) range of the source data loaded above\n        // Since we have only 8-wide permute, we have to do two separate permutes and then blend the results together.\n\n        // Assuming these eight data vectors have been calculated via Permute+Blend:\n        // __m256 data_0L, data_0H;\n        // __m256 data_1L, data_1H;\n        // __m256 data_2L, data_2H;\n        // __m256 data_3L, data_3H;\n\n        // ---------------------------------------------------------------------------\n        // 3. Calculation\n        // ---------------------------------------------------------------------------\n\n        // --- Low Half (Pixels 0-7) ---\n        // Uses: data_0L..3L and coef_0..3\n\n        __m256 result0L = _mm256_mul_ps(data_0L, coef_0);       // Tap 0\n        __m256 result1L = _mm256_mul_ps(data_2L, coef_2);       // Tap 2\n\n        result0L = _mm256_fmadd_ps(data_1L, coef_1, result0L);  // Tap 1\n        result1L = _mm256_fmadd_ps(data_3L, coef_3, result1L);  // Tap 3\n\n        __m256 final_result_L = _mm256_add_ps(result0L, result1L);\n\n\n        // --- High Half (Pixels 8-15) ---\n        // Uses: data_0H..3H and coef_4..7\n        // Note: coef_4 corresponds to Tap 0 for this group, coef_5 to Tap 1, etc.\n\n        __m256 result0H = _mm256_mul_ps(data_0H, coef_4);       // Tap 0 (High)\n        __m256 result1H = _mm256_mul_ps(data_2H, coef_6);       // Tap 2 (High)\n\n        result0H = _mm256_fmadd_ps(data_1H, coef_5, result0H);  // Tap 1 (High)\n        result1H = _mm256_fmadd_ps(data_3H, coef_7, result1H);  // Tap 3 (High)\n\n        __m256 final_result_H = _mm256_add_ps(result0H, result1H);\n\n        // ---------------------------------------------------------------------------\n        // 4. Store\n        // ---------------------------------------------------------------------------\n\n        _mm256_stream_ps(dst_ptr, final_result_L);     // dst[0..7]\n        _mm256_stream_ps(dst_ptr + 8, final_result_H); // dst[8..15]\n\n        dst_ptr += dst_pitch;\n        src_ptr += src_pitch;\n      }\n      current_coeff += filter_size * 16;\n      }; // end of lambda\n\n    // Process the 'safe zone' where direct full unaligned loads are acceptable.\n    for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)\n    {\n      do_h_float_core(std::false_type{}); // partial_load == false, use direct _mm_loadu_ps\n    }\n\n    // Process the potentially 'unsafe zone' near the image edge, using safe loading.\n    for (; x < width; x += PIXELS_AT_A_TIME)\n    {\n      do_h_float_core(std::true_type{}); // partial_load == true, use the safer '_mm256_load_partial_safe'\n    }\n  }\n\n}\n\n\n\ntemplate<int filtersizemod4>\nvoid resize_h_planar_float_avx2_gather_permutex_vstripe_ks4(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)\n{\n\n  // FIXME: this analysis could be done once in the dispatcher instead of per call, since the program is constant\n  bool bDoGather = program->resize_h_planar_gather_permutex_vstripe_check(8/*iSamplesInThGroup*/, 8 /*permutex_index_diff_limit*/, 4 /*kernel_size*/);\n  if (bDoGather)\n  {\n    resize_h_planar_float_avx2_transpose_vstripe_ks4<filtersizemod4>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  } // if bDoGather\n  else\n  {\n    resize_h_planar_float_avx2_permutex_vstripe_ks4(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  }\n\n  // versus the original one, which is a generic upsample/downsample method\n  //resize_h_planar_float_avx_transpose_vstripe_ks4<filtersizemod4>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\n\n// Instantiate them\ntemplate void resize_h_planar_float_avx2_transpose_vstripe_ks4<0>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resize_h_planar_float_avx2_transpose_vstripe_ks4<1>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resize_h_planar_float_avx2_transpose_vstripe_ks4<2>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resize_h_planar_float_avx2_transpose_vstripe_ks4<3>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\n// Instantiate them\ntemplate void resize_h_planar_float_avx2_gather_permutex_vstripe_ks4<0>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resize_h_planar_float_avx2_gather_permutex_vstripe_ks4<1>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resize_h_planar_float_avx2_gather_permutex_vstripe_ks4<2>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resize_h_planar_float_avx2_gather_permutex_vstripe_ks4<3>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\n//--------------------------------------------------------------------------\n\n// AVX2 Horizontal float\n\n// Three helpers, each for processing 4 target pixels from 16, 8 and 4 source pixel/coeff pairs.\n\n// Helper, implemented for AVX2 (simulating zext)\n// zero-extend 128-bit float vector to 256-bit float vector\nAVS_FORCEINLINE static __m256 _mm256_zextps128_ps256_avx2(__m128 a)\n{\n  __m256 zero_v = _mm256_setzero_ps();\n  return _mm256_insertf128_ps(zero_v, a, 0);\n}\n\n// 4 target pixels, each from 16 source pixel/coeff pair\n// Called only when accessing 16 source pixels and coefficients at a time is safe\n// AVX2 OPTIMIZATION: Process 2x8 blocks to simulate the 16-block stride\nAVS_FORCEINLINE static void process_pix4_coeff16_h_float_core_avx2(\n  const float* src,\n  int begin1, int begin2, int begin3, int begin4,\n  const float* current_coeff,\n  int filter_size,\n  __m256& result1, __m256& result2, __m256& result3, __m256& result4)\n{\n  // --- Block A: First 8 floats ---\n  __m256 data_1_a = _mm256_loadu_ps(src + begin1);\n  __m256 coeff_1_a = _mm256_loadu_ps(current_coeff);\n  result1 = _mm256_fmadd_ps(data_1_a, coeff_1_a, result1);\n  __m256 data_1_b = _mm256_loadu_ps(src + begin1 + 8);\n  __m256 coeff_1_b = _mm256_loadu_ps(current_coeff + 8);\n  result1 = _mm256_fmadd_ps(data_1_b, coeff_1_b, result1);\n\n  __m256 data_2_a = _mm256_loadu_ps(src + begin2);\n  __m256 coeff_2_a = _mm256_loadu_ps(current_coeff + 1 * filter_size);\n  result2 = _mm256_fmadd_ps(data_2_a, coeff_2_a, result2);\n  __m256 data_2_b = _mm256_loadu_ps(src + begin2 + 8);\n  __m256 coeff_2_b = _mm256_loadu_ps(current_coeff + 1 * filter_size + 8);\n  result2 = _mm256_fmadd_ps(data_2_b, coeff_2_b, result2);\n\n  __m256 data_3_a = _mm256_loadu_ps(src + begin3);\n  __m256 coeff_3_a = _mm256_loadu_ps(current_coeff + 2 * filter_size);\n  result3 = _mm256_fmadd_ps(data_3_a, coeff_3_a, result3);\n  __m256 data_3_b = _mm256_loadu_ps(src + begin3 + 8);\n  __m256 coeff_3_b = _mm256_loadu_ps(current_coeff + 2 * filter_size + 8);\n  result3 = _mm256_fmadd_ps(data_3_b, coeff_3_b, result3);\n\n  __m256 data_4_a = _mm256_loadu_ps(src + begin4);\n  __m256 coeff_4_a = _mm256_loadu_ps(current_coeff + 3 * filter_size);\n  result4 = _mm256_fmadd_ps(data_4_a, coeff_4_a, result4);\n  __m256 data_4_b = _mm256_loadu_ps(src + begin4 + 8);\n  __m256 coeff_4_b = _mm256_loadu_ps(current_coeff + 3 * filter_size + 8);\n  result4 = _mm256_fmadd_ps(data_4_b, coeff_4_b, result4);\n\n}\n\n// 4 target pixels, each from 8 source pixel/coeff pair\n// Called only when accessing 8 source pixels and coefficients at a time is safe\nAVS_FORCEINLINE static void process_pix4_coeff8_h_float_core_avx2(\n  const float* src,\n  int begin1, int begin2, int begin3, int begin4,\n  const float* current_coeff,\n  int filter_size,\n  __m256& result1, __m256& result2, __m256& result3, __m256& result4)\n{\n  // Load 8 source floats for each of the four beginning source offsets\n  // Load 8 coefficients for each of the four output pixels\n  __m256 data_1 = _mm256_loadu_ps(src + begin1);\n  __m256 coeff_1 = _mm256_load_ps(current_coeff);                     // 8 coeffs for pixel 1\n  result1 = _mm256_fmadd_ps(data_1, coeff_1, result1);\n\n  __m256 data_2 = _mm256_loadu_ps(src + begin2);\n  __m256 coeff_2 = _mm256_load_ps(current_coeff + 1 * filter_size); // 8 coeffs for pixel 2\n  result2 = _mm256_fmadd_ps(data_2, coeff_2, result2);\n\n  __m256 data_3 = _mm256_loadu_ps(src + begin3);\n  __m256 coeff_3 = _mm256_load_ps(current_coeff + 2 * filter_size); // 8 coeffs for pixel 3\n  result3 = _mm256_fmadd_ps(data_3, coeff_3, result3);\n\n  __m256 data_4 = _mm256_loadu_ps(src + begin4);\n  __m256 coeff_4 = _mm256_load_ps(current_coeff + 3 * filter_size); // 8 coeffs for pixel 4\n  result4 = _mm256_fmadd_ps(data_4, coeff_4, result4);\n}\n\n// 4 target pixels, each from 4 source pixel/coeff pair.\n// Called only for first iteration when results are not initialized.\n// Otherwise same as process_pix4_coeff8_h_float_core.\n// Optimized: Uses 256-bit MUL directly on zero-extended loads.\nAVS_FORCEINLINE static void process_pix4_coeff4_h_float_core_first_avx2(\n  const float* src,\n  int begin1, int begin2, int begin3, int begin4,\n  const float* current_coeff,\n  int filter_size,\n  __m256& result1, __m256& result2, __m256& result3, __m256& result4)\n{\n  // Pixel 1\n  __m128 data_1 = _mm_loadu_ps(src + begin1);\n  __m128 coeff_1 = _mm_load_ps(current_coeff);\n  __m128 temp_result_1 = _mm_mul_ps(data_1, coeff_1);\n  result1 = _mm256_zextps128_ps256_avx2(temp_result_1);\n\n  // Pixel 2\n  __m128 data_2 = _mm_loadu_ps(src + begin2);\n  __m128 coeff_2 = _mm_load_ps(current_coeff + 1 * filter_size);\n  __m128 temp_result_2 = _mm_mul_ps(data_2, coeff_2);\n  result2 = _mm256_zextps128_ps256_avx2(temp_result_2);\n\n  // Pixel 3\n  __m128 data_3 = _mm_loadu_ps(src + begin3);\n  __m128 coeff_3 = _mm_load_ps(current_coeff + 2 * filter_size);\n  __m128 temp_result_3 = _mm_mul_ps(data_3, coeff_3);\n  result3 = _mm256_zextps128_ps256_avx2(temp_result_3);\n\n  // Pixel 4\n  __m128 data_4 = _mm_loadu_ps(src + begin4);\n  __m128 coeff_4 = _mm_load_ps(current_coeff + 3 * filter_size);\n  __m128 temp_result_4 = _mm_mul_ps(data_4, coeff_4);\n  result4 = _mm256_zextps128_ps256_avx2(temp_result_4);\n}\n\n#define HAS_COEFF16_STEP\n\n// filtersize_hint: special: 0..4 for 4,8,16,24,32. Generic: -1\n// filter_size is an aligned value and always multiple of 8 (prerequisite)\ntemplate<bool safe_aligned_mode, int filtersize_hint>\nAVS_FORCEINLINE static void process_four_pixels_h_float_pix4of16_ks_4_8_16_avx2(\n  const float* src_ptr,\n  int begin1, int begin2, int begin3, int begin4,\n  float* current_coeff,\n  int filter_size,\n  __m256& result1, __m256& result2, __m256& result3, __m256& result4,\n  int kernel_size)\n{\n\n  // very special case: filter size <= 4\n  if constexpr (safe_aligned_mode) {\n    if constexpr(filtersize_hint == 0) {\n      // Process 4 target pixels and 4 source pixels/coefficients at a time\n      // XMM-based loop internally, but returns __m256 with upper 128 cleared\n      // Do not assume initialized zeros in result1..4, they will be set here.\n      process_pix4_coeff4_h_float_core_first_avx2(\n        src_ptr + 0, begin1, begin2, begin3, begin4,\n        current_coeff + 0,\n        filter_size,\n        result1, result2, result3, result4);\n      return;\n    }\n  }\n\n  // not: when filtersize_hint == -1, it is not covered with filtersize_hint maximum 4 case, which means\n  // that real filter size is over 32.\n  // Thus we surely can have 2x16 coeff processing here.\n\n  int i = 0;\n#ifdef HAS_COEFF16_STEP\n  if constexpr(filtersize_hint == -1) {\n    // Handle 2x16 coeffs first, since we know that real filter size is over 32 here, because of filtersize_hint == -1\n    const int ksmod16_sure = 32;\n    // this will be unrolled probably\n    for (; i < ksmod16_sure; i += 16) {\n      // Direct AVX2 adaptation: The core function now updates resultX (YMM) directly\n      process_pix4_coeff16_h_float_core_avx2(\n        src_ptr + i, begin1, begin2, begin3, begin4,\n        current_coeff + i,\n        filter_size,\n        result1, result2, result3, result4);\n    }\n    // processed 32 coeffs from the kernel, do the rest\n    const int ksmod16 = safe_aligned_mode ? (filter_size / 16 * 16) : (kernel_size / 16 * 16);\n    // Process 4 target pixels and 16 source pixels/coefficients at a time\n    for (; i < ksmod16; i += 16) {\n      // Direct AVX2 adaptation: The core function now updates resultX (YMM) directly\n      process_pix4_coeff16_h_float_core_avx2(\n        src_ptr + i, begin1, begin2, begin3, begin4,\n        current_coeff + i,\n        filter_size,\n        result1, result2, result3, result4);\n    }\n  }\n  else {\n    // do by 16 coeffs till possible\n    if (filtersize_hint >= 2) {\n      const int ksmod16 = safe_aligned_mode ? (filter_size / 16 * 16) : (kernel_size / 16 * 16);\n      // Process 4 target pixels and 16 source pixels/coefficients at a time\n      for (; i < ksmod16; i += 16) {\n        // Direct AVX2 adaptation: The core function now updates resultX (YMM) directly\n        process_pix4_coeff16_h_float_core_avx2(\n          src_ptr + i, begin1, begin2, begin3, begin4,\n          current_coeff + i,\n          filter_size,\n          result1, result2, result3, result4);\n      }\n    }\n  }\n\n  // filter sizes 16 or 32 can return here\n  if constexpr (safe_aligned_mode && (filtersize_hint == 2 || filtersize_hint == 4)) {\n    return;\n  }\n\n  if constexpr (!safe_aligned_mode) {\n    if (i == kernel_size) return; // kernel_size is not known compile time\n  }\n#else\n  // no coeff16 step\n  if constexpr (filtersize_hint == -1) {\n    // Handle 4x8 coeffs first, since we know that real filter size is over 32 here, because of filtersize_hint == -1\n    const int ksmod8_sure = 32;\n    // this will be unrolled probably\n    for (; i < ksmod8_sure; i += 8) {\n      process_pix4_coeff8_h_float_core_avx2(\n        src_ptr + i, begin1, begin2, begin3, begin4,\n        current_coeff + i,\n        filter_size,\n        result1, result2, result3, result4);\n    }\n  }\n#endif\n\n  // When to do the coeff8 step if we had the coeff16 step enabled:\n  // not safe-aligned mode: always. E.g. kernel_size == 28 -> 16 done, now 10 rest, do 8 next\n  // filtersize_hint == -1: not-compile-time known filtersize (kernel_size / 16 * 16 done, rest follows)\n  // filtersize_hint == 1 or 3: 0*16 or 1*16 done, now do 1*8\n#ifdef HAS_COEFF16_STEP\n  if (!safe_aligned_mode || filtersize_hint == -1 || filtersize_hint == 1 || filtersize_hint == 3) {\n#else\n  if (true) {\n#endif\n    // 32 bytes contain 8 floats. We will use 256-bit registers (YMM).\n    const int ksmod8 = safe_aligned_mode ? (filter_size / 8 * 8) : (kernel_size / 8 * 8);\n\n    // Process 4 target pixels and 8 source pixels/coefficients at a time (YMM-based loop)\n    for (; i < ksmod8; i += 8) {\n      process_pix4_coeff8_h_float_core_avx2(\n        src_ptr + i, begin1, begin2, begin3, begin4,\n        current_coeff + i,\n        filter_size,\n        result1, result2, result3, result4);\n    }\n  }\n\n  if constexpr (!safe_aligned_mode) {\n    // Right edge case.\n    // Coeffs are zero padded, reading them is no problem.\n    // But if we read past the end of source then we can get possible NaN contamination.\n    // Handle the remainder: 1 to 7 source/coefficient elements.\n    // real_kernel_size is used here, it's guaranteed that reading real_kernel_size elements\n    // from any pixel_offset[] is safe and ends within the source buffer.\n    // Optional 4-2-1 processing loop.\n\n    if (i == kernel_size) return;\n\n    // --- Define Base Pointers for Source and Coefficients ---\n    const float* src_ptr1 = src_ptr + begin1;\n    const float* src_ptr2 = src_ptr + begin2;\n    const float* src_ptr3 = src_ptr + begin3;\n    const float* src_ptr4 = src_ptr + begin4;\n\n    float* current_coeff2 = current_coeff + 1 * filter_size;\n    float* current_coeff3 = current_coeff + 2 * filter_size;\n    float* current_coeff4 = current_coeff + 3 * filter_size;\n\n    const int ksmod4 = kernel_size / 4 * 4;\n\n    // -------------------------------------------------------------------\n    // Mod 4 Block (4 elements for four pixels using __m128)\n    // -------------------------------------------------------------------\n    if (i < ksmod4) {\n\n      // Pixel 1\n      __m128 data_1 = _mm_loadu_ps(src_ptr1 + i);\n      __m128 coeff_1 = _mm_load_ps(current_coeff + i);\n      __m128 temp_result_1 = _mm_mul_ps(data_1, coeff_1);\n      result1 = _mm256_add_ps(result1, _mm256_zextps128_ps256_avx2(temp_result_1));\n\n      // Pixel 2\n      __m128 data_2 = _mm_loadu_ps(src_ptr2 + i);\n      __m128 coeff_2 = _mm_load_ps(current_coeff2 + i);\n      __m128 temp_result_2 = _mm_mul_ps(data_2, coeff_2);\n      result2 = _mm256_add_ps(result2, _mm256_zextps128_ps256_avx2(temp_result_2));\n\n      // Pixel 3\n      __m128 data_3 = _mm_loadu_ps(src_ptr3 + i);\n      __m128 coeff_3 = _mm_load_ps(current_coeff3 + i);\n      __m128 temp_result_3 = _mm_mul_ps(data_3, coeff_3);\n      result3 = _mm256_add_ps(result3, _mm256_zextps128_ps256_avx2(temp_result_3));\n\n      // Pixel 4\n      __m128 data_4 = _mm_loadu_ps(src_ptr4 + i);\n      __m128 coeff_4 = _mm_load_ps(current_coeff4 + i);\n      __m128 temp_result_4 = _mm_mul_ps(data_4, coeff_4);\n      result4 = _mm256_add_ps(result4, _mm256_zextps128_ps256_avx2(temp_result_4));\n\n      i += 4;\n      if (i == kernel_size) return;\n    }\n\n    const int ksmod2 = kernel_size / 2 * 2;\n\n    // -------------------------------------------------------------------\n    // Mod 2 Block (2 elements for four pixels using __m128)\n    // -------------------------------------------------------------------\n    if (i < ksmod2) {\n      // _mm_load_sd (vmovsd) loads 64 bits and zeroes everything else in the register.\n      // Vector looks like: [0, 0, 0, 0, 0, 0, val1, val0]\n      // We can use the exact same FMA trick.\n\n      auto load_2_floats_as_ymm = [](const float* p) {\n        return _mm256_zextps128_ps256_avx2(_mm_castpd_ps(_mm_load_sd(reinterpret_cast<const double*>(p))));\n        };\n\n      result1 = _mm256_fmadd_ps(load_2_floats_as_ymm(src_ptr1 + i), load_2_floats_as_ymm(current_coeff + i), result1);\n      result2 = _mm256_fmadd_ps(load_2_floats_as_ymm(src_ptr2 + i), load_2_floats_as_ymm(current_coeff2 + i), result2);\n      result3 = _mm256_fmadd_ps(load_2_floats_as_ymm(src_ptr3 + i), load_2_floats_as_ymm(current_coeff3 + i), result3);\n      result4 = _mm256_fmadd_ps(load_2_floats_as_ymm(src_ptr4 + i), load_2_floats_as_ymm(current_coeff4 + i), result4);\n\n      i += 2;\n      if (i == kernel_size) return;\n    }\n\n    // -------------------------------------------------------------------\n    // Fallback Scalar Operation (1 element remaining)\n    // -------------------------------------------------------------------\n    if (i < kernel_size) {\n\n      // Optimized scalar loop for the single remaining element\n      float final_scalar1 = src_ptr1[i] * current_coeff[i];\n      float final_scalar2 = src_ptr2[i] * current_coeff2[i];\n      float final_scalar3 = src_ptr3[i] * current_coeff3[i];\n      float final_scalar4 = src_ptr4[i] * current_coeff4[i];\n\n      // Using the helper for the last one to be safe/consistent with scalar ops\n      result1 = _mm256_add_ps(result1, _mm256_zextps128_ps256_avx2(_mm_set_ss(final_scalar1)));\n      result2 = _mm256_add_ps(result2, _mm256_zextps128_ps256_avx2(_mm_set_ss(final_scalar2)));\n      result3 = _mm256_add_ps(result3, _mm256_zextps128_ps256_avx2(_mm_set_ss(final_scalar3)));\n      result4 = _mm256_add_ps(result4, _mm256_zextps128_ps256_avx2(_mm_set_ss(final_scalar4)));\n      // i is now equal to kernel_size (i++)\n    }\n  }\n}\n\n\ntemplate<bool is_safe, int filtersize_hint>\nAVS_FORCEINLINE static void process_sixteen_pixels_h_float_pix16_sub4_ks_4_8_16_avx2(\n  const float* src, int x, float* current_coeff_base,\n  int filter_size, // 8, 16, 24, 32 are quasi-constexpr here, others not compile-time known but still aligned to 8\n  float* dst,\n  ResamplingProgram* program)\n{\n  assert(program->filter_size_alignment == 8);\n\n  float* current_coeff = current_coeff_base + x * filter_size;\n  const int unaligned_kernel_size = program->filter_size_real;\n  const __m256 zero256 = _mm256_setzero_ps();\n\n  // --- Block 1: Pixels 0, 1, 2, 3 ---\n  __m256 result0 = zero256;\n  __m256 result1 = zero256;\n  __m256 result2 = zero256;\n  __m256 result3 = zero256;\n\n  int begin0 = program->pixel_offset[x + 0];\n  int begin1 = program->pixel_offset[x + 1];\n  int begin2 = program->pixel_offset[x + 2];\n  int begin3 = program->pixel_offset[x + 3];\n\n  process_four_pixels_h_float_pix4of16_ks_4_8_16_avx2<is_safe, filtersize_hint>(\n    src, begin0, begin1, begin2, begin3, current_coeff, filter_size,\n    result0, result1, result2, result3, unaligned_kernel_size);\n  current_coeff += 4 * filter_size;\n\n  // --- Block 2: Pixels 4, 5, 6, 7 ---\n  __m256 result4 = zero256;\n  __m256 result5 = zero256;\n  __m256 result6 = zero256;\n  __m256 result7 = zero256;\n\n  int begin4 = program->pixel_offset[x + 4];\n  int begin5 = program->pixel_offset[x + 5];\n  int begin6 = program->pixel_offset[x + 6];\n  int begin7 = program->pixel_offset[x + 7];\n\n  process_four_pixels_h_float_pix4of16_ks_4_8_16_avx2<is_safe, filtersize_hint>(\n    src, begin4, begin5, begin6, begin7, current_coeff, filter_size,\n    result4, result5, result6, result7, unaligned_kernel_size);\n  current_coeff += 4 * filter_size;\n\n  // ---------------------------------------------------------------------------\n  // REDUCTION FOR PIXELS 0-7 (Result256_low)\n  // ---------------------------------------------------------------------------\n\n  // Round 1: Reduce pairs (8 vectors -> 4 vectors)\n  __m256 sum01 = _mm256_hadd_ps(result0, result1);\n  __m256 sum23 = _mm256_hadd_ps(result2, result3);\n  __m256 sum45 = _mm256_hadd_ps(result4, result5);\n  __m256 sum67 = _mm256_hadd_ps(result6, result7);\n\n  // Round 2: Reduce quads (4 vectors -> 2 vectors)\n  __m256 sum0123 = _mm256_hadd_ps(sum01, sum23);\n  __m256 sum4567 = _mm256_hadd_ps(sum45, sum67);\n\n  // Round 3: Final Merge (Add Lower 128-bit to Upper 128-bit)\n  __m128 lo_0123 = _mm256_castps256_ps128(sum0123);\n  __m128 lo_4567 = _mm256_castps256_ps128(sum4567);\n  __m256 result_lo = _mm256_insertf128_ps(_mm256_castps128_ps256(lo_0123), lo_4567, 1);\n\n  __m128 hi_0123 = _mm256_extractf128_ps(sum0123, 1);\n  __m128 hi_4567 = _mm256_extractf128_ps(sum4567, 1);\n  __m256 result_hi = _mm256_insertf128_ps(_mm256_castps128_ps256(hi_0123), hi_4567, 1);\n\n  // Assemble the Low 256-bit result (Pixels 0-7)\n  __m256 result256_low = _mm256_add_ps(result_lo, result_hi);\n  _mm256_stream_ps(reinterpret_cast<float*>(dst + x), result256_low);\n\n\n  // --- Block 3: Pixels 8, 9, 10, 11 ---\n  __m256 result8 = zero256;\n  __m256 result9 = zero256;\n  __m256 result10 = zero256;\n  __m256 result11 = zero256;\n\n  int begin8 = program->pixel_offset[x + 8];\n  int begin9 = program->pixel_offset[x + 9];\n  int begin10 = program->pixel_offset[x + 10];\n  int begin11 = program->pixel_offset[x + 11];\n\n  process_four_pixels_h_float_pix4of16_ks_4_8_16_avx2<is_safe, filtersize_hint>(\n    src, begin8, begin9, begin10, begin11, current_coeff, filter_size,\n    result8, result9, result10, result11, unaligned_kernel_size);\n  current_coeff += 4 * filter_size;\n\n  // --- Block 4: Pixels 12, 13, 14, 15 ---\n  __m256 result12 = zero256;\n  __m256 result13 = zero256;\n  __m256 result14 = zero256;\n  __m256 result15 = zero256;\n\n  int begin12 = program->pixel_offset[x + 12];\n  int begin13 = program->pixel_offset[x + 13];\n  int begin14 = program->pixel_offset[x + 14];\n  int begin15 = program->pixel_offset[x + 15];\n\n  process_four_pixels_h_float_pix4of16_ks_4_8_16_avx2<is_safe, filtersize_hint>(\n    src, begin12, begin13, begin14, begin15, current_coeff, filter_size,\n    result12, result13, result14, result15, unaligned_kernel_size);\n\n\n  // ---------------------------------------------------------------------------\n  // REDUCTION FOR PIXELS 8-15 (Result256_high)\n  // ---------------------------------------------------------------------------\n\n  // Round 1: Reduce pairs (8 vectors -> 4 vectors)\n  __m256 sum89 = _mm256_hadd_ps(result8, result9);\n  __m256 sum1011 = _mm256_hadd_ps(result10, result11);\n  __m256 sum1213 = _mm256_hadd_ps(result12, result13);\n  __m256 sum1415 = _mm256_hadd_ps(result14, result15);\n\n  // Round 2: Reduce quads (4 vectors -> 2 vectors)\n  __m256 sum8_11 = _mm256_hadd_ps(sum89, sum1011);\n  __m256 sum12_15 = _mm256_hadd_ps(sum1213, sum1415);\n\n  // Round 3: Final Merge (Add Lower 128-bit to Upper 128-bit)\n  __m128 lo_8_11 = _mm256_castps256_ps128(sum8_11);\n  __m128 lo_12_15 = _mm256_castps256_ps128(sum12_15);\n  __m256 result_lo_high = _mm256_insertf128_ps(_mm256_castps128_ps256(lo_8_11), lo_12_15, 1);\n\n  __m128 hi_8_11 = _mm256_extractf128_ps(sum8_11, 1);\n  __m128 hi_12_15 = _mm256_extractf128_ps(sum12_15, 1);\n  __m256 result_hi_high = _mm256_insertf128_ps(_mm256_castps128_ps256(hi_8_11), hi_12_15, 1);\n\n  // Assemble the High 256-bit result (Pixels 8-15)\n  __m256 result256_high = _mm256_add_ps(result_lo_high, result_hi_high);\n\n  // ---------------------------------------------------------------------------\n  // Stream the two 256-bit results\n  // ---------------------------------------------------------------------------\n  _mm256_stream_ps(reinterpret_cast<float*>(dst + x + 8), result256_high);\n}\n\n// filtersizealigned8: special: 0, 1..4, Generic : -1\ntemplate<int filtersize_hint>\nstatic void internal_resizer_h_avx2_generic_float_pix16_sub4_ks_4_8_16(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  AVS_UNUSED(bits_per_pixel);\n  // filter_size is aligned to 8 (prerequisite), contrary that we have a special case for filter size <=4\n\n  // We note that when template is used, filter_size is quasi-constexpr if filtersize_hint != -1.\n  // When filtersize_hint == -1, then program->filter_size is aligned to 8 anyway, but not known at compile time.\n  const int filter_size =\n    filtersize_hint == 0 ? 8 : // though we'll optimize for 4 internally, coeff buffer is still allocated for 8\n    (filtersize_hint >= 1) ? filtersize_hint * 8 : program->filter_size; // this latter is always aligned to 8 as well\n\n  const float* src = (float*)src8;\n  float* dst = (float*)dst8;\n  dst_pitch = dst_pitch / sizeof(float);\n  src_pitch = src_pitch / sizeof(float);\n\n  constexpr int PIXELS_AT_A_TIME = 16;\n  // Align safe zone to 16 pixels\n  const int w_safe_mod16 = (program->safelimit_16_pixels.overread_possible ? program->safelimit_16_pixels.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  for (int y = 0; y < height; y++) {\n    float* current_coeff_base = program->pixel_coefficient_float;\n\n    // Process safe aligned pixels\n    for (int x = 0; x < w_safe_mod16; x += PIXELS_AT_A_TIME) {\n      process_sixteen_pixels_h_float_pix16_sub4_ks_4_8_16_avx2<true, filtersize_hint>(src, x, current_coeff_base, filter_size, dst, program);\n    }\n\n    // Process up to the actual kernel size (unsafe zone)\n    for (int x = w_safe_mod16; x < width; x += PIXELS_AT_A_TIME) {\n      process_sixteen_pixels_h_float_pix16_sub4_ks_4_8_16_avx2<false, filtersize_hint>(src, x, current_coeff_base, filter_size, dst, program);\n    }\n\n    dst += dst_pitch;\n    src += src_pitch;\n  }\n}\n\n// Winner implementation: resizer_h_avx2_generic_float_pix16_sub4_ks_4_8_16;\nvoid resizer_h_avx2_generic_float_pix16_sub4_ks_4_8_16(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  const int filter_size = program->filter_size;\n  // Expected alignment\n  assert(program->filter_size_alignment >= 8);\n\n  // Dispatcher template now supports filter_size aligned to 8 (8, 16, 24, 32) and a special case for <=4\n  // Larger filter sizes will use the generic method (-1) which still benefit from 16-8-4 coeff processing blocks.\n  if (filter_size == 1 * 8)\n    if (program->filter_size_real <= 4)\n      internal_resizer_h_avx2_generic_float_pix16_sub4_ks_4_8_16<0>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel); // Internally optimized for 4\n    else\n      internal_resizer_h_avx2_generic_float_pix16_sub4_ks_4_8_16<1>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel); // Internally optimized for 8\n  else if (filter_size == 2 * 8) // Internally optimized for 16\n    internal_resizer_h_avx2_generic_float_pix16_sub4_ks_4_8_16<2>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else if (filter_size == 3 * 8) // Internally optimized for 16+8\n    internal_resizer_h_avx2_generic_float_pix16_sub4_ks_4_8_16<3>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else if (filter_size == 4 * 8) // Internally optimized for 2*16\n    internal_resizer_h_avx2_generic_float_pix16_sub4_ks_4_8_16<4>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else // -1: basic method, use program->filter_size, internally optimized for calculating coeffs in N*16 + 8 + 4 + 2 + 1 blocks\n    internal_resizer_h_avx2_generic_float_pix16_sub4_ks_4_8_16<-1>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\n\n"
  },
  {
    "path": "avs_core/filters/intel/resample_avx2.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Resample_AVX2_H__\n#define __Resample_AVX2_H__\n\n#include <avisynth.h>\n#include \"../resample_functions.h\"\n\nvoid resizer_h_avx2_generic_uint8_t(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\ntemplate<bool lessthan16bit>\nvoid resizer_h_avx2_generic_uint16_t(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\nvoid resizer_h_avx2_generic_float(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\nvoid resizer_h_avx2_generic_float_pix16_sub4_ks_4_8_16(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\nvoid resize_v_avx2_planar_uint8_t(BYTE* dst, const BYTE* src, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel);\n\ntemplate<bool lessthan16bit>\nvoid resize_v_avx2_planar_uint16_t(BYTE* dst0, const BYTE* src0, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel);\n\nvoid resize_v_avx2_planar_float(BYTE* dst0, const BYTE* src0, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel);\n\nvoid resize_v_avx2_planar_float_w_sr(BYTE* dst0, const BYTE* src0, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel);\n\ntemplate<int filtersizemod4>\nvoid resize_h_planar_float_avx_transpose_vstripe_ks4(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\ntemplate<int filtersizemod4>\nvoid resize_h_planar_float_avx2_transpose_vstripe_ks4(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\nvoid resize_h_planar_float_avx2_permutex_vstripe_ks4(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\nvoid resize_h_planar_float_avx2_permutex_vstripe_ks4_pix16(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\n// combined gather + permutex version\ntemplate<int filtersizemod4>\nvoid resize_h_planar_float_avx2_gather_permutex_vstripe_ks4(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\n// Transpose 4x4 blocks within each lane\n#define _MM_TRANSPOSE8_LANE4_PS(row0, row1, row2, row3) \\\n  do { \\\n    __m256 __t0, __t1, __t2, __t3; \\\n    __t0 = _mm256_unpacklo_ps(row0, row1); \\\n    __t1 = _mm256_unpackhi_ps(row0, row1); \\\n    __t2 = _mm256_unpacklo_ps(row2, row3); \\\n    __t3 = _mm256_unpackhi_ps(row2, row3); \\\n    row0 = _mm256_shuffle_ps(__t0, __t2, _MM_SHUFFLE(1, 0, 1, 0)); \\\n    row1 = _mm256_shuffle_ps(__t0, __t2, _MM_SHUFFLE(3, 2, 3, 2)); \\\n    row2 = _mm256_shuffle_ps(__t1, __t3, _MM_SHUFFLE(1, 0, 1, 0)); \\\n    row3 = _mm256_shuffle_ps(__t1, __t3, _MM_SHUFFLE(3, 2, 3, 2)); \\\n  } while (0)\n\n#define _MM_TRANSPOSE8_PS(row0, row1, row2, row3, row4, row5, row6, row7) \\\n  do { \\\n    __m256 __t0, __t1, __t2, __t3, __t4, __t5, __t6, __t7; \\\n    __m256 __tt0, __tt1, __tt2, __tt3, __tt4, __tt5, __tt6, __tt7; \\\n    __t0 = _mm256_unpacklo_ps(row0, row1); \\\n    __t1 = _mm256_unpackhi_ps(row0, row1); \\\n    __t2 = _mm256_unpacklo_ps(row2, row3); \\\n    __t3 = _mm256_unpackhi_ps(row2, row3); \\\n    __t4 = _mm256_unpacklo_ps(row4, row5); \\\n    __t5 = _mm256_unpackhi_ps(row4, row5); \\\n    __t6 = _mm256_unpacklo_ps(row6, row7); \\\n    __t7 = _mm256_unpackhi_ps(row6, row7); \\\n    __tt0 = _mm256_shuffle_ps(__t0, __t2, _MM_SHUFFLE(1, 0, 1, 0)); \\\n    __tt1 = _mm256_shuffle_ps(__t0, __t2, _MM_SHUFFLE(3, 2, 3, 2)); \\\n    __tt2 = _mm256_shuffle_ps(__t1, __t3, _MM_SHUFFLE(1, 0, 1, 0)); \\\n    __tt3 = _mm256_shuffle_ps(__t1, __t3, _MM_SHUFFLE(3, 2, 3, 2)); \\\n    __tt4 = _mm256_shuffle_ps(__t4, __t6, _MM_SHUFFLE(1, 0, 1, 0)); \\\n    __tt5 = _mm256_shuffle_ps(__t4, __t6, _MM_SHUFFLE(3, 2, 3, 2)); \\\n    __tt6 = _mm256_shuffle_ps(__t5, __t7, _MM_SHUFFLE(1, 0, 1, 0)); \\\n    __tt7 = _mm256_shuffle_ps(__t5, __t7, _MM_SHUFFLE(3, 2, 3, 2)); \\\n    row0 = _mm256_permute2f128_ps(__tt0, __tt4, 0x20); \\\n    row1 = _mm256_permute2f128_ps(__tt1, __tt5, 0x20); \\\n    row2 = _mm256_permute2f128_ps(__tt2, __tt6, 0x20); \\\n    row3 = _mm256_permute2f128_ps(__tt3, __tt7, 0x20); \\\n    row4 = _mm256_permute2f128_ps(__tt0, __tt4, 0x31); \\\n    row5 = _mm256_permute2f128_ps(__tt1, __tt5, 0x31); \\\n    row6 = _mm256_permute2f128_ps(__tt2, __tt6, 0x31); \\\n    row7 = _mm256_permute2f128_ps(__tt3, __tt7, 0x31); \\\n  } while (0)\n\n\n\n#ifndef _mm256_loadu_2_m128\n#define _mm256_loadu_2_m128(/* __m128 const* */ loaddr, \\\n                            /* __m128 const* */ hiaddr) \\\n    _mm256_set_m128(_mm_loadu_ps(hiaddr), _mm_loadu_ps(loaddr))\n#endif\n\n#ifndef _mm256_load_2_m128\n#define _mm256_load_2_m128(/* __m128 const* */ loaddr, \\\n                            /* __m128 const* */ hiaddr) \\\n    _mm256_set_m128(_mm_load_ps(hiaddr), _mm_load_ps(loaddr))\n#endif\n\n\n#endif // __Resample_AVX2_H__\n"
  },
  {
    "path": "avs_core/filters/intel/resample_avx512.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include <avs/config.h>\n#include \"../core/internal.h\"\n\n#include <avs/alignment.h>\n#include <avs/minmax.h>\n\n#include \"check_avx512.h\" // compiler avx512 directives check\n#include \"resample_avx512.h\"\n#include <type_traits>\n\n#include <immintrin.h> // Includes AVX-512 intrinsics\n\n#include \"resample_avx512.hpp\"\n\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_ks4_vbmi(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  // true template parameter: VBMI version\n  resize_h_planar_uint8_avx512_permutex_vstripe_ks4_internal<true>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\n\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_ks8_vbmi(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  // true template parameter: VBMI version\n  resize_h_planar_uint8_avx512_permutex_vstripe_ks8_internal<true>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\n\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_2s32_ks8_vbmi(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  // true template parameter: VBMI version\n  resize_h_planar_uint8_avx512_permutex_vstripe_2s32_ks8_internal<true>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\n\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_ks16_vbmi(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  // true template parameter: VBMI version\n  resize_h_planar_uint8_avx512_permutex_vstripe_ks16_internal<true>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\n\n// uint8_t h \"mpz\" avx512base 4,8,16\n\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_vnni(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  // template parameter true: UseVNNI\n  resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_internal<true>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_vnni(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  // template parameter true: UseVNNI\n  resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_internal<true>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_vnni(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  // template parameter true: UseVNNI\n  resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_internal<true>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\n\n\n// uint16_t h \"mp\" avx512fast vnni 4,8,16\n\ntemplate<bool lessthan16bit>\nvoid resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks4_vnni(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  // true template parameter: VNNI version\n  resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks4_internal<lessthan16bit, true>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\ntemplate<bool lessthan16bit>\nvoid resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks8_vnni(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  // true template parameter: VNNI version\n  resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks8_internal<lessthan16bit, true>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\ntemplate<bool lessthan16bit>\nvoid resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_vnni(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  // true template parameter: VNNI version\n  resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_internal<lessthan16bit, true>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\n\n// Explicit template instantiations\ntemplate void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks4_vnni<false>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks4_vnni<true>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks8_vnni<false>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks8_vnni<true>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_vnni<false>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_vnni<true>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n"
  },
  {
    "path": "avs_core/filters/intel/resample_avx512.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Resample_AVX512_H__\n#define __Resample_AVX512_H__\n\n#include <avisynth.h>\n#include \"../resample_functions.h\"\n\n// generic - non specialized filter size\nvoid resizer_h_avx512_generic_uint8_t(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel); // PF debug\ntemplate<bool lessthan16bit>\nvoid resizer_h_avx512_generic_uint16_t(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel); // PF debug\n\n// 8bit samples\ntemplate<bool UseVBMI>\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_ks4_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_ks4_base(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_ks4_vbmi(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate<bool UseVBMI>\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_ks8_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_ks8_base(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_ks8_vbmi(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate<bool UseVBMI>\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_2s32_ks8_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_2s32_ks8_base(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_2s32_ks8_vbmi(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate<bool UseVBMI>\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_ks16_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_ks16_base(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_ks16_vbmi(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\n// 8 bit sample, mpz\ntemplate<bool UseVNNI>\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_base(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_vnni(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\ntemplate<bool UseVNNI>\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_base(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_vnni(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\ntemplate<bool UseVNNI>\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_base(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_vnni(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\n\n// 16bit samples\ntemplate<bool lessthan16bit>\nvoid resize_h_planar_uint16_avx512_permutex_vstripe_ks4(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate<bool lessthan16bit>\nvoid resize_h_planar_uint16_avx512_permutex_vstripe_ks8(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate<bool lessthan16bit>\nvoid resize_h_planar_uint16_avx512_permutex_vstripe_2s16_ks8(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\n// 16 bit samples, mp\ntemplate<bool lessthan16bit, bool UseVNNI>\nvoid resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks4_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate<bool lessthan16bit>\nvoid resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks4_base(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate<bool lessthan16bit>\nvoid resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks4_vnni(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\ntemplate<bool lessthan16bit, bool UseVNNI>\nvoid resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks8_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate<bool lessthan16bit>\nvoid resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks8_base(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate<bool lessthan16bit>\nvoid resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks8_vnni(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\ntemplate<bool lessthan16bit, bool UseVNNI>\nvoid resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate<bool lessthan16bit>\nvoid resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_base(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate<bool lessthan16bit>\nvoid resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_vnni(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\n\n// float32 samples\nvoid resize_h_planar_float_avx512_transpose_vstripe_ks4(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\nvoid resize_h_planar_float_avx512_permutex_vstripe_ks4(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\nvoid resize_h_planar_float_avx512_transpose_vstripe_ks8(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\nvoid resize_h_planar_float_avx512_permutex_vstripe_ks8(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\nvoid resize_h_planar_float_avx512_permutex_vstripe_2s8_ks8(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\nvoid resize_h_planar_float_avx512_permutex_vstripe_ks16(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\nvoid resize_h_planar_float_avx512_permutex_vstripe_2s8_ks16(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\n// Vertical\n\nvoid resize_v_avx512_planar_float(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel);\nvoid resize_v_avx512_planar_float_w_sr(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel);\n// uint8_t\nvoid resize_v_avx512_planar_uint8_t_w_sr(BYTE* AVS_RESTRICT dst, const BYTE* src, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel);\n// uint16_t\ntemplate<bool lessthan16bit>\nvoid resize_v_avx512_planar_uint16_t_w_sr(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel);\n\nvoid resizer_h_avx512_generic_float_pix16_sub4_ks_4_8_16(BYTE * dst8, const BYTE * src8, int dst_pitch, int src_pitch, ResamplingProgram * program, int width, int height, int bits_per_pixel);\n\n#endif // __Resample_AVX512_H__\n"
  },
  {
    "path": "avs_core/filters/intel/resample_avx512.hpp",
    "content": "// AviSynth+.  Copyright 2026- AviSynth+ Project\n// https://avs-plus.net\n// http://avisynth.nl\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n/*\n\nThis is a common source cpp include file (not header) for multi-arch AVX512 functions.\nFunctions here are static, they will be compiled into each translation unit including this file.\n\n*/\n\n// Original function needed avx512vbmi feature flag, but we want to support also base AVX512 without VBMI.\n// We use _mm512_permutex2var_epi8_SIMUL<UseVBMI> and _mm512_maskz_permutex2var_epi8_SIMUL<UseVBMI>\n// Thus both Base AVX512 and ICL level arch is supported.\n// We are using two separated source modules and include this hpp file templated\n// with UseVBMI/UseVNNI\n\n\n// helper function for simulating _mm512_permutex2var_epi8 when VBMI is not available\n// The MSB bit (128) zeroing effect is _not_ considered here, the indices must be all positive and within 0-127 range.\ntemplate<bool UseVBMI>\nAVS_FORCEINLINE static __m512i _mm512_permutex2var_epi8_SIMUL(__m512i a, __m512i idx, __m512i b) {\n  if constexpr (UseVBMI) {\n    return _mm512_permutex2var_epi8(a, idx, b);\n  }\n  else {\n    // Constants\n    const __m512i v_one = _mm512_set1_epi16(1);\n\n    // 1. Extract the byte indices for the first 32 and last 32 target pixels\n    // We expand them to 16-bit so we can treat them as word-indices\n    __m512i idx_lo = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(idx));\n    __m512i idx_hi = _mm512_cvtepu8_epi16(_mm512_extracti64x4_epi64(idx, 1));\n\n    // Helper to process 32 bytes of the result at a time\n    auto get_32_bytes = [&](__m512i target_idx) {\n      // word_idx = byte_idx / 2\n      __m512i word_idx = _mm512_srli_epi16(target_idx, 1);\n\n      // VPERMT2W: Full 512-bit cross-lane word shuffle from 128-byte pool [a, b]\n      __m512i words = _mm512_permutex2var_epi16(a, word_idx, b);\n\n      // If the original byte index was odd, we need the High Byte of the word.\n      // We shift those words right by 8 to put the High Byte into the Low Byte position.\n      __mmask32 mask_odd = _mm512_test_epi16_mask(target_idx, v_one);\n      words = _mm512_mask_srli_epi16(words, mask_odd, words, 8);\n\n      // VPMOVWB: Truncates 32 words to 32 bytes LINEARLY (No lane scrambling)\n      // Returns a __m256i\n      return _mm512_cvtepi16_epi8(words);\n      };\n\n    // 2. Build the two 256-bit halves\n    __m256i res_0_31 = get_32_bytes(idx_lo);\n    __m256i res_32_63 = get_32_bytes(idx_hi);\n\n    // 3. Combine into final __m512i\n    return _mm512_inserti64x4(_mm512_castsi256_si512(res_0_31), res_32_63, 1);\n  }\n}\n\ntemplate<bool UseVBMI>\nAVS_FORCEINLINE static __m512i _mm512_maskz_permutex2var_epi8_SIMUL(\n  __mmask64 k,\n  __m512i a,\n  __m512i idx,\n  __m512i b)\n{\n  if constexpr (UseVBMI) {\n    return _mm512_maskz_permutex2var_epi8(k, a, idx, b);\n  }\n  else {\n    // 1. Run the base simulation to get the permuted bytes\n    // Note: Using your existing logic to get the full 512-bit permuted result\n    __m512i res = _mm512_permutex2var_epi8_SIMUL<false>(a, idx, b);\n\n    // 2. Apply the zero-mask using AVX-512BW\n    // _mm512_maskz_mov_epi8(k, src, src) returns 'src' where k[i]==1, and 0 where k[i]==0\n    return _mm512_maskz_mov_epi8(k, res);\n  }\n}\n\n// H-Float-Resampler: 16 pixels, filter size 4, transpose 4x (4x_m128) to 4x_m512\n// Transposes a 4x4 matrix of 4-float vectors (16x16 float matrix effectively).\n// Input/Output: Four 512-bit vectors (16 floats each) passed by reference.\nAVS_FORCEINLINE static void _MM_TRANSPOSE16_LANE4_PS(__m512& row0, __m512& row1, __m512& row2, __m512& row3) {\n  // Stage 1: Interleave 32-bit (float) elements within 128-bit chunks (lanes)\n  // t0 = (r0_lo, r1_lo) | t1 = (r0_hi, r1_hi)\n  // t2 = (r2_lo, r3_lo) | t3 = (r2_hi, r3_hi)\n  __m512 t0 = _mm512_unpacklo_ps(row0, row1);\n  __m512 t1 = _mm512_unpackhi_ps(row0, row1);\n  __m512 t2 = _mm512_unpacklo_ps(row2, row3);\n  __m512 t3 = _mm512_unpackhi_ps(row2, row3);\n\n  // Stage 2: Shuffle 128-bit chunks (lanes) to complete the transpose\n  // We use _mm512_shuffle_ps which shuffles 64-bit blocks across the 512-bit register.\n  // _MM_SHUFFLE(w, z, y, x) applies to the 64-bit pairs (4 floats) within each 128-bit lane.\n  // Result: row0 = columns 0, 1, 2, 3\n  row0 = _mm512_shuffle_ps(t0, t2, _MM_SHUFFLE(1, 0, 1, 0));\n  // Result: row1 = columns 4, 5, 6, 7\n  row1 = _mm512_shuffle_ps(t0, t2, _MM_SHUFFLE(3, 2, 3, 2));\n  // Result: row2 = columns 8, 9, 10, 11\n  row2 = _mm512_shuffle_ps(t1, t3, _MM_SHUFFLE(1, 0, 1, 0));\n  // Result: row3 = columns 12, 13, 14, 15\n  row3 = _mm512_shuffle_ps(t1, t3, _MM_SHUFFLE(3, 2, 3, 2));\n}\n\n// H-float-resampler: 16 pixels, filter size 8, transpose 8x (2x_m256) to 8x_m512\n// Transposes an 8x8 matrix of 2-float vectors (16x16 float matrix).\n// Input/Output: Eight 512-bit vectors (16 floats each) passed by reference.\nAVS_FORCEINLINE static void _MM_TRANSPOSE8x16_PS(\n  __m512& r0, __m512& r1, __m512& r2, __m512& r3,\n  __m512& r4, __m512& r5, __m512& r6, __m512& r7)\n{\n  // --- Stage 1: Unpack 32-bit (Pairs of rows) ---\n  __m512 t0 = _mm512_unpacklo_ps(r0, r1);\n  __m512 t1 = _mm512_unpackhi_ps(r0, r1);\n  __m512 t2 = _mm512_unpacklo_ps(r2, r3);\n  __m512 t3 = _mm512_unpackhi_ps(r2, r3);\n  __m512 t4 = _mm512_unpacklo_ps(r4, r5);\n  __m512 t5 = _mm512_unpackhi_ps(r4, r5);\n  __m512 t6 = _mm512_unpacklo_ps(r6, r7);\n  __m512 t7 = _mm512_unpackhi_ps(r6, r7);\n\n  // --- Stage 2: Unpack 64-bit (Quads of rows) ---\n  // Uses _mm512_unpacklo/hi_pd for 64-bit (double) to interleave pairs of __m512 floats\n  __m512 u0 = _mm512_castpd_ps(_mm512_unpacklo_pd(_mm512_castps_pd(t0), _mm512_castps_pd(t2)));\n  __m512 u1 = _mm512_castpd_ps(_mm512_unpackhi_pd(_mm512_castps_pd(t0), _mm512_castps_pd(t2)));\n  __m512 u2 = _mm512_castpd_ps(_mm512_unpacklo_pd(_mm512_castps_pd(t1), _mm512_castps_pd(t3)));\n  __m512 u3 = _mm512_castpd_ps(_mm512_unpackhi_pd(_mm512_castps_pd(t1), _mm512_castps_pd(t3)));\n  __m512 u4 = _mm512_castpd_ps(_mm512_unpacklo_pd(_mm512_castps_pd(t4), _mm512_castps_pd(t6)));\n  __m512 u5 = _mm512_castpd_ps(_mm512_unpackhi_pd(_mm512_castps_pd(t4), _mm512_castps_pd(t6)));\n  __m512 u6 = _mm512_castpd_ps(_mm512_unpacklo_pd(_mm512_castps_pd(t5), _mm512_castps_pd(t7)));\n  __m512 u7 = _mm512_castpd_ps(_mm512_unpackhi_pd(_mm512_castps_pd(t5), _mm512_castps_pd(t7)));\n\n  // --- Stage 3: Shuffle 128-bit lanes (Octets of rows) ---\n  // _mm512_shuffle_f32x4 shuffles the 128-bit (f32x4) sub-vectors within and between two __m512 vectors.\n  // 0x88 = (10001000)_2: selects lane 0 from first input and lane 0 from second input for lo/hi 256 bits.\n  // 0xDD = (11011101)_2: selects lane 3 from first input and lane 3 from second input for lo/hi 256 bits.\n  __m512 v0 = _mm512_shuffle_f32x4(u0, u4, 0x88); // Col 0, 4 (interleaved)\n  __m512 v1 = _mm512_shuffle_f32x4(u0, u4, 0xDD); // Col 1, 5 (interleaved)\n  __m512 v2 = _mm512_shuffle_f32x4(u1, u5, 0x88); // Col 2, 6 (interleaved)\n  __m512 v3 = _mm512_shuffle_f32x4(u1, u5, 0xDD); // Col 3, 7 (interleaved)\n  __m512 v4 = _mm512_shuffle_f32x4(u2, u6, 0x88); // Col 8, 12 (interleaved)\n  __m512 v5 = _mm512_shuffle_f32x4(u2, u6, 0xDD); // Col 9, 13 (interleaved)\n  __m512 v6 = _mm512_shuffle_f32x4(u3, u7, 0x88); // Col 10, 14 (interleaved)\n  __m512 v7 = _mm512_shuffle_f32x4(u3, u7, 0xDD); // Col 11, 15 (interleaved)\n\n  // --- Stage 4: Permute to Linearize Indices ---\n  // Corrects the order of the 128-bit lanes to linearize the columns.\n  // The columns are currently: (0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15)\n  // The required order is: (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)\n  __m512i idx = _mm512_setr_epi32(\n    0, 4, 1, 5,    /* Lane 0: Rows 0, 1, 2, 3 */\n    2, 6, 3, 7,    /* Lane 1: Rows 4, 5, 6, 7 */\n    8, 12, 9, 13, /* Lane 2: Rows 8, 9, 10, 11 */\n    10, 14, 11, 15 /* Lane 3: Rows 12, 13, 14, 15 */\n  );\n\n  // --- Final Assignment with Correct Mapping ---\n  // Maps the permuted vector components back to the original row variables (now columns).\n  r0 = _mm512_permutexvar_ps(idx, v0); // Col 0\n  r1 = _mm512_permutexvar_ps(idx, v2); // Col 1\n  r2 = _mm512_permutexvar_ps(idx, v4); // Col 2\n  r3 = _mm512_permutexvar_ps(idx, v6); // Col 3\n  r4 = _mm512_permutexvar_ps(idx, v1); // Col 4\n  r5 = _mm512_permutexvar_ps(idx, v3); // Col 5\n  r6 = _mm512_permutexvar_ps(idx, v5); // Col 6\n  r7 = _mm512_permutexvar_ps(idx, v7); // Col 7\n}\n\n// Loads two 256-bit float vectors from registers (__m256) into a single 512-bit register.\n// Equivalent to _mm512_insertf32x8(_mm512_castps256_ps512(lo), hi, 1)\nAVS_FORCEINLINE static __m512 _mm512_insert_2_m256(__m256 lo, __m256 hi) {\n  return _mm512_insertf32x8(_mm512_castps256_ps512(lo), hi, 1);\n}\n\n// Loads four 128-bit float vectors (unaligned) into a single 512-bit register.\nAVS_FORCEINLINE static __m512 _mm512_loadu_4_m128(\n  /* __m128 const* */ const float* addr1,\n  /* __m128 const* */ const float* addr2,\n  /* __m128 const* */ const float* addr3,\n  /* __m128 const* */ const float* addr4)\n{\n  // The cast is needed for the first insertion to make the target a 512-bit register\n  __m512 v = _mm512_castps128_ps512(_mm_loadu_ps(addr1));\n  v = _mm512_insertf32x4(v, _mm_loadu_ps(addr2), 1);\n  v = _mm512_insertf32x4(v, _mm_loadu_ps(addr3), 2);\n  v = _mm512_insertf32x4(v, _mm_loadu_ps(addr4), 3);\n  return v;\n}\n\n// Loads four 128-bit float vectors (aligned) into a single 512-bit register.\nAVS_FORCEINLINE static __m512 _mm512_load_4_m128(\n  /* __m128 const* */ const float* addr1,\n  /* __m128 const* */ const float* addr2,\n  /* __m128 const* */ const float* addr3,\n  /* __m128 const* */ const float* addr4)\n{\n  // The cast is needed for the first insertion to make the target a 512-bit register\n  __m512 v = _mm512_castps128_ps512(_mm_load_ps(addr1));\n  v = _mm512_insertf32x4(v, _mm_load_ps(addr2), 1);\n  v = _mm512_insertf32x4(v, _mm_load_ps(addr3), 2);\n  v = _mm512_insertf32x4(v, _mm_load_ps(addr4), 3);\n  return v;\n}\n\n// Loads two 256 - bit unaligned integer vectors from registers(__m256i) into a single 512i register.\nAVS_FORCEINLINE static __m512i _mm512i_loadu_2_m256i(\n  const __m256i* addr1,\n  const __m256i* addr2)\n{\n  return _mm512_inserti64x4(_mm512_castsi256_si512(_mm256_loadu_si256(addr1)), _mm256_loadu_si256(addr2), 1);\n}\n\n// Loads two 256 - bit aligned integer vectors from registers(__m256) into a single 512 - bit register.\nAVS_FORCEINLINE static __m512i _mm512i_load_2_m256i(\n  const __m256i* addr1,\n  const __m256i* addr2)\n{\n  return _mm512_inserti64x4(_mm512_castsi256_si512(_mm256_load_si256(addr1)), _mm256_load_si256(addr2), 1);\n}\n\n// Integers\n// Loads four 128-bit integer vectors (unaligned) into a single 512-bit integer register.\nAVS_FORCEINLINE static __m512i _mm512i_loadu_4_m128i(\n  const __m128i* addr1,\n  const __m128i* addr2,\n  const __m128i* addr3,\n  const __m128i* addr4)\n{\n  // The cast is needed for the first insertion to make the target a 512-bit register\n  __m512i v = _mm512_castsi128_si512(_mm_loadu_si128(addr1));\n  v = _mm512_inserti32x4(v, _mm_loadu_si128(addr2), 1);\n  v = _mm512_inserti32x4(v, _mm_loadu_si128(addr3), 2);\n  v = _mm512_inserti32x4(v, _mm_loadu_si128(addr4), 3);\n  return v;\n}\n\n// filter size up to 4\n// 64 target uint8_t pixels at a time\n// 128-byte source loads (128 uint8_t pixels)\n// maximum permute index is 128 for _mm512_permutex2var_epi8 (uint8_t)\ntemplate<bool UseVBMI>\nstatic void resize_h_planar_uint8_avx512_permutex_vstripe_ks4_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)\n{\n  const int filter_size = program->filter_size; // aligned, practically the coeff table stride\n\n  constexpr int PIXELS_AT_A_TIME = 64;\n\n  // 'source_overread_beyond_targetx' indicates if the filter kernel can read beyond the target width.\n  // we load 2x64 source bytes at a time, so ensure safe overread if needed.\n  // Our main loop processes calculates for 64 target pixels at a time.\n  // Inside that, we load 128 source bytes (2x64) to be able to permutex from that.\n  // This we have to check at each mod-PIXELS_AT_A_TIME boundary, the allowance of 128-byte source load.\n  const int width_safe_mod = (program->safelimit_128_pixels_each64th_target.overread_possible ? program->safelimit_128_pixels_each64th_target.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  // Preconditions:\n  assert(program->filter_size_real <= 4); // We preload all relevant coefficients (up to 4) before the height loop.\n\n  // 'target_size_alignment' ensures we can safely access coefficients using offsets like\n  // 'filter_size * 15' when processing 16 H pixels at a time\n  // 'filter_size * 63' when processing 64 H pixels at a time\n  assert(program->target_size_alignment >= 64); // Adjusted for 64 pixels (is it enough for uint8 ?)\n\n  assert(FRAME_ALIGN >= 64); // Good for 64x8 bit pixels\n\n  // Ensure that coefficient loading beyond the valid target size is safe for 4x4 float loads.\n  // We load 4x16bit coeffs at a time\n  assert(program->filter_size_alignment >= 4);\n\n  const int max_scanlines = program->max_scanlines;\n\n  __m512i rounder = _mm512_set1_epi32(1 << (FPScale8bits - 1));\n\n  // Vertical stripe loop for L2 cache optimization\n  for (int y_from = 0; y_from < height; y_from += max_scanlines)\n  {\n    int y_to = std::min(y_from + max_scanlines, height);\n\n    // Reset current_coeff for the start of the stripe (points to start of row's coeffs)\n    const short* AVS_RESTRICT current_coeff = program->pixel_coefficient;\n\n    int x = 0;\n\n    // Lambda to handle both safe (fast) and unsafe (masked/partial) loading paths\n    auto do_h_integer_core = [&](auto partial_load) {\n\n      // prepare coefs in transposed V-form\n      // TODO: make storage in transposed form, 64 x uint16 transposition looks too slow\n      // TO FIX: filter_size=4 resize uses filter_size=16 - lots or RAM/cache wasted, in the ready to use transposed form it will be much more optimized\n\n      // 4coefs of 16bit is 64bits, can be loaded as set_epi64 ?\n      __m512i coef_0_7 = _mm512_setr_epi64(\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 0),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 1),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 2),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 3),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 4),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 5),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 6),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 7)\n      );\n\n      __m512i coef_8_15 = _mm512_setr_epi64(\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 8),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 9),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 10),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 11),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 12),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 13),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 14),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 15)\n      );\n\n      __m512i coef_16_23 = _mm512_setr_epi64(\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 16),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 17),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 18),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 19),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 20),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 21),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 22),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 23)\n      );\n\n      __m512i coef_24_31 = _mm512_setr_epi64(\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 24),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 25),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 26),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 27),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 28),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 29),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 30),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 31)\n      );\n\n      __m512i coef_32_39 = _mm512_setr_epi64(\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 32),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 33),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 34),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 35),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 36),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 37),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 38),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 39)\n      );\n\n      __m512i coef_40_47 = _mm512_setr_epi64(\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 40),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 41),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 42),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 43),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 44),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 45),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 46),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 47)\n      );\n\n      __m512i coef_48_55 = _mm512_setr_epi64(\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 48),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 49),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 50),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 51),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 52),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 53),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 54),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 55)\n      );\n\n      __m512i coef_56_63 = _mm512_setr_epi64(\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 56),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 57),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 58),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 59),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 60),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 61),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 62),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 63)\n      );\n\n      // Transpose with permutex\n      __m512i c_perm_0 = _mm512_set_epi16(28 + 32, 24 + 32, 20 + 32, 16 + 32, 12 + 32, 8 + 32, 4 + 32, 0 + 32, 28, 24, 20, 16, 12, 8, 4, 0,\n        28 + 32, 24 + 32, 20 + 32, 16 + 32, 12 + 32, 8 + 32, 4 + 32, 0 + 32, 28, 24, 20, 16, 12, 8, 4, 0);\n      __m512i one_epi16 = _mm512_set1_epi16(1);\n      const __mmask32 k_high = 0xFFFF0000;\n      // 0.0 .. 15.0 in low 256, 16.0 .. 31.0 in high 256\n      __m512i coef_r0_0_31w = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(coef_0_7, c_perm_0, coef_8_15), _mm512_permutex2var_epi16(coef_16_23, c_perm_0, coef_24_31));\n      // 32.0 .. 47.0  in low 256, 48.0 .. 63.0 in high 256\n      __m512i coef_r0_32_63w = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(coef_32_39, c_perm_0, coef_40_47), _mm512_permutex2var_epi16(coef_48_55, c_perm_0, coef_56_63));\n      c_perm_0 = _mm512_add_epi16(c_perm_0, one_epi16);\n      __m512i coef_r1_0_31w = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(coef_0_7, c_perm_0, coef_8_15), _mm512_permutex2var_epi16(coef_16_23, c_perm_0, coef_24_31));\n      __m512i coef_r1_32_63w = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(coef_32_39, c_perm_0, coef_40_47), _mm512_permutex2var_epi16(coef_48_55, c_perm_0, coef_56_63));\n      c_perm_0 = _mm512_add_epi16(c_perm_0, one_epi16);\n      __m512i coef_r2_0_31w = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(coef_0_7, c_perm_0, coef_8_15), _mm512_permutex2var_epi16(coef_16_23, c_perm_0, coef_24_31));\n      __m512i coef_r2_32_63w = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(coef_32_39, c_perm_0, coef_40_47), _mm512_permutex2var_epi16(coef_48_55, c_perm_0, coef_56_63));\n      c_perm_0 = _mm512_add_epi16(c_perm_0, one_epi16);\n      __m512i coef_r3_0_31w = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(coef_0_7, c_perm_0, coef_8_15), _mm512_permutex2var_epi16(coef_16_23, c_perm_0, coef_24_31));\n      __m512i coef_r3_32_63w = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(coef_32_39, c_perm_0, coef_40_47), _mm512_permutex2var_epi16(coef_48_55, c_perm_0, coef_56_63));\n\n      // convert-transpose to H-pairs for madd ? better to do with single permutex in future\n      // 8 to 8 512 registers - finally real working coeffs to store in the transposed resampling program for block of 64 target samples\n      __m512i coef_r0r1_0_31lo = _mm512_unpacklo_epi16(coef_r0_0_31w, coef_r1_0_31w);\n      __m512i coef_r0r1_0_31hi = _mm512_unpackhi_epi16(coef_r0_0_31w, coef_r1_0_31w);\n\n      __m512i coef_r0r1_32_63lo = _mm512_unpacklo_epi16(coef_r0_32_63w, coef_r1_32_63w);\n      __m512i coef_r0r1_32_63hi = _mm512_unpackhi_epi16(coef_r0_32_63w, coef_r1_32_63w);\n\n      __m512i coef_r2r3_0_31lo = _mm512_unpacklo_epi16(coef_r2_0_31w, coef_r3_0_31w);\n      __m512i coef_r2r3_0_31hi = _mm512_unpackhi_epi16(coef_r2_0_31w, coef_r3_0_31w);\n\n      __m512i coef_r2r3_32_63lo = _mm512_unpacklo_epi16(coef_r2_32_63w, coef_r3_32_63w);\n      __m512i coef_r2r3_32_63hi = _mm512_unpackhi_epi16(coef_r2_32_63w, coef_r3_32_63w);\n\n      // TODO: store transposed resampling program coeffs to temp buffer for reusage at each line\n\n      // convert resampling program in H-form into permuting indexes for src transposition in V-form\n      __m512i perm_0_0_15 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x])); // 16 offsets\n      __m512i perm_0_16_31 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 16])); //  16 offsets\n      __m512i perm_0_32_47 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 32])); //  16 offsets\n      __m512i perm_0_48_63 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 48])); //  16 offsets\n\n      int iStart = program->pixel_offset[x];\n      __m512i m512i_Start = _mm512_set1_epi32(iStart);\n\n      perm_0_0_15 = _mm512_sub_epi32(perm_0_0_15, m512i_Start);\n      perm_0_16_31 = _mm512_sub_epi32(perm_0_16_31, m512i_Start);\n      perm_0_32_47 = _mm512_sub_epi32(perm_0_32_47, m512i_Start);\n      perm_0_48_63 = _mm512_sub_epi32(perm_0_48_63, m512i_Start);\n\n      __m256i m256i_perm_0_0_15 = _mm512_cvtepi32_epi16(perm_0_0_15);\n      __m256i m256i_perm_0_16_31 = _mm512_cvtepi32_epi16(perm_0_16_31);\n      __m256i m256i_perm_0_32_47 = _mm512_cvtepi32_epi16(perm_0_32_47);\n      __m256i m256i_perm_0_48_63 = _mm512_cvtepi32_epi16(perm_0_48_63);\n\n      __m128i mm128i_perm_0_0_15 = _mm256_cvtepi16_epi8(m256i_perm_0_0_15);\n      __m128i mm128i_perm_0_16_31 = _mm256_cvtepi16_epi8(m256i_perm_0_16_31);\n      __m128i mm128i_perm_0_32_47 = _mm256_cvtepi16_epi8(m256i_perm_0_32_47);\n      __m128i mm128i_perm_0_48_63 = _mm256_cvtepi16_epi8(m256i_perm_0_48_63);\n\n      // Insert each 128-bit register into the specific lane\n      __m512i perm_0 = _mm512_inserti32x4(_mm512_setzero_si512(), mm128i_perm_0_0_15, 0); // Lane 0\n      perm_0 = _mm512_inserti32x4(perm_0, mm128i_perm_0_16_31, 1); // Lane 1\n      perm_0 = _mm512_inserti32x4(perm_0, mm128i_perm_0_32_47, 2); // Lane 2\n      perm_0 = _mm512_inserti32x4(perm_0, mm128i_perm_0_48_63, 3); // Lane 3\n\n      // Taps are contiguous (0, 1, 2, 3), so we increment perm indexes by 1.\n      __m512i one_epi8 = _mm512_set1_epi8(1);\n      __m512i perm_1 = _mm512_add_epi8(perm_0, one_epi8);\n      __m512i perm_2 = _mm512_add_epi8(perm_1, one_epi8);\n      __m512i perm_3 = _mm512_add_epi8(perm_2, one_epi8);\n\n      uint8_t* AVS_RESTRICT dst_ptr = dst8 + x + y_from * dst_pitch;\n      const uint8_t* src_ptr = src8 + iStart + y_from * src_pitch; // all permute offsets relative to this start offset\n\n      // Calculate remaining pixels for bounds checking in partial_load mode. 1..128 remaining pixels possible.\n      const int remaining = program->source_size - iStart;\n      const __mmask64 k1 = _bzhi_u64(~0ULL, remaining); // _bzhi_u64 creates a mask with the lower N bits set. If N >= 64, it returns all ones (~0ULL). \n      const __mmask64 k2 = _bzhi_u64(~0ULL, std::max(0, remaining - 64));\n\n      for (int y = y_from; y < y_to; y++)\n      {\n        __m512i data_src, data_src2;\n\n        if constexpr (partial_load) {\n          // Safe masked loads for the image edge\n          data_src = _mm512_maskz_loadu_epi8(k1, src_ptr);\n          data_src2 = _mm512_maskz_loadu_epi8(k2, src_ptr + 64);\n        }\n        else {\n          // Fast unaligned loads for the safe zone\n          data_src = _mm512_loadu_si512(src_ptr);\n          data_src2 = _mm512_loadu_si512(src_ptr + 64);\n        }\n\n        __m512i data_0 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_0, data_src2);\n        __m512i data_1 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_1, data_src2);\n        __m512i data_2 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_2, data_src2);\n        __m512i data_3 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_3, data_src2);\n\n        // unpack 8->16bit 4 to 8 512bit registers source\n        __m512i src_r0_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_0));\n        __m512i src_r0_32_63 = _mm512_cvtepu8_epi16(_mm512_extracti64x4_epi64(data_0, 1));\n\n        __m512i src_r1_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_1));\n        __m512i src_r1_32_63 = _mm512_cvtepu8_epi16(_mm512_extracti64x4_epi64(data_1, 1));\n\n        __m512i src_r2_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_2));\n        __m512i src_r2_32_63 = _mm512_cvtepu8_epi16(_mm512_extracti64x4_epi64(data_2, 1));\n\n        __m512i src_r3_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_3));\n        __m512i src_r3_32_63 = _mm512_cvtepu8_epi16(_mm512_extracti64x4_epi64(data_3, 1));\n\n        // transposition to H-pairs 8 to 8 512bit registers (?)\n        __m512i src_r0r1_0_31lo = _mm512_unpacklo_epi16(src_r0_0_31, src_r1_0_31);\n        __m512i src_r0r1_0_31hi = _mm512_unpackhi_epi16(src_r0_0_31, src_r1_0_31);\n\n        __m512i src_r0r1_32_63lo = _mm512_unpacklo_epi16(src_r0_32_63, src_r1_32_63);\n        __m512i src_r0r1_32_63hi = _mm512_unpackhi_epi16(src_r0_32_63, src_r1_32_63);\n\n        __m512i src_r2r3_0_31lo = _mm512_unpacklo_epi16(src_r2_0_31, src_r3_0_31);\n        __m512i src_r2r3_0_31hi = _mm512_unpackhi_epi16(src_r2_0_31, src_r3_0_31);\n\n        __m512i src_r2r3_32_63lo = _mm512_unpacklo_epi16(src_r2_32_63, src_r3_32_63);\n        __m512i src_r2r3_32_63hi = _mm512_unpackhi_epi16(src_r2_32_63, src_r3_32_63);\n\n        // making FMA in 32bits accs as in AVX256 V-resize\n        __m512i result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31lo, coef_r0r1_0_31lo), _mm512_madd_epi16(src_r2r3_0_31lo, coef_r2r3_0_31lo));\n        __m512i result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31hi, coef_r0r1_0_31hi), _mm512_madd_epi16(src_r2r3_0_31hi, coef_r2r3_0_31hi));\n\n        __m512i result_32_63lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_32_63lo, coef_r0r1_32_63lo), _mm512_madd_epi16(src_r2r3_32_63lo, coef_r2r3_32_63lo));\n        __m512i result_32_63hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_32_63hi, coef_r0r1_32_63hi), _mm512_madd_epi16(src_r2r3_32_63hi, coef_r2r3_32_63hi));\n\n        // rounding\n        result_0_31lo = _mm512_add_epi32(result_0_31lo, rounder);\n        result_0_31hi = _mm512_add_epi32(result_0_31hi, rounder);\n        result_32_63lo = _mm512_add_epi32(result_32_63lo, rounder);\n        result_32_63hi = _mm512_add_epi32(result_32_63hi, rounder);\n        // scaling down\n        result_0_31lo = _mm512_srai_epi32(result_0_31lo, FPScale8bits);\n        result_0_31hi = _mm512_srai_epi32(result_0_31hi, FPScale8bits);\n        result_32_63lo = _mm512_srai_epi32(result_32_63lo, FPScale8bits);\n        result_32_63hi = _mm512_srai_epi32(result_32_63hi, FPScale8bits);\n\n        __m512i result_0_31_int16 = _mm512_packus_epi32(result_0_31lo, result_0_31hi);\n        __m512i result_32_63_int16 = _mm512_packus_epi32(result_32_63lo, result_32_63hi);\n\n        __m256i result_0_31_u8 = _mm512_cvtusepi16_epi8(result_0_31_int16);\n        __m256i result_32_63_u8 = _mm512_cvtusepi16_epi8(result_32_63_int16);\n\n        // cast is enough, no need to use zeroextend\n        _mm512_stream_si512(reinterpret_cast<__m512i*>(dst_ptr),\n          _mm512_inserti64x4(_mm512_castsi256_si512(result_0_31_u8), result_32_63_u8, 1));\n\n        dst_ptr += dst_pitch;\n        src_ptr += src_pitch;\n      }\n\n      current_coeff += filter_size * PIXELS_AT_A_TIME;\n      };\n\n    // Process the 'safe zone' where direct full unaligned loads are acceptable.\n    for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)\n    {\n      do_h_integer_core(std::false_type{});\n    }\n\n    // Process the potentially 'unsafe zone' near the image edge, using safe masked loading.\n    for (; x < width; x += PIXELS_AT_A_TIME)\n    {\n      do_h_integer_core(std::true_type{});\n    }\n  }\n}\n\n// filter size up to 8\n// 64 target uint8_t pixels at a time\n// 128-byte source loads (128 uint8_t pixels)\n// maximum permute index is 128 for _mm512_permutex2var_epi8(uint8_t)\ntemplate<bool UseVBMI>\nstatic void resize_h_planar_uint8_avx512_permutex_vstripe_ks8_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)\n{\n  const int filter_size = program->filter_size; // aligned, practically the coeff table stride\n\n  constexpr int PIXELS_AT_A_TIME = 64;\n\n  // 'source_overread_beyond_targetx' indicates if the filter kernel can read beyond the target width.\n  // we load 2x64 source bytes at a time, so ensure safe overread if needed.\n  // Our main loop processes calculates for 64 target pixels at a time.\n  // Inside that, we load 128 source bytes (2x64) to be able to permutex from that.\n  // This we have to check at each mod-PIXELS_AT_A_TIME boundary, the allowance of 128-byte source load.\n  const int width_safe_mod = (program->safelimit_128_pixels_each64th_target.overread_possible ? program->safelimit_128_pixels_each64th_target.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  // Preconditions:\n  assert(program->filter_size_real <= 8); // We preload all relevant coefficients (up to 8) before the height loop.\n\n  // 'target_size_alignment' ensures we can safely access coefficients using offsets like\n  // 'filter_size * 15' when processing 16 H pixels at a time\n  // 'filter_size * 63' when processing 64 H pixels at a time\n  assert(program->target_size_alignment >= 64); // Adjusted for 64 pixels (is it enough for uint8 ?)\n\n  assert(FRAME_ALIGN >= 64); // Good for 64x8 bit pixels\n\n  // Ensure that coefficient loading beyond the valid target size is safe for 4x8 float loads.\n  // We load 8x 'short' coeffs at a time\n  // Loading is unaligned, but we fill __m128 registers before combining into __m512\n  assert(program->filter_size_alignment >= 8);\n\n  const int max_scanlines = program->max_scanlines;\n\n  __m512i rounder = _mm512_set1_epi32(1 << (FPScale8bits - 1));\n\n  // Vertical stripe loop for L2 cache optimization\n  for (int y_from = 0; y_from < height; y_from += max_scanlines)\n  {\n    int y_to = std::min(y_from + max_scanlines, height);\n\n    // Reset current_coeff for the start of the stripe (points to start of row's coeffs)\n    const short* AVS_RESTRICT current_coeff = program->pixel_coefficient;\n\n    int x = 0;\n\n    // Lambda to handle both safe (fast) and unsafe (masked/partial) loading paths\n    auto do_h_integer_core = [&](auto partial_load) {\n\n      // prepare coefs in transposed V-form\n      // TODO: make storage in transposed form, 64 x uint16 transposition looks too slow\n\n      // 8coefs of 16bit is 128bits \n      __m512i coef_0_3 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 0), (__m128i*)(current_coeff + filter_size * 1), (__m128i*)(current_coeff + filter_size * 2), (__m128i*)(current_coeff + filter_size * 3));\n      __m512i coef_4_7 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 4), (__m128i*)(current_coeff + filter_size * 5), (__m128i*)(current_coeff + filter_size * 6), (__m128i*)(current_coeff + filter_size * 7));\n      __m512i coef_8_11 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 8), (__m128i*)(current_coeff + filter_size * 9), (__m128i*)(current_coeff + filter_size * 10), (__m128i*)(current_coeff + filter_size * 11));\n      __m512i coef_12_15 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 12), (__m128i*)(current_coeff + filter_size * 13), (__m128i*)(current_coeff + filter_size * 14), (__m128i*)(current_coeff + filter_size * 15));\n      __m512i coef_16_19 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 16), (__m128i*)(current_coeff + filter_size * 17), (__m128i*)(current_coeff + filter_size * 18), (__m128i*)(current_coeff + filter_size * 19));\n      __m512i coef_20_23 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 20), (__m128i*)(current_coeff + filter_size * 21), (__m128i*)(current_coeff + filter_size * 22), (__m128i*)(current_coeff + filter_size * 23));\n      __m512i coef_24_27 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 24), (__m128i*)(current_coeff + filter_size * 25), (__m128i*)(current_coeff + filter_size * 26), (__m128i*)(current_coeff + filter_size * 27));\n      __m512i coef_28_31 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 28), (__m128i*)(current_coeff + filter_size * 29), (__m128i*)(current_coeff + filter_size * 30), (__m128i*)(current_coeff + filter_size * 31));\n\n      __m512i coef_32_35 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 32), (__m128i*)(current_coeff + filter_size * 33), (__m128i*)(current_coeff + filter_size * 34), (__m128i*)(current_coeff + filter_size * 35));\n      __m512i coef_36_39 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 36), (__m128i*)(current_coeff + filter_size * 37), (__m128i*)(current_coeff + filter_size * 38), (__m128i*)(current_coeff + filter_size * 39));\n      __m512i coef_40_43 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 40), (__m128i*)(current_coeff + filter_size * 41), (__m128i*)(current_coeff + filter_size * 42), (__m128i*)(current_coeff + filter_size * 43));\n      __m512i coef_44_47 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 44), (__m128i*)(current_coeff + filter_size * 45), (__m128i*)(current_coeff + filter_size * 46), (__m128i*)(current_coeff + filter_size * 47));\n      __m512i coef_48_51 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 48), (__m128i*)(current_coeff + filter_size * 49), (__m128i*)(current_coeff + filter_size * 50), (__m128i*)(current_coeff + filter_size * 51));\n      __m512i coef_52_55 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 52), (__m128i*)(current_coeff + filter_size * 53), (__m128i*)(current_coeff + filter_size * 54), (__m128i*)(current_coeff + filter_size * 55));\n      __m512i coef_56_59 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 56), (__m128i*)(current_coeff + filter_size * 57), (__m128i*)(current_coeff + filter_size * 58), (__m128i*)(current_coeff + filter_size * 59));\n      __m512i coef_60_63 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 60), (__m128i*)(current_coeff + filter_size * 61), (__m128i*)(current_coeff + filter_size * 62), (__m128i*)(current_coeff + filter_size * 63));\n\n      // Transpose with permutex\n      __m512i c_perm_0_7 = _mm512_set_epi16(\n        0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0,\n        24 + 32, 16 + 32, 8 + 32, 0 + 32, 24, 16, 8, 0);\n      __m512i c_perm_8_15 = _mm512_set_epi16(\n        0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0,\n        24 + 32, 16 + 32, 8 + 32, 0 + 32, 24, 16, 8, 0,\n        0, 0, 0, 0, 0, 0, 0, 0);\n      __m512i c_perm_16_23 = _mm512_set_epi16(\n        0, 0, 0, 0, 0, 0, 0, 0,\n        24 + 32, 16 + 32, 8 + 32, 0 + 32, 24, 16, 8, 0,\n        0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0);\n      __m512i c_perm_24_31 = _mm512_set_epi16(\n        24 + 32, 16 + 32, 8 + 32, 0 + 32, 24, 16, 8, 0,\n        0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0);\n\n      __m512i one_epi16 = _mm512_set1_epi16(1);\n      const __mmask32 k_8_15 = 0x0000FF00;\n      const __mmask32 k_16_23 = 0x00FF0000;\n      const __mmask32 k_24_31 = 0xFF000000;\n\n      auto inc_perms = [&](\n        __m512i& c0_7,\n        __m512i& c8_15,\n        __m512i& c16_23,\n        __m512i& c24_31\n        ) {\n          c0_7 = _mm512_add_epi16(c0_7, one_epi16);\n          c8_15 = _mm512_add_epi16(c8_15, one_epi16);\n          c16_23 = _mm512_add_epi16(c16_23, one_epi16);\n          c24_31 = _mm512_add_epi16(c24_31, one_epi16);\n        };\n\n      auto make_row_0_63 = [&](\n        __m512i& row_0_31w, __m512i& row_32_63w,\n        __m512i c0_7, __m512i c8_15, __m512i c16_23, __m512i c24_31\n        ) {\n          // 0..31\n          row_0_31w = _mm512_mask_blend_epi16(\n            k_8_15,\n            _mm512_permutex2var_epi16(coef_0_3, c0_7, coef_4_7),\n            _mm512_permutex2var_epi16(coef_8_11, c8_15, coef_12_15)\n          );\n          row_0_31w = _mm512_mask_blend_epi16(\n            k_16_23,\n            row_0_31w,\n            _mm512_permutex2var_epi16(coef_16_19, c16_23, coef_20_23)\n          );\n          row_0_31w = _mm512_mask_blend_epi16(\n            k_24_31,\n            row_0_31w,\n            _mm512_permutex2var_epi16(coef_24_27, c24_31, coef_28_31)\n          );\n\n          // 32..63\n          row_32_63w = _mm512_mask_blend_epi16(\n            k_8_15,\n            _mm512_permutex2var_epi16(coef_32_35, c0_7, coef_36_39),\n            _mm512_permutex2var_epi16(coef_40_43, c8_15, coef_44_47)\n          );\n          row_32_63w = _mm512_mask_blend_epi16(\n            k_16_23,\n            row_32_63w,\n            _mm512_permutex2var_epi16(coef_48_51, c16_23, coef_52_55)\n          );\n          row_32_63w = _mm512_mask_blend_epi16(\n            k_24_31,\n            row_32_63w,\n            _mm512_permutex2var_epi16(coef_56_59, c24_31, coef_60_63)\n          );\n        };\n\n      __m512i coef_r0_0_31w, coef_r0_32_63w;\n      __m512i coef_r1_0_31w, coef_r1_32_63w;\n      __m512i coef_r2_0_31w, coef_r2_32_63w;\n      __m512i coef_r3_0_31w, coef_r3_32_63w;\n      __m512i coef_r4_0_31w, coef_r4_32_63w;\n      __m512i coef_r5_0_31w, coef_r5_32_63w;\n      __m512i coef_r6_0_31w, coef_r6_32_63w;\n      __m512i coef_r7_0_31w, coef_r7_32_63w;\n\n      // r0\n      make_row_0_63(coef_r0_0_31w, coef_r0_32_63w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r1\n      make_row_0_63(coef_r1_0_31w, coef_r1_32_63w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r2\n      make_row_0_63(coef_r2_0_31w, coef_r2_32_63w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r3\n      make_row_0_63(coef_r3_0_31w, coef_r3_32_63w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r4\n      make_row_0_63(coef_r4_0_31w, coef_r4_32_63w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r5\n      make_row_0_63(coef_r5_0_31w, coef_r5_32_63w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r6\n      make_row_0_63(coef_r6_0_31w, coef_r6_32_63w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r7\n      make_row_0_63(coef_r7_0_31w, coef_r7_32_63w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      /* // last one, not needed\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      */\n\n      // convert-transpose to H-pairs for madd ? better to do with single permutex in future\n      // 16 to 16 512 registers - finally real working coeffs to store in the transposed resampling program for block of 64 target samples\n      __m512i coef_r0r1_0_31lo = _mm512_unpacklo_epi16(coef_r0_0_31w, coef_r1_0_31w);\n      __m512i coef_r0r1_0_31hi = _mm512_unpackhi_epi16(coef_r0_0_31w, coef_r1_0_31w);\n\n      __m512i coef_r0r1_32_63lo = _mm512_unpacklo_epi16(coef_r0_32_63w, coef_r1_32_63w);\n      __m512i coef_r0r1_32_63hi = _mm512_unpackhi_epi16(coef_r0_32_63w, coef_r1_32_63w);\n\n      __m512i coef_r2r3_0_31lo = _mm512_unpacklo_epi16(coef_r2_0_31w, coef_r3_0_31w);\n      __m512i coef_r2r3_0_31hi = _mm512_unpackhi_epi16(coef_r2_0_31w, coef_r3_0_31w);\n\n      __m512i coef_r2r3_32_63lo = _mm512_unpacklo_epi16(coef_r2_32_63w, coef_r3_32_63w);\n      __m512i coef_r2r3_32_63hi = _mm512_unpackhi_epi16(coef_r2_32_63w, coef_r3_32_63w);\n\n      __m512i coef_r4r5_0_31lo = _mm512_unpacklo_epi16(coef_r4_0_31w, coef_r5_0_31w);\n      __m512i coef_r4r5_0_31hi = _mm512_unpackhi_epi16(coef_r4_0_31w, coef_r5_0_31w);\n\n      __m512i coef_r4r5_32_63lo = _mm512_unpacklo_epi16(coef_r4_32_63w, coef_r5_32_63w);\n      __m512i coef_r4r5_32_63hi = _mm512_unpackhi_epi16(coef_r4_32_63w, coef_r5_32_63w);\n\n      __m512i coef_r6r7_0_31lo = _mm512_unpacklo_epi16(coef_r6_0_31w, coef_r7_0_31w);\n      __m512i coef_r6r7_0_31hi = _mm512_unpackhi_epi16(coef_r6_0_31w, coef_r7_0_31w);\n\n      __m512i coef_r6r7_32_63lo = _mm512_unpacklo_epi16(coef_r6_32_63w, coef_r7_32_63w);\n      __m512i coef_r6r7_32_63hi = _mm512_unpackhi_epi16(coef_r6_32_63w, coef_r7_32_63w);\n\n      // TODO: store transposed resampling program coeffs to temp buffer for reusage at each line\n\n      // convert resampling program in H-form into permuting indexes for src transposition in V-form\n      __m512i perm_0_0_15 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x])); // 16 offsets\n      __m512i perm_0_16_31 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 16])); //  16 offsets\n      __m512i perm_0_32_47 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 32])); //  16 offsets\n      __m512i perm_0_48_63 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 48])); //  16 offsets\n\n      int iStart = program->pixel_offset[x];\n      __m512i m512i_Start = _mm512_set1_epi32(iStart);\n\n      perm_0_0_15 = _mm512_sub_epi32(perm_0_0_15, m512i_Start);\n      perm_0_16_31 = _mm512_sub_epi32(perm_0_16_31, m512i_Start);\n      perm_0_32_47 = _mm512_sub_epi32(perm_0_32_47, m512i_Start);\n      perm_0_48_63 = _mm512_sub_epi32(perm_0_48_63, m512i_Start);\n\n      __m256i m256i_perm_0_0_15 = _mm512_cvtepi32_epi16(perm_0_0_15);\n      __m256i m256i_perm_0_16_31 = _mm512_cvtepi32_epi16(perm_0_16_31);\n      __m256i m256i_perm_0_32_47 = _mm512_cvtepi32_epi16(perm_0_32_47);\n      __m256i m256i_perm_0_48_63 = _mm512_cvtepi32_epi16(perm_0_48_63);\n\n      __m128i mm128i_perm_0_0_15 = _mm256_cvtepi16_epi8(m256i_perm_0_0_15);\n      __m128i mm128i_perm_0_16_31 = _mm256_cvtepi16_epi8(m256i_perm_0_16_31);\n      __m128i mm128i_perm_0_32_47 = _mm256_cvtepi16_epi8(m256i_perm_0_32_47);\n      __m128i mm128i_perm_0_48_63 = _mm256_cvtepi16_epi8(m256i_perm_0_48_63);\n\n      // Insert each 128-bit register into the specific lane\n      // __m512i perm_0 = _mm512_inserti32x4(_mm512_setzero_si512(), mm128i_perm_0_0_15, 0); // Lane 0\n      __m512i perm_0 = _mm512_inserti32x4(_mm512_zextsi128_si512(mm128i_perm_0_0_15), mm128i_perm_0_16_31, 1); // Lane 0+1\n      perm_0 = _mm512_inserti32x4(perm_0, mm128i_perm_0_32_47, 2); // Lane 2\n      perm_0 = _mm512_inserti32x4(perm_0, mm128i_perm_0_48_63, 3); // Lane 3\n\n      // Taps are contiguous (0, 1, 2, 3), so we increment perm indexes by 1 (in pairs by 2 each).\n      const __m512i two_epi8 = _mm512_set1_epi8(2);\n\n      uint8_t* AVS_RESTRICT dst_ptr = dst8 + x + y_from * dst_pitch;\n      const uint8_t* src_ptr = src8 + iStart + y_from * src_pitch; // all permute offsets relative to this start offset\n\n      // Calculate remaining pixels for bounds checking in partial_load mode. 1..128 remaining pixels possible.\n      const int remaining = program->source_size - iStart;\n      const __mmask64 k1 = _bzhi_u64(~0ULL, remaining); // _bzhi_u64 creates a mask with the lower N bits set. If N >= 64, it returns all ones (~0ULL). \n      const __mmask64 k2 = _bzhi_u64(~0ULL, std::max(0, remaining - 64));\n\n      for (int y = y_from; y < y_to; y++)\n      {\n        __m512i data_src, data_src2;\n\n        // working permute indexes for advancing to save number of registers used\n        __m512i perm_w_even = perm_0;\n        __m512i perm_w_odd = _mm512_add_epi8(perm_0, _mm512_set1_epi8(1));\n\n        if constexpr (partial_load) {\n          // Safe masked loads for the image edge\n          data_src = _mm512_maskz_loadu_epi8(k1, src_ptr);\n          data_src2 = _mm512_maskz_loadu_epi8(k2, src_ptr + 64);\n        }\n        else {\n          // Fast unaligned loads for the safe zone\n          data_src = _mm512_loadu_si512(src_ptr);\n          data_src2 = _mm512_loadu_si512(src_ptr + 64);\n        }\n\n        // rows 0..3\n        __m512i data_0 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_even, data_src2);\n        __m512i data_1 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_odd, data_src2);\n        perm_w_even = _mm512_add_epi8(perm_w_even, two_epi8);\n        perm_w_odd = _mm512_add_epi8(perm_w_odd, two_epi8);\n\n        __m512i data_2 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_even, data_src2);\n        __m512i data_3 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_odd, data_src2);\n        perm_w_even = _mm512_add_epi8(perm_w_even, two_epi8);\n        perm_w_odd = _mm512_add_epi8(perm_w_odd, two_epi8);\n\n        // unpack 8->16bit 4 to 8 512bit registers source\n        __m512i src_r0_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_0));\n        __m512i src_r0_32_63 = _mm512_cvtepu8_epi16(_mm512_extracti64x4_epi64(data_0, 1));\n\n        __m512i src_r1_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_1));\n        __m512i src_r1_32_63 = _mm512_cvtepu8_epi16(_mm512_extracti64x4_epi64(data_1, 1));\n\n        __m512i src_r2_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_2));\n        __m512i src_r2_32_63 = _mm512_cvtepu8_epi16(_mm512_extracti64x4_epi64(data_2, 1));\n\n        __m512i src_r3_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_3));\n        __m512i src_r3_32_63 = _mm512_cvtepu8_epi16(_mm512_extracti64x4_epi64(data_3, 1));\n\n        // transposition to H-pairs 8 to 8 512bit registers \n        __m512i src_r0r1_0_31lo = _mm512_unpacklo_epi16(src_r0_0_31, src_r1_0_31);\n        __m512i src_r0r1_0_31hi = _mm512_unpackhi_epi16(src_r0_0_31, src_r1_0_31);\n\n        __m512i src_r0r1_32_63lo = _mm512_unpacklo_epi16(src_r0_32_63, src_r1_32_63);\n        __m512i src_r0r1_32_63hi = _mm512_unpackhi_epi16(src_r0_32_63, src_r1_32_63);\n\n        __m512i src_r2r3_0_31lo = _mm512_unpacklo_epi16(src_r2_0_31, src_r3_0_31);\n        __m512i src_r2r3_0_31hi = _mm512_unpackhi_epi16(src_r2_0_31, src_r3_0_31);\n\n        __m512i src_r2r3_32_63lo = _mm512_unpacklo_epi16(src_r2_32_63, src_r3_32_63);\n        __m512i src_r2r3_32_63hi = _mm512_unpackhi_epi16(src_r2_32_63, src_r3_32_63);\n\n        // making FMA in 32bits accs as in AVX256 V-resize\n        __m512i result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31lo, coef_r0r1_0_31lo), _mm512_madd_epi16(src_r2r3_0_31lo, coef_r2r3_0_31lo));\n        __m512i result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31hi, coef_r0r1_0_31hi), _mm512_madd_epi16(src_r2r3_0_31hi, coef_r2r3_0_31hi));\n\n        __m512i result_32_63lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_32_63lo, coef_r0r1_32_63lo), _mm512_madd_epi16(src_r2r3_32_63lo, coef_r2r3_32_63lo));\n        __m512i result_32_63hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_32_63hi, coef_r0r1_32_63hi), _mm512_madd_epi16(src_r2r3_32_63hi, coef_r2r3_32_63hi));\n\n        // rows 4..7\n        __m512i data_4 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_even, data_src2);\n        __m512i data_5 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_odd, data_src2);\n        perm_w_even = _mm512_add_epi8(perm_w_even, two_epi8);\n        perm_w_odd = _mm512_add_epi8(perm_w_odd, two_epi8);\n\n        __m512i data_6 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_even, data_src2);\n        __m512i data_7 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_odd, data_src2);\n\n        // unpack 8->16bit 4 to 8 512bit registers source\n        __m512i src_r4_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_4));\n        __m512i src_r4_32_63 = _mm512_cvtepu8_epi16(_mm512_extracti64x4_epi64(data_4, 1));\n\n        __m512i src_r5_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_5));\n        __m512i src_r5_32_63 = _mm512_cvtepu8_epi16(_mm512_extracti64x4_epi64(data_5, 1));\n\n        __m512i src_r6_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_6));\n        __m512i src_r6_32_63 = _mm512_cvtepu8_epi16(_mm512_extracti64x4_epi64(data_6, 1));\n\n        __m512i src_r7_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_7));\n        __m512i src_r7_32_63 = _mm512_cvtepu8_epi16(_mm512_extracti64x4_epi64(data_7, 1));\n\n        // transposition to H-pairs 8 to 8 512bit registers \n        __m512i src_r4r5_0_31lo = _mm512_unpacklo_epi16(src_r4_0_31, src_r5_0_31);\n        __m512i src_r4r5_0_31hi = _mm512_unpackhi_epi16(src_r4_0_31, src_r5_0_31);\n\n        __m512i src_r4r5_32_63lo = _mm512_unpacklo_epi16(src_r4_32_63, src_r5_32_63);\n        __m512i src_r4r5_32_63hi = _mm512_unpackhi_epi16(src_r4_32_63, src_r5_32_63);\n\n        __m512i src_r6r7_0_31lo = _mm512_unpacklo_epi16(src_r6_0_31, src_r7_0_31);\n        __m512i src_r6r7_0_31hi = _mm512_unpackhi_epi16(src_r6_0_31, src_r7_0_31);\n\n        __m512i src_r6r7_32_63lo = _mm512_unpacklo_epi16(src_r6_32_63, src_r7_32_63);\n        __m512i src_r6r7_32_63hi = _mm512_unpackhi_epi16(src_r6_32_63, src_r7_32_63);\n\n        result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_0_31lo, coef_r4r5_0_31lo), result_0_31lo);\n        result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_0_31hi, coef_r4r5_0_31hi), result_0_31hi);\n\n        result_32_63lo = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_32_63lo, coef_r4r5_32_63lo), result_32_63lo);\n        result_32_63hi = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_32_63hi, coef_r4r5_32_63hi), result_32_63hi);\n\n        result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_0_31lo, coef_r6r7_0_31lo), result_0_31lo);\n        result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_0_31hi, coef_r6r7_0_31hi), result_0_31hi);\n\n        result_32_63lo = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_32_63lo, coef_r6r7_32_63lo), result_32_63lo);\n        result_32_63hi = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_32_63hi, coef_r6r7_32_63hi), result_32_63hi);\n\n        // rounding\n        result_0_31lo = _mm512_add_epi32(result_0_31lo, rounder);\n        result_0_31hi = _mm512_add_epi32(result_0_31hi, rounder);\n        result_32_63lo = _mm512_add_epi32(result_32_63lo, rounder);\n        result_32_63hi = _mm512_add_epi32(result_32_63hi, rounder);\n        // scaling down\n        result_0_31lo = _mm512_srai_epi32(result_0_31lo, FPScale8bits);\n        result_0_31hi = _mm512_srai_epi32(result_0_31hi, FPScale8bits);\n        result_32_63lo = _mm512_srai_epi32(result_32_63lo, FPScale8bits);\n        result_32_63hi = _mm512_srai_epi32(result_32_63hi, FPScale8bits);\n\n        __m512i result_0_31_int16 = _mm512_packus_epi32(result_0_31lo, result_0_31hi);\n        __m512i result_32_63_int16 = _mm512_packus_epi32(result_32_63lo, result_32_63hi);\n\n        __m256i result_0_31_u8 = _mm512_cvtusepi16_epi8(result_0_31_int16);\n        __m256i result_32_63_u8 = _mm512_cvtusepi16_epi8(result_32_63_int16);\n\n        // cast is enough, no need to use zeroextend\n        _mm512_stream_si512(reinterpret_cast<__m512i*>(dst_ptr),\n          _mm512_inserti64x4(_mm512_castsi256_si512(result_0_31_u8), result_32_63_u8, 1));\n\n        dst_ptr += dst_pitch;\n        src_ptr += src_pitch;\n      }\n\n      current_coeff += filter_size * PIXELS_AT_A_TIME;\n      };\n\n    // Process the 'safe zone' where direct full unaligned loads are acceptable.\n    for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)\n    {\n      do_h_integer_core(std::false_type{});\n    }\n\n    // Process the potentially 'unsafe zone' near the image edge, using safe masked loading.\n    for (; x < width; x += PIXELS_AT_A_TIME)\n    {\n      do_h_integer_core(std::true_type{});\n    }\n  }\n}\n\n// filter size up to 8\n// 64 target uint8_t pixels at a time in 2 groups of 32 to support longer source loading to each group to support lower downsample ratios\n// support /2 downsample ratios for resizers with no-resize kernel size of 4 (or support of 2 ?) (Bicubic, Bilinear, and others, also SinPowResize (?))\n// 2 groups of 128-byte source loads (128 uint8_t pixels)\n// maximum permute index is 128 for _mm512_permutex2var_epi8 (uint8_t)\ntemplate<bool UseVBMI>\nstatic void resize_h_planar_uint8_avx512_permutex_vstripe_2s32_ks8_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)\n{\n  const int filter_size = program->filter_size; // aligned, practically the coeff table stride\n\n  constexpr int PIXELS_AT_A_TIME = 64;\n\n  // 'source_overread_beyond_targetx' indicates if the filter kernel can read beyond the target width.\n  // we load 2x64 source bytes at a time, so ensure safe overread if needed.\n  // Our main loop processes calculates for 64 target pixels at a time.\n  // Inside that, we load 128 source bytes (2x64) to be able to permutex from that.\n  // This we have to check at each mod-PIXELS_AT_A_TIME boundary, the allowance of 128-byte source load.\n  // Each group of 32 target samples loads 128 source with separate iStart offset (checker function arguments (32/*iSamplesInTheGroup*/, 128/*permutex_index_diff_limit*/, 8/*kernel_size*/)\n  // safelimit of 128 each 64 expected is enough ?\n  const int width_safe_mod = (program->safelimit_128_pixels_each64th_target.overread_possible ? program->safelimit_128_pixels_each64th_target.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  // Preconditions:\n  assert(program->filter_size_real <= 8); // We preload all relevant coefficients (up to 8) before the height loop.\n\n  // 'target_size_alignment' ensures we can safely access coefficients using offsets like\n  // 'filter_size * 15' when processing 16 H pixels at a time\n  // 'filter_size * 63' when processing 64 H pixels at a time\n  assert(program->target_size_alignment >= 64); // Adjusted for 64 pixels\n\n  assert(FRAME_ALIGN >= 64); // Good for 64x8 bit pixels\n\n  // Ensure that coefficient loading beyond the valid target size is safe for 4x8 float loads.\n  // We load 8x 'short' coeffs at a time\n  assert(program->filter_size_alignment >= 8);\n\n  const int max_scanlines = program->max_scanlines;\n\n  __m512i rounder = _mm512_set1_epi32(1 << (FPScale8bits - 1));\n\n  // Vertical stripe loop for L2 cache optimization\n  for (int y_from = 0; y_from < height; y_from += max_scanlines)\n  {\n    int y_to = std::min(y_from + max_scanlines, height);\n\n    // Reset current_coeff for the start of the stripe (points to start of row's coeffs)\n    const short* AVS_RESTRICT current_coeff = program->pixel_coefficient;\n\n    int x = 0;\n\n    // Lambda to handle both safe (fast) and unsafe (masked/partial) loading paths\n    auto do_h_integer_core = [&](auto partial_load) {\n\n      // prepare coefs in transposed V-form\n      // TODO: make storage in transposed form, 64 x uint16 transposition looks too slow\n\n      // 8coefs of 16bit is 128bits \n      __m512i coef_0_3 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 0), (__m128i*)(current_coeff + filter_size * 1), (__m128i*)(current_coeff + filter_size * 2), (__m128i*)(current_coeff + filter_size * 3));\n      __m512i coef_4_7 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 4), (__m128i*)(current_coeff + filter_size * 5), (__m128i*)(current_coeff + filter_size * 6), (__m128i*)(current_coeff + filter_size * 7));\n      __m512i coef_8_11 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 8), (__m128i*)(current_coeff + filter_size * 9), (__m128i*)(current_coeff + filter_size * 10), (__m128i*)(current_coeff + filter_size * 11));\n      __m512i coef_12_15 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 12), (__m128i*)(current_coeff + filter_size * 13), (__m128i*)(current_coeff + filter_size * 14), (__m128i*)(current_coeff + filter_size * 15));\n      __m512i coef_16_19 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 16), (__m128i*)(current_coeff + filter_size * 17), (__m128i*)(current_coeff + filter_size * 18), (__m128i*)(current_coeff + filter_size * 19));\n      __m512i coef_20_23 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 20), (__m128i*)(current_coeff + filter_size * 21), (__m128i*)(current_coeff + filter_size * 22), (__m128i*)(current_coeff + filter_size * 23));\n      __m512i coef_24_27 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 24), (__m128i*)(current_coeff + filter_size * 25), (__m128i*)(current_coeff + filter_size * 26), (__m128i*)(current_coeff + filter_size * 27));\n      __m512i coef_28_31 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 28), (__m128i*)(current_coeff + filter_size * 29), (__m128i*)(current_coeff + filter_size * 30), (__m128i*)(current_coeff + filter_size * 31));\n\n      __m512i coef_32_35 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 32), (__m128i*)(current_coeff + filter_size * 33), (__m128i*)(current_coeff + filter_size * 34), (__m128i*)(current_coeff + filter_size * 35));\n      __m512i coef_36_39 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 36), (__m128i*)(current_coeff + filter_size * 37), (__m128i*)(current_coeff + filter_size * 38), (__m128i*)(current_coeff + filter_size * 39));\n      __m512i coef_40_43 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 40), (__m128i*)(current_coeff + filter_size * 41), (__m128i*)(current_coeff + filter_size * 42), (__m128i*)(current_coeff + filter_size * 43));\n      __m512i coef_44_47 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 44), (__m128i*)(current_coeff + filter_size * 45), (__m128i*)(current_coeff + filter_size * 46), (__m128i*)(current_coeff + filter_size * 47));\n      __m512i coef_48_51 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 48), (__m128i*)(current_coeff + filter_size * 49), (__m128i*)(current_coeff + filter_size * 50), (__m128i*)(current_coeff + filter_size * 51));\n      __m512i coef_52_55 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 52), (__m128i*)(current_coeff + filter_size * 53), (__m128i*)(current_coeff + filter_size * 54), (__m128i*)(current_coeff + filter_size * 55));\n      __m512i coef_56_59 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 56), (__m128i*)(current_coeff + filter_size * 57), (__m128i*)(current_coeff + filter_size * 58), (__m128i*)(current_coeff + filter_size * 59));\n      __m512i coef_60_63 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 60), (__m128i*)(current_coeff + filter_size * 61), (__m128i*)(current_coeff + filter_size * 62), (__m128i*)(current_coeff + filter_size * 63));\n\n      // Transpose with permutex\n      __m512i c_perm_0_7 = _mm512_set_epi16(\n        0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0,\n        24 + 32, 16 + 32, 8 + 32, 0 + 32, 24, 16, 8, 0);\n      __m512i c_perm_8_15 = _mm512_set_epi16(\n        0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0,\n        24 + 32, 16 + 32, 8 + 32, 0 + 32, 24, 16, 8, 0,\n        0, 0, 0, 0, 0, 0, 0, 0);\n      __m512i c_perm_16_23 = _mm512_set_epi16(\n        0, 0, 0, 0, 0, 0, 0, 0,\n        24 + 32, 16 + 32, 8 + 32, 0 + 32, 24, 16, 8, 0,\n        0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0);\n      __m512i c_perm_24_31 = _mm512_set_epi16(\n        24 + 32, 16 + 32, 8 + 32, 0 + 32, 24, 16, 8, 0,\n        0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0);\n\n      __m512i one_epi16 = _mm512_set1_epi16(1);\n      const __mmask32 k_8_15 = 0x0000FF00;\n      const __mmask32 k_16_23 = 0x00FF0000;\n      const __mmask32 k_24_31 = 0xFF000000;\n\n      auto inc_perms = [&](\n        __m512i& c0_7,\n        __m512i& c8_15,\n        __m512i& c16_23,\n        __m512i& c24_31\n        ) {\n          c0_7 = _mm512_add_epi16(c0_7, one_epi16);\n          c8_15 = _mm512_add_epi16(c8_15, one_epi16);\n          c16_23 = _mm512_add_epi16(c16_23, one_epi16);\n          c24_31 = _mm512_add_epi16(c24_31, one_epi16);\n        };\n\n      auto make_row_0_63 = [&](\n        __m512i& row_0_31w, __m512i& row_32_63w,\n        __m512i c0_7, __m512i c8_15, __m512i c16_23, __m512i c24_31\n        ) {\n          // 0..31\n          row_0_31w = _mm512_mask_blend_epi16(\n            k_8_15,\n            _mm512_permutex2var_epi16(coef_0_3, c0_7, coef_4_7),\n            _mm512_permutex2var_epi16(coef_8_11, c8_15, coef_12_15)\n          );\n          row_0_31w = _mm512_mask_blend_epi16(\n            k_16_23,\n            row_0_31w,\n            _mm512_permutex2var_epi16(coef_16_19, c16_23, coef_20_23)\n          );\n          row_0_31w = _mm512_mask_blend_epi16(\n            k_24_31,\n            row_0_31w,\n            _mm512_permutex2var_epi16(coef_24_27, c24_31, coef_28_31)\n          );\n\n          // 32..63\n          row_32_63w = _mm512_mask_blend_epi16(\n            k_8_15,\n            _mm512_permutex2var_epi16(coef_32_35, c0_7, coef_36_39),\n            _mm512_permutex2var_epi16(coef_40_43, c8_15, coef_44_47)\n          );\n          row_32_63w = _mm512_mask_blend_epi16(\n            k_16_23,\n            row_32_63w,\n            _mm512_permutex2var_epi16(coef_48_51, c16_23, coef_52_55)\n          );\n          row_32_63w = _mm512_mask_blend_epi16(\n            k_24_31,\n            row_32_63w,\n            _mm512_permutex2var_epi16(coef_56_59, c24_31, coef_60_63)\n          );\n        };\n\n      __m512i coef_r0_0_31w, coef_r0_32_63w;\n      __m512i coef_r1_0_31w, coef_r1_32_63w;\n      __m512i coef_r2_0_31w, coef_r2_32_63w;\n      __m512i coef_r3_0_31w, coef_r3_32_63w;\n      __m512i coef_r4_0_31w, coef_r4_32_63w;\n      __m512i coef_r5_0_31w, coef_r5_32_63w;\n      __m512i coef_r6_0_31w, coef_r6_32_63w;\n      __m512i coef_r7_0_31w, coef_r7_32_63w;\n\n      // r0\n      make_row_0_63(coef_r0_0_31w, coef_r0_32_63w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r1\n      make_row_0_63(coef_r1_0_31w, coef_r1_32_63w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r2\n      make_row_0_63(coef_r2_0_31w, coef_r2_32_63w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r3\n      make_row_0_63(coef_r3_0_31w, coef_r3_32_63w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r4\n      make_row_0_63(coef_r4_0_31w, coef_r4_32_63w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r5\n      make_row_0_63(coef_r5_0_31w, coef_r5_32_63w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r6\n      make_row_0_63(coef_r6_0_31w, coef_r6_32_63w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r7\n      make_row_0_63(coef_r7_0_31w, coef_r7_32_63w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      /* // last one, not needed\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      */\n\n      // convert-transpose to H-pairs for madd ? better to do with single permutex in future\n      // 16 to 16 512 registers - finally real working coeffs to store in the transposed resampling program for block of 64 target samples\n      __m512i coef_r0r1_0_31lo = _mm512_unpacklo_epi16(coef_r0_0_31w, coef_r1_0_31w);\n      __m512i coef_r0r1_0_31hi = _mm512_unpackhi_epi16(coef_r0_0_31w, coef_r1_0_31w);\n\n      __m512i coef_r0r1_32_63lo = _mm512_unpacklo_epi16(coef_r0_32_63w, coef_r1_32_63w);\n      __m512i coef_r0r1_32_63hi = _mm512_unpackhi_epi16(coef_r0_32_63w, coef_r1_32_63w);\n\n      __m512i coef_r2r3_0_31lo = _mm512_unpacklo_epi16(coef_r2_0_31w, coef_r3_0_31w);\n      __m512i coef_r2r3_0_31hi = _mm512_unpackhi_epi16(coef_r2_0_31w, coef_r3_0_31w);\n\n      __m512i coef_r2r3_32_63lo = _mm512_unpacklo_epi16(coef_r2_32_63w, coef_r3_32_63w);\n      __m512i coef_r2r3_32_63hi = _mm512_unpackhi_epi16(coef_r2_32_63w, coef_r3_32_63w);\n\n      __m512i coef_r4r5_0_31lo = _mm512_unpacklo_epi16(coef_r4_0_31w, coef_r5_0_31w);\n      __m512i coef_r4r5_0_31hi = _mm512_unpackhi_epi16(coef_r4_0_31w, coef_r5_0_31w);\n\n      __m512i coef_r4r5_32_63lo = _mm512_unpacklo_epi16(coef_r4_32_63w, coef_r5_32_63w);\n      __m512i coef_r4r5_32_63hi = _mm512_unpackhi_epi16(coef_r4_32_63w, coef_r5_32_63w);\n\n      __m512i coef_r6r7_0_31lo = _mm512_unpacklo_epi16(coef_r6_0_31w, coef_r7_0_31w);\n      __m512i coef_r6r7_0_31hi = _mm512_unpackhi_epi16(coef_r6_0_31w, coef_r7_0_31w);\n\n      __m512i coef_r6r7_32_63lo = _mm512_unpacklo_epi16(coef_r6_32_63w, coef_r7_32_63w);\n      __m512i coef_r6r7_32_63hi = _mm512_unpackhi_epi16(coef_r6_32_63w, coef_r7_32_63w);\n\n      // TODO: store transposed resampling program coeffs to temp buffer for reusage at each line\n\n      // convert resampling program in H-form into permuting indexes for src transposition in V-form\n      __m512i perm_0_0_15 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x])); // 16 offsets\n      __m512i perm_0_16_31 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 16])); //  16 offsets\n      __m512i perm_0_32_47 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 32])); //  16 offsets\n      __m512i perm_0_48_63 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 48])); //  16 offsets\n\n      int iStart = program->pixel_offset[x];\n      __m512i m512i_Start = _mm512_set1_epi32(iStart);\n      int iStart_2 = program->pixel_offset[x + 32]; // start offset for second group of 32 targets\n      __m512i m512i_Start_2 = _mm512_set1_epi32(iStart_2);\n\n      perm_0_0_15 = _mm512_sub_epi32(perm_0_0_15, m512i_Start);\n      perm_0_16_31 = _mm512_sub_epi32(perm_0_16_31, m512i_Start);\n      perm_0_32_47 = _mm512_sub_epi32(perm_0_32_47, m512i_Start_2);\n      perm_0_48_63 = _mm512_sub_epi32(perm_0_48_63, m512i_Start_2);\n\n      __m256i m256i_perm_0_0_15 = _mm512_cvtepi32_epi16(perm_0_0_15);\n      __m256i m256i_perm_0_16_31 = _mm512_cvtepi32_epi16(perm_0_16_31);\n      __m256i m256i_perm_0_32_47 = _mm512_cvtepi32_epi16(perm_0_32_47);\n      __m256i m256i_perm_0_48_63 = _mm512_cvtepi32_epi16(perm_0_48_63);\n\n      __m128i mm128i_perm_0_0_15 = _mm256_cvtepi16_epi8(m256i_perm_0_0_15);\n      __m128i mm128i_perm_0_16_31 = _mm256_cvtepi16_epi8(m256i_perm_0_16_31);\n      __m128i mm128i_perm_0_32_47 = _mm256_cvtepi16_epi8(m256i_perm_0_32_47);\n      __m128i mm128i_perm_0_48_63 = _mm256_cvtepi16_epi8(m256i_perm_0_48_63);\n\n      // Insert each 128-bit register into the specific lane\n//      __m512i perm_0 = _mm512_inserti32x4(_mm512_setzero_si512(), mm128i_perm_0_0_15, 0); // Lane 0\n      __m512i perm_0 = _mm512_inserti32x4(_mm512_zextsi128_si512(mm128i_perm_0_0_15), mm128i_perm_0_16_31, 1); // Lane 0+1\n      perm_0 = _mm512_inserti32x4(perm_0, mm128i_perm_0_32_47, 2); // Lane 2\n      perm_0 = _mm512_inserti32x4(perm_0, mm128i_perm_0_48_63, 3); // Lane 3\n\n      // Taps are contiguous (0, 1, 2, 3), so we increment perm indexes by 1 (in pairs by 2 each).\n      const __m512i two_epi8 = _mm512_set1_epi8(2);\n\n      uint8_t* AVS_RESTRICT dst_ptr = dst8 + x + y_from * dst_pitch;\n      const uint8_t* src_ptr = src8 + iStart + y_from * src_pitch; // all permute offsets relative to this start offset\n      const uint8_t* src_ptr_2 = src8 + iStart_2 + y_from * src_pitch; // all permute offsets in second group of 32 relative to this start offset\n\n      // Calculate remaining pixels for bounds checking in partial_load mode. 1..128 remaining pixels possible.\n      const int remaining = program->source_size - iStart;\n      const int remaining_2 = program->source_size - iStart_2;\n      const __mmask64 k1 = _bzhi_u64(~0ULL, remaining); // _bzhi_u64 creates a mask with the lower N bits set. If N >= 64, it returns all ones (~0ULL). \n      const __mmask64 k2 = _bzhi_u64(~0ULL, std::max(0, remaining - 64));\n\n      const __mmask64 k1_2 = _bzhi_u64(~0ULL, remaining_2); // _bzhi_u64 creates a mask with the lower N bits set. If N >= 64, it returns all ones (~0ULL). \n      const __mmask64 k2_2 = _bzhi_u64(~0ULL, std::max(0, remaining_2 - 64));\n\n      for (int y = y_from; y < y_to; y++)\n      {\n        __m512i data_src, data_src2;\n        __m512i data_src_2, data_src2_2;\n\n        // working permute indexes for advancing to save number of registers used\n        __m512i perm_w_even = perm_0;\n        __m512i perm_w_odd = _mm512_add_epi8(perm_0, _mm512_set1_epi8(1));\n\n        if constexpr (partial_load) {\n          // Safe masked loads for the image edge\n          data_src = _mm512_maskz_loadu_epi8(k1, src_ptr);\n          data_src2 = _mm512_maskz_loadu_epi8(k2, src_ptr + 64);\n\n          data_src_2 = _mm512_maskz_loadu_epi8(k1_2, src_ptr_2);\n          data_src2_2 = _mm512_maskz_loadu_epi8(k2_2, src_ptr_2 + 64);\n        }\n        else {\n          // Fast unaligned loads for the safe zone\n          data_src = _mm512_loadu_si512(src_ptr);\n          data_src2 = _mm512_loadu_si512(src_ptr + 64);\n\n          data_src_2 = _mm512_loadu_si512(src_ptr_2);\n          data_src2_2 = _mm512_loadu_si512(src_ptr_2 + 64);\n        }\n\n        // 64 target pixels into two groups: 0-31 and 32-63.\n        const __mmask32 k_high = 0xFFFF0000;\n\n        // rows 0..3\n        __m512i data_0 = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_even, data_src2), _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src_2, perm_w_even, data_src2_2));\n        __m512i data_1 = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_odd, data_src2), _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src_2, perm_w_odd, data_src2_2));\n        perm_w_even = _mm512_add_epi8(perm_w_even, two_epi8);\n        perm_w_odd = _mm512_add_epi8(perm_w_odd, two_epi8); // Use perm_w_odd here!\n        __m512i data_2 = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_even, data_src2), _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src_2, perm_w_even, data_src2_2));\n        __m512i data_3 = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_odd, data_src2), _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src_2, perm_w_odd, data_src2_2));\n\n        // unpack 8->16bit 4 to 8 512bit registers source\n        __m512i src_r0_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_0));\n        __m512i src_r0_32_63 = _mm512_cvtepu8_epi16(_mm512_extracti64x4_epi64(data_0, 1));\n\n        __m512i src_r1_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_1));\n        __m512i src_r1_32_63 = _mm512_cvtepu8_epi16(_mm512_extracti64x4_epi64(data_1, 1));\n\n        __m512i src_r2_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_2));\n        __m512i src_r2_32_63 = _mm512_cvtepu8_epi16(_mm512_extracti64x4_epi64(data_2, 1));\n\n        __m512i src_r3_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_3));\n        __m512i src_r3_32_63 = _mm512_cvtepu8_epi16(_mm512_extracti64x4_epi64(data_3, 1));\n\n        // transposition to H-pairs 8 to 8 512bit registers \n        __m512i src_r0r1_0_31lo = _mm512_unpacklo_epi16(src_r0_0_31, src_r1_0_31);\n        __m512i src_r0r1_0_31hi = _mm512_unpackhi_epi16(src_r0_0_31, src_r1_0_31);\n\n        __m512i src_r0r1_32_63lo = _mm512_unpacklo_epi16(src_r0_32_63, src_r1_32_63);\n        __m512i src_r0r1_32_63hi = _mm512_unpackhi_epi16(src_r0_32_63, src_r1_32_63);\n\n        __m512i src_r2r3_0_31lo = _mm512_unpacklo_epi16(src_r2_0_31, src_r3_0_31);\n        __m512i src_r2r3_0_31hi = _mm512_unpackhi_epi16(src_r2_0_31, src_r3_0_31);\n\n        __m512i src_r2r3_32_63lo = _mm512_unpacklo_epi16(src_r2_32_63, src_r3_32_63);\n        __m512i src_r2r3_32_63hi = _mm512_unpackhi_epi16(src_r2_32_63, src_r3_32_63);\n\n        // making FMA in 32bits accs as in AVX256 V-resize\n        __m512i result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31lo, coef_r0r1_0_31lo), _mm512_madd_epi16(src_r2r3_0_31lo, coef_r2r3_0_31lo));\n        __m512i result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31hi, coef_r0r1_0_31hi), _mm512_madd_epi16(src_r2r3_0_31hi, coef_r2r3_0_31hi));\n\n        __m512i result_32_63lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_32_63lo, coef_r0r1_32_63lo), _mm512_madd_epi16(src_r2r3_32_63lo, coef_r2r3_32_63lo));\n        __m512i result_32_63hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_32_63hi, coef_r0r1_32_63hi), _mm512_madd_epi16(src_r2r3_32_63hi, coef_r2r3_32_63hi));\n\n        // rows 4..7\n        perm_w_even = _mm512_add_epi8(perm_w_even, two_epi8);\n        perm_w_odd = _mm512_add_epi8(perm_w_odd, two_epi8); // Use perm_w_odd here!\n        __m512i data_4 = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_even, data_src2), _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src_2, perm_w_even, data_src2_2));\n        __m512i data_5 = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_odd, data_src2), _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src_2, perm_w_odd, data_src2_2));\n        perm_w_even = _mm512_add_epi8(perm_w_even, two_epi8);\n        perm_w_odd = _mm512_add_epi8(perm_w_odd, two_epi8);\n        __m512i data_6 = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_even, data_src2), _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src_2, perm_w_even, data_src2_2));\n        __m512i data_7 = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_odd, data_src2), _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src_2, perm_w_odd, data_src2_2));\n\n        // unpack 8->16bit 4 to 8 512bit registers source\n        __m512i src_r4_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_4));\n        __m512i src_r4_32_63 = _mm512_cvtepu8_epi16(_mm512_extracti64x4_epi64(data_4, 1));\n\n        __m512i src_r5_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_5));\n        __m512i src_r5_32_63 = _mm512_cvtepu8_epi16(_mm512_extracti64x4_epi64(data_5, 1));\n\n        __m512i src_r6_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_6));\n        __m512i src_r6_32_63 = _mm512_cvtepu8_epi16(_mm512_extracti64x4_epi64(data_6, 1));\n\n        __m512i src_r7_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_7));\n        __m512i src_r7_32_63 = _mm512_cvtepu8_epi16(_mm512_extracti64x4_epi64(data_7, 1));\n\n        // transposition to H-pairs 8 to 8 512bit registers \n        __m512i src_r4r5_0_31lo = _mm512_unpacklo_epi16(src_r4_0_31, src_r5_0_31);\n        __m512i src_r4r5_0_31hi = _mm512_unpackhi_epi16(src_r4_0_31, src_r5_0_31);\n\n        __m512i src_r4r5_32_63lo = _mm512_unpacklo_epi16(src_r4_32_63, src_r5_32_63);\n        __m512i src_r4r5_32_63hi = _mm512_unpackhi_epi16(src_r4_32_63, src_r5_32_63);\n\n        __m512i src_r6r7_0_31lo = _mm512_unpacklo_epi16(src_r6_0_31, src_r7_0_31);\n        __m512i src_r6r7_0_31hi = _mm512_unpackhi_epi16(src_r6_0_31, src_r7_0_31);\n\n        __m512i src_r6r7_32_63lo = _mm512_unpacklo_epi16(src_r6_32_63, src_r7_32_63);\n        __m512i src_r6r7_32_63hi = _mm512_unpackhi_epi16(src_r6_32_63, src_r7_32_63);\n        result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_0_31lo, coef_r4r5_0_31lo), result_0_31lo);\n        result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_0_31hi, coef_r4r5_0_31hi), result_0_31hi);\n\n        result_32_63lo = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_32_63lo, coef_r4r5_32_63lo), result_32_63lo);\n        result_32_63hi = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_32_63hi, coef_r4r5_32_63hi), result_32_63hi);\n\n        result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_0_31lo, coef_r6r7_0_31lo), result_0_31lo);\n        result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_0_31hi, coef_r6r7_0_31hi), result_0_31hi);\n\n        result_32_63lo = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_32_63lo, coef_r6r7_32_63lo), result_32_63lo);\n        result_32_63hi = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_32_63hi, coef_r6r7_32_63hi), result_32_63hi);\n\n        // rounding\n        result_0_31lo = _mm512_add_epi32(result_0_31lo, rounder);\n        result_0_31hi = _mm512_add_epi32(result_0_31hi, rounder);\n        result_32_63lo = _mm512_add_epi32(result_32_63lo, rounder);\n        result_32_63hi = _mm512_add_epi32(result_32_63hi, rounder);\n        // scaling down\n        result_0_31lo = _mm512_srai_epi32(result_0_31lo, FPScale8bits);\n        result_0_31hi = _mm512_srai_epi32(result_0_31hi, FPScale8bits);\n        result_32_63lo = _mm512_srai_epi32(result_32_63lo, FPScale8bits);\n        result_32_63hi = _mm512_srai_epi32(result_32_63hi, FPScale8bits);\n\n        __m512i result_0_31_int16 = _mm512_packus_epi32(result_0_31lo, result_0_31hi);\n        __m512i result_32_63_int16 = _mm512_packus_epi32(result_32_63lo, result_32_63hi);\n\n        __m256i result_0_31_u8 = _mm512_cvtusepi16_epi8(result_0_31_int16);\n        __m256i result_32_63_u8 = _mm512_cvtusepi16_epi8(result_32_63_int16);\n\n        // cast is enough, no need to use zeroextend\n        _mm512_stream_si512(reinterpret_cast<__m512i*>(dst_ptr),\n          _mm512_inserti64x4(_mm512_castsi256_si512(result_0_31_u8), result_32_63_u8, 1));\n\n        dst_ptr += dst_pitch;\n        src_ptr += src_pitch;\n        src_ptr_2 += src_pitch;\n      }\n\n      current_coeff += filter_size * PIXELS_AT_A_TIME;\n      };\n\n    // Process the 'safe zone' where direct full unaligned loads are acceptable.\n    for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)\n    {\n      do_h_integer_core(std::false_type{});\n    }\n\n    // Process the potentially 'unsafe zone' near the image edge, using safe masked loading.\n    for (; x < width; x += PIXELS_AT_A_TIME)\n    {\n      do_h_integer_core(std::true_type{});\n    }\n  }\n}\n\n// filter size up to 16\n// 32 target uint8_t pixels at a time\n// 128-byte source loads (128 uint8_t pixels)\n// maximum permute index is 128 for _mm512_permutex2var_epi8 (uint8_t)\n// expect to support all upsampling ratios up to filter support of 8 (or 7..6 ?) and some downsampling ratios with filter support up to 3 (with downsample ratios from 0.5 or a bit lower)\ntemplate<bool UseVBMI>\nstatic void resize_h_planar_uint8_avx512_permutex_vstripe_ks16_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)\n{\n  const int filter_size = program->filter_size; // aligned, practically the coeff table stride\n\n  constexpr int PIXELS_AT_A_TIME = 32;\n\n  // 'source_overread_beyond_targetx' indicates if the filter kernel can read beyond the target width.\n  // we load 2x64 source bytes at a time, so ensure safe overread if needed.\n  // Our main loop processes calculates for 64 target pixels at a time.\n  // Inside that, we load 128 source bytes (2x64) to be able to permutex from that.\n  // This we have to check at each mod-PIXELS_AT_A_TIME boundary, the allowance of 128-byte source load.\n  const int width_safe_mod = (program->safelimit_128_pixels_each64th_target.overread_possible ? program->safelimit_128_pixels_each64th_target.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  // Preconditions:\n  assert(program->filter_size_real <= 16); // We preload all relevant coefficients (up to 16) before the height loop.\n\n  // 'target_size_alignment' ensures we can safely access coefficients using offsets like\n  // 'filter_size * 15' when processing 16 H pixels at a time\n  // 'filter_size * 31' when processing 32 H pixels at a time\n  assert(program->target_size_alignment >= 32); // Adjusted for 32 pixels (is it enough for uint8 ?)\n\n  assert(FRAME_ALIGN >= 32); // Good for 32x8 bit pixels\n\n  // Ensure that coefficient loading beyond the valid target size is safe \n  // We load 16x 'short' coeffs at a time\n  // We aligned_load from coeff positions, 32 bytes boundary needed, which is\n  // guaranteed by filter_size_alignment >=16\n  assert(program->filter_size_alignment >= 16);\n\n  const int max_scanlines = program->max_scanlines;\n\n  __m512i rounder = _mm512_set1_epi32(1 << (FPScale8bits - 1));\n\n  // Vertical stripe loop for L2 cache optimization\n  for (int y_from = 0; y_from < height; y_from += max_scanlines)\n  {\n    int y_to = std::min(y_from + max_scanlines, height);\n\n    // Reset current_coeff for the start of the stripe (points to start of row's coeffs)\n    const short* AVS_RESTRICT current_coeff = program->pixel_coefficient;\n\n    int x = 0;\n\n    // Lambda to handle both safe (fast) and unsafe (masked/partial) loading paths\n    auto do_h_integer_core = [&](auto partial_load) {\n\n      // prepare coefs in transposed V-form\n      // TODO: make storage in transposed form, 32 x uint8 transposition looks too slow\n\n      // 16coefs of 16bit is 256bits - load as pairs of _m256i\n      // hope 16-coeffs blocks are 32-bytes aligned for m256i aligned loads ?\n      __m512i coef_0_1 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 0), (__m256i*)(current_coeff + filter_size * 1));\n      __m512i coef_2_3 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 2), (__m256i*)(current_coeff + filter_size * 3));\n      __m512i coef_4_5 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 4), (__m256i*)(current_coeff + filter_size * 5));\n      __m512i coef_6_7 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 6), (__m256i*)(current_coeff + filter_size * 7));\n      __m512i coef_8_9 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 8), (__m256i*)(current_coeff + filter_size * 9));\n      __m512i coef_10_11 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 10), (__m256i*)(current_coeff + filter_size * 11));\n      __m512i coef_12_13 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 12), (__m256i*)(current_coeff + filter_size * 13));\n      __m512i coef_14_15 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 14), (__m256i*)(current_coeff + filter_size * 15));\n      __m512i coef_16_17 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 16), (__m256i*)(current_coeff + filter_size * 17));\n      __m512i coef_18_19 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 18), (__m256i*)(current_coeff + filter_size * 19));\n      __m512i coef_20_21 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 20), (__m256i*)(current_coeff + filter_size * 21));\n      __m512i coef_22_23 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 22), (__m256i*)(current_coeff + filter_size * 23));\n      __m512i coef_24_25 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 24), (__m256i*)(current_coeff + filter_size * 25));\n      __m512i coef_26_27 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 26), (__m256i*)(current_coeff + filter_size * 27));\n      __m512i coef_28_29 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 28), (__m256i*)(current_coeff + filter_size * 29));\n      __m512i coef_30_31 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 30), (__m256i*)(current_coeff + filter_size * 31));\n\n      // Transpose with permutex\n      __m512i c_perm_0_3 = _mm512_set_epi16(\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        16 + 32, 0 + 32, 16, 0);\n\n      __m512i c_perm_4_7 = _mm512_set_epi16(\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        16 + 32, 0 + 32, 16, 0,\n        0, 0, 0, 0);\n\n      __m512i c_perm_8_11 = _mm512_set_epi16(\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        16 + 32, 0 + 32, 16, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0);\n\n      __m512i c_perm_12_15 = _mm512_set_epi16(\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        16 + 32, 0 + 32, 16, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0);\n\n      __m512i c_perm_16_19 = _mm512_set_epi16(\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        16 + 32, 0 + 32, 16, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0);\n\n      __m512i c_perm_20_23 = _mm512_set_epi16(\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        16 + 32, 0 + 32, 16, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0);\n\n      __m512i c_perm_24_27 = _mm512_set_epi16(\n        0, 0, 0, 0,\n        16 + 32, 0 + 32, 16, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0);\n\n      __m512i c_perm_28_31 = _mm512_set_epi16(\n        16 + 32, 0 + 32, 16, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0);\n\n\n      __m512i one_epi16 = _mm512_set1_epi16(1);\n\n      // Define masks for the 4-word (8-byte, 4x 16-bit word) segments within the 32-word vector.\n      // Note: Each AVX-512 word (epi16) lane corresponds to one bit in the __mmask32.\n      // The masks target chunks of 4 words (k_X_Y represents bits X through Y inclusive).\n      const __mmask32 k_4_7 = 0x000000F0;\n      const __mmask32 k_8_11 = 0x00000F00;\n      const __mmask32 k_12_15 = 0x0000F000;\n      const __mmask32 k_16_19 = 0x000F0000;\n      const __mmask32 k_20_23 = 0x00F00000;\n      const __mmask32 k_24_27 = 0x0F000000;\n      const __mmask32 k_28_31 = 0xF0000000;\n\n      // Helper lambda to increment all eight permutation vectors by one.\n      auto inc_perms = [&](\n        __m512i& p0_3, __m512i& p4_7, __m512i& p8_11, __m512i& p12_15,\n        __m512i& p16_19, __m512i& p20_23, __m512i& p24_27, __m512i& p28_31\n        ) {\n          p0_3 = _mm512_add_epi16(p0_3, one_epi16);\n          p4_7 = _mm512_add_epi16(p4_7, one_epi16);\n          p8_11 = _mm512_add_epi16(p8_11, one_epi16);\n          p12_15 = _mm512_add_epi16(p12_15, one_epi16);\n          p16_19 = _mm512_add_epi16(p16_19, one_epi16);\n          p20_23 = _mm512_add_epi16(p20_23, one_epi16);\n          p24_27 = _mm512_add_epi16(p24_27, one_epi16);\n          p28_31 = _mm512_add_epi16(p28_31, one_epi16);\n        };\n\n      // Helper lambda to construct one full 32-word (512-bit) coefficient row.\n      // It uses mask blending to merge the results of _mm512_permutex2var_epi16\n      // for different 4-word segments, using the current permutation vectors.\n      auto make_coef_row = [&](\n        __m512i& row_result,\n        __m512i p0_3, __m512i p4_7, __m512i p8_11, __m512i p12_15,\n        __m512i p16_19, __m512i p20_23, __m512i p24_27, __m512i p28_31\n        ) {\n          // Start with the first segment (words 0-3) and the fourth segment (words 4-7).\n          row_result = _mm512_mask_blend_epi16(\n            k_4_7,\n            _mm512_permutex2var_epi16(coef_0_1, p0_3, coef_2_3),  // words 0-3 (unmasked)\n            _mm512_permutex2var_epi16(coef_4_5, p4_7, coef_6_7)   // words 4-7 (masked)\n          );\n\n          // Merge segment 8-11\n          row_result = _mm512_mask_blend_epi16(\n            k_8_11,\n            row_result,\n            _mm512_permutex2var_epi16(coef_8_9, p8_11, coef_10_11)\n          );\n\n          // Merge segment 12-15\n          row_result = _mm512_mask_blend_epi16(\n            k_12_15,\n            row_result,\n            _mm512_permutex2var_epi16(coef_12_13, p12_15, coef_14_15)\n          );\n\n          // Merge segment 16-19\n          row_result = _mm512_mask_blend_epi16(\n            k_16_19,\n            row_result,\n            _mm512_permutex2var_epi16(coef_16_17, p16_19, coef_18_19)\n          );\n\n          // Merge segment 20-23\n          row_result = _mm512_mask_blend_epi16(\n            k_20_23,\n            row_result,\n            _mm512_permutex2var_epi16(coef_20_21, p20_23, coef_22_23)\n          );\n\n          // Merge segment 24-27\n          row_result = _mm512_mask_blend_epi16(\n            k_24_27,\n            row_result,\n            _mm512_permutex2var_epi16(coef_24_25, p24_27, coef_26_27)\n          );\n\n          // Merge segment 28-31\n          row_result = _mm512_mask_blend_epi16(\n            k_28_31,\n            row_result,\n            _mm512_permutex2var_epi16(coef_28_29, p28_31, coef_30_31)\n          );\n        };\n\n      // Declare the coefficient row variables\n      __m512i coef_r0_0_31w, coef_r1_0_31w, coef_r2_0_31w, coef_r3_0_31w;\n      __m512i coef_r4_0_31w, coef_r5_0_31w, coef_r6_0_31w, coef_r7_0_31w;\n      __m512i coef_r8_0_31w, coef_r9_0_31w, coef_r10_0_31w, coef_r11_0_31w;\n      __m512i coef_r12_0_31w, coef_r13_0_31w, coef_r14_0_31w, coef_r15_0_31w;\n\n      // Process Row 0\n      make_coef_row(coef_r0_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 1\n      make_coef_row(coef_r1_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 2\n      make_coef_row(coef_r2_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 3\n      make_coef_row(coef_r3_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 4\n      make_coef_row(coef_r4_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 5\n      make_coef_row(coef_r5_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 6\n      make_coef_row(coef_r6_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 7\n      make_coef_row(coef_r7_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 8\n      make_coef_row(coef_r8_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 9\n      make_coef_row(coef_r9_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 10\n      make_coef_row(coef_r10_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 11\n      make_coef_row(coef_r11_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 12\n      make_coef_row(coef_r12_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 13\n      make_coef_row(coef_r13_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 14\n      make_coef_row(coef_r14_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 15\n      make_coef_row(coef_r15_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      // No inc_perms here\n\n      // convert-transpose to H-pairs for madd ? better to do with single permutex in future\n      // 16 to 16 512 registers - finally real working coeffs to store in the transposed resampling program for block of 64 target samples\n      __m512i coef_r0r1_0_31lo = _mm512_unpacklo_epi16(coef_r0_0_31w, coef_r1_0_31w);\n      __m512i coef_r0r1_0_31hi = _mm512_unpackhi_epi16(coef_r0_0_31w, coef_r1_0_31w);\n\n      __m512i coef_r2r3_0_31lo = _mm512_unpacklo_epi16(coef_r2_0_31w, coef_r3_0_31w);\n      __m512i coef_r2r3_0_31hi = _mm512_unpackhi_epi16(coef_r2_0_31w, coef_r3_0_31w);\n\n      __m512i coef_r4r5_0_31lo = _mm512_unpacklo_epi16(coef_r4_0_31w, coef_r5_0_31w);\n      __m512i coef_r4r5_0_31hi = _mm512_unpackhi_epi16(coef_r4_0_31w, coef_r5_0_31w);\n\n      __m512i coef_r6r7_0_31lo = _mm512_unpacklo_epi16(coef_r6_0_31w, coef_r7_0_31w);\n      __m512i coef_r6r7_0_31hi = _mm512_unpackhi_epi16(coef_r6_0_31w, coef_r7_0_31w);\n\n      __m512i coef_r8r9_0_31lo = _mm512_unpacklo_epi16(coef_r8_0_31w, coef_r9_0_31w);\n      __m512i coef_r8r9_0_31hi = _mm512_unpackhi_epi16(coef_r8_0_31w, coef_r9_0_31w);\n\n      __m512i coef_r10r11_0_31lo = _mm512_unpacklo_epi16(coef_r10_0_31w, coef_r11_0_31w);\n      __m512i coef_r10r11_0_31hi = _mm512_unpackhi_epi16(coef_r10_0_31w, coef_r11_0_31w);\n\n      __m512i coef_r12r13_0_31lo = _mm512_unpacklo_epi16(coef_r12_0_31w, coef_r13_0_31w);\n      __m512i coef_r12r13_0_31hi = _mm512_unpackhi_epi16(coef_r12_0_31w, coef_r13_0_31w);\n\n      __m512i coef_r14r15_0_31lo = _mm512_unpacklo_epi16(coef_r14_0_31w, coef_r15_0_31w);\n      __m512i coef_r14r15_0_31hi = _mm512_unpackhi_epi16(coef_r14_0_31w, coef_r15_0_31w);\n\n      // TODO: store transposed resampling program coeffs to temp buffer for reusage at each line\n\n      // convert resampling program in H-form into permuting indexes for src transposition in V-form\n      __m512i perm_0_0_15 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x])); // 16 offsets\n      __m512i perm_0_16_31 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 16])); //  16 offsets\n\n      int iStart = program->pixel_offset[x];\n      __m512i m512i_Start = _mm512_set1_epi32(iStart);\n\n      perm_0_0_15 = _mm512_sub_epi32(perm_0_0_15, m512i_Start);\n      perm_0_16_31 = _mm512_sub_epi32(perm_0_16_31, m512i_Start);\n\n      __m256i m256i_perm_0_0_15 = _mm512_cvtepi32_epi16(perm_0_0_15);\n      __m256i m256i_perm_0_16_31 = _mm512_cvtepi32_epi16(perm_0_16_31);\n\n      __m128i mm128i_perm_0_0_15 = _mm256_cvtepi16_epi8(m256i_perm_0_0_15);\n      __m128i mm128i_perm_0_16_31 = _mm256_cvtepi16_epi8(m256i_perm_0_16_31);\n\n      __m512i perm_0 = _mm512_inserti32x4(_mm512_zextsi128_si512(mm128i_perm_0_0_15), mm128i_perm_0_16_31, 1); // Lane 0+1 - 32 offsets only\n\n      // Taps are contiguous (0, 1, 2, 3), so we increment perm indexes by 1 (in pairs by 2 each).\n      const __m512i two_epi8 = _mm512_set1_epi8(2);\n\n      uint8_t* AVS_RESTRICT dst_ptr = dst8 + x + y_from * dst_pitch;\n      const uint8_t* src_ptr = src8 + iStart + y_from * src_pitch; // all permute offsets relative to this start offset\n\n      // Calculate remaining pixels for bounds checking in partial_load mode. 1..128 remaining pixels possible.\n      const int remaining = program->source_size - iStart;\n      const __mmask64 k1 = _bzhi_u64(~0ULL, remaining); // _bzhi_u64 creates a mask with the lower N bits set. If N >= 64, it returns all ones (~0ULL). \n      const __mmask64 k2 = _bzhi_u64(~0ULL, std::max(0, remaining - 64));\n\n      for (int y = y_from; y < y_to; y++)\n      {\n        __m512i data_src, data_src2;\n\n        // working permute indexes for advancing to save number of registers used\n        __m512i perm_w_even = perm_0;\n        __m512i perm_w_odd = _mm512_add_epi8(perm_0, _mm512_set1_epi8(1));\n\n        if constexpr (partial_load) {\n          // Safe masked loads for the image edge\n          data_src = _mm512_maskz_loadu_epi8(k1, src_ptr);\n          data_src2 = _mm512_maskz_loadu_epi8(k2, src_ptr + 64);\n        }\n        else {\n          // Fast unaligned loads for the safe zone\n          data_src = _mm512_loadu_si512(src_ptr);\n          data_src2 = _mm512_loadu_si512(src_ptr + 64);\n        }\n\n        // rows 0..3\n        __m512i data_0 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_even, data_src2);\n        __m512i data_1 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_odd, data_src2);\n        perm_w_even = _mm512_add_epi8(perm_w_even, two_epi8);\n        perm_w_odd = _mm512_add_epi8(perm_w_odd, two_epi8);\n\n        __m512i data_2 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_even, data_src2);\n        __m512i data_3 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_odd, data_src2);\n        perm_w_even = _mm512_add_epi8(perm_w_even, two_epi8);\n        perm_w_odd = _mm512_add_epi8(perm_w_odd, two_epi8);\n\n        // unpack 8->16bit 4 to 4 512bit registers source\n        __m512i src_r0_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_0));\n        __m512i src_r1_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_1));\n        __m512i src_r2_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_2));\n        __m512i src_r3_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_3));\n\n        // transposition to H-pairs 4 to 4 512bit registers \n        __m512i src_r0r1_0_31lo = _mm512_unpacklo_epi16(src_r0_0_31, src_r1_0_31);\n        __m512i src_r0r1_0_31hi = _mm512_unpackhi_epi16(src_r0_0_31, src_r1_0_31);\n        __m512i src_r2r3_0_31lo = _mm512_unpacklo_epi16(src_r2_0_31, src_r3_0_31);\n        __m512i src_r2r3_0_31hi = _mm512_unpackhi_epi16(src_r2_0_31, src_r3_0_31);\n\n        // making FMA in 32bits accs as in AVX256 V-resize\n        __m512i result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31lo, coef_r0r1_0_31lo), _mm512_madd_epi16(src_r2r3_0_31lo, coef_r2r3_0_31lo));\n        __m512i result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31hi, coef_r0r1_0_31hi), _mm512_madd_epi16(src_r2r3_0_31hi, coef_r2r3_0_31hi));\n\n        // rows 4..7\n        __m512i data_4 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_even, data_src2);\n        __m512i data_5 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_odd, data_src2);\n        perm_w_even = _mm512_add_epi8(perm_w_even, two_epi8);\n        perm_w_odd = _mm512_add_epi8(perm_w_odd, two_epi8);\n\n        __m512i data_6 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_even, data_src2);\n        __m512i data_7 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_odd, data_src2);\n        perm_w_even = _mm512_add_epi8(perm_w_even, two_epi8);\n        perm_w_odd = _mm512_add_epi8(perm_w_odd, two_epi8);\n\n        // unpack 8->16bit 4 to 8 512bit registers source\n        __m512i src_r4_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_4));\n        __m512i src_r5_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_5));\n        __m512i src_r6_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_6));\n        __m512i src_r7_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_7));\n\n        // transposition to H-pairs 4 to 4 512bit registers \n        __m512i src_r4r5_0_31lo = _mm512_unpacklo_epi16(src_r4_0_31, src_r5_0_31);\n        __m512i src_r4r5_0_31hi = _mm512_unpackhi_epi16(src_r4_0_31, src_r5_0_31);\n        __m512i src_r6r7_0_31lo = _mm512_unpacklo_epi16(src_r6_0_31, src_r7_0_31);\n        __m512i src_r6r7_0_31hi = _mm512_unpackhi_epi16(src_r6_0_31, src_r7_0_31);\n\n        result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_0_31lo, coef_r4r5_0_31lo), result_0_31lo);\n        result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_0_31hi, coef_r4r5_0_31hi), result_0_31hi);\n        result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_0_31lo, coef_r6r7_0_31lo), result_0_31lo);\n        result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_0_31hi, coef_r6r7_0_31hi), result_0_31hi);\n\n        // rows 8..11\n        __m512i data_8 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_even, data_src2);\n        __m512i data_9 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_odd, data_src2);\n        perm_w_even = _mm512_add_epi8(perm_w_even, two_epi8);\n        perm_w_odd = _mm512_add_epi8(perm_w_odd, two_epi8);\n\n        __m512i data_10 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_even, data_src2);\n        __m512i data_11 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_odd, data_src2);\n        perm_w_even = _mm512_add_epi8(perm_w_even, two_epi8);\n        perm_w_odd = _mm512_add_epi8(perm_w_odd, two_epi8);\n\n        // unpack 8->16bit 4 to 8 512bit registers source\n        __m512i src_r8_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_8));\n        __m512i src_r9_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_9));\n        __m512i src_r10_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_10));\n        __m512i src_r11_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_11));\n\n        // transposition to H-pairs 4 to 4 512bit registers \n        __m512i src_r8r9_0_31lo = _mm512_unpacklo_epi16(src_r8_0_31, src_r9_0_31);\n        __m512i src_r8r9_0_31hi = _mm512_unpackhi_epi16(src_r8_0_31, src_r9_0_31);\n        __m512i src_r10r11_0_31lo = _mm512_unpacklo_epi16(src_r10_0_31, src_r11_0_31);\n        __m512i src_r10r11_0_31hi = _mm512_unpackhi_epi16(src_r10_0_31, src_r11_0_31);\n\n        result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r8r9_0_31lo, coef_r8r9_0_31lo), result_0_31lo);\n        result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r8r9_0_31hi, coef_r8r9_0_31hi), result_0_31hi);\n        result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r10r11_0_31lo, coef_r10r11_0_31lo), result_0_31lo);\n        result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r10r11_0_31hi, coef_r10r11_0_31hi), result_0_31hi);\n\n        // rows 12..15\n        __m512i data_12 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_even, data_src2);\n        __m512i data_13 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_odd, data_src2);\n        perm_w_even = _mm512_add_epi8(perm_w_even, two_epi8);\n        perm_w_odd = _mm512_add_epi8(perm_w_odd, two_epi8);\n\n        __m512i data_14 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_even, data_src2);\n        __m512i data_15 = _mm512_permutex2var_epi8_SIMUL<UseVBMI>(data_src, perm_w_odd, data_src2);\n\n        // unpack 8->16bit 4 to 8 512bit registers source\n        __m512i src_r12_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_12));\n        __m512i src_r13_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_13));\n        __m512i src_r14_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_14));\n        __m512i src_r15_0_31 = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(data_15));\n\n        // transposition to H-pairs 4 to 4 512bit registers \n        __m512i src_r12r13_0_31lo = _mm512_unpacklo_epi16(src_r12_0_31, src_r13_0_31);\n        __m512i src_r12r13_0_31hi = _mm512_unpackhi_epi16(src_r12_0_31, src_r13_0_31);\n        __m512i src_r14r15_0_31lo = _mm512_unpacklo_epi16(src_r14_0_31, src_r15_0_31);\n        __m512i src_r14r15_0_31hi = _mm512_unpackhi_epi16(src_r14_0_31, src_r15_0_31);\n\n        result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r12r13_0_31lo, coef_r12r13_0_31lo), result_0_31lo);\n        result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r12r13_0_31hi, coef_r12r13_0_31hi), result_0_31hi);\n        result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r14r15_0_31lo, coef_r14r15_0_31lo), result_0_31lo);\n        result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r14r15_0_31hi, coef_r14r15_0_31hi), result_0_31hi);\n\n        // rounding\n        result_0_31lo = _mm512_add_epi32(result_0_31lo, rounder);\n        result_0_31hi = _mm512_add_epi32(result_0_31hi, rounder);\n        // scaling down\n        result_0_31lo = _mm512_srai_epi32(result_0_31lo, FPScale8bits);\n        result_0_31hi = _mm512_srai_epi32(result_0_31hi, FPScale8bits);\n\n        __m512i result_0_31_int16 = _mm512_packus_epi32(result_0_31lo, result_0_31hi);\n\n        __m256i result_0_31_u8 = _mm512_cvtusepi16_epi8(result_0_31_int16);\n\n        _mm256_stream_si256(reinterpret_cast<__m256i*>(dst_ptr), result_0_31_u8);\n\n        dst_ptr += dst_pitch;\n        src_ptr += src_pitch;\n      }\n\n      current_coeff += filter_size * PIXELS_AT_A_TIME;\n      };\n\n    // Process the 'safe zone' where direct full unaligned loads are acceptable.\n    for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)\n    {\n      do_h_integer_core(std::false_type{});\n    }\n\n    // Process the potentially 'unsafe zone' near the image edge, using safe masked loading.\n    for (; x < width; x += PIXELS_AT_A_TIME)\n    {\n      do_h_integer_core(std::true_type{});\n    }\n  }\n}\n\n// uint8_t \"mp\" versions\n\n// filter size up to 4\n// 64 target uint8_t pixels at a time\n// 127-byte source loads (127 uint8_t pixels)\n// maximum permute index is 127 for _mm512_maskz_permutex2var_epi8 (uint8_t) \n// more premutex version to create 8->16bit converted and low-hi unpacked registers in single permutex instruction\ntemplate<bool UseVNNI>\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)\n{\n  const int filter_size = program->filter_size; // aligned, practically the coeff table stride\n\n  constexpr int PIXELS_AT_A_TIME = 64;\n\n  // 'source_overread_beyond_targetx' indicates if the filter kernel can read beyond the target width.\n  // we load 2x64 source bytes at a time, so ensure safe overread if needed.\n  // Our main loop processes calculates for 64 target pixels at a time.\n  // Inside that, we load 128 source bytes (2x64) to be able to permutex from that.\n  // This we have to check at each mod-PIXELS_AT_A_TIME boundary, the allowance of 128-byte source load.\n  const int width_safe_mod = (program->safelimit_128_pixels_each64th_target.overread_possible ? program->safelimit_128_pixels_each64th_target.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  // Preconditions:\n  assert(program->filter_size_real <= 4); // We preload all relevant coefficients (up to 4) before the height loop.\n\n  // 'target_size_alignment' ensures we can safely access coefficients using offsets like\n  // 'filter_size * 15' when processing 16 H pixels at a time\n  // 'filter_size * 63' when processing 64 H pixels at a time\n  assert(program->target_size_alignment >= 64); // Adjusted for 64 pixels (is it enough for uint8 ?)\n\n  assert(FRAME_ALIGN >= 64); // Good for 64x8 bit pixels\n\n  // Ensure that coefficient loading beyond the valid target size is safe for 4x4 float loads.\n  // We load 4x16bit coeffs at a time\n  assert(program->filter_size_alignment >= 4);\n\n  const int max_scanlines = program->max_scanlines;\n\n  __m512i rounder = _mm512_set1_epi32(1 << (FPScale8bits - 1));\n\n  // Vertical stripe loop for L2 cache optimization\n  for (int y_from = 0; y_from < height; y_from += max_scanlines)\n  {\n    int y_to = std::min(y_from + max_scanlines, height);\n\n    // Reset current_coeff for the start of the stripe (points to start of row's coeffs)\n    const short* AVS_RESTRICT current_coeff = program->pixel_coefficient;\n\n    int x = 0;\n\n    // Lambda to handle both safe (fast) and unsafe (masked/partial) loading paths\n    auto do_h_integer_core = [&](auto partial_load) {\n\n      // prepare coefs in transposed V-form\n      // TODO: make storage in transposed form, 64 x uint16 transposition looks too slow\n      // TO FIX: filter_size=4 resize uses filter_size=16 - lots or RAM/cache wasted, in the ready to use transposed form it will be much more optimized\n\n      // 4coefs of 16bit is 64bits, can be loaded as set_epi64 ?\n      __m512i coef_0_7 = _mm512_setr_epi64(\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 0),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 1),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 2),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 3),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 4),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 5),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 6),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 7)\n      );\n\n      __m512i coef_8_15 = _mm512_setr_epi64(\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 8),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 9),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 10),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 11),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 12),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 13),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 14),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 15)\n      );\n\n      __m512i coef_16_23 = _mm512_setr_epi64(\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 16),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 17),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 18),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 19),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 20),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 21),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 22),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 23)\n      );\n\n      __m512i coef_24_31 = _mm512_setr_epi64(\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 24),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 25),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 26),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 27),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 28),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 29),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 30),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 31)\n      );\n\n      __m512i coef_32_39 = _mm512_setr_epi64(\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 32),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 33),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 34),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 35),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 36),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 37),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 38),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 39)\n      );\n\n      __m512i coef_40_47 = _mm512_setr_epi64(\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 40),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 41),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 42),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 43),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 44),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 45),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 46),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 47)\n      );\n\n      __m512i coef_48_55 = _mm512_setr_epi64(\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 48),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 49),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 50),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 51),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 52),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 53),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 54),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 55)\n      );\n\n      __m512i coef_56_63 = _mm512_setr_epi64(\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 56),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 57),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 58),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 59),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 60),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 61),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 62),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 63)\n      );\n\n      // Transpose with permutex\n      __m512i c_perm_0 = _mm512_set_epi16(28 + 32, 24 + 32, 20 + 32, 16 + 32, 12 + 32, 8 + 32, 4 + 32, 0 + 32, 28, 24, 20, 16, 12, 8, 4, 0,\n        28 + 32, 24 + 32, 20 + 32, 16 + 32, 12 + 32, 8 + 32, 4 + 32, 0 + 32, 28, 24, 20, 16, 12, 8, 4, 0);\n      __m512i one_epi16 = _mm512_set1_epi16(1);\n      const __mmask32 k_high = 0xFFFF0000;\n      // 0.0 .. 15.0 in low 256, 16.0 .. 31.0 in high 256\n      __m512i coef_r0_0_31w = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(coef_0_7, c_perm_0, coef_8_15), _mm512_permutex2var_epi16(coef_16_23, c_perm_0, coef_24_31));\n      // 32.0 .. 47.0  in low 256, 48.0 .. 63.0 in high 256\n      __m512i coef_r0_32_63w = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(coef_32_39, c_perm_0, coef_40_47), _mm512_permutex2var_epi16(coef_48_55, c_perm_0, coef_56_63));\n      c_perm_0 = _mm512_add_epi16(c_perm_0, one_epi16);\n      __m512i coef_r1_0_31w = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(coef_0_7, c_perm_0, coef_8_15), _mm512_permutex2var_epi16(coef_16_23, c_perm_0, coef_24_31));\n      __m512i coef_r1_32_63w = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(coef_32_39, c_perm_0, coef_40_47), _mm512_permutex2var_epi16(coef_48_55, c_perm_0, coef_56_63));\n      c_perm_0 = _mm512_add_epi16(c_perm_0, one_epi16);\n      __m512i coef_r2_0_31w = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(coef_0_7, c_perm_0, coef_8_15), _mm512_permutex2var_epi16(coef_16_23, c_perm_0, coef_24_31));\n      __m512i coef_r2_32_63w = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(coef_32_39, c_perm_0, coef_40_47), _mm512_permutex2var_epi16(coef_48_55, c_perm_0, coef_56_63));\n      c_perm_0 = _mm512_add_epi16(c_perm_0, one_epi16);\n      __m512i coef_r3_0_31w = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(coef_0_7, c_perm_0, coef_8_15), _mm512_permutex2var_epi16(coef_16_23, c_perm_0, coef_24_31));\n      __m512i coef_r3_32_63w = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(coef_32_39, c_perm_0, coef_40_47), _mm512_permutex2var_epi16(coef_48_55, c_perm_0, coef_56_63));\n\n      // convert-transpose to H-pairs for madd ? better to do with single permutex in future\n      // 8 to 8 512 registers - finally real working coeffs to store in the transposed resampling program for block of 64 target samples\n      const __m512i coef_r0r1_0_31lo = _mm512_unpacklo_epi16(coef_r0_0_31w, coef_r1_0_31w);\n      const __m512i coef_r0r1_0_31hi = _mm512_unpackhi_epi16(coef_r0_0_31w, coef_r1_0_31w);\n\n      const __m512i coef_r0r1_32_63lo = _mm512_unpacklo_epi16(coef_r0_32_63w, coef_r1_32_63w);\n      const __m512i coef_r0r1_32_63hi = _mm512_unpackhi_epi16(coef_r0_32_63w, coef_r1_32_63w);\n\n      const __m512i coef_r2r3_0_31lo = _mm512_unpacklo_epi16(coef_r2_0_31w, coef_r3_0_31w);\n      const __m512i coef_r2r3_0_31hi = _mm512_unpackhi_epi16(coef_r2_0_31w, coef_r3_0_31w);\n\n      const __m512i coef_r2r3_32_63lo = _mm512_unpacklo_epi16(coef_r2_32_63w, coef_r3_32_63w);\n      const __m512i coef_r2r3_32_63hi = _mm512_unpackhi_epi16(coef_r2_32_63w, coef_r3_32_63w);\n\n      // TODO: store transposed resampling program coeffs to temp buffer for reusage at each line\n\n      // convert resampling program in H-form into permuting indexes for src transposition in V-form\n      __m512i perm_0_0_15 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x])); // 16 offsets\n      __m512i perm_0_16_31 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 16])); //  16 offsets\n      __m512i perm_0_32_47 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 32])); //  16 offsets\n      __m512i perm_0_48_63 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 48])); //  16 offsets\n\n      int iStart = program->pixel_offset[x];\n      __m512i m512i_Start = _mm512_set1_epi32(iStart);\n\n      perm_0_0_15 = _mm512_sub_epi32(perm_0_0_15, m512i_Start);\n      perm_0_16_31 = _mm512_sub_epi32(perm_0_16_31, m512i_Start);\n      perm_0_32_47 = _mm512_sub_epi32(perm_0_32_47, m512i_Start);\n      perm_0_48_63 = _mm512_sub_epi32(perm_0_48_63, m512i_Start);\n\n      __m256i m256i_perm_0_0_15 = _mm512_cvtepi32_epi16(perm_0_0_15);\n      __m256i m256i_perm_0_16_31 = _mm512_cvtepi32_epi16(perm_0_16_31);\n      __m256i m256i_perm_0_32_47 = _mm512_cvtepi32_epi16(perm_0_32_47);\n      __m256i m256i_perm_0_48_63 = _mm512_cvtepi32_epi16(perm_0_48_63);\n\n      __m512i perm_0_0_31 = _mm512_inserti64x4(_mm512_zextsi256_si512(m256i_perm_0_0_15), m256i_perm_0_16_31, 1);\n      __m512i perm_0_32_63 = _mm512_inserti64x4(_mm512_zextsi256_si512(m256i_perm_0_32_47), m256i_perm_0_48_63, 1);\n\n      // Taps are contiguous (0, 1, 2, 3), so we increment perm indexes by 1.\n      __m512i perm_1_0_31 = _mm512_add_epi16(perm_0_0_31, one_epi16);\n      __m512i perm_2_0_31 = _mm512_add_epi16(perm_1_0_31, one_epi16);\n      __m512i perm_3_0_31 = _mm512_add_epi16(perm_2_0_31, one_epi16);\n\n      __m512i perm_1_32_63 = _mm512_add_epi16(perm_0_32_63, one_epi16);\n      __m512i perm_2_32_63 = _mm512_add_epi16(perm_1_32_63, one_epi16);\n      __m512i perm_3_32_63 = _mm512_add_epi16(perm_2_32_63, one_epi16);\n\n      const __m512i perm_r0r1_0_31lo = _mm512_unpacklo_epi16(perm_0_0_31, perm_1_0_31);\n      const __m512i perm_r0r1_0_31hi = _mm512_unpackhi_epi16(perm_0_0_31, perm_1_0_31);\n\n      const __m512i perm_r0r1_32_63lo = _mm512_unpacklo_epi16(perm_0_32_63, perm_1_32_63);\n      const __m512i perm_r0r1_32_63hi = _mm512_unpackhi_epi16(perm_0_32_63, perm_1_32_63);\n\n      const __m512i perm_r2r3_0_31lo = _mm512_unpacklo_epi16(perm_2_0_31, perm_3_0_31);\n      const __m512i perm_r2r3_0_31hi = _mm512_unpackhi_epi16(perm_2_0_31, perm_3_0_31);\n\n      const __m512i perm_r2r3_32_63lo = _mm512_unpacklo_epi16(perm_2_32_63, perm_3_32_63);\n      const __m512i perm_r2r3_32_63hi = _mm512_unpackhi_epi16(perm_2_32_63, perm_3_32_63);\n\n      uint8_t* AVS_RESTRICT dst_ptr = dst8 + x + y_from * dst_pitch;\n      const uint8_t* src_ptr = src8 + iStart + y_from * src_pitch; // all permute offsets relative to this start offset\n\n      // Calculate remaining pixels for bounds checking in partial_load mode. 1..128 remaining pixels possible.\n      const int remaining = program->source_size - iStart;\n      __mmask64 k1 = _bzhi_u64(~0ULL, remaining); // _bzhi_u64 creates a mask with the lower N bits set. If N >= 64, it returns all ones (~0ULL). \n      __mmask64 k2 = _bzhi_u64(~0ULL, std::max(0, remaining - 64));\n\n      // mask is used to zero out every odd byte, so that the result of the permute is a\n      // vector of zero-extended 8-bit values in 16-bit lanes, preparing 8-bit data for 16-bit FMA operations in AVX512.\n      const __mmask64 k_zh8 = 0x5555555555555555ULL;\n\n      for (int y = y_from; y < y_to; y++)\n      {\n        // 8 coeffs + 8 permute_idx + 2 src + 4 temporal + 1 rounder ~= 23 regs (permute2var overwrite first source - really may be more needed)\n        __m512i data_src, data_src2;\n\n        if constexpr (partial_load) {\n          // Safe masked loads for the image edge\n          data_src = _mm512_maskz_loadu_epi8(k1, src_ptr);\n          data_src2 = _mm512_maskz_loadu_epi8(k2, src_ptr + 64);\n        }\n        else {\n          // Fast unaligned loads for the safe zone\n          data_src = _mm512_loadu_si512(src_ptr);\n          data_src2 = _mm512_loadu_si512(src_ptr + 64);\n        }\n\n        __m512i src_r0r1_0_31lo = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_r0r1_0_31lo, data_src2);\n        __m512i src_r0r1_0_31hi = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_r0r1_0_31hi, data_src2);\n\n        __m512i src_r0r1_32_63lo = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_r0r1_32_63lo, data_src2);\n        __m512i src_r0r1_32_63hi = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_r0r1_32_63hi, data_src2);\n\n        __m512i src_r2r3_0_31lo = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_r2r3_0_31lo, data_src2);\n        __m512i src_r2r3_0_31hi = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_r2r3_0_31hi, data_src2);\n\n        __m512i src_r2r3_32_63lo = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_r2r3_32_63lo, data_src2);\n        __m512i src_r2r3_32_63hi = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_r2r3_32_63hi, data_src2);\n\n        __m512i result_0_31lo, result_0_31hi;\n        __m512i result_32_63lo, result_32_63hi;\n\n        if constexpr (UseVNNI)\n        {\n          // Unlike _ks8, here in _ks4 LLVM did not use VNNI vpdpwssd, but decided to use madd and add. Perhaps it knows port pressure and latency?\n          result_0_31lo = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31lo, coef_r0r1_0_31lo);\n          result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r2r3_0_31lo, coef_r2r3_0_31lo);\n\n          result_0_31hi = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31hi, coef_r0r1_0_31hi);\n          result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r2r3_0_31hi, coef_r2r3_0_31hi);\n\n          result_32_63lo = _mm512_dpwssd_epi32(rounder, src_r0r1_32_63lo, coef_r0r1_32_63lo);\n          result_32_63lo = _mm512_dpwssd_epi32(result_32_63lo, src_r2r3_32_63lo, coef_r2r3_32_63lo);\n\n          result_32_63hi = _mm512_dpwssd_epi32(rounder, src_r0r1_32_63hi, coef_r0r1_32_63hi);\n          result_32_63hi = _mm512_dpwssd_epi32(result_32_63hi, src_r2r3_32_63hi, coef_r2r3_32_63hi);\n        }\n        else\n        {\n          // making FMA in 32bits accs as in AVX256 V-resize\n          result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31lo, coef_r0r1_0_31lo), _mm512_madd_epi16(src_r2r3_0_31lo, coef_r2r3_0_31lo));\n          result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31hi, coef_r0r1_0_31hi), _mm512_madd_epi16(src_r2r3_0_31hi, coef_r2r3_0_31hi));\n\n          result_32_63lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_32_63lo, coef_r0r1_32_63lo), _mm512_madd_epi16(src_r2r3_32_63lo, coef_r2r3_32_63lo));\n          result_32_63hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_32_63hi, coef_r0r1_32_63hi), _mm512_madd_epi16(src_r2r3_32_63hi, coef_r2r3_32_63hi));\n\n          // rounding\n          result_0_31lo = _mm512_add_epi32(result_0_31lo, rounder);\n          result_0_31hi = _mm512_add_epi32(result_0_31hi, rounder);\n          result_32_63lo = _mm512_add_epi32(result_32_63lo, rounder);\n          result_32_63hi = _mm512_add_epi32(result_32_63hi, rounder);\n        }\n\n        // scaling down\n        result_0_31lo = _mm512_srai_epi32(result_0_31lo, FPScale8bits);\n        result_0_31hi = _mm512_srai_epi32(result_0_31hi, FPScale8bits);\n        result_32_63lo = _mm512_srai_epi32(result_32_63lo, FPScale8bits);\n        result_32_63hi = _mm512_srai_epi32(result_32_63hi, FPScale8bits);\n\n        __m512i result_0_31_int16 = _mm512_packus_epi32(result_0_31lo, result_0_31hi);\n        __m512i result_32_63_int16 = _mm512_packus_epi32(result_32_63lo, result_32_63hi);\n\n        // cast is enough, no need to _mm512_zextsi256_si512\n        _mm512_stream_si512(reinterpret_cast<__m512i*>(dst_ptr),\n          _mm512_inserti64x4(_mm512_castsi256_si512(_mm512_cvtusepi16_epi8(result_0_31_int16)), _mm512_cvtusepi16_epi8(result_32_63_int16), 1));\n\n        dst_ptr += dst_pitch;\n        src_ptr += src_pitch;\n      }\n\n      current_coeff += filter_size * PIXELS_AT_A_TIME;\n      };\n\n    // Process the 'safe zone' where direct full unaligned loads are acceptable.\n    for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)\n    {\n      do_h_integer_core(std::false_type{});\n    }\n\n    // Process the potentially 'unsafe zone' near the image edge, using safe masked loading.\n    for (; x < width; x += PIXELS_AT_A_TIME)\n    {\n      do_h_integer_core(std::true_type{});\n    }\n  }\n}\n\n// filter size up to 8\n// 64 target uint8_t pixels at a time\n// 128-byte source loads (128 uint8_t pixels)\n// maximum permute index is 128 for _mm512_maskz_permutex2var_epi8 (uint8_t)\n// support VNNI and madd FMA\ntemplate<bool UseVNNI>\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)\n{\n  const int filter_size = program->filter_size; // aligned, practically the coeff table stride\n\n  constexpr int PIXELS_AT_A_TIME = 64;\n\n  // 'source_overread_beyond_targetx' indicates if the filter kernel can read beyond the target width.\n  // we load 2x64 source bytes at a time, so ensure safe overread if needed.\n  // Our main loop processes calculates for 64 target pixels at a time.\n  // Inside that, we load 128 source bytes (2x64) to be able to permutex from that.\n  // This we have to check at each mod-PIXELS_AT_A_TIME boundary, the allowance of 128-byte source load.\n  const int width_safe_mod = (program->safelimit_128_pixels_each64th_target.overread_possible ? program->safelimit_128_pixels_each64th_target.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  // Preconditions:\n  assert(program->filter_size_real <= 8); // We preload all relevant coefficients (up to 8) before the height loop.\n\n  // 'target_size_alignment' ensures we can safely access coefficients using offsets like\n  // 'filter_size * 15' when processing 16 H pixels at a time\n  // 'filter_size * 63' when processing 64 H pixels at a time\n  assert(program->target_size_alignment >= 64); // Adjusted for 64 pixels (is it enough for uint8 ?)\n\n  assert(FRAME_ALIGN >= 64); // Good for 64x8 bit pixels\n\n  // Ensure that coefficient loading beyond the valid target size is safe for 4x8 float loads.\n  // We load 8x 'short' coeffs at a time\n  // Loading is unaligned, but we fill __m128 registers before combining into __m512\n  assert(program->filter_size_alignment >= 8);\n\n  const int max_scanlines = program->max_scanlines;\n\n  __m512i rounder = _mm512_set1_epi32(1 << (FPScale8bits - 1));\n\n  // Vertical stripe loop for L2 cache optimization\n  for (int y_from = 0; y_from < height; y_from += max_scanlines)\n  {\n    int y_to = std::min(y_from + max_scanlines, height);\n\n    // Reset current_coeff for the start of the stripe (points to start of row's coeffs)\n    const short* AVS_RESTRICT current_coeff = program->pixel_coefficient;\n\n    int x = 0;\n\n    // Lambda to handle both safe (fast) and unsafe (masked/partial) loading paths\n    auto do_h_integer_core = [&](auto partial_load) {\n\n      // prepare coefs in transposed V-form\n      // TODO: make storage in transposed form, 64 x uint16 transposition looks too slow\n\n      // 8coefs of 16bit is 128bits \n      __m512i coef_0_3 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 0), (__m128i*)(current_coeff + filter_size * 1), (__m128i*)(current_coeff + filter_size * 2), (__m128i*)(current_coeff + filter_size * 3));\n      __m512i coef_4_7 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 4), (__m128i*)(current_coeff + filter_size * 5), (__m128i*)(current_coeff + filter_size * 6), (__m128i*)(current_coeff + filter_size * 7));\n      __m512i coef_8_11 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 8), (__m128i*)(current_coeff + filter_size * 9), (__m128i*)(current_coeff + filter_size * 10), (__m128i*)(current_coeff + filter_size * 11));\n      __m512i coef_12_15 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 12), (__m128i*)(current_coeff + filter_size * 13), (__m128i*)(current_coeff + filter_size * 14), (__m128i*)(current_coeff + filter_size * 15));\n      __m512i coef_16_19 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 16), (__m128i*)(current_coeff + filter_size * 17), (__m128i*)(current_coeff + filter_size * 18), (__m128i*)(current_coeff + filter_size * 19));\n      __m512i coef_20_23 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 20), (__m128i*)(current_coeff + filter_size * 21), (__m128i*)(current_coeff + filter_size * 22), (__m128i*)(current_coeff + filter_size * 23));\n      __m512i coef_24_27 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 24), (__m128i*)(current_coeff + filter_size * 25), (__m128i*)(current_coeff + filter_size * 26), (__m128i*)(current_coeff + filter_size * 27));\n      __m512i coef_28_31 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 28), (__m128i*)(current_coeff + filter_size * 29), (__m128i*)(current_coeff + filter_size * 30), (__m128i*)(current_coeff + filter_size * 31));\n\n      __m512i coef_32_35 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 32), (__m128i*)(current_coeff + filter_size * 33), (__m128i*)(current_coeff + filter_size * 34), (__m128i*)(current_coeff + filter_size * 35));\n      __m512i coef_36_39 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 36), (__m128i*)(current_coeff + filter_size * 37), (__m128i*)(current_coeff + filter_size * 38), (__m128i*)(current_coeff + filter_size * 39));\n      __m512i coef_40_43 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 40), (__m128i*)(current_coeff + filter_size * 41), (__m128i*)(current_coeff + filter_size * 42), (__m128i*)(current_coeff + filter_size * 43));\n      __m512i coef_44_47 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 44), (__m128i*)(current_coeff + filter_size * 45), (__m128i*)(current_coeff + filter_size * 46), (__m128i*)(current_coeff + filter_size * 47));\n      __m512i coef_48_51 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 48), (__m128i*)(current_coeff + filter_size * 49), (__m128i*)(current_coeff + filter_size * 50), (__m128i*)(current_coeff + filter_size * 51));\n      __m512i coef_52_55 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 52), (__m128i*)(current_coeff + filter_size * 53), (__m128i*)(current_coeff + filter_size * 54), (__m128i*)(current_coeff + filter_size * 55));\n      __m512i coef_56_59 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 56), (__m128i*)(current_coeff + filter_size * 57), (__m128i*)(current_coeff + filter_size * 58), (__m128i*)(current_coeff + filter_size * 59));\n      __m512i coef_60_63 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 60), (__m128i*)(current_coeff + filter_size * 61), (__m128i*)(current_coeff + filter_size * 62), (__m128i*)(current_coeff + filter_size * 63));\n\n      // Transpose with permutex\n      __m512i c_perm_0_7 = _mm512_set_epi16(\n        0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0,\n        24 + 32, 16 + 32, 8 + 32, 0 + 32, 24, 16, 8, 0);\n      __m512i c_perm_8_15 = _mm512_set_epi16(\n        0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0,\n        24 + 32, 16 + 32, 8 + 32, 0 + 32, 24, 16, 8, 0,\n        0, 0, 0, 0, 0, 0, 0, 0);\n      __m512i c_perm_16_23 = _mm512_set_epi16(\n        0, 0, 0, 0, 0, 0, 0, 0,\n        24 + 32, 16 + 32, 8 + 32, 0 + 32, 24, 16, 8, 0,\n        0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0);\n      __m512i c_perm_24_31 = _mm512_set_epi16(\n        24 + 32, 16 + 32, 8 + 32, 0 + 32, 24, 16, 8, 0,\n        0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0);\n\n      __m512i one_epi16 = _mm512_set1_epi16(1);\n      const __mmask32 k_8_15 = 0x0000FF00;\n      const __mmask32 k_16_23 = 0x00FF0000;\n      const __mmask32 k_24_31 = 0xFF000000;\n\n      auto inc_perms = [&](\n        __m512i& c0_7,\n        __m512i& c8_15,\n        __m512i& c16_23,\n        __m512i& c24_31\n        ) {\n          c0_7 = _mm512_add_epi16(c0_7, one_epi16);\n          c8_15 = _mm512_add_epi16(c8_15, one_epi16);\n          c16_23 = _mm512_add_epi16(c16_23, one_epi16);\n          c24_31 = _mm512_add_epi16(c24_31, one_epi16);\n        };\n\n      auto make_row_0_63 = [&](\n        __m512i& row_0_31w, __m512i& row_32_63w,\n        __m512i c0_7, __m512i c8_15, __m512i c16_23, __m512i c24_31\n        ) {\n          // 0..31\n          row_0_31w = _mm512_mask_blend_epi16(\n            k_8_15,\n            _mm512_permutex2var_epi16(coef_0_3, c0_7, coef_4_7),\n            _mm512_permutex2var_epi16(coef_8_11, c8_15, coef_12_15)\n          );\n          row_0_31w = _mm512_mask_blend_epi16(\n            k_16_23,\n            row_0_31w,\n            _mm512_permutex2var_epi16(coef_16_19, c16_23, coef_20_23)\n          );\n          row_0_31w = _mm512_mask_blend_epi16(\n            k_24_31,\n            row_0_31w,\n            _mm512_permutex2var_epi16(coef_24_27, c24_31, coef_28_31)\n          );\n\n          // 32..63\n          row_32_63w = _mm512_mask_blend_epi16(\n            k_8_15,\n            _mm512_permutex2var_epi16(coef_32_35, c0_7, coef_36_39),\n            _mm512_permutex2var_epi16(coef_40_43, c8_15, coef_44_47)\n          );\n          row_32_63w = _mm512_mask_blend_epi16(\n            k_16_23,\n            row_32_63w,\n            _mm512_permutex2var_epi16(coef_48_51, c16_23, coef_52_55)\n          );\n          row_32_63w = _mm512_mask_blend_epi16(\n            k_24_31,\n            row_32_63w,\n            _mm512_permutex2var_epi16(coef_56_59, c24_31, coef_60_63)\n          );\n        };\n\n      __m512i coef_r0_0_31w, coef_r0_32_63w;\n      __m512i coef_r1_0_31w, coef_r1_32_63w;\n      __m512i coef_r2_0_31w, coef_r2_32_63w;\n      __m512i coef_r3_0_31w, coef_r3_32_63w;\n      __m512i coef_r4_0_31w, coef_r4_32_63w;\n      __m512i coef_r5_0_31w, coef_r5_32_63w;\n      __m512i coef_r6_0_31w, coef_r6_32_63w;\n      __m512i coef_r7_0_31w, coef_r7_32_63w;\n\n      // r0\n      make_row_0_63(coef_r0_0_31w, coef_r0_32_63w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r1\n      make_row_0_63(coef_r1_0_31w, coef_r1_32_63w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r2\n      make_row_0_63(coef_r2_0_31w, coef_r2_32_63w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r3\n      make_row_0_63(coef_r3_0_31w, coef_r3_32_63w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r4\n      make_row_0_63(coef_r4_0_31w, coef_r4_32_63w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r5\n      make_row_0_63(coef_r5_0_31w, coef_r5_32_63w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r6\n      make_row_0_63(coef_r6_0_31w, coef_r6_32_63w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r7\n      make_row_0_63(coef_r7_0_31w, coef_r7_32_63w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      /* // last one, not needed\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      */\n\n      // convert-transpose to H-pairs for madd ? better to do with single permutex in future\n      // 16 to 16 512 registers - finally real working coeffs to store in the transposed resampling program for block of 64 target samples\n      __m512i coef_r0r1_0_31lo = _mm512_unpacklo_epi16(coef_r0_0_31w, coef_r1_0_31w);\n      __m512i coef_r0r1_0_31hi = _mm512_unpackhi_epi16(coef_r0_0_31w, coef_r1_0_31w);\n\n      __m512i coef_r0r1_32_63lo = _mm512_unpacklo_epi16(coef_r0_32_63w, coef_r1_32_63w);\n      __m512i coef_r0r1_32_63hi = _mm512_unpackhi_epi16(coef_r0_32_63w, coef_r1_32_63w);\n\n      __m512i coef_r2r3_0_31lo = _mm512_unpacklo_epi16(coef_r2_0_31w, coef_r3_0_31w);\n      __m512i coef_r2r3_0_31hi = _mm512_unpackhi_epi16(coef_r2_0_31w, coef_r3_0_31w);\n\n      __m512i coef_r2r3_32_63lo = _mm512_unpacklo_epi16(coef_r2_32_63w, coef_r3_32_63w);\n      __m512i coef_r2r3_32_63hi = _mm512_unpackhi_epi16(coef_r2_32_63w, coef_r3_32_63w);\n\n      __m512i coef_r4r5_0_31lo = _mm512_unpacklo_epi16(coef_r4_0_31w, coef_r5_0_31w);\n      __m512i coef_r4r5_0_31hi = _mm512_unpackhi_epi16(coef_r4_0_31w, coef_r5_0_31w);\n\n      __m512i coef_r4r5_32_63lo = _mm512_unpacklo_epi16(coef_r4_32_63w, coef_r5_32_63w);\n      __m512i coef_r4r5_32_63hi = _mm512_unpackhi_epi16(coef_r4_32_63w, coef_r5_32_63w);\n\n      __m512i coef_r6r7_0_31lo = _mm512_unpacklo_epi16(coef_r6_0_31w, coef_r7_0_31w);\n      __m512i coef_r6r7_0_31hi = _mm512_unpackhi_epi16(coef_r6_0_31w, coef_r7_0_31w);\n\n      __m512i coef_r6r7_32_63lo = _mm512_unpacklo_epi16(coef_r6_32_63w, coef_r7_32_63w);\n      __m512i coef_r6r7_32_63hi = _mm512_unpackhi_epi16(coef_r6_32_63w, coef_r7_32_63w);\n\n      // TODO: store transposed resampling program coeffs to temp buffer for reusage at each line\n\n      // convert resampling program in H-form into permuting indexes for src transposition in V-form\n      __m512i perm_0_0_15 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x])); // 16 offsets\n      __m512i perm_0_16_31 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 16])); //  16 offsets\n      __m512i perm_0_32_47 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 32])); //  16 offsets\n      __m512i perm_0_48_63 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 48])); //  16 offsets\n\n      int iStart = program->pixel_offset[x];\n      __m512i m512i_Start = _mm512_set1_epi32(iStart);\n\n      perm_0_0_15 = _mm512_sub_epi32(perm_0_0_15, m512i_Start);\n      perm_0_16_31 = _mm512_sub_epi32(perm_0_16_31, m512i_Start);\n      perm_0_32_47 = _mm512_sub_epi32(perm_0_32_47, m512i_Start);\n      perm_0_48_63 = _mm512_sub_epi32(perm_0_48_63, m512i_Start);\n\n      __m256i m256i_perm_0_0_15 = _mm512_cvtepi32_epi16(perm_0_0_15);\n      __m256i m256i_perm_0_16_31 = _mm512_cvtepi32_epi16(perm_0_16_31);\n      __m256i m256i_perm_0_32_47 = _mm512_cvtepi32_epi16(perm_0_32_47);\n      __m256i m256i_perm_0_48_63 = _mm512_cvtepi32_epi16(perm_0_48_63);\n\n      __m512i perm_0_0_31 = _mm512_inserti64x4(_mm512_zextsi256_si512(m256i_perm_0_0_15), m256i_perm_0_16_31, 1);\n      __m512i perm_0_32_63 = _mm512_inserti64x4(_mm512_zextsi256_si512(m256i_perm_0_32_47), m256i_perm_0_48_63, 1);\n\n      // no add_one to each perm group to save number of registers used in processing loop\n      // need only to first pair (r0 and r1)\n      __m512i perm_1_0_31 = _mm512_add_epi16(perm_0_0_31, one_epi16);\n      __m512i perm_1_32_63 = _mm512_add_epi16(perm_0_32_63, one_epi16);\n\n      const __m512i perm_r0r1_0_31lo = _mm512_unpacklo_epi16(perm_0_0_31, perm_1_0_31);\n      const __m512i perm_r0r1_0_31hi = _mm512_unpackhi_epi16(perm_0_0_31, perm_1_0_31);\n\n      const __m512i perm_r0r1_32_63lo = _mm512_unpacklo_epi16(perm_0_32_63, perm_1_32_63);\n      const __m512i perm_r0r1_32_63hi = _mm512_unpackhi_epi16(perm_0_32_63, perm_1_32_63);\n\n      // Taps are contiguous (0, 1, 2, 3), so we increment perm indexes by 1 (in pairs by 2 each).\n      const __m512i two_epi16 = _mm512_set1_epi16(2);\n\n      uint8_t* AVS_RESTRICT dst_ptr = dst8 + x + y_from * dst_pitch;\n      const uint8_t* src_ptr = src8 + iStart + y_from * src_pitch; // all permute offsets relative to this start offset\n\n      // Calculate remaining pixels for bounds checking in partial_load mode. 1..128 remaining pixels possible.\n      const int remaining = program->source_size - iStart;\n      __mmask64 k1 = _bzhi_u64(~0ULL, remaining); // _bzhi_u64 creates a mask with the lower N bits set. If N >= 64, it returns all ones (~0ULL). \n      const __mmask64 k2 = _bzhi_u64(~0ULL, std::max(0, remaining - 64));\n\n      // mask is used to zero out every odd byte, so that the result of the permute is a\n      // vector of zero-extended 8-bit values in 16-bit lanes, preparing 8-bit data for 16-bit FMA operations in AVX512.\n      const __mmask64 k_zh8 = 0x5555555555555555ULL;\n\n      for (int y = y_from; y < y_to; y++)\n      {\n        __m512i data_src, data_src2;\n\n        // working permute indexes for advancing to save number of registers used\n        __m512i perm_rNrNp1_0_31lo_w = perm_r0r1_0_31lo;\n        __m512i perm_rNrNp1_0_31hi_w = perm_r0r1_0_31hi;\n\n        __m512i perm_rNrNp1_32_63lo_w = perm_r0r1_32_63lo;\n        __m512i perm_rNrNp1_32_63hi_w = perm_r0r1_32_63hi;\n\n        if constexpr (partial_load) {\n          // Safe masked loads for the image edge\n          data_src = _mm512_maskz_loadu_epi8(k1, src_ptr);\n          data_src2 = _mm512_maskz_loadu_epi8(k2, src_ptr + 64);\n        }\n        else {\n          // Fast unaligned loads for the safe zone\n          data_src = _mm512_loadu_si512(src_ptr);\n          data_src2 = _mm512_loadu_si512(src_ptr + 64);\n        }\n\n        // rows 0..3\n        __m512i src_r0r1_0_31lo = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_0_31lo_w, data_src2);\n        __m512i src_r0r1_0_31hi = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_0_31hi_w, data_src2);\n\n        __m512i src_r0r1_32_63lo = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_32_63lo_w, data_src2);\n        __m512i src_r0r1_32_63hi = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_32_63hi_w, data_src2);\n\n        // for r2r3\n        perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);\n        perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);\n        perm_rNrNp1_32_63lo_w = _mm512_add_epi16(perm_rNrNp1_32_63lo_w, two_epi16);\n        perm_rNrNp1_32_63hi_w = _mm512_add_epi16(perm_rNrNp1_32_63hi_w, two_epi16);\n\n        __m512i src_r2r3_0_31lo = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_0_31lo_w, data_src2);\n        __m512i src_r2r3_0_31hi = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_0_31hi_w, data_src2);\n\n        __m512i src_r2r3_32_63lo = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_32_63lo_w, data_src2);\n        __m512i src_r2r3_32_63hi = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_32_63hi_w, data_src2);\n\n        // for r4r5\n        perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);\n        perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);\n        perm_rNrNp1_32_63lo_w = _mm512_add_epi16(perm_rNrNp1_32_63lo_w, two_epi16);\n        perm_rNrNp1_32_63hi_w = _mm512_add_epi16(perm_rNrNp1_32_63hi_w, two_epi16);\n\n        __m512i result_0_31lo, result_0_31hi;\n        __m512i result_32_63lo, result_32_63hi;\n\n        if constexpr (UseVNNI)\n        {\n          result_0_31lo = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31lo, coef_r0r1_0_31lo);\n          result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r2r3_0_31lo, coef_r2r3_0_31lo);\n\n          result_0_31hi = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31hi, coef_r0r1_0_31hi);\n          result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r2r3_0_31hi, coef_r2r3_0_31hi);\n\n          result_32_63lo = _mm512_dpwssd_epi32(rounder, src_r0r1_32_63lo, coef_r0r1_32_63lo);\n          result_32_63lo = _mm512_dpwssd_epi32(result_32_63lo, src_r2r3_32_63lo, coef_r2r3_32_63lo);\n\n          result_32_63hi = _mm512_dpwssd_epi32(rounder, src_r0r1_32_63hi, coef_r0r1_32_63hi);\n          result_32_63hi = _mm512_dpwssd_epi32(result_32_63hi, src_r2r3_32_63hi, coef_r2r3_32_63hi);\n        }\n        else\n        {\n          // making FMA in 32bits accs as in AVX256 V-resize\n          result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31lo, coef_r0r1_0_31lo), _mm512_madd_epi16(src_r2r3_0_31lo, coef_r2r3_0_31lo));\n          result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31hi, coef_r0r1_0_31hi), _mm512_madd_epi16(src_r2r3_0_31hi, coef_r2r3_0_31hi));\n\n          result_32_63lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_32_63lo, coef_r0r1_32_63lo), _mm512_madd_epi16(src_r2r3_32_63lo, coef_r2r3_32_63lo));\n          result_32_63hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_32_63hi, coef_r0r1_32_63hi), _mm512_madd_epi16(src_r2r3_32_63hi, coef_r2r3_32_63hi));\n        }\n\n        // rows 4..7\n        __m512i src_r4r5_0_31lo = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_0_31lo_w, data_src2);\n        __m512i src_r4r5_0_31hi = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_0_31hi_w, data_src2);\n\n        __m512i src_r4r5_32_63lo = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_32_63lo_w, data_src2);\n        __m512i src_r4r5_32_63hi = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_32_63hi_w, data_src2);\n\n        // for r6r7\n        perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);\n        perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);\n        perm_rNrNp1_32_63lo_w = _mm512_add_epi16(perm_rNrNp1_32_63lo_w, two_epi16);\n        perm_rNrNp1_32_63hi_w = _mm512_add_epi16(perm_rNrNp1_32_63hi_w, two_epi16);\n\n        __m512i src_r6r7_0_31lo = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_0_31lo_w, data_src2);\n        __m512i src_r6r7_0_31hi = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_0_31hi_w, data_src2);\n\n        __m512i src_r6r7_32_63lo = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_32_63lo_w, data_src2);\n        __m512i src_r6r7_32_63hi = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_32_63hi_w, data_src2);\n\n        if constexpr (UseVNNI)\n        {\n          result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r4r5_0_31lo, coef_r4r5_0_31lo);\n          result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r6r7_0_31lo, coef_r6r7_0_31lo);\n\n          result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r4r5_0_31hi, coef_r4r5_0_31hi);\n          result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r6r7_0_31hi, coef_r6r7_0_31hi);\n\n          result_32_63lo = _mm512_dpwssd_epi32(result_32_63lo, src_r4r5_32_63lo, coef_r4r5_32_63lo);\n          result_32_63lo = _mm512_dpwssd_epi32(result_32_63lo, src_r6r7_32_63lo, coef_r6r7_32_63lo);\n\n          result_32_63hi = _mm512_dpwssd_epi32(result_32_63hi, src_r4r5_32_63hi, coef_r4r5_32_63hi);\n          result_32_63hi = _mm512_dpwssd_epi32(result_32_63hi, src_r6r7_32_63hi, coef_r6r7_32_63hi);\n\n          // rounding VNNI in first FMA already summed\n        }\n        else\n        {\n          result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_0_31lo, coef_r4r5_0_31lo), result_0_31lo);\n          result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_0_31hi, coef_r4r5_0_31hi), result_0_31hi);\n\n          result_32_63lo = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_32_63lo, coef_r4r5_32_63lo), result_32_63lo);\n          result_32_63hi = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_32_63hi, coef_r4r5_32_63hi), result_32_63hi);\n\n          result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_0_31lo, coef_r6r7_0_31lo), result_0_31lo);\n          result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_0_31hi, coef_r6r7_0_31hi), result_0_31hi);\n\n          result_32_63lo = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_32_63lo, coef_r6r7_32_63lo), result_32_63lo);\n          result_32_63hi = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_32_63hi, coef_r6r7_32_63hi), result_32_63hi);\n\n          // rounding\n          result_0_31lo = _mm512_add_epi32(result_0_31lo, rounder);\n          result_0_31hi = _mm512_add_epi32(result_0_31hi, rounder);\n          result_32_63lo = _mm512_add_epi32(result_32_63lo, rounder);\n          result_32_63hi = _mm512_add_epi32(result_32_63hi, rounder);\n        }\n\n        // scaling down\n        result_0_31lo = _mm512_srai_epi32(result_0_31lo, FPScale8bits);\n        result_0_31hi = _mm512_srai_epi32(result_0_31hi, FPScale8bits);\n        result_32_63lo = _mm512_srai_epi32(result_32_63lo, FPScale8bits);\n        result_32_63hi = _mm512_srai_epi32(result_32_63hi, FPScale8bits);\n\n        __m512i result_0_31_int16 = _mm512_packus_epi32(result_0_31lo, result_0_31hi);\n        __m512i result_32_63_int16 = _mm512_packus_epi32(result_32_63lo, result_32_63hi);\n\n        __m256i result_0_31_u8 = _mm512_cvtusepi16_epi8(result_0_31_int16);\n        __m256i result_32_63_u8 = _mm512_cvtusepi16_epi8(result_32_63_int16);\n\n        // cast is enough, no need to use zeroextend\n        _mm512_stream_si512(reinterpret_cast<__m512i*>(dst_ptr),\n          _mm512_inserti64x4(_mm512_castsi256_si512(result_0_31_u8), result_32_63_u8, 1));\n\n        dst_ptr += dst_pitch;\n        src_ptr += src_pitch;\n      }\n\n      current_coeff += filter_size * PIXELS_AT_A_TIME;\n      };\n\n    // Process the 'safe zone' where direct full unaligned loads are acceptable.\n    for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)\n    {\n      do_h_integer_core(std::false_type{});\n    }\n\n    // Process the potentially 'unsafe zone' near the image edge, using safe masked loading.\n    for (; x < width; x += PIXELS_AT_A_TIME)\n    {\n      do_h_integer_core(std::true_type{});\n    }\n  }\n}\n\n// filter size up to 16\n// 32 target uint8_t pixels at a time\n// 128-byte source loads (128 uint8_t pixels)\n// maximum permute index is 128 for _mm512_maskz_permutex2var_epi8 (uint8_t)\ntemplate<bool UseVNNI>\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)\n{\n  const int filter_size = program->filter_size; // aligned, practically the coeff table stride\n\n  constexpr int PIXELS_AT_A_TIME = 32;\n\n  // 'source_overread_beyond_targetx' indicates if the filter kernel can read beyond the target width.\n  // we load 2x64 source bytes at a time, so ensure safe overread if needed.\n  // Our main loop processes calculates for 64 target pixels at a time.\n  // Inside that, we load 128 source bytes (2x64) to be able to permutex from that.\n  // This we have to check at each mod-PIXELS_AT_A_TIME boundary, the allowance of 128-byte source load.\n  const int width_safe_mod = (program->safelimit_128_pixels_each64th_target.overread_possible ? program->safelimit_128_pixels_each64th_target.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  // Preconditions:\n  assert(program->filter_size_real <= 16); // We preload all relevant coefficients (up to 16) before the height loop.\n\n  // 'target_size_alignment' ensures we can safely access coefficients using offsets like\n  // 'filter_size * 15' when processing 16 H pixels at a time\n  // 'filter_size * 31' when processing 32 H pixels at a time\n  assert(program->target_size_alignment >= 32); // Adjusted for 32 pixels (is it enough for uint8 ?)\n\n  assert(FRAME_ALIGN >= 32); // Good for 32x8 bit pixels\n\n  // Ensure that coefficient loading beyond the valid target size is safe \n  // We load 16x 'short' coeffs at a time\n  // We aligned_load from coeff positions, 32 bytes boundary needed, which is\n  // guaranteed by filter_size_alignment >=16\n  assert(program->filter_size_alignment >= 16);\n\n  const int max_scanlines = program->max_scanlines;\n\n  __m512i rounder = _mm512_set1_epi32(1 << (FPScale8bits - 1));\n\n  // Vertical stripe loop for L2 cache optimization\n  for (int y_from = 0; y_from < height; y_from += max_scanlines)\n  {\n    int y_to = std::min(y_from + max_scanlines, height);\n\n    // Reset current_coeff for the start of the stripe (points to start of row's coeffs)\n    const short* AVS_RESTRICT current_coeff = program->pixel_coefficient;\n\n    int x = 0;\n\n    // Lambda to handle both safe (fast) and unsafe (masked/partial) loading paths\n    auto do_h_integer_core = [&](auto partial_load) {\n\n      // prepare coefs in transposed V-form\n      // TODO: make storage in transposed form, 32 x uint8 transposition looks too slow\n\n      // 16coefs of 16bit is 256bits - load as pairs of _m256i\n      // hope 16-coeffs blocks are 32-bytes aligned for m256i aligned loads ?\n      __m512i coef_0_1 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 0), (__m256i*)(current_coeff + filter_size * 1));\n      __m512i coef_2_3 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 2), (__m256i*)(current_coeff + filter_size * 3));\n      __m512i coef_4_5 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 4), (__m256i*)(current_coeff + filter_size * 5));\n      __m512i coef_6_7 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 6), (__m256i*)(current_coeff + filter_size * 7));\n      __m512i coef_8_9 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 8), (__m256i*)(current_coeff + filter_size * 9));\n      __m512i coef_10_11 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 10), (__m256i*)(current_coeff + filter_size * 11));\n      __m512i coef_12_13 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 12), (__m256i*)(current_coeff + filter_size * 13));\n      __m512i coef_14_15 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 14), (__m256i*)(current_coeff + filter_size * 15));\n      __m512i coef_16_17 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 16), (__m256i*)(current_coeff + filter_size * 17));\n      __m512i coef_18_19 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 18), (__m256i*)(current_coeff + filter_size * 19));\n      __m512i coef_20_21 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 20), (__m256i*)(current_coeff + filter_size * 21));\n      __m512i coef_22_23 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 22), (__m256i*)(current_coeff + filter_size * 23));\n      __m512i coef_24_25 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 24), (__m256i*)(current_coeff + filter_size * 25));\n      __m512i coef_26_27 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 26), (__m256i*)(current_coeff + filter_size * 27));\n      __m512i coef_28_29 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 28), (__m256i*)(current_coeff + filter_size * 29));\n      __m512i coef_30_31 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 30), (__m256i*)(current_coeff + filter_size * 31));\n\n      // Transpose with permutex\n      __m512i c_perm_0_3 = _mm512_set_epi16(\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        16 + 32, 0 + 32, 16, 0);\n\n      __m512i c_perm_4_7 = _mm512_set_epi16(\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        16 + 32, 0 + 32, 16, 0,\n        0, 0, 0, 0);\n\n      __m512i c_perm_8_11 = _mm512_set_epi16(\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        16 + 32, 0 + 32, 16, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0);\n\n      __m512i c_perm_12_15 = _mm512_set_epi16(\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        16 + 32, 0 + 32, 16, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0);\n\n      __m512i c_perm_16_19 = _mm512_set_epi16(\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        16 + 32, 0 + 32, 16, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0);\n\n      __m512i c_perm_20_23 = _mm512_set_epi16(\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        16 + 32, 0 + 32, 16, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0);\n\n      __m512i c_perm_24_27 = _mm512_set_epi16(\n        0, 0, 0, 0,\n        16 + 32, 0 + 32, 16, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0);\n\n      __m512i c_perm_28_31 = _mm512_set_epi16(\n        16 + 32, 0 + 32, 16, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0);\n\n\n      __m512i one_epi16 = _mm512_set1_epi16(1);\n\n      // Define masks for the 4-word (8-byte, 4x 16-bit word) segments within the 32-word vector.\n      // Note: Each AVX-512 word (epi16) lane corresponds to one bit in the __mmask32.\n      // The masks target chunks of 4 words (k_X_Y represents bits X through Y inclusive).\n      const __mmask32 k_4_7 = 0x000000F0;\n      const __mmask32 k_8_11 = 0x00000F00;\n      const __mmask32 k_12_15 = 0x0000F000;\n      const __mmask32 k_16_19 = 0x000F0000;\n      const __mmask32 k_20_23 = 0x00F00000;\n      const __mmask32 k_24_27 = 0x0F000000;\n      const __mmask32 k_28_31 = 0xF0000000;\n\n      // Helper lambda to increment all eight permutation vectors by one.\n      auto inc_perms = [&](\n        __m512i& p0_3, __m512i& p4_7, __m512i& p8_11, __m512i& p12_15,\n        __m512i& p16_19, __m512i& p20_23, __m512i& p24_27, __m512i& p28_31\n        ) {\n          p0_3 = _mm512_add_epi16(p0_3, one_epi16);\n          p4_7 = _mm512_add_epi16(p4_7, one_epi16);\n          p8_11 = _mm512_add_epi16(p8_11, one_epi16);\n          p12_15 = _mm512_add_epi16(p12_15, one_epi16);\n          p16_19 = _mm512_add_epi16(p16_19, one_epi16);\n          p20_23 = _mm512_add_epi16(p20_23, one_epi16);\n          p24_27 = _mm512_add_epi16(p24_27, one_epi16);\n          p28_31 = _mm512_add_epi16(p28_31, one_epi16);\n        };\n\n      // Helper lambda to construct one full 32-word (512-bit) coefficient row.\n      // It uses mask blending to merge the results of _mm512_permutex2var_epi16\n      // for different 4-word segments, using the current permutation vectors.\n      auto make_coef_row = [&](\n        __m512i& row_result,\n        __m512i p0_3, __m512i p4_7, __m512i p8_11, __m512i p12_15,\n        __m512i p16_19, __m512i p20_23, __m512i p24_27, __m512i p28_31\n        ) {\n          // Start with the first segment (words 0-3) and the fourth segment (words 4-7).\n          row_result = _mm512_mask_blend_epi16(\n            k_4_7,\n            _mm512_permutex2var_epi16(coef_0_1, p0_3, coef_2_3),  // words 0-3 (unmasked)\n            _mm512_permutex2var_epi16(coef_4_5, p4_7, coef_6_7)   // words 4-7 (masked)\n          );\n\n          // Merge segment 8-11\n          row_result = _mm512_mask_blend_epi16(\n            k_8_11,\n            row_result,\n            _mm512_permutex2var_epi16(coef_8_9, p8_11, coef_10_11)\n          );\n\n          // Merge segment 12-15\n          row_result = _mm512_mask_blend_epi16(\n            k_12_15,\n            row_result,\n            _mm512_permutex2var_epi16(coef_12_13, p12_15, coef_14_15)\n          );\n\n          // Merge segment 16-19\n          row_result = _mm512_mask_blend_epi16(\n            k_16_19,\n            row_result,\n            _mm512_permutex2var_epi16(coef_16_17, p16_19, coef_18_19)\n          );\n\n          // Merge segment 20-23\n          row_result = _mm512_mask_blend_epi16(\n            k_20_23,\n            row_result,\n            _mm512_permutex2var_epi16(coef_20_21, p20_23, coef_22_23)\n          );\n\n          // Merge segment 24-27\n          row_result = _mm512_mask_blend_epi16(\n            k_24_27,\n            row_result,\n            _mm512_permutex2var_epi16(coef_24_25, p24_27, coef_26_27)\n          );\n\n          // Merge segment 28-31\n          row_result = _mm512_mask_blend_epi16(\n            k_28_31,\n            row_result,\n            _mm512_permutex2var_epi16(coef_28_29, p28_31, coef_30_31)\n          );\n        };\n\n      // Declare the coefficient row variables\n      __m512i coef_r0_0_31w, coef_r1_0_31w, coef_r2_0_31w, coef_r3_0_31w;\n      __m512i coef_r4_0_31w, coef_r5_0_31w, coef_r6_0_31w, coef_r7_0_31w;\n      __m512i coef_r8_0_31w, coef_r9_0_31w, coef_r10_0_31w, coef_r11_0_31w;\n      __m512i coef_r12_0_31w, coef_r13_0_31w, coef_r14_0_31w, coef_r15_0_31w;\n\n      // Process Row 0\n      make_coef_row(coef_r0_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 1\n      make_coef_row(coef_r1_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 2\n      make_coef_row(coef_r2_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 3\n      make_coef_row(coef_r3_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 4\n      make_coef_row(coef_r4_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 5\n      make_coef_row(coef_r5_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 6\n      make_coef_row(coef_r6_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 7\n      make_coef_row(coef_r7_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 8\n      make_coef_row(coef_r8_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 9\n      make_coef_row(coef_r9_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 10\n      make_coef_row(coef_r10_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 11\n      make_coef_row(coef_r11_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 12\n      make_coef_row(coef_r12_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 13\n      make_coef_row(coef_r13_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 14\n      make_coef_row(coef_r14_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 15\n      make_coef_row(coef_r15_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      // No inc_perms here\n\n      // convert-transpose to H-pairs for madd ? better to do with single permutex in future\n      // 16 to 16 512 registers - finally real working coeffs to store in the transposed resampling program for block of 64 target samples\n      __m512i coef_r0r1_0_31lo = _mm512_unpacklo_epi16(coef_r0_0_31w, coef_r1_0_31w);\n      __m512i coef_r0r1_0_31hi = _mm512_unpackhi_epi16(coef_r0_0_31w, coef_r1_0_31w);\n\n      __m512i coef_r2r3_0_31lo = _mm512_unpacklo_epi16(coef_r2_0_31w, coef_r3_0_31w);\n      __m512i coef_r2r3_0_31hi = _mm512_unpackhi_epi16(coef_r2_0_31w, coef_r3_0_31w);\n\n      __m512i coef_r4r5_0_31lo = _mm512_unpacklo_epi16(coef_r4_0_31w, coef_r5_0_31w);\n      __m512i coef_r4r5_0_31hi = _mm512_unpackhi_epi16(coef_r4_0_31w, coef_r5_0_31w);\n\n      __m512i coef_r6r7_0_31lo = _mm512_unpacklo_epi16(coef_r6_0_31w, coef_r7_0_31w);\n      __m512i coef_r6r7_0_31hi = _mm512_unpackhi_epi16(coef_r6_0_31w, coef_r7_0_31w);\n\n      __m512i coef_r8r9_0_31lo = _mm512_unpacklo_epi16(coef_r8_0_31w, coef_r9_0_31w);\n      __m512i coef_r8r9_0_31hi = _mm512_unpackhi_epi16(coef_r8_0_31w, coef_r9_0_31w);\n\n      __m512i coef_r10r11_0_31lo = _mm512_unpacklo_epi16(coef_r10_0_31w, coef_r11_0_31w);\n      __m512i coef_r10r11_0_31hi = _mm512_unpackhi_epi16(coef_r10_0_31w, coef_r11_0_31w);\n\n      __m512i coef_r12r13_0_31lo = _mm512_unpacklo_epi16(coef_r12_0_31w, coef_r13_0_31w);\n      __m512i coef_r12r13_0_31hi = _mm512_unpackhi_epi16(coef_r12_0_31w, coef_r13_0_31w);\n\n      __m512i coef_r14r15_0_31lo = _mm512_unpacklo_epi16(coef_r14_0_31w, coef_r15_0_31w);\n      __m512i coef_r14r15_0_31hi = _mm512_unpackhi_epi16(coef_r14_0_31w, coef_r15_0_31w);\n\n      // TODO: store transposed resampling program coeffs to temp buffer for reusage at each line\n\n      // convert resampling program in H-form into permuting indexes for src transposition in V-form\n      __m512i perm_0_0_15 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x])); // 16 offsets\n      __m512i perm_0_16_31 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 16])); //  16 offsets\n\n      int iStart = program->pixel_offset[x];\n      __m512i m512i_Start = _mm512_set1_epi32(iStart);\n\n      perm_0_0_15 = _mm512_sub_epi32(perm_0_0_15, m512i_Start);\n      perm_0_16_31 = _mm512_sub_epi32(perm_0_16_31, m512i_Start);\n\n      __m256i m256i_perm_0_0_15 = _mm512_cvtepi32_epi16(perm_0_0_15);\n      __m256i m256i_perm_0_16_31 = _mm512_cvtepi32_epi16(perm_0_16_31);\n\n      __m512i perm_0_0_31 = _mm512_inserti64x4(_mm512_zextsi256_si512(m256i_perm_0_0_15), m256i_perm_0_16_31, 1);\n\n      // no add_one to each perm group to save number of registers used in processing loop\n      // need only to first pair (r0 and r1)\n      __m512i perm_1_0_31 = _mm512_add_epi16(perm_0_0_31, one_epi16);\n\n      const __m512i perm_r0r1_0_31lo = _mm512_unpacklo_epi16(perm_0_0_31, perm_1_0_31);\n      const __m512i perm_r0r1_0_31hi = _mm512_unpackhi_epi16(perm_0_0_31, perm_1_0_31);\n\n      // Taps are contiguous (0, 1, 2, 3), so we increment perm indexes by 1 (in pairs by 2 each).\n      const __m512i two_epi16 = _mm512_set1_epi16(2);\n\n      uint8_t* AVS_RESTRICT dst_ptr = dst8 + x + y_from * dst_pitch;\n      const uint8_t* src_ptr = src8 + iStart + y_from * src_pitch; // all permute offsets relative to this start offset\n\n      // Calculate remaining pixels for bounds checking in partial_load mode. 1..128 remaining pixels possible.\n      const int remaining = program->source_size - iStart;\n      __mmask64 k1 = _bzhi_u64(~0ULL, remaining); // _bzhi_u64 creates a mask with the lower N bits set. If N >= 64, it returns all ones (~0ULL). \n      const __mmask64 k2 = _bzhi_u64(~0ULL, std::max(0, remaining - 64));\n\n      // mask is used to zero out every odd byte, so that the result of the permute is a\n      // vector of zero-extended 8-bit values in 16-bit lanes, preparing 8-bit data for 16-bit FMA operations in AVX512.\n      const __mmask64 k_zh8 = 0x5555555555555555ULL;\n\n      for (int y = y_from; y < y_to; y++)\n      {\n        __m512i data_src, data_src2;\n\n        // working permute indexes for advancing to save number of registers used\n        __m512i perm_rNrNp1_0_31lo_w = perm_r0r1_0_31lo;\n        __m512i perm_rNrNp1_0_31hi_w = perm_r0r1_0_31hi;\n\n        if constexpr (partial_load) {\n          // Safe masked loads for the image edge\n          data_src = _mm512_maskz_loadu_epi8(k1, src_ptr);\n          data_src2 = _mm512_maskz_loadu_epi8(k2, src_ptr + 64);\n        }\n        else {\n          // Fast unaligned loads for the safe zone\n          data_src = _mm512_loadu_si512(src_ptr);\n          data_src2 = _mm512_loadu_si512(src_ptr + 64);\n        }\n\n        // rows 0..3\n        __m512i src_r0r1_0_31lo = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_0_31lo_w, data_src2); // even index filled from permute, odd index zeroed\n        __m512i src_r0r1_0_31hi = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_0_31hi_w, data_src2);\n\n        // for r2r3\n        perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);\n        perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);\n\n        __m512i src_r2r3_0_31lo = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_0_31lo_w, data_src2);\n        __m512i src_r2r3_0_31hi = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_0_31hi_w, data_src2);\n\n        // for r4r5\n        perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);\n        perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);\n\n        __m512i result_0_31lo, result_0_31hi;\n\n        if constexpr (UseVNNI)\n        {\n          result_0_31lo = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31lo, coef_r0r1_0_31lo);\n          result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r2r3_0_31lo, coef_r2r3_0_31lo);\n          result_0_31hi = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31hi, coef_r0r1_0_31hi);\n          result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r2r3_0_31hi, coef_r2r3_0_31hi);\n        }\n        else\n        {\n          // making FMA in 32bits accs as in AVX256 V-resize\n          result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31lo, coef_r0r1_0_31lo), _mm512_madd_epi16(src_r2r3_0_31lo, coef_r2r3_0_31lo));\n          result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31hi, coef_r0r1_0_31hi), _mm512_madd_epi16(src_r2r3_0_31hi, coef_r2r3_0_31hi));\n        }\n\n        // rows 4..7\n        __m512i src_r4r5_0_31lo = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_0_31lo_w, data_src2);\n        __m512i src_r4r5_0_31hi = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_0_31hi_w, data_src2);\n\n        // for r6r7\n        perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);\n        perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);\n\n        __m512i src_r6r7_0_31lo = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_0_31lo_w, data_src2);\n        __m512i src_r6r7_0_31hi = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_0_31hi_w, data_src2);\n\n        // for r8r9\n        perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);\n        perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);\n\n        if constexpr (UseVNNI)\n        {\n          result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r4r5_0_31lo, coef_r4r5_0_31lo);\n          result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r6r7_0_31lo, coef_r6r7_0_31lo);\n          result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r4r5_0_31hi, coef_r4r5_0_31hi);\n          result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r6r7_0_31hi, coef_r6r7_0_31hi);\n        }\n        else\n        {\n          result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_0_31lo, coef_r4r5_0_31lo), result_0_31lo);\n          result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_0_31hi, coef_r4r5_0_31hi), result_0_31hi);\n          result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_0_31lo, coef_r6r7_0_31lo), result_0_31lo);\n          result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_0_31hi, coef_r6r7_0_31hi), result_0_31hi);\n        }\n\n        // rows 8..11\n        __m512i src_r8r9_0_31lo = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_0_31lo_w, data_src2);\n        __m512i src_r8r9_0_31hi = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_0_31hi_w, data_src2);\n\n        // for r10r11\n        perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);\n        perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);\n\n        __m512i src_r10r11_0_31lo = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_0_31lo_w, data_src2);\n        __m512i src_r10r11_0_31hi = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_0_31hi_w, data_src2);\n\n        // for r12r13\n        perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);\n        perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);\n\n        if constexpr (UseVNNI)\n        {\n          result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r8r9_0_31lo, coef_r8r9_0_31lo);\n          result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r10r11_0_31lo, coef_r10r11_0_31lo);\n          result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r8r9_0_31hi, coef_r8r9_0_31hi);\n          result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r10r11_0_31hi, coef_r10r11_0_31hi);\n        }\n        else\n        {\n          result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r8r9_0_31lo, coef_r8r9_0_31lo), result_0_31lo);\n          result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r8r9_0_31hi, coef_r8r9_0_31hi), result_0_31hi);\n          result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r10r11_0_31lo, coef_r10r11_0_31lo), result_0_31lo);\n          result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r10r11_0_31hi, coef_r10r11_0_31hi), result_0_31hi);\n        }\n\n        // rows 12..15\n        __m512i src_r12r13_0_31lo = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_0_31lo_w, data_src2);\n        __m512i src_r12r13_0_31hi = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_0_31hi_w, data_src2);\n\n        // for r14r15\n        perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);\n        perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);\n\n        __m512i src_r14r15_0_31lo = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_0_31lo_w, data_src2);\n        __m512i src_r14r15_0_31hi = _mm512_maskz_permutex2var_epi8_SIMUL<UseVNNI>(k_zh8, data_src, perm_rNrNp1_0_31hi_w, data_src2);\n\n        if constexpr (UseVNNI)\n        {\n          result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r12r13_0_31lo, coef_r12r13_0_31lo);\n          result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r14r15_0_31lo, coef_r14r15_0_31lo);\n          result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r12r13_0_31hi, coef_r12r13_0_31hi);\n          result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r14r15_0_31hi, coef_r14r15_0_31hi);\n\n          // rounding in first FMA\n        }\n        else\n        {\n          result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r12r13_0_31lo, coef_r12r13_0_31lo), result_0_31lo);\n          result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r12r13_0_31hi, coef_r12r13_0_31hi), result_0_31hi);\n          result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r14r15_0_31lo, coef_r14r15_0_31lo), result_0_31lo);\n          result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r14r15_0_31hi, coef_r14r15_0_31hi), result_0_31hi);\n\n          // rounding\n          result_0_31lo = _mm512_add_epi32(result_0_31lo, rounder);\n          result_0_31hi = _mm512_add_epi32(result_0_31hi, rounder);\n        }\n\n        // scaling down\n        result_0_31lo = _mm512_srai_epi32(result_0_31lo, FPScale8bits);\n        result_0_31hi = _mm512_srai_epi32(result_0_31hi, FPScale8bits);\n\n        __m512i result_0_31_int16 = _mm512_packus_epi32(result_0_31lo, result_0_31hi);\n\n        __m256i result_0_31_u8 = _mm512_cvtusepi16_epi8(result_0_31_int16);\n\n        _mm256_stream_si256(reinterpret_cast<__m256i*>(dst_ptr), result_0_31_u8);\n\n        dst_ptr += dst_pitch;\n        src_ptr += src_pitch;\n      }\n\n      current_coeff += filter_size * PIXELS_AT_A_TIME;\n      };\n\n    // Process the 'safe zone' where direct full unaligned loads are acceptable.\n    for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)\n    {\n      do_h_integer_core(std::false_type{});\n    }\n\n    // Process the potentially 'unsafe zone' near the image edge, using safe masked loading.\n    for (; x < width; x += PIXELS_AT_A_TIME)\n    {\n      do_h_integer_core(std::true_type{});\n    }\n  }\n}\n\n\n// uint16_t\n\n// filter size up to 4\n// 32 target uint16_t pixels at a time\n// 128-byte source loads (64 uint16_t pixels)\n// maximum permute index is 64 for _mm512_permutex2var_epi16 (uint16_t)\n// making lo-hi unpacking with single permutex2var operation and optional VNNI FMA\ntemplate<bool lessthan16bit, bool UseVNNI>\nvoid resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks4_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)\n{\n  const int filter_size = program->filter_size; // aligned, practically the coeff table stride\n\n  const uint16_t* src = (uint16_t*)src8;\n  uint16_t* AVS_RESTRICT dst = (uint16_t * AVS_RESTRICT)dst8;\n  dst_pitch = dst_pitch / sizeof(uint16_t);\n  src_pitch = src_pitch / sizeof(uint16_t);\n\n  constexpr int PIXELS_AT_A_TIME = 32;\n\n  // 'source_overread_beyond_targetx' indicates if the filter kernel can read beyond the target width.\n  // we load 2x32 source uint16_t pixels at a time, so ensure safe overread if needed.\n  // Our main loop processes calculates for 32 target pixels at a time.\n  // Inside that, we load 64 source uint16_t pixels (2x32) to be able to permutex from that.\n  // This we have to check at each mod-PIXELS_AT_A_TIME boundary, the allowance of 64-element source load.\n  const int width_safe_mod = (program->safelimit_64_pixels_each32th_target.overread_possible ? program->safelimit_64_pixels_each32th_target.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  // Preconditions:\n  assert(program->filter_size_real <= 4); // We preload all relevant coefficients (up to 4) before the height loop.\n\n  // 'target_size_alignment' ensures we can safely access coefficients using offsets like\n  // 'filter_size * 31' when processing 32 source H pixels at a time\n  assert(program->target_size_alignment >= 32); // source-offset starts for 32 target pixels, 32 coeff strides\n  assert(FRAME_ALIGN >= 64); // storing 32x2 uint16_t at a time\n\n  // Ensure that coefficient loading beyond the valid target size is safe for 4 coeffs\n  // We load 4x16bit coeffs at a time\n  assert(program->filter_size_alignment >= 4);\n\n  const int max_scanlines = program->max_scanlines;\n\n  // for 16 bits only\n  const __m512i shifttosigned = _mm512_set1_epi16(-32768);\n  const __m512i shiftfromsigned = _mm512_set1_epi32(32768 << FPScale16bits);\n\n  const int limit = (1 << bits_per_pixel) - 1;\n  // only used when template lessthan16bit is true\n  __m512i clamp_limit = _mm512_set1_epi16((short)limit); // clamp limit for <16 bits\n\n  __m512i rounder = _mm512_set1_epi32(1 << (FPScale16bits - 1));\n\n  // Vertical stripe loop for L2 cache optimization\n  for (int y_from = 0; y_from < height; y_from += max_scanlines)\n  {\n    int y_to = std::min(y_from + max_scanlines, height);\n\n    // Reset current_coeff for the start of the stripe (points to start of row's coeffs)\n    const short* AVS_RESTRICT current_coeff = program->pixel_coefficient;\n\n    int x = 0;\n\n    // Lambda to handle both safe (fast) and unsafe (masked/partial) loading paths\n    auto do_h_integer_core = [&](auto partial_load) {\n\n      // prepare coefs in transposed V-form\n      // 32 source pixels, 32 coeff strides\n      // TODO: make storage in transposed form, 64 x uint16 transposition looks too slow\n      // TO FIX: filter_size=4 resize uses filter_size=16 - lots or RAM/cache wasted, in the ready to use transposed form it will be much more optimized\n\n      // 4coefs of 16bit is 64bits, can be loaded as set_epi64 ?\n      __m512i coef_0_7 = _mm512_setr_epi64(\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 0),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 1),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 2),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 3),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 4),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 5),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 6),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 7)\n      );\n\n      __m512i coef_8_15 = _mm512_setr_epi64(\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 8),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 9),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 10),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 11),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 12),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 13),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 14),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 15)\n      );\n\n      __m512i coef_16_23 = _mm512_setr_epi64(\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 16),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 17),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 18),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 19),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 20),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 21),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 22),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 23)\n      );\n\n      __m512i coef_24_31 = _mm512_setr_epi64(\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 24),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 25),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 26),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 27),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 28),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 29),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 30),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 31)\n      );\n\n      // Transpose with permutex\n      __m512i c_perm_0 = _mm512_set_epi16(\n        28 + 32, 24 + 32, 20 + 32, 16 + 32, 12 + 32, 8 + 32, 4 + 32, 0 + 32, 28, 24, 20, 16, 12, 8, 4, 0,\n        28 + 32, 24 + 32, 20 + 32, 16 + 32, 12 + 32, 8 + 32, 4 + 32, 0 + 32, 28, 24, 20, 16, 12, 8, 4, 0);\n      __m512i one_epi16 = _mm512_set1_epi16(1);\n\n      const __mmask32 k_high = 0xFFFF0000;\n\n      // 0.0 .. 15.0 in low 256, 16.0 .. 31.0 in high 256\n      __m512i coef_r0_0_31w = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(coef_0_7, c_perm_0, coef_8_15), _mm512_permutex2var_epi16(coef_16_23, c_perm_0, coef_24_31));\n      c_perm_0 = _mm512_add_epi16(c_perm_0, one_epi16);\n      __m512i coef_r1_0_31w = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(coef_0_7, c_perm_0, coef_8_15), _mm512_permutex2var_epi16(coef_16_23, c_perm_0, coef_24_31));\n      c_perm_0 = _mm512_add_epi16(c_perm_0, one_epi16);\n      __m512i coef_r2_0_31w = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(coef_0_7, c_perm_0, coef_8_15), _mm512_permutex2var_epi16(coef_16_23, c_perm_0, coef_24_31));\n      c_perm_0 = _mm512_add_epi16(c_perm_0, one_epi16);\n      __m512i coef_r3_0_31w = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(coef_0_7, c_perm_0, coef_8_15), _mm512_permutex2var_epi16(coef_16_23, c_perm_0, coef_24_31));\n\n      // convert-transpose to H-pairs for madd ? better to do with single permutex in future\n      // 4 to 4 512 registers - finally real working coeffs to store in the transposed resampling program for block of 64 target samples\n      __m512i coef_r0r1_0_31lo = _mm512_unpacklo_epi16(coef_r0_0_31w, coef_r1_0_31w);\n      __m512i coef_r0r1_0_31hi = _mm512_unpackhi_epi16(coef_r0_0_31w, coef_r1_0_31w);\n\n      __m512i coef_r2r3_0_31lo = _mm512_unpacklo_epi16(coef_r2_0_31w, coef_r3_0_31w);\n      __m512i coef_r2r3_0_31hi = _mm512_unpackhi_epi16(coef_r2_0_31w, coef_r3_0_31w);\n\n      // TODO: store transposed resampling program coeffs to temp buffer for reusage at each line\n\n      // convert resampling program in H-form into permuting indexes for src transposition in V-form\n      __m512i perm_0_0_15 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x])); // 16 offsets\n      __m512i perm_0_16_31 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 16])); //  16 offsets\n\n      int iStart = program->pixel_offset[x];\n      __m512i m512i_Start = _mm512_set1_epi32(iStart);\n\n      perm_0_0_15 = _mm512_sub_epi32(perm_0_0_15, m512i_Start);\n      perm_0_16_31 = _mm512_sub_epi32(perm_0_16_31, m512i_Start);\n\n      __m256i m256i_perm_0_0_15 = _mm512_cvtepi32_epi16(perm_0_0_15);\n      __m256i m256i_perm_0_16_31 = _mm512_cvtepi32_epi16(perm_0_16_31);\n\n      // Insert each 256-bit register into the specific lane\n      __m512i perm_0 = _mm512_inserti64x4(_mm512_zextsi256_si512(m256i_perm_0_0_15), m256i_perm_0_16_31, 1);\n\n      // Taps are contiguous (0, 1, 2, 3), so we increment perm indexes by 1.\n      __m512i perm_1 = _mm512_add_epi16(perm_0, one_epi16);\n      __m512i perm_2 = _mm512_add_epi16(perm_1, one_epi16);\n      __m512i perm_3 = _mm512_add_epi16(perm_2, one_epi16);\n\n      const __m512i perm_r0r1_0_31lo = _mm512_unpacklo_epi16(perm_0, perm_1);\n      const __m512i perm_r0r1_0_31hi = _mm512_unpackhi_epi16(perm_0, perm_1);\n\n      const __m512i perm_r2r3_0_31lo = _mm512_unpacklo_epi16(perm_2, perm_3);\n      const __m512i perm_r2r3_0_31hi = _mm512_unpackhi_epi16(perm_2, perm_3);\n\n      uint16_t* AVS_RESTRICT dst_ptr = dst + x + y_from * dst_pitch;\n      const uint16_t* src_ptr = src + iStart + y_from * src_pitch; // all permute offsets relative to this start offset\n\n      // Calculate remaining pixels for bounds checking in partial_load mode. 1..64 remaining uint16_t pixels possible.\n      // only when partial_load\n      const int remaining = program->source_size - iStart;\n      // two masks for partial loads of 32 + 32 shorts\n      const __mmask32 k1 = _bzhi_u32(~0UL, remaining);\n      const __mmask32 k2 = _bzhi_u32(~0UL, remaining - 32);\n\n      for (int y = y_from; y < y_to; y++)\n      {\n        __m512i data_src, data_src2;\n\n        if constexpr (partial_load) {\n          // Safe masked loads for the image edge 2x32 shorts\n          data_src = _mm512_maskz_loadu_epi16(k1, src_ptr);\n          data_src2 = _mm512_maskz_loadu_epi16(k2, src_ptr + 32);\n        }\n        else {\n          // Fast unaligned loads for the safe zone\n          data_src = _mm512_loadu_si512(src_ptr);\n          data_src2 = _mm512_loadu_si512(src_ptr + 32);\n        }\n\n        __m512i src_r0r1_0_31lo = _mm512_permutex2var_epi16(data_src, perm_r0r1_0_31lo, data_src2);\n        __m512i src_r0r1_0_31hi = _mm512_permutex2var_epi16(data_src, perm_r0r1_0_31hi, data_src2);\n\n        __m512i src_r2r3_0_31lo = _mm512_permutex2var_epi16(data_src, perm_r2r3_0_31lo, data_src2);\n        __m512i src_r2r3_0_31hi = _mm512_permutex2var_epi16(data_src, perm_r2r3_0_31hi, data_src2);\n\n        if constexpr (!lessthan16bit) {\n          // madd requires signed integers, so shift to signed range\n          src_r0r1_0_31lo = _mm512_add_epi16(src_r0r1_0_31lo, shifttosigned);\n          src_r0r1_0_31hi = _mm512_add_epi16(src_r0r1_0_31hi, shifttosigned);\n          src_r2r3_0_31lo = _mm512_add_epi16(src_r2r3_0_31lo, shifttosigned);\n          src_r2r3_0_31hi = _mm512_add_epi16(src_r2r3_0_31hi, shifttosigned);\n        }\n\n        __m512i result_0_31lo, result_0_31hi;\n\n        if constexpr (UseVNNI)\n        {\n          result_0_31lo = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31lo, coef_r0r1_0_31lo);\n          result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r2r3_0_31lo, coef_r2r3_0_31lo);\n\n          result_0_31hi = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31hi, coef_r0r1_0_31hi);\n          result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r2r3_0_31hi, coef_r2r3_0_31hi);\n        }\n        else\n        {\n          // making FMA in 32bits accs as in AVX256 V-resize\n          result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31lo, coef_r0r1_0_31lo), _mm512_madd_epi16(src_r2r3_0_31lo, coef_r2r3_0_31lo));\n          result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31hi, coef_r0r1_0_31hi), _mm512_madd_epi16(src_r2r3_0_31hi, coef_r2r3_0_31hi));\n\n          // rounding\n          result_0_31lo = _mm512_add_epi32(result_0_31lo, rounder);\n          result_0_31hi = _mm512_add_epi32(result_0_31hi, rounder);\n        }\n\n        if constexpr (!lessthan16bit) {\n          // return from signed range\n          result_0_31lo = _mm512_add_epi32(result_0_31lo, shiftfromsigned);\n          result_0_31hi = _mm512_add_epi32(result_0_31hi, shiftfromsigned);\n        }\n\n        // scale down\n        result_0_31lo = _mm512_srai_epi32(result_0_31lo, FPScale16bits);\n        result_0_31hi = _mm512_srai_epi32(result_0_31hi, FPScale16bits);\n\n        // negative and over 16 bit values are clamped automatically\n        __m512i result_0_31_int16 = _mm512_packus_epi32(result_0_31lo, result_0_31hi);\n\n        if constexpr (lessthan16bit) {\n          result_0_31_int16 = _mm512_min_epu16(result_0_31_int16, clamp_limit); // extra clamp for 10-14 bit\n        }\n\n        _mm512_stream_si512(reinterpret_cast<__m512i*>(dst_ptr), result_0_31_int16);\n\n        dst_ptr += dst_pitch;\n        src_ptr += src_pitch;\n      }\n\n      current_coeff += filter_size * PIXELS_AT_A_TIME;\n      };\n\n    // Process the 'safe zone' where direct full unaligned loads are acceptable.\n    for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)\n    {\n      do_h_integer_core(std::false_type{});\n    }\n\n    // Process the potentially 'unsafe zone' near the image edge, using safe masked loading.\n    for (; x < width; x += PIXELS_AT_A_TIME)\n    {\n      do_h_integer_core(std::true_type{});\n    }\n  }\n}\n\n// filter size up to 8\n// 32 target uint16_t pixels at a time\n// 128-byte source loads (64 uint16_t pixels)\n// maximum permute index is 64 for _mm512_permutex2var_epi16 (uint16_t)\n// support VNNI and madd FMA\ntemplate<bool lessthan16bit, bool UseVNNI>\nvoid resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks8_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)\n{\n  const int filter_size = program->filter_size; // aligned, practically the coeff table stride\n\n  const uint16_t* src = (uint16_t*)src8;\n  uint16_t* AVS_RESTRICT dst = (uint16_t * AVS_RESTRICT)dst8;\n  dst_pitch = dst_pitch / sizeof(uint16_t);\n  src_pitch = src_pitch / sizeof(uint16_t);\n\n  constexpr int PIXELS_AT_A_TIME = 32;\n\n  // 'source_overread_beyond_targetx' indicates if the filter kernel can read beyond the target width.\n  // we load 2x32 source bytes at a time, so ensure safe overread if needed.\n  // Our main loop processes calculates for 64 target pixels at a time.\n  // Inside that, we load 128 source bytes (2x64) to be able to permutex from that.\n  // This we have to check at each mod-PIXELS_AT_A_TIME boundary, the allowance of 128-byte source load.\n  const int width_safe_mod = (program->safelimit_64_pixels_each32th_target.overread_possible ? program->safelimit_64_pixels_each32th_target.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  // Preconditions:\n  assert(program->filter_size_real <= 8); // We preload all relevant coefficients (up to 8) before the height loop.\n\n  // 'target_size_alignment' ensures we can safely access coefficients using offsets like\n  // 'filter_size * 15' when processing 16 H pixels at a time\n  // 'filter_size * 63' when processing 64 H pixels at a time\n  assert(program->target_size_alignment >= 32); // Adjusted for 32 pixels (is it enough for uint16 ?)\n\n  assert(FRAME_ALIGN >= 64); // Good for 32x16 bit pixels\n\n  // Ensure that coefficient loading beyond the valid target size is safe for 4x8 float loads.\n  // We load 8x 'short' coeffs at a time\n  // Loading is unaligned, but we fill __m128 registers before combining into __m512\n  assert(program->filter_size_alignment >= 8);\n\n  const int max_scanlines = program->max_scanlines;\n\n  // for 16 bits only\n  const __m512i shifttosigned = _mm512_set1_epi16(-32768);\n  const __m512i shiftfromsigned = _mm512_set1_epi32(32768 << FPScale16bits);\n\n  const int limit = (1 << bits_per_pixel) - 1;\n  // only used when template lessthan16bit is true\n  __m512i clamp_limit = _mm512_set1_epi16((short)limit); // clamp limit for <16 bits\n\n  __m512i rounder = _mm512_set1_epi32(1 << (FPScale16bits - 1));\n\n  // Vertical stripe loop for L2 cache optimization\n  for (int y_from = 0; y_from < height; y_from += max_scanlines)\n  {\n    int y_to = std::min(y_from + max_scanlines, height);\n\n    // Reset current_coeff for the start of the stripe (points to start of row's coeffs)\n    const short* AVS_RESTRICT current_coeff = program->pixel_coefficient;\n\n    int x = 0;\n\n    // Lambda to handle both safe (fast) and unsafe (masked/partial) loading paths\n    auto do_h_integer_core = [&](auto partial_load) {\n\n      // prepare coefs in transposed V-form\n      // TODO: make storage in transposed form, 64 x uint16 transposition looks too slow\n\n      // 8coefs of 16bit is 128bits \n      __m512i coef_0_3 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 0), (__m128i*)(current_coeff + filter_size * 1), (__m128i*)(current_coeff + filter_size * 2), (__m128i*)(current_coeff + filter_size * 3));\n      __m512i coef_4_7 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 4), (__m128i*)(current_coeff + filter_size * 5), (__m128i*)(current_coeff + filter_size * 6), (__m128i*)(current_coeff + filter_size * 7));\n      __m512i coef_8_11 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 8), (__m128i*)(current_coeff + filter_size * 9), (__m128i*)(current_coeff + filter_size * 10), (__m128i*)(current_coeff + filter_size * 11));\n      __m512i coef_12_15 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 12), (__m128i*)(current_coeff + filter_size * 13), (__m128i*)(current_coeff + filter_size * 14), (__m128i*)(current_coeff + filter_size * 15));\n      __m512i coef_16_19 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 16), (__m128i*)(current_coeff + filter_size * 17), (__m128i*)(current_coeff + filter_size * 18), (__m128i*)(current_coeff + filter_size * 19));\n      __m512i coef_20_23 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 20), (__m128i*)(current_coeff + filter_size * 21), (__m128i*)(current_coeff + filter_size * 22), (__m128i*)(current_coeff + filter_size * 23));\n      __m512i coef_24_27 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 24), (__m128i*)(current_coeff + filter_size * 25), (__m128i*)(current_coeff + filter_size * 26), (__m128i*)(current_coeff + filter_size * 27));\n      __m512i coef_28_31 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 28), (__m128i*)(current_coeff + filter_size * 29), (__m128i*)(current_coeff + filter_size * 30), (__m128i*)(current_coeff + filter_size * 31));\n\n      // Transpose with permutex\n      __m512i c_perm_0_7 = _mm512_set_epi16(\n        0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0,\n        24 + 32, 16 + 32, 8 + 32, 0 + 32, 24, 16, 8, 0);\n      __m512i c_perm_8_15 = _mm512_set_epi16(\n        0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0,\n        24 + 32, 16 + 32, 8 + 32, 0 + 32, 24, 16, 8, 0,\n        0, 0, 0, 0, 0, 0, 0, 0);\n      __m512i c_perm_16_23 = _mm512_set_epi16(\n        0, 0, 0, 0, 0, 0, 0, 0,\n        24 + 32, 16 + 32, 8 + 32, 0 + 32, 24, 16, 8, 0,\n        0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0);\n      __m512i c_perm_24_31 = _mm512_set_epi16(\n        24 + 32, 16 + 32, 8 + 32, 0 + 32, 24, 16, 8, 0,\n        0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0);\n\n      __m512i one_epi16 = _mm512_set1_epi16(1);\n      const __mmask32 k_8_15 = 0x0000FF00;\n      const __mmask32 k_16_23 = 0x00FF0000;\n      const __mmask32 k_24_31 = 0xFF000000;\n\n      auto inc_perms = [&](\n        __m512i& c0_7,\n        __m512i& c8_15,\n        __m512i& c16_23,\n        __m512i& c24_31\n        ) {\n          c0_7 = _mm512_add_epi16(c0_7, one_epi16);\n          c8_15 = _mm512_add_epi16(c8_15, one_epi16);\n          c16_23 = _mm512_add_epi16(c16_23, one_epi16);\n          c24_31 = _mm512_add_epi16(c24_31, one_epi16);\n        };\n\n      auto make_row_0_31 = [&](\n        __m512i& row_0_31w,\n        __m512i c0_7, __m512i c8_15, __m512i c16_23, __m512i c24_31\n        ) {\n          // 0..31\n          row_0_31w = _mm512_mask_blend_epi16(\n            k_8_15,\n            _mm512_permutex2var_epi16(coef_0_3, c0_7, coef_4_7),\n            _mm512_permutex2var_epi16(coef_8_11, c8_15, coef_12_15)\n          );\n          row_0_31w = _mm512_mask_blend_epi16(\n            k_16_23,\n            row_0_31w,\n            _mm512_permutex2var_epi16(coef_16_19, c16_23, coef_20_23)\n          );\n          row_0_31w = _mm512_mask_blend_epi16(\n            k_24_31,\n            row_0_31w,\n            _mm512_permutex2var_epi16(coef_24_27, c24_31, coef_28_31)\n          );\n        };\n\n      __m512i coef_r0_0_31w;\n      __m512i coef_r1_0_31w;\n      __m512i coef_r2_0_31w;\n      __m512i coef_r3_0_31w;\n      __m512i coef_r4_0_31w;\n      __m512i coef_r5_0_31w;\n      __m512i coef_r6_0_31w;\n      __m512i coef_r7_0_31w;\n\n      // r0\n      make_row_0_31(coef_r0_0_31w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r1\n      make_row_0_31(coef_r1_0_31w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r2\n      make_row_0_31(coef_r2_0_31w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r3\n      make_row_0_31(coef_r3_0_31w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r4\n      make_row_0_31(coef_r4_0_31w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r5\n      make_row_0_31(coef_r5_0_31w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r6\n      make_row_0_31(coef_r6_0_31w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      inc_perms(c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n      // r7\n      make_row_0_31(coef_r7_0_31w, c_perm_0_7, c_perm_8_15, c_perm_16_23, c_perm_24_31);\n\n      // convert-transpose to H-pairs for madd ? better to do with single permutex in future\n      // 8 to 8 512 registers - finally real working coeffs to store in the transposed resampling program for block of 64 target samples\n      __m512i coef_r0r1_0_31lo = _mm512_unpacklo_epi16(coef_r0_0_31w, coef_r1_0_31w);\n      __m512i coef_r0r1_0_31hi = _mm512_unpackhi_epi16(coef_r0_0_31w, coef_r1_0_31w);\n\n      __m512i coef_r2r3_0_31lo = _mm512_unpacklo_epi16(coef_r2_0_31w, coef_r3_0_31w);\n      __m512i coef_r2r3_0_31hi = _mm512_unpackhi_epi16(coef_r2_0_31w, coef_r3_0_31w);\n\n      __m512i coef_r4r5_0_31lo = _mm512_unpacklo_epi16(coef_r4_0_31w, coef_r5_0_31w);\n      __m512i coef_r4r5_0_31hi = _mm512_unpackhi_epi16(coef_r4_0_31w, coef_r5_0_31w);\n\n      __m512i coef_r6r7_0_31lo = _mm512_unpacklo_epi16(coef_r6_0_31w, coef_r7_0_31w);\n      __m512i coef_r6r7_0_31hi = _mm512_unpackhi_epi16(coef_r6_0_31w, coef_r7_0_31w);\n\n      // TODO: store transposed resampling program coeffs to temp buffer for reusage at each line\n\n      // convert resampling program in H-form into permuting indexes for src transposition in V-form\n      __m512i perm_0_0_15 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x])); // 16 offsets\n      __m512i perm_0_16_31 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 16])); //  16 offsets\n\n      int iStart = program->pixel_offset[x];\n      __m512i m512i_Start = _mm512_set1_epi32(iStart);\n\n      perm_0_0_15 = _mm512_sub_epi32(perm_0_0_15, m512i_Start);\n      perm_0_16_31 = _mm512_sub_epi32(perm_0_16_31, m512i_Start);\n\n      __m256i m256i_perm_0_0_15 = _mm512_cvtepi32_epi16(perm_0_0_15);\n      __m256i m256i_perm_0_16_31 = _mm512_cvtepi32_epi16(perm_0_16_31);\n\n      // Insert each 256-bit register into the specific lane\n      __m512i perm_0_0_31 = _mm512_inserti64x4(_mm512_zextsi256_si512(m256i_perm_0_0_15), m256i_perm_0_16_31, 1);\n\n      // no add_one to each perm group to save number of registers used in processing loop\n      // need only to first pair (r0 and r1)\n      __m512i perm_1_0_31 = _mm512_add_epi16(perm_0_0_31, one_epi16);\n\n      const __m512i perm_r0r1_0_31lo = _mm512_unpacklo_epi16(perm_0_0_31, perm_1_0_31);\n      const __m512i perm_r0r1_0_31hi = _mm512_unpackhi_epi16(perm_0_0_31, perm_1_0_31);\n\n      // Taps are contiguous (0, 1, 2, 3), so we increment perm indexes by 1 (in pairs by 2 each).\n      const __m512i two_epi16 = _mm512_set1_epi16(2);\n\n      uint16_t* AVS_RESTRICT dst_ptr = dst + x + y_from * dst_pitch;\n      const uint16_t* src_ptr = src + iStart + y_from * src_pitch; // all permute offsets relative to this start offset\n\n      // Calculate remaining pixels for bounds checking in partial_load mode. 1..64 remaining uint16_t pixels possible.\n      // only when partial_load\n      const int remaining = program->source_size - iStart;\n      // two masks for partial loads of 32 + 32 shorts\n      const __mmask32 k1 = _bzhi_u32(~0UL, remaining);\n      const __mmask32 k2 = _bzhi_u32(~0UL, remaining - 32);\n\n      for (int y = y_from; y < y_to; y++)\n      {\n        __m512i data_src, data_src2;\n\n        // working permute indexes for advancing to save number of registers used\n        __m512i perm_rNrNp1_0_31lo_w = perm_r0r1_0_31lo;\n        __m512i perm_rNrNp1_0_31hi_w = perm_r0r1_0_31hi;\n\n        if constexpr (partial_load) {\n          // Safe masked loads for the image edge\n          data_src = _mm512_maskz_loadu_epi16(k1, src_ptr);\n          data_src2 = _mm512_maskz_loadu_epi16(k2, src_ptr + 32);\n        }\n        else {\n          // Fast unaligned loads for the safe zone\n          data_src = _mm512_loadu_si512(src_ptr);\n          data_src2 = _mm512_loadu_si512(src_ptr + 32);\n        }\n\n        // rows 0..3\n        __m512i src_r0r1_0_31lo = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31lo_w, data_src2);\n        __m512i src_r0r1_0_31hi = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31hi_w, data_src2);\n\n        // for r2r3\n        perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);\n        perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);\n\n        __m512i src_r2r3_0_31lo = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31lo_w, data_src2);\n        __m512i src_r2r3_0_31hi = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31hi_w, data_src2);\n\n        // for r4r5\n        perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);\n        perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);\n\n        __m512i result_0_31lo, result_0_31hi;\n\n        if constexpr (!lessthan16bit) {\n          // madd requires signed integers, so shift to signed range\n          src_r0r1_0_31lo = _mm512_add_epi16(src_r0r1_0_31lo, shifttosigned);\n          src_r0r1_0_31hi = _mm512_add_epi16(src_r0r1_0_31hi, shifttosigned);\n          src_r2r3_0_31lo = _mm512_add_epi16(src_r2r3_0_31lo, shifttosigned);\n          src_r2r3_0_31hi = _mm512_add_epi16(src_r2r3_0_31hi, shifttosigned);\n        }\n\n        if constexpr (UseVNNI)\n        {\n          result_0_31lo = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31lo, coef_r0r1_0_31lo);\n          result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r2r3_0_31lo, coef_r2r3_0_31lo);\n\n          result_0_31hi = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31hi, coef_r0r1_0_31hi);\n          result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r2r3_0_31hi, coef_r2r3_0_31hi);\n        }\n        else\n        {\n          // making FMA in 32bits accs as in AVX256 V-resize\n          result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31lo, coef_r0r1_0_31lo), _mm512_madd_epi16(src_r2r3_0_31lo, coef_r2r3_0_31lo));\n          result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31hi, coef_r0r1_0_31hi), _mm512_madd_epi16(src_r2r3_0_31hi, coef_r2r3_0_31hi));\n        }\n\n        // rows 4..7\n        __m512i src_r4r5_0_31lo = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31lo_w, data_src2);\n        __m512i src_r4r5_0_31hi = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31hi_w, data_src2);\n\n        // for r6r7\n        perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);\n        perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);\n\n        __m512i src_r6r7_0_31lo = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31lo_w, data_src2);\n        __m512i src_r6r7_0_31hi = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31hi_w, data_src2);\n\n        if constexpr (!lessthan16bit) {\n          // madd requires signed integers, so shift to signed range\n          src_r4r5_0_31lo = _mm512_add_epi16(src_r4r5_0_31lo, shifttosigned);\n          src_r4r5_0_31hi = _mm512_add_epi16(src_r4r5_0_31hi, shifttosigned);\n          src_r6r7_0_31lo = _mm512_add_epi16(src_r6r7_0_31lo, shifttosigned);\n          src_r6r7_0_31hi = _mm512_add_epi16(src_r6r7_0_31hi, shifttosigned);\n        }\n\n        if constexpr (UseVNNI)\n        {\n          result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r4r5_0_31lo, coef_r4r5_0_31lo);\n          result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r6r7_0_31lo, coef_r6r7_0_31lo);\n\n          result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r4r5_0_31hi, coef_r4r5_0_31hi);\n          result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r6r7_0_31hi, coef_r6r7_0_31hi);\n\n          // rounding VNNI in first FMA already summed\n        }\n        else\n        {\n          result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_0_31lo, coef_r4r5_0_31lo), result_0_31lo);\n          result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_0_31hi, coef_r4r5_0_31hi), result_0_31hi);\n\n          result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_0_31lo, coef_r6r7_0_31lo), result_0_31lo);\n          result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_0_31hi, coef_r6r7_0_31hi), result_0_31hi);\n\n          // rounding\n          result_0_31lo = _mm512_add_epi32(result_0_31lo, rounder);\n          result_0_31hi = _mm512_add_epi32(result_0_31hi, rounder);\n        }\n\n        if constexpr (!lessthan16bit) {\n          // return from signed range\n          result_0_31lo = _mm512_add_epi32(result_0_31lo, shiftfromsigned);\n          result_0_31hi = _mm512_add_epi32(result_0_31hi, shiftfromsigned);\n        }\n\n        // scaling down\n        result_0_31lo = _mm512_srai_epi32(result_0_31lo, FPScale16bits);\n        result_0_31hi = _mm512_srai_epi32(result_0_31hi, FPScale16bits);\n\n        __m512i result_0_31_int16 = _mm512_packus_epi32(result_0_31lo, result_0_31hi);\n\n        if constexpr (lessthan16bit) {\n          result_0_31_int16 = _mm512_min_epu16(result_0_31_int16, clamp_limit); // extra clamp for 10-14 bit\n        }\n\n        _mm512_stream_si512(reinterpret_cast<__m512i*>(dst_ptr), result_0_31_int16);\n\n        dst_ptr += dst_pitch;\n        src_ptr += src_pitch;\n      }\n\n      current_coeff += filter_size * PIXELS_AT_A_TIME;\n      };\n\n    // Process the 'safe zone' where direct full unaligned loads are acceptable.\n    for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)\n    {\n      do_h_integer_core(std::false_type{});\n    }\n\n    // Process the potentially 'unsafe zone' near the image edge, using safe masked loading.\n    for (; x < width; x += PIXELS_AT_A_TIME)\n    {\n      do_h_integer_core(std::true_type{});\n    }\n  }\n}\n\n// filter size up to 16\n// 32 target uint16_t pixels at a time\n// 128-byte source loads (64 uint16_t pixels)\n// maximum permute index is 64 for _mm512_permutex2var_epi16 (uint16_t)\n// support VNNI and madd FMA\ntemplate<bool lessthan16bit, bool UseVNNI>\nvoid resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)\n{\n  const int filter_size = program->filter_size; // aligned, practically the coeff table stride\n\n  const uint16_t* src = (uint16_t*)src8;\n  uint16_t* AVS_RESTRICT dst = (uint16_t * AVS_RESTRICT)dst8;\n  dst_pitch = dst_pitch / sizeof(uint16_t);\n  src_pitch = src_pitch / sizeof(uint16_t);\n\n  constexpr int PIXELS_AT_A_TIME = 32;\n\n  // 'source_overread_beyond_targetx' indicates if the filter kernel can read beyond the target width.\n  // we load 2x32 source bytes at a time, so ensure safe overread if needed.\n  // Our main loop processes calculates for 64 target pixels at a time.\n  // Inside that, we load 128 source bytes (2x64) to be able to permutex from that.\n  // This we have to check at each mod-PIXELS_AT_A_TIME boundary, the allowance of 128-byte source load.\n  const int width_safe_mod = (program->safelimit_64_pixels_each32th_target.overread_possible ? program->safelimit_64_pixels_each32th_target.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  // Preconditions:\n  assert(program->filter_size_real <= 16); // We preload all relevant coefficients (up to 16) before the height loop.\n\n  // 'target_size_alignment' ensures we can safely access coefficients using offsets like\n  // 'filter_size * 15' when processing 16 H pixels at a time\n  // 'filter_size * 31' when processing 64 H pixels at a time\n  assert(program->target_size_alignment >= 32); // Adjusted for 32 pixels (is it enough for uint16 ?)\n\n  assert(FRAME_ALIGN >= 64); // Good for 32x16 bit pixels\n\n  // Ensure that coefficient loading beyond the valid target size is safe for 4x8 float loads.\n  // We load 8x 'short' coeffs at a time\n  // Loading is unaligned, but we fill __m128 registers before combining into __m512\n  assert(program->filter_size_alignment >= 16);\n\n  const int max_scanlines = program->max_scanlines;\n\n  // for 16 bits only\n  const __m512i shifttosigned = _mm512_set1_epi16(-32768);\n  const __m512i shiftfromsigned = _mm512_set1_epi32(32768 << FPScale16bits);\n\n  const int limit = (1 << bits_per_pixel) - 1;\n  // only used when template lessthan16bit is true\n  __m512i clamp_limit = _mm512_set1_epi16((short)limit); // clamp limit for <16 bits\n\n  __m512i rounder = _mm512_set1_epi32(1 << (FPScale16bits - 1));\n\n  // Vertical stripe loop for L2 cache optimization\n  for (int y_from = 0; y_from < height; y_from += max_scanlines)\n  {\n    int y_to = std::min(y_from + max_scanlines, height);\n\n    // Reset current_coeff for the start of the stripe (points to start of row's coeffs)\n    const short* AVS_RESTRICT current_coeff = program->pixel_coefficient;\n\n    int x = 0;\n\n    // Lambda to handle both safe (fast) and unsafe (masked/partial) loading paths\n    auto do_h_integer_core = [&](auto partial_load) {\n\n      // prepare coefs in transposed V-form\n      // TODO: make storage in transposed form, 64 x uint16 transposition looks too slow\n\n      // 16coefs of 16bit is 256bits - load as pairs of _m256i\n      // hope 16-coeffs blocks are 32-bytes aligned for m256i aligned loads ?\n      __m512i coef_0_1 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 0), (__m256i*)(current_coeff + filter_size * 1));\n      __m512i coef_2_3 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 2), (__m256i*)(current_coeff + filter_size * 3));\n      __m512i coef_4_5 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 4), (__m256i*)(current_coeff + filter_size * 5));\n      __m512i coef_6_7 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 6), (__m256i*)(current_coeff + filter_size * 7));\n      __m512i coef_8_9 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 8), (__m256i*)(current_coeff + filter_size * 9));\n      __m512i coef_10_11 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 10), (__m256i*)(current_coeff + filter_size * 11));\n      __m512i coef_12_13 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 12), (__m256i*)(current_coeff + filter_size * 13));\n      __m512i coef_14_15 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 14), (__m256i*)(current_coeff + filter_size * 15));\n      __m512i coef_16_17 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 16), (__m256i*)(current_coeff + filter_size * 17));\n      __m512i coef_18_19 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 18), (__m256i*)(current_coeff + filter_size * 19));\n      __m512i coef_20_21 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 20), (__m256i*)(current_coeff + filter_size * 21));\n      __m512i coef_22_23 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 22), (__m256i*)(current_coeff + filter_size * 23));\n      __m512i coef_24_25 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 24), (__m256i*)(current_coeff + filter_size * 25));\n      __m512i coef_26_27 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 26), (__m256i*)(current_coeff + filter_size * 27));\n      __m512i coef_28_29 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 28), (__m256i*)(current_coeff + filter_size * 29));\n      __m512i coef_30_31 = _mm512i_load_2_m256i((__m256i*)(current_coeff + filter_size * 30), (__m256i*)(current_coeff + filter_size * 31));\n\n      // Transpose with permutex\n      __m512i c_perm_0_3 = _mm512_set_epi16(\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        16 + 32, 0 + 32, 16, 0);\n\n      __m512i c_perm_4_7 = _mm512_set_epi16(\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        16 + 32, 0 + 32, 16, 0,\n        0, 0, 0, 0);\n\n      __m512i c_perm_8_11 = _mm512_set_epi16(\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        16 + 32, 0 + 32, 16, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0);\n\n      __m512i c_perm_12_15 = _mm512_set_epi16(\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        16 + 32, 0 + 32, 16, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0);\n\n      __m512i c_perm_16_19 = _mm512_set_epi16(\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        16 + 32, 0 + 32, 16, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0);\n\n      __m512i c_perm_20_23 = _mm512_set_epi16(\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        16 + 32, 0 + 32, 16, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0);\n\n      __m512i c_perm_24_27 = _mm512_set_epi16(\n        0, 0, 0, 0,\n        16 + 32, 0 + 32, 16, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0);\n\n      __m512i c_perm_28_31 = _mm512_set_epi16(\n        16 + 32, 0 + 32, 16, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0);\n\n\n      __m512i one_epi16 = _mm512_set1_epi16(1);\n\n      // Define masks for the 4-word (8-byte, 4x 16-bit word) segments within the 32-word vector.\n      // Note: Each AVX-512 word (epi16) lane corresponds to one bit in the __mmask32.\n      // The masks target chunks of 4 words (k_X_Y represents bits X through Y inclusive).\n      const __mmask32 k_4_7 = 0x000000F0;\n      const __mmask32 k_8_11 = 0x00000F00;\n      const __mmask32 k_12_15 = 0x0000F000;\n      const __mmask32 k_16_19 = 0x000F0000;\n      const __mmask32 k_20_23 = 0x00F00000;\n      const __mmask32 k_24_27 = 0x0F000000;\n      const __mmask32 k_28_31 = 0xF0000000;\n\n      // Helper lambda to increment all eight permutation vectors by one.\n      auto inc_perms = [&](\n        __m512i& p0_3, __m512i& p4_7, __m512i& p8_11, __m512i& p12_15,\n        __m512i& p16_19, __m512i& p20_23, __m512i& p24_27, __m512i& p28_31\n        ) {\n          p0_3 = _mm512_add_epi16(p0_3, one_epi16);\n          p4_7 = _mm512_add_epi16(p4_7, one_epi16);\n          p8_11 = _mm512_add_epi16(p8_11, one_epi16);\n          p12_15 = _mm512_add_epi16(p12_15, one_epi16);\n          p16_19 = _mm512_add_epi16(p16_19, one_epi16);\n          p20_23 = _mm512_add_epi16(p20_23, one_epi16);\n          p24_27 = _mm512_add_epi16(p24_27, one_epi16);\n          p28_31 = _mm512_add_epi16(p28_31, one_epi16);\n        };\n\n      // Helper lambda to construct one full 32-word (512-bit) coefficient row.\n      // It uses mask blending to merge the results of _mm512_permutex2var_epi16\n      // for different 4-word segments, using the current permutation vectors.\n      auto make_coef_row = [&](\n        __m512i& row_result,\n        __m512i p0_3, __m512i p4_7, __m512i p8_11, __m512i p12_15,\n        __m512i p16_19, __m512i p20_23, __m512i p24_27, __m512i p28_31\n        ) {\n          // Start with the first segment (words 0-3) and the fourth segment (words 4-7).\n          row_result = _mm512_mask_blend_epi16(\n            k_4_7,\n            _mm512_permutex2var_epi16(coef_0_1, p0_3, coef_2_3),  // words 0-3 (unmasked)\n            _mm512_permutex2var_epi16(coef_4_5, p4_7, coef_6_7)   // words 4-7 (masked)\n          );\n\n          // Merge segment 8-11\n          row_result = _mm512_mask_blend_epi16(\n            k_8_11,\n            row_result,\n            _mm512_permutex2var_epi16(coef_8_9, p8_11, coef_10_11)\n          );\n\n          // Merge segment 12-15\n          row_result = _mm512_mask_blend_epi16(\n            k_12_15,\n            row_result,\n            _mm512_permutex2var_epi16(coef_12_13, p12_15, coef_14_15)\n          );\n\n          // Merge segment 16-19\n          row_result = _mm512_mask_blend_epi16(\n            k_16_19,\n            row_result,\n            _mm512_permutex2var_epi16(coef_16_17, p16_19, coef_18_19)\n          );\n\n          // Merge segment 20-23\n          row_result = _mm512_mask_blend_epi16(\n            k_20_23,\n            row_result,\n            _mm512_permutex2var_epi16(coef_20_21, p20_23, coef_22_23)\n          );\n\n          // Merge segment 24-27\n          row_result = _mm512_mask_blend_epi16(\n            k_24_27,\n            row_result,\n            _mm512_permutex2var_epi16(coef_24_25, p24_27, coef_26_27)\n          );\n\n          // Merge segment 28-31\n          row_result = _mm512_mask_blend_epi16(\n            k_28_31,\n            row_result,\n            _mm512_permutex2var_epi16(coef_28_29, p28_31, coef_30_31)\n          );\n        };\n\n      // Declare the coefficient row variables\n      __m512i coef_r0_0_31w, coef_r1_0_31w, coef_r2_0_31w, coef_r3_0_31w;\n      __m512i coef_r4_0_31w, coef_r5_0_31w, coef_r6_0_31w, coef_r7_0_31w;\n      __m512i coef_r8_0_31w, coef_r9_0_31w, coef_r10_0_31w, coef_r11_0_31w;\n      __m512i coef_r12_0_31w, coef_r13_0_31w, coef_r14_0_31w, coef_r15_0_31w;\n\n      // Process Row 0\n      make_coef_row(coef_r0_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 1\n      make_coef_row(coef_r1_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 2\n      make_coef_row(coef_r2_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 3\n      make_coef_row(coef_r3_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 4\n      make_coef_row(coef_r4_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 5\n      make_coef_row(coef_r5_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 6\n      make_coef_row(coef_r6_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 7\n      make_coef_row(coef_r7_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 8\n      make_coef_row(coef_r8_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 9\n      make_coef_row(coef_r9_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 10\n      make_coef_row(coef_r10_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 11\n      make_coef_row(coef_r11_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 12\n      make_coef_row(coef_r12_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 13\n      make_coef_row(coef_r13_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 14\n      make_coef_row(coef_r14_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n\n      // Process Row 15\n      make_coef_row(coef_r15_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15, c_perm_16_19, c_perm_20_23, c_perm_24_27, c_perm_28_31);\n      // No inc_perms here\n\n      // convert-transpose to H-pairs for madd ? better to do with single permutex in future\n      // 16 to 16 512 registers - finally real working coeffs to store in the transposed resampling program for block of 64 target samples\n      __m512i coef_r0r1_0_31lo = _mm512_unpacklo_epi16(coef_r0_0_31w, coef_r1_0_31w);\n      __m512i coef_r0r1_0_31hi = _mm512_unpackhi_epi16(coef_r0_0_31w, coef_r1_0_31w);\n\n      __m512i coef_r2r3_0_31lo = _mm512_unpacklo_epi16(coef_r2_0_31w, coef_r3_0_31w);\n      __m512i coef_r2r3_0_31hi = _mm512_unpackhi_epi16(coef_r2_0_31w, coef_r3_0_31w);\n\n      __m512i coef_r4r5_0_31lo = _mm512_unpacklo_epi16(coef_r4_0_31w, coef_r5_0_31w);\n      __m512i coef_r4r5_0_31hi = _mm512_unpackhi_epi16(coef_r4_0_31w, coef_r5_0_31w);\n\n      __m512i coef_r6r7_0_31lo = _mm512_unpacklo_epi16(coef_r6_0_31w, coef_r7_0_31w);\n      __m512i coef_r6r7_0_31hi = _mm512_unpackhi_epi16(coef_r6_0_31w, coef_r7_0_31w);\n\n      __m512i coef_r8r9_0_31lo = _mm512_unpacklo_epi16(coef_r8_0_31w, coef_r9_0_31w);\n      __m512i coef_r8r9_0_31hi = _mm512_unpackhi_epi16(coef_r8_0_31w, coef_r9_0_31w);\n\n      __m512i coef_r10r11_0_31lo = _mm512_unpacklo_epi16(coef_r10_0_31w, coef_r11_0_31w);\n      __m512i coef_r10r11_0_31hi = _mm512_unpackhi_epi16(coef_r10_0_31w, coef_r11_0_31w);\n\n      __m512i coef_r12r13_0_31lo = _mm512_unpacklo_epi16(coef_r12_0_31w, coef_r13_0_31w);\n      __m512i coef_r12r13_0_31hi = _mm512_unpackhi_epi16(coef_r12_0_31w, coef_r13_0_31w);\n\n      __m512i coef_r14r15_0_31lo = _mm512_unpacklo_epi16(coef_r14_0_31w, coef_r15_0_31w);\n      __m512i coef_r14r15_0_31hi = _mm512_unpackhi_epi16(coef_r14_0_31w, coef_r15_0_31w);\n\n      // TODO: store transposed resampling program coeffs to temp buffer for reusage at each line\n\n      // convert resampling program in H-form into permuting indexes for src transposition in V-form\n      __m512i perm_0_0_15 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x])); // 16 offsets\n      __m512i perm_0_16_31 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 16])); //  16 offsets\n\n      int iStart = program->pixel_offset[x];\n      __m512i m512i_Start = _mm512_set1_epi32(iStart);\n\n      perm_0_0_15 = _mm512_sub_epi32(perm_0_0_15, m512i_Start);\n      perm_0_16_31 = _mm512_sub_epi32(perm_0_16_31, m512i_Start);\n\n      __m256i m256i_perm_0_0_15 = _mm512_cvtepi32_epi16(perm_0_0_15);\n      __m256i m256i_perm_0_16_31 = _mm512_cvtepi32_epi16(perm_0_16_31);\n\n      // Insert each 256-bit register into the specific lane\n      __m512i perm_0_0_31 = _mm512_inserti64x4(_mm512_zextsi256_si512(m256i_perm_0_0_15), m256i_perm_0_16_31, 1);\n\n      // no add_one to each perm group to save number of registers used in processing loop\n      // need only to first pair (r0 and r1)\n      __m512i perm_1_0_31 = _mm512_add_epi16(perm_0_0_31, one_epi16);\n\n      const __m512i perm_r0r1_0_31lo = _mm512_unpacklo_epi16(perm_0_0_31, perm_1_0_31);\n      const __m512i perm_r0r1_0_31hi = _mm512_unpackhi_epi16(perm_0_0_31, perm_1_0_31);\n\n      // Taps are contiguous (0, 1, 2, 3), so we increment perm indexes by 1 (in pairs by 2 each).\n      const __m512i two_epi16 = _mm512_set1_epi16(2);\n\n      uint16_t* AVS_RESTRICT dst_ptr = dst + x + y_from * dst_pitch;\n      const uint16_t* src_ptr = src + iStart + y_from * src_pitch; // all permute offsets relative to this start offset\n\n      // Calculate remaining pixels for bounds checking in partial_load mode. 1..64 remaining uint16_t pixels possible.\n      // only when partial_load\n      const int remaining = program->source_size - iStart;\n      // two masks for partial loads of 32 + 32 shorts\n      const __mmask32 k1 = _bzhi_u32(~0UL, remaining);\n      const __mmask32 k2 = _bzhi_u32(~0UL, remaining - 32);\n\n      for (int y = y_from; y < y_to; y++)\n      {\n        __m512i data_src, data_src2;\n\n        // working permute indexes for advancing to save number of registers used\n        __m512i perm_rNrNp1_0_31lo_w = perm_r0r1_0_31lo;\n        __m512i perm_rNrNp1_0_31hi_w = perm_r0r1_0_31hi;\n\n        if constexpr (partial_load) {\n          // Safe masked loads for the image edge\n          data_src = _mm512_maskz_loadu_epi16(k1, src_ptr);\n          data_src2 = _mm512_maskz_loadu_epi16(k2, src_ptr + 32);\n        }\n        else {\n          // Fast unaligned loads for the safe zone\n          data_src = _mm512_loadu_si512(src_ptr);\n          data_src2 = _mm512_loadu_si512(src_ptr + 32);\n        }\n\n        // rows 0..3\n        __m512i src_r0r1_0_31lo = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31lo_w, data_src2);\n        __m512i src_r0r1_0_31hi = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31hi_w, data_src2);\n\n        // for r2r3\n        perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);\n        perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);\n\n        __m512i src_r2r3_0_31lo = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31lo_w, data_src2);\n        __m512i src_r2r3_0_31hi = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31hi_w, data_src2);\n\n        // for r4r5\n        perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);\n        perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);\n\n        __m512i result_0_31lo, result_0_31hi;\n\n        if constexpr (!lessthan16bit) {\n          // madd requires signed integers, so shift to signed range\n          src_r0r1_0_31lo = _mm512_add_epi16(src_r0r1_0_31lo, shifttosigned);\n          src_r0r1_0_31hi = _mm512_add_epi16(src_r0r1_0_31hi, shifttosigned);\n          src_r2r3_0_31lo = _mm512_add_epi16(src_r2r3_0_31lo, shifttosigned);\n          src_r2r3_0_31hi = _mm512_add_epi16(src_r2r3_0_31hi, shifttosigned);\n        }\n\n        if constexpr (UseVNNI)\n        {\n          result_0_31lo = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31lo, coef_r0r1_0_31lo);\n          result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r2r3_0_31lo, coef_r2r3_0_31lo);\n\n          result_0_31hi = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31hi, coef_r0r1_0_31hi);\n          result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r2r3_0_31hi, coef_r2r3_0_31hi);\n        }\n        else\n        {\n          // making FMA in 32bits accs as in AVX256 V-resize\n          result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31lo, coef_r0r1_0_31lo), _mm512_madd_epi16(src_r2r3_0_31lo, coef_r2r3_0_31lo));\n          result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31hi, coef_r0r1_0_31hi), _mm512_madd_epi16(src_r2r3_0_31hi, coef_r2r3_0_31hi));\n        }\n\n        // rows 4..7\n        __m512i src_r4r5_0_31lo = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31lo_w, data_src2);\n        __m512i src_r4r5_0_31hi = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31hi_w, data_src2);\n\n        // for r6r7\n        perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);\n        perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);\n\n        __m512i src_r6r7_0_31lo = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31lo_w, data_src2);\n        __m512i src_r6r7_0_31hi = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31hi_w, data_src2);\n\n        // for r8r9\n        perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);\n        perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);\n\n        if constexpr (!lessthan16bit) {\n          // madd requires signed integers, so shift to signed range\n          src_r4r5_0_31lo = _mm512_add_epi16(src_r4r5_0_31lo, shifttosigned);\n          src_r4r5_0_31hi = _mm512_add_epi16(src_r4r5_0_31hi, shifttosigned);\n          src_r6r7_0_31lo = _mm512_add_epi16(src_r6r7_0_31lo, shifttosigned);\n          src_r6r7_0_31hi = _mm512_add_epi16(src_r6r7_0_31hi, shifttosigned);\n        }\n\n        if constexpr (UseVNNI)\n        {\n          result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r4r5_0_31lo, coef_r4r5_0_31lo);\n          result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r6r7_0_31lo, coef_r6r7_0_31lo);\n\n          result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r4r5_0_31hi, coef_r4r5_0_31hi);\n          result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r6r7_0_31hi, coef_r6r7_0_31hi);\n        }\n        else\n        {\n          // making FMA in 32bits accs as in AVX256 V-resize\n          result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_0_31lo, coef_r4r5_0_31lo), result_0_31lo);\n          result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_0_31hi, coef_r4r5_0_31hi), result_0_31hi);\n\n          result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_0_31lo, coef_r6r7_0_31lo), result_0_31lo);\n          result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_0_31hi, coef_r6r7_0_31hi), result_0_31hi);\n        }\n\n        // rows 8..11\n        __m512i src_r8r9_0_31lo = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31lo_w, data_src2);\n        __m512i src_r8r9_0_31hi = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31hi_w, data_src2);\n\n        // for r10r11\n        perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);\n        perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);\n\n        __m512i src_r10r11_0_31lo = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31lo_w, data_src2);\n        __m512i src_r10r11_0_31hi = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31hi_w, data_src2);\n\n        // for r12r13\n        perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);\n        perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);\n\n        if constexpr (!lessthan16bit) {\n          // madd requires signed integers, so shift to signed range\n          src_r8r9_0_31lo = _mm512_add_epi16(src_r8r9_0_31lo, shifttosigned);\n          src_r8r9_0_31hi = _mm512_add_epi16(src_r8r9_0_31hi, shifttosigned);\n          src_r10r11_0_31lo = _mm512_add_epi16(src_r10r11_0_31lo, shifttosigned);\n          src_r10r11_0_31hi = _mm512_add_epi16(src_r10r11_0_31hi, shifttosigned);\n        }\n\n        if constexpr (UseVNNI)\n        {\n          result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r8r9_0_31lo, coef_r8r9_0_31lo);\n          result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r10r11_0_31lo, coef_r10r11_0_31lo);\n\n          result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r8r9_0_31hi, coef_r8r9_0_31hi);\n          result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r10r11_0_31hi, coef_r10r11_0_31hi);\n        }\n        else\n        {\n          // making FMA in 32bits accs as in AVX256 V-resize\n          result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r8r9_0_31lo, coef_r8r9_0_31lo), result_0_31lo);\n          result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r8r9_0_31hi, coef_r8r9_0_31hi), result_0_31hi);\n\n          result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r10r11_0_31lo, coef_r10r11_0_31lo), result_0_31lo);\n          result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r10r11_0_31hi, coef_r10r11_0_31hi), result_0_31hi);\n        }\n\n        // rows 12..15\n        __m512i src_r12r13_0_31lo = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31lo_w, data_src2);\n        __m512i src_r12r13_0_31hi = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31hi_w, data_src2);\n\n        // for r14r15\n        perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);\n        perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);\n\n        __m512i src_r14r15_0_31lo = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31lo_w, data_src2);\n        __m512i src_r14r15_0_31hi = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31hi_w, data_src2);\n\n        if constexpr (!lessthan16bit) {\n          // madd requires signed integers, so shift to signed range\n          src_r12r13_0_31lo = _mm512_add_epi16(src_r12r13_0_31lo, shifttosigned);\n          src_r12r13_0_31hi = _mm512_add_epi16(src_r12r13_0_31hi, shifttosigned);\n          src_r14r15_0_31lo = _mm512_add_epi16(src_r14r15_0_31lo, shifttosigned);\n          src_r14r15_0_31hi = _mm512_add_epi16(src_r14r15_0_31hi, shifttosigned);\n        }\n\n        if constexpr (UseVNNI)\n        {\n          result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r12r13_0_31lo, coef_r12r13_0_31lo);\n          result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r14r15_0_31lo, coef_r14r15_0_31lo);\n\n          result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r12r13_0_31hi, coef_r12r13_0_31hi);\n          result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r14r15_0_31hi, coef_r14r15_0_31hi);\n\n          // rounding VNNI in first FMA already summed\n        }\n        else\n        {\n          result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r12r13_0_31lo, coef_r12r13_0_31lo), result_0_31lo);\n          result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r12r13_0_31hi, coef_r12r13_0_31hi), result_0_31hi);\n\n          result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r14r15_0_31lo, coef_r14r15_0_31lo), result_0_31lo);\n          result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r14r15_0_31hi, coef_r14r15_0_31hi), result_0_31hi);\n\n          // rounding\n          result_0_31lo = _mm512_add_epi32(result_0_31lo, rounder);\n          result_0_31hi = _mm512_add_epi32(result_0_31hi, rounder);\n        }\n\n        if constexpr (!lessthan16bit) {\n          // return from signed range\n          result_0_31lo = _mm512_add_epi32(result_0_31lo, shiftfromsigned);\n          result_0_31hi = _mm512_add_epi32(result_0_31hi, shiftfromsigned);\n        }\n\n        // scaling down\n        result_0_31lo = _mm512_srai_epi32(result_0_31lo, FPScale16bits);\n        result_0_31hi = _mm512_srai_epi32(result_0_31hi, FPScale16bits);\n\n        __m512i result_0_31_int16 = _mm512_packus_epi32(result_0_31lo, result_0_31hi);\n\n        if constexpr (lessthan16bit) {\n          result_0_31_int16 = _mm512_min_epu16(result_0_31_int16, clamp_limit); // extra clamp for 10-14 bit\n        }\n\n        _mm512_stream_si512(reinterpret_cast<__m512i*>(dst_ptr), result_0_31_int16);\n\n        dst_ptr += dst_pitch;\n        src_ptr += src_pitch;\n      }\n\n      current_coeff += filter_size * PIXELS_AT_A_TIME;\n      };\n\n    // Process the 'safe zone' where direct full unaligned loads are acceptable.\n    for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)\n    {\n      do_h_integer_core(std::false_type{});\n    }\n\n    // Process the potentially 'unsafe zone' near the image edge, using safe masked loading.\n    for (; x < width; x += PIXELS_AT_A_TIME)\n    {\n      do_h_integer_core(std::true_type{});\n    }\n  }\n}\n"
  },
  {
    "path": "avs_core/filters/intel/resample_avx512b.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include <avs/config.h>\n#include \"../core/internal.h\"\n\n#include <avs/alignment.h>\n#include <avs/minmax.h>\n\n#include \"check_avx512.h\" // compiler avx512 directives check\n#include \"resample_avx512.h\"\n#include <type_traits>\n\n#include <immintrin.h> // Includes AVX-512 intrinsics\n\n#include \"resample_avx512.hpp\"\n\n/**\n * Simulates _mm256_dpwssd_epi32 for CPUs without AVX512_VNNI (e.g., Xeon 613x).\n * Logic: For each 32-bit lane, it treats the inputs as pairs of 16-bit signed ints,\n * multiplies the pairs, adds them together, and adds the result to the accumulator.\n */\nstatic AVS_FORCEINLINE __m256i _MM256_DPWSSD_EPI32_SIMUL(__m256i acc, __m256i a, __m256i b) {\n#if defined(__AVX512VNNI__) || defined(__AVX_VNNI__)\n  return _mm256_dpwssd_epi32(acc, a, b);\n#else\n  // vpmaddwd: (a_even * b_even) + (a_odd * b_odd) for each 32-bit slot\n  __m256i product = _mm256_madd_epi16(a, b);\n  // vpaddd: add the products to the existing accumulator\n  return _mm256_add_epi32(acc, product);\n#endif\n}\n\n/**\n * SIMD Optimization Strategy for Horizontal Resampling Kernel (Filter) Execution.\n *\n * This section details the performance optimization strategy based on the filter's kernel size,\n * ensuring high throughput across common resampling scenarios (upscaling/downscaling).\n *\n * I. Typical Kernel Sizes (Taps):\n * ----------------------------------------------------------------------------------------------------------------\n * Small (Best Case/Upscale): Taps = 4 (Bilinear/Spline36), 8 (Spline64/Lanczos 4).\n * Medium (Mild Downscale):   Taps = 12 (Lanczos 3, 2x downscale).\n * Large (Worst Case/Downscale): Taps = 16 to 32 (Spline64/Lanczos 4, 2x to 4x downscale).\n * ----------------------------------------------------------------------------------------------------------------\n *\n * II. Optimization Tiers (Template Specialization):\n *\n * 1. Dedicated, Fully Unrolled Paths (FixedFilterSize = 4, 8, 12):\n * - Purpose: Eliminate all loop overhead (setup/teardown, bounds checks).\n * - SIMD Choice: Uses __m128i/__m256i for efficiency with small loads, accumulating into __m512i.\n * - Performance Gain: Estimated 1.5x to 2.5x speedup over generic loops for small, common kernels.\n * - Micro-arch Benefit (i7-11700): Reduces uOps (instruction count) and avoids unnecessary register pressure.\n *\n * 2. Aligned VNNI Paths (FixedFilterSize = 16, 32, 48, 64...):\n * - Purpose: Maximize vector utilization for worst-case downscaling.\n * - SIMD Choice: Uses __m512i (AVX-512) processing 32 taps per iteration.\n * - VNNI Advantage: Uses _mm512_dpwssd_epi32 for fused 16-bit multiply + 32-bit accumulation.\n *\n * 3. Generic Path (FixedFilterSize = -1):\n * - Purpose: Handles all remaining unaligned or uncommon kernel sizes. Slower, but safe fallback.\n */\n\n // Helper to reduce a ZMM (16x int32) to a scalar int32 sum\n// -----------------------------------------------------------------------------------------\n// Helper: Reduce ZMM (16x int32) to scalar int32\n// -----------------------------------------------------------------------------------------\nAVS_FORCEINLINE static int32_t _mm512_reduce_add_epi32_compat(__m512i v) {\n  /*\n  __m256i v256 = _mm256_add_epi32(_mm512_extracti64x4_epi64(v, 0), _mm512_extracti64x4_epi64(v, 1));\n  __m128i v128 = _mm_add_epi32(_mm256_castsi256_si128(v256), _mm256_extracti128_si256(v256, 1));\n  v128 = _mm_add_epi32(v128, _mm_shuffle_epi32(v128, _MM_SHUFFLE(1, 0, 3, 2)));\n  v128 = _mm_add_epi32(v128, _mm_shuffle_epi32(v128, _MM_SHUFFLE(0, 3, 0, 1)));\n  return _mm_cvtsi128_si32(v128);\n  */\n  return _mm512_reduce_add_epi32(v);\n}\n\n// These are the direct rewrite of the full-generic AVX2 h resamplers\n// - resizer_h_avx512_generic_uint8_t and\n// - resizer_h_avx512_generic_uint16_t<bool lessthan16bit>\n// They are not any quicker than the AVX2 versions, but they serve as a base for further optimizations.\n// The 512-bitness is not exploited, only have more registers, but they did not help. WIP.\n\n// -----------------------------------------------------------------------------------------\n// Core Processing: 4x16, 2x16 Taps\n// -----------------------------------------------------------------------------------------\n// taps16, 4 coeffs\ntemplate<typename pixel_t, bool lessthan16bit>\nAVS_FORCEINLINE static void process_two_16pixels_core(const pixel_t * AVS_RESTRICT src, int begin1, int begin2, int i, const short* AVS_RESTRICT current_coeff, int filter_size, __m256i & result1, __m256i & result2, __m256i & shifttosigned) {\n  __m256i data_1, data_2;\n\n  if constexpr (sizeof(pixel_t) == 1) {\n    data_1 = _mm256_cvtepu8_epi16(_mm_loadu_si128(reinterpret_cast<const __m128i*>(src + begin1 + i)));\n    data_2 = _mm256_cvtepu8_epi16(_mm_loadu_si128(reinterpret_cast<const __m128i*>(src + begin2 + i)));\n  }\n  else {\n    data_1 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(src + begin1 + i));\n    data_2 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(src + begin2 + i));\n    if constexpr (!lessthan16bit) {\n      data_1 = _mm256_add_epi16(data_1, shifttosigned);\n      data_2 = _mm256_add_epi16(data_2, shifttosigned);\n    }\n  }\n\n  // Aligned load is not OK for coeffs if filter size is only 4\n  // Coeffs are aligned to 4 or 8 shorts, so alignment is 8 or 16 bytes, _m256i requires 32 bytes alignment.\n\n  // assume 16 alignment\n\n  __m256i coeff_1 = _mm256_load_si256(reinterpret_cast<const __m256i*>(current_coeff));\n  __m256i coeff_2 = _mm256_load_si256(reinterpret_cast<const __m256i*>(current_coeff + filter_size));\n\n  result1 = _MM256_DPWSSD_EPI32_SIMUL(result1, data_1, coeff_1); // vnni, not really a bottleneck here\n  result2 = _MM256_DPWSSD_EPI32_SIMUL(result2, data_2, coeff_2);\n}\n\n// taps16, 4 coeffs\ntemplate<typename pixel_t, bool lessthan16bit>\nAVS_FORCEINLINE static void process_four_16pixels_core(const pixel_t* AVS_RESTRICT src,\n  int begin1, int begin2, int begin3, int begin4, int i, const short* AVS_RESTRICT current_coeff, int filter_size,\n  __m256i& result1, __m256i& result2, __m256i& result3, __m256i& result4, __m256i& shifttosigned) {\n  __m256i data_1, data_2, data_3, data_4;\n\n  if constexpr (sizeof(pixel_t) == 1) {\n    data_1 = _mm256_cvtepu8_epi16(_mm_loadu_si128(reinterpret_cast<const __m128i*>(src + begin1 + i)));\n    data_2 = _mm256_cvtepu8_epi16(_mm_loadu_si128(reinterpret_cast<const __m128i*>(src + begin2 + i)));\n    data_3 = _mm256_cvtepu8_epi16(_mm_loadu_si128(reinterpret_cast<const __m128i*>(src + begin3 + i)));\n    data_4 = _mm256_cvtepu8_epi16(_mm_loadu_si128(reinterpret_cast<const __m128i*>(src + begin4 + i)));\n  }\n  else {\n    data_1 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(src + begin1 + i));\n    data_2 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(src + begin2 + i));\n    data_3 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(src + begin3 + i));\n    data_4 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(src + begin4 + i));\n    if constexpr (!lessthan16bit) {\n      data_1 = _mm256_add_epi16(data_1, shifttosigned);\n      data_2 = _mm256_add_epi16(data_2, shifttosigned);\n      data_3 = _mm256_add_epi16(data_3, shifttosigned);\n      data_4 = _mm256_add_epi16(data_4, shifttosigned);\n    }\n  }\n\n  // Aligned load is not OK for coeffs if filter size is only 4\n  // Coeffs are aligned to 4 or 8 shorts, so alignment is 8 or 16 bytes, _m256i requires 32 bytes alignment.\n\n  // assume 16 alignment\n\n  __m256i coeff_1 = _mm256_load_si256(reinterpret_cast<const __m256i*>(current_coeff));\n  __m256i coeff_2 = _mm256_load_si256(reinterpret_cast<const __m256i*>(current_coeff + filter_size));\n  __m256i coeff_3 = _mm256_load_si256(reinterpret_cast<const __m256i*>(current_coeff + 2 * filter_size));\n  __m256i coeff_4 = _mm256_load_si256(reinterpret_cast<const __m256i*>(current_coeff + 3 * filter_size));\n\n  result1 = _MM256_DPWSSD_EPI32_SIMUL(result1, data_1, coeff_1);\n  result2 = _MM256_DPWSSD_EPI32_SIMUL(result2, data_2, coeff_2);\n  result3 = _MM256_DPWSSD_EPI32_SIMUL(result3, data_3, coeff_3);\n  result4 = _MM256_DPWSSD_EPI32_SIMUL(result4, data_4, coeff_4);\n}\n\n// -----------------------------------------------------------------------------------------\n// Helper: Unrolled Partial Core (4 or 8 Taps) XMM would be enough\n// -----------------------------------------------------------------------------------------\n// filter_size must be the aligned size, better named as filter_coeff_stride\ntemplate<typename pixel_t, bool lessthan16bit, int Taps>\nAVS_FORCEINLINE static void process_two_partial_unrolled(const pixel_t* src, int begin1, int begin2, int offset, const short* coeff, int filter_size, __m256i& result1, __m256i& result2, __m256i& shifttosigned) {\n  // Taps is 4 or 8.\n  __m128i d1, d2;\n\n  // Load Data\n  if constexpr (sizeof(pixel_t) == 1) {\n    if constexpr (Taps == 4) {\n      d1 = _mm_cvtepu8_epi16(_mm_cvtsi32_si128(*reinterpret_cast<const int*>(src + begin1 + offset)));\n      d2 = _mm_cvtepu8_epi16(_mm_cvtsi32_si128(*reinterpret_cast<const int*>(src + begin2 + offset)));\n    }\n    else { // 8\n      d1 = _mm_cvtepu8_epi16(_mm_loadl_epi64(reinterpret_cast<const __m128i*>(src + begin1 + offset)));\n      d2 = _mm_cvtepu8_epi16(_mm_loadl_epi64(reinterpret_cast<const __m128i*>(src + begin2 + offset)));\n    }\n  }\n  else {\n    if constexpr (Taps == 4) {\n      d1 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(src + begin1 + offset));\n      d2 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(src + begin2 + offset));\n    }\n    else { // 8\n      d1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src + begin1 + offset));\n      d2 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src + begin2 + offset));\n    }\n    if constexpr (!lessthan16bit) {\n      d1 = _mm_add_epi16(d1, _mm256_castsi256_si128(shifttosigned));\n      d2 = _mm_add_epi16(d2, _mm256_castsi256_si128(shifttosigned));\n    }\n  }\n\n  // Load Coeffs (Need to handle offset)\n  __m128i c1, c2;\n  if constexpr (Taps == 4) {\n    c1 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(coeff + offset));\n    c2 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(coeff + filter_size + offset));\n  }\n  else {\n    c1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(coeff + offset));\n    c2 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(coeff + filter_size + offset));\n  }\n\n  // Calc\n/*\n  result1 = _mm512_zextsi128_si512(_mm_dpwssd_epi32(_mm512_castsi512_si128(result1), d1, c1));\n  result2 = _mm512_zextsi128_si512(_mm_dpwssd_epi32(_mm512_castsi512_si128(result2), d2, c2));\n*/\n  __m256i c1_256 = _mm256_zextsi128_si256(c1);\n  __m256i c2_256 = _mm256_zextsi128_si256(c2);\n  __m256i d1_256 = _mm256_zextsi128_si256(d1);\n  __m256i d2_256 = _mm256_zextsi128_si256(d2);\n\n  result1 = _MM256_DPWSSD_EPI32_SIMUL(result1, d1_256, c1_256);\n  result2 = _MM256_DPWSSD_EPI32_SIMUL(result2, d2_256, c2_256);\n\n}\n\n// -----------------------------------------------------------------------------------------\n// Helper: Unrolled Partial Core (4 or 8 Taps) XMM would be enough\n// -----------------------------------------------------------------------------------------\n// filter_size must be the aligned size, better named as filter_coeff_stride\ntemplate<typename pixel_t, bool lessthan16bit, int Taps>\nAVS_FORCEINLINE static void process_four_partial_unrolled(const pixel_t* src,\n  int begin1, int begin2, int begin3, int begin4, int offset,\n  const short* coeff, int filter_size,\n  __m256i& result1, __m256i& result2, __m256i& result3, __m256i& result4, __m256i& shifttosigned) {\n  // Taps is 4 or 8.\n  __m128i d1, d2, d3, d4;\n\n  // Load Data\n  if constexpr (sizeof(pixel_t) == 1) {\n    if constexpr (Taps == 4) {\n      d1 = _mm_cvtepu8_epi16(_mm_cvtsi32_si128(*reinterpret_cast<const int*>(src + begin1 + offset)));\n      d2 = _mm_cvtepu8_epi16(_mm_cvtsi32_si128(*reinterpret_cast<const int*>(src + begin2 + offset)));\n      d3 = _mm_cvtepu8_epi16(_mm_cvtsi32_si128(*reinterpret_cast<const int*>(src + begin3 + offset)));\n      d4 = _mm_cvtepu8_epi16(_mm_cvtsi32_si128(*reinterpret_cast<const int*>(src + begin4 + offset)));\n    }\n    else { // 8\n      d1 = _mm_cvtepu8_epi16(_mm_loadl_epi64(reinterpret_cast<const __m128i*>(src + begin1 + offset)));\n      d2 = _mm_cvtepu8_epi16(_mm_loadl_epi64(reinterpret_cast<const __m128i*>(src + begin2 + offset)));\n      d3 = _mm_cvtepu8_epi16(_mm_loadl_epi64(reinterpret_cast<const __m128i*>(src + begin3 + offset)));\n      d4 = _mm_cvtepu8_epi16(_mm_loadl_epi64(reinterpret_cast<const __m128i*>(src + begin4 + offset)));\n    }\n  }\n  else {\n    if constexpr (Taps == 4) {\n      d1 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(src + begin1 + offset));\n      d2 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(src + begin2 + offset));\n      d3 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(src + begin3 + offset));\n      d4 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(src + begin4 + offset));\n    }\n    else { // 8\n      d1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src + begin1 + offset));\n      d2 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src + begin2 + offset));\n      d3 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src + begin3 + offset));\n      d4 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src + begin4 + offset));\n    }\n    if constexpr (!lessthan16bit) {\n      d1 = _mm_add_epi16(d1, _mm256_castsi256_si128(shifttosigned));\n      d2 = _mm_add_epi16(d2, _mm256_castsi256_si128(shifttosigned));\n      d3 = _mm_add_epi16(d3, _mm256_castsi256_si128(shifttosigned));\n      d4 = _mm_add_epi16(d4, _mm256_castsi256_si128(shifttosigned));\n    }\n  }\n\n  // Load Coeffs (Need to handle offset)\n  __m128i c1, c2, c3, c4;\n  if constexpr (Taps == 4) {\n    c1 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(coeff + offset));\n    c2 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(coeff + filter_size + offset));\n    c3 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(coeff + 2 * filter_size + offset));\n    c4 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(coeff + 3 * filter_size + offset));\n  }\n  else {\n    c1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(coeff + offset));\n    c2 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(coeff + filter_size + offset));\n    c3 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(coeff + 2 * filter_size + offset));\n    c4 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(coeff + 3 * filter_size + offset));\n  }\n\n  // Calc\n/*\n  result1 = _mm512_zextsi128_si512(_mm_dpwssd_epi32(_mm512_castsi512_si128(result1), d1, c1));\n  result2 = _mm512_zextsi128_si512(_mm_dpwssd_epi32(_mm512_castsi512_si128(result2), d2, c2));\n*/\n  __m256i c1_256 = _mm256_zextsi128_si256(c1);\n  __m256i c2_256 = _mm256_zextsi128_si256(c2);\n  __m256i c3_256 = _mm256_zextsi128_si256(c3);\n  __m256i c4_256 = _mm256_zextsi128_si256(c4);\n  __m256i d1_256 = _mm256_zextsi128_si256(d1);\n  __m256i d2_256 = _mm256_zextsi128_si256(d2);\n  __m256i d3_256 = _mm256_zextsi128_si256(d3);\n  __m256i d4_256 = _mm256_zextsi128_si256(d4);\n\n  result1 = _MM256_DPWSSD_EPI32_SIMUL(result1, d1_256, c1_256);\n  result2 = _MM256_DPWSSD_EPI32_SIMUL(result2, d2_256, c2_256);\n  result3 = _MM256_DPWSSD_EPI32_SIMUL(result3, d3_256, c3_256);\n  result4 = _MM256_DPWSSD_EPI32_SIMUL(result4, d4_256, c4_256);\n}\n\n\n// ---------------------------------------------------------------------------\n// FULLY VECTORIZED TREE REDUCTION (AVX2/AVX-512VL)\n// Input: 8x __m256i accumulators (r0 through r7)\n// Output: __m256i with 8 final, rounded pixel sums (p0 through p7)\n// ---------------------------------------------------------------------------\n\nAVS_FORCEINLINE static __m256i reduce_8x256i_32i_tree(\n  __m256i r0, __m256i r1, __m256i r2, __m256i r3,\n  __m256i r4, __m256i r5, __m256i r6, __m256i r7,\n  int rounder_scalar)\n{\n  // --- Round 1: Reduce pairs (8 elements -> 4 elements per vector) ---\n  // VPHADDD on each pair. The results are still interleaved within the 128-bit blocks.\n  __m256i sum01 = _mm256_hadd_epi32(r0, r1);\n  __m256i sum23 = _mm256_hadd_epi32(r2, r3);\n  __m256i sum45 = _mm256_hadd_epi32(r4, r5);\n  __m256i sum67 = _mm256_hadd_epi32(r6, r7);\n\n  // --- Round 2: Reduce quads (4 elements -> 2 elements per vector) ---\n  // The final pixel sum is now split between the low 128-bit half and the high 128-bit half.\n  __m256i sum0123 = _mm256_hadd_epi32(sum01, sum23);\n  __m256i sum4567 = _mm256_hadd_epi32(sum45, sum67);\n\n  // --- Round 3: Final Horizontal Reduction (Across 128-bit boundary) ---\n\n  // 1. Add the low 128-bit half to the high 128-bit half to finalize the sum for P0-P7.\n  // VPERM2I128 (0x01 swaps the 128-bit halves)\n  __m256i hi_add0123 = _mm256_permute2f128_si256(sum0123, sum0123, 0x01);\n  __m256i hi_add4567 = _mm256_permute2f128_si256(sum4567, sum4567, 0x01);\n\n  // The final sums for P0-P3 are now consolidated into the low 4 lanes of final0123.\n  __m256i final0123 = _mm256_add_epi32(sum0123, hi_add0123);\n  __m256i final4567 = _mm256_add_epi32(sum4567, hi_add4567);\n\n  // --- Round 4: Final Consolidation (P0-P7 into one __m256i) ---\n\n  // 1. Extract the low 128 bits (which contain the P0-P3 sums)\n  __m128i p0_p3 = _mm256_castsi256_si128(final0123);\n  __m128i p4_p7 = _mm256_castsi256_si128(final4567);\n\n  // 2. Assemble the two 128-bit blocks into the final 256-bit result (VINSERTI128).\n  __m256i result_8x_32 = _mm256_inserti128_si256(_mm256_castsi128_si256(p0_p3), p4_p7, 1);\n\n  // --- Final Vectorized Rounding ---\n\n  // Create the rounder vector\n  __m256i rounder_v = _mm256_set1_epi32(rounder_scalar);\n\n  // Apply rounding to all 8 pixels simultaneously (VPADDD)\n  return _mm256_add_epi32(result_8x_32, rounder_v);\n}\n\n\nAVS_FORCEINLINE static __m256i reduce_8x128i_to_8x32i(\n  __m128i r0, __m128i r1, __m128i r2, __m128i r3,\n  __m128i r4, __m128i r5, __m128i r6, __m128i r7,\n  int rounder_scalar)\n{\n  // --- Round 1: Reduce pairs (8 elements -> 4 elements per vector) ---\n  // VPHADDD on each pair. The results are still interleaved within the 128-bit blocks.\n  __m128i sum01 = _mm_hadd_epi32(r0, r1);\n  __m128i sum23 = _mm_hadd_epi32(r2, r3);\n  __m128i sum45 = _mm_hadd_epi32(r4, r5);\n  __m128i sum67 = _mm_hadd_epi32(r6, r7);\n\n  // --- Round 2: Reduce quads (4 elements -> 2 elements per vector) ---\n  // The final pixel sum is now split between the low 128-bit half and the high 128-bit half.\n  __m128i sum0123 = _mm_hadd_epi32(sum01, sum23);\n  __m128i sum4567 = _mm_hadd_epi32(sum45, sum67);\n\n  // 2. Assemble the two 128-bit blocks into the final 256-bit result (VINSERTI128).\n  __m256i result_8x_32 = _mm256_inserti128_si256(_mm256_castsi128_si256(sum0123), sum4567, 1);\n\n  // --- Final Vectorized Rounding ---\n\n  // Create the rounder vector\n  __m256i rounder_v = _mm256_set1_epi32(rounder_scalar);\n\n  // Apply rounding to all 8 pixels simultaneously (VPADDD)\n  return _mm256_add_epi32(result_8x_32, rounder_v);\n}\n\n\n// -----------------------------------------------------------------------------------------\n// Wrapper for Two-Pixel Processing\n// -----------------------------------------------------------------------------------------\ntemplate<bool safe_aligned_mode, typename pixel_t, bool lessthan16bit, int FixedFilterSize>\nAVS_FORCEINLINE static void process_two_pixels_h_avx512(const pixel_t * AVS_RESTRICT src_ptr, int begin1, int begin2, const short* AVS_RESTRICT current_coeff,\n  int filter_size, __m256i & result1, __m256i & result2, int kernel_size, __m256i & shifttosigned) {\n\n  // filter_size here is the stride for coeffs, kernel_size is the actual number of taps to process.\n\n  if constexpr (FixedFilterSize == 4) {\n    process_two_partial_unrolled<pixel_t, lessthan16bit, 4>(src_ptr, begin1, begin2, 0, current_coeff, filter_size, result1, result2, shifttosigned);\n    return;\n  }\n  if constexpr (FixedFilterSize == 8) {\n    process_two_partial_unrolled<pixel_t, lessthan16bit, 8>(src_ptr, begin1, begin2, 0, current_coeff, filter_size, result1, result2, shifttosigned);\n    return;\n  }\n  if constexpr (FixedFilterSize == 12) {\n    process_two_partial_unrolled<pixel_t, lessthan16bit, 8>(src_ptr, begin1, begin2, 0, current_coeff, filter_size, result1, result2, shifttosigned);\n    process_two_partial_unrolled<pixel_t, lessthan16bit, 4>(src_ptr, begin1, begin2, 8, current_coeff, filter_size, result1, result2, shifttosigned);\n    return;\n  }\n\n  // 2. Large Kernel Loop (16-tap blocks)\n  int i = 0;\n  // We can use the FixedFilterSize to cap the loop if it's large (like 48, 64)\n  int runtime_filter_size = (FixedFilterSize >= 1) ? FixedFilterSize : filter_size;\n  int ksmod16 = (safe_aligned_mode && FixedFilterSize >= 16) ? (FixedFilterSize / 16 * 16) : (kernel_size / 16 * 16);\n\n  for (; i < ksmod16; i += 16) {\n    process_two_16pixels_core<pixel_t, lessthan16bit>(src_ptr, begin1, begin2, i, current_coeff + i, filter_size, result1, result2, shifttosigned);\n  }\n\n  // 3. Tail Handling\n  // If we are in safe mode and FixedSize is a multiple of 32, we are done.\n  if constexpr (safe_aligned_mode && (FixedFilterSize % 16 == 0) && FixedFilterSize > 0) return;\n\n  int remaining = runtime_filter_size - i;\n  if (remaining <= 0) return;\n\n  // Process remaining using scalar fallbacks\n  // Unrolled helpers for chunks of 8/4/scalar.\n\n  // Chunk 8\n  if (remaining >= 8) {\n    process_two_partial_unrolled<pixel_t, lessthan16bit, 8>(src_ptr, begin1, begin2, i, current_coeff, filter_size, result1, result2, shifttosigned);\n    i += 8;\n    remaining -= 8;\n  }\n  if (remaining >= 4) {\n    process_two_partial_unrolled<pixel_t, lessthan16bit, 4>(src_ptr, begin1, begin2, i, current_coeff, filter_size, result1, result2, shifttosigned);\n    i += 4;\n    remaining -= 4;\n  }\n\n  // Final scalar tail (1-3 pixels)\n  while (remaining > 0) {\n    int val1, val2;\n    if constexpr (sizeof(pixel_t) == 1) {\n      val1 = src_ptr[begin1 + i];\n      val2 = src_ptr[begin2 + i];\n    }\n    else {\n      val1 = src_ptr[begin1 + i];\n      val2 = src_ptr[begin2 + i];\n      if constexpr (!lessthan16bit) { val1 -= 32768; val2 -= 32768; }\n    }\n    int c1 = current_coeff[i];\n    int c2 = current_coeff[filter_size + i];\n\n    // Add to the first lane of the accumulator\n    __m256i s1 = _mm256_zextsi128_si256(_mm_cvtsi32_si128(val1 * c1));\n    __m256i s2 = _mm256_zextsi128_si256(_mm_cvtsi32_si128(val2 * c2));\n\n    result1 = _mm256_add_epi32(result1, s1);\n    result2 = _mm256_add_epi32(result2, s2);\n\n    i++;\n    remaining--;\n  }\n}\n\n// -----------------------------------------------------------------------------------------\n// Wrapper for Four-Pixel Processing\n// -----------------------------------------------------------------------------------------\ntemplate<bool safe_aligned_mode, typename pixel_t, bool lessthan16bit, int FixedFilterSize>\nAVS_FORCEINLINE static void process_four_pixels_h_avx512(const pixel_t* AVS_RESTRICT src_ptr,\n  int begin1, int begin2, int begin3, int begin4, const short* AVS_RESTRICT current_coeff, int filter_size,\n  __m256i& result1, __m256i& result2, __m256i& result3, __m256i& result4, int kernel_size, __m256i& shifttosigned) {\n\n  // filter_size here is the stride for coeffs, kernel_size is the actual number of taps to process.\n\n  if constexpr (FixedFilterSize == 4) {\n    process_four_partial_unrolled<pixel_t, lessthan16bit, 4>(src_ptr, begin1, begin2, begin3, begin4, 0, current_coeff, filter_size, result1, result2, result3, result4, shifttosigned);\n    return;\n  }\n  if constexpr (FixedFilterSize == 8) {\n    process_four_partial_unrolled<pixel_t, lessthan16bit, 8>(src_ptr, begin1, begin2, begin3, begin4, 0, current_coeff, filter_size, result1, result2, result3, result4, shifttosigned);\n    return;\n  }\n  if constexpr (FixedFilterSize == 12) {\n    process_four_partial_unrolled<pixel_t, lessthan16bit, 8>(src_ptr, begin1, begin2, begin3, begin4, 0, current_coeff, filter_size, result1, result2, result3, result4, shifttosigned);\n    process_four_partial_unrolled<pixel_t, lessthan16bit, 4>(src_ptr, begin1, begin2, begin3, begin4, 8, current_coeff, filter_size, result1, result2, result3, result4, shifttosigned);\n    return;\n  }\n\n  // 2. Large Kernel Loop (16-tap blocks)\n  int i = 0;\n  // We can use the FixedFilterSize to cap the loop if it's large (like 48, 64)\n  int runtime_filter_size = (FixedFilterSize >= 1) ? FixedFilterSize : filter_size;\n  int ksmod16 = (safe_aligned_mode && FixedFilterSize >= 16) ? (FixedFilterSize / 16 * 16) : (kernel_size / 16 * 16);\n\n  for (; i < ksmod16; i += 16) {\n    process_four_16pixels_core<pixel_t, lessthan16bit>(src_ptr, begin1, begin2, begin3, begin4, i, current_coeff + i, filter_size, result1, result2, result3, result4, shifttosigned);\n  }\n\n  // 3. Tail Handling\n  // If we are in safe mode and FixedSize is a multiple of 32, we are done.\n  if constexpr (safe_aligned_mode && (FixedFilterSize % 16 == 0) && FixedFilterSize > 0) return;\n\n  int remaining = runtime_filter_size - i;\n  if (remaining <= 0) return;\n\n  // Process remaining using scalar fallbacks\n  // Unrolled helpers for chunks of 8/4/scalar.\n\n  // Chunk 8\n  if (remaining >= 8) {\n    process_four_partial_unrolled<pixel_t, lessthan16bit, 8>(src_ptr, begin1, begin2, begin3, begin4, i, current_coeff, filter_size, result1, result2, result3, result4, shifttosigned);\n    i += 8;\n    remaining -= 8;\n  }\n  if (remaining >= 4) {\n    process_four_partial_unrolled<pixel_t, lessthan16bit, 4>(src_ptr, begin1, begin2, begin3, begin4, i, current_coeff, filter_size, result1, result2, result3, result4, shifttosigned);\n    i += 4;\n    remaining -= 4;\n  }\n\n  // Final scalar tail (1-3 pixels)\n  while (remaining > 0) {\n    int val1, val2, val3, val4;\n    if constexpr (sizeof(pixel_t) == 1) {\n      val1 = src_ptr[begin1 + i];\n      val2 = src_ptr[begin2 + i];\n      val3 = src_ptr[begin3 + i];\n      val4 = src_ptr[begin4 + i];\n    }\n    else {\n      val1 = src_ptr[begin1 + i];\n      val2 = src_ptr[begin2 + i];\n      val3 = src_ptr[begin3 + i];\n      val4 = src_ptr[begin4 + i];\n      if constexpr (!lessthan16bit) { val1 -= 32768; val2 -= 32768; val3 -= 32768; val4 -= 32768; }\n    }\n    int c1 = current_coeff[i];\n    int c2 = current_coeff[filter_size + i];\n    int c3 = current_coeff[2 * filter_size + i];\n    int c4 = current_coeff[3 * filter_size + i];\n\n    // Add to the first lane of the accumulator\n    __m256i s1 = _mm256_zextsi128_si256(_mm_cvtsi32_si128(val1 * c1));\n    __m256i s2 = _mm256_zextsi128_si256(_mm_cvtsi32_si128(val2 * c2));\n    __m256i s3 = _mm256_zextsi128_si256(_mm_cvtsi32_si128(val3 * c3));\n    __m256i s4 = _mm256_zextsi128_si256(_mm_cvtsi32_si128(val4 * c4));\n\n    result1 = _mm256_add_epi32(result1, s1);\n    result2 = _mm256_add_epi32(result2, s2);\n    result3 = _mm256_add_epi32(result3, s3);\n    result4 = _mm256_add_epi32(result4, s4);\n\n    i++;\n    remaining--;\n  }\n}\n\n// -----------------------------------------------------------------------------------------\n// Main Block Processor, TWO_PIXELS_AT_ONCE for testing performance difference\n// -----------------------------------------------------------------------------------------\ntemplate<bool is_safe, typename pixel_t, bool lessthan16bit, int FixedFilterSize>\nAVS_FORCEINLINE static void process_sixteen_pixels_h_avx512(const pixel_t * src, int x, const short* current_coeff_base, int filter_size,\n  int rounder_scalar, __m256i& shifttosigned, __m256i& clamp_limit,\n  pixel_t* dst, ResamplingProgram* program)\n{\n  int run_filter_size_stride = (FixedFilterSize >= 1) ? FixedFilterSize : filter_size; // quasi constexpr if templated\n  const short* AVS_RESTRICT current_coeff = current_coeff_base + x * run_filter_size_stride;\n  const int unaligned_kernel_size = program->filter_size_real;\n\n#ifdef TWO_PIXELS_AT_ONCE\n  __m256i result0 = _mm256_setzero_si256();\n  __m256i result1 = _mm256_setzero_si256();\n  process_two_pixels_h_avx512<is_safe, pixel_t, lessthan16bit, FixedFilterSize>(src, program->pixel_offset[x], program->pixel_offset[x + 1], current_coeff, run_filter_size_stride, result0, result1, unaligned_kernel_size, shifttosigned);\n  current_coeff += 2 * run_filter_size_stride;\n\n  __m256i result2 = _mm256_setzero_si256();\n  __m256i result3 = _mm256_setzero_si256();\n  process_two_pixels_h_avx512<is_safe, pixel_t, lessthan16bit, FixedFilterSize>(src, program->pixel_offset[x + 2], program->pixel_offset[x + 3], current_coeff, run_filter_size_stride, result2, result3, unaligned_kernel_size, shifttosigned);\n  current_coeff += 2 * run_filter_size_stride;\n\n  __m256i result4 = _mm256_setzero_si256();\n  __m256i result5 = _mm256_setzero_si256();\n  process_two_pixels_h_avx512<is_safe, pixel_t, lessthan16bit, FixedFilterSize>(src, program->pixel_offset[x + 4], program->pixel_offset[x + 5], current_coeff, run_filter_size_stride, result4, result5, unaligned_kernel_size, shifttosigned);\n  current_coeff += 2 * run_filter_size_stride;\n\n  __m256i result6 = _mm256_setzero_si256();\n  __m256i result7 = _mm256_setzero_si256();\n  process_two_pixels_h_avx512<is_safe, pixel_t, lessthan16bit, FixedFilterSize>(src, program->pixel_offset[x + 6], program->pixel_offset[x + 7], current_coeff, run_filter_size_stride, result6, result7, unaligned_kernel_size, shifttosigned);\n  current_coeff += 2 * run_filter_size_stride;\n#else\n  __m256i result0 = _mm256_setzero_si256();\n  __m256i result1 = _mm256_setzero_si256();\n  __m256i result2 = _mm256_setzero_si256();\n  __m256i result3 = _mm256_setzero_si256();\n  process_four_pixels_h_avx512 < is_safe, pixel_t, lessthan16bit, FixedFilterSize>(src,\n    program->pixel_offset[x], program->pixel_offset[x + 1],\n    program->pixel_offset[x + 2], program->pixel_offset[x + 3],\n    current_coeff, run_filter_size_stride,\n    result0, result1, result2, result3,\n    unaligned_kernel_size, shifttosigned);\n  current_coeff += 4 * run_filter_size_stride;\n  __m256i result4 = _mm256_setzero_si256();\n  __m256i result5 = _mm256_setzero_si256();\n  __m256i result6 = _mm256_setzero_si256();\n  __m256i result7 = _mm256_setzero_si256();\n  process_four_pixels_h_avx512 < is_safe, pixel_t, lessthan16bit, FixedFilterSize>(src,\n    program->pixel_offset[x + 4], program->pixel_offset[x + 5],\n    program->pixel_offset[x + 6], program->pixel_offset[x + 7],\n    current_coeff, run_filter_size_stride,\n    result4, result5, result6, result7,\n    unaligned_kernel_size, shifttosigned);\n  current_coeff += 4 * run_filter_size_stride;\n#endif\n  __m256i result_8x_32_lo = reduce_8x256i_32i_tree(\n    result0, result1, result2, result3,\n    result4, result5, result6, result7,\n    rounder_scalar);\n\n  // same for pixels 8..15\n#ifdef TWO_PIXELS_AT_ONCE\n  __m256i result8 = _mm256_setzero_si256();\n  __m256i result9 = _mm256_setzero_si256();\n  process_two_pixels_h_avx512<is_safe, pixel_t, lessthan16bit, FixedFilterSize>(src, program->pixel_offset[x + 8], program->pixel_offset[x + 9], current_coeff, run_filter_size_stride, result8, result9, unaligned_kernel_size, shifttosigned);\n  current_coeff += 2 * run_filter_size_stride;\n\n  __m256i result10 = _mm256_setzero_si256();\n  __m256i result11 = _mm256_setzero_si256();\n  process_two_pixels_h_avx512<is_safe, pixel_t, lessthan16bit, FixedFilterSize>(src, program->pixel_offset[x + 10], program->pixel_offset[x + 11], current_coeff, run_filter_size_stride, result10, result11, unaligned_kernel_size, shifttosigned);\n  current_coeff += 2 * run_filter_size_stride;\n\n  __m256i result12 = _mm256_setzero_si256();\n  __m256i result13 = _mm256_setzero_si256();\n  process_two_pixels_h_avx512<is_safe, pixel_t, lessthan16bit, FixedFilterSize>(src, program->pixel_offset[x + 12], program->pixel_offset[x + 13], current_coeff, run_filter_size_stride, result12, result13, unaligned_kernel_size, shifttosigned);\n  current_coeff += 2 * run_filter_size_stride;\n\n  __m256i result14 = _mm256_setzero_si256();\n  __m256i result15 = _mm256_setzero_si256();\n  process_two_pixels_h_avx512<is_safe, pixel_t, lessthan16bit, FixedFilterSize>(src, program->pixel_offset[x + 14], program->pixel_offset[x + 15], current_coeff, run_filter_size_stride, result14, result15, unaligned_kernel_size, shifttosigned);\n  // last one, no need:\n  // current_coeff += 2 * run_filter_size_stride;\n#else\n  __m256i result8 = _mm256_setzero_si256();\n  __m256i result9 = _mm256_setzero_si256();\n  __m256i result10 = _mm256_setzero_si256();\n  __m256i result11 = _mm256_setzero_si256();\n  process_four_pixels_h_avx512 < is_safe, pixel_t, lessthan16bit, FixedFilterSize>(src,\n    program->pixel_offset[x + 8], program->pixel_offset[x + 9],\n    program->pixel_offset[x + 10], program->pixel_offset[x + 11],\n    current_coeff, run_filter_size_stride,\n    result8, result9, result10, result11,\n    unaligned_kernel_size, shifttosigned);\n  current_coeff += 4 * run_filter_size_stride;\n  __m256i result12 = _mm256_setzero_si256();\n  __m256i result13 = _mm256_setzero_si256();\n  __m256i result14 = _mm256_setzero_si256();\n  __m256i result15 = _mm256_setzero_si256();\n  process_four_pixels_h_avx512 < is_safe, pixel_t, lessthan16bit, FixedFilterSize>(src,\n    program->pixel_offset[x + 12], program->pixel_offset[x + 13],\n    program->pixel_offset[x + 14], program->pixel_offset[x + 15],\n    current_coeff, run_filter_size_stride,\n    result12, result13, result14, result15,\n    unaligned_kernel_size, shifttosigned);\n#endif\n\n  __m256i result_8x_32_hi = reduce_8x256i_32i_tree(\n    result8, result9, result10, result11,\n    result12, result13, result14, result15,\n    rounder_scalar);\n\n  // \n  if constexpr (sizeof(pixel_t) == 2 && !lessthan16bit) {\n    const __m256i shiftfromsigned = _mm256_set1_epi32(+32768 << FPScale16bits);\n    result_8x_32_lo = _mm256_add_epi32(result_8x_32_lo, shiftfromsigned);\n    result_8x_32_hi = _mm256_add_epi32(result_8x_32_hi, shiftfromsigned);\n  }\n\n  // ... scale/pack ...\n  const int shift = (sizeof(pixel_t) == 1) ? FPScale8bits : FPScale16bits;\n  __m256i scaled_lo = _mm256_srai_epi32(result_8x_32_lo, shift);\n  __m256i scaled_hi = _mm256_srai_epi32(result_8x_32_hi, shift);\n\n  // integer 32->unsigned 16 bit, the usual and quick way\n  __m256i result_16 = _mm256_packus_epi32(scaled_lo, scaled_hi);\n\n  // we have 8x16 bit unsigned pixels now in result_16\n  if constexpr (sizeof(pixel_t) == 2 && lessthan16bit) {\n    result_16 = _mm256_min_epu16(result_16, clamp_limit);\n  }\n\n  result_16 =  _mm256_permute4x64_epi64(result_16, (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6));\n\n  if constexpr (sizeof(pixel_t) == 1) {\n    __m128i result_8 = _mm_packus_epi16(_mm256_castsi256_si128(result_16), _mm256_extracti128_si256(result_16, 1));\n    _mm_stream_si128(reinterpret_cast<__m128i*>(dst + x), result_8); // 16x 8bit pixels\n  }\n  else {\n    _mm256_stream_si256(reinterpret_cast<__m256i*>(dst + x), result_16);\n  }\n}\n\n// -----------------------------------------------------------------------------------------\n// Dispatcher\n// -----------------------------------------------------------------------------------------\ntemplate<typename pixel_t, bool lessthan16bit, int FixedFilterSize>\nstatic void internal_resizer_h_avx512_generic(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  int current_fp_scale_bits = (sizeof(pixel_t) == 1) ? FPScale8bits : FPScale16bits;\n  int rounder_scalar = 1 << (current_fp_scale_bits - 1);\n\n  __m256i shifttosigned = _mm256_set1_epi16(-32768);\n  __m256i clamp_limit = _mm256_set1_epi16((short)((1 << bits_per_pixel) - 1));\n\n  const pixel_t* src = reinterpret_cast<const pixel_t*>(src8);\n  pixel_t* dst = reinterpret_cast<pixel_t*>(dst8);\n  dst_pitch /= sizeof(pixel_t);\n  src_pitch /= sizeof(pixel_t);\n\n  const int PIXELS_AT_A_TIME = 16;\n\n  const int filter_size = (FixedFilterSize >= 1) ? FixedFilterSize : program->filter_size; // aligned coeff stride\n  const int w_safe = (program->safelimit_filter_size_aligned.overread_possible ? program->safelimit_filter_size_aligned.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < w_safe; x += PIXELS_AT_A_TIME) {\n      process_sixteen_pixels_h_avx512<true, pixel_t, lessthan16bit, FixedFilterSize>(src, x, program->pixel_coefficient, filter_size, rounder_scalar, shifttosigned, clamp_limit, dst, program);\n    }\n    for (int x = w_safe; x < width; x += PIXELS_AT_A_TIME) {\n      process_sixteen_pixels_h_avx512<false, pixel_t, lessthan16bit, FixedFilterSize>(src, x, program->pixel_coefficient, filter_size, rounder_scalar, shifttosigned, clamp_limit, dst, program);\n    }\n    dst += dst_pitch;\n    src += src_pitch;\n  }\n}\n\n// Entry Points: Map filter sizes to optimized templates\nvoid resizer_h_avx512_generic_uint8_t(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  int fs = program->filter_size; // aligned coeff stride\n  // Dispatch to optimized templates based on filter size\n  if (fs == 4)  internal_resizer_h_avx512_generic<uint8_t, true, 4>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else if (fs == 8)  internal_resizer_h_avx512_generic<uint8_t, true, 8>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else if (fs == 12) internal_resizer_h_avx512_generic<uint8_t, true, 12>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else if (fs == 16) internal_resizer_h_avx512_generic<uint8_t, true, 16>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else if (fs == 32) internal_resizer_h_avx512_generic<uint8_t, true, 32>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else if (fs == 48) internal_resizer_h_avx512_generic<uint8_t, true, 48>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else internal_resizer_h_avx512_generic<uint8_t, true, -1>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\n\n// 16 bit Horizontal Dispatcher\n// Handles both full 16-bit (lessthan16bit=false) and 10-14 bit (lessthan16bit=true)\ntemplate<bool lessthan16bit>\nvoid resizer_h_avx512_generic_uint16_t(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  const int fs = program->filter_size; // aligned coeff stride\n  // Dispatch to optimized templates based on filter size\n  if (fs == 4)       internal_resizer_h_avx512_generic<uint16_t, lessthan16bit, 4>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else if (fs == 8)  internal_resizer_h_avx512_generic<uint16_t, lessthan16bit, 8>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else if (fs == 12) internal_resizer_h_avx512_generic<uint16_t, lessthan16bit, 12>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else if (fs == 16) internal_resizer_h_avx512_generic<uint16_t, lessthan16bit, 16>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else if (fs == 32) internal_resizer_h_avx512_generic<uint16_t, lessthan16bit, 32>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else if (fs == 48) internal_resizer_h_avx512_generic<uint16_t, lessthan16bit, 48>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else               internal_resizer_h_avx512_generic<uint16_t, lessthan16bit, -1>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\n\n// Explicit template instantiation\n// AVX512 16-bit (unsigned, full range)\ntemplate void resizer_h_avx512_generic_uint16_t<false>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\n// AVX512 10-14 bit (requires clamping)\ntemplate void resizer_h_avx512_generic_uint16_t<true>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\n\n//------- 512 bit float Horizontals\n\n// Safe quad lane partial load with AVX512 using masks.\n// Replaces scalar set_ps sequences with hardware-masked loads.\n// Requires AVX-512VL (standard on Rocket Lake, Zen 4/5).\nAVS_FORCEINLINE static __m512 _mm512_load_partial_safe_4_m128(const float* src_ptr_offsetted1, const float* src_ptr_offsetted2, const float* src_ptr_offsetted3, const float* src_ptr_offsetted4, int floats_to_load) {\n  // Example: N=3 -> (1<<3)-1 = 7 (binary 0111) -> Loads floats 0, 1, 2.\n  const __mmask8 k = (1 << floats_to_load) - 1;\n\n  // perform masked loads.\n  // _mm_maskz_loadu_ps(k, ptr):\n  // - Loads 'valid_pixels' floats from memory.\n  // - Zeros out the remaining upper floats in the XMM register (z-masking).\n  // - FAULT SUPPRESSION: Hardware guarantees no page fault for masked-off elements.\n  //   Thought Avisynth frame buffers are overallocated to avoid OOB reads, this adds extra safety.\n  __m128 s1 = _mm_maskz_loadu_ps(k, src_ptr_offsetted1);\n  __m128 s2 = _mm_maskz_loadu_ps(k, src_ptr_offsetted2);\n  __m128 s3 = _mm_maskz_loadu_ps(k, src_ptr_offsetted3);\n  __m128 s4 = _mm_maskz_loadu_ps(k, src_ptr_offsetted4);\n\n  // Combine into ZMM\n  __m512 result = _mm512_castps128_ps512(s1);      // Free (register aliasing)\n  result = _mm512_insertf32x4(result, s2, 1);      // vinsertf32x4\n  result = _mm512_insertf32x4(result, s3, 2);\n  result = _mm512_insertf32x4(result, s4, 3);\n\n  return result;\n}\n\nAVS_FORCEINLINE static __m512 _mm512_load_partial_safe_2_m256(const float* src_ptr_offsetted1, const float* src_ptr_offsetted2, int floats_to_load) {\n  // Calculate the mask. \n  const __mmask8 k = (1U << floats_to_load) - 1;\n\n  // _mm256_maskz_loadu_ps provides fault suppression for masked-off elements,\n  // ensuring no page faults occur even if the pointer is near a boundary.\n  __m256 s1 = _mm256_maskz_loadu_ps(k, src_ptr_offsetted1);\n  __m256 s2 = _mm256_maskz_loadu_ps(k, src_ptr_offsetted2);\n\n  // Combine into ZMM.\n  __m512 result = _mm512_castps256_ps512(s1);\n  result = _mm512_insertf32x8(result, s2, 1);\n\n  return result;\n}\n\n#if 0\n// Safe quad lane partial load with AVX512\n// Read exactly N pixels (where N mod 4 is the template parameter), avoiding\n// - reading beyond the end of the source buffer.\n// - avoid NaN contamination by padding with zeros.\ntemplate <int Nmod4>\nAVS_FORCEINLINE static __m512 _mm512_load_partial_safe_4_m128_avx2like(const float* src_ptr_offsetted1, const float* src_ptr_offsetted2, const float* src_ptr_offsetted3, const float* src_ptr_offsetted4) {\n  __m128 s1, s2, s3, s4;\n  switch (Nmod4) {\n  case 1:\n    s1 = _mm_set_ps(0.0f, 0.0f, 0.0f, src_ptr_offsetted1[0]);\n    s2 = _mm_set_ps(0.0f, 0.0f, 0.0f, src_ptr_offsetted2[0]);\n    s3 = _mm_set_ps(0.0f, 0.0f, 0.0f, src_ptr_offsetted3[0]);\n    s4 = _mm_set_ps(0.0f, 0.0f, 0.0f, src_ptr_offsetted4[0]);\n    // ideally: movss\n    break;\n  case 2:\n    s1 = _mm_set_ps(0.0f, 0.0f, src_ptr_offsetted1[1], src_ptr_offsetted1[0]);\n    s2 = _mm_set_ps(0.0f, 0.0f, src_ptr_offsetted2[1], src_ptr_offsetted2[0]);\n    s3 = _mm_set_ps(0.0f, 0.0f, src_ptr_offsetted3[1], src_ptr_offsetted3[0]);\n    s4 = _mm_set_ps(0.0f, 0.0f, src_ptr_offsetted4[1], src_ptr_offsetted4[0]);\n    // ideally: movsd\n    break;\n  case 3:\n    s1 = _mm_set_ps(0.0f, src_ptr_offsetted1[2], src_ptr_offsetted1[1], src_ptr_offsetted1[0]);\n    s2 = _mm_set_ps(0.0f, src_ptr_offsetted2[2], src_ptr_offsetted2[1], src_ptr_offsetted2[0]);\n    s3 = _mm_set_ps(0.0f, src_ptr_offsetted3[2], src_ptr_offsetted3[1], src_ptr_offsetted3[0]);\n    s4 = _mm_set_ps(0.0f, src_ptr_offsetted4[2], src_ptr_offsetted4[1], src_ptr_offsetted4[0]);\n    // ideally: movss + movsd + shuffle or movsd + insert\n    break;\n  case 0:\n    s1 = _mm_set_ps(src_ptr_offsetted1[3], src_ptr_offsetted1[2], src_ptr_offsetted1[1], src_ptr_offsetted1[0]);\n    s2 = _mm_set_ps(src_ptr_offsetted2[3], src_ptr_offsetted2[2], src_ptr_offsetted2[1], src_ptr_offsetted2[0]);\n    s3 = _mm_set_ps(src_ptr_offsetted3[3], src_ptr_offsetted3[2], src_ptr_offsetted3[1], src_ptr_offsetted3[0]);\n    s4 = _mm_set_ps(src_ptr_offsetted4[3], src_ptr_offsetted4[2], src_ptr_offsetted4[1], src_ptr_offsetted4[0]);\n    // ideally: movups\n    break;\n  default:\n    s1 = _mm_setzero_ps(); // n/a cannot happen\n    s2 = _mm_setzero_ps();\n    s3 = _mm_setzero_ps();\n    s4 = _mm_setzero_ps();\n  }\n  __m512 result = _mm512_castps128_ps512(s1); // Cast the first __m128 to __m512\n  result = _mm512_insertf32x4(result, s2, 1); // Insert the second __m128 at position 1\n  result = _mm512_insertf32x4(result, s3, 2); // Insert the third __m128 at position 2\n  result = _mm512_insertf32x4(result, s4, 3); // Insert the fourth __m128 at position 3\n  return result;\n}\n#endif\n\n// Processes a horizontal resampling kernel of up to four coefficients for float pixel types.\n// Supports BilinearResize, BicubicResize, or sinc with up to 2 taps (filter size <= 4).\n// AVX512 optimization loads and processes four float coefficients and sixteen pixels simultaneously.\n// This AVX512 requires only filter_size_alignment of 4.\nvoid resize_h_planar_float_avx512_transpose_vstripe_ks4(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n\n  const int filter_size = program->filter_size; // aligned, practically the coeff table stride\n  // needed for partial load\n  const int Nmod4 = program->filter_size_real % 4;\n  const int floats_to_load = (Nmod4 == 0) ? 4 : Nmod4;\n\n  src_pitch /= sizeof(float);\n  dst_pitch /= sizeof(float);\n\n  float* src = (float*)src8;\n  float* dst = (float*)dst8;\n\n  constexpr int PIXELS_AT_A_TIME = 16; // Process sixteen pixels in parallel using AVX512 (4x4 using m128 lanes)\n\n  // 'source_overread_beyond_targetx' indicates if the filter kernel can read beyond the target width.\n  // Even if the filter alignment allows larger reads, our safety boundary for unaligned loads starts at 4 pixels back\n  // from the target width, as we load 4 floats at once conceptually with our safe load.\n  const int width_safe_mod = (program->safelimit_4_pixels.overread_possible ? program->safelimit_4_pixels.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  // Preconditions:\n  assert(program->filter_size_real <= 4);\n  assert(program->target_size_alignment >= 16); // Must align for 16 pixel offsets\n  assert(program->filter_size_alignment >= 4);\n  assert(FRAME_ALIGN >= 64); // Adjusted for 16 pixels AviSynth+ default\n\n  // Vertical stripe alignment\n  constexpr int STRIPE_ALIGN = 16;\n\n  int max_scanlines = program->max_scanlines / STRIPE_ALIGN * STRIPE_ALIGN;\n  if (max_scanlines < STRIPE_ALIGN) max_scanlines = STRIPE_ALIGN;\n\n  // --- outer loop: vertical stripes ---\n  for (auto y_from = 0; y_from < height; y_from += max_scanlines) {\n    size_t y_to = std::min(y_from + max_scanlines, height);\n\n    // Reset current_coeff for the start of the stripe\n    const float* AVS_RESTRICT current_coeff = program->pixel_coefficient_float;\n\n    size_t x = 0;\n\n    // Lambda for 512-bit Core\n    auto do_h_float_core = [&](auto partial_load) {\n\n      // load 4x4 sets of coefficients (16 pixels total)\n      // at once before the height loop.\n      // Coefficients for the source pixel offset (for src_ptr + begin1 [0..3], begin5 [0..3], begin9 [0..3], begin13 [0..3])\n      __m512 coef_1_5_9_13 = _mm512_load_4_m128(current_coeff + filter_size * 0, current_coeff + filter_size * 4, current_coeff + filter_size * 8, current_coeff + filter_size * 12);\n      __m512 coef_2_6_10_14 = _mm512_load_4_m128(current_coeff + filter_size * 1, current_coeff + filter_size * 5, current_coeff + filter_size * 9, current_coeff + filter_size * 13);\n      __m512 coef_3_7_11_15 = _mm512_load_4_m128(current_coeff + filter_size * 2, current_coeff + filter_size * 6, current_coeff + filter_size * 10, current_coeff + filter_size * 14);\n      __m512 coef_4_8_12_16 = _mm512_load_4_m128(current_coeff + filter_size * 3, current_coeff + filter_size * 7, current_coeff + filter_size * 11, current_coeff + filter_size * 15);\n\n      _MM_TRANSPOSE16_LANE4_PS(coef_1_5_9_13, coef_2_6_10_14, coef_3_7_11_15, coef_4_8_12_16);\n\n      // Pixel offsets for the current target x-positions.\n      // Even for x >= width, these offsets are guaranteed to be within the allocated 'target_size_alignment'.\n      const int begin1 = program->pixel_offset[x + 0];\n      const int begin2 = program->pixel_offset[x + 1];\n      const int begin3 = program->pixel_offset[x + 2];\n      const int begin4 = program->pixel_offset[x + 3];\n      const int begin5 = program->pixel_offset[x + 4];\n      const int begin6 = program->pixel_offset[x + 5];\n      const int begin7 = program->pixel_offset[x + 6];\n      const int begin8 = program->pixel_offset[x + 7];\n      const int begin9 = program->pixel_offset[x + 8];\n      const int begin10 = program->pixel_offset[x + 9];\n      const int begin11 = program->pixel_offset[x + 10];\n      const int begin12 = program->pixel_offset[x + 11];\n      const int begin13 = program->pixel_offset[x + 12];\n      const int begin14 = program->pixel_offset[x + 13];\n      const int begin15 = program->pixel_offset[x + 14];\n      const int begin16 = program->pixel_offset[x + 15];\n\n      int y = y_from;\n\n      // Calculate pointers ONCE before the inner loop (Optimization from AVX2 version)\n      float* AVS_RESTRICT dst_ptr = dst + y * dst_pitch + x;\n      const float* src_ptr = src + y * src_pitch;\n\n      // Inner loop: vertical processing. unroll 2 tested, no benefit\n      for (; y < y_to; ++y) {\n\n        __m512 data_1_5_9_13;\n        __m512 data_2_6_10_14;\n        __m512 data_3_7_11_15;\n        __m512 data_4_8_12_16;\n\n        if constexpr (partial_load) {\n          // In the potentially unsafe zone (near the right edge of the image), we use a safe loading function\n          // to prevent reading beyond the allocated source scanline.\n          data_1_5_9_13 = _mm512_load_partial_safe_4_m128(src_ptr + begin1, src_ptr + begin5, src_ptr + begin9, src_ptr + begin13, floats_to_load);\n          data_2_6_10_14 = _mm512_load_partial_safe_4_m128(src_ptr + begin2, src_ptr + begin6, src_ptr + begin10, src_ptr + begin14, floats_to_load);\n          data_3_7_11_15 = _mm512_load_partial_safe_4_m128(src_ptr + begin3, src_ptr + begin7, src_ptr + begin11, src_ptr + begin15, floats_to_load);\n          data_4_8_12_16 = _mm512_load_partial_safe_4_m128(src_ptr + begin4, src_ptr + begin8, src_ptr + begin12, src_ptr + begin16, floats_to_load);\n        }\n        else {\n          // In the safe zone, we can directly load 4 source pixels at a time for each of the 16 lanes.\n          data_1_5_9_13 = _mm512_loadu_4_m128(src_ptr + begin1, src_ptr + begin5, src_ptr + begin9, src_ptr + begin13);\n          data_2_6_10_14 = _mm512_loadu_4_m128(src_ptr + begin2, src_ptr + begin6, src_ptr + begin10, src_ptr + begin14);\n          data_3_7_11_15 = _mm512_loadu_4_m128(src_ptr + begin3, src_ptr + begin7, src_ptr + begin11, src_ptr + begin15);\n          data_4_8_12_16 = _mm512_loadu_4_m128(src_ptr + begin4, src_ptr + begin8, src_ptr + begin12, src_ptr + begin16);\n        }\n\n        _MM_TRANSPOSE16_LANE4_PS(data_1_5_9_13, data_2_6_10_14, data_3_7_11_15, data_4_8_12_16);\n\n        // two sets, hint for the compiler to allow parallel fma's\n        __m512 result_0 = _mm512_mul_ps(data_1_5_9_13, coef_1_5_9_13);\n        __m512 result_1 = _mm512_mul_ps(data_2_6_10_14, coef_2_6_10_14);\n        result_0 = _mm512_fmadd_ps(data_3_7_11_15, coef_3_7_11_15, result_0);\n        result_1 = _mm512_fmadd_ps(data_4_8_12_16, coef_4_8_12_16, result_1);\n        _mm512_stream_ps(dst_ptr, _mm512_add_ps(result_0, result_1));\n\n        dst_ptr += dst_pitch;\n        src_ptr += src_pitch;\n      } // y\n\n        // Move to the next set of coefficients for the next 16 output pixels\n      current_coeff += filter_size * 16;\n      };\n\n    // Process the 'safe zone' where direct full unaligned loads are acceptable.\n    for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)\n    {\n      do_h_float_core(std::false_type{});  // partial_load == false, use direct _mm512_loadu_ps\n    }\n\n    // Process the potentially 'unsafe zone' near the image edge, using safe loading.\n    for (; x < width; x += PIXELS_AT_A_TIME)\n    {\n      do_h_float_core(std::true_type{}); // partial_load == true, use the safer _mm512_load_partial_safe_4_m128\n    }\n  }\n}\n\n\nvoid resize_h_planar_float_avx512_transpose_vstripe_ks8(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n\n  const int filter_size = program->filter_size; // aligned, practically the coeff table stride\n\n  src_pitch /= sizeof(float);\n  dst_pitch /= sizeof(float);\n\n  float* src = (float*)src8;\n  float* dst = (float*)dst8;\n\n  constexpr int PIXELS_AT_A_TIME = 16; // Process sixteen pixels in parallel using AVX512 (4x4 using m128 lanes)\n\n  // 'source_overread_beyond_targetx' indicates if the filter kernel can read beyond the target width.\n  // Even if the filter alignment allows larger reads, our safety boundary for unaligned loads starts at 4 pixels back\n  // from the target width, as we load 4 floats at once conceptually with our safe load.\n  const int width_safe_mod = (program->safelimit_4_pixels.overread_possible ? program->safelimit_4_pixels.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  // Preconditions:\n  assert(program->filter_size_real <= 8);\n  assert(program->target_size_alignment >= 16); // Must align for 16 pixel offsets\n  assert(program->filter_size_alignment >= 8);\n  assert(FRAME_ALIGN >= 64); // Adjusted for 16 pixels AviSynth+ default\n\n  // Vertical stripe alignment\n  constexpr int STRIPE_ALIGN = 16; // this must be multiple of PIXELS_AT_A_TIME \n\n  int max_scanlines = program->max_scanlines / STRIPE_ALIGN * STRIPE_ALIGN;\n\n  if (max_scanlines < STRIPE_ALIGN) max_scanlines = STRIPE_ALIGN;\n\n  // --- outer loop: vertical stripes ---\n  for (auto y_from = 0; y_from < height; y_from += max_scanlines) {\n    size_t y_to = std::min(y_from + max_scanlines, height);\n\n    // Reset current_coeff for the start of the stripe\n    const float* AVS_RESTRICT current_coeff = program->pixel_coefficient_float;\n\n    size_t x = 0;\n\n    // Lambda for 512-bit Core\n    auto do_h_float_core = [&](auto partial_load) {\n\n      // Load to 8 coefficients per source pixel at once before the height loop.\n      // Pre-loading and transposing coefficients keeps register usage efficient.\n      // Assumes 'filter_size_aligned' is at least 8.\n\n      __m256 coef0 = _mm256_loadu_ps(current_coeff + filter_size * 0);\n      __m256 coef1 = _mm256_loadu_ps(current_coeff + filter_size * 1);\n      __m512 coef01 = _mm512_insert_2_m256(coef0, coef1);\n\n      __m256 coef2 = _mm256_loadu_ps(current_coeff + filter_size * 2);\n      __m256 coef3 = _mm256_loadu_ps(current_coeff + filter_size * 3);\n      __m512 coef23 = _mm512_insert_2_m256(coef2, coef3);\n\n      __m256 coef4 = _mm256_loadu_ps(current_coeff + filter_size * 4);\n      __m256 coef5 = _mm256_loadu_ps(current_coeff + filter_size * 5);\n      __m512 coef45 = _mm512_insert_2_m256(coef4, coef5);\n\n      __m256 coef6 = _mm256_loadu_ps(current_coeff + filter_size * 6);\n      __m256 coef7 = _mm256_loadu_ps(current_coeff + filter_size * 7);\n      __m512 coef67 = _mm512_insert_2_m256(coef6, coef7);\n\n      __m256 coef8 = _mm256_loadu_ps(current_coeff + filter_size * 8);\n      __m256 coef9 = _mm256_loadu_ps(current_coeff + filter_size * 9);\n      __m512 coef89 = _mm512_insert_2_m256(coef8, coef9);\n\n      __m256 coef10 = _mm256_loadu_ps(current_coeff + filter_size * 10);\n      __m256 coef11 = _mm256_loadu_ps(current_coeff + filter_size * 11);\n      __m512 coef1011 = _mm512_insert_2_m256(coef10, coef11);\n\n      __m256 coef12 = _mm256_loadu_ps(current_coeff + filter_size * 12);\n      __m256 coef13 = _mm256_loadu_ps(current_coeff + filter_size * 13);\n      __m512 coef1213 = _mm512_insert_2_m256(coef12, coef13);\n\n      __m256 coef14 = _mm256_loadu_ps(current_coeff + filter_size * 14);\n      __m256 coef15 = _mm256_loadu_ps(current_coeff + filter_size * 15);\n      __m512 coef1415 = _mm512_insert_2_m256(coef14, coef15);\n\n      // Before: 8x_m512 as 8x2x_m256 holding 16*8 coefficients each for 16 pixels\n      // coef01:   0.0 ... 0.7 | 1.0 ... 1.7\n      // coef23:   2.0 ... 2.7 | 3.0 ... 3.7\n      // coef45:   4.0 ... 4.7 | 5.0 ... 5.7\n      // coef67:   6.0 ... 6.7 | 7.0 ... 7.7\n      // coef89:   8.0 ... 8.7 | 9.0 ... 9.7\n      // coef1011: A.0 ... A.7 | B.0 ... B.7\n      // coef1213: C.0 ... C.7 | D.0 ... D.7\n      // coef1415: E.0 ... E.7 | F.0 ... F.7\n\n      _MM_TRANSPOSE8x16_PS(coef01, coef23, coef45, coef67, coef89, coef1011, coef1213, coef1415);\n\n      // After: 8x _m512 holding 16 coefficients, each for 16 pixels\n      // result0, as old_coef01 : 0.0 .. 7.0 | 8.0 .. F.0\n      // result1, as old_coef23 : 0.1 .. 7.1 | 8.1 .. F.1\n      // result2, as old_coef45 : 0.2 .. 7.2 | 8.2 .. F.2\n      // result3, as old_coef67 : 0.3 .. 7.3 | 8.3 .. F.3\n      // result4, as old_coef89 : 0.4 .. 7.4 | 8.4 .. F.4\n      // result5, as old_coef1011: 0.5 .. 7.5 | 8.5 .. F.5\n      // result6, as old_coef1213: 0.6 .. 7.6 | 8.6 .. F.6\n      // result7, as old_coef1415: 0.7 .. 7.7 | 8.7 .. F.7\n\n      // Pixel offsets for the current target x-positions.\n      // Even for x >= width, these offsets are guaranteed to be within the allocated 'target_size_alignment'.\n      const int begin1 = program->pixel_offset[x + 0];\n      const int begin2 = program->pixel_offset[x + 1];\n      const int begin3 = program->pixel_offset[x + 2];\n      const int begin4 = program->pixel_offset[x + 3];\n      const int begin5 = program->pixel_offset[x + 4];\n      const int begin6 = program->pixel_offset[x + 5];\n      const int begin7 = program->pixel_offset[x + 6];\n      const int begin8 = program->pixel_offset[x + 7];\n      const int begin9 = program->pixel_offset[x + 8];\n      const int begin10 = program->pixel_offset[x + 9];\n      const int begin11 = program->pixel_offset[x + 10];\n      const int begin12 = program->pixel_offset[x + 11];\n      const int begin13 = program->pixel_offset[x + 12];\n      const int begin14 = program->pixel_offset[x + 13];\n      const int begin15 = program->pixel_offset[x + 14];\n      const int begin16 = program->pixel_offset[x + 15];\n\n      int y = y_from;\n\n      // Calculate pointers ONCE before the inner loop (Optimization from AVX2 version)\n      float* AVS_RESTRICT dst_ptr = dst + y * dst_pitch + x;\n      const float* src_ptr = src + y * src_pitch;\n\n      // only needed for partial load\n      const int Nmod8 = program->filter_size_real % 8;\n      const int floats_to_load = Nmod8 == 0 ? 8 : Nmod8;\n\n      for (; y < y_to; ++y) {\n\n        __m512 data01, data23, data45, data67, data89, data1011, data1213, data1415;\n\n        if constexpr (partial_load) {\n          // In the potentially unsafe zone (near the right edge of the image), we use a safe loading function\n          // to prevent reading beyond the allocated source scanline.\n          data01 = _mm512_load_partial_safe_2_m256(src_ptr + begin1, src_ptr + begin2, floats_to_load);\n          data23 = _mm512_load_partial_safe_2_m256(src_ptr + begin3, src_ptr + begin4, floats_to_load);\n          data45 = _mm512_load_partial_safe_2_m256(src_ptr + begin5, src_ptr + begin6, floats_to_load);\n          data67 = _mm512_load_partial_safe_2_m256(src_ptr + begin7, src_ptr + begin8, floats_to_load);\n          data89 = _mm512_load_partial_safe_2_m256(src_ptr + begin9, src_ptr + begin10, floats_to_load);\n          data1011 = _mm512_load_partial_safe_2_m256(src_ptr + begin11, src_ptr + begin12, floats_to_load);\n          data1213 = _mm512_load_partial_safe_2_m256(src_ptr + begin13, src_ptr + begin14, floats_to_load);\n          data1415 = _mm512_load_partial_safe_2_m256(src_ptr + begin15, src_ptr + begin16, floats_to_load);\n        }\n        else {\n          // In the safe zone, we can directly load 8 source pixels at a time for each of the 16 lanes.\n          data01 = _mm512_insert_2_m256(_mm256_loadu_ps(src_ptr + begin1), _mm256_loadu_ps(src_ptr + begin2));\n          data23 = _mm512_insert_2_m256(_mm256_loadu_ps(src_ptr + begin3), _mm256_loadu_ps(src_ptr + begin4));\n          data45 = _mm512_insert_2_m256(_mm256_loadu_ps(src_ptr + begin5), _mm256_loadu_ps(src_ptr + begin6));\n          data67 = _mm512_insert_2_m256(_mm256_loadu_ps(src_ptr + begin7), _mm256_loadu_ps(src_ptr + begin8));\n          data89 = _mm512_insert_2_m256(_mm256_loadu_ps(src_ptr + begin9), _mm256_loadu_ps(src_ptr + begin10));\n          data1011 = _mm512_insert_2_m256(_mm256_loadu_ps(src_ptr + begin11), _mm256_loadu_ps(src_ptr + begin12));\n          data1213 = _mm512_insert_2_m256(_mm256_loadu_ps(src_ptr + begin13), _mm256_loadu_ps(src_ptr + begin14));\n          data1415 = _mm512_insert_2_m256(_mm256_loadu_ps(src_ptr + begin15), _mm256_loadu_ps(src_ptr + begin16));\n        }\n\n        _MM_TRANSPOSE8x16_PS(data01, data23, data45, data67, data89, data1011, data1213, data1415);\n\n        // two sets, hint for the compiler to allow parallel fma's\n        __m512 result_0 = _mm512_mul_ps(data01, coef01);\n        __m512 result_1 = _mm512_mul_ps(data23, coef23);\n        result_0 = _mm512_fmadd_ps(data45, coef45, result_0);\n        result_1 = _mm512_fmadd_ps(data67, coef67, result_1);\n        result_0 = _mm512_fmadd_ps(data89, coef89, result_0);\n        result_1 = _mm512_fmadd_ps(data1011, coef1011, result_1);\n        result_0 = _mm512_fmadd_ps(data1213, coef1213, result_0);\n        result_1 = _mm512_fmadd_ps(data1415, coef1415, result_1);\n\n        _mm512_stream_ps(dst_ptr, _mm512_add_ps(result_0, result_1));\n\n        dst_ptr += dst_pitch;\n        src_ptr += src_pitch;\n      } // y\n\n      // Move to the next set of coefficients for the next 16 output pixels\n      current_coeff += filter_size * 16;\n      }; // lambda\n\n    // Process the 'safe zone' where direct full unaligned loads are acceptable.\n    for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)\n    {\n      do_h_float_core(std::false_type{});  // partial_load == false, use direct _mm512_loadu_ps\n    }\n\n    // Process the potentially 'unsafe zone' near the image edge, using safe loading.\n    for (; x < width; x += PIXELS_AT_A_TIME)\n    {\n      do_h_float_core(std::true_type{}); // partial_load == true, use the safer _mm512_load_partial_safe_2_m256\n    }\n  }\n}\n\n// Similar to AVX2 resize_h_planar_float_avx512_permutex_vstripe_ks4\n// but doing 16 pixels at a time with AVX512 permutex instructions.\nvoid resize_h_planar_float_avx512_permutex_vstripe_ks4(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)\n{\n  const int filter_size = program->filter_size; // aligned, practically the coeff table stride\n\n  src_pitch /= sizeof(float);\n  dst_pitch /= sizeof(float);\n\n  float* src = (float*)src8;\n  float* dst = (float*)dst8;\n\n  constexpr int PIXELS_AT_A_TIME = 16; // Process sixteen pixels in parallel using AVX512 (4x4 using m128 lanes)\n\n  // 'source_overread_beyond_targetx' indicates if the filter kernel can read beyond the target width.\n  const int width_safe_mod = (program->safelimit_4_pixels.overread_possible ? program->safelimit_4_pixels.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  // Preconditions:\n  assert(program->filter_size_real <= 4); // We preload all relevant coefficients (up to 4) before the height loop.\n\n  // 'target_size_alignment' ensures we can safely access coefficients using offsets like\n  // 'filter_size * 15' when processing 16 H pixels at a time\n  assert(program->target_size_alignment >= 16); // Adjusted for 16 pixels\n  assert(FRAME_ALIGN >= 64); // Adjusted for 16 pixels AviSynth+ default\n\n  // Ensure that coefficient loading beyond the valid target size is safe for 4x4 float loads.\n  assert(program->filter_size_alignment >= 4);\n\n  const int max_scanlines = program->max_scanlines;\n\n  // Vertical stripe loop for L2 cache optimization\n  for (int y_from = 0; y_from < height; y_from += max_scanlines)\n  {\n    int y_to = std::min(y_from + max_scanlines, height);\n\n    // Reset current_coeff for the start of the stripe (points to start of row's coeffs)\n    const float* AVS_RESTRICT current_coeff = (const float* AVS_RESTRICT)program->pixel_coefficient_float;\n\n    int x = 0;\n\n    // Lambda to handle both safe (fast) and unsafe (masked/partial) loading paths\n    auto do_h_float_core = [&](auto partial_load) {\n\n      // prepare coefs in transposed V-form\n      // We load 4 coefficients sets (for 4 pixels) into 4 lanes of a zmm register\n      __m512 coef_r0 = _mm512_load_4_m128(current_coeff + filter_size * 0, current_coeff + filter_size * 4, current_coeff + filter_size * 8, current_coeff + filter_size * 12);\n      __m512 coef_r1 = _mm512_load_4_m128(current_coeff + filter_size * 1, current_coeff + filter_size * 5, current_coeff + filter_size * 9, current_coeff + filter_size * 13);\n      __m512 coef_r2 = _mm512_load_4_m128(current_coeff + filter_size * 2, current_coeff + filter_size * 6, current_coeff + filter_size * 10, current_coeff + filter_size * 14);\n      __m512 coef_r3 = _mm512_load_4_m128(current_coeff + filter_size * 3, current_coeff + filter_size * 7, current_coeff + filter_size * 11, current_coeff + filter_size * 15);\n\n      _MM_TRANSPOSE16_LANE4_PS(coef_r0, coef_r1, coef_r2, coef_r3);\n\n      // convert resampling program in H-form into permuting indexes for src transposition in V-form\n      __m512i perm_0 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x]));\n      int iStart = program->pixel_offset[x];\n      perm_0 = _mm512_sub_epi32(perm_0, _mm512_set1_epi32(iStart));\n      /* like this:\n      __m512i perm_0 = _mm512_set_epi32(\n        program->pixel_offset[x + 15] - iStart,\n        ...\n        program->pixel_offset[x + 0] - iStart);\n      */\n\n      // Taps are contiguous (0, 1, 2, 3), so we increment perm indexes by 1.\n      __m512i one_epi32 = _mm512_set1_epi32(1);\n      __m512i perm_1 = _mm512_add_epi32(perm_0, one_epi32);\n      __m512i perm_2 = _mm512_add_epi32(perm_1, one_epi32);\n      __m512i perm_3 = _mm512_add_epi32(perm_2, one_epi32);\n\n      float* AVS_RESTRICT dst_ptr = dst + x + y_from * dst_pitch;\n      const float* src_ptr = src + iStart + y_from * src_pitch; // all permute offsets relative to this start offset\n\n      // Calculate remaining pixels for bounds checking in partial_load mode\n      const int remaining = program->source_size - iStart;\n\n      for (int y = y_from; y < y_to; y++)\n      {\n        __m512 data_src, data_src2;\n\n        if constexpr (partial_load) {\n          // Safe masked loads for the image edge\n          // Load first 16 floats\n          int rem1 = std::max(0, std::min(16, remaining));\n          __mmask16 k1 = (1U << rem1) - 1;\n          data_src = _mm512_maskz_loadu_ps(k1, src_ptr);\n\n          // Load next 16 floats (offset by 16)\n          int rem2 = std::max(0, std::min(16, remaining - 16));\n          __mmask16 k2 = (1U << rem2) - 1;\n          data_src2 = _mm512_maskz_loadu_ps(k2, src_ptr + 16);\n        }\n        else {\n          // Fast unaligned loads for the safe zone\n          data_src = _mm512_loadu_ps(src_ptr);\n          data_src2 = _mm512_loadu_ps(src_ptr + 16);\n        }\n\n        __m512 data_0 = _mm512_permutex2var_ps(data_src, perm_0, data_src2);\n        __m512 data_1 = _mm512_permutex2var_ps(data_src, perm_1, data_src2);\n        __m512 data_2 = _mm512_permutex2var_ps(data_src, perm_2, data_src2);\n        __m512 data_3 = _mm512_permutex2var_ps(data_src, perm_3, data_src2);\n\n        __m512 result0 = _mm512_mul_ps(data_0, coef_r0);\n        __m512 result1 = _mm512_mul_ps(data_2, coef_r2);\n\n        result0 = _mm512_fmadd_ps(data_1, coef_r1, result0);\n        result1 = _mm512_fmadd_ps(data_3, coef_r3, result1);\n\n        _mm512_stream_ps(dst_ptr, _mm512_add_ps(result0, result1));\n\n        dst_ptr += dst_pitch;\n        src_ptr += src_pitch;\n      }\n\n      current_coeff += filter_size * 16;\n      };\n\n    // Process the 'safe zone' where direct full unaligned loads are acceptable.\n    for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)\n    {\n      do_h_float_core(std::false_type{});\n    }\n\n    // Process the potentially 'unsafe zone' near the image edge, using safe masked loading.\n    for (; x < width; x += PIXELS_AT_A_TIME)\n    {\n      do_h_float_core(std::true_type{});\n    }\n  }\n}\n\n// Similar to resize_h_planar_float_avx512_permutex_vstripe_ks4 but for kernel size up to 8\n// 16 target pixels at a time with AVX512 permutex instructions.\nvoid resize_h_planar_float_avx512_permutex_vstripe_ks8(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)\n{\n  const int filter_size = program->filter_size; // aligned, practically the coeff table stride\n\n  src_pitch /= sizeof(float);\n  dst_pitch /= sizeof(float);\n\n  float* src = (float*)src8;\n  float* dst = (float*)dst8;\n\n  constexpr int PIXELS_AT_A_TIME = 16; // Process sixteen pixels in parallel using AVX512 (4x4 using m128 lanes)\n\n  // 'source_overread_beyond_targetx' indicates if the filter kernel can read beyond the target width.\n  const int width_safe_mod = (program->safelimit_8_pixels.overread_possible ? program->safelimit_8_pixels.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  // Preconditions:\n  assert(program->filter_size_real <= 8); // We preload all relevant coefficients (up to 8) before the height loop.\n\n  // 'target_size_alignment' ensures we can safely access coefficients using offsets like\n  // 'filter_size * 15' when processing 16 H pixels at a time\n  assert(program->target_size_alignment >= 16); // Adjusted for 16 pixels\n  assert(FRAME_ALIGN >= 64); // Adjusted for 16 pixels AviSynth+ default\n\n  // Ensure that coefficient loading beyond the valid target size is safe for 4x8 float loads.\n  // n/a: load once 8. align 4 is the same as 8 for the purpose.\n  assert(program->filter_size_alignment >= 8);\n\n  const int max_scanlines = program->max_scanlines;\n\n  // Vertical stripe loop for L2 cache optimization\n  for (int y_from = 0; y_from < height; y_from += max_scanlines)\n  {\n    int y_to = std::min(y_from + max_scanlines, height);\n\n    // Reset current_coeff for the start of the stripe (points to start of row's coeffs)\n    const float* AVS_RESTRICT current_coeff = (const float* AVS_RESTRICT)program->pixel_coefficient_float;\n\n    int x = 0;\n\n    // Lambda to handle both safe (fast) and unsafe (masked/partial) loading paths\n    auto do_h_float_core = [&](auto partial_load) {\n\n      // prepare coefs in transposed V-form\n      // 4 coefficients sets (for 4 pixels) into 4 lanes of a zmm register\n      __m512 coef_r0 = _mm512_load_4_m128(current_coeff + filter_size * 0, current_coeff + filter_size * 4, current_coeff + filter_size * 8, current_coeff + filter_size * 12);\n      __m512 coef_r1 = _mm512_load_4_m128(current_coeff + filter_size * 1, current_coeff + filter_size * 5, current_coeff + filter_size * 9, current_coeff + filter_size * 13);\n      __m512 coef_r2 = _mm512_load_4_m128(current_coeff + filter_size * 2, current_coeff + filter_size * 6, current_coeff + filter_size * 10, current_coeff + filter_size * 14);\n      __m512 coef_r3 = _mm512_load_4_m128(current_coeff + filter_size * 3, current_coeff + filter_size * 7, current_coeff + filter_size * 11, current_coeff + filter_size * 15);\n\n      const float* AVS_RESTRICT current_coeff_47 = current_coeff + 4;\n\n      __m512 coef_r4 = _mm512_load_4_m128(current_coeff_47 + filter_size * 0, current_coeff_47 + filter_size * 4, current_coeff_47 + filter_size * 8, current_coeff_47 + filter_size * 12);\n      __m512 coef_r5 = _mm512_load_4_m128(current_coeff_47 + filter_size * 1, current_coeff_47 + filter_size * 5, current_coeff_47 + filter_size * 9, current_coeff_47 + filter_size * 13);\n      __m512 coef_r6 = _mm512_load_4_m128(current_coeff_47 + filter_size * 2, current_coeff_47 + filter_size * 6, current_coeff_47 + filter_size * 10, current_coeff_47 + filter_size * 14);\n      __m512 coef_r7 = _mm512_load_4_m128(current_coeff_47 + filter_size * 3, current_coeff_47 + filter_size * 7, current_coeff_47 + filter_size * 11, current_coeff_47 + filter_size * 15);\n\n      _MM_TRANSPOSE16_LANE4_PS(coef_r0, coef_r1, coef_r2, coef_r3);\n      _MM_TRANSPOSE16_LANE4_PS(coef_r4, coef_r5, coef_r6, coef_r7);\n\n      // convert resampling program in H-form into permuting indexes for src transposition in V-form\n      __m512i perm_0 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x]));\n      int iStart = program->pixel_offset[x + 0];\n      perm_0 = _mm512_sub_epi32(perm_0, _mm512_set1_epi32(iStart));\n      /* like this:\n      __m512i perm_0 = _mm512_set_epi32(\n        program->pixel_offset[x + 15] - iStart,\n        ...\n        program->pixel_offset[x + 0] - iStart);\n        */\n\n      // Taps are contiguous (0, 1, 2, 3 .. 7), so we increment perm indexes by 1.\n      __m512i one_epi32 = _mm512_set1_epi32(1);\n      __m512i perm_1 = _mm512_add_epi32(perm_0, one_epi32);\n      __m512i perm_2 = _mm512_add_epi32(perm_1, one_epi32);\n      __m512i perm_3 = _mm512_add_epi32(perm_2, one_epi32);\n      __m512i perm_4 = _mm512_add_epi32(perm_3, one_epi32);\n      __m512i perm_5 = _mm512_add_epi32(perm_4, one_epi32);\n      __m512i perm_6 = _mm512_add_epi32(perm_5, one_epi32);\n      __m512i perm_7 = _mm512_add_epi32(perm_6, one_epi32);\n\n      float* AVS_RESTRICT dst_ptr = dst + x + y_from * dst_pitch;\n      const float* src_ptr = src + iStart + y_from * src_pitch; // all permute offsets relative to this start offset\n\n      // Calculate remaining pixels for bounds checking in partial_load mode\n      const int remaining = program->source_size - iStart;\n\n      for (int y = y_from; y < y_to; y++)\n      {\n        __m512 data_src, data_src2;\n\n        if constexpr (partial_load) {\n          // Safe masked loads for the image edge\n          // Load first 16 floats\n          int rem1 = std::max(0, std::min(16, remaining));\n          __mmask16 k1 = (1U << rem1) - 1;\n          data_src = _mm512_maskz_loadu_ps(k1, src_ptr);\n\n          // Load next 16 floats (offset by 16)\n          int rem2 = std::max(0, std::min(16, remaining - 16));\n          __mmask16 k2 = (1U << rem2) - 1;\n          data_src2 = _mm512_maskz_loadu_ps(k2, src_ptr + 16);\n        }\n        else {\n          // Fast unaligned loads for the safe zone\n          data_src = _mm512_loadu_ps(src_ptr);\n          data_src2 = _mm512_loadu_ps(src_ptr + 16);\n        }\n\n        __m512 data_0 = _mm512_permutex2var_ps(data_src, perm_0, data_src2);\n        __m512 data_1 = _mm512_permutex2var_ps(data_src, perm_1, data_src2);\n        __m512 data_2 = _mm512_permutex2var_ps(data_src, perm_2, data_src2);\n        __m512 data_3 = _mm512_permutex2var_ps(data_src, perm_3, data_src2);\n        __m512 data_4 = _mm512_permutex2var_ps(data_src, perm_4, data_src2);\n        __m512 data_5 = _mm512_permutex2var_ps(data_src, perm_5, data_src2);\n        __m512 data_6 = _mm512_permutex2var_ps(data_src, perm_6, data_src2);\n        __m512 data_7 = _mm512_permutex2var_ps(data_src, perm_7, data_src2);\n\n        __m512 result0 = _mm512_mul_ps(data_0, coef_r0);\n        __m512 result1 = _mm512_mul_ps(data_2, coef_r2);\n        __m512 result2 = _mm512_mul_ps(data_4, coef_r4);\n        __m512 result3 = _mm512_mul_ps(data_6, coef_r6);\n\n        result0 = _mm512_fmadd_ps(data_1, coef_r1, result0);\n        result1 = _mm512_fmadd_ps(data_3, coef_r3, result1);\n        result2 = _mm512_fmadd_ps(data_5, coef_r5, result2);\n        result3 = _mm512_fmadd_ps(data_7, coef_r7, result3);\n\n        __m512 result01 = _mm512_add_ps(result0, result1);\n        __m512 result23 = _mm512_add_ps(result2, result3);\n        __m512 result0123 = _mm512_add_ps(result01, result23);\n        _mm512_stream_ps(dst_ptr, result0123);\n\n        dst_ptr += dst_pitch;\n        src_ptr += src_pitch;\n      }\n\n      current_coeff += filter_size * 16;\n      };\n\n    // Process the 'safe zone' where direct full unaligned loads are acceptable.\n    for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)\n    {\n      do_h_float_core(std::false_type{});\n    }\n\n    // Process the potentially 'unsafe zone' near the image edge, using safe masked loading.\n    for (; x < width; x += PIXELS_AT_A_TIME)\n    {\n      do_h_float_core(std::true_type{});\n    }\n  }\n}\n\n\n// Similar to resize_h_planar_float_avx512_permutex_vstripe_ks4 but for kernel size up to \n// 16 target pixels at a time with AVX512 permutex instructions.\n// Uses 2 groups of 8 output samples processing by independednd gathering 2x32 contigous groups of sources to support more downscale ratios\nvoid resize_h_planar_float_avx512_permutex_vstripe_2s8_ks8(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)\n{\n  const int filter_size = program->filter_size; // aligned, practically the coeff table stride\n\n  src_pitch /= sizeof(float);\n  dst_pitch /= sizeof(float);\n\n  float* src = (float*)src8;\n  float* dst = (float*)dst8;\n\n  constexpr int PIXELS_AT_A_TIME = 16; // Process 2 groups of 8 pixels in parallel using AVX512 with wider source gathering for downsample\n\n  // 'source_overread_beyond_targetx' indicates if the filter kernel can read beyond the target width.\n  const int width_safe_mod = (program->safelimit_8_pixels.overread_possible ? program->safelimit_8_pixels.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  // Preconditions:\n  assert(program->filter_size_real <= 8); // We preload all relevant coefficients (up to 8) before the height loop.\n\n  // 'target_size_alignment' ensures we can safely access coefficients using offsets like\n  // 'filter_size * 15' when processing 16 H pixels at a time\n  assert(program->target_size_alignment >= 16); // Adjusted for 16 pixels\n  assert(FRAME_ALIGN >= 64); // Adjusted for 16 pixels AviSynth+ default\n\n  // Ensure that coefficient loading beyond the valid target size is safe for 4x8 float loads.\n  assert(program->filter_size_alignment >= 8);\n  // n/a: load once 8. align 4 is the same as 8 for the purpose.\n\n  const int max_scanlines = program->max_scanlines;\n\n  // Vertical stripe loop for L2 cache optimization\n  for (int y_from = 0; y_from < height; y_from += max_scanlines)\n  {\n    int y_to = std::min(y_from + max_scanlines, height);\n\n    // Reset current_coeff for the start of the stripe (points to start of row's coeffs)\n    const float* AVS_RESTRICT current_coeff = (const float* AVS_RESTRICT)program->pixel_coefficient_float;\n\n    int x = 0;\n\n    // Lambda to handle both safe (fast) and unsafe (masked/partial) loading paths\n    auto do_h_float_core = [&](auto partial_load) {\n\n      // prepare coefs in transposed V-form\n      // 4 coefficients sets (for 4 pixels) into 4 lanes of a zmm register\n      __m512 coef_r0 = _mm512_load_4_m128(current_coeff + filter_size * 0, current_coeff + filter_size * 4, current_coeff + filter_size * 8, current_coeff + filter_size * 12);\n      __m512 coef_r1 = _mm512_load_4_m128(current_coeff + filter_size * 1, current_coeff + filter_size * 5, current_coeff + filter_size * 9, current_coeff + filter_size * 13);\n      __m512 coef_r2 = _mm512_load_4_m128(current_coeff + filter_size * 2, current_coeff + filter_size * 6, current_coeff + filter_size * 10, current_coeff + filter_size * 14);\n      __m512 coef_r3 = _mm512_load_4_m128(current_coeff + filter_size * 3, current_coeff + filter_size * 7, current_coeff + filter_size * 11, current_coeff + filter_size * 15);\n\n      const float* AVS_RESTRICT current_coeff_47 = current_coeff + 4;\n\n      __m512 coef_r4 = _mm512_load_4_m128(current_coeff_47 + filter_size * 0, current_coeff_47 + filter_size * 4, current_coeff_47 + filter_size * 8, current_coeff_47 + filter_size * 12);\n      __m512 coef_r5 = _mm512_load_4_m128(current_coeff_47 + filter_size * 1, current_coeff_47 + filter_size * 5, current_coeff_47 + filter_size * 9, current_coeff_47 + filter_size * 13);\n      __m512 coef_r6 = _mm512_load_4_m128(current_coeff_47 + filter_size * 2, current_coeff_47 + filter_size * 6, current_coeff_47 + filter_size * 10, current_coeff_47 + filter_size * 14);\n      __m512 coef_r7 = _mm512_load_4_m128(current_coeff_47 + filter_size * 3, current_coeff_47 + filter_size * 7, current_coeff_47 + filter_size * 11, current_coeff_47 + filter_size * 15);\n\n      _MM_TRANSPOSE16_LANE4_PS(coef_r0, coef_r1, coef_r2, coef_r3);\n      _MM_TRANSPOSE16_LANE4_PS(coef_r4, coef_r5, coef_r6, coef_r7);\n\n      // convert resampling program in H-form into permuting indexes for src transposition in V-form\n      // shorter SIMD-way - single memory load (hacky SIMD load from int vector ?)\n      __m512i perm_0_low8 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x]));\n      int iStart_low8 = program->pixel_offset[x];\n      perm_0_low8 = _mm512_sub_epi32(perm_0_low8, _mm512_set1_epi32(iStart_low8)); // vpbroadcastd zmm, r32\n\n      __m512i perm_0_high8 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 8]));\n      int iStart_high8 = program->pixel_offset[x + 8];\n      perm_0_high8 = _mm512_sub_epi32(perm_0_high8, _mm512_set1_epi32(iStart_high8)); // vpbroadcastd zmm, r32\n      perm_0_high8 = _mm512_inserti64x4(perm_0_high8, _mm512_castsi512_si256(perm_0_high8), 1);// shift low 8 epi32 to high 8\n      \n      const __mmask16 k_high8 = _mm512_int2mask(0xFF00);\n      __m512i perm_0 = _mm512_mask_blend_epi32(k_high8, perm_0_low8, perm_0_high8); \n\n      float* AVS_RESTRICT dst_ptr = dst + x + y_from * dst_pitch;\n      const float* src_ptr_low8 = src + iStart_low8 + y_from * src_pitch; // all permute offsets relative to this start offset\n      const float* src_ptr_high8 = src + iStart_high8 + y_from * src_pitch; // all permute offsets relative to this start offset\n\n      // Calculate remaining pixels for bounds checking in partial_load mode\n      const int remaining_low8 = program->source_size - iStart_low8;\n      const int remaining_high8 = program->source_size - iStart_high8;\n\n      int rem1_low8 = std::max(0, std::min(16, remaining_low8));\n      __mmask16 k1_low8 = (1U << rem1_low8) - 1;\n      int rem2 = std::max(0, std::min(16, remaining_low8 - 16));\n      __mmask16 k2_low8 = (1U << rem2) - 1;\n      int rem1_high8 = std::max(0, std::min(16, remaining_high8));\n      __mmask16 k1_high8 = (1U << rem1_high8) - 1;\n      int rem2_high8 = std::max(0, std::min(16, remaining_high8 - 16));\n      __mmask16 k2_high8 = (1U << rem2_high8) - 1;\n\n      // Taps are contiguous (0, 1, 2, 3 .. 7), so we increment perm indexes by 1.\n      const __m512i one_epi32 = _mm512_set1_epi32(1);\n      const __m512i perm_1 = _mm512_add_epi32(perm_0, one_epi32);\n      const __m512i perm_2 = _mm512_add_epi32(perm_1, one_epi32);\n      const __m512i perm_3 = _mm512_add_epi32(perm_2, one_epi32);\n      const __m512i perm_4 = _mm512_add_epi32(perm_3, one_epi32);\n      const __m512i perm_5 = _mm512_add_epi32(perm_4, one_epi32);\n      const __m512i perm_6 = _mm512_add_epi32(perm_5, one_epi32);\n      const __m512i perm_7 = _mm512_add_epi32(perm_6, one_epi32);\n\n      for (int y = y_from; y < y_to; y++)\n      {\n        __m512 data_src_low8, data_src2_low8;\n        __m512 data_src_high8, data_src2_high8;\n\n        if constexpr (partial_load) {\n          // Safe masked loads for the image edge\n          // Load first 16 floats\n          data_src_low8 = _mm512_maskz_loadu_ps(k1_low8, src_ptr_low8);\n          // Load next 16 floats (offset by 16)\n          data_src2_low8 = _mm512_maskz_loadu_ps(k2_low8, src_ptr_low8 + 16);\n\n          // high8\n          // Safe masked loads for the image edge\n          // Load first 16 floats\n          data_src_high8 = _mm512_maskz_loadu_ps(k1_high8, src_ptr_high8);\n          // Load next 16 floats (offset by 16)\n          data_src2_high8 = _mm512_maskz_loadu_ps(k2_high8, src_ptr_high8 + 16);\n        }\n        else {\n          // Fast unaligned loads for the safe zone\n          data_src_low8 = _mm512_loadu_ps(src_ptr_low8);\n          data_src2_low8 = _mm512_loadu_ps(src_ptr_low8 + 16);\n          data_src_high8 = _mm512_loadu_ps(src_ptr_high8);\n          data_src2_high8 = _mm512_loadu_ps(src_ptr_high8 + 16);\n        }\n\n       /* __m512 data_0 = _mm512_permutex2var_ps(data_src_low8, perm_0, data_src2_low8);\n        __m512 data_0_high8 = _mm512_permutex2var_ps(data_src_high8, perm_0, data_src2_high8);\n        data_0 = _mm512_mask_blend_ps(k_high8, data_0, data_0_high8);*/\n        __m512 data_0 = _mm512_mask_blend_ps(k_high8, _mm512_permutex2var_ps(data_src_low8, perm_0, data_src2_low8), _mm512_permutex2var_ps(data_src_high8, perm_0, data_src2_high8));\n        __m512 data_1 = _mm512_mask_blend_ps(k_high8, _mm512_permutex2var_ps(data_src_low8, perm_1, data_src2_low8), _mm512_permutex2var_ps(data_src_high8, perm_1, data_src2_high8));\n        __m512 data_2 = _mm512_mask_blend_ps(k_high8, _mm512_permutex2var_ps(data_src_low8, perm_2, data_src2_low8), _mm512_permutex2var_ps(data_src_high8, perm_2, data_src2_high8));\n        __m512 data_3 = _mm512_mask_blend_ps(k_high8, _mm512_permutex2var_ps(data_src_low8, perm_3, data_src2_low8), _mm512_permutex2var_ps(data_src_high8, perm_3, data_src2_high8));\n        __m512 data_4 = _mm512_mask_blend_ps(k_high8, _mm512_permutex2var_ps(data_src_low8, perm_4, data_src2_low8), _mm512_permutex2var_ps(data_src_high8, perm_4, data_src2_high8));\n        __m512 data_5 = _mm512_mask_blend_ps(k_high8, _mm512_permutex2var_ps(data_src_low8, perm_5, data_src2_low8), _mm512_permutex2var_ps(data_src_high8, perm_5, data_src2_high8));\n        __m512 data_6 = _mm512_mask_blend_ps(k_high8, _mm512_permutex2var_ps(data_src_low8, perm_6, data_src2_low8), _mm512_permutex2var_ps(data_src_high8, perm_6, data_src2_high8));\n        __m512 data_7 = _mm512_mask_blend_ps(k_high8, _mm512_permutex2var_ps(data_src_low8, perm_7, data_src2_low8), _mm512_permutex2var_ps(data_src_high8, perm_7, data_src2_high8));\n\n        __m512 result0 = _mm512_mul_ps(data_0, coef_r0);\n        __m512 result1 = _mm512_mul_ps(data_2, coef_r2);\n        __m512 result2 = _mm512_mul_ps(data_4, coef_r4);\n        __m512 result3 = _mm512_mul_ps(data_6, coef_r6);\n\n        result0 = _mm512_fmadd_ps(data_1, coef_r1, result0);\n        result1 = _mm512_fmadd_ps(data_3, coef_r3, result1);\n        result2 = _mm512_fmadd_ps(data_5, coef_r5, result2);\n        result3 = _mm512_fmadd_ps(data_7, coef_r7, result3);\n\n        __m512 result01 = _mm512_add_ps(result0, result1);\n        __m512 result23 = _mm512_add_ps(result2, result3);\n        __m512 result0123 = _mm512_add_ps(result01, result23);\n        _mm512_stream_ps(dst_ptr, result0123); \n\n        dst_ptr += dst_pitch;\n        src_ptr_low8 += src_pitch;\n        src_ptr_high8 += src_pitch;\n      }\n\n      current_coeff += filter_size * PIXELS_AT_A_TIME;\n    };\n\n    // Process the 'safe zone' where direct full unaligned loads are acceptable.\n    for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)\n    {\n      do_h_float_core(std::false_type{});\n    }\n\n    // Process the potentially 'unsafe zone' near the image edge, using safe masked loading.\n    for (; x < width; x += PIXELS_AT_A_TIME)\n    {\n      do_h_float_core(std::true_type{});\n    }\n  }\n}\n\n\n\n// Similar to resize_h_planar_float_avx512_permutex_vstripe_ks4 but for kernel size up to 16\n// 16 target pixels at a time with AVX512 permutex instructions.\nvoid resize_h_planar_float_avx512_permutex_vstripe_ks16(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)\n{\n  const int filter_size = program->filter_size; // aligned, practically the coeff table stride\n\n  src_pitch /= sizeof(float);\n  dst_pitch /= sizeof(float);\n\n  float* src = (float*)src8;\n  float* dst = (float*)dst8;\n\n  constexpr int PIXELS_AT_A_TIME = 16; // Process sixteen pixels in parallel using AVX512 \n\n  // 'source_overread_beyond_targetx' indicates if the filter kernel can read beyond the target width.\n  const int width_safe_mod = (program->safelimit_8_pixels.overread_possible ? program->safelimit_8_pixels.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  // Preconditions:\n  assert(program->filter_size_real <= 16); // We preload all relevant coefficients (up to 8) before the height loop.\n\n  // 'target_size_alignment' ensures we can safely access coefficients using offsets like\n  // 'filter_size * 15' when processing 16 H pixels at a time\n  assert(program->target_size_alignment >= 16); // Adjusted for 16 pixels\n  assert(FRAME_ALIGN >= 64); // Adjusted for 16 pixels AviSynth+ default\n\n  // Ensure that coefficient loading beyond the valid target size is safe for 4x16 float loads.\n  // We gather_load 'short' coeffs, from 0..15. \n  // Load is unaligned, but we treat 16 coeffs.\n  // - For kernel_size 9..16 we have valid entries until 16 when filter_size_alignment==8:\n  //   alignment 8 is enough for gathering with filter_size*15 offset.\n  // - But for kernel_size 1..8 we need alignment 16 to be able to gather up to\n  //   filter_size*15 offset.\n  // This is just an extra safety; this case is called in practice between kernel sizes 9..16.\n  assert(\n    (program->filter_size_real < 8 && program->filter_size_alignment >= 16)\n    ||\n    (program->filter_size_real >= 8 && program->filter_size_alignment >= 8)\n  );\n\n  const int max_scanlines = program->max_scanlines;\n\n  // Vertical stripe loop for L2 cache optimization\n  for (int y_from = 0; y_from < height; y_from += max_scanlines)\n  {\n    int y_to = std::min(y_from + max_scanlines, height);\n\n    // Reset current_coeff for the start of the stripe (points to start of row's coeffs)\n    const float* AVS_RESTRICT current_coeff = (const float* AVS_RESTRICT)program->pixel_coefficient_float;\n\n    int x = 0;\n\n    // Lambda to handle both safe (fast) and unsafe (masked/partial) loading paths\n    auto do_h_float_core = [&](auto partial_load) {\n\n      // prepare coefs in transposed V-form, use gathering - not very slow until TRANSPOSE16_ is designed\n      // TODO: make transposed coeffs buffer in ResamplingProgram for permutex-based resizers so it can be calculated and stored once at the class constructor (or before calling of the resampling functions)\n      const __m512i one_epi32 = _mm512_set1_epi32(1);\n      __m512i offsets = _mm512_set_epi32(filter_size * 15, filter_size * 14, filter_size * 13, filter_size * 12, filter_size * 11, filter_size * 10, filter_size * 9, filter_size * 8, \\\n        filter_size * 7, filter_size * 6, filter_size * 5, filter_size * 4, filter_size * 3, filter_size * 2, filter_size * 1, filter_size * 0);\n\n      const __m512 coef_r0 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r1 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r2 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r3 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r4 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r5 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r6 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r7 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r8 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r9 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r10 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r11 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r12 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r13 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r14 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r15 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n\n      // convert resampling program in H-form into permuting indexes for src transposition in V-form\n      // shorter SIMD-way - single memory load (hacky SIMD load from int vector ?)\n      __m512i perm_0 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x]));\n      int iStart = _mm256_extract_epi32(_mm512_castsi512_si256(perm_0), 0);\n      perm_0 = _mm512_sub_epi32(perm_0, _mm512_set1_epi32(iStart)); // vpbroadcastd zmm, r32\n\n      float* AVS_RESTRICT dst_ptr = dst + x + y_from * dst_pitch;\n      const float* src_ptr = src + iStart + y_from * src_pitch; // all permute offsets relative to this start offset\n\n      // Calculate remaining pixels for bounds checking in partial_load mode\n      const int remaining = program->source_size - iStart;\n\n      int rem1 = std::max(0, std::min(16, remaining));\n      __mmask16 k1 = (1U << rem1) - 1;\n      int rem2 = std::max(0, std::min(16, remaining - 16));\n      __mmask16 k2 = (1U << rem2) - 1;\n\n      for (int y = y_from; y < y_to; y++)\n      {\n        // Taps are contiguous (0, 1, 2, 3 .. 7), so we increment perm indexes by 1.\n        // To save register usage in ks16 version - calculate offsets at runtime\n        // working indexes, reloaded from constant perm_0\n        __m512i perm_0w = perm_0;\n        __m512i perm_1w = _mm512_add_epi32(perm_0, one_epi32);\n\n        const __m512i two_epi32 = _mm512_set1_epi32(2);\n\n        __m512 data_src, data_src2;\n\n        if constexpr (partial_load) {\n          // Safe masked loads for the image edge\n          // Load first 16 floats\n          data_src = _mm512_maskz_loadu_ps(k1, src_ptr);\n          // Load next 16 floats (offset by 16)\n          data_src2 = _mm512_maskz_loadu_ps(k2, src_ptr + 16);\n        }\n        else {\n          // Fast unaligned loads for the safe zone\n          data_src = _mm512_loadu_ps(src_ptr);\n          data_src2 = _mm512_loadu_ps(src_ptr + 16);\n        }\n\n        __m512 data_0 = _mm512_permutex2var_ps(data_src, perm_0w, data_src2); // TODO: replace with shorter _mm512_mul_ps(_mm512_permutex2var_ps(data_src, perm_0w, data_src2), coef_r0);\n        __m512 data_1 = _mm512_permutex2var_ps(data_src, perm_1w, data_src2);\n\n        __m512 result0 = _mm512_mul_ps(data_0, coef_r0);\n        __m512 result1 = _mm512_mul_ps(data_1, coef_r1);\n\n        perm_0w = _mm512_add_epi32(perm_0w, two_epi32);\n        perm_1w = _mm512_add_epi32(perm_1w, two_epi32);\n\n        __m512 data_2 = _mm512_permutex2var_ps(data_src, perm_0w, data_src2); // TODO: replace with shorter result0 = _mm512_fmadd_ps(_mm512_permutex2var_ps(data_src, perm_0w, data_src2), coef_r2, result0);\n        __m512 data_3 = _mm512_permutex2var_ps(data_src, perm_1w, data_src2);\n\n        result0 = _mm512_fmadd_ps(data_2, coef_r2, result0);\n        result1 = _mm512_fmadd_ps(data_3, coef_r3, result1);\n\n        perm_0w = _mm512_add_epi32(perm_0w, two_epi32);\n        perm_1w = _mm512_add_epi32(perm_1w, two_epi32);\n\n        __m512 data_4 = _mm512_permutex2var_ps(data_src, perm_0w, data_src2);\n        __m512 data_5 = _mm512_permutex2var_ps(data_src, perm_1w, data_src2);\n\n        result0 = _mm512_fmadd_ps(data_4, coef_r4, result0);\n        result1 = _mm512_fmadd_ps(data_5, coef_r5, result1);\n\n        perm_0w = _mm512_add_epi32(perm_0w, two_epi32);\n        perm_1w = _mm512_add_epi32(perm_1w, two_epi32);\n\n        __m512 data_6 = _mm512_permutex2var_ps(data_src, perm_0w, data_src2);\n        __m512 data_7 = _mm512_permutex2var_ps(data_src, perm_1w, data_src2);\n\n        result0 = _mm512_fmadd_ps(data_6, coef_r6, result0);\n        result1 = _mm512_fmadd_ps(data_7, coef_r7, result1);\n\n        perm_0w = _mm512_add_epi32(perm_0w, two_epi32);\n        perm_1w = _mm512_add_epi32(perm_1w, two_epi32);\n\n        __m512 data_8 = _mm512_permutex2var_ps(data_src, perm_0w, data_src2);\n        __m512 data_9 = _mm512_permutex2var_ps(data_src, perm_1w, data_src2);\n\n        result0 = _mm512_fmadd_ps(data_8, coef_r8, result0);\n        result1 = _mm512_fmadd_ps(data_9, coef_r9, result1);\n\n        perm_0w = _mm512_add_epi32(perm_0w, two_epi32);\n        perm_1w = _mm512_add_epi32(perm_1w, two_epi32);\n\n        __m512 data_10 = _mm512_permutex2var_ps(data_src, perm_0w, data_src2);\n        __m512 data_11 = _mm512_permutex2var_ps(data_src, perm_1w, data_src2);\n\n        result0 = _mm512_fmadd_ps(data_10, coef_r10, result0);\n        result1 = _mm512_fmadd_ps(data_11, coef_r11, result1);\n\n        perm_0w = _mm512_add_epi32(perm_0w, two_epi32);\n        perm_1w = _mm512_add_epi32(perm_1w, two_epi32);\n\n        __m512 data_12 = _mm512_permutex2var_ps(data_src, perm_0w, data_src2);\n        __m512 data_13 = _mm512_permutex2var_ps(data_src, perm_1w, data_src2);\n\n        result0 = _mm512_fmadd_ps(data_12, coef_r12, result0);\n        result1 = _mm512_fmadd_ps(data_13, coef_r13, result1);\n\n        perm_0w = _mm512_add_epi32(perm_0w, two_epi32);\n        perm_1w = _mm512_add_epi32(perm_1w, two_epi32);\n\n        __m512 data_14 = _mm512_permutex2var_ps(data_src, perm_0w, data_src2);\n        __m512 data_15 = _mm512_permutex2var_ps(data_src, perm_1w, data_src2);\n\n        result0 = _mm512_fmadd_ps(data_14, coef_r14, result0);\n        result1 = _mm512_fmadd_ps(data_15, coef_r15, result1);\n\n        _mm512_stream_ps(dst_ptr, _mm512_add_ps(result0, result1));\n\n        dst_ptr += dst_pitch;\n        src_ptr += src_pitch;\n      }\n\n      current_coeff += filter_size * PIXELS_AT_A_TIME;\n    };\n\n    // Process the 'safe zone' where direct full unaligned loads are acceptable.\n    for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)\n    {\n      do_h_float_core(std::false_type{});\n    }\n\n    // Process the potentially 'unsafe zone' near the image edge, using safe masked loading.\n    for (; x < width; x += PIXELS_AT_A_TIME)\n    {\n      do_h_float_core(std::true_type{});\n    }\n  }\n}\n\n\n// Similar to resize_h_planar_float_avx512_permutex_vstripe_ks4 but for kernel size up to 16\n// 16 target pixels at a time with AVX512 permutex instructions.\n// Uses 2 groups of 8 output samples processing by independent gathering 2x32 contigous groups of sources to support more downscale ratios\nvoid resize_h_planar_float_avx512_permutex_vstripe_2s8_ks16(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)\n{\n  const int filter_size = program->filter_size; // aligned, practically the coeff table stride\n\n  src_pitch /= sizeof(float);\n  dst_pitch /= sizeof(float);\n\n  float* src = (float*)src8;\n  float* dst = (float*)dst8;\n\n  constexpr int PIXELS_AT_A_TIME = 16; // Process 16 pixels in parallel using AVX512 for partial downsampling works\n\n  // 'source_overread_beyond_targetx' indicates if the filter kernel can read beyond the target width.\n  const int width_safe_mod = (program->safelimit_8_pixels.overread_possible ? program->safelimit_8_pixels.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  // Preconditions:\n  assert(program->filter_size_real <= 16); // We preload all relevant coefficients (up to 8) before the height loop.\n\n  // 'target_size_alignment' ensures we can safely access coefficients using offsets like\n  // 'filter_size * 15' when processing 16 H pixels at a time\n  assert(program->target_size_alignment >= 16); // Adjusted for 16 pixels\n  assert(FRAME_ALIGN >= 64); // Adjusted for 16 pixels AviSynth+ default\n\n  // Ensure that coefficient loading beyond the valid target size is safe for 4x16 float loads.\n  // n/a: load once 16. align 8 is the same as 16 for the purpose.\n  assert(program->filter_size_alignment >= 8);\n\n  const int max_scanlines = program->max_scanlines;\n\n  // Vertical stripe loop for L2 cache optimization\n  for (int y_from = 0; y_from < height; y_from += max_scanlines)\n  {\n    int y_to = std::min(y_from + max_scanlines, height);\n\n    // Reset current_coeff for the start of the stripe (points to start of row's coeffs)\n    const float* AVS_RESTRICT current_coeff = (const float* AVS_RESTRICT)program->pixel_coefficient_float;\n\n    int x = 0;\n\n    // Lambda to handle both safe (fast) and unsafe (masked/partial) loading paths\n    auto do_h_float_core = [&](auto partial_load) {\n\n      // prepare coefs in transposed V-form, use gathering - not very slow until TRANSPOSE16_ is designed\n      // TODO: make transposed coeffs buffer in ResamplingProgram for permutex-based resizers so it can be calculated and stored once at the class constructor (or before calling of the resampling functions)\n      const __m512i one_epi32 = _mm512_set1_epi32(1);\n\n      __m512i offsets = _mm512_set_epi32(filter_size * 15, filter_size * 14, filter_size * 13, filter_size * 12, filter_size * 11, filter_size * 10, filter_size * 9, filter_size * 8, \\\n        filter_size * 7, filter_size * 6, filter_size * 5, filter_size * 4, filter_size * 3, filter_size * 2, filter_size * 1, filter_size * 0);\n\n      const __m512 coef_r0 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r1 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r2 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r3 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r4 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r5 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r6 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r7 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r8 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r9 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r10 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r11 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r12 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r13 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r14 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      offsets = _mm512_add_epi32(offsets, one_epi32);\n      const __m512 coef_r15 = _mm512_i32gather_ps(offsets, current_coeff, 4);\n\n      // convert resampling program in H-form into permuting indexes for src transposition in V-form\n      // shorter SIMD-way - single memory load (hacky SIMD load from int vector ?)\n      __m512i perm_0_low8 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x]));\n      int iStart_low8 = program->pixel_offset[x];\n      perm_0_low8 = _mm512_sub_epi32(perm_0_low8, _mm512_set1_epi32(iStart_low8)); // vpbroadcastd zmm, r32\n\n      __m512i perm_0_high8 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 8]));\n      int iStart_high8 = program->pixel_offset[x + 8];\n      perm_0_high8 = _mm512_sub_epi32(perm_0_high8, _mm512_set1_epi32(iStart_high8)); // vpbroadcastd zmm, r32\n      perm_0_high8 = _mm512_inserti64x4(perm_0_high8, _mm512_castsi512_si256(perm_0_high8), 1);// shift low 8 epi32 to high 8\n\n      const __mmask16 k_high8 = _mm512_int2mask(0xFF00);\n      const __m512i perm_0 = _mm512_mask_blend_epi32(k_high8, perm_0_low8, perm_0_high8);\n\n      float* AVS_RESTRICT dst_ptr = dst + x + y_from * dst_pitch;\n      const float* src_ptr_low8 = src + iStart_low8 + y_from * src_pitch; // all permute offsets in a first group relative to this start offset\n      const float* src_ptr_high8 = src + iStart_high8 + y_from * src_pitch; // all permute offsets in a second group relative to this start offset\n\n      // Calculate remaining pixels for bounds checking in partial_load mode\n      const int remaining_low8 = program->source_size - iStart_low8;\n      const int remaining_high8 = program->source_size - iStart_high8;\n\n      int rem1_low8 = std::max(0, std::min(16, remaining_low8));\n      __mmask16 k1_low8 = (1U << rem1_low8) - 1;\n      int rem1_high8 = std::max(0, std::min(16, remaining_high8));\n      __mmask16 k1_high8 = (1U << rem1_high8) - 1;\n\n      for (int y = y_from; y < y_to; y++)\n      {\n        // Taps are contiguous (0, 1, 2, 3 .. 7), so we increment perm indexes by 1.\n        // To save register usage in ks16 version - calculate offsets at runtime\n        // working indexes, reloaded from constant perm_0\n        __m512i perm_0w = perm_0;\n        __m512i perm_1w = _mm512_add_epi32(perm_0, one_epi32);\n\n        const __m512i two_epi32 = _mm512_set1_epi32(2);\n\n        __m512 data_src_low8, data_src2_low8;\n        __m512 data_src_high8, data_src2_high8;\n\n        if constexpr (partial_load) {\n          // Safe masked loads for the image edge\n          // Load first 16 floats\n          data_src_low8 = _mm512_maskz_loadu_ps(k1_low8, src_ptr_low8);\n\n          // Load next 16 floats (offset by 16)\n          int rem2 = std::max(0, std::min(16, remaining_low8 - 16));\n          __mmask16 k2_low8 = (1U << rem2) - 1;\n          data_src2_low8 = _mm512_maskz_loadu_ps(k2_low8, src_ptr_low8 + 16);\n\n          // high8\n          // Safe masked loads for the image edge\n          // Load first 16 floats\n          data_src_high8 = _mm512_maskz_loadu_ps(k1_high8, src_ptr_high8);\n\n          // Load next 16 floats (offset by 16)\n          int rem2_high8 = std::max(0, std::min(16, remaining_high8 - 16));\n          __mmask16 k2_high8 = (1U << rem2_high8) - 1;\n          data_src2_high8 = _mm512_maskz_loadu_ps(k2_high8, src_ptr_high8 + 16);\n        }\n        else {\n          // Fast unaligned loads for the safe zone\n          data_src_low8 = _mm512_loadu_ps(src_ptr_low8);\n          data_src2_low8 = _mm512_loadu_ps(src_ptr_low8 + 16);\n          data_src_high8 = _mm512_loadu_ps(src_ptr_high8);\n          data_src2_high8 = _mm512_loadu_ps(src_ptr_high8 + 16);\n        }\n\n        __m512 data_0 = _mm512_mask_blend_ps(k_high8, _mm512_permutex2var_ps(data_src_low8, perm_0w, data_src2_low8), _mm512_permutex2var_ps(data_src_high8, perm_0w, data_src2_high8));\n        __m512 data_1 = _mm512_mask_blend_ps(k_high8, _mm512_permutex2var_ps(data_src_low8, perm_1w, data_src2_low8), _mm512_permutex2var_ps(data_src_high8, perm_1w, data_src2_high8));\n\n        __m512 result0 = _mm512_mul_ps(data_0, coef_r0);\n        __m512 result1 = _mm512_mul_ps(data_1, coef_r1);\n\n        perm_0w = _mm512_add_epi32(perm_0w, two_epi32);\n        perm_1w = _mm512_add_epi32(perm_1w, two_epi32);\n\n        __m512 data_2 = _mm512_mask_blend_ps(k_high8, _mm512_permutex2var_ps(data_src_low8, perm_0w, data_src2_low8), _mm512_permutex2var_ps(data_src_high8, perm_0w, data_src2_high8));\n        __m512 data_3 = _mm512_mask_blend_ps(k_high8, _mm512_permutex2var_ps(data_src_low8, perm_1w, data_src2_low8), _mm512_permutex2var_ps(data_src_high8, perm_1w, data_src2_high8));\n\n        result0 = _mm512_fmadd_ps(data_2, coef_r2, result0);\n        result1 = _mm512_fmadd_ps(data_3, coef_r3, result1);\n\n        perm_0w = _mm512_add_epi32(perm_0w, two_epi32);\n        perm_1w = _mm512_add_epi32(perm_1w, two_epi32);\n\n        __m512 data_4 = _mm512_mask_blend_ps(k_high8, _mm512_permutex2var_ps(data_src_low8, perm_0w, data_src2_low8), _mm512_permutex2var_ps(data_src_high8, perm_0w, data_src2_high8));\n        __m512 data_5 = _mm512_mask_blend_ps(k_high8, _mm512_permutex2var_ps(data_src_low8, perm_1w, data_src2_low8), _mm512_permutex2var_ps(data_src_high8, perm_1w, data_src2_high8));\n\n        result0 = _mm512_fmadd_ps(data_4, coef_r4, result0);\n        result1 = _mm512_fmadd_ps(data_5, coef_r5, result1);\n\n        perm_0w = _mm512_add_epi32(perm_0w, two_epi32);\n        perm_1w = _mm512_add_epi32(perm_1w, two_epi32);\n\n        __m512 data_6 = _mm512_mask_blend_ps(k_high8, _mm512_permutex2var_ps(data_src_low8, perm_0w, data_src2_low8), _mm512_permutex2var_ps(data_src_high8, perm_0w, data_src2_high8));\n        __m512 data_7 = _mm512_mask_blend_ps(k_high8, _mm512_permutex2var_ps(data_src_low8, perm_1w, data_src2_low8), _mm512_permutex2var_ps(data_src_high8, perm_1w, data_src2_high8));\n\n        result0 = _mm512_fmadd_ps(data_6, coef_r6, result0);\n        result1 = _mm512_fmadd_ps(data_7, coef_r7, result1);\n\n        perm_0w = _mm512_add_epi32(perm_0w, two_epi32);\n        perm_1w = _mm512_add_epi32(perm_1w, two_epi32);\n\n        __m512 data_8 = _mm512_mask_blend_ps(k_high8, _mm512_permutex2var_ps(data_src_low8, perm_0w, data_src2_low8), _mm512_permutex2var_ps(data_src_high8, perm_0w, data_src2_high8));\n        __m512 data_9 = _mm512_mask_blend_ps(k_high8, _mm512_permutex2var_ps(data_src_low8, perm_1w, data_src2_low8), _mm512_permutex2var_ps(data_src_high8, perm_1w, data_src2_high8));\n\n        result0 = _mm512_fmadd_ps(data_8, coef_r8, result0);\n        result1 = _mm512_fmadd_ps(data_9, coef_r9, result1);\n\n        perm_0w = _mm512_add_epi32(perm_0w, two_epi32);\n        perm_1w = _mm512_add_epi32(perm_1w, two_epi32);\n\n        __m512 data_10 = _mm512_mask_blend_ps(k_high8, _mm512_permutex2var_ps(data_src_low8, perm_0w, data_src2_low8), _mm512_permutex2var_ps(data_src_high8, perm_0w, data_src2_high8));\n        __m512 data_11 = _mm512_mask_blend_ps(k_high8, _mm512_permutex2var_ps(data_src_low8, perm_1w, data_src2_low8), _mm512_permutex2var_ps(data_src_high8, perm_1w, data_src2_high8));\n\n        result0 = _mm512_fmadd_ps(data_10, coef_r10, result0);\n        result1 = _mm512_fmadd_ps(data_11, coef_r11, result1);\n\n        perm_0w = _mm512_add_epi32(perm_0w, two_epi32);\n        perm_1w = _mm512_add_epi32(perm_1w, two_epi32);\n\n        __m512 data_12 = _mm512_mask_blend_ps(k_high8, _mm512_permutex2var_ps(data_src_low8, perm_0w, data_src2_low8), _mm512_permutex2var_ps(data_src_high8, perm_0w, data_src2_high8));\n        __m512 data_13 = _mm512_mask_blend_ps(k_high8, _mm512_permutex2var_ps(data_src_low8, perm_1w, data_src2_low8), _mm512_permutex2var_ps(data_src_high8, perm_1w, data_src2_high8));\n\n        result0 = _mm512_fmadd_ps(data_12, coef_r12, result0);\n        result1 = _mm512_fmadd_ps(data_13, coef_r13, result1);\n\n        perm_0w = _mm512_add_epi32(perm_0w, two_epi32);\n        perm_1w = _mm512_add_epi32(perm_1w, two_epi32);\n\n        __m512 data_14 = _mm512_mask_blend_ps(k_high8, _mm512_permutex2var_ps(data_src_low8, perm_0w, data_src2_low8), _mm512_permutex2var_ps(data_src_high8, perm_0w, data_src2_high8));\n        __m512 data_15 = _mm512_mask_blend_ps(k_high8, _mm512_permutex2var_ps(data_src_low8, perm_1w, data_src2_low8), _mm512_permutex2var_ps(data_src_high8, perm_1w, data_src2_high8));\n\n        result0 = _mm512_fmadd_ps(data_14, coef_r14, result0);\n        result1 = _mm512_fmadd_ps(data_15, coef_r15, result1);\n\n        _mm512_stream_ps(dst_ptr, _mm512_add_ps(result0, result1)); \n\n        dst_ptr += dst_pitch;\n        src_ptr_low8 += src_pitch;\n        src_ptr_high8 += src_pitch;\n      }\n\n      current_coeff += filter_size * PIXELS_AT_A_TIME;\n    };\n\n    // Process the 'safe zone' where direct full unaligned loads are acceptable.\n    for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)\n    {\n      do_h_float_core(std::false_type{});\n    }\n\n    // Process the potentially 'unsafe zone' near the image edge, using safe masked loading.\n    for (; x < width; x += PIXELS_AT_A_TIME)\n    {\n      do_h_float_core(std::true_type{});\n    }\n  }\n}\n\n\n//-------- 512 bit float Verticals\n\n// base version, no horizontal unrolling\nvoid resize_v_avx512_planar_float(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel)\n{\n  AVS_UNUSED(bits_per_pixel);\n\n  const int filter_size = program->filter_size;\n  const float* AVS_RESTRICT current_coeff = program->pixel_coefficient_float;\n\n  const float* src = (const float*)src8;\n  float* AVS_RESTRICT dst = (float*)dst8;\n  dst_pitch = dst_pitch / sizeof(float);\n  src_pitch = src_pitch / sizeof(float);\n\n  const int kernel_size = program->filter_size_real; // not the aligned\n  const int kernel_size_mod2 = (kernel_size / 2) * 2; // Process pairs of rows for better efficiency\n  const bool notMod2 = kernel_size_mod2 < kernel_size;\n\n  for (int y = 0; y < target_height; y++) {\n    int offset = program->pixel_offset[y];\n    const float* src_ptr = src + offset * src_pitch;\n\n    // 64 byte 16 floats (AVX512 register holds 16 floats)\n    // no need for wmod8, alignment is safe 32 bytes at least - is it safe for 64 bytes ?\n    for (int x = 0; x < width; x += 16) {\n      __m512 result_single = _mm512_setzero_ps();\n      __m512 result_single_2 = _mm512_setzero_ps();\n\n      const float* AVS_RESTRICT src2_ptr = src_ptr + x; // __restrict here\n\n      // Process pairs of rows for better efficiency (2 coeffs/cycle)\n      // two result variables for potential parallel operation\n      int i = 0;\n      for (; i < kernel_size_mod2; i += 2) {\n        __m512 coeff_even = _mm512_set1_ps(current_coeff[i]);\n        __m512 coeff_odd = _mm512_set1_ps(current_coeff[i + 1]);\n\n        __m512 src_even = _mm512_load_ps(src2_ptr);\n        __m512 src_odd = _mm512_load_ps(src2_ptr + src_pitch);\n\n        result_single = _mm512_fmadd_ps(src_even, coeff_even, result_single);\n        result_single_2 = _mm512_fmadd_ps(src_odd, coeff_odd, result_single_2);\n\n        src2_ptr += 2 * src_pitch;\n      }\n\n      result_single = _mm512_add_ps(result_single, result_single_2);\n\n      // Process the last odd row if needed\n      if (notMod2) {\n        __m512 coeff = _mm512_set1_ps(current_coeff[i]);\n        __m512 src_val = _mm512_load_ps(src2_ptr);\n        result_single = _mm512_fmadd_ps(src_val, coeff, result_single);\n      }\n\n      _mm512_stream_ps(dst + x, result_single);\n    }\n\n    dst += dst_pitch;\n    current_coeff += filter_size;\n  }\n}\n\n// memory-optimized version of resize_v_avx512_planar_float\nvoid resize_v_avx512_planar_float_w_sr(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel)\n{\n  AVS_UNUSED(bits_per_pixel);\n\n  const int filter_size = program->filter_size;\n  const float* AVS_RESTRICT current_coeff = (const float* AVS_RESTRICT)program->pixel_coefficient_float;\n\n  const float* src = (const float*)src8;\n  float* AVS_RESTRICT dst = (float*)dst8;\n\n  const int dst_stride_float = dst_pitch / sizeof(float);\n  const int src_stride_float = src_pitch / sizeof(float);\n\n  const int kernel_size = program->filter_size_real;\n  // Pre-calculate Mod2 size for the remainder loop\n  const int kernel_size_mod2 = (kernel_size / 2) * 2;\n  const bool notMod2 = kernel_size_mod2 < kernel_size;\n\n  for (int y = 0; y < target_height; y++) {\n    int offset = program->pixel_offset[y];\n    const float* src_row_start = src + offset * src_stride_float;\n\n    int x = 0;\n\n    // -----------------------------------------------------------------------\n    // 128 pixels (512 bytes) per iteration\n    // Uses ~17 ZMM registers. Safe for x64 (32 regs available).\n    // Provides 8 independent dependency chains to hide FMA latency.\n    // -----------------------------------------------------------------------\n    const int width_mod128 = (width / 128) * 128;\n    for (; x < width_mod128; x += 128) {\n      __m512 result_1 = _mm512_setzero_ps();\n      __m512 result_2 = _mm512_setzero_ps();\n      __m512 result_3 = _mm512_setzero_ps();\n      __m512 result_4 = _mm512_setzero_ps();\n      __m512 result_5 = _mm512_setzero_ps();\n      __m512 result_6 = _mm512_setzero_ps();\n      __m512 result_7 = _mm512_setzero_ps();\n      __m512 result_8 = _mm512_setzero_ps();\n\n      const float* AVS_RESTRICT src2_ptr = src_row_start + x;\n\n      for (int i = 0; i < kernel_size; i++) {\n        __m512 coeff = _mm512_set1_ps(current_coeff[i]);\n\n        // Loading 512 bytes contiguous memory (8 cache lines)\n        __m512 src_1 = _mm512_load_ps(src2_ptr);       // 0..15\n        __m512 src_2 = _mm512_load_ps(src2_ptr + 16);  // 16..31 (offset in floats)\n        __m512 src_3 = _mm512_load_ps(src2_ptr + 32);\n        __m512 src_4 = _mm512_load_ps(src2_ptr + 48);\n        __m512 src_5 = _mm512_load_ps(src2_ptr + 64);\n        __m512 src_6 = _mm512_load_ps(src2_ptr + 80);\n        __m512 src_7 = _mm512_load_ps(src2_ptr + 96);\n        __m512 src_8 = _mm512_load_ps(src2_ptr + 112);\n\n        result_1 = _mm512_fmadd_ps(src_1, coeff, result_1);\n        result_2 = _mm512_fmadd_ps(src_2, coeff, result_2);\n        result_3 = _mm512_fmadd_ps(src_3, coeff, result_3);\n        result_4 = _mm512_fmadd_ps(src_4, coeff, result_4);\n        result_5 = _mm512_fmadd_ps(src_5, coeff, result_5);\n        result_6 = _mm512_fmadd_ps(src_6, coeff, result_6);\n        result_7 = _mm512_fmadd_ps(src_7, coeff, result_7);\n        result_8 = _mm512_fmadd_ps(src_8, coeff, result_8);\n\n        src2_ptr += src_stride_float;\n      }\n\n      _mm512_stream_ps(dst + x, result_1);\n      _mm512_stream_ps(dst + x + 16, result_2);\n      _mm512_stream_ps(dst + x + 32, result_3);\n      _mm512_stream_ps(dst + x + 48, result_4);\n      _mm512_stream_ps(dst + x + 64, result_5);\n      _mm512_stream_ps(dst + x + 80, result_6);\n      _mm512_stream_ps(dst + x + 96, result_7);\n      _mm512_stream_ps(dst + x + 112, result_8);\n    }\n\n    // -----------------------------------------------------------------------\n    // 64 pixels per iteration\n    // -----------------------------------------------------------------------\n    const int width_mod64 = (width / 64) * 64;\n    for (; x < width_mod64; x += 64) {\n      __m512 result_1 = _mm512_setzero_ps();\n      __m512 result_2 = _mm512_setzero_ps();\n      __m512 result_3 = _mm512_setzero_ps();\n      __m512 result_4 = _mm512_setzero_ps();\n\n      const float* AVS_RESTRICT src2_ptr = src_row_start + x;\n\n      for (int i = 0; i < kernel_size; i++) {\n        __m512 coeff = _mm512_set1_ps(current_coeff[i]);\n\n        __m512 src_1 = _mm512_load_ps(src2_ptr);\n        __m512 src_2 = _mm512_load_ps(src2_ptr + 16);\n        __m512 src_3 = _mm512_load_ps(src2_ptr + 32);\n        __m512 src_4 = _mm512_load_ps(src2_ptr + 48);\n\n        result_1 = _mm512_fmadd_ps(src_1, coeff, result_1);\n        result_2 = _mm512_fmadd_ps(src_2, coeff, result_2);\n        result_3 = _mm512_fmadd_ps(src_3, coeff, result_3);\n        result_4 = _mm512_fmadd_ps(src_4, coeff, result_4);\n\n        src2_ptr += src_stride_float;\n      }\n\n      _mm512_stream_ps(dst + x, result_1);\n      _mm512_stream_ps(dst + x + 16, result_2);\n      _mm512_stream_ps(dst + x + 32, result_3);\n      _mm512_stream_ps(dst + x + 48, result_4);\n    }\n\n    // -----------------------------------------------------------------------\n    // 32 pixels per iteration\n    // -----------------------------------------------------------------------\n    const int width_mod32 = (width / 32) * 32;\n    for (; x < width_mod32; x += 32) {\n      __m512 result_1 = _mm512_setzero_ps();\n      __m512 result_2 = _mm512_setzero_ps();\n\n      const float* AVS_RESTRICT src2_ptr = src_row_start + x;\n\n      for (int i = 0; i < kernel_size; i++) {\n        __m512 coeff = _mm512_set1_ps(current_coeff[i]);\n\n        __m512 src_1 = _mm512_load_ps(src2_ptr);\n        __m512 src_2 = _mm512_load_ps(src2_ptr + 16);\n\n        result_1 = _mm512_fmadd_ps(src_1, coeff, result_1);\n        result_2 = _mm512_fmadd_ps(src_2, coeff, result_2);\n\n        src2_ptr += src_stride_float;\n      }\n\n      _mm512_stream_ps(dst + x, result_1);\n      _mm512_stream_ps(dst + x + 16, result_2);\n    }\n\n    // -----------------------------------------------------------------------\n    // Remainder loop (16 pixels)\n    // Uses vertical loop unrolling (pairs of taps) to hide FMA latency\n    // because we don't have enough horizontal data to do it spatially.\n    // -----------------------------------------------------------------------\n    const int src_stride_2 = src_stride_float * 2;\n\n    for (; x < width; x += 16) {\n      __m512 result_single = _mm512_setzero_ps();\n      __m512 result_single_2 = _mm512_setzero_ps();\n\n      const float* AVS_RESTRICT src2_ptr = src_row_start + x;\n      int i = 0;\n\n      // Process pairs of rows\n      for (; i < kernel_size_mod2; i += 2) {\n        __m512 coeff_even = _mm512_set1_ps(current_coeff[i]);\n        __m512 coeff_odd = _mm512_set1_ps(current_coeff[i + 1]);\n\n        __m512 src_even = _mm512_load_ps(src2_ptr);\n        __m512 src_odd = _mm512_load_ps(src2_ptr + src_stride_float);\n\n        result_single = _mm512_fmadd_ps(src_even, coeff_even, result_single);\n        result_single_2 = _mm512_fmadd_ps(src_odd, coeff_odd, result_single_2);\n\n        src2_ptr += src_stride_2;\n      }\n\n      result_single = _mm512_add_ps(result_single, result_single_2);\n\n      // Process the last odd row if needed\n      if (notMod2) {\n        __m512 coeff = _mm512_set1_ps(current_coeff[i]);\n        __m512 src_val = _mm512_load_ps(src2_ptr);\n        result_single = _mm512_fmadd_ps(src_val, coeff, result_single);\n      }\n\n      _mm512_stream_ps(dst + x, result_single);\n    }\n\n    dst += dst_stride_float;\n    current_coeff += filter_size;\n  }\n}\n\n// uint8_t\nvoid resize_v_avx512_planar_uint8_t_w_sr(BYTE* AVS_RESTRICT dst, const BYTE* src, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel)\n{\n  AVS_UNUSED(bits_per_pixel);\n  int filter_size = program->filter_size;\n  const short* AVS_RESTRICT current_coeff = program->pixel_coefficient;\n  __m512i rounder = _mm512_set1_epi32(1 << (FPScale8bits - 1));\n  __m512i zero = _mm512_setzero_si512();\n\n  const int kernel_size = program->filter_size_real; // not the aligned\n\n  const int width_mod128 = (width / 128) * 128;\n\n  const __m512i perm_idx1 = _mm512_set_epi64(8 + 5, 8 + 4, 8 + 1, 8 + 0, 5, 4, 1, 0);\n  const __m512i perm_idx2 = _mm512_set_epi64(8 + 7, 8 + 6, 8 + 3, 8 + 2, 7, 6, 3, 2);\n\n  for (int y = 0; y < target_height; y++) {\n    int offset = program->pixel_offset[y];\n    const BYTE* AVS_RESTRICT src_ptr = src + offset * src_pitch;\n\n    for (int x = 0; x < width_mod128; x += 128) {\n\n      __m512i result_lo = rounder;\n      __m512i result_hi = rounder;\n      __m512i result_lo2 = rounder;\n      __m512i result_hi2 = rounder;\n\n      __m512i result_lo_2 = rounder;\n      __m512i result_hi_2 = rounder;\n      __m512i result_lo2_2 = rounder;\n      __m512i result_hi2_2 = rounder;\n\n      const uint8_t* AVS_RESTRICT src2_ptr = src_ptr + x;\n\n      int i = 0;\n      // 128 byte 128 pixel\n      for (; i < kernel_size; i++) {\n        // Broadcast a single coefficients\n        __m512i coeff = _mm512_set1_epi16(*reinterpret_cast<const short*>(current_coeff + i)); // 0|co|0|co|0|co|0|co   0|co|0|co|0|co|0|co\n\n        __m512i src_1_1 = _mm512_cvtepu8_epi16(_mm256_load_si256(reinterpret_cast<const __m256i*>(src2_ptr))); // 32x 8->16bit pixels\n        __m512i src_1_2 = _mm512_cvtepu8_epi16(_mm256_load_si256(reinterpret_cast<const __m256i*>(src2_ptr + 32))); // 32x 8->16bit pixels\n        __m512i src_2_1 = _mm512_cvtepu8_epi16(_mm256_load_si256(reinterpret_cast<const __m256i*>(src2_ptr + 64))); // 32x 8->16bit pixels\n        __m512i src_2_2 = _mm512_cvtepu8_epi16(_mm256_load_si256(reinterpret_cast<const __m256i*>(src2_ptr + 96))); // 32x 8->16bit pixels\n\n        __m512i src_lo = _mm512_unpacklo_epi16(src_1_1, zero);\n        __m512i src_hi = _mm512_unpackhi_epi16(src_1_1, zero);\n        __m512i src_lo2 = _mm512_unpacklo_epi16(src_1_2, zero);\n        __m512i src_hi2 = _mm512_unpackhi_epi16(src_1_2, zero);\n\n        __m512i src_lo_2 = _mm512_unpacklo_epi16(src_2_1, zero);\n        __m512i src_hi_2 = _mm512_unpackhi_epi16(src_2_1, zero);\n        __m512i src_lo2_2 = _mm512_unpacklo_epi16(src_2_2, zero);\n        __m512i src_hi2_2 = _mm512_unpackhi_epi16(src_2_2, zero);\n\n        result_lo = _mm512_add_epi32(result_lo, _mm512_madd_epi16(src_lo, coeff)); // a*b + c\n        result_hi = _mm512_add_epi32(result_hi, _mm512_madd_epi16(src_hi, coeff)); // a*b + c\n        result_lo2 = _mm512_add_epi32(result_lo2, _mm512_madd_epi16(src_lo2, coeff)); // a*b + c\n        result_hi2 = _mm512_add_epi32(result_hi2, _mm512_madd_epi16(src_hi2, coeff)); // a*b + c\n\n        result_lo_2 = _mm512_add_epi32(result_lo_2, _mm512_madd_epi16(src_lo_2, coeff)); // a*b + c\n        result_hi_2 = _mm512_add_epi32(result_hi_2, _mm512_madd_epi16(src_hi_2, coeff)); // a*b + c\n        result_lo2_2 = _mm512_add_epi32(result_lo2_2, _mm512_madd_epi16(src_lo2_2, coeff)); // a*b + c\n        result_hi2_2 = _mm512_add_epi32(result_hi2_2, _mm512_madd_epi16(src_hi2_2, coeff)); // a*b + c\n\n        src2_ptr += src_pitch;\n\n      }\n\n      // scale back, store\n      // shift back integer arithmetic 14 bits precision\n      result_lo = _mm512_srai_epi32(result_lo, FPScale8bits);\n      result_hi = _mm512_srai_epi32(result_hi, FPScale8bits);\n      result_lo2 = _mm512_srai_epi32(result_lo2, FPScale8bits);\n      result_hi2 = _mm512_srai_epi32(result_hi2, FPScale8bits);\n\n      result_lo_2 = _mm512_srai_epi32(result_lo_2, FPScale8bits);\n      result_hi_2 = _mm512_srai_epi32(result_hi_2, FPScale8bits);\n      result_lo2_2 = _mm512_srai_epi32(result_lo2_2, FPScale8bits);\n      result_hi2_2 = _mm512_srai_epi32(result_hi2_2, FPScale8bits);\n\n      __m512i result_2x8x_uint16 = _mm512_packus_epi32(result_lo, result_hi);\n      __m512i result2_2x8x_uint16 = _mm512_packus_epi32(result_lo2, result_hi2);\n\n      __m512i result_2x8x_uint16_2 = _mm512_packus_epi32(result_lo_2, result_hi_2);\n      __m512i result2_2x8x_uint16_2 = _mm512_packus_epi32(result_lo2_2, result_hi2_2);\n\n      __m512i pack_1 = _mm512_permutex2var_epi64(result_2x8x_uint16, perm_idx1, result2_2x8x_uint16);\n      __m512i pack_2 = _mm512_permutex2var_epi64(result_2x8x_uint16, perm_idx2, result2_2x8x_uint16);\n\n      __m512i pack_1_2 = _mm512_permutex2var_epi64(result_2x8x_uint16_2, perm_idx1, result2_2x8x_uint16_2);\n      __m512i pack_2_2 = _mm512_permutex2var_epi64(result_2x8x_uint16_2, perm_idx2, result2_2x8x_uint16_2);\n\n      __m512i res = _mm512_packus_epi16(pack_1, pack_2);\n      __m512i res_2 = _mm512_packus_epi16(pack_1_2, pack_2_2);\n\n      _mm512_store_si512(reinterpret_cast<__m512i*>(dst + x), res);\n      _mm512_store_si512(reinterpret_cast<__m512i*>(dst + x + 64), res_2);\n\n    }\n\n    // 64 byte 64 pixel\n    // no need wmod16, alignment is safe at least 32\n    for (int x = width_mod128; x < width; x += 64) {\n\n      __m512i result_lo = rounder;\n      __m512i result_hi = rounder;\n\n      __m512i result_lo2 = rounder;\n      __m512i result_hi2 = rounder;\n\n      const uint8_t* AVS_RESTRICT src2_ptr = src_ptr + x;\n\n      int i = 0;\n      for (; i < kernel_size; i++) {\n        // Broadcast a single coefficients\n        __m512i coeff = _mm512_set1_epi16(*reinterpret_cast<const short*>(current_coeff + i)); // 0|co|0|co|0|co|0|co   0|co|0|co|0|co|0|co\n\n        __m512i src_1_1 = _mm512_cvtepu8_epi16(_mm256_load_si256(reinterpret_cast<const __m256i*>(src2_ptr))); // 32x 8->16bit pixels\n        __m512i src_1_2 = _mm512_cvtepu8_epi16(_mm256_load_si256(reinterpret_cast<const __m256i*>(src2_ptr + 32))); // 32x 8->16bit pixels\n\n        __m512i src_lo = _mm512_unpacklo_epi16(src_1_1, zero);\n        __m512i src_hi = _mm512_unpackhi_epi16(src_1_1, zero);\n\n        __m512i src_lo2 = _mm512_unpacklo_epi16(src_1_2, zero);\n        __m512i src_hi2 = _mm512_unpackhi_epi16(src_1_2, zero);\n\n        result_lo = _mm512_add_epi32(result_lo, _mm512_madd_epi16(src_lo, coeff)); // a*b + c\n        result_hi = _mm512_add_epi32(result_hi, _mm512_madd_epi16(src_hi, coeff)); // a*b + c\n\n        result_lo2 = _mm512_add_epi32(result_lo2, _mm512_madd_epi16(src_lo2, coeff)); // a*b + c\n        result_hi2 = _mm512_add_epi32(result_hi2, _mm512_madd_epi16(src_hi2, coeff)); // a*b + c\n\n        src2_ptr += src_pitch;\n\n      }\n\n      // scale back, store\n      // shift back integer arithmetic 14 bits precision\n      result_lo = _mm512_srai_epi32(result_lo, FPScale8bits);\n      result_hi = _mm512_srai_epi32(result_hi, FPScale8bits);\n\n      result_lo2 = _mm512_srai_epi32(result_lo2, FPScale8bits);\n      result_hi2 = _mm512_srai_epi32(result_hi2, FPScale8bits);\n\n      __m512i result_2x8x_uint16 = _mm512_packus_epi32(result_lo, result_hi);\n      __m512i result_2x8x_uint16_2 = _mm512_packus_epi32(result_lo2, result_hi2);\n\n      __m512i pack_1 = _mm512_permutex2var_epi64(result_2x8x_uint16, perm_idx1, result_2x8x_uint16_2);\n      __m512i pack_2 = _mm512_permutex2var_epi64(result_2x8x_uint16, perm_idx2, result_2x8x_uint16_2);\n\n      __m512i res = _mm512_packus_epi16(pack_1, pack_2);\n\n      _mm512_stream_si512(reinterpret_cast<__m512i*>(dst + x), res);\n\n    }\n\n    dst += dst_pitch;\n    current_coeff += filter_size;\n  }\n}\n\n//uint16_t\ntemplate<bool lessthan16bit>\nvoid resize_v_avx512_planar_uint16_t_w_sr(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel)\n{\n  int filter_size = program->filter_size;\n  const short* AVS_RESTRICT current_coeff = program->pixel_coefficient;\n\n  const __m512i zero = _mm512_setzero_si512();\n\n  const int width_mod64 = (width / 64) * 64;\n\n  // for 16 bits only\n  const __m512i shifttosigned = _mm512_set1_epi16(-32768);\n  const __m512i shiftfromsigned = _mm512_set1_epi32(32768 << FPScale16bits);\n\n  const __m512i rounder = _mm512_set1_epi32(1 << (FPScale16bits - 1));\n\n  const uint16_t* src = (uint16_t*)src8;\n  uint16_t* AVS_RESTRICT dst = (uint16_t * AVS_RESTRICT)dst8;\n  dst_pitch = dst_pitch / sizeof(uint16_t);\n  src_pitch = src_pitch / sizeof(uint16_t);\n\n  const int kernel_size = program->filter_size_real; // not the aligned\n\n  const int limit = (1 << bits_per_pixel) - 1;\n  __m512i clamp_limit = _mm512_set1_epi16((short)limit); // clamp limit for <16 bits\n\n  for (int y = 0; y < target_height; y++) {\n    int offset = program->pixel_offset[y];\n    const uint16_t* src_ptr = src + offset * src_pitch;\n\n    // 128 byte 32 word\n    for (int x = 0; x < width_mod64; x += 64) {\n\n      __m512i result_lo = rounder;\n      __m512i result_hi = rounder;\n\n      __m512i result_lo_2 = rounder;\n      __m512i result_hi_2 = rounder;\n\n      const uint16_t* AVS_RESTRICT src2_ptr = src_ptr + x;\n\n      int i = 0;\n      for (; i < kernel_size; i++) {\n        // Broadcast a single coefficients\n        __m512i coeff = _mm512_set1_epi16(current_coeff[i]); // 0|co|0|co|0|co|0|co   0|co|0|co|0|co|0|co\n\n        __m512i src = _mm512_load_si512(reinterpret_cast<const __m512i*>(src2_ptr)); // 32x 16bit pixels\n        __m512i src_2 = _mm512_load_si512(reinterpret_cast<const __m512i*>(src2_ptr + 32)); // 32x 16bit pixels\n\n        if constexpr (!lessthan16bit) {\n          src = _mm512_add_epi16(src, shifttosigned);\n          src_2 = _mm512_add_epi16(src_2, shifttosigned);\n        }\n\n        __m512i src_lo = _mm512_unpacklo_epi16(src, zero);\n        __m512i src_hi = _mm512_unpackhi_epi16(src, zero);\n\n        __m512i src_lo_2 = _mm512_unpacklo_epi16(src_2, zero);\n        __m512i src_hi_2 = _mm512_unpackhi_epi16(src_2, zero);\n\n        result_lo = _mm512_add_epi32(result_lo, _mm512_madd_epi16(src_lo, coeff)); // a*b + c\n        result_hi = _mm512_add_epi32(result_hi, _mm512_madd_epi16(src_hi, coeff)); // a*b + c\n\n        result_lo_2 = _mm512_add_epi32(result_lo_2, _mm512_madd_epi16(src_lo_2, coeff)); // a*b + c\n        result_hi_2 = _mm512_add_epi32(result_hi_2, _mm512_madd_epi16(src_hi_2, coeff)); // a*b + c\n\n        src2_ptr += src_pitch;\n      }\n\n      if constexpr (!lessthan16bit) {\n        result_lo = _mm512_add_epi32(result_lo, shiftfromsigned);\n        result_hi = _mm512_add_epi32(result_hi, shiftfromsigned);\n\n        result_lo_2 = _mm512_add_epi32(result_lo_2, shiftfromsigned);\n        result_hi_2 = _mm512_add_epi32(result_hi_2, shiftfromsigned);\n\n      }\n      // shift back integer arithmetic 13 bits precision\n      result_lo = _mm512_srai_epi32(result_lo, FPScale16bits);\n      result_hi = _mm512_srai_epi32(result_hi, FPScale16bits);\n\n      result_lo_2 = _mm512_srai_epi32(result_lo_2, FPScale16bits);\n      result_hi_2 = _mm512_srai_epi32(result_hi_2, FPScale16bits);\n\n      __m512i result_2x8x_uint16 = _mm512_packus_epi32(result_lo, result_hi);\n      __m512i result_2x8x_uint16_2 = _mm512_packus_epi32(result_lo_2, result_hi_2);\n      if constexpr (lessthan16bit) {\n        result_2x8x_uint16 = _mm512_min_epu16(result_2x8x_uint16, clamp_limit); // extra clamp for 10-14 bit\n        result_2x8x_uint16_2 = _mm512_min_epu16(result_2x8x_uint16_2, clamp_limit); // extra clamp for 10-14 bit\n      }\n      _mm512_store_si512(reinterpret_cast<__m512i*>(dst + x), result_2x8x_uint16);\n      _mm512_store_si512(reinterpret_cast<__m512i*>(dst + x + 32), result_2x8x_uint16_2);\n    }\n\n    // last 32\n    // 64 byte 32 word\n    for (int x = width_mod64; x < width; x += 32) {\n\n      __m512i result_lo = rounder;\n      __m512i result_hi = rounder;\n\n      const uint16_t* AVS_RESTRICT src2_ptr = src_ptr + x;\n\n      int i = 0;\n      for (; i < kernel_size; i++) {\n        // Broadcast a single coefficients\n        __m512i coeff = _mm512_set1_epi16(current_coeff[i]); // 0|co|0|co|0|co|0|co   0|co|0|co|0|co|0|co\n\n        __m512i src = _mm512_load_si512(reinterpret_cast<const __m512i*>(src2_ptr)); // 32x 16bit pixels\n        if constexpr (!lessthan16bit) {\n          src = _mm512_add_epi16(src, shifttosigned);\n        }\n        __m512i src_lo = _mm512_unpacklo_epi16(src, zero);\n        __m512i src_hi = _mm512_unpackhi_epi16(src, zero);\n        result_lo = _mm512_add_epi32(result_lo, _mm512_madd_epi16(src_lo, coeff)); // a*b + c\n        result_hi = _mm512_add_epi32(result_hi, _mm512_madd_epi16(src_hi, coeff)); // a*b + c\n\n        src2_ptr += src_pitch;\n      }\n\n      if constexpr (!lessthan16bit) {\n        result_lo = _mm512_add_epi32(result_lo, shiftfromsigned);\n        result_hi = _mm512_add_epi32(result_hi, shiftfromsigned);\n      }\n      // shift back integer arithmetic 13 bits precision\n      result_lo = _mm512_srai_epi32(result_lo, FPScale16bits);\n      result_hi = _mm512_srai_epi32(result_hi, FPScale16bits);\n\n      __m512i result_2x8x_uint16 = _mm512_packus_epi32(result_lo, result_hi);\n      if constexpr (lessthan16bit) {\n        result_2x8x_uint16 = _mm512_min_epu16(result_2x8x_uint16, clamp_limit); // extra clamp for 10-14 bit\n      }\n      _mm512_stream_si512(reinterpret_cast<__m512i*>(dst + x), result_2x8x_uint16);\n\n    }\n\n    dst += dst_pitch;\n    current_coeff += filter_size;\n  }\n}\n\n// avx512 16\ntemplate void resize_v_avx512_planar_uint16_t_w_sr<false>(BYTE* dst0, const BYTE* src0, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel);\n// avx512 10-14bit\ntemplate void resize_v_avx512_planar_uint16_t_w_sr<true>(BYTE* dst0, const BYTE* src0, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel);\n\n//----------------------- generic horizontal avx512 float\n\n// AVX512 Horizontal float\n\n// Three helpers, each for processing 4 target pixels from 16, 8 and 4 source pixel/coeff pairs.\n\n// Helper, _mm256_zextps128_ps256 exists only in AVX512 VL\n// zero-extend 128-bit float vector to 256-bit float vector\nAVS_FORCEINLINE static __m256 _mm256_zextps128_ps256_simul_avx(__m128 a)\n{\n  // Flags defines by MSVC at /AVX512 mode\n  // other flags: __AVX512F__, __AVX512CD__, __AVX512VL__, __AVX512BW__, __AVX512DQ__\n#ifdef __AVX512VL__\n  return _mm256_zextps128_ps256(a);\n#else\n  __m256 zero_v = _mm256_setzero_ps();\n  return _mm256_insertf128_ps(zero_v, a, 0);\n#endif\n}\n\n// 4 target pixels, each from 16 source pixel/coeff pair\n// Called only when accessing 16 source pixels and coefficients at a time is safe\nAVS_FORCEINLINE static void process_pix4_coeff16_h_float_core_512(\n  const float* src,\n  int begin1, int begin2, int begin3, int begin4,\n  const float* current_coeff,\n  int filter_size,\n  __m512& result1, __m512& result2, __m512& result3, __m512& result4)\n{\n  // 16 source floats for each of the four beginning source offsets\n  __m512 data_1 = _mm512_loadu_ps(src + begin1);\n  __m512 data_2 = _mm512_loadu_ps(src + begin2);\n  __m512 data_3 = _mm512_loadu_ps(src + begin3);\n  __m512 data_4 = _mm512_loadu_ps(src + begin4);\n\n  // 16 coefficients for each of the four output pixels\n  __m512 coeff_1 = _mm512_loadu_ps(current_coeff);               // 16 coeffs for pixel 1\n  __m512 coeff_2 = _mm512_loadu_ps(current_coeff + 1 * filter_size); // 16 coeffs for pixel 2\n  __m512 coeff_3 = _mm512_loadu_ps(current_coeff + 2 * filter_size); // 16 coeffs for pixel 3\n  __m512 coeff_4 = _mm512_loadu_ps(current_coeff + 3 * filter_size); // 16 coeffs for pixel 4\n\n  // multiply and accumulate\n  result1 = _mm512_fmadd_ps(data_1, coeff_1, result1);\n  result2 = _mm512_fmadd_ps(data_2, coeff_2, result2);\n  result3 = _mm512_fmadd_ps(data_3, coeff_3, result3);\n  result4 = _mm512_fmadd_ps(data_4, coeff_4, result4);\n}\n\n// 4 target pixels, each from 8 source pixel/coeff pair\n// Called only when accessing 8 source pixels and coefficients at a time is safe\nAVS_FORCEINLINE static void process_pix4_coeff8_h_float_core(\n  const float* src,\n  int begin1, int begin2, int begin3, int begin4,\n  const float* current_coeff,\n  int filter_size,\n  __m256& result1, __m256& result2, __m256& result3, __m256& result4)\n{\n  // Load 8 source floats for each of the four beginning source offsets\n  // Load 8 coefficients for each of the four output pixels\n  __m256 data_1 = _mm256_loadu_ps(src + begin1);\n  __m256 coeff_1 = _mm256_load_ps(current_coeff);                    // 8 coeffs for pixel 1\n  result1 = _mm256_fmadd_ps(data_1, coeff_1, result1);\n\n  __m256 data_2 = _mm256_loadu_ps(src + begin2);\n  __m256 coeff_2 = _mm256_load_ps(current_coeff + 1 * filter_size); // 8 coeffs for pixel 2\n  result2 = _mm256_fmadd_ps(data_2, coeff_2, result2);\n\n  __m256 data_3 = _mm256_loadu_ps(src + begin3);\n  __m256 coeff_3 = _mm256_load_ps(current_coeff + 2 * filter_size); // 8 coeffs for pixel 3\n  result3 = _mm256_fmadd_ps(data_3, coeff_3, result3);\n\n  __m256 data_4 = _mm256_loadu_ps(src + begin4);\n  __m256 coeff_4 = _mm256_load_ps(current_coeff + 3 * filter_size); // 8 coeffs for pixel 4\n  result4 = _mm256_fmadd_ps(data_4, coeff_4, result4);\n}\n\n// 4 target pixels, each from 4 source pixel/coeff pair.\n// Called only for first iteration when results are not initialized.\n// Otherwise same as process_pix4_coeff8_h_float_core.\nAVS_FORCEINLINE static void process_pix4_coeff4_h_float_core_first(\n  const float* src,\n  int begin1, int begin2, int begin3, int begin4,\n  const float* current_coeff,\n  int filter_size,\n  __m256& result1, __m256& result2, __m256& result3, __m256& result4)\n{\n  // Pixel 1: Load, Multiply, and Zero-Extend to __m256\n  __m128 data_1 = _mm_loadu_ps(src + begin1);\n  __m128 coeff_1 = _mm_load_ps(current_coeff);\n  __m128 mul_result1 = _mm_mul_ps(data_1, coeff_1);\n  result1 = _mm256_zextps128_ps256(mul_result1); // Sets upper 128 bits to zero\n\n  // Pixel 2: Load, Multiply, and Zero-Extend to __m256\n  __m128 data_2 = _mm_loadu_ps(src + begin2);\n  __m128 coeff_2 = _mm_load_ps(current_coeff + 1 * filter_size);\n  __m128 mul_result2 = _mm_mul_ps(data_2, coeff_2);\n  result2 = _mm256_zextps128_ps256(mul_result2); // Sets upper 128 bits to zero\n\n  // Pixel 3: Load, Multiply, and Zero-Extend to __m256\n  __m128 data_3 = _mm_loadu_ps(src + begin3);\n  __m128 coeff_3 = _mm_load_ps(current_coeff + 2 * filter_size);\n  __m128 mul_result3 = _mm_mul_ps(data_3, coeff_3);\n  result3 = _mm256_zextps128_ps256(mul_result3); // Sets upper 128 bits to zero\n\n  // Pixel 4: Load, Multiply, and Zero-Extend to __m256\n  __m128 data_4 = _mm_loadu_ps(src + begin4);\n  __m128 coeff_4 = _mm_load_ps(current_coeff + 3 * filter_size);\n  __m128 mul_result4 = _mm_mul_ps(data_4, coeff_4);\n  result4 = _mm256_zextps128_ps256(mul_result4); // Sets upper 128 bits to zero\n}\n\n// filtersize_hint: special: 0..4 for 4,8,16,24,32. Generic: -1\n// filter_size is an aligned value and always multiple of 8 (prerequisite)\n// Processing rules:\n// if filtersize_hint==0: filter size <=4, do one coeff4 step only\n// if filtersize_hint>=2: do 1 or 2 coeff16 steps\n// if filtersize_hint==1 or 3: do 1 coeff8 step (0*16 or 1*16 step done already)\n// if filtersize_hint==-1: unknown filter size, do 16,8 steps as possible\ntemplate<bool safe_aligned_mode, int filtersize_hint>\nAVS_FORCEINLINE static void process_four_pixels_h_float_pix4of16_ks_4_8_16(\n  const float* src_ptr,\n  int begin1, int begin2, int begin3, int begin4,\n  float* current_coeff,\n  int filter_size,\n  __m256& result1, __m256& result2, __m256& result3, __m256& result4,\n  int kernel_size)\n{\n\n  // very special case: filter size <= 4\n  if constexpr (safe_aligned_mode) {\n    if (filtersize_hint == 0) {\n      // Process 4 target pixels and 4 source pixels/coefficients at a time\n      // XMM-based loop internally, but returns __m256 with upper 128 cleared\n      // Do not assume initialized zeros in result1..4, they will be set here.\n      process_pix4_coeff4_h_float_core_first(\n        src_ptr + 0, begin1, begin2, begin3, begin4,\n        current_coeff + 0,\n        filter_size,\n        result1, result2, result3, result4);\n      return;\n    }\n  }\n\n  int i = 0;\n\n  // do by 16 coeffs until possible\n  if (filtersize_hint == -1 || filtersize_hint >= 2) {\n    __m512 result1_512 = _mm512_setzero_ps();\n    __m512 result2_512 = _mm512_setzero_ps();\n    __m512 result3_512 = _mm512_setzero_ps();\n    __m512 result4_512 = _mm512_setzero_ps();\n    const int ksmod16 = safe_aligned_mode ? (filter_size / 16 * 16) : (kernel_size / 16 * 16);\n    // Process 4 target pixels and 16 source pixels/coefficients at a time (ZMM-based loop)\n    for (; i < ksmod16; i += 16) {\n      process_pix4_coeff16_h_float_core_512(\n        src_ptr + i, begin1, begin2, begin3, begin4,\n        current_coeff + i,\n        filter_size,\n        result1_512, result2_512, result3_512, result4_512);\n    }\n    // Horizontal sum reduction from __m512 to __m256\n    result1 = _mm256_add_ps(_mm512_castps512_ps256(result1_512), _mm512_extractf32x8_ps(result1_512, 1));\n    result2 = _mm256_add_ps(_mm512_castps512_ps256(result2_512), _mm512_extractf32x8_ps(result2_512, 1));\n    result3 = _mm256_add_ps(_mm512_castps512_ps256(result3_512), _mm512_extractf32x8_ps(result3_512, 1));\n    result4 = _mm256_add_ps(_mm512_castps512_ps256(result4_512), _mm512_extractf32x8_ps(result4_512, 1));\n  }\n\n  // filter sizes 16 or 32 can return here\n  if constexpr (safe_aligned_mode && (filtersize_hint == 2 || filtersize_hint == 4)) {\n    return;\n  }\n\n  if constexpr (!safe_aligned_mode) {\n    if (i == kernel_size) return; // kernel_size is not known compile time\n  }\n\n  // When to do the coeff8 step:\n  // not safe-aligned mode: always. E.g. kernel_size == 28 -> 16 done, now 10 rest, do 8 next\n  // filtersize_hint == -1: not-compile-time known filtersize (kernel_size / 16 * 16 done, rest follows)\n  // filtersize_hint == 1 or 3: 0*16 or 1*16 done, now do 1*8\n  if (!safe_aligned_mode || filtersize_hint == -1 || filtersize_hint == 1 || filtersize_hint == 3) {\n    // 32 bytes contain 8 floats. We will use 256-bit registers (YMM).\n    const int ksmod8 = safe_aligned_mode ? (filter_size / 8 * 8) : (kernel_size / 8 * 8);\n\n    // Process 4 target pixels and 8 source pixels/coefficients at a time (YMM-based loop)\n    for (; i < ksmod8; i += 8) {\n      process_pix4_coeff8_h_float_core(\n        src_ptr + i, begin1, begin2, begin3, begin4,\n        current_coeff + i,\n        filter_size,\n        result1, result2, result3, result4);\n    }\n  }\n\n  if constexpr (!safe_aligned_mode) {\n    // Right edge case.\n    // Coeffs are zero padded, reading them is no problem.\n    // But if we read past the end of source then we can get possible NaN contamination.\n    // Handle the remainder: 1 to 7 source/coefficient elements.\n    // unaligned_kernel_size is used here, it's guaranteed that reading unaligned_kernel_size elements\n    // from any pixel_offset[] is safe and ends within the source buffer.\n    // Optional 4-2-1 processing loop.\n\n    if (i == kernel_size) return;\n\n    // --- Define Base Pointers for Source and Coefficients ---\n    const float* src_ptr1 = src_ptr + begin1;\n    const float* src_ptr2 = src_ptr + begin2;\n    const float* src_ptr3 = src_ptr + begin3;\n    const float* src_ptr4 = src_ptr + begin4;\n\n    float* current_coeff2 = current_coeff + 1 * filter_size;\n    float* current_coeff3 = current_coeff + 2 * filter_size;\n    float* current_coeff4 = current_coeff + 3 * filter_size;\n\n    const int ksmod4 = kernel_size / 4 * 4;\n\n    // -------------------------------------------------------------------\n    // Mod 4 Block (4 elements for four pixels using __m128)\n    // -------------------------------------------------------------------\n    if (i < ksmod4) {\n      // Load 4 source floats and 4 coefficients for each of the four output pixels\n      __m128 data_1 = _mm_loadu_ps(src_ptr1 + i);\n      __m128 coeff_1 = _mm_loadu_ps(current_coeff + i);\n      __m128 temp_result1 = _mm_mul_ps(data_1, coeff_1);\n\n      __m128 data_2 = _mm_loadu_ps(src_ptr2 + i);\n      __m128 coeff_2 = _mm_loadu_ps(current_coeff2 + i);\n      __m128 temp_result2 = _mm_mul_ps(data_2, coeff_2);\n\n      __m128 data_3 = _mm_loadu_ps(src_ptr3 + i);\n      __m128 coeff_3 = _mm_loadu_ps(current_coeff3 + i);\n      __m128 temp_result3 = _mm_mul_ps(data_3, coeff_3);\n\n      __m128 data_4 = _mm_loadu_ps(src_ptr4 + i);\n      __m128 coeff_4 = _mm_loadu_ps(current_coeff4 + i);\n      __m128 temp_result4 = _mm_mul_ps(data_4, coeff_4);\n\n      // --- Accumulate 128-bit results into 256-bit registers ---\n      // Note: Since we are using __m256, we must zero the high 128-bits before insertion/addition.\n\n      result1 = _mm256_add_ps(result1, _mm256_zextps128_ps256(temp_result1));\n      result2 = _mm256_add_ps(result2, _mm256_zextps128_ps256(temp_result2));\n      result3 = _mm256_add_ps(result3, _mm256_zextps128_ps256(temp_result3));\n      result4 = _mm256_add_ps(result4, _mm256_zextps128_ps256(temp_result4));\n\n      i += 4;\n      if (i == kernel_size) return;\n    }\n\n    const int ksmod2 = kernel_size / 2 * 2;\n\n    // -------------------------------------------------------------------\n    // New Mod 2 Block (2 elements for four pixels using __m128)\n    // -------------------------------------------------------------------\n    if (i < ksmod2) {\n      // We only need to load 2 elements (4 floats) for the __m128 load, \n      // but the low 2 elements of the __m128 register are used.\n      // Since we use the scalar accumulation method, we load 4, but only the \n      // first 2 elements will hold non-zero data (or load 2, and rely on \n      // the two __m128 registers to contain the result).\n\n      // Let's stick to using the low 2 elements of __m128 for 2 elements.\n\n      // Load 2 source floats and 2 coefficients for each of the four output pixels\n      __m128 data_1 = _mm_castpd_ps(_mm_load_sd(reinterpret_cast<const double*>(src_ptr1 + i))); // Load 2 floats (double)\n      __m128 coeff_1 = _mm_castpd_ps(_mm_load_sd(reinterpret_cast<const double*>(current_coeff + i)));\n      __m128 temp_result1 = _mm_mul_ps(data_1, coeff_1);\n\n      __m128 data_2 = _mm_castpd_ps(_mm_load_sd(reinterpret_cast<const double*>(src_ptr2 + i)));\n      __m128 coeff_2 = _mm_castpd_ps(_mm_load_sd(reinterpret_cast<const double*>(current_coeff2 + i)));\n      __m128 temp_result2 = _mm_mul_ps(data_2, coeff_2);\n\n      __m128 data_3 = _mm_castpd_ps(_mm_load_sd(reinterpret_cast<const double*>(src_ptr3 + i)));\n      __m128 coeff_3 = _mm_castpd_ps(_mm_load_sd(reinterpret_cast<const double*>(current_coeff3 + i)));\n      __m128 temp_result3 = _mm_mul_ps(data_3, coeff_3);\n\n      __m128 data_4 = _mm_castpd_ps(_mm_load_sd(reinterpret_cast<const double*>(src_ptr4 + i)));\n      __m128 coeff_4 = _mm_castpd_ps(_mm_load_sd(reinterpret_cast<const double*>(current_coeff4 + i)));\n      __m128 temp_result4 = _mm_mul_ps(data_4, coeff_4);\n\n      result1 = _mm256_add_ps(result1, _mm256_zextps128_ps256(temp_result1));\n      result2 = _mm256_add_ps(result2, _mm256_zextps128_ps256(temp_result2));\n      result3 = _mm256_add_ps(result3, _mm256_zextps128_ps256(temp_result3));\n      result4 = _mm256_add_ps(result4, _mm256_zextps128_ps256(temp_result4));\n\n      i += 2;\n      if (i == kernel_size) return;\n    }\n\n    // -------------------------------------------------------------------\n    // Fallback Scalar Operation (1 element remaining)\n    // -------------------------------------------------------------------\n    if (i < kernel_size) {\n\n      // Optimized scalar loop for the single remaining element\n      float final_scalar1 = src_ptr1[i] * current_coeff[i];\n      float final_scalar2 = src_ptr2[i] * current_coeff2[i];\n      float final_scalar3 = src_ptr3[i] * current_coeff3[i];\n      float final_scalar4 = src_ptr4[i] * current_coeff4[i];\n\n      __m128 s1_128 = _mm_set_ss(final_scalar1);\n      __m128 s2_128 = _mm_set_ss(final_scalar2);\n      __m128 s3_128 = _mm_set_ss(final_scalar3);\n      __m128 s4_128 = _mm_set_ss(final_scalar4);\n\n      result1 = _mm256_add_ps(result1, _mm256_zextps128_ps256(s1_128));\n      result2 = _mm256_add_ps(result2, _mm256_zextps128_ps256(s2_128));\n      result3 = _mm256_add_ps(result3, _mm256_zextps128_ps256(s3_128));\n      result4 = _mm256_add_ps(result4, _mm256_zextps128_ps256(s4_128));\n\n      // i is now equal to kernel_size (i++)\n    }\n  }\n}\n\n\ntemplate<bool is_safe, int filtersize_hint>\nAVS_FORCEINLINE static void process_sixteen_pixels_h_float_pix16_sub4_ks_4_8_16(\n  const float* src, int x, float* current_coeff_base,\n  int filter_size, // 8, 16, 24, 32 are quasi-constexpr here, others not compile-time known but still aligned to 8\n  float* dst,\n  ResamplingProgram* program)\n{\n  assert(program->filter_size_alignment >= 8);\n\n  float* current_coeff = current_coeff_base + x * filter_size;\n  const int unaligned_kernel_size = program->filter_size_real;\n  const __m256 zero256 = _mm256_setzero_ps();\n\n  // --- Block 1: Pixels 0, 1, 2, 3 ---\n  __m256 result0 = zero256;\n  __m256 result1 = zero256;\n  __m256 result2 = zero256;\n  __m256 result3 = zero256;\n\n  int begin0 = program->pixel_offset[x + 0];\n  int begin1 = program->pixel_offset[x + 1];\n  int begin2 = program->pixel_offset[x + 2];\n  int begin3 = program->pixel_offset[x + 3];\n\n  process_four_pixels_h_float_pix4of16_ks_4_8_16<is_safe, filtersize_hint>(\n    src, begin0, begin1, begin2, begin3, current_coeff, filter_size,\n    result0, result1, result2, result3, unaligned_kernel_size);\n  current_coeff += 4 * filter_size;\n\n  // --- Block 2: Pixels 4, 5, 6, 7 ---\n  __m256 result4 = zero256;\n  __m256 result5 = zero256;\n  __m256 result6 = zero256;\n  __m256 result7 = zero256;\n\n  int begin4 = program->pixel_offset[x + 4];\n  int begin5 = program->pixel_offset[x + 5];\n  int begin6 = program->pixel_offset[x + 6];\n  int begin7 = program->pixel_offset[x + 7];\n\n  process_four_pixels_h_float_pix4of16_ks_4_8_16<is_safe, filtersize_hint>(\n    src, begin4, begin5, begin6, begin7, current_coeff, filter_size,\n    result4, result5, result6, result7, unaligned_kernel_size);\n  current_coeff += 4 * filter_size;\n\n  // ---------------------------------------------------------------------------\n  // REDUCTION FOR PIXELS 0-7 (Result256_low)\n  // ---------------------------------------------------------------------------\n\n  // Round 1: Reduce pairs (8 vectors -> 4 vectors)\n  __m256 sum01 = _mm256_hadd_ps(result0, result1);\n  __m256 sum23 = _mm256_hadd_ps(result2, result3);\n  __m256 sum45 = _mm256_hadd_ps(result4, result5);\n  __m256 sum67 = _mm256_hadd_ps(result6, result7);\n\n  // Round 2: Reduce quads (4 vectors -> 2 vectors)\n  __m256 sum0123 = _mm256_hadd_ps(sum01, sum23);\n  __m256 sum4567 = _mm256_hadd_ps(sum45, sum67);\n\n  // Round 3: Final Merge (Add Lower 128-bit to Upper 128-bit)\n  __m128 lo_0123 = _mm256_castps256_ps128(sum0123);\n  __m128 lo_4567 = _mm256_castps256_ps128(sum4567);\n  __m256 result_lo = _mm256_insertf128_ps(_mm256_castps128_ps256(lo_0123), lo_4567, 1);\n\n  __m128 hi_0123 = _mm256_extractf128_ps(sum0123, 1);\n  __m128 hi_4567 = _mm256_extractf128_ps(sum4567, 1);\n  __m256 result_hi = _mm256_insertf128_ps(_mm256_castps128_ps256(hi_0123), hi_4567, 1);\n\n  // Assemble the Low 256-bit result (Pixels 0-7)\n  __m256 result256_low = _mm256_add_ps(result_lo, result_hi);\n\n\n  // --- Block 3: Pixels 8, 9, 10, 11 ---\n  __m256 result8 = zero256;\n  __m256 result9 = zero256;\n  __m256 result10 = zero256;\n  __m256 result11 = zero256;\n\n  int begin8 = program->pixel_offset[x + 8];\n  int begin9 = program->pixel_offset[x + 9];\n  int begin10 = program->pixel_offset[x + 10];\n  int begin11 = program->pixel_offset[x + 11];\n\n  process_four_pixels_h_float_pix4of16_ks_4_8_16<is_safe, filtersize_hint>(\n    src, begin8, begin9, begin10, begin11, current_coeff, filter_size,\n    result8, result9, result10, result11, unaligned_kernel_size);\n  current_coeff += 4 * filter_size;\n\n  // --- Block 4: Pixels 12, 13, 14, 15 ---\n  __m256 result12 = zero256;\n  __m256 result13 = zero256;\n  __m256 result14 = zero256;\n  __m256 result15 = zero256;\n\n  int begin12 = program->pixel_offset[x + 12];\n  int begin13 = program->pixel_offset[x + 13];\n  int begin14 = program->pixel_offset[x + 14];\n  int begin15 = program->pixel_offset[x + 15];\n\n  process_four_pixels_h_float_pix4of16_ks_4_8_16<is_safe, filtersize_hint>(\n    src, begin12, begin13, begin14, begin15, current_coeff, filter_size,\n    result12, result13, result14, result15, unaligned_kernel_size);\n\n\n  // ---------------------------------------------------------------------------\n  // REDUCTION FOR PIXELS 8-15 (Result256_high)\n  // ---------------------------------------------------------------------------\n\n  // Round 1: Reduce pairs (8 vectors -> 4 vectors)\n  __m256 sum89 = _mm256_hadd_ps(result8, result9);\n  __m256 sum1011 = _mm256_hadd_ps(result10, result11);\n  __m256 sum1213 = _mm256_hadd_ps(result12, result13);\n  __m256 sum1415 = _mm256_hadd_ps(result14, result15);\n\n  // Round 2: Reduce quads (4 vectors -> 2 vectors)\n  __m256 sum8_11 = _mm256_hadd_ps(sum89, sum1011);\n  __m256 sum12_15 = _mm256_hadd_ps(sum1213, sum1415);\n\n  // Round 3: Final Merge (Add Lower 128-bit to Upper 128-bit)\n  __m128 lo_8_11 = _mm256_castps256_ps128(sum8_11);\n  __m128 lo_12_15 = _mm256_castps256_ps128(sum12_15);\n  __m256 result_lo_high = _mm256_insertf128_ps(_mm256_castps128_ps256(lo_8_11), lo_12_15, 1);\n\n  __m128 hi_8_11 = _mm256_extractf128_ps(sum8_11, 1);\n  __m128 hi_12_15 = _mm256_extractf128_ps(sum12_15, 1);\n  __m256 result_hi_high = _mm256_insertf128_ps(_mm256_castps128_ps256(hi_8_11), hi_12_15, 1);\n\n  // Assemble the High 256-bit result (Pixels 8-15)\n  __m256 result256_high = _mm256_add_ps(result_lo_high, result_hi_high);\n\n  // ---------------------------------------------------------------------------\n  // Stream the two 256-bit results\n  // ---------------------------------------------------------------------------\n  _mm256_stream_ps(reinterpret_cast<float*>(dst + x), result256_low);\n  _mm256_stream_ps(reinterpret_cast<float*>(dst + x + 8), result256_high);\n}\n\n// filtersizealigned8: special: 0, 1..4, Generic : -1\ntemplate<int filtersize_hint>\nstatic void internal_resizer_h_avx512_generic_float_pix16_sub4_ks_4_8_16(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  AVS_UNUSED(bits_per_pixel);\n  // filter_size is aligned to 8 (prerequisite), contrary that we have a special case for filter size <=4\n\n  // We note that when template is used, filter_size is quasi-constexpr if filtersize_hint != -1.\n  // When filtersize_hint == -1, then program->filter_size is aligned to 8 anyway, but not known at compile time.\n  const int filter_size =\n    filtersize_hint == 0 ? 8 : // though we'll optimize for 4 internally, coeff buffer is still allocated for 8\n    (filtersize_hint >= 1) ? filtersize_hint * 8 : program->filter_size; // this latter is always aligned to 8 as well\n\n  const float* src = (float*)src8;\n  float* dst = (float*)dst8;\n  dst_pitch = dst_pitch / sizeof(float);\n  src_pitch = src_pitch / sizeof(float);\n\n  constexpr int PIXELS_AT_A_TIME = 16;\n  // Align safe zone to 16 pixels\n  const int w_safe_mod16 = (program->safelimit_16_pixels.overread_possible ? program->safelimit_16_pixels.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  for (int y = 0; y < height; y++) {\n    float* current_coeff_base = program->pixel_coefficient_float;\n\n    // Process safe aligned pixels\n    for (int x = 0; x < w_safe_mod16; x += PIXELS_AT_A_TIME) {\n      process_sixteen_pixels_h_float_pix16_sub4_ks_4_8_16<true, filtersize_hint>(src, x, current_coeff_base, filter_size, dst, program);\n    }\n\n    // Process up to the actual kernel size (unsafe zone)\n    for (int x = w_safe_mod16; x < width; x += PIXELS_AT_A_TIME) {\n      process_sixteen_pixels_h_float_pix16_sub4_ks_4_8_16<false, filtersize_hint>(src, x, current_coeff_base, filter_size, dst, program);\n    }\n\n    dst += dst_pitch;\n    src += src_pitch;\n  }\n}\n\n// Winner implementation: resizer_h_avx512_generic_float_pix16_sub4_ks_4_8_16;\n// Other variants kept for reference, speed tested.\n// Main test dimensions: pixels per cycle: 8,16,32 (pixX); sub-loops: 2,4,8 (subX); aligned filter sizes (ksX): 4, 8,16\n// resizer_h_avx512_generic_float_pix8_sub8_ks16;\n// resizer_h_avx512_generic_float_pix16_sub16_ks8;\n// resizer_h_avx512_generic_float_pix32_sub8_ks8;\n// resizer_h_avx2_generic_float_pix8_sub2_ks8; // like AVX2 version resizer_h_avx2_generic_float\n// resizer_h_avx512_generic_float_pix8_sub2_ks8; // like AVX2 version with minor differences\n// resizer_h_avx512_generic_float_pix8_sub4_ks8;\n// resizer_h_avx512_generic_float_pix16_sub4_ks4;\n// resizer_h_avx512_generic_float_pix16_sub4_ks8;\n\n// Features of the chosen implementation:\n// - 16 pixels per cycle\n// - sub-loop 4 pixels per loop\n// - filter size is aligned to 8 (prerequisite)\n// - Special cases for aligned filter sizes 4,8,16,24,32\n// - Depending on the filter size, calculates in chunks of 16, then 8, then 4 source pixels and coeffs at a time.\nvoid resizer_h_avx512_generic_float_pix16_sub4_ks_4_8_16(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  const int filter_size = program->filter_size;\n  // Expected alignment\n  assert(program->filter_size_alignment >= 8);\n\n  // Dispatcher template now supports filter_size aligned to 8 (8, 16, 24, 32) and a special case for <=4\n  // Larger filter sizes will use the generic method (-1) which still benefit from 16-8-4 coeff processing blocks.\n  if (filter_size == 1 * 8)\n    if (program->filter_size_real <= 4)\n      internal_resizer_h_avx512_generic_float_pix16_sub4_ks_4_8_16<0>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel); // Internally optimized for 4\n    else\n      internal_resizer_h_avx512_generic_float_pix16_sub4_ks_4_8_16<1>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel); // Internally optimized for 8\n  else if (filter_size == 2 * 8) // Internally optimized for 16\n    internal_resizer_h_avx512_generic_float_pix16_sub4_ks_4_8_16<2>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else if (filter_size == 3 * 8) // Internally optimized for 16+8\n    internal_resizer_h_avx512_generic_float_pix16_sub4_ks_4_8_16<3>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else if (filter_size == 4 * 8) // Internally optimized for 2*16\n    internal_resizer_h_avx512_generic_float_pix16_sub4_ks_4_8_16<4>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n  else // -1: basic method, use program->filter_size, internally optimized for calculating coeffs in N*16 + 8 + 4 + 2 + 1 blocks\n    internal_resizer_h_avx512_generic_float_pix16_sub4_ks_4_8_16<-1>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\n\n// Horizontals uint8\n\n\n\n\n/*\nThe core of these function moved into resample_avx512.hpp because of dual BASE and CPUF_AVX512_FAST requirement.\n*/\n\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_ks4_base(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  // false template parameter: BASE version, no VBMI\n  resize_h_planar_uint8_avx512_permutex_vstripe_ks4_internal<false>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\n\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_ks8_base(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  // false template parameter: BASE version, no VBMI\n  resize_h_planar_uint8_avx512_permutex_vstripe_ks8_internal<false>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\n\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_2s32_ks8_base(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  // false template parameter: BASE version, no VBMI\n  resize_h_planar_uint8_avx512_permutex_vstripe_2s32_ks8_internal<false>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\n\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_ks16_base(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  // false template parameter: BASE version, no VBMI\n  resize_h_planar_uint8_avx512_permutex_vstripe_ks16_internal<false>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\n\n// Horizontals uint16\n\n// filter size up to 4\n// 32 target uint16_t pixels at a time\n// 128-byte source loads (64 uint16_t pixels)\n// maximum permute index is 64 for _mm512_permutex2var_epi16 (uint16_t)\ntemplate<bool lessthan16bit>\nvoid resize_h_planar_uint16_avx512_permutex_vstripe_ks4(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)\n{\n  const int filter_size = program->filter_size; // aligned, practically the coeff table stride\n\n  const uint16_t* src = (uint16_t*)src8;\n  uint16_t* AVS_RESTRICT dst = (uint16_t* AVS_RESTRICT)dst8;\n  dst_pitch = dst_pitch / sizeof(uint16_t);\n  src_pitch = src_pitch / sizeof(uint16_t);\n\n  constexpr int PIXELS_AT_A_TIME = 32;\n\n  // 'source_overread_beyond_targetx' indicates if the filter kernel can read beyond the target width.\n  // we load 2x32 source uint16_t pixels at a time, so ensure safe overread if needed.\n  // Our main loop processes calculates for 32 target pixels at a time.\n  // Inside that, we load 64 source uint16_t pixels (2x32) to be able to permutex from that.\n  // This we have to check at each mod-PIXELS_AT_A_TIME boundary, the allowance of 64-element source load.\n  const int width_safe_mod = (program->safelimit_64_pixels_each32th_target.overread_possible ? program->safelimit_64_pixels_each32th_target.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  // Preconditions:\n  assert(program->filter_size_real <= 4); // We preload all relevant coefficients (up to 4) before the height loop.\n\n  // 'target_size_alignment' ensures we can safely access coefficients using offsets like\n  // 'filter_size * 31' when processing 32 source H pixels at a time\n  assert(program->target_size_alignment >= 32); // source-offset starts for 32 target pixels, 32 coeff strides\n  assert(FRAME_ALIGN >= 64); // storing 32x2 uint16_t at a time\n\n  // Ensure that coefficient loading beyond the valid target size is safe for 4 coeffs\n  // We load 4x16bit coeffs at a time\n  assert(program->filter_size_alignment >= 4);\n\n  const int max_scanlines = program->max_scanlines;\n\n  // for 16 bits only\n  const __m512i shifttosigned = _mm512_set1_epi16(-32768);\n  const __m512i shiftfromsigned = _mm512_set1_epi32(32768 << FPScale16bits);\n\n  const int limit = (1 << bits_per_pixel) - 1;\n  // only used when template lessthan16bit is true\n  __m512i clamp_limit = _mm512_set1_epi16((short)limit); // clamp limit for <16 bits\n\n  __m512i rounder = _mm512_set1_epi32(1 << (FPScale16bits - 1));\n\n  // Vertical stripe loop for L2 cache optimization\n  for (int y_from = 0; y_from < height; y_from += max_scanlines)\n  {\n    int y_to = std::min(y_from + max_scanlines, height);\n\n    // Reset current_coeff for the start of the stripe (points to start of row's coeffs)\n    const short* AVS_RESTRICT current_coeff = program->pixel_coefficient;\n\n    int x = 0;\n\n    // Lambda to handle both safe (fast) and unsafe (masked/partial) loading paths\n    auto do_h_integer_core = [&](auto partial_load) {\n\n      // prepare coefs in transposed V-form\n      // 32 source pixels, 32 coeff strides\n      // TODO: make storage in transposed form, 64 x uint16 transposition looks too slow\n      // TO FIX: filter_size=4 resize uses filter_size=16 - lots or RAM/cache wasted, in the ready to use transposed form it will be much more optimized\n\n      // 4coefs of 16bit is 64bits, can be loaded as set_epi64 ?\n      __m512i coef_0_7 = _mm512_setr_epi64(\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 0),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 1),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 2),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 3),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 4),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 5),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 6),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 7)\n      );\n\n      __m512i coef_8_15 = _mm512_setr_epi64(\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 8),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 9),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 10),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 11),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 12),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 13),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 14),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 15)\n      );\n\n      __m512i coef_16_23 = _mm512_setr_epi64(\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 16),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 17),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 18),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 19),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 20),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 21),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 22),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 23)\n      );\n\n      __m512i coef_24_31 = _mm512_setr_epi64(\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 24),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 25),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 26),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 27),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 28),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 29),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 30),\n        *reinterpret_cast<const long long*>(current_coeff + filter_size * 31)\n      );\n\n      // Transpose with permutex\n      __m512i c_perm_0 = _mm512_set_epi16(\n        28 + 32, 24 + 32, 20 + 32, 16 + 32, 12 + 32, 8 + 32, 4 + 32, 0 + 32, 28, 24, 20, 16, 12, 8, 4, 0,\n        28 + 32, 24 + 32, 20 + 32, 16 + 32, 12 + 32, 8 + 32, 4 + 32, 0 + 32, 28, 24, 20, 16, 12, 8, 4, 0);\n      __m512i one_epi16 = _mm512_set1_epi16(1);\n       const __mmask32 k_high = 0xFFFF0000;\n\n      // 0.0 .. 15.0 in low 256, 16.0 .. 31.0 in high 256\n      __m512i coef_r0_0_31w = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(coef_0_7, c_perm_0, coef_8_15), _mm512_permutex2var_epi16(coef_16_23, c_perm_0, coef_24_31));\n      c_perm_0 = _mm512_add_epi16(c_perm_0, one_epi16);\n      __m512i coef_r1_0_31w = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(coef_0_7, c_perm_0, coef_8_15), _mm512_permutex2var_epi16(coef_16_23, c_perm_0, coef_24_31));\n      c_perm_0 = _mm512_add_epi16(c_perm_0, one_epi16);\n      __m512i coef_r2_0_31w = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(coef_0_7, c_perm_0, coef_8_15), _mm512_permutex2var_epi16(coef_16_23, c_perm_0, coef_24_31));\n      c_perm_0 = _mm512_add_epi16(c_perm_0, one_epi16);\n      __m512i coef_r3_0_31w = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(coef_0_7, c_perm_0, coef_8_15), _mm512_permutex2var_epi16(coef_16_23, c_perm_0, coef_24_31));\n\n      // convert-transpose to H-pairs for madd ? better to do with single permutex in future\n      // 4 to 4 512 registers - finally real working coeffs to store in the transposed resampling program for block of 64 target samples\n      __m512i coef_r0r1_0_31lo = _mm512_unpacklo_epi16(coef_r0_0_31w, coef_r1_0_31w);\n      __m512i coef_r0r1_0_31hi = _mm512_unpackhi_epi16(coef_r0_0_31w, coef_r1_0_31w);\n\n      __m512i coef_r2r3_0_31lo = _mm512_unpacklo_epi16(coef_r2_0_31w, coef_r3_0_31w);\n      __m512i coef_r2r3_0_31hi = _mm512_unpackhi_epi16(coef_r2_0_31w, coef_r3_0_31w);\n\n      // TODO: store transposed resampling program coeffs to temp buffer for reusage at each line\n\n      // convert resampling program in H-form into permuting indexes for src transposition in V-form\n      __m512i perm_0_0_15 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x])); // 16 offsets\n      __m512i perm_0_16_31 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 16])); //  16 offsets\n\n      int iStart = program->pixel_offset[x];\n      __m512i m512i_Start = _mm512_set1_epi32(iStart);\n\n      perm_0_0_15 = _mm512_sub_epi32(perm_0_0_15, m512i_Start);\n      perm_0_16_31 = _mm512_sub_epi32(perm_0_16_31, m512i_Start);\n\n      __m256i m256i_perm_0_0_15 = _mm512_cvtepi32_epi16(perm_0_0_15);\n      __m256i m256i_perm_0_16_31 = _mm512_cvtepi32_epi16(perm_0_16_31);\n\n      // Insert each 256-bit register into the specific lane\n      __m512i perm_0 = _mm512_inserti64x4(_mm512_zextsi256_si512(m256i_perm_0_0_15), m256i_perm_0_16_31, 1);\n\n      // Taps are contiguous (0, 1, 2, 3), so we increment perm indexes by 1.\n      __m512i perm_1 = _mm512_add_epi16(perm_0, one_epi16);\n      __m512i perm_2 = _mm512_add_epi16(perm_1, one_epi16);\n      __m512i perm_3 = _mm512_add_epi16(perm_2, one_epi16);\n\n      uint16_t* AVS_RESTRICT dst_ptr = dst + x + y_from * dst_pitch;\n      const uint16_t* src_ptr = src + iStart + y_from * src_pitch; // all permute offsets relative to this start offset\n\n      // Calculate remaining pixels for bounds checking in partial_load mode. 1..64 remaining uint16_t pixels possible.\n      // only when partial_load\n      const int remaining = program->source_size - iStart;\n      // two masks for partial loads of 32 + 32 shorts\n      const __mmask32 k1 = _bzhi_u32(~0UL, remaining);\n      const __mmask32 k2 = _bzhi_u32(~0UL, remaining - 32);\n\n      for (int y = y_from; y < y_to; y++)\n      {\n        __m512i data_src, data_src2;\n\n        if constexpr (partial_load) {\n          // Safe masked loads for the image edge 2x32 shorts\n          data_src = _mm512_maskz_loadu_epi16(k1, src_ptr);\n          data_src2 = _mm512_maskz_loadu_epi16(k2, src_ptr + 32);\n        }\n        else {\n          // Fast unaligned loads for the safe zone\n          data_src = _mm512_loadu_si512(src_ptr);\n          data_src2 = _mm512_loadu_si512(src_ptr + 32);\n        }\n\n        __m512i src_r0_0_31 = _mm512_permutex2var_epi16(data_src, perm_0, data_src2);\n        __m512i src_r1_0_31 = _mm512_permutex2var_epi16(data_src, perm_1, data_src2);\n        __m512i src_r2_0_31 = _mm512_permutex2var_epi16(data_src, perm_2, data_src2);\n        __m512i src_r3_0_31 = _mm512_permutex2var_epi16(data_src, perm_3, data_src2);\n\n        if constexpr (!lessthan16bit) {\n          // madd requires signed integers, so shift to signed range\n          src_r0_0_31 = _mm512_add_epi16(src_r0_0_31, shifttosigned);\n          src_r1_0_31 = _mm512_add_epi16(src_r1_0_31, shifttosigned);\n          src_r2_0_31 = _mm512_add_epi16(src_r2_0_31, shifttosigned);\n          src_r3_0_31 = _mm512_add_epi16(src_r3_0_31, shifttosigned);\n        }\n\n        // transposition to H-pairs 4 to 4 512bit registers (?)\n        __m512i src_r0r1_0_31lo = _mm512_unpacklo_epi16(src_r0_0_31, src_r1_0_31);\n        __m512i src_r0r1_0_31hi = _mm512_unpackhi_epi16(src_r0_0_31, src_r1_0_31);\n\n        __m512i src_r2r3_0_31lo = _mm512_unpacklo_epi16(src_r2_0_31, src_r3_0_31);\n        __m512i src_r2r3_0_31hi = _mm512_unpackhi_epi16(src_r2_0_31, src_r3_0_31);\n\n        // making FMA in 32bits accs as in AVX256 V-resize\n        __m512i result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31lo, coef_r0r1_0_31lo), _mm512_madd_epi16(src_r2r3_0_31lo, coef_r2r3_0_31lo));\n        __m512i result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31hi, coef_r0r1_0_31hi), _mm512_madd_epi16(src_r2r3_0_31hi, coef_r2r3_0_31hi));\n\n        if constexpr (!lessthan16bit) {\n          // return from signed range\n          result_0_31lo = _mm512_add_epi32(result_0_31lo, shiftfromsigned);\n          result_0_31hi = _mm512_add_epi32(result_0_31hi, shiftfromsigned);\n        }\n\n        // rounding\n        result_0_31lo = _mm512_add_epi32(result_0_31lo, rounder);\n        result_0_31hi = _mm512_add_epi32(result_0_31hi, rounder);\n        // scale down\n        result_0_31lo = _mm512_srai_epi32(result_0_31lo, FPScale16bits);\n        result_0_31hi = _mm512_srai_epi32(result_0_31hi, FPScale16bits);\n\n        // negative and over 16 bit values are clamped automatically\n        __m512i result_0_31_int16 = _mm512_packus_epi32(result_0_31lo, result_0_31hi);\n\n        if constexpr (lessthan16bit) {\n          result_0_31_int16 = _mm512_min_epu16(result_0_31_int16, clamp_limit); // extra clamp for 10-14 bit\n        }\n        \n        _mm512_stream_si512(reinterpret_cast<__m512i*>(dst_ptr), result_0_31_int16);\n\n        dst_ptr += dst_pitch;\n        src_ptr += src_pitch;\n      }\n\n      current_coeff += filter_size * PIXELS_AT_A_TIME;\n    };\n\n    // Process the 'safe zone' where direct full unaligned loads are acceptable.\n    for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)\n    {\n      do_h_integer_core(std::false_type{});\n    }\n\n    // Process the potentially 'unsafe zone' near the image edge, using safe masked loading.\n    for (; x < width; x += PIXELS_AT_A_TIME)\n    {\n      do_h_integer_core(std::true_type{});\n    }\n  }\n}\n\ntemplate void resize_h_planar_uint16_avx512_permutex_vstripe_ks4<false>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resize_h_planar_uint16_avx512_permutex_vstripe_ks4<true>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\n// filter size up to 8\n// 32 target uint16_t pixels at a time\n// 128-byte source loads (64 uint16_t pixels)\n// maximum permute index is 64 for _mm512_permutex2var_epi16 (uint16_t)\ntemplate<bool lessthan16bit>\nvoid resize_h_planar_uint16_avx512_permutex_vstripe_ks8(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)\n{\n  const int filter_size = program->filter_size; // aligned, practically the coeff table stride\n\n  const uint16_t* src = (const uint16_t*)src8;\n  uint16_t* AVS_RESTRICT dst = (uint16_t * AVS_RESTRICT)dst8;\n  dst_pitch = dst_pitch / sizeof(uint16_t);\n  src_pitch = src_pitch / sizeof(uint16_t);\n\n  constexpr int PIXELS_AT_A_TIME = 32;\n\n  // 'source_overread_beyond_targetx' indicates if the filter kernel can read beyond the target width.\n  // we load 2x32 source uint16_t pixels at a time, so ensure safe overread if needed.\n  // Our main loop processes calculates for 32 target pixels at a time.\n  // Inside that, we load 64 source uint16_t pixels (2x32) to be able to permutex from that.\n  // This we have to check at each mod-PIXELS_AT_A_TIME boundary, the allowance of 64-element source load.\n  const int width_safe_mod = (program->safelimit_64_pixels_each32th_target.overread_possible ? program->safelimit_64_pixels_each32th_target.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  // Preconditions:\n  assert(program->filter_size_real <= 8); // We preload all relevant coefficients (up to 8) before the height loop.\n  assert(program->target_size_alignment >= 32); // source-offset starts for 32 target pixels, 32 coeff strides\n  assert(FRAME_ALIGN >= 64); // storing 32x2 uint16_t at a time\n  assert(program->filter_size_alignment >= 8);\n\n  const int max_scanlines = program->max_scanlines;\n\n  // for 16 bits only\n  const __m512i shifttosigned = _mm512_set1_epi16(-32768);\n  const __m512i shiftfromsigned = _mm512_set1_epi32(32768 << FPScale16bits);\n\n  const int limit = (1 << bits_per_pixel) - 1;\n  // only used when template lessthan16bit is true\n  __m512i clamp_limit = _mm512_set1_epi16((short)limit); // clamp limit for <16 bits\n\n  __m512i rounder = _mm512_set1_epi32(1 << (FPScale16bits - 1));\n\n  // Vertical stripe loop for L2 cache optimization\n  for (int y_from = 0; y_from < height; y_from += max_scanlines)\n  {\n    int y_to = std::min(y_from + max_scanlines, height);\n\n    // Reset current_coeff for the start of the stripe (points to start of row's coeffs)\n    const short* AVS_RESTRICT current_coeff = program->pixel_coefficient;\n\n    int x = 0;\n\n    // Lambda to handle both safe (fast) and unsafe (masked/partial) loading paths\n    auto do_h_integer_core = [&](auto partial_load) {\n\n      // prepare coefs in transposed V-form\n      // 32 source pixels, 32 coeff strides\n      // 8coefs of 16bit is 128bits \n      __m512i coef_0_3 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 0), (__m128i*)(current_coeff + filter_size * 1), (__m128i*)(current_coeff + filter_size * 2), (__m128i*)(current_coeff + filter_size * 3));\n      __m512i coef_4_7 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 4), (__m128i*)(current_coeff + filter_size * 5), (__m128i*)(current_coeff + filter_size * 6), (__m128i*)(current_coeff + filter_size * 7));\n      __m512i coef_8_11 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 8), (__m128i*)(current_coeff + filter_size * 9), (__m128i*)(current_coeff + filter_size * 10), (__m128i*)(current_coeff + filter_size * 11));\n      __m512i coef_12_15 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 12), (__m128i*)(current_coeff + filter_size * 13), (__m128i*)(current_coeff + filter_size * 14), (__m128i*)(current_coeff + filter_size * 15));\n      __m512i coef_16_19 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 16), (__m128i*)(current_coeff + filter_size * 17), (__m128i*)(current_coeff + filter_size * 18), (__m128i*)(current_coeff + filter_size * 19));\n      __m512i coef_20_23 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 20), (__m128i*)(current_coeff + filter_size * 21), (__m128i*)(current_coeff + filter_size * 22), (__m128i*)(current_coeff + filter_size * 23));\n      __m512i coef_24_27 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 24), (__m128i*)(current_coeff + filter_size * 25), (__m128i*)(current_coeff + filter_size * 26), (__m128i*)(current_coeff + filter_size * 27));\n      __m512i coef_28_31 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 28), (__m128i*)(current_coeff + filter_size * 29), (__m128i*)(current_coeff + filter_size * 30), (__m128i*)(current_coeff + filter_size * 31));\n\n      // Transpose with permutex\n      __m512i c_perm_0_3 = _mm512_set_epi16(\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        8 + 16, 0 + 16, 8, 0);\n\n      __m512i c_perm_4_7 = _mm512_set_epi16(\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        8 + 16, 0 + 16, 8, 0,\n        0, 0, 0, 0);\n\n      __m512i c_perm_8_11 = _mm512_set_epi16(\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        8 + 16, 0 + 16, 8, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0);\n\n      __m512i c_perm_12_15 = _mm512_set_epi16(\n        0, 0, 0, 0,\n        8 + 16, 0 + 16, 8, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0,\n        0, 0, 0, 0);\n\n      __m512i one_epi16 = _mm512_set1_epi16(1);\n\n      // Define masks for the 2-word (4-byte, 2x 16-bit word) segments within the 32-word vector.\n      const __mmask32 k_4_7 = 0x000000F0;\n      const __mmask32 k_8_11 = 0x00000F00;\n      const __mmask32 k_12_15 = 0x0000F000;\n\n      auto inc_perms = [&](\n        __m512i& p0_3, __m512i& p4_7, __m512i& p8_11, __m512i& p12_15\n        ) {\n          p0_3 = _mm512_add_epi16(p0_3, one_epi16);\n          p4_7 = _mm512_add_epi16(p4_7, one_epi16);\n          p8_11 = _mm512_add_epi16(p8_11, one_epi16);\n          p12_15 = _mm512_add_epi16(p12_15, one_epi16);\n        };\n\n      auto make_coef_row = [&](\n        __m512i& row_result,\n        __m512i p0_3, __m512i p4_7, __m512i p8_11, __m512i p12_15\n        ) {\n          row_result = _mm512_mask_blend_epi16(\n            k_4_7,\n            _mm512_permutex2var_epi16(coef_0_3, p0_3, coef_4_7),\n            _mm512_permutex2var_epi16(coef_8_11, p8_11, coef_12_15)\n          );\n          row_result = _mm512_mask_blend_epi16(\n            k_8_11,\n            row_result,\n            _mm512_permutex2var_epi16(coef_16_19, p8_11, coef_20_23)\n          );\n          row_result = _mm512_mask_blend_epi16(\n            k_12_15,\n            row_result,\n            _mm512_permutex2var_epi16(coef_24_27, p12_15, coef_28_31)\n          );\n        };\n\n      __m512i coef_r0_0_31w, coef_r1_0_31w, coef_r2_0_31w, coef_r3_0_31w;\n      __m512i coef_r4_0_31w, coef_r5_0_31w, coef_r6_0_31w, coef_r7_0_31w;\n\n      // r0\n      make_coef_row(coef_r0_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15);\n      // r1\n      make_coef_row(coef_r1_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15);\n      // r2\n      make_coef_row(coef_r2_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15);\n      // r3\n      make_coef_row(coef_r3_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15);\n      // r4\n      make_coef_row(coef_r4_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15);\n      // r5\n      make_coef_row(coef_r5_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15);\n      // r6\n      make_coef_row(coef_r6_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15);\n      inc_perms(c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15);\n      // r7\n      make_coef_row(coef_r7_0_31w, c_perm_0_3, c_perm_4_7, c_perm_8_11, c_perm_12_15);\n\n      // convert-transpose to H-pairs for madd\n      __m512i coef_r0r1_0_31lo = _mm512_unpacklo_epi16(coef_r0_0_31w, coef_r1_0_31w);\n      __m512i coef_r0r1_0_31hi = _mm512_unpackhi_epi16(coef_r0_0_31w, coef_r1_0_31w);\n\n      __m512i coef_r2r3_0_31lo = _mm512_unpacklo_epi16(coef_r2_0_31w, coef_r3_0_31w);\n      __m512i coef_r2r3_0_31hi = _mm512_unpackhi_epi16(coef_r2_0_31w, coef_r3_0_31w);\n\n      __m512i coef_r4r5_0_31lo = _mm512_unpacklo_epi16(coef_r4_0_31w, coef_r5_0_31w);\n      __m512i coef_r4r5_0_31hi = _mm512_unpackhi_epi16(coef_r4_0_31w, coef_r5_0_31w);\n\n      __m512i coef_r6r7_0_31lo = _mm512_unpacklo_epi16(coef_r6_0_31w, coef_r7_0_31w);\n      __m512i coef_r6r7_0_31hi = _mm512_unpackhi_epi16(coef_r6_0_31w, coef_r7_0_31w);\n\n      // convert resampling program in H-form into permuting indexes for src transposition in V-form\n      __m512i perm_0_0_15 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x])); // 16 offsets\n      __m512i perm_0_16_31 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 16])); //  16 offsets\n\n      int iStart = program->pixel_offset[x];\n      __m512i m512i_Start = _mm512_set1_epi32(iStart);\n\n      perm_0_0_15 = _mm512_sub_epi32(perm_0_0_15, m512i_Start);\n      perm_0_16_31 = _mm512_sub_epi32(perm_0_16_31, m512i_Start);\n\n      __m256i m256i_perm_0_0_15 = _mm512_cvtepi32_epi16(perm_0_0_15);\n      __m256i m256i_perm_0_16_31 = _mm512_cvtepi32_epi16(perm_0_16_31);\n\n      // Insert each 256-bit register into the specific lane\n      __m512i perm_0 = _mm512_inserti64x4(_mm512_zextsi256_si512(m256i_perm_0_0_15), m256i_perm_0_16_31, 1);\n\n      // Taps are contiguous (0, 1, 2, 3, 4, 5, 6, 7), so we increment perm indexes by 1.\n      __m512i one_epi16_perm = _mm512_set1_epi16(1);\n      __m512i perm_1 = _mm512_add_epi16(perm_0, one_epi16_perm);\n      __m512i perm_2 = _mm512_add_epi16(perm_1, one_epi16_perm);\n      __m512i perm_3 = _mm512_add_epi16(perm_2, one_epi16_perm);\n      __m512i perm_4 = _mm512_add_epi16(perm_3, one_epi16_perm);\n      __m512i perm_5 = _mm512_add_epi16(perm_4, one_epi16_perm);\n      __m512i perm_6 = _mm512_add_epi16(perm_5, one_epi16_perm);\n      __m512i perm_7 = _mm512_add_epi16(perm_6, one_epi16_perm);\n\n      uint16_t* AVS_RESTRICT dst_ptr = dst + x + y_from * dst_pitch;\n      const uint16_t* src_ptr = src + iStart + y_from * src_pitch; // all permute offsets relative to this start offset\n\n      // Calculate remaining pixels for bounds checking in partial_load mode. 1..64 remaining uint16_t pixels possible.\n      // only when partial_load\n      const int remaining = program->source_size - iStart;\n      // two masks for partial loads of 32 + 32 shorts\n      const __mmask32 k1 = _bzhi_u32(~0UL, remaining);\n      const __mmask32 k2 = _bzhi_u32(~0UL, std::max(0, remaining - 32));\n\n      for (int y = y_from; y < y_to; y++)\n      {\n        __m512i data_src, data_src2;\n\n        if constexpr (partial_load) {\n          // Safe masked loads for the image edge 2x32 shorts\n          data_src = _mm512_maskz_loadu_epi16(k1, src_ptr);\n          data_src2 = _mm512_maskz_loadu_epi16(k2, src_ptr + 32);\n        }\n        else {\n          // Fast unaligned loads for the safe zone\n          data_src = _mm512_loadu_si512(src_ptr);\n          data_src2 = _mm512_loadu_si512(src_ptr + 32);\n        }\n\n        __m512i src_r0_0_31 = _mm512_permutex2var_epi16(data_src, perm_0, data_src2);\n        __m512i src_r1_0_31 = _mm512_permutex2var_epi16(data_src, perm_1, data_src2);\n        __m512i src_r2_0_31 = _mm512_permutex2var_epi16(data_src, perm_2, data_src2);\n        __m512i src_r3_0_31 = _mm512_permutex2var_epi16(data_src, perm_3, data_src2);\n        __m512i src_r4_0_31 = _mm512_permutex2var_epi16(data_src, perm_4, data_src2);\n        __m512i src_r5_0_31 = _mm512_permutex2var_epi16(data_src, perm_5, data_src2);\n        __m512i src_r6_0_31 = _mm512_permutex2var_epi16(data_src, perm_6, data_src2);\n        __m512i src_r7_0_31 = _mm512_permutex2var_epi16(data_src, perm_7, data_src2);\n\n        if constexpr (!lessthan16bit) {\n          // madd requires signed integers, so shift to signed range\n          src_r0_0_31 = _mm512_add_epi16(src_r0_0_31, shifttosigned);\n          src_r1_0_31 = _mm512_add_epi16(src_r1_0_31, shifttosigned);\n          src_r2_0_31 = _mm512_add_epi16(src_r2_0_31, shifttosigned);\n          src_r3_0_31 = _mm512_add_epi16(src_r3_0_31, shifttosigned);\n          src_r4_0_31 = _mm512_add_epi16(src_r4_0_31, shifttosigned);\n          src_r5_0_31 = _mm512_add_epi16(src_r5_0_31, shifttosigned);\n          src_r6_0_31 = _mm512_add_epi16(src_r6_0_31, shifttosigned);\n          src_r7_0_31 = _mm512_add_epi16(src_r7_0_31, shifttosigned);\n        }\n\n        // transposition to H-pairs 8 to 8 512bit registers\n        __m512i src_r0r1_0_31lo = _mm512_unpacklo_epi16(src_r0_0_31, src_r1_0_31);\n        __m512i src_r0r1_0_31hi = _mm512_unpackhi_epi16(src_r0_0_31, src_r1_0_31);\n\n        __m512i src_r2r3_0_31lo = _mm512_unpacklo_epi16(src_r2_0_31, src_r3_0_31);\n        __m512i src_r2r3_0_31hi = _mm512_unpackhi_epi16(src_r2_0_31, src_r3_0_31);\n\n        __m512i src_r4r5_0_31lo = _mm512_unpacklo_epi16(src_r4_0_31, src_r5_0_31);\n        __m512i src_r4r5_0_31hi = _mm512_unpackhi_epi16(src_r4_0_31, src_r5_0_31);\n\n        __m512i src_r6r7_0_31lo = _mm512_unpacklo_epi16(src_r6_0_31, src_r7_0_31);\n        __m512i src_r6r7_0_31hi = _mm512_unpackhi_epi16(src_r6_0_31, src_r7_0_31);\n\n        // making FMA in 32bits accs as in AVX256 V-resize\n        __m512i result_0_31lo = _mm512_add_epi32(\n          _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31lo, coef_r0r1_0_31lo), _mm512_madd_epi16(src_r2r3_0_31lo, coef_r2r3_0_31lo)),\n          _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_0_31lo, coef_r4r5_0_31lo), _mm512_madd_epi16(src_r6r7_0_31lo, coef_r6r7_0_31lo))\n        );\n        __m512i result_0_31hi = _mm512_add_epi32(\n          _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31hi, coef_r0r1_0_31hi), _mm512_madd_epi16(src_r2r3_0_31hi, coef_r2r3_0_31hi)),\n          _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_0_31hi, coef_r4r5_0_31hi), _mm512_madd_epi16(src_r6r7_0_31hi, coef_r6r7_0_31hi))\n        );\n\n        if constexpr (!lessthan16bit) {\n          // return from signed range\n          result_0_31lo = _mm512_add_epi32(result_0_31lo, shiftfromsigned);\n          result_0_31hi = _mm512_add_epi32(result_0_31hi, shiftfromsigned);\n        }\n\n        // rounding\n        result_0_31lo = _mm512_add_epi32(result_0_31lo, rounder);\n        result_0_31hi = _mm512_add_epi32(result_0_31hi, rounder);\n        // scale down\n        result_0_31lo = _mm512_srai_epi32(result_0_31lo, FPScale16bits);\n        result_0_31hi = _mm512_srai_epi32(result_0_31hi, FPScale16bits);\n\n        // negative and over 16 bit values are clamped automatically\n        __m512i result_0_31_int16 = _mm512_packus_epi32(result_0_31lo, result_0_31hi);\n\n        if constexpr (lessthan16bit) {\n          result_0_31_int16 = _mm512_min_epu16(result_0_31_int16, clamp_limit); // extra clamp for 10-14 bit\n        }\n\n        _mm512_stream_si512(reinterpret_cast<__m512i*>(dst_ptr), result_0_31_int16);\n\n        dst_ptr += dst_pitch;\n        src_ptr += src_pitch;\n      }\n\n      current_coeff += filter_size * PIXELS_AT_A_TIME;\n      };\n\n    // Process the 'safe zone' where direct full unaligned loads are acceptable.\n    for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)\n    {\n      do_h_integer_core(std::false_type{});\n    }\n\n    // Process the potentially 'unsafe zone' near the image edge, using safe masked loading.\n    for (; x < width; x += PIXELS_AT_A_TIME)\n    {\n      do_h_integer_core(std::true_type{});\n    }\n  }\n}\n\n// Explicit template instantiations\ntemplate void resize_h_planar_uint16_avx512_permutex_vstripe_ks8<false>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resize_h_planar_uint16_avx512_permutex_vstripe_ks8<true>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\n// filter size up to 8\n// 32 target uint16_t pixels at a time in 2 groups of 16 to support longer source loading to each group to support lower downsample ratios\n// 2 groups of 128-byte source loads (64 uint16_t pixels)\n// maximum permute index is 64 for _mm512_permutex2var_epi16 (uint16_t)\ntemplate<bool lessthan16bit>\nvoid resize_h_planar_uint16_avx512_permutex_vstripe_2s16_ks8(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)\n{\n  const int filter_size = program->filter_size;\n\n  const uint16_t* src = (const uint16_t*)src8;\n  uint16_t* AVS_RESTRICT dst = (uint16_t*)dst8;\n  dst_pitch /= sizeof(uint16_t);\n  src_pitch /= sizeof(uint16_t);\n\n  constexpr int PIXELS_AT_A_TIME = 32; // 2x16\n\n  const int width_safe_mod = (program->safelimit_64_pixels_each32th_target.overread_possible\n    ? program->safelimit_64_pixels_each32th_target.source_overread_beyond_targetx\n    : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  assert(program->filter_size_real <= 8);\n  assert(program->target_size_alignment >= 32);\n  assert(FRAME_ALIGN >= 64);\n  assert(program->filter_size_alignment >= 8);\n\n  const int max_scanlines = program->max_scanlines;\n\n  const __m512i shifttosigned = _mm512_set1_epi16(-32768);\n  const __m512i shiftfromsigned = _mm512_set1_epi32(32768 << FPScale16bits);\n\n  const int limit = (1 << bits_per_pixel) - 1;\n  __m512i clamp_limit = _mm512_set1_epi16((short)limit);\n\n  __m512i rounder = _mm512_set1_epi32(1 << (FPScale16bits - 1));\n\n  for (int y_from = 0; y_from < height; y_from += max_scanlines) {\n    int y_to = std::min(y_from + max_scanlines, height);\n    const short* AVS_RESTRICT current_coeff = program->pixel_coefficient;\n    int x = 0;\n\n    auto do_h_integer_core = [&](auto partial_load) {\n\n      // prepare coefs in transposed V-form\n      // 32 source pixels, 32 coeff strides\n      // 8coefs of 16bit is 128bits \n      __m512i coef_0_3 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 0), (__m128i*)(current_coeff + filter_size * 1), (__m128i*)(current_coeff + filter_size * 2), (__m128i*)(current_coeff + filter_size * 3));\n      __m512i coef_4_7 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 4), (__m128i*)(current_coeff + filter_size * 5), (__m128i*)(current_coeff + filter_size * 6), (__m128i*)(current_coeff + filter_size * 7));\n      __m512i coef_8_11 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 8), (__m128i*)(current_coeff + filter_size * 9), (__m128i*)(current_coeff + filter_size * 10), (__m128i*)(current_coeff + filter_size * 11));\n      __m512i coef_12_15 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 12), (__m128i*)(current_coeff + filter_size * 13), (__m128i*)(current_coeff + filter_size * 14), (__m128i*)(current_coeff + filter_size * 15));\n      __m512i coef_16_19 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 16), (__m128i*)(current_coeff + filter_size * 17), (__m128i*)(current_coeff + filter_size * 18), (__m128i*)(current_coeff + filter_size * 19));\n      __m512i coef_20_23 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 20), (__m128i*)(current_coeff + filter_size * 21), (__m128i*)(current_coeff + filter_size * 22), (__m128i*)(current_coeff + filter_size * 23));\n      __m512i coef_24_27 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 24), (__m128i*)(current_coeff + filter_size * 25), (__m128i*)(current_coeff + filter_size * 26), (__m128i*)(current_coeff + filter_size * 27));\n      __m512i coef_28_31 = _mm512i_loadu_4_m128i(\n        (__m128i*)(current_coeff + filter_size * 28), (__m128i*)(current_coeff + filter_size * 29), (__m128i*)(current_coeff + filter_size * 30), (__m128i*)(current_coeff + filter_size * 31));\n\n      // Transpose with permutex\n      __m512i one_epi16 = _mm512_set1_epi16(1);\n\n      // 1. Define the base permutation indices for a group of 8 pixels.\n      // This picks Tap N from two registers (4 pixels each).\n      // Index 0-31 = First register, Index 32-63 = Second register.\n      __m512i c_perm_base = _mm512_set_epi16(\n        56, 48, 40, 32, 24, 16, 8, 0, // Pixels 24-31 (using mask)\n        56, 48, 40, 32, 24, 16, 8, 0, // Pixels 16-23 (using mask)\n        56, 48, 40, 32, 24, 16, 8, 0, // Pixels 8-15  (using mask)\n        56, 48, 40, 32, 24, 16, 8, 0  // Pixels 0-7   (base)\n      );\n\n      // 2. Define masks for each 8-pixel (128-bit) segment\n      const __mmask32 k_pixels_8_15 = 0x0000FF00;\n      const __mmask32 k_pixels_16_23 = 0x00FF0000;\n      const __mmask32 k_pixels_24_31 = 0xFF000000;\n\n      // 3. Updated make_coef_row Lambda\n      auto make_coef_row = [&](__m512i& row_result, __m512i p) {\n        // Fill Pixels 0-7 using coef_0_3 and coef_4_7\n        row_result = _mm512_permutex2var_epi16(coef_0_3, p, coef_4_7);\n\n        // Fill Pixels 8-15 using coef_8_11 and coef_12_15\n        row_result = _mm512_mask_blend_epi16(k_pixels_8_15, row_result,\n          _mm512_permutex2var_epi16(coef_8_11, p, coef_12_15));\n\n        // Fill Pixels 16-23 using coef_16_19 and coef_20_23\n        row_result = _mm512_mask_blend_epi16(k_pixels_16_23, row_result,\n          _mm512_permutex2var_epi16(coef_16_19, p, coef_20_23));\n\n        // Fill Pixels 24-31 using coef_24_27 and coef_28_31\n        row_result = _mm512_mask_blend_epi16(k_pixels_24_31, row_result,\n          _mm512_permutex2var_epi16(coef_24_27, p, coef_28_31));\n        };\n\n      // 4. Generate rows 0 - 7\n        __m512i coef_r[8];\n      for (int i = 0; i < 8; ++i) {\n        make_coef_row(coef_r[i], c_perm_base);\n        c_perm_base = _mm512_add_epi16(c_perm_base, one_epi16); // Move to next Tap\n      }\n\n      // convert-transpose to H-pairs for madd\n      __m512i coef_r0r1_0_31lo = _mm512_unpacklo_epi16(coef_r[0], coef_r[1]);\n      __m512i coef_r0r1_0_31hi = _mm512_unpackhi_epi16(coef_r[0], coef_r[1]);\n\n      __m512i coef_r2r3_0_31lo = _mm512_unpacklo_epi16(coef_r[2], coef_r[3]);\n      __m512i coef_r2r3_0_31hi = _mm512_unpackhi_epi16(coef_r[2], coef_r[3]);\n\n      __m512i coef_r4r5_0_31lo = _mm512_unpacklo_epi16(coef_r[4], coef_r[5]);\n      __m512i coef_r4r5_0_31hi = _mm512_unpackhi_epi16(coef_r[4], coef_r[5]);\n\n      __m512i coef_r6r7_0_31lo = _mm512_unpacklo_epi16(coef_r[6], coef_r[7]);\n      __m512i coef_r6r7_0_31hi = _mm512_unpackhi_epi16(coef_r[6], coef_r[7]);\n\n      // Prepare permute indices for 32 outputs (split into two groups of 16)\n      __m512i perm_0_0_15 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x]));\n      __m512i perm_0_16_31 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 16]));\n      int iStart = program->pixel_offset[x];\n      int iStart2 = program->pixel_offset[x + 16];\n      __m512i m512i_Start = _mm512_set1_epi32(iStart);\n      __m512i m512i_Start2 = _mm512_set1_epi32(iStart2);\n\n      perm_0_0_15 = _mm512_sub_epi32(perm_0_0_15, m512i_Start);\n      perm_0_16_31 = _mm512_sub_epi32(perm_0_16_31, m512i_Start2);\n\n      __m256i m256i_perm_0_0_15 = _mm512_cvtepi32_epi16(perm_0_0_15);\n      __m256i m256i_perm_0_16_31 = _mm512_cvtepi32_epi16(perm_0_16_31);\n\n      // Insert each 256-bit register into the specific lane\n      __m512i perm_0 = _mm512_inserti64x4(_mm512_castsi256_si512(m256i_perm_0_0_15), m256i_perm_0_16_31, 1);\n\n      // Taps are contiguous (0, 1, 2, 3, 4, 5, 6, 7), so we increment perm indexes by 1 in even-odd pairs\n      __m512i one_epi16_perm = _mm512_set1_epi16(1);\n\n      uint16_t* AVS_RESTRICT dst_ptr = dst + x + y_from * dst_pitch;\n      const uint16_t* src_ptr = src + iStart + y_from * src_pitch;\n      const uint16_t* src_ptr2 = src + iStart2 + y_from * src_pitch;\n      int remaining = program->source_size - iStart;\n      int remaining2 = program->source_size - iStart2;\n      __mmask32 k1 = _bzhi_u32(~0UL, remaining); // note: epi16, mask32\n      __mmask32 k2 = _bzhi_u32(~0UL, std::max(0, remaining - 32));\n      __mmask32 k12 = _bzhi_u32(~0UL, remaining2);\n      __mmask32 k22 = _bzhi_u32(~0UL, std::max(0, remaining2 - 32));\n\n      // mask: High 16 bits are 1 (0xFFFF0000)\n      const __mmask32 khigh = 0xFFFF0000;\n\n      for (int y = y_from; y < y_to; y++) {\n        __m512i data_src, data_src2, data_src2_, data_src22;\n        if constexpr (partial_load) {\n          data_src = _mm512_maskz_loadu_epi16(k1, src_ptr);\n          data_src2 = _mm512_maskz_loadu_epi16(k2, src_ptr + 32);\n          data_src2_ = _mm512_maskz_loadu_epi16(k12, src_ptr2);\n          data_src22 = _mm512_maskz_loadu_epi16(k22, src_ptr2 + 32);\n        }\n        else {\n          data_src = _mm512_loadu_si512(src_ptr);\n          data_src2 = _mm512_loadu_si512(src_ptr + 32);\n          data_src2_ = _mm512_loadu_si512(src_ptr2);\n          data_src22 = _mm512_loadu_si512(src_ptr2 + 32);\n        }\n        // FIXME!!! Use constexpr, compiler BUG in v143/v145!\n        // https://developercommunity.visualstudio.com/t/Silent-Bad-CodeGen:-Regression-in-Lambda/11030256\n        if constexpr (!lessthan16bit) {\n          // madd requires signed integers, so shift to signed range\n          data_src = _mm512_add_epi16(data_src, shifttosigned);\n          data_src2 = _mm512_add_epi16(data_src2, shifttosigned);\n          data_src2_ = _mm512_add_epi16(data_src2_, shifttosigned);\n          data_src22 = _mm512_add_epi16(data_src22, shifttosigned);\n        }\n\n        __m512i perm_current = perm_0; // reuse as in 8b even/odd\n\n        // Inside the y-loop:\n        auto get_src_row = [&](__m512i p) {\n          __m512i low_half = _mm512_permutex2var_epi16(data_src, p, data_src2);\n          __m512i high_half = _mm512_permutex2var_epi16(data_src2_, p, data_src22);\n          // Blend: low_half when mask bit is 0, high_half when mask bit is 1\n          return _mm512_mask_blend_epi16(khigh, low_half, high_half);\n          };\n\n        __m512i src_r0_0_31 = get_src_row(perm_current);\n        perm_current = _mm512_add_epi16(perm_current, one_epi16_perm);\n        __m512i src_r1_0_31 = get_src_row(perm_current);\n        perm_current = _mm512_add_epi16(perm_current, one_epi16_perm);\n        __m512i src_r2_0_31 = get_src_row(perm_current);\n        perm_current = _mm512_add_epi16(perm_current, one_epi16_perm);\n        __m512i src_r3_0_31 = get_src_row(perm_current);\n        perm_current = _mm512_add_epi16(perm_current, one_epi16_perm);\n        __m512i src_r4_0_31 = get_src_row(perm_current);\n        perm_current = _mm512_add_epi16(perm_current, one_epi16_perm);\n        __m512i src_r5_0_31 = get_src_row(perm_current);\n        perm_current = _mm512_add_epi16(perm_current, one_epi16_perm);\n        __m512i src_r6_0_31 = get_src_row(perm_current);\n        perm_current = _mm512_add_epi16(perm_current, one_epi16_perm);\n        __m512i src_r7_0_31 = get_src_row(perm_current);\n        // perm_current = _mm512_add_epi16(perm_current, one_epi16_perm); // last one, not needed anymore\n\n        // transposition to H-pairs 8 to 8 512bit registers\n        __m512i src_r0r1_0_31lo = _mm512_unpacklo_epi16(src_r0_0_31, src_r1_0_31);\n        __m512i src_r0r1_0_31hi = _mm512_unpackhi_epi16(src_r0_0_31, src_r1_0_31);\n\n        __m512i src_r2r3_0_31lo = _mm512_unpacklo_epi16(src_r2_0_31, src_r3_0_31);\n        __m512i src_r2r3_0_31hi = _mm512_unpackhi_epi16(src_r2_0_31, src_r3_0_31);\n\n        __m512i src_r4r5_0_31lo = _mm512_unpacklo_epi16(src_r4_0_31, src_r5_0_31);\n        __m512i src_r4r5_0_31hi = _mm512_unpackhi_epi16(src_r4_0_31, src_r5_0_31);\n\n        __m512i src_r6r7_0_31lo = _mm512_unpacklo_epi16(src_r6_0_31, src_r7_0_31);\n        __m512i src_r6r7_0_31hi = _mm512_unpackhi_epi16(src_r6_0_31, src_r7_0_31);\n\n        // making FMA in 32bits accs as in AVX256 V-resize\n        __m512i result_0_31lo = _mm512_add_epi32(\n          _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31lo, coef_r0r1_0_31lo), _mm512_madd_epi16(src_r2r3_0_31lo, coef_r2r3_0_31lo)),\n          _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_0_31lo, coef_r4r5_0_31lo), _mm512_madd_epi16(src_r6r7_0_31lo, coef_r6r7_0_31lo))\n        );\n        __m512i result_0_31hi = _mm512_add_epi32(\n          _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31hi, coef_r0r1_0_31hi), _mm512_madd_epi16(src_r2r3_0_31hi, coef_r2r3_0_31hi)),\n          _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_0_31hi, coef_r4r5_0_31hi), _mm512_madd_epi16(src_r6r7_0_31hi, coef_r6r7_0_31hi))\n        );\n\n        if constexpr(!lessthan16bit) {\n          // return from signed range\n          result_0_31lo = _mm512_add_epi32(result_0_31lo, shiftfromsigned);\n          result_0_31hi = _mm512_add_epi32(result_0_31hi, shiftfromsigned);\n        }\n\n        // rounding\n        result_0_31lo = _mm512_add_epi32(result_0_31lo, rounder);\n        result_0_31hi = _mm512_add_epi32(result_0_31hi, rounder);\n        // scale down\n        result_0_31lo = _mm512_srai_epi32(result_0_31lo, FPScale16bits);\n        result_0_31hi = _mm512_srai_epi32(result_0_31hi, FPScale16bits);\n\n        // negative and over 16 bit values are clamped automatically\n        __m512i result_0_31_int16 = _mm512_packus_epi32(result_0_31lo, result_0_31hi);\n\n        if constexpr(lessthan16bit) {\n          result_0_31_int16 = _mm512_min_epu16(result_0_31_int16, clamp_limit); // extra clamp for 10-14 bit\n        }\n\n        _mm512_stream_si512(reinterpret_cast<__m512i*>(dst_ptr), result_0_31_int16);\n\n        dst_ptr += dst_pitch;\n        src_ptr += src_pitch;\n        src_ptr2 += src_pitch;\n      }\n      current_coeff += filter_size * PIXELS_AT_A_TIME;\n      };\n\n    for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)\n      do_h_integer_core(std::false_type{});\n    for (; x < width; x += PIXELS_AT_A_TIME)\n      do_h_integer_core(std::true_type{});\n  }\n}\n\n// Explicit template instantiations\ntemplate void resize_h_planar_uint16_avx512_permutex_vstripe_2s16_ks8<false>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resize_h_planar_uint16_avx512_permutex_vstripe_2s16_ks8<true>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\n// uint8_t h \"mpz\" avx512base 4,8,16\n\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_base(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  // template parameter false: no VNNI, base AVX512 madd\n  resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_internal<false>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_base(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  // template parameter false: no VNNI, base AVX512 madd\n  resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_internal<false>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\nvoid resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_base(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  // template parameter false: no VNNI, base AVX512 madd\n  resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_internal<false>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\n\n// uint16_t h \"mp\" avx512base 4,8,16\n\ntemplate<bool lessthan16bit>\nvoid resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks4_base(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks4_internal<lessthan16bit, false>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\ntemplate<bool lessthan16bit>\nvoid resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks8_base(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks8_internal<lessthan16bit, false>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\ntemplate<bool lessthan16bit>\nvoid resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_base(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_internal<lessthan16bit, false>(dst8, src8, dst_pitch, src_pitch, program, width, height, bits_per_pixel);\n}\n\n// Explicit template instantiations\ntemplate void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks4_base<false>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks4_base<true>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks8_base<false>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks8_base<true>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_base<false>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_base<true>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\n"
  },
  {
    "path": "avs_core/filters/intel/resample_sse.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include <avisynth.h>\n#include <avs/config.h>\n\n#include \"../resample.h\"\n\n// Intrinsics base header + really required extension headers\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n#include <tmmintrin.h> // SSSE3\n\n#include \"../../core/internal.h\"\n\n\n#ifdef X86_32\nvoid resize_v_mmx_planar(BYTE* dst, const BYTE* src, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel)\n{\n  int filter_size = program->filter_size;\n  short* current_coeff = program->pixel_coefficient;\n\n  int wMod8 = (width / 8) * 8;\n\n  __m64 zero = _mm_setzero_si64();\n\n  const int kernel_size = program->filter_size_real; // not the aligned\n  const int kernel_size_mod2 = (kernel_size / 2) * 2;\n  const bool notMod2 = kernel_size_mod2 < kernel_size;\n\n  for (int y = 0; y < target_height; y++) {\n    int offset = program->pixel_offset[y];\n    const BYTE* src_ptr = src + offset * src_pitch;\n\n    for (int x = 0; x < wMod8; x += 8) {\n      __m64 result_1 = _mm_set1_pi32(8192); // Init. with rounder (16384/2 = 8192)\n      __m64 result_2 = result_1;\n      __m64 result_3 = result_1;\n      __m64 result_4 = result_1;\n\n      for (int i = 0; i < kernel_size_mod2; i += 2) {\n        __m64 src_p1 = *(reinterpret_cast<const __m64*>(src_ptr + i * src_pitch + x)); // For detailed explanation please see SSE2 version.\n        __m64 src_p2 = *(reinterpret_cast<const __m64*>(src_ptr + (i + 1) * src_pitch + x));\n\n        __m64 src_l = _mm_unpacklo_pi8(src_p1, src_p2);\n        __m64 src_h = _mm_unpackhi_pi8(src_p1, src_p2);\n\n        __m64 src_1 = _mm_unpacklo_pi8(src_l, zero);\n        __m64 src_2 = _mm_unpackhi_pi8(src_l, zero);\n        __m64 src_3 = _mm_unpacklo_pi8(src_h, zero);\n        __m64 src_4 = _mm_unpackhi_pi8(src_h, zero);\n\n        // two 16 bit short coeffs\n        __m64 coeff = _mm_cvtsi32_si64(*reinterpret_cast<const int*>(current_coeff + i));\n        coeff = _mm_unpacklo_pi32(coeff, coeff);\n\n        __m64 dst_1 = _mm_madd_pi16(src_1, coeff);\n        __m64 dst_2 = _mm_madd_pi16(src_2, coeff);\n        __m64 dst_3 = _mm_madd_pi16(src_3, coeff);\n        __m64 dst_4 = _mm_madd_pi16(src_4, coeff);\n\n        result_1 = _mm_add_pi32(result_1, dst_1);\n        result_2 = _mm_add_pi32(result_2, dst_2);\n        result_3 = _mm_add_pi32(result_3, dst_3);\n        result_4 = _mm_add_pi32(result_4, dst_4);\n      }\n\n      if (notMod2) { // do last odd row\n        __m64 src_p = *(reinterpret_cast<const __m64*>(src_ptr + kernel_size_mod2 * src_pitch + x));\n\n        __m64 src_l = _mm_unpacklo_pi8(src_p, zero);\n        __m64 src_h = _mm_unpackhi_pi8(src_p, zero);\n\n        __m64 coeff = _mm_set1_pi16(current_coeff[kernel_size_mod2]);\n\n        __m64 dst_ll = _mm_mullo_pi16(src_l, coeff);   // Multiply by coefficient\n        __m64 dst_lh = _mm_mulhi_pi16(src_l, coeff);\n        __m64 dst_hl = _mm_mullo_pi16(src_h, coeff);\n        __m64 dst_hh = _mm_mulhi_pi16(src_h, coeff);\n\n        __m64 dst_1 = _mm_unpacklo_pi16(dst_ll, dst_lh); // Unpack to 32-bit integer\n        __m64 dst_2 = _mm_unpackhi_pi16(dst_ll, dst_lh);\n        __m64 dst_3 = _mm_unpacklo_pi16(dst_hl, dst_hh);\n        __m64 dst_4 = _mm_unpackhi_pi16(dst_hl, dst_hh);\n\n        result_1 = _mm_add_pi32(result_1, dst_1);\n        result_2 = _mm_add_pi32(result_2, dst_2);\n        result_3 = _mm_add_pi32(result_3, dst_3);\n        result_4 = _mm_add_pi32(result_4, dst_4);\n      }\n\n      // Divide by 16348 (FPRound)\n      result_1 = _mm_srai_pi32(result_1, 14);\n      result_2 = _mm_srai_pi32(result_2, 14);\n      result_3 = _mm_srai_pi32(result_3, 14);\n      result_4 = _mm_srai_pi32(result_4, 14);\n\n      // Pack and store\n      __m64 result_l = _mm_packs_pi32(result_1, result_2);\n      __m64 result_h = _mm_packs_pi32(result_3, result_4);\n      __m64 result = _mm_packs_pu16(result_l, result_h);\n\n      *(reinterpret_cast<__m64*>(dst + x)) = result;\n    }\n\n    // Leftover\n    for (int x = wMod8; x < width; x++) {\n      int result = 0;\n      for (int i = 0; i < kernel_size; i++) {\n        result += (src_ptr + i * src_pitch)[x] * current_coeff[i];\n      }\n      result = ((result + 8192) / 16384);\n      result = result > 255 ? 255 : result < 0 ? 0 : result;\n      dst[x] = (BYTE)result;\n    }\n\n    dst += dst_pitch;\n    current_coeff += filter_size;\n  }\n\n  _mm_empty();\n}\n#endif\n\n// On x86-32 keep the 1×8 (or 2-lane/8-pixel) kernel\n// On x86-64 use the 2×8 (4-lane/16-pixel) kernel.\n// On 32-bit the only 8 XMM registers are available, 2x8 kernel causes register pressure issues.\n\n// 1x8 pixel kernel, hoped to have less register pressure on x86-32 thus slower, but the 2x8 is faster anyway.\n// Left here for reference.\nvoid resize_v_sse2_planar_pix8(BYTE* dst8, const BYTE* src, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel)\n{\n  AVS_UNUSED(bits_per_pixel);\n\n  const int filter_size = program->filter_size;\n  uint8_t* AVS_RESTRICT dst = (uint8_t * AVS_RESTRICT)dst8;\n  const short* AVS_RESTRICT current_coeff = program->pixel_coefficient;\n\n  const __m128i zero = _mm_setzero_si128();\n  const __m128i rounder = _mm_set1_epi32(1 << (FPScale8bits - 1));\n\n  const int kernel_size = program->filter_size_real; // not the aligned\n  const int kernel_size_mod2 = (kernel_size / 2) * 2;\n  const bool notMod2 = kernel_size_mod2 < kernel_size;\n\n  for (int y = 0; y < target_height; y++) {\n    const int offset = program->pixel_offset[y];\n    const BYTE* src_ptr = src + offset * src_pitch;\n\n    // alignment is safe till 64 bytes\n    // 8 pixels at a time\n    for (int x = 0; x < width; x += 8) {\n      __m128i result_single_lo = rounder;\n      __m128i result_single_hi = rounder;\n\n      const uint8_t* AVS_RESTRICT src2_ptr = src_ptr + x;\n\n      // Process pairs of rows for better efficiency (2 coeffs/cycle)\n      int i = 0;\n      for (; i < kernel_size_mod2; i += 2) {\n        // Load _two_ coefficients as a single packed value and broadcast\n        __m128i coeff = _mm_set1_epi32(*reinterpret_cast<const int*>(current_coeff + i)); // CO|co|CO|co|CO|co|CO|co\n\n        __m128i src_even = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(src2_ptr)); // 8x 8bit pixels\n        __m128i src_odd = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(src2_ptr + src_pitch));  // 8x 8bit pixels\n        src_even = _mm_unpacklo_epi8(src_even, zero);\n        src_odd = _mm_unpacklo_epi8(src_odd, zero);\n        __m128i src_lo = _mm_unpacklo_epi16(src_even, src_odd);\n        __m128i src_hi = _mm_unpackhi_epi16(src_even, src_odd);\n        result_single_lo = _mm_add_epi32(result_single_lo, _mm_madd_epi16(src_lo, coeff)); // a*b + c\n        result_single_hi = _mm_add_epi32(result_single_hi, _mm_madd_epi16(src_hi, coeff)); // a*b + c\n        src2_ptr += 2 * src_pitch; // Move to the next pair of rows\n      }\n\n      // Process the last odd row if needed\n      if (notMod2) {\n        // Load a single coefficients as a single packed value and broadcast\n        __m128i coeff = _mm_set1_epi16(*reinterpret_cast<const short*>(current_coeff + i)); // 0|co|0|co|0|co|0|co\n\n        __m128i src_even = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(src2_ptr)); // 8x 8bit pixels\n        src_even = _mm_unpacklo_epi8(src_even, zero);\n        __m128i src_lo = _mm_unpacklo_epi16(src_even, zero);\n        __m128i src_hi = _mm_unpackhi_epi16(src_even, zero);\n        result_single_lo = _mm_add_epi32(result_single_lo, _mm_madd_epi16(src_lo, coeff)); // a*b + c\n        result_single_hi = _mm_add_epi32(result_single_hi, _mm_madd_epi16(src_hi, coeff)); // a*b + c\n      }\n\n      // scale back, store\n      __m128i result_lo = result_single_lo;\n      __m128i result_hi = result_single_hi;\n      // shift back integer arithmetic 14 bits precision\n      result_lo = _mm_srai_epi32(result_lo, FPScale8bits);\n      result_hi = _mm_srai_epi32(result_hi, FPScale8bits);\n\n      // Note: SSE4.1 simulations for SSE2: _mm_packus_epi32\n      __m128i result_8x_uint16 = _MM_PACKUS_EPI32(result_lo, result_hi); // 8*32 => 8*16\n      __m128i result_8x_uint8 = _mm_packus_epi16(result_8x_uint16, result_8x_uint16); // 8*16 => 8*8\n      _mm_storel_epi64(reinterpret_cast<__m128i*>(dst + x), result_8x_uint8);\n    }\n\n    dst += dst_pitch;\n    current_coeff += filter_size;\n  }\n}\n\n// 2x8 (4-lane/16-pixel) kernel.\n// For some reason, this is actually faster even on x86-32 contrary to the register pressure worries.\nvoid resize_v_sse2_planar_pix16(BYTE* dst8, const BYTE* src, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel)\n{\n    AVS_UNUSED(bits_per_pixel);\n\n    const int filter_size = program->filter_size;\n    uint8_t* AVS_RESTRICT dst = (uint8_t * AVS_RESTRICT)dst8;\n    const short* AVS_RESTRICT current_coeff = program->pixel_coefficient;\n\n    const __m128i zero = _mm_setzero_si128();\n    const __m128i rounder = _mm_set1_epi32(1 << (FPScale8bits - 1));\n\n    const int kernel_size = program->filter_size_real; // not the aligned\n    const int kernel_size_mod2 = (kernel_size / 2) * 2;\n    const bool notMod2 = kernel_size_mod2 < kernel_size;\n\n    for (int y = 0; y < target_height; y++) {\n        const int offset = program->pixel_offset[y];\n        const BYTE* src_ptr = src + offset * src_pitch;\n\n        // alignment is safe till 64\n        // 16 pixels at a time\n        for (int x = 0; x < width; x += 16) {\n            __m128i result_single_lo = rounder;\n            __m128i result_single_hi = rounder;\n\n            __m128i result_single2_lo = rounder;\n            __m128i result_single2_hi = rounder;\n\n            const uint8_t* AVS_RESTRICT src2_ptr = src_ptr + x;\n\n            // Process pairs of rows for better efficiency (2 coeffs/cycle)\n            int i = 0;\n            for (; i < kernel_size_mod2; i += 2) {\n                // Load _two_ coefficients as a single packed value and broadcast\n                __m128i coeff = _mm_set1_epi32(*reinterpret_cast<const int*>(current_coeff + i)); // CO|co|CO|co|CO|co|CO|co\n\n                __m128i src_even = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(src2_ptr)); // 8x 8bit pixels\n                __m128i src_odd = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(src2_ptr + src_pitch));  // 8x 8bit pixels\n\n                __m128i src_even2 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(src2_ptr + 8)); // 8x 8bit pixels\n                __m128i src_odd2 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(src2_ptr + src_pitch + 8));  // 8x 8bit pixels\n\n                src_even = _mm_unpacklo_epi8(src_even, zero);\n                src_odd = _mm_unpacklo_epi8(src_odd, zero);\n\n                src_even2 = _mm_unpacklo_epi8(src_even2, zero);\n                src_odd2 = _mm_unpacklo_epi8(src_odd2, zero);\n\n                __m128i src_lo = _mm_unpacklo_epi16(src_even, src_odd);\n                __m128i src_hi = _mm_unpackhi_epi16(src_even, src_odd);\n\n                __m128i src_lo2 = _mm_unpacklo_epi16(src_even2, src_odd2);\n                __m128i src_hi2 = _mm_unpackhi_epi16(src_even2, src_odd2);\n\n                result_single_lo = _mm_add_epi32(result_single_lo, _mm_madd_epi16(src_lo, coeff)); // a*b + c\n                result_single_hi = _mm_add_epi32(result_single_hi, _mm_madd_epi16(src_hi, coeff)); // a*b + c\n\n                result_single2_lo = _mm_add_epi32(result_single2_lo, _mm_madd_epi16(src_lo2, coeff)); // a*b + c\n                result_single2_hi = _mm_add_epi32(result_single2_hi, _mm_madd_epi16(src_hi2, coeff)); // a*b + c\n\n                src2_ptr += 2 * src_pitch; // Move to the next pair of rows\n            }\n\n            // Process the last odd row if needed\n            if (notMod2) {\n                // Load a single coefficients as a single packed value and broadcast\n                __m128i coeff = _mm_set1_epi16(*reinterpret_cast<const short*>(current_coeff + i)); // 0|co|0|co|0|co|0|co\n\n                __m128i src_even = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(src2_ptr)); // 8x 8bit pixels\n                __m128i src_even2 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(src2_ptr + 8)); // 8x 8bit pixels\n\n                src_even = _mm_unpacklo_epi8(src_even, zero);\n                src_even2 = _mm_unpacklo_epi8(src_even2, zero);\n\n                __m128i src_lo = _mm_unpacklo_epi16(src_even, zero);\n                __m128i src_hi = _mm_unpackhi_epi16(src_even, zero);\n                __m128i src_lo2 = _mm_unpacklo_epi16(src_even2, zero);\n                __m128i src_hi2 = _mm_unpackhi_epi16(src_even2, zero);\n\n                result_single_lo = _mm_add_epi32(result_single_lo, _mm_madd_epi16(src_lo, coeff)); // a*b + c\n                result_single_hi = _mm_add_epi32(result_single_hi, _mm_madd_epi16(src_hi, coeff)); // a*b + c\n                result_single2_lo = _mm_add_epi32(result_single2_lo, _mm_madd_epi16(src_lo2, coeff)); // a*b + c\n                result_single2_hi = _mm_add_epi32(result_single2_hi, _mm_madd_epi16(src_hi2, coeff)); // a*b + c\n\n            }\n\n            // scale back, store\n            __m128i result_lo = result_single_lo;\n            __m128i result_hi = result_single_hi;\n            __m128i result_lo2 = result_single2_lo;\n            __m128i result_hi2 = result_single2_hi;\n\n            // shift back integer arithmetic 14 bits precision\n            result_lo = _mm_srai_epi32(result_lo, FPScale8bits);\n            result_hi = _mm_srai_epi32(result_hi, FPScale8bits);\n            result_lo2 = _mm_srai_epi32(result_lo2, FPScale8bits);\n            result_hi2 = _mm_srai_epi32(result_hi2, FPScale8bits);\n\n            // Note: SSE4.1 simulations for SSE2: _mm_packus_epi32\n            __m128i result_8x_uint16 = _MM_PACKUS_EPI32(result_lo, result_hi); // 8*32 => 8*16\n            __m128i result_8x_uint8 = _mm_packus_epi16(result_8x_uint16, result_8x_uint16); // 8*16 => 8*8\n            _mm_storel_epi64(reinterpret_cast<__m128i*>(dst + x), result_8x_uint8);\n\n            __m128i result2_8x_uint16 = _MM_PACKUS_EPI32(result_lo2, result_hi2); // 8*32 => 8*16\n            __m128i result2_8x_uint8 = _mm_packus_epi16(result2_8x_uint16, result2_8x_uint16); // 8*16 => 8*8\n            _mm_storel_epi64(reinterpret_cast<__m128i*>(dst + x + 8), result2_8x_uint8);\n\n        }\n\n        dst += dst_pitch;\n        current_coeff += filter_size;\n    }\n}\n\n#if defined(X86_64)\nstatic void resize_v_sse2_planar_impl(BYTE* dst8, const BYTE* src, int dst_pitch, int src_pitch,\n  ResamplingProgram* program, int width, int target_height, int bits_per_pixel)\n{\n  resize_v_sse2_planar_pix16(dst8, src, dst_pitch, src_pitch, program, width, target_height, bits_per_pixel);\n}\n#elif defined(X86_32)\nstatic void resize_v_sse2_planar_impl(BYTE* dst8, const BYTE* src, int dst_pitch, int src_pitch,\n  ResamplingProgram* program, int width, int target_height, int bits_per_pixel)\n{\n  // Use the 2x8 kernel even on x86-32 as it is faster despite register pressure concerns.\n  resize_v_sse2_planar_pix16(dst8, src, dst_pitch, src_pitch, program, width, target_height, bits_per_pixel);\n  //resize_v_sse2_planar_pix8(dst8, src, dst_pitch, src_pitch, program, width, target_height, bits_per_pixel);\n}\n#else\n#error Unsupported target for resize_v_sse2_planar\n#endif\n\nvoid resize_v_sse2_planar(BYTE* dst8, const BYTE* src, int dst_pitch, int src_pitch,\n  ResamplingProgram* program, int width, int target_height, int bits_per_pixel)\n{\n  resize_v_sse2_planar_impl(dst8, src, dst_pitch, src_pitch, program, width, target_height, bits_per_pixel);\n}\n\n// like the AVX2 version, but only 8 pixels at a time\ntemplate<bool lessthan16bit>\nvoid resize_v_sse2_planar_uint16_t(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel)\n{\n  AVS_UNUSED(bits_per_pixel);\n\n  const int filter_size = program->filter_size;\n  const short* AVS_RESTRICT current_coeff = program->pixel_coefficient;\n\n  const __m128i zero = _mm_setzero_si128();\n  \n  // for 16 bits only\n  [[maybe_unused]] const __m128i shifttosigned = _mm_set1_epi16(-32768);\n  [[maybe_unused]] const __m128i shiftfromsigned = _mm_set1_epi32(32768 << FPScale16bits);\n\n  const __m128i rounder = _mm_set1_epi32(1 << (FPScale16bits - 1));\n\n  const uint16_t* src = (uint16_t*)src8;\n  uint16_t* AVS_RESTRICT dst = (uint16_t* AVS_RESTRICT)dst8;\n  dst_pitch = dst_pitch / sizeof(uint16_t);\n  src_pitch = src_pitch / sizeof(uint16_t);\n\n  const int limit = (1 << bits_per_pixel) - 1;\n  __m128i clamp_limit = _mm_set1_epi16((short)limit); // clamp limit for <16 bits\n\n  const int kernel_size = program->filter_size_real; // not the aligned\n  const int kernel_size_mod2 = (kernel_size / 2) * 2;\n  const bool notMod2 = kernel_size_mod2 < kernel_size;\n\n  for (int y = 0; y < target_height; y++) {\n    const int offset = program->pixel_offset[y];\n    const uint16_t* src_ptr = src + offset * src_pitch;\n\n    // 16 byte 8 word (half as many as AVX2)\n    // no need wmod8, alignment is safe at least 32\n    for (int x = 0; x < width; x += 8) {\n\n      __m128i result_single_lo = rounder;\n      __m128i result_single_hi = rounder;\n\n      const uint16_t* AVS_RESTRICT src2_ptr = src_ptr + x;\n\n      // Process pairs of rows for better efficiency (2 coeffs/cycle)\n      int i = 0;\n      for (; i < kernel_size_mod2; i += 2) {\n        // Load _two_ coefficients as a single packed value and broadcast\n        __m128i coeff = _mm_set1_epi32(*reinterpret_cast<const int*>(current_coeff + i)); // CO|co|CO|co|CO|co|CO|co\n\n        __m128i src_even = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src2_ptr)); // 8x 16bit pixels\n        __m128i src_odd = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src2_ptr + src_pitch));  // 8x 16bit pixels\n        if constexpr (!lessthan16bit) {\n          src_even = _mm_add_epi16(src_even, shifttosigned);\n          src_odd = _mm_add_epi16(src_odd, shifttosigned);\n        }\n        __m128i src_lo = _mm_unpacklo_epi16(src_even, src_odd);\n        __m128i src_hi = _mm_unpackhi_epi16(src_even, src_odd);\n        result_single_lo = _mm_add_epi32(result_single_lo, _mm_madd_epi16(src_lo, coeff)); // a*b + c\n        result_single_hi = _mm_add_epi32(result_single_hi, _mm_madd_epi16(src_hi, coeff)); // a*b + c\n        src2_ptr += 2 * src_pitch; // Move to the next pair of rows\n      }\n\n      // Process the last odd row if needed\n      if (notMod2) {\n        // Load a single coefficients as a single packed value and broadcast\n        __m128i coeff = _mm_set1_epi16(*reinterpret_cast<const short*>(current_coeff + i)); // 0|co|0|co|0|co|0|co\n\n        __m128i src_even = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src2_ptr)); // 8x 16bit pixels\n        if constexpr (!lessthan16bit) {\n          src_even = _mm_add_epi16(src_even, shifttosigned);\n        }\n        __m128i src_lo = _mm_unpacklo_epi16(src_even, zero);\n        __m128i src_hi = _mm_unpackhi_epi16(src_even, zero);\n        result_single_lo = _mm_add_epi32(result_single_lo, _mm_madd_epi16(src_lo, coeff)); // a*b + c\n        result_single_hi = _mm_add_epi32(result_single_hi, _mm_madd_epi16(src_hi, coeff)); // a*b + c\n      }\n\n      // correct if signed, scale back, store\n      __m128i result_lo = result_single_lo;\n      __m128i result_hi = result_single_hi;\n      if constexpr (!lessthan16bit) {\n        result_lo = _mm_add_epi32(result_lo, shiftfromsigned);\n        result_hi = _mm_add_epi32(result_hi, shiftfromsigned);\n      }\n      // shift back integer arithmetic 13 bits precision\n      result_lo = _mm_srai_epi32(result_lo, FPScale16bits);\n      result_hi = _mm_srai_epi32(result_hi, FPScale16bits);\n\n      // Note: SSE4.1 simulations for SSE2: _mm_packus_epi32, _mm_min_epu16\n      __m128i result_8x_uint16 = _MM_PACKUS_EPI32(result_lo, result_hi); // 8*32 => 8*16\n      if constexpr (lessthan16bit) {\n        result_8x_uint16 = _MM_MIN_EPU16(result_8x_uint16, clamp_limit); // extra clamp for 10-14 bit\n      }\n      _mm_stream_si128(reinterpret_cast<__m128i*>(dst + x), result_8x_uint16);\n    }\n\n    dst += dst_pitch;\n    current_coeff += filter_size;\n  }\n}\n//-------- 128 bit float Horizontals\n\nAVS_FORCEINLINE static void process_two_8pixels_h_float(const float* src, int begin1, int begin2, int i, float* current_coeff, int filter_size, __m128& result1, __m128& result2) {\n  __m128 data_1_low = _mm_loadu_ps(src + begin1 + i); // Load first 4 floats\n  __m128 data_1_high = _mm_loadu_ps(src + begin1 + i + 4); // Load next 4 floats\n  __m128 data_2_low = _mm_loadu_ps(src + begin2 + i); // Load first 4 floats\n  __m128 data_2_high = _mm_loadu_ps(src + begin2 + i + 4); // Load next 4 floats\n\n  __m128 coeff_1_low = _mm_load_ps(current_coeff); // Load first 4 coefficients\n  __m128 coeff_1_high = _mm_load_ps(current_coeff + 4); // Load next 4 coefficients\n  __m128 coeff_2_low = _mm_load_ps(current_coeff + filter_size); // Load first 4 coefficients for second pixel\n  __m128 coeff_2_high = _mm_load_ps(current_coeff + filter_size + 4); // Load next 4 coefficients for second pixel\n\n  result1 = _mm_add_ps(result1, _mm_mul_ps(data_1_low, coeff_1_low)); // a*b + c for first 4 floats\n  result1 = _mm_add_ps(result1, _mm_mul_ps(data_1_high, coeff_1_high)); // a*b + c for next 4 floats\n  result2 = _mm_add_ps(result2, _mm_mul_ps(data_2_low, coeff_2_low)); // a*b + c for first 4 floats\n  result2 = _mm_add_ps(result2, _mm_mul_ps(data_2_high, coeff_2_high)); // a*b + c for next 4 floats\n}\n\ntemplate<bool safe_aligned_mode>\nAVS_FORCEINLINE static void process_two_pixels_h_float(const float* src_ptr, int begin1, int begin2, float* current_coeff, int filter_size, __m128& result1, __m128& result2, int kernel_size) {\n  int ksmod8;\n  // 32 bytes contain 8 floats\n  if constexpr (safe_aligned_mode)\n    ksmod8 = filter_size / 8 * 8;\n  else\n    ksmod8 = kernel_size / 8 * 8; // danger zone, scanline overread possible. Use exact unaligned kernel_size\n  const float* src_ptr1 = src_ptr + begin1;\n  const float* src_ptr2 = src_ptr + begin2;\n  int i = 0;\n\n  // Process 8 elements at a time\n  for (; i < ksmod8; i += 8) {\n    process_two_8pixels_h_float(src_ptr, begin1, begin2, i, current_coeff + i, filter_size, result1, result2);\n  }\n\n  if constexpr (!safe_aligned_mode) {\n    // working with the original, unaligned kernel_size\n    if (i == kernel_size) return;\n\n    float* current_coeff2 = current_coeff + filter_size; // Points to second pixel's coefficients\n    const int ksmod4 = kernel_size / 4 * 4;\n\n    // Process 4 elements if needed\n    if (i < ksmod4) {\n      // Process 4 elements for first pixel\n      __m128 data_1 = _mm_loadu_ps(src_ptr1 + i);\n      __m128 coeff_1 = _mm_load_ps(current_coeff + i);\n      __m128 temp_result1 = _mm_mul_ps(data_1, coeff_1);\n\n      // Process 4 elements for second pixel\n      __m128 data_2 = _mm_loadu_ps(src_ptr2 + i);\n      __m128 coeff_2 = _mm_load_ps(current_coeff2 + i);\n      __m128 temp_result2 = _mm_mul_ps(data_2, coeff_2);\n\n      // update result vectors\n      result1 = _mm_add_ps(result1, temp_result1);\n      result2 = _mm_add_ps(result2, temp_result2);\n\n      i += 4;\n      if (i == kernel_size) return;\n    }\n\n    // Process remaining elements with scalar operations\n    if (i < kernel_size) {\n      float scalar_sum1[4] = { 0, 0, 0, 0 }; // like an __m128\n      float scalar_sum2[4] = { 0, 0, 0, 0 };\n\n      for (; i < kernel_size; i++) {\n        scalar_sum1[i % 4] += src_ptr1[i] * current_coeff[i];\n        scalar_sum2[i % 4] += src_ptr2[i] * current_coeff2[i];\n      }\n\n      // Convert scalar results to SIMD and add to result vectors\n      __m128 temp_result1 = _mm_loadu_ps(scalar_sum1);\n      __m128 temp_result2 = _mm_loadu_ps(scalar_sum2);\n\n      result1 = _mm_add_ps(result1, temp_result1);\n      result2 = _mm_add_ps(result2, temp_result2);\n    }\n  }\n}\n\ntemplate<bool is_safe>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nAVS_FORCEINLINE static void process_eight_pixels_h_float(const float* src, int x, float* current_coeff_base, int filter_size,\n  __m128& zero128,\n  float* dst,\n  ResamplingProgram* program)\n{\n  assert(program->filter_size_alignment >= 8); // code assumes this\n\n  float* current_coeff = current_coeff_base + x * filter_size;\n  const int unaligned_kernel_size = program->filter_size_real;\n\n  // Unrolled processing of all 8 pixels\n\n  // 0 & 1\n  __m128 result0 = zero128;\n  __m128 result1 = zero128;\n  int begin0 = program->pixel_offset[x + 0];\n  int begin1 = program->pixel_offset[x + 1];\n  process_two_pixels_h_float<is_safe>(src, begin0, begin1, current_coeff, filter_size, result0, result1, unaligned_kernel_size);\n  current_coeff += 2 * filter_size;\n  __m128 sumQuad12 = _mm_hadd_ps(result0, result1); // L1L1L1L1L1L1L1L1 + L2L2L2L2L2L2L2L2L2 = L1L1 L2L2 L1L1 L2L2\n\n  // 2 & 3\n  result0 = zero128;\n  result1 = zero128;\n  begin0 = program->pixel_offset[x + 2];\n  begin1 = program->pixel_offset[x + 3];\n  process_two_pixels_h_float<is_safe>(src, begin0, begin1, current_coeff, filter_size, result0, result1, unaligned_kernel_size);\n  current_coeff += 2 * filter_size;\n  __m128 sumQuad1234 = _mm_hadd_ps(sumQuad12, _mm_hadd_ps(result0, result1));\n\n  __m128 result_lo = sumQuad1234; // L1 L2 L3 L4\n\n  // 4 & 5\n  result0 = zero128;\n  result1 = zero128;\n  begin0 = program->pixel_offset[x + 4];\n  begin1 = program->pixel_offset[x + 5];\n  process_two_pixels_h_float<is_safe>(src, begin0, begin1, current_coeff, filter_size, result0, result1, unaligned_kernel_size);\n  current_coeff += 2 * filter_size;\n  __m128 sumQuad56 = _mm_hadd_ps(result0, result1); // L1L1L1L1L1L1L1L1 + L2L2L2L2L2L2L2L2L2 = L1L1 L2L2 L1L1 L2L2\n\n  // 6 & 7\n  result0 = zero128;\n  result1 = zero128;\n  begin0 = program->pixel_offset[x + 6];\n  begin1 = program->pixel_offset[x + 7];\n  process_two_pixels_h_float<is_safe>(src, begin0, begin1, current_coeff, filter_size, result0, result1, unaligned_kernel_size);\n  //current_coeff += 2 * filter_size;\n  __m128 sumQuad5678 = _mm_hadd_ps(sumQuad56, _mm_hadd_ps(result0, result1));\n\n  __m128 result_hi = sumQuad5678; // L1 L2 L3 L4\n\n  _mm_stream_ps(reinterpret_cast<float*>(dst + x), result_lo); // 8 results at a time\n  _mm_stream_ps(reinterpret_cast<float*>(dst + x + 4), result_hi); // 8 results at a time\n\n}\n\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nvoid resizer_h_ssse3_generic_float(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  AVS_UNUSED(bits_per_pixel);\n  int filter_size = program->filter_size;\n  __m128 zero128 = _mm_setzero_ps();\n\n  const float* src = (float*)src8;\n  float* dst = (float*)dst8;\n  dst_pitch = dst_pitch / sizeof(float);\n  src_pitch = src_pitch / sizeof(float);\n\n  const int w_safe_mod8 = (program->safelimit_filter_size_aligned.overread_possible ? program->safelimit_filter_size_aligned.source_overread_beyond_targetx : width) / 8 * 8;\n\n  for (int y = 0; y < height; y++) {\n    float* current_coeff_base = program->pixel_coefficient_float;\n\n    // Process safe aligned pixels\n    for (int x = 0; x < w_safe_mod8; x += 8) {\n      process_eight_pixels_h_float<true>(src, x, current_coeff_base, filter_size, zero128, dst, program);\n    }\n\n    // Process up to the actual kernel size instead of the aligned filter_size to prevent overreading beyond the last source pixel.\n    // We assume extra offset entries were added to the p->pixel_offset array (aligned to 8 during initialization).\n    // This may store 1-7 false pixels, but they are ignored since Avisynth will not read beyond the width.\n    for (int x = w_safe_mod8; x < width; x += 8) {\n      process_eight_pixels_h_float<false>(src, x, current_coeff_base, filter_size, zero128, dst, program);\n    }\n\n    dst += dst_pitch;\n    src += src_pitch;\n  }\n}\n\n//-------- 32 bit float Vertical\n\n// Process each row with its coefficient\nvoid resize_v_sse2_planar_float(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel)\n{\n  AVS_UNUSED(bits_per_pixel);\n\n  const int filter_size = program->filter_size;\n  const float* AVS_RESTRICT current_coeff = program->pixel_coefficient_float;\n\n  const float* src = (const float*)src8;\n  float* AVS_RESTRICT dst = (float*)dst8;\n  dst_pitch = dst_pitch / sizeof(float);\n  src_pitch = src_pitch / sizeof(float);\n\n  const int kernel_size = program->filter_size_real; // not the aligned\n  const int kernel_size_mod2 = (kernel_size / 2) * 2; // Process pairs of rows for better efficiency\n  const bool notMod2 = kernel_size_mod2 < kernel_size;\n\n  for (int y = 0; y < target_height; y++) {\n    int offset = program->pixel_offset[y];\n    const float* src_ptr = src + offset * src_pitch;\n\n    // use 8 pixels, like AVX2, by utilizing 2x2 ps registers (speed)\n    for (int x = 0; x < width; x += 8) {\n      __m128 result_single_even = _mm_setzero_ps();\n      __m128 result_single_odd = _mm_setzero_ps();\n      __m128 result_single_even_b = _mm_setzero_ps();\n      __m128 result_single_odd_b = _mm_setzero_ps();\n\n      const float* AVS_RESTRICT src2_ptr = src_ptr + x; // __restrict here\n\n      // Process pairs of rows for better efficiency (2 coeffs/cycle)\n      int i = 0;\n      for (; i < kernel_size_mod2; i += 2) {\n        __m128 coeff_even = _mm_set1_ps(current_coeff[i]);\n        __m128 coeff_odd = _mm_set1_ps(current_coeff[i + 1]);\n\n        __m128 src_even = _mm_loadu_ps(src2_ptr);\n        __m128 src_odd = _mm_loadu_ps(src2_ptr + src_pitch);\n\n        __m128 mul_even = _mm_mul_ps(src_even, coeff_even);\n        __m128 mul_odd = _mm_mul_ps(src_odd, coeff_odd);\n\n        result_single_even = _mm_add_ps(result_single_even, mul_even);\n        result_single_odd = _mm_add_ps(result_single_odd, mul_odd);\n\n        __m128 src_even_b = _mm_loadu_ps(src2_ptr + 4);\n        __m128 src_odd_b = _mm_loadu_ps(src2_ptr + 4 + src_pitch);\n\n        __m128 mul_even_b = _mm_mul_ps(src_even_b, coeff_even);\n        __m128 mul_odd_b = _mm_mul_ps(src_odd_b, coeff_odd);\n\n        result_single_even_b = _mm_add_ps(result_single_even_b, mul_even_b);\n        result_single_odd_b = _mm_add_ps(result_single_odd_b, mul_odd_b);\n\n        src2_ptr += 2 * src_pitch;\n      }\n\n      result_single_even = _mm_add_ps(result_single_even, result_single_odd);\n      result_single_even_b = _mm_add_ps(result_single_even_b, result_single_odd_b);\n\n      // Process the last odd row if needed  \n      if (notMod2) {\n        __m128 coeff = _mm_set1_ps(current_coeff[i]);\n        __m128 src_val = _mm_loadu_ps(src2_ptr);\n        __m128 src_val_b = _mm_loadu_ps(src2_ptr + 4);\n\n        result_single_even = _mm_add_ps(result_single_even, _mm_mul_ps(src_val, coeff));\n        result_single_even_b = _mm_add_ps(result_single_even_b, _mm_mul_ps(src_val_b, coeff));\n      }\n\n      // Store result  \n      _mm_stream_ps(dst + x, result_single_even);\n      _mm_stream_ps(dst + x + 4, result_single_even_b);\n    }\n\n    dst += dst_pitch;\n    current_coeff += filter_size;\n  }\n}\n\n// -----------------------------------------------\n// 8 bit Horizontal.\n// Dual line processing, use template until alignment and end conditions allow.\n\n// Based on AVX2 code, but without the filter_size alignment template\n\ntemplate<typename pixel_t, bool lessthan16bit>\nAVS_FORCEINLINE static void process_two_16pixels_h_uint8_16_core(const pixel_t* AVS_RESTRICT src, int begin1, int begin2, int i, const short* AVS_RESTRICT current_coeff, int filter_size, __m128i& result1, __m128i& result2, \n  const __m128i& shifttosigned_or_zero128) {\n\n  __m128i data_1_lo, data_1_hi, data_2_lo, data_2_hi;\n\n  if constexpr (sizeof(pixel_t) == 1) {\n    // pixel_t is uint8_t\n  __m128i data_1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src + begin1 + i));\n  __m128i data_2 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src + begin2 + i));\n\n    data_1_lo = _mm_unpacklo_epi8(data_1, shifttosigned_or_zero128);\n    data_1_hi = _mm_unpackhi_epi8(data_1, shifttosigned_or_zero128);\n    data_2_lo = _mm_unpacklo_epi8(data_2, shifttosigned_or_zero128);\n    data_2_hi = _mm_unpackhi_epi8(data_2, shifttosigned_or_zero128);\n  }\n  else {\n    // pixel_t is uint16_t, at exact 16 bit size an unsigned -> signed 16 bit conversion needed\n    data_1_lo = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src + begin1 + i));\n    data_1_hi = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src + begin1 + i + 8));\n    if constexpr (!lessthan16bit) {\n      data_1_lo = _mm_add_epi16(data_1_lo, shifttosigned_or_zero128);\n      data_1_hi = _mm_add_epi16(data_1_hi, shifttosigned_or_zero128);\n    }\n    data_2_lo = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src + begin2 + i));\n    data_2_hi = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src + begin2 + i + 8));\n    if constexpr (!lessthan16bit) {\n      data_2_lo = _mm_add_epi16(data_2_lo, shifttosigned_or_zero128);\n      data_2_hi = _mm_add_epi16(data_2_hi, shifttosigned_or_zero128);\n    }\n  }\n\n  __m128i coeff_1_lo = _mm_load_si128(reinterpret_cast<const __m128i*>(current_coeff)); // 8 coeffs\n  __m128i coeff_1_hi = _mm_load_si128(reinterpret_cast<const __m128i*>(current_coeff + 8)); // next 8 coeffs\n  __m128i coeff_2_lo = _mm_load_si128(reinterpret_cast<const __m128i*>(current_coeff + 1 * filter_size)); // 8x second pixel's coefficients\n  __m128i coeff_2_hi = _mm_load_si128(reinterpret_cast<const __m128i*>(current_coeff + 1 * filter_size + 8)); // next 8x second pixel's coefficients\n\n  result1 = _mm_add_epi32(result1, _mm_madd_epi16(data_1_lo, coeff_1_lo));\n  result1 = _mm_add_epi32(result1, _mm_madd_epi16(data_1_hi, coeff_1_hi));\n  result2 = _mm_add_epi32(result2, _mm_madd_epi16(data_2_lo, coeff_2_lo));\n  result2 = _mm_add_epi32(result2, _mm_madd_epi16(data_2_hi, coeff_2_hi));\n}\n\ntemplate<bool safe_aligned_mode, typename pixel_t, bool lessthan16bit>\nAVS_FORCEINLINE static void process_two_pixels_h_uint8_16(const pixel_t* AVS_RESTRICT src_ptr, int begin1, int begin2, const short* AVS_RESTRICT current_coeff, int filter_size, __m128i& result1, __m128i& result2, int kernel_size, \n  const __m128i& shifttosigned_or_zero128) {\n  int ksmod16;\n  if constexpr (safe_aligned_mode)\n    ksmod16 = filter_size / 16 * 16;\n  else\n    ksmod16 = kernel_size / 16 * 16; // danger zone, scanline overread possible. Use exact unaligned kernel_size\n  const pixel_t* src_ptr1 = src_ptr + begin1;\n  const pixel_t* src_ptr2 = src_ptr + begin2;\n  int i = 0;\n\n  // Process 16 elements at a time\n  for (; i < ksmod16; i += 16) {\n    process_two_16pixels_h_uint8_16_core<pixel_t, lessthan16bit>(src_ptr, begin1, begin2, i, current_coeff + i, filter_size, result1, result2, shifttosigned_or_zero128);\n  }\n\n  if constexpr (!safe_aligned_mode) {\n    // working with the original, unaligned kernel_size\n    if (i == kernel_size) return;\n\n    const short* current_coeff2 = current_coeff + filter_size; // Points to second pixel's coefficients\n    const int ksmod8 = kernel_size / 8 * 8;\n    const int ksmod4 = kernel_size / 4 * 4;\n\n    // Process 8 elements if needed\n    if (i < ksmod8) {\n      // Process 8 elements for first pixel\n      __m128i data_1;\n      if constexpr(sizeof(pixel_t) == 1)\n        data_1 = _mm_unpacklo_epi8(_mm_loadl_epi64(reinterpret_cast<const __m128i*>(src_ptr1 + i)), shifttosigned_or_zero128);\n      else {\n        // uint16_t\n        data_1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src_ptr1 + i));\n        if constexpr (!lessthan16bit)\n          data_1 = _mm_add_epi16(data_1, shifttosigned_or_zero128); // unsigned -> signed\n      }\n\n      __m128i coeff_1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(current_coeff + i));\n      __m128i temp_result1 = _mm_madd_epi16(data_1, coeff_1);\n\n      // Process 8 elements for second pixel\n      __m128i data_2;\n      if constexpr (sizeof(pixel_t) == 1)\n        data_2 = _mm_unpacklo_epi8(_mm_loadl_epi64(reinterpret_cast<const __m128i*>(src_ptr2 + i)), shifttosigned_or_zero128);\n      else {\n        // uint16_t\n        data_2 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src_ptr2 + i));\n        if constexpr (!lessthan16bit)\n          data_2 = _mm_add_epi16(data_2, shifttosigned_or_zero128); // unsigned -> signed\n      }\n\n      __m128i coeff_2 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(current_coeff2 + i));\n      __m128i temp_result2 = _mm_madd_epi16(data_2, coeff_2);\n\n      // update result vectors\n      result1 = _mm_add_epi32(result1, temp_result1);\n      result2 = _mm_add_epi32(result2, temp_result2);\n\n      i += 8;\n      if (i == kernel_size) return;\n    }\n\n    // Process 4 elements if needed\n    if (i < ksmod4) {\n      // Process 4 elements for first pixel\n      __m128i data_1;\n      if constexpr (sizeof(pixel_t) == 1)\n        data_1 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*reinterpret_cast<const int*>(src_ptr1 + i)), shifttosigned_or_zero128);\n      else {\n        data_1 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(src_ptr1 + i));\n        if constexpr (!lessthan16bit)\n          data_1 = _mm_add_epi16(data_1, shifttosigned_or_zero128); // unsigned -> signed\n      }\n\n      __m128i coeff_1 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(current_coeff + i));\n      __m128i temp_result1 = _mm_madd_epi16(data_1, coeff_1);\n\n      // Process 4 elements for second pixel\n      __m128i data_2;\n      if constexpr (sizeof(pixel_t) == 1)\n        data_2 = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*reinterpret_cast<const int*>(src_ptr2 + i)), shifttosigned_or_zero128);\n      else {\n        data_2 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(src_ptr2 + i));\n        if constexpr (!lessthan16bit)\n          data_2 = _mm_add_epi16(data_2, shifttosigned_or_zero128); // unsigned -> signed\n      }\n      __m128i coeff_2 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(current_coeff2 + i));\n      __m128i temp_result2 = _mm_madd_epi16(data_2, coeff_2);\n\n      // update result vectors\n      result1 = _mm_add_epi32(result1, temp_result1);\n      result2 = _mm_add_epi32(result2, temp_result2);\n\n      i += 4;\n      if (i == kernel_size) return;\n    }\n\n    // Process remaining elements with scalar operations\n    if (i < kernel_size) {\n      int scalar_sum1[4] = { 0, 0, 0, 0 }; // like an __m128i\n      int scalar_sum2[4] = { 0, 0, 0, 0 };\n\n      for (; i < kernel_size; i++) {\n        if constexpr (sizeof(pixel_t) == 1) {\n        scalar_sum1[i % 4] += src_ptr1[i] * current_coeff[i];\n        scalar_sum2[i % 4] += src_ptr2[i] * current_coeff2[i];\n        } else {\n          uint16_t pix1 = src_ptr1[i];\n          uint16_t pix2 = src_ptr2[i];\n\n          if constexpr (!lessthan16bit) {\n            pix1 -= 32768;\n            pix2 -= 32768;\n          }\n\n          scalar_sum1[i % 4] += (short)pix1 * current_coeff[i];\n          scalar_sum2[i % 4] += (short)pix2 * current_coeff2[i];\n        }\n      }\n\n      // Convert scalar results to SIMD and add to result vectors\n      __m128i temp_result1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(scalar_sum1));\n      __m128i temp_result2 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(scalar_sum2));\n\n      // update result vectors\n      result1 = _mm_add_epi32(result1, temp_result1);\n      result2 = _mm_add_epi32(result2, temp_result2);\n    }\n  }\n}\n\ntemplate<bool is_safe, typename pixel_t, bool lessthan16bit>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nAVS_FORCEINLINE static void process_eight_pixels_h_uint8_16(const pixel_t* AVS_RESTRICT src, int x, const short* current_coeff_base, int filter_size,\n  __m128i& rounder128, __m128i& shifttosigned_or_zero128, __m128i& clamp_limit,\n  pixel_t* AVS_RESTRICT dst,\n  ResamplingProgram* program)\n{\n  assert(program->filter_size_alignment >= 16); // code assumes this\n\n  const short* AVS_RESTRICT current_coeff = current_coeff_base + x * filter_size;\n  const int unaligned_kernel_size = program->filter_size_real;\n\n  // Unrolled processing of all 8 pixels\n\n  // 0 & 1\n  __m128i result0 = rounder128;\n  __m128i result1 = rounder128;\n  int begin0 = program->pixel_offset[x + 0];\n  int begin1 = program->pixel_offset[x + 1];\n  process_two_pixels_h_uint8_16<is_safe, pixel_t, lessthan16bit>(src, begin0, begin1, current_coeff, filter_size, result0, result1, unaligned_kernel_size, shifttosigned_or_zero128);\n  current_coeff += 2 * filter_size;\n  __m128i sumQuad12 = _mm_hadd_epi32(result0, result1);\n\n  // 2 & 3\n  result0 = rounder128;\n  result1 = rounder128;\n  begin0 = program->pixel_offset[x + 2];\n  begin1 = program->pixel_offset[x + 3];\n  process_two_pixels_h_uint8_16<is_safe, pixel_t, lessthan16bit>(src, begin0, begin1, current_coeff, filter_size, result0, result1, unaligned_kernel_size, shifttosigned_or_zero128);\n  current_coeff += 2 * filter_size;\n  __m128i sumQuad1234 = _mm_hadd_epi32(sumQuad12, _mm_hadd_epi32(result0, result1));\n\n  // 4 & 5\n  result0 = rounder128;\n  result1 = rounder128;\n  begin0 = program->pixel_offset[x + 4];\n  begin1 = program->pixel_offset[x + 5];\n  process_two_pixels_h_uint8_16<is_safe, pixel_t, lessthan16bit>(src, begin0, begin1, current_coeff, filter_size, result0, result1, unaligned_kernel_size, shifttosigned_or_zero128);\n  current_coeff += 2 * filter_size;\n  __m128i sumQuad56 = _mm_hadd_epi32(result0, result1);\n\n  // 6 & 7\n  result0 = rounder128;\n  result1 = rounder128;\n  begin0 = program->pixel_offset[x + 6];\n  begin1 = program->pixel_offset[x + 7];\n  process_two_pixels_h_uint8_16<is_safe, pixel_t, lessthan16bit>(src, begin0, begin1, current_coeff, filter_size, result0, result1, unaligned_kernel_size, shifttosigned_or_zero128);\n  //current_coeff += 2 * filter_size;\n  __m128i sumQuad5678 = _mm_hadd_epi32(sumQuad56, _mm_hadd_epi32(result0, result1));\n\n  __m128i pix1234 = sumQuad1234;\n  __m128i pix5678 = sumQuad5678;\n\n  // correct if signed, scale back, store\n  if constexpr (sizeof(pixel_t) == 2 && !lessthan16bit) {\n    const __m128i shiftfromsigned = _mm_set1_epi32(+32768 << FPScale16bits); // yes, 32 bit data. for 16 bits only\n    pix1234 = _mm_add_epi32(pix1234, shiftfromsigned);\n    pix5678 = _mm_add_epi32(pix5678, shiftfromsigned);\n  }\n\n  const int current_fp_scale_bits = (sizeof(pixel_t) == 1) ? FPScale8bits : FPScale16bits;\n  // scale back, shuffle, store\n  __m128i result1234 = _mm_srai_epi32(pix1234, current_fp_scale_bits);\n  __m128i result5678 = _mm_srai_epi32(pix5678, current_fp_scale_bits);\n  __m128i result_2x4x_uint16_128 = _MM_PACKUS_EPI32(result1234, result5678);\n  if constexpr (sizeof(pixel_t) == 1) {\n    __m128i result_2x4x_uint8 = _mm_packus_epi16(result_2x4x_uint16_128, shifttosigned_or_zero128);\n  _mm_storel_epi64(reinterpret_cast<__m128i*>(dst + x), result_2x4x_uint8);\n}\n  else {\n    // uint16_t\n    if constexpr (lessthan16bit)\n      result_2x4x_uint16_128 = _MM_MIN_EPU16(result_2x4x_uint16_128, clamp_limit); // extra clamp for 10-14 bits\n\n    _mm_store_si128(reinterpret_cast<__m128i*>(dst + x), result_2x4x_uint16_128);\n\n  }\n}\n\n//-------- uint8/16_t Horizontal\n// 4 pixels at a time. \n// ssse3: _mm_hadd_epi32\ntemplate<typename pixel_t, bool lessthan16bit>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nvoid resizer_h_ssse3_generic_uint8_16(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  int filter_size = program->filter_size;\n  const int current_fp_scale_bits = (sizeof(pixel_t) == 1) ? FPScale8bits : FPScale16bits;\n  __m128i rounder128 = _mm_setr_epi32(1 << (current_fp_scale_bits - 1), 0, 0, 0);\n\n  __m128i shifttosigned_or_zero128;\n  if constexpr(sizeof(pixel_t) == 1)\n    shifttosigned_or_zero128 = _mm_setzero_si128();\n  else\n    shifttosigned_or_zero128 = _mm_set1_epi16(-32768); // for 16 bits only\n  __m128i clamp_limit = _mm_set1_epi16((short)((1 << bits_per_pixel) - 1)); // clamp limit for 8< <16 bits\n\n  const pixel_t* src = reinterpret_cast<const pixel_t* AVS_RESTRICT>(src8);\n  pixel_t* dst = reinterpret_cast<pixel_t* AVS_RESTRICT>(dst8);\n  dst_pitch /= sizeof(pixel_t);\n  src_pitch /= sizeof(pixel_t);\n\n  const int w_safe_mod8 = (program->safelimit_filter_size_aligned.overread_possible ? program->safelimit_filter_size_aligned.source_overread_beyond_targetx : width) / 8 * 8;\n\n  for (int y = 0; y < height; y++) {\n    const short* AVS_RESTRICT current_coeff_base = program->pixel_coefficient;\n\n    // Process safe aligned pixels\n    for (int x = 0; x < w_safe_mod8; x += 8) {\n      process_eight_pixels_h_uint8_16<true, pixel_t, lessthan16bit>(src, x, current_coeff_base, filter_size, rounder128, shifttosigned_or_zero128, clamp_limit, dst, program);\n    }\n\n    // Process up to the actual kernel size instead of the aligned filter_size to prevent overreading beyond the last source pixel.\n    // We assume extra offset entries were added to the p->pixel_offset array (aligned to 8 during initialization).\n    // This may store 1-7 false pixels, but they are ignored since Avisynth will not read beyond the width.\n    for (int x = w_safe_mod8; x < width; x += 8) {\n      process_eight_pixels_h_uint8_16<false, pixel_t, lessthan16bit>(src, x, current_coeff_base, filter_size, rounder128, shifttosigned_or_zero128, clamp_limit, dst, program);\n    }\n\n    dst += dst_pitch;\n    src += src_pitch;\n  }\n}\n\n// 16 bit Horizontal\n\ntemplate void resizer_h_ssse3_generic_uint8_16<uint8_t, true>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resizer_h_ssse3_generic_uint8_16<uint16_t, false>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resizer_h_ssse3_generic_uint8_16<uint16_t, true>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\ntemplate void resize_v_sse2_planar_uint16_t<false>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel);\ntemplate void resize_v_sse2_planar_uint16_t<true>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel);\n\n\n// Safe partial load with SSE2\n// Read exactly N pixels, avoiding\n// - reading beyond the end of the source buffer.\n// - avoid NaN contamination, since event with zero coefficients NaN * 0 = NaN\ntemplate <int Nmod4>\nAVS_FORCEINLINE static __m128 load_partial_safe_sse2(const float* src_ptr_offsetted) {\n  switch (Nmod4) {\n  case 1:\n    return _mm_set_ps(0.0f, 0.0f, 0.0f, src_ptr_offsetted[0]);\n    // ideally: movss\n  case 2:\n    return _mm_set_ps(0.0f, 0.0f, src_ptr_offsetted[1], src_ptr_offsetted[0]);\n    // ideally: movsd\n  case 3:\n    return _mm_set_ps(0.0f, src_ptr_offsetted[2], src_ptr_offsetted[1], src_ptr_offsetted[0]);\n    // ideally: movss + movsd + shuffle or movsd + insert\n  case 0:\n    return _mm_set_ps(src_ptr_offsetted[3], src_ptr_offsetted[2], src_ptr_offsetted[1], src_ptr_offsetted[0]);\n    // ideally: movups\n  default:\n    return _mm_setzero_ps(); // n/a cannot happen\n  }\n}\n\n// Processes a horizontal resampling kernel of up to four coefficients for float pixel types.\n// Supports BilinearResize, BicubicResize, or sinc with up to 2 taps (filter size <= 4).\n// SSE2 optimization loads and processes four float coefficients and pixels simultaneously.\n// The 'filtersizemod4' template parameter (0-3) helps optimize for different filter sizes modulo 4.\n// This SSE2 requires only filter_size_alignment of 4.\ntemplate<int filtersizemod4>\nvoid resize_h_planar_float_sse_transpose_vstripe_ks4(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  assert(filtersizemod4 >= 0 && filtersizemod4 <= 3);\n\n  const int filter_size = program->filter_size; // aligned, practically the coeff table stride\n\n  src_pitch /= sizeof(float);\n  dst_pitch /= sizeof(float);\n\n  float* src = (float*)src8;\n  float* dst = (float*)dst8;\n\n  const float* AVS_RESTRICT current_coeff = (const float* AVS_RESTRICT)program->pixel_coefficient_float;\n\n  constexpr int PIXELS_AT_A_TIME = 4; // Process four pixels in parallel using SSE2\n\n  // 'source_overread_beyond_targetx' indicates if the filter kernel can read beyond the target width.\n  // Even if the filter alignment allows larger reads, our safety boundary for unaligned loads starts at 4 pixels back\n  // from the target width, as we load 4 floats at once with '_mm_loadu_ps'.\n  // In AVX2 we process two lanes, so any of the 8 offsets cannot be safely used, fallback to the unsafe case.\n  // This is why then safelimit_4_pixels is used combined with safelimit_4 / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME.\n  const int width_safe_mod = (program->safelimit_4_pixels.overread_possible ? program->safelimit_4_pixels.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;\n\n  // Preconditions:\n  assert(program->filter_size_real <= 4); // We preload all relevant coefficients (up to 4) before the height loop.\n\n  // 'target_size_alignment' ensures we can safely access coefficients using offsets like\n  // 'filter_size * 3' when processing 4 H pixels at a time\n  assert(program->target_size_alignment >= 4);\n\n  // Ensure that coefficient loading beyond the valid target size is safe for 4x4 float loads.\n  assert(program->filter_size_alignment >= 4);\n\n  int x = 0;\n\n  // This 'auto' lambda construct replaces the need of templates\n  auto do_h_float_core = [&](auto partial_load) {\n    // Load up to 4 coefficients at once before the height loop.\n    // Pre-loading and transposing coefficients keeps register usage efficient.\n    // Assumes 'filter_size_aligned' is at least 4.\n    __m128 coeff_1 = _mm_load_ps(current_coeff + filter_size * 0); // Coefficients for the source pixel offset (for src_ptr + begin1 [0..3])\n    __m128 coeff_2 = _mm_load_ps(current_coeff + filter_size * 1); // for src_ptr + begin2 [0..3]\n    __m128 coeff_3 = _mm_load_ps(current_coeff + filter_size * 2); // for src_ptr + begin3 [0..3]\n    __m128 coeff_4 = _mm_load_ps(current_coeff + filter_size * 3); // for src_ptr + begin4 [0..3]\n\n    _MM_TRANSPOSE4_PS(coeff_1, coeff_2, coeff_3, coeff_4);\n\n    float* AVS_RESTRICT dst_ptr = dst + x;\n    const float* src_ptr = src;\n\n    // Pixel offsets for the current target x-positions.\n    // Even for x >= width, these offsets are guaranteed to be within the allocated 'target_size_alignment'.\n    const int begin1 = program->pixel_offset[x + 0];\n    const int begin2 = program->pixel_offset[x + 1];\n    const int begin3 = program->pixel_offset[x + 2];\n    const int begin4 = program->pixel_offset[x + 3];\n\n    for (int y = 0; y < height; y++)\n    {\n      __m128 data_1;\n      __m128 data_2;\n      __m128 data_3;\n      __m128 data_4;\n      if constexpr (partial_load) {\n        // In the potentially unsafe zone (near the right edge of the image), we use a safe loading function\n        // to prevent reading beyond the allocated source scanline. This handles cases where loading 4 floats\n        // starting from 'src_ptr + beginX' might exceed the source buffer.\n\n        // Example of the unsafe scenario: If target width is 320, a naive load at src_ptr + 317\n        // would attempt to read floats at indices 317, 318, 319, and 320, potentially going out of bounds.\n\n        // Two main issues in the unsafe zone:\n        // 1.) Out-of-bounds memory access: Reading beyond the allocated memory for the source scanline can\n        //     lead to access violations and crashes. '_mm_loadu_ps' attempts to load 16 bytes, so even if\n        //     the starting address is within bounds, subsequent reads might not be.\n        // 2.) Garbage or NaN values: Even if a read doesn't cause a crash, accessing uninitialized or\n        //     out-of-bounds memory (especially for float types) can result in garbage data, including NaN.\n        //     Multiplying by a valid coefficient and accumulating this NaN can contaminate the final result.\n\n        // 'load_partial_safe_sse2' safely loads up to 'filter_size_real' pixels and pads with zeros if needed,\n        // preventing out-of-bounds reads and ensuring predictable results even near the image edges.\n\n        data_1 = load_partial_safe_sse2<filtersizemod4>(src_ptr + begin1);\n        data_2 = load_partial_safe_sse2<filtersizemod4>(src_ptr + begin2);\n        data_3 = load_partial_safe_sse2<filtersizemod4>(src_ptr + begin3);\n        data_4 = load_partial_safe_sse2<filtersizemod4>(src_ptr + begin4);\n      }\n      else {\n        // In the safe zone, we can directly load 4 pixels at a time using unaligned loads.\n        data_1 = _mm_loadu_ps(src_ptr + begin1);\n        data_2 = _mm_loadu_ps(src_ptr + begin2);\n        data_3 = _mm_loadu_ps(src_ptr + begin3);\n        data_4 = _mm_loadu_ps(src_ptr + begin4);\n      }\n\n      _MM_TRANSPOSE4_PS(data_1, data_2, data_3, data_4);\n\n      __m128 result = _mm_mul_ps(data_1, coeff_1);\n      result = _mm_add_ps(_mm_mul_ps(data_2, coeff_2), result);\n      result = _mm_add_ps(_mm_mul_ps(data_3, coeff_3), result);\n      result = _mm_add_ps(_mm_mul_ps(data_4, coeff_4), result);\n\n      _mm_store_ps(dst_ptr, result);\n\n      dst_ptr += dst_pitch;\n      src_ptr += src_pitch;\n    } // y\n    current_coeff += filter_size * 4; // Move to the next set of coefficients for the next 4 output pixels\n    }; // end of lambda\n\n  // Process the 'safe zone' where direct full unaligned loads are acceptable.\n  for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)\n  {\n    do_h_float_core(std::false_type{}); // partial_load == false, use direct _mm_loadu_ps\n  }\n\n  // Process the potentially 'unsafe zone' near the image edge, using safe loading.\n  for (; x < width; x += PIXELS_AT_A_TIME)\n  {\n    do_h_float_core(std::true_type{}); // partial_load == true, use the safer 'load_partial_safe_sse2'\n  }\n}\n\n// Instantiate them\ntemplate void resize_h_planar_float_sse_transpose_vstripe_ks4<0>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resize_h_planar_float_sse_transpose_vstripe_ks4<1>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resize_h_planar_float_sse_transpose_vstripe_ks4<2>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resize_h_planar_float_sse_transpose_vstripe_ks4<3>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n"
  },
  {
    "path": "avs_core/filters/intel/resample_sse.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Resample_SSE_H__\n#define __Resample_SSE_H__\n\n#include <avisynth.h>\n#include <avs/config.h>\n#include \"../resample.h\"\n\n#ifdef X86_32\nvoid resize_v_mmx_planar(BYTE* dst, const BYTE* src, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel);\n#endif\nvoid resize_v_sse2_planar(BYTE* dst, const BYTE* src, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel);\n\ntemplate<bool lessthan16bit>\nvoid resize_v_sse2_planar_uint16_t(BYTE* dst0, const BYTE* src0, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel);\n\nvoid resize_v_sse2_planar_float(BYTE* dst0, const BYTE* src0, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel);\n\ntemplate<typename pixel_t, bool lessthan16bit>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nvoid resizer_h_ssse3_generic_uint8_16(BYTE* dst, const BYTE* src, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nvoid resizer_h_ssse3_generic_float(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\ntemplate<int filtersizemod4>\nvoid resize_h_planar_float_sse_transpose_vstripe_ks4(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\n#endif // __Resample_SSE_H__\n"
  },
  {
    "path": "avs_core/filters/intel/resize_sse.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include <avisynth.h>\n\n// Intrinsics base header + really required extension headers\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n\n\n\n//todo: think of a way to do this with pavgb\nstatic AVS_FORCEINLINE __m128i vertical_reduce_sse2_blend(__m128i& src, __m128i& src_next, __m128i& src_next2, __m128i& zero, __m128i& two) {\n  __m128i src_unpck_lo = _mm_unpacklo_epi8(src, zero);\n  __m128i src_unpck_hi = _mm_unpackhi_epi8(src, zero);\n\n  __m128i src_next_unpck_lo = _mm_unpacklo_epi8(src_next, zero);\n  __m128i src_next_unpck_hi = _mm_unpackhi_epi8(src_next, zero);\n\n  __m128i src_next2_unpck_lo = _mm_unpacklo_epi8(src_next2, zero);\n  __m128i src_next2_unpck_hi = _mm_unpackhi_epi8(src_next2, zero);\n\n  __m128i acc_lo = _mm_adds_epu16(src_next_unpck_lo, src_next_unpck_lo);\n  acc_lo = _mm_adds_epu16(acc_lo, src_unpck_lo);\n  acc_lo = _mm_adds_epu16(acc_lo, src_next2_unpck_lo);\n\n  __m128i acc_hi = _mm_adds_epu16(src_next_unpck_hi, src_next_unpck_hi);\n  acc_hi = _mm_adds_epu16(acc_hi, src_unpck_hi);\n  acc_hi = _mm_adds_epu16(acc_hi, src_next2_unpck_hi);\n\n  acc_lo = _mm_adds_epu16(acc_lo, two);\n  acc_hi = _mm_adds_epu16(acc_hi, two);\n\n  acc_lo = _mm_srai_epi16(acc_lo, 2);\n  acc_hi = _mm_srai_epi16(acc_hi, 2);\n\n  return _mm_packus_epi16(acc_lo, acc_hi);\n}\n\nvoid vertical_reduce_sse2(BYTE* dstp, const BYTE* srcp, int dst_pitch, int src_pitch, size_t width, size_t height) {\n  const BYTE* srcp_next = srcp + src_pitch;\n  const BYTE* srcp_next2 = srcp + src_pitch * 2;\n  __m128i zero = _mm_setzero_si128();\n  __m128i two = _mm_set1_epi16(2);\n\n  for (size_t y = 0; y < height - 1; ++y) {\n    for (size_t x = 0; x < width; x += 16) {\n      __m128i src = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x));\n      __m128i src_next = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp_next + x));\n      __m128i src_next2 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp_next2 + x));\n\n      __m128i avg = vertical_reduce_sse2_blend(src, src_next, src_next2, zero, two);\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x), avg);\n    }\n\n    dstp += dst_pitch;\n    srcp += src_pitch * 2;\n    srcp_next += src_pitch * 2;\n    srcp_next2 += src_pitch * 2;\n  }\n  //last line\n  for (size_t x = 0; x < width; x += 16) {\n    __m128i src = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x));\n    __m128i src_next = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp_next + x));\n\n    __m128i avg = vertical_reduce_sse2_blend(src, src_next, src_next, zero, two);\n\n    _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x), avg);\n  }\n}\n\n#ifdef X86_32\n\n//todo: think of a way to do this with pavgb\nstatic AVS_FORCEINLINE __m64 vertical_reduce_mmx_blend(__m64& src, __m64& src_next, __m64& src_next2, __m64& zero, __m64& two) {\n  __m64 src_unpck_lo = _mm_unpacklo_pi8(src, zero);\n  __m64 src_unpck_hi = _mm_unpackhi_pi8(src, zero);\n\n  __m64 src_next_unpck_lo = _mm_unpacklo_pi8(src_next, zero);\n  __m64 src_next_unpck_hi = _mm_unpackhi_pi8(src_next, zero);\n\n  __m64 src_next2_unpck_lo = _mm_unpacklo_pi8(src_next2, zero);\n  __m64 src_next2_unpck_hi = _mm_unpackhi_pi8(src_next2, zero);\n\n  __m64 acc_lo = _mm_adds_pu16(src_next_unpck_lo, src_next_unpck_lo);\n  acc_lo = _mm_adds_pu16(acc_lo, src_unpck_lo);\n  acc_lo = _mm_adds_pu16(acc_lo, src_next2_unpck_lo);\n\n  __m64 acc_hi = _mm_adds_pu16(src_next_unpck_hi, src_next_unpck_hi);\n  acc_hi = _mm_adds_pu16(acc_hi, src_unpck_hi);\n  acc_hi = _mm_adds_pu16(acc_hi, src_next2_unpck_hi);\n\n  acc_lo = _mm_adds_pu16(acc_lo, two);\n  acc_hi = _mm_adds_pu16(acc_hi, two);\n\n  acc_lo = _mm_srai_pi16(acc_lo, 2);\n  acc_hi = _mm_srai_pi16(acc_hi, 2);\n\n  return _mm_packs_pu16(acc_lo, acc_hi);\n}\n\nvoid vertical_reduce_mmx(BYTE* dstp, const BYTE* srcp, int dst_pitch, int src_pitch, size_t width, size_t height) {\n  const BYTE* srcp_next = srcp + src_pitch;\n  const BYTE* srcp_next2 = srcp + src_pitch * 2;\n  __m64 zero = _mm_setzero_si64();\n  __m64 two = _mm_set1_pi16(2);\n\n  size_t mod8_width = width / 8 * 8;\n\n  for (size_t y = 0; y < height - 1; ++y) {\n    for (size_t x = 0; x < mod8_width; x += 8) {\n      __m64 src = *reinterpret_cast<const __m64*>(srcp + x);\n      __m64 src_next = *reinterpret_cast<const __m64*>(srcp_next + x);\n      __m64 src_next2 = *reinterpret_cast<const __m64*>(srcp_next2 + x);\n\n      __m64 avg = vertical_reduce_mmx_blend(src, src_next, src_next2, zero, two);\n\n      *reinterpret_cast<__m64*>(dstp + x) = avg;\n    }\n\n    if (mod8_width != width) {\n      size_t x = width - 8;\n      __m64 src = *reinterpret_cast<const __m64*>(srcp + x);\n      __m64 src_next = *reinterpret_cast<const __m64*>(srcp_next + x);\n      __m64 src_next2 = *reinterpret_cast<const __m64*>(srcp_next2 + x);\n\n      __m64 avg = vertical_reduce_mmx_blend(src, src_next, src_next2, zero, two);\n\n      *reinterpret_cast<__m64*>(dstp + x) = avg;\n    }\n\n    dstp += dst_pitch;\n    srcp += src_pitch * 2;\n    srcp_next += src_pitch * 2;\n    srcp_next2 += src_pitch * 2;\n  }\n  //last line\n  for (size_t x = 0; x < mod8_width; x += 8) {\n    __m64 src = *reinterpret_cast<const __m64*>(srcp + x);\n    __m64 src_next = *reinterpret_cast<const __m64*>(srcp_next + x);\n\n    __m64 avg = vertical_reduce_mmx_blend(src, src_next, src_next, zero, two);\n\n    *reinterpret_cast<__m64*>(dstp + x) = avg;\n  }\n\n  if (mod8_width != width) {\n    size_t x = width - 8;\n    __m64 src = *reinterpret_cast<const __m64*>(srcp + x);\n    __m64 src_next = *reinterpret_cast<const __m64*>(srcp_next + x);\n\n    __m64 avg = vertical_reduce_mmx_blend(src, src_next, src_next, zero, two);\n\n    *reinterpret_cast<__m64*>(dstp + x) = avg;\n  }\n\n  _mm_empty();\n}\n#endif\n\n\n\n"
  },
  {
    "path": "avs_core/filters/intel/resize_sse.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Resize_SSE_H__\n#define __Resize_SSE_H__\n\n#include <avisynth.h>\n\nvoid vertical_reduce_sse2(BYTE* dstp, const BYTE* srcp, int dst_pitch, int src_pitch, size_t width, size_t height);\n#ifdef X86_32\nvoid vertical_reduce_mmx(BYTE* dstp, const BYTE* srcp, int dst_pitch, int src_pitch, size_t width, size_t height);\n#endif\n\n#endif  // __Resize_SSE_H__"
  },
  {
    "path": "avs_core/filters/intel/text-overlay_sse.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include <avisynth.h>\n#include <avs/minmax.h>\n#define __STDC_FORMAT_MACROS\n#include <inttypes.h>\n\n// Intrinsics base header + really required extension headers\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n\n\nvoid compare_sse2(uint32_t mask, int increment,\n                         const BYTE * f1ptr, int pitch1,\n                         const BYTE * f2ptr, int pitch2,\n                         int rowsize, int height,\n                         int &SAD_sum, int &SD_sum, int &pos_D,  int &neg_D, double &SSD_sum)\n{\n  // rowsize multiple of 16 for YUV Planar, RGB32 and YUY2; 12 for RGB24\n  // increment must be 3 for RGB24 and 4 for others\n\n  int64_t issd = 0;\n  __m128i sad_vector = _mm_setzero_si128(); //sum of absolute differences\n  __m128i sd_vector = _mm_setzero_si128(); // sum of differences\n  __m128i positive_diff = _mm_setzero_si128();\n  __m128i negative_diff = _mm_setzero_si128();\n  __m128i zero = _mm_setzero_si128();\n\n  __m128i mask64 = _mm_set_epi32(0, 0, 0, mask);\n  if (increment == 3) {\n    mask64 = _mm_or_si128(mask64, _mm_slli_si128(mask64, 3));\n    mask64 = _mm_or_si128(mask64, _mm_slli_si128(mask64, 6));\n  } else {\n    mask64 = _mm_or_si128(mask64, _mm_slli_si128(mask64, 4));\n    mask64 = _mm_or_si128(mask64, _mm_slli_si128(mask64, 8));\n  }\n\n\n\n  for (int y = 0; y < height; ++y) {\n    __m128i row_ssd = _mm_setzero_si128();  // sum of squared differences (row_SSD)\n\n    for (int x = 0; x < rowsize; x+=increment*4) {\n      __m128i src1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(f1ptr+x));\n      __m128i src2 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(f2ptr+x));\n\n      src1 = _mm_and_si128(src1, mask64);\n      src2 = _mm_and_si128(src2, mask64);\n\n      __m128i diff_1_minus_2 = _mm_subs_epu8(src1, src2);\n      __m128i diff_2_minus_1 = _mm_subs_epu8(src2, src1);\n\n      positive_diff = _mm_max_epu8(positive_diff, diff_1_minus_2);\n      negative_diff = _mm_max_epu8(negative_diff, diff_2_minus_1);\n\n      __m128i absdiff1 = _mm_sad_epu8(diff_1_minus_2, zero);\n      __m128i absdiff2 = _mm_sad_epu8(diff_2_minus_1, zero);\n\n      sad_vector = _mm_add_epi32(sad_vector, absdiff1);\n      sad_vector = _mm_add_epi32(sad_vector, absdiff2);\n\n      sd_vector = _mm_add_epi32(sd_vector, absdiff1);\n      sd_vector = _mm_sub_epi32(sd_vector, absdiff2);\n\n      __m128i ssd = _mm_or_si128(diff_1_minus_2, diff_2_minus_1);\n      __m128i ssd_lo = _mm_unpacklo_epi8(ssd, zero);\n      __m128i ssd_hi = _mm_unpackhi_epi8(ssd, zero);\n      ssd_lo   = _mm_madd_epi16(ssd_lo, ssd_lo);\n      ssd_hi   = _mm_madd_epi16(ssd_hi, ssd_hi);\n      row_ssd = _mm_add_epi32(row_ssd, ssd_lo);\n      row_ssd = _mm_add_epi32(row_ssd, ssd_hi);\n    }\n\n    f1ptr += pitch1;\n    f2ptr += pitch2;\n\n    __m128i tmp = _mm_srli_si128(row_ssd, 8);\n    row_ssd = _mm_add_epi32(row_ssd, tmp);\n    tmp = _mm_srli_si128(row_ssd, 4);\n    row_ssd = _mm_add_epi32(row_ssd, tmp);\n\n    issd += _mm_cvtsi128_si32(row_ssd);\n  }\n\n  SAD_sum += _mm_cvtsi128_si32(sad_vector);\n  SAD_sum += _mm_cvtsi128_si32(_mm_srli_si128(sad_vector, 8));\n  SD_sum  += _mm_cvtsi128_si32(sd_vector);\n  SD_sum += _mm_cvtsi128_si32(_mm_srli_si128(sd_vector, 8));\n\n  BYTE posdiff_tmp[16];\n  BYTE negdiff_tmp[16];\n  _mm_store_si128(reinterpret_cast<__m128i*>(posdiff_tmp), positive_diff);\n  _mm_store_si128(reinterpret_cast<__m128i*>(negdiff_tmp), negative_diff);\n\n  SSD_sum += (double)issd;\n\n  neg_D = -neg_D; // 160801! false neg_D fix for isse\n\n  for (int i = 0; i < increment*4; ++i) {\n    pos_D = max(pos_D, (int)(posdiff_tmp[i]));\n    neg_D = max(neg_D, (int)(negdiff_tmp[i]));\n  }\n\n  neg_D = -neg_D;\n}\n\n#ifdef X86_32\n\nvoid compare_isse(uint32_t mask, int increment,\n                         const BYTE * f1ptr, int pitch1,\n                         const BYTE * f2ptr, int pitch2,\n                         int rowsize, int height,\n                         int &SAD_sum, int &SD_sum, int &pos_D,  int &neg_D, double &SSD_sum)\n{\n  // rowsize multiple of 8 for YUV Planar, RGB32 and YUY2; 6 for RGB24\n  // increment must be 3 for RGB24 and 4 for others\n\n  int64_t issd = 0;\n  __m64 sad_vector = _mm_setzero_si64(); //sum of absolute differences\n  __m64 sd_vector = _mm_setzero_si64(); // sum of differences\n  __m64 positive_diff = _mm_setzero_si64();\n  __m64 negative_diff = _mm_setzero_si64();\n  __m64 zero = _mm_setzero_si64();\n\n  __m64 mask64 = _mm_set_pi32(0, mask);\n  mask64 = _mm_or_si64(mask64, _mm_slli_si64(mask64, increment*8));\n\n\n  for (int y = 0; y < height; ++y) {\n    __m64 row_ssd = _mm_setzero_si64();  // sum of squared differences (row_SSD)\n\n    for (int x = 0; x < rowsize; x+=increment*2) {\n      __m64 src1 = *reinterpret_cast<const __m64*>(f1ptr+x);\n      __m64 src2 = *reinterpret_cast<const __m64*>(f2ptr+x);\n\n      src1 = _mm_and_si64(src1, mask64);\n      src2 = _mm_and_si64(src2, mask64);\n\n      __m64 diff_1_minus_2 = _mm_subs_pu8(src1, src2);\n      __m64 diff_2_minus_1 = _mm_subs_pu8(src2, src1);\n\n      positive_diff = _mm_max_pu8(positive_diff, diff_1_minus_2);\n      negative_diff = _mm_max_pu8(negative_diff, diff_2_minus_1);\n\n      __m64 absdiff1 = _mm_sad_pu8(diff_1_minus_2, zero);\n      __m64 absdiff2 = _mm_sad_pu8(diff_2_minus_1, zero);\n\n      sad_vector = _mm_add_pi32(sad_vector, absdiff1);\n      sad_vector = _mm_add_pi32(sad_vector, absdiff2);\n\n      sd_vector = _mm_add_pi32(sd_vector, absdiff1);\n      sd_vector = _mm_sub_pi32(sd_vector, absdiff2);\n\n      __m64 ssd = _mm_or_si64(diff_1_minus_2, diff_2_minus_1);\n      __m64 ssd_lo = _mm_unpacklo_pi8(ssd, zero);\n      __m64 ssd_hi = _mm_unpackhi_pi8(ssd, zero);\n      ssd_lo   = _mm_madd_pi16(ssd_lo, ssd_lo);\n      ssd_hi   = _mm_madd_pi16(ssd_hi, ssd_hi);\n      row_ssd = _mm_add_pi32(row_ssd, ssd_lo);\n      row_ssd = _mm_add_pi32(row_ssd, ssd_hi);\n    }\n\n    f1ptr += pitch1;\n    f2ptr += pitch2;\n\n    __m64 tmp = _mm_unpackhi_pi32(row_ssd, zero);\n    row_ssd = _mm_add_pi32(row_ssd, tmp);\n\n    issd += _mm_cvtsi64_si32(row_ssd);\n  }\n\n  SAD_sum += _mm_cvtsi64_si32(sad_vector);\n  SD_sum  += _mm_cvtsi64_si32(sd_vector);\n\n  BYTE posdiff_tmp[8];\n  BYTE negdiff_tmp[8];\n  *reinterpret_cast<__m64*>(posdiff_tmp) = positive_diff;\n  *reinterpret_cast<__m64*>(negdiff_tmp) = negative_diff;\n  _mm_empty();\n\n  SSD_sum += (double)issd;\n\n  neg_D = -neg_D; // 160801! false neg_D fix for isse\n\n  for (int i = 0; i < increment*2; ++i) {\n    pos_D = max(pos_D, (int)(posdiff_tmp[i]));\n    neg_D = max(neg_D, (int)(negdiff_tmp[i]));\n  }\n\n  neg_D = -neg_D;\n}\n\n#endif\n\n\n\n"
  },
  {
    "path": "avs_core/filters/intel/text-overlay_sse.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Text_overlay_SSE_H__\n#define __Text_overlay_SSE_H__\n\n#include <avisynth.h>\n\nvoid compare_sse2(uint32_t mask, int increment, const BYTE * f1ptr, int pitch1, const BYTE * f2ptr, int pitch2,\n                         int rowsize, int height, int &SAD_sum, int &SD_sum, int &pos_D,  int &neg_D, double &SSD_sum);\n\n#ifdef X86_32\nvoid compare_isse(uint32_t mask, int increment, const BYTE * f1ptr, int pitch1, const BYTE * f2ptr, int pitch2,\n                         int rowsize, int height, int &SAD_sum, int &SD_sum, int &pos_D,  int &neg_D, double &SSD_sum);\n#endif\n\n#endif  // __Text_overlay_SSE_H__\n"
  },
  {
    "path": "avs_core/filters/intel/turn_avx2.cpp",
    "content": "// AviSynth+.  Copyright 2026- AviSynth+ Project\n// https://avs-plus.net\n// http://avisynth.nl\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include \"../turn.h\"\n#include \"turn_avx2.h\"\n\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n#include <immintrin.h>\n\n#include <cstdint>\n\n//-------------------------------------------------------------------------------------------------\n// 8-bit Transpose Kernels\n//-------------------------------------------------------------------------------------------------\n\n// The final winner over 8x8, 16x8 and 8x32.\n// Transpose 32x8 (input) -> 8x32 (output)\n// Input: 32 rows of 8 pixels (uint8_t)\n// Output: 8 rows of 32 pixels\nstatic AVS_FORCEINLINE void transpose_32x8x8_avx2(const uint8_t* AVS_RESTRICT srcp, uint8_t* AVS_RESTRICT dstp, const int src_pitch, const int dst_pitch)\n{\n  // Load 32 rows, 8 bytes each\n  // One 256 bit register contains 4x8 bytes, which are 4 rows apart, so A,E,I,M in reg0, B,F,J,N in reg1, etc.\n  // after reaching the 16th row, it continues with Q,U,Y,c in reg4, R,V,Z,d in reg5, etc.\n  auto load_quad_row = [](const uint8_t* base, int pitch, int offset) -> __m256i {\n    __m128i r0 = _mm_loadu_si64((const __m128i*)(base + (offset + 0 * 4) * pitch));\n    __m128i r1 = _mm_loadu_si64((const __m128i*)(base + (offset + 1 * 4) * pitch));\n    __m128i r2 = _mm_loadu_si64((const __m128i*)(base + (offset + 2 * 4) * pitch));\n    __m128i r3 = _mm_loadu_si64((const __m128i*)(base + (offset + 3 * 4) * pitch));\n\n    __m128i r01 = _mm_unpacklo_epi64(r0, r1);\n    __m128i r23 = _mm_unpacklo_epi64(r2, r3);\n    return _mm256_inserti128_si256(_mm256_castsi128_si256(r01), r23, 1);\n  };\n\n  // Load 32 rows into 8 registers\n  __m256i r0 = load_quad_row(srcp, src_pitch, 0);  // Rows 0,4,8,12\n  __m256i r1 = load_quad_row(srcp, src_pitch, 1);  // Rows 1,5,9,13\n  __m256i r2 = load_quad_row(srcp, src_pitch, 2);  // Rows 2,6,10,14\n  __m256i r3 = load_quad_row(srcp, src_pitch, 3);  // Rows 3,7,11,15\n  __m256i r4 = load_quad_row(srcp, src_pitch, 16); // Rows 16,20,24,28\n  __m256i r5 = load_quad_row(srcp, src_pitch, 17); // Rows 17,21,25,29\n  __m256i r6 = load_quad_row(srcp, src_pitch, 18); // Rows 18,22,26,30\n  __m256i r7 = load_quad_row(srcp, src_pitch, 19); // Rows 19,23,27,31\n\n  __m256i t0 = _mm256_unpacklo_epi8(r0, r1);\n  __m256i t1 = _mm256_unpackhi_epi8(r0, r1);\n  __m256i t2 = _mm256_unpacklo_epi8(r2, r3);\n  __m256i t3 = _mm256_unpackhi_epi8(r2, r3);\n  __m256i t4 = _mm256_unpacklo_epi8(r4, r5);\n  __m256i t5 = _mm256_unpackhi_epi8(r4, r5);\n  __m256i t6 = _mm256_unpacklo_epi8(r6, r7);\n  __m256i t7 = _mm256_unpackhi_epi8(r6, r7);\n\n  __m256i u0 = _mm256_unpacklo_epi16(t0, t2);\n  __m256i u1 = _mm256_unpacklo_epi16(t1, t3);\n  __m256i u2 = _mm256_unpackhi_epi16(t0, t2);\n  __m256i u3 = _mm256_unpackhi_epi16(t1, t3);\n  __m256i u4 = _mm256_unpacklo_epi16(t4, t6);\n  __m256i u5 = _mm256_unpacklo_epi16(t5, t7);\n  __m256i u6 = _mm256_unpackhi_epi16(t4, t6);\n  __m256i u7 = _mm256_unpackhi_epi16(t5, t7);\n\n  __m256i v0 = _mm256_unpacklo_epi32(u0, u1);\n  __m256i v1 = _mm256_unpackhi_epi32(u0, u1);\n  __m256i v2 = _mm256_unpacklo_epi32(u2, u3);\n  __m256i v3 = _mm256_unpackhi_epi32(u2, u3);\n  __m256i v4 = _mm256_unpacklo_epi32(u4, u5);\n  __m256i v5 = _mm256_unpackhi_epi32(u4, u5);\n  __m256i v6 = _mm256_unpacklo_epi32(u6, u7);\n  __m256i v7 = _mm256_unpackhi_epi32(u6, u7);\n\n  __m256i w0 = _mm256_unpacklo_epi64(v0, v4); // AH0, QX0, IP0, Yf0\n  __m256i w1 = _mm256_unpackhi_epi64(v0, v4); // AH1, QX1, IP1, Yf1\n  __m256i w2 = _mm256_unpacklo_epi64(v1, v5); // AH2, QX2, IP2, Yf2\n  __m256i w3 = _mm256_unpackhi_epi64(v1, v5); // AH3, QX3, IP3, Yf3\n  __m256i w4 = _mm256_unpacklo_epi64(v2, v6); // AH4, QX4, IP4, Yf4\n  __m256i w5 = _mm256_unpackhi_epi64(v2, v6); // AH5, QX5, IP5, Yf5\n  __m256i w6 = _mm256_unpacklo_epi64(v3, v7); // AH6, QX6, IP6, Yf6\n  __m256i w7 = _mm256_unpackhi_epi64(v3, v7); // AH7, QX7, IP7, Yf7\n\n  // Cross-lane permute to fix AVX2 dual-lane unpack.\n  // Arrange 64-bit blocks into the correct linear order\n  const int PERM_CTRL = 0b11'01'10'00; // Standard 0,2,1,3 permute\n  __m256i out0 = _mm256_permute4x64_epi64(w0, PERM_CTRL); // AH0 | IP0 | QX0 | Yf0: ABCEFGHIJKLMNOPQRTSUVWXYZabcdef_0 ready\n  __m256i out1 = _mm256_permute4x64_epi64(w1, PERM_CTRL); // AH1 | IP1 | QX1 | Yf1\n  __m256i out2 = _mm256_permute4x64_epi64(w2, PERM_CTRL); // AH2 | IP2 | QX2 | Yf2\n  __m256i out3 = _mm256_permute4x64_epi64(w3, PERM_CTRL); // AH3 | IP3 | QX3 | Yf3\n  __m256i out4 = _mm256_permute4x64_epi64(w4, PERM_CTRL); // AH4 | IP4 | QX4 | Yf4\n  __m256i out5 = _mm256_permute4x64_epi64(w5, PERM_CTRL); // AH5 | IP5 | QX5 | Yf5\n  __m256i out6 = _mm256_permute4x64_epi64(w6, PERM_CTRL); // AH6 | IP6 | QX6 | Yf6\n  __m256i out7 = _mm256_permute4x64_epi64(w7, PERM_CTRL); // AH7 | IP7 | QX7 | Yf7\n\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + 0 * dst_pitch), out0);\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + 1 * dst_pitch), out1);\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + 2 * dst_pitch), out2);\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + 3 * dst_pitch), out3);\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + 4 * dst_pitch), out4);\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + 5 * dst_pitch), out5);\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + 6 * dst_pitch), out6);\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + 7 * dst_pitch), out7);\n}\n\nvoid turn_right_plane_8_avx2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n  // Start at the BOTTOM left of the source\n  const uint8_t* s0 = srcp + src_pitch * (src_height - 1);\n\n  constexpr int PIXELS_W = 8; // width block size\n  constexpr int PIXELS_H = 32; // height block size\n\n  const int w = src_rowsize & ~(PIXELS_W * sizeof(uint8_t) - 1);\n  const int h = src_height & ~(PIXELS_H - 1);\n  const int simd_width_in_pixels = w / sizeof(uint8_t);\n\n  for (int y = 0; y < h; y += PIXELS_H)\n  {\n    // Destination starts at y offset\n    uint8_t* d0 = dstp + y;\n\n    for (int x = 0; x < w; x += PIXELS_W * sizeof(uint8_t))\n    {\n      // Use negative pitch to load rows bottom-to-top to avoid row reversing after transpose.\n      transpose_32x8x8_avx2(s0 + x, d0, -src_pitch, dst_pitch);\n\n      d0 += PIXELS_W * dst_pitch;\n    }\n    s0 -= PIXELS_H * src_pitch;\n  }\n\n  // Boundary handling fallback\n  if (src_rowsize != w)\n  {\n    // consider calling the sse2 version when difference is at least 8, since sse2 does 8x8 blocks\n    turn_right_plane_8_c(srcp + w, dstp + dst_pitch * simd_width_in_pixels, src_rowsize - w, src_height, src_pitch, dst_pitch);\n  }\n\n  if (src_height != h)\n  {\n    turn_right_plane_8_c(srcp, dstp + h * sizeof(uint8_t), src_rowsize, src_height - h, src_pitch, dst_pitch);\n  }\n}\n\nvoid turn_left_plane_8_avx2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n  turn_right_plane_8_avx2(srcp + src_pitch * (src_height - 1), dstp + dst_pitch * (src_rowsize / sizeof(uint8_t) - 1), src_rowsize, src_height, -src_pitch, -dst_pitch);\n}\n\n//-------------------------------------------------------------------------------------------------\n// 16-bit Transpose Kernels\n//-------------------------------------------------------------------------------------------------\n\n// Transpose 8x16 (input) -> 16x8 (output)\n// Input: 16 rows of 8 pixels (uint16_t)\n// Output: 8 rows of 16 pixels\nstatic AVS_FORCEINLINE void transpose_16x8x16_avx2(const BYTE* AVS_RESTRICT srcp, BYTE* AVS_RESTRICT dstp, const int src_pitch, const int dst_pitch)\n{\n  // Helper to load 16 bytes from row i (low lane) and row i+8 (high lane)\n  auto load_dual_row_avx2 = [](const BYTE* base, int pitch, int row_idx) -> __m256i\n  {\n    __m128i lo = _mm_loadu_si128(reinterpret_cast<const __m128i*>(base + pitch * row_idx));\n    __m128i hi = _mm_loadu_si128(reinterpret_cast<const __m128i*>(base + pitch * (row_idx + 8)));\n    return _mm256_inserti128_si256(_mm256_castsi128_si256(lo), hi, 1);\n  };\n\n  // Load 16 rows into 8 registers.\n  // Row x in low lane and row x+8 in high lane.\n  __m256i v0 = load_dual_row_avx2(srcp, src_pitch, 0); // r0 | r8 // A0..A7 | I0..I7\n  __m256i v1 = load_dual_row_avx2(srcp, src_pitch, 1); // r1 | r9 // B0..B7 | J0..J7\n  __m256i v2 = load_dual_row_avx2(srcp, src_pitch, 2); // r2 | r10 // C0..C7 | K0..K7\n  __m256i v3 = load_dual_row_avx2(srcp, src_pitch, 3); // r3 | r11 // D0..D7 | L0..L7\n  __m256i v4 = load_dual_row_avx2(srcp, src_pitch, 4); // r4 | r12 // E0..E7 | M0..M7\n  __m256i v5 = load_dual_row_avx2(srcp, src_pitch, 5); // r5 | r13 // F0..F7 | N0..N7\n  __m256i v6 = load_dual_row_avx2(srcp, src_pitch, 6); // r6 | r14 // G0..G7 | O0..O7\n  __m256i v7 = load_dual_row_avx2(srcp, src_pitch, 7); // r7 | r15 // H0..H7 | P0..P7\n\n  // Standard 8x8 Transpose Logic (applied to both lanes simultaneously)\n  __m256i t0 = _mm256_unpacklo_epi16(v0, v1); // A0 B0 A1 B1 A2 B2 A3 B3 | I0 J0 I1 J1 I2 J2 I3 J3\n  __m256i t1 = _mm256_unpackhi_epi16(v0, v1); // A4 B4 A5 B5 A6 B6 A7 B7 | I4 J4 I5 J5 I6 J6 I7 J7\n  __m256i t2 = _mm256_unpacklo_epi16(v2, v3); // C0 D0 C1 D1 C2 D2 C3 D3 | K0 L0 K1 L1 K2 L2 K3 L3\n  __m256i t3 = _mm256_unpackhi_epi16(v2, v3); // C4 D4 C5 D5 C6 D6 C7 D7 | K4 L4 K5 L5 K6 L6 K7 L7\n  __m256i t4 = _mm256_unpacklo_epi16(v4, v5); // E0 F0 E1 F1 E2 F2 E3 F3 | M0 N0 M1 N1 M2 N2 M3 N3\n  __m256i t5 = _mm256_unpackhi_epi16(v4, v5); // E4 F4 E5 F5 E6 F6 E7 F7 | M4 N4 M5 N5 M6 N6 M7 N7\n  __m256i t6 = _mm256_unpacklo_epi16(v6, v7); // G0 H0 G1 H1 G2 H2 G3 H3 | O0 P0 O1 P1 O2 P2 O3 P3\n  __m256i t7 = _mm256_unpackhi_epi16(v6, v7); // G4 H4 G5 H5 G6 H6 G7 H7 | O4 P4 O5 P5 O6 P6 O7 P7\n\n  __m256i m0 = _mm256_unpacklo_epi32(t0, t2); // AD0,AD1 | IL0,IL1\n  __m256i m1 = _mm256_unpackhi_epi32(t0, t2); // AD2,AD3 | IL2,IL3\n  __m256i m2 = _mm256_unpacklo_epi32(t1, t3); // AD4,AD5 | IL4,IL5\n  __m256i m3 = _mm256_unpackhi_epi32(t1, t3); // AD6,AD7 | IL6,IL7\n  __m256i m4 = _mm256_unpacklo_epi32(t4, t6); // EH0,EH1 | MP0,MP1\n  __m256i m5 = _mm256_unpackhi_epi32(t4, t6); // EH2,EH3 | MP2,MP3\n  __m256i m6 = _mm256_unpacklo_epi32(t5, t7); // EH4,EH5 | MP4,MP5\n  __m256i m7 = _mm256_unpackhi_epi32(t5, t7); // EH6,EH7 | MP6,MP7\n\n  __m256i out0 = _mm256_unpacklo_epi64(m0, m4); // AD0,EH0 | IL0,MP0\n  __m256i out1 = _mm256_unpackhi_epi64(m0, m4); // AD1,EH1 | IL1,MP1\n  __m256i out2 = _mm256_unpacklo_epi64(m1, m5); // AD2,EH2 | IL2,MP2\n  __m256i out3 = _mm256_unpackhi_epi64(m1, m5); // AD3,EH3 | IL3,MP3\n  __m256i out4 = _mm256_unpacklo_epi64(m2, m6); // AD4,EH4 | IL4,MP4\n  __m256i out5 = _mm256_unpackhi_epi64(m2, m6); // AD5,EH5 | IL5,MP5\n  __m256i out6 = _mm256_unpacklo_epi64(m3, m7); // AD6,EH6 | IL6,MP6\n  __m256i out7 = _mm256_unpackhi_epi64(m3, m7); // AD7,EH7 | IL7,MP7\n\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + dst_pitch * 0), out0);\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + dst_pitch * 1), out1);\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + dst_pitch * 2), out2);\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + dst_pitch * 3), out3);\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + dst_pitch * 4), out4);\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + dst_pitch * 5), out5);\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + dst_pitch * 6), out6);\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + dst_pitch * 7), out7);\n}\n\nvoid turn_right_plane_16_avx2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n  // source order: bottom to top\n  const BYTE* s0 = srcp + src_pitch * (src_height - 1);\n\n  constexpr int PIXELS_W = 8; // width block size\n  constexpr int PIXELS_H = 16; // height block size\n\n  const int w = src_rowsize & ~(PIXELS_W * sizeof(uint16_t) - 1);\n  const int h = src_height & ~(PIXELS_H - 1);\n  const int simd_width_in_pixels = w / sizeof(uint16_t);\n\n  for (int y = 0; y < h; y += PIXELS_H)\n  {\n    BYTE* d0 = dstp + y * sizeof(uint16_t);\n\n    for (int x = 0; x < w; x += PIXELS_W * sizeof(uint16_t))\n    {\n      // Use negative pitch to load rows bottom-to-top to avoid row reversing after transpose.\n      transpose_16x8x16_avx2(s0 + x, d0, -src_pitch, dst_pitch);\n      d0 += PIXELS_W * dst_pitch;\n    }\n    s0 -= PIXELS_H * src_pitch;\n  }\n\n  // Boundary handling\n  if (src_rowsize != w)\n  {\n    turn_right_plane_16_c(srcp + w, dstp + dst_pitch * simd_width_in_pixels, src_rowsize - w, src_height, src_pitch, dst_pitch);\n  }\n\n  if (src_height != h)\n  {\n    turn_right_plane_16_c(srcp, dstp + h * sizeof(uint16_t), src_rowsize, src_height - h, src_pitch, dst_pitch);\n  }\n}\n\nvoid turn_left_plane_16_avx2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n  turn_right_plane_16_avx2(srcp + src_pitch * (src_height - 1), dstp + dst_pitch * (src_rowsize / sizeof(uint16_t) - 1), src_rowsize, src_height, -src_pitch, -dst_pitch);\n}\n\n//-------------------------------------------------------------------------------------------------\n// 32-bit Transpose Kernels (Float/RGB32)\n//-------------------------------------------------------------------------------------------------\n\nstatic AVS_FORCEINLINE void transpose_8x8_32bit_avx2(const BYTE* AVS_RESTRICT srcp, BYTE* AVS_RESTRICT dstp, int src_pitch, int dst_pitch)\n{\n  // load 8 rows of 8 pixels (32-bit each)\n  __m256i r0 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(srcp + src_pitch * 0));\n  __m256i r1 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(srcp + src_pitch * 1));\n  __m256i r2 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(srcp + src_pitch * 2));\n  __m256i r3 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(srcp + src_pitch * 3));\n  __m256i r4 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(srcp + src_pitch * 4));\n  __m256i r5 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(srcp + src_pitch * 5));\n  __m256i r6 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(srcp + src_pitch * 6));\n  __m256i r7 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(srcp + src_pitch * 7));\n\n  __m256i t0 = _mm256_unpacklo_epi32(r0, r1);\n  __m256i t1 = _mm256_unpackhi_epi32(r0, r1);\n  __m256i t2 = _mm256_unpacklo_epi32(r2, r3);\n  __m256i t3 = _mm256_unpackhi_epi32(r2, r3);\n  __m256i t4 = _mm256_unpacklo_epi32(r4, r5);\n  __m256i t5 = _mm256_unpackhi_epi32(r4, r5);\n  __m256i t6 = _mm256_unpacklo_epi32(r6, r7);\n  __m256i t7 = _mm256_unpackhi_epi32(r6, r7);\n\n  __m256i q0 = _mm256_unpacklo_epi64(t0, t2);\n  __m256i q1 = _mm256_unpackhi_epi64(t0, t2);\n  __m256i q2 = _mm256_unpacklo_epi64(t1, t3);\n  __m256i q3 = _mm256_unpackhi_epi64(t1, t3);\n  __m256i q4 = _mm256_unpacklo_epi64(t4, t6);\n  __m256i q5 = _mm256_unpackhi_epi64(t4, t6);\n  __m256i q6 = _mm256_unpacklo_epi64(t5, t7);\n  __m256i q7 = _mm256_unpackhi_epi64(t5, t7);\n\n  // cross-lane permute\n  // out0..3 gets low lane of (rows 0-3) and low lane of (rows 4-7)\n  // out4..7 gets high lane of (rows 0-3) and high lane of (rows 4-7)\n  __m256i out0 = _mm256_permute2x128_si256(q0, q4, 0x20);\n  __m256i out1 = _mm256_permute2x128_si256(q1, q5, 0x20);\n  __m256i out2 = _mm256_permute2x128_si256(q2, q6, 0x20);\n  __m256i out3 = _mm256_permute2x128_si256(q3, q7, 0x20);\n  __m256i out4 = _mm256_permute2x128_si256(q0, q4, 0x31);\n  __m256i out5 = _mm256_permute2x128_si256(q1, q5, 0x31);\n  __m256i out6 = _mm256_permute2x128_si256(q2, q6, 0x31);\n  __m256i out7 = _mm256_permute2x128_si256(q3, q7, 0x31);\n\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + dst_pitch * 0), out0);\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + dst_pitch * 1), out1);\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + dst_pitch * 2), out2);\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + dst_pitch * 3), out3);\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + dst_pitch * 4), out4);\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + dst_pitch * 5), out5);\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + dst_pitch * 6), out6);\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + dst_pitch * 7), out7);\n}\n\n// float, rgb32\nvoid turn_right_plane_32_avx2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n  // source order: bottom to top\n  const BYTE* s0 = srcp + src_pitch * (src_height - 1);\n\n  constexpr int PIXELS_W = 8; // width block size\n  constexpr int PIXELS_H = 8; // height block size\n\n  const int w = src_rowsize & ~(PIXELS_W * sizeof(uint32_t) - 1);\n  const int h = src_height & ~(PIXELS_H - 1);\n  const int simd_width_in_pixels = w / sizeof(uint32_t);\n\n  for (int y = 0; y < h; y += PIXELS_H)\n  {\n    // Destination grows forward: y index becomes the x-offset in the rotated image\n    BYTE* d0 = dstp + y * sizeof(uint32_t);\n\n    for (int x = 0; x < w; x += PIXELS_W * sizeof(uint32_t))\n    {\n      // Use negative pitch to load rows bottom-to-top to avoid row reversing after transpose.\n      transpose_8x8_32bit_avx2(s0 + x, d0, -src_pitch, dst_pitch);\n      d0 += PIXELS_W * dst_pitch;\n    }\n    s0 -= PIXELS_H * src_pitch;\n  }\n\n  // Boundary handling fallbacks\n  if (src_rowsize != w)\n  {\n    turn_right_plane_32_c(srcp + w, dstp + dst_pitch * simd_width_in_pixels, src_rowsize - w, src_height, src_pitch, dst_pitch);\n  }\n  if (src_height != h)\n  {\n    turn_right_plane_32_c(srcp, dstp + h * sizeof(uint32_t), src_rowsize, src_height - h, src_pitch, dst_pitch);\n  }\n}\n\nvoid turn_left_plane_32_avx2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n  turn_right_plane_32_avx2(srcp + src_pitch * (src_height - 1), dstp + dst_pitch * (src_rowsize / sizeof(float) - 1), src_rowsize, src_height, -src_pitch, -dst_pitch);\n}\n\nvoid turn_left_rgb32_avx2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n  // packed rgb is upside down\n  turn_right_plane_32_avx2(srcp, dstp, src_rowsize, src_height, src_pitch, dst_pitch);\n}\n\nvoid turn_right_rgb32_avx2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n  // packed rgb is upside down\n  turn_left_plane_32_avx2(srcp, dstp, src_rowsize, src_height, src_pitch, dst_pitch);\n}\n\n//-------------------------------------------------------------------------------------------------\n// 64-bit Transpose Kernels (RGB64)\n//-------------------------------------------------------------------------------------------------\n\nstatic AVS_FORCEINLINE void transpose_4x4_64bit_avx2(const BYTE* AVS_RESTRICT srcp, BYTE* AVS_RESTRICT dstp, int src_pitch, int dst_pitch)\n{\n  // Load 4 rows (4 pixels each reg = 32 bytes = 1 YMM register)\n  __m256i r0 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(srcp + src_pitch * 0));\n  __m256i r1 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(srcp + src_pitch * 1));\n  __m256i r2 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(srcp + src_pitch * 2));\n  __m256i r3 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(srcp + src_pitch * 3));\n\n  __m256i t0 = _mm256_unpacklo_epi64(r0, r1); // [R0_P0, R1_P0 | R0_P2, R1_P2]\n  __m256i t1 = _mm256_unpackhi_epi64(r0, r1); // [R0_P1, R1_P1 | R0_P3, R1_P3]\n  __m256i t2 = _mm256_unpacklo_epi64(r2, r3); // [R2_P0, R3_P0 | R2_P2, R3_P2]\n  __m256i t3 = _mm256_unpackhi_epi64(r2, r3); // [R2_P1, R3_P1 | R2_P3, R3_P3]\n\n  // Cross lane permute\n  // Combine low lanes of t0/t2, t1/t3 and high lanes of t0/t2, t1/t3\n  __m256i d0 = _mm256_permute2x128_si256(t0, t2, 0x20); // Column 0: [R0-R3]_P0\n  __m256i d1 = _mm256_permute2x128_si256(t1, t3, 0x20); // Column 1: [R0-R3]_P1\n  __m256i d2 = _mm256_permute2x128_si256(t0, t2, 0x31); // Column 2: [R0-R3]_P2\n  __m256i d3 = _mm256_permute2x128_si256(t1, t3, 0x31); // Column 3: [R0-R3]_P3\n\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + dst_pitch * 0), d0);\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + dst_pitch * 1), d1);\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + dst_pitch * 2), d2);\n  _mm256_storeu_si256(reinterpret_cast<__m256i*>(dstp + dst_pitch * 3), d3);\n}\n\nvoid turn_right_plane_64_avx2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n  // Start at bottom row\n  const BYTE* s0 = srcp + src_pitch * (src_height - 1);\n\n  constexpr int PIXELS_W = 4;\n  constexpr int PIXELS_H = 4;\n\n  const int w = src_rowsize & ~(PIXELS_W * sizeof(uint64_t) - 1);\n  const int h = src_height & ~(PIXELS_H - 1);\n  const int simd_width_in_pixels = w / sizeof(uint64_t);\n\n  for (int y = 0; y < h; y += PIXELS_H)\n  {\n    // Destination starts at y offset (which is the x-coordinate in turn-right)\n    BYTE* d0 = dstp + y * sizeof(uint64_t);\n\n    for (int x = 0; x < w; x += PIXELS_W * sizeof(uint64_t))\n    {\n      // Standard transpose + Negative Pitch = 90 CW Turn\n      transpose_4x4_64bit_avx2(s0 + x, d0, -src_pitch, dst_pitch);\n      d0 += PIXELS_W * dst_pitch;\n    }\n    s0 -= PIXELS_H * src_pitch;\n  }\n\n  if (src_rowsize != w)\n  {\n    turn_right_plane_c<uint64_t>(srcp + w, dstp + dst_pitch * simd_width_in_pixels, src_rowsize - w, src_height, src_pitch, dst_pitch);\n  }\n  if (src_height != h)\n  {\n    turn_right_plane_c<uint64_t>(srcp, dstp + h * sizeof(uint64_t), src_rowsize, src_height - h, src_pitch, dst_pitch);\n  }\n\n}\n\nvoid turn_left_rgb64_avx2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n  // packed rgb is upside down\n  turn_right_plane_64_avx2(srcp, dstp, src_rowsize, src_height, src_pitch, dst_pitch);\n}\n\nvoid turn_right_rgb64_avx2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n  // packed rgb is upside down\n  turn_right_plane_64_avx2(srcp + src_pitch * (src_height - 1), dstp + dst_pitch * (src_rowsize / sizeof(uint64_t) - 1), src_rowsize, src_height, -src_pitch, -dst_pitch);\n}\n\n//-------------------------------------------------------------------------------------------------\n// Turn 180 (Flip)\n//-------------------------------------------------------------------------------------------------\n\ntemplate <typename T>\nvoid turn_180_plane_avx2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n  const BYTE* AVS_RESTRICT s0 = srcp;\n  const int row_bytes = src_rowsize; // src_rowsize is the byte width of the row.\n\n  // d0 points to the byte after the last pixel (byte) of the last row of dst.\n  // dst_pitch * (src_height - 1) is the start of the last row.\n  // + row_bytes is the address after the last byte of that row.\n  BYTE* AVS_RESTRICT d0 = dstp + dst_pitch * (src_height - 1) + row_bytes;\n\n  constexpr int vector_bytes = 32;\n  const int aligned_row_bytes = row_bytes & ~(vector_bytes - 1);\n\n  // Prepare Shuffle Masks (These masks are correct for byte reversal within lanes)\n  __m256i shuf_mask; // only for 8/16-bit types\n  if constexpr (sizeof(T) == 1) {\n    // Reverse bytes in 16-byte chunks (31..16 and 15..0)\n    shuf_mask = _mm256_set_epi8(\n      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\n      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15\n    );\n  }\n  else if constexpr (sizeof(T) == 2) {\n    // Reverse words (16-bit elements) in 16-byte chunks\n    shuf_mask = _mm256_set_epi8(\n      1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14,\n      1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14\n    );\n  }\n  // For 32/64 we use permute instructions, no shuffle mask needed.\n\n  for (int y = 0; y < src_height; ++y)\n  {\n    // Main AVX2 Loop\n    for (int x = 0; x < aligned_row_bytes; x += vector_bytes)\n    {\n      __m256i src = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(s0 + x));\n\n      if constexpr (sizeof(T) == 8) { // uint64_t (4 pixels)\n        // Swap 64-bit elements: 3, 2, 1, 0\n        src = _mm256_permute4x64_epi64(src, _MM_SHUFFLE(0, 1, 2, 3));\n      }\n      else if constexpr (sizeof(T) == 4) { // uint32_t (8 pixels)\n        // Reverse 32-bit elements: 7, 6, 5, 4, 3, 2, 1, 0\n        const __m256i idx = _mm256_set_epi32(0, 1, 2, 3, 4, 5, 6, 7);\n        src = _mm256_permutevar8x32_epi32(src, idx);\n      }\n      else { // uint8_t or uint16_t\n        // reverse within 128-bit lanes (using precomputed mask)\n        src = _mm256_shuffle_epi8(src, shuf_mask);\n        // Swap the 128-bit lanes\n        src = _mm256_permute2x128_si256(src, src, 0x01);\n      }\n\n      // Store backwards: d0 points to end, x is byte offset from start.\n      _mm256_storeu_si256(reinterpret_cast<__m256i*>(d0 - x - vector_bytes), src);\n    }\n\n    // fallback for leftovers \n    int x = aligned_row_bytes;\n    int rem_bytes = row_bytes - x;\n\n    if (rem_bytes > 0) {\n      const BYTE* src_tail = s0 + x;\n\n      // Destination pointer: The first pixel of the remainder (src_tail)\n      // must go to the address *just before* where the AVX loop finished writing.\n      // The AVX loop finished writing at: d0 - aligned_row_bytes.\n      // The remaining bytes (rem_bytes) are written to fill the gap.\n      // Start of destination remainder region: d0 - row_bytes\n      BYTE* dst_rem_start = d0 - row_bytes;\n\n      const int n_pixels = rem_bytes / sizeof(T);\n\n      // Pointers for pixel-wise copy and reverse.\n      const T* s_ptr = reinterpret_cast<const T*>(src_tail);\n\n      // d_ptr starts at the last pixel position of the remainder region, \n      // and moves backward to reverse the order.\n      T* d_ptr = reinterpret_cast<T*>(dst_rem_start + rem_bytes) - 1;\n\n      for (int k = 0; k < n_pixels; ++k) {\n        *d_ptr = s_ptr[k];\n        d_ptr--; // Move backward\n      }\n    }\n    s0 += src_pitch;\n    d0 -= dst_pitch;\n  }\n}\n\n// Instantiate templates\ntemplate void turn_180_plane_avx2<uint8_t>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\ntemplate void turn_180_plane_avx2<uint16_t>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\ntemplate void turn_180_plane_avx2<uint32_t>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\ntemplate void turn_180_plane_avx2<uint64_t>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\n"
  },
  {
    "path": "avs_core/filters/intel/turn_avx2.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef _AVS_TURN_AVX2_H\n#define _AVS_TURN_AVX2_H\n\n#include <avisynth.h>\n#include \"../turn.h\"\n\n// Other filters (e.g. resampler) might also use these functions\nvoid turn_left_plane_8_avx2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\nvoid turn_left_plane_16_avx2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\nvoid turn_left_plane_32_avx2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int srcHeight, int src_pitch, int dst_pitch);\nvoid turn_left_rgb32_avx2(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\nvoid turn_left_rgb64_avx2(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\nvoid turn_right_plane_8_avx2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int srcHeight, int src_pitch, int dst_pitch);\nvoid turn_right_plane_16_avx2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int srcHeight, int src_pitch, int dst_pitch);\nvoid turn_right_plane_32_avx2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int srcHeight, int src_pitch, int dst_pitch);\nvoid turn_right_rgb32_avx2(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\nvoid turn_right_rgb64_avx2(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\n\ntemplate <typename T>\nvoid turn_180_plane_avx2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\n\n#endif  // _AVS_TURN_AVX2_H\n"
  },
  {
    "path": "avs_core/filters/intel/turn_sse.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n/*\n** Turn. version 0.1\n** (c) 2003 - Ernst Peché\n**\n*/\n\n#include \"../turn.h\"\n#include \"turn_sse.h\"\n\n// Intrinsics base header + really required extension headers\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n#include <tmmintrin.h> // SSSE3\n\n#include <cstdint>\n\n\nstatic AVS_FORCEINLINE __m128i movehl(const __m128i& x)\n{\n    __m128 ps = _mm_castsi128_ps(x);\n    return _mm_castps_si128(_mm_movehl_ps(ps, ps));\n}\n\n\n// This pattern seems faster than the others.\nstatic AVS_FORCEINLINE void transpose_8x8x8_sse2(const BYTE* AVS_RESTRICT srcp, BYTE* AVS_RESTRICT dstp, int src_pitch, int dst_pitch)\n{\n    __m128i a07 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 0)); //a0 a1 a2 a3 a4 a5 a6 a7\n    __m128i b07 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 1)); //b0 b1 b2 b3 b4 b5 b6 b7\n    __m128i c07 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 2)); //c0 c1 c2 c3 c4 c5 c6 c7\n    __m128i d07 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 3)); //d0 d1 d2 d3 d4 d5 d6 d7\n    __m128i e07 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 4)); //e0 e1 e2 e3 e4 e5 e6 e7\n    __m128i f07 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 5)); //f0 f1 f2 f3 f4 f5 f6 f7\n    __m128i g07 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 6)); //g0 g1 g2 g3 g4 g5 g6 g7\n    __m128i h07 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 7)); //h0 h1 h2 h3 h4 h5 h6 h7\n\n    __m128i ea07 = _mm_unpacklo_epi8(e07, a07); //e0 a0 e1 a1 e2 a2 e3 a3 e4 a4 e5 a5 e6 a6 e7 a7\n    __m128i fb07 = _mm_unpacklo_epi8(f07, b07); //f0 b0 f1 b1 f2 b2 f3 b3 f4 b4 f5 b5 f6 b6 f7 b7\n    __m128i gc07 = _mm_unpacklo_epi8(g07, c07); //g0 c0 g1 c1 g2 c2 g3 c3 g4 c4 g5 c5 g6 c6 g7 c7\n    __m128i hd07 = _mm_unpacklo_epi8(h07, d07); //h0 d0 h1 d1 h2 d2 h3 d3 h4 d4 h5 d5 h6 d6 h7 d7\n\n    __m128i geca03 = _mm_unpacklo_epi8(gc07, ea07); //g0 e0 c0 a0 g1 e1 c1 a1 g2 e2 c2 a2 g3 e3 c3 a3\n    __m128i geca47 = _mm_unpackhi_epi8(gc07, ea07); //g4 e4 c4 a4 g5 e5 c5 a5 g6 e6 c6 a6 g7 e7 c7 a7\n    __m128i hfdb03 = _mm_unpacklo_epi8(hd07, fb07); //h0 f0 d0 b0 h1 f1 d1 b1 h2 f2 d2 b2 h3 f3 d3 b3\n    __m128i hfdb47 = _mm_unpackhi_epi8(hd07, fb07); //h4 f4 d4 b4 h5 f5 d5 b5 h6 f6 d6 b6 h7 f7 d7 b7\n\n    __m128i hgfedcba01 = _mm_unpacklo_epi8(hfdb03, geca03); //h0 g0 f0 e0 d0 c0 b0 a0 h1 g1 f1 e1 d1 c1 b1 a1\n    __m128i hgfedcba23 = _mm_unpackhi_epi8(hfdb03, geca03); //h2 g2 f2 e2 d2 c2 b2 a2 h3 g3 f3 e3 d3 c3 b3 a3\n    __m128i hgfedcba45 = _mm_unpacklo_epi8(hfdb47, geca47); //h4 g4 f4 e4 d4 c4 b4 a4 h5 g5 f5 e5 d5 c5 b5 a5\n    __m128i hgfedcba67 = _mm_unpackhi_epi8(hfdb47, geca47); //h6 g6 f6 e6 d6 c6 b6 a6 h7 g7 f7 e7 d7 c7 b7 a7\n\n    _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + dst_pitch * 0), hgfedcba01);\n    _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + dst_pitch * 1), movehl(hgfedcba01));\n    _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + dst_pitch * 2), hgfedcba23);\n    _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + dst_pitch * 3), movehl(hgfedcba23));\n    _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + dst_pitch * 4), hgfedcba45);\n    _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + dst_pitch * 5), movehl(hgfedcba45));\n    _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + dst_pitch * 6), hgfedcba67);\n    _mm_storel_epi64(reinterpret_cast<__m128i*>(dstp + dst_pitch * 7), movehl(hgfedcba67));\n}\n\n\nvoid turn_right_plane_8_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    const BYTE* s0 = srcp;\n    int w = src_rowsize & ~7;\n    int h = src_height & ~7;\n\n    for (int y = 0; y < h; y += 8)\n    {\n        BYTE* d0 = dstp + src_height - 8  - y;\n        for (int x = 0; x < w; x += 8)\n        {\n            transpose_8x8x8_sse2(s0 + x, d0, src_pitch, dst_pitch);\n            d0 += dst_pitch * 8;\n        }\n        s0 += src_pitch * 8;\n    }\n\n    if (src_rowsize != w)\n    {\n        turn_right_plane_8_c(srcp + w, dstp + w * dst_pitch, src_rowsize - w, src_height, src_pitch, dst_pitch);\n    }\n\n    if (src_height != h)\n    {\n        turn_right_plane_8_c(srcp + h * src_pitch, dstp, src_rowsize, src_height - h, src_pitch, dst_pitch);\n    }\n}\n\n\nvoid turn_left_plane_8_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    turn_right_plane_8_sse2(srcp + (src_height - 1) * src_pitch, dstp + (src_rowsize - 1) * dst_pitch, src_rowsize, src_height, -src_pitch, -dst_pitch);\n}\n\n\n\nstatic AVS_FORCEINLINE void transpose_16x4x8_sse2(const BYTE* AVS_RESTRICT srcp, BYTE* AVS_RESTRICT dstp, const int src_pitch, const int dst_pitch)\n{\n    __m128i a03 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 0)); //a0 a1 a2 a3\n    __m128i b03 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 1)); //b0 b1 b2 b3\n    __m128i c03 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 2)); //c0 c1 c2 c3\n    __m128i d03 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 3)); //d0 d1 d2 d3\n    __m128i e03 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 4)); //e0 e1 e2 e3\n    __m128i f03 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 5)); //f0 f1 f2 f3\n    __m128i g03 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 6)); //g0 g1 g2 g3\n    __m128i h03 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp + src_pitch * 7)); //h0 h1 h2 h3\n\n    __m128i ae03 = _mm_unpacklo_epi16(a03, e03); //a0 e0 a1 e1 a2 e2 a3 e3\n    __m128i bf03 = _mm_unpacklo_epi16(b03, f03); //b0 f0 b1 f1 b2 f2 b3 f3\n    __m128i cg03 = _mm_unpacklo_epi16(c03, g03); //c0 g0 c1 g1 c2 g2 c3 g3\n    __m128i dh03 = _mm_unpacklo_epi16(d03, h03); //d0 h0 d1 h1 d2 h2 d3 h3\n\n    __m128i aceg01 = _mm_unpacklo_epi16(ae03, cg03); //a0 c0 e0 g0 a1 c1 e1 g1\n    __m128i aceg23 = _mm_unpackhi_epi16(ae03, cg03); //a2 c2 e2 g2 a3 c3 e3 g3\n    __m128i bdfh01 = _mm_unpacklo_epi16(bf03, dh03); //b0 d0 f0 h0 b1 d1 f1 h1\n    __m128i bdfh23 = _mm_unpackhi_epi16(bf03, dh03); //b2 d2 f2 h2 b3 d3 f3 h3\n\n    __m128i abcdefgh0 = _mm_unpacklo_epi16(aceg01, bdfh01); //a0 b0 c0 d0 e0 f0 g0 h0\n    __m128i abcdefgh1 = _mm_unpackhi_epi16(aceg01, bdfh01); //a1 b1 c1 d1 e1 f1 g1 h1\n    __m128i abcdefgh2 = _mm_unpacklo_epi16(aceg23, bdfh23); //a2 b2 c2 d2 e2 f2 g2 h2\n    __m128i abcdefgh3 = _mm_unpackhi_epi16(aceg23, bdfh23); //a3 b3 c3 d3 e3 f3 g3 h3\n\n    _mm_store_si128(reinterpret_cast<__m128i*>(dstp + dst_pitch * 0), abcdefgh0);\n    _mm_store_si128(reinterpret_cast<__m128i*>(dstp + dst_pitch * 1), abcdefgh1);\n    _mm_store_si128(reinterpret_cast<__m128i*>(dstp + dst_pitch * 2), abcdefgh2);\n    _mm_store_si128(reinterpret_cast<__m128i*>(dstp + dst_pitch * 3), abcdefgh3);\n}\n\n\nvoid turn_right_plane_16_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    const BYTE* s0 = srcp + src_pitch * (src_height - 1);\n    int w = src_rowsize & ~7;\n    int h = src_height & ~7;\n\n    for (int y = 0; y < h; y += 8)\n    {\n        BYTE* d0 = dstp + y * 2;\n        for (int x = 0; x < w; x += 8)\n        {\n            transpose_16x4x8_sse2(s0 + x, d0, -src_pitch, dst_pitch);\n            d0 += 4 * dst_pitch;\n        }\n        s0 -= 8 * src_pitch;\n    }\n    if (src_rowsize != w)\n    {\n        turn_right_plane_16_c(srcp + w, dstp + dst_pitch * w / 2, src_rowsize - w, src_height, src_pitch, dst_pitch);\n    }\n\n    if (src_height != h)\n    {\n        turn_right_plane_16_c(srcp, dstp + h * 2, src_rowsize, src_height - h, src_pitch, dst_pitch);\n    }\n}\n\n\nvoid turn_left_plane_16_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    turn_right_plane_16_sse2(srcp + src_pitch * (src_height - 1), dstp + dst_pitch * (src_rowsize / 2 - 1), src_rowsize, src_height, -src_pitch, -dst_pitch);\n}\n\n\n\nstatic AVS_FORCEINLINE void transpose_32x4x4_sse2(const BYTE* AVS_RESTRICT srcp, BYTE* AVS_RESTRICT dstp, const int src_pitch, const int dst_pitch)\n{\n    __m128i a03 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + src_pitch * 0)); //a0 a1 a2 a3\n    __m128i b03 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + src_pitch * 1)); //b0 b1 b2 b3\n    __m128i c03 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + src_pitch * 2)); //c0 c1 c2 c3\n    __m128i d03 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + src_pitch * 3)); //d0 d1 d2 d3\n\n    __m128i ac01 = _mm_unpacklo_epi32(a03, c03); //a0 c0 a1 c1\n    __m128i ac23 = _mm_unpackhi_epi32(a03, c03); //a2 c2 a3 c3\n    __m128i bd01 = _mm_unpacklo_epi32(b03, d03); //b0 d0 b1 d1\n    __m128i bd23 = _mm_unpackhi_epi32(b03, d03); //b2 d2 b3 d3\n\n    __m128i abcd0 = _mm_unpacklo_epi32(ac01, bd01); //a0 b0 c0 d0\n    __m128i abcd1 = _mm_unpackhi_epi32(ac01, bd01); //a1 b1 c1 d1\n    __m128i abcd2 = _mm_unpacklo_epi32(ac23, bd23); //a2 b2 c2 d2\n    __m128i abcd3 = _mm_unpackhi_epi32(ac23, bd23); //a3 b3 c3 d3\n\n    _mm_storeu_si128(reinterpret_cast<__m128i*>(dstp + dst_pitch * 0), abcd0);\n    _mm_storeu_si128(reinterpret_cast<__m128i*>(dstp + dst_pitch * 1), abcd1);\n    _mm_storeu_si128(reinterpret_cast<__m128i*>(dstp + dst_pitch * 2), abcd2);\n    _mm_storeu_si128(reinterpret_cast<__m128i*>(dstp + dst_pitch * 3), abcd3);\n}\n\n\nvoid turn_right_plane_32_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    const BYTE* s0 = srcp + src_pitch * (src_height - 1);\n    int w = src_rowsize & ~15;\n    int h = src_height & ~3;\n\n    for (int y = 0; y < h; y += 4)\n    {\n        BYTE* d0 = dstp + y * 4;\n        for (int x = 0; x < w; x += 16)\n        {\n            transpose_32x4x4_sse2(s0 + x, d0, -src_pitch, dst_pitch);\n            d0 += 4 * dst_pitch;\n        }\n        s0 -= 4 * src_pitch;\n    }\n\n    if (src_rowsize != w)\n    {\n        turn_right_plane_32_c(srcp + w, dstp + w / 4 * dst_pitch, src_rowsize - w, src_height, src_pitch, dst_pitch);\n    }\n\n    if (src_height != h)\n    {\n        turn_right_plane_32_c(srcp, dstp + h * 4, src_rowsize, src_height - h, src_pitch, dst_pitch);\n    }\n}\n\nvoid turn_left_plane_32_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    turn_right_plane_32_sse2(srcp + src_pitch * (src_height - 1), dstp + dst_pitch * (src_rowsize / 4 - 1), src_rowsize, src_height, -src_pitch, -dst_pitch);\n}\n\n\n// on RGB, TurnLeft and TurnRight are reversed.\n\nvoid turn_left_rgb32_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    turn_right_plane_32_sse2(srcp, dstp, src_rowsize, src_height, src_pitch, dst_pitch);\n}\n\n\nvoid turn_right_rgb32_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    turn_left_plane_32_sse2(srcp, dstp, src_rowsize, src_height, src_pitch, dst_pitch);\n}\n\n\n\n\nstatic inline void turn_right_plane_64_sse2(const BYTE* AVS_RESTRICT srcp, BYTE* AVS_RESTRICT dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    const BYTE* s0 = srcp + src_pitch * (src_height - 1);\n    int w = src_rowsize & ~15;\n    int h = src_height & ~1;\n\n    for (int y = 0; y < h; y += 2)\n    {\n        BYTE* d0 = dstp + y * 8;\n        for (int x = 0; x < w; x += 16)\n        {\n            __m128i a01 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(s0 + x));               // a0 a1\n            __m128i b01 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(s0 + x - src_pitch));   // b0 b1\n            __m128i ab0 = _mm_unpacklo_epi64(a01, b01); // a0 b0\n            __m128i ab1 = _mm_unpackhi_epi64(a01, b01); // a1 b1\n            _mm_storeu_si128(reinterpret_cast<__m128i*>(d0), ab0);\n            _mm_storeu_si128(reinterpret_cast<__m128i*>(d0 + dst_pitch), ab1);\n            d0 += 2 * dst_pitch;\n        }\n        s0 -= 2 * src_pitch;\n    }\n\n    if (src_rowsize != w)\n    {\n        turn_right_plane_c<uint64_t>(srcp + w, dstp + w / 8 * dst_pitch, 8, src_height, src_pitch, dst_pitch);\n    }\n\n    if (src_height != h)\n    {\n        turn_right_plane_c<uint64_t>(srcp, dstp + h * 8, src_rowsize, 1, src_pitch, dst_pitch);\n    }\n}\n\n\nvoid turn_left_rgb64_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    turn_right_plane_64_sse2(srcp, dstp, src_rowsize, src_height, src_pitch, dst_pitch);\n}\n\n\nvoid turn_right_rgb64_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    turn_right_plane_64_sse2(srcp + src_pitch * (src_height - 1), dstp + dst_pitch * (src_rowsize / 8 - 1), src_rowsize, src_height, -src_pitch, -dst_pitch);\n}\n\n\n\n\n\ntemplate <typename T>\nvoid turn_180_plane_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n  const BYTE* AVS_RESTRICT s0 = srcp;\n  BYTE* AVS_RESTRICT d0 = dstp + dst_pitch * (src_height - 1) + src_rowsize - 16;\n  const int w = src_rowsize & ~15;\n\n  for (int y = 0; y < src_height; ++y)\n  {\n    for (int x = 0; x < w; x += 16)\n    {\n      __m128i src = _mm_loadu_si128(reinterpret_cast<const __m128i*>(s0 + x));\n      if constexpr (sizeof(T) == 8) // RGB64\n        src = _mm_shuffle_epi32(src, _MM_SHUFFLE(1, 0, 3, 2));\n      else if constexpr (sizeof(T) == 4) // RGB32\n        src = _mm_shuffle_epi32(src, _MM_SHUFFLE(0, 1, 2, 3));\n      else { // uint16_t, uint8_t\n        src = _mm_shuffle_epi32(src, _MM_SHUFFLE(0, 1, 2, 3));\n        src = _mm_shufflelo_epi16(src, _MM_SHUFFLE(2, 3, 0, 1));\n        src = _mm_shufflehi_epi16(src, _MM_SHUFFLE(2, 3, 0, 1));\n\n        if constexpr (sizeof(T) == 1)\n          src = _mm_or_si128(_mm_srli_epi16(src, 8), _mm_slli_epi16(src, 8));\n      }\n      _mm_storeu_si128(reinterpret_cast<__m128i*>(d0 - x), src);\n    }\n    s0 += src_pitch;\n    d0 -= dst_pitch;\n  }\n\n  if (src_rowsize != w)\n  {\n    turn_180_plane_c<T>(srcp + w, dstp, src_rowsize - w, src_height, src_pitch, dst_pitch);\n  }\n}\n\n// instantiate\ntemplate void turn_180_plane_sse2<uint8_t>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\ntemplate void turn_180_plane_sse2<uint16_t>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\ntemplate void turn_180_plane_sse2<uint32_t>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\ntemplate void turn_180_plane_sse2<uint64_t>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\n\n\ntemplate <typename T>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nvoid turn_180_plane_ssse3(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n  const BYTE* s0 = srcp;\n  BYTE* d0 = dstp + dst_pitch * (src_height - 1) + src_rowsize - 16;\n  const int w = src_rowsize & ~15;\n\n  for (int y = 0; y < src_height; ++y)\n  {\n    for (int x = 0; x < w; x += 16)\n    {\n      __m128i src = _mm_loadu_si128(reinterpret_cast<const __m128i*>(s0 + x));\n      if constexpr (sizeof(T) == 8) // RGB64\n        src = _mm_shuffle_epi32(src, _MM_SHUFFLE(1, 0, 3, 2));\n      else if constexpr (sizeof(T) == 4) // RGB32\n        src = _mm_shuffle_epi32(src, _MM_SHUFFLE(0, 1, 2, 3));\n      else { // uint16_t, uint8_t\n        // SSSE3\n        __m128i pshufb_mask;\n        if constexpr (sizeof(T) == 1)\n          pshufb_mask = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);\n        else if constexpr (sizeof(T) == 2)\n          pshufb_mask = _mm_set_epi8(1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14);\n\n        src = _mm_shuffle_epi8(src, pshufb_mask);\n      }\n      _mm_storeu_si128(reinterpret_cast<__m128i*>(d0 - x), src);\n    }\n    s0 += src_pitch;\n    d0 -= dst_pitch;\n  }\n\n  if (src_rowsize != w)\n  {\n    turn_180_plane_c<T>(srcp + w, dstp, src_rowsize - w, src_height, src_pitch, dst_pitch);\n  }\n}\n\n// instantiate\ntemplate void turn_180_plane_ssse3<uint8_t>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\ntemplate void turn_180_plane_ssse3<uint16_t>(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\n"
  },
  {
    "path": "avs_core/filters/intel/turn_sse.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef _AVS_TURN_SSE_H\n#define _AVS_TURN_SSE_H\n\n#include <avisynth.h>\n#include \"../turn.h\"\n\n// Other filters (e.g. resampler) might also use these functions\nvoid turn_left_plane_8_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\nvoid turn_left_plane_16_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\nvoid turn_left_plane_32_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int srcHeight, int src_pitch, int dst_pitch);\nvoid turn_left_rgb32_sse2(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\nvoid turn_left_rgb64_sse2(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\nvoid turn_right_plane_8_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int srcHeight, int src_pitch, int dst_pitch);\nvoid turn_right_plane_16_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int srcHeight, int src_pitch, int dst_pitch);\nvoid turn_right_plane_32_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int srcHeight, int src_pitch, int dst_pitch);\nvoid turn_right_rgb32_sse2(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\nvoid turn_right_rgb64_sse2(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\n\ntemplate <typename T>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"ssse3\")))\n#endif\nvoid turn_180_plane_ssse3(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\n\ntemplate <typename T>\nvoid turn_180_plane_sse2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\n\n#endif  // _AVS_TURN_SSE_H\n"
  },
  {
    "path": "avs_core/filters/layer.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n\n// Avisynth filter: Layer\n// by \"poptones\" (poptones@myrealbox.com)\n\n#include \"layer.h\"\n#ifdef INTEL_INTRINSICS\n#include \"intel/layer_sse.h\"\n#include \"intel/layer_avx2.h\"\n#endif\n#ifdef AVS_WINDOWS\n#include <avs/win.h>\n#else\n#include <avs/posix.h>\n#endif\n\n#include <avs/minmax.h>\n#include <avs/alignment.h>\n#include \"../core/internal.h\"\n#include \"../convert/convert_planar.h\"\n#include <algorithm>\n#include <vector>\n\nstatic int getPlacement(const AVSValue& _placement, IScriptEnvironment* env) {\n  const char* placement = _placement.AsString(0);\n\n  if (placement) {\n    if (!lstrcmpi(placement, \"mpeg2\"))\n      return PLACEMENT_MPEG2;\n\n    if (!lstrcmpi(placement, \"mpeg1\"))\n      return PLACEMENT_MPEG1;\n\n    env->ThrowError(\"Layer: Unknown chroma placement\");\n  }\n  return PLACEMENT_MPEG2;\n}\n\n/********************************************************************\n***** Declare index of new filters for Avisynth's filter engine *****\n********************************************************************/\n\nextern const AVSFunction Layer_filters[] = {\n  { \"Mask\",         BUILTIN_FUNC_PREFIX, \"cc\", Mask::Create },     // clip, mask\n  { \"ColorKeyMask\", BUILTIN_FUNC_PREFIX, \"ci[]i[]i[]i\", ColorKeyMask::Create },    // clip, color, tolerance[B, toleranceG, toleranceR]\n  { \"ResetMask\",    BUILTIN_FUNC_PREFIX, \"c[mask]f[opacity]f\", ResetMask::Create },\n  { \"Invert\",       BUILTIN_FUNC_PREFIX, \"c[channels]s\", Invert::Create },\n  { \"ShowAlpha\",    BUILTIN_FUNC_PREFIX, \"c[pixel_type]s\", ShowChannel::Create, (void*)3 }, // AVS+ also for YUVA, PRGBA\n  { \"ShowRed\",      BUILTIN_FUNC_PREFIX, \"c[pixel_type]s\", ShowChannel::Create, (void*)2 },\n  { \"ShowGreen\",    BUILTIN_FUNC_PREFIX, \"c[pixel_type]s\", ShowChannel::Create, (void*)1 },\n  { \"ShowBlue\",     BUILTIN_FUNC_PREFIX, \"c[pixel_type]s\", ShowChannel::Create, (void*)0 },\n  { \"ShowY\",        BUILTIN_FUNC_PREFIX, \"c[pixel_type]s\", ShowChannel::Create, (void*)4 }, // AVS+\n  { \"ShowU\",        BUILTIN_FUNC_PREFIX, \"c[pixel_type]s\", ShowChannel::Create, (void*)5 }, // AVS+\n  { \"ShowV\",        BUILTIN_FUNC_PREFIX, \"c[pixel_type]s\", ShowChannel::Create, (void*)6 }, // AVS+\n  { \"MergeRGB\",     BUILTIN_FUNC_PREFIX, \"ccc[pixel_type]s\", MergeRGB::Create, (void*)0 },\n  { \"MergeARGB\",    BUILTIN_FUNC_PREFIX, \"cccc[pixel_type]s\", MergeRGB::Create, (void*)1 },\n  { \"Layer\",        BUILTIN_FUNC_PREFIX, \"cc[op]s[level]i[x]i[y]i[threshold]i[use_chroma]b[opacity]f[placement]s\", Layer::Create },\n  /**\n    * Layer(clip, overlayclip, operation, amount, xpos, ypos, [threshold=0], [use_chroma=true])\n   **/\n  { \"Subtract\", BUILTIN_FUNC_PREFIX, \"cc\", Subtract::Create },\n  { NULL }\n};\n\n\n/******************************\n *******   Mask Filter   ******\n ******************************/\n\nMask::Mask(PClip _child1, PClip _child2, IScriptEnvironment* env)\n  : child1(_child1), child2(_child2)\n{\n  const VideoInfo& vi1 = child1->GetVideoInfo();\n  const VideoInfo& vi2 = child2->GetVideoInfo();\n  if (vi1.width != vi2.width || vi1.height != vi2.height)\n    env->ThrowError(\"Mask error: image dimensions don't match\");\n  if (!((vi1.IsRGB32() && vi2.IsRGB32()) ||\n    (vi1.IsRGB64() && vi2.IsRGB64()) ||\n    (vi1.IsPlanarRGBA() && vi2.IsPlanarRGBA()))\n    )\n    env->ThrowError(\"Mask error: sources must be RGB32, RGB64 or Planar RGBA\");\n\n  if (vi1.BitsPerComponent() != vi2.BitsPerComponent())\n    env->ThrowError(\"Mask error: Components are not of the same bit depths\");\n\n  vi = vi1;\n\n  pixelsize = vi.ComponentSize();\n  bits_per_pixel = vi.BitsPerComponent();\n\n  mask_frames = vi2.num_frames;\n}\n\n\ntemplate<typename pixel_t>\nstatic void mask_c(BYTE* srcp8, const BYTE* alphap8, int src_pitch, int alpha_pitch, size_t width, size_t height) {\n  pixel_t* srcp = reinterpret_cast<pixel_t*>(srcp8);\n  const pixel_t* alphap = reinterpret_cast<const pixel_t*>(alphap8);\n\n  src_pitch /= sizeof(pixel_t);\n  alpha_pitch /= sizeof(pixel_t);\n\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < width; ++x) {\n      srcp[x * 4 + 3] = (cyb * alphap[x * 4 + 0] + cyg * alphap[x * 4 + 1] + cyr * alphap[x * 4 + 2] + 16384) >> 15;\n    }\n    srcp += src_pitch;\n    alphap += alpha_pitch;\n  }\n}\n\ntemplate<typename pixel_t>\nstatic void mask_planar_rgb_c(BYTE* dstp8, const BYTE* srcp_r8, const BYTE* srcp_g8, const BYTE* srcp_b8, int dst_pitch, int src_pitch, size_t width, size_t height, int bits_per_pixel) {\n  pixel_t* dstp = reinterpret_cast<pixel_t*>(dstp8);\n  const pixel_t* srcp_r = reinterpret_cast<const pixel_t*>(srcp_r8);\n  const pixel_t* srcp_g = reinterpret_cast<const pixel_t*>(srcp_g8);\n  const pixel_t* srcp_b = reinterpret_cast<const pixel_t*>(srcp_b8);\n  src_pitch /= sizeof(pixel_t);\n  dst_pitch /= sizeof(pixel_t);\n\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < width; ++x) {\n      dstp[x] = ((cyb * srcp_b[x] + cyg * srcp_g[x] + cyr * srcp_r[x] + 16384) >> 15);\n    }\n    dstp += dst_pitch;\n    srcp_r += src_pitch;\n    srcp_g += src_pitch;\n    srcp_b += src_pitch;\n  }\n}\n\nstatic void mask_planar_rgb_float_c(BYTE* dstp8, const BYTE* srcp_r8, const BYTE* srcp_g8, const BYTE* srcp_b8, int dst_pitch, int src_pitch, size_t width, size_t height) {\n\n  float* dstp = reinterpret_cast<float*>(dstp8);\n  const float* srcp_r = reinterpret_cast<const float*>(srcp_r8);\n  const float* srcp_g = reinterpret_cast<const float*>(srcp_g8);\n  const float* srcp_b = reinterpret_cast<const float*>(srcp_b8);\n  src_pitch /= sizeof(float);\n  dst_pitch /= sizeof(float);\n\n  for (size_t y = 0; y < height; ++y) {\n    for (size_t x = 0; x < width; ++x) {\n      dstp[x] = cyb_f * srcp_b[x] + cyg_f * srcp_g[x] + cyr_f * srcp_r[x];\n    }\n    dstp += dst_pitch;\n    srcp_r += src_pitch;\n    srcp_g += src_pitch;\n    srcp_b += src_pitch;\n  }\n}\n\nPVideoFrame __stdcall Mask::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame src1 = child1->GetFrame(n, env);\n  PVideoFrame src2 = child2->GetFrame(min(n, mask_frames - 1), env);\n\n  env->MakeWritable(&src1);\n\n  if (vi.IsPlanar()) {\n    // planar RGB\n    BYTE* dstp = src1->GetWritePtr(PLANAR_A); // destination Alpha plane\n\n    const BYTE* srcp_g = src2->GetReadPtr(PLANAR_G);\n    const BYTE* srcp_b = src2->GetReadPtr(PLANAR_B);\n    const BYTE* srcp_r = src2->GetReadPtr(PLANAR_R);\n\n    const int dst_pitch = src1->GetPitch();\n    const int src_pitch = src2->GetPitch();\n\n    // clip1_alpha = greyscale(clip2)\n    if (pixelsize == 1)\n      mask_planar_rgb_c<uint8_t>(dstp, srcp_r, srcp_g, srcp_b, dst_pitch, src_pitch, vi.width, vi.height, bits_per_pixel);\n    else if (pixelsize == 2)\n      mask_planar_rgb_c<uint16_t>(dstp, srcp_r, srcp_g, srcp_b, dst_pitch, src_pitch, vi.width, vi.height, bits_per_pixel);\n    else\n      mask_planar_rgb_float_c(dstp, srcp_r, srcp_g, srcp_b, dst_pitch, src_pitch, vi.width, vi.height);\n  }\n  else {\n    // Packed RGB32/64\n    BYTE* src1p = src1->GetWritePtr();\n    const BYTE* src2p = src2->GetReadPtr();\n\n    const int src1_pitch = src1->GetPitch();\n    const int src2_pitch = src2->GetPitch();\n\n    // clip1_alpha = greyscale(clip2)\n#ifdef INTEL_INTRINSICS\n    if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_AVX2))\n    {\n      mask_avx2(src1p, src2p, src1_pitch, src2_pitch, vi.width, vi.height);\n    }\n    else if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_SSE2))\n    {\n      mask_sse2(src1p, src2p, src1_pitch, src2_pitch, vi.width, vi.height);\n    }\n    else\n#ifdef X86_32\n      if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_MMX))\n      {\n        mask_mmx(src1p, src2p, src1_pitch, src2_pitch, vi.width, vi.height);\n      }\n      else\n#endif\n#endif\n      {\n        if (pixelsize == 1) { // RGB32\n          mask_c<uint8_t>(src1p, src2p, src1_pitch, src2_pitch, vi.width, vi.height);\n        }\n        else { // if (pixelsize == 2) RGB64\n          mask_c<uint16_t>(src1p, src2p, src1_pitch, src2_pitch, vi.width, vi.height);\n        }\n      }\n  }\n\n  return src1;\n}\n\nAVSValue __cdecl Mask::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  return new Mask(args[0].AsClip(), args[1].AsClip(), env);\n}\n\n\n/**************************************\n *******   ColorKeyMask Filter   ******\n **************************************/\n\n\nColorKeyMask::ColorKeyMask(PClip _child, int _color, int _tolB, int _tolG, int _tolR, IScriptEnvironment* env)\n  : GenericVideoFilter(_child), color(_color & 0xffffff), tolB(_tolB & 0xff), tolG(_tolG & 0xff), tolR(_tolR & 0xff)\n{\n  if (!vi.IsRGB32() && !vi.IsRGB64() && !vi.IsPlanarRGBA())\n    env->ThrowError(\"ColorKeyMask: requires RGB32, RGB64 or Planar RGBA input\");\n  pixelsize = vi.ComponentSize();\n  bits_per_pixel = vi.BitsPerComponent();\n  max_pixel_value = (1 << bits_per_pixel) - 1;\n\n  auto rgbcolor8to16 = [](uint8_t color8, int max_pixel_value) { return (uint16_t)(color8 * max_pixel_value / 255); };\n\n  uint64_t r = rgbcolor8to16((color >> 16) & 0xFF, max_pixel_value);\n  uint64_t g = rgbcolor8to16((color >> 8) & 0xFF, max_pixel_value);\n  uint64_t b = rgbcolor8to16((color) & 0xFF, max_pixel_value);\n  uint64_t a = rgbcolor8to16((color >> 24) & 0xFF, max_pixel_value);\n  color64 = (a << 48) + (r << 32) + (g << 16) + (b);\n  tolR16 = rgbcolor8to16(tolR & 0xFF, max_pixel_value); // scale tolerance\n  tolG16 = rgbcolor8to16(tolG & 0xFF, max_pixel_value);\n  tolB16 = rgbcolor8to16(tolB & 0xFF, max_pixel_value);\n}\n\n\ntemplate<typename pixel_t>\nstatic void colorkeymask_c(BYTE* pf8, int pitch, int R, int G, int B, int height, int rowsize, int tolB, int tolG, int tolR) {\n  pixel_t* pf = reinterpret_cast<pixel_t*>(pf8);\n  rowsize /= sizeof(pixel_t);\n  pitch /= sizeof(pixel_t);\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < rowsize; x += 4) {\n      if (IsClose(pf[x], B, tolB) && IsClose(pf[x + 1], G, tolG) && IsClose(pf[x + 2], R, tolR))\n        pf[x + 3] = 0;\n    }\n    pf += pitch;\n  }\n}\n\ntemplate<typename pixel_t>\nstatic void colorkeymask_planar_c(const BYTE* pfR8, const BYTE* pfG8, const BYTE* pfB8, BYTE* pfA8, int pitch, int R, int G, int B, int height, int width, int tolB, int tolG, int tolR) {\n  const pixel_t* pfR = reinterpret_cast<const pixel_t*>(pfR8);\n  const pixel_t* pfG = reinterpret_cast<const pixel_t*>(pfG8);\n  const pixel_t* pfB = reinterpret_cast<const pixel_t*>(pfB8);\n  pixel_t* pfA = reinterpret_cast<pixel_t*>(pfA8);\n  pitch /= sizeof(pixel_t);\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < width; x++) {\n      if (IsClose(pfB[x], B, tolB) && IsClose(pfG[x], G, tolG) && IsClose(pfR[x], R, tolR))\n        pfA[x] = 0;\n    }\n    pfR += pitch;\n    pfG += pitch;\n    pfB += pitch;\n    pfA += pitch;\n  }\n}\n\nstatic void colorkeymask_planar_float_c(const BYTE* pfR8, const BYTE* pfG8, const BYTE* pfB8, BYTE* pfA8, int pitch, float R, float G, float B, int height, int width, float tolB, float tolG, float tolR) {\n  typedef float pixel_t;\n  const pixel_t* pfR = reinterpret_cast<const pixel_t*>(pfR8);\n  const pixel_t* pfG = reinterpret_cast<const pixel_t*>(pfG8);\n  const pixel_t* pfB = reinterpret_cast<const pixel_t*>(pfB8);\n  pixel_t* pfA = reinterpret_cast<pixel_t*>(pfA8);\n  pitch /= sizeof(pixel_t);\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < width; x++) {\n      if (IsCloseFloat(pfB[x], B, tolB) && IsCloseFloat(pfG[x], G, tolG) && IsCloseFloat(pfR[x], R, tolR))\n        pfA[x] = 0;\n    }\n    pfR += pitch;\n    pfG += pitch;\n    pfB += pitch;\n    pfA += pitch;\n  }\n}\n\n\nPVideoFrame __stdcall ColorKeyMask::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame frame = child->GetFrame(n, env);\n  env->MakeWritable(&frame);\n\n  BYTE* pf = frame->GetWritePtr();\n  const int pitch = frame->GetPitch();\n  const int rowsize = frame->GetRowSize();\n\n  if (vi.IsPlanarRGBA()) {\n    const BYTE* pf_g = frame->GetReadPtr(PLANAR_G);\n    const BYTE* pf_b = frame->GetReadPtr(PLANAR_B);\n    const BYTE* pf_r = frame->GetReadPtr(PLANAR_R);\n    BYTE* pf_a = frame->GetWritePtr(PLANAR_A);\n\n    const int pitch = frame->GetPitch();\n    const int width = vi.width;\n\n    if (pixelsize == 1) {\n      const int R = (color >> 16) & 0xff;\n      const int G = (color >> 8) & 0xff;\n      const int B = color & 0xff;\n      colorkeymask_planar_c<uint8_t>(pf_r, pf_g, pf_b, pf_a, pitch, R, G, B, vi.height, width, tolB, tolG, tolR);\n    }\n    else if (pixelsize == 2) {\n      const int R = (color64 >> 32) & 0xffff;\n      const int G = (color64 >> 16) & 0xffff;\n      const int B = color64 & 0xffff;\n      colorkeymask_planar_c<uint16_t>(pf_r, pf_g, pf_b, pf_a, pitch, R, G, B, vi.height, width, tolB16, tolG16, tolR16);\n    }\n    else { // float\n      const float R = ((color >> 16) & 0xff) / 255.0f;\n      const float G = ((color >> 8) & 0xff) / 255.0f;\n      const float B = (color & 0xff) / 255.0f;\n      colorkeymask_planar_float_c(pf_r, pf_g, pf_b, pf_a, pitch, R, G, B, vi.height, width, tolB / 255.0f, tolG / 255.0f, tolR / 255.0f);\n    }\n  }\n  else {\n    // RGB32, RGB64\n#ifdef INTEL_INTRINSICS\n    if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_AVX2))\n    {\n      colorkeymask_avx2(pf, pitch, color, vi.height, rowsize, tolB, tolG, tolR);\n    }\n    else if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_SSE2))\n    {\n      colorkeymask_sse2(pf, pitch, color, vi.height, rowsize, tolB, tolG, tolR);\n    }\n    else\n#ifdef X86_32\n      if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_MMX))\n      {\n        colorkeymask_mmx(pf, pitch, color, vi.height, rowsize, tolB, tolG, tolR);\n      }\n      else\n#endif\n#endif\n      {\n        if (pixelsize == 1) {\n          const int R = (color >> 16) & 0xff;\n          const int G = (color >> 8) & 0xff;\n          const int B = color & 0xff;\n          colorkeymask_c<uint8_t>(pf, pitch, R, G, B, vi.height, rowsize, tolB, tolG, tolR);\n        }\n        else {\n          const int R = (color64 >> 32) & 0xffff;\n          const int G = (color64 >> 16) & 0xffff;\n          const int B = color64 & 0xffff;\n          colorkeymask_c<uint16_t>(pf, pitch, R, G, B, vi.height, rowsize, tolB16, tolG16, tolR16);\n        }\n      }\n  }\n\n  return frame;\n}\n\nAVSValue __cdecl ColorKeyMask::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  enum { CHILD, COLOR, TOLERANCE_B, TOLERANCE_G, TOLERANCE_R };\n  return new ColorKeyMask(args[CHILD].AsClip(),\n    args[COLOR].AsInt(0),\n    args[TOLERANCE_B].AsInt(10),\n    args[TOLERANCE_G].AsInt(args[TOLERANCE_B].AsInt(10)),\n    args[TOLERANCE_R].AsInt(args[TOLERANCE_B].AsInt(10)), env);\n}\n\n\n/********************************\n ******  ResetMask filter  ******\n ********************************/\n\n\nResetMask::ResetMask(PClip _child, AVSValue _mask_f, AVSValue _opacity_f, IScriptEnvironment* env)\n  : GenericVideoFilter(_child)\n{\n  if (!(vi.IsRGB32() || vi.IsRGB64() || vi.IsPlanarRGBA() || vi.IsYUVA()))\n    env->ThrowError(\"ResetMask: format has no alpha channel\");\n\n  mask_f = _mask_f.AsFloatf(-1.0f);\n  const bool mask_defined = _mask_f.Defined();\n  const bool opacity_defined = _opacity_f.Defined();\n  if (mask_defined && mask_f < 0.0f) {\n    env->ThrowError(\"ResetMask: mask value must be non-negative\");\n  }\n  // only for integers\n  int max_pixel_value = vi.BitsPerComponent() <= 16 ? (1 << vi.BitsPerComponent()) - 1 : /*n/a*/ 255;\n  // mask and mask_f are the exact unscaled values to put into A channel (integer/float)\n  if (!mask_defined) {\n    mask_f = 1.0f;\n    mask = max_pixel_value;\n  }\n  else {\n    // mask is defined - convert to integer for non-float formats\n    if (vi.ComponentSize() < 4) {\n      // integer format - use mask value directly\n      mask = (int)(mask_f + 0.5f);\n    }\n    // for float formats, mask_f is already set correctly\n  }\n  // no check, allow rounding errors\n  /*\n  if (opacity_defined && _opacity_f.AsFloat(1.0f) < 0.0f) {\n    env->ThrowError(\"ResetMask: opacity value must be non-negative\");\n  }\n  if (opacity_defined && _opacity_f.AsFloat(1.0f) > 1.0f) {\n    env->ThrowError(\"ResetMask: opacity value must be between 0.0 and 1.0\");\n  }\n  */\n  if (opacity_defined) {\n    // if opacity is defined, calculate mask_f from opacity\n    mask_f = _opacity_f.AsFloatf(1.0f);\n    if (mask_f < 0.0f) mask_f = 0.0f;\n    if (mask_f > 1.0f) mask_f = 1.0f;\n    mask = (int)(mask_f * max_pixel_value + 0.5f);\n  }\n\n  // mask (bit depth dependent): unscaled value. If none -> max OPACITY (fully opaque)\n  //\n  // opacity parameter (0.0 to 1.0):\n  // opacity = 1.0 means OPAQUE (fully visible, mask value 255/1023/etc. : white)\n  // opacity = 0.0 means TRANSPARENT (invisible, mask value 0 : black)\n  // when opacity is set, it overrides mask\n\n  mask = clamp(mask, 0, max_pixel_value);\n  mask_f = clamp(mask_f, 0.0f, 1.0f);\n}\n\n\nPVideoFrame ResetMask::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame f = child->GetFrame(n, env);\n  env->MakeWritable(&f);\n\n  if (vi.IsPlanarRGBA() || vi.IsYUVA()) {\n    const int dst_rowsizeA = f->GetRowSize(PLANAR_A);\n    const int dst_pitchA = f->GetPitch(PLANAR_A);\n    BYTE* dstp_a = f->GetWritePtr(PLANAR_A);\n    const int heightA = f->GetHeight(PLANAR_A);\n\n    switch (vi.ComponentSize())\n    {\n    case 1:\n      fill_plane<BYTE>(dstp_a, heightA, dst_rowsizeA, dst_pitchA, mask);\n      break;\n    case 2:\n      fill_plane<uint16_t>(dstp_a, heightA, dst_rowsizeA, dst_pitchA, mask);\n      break;\n    case 4:\n      fill_plane<float>(dstp_a, heightA, dst_rowsizeA, dst_pitchA, mask_f);\n      break;\n    }\n    return f;\n  }\n  // RGB32 and RGB64\n\n  BYTE* pf = f->GetWritePtr();\n  int pitch = f->GetPitch();\n  int rowsize = f->GetRowSize();\n  int height = f->GetHeight();\n\n  if (vi.IsRGB32()) {\n    for (int y = 0; y < height; y++) {\n      for (int x = 3; x < rowsize; x += 4) {\n        pf[x] = mask;\n      }\n      pf += pitch;\n    }\n  }\n  else if (vi.IsRGB64()) {\n    rowsize /= sizeof(uint16_t);\n    for (int y = 0; y < height; y++) {\n      for (int x = 3; x < rowsize; x += 4) {\n        reinterpret_cast<uint16_t*>(pf)[x] = mask;\n      }\n      pf += pitch;\n    }\n  }\n\n  return f;\n}\n\n\nAVSValue ResetMask::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  return new ResetMask(args[0].AsClip(), args[1], args[2], env);\n}\n\n\n/********************************\n ******  Invert filter  ******\n ********************************/\n\n\nInvert::Invert(PClip _child, const char* _channels, IScriptEnvironment* env)\n  : GenericVideoFilter(_child)\n{\n  doB = doG = doR = doA = doY = doU = doV = false;\n\n  for (int k = 0; _channels[k] != '\\0'; ++k) {\n    switch (_channels[k]) {\n    case 'B':\n    case 'b':\n      doB = true;\n      break;\n    case 'G':\n    case 'g':\n      doG = true;\n      break;\n    case 'R':\n    case 'r':\n      doR = true;\n      break;\n    case 'A':\n    case 'a':\n      doA = (vi.NumComponents() > 3);\n      break;\n    case 'Y':\n    case 'y':\n      doY = true;\n      break;\n    case 'U':\n    case 'u':\n      doU = (vi.NumComponents() > 1);\n      break;\n    case 'V':\n    case 'v':\n      doV = (vi.NumComponents() > 1);\n      break;\n    default:\n      break;\n    }\n  }\n  pixelsize = vi.ComponentSize();\n  bits_per_pixel = vi.BitsPerComponent();\n  if (vi.IsYUY2()) {\n    mask = doY ? 0x00ff00ff : 0;\n    mask |= doU ? 0x0000ff00 : 0;\n    mask |= doV ? 0xff000000 : 0;\n  }\n  else if (vi.IsRGB32()) {\n    mask = doB ? 0x000000ff : 0;\n    mask |= doG ? 0x0000ff00 : 0;\n    mask |= doR ? 0x00ff0000 : 0;\n    mask |= doA ? 0xff000000 : 0;\n  }\n  else if (vi.IsRGB64()) {\n    mask64 = doB ? 0x000000000000ffffull : 0;\n    mask64 |= (doG ? 0x00000000ffff0000ull : 0);\n    mask64 |= (doR ? 0x0000ffff00000000ull : 0);\n    mask64 |= (doA ? 0xffff000000000000ull : 0);\n  }\n  else {\n    mask = 0xffffffff;\n    mask64 = (1 << bits_per_pixel) - 1;\n    mask64 |= (mask64 << 48) | (mask64 << 32) | (mask64 << 16); // works for 10 bit, too\n    // RGB24/48 is special case no use of this mask\n  }\n}\n\n\n//mod4 width is required\nstatic void invert_frame_inplace_c(BYTE* frame, int pitch, int width, int height, int mask) {\n  for (int y = 0; y < height; ++y) {\n    int* intptr = reinterpret_cast<int*>(frame);\n\n    for (int x = 0; x < width / 4; ++x) {\n      intptr[x] = intptr[x] ^ mask;\n    }\n    frame += pitch;\n  }\n}\n\nstatic void invert_frame_uint16_inplace_c(BYTE* frame, int pitch, int width, int height, uint64_t mask64) {\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width / 8; ++x) {\n      reinterpret_cast<uint64_t*>(frame)[x] = reinterpret_cast<uint64_t*>(frame)[x] ^ mask64;\n    }\n    frame += pitch;\n  }\n}\n\n// called for uint8_t, uint16_t and float planar, chroma planes are inverted differently than luma plane\n// R G B are treated the same way as luma.\n// We assume full-range.\n// 3.7.6 minor change: chroma: uint8_t, uint16_t: pivot around half and not xor FF/FFFF for chroma\n// Note: this filter is so simple that it is optimized from C to same speed as SIMD in release\n// Also, it is memory-bound AVX2 is not quicker than SSE2.\n// lessthan16bits helps optimizing the exact 16 bit case.\n// We use this very same C source for AVX2, where it is optimized even with 2x256 bit paths\ntemplate<typename pixel_t, bool lessthan16bits, bool chroma>\nstatic void invert_plane_c(uint8_t* dstp, const uint8_t* srcp, int src_pitch, int dst_pitch, int width, int height, int bits_per_pixel) {\n  if constexpr (std::is_same_v<pixel_t, float>) {\n    if constexpr (chroma) {\n      // For chroma planes, invert around 0.0 -> negate\n      for (int y = 0; y < height; ++y) {\n        for (int x = 0; x < width; ++x) {\n          reinterpret_cast<float*>(dstp)[x] = -reinterpret_cast<const float*>(srcp)[x];\n        }\n        srcp += src_pitch;\n        dstp += dst_pitch;\n      }\n    }\n    else {\n      // For luma plane, invert around 1.0 -> 1.0 - value\n      for (int y = 0; y < height; ++y) {\n        for (int x = 0; x < width; ++x) {\n          reinterpret_cast<float*>(dstp)[x] = 1.0f - reinterpret_cast<const float*>(srcp)[x];\n        }\n        srcp += src_pitch;\n        dstp += dst_pitch;\n      }\n    }\n    return;\n  }\n  // 8 bit\n  if constexpr (std::is_same_v<pixel_t, uint8_t>) {\n    constexpr int max_pixel_value = 255;\n    if constexpr (chroma) {\n      constexpr int half = 128;\n      // For chroma planes, invert around 128 -> negate\n      for (int y = 0; y < height; ++y) {\n        for (int x = 0; x < width; ++x) {\n          reinterpret_cast<uint8_t*>(dstp)[x] = std::min(2 * half - reinterpret_cast<const uint8_t*>(srcp)[x], max_pixel_value);\n          // chroma invert: -(srcp[x] - half) + half\n          // = 2*half - srcp[x] = (1 << bits_per_pixel) - srcp[x]\n          // Watch for src==0, must top at max_pixel_value\n        }\n        srcp += src_pitch;\n        dstp += dst_pitch;\n      }\n    }\n    else {\n      // For luma plane, 255-x which is xor 0xff\n      for (int y = 0; y < height; ++y) {\n        for (int x = 0; x < width; ++x) {\n          reinterpret_cast<uint8_t*>(dstp)[x] = max_pixel_value - reinterpret_cast<const uint8_t*>(srcp)[x];\n        }\n        srcp += src_pitch;\n        dstp += dst_pitch;\n      }\n    }\n    return;\n  }\n  // 10-16 bit uint16_t, luma: max_pixel_value - x which is xor with max_pixel_value, chroma: half - x\n  if constexpr (std::is_same_v<pixel_t, uint16_t>) {\n    if constexpr (!lessthan16bits)\n      bits_per_pixel = 16; // quasi constexpr for optimization\n    const int max_pixel_value = (1 << bits_per_pixel) - 1;\n    if constexpr (chroma) {\n      const int half = 1 << (bits_per_pixel - 1);\n      // For chroma planes, invert around mid-point (2^(bits-1))\n      for (int y = 0; y < height; ++y) {\n        for (int x = 0; x < width; ++x) {\n          reinterpret_cast<uint16_t*>(dstp)[x] = std::min(2 * half - reinterpret_cast<const uint16_t*>(srcp)[x], max_pixel_value);\n          // chroma invert: -(srcp[x] - half) + half\n          // = 2*half - srcp[x] = (1 << bits_per_pixel) - srcp[x]\n          // Watch for src==0, must top at max_pixel_value\n        }\n        srcp += src_pitch;\n        dstp += dst_pitch;\n      }\n    }\n    else {\n      // For luma plane, max_pixel_value - x\n      for (int y = 0; y < height; ++y) {\n        for (int x = 0; x < width; ++x) {\n          reinterpret_cast<uint16_t*>(dstp)[x] = max_pixel_value - reinterpret_cast<const uint16_t*>(srcp)[x];\n        }\n        srcp += src_pitch;\n        dstp += dst_pitch;\n      }\n    }\n  }\n}\n\n// YUY2 and packed RGB formats\nstatic void invert_frame_inplace(BYTE* frame, int pitch, int rowsize, int height, int mask, uint64_t mask64, int pixelsize, IScriptEnvironment* env) {\n#ifdef INTEL_INTRINSICS\n  if ((pixelsize == 1 || pixelsize == 2) && (env->GetCPUFlags() & CPUF_AVX2))\n  {\n    if (pixelsize == 1)\n      invert_frame_inplace_avx2(frame, pitch, rowsize, height, mask);\n    else\n      invert_frame_uint16_inplace_avx2(frame, pitch, rowsize, height, mask64);\n  }\n  else if ((pixelsize == 1 || pixelsize == 2) && (env->GetCPUFlags() & CPUF_SSE2))\n  {\n    if (pixelsize == 1)\n      invert_frame_inplace_sse2(frame, pitch, rowsize, height, mask);\n    else\n      invert_frame_uint16_inplace_sse2(frame, pitch, rowsize, height, mask64);\n  }\n  else\n#endif\n  {\n    if (pixelsize == 1)\n      invert_frame_inplace_c(frame, pitch, rowsize, height, mask);\n    else\n      invert_frame_uint16_inplace_c(frame, pitch, rowsize, height, mask64);\n  }\n}\n\n// Function pointer type definition\nusing invert_plane_fn_t = void(*)(uint8_t*, const uint8_t*, int, int, int, int, int);\n\n// width is in pixels, not bytes.\n// Invoking only C functions, since optimizers do a decent work, code is not slower than manual SIMD for this easy filter.\nstatic void invert_plane(uint8_t* dstp, const uint8_t* srcp, int src_pitch, int dst_pitch, int width, int height, int bits_per_pixel, bool chroma, IScriptEnvironment* env) {\n  const int pixelsize = bits_per_pixel == 8 ? 1 : bits_per_pixel <= 16 ? 2 : 4; // 8 bit = 1 byte, 10-16 bit = 2 bytes, float = 4 bytes\n#ifdef INTEL_INTRINSICS\n  const bool avx2 = env->GetCPUFlags() & CPUF_AVX2;\n#endif\n\n  invert_plane_fn_t fn = nullptr;\n\n  switch (pixelsize) {\n  case 1:\n#ifdef INTEL_INTRINSICS\n    if (avx2)\n      fn = chroma ? invert_plane_c_avx2<uint8_t, true /*lt16b* n/a */, true> : invert_plane_c_avx2<uint8_t, true /*lt16b* n/a */, false>;\n    else\n#endif\n      fn = chroma ? invert_plane_c<uint8_t, true /*lt16b* n/a */, true> : invert_plane_c<uint8_t, true /*lt16b* n/a */, false>;\n    break;\n  case 2:\n    if (bits_per_pixel < 16) {\n#ifdef INTEL_INTRINSICS\n      if (avx2)\n        fn = chroma ? invert_plane_c_avx2<uint16_t, true /*lt16b**/, true> : invert_plane_c_avx2<uint16_t, true /*lt16b**/, false>;\n      else\n#endif\n        fn = chroma ? invert_plane_c<uint16_t, true /*lt16b**/, true> : invert_plane_c<uint16_t, true /*lt16b**/, false>;\n    }\n    else {\n#ifdef INTEL_INTRINSICS\n      if (avx2)\n        fn = chroma ? invert_plane_c_avx2<uint16_t, false /*lt16b**/, true> : invert_plane_c_avx2<uint16_t, false /*lt16b**/, false>;\n      else\n#endif\n        fn = chroma ? invert_plane_c<uint16_t, false /*lt16b**/, true> : invert_plane_c<uint16_t, false /*lt16b**/, false>;\n    }\n    break;\n  case 4:\n#ifdef INTEL_INTRINSICS\n    if (avx2)\n      fn = chroma ? invert_plane_c_avx2<float, false /*lt16b* n/a */, true> : invert_plane_c_avx2<float, false /*lt16b* n/a */, false>;\n    else\n#endif\n      fn = chroma ? invert_plane_c<float, false /*lt16b* n/a */, true> : invert_plane_c<float, false /*lt16b* n/a */, false>;\n    break;\n  }\n\n  fn(dstp, srcp, src_pitch, dst_pitch, width, height, bits_per_pixel);\n}\n\nPVideoFrame Invert::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame src = child->GetFrame(n, env);\n\n  if (vi.IsPlanar()) {\n\n    // We do not use worst case MakeWritable, do it per plane.\n    // Read and Invert only those planes which are needed, BitBlt the rest.\n\n    PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n\n    // Helper function to process or copy a plane\n    auto process_plane = [&](int plane, bool do_process, bool is_chroma) {\n      if (do_process) {\n        invert_plane(\n          dst->GetWritePtr(plane),\n          src->GetReadPtr(plane),\n          src->GetPitch(plane),\n          dst->GetPitch(plane),\n          dst->GetRowSize(plane) / pixelsize,\n          dst->GetHeight(plane),\n          bits_per_pixel,\n          is_chroma,\n          env\n        );\n      }\n      else {\n        env->BitBlt(\n          dst->GetWritePtr(plane),\n          dst->GetPitch(plane),\n          src->GetReadPtr(plane),\n          src->GetPitch(plane),\n          src->GetRowSize(plane | PLANAR_ALIGNED),  // Use aligned row size for BitBlt optimization\n          src->GetHeight(plane)\n        );\n      }\n      };\n\n    // YUV/YUVA\n    if (vi.IsYUV() || vi.IsYUVA()) {\n      process_plane(PLANAR_Y, doY, false);\n      process_plane(PLANAR_U, doU, true);\n      process_plane(PLANAR_V, doV, true);\n    }\n\n    // Planar RGB/RGBA\n    if (vi.IsPlanarRGB() || vi.IsPlanarRGBA()) {\n      process_plane(PLANAR_G, doG, false);\n      process_plane(PLANAR_B, doB, false);\n      process_plane(PLANAR_R, doR, false);\n    }\n\n    // Alpha channel\n    if (vi.IsPlanarRGBA() || vi.IsYUVA()) {\n      process_plane(PLANAR_A, doA, false);\n    }\n\n    return dst;\n  }\n\n  // packed formats, we do a full copy of the frame before inverting\n  env->MakeWritable(&src);\n\n  BYTE* pf = src->GetWritePtr();\n  int pitch = src->GetPitch();\n  int rowsize = src->GetRowSize();\n  int height = src->GetHeight();\n\n  if (vi.IsYUY2() || vi.IsRGB32() || vi.IsRGB64()) {\n    // packed pixels, 4x1 or 4x2 bytes, all can be treated the same way with a mask\n    // YUY2 is simply xored even in its chroma component. Not really correct, but YUY2 is a compability format.\n    // we won't convert it to and from YV16, keep its pre-3.7.6 behavior.\n    invert_frame_inplace(pf, pitch, rowsize, height, mask, mask64, pixelsize, env);\n  }\n  else if (vi.IsRGB24()) {\n    int rMask = doR ? 0xff : 0;\n    int gMask = doG ? 0xff : 0;\n    int bMask = doB ? 0xff : 0;\n    for (int i = 0; i < height; i++) {\n\n      for (int j = 0; j < rowsize; j += 3) {\n        pf[j + 0] = pf[j + 0] ^ bMask;\n        pf[j + 1] = pf[j + 1] ^ gMask;\n        pf[j + 2] = pf[j + 2] ^ rMask;\n      }\n      pf += pitch;\n    }\n  }\n  else if (vi.IsRGB48()) {\n    int rMask = doR ? 0xffff : 0;\n    int gMask = doG ? 0xffff : 0;\n    int bMask = doB ? 0xffff : 0;\n    for (int i = 0; i < height; i++) {\n      for (int j = 0; j < rowsize / pixelsize; j += 3) {\n        reinterpret_cast<uint16_t*>(pf)[j + 0] ^= bMask;\n        reinterpret_cast<uint16_t*>(pf)[j + 1] ^= gMask;\n        reinterpret_cast<uint16_t*>(pf)[j + 2] ^= rMask;\n      }\n      pf += pitch;\n    }\n  }\n\n  return src;\n}\n\n\nAVSValue Invert::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  return new Invert(args[0].AsClip(), args[0].AsClip()->GetVideoInfo().IsRGB() ? args[1].AsString(\"RGBA\") : args[1].AsString(\"YUVA\"), env);\n}\n\n\n/**********************************\n ******  ShowChannel filter  ******\n **********************************/\n\n\nShowChannel::ShowChannel(PClip _child, const char* pixel_type, int _channel, IScriptEnvironment* env)\n  : GenericVideoFilter(_child), channel(_channel), input_type(_child->GetVideoInfo().pixel_type),\n  pixelsize(_child->GetVideoInfo().ComponentSize()), bits_per_pixel(_child->GetVideoInfo().BitsPerComponent())\n{\n  static const char* const ShowText[7] = { \"Blue\", \"Green\", \"Red\", \"Alpha\", \"Y\", \"U\", \"V\" };\n\n  input_type_is_packed_rgb = vi.IsRGB() && !vi.IsPlanar();\n  input_type_is_planar_rgb = vi.IsPlanarRGB();\n  input_type_is_planar_rgba = vi.IsPlanarRGBA();\n  input_type_is_yuva = vi.IsYUVA();\n  input_type_is_yuv = vi.IsYUV() && vi.IsPlanar();\n  input_type_is_planar = vi.IsPlanar();\n\n  int orig_channel = channel;\n\n  // A channel\n  if ((channel == 3) && !vi.IsRGB32() && !vi.IsRGB64() && !vi.IsPlanarRGBA() && !vi.IsYUVA())\n    env->ThrowError(\"ShowAlpha: RGB32, RGB64, Planar RGBA or YUVA data only\");\n\n  // R, G, B channel\n  if ((channel >= 0) && (channel <= 2) && !vi.IsRGB())\n    env->ThrowError(\"Show%s: plane is valid only with RGB or planar RGB(A) source\", ShowText[channel]);\n\n  // Y, U, V channel (4,5,6)\n  if ((channel >= 4) && (channel <= 6)) {\n    if (!vi.IsYUV() && !vi.IsYUVA())\n      env->ThrowError(\"Show%s: plane is valid only with YUV(A) source\", ShowText[channel]);\n    if (channel != 4 && vi.IsY())\n      env->ThrowError(\"Show%s: invalid plane for greyscale source\", ShowText[channel]);\n    channel -= 4; // map to 0,1,2\n  }\n\n  int target_bits_per_pixel;\n\n  const int orig_width = vi.width;\n  const int orig_height = vi.height;\n\n  if (input_type_is_yuv || input_type_is_yuva)\n  {\n    if (channel == 1 || channel == 2) // U or V: target can be smaller than Y\n    {\n      vi.width >>= vi.GetPlaneWidthSubsampling(PLANAR_U);\n      vi.height >>= vi.GetPlaneHeightSubsampling(PLANAR_U);\n    }\n  }\n\n  const bool empty_pixel_type = pixel_type == nullptr || *pixel_type == 0;\n\n  if (!lstrcmpi(pixel_type, \"rgb\") || (vi.IsRGB() && empty_pixel_type)) {\n    // target is RGB, rgb (packed) is adaptively 32 or 64 bits\n    //                rgb (planar) is of any bit depths\n    if (vi.IsPlanar()) {\n      // YUV, planar RGB or Y\n      // always alphaless planar RGB output\n      switch (bits_per_pixel) {\n      case 8: vi.pixel_type = VideoInfo::CS_RGBP8; break;\n      case 10: vi.pixel_type = VideoInfo::CS_RGBP10; break;\n      case 12: vi.pixel_type = VideoInfo::CS_RGBP12; break;\n      case 14: vi.pixel_type = VideoInfo::CS_RGBP14; break;\n      case 16: vi.pixel_type = VideoInfo::CS_RGBP16; break;\n      case 32: vi.pixel_type = VideoInfo::CS_RGBPS; break;\n      }\n    }\n    else if (vi.IsRGB()) {\n      // packed RGB source\n      switch (bits_per_pixel) {\n      case 8: vi.pixel_type = VideoInfo::CS_BGR32; break; // bit-depth adaptive\n      case 16: vi.pixel_type = VideoInfo::CS_BGR64; break;\n      default: env->ThrowError(\"Show%s: source must be 8 or 16 bits\", ShowText[orig_channel]);\n      }\n    }\n    else {\n      env->ThrowError(\"Show%s: unsupported source format\", ShowText[orig_channel]);\n    }\n    target_bits_per_pixel = bits_per_pixel;\n  }\n  else if (!lstrcmpi(pixel_type, \"yuv\") || ((vi.IsYUV() || vi.IsYUVA()) && empty_pixel_type)) {\n    // target is YUV, rgb (packed) is adaptively 32 or 64 bits\n    //                rgb (planar) is of any bit depths\n    //                YUV,Y: 420\n      // RGB source, when only 'yuv' is given, convert to 444\n    switch (bits_per_pixel) {\n    case 8: vi.pixel_type = VideoInfo::CS_YV24; break;\n    case 10: vi.pixel_type = VideoInfo::CS_YUV444P10; break;\n    case 12: vi.pixel_type = VideoInfo::CS_YUV444P12; break;\n    case 14: vi.pixel_type = VideoInfo::CS_YUV444P14; break;\n    case 16: vi.pixel_type = VideoInfo::CS_YUV444P16; break;\n    case 32: vi.pixel_type = VideoInfo::CS_YUV444PS; break;\n    }\n    target_bits_per_pixel = bits_per_pixel;\n  }\n  else {\n    // explicitely given output pixel type\n    \n    // first try\n    // Append bit depth and check\n    std::string format = pixel_type;\n    // RGBP --> RGBPS, Y -> Y16, YUV420 -> YUV420P10\n    if (!lstrcmpi(pixel_type, \"y\")) {\n      format = format + std::to_string(bits_per_pixel); // Y8..Y16, also Y32\n    }\n    else if (!lstrcmpi(pixel_type, \"rgbp\") || !lstrcmpi(pixel_type, \"rgbap\")) {\n      if (bits_per_pixel == 32)\n        format = format + \"S\"; // RGBAPS\n      else\n        format = format + std::to_string(bits_per_pixel); // RGBP16\n    }\n    else {\n      // hopefully like \"yuv420\" or \"yuva444\"\n      if (bits_per_pixel == 32)\n        format = format + \"PS\"; // YUV420PS\n      else\n        format = format + \"P\" + std::to_string(bits_per_pixel); // YUV420P16\n    }\n\n    int new_pixel_type = GetPixelTypeFromName(format.c_str());\n    if (new_pixel_type == VideoInfo::CS_UNKNOWN) {\n      new_pixel_type = GetPixelTypeFromName(pixel_type);\n      if (new_pixel_type == VideoInfo::CS_UNKNOWN)\n        env->ThrowError(\"Show%s: invalid pixel_type!\", ShowText[orig_channel]);\n    }\n    // new output format\n    vi.pixel_type = new_pixel_type;\n\n    if (vi.IsYUY2()) {\n      if (vi.width & 1) {\n        env->ThrowError(\"Show%s: width must be mod 2 for yuy2\", ShowText[orig_channel]);\n      }\n    }\n    if (vi.Is420()) {\n      if (vi.width & 1) {\n        env->ThrowError(\"Show%s: width must be mod 2 for 4:2:0 target\", ShowText[orig_channel]);\n      }\n      if (vi.height & 1) {\n        env->ThrowError(\"Show%s: height must be mod 2 for 4:2:0 target\", ShowText[orig_channel]);\n      }\n    }\n    if (vi.Is422()) {\n      if (vi.width & 1) {\n        env->ThrowError(\"Show%s: width must be mod 2 for 4:2:2 target\", ShowText[orig_channel]);\n      }\n    }\n    if (vi.IsYV411()) {\n      if (vi.width & 3) {\n        env->ThrowError(\"Show%s: width must be mod 4 for 4:1:1 target\", ShowText[orig_channel]);\n      }\n    }\n\n    target_bits_per_pixel = vi.BitsPerComponent();\n  }\n\n  if (target_bits_per_pixel != bits_per_pixel)\n    env->ThrowError(\"Show%s: source bit depth must be %d for %s\", ShowText[orig_channel], target_bits_per_pixel, pixel_type);\n\n  target_hasalpha = vi.IsRGB32() || vi.IsRGB64() || vi.IsPlanarRGBA() || vi.IsYUVA();\n  source_hasalpha = input_type == VideoInfo::CS_BGR32 || input_type == VideoInfo::CS_BGR64 || input_type_is_planar_rgba || input_type_is_yuva;\n\n  if (target_hasalpha && source_hasalpha && (vi.width != orig_width || vi.height != orig_height)) {\n    env->ThrowError(\"Show%s: subsampled source plane and alpha-aware source and destination format: alpha dimensions must be the same\", ShowText[orig_channel]);\n  }\n\n}\n\n\ntemplate<typename pixel_t, bool source_hasalpha, bool target_hasalpha>\nstatic void planar_to_packedrgb(uint8_t* dstp, int dst_pitch, const uint8_t* srcp, const uint8_t* srcp_a, int src_pitch, int width, int height)\n{\n  // packed RGB is upside-down\n  dstp += (height - 1) * dst_pitch;\n  constexpr int target_rgb_step = target_hasalpha ? 4 : 3;\n  constexpr int max_pixel_value = sizeof(pixel_t) == 1 ? 255 : 65535;\n\n  for (int i = 0; i < height; ++i) {\n    for (int j = 0; j < width; j++) {\n      pixel_t* curr_dstp = reinterpret_cast<pixel_t*>(dstp);\n      curr_dstp[j * target_rgb_step + 0] = curr_dstp[j * target_rgb_step + 1] = curr_dstp[j * target_rgb_step + 2] = reinterpret_cast<const pixel_t*>(srcp)[j];\n      if constexpr(target_hasalpha) {\n        const int alpha = source_hasalpha ? reinterpret_cast<const pixel_t*>(srcp_a)[j] : max_pixel_value;\n        curr_dstp[j * target_rgb_step + 3] = alpha;\n      }\n    }\n    srcp += src_pitch;\n    if constexpr(source_hasalpha)\n      srcp_a += src_pitch; // alpha has the same pitch\n    dstp -= dst_pitch;\n  }\n}\n\ntemplate<typename pixel_t, bool source_hasalpha, bool target_hasalpha>\nstatic void packed_to_packedrgb(uint8_t* dstp, int dst_pitch, const uint8_t* srcp, int pitch, int width, int height, int channel)\n{\n  constexpr int target_rgb_step = target_hasalpha ? 4 : 3;\n  constexpr int source_rgb_step = source_hasalpha ? 4 : 3;\n  constexpr int max_pixel_value = sizeof(pixel_t) == 1 ? 255 : 65535;\n\n  for (int i = 0; i < height; ++i) {\n    for (int j = 0; j < width; j++) {\n      pixel_t* curr_dstp = reinterpret_cast<pixel_t*>(dstp);\n      const int pixel = reinterpret_cast<const pixel_t*>(srcp)[j * source_rgb_step + channel];\n      curr_dstp[j * target_rgb_step + 0] = curr_dstp[j * target_rgb_step + 1] = curr_dstp[j * target_rgb_step + 2] = pixel;\n      if constexpr(target_hasalpha) {\n        const int alpha = source_hasalpha ? reinterpret_cast<const pixel_t*>(srcp)[j * source_rgb_step + 3] : max_pixel_value;\n        curr_dstp[j * target_rgb_step + 3] = alpha; // alpha\n      }\n    }\n    srcp += pitch;\n    dstp += dst_pitch;\n  }\n}\n\ntemplate<typename pixel_t, bool source_hasalpha, bool target_hasalpha>\nstatic void packed_to_planarrgb(uint8_t* dstp_r, uint8_t* dstp_g, uint8_t* dstp_b, uint8_t* dstp_a, int dst_pitch, const uint8_t* srcp, int src_pitch, int width, int height, int channel)\n{\n  constexpr int source_rgb_step = source_hasalpha ? 4 : 3;\n  constexpr int max_pixel_value = sizeof(pixel_t) == 1 ? 255 : 65535;\n\n  // packed RGB is upside-down\n  srcp += (height - 1) * src_pitch;\n\n  for (int i = 0; i < height; ++i) {\n    for (int j = 0; j < width; ++j) {\n      const int pixel = reinterpret_cast<const pixel_t*>(srcp)[j * source_rgb_step + channel];\n      reinterpret_cast<pixel_t*>(dstp_g)[j] =\n        reinterpret_cast<pixel_t*>(dstp_b)[j] =\n        reinterpret_cast<pixel_t*>(dstp_r)[j] = pixel;\n      if constexpr (target_hasalpha) {\n        const int alpha = source_hasalpha ? reinterpret_cast<const pixel_t*>(srcp)[j * source_rgb_step + 3] : max_pixel_value;\n        reinterpret_cast<pixel_t*>(dstp_a)[j] = alpha;\n      }\n    }\n    srcp -= src_pitch;\n    dstp_g += dst_pitch;\n    dstp_b += dst_pitch;\n    dstp_r += dst_pitch;\n    if constexpr (target_hasalpha)\n      dstp_a += dst_pitch;\n  }\n}\n\ntemplate<typename pixel_t, bool source_hasalpha, bool target_hasalpha>\nstatic void packed_to_luma_alpha(uint8_t* dstp_y, uint8_t* dstp_a, int dst_pitch, const uint8_t* srcp, int src_pitch, int width, int height, int channel)\n{\n  constexpr int source_rgb_step = source_hasalpha ? 4 : 3;\n  constexpr int max_pixel_value = sizeof(pixel_t) == 1 ? 255 : 65535;\n\n  // packed RGB is upside-down\n  srcp += (height - 1) * src_pitch;\n\n  for (int i = 0; i < height; ++i) {\n    for (int j = 0; j < width; ++j) {\n      const int pixel = reinterpret_cast<const pixel_t*>(srcp)[j * source_rgb_step + channel];\n      reinterpret_cast<pixel_t*>(dstp_y)[j] = pixel;\n      if constexpr (target_hasalpha) {\n        const int alpha = source_hasalpha ? reinterpret_cast<const pixel_t*>(srcp)[j * source_rgb_step + 3] : max_pixel_value;\n        reinterpret_cast<pixel_t*>(dstp_a)[j] = alpha;\n      }\n    }\n    srcp -= src_pitch;\n    dstp_y += dst_pitch;\n    if constexpr (target_hasalpha)\n      dstp_a += dst_pitch;\n  }\n}\n\n\nPVideoFrame ShowChannel::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame src = child->GetFrame(n, env);\n\n  // for planar these will be reread for proper plane\n  const BYTE* srcp = src->GetReadPtr();\n  const int height = src->GetHeight();\n  const int pitch = src->GetPitch();\n  const int rowsize = src->GetRowSize();\n\n  const float chroma_center_f = 0.0f;\n\n  if (input_type_is_packed_rgb) {\n    PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n\n    if (!vi.IsRGB()) {\n      // delete _Matrix when target is not an RGB\n      auto props = env->getFramePropsRW(dst);\n      env->propDeleteKey(props, \"_Matrix\");\n    }\n\n    const int source_rgb_step = source_hasalpha ? 4 : 3;\n    const int w = rowsize / pixelsize / source_rgb_step;\n\n    if (vi.IsRGB() && !vi.IsPlanar())\n    {\n      // packed RGB to packed RGB\n      BYTE* dstp = dst->GetWritePtr();\n      const int dstpitch = dst->GetPitch();\n\n      if (pixelsize == 1) {\n        if (!source_hasalpha && !target_hasalpha)\n          packed_to_packedrgb<uint8_t, false, false>(dstp, dstpitch, srcp, pitch, w, height, channel);\n        else if (!source_hasalpha && target_hasalpha)\n          packed_to_packedrgb<uint8_t, false, true>(dstp, dstpitch, srcp, pitch, w, height, channel);\n        else if (source_hasalpha && !target_hasalpha)\n          packed_to_packedrgb<uint8_t, true, false>(dstp, dstpitch, srcp, pitch, w, height, channel);\n        else // if (source_hasalpha && target_hasalpha)\n          packed_to_packedrgb<uint8_t, true, true>(dstp, dstpitch, srcp, pitch, w, height, channel);\n      }\n      else {\n        if (!source_hasalpha && !target_hasalpha)\n          packed_to_packedrgb<uint16_t, false, false>(dstp, dstpitch, srcp, pitch, w, height, channel);\n        else if (!source_hasalpha && target_hasalpha)\n          packed_to_packedrgb<uint16_t, false, true>(dstp, dstpitch, srcp, pitch, w, height, channel);\n        else if (source_hasalpha && !target_hasalpha)\n          packed_to_packedrgb<uint16_t, true, false>(dstp, dstpitch, srcp, pitch, w, height, channel);\n        else // if (source_hasalpha && target_hasalpha)\n          packed_to_packedrgb<uint16_t, true, true>(dstp, dstpitch, srcp, pitch, w, height, channel);\n      }\n    }\n    else if (vi.pixel_type == VideoInfo::CS_YUY2)\n    {\n      // packed RGB to YUY2\n      BYTE* dstp = dst->GetWritePtr();\n      const int dstpitch = dst->GetPitch();\n\n      // RGB is upside-down\n      srcp += (height - 1) * pitch;\n\n      for (int i = 0; i < height; ++i) {\n        for (int j = 0; j < w; j++) {\n          dstp[j * 2 + 0] = srcp[j * source_rgb_step + channel];\n          dstp[j * 2 + 1] = 128;\n        }\n        srcp -= pitch;\n        dstp += dstpitch;\n      }\n    }\n    else if (vi.IsYUV() || vi.IsYUVA() || vi.IsY())\n    {\n      // packed RGB -> Y, YUV(A)\n      BYTE* dstp = dst->GetWritePtr();\n      int dstpitch = dst->GetPitch();\n\n      BYTE* dstp_a = target_hasalpha ? dst->GetWritePtr(PLANAR_A) : nullptr;\n\n      if (pixelsize == 1) {\n        if (!source_hasalpha && !target_hasalpha)\n          packed_to_luma_alpha<uint8_t, false, false>(dstp, dstp_a, dstpitch, srcp, pitch, w, height, channel);\n        else if (!source_hasalpha && target_hasalpha)\n          packed_to_luma_alpha<uint8_t, false, true>(dstp, dstp_a, dstpitch, srcp, pitch, w, height, channel);\n        else if (source_hasalpha && !target_hasalpha)\n          packed_to_luma_alpha<uint8_t, true, false>(dstp, dstp_a, dstpitch, srcp, pitch, w, height, channel);\n        else // if (source_hasalpha && target_hasalpha)\n          packed_to_luma_alpha<uint8_t, true, true>(dstp, dstp_a, dstpitch, srcp, pitch, w, height, channel);\n      }\n      else {\n        // 16 bit\n        if (!source_hasalpha && !target_hasalpha)\n          packed_to_luma_alpha<uint16_t, false, false>(dstp, dstp_a, dstpitch, srcp, pitch, w, height, channel);\n        else if (!source_hasalpha && target_hasalpha)\n          packed_to_luma_alpha<uint16_t, false, true>(dstp, dstp_a, dstpitch, srcp, pitch, w, height, channel);\n        else if (source_hasalpha && !target_hasalpha)\n          packed_to_luma_alpha<uint16_t, true, false>(dstp, dstp_a, dstpitch, srcp, pitch, w, height, channel);\n        else // if (source_hasalpha && target_hasalpha)\n          packed_to_luma_alpha<uint16_t, true, true>(dstp, dstp_a, dstpitch, srcp, pitch, w, height, channel);\n      }\n\n      // fill chroma neutral\n      if (!vi.IsY())\n      {\n        int uvrowsize = dst->GetRowSize(PLANAR_U);\n        int uvpitch = dst->GetPitch(PLANAR_U);\n        int dstheight = dst->GetHeight(PLANAR_U);\n        BYTE* dstp_u = dst->GetWritePtr(PLANAR_U);\n        BYTE* dstp_v = dst->GetWritePtr(PLANAR_V);\n        switch (pixelsize) {\n        case 1: fill_chroma<BYTE>(dstp_u, dstp_v, dstheight, uvrowsize, uvpitch, (BYTE)0x80); break;\n        case 2: fill_chroma<uint16_t>(dstp_u, dstp_v, dstheight, uvrowsize, uvpitch, 1 << (vi.BitsPerComponent() - 1)); break;\n        case 4:\n          fill_chroma<float>(dstp_u, dstp_v, dstheight, uvrowsize, uvpitch, chroma_center_f);\n          break;\n        }\n      }\n    }\n    else if (vi.IsPlanarRGB() || vi.IsPlanarRGBA())\n    {  // packed RGB -> Planar RGB 8/16 bit\n      BYTE* dstp_g = dst->GetWritePtr(PLANAR_G);\n      BYTE* dstp_b = dst->GetWritePtr(PLANAR_B);\n      BYTE* dstp_r = dst->GetWritePtr(PLANAR_R);\n      int dstpitch = dst->GetPitch();\n\n      BYTE* dstp_a = target_hasalpha ? dst->GetWritePtr(PLANAR_A) : nullptr;\n\n      if (pixelsize == 1) {\n        if (!source_hasalpha && !target_hasalpha)\n          packed_to_planarrgb<uint8_t, false, false>(dstp_r, dstp_g, dstp_b, dstp_a, dstpitch, srcp, pitch, w, height, channel);\n        else if (!source_hasalpha && target_hasalpha)\n          packed_to_planarrgb<uint8_t, false, true>(dstp_r, dstp_g, dstp_b, dstp_a, dstpitch, srcp, pitch, w, height, channel);\n        else if (source_hasalpha && !target_hasalpha)\n          packed_to_planarrgb<uint8_t, true, false>(dstp_r, dstp_g, dstp_b, dstp_a, dstpitch, srcp, pitch, w, height, channel);\n        else // if (source_hasalpha && target_hasalpha)\n          packed_to_planarrgb<uint8_t, true, true>(dstp_r, dstp_g, dstp_b, dstp_a, dstpitch, srcp, pitch, w, height, channel);\n      }\n      else {\n        // 16 bit\n        if (!source_hasalpha && !target_hasalpha)\n          packed_to_planarrgb<uint16_t, false, false>(dstp_r, dstp_g, dstp_b, dstp_a, dstpitch, srcp, pitch, w, height, channel);\n        else if (!source_hasalpha && target_hasalpha)\n          packed_to_planarrgb<uint16_t, false, true>(dstp_r, dstp_g, dstp_b, dstp_a, dstpitch, srcp, pitch, w, height, channel);\n        else if (source_hasalpha && !target_hasalpha)\n          packed_to_planarrgb<uint16_t, true, false>(dstp_r, dstp_g, dstp_b, dstp_a, dstpitch, srcp, pitch, w, height, channel);\n        else // if (source_hasalpha && target_hasalpha)\n          packed_to_planarrgb<uint16_t, true, true>(dstp_r, dstp_g, dstp_b, dstp_a, dstpitch, srcp, pitch, w, height, channel);\n      }\n    }\n    return dst;\n  } // end of packed rgb source\n  \n  if (input_type_is_planar_rgb || input_type_is_planar_rgba || input_type_is_yuv || input_type_is_yuva) {\n    // planar source\n    const int planesYUV[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };\n    const int planesRGB[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A };\n    const int* planes = (input_type_is_planar_rgb || input_type_is_planar_rgba) ? planesRGB : planesYUV;\n    int final_channel = channel;\n    // RGB channels: B=0 G=1 R=2 (like packed)\n    // Planar order: G=0 B=1 R=2\n    if (input_type_is_planar_rgb || input_type_is_planar_rgba) {\n      // exchange B and G\n      if (channel == 0) final_channel = 1;\n      else if (channel == 1) final_channel = 0;\n    }\n    const int plane = planes[final_channel];\n\n    const BYTE* srcp = src->GetReadPtr(plane); // source plane\n    const BYTE* srcp_a = source_hasalpha ? src->GetReadPtr(PLANAR_A) : nullptr;\n\n    const int width = src->GetRowSize(plane) / pixelsize;\n    const int height = src->GetHeight(plane);\n    const int pitch = src->GetPitch(plane);\n\n    if (vi.IsRGB() && !vi.IsPlanar())\n    {\n      // planar RGBP/YUVA -> packed RGB\n      PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n      BYTE* dstp = dst->GetWritePtr();\n      const int dstpitch = dst->GetPitch();\n\n      if (!input_type_is_planar_rgb && !input_type_is_planar_rgba) {\n        auto props = env->getFramePropsRW(dst);\n        // delete _Matrix and ChromaLocation when source is not RGB\n        env->propDeleteKey(props, \"_Matrix\");\n        env->propDeleteKey(props, \"_ChromaLocation\");\n      }\n\n      if (bits_per_pixel == 8) {\n        if (target_hasalpha) {\n          if (source_hasalpha)\n            planar_to_packedrgb<uint8_t, true, true>(dstp, dstpitch, srcp, srcp_a, pitch, width, height);\n          else\n            planar_to_packedrgb<uint8_t, false, true>(dstp, dstpitch, srcp, srcp_a, pitch, width, height);\n        }\n        else {\n          planar_to_packedrgb<uint8_t, false, false>(dstp, dstpitch, srcp, srcp_a, pitch, width, height);\n        }\n      }\n      else {\n        // 16 bits\n        if (target_hasalpha) {\n          if (source_hasalpha)\n            planar_to_packedrgb<uint16_t, true, true>(dstp, dstpitch, srcp, srcp_a, pitch, width, height);\n          else\n            planar_to_packedrgb<uint16_t, false, true>(dstp, dstpitch, srcp, srcp_a, pitch, width, height);\n        }\n        else {\n          planar_to_packedrgb<uint16_t, false, false>(dstp, dstpitch, srcp, srcp_a, pitch, width, height);\n        }\n      }\n\n      return dst;\n    }\n    else if (vi.pixel_type == VideoInfo::CS_YUY2) // RGB(A)P/YUVA->YUY2\n    {\n      PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n      BYTE* dstp = dst->GetWritePtr();\n      const int dstpitch = dst->GetPitch();\n\n      auto props = env->getFramePropsRW(dst);\n      env->propDeleteKey(props, \"_Matrix\");\n      env->propDeleteKey(props, \"_ChromaLocation\");\n\n      for (int i = 0; i < height; ++i) {\n        for (int j = 0; j < width; j++) {\n          dstp[j * 2 + 0] = srcp[j];\n          dstp[j * 2 + 1] = 128;\n        }\n        srcp += pitch;\n        dstp += dstpitch;\n      }\n      return dst;\n    }\n    else\n    { // planar to planar\n      // RGB(A)P/YUVA -> YV12/16/24/Y8 + 16bit\n      PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n\n      // remove frame props if either src or target is not RGB\n      if (!(input_type_is_planar_rgb || input_type_is_planar_rgba || vi.IsRGB())) {\n        // RGB origin to YUV\n        auto props = env->getFramePropsRW(dst);\n        env->propDeleteKey(props, \"_Matrix\");\n        if(input_type_is_yuv || input_type_is_yuva)\n          env->propDeleteKey(props, \"_ChromaLocation\");\n      }\n\n      if (vi.IsYUV() || vi.IsYUVA() || vi.IsY()) // Y8, YV12, Y16, YUV420P16, etc.\n      {\n        BYTE* dstp = dst->GetWritePtr();\n        int dstpitch = dst->GetPitch();\n\n        // copy source plane to luma\n        env->BitBlt(dstp, dstpitch, srcp, pitch, width * pixelsize, height);\n        // fill UV with neutral\n        if (!vi.IsY())\n        {\n          int uvrowsize = dst->GetRowSize(PLANAR_U);\n          int uvpitch = dst->GetPitch(PLANAR_U);\n          int dstheight = dst->GetHeight(PLANAR_U);\n          BYTE* dstp_u = dst->GetWritePtr(PLANAR_U);\n          BYTE* dstp_v = dst->GetWritePtr(PLANAR_V);\n          switch (pixelsize) {\n          case 1: fill_chroma<uint8_t>(dstp_u, dstp_v, dstheight, uvrowsize, uvpitch, (uint8_t)0x80); break;\n          case 2: fill_chroma<uint16_t>(dstp_u, dstp_v, dstheight, uvrowsize, uvpitch, 1 << (vi.BitsPerComponent() - 1)); break;\n          case 4: fill_chroma<float>(dstp_u, dstp_v, dstheight, uvrowsize, uvpitch, chroma_center_f); break;\n          }\n        }\n      }\n      else if (vi.IsPlanarRGB() || vi.IsPlanarRGBA())\n      {  // RGBP(A)/YUVA -> Planar RGB\n        BYTE* dstp_g = dst->GetWritePtr(PLANAR_G);\n        BYTE* dstp_b = dst->GetWritePtr(PLANAR_B);\n        BYTE* dstp_r = dst->GetWritePtr(PLANAR_R);\n\n        int dstpitch = dst->GetPitch();\n        int dstwidth = dst->GetRowSize() / pixelsize;\n\n        // copy to all channels\n        if (pixelsize == 1) {\n          for (int i = 0; i < height; ++i) {\n            for (int j = 0; j < dstwidth; ++j) {\n              dstp_g[j] = dstp_b[j] = dstp_r[j] = srcp[j];\n            }\n            srcp += pitch;\n            dstp_g += dstpitch;\n            dstp_b += dstpitch;\n            dstp_r += dstpitch;\n          }\n        }\n        else if (pixelsize == 2) {\n          for (int i = 0; i < height; ++i) {\n            for (int j = 0; j < dstwidth; ++j) {\n              reinterpret_cast<uint16_t*>(dstp_g)[j] =\n                reinterpret_cast<uint16_t*>(dstp_b)[j] =\n                reinterpret_cast<uint16_t*>(dstp_r)[j] = reinterpret_cast<const uint16_t*>(srcp)[j];\n            }\n            srcp += pitch;\n            dstp_g += dstpitch;\n            dstp_b += dstpitch;\n            dstp_r += dstpitch;\n          }\n        }\n        else { // pixelsize==4\n          for (int i = 0; i < height; ++i) {\n            for (int j = 0; j < dstwidth; ++j) {\n              reinterpret_cast<float*>(dstp_g)[j] =\n                reinterpret_cast<float*>(dstp_b)[j] =\n                reinterpret_cast<float*>(dstp_r)[j] = reinterpret_cast<const float*>(srcp)[j];\n            }\n            srcp += pitch;\n            dstp_g += dstpitch;\n            dstp_b += dstpitch;\n            dstp_r += dstpitch;\n          }\n        }\n      }\n      if (target_hasalpha) {\n        // fill alpha with transparent\n        const int dst_rowsizeA = dst->GetRowSize(PLANAR_A);\n        const int dst_pitchA = dst->GetPitch(PLANAR_A);\n        BYTE* dstp_a = dst->GetWritePtr(PLANAR_A);\n        const int heightA = dst->GetHeight(PLANAR_A);\n\n        if (source_hasalpha) {\n          // copy source alpha plane to target alpha plane\n          env->BitBlt(dstp_a, dst_pitchA, srcp_a, pitch, width* pixelsize, height);\n        }\n        else {\n          switch (vi.ComponentSize())\n          {\n          case 1:\n            fill_plane<uint8_t>(dstp_a, heightA, dst_rowsizeA, dst_pitchA, 0xFF);\n            break;\n          case 2:\n            fill_plane<uint16_t>(dstp_a, heightA, dst_rowsizeA, dst_pitchA, (1 << vi.BitsPerComponent()) - 1);\n            break;\n          case 4:\n            fill_plane<float>(dstp_a, heightA, dst_rowsizeA, dst_pitchA, 1.0f);\n            break;\n          }\n        }\n      }\n      return dst;\n    }\n  } // planar RGB(A) or YUVA source\n\n  env->ThrowError(\"ShowChannel: unexpected end of function\");\n  return src;\n}\n\n\nAVSValue ShowChannel::Create(AVSValue args, void* channel, IScriptEnvironment* env)\n{\n  // yuy2 is autoconverted to YV16\n  PClip clip = args[0].AsClip();\n  const VideoInfo& vi = clip->GetVideoInfo();\n\n  if (vi.IsYUY2()) {\n    AVSValue new_args[1] = { clip };\n    clip = env->Invoke(\"ConvertToYV16\", AVSValue(new_args, 1)).AsClip();\n  }\n  return new ShowChannel(clip, args[1].AsString(\"\"), (int)(size_t)channel, env);\n}\n\n\n/**********************************\n ******  MergeRGB filter  ******\n **********************************/\n\n\nMergeRGB::MergeRGB(PClip _child, PClip _blue, PClip _green, PClip _red, PClip _alpha,\n  const char* pixel_type, IScriptEnvironment* env)\n  : GenericVideoFilter(_child), blue(_blue), green(_green), red(_red), alpha(_alpha),\n  viB(blue->GetVideoInfo()), viG(green->GetVideoInfo()), viR(red->GetVideoInfo()),\n  viA(((alpha) ? alpha : child)->GetVideoInfo()), myname((alpha) ? \"MergeARGB\" : \"MergeRGB\")\n{\n  vi = viR; // comparison base\n\n  if ((vi.BitsPerComponent() != viB.BitsPerComponent()) || (vi.BitsPerComponent() != viG.BitsPerComponent()) ||\n    (vi.BitsPerComponent() != viR.BitsPerComponent()) || (vi.BitsPerComponent() != viA.BitsPerComponent()))\n    env->ThrowError(\"%s: All clips must have the same bit depth.\", myname);\n\n  if ((vi.width != viB.width) || (vi.width != viG.width) || (vi.width != viR.width) || (vi.width != viA.width))\n    env->ThrowError(\"%s: All clips must have the same width.\", myname);\n\n  if ((vi.height != viB.height) || (vi.height != viG.height) || (vi.height != viR.height) || (vi.height != viA.height))\n    env->ThrowError(\"%s: All clips must have the same height.\", myname);\n\n  const int is_any_planar_rgb =\n    viR.IsPlanarRGB() || viR.IsPlanarRGBA() ||\n    viG.IsPlanarRGB() || viG.IsPlanarRGBA() ||\n    viB.IsPlanarRGB() || viB.IsPlanarRGBA() ||\n    viA.IsPlanarRGB() || viA.IsPlanarRGBA();\n\n  const int bits_per_pixel = viR.BitsPerComponent();\n  const bool empty_pixel_type = pixel_type == nullptr || *pixel_type == 0;\n\n  // planar rgb target if\n  // - pixel_type is \"rgb\" or\n  // - pixel_type not specified and\n  //   - bit depth is not 8 or 16 (cannot have packed rgb representation) or\n  //   - any of the input clips is planar rgb\n\n  if (!lstrcmpi(pixel_type, \"rgb\") ||\n    (empty_pixel_type && (is_any_planar_rgb || (bits_per_pixel != 8 && bits_per_pixel != 16))))\n  {\n    switch (bits_per_pixel) {\n    case 8: vi.pixel_type = alpha ? VideoInfo::CS_RGBAP8 : VideoInfo::CS_RGBP8; break;\n    case 10: vi.pixel_type = alpha ? VideoInfo::CS_RGBAP10 : VideoInfo::CS_RGBP10; break;\n    case 12: vi.pixel_type = alpha ? VideoInfo::CS_RGBAP12 : VideoInfo::CS_RGBP12; break;\n    case 14: vi.pixel_type = alpha ? VideoInfo::CS_RGBAP14 : VideoInfo::CS_RGBP14; break;\n    case 16: vi.pixel_type = alpha ? VideoInfo::CS_RGBAP16 : VideoInfo::CS_RGBP16; break;\n    case 32: vi.pixel_type = alpha ? VideoInfo::CS_RGBAPS : VideoInfo::CS_RGBPS; break;\n    }\n  }\n  else if (empty_pixel_type && vi.BitsPerComponent() == 8) {\n    // default for 8 bit\n    vi.pixel_type = VideoInfo::CS_BGR32;\n  }\n  else if (empty_pixel_type && vi.BitsPerComponent() == 16) {\n    // default for 16 bit\n    vi.pixel_type = VideoInfo::CS_BGR64;\n  }\n  else {\n    // explicitely given output pixel type\n\n    // first try\n    // Append bit depth and check\n    std::string format = pixel_type;\n    // RGBP --> RGBPS, Y -> Y16, YUV420 -> YUV420P10\n    if (!lstrcmpi(pixel_type, \"y\")) {\n      format = format + std::to_string(bits_per_pixel); // Y8..Y16, also Y32\n    }\n    else if (!lstrcmpi(pixel_type, \"rgbp\") || !lstrcmpi(pixel_type, \"rgbap\")) {\n      if (bits_per_pixel == 32)\n        format = format + \"S\"; // RGBAPS\n      else\n        format = format + std::to_string(bits_per_pixel); // RGBP16\n    }\n    else {\n      // hopefully like \"yuv420\" or \"yuva444\"\n      if (bits_per_pixel == 32)\n        format = format + \"PS\"; // YUV420PS\n      else\n        format = format + \"P\" + std::to_string(bits_per_pixel); // YUV420P16\n    }\n\n    int new_pixel_type = GetPixelTypeFromName(format.c_str());\n    if (new_pixel_type == VideoInfo::CS_UNKNOWN) {\n      new_pixel_type = GetPixelTypeFromName(pixel_type);\n      if (new_pixel_type == VideoInfo::CS_UNKNOWN)\n        env->ThrowError(\"%s: invalid pixel_type!\", myname);\n    }\n    // new output format\n    vi.pixel_type = new_pixel_type;\n  }\n\n  if (vi.BitsPerComponent() != bits_per_pixel)\n    env->ThrowError(\"%s: target bit depth (%d) must match with sources (%d)\", myname, vi.BitsPerComponent(), bits_per_pixel);\n\n  if (!vi.IsRGB())\n    env->ThrowError(\"%s: target format must be an RGB format\", myname);\n\n  if(alpha && vi.NumComponents() != 4)\n    env->ThrowError(\"MergeARGB: target format must have an alpha channel\");\n\n  // When not in ARGB mode, target is still allowed to have an alpha channel.\n  // If no alpha source is given, target alpha will be filled by default 0 value.\n\n  if (alpha && (viA.IsRGB24() || viA.IsRGB48() || viA.IsPlanarRGB()))\n    env->ThrowError(\"MergeARGB: Alpha source channel cannot be obtained from RGB24, RGB48 or alphaless planar RGB\");\n}\n\n\nPVideoFrame MergeRGB::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame B = blue->GetFrame(n, env);\n  PVideoFrame G = green->GetFrame(n, env);\n  PVideoFrame R = red->GetFrame(n, env);\n  PVideoFrame A = (alpha) ? alpha->GetFrame(n, env) : 0;\n\n  // choose one for frame property source: R\n  PVideoFrame dst = env->NewVideoFrameP(vi, &R);\n\n  auto props = env->getFramePropsRW(dst);\n  if (!viR.IsRGB()) {\n    // delete _Matrix and ChromaLocation when source is not RGB\n    env->propDeleteKey(props, \"_Matrix\");\n    env->propDeleteKey(props, \"_ChromaLocation\");\n  }\n\n  const int pixelsize = viR.ComponentSize();\n\n  if (!vi.IsPlanar()) {\n    // target is packed RGB\n    const int height = dst->GetHeight();\n    const int pitch = dst->GetPitch();\n    const int rowsize = dst->GetRowSize();\n    const int modulo = pitch - rowsize;\n\n    BYTE* dstp = dst->GetWritePtr();\n\n\n    int planeB = viB.IsPlanar() && viB.IsRGB() ? PLANAR_B : vi.IsRGB() ? 0 : PLANAR_Y;\n    int planeG = viG.IsPlanar() && viG.IsRGB() ? PLANAR_G : vi.IsRGB() ? 0 : PLANAR_Y;\n    int planeR = viR.IsPlanar() && viR.IsRGB() ? PLANAR_R : vi.IsRGB() ? 0 : PLANAR_Y;\n    int planeA = viA.IsPlanar() && viA.IsRGB() ? PLANAR_A : vi.IsRGB() ? 0 : PLANAR_Y;\n\n    // RGB is upside-down, backscan any Planar to match\n    const int Bpitch = (viB.IsPlanar()) ? -(B->GetPitch(planeB)) : B->GetPitch();\n    const int Gpitch = (viG.IsPlanar()) ? -(G->GetPitch(planeG)) : G->GetPitch();\n    const int Rpitch = (viR.IsPlanar()) ? -(R->GetPitch(planeR)) : R->GetPitch();\n\n    // Bump any RGB channels, move any YUV channels to last line\n    const BYTE* Bp = B->GetReadPtr(planeB) + (viB.IsPlanar() ? Bpitch * (1 - height) : 0);\n    const BYTE* Gp = G->GetReadPtr(planeG) + (viG.IsPlanar() ? Gpitch * (1 - height) : (1 * pixelsize));\n    const BYTE* Rp = R->GetReadPtr(planeR) + (viR.IsPlanar() ? Rpitch * (1 - height) : (2 * pixelsize));\n\n    // Adjustment from the end of 1 line to the start of the next\n    const int Bmodulo = Bpitch - B->GetRowSize(planeB);\n    const int Gmodulo = Gpitch - G->GetRowSize(planeG);\n    const int Rmodulo = Rpitch - R->GetRowSize(planeR);\n\n    // Number of bytes per pixel (1, 2, 3 or 4 .. 8)\n    const int Bstride = viB.IsPlanar() ? pixelsize : (viB.BitsPerPixel() >> 3);\n    const int Gstride = viG.IsPlanar() ? pixelsize : (viG.BitsPerPixel() >> 3);\n    const int Rstride = viR.IsPlanar() ? pixelsize : (viR.BitsPerPixel() >> 3);\n\n    // End of VFB\n    BYTE const* yend = dstp + pitch * height;\n\n    if (alpha) { // ARGB mode\n      const int Apitch = (viA.IsPlanar()) ? -(A->GetPitch(planeA)) : A->GetPitch();\n      const BYTE* Ap = A->GetReadPtr(planeA) + (viA.IsPlanar() ? Apitch * (1 - height) : (3 * pixelsize));\n      const int Amodulo = Apitch - A->GetRowSize(planeA);\n      const int Astride = viA.IsPlanar() ? pixelsize : (viA.BitsPerPixel() >> 3);\n\n      switch (pixelsize) {\n      case 1:\n        while (dstp < yend) {\n          BYTE const* xend = dstp + rowsize;\n          while (dstp < xend) {\n            *dstp++ = *Bp; Bp += Bstride;\n            *dstp++ = *Gp; Gp += Gstride;\n            *dstp++ = *Rp; Rp += Rstride;\n            *dstp++ = *Ap; Ap += Astride;\n          }\n          dstp += modulo;\n          Bp += Bmodulo;\n          Gp += Gmodulo;\n          Rp += Rmodulo;\n          Ap += Amodulo;\n        }\n        break;\n      case 2:\n      {\n        uint16_t* dstp16 = reinterpret_cast<uint16_t*>(dstp);\n        uint16_t const* yend16 = dstp16 + pitch * height / sizeof(uint16_t);\n        while (dstp16 < yend16) {\n          uint16_t const* xend16 = dstp16 + rowsize / sizeof(uint16_t);\n          while (dstp16 < xend16) {\n            *dstp16++ = *reinterpret_cast<const uint16_t*>(Bp); Bp += Bstride;\n            *dstp16++ = *reinterpret_cast<const uint16_t*>(Gp); Gp += Gstride;\n            *dstp16++ = *reinterpret_cast<const uint16_t*>(Rp); Rp += Rstride;\n            *dstp16++ = *reinterpret_cast<const uint16_t*>(Ap); Ap += Astride;\n          }\n          dstp16 += modulo / sizeof(uint16_t);\n          Bp += Bmodulo;\n          Gp += Gmodulo;\n          Rp += Rmodulo;\n          Ap += Amodulo;\n        }\n      }\n      break;\n      default:\n        env->ThrowError(\"%s: float pixel type not supported\", myname);\n        break;\n      }\n    }\n    else if (vi.pixel_type == VideoInfo::CS_BGR32 || vi.pixel_type == VideoInfo::CS_BGR64) { // RGB32 mode\n      switch (pixelsize) {\n      case 1:\n        while (dstp < yend) {\n          BYTE const* xend = dstp + rowsize;\n          while (dstp < xend) {\n            *dstp++ = *Bp; Bp += Bstride;\n            *dstp++ = *Gp; Gp += Gstride;\n            *dstp++ = *Rp; Rp += Rstride;\n            *dstp++ = 0; // default Alpha is 0!\n          }\n          dstp += modulo;\n          Bp += Bmodulo;\n          Gp += Gmodulo;\n          Rp += Rmodulo;\n        }\n        break;\n      case 2:\n      {\n        uint16_t* dstp16 = reinterpret_cast<uint16_t*>(dstp);\n        uint16_t const* yend16 = dstp16 + pitch * height / sizeof(uint16_t);\n        while (dstp16 < yend16) {\n          uint16_t const* xend16 = dstp16 + rowsize / sizeof(uint16_t);\n          while (dstp16 < xend16) {\n            *dstp16++ = *reinterpret_cast<const uint16_t*>(Bp); Bp += Bstride;\n            *dstp16++ = *reinterpret_cast<const uint16_t*>(Gp); Gp += Gstride;\n            *dstp16++ = *reinterpret_cast<const uint16_t*>(Rp); Rp += Rstride;\n            *dstp16++ = 0; // default Alpha is 0!\n          }\n          dstp16 += modulo / sizeof(uint16_t);\n          Bp += Bmodulo;\n          Gp += Gmodulo;\n          Rp += Rmodulo;\n        }\n      }\n      break;\n      default:\n        env->ThrowError(\"%s: float pixel type not supported\", myname);\n        break;\n      }\n    }\n    else if (vi.pixel_type == VideoInfo::CS_BGR24 || vi.pixel_type == VideoInfo::CS_BGR48) { // RGB24 mode\n      switch (pixelsize) {\n      case 1:\n        while (dstp < yend) {\n          BYTE const* xend = dstp + rowsize;\n          while (dstp < xend) {\n            *dstp++ = *Bp; Bp += Bstride;\n            *dstp++ = *Gp; Gp += Gstride;\n            *dstp++ = *Rp; Rp += Rstride;\n          }\n          dstp += modulo;\n          Bp += Bmodulo;\n          Gp += Gmodulo;\n          Rp += Rmodulo;\n        }\n        break;\n      case 2:\n      {\n        uint16_t* dstp16 = reinterpret_cast<uint16_t*>(dstp);\n        uint16_t const* yend16 = dstp16 + pitch * height / sizeof(uint16_t);\n        while (dstp16 < yend16) {\n          uint16_t const* xend16 = dstp16 + rowsize / sizeof(uint16_t);\n          while (dstp16 < xend16) {\n            *dstp16++ = *reinterpret_cast<const uint16_t*>(Bp); Bp += Bstride;\n            *dstp16++ = *reinterpret_cast<const uint16_t*>(Gp); Gp += Gstride;\n            *dstp16++ = *reinterpret_cast<const uint16_t*>(Rp); Rp += Rstride;\n          }\n          dstp16 += modulo / sizeof(uint16_t);\n          Bp += Bmodulo;\n          Gp += Gmodulo;\n          Rp += Rmodulo;\n        }\n      }\n      break;\n      default:\n        env->ThrowError(\"%s: float pixel type not supported\", myname);\n        break;\n      }\n    }\n    else\n      env->ThrowError(\"%s: unexpected end of function\", myname);\n\n    return dst;\n  }\n\n  // target is planar RGB\n  for (int p = 0; p < vi.NumComponents(); p++) {\n    int planes_r[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A };\n    const int plane = planes_r[p];\n\n    const VideoInfo& vi_src =\n      plane == PLANAR_G ? viG :\n      plane == PLANAR_B ? viB :\n      plane == PLANAR_R ? viR : viA;\n\n    PVideoFrame& src =\n      plane == PLANAR_G ? G :\n      plane == PLANAR_B ? B :\n      plane == PLANAR_R ? R : A;\n\n    // actual plane source is not a packed RGB type\n\n    if (p == 3 && !alpha) {\n      // fill alpha, but not ARGB mode\n\n      const int dst_rowsizeA = dst->GetRowSize(PLANAR_A);\n      const int dst_pitchA = dst->GetPitch(PLANAR_A);\n      BYTE* dstp_a = dst->GetWritePtr(PLANAR_A);\n      const int heightA = dst->GetHeight(PLANAR_A);\n      // unlike in other filters, default alpha value here is 0 instead of max transparent 255\n      switch (vi.ComponentSize())\n      {\n      case 1:\n        fill_plane<uint8_t>(dstp_a, heightA, dst_rowsizeA, dst_pitchA, 0);\n        break;\n      case 2:\n        fill_plane<uint16_t>(dstp_a, heightA, dst_rowsizeA, dst_pitchA, 0);\n        break;\n      case 4:\n        fill_plane<float>(dstp_a, heightA, dst_rowsizeA, dst_pitchA, 0.0f);\n        break;\n      }\n    }\n    else {\n      if (vi_src.IsPlanar())\n      {\n        // plane copy\n        const int plane_src = vi_src.IsRGB() ? plane : PLANAR_Y;\n        env->BitBlt(dst->GetWritePtr(plane), dst->GetPitch(plane), src->GetReadPtr(plane_src),\n          src->GetPitch(plane_src), src->GetRowSize(plane_src), src->GetHeight(plane_src));\n      }\n      else {\n        // fill a plane from packed RGB\n        // packed RGB -> Y, YUV(A)\n        BYTE* dstp = dst->GetWritePtr(plane);\n        int dstpitch = dst->GetPitch(plane);\n\n\n        const BYTE* srcp = src->GetReadPtr();\n        const int pitch = src->GetPitch();\n        const int packed_rgb_channel =\n          plane == PLANAR_G ? 1 :\n          plane == PLANAR_B ? 0 :\n          plane == PLANAR_R ? 2 : 3;\n\n        if (pixelsize == 1) {\n          if (vi_src.NumComponents() == 3)\n            packed_to_luma_alpha<uint8_t, false, false>(dstp, nullptr, dstpitch, srcp, pitch, vi.width, vi.height, packed_rgb_channel);\n          else\n            packed_to_luma_alpha<uint8_t, true, false>(dstp, nullptr, dstpitch, srcp, pitch, vi.width, vi.height, packed_rgb_channel);\n        }\n        else {\n          if (vi_src.NumComponents() == 3)\n            packed_to_luma_alpha<uint16_t, false, false>(dstp, nullptr, dstpitch, srcp, pitch, vi.width, vi.height, packed_rgb_channel);\n          else\n            packed_to_luma_alpha<uint16_t, true, false>(dstp, nullptr, dstpitch, srcp, pitch, vi.width, vi.height, packed_rgb_channel);\n        }\n      }\n    }\n  }\n  return dst;\n}\n\n\nAVSValue MergeRGB::Create(AVSValue args, void* mode, IScriptEnvironment* env)\n{\n  if (mode) // ARGB\n    return new MergeRGB(args[0].AsClip(), args[3].AsClip(), args[2].AsClip(), args[1].AsClip(), args[0].AsClip(), args[4].AsString(\"\"), env);\n  else      // RGB[type]\n    return new MergeRGB(args[0].AsClip(), args[2].AsClip(), args[1].AsClip(), args[0].AsClip(), 0, args[3].AsString(\"\"), env);\n}\n\n\n/*******************************\n *******   Layer Filter   ******\n *******************************/\n\n// YUY2 in pre- and post-converted to YV16. No YUY2 here.\nLayer::Layer(PClip _child1, PClip _child2, const char _op[], int _lev, int _x, int _y,\n  int _t, bool _chroma, float _opacity, int _placement, IScriptEnvironment* env)\n  : child1(_child1), child2(_child2), Op(_op), levelB(_lev), ofsX(_x), ofsY(_y),\n  chroma(_chroma), opacity(_opacity), placement(_placement)\n{\n  const VideoInfo& vi1 = child1->GetVideoInfo();\n  const VideoInfo& vi2 = child2->GetVideoInfo();\n\n  if (vi1.pixel_type != vi2.pixel_type && !vi1.IsSameColorspace(vi2)) // i420 and YV12 are matched OK\n    env->ThrowError(\"Layer: image formats don't match\");\n\n  vi = vi1;\n\n  hasAlpha = vi.IsRGB32() || vi.IsRGB64() || vi.IsYUVA() || vi.IsPlanarRGBA();\n  bits_per_pixel = vi.BitsPerComponent();\n\n  const bool levelSpecified = levelB >= 0;\n  const bool strengthSpecified = opacity >= 0.0f;\n\n  if (levelSpecified && strengthSpecified)\n    env->ThrowError(\"Layer: cannot specify both level and opacity\");\n  if (levelSpecified && bits_per_pixel == 32)\n    env->ThrowError(\"Layer: cannot specify level for 32 bit float format\");\n\n  if (levelSpecified)\n  {\n    if (hasAlpha)\n      opacity = (float)levelB / ((1 << bits_per_pixel) + 1); // gives 1.0f for 257 (@8bit) and 65537 (@16 bits)\n      // originally levelB was used in formula: (alpha*level + 1) / range_size,\n      // now level is calculated from opacity as: level = opacity * ((1 << bits_per_pixel) + 1)\n    else\n      opacity = (float)levelB / ((1 << bits_per_pixel)); // YUY2 or other non-Alpha, gives 1.0f for 256 (@8bit)\n    // we'll calculate back the level as: level = opacity * ((1 << bits_per_pixel))\n  }\n  else if (!strengthSpecified)\n    opacity = 1.0f;\n\n  if (vi.IsRGB32() || vi.IsRGB64() || vi.IsRGB24() || vi.IsRGB48())\n    ofsY = vi.height - vi2.height - ofsY; // packed RGB is upside down\n  else if ((vi.IsYUV() || vi.IsYUVA()) && !vi.IsY()) {\n    // make offsets subsampling friendly\n    ofsX = ofsX & ~((1 << vi.GetPlaneWidthSubsampling(PLANAR_U)) - 1);\n    ofsY = ofsY & ~((1 << vi.GetPlaneHeightSubsampling(PLANAR_U)) - 1);\n  }\n\n  xdest = (ofsX < 0) ? 0 : ofsX;\n  ydest = (ofsY < 0) ? 0 : ofsY;\n\n  xsrc = (ofsX < 0) ? (0 - ofsX) : 0;\n  ysrc = (ofsY < 0) ? (0 - ofsY) : 0;\n\n  xcount = (vi.width < (ofsX + vi2.width)) ? (vi.width - xdest) : (vi2.width - xsrc);\n  ycount = (vi.height < (ofsY + vi2.height)) ? (vi.height - ydest) : (vi2.height - ysrc);\n\n  if (!(!lstrcmpi(Op, \"Mul\") || !lstrcmpi(Op, \"Add\") || !lstrcmpi(Op, \"Fast\") ||\n    !lstrcmpi(Op, \"Subtract\") || !lstrcmpi(Op, \"Lighten\") || !lstrcmpi(Op, \"Darken\")))\n    env->ThrowError(\"Layer supports the following ops: Fast, Lighten, Darken, Add, Subtract, Mul\");\n\n  if (!chroma)\n  {\n    if (!lstrcmpi(Op, \"Darken\")) env->ThrowError(\"Layer: monochrome darken illegal op\");\n    if (!lstrcmpi(Op, \"Lighten\")) env->ThrowError(\"Layer: monochrome lighten illegal op\");\n    if (!lstrcmpi(Op, \"Fast\")) env->ThrowError(\"Layer: this mode not allowed in FAST; use ADD instead\");\n  }\n\n  // autoscale ThresholdParam from 8 bit base\n  // todo check validity\n  if (bits_per_pixel == 32)\n    ThresholdParam = _t; // n/a\n  else\n    ThresholdParam = _t << (bits_per_pixel - 8);\n  ThresholdParam_f = _t / 255.0f;\n\n  overlay_frames = vi2.num_frames;\n}\n\n\n// simple averaging\ntemplate<typename pixel_t>\nstatic void layer_genericplane_fast_c(BYTE* dstp8, const BYTE* ovrp8, int dst_pitch, int overlay_pitch, int width, int height, int level) {\n  AVS_UNUSED(level);\n  pixel_t* dstp = reinterpret_cast<pixel_t*>(dstp8);\n  const pixel_t* ovrp = reinterpret_cast<const pixel_t*>(ovrp8);\n  dst_pitch /= sizeof(pixel_t);\n  overlay_pitch /= sizeof(pixel_t);\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; ++x) {\n      dstp[x] = (dstp[x] + ovrp[x] + 1) / 2;\n    }\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n  }\n}\n\nstatic void layer_genericplane_fast_f_c(BYTE* dstp8, const BYTE* ovrp8, int dst_pitch, int overlay_pitch, int width, int height, float level) {\n  AVS_UNUSED(level);\n  float* dstp = reinterpret_cast<float*>(dstp8);\n  const float* ovrp = reinterpret_cast<const float*>(ovrp8);\n  dst_pitch /= sizeof(float);\n  overlay_pitch /= sizeof(float);\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; ++x) {\n      dstp[x] = (dstp[x] + ovrp[x]) * 0.5f;\n    }\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n  }\n}\n\n/* RGB32 */\n\n// For Full Strength: 8 bit Level must be 257, 16 bit must be 65537!\n// in 8 bit:   (255*257+1)/256 = (65535+1)/256 = 256 -> alpha_max = 256\n// in 16 bit:  (65535*65537+1)/65536 = 65536, x=? 7FFFFFFF, x=65537 -> alpha_max = 65536\n\ntemplate<typename pixel_t>\nstatic void layer_rgb32_mul_chroma_c(BYTE* dstp8, const BYTE* ovrp8, int dst_pitch, int overlay_pitch, int width, int height, int level) {\n  pixel_t* dstp = reinterpret_cast<pixel_t*>(dstp8);\n  const pixel_t* ovrp = reinterpret_cast<const pixel_t*>(ovrp8);\n  dst_pitch /= sizeof(pixel_t);\n  overlay_pitch /= sizeof(pixel_t);\n  const int SHIFT = sizeof(pixel_t) == 1 ? 8 : 16;\n\n  typedef typename std::conditional < sizeof(pixel_t) == 1, int, int64_t>::type calc_t;\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; ++x) {\n      calc_t alpha = ((calc_t)ovrp[x * 4 + 3] * level + 1) >> SHIFT;\n\n      dstp[x * 4 + 0] = (pixel_t)(dstp[x * 4 + 0] + ((((((calc_t)ovrp[x * 4 + 0] * dstp[x * 4 + 0]) >> SHIFT) - dstp[x * 4 + 0]) * alpha) >> SHIFT));\n      dstp[x * 4 + 1] = (pixel_t)(dstp[x * 4 + 1] + ((((((calc_t)ovrp[x * 4 + 1] * dstp[x * 4 + 1]) >> SHIFT) - dstp[x * 4 + 1]) * alpha) >> SHIFT));\n      dstp[x * 4 + 2] = (pixel_t)(dstp[x * 4 + 2] + ((((((calc_t)ovrp[x * 4 + 2] * dstp[x * 4 + 2]) >> SHIFT) - dstp[x * 4 + 2]) * alpha) >> SHIFT));\n      dstp[x * 4 + 3] = (pixel_t)(dstp[x * 4 + 3] + ((((((calc_t)ovrp[x * 4 + 3] * dstp[x * 4 + 3]) >> SHIFT) - dstp[x * 4 + 3]) * alpha) >> SHIFT));\n    }\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n  }\n}\n\ntemplate<typename pixel_t>\nstatic void layer_rgb32_mul_c(BYTE* dstp8, const BYTE* ovrp8, int dst_pitch, int overlay_pitch, int width, int height, int level) {\n  pixel_t* dstp = reinterpret_cast<pixel_t*>(dstp8);\n  const pixel_t* ovrp = reinterpret_cast<const pixel_t*>(ovrp8);\n  dst_pitch /= sizeof(pixel_t);\n  overlay_pitch /= sizeof(pixel_t);\n  const int SHIFT = sizeof(pixel_t) == 1 ? 8 : 16;\n\n  typedef typename std::conditional < sizeof(pixel_t) == 1, int, int64_t>::type calc_t;\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; ++x) {\n      calc_t alpha = ((calc_t)ovrp[x * 4 + 3] * level + 1) >> SHIFT;\n      calc_t luma = (cyb * ovrp[x * 4] + cyg * ovrp[x * 4 + 1] + cyr * ovrp[x * 4 + 2]) >> 15;\n\n      dstp[x * 4 + 0] = (pixel_t)(dstp[x * 4 + 0] + (((((luma * dstp[x * 4 + 0]) >> SHIFT) - dstp[x * 4 + 0]) * alpha) >> SHIFT));\n      dstp[x * 4 + 1] = (pixel_t)(dstp[x * 4 + 1] + (((((luma * dstp[x * 4 + 1]) >> SHIFT) - dstp[x * 4 + 1]) * alpha) >> SHIFT));\n      dstp[x * 4 + 2] = (pixel_t)(dstp[x * 4 + 2] + (((((luma * dstp[x * 4 + 2]) >> SHIFT) - dstp[x * 4 + 2]) * alpha) >> SHIFT));\n      dstp[x * 4 + 3] = (pixel_t)(dstp[x * 4 + 3] + (((((luma * dstp[x * 4 + 3]) >> SHIFT) - dstp[x * 4 + 3]) * alpha) >> SHIFT));\n    }\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n  }\n}\n\n\ntemplate<typename pixel_t>\nstatic void layer_rgb32_add_chroma_c(BYTE* dstp8, const BYTE* ovrp8, int dst_pitch, int overlay_pitch, int width, int height, int level) {\n  pixel_t* dstp = reinterpret_cast<pixel_t*>(dstp8);\n  const pixel_t* ovrp = reinterpret_cast<const pixel_t*>(ovrp8);\n  dst_pitch /= sizeof(pixel_t);\n  overlay_pitch /= sizeof(pixel_t);\n  const int SHIFT = sizeof(pixel_t) == 1 ? 8 : 16;\n\n  typedef typename std::conditional < sizeof(pixel_t) == 1, int, int64_t>::type calc_t;\n\n  constexpr int rounder = sizeof(pixel_t) == 1 ? 128 : 32768;\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; ++x) {\n      calc_t alpha = ((calc_t)ovrp[x * 4 + 3] * level + 1) >> SHIFT;\n\n      dstp[x * 4] = (pixel_t)(dstp[x * 4] + ((((calc_t)ovrp[x * 4] - dstp[x * 4]) * alpha + rounder) >> SHIFT));\n      dstp[x * 4 + 1] = (pixel_t)(dstp[x * 4 + 1] + ((((calc_t)ovrp[x * 4 + 1] - dstp[x * 4 + 1]) * alpha + rounder) >> SHIFT));\n      dstp[x * 4 + 2] = (pixel_t)(dstp[x * 4 + 2] + ((((calc_t)ovrp[x * 4 + 2] - dstp[x * 4 + 2]) * alpha + rounder) >> SHIFT));\n      dstp[x * 4 + 3] = (pixel_t)(dstp[x * 4 + 3] + ((((calc_t)ovrp[x * 4 + 3] - dstp[x * 4 + 3]) * alpha + rounder) >> SHIFT));\n    }\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n  }\n}\n\ntemplate<typename pixel_t>\nstatic void layer_rgb32_add_c(BYTE* dstp8, const BYTE* ovrp8, int dst_pitch, int overlay_pitch, int width, int height, int level) {\n  pixel_t* dstp = reinterpret_cast<pixel_t*>(dstp8);\n  const pixel_t* ovrp = reinterpret_cast<const pixel_t*>(ovrp8);\n  dst_pitch /= sizeof(pixel_t);\n  overlay_pitch /= sizeof(pixel_t);\n  const int SHIFT = sizeof(pixel_t) == 1 ? 8 : 16;\n\n  typedef typename std::conditional < sizeof(pixel_t) == 1, int, int64_t>::type calc_t;\n\n  constexpr int rounder = sizeof(pixel_t) == 1 ? 128 : 32768;\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; ++x) {\n      calc_t alpha = ((calc_t)ovrp[x * 4 + 3] * level + 1) >> SHIFT;\n      calc_t luma = (cyb * ovrp[x * 4] + cyg * ovrp[x * 4 + 1] + cyr * ovrp[x * 4 + 2]) >> 15;\n\n      dstp[x * 4] = (pixel_t)(dstp[x * 4] + (((luma - dstp[x * 4]) * alpha + rounder) >> SHIFT));\n      dstp[x * 4 + 1] = (pixel_t)(dstp[x * 4 + 1] + (((luma - dstp[x * 4 + 1]) * alpha + rounder) >> SHIFT));\n      dstp[x * 4 + 2] = (pixel_t)(dstp[x * 4 + 2] + (((luma - dstp[x * 4 + 2]) * alpha + rounder) >> SHIFT));\n      dstp[x * 4 + 3] = (pixel_t)(dstp[x * 4 + 3] + (((luma - dstp[x * 4 + 3]) * alpha + rounder) >> SHIFT));\n    }\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n  }\n}\n\n\n\ntemplate<typename pixel_t>\nstatic void layer_rgb32_fast_c(BYTE* dstp, const BYTE* ovrp, int dst_pitch, int overlay_pitch, int width, int height, int level) {\n  layer_genericplane_fast_c<pixel_t>(dstp, ovrp, dst_pitch, overlay_pitch, width * 4, height, level);\n}\n\n\ntemplate<typename pixel_t>\nstatic void layer_rgb32_subtract_chroma_c(BYTE* dstp8, const BYTE* ovrp8, int dst_pitch, int overlay_pitch, int width, int height, int level) {\n  pixel_t* dstp = reinterpret_cast<pixel_t*>(dstp8);\n  const pixel_t* ovrp = reinterpret_cast<const pixel_t*>(ovrp8);\n  dst_pitch /= sizeof(pixel_t);\n  overlay_pitch /= sizeof(pixel_t);\n  const int SHIFT = sizeof(pixel_t) == 1 ? 8 : 16;\n\n  typedef typename std::conditional < sizeof(pixel_t) == 1, int, int64_t>::type calc_t;\n\n  const calc_t MAX_PIXEL_VALUE = sizeof(pixel_t) == 1 ? 255 : 65535;\n  constexpr int rounder = sizeof(pixel_t) == 1 ? 128 : 32768;\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; ++x) {\n      calc_t alpha = ((calc_t)ovrp[x * 4 + 3] * level + 1) >> SHIFT;\n\n      dstp[x * 4] = (pixel_t)(dstp[x * 4] + (((MAX_PIXEL_VALUE - ovrp[x * 4] - dstp[x * 4]) * alpha + rounder) >> SHIFT));\n      dstp[x * 4 + 1] = (pixel_t)(dstp[x * 4 + 1] + (((MAX_PIXEL_VALUE - ovrp[x * 4 + 1] - dstp[x * 4 + 1]) * alpha + rounder) >> SHIFT));\n      dstp[x * 4 + 2] = (pixel_t)(dstp[x * 4 + 2] + (((MAX_PIXEL_VALUE - ovrp[x * 4 + 2] - dstp[x * 4 + 2]) * alpha + rounder) >> SHIFT));\n      dstp[x * 4 + 3] = (pixel_t)(dstp[x * 4 + 3] + (((MAX_PIXEL_VALUE - ovrp[x * 4 + 3] - dstp[x * 4 + 3]) * alpha + rounder) >> SHIFT));\n    }\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n  }\n}\n\ntemplate<typename pixel_t>\nstatic void layer_rgb32_subtract_c(BYTE* dstp8, const BYTE* ovrp8, int dst_pitch, int overlay_pitch, int width, int height, int level) {\n  pixel_t* dstp = reinterpret_cast<pixel_t*>(dstp8);\n  const pixel_t* ovrp = reinterpret_cast<const pixel_t*>(ovrp8);\n  dst_pitch /= sizeof(pixel_t);\n  overlay_pitch /= sizeof(pixel_t);\n  const int SHIFT = sizeof(pixel_t) == 1 ? 8 : 16;\n\n  typedef typename std::conditional < sizeof(pixel_t) == 1, int, int64_t>::type calc_t;\n\n  const calc_t MAX_PIXEL_VALUE = sizeof(pixel_t) == 1 ? 255 : 65535;\n  constexpr int rounder = sizeof(pixel_t) == 1 ? 128 : 32768;\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; ++x) {\n      calc_t alpha = ((calc_t)ovrp[x * 4 + 3] * level + 1) >> SHIFT;\n      calc_t luma = (cyb * (MAX_PIXEL_VALUE - ovrp[x * 4]) + cyg * (MAX_PIXEL_VALUE - ovrp[x * 4 + 1]) + cyr * (MAX_PIXEL_VALUE - ovrp[x * 4 + 2])) >> 15;\n\n      dstp[x * 4] = (pixel_t)(dstp[x * 4] + (((luma - dstp[x * 4]) * alpha + rounder) >> SHIFT));\n      dstp[x * 4 + 1] = (pixel_t)(dstp[x * 4 + 1] + (((luma - dstp[x * 4 + 1]) * alpha + rounder) >> SHIFT));\n      dstp[x * 4 + 2] = (pixel_t)(dstp[x * 4 + 2] + (((luma - dstp[x * 4 + 2]) * alpha + rounder) >> SHIFT));\n      dstp[x * 4 + 3] = (pixel_t)(dstp[x * 4 + 3] + (((luma - dstp[x * 4 + 3]) * alpha + rounder) >> SHIFT));\n    }\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n  }\n}\n\n\ntemplate<int mode, typename pixel_t>\nstatic void layer_rgb32_lighten_darken_c(BYTE* dstp8, const BYTE* ovrp8, int dst_pitch, int overlay_pitch, int width, int height, int level, int thresh) {\n  pixel_t* dstp = reinterpret_cast<pixel_t*>(dstp8);\n  const pixel_t* ovrp = reinterpret_cast<const pixel_t*>(ovrp8);\n  dst_pitch /= sizeof(pixel_t);\n  overlay_pitch /= sizeof(pixel_t);\n  const int SHIFT = sizeof(pixel_t) == 1 ? 8 : 16;\n\n  typedef typename std::conditional < sizeof(pixel_t) == 1, int, int64_t>::type calc_t;\n\n  constexpr int rounder = sizeof(pixel_t) == 1 ? 128 : 32768;\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; ++x) {\n      calc_t alpha = ((calc_t)ovrp[x * 4 + 3] * level + 1) >> SHIFT;\n      int luma_ovr = (cyb * ovrp[x * 4] + cyg * ovrp[x * 4 + 1] + cyr * ovrp[x * 4 + 2]) >> 15;\n      int luma_src = (cyb * dstp[x * 4] + cyg * dstp[x * 4 + 1] + cyr * dstp[x * 4 + 2]) >> 15;\n\n      if constexpr (mode == LIGHTEN)\n        alpha = luma_ovr > luma_src + thresh ? alpha : 0;\n      else // DARKEN\n        alpha = luma_ovr < luma_src - thresh ? alpha : 0;\n\n      dstp[x * 4] = (pixel_t)(dstp[x * 4] + ((((calc_t)ovrp[x * 4] - dstp[x * 4]) * alpha + rounder) >> SHIFT));\n      dstp[x * 4 + 1] = (pixel_t)(dstp[x * 4 + 1] + ((((calc_t)ovrp[x * 4 + 1] - dstp[x * 4 + 1]) * alpha + rounder) >> SHIFT));\n      dstp[x * 4 + 2] = (pixel_t)(dstp[x * 4 + 2] + ((((calc_t)ovrp[x * 4 + 2] - dstp[x * 4 + 2]) * alpha + rounder) >> SHIFT));\n      dstp[x * 4 + 3] = (pixel_t)(dstp[x * 4 + 3] + ((((calc_t)ovrp[x * 4 + 3] - dstp[x * 4 + 3]) * alpha + rounder) >> SHIFT));\n    }\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n  }\n}\n\n\n// chroma placement to mask helpers\n// yuv add, subtract, mul, lighten, darken\n// included in base and the avx2 source module, to get different optimizations\n#include \"layer.hpp\"\n\n\n\nPVideoFrame __stdcall Layer::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame src1 = child1->GetFrame(n, env);\n\n  if (xcount <= 0 || ycount <= 0) return src1;\n\n  PVideoFrame src2 = child2->GetFrame(min(n, overlay_frames - 1), env);\n\n  env->MakeWritable(&src1);\n\n  const int mylevel = hasAlpha ? (int)(opacity * ((1 << bits_per_pixel) + 1) + 0.5f) : (int)(opacity * (1 << bits_per_pixel) + 0.5f);\n  // Alpha mode: opacity of 1.0f gives 257 (@8bit) and 65537 (@16 bits), used in (alpha*level + 1) / range_size,\n  // non-Alpha mode: 1.0f gives 256 (@8bit)\n\n  const int height = ycount; // these may be divided by subsampling factor\n  const int width = xcount;\n\n  if (vi.IsRGB32() || vi.IsRGB64())\n  {\n    const int src1_pitch = src1->GetPitch();\n    const int src2_pitch = src2->GetPitch();\n    BYTE* src1p = src1->GetWritePtr();\n    const BYTE* src2p = src2->GetReadPtr();\n\n    int rgb_step = vi.BytesFromPixels(1); // 4 or 8 bytes/pixelgroup\n    int pixelsize = vi.ComponentSize();\n\n    src1p += (src1_pitch * ydest) + (xdest * rgb_step);\n    src2p += (src2_pitch * ysrc) + (xsrc * rgb_step);\n\n    // note: ThresholdParam is not scaled automatically\n    int thresh = std::max(0, std::min(ThresholdParam, (1 << bits_per_pixel) - 1)); // limit threshold, old method was: & 0xFF\n\n    if (!lstrcmpi(Op, \"Mul\"))\n    {\n      if (chroma)\n      {\n#ifdef INTEL_INTRINSICS\n        if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_AVX2))\n        {\n          layer_rgb32_mul_avx2<true>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n        }\n        else if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_SSE2))\n        {\n          layer_rgb32_mul_sse2<true>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n        }\n#ifdef X86_32\n        else if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_INTEGER_SSE))\n        {\n          layer_rgb32_mul_isse<true>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n        }\n#endif\n        else\n#endif\n        {\n          if (pixelsize == 1)\n            layer_rgb32_mul_chroma_c<uint8_t>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n          else\n            layer_rgb32_mul_chroma_c<uint16_t>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n        }\n      }\n      else // Mul, chroma==false\n      {\n#ifdef INTEL_INTRINSICS\n        if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_AVX2))\n        {\n          layer_rgb32_mul_avx2<false>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n        }\n        else if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_SSE2))\n        {\n          layer_rgb32_mul_sse2<false>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n        }\n#ifdef X86_32\n        else if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_INTEGER_SSE))\n        {\n          layer_rgb32_mul_isse<false>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n        }\n#endif\n        else\n#endif\n        {\n          if (pixelsize == 1)\n            layer_rgb32_mul_c<uint8_t>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n          else\n            layer_rgb32_mul_c<uint16_t>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n        }\n      }\n    }\n    if (!lstrcmpi(Op, \"Add\"))\n    {\n      // like Overlay \"blend\"\n      // rgb : base = base + ((overlay-base)*(alpha*level + 1)/256)/256\n      // yuy2: base = base + ((overlay-base)*(      level    )/256)/256 (no alpha)\n      if (chroma)\n      {\n#ifdef INTEL_INTRINSICS\n        if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_AVX2))\n        {\n          layer_rgb32_add_avx2<true>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n        }\n        else if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_SSE2))\n        {\n          layer_rgb32_add_sse2<true>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n        }\n#ifdef X86_32\n        else if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_INTEGER_SSE))\n        {\n          layer_rgb32_add_isse<true>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n        }\n#endif\n        else\n#endif\n        {\n          if (pixelsize == 1)\n            layer_rgb32_add_chroma_c<uint8_t>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n          else\n            layer_rgb32_add_chroma_c<uint16_t>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n        }\n      }\n      else // Add, chroma == false\n      {\n#ifdef INTEL_INTRINSICS\n        if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_AVX2))\n        {\n          layer_rgb32_add_avx2<false>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n        }\n        else if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_SSE2))\n        {\n          layer_rgb32_add_sse2<false>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n        }\n#ifdef X86_32\n        else if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_INTEGER_SSE))\n        {\n          layer_rgb32_add_isse<false>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n        }\n#endif\n        else\n#endif\n        {\n          if (pixelsize == 1)\n            layer_rgb32_add_c<uint8_t>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n          else\n            layer_rgb32_add_c<uint16_t>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n        }\n      }\n    }\n    if (!lstrcmpi(Op, \"Lighten\"))\n    {\n      // Copy overlay_clip over base_clip in areas where overlay_clip is lighter by threshold.\n      // only chroma == true\n#ifdef INTEL_INTRINSICS\n      if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_AVX2))\n      {\n        layer_rgb32_lighten_darken_avx2<LIGHTEN>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel, thresh);\n      }\n      else if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_SSE2))\n      {\n        layer_rgb32_lighten_darken_sse2<LIGHTEN>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel, thresh);\n      }\n#ifdef X86_32\n      else if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_INTEGER_SSE))\n      {\n        layer_rgb32_lighten_darken_isse<LIGHTEN>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel, thresh);\n      }\n#endif\n      else\n#endif \n      {\n        if (pixelsize == 1)\n          layer_rgb32_lighten_darken_c<LIGHTEN, uint8_t>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel, thresh);\n        else\n          layer_rgb32_lighten_darken_c<LIGHTEN, uint16_t>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel, thresh);\n      }\n    }\n    if (!lstrcmpi(Op, \"Darken\"))\n    {\n      // Copy overlay_clip over base_clip in areas where overlay_clip is darker by threshold.\n      // only chroma == true\n#ifdef INTEL_INTRINSICS\n      if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_AVX2))\n      {\n        layer_rgb32_lighten_darken_avx2<DARKEN>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel, thresh);\n      }\n      else if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_SSE2))\n      {\n        layer_rgb32_lighten_darken_sse2<DARKEN>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel, thresh);\n      }\n#ifdef X86_32\n      else if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_INTEGER_SSE))\n      {\n        layer_rgb32_lighten_darken_isse<DARKEN>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel, thresh);\n      }\n#endif\n      else\n#endif\n      {\n        if (pixelsize == 1)\n          layer_rgb32_lighten_darken_c<DARKEN, uint8_t>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel, thresh);\n        else\n          layer_rgb32_lighten_darken_c<DARKEN, uint16_t>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel, thresh);\n      }\n    }\n    if (!lstrcmpi(Op, \"Fast\"))\n    {\n      // Like add, but without masking.\n      // use_chroma must be true; level and threshold are not used.\n      // The result is simply the average of base_clip and overlay_clip.\n      // only chroma == true\n#ifdef INTEL_INTRINSICS\n      // yes, alignment check, we can have x offsets\n      // But this avx2 does not require it\n      if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_AVX2))\n      {\n        layer_rgb32_fast_avx2(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n      }\n      else if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_SSE2) && IsPtrAligned(src1p, 16) && IsPtrAligned(src2p, 16))\n      {\n        layer_rgb32_fast_sse2(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n      }\n      else\n#endif\n      {\n        if (pixelsize == 1)\n          layer_rgb32_fast_c<uint8_t>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n        else // rgb64\n          layer_rgb32_fast_c<uint16_t>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n      }\n    }\n    if (!lstrcmpi(Op, \"Subtract\"))\n    {\n      // base_clip - overlay_clip.\n      // Similar to add, but overlay_clip is inverted before adding.\n      if (chroma)\n      {\n#ifdef INTEL_INTRINSICS\n        if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_AVX2))\n        {\n          layer_rgb32_subtract_avx2<true>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n        }\n        else if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_SSE2))\n        {\n          layer_rgb32_subtract_sse2<true>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n        }\n#ifdef X86_32\n        else if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_INTEGER_SSE))\n        {\n          layer_rgb32_subtract_isse<true>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n        }\n#endif\n        else\n#endif\n        {\n          if (pixelsize == 1)\n            layer_rgb32_subtract_chroma_c<uint8_t>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n          else\n            layer_rgb32_subtract_chroma_c<uint16_t>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n        }\n      }\n      else\n      {\n#ifdef INTEL_INTRINSICS\n        if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_AVX2))\n        {\n          layer_rgb32_subtract_avx2<false>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n        }\n        else if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_SSE2))\n        {\n          layer_rgb32_subtract_sse2<false>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n        }\n#ifdef X86_32\n        else if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_INTEGER_SSE))\n        {\n          layer_rgb32_subtract_isse<false>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n        }\n#endif\n        else\n#endif\n        {\n          if (pixelsize == 1)\n            layer_rgb32_subtract_c<uint8_t>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n          else\n            layer_rgb32_subtract_c<uint16_t>(src1p, src2p, src1_pitch, src2_pitch, width, height, mylevel);\n        }\n      }\n    }\n  }\n  else if (vi.IsYUV() || vi.IsYUVA())\n  {\n    // planar YUV(A) source\n\n    const int pixelsize = vi.ComponentSize();\n\n    // when exists, alpha comes from overlay (source) clip. Not used yet\n    //const int src2_pitch_a = hasAlpha ? src2->GetPitch(PLANAR_A) : 0;\n    //const BYTE* srcp2_a = hasAlpha ? src2->GetReadPtr(PLANAR_A) + src2_pitch_a * ysrc + xsrc * pixelsize : nullptr;\n\n    if (!lstrcmpi(Op, \"Lighten\") || !lstrcmpi(Op, \"Darken\"))\n    {\n      const bool isLighten = !lstrcmpi(Op, \"Lighten\");\n      // only chroma == true\n\n      const int src1_pitch = src1->GetPitch(PLANAR_Y);\n      const int src2_pitch = src2->GetPitch(PLANAR_Y);\n      const int src1_pitchUV = src1->GetPitch(PLANAR_U);\n      const int src2_pitchUV = src2->GetPitch(PLANAR_U);\n\n      const bool grey = vi.IsY();\n\n      const int ws = grey ? 1 : vi.GetPlaneWidthSubsampling(PLANAR_U);\n      const int hs = grey ? 1 : vi.GetPlaneHeightSubsampling(PLANAR_U);\n\n      BYTE* src1p = src1->GetWritePtr(PLANAR_Y) + src1_pitch * (ydest)+(xdest)*pixelsize; // in-place source and destination\n      const BYTE* src2p = src2->GetReadPtr(PLANAR_Y) + src2_pitch * (ysrc)+(xsrc)*pixelsize; // overlay\n\n      BYTE* src1p_u = grey ? nullptr : src1->GetWritePtr(PLANAR_U) + src1_pitchUV * (ydest >> hs) + (xdest >> ws) * pixelsize;\n      const BYTE* src2p_u = grey ? nullptr : src2->GetReadPtr(PLANAR_U) + src2_pitchUV * (ysrc >> hs) + (xsrc >> ws) * pixelsize;\n\n      BYTE* src1p_v = grey ? nullptr : src1->GetWritePtr(PLANAR_V) + src1_pitchUV * (ydest >> hs) + (xdest >> ws) * pixelsize;\n      const BYTE* src2p_v = grey ? nullptr : src2->GetReadPtr(PLANAR_V) + src2_pitchUV * (ysrc >> hs) + (xsrc >> ws) * pixelsize;\n\n      // target alpha channel is unaffected\n      //BYTE* src1p_a = hasAlpha ? src1->GetWritePtr(PLANAR_Y) + src1_pitch * (ydest)+(xdest)* pixelsize : nullptr;\n      const BYTE* maskp = hasAlpha ? src2->GetReadPtr(PLANAR_A) + src2_pitch * (ysrc)+(xsrc)*pixelsize : nullptr; // overlay alpha\n      const int mask_pitch = src2->GetPitch(PLANAR_A);\n\n      // called only once, for all planes\n\n      layer_yuv_lighten_darken_c_t* layer_fn = nullptr;\n      layer_yuv_lighten_darken_f_c_t* layer_f_fn = nullptr;\n\n      // fills layer_yuv_lighten_darken_c_t or layer_yuv_lighten_darken_f_c_t depending on video format, and bits_per_pixel.\n      get_layer_yuv_lighten_darken_functions(isLighten, placement, vi, bits_per_pixel, &layer_fn, &layer_f_fn);\n\n      // ThresholdParam was scaled from the 8 bit world\n      if (layer_fn && bits_per_pixel != 32) {\n        layer_fn(\n          src1p, src1p_u, src1p_v,\n          src2p, src2p_u, src2p_v, maskp,\n          src1_pitch, src1_pitchUV,\n          src2_pitch, src2_pitchUV,\n          mask_pitch,\n          width, height, mylevel, ThresholdParam, bits_per_pixel);\n      }\n      else if (layer_f_fn && bits_per_pixel == 32) {\n        layer_f_fn(\n          src1p, src1p_u, src1p_v,\n          src2p, src2p_u, src2p_v, maskp,\n          src1_pitch, src1_pitchUV,\n          src2_pitch, src2_pitchUV,\n          mask_pitch,\n          width, height, opacity, ThresholdParam_f);\n      }\n      // lighten/darken end\n    }\n    else {\n      // not Lighten and not Darken, process planes individually\n      const int maxPlanes = std::min(vi.NumComponents(), 3); // do not process alpha plane\n      const int planesYUV[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };\n      for (int channel = 0; channel < maxPlanes; channel++)\n      {\n        const int plane = planesYUV[channel];\n\n        const int src1_pitch = src1->GetPitch(plane);\n        const int src2_pitch = src2->GetPitch(plane);\n\n        const int ws = vi.GetPlaneWidthSubsampling(plane);\n        const int hs = vi.GetPlaneHeightSubsampling(plane);\n        const int currentwidth = width >> ws;\n        const int currentheight = height >> hs;\n\n        BYTE* src1p = src1->GetWritePtr(plane) + src1_pitch * (ydest >> hs) + (xdest >> ws) * pixelsize; // destination\n        const BYTE* src2p = src2->GetReadPtr(plane) + src2_pitch * (ysrc >> hs) + (xsrc >> ws) * pixelsize; // source plane\n\n        const BYTE* maskp = hasAlpha ? src2->GetReadPtr(PLANAR_A) + src2_pitch * (ysrc >> hs) + (xsrc >> ws) * pixelsize : nullptr; // alpha plane from Overlay\n        const int mask_pitch = hasAlpha ? src2->GetPitch(PLANAR_A) : 0;\n\n        const bool is_chroma = plane != PLANAR_Y;\n\n        if (!lstrcmpi(Op, \"Mul\"))\n        {\n          layer_yuv_mul_c_t* layer_fn = nullptr;\n          layer_yuv_mul_f_c_t* layer_f_fn = nullptr;\n\n#ifdef INTEL_INTRINSICS\n          if (env->GetCPUFlags() & CPUF_AVX2) {\n            // wrapper for the avx2 module, which calls its local scoped get_layer_yuv_mul_functions the included layer.hpp\n            get_layer_yuv_mul_functions_avx2(is_chroma, chroma, hasAlpha, placement, vi, bits_per_pixel, &layer_fn, &layer_f_fn);\n          }\n          else\n#endif\n            get_layer_yuv_mul_functions(is_chroma, chroma, hasAlpha, placement, vi, bits_per_pixel, &layer_fn, &layer_f_fn);\n\n          if (layer_fn && bits_per_pixel != 32) {\n            layer_fn(src1p, src2p, maskp, src1_pitch, src2_pitch, mask_pitch,\n              currentwidth, currentheight, mylevel, bits_per_pixel);\n          }\n          else if (layer_f_fn && bits_per_pixel == 32) {\n            layer_f_fn(src1p, src2p, maskp, src1_pitch, src2_pitch, mask_pitch,\n              currentwidth, currentheight, opacity);\n          }\n        }\n        else if (!lstrcmpi(Op, \"Add\"))\n        {\n          layer_yuv_add_subtract_c_t* layer_fn = nullptr;\n          layer_yuv_add_subtract_f_c_t* layer_f_fn = nullptr;\n\n          // template: subtract = true, add = false\n#ifdef INTEL_INTRINSICS\n          if (env->GetCPUFlags() & CPUF_AVX2) {\n            // wrapper for the avx2 module, which calls its local scoped get_layer_yuv_add_subtract_functions the included layer.hpp\n            get_layer_yuv_add_subtract_functions_avx2<false>(is_chroma, chroma, hasAlpha, placement, vi, bits_per_pixel, &layer_fn, &layer_f_fn);\n          }\n          else\n#endif\n            get_layer_yuv_add_subtract_functions<false>(is_chroma, chroma, hasAlpha, placement, vi, bits_per_pixel, &layer_fn, &layer_f_fn);\n\n          if (layer_fn && bits_per_pixel != 32) {\n            layer_fn(src1p, src2p, maskp, src1_pitch, src2_pitch, mask_pitch,\n              currentwidth, currentheight, mylevel, bits_per_pixel);\n          }\n          else if (layer_f_fn && bits_per_pixel == 32) {\n            layer_f_fn(src1p, src2p, maskp, src1_pitch, src2_pitch, mask_pitch,\n              currentwidth, currentheight, opacity);\n          }\n        }\n        if (!lstrcmpi(Op, \"Subtract\"))\n        {\n          layer_yuv_add_subtract_c_t* layer_fn = nullptr;\n          layer_yuv_add_subtract_f_c_t* layer_f_fn = nullptr;\n\n          // template: subtract = true, add = false\n#ifdef INTEL_INTRINSICS\n          if (env->GetCPUFlags() & CPUF_AVX2) {\n            // wrapper for the avx2 module, which calls its local scoped get_layer_yuv_add_subtract_functions the included layer.hpp\n            get_layer_yuv_add_subtract_functions_avx2<true>(is_chroma, chroma, hasAlpha, placement, vi, bits_per_pixel, &layer_fn, &layer_f_fn);\n          }\n          else\n#endif\n            get_layer_yuv_add_subtract_functions<true>(is_chroma, chroma, hasAlpha, placement, vi, bits_per_pixel, &layer_fn, &layer_f_fn);\n\n          if (layer_fn && bits_per_pixel != 32) {\n            layer_fn(src1p, src2p, maskp, src1_pitch, src2_pitch, mask_pitch,\n              currentwidth, currentheight, mylevel, bits_per_pixel);\n          }\n          else if (layer_f_fn && bits_per_pixel == 32) {\n            layer_f_fn(src1p, src2p, maskp, src1_pitch, src2_pitch, mask_pitch,\n              currentwidth, currentheight, opacity);\n          }\n        }\n        if (!lstrcmpi(Op, \"Fast\"))\n        {\n          // only chroma == true\n#ifdef INTEL_INTRINSICS\n          if (env->GetCPUFlags() & CPUF_AVX2 && bits_per_pixel != 32)\n          {\n            if (bits_per_pixel == 8)\n              layer_genericplane_fast_avx2<uint8_t>(src1p, src2p, src1_pitch, src2_pitch, currentwidth, currentheight, mylevel);\n            else if (bits_per_pixel <= 16) // simply averaging, no difference for 10-16 bits\n              layer_genericplane_fast_avx2<uint16_t>(src1p, src2p, src1_pitch, src2_pitch, currentwidth, currentheight, mylevel);\n          }\n          else if (env->GetCPUFlags() & CPUF_SSE2 && bits_per_pixel != 32)\n          {\n            if (bits_per_pixel == 8)\n              layer_genericplane_fast_sse2<uint8_t>(src1p, src2p, src1_pitch, src2_pitch, currentwidth, currentheight, mylevel);\n            else if (bits_per_pixel <= 16) // simply averaging, no difference for 10-16 bits\n              layer_genericplane_fast_sse2<uint16_t>(src1p, src2p, src1_pitch, src2_pitch, currentwidth, currentheight, mylevel);\n          }\n          else\n#endif\n          {\n            if (bits_per_pixel == 8)\n              layer_genericplane_fast_c<uint8_t>(src1p, src2p, src1_pitch, src2_pitch, currentwidth, currentheight, mylevel);\n            else if (bits_per_pixel <= 16) // simply averaging, no difference for 10-16 bits\n              layer_genericplane_fast_c<uint16_t>(src1p, src2p, src1_pitch, src2_pitch, currentwidth, currentheight, mylevel);\n            else // 32 bit\n              layer_genericplane_fast_f_c(src1p, src2p, src1_pitch, src2_pitch, currentwidth, currentheight, opacity /*n/a*/);\n          }\n        }\n      } // for one channel\n    } // if lighten/darken else\n\n  }\n  else if (vi.IsPlanarRGB() || vi.IsPlanarRGBA())\n  {\n    const int pixelsize = vi.ComponentSize();\n\n    BYTE* dstp[4];\n    const BYTE* ovrp[4];\n    const int dstp_pitch = src1->GetPitch(PLANAR_G); // same for all\n    const int ovrp_pitch = src2->GetPitch(PLANAR_G); // same for all\n\n    const int maxPlanes = vi.NumComponents();\n    const int planesRGB[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A };\n    for (int channel = 0; channel < maxPlanes; channel++)\n    {\n      const int plane = planesRGB[channel];\n      dstp[channel] = src1->GetWritePtr(plane) + dstp_pitch * ydest + xdest * pixelsize; // destination\n      ovrp[channel] = src2->GetReadPtr(plane) + ovrp_pitch * ysrc + xsrc * pixelsize; // overlay\n    }\n\n    if (!lstrcmpi(Op, \"Mul\"))\n    {\n      // called only once, for all planes\n      layer_planarrgb_mul_c_t* layer_fn = nullptr;\n      layer_planarrgb_mul_f_c_t* layer_f_fn = nullptr;\n\n#ifdef INTEL_INTRINSICS\n      if (env->GetCPUFlags() & CPUF_AVX2) {\n        get_layer_planarrgb_mul_functions_avx2(chroma, hasAlpha, bits_per_pixel, &layer_fn, &layer_f_fn);\n      }\n      else\n#endif\n        get_layer_planarrgb_mul_functions(chroma, hasAlpha, bits_per_pixel, &layer_fn, &layer_f_fn);\n\n      if (layer_fn && bits_per_pixel != 32)\n        layer_fn(dstp, ovrp, dstp_pitch, ovrp_pitch, width, height, mylevel, bits_per_pixel);\n      else if (layer_f_fn && bits_per_pixel == 32)\n        layer_f_fn(dstp, ovrp, dstp_pitch, ovrp_pitch, width, height, opacity);\n      // planar_rgba mul end\n    }\n    else if (!lstrcmpi(Op, \"Add\") || !lstrcmpi(Op, \"Subtract\"))\n    {\n      const bool isSubtract = !lstrcmpi(Op, \"Subtract\");\n\n      // called only once, for all planes\n      layer_planarrgb_add_subtract_c_t* layer_fn = nullptr;\n      layer_planarrgb_add_subtract_f_c_t* layer_f_fn = nullptr;\n\n      if (isSubtract) {\n#ifdef INTEL_INTRINSICS\n        if (env->GetCPUFlags() & CPUF_AVX2) {\n          // wrapper for the avx2 module, which calls its local scoped get_layer_planarrgb_add_subtract_functions the included layer.hpp\n          get_layer_planarrgb_add_subtract_functions_avx2<true>(chroma, hasAlpha, bits_per_pixel, &layer_fn, &layer_f_fn);\n        }\n        else\n#endif\n          get_layer_planarrgb_add_subtract_functions<true>(chroma, hasAlpha, bits_per_pixel, &layer_fn, &layer_f_fn);\n      }\n      else {\n#ifdef INTEL_INTRINSICS\n        if (env->GetCPUFlags() & CPUF_AVX2) {\n          // wrapper for the avx2 module, which calls its local scoped get_layer_planarrgb_add_subtract_functions the included layer.hpp\n          get_layer_planarrgb_add_subtract_functions_avx2<false>(chroma, hasAlpha, bits_per_pixel, &layer_fn, &layer_f_fn);\n        }\n        else\n#endif\n          get_layer_planarrgb_add_subtract_functions<false>(chroma, hasAlpha, bits_per_pixel, &layer_fn, &layer_f_fn);\n      }\n\n      if (layer_fn && bits_per_pixel != 32)\n        layer_fn(dstp, ovrp, dstp_pitch, ovrp_pitch, width, height, mylevel, bits_per_pixel);\n      else if (layer_f_fn && bits_per_pixel == 32)\n        layer_f_fn(dstp, ovrp, dstp_pitch, ovrp_pitch, width, height, opacity);\n      // planar rgb(a) sub end\n    }\n    else if (!lstrcmpi(Op, \"Lighten\") || !lstrcmpi(Op, \"Darken\"))\n    {\n      const bool isLighten = !lstrcmpi(Op, \"Lighten\");\n      // only chroma == true\n      // Copy overlay_clip over base_clip in areas where overlay_clip is lighter by threshold.\n      // called only once, for all planes\n      // integer 8-16 bits version\n      layer_planarrgb_lighten_darken_c_t* layer_fn = nullptr;\n      // 32 bit float version\n      layer_planarrgb_lighten_darken_f_c_t* layer_f_fn = nullptr;\n\n#ifdef INTEL_INTRINSICS\n      if (env->GetCPUFlags() & CPUF_AVX2) {\n        // wrapper for the avx2 module, which calls its local scoped get_layer_planarrgb_lighten_darken_functions the included layer.hpp\n        get_layer_planarrgb_lighten_darken_functions_avx2(isLighten, hasAlpha, bits_per_pixel, &layer_fn, &layer_f_fn);\n      }\n      else\n#endif\n        get_layer_planarrgb_lighten_darken_functions(isLighten, hasAlpha, bits_per_pixel, &layer_fn, &layer_f_fn);\n\n      if (layer_fn && bits_per_pixel != 32)\n        layer_fn(dstp, ovrp, dstp_pitch, ovrp_pitch, width, height, mylevel, ThresholdParam, bits_per_pixel);\n      else if (layer_f_fn && bits_per_pixel == 32)\n        layer_f_fn(dstp, ovrp, dstp_pitch, ovrp_pitch, width, height, opacity, ThresholdParam_f);\n      // planar rgba lighten/darken end\n    }\n    if (!lstrcmpi(Op, \"Fast\"))\n    {\n      // only chroma == true\n      // target alpha channel is unaffected\n      for (int i = 0; i < std::min(vi.NumComponents(), 3); i++) {\n#ifdef INTEL_INTRINSICS\n        if (env->GetCPUFlags() & CPUF_AVX2 && bits_per_pixel != 32)\n        {\n          if (bits_per_pixel == 8)\n            layer_genericplane_fast_avx2<uint8_t>(dstp[i], ovrp[i], dstp_pitch, ovrp_pitch, width, height, mylevel);\n          else if (bits_per_pixel <= 16) // simply averaging, no difference for 10-16 bits\n            layer_genericplane_fast_avx2<uint16_t>(dstp[i], ovrp[i], dstp_pitch, ovrp_pitch, width, height, mylevel);\n        }\n        else if (env->GetCPUFlags() & CPUF_SSE2 && bits_per_pixel != 32)\n        {\n          if (bits_per_pixel == 8)\n            layer_genericplane_fast_sse2<uint8_t>(dstp[i], ovrp[i], dstp_pitch, ovrp_pitch, width, height, mylevel);\n          else if (bits_per_pixel <= 16) // simply averaging, no difference for 10-16 bits\n            layer_genericplane_fast_sse2<uint16_t>(dstp[i], ovrp[i], dstp_pitch, ovrp_pitch, width, height, mylevel);\n        }\n        else\n#endif\n        {\n          if (bits_per_pixel == 8)\n            layer_genericplane_fast_c<uint8_t>(dstp[i], ovrp[i], dstp_pitch, ovrp_pitch, width, height, mylevel);\n          else if (bits_per_pixel <= 16) // simply averaging, no difference for 10-16 bits\n            layer_genericplane_fast_c<uint16_t>(dstp[i], ovrp[i], dstp_pitch, ovrp_pitch, width, height, mylevel);\n          else // 32 bit\n            layer_genericplane_fast_f_c(dstp[i], ovrp[i], dstp_pitch, ovrp_pitch, width, height, opacity /*n/a*/);\n        }\n      }\n    }\n    // Layer planar RGB(A) end\n  }\n\n  return src1;\n}\n\n\nAVSValue __cdecl Layer::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  const VideoInfo& vi1 = args[0].AsClip()->GetVideoInfo();\n  const VideoInfo& vi2 = args[1].AsClip()->GetVideoInfo();\n\n  // convert old RGB format to planar RGB\n  PClip clip1;\n  if (vi1.IsRGB24() || vi1.IsRGB48()) {\n    AVSValue new_args[1] = { args[0].AsClip() };\n    clip1 = env->Invoke(\"ConvertToPlanarRGB\", AVSValue(new_args, 1)).AsClip();\n  }\n  /* formats handled by Layer core\n  else if (vi1.IsRGB32() || vi1.IsRGB64()) {\n    AVSValue new_args[1] = { args[0].AsClip() };\n    clip1 = env->Invoke(\"ConvertToPlanarRGBA\", AVSValue(new_args, 1)).AsClip();\n  }\n  */\n  else if (vi1.IsYUY2()) {\n    AVSValue new_args[1] = { args[0].AsClip() };\n    clip1 = env->Invoke(\"ConvertToYV16\", AVSValue(new_args, 1)).AsClip();\n  }\n  else {\n    clip1 = args[0].AsClip();\n  }\n\n  PClip clip2;\n  if (vi2.IsRGB24() || vi2.IsRGB48()) {\n    AVSValue new_args[1] = { args[1].AsClip() };\n    clip2 = env->Invoke(\"ConvertToPlanarRGB\", AVSValue(new_args, 1)).AsClip();\n  }\n  /* formats handled by Layer core\n  else if (vi2.IsRGB32() || vi2.IsRGB64()) {\n    AVSValue new_args[1] = { args[1].AsClip() };\n    clip2 = env->Invoke(\"ConvertToPlanarRGBA\", AVSValue(new_args, 1)).AsClip();\n  }\n  */\n  else if (vi2.IsYUY2()) {\n    AVSValue new_args[1] = { args[1].AsClip() };\n    clip2 = env->Invoke(\"ConvertToYV16\", AVSValue(new_args, 1)).AsClip();\n  }\n  else {\n    clip2 = args[1].AsClip();\n  }\n\n  Layer* Result = new Layer(clip1, clip2, args[2].AsString(\"Add\"), args[3].AsInt(-1),\n    args[4].AsInt(0), args[5].AsInt(0), args[6].AsInt(0),\n    args[7].AsBool(true), // chroma\n    args[8].AsFloatf(-1.0f), // opacity\n    getPlacement(args[9], env), // chroma placement\n    env);\n\n  if (vi1.IsRGB24()) {\n    AVSValue new_args2[1] = { Result };\n    return env->Invoke(\"ConvertToRGB24\", AVSValue(new_args2, 1)).AsClip();\n  }\n  else if (vi1.IsRGB48()) {\n    AVSValue new_args2[1] = { Result };\n    return env->Invoke(\"ConvertToRGB48\", AVSValue(new_args2, 1)).AsClip();\n  }\n  /* formats handled by Layer core\n  else if (vi1.IsRGB32()) {\n    AVSValue new_args2[1] = { Result };\n    return env->Invoke(\"ConvertToRGB32\", AVSValue(new_args2, 1)).AsClip();\n  }\n  else if (vi1.IsRGB64()) {\n    AVSValue new_args2[1] = { Result };\n    return env->Invoke(\"ConvertToRGB64\", AVSValue(new_args2, 1)).AsClip();\n  }\n  */\n  else if (vi1.IsYUY2()) {\n    // convert back to original\n    AVSValue new_args2[1] = { Result };\n    return env->Invoke(\"ConvertToYUY2\", AVSValue(new_args2, 1)).AsClip();\n  }\n\n  return Result;\n\n}\n\n\n\n/**********************************\n *******   Subtract Filter   ******\n *********************************/\nbool Subtract::DiffFlag = false;\nBYTE Subtract::LUT_Diff8[513];\n\nSubtract::Subtract(PClip _child1, PClip _child2, IScriptEnvironment* env)\n  : child1(_child1), child2(_child2)\n{\n  VideoInfo vi1 = child1->GetVideoInfo();\n  VideoInfo vi2 = child2->GetVideoInfo();\n\n  if (vi1.width != vi2.width || vi1.height != vi2.height)\n    env->ThrowError(\"Subtract: image dimensions don't match\");\n\n  if (!(vi1.IsSameColorspace(vi2)))\n    env->ThrowError(\"Subtract: image formats don't match\");\n\n  vi = vi1;\n  vi.num_frames = max(vi1.num_frames, vi2.num_frames);\n  vi.num_audio_samples = max(vi1.num_audio_samples, vi2.num_audio_samples);\n\n  pixelsize = vi.ComponentSize();\n  bits_per_pixel = vi.BitsPerComponent();\n\n  if (!DiffFlag) { // Init the global Diff table\n    DiffFlag = true;\n    for (int i = 0; i <= 512; i++) LUT_Diff8[i] = max(0, min(255, i - 129));\n    // 0 ..  129  130 131   ... 255 256 257 258     384 ... 512\n    // 0 ..   0    1   2  3 ... 126 127 128 129 ... 255 ... 255\n  }\n}\n\ntemplate<typename pixel_t, int midpixel, bool chroma>\nstatic void subtract_plane(BYTE* src1p, const BYTE* src2p, int src1_pitch, int src2_pitch, int width, int height, int bits_per_pixel)\n{\n  typedef typename std::conditional < sizeof(pixel_t) == 4, float, int>::type limits_t;\n\n  const limits_t limit_lo = sizeof(pixel_t) <= 2 ? 0 : (limits_t)(chroma ? uv8tof(0) : c8tof(0));\n  const limits_t limit_hi = sizeof(pixel_t) == 1 ? 255 : sizeof(pixel_t) == 2 ? ((1 << bits_per_pixel) - 1) : (limits_t)(chroma ? uv8tof(255) : c8tof(255));\n  const limits_t equal_luma = sizeof(pixel_t) == 1 ? midpixel : sizeof(pixel_t) == 2 ? (midpixel << (bits_per_pixel - 8)) : (limits_t)(chroma ? uv8tof(midpixel) : c8tof(midpixel));\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < width; x++) {\n      reinterpret_cast<pixel_t*>(src1p)[x] =\n        (pixel_t)clamp(\n          (limits_t)(reinterpret_cast<pixel_t*>(src1p)[x] - reinterpret_cast<const pixel_t*>(src2p)[x] + equal_luma), // 126: luma of equality\n          limit_lo,\n          limit_hi);\n    }\n    src1p += src1_pitch;\n    src2p += src2_pitch;\n  }\n}\n\nPVideoFrame __stdcall Subtract::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame src1 = child1->GetFrame(n, env);\n  PVideoFrame src2 = child2->GetFrame(n, env);\n\n  env->MakeWritable(&src1);\n\n  BYTE* src1p = src1->GetWritePtr();\n  const BYTE* src2p = src2->GetReadPtr();\n  int row_size = src1->GetRowSize();\n  int src1_pitch = src1->GetPitch();\n  int src2_pitch = src2->GetPitch();\n\n  int width = row_size / pixelsize;\n  int height = vi.height;\n\n  if (vi.IsPlanar() && (vi.IsYUV() || vi.IsYUVA())) {\n    // alpha\n    if (pixelsize == 1) {\n      // LUT is a bit faster than clamp version\n      for (int y = 0; y < vi.height; y++) {\n        for (int x = 0; x < row_size; x++) {\n          src1p[x] = LUT_Diff8[src1p[x] - src2p[x] + 126 + 129];\n        }\n        src1p += src1->GetPitch();\n        src2p += src2->GetPitch();\n      }\n    }\n    else if (pixelsize == 2)\n      subtract_plane<uint16_t, 126, false>(src1p, src2p, src1_pitch, src2_pitch, width, height, bits_per_pixel);\n    else //if (pixelsize==4)\n      subtract_plane<float, 126, false>(src1p, src2p, src1_pitch, src2_pitch, width, height, bits_per_pixel);\n\n    // chroma\n    row_size = src1->GetRowSize(PLANAR_U);\n    if (row_size) {\n      width = row_size / pixelsize;\n      height = src1->GetHeight(PLANAR_U);\n      src1_pitch = src1->GetPitch(PLANAR_U);\n      src2_pitch = src2->GetPitch(PLANAR_U);\n      // U_plane exists\n      BYTE* src1p = src1->GetWritePtr(PLANAR_U);\n      const BYTE* src2p = src2->GetReadPtr(PLANAR_U);\n      BYTE* src1pV = src1->GetWritePtr(PLANAR_V);\n      const BYTE* src2pV = src2->GetReadPtr(PLANAR_V);\n\n      if (pixelsize == 1) {\n        // LUT is a bit faster than clamp version\n        for (int y = 0; y < height; y++) {\n          for (int x = 0; x < width; x++) {\n            src1p[x] = LUT_Diff8[src1p[x] - src2p[x] + 128 + 129];\n            src1pV[x] = LUT_Diff8[src1pV[x] - src2pV[x] + 128 + 129];\n          }\n          src1p += src1_pitch;\n          src2p += src2_pitch;\n          src1pV += src1_pitch;\n          src2pV += src2_pitch;\n        }\n      }\n      else if (pixelsize == 2) {\n        subtract_plane<uint16_t, 128, true>(src1p, src2p, src1_pitch, src2_pitch, width, height, bits_per_pixel);\n        subtract_plane<uint16_t, 128, true>(src1pV, src2pV, src1_pitch, src2_pitch, width, height, bits_per_pixel);\n      }\n      else { //if (pixelsize==4)\n        subtract_plane<float, 128, true>(src1p, src2p, src1_pitch, src2_pitch, width, height, bits_per_pixel);\n        subtract_plane<float, 128, true>(src1pV, src2pV, src1_pitch, src2_pitch, width, height, bits_per_pixel);\n      }\n    }\n    return src1;\n  } // End planar YUV\n\n  // For YUY2, 50% gray is about (126,128,128) instead of (128,128,128).  Grr...\n  if (vi.IsYUY2()) {\n    for (int y = 0; y < vi.height; ++y) {\n      for (int x = 0; x < row_size; x += 2) {\n        src1p[x] = LUT_Diff8[src1p[x] - src2p[x] + 126 + 129];\n        src1p[x + 1] = LUT_Diff8[src1p[x + 1] - src2p[x + 1] + 128 + 129];\n      }\n      src1p += src1->GetPitch();\n      src2p += src2->GetPitch();\n    }\n  }\n  else { // RGB\n    if (vi.IsPlanarRGB() || vi.IsPlanarRGBA()) {\n      const int planesRGB[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A };\n\n      // do not diff Alpha\n      for (int p = 0; p < 3; p++) {\n        const int plane = planesRGB[p];\n        src1p = src1->GetWritePtr(plane);\n        src2p = src2->GetReadPtr(plane);\n        src1_pitch = src1->GetPitch(plane);\n        src2_pitch = src2->GetPitch(plane);\n        if (pixelsize == 1)\n          subtract_plane<uint8_t, 128, false>(src1p, src2p, src1_pitch, src2_pitch, width, height, bits_per_pixel);\n        else if (pixelsize == 2)\n          subtract_plane<uint16_t, 128, false>(src1p, src2p, src1_pitch, src2_pitch, width, height, bits_per_pixel);\n        else\n          subtract_plane<float, 128, false>(src1p, src2p, src1_pitch, src2_pitch, width, height, bits_per_pixel);\n      }\n    }\n    else { // packed RGB\n      if (pixelsize == 1) {\n        for (int y = 0; y < vi.height; ++y) {\n          for (int x = 0; x < row_size; ++x)\n            src1p[x] = LUT_Diff8[src1p[x] - src2p[x] + 128 + 129];\n\n          src1p += src1->GetPitch();\n          src2p += src2->GetPitch();\n        }\n      }\n      else { // pixelsize == 2: RGB48, RGB64\n        // width is getrowsize based here: ok.\n        subtract_plane<uint16_t, 128, false>(src1p, src2p, src1_pitch, src2_pitch, width, height, bits_per_pixel);\n      }\n    }\n  }\n  return src1;\n}\n\n\n\nAVSValue __cdecl Subtract::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  return new Subtract(args[0].AsClip(), args[1].AsClip(), env);\n}\n"
  },
  {
    "path": "avs_core/filters/layer.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n\n\n// Avisynth filter: Layer\n// by \"poptones\" (poptones@myrealbox.com)\n\n\n#ifndef __Layer_H__\n#define __Layer_H__\n\n#include <avisynth.h>\n#include <stdint.h>\n\nenum { PLACEMENT_MPEG2, PLACEMENT_MPEG1 }; // for Layer 420, 422\n\n// For \"Layer\"\nenum MaskMode {\n  MASK411,\n  MASK420,\n  MASK420_MPEG2,\n  MASK422,\n  MASK422_MPEG2,\n  MASK444\n};\n\n// called only once, for all planes\n// integer 8-16 bits version\nusing layer_yuv_lighten_darken_c_t = void (BYTE* dstp8, BYTE* dstp8_u, BYTE* dstp8_v,\n  const BYTE* ovrp8, const BYTE* ovrp8_u, const BYTE* ovrp8_v, const BYTE* mask8,\n  int dst_pitch, int dst_pitchUV,\n  int overlay_pitch, int overlay_pitchUV,\n  int mask_pitch,\n  int width, int height, int level, int thresh,\n  int bits_per_pixel);\n\n// 32 bit float version\nusing layer_yuv_lighten_darken_f_c_t = void (BYTE* dstp8, BYTE* dstp8_u, BYTE* dstp8_v,\n  const BYTE* ovrp8, const BYTE* ovrp8_u, const BYTE* ovrp8_v, const BYTE* mask8,\n  int dst_pitch, int dst_pitchUV,\n  int overlay_pitch, int overlay_pitchUV,\n  int mask_pitch,\n  int width, int height, float level, float thresh);\n\nusing layer_planarrgb_lighten_darken_c_t = void(BYTE** dstp8, const BYTE** ovrp8, int dst_pitch, int overlay_pitch, int width, int height, int level, int thresh, int bits_per_pixel);\nusing layer_planarrgb_lighten_darken_f_c_t = void(BYTE** dstp8, const BYTE** ovrp8, int dst_pitch, int overlay_pitch, int width, int height, float opacity, float thresh);\n\n// YUV Mul function pointers\n// integer 8-16 bits version\nusing layer_yuv_mul_c_t = void(BYTE* dstp8, const BYTE* ovrp8, const BYTE* maskp8,\n  int dst_pitch, int overlay_pitch, int mask_pitch,\n  int width, int height, int level, int bits_per_pixel);\n\n// 32 bit float version\nusing layer_yuv_mul_f_c_t = void(BYTE* dstp8, const BYTE* ovrp8, const BYTE* maskp8,\n  int dst_pitch, int overlay_pitch, int mask_pitch,\n  int width, int height, float opacity);\n\n// YUV Add/Subtract function pointers (same signatures for both)\nusing layer_yuv_add_subtract_c_t = void(BYTE* dstp8, const BYTE* ovrp8, const BYTE* mask8,\n  int dst_pitch, int overlay_pitch, int mask_pitch,\n  int width, int height, int level, int bits_per_pixel);\n\nusing layer_yuv_add_subtract_f_c_t = void(BYTE* dstp8, const BYTE* ovrp8, const BYTE* mask8,\n  int dst_pitch, int overlay_pitch, int mask_pitch,\n  int width, int height, float opacity);\n\n// integer 8-16 bits version\nusing layer_planarrgb_add_subtract_c_t = void(BYTE** dstp8, const BYTE** ovrp8, int dst_pitch, int overlay_pitch, int width, int height, int level, int bits_per_pixel);\n// 32 bit float version\nusing layer_planarrgb_add_subtract_f_c_t = void(BYTE** dstp8, const BYTE** ovrp8, int dst_pitch, int overlay_pitch, int width, int height, float opacity);\n\n// Planar RGB mul function pointers\n// integer 8-16 bits version\nusing layer_planarrgb_mul_c_t = void(BYTE** dstp8, const BYTE** ovrp8,\n  int dst_pitch, int overlay_pitch, int width, int height, int level, int bits_per_pixel);\n// 32 bit float version\nusing layer_planarrgb_mul_f_c_t = void(BYTE** dstp8, const BYTE** ovrp8,\n  int dst_pitch, int overlay_pitch, int width, int height, float opacity);\n\n/********************************************************************\n********************************************************************/\n\nclass Mask : public IClip\n  /**\n    * Class for overlaying a mask clip on a video clip\n   **/\n{\npublic:\n  Mask(PClip _child1, PClip _child2, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  inline virtual void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) override\n  {\n    child1->GetAudio(buf, start, count, env);\n  }\n  inline virtual const VideoInfo& __stdcall GetVideoInfo() override\n  {\n    return vi;\n  }\n  inline virtual bool __stdcall GetParity(int n) override\n  {\n    return child1->GetParity(n);\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\nprivate:\n  const PClip child1, child2;\n  VideoInfo vi;\n  int mask_frames;\n  int pixelsize;\n  int bits_per_pixel;\n\n};\n\n\n\nclass ColorKeyMask : public GenericVideoFilter\n  /**\n    * Class for setting a mask on a video clip based on a color key\n  **/\n{\npublic:\n  ColorKeyMask(PClip _child, int _color, int _tolB, int _tolG, int _tolR, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\nprivate:\n  const int color, tolB, tolG, tolR;\n  uint64_t color64;\n  int tolB16, tolG16, tolR16;\n  int pixelsize;\n  int bits_per_pixel;\n  int max_pixel_value;\n\n};\n\n\n\nclass ResetMask : public GenericVideoFilter\n  /**\n    * Class to set the mask to all-opaque\n  **/\n{\npublic:\n  ResetMask(PClip _child, AVSValue _mask_f, AVSValue opacity_f, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\nprivate:\n  float mask_f;\n  int mask;\n};\n\n\n\nclass Invert : public GenericVideoFilter\n  /**\n    * Class to invert selected RGBA channels\n  **/\n{\npublic:\n  Invert(PClip _child, const char* _channels, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\nprivate:\n  int mask;\n  bool doB, doG, doR, doA;\n  bool doY, doU, doV;\n\n  uint64_t mask64;\n  int pixelsize;\n  int bits_per_pixel; // 8,10..16\n};\n\n\n\nclass ShowChannel : public GenericVideoFilter\n  /**\n    * Class to set the RGB components to the alpha mask\n  **/\n{\npublic:\n  ShowChannel(PClip _child, const char* _pixel_type, int _channel, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void* channel, IScriptEnvironment* env);\nprivate:\n  int channel;\n  const int input_type;\n  const int pixelsize;\n  const int bits_per_pixel;\n  bool input_type_is_planar_rgb;\n  bool input_type_is_planar_rgba;\n  bool input_type_is_yuv;\n  bool input_type_is_yuva;\n  bool input_type_is_planar;\n  bool input_type_is_packed_rgb;\n  bool target_hasalpha;\n  bool source_hasalpha;\n};\n\n\n\n\nclass MergeRGB : public GenericVideoFilter\n  /**\n    * Class to load the RGB components from specified clips\n  **/\n{\npublic:\n  MergeRGB(PClip _child, PClip _blue, PClip _green, PClip _red, PClip _alpha,\n    const char* _pixel_type, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void* mode, IScriptEnvironment* env);\nprivate:\n  const PClip blue, green, red, alpha;\n  const VideoInfo& viB, & viG, & viR, & viA;\n  const char* myname;\n};\n\n\nenum\n{\n  LIGHTEN = 0,\n  DARKEN = 1\n};\n\n// Simply Rec.601\n\n// 15 bit scaled constants used for calculating luma mask from RGB\n// original constants (3736,19235,9798) cause int32 overflow at 16 bits as sum()=32769\n// modified constants (3736,19234,9798) O.K. at 16 bits as sum()=32768\n// 32769 * 65535 + 16384 = 8000BFFF int32 overflow\n// 32768 * 65535 + 16384 = 7FFFC000 OK\nconst int cyb = 3736;      // int(0.114 * 32768 + 0.5); // 3736\nconst int cyg = 19235 - 1; // int(0.587 * 32768 + 0.5); // 19235\nconst int cyr = 9798;      // int(0.299 * 32768 + 0.5); // 9798\n// w/o correction: 32769\nconst float cyb_f = 0.114f;\nconst float cyg_f = 0.587f;\nconst float cyr_f = 0.299f;\n\nclass Layer : public IClip\n  /**\n    * Class for layering two clips on each other, combined by various functions\n   **/\n{\npublic:\n  Layer(PClip _child1, PClip _child2, const char _op[], int _lev, int _x, int _y,\n    int _t, bool _chroma, float _strength, int _placement, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  inline virtual void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) override\n  {\n    child1->GetAudio(buf, start, count, env);\n  }\n  inline virtual const VideoInfo& __stdcall GetVideoInfo() override\n  {\n    return vi;\n  }\n  inline virtual bool __stdcall GetParity(int n) override\n  {\n    return child1->GetParity(n);\n  }\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\nprivate:\n  const PClip child1, child2;\n  VideoInfo vi;\n  const  char* Op;\n  int levelB, ThresholdParam;\n  int ydest, xdest, ysrc, xsrc, ofsX, ofsY, ycount, xcount, overlay_frames;\n  const bool chroma;\n  bool hasAlpha;\n  int bits_per_pixel;\n  float opacity; // like in \"Overlay\"\n  int placement; // PLACEMENT_MPEG1 or PLACEMENT_MPEG2\n  float ThresholdParam_f;\n};\n\n\n\nclass Subtract : public IClip\n  /**\n    * Class for subtracting one clip from another\n   **/\n{\npublic:\n  Subtract(PClip _child1, PClip _child2, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  inline virtual void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) override\n  {\n    child1->GetAudio(buf, start, count, env);\n  }\n  inline virtual const VideoInfo& __stdcall GetVideoInfo() override\n  {\n    return vi;\n  }\n  inline virtual bool __stdcall GetParity(int n) override\n  {\n    return child1->GetParity(n);\n  }\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\nprivate:\n  const PClip child1, child2;\n  VideoInfo vi;\n\n  // Common to all instances\n  static bool DiffFlag;\n  static BYTE LUT_Diff8[513];\n  int pixelsize;\n  int bits_per_pixel;\n\n};\n\n\n\n#endif  // __Layer_H__\n"
  },
  {
    "path": "avs_core/filters/layer.hpp",
    "content": "\n// Basic utils in C++ language, to be included in both base and processor specific (e.g. avx2) source modules, where they can\n// be optimized for the specific instruction set.\n// Chroma placement to mask helpers, yuv add, subtract, mul, lighten, darken\n\nDISABLE_WARNING_PUSH\nDISABLE_WARNING_UNREFERENCED_LOCAL_VARIABLE\n\n// Single function for all cases\n\n// Helper function for calculation of effective mask value for a pixel, based on chroma placement\n// integer 8-16 bits version, with in/out parameter for MPEG2 sliding window modes\ntemplate<MaskMode maskMode, typename pixel_t>\nAVS_FORCEINLINE static int calculate_effective_mask(\n  const pixel_t* ptr,\n  int x,\n  int pitch,\n  int& right_value  // in/out parameter for MPEG2 sliding window modes\n) {\n  if constexpr (maskMode == MASK444) {\n    // +------+\n    // | 1.0  |\n    // +------+\n    return ptr[x];\n  }\n  else if constexpr (maskMode == MASK411) {\n    // +------+------+------+------+\n    // | 0.25 | 0.25 | 0.25 | 0.25 |\n    // +------+------+------+------+\n    return (ptr[x * 4] + ptr[x * 4 + 1] + ptr[x * 4 + 2] + ptr[x * 4 + 3] + 2) >> 2;\n  }\n  else if constexpr (maskMode == MASK420) {\n    // +------+------+\n    // | 0.25 | 0.25 |\n    // |------+------|\n    // | 0.25 | 0.25 |\n    // +------+------+\n    return (ptr[x * 2] + ptr[x * 2 + 1] + ptr[x * 2 + pitch] + ptr[x * 2 + 1 + pitch] + 2) >> 2;\n  }\n  else if constexpr (maskMode == MASK420_MPEG2) {\n    // ------+------+-------+\n    // 0.125 | 0.25 | 0.125 |\n    // ------|------+-------|\n    // 0.125 | 0.25 | 0.125 |\n    // ------+------+-------+\n    int left = right_value;\n    const int mid = ptr[x * 2] + ptr[x * 2 + pitch];\n    right_value = ptr[x * 2 + 1] + ptr[x * 2 + 1 + pitch];\n    return (left + 2 * mid + right_value + 4) >> 3;\n  }\n  else if constexpr (maskMode == MASK422) {\n    // +------+------+\n    // | 0.5  | 0.5  |\n    // +------+------+\n    return (ptr[x * 2] + ptr[x * 2 + 1] + 1) >> 1;\n  }\n  else if constexpr (maskMode == MASK422_MPEG2) {\n    // ------+------+-------+\n    // 0.25  | 0.5  | 0.25  |\n    // ------+------+-------+\n    int left = right_value;\n    const int mid = ptr[x * 2];\n    right_value = ptr[x * 2 + 1];\n    return (left + 2 * mid + right_value + 2) >> 2;\n  }\n}\n\n// Helper function for calculation of effective mask value for a pixel, based on chroma placement\n// Float version, with in/out parameter for MPEG2 sliding window modes\ntemplate<MaskMode maskMode>\nAVS_FORCEINLINE static float calculate_effective_mask_f(\n  const float* ptr,\n  int x,\n  int pitch,\n  float& right_value  // in/out parameter for MPEG2 sliding window modes\n) {\n  if constexpr (maskMode == MASK444) {\n    return ptr[x];\n  }\n  else if constexpr (maskMode == MASK411) {\n    return (ptr[x * 4] + ptr[x * 4 + 1] + ptr[x * 4 + 2] + ptr[x * 4 + 3]) * 0.25f;\n  }\n  else if constexpr (maskMode == MASK420) {\n    return (ptr[x * 2] + ptr[x * 2 + 1] + ptr[x * 2 + pitch] + ptr[x * 2 + 1 + pitch]) * 0.25f;\n  }\n  else if constexpr (maskMode == MASK420_MPEG2) {\n    float left = right_value;\n    const float mid = ptr[x * 2] + ptr[x * 2 + pitch];\n    right_value = ptr[x * 2 + 1] + ptr[x * 2 + 1 + pitch];\n    return (left + 2.0f * mid + right_value) * 0.125f;\n  }\n  else if constexpr (maskMode == MASK422) {\n    return (ptr[x * 2] + ptr[x * 2 + 1]) * 0.5f;\n  }\n  else if constexpr (maskMode == MASK422_MPEG2) {\n    float left = right_value;\n    const float mid = ptr[x * 2];\n    right_value = ptr[x * 2 + 1];\n    return (left + 2.0f * mid + right_value) * 0.25f;\n  }\n}\n\n// Helper function to prepare effective mask pointer for a complete row\n// integer 8-16 bits version\ntemplate<MaskMode maskMode, typename pixel_t>\nAVS_FORCEINLINE static const pixel_t* prepare_effective_mask_for_row(\n  const pixel_t* maskp,\n  int mask_pitch,\n  int width,\n  std::vector<pixel_t>& effective_mask_buffer\n) {\n  if constexpr (maskMode == MASK444) {\n    // Direct access to original mask - no pre-calculation needed\n    return maskp;\n  }\n  else {\n    // Initialize sliding window state for MPEG2 modes\n    int mask_right = 0; // initialized to silence warnings, actual value set below\n    if constexpr (maskMode == MASK420_MPEG2) {\n      mask_right = maskp[0] + maskp[0 + mask_pitch];\n    }\n    else if constexpr (maskMode == MASK422_MPEG2) {\n      mask_right = maskp[0];\n    }\n\n    // Pre-calculate averaged mask values\n    for (int x = 0; x < width; ++x) {\n      effective_mask_buffer[x] = (pixel_t)calculate_effective_mask<maskMode>(maskp, x, mask_pitch, mask_right);\n    }\n    return effective_mask_buffer.data();\n  }\n}\n\n// Helper function to prepare effective mask pointer for a complete row\n// float version\ntemplate<MaskMode maskMode>\nAVS_FORCEINLINE static const float* prepare_effective_mask_for_row_f(\n  const float* maskp,\n  int mask_pitch,\n  int width,\n  std::vector<float>& effective_mask_buffer\n) {\n  if constexpr (maskMode == MASK444) {\n    // Direct access to original mask - no pre-calculation needed\n    return maskp;\n  }\n  else {\n    // Initialize sliding window state for MPEG2 modes\n    float mask_right = 0.0f; // initialized to silence warnings, actual value set below\n    if constexpr (maskMode == MASK420_MPEG2) {\n      mask_right = maskp[0] + maskp[0 + mask_pitch];\n    }\n    else if constexpr (maskMode == MASK422_MPEG2) {\n      mask_right = maskp[0];\n    }\n\n    // Pre-calculate averaged mask values\n    for (int x = 0; x < width; ++x) {\n      effective_mask_buffer[x] = calculate_effective_mask_f<maskMode>(maskp, x, mask_pitch, mask_right);\n    }\n    return effective_mask_buffer.data();\n  }\n}\n\n// YUV(A) mul 8-16 bits\n// when chroma is processed, one can use/not use source chroma,\n// Only when use_alpha: maskMode defines mask generation for chroma planes\n// When use_alpha == false maskMode ignored\ntemplate<MaskMode maskMode, typename pixel_t, bool lessthan16bits, bool is_chroma, bool use_chroma, bool has_alpha>\nstatic void layer_yuv_mul_c(BYTE* dstp8, const BYTE* ovrp8, const BYTE* maskp8, int dst_pitch, int overlay_pitch, int mask_pitch, int width, int height, int level, int bits_per_pixel) {\n  pixel_t* dstp = reinterpret_cast<pixel_t*>(dstp8);\n  const pixel_t* ovrp = reinterpret_cast<const pixel_t*>(ovrp8);\n  const pixel_t* maskp = reinterpret_cast<const pixel_t*>(maskp8);\n  dst_pitch /= sizeof(pixel_t);\n  overlay_pitch /= sizeof(pixel_t);\n  mask_pitch /= sizeof(pixel_t);\n\n  typedef typename std::conditional<lessthan16bits, int, int64_t>::type calc_t;\n\n  if constexpr (sizeof(pixel_t) == 1)\n    bits_per_pixel = 8; // make quasi constexpr\n  else if constexpr (sizeof(pixel_t) == 2 && !lessthan16bits)\n    bits_per_pixel = 16; // make quasi constexpr\n\n  // precalculate mask buffer\n  std::vector<pixel_t> effective_mask_buffer;\n  if constexpr (has_alpha && maskMode != MASK444) {\n    effective_mask_buffer.resize(width);\n  }\n\n  for (int y = 0; y < height; ++y) {\n    const pixel_t* effective_mask_ptr = nullptr;\n\n    // precalculate effective mask for this row\n    if constexpr (has_alpha) {\n      effective_mask_ptr = prepare_effective_mask_for_row<maskMode, pixel_t>(maskp, mask_pitch, width, effective_mask_buffer);\n    }\n\n    // Main blending loop - now simplified and vectorizable\n    for (int x = 0; x < width; ++x) {\n      int effective_mask = has_alpha ? effective_mask_ptr[x] : 0;\n      int alpha_mask = has_alpha ? (int)(((calc_t)effective_mask * level + 1) >> bits_per_pixel) : level;\n\n      // fixme: no rounding? (code from YUY2)\n      // for mul: no.\n      if constexpr (!is_chroma)\n        dstp[x] = (pixel_t)(dstp[x] + ((((((calc_t)ovrp[x] * dstp[x]) >> bits_per_pixel) - dstp[x]) * alpha_mask) >> bits_per_pixel));\n      else if constexpr (use_chroma) {\n        // chroma mode + process chroma\n        dstp[x] = (pixel_t)(dstp[x] + (((calc_t)(ovrp[x] - dstp[x]) * alpha_mask) >> bits_per_pixel));\n        // U = U + ( ((Uovr - U)*level) >> 8 )\n        // V = V + ( ((Vovr - V)*level) >> 8 )\n      }\n      else {\n        // non-chroma mode + process chroma\n        const int half = 1 << (bits_per_pixel - 1);\n        dstp[x] = (pixel_t)(dstp[x] + (((calc_t)(half - dstp[x]) * (alpha_mask / 2)) >> bits_per_pixel));\n        // U = U + ( ((128 - U)*(level/2)) >> 8 )\n        // V = V + ( ((128 - V)*(level/2)) >> 8 )\n      }\n    }\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n    if constexpr (has_alpha) {\n      if constexpr (maskMode == MASK420 || maskMode == MASK420_MPEG2)\n        maskp += mask_pitch * 2;\n      else\n        maskp += mask_pitch;\n    }\n  }\n}\n\n// YUV(A) mul 32 bits\ntemplate<MaskMode maskMode, bool is_chroma, bool use_chroma, bool has_alpha>\nstatic void layer_yuv_mul_f_c(BYTE* dstp8, const BYTE* ovrp8, const BYTE* maskp8, int dst_pitch, int overlay_pitch, int mask_pitch, int width, int height, float opacity) {\n  float* dstp = reinterpret_cast<float*>(dstp8);\n  const float* ovrp = reinterpret_cast<const float*>(ovrp8);\n  const float* maskp = reinterpret_cast<const float*>(maskp8);\n  dst_pitch /= sizeof(float);\n  overlay_pitch /= sizeof(float);\n  mask_pitch /= sizeof(float);\n\n  // precalculate mask buffer\n  std::vector<float> effective_mask_buffer;\n  if constexpr (has_alpha && maskMode != MASK444) {\n    effective_mask_buffer.resize(width);\n  }\n\n  for (int y = 0; y < height; ++y) {\n    const float* effective_mask_ptr = nullptr;\n\n    // precalculate effective mask for this row\n    if constexpr (has_alpha) {\n      effective_mask_ptr = prepare_effective_mask_for_row_f<maskMode>(maskp, mask_pitch, width, effective_mask_buffer);\n    }\n\n    // Main blending loop - now simplified and vectorizable\n    for (int x = 0; x < width; ++x) {\n      float effective_mask = has_alpha ? effective_mask_ptr[x] : 0.0f;\n      float alpha_mask = has_alpha ? effective_mask * opacity : opacity;\n\n      if constexpr (!is_chroma)\n        dstp[x] = dstp[x] + (ovrp[x] * dstp[x] - dstp[x]) * alpha_mask;\n      else if constexpr (use_chroma) {\n        // chroma mode + process chroma\n        dstp[x] = dstp[x] + (ovrp[x] - dstp[x]) * alpha_mask;\n        // U = U + ( ((Uovr - U)*level) >> 8 )\n        // V = V + ( ((Vovr - V)*level) >> 8 )\n      }\n      else {\n        // non-chroma mode + process chroma\n        constexpr float half = 0.0f;\n        dstp[x] = dstp[x] + (half - dstp[x]) * (alpha_mask * 0.5f);\n        // U = U + ( ((128 - U)*(level/2)) >> 8 )\n        // V = V + ( ((128 - V)*(level/2)) >> 8 )\n      }\n    }\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n    if constexpr (has_alpha) {\n      if constexpr (maskMode == MASK420 || maskMode == MASK420_MPEG2)\n        maskp += mask_pitch * 2;\n      else\n        maskp += mask_pitch;\n    }\n  }\n}\n\n// YUV mul 8-16 bits\n// when chroma is processed, one can use/not use source chroma\n// Only when use_alpha: maskMode defines mask generation for chroma planes\n// When use_alpha == false -> maskMode ignored\n\n\n// Generated ASM analysis after doing chroma placement-dependent mask precalculation\n// => vectorized blending now recognized!\n//\n// Refactoring separated mask calculation from blending, enabling compilers to auto-vectorize the main loop.\n// Memory overhead: single row buffer (e.g., 1920 bytes for 1080p) fits comfortably in L1 cache.\n// Estimated speedups were told by AI, but preparing the inputs for Layer takes time, i could not measure only the\n// blending loop; but the speedup is significant (except 444 where no precalculation is needed)\n//\n// Mask calculation (e.g. MASK420_MPEG2 2x2 gather with sliding window):\n//   - All compilers: Scalar with no or max. 2x unrolling (complex gather+dependency pattern blocks vectorization)\n//   - Minimal overhead: ~1-2% of total runtime, one-time cost per row\n//\n// Main blending loop vectorization results:\n//   MSVC 2022 (SSE4.1):  4-wide vectorization, ~80 instructions per 16 pixels\n//     - Uses pmulld (SSE4.1) for 32-bit multiply, pmovzxbd for byte→dword extension\n//     - Fallback path: 16→4→1 (main loop, then scalar cleanup)\n//     - Estimated speedup: 3-4x vs scalar\n//   \n//   Intel C++ 2025 (SSE2):  16-wide vectorization, ~150 instructions per 16 pixels\n//     - Workaround for missing pmulld: pmuludq + shuffle for odd/even dwords (complex!)\n//     - Complex unpacking chain: 4× punpcklbw/punpckhbw + punpcklwd/punpckhwd for byte→dword\n//     - Fallback path: 16→1 (main loop processes full 16, scalar cleanup for remainder)\n//     - Estimated speedup: 6-8x vs scalar\n//   \n//   Intel C++ 2025 (AVX2):  16-wide vectorization (2×YMM), ~60 instructions per 16 pixels\n//     - Native vpmulld on YMM, vpmovzxbd for clean extension, vpshufb+vpackusdw packing\n//     - Fallback path: 16→4→1 (YMM main, XMM for 4-15 remaining, scalar for <4)\n//     - Requires XMM6-XMM14 save/restore (ABI requirement), adds minimal function overhead\n//     - Estimated speedup: 10-12x vs scalar\n//   \n//   Intel C++ 2025 (AVX-512):  16-wide vectorization (ZMM), ~40 instructions per 16 pixels\n//     - Predicated execution via k-registers: vpcmpuq+kunpckbw for boundary checking\n//     - Masked loads/stores (vmovdqu8 {k1}{z}) eliminate separate cleanup loops entirely!\n//     - Native vpmovdb for efficient dword→byte packing, vpmovzxbd for extension\n//     - Fallback path: 16→1 with masking (5+ remaining uses masked 16-wide, <5 uses scalar)\n//     - No XMM register save overhead (ZMM registers are volatile), only vzeroupper at exit\n//     - Estimated speedup: 12-15x vs scalar (requires Ice Lake+, Zen4+; may throttle on some CPUs)\n//\n// Sequential mask access pattern (vs. inline 2x2, 1x2, 2x3 gather) was critical for unlocking\n// auto-vectorization. The 16-wide SIMD implementations process the same data in 1/10th the time\n// despite the overhead of mask pre-calculation, proving the separation-of-concerns approach.\n// \n// Instruction count <> performance; Intel SSE2 uses ~2x more instructions than \n// MSVC SSE4.1, but achieves better speedup due to:\n//   1. Better instruction-level parallelism (ILP) - processes all 16 pixels in parallel\n//   2. Lower loop overhead - single iteration vs 4 iterations for 16 pixels\n//   3. Better memory bandwidth utilization - coalesced loads/stores\n//   4. Aggressive register usage (all 16 XMM) reduces memory traffic\n// The 16-wide approach's higher upfront cost is amortized by massive parallelism.\n\n// Separated mask precalculation per row.\ntemplate<MaskMode maskMode, typename pixel_t, bool lessthan16bits, bool is_chroma, bool use_chroma, bool has_alpha, bool subtract>\nstatic void layer_yuv_add_subtract_c(BYTE* dstp8, const BYTE* ovrp8, const BYTE* mask8, int dst_pitch, int overlay_pitch, int mask_pitch, int width, int height, int level, int bits_per_pixel) {\n  pixel_t* dstp = reinterpret_cast<pixel_t*>(dstp8);\n  const pixel_t* ovrp = reinterpret_cast<const pixel_t*>(ovrp8);\n  const pixel_t* maskp = reinterpret_cast<const pixel_t*>(mask8);\n  dst_pitch /= sizeof(pixel_t);\n  overlay_pitch /= sizeof(pixel_t);\n  mask_pitch /= sizeof(pixel_t);\n\n  typedef typename std::conditional<lessthan16bits, int, int64_t>::type calc_t;\n\n  if constexpr (sizeof(pixel_t) == 1)\n    bits_per_pixel = 8; // make quasi constexpr\n  else if constexpr (sizeof(pixel_t) == 2 && !lessthan16bits)\n    bits_per_pixel = 16; // make quasi constexpr\n\n  const int max_pixel_value = (1 << bits_per_pixel) - 1;\n  const int rounder = 1 << (bits_per_pixel - 1);\n\n  // Allocate temporary mask buffer\n  std::vector<pixel_t> effective_mask_buffer;\n  if constexpr (has_alpha && maskMode != MASK444) {\n    effective_mask_buffer.resize(width);\n  }\n\n  for (int y = 0; y < height; ++y) {\n    const pixel_t* effective_mask_ptr = nullptr;\n\n    // precalculate effective mask for this row\n    if constexpr (has_alpha) {\n      effective_mask_ptr = prepare_effective_mask_for_row<maskMode, pixel_t>(maskp, mask_pitch, width, effective_mask_buffer);\n    }\n\n    // Main blending loop - now simplified\n    for (int x = 0; x < width; ++x) {\n      int alpha_mask;\n      if constexpr (has_alpha) {\n        int effective_mask = effective_mask_ptr[x];\n        alpha_mask = (int)(((calc_t)effective_mask * level + 1) >> bits_per_pixel);\n      }\n      else {\n        alpha_mask = level;\n      }\n\n      if constexpr (subtract) {\n        if constexpr (!is_chroma || use_chroma) {\n          if constexpr (!is_chroma)\n            dstp[x] = (pixel_t)(dstp[x] + (((calc_t)(max_pixel_value - ovrp[x] - dstp[x]) * alpha_mask + rounder) >> bits_per_pixel));\n          else\n          {\n            const int half = 1 << (bits_per_pixel - 1);\n            dstp[x] = (pixel_t)(dstp[x] + (((calc_t)(2 * half - ovrp[x] - dstp[x]) * alpha_mask + rounder) >> bits_per_pixel));\n          }\n        }\n        else {\n          const int half = 1 << (bits_per_pixel - 1);\n          dstp[x] = (pixel_t)(dstp[x] + (((calc_t)(half - dstp[x]) * alpha_mask + rounder) >> bits_per_pixel));\n        }\n      }\n      else {\n        if constexpr (!is_chroma || use_chroma)\n          dstp[x] = (pixel_t)(dstp[x] + (((calc_t)(ovrp[x] - dstp[x]) * alpha_mask + rounder) >> bits_per_pixel));\n        else {\n          const int half = 1 << (bits_per_pixel - 1);\n          dstp[x] = (pixel_t)(dstp[x] + (((calc_t)(half - dstp[x]) * alpha_mask + rounder) >> bits_per_pixel));\n        }\n      }\n    }\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n    if constexpr (has_alpha) {\n      if constexpr (maskMode == MASK420 || maskMode == MASK420_MPEG2)\n        maskp += mask_pitch * 2;\n      else\n        maskp += mask_pitch;\n    }\n  }\n}\n\n// YUV(A) add/subtract 32 bits\ntemplate<MaskMode maskMode, bool is_chroma, bool use_chroma, bool has_alpha, bool subtract>\nstatic void layer_yuv_add_subtract_f_c(BYTE* dstp8, const BYTE* ovrp8, const BYTE* maskp8, int dst_pitch, int overlay_pitch, int mask_pitch, int width, int height, float opacity) {\n  float* dstp = reinterpret_cast<float*>(dstp8);\n  const float* ovrp = reinterpret_cast<const float*>(ovrp8);\n  const float* maskp = reinterpret_cast<const float*>(maskp8);\n  dst_pitch /= sizeof(float);\n  overlay_pitch /= sizeof(float);\n  mask_pitch /= sizeof(float);\n\n  // precalculate mask buffer\n  std::vector<float> effective_mask_buffer;\n  if constexpr (has_alpha && maskMode != MASK444) {\n    effective_mask_buffer.resize(width);\n  }\n\n  for (int y = 0; y < height; ++y) {\n    const float* effective_mask_ptr = nullptr;\n\n    // precalculate effective mask for this row\n    if constexpr (has_alpha) {\n      if constexpr (maskMode == MASK444) {\n        // Direct access to original mask - no pre-calculation needed\n        effective_mask_ptr = maskp;\n      }\n      else {\n        // Initialize sliding window state for MPEG2 modes\n        float mask_right = 0.0f;\n        if constexpr (maskMode == MASK420_MPEG2) {\n          mask_right = maskp[0] + maskp[0 + mask_pitch];\n        }\n        else if constexpr (maskMode == MASK422_MPEG2) {\n          mask_right = maskp[0];\n        }\n\n        // precalculate averaged mask values\n        for (int x = 0; x < width; ++x) {\n          effective_mask_buffer[x] = calculate_effective_mask_f<maskMode>(\n            maskp, x, mask_pitch, mask_right\n          );\n        }\n        effective_mask_ptr = effective_mask_buffer.data();\n      }\n    }\n\n    // Main blending loop - now simplified and vectorizable\n    for (int x = 0; x < width; ++x) {\n      float effective_mask = has_alpha ? effective_mask_ptr[x] : 0.0f;\n      float alpha_mask = has_alpha ? effective_mask * opacity : opacity;\n\n      if constexpr (subtract) {\n        constexpr float ref_pixel_value = is_chroma ? 0.0f : 1.0f;\n        if constexpr (!is_chroma || use_chroma) {\n          dstp[x] = dstp[x] + (ref_pixel_value - ovrp[x] - dstp[x]) * alpha_mask;\n        }\n        else {\n          dstp[x] = dstp[x] + (ref_pixel_value - dstp[x]) * alpha_mask;\n        }\n      }\n      else {\n        if constexpr (!is_chroma || use_chroma) {\n          dstp[x] = dstp[x] + (ovrp[x] - dstp[x]) * alpha_mask;\n        }\n        else {\n          constexpr float half = 0.0f;\n          dstp[x] = dstp[x] + (half - dstp[x]) * alpha_mask;\n        }\n      }\n    }\n    dstp += dst_pitch;\n    ovrp += overlay_pitch;\n    if constexpr (has_alpha) {\n      if constexpr (maskMode == MASK420 || maskMode == MASK420_MPEG2)\n        maskp += mask_pitch * 2;\n      else\n        maskp += mask_pitch;\n    }\n  }\n}\n\n// Unlike RGBA version, YUVA does not update destination alpha\ntemplate<int mode, MaskMode maskMode, typename pixel_t, bool lessthan16bits, bool lumaonly, bool has_alpha>\nstatic void layer_yuv_lighten_darken_c(\n  BYTE* dstp8, BYTE* dstp8_u, BYTE* dstp8_v,/* BYTE* dstp8_a,*/\n  const BYTE* ovrp8, const BYTE* ovrp8_u, const BYTE* ovrp8_v, const BYTE* maskp8,\n  int dst_pitch, int dst_pitchUV,\n  int overlay_pitch, int overlay_pitchUV,\n  int mask_pitch,\n  int width, int height, int level, int thresh,\n  int bits_per_pixel) {\n\n  pixel_t* dstp = reinterpret_cast<pixel_t*>(dstp8);\n  pixel_t* dstp_u = reinterpret_cast<pixel_t*>(dstp8_u);\n  pixel_t* dstp_v = reinterpret_cast<pixel_t*>(dstp8_v);\n  // pixel_t* dstp_a = reinterpret_cast<pixel_t *>(dstp8_a); // not destination alpha update\n\n  const pixel_t* ovrp = reinterpret_cast<const pixel_t*>(ovrp8);\n  const pixel_t* ovrp_u = reinterpret_cast<const pixel_t*>(ovrp8_u);\n  const pixel_t* ovrp_v = reinterpret_cast<const pixel_t*>(ovrp8_v);\n  const pixel_t* maskp = reinterpret_cast<const pixel_t*>(maskp8);\n\n  dst_pitch /= sizeof(pixel_t);\n  dst_pitchUV /= sizeof(pixel_t);\n  overlay_pitch /= sizeof(pixel_t);\n  overlay_pitchUV /= sizeof(pixel_t);\n  mask_pitch /= sizeof(pixel_t);\n\n  const int cwidth = (maskMode == MASK444) ? width : (maskMode == MASK411) ? width >> 2 : width >> 1; // 444:/1  420,422:/2  411:/4\n  const int cheight = (maskMode == MASK444 || maskMode == MASK422 || maskMode == MASK422_MPEG2 || maskMode == MASK411) ? height : height >> 1; // 444,422,411:/1  420:/2\n\n  // In lighten/darken we need 3 buffers:\n  std::vector<pixel_t> ovr_buffer;\n  std::vector<pixel_t> src_buffer;\n  std::vector<pixel_t> mask_buffer;\n\n  // precalculate mask buffer et al.\n  if constexpr (maskMode != MASK444) {\n    ovr_buffer.resize(cwidth);\n    src_buffer.resize(cwidth);\n    if constexpr (has_alpha)\n      mask_buffer.resize(cwidth);\n  }\n\n  using calc_t = typename std::conditional < lessthan16bits, int, int64_t>::type; // for non-overflowing 16 bit alpha_mul\n  if constexpr (sizeof(pixel_t) == 1)\n    bits_per_pixel = 8; // make quasi constexpr\n  else if constexpr (sizeof(pixel_t) == 2 && !lessthan16bits)\n    bits_per_pixel = 16; // make quasi constexpr\n\n  const int rounder = 1 << (bits_per_pixel - 1);\n\n  // for subsampled color spaces first do chroma, luma is only used for decision\n  // second pass will do luma only\n  for (int y = 0; y < cheight; ++y) {\n\n    // Prepare all three pointers using the helper\n    const pixel_t* ovr_ptr = prepare_effective_mask_for_row<maskMode, pixel_t>(ovrp, overlay_pitch, cwidth, ovr_buffer);\n    const pixel_t* src_ptr = prepare_effective_mask_for_row<maskMode, pixel_t>(dstp, dst_pitch, cwidth, src_buffer);\n    const pixel_t* effective_mask_ptr = nullptr;\n    if constexpr (has_alpha) {\n      effective_mask_ptr = prepare_effective_mask_for_row<maskMode, pixel_t>(maskp, mask_pitch, cwidth, mask_buffer);\n    }\n\n    for (int x = 0; x < cwidth; ++x) {\n      int ovr = ovr_ptr[x];\n      int src = src_ptr[x];\n      int effective_mask = has_alpha ? effective_mask_ptr[x] : 0;\n\n      const int alpha = has_alpha ? (int)(((calc_t)effective_mask * level + 1) >> bits_per_pixel) : level;\n\n      int alpha_mask;\n      if constexpr (mode == LIGHTEN)\n        alpha_mask = ovr > (src + thresh) ? alpha : 0; // YUY2 was wrong: alpha_mask = (thresh + ovr) > src ? level : 0;\n      else // DARKEN\n        alpha_mask = ovr < (src - thresh) ? alpha : 0; // YUY2 was wrong: alpha_mask = (thresh + src) > ovr ? level : 0;\n\n      if constexpr (!lumaonly)\n      {\n        // chroma u,v\n        dstp_u[x] = dstp_u[x] + (int)(((calc_t)(ovrp_u[x] - dstp_u[x]) * alpha_mask + rounder) >> bits_per_pixel);\n        dstp_v[x] = dstp_v[x] + (int)(((calc_t)(ovrp_v[x] - dstp_v[x]) * alpha_mask + rounder) >> bits_per_pixel);\n      }\n\n      // for 444: update here, width/height is the same as for chroma\n      if constexpr (maskMode == MASK444)\n        dstp[x] = dstp[x] + (int)(((calc_t)(ovrp[x] - dstp[x]) * alpha_mask + rounder) >> bits_per_pixel);\n    }\n    if constexpr (maskMode == MASK420 || maskMode == MASK420_MPEG2) {\n      dstp += dst_pitch * 2; // skip vertical subsampling\n      ovrp += overlay_pitch * 2;\n      if constexpr (has_alpha) {\n        //dstp_a += dst_pitch * 2;\n        maskp += mask_pitch * 2;\n      }\n    }\n    else {\n      dstp += dst_pitch;\n      ovrp += overlay_pitch;\n      if constexpr (has_alpha) {\n        //dstp_a += dst_pitch;\n        maskp += mask_pitch;\n      }\n    }\n\n    if constexpr (!lumaonly) {\n      dstp_u += dst_pitchUV;\n      dstp_v += dst_pitchUV;\n      ovrp_u += overlay_pitchUV;\n      ovrp_v += overlay_pitchUV;\n    }\n\n  }\n\n  dst_pitch *= sizeof(pixel_t);\n  dst_pitchUV *= sizeof(pixel_t);\n  overlay_pitch *= sizeof(pixel_t);\n  overlay_pitchUV *= sizeof(pixel_t);\n  mask_pitch *= sizeof(pixel_t);\n\n  // make luma\n  if constexpr (!lumaonly && maskMode != MASK444)\n    layer_yuv_lighten_darken_c<mode, MASK444, pixel_t, lessthan16bits, true /* lumaonly*/, has_alpha>(\n      dstp8, dstp8_u, dstp8_v, //dstp8_a,\n      ovrp8, ovrp8_u, ovrp8_v, maskp8,\n      dst_pitch, dst_pitchUV, overlay_pitch, overlay_pitchUV, mask_pitch,\n      width, height, level, thresh, bits_per_pixel);\n}\n\ntemplate<int mode, MaskMode maskMode, bool lumaonly, bool has_alpha>\nstatic void layer_yuv_lighten_darken_f_c(\n  BYTE* dstp8, BYTE* dstp8_u, BYTE* dstp8_v /*, BYTE* dstp8_a*/,\n  const BYTE* ovrp8, const BYTE* ovrp8_u, const BYTE* ovrp8_v, const BYTE* maskp8,\n  int dst_pitch, int dst_pitchUV,\n  int overlay_pitch, int overlay_pitchUV,\n  int mask_pitch,\n  int width, int height, float opacity, float thresh) {\n\n  float* dstp = reinterpret_cast<float*>(dstp8);\n  float* dstp_u = reinterpret_cast<float*>(dstp8_u);\n  float* dstp_v = reinterpret_cast<float*>(dstp8_v);\n  //float* dstp_a = reinterpret_cast<float *>(dstp8_a);\n\n  const float* ovrp = reinterpret_cast<const float*>(ovrp8);\n  const float* ovrp_u = reinterpret_cast<const float*>(ovrp8_u);\n  const float* ovrp_v = reinterpret_cast<const float*>(ovrp8_v);\n  const float* maskp = reinterpret_cast<const float*>(maskp8);\n\n  dst_pitch /= sizeof(float);\n  dst_pitchUV /= sizeof(float);\n  overlay_pitch /= sizeof(float);\n  overlay_pitchUV /= sizeof(float);\n  mask_pitch /= sizeof(float);\n\n  const int cwidth = (maskMode == MASK444) ? width : (maskMode == MASK411) ? width >> 2 : width >> 1; // 444:/1  420,422:/2  411:/4\n  const int cheight = (maskMode == MASK444 || maskMode == MASK422 || maskMode == MASK422_MPEG2 || maskMode == MASK411) ? height : height >> 1; // 444,422,411:/1  420:/2\n\n  // In lighten/darken we need 3 buffers:\n  std::vector<float> ovr_buffer;\n  std::vector<float> src_buffer;\n  std::vector<float> mask_buffer;\n\n  // precalculate mask buffer et al.\n  if constexpr (maskMode != MASK444) {\n    ovr_buffer.resize(cwidth);\n    src_buffer.resize(cwidth);\n    if constexpr (has_alpha)\n      mask_buffer.resize(cwidth);\n  }\n\n  // for subsampled color spaces first do chroma, because luma is used for decision\n  // second pass will do luma only\n  for (int y = 0; y < cheight; ++y) {\n    const float* ovr_ptr = prepare_effective_mask_for_row_f<maskMode>(ovrp, overlay_pitch, cwidth, ovr_buffer);\n    const float* src_ptr = prepare_effective_mask_for_row_f<maskMode>(dstp, dst_pitch, cwidth, src_buffer);\n    const float* effective_mask_ptr = nullptr;\n    if constexpr (has_alpha) {\n      effective_mask_ptr = prepare_effective_mask_for_row_f<maskMode>(maskp, mask_pitch, cwidth, mask_buffer);\n    }\n\n    for (int x = 0; x < cwidth; ++x) {\n      float ovr = ovr_ptr[x];\n      float src = src_ptr[x];\n      float effective_mask = has_alpha ? effective_mask_ptr[x] : 0;\n\n      const float alpha = has_alpha ? effective_mask * opacity : opacity;\n\n      float alpha_mask;\n      if constexpr (mode == LIGHTEN)\n        alpha_mask = ovr > (src + thresh) ? alpha : 0; // YUY2 was wrong: alpha_mask = (thresh + ovr) > src ? level : 0;\n      else // DARKEN\n        alpha_mask = ovr < (src - thresh) ? alpha : 0; // YUY2 was wrong: alpha_mask = (thresh + src) > ovr ? level : 0;\n\n      if constexpr (!lumaonly)\n      {\n        // chroma u,v\n        dstp_u[x] = dstp_u[x] + (ovrp_u[x] - dstp_u[x]) * alpha_mask;\n        dstp_v[x] = dstp_v[x] + (ovrp_v[x] - dstp_v[x]) * alpha_mask;\n        //dstp_a[x] = dstp_a[x] + (maskp[x] - dstp_a[x]) * alpha_mask;\n      }\n\n      // for 444: update here, width/height is the same as for chroma\n      if constexpr (maskMode == MASK444)\n        dstp[x] = dstp[x] + (ovrp[x] - dstp[x]) * alpha_mask;\n    }\n    if constexpr (maskMode == MASK420 || maskMode == MASK420_MPEG2) {\n      dstp += dst_pitch * 2; // skip vertical subsampling\n      ovrp += overlay_pitch * 2;\n      if constexpr (has_alpha) {\n        //dstp_a += dst_pitch * 2;\n        maskp += mask_pitch * 2;\n      }\n    }\n    else {\n      dstp += dst_pitch;\n      ovrp += overlay_pitch;\n      if constexpr (has_alpha) {\n        //dstp_a += dst_pitch;\n        maskp += mask_pitch;\n      }\n    }\n\n    if constexpr (!lumaonly) {\n      dstp_u += dst_pitchUV;\n      dstp_v += dst_pitchUV;\n      ovrp_u += overlay_pitchUV;\n      ovrp_v += overlay_pitchUV;\n    }\n  }\n\n  dst_pitch *= sizeof(float);\n  dst_pitchUV *= sizeof(float);\n  overlay_pitch *= sizeof(float);\n  overlay_pitchUV *= sizeof(float);\n  mask_pitch *= sizeof(float);\n\n  // make luma\n  if constexpr (!lumaonly && maskMode != MASK444)\n    layer_yuv_lighten_darken_f_c<mode, MASK444, true /* lumaonly*/, has_alpha>(\n      dstp8, dstp8_u, dstp8_v, //dstp8_a,\n      ovrp8, ovrp8_u, ovrp8_v, maskp8,\n      dst_pitch, dst_pitchUV, overlay_pitch, overlay_pitchUV, mask_pitch,\n      width, height, opacity, thresh);\n}\n\nDISABLE_WARNING_POP\n\n// Dispatchers\n\nstatic void get_layer_yuv_lighten_darken_functions(bool isLighten, int placement, VideoInfo& vi, int bits_per_pixel, /*out*/layer_yuv_lighten_darken_c_t** layer_fn, /*out*/layer_yuv_lighten_darken_f_c_t** layer_f_fn) {\n\n#define YUV_LIGHTEN_DARKEN_DISPATCH(L_or_D, MaskType, lumaonly, has_alpha) \\\n      { if (bits_per_pixel == 8) \\\n        *layer_fn = layer_yuv_lighten_darken_c<L_or_D, MaskType, uint8_t, true /*lessthan16bits*/, lumaonly /*lumaonly*/, has_alpha /*has_alpha*/>; \\\n      else if (bits_per_pixel < 16) \\\n        *layer_fn = layer_yuv_lighten_darken_c<L_or_D, MaskType, uint16_t, true/*lessthan16bits*/, lumaonly /*lumaonly*/, has_alpha /*has_alpha*/>; \\\n      else if (bits_per_pixel == 16) \\\n        *layer_fn = layer_yuv_lighten_darken_c<L_or_D, MaskType, uint16_t, false/*lessthan16bits*/, lumaonly /*lumaonly*/, has_alpha /*has_alpha*/>; \\\n      else /* float */ \\\n        *layer_f_fn = layer_yuv_lighten_darken_f_c<L_or_D, MaskType, lumaonly /*lumaonly*/, has_alpha /*has_alpha*/>; \\\n}\n\n  if (isLighten) {\n\n    if (vi.IsYV411())\n      *layer_fn = layer_yuv_lighten_darken_c<LIGHTEN, MASK411, uint8_t, true /*lessthan16bits*/, false /*lumaonly*/, false /*has_alpha*/>;\n    else if (vi.Is420())\n    {\n      if (placement == PLACEMENT_MPEG1)\n        YUV_LIGHTEN_DARKEN_DISPATCH(LIGHTEN, MASK420, false, false)\n      else\n        YUV_LIGHTEN_DARKEN_DISPATCH(LIGHTEN, MASK420_MPEG2, false, false)\n        // PLACEMENT_MPEG2\n    }\n    else if (vi.Is422())\n    {\n      if (placement == PLACEMENT_MPEG1)\n        YUV_LIGHTEN_DARKEN_DISPATCH(LIGHTEN, MASK422, false, false)\n      else\n        YUV_LIGHTEN_DARKEN_DISPATCH(LIGHTEN, MASK422_MPEG2, false, false)\n        // PLACEMENT_MPEG2\n    }\n    else if (vi.Is444())\n      YUV_LIGHTEN_DARKEN_DISPATCH(LIGHTEN, MASK444, false, false)\n    else if (vi.IsY())\n      YUV_LIGHTEN_DARKEN_DISPATCH(LIGHTEN, MASK444, true, false)\n  }\n  else {\n    // darken\n    if (vi.IsYV411())\n      *layer_fn = layer_yuv_lighten_darken_c<DARKEN, MASK411, uint8_t, true /*lessthan16bits*/, false /*lumaonly*/, false /*has_alpha*/>;\n    else if (vi.Is420())\n    {\n      if (placement == PLACEMENT_MPEG1)\n        YUV_LIGHTEN_DARKEN_DISPATCH(DARKEN, MASK420, false, false)\n      else // PLACEMENT_MPEG2\n        YUV_LIGHTEN_DARKEN_DISPATCH(DARKEN, MASK420_MPEG2, false, false)\n    }\n    else if (vi.Is422())\n    {\n      if (placement == PLACEMENT_MPEG1)\n        YUV_LIGHTEN_DARKEN_DISPATCH(DARKEN, MASK422, false, false)\n      else // PLACEMENT_MPEG2\n        YUV_LIGHTEN_DARKEN_DISPATCH(DARKEN, MASK422_MPEG2, false, false)\n    }\n    else if (vi.Is444())\n      YUV_LIGHTEN_DARKEN_DISPATCH(DARKEN, MASK444, false, false)\n    else if (vi.IsY())\n      YUV_LIGHTEN_DARKEN_DISPATCH(DARKEN, MASK444, true, false)\n  }\n#undef YUV_LIGHTEN_DARKEN_DISPATCH\n}\n\n\nstatic void get_layer_yuv_mul_functions(\n  bool is_chroma, bool use_chroma, bool hasAlpha,\n  int placement, VideoInfo& vi, int bits_per_pixel,\n  /*out*/layer_yuv_mul_c_t** layer_fn,\n  /*out*/layer_yuv_mul_f_c_t** layer_f_fn)\n{\n#define YUV_MUL_DISPATCH(MaskType, is_chroma, use_chroma, has_alpha) \\\n  { if (bits_per_pixel == 8) \\\n    *layer_fn = layer_yuv_mul_c<MaskType, uint8_t, true /*lessthan16bits*/, is_chroma, use_chroma, has_alpha>; \\\n  else if (bits_per_pixel < 16) \\\n    *layer_fn = layer_yuv_mul_c<MaskType, uint16_t, true /*lessthan16bits*/, is_chroma, use_chroma, has_alpha>; \\\n  else if (bits_per_pixel == 16) \\\n    *layer_fn = layer_yuv_mul_c<MaskType, uint16_t, false /*lessthan16bits*/, is_chroma, use_chroma, has_alpha>; \\\n  else /* float */ \\\n    *layer_f_fn = layer_yuv_mul_f_c<MaskType, is_chroma, use_chroma, has_alpha>; \\\n  }\n\n  if (is_chroma) // not luma channel\n  {\n    if (vi.IsYV411())\n    {\n      if (use_chroma)\n        *layer_fn = layer_yuv_mul_c<MASK411, uint8_t, true /*lessthan16bits*/, true, true, false>;\n      else\n        *layer_fn = layer_yuv_mul_c<MASK411, uint8_t, true /*lessthan16bits*/, true, false, false>;\n    }\n    else if (vi.Is420())\n    {\n      if (placement == PLACEMENT_MPEG1) {\n        if (hasAlpha) {\n          if (use_chroma) YUV_MUL_DISPATCH(MASK420, true, true, true)\n          else YUV_MUL_DISPATCH(MASK420, true, false, true)\n        }\n        else {\n          if (use_chroma) YUV_MUL_DISPATCH(MASK420, true, true, false)\n          else YUV_MUL_DISPATCH(MASK420, true, false, false)\n        }\n      }\n      else {\n        if (hasAlpha) {\n          if (use_chroma) YUV_MUL_DISPATCH(MASK420_MPEG2, true, true, true)\n          else YUV_MUL_DISPATCH(MASK420_MPEG2, true, false, true)\n        }\n        else {\n          if (use_chroma) YUV_MUL_DISPATCH(MASK420_MPEG2, true, true, false)\n          else YUV_MUL_DISPATCH(MASK420_MPEG2, true, false, false)\n        }\n      }\n    }\n    else if (vi.Is422())\n    {\n      if (placement == PLACEMENT_MPEG1) {\n        if (hasAlpha) {\n          if (use_chroma) YUV_MUL_DISPATCH(MASK422, true, true, true)\n          else YUV_MUL_DISPATCH(MASK422, true, false, true)\n        }\n        else {\n          if (use_chroma) YUV_MUL_DISPATCH(MASK422, true, true, false)\n          else YUV_MUL_DISPATCH(MASK422, true, false, false)\n        }\n      }\n      else {\n        if (hasAlpha) {\n          if (use_chroma) YUV_MUL_DISPATCH(MASK422_MPEG2, true, true, true)\n          else YUV_MUL_DISPATCH(MASK422_MPEG2, true, false, true)\n        }\n        else {\n          if (use_chroma) YUV_MUL_DISPATCH(MASK422_MPEG2, true, true, false)\n          else YUV_MUL_DISPATCH(MASK422_MPEG2, true, false, false)\n        }\n      }\n    }\n    else if (vi.Is444())\n    {\n      if (hasAlpha) {\n        if (use_chroma) YUV_MUL_DISPATCH(MASK444, true, true, true)\n        else YUV_MUL_DISPATCH(MASK444, true, false, true)\n      }\n      else {\n        if (use_chroma) YUV_MUL_DISPATCH(MASK444, true, true, false)\n        else YUV_MUL_DISPATCH(MASK444, true, false, false)\n      }\n    }\n  }\n  else // luma channel\n  {\n    if (hasAlpha)\n      YUV_MUL_DISPATCH(MASK444, false, false, true)\n    else\n      YUV_MUL_DISPATCH(MASK444, false, false, false)\n  }\n#undef YUV_MUL_DISPATCH\n}\n\ntemplate<bool is_subtract>\nstatic void get_layer_yuv_add_subtract_functions(\n  bool is_chroma, bool use_chroma, bool hasAlpha,\n  int placement, VideoInfo& vi, int bits_per_pixel,\n  /*out*/layer_yuv_add_subtract_c_t** layer_fn,\n  /*out*/layer_yuv_add_subtract_f_c_t** layer_f_fn)\n{\n#define YUV_ADD_SUBTRACT_DISPATCH(MaskType, is_chroma, use_chroma, has_alpha) \\\n  { if (bits_per_pixel == 8) \\\n    *layer_fn = layer_yuv_add_subtract_c<MaskType, uint8_t, true /*lessthan16bits*/, is_chroma, use_chroma, has_alpha, is_subtract>; \\\n  else if (bits_per_pixel < 16) \\\n    *layer_fn = layer_yuv_add_subtract_c<MaskType, uint16_t, true /*lessthan16bits*/, is_chroma, use_chroma, has_alpha, is_subtract>; \\\n  else if (bits_per_pixel == 16) \\\n    *layer_fn = layer_yuv_add_subtract_c<MaskType, uint16_t, false /*lessthan16bits*/, is_chroma, use_chroma, has_alpha, is_subtract>; \\\n  else /* float */ \\\n    *layer_f_fn = layer_yuv_add_subtract_f_c<MaskType, is_chroma, use_chroma, has_alpha, is_subtract>; \\\n  }\n\n  if (is_chroma) // not luma channel\n  {\n    if (vi.IsYV411())\n    {\n      if (use_chroma)\n        *layer_fn = layer_yuv_add_subtract_c<MASK411, uint8_t, true /*lessthan16bits*/, true, true, false, is_subtract>;\n      else\n        *layer_fn = layer_yuv_add_subtract_c<MASK411, uint8_t, true /*lessthan16bits*/, true, false, false, is_subtract>;\n    }\n    else if (vi.Is420())\n    {\n      if (placement == PLACEMENT_MPEG1) {\n        if (hasAlpha) {\n          if (use_chroma) YUV_ADD_SUBTRACT_DISPATCH(MASK420, true, true, true)\n          else YUV_ADD_SUBTRACT_DISPATCH(MASK420, true, false, true)\n        }\n        else {\n          if (use_chroma) YUV_ADD_SUBTRACT_DISPATCH(MASK420, true, true, false)\n          else YUV_ADD_SUBTRACT_DISPATCH(MASK420, true, false, false)\n        }\n      }\n      else {\n        if (hasAlpha) {\n          if (use_chroma) YUV_ADD_SUBTRACT_DISPATCH(MASK420_MPEG2, true, true, true)\n          else YUV_ADD_SUBTRACT_DISPATCH(MASK420_MPEG2, true, false, true)\n        }\n        else {\n          if (use_chroma) YUV_ADD_SUBTRACT_DISPATCH(MASK420_MPEG2, true, true, false)\n          else YUV_ADD_SUBTRACT_DISPATCH(MASK420_MPEG2, true, false, false)\n        }\n      }\n    }\n    else if (vi.Is422())\n    {\n      if (placement == PLACEMENT_MPEG1) {\n        if (hasAlpha) {\n          if (use_chroma) YUV_ADD_SUBTRACT_DISPATCH(MASK422, true, true, true)\n          else YUV_ADD_SUBTRACT_DISPATCH(MASK422, true, false, true)\n        }\n        else {\n          if (use_chroma) YUV_ADD_SUBTRACT_DISPATCH(MASK422, true, true, false)\n          else YUV_ADD_SUBTRACT_DISPATCH(MASK422, true, false, false)\n        }\n      }\n      else {\n        if (hasAlpha) {\n          if (use_chroma) YUV_ADD_SUBTRACT_DISPATCH(MASK422_MPEG2, true, true, true)\n          else YUV_ADD_SUBTRACT_DISPATCH(MASK422_MPEG2, true, false, true)\n        }\n        else {\n          if (use_chroma) YUV_ADD_SUBTRACT_DISPATCH(MASK422_MPEG2, true, true, false)\n          else YUV_ADD_SUBTRACT_DISPATCH(MASK422_MPEG2, true, false, false)\n        }\n      }\n    }\n    else if (vi.Is444())\n    {\n      if (hasAlpha) {\n        if (use_chroma) YUV_ADD_SUBTRACT_DISPATCH(MASK444, true, true, true)\n        else YUV_ADD_SUBTRACT_DISPATCH(MASK444, true, false, true)\n      }\n      else {\n        if (use_chroma) YUV_ADD_SUBTRACT_DISPATCH(MASK444, true, true, false)\n        else YUV_ADD_SUBTRACT_DISPATCH(MASK444, true, false, false)\n      }\n    }\n  }\n  else // luma channel\n  {\n    if (hasAlpha)\n      YUV_ADD_SUBTRACT_DISPATCH(MASK444, false, false, true)\n    else\n      YUV_ADD_SUBTRACT_DISPATCH(MASK444, false, false, false)\n  }\n#undef YUV_ADD_SUBTRACT_DISPATCH\n}\n\n/* planar rgb */\n\ntemplate<int mode, typename pixel_t, bool lessthan16bits, bool has_alpha>\nstatic void layer_planarrgb_lighten_darken_c(BYTE** dstp8, const BYTE** ovrp8, int dst_pitch, int overlay_pitch, int width, int height, int level, int thresh, int bits_per_pixel) {\n  pixel_t* dstp_g = reinterpret_cast<pixel_t*>(dstp8[0]);\n  pixel_t* dstp_b = reinterpret_cast<pixel_t*>(dstp8[1]);\n  pixel_t* dstp_r = reinterpret_cast<pixel_t*>(dstp8[2]);\n  pixel_t* dstp_a = reinterpret_cast<pixel_t*>(dstp8[3]);\n  const pixel_t* ovrp_g = reinterpret_cast<const pixel_t*>(ovrp8[0]);\n  const pixel_t* ovrp_b = reinterpret_cast<const pixel_t*>(ovrp8[1]);\n  const pixel_t* ovrp_r = reinterpret_cast<const pixel_t*>(ovrp8[2]);\n  const pixel_t* maskp = reinterpret_cast<const pixel_t*>(ovrp8[3]);\n\n  dst_pitch /= sizeof(pixel_t);\n  overlay_pitch /= sizeof(pixel_t);\n\n  using calc_t = typename std::conditional < lessthan16bits, int, int64_t>::type; // for non-overflowing 16 bit alpha_mul\n  if constexpr (sizeof(pixel_t) == 1)\n    bits_per_pixel = 8; // make quasi constexpr\n  else if constexpr (sizeof(pixel_t) == 2 && !lessthan16bits)\n    bits_per_pixel = 16; // make quasi constexpr\n\n  const int rounder = 1 << (bits_per_pixel - 1);\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; ++x) {\n      calc_t alpha = has_alpha ? ((calc_t)maskp[x] * level + 1) >> bits_per_pixel : level;\n\n      calc_t luma_ovr = (cyb * ovrp_b[x] + cyg * ovrp_g[x] + cyr * ovrp_r[x]) >> 15; // no rounding, not really needed here\n      calc_t luma_src = (cyb * dstp_b[x] + cyg * dstp_g[x] + cyr * dstp_r[x]) >> 15;\n\n      if constexpr (mode == LIGHTEN)\n        alpha = luma_ovr > luma_src + thresh ? alpha : 0;\n      else // DARKEN\n        alpha = luma_ovr < luma_src - thresh ? alpha : 0;\n\n      dstp_r[x] = (pixel_t)(dstp_r[x] + (((ovrp_r[x] - dstp_r[x]) * alpha + rounder) >> bits_per_pixel));\n      dstp_g[x] = (pixel_t)(dstp_g[x] + (((ovrp_g[x] - dstp_g[x]) * alpha + rounder) >> bits_per_pixel));\n      dstp_b[x] = (pixel_t)(dstp_b[x] + (((ovrp_b[x] - dstp_b[x]) * alpha + rounder) >> bits_per_pixel));\n      if constexpr (has_alpha)\n        dstp_a[x] = (pixel_t)(dstp_a[x] + (((maskp[x] - dstp_a[x]) * alpha + rounder) >> bits_per_pixel));\n    }\n    dstp_g += dst_pitch;\n    dstp_b += dst_pitch;\n    dstp_r += dst_pitch;\n    if constexpr (has_alpha)\n      dstp_a += dst_pitch;\n    ovrp_g += overlay_pitch;\n    ovrp_b += overlay_pitch;\n    ovrp_r += overlay_pitch;\n    if constexpr (has_alpha)\n      maskp += overlay_pitch;\n  }\n}\n\ntemplate<int mode, bool has_alpha>\nstatic void layer_planarrgb_lighten_darken_f_c(BYTE** dstp8, const BYTE** ovrp8, int dst_pitch, int overlay_pitch, int width, int height, float opacity, float thresh) {\n  float* dstp_g = reinterpret_cast<float*>(dstp8[0]);\n  float* dstp_b = reinterpret_cast<float*>(dstp8[1]);\n  float* dstp_r = reinterpret_cast<float*>(dstp8[2]);\n  float* dstp_a = reinterpret_cast<float*>(dstp8[3]);\n  const float* ovrp_g = reinterpret_cast<const float*>(ovrp8[0]);\n  const float* ovrp_b = reinterpret_cast<const float*>(ovrp8[1]);\n  const float* ovrp_r = reinterpret_cast<const float*>(ovrp8[2]);\n  const float* maskp = reinterpret_cast<const float*>(ovrp8[3]);\n\n  dst_pitch /= sizeof(float);\n  overlay_pitch /= sizeof(float);\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; ++x) {\n      float alpha = has_alpha ? maskp[x] * opacity : opacity;\n\n      float luma_ovr = cyb_f * ovrp_b[x] + cyg_f * ovrp_g[x] + cyr_f * ovrp_r[x];\n      float luma_src = cyb_f * dstp_b[x] + cyg_f * dstp_g[x] + cyr_f * dstp_r[x];\n\n      if constexpr (mode == LIGHTEN)\n        alpha = luma_ovr > luma_src + thresh ? alpha : 0;\n      else // DARKEN\n        alpha = luma_ovr < luma_src - thresh ? alpha : 0;\n\n      dstp_r[x] = dstp_r[x] + (ovrp_r[x] - dstp_r[x]) * alpha;\n      dstp_g[x] = dstp_g[x] + (ovrp_g[x] - dstp_g[x]) * alpha;\n      dstp_b[x] = dstp_b[x] + (ovrp_b[x] - dstp_b[x]) * alpha;\n      if constexpr (has_alpha)\n        dstp_a[x] = dstp_a[x] + (maskp[x] - dstp_a[x]) * alpha;\n    }\n    dstp_g += dst_pitch;\n    dstp_b += dst_pitch;\n    dstp_r += dst_pitch;\n    if constexpr (has_alpha)\n      dstp_a += dst_pitch;\n    ovrp_g += overlay_pitch;\n    ovrp_b += overlay_pitch;\n    ovrp_r += overlay_pitch;\n    if constexpr (has_alpha)\n      maskp += overlay_pitch;\n  }\n}\n\n\nstatic void get_layer_planarrgb_lighten_darken_functions(bool isLighten, bool hasAlpha, int bits_per_pixel, /*out*/layer_planarrgb_lighten_darken_c_t** layer_fn, /*out*/layer_planarrgb_lighten_darken_f_c_t** layer_f_fn) {\n\n#define PLANARRGB_LD_DISPATCH(LorD, has_alpha) \\\n      { if (bits_per_pixel == 8) \\\n        *layer_fn = layer_planarrgb_lighten_darken_c<LorD, uint8_t, true /*lessthan16bits*/, has_alpha>; \\\n      else if (bits_per_pixel < 16) \\\n        *layer_fn = layer_planarrgb_lighten_darken_c<LorD, uint16_t, true /*lessthan16bits*/, has_alpha>; \\\n      else if (bits_per_pixel == 16) \\\n        *layer_fn = layer_planarrgb_lighten_darken_c<LorD, uint16_t, false /*lessthan16bits*/, has_alpha>; \\\n      else /* float */ \\\n        *layer_f_fn = layer_planarrgb_lighten_darken_f_c<LorD, has_alpha>; \\\n      }\n\n  if (isLighten) {\n    if (hasAlpha) {\n      PLANARRGB_LD_DISPATCH(LIGHTEN, true)\n    }\n    else {\n      PLANARRGB_LD_DISPATCH(LIGHTEN, false)\n    }\n  } // lighten end\n  else {\n    if (hasAlpha) {\n      PLANARRGB_LD_DISPATCH(DARKEN, true)\n    }\n    else {\n      PLANARRGB_LD_DISPATCH(DARKEN, false)\n    }\n  }\n#undef PLANARRGB_LD_DISPATCH\n}\n\ntemplate<typename pixel_t, bool lessthan16bits, bool chroma, bool has_alpha, bool subtract>\nstatic void layer_planarrgb_add_subtract_c(BYTE** dstp8, const BYTE** ovrp8, int dst_pitch, int overlay_pitch, int width, int height, int level, int bits_per_pixel) {\n  pixel_t* dstp_g = reinterpret_cast<pixel_t*>(dstp8[0]);\n  pixel_t* dstp_b = reinterpret_cast<pixel_t*>(dstp8[1]);\n  pixel_t* dstp_r = reinterpret_cast<pixel_t*>(dstp8[2]);\n  pixel_t* dstp_a = reinterpret_cast<pixel_t*>(dstp8[3]);\n  const pixel_t* ovrp_g = reinterpret_cast<const pixel_t*>(ovrp8[0]);\n  const pixel_t* ovrp_b = reinterpret_cast<const pixel_t*>(ovrp8[1]);\n  const pixel_t* ovrp_r = reinterpret_cast<const pixel_t*>(ovrp8[2]);\n  const pixel_t* maskp = reinterpret_cast<const pixel_t*>(ovrp8[3]);\n\n  dst_pitch /= sizeof(pixel_t);\n  overlay_pitch /= sizeof(pixel_t);\n\n  using calc_t = typename std::conditional < lessthan16bits, int, int64_t>::type; // for non-overflowing 16 bit alpha_mul\n  if constexpr (sizeof(pixel_t) == 1)\n    bits_per_pixel = 8; // make quasi constexpr\n  else if constexpr (sizeof(pixel_t) == 2 && !lessthan16bits)\n    bits_per_pixel = 16; // make quasi constexpr\n\n  const int max_pixel_value = (1 << bits_per_pixel) - 1;\n\n  const int rounder = 1 << (bits_per_pixel - 1);\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; ++x) {\n      calc_t alpha = has_alpha ? ((calc_t)maskp[x] * level + 1) >> bits_per_pixel : level;\n      if constexpr (subtract) {\n        // subtract\n        if constexpr (chroma) {\n          dstp_r[x] = (pixel_t)(dstp_r[x] + (((max_pixel_value - ovrp_r[x] - dstp_r[x]) * alpha + rounder) >> bits_per_pixel));\n          dstp_g[x] = (pixel_t)(dstp_g[x] + (((max_pixel_value - ovrp_g[x] - dstp_g[x]) * alpha + rounder) >> bits_per_pixel));\n          dstp_b[x] = (pixel_t)(dstp_b[x] + (((max_pixel_value - ovrp_b[x] - dstp_b[x]) * alpha + rounder) >> bits_per_pixel));\n          if constexpr (has_alpha) // fixme: to be decided. YUV does not update target alpha, rgb32 does\n            dstp_a[x] = (pixel_t)(dstp_a[x] + (((max_pixel_value - maskp[x] - dstp_a[x]) * alpha + rounder) >> bits_per_pixel));\n        }\n        else { // use luma instead of overlay\n          calc_t luma = (cyb * (max_pixel_value - ovrp_b[x]) + cyg * (max_pixel_value - ovrp_g[x]) + cyr * (max_pixel_value - ovrp_r[x])) >> 15; // no rounding not really needed here\n\n          dstp_r[x] = (pixel_t)(dstp_r[x] + (((luma - dstp_r[x]) * alpha + rounder) >> bits_per_pixel));\n          dstp_g[x] = (pixel_t)(dstp_g[x] + (((luma - dstp_g[x]) * alpha + rounder) >> bits_per_pixel));\n          dstp_b[x] = (pixel_t)(dstp_b[x] + (((luma - dstp_b[x]) * alpha + rounder) >> bits_per_pixel));\n          if constexpr (has_alpha)\n            dstp_a[x] = (pixel_t)(dstp_a[x] + (((luma - dstp_a[x]) * alpha + rounder) >> bits_per_pixel));\n        }\n      }\n      else {\n        // add\n        if constexpr (chroma) {\n          dstp_r[x] = (pixel_t)(dstp_r[x] + (((ovrp_r[x] - dstp_r[x]) * alpha + rounder) >> bits_per_pixel));\n          dstp_g[x] = (pixel_t)(dstp_g[x] + (((ovrp_g[x] - dstp_g[x]) * alpha + rounder) >> bits_per_pixel));\n          dstp_b[x] = (pixel_t)(dstp_b[x] + (((ovrp_b[x] - dstp_b[x]) * alpha + rounder) >> bits_per_pixel));\n          if constexpr (has_alpha)\n            dstp_a[x] = (pixel_t)(dstp_a[x] + (((maskp[x] - dstp_a[x]) * alpha + rounder) >> bits_per_pixel));\n        }\n        else { // use luma instead of overlay\n          calc_t luma = (cyb * ovrp_b[x] + cyg * ovrp_g[x] + cyr * ovrp_r[x]) >> 15; // no rounding not really needed here\n\n          dstp_r[x] = (pixel_t)(dstp_r[x] + (((luma - dstp_r[x]) * alpha + rounder) >> bits_per_pixel));\n          dstp_g[x] = (pixel_t)(dstp_g[x] + (((luma - dstp_g[x]) * alpha + rounder) >> bits_per_pixel));\n          dstp_b[x] = (pixel_t)(dstp_b[x] + (((luma - dstp_b[x]) * alpha + rounder) >> bits_per_pixel));\n          if constexpr (has_alpha)\n            dstp_a[x] = (pixel_t)(dstp_a[x] + (((luma - dstp_a[x]) * alpha + rounder) >> bits_per_pixel));\n        }\n      }\n    }\n    dstp_g += dst_pitch;\n    dstp_b += dst_pitch;\n    dstp_r += dst_pitch;\n    if constexpr (has_alpha)\n      dstp_a += dst_pitch;\n    ovrp_g += overlay_pitch;\n    ovrp_b += overlay_pitch;\n    ovrp_r += overlay_pitch;\n    if constexpr (has_alpha)\n      maskp += overlay_pitch;\n  }\n}\n\ntemplate<bool chroma, bool has_alpha, bool subtract>\nstatic void layer_planarrgb_add_subtract_f_c(BYTE** dstp8, const BYTE** ovrp8, int dst_pitch, int overlay_pitch, int width, int height, float opacity) {\n  float* dstp_g = reinterpret_cast<float*>(dstp8[0]);\n  float* dstp_b = reinterpret_cast<float*>(dstp8[1]);\n  float* dstp_r = reinterpret_cast<float*>(dstp8[2]);\n  float* dstp_a = reinterpret_cast<float*>(dstp8[3]);\n  const float* ovrp_g = reinterpret_cast<const float*>(ovrp8[0]);\n  const float* ovrp_b = reinterpret_cast<const float*>(ovrp8[1]);\n  const float* ovrp_r = reinterpret_cast<const float*>(ovrp8[2]);\n  const float* maskp = reinterpret_cast<const float*>(ovrp8[3]);\n\n  dst_pitch /= sizeof(float);\n  overlay_pitch /= sizeof(float);\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; ++x) {\n      float alpha = has_alpha ? maskp[x] * opacity : opacity;\n\n      if constexpr (subtract) {\n        // subtract\n        if constexpr (chroma) {\n          dstp_r[x] = dstp_r[x] + (1.0f - ovrp_r[x] - dstp_r[x]) * alpha;\n          dstp_g[x] = dstp_g[x] + (1.0f - ovrp_g[x] - dstp_g[x]) * alpha;\n          dstp_b[x] = dstp_b[x] + (1.0f - ovrp_b[x] - dstp_b[x]) * alpha;\n          if constexpr (has_alpha)\n            dstp_a[x] = dstp_a[x] + (1.0f - maskp[x] - dstp_a[x]) * alpha;\n        }\n        else { // use luma instead of overlay\n          float luma = cyb_f * (1.0f - ovrp_b[x]) + cyg_f * (1.0f - ovrp_g[x]) + cyr_f * (1.0f - ovrp_r[x]);\n          dstp_r[x] = dstp_r[x] + (luma - dstp_r[x]) * alpha;\n          dstp_g[x] = dstp_g[x] + (luma - dstp_g[x]) * alpha;\n          dstp_b[x] = dstp_b[x] + (luma - dstp_b[x]) * alpha;\n          if constexpr (has_alpha)\n            dstp_a[x] = dstp_a[x] + (luma * dstp_a[x] - dstp_a[x]) * alpha;\n        }\n      }\n      else {\n        // add\n        if constexpr (chroma) {\n          dstp_r[x] = dstp_r[x] + (ovrp_r[x] - dstp_r[x]) * alpha;\n          dstp_g[x] = dstp_g[x] + (ovrp_g[x] - dstp_g[x]) * alpha;\n          dstp_b[x] = dstp_b[x] + (ovrp_b[x] - dstp_b[x]) * alpha;\n          if constexpr (has_alpha)\n            dstp_a[x] = dstp_a[x] + (maskp[x] - dstp_a[x]) * alpha;\n        }\n        else { // use luma instead of overlay\n          float luma = cyb_f * ovrp_b[x] + cyg_f * ovrp_g[x] + cyr_f * ovrp_r[x];\n          dstp_r[x] = dstp_r[x] + (luma - dstp_r[x]) * alpha;\n          dstp_g[x] = dstp_g[x] + (luma - dstp_g[x]) * alpha;\n          dstp_b[x] = dstp_b[x] + (luma - dstp_b[x]) * alpha;\n          if constexpr (has_alpha)\n            dstp_a[x] = dstp_a[x] + (luma * dstp_a[x] - dstp_a[x]) * alpha;\n        }\n      }\n    }\n    dstp_g += dst_pitch;\n    dstp_b += dst_pitch;\n    dstp_r += dst_pitch;\n    if constexpr (has_alpha)\n      dstp_a += dst_pitch;\n    ovrp_g += overlay_pitch;\n    ovrp_b += overlay_pitch;\n    ovrp_r += overlay_pitch;\n    if constexpr (has_alpha)\n      maskp += overlay_pitch;\n  }\n}\n\ntemplate<bool is_subtract>\nstatic void get_layer_planarrgb_add_subtract_functions(\n  bool chroma, bool hasAlpha, int bits_per_pixel,\n  /*out*/layer_planarrgb_add_subtract_c_t** layer_fn,\n  /*out*/layer_planarrgb_add_subtract_f_c_t** layer_f_fn)\n{\n#define PLANARRGB_ADD_SUBTRACT_DISPATCH(chroma, has_alpha) \\\n  { if (bits_per_pixel == 8) \\\n    *layer_fn = layer_planarrgb_add_subtract_c<uint8_t, true /*lessthan16bits*/, chroma, has_alpha, is_subtract>; \\\n  else if (bits_per_pixel < 16) \\\n    *layer_fn = layer_planarrgb_add_subtract_c<uint16_t, true /*lessthan16bits*/, chroma, has_alpha, is_subtract>; \\\n  else if (bits_per_pixel == 16) \\\n    *layer_fn = layer_planarrgb_add_subtract_c<uint16_t, false /*lessthan16bits*/, chroma, has_alpha, is_subtract>; \\\n  else /* float */ \\\n    *layer_f_fn = layer_planarrgb_add_subtract_f_c<chroma, has_alpha, is_subtract>; \\\n  }\n\n  if (hasAlpha) {\n    // planar RGBA\n    if (chroma) {\n      PLANARRGB_ADD_SUBTRACT_DISPATCH(true, true)\n    }\n    else {\n      PLANARRGB_ADD_SUBTRACT_DISPATCH(false, true)\n    }\n  }\n  else {\n    // planar RGB\n    if (chroma) {\n      PLANARRGB_ADD_SUBTRACT_DISPATCH(true, false)\n    }\n    else {\n      PLANARRGB_ADD_SUBTRACT_DISPATCH(false, false)\n    }\n  }\n#undef PLANARRGB_ADD_SUBTRACT_DISPATCH\n}\n\ntemplate<typename pixel_t, bool lessthan16bits, bool chroma, bool has_alpha>\nstatic void layer_planarrgb_mul_c(BYTE** dstp8, const BYTE** ovrp8, int dst_pitch, int overlay_pitch, int width, int height, int level, int bits_per_pixel) {\n  pixel_t* dstp_g = reinterpret_cast<pixel_t*>(dstp8[0]);\n  pixel_t* dstp_b = reinterpret_cast<pixel_t*>(dstp8[1]);\n  pixel_t* dstp_r = reinterpret_cast<pixel_t*>(dstp8[2]);\n  pixel_t* dstp_a = reinterpret_cast<pixel_t*>(dstp8[3]);\n  const pixel_t* ovrp_g = reinterpret_cast<const pixel_t*>(ovrp8[0]);\n  const pixel_t* ovrp_b = reinterpret_cast<const pixel_t*>(ovrp8[1]);\n  const pixel_t* ovrp_r = reinterpret_cast<const pixel_t*>(ovrp8[2]);\n  const pixel_t* maskp = reinterpret_cast<const pixel_t*>(ovrp8[3]);\n\n  dst_pitch /= sizeof(pixel_t);\n  overlay_pitch /= sizeof(pixel_t);\n\n  using calc_t = typename std::conditional < lessthan16bits, int, int64_t>::type;\n  if constexpr (sizeof(pixel_t) == 1)\n    bits_per_pixel = 8; // make quasi constexpr\n  else if constexpr (sizeof(pixel_t) == 2 && !lessthan16bits)\n    bits_per_pixel = 16; // make quasi constexpr\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; ++x) {\n      calc_t alpha = has_alpha ? ((calc_t)maskp[x] * level + 1) >> bits_per_pixel : level;\n\n      if constexpr (chroma) {\n        dstp_r[x] = (pixel_t)(dstp_r[x] + ((((((calc_t)ovrp_r[x] * dstp_r[x]) >> bits_per_pixel) - dstp_r[x]) * alpha) >> bits_per_pixel));\n        dstp_g[x] = (pixel_t)(dstp_g[x] + ((((((calc_t)ovrp_g[x] * dstp_g[x]) >> bits_per_pixel) - dstp_g[x]) * alpha) >> bits_per_pixel));\n        dstp_b[x] = (pixel_t)(dstp_b[x] + ((((((calc_t)ovrp_b[x] * dstp_b[x]) >> bits_per_pixel) - dstp_b[x]) * alpha) >> bits_per_pixel));\n        if constexpr (has_alpha)\n          dstp_a[x] = (pixel_t)(dstp_a[x] + ((((((calc_t)maskp[x] * dstp_a[x]) >> bits_per_pixel) - dstp_a[x]) * alpha) >> bits_per_pixel));\n      }\n      else { // use luma instead of overlay\n        calc_t luma = (cyb * ovrp_b[x] + cyg * ovrp_g[x] + cyr * ovrp_r[x]) >> 15; // no rounding not really needed here\n\n        dstp_r[x] = (pixel_t)(dstp_r[x] + (((((luma * dstp_r[x]) >> bits_per_pixel) - dstp_r[x]) * alpha) >> bits_per_pixel));\n        dstp_g[x] = (pixel_t)(dstp_g[x] + (((((luma * dstp_g[x]) >> bits_per_pixel) - dstp_g[x]) * alpha) >> bits_per_pixel));\n        dstp_b[x] = (pixel_t)(dstp_b[x] + (((((luma * dstp_b[x]) >> bits_per_pixel) - dstp_b[x]) * alpha) >> bits_per_pixel));\n        if constexpr (has_alpha)\n          dstp_a[x] = (pixel_t)(dstp_a[x] + (((((luma * dstp_a[x]) >> bits_per_pixel) - dstp_a[x]) * alpha) >> bits_per_pixel));\n      }\n    }\n    dstp_g += dst_pitch;\n    dstp_b += dst_pitch;\n    dstp_r += dst_pitch;\n    if constexpr (has_alpha)\n      dstp_a += dst_pitch;\n    ovrp_g += overlay_pitch;\n    ovrp_b += overlay_pitch;\n    ovrp_r += overlay_pitch;\n    if constexpr (has_alpha)\n      maskp += overlay_pitch;\n  }\n}\n\ntemplate<bool chroma, bool has_alpha>\nstatic void layer_planarrgb_mul_f_c(BYTE** dstp8, const BYTE** ovrp8, int dst_pitch, int overlay_pitch, int width, int height, float opacity) {\n  float* dstp_g = reinterpret_cast<float*>(dstp8[0]);\n  float* dstp_b = reinterpret_cast<float*>(dstp8[1]);\n  float* dstp_r = reinterpret_cast<float*>(dstp8[2]);\n  float* dstp_a = reinterpret_cast<float*>(dstp8[3]);\n  const float* ovrp_g = reinterpret_cast<const float*>(ovrp8[0]);\n  const float* ovrp_b = reinterpret_cast<const float*>(ovrp8[1]);\n  const float* ovrp_r = reinterpret_cast<const float*>(ovrp8[2]);\n  const float* maskp = reinterpret_cast<const float*>(ovrp8[3]);\n\n  dst_pitch /= sizeof(float);\n  overlay_pitch /= sizeof(float);\n\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; ++x) {\n      float alpha = has_alpha ? maskp[x] * opacity : opacity;\n\n      if constexpr (chroma) {\n        dstp_r[x] = dstp_r[x] + (ovrp_r[x] * dstp_r[x] - dstp_r[x]) * alpha;\n        dstp_g[x] = dstp_g[x] + (ovrp_g[x] * dstp_g[x] - dstp_g[x]) * alpha;\n        dstp_b[x] = dstp_b[x] + (ovrp_b[x] * dstp_b[x] - dstp_b[x]) * alpha;\n        if constexpr (has_alpha)\n          dstp_a[x] = dstp_a[x] + (maskp[x] * dstp_a[x] - dstp_a[x]) * alpha;\n      }\n      else { // use luma instead of overlay\n        float luma = cyb_f * ovrp_b[x] + cyg_f * ovrp_g[x] + cyr_f * ovrp_r[x];\n        dstp_r[x] = dstp_r[x] + (luma * dstp_r[x] - dstp_r[x]) * alpha;\n        dstp_g[x] = dstp_g[x] + (luma * dstp_g[x] - dstp_g[x]) * alpha;\n        dstp_b[x] = dstp_b[x] + (luma * dstp_b[x] - dstp_b[x]) * alpha;\n        if constexpr (has_alpha)\n          dstp_a[x] = dstp_a[x] + (luma * dstp_a[x] - dstp_a[x]) * alpha;\n      }\n    }\n    dstp_g += dst_pitch;\n    dstp_b += dst_pitch;\n    dstp_r += dst_pitch;\n    if constexpr (has_alpha)\n      dstp_a += dst_pitch;\n    ovrp_g += overlay_pitch;\n    ovrp_b += overlay_pitch;\n    ovrp_r += overlay_pitch;\n    if constexpr (has_alpha)\n      maskp += overlay_pitch;\n  }\n}\n\nstatic void get_layer_planarrgb_mul_functions(\n  bool chroma, bool hasAlpha, int bits_per_pixel,\n  /*out*/layer_planarrgb_mul_c_t** layer_fn,\n  /*out*/layer_planarrgb_mul_f_c_t** layer_f_fn)\n{\n#define PLANARRGB_MUL_DISPATCH(chroma, has_alpha) \\\n  { if (bits_per_pixel == 8) \\\n    *layer_fn = layer_planarrgb_mul_c<uint8_t, true /*lessthan16bits*/, chroma, has_alpha>; \\\n  else if (bits_per_pixel < 16) \\\n    *layer_fn = layer_planarrgb_mul_c<uint16_t, true /*lessthan16bits*/, chroma, has_alpha>; \\\n  else if (bits_per_pixel == 16) \\\n    *layer_fn = layer_planarrgb_mul_c<uint16_t, false /*lessthan16bits*/, chroma, has_alpha>; \\\n  else /* float */ \\\n    *layer_f_fn = layer_planarrgb_mul_f_c<chroma, has_alpha>; \\\n  }\n\n  if (hasAlpha) {\n    // planar RGBA\n    if (chroma) {\n      PLANARRGB_MUL_DISPATCH(true, true)\n    }\n    else {\n      PLANARRGB_MUL_DISPATCH(false, true)\n    }\n  }\n  else {\n    // planar RGB\n    if (chroma) {\n      PLANARRGB_MUL_DISPATCH(true, false)\n    }\n    else {\n      PLANARRGB_MUL_DISPATCH(false, false)\n    }\n  }\n#undef PLANARRGB_MUL_DISPATCH\n}\n\n"
  },
  {
    "path": "avs_core/filters/levels.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include \"levels.h\"\n#include <float.h>\n#include \"limiter.h\"\n#include <cstdio>\n#include <cmath>\n#include <avs/minmax.h>\n#include <avs/alignment.h>\n#include \"../core/internal.h\"\n#include <algorithm>\n#include <string>\n\n#define PI 3.141592653589793\n\n\n/********************************************************************\n***** Declare index of new filters for Avisynth's filter engine *****\n********************************************************************/\n\nextern const AVSFunction Levels_filters[] = {\n  { \"Levels\",    BUILTIN_FUNC_PREFIX, \"cfffff[coring]b[dither]b\", Levels::Create },        // src_low, gamma, src_high, dst_low, dst_high cifiii->ffffff\n  { \"RGBAdjust\", BUILTIN_FUNC_PREFIX, \"c[r]f[g]f[b]f[a]f[rb]f[gb]f[bb]f[ab]f[rg]f[gg]f[bg]f[ag]f[analyze]b[dither]b[conditional]b[condvarsuffix]s\", RGBAdjust::Create },\n  // 'sse': unused even on INTEL, just for script compatibility\n  { \"Tweak\",     BUILTIN_FUNC_PREFIX, \"c[hue]f[sat]f[bright]f[cont]f[coring]b[sse]b[startHue]f[endHue]f[maxSat]f[minSat]f[interp]f[dither]b[realcalc]b[dither_strength]f\", Tweak::Create },\n  { \"MaskHS\",    BUILTIN_FUNC_PREFIX, \"c[startHue]f[endHue]f[maxSat]f[minSat]f[coring]b[realcalc]b\", MaskHS::Create },\n  { \"Limiter\",   BUILTIN_FUNC_PREFIX, \"c[min_luma]f[max_luma]f[min_chroma]f[max_chroma]f[show]s[paramscale]b\", Limiter::Create },\n  { 0 }\n};\n\n\navs_alignas(64) static const BYTE ditherMap[256] = {\n#if 0\n  // default 0231 recursed table\n  0x00, 0x80, 0x20, 0xA0,  0x08, 0x88, 0x28, 0xA8,  0x02, 0x82, 0x22, 0xA2,  0x0A, 0x8A, 0x2A, 0xAA,\n  0xC0, 0x40, 0xE0, 0x60,  0xC8, 0x48, 0xE8, 0x68,  0xC2, 0x42, 0xE2, 0x62,  0xCA, 0x4A, 0xEA, 0x6A,\n  0x30, 0xB0, 0x10, 0x90,  0x38, 0xB8, 0x18, 0x98,  0x32, 0xB2, 0x12, 0x92,  0x3A, 0xBA, 0x1A, 0x9A,\n  0xF0, 0x70, 0xD0, 0x50,  0xF8, 0x78, 0xD8, 0x58,  0xF2, 0x72, 0xD2, 0x52,  0xFA, 0x7A, 0xDA, 0x5A,\n\n  0x0C, 0x8C, 0x2C, 0xAC,  0x04, 0x84, 0x24, 0xA4,  0x0E, 0x8E, 0x2E, 0xAE,  0x06, 0x86, 0x26, 0xA6,\n  0xCC, 0x4C, 0xEC, 0x6C,  0xC4, 0x44, 0xE4, 0x64,  0xCE, 0x4E, 0xEE, 0x6E,  0xC6, 0x46, 0xE6, 0x66,\n  0x3C, 0xBC, 0x1C, 0x9C,  0x34, 0xB4, 0x14, 0x94,  0x3E, 0xBE, 0x1E, 0x9E,  0x36, 0xB6, 0x16, 0x96,\n  0xFC, 0x7C, 0xDC, 0x5C,  0xF4, 0x74, 0xD4, 0x54,  0xFE, 0x7E, 0xDE, 0x5E,  0xF6, 0x76, 0xD6, 0x56,\n\n  0x03, 0x83, 0x23, 0xA3,  0x0B, 0x8B, 0x2B, 0xAB,  0x01, 0x81, 0x21, 0xA1,  0x09, 0x89, 0x29, 0xA9,\n  0xC3, 0x43, 0xE3, 0x63,  0xCB, 0x4B, 0xEB, 0x6B,  0xC1, 0x41, 0xE1, 0x61,  0xC9, 0x49, 0xE9, 0x69,\n  0x33, 0xB3, 0x13, 0x93,  0x3B, 0xBB, 0x1B, 0x9B,  0x31, 0xB1, 0x11, 0x91,  0x39, 0xB9, 0x19, 0x99,\n  0xF3, 0x73, 0xD3, 0x53,  0xFB, 0x7B, 0xDB, 0x5B,  0xF1, 0x71, 0xD1, 0x51,  0xF9, 0x79, 0xD9, 0x59,\n\n  0x0F, 0x8F, 0x2F, 0xAF,  0x07, 0x87, 0x27, 0xA7,  0x0D, 0x8D, 0x2D, 0xAD,  0x05, 0x85, 0x25, 0xA5,\n  0xCF, 0x4F, 0xEF, 0x6F,  0xC7, 0x47, 0xE7, 0x67,  0xCD, 0x4D, 0xED, 0x6D,  0xC5, 0x45, 0xE5, 0x65,\n  0x3F, 0xBF, 0x1F, 0x9F,  0x37, 0xB7, 0x17, 0x97,  0x3D, 0xBD, 0x1D, 0x9D,  0x35, 0xB5, 0x15, 0x95,\n  0xFF, 0x7F, 0xDF, 0x5F,  0xF7, 0x77, 0xD7, 0x57,  0xFD, 0x7D, 0xDD, 0x5D,  0xF5, 0x75, 0xD5, 0x55,\n#else\n  // improved \"equal sum\" modified table\n  0x00, 0xB0, 0x60, 0xD0,  0x0B, 0xBB, 0x6B, 0xDB,  0x06, 0xB6, 0x66, 0xD6,  0x0D, 0xBD, 0x6D, 0xDD,\n  0xC0, 0x70, 0x90, 0x20,  0xCB, 0x7B, 0x9B, 0x2B,  0xC6, 0x76, 0x96, 0x26,  0xCD, 0x7D, 0x9D, 0x2D,\n  0x30, 0x80, 0x50, 0xE0,  0x3B, 0x8B, 0x5B, 0xEB,  0x36, 0x86, 0x56, 0xE6,  0x3D, 0x8D, 0x5D, 0xED,\n  0xF0, 0x40, 0xA0, 0x10,  0xFB, 0x4B, 0xAB, 0x1B,  0xF6, 0x46, 0xA6, 0x16,  0xFD, 0x4D, 0xAD, 0x1D,\n\n  0x0C, 0xBC, 0x6C, 0xDC,  0x07, 0xB7, 0x67, 0xD7,  0x09, 0xB9, 0x69, 0xD9,  0x02, 0xB2, 0x62, 0xD2,\n  0xCC, 0x7C, 0x9C, 0x2C,  0xC7, 0x77, 0x97, 0x27,  0xC9, 0x79, 0x99, 0x29,  0xC2, 0x72, 0x92, 0x22,\n  0x3C, 0x8C, 0x5C, 0xEC,  0x37, 0x87, 0x57, 0xE7,  0x39, 0x89, 0x59, 0xE9,  0x32, 0x82, 0x52, 0xE2,\n  0xFC, 0x4C, 0xAC, 0x1C,  0xF7, 0x47, 0xA7, 0x17,  0xF9, 0x49, 0xA9, 0x19,  0xF2, 0x42, 0xA2, 0x12,\n\n  0x03, 0xB3, 0x63, 0xD3,  0x08, 0xB8, 0x68, 0xD8,  0x05, 0xB5, 0x65, 0xD5,  0x0E, 0xBE, 0x6E, 0xDE,\n  0xC3, 0x73, 0x93, 0x23,  0xC8, 0x78, 0x98, 0x28,  0xC5, 0x75, 0x95, 0x25,  0xCE, 0x7E, 0x9E, 0x2E,\n  0x33, 0x83, 0x53, 0xE3,  0x38, 0x88, 0x58, 0xE8,  0x35, 0x85, 0x55, 0xE5,  0x3E, 0x8E, 0x5E, 0xEE,\n  0xF3, 0x43, 0xA3, 0x13,  0xF8, 0x48, 0xA8, 0x18,  0xF5, 0x45, 0xA5, 0x15,  0xFE, 0x4E, 0xAE, 0x1E,\n\n  0x0F, 0xBF, 0x6F, 0xDF,  0x04, 0xB4, 0x64, 0xD4,  0x0A, 0xBA, 0x6A, 0xDA,  0x01, 0xB1, 0x61, 0xD1,\n  0xCF, 0x7F, 0x9F, 0x2F,  0xC4, 0x74, 0x94, 0x24,  0xCA, 0x7A, 0x9A, 0x2A,  0xC1, 0x71, 0x91, 0x21,\n  0x3F, 0x8F, 0x5F, 0xEF,  0x34, 0x84, 0x54, 0xE4,  0x3A, 0x8A, 0x5A, 0xEA,  0x31, 0x81, 0x51, 0xE1,\n  0xFF, 0x4F, 0xAF, 0x1F,  0xF4, 0x44, 0xA4, 0x14,  0xFA, 0x4A, 0xAA, 0x1A,  0xF1, 0x41, 0xA1, 0x11,\n#endif\n};\n\n\navs_alignas(16) static const BYTE ditherMap4[16] = {\n  0x0, 0xB, 0x6, 0xD,\n  0xC, 0x7, 0x9, 0x2,\n  0x3, 0x8, 0x5, 0xE,\n  0xF, 0x4, 0xA, 0x1,\n};\n\nstatic void __cdecl free_buffer(void* buff, IScriptEnvironment* env)\n{\n    if (buff) {\n        static_cast<IScriptEnvironment2*>(env)->Free(buff);\n    }\n}\n\n// Helper for Limits, MaskHS, Tweak\nstatic void get_limits(luma_chroma_limits_t &d, int bits_per_pixel) {\n  int tv_range_lo_luma_8 = 16;\n  int tv_range_hi_luma_8 = 235;\n  int tv_range_lo_chroma_8 = tv_range_lo_luma_8;\n  int tv_range_hi_chroma_8 = 240;\n\n  if (bits_per_pixel == 32) {\n    d.tv_range_low_luma_f = tv_range_lo_luma_8 / 255.0f;\n    d.tv_range_hi_luma_f = tv_range_hi_luma_8 / 255.0f;\n    d.full_range_low_luma_f = 0.0f;\n    d.full_range_hi_luma_f = 1.0f;\n#ifdef FLOAT_CHROMA_IS_HALF_CENTERED\n    d.middle_chroma_f = 0.5f;\n#else\n    d.middle_chroma_f = 0.0f;\n#endif\n    d.tv_range_low_chroma_f = (tv_range_lo_chroma_8 - 128) / 255.0f + d.middle_chroma_f; // -112\n    d.tv_range_hi_chroma_f = (tv_range_hi_chroma_8 - 128) / 255.0f + d.middle_chroma_f; // 112\n    d.full_range_low_chroma_f = d.middle_chroma_f - 0.5f; // -0.5..0.5 or 0..1.0\n    d.full_range_hi_chroma_f = d.middle_chroma_f + 0.5f;\n\n    d.range_luma_f = d.tv_range_hi_luma_f - d.tv_range_low_luma_f;\n    d.range_chroma_f = d.tv_range_hi_chroma_f - d.tv_range_low_chroma_f;\n  }\n  else {\n    d.tv_range_low = tv_range_lo_luma_8 << (bits_per_pixel - 8); // 16-240,64-960, 256-3852,... 4096-61692\n    d.tv_range_hi_luma = tv_range_hi_luma_8 << (bits_per_pixel - 8);\n    d.tv_range_hi_chroma = tv_range_hi_chroma_8 << (bits_per_pixel - 8);\n    d.middle_chroma = 1 << (bits_per_pixel - 1); // 128\n    d.range_luma = d.tv_range_hi_luma - d.tv_range_low; // 219\n    d.range_chroma = d.tv_range_hi_chroma - d.tv_range_low; // 224\n  }\n}\n\n/********************************\n *******   Levels Filter   ******\n ********************************/\n\ntemplate<bool chroma, bool use_gamma>\nAVS_FORCEINLINE float Levels::calcPixel(const float pixel)\n{\n    float result;\n    if (!chroma) {\n      float p;\n      if (coring)\n        p = ((pixel - limits.tv_range_low_luma_f)*(1.0f / limits.range_luma_f) - in_min_f) / divisor_f;\n      else\n        p = (pixel - in_min_f) / divisor_f;\n\n      if(use_gamma)\n        p = (float)pow((double)clamp(p, 0.0f, 1.0f), gamma);\n\n      p = p * out_diff_f + out_min_f; // out_diff_f = out_max_f - out_min_f;\n      // luma\n      if (coring) {\n        result = clamp(p* limits.range_luma_f / 1.0f + limits.tv_range_low_luma_f, limits.tv_range_low_luma_f, limits.tv_range_hi_luma_f);\n      }\n      else\n        result = clamp(p, 0.0f, 1.0f); // todo: theoretical question, should we clamp in Levels function?\n    }\n    else {\n      /*\n      int q = (int)(((bias_dither + ii - middle_chroma * scale) * (out_max - out_min)) / divisor + middle_chroma + 0.5);\n      int chroma;\n      if (coring)\n        chroma = clamp(q, tv_range_low, tv_range_hi_chroma); // e.g. clamp(q, 16, 240)\n      else\n        chroma = clamp(q, 0, max_pixel_value); // e.g. clamp(q, 0, 255)\n      */\n      float q = ((pixel - limits.middle_chroma_f) * out_diff_f) / divisor_f + limits.middle_chroma_f;\n      if (coring)\n        result = clamp(q, limits.tv_range_low_chroma_f, limits.tv_range_hi_chroma_f); // e.g. clamp(q, 16, 240)\n      else\n        result = clamp(q, limits.full_range_low_chroma_f, limits.full_range_hi_chroma_f); // e.g. clamp(q, 0, 255) todo: theoretical question, should we clamp in Levels function?\n    }\n    return result;\n}\n\n\nLevels::Levels(PClip _child, float _in_min, double _gamma, float _in_max, float _out_min, float _out_max, bool _coring, bool _dither,\n  IScriptEnvironment* env)\n  : GenericVideoFilter(_child), coring(_coring), dither(_dither), gamma(_gamma), in_min_f(_in_min), in_max_f(_in_max), out_min_f(_out_min), out_max_f(_out_max)\n{\n  if (gamma <= 0.0)\n    env->ThrowError(\"Levels: gamma must be positive\");\n\n  gamma = 1/gamma;\n  use_gamma = (gamma != 1.0);\n\n  int in_min = (int)in_min_f;\n  int in_max = (int)in_max_f;\n  int out_min = (int)out_min_f;\n  int out_max = (int)out_max_f;\n  out_diff_f = out_max_f - out_min_f;\n\n  int divisor;\n  if (in_min == in_max)\n    divisor = 1;\n  else\n    divisor = in_max - in_min;\n\n  if (in_min_f == in_max_f)\n    divisor_f = 1;\n  else\n    divisor_f = in_max_f - in_min_f;\n\n  int scale = 1;\n  //double bias = 0.0;\n\n  dither_strength = 1.0f; // later: from parameter as Tweak\n\n  pixelsize = vi.ComponentSize();\n  bits_per_pixel = vi.BitsPerComponent(); // 8,10..16\n\n  // No lookup for float. Only slow pixel-by-pixel realtime calculation\n\n  int lookup_size = 1 << bits_per_pixel; // 256, 1024, 4096, 16384, 65536\n  real_lookup_size = (pixelsize == 1) ? 256 : 65536; // avoids lut overflow in case of non-standard content of a 10 bit clip\n  int max_pixel_value = (1 << bits_per_pixel) - 1;\n\n  use_lut = bits_per_pixel != 32; // for float: realtime only\n\n  get_limits(limits, bits_per_pixel); // tv range limits\n\n  if (pixelsize == 4)\n    dither_strength /= 65536.0f; // same dither range as for a 16 bit clip\n\n  if (dither) {\n    // lut scale settings\n    // same 256*dither for chroma and luma\n    scale = 256; // lower 256 is dither value\n    divisor *= 256;\n    in_min *= 256;\n    bias_dither = -(256.0f * dither_strength - 1) / 2; // -127.5 for 8 bit, scaling because of dithershift\n  }\n  else {\n    scale = 1;\n    bias_dither = 0.0f;\n  }\n\n  need_chroma = (vi.IsYUV() || vi.IsYUVA()) && !vi.IsY8();\n  if (vi.IsRGB())\n    coring = false; // no coring option for packed and planar RGBs\n\n  // one buffer for map and mapchroma\n  map = nullptr;\n  if (use_lut) {\n    int number_of_maps = need_chroma ? 2 : 1;\n    int bufsize = pixelsize * real_lookup_size * scale * number_of_maps;\n    map = static_cast<uint8_t*>(env->Allocate(bufsize, 16, AVS_NORMAL_ALLOC));\n    if (!map)\n      env->ThrowError(\"Levels: Could not reserve memory.\");\n    env->AtExit(free_buffer, map);\n    if (bits_per_pixel > 8 && bits_per_pixel < 16) // make lut table safe for 10-14 bit garbage\n      std::fill_n(map, bufsize, 0); // 8 and 16 bit is safe\n\n    if(need_chroma)\n      mapchroma = map + pixelsize * real_lookup_size * scale; // pointer offset\n\n    for (int i = 0; i < lookup_size*scale; ++i) {\n      double p;\n\n      int ii;\n      if (dither)\n        ii = (i & 0xFFFFFF00) + (int)((i & 0xFF)*dither_strength);\n      else\n        ii = i;\n\n      if (coring)\n        p = ((bias_dither + ii - limits.tv_range_low *scale)*((double)max_pixel_value / limits.range_luma) - in_min) / divisor;\n      else\n        p = (bias_dither + ii - in_min) / divisor;\n\n      p = pow(clamp(p, 0.0, 1.0), gamma);\n      p = p * (out_max - out_min) + out_min;\n      int luma;\n      if (coring)\n        luma = clamp(int(p*((double)limits.range_luma / max_pixel_value) + limits.tv_range_low + 0.5), limits.tv_range_low, limits.tv_range_hi_luma);\n      else\n        luma = clamp(int(p + 0.5), 0, max_pixel_value);\n\n      if (pixelsize == 1)\n        map[i] = (BYTE)luma;\n      else // pixelsize==2\n        reinterpret_cast<uint16_t *>(map)[i] = (uint16_t)luma;\n\n      if (need_chroma) {\n        int q = (int)(((bias_dither + ii - limits.middle_chroma*scale) * (out_max - out_min)) / divisor + limits.middle_chroma + 0.5f);\n        int chroma;\n        if (coring)\n          chroma = clamp(q, limits.tv_range_low, limits.tv_range_hi_chroma); // e.g. clamp(q, 16, 240)\n        else\n          chroma = clamp(q, 0, max_pixel_value); // e.g. clamp(q, 0, 255)\n        if (pixelsize == 1)\n          mapchroma[i] = (BYTE)chroma;\n        else // pixelsize==2\n          reinterpret_cast<uint16_t *>(mapchroma)[i] = (uint16_t)chroma;\n      }\n    }\n  }\n  else {\n    // precalc float dither table from integer one\n    if (dither) {\n      for (int y = 0; y <= 15; y++)\n        for (int x = 0; x <= 15; x++) {\n          int index = (y << 4) | x; // 0..255\n          ditherMap_f[index] = (ditherMap[index] / 255.0f - 0.5f) * dither_strength;\n          // float dithering is 16 bit granularity, dither_strength is 1/65536.0 and not a parameter yet\n        }\n    }\n  }\n}\n\n\nPVideoFrame __stdcall Levels::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame frame = child->GetFrame(n, env);\n  env->MakeWritable(&frame);\n  BYTE* p = frame->GetWritePtr();\n  const int pitch = frame->GetPitch();\n\n  if (use_lut) {\n    if (dither) {\n      if (vi.IsYUY2()) {\n        const int UVwidth = vi.width / 2;\n        for (int y = 0; y < vi.height; ++y) {\n          const int _y = (y << 4) & 0xf0;\n          for (int x = 0; x < vi.width; ++x) {\n            p[x * 2] = map[p[x * 2] << 8 | ditherMap[(x & 0x0f) | _y]];\n          }\n          for (int z = 0; z < UVwidth; ++z) {\n            const int _dither = ditherMap[(z & 0x0f) | _y];\n            p[z * 4 + 1] = mapchroma[p[z * 4 + 1] << 8 | _dither];\n            p[z * 4 + 3] = mapchroma[p[z * 4 + 3] << 8 | _dither];\n          }\n          p += pitch;\n        }\n      }\n      else if (vi.IsPlanar()) {\n        if (vi.IsYUV() || vi.IsYUVA()) {\n          // planar YUV\n          if (pixelsize == 1) {\n            for (int y = 0; y < vi.height; ++y) {\n              const int _y = (y << 4) & 0xf0;\n              for (int x = 0; x < vi.width; ++x) {\n                p[x] = map[p[x] << 8 | ditherMap[(x & 0x0f) | _y]];\n              }\n              p += pitch;\n            }\n          }\n          else { // pixelsize==2\n            for (int y = 0; y < vi.height; ++y) {\n              const int _y = (y << 4) & 0xf0;\n              for (int x = 0; x < vi.width; ++x) {\n                reinterpret_cast<uint16_t *>(p)[x] = reinterpret_cast<uint16_t *>(map)[reinterpret_cast<uint16_t *>(p)[x] << 8 | ditherMap[(x & 0x0f) | _y]];\n              }\n              p += pitch;\n            }\n          }\n          const int UVpitch = frame->GetPitch(PLANAR_U);\n          const int w = frame->GetRowSize(PLANAR_U) / pixelsize;\n          const int h = frame->GetHeight(PLANAR_U);\n          p = frame->GetWritePtr(PLANAR_U);\n          BYTE* q = frame->GetWritePtr(PLANAR_V);\n          if (pixelsize == 1) {\n            for (int y = 0; y < h; ++y) {\n              const int _y = (y << 4) & 0xf0;\n              for (int x = 0; x < w; ++x) {\n                const int _dither = ditherMap[(x & 0x0f) | _y];\n                p[x] = mapchroma[p[x] << 8 | _dither];\n                q[x] = mapchroma[q[x] << 8 | _dither];\n              }\n              p += UVpitch;\n              q += UVpitch;\n            }\n          }\n          else { // pixelsize==2\n            for (int y = 0; y < h; ++y) {\n              const int _y = (y << 4) & 0xf0;\n              for (int x = 0; x < w; ++x) {\n                const int _dither = ditherMap[(x & 0x0f) | _y];\n                reinterpret_cast<uint16_t *>(p)[x] = reinterpret_cast<uint16_t *>(mapchroma)[reinterpret_cast<uint16_t *>(p)[x] << 8 | _dither];\n                reinterpret_cast<uint16_t *>(q)[x] = reinterpret_cast<uint16_t *>(mapchroma)[reinterpret_cast<uint16_t *>(q)[x] << 8 | _dither];\n              }\n              p += UVpitch;\n              q += UVpitch;\n            }\n          }\n        }\n        else {\n          // planar RGB\n          BYTE* b = frame->GetWritePtr(PLANAR_B);\n          BYTE* r = frame->GetWritePtr(PLANAR_R);\n          const int pitch_b = frame->GetPitch(PLANAR_B);\n          const int pitch_r = frame->GetPitch(PLANAR_R);\n          if (pixelsize == 1) {\n            for (int y = 0; y < vi.height; ++y) {\n              const int _y = (y << 4) & 0xf0;\n              for (int x = 0; x < vi.width; ++x) {\n                p[x] = map[p[x] << 8 | ditherMap[(x & 0x0f) | _y]];\n                b[x] = map[b[x] << 8 | ditherMap[(x & 0x0f) | _y]];\n                r[x] = map[r[x] << 8 | ditherMap[(x & 0x0f) | _y]];\n              }\n              p += pitch;\n              b += pitch_b;\n              r += pitch_r;\n            }\n          }\n          else { // pixelsize==2\n            for (int y = 0; y < vi.height; ++y) {\n              const int _y = (y << 4) & 0xf0;\n              for (int x = 0; x < vi.width; ++x) {\n                reinterpret_cast<uint16_t *>(p)[x] = reinterpret_cast<uint16_t *>(map)[reinterpret_cast<uint16_t *>(p)[x] << 8 | ditherMap[(x & 0x0f) | _y]];\n                reinterpret_cast<uint16_t *>(b)[x] = reinterpret_cast<uint16_t *>(map)[reinterpret_cast<uint16_t *>(b)[x] << 8 | ditherMap[(x & 0x0f) | _y]];\n                reinterpret_cast<uint16_t *>(r)[x] = reinterpret_cast<uint16_t *>(map)[reinterpret_cast<uint16_t *>(r)[x] << 8 | ditherMap[(x & 0x0f) | _y]];\n              }\n              p += pitch;\n              b += pitch_b;\n              r += pitch_r;\n            }\n          }\n        }\n      }\n      else if (vi.IsRGB32()) {\n        for (int y = 0; y < vi.height; ++y) {\n          const int _y = (y << 4) & 0xf0;\n          for (int x = 0; x < vi.width; ++x) {\n            const int _dither = ditherMap[(x & 0x0f) | _y];\n            p[x * 4 + 0] = map[p[x * 4 + 0] << 8 | _dither];\n            p[x * 4 + 1] = map[p[x * 4 + 1] << 8 | _dither];\n            p[x * 4 + 2] = map[p[x * 4 + 2] << 8 | _dither];\n            p[x * 4 + 3] = map[p[x * 4 + 3] << 8 | _dither];\n          }\n          p += pitch;\n        }\n      }\n      else if (vi.IsRGB24()) {\n        for (int y = 0; y < vi.height; ++y) {\n          const int _y = (y << 4) & 0xf0;\n          for (int x = 0; x < vi.width; ++x) {\n            const int _dither = ditherMap[(x & 0x0f) | _y];\n            p[x * 3 + 0] = map[p[x * 3 + 0] << 8 | _dither];\n            p[x * 3 + 1] = map[p[x * 3 + 1] << 8 | _dither];\n            p[x * 3 + 2] = map[p[x * 3 + 2] << 8 | _dither];\n          }\n          p += pitch;\n        }\n      }\n      else if (vi.IsRGB64()) {\n        for (int y = 0; y < vi.height; ++y) {\n          const int _y = (y << 4) & 0xf0;\n          for (int x = 0; x < vi.width; ++x) {\n            const int _dither = ditherMap[(x & 0x0f) | _y];\n            reinterpret_cast<uint16_t *>(p)[x * 4 + 0] = reinterpret_cast<uint16_t *>(map)[reinterpret_cast<uint16_t *>(p)[x * 4 + 0] << 8 | _dither];\n            reinterpret_cast<uint16_t *>(p)[x * 4 + 1] = reinterpret_cast<uint16_t *>(map)[reinterpret_cast<uint16_t *>(p)[x * 4 + 1] << 8 | _dither];\n            reinterpret_cast<uint16_t *>(p)[x * 4 + 2] = reinterpret_cast<uint16_t *>(map)[reinterpret_cast<uint16_t *>(p)[x * 4 + 2] << 8 | _dither];\n            reinterpret_cast<uint16_t *>(p)[x * 4 + 3] = reinterpret_cast<uint16_t *>(map)[reinterpret_cast<uint16_t *>(p)[x * 4 + 3] << 8 | _dither];\n          }\n          p += pitch;\n        }\n      }\n      else if (vi.IsRGB48()) {\n        for (int y = 0; y < vi.height; ++y) {\n          const int _y = (y << 4) & 0xf0;\n          for (int x = 0; x < vi.width; ++x) {\n            const int _dither = ditherMap[(x & 0x0f) | _y];\n            reinterpret_cast<uint16_t *>(p)[x * 3 + 0] = reinterpret_cast<uint16_t *>(map)[reinterpret_cast<uint16_t *>(p)[x * 3 + 0] << 8 | _dither];\n            reinterpret_cast<uint16_t *>(p)[x * 3 + 1] = reinterpret_cast<uint16_t *>(map)[reinterpret_cast<uint16_t *>(p)[x * 3 + 1] << 8 | _dither];\n            reinterpret_cast<uint16_t *>(p)[x * 3 + 2] = reinterpret_cast<uint16_t *>(map)[reinterpret_cast<uint16_t *>(p)[x * 3 + 2] << 8 | _dither];\n          }\n          p += pitch;\n        }\n      }\n    }\n    else { // no dithering\n      if (vi.IsYUY2()) {\n        for (int y = 0; y < vi.height; ++y) {\n          for (int x = 0; x < vi.width; ++x) {\n            p[x * 2 + 0] = map[p[x * 2 + 0]];\n            p[x * 2 + 1] = mapchroma[p[x * 2 + 1]];\n          }\n          p += pitch;\n        }\n      }\n      else if (vi.IsPlanar()) {\n        if (vi.IsYUV() || vi.IsYUVA()) {\n          // planar YUV\n          if (pixelsize == 1) {\n            for (int y = 0; y < vi.height; ++y) {\n              for (int x = 0; x < vi.width; ++x) {\n                p[x] = map[p[x]];\n              }\n              p += pitch;\n            }\n          }\n          else { // pixelsize==2\n            for (int y = 0; y < vi.height; ++y) {\n              for (int x = 0; x < vi.width; ++x) {\n                reinterpret_cast<uint16_t *>(p)[x] = reinterpret_cast<uint16_t *>(map)[reinterpret_cast<uint16_t *>(p)[x]];\n              }\n              p += pitch;\n            }\n          }\n          const int UVpitch = frame->GetPitch(PLANAR_U);\n          p = frame->GetWritePtr(PLANAR_U);\n          const int w = frame->GetRowSize(PLANAR_U) / pixelsize;\n          const int h = frame->GetHeight(PLANAR_U);\n          if (pixelsize == 1) {\n            for (int y = 0; y < h; ++y) {\n              for (int x = 0; x < w; ++x) {\n                p[x] = mapchroma[p[x]];\n              }\n              p += UVpitch;\n            }\n            p = frame->GetWritePtr(PLANAR_V);\n            for (int y = 0; y < h; ++y) {\n              for (int x = 0; x < w; ++x) {\n                p[x] = mapchroma[p[x]];\n              }\n              p += UVpitch;\n            }\n          }\n          else { // pixelsize==2\n            for (int y = 0; y < h; ++y) {\n              for (int x = 0; x < w; ++x) {\n                reinterpret_cast<uint16_t *>(p)[x] = reinterpret_cast<uint16_t *>(mapchroma)[reinterpret_cast<uint16_t *>(p)[x]];\n              }\n              p += UVpitch;\n            }\n            p = frame->GetWritePtr(PLANAR_V);\n            for (int y = 0; y < h; ++y) {\n              for (int x = 0; x < w; ++x) {\n                reinterpret_cast<uint16_t *>(p)[x] = reinterpret_cast<uint16_t *>(mapchroma)[reinterpret_cast<uint16_t *>(p)[x]];\n              }\n              p += UVpitch;\n            }\n          }\n        }\n        else {\n          // Planar RGB\n          BYTE* b = frame->GetWritePtr(PLANAR_B);\n          BYTE* r = frame->GetWritePtr(PLANAR_R);\n          const int pitch_b = frame->GetPitch(PLANAR_B);\n          const int pitch_r = frame->GetPitch(PLANAR_R);\n          if (pixelsize == 1) {\n            for (int y = 0; y < vi.height; ++y) {\n              for (int x = 0; x < vi.width; ++x) {\n                p[x] = map[p[x]];\n                b[x] = map[b[x]];\n                r[x] = map[r[x]];\n              }\n              p += pitch;\n              b += pitch_b;\n              r += pitch_r;\n            }\n          }\n          else { // pixelsize==2\n            for (int y = 0; y < vi.height; ++y) {\n              for (int x = 0; x < vi.width; ++x) {\n                reinterpret_cast<uint16_t *>(p)[x] = reinterpret_cast<uint16_t *>(map)[reinterpret_cast<uint16_t *>(p)[x]];\n                reinterpret_cast<uint16_t *>(b)[x] = reinterpret_cast<uint16_t *>(map)[reinterpret_cast<uint16_t *>(b)[x]];\n                reinterpret_cast<uint16_t *>(r)[x] = reinterpret_cast<uint16_t *>(map)[reinterpret_cast<uint16_t *>(r)[x]];\n              }\n              p += pitch;\n              b += pitch_b;\n              r += pitch_r;\n            }\n          }\n        }\n      }\n      else if (vi.IsRGB()) {\n     // packed RGB\n        const int work_width = frame->GetRowSize() / pixelsize;\n        if (pixelsize == 1) {\n          for (int y = 0; y < vi.height; ++y) {\n            for (int x = 0; x < work_width; ++x) {\n              p[x] = map[p[x]];\n            }\n            p += pitch;\n          }\n        }\n        else { // pixelsize==2\n          for (int y = 0; y < vi.height; ++y) {\n            for (int x = 0; x < work_width; ++x) {\n              reinterpret_cast<uint16_t *>(p)[x] = reinterpret_cast<uint16_t *>(map)[reinterpret_cast<uint16_t *>(p)[x]];\n            }\n            p += pitch;\n          }\n        }\n      }\n    }\n  }\n  else {\n    // float 32 bit. only planars here\n    // no lut, realtime calculation only\n    if (dither) {\n      if (vi.IsYUV() || vi.IsYUVA()) { // planar YUV (incl Y only)\n        // luma. with or w/o gamma\n        if (use_gamma) {\n          for (int y = 0; y < vi.height; ++y) {\n            const int _y = (y << 4) & 0xf0;\n            for (int x = 0; x < vi.width; ++x) {\n              float _dither = ditherMap_f[(x & 0x0f) | _y];\n              const float pixel = reinterpret_cast<float *>(p)[x] + _dither;\n              reinterpret_cast<float *>(p)[x] = calcPixel<false, true>(pixel);\n            }\n            p += pitch;\n          }\n        }\n        else {\n          // don't use gamma (faster)\n          for (int y = 0; y < vi.height; ++y) {\n            const int _y = (y << 4) & 0xf0;\n            for (int x = 0; x < vi.width; ++x) {\n              float _dither = ditherMap_f[(x & 0x0f) | _y];\n              const float pixel = reinterpret_cast<float *>(p)[x] + _dither;\n              reinterpret_cast<float *>(p)[x] = calcPixel<false, false>(pixel); // w/o gamma\n            }\n            p += pitch;\n          }\n        }\n        // chroma\n        if (need_chroma) {\n          const int UVpitch = frame->GetPitch(PLANAR_U);\n          const int w = frame->GetRowSize(PLANAR_U) / pixelsize;\n          const int h = frame->GetHeight(PLANAR_U);\n          p = frame->GetWritePtr(PLANAR_U);\n          BYTE* q = frame->GetWritePtr(PLANAR_V);\n          for (int y = 0; y < h; ++y) {\n            const int _y = (y << 4) & 0xf0;\n            for (int x = 0; x < w; ++x) {\n              float _dither = ditherMap_f[(x & 0x0f) | _y];\n              const float pixel_u = reinterpret_cast<float *>(p)[x] + _dither;\n              reinterpret_cast<float *>(p)[x] = calcPixel<true, false>(pixel_u);\n              const float pixel_v = reinterpret_cast<float *>(q)[x] + _dither;\n              reinterpret_cast<float *>(q)[x] = calcPixel<true, false>(pixel_v);\n            }\n            p += UVpitch;\n            q += UVpitch;\n          }\n        }\n      }\n      else if (vi.IsPlanarRGB() || vi.IsPlanarRGBA()) {\n        // planar RGB\n        BYTE* b = frame->GetWritePtr(PLANAR_B);\n        BYTE* r = frame->GetWritePtr(PLANAR_R);\n        const int pitch_b = frame->GetPitch(PLANAR_B);\n        const int pitch_r = frame->GetPitch(PLANAR_R);\n        if (use_gamma) {\n          for (int y = 0; y < vi.height; ++y) {\n            const int _y = (y << 4) & 0xf0;\n            for (int x = 0; x < vi.width; ++x) {\n              float _dither = ditherMap_f[(x & 0x0f) | _y];\n              const float pixel_p = reinterpret_cast<float *>(p)[x] + _dither; // g channel\n              reinterpret_cast<float *>(p)[x] = calcPixel<false, true>(pixel_p);\n              const float pixel_b = reinterpret_cast<float *>(b)[x] + _dither;\n              reinterpret_cast<float *>(b)[x] = calcPixel<false, true>(pixel_b);\n              const float pixel_r = reinterpret_cast<float *>(r)[x] + _dither;\n              reinterpret_cast<float *>(r)[x] = calcPixel<false, true>(pixel_r);\n            }\n            p += pitch; // g\n            b += pitch_b;\n            r += pitch_r;\n          }\n        }\n        else {\n          for (int y = 0; y < vi.height; ++y) {\n            const int _y = (y << 4) & 0xf0;\n            for (int x = 0; x < vi.width; ++x) {\n              float _dither = ditherMap_f[(x & 0x0f) | _y];\n              const float pixel_p = reinterpret_cast<float *>(p)[x] + _dither; // g channel\n              reinterpret_cast<float *>(p)[x] = calcPixel<false, false>(pixel_p);\n              const float pixel_b = reinterpret_cast<float *>(b)[x] + _dither;\n              reinterpret_cast<float *>(b)[x] = calcPixel<false, false>(pixel_b);\n              const float pixel_r = reinterpret_cast<float *>(r)[x] + _dither;\n              reinterpret_cast<float *>(r)[x] = calcPixel<false, false>(pixel_r);\n            }\n            p += pitch; // g\n            b += pitch_b;\n            r += pitch_r;\n          }\n        }\n      }\n      else {\n        // 32 bit, neither YUV(A), nor RGB(A)\n      }\n    }\n    else {\n      // no dither\n      if (vi.IsYUV() || vi.IsYUVA()) { // planar YUV (incl Y only)\n                                       // luma. with or w/o gamma\n        if (use_gamma) {\n          for (int y = 0; y < vi.height; ++y) {\n            for (int x = 0; x < vi.width; ++x) {\n              const float pixel = reinterpret_cast<float *>(p)[x];\n              reinterpret_cast<float *>(p)[x] = calcPixel<false, true>(pixel);\n            }\n            p += pitch;\n          }\n        }\n        else {\n          // don't use gamma (faster)\n          for (int y = 0; y < vi.height; ++y) {\n            for (int x = 0; x < vi.width; ++x) {\n              const float pixel = reinterpret_cast<float *>(p)[x];\n              reinterpret_cast<float *>(p)[x] = calcPixel<false, false>(pixel); // w/o gamma\n            }\n            p += pitch;\n          }\n        }\n        // chroma\n        if (need_chroma) {\n          const int UVpitch = frame->GetPitch(PLANAR_U);\n          const int w = frame->GetRowSize(PLANAR_U) / pixelsize;\n          const int h = frame->GetHeight(PLANAR_U);\n          p = frame->GetWritePtr(PLANAR_U);\n          BYTE* q = frame->GetWritePtr(PLANAR_V);\n          for (int y = 0; y < h; ++y) {\n            for (int x = 0; x < w; ++x) {\n              const float pixel_u = reinterpret_cast<float *>(p)[x];\n              reinterpret_cast<float *>(p)[x] = calcPixel<true, false>(pixel_u);\n              const float pixel_v = reinterpret_cast<float *>(q)[x];\n              reinterpret_cast<float *>(q)[x] = calcPixel<true, false>(pixel_v);\n            }\n            p += UVpitch;\n            q += UVpitch;\n          }\n        }\n      }\n      else if (vi.IsPlanarRGB() || vi.IsPlanarRGBA()) {\n        // planar RGB\n        BYTE* b = frame->GetWritePtr(PLANAR_B);\n        BYTE* r = frame->GetWritePtr(PLANAR_R);\n        const int pitch_b = frame->GetPitch(PLANAR_B);\n        const int pitch_r = frame->GetPitch(PLANAR_R);\n        if (use_gamma) {\n          for (int y = 0; y < vi.height; ++y) {\n            for (int x = 0; x < vi.width; ++x) {\n              const float pixel_p = reinterpret_cast<float *>(p)[x]; // g channel\n              reinterpret_cast<float *>(p)[x] = calcPixel<false, true>(pixel_p);\n              const float pixel_b = reinterpret_cast<float *>(b)[x];\n              reinterpret_cast<float *>(b)[x] = calcPixel<false, true>(pixel_b);\n              const float pixel_r = reinterpret_cast<float *>(r)[x];\n              reinterpret_cast<float *>(r)[x] = calcPixel<false, true>(pixel_r);\n            }\n            p += pitch; // g\n            b += pitch_b;\n            r += pitch_r;\n          }\n        }\n        else {\n          for (int y = 0; y < vi.height; ++y) {\n            for (int x = 0; x < vi.width; ++x) {\n              const float pixel_p = reinterpret_cast<float *>(p)[x]; // g channel\n              reinterpret_cast<float *>(p)[x] = calcPixel<false, false>(pixel_p);\n              const float pixel_b = reinterpret_cast<float *>(b)[x];\n              reinterpret_cast<float *>(b)[x] = calcPixel<false, false>(pixel_b);\n              const float pixel_r = reinterpret_cast<float *>(r)[x];\n              reinterpret_cast<float *>(r)[x] = calcPixel<false, false>(pixel_r);\n            }\n            p += pitch; // g\n            b += pitch_b;\n            r += pitch_r;\n          }\n        }\n      }\n      else {\n        // 32 bit, neither YUV(A), nor RGB(A)\n      }\n    }\n  }\n  return frame;\n}\n\nAVSValue __cdecl Levels::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  enum { CHILD, IN_MIN, GAMMA, IN_MAX, OUT_MIN, OUT_MAX, CORING, DITHER };\n  return new Levels( args[CHILD].AsClip(), (float)args[IN_MIN].AsFloat(), (float)args[GAMMA].AsFloat(), (float)args[IN_MAX].AsFloat(),\n    (float)args[OUT_MIN].AsFloat(), (float)args[OUT_MAX].AsFloat(), args[CORING].AsBool(true), args[DITHER].AsBool(false), env );\n}\n\n/********************************\n *******    RGBA Filter    ******\n ********************************/\n\n#define READ_CONDITIONAL(plane_num, var_name, internal_name, condVarSuffix)  \\\n    {                                                     \\\n        std::string s = \"rgbadjust_\" #var_name;\\\n        s = s + condVarSuffix; \\\n        const double t = env->GetVarDouble(s.c_str(), DBL_MIN); \\\n        if (t != DBL_MIN) {                             \\\n            config->rgba[plane_num].internal_name = t;  \\\n            config->rgba[plane_num].changed = true;     \\\n        }                                               \\\n    }\n\nstatic void rgbadjust_read_conditional(IScriptEnvironment* env, RGBAdjustConfig* config, const char * condVarSuffix)\n{\n  READ_CONDITIONAL(0, r, scale, condVarSuffix);\n  READ_CONDITIONAL(1, g, scale, condVarSuffix);\n  READ_CONDITIONAL(2, b, scale, condVarSuffix);\n  READ_CONDITIONAL(3, a, scale, condVarSuffix);\n\n  READ_CONDITIONAL(0, rb, bias, condVarSuffix);\n  READ_CONDITIONAL(1, gb, bias, condVarSuffix);\n  READ_CONDITIONAL(2, bb, bias, condVarSuffix);\n  READ_CONDITIONAL(3, ab, bias, condVarSuffix);\n\n  READ_CONDITIONAL(0, rg, gamma, condVarSuffix);\n  READ_CONDITIONAL(1, gg, gamma, condVarSuffix);\n  READ_CONDITIONAL(2, bg, gamma, condVarSuffix);\n  READ_CONDITIONAL(3, ag, gamma, condVarSuffix);\n}\n\n#undef READ_CONDITIONAL\n\n\n\nRGBAdjust::~RGBAdjust()\n{\n  if (map_holder)\n    delete[] map_holder;\n}\n\nvoid RGBAdjust::CheckAndConvertParams(RGBAdjustConfig &config, IScriptEnvironment *env)\n{\n  if ((config.rgba[0].gamma <= 0.0) || (config.rgba[1].gamma <= 0.0) || (config.rgba[2].gamma <= 0.0) || (config.rgba[3].gamma <= 0.0))\n    env->ThrowError(\"RGBAdjust: gammas must be positive\");\n}\n\nstatic __inline float RGBAdjust_processPixel(const float val, const double c0, const double c1, const double c2)\n{\n  const double pixel_max = 1.0;\n  return (float)(pow(clamp((c0 + val * c1) / pixel_max, 0.0, 1.0), c2));\n}\n\nvoid RGBAdjust::rgbadjust_create_lut(BYTE *lut_buf, const int plane, RGBAdjustConfig &cfg) {\n  if (!use_lut)\n    return;\n\n  const int lookup_size = 1 << bits_per_pixel; // 256, 1024, 4096, 16384, 65536\n\n  void(*set_map)(BYTE*, int, int, float, const double, const double, const double);\n  if (dither) {\n    set_map = [](BYTE* map, int lookup_size, int bits_per_pixel, float dither_strength, const double c0, const double c1, const double c2) {\n      double bias_dither = -(256.0f * dither_strength - 1) / 2; // -127.5 for 8 bit, scaling because of dithershift\n      double pixel_max = (1 << bits_per_pixel) - 1;\n      if (bits_per_pixel == 8) {\n        for (int i = 0; i < lookup_size * 256; ++i) {\n          int ii = (i & 0xFFFFFF00) + (int)((i & 0xFF)*dither_strength);\n          map[i] = BYTE(pow(clamp((c0 * 256 + ii * c1 - bias_dither) / (double(pixel_max) * 256), 0.0, 1.0), c2) * (double)pixel_max + 0.5);\n        }\n      }\n      else {\n        for (int i = 0; i < lookup_size * 256; ++i) {\n          int ii = (i & 0xFFFFFF00) + (int)((i & 0xFF)*dither_strength);\n          reinterpret_cast<uint16_t *>(map)[i] = uint16_t(pow(clamp((c0 * 256 + ii * c1 - bias_dither) / (double(pixel_max) * 256), 0.0, 1.0), c2) * (double)pixel_max + 0.5);\n        }\n      }\n    };\n  }\n  else {\n    set_map = [](BYTE* map, int lookup_size, int bits_per_pixel, float dither_strength, const double c0, const double c1, const double c2) {\n      double pixel_max = (1 << bits_per_pixel) - 1;\n      if (bits_per_pixel == 8) {\n        for (int i = 0; i < lookup_size; ++i) { // fix of bug introduced in an earlier refactor was: i < 256 * 256\n          map[i] = BYTE(pow(clamp((c0 + i * c1) / (double)pixel_max, 0.0, 1.0), c2) * double(pixel_max) + 0.5);\n        }\n      }\n      else {\n        for (int i = 0; i < lookup_size; ++i) { // fix of bug introduced in an earlier refactor was: i < 256 * 256\n          reinterpret_cast<uint16_t *>(map)[i] = uint16_t(pow(clamp((c0 + i * c1) / (double)pixel_max, 0.0, 1.0), c2) * double(pixel_max) + 0.5);\n        }\n      }\n    };\n  }\n\n  set_map(lut_buf, lookup_size, bits_per_pixel, dither_strength, cfg.rgba[plane].bias, cfg.rgba[plane].scale, 1 / cfg.rgba[plane].gamma);\n}\n\nRGBAdjust::RGBAdjust(PClip _child, double r, double g, double b, double a,\n    double rb, double gb, double bb, double ab,\n    double rg, double gg, double bg, double ag,\n    bool _analyze, bool _dither, bool _conditional, const char *_condVarSuffix, IScriptEnvironment* env)\n    : GenericVideoFilter(_child), analyze(_analyze), dither(_dither), condVarSuffix(_condVarSuffix)\n{\n    // one buffer for all maps\n    map_holder = nullptr;\n\n    if (!vi.IsRGB())\n        env->ThrowError(\"RGBAdjust requires RGB input\");\n\n    config.rgba[0].scale = r;\n    config.rgba[1].scale = g;\n    config.rgba[2].scale = b;\n    config.rgba[3].scale = a;\n    // bias\n    config.rgba[0].bias = rb;\n    config.rgba[1].bias = gb;\n    config.rgba[2].bias = bb;\n    config.rgba[3].bias = ab;\n    // gammas\n    config.rgba[0].gamma = rg;\n    config.rgba[1].gamma = gg;\n    config.rgba[2].gamma = bg;\n    config.rgba[3].gamma = ag;\n\n    config.rgba[0].changed = false;\n    config.rgba[1].changed = false;\n    config.rgba[2].changed = false;\n    config.rgba[3].changed = false;\n\n    CheckAndConvertParams(config, env);\n\n    pixelsize = vi.ComponentSize();\n    bits_per_pixel = vi.BitsPerComponent(); // 8,10..16\n\n    if (pixelsize == 4) {\n      // dither parameter is silently ignored\n      // if (dither) env->ThrowError(\"RGBAdjust: cannot 'dither' a 32bit float video\");\n    }\n    // No lookup for float. todo: slow on-the-fly realtime calculation\n\n    real_lookup_size = (pixelsize == 1) ? 256 : 65536; // avoids lut overflow in case of non-standard content of a 10 bit clip\n    max_pixel_value = (pixelsize == 4) ? 255 : (1 << bits_per_pixel) - 1; // n/a for float formats\n    dither_strength = 1.0f; // fixed, not used\n\n    use_lut = bits_per_pixel != 32; // for float: realtime (todo)\n\n    if (!use_lut)\n      dither = false;\n\n    if(use_lut) {\n      number_of_maps = (vi.IsRGB24() || vi.IsRGB48() || vi.IsPlanarRGB()) ? 3 : 4;\n      int one_bufsize = pixelsize * real_lookup_size;\n      if (dither) one_bufsize *= 256;\n\n      map_holder = new uint8_t[one_bufsize * number_of_maps];\n      /*\n      // left here intentionally:\n      // for some reason, AtExit does not get called from within ScriptClip, causing no free thus memory leak\n      // We are using new here and delete in destructor\n      static_cast<uint8_t*>(env->Allocate(one_bufsize * number_of_maps, 16, AVS_NORMAL_ALLOC));\n      if (!mapR)\n          env->ThrowError(\"RGBAdjust: Could not reserve memory.\");\n      env->AtExit(free_buffer, mapR);\n      */\n      if(bits_per_pixel>8 && bits_per_pixel<16) // make lut table safe for 10-14 bit garbage\n        std::fill_n(map_holder, one_bufsize * number_of_maps, 0); // 8 and 16 bit fully overwrites\n      maps[0] = map_holder;\n      maps[1] = maps[0] + one_bufsize;\n      maps[2] = maps[1] + one_bufsize;\n      maps[3] = number_of_maps == 4 ? maps[2] + one_bufsize : nullptr;\n\n      for (int plane = 0; plane < number_of_maps; plane++) {\n        rgbadjust_create_lut(maps[plane], plane, config);\n      }\n    }\n}\n\ntemplate<typename pixel_t>\nstatic void fill_accum_rgb_planar_c(const BYTE *srcpR, const BYTE* srcpG, const BYTE* srcpB, int pitch,\n  unsigned int *accum_r, unsigned int *accum_g, unsigned int *accum_b,\n  int width, int height, int max_pixel_value) {\n    for (int y = 0; y < height; y++) {\n      for (int x = 0; x < width; x++) {\n        int r = reinterpret_cast<const pixel_t*>(srcpR)[x];\n        int g = reinterpret_cast<const pixel_t*>(srcpG)[x];\n        int b = reinterpret_cast<const pixel_t*>(srcpB)[x];\n        if constexpr (sizeof(pixel_t) != 1) {\n          if (r > max_pixel_value) r = max_pixel_value;\n          if (g > max_pixel_value) g = max_pixel_value;\n          if (b > max_pixel_value) b = max_pixel_value;\n        }\n        accum_r[r]++;\n        accum_g[g]++;\n        accum_b[b]++;\n      }\n      srcpR += pitch;\n      srcpG += pitch;\n      srcpB += pitch;\n    }\n}\n\nstatic void fill_accum_rgb_planar_float_c(const BYTE* srcpR, const BYTE* srcpG, const BYTE* srcpB, int pitch,\n  unsigned int* accum_r, unsigned int* accum_g, unsigned int* accum_b,\n  int width, int height, RGBStats &rgbplanedata) {\n\n  for (int i = 0; i < 3; i++) {\n    rgbplanedata.data[i].real_max = std::numeric_limits<float>::min();\n    rgbplanedata.data[i].real_min = std::numeric_limits<float>::max();\n    rgbplanedata.data[i].sum = 0.0;\n  }\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < width; x++) {\n      // convert range 0..1 to 0..65535 for loose_min/max fake histogram\n      float r = reinterpret_cast<const float*>(srcpR)[x];\n      float g = reinterpret_cast<const float*>(srcpG)[x];\n      float b = reinterpret_cast<const float*>(srcpB)[x];\n      int ri = (int)(clamp(r * 65535.0f + 0.5f, 0.0f, 65535.0f));\n      int gi = (int)(clamp(g * 65535.0f + 0.5f, 0.0f, 65535.0f));\n      int bi = (int)(clamp(b * 65535.0f + 0.5f, 0.0f, 65535.0f));\n      if (r > rgbplanedata.data[0].real_max) rgbplanedata.data[0].real_max = r;\n      if (r < rgbplanedata.data[0].real_min) rgbplanedata.data[0].real_min = r;\n      rgbplanedata.data[0].sum += r;\n      if (g > rgbplanedata.data[1].real_max) rgbplanedata.data[1].real_max = g;\n      if (g < rgbplanedata.data[1].real_min) rgbplanedata.data[1].real_min = g;\n      rgbplanedata.data[1].sum += g;\n      if (b > rgbplanedata.data[2].real_max) rgbplanedata.data[2].real_max = b;\n      if (b < rgbplanedata.data[2].real_min) rgbplanedata.data[2].real_min = b;\n      rgbplanedata.data[2].sum += b;\n      accum_r[ri]++;\n      accum_g[gi]++;\n      accum_b[bi]++;\n    }\n    srcpR += pitch;\n    srcpG += pitch;\n    srcpB += pitch;\n  }\n}\n\ntemplate<typename pixel_t>\nstatic void fill_accum_rgb_packed_c(const BYTE *srcp, int pitch,\n  unsigned int *accum_r, unsigned int *accum_g, unsigned int *accum_b,\n  int work_width, int height, int pixel_step) {\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < work_width; x += pixel_step) {\n      accum_r[reinterpret_cast<const pixel_t *>(srcp)[x + 2]]++;\n      accum_g[reinterpret_cast<const pixel_t *>(srcp)[x + 1]]++;\n      accum_b[reinterpret_cast<const pixel_t *>(srcp)[x + 0]]++;\n    }\n    srcp += pitch;\n  }\n}\n\ntemplate<typename pixel_t, int pixel_step, bool dither>\nstatic void apply_map_rgb_packed_c(BYTE *dstp8, int pitch,\n  BYTE *mapR, BYTE *mapG, BYTE *mapB, BYTE *mapA,\n  int width, int height)\n{\n  int _y = 0;\n  int _dither = 0;\n  pixel_t *dstp = reinterpret_cast<pixel_t *>(dstp8);\n  pitch /= sizeof(pixel_t);\n\n  for (int y = 0; y < height; y++) {\n    if(dither)\n      _y = (y << 4) & 0xf0;\n    for (int x = 0; x < width; x++) {\n      if (dither)\n        _dither = ditherMap[(x & 0x0f) | _y];\n      dstp[x * pixel_step + 0] = reinterpret_cast<pixel_t *>(mapB)[dither ? dstp[x * pixel_step + 0] << 8 | _dither : dstp[x * pixel_step + 0]];\n      dstp[x * pixel_step + 1] = reinterpret_cast<pixel_t *>(mapG)[dither ? dstp[x * pixel_step + 1] << 8 | _dither : dstp[x * pixel_step + 1]];\n      dstp[x * pixel_step + 2] = reinterpret_cast<pixel_t *>(mapR)[dither ? dstp[x * pixel_step + 2] << 8 | _dither : dstp[x * pixel_step + 2]];\n      if constexpr(pixel_step == 4)\n        dstp[x * pixel_step + 3] = reinterpret_cast<pixel_t *>(mapA)[dither ? dstp[x * pixel_step + 3] << 8 | _dither : dstp[x * pixel_step + 3]];\n    }\n    dstp += pitch;\n  }\n}\n\ntemplate<typename pixel_t, bool hasAlpha, bool dither>\nstatic void apply_map_rgb_planar_c(BYTE *dstpR8, BYTE *dstpG8, BYTE *dstpB8, BYTE *dstpA8, int pitch,\n  BYTE *mapR, BYTE *mapG, BYTE *mapB, BYTE *mapA,\n  int width, int height)\n{\n  int _y = 0;\n  int _dither = 0;\n  pixel_t *dstpR = reinterpret_cast<pixel_t *>(dstpR8);\n  pixel_t *dstpG = reinterpret_cast<pixel_t *>(dstpG8);\n  pixel_t *dstpB = reinterpret_cast<pixel_t *>(dstpB8);\n  pixel_t *dstpA = reinterpret_cast<pixel_t *>(dstpA8);\n  pitch /= sizeof(pixel_t);\n\n  for (int y = 0; y < height; y++) {\n    if(dither)\n      _y = (y << 4) & 0xf0;\n    for (int x = 0; x < width; x++) {\n      if (dither)\n        _dither = ditherMap[(x & 0x0f) | _y];\n      reinterpret_cast<pixel_t *>(dstpG)[x] = reinterpret_cast<pixel_t *>(mapG)[dither ? dstpG[x] << 8 | _dither : dstpG[x]];\n      reinterpret_cast<pixel_t *>(dstpB)[x] = reinterpret_cast<pixel_t *>(mapB)[dither ? dstpB[x] << 8 | _dither : dstpB[x]];\n      reinterpret_cast<pixel_t *>(dstpR)[x] = reinterpret_cast<pixel_t *>(mapR)[dither ? dstpR[x] << 8 | _dither : dstpR[x]];\n      if(hasAlpha)\n        reinterpret_cast<pixel_t *>(dstpA)[x] = reinterpret_cast<pixel_t *>(mapA)[dither ? dstpA[x] << 8 | _dither : dstpA[x]];\n    }\n    dstpG += pitch; dstpB += pitch; dstpR += pitch;\n    if(hasAlpha)\n      dstpA += pitch;\n  }\n}\n\n\nPVideoFrame __stdcall RGBAdjust::GetFrame(int n, IScriptEnvironment* env)\n{\n    PVideoFrame frame = child->GetFrame(n, env);\n    env->MakeWritable(&frame);\n    BYTE* p = frame->GetWritePtr();\n    const int pitch = frame->GetPitch();\n\n    int w = vi.width;\n    int h = vi.height;\n\n    RGBAdjustConfig local_config = config;\n\n    // Read conditional variables\n    local_config.rgba[0].changed = false;\n    local_config.rgba[1].changed = false;\n    local_config.rgba[2].changed = false;\n    local_config.rgba[3].changed = false;\n    rgbadjust_read_conditional(env, &local_config, condVarSuffix);\n\n    BYTE *maps_live[4] = { nullptr };\n    BYTE *maps_local[4] = { nullptr }; // for local lut table allocation, don't overwrite common buffer\n    for (int i = 0; i < 4; i++)\n      maps_live[i] = maps[i];\n\n    if (local_config.rgba[0].changed || local_config.rgba[1].changed || local_config.rgba[2].changed || local_config.rgba[3].changed) {\n      CheckAndConvertParams(local_config, env);\n      if (use_lut) {\n        for (int plane = 0; plane < (int)number_of_maps; plane++) {\n          // recalculate plane LUT only if changed\n          if (local_config.rgba[plane].changed)\n          {\n            maps_local[plane] = new BYTE[pixelsize * real_lookup_size];\n            maps_live[plane] = maps_local[plane]; // use our new local lut\n            rgbadjust_create_lut(maps_live[plane], plane, local_config);\n          }\n        }\n      }\n    }\n\n    if (dither) {\n      if (vi.IsRGB32())\n        apply_map_rgb_packed_c<uint8_t, 4, true>(p, pitch, maps_live[0], maps_live[1], maps_live[2], maps_live[3], w, h);\n      else if(vi.IsRGB24())\n        apply_map_rgb_packed_c<uint8_t, 3, true>(p, pitch, maps_live[0], maps_live[1], maps_live[2], maps_live[3], w, h);\n      else if(vi.IsRGB64())\n        apply_map_rgb_packed_c<uint16_t, 4, true>(p, pitch, maps_live[0], maps_live[1], maps_live[2], maps_live[3], w, h);\n      else if(vi.IsRGB48())\n        apply_map_rgb_packed_c<uint16_t, 3, true>(p, pitch, maps_live[0], maps_live[1], maps_live[2], maps_live[3], w, h);\n      else {\n        // Planar RGB\n        bool hasAlpha = vi.IsPlanarRGBA();\n        BYTE *p_g = p;\n        BYTE *p_b = frame->GetWritePtr(PLANAR_B);\n        BYTE *p_r = frame->GetWritePtr(PLANAR_R);\n        BYTE *p_a = frame->GetWritePtr(PLANAR_A);\n        // no float support\n        if(pixelsize==1) {\n          if(hasAlpha)\n            apply_map_rgb_planar_c<uint8_t, true, true>(p_r, p_g, p_b, p_a, pitch, maps_live[0], maps_live[1], maps_live[2], maps_live[3], w, h);\n          else\n            apply_map_rgb_planar_c<uint8_t, false, true>(p_r, p_g, p_b, p_a, pitch, maps_live[0], maps_live[1], maps_live[2], maps_live[3], w, h);\n        }\n        else {\n          if(hasAlpha)\n            apply_map_rgb_planar_c<uint16_t, true, true>(p_r, p_g, p_b, p_a, pitch, maps_live[0], maps_live[1], maps_live[2], maps_live[3], w, h);\n          else\n            apply_map_rgb_planar_c<uint16_t, false, true>(p_r, p_g, p_b, p_a, pitch, maps_live[0], maps_live[1], maps_live[2], maps_live[3], w, h);\n        }\n      }\n    }\n    else {\n      // no dither\n      if (vi.IsRGB32())\n        apply_map_rgb_packed_c<uint8_t, 4, false>(p, pitch, maps_live[0], maps_live[1], maps_live[2], maps_live[3], w, h);\n      else if(vi.IsRGB24())\n        apply_map_rgb_packed_c<uint8_t, 3, false>(p, pitch, maps_live[0], maps_live[1], maps_live[2], maps_live[3], w, h);\n      else if(vi.IsRGB64())\n        apply_map_rgb_packed_c<uint16_t, 4, false>(p, pitch, maps_live[0], maps_live[1], maps_live[2], maps_live[3], w, h);\n      else if(vi.IsRGB48())\n        apply_map_rgb_packed_c<uint16_t, 3, false>(p, pitch, maps_live[0], maps_live[1], maps_live[2], maps_live[3], w, h);\n      else {\n          // Planar RGB\n        bool hasAlpha = vi.IsPlanarRGBA();\n        BYTE *p_g = p;\n        BYTE *p_b = frame->GetWritePtr(PLANAR_B);\n        BYTE *p_r = frame->GetWritePtr(PLANAR_R);\n        BYTE *p_a = frame->GetWritePtr(PLANAR_A);\n        // no float support\n        if(pixelsize==1) {\n          if(hasAlpha)\n            apply_map_rgb_planar_c<uint8_t, true, false>(p_r, p_g, p_b, p_a, pitch, maps_live[0], maps_live[1], maps_live[2], maps_live[3], w, h);\n          else\n            apply_map_rgb_planar_c<uint8_t, false, false>(p_r, p_g, p_b, p_a, pitch, maps_live[0], maps_live[1], maps_live[2], maps_live[3], w, h);\n        }\n        else if(pixelsize==2) {\n          if(hasAlpha)\n            apply_map_rgb_planar_c<uint16_t, true, false>(p_r, p_g, p_b, p_a, pitch, maps_live[0], maps_live[1], maps_live[2], maps_live[3], w, h);\n          else\n            apply_map_rgb_planar_c<uint16_t, false, false>(p_r, p_g, p_b, p_a, pitch, maps_live[0], maps_live[1], maps_live[2], maps_live[3], w, h);\n        }\n        else {\n          // 32 bit float, no dither\n          const int planesRGB_RgbaOrder[4] = { PLANAR_R, PLANAR_G, PLANAR_B, PLANAR_A };\n          const int *planes = planesRGB_RgbaOrder;\n\n          for (int cplane = 0; cplane < (hasAlpha ? 4 : 3); cplane++) {\n            RGBAdjustPlaneConfig x = local_config.rgba[cplane];\n            const double scale = x.scale;\n            const double bias = x.bias;\n            const double gamma = 1 / x.gamma;\n            int plane = planes[cplane];\n            float* dstp = reinterpret_cast<float *>(frame->GetWritePtr(plane));\n            int pitch = frame->GetPitch(plane) / sizeof(float);\n            for (int y = 0; y < h; y++) {\n              for (int x = 0; x < w; x++) {\n                dstp[x] = RGBAdjust_processPixel(dstp[x], bias, scale, gamma);\n              }\n              dstp += pitch;\n            }\n          }\n        }\n      }\n    }\n\n    if (use_lut && conditional) {\n      for(int i = 0; i<4; i++)\n        if (maps_local[i]) delete[] maps_local[i];\n    }\n\n    if (analyze) {\n        const int w = frame->GetRowSize() / pixelsize;\n        const int h = frame->GetHeight();\n\n        const int analyze_lookup_size = pixelsize == 4 ? 1 << 16 : 1 << bits_per_pixel; // 32 bit float is quantized to 16 bits\n        const int max_pixel_value_analyze = analyze_lookup_size - 1;\n\n        // allocate 3x bufsize for R. G and B will share it\n        auto accum_r = static_cast<uint32_t*>(env->Allocate(analyze_lookup_size * sizeof(uint32_t) * 3, 16, AVS_NORMAL_ALLOC));\n        auto accum_g = accum_r + analyze_lookup_size;\n        auto accum_b = accum_g + analyze_lookup_size;\n        if (!accum_r)\n          env->ThrowError(\"RGBAdjust: Could not reserve memory.\");\n\n        for (int i = 0; i < analyze_lookup_size; i++) {\n          accum_r[i] = 0;\n          accum_g[i] = 0;\n          accum_b[i] = 0;\n        }\n\n        const int pixels = vi.width * vi.height;\n\n        if (bits_per_pixel == 32) {\n          RGBStats rgbplanedata;\n          const BYTE* p_g = frame->GetReadPtr(PLANAR_G);;\n          const BYTE* p_b = frame->GetReadPtr(PLANAR_B);\n          const BYTE* p_r = frame->GetReadPtr(PLANAR_R);\n          fill_accum_rgb_planar_float_c(p_r, p_g, p_b, pitch, accum_r, accum_g, accum_b, w, h, rgbplanedata);\n\n          double avg_r = rgbplanedata.data[0].sum / pixels;\n          double avg_g = rgbplanedata.data[1].sum / pixels;\n          double avg_b = rgbplanedata.data[2].sum / pixels;\n\n          int Amin_r = 0, Amin_g = 0, Amin_b = 0;\n          int Amax_r = 0, Amax_g = 0, Amax_b = 0;\n          bool Ahit_minr = false, Ahit_ming = false, Ahit_minb = false;\n          bool Ahit_maxr = false, Ahit_maxg = false, Ahit_maxb = false;\n          int At_256 = (pixels + 128) / 256; // When 1/256th of all pixels have been reached, trigger \"Loose min/max\"\n\n          double st_r = 0, st_g = 0, st_b = 0;\n\n          for (int i = 0; i < analyze_lookup_size; i++) {\n            double i_float = i / 65535.0;\n            st_r += accum_r[i] * (i_float - avg_r) * (i_float - avg_r);\n            st_g += accum_g[i] * (i_float - avg_g) * (i_float - avg_g);\n            st_b += accum_b[i] * (i_float - avg_b) * (i_float - avg_b);\n\n            // loose min\n            if (!Ahit_minr) { Amin_r += accum_r[i]; if (Amin_r > At_256) { Ahit_minr = true; Amin_r = i; } }\n            if (!Ahit_ming) { Amin_g += accum_g[i]; if (Amin_g > At_256) { Ahit_ming = true; Amin_g = i; } }\n            if (!Ahit_minb) { Amin_b += accum_b[i]; if (Amin_b > At_256) { Ahit_minb = true; Amin_b = i; } }\n            // loose max\n            if (!Ahit_maxr) { Amax_r += accum_r[max_pixel_value_analyze - i]; if (Amax_r > At_256) { Ahit_maxr = true; Amax_r = max_pixel_value_analyze - i; } }\n            if (!Ahit_maxg) { Amax_g += accum_g[max_pixel_value_analyze - i]; if (Amax_g > At_256) { Ahit_maxg = true; Amax_g = max_pixel_value_analyze - i; } }\n            if (!Ahit_maxb) { Amax_b += accum_b[max_pixel_value_analyze - i]; if (Amax_b > At_256) { Ahit_maxb = true; Amax_b = max_pixel_value_analyze - i; } }\n          }\n\n          auto Fst_r = sqrt(st_r / pixels);\n          auto Fst_g = sqrt(st_g / pixels);\n          auto Fst_b = sqrt(st_b / pixels);\n\n          char text[512];\n          const bool StatsAsInteger16 = false;\n          if(StatsAsInteger16)\n            sprintf(text,\n              \"At 16 bits.  Frame: %-8u (   Red   /  Green  /  Blue   )\\n\"\n              \"           Average:      ( %7.2f / %7.2f / %7.2f )\\n\"\n              \"Standard Deviation:      ( %7.2f / %7.2f / %7.2f )\\n\"\n              \"           Minimum:      ( %7.2f / %7.2f / %7.2f )\\n\"\n              \"           Maximum:      ( %7.2f / %7.2f / %7.2f )\\n\"\n              \"     Loose Minimum:      ( %5d    / %5d    / %5d    )\\n\"\n              \"     Loose Maximum:      ( %5d    / %5d    / %5d    )\\n\"\n              ,\n              (unsigned int)n,\n              avg_r * 65535, avg_g * 65535, avg_b * 65535,\n              Fst_r * 65535, Fst_g * 65535, Fst_b * 65535,\n              rgbplanedata.data[0].real_min * 65535, rgbplanedata.data[1].real_min * 65535, rgbplanedata.data[2].real_min * 65535,\n              rgbplanedata.data[0].real_max * 65535, rgbplanedata.data[1].real_max * 65535, rgbplanedata.data[2].real_max * 65535,\n              Amin_r, Amin_g, Amin_b,\n              Amax_r, Amax_g, Amax_b\n            );\n          else // stats as Float\n            sprintf(text,\n              \"             Frame: %-8u (   Red   /  Green  /  Blue   )\\n\"\n              \"           Average:      ( %7.5f / %7.5f / %7.5f )\\n\"\n              \"Standard Deviation:      ( %7.5f / %7.5f / %7.5f )\\n\"\n              \"           Minimum:      ( %7.5f / %7.5f / %7.5f )\\n\"\n              \"           Maximum:      ( %7.5f / %7.5f / %7.5f )\\n\"\n              \"     Loose Minimum:      ( %7.5f / %7.5f / %7.5f )\\n\"\n              \"     Loose Maximum:      ( %7.5f / %7.5f / %7.5f )\\n\"\n              ,\n              (unsigned int)n,\n              avg_r, avg_g, avg_b,\n              Fst_r, Fst_g, Fst_b,\n              rgbplanedata.data[0].real_min, rgbplanedata.data[1].real_min, rgbplanedata.data[2].real_min,\n              rgbplanedata.data[0].real_max, rgbplanedata.data[1].real_max, rgbplanedata.data[2].real_max,\n              Amin_r / 65535.0, Amin_g / 65535.0, Amin_b / 65535.0,\n              Amax_r / 65535.0, Amax_g / 65535.0, Amax_b / 65535.0\n            );\n          env->ApplyMessage(&frame, vi, text, vi.width / 4, 0xa0a0a0, 0, 0);\n        }\n        else {\n\n          if (vi.IsPlanarRGB() || vi.IsPlanarRGBA())\n          {\n            const BYTE* p_g = frame->GetReadPtr(PLANAR_G);;\n            const BYTE* p_b = frame->GetReadPtr(PLANAR_B);\n            const BYTE* p_r = frame->GetReadPtr(PLANAR_R);\n            if (bits_per_pixel == 8)\n              fill_accum_rgb_planar_c<uint8_t>(p_r, p_g, p_b, pitch, accum_r, accum_g, accum_b, w, h, max_pixel_value_analyze);\n            else if (bits_per_pixel <= 16)\n              fill_accum_rgb_planar_c<uint16_t>(p_r, p_g, p_b, pitch, accum_r, accum_g, accum_b, w, h, max_pixel_value_analyze);\n            else // 32 bit float\n              ;// handled in other branch;\n          }\n          else {\n            // packed RGB\n            const BYTE* srcp = frame->GetReadPtr();\n            const int pixel_step = vi.IsRGB24() || vi.IsRGB48() ? 3 : 4;\n\n            if (pixelsize == 1)\n              fill_accum_rgb_packed_c<uint8_t>(srcp, pitch, accum_r, accum_g, accum_b, w, h, pixel_step);\n            else\n              fill_accum_rgb_packed_c<uint16_t>(srcp, pitch, accum_r, accum_g, accum_b, w, h, pixel_step);\n          }\n\n          double avg_r = 0, avg_g = 0, avg_b = 0;\n          double st_r = 0, st_g = 0, st_b = 0;\n          int min_r = 0, min_g = 0, min_b = 0;\n          int max_r = 0, max_g = 0, max_b = 0;\n          bool hit_r = false, hit_g = false, hit_b = false;\n          int Amin_r = 0, Amin_g = 0, Amin_b = 0;\n          int Amax_r = 0, Amax_g = 0, Amax_b = 0;\n          bool Ahit_minr = false, Ahit_ming = false, Ahit_minb = false;\n          bool Ahit_maxr = false, Ahit_maxg = false, Ahit_maxb = false;\n          int At_256 = (pixels + 128) / 256; // When 1/256th of all pixels have been reached, trigger \"Loose min/max\"\n\n          for (int i = 0; i < analyze_lookup_size; i++) {\n            avg_r += (double)accum_r[i] * i;\n            avg_g += (double)accum_g[i] * i;\n            avg_b += (double)accum_b[i] * i;\n\n            if (accum_r[i] != 0) { max_r = i; hit_r = true; }\n            else { if (!hit_r) min_r = i + 1; }\n            if (accum_g[i] != 0) { max_g = i; hit_g = true; }\n            else { if (!hit_g) min_g = i + 1; }\n            if (accum_b[i] != 0) { max_b = i; hit_b = true; }\n            else { if (!hit_b) min_b = i + 1; }\n\n            if (!Ahit_minr) { Amin_r += accum_r[i]; if (Amin_r > At_256) { Ahit_minr = true; Amin_r = i; } }\n            if (!Ahit_ming) { Amin_g += accum_g[i]; if (Amin_g > At_256) { Ahit_ming = true; Amin_g = i; } }\n            if (!Ahit_minb) { Amin_b += accum_b[i]; if (Amin_b > At_256) { Ahit_minb = true; Amin_b = i; } }\n\n            if (!Ahit_maxr) { Amax_r += accum_r[max_pixel_value_analyze - i]; if (Amax_r > At_256) { Ahit_maxr = true; Amax_r = max_pixel_value_analyze - i; } }\n            if (!Ahit_maxg) { Amax_g += accum_g[max_pixel_value_analyze - i]; if (Amax_g > At_256) { Ahit_maxg = true; Amax_g = max_pixel_value_analyze - i; } }\n            if (!Ahit_maxb) { Amax_b += accum_b[max_pixel_value_analyze - i]; if (Amax_b > At_256) { Ahit_maxb = true; Amax_b = max_pixel_value_analyze - i; } }\n          }\n\n          float Favg_r = (float)(avg_r / pixels);\n          float Favg_g = (float)(avg_g / pixels);\n          float Favg_b = (float)(avg_b / pixels);\n\n          for (int i = 0; i < analyze_lookup_size; i++) {\n            st_r += (float)accum_r[i] * (float(i - Favg_r) * (i - Favg_r));\n            st_g += (float)accum_g[i] * (float(i - Favg_g) * (i - Favg_g));\n            st_b += (float)accum_b[i] * (float(i - Favg_b) * (i - Favg_b));\n          }\n\n          float Fst_r = (float)sqrt(st_r / pixels);\n          float Fst_g = (float)sqrt(st_g / pixels);\n          float Fst_b = (float)sqrt(st_b / pixels);\n\n          char text[512];\n          if (bits_per_pixel == 8)\n            sprintf(text,\n              \"             Frame: %-8u (  Red  / Green / Blue  )\\n\"\n              \"           Average:      ( %5.2f / %5.2f / %5.2f )\\n\"\n              \"Standard Deviation:      ( %5.2f / %5.2f / %5.2f )\\n\"\n              \"           Minimum:      ( %3d    / %3d    / %3d    )\\n\"\n              \"           Maximum:      ( %3d    / %3d    / %3d    )\\n\"\n              \"     Loose Minimum:      ( %3d    / %3d    / %3d    )\\n\"\n              \"     Loose Maximum:      ( %3d    / %3d    / %3d    )\\n\"\n              ,\n              (unsigned int)n,\n              Favg_r, Favg_g, Favg_b,\n              Fst_r, Fst_g, Fst_b,\n              min_r, min_g, min_b,\n              max_r, max_g, max_b,\n              Amin_r, Amin_g, Amin_b,\n              Amax_r, Amax_g, Amax_b\n            );\n          else // if (bits_per_pixel <= 16)\n            sprintf(text,\n              \"             Frame: %-8u (  Red  / Green / Blue  )\\n\"\n              \"           Average:      ( %7.2f / %7.2f / %7.2f )\\n\"\n              \"Standard Deviation:      ( %7.2f / %7.2f / %7.2f )\\n\"\n              \"           Minimum:      ( %5d    / %5d    / %5d    )\\n\"\n              \"           Maximum:      ( %5d    / %5d    / %5d    )\\n\"\n              \"     Loose Minimum:      ( %5d    / %5d    / %5d    )\\n\"\n              \"     Loose Maximum:      ( %5d    / %5d    / %5d    )\\n\"\n              ,\n              (unsigned int)n,\n              Favg_r, Favg_g, Favg_b,\n              Fst_r, Fst_g, Fst_b,\n              min_r, min_g, min_b,\n              max_r, max_g, max_b,\n              Amin_r, Amin_g, Amin_b,\n              Amax_r, Amax_g, Amax_b\n            );\n          env->ApplyMessage(&frame, vi, text, vi.width / 4, 0xa0a0a0, 0, 0);\n        }\n        env->Free(accum_r);\n    }\n    return frame;\n}\n\n\nAVSValue __cdecl RGBAdjust::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  return new RGBAdjust(args[ 0].AsClip(),\n                       args[ 1].AsDblDef(1.0), args[ 2].AsDblDef(1.0), args[ 3].AsDblDef(1.0), args[ 4].AsDblDef(1.0),\n                       args[ 5].AsDblDef(0.0), args[ 6].AsDblDef(0.0), args[ 7].AsDblDef(0.0), args[ 8].AsDblDef(0.0),\n                       args[ 9].AsDblDef(1.0), args[10].AsDblDef(1.0), args[11].AsDblDef(1.0), args[12].AsDblDef(1.0),\n                       args[13].AsBool(false), args[14].AsBool(false), args[15].AsBool(false), args[16].AsString(\"\"), env );\n}\n\n\n\n/* helper function for Tweak and MaskHS filters */\nstatic bool ProcessPixel(double X, double Y, double startHue, double endHue,\n    double maxSat, double minSat, double p, int &iSat)\n{\n    // a hue analog\n    double T = atan2(X, Y) * 180.0 / PI;\n    if (T < 0.0) T += 360.0;\n\n    // startHue <= hue <= endHue\n    if (startHue < endHue) {\n        if (T > endHue || T < startHue) return false;\n    }\n    else {\n        if (T<startHue && T>endHue) return false;\n    }\n\n    const double W = X*X + Y*Y;\n\n    // In Range, full adjust but no need to interpolate\n    if (minSat*minSat <= W && W <= maxSat*maxSat) return true;\n\n    // p == 0 (no interpolation) needed for MaskHS\n    if (p == 0.0) return false;\n\n    // Interpolation range is +/-p for p>0\n    // 180 is not in degrees!\n    // its sqrt(127^2 + 127^2): max overshoot for 8 bits; U and V is 0 +/- 127\n    const double max = min(maxSat + p, 180.0);\n    const double min = ::max(minSat - p, 0.0);\n\n    // Outside of [min-p, max+p] no adjustment\n    // minSat-p <= (U^2 + V^2) <= maxSat+p\n    if (W <= min*min || max*max <= W) return false; // don't adjust\n\n    // Interpolate saturation value\n    const double holdSat = W < 180.0*180.0 ? sqrt(W) : 180.0;\n\n    if (holdSat < minSat) { // within p of lower range\n        iSat += (int)((512 - iSat) * (minSat - holdSat) / p);\n    }\n    else { // within p of upper range\n        iSat += (int)((512 - iSat) * (holdSat - maxSat) / p);\n    }\n\n    return true;\n}\n\n// for float\nstatic bool ProcessPixelUnscaled(double X, double Y, double startHue, double endHue,\n    double maxSat, double minSat, double p, double &dSat)\n{\n    // a hue analog\n    double T = atan2(X, Y) * 180.0 / PI;\n    if (T < 0.0) T += 360.0;\n\n    // startHue <= hue <= endHue\n    if (startHue < endHue) {\n        if (T > endHue || T < startHue) return false;\n    }\n    else {\n        if (T<startHue && T>endHue) return false;\n    }\n\n    const double W = X*X + Y*Y;\n\n    // In Range, full adjust but no need to interpolate\n    if (minSat*minSat <= W && W <= maxSat*maxSat) return true;\n\n    // p == 0 (no interpolation) needed for MaskHS\n    if (p == 0.0) return false;\n\n    // Interpolation range is +/-p for p>0\n    const double max = min(maxSat + p, 180.0);\n    const double min = ::max(minSat - p, 0.0);\n\n    // Outside of [min-p, max+p] no adjustment\n    // minSat-p <= (U^2 + V^2) <= maxSat+p\n    if (W <= min*min || max*max <= W) return false; // don't adjust\n\n    // Interpolate saturation value\n    const double holdSat = W < 180.0*180.0 ? sqrt(W) : 180.0;\n\n    if (holdSat < minSat) { // within p of lower range\n        dSat += ((1 - dSat) * (minSat - holdSat) / p);\n    }\n    else { // within p of upper range\n        dSat += ((1 - dSat) * (holdSat - maxSat) / p);\n    }\n\n    return true;\n}\n\n\n/**********************\n******   Tweak    *****\n**********************/\ntemplate<typename pixel_t, bool bpp10_14, bool dither>\nvoid Tweak::tweak_calc_luma(BYTE *srcp, int src_pitch, float minY, float maxY, int width, int height)\n{\n  float ditherval = 0.0f;\n  for (int y = 0; y < height; ++y) {\n    const int _y = (y << 4) & 0xf0;\n    for (int x = 0; x < width; ++x) {\n      if (dither)\n        ditherval = (ditherMap[(x & 0x0f) | _y] * dither_strength + bias_dither_luma) / (float)scale_dither_luma; // 0x00..0xFF -> -0.7F .. + 0.7F (+/- maxrange/512)\n      float y0 = reinterpret_cast<pixel_t *>(srcp)[x] - minY;\n      if(bpp10_14)\n        y0 = minY + (y0 + ditherval)*(float)dcont + (float)(1 << (bits_per_pixel - 8))*(float)dbright; // dbright parameter always 0..255. Scale to 0..255*4, 0.. 255*256\n      else if(pixelsize == 2)\n        y0 = minY + (y0 + ditherval)*(float)dcont + 256.0f*(float)dbright; // dbright parameter always 0..255. Scale to 0..255*4, 0.. 255*256\n      else if(pixelsize == 4)\n        y0 = minY + (y0 + ditherval)*(float)dcont + (float)dbright / 256.0f; // dbright parameter always 0..255, scale it to 0..1\n      else // pixelsize == 1\n        y0 = minY + ((y0 + ditherval)*(float)dcont + 1.0f*(float)dbright); // dbright parameter always 0..255. Scale to 0..255*4, 0.. 255*256\n\n      reinterpret_cast<pixel_t *>(srcp)[x] = (pixel_t)clamp(y0, minY, maxY);\n      /*\n      int y = int(((ii - range_low * scale_dither_luma)*_cont + _bright * scale_dither_luma + bias_dither_luma) / scale_dither_luma + range_low + 0.5); // 256 _cont & _bright param range\n      // coring, dither:\n      // int y = int(((ii - 16 * 256)*_cont + _bright * 256 - 127.5) / 256 + 16.5); // 256 _cont & _bright param range\n      // coring, no dither:\n      // int y = int(((ii - 16)*_cont + _bright) + 16.5); // 256 _cont & _bright param range\n      // no coring, dither:\n      // int y = int((ii *_cont + _bright * 256 - 127.5) / 256 + 0.5 ); // 256 _cont & _bright param range\n      // no coring, no dither:\n      // int y = int((ii *_cont + _bright) + 0.5 ); // 256 _cont & _bright param range\n      */\n    }\n    srcp += src_pitch;\n  }\n}\n\nTweak::Tweak(PClip _child, double _hue, double _sat, double _bright, double _cont, bool _coring,\n            double _startHue, double _endHue, double _maxSat, double _minSat, double p,\n            bool _dither, bool _realcalc, double _dither_strength, IScriptEnvironment* env)\n  : GenericVideoFilter(_child), coring(_coring), \n  dither(_dither), realcalc(_realcalc),\n  dhue(_hue), dsat(_sat), dbright(_bright), dcont(_cont), dstartHue(_startHue), dendHue(_endHue),\n  dmaxSat(_maxSat), dminSat(_minSat), dinterp(p), dither_strength((float)_dither_strength)\n{\n  if (vi.IsRGB())\n        env->ThrowError(\"Tweak: YUV data only (no RGB)\");\n\n  pixelsize = vi.ComponentSize();\n  bits_per_pixel = vi.BitsPerComponent();\n  max_pixel_value = (1 << bits_per_pixel) - 1;\n  lut_size = 1 << bits_per_pixel;\n  int safe_luma_lookup_size = (pixelsize == 1) ? 256 : 65536; // avoids lut overflow in case of non-standard content of a 10 bit clip\n\n  get_limits(limits, bits_per_pixel); // tv range limits\n\n  scale_dither_luma = 1;\n  divisor_dither_luma = 1;\n  bias_dither_luma = 0.0;\n\n  scale_dither_chroma = 1;\n  divisor_dither_chroma = 1;\n  bias_dither_chroma = 0.0;\n\n  if (pixelsize == 4)\n    dither_strength /= 65536.0f; // same dither range as for a 16 bit clip\n  // Set dither_strength = 4.0 for 10 bits or 256.0 for 16 bits in order to have same dither range as for 8 bits\n  // Otherwise dithering is always +/- 0.5 at all bit-depth\n\n  if (dither) {\n    // lut scale settings\n    scale_dither_luma = 256; // lower 256 is dither value\n    divisor_dither_luma *= 256;\n    bias_dither_luma = -(256.0f * dither_strength - 1) / 2;\n    // original bias: -127.5 or -(256.0f * dither_strength - 1) / 2;\n    // dither strength =1 = (1 << (8-8))\n    // dither min: int( (0*1-127.5)/256+0.5) = -0.498046875 + 0.5 = 0,001953125\n    // dither max: int( (255*1-127.5)/256+0.5) = 0,998046875\n\n    // 16 bit: 32767,5\n    // dither strength =256 = (1 << (16-8))\n    // dither min: int( (0*256-32767,5)/256+0.5)   = -127,498046875\n    // dither max: int( (255*256-32767,5)/256+0.5) = 127,501953125\n\n\n    scale_dither_chroma = 16; // lower 16 is dither value\n    divisor_dither_chroma *= 16;\n    bias_dither_chroma = -(16.0f * dither_strength - (pixelsize==4 ? 1/256.0f : 1)) / 2; // -7.5\n  }\n\n  // Flag to skip special processing if doing all pixels\n  // If defaults, don't check for ranges, just do all\n  allPixels = (_startHue == 0.0 && _endHue == 360.0 && _maxSat == 150.0 && _minSat == 0.0);\n\n  if (vi.NumComponents() == 1) {\n      if (!(_hue == 0.0 && _sat == 1.0 && allPixels))\n      env->ThrowError(\"Tweak: bright and cont are the only options available for greyscale.\");\n  }\n\n  if (_startHue < 0.0 || _startHue >= 360.0)\n        env->ThrowError(\"Tweak: startHue must be greater than or equal to 0.0 and less than 360.0\");\n\n  if (_endHue <= 0.0 || _endHue > 360.0)\n        env->ThrowError(\"Tweak: endHue must be greater than 0.0 and less than or equal to 360.0\");\n\n  if (_minSat >= _maxSat)\n        env->ThrowError(\"Tweak: MinSat must be less than MaxSat\");\n\n  if (_minSat < 0.0 || _minSat >= 150.0)\n        env->ThrowError(\"Tweak: minSat must be greater than or equal to 0 and less than 150.\");\n\n  if (_maxSat <= 0.0 || _maxSat > 150.0)\n        env->ThrowError(\"Tweak: maxSat must be greater than 0 and less than or equal to 150.\");\n\n  if (p>=150.0 || p<0.0)\n        env->ThrowError(\"Tweak: Interp must be greater than or equal to 0 and less than 150.\");\n\n  Sat = (int) (_sat * 512);    // 9 bits extra precision\n  Cont = (int) (_cont * 512);\n  Bright = (int) _bright;\n\n  const double Hue = (_hue * PI) / 180.0;\n  const double SIN = sin(Hue);\n  const double COS = cos(Hue);\n\n  Sin = (int) (SIN * 4096 + 0.5);\n  Cos = (int) (COS * 4096 + 0.5);\n\n  realcalc_luma = realcalc; // from parameter\n  realcalc_chroma = realcalc;\n  if (vi.IsPlanar() && (bits_per_pixel > 10))\n    realcalc_chroma = true;\n  if (vi.IsPlanar() && (bits_per_pixel == 32))\n    realcalc_luma = true;\n  // 8/10bit: chroma lut OK. 12+ bits: force no lookup tables.\n  // 8-16bit: luma lut OK. float: force no lookup tables.\n\n  // fill brightness/constrast lookup tables\n  if(!(realcalc_luma && vi.IsPlanar()))\n  {\n    size_t map_size = pixelsize * safe_luma_lookup_size * scale_dither_luma;\n    // for 10-16 bit with dither: 2 * 65536 * 256 = 33 MByte\n    //               w/o  dither: 2 * 65536 = 128 KByte\n    map = static_cast<uint8_t*>(env->Allocate(map_size, 8, AVS_NORMAL_ALLOC));\n    if (!map)\n      env->ThrowError(\"Tweak: Could not reserve memory.\");\n    env->AtExit(free_buffer, map);\n\n    if(bits_per_pixel>8 && bits_per_pixel<16) // make lut table safe for 10-14 bit garbage\n      std::fill_n((uint16_t *)map, map_size / pixelsize, max_pixel_value);\n\n    int range_low = coring ? limits.tv_range_low : 0;\n    int range_high = coring ? limits.tv_range_hi_luma : max_pixel_value;\n\n    // dither_scale_luma = 1 if no dither, 256 if dither\n    /* create luma lut for brightness and contrast */\n    for (int i = 0; i < lut_size * scale_dither_luma; i++) {\n      int ii;\n      if(dither) {\n        ii = (i & 0xFFFFFF00) + (int)((i & 0xFF)*dither_strength);\n      } else {\n        ii = i;\n      }\n      // _bright param range is accepted as 0..256\n      int y = (int)(((ii - range_low * scale_dither_luma)*_cont + _bright * (1 << (bits_per_pixel - 8)) * scale_dither_luma + bias_dither_luma) / scale_dither_luma + range_low + 0.5);\n\n      // coring, dither:\n      // int y = int(((ii - 16 * 256)*_cont + _bright * 256 - 127.5) / 256 + 16.5); // 256 _cont & _bright param range\n      // coring, no dither:\n      // int y = int(((ii - 16)*_cont + _bright) + 16.5); // 256 _cont & _bright param range\n      // no coring, dither:\n      // int y = int((ii *_cont + _bright * 256 - 127.5) / 256 + 0.5 ); // 256 _cont & _bright param range\n      // no coring, no dither:\n      // int y = int((ii *_cont + _bright) + 0.5 ); // 256 _cont & _bright param range\n      if(pixelsize==1)\n        map[i] = (BYTE)clamp(y, range_low, range_high);\n      else\n        reinterpret_cast<uint16_t *>(map)[i] = (uint16_t)clamp(y, range_low, range_high);\n    }\n  }\n  // 100% equals sat=119 (= maximal saturation of valid RGB (R=255,G=B=0)\n  // 150% (=180) - 100% (=119) overshoot\n  const double minSat = 1.19 * _minSat;\n  const double maxSat = 1.19 * _maxSat;\n\n  p *= 1.19; // Same units as minSat/maxSat\n\n  if (!(realcalc_chroma && vi.IsPlanar()))\n  { // fill lookup tables for UV\n    size_t map_size = pixelsize * lut_size * lut_size * 2 * scale_dither_chroma;\n    // for 10 bit with dither: 2 * 1024 * 1024 * 2 * 4 = 4*64 MByte = 256M huh!\n    // for 10 bit w/o  dither: 2 * 1024 * 1024 * 2 = 64 MByte\n\n    mapUV = static_cast<uint16_t*>(env->Allocate(map_size, 8, AVS_NORMAL_ALLOC)); // uint16_t for (U+V bytes), casted to uint32_t for (U+V words in non-8 bit)\n    if (!mapUV)\n      env->ThrowError(\"Tweak: Could not reserve memory.\");\n    env->AtExit(free_buffer, mapUV);\n\n    int range_low = coring ? limits.tv_range_low : 0;\n    int range_high = coring ? limits.tv_range_hi_chroma : max_pixel_value;\n\n    double uv_range_corr = 1.0 / (1 << (bits_per_pixel - 8));\n\n    if (dither) {\n      // lut chroma, dither\n      for (int d = 0; d < scale_dither_chroma; d++) { // scale = 4    0..15 mini-dither\n        for (int u = 0; u < lut_size; u++) {\n          // dither_strength: optional correction for 8+ bit to have the same dither range as in 8 bits\n          const double destu = (((u << 4) + d*dither_strength) + bias_dither_chroma) / scale_dither_chroma - limits.middle_chroma; // scale_dither_chroma: 16\n          for (int v = 0; v < lut_size; v++) {\n            const double destv = (((v << 4) + d*dither_strength) + bias_dither_chroma) / scale_dither_chroma - limits.middle_chroma;\n            int iSat = Sat;\n            if (allPixels || ProcessPixel(destv * uv_range_corr, destu * uv_range_corr, _startHue, _endHue, maxSat, minSat, p, iSat)) {\n              int du = (int)((destu*COS + destv*SIN) * iSat + 0x100) >> 9; // back from the extra 9 bits Sat precision\n              int dv = (int)((destv*COS - destu*SIN) * iSat + 0x100) >> 9;\n              du = clamp(du + limits.middle_chroma, range_low, range_high);\n              dv = clamp(dv + limits.middle_chroma, range_low, range_high);\n              if(pixelsize==1)\n                mapUV[(u << 12) | (v << 4) | d] = (uint16_t)(du | (dv << 8)); // U and V: two bytes\n              else\n                reinterpret_cast<uint32_t *>(mapUV)[(u << (4+bits_per_pixel)) | (v << 4) | d] = (uint32_t)(du | (dv << 16)); // U and V: two words\n            }\n            else {\n              if(pixelsize==1)\n                mapUV[(u << 12) | (v << 4) | d] = (uint16_t)(clamp(u, range_low, range_high) | (clamp(v, range_low, range_high) << 8)); // U and V: two bytes\n              else\n                reinterpret_cast<uint32_t *>(mapUV)[(u << (4+bits_per_pixel)) | (v << 4) | d] = (uint32_t)(clamp(u, range_low, range_high) | ((clamp(v, range_low, range_high) << 16))); // U and V: two words\n            }\n          }\n        }\n      }\n    }\n    else {\n      // lut chroma, no dither\n      for (int u = 0; u < lut_size; u++) {\n        const double destu = u - limits.middle_chroma;\n        for (int v = 0; v < lut_size; v++) {\n          const double destv = v - limits.middle_chroma;\n          int iSat = Sat;\n          if (allPixels || ProcessPixel(destv * uv_range_corr, destu * uv_range_corr, _startHue, _endHue, maxSat, minSat, p, iSat)) {\n            int du = int((destu*COS + destv*SIN) * iSat) >> 9; // back from the extra 9 bits Sat precision\n            int dv = int((destv*COS - destu*SIN) * iSat) >> 9;\n            du = clamp(du + limits.middle_chroma, range_low, range_high);\n            dv = clamp(dv + limits.middle_chroma, range_low, range_high);\n            if(pixelsize==1)\n              mapUV[(u << 8) | v] = (uint16_t)(du | (dv << 8)); // U and V: two bytes\n            else\n              reinterpret_cast<uint32_t *>(mapUV)[(u << bits_per_pixel) | v] = (uint32_t)(du | (dv << 16)); // U and V: two words\n          }\n          else {\n            if(pixelsize==1)\n              mapUV[(u << 8) | v] = (uint16_t)(clamp(u, range_low, range_high) | (clamp(v, range_low, range_high) << 8));  // U and V: two bytes\n            else\n              reinterpret_cast<uint32_t *>(mapUV)[(u << bits_per_pixel) | v] = (uint32_t)(clamp(u, range_low, range_high) | (clamp(v, range_low, range_high) << 16));  // U and V: two words\n          }\n        }\n      }\n    }\n  }\n}\n\n\ntemplate<typename pixel_t, bool dither>\nvoid Tweak::tweak_calc_chroma(BYTE *srcpu, BYTE *srcpv, int src_pitch, int width, int height, float minUV, float maxUV)\n{\n  // no lookup, alway true for 16/32 bit, optional for 8 bit\n  const double Hue = (dhue * PI) / 180.0;\n  // 100% equals sat=119 (= maximal saturation of valid RGB (R=255,G=B=0)\n  // 150% (=180) - 100% (=119) overshoot\n  const double minSat = 1.19 * dminSat;\n  const double maxSat = 1.19 * dmaxSat;\n\n  const double p = dinterp * 1.19; // Same units as minSat/maxSat\n\n  const int minUVi = (int)minUV;\n  const int maxUVi = (int)maxUV;\n\n  float ditherval = 0.0;\n  float u, v;\n  const float cosHue = (float)cos(Hue);\n  const float sinHue = (float)sin(Hue);\n  // no lut, realcalc, float internals\n  const float pixel_range = sizeof(pixel_t) == 4 ? 1.0f : (float)(max_pixel_value + 1);\n\n  double uv_range_corr = 255.0;\n\n  const bool isFloat = sizeof(pixel_t) == 4;\n\n  for (int y = 0; y < height; ++y) {\n    const int _y = (y << 2) & 0xC;\n    for (int x = 0; x < width; ++x) {\n      if (dither)\n        ditherval = ((float(ditherMap4[(x & 0x3) | _y]) * dither_strength + bias_dither_chroma) / scale_dither_chroma); // +/-0.5 on 0..255 range\n      pixel_t orig_u = reinterpret_cast<pixel_t *>(srcpu)[x];\n      pixel_t orig_v = reinterpret_cast<pixel_t *>(srcpv)[x] ;\n      u = isFloat ? (orig_u - limits.middle_chroma_f) : (orig_u - limits.middle_chroma);\n      v = isFloat ? (orig_v - limits.middle_chroma_f) : (orig_v - limits.middle_chroma);\n\n      u = (u + (dither ? ditherval : 0)) / (sizeof(pixel_t) == 4 ? 1.0f : pixel_range); // going from 0..1 to +/-0.5\n      v = (v + (dither ? ditherval : 0)) / (sizeof(pixel_t) == 4 ? 1.0f : pixel_range);\n\n      double dWorkSat = dsat; // init from original param\n      if(allPixels || ProcessPixelUnscaled(v * uv_range_corr, u * uv_range_corr, dstartHue, dendHue, maxSat, minSat, p, dWorkSat))\n      {\n        float du = ((u*cosHue + v*sinHue) * (float)dWorkSat);\n        float dv = ((v*cosHue - u*sinHue) * (float)dWorkSat);\n\n        if (isFloat) {\n          du = du + limits.middle_chroma_f;\n          dv = dv + limits.middle_chroma_f;\n        }\n        else {\n          // back to 0..1\n          du = du + 0.5f;\n          dv = dv + 0.5f;\n        }\n\n        if(isFloat) {\n          reinterpret_cast<pixel_t *>(srcpu)[x] = (pixel_t)clamp(du, minUV, maxUV);\n          reinterpret_cast<pixel_t *>(srcpv)[x] = (pixel_t)clamp(dv, minUV, maxUV);\n        } else {\n          reinterpret_cast<pixel_t *>(srcpu)[x] = (pixel_t)clamp((int)(du * pixel_range), minUVi, maxUVi);\n          reinterpret_cast<pixel_t *>(srcpv)[x] = (pixel_t)clamp((int)(dv * pixel_range), minUVi, maxUVi);\n        }\n      }\n      else {\n        if(isFloat) {\n          reinterpret_cast<pixel_t *>(srcpu)[x] = (pixel_t)clamp((float)orig_u, minUV, maxUV);\n          reinterpret_cast<pixel_t *>(srcpv)[x] = (pixel_t)clamp((float)orig_v, minUV, maxUV);\n        } else {\n          reinterpret_cast<pixel_t *>(srcpu)[x] = (pixel_t)clamp((int)(orig_u), minUVi, maxUVi);\n          reinterpret_cast<pixel_t *>(srcpv)[x] = (pixel_t)clamp((int)(orig_v), minUVi, maxUVi);\n        }\n      }\n    }\n    srcpu += src_pitch;\n    srcpv += src_pitch;\n  }\n\n}\n\n\nPVideoFrame __stdcall Tweak::GetFrame(int n, IScriptEnvironment* env)\n{\n    PVideoFrame src = child->GetFrame(n, env);\n    env->MakeWritable(&src);\n\n    BYTE* srcp = src->GetWritePtr();\n\n    int src_pitch = src->GetPitch();\n    int height = src->GetHeight();\n    int row_size = src->GetRowSize();\n\n    if (vi.IsYUY2()) {\n\n        if (dither) {\n            const int UVwidth = vi.width / 2;\n            for (int y = 0; y < height; y++) {\n                {const int _y = (y << 4) & 0xf0;\n                for (int x = 0; x < vi.width; ++x) {\n                    /* brightness and contrast */\n                    srcp[x * 2] = map[srcp[x * 2] << 8 | ditherMap[(x & 0x0f) | _y]];\n                }}\n                {const int _y = (y << 2) & 0xC;\n                for (int x = 0; x < UVwidth; ++x) {\n                    const int _dither = ditherMap4[(x & 0x3) | _y];\n                    /* hue and saturation */\n                    const int u = srcp[x * 4 + 1];\n                    const int v = srcp[x * 4 + 3];\n                    const int mapped = mapUV[(u << 12) | (v << 4) | _dither];\n                    srcp[x * 4 + 1] = (BYTE)(mapped & 0xff);\n                    srcp[x * 4 + 3] = (BYTE)(mapped >> 8);\n                }}\n                srcp += src_pitch;\n            }\n        }\n        else {\n            for (int y = 0; y < height; y++)\n            {\n                for (int x = 0; x < row_size; x += 4)\n                {\n                    /* brightness and contrast */\n                    srcp[x] = map[srcp[x]];\n                    srcp[x + 2] = map[srcp[x + 2]];\n\n                    /* hue and saturation */\n                    const int u = srcp[x + 1];\n                    const int v = srcp[x + 3];\n                    const int mapped = mapUV[(u << 8) | v];\n                    srcp[x + 1] = (BYTE)(mapped & 0xff);\n                    srcp[x + 3] = (BYTE)(mapped >> 8);\n                }\n                srcp += src_pitch;\n            }\n        }\n        // YUY2 end\n    }\n    else if (vi.IsPlanar()) {\n        // brightness and contrast\n        // no_lut and lut\n        int width = row_size / pixelsize;\n        if (realcalc_luma)\n        {\n          // no luma lookup! alway true for 32 bit, optional for 8-16 bits\n            float maxY;\n            float minY;\n            // unique for each bit-depth, difference in the innermost loop (speed)\n            maxY = (float)(coring ? limits.tv_range_hi_luma : max_pixel_value);\n            minY = (float)(coring ? limits.tv_range_low : 0);\n\n            if(pixelsize == 1) {\n              if(dither)\n                tweak_calc_luma<uint8_t, false, true>(srcp, src_pitch, minY, maxY, width, height);\n              else\n                tweak_calc_luma<uint8_t, false, false>(srcp, src_pitch, minY, maxY, width, height);\n            } else if (bits_per_pixel < 16) {\n              if(dither)\n                tweak_calc_luma<uint16_t, true, true>(srcp, src_pitch, minY, maxY, width, height);\n              else\n                tweak_calc_luma<uint16_t, true, false>(srcp, src_pitch, minY, maxY, width, height);\n            } else if(bits_per_pixel == 16) {\n              if(dither)\n                tweak_calc_luma<uint16_t, false, true>(srcp, src_pitch, minY, maxY, width, height);\n              else\n                tweak_calc_luma<uint16_t, false, false>(srcp, src_pitch, minY, maxY, width, height);\n            } else { // float\n              maxY = coring ? 235.0f / 256 : 1.0f; // scale into 0..1 range\n              minY = coring ? 16.0f / 256 : 0;\n              if(dither)\n                tweak_calc_luma<float, false, true>(srcp, src_pitch, minY, maxY, width, height);\n              else\n                tweak_calc_luma<float, false, false>(srcp, src_pitch, minY, maxY, width, height);\n            }\n        }\n        else {\n            /* brightness and contrast */\n            // use luma lookup for 8-16 bits\n            if (dither) {\n              if(pixelsize==1) {\n                for (int y = 0; y < height; ++y) {\n                    const int _y = (y << 4) & 0xf0;\n                    for (int x = 0; x < width; ++x) {\n                        /* brightness and contrast */\n                        srcp[x] = map[srcp[x] << 8 | ditherMap[(x & 0x0f) | _y]];\n                    }\n                    srcp += src_pitch;\n                }\n              }\n              else { // pixelsize == 2\n                for (int y = 0; y < height; ++y) {\n                  const int _y = (y << 4) & 0xf0;\n                  for (int x = 0; x < width; ++x) {\n                    reinterpret_cast<uint16_t *>(srcp)[x] = reinterpret_cast<uint16_t *>(map)[reinterpret_cast<uint16_t *>(srcp)[x] << 8 | ditherMap[(x & 0x0f) | _y]];\n                    // no clamp, map is safely sized\n                  }\n                  srcp += src_pitch;\n                }\n              }\n            }\n            else {\n              if(pixelsize==1) {\n                for (int y = 0; y < height; ++y) {\n                    for (int x = 0; x < width; ++x) {\n                        srcp[x] = map[srcp[x]];\n                    }\n                    srcp += src_pitch;\n                }\n              }\n              else { // pixelsize == 2\n                for (int y = 0; y < height; ++y) {\n                  for (int x = 0; x < width; ++x) {\n                    reinterpret_cast<uint16_t *>(srcp)[x] = reinterpret_cast<uint16_t *>(map)[reinterpret_cast<uint16_t *>(srcp)[x]];\n                    // no clamp, map is safely sized\n                  }\n                  srcp += src_pitch;\n                }\n              }\n            }\n        }\n        // Y: brightness and contrast done\n\n        // UV: hue and saturation start\n        src_pitch = src->GetPitch(PLANAR_U);\n        BYTE * srcpu = src->GetWritePtr(PLANAR_U);\n        BYTE * srcpv = src->GetWritePtr(PLANAR_V);\n        row_size = src->GetRowSize(PLANAR_U);\n        height = src->GetHeight(PLANAR_U);\n        width = row_size / pixelsize;\n\n        if (realcalc_chroma) {\n          // no lookup, alway true for > 10 bit, optional for 8/10 bit\n          float maxUV = (float)(coring ? limits.tv_range_hi_chroma : max_pixel_value);\n          float minUV = (float)(coring ? limits.tv_range_low : 0);\n          if(pixelsize == 1) {\n            if (dither)\n              tweak_calc_chroma<uint8_t, true>(srcpu, srcpv, src_pitch, width, height, minUV, maxUV);\n            else\n              tweak_calc_chroma<uint8_t, false>(srcpu, srcpv, src_pitch, width, height, minUV, maxUV);\n          } else if(pixelsize==2) {\n            if (dither)\n              tweak_calc_chroma<uint16_t, true>(srcpu, srcpv, src_pitch, width, height, minUV, maxUV);\n            else\n              tweak_calc_chroma<uint16_t, false>(srcpu, srcpv, src_pitch, width, height, minUV, maxUV);\n          } else { // pixelsize == 4\n            maxUV = coring ? limits.tv_range_hi_chroma_f : limits.full_range_hi_chroma_f;\n            minUV = coring ? limits.tv_range_low_chroma_f : limits.full_range_low_chroma_f;\n            if (dither)\n              tweak_calc_chroma<float, true>(srcpu, srcpv, src_pitch, width, height, minUV, maxUV);\n            else\n              tweak_calc_chroma<float, false>(srcpu, srcpv, src_pitch, width, height, minUV, maxUV);\n          }\n        }\n        else { // lookup UV\n            if (dither) {\n              // lut + dither\n              if(pixelsize==1) {\n                for (int y = 0; y < height; ++y) {\n                    const int _y = (y << 2) & 0xC;\n                    for (int x = 0; x < width; ++x) {\n                        const int _dither = ditherMap4[(x & 0x3) | _y];\n                        /* hue and saturation */\n                        const int u = srcpu[x];\n                        const int v = srcpv[x];\n                        const int mapped = mapUV[(u << 12) | (v << 4) | _dither];\n                        srcpu[x] = (BYTE)(mapped & 0xff);\n                        srcpv[x] = (BYTE)(mapped >> 8);\n                    }\n                    srcpu += src_pitch;\n                    srcpv += src_pitch;\n                }\n              }\n              else { // pixelsize == 2\n                for (int y = 0; y < height; ++y) {\n                  const int _y = (y << 2) & 0xC;\n                  for (int x = 0; x < width; ++x) {\n                    const int _dither = ditherMap4[(x & 0x3) | _y]; // 0..15\n                    /* hue and saturation */\n                    const int u = clamp(0,(int)reinterpret_cast<uint16_t *>(srcpu)[x], max_pixel_value);\n                    const int v = clamp(0,(int)reinterpret_cast<uint16_t *>(srcpv)[x], max_pixel_value);\n                    const unsigned int mapped = reinterpret_cast<uint32_t *>(mapUV)[(u << (4+bits_per_pixel)) | (v << 4) | _dither];\n                    reinterpret_cast<uint16_t *>(srcpu)[x] = (uint16_t)(mapped & 0xffff);\n                    reinterpret_cast<uint16_t *>(srcpv)[x] = (uint16_t)(mapped >> 16);\n                  }\n                  srcpu += src_pitch;\n                  srcpv += src_pitch;\n                }\n              }\n            }\n            else {\n              // lut + no dither\n              if(pixelsize==1) {\n                for (int y = 0; y < height; ++y) {\n                      for (int x = 0; x < width; ++x) {\n                          /* hue and saturation */\n                          const int u = srcpu[x];\n                          const int v = srcpv[x];\n                          const int mapped = mapUV[(u << 8) | v];\n                          srcpu[x] = (BYTE)(mapped & 0xff);\n                          srcpv[x] = (BYTE)(mapped >> 8);\n                      }\n                      srcpu += src_pitch;\n                      srcpv += src_pitch;\n                  }\n              }\n              else { // pixelsize == 2\n                for (int y = 0; y < height; ++y) {\n                  for (int x = 0; x < width; ++x) {\n                    const int u = clamp(0,(int)reinterpret_cast<uint16_t *>(srcpu)[x], max_pixel_value);\n                    const int v = clamp(0,(int)reinterpret_cast<uint16_t *>(srcpv)[x], max_pixel_value);\n                    const unsigned int mapped = reinterpret_cast<uint32_t *>(mapUV)[(u << bits_per_pixel) | v];\n                    reinterpret_cast<uint16_t *>(srcpu)[x] = (uint16_t)(mapped & 0xffff);\n                    reinterpret_cast<uint16_t *>(srcpv)[x] = (uint16_t)(mapped >> 16);\n                  }\n                  srcpu += src_pitch;\n                  srcpv += src_pitch;\n                }\n              }\n            }\n        }\n    }\n\n    return src;\n}\n\nAVSValue __cdecl Tweak::Create(AVSValue args, void* , IScriptEnvironment* env)\n{\n    return new Tweak(args[0].AsClip(),\n        args[1].AsDblDef(0.0),     // hue\n        args[2].AsDblDef(1.0),     // sat\n        args[3].AsDblDef(0.0),     // bright\n        args[4].AsDblDef(1.0),     // cont\n        args[5].AsBool(true),      // coring\n        // not used even on intel. // args[6].AsBool(false),     // sse\n        args[7].AsDblDef(0.0),     // startHue\n        args[8].AsDblDef(360.0),   // endHue\n        args[9].AsDblDef(150.0),   // maxSat\n        args[10].AsDblDef(0.0),    // minSat\n        args[11].AsDblDef(16.0 / 1.19),// interp\n        args[12].AsBool(false),    // dither\n        args[13].AsBool(false),    // realcalc: force no-lookup (pure float calculation pixel)\n        args[14].AsDblDef(1.0),    // dither_strength 1.0 = +/-0.5 on the 0.255 range, scaled for others\n        env);\n}\n\n/**********************\n******   MaskHS   *****\n**********************/\n\nMaskHS::MaskHS(PClip _child, double _startHue, double _endHue, double _maxSat, double _minSat, bool _coring, bool _realcalc,\n    IScriptEnvironment* env)\n    : GenericVideoFilter(_child), dstartHue(_startHue), dendHue(_endHue), dmaxSat(_maxSat), dminSat(_minSat), coring(_coring), realcalc(_realcalc)\n{\n    if (vi.IsRGB())\n        env->ThrowError(\"MaskHS: YUV data only (no RGB)\");\n\n    if (vi.NumComponents() == 1) {\n        env->ThrowError(\"MaskHS: clip must contain chroma.\");\n    }\n\n    if (dstartHue < 0.0 || dstartHue >= 360.0)\n        env->ThrowError(\"MaskHS: startHue must be greater than or equal to 0.0 and less than 360.0\");\n\n    if (dendHue <= 0.0 || dendHue > 360.0)\n        env->ThrowError(\"MaskHS: endHue must be greater than 0.0 and less than or equal to 360.0\");\n\n    if (dminSat >= dmaxSat)\n        env->ThrowError(\"MaskHS: MinSat must be less than MaxSat\");\n\n    if (dminSat < 0.0 || dminSat >= 150.0)\n        env->ThrowError(\"MaskHS: minSat must be greater than or equal to 0 and less than 150.\");\n\n    if (dmaxSat <= 0.0 || dmaxSat > 150.0)\n        env->ThrowError(\"MaskHS: maxSat must be greater than 0 and less than or equal to 150.\");\n\n    pixelsize = vi.ComponentSize();\n    bits_per_pixel = vi.BitsPerComponent();\n    max_pixel_value = (1 << bits_per_pixel) - 1;\n    lut_size = 1 << bits_per_pixel;\n\n    get_limits(limits, bits_per_pixel);\n\n    mask_low = coring ? limits.tv_range_low : 0;\n    mask_high = coring ? limits.tv_range_hi_luma : max_pixel_value;\n\n    if (bits_per_pixel == 32) {\n      mask_low_f = coring ? limits.tv_range_low_luma_f : limits.full_range_low_luma_f;\n      mask_high_f = coring ? limits.tv_range_hi_luma_f : limits.full_range_hi_luma_f;\n    }\n\n    realcalc_chroma = realcalc;\n    if (vi.IsPlanar() && (bits_per_pixel > 12)) // max bitdepth is 12 for lut\n      realcalc_chroma = true;\n\n    // 100% equals sat=119 (= maximal saturation of valid RGB (R=255,G=B=0)\n    // 150% (=180) - 100% (=119) overshoot\n    minSat = 1.19 * dminSat;\n    maxSat = 1.19 * dmaxSat;\n\n    if (!(realcalc_chroma && vi.IsPlanar()))\n    { // fill lookup tables for UV\n      size_t map_size = pixelsize * lut_size * lut_size;\n      // for  8 bit : 1 * 256 * 256 = 65536 byte\n      // for 10 bit : 2 * 1024 * 1024 = 2 MByte\n      // for 12 bit : 2 * 4096 * 4096 = 32 MByte\n      mapUV = static_cast<uint8_t*>(env->Allocate(map_size, 8, AVS_NORMAL_ALLOC)); // uint16_t for (U+V bytes), casted to uint32_t for (U+V words in non-8 bit)\n      if (!mapUV)\n        env->ThrowError(\"Tweak: Could not reserve memory.\");\n      env->AtExit(free_buffer, mapUV);\n\n      // apply mask\n      double uv_range_corr = 1.0 / (1 << (bits_per_pixel - 8)); // no float here\n      for (int u = 0; u < lut_size; u++) {\n          const double destu = (u - limits.middle_chroma) * uv_range_corr; // processpixel's minSat and maxSat is for 256 range\n          int ushift = u << bits_per_pixel;\n          for (int v = 0; v < lut_size; v++) {\n              const double destv = (v - limits.middle_chroma) * uv_range_corr;\n              int iSat = 0; // won't be used in MaskHS; interpolation is skipped since p==0:\n              bool ppres = ProcessPixel(destv, destu, dstartHue, dendHue, maxSat, minSat, 0.0, iSat);\n              if(pixelsize==1)\n                  mapUV[ushift | v] = ppres ? mask_high : mask_low;\n              else\n                  reinterpret_cast<uint16_t *>(mapUV)[ushift | v] = ppres ? mask_high : mask_low;\n          }\n      }\n    } // end of lut calculation\n    // #define MaskPointResizing\n#ifndef MaskPointResizing\n    vi.width >>= vi.GetPlaneWidthSubsampling(PLANAR_U);\n    vi.height >>= vi.GetPlaneHeightSubsampling(PLANAR_U);\n#endif\n    switch(bits_per_pixel) {\n    case 8: vi.pixel_type = VideoInfo::CS_Y8; break;\n    case 10: vi.pixel_type = VideoInfo::CS_Y10; break;\n    case 12: vi.pixel_type = VideoInfo::CS_Y12; break;\n    case 14: vi.pixel_type = VideoInfo::CS_Y14; break;\n    case 16: vi.pixel_type = VideoInfo::CS_Y16; break;\n    case 32: vi.pixel_type = VideoInfo::CS_Y32; break;\n    }\n}\n\n\n\nPVideoFrame __stdcall MaskHS::GetFrame(int n, IScriptEnvironment* env)\n{\n    PVideoFrame src = child->GetFrame(n, env);\n    PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n\n    uint8_t* dstp = dst->GetWritePtr();\n    int dst_pitch = dst->GetPitch();\n\n    // show mask\n    if (child->GetVideoInfo().IsYUY2()) {\n        const uint8_t* srcp = src->GetReadPtr();\n        const int src_pitch = src->GetPitch();\n        const int height = src->GetHeight();\n\n#ifndef MaskPointResizing\n        const int row_size = src->GetRowSize() >> 2;\n\n        for (int y = 0; y < height; y++) {\n            for (int x = 0; x < row_size; x++) {\n                dstp[x] = mapUV[((srcp[x * 4 + 1]) << 8) | srcp[x * 4 + 3]];\n            }\n            srcp += src_pitch;\n            dstp += dst_pitch;\n        }\n#else\n        const int row_size = src->GetRowSize();\n\n        for (int y = 0; y < height; y++) {\n            for (int xs = 0, xd = 0; xs < row_size; xs += 4, xd += 2) {\n                const BYTE mapped = mapY[((srcp[xs + 1]) << 8) | srcp[xs + 3]];\n                dstp[xd] = mapped;\n                dstp[xd + 1] = mapped;\n            }\n            srcp += src_pitch;\n            dstp += dst_pitch;\n        }\n#endif\n    }\n    else if (child->GetVideoInfo().IsPlanar()) {\n        const int srcu_pitch = src->GetPitch(PLANAR_U);\n        const uint8_t* srcpu = src->GetReadPtr(PLANAR_U);\n        const uint8_t* srcpv = src->GetReadPtr(PLANAR_V);\n        const int width = src->GetRowSize(PLANAR_U) / pixelsize;\n        const int heightu = src->GetHeight(PLANAR_U);\n\n#ifndef MaskPointResizing\n        if(realcalc_chroma) {\n          double uv_range_corr = (pixelsize == 4) ? 255.0 : 1.0 / (1 << (bits_per_pixel - 8));\n          if(pixelsize == 1) {\n            for (int y = 0; y < heightu; ++y) {\n              for (int x = 0; x < width; ++x) {\n                const double destu = srcpu[x] - limits.middle_chroma;\n                const double destv = srcpv[x] - limits.middle_chroma;\n                int iSat = 0; // won't be used in MaskHS; interpolation is skipped since p==0:\n                bool ppres = ProcessPixel(destv * uv_range_corr, destu * uv_range_corr, dstartHue, dendHue, maxSat, minSat, 0.0, iSat);\n                dstp[x] = ppres ? mask_high : mask_low;\n              }\n              dstp += dst_pitch;\n              srcpu += srcu_pitch;\n              srcpv += srcu_pitch;\n            }\n          }\n          else if (pixelsize == 2) {\n            for (int y = 0; y < heightu; ++y) {\n              for (int x = 0; x < width; ++x) {\n                const double destu = (reinterpret_cast<const uint16_t *>(srcpu)[x] - limits.middle_chroma);\n                const double destv = (reinterpret_cast<const uint16_t *>(srcpv)[x] - limits.middle_chroma);\n                int iSat = 0; // won't be used in MaskHS; interpolation is skipped since p==0:\n                bool ppres = ProcessPixel(destv * uv_range_corr, destu * uv_range_corr, dstartHue, dendHue, maxSat, minSat, 0.0, iSat);\n                reinterpret_cast<uint16_t *>(dstp)[x] = ppres ? mask_high : mask_low;\n              }\n              dstp += dst_pitch;\n              srcpu += srcu_pitch;\n              srcpv += srcu_pitch;\n            }\n          } else { // pixelsize == 4\n            for (int y = 0; y < heightu; ++y) {\n              for (int x = 0; x < width; ++x) {\n                const double destu = (reinterpret_cast<const float *>(srcpu)[x] - limits.middle_chroma_f);\n                const double destv = (reinterpret_cast<const float *>(srcpv)[x] - limits.middle_chroma_f);\n                int iSat = 0; // won't be used in MaskHS; interpolation is skipped since p==0:\n                bool ppres = ProcessPixel(destv * uv_range_corr, destu * uv_range_corr, dstartHue, dendHue, maxSat, minSat, 0.0, iSat);\n                reinterpret_cast<float *>(dstp)[x] = ppres ? mask_high_f : mask_low_f;\n              }\n              dstp += dst_pitch;\n              srcpu += srcu_pitch;\n              srcpv += srcu_pitch;\n            }\n          }\n\n        } else {\n          // use LUT\n          if(pixelsize==1) {\n            for (int y = 0; y < heightu; ++y) {\n                for (int x = 0; x < width; ++x) {\n                    dstp[x] = mapUV[((srcpu[x]) << 8) | srcpv[x]];\n                }\n                dstp += dst_pitch;\n                srcpu += srcu_pitch;\n                srcpv += srcu_pitch;\n            }\n          }\n          else if (pixelsize == 2) {\n            for (int y = 0; y < heightu; ++y) {\n              for (int x = 0; x < width; ++x) {\n                reinterpret_cast<uint16_t *>(dstp)[x] =\n                  reinterpret_cast<uint16_t *>(mapUV)[((reinterpret_cast<const uint16_t *>(srcpu)[x]) << bits_per_pixel) | reinterpret_cast<const uint16_t *>(srcpv)[x]];\n              }\n              dstp += dst_pitch;\n              srcpu += srcu_pitch;\n              srcpv += srcu_pitch;\n            }\n          } // no lut for float (and for 14-16 bit)\n        }\n#else\n        const int swidth = child->GetVideoInfo().GetPlaneWidthSubsampling(PLANAR_U);\n        const int sheight = child->GetVideoInfo().GetPlaneHeightSubsampling(PLANAR_U);\n        const int sw = 1 << swidth;\n        const int sh = 1 << sheight;\n\n        const int dpitch = dst_pitch << sheight;\n        for (int y = 0; y < heightu; ++y) {\n            for (int x = 0; x < row_sizeu; ++x) {\n                const BYTE mapped = mapY[((srcpu[x]) << 8) | srcpv[x]];\n                const int sx = x << swidth;\n\n                for (int lumv = 0; lumv < sh; ++lumv) {\n                    const int sy = lumv*dst_pitch + sx;\n\n                    for (int lumh = 0; lumh < sw; ++lumh) {\n                        dstp[sy + lumh] = mapped;\n                    }\n                }\n            }\n            dstp += dpitch;\n            srcpu += srcu_pitch;\n            srcpv += srcu_pitch;\n        }\n#endif\n    }\n    return dst;\n}\n\n\n\nAVSValue __cdecl MaskHS::Create(AVSValue args, void* , IScriptEnvironment* env)\n{\n    return new MaskHS(args[0].AsClip(),\n        args[1].AsDblDef(0.0),    // startHue\n        args[2].AsDblDef(360.0),    // endHue\n        args[3].AsDblDef(150.0),    // maxSat\n        args[4].AsDblDef(0.0),    // minSat\n        args[5].AsBool(false),      // coring\n        args[6].AsBool(false),      // realcalc\n      env);\n}\n\n"
  },
  {
    "path": "avs_core/filters/levels.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Levels_H__\n#define __Levels_H__\n\n#include <avisynth.h>\n#include <stdint.h>\n\n\n/********************************************************************\n********************************************************************/\n\ntypedef struct {\n  int tv_range_low;\n  int tv_range_hi_luma;\n  int range_luma;\n\n  int tv_range_hi_chroma;\n  int range_chroma;\n\n  int middle_chroma;\n\n  // float things\n  float full_range_low_luma_f;\n  float full_range_hi_luma_f;\n  float tv_range_low_luma_f;\n  float tv_range_hi_luma_f;\n  float range_luma_f;\n\n  float full_range_low_chroma_f;\n  float full_range_hi_chroma_f;\n  float tv_range_low_chroma_f;\n  float tv_range_hi_chroma_f;\n  float range_chroma_f;\n\n  float middle_chroma_f;\n} luma_chroma_limits_t;\n\nclass Levels : public GenericVideoFilter\n/**\n  * Class for adjusting levels in a clip\n **/\n{\npublic:\n  Levels(PClip _child, float _in_min, double _gamma, float _in_max, float _out_min, float _out_max, bool _coring, bool _dither,\n          IScriptEnvironment* env );\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\nprivate:\n  BYTE *map, *mapchroma;\n  bool need_chroma;\n  bool coring;\n  bool dither;\n  double gamma;\n  bool use_gamma;\n  float in_min_f, in_max_f, out_min_f, out_max_f;\n\n  // avs+\n  int pixelsize;\n  int bits_per_pixel; // 8,10..16\n  bool use_lut;\n\n  int real_lookup_size;\n\n  luma_chroma_limits_t limits;\n\n  float divisor_f;\n  float out_diff_f; // precalc for speed\n\n  float ditherMap_f[256];\n\n  float bias_dither;\n  float dither_strength;\n\n  template<bool chroma, bool use_gamma>\n  AVS_FORCEINLINE float calcPixel(const float pixel);\n};\n\n\nstruct RGBAdjustPlaneConfig\n{\n  double scale;\n  double bias;\n  double gamma;\n  bool changed; // for lut recalc\n};\n\nstruct RGBAdjustConfig\n{\n  RGBAdjustPlaneConfig rgba[4];\n};\n\nstruct RGBPlaneStat\n{\n  double sum;\n  float real_min, real_max;\n};\n\nstruct RGBStats\n{\n  RGBPlaneStat data[3];\n};\n\nclass RGBAdjust : public GenericVideoFilter\n/**\n  * Class for adjusting and analyzing colors in RGBA space\n **/\n{\npublic:\n  RGBAdjust(PClip _child, double r,  double g,  double b,  double a,\n                          double rb, double gb, double bb, double ab,\n                          double rg, double gg, double bg, double ag,\n                          bool _analyze, bool _dither, bool _conditional, const char *_condVarSuffix, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n  ~RGBAdjust();\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\nprivate:\n  bool analyze;\n  bool dither;\n  bool conditional;\n  const char* condVarSuffix;\n\n  RGBAdjustConfig config;\n\n  int number_of_maps;\n  BYTE *map_holder;\n  BYTE *maps[4];\n  // avs+\n  int pixelsize;\n  int bits_per_pixel; // 8,10..16\n  bool use_lut;\n\n  int max_pixel_value;\n  int real_lookup_size;\n\n  float dither_strength;\n\n\n  void CheckAndConvertParams(RGBAdjustConfig &config, IScriptEnvironment *env);\n  void rgbadjust_create_lut(BYTE *lut_buf, const int plane, RGBAdjustConfig &config);\n};\n\n\n\n\nclass Tweak : public GenericVideoFilter\n{\npublic:\n  Tweak(PClip _child, double _hue, double _sat, double _bright, double _cont, bool _coring,\n    double _startHue, double _endHue, double _maxSat, double _minSat, double _interp,\n    bool _dither, bool _realcalc, double _dither_strength, IScriptEnvironment* env);\n\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void* user_data, IScriptEnvironment* env);\n\nprivate:\n  template<typename pixel_t, bool bpp10_14, bool dither>\n  void tweak_calc_luma(BYTE *srcp, int src_pitch, float minY, float maxY, int width, int height);\n\n  template<typename pixel_t, bool dither>\n  void tweak_calc_chroma(BYTE *srcpU, BYTE *srcpV, int src_pitch, int width, int height, float minUV, float maxUV);\n\n    int Sin, Cos;\n    int Sat, Bright, Cont;\n    bool coring, dither;\n\n    const bool realcalc; // no lookup, realtime calculation, always for 16/32 bits\n    double dhue, dsat, dbright, dcont, dstartHue, dendHue, dmaxSat, dminSat, dinterp;\n\n    bool allPixels;\n\n    BYTE *map;\n    uint16_t *mapUV;\n    // avs+\n    bool realcalc_luma;\n    bool realcalc_chroma;\n\n    int pixelsize;\n    int bits_per_pixel; // 8,10..16\n    int max_pixel_value;\n    int lut_size;\n\n    luma_chroma_limits_t limits;\n\n    int scale_dither_luma;\n    int divisor_dither_luma;\n    float bias_dither_luma;\n\n    int scale_dither_chroma;\n    int divisor_dither_chroma;\n    float bias_dither_chroma;\n\n    float dither_strength;\n};\n\n\nclass MaskHS : public GenericVideoFilter\n{\npublic:\n  MaskHS( PClip _child, double _startHue, double _endHue, double _maxSat, double _minSat, bool _coring, bool _realcalc, IScriptEnvironment* env );\n\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void* user_data, IScriptEnvironment* env);\n\nprivate:\n  const double dstartHue, dendHue, dmaxSat, dminSat;\n  const bool coring;\n  const bool realcalc;\n\n  double minSat, maxSat; // corrected values\n\n  uint8_t *mapUV;\n  // avs+\n  bool realcalc_chroma;\n\n  int pixelsize;\n  int bits_per_pixel; // 8,10..16\n  int max_pixel_value;\n  int lut_size;\n\n  luma_chroma_limits_t limits;\n\n  int mask_low;\n  int mask_high;\n  float mask_low_f;\n  float mask_high_f;\n\n};\n\n#endif  // __Levels_H__\n\n"
  },
  {
    "path": "avs_core/filters/limiter.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include \"limiter.h\"\n#ifdef INTEL_INTRINSICS\n#include \"intel/limiter_sse.h\"\n#endif\n#include <avs/alignment.h>\n\n#ifdef AVS_WINDOWS\n    #include <avs/win.h>\n#else\n    #include <avs/posix.h>\n#endif\n\n#include <../core/internal.h>\n\n\nLimiter::Limiter(PClip _child, float _min_luma, float _max_luma, float _min_chroma, float _max_chroma, int _show, bool paramscale, IScriptEnvironment* env) :\n  GenericVideoFilter(_child),\n  max_luma((int)_max_luma),\n  min_luma((int)_min_luma),\n  max_chroma((int)_max_chroma),\n  min_chroma((int)_min_chroma),\n  max_luma_f(_max_luma),\n  min_luma_f(_min_luma),\n  max_chroma_f(_max_chroma),\n  min_chroma_f(_min_chroma),\n  show(show_e(_show))\n{\n  if (!vi.IsYUV() && !vi.IsYUVA())\n      env->ThrowError(\"Limiter: Source must be YUV or YUVA\");\n\n  if(show != show_none && !vi.IsYUY2() && !vi.Is444() && !vi.Is420())\n      env->ThrowError(\"Limiter: Source must be YUV(A) 4:4:4, 4:2:0 or YUY2 with show option.\");\n\n  pixelsize = vi.ComponentSize();\n  bits_per_pixel = vi.BitsPerComponent(); // 8,10..16\n  int pixel_max = (1 << bits_per_pixel) - 1; // 255, 1023, 4095, 16383, 65535\n\n  const bool isFloat = bits_per_pixel == 32;\n  int tv_range_low   = isFloat ? 16 : (16 << (bits_per_pixel - 8)); // 16\n  int tv_range_hi_luma   = isFloat ? 235 : (235 << (bits_per_pixel - 8)); // 16-235\n  int tv_range_hi_chroma = isFloat ? 240 : (240 << (bits_per_pixel - 8)); // 16-240,64-960, ...\n\n  float tv_range_low_luma_f = 16 / 255.0f;\n  float tv_range_hi_luma_f = 235 / 255.0f;\n#ifdef FLOAT_CHROMA_IS_HALF_CENTERED\n  float tv_range_low_chroma = (16-128) / 255.0f + 0.5f;\n  float tv_range_hi_chroma_f = (240 - 128) / 255.0f + 0.5f;\n#else\n  float tv_range_low_chroma_f = (16 - 128) / 255.0f;\n  float tv_range_hi_chroma_f = (240 - 128) / 255.0f;\n#endif\n\n  if (paramscale) {\n    // int versions, scale from the original float accuracy (e.g. 127.5)\n    min_luma = (int)(_min_luma * (1 << (bits_per_pixel - 8)) + 0.5f);\n    max_luma = (int)(_max_luma * (1 << (bits_per_pixel - 8)) + 0.5f);\n    min_chroma = (int)(_min_chroma * (1 << (bits_per_pixel - 8)) + 0.5f);\n    max_chroma = (int)(_max_chroma * (1 << (bits_per_pixel - 8)) + 0.5f);\n\n    // float versions\n    min_luma_f = min_luma_f / 255.0f;\n    max_luma_f = max_luma_f / 255.0f;\n#ifdef FLOAT_CHROMA_IS_HALF_CENTERED\n    min_chroma_f = (min_chroma_f - 128) / 255.0f + 0.5f;\n    max_chroma_f = (max_chroma_f - 128) / 255.0f + 0.5f;\n#else\n    min_chroma_f = (min_chroma_f - 128) / 255.0f;\n    max_chroma_f = (max_chroma_f - 128) / 255.0f;\n#endif\n  }\n\n\n  // default min and max values by bitdepths\n  if (_min_luma == -9999.0f) {\n    min_luma = tv_range_low;\n    min_luma_f = tv_range_low_luma_f;\n  }\n  if (_max_luma == -9999.0f) {\n    max_luma = tv_range_hi_luma;\n    max_luma_f = tv_range_hi_luma_f;\n  }\n  if (_min_chroma == -9999.0f) {\n    min_chroma = tv_range_low;\n    min_chroma_f = tv_range_low_chroma_f;\n  }\n  if (_max_chroma == -9999.0f) {\n    max_chroma = tv_range_hi_chroma;\n    max_chroma_f = tv_range_hi_chroma_f;\n  }\n\n  if (pixelsize != 4) {\n    // no check for float\n    if ((min_luma < 0) || (min_luma > pixel_max))\n      env->ThrowError(\"Limiter: Invalid minimum luma\");\n    if ((max_luma < 0) || (max_luma > pixel_max))\n      env->ThrowError(\"Limiter: Invalid maximum luma\");\n    if ((min_chroma < 0) || (min_chroma > pixel_max))\n      env->ThrowError(\"Limiter: Invalid minimum chroma\");\n    if ((max_chroma < 0) || (max_chroma > pixel_max))\n      env->ThrowError(\"Limiter: Invalid maximum chroma\");\n  }\n\n}\n\ntemplate<typename pixel_t>\nstatic void limit_plane_c(BYTE *srcp8, int pitch, int min, int max, int width, int height) {\n  pixel_t *srcp = reinterpret_cast<pixel_t *>(srcp8);\n  pitch /= sizeof(pixel_t);\n  for(int y = 0; y < height; y++) {\n    for(int x = 0; x < width; x++) {\n      if(srcp[x] < min )\n        srcp[x] = (pixel_t)min;\n      else if(srcp[x] > max)\n        srcp[x] = (pixel_t)max;\n    }\n    srcp += pitch;\n  }\n}\n\nstatic void limit_plane_f_c(BYTE *srcp8, int pitch, float min, float max, int width, int height) {\n  float *srcp = reinterpret_cast<float *>(srcp8);\n  pitch /= sizeof(float);\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < width; x++) {\n      if (srcp[x] < min)\n        srcp[x] = min;\n      else if (srcp[x] > max)\n        srcp[x] = max;\n    }\n    srcp += pitch;\n  }\n}\n\ntemplate<typename pixel_t, bool show_luma_grey>\nstatic void show_luma_with_grey_opt_yuv444(BYTE *srcp8, BYTE *srcpU8, BYTE *srcpV8, int pitch, int pitchUV, int width, int height, int min_luma, int max_luma, int bits_per_pixel)\n{\n  // show_luma       Mark clamped pixels red/green over a colour image\n  // show_luma_grey  Mark clamped pixels red/green over a greyscaled image\n    const int shift = sizeof(pixel_t) == 1 ? 0 : (bits_per_pixel - 8);\n    pixel_t *srcp = reinterpret_cast<pixel_t *>(srcp8);\n    pixel_t *srcpU = reinterpret_cast<pixel_t *>(srcpU8);\n    pixel_t *srcpV = reinterpret_cast<pixel_t *>(srcpV8);\n    pitch /= sizeof(pixel_t);\n    pitchUV /= sizeof(pixel_t);\n\n    for (int h=0; h < height; h+=1) {\n      for (int x = 0; x < width; x+=1) {\n        if      (srcp[x] < min_luma) { srcp[x] =  81 << shift; srcpU[x] = 91 << shift; srcpV[x] = 240 << shift; }       // red:   Y=81, U=91 and V=240\n        else if (srcp[x] > max_luma) { srcp[x] = 145 << shift; srcpU[x] = 54 << shift; srcpV[x] =  34 << shift; }       // green: Y=145, U=54 and V=34\n        // this differs from show_luma\n        else if(show_luma_grey)      {                srcpU[x] =     srcpV[x] = 128 << shift; }       // grey\n      }\n      srcp  += pitch;\n      srcpV += pitchUV;\n      srcpU += pitchUV;\n    }\n}\n\ntemplate<typename pixel_t, bool show_luma_grey>\nstatic void show_luma_with_grey_opt_yuv420(BYTE *srcp8, BYTE *srcpU8, BYTE *srcpV8, int pitch, int pitchUV, int width, int height, int min_luma, int max_luma, int bits_per_pixel)\n{\n  // show_luma       Mark clamped pixels red/green over a colour image\n  // show_luma_grey  Mark clamped pixels red/green over a greyscaled image\n  const int shift = sizeof(pixel_t) == 1 ? 0 : (bits_per_pixel - 8);\n  pixel_t *srcp = reinterpret_cast<pixel_t *>(srcp8);\n  pixel_t *srcn = reinterpret_cast<pixel_t *>(srcp8 + pitch); // next line\n  pixel_t *srcpU = reinterpret_cast<pixel_t *>(srcpU8);\n  pixel_t *srcpV = reinterpret_cast<pixel_t *>(srcpV8);\n  pitch /= sizeof(pixel_t);\n  pitchUV /= sizeof(pixel_t);\n\n  for (int h=0; h < height; h+=2) {\n    for (int x = 0; x < width; x+=2) {\n      int uv = 0;\n      if      (srcp[x  ] < min_luma) { srcp[x  ] =  81 << shift; uv |= 1;}\n      else if (srcp[x  ] > max_luma) { srcp[x  ] = 145 << shift; uv |= 2;}\n      if      (srcp[x+1] < min_luma) { srcp[x+1] =  81 << shift; uv |= 1;}\n      else if (srcp[x+1] > max_luma) { srcp[x+1] = 145 << shift; uv |= 2;}\n      if      (srcn[x  ] < min_luma) { srcn[x  ] =  81 << shift; uv |= 1;}\n      else if (srcn[x  ] > max_luma) { srcn[x  ] = 145 << shift; uv |= 2;}\n      if      (srcn[x+1] < min_luma) { srcn[x+1] =  81 << shift; uv |= 1;}\n      else if (srcn[x+1] > max_luma) { srcn[x+1] = 145 << shift; uv |= 2;}\n      switch (uv) {\n      case 1: srcpU[x/2] = 91 << shift; srcpV[x/2] = 240 << shift; break;       // red:   Y=81, U=91 and V=240\n      case 2: srcpU[x/2] = 54 << shift; srcpV[x/2] =  34 << shift; break;       // green: Y=145, U=54 and V=34\n      // this differs from show_luma_grey\n      case 3:\n        if(show_luma_grey) {\n          srcpU[x/2] = 90 << shift;\n          srcpV[x/2] = 134 << shift; break;       // puke:  Y=81, U=90 and V=134 olive: Y=145, U=90 and V=134\n        } else {\n        srcp[x]=srcp[x+2]=srcn[x]=srcn[x+2]=210 << shift; // yellow:Y=210, U=16 and V=146\n        srcpU[x/2] = 16 << shift;\n        srcpV[x/2] = 146 << shift;\n        }\n        break;\n      default:\n        if(show_luma_grey) {\n          srcpU[x/2] = srcpV[x/2] = 128 << shift; // olive: Y=145, U=90 and V=134\n        }\n        break;\n      }\n    }\n    srcp += pitch*2; // 2x2 pixels at a time (4:2:0 subsampling)\n    srcn += pitch*2;\n    srcpV += pitchUV;\n    srcpU += pitchUV;\n  }\n}\n\ntemplate<bool show_luma_grey>\nstatic void show_luma_with_grey_opt_yuv444_f(BYTE *srcp8, BYTE *srcpU8, BYTE *srcpV8, int pitch, int pitchUV, int width, int height, float min_luma, float max_luma)\n{\n  // show_luma       Mark clamped pixels red/green over a colour image\n  // show_luma_grey  Mark clamped pixels red/green over a greyscaled image\n  float *srcp = reinterpret_cast<float *>(srcp8);\n  float *srcpU = reinterpret_cast<float *>(srcpU8);\n  float *srcpV = reinterpret_cast<float *>(srcpV8);\n  pitch /= sizeof(float);\n  pitchUV /= sizeof(float);\n\n  for (int h = 0; h < height; h += 1) {\n    for (int x = 0; x < width; x += 1) {\n      if (srcp[x] < min_luma) { srcp[x] =  c8tof(81); srcpU[x] = uv8tof(91); srcpV[x] = uv8tof(240); }       // red:   Y=81, U=91 and V=240\n      else if (srcp[x] > max_luma) { srcp[x] = c8tof(145); srcpU[x] = uv8tof(54); srcpV[x] = uv8tof(34); }       // green: Y=145, U=54 and V=34\n                                                                                                                     // this differs from show_luma\n      else if (show_luma_grey) { srcpU[x] = srcpV[x] = uv8tof(128); }       // grey\n    }\n    srcp += pitch;\n    srcpV += pitchUV;\n    srcpU += pitchUV;\n  }\n}\n\ntemplate<bool show_luma_grey>\nstatic void show_luma_with_grey_opt_yuv420_f(BYTE *srcp8, BYTE *srcpU8, BYTE *srcpV8, int pitch, int pitchUV, int width, int height, float min_luma, float max_luma)\n{\n  // show_luma       Mark clamped pixels red/green over a colour image\n  // show_luma_grey  Mark clamped pixels red/green over a greyscaled image\n  float *srcp = reinterpret_cast<float *>(srcp8);\n  float *srcn = reinterpret_cast<float *>(srcp8 + pitch); // next line\n  float *srcpU = reinterpret_cast<float *>(srcpU8);\n  float *srcpV = reinterpret_cast<float *>(srcpV8);\n  pitch /= sizeof(float);\n  pitchUV /= sizeof(float);\n\n  for (int h = 0; h < height; h += 2) {\n    for (int x = 0; x < width; x += 2) {\n      int uv = 0;\n      if (srcp[x] < min_luma) { srcp[x] = c8tof(81); uv |= 1; }\n      else if (srcp[x] > max_luma) { srcp[x] = c8tof(145); uv |= 2; }\n      if (srcp[x + 1] < min_luma) { srcp[x + 1] = c8tof(81); uv |= 1; }\n      else if (srcp[x + 1] > max_luma) { srcp[x + 1] = c8tof(145); uv |= 2; }\n      if (srcn[x] < min_luma) { srcn[x] = c8tof(81); uv |= 1; }\n      else if (srcn[x] > max_luma) { srcn[x] = c8tof(145); uv |= 2; }\n      if (srcn[x + 1] < min_luma) { srcn[x + 1] = c8tof(81); uv |= 1; }\n      else if (srcn[x + 1] > max_luma) { srcn[x + 1] = c8tof(145); uv |= 2; }\n      switch (uv) {\n      case 1: srcpU[x / 2] = uv8tof(91); srcpV[x / 2] = uv8tof(240); break;       // red:   Y=81, U=91 and V=240\n      case 2: srcpU[x / 2] = uv8tof(54); srcpV[x / 2] = uv8tof(34); break;       // green: Y=145, U=54 and V=34\n                                                                                   // this differs from show_luma_grey\n      case 3:\n        if (show_luma_grey) {\n          srcpU[x / 2] = uv8tof(90);\n          srcpV[x / 2] = uv8tof(134); break;       // puke:  Y=81, U=90 and V=134 olive: Y=145, U=90 and V=134\n        }\n        else {\n          srcp[x] = srcp[x + 2] = srcn[x] = srcn[x + 2] = c8tof(210); // yellow:Y=210, U=16 and V=146\n          srcpU[x / 2] = uv8tof(16);\n          srcpV[x / 2] = uv8tof(146);\n        }\n        break;\n      default:\n        if (show_luma_grey) {\n          srcpU[x / 2] = srcpV[x / 2] = uv8tof(128); // olive: Y=145, U=90 and V=134\n        }\n        break;\n      }\n    }\n    srcp += pitch * 2; // 2x2 pixels at a time (4:2:0 subsampling)\n    srcn += pitch * 2;\n    srcpV += pitchUV;\n    srcpU += pitchUV;\n  }\n}\n\ntemplate<typename pixel_t>\nstatic void show_chroma_yuv444(BYTE *srcp8, BYTE *srcpU8, BYTE *srcpV8, int pitch, int pitchUV, int width, int height, int min_chroma, int max_chroma, int bits_per_pixel)\n{\n  const int shift = sizeof(pixel_t) == 1 ? 0 : (bits_per_pixel - 8);\n  pixel_t *srcp = reinterpret_cast<pixel_t *>(srcp8);\n  pixel_t *srcpU = reinterpret_cast<pixel_t *>(srcpU8);\n  pixel_t *srcpV = reinterpret_cast<pixel_t *>(srcpV8);\n  pitch /= sizeof(pixel_t);\n  pitchUV /= sizeof(pixel_t);\n\n  for (int h=0; h < height; h+=1) {\n    for (int x = 0; x < width; x+=1) {\n      if ( (srcpU[x] < min_chroma)  // U-\n        || (srcpU[x] > max_chroma)  // U+\n        || (srcpV[x] < min_chroma)  // V-\n        || (srcpV[x] > max_chroma) )// V+\n      { srcp[x]=210 << shift; srcpU[x]= 16 << shift; srcpV[x]=146 << shift; }   // yellow:Y=210, U=16 and V=146\n    }\n    srcp  += pitch;\n    srcpV += pitchUV;\n    srcpU += pitchUV;\n  }\n}\n\ntemplate<typename pixel_t>\nstatic void show_chroma_yuv420(BYTE *srcp8, BYTE *srcpU8, BYTE *srcpV8, int pitch, int pitchUV, int width, int height, int min_chroma, int max_chroma, int bits_per_pixel)\n{\n  const int shift = sizeof(pixel_t) == 1 ? 0 : (bits_per_pixel - 8);\n  pixel_t *srcp = reinterpret_cast<pixel_t *>(srcp8);\n  pixel_t *srcn = reinterpret_cast<pixel_t *>(srcp8 + pitch); // next line\n  pixel_t *srcpU = reinterpret_cast<pixel_t *>(srcpU8);\n  pixel_t *srcpV = reinterpret_cast<pixel_t *>(srcpV8);\n  pitch /= sizeof(pixel_t);\n  pitchUV /= sizeof(pixel_t);\n\n  for (int h=0; h < height; h+=2) {\n    for (int x = 0; x < width; x+=2) {\n      if ( (srcpU[x/2] < min_chroma)  // U-\n        || (srcpU[x/2] > max_chroma)  // U+\n        || (srcpV[x/2] < min_chroma)  // V-\n        || (srcpV[x/2] > max_chroma) )// V+\n      { srcp[x]=srcp[x+1]=srcn[x]=srcn[x+1]=210 << shift; srcpU[x/2]= 16 << shift; srcpV[x/2]=146 << shift; }   // yellow:Y=210, U=16 and V=146\n    }\n    srcp += pitch*2; // 2x2 pixels at a time (4:2:0 subsampling)\n    srcn += pitch*2;\n    srcpV += pitchUV;\n    srcpU += pitchUV;\n  }\n}\n\ntemplate<typename pixel_t>\nstatic void show_chroma_grey_yuv444(BYTE *srcp8, BYTE *srcpU8, BYTE *srcpV8, int pitch, int pitchUV, int width, int height, int min_chroma, int max_chroma, int bits_per_pixel)\n{\n  const int shift = sizeof(pixel_t) == 1 ? 0 : (bits_per_pixel - 8);\n  pixel_t *srcp = reinterpret_cast<pixel_t *>(srcp8);\n  pixel_t *srcpU = reinterpret_cast<pixel_t *>(srcpU8);\n  pixel_t *srcpV = reinterpret_cast<pixel_t *>(srcpV8);\n  pitch /= sizeof(pixel_t);\n  pitchUV /= sizeof(pixel_t);\n\n  for (int h=0; h < height; h+=1) {\n    for (int x = 0; x < width; x+=1) {\n      int uv = 0;\n      if      (srcpU[x] < min_chroma) uv |= 1; // U-\n      else if (srcpU[x] > max_chroma) uv |= 2; // U+\n      if      (srcpV[x] < min_chroma) uv |= 4; // V-\n      else if (srcpV[x] > max_chroma) uv |= 8; // V+\n      switch (uv) {\n      case  8: srcp[x]= 81 << shift; srcpU[x]= 91 << shift; srcpV[x]=240 << shift; break;   //   +V Red\n      case  9: srcp[x]=146 << shift; srcpU[x]= 53 << shift; srcpV[x]=193 << shift; break;   // -U+V Orange\n      case  1: srcp[x]=210 << shift; srcpU[x]= 16 << shift; srcpV[x]=146 << shift; break;   // -U   Yellow\n      case  5: srcp[x]=153 << shift; srcpU[x]= 49 << shift; srcpV[x]= 49 << shift; break;   // -U-V Green\n      case  4: srcp[x]=170 << shift; srcpU[x]=165 << shift; srcpV[x]= 16 << shift; break;   //   -V Cyan\n      case  6: srcp[x]=105 << shift; srcpU[x]=203 << shift; srcpV[x]= 63 << shift; break;   // +U-V Teal\n      case  2: srcp[x]= 41 << shift; srcpU[x]=240 << shift; srcpV[x]=110 << shift; break;   // +U   Blue\n      case 10: srcp[x]=106 << shift; srcpU[x]=202 << shift; srcpV[x]=222 << shift; break;   // +U+V Magenta\n      default:              srcpU[x]=     srcpV[x]=128 << shift; break;\n      }\n    }\n    srcp  += pitch;\n    srcpV += pitchUV;\n    srcpU += pitchUV;\n  }\n}\n\ntemplate<typename pixel_t>\nstatic void show_chroma_grey_yuv420(BYTE *srcp8, BYTE *srcpU8, BYTE *srcpV8, int pitch, int pitchUV, int width, int height, int min_chroma, int max_chroma, int bits_per_pixel)\n{\n  const int shift = sizeof(pixel_t) == 1 ? 0 : (bits_per_pixel - 8);\n  pixel_t *srcp = reinterpret_cast<pixel_t *>(srcp8);\n  pixel_t *srcn = reinterpret_cast<pixel_t *>(srcp8 + pitch); // next line\n  pixel_t *srcpU = reinterpret_cast<pixel_t *>(srcpU8);\n  pixel_t *srcpV = reinterpret_cast<pixel_t *>(srcpV8);\n  pitch /= sizeof(pixel_t);\n  pitchUV /= sizeof(pixel_t);\n\n  for (int h=0; h < height; h+=2) {\n    for (int x = 0; x < width; x+=2) {\n      int uv = 0;\n      if      (srcpU[x/2] < min_chroma) uv |= 1; // U-\n      else if (srcpU[x/2] > max_chroma) uv |= 2; // U+\n      if      (srcpV[x/2] < min_chroma) uv |= 4; // V-\n      else if (srcpV[x/2] > max_chroma) uv |= 8; // V+\n      switch (uv) {\n      case  8: srcp[x]=srcp[x+1]=srcn[x]=srcn[x+1]= 81 << shift; srcpU[x/2]= 91 << shift; srcpV[x/2]=240 << shift; break;   //   +V Red\n      case  9: srcp[x]=srcp[x+1]=srcn[x]=srcn[x+1]=146 << shift; srcpU[x/2]= 53 << shift; srcpV[x/2]=193 << shift; break;   // -U+V Orange\n      case  1: srcp[x]=srcp[x+1]=srcn[x]=srcn[x+1]=210 << shift; srcpU[x/2]= 16 << shift; srcpV[x/2]=146 << shift; break;   // -U   Yellow\n      case  5: srcp[x]=srcp[x+1]=srcn[x]=srcn[x+1]=153 << shift; srcpU[x/2]= 49 << shift; srcpV[x/2]= 49 << shift; break;   // -U-V Green\n      case  4: srcp[x]=srcp[x+1]=srcn[x]=srcn[x+1]=170 << shift; srcpU[x/2]=165 << shift; srcpV[x/2]= 16 << shift; break;   //   -V Cyan\n      case  6: srcp[x]=srcp[x+1]=srcn[x]=srcn[x+1]=105 << shift; srcpU[x/2]=203 << shift; srcpV[x/2]= 63 << shift; break;   // +U-V Teal\n      case  2: srcp[x]=srcp[x+1]=srcn[x]=srcn[x+1]= 41 << shift; srcpU[x/2]=240 << shift; srcpV[x/2]=110 << shift; break;   // +U   Blue\n      case 10: srcp[x]=srcp[x+1]=srcn[x]=srcn[x+1]=106 << shift; srcpU[x/2]=202 << shift; srcpV[x/2]=222 << shift; break;   // +U+V Magenta\n      default: srcpU[x/2] = srcpV[x/2] = 128 << shift; break;\n      }\n    }\n    srcp += pitch*2; // 2x2 pixels at a time (4:2:0 subsampling)\n    srcn += pitch*2;\n    srcpV += pitchUV;\n    srcpU += pitchUV;\n  }\n}\n\nstatic void show_chroma_yuv444_f(BYTE *srcp8, BYTE *srcpU8, BYTE *srcpV8, int pitch, int pitchUV, int width, int height, float min_chroma, float max_chroma)\n{\n  float *srcp = reinterpret_cast<float *>(srcp8);\n  float *srcpU = reinterpret_cast<float *>(srcpU8);\n  float *srcpV = reinterpret_cast<float *>(srcpV8);\n  pitch /= sizeof(float);\n  pitchUV /= sizeof(float);\n\n  for (int h = 0; h < height; h += 1) {\n    for (int x = 0; x < width; x += 1) {\n      if ((srcpU[x] < min_chroma)  // U-\n        || (srcpU[x] > max_chroma)  // U+\n        || (srcpV[x] < min_chroma)  // V-\n        || (srcpV[x] > max_chroma))// V+\n      {\n        srcp[x] = c8tof(210); srcpU[x] = uv8tof(16); srcpV[x] = uv8tof(146);\n      }   // yellow:Y=210, U=16 and V=146\n    }\n    srcp += pitch;\n    srcpV += pitchUV;\n    srcpU += pitchUV;\n  }\n}\n\nstatic void show_chroma_yuv420_f(BYTE *srcp8, BYTE *srcpU8, BYTE *srcpV8, int pitch, int pitchUV, int width, int height, float min_chroma, float max_chroma)\n{\n  float *srcp = reinterpret_cast<float *>(srcp8);\n  float *srcn = reinterpret_cast<float *>(srcp8 + pitch); // next line\n  float *srcpU = reinterpret_cast<float *>(srcpU8);\n  float *srcpV = reinterpret_cast<float *>(srcpV8);\n  pitch /= sizeof(float);\n  pitchUV /= sizeof(float);\n\n  for (int h = 0; h < height; h += 2) {\n    for (int x = 0; x < width; x += 2) {\n      if ((srcpU[x / 2] < min_chroma)  // U-\n        || (srcpU[x / 2] > max_chroma)  // U+\n        || (srcpV[x / 2] < min_chroma)  // V-\n        || (srcpV[x / 2] > max_chroma))// V+\n      {\n        srcp[x] = srcp[x + 1] = srcn[x] = srcn[x + 1] = c8tof(210); srcpU[x / 2] = uv8tof(16); srcpV[x / 2] = uv8tof(146);\n      }   // yellow:Y=210, U=16 and V=146\n    }\n    srcp += pitch * 2; // 2x2 pixels at a time (4:2:0 subsampling)\n    srcn += pitch * 2;\n    srcpV += pitchUV;\n    srcpU += pitchUV;\n  }\n}\n\nstatic void show_chroma_grey_yuv444_f(BYTE *srcp8, BYTE *srcpU8, BYTE *srcpV8, int pitch, int pitchUV, int width, int height, float min_chroma, float max_chroma)\n{\n  float *srcp = reinterpret_cast<float *>(srcp8);\n  float *srcpU = reinterpret_cast<float *>(srcpU8);\n  float *srcpV = reinterpret_cast<float *>(srcpV8);\n  pitch /= sizeof(float);\n  pitchUV /= sizeof(float);\n\n  for (int h = 0; h < height; h += 1) {\n    for (int x = 0; x < width; x += 1) {\n      int uv = 0;\n      if (srcpU[x] < min_chroma) uv |= 1; // U-\n      else if (srcpU[x] > max_chroma) uv |= 2; // U+\n      if (srcpV[x] < min_chroma) uv |= 4; // V-\n      else if (srcpV[x] > max_chroma) uv |= 8; // V+\n      switch (uv) {\n      case  8: srcp[x] = c8tof(81); srcpU[x] = uv8tof(91); srcpV[x] = uv8tof(240); break;   //   +V Red\n      case  9: srcp[x] = c8tof(146); srcpU[x] = uv8tof(53); srcpV[x] = uv8tof(193); break;   // -U+V Orange\n      case  1: srcp[x] = c8tof(210); srcpU[x] = uv8tof(16); srcpV[x] = uv8tof(146); break;   // -U   Yellow\n      case  5: srcp[x] = c8tof(153); srcpU[x] = uv8tof(49); srcpV[x] = uv8tof(49); break;   // -U-V Green\n      case  4: srcp[x] = c8tof(170); srcpU[x] = uv8tof(165); srcpV[x] = uv8tof(16); break;   //   -V Cyan\n      case  6: srcp[x] = c8tof(105); srcpU[x] = uv8tof(203); srcpV[x] = uv8tof(63); break;   // +U-V Teal\n      case  2: srcp[x] = c8tof(41); srcpU[x] = uv8tof(240); srcpV[x] = uv8tof(110); break;   // +U   Blue\n      case 10: srcp[x] = c8tof(106); srcpU[x] = uv8tof(202); srcpV[x] = uv8tof(222); break;   // +U+V Magenta\n      default:              srcpU[x] = srcpV[x] = uv8tof(128); break;\n      }\n    }\n    srcp += pitch;\n    srcpV += pitchUV;\n    srcpU += pitchUV;\n  }\n}\n\nstatic void show_chroma_grey_yuv420_f(BYTE *srcp8, BYTE *srcpU8, BYTE *srcpV8, int pitch, int pitchUV, int width, int height, float min_chroma, float max_chroma)\n{\n  float *srcp = reinterpret_cast<float *>(srcp8);\n  float *srcn = reinterpret_cast<float *>(srcp8 + pitch); // next line\n  float *srcpU = reinterpret_cast<float *>(srcpU8);\n  float *srcpV = reinterpret_cast<float *>(srcpV8);\n  pitch /= sizeof(float);\n  pitchUV /= sizeof(float);\n\n  for (int h = 0; h < height; h += 2) {\n    for (int x = 0; x < width; x += 2) {\n      int uv = 0;\n      if (srcpU[x / 2] < min_chroma) uv |= 1; // U-\n      else if (srcpU[x / 2] > max_chroma) uv |= 2; // U+\n      if (srcpV[x / 2] < min_chroma) uv |= 4; // V-\n      else if (srcpV[x / 2] > max_chroma) uv |= 8; // V+\n      switch (uv) {\n      case  8: srcp[x] = srcp[x + 1] = srcn[x] = srcn[x + 1] = c8tof(81); srcpU[x / 2] = uv8tof(91); srcpV[x / 2] = uv8tof(240); break;   //   +V Red\n      case  9: srcp[x] = srcp[x + 1] = srcn[x] = srcn[x + 1] = c8tof(146); srcpU[x / 2] = uv8tof(53); srcpV[x / 2] = uv8tof(193); break;   // -U+V Orange\n      case  1: srcp[x] = srcp[x + 1] = srcn[x] = srcn[x + 1] = c8tof(210); srcpU[x / 2] = uv8tof(16); srcpV[x / 2] = uv8tof(146); break;   // -U   Yellow\n      case  5: srcp[x] = srcp[x + 1] = srcn[x] = srcn[x + 1] = c8tof(153); srcpU[x / 2] = uv8tof(49); srcpV[x / 2] = uv8tof(49); break;   // -U-V Green\n      case  4: srcp[x] = srcp[x + 1] = srcn[x] = srcn[x + 1] = c8tof(170); srcpU[x / 2] = uv8tof(165); srcpV[x / 2] = uv8tof(16); break;   //   -V Cyan\n      case  6: srcp[x] = srcp[x + 1] = srcn[x] = srcn[x + 1] = c8tof(105); srcpU[x / 2] = uv8tof(203); srcpV[x / 2] = uv8tof(63); break;   // +U-V Teal\n      case  2: srcp[x] = srcp[x + 1] = srcn[x] = srcn[x + 1] = c8tof(41); srcpU[x / 2] = uv8tof(240); srcpV[x / 2] = uv8tof(110); break;   // +U   Blue\n      case 10: srcp[x] = srcp[x + 1] = srcn[x] = srcn[x + 1] = c8tof(106); srcpU[x / 2] = uv8tof(202); srcpV[x / 2] = uv8tof(222); break;   // +U+V Magenta\n      default: srcpU[x / 2] = srcpV[x / 2] = uv8tof(128); break;\n      }\n    }\n    srcp += pitch * 2; // 2x2 pixels at a time (4:2:0 subsampling)\n    srcn += pitch * 2;\n    srcpV += pitchUV;\n    srcpU += pitchUV;\n  }\n}\n\nPVideoFrame __stdcall Limiter::GetFrame(int n, IScriptEnvironment* env) {\n  PVideoFrame frame = child->GetFrame(n, env);\n  env->MakeWritable(&frame);\n  unsigned char* srcp = frame->GetWritePtr();\n  int pitch = frame->GetPitch();\n  int row_size = frame->GetRowSize();\n  int width = vi.width;\n  int height = vi.height;\n\n  if (vi.IsYUY2()) {\n\n    if (show == show_luma) {  // Mark clamped pixels red/yellow/green over a colour image\n      for (int y = 0; y < height; y++) {\n        for (int x = 0; x < row_size; x+=4) {\n          int uv = 0;\n          if      (srcp[x  ] < min_luma) { srcp[x  ] =  81; uv |= 1;}\n          else if (srcp[x  ] > max_luma) { srcp[x  ] = 145; uv |= 2;}\n          if      (srcp[x+2] < min_luma) { srcp[x+2] =  81; uv |= 1;}\n          else if (srcp[x+2] > max_luma) { srcp[x+2] = 145; uv |= 2;}\n          switch (uv) {\n            case 1: srcp[x+1] = 91; srcp[x+3] = 240; break;     // red:   Y= 81, U=91 and V=240\n            case 2: srcp[x+1] = 54; srcp[x+3] =  34; break;     // green: Y=145, U=54 and V=34\n            case 3: srcp[x  ] =     srcp[x+2] = 210;\n                    srcp[x+1] = 16; srcp[x+3] = 146; break;     // yellow:Y=210, U=16 and V=146\n            default: break;\n          }\n        }\n        srcp += pitch;\n      }\n      return frame;\n    }\n    else if (show == show_luma_grey) {    // Mark clamped pixels coloured over a greyscaled image\n      for (int y = 0; y < height; y++) {\n        for (int x = 0; x < row_size; x+=4) {\n          int uv = 0;\n          if      (srcp[x  ] < min_luma) { srcp[x  ] =  81; uv |= 1;}\n          else if (srcp[x  ] > max_luma) { srcp[x  ] = 145; uv |= 2;}\n          if      (srcp[x+2] < min_luma) { srcp[x+2] =  81; uv |= 1;}\n          else if (srcp[x+2] > max_luma) { srcp[x+2] = 145; uv |= 2;}\n          switch (uv) {\n            case 1: srcp[x+1] = 91; srcp[x+3] = 240; break;     // red:   Y=81, U=91 and V=240\n            case 2: srcp[x+1] = 54; srcp[x+3] =  34; break;     // green: Y=145, U=54 and V=34\n            case 3: srcp[x+1] = 90; srcp[x+3] = 134; break;     // puke:  Y=81, U=90 and V=134\n            default: srcp[x+1] = srcp[x+3] = 128; break;        // olive: Y=145, U=90 and V=134\n          }\n        }\n        srcp += pitch;\n      }\n      return frame;\n    }\n    else if (show == show_chroma) {    // Mark clamped pixels yellow over a colour image\n      for (int y = 0; y < height; y++) {\n        for (int x = 0; x < row_size; x+=4) {\n          if ( (srcp[x+1] < min_chroma)  // U-\n            || (srcp[x+1] > max_chroma)  // U+\n            || (srcp[x+3] < min_chroma)  // V-\n            || (srcp[x+3] > max_chroma) )// V+\n           { srcp[x]=srcp[x+2]=210; srcp[x+1]=16; srcp[x+3]=146; }    // yellow:Y=210, U=16 and V=146\n        }\n        srcp += pitch;\n      }\n      return frame;\n    }\n    else if (show == show_chroma_grey) {    // Mark clamped pixels coloured over a greyscaled image\n      for (int y = 0; y < height; y++) {\n        for (int x = 0; x < row_size; x+=4) {\n          int uv = 0;\n          if      (srcp[x+1] < min_chroma) uv |= 1; // U-\n          else if (srcp[x+1] > max_chroma) uv |= 2; // U+\n          if      (srcp[x+3] < min_chroma) uv |= 4; // V-\n          else if (srcp[x+3] > max_chroma) uv |= 8; // V+\n          switch (uv) {\n            case  8: srcp[x] = srcp[x+2] =  81; srcp[x+1] =  91; srcp[x+3] = 240; break;    //   +V Red\n            case  9: srcp[x] = srcp[x+2] = 146; srcp[x+1] =  53; srcp[x+3] = 193; break;    // -U+V Orange\n            case  1: srcp[x] = srcp[x+2] = 210; srcp[x+1] =  16; srcp[x+3] = 146; break;    // -U   Yellow\n            case  5: srcp[x] = srcp[x+2] = 153; srcp[x+1] =  49; srcp[x+3] =  49; break;    // -U-V Green\n            case  4: srcp[x] = srcp[x+2] = 170; srcp[x+1] = 165; srcp[x+3] =  16; break;    //   -V Cyan\n            case  6: srcp[x] = srcp[x+2] = 105; srcp[x+1] = 203; srcp[x+3] =  63; break;    // +U-V Teal\n            case  2: srcp[x] = srcp[x+2] =  41; srcp[x+1] = 240; srcp[x+3] = 110; break;    // +U   Blue\n            case 10: srcp[x] = srcp[x+2] = 106; srcp[x+1] = 202; srcp[x+3] = 222; break;    // +U+V Magenta\n            default: srcp[x+1] = srcp[x+3] = 128; break;\n          }\n        }\n        srcp += pitch;\n      }\n      return frame;\n    }\n#ifdef INTEL_INTRINSICS\n    if (env->GetCPUFlags() & CPUF_SSE2) {\n      limit_plane_sse2(srcp, min_luma | (min_chroma << 8), max_luma | (max_chroma << 8), pitch, row_size, height);\n      return frame;\n    }\n\n    /** Run emulator if CPU supports it**/\n#ifdef X86_32\n    if (env->GetCPUFlags() & CPUF_INTEGER_SSE)\n    {\n      //limit_plane_mmx(srcp, min_luma, max_luma, pitch, row_size, height);\n      limit_plane_isse(srcp, min_luma | (min_chroma << 8), max_luma | (max_chroma << 8), pitch, row_size, height);\n      return frame;\n    }\n#endif\n    // If not ISSE\n#endif\n    for(int y = 0; y < height; y++) {\n      for(int x = 0; x < row_size; x++) {\n        if(srcp[x] < min_luma )\n          srcp[x++] = (unsigned char)min_luma;\n        else if(srcp[x] > max_luma)\n          srcp[x++] = (unsigned char)max_luma;\n        else\n          x++;\n        if(srcp[x] < min_chroma)\n          srcp[x] = (unsigned char)min_chroma;\n        else if(srcp[x] > max_chroma)\n          srcp[x] = (unsigned char)max_chroma;\n      }\n      srcp += pitch;\n    }\n    return frame;\n    // YUY end\n  } else if(vi.Is420() && show != show_none) {\n    const int pitchUV = frame->GetPitch(PLANAR_U);\n    unsigned char* srcpV = frame->GetWritePtr(PLANAR_V);\n    unsigned char* srcpU = frame->GetWritePtr(PLANAR_U);\n\n    if (show == show_luma || show == show_luma_grey) {    // Mark clamped pixels red/yellow/green over a colour image\n      if (pixelsize == 1) {\n        if (show == show_luma)\n          show_luma_with_grey_opt_yuv420<uint8_t, false>(srcp, srcpU, srcpV, pitch, pitchUV, width, height, min_luma, max_luma, bits_per_pixel);\n        else // show_luma_grey\n          show_luma_with_grey_opt_yuv420<uint8_t, true>(srcp, srcpU, srcpV, pitch, pitchUV, width, height, min_luma, max_luma, bits_per_pixel);\n      } else if (pixelsize == 2) { // pixelsize == 2\n        if (show == show_luma)\n          show_luma_with_grey_opt_yuv420<uint16_t, false>(srcp, srcpU, srcpV, pitch, pitchUV, width, height, min_luma, max_luma, bits_per_pixel);\n        else // show_luma_grey\n          show_luma_with_grey_opt_yuv420<uint16_t, true>(srcp, srcpU, srcpV, pitch, pitchUV, width, height, min_luma, max_luma, bits_per_pixel);\n      }\n      else { // pixelsize == 4\n        if (show == show_luma)\n          show_luma_with_grey_opt_yuv420_f<false>(srcp, srcpU, srcpV, pitch, pitchUV, width, height, min_luma_f, max_luma_f);\n        else // show_luma_grey\n          show_luma_with_grey_opt_yuv420_f<true>(srcp, srcpU, srcpV, pitch, pitchUV, width, height, min_luma_f, max_luma_f);\n      }\n      return frame;\n    }\n    else if (show == show_chroma) {   // Mark clamped pixels yellow over a colour image\n      if (pixelsize == 1)\n        show_chroma_yuv420<uint8_t>(srcp, srcpU, srcpV, pitch, pitchUV, width, height, min_chroma, max_chroma, bits_per_pixel);\n      else if (pixelsize == 2)\n        show_chroma_yuv420<uint16_t>(srcp, srcpU, srcpV, pitch, pitchUV, width, height, min_chroma, max_chroma, bits_per_pixel);\n      else // float\n        show_chroma_yuv420_f(srcp, srcpU, srcpV, pitch, pitchUV, width, height, min_chroma_f, max_chroma_f);\n      return frame;\n    }\n    else if (show == show_chroma_grey) {   // Mark clamped pixels coloured over a greyscaled image\n      if (pixelsize == 1)\n        show_chroma_grey_yuv420<uint8_t>(srcp, srcpU, srcpV, pitch, pitchUV, width, height, min_chroma, max_chroma, bits_per_pixel);\n      else if (pixelsize == 2)\n        show_chroma_grey_yuv420<uint16_t>(srcp, srcpU, srcpV, pitch, pitchUV, width, height, min_chroma, max_chroma, bits_per_pixel);\n      else // float\n        show_chroma_grey_yuv420_f(srcp, srcpU, srcpV, pitch, pitchUV, width, height, min_chroma_f, max_chroma_f);\n      return frame;\n    }\n    // YV12 (4:2:0) end\n  } else if(vi.Is444() && show != show_none) {\n\n    const int pitchUV = frame->GetPitch(PLANAR_U);\n    unsigned char* srcpV = frame->GetWritePtr(PLANAR_V);\n    unsigned char* srcpU = frame->GetWritePtr(PLANAR_U);\n\n    if (show == show_luma || show == show_luma_grey) {\n      if (pixelsize == 1) {\n        if (show == show_luma)\n          show_luma_with_grey_opt_yuv444<uint8_t, false>(srcp, srcpU, srcpV, pitch, pitchUV, width, height, min_luma, max_luma, bits_per_pixel);\n        else // show_luma_grey\n          show_luma_with_grey_opt_yuv444<uint8_t, true>(srcp, srcpU, srcpV, pitch, pitchUV, width, height, min_luma, max_luma, bits_per_pixel);\n      } else if (pixelsize == 2) {\n          if (show == show_luma)\n            show_luma_with_grey_opt_yuv444<uint16_t, false>(srcp, srcpU, srcpV, pitch, pitchUV, width, height, min_luma, max_luma, bits_per_pixel);\n          else // show_luma_grey\n            show_luma_with_grey_opt_yuv444<uint16_t, true>(srcp, srcpU, srcpV, pitch, pitchUV, width, height, min_luma, max_luma, bits_per_pixel);\n      }\n      else { // pixelsize == 4\n        if (show == show_luma)\n          show_luma_with_grey_opt_yuv444_f<false>(srcp, srcpU, srcpV, pitch, pitchUV, width, height, min_luma_f, max_luma_f);\n        else // show_luma_grey\n          show_luma_with_grey_opt_yuv444_f<true>(srcp, srcpU, srcpV, pitch, pitchUV, width, height, min_luma_f, max_luma_f);\n      }\n      return frame;\n    }\n    else if (show == show_chroma) {   // Mark clamped pixels yellow over a colour image\n      if (pixelsize == 1)\n        show_chroma_yuv444<uint8_t>(srcp, srcpU, srcpV, pitch, pitchUV, width, height, min_chroma, max_chroma, bits_per_pixel);\n      else if (pixelsize == 2)\n        show_chroma_yuv444<uint16_t>(srcp, srcpU, srcpV, pitch, pitchUV, width, height, min_chroma, max_chroma, bits_per_pixel);\n      else // float\n        show_chroma_yuv444_f(srcp, srcpU, srcpV, pitch, pitchUV, width, height, min_chroma_f, max_chroma_f);\n      return frame;\n    }\n    else if (show == show_chroma_grey) {   // Mark clamped pixels coloured over a greyscaled image\n      if (pixelsize == 1)\n        show_chroma_grey_yuv444<uint8_t>(srcp, srcpU, srcpV, pitch, pitchUV, width, height, min_chroma, max_chroma, bits_per_pixel);\n      else if (pixelsize == 2)\n        show_chroma_grey_yuv444<uint16_t>(srcp, srcpU, srcpV, pitch, pitchUV, width, height, min_chroma, max_chroma, bits_per_pixel);\n      else // float\n        show_chroma_grey_yuv444_f(srcp, srcpU, srcpV, pitch, pitchUV, width, height, min_chroma_f, max_chroma_f);\n      return frame;\n    }\n    // YV24 (4:4:4) end\n  }\n  if (vi.IsPlanar())\n  {\n#ifdef INTEL_INTRINSICS\n    //todo: separate to functions and use sse2 for aligned planes even if some are unaligned\n    if ((pixelsize==1) && (env->GetCPUFlags() & CPUF_SSE2)) {\n        limit_plane_sse2(srcp, min_luma | (min_luma << 8), max_luma | (max_luma << 8), pitch, row_size, height);\n\n        limit_plane_sse2(frame->GetWritePtr(PLANAR_U), min_chroma | (min_chroma << 8), max_chroma | (max_chroma << 8),\n          frame->GetPitch(PLANAR_U), frame->GetRowSize(PLANAR_U), frame->GetHeight(PLANAR_U));\n\n        limit_plane_sse2(frame->GetWritePtr(PLANAR_V), min_chroma | (min_chroma << 8), max_chroma | (max_chroma << 8),\n          frame->GetPitch(PLANAR_V), frame->GetRowSize(PLANAR_V), frame->GetHeight(PLANAR_V));\n\n        return frame;\n    }\n\n#ifdef X86_32\n    if ((pixelsize==1) && (env->GetCPUFlags() & CPUF_INTEGER_SSE))\n    {\n      limit_plane_isse(srcp, min_luma | (min_luma << 8), max_luma | (max_luma << 8), pitch, row_size, height);\n      limit_plane_isse(frame->GetWritePtr(PLANAR_U), min_chroma | (min_chroma << 8), max_chroma | (max_chroma << 8),\n        frame->GetPitch(PLANAR_U), frame->GetRowSize(PLANAR_U), frame->GetHeight(PLANAR_U));\n      limit_plane_isse(frame->GetWritePtr(PLANAR_V), min_chroma | (min_chroma << 8), max_chroma | (max_chroma << 8),\n        frame->GetPitch(PLANAR_V), frame->GetRowSize(PLANAR_V), frame->GetHeight(PLANAR_V));\n\n      return frame;\n    }\n#endif\n\n    if (pixelsize == 2 )\n    {\n      if (env->GetCPUFlags() & CPUF_SSE4_1) {\n        limit_plane_uint16_sse4(srcp, min_luma, max_luma, pitch, height);\n\n        limit_plane_uint16_sse4(frame->GetWritePtr(PLANAR_U), min_chroma, max_chroma,\n          frame->GetPitch(PLANAR_U), frame->GetHeight(PLANAR_U));\n\n        limit_plane_uint16_sse4(frame->GetWritePtr(PLANAR_V), min_chroma, max_chroma,\n          frame->GetPitch(PLANAR_V), frame->GetHeight(PLANAR_V));\n\n        return frame;\n      }\n      if (env->GetCPUFlags() & CPUF_SSE2) {\n        limit_plane_uint16_sse2(srcp, min_luma, max_luma, pitch, height);\n\n        limit_plane_uint16_sse2(frame->GetWritePtr(PLANAR_U), min_chroma, max_chroma,\n          frame->GetPitch(PLANAR_U), frame->GetHeight(PLANAR_U));\n\n        limit_plane_uint16_sse2(frame->GetWritePtr(PLANAR_V), min_chroma, max_chroma,\n          frame->GetPitch(PLANAR_V), frame->GetHeight(PLANAR_V));\n\n        return frame;\n      }\n    }\n#endif\n    // C\n    // luma\n    if(pixelsize == 1)\n      limit_plane_c<uint8_t>(srcp, pitch, min_luma, max_luma, width, height);\n    else if(pixelsize == 2)\n      limit_plane_c<uint16_t>(srcp, pitch, min_luma, max_luma, width, height);\n    else // pixelsize == 4: 32 bit float\n      limit_plane_f_c(srcp, pitch, min_luma_f, max_luma_f, width, height);\n\n    // chroma if exists\n    srcp = frame->GetWritePtr(PLANAR_U);\n    width = frame->GetRowSize(PLANAR_U) / pixelsize;\n    height = frame->GetHeight(PLANAR_U);\n    pitch = frame->GetPitch(PLANAR_U);\n    if (!pitch)\n      return frame;\n    BYTE* srcpV = frame->GetWritePtr(PLANAR_V);\n    if(pixelsize == 1) {\n      limit_plane_c<uint8_t>(srcp, pitch, min_chroma, max_chroma, width, height);\n      limit_plane_c<uint8_t>(srcpV, pitch, min_chroma, max_chroma, width, height);\n    } else if(pixelsize == 2) {\n      limit_plane_c<uint16_t>(srcp, pitch, min_chroma, max_chroma, width, height);\n      limit_plane_c<uint16_t>(srcpV, pitch, min_chroma, max_chroma, width, height);\n    }\n    else {\n      // pixelsize == 4: 32 bit float\n      limit_plane_f_c(srcp, pitch, min_chroma_f, max_chroma_f, width, height);\n      limit_plane_f_c(srcpV, pitch, min_chroma_f, max_chroma_f, width, height);\n    }\n  }\n  return frame;\n}\n\nAVSValue __cdecl Limiter::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  const char* option = args[5].AsString(nullptr);\n  show_e show = show_none;\n\n  if (option) {\n    if (lstrcmpi(option, \"luma\") == 0)\n      show = show_luma;\n    else if (lstrcmpi(option, \"luma_grey\") == 0)\n      show = show_luma_grey;\n    else if (lstrcmpi(option, \"chroma\") == 0)\n      show = show_chroma;\n    else if (lstrcmpi(option, \"chroma_grey\") == 0)\n      show = show_chroma_grey;\n    else\n      env->ThrowError(\"Limiter: show must be \\\"luma\\\", \\\"luma_grey\\\", \\\"chroma\\\" or \\\"chroma_grey\\\"\");\n  }\n\n  const bool paramscale = args[6].AsBool(false);\n  return new Limiter(args[0].AsClip(), args[1].AsFloatf(-9999.0f), args[2].AsFloatf(-9999.0f), args[3].AsFloatf(-9999.0f), args[4].AsFloatf(-9999.0f), show, paramscale, env);\n}\n"
  },
  {
    "path": "avs_core/filters/limiter.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Limiter_H__\n#define __Limiter_H__\n\n#include <avisynth.h>\n\nclass Limiter : public GenericVideoFilter\n{\npublic:\n    Limiter(PClip _child, float _min_luma, float _max_luma, float _min_chroma, float _max_chroma, int _show, bool paramscale, IScriptEnvironment* env);\n    PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n    int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n      AVS_UNUSED(frame_range);\n      return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n    }\n\n    static AVSValue __cdecl Create(AVSValue args, void* user_data, IScriptEnvironment* env);\nprivate:\n\n  int max_luma;\n  int min_luma;\n  int max_chroma;\n  int min_chroma;\n\n  float max_luma_f;\n  float min_luma_f;\n  float max_chroma_f;\n  float min_chroma_f;\n\n  enum show_e{show_none, show_luma, show_luma_grey, show_chroma, show_chroma_grey};\n  const show_e show;\n\n  // avs+\n  int pixelsize;\n  int bits_per_pixel; // 8,10..16\n};\n\n#endif  // __Limiter_H__\n\n"
  },
  {
    "path": "avs_core/filters/merge.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n// Avisynth filter: YUV merge / Swap planes\n// by Klaus Post (kp@interact.dk)\n// adapted by Richard Berg (avisynth-dev@richardberg.net)\n// iSSE code by Ian Brabham\n\n#include <avisynth.h>\n#include \"merge.h\"\n#ifdef INTEL_INTRINSICS\n#include \"intel/merge_sse.h\"\n#include \"intel/merge_avx2.h\"\n#endif\n#include \"../core/internal.h\"\n#include \"avs/alignment.h\"\n#include <cstdint>\n\n\n/* -----------------------------------\n *     weighted_merge_chroma_yuy2\n * -----------------------------------\n */\nstatic void weighted_merge_chroma_yuy2_c(BYTE *src, const BYTE *chroma, int pitch, int chroma_pitch,int width, int height, int weight, int invweight) {\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; x+=2) {\n      src[x+1] = (chroma[x+1] * weight + src[x+1] * invweight + 16384) >> 15;\n    }\n    src+=pitch;\n    chroma+=chroma_pitch;\n  }\n}\n\n\n/* -----------------------------------\n *      weighted_merge_luma_yuy2\n * -----------------------------------\n */\nstatic void weighted_merge_luma_yuy2_c(BYTE *src, const BYTE *luma, int pitch, int luma_pitch,int width, int height, int weight, int invweight) {\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; x+=2) {\n      src[x] = (luma[x] * weight + src[x] * invweight + 16384) >> 15;\n    }\n    src+=pitch;\n    luma+=luma_pitch;\n  }\n}\n\n\n/* -----------------------------------\n *          replace_luma_yuy2\n * -----------------------------------\n */\nstatic void replace_luma_yuy2_c(BYTE *src, const BYTE *luma, int pitch, int luma_pitch,int width, int height ) {\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; x+=2) {\n      src[x] = luma[x];\n    }\n    src+=pitch;\n    luma+=luma_pitch;\n  }\n}\n\n\n/* -----------------------------------\n *            average_plane\n * -----------------------------------\n */\n// for uint8_t and uint16_t\ntemplate<typename pixel_t>\nstatic void average_plane_c(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height) {\n  for (int y = 0; y < height; ++y) {\n    for (size_t x = 0; x < rowsize / sizeof(pixel_t); ++x) {\n      reinterpret_cast<pixel_t *>(p1)[x] = (int(reinterpret_cast<pixel_t *>(p1)[x]) + reinterpret_cast<const pixel_t *>(p2)[x] + 1) >> 1;\n    }\n    p1 += p1_pitch;\n    p2 += p2_pitch;\n  }\n}\n// for float\nstatic void average_plane_c_float(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height) {\n\n  size_t rs = rowsize / sizeof(float);\n\n  for (int y = 0; y < height; ++y) {\n    for (size_t x = 0; x < rs; ++x) {\n      reinterpret_cast<float *>(p1)[x] = (reinterpret_cast<float *>(p1)[x] + reinterpret_cast<const float *>(p2)[x]) / 2.0f;\n    }\n    p1 += p1_pitch;\n    p2 += p2_pitch;\n  }\n}\n\n/* -----------------------------------\n *       weighted_merge_planar\n * -----------------------------------\n */\n\ntemplate<typename pixel_t>\nvoid weighted_merge_planar_c(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch,int rowsize, int height, float weight_f, int weight_i, int invweight_i) {\n  AVS_UNUSED(weight_f);\n  for (int y=0;y<height;y++) {\n    for (size_t x=0;x<rowsize / sizeof(pixel_t);x++) {\n      (reinterpret_cast<pixel_t *>(p1))[x] = ((reinterpret_cast<pixel_t *>(p1))[x]*invweight_i + (reinterpret_cast<const pixel_t *>(p2))[x]*weight_i + 32768) >> 16;\n    }\n    p2+=p2_pitch;\n    p1+=p1_pitch;\n  }\n}\n\nvoid weighted_merge_planar_c_float(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height, float weight_f, int weight_i, int invweight_i) {\n  AVS_UNUSED(weight_i);\n  AVS_UNUSED(invweight_i);\n  float invweight_f = 1.0f - weight_f;\n  size_t rs = rowsize / sizeof(float);\n\n  for (int y = 0; y < height; ++y) {\n    for (size_t x = 0; x < rs; ++x) {\n      reinterpret_cast<float *>(p1)[x] = (reinterpret_cast<float *>(p1)[x] * invweight_f + reinterpret_cast<const float *>(p2)[x] * weight_f);\n    }\n    p1 += p1_pitch;\n    p2 += p2_pitch;\n  }\n}\n\n\n/********************************************************************\n***** Declare index of new filters for Avisynth's filter engine *****\n********************************************************************/\nextern const AVSFunction Merge_filters[] = {\n  { \"Merge\",       BUILTIN_FUNC_PREFIX, \"cc[weight]f\", MergeAll::Create },  // src, src2, weight\n  { \"MergeChroma\", BUILTIN_FUNC_PREFIX, \"cc[weight]f\", MergeChroma::Create },  // src, chroma src, weight\n  { \"MergeChroma\", BUILTIN_FUNC_PREFIX, \"cc[chromaweight]f\", MergeChroma::Create },  // Legacy!\n  { \"MergeLuma\",   BUILTIN_FUNC_PREFIX, \"cc[weight]f\", MergeLuma::Create },      // src, luma src, weight\n  { \"MergeLuma\",   BUILTIN_FUNC_PREFIX, \"cc[lumaweight]f\", MergeLuma::Create },      // Legacy!\n  { 0 }\n};\n\n// also returns the proper integer weight/inverse weight for 8-16 bits\n#ifdef INTEL_INTRINSICS\nMergeFuncPtr getMergeFunc(int bits_per_pixel, int cpuFlags, BYTE *srcp, const BYTE *otherp, float weight_f, int &weight_i, int &invweight_i)\n#else\nMergeFuncPtr getMergeFunc(int bits_per_pixel, BYTE *srcp, const BYTE *otherp, float weight_f, int &weight_i, int &invweight_i)\n#endif\n{\n  const int pixelsize = bits_per_pixel == 8 ? 1 : (bits_per_pixel == 32 ? 4 : 2);\n\n  // SIMD 8-16 bit: bitshift 15 integer arithmetic\n  // C    8-16 bit: bitshift 16 integer arithmetic\n  // SIMD/C Float: original float weight\n\n  // set basic 8-16bit SIMD\n  weight_i = (int)(weight_f * 32767.0f + 0.5f);\n  invweight_i = 32767 - weight_i;\n\n  if (pixelsize == 1) {\n#ifdef INTEL_INTRINSICS\n    if (cpuFlags & CPUF_AVX2)\n      return &weighted_merge_planar_avx2;\n    if (cpuFlags & CPUF_SSE2)\n      return &weighted_merge_planar_sse2;\n#ifdef X86_32\n    if (cpuFlags & CPUF_MMX)\n      return &weighted_merge_planar_mmx;\n#endif\n#endif\n    // C: different scale!\n    weight_i = (int)(weight_f * 65535.0f + 0.5f);\n    invweight_i = 65535 - weight_i;\n    return &weighted_merge_planar_c<uint8_t>;\n  }\n  if (pixelsize == 2) {\n#ifdef INTEL_INTRINSICS\n    if (cpuFlags & CPUF_AVX2)\n    {\n      if (bits_per_pixel == 16)\n        return &weighted_merge_planar_uint16_avx2<false>;\n      return &weighted_merge_planar_uint16_avx2<true>;\n    }\n    if (cpuFlags & CPUF_SSE2)\n    {\n      if (bits_per_pixel == 16)\n        return &weighted_merge_planar_uint16_sse2<false>;\n      return &weighted_merge_planar_uint16_sse2<true>;\n    }\n#endif\n    // C: different scale!\n    weight_i = (int)(weight_f * 65535.0f + 0.5f);\n    invweight_i = 65535 - weight_i;\n    return &weighted_merge_planar_c<uint16_t>;\n  }\n\n  // pixelsize == 4\n#ifdef INTEL_INTRINSICS\n  if (cpuFlags & CPUF_SSE2)\n    return &weighted_merge_planar_sse2_float;\n#endif\n  return &weighted_merge_planar_c_float;\n}\n\nstatic void merge_plane(BYTE* srcp, const BYTE* otherp, int src_pitch, int other_pitch, int src_rowsize, int src_height, float weight, int pixelsize, int bits_per_pixel, IScriptEnvironment* env) {\n  if ((weight > 0.4961f) && (weight < 0.5039f))\n  {\n    //average of two planes\n    if (pixelsize != 4) // 1 or 2\n    {\n#ifdef INTEL_INTRINSICS\n      if (env->GetCPUFlags() & CPUF_AVX2) {\n        if (pixelsize == 1)\n          average_plane_avx2<uint8_t>(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height);\n        else // pixel_size==2\n          average_plane_avx2<uint16_t>(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height);\n      }\n      else if (env->GetCPUFlags() & CPUF_SSE2) {\n        if (pixelsize == 1)\n          average_plane_sse2<uint8_t>(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height);\n        else // pixel_size==2\n          average_plane_sse2<uint16_t>(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height);\n      }\n      else\n#ifdef X86_32\n        if (env->GetCPUFlags() & CPUF_INTEGER_SSE) {\n          if (pixelsize == 1)\n            average_plane_isse<uint8_t>(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height);\n          else // pixel_size==2\n            average_plane_isse<uint16_t>(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height);\n        }\n        else\n#endif\n#endif\n        {\n          if (pixelsize == 1)\n            average_plane_c<uint8_t>(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height);\n          else // pixel_size==2\n            average_plane_c<uint16_t>(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height);\n        }\n    }\n    else { // if (pixelsize == 4)\n#ifdef INTEL_INTRINSICS\n      if (env->GetCPUFlags() & CPUF_SSE2)\n        average_plane_sse2_float(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height);\n      else\n#endif\n        average_plane_c_float(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height);\n    }\n  }\n  else\n  {\n    int weight_i;\n    int invweight_i;\n#ifdef INTEL_INTRINSICS\n    MergeFuncPtr weighted_merge_planar = getMergeFunc(bits_per_pixel, env->GetCPUFlags(), srcp, otherp, weight, /*out*/weight_i, /*out*/invweight_i);\n#else\n    MergeFuncPtr weighted_merge_planar = getMergeFunc(bits_per_pixel, srcp, otherp, weight, /*out*/weight_i, /*out*/invweight_i);\n#endif\n    weighted_merge_planar(srcp, otherp, src_pitch, other_pitch, src_rowsize, src_height, weight, weight_i, invweight_i);\n  }\n}\n\n/****************************\n******   Merge Chroma   *****\n****************************/\n\nMergeChroma::MergeChroma(PClip _child, PClip _clip, float _weight, IScriptEnvironment* env)\n  : GenericVideoFilter(_child), clip(_clip), weight(_weight)\n{\n  const VideoInfo& vi2 = clip->GetVideoInfo();\n\n  if (!(vi.IsYUV() || vi.IsYUVA()) || !(vi2.IsYUV() || vi2.IsYUVA()))\n    env->ThrowError(\"MergeChroma: YUV data only (no RGB); use ConvertToYUY2, ConvertToYV12/16/24 or ConvertToYUVxxx\");\n\n  if (!(vi.IsSameColorspace(vi2)))\n    env->ThrowError(\"MergeChroma: YUV images must have same data type.\");\n\n  if (vi.width!=vi2.width || vi.height!=vi2.height)\n    env->ThrowError(\"MergeChroma: Images must have same width and height!\");\n\n  if (weight<0.0f) weight=0.0f;\n  if (weight>1.0f) weight=1.0f;\n\n  pixelsize = vi.ComponentSize();\n  bits_per_pixel = vi.BitsPerComponent();\n}\n\n\nPVideoFrame __stdcall MergeChroma::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame src = child->GetFrame(n, env);\n\n  if (weight < 0.0039f) return src;\n\n  PVideoFrame chroma = clip->GetFrame(n, env);\n\n  int h = src->GetHeight();\n  int w = src->GetRowSize(); // width in pixels\n\n  if (weight < 0.9961f) {\n    if (vi.IsYUY2()) {\n      env->MakeWritable(&src);\n      BYTE* srcp = src->GetWritePtr();\n      const BYTE* chromap = chroma->GetReadPtr();\n\n      int src_pitch = src->GetPitch();\n      int chroma_pitch = chroma->GetPitch();\n#ifdef INTEL_INTRINSICS\n      if (env->GetCPUFlags() & CPUF_SSE2)\n      {\n        weighted_merge_chroma_yuy2_sse2(srcp, chromap, src_pitch, chroma_pitch, w, h, (int)(weight * 32768.0f), 32768 - (int)(weight * 32768.0f));\n      }\n      else\n#ifdef X86_32\n        if (env->GetCPUFlags() & CPUF_MMX)\n        {\n          weighted_merge_chroma_yuy2_mmx(srcp, chromap, src_pitch, chroma_pitch, w, h, (int)(weight * 32768.0f), 32768 - (int)(weight * 32768.0f));\n        }\n        else\n#endif\n#endif\n        {\n          weighted_merge_chroma_yuy2_c(srcp, chromap, src_pitch, chroma_pitch, w, h, (int)(weight * 32768.0f), 32768 - (int)(weight * 32768.0f));\n        }\n    }\n    else {  // Planar YUV\n      env->MakeWritable(&src);\n      src->GetWritePtr(PLANAR_Y); //Must be requested\n\n      BYTE* srcpU = (BYTE*)src->GetWritePtr(PLANAR_U);\n      BYTE* chromapU = (BYTE*)chroma->GetReadPtr(PLANAR_U);\n      BYTE* srcpV = (BYTE*)src->GetWritePtr(PLANAR_V);\n      BYTE* chromapV = (BYTE*)chroma->GetReadPtr(PLANAR_V);\n      int src_pitch_uv = src->GetPitch(PLANAR_U);\n      int chroma_pitch_uv = chroma->GetPitch(PLANAR_U);\n      int src_rowsize_u = src->GetRowSize(PLANAR_U_ALIGNED);\n      int src_rowsize_v = src->GetRowSize(PLANAR_V_ALIGNED);\n      int src_height_uv = src->GetHeight(PLANAR_U);\n\n      merge_plane(srcpU, chromapU, src_pitch_uv, chroma_pitch_uv, src_rowsize_u, src_height_uv, weight, pixelsize, bits_per_pixel, env);\n      merge_plane(srcpV, chromapV, src_pitch_uv, chroma_pitch_uv, src_rowsize_v, src_height_uv, weight, pixelsize, bits_per_pixel, env);\n\n      if (vi.IsYUVA())\n        merge_plane(src->GetWritePtr(PLANAR_A), chroma->GetReadPtr(PLANAR_A), src->GetPitch(PLANAR_A), chroma->GetPitch(PLANAR_A),\n          src->GetRowSize(PLANAR_A_ALIGNED), src->GetHeight(PLANAR_A), weight, pixelsize, bits_per_pixel, env);\n    }\n  }\n  else { // weight == 1.0\n    if (vi.IsYUY2()) {\n      const BYTE* srcp = src->GetReadPtr();\n      env->MakeWritable(&chroma);\n      BYTE* chromap = chroma->GetWritePtr();\n\n      int src_pitch = src->GetPitch();\n      int chroma_pitch = chroma->GetPitch();\n#ifdef INTEL_INTRINSICS\n      if (env->GetCPUFlags() & CPUF_SSE2)\n      {\n        replace_luma_yuy2_sse2(chromap, srcp, chroma_pitch, src_pitch, w, h);  // Just swap luma/chroma\n      }\n      else\n#ifdef X86_32\n        if (env->GetCPUFlags() & CPUF_MMX)\n        {\n          replace_luma_yuy2_mmx(chromap, srcp, chroma_pitch, src_pitch, w, h);  // Just swap luma/chroma\n        }\n        else\n#endif\n#endif\n        {\n          replace_luma_yuy2_c(chromap, srcp, chroma_pitch, src_pitch, w, h);  // Just swap luma/chroma\n        }\n\n      return chroma;\n    }\n    else {\n      if (src->IsWritable()) {\n        src->GetWritePtr(PLANAR_Y); //Must be requested\n        env->BitBlt(src->GetWritePtr(PLANAR_U), src->GetPitch(PLANAR_U), chroma->GetReadPtr(PLANAR_U), chroma->GetPitch(PLANAR_U), chroma->GetRowSize(PLANAR_U), chroma->GetHeight(PLANAR_U));\n        env->BitBlt(src->GetWritePtr(PLANAR_V), src->GetPitch(PLANAR_V), chroma->GetReadPtr(PLANAR_V), chroma->GetPitch(PLANAR_V), chroma->GetRowSize(PLANAR_V), chroma->GetHeight(PLANAR_V));\n        if (vi.IsYUVA())\n          env->BitBlt(src->GetWritePtr(PLANAR_A), src->GetPitch(PLANAR_A), chroma->GetReadPtr(PLANAR_A), chroma->GetPitch(PLANAR_A), chroma->GetRowSize(PLANAR_A), chroma->GetHeight(PLANAR_A));\n      }\n      else { // avoid the cost of 2 chroma blits\n        PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n\n        env->BitBlt(dst->GetWritePtr(PLANAR_Y), dst->GetPitch(PLANAR_Y), src->GetReadPtr(PLANAR_Y), src->GetPitch(PLANAR_Y), src->GetRowSize(PLANAR_Y), src->GetHeight(PLANAR_Y));\n        env->BitBlt(dst->GetWritePtr(PLANAR_U), dst->GetPitch(PLANAR_U), chroma->GetReadPtr(PLANAR_U), chroma->GetPitch(PLANAR_U), chroma->GetRowSize(PLANAR_U), chroma->GetHeight(PLANAR_U));\n        env->BitBlt(dst->GetWritePtr(PLANAR_V), dst->GetPitch(PLANAR_V), chroma->GetReadPtr(PLANAR_V), chroma->GetPitch(PLANAR_V), chroma->GetRowSize(PLANAR_V), chroma->GetHeight(PLANAR_V));\n        if (vi.IsYUVA())\n          env->BitBlt(dst->GetWritePtr(PLANAR_A), dst->GetPitch(PLANAR_A), chroma->GetReadPtr(PLANAR_A), chroma->GetPitch(PLANAR_A), chroma->GetRowSize(PLANAR_A), chroma->GetHeight(PLANAR_A));\n\n        return dst;\n      }\n    }\n  }\n  return src;\n}\n\n\nAVSValue __cdecl MergeChroma::Create(AVSValue args, void* , IScriptEnvironment* env)\n{\n  return new MergeChroma(args[0].AsClip(), args[1].AsClip(), (float)args[2].AsFloat(1.0f), env);\n}\n\n\n/**************************\n******   Merge Luma   *****\n**************************/\n\n\nMergeLuma::MergeLuma(PClip _child, PClip _clip, float _weight, IScriptEnvironment* env)\n  : GenericVideoFilter(_child), clip(_clip), weight(_weight)\n{\n  const VideoInfo& vi2 = clip->GetVideoInfo();\n\n  if (!(vi.IsYUV() || vi.IsYUVA()) || !(vi2.IsYUV() || vi2.IsYUVA()))\n    env->ThrowError(\"MergeLuma: YUV data only (no RGB); use ConvertToYUY2, ConvertToYV12/16/24 or ConvertToYUVxxx\");\n\n  pixelsize = vi.ComponentSize();\n  bits_per_pixel = vi.BitsPerComponent();\n\n  if (!vi.IsSameColorspace(vi2)) {  // Since this is luma we allow all planar formats to be merged.\n    if (!(vi.IsPlanar() && vi2.IsPlanar())) {\n      env->ThrowError(\"MergeLuma: YUV data is not same type. YUY2 and planar images doesn't mix.\");\n    }\n    if (pixelsize != vi2.ComponentSize()) {\n      env->ThrowError(\"MergeLuma: YUV data bit depth is not same.\");\n    }\n  }\n\n  if (vi.width!=vi2.width || vi.height!=vi2.height)\n    env->ThrowError(\"MergeLuma: Images must have same width and height!\");\n\n  if (weight<0.0f) weight=0.0f;\n  if (weight>1.0f) weight=1.0f;\n\n}\n\n\nPVideoFrame __stdcall MergeLuma::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame src = child->GetFrame(n, env);\n\n  if (weight < 0.0039f) return src;\n\n  PVideoFrame luma = clip->GetFrame(n, env);\n\n  if (vi.IsYUY2()) {\n    env->MakeWritable(&src);\n    BYTE* srcp = src->GetWritePtr();\n    const BYTE* lumap = luma->GetReadPtr();\n\n    int isrc_pitch = src->GetPitch();\n    int iluma_pitch = luma->GetPitch();\n\n    int h = src->GetHeight();\n    int w = src->GetRowSize();\n\n    if (weight < 0.9961f) {\n#ifdef INTEL_INTRINSICS\n      if (env->GetCPUFlags() & CPUF_SSE2)\n      {\n        weighted_merge_luma_yuy2_sse2(srcp, lumap, isrc_pitch, iluma_pitch, w, h, (int)(weight * 32768.0f), 32768 - (int)(weight * 32768.0f));\n      }\n      else\n#ifdef X86_32\n        if (env->GetCPUFlags() & CPUF_MMX)\n        {\n          weighted_merge_luma_yuy2_mmx(srcp, lumap, isrc_pitch, iluma_pitch, w, h, (int)(weight * 32768.0f), 32768 - (int)(weight * 32768.0f));\n        }\n        else\n#endif\n#endif\n        {\n          weighted_merge_luma_yuy2_c(srcp, lumap, isrc_pitch, iluma_pitch, w, h, (int)(weight * 32768.0f), 32768 - (int)(weight * 32768.0f));\n        }\n    }\n    else {\n#ifdef INTEL_INTRINSICS\n      if (env->GetCPUFlags() & CPUF_SSE2)\n      {\n        replace_luma_yuy2_sse2(srcp, lumap, isrc_pitch, iluma_pitch, w, h);\n      }\n      else\n#ifdef X86_32\n        if (env->GetCPUFlags() & CPUF_MMX)\n        {\n          replace_luma_yuy2_mmx(srcp, lumap, isrc_pitch, iluma_pitch, w, h);\n        }\n        else\n#endif\n#endif\n        {\n          replace_luma_yuy2_c(srcp, lumap, isrc_pitch, iluma_pitch, w, h);\n        }\n    }\n    return src;\n  }  // Planar\n  if (weight > 0.9961f) {\n    // 2nd clip weight is almost 100%: no merge, just copy\n    const VideoInfo& vi2 = clip->GetVideoInfo();\n    if (luma->IsWritable() && vi.IsSameColorspace(vi2)) {\n      if (luma->GetRowSize(PLANAR_U)) {\n        luma->GetWritePtr(PLANAR_Y); //Must be requested BUT only if we actually do something\n        env->BitBlt(luma->GetWritePtr(PLANAR_U), luma->GetPitch(PLANAR_U), src->GetReadPtr(PLANAR_U), src->GetPitch(PLANAR_U), src->GetRowSize(PLANAR_U), src->GetHeight(PLANAR_U));\n        env->BitBlt(luma->GetWritePtr(PLANAR_V), luma->GetPitch(PLANAR_V), src->GetReadPtr(PLANAR_V), src->GetPitch(PLANAR_V), src->GetRowSize(PLANAR_V), src->GetHeight(PLANAR_V));\n      }\n      if (luma->GetPitch(PLANAR_A)) // copy Alpha if exists\n        env->BitBlt(luma->GetWritePtr(PLANAR_A), luma->GetPitch(PLANAR_A), src->GetReadPtr(PLANAR_A), src->GetPitch(PLANAR_A), src->GetRowSize(PLANAR_A), src->GetHeight(PLANAR_A));\n\n      return luma;\n    }\n    else { // avoid the cost of 2 chroma blits\n      PVideoFrame dst = env->NewVideoFrameP(vi, &luma);\n\n      env->BitBlt(dst->GetWritePtr(PLANAR_Y), dst->GetPitch(PLANAR_Y), luma->GetReadPtr(PLANAR_Y), luma->GetPitch(PLANAR_Y), luma->GetRowSize(PLANAR_Y), luma->GetHeight(PLANAR_Y));\n      if (src->GetRowSize(PLANAR_U) && dst->GetRowSize(PLANAR_U)) {\n        env->BitBlt(dst->GetWritePtr(PLANAR_U), dst->GetPitch(PLANAR_U), src->GetReadPtr(PLANAR_U), src->GetPitch(PLANAR_U), src->GetRowSize(PLANAR_U), src->GetHeight(PLANAR_U));\n        env->BitBlt(dst->GetWritePtr(PLANAR_V), dst->GetPitch(PLANAR_V), src->GetReadPtr(PLANAR_V), src->GetPitch(PLANAR_V), src->GetRowSize(PLANAR_V), src->GetHeight(PLANAR_V));\n      }\n      if (dst->GetPitch(PLANAR_A) && src->GetPitch(PLANAR_A)) // copy Alpha if in both clip exists\n        env->BitBlt(dst->GetWritePtr(PLANAR_A), dst->GetPitch(PLANAR_A), src->GetReadPtr(PLANAR_A), src->GetPitch(PLANAR_A), src->GetRowSize(PLANAR_A), src->GetHeight(PLANAR_A));\n\n      return dst;\n    }\n  }\n  else { // weight <= 0.9961f\n    env->MakeWritable(&src);\n    BYTE* srcpY = (BYTE*)src->GetWritePtr(PLANAR_Y);\n    BYTE* lumapY = (BYTE*)luma->GetReadPtr(PLANAR_Y);\n    int src_pitch = src->GetPitch(PLANAR_Y);\n    int luma_pitch = luma->GetPitch(PLANAR_Y);\n    int src_rowsize = src->GetRowSize(PLANAR_Y);\n    int src_height = src->GetHeight(PLANAR_Y);\n\n    merge_plane(srcpY, lumapY, src_pitch, luma_pitch, src_rowsize, src_height, weight, pixelsize, bits_per_pixel, env);\n  }\n\n  return src;\n}\n\n\nAVSValue __cdecl MergeLuma::Create(AVSValue args, void* , IScriptEnvironment* env)\n{\n  return new MergeLuma(args[0].AsClip(), args[1].AsClip(), (float)args[2].AsFloat(1.0f), env);\n}\n\n\n/*************************\n******   Merge All   *****\n*************************/\n\n\nMergeAll::MergeAll(PClip _child, PClip _clip, float _weight, IScriptEnvironment* env)\n  : GenericVideoFilter(_child), clip(_clip), weight(_weight)\n{\n  const VideoInfo& vi2 = clip->GetVideoInfo();\n\n  if (!vi.IsSameColorspace(vi2))\n    env->ThrowError(\"Merge: Pixel types are not the same. Both must be the same.\");\n\n  if (vi.width!=vi2.width || vi.height!=vi2.height)\n    env->ThrowError(\"Merge: Images must have same width and height!\");\n\n  pixelsize = vi.ComponentSize();\n  bits_per_pixel = vi.BitsPerComponent();\n\n  if (weight<0.0f) weight=0.0f;\n  if (weight>1.0f) weight=1.0f;\n}\n\n\nPVideoFrame __stdcall MergeAll::GetFrame(int n, IScriptEnvironment* env)\n{\n  if (weight<0.0039f) return child->GetFrame(n, env);\n  if (weight>0.9961f) return clip->GetFrame(n, env);\n\n  PVideoFrame src  = child->GetFrame(n, env);\n  PVideoFrame src2 =  clip->GetFrame(n, env);\n\n  env->MakeWritable(&src);\n  BYTE* srcp  = src->GetWritePtr();\n  const BYTE* srcp2 = src2->GetReadPtr();\n\n  const int src_pitch = src->GetPitch();\n  const int src_rowsize = src->GetRowSize();\n\n  merge_plane(srcp, srcp2, src_pitch, src2->GetPitch(), src_rowsize, src->GetHeight(), weight, pixelsize, bits_per_pixel, env);\n\n  if (vi.IsPlanar()) {\n    const int planesYUV[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A};\n    const int planesRGB[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A};\n    const int *planes = (vi.IsYUV() || vi.IsYUVA()) ? planesYUV : planesRGB;\n    // first plane is already processed\n    for (int p = 1; p < vi.NumComponents(); p++) {\n      const int plane = planes[p];\n      merge_plane(src->GetWritePtr(plane), src2->GetReadPtr(plane), src->GetPitch(plane), src2->GetPitch(plane), src->GetRowSize(plane), src->GetHeight(plane), weight, pixelsize, bits_per_pixel, env);\n    }\n  }\n\n  return src;\n}\n\n\nAVSValue __cdecl MergeAll::Create(AVSValue args, void* , IScriptEnvironment* env)\n{\n  return new MergeAll(args[0].AsClip(), args[1].AsClip(), (float)args[2].AsFloat(0.5f), env);\n}\n"
  },
  {
    "path": "avs_core/filters/merge.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n// Avisynth filter: YUV merge\n// by Klaus Post\n// adapted by Richard Berg (avisynth-dev@richardberg.net)\n\n\n#ifndef __Merge_H__\n#define __Merge_H__\n\n#include <avisynth.h>\n\n\n/****************************************************\n****************************************************/\n\nclass MergeChroma : public GenericVideoFilter\n/**\n  * Merge the chroma planes of one clip into another, preserving luma\n **/\n{\npublic:\n  MergeChroma(PClip _child, PClip _clip, float _weight, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void* user_data, IScriptEnvironment* env);\n\nprivate:\n  PClip clip;\n  float weight;\n  int pixelsize;\n  int bits_per_pixel;\n};\n\n\nclass MergeLuma : public GenericVideoFilter\n/**\n  * Merge the luma plane of one clip into another, preserving chroma\n **/\n{\npublic:\n  MergeLuma(PClip _child, PClip _clip, float _weight, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void* user_data, IScriptEnvironment* env);\n\nprivate:\n  PClip clip;\n  float weight;\n  int pixelsize;\n  int bits_per_pixel;\n};\n\n\nclass MergeAll : public GenericVideoFilter\n/**\n  * Merge the planes of one clip into another\n **/\n{\npublic:\n  MergeAll(PClip _child, PClip _clip, float _weight, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void* user_data, IScriptEnvironment* env);\n\nprivate:\n  PClip clip;\n  float weight;\n  int pixelsize;\n  int bits_per_pixel;\n};\n\ntypedef void(*MergeFuncPtr) (BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height, float weight_f, int weight_i, int invweight_i);\n#ifdef INTEL_INTRINSICS\nMergeFuncPtr getMergeFunc(int bits_per_pixel, int cpuFlags, BYTE *srcp, const BYTE *otherp, float weight_f, int &weight_i, int &invweight_i);\n#else\nMergeFuncPtr getMergeFunc(int bits_per_pixel, BYTE *srcp, const BYTE *otherp, float weight_f, int &weight_i, int &invweight_i);\n#endif\n\ntemplate<bool lessthan16bit>\nvoid weighted_merge_planar_uint16_sse2(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height, float weight_f, int weight_i, int invweight_i);\n\ntemplate<typename pixel_t>\nvoid weighted_merge_planar_c(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height, float weight_f, int weight_i, int invweight_i);\nvoid weighted_merge_planar_c_float(BYTE *p1, const BYTE *p2, int p1_pitch, int p2_pitch, int rowsize, int height, float weight_f, int weight_i, int invweight_i);\n\n#endif  // __Merge_H__\n"
  },
  {
    "path": "avs_core/filters/misc.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include \"misc.h\"\n#include <avs/minmax.h>\n#include \"../core/bitblt.h\"\n#include \"../core/internal.h\"\n\n\n\n\n/********************************************************************\n***** Declare index of new filters for Avisynth's filter engine *****\n********************************************************************/\n\nextern const AVSFunction Misc_filters[] = {\n  { \"FixLuminance\",  BUILTIN_FUNC_PREFIX, \"cif\", FixLuminance::Create },    // clip, intercept, slope\n  { \"PeculiarBlend\", BUILTIN_FUNC_PREFIX, \"ci\", PeculiarBlend::Create },   // clip, cutoff\n  { \"SkewRows\",      BUILTIN_FUNC_PREFIX, \"ci\", SkewRows::Create },   // clip, skew\n  { \"FixBrokenChromaUpsampling\", BUILTIN_FUNC_PREFIX, \"c\", FixBrokenChromaUpsampling::Create },\n  { NULL }\n};\n\n\n\n\n\n\n\n/********************************\n *******   Fix Luminance   ******\n ********************************/\n\nFixLuminance::FixLuminance(PClip _child, int _vertex, int _slope, IScriptEnvironment* env)\n : GenericVideoFilter(_child), vertex(_vertex), slope(_slope)\n{\n  if (!vi.IsYUY2())\n    env->ThrowError(\"FixLuminance: requires YUY2 input\");\n}\n\n\nPVideoFrame FixLuminance::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame frame = child->GetFrame(n, env);\n  env->MakeWritable(&frame);\n  BYTE* p = frame->GetWritePtr();\n  const int pitch = frame->GetPitch();\n  for (int y=0; y<=vertex-slope/16; ++y)\n  {\n    const int subtract = (vertex-y)*16/slope;\n    for (int x=0; x<vi.width; ++x)\n      p[x*2] = (BYTE)max(0, p[x*2]-subtract);\n    p += pitch;\n  }\n  return frame;\n}\n\n\nAVSValue __cdecl FixLuminance::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  return new FixLuminance(args[0].AsClip(), args[1].AsInt(), int(args[2].AsFloat()*16), env);\n}\n\n\n\n\n\n\n/***********************************************\n *******   Fix Broken Chroma Upsampling   ******\n ***********************************************/\n\nFixBrokenChromaUpsampling::FixBrokenChromaUpsampling(PClip _clip, IScriptEnvironment* env)\n  : GenericVideoFilter(_clip)\n{\n  if (!vi.IsYUY2())\n    env->ThrowError(\"FixBrokenChromaUpsampling: requires YUY2 input\");\n}\n\n\nPVideoFrame __stdcall FixBrokenChromaUpsampling::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame frame = child->GetFrame(n, env);\n  env->MakeWritable(&frame);\n  const int pitch = frame->GetPitch();\n  BYTE* p = frame->GetWritePtr() + pitch;\n  for (int y = (frame->GetHeight()+1)/4; y > 0; --y) {\n    for (int x = 0; x < frame->GetRowSize(); x += 4) {\n      BYTE t1 = p[x+1], t3 = p[x+3];\n      p[x+1] = p[pitch+x+1]; p[x+3] = p[pitch+x+3];\n      p[pitch+x+1] = t1; p[pitch+x+3] = t3;\n    }\n    p += pitch*4;\n  }\n  return frame;\n}\n\n\nAVSValue __cdecl FixBrokenChromaUpsampling::Create( AVSValue args, void*,\n                                                    IScriptEnvironment* env )\n{\n  return new FixBrokenChromaUpsampling(args[0].AsClip(), env);\n}\n\n\n\n\n\n\n/*********************************\n *******   Peculiar Blend   ******\n *********************************/\n\nPeculiarBlend::PeculiarBlend(PClip _child, int _cutoff, IScriptEnvironment* env)\n : GenericVideoFilter(_child), cutoff(_cutoff)\n{\n  if (!vi.IsYUY2())\n    env->ThrowError(\"PeculiarBlend: requires YUY2 input\");\n}\n\n\nPVideoFrame PeculiarBlend::GetFrame(int n, IScriptEnvironment* env) {\n  PVideoFrame a = child->GetFrame(n, env);\n  PVideoFrame b = child->GetFrame(n+1, env);\n  env->MakeWritable(&a);\n  BYTE* main = a->GetWritePtr();\n  const BYTE* other = b->GetReadPtr();\n  const int main_pitch = a->GetPitch();\n  const int other_pitch = b->GetPitch();\n  const int row_size = a->GetRowSize();\n\n  if (cutoff-31 > 0) {\n    int copy_top = min(cutoff-31, vi.height);\n    env->BitBlt(main, main_pitch, other, other_pitch, row_size, copy_top);\n    main += main_pitch * copy_top;\n    other += other_pitch * copy_top;\n  }\n  for (int y = max(0, cutoff-31); y < min(cutoff, vi.height-1); ++y) {\n    int scale = cutoff - y;\n    for (int x = 0; x < row_size; ++x)\n      main[x] = main[x] + BYTE(((other[x] - main[x]) * scale + 16) >> 5);\n    main += main_pitch;\n    other += other_pitch;\n  }\n\n  return a;\n}\n\n\nAVSValue __cdecl PeculiarBlend::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  return new PeculiarBlend(args[0].AsClip(), args[1].AsInt(), env);\n}\n\n\n\n\n\n\n/********************************\n *******     SkewRows      ******\n ********************************/\n\nSkewRows::SkewRows(PClip _child, int skew, IScriptEnvironment* env)\n : GenericVideoFilter(_child)\n{\n  if ((vi.NumComponents() > 1) && vi.IsPlanar())\n    env->ThrowError(\"SkewRows: requires non-planar or greyscale input\");\n\n  if (vi.IsYUY2() && skew&1)\n    env->ThrowError(\"SkewRows: For YUY2 skew must be even\");\n\n  vi.height *= vi.width;\n  vi.width  += skew;\n  vi.height += vi.width-1; // Ceiling\n  vi.height /= vi.width;\n}\n\n\nPVideoFrame SkewRows::GetFrame(int n, IScriptEnvironment* env) {\n\n  PVideoFrame src = child->GetFrame(n, env);\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n\n  const int srowsize = src->GetRowSize();\n  const int spitch   = src->GetPitch();\n  const BYTE *sptr   = src->GetReadPtr();\n\n  const int drowsize = dst->GetRowSize();\n  const int dpitch   = dst->GetPitch();\n  BYTE *dptr         = dst->GetWritePtr();\n\n  const int ssize = src->GetHeight()*srowsize;\n\n  int s=0, d=0;\n  for (int i=0; i < ssize; i++) {\n    if (s >= srowsize) {\n      s = 0;\n      sptr += spitch;\n    }\n    if (d >= drowsize) {\n      d = 0;\n      dptr += dpitch;\n    }\n    dptr[d++] = sptr[s++];\n  }\n\n  while (d < drowsize)\n    dptr[d++] = 128;\n\n  return dst;\n\n}\n\n\nAVSValue __cdecl SkewRows::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  return new SkewRows(args[0].AsClip(), args[1].AsInt(), env);\n}\n"
  },
  {
    "path": "avs_core/filters/misc.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Misc_H__\n#define __Misc_H__\n\n\n#include <avisynth.h>\n\n\n/********************************************************************\n********************************************************************/\n\n\nclass FixLuminance : public GenericVideoFilter\n/**\n  * Class to progressively darken the top of a YUY2 clip to compensate for bad VCRs\n **/\n{\npublic:\n  FixLuminance(PClip _child, int _vertex, int _slope, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\nprivate:\n  const int vertex, slope;\n};\n\n\nclass FixBrokenChromaUpsampling : public GenericVideoFilter\n/**\n  * Class to correct for the incorrect chroma upsampling done by the MS DV codec\n **/\n{\npublic:\n  FixBrokenChromaUpsampling(PClip _clip, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n};\n\n\nclass PeculiarBlend : public GenericVideoFilter\n/**\n  * Class to remove nasty telecining effect (see docs)\n **/\n{\npublic:\n  PeculiarBlend(PClip _child, int _cutoff, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\nprivate:\n  const int cutoff;\n};\n\n\nclass SkewRows : public GenericVideoFilter\n/**\n  * Class to recast the row alignment of a frame\n **/\n{\npublic:\n  SkewRows(PClip _child, int skew, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n};\n\n\n#endif  // __Misc_H__\n"
  },
  {
    "path": "avs_core/filters/overlay/444convert.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// Overlay (c) 2003, 2004 by Klaus Post\n\n#include \"444convert.h\"\n#include \"../../core/internal.h\"\n#include <avs/alignment.h>\n\n// fast in-place conversions from and to 4:4:4\n\n/***** YV12 -> YUV 4:4:4   ******/\n\ntemplate<typename pixel_t>\nstatic void convert_yv12_chroma_to_yv24_c(BYTE *dstp8, const BYTE *srcp8, int dst_pitch, int src_pitch, int src_width, int src_height) {\n  pixel_t *dstp = reinterpret_cast<pixel_t *>(dstp8);\n  const pixel_t *srcp = reinterpret_cast<const pixel_t *>(srcp8);\n  dst_pitch /= sizeof(pixel_t);\n  src_pitch /= sizeof(pixel_t);\n  for (int y = 0; y < src_height; ++y) {\n    for (int x = 0; x < src_width; ++x) {\n      dstp[x*2]             = srcp[x];\n      dstp[x*2+1]           = srcp[x];\n      dstp[x*2+dst_pitch]   = srcp[x];\n      dstp[x*2+dst_pitch+1] = srcp[x];\n    }\n    dstp += dst_pitch*2;\n    srcp += src_pitch;\n  }\n}\n\nvoid Convert444FromYV12(PVideoFrame &src, PVideoFrame &dst, int pixelsize, int bits_per_pixel, IScriptEnvironment* env)\n{\n  AVS_UNUSED(bits_per_pixel);\n  env->BitBlt(dst->GetWritePtr(PLANAR_Y), dst->GetPitch(PLANAR_Y), src->GetReadPtr(PLANAR_Y),src->GetPitch(PLANAR_Y), src->GetRowSize(PLANAR_Y), src->GetHeight());\n\n  const BYTE* srcU = src->GetReadPtr(PLANAR_U);\n  const BYTE* srcV = src->GetReadPtr(PLANAR_V);\n\n  int srcUVpitch = src->GetPitch(PLANAR_U);\n\n  BYTE* dstU = dst->GetWritePtr(PLANAR_U);\n  BYTE* dstV = dst->GetWritePtr(PLANAR_V);\n\n  int dstUVpitch = dst->GetPitch(PLANAR_U);\n\n  int width = src->GetRowSize(PLANAR_U) / pixelsize;\n  int height = src->GetHeight(PLANAR_U);\n\n      if (pixelsize == 1) {\n        convert_yv12_chroma_to_yv24_c<uint8_t>(dstU, srcU, dstUVpitch, srcUVpitch, width, height);\n        convert_yv12_chroma_to_yv24_c<uint8_t>(dstV, srcV, dstUVpitch, srcUVpitch, width, height);\n      } else if(pixelsize == 2) {\n        convert_yv12_chroma_to_yv24_c<uint16_t>(dstU, srcU, dstUVpitch, srcUVpitch, width, height);\n        convert_yv12_chroma_to_yv24_c<uint16_t>(dstV, srcV, dstUVpitch, srcUVpitch, width, height);\n      }\n      else {\n        convert_yv12_chroma_to_yv24_c<float>(dstU, srcU, dstUVpitch, srcUVpitch, width, height);\n        convert_yv12_chroma_to_yv24_c<float>(dstV, srcV, dstUVpitch, srcUVpitch, width, height);\n      }\n\n  env->BitBlt(dst->GetWritePtr(PLANAR_A), dst->GetPitch(PLANAR_A),\n    src->GetReadPtr(PLANAR_A), src->GetPitch(PLANAR_A), dst->GetRowSize(PLANAR_A), dst->GetHeight(PLANAR_A));\n\n\n}\n\n/***** YV16 -> YUV 4:4:4   ******/\n\ntemplate<typename pixel_t>\nstatic void convert_yv16_chroma_to_yv24_c(BYTE *dstp8, const BYTE *srcp8, int dst_pitch, int src_pitch, int src_width, int src_height) {\n  pixel_t *dstp = reinterpret_cast<pixel_t *>(dstp8);\n  const pixel_t *srcp = reinterpret_cast<const pixel_t *>(srcp8);\n  dst_pitch /= sizeof(pixel_t);\n  src_pitch /= sizeof(pixel_t);\n  for (int y = 0; y < src_height; ++y) {\n    for (int x = 0; x < src_width; ++x) {\n      dstp[x*2]             = srcp[x];\n      dstp[x*2+1]           = srcp[x];\n    }\n    dstp += dst_pitch;\n    srcp += src_pitch;\n  }\n}\n\nvoid Convert444FromYV16(PVideoFrame &src, PVideoFrame &dst, int pixelsize, int bits_per_pixel, IScriptEnvironment* env)\n{\n  AVS_UNUSED(bits_per_pixel);\n  env->BitBlt(dst->GetWritePtr(PLANAR_Y), dst->GetPitch(PLANAR_Y), src->GetReadPtr(PLANAR_Y),src->GetPitch(PLANAR_Y), src->GetRowSize(PLANAR_Y), src->GetHeight());\n\n  const BYTE* srcU = src->GetReadPtr(PLANAR_U);\n  const BYTE* srcV = src->GetReadPtr(PLANAR_V);\n\n  int srcUVpitch = src->GetPitch(PLANAR_U);\n\n  BYTE* dstU = dst->GetWritePtr(PLANAR_U);\n  BYTE* dstV = dst->GetWritePtr(PLANAR_V);\n\n  int dstUVpitch = dst->GetPitch(PLANAR_U);\n\n  int width = src->GetRowSize(PLANAR_U) / pixelsize;\n  int height = src->GetHeight(PLANAR_U);\n\n      if (pixelsize == 1) {\n        convert_yv16_chroma_to_yv24_c<uint8_t>(dstU, srcU, dstUVpitch, srcUVpitch, width, height);\n        convert_yv16_chroma_to_yv24_c<uint8_t>(dstV, srcV, dstUVpitch, srcUVpitch, width, height);\n      } else if(pixelsize == 2) {\n        convert_yv16_chroma_to_yv24_c<uint16_t>(dstU, srcU, dstUVpitch, srcUVpitch, width, height);\n        convert_yv16_chroma_to_yv24_c<uint16_t>(dstV, srcV, dstUVpitch, srcUVpitch, width, height);\n      }\n      else {\n        convert_yv16_chroma_to_yv24_c<float>(dstU, srcU, dstUVpitch, srcUVpitch, width, height);\n        convert_yv16_chroma_to_yv24_c<float>(dstV, srcV, dstUVpitch, srcUVpitch, width, height);\n      }\n\n  env->BitBlt(dst->GetWritePtr(PLANAR_A), dst->GetPitch(PLANAR_A),\n    src->GetReadPtr(PLANAR_A), src->GetPitch(PLANAR_A), dst->GetRowSize(PLANAR_A), dst->GetHeight(PLANAR_A));\n\n}\n\n/***** YUY2 -> YUV 4:4:4   ******/\n\nvoid Convert444FromYUY2(PVideoFrame &src, PVideoFrame &dst, int pixelsize, int bits_per_pixel, IScriptEnvironment* env) {\n  AVS_UNUSED(pixelsize);\n  AVS_UNUSED(bits_per_pixel);\n  AVS_UNUSED(env);\n\n  const BYTE* srcP = src->GetReadPtr();\n  int srcPitch = src->GetPitch();\n\n  BYTE* dstY = dst->GetWritePtr(PLANAR_Y);\n  BYTE* dstU = dst->GetWritePtr(PLANAR_U);\n  BYTE* dstV = dst->GetWritePtr(PLANAR_V);\n\n  int dstPitch = dst->GetPitch();\n\n  int w = src->GetRowSize() / 2;\n  int h = src->GetHeight();\n\n  for (int y=0; y<h; y++) {\n    for (int x=0; x<w; x+=2) {\n      int x2 = x<<1;\n      dstY[x]   = srcP[x2];\n      dstU[x]   = dstU[x+1] = srcP[x2+1];\n      dstV[x]   = dstV[x+1] = srcP[x2+3];\n      dstY[x+1] = srcP[x2+2];\n    }\n    srcP+=srcPitch;\n\n    dstY+=dstPitch;\n    dstU+=dstPitch;\n    dstV+=dstPitch;\n  }\n}\n\ntemplate<typename pixel_t>\nstatic void convert_yv24_chroma_to_yv12_c(BYTE *dstp8, const BYTE *srcp8, int dst_pitch, int src_pitch, int dst_width, const int dst_height) {\n  const pixel_t *srcp = reinterpret_cast<const pixel_t *>(srcp8);\n  pixel_t *dstp = reinterpret_cast<pixel_t *>(dstp8);\n  dst_pitch /= sizeof(pixel_t);\n  src_pitch /= sizeof(pixel_t);\n  for (int y = 0; y < dst_height; y++) {\n    for (int x = 0; x < dst_width; x++) {\n      if constexpr (sizeof(pixel_t) == 4)\n        dstp[x] = (srcp[x * 2] + srcp[x * 2 + 1] + srcp[x * 2 + src_pitch] + srcp[x * 2 + src_pitch + 1]) * 0.25f; // /4\n      else\n        dstp[x] = (srcp[x * 2] + srcp[x * 2 + 1] + srcp[x * 2 + src_pitch] + srcp[x * 2 + src_pitch + 1] + 2) >> 2;\n    }\n    srcp += src_pitch * 2;\n    dstp += dst_pitch;\n  }\n}\n\ntemplate<typename pixel_t>\nstatic void convert_yv24_chroma_to_yv16_c(BYTE *dstp8, const BYTE *srcp8, int dst_pitch, int src_pitch, int dst_width, const int dst_height) {\n  const pixel_t *srcp = reinterpret_cast<const pixel_t *>(srcp8);\n  pixel_t *dstp = reinterpret_cast<pixel_t *>(dstp8);\n  dst_pitch /= sizeof(pixel_t);\n  src_pitch /= sizeof(pixel_t);\n  for (int y=0; y < dst_height; y++) {\n    for (int x=0; x < dst_width; x++) {\n      if constexpr (sizeof(pixel_t) == 4)\n        dstp[x] = (srcp[x * 2] + srcp[x * 2 + 1]) * 0.5f;\n      else\n        dstp[x] = (srcp[x * 2] + srcp[x * 2 + 1] + 1) >> 1;\n    }\n    srcp+=src_pitch;\n    dstp+=dst_pitch;\n  }\n}\n\nvoid ConvertYToYV12Chroma(BYTE *dst, BYTE *src, int dstpitch, int srcpitch, int pixelsize, int w, int h, IScriptEnvironment* env)\n{\n    if(pixelsize==1)\n      convert_yv24_chroma_to_yv12_c<uint8_t>(dst, src, dstpitch, srcpitch, w, h);\n    else if (pixelsize == 2)\n      convert_yv24_chroma_to_yv12_c<uint16_t>(dst, src, dstpitch, srcpitch, w, h);\n    else // if (pixelsize == 4)\n      convert_yv24_chroma_to_yv12_c<float>(dst, src, dstpitch, srcpitch, w, h);\n}\n\nvoid ConvertYToYV16Chroma(BYTE *dst, BYTE *src, int dstpitch, int srcpitch, int pixelsize, int w, int h, IScriptEnvironment* env)\n{\n    if(pixelsize==1)\n      convert_yv24_chroma_to_yv16_c<uint8_t>(dst, src, dstpitch, srcpitch, w, h);\n    else if (pixelsize == 2)\n      convert_yv24_chroma_to_yv16_c<uint16_t>(dst, src, dstpitch, srcpitch, w, h);\n    else // if (pixelsize == 4)\n      convert_yv24_chroma_to_yv16_c<float>(dst, src, dstpitch, srcpitch, w, h);\n}\n\nvoid Convert444ToYV16(PVideoFrame &src, PVideoFrame &dst, int pixelsize, int bits_per_pixel, IScriptEnvironment* env)\n{\n  AVS_UNUSED(bits_per_pixel);\n  env->BitBlt(dst->GetWritePtr(PLANAR_Y), dst->GetPitch(PLANAR_Y),\n    src->GetReadPtr(PLANAR_Y), src->GetPitch(), dst->GetRowSize(PLANAR_Y), dst->GetHeight());\n\n  const BYTE* srcU = src->GetReadPtr(PLANAR_U);\n  const BYTE* srcV = src->GetReadPtr(PLANAR_V);\n\n  int srcUVpitch = src->GetPitch(PLANAR_U);\n\n  BYTE* dstU = dst->GetWritePtr(PLANAR_U);\n  BYTE* dstV = dst->GetWritePtr(PLANAR_V);\n\n  int dstUVpitch = dst->GetPitch(PLANAR_U);\n\n  int w = dst->GetRowSize(PLANAR_U);\n  int h = dst->GetHeight(PLANAR_U);\n\n      if(pixelsize==1) {\n        convert_yv24_chroma_to_yv16_c<uint8_t>(dstU, srcU, dstUVpitch, srcUVpitch, w, h);\n        convert_yv24_chroma_to_yv16_c<uint8_t>(dstV, srcV, dstUVpitch, srcUVpitch, w, h);\n      }\n      else if (pixelsize == 2) {\n        convert_yv24_chroma_to_yv16_c<uint16_t>(dstU, srcU, dstUVpitch, srcUVpitch, w, h);\n        convert_yv24_chroma_to_yv16_c<uint16_t>(dstV, srcV, dstUVpitch, srcUVpitch, w, h);\n      }\n      else { // if (pixelsize == 4)\n        convert_yv24_chroma_to_yv16_c<float>(dstU, srcU, dstUVpitch, srcUVpitch, w, h);\n        convert_yv24_chroma_to_yv16_c<float>(dstV, srcV, dstUVpitch, srcUVpitch, w, h);\n      }\n\n  env->BitBlt(dst->GetWritePtr(PLANAR_A), dst->GetPitch(PLANAR_A),\n    src->GetReadPtr(PLANAR_A), src->GetPitch(PLANAR_A), dst->GetRowSize(PLANAR_A), dst->GetHeight(PLANAR_A));\n}\n\n\nvoid Convert444ToYV12(PVideoFrame &src, PVideoFrame &dst, int pixelsize, int bits_per_pixel, IScriptEnvironment* env)\n{\n  AVS_UNUSED(bits_per_pixel);\n  env->BitBlt(dst->GetWritePtr(PLANAR_Y), dst->GetPitch(PLANAR_Y),\n    src->GetReadPtr(PLANAR_Y), src->GetPitch(), dst->GetRowSize(PLANAR_Y), dst->GetHeight());\n\n  const BYTE* srcU = src->GetReadPtr(PLANAR_U);\n  const BYTE* srcV = src->GetReadPtr(PLANAR_V);\n\n  int srcUVpitch = src->GetPitch(PLANAR_U);\n\n  BYTE* dstU = dst->GetWritePtr(PLANAR_U);\n  BYTE* dstV = dst->GetWritePtr(PLANAR_V);\n\n  int dstUVpitch = dst->GetPitch(PLANAR_U);\n\n  int w = dst->GetRowSize(PLANAR_U);\n  int h = dst->GetHeight(PLANAR_U);\n\n  if(pixelsize==1) {\n    convert_yv24_chroma_to_yv12_c<uint8_t>(dstU, srcU, dstUVpitch, srcUVpitch, w, h);\n    convert_yv24_chroma_to_yv12_c<uint8_t>(dstV, srcV, dstUVpitch, srcUVpitch, w, h);\n  }\n  else if (pixelsize == 2) {\n    convert_yv24_chroma_to_yv12_c<uint16_t>(dstU, srcU, dstUVpitch, srcUVpitch, w, h);\n    convert_yv24_chroma_to_yv12_c<uint16_t>(dstV, srcV, dstUVpitch, srcUVpitch, w, h);\n  }\n  else { // if (pixelsize == 4)\n    convert_yv24_chroma_to_yv12_c<float>(dstU, srcU, dstUVpitch, srcUVpitch, w, h);\n    convert_yv24_chroma_to_yv12_c<float>(dstV, srcV, dstUVpitch, srcUVpitch, w, h);\n  }\n\n  env->BitBlt(dst->GetWritePtr(PLANAR_A), dst->GetPitch(PLANAR_A),\n    src->GetReadPtr(PLANAR_A), src->GetPitch(PLANAR_A), dst->GetRowSize(PLANAR_A), dst->GetHeight(PLANAR_A));\n\n}\n\n/*****   YUV 4:4:4 -> YUY2   *******/\n\nvoid Convert444ToYUY2(PVideoFrame &src, PVideoFrame &dst, int pixelsize, int bits_per_pixel, IScriptEnvironment* env) {\n  AVS_UNUSED(bits_per_pixel);\n  AVS_UNUSED(env);\n\n  const BYTE* srcY = src->GetReadPtr(PLANAR_Y);\n  const BYTE* srcU = src->GetReadPtr(PLANAR_U);\n  const BYTE* srcV = src->GetReadPtr(PLANAR_V);\n\n  int srcPitch = src->GetPitch();\n\n  BYTE* dstP = dst->GetWritePtr();\n\n  int dstPitch = dst->GetPitch();\n\n  int w = src->GetRowSize() / pixelsize;\n  int h = src->GetHeight();\n\n  for (int y=0; y<h; y++) {\n    for (int x=0; x<w; x+=2) {\n      int x2 = x<<1;\n      dstP[x2]   = srcY[x];\n      dstP[x2+1] = (srcU[x] + srcU[x+1] + 1)>>1;\n      dstP[x2+2] = srcY[x+1];\n      dstP[x2+3] = (srcV[x] + srcV[x+1] + 1)>>1;\n    }\n    srcY+=srcPitch;\n    srcU+=srcPitch;\n    srcV+=srcPitch;\n    dstP+=dstPitch;\n  }\n}\n"
  },
  {
    "path": "avs_core/filters/overlay/444convert.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// Overlay (c) 2003, 2004 by Klaus Post\n\n#ifndef __444Convert_h\n#define __444Convert_h\n\n#include <avisynth.h>\n\nvoid Convert444FromYV16(PVideoFrame &src, PVideoFrame &dst, int pixelsize, int bits_per_pixel, IScriptEnvironment* env);\nvoid Convert444FromYV12(PVideoFrame &src, PVideoFrame &dst, int pixelsize, int bits_per_pixel, IScriptEnvironment* env);\nvoid Convert444FromYUY2(PVideoFrame &src, PVideoFrame &dst, int pixelsize, int bits_per_pixel, IScriptEnvironment* env);\nvoid Convert444ToYV16(PVideoFrame &src, PVideoFrame &dst, int pixelsize, int bits_per_pixel, IScriptEnvironment* env);\nvoid Convert444ToYV12(PVideoFrame &src, PVideoFrame &dst, int pixelsize, int bits_per_pixel, IScriptEnvironment* env);\nvoid Convert444ToYUY2(PVideoFrame &src, PVideoFrame &dst, int pixelsize, int bits_per_pixel, IScriptEnvironment* env);\nvoid ConvertYToYV12Chroma(BYTE *dst, BYTE *src, int dstpitch, int srcpitch, int pixelsize, int w, int h, IScriptEnvironment* env);\nvoid ConvertYToYV16Chroma(BYTE *dst, BYTE *src, int dstpitch, int srcpitch, int pixelsize, int w, int h, IScriptEnvironment* env);\n\n#endif //444Convert"
  },
  {
    "path": "avs_core/filters/overlay/OF_add.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// Overlay (c) 2003, 2004 by Klaus Post\n\n#include \"overlayfunctions.h\"\n\n#include <stdint.h>\n#include <type_traits>\n\nvoid OL_AddImage::DoBlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) {\n  if (rgb) {\n    if (of_mode == OF_Add) {\n      if (bits_per_pixel == 8)\n        BlendImageMask_RGB<uint8_t, true, true>(base, overlay, mask);\n      else if (bits_per_pixel <= 16)\n        BlendImageMask_RGB<uint16_t, true, true>(base, overlay, mask);\n      else if (bits_per_pixel == 32)\n        BlendImageMask_RGB_float<true, true>(base, overlay, mask);\n    } else {\n      // OF_Subtract\n      if (bits_per_pixel == 8)\n        BlendImageMask_RGB<uint8_t, true, false>(base, overlay, mask);\n      else if (bits_per_pixel <= 16)\n        BlendImageMask_RGB<uint16_t, true, false>(base, overlay, mask);\n      else if (bits_per_pixel == 32)\n        BlendImageMask_RGB_float<true, false>(base, overlay, mask);\n    }\n    return;\n  }\n  // existing YUV logic\n  if(of_mode == OF_Add) {\n    if (bits_per_pixel == 8)\n      BlendImageMask<uint8_t, true, true>(base, overlay, mask);\n    else if(bits_per_pixel <= 16)\n      BlendImageMask<uint16_t, true, true>(base, overlay, mask);\n    else if(bits_per_pixel == 32)\n      BlendImageMask_float<true, true>(base, overlay, mask);\n  }\n  else {\n    // OF_Subtract\n    if (bits_per_pixel == 8)\n      BlendImageMask<uint8_t, true, false>(base, overlay, mask);\n    else if(bits_per_pixel <= 16)\n      BlendImageMask<uint16_t, true, false>(base, overlay, mask);\n    else if(bits_per_pixel == 32)\n      BlendImageMask_float<true, false>(base, overlay, mask);\n  }\n}\n\nvoid OL_AddImage::DoBlendImage(ImageOverlayInternal* base, ImageOverlayInternal* overlay) {\n  if (rgb) {\n    if (of_mode == OF_Add) {\n      if (bits_per_pixel == 8)\n        BlendImageMask_RGB<uint8_t, false, true>(base, overlay, nullptr);\n      else if (bits_per_pixel <= 16)\n        BlendImageMask_RGB<uint16_t, false, true>(base, overlay, nullptr);\n      else if (bits_per_pixel == 32)\n        BlendImageMask_RGB_float<false, true>(base, overlay, nullptr);\n    }\n    else {\n      // OF_Subtract\n      if (bits_per_pixel == 8)\n        BlendImageMask_RGB<uint8_t, false, false>(base, overlay, nullptr);\n      else if (bits_per_pixel <= 16)\n        BlendImageMask_RGB<uint16_t, false, false>(base, overlay, nullptr);\n      else if (bits_per_pixel == 32)\n        BlendImageMask_RGB_float<false, false>(base, overlay, nullptr);\n    }\n    return;\n  }\n  // existing YUV logic\n  if(of_mode == OF_Add) {\n    if (bits_per_pixel == 8)\n      BlendImageMask<uint8_t, false, true>(base, overlay, nullptr);\n    else if(bits_per_pixel <= 16)\n      BlendImageMask<uint16_t, false, true>(base, overlay, nullptr);\n    else if(bits_per_pixel == 32)\n      BlendImageMask_float<false, true>(base, overlay, nullptr);\n  }\n  else {\n    // OF_Subtract\n    if (bits_per_pixel == 8)\n      BlendImageMask<uint8_t, false, false>(base, overlay, nullptr);\n    else if(bits_per_pixel <= 16)\n      BlendImageMask<uint16_t, false, false>(base, overlay, nullptr);\n    else if(bits_per_pixel == 32)\n      BlendImageMask_float<false, false>(base, overlay, nullptr);\n  }\n}\n\n// integer 8-16 bit add/subtract with YUV overshoot handling\ntemplate<typename pixel_t, bool maskMode, bool of_add>\nvoid OL_AddImage::BlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) {\n\n  pixel_t* baseY = reinterpret_cast<pixel_t *>(base->GetPtr(PLANAR_Y));\n  pixel_t* baseU = reinterpret_cast<pixel_t *>(base->GetPtr(PLANAR_U));\n  pixel_t* baseV = reinterpret_cast<pixel_t *>(base->GetPtr(PLANAR_V));\n\n  pixel_t* ovY = reinterpret_cast<pixel_t *>(overlay->GetPtr(PLANAR_Y));\n  pixel_t* ovU = reinterpret_cast<pixel_t *>(overlay->GetPtr(PLANAR_U));\n  pixel_t* ovV = reinterpret_cast<pixel_t *>(overlay->GetPtr(PLANAR_V));\n\n  pixel_t* maskY = maskMode ? reinterpret_cast<pixel_t *>(mask->GetPtr(PLANAR_Y)) : nullptr;\n  pixel_t* maskU = maskMode ? reinterpret_cast<pixel_t *>(mask->GetPtr(PLANAR_U)) : nullptr;\n  pixel_t* maskV = maskMode ? reinterpret_cast<pixel_t *>(mask->GetPtr(PLANAR_V)) : nullptr;\n\n  const int half_pixel_value = (sizeof(pixel_t) == 1) ? 128 : (1 << (bits_per_pixel - 1));\n  const int max_pixel_value = (sizeof(pixel_t) == 1) ? 255 : (1 << bits_per_pixel) - 1;\n  const int pixel_range = max_pixel_value + 1;\n  const int SHIFT  = (sizeof(pixel_t) == 1) ? 5 : 5 + (bits_per_pixel - 8);\n  const int MASK_CORR_SHIFT = (sizeof(pixel_t) == 1) ? 8 : bits_per_pixel;\n  const int OPACITY_SHIFT  = 8; // opacity always max 0..256\n  const int over32 = (1 << SHIFT); // 32\n  const int basepitch = (base->pitch) / sizeof(pixel_t);\n  const int overlaypitch = (overlay->pitch) / sizeof(pixel_t);\n  const int maskpitch = maskMode ? (mask->pitch) / sizeof(pixel_t) : 0;\n\n  // avoid \"uint16*uint16 can't get into int32\" overflows\n  typedef typename std::conditional < sizeof(pixel_t) == 1, int, typename std::conditional < sizeof(pixel_t) == 2, int64_t, float>::type >::type result_t;\n\n/*\n  In YUV, \"add\" and \"subtract\" are not just per-channel math. The luma (Y) is added/subtracted, but if the result\n  overflows (Y > max) or underflows (Y < 0), the chroma (U/V) is \"pulled\" toward neutral (gray/white) to mimic\n  how RGB overbright/underbright behaves visually.\n\n  In RGB, adding two bright colors can result in \"white\" (all channels maxed). In YUV, if you just add Y, U, and V,\n  we can get weird color shifts. The code compensates by blending U/V toward neutral when Y is out of range,\n  making the result look more like RGB addition.\n\n  For RGB, a simple per-channel add/subtract (with clamping for 8/16-bit, or no clamping for float) is done.\n  The \"magic\" is only needed for YUV to avoid odd color artifacts. In RGB, overbright naturally becomes white,\n  so no special handling is needed.\n*/\n\n  int w = base->w();\n  int h = base->h();\n  if (opacity == 256) {\n    for (int y = 0; y < h; y++) {\n      for (int x = 0; x < w; x++) {\n        int Y, U, V;\n        if (of_add) {\n          Y = baseY[x] + (maskMode ? (((result_t)ovY[x] * maskY[x]) >> MASK_CORR_SHIFT) : ovY[x]);\n          U = baseU[x] + (int)(maskMode ? ((((result_t)half_pixel_value*(pixel_range - maskU[x])) + ((result_t)maskU[x] * ovU[x])) >> MASK_CORR_SHIFT) : ovU[x]) - half_pixel_value;\n          V = baseV[x] + (int)(maskMode ? ((((result_t)half_pixel_value*(pixel_range - maskV[x])) + ((result_t)maskV[x] * ovV[x])) >> MASK_CORR_SHIFT) : ovV[x]) - half_pixel_value;\n          // When Y is too high, U and V are blended toward half_pixel_value (neutral chroma), making the color \"whiter\".\n          if (Y>max_pixel_value) {  // Apply overbrightness to UV\n            int multiplier = max(0,pixel_range + over32 -Y);  // 0 to 32\n            U = ((U*(         multiplier)) + (half_pixel_value*(over32-multiplier)))>>SHIFT;\n            V = ((V*(         multiplier)) + (half_pixel_value*(over32-multiplier)))>>SHIFT;\n            Y = max_pixel_value;\n          }\n        }\n        else {\n          // of_subtract\n          Y = baseY[x] - (maskMode ? (((result_t)ovY[x] * maskY[x]) >> MASK_CORR_SHIFT) : ovY[x]);\n          U = baseU[x] - (int)(maskMode ? ((((result_t)half_pixel_value*(pixel_range - maskU[x])) + ((result_t)maskU[x] * ovU[x])) >> MASK_CORR_SHIFT) : ovU[x]) + half_pixel_value;\n          V = baseV[x] - (int)(maskMode ? ((((result_t)half_pixel_value*(pixel_range - maskV[x])) + ((result_t)maskV[x] * ovV[x])) >> MASK_CORR_SHIFT) : ovV[x]) + half_pixel_value;\n          if (Y<0) {  // Apply superdark to UV\n            int multiplier = min(-Y,over32);  // 0 to 32\n            U = ((U*(over32 - multiplier)) + (half_pixel_value*(       multiplier)))>>SHIFT;\n            V = ((V*(over32 - multiplier)) + (half_pixel_value*(       multiplier)))>>SHIFT;\n            Y = 0;\n          }\n        }\n        baseU[x] = (pixel_t)clamp(U, 0, max_pixel_value);\n        baseV[x] = (pixel_t)clamp(V, 0, max_pixel_value);\n        baseY[x] = (pixel_t)Y;\n      }\n      baseY += basepitch;\n      baseU += basepitch;\n      baseV += basepitch;\n\n      ovY += overlaypitch;\n      ovU += overlaypitch;\n      ovV += overlaypitch;\n\n      if(maskMode) {\n        maskY += maskpitch;\n        maskU += maskpitch;\n        maskV += maskpitch;\n      }\n    }\n  } else {\n    for (int y = 0; y < h; y++) {\n      for (int x = 0; x < w; x++) {\n        int Y, U, V;\n        if(of_add)\n          Y = baseY[x] + (maskMode ? (((result_t)maskY[x] * opacity*ovY[x]) >> (OPACITY_SHIFT + MASK_CORR_SHIFT)) : ((opacity*ovY[x]) >> OPACITY_SHIFT));\n        else\n          Y = baseY[x] - (maskMode ? (((result_t)maskY[x] * opacity*ovY[x]) >> (OPACITY_SHIFT + MASK_CORR_SHIFT)) : ((opacity*ovY[x]) >> OPACITY_SHIFT));\n        if (maskMode) {\n          result_t mU = (maskU[x] * opacity) >> OPACITY_SHIFT;\n          result_t mV = (maskV[x] * opacity) >> OPACITY_SHIFT;\n          if(of_add) {\n            U = baseU[x] + (int)(((half_pixel_value*(pixel_range - mU)) + (mU*ovU[x])) >> MASK_CORR_SHIFT) - half_pixel_value;\n            V = baseV[x] + (int)(((half_pixel_value*(pixel_range - mV)) + (mV*ovV[x])) >> MASK_CORR_SHIFT) - half_pixel_value;\n          }\n          else {\n            U = baseU[x] - (int)(((half_pixel_value*(pixel_range - mU)) + (mU*ovU[x])) >> MASK_CORR_SHIFT) + half_pixel_value;\n            V = baseV[x] - (int)(((half_pixel_value*(pixel_range - mV)) + (mV*ovV[x])) >> MASK_CORR_SHIFT) + half_pixel_value;\n          }\n        }\n        else {\n          if(of_add) {\n            U = baseU[x] + (((half_pixel_value*inv_opacity)+(opacity*(ovU[x])))>>OPACITY_SHIFT) - half_pixel_value;\n            V = baseV[x] + (((half_pixel_value*inv_opacity)+(opacity*(ovV[x])))>>OPACITY_SHIFT) - half_pixel_value;\n          }\n          else {\n            U = baseU[x] - (((half_pixel_value*inv_opacity)+(opacity*(ovU[x])))>>OPACITY_SHIFT) + half_pixel_value;\n            V = baseV[x] - (((half_pixel_value*inv_opacity)+(opacity*(ovV[x])))>>OPACITY_SHIFT) + half_pixel_value;\n          }\n        }\n        if(of_add) {\n          if (Y>max_pixel_value) {  // Apply overbrightness to UV\n            int multiplier = max(0,(max_pixel_value + 1) + over32 - Y);  // 288-Y : 0 to 32\n            U = ((U*multiplier) + (half_pixel_value*(over32 - multiplier))) >> SHIFT;\n            V = ((V*multiplier) + (half_pixel_value*(over32 - multiplier))) >> SHIFT;\n            Y = max_pixel_value;\n          }\n        }\n        else {\n          // of_subtract\n          if (Y<0) {  // Apply overbrightness to UV\n            int multiplier = min(-Y,over32);  // 0 to 32\n            U = ((U*(over32 - multiplier)) + (half_pixel_value*(       multiplier)))>>SHIFT;\n            V = ((V*(over32 - multiplier)) + (half_pixel_value*(       multiplier)))>>SHIFT;\n            Y = 0;\n          }\n        }\n        baseU[x] = (pixel_t)clamp(U, 0, max_pixel_value);\n        baseV[x] = (pixel_t)clamp(V, 0, max_pixel_value);\n        baseY[x] = (pixel_t)Y;\n      }\n      baseY += basepitch;\n      baseU += basepitch;\n      baseV += basepitch;\n\n      ovY += overlaypitch;\n      ovU += overlaypitch;\n      ovV += overlaypitch;\n\n      if(maskMode) {\n        maskY += maskpitch;\n        maskU += maskpitch;\n        maskV += maskpitch;\n      }\n    }\n  }\n}\n\n// float add/subtract with YUV overshoot handling\ntemplate<bool maskMode, bool of_add>\nvoid OL_AddImage::BlendImageMask_float(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) {\n  // specialized pixel_t float images\n  // No clamping needed.\n  // float range here is supposed to be [0.0f .. 1.0f] for Y, [-0.5f .. 0.5f] for U/V\n  // mask is [0.0f .. 1.0f]\n  float* baseY = reinterpret_cast<float*>(base->GetPtr(PLANAR_Y));\n  float* baseU = reinterpret_cast<float*>(base->GetPtr(PLANAR_U));\n  float* baseV = reinterpret_cast<float*>(base->GetPtr(PLANAR_V));\n\n  float* ovY = reinterpret_cast<float*>(overlay->GetPtr(PLANAR_Y));\n  float* ovU = reinterpret_cast<float*>(overlay->GetPtr(PLANAR_U));\n  float* ovV = reinterpret_cast<float*>(overlay->GetPtr(PLANAR_V));\n\n  float* maskY = maskMode ? reinterpret_cast<float*>(mask->GetPtr(PLANAR_Y)) : nullptr;\n  float* maskU = maskMode ? reinterpret_cast<float*>(mask->GetPtr(PLANAR_U)) : nullptr;\n  float* maskV = maskMode ? reinterpret_cast<float*>(mask->GetPtr(PLANAR_V)) : nullptr;\n\n  // For float, half_pixel_value is 0.0f, max_pixel_value is 1.0f for Y\n  constexpr float half_pixel_value = 0.0f; // intentionally keep it 0.0f for U/V calculation, compiler will optimize away\n  constexpr float max_pixel_value = 1.0f; // for Y overshoot check\n  constexpr float pixel_range = 1.0f; // mask must be in [0.0f, 1.0f]\n\n  // have no opacity (0..256), but special opacity_f (0..1.0) for float\n  // Unlike integer case which has OPACITY_SHIFT of 8 bit for integer arithmetic \n  const float inv_opacity_f = 1.0f - opacity_f; \n\n  const int basepitch = (base->pitch) / sizeof(float);\n  const int overlaypitch = (overlay->pitch) / sizeof(float);\n  const int maskpitch = maskMode ? (mask->pitch) / sizeof(float) : 0;\n\n  int w = base->w();\n  int h = base->h();\n\n  if (opacity_f == 1.0f) {\n    for (int y = 0; y < h; y++) {\n      for (int x = 0; x < w; ++x) {\n        float Y, U, V;\n        if (of_add) {\n          Y = baseY[x] + (maskMode ? ovY[x] * maskY[x] : ovY[x]);\n          U = baseU[x] + (maskMode ? (half_pixel_value * (pixel_range - maskU[x]) + maskU[x] * ovU[x]) : ovU[x]) - half_pixel_value;\n          V = baseV[x] + (maskMode ? (half_pixel_value * (pixel_range - maskV[x]) + maskV[x] * ovV[x]) : ovV[x]) - half_pixel_value;\n        } else {\n          Y = baseY[x] - (maskMode ? ovY[x] * maskY[x] : ovY[x]);\n          U = baseU[x] - (maskMode ? (half_pixel_value * (pixel_range - maskU[x]) + maskU[x] * ovU[x]) : ovU[x]) + half_pixel_value;\n          V = baseV[x] - (maskMode ? (half_pixel_value * (pixel_range - maskV[x]) + maskV[x] * ovV[x]) : ovV[x]) + half_pixel_value;\n        }\n\n        constexpr float over32 = 32.0f / 255.0f; // ~0.12549f\n\n        if (of_add) {\n          if (Y > max_pixel_value) { // Y > 1.0f\n            float multiplier = max(0.0f, 1.0f + over32 - Y); // 1.12549 - Y, clamp to >=0\n            // Blend U/V toward neutral (0.0f)\n            U = U * multiplier / over32;\n            V = V * multiplier / over32;\n            Y = max_pixel_value; // 1.0f\n          }\n        }\n        else {\n          if (Y < 0.0f) {\n            float multiplier = min(-Y, over32); // 0 to over32\n            U = U * (over32 - multiplier) / over32;\n            V = V * (over32 - multiplier) / over32;\n            Y = 0.0f;\n          }\n        }\n\n        // No other clamping for float\n        baseU[x] = U;\n        baseV[x] = V;\n        baseY[x] = Y;\n      }\n      baseY += basepitch;\n      baseU += basepitch;\n      baseV += basepitch;\n\n      ovY += overlaypitch;\n      ovU += overlaypitch;\n      ovV += overlaypitch;\n\n      if (maskMode) {\n        maskY += maskpitch;\n        maskU += maskpitch;\n        maskV += maskpitch;\n      }\n    }\n  } else {\n    for (int y = 0; y < h; y++) {\n      for (int x = 0; x < w; ++x) {\n        float Y, U, V;\n        if (of_add)\n          Y = baseY[x] + (maskMode ? maskY[x] * opacity_f * ovY[x] : opacity_f * ovY[x]);\n        else\n          Y = baseY[x] - (maskMode ? maskY[x] * opacity_f * ovY[x] : opacity_f * ovY[x]);\n        if (maskMode) {\n          float mU = maskU[x] * opacity_f;\n          float mV = maskV[x] * opacity_f;\n          if (of_add) {\n            U = baseU[x] + (half_pixel_value * (pixel_range - mU) + mU * ovU[x]) - half_pixel_value;\n            V = baseV[x] + (half_pixel_value * (pixel_range - mV) + mV * ovV[x]) - half_pixel_value;\n          } else {\n            U = baseU[x] - (half_pixel_value * (pixel_range - mU) + mU * ovU[x]) + half_pixel_value;\n            V = baseV[x] - (half_pixel_value * (pixel_range - mV) + mV * ovV[x]) + half_pixel_value;\n          }\n        } else {\n          if (of_add) {\n            U = baseU[x] + (half_pixel_value * inv_opacity_f + opacity_f * ovU[x]) - half_pixel_value;\n            V = baseV[x] + (half_pixel_value * inv_opacity_f + opacity_f * ovV[x]) - half_pixel_value;\n          } else {\n            U = baseU[x] - (half_pixel_value * inv_opacity_f + opacity_f * ovU[x]) + half_pixel_value;\n            V = baseV[x] - (half_pixel_value * inv_opacity_f + opacity_f * ovV[x]) + half_pixel_value;\n          }\n        }\n\n        constexpr float over32 = 32.0f / 255.0f; // ~0.12549f\n\n        if (of_add) {\n          if (Y > max_pixel_value) { // Y > 1.0f\n            float multiplier = max(0.0f, 1.0f + over32 - Y); // 1.12549 - Y, clamp to >=0\n            // Blend U/V toward neutral (0.0f)\n            U = U * multiplier / over32;\n            V = V * multiplier / over32;\n            Y = max_pixel_value; // 1.0f\n          }\n        }\n        else {\n          if (Y < 0.0f) {\n            float multiplier = min(-Y, over32); // 0 to over32\n            U = U * (over32 - multiplier) / over32;\n            V = V * (over32 - multiplier) / over32;\n            Y = 0.0f;\n          }\n        }\n\n        // No other clamping for float\n        baseU[x] = U;\n        baseV[x] = V;\n        baseY[x] = Y;\n      }\n      baseY += basepitch;\n      baseU += basepitch;\n      baseV += basepitch;\n\n      ovY += overlaypitch;\n      ovU += overlaypitch;\n      ovV += overlaypitch;\n\n      if (maskMode) {\n        maskY += maskpitch;\n        maskU += maskpitch;\n        maskV += maskpitch;\n      }\n    }\n  }\n}\n\n\n// integer 8-16-bit RGB add/subtract\ntemplate<typename pixel_t, bool maskMode, bool of_add>\nvoid OL_AddImage::BlendImageMask_RGB(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) {\n  int w = base->w();\n  int h = base->h();\n  const int pixelsize = sizeof(pixel_t);\n  const int max_pixel_value = (sizeof(pixel_t) == 1) ? 255 : (1 << bits_per_pixel) - 1;\n  auto factor = maskMode ? opacity_f / max_pixel_value : opacity_f;\n\n  for (int p = 0; p < 3; ++p) {\n    pixel_t* baseP = reinterpret_cast<pixel_t*>(base->GetPtrByIndex(p));\n    pixel_t* ovP = reinterpret_cast<pixel_t*>(overlay->GetPtrByIndex(p));\n    pixel_t* maskP = maskMode ? reinterpret_cast<pixel_t*>(mask->GetPtrByIndex(p)) : nullptr;\n    int basePitch = base->GetPitchByIndex(p) / pixelsize;\n    int overlayPitch = overlay->GetPitchByIndex(p) / pixelsize;\n    int maskPitch = maskMode ? (mask->GetPitchByIndex(p) / pixelsize) : 0;\n\n    for (int y = 0; y < h; ++y) {\n      for (int x = 0; x < w; ++x) {\n        int baseVal = baseP[x];\n        int ovVal = ovP[x];\n\n        const float new_mask = maskMode ? (float)reinterpret_cast<const pixel_t*>(maskP)[x] * factor : factor;\n        float result;\n\n        if constexpr (of_add)\n          result = baseVal + ovVal * new_mask;\n        else\n          result = baseVal - ovVal * new_mask;\n\n        baseP[x] = (pixel_t)(min(max((int)(result + 0.5f), 0), max_pixel_value));\n      }\n      baseP += basePitch;\n      ovP += overlayPitch;\n      if constexpr (maskMode) maskP += maskPitch;\n    }\n  }\n}\n\n\n// 32-bit float RGB add/subtract\ntemplate<bool maskMode, bool of_add>\nvoid OL_AddImage::BlendImageMask_RGB_float(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) {\n  int w = base->w();\n  int h = base->h();\n\n  auto factor = maskMode ? opacity_f / 1.0f : opacity_f; // for float, max_pixel_value is 1.0f for masks\n\n  for (int p = 0; p < 3; ++p) {\n    float* baseP = reinterpret_cast<float*>(base->GetPtrByIndex(p));\n    float* ovP = reinterpret_cast<float*>(overlay->GetPtrByIndex(p));\n    float* maskP = maskMode ? reinterpret_cast<float*>(mask->GetPtrByIndex(p)) : nullptr;\n    int basePitch = base->GetPitchByIndex(p) / sizeof(float);\n    int overlayPitch = overlay->GetPitchByIndex(p) / sizeof(float);\n    int maskPitch = maskMode ? (mask->GetPitchByIndex(p) / sizeof(float)) : 0;\n\n    for (int y = 0; y < h; ++y) {\n      for (int x = 0; x < w; ++x) {\n        float baseVal = baseP[x];\n        float ovVal = ovP[x];\n\n        const float new_mask = maskMode ? (float)reinterpret_cast<const float*>(maskP)[x] * factor : factor;\n        float result;\n\n        if constexpr (of_add)\n          result = baseVal + ovVal * new_mask;\n        else\n          result = baseVal - ovVal * new_mask;\n        baseP[x] = result; // no clamping for float\n      }\n      baseP += basePitch;\n      ovP += overlayPitch;\n      if constexpr (maskMode) maskP += maskPitch;\n    }\n  }\n}\n\n"
  },
  {
    "path": "avs_core/filters/overlay/OF_blend.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// Overlay (c) 2003, 2004 by Klaus Post\n\n#include \"overlayfunctions.h\"\n#include \"blend_common.h\"\n#ifdef INTEL_INTRINSICS\n#include \"intel/blend_common_sse.h\"\n#include \"intel/blend_common_avx2.h\"\n#endif\n#ifdef NEON_INTRINSICS\n#include \"aarch64/blend_common_neon.h\"\n#endif\n\n\n#include <stdint.h>\n\nvoid OL_BlendImage::DoBlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) {\n  if (bits_per_pixel == 8)\n    BlendImageMask<uint8_t>(base, overlay, mask);\n  else if (bits_per_pixel <= 16)\n    BlendImageMask<uint16_t>(base, overlay, mask);\n  else if (bits_per_pixel == 32)\n    BlendImageMask<float>(base, overlay, mask);\n}\n\nvoid OL_BlendImage::DoBlendImage(ImageOverlayInternal* base, ImageOverlayInternal* overlay) {\n  if (bits_per_pixel == 8)\n    BlendImage<uint8_t>(base, overlay);\n  else if (bits_per_pixel <= 16)\n    BlendImage<uint16_t>(base, overlay);\n  else if (bits_per_pixel == 32)\n    BlendImage<float>(base, overlay);\n}\n\n\ntemplate<typename pixel_t>\nvoid OL_BlendImage::BlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) {\n  int w = base->w();\n  int h = base->h();\n\n  const int pixelsize = sizeof(pixel_t);\n\n  int planeindex_from = 0;\n  int planeindex_to = 0;\n\n  if (of_mode == OF_Blend) {\n    planeindex_from = 0;\n    planeindex_to = greyscale ? 0 : 2;\n  }\n  else if (of_mode == OF_Luma) {\n    planeindex_from = 0;\n    planeindex_to = 0;\n  }\n  else if (of_mode == OF_Chroma) {\n    if (greyscale)\n      return;\n    planeindex_from = 1;\n    planeindex_to = 2;\n  }\n\n  overlay_blend_plane_masked_opacity_t* blend_fn = nullptr;\n\n  // 32 bit float inside\n  // independent from full/not full opacity\n#ifdef INTEL_INTRINSICS\n  if (pixelsize == 4 && (env->GetCPUFlags() & CPUF_AVX2)) {\n    blend_fn = overlay_blend_avx2_float<true>;\n  }\n  else if (pixelsize == 4 && (env->GetCPUFlags() & CPUF_SSE2)) {\n    blend_fn = overlay_blend_sse2_float<true>;\n  }\n  else if (env->GetCPUFlags() & CPUF_AVX2) {\n    switch (bits_per_pixel) {\n    case 8: blend_fn = overlay_blend_avx2_uint<true, uint8_t, true>; break;\n    case 10:\n    case 12:\n    case 14: blend_fn = overlay_blend_avx2_uint<true, uint16_t, true>; break;\n    case 16: blend_fn = overlay_blend_avx2_uint<true, uint16_t, false>; break;\n    }\n  }\n  else if (env->GetCPUFlags() & CPUF_SSE2) {\n    switch (bits_per_pixel) {\n    case 8: blend_fn = overlay_blend_sse2_uint<true, uint8_t, true>; break;\n    case 10:\n    case 12:\n    case 14: blend_fn = overlay_blend_sse2_uint<true, uint16_t, true>; break;\n    case 16: blend_fn = overlay_blend_sse2_uint<true, uint16_t, false>; break;\n    }\n  }\n  else\n#endif // INTEL_INTRINSICS\n#ifdef NEON_INTRINSICS\n    if (pixelsize == 4 && (env->GetCPUFlags() & CPUF_ARM_NEON)) {\n      blend_fn = overlay_blend_neon_float<true>;\n    }\n    else if (env->GetCPUFlags() & CPUF_ARM_NEON) {\n      switch (bits_per_pixel) {\n      case 8: blend_fn = overlay_blend_neon_uint<true, uint8_t>; break;\n      case 10:\n      case 12:\n      case 14:\n      case 16: blend_fn = overlay_blend_neon_uint<true, uint16_t>; break;\n      }\n    }\n    else\n#endif // NEON_INTRINSICS\n    {\n    // pure C\n    switch (bits_per_pixel) {\n    case 8: blend_fn = overlay_blend_c_uint<true, uint8_t>; break;\n    case 10:\n    case 12:\n    case 14:\n    case 16: blend_fn = overlay_blend_c_uint<true, uint16_t>; break;\n    case 32: blend_fn = overlay_blend_c_float<true>; break;\n    }\n  }\n\n  // end of new, float precision inside masked overlays\n\n  if (blend_fn == nullptr)\n    env->ThrowError(\"Blend: no valid internal function\");\n\n  for (int p = planeindex_from; p <= planeindex_to; p++) {\n    blend_fn(base->GetPtrByIndex(p), overlay->GetPtrByIndex(p), mask->GetPtrByIndex(p),\n      base->GetPitchByIndex(p), overlay->GetPitchByIndex(p), mask->GetPitchByIndex(p),\n      (w >> base->xSubSamplingShifts[p]), h >> base->ySubSamplingShifts[p], opacity, opacity_f,\n      bits_per_pixel);\n  }\n}\n\ntemplate<typename pixel_t>\nvoid OL_BlendImage::BlendImage(ImageOverlayInternal* base, ImageOverlayInternal* overlay) {\n  int w = base->w();\n  int h = base->h();\n\n  const int pixelsize = sizeof(pixel_t);\n\n  int planeindex_from = 0;\n  int planeindex_to = 0;\n\n  if (of_mode == OF_Blend) {\n    planeindex_from = 0;\n    planeindex_to = greyscale ? 0 : 2;\n  }\n  else if (of_mode == OF_Luma) {\n    planeindex_from = 0;\n    planeindex_to = 0;\n  }\n  else if (of_mode == OF_Chroma) {\n    if (greyscale)\n      return;\n    planeindex_from = 1;\n    planeindex_to = 2;\n  }\n\n  if (opacity == 256) {\n    for (int p = planeindex_from; p <= planeindex_to; p++) {\n      env->BitBlt(base->GetPtrByIndex(p), base->GetPitchByIndex(p), overlay->GetPtrByIndex(p), overlay->GetPitchByIndex(p), (w >> base->xSubSamplingShifts[p]) * pixelsize, h >> base->ySubSamplingShifts[p]);\n    }\n  }\n  else {\n    overlay_blend_plane_masked_opacity_t* blend_fn = nullptr;\n\n#ifdef INTEL_INTRINSICS\n  if (pixelsize == 4 && (env->GetCPUFlags() & CPUF_AVX2)) {\n    blend_fn = overlay_blend_avx2_float<false>;\n  }\n  else if (pixelsize == 4 && (env->GetCPUFlags() & CPUF_SSE2)) {\n    blend_fn = overlay_blend_sse2_float<false>;\n  }\n  else if (env->GetCPUFlags() & CPUF_AVX2) {\n    switch (bits_per_pixel) {\n    case 8: blend_fn = overlay_blend_avx2_uint<false, uint8_t, true>; break;\n    case 10:\n    case 12:\n    case 14: blend_fn = overlay_blend_avx2_uint<false, uint16_t, true>; break;\n    case 16: blend_fn = overlay_blend_avx2_uint<false, uint16_t, false>; break;\n    }\n  }\n  else if (env->GetCPUFlags() & CPUF_SSE2) {\n    switch (bits_per_pixel) {\n    case 8: blend_fn = overlay_blend_sse2_uint<false, uint8_t, true>; break;\n    case 10:\n    case 12:\n    case 14: blend_fn = overlay_blend_sse2_uint<false, uint16_t, true>; break;\n    case 16: blend_fn = overlay_blend_sse2_uint<false, uint16_t, false>; break;\n    }\n  }\n  else\n#endif // INTEL_INTRINSICS\n#ifdef NEON_INTRINSICS\n    if (pixelsize == 4 && (env->GetCPUFlags() & CPUF_ARM_NEON)) {\n      blend_fn = overlay_blend_neon_float<false>;\n    }\n    else if (env->GetCPUFlags() & CPUF_ARM_NEON) {\n      switch (bits_per_pixel) {\n      case 8: blend_fn = overlay_blend_neon_uint<false, uint8_t>; break;\n      case 10:\n      case 12:\n      case 14:\n      case 16: blend_fn = overlay_blend_neon_uint<false, uint16_t>; break;\n      }\n    }\n    else\n#endif // NEON_INTRINSICS\n    {\n    // pure C\n    switch (bits_per_pixel) {\n    case 8: blend_fn = overlay_blend_c_uint<false, uint8_t>; break;\n    case 10:\n    case 12:\n    case 14:\n    case 16: blend_fn = overlay_blend_c_uint<false, uint16_t>; break;\n    case 32: blend_fn = overlay_blend_c_float<false>; break;\n    }\n  }\n  // end of new, float precision inside masked overlays\n\n    if (blend_fn == nullptr)\n      env->ThrowError(\"Blend: no valid internal function\");\n\n    for (int p = planeindex_from; p <= planeindex_to; p++) {\n      // no mask ptr\n      blend_fn(\n        base->GetPtrByIndex(p), overlay->GetPtrByIndex(p), nullptr,\n        base->GetPitchByIndex(p), overlay->GetPitchByIndex(p), 0,\n        (w >> base->xSubSamplingShifts[p]), h >> base->ySubSamplingShifts[p], opacity, opacity_f,\n        bits_per_pixel);\n    }\n\n  }\n}\n"
  },
  {
    "path": "avs_core/filters/overlay/OF_darken.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// Overlay (c) 2003, 2004 by Klaus Post\n\n#include \"overlayfunctions.h\"\n\n#include \"blend_common.h\"\n#ifdef INTEL_INTRINSICS\n#include \"intel/blend_common_sse.h\"\n#endif\n\n#include <stdint.h>\n#include <type_traits>\n\nvoid OL_DarkenImage::DoBlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) {\n  if(of_mode == OF_Darken) {\n    if (bits_per_pixel == 8)\n      BlendImageMask<uint8_t, true, true>(base, overlay, mask);\n    else if(bits_per_pixel <= 16)\n      BlendImageMask<uint16_t, true, true>(base, overlay, mask);\n    //else if(bits_per_pixel == 32)\n    //  BlendImageMask<float>(base, overlay, mask);\n  }\n  else {\n    // OF_Lighten\n    if (bits_per_pixel == 8)\n      BlendImageMask<uint8_t, true, false>(base, overlay, mask);\n    else if(bits_per_pixel <= 16)\n      BlendImageMask<uint16_t, true, false>(base, overlay, mask);\n    //else if(bits_per_pixel == 32)\n    //  BlendImageMask<float>(base, overlay, mask);\n  }\n}\n\nvoid OL_DarkenImage::DoBlendImage(ImageOverlayInternal* base, ImageOverlayInternal* overlay) {\n  if(of_mode == OF_Darken) {\n    if (bits_per_pixel == 8)\n      BlendImageMask<uint8_t, false, true>(base, overlay, nullptr);\n    else if(bits_per_pixel <= 16)\n      BlendImageMask<uint16_t, false, true>(base, overlay, nullptr);\n    //else if(bits_per_pixel == 32)\n    //  BlendImageMask<float>(base, overlay, mask);\n  }\n  else {\n    // OF_Lighten\n    if (bits_per_pixel == 8)\n      BlendImageMask<uint8_t, false, false>(base, overlay, nullptr);\n    else if(bits_per_pixel <= 16)\n      BlendImageMask<uint16_t, false, false>(base, overlay, nullptr);\n    //else if(bits_per_pixel == 32)\n    //  BlendImageMask<float>(base, overlay, mask);\n  }\n}\n\n// float not supported yet\ntemplate<typename pixel_t, bool maskMode, bool of_darken>\nvoid OL_DarkenImage::BlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) {\n\n  pixel_t* baseY = reinterpret_cast<pixel_t *>(base->GetPtr(PLANAR_Y));\n  pixel_t* baseU = reinterpret_cast<pixel_t *>(base->GetPtr(PLANAR_U));\n  pixel_t* baseV = reinterpret_cast<pixel_t *>(base->GetPtr(PLANAR_V));\n\n  pixel_t* ovY = reinterpret_cast<pixel_t *>(overlay->GetPtr(PLANAR_Y));\n  pixel_t* ovU = reinterpret_cast<pixel_t *>(overlay->GetPtr(PLANAR_U));\n  pixel_t* ovV = reinterpret_cast<pixel_t *>(overlay->GetPtr(PLANAR_V));\n\n  pixel_t* maskY = maskMode ? reinterpret_cast<pixel_t *>(mask->GetPtr(PLANAR_Y)) : nullptr;\n  pixel_t* maskU = maskMode ? reinterpret_cast<pixel_t *>(mask->GetPtr(PLANAR_U)) : nullptr;\n  pixel_t* maskV = maskMode ? reinterpret_cast<pixel_t *>(mask->GetPtr(PLANAR_V)) : nullptr;\n\n  const int half_pixel_value = (sizeof(pixel_t) == 1) ? 128 : (1 << (bits_per_pixel - 1));\n  const int max_pixel_value = (sizeof(pixel_t) == 1) ? 255 : (1 << bits_per_pixel) - 1;\n  const int pixel_range = max_pixel_value + 1;\n  const int MASK_CORR_SHIFT = (sizeof(pixel_t) == 1) ? 8 : bits_per_pixel;\n  const int OPACITY_SHIFT  = 8; // opacity always max 0..256\n  const int basepitch = (base->pitch) / sizeof(pixel_t);\n  const int overlaypitch = (overlay->pitch) / sizeof(pixel_t);\n  const int maskpitch = maskMode ? (mask->pitch) / sizeof(pixel_t) : 0;\n\n  // avoid \"uint16*uint16 can't get into int32\" overflows\n  using result_t = typename std::conditional<sizeof(pixel_t) == 1, int, int64_t>::type;\n\n  int w = base->w();\n  int h = base->h();\n  if (opacity == 256) {\n    // full opacity - optimize\n    if constexpr (maskMode) {\n      // opacity == 256 && maskMode\n      for (int y = 0; y < h; y++) {\n        for (int x = 0; x < w; x++) {\n          bool cmp;\n          if constexpr (of_darken)\n            cmp = ovY[x] < baseY[x];\n          else\n            cmp = ovY[x] > baseY[x];\n          if (cmp) {\n            result_t maskYx = maskY[x];\n            result_t maskUx = maskU[x];\n            result_t maskVx = maskV[x];\n            baseY[x] = (pixel_t)((((pixel_range - maskYx)*baseY[x]) + (maskYx * ovY[x] + half_pixel_value)) >> MASK_CORR_SHIFT);\n            baseU[x] = (pixel_t)((((pixel_range - maskUx)*baseU[x]) + (maskUx * ovU[x] + half_pixel_value)) >> MASK_CORR_SHIFT);\n            baseV[x] = (pixel_t)((((pixel_range - maskVx)*baseV[x]) + (maskVx * ovV[x] + half_pixel_value)) >> MASK_CORR_SHIFT);\n          }\n        }\n        maskY += maskpitch;\n        maskU += maskpitch;\n        maskV += maskpitch;\n\n        baseY += basepitch;\n        baseU += basepitch;\n        baseV += basepitch;\n\n        ovY += overlaypitch;\n        ovU += overlaypitch;\n        ovV += overlaypitch;\n      }\n    } else {\n      // opacity == 256 && !maskMode\n      if constexpr (of_darken) {\n#ifdef INTEL_INTRINSICS\n        if (sizeof(pixel_t)==1 && (env->GetCPUFlags() & CPUF_SSE4_1)) {\n          overlay_darken_sse41((BYTE *)baseY, (BYTE *)baseU, (BYTE *)baseV, (BYTE *)ovY, (BYTE *)ovU, (BYTE *)ovV, basepitch, overlaypitch, w, h);\n        } else if (sizeof(pixel_t)==1 && (env->GetCPUFlags() & CPUF_SSE2)) {\n          overlay_darken_sse2((BYTE *)baseY, (BYTE *)baseU, (BYTE *)baseV, (BYTE *)ovY, (BYTE *)ovU, (BYTE *)ovV, basepitch, overlaypitch, w, h);\n        } else\n  #ifdef X86_32\n          if (sizeof(pixel_t)==1 && (env->GetCPUFlags() & CPUF_MMX)) {\n            overlay_darken_mmx((BYTE *)baseY, (BYTE *)baseU, (BYTE *)baseV, (BYTE *)ovY, (BYTE *)ovU, (BYTE *)ovV, basepitch, overlaypitch, w, h);\n          } else\n  #endif\n#endif\n          {\n\n            overlay_darken_c<pixel_t>((BYTE *)baseY, (BYTE *)baseU, (BYTE *)baseV, (BYTE *)ovY, (BYTE *)ovU, (BYTE *)ovV, basepitch, overlaypitch, w, h);\n          }\n      } else {\n        // OF_Lighten\n#ifdef INTEL_INTRINSICS\n        if (sizeof(pixel_t)==1 && (env->GetCPUFlags() & CPUF_SSE4_1)) {\n          overlay_lighten_sse41((BYTE *)baseY, (BYTE *)baseU, (BYTE *)baseV, (BYTE *)ovY, (BYTE *)ovU, (BYTE *)ovV, basepitch, overlaypitch, w, h);\n        } else if (sizeof(pixel_t)==1 && (env->GetCPUFlags() & CPUF_SSE2)) {\n          overlay_lighten_sse2((BYTE *)baseY, (BYTE *)baseU, (BYTE *)baseV, (BYTE *)ovY, (BYTE *)ovU, (BYTE *)ovV, basepitch, overlaypitch, w, h);\n        } else\n#ifdef X86_32\n          if (sizeof(pixel_t)==1 && (env->GetCPUFlags() & CPUF_MMX)) {\n            overlay_lighten_mmx((BYTE *)baseY, (BYTE *)baseU, (BYTE *)baseV, (BYTE *)ovY, (BYTE *)ovU, (BYTE *)ovV, basepitch, overlaypitch, w, h);\n          } else\n#endif\n#endif\n          {\n            overlay_lighten_c<pixel_t>((BYTE *)baseY, (BYTE *)baseU, (BYTE *)baseV, (BYTE *)ovY, (BYTE *)ovU, (BYTE *)ovV, basepitch, overlaypitch, w, h);\n          }\n      }\n\n    }\n  } else {\n    // opacity != 256 && maskMode\n    for (int y = 0; y < h; y++) {\n      for (int x = 0; x < w; x++) {\n        bool cmp;\n        if constexpr (of_darken)\n          cmp = ovY[x] < baseY[x];\n        else\n          cmp = ovY[x] > baseY[x];\n        if (cmp)  {\n          if constexpr (maskMode) {\n            result_t mY = (maskY[x] * opacity) >> OPACITY_SHIFT;\n            result_t mU = (maskU[x] * opacity) >> OPACITY_SHIFT;\n            result_t mV = (maskV[x] * opacity) >> OPACITY_SHIFT;\n            baseY[x] = (pixel_t)((((pixel_range - mY)*baseY[x]) + (mY*ovY[x] + half_pixel_value)) >> MASK_CORR_SHIFT);\n            baseU[x] = (pixel_t)((((pixel_range - mU)*baseU[x]) + (mU*ovU[x] + half_pixel_value)) >> MASK_CORR_SHIFT);\n            baseV[x] = (pixel_t)((((pixel_range - mV)*baseV[x]) + (mV*ovV[x] + half_pixel_value)) >> MASK_CORR_SHIFT);\n          }\n          else {\n            baseY[x] = (pixel_t)(((inv_opacity*baseY[x]) + (opacity*ovY[x] + 128)) >> OPACITY_SHIFT); // 128: half 256 opacity mul rounding\n            baseU[x] = (pixel_t)(((inv_opacity*baseU[x]) + (opacity*ovU[x] + 128)) >> OPACITY_SHIFT);\n            baseV[x] = (pixel_t)(((inv_opacity*baseV[x]) + (opacity*ovV[x] + 128)) >> OPACITY_SHIFT);\n          }\n        }\n      }\n      baseY += basepitch;\n      baseU += basepitch;\n      baseV += basepitch;\n\n      ovY += overlaypitch;\n      ovU += overlaypitch;\n      ovV += overlaypitch;\n\n      if constexpr (maskMode) {\n        maskY += maskpitch;\n        maskU += maskpitch;\n        maskV += maskpitch;\n      }\n    }\n  }\n}\n\n"
  },
  {
    "path": "avs_core/filters/overlay/OF_difference.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// Overlay (c) 2003, 2004 by Klaus Post\n\n#include \"overlayfunctions.h\"\n#include <cmath>\n#include <avs/minmax.h>\n\n#include <stdint.h>\n#include <type_traits>\n\nvoid OL_DifferenceImage::DoBlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) {\n  if (bits_per_pixel == 8)\n    BlendImageMask<uint8_t, true>(base, overlay, mask);\n  else if(bits_per_pixel <= 16)\n    BlendImageMask<uint16_t, true>(base, overlay, mask);\n  //else if(bits_per_pixel == 32)\n  //  BlendImageMask<float>(base, overlay, mask);\n}\n\nvoid OL_DifferenceImage::DoBlendImage(ImageOverlayInternal* base, ImageOverlayInternal* overlay) {\n  if (bits_per_pixel == 8)\n    BlendImageMask<uint8_t, false>(base, overlay, nullptr);\n  else if(bits_per_pixel <= 16)\n    BlendImageMask<uint16_t, false>(base, overlay, nullptr);\n  //else if(bits_per_pixel == 32)\n  //  BlendImage<float>(base, overlay);\n}\n\n// no float support\ntemplate<typename pixel_t, bool maskMode>\nvoid OL_DifferenceImage::BlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) {\n  pixel_t* baseY = reinterpret_cast<pixel_t *>(base->GetPtr(PLANAR_Y));\n  pixel_t* baseU = reinterpret_cast<pixel_t *>(base->GetPtr(PLANAR_U));\n  pixel_t* baseV = reinterpret_cast<pixel_t *>(base->GetPtr(PLANAR_V));\n\n  pixel_t* ovY = reinterpret_cast<pixel_t *>(overlay->GetPtr(PLANAR_Y));\n  pixel_t* ovU = reinterpret_cast<pixel_t *>(overlay->GetPtr(PLANAR_U));\n  pixel_t* ovV = reinterpret_cast<pixel_t *>(overlay->GetPtr(PLANAR_V));\n\n  pixel_t* maskY = maskMode ? reinterpret_cast<pixel_t *>(mask->GetPtr(PLANAR_Y)) : nullptr;\n  pixel_t* maskU = maskMode ? reinterpret_cast<pixel_t *>(mask->GetPtr(PLANAR_U)) : nullptr;\n  pixel_t* maskV = maskMode ? reinterpret_cast<pixel_t *>(mask->GetPtr(PLANAR_V)) : nullptr;\n\n  const int half_pixel_value = (sizeof(pixel_t) == 1) ? 128 : (1 << (bits_per_pixel - 1));\n  const int max_pixel_value = (sizeof(pixel_t) == 1) ? 255 : (1 << bits_per_pixel) - 1;\n  const int pixel_range = max_pixel_value + 1;\n  const int SHIFT  = (sizeof(pixel_t) == 1) ? 5 : 5 + (bits_per_pixel - 8);\n  const int MASK_CORR_SHIFT = (sizeof(pixel_t) == 1) ? 8 : bits_per_pixel;\n  const int OPACITY_SHIFT  = 8; // opacity always max 0..256\n  const int over32 = (1 << SHIFT); // 32\n  const int basepitch = (base->pitch) / sizeof(pixel_t);\n  const int overlaypitch = (overlay->pitch) / sizeof(pixel_t);\n  const int maskpitch = maskMode ? (mask->pitch) / sizeof(pixel_t) : 0;\n\n  // avoid \"uint16*uint16 can't get into int32\" overflows\n  using result_t = typename std::conditional<sizeof(pixel_t) == 1, int, int64_t>::type;\n\n  int w = base->w();\n  int h = base->h();\n\n  if (opacity == 256) {\n    for (int y = 0; y < h; y++) {\n      for (int x = 0; x < w; x++) {\n        int Y = abs((int)baseY[x] - (int)ovY[x]) + half_pixel_value;\n        int U = abs((int)baseU[x] - (int)ovU[x]) + half_pixel_value;\n        int V = abs((int)baseV[x] - (int)ovV[x]) + half_pixel_value;\n        if constexpr (maskMode) {\n          result_t mY = maskY[x];\n          result_t mU = maskU[x];\n          result_t mV = maskV[x];\n          Y = (int)(((Y*mY) + ((pixel_range - mY)*baseY[x])) >> MASK_CORR_SHIFT);\n          U = (int)(((U*mU) + ((pixel_range - mU)*baseU[x])) >> MASK_CORR_SHIFT);\n          V = (int)(((V*mV) + ((pixel_range - mV)*baseV[x])) >> MASK_CORR_SHIFT);\n        }\n        if (Y>max_pixel_value) {  // Apply overbrightness to UV\n          int multiplier = max(0,pixel_range + over32 -Y);  // 0 to 32\n          U = ((U*(         multiplier)) + (half_pixel_value*(over32-multiplier)))>>SHIFT;\n          V = ((V*(         multiplier)) + (half_pixel_value*(over32-multiplier)))>>SHIFT;\n          Y = max_pixel_value;\n        } else if (Y<0) {  // Apply superdark to UV\n          int multiplier = min(-Y,over32);  // 0 to 32\n          U = ((U*(over32 - multiplier)) + (half_pixel_value*(       multiplier)))>>SHIFT;\n          V = ((V*(over32 - multiplier)) + (half_pixel_value*(       multiplier)))>>SHIFT;\n          Y = 0;\n        }\n        baseY[x] = (pixel_t)Y;\n        baseU[x] = (pixel_t)clamp(U, 0, max_pixel_value);\n        baseV[x] = (pixel_t)clamp(V, 0, max_pixel_value);\n      }\n      baseY += basepitch;\n      baseU += basepitch;\n      baseV += basepitch;\n\n      ovY += overlaypitch;\n      ovU += overlaypitch;\n      ovV += overlaypitch;\n\n      if constexpr (maskMode) {\n        maskY += maskpitch;\n        maskU += maskpitch;\n        maskV += maskpitch;\n      }\n    } // for y\n  } else {\n    for (int y = 0; y < h; y++) {\n      for (int x = 0; x < w; x++) {\n        int Y = abs((int)baseY[x] - (int)ovY[x]) + half_pixel_value;\n        int U = abs((int)baseU[x] - (int)ovU[x]) + half_pixel_value;\n        int V = abs((int)baseV[x] - (int)ovV[x]) + half_pixel_value;\n        if constexpr (maskMode) {\n          result_t  mY = (maskY[x] * opacity) >> OPACITY_SHIFT;\n          result_t  mU = (maskU[x] * opacity) >> OPACITY_SHIFT;\n          result_t  mV = (maskV[x] * opacity) >> OPACITY_SHIFT;\n          Y = (int)(((Y*mY) + ((pixel_range - mY)*baseY[x])) >> MASK_CORR_SHIFT);\n          U = (int)(((U*mU) + ((pixel_range - mU)*baseU[x])) >> MASK_CORR_SHIFT);\n          V = (int)(((V*mV) + ((pixel_range - mV)*baseV[x])) >> MASK_CORR_SHIFT);\n        }\n        else {\n          Y = ((Y*opacity) + (inv_opacity*baseY[x])) >> OPACITY_SHIFT;\n          U = ((U*opacity) + (inv_opacity*baseU[x])) >> OPACITY_SHIFT;\n          V = ((V*opacity) + (inv_opacity*baseV[x])) >> OPACITY_SHIFT;\n        }\n        if (Y>max_pixel_value) {  // Apply overbrightness to UV\n          int multiplier = max(0,pixel_range + over32 -Y);  // 0 to 32\n          U = ((U*(         multiplier)) + (half_pixel_value*(over32-multiplier)))>>SHIFT;\n          V = ((V*(         multiplier)) + (half_pixel_value*(over32-multiplier)))>>SHIFT;\n          Y = max_pixel_value;\n        } else if (Y<0) {  // Apply superdark to UV\n          int multiplier = min(-Y,over32);  // 0 to 32\n          U = ((U*(over32 - multiplier)) + (half_pixel_value*(       multiplier)))>>SHIFT;\n          V = ((V*(over32 - multiplier)) + (half_pixel_value*(       multiplier)))>>SHIFT;\n          Y = 0;\n        }\n        baseY[x] = (pixel_t)Y;\n        baseU[x] = (pixel_t)clamp(U, 0, max_pixel_value);\n        baseV[x] = (pixel_t)clamp(V, 0, max_pixel_value);\n      }\n      baseY += basepitch;\n      baseU += basepitch;\n      baseV += basepitch;\n\n      ovY += overlaypitch;\n      ovU += overlaypitch;\n      ovV += overlaypitch;\n\n      if constexpr (maskMode) {\n        maskY += maskpitch;\n        maskU += maskpitch;\n        maskV += maskpitch;\n      }\n    } // for x\n  } // for y\n}\n\n"
  },
  {
    "path": "avs_core/filters/overlay/OF_exclusion.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// Overlay (c) 2003, 2004 by Klaus Post\n\n#include \"overlayfunctions.h\"\n#include <avs/minmax.h>\n\n#include <stdint.h>\n#include <type_traits>\n\nvoid OL_ExclusionImage::DoBlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) {\n  if (bits_per_pixel == 8)\n    BlendImageMask<uint8_t, true>(base, overlay, mask);\n  else if(bits_per_pixel <= 16)\n    BlendImageMask<uint16_t, true>(base, overlay, mask);\n  //else if(bits_per_pixel == 32)\n  //  BlendImageMask<float>(base, overlay, mask);\n}\n\nvoid OL_ExclusionImage::DoBlendImage(ImageOverlayInternal* base, ImageOverlayInternal* overlay) {\n  if (bits_per_pixel == 8)\n    BlendImageMask<uint8_t, false>(base, overlay, nullptr);\n  else if(bits_per_pixel <= 16)\n    BlendImageMask<uint16_t, false>(base, overlay, nullptr);\n  //else if(bits_per_pixel == 32)\n  //  BlendImage<float>(base, overlay);\n}\n\n\ntemplate<typename pixel_t, bool maskMode>\nvoid OL_ExclusionImage::BlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) {\n  pixel_t* baseY = reinterpret_cast<pixel_t *>(base->GetPtr(PLANAR_Y));\n  pixel_t* baseU = reinterpret_cast<pixel_t *>(base->GetPtr(PLANAR_U));\n  pixel_t* baseV = reinterpret_cast<pixel_t *>(base->GetPtr(PLANAR_V));\n\n  pixel_t* ovY = reinterpret_cast<pixel_t *>(overlay->GetPtr(PLANAR_Y));\n  pixel_t* ovU = reinterpret_cast<pixel_t *>(overlay->GetPtr(PLANAR_U));\n  pixel_t* ovV = reinterpret_cast<pixel_t *>(overlay->GetPtr(PLANAR_V));\n\n  pixel_t* maskY = maskMode ? reinterpret_cast<pixel_t *>(mask->GetPtr(PLANAR_Y)) : nullptr;\n  pixel_t* maskU = maskMode ? reinterpret_cast<pixel_t *>(mask->GetPtr(PLANAR_U)) : nullptr;\n  pixel_t* maskV = maskMode ? reinterpret_cast<pixel_t *>(mask->GetPtr(PLANAR_V)) : nullptr;\n\n  const int half_pixel_value = (sizeof(pixel_t) == 1) ? 128 : (1 << (bits_per_pixel - 1));\n  const int max_pixel_value = (sizeof(pixel_t) == 1) ? 255 : (1 << bits_per_pixel) - 1;\n  const int xor_mask = max_pixel_value;\n  const int pixel_range = max_pixel_value + 1;\n  const int SHIFT  = (sizeof(pixel_t) == 1) ? 5 : 5 + (bits_per_pixel - 8);\n  const int MASK_CORR_SHIFT = (sizeof(pixel_t) == 1) ? 8 : bits_per_pixel;\n  const int OPACITY_SHIFT  = 8; // opacity always max 0..256\n  const int over32 = (1 << SHIFT); // 32\n  const int basepitch = (base->pitch) / sizeof(pixel_t);\n  const int overlaypitch = (overlay->pitch) / sizeof(pixel_t);\n  const int maskpitch = maskMode ? (mask->pitch) / sizeof(pixel_t) : 0;\n\n  // avoid \"uint16*uint16 can't get into int32\" overflows\n  typedef typename std::conditional < sizeof(pixel_t) == 1, int, typename std::conditional < sizeof(pixel_t) == 2, int64_t, float>::type >::type result_t;\n\n  int w = base->w();\n  int h = base->h();\n\n  if (opacity == 256) {\n    for (int y = 0; y < h; y++) {\n      for (int x = 0; x < w; x++) {\n        result_t ovYx = ovY[x];\n        int Y = (int)(((baseY[x] ^ xor_mask)*ovYx + (ovYx ^ xor_mask)*baseY[x]) >> MASK_CORR_SHIFT);\n        int U = (int)(((baseU[x] ^ xor_mask)*ovYx + (ovYx ^ xor_mask)*baseU[x]) >> MASK_CORR_SHIFT);\n        int V = (int)(((baseV[x] ^ xor_mask)*ovYx + (ovYx ^ xor_mask)*baseV[x]) >> MASK_CORR_SHIFT);\n        if constexpr (maskMode) {\n          result_t mY = maskY[x];\n          result_t mU = maskU[x];\n          result_t mV = maskV[x];\n          Y = (int)(((Y*mY) + ((pixel_range - mY)*baseY[x])) >> MASK_CORR_SHIFT);\n          U = (int)(((U*mU) + ((pixel_range - mU)*baseU[x])) >> MASK_CORR_SHIFT);\n          V = (int)(((V*mV) + ((pixel_range - mV)*baseV[x])) >> MASK_CORR_SHIFT);\n        }\n        if (Y>max_pixel_value) {  // Apply overbrightness to UV\n          int multiplier = max(0,pixel_range + over32 -Y);  // 0 to 32\n          U = ((U*(         multiplier)) + (half_pixel_value*(over32-multiplier)))>>SHIFT;\n          V = ((V*(         multiplier)) + (half_pixel_value*(over32-multiplier)))>>SHIFT;\n          Y = max_pixel_value;\n        } else if (Y<0) {  // Apply superdark to UV\n          int multiplier = min(-Y,over32);  // 0 to 32\n          U = ((U*(over32 - multiplier)) + (half_pixel_value*(       multiplier)))>>SHIFT;\n          V = ((V*(over32 - multiplier)) + (half_pixel_value*(       multiplier)))>>SHIFT;\n          Y = 0;\n        }\n        baseY[x] = (pixel_t)Y;\n        baseU[x] = (pixel_t)clamp(U, 0, max_pixel_value);\n        baseV[x] = (pixel_t)clamp(V, 0, max_pixel_value);\n      }\n      baseY += basepitch;\n      baseU += basepitch;\n      baseV += basepitch;\n\n      ovY += overlaypitch;\n      ovU += overlaypitch;\n      ovV += overlaypitch;\n\n      if constexpr (maskMode) {\n        maskY += maskpitch;\n        maskU += maskpitch;\n        maskV += maskpitch;\n      }\n    } // for y\n  } else {\n    for (int y = 0; y < h; y++) {\n      for (int x = 0; x < w; x++) {\n        result_t ovYx = ovY[x];\n        int Y = (int)(((baseY[x] ^ xor_mask)*ovYx + (ovYx^xor_mask)*baseY[x]) >> MASK_CORR_SHIFT);\n        int U = (int)(((baseU[x] ^ xor_mask)*ovYx + (ovYx^xor_mask)*baseU[x]) >> MASK_CORR_SHIFT);\n        int V = (int)(((baseV[x] ^ xor_mask)*ovYx + (ovYx^xor_mask)*baseV[x]) >> MASK_CORR_SHIFT);\n        if constexpr (maskMode) {\n          result_t  mY = (maskY[x] * opacity) >> OPACITY_SHIFT;\n          result_t  mU = (maskU[x] * opacity) >> OPACITY_SHIFT;\n          result_t  mV = (maskV[x] * opacity) >> OPACITY_SHIFT;\n          Y = (int)(((Y*mY) + ((pixel_range - mY)*baseY[x])) >> MASK_CORR_SHIFT);\n          U = (int)(((U*mU) + ((pixel_range - mU)*baseU[x])) >> MASK_CORR_SHIFT);\n          V = (int)(((V*mV) + ((pixel_range - mV)*baseV[x])) >> MASK_CORR_SHIFT);\n        }\n        else {\n          Y = ((Y*opacity) + (inv_opacity*baseY[x])) >> OPACITY_SHIFT;\n          U = ((U*opacity) + (inv_opacity*baseU[x])) >> OPACITY_SHIFT;\n          V = ((V*opacity) + (inv_opacity*baseV[x])) >> OPACITY_SHIFT;\n        }\n        if (Y>max_pixel_value) {  // Apply overbrightness to UV\n          int multiplier = max(0,pixel_range + over32 -Y);  // 0 to 32\n          U = ((U*(         multiplier)) + (half_pixel_value*(over32-multiplier)))>>SHIFT;\n          V = ((V*(         multiplier)) + (half_pixel_value*(over32-multiplier)))>>SHIFT;\n          Y = max_pixel_value;\n        } else if (Y<0) {  // Apply superdark to UV\n          int multiplier = min(-Y,over32);  // 0 to 32\n          U = ((U*(over32 - multiplier)) + (half_pixel_value*(       multiplier)))>>SHIFT;\n          V = ((V*(over32 - multiplier)) + (half_pixel_value*(       multiplier)))>>SHIFT;\n          Y = 0;\n        }\n        baseY[x] = (pixel_t)Y;\n        baseU[x] = (pixel_t)clamp(U, 0, max_pixel_value);\n        baseV[x] = (pixel_t)clamp(V, 0, max_pixel_value);\n      }\n      baseY += basepitch;\n      baseU += basepitch;\n      baseV += basepitch;\n\n      ovY += overlaypitch;\n      ovU += overlaypitch;\n      ovV += overlaypitch;\n\n      if constexpr (maskMode) {\n        maskY += maskpitch;\n        maskU += maskpitch;\n        maskV += maskpitch;\n      }\n    } // for x\n  } // for y\n}\n\n"
  },
  {
    "path": "avs_core/filters/overlay/OF_multiply.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// Overlay (c) 2003, 2004 by Klaus Post\n\n#include \"overlayfunctions.h\"\n\n#include <stdint.h>\n#include <type_traits>\n#ifdef INTEL_INTRINSICS\n#include \"intel/OF_multiply_sse.h\"\n#include \"intel/OF_multiply_avx2.h\"\n#endif\nvoid OL_MultiplyImage::DoBlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) {\n  if (bits_per_pixel == 8)\n    BlendImageMask<uint8_t>(base, overlay, mask);\n  else if(bits_per_pixel <= 16)\n    BlendImageMask<uint16_t>(base, overlay, mask);\n  //else if(bits_per_pixel == 32)\n  //  BlendImageMask<float>(base, overlay, mask);\n\n}\n\nvoid OL_MultiplyImage::DoBlendImage(ImageOverlayInternal* base, ImageOverlayInternal* overlay) {\n  if (bits_per_pixel == 8)\n    BlendImage<uint8_t>(base, overlay);\n  else if(bits_per_pixel <= 16)\n    BlendImage<uint16_t>(base, overlay);\n  //else if(bits_per_pixel == 32)\n  //  BlendImage<float>(base, overlay);\n}\n\n// mode multiply: Darkens the image in proportion to overlay lightness.\n\ntemplate<typename pixel_t, bool opacity_is_full, bool has_mask>\nstatic void of_multiply_c(\n  int bits_per_pixel,\n  const float opacity_f,\n  const int opacity,\n  int width, int height,\n  const pixel_t* ovY,\n  int overlaypitch,\n  pixel_t* baseY, pixel_t* baseU, pixel_t* baseV,\n  int basepitch,\n  const pixel_t* maskY, const pixel_t* maskU, const pixel_t* maskV,\n  int maskpitch\n  )\n{\n  const int max_pixel_value = (sizeof(pixel_t) == 1) ? 255 : (1 << bits_per_pixel) - 1;\n  const float factor = 1.0f / max_pixel_value;\n  const int half_i = 1 << (bits_per_pixel - 1);\n  const float half_f = (float)half_i;\n\n  float factor_mul_opacity;\n  if constexpr (opacity_is_full)\n    factor_mul_opacity = factor * 1.0f;\n  else\n    factor_mul_opacity = factor * opacity_f;\n\n  // start processing\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < width; x++) {\n      int Y, U, V;\n\n      // generic, 8-16 bits\n      // This part re-appears in SSE code (non mod4 end-of-line fragment in C)\n      // Unlike the old integer version here is proper rounding\n      const float overlay_opacity_minus1 = ovY[x] * factor - 1.0f;\n      if constexpr (has_mask) {\n        float final_opacity;\n\n        final_opacity = maskY[x] * factor_mul_opacity;\n        auto Yfactor = 1.0f + overlay_opacity_minus1 * final_opacity;\n        Y = (int)(baseY[x] * Yfactor + 0.5f);\n\n        final_opacity = maskU[x] * factor_mul_opacity;\n        auto Ufactor = 1.0f + overlay_opacity_minus1 * final_opacity;\n        U = (int)(((float)baseU[x] - half_f) * Ufactor + half_f + 0.5f);\n\n        final_opacity = maskV[x] * factor_mul_opacity;\n        auto Vfactor = 1.0f + overlay_opacity_minus1 * final_opacity;\n        V = (int)(((float)baseV[x] - half_f) * Vfactor + half_f + 0.5f);\n      }\n      else {\n        const float common_factor = 1.0f + overlay_opacity_minus1 * opacity_f;\n\n        auto Yfactor = common_factor;\n        Y = (int)((float)baseY[x] * Yfactor + 0.5f);\n\n        auto Ufactor = common_factor;\n        U = (int)(((float)baseU[x] - half_f) * Ufactor + half_f + 0.5f);\n\n        auto Vfactor = common_factor;\n        V = (int)(((float)baseV[x] - half_f) * Vfactor + half_f + 0.5f);\n\n      }\n\n      baseU[x] = (pixel_t)U;\n      baseV[x] = (pixel_t)V;\n      baseY[x] = (pixel_t)Y;\n    }\n\n    if constexpr (has_mask) {\n      maskY += maskpitch;\n      maskU += maskpitch;\n      maskV += maskpitch;\n    }\n\n    baseY += basepitch;\n    baseU += basepitch;\n    baseV += basepitch;\n\n    ovY += overlaypitch;\n\n  }\n}\n\n// old, integer-inside C version.\n// compared to the float-inside version, here is no proper rounding\n// 8 bit processing is quicker though\ntemplate<typename pixel_t, bool opacity_is_full, bool has_mask>\nstatic void of_multiply_c_old(\n  int bits_per_pixel,\n  const float opacity_f,\n  const int opacity,\n  int width, int height,\n  const pixel_t* ovY,\n  int overlaypitch,\n  pixel_t* baseY, pixel_t* baseU, pixel_t* baseV,\n  int basepitch,\n  const pixel_t* maskY, const pixel_t* maskU, const pixel_t* maskV,\n  int maskpitch\n)\n{\n  const int max_pixel_value = (sizeof(pixel_t) == 1) ? 255 : (1 << bits_per_pixel) - 1;\n  const int chroma_half_corr = (sizeof(pixel_t) == 1) ? 128 : (1 << (bits_per_pixel - 1));\n  const int pixel_range = max_pixel_value + 1;\n  const int MASK_CORR_SHIFT = (sizeof(pixel_t) == 1) ? 8 : bits_per_pixel;\n  const int inv_opacity = 256 - opacity;\n\n  // start processing\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < width; x++) {\n      int Y, U, V;\n\n      // for 8 bit, which is a bit quicker with integer arithmetics\n      // avoid \"uint16*uint16 can't get into int32\" overflows\n      typedef typename std::conditional < sizeof(pixel_t) == 1, int, typename std::conditional < sizeof(pixel_t) == 2, int64_t, float>::type >::type result_t;\n\n      if constexpr (has_mask) {\n        result_t overlay_Y = ovY[x];\n\n        int final_opacity;\n        result_t inverse_final_opacity;\n\n        if constexpr (opacity_is_full)\n          final_opacity = maskY[x];\n        else\n          final_opacity = (maskY[x] * opacity) >> 8;\n        inverse_final_opacity = pixel_range - final_opacity;\n        Y = (int)((baseY[x] * (pixel_range * inverse_final_opacity + (overlay_Y * final_opacity))) >> (MASK_CORR_SHIFT * 2));\n\n        if constexpr (opacity_is_full)\n          final_opacity = maskU[x];\n        else\n          final_opacity = (maskU[x] * opacity) >> 8;\n        inverse_final_opacity = pixel_range - final_opacity;\n        U = (int)(((baseU[x] * inverse_final_opacity * pixel_range) + (final_opacity * (baseU[x] * overlay_Y + chroma_half_corr * (pixel_range - overlay_Y)))) >> (MASK_CORR_SHIFT * 2));\n\n        if constexpr (opacity_is_full)\n          final_opacity = maskV[x];\n        else\n          final_opacity = (maskV[x] * opacity) >> 8;\n        inverse_final_opacity = pixel_range - final_opacity;\n        V = (int)(((baseV[x] * inverse_final_opacity * pixel_range) + (final_opacity * (baseV[x] * overlay_Y + chroma_half_corr * (pixel_range - overlay_Y)))) >> (MASK_CORR_SHIFT * 2));\n      }\n      else {\n        // no mask clip\n        if constexpr (opacity_is_full) {\n          result_t ovYx = ovY[x];\n          Y = (int)((baseY[x] * ovYx) >> MASK_CORR_SHIFT);\n          U = (int)((baseU[x] * ovYx + chroma_half_corr * (pixel_range - ovYx)) >> MASK_CORR_SHIFT);\n          V = (int)((baseV[x] * ovYx + chroma_half_corr * (pixel_range - ovYx)) >> MASK_CORR_SHIFT);\n        }\n        else {\n          result_t ovYx = ovY[x];\n          result_t baseYx = baseY[x];\n          Y = (int)((baseYx * (pixel_range * inv_opacity + (ovYx * opacity))) >> (MASK_CORR_SHIFT + 8));\n          result_t baseUx = baseU[x];\n          U = (int)(((baseUx * inv_opacity * pixel_range) + (opacity * (baseUx * ovYx + chroma_half_corr * (pixel_range - ovYx)))) >> (MASK_CORR_SHIFT + 8));\n          result_t baseVx = baseV[x];\n          V = (int)(((baseVx * inv_opacity * pixel_range) + (opacity * (baseVx * ovYx + chroma_half_corr * (pixel_range - ovYx)))) >> (MASK_CORR_SHIFT + 8));\n        }\n      }\n\n      baseU[x] = (pixel_t)U;\n      baseV[x] = (pixel_t)V;\n      baseY[x] = (pixel_t)Y;\n    }\n\n    if constexpr (has_mask) {\n      maskY += maskpitch;\n      maskU += maskpitch;\n      maskV += maskpitch;\n    }\n\n    baseY += basepitch;\n    baseU += basepitch;\n    baseV += basepitch;\n\n    ovY += overlaypitch;\n\n  }\n}\n\n// mode multiply: Darkens the image in proportion to overlay lightness.\ntemplate<typename pixel_t>\nvoid OL_MultiplyImage::BlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) {\n  pixel_t* baseY = reinterpret_cast<pixel_t*>(base->GetPtr(PLANAR_Y));\n  pixel_t* baseU = reinterpret_cast<pixel_t*>(base->GetPtr(PLANAR_U));\n  pixel_t* baseV = reinterpret_cast<pixel_t*>(base->GetPtr(PLANAR_V));\n\n  pixel_t* ovY = reinterpret_cast<pixel_t*>(overlay->GetPtr(PLANAR_Y));\n\n  pixel_t* maskY = reinterpret_cast<pixel_t*>(mask->GetPtr(PLANAR_Y));\n  pixel_t* maskU = reinterpret_cast<pixel_t*>(mask->GetPtr(PLANAR_U));\n  pixel_t* maskV = reinterpret_cast<pixel_t*>(mask->GetPtr(PLANAR_V));\n\n  const int basepitch = (base->pitch) / sizeof(pixel_t);\n  const int overlaypitch = (overlay->pitch) / sizeof(pixel_t);\n  const int maskpitch = (mask->pitch) / sizeof(pixel_t);\n\n  int w = base->w();\n  int h = base->h();\n#ifdef INTEL_INTRINSICS\n  if (!!(env->GetCPUFlags() & CPUF_AVX2))\n  {\n    if (opacity == 256)\n      of_multiply_avx2<pixel_t, true, true>(bits_per_pixel, opacity_f, opacity, w, h, ovY, overlaypitch, baseY, baseU, baseV, basepitch, maskY, maskU, maskV, maskpitch);\n    else\n      of_multiply_avx2<pixel_t, false, true>(bits_per_pixel, opacity_f, opacity, w, h, ovY, overlaypitch, baseY, baseU, baseV, basepitch, maskY, maskU, maskV, maskpitch);\n  }\n  else if (!!(env->GetCPUFlags() & CPUF_SSE4_1))\n  {\n    if (opacity == 256)\n      of_multiply_sse41<pixel_t, true, true>(bits_per_pixel, opacity_f, opacity, w, h, ovY, overlaypitch, baseY, baseU, baseV, basepitch, maskY, maskU, maskV, maskpitch);\n    else\n      of_multiply_sse41<pixel_t, false, true>(bits_per_pixel, opacity_f, opacity, w, h, ovY, overlaypitch, baseY, baseU, baseV, basepitch, maskY, maskU, maskV, maskpitch);\n  }\n  else\n#endif\n  {\n    // old integer C code: 8 bit is quicker than float-based\n    if (sizeof(pixel_t) == 1) {\n      if (opacity == 256)\n        of_multiply_c_old<pixel_t, true, true>(bits_per_pixel, opacity_f, opacity, w, h, ovY, overlaypitch, baseY, baseU, baseV, basepitch, maskY, maskU, maskV, maskpitch);\n      else\n        of_multiply_c_old<pixel_t, false, true>(bits_per_pixel, opacity_f, opacity, w, h, ovY, overlaypitch, baseY, baseU, baseV, basepitch, maskY, maskU, maskV, maskpitch);\n    }\n    else {\n      if (opacity == 256)\n        of_multiply_c<pixel_t, true, true>(bits_per_pixel, opacity_f, opacity, w, h, ovY, overlaypitch, baseY, baseU, baseV, basepitch, maskY, maskU, maskV, maskpitch);\n      else\n        of_multiply_c<pixel_t, false, true>(bits_per_pixel, opacity_f, opacity, w, h, ovY, overlaypitch, baseY, baseU, baseV, basepitch, maskY, maskU, maskV, maskpitch);\n    }\n  }\n}\n\n// no mask involved\ntemplate<typename pixel_t>\nvoid OL_MultiplyImage::BlendImage(ImageOverlayInternal* base, ImageOverlayInternal* overlay) {\n  pixel_t* baseY = reinterpret_cast<pixel_t*>(base->GetPtr(PLANAR_Y));\n  pixel_t* baseU = reinterpret_cast<pixel_t*>(base->GetPtr(PLANAR_U));\n  pixel_t* baseV = reinterpret_cast<pixel_t*>(base->GetPtr(PLANAR_V));\n\n  pixel_t* ovY = reinterpret_cast<pixel_t*>(overlay->GetPtr(PLANAR_Y));\n\n  const int basepitch = (base->pitch) / sizeof(pixel_t);\n  const int overlaypitch = (overlay->pitch) / sizeof(pixel_t);\n\n  int w = base->w();\n  int h = base->h();\n#ifdef INTEL_INTRINSICS\n  if (!!(env->GetCPUFlags() & CPUF_AVX2))\n  {\n    if (opacity == 256)\n      of_multiply_avx2<pixel_t, true, false>(bits_per_pixel, opacity_f, opacity, w, h, ovY, overlaypitch, baseY, baseU, baseV, basepitch, nullptr, nullptr, nullptr, 0);\n    else\n      of_multiply_avx2<pixel_t, false, false>(bits_per_pixel, opacity_f, opacity, w, h, ovY, overlaypitch, baseY, baseU, baseV, basepitch, nullptr, nullptr, nullptr, 0);\n  }\n  else if (!!(env->GetCPUFlags() & CPUF_SSE4_1))\n  {\n    if (opacity == 256)\n      of_multiply_sse41<pixel_t, true, false>(bits_per_pixel, opacity_f, opacity, w, h, ovY, overlaypitch, baseY, baseU, baseV, basepitch, nullptr, nullptr, nullptr, 0);\n    else\n      of_multiply_sse41<pixel_t, false, false>(bits_per_pixel, opacity_f, opacity, w, h, ovY, overlaypitch, baseY, baseU, baseV, basepitch, nullptr, nullptr, nullptr, 0);\n  }\n  else\n#endif\n  {\n    if (sizeof(pixel_t) == 1) {\n      // old integer C code: 8 bit is quicker than float-based\n      if (opacity == 256)\n        of_multiply_c_old<pixel_t, true, false>(bits_per_pixel, opacity_f, opacity, w, h, ovY, overlaypitch, baseY, baseU, baseV, basepitch, nullptr, nullptr, nullptr, 0);\n      else\n        of_multiply_c_old<pixel_t, false, false>(bits_per_pixel, opacity_f, opacity, w, h, ovY, overlaypitch, baseY, baseU, baseV, basepitch, nullptr, nullptr, nullptr, 0);\n    }\n    else {\n      if (opacity == 256)\n        of_multiply_c<pixel_t, true, false>(bits_per_pixel, opacity_f, opacity, w, h, ovY, overlaypitch, baseY, baseU, baseV, basepitch, nullptr, nullptr, nullptr, 0);\n      else\n        of_multiply_c<pixel_t, false, false>(bits_per_pixel, opacity_f, opacity, w, h, ovY, overlaypitch, baseY, baseU, baseV, basepitch, nullptr, nullptr, nullptr, 0);\n    }\n\n  }\n}\n"
  },
  {
    "path": "avs_core/filters/overlay/OF_softhardlight.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// Overlay (c) 2003, 2004 by Klaus Post\n\n#include \"overlayfunctions.h\"\n\n#include <stdint.h>\n#include <type_traits>\n\nvoid OL_SoftLightImage::DoBlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) {\n  if(of_mode == OF_SoftLight) {\n    if (bits_per_pixel == 8)\n      BlendImageMask<uint8_t, true, false>(base, overlay, mask);\n    else if(bits_per_pixel <= 16)\n      BlendImageMask<uint16_t, true, false>(base, overlay, mask);\n    //else if(bits_per_pixel == 32)\n    //  BlendImageMask<float>(base, overlay, mask);\n  } else {\n    // OF_HardLight\n    if (bits_per_pixel == 8)\n      BlendImageMask<uint8_t, true, true>(base, overlay, mask);\n    else if(bits_per_pixel <= 16)\n      BlendImageMask<uint16_t, true, true>(base, overlay, mask);\n    //else if(bits_per_pixel == 32)\n    //  BlendImageMask<float>(base, overlay, mask);\n  }\n}\n\nvoid OL_SoftLightImage::DoBlendImage(ImageOverlayInternal* base, ImageOverlayInternal* overlay) {\n  if(of_mode == OF_SoftLight) {\n    if (bits_per_pixel == 8)\n      BlendImageMask<uint8_t, false, false>(base, overlay, nullptr);\n    else if(bits_per_pixel <= 16)\n      BlendImageMask<uint16_t, false, false>(base, overlay, nullptr);\n    //else if(bits_per_pixel == 32)\n    //  BlendImage<float>(base, overlay);\n  }\n  else {\n    // OF_HardLight\n    if (bits_per_pixel == 8)\n      BlendImageMask<uint8_t, false, true>(base, overlay, nullptr);\n    else if(bits_per_pixel <= 16)\n      BlendImageMask<uint16_t, false, true>(base, overlay, nullptr);\n    //else if(bits_per_pixel == 32)\n    //  BlendImageMask<float>(base, overlay, mask);\n  }\n}\n\ntemplate<typename pixel_t, bool maskMode, bool hardLight>\nvoid OL_SoftLightImage::BlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) {\n  pixel_t* baseY = reinterpret_cast<pixel_t *>(base->GetPtr(PLANAR_Y));\n  pixel_t* baseU = reinterpret_cast<pixel_t *>(base->GetPtr(PLANAR_U));\n  pixel_t* baseV = reinterpret_cast<pixel_t *>(base->GetPtr(PLANAR_V));\n\n  pixel_t* ovY = reinterpret_cast<pixel_t *>(overlay->GetPtr(PLANAR_Y));\n  pixel_t* ovU = reinterpret_cast<pixel_t *>(overlay->GetPtr(PLANAR_U));\n  pixel_t* ovV = reinterpret_cast<pixel_t *>(overlay->GetPtr(PLANAR_V));\n\n  pixel_t* maskY = maskMode ? reinterpret_cast<pixel_t *>(mask->GetPtr(PLANAR_Y)) : nullptr;\n  pixel_t* maskU = maskMode ? reinterpret_cast<pixel_t *>(mask->GetPtr(PLANAR_U)) : nullptr;\n  pixel_t* maskV = maskMode ? reinterpret_cast<pixel_t *>(mask->GetPtr(PLANAR_V)) : nullptr;\n\n  const int half_pixel_value = (sizeof(pixel_t) == 1) ? 128 : (1 << (bits_per_pixel - 1));\n  const int max_pixel_value = (sizeof(pixel_t) == 1) ? 255 : (1 << bits_per_pixel) - 1;\n  const int pixel_range = max_pixel_value + 1;\n  const int SHIFT  = (sizeof(pixel_t) == 1) ? 5 : 5 + (bits_per_pixel - 8);\n  const int MASK_CORR_SHIFT = (sizeof(pixel_t) == 1) ? 8 : bits_per_pixel;\n  const int OPACITY_SHIFT  = 8; // opacity always max 0..256\n  const int over32 = (1 << SHIFT); // 32\n  const int basepitch = (base->pitch) / sizeof(pixel_t);\n  const int overlaypitch = (overlay->pitch) / sizeof(pixel_t);\n  const int maskpitch = maskMode ? (mask->pitch) / sizeof(pixel_t) : 0;\n\n  // avoid \"uint16*uint16 can't get into int32\" overflows\n  typedef typename std::conditional < sizeof(pixel_t) == 1, int, typename std::conditional < sizeof(pixel_t) == 2, int64_t, float>::type >::type result_t;\n\n  int w = base->w();\n  int h = base->h();\n\n  if (opacity == 256) {\n    for (int y = 0; y < h; y++) {\n      for (int x = 0; x < w; x++) {\n        int Y;\n        if(hardLight)\n          Y = (int)baseY[x] + ((int)ovY[x])*2 - half_pixel_value*2;\n        else\n          Y = (int)baseY[x] + (int)ovY[x] - half_pixel_value;\n        int U = baseU[x] + ovU[x] - half_pixel_value;\n        int V = baseV[x] + ovV[x] - half_pixel_value;\n        if(maskMode) {\n          result_t mY = maskY[x];\n          result_t mU = maskU[x];\n          result_t mV = maskV[x];\n          Y = (int)(((Y*mY) + ((pixel_range - mY)*baseY[x])) >> MASK_CORR_SHIFT);\n          U = (int)(((U*mU) + ((pixel_range - mU)*baseU[x])) >> MASK_CORR_SHIFT);\n          V = (int)(((V*mV) + ((pixel_range - mV)*baseV[x])) >> MASK_CORR_SHIFT);\n        }\n        if (Y>max_pixel_value) {  // Apply overbrightness to UV\n          int multiplier = max(0,pixel_range + over32 -Y);  // 0 to 32\n          U = ((U*(         multiplier)) + (half_pixel_value*(over32-multiplier)))>>SHIFT;\n          V = ((V*(         multiplier)) + (half_pixel_value*(over32-multiplier)))>>SHIFT;\n          Y = max_pixel_value;\n        } else if (Y<0) {  // Apply superdark to UV\n          int multiplier = min(-Y,over32);  // 0 to 32\n          U = ((U*(over32 - multiplier)) + (half_pixel_value*(       multiplier)))>>SHIFT;\n          V = ((V*(over32 - multiplier)) + (half_pixel_value*(       multiplier)))>>SHIFT;\n          Y = 0;\n        }\n        baseY[x] = (pixel_t)Y;\n        baseU[x] = (pixel_t)clamp(U, 0, max_pixel_value);\n        baseV[x] = (pixel_t)clamp(V, 0, max_pixel_value);\n      }\n      baseY += basepitch;\n      baseU += basepitch;\n      baseV += basepitch;\n\n      ovY += overlaypitch;\n      ovU += overlaypitch;\n      ovV += overlaypitch;\n\n      if(maskMode) {\n        maskY += maskpitch;\n        maskU += maskpitch;\n        maskV += maskpitch;\n      }\n    } // for y\n  } else {\n    for (int y = 0; y < h; y++) {\n      for (int x = 0; x < w; x++) {\n        int Y;\n        if (hardLight)\n          Y = (int)baseY[x] + ((int)ovY[x])*2 - half_pixel_value*2;\n        else\n          Y = (int)baseY[x] + (int)ovY[x] - half_pixel_value;\n        int U = baseU[x] + ovU[x] - half_pixel_value;\n        int V = baseV[x] + ovV[x] - half_pixel_value;\n        if(maskMode) {\n          result_t  mY = (maskY[x] * opacity) >> OPACITY_SHIFT;\n          result_t  mU = (maskU[x] * opacity) >> OPACITY_SHIFT;\n          result_t  mV = (maskV[x] * opacity) >> OPACITY_SHIFT;\n          Y = (int)(((Y*mY) + ((pixel_range - mY)*baseY[x])) >> MASK_CORR_SHIFT);\n          U = (int)(((U*mU) + ((pixel_range - mU)*baseU[x])) >> MASK_CORR_SHIFT);\n          V = (int)(((V*mV) + ((pixel_range - mV)*baseV[x])) >> MASK_CORR_SHIFT);\n        }\n        else {\n          Y = ((Y*opacity) + (inv_opacity*baseY[x])) >> OPACITY_SHIFT;\n          U = ((U*opacity) + (inv_opacity*baseU[x])) >> OPACITY_SHIFT;\n          V = ((V*opacity) + (inv_opacity*baseV[x])) >> OPACITY_SHIFT;\n        }\n        if (Y>max_pixel_value) {  // Apply overbrightness to UV\n          int multiplier = max(0,pixel_range + over32 -Y);  // 0 to 32\n          U = ((U*(         multiplier)) + (half_pixel_value*(over32-multiplier)))>>SHIFT;\n          V = ((V*(         multiplier)) + (half_pixel_value*(over32-multiplier)))>>SHIFT;\n          Y = max_pixel_value;\n        } else if (Y<0) {  // Apply superdark to UV\n          int multiplier = min(-Y,over32);  // 0 to 32\n          U = ((U*(over32 - multiplier)) + (half_pixel_value*(       multiplier)))>>SHIFT;\n          V = ((V*(over32 - multiplier)) + (half_pixel_value*(       multiplier)))>>SHIFT;\n          Y = 0;\n        }\n        baseY[x] = (pixel_t)Y;\n        baseU[x] = (pixel_t)clamp(U, 0, max_pixel_value);\n        baseV[x] = (pixel_t)clamp(V, 0, max_pixel_value);\n      }\n      baseY += basepitch;\n      baseU += basepitch;\n      baseV += basepitch;\n\n      ovY += overlaypitch;\n      ovU += overlaypitch;\n      ovV += overlaypitch;\n\n      if(maskMode) {\n        maskY += maskpitch;\n        maskU += maskpitch;\n        maskV += maskpitch;\n      }\n    } // for x\n  } // for y\n}\n\n"
  },
  {
    "path": "avs_core/filters/overlay/aarch64/blend_common_neon.cpp",
    "content": "// AviSynth+.  Copyright 2026- AviSynth+ Project\n// https://avs-plus.net\n// http://avisynth.nl\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include <avisynth.h>\n#include \"../blend_common.h\"\n#include \"blend_common_neon.h\"\n#include <arm_neon.h>\n#include <cstdint>\n\n/********************************\n ********* Blend Opaque *********\n ** Use for Lighten and Darken **\n ********************************/\n\n// avs_core/filters/overlay/aarch64/blend_common_neon.cpp\n\ntemplate<typename pixel_t>\nstatic AVS_FORCEINLINE void Eightpixels_to_Eightfloats_neon(const pixel_t* src, float32x4_t& src_lo, float32x4_t& src_hi) {\n  if constexpr (sizeof(pixel_t) == 1) {\n    // Load 8 bytes, widen to 8x16, then to 8x32, then to float\n    uint8x8_t v = vld1_u8(reinterpret_cast<const uint8_t*>(src));\n    uint16x8_t v16 = vmovl_u8(v);\n    uint32x4_t v32_lo = vmovl_u16(vget_low_u16(v16));\n    uint32x4_t v32_hi = vmovl_u16(vget_high_u16(v16));\n    src_lo = vcvtq_f32_u32(v32_lo);\n    src_hi = vcvtq_f32_u32(v32_hi);\n  } else {\n    // 16-bit: load 8x16, widen to 8x32, then to float\n    uint16x8_t v16 = vld1q_u16(reinterpret_cast<const uint16_t*>(src));\n    uint32x4_t v32_lo = vmovl_u16(vget_low_u16(v16));\n    uint32x4_t v32_hi = vmovl_u16(vget_high_u16(v16));\n    src_lo = vcvtq_f32_u32(v32_lo);\n    src_hi = vcvtq_f32_u32(v32_hi);\n  }\n}\n\ntemplate<typename pixel_t>\nstatic AVS_FORCEINLINE void Store_Eightpixels_neon(pixel_t* dst, float32x4_t what_lo, float32x4_t what_hi, const float32x4_t rounder) {\n  // Add rounder and convert to int32\n  what_lo = vaddq_f32(what_lo, rounder);\n  what_hi = vaddq_f32(what_hi, rounder);\n  int32x4_t si32_lo = vcvtq_s32_f32(what_lo);\n  int32x4_t si32_hi = vcvtq_s32_f32(what_hi);\n\n  if constexpr (sizeof(pixel_t) == 1) {\n    // Clamp to [0,255], narrow to 16, then to 8, and store 8 bytes\n    uint16x4_t u16_lo = vqmovun_s32(si32_lo);\n    uint16x4_t u16_hi = vqmovun_s32(si32_hi);\n    uint8x8_t u8 = vqmovn_u16(vcombine_u16(u16_lo, u16_hi));\n    vst1_u8(reinterpret_cast<uint8_t*>(dst), u8);\n  } else {\n    // Clamp to [0,65535], narrow to 16, and store 8x16\n    uint16x4_t u16_lo = vqmovun_s32(si32_lo);\n    uint16x4_t u16_hi = vqmovun_s32(si32_hi);\n    uint16x8_t u16 = vcombine_u16(u16_lo, u16_hi);\n    vst1q_u16(reinterpret_cast<uint16_t*>(dst), u16);\n  }\n}\n\nstatic AVS_FORCEINLINE float32x4_t overlay_blend_neon_core(const float32x4_t& p1_f, const float32x4_t& p2_f, const float32x4_t& factor) {\n  // p1 + (p2 - p1) * factor\n  return vmlaq_f32(p1_f, vsubq_f32(p2_f, p1_f), factor);\n}\n\ntemplate<bool has_mask, typename pixel_t>\nvoid overlay_blend_neon_uint_slow(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch,\n  const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel)\n{\n  const float32x4_t rounder = vdupq_n_f32(0.5f);\n  const int max_pixel_value = (1 << bits_per_pixel) - 1;\n  const float factor = has_mask ? (opacity_f / max_pixel_value) : opacity_f;\n  const float32x4_t factor_v = vdupq_n_f32(factor);\n\n  const int realwidth = width * sizeof(pixel_t);\n  constexpr int bytes_per_cycle = 8 * sizeof(pixel_t);\n  int wMod8 = (realwidth / bytes_per_cycle) * bytes_per_cycle;\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wMod8; x += bytes_per_cycle) {\n      float32x4_t unpacked_p1_lo, unpacked_p1_hi;\n      float32x4_t unpacked_p2_lo, unpacked_p2_hi;\n      Eightpixels_to_Eightfloats_neon<pixel_t>((const pixel_t*)(p1 + x), unpacked_p1_lo, unpacked_p1_hi);\n      Eightpixels_to_Eightfloats_neon<pixel_t>((const pixel_t*)(p2 + x), unpacked_p2_lo, unpacked_p2_hi);\n\n      float32x4_t result_lo, result_hi;\n      if constexpr (has_mask) {\n        float32x4_t unpacked_mask_lo, unpacked_mask_hi;\n        Eightpixels_to_Eightfloats_neon<pixel_t>((const pixel_t*)(mask + x), unpacked_mask_lo, unpacked_mask_hi);\n        unpacked_mask_lo = vmulq_f32(unpacked_mask_lo, factor_v);\n        unpacked_mask_hi = vmulq_f32(unpacked_mask_hi, factor_v);\n        result_lo = overlay_blend_neon_core(unpacked_p1_lo, unpacked_p2_lo, unpacked_mask_lo);\n        result_hi = overlay_blend_neon_core(unpacked_p1_hi, unpacked_p2_hi, unpacked_mask_hi);\n      } else {\n        result_lo = overlay_blend_neon_core(unpacked_p1_lo, unpacked_p2_lo, factor_v);\n        result_hi = overlay_blend_neon_core(unpacked_p1_hi, unpacked_p2_hi, factor_v);\n      }\n\n      Store_Eightpixels_neon<pixel_t>((pixel_t*)(p1 + x), result_lo, result_hi, rounder);\n    }\n\n    // Leftover value\n    for (int x = wMod8 / sizeof(pixel_t); x < width; x++) {\n      const float new_factor = has_mask ? static_cast<float>(reinterpret_cast<const pixel_t*>(mask)[x]) * factor : factor;\n      auto result = overlay_blend_c_core_simple(reinterpret_cast<pixel_t*>(p1)[x], reinterpret_cast<const pixel_t*>(p2)[x], new_factor);\n      reinterpret_cast<pixel_t*>(p1)[x] = (pixel_t)(result + 0.5f);\n    }\n\n    p1 += p1_pitch;\n    p2 += p2_pitch;\n    if constexpr(has_mask)\n      mask += mask_pitch;\n  }\n}\n\n// Process_SixteenPixels_neon:\n// To the greatest surprise, gcc 14 optimized the original (non-mask) C code so perfectly, that it took\n// two days of refining to achieve their speed using these hand-crafted intrinsics :)\n// Still, I leave this here, since it can work quickly in a debug build as well, and quicker than C from LLVM 19.\n\ntemplate<bool has_mask, typename pixel_t>\nstatic AVS_FORCEINLINE void Process_SixteenPixels_neon(\n  BYTE* p1_ptr, const BYTE* p2_ptr, const BYTE* mask_ptr, const float32x4_t factor_v, const float32x4_t rounder, const int offset)\n{\n  // The core blending function (p1 + (p2 - p1) * factor)\n  auto overlay_blend_neon_core = [](const float32x4_t& p1_f, const float32x4_t& delta_f, const float32x4_t& factor) -> float32x4_t {\n    // 1. Calculate the blend: p1_f + (delta_f * factor) (where delta_f = p2_f - p1_f)\n    return vfmaq_f32(p1_f, delta_f, factor); // A + B * C\n    };\n\n  // --- CASE 1: 8-bit Pixels (uint8_t) ---\n  if constexpr (sizeof(pixel_t) == 1) {\n    // Pointers\n    const uint8_t* src1 = reinterpret_cast<const uint8_t*>(p1_ptr + offset);\n    const uint8_t* src2 = reinterpret_cast<const uint8_t*>(p2_ptr + offset);\n\n    // 1. Load 16 bytes (128-bit)\n    uint8x16_t q_p1 = vld1q_u8(src1);\n    uint8x16_t q_p2 = vld1q_u8(src2);\n\n    // 2. Calc Delta and Widen P1 (Keep everything in 128-bit Q regs)\n    // Use _high intrinsics to generate 'usubl2' and 'uxtl2' instructions directly\n\n    // Low 8 pixels\n    // blending is p1 + (p2-p1)*f. We want p2-p1.\n    int16x8_t delta_16_lo = vreinterpretq_s16_u16(vsubl_u8(vget_low_u8(q_p2), vget_low_u8(q_p1)));\n\n    // High 8 pixels (Direct Hardware Instruction: usubl2)\n    int16x8_t delta_16_hi = vreinterpretq_s16_u16(vsubl_high_u8(q_p2, q_p1));\n\n    // Widen P1, cast to signed\n    int16x8_t p1_16_lo = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(q_p1)));\n    int16x8_t p1_16_hi = vreinterpretq_s16_u16(vmovl_high_u8(q_p1));\n\n    float32x4_t res0, res1, res2, res3;\n\n    if constexpr(has_mask) {\n      // const float new_factor = has_mask ? static_cast<float>(reinterpret_cast<const pixel_t*>(mask)[x]) * factor : factor;\n      // trouble: factor is fixed global here, mask is individual per pixel\n      // Since mask byte is in [0,255], the original factor [0..1] was already scaled down by 255 (8 bit max_pixel_value)\n      // So we don't have to take care here of max_pixel_value again.\n      // Is it optimal to calculate the multiplied factor_v independently?\n      // each 4 pixels must converted to 32 bit (uint8 -> signed 16 -> signed 32 -> float, like p1)\n\n      // Next calculation needs to be changed accordingly, take care of minimal lo-hi loads,\n      // stay in 128-bit pipeline as long as we can, multiply factor_v's with actual mask values\n\n      const uint8_t* src_mask = reinterpret_cast<const uint8_t*>(mask_ptr + offset);\n\n      // 1. Load 16 mask bytes\n      uint8x16_t q_mask = vld1q_u8(src_mask);\n\n      // 2. Widen 8-bit mask to 16-bit (low/high 8 pixels)\n      // and cast to signed to spare instructions on 32 bit widening\n      int16x8_t mask_16_lo = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(q_mask)));\n      int16x8_t mask_16_hi = vreinterpretq_s16_u16(vmovl_high_u8(q_mask));\n\n      // 3. Widen 16-bit mask to 32-bit (4 blocks of 4 pixels) and convert to float\n      // Stay in Signed domain, uint8_t fits into int16_t without issues\n      // Block 0 (Pixels 0-3) - new_factor0 = (float)mask[0-3] * factor_v\n      float32x4_t new_factor0 = vcvtq_f32_s32(vmovl_s16(vget_low_s16(mask_16_lo)));\n\n      // Block 1 (Pixels 4-7)\n      float32x4_t new_factor1 = vcvtq_f32_s32(vmovl_high_s16(mask_16_lo));\n\n      // Block 2 (Pixels 8-11)\n      float32x4_t new_factor2 = vcvtq_f32_s32(vmovl_s16(vget_low_s16(mask_16_hi)));\n\n      // Block 3 (Pixels 12-15)\n      float32x4_t new_factor3 = vcvtq_f32_s32(vmovl_high_s16(mask_16_hi));\n\n      // 4. Multiply mask float vectors by the constant global factor_v\n      new_factor0 = vmulq_f32(new_factor0, factor_v);\n      new_factor1 = vmulq_f32(new_factor1, factor_v);\n      new_factor2 = vmulq_f32(new_factor2, factor_v);\n      new_factor3 = vmulq_f32(new_factor3, factor_v);\n\n      // 5. Blend using the new per-pixel factors\n      // Block 0 (Pixels 0-3)\n      res0 = overlay_blend_neon_core(\n        vcvtq_f32_s32(vmovl_s16(vget_low_s16(p1_16_lo))),\n        vcvtq_f32_s32(vmovl_s16(vget_low_s16(delta_16_lo))),\n        new_factor0); // *** Use new_factor0 ***\n\n      // Block 1 (Pixels 4-7)\n      res1 = overlay_blend_neon_core(\n        vcvtq_f32_s32(vmovl_high_s16(p1_16_lo)),\n        vcvtq_f32_s32(vmovl_high_s16(delta_16_lo)),\n        new_factor1); // *** Use new_factor1 ***\n\n      // Block 2 (Pixels 8-11)\n      res2 = overlay_blend_neon_core(\n        vcvtq_f32_s32(vmovl_s16(vget_low_s16(p1_16_hi))),\n        vcvtq_f32_s32(vmovl_s16(vget_low_s16(delta_16_hi))),\n        new_factor2); // *** Use new_factor2 ***\n\n      // Block 3 (Pixels 12-15)\n      res3 = overlay_blend_neon_core(\n        vcvtq_f32_s32(vmovl_high_s16(p1_16_hi)),\n        vcvtq_f32_s32(vmovl_high_s16(delta_16_hi)),\n        new_factor3); // *** Use new_factor3 ***\n\n    }\n    else {\n      // Keep highly optimized non-mask path\n\n      // 3. Convert to Float and Blend (4 blocks of 4 pixels)\n      // We treat the 16-bit vectors as 32-bit vectors during conversion to save moves\n\n      // Block 0 (Pixels 0-3)\n      res0 = overlay_blend_neon_core(\n        vcvtq_f32_s32(vmovl_s16(vget_low_s16(p1_16_lo))),\n        vcvtq_f32_s32(vmovl_s16(vget_low_s16(delta_16_lo))),\n        factor_v);\n\n      // Block 1 (Pixels 4-7) - use _high to avoid 'dup'\n      res1 = overlay_blend_neon_core(\n        vcvtq_f32_s32(vmovl_high_s16(p1_16_lo)),\n        vcvtq_f32_s32(vmovl_high_s16(delta_16_lo)),\n        factor_v);\n\n      // Block 2 (Pixels 8-11)\n      res2 = overlay_blend_neon_core(\n        vcvtq_f32_s32(vmovl_s16(vget_low_s16(p1_16_hi))),\n        vcvtq_f32_s32(vmovl_s16(vget_low_s16(delta_16_hi))),\n        factor_v);\n\n      // Block 3 (Pixels 12-15) - use _high\n      res3 = overlay_blend_neon_core(\n        vcvtq_f32_s32(vmovl_high_s16(p1_16_hi)),\n        vcvtq_f32_s32(vmovl_high_s16(delta_16_hi)),\n        factor_v);\n    }\n\n    // 4. Rounding\n    res0 = vaddq_f32(res0, rounder);\n    res1 = vaddq_f32(res1, rounder);\n    res2 = vaddq_f32(res2, rounder);\n    res3 = vaddq_f32(res3, rounder);\n\n    // 5. Convert to Int32\n    int32x4_t s32_0 = vcvtq_s32_f32(res0);\n    int32x4_t s32_1 = vcvtq_s32_f32(res1);\n    int32x4_t s32_2 = vcvtq_s32_f32(res2);\n    int32x4_t s32_3 = vcvtq_s32_f32(res3);\n\n    // 6. FAST NARROWING (The \"Compiler Trick\")\n    // Instead of vmovn (which goes 128->64 bit), we use vuzp1q (Unzip).\n    // This packs the low 16-bits of every 32-bit element from two vectors into one 128-bit vector.\n    // It stays in the 128-bit pipeline.\n\n    // Narrow 32-bit -> 16-bit\n    // Takes Pixels 0-3 (s32_0) and Pixels 4-7 (s32_1) -> Pixels 0-7 (u16_lo)\n    int16x8_t u16_lo = vuzp1q_s16(vreinterpretq_s16_s32(s32_0), vreinterpretq_s16_s32(s32_1));\n\n    // Takes Pixels 8-11 (s32_2) and Pixels 12-15 (s32_3) -> Pixels 8-15 (u16_hi)\n    int16x8_t u16_hi = vuzp1q_s16(vreinterpretq_s16_s32(s32_2), vreinterpretq_s16_s32(s32_3));\n\n    // Narrow 16-bit -> 8-bit\n    // Takes Pixels 0-7 (u16_lo) and Pixels 8-15 (u16_hi) -> Pixels 0-15 (result)\n    // Note: We cast to s8 to perform the unzip on bytes\n    uint8x16_t result = vreinterpretq_u8_s8(\n      vuzp1q_s8(vreinterpretq_s8_s16(u16_lo), vreinterpretq_s8_s16(u16_hi))\n    );\n\n    // 7. Store\n    vst1q_u8(reinterpret_cast<uint8_t*>(p1_ptr + offset), result);\n  }\n  // --- CASE 2: 16-bit Pixels (uint16_t) ---\n  else if constexpr (sizeof(pixel_t) == 2) {\n    const uint16_t* src1 = reinterpret_cast<const uint16_t*>(p1_ptr + offset);\n    const uint16_t* src2 = reinterpret_cast<const uint16_t*>(p2_ptr + offset);\n\n    // 1. Bulk load + delta (like 8-bit success)\n    uint16x8_t v_p1 = vld1q_u16(src1);\n    uint16x8_t v_p2 = vld1q_u16(src2);\n\n    // 2. Bulk signed deltas (p2-p1) - vsubl_u16 → sxtl\n    int32x4_t delta_lo = vreinterpretq_s32_u32(vsubl_u16(vget_low_u16(v_p2), vget_low_u16(v_p1)));\n    int32x4_t delta_hi = vreinterpretq_s32_u32(vsubl_high_u16(v_p2, v_p1));  // Direct USUBL2\n\n    // 3. because we can have full 16 bit, we use unsigned 16 bit before 32 bit widening\n    int32x4_t p1_s_lo = vreinterpretq_s32_u32(vmovl_u16(vget_low_u16(v_p1)));\n    int32x4_t p1_s_hi = vreinterpretq_s32_u32(vmovl_high_u16(v_p1));\n\n    // 4. Single scvtf path (matches 8-bit victory)\n    float32x4_t p1_f_lo = vcvtq_f32_s32(p1_s_lo);\n    float32x4_t delta_f_lo = vcvtq_f32_s32(delta_lo);\n    float32x4_t p1_f_hi = vcvtq_f32_s32(p1_s_hi);\n    float32x4_t delta_f_hi = vcvtq_f32_s32(delta_hi);\n\n    float32x4_t res_lo, res_hi;\n\n    if constexpr (has_mask) {\n      const uint16_t* src_mask = reinterpret_cast<const uint16_t*>(mask_ptr + offset);\n      // const float new_factor = has_mask ? static_cast<float>(reinterpret_cast<const pixel_t*>(mask)[x]) * factor : factor;\n      // trouble: factor is fixed global here, mask is individual per pixel\n      // Since mask byte is in [0,(max_pixel_value-1)], the original factor [0..1] was already scaled down by (2^N - 1) 1023,4095,16383,65535 (10-16 bit max_pixel_value)\n      // So we don't have to take care here of max_pixel_value again.\n      // Is it optimal to calculate the multiplied factor_v independently?\n      // each 4 pixels must converted to 32 bit (uint16 -> signed 32 -> float, like p1)\n\n      // Next calculation needs to be changed accordingly, take care of minimal lo-hi loads,\n      // stay in 128-bit pipeline as long as we can, multiply factor_v's with actual mask values\n\n      // 1. Load 16 mask bytes\n      uint16x8_t v_mask = vld1q_u16(src_mask);\n\n      // 2. because we can have full 16 bit, we use unsigned 16 bit before 32 bit widening\n      int32x4_t mask_16_lo = vreinterpretq_s32_u32(vmovl_u16(vget_low_u16(v_mask))); // LSL, SXT\n      int32x4_t mask_16_hi = vreinterpretq_s32_u32(vmovl_high_u16(v_mask));\n\n      // 3. Widen 16-bit mask to 32-bit (4 blocks of 4 pixels) and convert to float\n      // Unlike at 8 bit, we cannot stay in Signed domain\n\n      // 4. Convert 32-bit mask to float\n      float32x4_t mask_f_lo = vcvtq_f32_s32(mask_16_lo);\n      float32x4_t mask_f_hi = vcvtq_f32_s32(mask_16_hi);\n\n      // 4. Multiply mask float vectors by the constant global factor_v\n      float32x4_t new_factor_lo = vmulq_f32(mask_f_lo, factor_v);\n      float32x4_t new_factor_hi = vmulq_f32(mask_f_hi, factor_v);\n\n      // 5. FMA + round\n      // 5. FMA using the new per-pixel factors\n      res_lo = vfmaq_f32(p1_f_lo, delta_f_lo, new_factor_lo); // *** Use new_factor_lo ***\n      res_hi = vfmaq_f32(p1_f_hi, delta_f_hi, new_factor_hi); // *** Use new_factor_hi ***\n\n    }\n    else {\n      // Keep highly optimized non-mask path\n\n    // 5. FMA + round\n      res_lo = vfmaq_f32(p1_f_lo, delta_f_lo, factor_v);\n      res_hi = vfmaq_f32(p1_f_hi, delta_f_hi, factor_v);\n    }\n\n    // Rounding +0.5f\n    res_lo = vaddq_f32(res_lo, rounder);\n    res_hi = vaddq_f32(res_hi, rounder);\n\n    // 6. FAST NON-SAT NARROW (like 8-bit uzp1 magic)\n    // With factor in [0,1], and p1,p2 in [0,65535], rounder 0.5f, the truncated result is also in [0,65535].\n    int32x4_t i32_lo = vcvtq_s32_f32(res_lo);\n    int32x4_t i32_hi = vcvtq_s32_f32(res_hi);\n\n    // Direct narrow (no vqmovun overhead)\n    int16x4_t h16_lo = vmovn_s32(i32_lo);      // MOVN, 1 cycle\n    int16x4_t h16_hi = vmovn_s32(i32_hi);\n    uint16x8_t result = vreinterpretq_u16_s16(vcombine_s16(h16_lo, h16_hi));\n\n    vst1q_u16(reinterpret_cast<uint16_t*>(p1_ptr + offset), result);\n\n  }\n}\n\n/*\n* Final new result asm:\n* _Z23overlay_blend_neon_uintILb0EhEvPhPKhS2_iiiiiifi\n  ldr\tq7, [x0, x19]\t//, MEM <__Uint8x16_t> [(unsigned char * {ref-all})p1_188 + ivtmp.288_938 * 1]\n  ldr\tq19, [x1, x19]\t//, MEM <__Uint8x16_t> [(unsigned char * {ref-all})p2_928 + ivtmp.288_938 * 1]\n  zip1\tv16.16b, v7.16b, v31.16b\t//,,\n  usubl\tv1.8h, v19.8b, v7.8b\t//,,\n  usubl2\tv19.8h, v19.16b, v7.16b\t//,,\n  zip2\tv7.16b, v7.16b, v31.16b\t//,,\n  sxtl\tv18.4s, v16.4h\t//,\n  sxtl\tv23.4s, v1.4h\t//,\n  sxtl\tv20.4s, v19.4h\t//,\n  sxtl\tv17.4s, v7.4h\t//,\n  sxtl2\tv16.4s, v16.8h\t//,\n  sxtl2\tv1.4s, v1.8h\t//,\n  sxtl2\tv7.4s, v7.8h\t//,\n  sxtl2\tv19.4s, v19.8h\t//,\n  scvtf\tv18.4s, v18.4s\t//,\n  scvtf\tv16.4s, v16.4s\t//,\n  scvtf\tv23.4s, v23.4s\t//,\n  scvtf\tv1.4s, v1.4s\t//,\n  scvtf\tv17.4s, v17.4s\t//,\n  scvtf\tv7.4s, v7.4s\t//,\n  scvtf\tv20.4s, v20.4s\t//,\n  scvtf\tv19.4s, v19.4s\t//,\n  fmla\tv18.4s, v23.4s, v30.4s\t//,,\n  fmla\tv16.4s, v1.4s, v30.4s\t//,,\n  fmla\tv17.4s, v20.4s, v30.4s\t//,,\n  fmla\tv7.4s, v19.4s, v30.4s\t//,,\n  fadd\tv18.4s, v18.4s, v29.4s\t//,,\n  fadd\tv16.4s, v16.4s, v29.4s\t//,,\n  fadd\tv17.4s, v17.4s, v29.4s\t//,,\n  fadd\tv7.4s, v7.4s, v29.4s\t//,,\n  fcvtzs\tv18.4s, v18.4s\t//,\n  fcvtzs\tv16.4s, v16.4s\t//,\n  fcvtzs\tv17.4s, v17.4s\t//,\n  fcvtzs\tv7.4s, v7.4s\t//,\n  uzp1\tv16.8h, v18.8h, v16.8h\t//,,\n  uzp1\tv7.8h, v17.8h, v7.8h\t//,,\n  uzp1\tv7.16b, v16.16b, v7.16b\t//,,\n  str\tq7, [x0, x19]\t//, MEM <__Uint8x16_t> [(unsigned char * {ref-all})p1_188 + ivtmp.288_938 * 1]\npre SIMD:\n  ldr\tq3, [x0, x19]\t//, MEM <__Uint8x16_t> [(unsigned char * {ref-all})p1_194 + ivtmp.289_958 * 1]\n  ldr\tq26, [x1, x19]\t//, MEM <__Uint8x16_t> [(unsigned char * {ref-all})p2_948 + ivtmp.289_958 * 1]\n  dup\td27, v3.d[1]\t//,\n  zip1\tv18.16b, v3.16b, v31.16b\t//,,\n  dup\td1, v26.d[1]\t//,\n  usubl\tv26.8h, v26.8b, v3.8b\t//,,\n  zip1\tv17.16b, v27.16b, v31.16b\t//,,\n  zip1\tv23.8h, v18.8h, v31.8h\t//,,\n  usubl\tv1.8h, v1.8b, v27.8b\t//,,\n  sxtl\tv22.4s, v26.4h\t//,\n  zip1\tv19.8h, v17.8h, v31.8h\t//,,\n  zip2\tv18.8h, v18.8h, v31.8h\t//,,\n  sxtl\tv2.4s, v1.4h\t//,\n  zip2\tv17.8h, v17.8h, v31.8h\t//,,\n  sxtl2\tv26.4s, v26.8h\t//,\n  sxtl2\tv1.4s, v1.8h\t//,\n  ucvtf\tv19.4s, v19.4s\t//,\n  ucvtf\tv17.4s, v17.4s\t//,\n  scvtf\tv2.4s, v2.4s\t//,\n  scvtf\tv1.4s, v1.4s\t//,\n  ucvtf\tv23.4s, v23.4s\t//,\n  ucvtf\tv18.4s, v18.4s\t//,\n  scvtf\tv22.4s, v22.4s\t//,\n  scvtf\tv26.4s, v26.4s\t//,\n  fmla\tv19.4s, v2.4s, v30.4s\t//,,\n  fmla\tv17.4s, v1.4s, v30.4s\t//,,\n  fmla\tv23.4s, v22.4s, v30.4s\t//,,\n  fmla\tv18.4s, v26.4s, v30.4s\t//,,\n  fadd\tv19.4s, v19.4s, v29.4s\t//,,\n  fadd\tv17.4s, v17.4s, v29.4s\t//,,\n  fadd\tv23.4s, v23.4s, v29.4s\t//,,\n  fadd\tv18.4s, v18.4s, v29.4s\t//,,\n  fcvtzs\tv19.4s, v19.4s\t//,\n  fcvtzs\tv17.4s, v17.4s\t//,\n  fcvtzs\tv23.4s, v23.4s\t//,\n  fcvtzs\tv18.4s, v18.4s\t//,\n  uzp1\tv17.8h, v19.8h, v17.8h\t//,,\n  uzp1\tv18.8h, v23.8h, v18.8h\t//,,\n  uzp1\tv17.16b, v18.16b, v17.16b\t//,,\n  str\tq17, [x0, x19]\t//, MEM <__Uint8x16_t> [(unsigned char * {ref-all})p1_194 + ivtmp.289_958 * 1]\n\nPrevSIMD:\n  ldr\tq27, [x0, x19]\t//, MEM <__Uint8x16_t> [(unsigned char * {ref-all})p1_182 + ivtmp.289_958 * 1]\n  ldr\tq1, [x1, x19]\t//, MEM <__Uint8x16_t> [(unsigned char * {ref-all})p2_948 + ivtmp.289_958 * 1]\n  zip1\tv18.16b, v27.16b, v31.16b\t//,,\n  usubl\tv24.8h, v1.8b, v27.8b\t//,,\n  dup\td27, v27.d[1]\t//,\n  dup\td1, v1.d[1]\t//,\n  zip1\tv25.8h, v18.8h, v31.8h\t//,,\n  sxtl\tv23.4s, v24.4h\t//,\n  zip1\tv17.16b, v27.16b, v31.16b\t//,,\n  usubl\tv1.8h, v1.8b, v27.8b\t//,,\n  sxtl2\tv24.4s, v24.8h\t//,\n  zip2\tv18.8h, v18.8h, v31.8h\t//,,\n  zip1\tv19.8h, v17.8h, v31.8h\t//,,\n  sxtl\tv2.4s, v1.4h\t//,\n  zip2\tv17.8h, v17.8h, v31.8h\t//,,\n  sxtl2\tv1.4s, v1.8h\t//,\n  ucvtf\tv25.4s, v25.4s\t//,\n  scvtf\tv2.4s, v2.4s\t//,\n  ucvtf\tv19.4s, v19.4s\t//,\n  scvtf\tv1.4s, v1.4s\t//,\n  ucvtf\tv17.4s, v17.4s\t//,\n  ucvtf\tv18.4s, v18.4s\t//,\n  scvtf\tv23.4s, v23.4s\t//,\n  scvtf\tv24.4s, v24.4s\t//,\n  fmla\tv19.4s, v2.4s, v30.4s\t//,,\n  fmla\tv17.4s, v1.4s, v30.4s\t//,,\n  fmla\tv25.4s, v23.4s, v30.4s\t//,,\n  fmla\tv18.4s, v24.4s, v30.4s\t//,,\n  fadd\tv19.4s, v19.4s, v29.4s\t//,,\n  fadd\tv17.4s, v17.4s, v29.4s\t//,,\n  fadd\tv25.4s, v25.4s, v29.4s\t//,,\n  fadd\tv18.4s, v18.4s, v29.4s\t//,,\n  fcvtzs\tv19.4s, v19.4s\t//,\n  fcvtzs\tv17.4s, v17.4s\t//,\n  fcvtzs\tv25.4s, v25.4s\t//,\n  fcvtzs\tv18.4s, v18.4s\t//,\n  uzp1\tv17.8h, v19.8h, v17.8h\t//,,\n  uzp1\tv18.8h, v25.8h, v18.8h\t//,,\n  uzp1\tv17.16b, v18.16b, v17.16b\t//,,\n  str\tq17, [x0, x19]\t//, MEM <__Uint8x16_t> [(unsigned char * {ref-all})p1_182 + ivtmp.289_958 * 1]\n\n And the quicker C version:\n\n    ldr    q4, [x0, x16]    //, MEM <vector(16) unsigned char> [(BYTE *)p1_218 + ivtmp.60_46 * 1]\n    ldr    q25, [x1, x16]    //, MEM <const vector(16) unsigned char> [(const BYTE *)p2_62 + ivtmp.60_46 * 1]\n    zip1    v2.16b, v4.16b, v31.16b    //,,\n    zip2    v26.16b, v4.16b, v31.16b    //,,\n    usubl    v22.8h, v25.8b, v4.8b    //,,\n    usubl2    v25.8h, v25.16b, v4.16b    //,,\n    zip1    v3.8h, v2.8h, v31.8h    //,,\n    zip1    v1.8h, v26.8h, v31.8h    //,,\n    sxtl2    v21.4s, v22.8h    //,\n    sxtl    v28.4s, v25.4h    //,\n    zip2    v2.8h, v2.8h, v31.8h    //,,\n    sxtl    v22.4s, v22.4h    //,\n    zip2    v26.8h, v26.8h, v31.8h    //,,\n    sxtl2    v25.4s, v25.8h    //,\n    scvtf    v21.4s, v21.4s    //,\n    scvtf    v22.4s, v22.4s    //,\n    scvtf    v3.4s, v3.4s    //,\n    scvtf    v2.4s, v2.4s    //,\n    scvtf    v1.4s, v1.4s    //,\n    scvtf    v26.4s, v26.4s    //,\n    scvtf    v28.4s, v28.4s    //,\n    scvtf    v25.4s, v25.4s    //,\n    fmla    v3.4s, v22.4s, v30.4s    //,,\n    fmla    v2.4s, v21.4s, v30.4s    //,,\n    fmla    v1.4s, v28.4s, v30.4s    //,,\n    fmla    v26.4s, v25.4s, v30.4s    //,,\n    fadd    v3.4s, v3.4s, v29.4s    //,,\n    fadd    v2.4s, v2.4s, v29.4s    //,,\n    fadd    v1.4s, v1.4s, v29.4s    //,,\n    fadd    v26.4s, v26.4s, v29.4s    //,,\n    fcvtzs    v3.4s, v3.4s    //,\n    fcvtzs    v2.4s, v2.4s    //,\n    fcvtzs    v1.4s, v1.4s    //,\n    fcvtzs    v26.4s, v26.4s    //,\n    uzp1    v2.8h, v3.8h, v2.8h    //,,\n    uzp1    v26.8h, v1.8h, v26.8h    //,,\n    uzp1    v26.16b, v2.16b, v26.16b    //,,\n    str    q26, [x0, x16]    //, MEM <vector(16) unsigned char> [(BYTE *)p1_218 + ivtmp.60_46 * 1]\n\n\n*/\n\n\ntemplate<bool has_mask, typename pixel_t>\nvoid overlay_blend_neon_uint(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch,\n  const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel)\n{\n  const float32x4_t rounder = vdupq_n_f32(0.5f);\n  const int max_pixel_value = (1 << bits_per_pixel) - 1;\n  const float factor = has_mask ? (opacity_f / max_pixel_value) : opacity_f;\n  const float32x4_t factor_v = vdupq_n_f32(factor);\n\n  // Calculate the vectorized limit (width rounded down to the nearest multiple of 16 bytes)\n  constexpr int bytes_per_pixel = sizeof(pixel_t);\n  constexpr int pixels_per_cycle = (bytes_per_pixel == 1) ? 16 : 8; // 16 bytes per cycle\n  const int real_width_bytes = width * bytes_per_pixel;\n  const int vector_limit_bytes = (real_width_bytes / (pixels_per_cycle * bytes_per_pixel)) * (pixels_per_cycle * bytes_per_pixel);\n\n  // The vector processing size is always 16 bytes for either 8-bit (16 pixels) or 16-bit (8 pixels).\n  constexpr int bytes_per_cycle = 16;\n\n  for (int y = 0; y < height; y++) {\n    // --- Vector Loop (16 bytes at a time) ---\n    for (int x_bytes = 0; x_bytes < vector_limit_bytes; x_bytes += bytes_per_cycle) {\n      // Call the core 16-byte processing function\n      Process_SixteenPixels_neon<has_mask, pixel_t>(p1, p2, mask, factor_v, rounder, x_bytes);\n    }\n\n    // --- Scalar Tail (Pixel by pixel) ---\n    const int start_pixel = vector_limit_bytes / bytes_per_pixel;\n    for (int x = start_pixel; x < width; x++) {\n      const float new_factor = has_mask ? static_cast<float>(reinterpret_cast<const pixel_t*>(mask)[x]) * factor : factor;\n      auto result = overlay_blend_c_core_simple(reinterpret_cast<pixel_t*>(p1)[x], reinterpret_cast<const pixel_t*>(p2)[x], new_factor);\n      reinterpret_cast<pixel_t*>(p1)[x] = (pixel_t)(result + 0.5f);\n    }\n\n    p1 += p1_pitch;\n    p2 += p2_pitch;\n    if constexpr (has_mask)\n      mask += mask_pitch;\n  }\n}\n\n// instantiate\ntemplate void overlay_blend_neon_uint<true, uint8_t>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\ntemplate void overlay_blend_neon_uint<true, uint16_t>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\ntemplate void overlay_blend_neon_uint<false, uint8_t>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\ntemplate void overlay_blend_neon_uint<false, uint16_t>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\n\n// NEON equivalent of overlay_blend_opaque_sse2_core\nAVS_FORCEINLINE uint8x16_t overlay_blend_opaque_neon_core(const uint8x16_t& p1, const uint8x16_t& p2, const uint8x16_t& mask) {\n  // return (mask) ? p2 : p1;\n  // mask: 0x00 = p1, 0xFF = p2 (same as SSE)\n  // vbslq_u8(mask, p2, p1): for each bit, if mask=1, take from p2, else from p1\n  return vbslq_u8(mask, p2, p1);\n}\n\n// For 16-bit pixels\nAVS_FORCEINLINE uint16x8_t overlay_blend_opaque_neon_core_u16(const uint16x8_t& p1, const uint16x8_t& p2, const uint16x8_t& mask) {\n  return vbslq_u16(mask, p2, p1);\n}\n\n// Compare functions for lighten and darken mode (8-bit)\nAVS_FORCEINLINE static uint8x16_t overlay_darken_neon_cmp(const uint8x16_t& p1, const uint8x16_t& p2) {\n  // mask = (p2 <= p1) ? 0xFF : 0x00\n  return vorrq_u8(vcltq_u8(p2, p1), vceqq_u8(p2, p1)); // (p2 < p1) | (p2 == p1)\n}\n\nAVS_FORCEINLINE static uint8x16_t overlay_lighten_neon_cmp(const uint8x16_t& p1, const uint8x16_t& p2) {\n  // mask = (p2 >= p1) ? 0xFF : 0x00\n  return vorrq_u8(vcgtq_u8(p2, p1), vceqq_u8(p2, p1)); // (p2 > p1) | (p2 == p1)\n}\n\n// Compare functions for lighten and darken mode\nAVS_FORCEINLINE static int overlay_darken_c_cmp(BYTE p1, BYTE p2) {\n  return p2 <= p1;\n}\n\nAVS_FORCEINLINE static int overlay_lighten_c_cmp(BYTE p1, BYTE p2) {\n  return p2 >= p1;\n}\n\n/***************************************\n ********* Mode: Lighten/Darken ********\n ***************************************/\n\nusing OverlayNeonCompare = uint8x16_t(const uint8x16_t& p1, const uint8x16_t& p2);\nusing OverlayCCompare = int(BYTE, BYTE);\n\n// Main NEON version for 8-bit\ntemplate <OverlayNeonCompare compare, OverlayCCompare compare_c>\nvoid overlay_darklighten_neon(BYTE *p1Y, BYTE *p1U, BYTE *p1V, const BYTE *p2Y, const BYTE *p2U, const BYTE *p2V,\n                              int p1_pitch, int p2_pitch, int width, int height) {\n  int wMod16 = (width / 16) * 16;\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wMod16; x += 16) {\n      uint8x16_t p1_y = vld1q_u8(p1Y + x);\n      uint8x16_t p2_y = vld1q_u8(p2Y + x);\n      uint8x16_t mask = compare(p1_y, p2_y);\n      uint8x16_t result_y = overlay_blend_opaque_neon_core(p1_y, p2_y, mask);\n      vst1q_u8(p1Y + x, result_y);\n\n      uint8x16_t p1_u = vld1q_u8(p1U + x);\n      uint8x16_t p2_u = vld1q_u8(p2U + x);\n      uint8x16_t result_u = overlay_blend_opaque_neon_core(p1_u, p2_u, mask);\n      vst1q_u8(p1U + x, result_u);\n\n      uint8x16_t p1_v = vld1q_u8(p1V + x);\n      uint8x16_t p2_v = vld1q_u8(p2V + x);\n      uint8x16_t result_v = overlay_blend_opaque_neon_core(p1_v, p2_v, mask);\n      vst1q_u8(p1V + x, result_v);\n    }\n    // Leftover value (fallback to C)\n    for (int x = wMod16; x < width; x++) {\n      int mask = compare_c(p1Y[x], p2Y[x]) ? 0xFF : 0x00;\n      p1Y[x] = overlay_blend_opaque_c_core<uint8_t>(p1Y[x], p2Y[x], mask);\n      p1U[x] = overlay_blend_opaque_c_core<uint8_t>(p1U[x], p2U[x], mask);\n      p1V[x] = overlay_blend_opaque_c_core<uint8_t>(p1V[x], p2V[x], mask);\n    }\n    p1Y += p1_pitch; p1U += p1_pitch; p1V += p1_pitch;\n    p2Y += p2_pitch; p2U += p2_pitch; p2V += p2_pitch;\n  }\n}\n\n\ntemplate<bool has_mask>\nvoid overlay_blend_neon_float(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch,\n  const int width, const int height, const int /*opacity*/, const float opacity_f, const int bits_per_pixel)\n{\n  const int realwidth = width * sizeof(float);\n  int wMod16 = (realwidth / 16) * 16;\n  float32x4_t opacity_v = vdupq_n_f32(opacity_f);\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wMod16; x += 16) {\n      float32x4_t p1_f0 = vld1q_f32(reinterpret_cast<const float*>(p1 + x + 0));\n      float32x4_t p1_f1 = vld1q_f32(reinterpret_cast<const float*>(p1 + x + 4));\n      float32x4_t p1_f2 = vld1q_f32(reinterpret_cast<const float*>(p1 + x + 8));\n      float32x4_t p1_f3 = vld1q_f32(reinterpret_cast<const float*>(p1 + x + 12));\n\n      float32x4_t p2_f0 = vld1q_f32(reinterpret_cast<const float*>(p2 + x + 0));\n      float32x4_t p2_f1 = vld1q_f32(reinterpret_cast<const float*>(p2 + x + 4));\n      float32x4_t p2_f2 = vld1q_f32(reinterpret_cast<const float*>(p2 + x + 8));\n      float32x4_t p2_f3 = vld1q_f32(reinterpret_cast<const float*>(p2 + x + 12));\n\n      float32x4_t mask0, mask1, mask2, mask3;\n      if constexpr (has_mask) {\n        mask0 = vld1q_f32(reinterpret_cast<const float*>(mask + x + 0));\n        mask1 = vld1q_f32(reinterpret_cast<const float*>(mask + x + 4));\n        mask2 = vld1q_f32(reinterpret_cast<const float*>(mask + x + 8));\n        mask3 = vld1q_f32(reinterpret_cast<const float*>(mask + x + 12));\n        mask0 = vmulq_f32(mask0, opacity_v);\n        mask1 = vmulq_f32(mask1, opacity_v);\n        mask2 = vmulq_f32(mask2, opacity_v);\n        mask3 = vmulq_f32(mask3, opacity_v);\n      }\n      else {\n        mask0 = opacity_v;\n        mask1 = opacity_v;\n        mask2 = opacity_v;\n        mask3 = opacity_v;\n      }\n\n      float32x4_t result0 = vaddq_f32(p1_f0, vmulq_f32(vsubq_f32(p2_f0, p1_f0), mask0));\n      float32x4_t result1 = vaddq_f32(p1_f1, vmulq_f32(vsubq_f32(p2_f1, p1_f1), mask1));\n      float32x4_t result2 = vaddq_f32(p1_f2, vmulq_f32(vsubq_f32(p2_f2, p1_f2), mask2));\n      float32x4_t result3 = vaddq_f32(p1_f3, vmulq_f32(vsubq_f32(p2_f3, p1_f3), mask3));\n\n      vst1q_f32(reinterpret_cast<float*>(p1 + x + 0), result0);\n      vst1q_f32(reinterpret_cast<float*>(p1 + x + 4), result1);\n      vst1q_f32(reinterpret_cast<float*>(p1 + x + 8), result2);\n      vst1q_f32(reinterpret_cast<float*>(p1 + x + 12), result3);\n    }\n\n    // Leftover value\n    for (int x = wMod16 / sizeof(float); x < width; x++) {\n      auto new_mask = has_mask ? reinterpret_cast<const float*>(mask)[x] * opacity_f : opacity_f;\n      auto p1x = reinterpret_cast<float*>(p1)[x];\n      auto p2x = reinterpret_cast<const float*>(p2)[x];\n      auto result = p1x + (p2x - p1x) * new_mask;\n      reinterpret_cast<float*>(p1)[x] = result;\n    }\n\n    p1 += p1_pitch;\n    p2 += p2_pitch;\n    if constexpr (has_mask)\n      mask += mask_pitch;\n  }\n}\n\n// instantiate\ntemplate void overlay_blend_neon_float<false>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int /*opacity*/, const float opacity_f, const int bits_per_pixel);\ntemplate void overlay_blend_neon_float<true>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int /*opacity*/, const float opacity_f, const int bits_per_pixel);\n\nvoid overlay_darken_neon(BYTE* p1Y, BYTE* p1U, BYTE* p1V, const BYTE* p2Y, const BYTE* p2U, const BYTE* p2V, int p1_pitch, int p2_pitch, int width, int height) {\n  overlay_darklighten_neon<overlay_darken_neon_cmp, overlay_darken_c_cmp>(p1Y, p1U, p1V, p2Y, p2U, p2V, p1_pitch, p2_pitch, width, height);\n}\nvoid overlay_lighten_neon(BYTE* p1Y, BYTE* p1U, BYTE* p1V, const BYTE* p2Y, const BYTE* p2U, const BYTE* p2V, int p1_pitch, int p2_pitch, int width, int height) {\n  overlay_darklighten_neon<overlay_lighten_neon_cmp, overlay_lighten_c_cmp>(p1Y, p1U, p1V, p2Y, p2U, p2V, p1_pitch, p2_pitch, width, height);\n}\n"
  },
  {
    "path": "avs_core/filters/overlay/aarch64/blend_common_neon.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __blend_common_neon_h\n#define __blend_common_neon_h\n\n#include <avs/types.h>\n\ntemplate<bool has_mask, typename pixel_t>\nvoid overlay_blend_neon_uint(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch,\n  const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\ntemplate<bool has_mask>\nvoid overlay_blend_neon_float(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch,\n  const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\nvoid overlay_darken_neon(BYTE* p1Y, BYTE* p1U, BYTE* p1V, const BYTE* p2Y, const BYTE* p2U, const BYTE* p2V, int p1_pitch, int p2_pitch, int width, int height);\nvoid overlay_lighten_neon(BYTE* p1Y, BYTE* p1U, BYTE* p1V, const BYTE* p2Y, const BYTE* p2U, const BYTE* p2V, int p1_pitch, int p2_pitch, int width, int height);\n\n#endif // __blend_common_neon_h\n"
  },
  {
    "path": "avs_core/filters/overlay/blend_common.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// Overlay (c) 2003, 2004 by Klaus Post\n\n#include <avs/config.h>\n\n#include \"blend_common.h\"\n#include \"overlayfunctions.h\"\n\n#include <stdint.h>\n#include <type_traits>\n\n\n/******************************\n ********* Mode: Blend ********\n ******************************/\n\n// 32 bit float mask calculation inside\ntemplate<bool has_mask, typename pixel_t>\nvoid overlay_blend_c_uint(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch,\n  const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel)\n{\n  const int max_pixel_value = (1 << bits_per_pixel) - 1;\n  auto factor = has_mask ? opacity_f / max_pixel_value : opacity_f;\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < width; x++) {\n      const float new_factor = has_mask ? static_cast<float>(reinterpret_cast<const pixel_t*>(mask)[x]) * factor : factor;\n      const pixel_t pix1 = reinterpret_cast<pixel_t*>(p1)[x];\n      const pixel_t pix2 = reinterpret_cast<const pixel_t*>(p2)[x];\n      pixel_t result = pix1 + (int)((pix2 - pix1) * new_factor + 0.5f);\n      reinterpret_cast<pixel_t*>(p1)[x] = result;\n    }\n\n    p1 += p1_pitch;\n    p2 += p2_pitch;\n    if(has_mask)\n      mask += mask_pitch;\n  }\n}\n\n// instantiate\n// w/o mask\ntemplate void overlay_blend_c_uint<false, uint8_t>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\ntemplate void overlay_blend_c_uint<false, uint16_t>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\n// w/ mask\ntemplate void overlay_blend_c_uint<true, uint8_t>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\ntemplate void overlay_blend_c_uint<true, uint16_t>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\n\n\ntemplate<bool has_mask>\nvoid overlay_blend_c_float(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch,\n  const int width, const int height, const int /*opacity*/, const float opacity_f, const int bits_per_pixel) {\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < width; x++) {\n      auto new_mask = has_mask ? reinterpret_cast<const float*>(mask)[x] * opacity_f : opacity_f;\n      auto p1x = reinterpret_cast<float*>(p1)[x];\n      auto p2x = reinterpret_cast<const float*>(p2)[x];\n      auto result = p1x + (p2x - p1x) * new_mask; // p1x*(1-new_mask) + p2x*mask\n      reinterpret_cast<float*>(p1)[x] = result;\n    }\n\n    p1 += p1_pitch;\n    p2 += p2_pitch;\n    if constexpr (has_mask)\n      mask += mask_pitch;\n  }\n}\n\n// instantiate\ntemplate void overlay_blend_c_float<false>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int /*opacity*/, const float opacity_f, const int bits_per_pixel);\ntemplate void overlay_blend_c_float<true>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int /*opacity*/, const float opacity_f, const int bits_per_pixel);\n\n\n/***************************************\n ********* Mode: Lighten/Darken ********\n ***************************************/\n\ntypedef int (OverlayCCompare)(BYTE, BYTE);\n\ntemplate<typename pixel_t, bool darken /* OverlayCCompare<pixel_t> compare*/>\nstatic void overlay_darklighten_c(BYTE *p1Y_8, BYTE *p1U_8, BYTE *p1V_8, const BYTE *p2Y_8, const BYTE *p2U_8, const BYTE *p2V_8, int p1_pitch, int p2_pitch, int width, int height) {\n  pixel_t* p1Y = reinterpret_cast<pixel_t *>(p1Y_8);\n  pixel_t* p1U = reinterpret_cast<pixel_t *>(p1U_8);\n  pixel_t* p1V = reinterpret_cast<pixel_t *>(p1V_8);\n\n  const pixel_t* p2Y = reinterpret_cast<const pixel_t *>(p2Y_8);\n  const pixel_t* p2U = reinterpret_cast<const pixel_t *>(p2U_8);\n  const pixel_t* p2V = reinterpret_cast<const pixel_t *>(p2V_8);\n\n  // pitches are already scaled\n  //p1_pitch /= sizeof(pixel_t);\n  //p2_pitch /= sizeof(pixel_t);\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < width; x++) {\n      int mask = darken ? (p2Y[x] <= p1Y[x]) : (p2Y[x] >= p1Y[x]); // compare(p1Y[x], p2Y[x]);\n      p1Y[x] = overlay_blend_opaque_c_core<pixel_t>(p1Y[x], p2Y[x], mask);\n      p1U[x] = overlay_blend_opaque_c_core<pixel_t>(p1U[x], p2U[x], mask);\n      p1V[x] = overlay_blend_opaque_c_core<pixel_t>(p1V[x], p2V[x], mask);\n    }\n\n    p1Y += p1_pitch;\n    p1U += p1_pitch;\n    p1V += p1_pitch;\n\n    p2Y += p2_pitch;\n    p2U += p2_pitch;\n    p2V += p2_pitch;\n  }\n}\n\n// Exported function\ntemplate<typename pixel_t>\nvoid overlay_darken_c(BYTE *p1Y_8, BYTE *p1U_8, BYTE *p1V_8, const BYTE *p2Y_8, const BYTE *p2U_8, const BYTE *p2V_8, int p1_pitch, int p2_pitch, int width, int height) {\n  overlay_darklighten_c<pixel_t, true /*overlay_darken_c_cmp */>(p1Y_8, p1U_8, p1V_8, p2Y_8, p2U_8, p2V_8, p1_pitch, p2_pitch, width, height);\n}\n// instantiate\ntemplate void overlay_darken_c<uint8_t>(BYTE *p1Y_8, BYTE *p1U_8, BYTE *p1V_8, const BYTE *p2Y_8, const BYTE *p2U_8, const BYTE *p2V_8, int p1_pitch, int p2_pitch, int width, int height);\ntemplate void overlay_darken_c<uint16_t>(BYTE *p1Y_8, BYTE *p1U_8, BYTE *p1V_8, const BYTE *p2Y_8, const BYTE *p2U_8, const BYTE *p2V_8, int p1_pitch, int p2_pitch, int width, int height);\n\ntemplate<typename pixel_t>\nvoid overlay_lighten_c(BYTE *p1Y_8, BYTE *p1U_8, BYTE *p1V_8, const BYTE *p2Y_8, const BYTE *p2U_8, const BYTE *p2V_8, int p1_pitch, int p2_pitch, int width, int height) {\n  overlay_darklighten_c<pixel_t, false /*overlay_lighten_c_cmp*/>(p1Y_8, p1U_8, p1V_8, p2Y_8, p2U_8, p2V_8, p1_pitch, p2_pitch, width, height);\n}\n\n// instantiate\ntemplate void overlay_lighten_c<uint8_t>(BYTE *p1Y_8, BYTE *p1U_8, BYTE *p1V_8, const BYTE *p2Y_8, const BYTE *p2U_8, const BYTE *p2V_8, int p1_pitch, int p2_pitch, int width, int height);\ntemplate void overlay_lighten_c<uint16_t>(BYTE *p1Y_8, BYTE *p1U_8, BYTE *p1V_8, const BYTE *p2Y_8, const BYTE *p2U_8, const BYTE *p2V_8, int p1_pitch, int p2_pitch, int width, int height);\n"
  },
  {
    "path": "avs_core/filters/overlay/blend_common.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// Overlay (c) 2003, 2004 by Klaus Post\n\n#ifndef __blend_common_h\n#define __blend_common_h\n\n#include <avs/types.h>\n#include <avs/config.h>\n\nusing overlay_blend_plane_masked_opacity_t = void(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch,\n  const int width, const int height, const int opacity, const float opacity_f,\n  const int bits_per_pixel);\n\n/*******************************\n ********* Masked Blend ********\n *******************************/\n\nAVS_FORCEINLINE static float overlay_blend_c_core_simple(const int p1, const int p2, const float factor) {\n  //  p1*(1-mask_f) + p2*mask_f -> p1 + (p2-p1)*mask_f\n  const float res = p1 + (p2 - p1) * factor;\n  return res;\n}\n\n/********************************\n ********* Blend Opaque *********\n ** Use for Lighten and Darken **\n ********************************/\ntemplate<typename pixel_t>\nAVS_FORCEINLINE pixel_t overlay_blend_opaque_c_core(const pixel_t p1, const pixel_t p2, const pixel_t mask) {\n  return (mask) ? p2 : p1;\n}  \n\n// Mode: Overlay\n\ntemplate<bool has_mask, typename pixel_t>\nvoid overlay_blend_c_uint(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch,\n  const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\n\ntemplate<bool has_mask>\nvoid overlay_blend_c_float(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch,\n  const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\n\n// Mode: Darken/lighten\n\ntemplate<typename pixel_t>\nvoid overlay_darken_c(BYTE *p1Y, BYTE *p1U, BYTE *p1V, const BYTE *p2Y, const BYTE *p2U, const BYTE *p2V, int p1_pitch, int p2_pitch, int width, int height);\ntemplate<typename pixel_t>\nvoid overlay_lighten_c(BYTE *p1Y, BYTE *p1U, BYTE *p1V, const BYTE *p2Y, const BYTE *p2U, const BYTE *p2V, int p1_pitch, int p2_pitch, int width, int height);\n\n#endif // __blend_common_h\n"
  },
  {
    "path": "avs_core/filters/overlay/imghelpers.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// Overlay (c) 2003, 2004 by Klaus Post\n\n#ifndef __Overlay_helpers_h\n#define __Overlay_helpers_h\n\n#include <avisynth.h>\n#include <avs/minmax.h>\n#include <avs/alignment.h>\n#include \"444convert.h\"\n\nclass ImageOverlayInternal {\nprivate:\n  IScriptEnvironment* Env;\n\n  PVideoFrame &frame;\n\n  BYTE* origPlanes[4];\n  BYTE* fakePlanes[4];\n\n  int fake_w;\n  int fake_h;\n  const int _w;\n  const int _h;\n  const int _bits_per_pixel;\n  const bool grey;\n\n  bool return_original;\n\n  const int planes_y[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };\n  const int planes_r[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A };\n  const int *planes;\n\n  int planeCount;\n  int pitches[4];\n\n  BYTE *maskChroma;\npublic:\n  int xSubSamplingShifts[4];\n  int ySubSamplingShifts[4];\n  int pitch;\n  int pitchUV;\n  int pitchA;\n\n  ImageOverlayInternal(\n    PVideoFrame &_frame,\n    int _inw, int _inh, VideoInfo &_workingVI, bool _hasAlpha, bool _grey, IScriptEnvironment* env) :\n    Env(env),\n    frame(_frame),\n    _w(_inw), _h(_inh), _bits_per_pixel(_workingVI.BitsPerComponent()), grey(_grey), maskChroma(nullptr) {\n\n    int pixelsize;\n    if (_bits_per_pixel == 8) pixelsize = 1;\n    else if (_bits_per_pixel <= 16) pixelsize = 2;\n    else pixelsize = 4;\n\n    planeCount = _workingVI.NumComponents();\n\n    planes = (_workingVI.IsYUV() || _workingVI.IsYUVA()) ? planes_y : planes_r;\n    for (int p = 0; p < 4; p++) {\n      xSubSamplingShifts[p] = ySubSamplingShifts[p] = 0;\n      pitches[p] = 0;\n    }\n\n    for (int p = 0; p < planeCount; ++p) {\n      const int plane = planes[p];\n      xSubSamplingShifts[p] = _workingVI.GetPlaneWidthSubsampling(plane);\n      ySubSamplingShifts[p] = _workingVI.GetPlaneHeightSubsampling(plane);\n      pitches[p] = frame->GetPitch(plane);\n    }\n\n    // allocate extra chroma and set chroma pitches for greymask mode\n    if (grey) {\n      if (_workingVI.Is420() || _workingVI.Is422()) {\n        // allocate for subSampled chroma when original mask is grey (Y only)\n        int tmppitch = AlignNumber((_w >> xSubSamplingShifts[1])*pixelsize, FRAME_ALIGN);\n        maskChroma = static_cast<BYTE*>(Env->Allocate(\n          tmppitch * (_h >> ySubSamplingShifts[1]), 64, AVS_POOLED_ALLOC)\n          );\n        pitches[1] = pitches[2] = tmppitch;\n      }\n      else {\n        pitches[1] = pitches[2] = pitches[0];\n      }\n    }\n\n    // temporarily. so far only blend is ported to arrays\n    pitch = pitches[0];\n    pitchUV = pitches[1];\n    pitchA = pitches[3];\n\n    for (int p = 0; p < planeCount; p++)\n      origPlanes[p] = (BYTE*)frame->GetReadPtr(planes[p]);\n    if (grey) {\n      if (_workingVI.Is420()) {\n        // resize Y-only mask to 4:2:0 chroma\n        ConvertYToYV12Chroma(maskChroma, origPlanes[0], pitches[1], pitches[0], pixelsize, _w >> xSubSamplingShifts[1], _h >> ySubSamplingShifts[1], Env);\n        origPlanes[1] = origPlanes[2] = maskChroma;\n      }\n      else if (_workingVI.Is422()) {\n        // resize Y-only mask to 4:2:2 chroma\n        ConvertYToYV16Chroma(maskChroma, origPlanes[0], pitches[1], pitches[0], pixelsize, _w >> xSubSamplingShifts[1], _h >> ySubSamplingShifts[1], Env);\n        origPlanes[1] = origPlanes[2] = maskChroma;\n      }\n      else {\n        // UV = Y plane pointer\n        origPlanes[1] = origPlanes[2] = origPlanes[0];\n        xSubSamplingShifts[1] = xSubSamplingShifts[2] = 0;\n        ySubSamplingShifts[1] = ySubSamplingShifts[2] = 0;\n      }\n    }\n\n    ResetFake();\n  }\n\n  __inline int w() { return (return_original) ? _w : fake_w; }\n  __inline int h() { return (return_original) ? _h : fake_h; }\n\n  BYTE* GetPtr(int plane) {\n    if (!(_w && _h)) {\n      _RPT0(1,\"Image444: Height or Width is 0\");\n    }\n    switch (plane) {\n      case PLANAR_Y:\n        return (return_original) ? origPlanes[0] : fakePlanes[0];\n      case PLANAR_U:\n        return (return_original) ? origPlanes[1] : fakePlanes[1];\n      case PLANAR_V:\n        return (return_original) ? origPlanes[2] : fakePlanes[2];\n      case PLANAR_A:\n        return (return_original) ? origPlanes[3] : fakePlanes[3];\n    }\n    return origPlanes[0];\n  }\n\n  int GetPitchByIndex(int planeIndex) {\n    if (planeIndex>=0 && planeIndex <=3)\n      return pitches[planeIndex];\n    return pitches[0]; // Y\n  }\n\n\n  BYTE* GetPtrByIndex(int planeIndex) {\n    if (!(_w && _h)) {\n      _RPT0(1,\"Image444: Height or Width is 0\");\n    }\n    if (planeIndex>=0 && planeIndex <=3)\n      return (return_original) ? origPlanes[planeIndex] : fakePlanes[planeIndex];\n    return origPlanes[0]; // Y\n  }\n\n  /*\n  void SetPtr(BYTE* ptr, int plane) {\n    if (!(_w && _h)) {\n      _RPT0(1,\"Image444: Height or Width is 0\");\n    }\n    switch (plane) {\n      case PLANAR_Y:\n        fake_Y_plane = Y_plane = ptr;\n        break;\n      case PLANAR_U:\n        fake_Y_plane = U_plane = ptr;\n        break;\n      case PLANAR_V:\n        fake_Y_plane = V_plane = ptr;\n        break;\n      case PLANAR_A:\n        fake_A_plane = A_plane = ptr;\n        break;\n    }\n  }\n  */\n  void SetPtrByIndex(BYTE* ptr, int planeIndex) {\n    if (!(_w && _h)) {\n      _RPT0(1,\"Image444: Height or Width is 0\");\n    }\n    if (planeIndex >= 0 && planeIndex <= 3)\n      origPlanes[planeIndex] = fakePlanes[planeIndex] = ptr;\n  }\n\n\n  int GetPitch(int plane) {\n    if (!(_w && _h)) {\n      _RPT0(1,\"Image444: Height or Width is 0\");\n    }\n    switch (plane) {\n    case PLANAR_Y:\n    case PLANAR_G:\n    case PLANAR_B:\n    case PLANAR_R:\n      return pitch;\n    case PLANAR_U:\n    case PLANAR_V:\n      return pitchUV;\n    case PLANAR_A:\n      return pitchA;\n    }\n    return pitch;\n  }\n\n  void SubFrame(int x, int y, int new_w, int new_h) {\n    new_w = min(new_w, w()-x);\n    new_h = min(new_h, h()-y);\n\n    int pixelsize;\n    switch(_bits_per_pixel) {\n    case 8: pixelsize = 1; break;\n    case 32: pixelsize = 4; break;\n    default: pixelsize = 2;\n    }\n\n    for (int p = 0; p < 3; p++)\n    {\n      fakePlanes[p] = GetPtrByIndex(p) + (x >> xSubSamplingShifts[p]) * pixelsize + (y >> ySubSamplingShifts[p]) * pitches[p];\n    }\n    fakePlanes[3] = pitches[3] > 0 ? (GetPtrByIndex(3) + (x >> xSubSamplingShifts[3])*pixelsize + (y >> ySubSamplingShifts[3])*pitches[3]) : nullptr;\n\n    fake_w = new_w;\n    fake_h = new_h;\n  }\n\n  bool IsSizeZero() {\n    if (w()<=0) return true;\n    if (h()<=0) return true;\n    if (!(pitch && origPlanes[0])) return true;\n    return false;\n  }\n\n  void ReturnOriginal(bool shouldI) {\n    return_original = shouldI;\n  }\n\n  void ResetFake() {\n    return_original = true;\n    for (int i = 0; i < 4; i++)\n      fakePlanes[i] = origPlanes[i];\n    fake_w = _w;\n    fake_h = _h;\n  }\n\n  ~ImageOverlayInternal() {\n    if(maskChroma)\n      Env->Free(maskChroma);\n  }\n\n};\n\n\n#endif\n"
  },
  {
    "path": "avs_core/filters/overlay/intel/444convert_sse.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// Overlay (c) 2003, 2004 by Klaus Post\n\n#include \"444convert_sse.h\"\n#include \"../core/internal.h\"\n\n// Intrinsics base header + really required extension headers\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n#include <smmintrin.h> // SSE4.1\n\n#include <avs/alignment.h>\n\n// fast in-place conversions from and to 4:4:4\n\n/***** YV12 -> YUV 4:4:4   ******/\n\ntemplate<typename pixel_t>\nstatic void convert_yv12_chroma_to_yv24_sse2(BYTE *dstp, const BYTE *srcp, int dst_pitch, int src_pitch, int src_width, int src_height) {\n  src_width *= sizeof(pixel_t);\n  int mod8_width = src_width / 8 * 8;\n  for (int y = 0; y < src_height; ++y) {\n    for (int x = 0; x < mod8_width; x+=8) {\n      // 0 0 0 0 0 0 0 0 U7 U6 U5 U4 U3 U2 U1 U0 for 8 bits\n      // 0 0 0 0 U3 U2 U1 U0 for 16 bits\n      __m128i src = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp+x));\n      if constexpr(sizeof(pixel_t) == 1)\n        src = _mm_unpacklo_epi8(src, src); //U7 U7 U6 U6 U5 U5 U4 U4 U3 U3 U2 U2 U1 U1 U0 U0\n      else\n        src = _mm_unpacklo_epi16(src, src); //U3 U3 U2 U2 U1 U1 U0 U0\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp+x*2), src);\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp+x*2 + dst_pitch), src);\n    }\n\n    if (mod8_width != src_width) {\n      __m128i src = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp+src_width - 8));\n      if constexpr(sizeof(pixel_t) == 1)\n        src = _mm_unpacklo_epi8(src, src); //U7 U7 U6 U6 U5 U5 U4 U4 U3 U3 U2 U2 U1 U1 U0 U0\n      else\n        src = _mm_unpacklo_epi16(src, src); //U3 U3 U2 U2 U1 U1 U0 U0\n\n      _mm_storeu_si128(reinterpret_cast<__m128i*>(dstp + (src_width * 2) - 16), src);\n      _mm_storeu_si128(reinterpret_cast<__m128i*>(dstp + (src_width * 2) - 16 + dst_pitch), src);\n    }\n\n    dstp += dst_pitch*2;\n    srcp += src_pitch;\n  }\n}\n\n\n#ifdef X86_32\n\nstatic void convert_yv12_chroma_to_yv24_mmx(BYTE *dstp, const BYTE *srcp, int dst_pitch, int src_pitch, int src_width, int src_height) {\n  int mod4_width = src_width / 4 * 4;\n  for (int y = 0; y < src_height; ++y) {\n    for (int x = 0; x < mod4_width; x+=4) {\n      __m64 src = _mm_cvtsi32_si64(*reinterpret_cast<const int*>(srcp+x)); //0 0 0 0 U3 U2 U1 U0\n      src = _mm_unpacklo_pi8(src, src); //U3 U3 U2 U2 U1 U1 U0 U0\n\n      *reinterpret_cast<__m64*>(dstp+x*2) = src;\n      *reinterpret_cast<__m64*>(dstp+x*2 + dst_pitch) = src;\n    }\n\n    if (mod4_width != src_width) {\n      __m64 src = _mm_cvtsi32_si64(*reinterpret_cast<const int*>(srcp-4)); //0 0 0 0 U3 U2 U1 U0\n      src = _mm_unpacklo_pi8(src, src); //U3 U3 U2 U2 U1 U1 U0 U0\n\n      *reinterpret_cast<__m64*>(dstp + (src_width * 2) - 8) = src;\n      *reinterpret_cast<__m64*>(dstp + (src_width * 2) - 8 + dst_pitch) = src;\n    }\n\n    dstp += dst_pitch*2;\n    srcp += src_pitch;\n  }\n  _mm_empty();\n}\n\n#endif // X86_32\n\n\ntemplate<typename pixel_t>\nstatic void convert_yv12_chroma_to_yv24_c(BYTE *dstp8, const BYTE *srcp8, int dst_pitch, int src_pitch, int src_width, int src_height) {\n  pixel_t *dstp = reinterpret_cast<pixel_t *>(dstp8);\n  const pixel_t *srcp = reinterpret_cast<const pixel_t *>(srcp8);\n  dst_pitch /= sizeof(pixel_t);\n  src_pitch /= sizeof(pixel_t);\n  for (int y = 0; y < src_height; ++y) {\n    for (int x = 0; x < src_width; ++x) {\n      dstp[x*2]             = srcp[x];\n      dstp[x*2+1]           = srcp[x];\n      dstp[x*2+dst_pitch]   = srcp[x];\n      dstp[x*2+dst_pitch+1] = srcp[x];\n    }\n    dstp += dst_pitch*2;\n    srcp += src_pitch;\n  }\n}\n\nvoid Convert444FromYV12(PVideoFrame &src, PVideoFrame &dst, int pixelsize, int bits_per_pixel, IScriptEnvironment* env)\n{\n  AVS_UNUSED(bits_per_pixel);\n  env->BitBlt(dst->GetWritePtr(PLANAR_Y), dst->GetPitch(PLANAR_Y), src->GetReadPtr(PLANAR_Y),src->GetPitch(PLANAR_Y), src->GetRowSize(PLANAR_Y), src->GetHeight());\n\n  const BYTE* srcU = src->GetReadPtr(PLANAR_U);\n  const BYTE* srcV = src->GetReadPtr(PLANAR_V);\n\n  int srcUVpitch = src->GetPitch(PLANAR_U);\n\n  BYTE* dstU = dst->GetWritePtr(PLANAR_U);\n  BYTE* dstV = dst->GetWritePtr(PLANAR_V);\n\n  int dstUVpitch = dst->GetPitch(PLANAR_U);\n\n  int width = src->GetRowSize(PLANAR_U) / pixelsize;\n  int height = src->GetHeight(PLANAR_U);\n\n  if ((pixelsize == 1 || pixelsize == 2) && (env->GetCPUFlags() & CPUF_SSE2) && IsPtrAligned(dstU, 16) && IsPtrAligned(dstV, 16))\n  {\n    if (pixelsize == 1) {\n      convert_yv12_chroma_to_yv24_sse2<uint8_t>(dstU, srcU, dstUVpitch, srcUVpitch, width, height);\n      convert_yv12_chroma_to_yv24_sse2<uint8_t>(dstV, srcV, dstUVpitch, srcUVpitch, width, height);\n    }\n    else if (pixelsize == 2) {\n      convert_yv12_chroma_to_yv24_sse2<uint16_t>(dstU, srcU, dstUVpitch, srcUVpitch, width, height);\n      convert_yv12_chroma_to_yv24_sse2<uint16_t>(dstV, srcV, dstUVpitch, srcUVpitch, width, height);\n    }\n  }\n  else\n#ifdef X86_32\n    if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_MMX))\n    {\n      convert_yv12_chroma_to_yv24_mmx(dstU, srcU, dstUVpitch, srcUVpitch, width, height);\n      convert_yv12_chroma_to_yv24_mmx(dstV, srcV, dstUVpitch, srcUVpitch, width, height);\n    }\n    else\n#endif\n    {\n      if (pixelsize == 1) {\n        convert_yv12_chroma_to_yv24_c<uint8_t>(dstU, srcU, dstUVpitch, srcUVpitch, width, height);\n        convert_yv12_chroma_to_yv24_c<uint8_t>(dstV, srcV, dstUVpitch, srcUVpitch, width, height);\n      } else if(pixelsize == 2) {\n        convert_yv12_chroma_to_yv24_c<uint16_t>(dstU, srcU, dstUVpitch, srcUVpitch, width, height);\n        convert_yv12_chroma_to_yv24_c<uint16_t>(dstV, srcV, dstUVpitch, srcUVpitch, width, height);\n      }\n      else {\n        convert_yv12_chroma_to_yv24_c<float>(dstU, srcU, dstUVpitch, srcUVpitch, width, height);\n        convert_yv12_chroma_to_yv24_c<float>(dstV, srcV, dstUVpitch, srcUVpitch, width, height);\n      }\n    }\n\n  env->BitBlt(dst->GetWritePtr(PLANAR_A), dst->GetPitch(PLANAR_A),\n    src->GetReadPtr(PLANAR_A), src->GetPitch(PLANAR_A), dst->GetRowSize(PLANAR_A), dst->GetHeight(PLANAR_A));\n\n\n}\n\n/***** YV16 -> YUV 4:4:4   ******/\n\ntemplate<typename pixel_t>\nstatic void convert_yv16_chroma_to_yv24_sse2(BYTE *dstp, const BYTE *srcp, int dst_pitch, int src_pitch, int src_width, int src_height) {\n  src_width *= sizeof(pixel_t);\n  int mod8_width = src_width / 8 * 8;\n  for (int y = 0; y < src_height; ++y) {\n    for (int x = 0; x < mod8_width; x+=8) {\n      // 0 0 0 0 0 0 0 0 U7 U6 U5 U4 U3 U2 U1 U0 for 8 bits\n      // 0 0 0 0 U3 U2 U1 U0 for 16 bits\n      __m128i src = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp+x));\n      if constexpr(sizeof(pixel_t) == 1)\n        src = _mm_unpacklo_epi8(src, src); //U7 U7 U6 U6 U5 U5 U4 U4 U3 U3 U2 U2 U1 U1 U0 U0\n      else\n        src = _mm_unpacklo_epi16(src, src); //U3 U3 U2 U2 U1 U1 U0 U0\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp+x*2), src);\n    }\n\n    if (mod8_width != src_width) {\n      __m128i src = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(srcp+src_width - 8)); //0 0 0 0 0 0 0 0 U8 U7 U6 U5 U4 U3 U2 U1 U0\n      if constexpr(sizeof(pixel_t)==1)\n        src = _mm_unpacklo_epi8(src, src); //U7 U7 U6 U6 U5 U5 U4 U4 U3 U3 U2 U2 U1 U1 U0 U0\n      else\n        src = _mm_unpacklo_epi16(src, src); //U3 U3 U2 U2 U1 U1 U0 U0\n\n      _mm_storeu_si128(reinterpret_cast<__m128i*>(dstp + (src_width * 2) - 16), src);\n    }\n\n    dstp += dst_pitch;\n    srcp += src_pitch;\n  }\n}\n\n\ntemplate<typename pixel_t>\nstatic void convert_yv16_chroma_to_yv24_c(BYTE *dstp8, const BYTE *srcp8, int dst_pitch, int src_pitch, int src_width, int src_height) {\n  pixel_t *dstp = reinterpret_cast<pixel_t *>(dstp8);\n  const pixel_t *srcp = reinterpret_cast<const pixel_t *>(srcp8);\n  dst_pitch /= sizeof(pixel_t);\n  src_pitch /= sizeof(pixel_t);\n  for (int y = 0; y < src_height; ++y) {\n    for (int x = 0; x < src_width; ++x) {\n      dstp[x*2]             = srcp[x];\n      dstp[x*2+1]           = srcp[x];\n    }\n    dstp += dst_pitch;\n    srcp += src_pitch;\n  }\n}\n\nvoid Convert444FromYV16(PVideoFrame &src, PVideoFrame &dst, int pixelsize, int bits_per_pixel, IScriptEnvironment* env)\n{\n  AVS_UNUSED(bits_per_pixel);\n  env->BitBlt(dst->GetWritePtr(PLANAR_Y), dst->GetPitch(PLANAR_Y), src->GetReadPtr(PLANAR_Y),src->GetPitch(PLANAR_Y), src->GetRowSize(PLANAR_Y), src->GetHeight());\n\n  const BYTE* srcU = src->GetReadPtr(PLANAR_U);\n  const BYTE* srcV = src->GetReadPtr(PLANAR_V);\n\n  int srcUVpitch = src->GetPitch(PLANAR_U);\n\n  BYTE* dstU = dst->GetWritePtr(PLANAR_U);\n  BYTE* dstV = dst->GetWritePtr(PLANAR_V);\n\n  int dstUVpitch = dst->GetPitch(PLANAR_U);\n\n  int width = src->GetRowSize(PLANAR_U) / pixelsize;\n  int height = src->GetHeight(PLANAR_U);\n\n  if ((pixelsize == 1 || pixelsize==2) && (env->GetCPUFlags() & CPUF_SSE2) && IsPtrAligned(dstU, 16) && IsPtrAligned(dstV, 16))\n  {\n    if (pixelsize == 1) {\n      convert_yv16_chroma_to_yv24_sse2<uint8_t>(dstU, srcU, dstUVpitch, srcUVpitch, width, height);\n      convert_yv16_chroma_to_yv24_sse2<uint8_t>(dstV, srcV, dstUVpitch, srcUVpitch, width, height);\n    }\n    else if (pixelsize == 2) {\n      convert_yv16_chroma_to_yv24_sse2<uint16_t>(dstU, srcU, dstUVpitch, srcUVpitch, width, height);\n      convert_yv16_chroma_to_yv24_sse2<uint16_t>(dstV, srcV, dstUVpitch, srcUVpitch, width, height);\n    }\n  }\n  else\n    {\n      if (pixelsize == 1) {\n        convert_yv16_chroma_to_yv24_c<uint8_t>(dstU, srcU, dstUVpitch, srcUVpitch, width, height);\n        convert_yv16_chroma_to_yv24_c<uint8_t>(dstV, srcV, dstUVpitch, srcUVpitch, width, height);\n      } else if(pixelsize == 2) {\n        convert_yv16_chroma_to_yv24_c<uint16_t>(dstU, srcU, dstUVpitch, srcUVpitch, width, height);\n        convert_yv16_chroma_to_yv24_c<uint16_t>(dstV, srcV, dstUVpitch, srcUVpitch, width, height);\n      }\n      else {\n        convert_yv16_chroma_to_yv24_c<float>(dstU, srcU, dstUVpitch, srcUVpitch, width, height);\n        convert_yv16_chroma_to_yv24_c<float>(dstV, srcV, dstUVpitch, srcUVpitch, width, height);\n      }\n    }\n\n  env->BitBlt(dst->GetWritePtr(PLANAR_A), dst->GetPitch(PLANAR_A),\n    src->GetReadPtr(PLANAR_A), src->GetPitch(PLANAR_A), dst->GetRowSize(PLANAR_A), dst->GetHeight(PLANAR_A));\n\n}\n\n/***** YUY2 -> YUV 4:4:4   ******/\n\nvoid Convert444FromYUY2(PVideoFrame &src, PVideoFrame &dst, int pixelsize, int bits_per_pixel, IScriptEnvironment* env) {\n  AVS_UNUSED(pixelsize);\n  AVS_UNUSED(bits_per_pixel);\n  AVS_UNUSED(env);\n\n  const BYTE* srcP = src->GetReadPtr();\n  int srcPitch = src->GetPitch();\n\n  BYTE* dstY = dst->GetWritePtr(PLANAR_Y);\n  BYTE* dstU = dst->GetWritePtr(PLANAR_U);\n  BYTE* dstV = dst->GetWritePtr(PLANAR_V);\n\n  int dstPitch = dst->GetPitch();\n\n  int w = src->GetRowSize() / 2;\n  int h = src->GetHeight();\n\n  for (int y=0; y<h; y++) {\n    for (int x=0; x<w; x+=2) {\n      int x2 = x<<1;\n      dstY[x]   = srcP[x2];\n      dstU[x]   = dstU[x+1] = srcP[x2+1];\n      dstV[x]   = dstV[x+1] = srcP[x2+3];\n      dstY[x+1] = srcP[x2+2];\n    }\n    srcP+=srcPitch;\n\n    dstY+=dstPitch;\n    dstU+=dstPitch;\n    dstV+=dstPitch;\n  }\n}\n\n// YV24->YV12 float types\n// Quick simple 2x2 averaging, no mpeg2 or mpeg1 placement involved\nstatic AVS_FORCEINLINE __m128 convert_yv24_chroma_block_to_yv12_float_sse2(const __m128 &src_line0_p0, const __m128 &src_line1_p0, const __m128 &src_line0_p1, const __m128 &src_line1_p1, const __m128 &onefourth) {\n  __m128 avg1f = _mm_add_ps(src_line0_p0, src_line1_p0); // vertical sum\n  __m128 avg2f = _mm_add_ps(src_line0_p1, src_line1_p1);\n  // ABCD -> a3, a2+a3, a1, a1+a0\n  avg1f = _mm_add_ps(avg1f, _mm_castsi128_ps(_mm_srli_epi64(_mm_castps_si128(avg1f), 32)));\n  avg2f = _mm_add_ps(avg2f, _mm_castsi128_ps(_mm_srli_epi64(_mm_castps_si128(avg2f), 32)));\n  return _mm_mul_ps(_mm_shuffle_ps(avg1f, avg2f, _MM_SHUFFLE(2, 0, 2, 0)), onefourth);\n}\n\nstatic void convert_yv24_chroma_to_yv12_float_sse2(BYTE *dstp, const BYTE *srcp, int dst_pitch, int src_pitch, int dst_width, const int dst_height) {\n  int mod16_width = dst_width / 16 * 16;\n  const __m128 onefourth = _mm_set1_ps(0.25f);\n\n  for (int y = 0; y < dst_height; ++y) {\n    for (int x = 0; x < mod16_width; x += 16) {\n      __m128 src_line0_p0 = _mm_load_ps(reinterpret_cast<const float*>(srcp + x * 2));\n      __m128 src_line0_p1 = _mm_load_ps(reinterpret_cast<const float*>(srcp + x * 2 + 16));\n      __m128 src_line1_p0 = _mm_load_ps(reinterpret_cast<const float*>(srcp + x * 2 + src_pitch));\n      __m128 src_line1_p1 = _mm_load_ps(reinterpret_cast<const float*>(srcp + x * 2 + src_pitch + 16));\n\n      __m128 avg = convert_yv24_chroma_block_to_yv12_float_sse2(src_line0_p0, src_line1_p0, src_line0_p1, src_line1_p1, onefourth);\n\n      _mm_store_ps(reinterpret_cast<float*>(dstp + x), avg);\n    }\n\n    if (mod16_width != dst_width) {\n      __m128 src_line0_p0 = _mm_loadu_ps(reinterpret_cast<const float*>(srcp + dst_width * 2 - 32));\n      __m128 src_line0_p1 = _mm_loadu_ps(reinterpret_cast<const float*>(srcp + dst_width * 2 - 16));\n      __m128 src_line1_p0 = _mm_loadu_ps(reinterpret_cast<const float*>(srcp + dst_width * 2 + src_pitch - 32));\n      __m128 src_line1_p1 = _mm_loadu_ps(reinterpret_cast<const float*>(srcp + dst_width * 2 + src_pitch - 16));\n\n      __m128 avg = convert_yv24_chroma_block_to_yv12_float_sse2(src_line0_p0, src_line1_p0, src_line0_p1, src_line1_p1, onefourth);\n\n      _mm_storeu_ps(reinterpret_cast<float*>(dstp + dst_width - 16), avg);\n    }\n\n    dstp += dst_pitch;\n    srcp += src_pitch * 2;\n  }\n}\n\n// YV24->YV12, uint8_t uint16-t\n// Quick simple 2x2 averaging, no mpeg2 or mpeg1 placement involved\n// 16bit: SSE4 option\n\n// Reason of \"XOR FFFFFFFF...\":\n// Note! (((a+b+1) >> 1) + ((c+d+1) >> 1) + 1) >> 1 = (a+b+c+d+3) >> 2\n/*\n      should be (a+b+c+d+2) >> 2\n      average_round_down(average_round_up(a, b), average_round_up(c, d))\n    = average_round_down(pavgb(a, b), pavgb(c, d))\n    = ~pavgb(~pavgb(a, b), ~pavgb(c, d))\n*/\ntemplate<typename pixel_t>\nstatic AVS_FORCEINLINE __m128i convert_yv24_chroma_block_to_yv12_sse2(const __m128i &src_line0_p0, const __m128i &src_line1_p0, const __m128i &src_line0_p1, const __m128i &src_line1_p1, const __m128i &ffff, const __m128i &mask) {\n  __m128i avg1, avg2;\n  if constexpr(sizeof(pixel_t) == 1) {\n    avg1 = _mm_avg_epu8(src_line0_p0, src_line1_p0);\n    avg2 = _mm_avg_epu8(src_line0_p1, src_line1_p1);\n  }\n  else { // if constexpr(sizeof(pixel_t) == 2)\n    avg1 = _mm_avg_epu16(src_line0_p0, src_line1_p0);\n    avg2 = _mm_avg_epu16(src_line0_p1, src_line1_p1);\n  }\n\n  __m128i avg1x = _mm_xor_si128(avg1, ffff);\n  __m128i avg2x = _mm_xor_si128(avg2, ffff);\n\n  if constexpr(sizeof(pixel_t) == 1) {\n    __m128i avg1_sh = _mm_srli_epi16(avg1x, 8);\n    __m128i avg2_sh = _mm_srli_epi16(avg2x, 8);\n    avg1 = _mm_avg_epu8(avg1x, avg1_sh);\n    avg2 = _mm_avg_epu8(avg2x, avg2_sh);\n  }\n  else if constexpr(sizeof(pixel_t) == 2) {\n    __m128i avg1_sh = _mm_srli_epi32(avg1x, 16);\n    __m128i avg2_sh = _mm_srli_epi32(avg2x, 16);\n    avg1 = _mm_avg_epu16(avg1x, avg1_sh);\n    avg2 = _mm_avg_epu16(avg2x, avg2_sh);\n  }\n\n  avg1 = _mm_and_si128(avg1, mask);\n  avg2 = _mm_and_si128(avg2, mask);\n\n  __m128i packed;\n  if constexpr(sizeof(pixel_t) == 1)\n    packed = _mm_packus_epi16(avg1, avg2);\n  else if constexpr(sizeof(pixel_t) == 2) {\n    packed = _MM_PACKUS_EPI32(avg1, avg2); // SSE4.1 simul for SSE2\n  }\n  return _mm_xor_si128(packed, ffff);\n}\n\ntemplate<typename pixel_t>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nstatic AVS_FORCEINLINE __m128i convert_yv24_chroma_block_to_yv12_sse41(const __m128i &src_line0_p0, const __m128i &src_line1_p0, const __m128i &src_line0_p1, const __m128i &src_line1_p1, const __m128i &ffff, const __m128i &mask)\n{\n  __m128i avg1, avg2;\n  if constexpr (sizeof(pixel_t) == 1) {\n    avg1 = _mm_avg_epu8(src_line0_p0, src_line1_p0);\n    avg2 = _mm_avg_epu8(src_line0_p1, src_line1_p1);\n  }\n  else { // if constexpr(sizeof(pixel_t) == 2)\n    avg1 = _mm_avg_epu16(src_line0_p0, src_line1_p0);\n    avg2 = _mm_avg_epu16(src_line0_p1, src_line1_p1);\n  }\n\n  __m128i avg1x = _mm_xor_si128(avg1, ffff);\n  __m128i avg2x = _mm_xor_si128(avg2, ffff);\n\n  if constexpr (sizeof(pixel_t) == 1) {\n    __m128i avg1_sh = _mm_srli_epi16(avg1x, 8);\n    __m128i avg2_sh = _mm_srli_epi16(avg2x, 8);\n    avg1 = _mm_avg_epu8(avg1x, avg1_sh);\n    avg2 = _mm_avg_epu8(avg2x, avg2_sh);\n  }\n  else if constexpr (sizeof(pixel_t) == 2) {\n    __m128i avg1_sh = _mm_srli_epi32(avg1x, 16);\n    __m128i avg2_sh = _mm_srli_epi32(avg2x, 16);\n    avg1 = _mm_avg_epu16(avg1x, avg1_sh);\n    avg2 = _mm_avg_epu16(avg2x, avg2_sh);\n  }\n\n  avg1 = _mm_and_si128(avg1, mask);\n  avg2 = _mm_and_si128(avg2, mask);\n\n  __m128i packed;\n  if constexpr (sizeof(pixel_t) == 1)\n    packed = _mm_packus_epi16(avg1, avg2);\n  else if constexpr (sizeof(pixel_t) == 2) {\n    packed = _mm_packus_epi32(avg1, avg2); // SSE4\n  }\n  return _mm_xor_si128(packed, ffff);\n}\n\ntemplate<typename pixel_t>\nstatic void convert_yv24_chroma_to_yv12_sse2(BYTE *dstp, const BYTE *srcp, int dst_pitch, int src_pitch, int dst_width, const int dst_height) {\n  int mod16_width = dst_width / 16 * 16;\n  __m128i ffff = _mm_set1_epi8((char)0xFF);\n  __m128i mask;\n  if constexpr(sizeof(pixel_t) == 1)\n    mask = _mm_set1_epi16(0x00FF);\n  else\n    mask = _mm_set1_epi32(0x0000FFFF);\n\n\n  for (int y = 0; y < dst_height; ++y) {\n    for (int x = 0; x < mod16_width; x+=16) {\n      __m128i src_line0_p0 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp+x*2));\n      __m128i src_line0_p1 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp+x*2+16));\n      __m128i src_line1_p0 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp+x*2+src_pitch));\n      __m128i src_line1_p1 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp+x*2+src_pitch+16));\n\n      __m128i avg = convert_yv24_chroma_block_to_yv12_sse2<pixel_t>(src_line0_p0, src_line1_p0, src_line0_p1, src_line1_p1, ffff, mask);\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp+x), avg);\n    }\n\n    if (mod16_width != dst_width) {\n      __m128i src_line0_p0 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp+dst_width*2-32));\n      __m128i src_line0_p1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp+dst_width*2-16));\n      __m128i src_line1_p0 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp+dst_width*2+src_pitch-32));\n      __m128i src_line1_p1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp+dst_width*2+src_pitch-16));\n\n      __m128i avg = convert_yv24_chroma_block_to_yv12_sse2<pixel_t>(src_line0_p0, src_line1_p0, src_line0_p1, src_line1_p1, ffff, mask);\n\n      _mm_storeu_si128(reinterpret_cast<__m128i*>(dstp+dst_width-16), avg);\n    }\n\n    dstp += dst_pitch;\n    srcp += src_pitch*2;\n  }\n}\n\ntemplate<typename pixel_t>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nstatic void convert_yv24_chroma_to_yv12_sse41(BYTE *dstp, const BYTE *srcp, int dst_pitch, int src_pitch, int dst_width, const int dst_height)\n{\n  int mod16_width = dst_width / 16 * 16;\n  __m128i ffff = _mm_set1_epi8((char)0xFF);\n  __m128i mask;\n  if constexpr (sizeof(pixel_t) == 1)\n    mask = _mm_set1_epi16(0x00FF);\n  else\n    mask = _mm_set1_epi32(0x0000FFFF);\n\n\n  for (int y = 0; y < dst_height; ++y) {\n    for (int x = 0; x < mod16_width; x += 16) {\n      __m128i src_line0_p0 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x * 2));\n      __m128i src_line0_p1 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x * 2 + 16));\n      __m128i src_line1_p0 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x * 2 + src_pitch));\n      __m128i src_line1_p1 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x * 2 + src_pitch + 16));\n\n      __m128i avg = convert_yv24_chroma_block_to_yv12_sse41<pixel_t>(src_line0_p0, src_line1_p0, src_line0_p1, src_line1_p1, ffff, mask);\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x), avg);\n    }\n\n    if (mod16_width != dst_width) {\n      __m128i src_line0_p0 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + dst_width * 2 - 32));\n      __m128i src_line0_p1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + dst_width * 2 - 16));\n      __m128i src_line1_p0 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + dst_width * 2 + src_pitch - 32));\n      __m128i src_line1_p1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + dst_width * 2 + src_pitch - 16));\n\n      __m128i avg = convert_yv24_chroma_block_to_yv12_sse41<pixel_t>(src_line0_p0, src_line1_p0, src_line0_p1, src_line1_p1, ffff, mask);\n\n      _mm_storeu_si128(reinterpret_cast<__m128i*>(dstp + dst_width - 16), avg);\n    }\n\n    dstp += dst_pitch;\n    srcp += src_pitch * 2;\n  }\n}\n\n#ifdef X86_32\n\nstatic AVS_FORCEINLINE __m64 convert_yv24_chroma_block_to_yv12_isse(const __m64 &src_line0_p0, const __m64 &src_line1_p0, const __m64 &src_line0_p1, const __m64 &src_line1_p1, const __m64 &ffff, const __m64 &mask) {\n  __m64 avg1 = _mm_avg_pu8(src_line0_p0, src_line1_p0);\n  __m64 avg2 = _mm_avg_pu8(src_line0_p1, src_line1_p1);\n\n  __m64 avg1x = _mm_xor_si64(avg1, ffff);\n  __m64 avg2x = _mm_xor_si64(avg2, ffff);\n\n  __m64 avg1_sh = _mm_srli_pi16(avg1x, 8);\n  __m64 avg2_sh = _mm_srli_pi16(avg2x, 8);\n\n  avg1 = _mm_avg_pu8(avg1x, avg1_sh);\n  avg2 = _mm_avg_pu8(avg2x, avg2_sh);\n\n  avg1 = _mm_and_si64(avg1, mask);\n  avg2 = _mm_and_si64(avg2, mask);\n\n  __m64 packed = _mm_packs_pu16(avg1, avg2);\n  return _mm_xor_si64(packed, ffff);\n}\n\nstatic void convert_yv24_chroma_to_yv12_isse(BYTE *dstp, const BYTE *srcp, int dst_pitch, int src_pitch, int dst_width, const int dst_height) {\n  int mod8_width = dst_width / 8 * 8;\n\n  __m64 ffff = _mm_set1_pi8((char)0xFF);\n  __m64 mask = _mm_set1_pi16(0x00FF);\n\n  for (int y = 0; y < dst_height; ++y) {\n    for (int x = 0; x < mod8_width; x+=8) {\n      __m64 src_line0_p0 = *reinterpret_cast<const __m64*>(srcp+x*2);\n      __m64 src_line0_p1 = *reinterpret_cast<const __m64*>(srcp+x*2+8);\n      __m64 src_line1_p0 = *reinterpret_cast<const __m64*>(srcp+x*2+src_pitch);\n      __m64 src_line1_p1 = *reinterpret_cast<const __m64*>(srcp+x*2+src_pitch+8);\n\n      __m64 avg = convert_yv24_chroma_block_to_yv12_isse(src_line0_p0, src_line1_p0, src_line0_p1, src_line1_p1, ffff, mask);\n\n      *reinterpret_cast<__m64*>(dstp+x) = avg;\n    }\n\n    if (mod8_width != dst_width) {\n      __m64 src_line0_p0 = *reinterpret_cast<const __m64*>(srcp+dst_width*2-16);\n      __m64 src_line0_p1 = *reinterpret_cast<const __m64*>(srcp+dst_width*2-8);\n      __m64 src_line1_p0 = *reinterpret_cast<const __m64*>(srcp+dst_width*2+src_pitch-16);\n      __m64 src_line1_p1 = *reinterpret_cast<const __m64*>(srcp+dst_width*2+src_pitch-8);\n\n      __m64 avg = convert_yv24_chroma_block_to_yv12_isse(src_line0_p0, src_line1_p0, src_line0_p1, src_line1_p1, ffff, mask);\n\n      *reinterpret_cast<__m64*>(dstp+dst_width-8) = avg;\n    }\n\n    dstp += dst_pitch;\n    srcp += src_pitch*2;\n  }\n  _mm_empty();\n}\n\n#endif // X86_32\n\ntemplate<typename pixel_t>\nstatic void convert_yv24_chroma_to_yv12_c(BYTE *dstp8, const BYTE *srcp8, int dst_pitch, int src_pitch, int dst_width, const int dst_height) {\n  const pixel_t *srcp = reinterpret_cast<const pixel_t *>(srcp8);\n  pixel_t *dstp = reinterpret_cast<pixel_t *>(dstp8);\n  dst_pitch /= sizeof(pixel_t);\n  src_pitch /= sizeof(pixel_t);\n  for (int y = 0; y < dst_height; y++) {\n    for (int x = 0; x < dst_width; x++) {\n      if constexpr (sizeof(pixel_t) == 4)\n        dstp[x] = (srcp[x * 2] + srcp[x * 2 + 1] + srcp[x * 2 + src_pitch] + srcp[x * 2 + src_pitch + 1]) * 0.25f; // /4\n      else\n        dstp[x] = (srcp[x * 2] + srcp[x * 2 + 1] + srcp[x * 2 + src_pitch] + srcp[x * 2 + src_pitch + 1] + 2) >> 2;\n    }\n    srcp += src_pitch * 2;\n    dstp += dst_pitch;\n  }\n}\n\n// Quick YV24->YV16 chroma\nstatic AVS_FORCEINLINE __m128 convert_yv24_chroma_block_to_yv16_float_sse2(const __m128 &src_line0_p0, const __m128 &src_line0_p1, const __m128 &half) {\n  // A3 A2 A1 A0 B3 B2 B1 B0 -> A3 + A2, A1 + A0, B3 + B2, B1 + B0\n  __m128 avg1 = src_line0_p0;\n  __m128 avg2 = src_line0_p1;\n  // ABCD -> a3, a2+a3, a1, a1+a0\n  avg1 = _mm_add_ps(avg1, _mm_castsi128_ps(_mm_srli_epi64(_mm_castps_si128(avg1), 32)));\n  // ABCD -> b3, b2+b3, b1, b1+a0\n  avg2 = _mm_add_ps(avg2, _mm_castsi128_ps(_mm_srli_epi64(_mm_castps_si128(avg2), 32)));\n  return _mm_mul_ps(_mm_shuffle_ps(avg1, avg2, _MM_SHUFFLE(2, 0, 2, 0)), half);\n}\n\n// min width: dst_width >= 16\nstatic void convert_yv24_chroma_to_yv16_float_sse2(BYTE *dstp, const BYTE *srcp, int dst_pitch, int src_pitch, int dst_width, const int dst_height) {\n  int mod16_width = dst_width / 16 * 16;\n  const __m128 half = _mm_set1_ps(0.5f); // averaging\n\n  for (int y = 0; y < dst_height; ++y) {\n    for (int x = 0; x < mod16_width; x += 16) {\n      __m128 src_line0_p0 = _mm_load_ps(reinterpret_cast<const float*>(srcp + x * 2));\n      __m128 src_line0_p1 = _mm_load_ps(reinterpret_cast<const float*>(srcp + x * 2 + 16));\n\n      __m128 avg = convert_yv24_chroma_block_to_yv16_float_sse2(src_line0_p0, src_line0_p1, half);\n\n      _mm_store_ps(reinterpret_cast<float*>(dstp + x), avg);\n    }\n\n    if (mod16_width != dst_width) {\n      __m128 src_line0_p0 = _mm_loadu_ps(reinterpret_cast<const float*>(srcp + dst_width * 2 - 32));\n      __m128 src_line0_p1 = _mm_loadu_ps(reinterpret_cast<const float*>(srcp + dst_width * 2 - 16));\n\n      __m128 avg = convert_yv24_chroma_block_to_yv16_float_sse2(src_line0_p0, src_line0_p1, half);\n\n      _mm_storeu_ps(reinterpret_cast<float*>(dstp + dst_width - 16), avg);\n    }\n\n    dstp += dst_pitch;\n    srcp += src_pitch;\n  }\n}\n\n// 16 bit: SSE4 option\n// uint8_t, uint16_t\ntemplate<typename pixel_t>\nstatic AVS_FORCEINLINE __m128i convert_yv24_chroma_block_to_yv16_sse2(const __m128i &src_line0_p0, const __m128i &src_line0_p1, const __m128i &mask) {\n  __m128i avg1, avg2;\n\n  if constexpr(sizeof(pixel_t) == 1) {\n    __m128i avg1_sh = _mm_srli_epi16(src_line0_p0, 8);\n    __m128i avg2_sh = _mm_srli_epi16(src_line0_p1, 8);\n\n    avg1 = _mm_avg_epu8(src_line0_p0, avg1_sh);\n    avg2 = _mm_avg_epu8(src_line0_p1, avg2_sh);\n  }\n  else { // if constexpr(sizeof(pixel_t) == 2)\n    __m128i avg1_sh = _mm_srli_epi32(src_line0_p0, 16);\n    __m128i avg2_sh = _mm_srli_epi32(src_line0_p1, 16);\n\n    avg1 = _mm_avg_epu16(src_line0_p0, avg1_sh);\n    avg2 = _mm_avg_epu16(src_line0_p1, avg2_sh);\n  }\n\n  avg1 = _mm_and_si128(avg1, mask);\n  avg2 = _mm_and_si128(avg2, mask);\n\n  __m128i packed;\n  if constexpr(sizeof(pixel_t) == 1)\n    packed = _mm_packus_epi16(avg1, avg2);\n  else { // if constexpr(sizeof(pixel_t) == 2)\n    packed = _MM_PACKUS_EPI32(avg1, avg2); // SSE4.1 simul for SSE2\n  }\n  return packed;\n}\n\ntemplate<typename pixel_t>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nstatic AVS_FORCEINLINE __m128i convert_yv24_chroma_block_to_yv16_sse41(const __m128i &src_line0_p0, const __m128i &src_line0_p1, const __m128i &mask)\n{\n  __m128i avg1, avg2;\n\n  if constexpr (sizeof(pixel_t) == 1) {\n    __m128i avg1_sh = _mm_srli_epi16(src_line0_p0, 8);\n    __m128i avg2_sh = _mm_srli_epi16(src_line0_p1, 8);\n\n    avg1 = _mm_avg_epu8(src_line0_p0, avg1_sh);\n    avg2 = _mm_avg_epu8(src_line0_p1, avg2_sh);\n  }\n  else { // if constexpr(sizeof(pixel_t) == 2)\n    __m128i avg1_sh = _mm_srli_epi32(src_line0_p0, 16);\n    __m128i avg2_sh = _mm_srli_epi32(src_line0_p1, 16);\n\n    avg1 = _mm_avg_epu16(src_line0_p0, avg1_sh);\n    avg2 = _mm_avg_epu16(src_line0_p1, avg2_sh);\n  }\n\n  avg1 = _mm_and_si128(avg1, mask);\n  avg2 = _mm_and_si128(avg2, mask);\n\n  __m128i packed;\n  if constexpr (sizeof(pixel_t) == 1)\n    packed = _mm_packus_epi16(avg1, avg2);\n  else { // if constexpr(sizeof(pixel_t) == 2)\n    packed = _mm_packus_epi32(avg1, avg2); // SSE4\n  }\n  return packed;\n}\n\n// uint8_t, uint16_t\ntemplate<typename pixel_t>\nstatic void convert_yv24_chroma_to_yv16_sse2(BYTE *dstp, const BYTE *srcp, int dst_pitch, int src_pitch, int dst_width, const int dst_height) {\n  int mod16_width = dst_width / 16 * 16;\n\n  __m128i mask;\n  if constexpr(sizeof(pixel_t) == 1)\n    mask = _mm_set1_epi16(0x00FF);\n  else\n    mask = _mm_set1_epi32(0x0000FFFF);\n\n  for (int y = 0; y < dst_height; ++y) {\n    for (int x = 0; x < mod16_width; x+=16) {\n      __m128i src_line0_p0 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp+x*2));\n      __m128i src_line0_p1 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp+x*2+16));\n\n      __m128i avg = convert_yv24_chroma_block_to_yv16_sse2<pixel_t>(src_line0_p0, src_line0_p1, mask);\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp+x), avg);\n    }\n\n    if (mod16_width != dst_width) {\n      __m128i src_line0_p0 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp+dst_width*2-32));\n      __m128i src_line0_p1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp+dst_width*2-16));\n\n      __m128i avg = convert_yv24_chroma_block_to_yv16_sse2<pixel_t>(src_line0_p0, src_line0_p1, mask);\n\n      _mm_storeu_si128(reinterpret_cast<__m128i*>(dstp+dst_width-16), avg);\n    }\n\n    dstp += dst_pitch;\n    srcp += src_pitch;\n  }\n}\n\ntemplate<typename pixel_t>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nstatic void convert_yv24_chroma_to_yv16_sse41(BYTE *dstp, const BYTE *srcp, int dst_pitch, int src_pitch, int dst_width, const int dst_height)\n{\n  int mod16_width = dst_width / 16 * 16;\n\n  __m128i mask;\n  if constexpr (sizeof(pixel_t) == 1)\n    mask = _mm_set1_epi16(0x00FF);\n  else\n    mask = _mm_set1_epi32(0x0000FFFF);\n\n  for (int y = 0; y < dst_height; ++y) {\n    for (int x = 0; x < mod16_width; x += 16) {\n      __m128i src_line0_p0 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x * 2));\n      __m128i src_line0_p1 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x * 2 + 16));\n\n      __m128i avg = convert_yv24_chroma_block_to_yv16_sse41<pixel_t>(src_line0_p0, src_line0_p1, mask);\n\n      _mm_store_si128(reinterpret_cast<__m128i*>(dstp + x), avg);\n    }\n\n    if (mod16_width != dst_width) {\n      __m128i src_line0_p0 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + dst_width * 2 - 32));\n      __m128i src_line0_p1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(srcp + dst_width * 2 - 16));\n\n      __m128i avg = convert_yv24_chroma_block_to_yv16_sse41<pixel_t>(src_line0_p0, src_line0_p1, mask);\n\n      _mm_storeu_si128(reinterpret_cast<__m128i*>(dstp + dst_width - 16), avg);\n    }\n\n    dstp += dst_pitch;\n    srcp += src_pitch;\n  }\n}\n\ntemplate<typename pixel_t>\nstatic void convert_yv24_chroma_to_yv16_c(BYTE *dstp8, const BYTE *srcp8, int dst_pitch, int src_pitch, int dst_width, const int dst_height) {\n  const pixel_t *srcp = reinterpret_cast<const pixel_t *>(srcp8);\n  pixel_t *dstp = reinterpret_cast<pixel_t *>(dstp8);\n  dst_pitch /= sizeof(pixel_t);\n  src_pitch /= sizeof(pixel_t);\n  for (int y=0; y < dst_height; y++) {\n    for (int x=0; x < dst_width; x++) {\n      if constexpr (sizeof(pixel_t) == 4)\n        dstp[x] = (srcp[x * 2] + srcp[x * 2 + 1]) * 0.5f;\n      else\n        dstp[x] = (srcp[x * 2] + srcp[x * 2 + 1] + 1) >> 1;\n    }\n    srcp+=src_pitch;\n    dstp+=dst_pitch;\n  }\n}\n\nvoid ConvertYToYV12Chroma(BYTE *dst, BYTE *src, int dstpitch, int srcpitch, int pixelsize, int w, int h, IScriptEnvironment* env)\n{\n  if ((env->GetCPUFlags() & CPUF_SSE2) && IsPtrAligned(src, 16) && IsPtrAligned(dst, 16))\n  {\n    if (pixelsize == 1)\n      convert_yv24_chroma_to_yv12_sse2<uint8_t>(dst, src, dstpitch, srcpitch, w, h);\n    else if (pixelsize == 2) {\n      if (env->GetCPUFlags() & CPUF_SSE4) { // packus_epi32\n        convert_yv24_chroma_to_yv12_sse41<uint16_t>(dst, src, dstpitch, srcpitch, w*pixelsize, h);\n      }\n      else {\n        convert_yv24_chroma_to_yv12_sse2<uint16_t>(dst, src, dstpitch, srcpitch, w*pixelsize, h);\n      }\n    }\n    else\n      convert_yv24_chroma_to_yv12_float_sse2(dst, src, dstpitch, srcpitch, w*pixelsize, h);\n  }\n  else {\n    if(pixelsize==1)\n      convert_yv24_chroma_to_yv12_c<uint8_t>(dst, src, dstpitch, srcpitch, w, h);\n    else if (pixelsize == 2)\n      convert_yv24_chroma_to_yv12_c<uint16_t>(dst, src, dstpitch, srcpitch, w, h);\n    else // if (pixelsize == 4)\n      convert_yv24_chroma_to_yv12_c<float>(dst, src, dstpitch, srcpitch, w, h);\n  }\n}\n\nvoid ConvertYToYV16Chroma(BYTE *dst, BYTE *src, int dstpitch, int srcpitch, int pixelsize, int w, int h, IScriptEnvironment* env)\n{\n  if ((env->GetCPUFlags() & CPUF_SSE2) && IsPtrAligned(src, 16) && IsPtrAligned(dst, 16)\n    && w * pixelsize >= 16) // last chunk is also simd, but working on a right-aligned 32 bytes -> 8 bytes. Also simd but unaligned.\n  {\n    if (pixelsize == 1)\n      convert_yv24_chroma_to_yv16_sse2<uint8_t>(dst, src, dstpitch, srcpitch, w, h);\n    else if (pixelsize == 2) {\n      if (env->GetCPUFlags() & CPUF_SSE4) { // packus_epi32\n        convert_yv24_chroma_to_yv16_sse41<uint16_t>(dst, src, dstpitch, srcpitch, w*pixelsize, h);\n      }\n      else {\n        convert_yv24_chroma_to_yv16_sse2<uint16_t>(dst, src, dstpitch, srcpitch, w*pixelsize, h);\n      }\n    }\n    else {\n      convert_yv24_chroma_to_yv16_float_sse2(dst, src, dstpitch, srcpitch, w*pixelsize, h);\n    }\n  }\n  else {\n    if(pixelsize==1)\n      convert_yv24_chroma_to_yv16_c<uint8_t>(dst, src, dstpitch, srcpitch, w, h);\n    else if (pixelsize == 2)\n      convert_yv24_chroma_to_yv16_c<uint16_t>(dst, src, dstpitch, srcpitch, w, h);\n    else // if (pixelsize == 4)\n      convert_yv24_chroma_to_yv16_c<float>(dst, src, dstpitch, srcpitch, w, h);\n  }\n}\n\nvoid Convert444ToYV16(PVideoFrame &src, PVideoFrame &dst, int pixelsize, int bits_per_pixel, IScriptEnvironment* env)\n{\n  AVS_UNUSED(bits_per_pixel);\n  env->BitBlt(dst->GetWritePtr(PLANAR_Y), dst->GetPitch(PLANAR_Y),\n    src->GetReadPtr(PLANAR_Y), src->GetPitch(), dst->GetRowSize(PLANAR_Y), dst->GetHeight());\n\n  const BYTE* srcU = src->GetReadPtr(PLANAR_U);\n  const BYTE* srcV = src->GetReadPtr(PLANAR_V);\n\n  int srcUVpitch = src->GetPitch(PLANAR_U);\n\n  BYTE* dstU = dst->GetWritePtr(PLANAR_U);\n  BYTE* dstV = dst->GetWritePtr(PLANAR_V);\n\n  int dstUVpitch = dst->GetPitch(PLANAR_U);\n\n  int w = dst->GetRowSize(PLANAR_U);\n  int h = dst->GetHeight(PLANAR_U);\n\n  if ((env->GetCPUFlags() & CPUF_SSE2) && IsPtrAligned(srcU, 16) && IsPtrAligned(srcV, 16) && IsPtrAligned(dstU, 16) && IsPtrAligned(dstV, 16))\n  {\n    if (pixelsize == 1) {\n      convert_yv24_chroma_to_yv16_sse2<uint8_t>(dstU, srcU, dstUVpitch, srcUVpitch, w, h);\n      convert_yv24_chroma_to_yv16_sse2<uint8_t>(dstV, srcV, dstUVpitch, srcUVpitch, w, h);\n    }\n    else if (pixelsize == 2) {\n      if (env->GetCPUFlags() & CPUF_SSE4) { // packus_epi32\n        convert_yv24_chroma_to_yv16_sse41<uint16_t>(dstU, srcU, dstUVpitch, srcUVpitch, w, h);\n        convert_yv24_chroma_to_yv16_sse41<uint16_t>(dstV, srcV, dstUVpitch, srcUVpitch, w, h);\n      }\n      else {\n        convert_yv24_chroma_to_yv16_sse2<uint16_t>(dstU, srcU, dstUVpitch, srcUVpitch, w, h);\n        convert_yv24_chroma_to_yv16_sse2<uint16_t>(dstV, srcV, dstUVpitch, srcUVpitch, w, h);\n      }\n    }\n    else {\n      convert_yv24_chroma_to_yv16_float_sse2(dstU, srcU, dstUVpitch, srcUVpitch, w, h);\n      convert_yv24_chroma_to_yv16_float_sse2(dstV, srcV, dstUVpitch, srcUVpitch, w, h);\n    }\n  }\n  else {\n      if(pixelsize==1) {\n        convert_yv24_chroma_to_yv16_c<uint8_t>(dstU, srcU, dstUVpitch, srcUVpitch, w, h);\n        convert_yv24_chroma_to_yv16_c<uint8_t>(dstV, srcV, dstUVpitch, srcUVpitch, w, h);\n      }\n      else if (pixelsize == 2) {\n        convert_yv24_chroma_to_yv16_c<uint16_t>(dstU, srcU, dstUVpitch, srcUVpitch, w, h);\n        convert_yv24_chroma_to_yv16_c<uint16_t>(dstV, srcV, dstUVpitch, srcUVpitch, w, h);\n      }\n      else { // if (pixelsize == 4)\n        convert_yv24_chroma_to_yv16_c<float>(dstU, srcU, dstUVpitch, srcUVpitch, w, h);\n        convert_yv24_chroma_to_yv16_c<float>(dstV, srcV, dstUVpitch, srcUVpitch, w, h);\n      }\n  }\n\n  env->BitBlt(dst->GetWritePtr(PLANAR_A), dst->GetPitch(PLANAR_A),\n    src->GetReadPtr(PLANAR_A), src->GetPitch(PLANAR_A), dst->GetRowSize(PLANAR_A), dst->GetHeight(PLANAR_A));\n}\n\n\nvoid Convert444ToYV12(PVideoFrame &src, PVideoFrame &dst, int pixelsize, int bits_per_pixel, IScriptEnvironment* env)\n{\n  AVS_UNUSED(bits_per_pixel);\n  env->BitBlt(dst->GetWritePtr(PLANAR_Y), dst->GetPitch(PLANAR_Y),\n    src->GetReadPtr(PLANAR_Y), src->GetPitch(), dst->GetRowSize(PLANAR_Y), dst->GetHeight());\n\n  const BYTE* srcU = src->GetReadPtr(PLANAR_U);\n  const BYTE* srcV = src->GetReadPtr(PLANAR_V);\n\n  int srcUVpitch = src->GetPitch(PLANAR_U);\n\n  BYTE* dstU = dst->GetWritePtr(PLANAR_U);\n  BYTE* dstV = dst->GetWritePtr(PLANAR_V);\n\n  int dstUVpitch = dst->GetPitch(PLANAR_U);\n\n  int w = dst->GetRowSize(PLANAR_U);\n  int h = dst->GetHeight(PLANAR_U);\n\n  if ((env->GetCPUFlags() & CPUF_SSE2) && IsPtrAligned(srcU, 16) && IsPtrAligned(srcV, 16) && IsPtrAligned(dstU, 16) && IsPtrAligned(dstV, 16))\n  {\n    if (pixelsize == 1) {\n      convert_yv24_chroma_to_yv12_sse2<uint8_t>(dstU, srcU, dstUVpitch, srcUVpitch, w, h);\n      convert_yv24_chroma_to_yv12_sse2<uint8_t>(dstV, srcV, dstUVpitch, srcUVpitch, w, h);\n    }\n    else if (pixelsize == 2) {\n      if (env->GetCPUFlags() & CPUF_SSE4) {  // packus_epi32\n        convert_yv24_chroma_to_yv12_sse41<uint16_t>(dstU, srcU, dstUVpitch, srcUVpitch, w, h);\n        convert_yv24_chroma_to_yv12_sse41<uint16_t>(dstV, srcV, dstUVpitch, srcUVpitch, w, h);\n      }\n      else {\n        convert_yv24_chroma_to_yv12_sse2<uint16_t>(dstU, srcU, dstUVpitch, srcUVpitch, w, h);\n        convert_yv24_chroma_to_yv12_sse2<uint16_t>(dstV, srcV, dstUVpitch, srcUVpitch, w, h);\n      }\n    }\n    else {\n      convert_yv24_chroma_to_yv12_float_sse2(dstU, srcU, dstUVpitch, srcUVpitch, w, h);\n      convert_yv24_chroma_to_yv12_float_sse2(dstV, srcV, dstUVpitch, srcUVpitch, w, h);\n    }\n  }\n  else {\n#ifdef X86_32\n    if ((pixelsize == 1) && (env->GetCPUFlags() & CPUF_INTEGER_SSE))\n    {\n      convert_yv24_chroma_to_yv12_isse(dstU, srcU, dstUVpitch, srcUVpitch, w, h);\n      convert_yv24_chroma_to_yv12_isse(dstV, srcV, dstUVpitch, srcUVpitch, w, h);\n    }\n    else\n#endif\n    {\n      if(pixelsize==1) {\n        convert_yv24_chroma_to_yv12_c<uint8_t>(dstU, srcU, dstUVpitch, srcUVpitch, w, h);\n        convert_yv24_chroma_to_yv12_c<uint8_t>(dstV, srcV, dstUVpitch, srcUVpitch, w, h);\n      }\n      else if (pixelsize == 2) {\n        convert_yv24_chroma_to_yv12_c<uint16_t>(dstU, srcU, dstUVpitch, srcUVpitch, w, h);\n        convert_yv24_chroma_to_yv12_c<uint16_t>(dstV, srcV, dstUVpitch, srcUVpitch, w, h);\n      }\n      else { // if (pixelsize == 4)\n        convert_yv24_chroma_to_yv12_c<float>(dstU, srcU, dstUVpitch, srcUVpitch, w, h);\n        convert_yv24_chroma_to_yv12_c<float>(dstV, srcV, dstUVpitch, srcUVpitch, w, h);\n      }\n    }\n  }\n\n  env->BitBlt(dst->GetWritePtr(PLANAR_A), dst->GetPitch(PLANAR_A),\n    src->GetReadPtr(PLANAR_A), src->GetPitch(PLANAR_A), dst->GetRowSize(PLANAR_A), dst->GetHeight(PLANAR_A));\n\n}\n\n/*****   YUV 4:4:4 -> YUY2   *******/\n\nvoid Convert444ToYUY2(PVideoFrame &src, PVideoFrame &dst, int pixelsize, int bits_per_pixel, IScriptEnvironment* env) {\n  AVS_UNUSED(bits_per_pixel);\n  AVS_UNUSED(env);\n\n  const BYTE* srcY = src->GetReadPtr(PLANAR_Y);\n  const BYTE* srcU = src->GetReadPtr(PLANAR_U);\n  const BYTE* srcV = src->GetReadPtr(PLANAR_V);\n\n  int srcPitch = src->GetPitch();\n\n  BYTE* dstP = dst->GetWritePtr();\n\n  int dstPitch = dst->GetPitch();\n\n  int w = src->GetRowSize() / pixelsize;\n  int h = src->GetHeight();\n\n  for (int y=0; y<h; y++) {\n    for (int x=0; x<w; x+=2) {\n      int x2 = x<<1;\n      dstP[x2]   = srcY[x];\n      dstP[x2+1] = (srcU[x] + srcU[x+1] + 1)>>1;\n      dstP[x2+2] = srcY[x+1];\n      dstP[x2+3] = (srcV[x] + srcV[x+1] + 1)>>1;\n    }\n    srcY+=srcPitch;\n    srcU+=srcPitch;\n    srcV+=srcPitch;\n    dstP+=dstPitch;\n  }\n}\n"
  },
  {
    "path": "avs_core/filters/overlay/intel/444convert_sse.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// Overlay (c) 2003, 2004 by Klaus Post\n\n#ifndef __444Convert_h\n#define __444Convert_h\n\n#include <avisynth.h>\n\nvoid Convert444FromYV16(PVideoFrame &src, PVideoFrame &dst, int pixelsize, int bits_per_pixel, IScriptEnvironment* env);\nvoid Convert444FromYV12(PVideoFrame &src, PVideoFrame &dst, int pixelsize, int bits_per_pixel, IScriptEnvironment* env);\nvoid Convert444FromYUY2(PVideoFrame &src, PVideoFrame &dst, int pixelsize, int bits_per_pixel, IScriptEnvironment* env);\nvoid Convert444ToYV16(PVideoFrame &src, PVideoFrame &dst, int pixelsize, int bits_per_pixel, IScriptEnvironment* env);\nvoid Convert444ToYV12(PVideoFrame &src, PVideoFrame &dst, int pixelsize, int bits_per_pixel, IScriptEnvironment* env);\nvoid Convert444ToYUY2(PVideoFrame &src, PVideoFrame &dst, int pixelsize, int bits_per_pixel, IScriptEnvironment* env);\nvoid ConvertYToYV12Chroma(BYTE *dst, BYTE *src, int dstpitch, int srcpitch, int pixelsize, int w, int h, IScriptEnvironment* env);\nvoid ConvertYToYV16Chroma(BYTE *dst, BYTE *src, int dstpitch, int srcpitch, int pixelsize, int w, int h, IScriptEnvironment* env);\n\n#endif //444Convert"
  },
  {
    "path": "avs_core/filters/overlay/intel/OF_multiply_avx2.cpp",
    "content": "// Avisynth+\n// https://avs-plus.net\n//\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include \"avisynth.h\"\n#include \"OF_multiply_avx2.h\"\n\n#include <stdint.h>\n\n#ifdef _MSC_VER\n#include <intrin.h>\n#else\n#include <x86intrin.h>\n#endif\n#include <immintrin.h>\n\ntemplate<typename pixel_t>\nstatic AVS_FORCEINLINE __m256 Eightpixels_to_floats(const pixel_t* src) {\n  __m256i srci;\n  if constexpr (sizeof(pixel_t) == 1) {\n    srci = _mm256_cvtepu8_epi32(_mm_loadl_epi64(reinterpret_cast<const __m128i*>(src)));\n  }\n  else {\n    srci = _mm256_cvtepu16_epi32(_mm_loadu_si128(reinterpret_cast<const __m128i*>(src)));\n  }\n  return _mm256_cvtepi32_ps(srci);\n}\n\ntemplate<typename pixel_t>\nstatic AVS_FORCEINLINE __m256 EightChromapixels_to_floats(const pixel_t* src, const __m256i half) {\n  __m256i srci;\n  if constexpr (sizeof(pixel_t) == 1) {\n    srci = _mm256_cvtepu8_epi32(_mm_loadl_epi64(reinterpret_cast<const __m128i*>(src)));\n  }\n  else {\n    srci = _mm256_cvtepu16_epi32(_mm_loadu_si128(reinterpret_cast<const __m128i*>(src)));\n  }\n  srci = _mm256_sub_epi32(srci, half);\n  return _mm256_cvtepi32_ps(srci);\n}\n\ntemplate<typename pixel_t>\nstatic AVS_FORCEINLINE void Store_Eightpixels(pixel_t* dst, __m256 what, const __m256 rounder) {\n  what = _mm256_add_ps(what, rounder); // round\n  __m256i si32 = _mm256_cvttps_epi32(what); // truncate\n  __m256i result = _mm256_packus_epi32(si32, si32); // only low 8 words needed\n  result = _mm256_permute4x64_epi64(result, (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6));\n  __m128i result128 = _mm256_castsi256_si128(result);\n  if constexpr (sizeof(pixel_t) == 1) {\n    __m128i result64 = _mm_packus_epi16(result128, result128);\n    _mm_storel_epi64(reinterpret_cast<__m128i*>(dst), result64);\n  } else {\n    _mm_storeu_si128(reinterpret_cast<__m128i*>(dst), result128);\n  }\n}\n\ntemplate<typename pixel_t>\nstatic AVS_FORCEINLINE void Store_EightChromapixels(pixel_t* dst, __m256 what, const __m256 half_plus_rounder) {\n  what = _mm256_add_ps(what, half_plus_rounder); // chroma offset back with rounder\n  __m256i si32 = _mm256_cvttps_epi32(what); // truncate\n  __m256i result = _mm256_packus_epi32(si32, si32); // only low 8 words needed\n  result = _mm256_permute4x64_epi64(result, (0 << 0) | (2 << 2) | (1 << 4) | (3 << 6));\n  __m128i result128 = _mm256_castsi256_si128(result);\n  if constexpr (sizeof(pixel_t) == 1) {\n    __m128i result64 = _mm_packus_epi16(result128, result128);\n    _mm_storel_epi64(reinterpret_cast<__m128i*>(dst), result64);\n  }\n  else {\n    _mm_storeu_si128(reinterpret_cast<__m128i*>(dst), result128);\n  }\n}\n\n\ntemplate<typename pixel_t, bool opacity_is_full, bool has_mask>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"avx2\")))\n#endif\nvoid of_multiply_avx2(\n  int bits_per_pixel,\n  const float opacity_f,\n  const int opacity,\n  int width, int height,\n  const pixel_t* ovY,\n  int overlaypitch,\n  pixel_t* baseY, pixel_t* baseU, pixel_t* baseV,\n  int basepitch,\n  const pixel_t* maskY, const pixel_t* maskU, const pixel_t* maskV,\n  int maskpitch\n)\n{\n  const int max_pixel_value = (sizeof(pixel_t) == 1) ? 255 : (1 << bits_per_pixel) - 1;\n  const float factor = 1.0f / max_pixel_value;\n  const int half_i = sizeof(pixel_t) == 1 ? 128 : 1 << (bits_per_pixel - 1);\n  const float half_f = (float)half_i;\n\n  float factor_mul_opacity;\n  if constexpr (opacity_is_full)\n    factor_mul_opacity = factor * 1.0f;\n  else\n    factor_mul_opacity = factor * opacity_f;\n\n  auto opacity_simd = _mm256_set1_ps(opacity_f);\n  auto factor_simd = _mm256_set1_ps(factor);\n  auto factor_mul_opacity_simd = _mm256_set1_ps(factor_mul_opacity);\n  auto one_ps_simd = _mm256_set1_ps(1.0f);\n  const __m256i half_i_simd = _mm256_set1_epi32(half_i);\n  const __m256 half_and_rounder_simd = _mm256_set1_ps(half_f + 0.5f);\n  const __m256 rounder_simd = _mm256_set1_ps(0.5f);\n\n  const int wMod8 = width / 8 * 8;\n\n  // start processing\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wMod8; x += 8) {\n      __m256 Y, U, V;\n      // 8 pixels at a time. 8 or 16 bits to floats\n      __m256 ovY_ps = Eightpixels_to_floats<pixel_t>(ovY + x);\n\n      // generic, 8-16 bits\n      if constexpr (has_mask) {\n        __m256 final_opacity;\n        auto overlay_opacity_minus1 = _mm256_sub_ps(_mm256_mul_ps(ovY_ps, factor_simd), one_ps_simd); // ovY[x] * factor - 1.0f;\n\n        __m256 maskY_ps = Eightpixels_to_floats<pixel_t>(maskY + x);\n        final_opacity = _mm256_mul_ps(maskY_ps, factor_mul_opacity_simd); // maskY[x] * factor_mul_opacity;\n        auto Yfactor = _mm256_add_ps(one_ps_simd, _mm256_mul_ps(overlay_opacity_minus1, final_opacity)); // 1.0f + overlay_opacity_minus1 * final_opacity;\n        __m256 baseY_ps = Eightpixels_to_floats<pixel_t>(baseY + x);\n        Y = _mm256_mul_ps(baseY_ps, Yfactor); // Y = (int)(baseY[x] * Yfactor);\n\n        __m256 maskU_ps = Eightpixels_to_floats<pixel_t>(maskU + x);\n        final_opacity = _mm256_mul_ps(maskU_ps, factor_mul_opacity_simd); // maskY[x] * factor_mul_opacity;\n        auto Ufactor = _mm256_add_ps(one_ps_simd, _mm256_mul_ps(overlay_opacity_minus1, final_opacity)); // 1.0f + overlay_opacity_minus1 * final_opacity;\n        __m256 baseU_ps = EightChromapixels_to_floats<pixel_t>(baseU + x, half_i_simd);\n        U = _mm256_mul_ps(baseU_ps, Ufactor); // U = (int)((baseU[x] - half_i) * Ufactor)         not yet: + half_i;\n\n        __m256 maskV_ps = Eightpixels_to_floats<pixel_t>(maskV + x);\n        final_opacity = _mm256_mul_ps(maskV_ps, factor_mul_opacity_simd); // maskY[x] * factor_mul_opacity;\n        auto Vfactor = _mm256_add_ps(one_ps_simd, _mm256_mul_ps(overlay_opacity_minus1, final_opacity)); // 1.0f + overlay_opacity_minus1 * final_opacity;\n        __m256 baseV_ps = EightChromapixels_to_floats<pixel_t>(baseV + x, half_i_simd);\n        V = _mm256_mul_ps(baseV_ps, Vfactor); // V = (int)((baseV[x] - half_i) * Vfactor)         not yet: + half_i;\n\n      }\n      else {\n        auto overlay_opacity_minus1 = _mm256_sub_ps(_mm256_mul_ps(ovY_ps, factor_simd), one_ps_simd); // ovY[x] * factor - 1.0f;\n        auto common_factor = _mm256_add_ps(one_ps_simd, _mm256_mul_ps(overlay_opacity_minus1, opacity_simd)); // 1.0f + overlay_opacity_minus1 * opacity_f;\n\n        auto Yfactor = common_factor;\n        __m256 baseY_ps = Eightpixels_to_floats<pixel_t>(baseY + x);\n        Y = _mm256_mul_ps(baseY_ps, Yfactor); // Y = (int)(baseY[x] * Yfactor); \n\n        auto Ufactor = common_factor;\n        __m256 baseU_ps = EightChromapixels_to_floats<pixel_t>(baseU + x, half_i_simd);\n        U = _mm256_mul_ps(baseU_ps, Ufactor); // U = (int)((baseU[x] - half_i) * Ufactor)         not yet: + half_i;\n\n        auto Vfactor = common_factor;\n        __m256 baseV_ps = EightChromapixels_to_floats<pixel_t>(baseV + x, half_i_simd);\n        V = _mm256_mul_ps(baseV_ps, Vfactor); // V = (int)((baseV[x] - half_i) * Vfactor)         not yet: + half_i;\n\n      }\n\n      Store_Eightpixels<pixel_t>(baseY + x, Y, rounder_simd);\n      Store_EightChromapixels<pixel_t>(baseU + x, U, half_and_rounder_simd);\n      Store_EightChromapixels<pixel_t>(baseV + x, V, half_and_rounder_simd);\n\n    }\n\n    for (int x = wMod8; x < width; x++) {\n      // from of_mul_c\n      int Y, U, V;\n\n      // generic, 8-16 bits\n      // This part re-appears in SSE2 code (non mod4 end-of-line fragment)\n      // Unlike the old integer version here is proper rounding\n      const float overlay_opacity_minus1 = ovY[x] * factor - 1.0f;\n      if constexpr (has_mask) {\n        float final_opacity;\n\n        final_opacity = maskY[x] * factor_mul_opacity;\n        auto Yfactor = 1.0f + overlay_opacity_minus1 * final_opacity;\n        Y = (int)(baseY[x] * Yfactor + 0.5f);\n\n        final_opacity = maskU[x] * factor_mul_opacity;\n        auto Ufactor = 1.0f + overlay_opacity_minus1 * final_opacity;\n        U = (int)(((float)baseU[x] - half_f) * Ufactor + half_f + 0.5f);\n\n        final_opacity = maskV[x] * factor_mul_opacity;\n        auto Vfactor = 1.0f + overlay_opacity_minus1 * final_opacity;\n        V = (int)(((float)baseV[x] - half_f) * Vfactor + half_f + 0.5f);\n      }\n      else {\n        const float common_factor = 1.0f + overlay_opacity_minus1 * opacity_f;\n\n        auto Yfactor = common_factor;\n        Y = (int)((float)baseY[x] * Yfactor + 0.5f);\n\n        auto Ufactor = common_factor;\n        U = (int)(((float)baseU[x] - half_f) * Ufactor + half_f + 0.5f);\n\n        auto Vfactor = common_factor;\n        V = (int)(((float)baseV[x] - half_f) * Vfactor + half_f + 0.5f);\n\n      }\n\n      baseU[x] = (pixel_t)U;\n      baseV[x] = (pixel_t)V;\n      baseY[x] = (pixel_t)Y;\n    }\n\n    if constexpr (has_mask) {\n      maskY += maskpitch;\n      maskU += maskpitch;\n      maskV += maskpitch;\n    }\n\n    baseY += basepitch;\n    baseU += basepitch;\n    baseV += basepitch;\n\n    ovY += overlaypitch;\n\n  }\n}\n\n// instantiate\ntemplate void of_multiply_avx2<uint8_t, false, false>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height, \n  const uint8_t* ovY, int overlaypitch, uint8_t* baseY, uint8_t* baseU, uint8_t* baseV, int basepitch, const uint8_t* maskY, const uint8_t* maskU, const uint8_t* maskV, int maskpitch);\ntemplate void of_multiply_avx2<uint8_t, false, true>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height,\n  const uint8_t* ovY, int overlaypitch, uint8_t* baseY, uint8_t* baseU, uint8_t* baseV, int basepitch, const uint8_t* maskY, const uint8_t* maskU, const uint8_t* maskV, int maskpitch);\ntemplate void of_multiply_avx2<uint8_t, true, false>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height,\n  const uint8_t* ovY, int overlaypitch, uint8_t* baseY, uint8_t* baseU, uint8_t* baseV, int basepitch, const uint8_t* maskY, const uint8_t* maskU, const uint8_t* maskV, int maskpitch);\ntemplate void of_multiply_avx2<uint8_t, true, true>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height,\n  const uint8_t* ovY, int overlaypitch, uint8_t* baseY, uint8_t* baseU, uint8_t* baseV, int basepitch, const uint8_t* maskY, const uint8_t* maskU, const uint8_t* maskV, int maskpitch);\ntemplate void of_multiply_avx2<uint16_t, false, false>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height,\n  const uint16_t* ovY, int overlaypitch, uint16_t* baseY, uint16_t* baseU, uint16_t* baseV, int basepitch, const uint16_t* maskY, const uint16_t* maskU, const uint16_t* maskV, int maskpitch);\ntemplate void of_multiply_avx2<uint16_t, false, true>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height,\n  const uint16_t* ovY, int overlaypitch, uint16_t* baseY, uint16_t* baseU, uint16_t* baseV, int basepitch, const uint16_t* maskY, const uint16_t* maskU, const uint16_t* maskV, int maskpitch);\ntemplate void of_multiply_avx2<uint16_t, true, false>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height,\n  const uint16_t* ovY, int overlaypitch, uint16_t* baseY, uint16_t* baseU, uint16_t* baseV, int basepitch, const uint16_t* maskY, const uint16_t* maskU, const uint16_t* maskV, int maskpitch);\ntemplate void of_multiply_avx2<uint16_t, true, true>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height,\n  const uint16_t* ovY, int overlaypitch, uint16_t* baseY, uint16_t* baseU, uint16_t* baseV, int basepitch, const uint16_t* maskY, const uint16_t* maskU, const uint16_t* maskV, int maskpitch);\n\n"
  },
  {
    "path": "avs_core/filters/overlay/intel/OF_multiply_avx2.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __of_multiply_avx2_h\n#define __of_multiply_avx2_h\n\n#include <avs/types.h>\n\ntemplate<typename pixel_t, bool opacity_is_full, bool has_mask>\nvoid of_multiply_avx2(\n  int bits_per_pixel,\n  const float opacity_f,\n  const int opacity,\n  int width, int height,\n  const pixel_t* ovY,\n  int overlaypitch,\n  pixel_t* baseY, pixel_t* baseU, pixel_t* baseV,\n  int basepitch,\n  const pixel_t* maskY, const pixel_t* maskU, const pixel_t* maskV,\n  int maskpitch\n);\n\n#endif // __of_multiply_avx2_h\n"
  },
  {
    "path": "avs_core/filters/overlay/intel/OF_multiply_sse.cpp",
    "content": "// Avisynth+\n// https://avs-plus.net\n//\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include \"avisynth.h\"\n#include \"OF_multiply_sse.h\"\n\n#include <stdint.h>\n#include <type_traits>\n\n// Intrinsics base header + really required extension headers\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n#include <smmintrin.h> // SSE4.1\n\ntemplate<typename pixel_t>\nstatic AVS_FORCEINLINE __m128 Fourpixels_to_floats(const pixel_t* src) {\n  auto zero = _mm_setzero_si128();\n  __m128i srci;\n  if constexpr (sizeof(pixel_t) == 1) {\n    srci = _mm_cvtsi32_si128(*(uint32_t*)src);\n    srci = _mm_unpacklo_epi8(srci, zero);\n    srci = _mm_unpacklo_epi16(srci, zero);\n  }\n  else {\n    srci = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(src));\n    srci = _mm_unpacklo_epi16(srci, zero);\n  }\n  return _mm_cvtepi32_ps(srci);\n}\n\ntemplate<typename pixel_t>\nstatic AVS_FORCEINLINE __m128 FourChromapixels_to_floats(const pixel_t* src, const __m128i half) {\n  auto zero = _mm_setzero_si128();\n  __m128i srci;\n  if constexpr (sizeof(pixel_t) == 1) {\n    srci = _mm_cvtsi32_si128(*(uint32_t*)src);\n    srci = _mm_unpacklo_epi8(srci, zero);\n    srci = _mm_unpacklo_epi16(srci, zero);\n  }\n  else {\n    srci = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(src));\n    srci = _mm_unpacklo_epi16(srci, zero);\n  }\n  srci = _mm_sub_epi32(srci, half);\n  return _mm_cvtepi32_ps(srci);\n}\n\ntemplate<typename pixel_t>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nstatic AVS_FORCEINLINE void Store_Fourpixels(pixel_t* dst, __m128 what, const __m128 rounder) {\n  what = _mm_add_ps(what, rounder); // round\n  __m128i si32 = _mm_cvttps_epi32(what); // truncate\n  __m128i result_16 = _mm_packus_epi32(si32, si32); // sse4.1\n  if constexpr (sizeof(pixel_t) == 1) {\n    __m128i result_8 = _mm_packus_epi16(result_16, result_16);\n    *(uint32_t*)(dst) = _mm_cvtsi128_si32(result_8);\n  }\n  else {\n    _mm_storel_epi64(reinterpret_cast<__m128i*>(dst), result_16);\n  }\n}\n\ntemplate<typename pixel_t>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nstatic AVS_FORCEINLINE void Store_FourChromapixels(pixel_t* dst, __m128 what, const __m128 half_plus_rounder) {\n  what = _mm_add_ps(what, half_plus_rounder); // chroma offset back with rounder\n  __m128i si32 = _mm_cvttps_epi32(what); // truncate\n  __m128i result_16 = _mm_packus_epi32(si32, si32); // sse4.1\n  if constexpr (sizeof(pixel_t) == 1) {\n    __m128i result_8 = _mm_packus_epi16(result_16, result_16);\n    *(uint32_t*)(dst) = _mm_cvtsi128_si32(result_8);\n  }\n  else {\n    _mm_storel_epi64(reinterpret_cast<__m128i*>(dst), result_16);\n  }\n}\n\n\ntemplate<typename pixel_t, bool opacity_is_full, bool has_mask>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid of_multiply_sse41(\n  int bits_per_pixel,\n  const float opacity_f,\n  const int opacity,\n  int width, int height,\n  const pixel_t* ovY,\n  int overlaypitch,\n  pixel_t* baseY, pixel_t* baseU, pixel_t* baseV,\n  int basepitch,\n  const pixel_t* maskY, const pixel_t* maskU, const pixel_t* maskV,\n  int maskpitch\n)\n{\n  const int max_pixel_value = (sizeof(pixel_t) == 1) ? 255 : (1 << bits_per_pixel) - 1;\n  const float factor = 1.0f / max_pixel_value;\n  const int half_i = sizeof(pixel_t) == 1 ? 128 : 1 << (bits_per_pixel - 1);\n  const float half_f = (float)half_i;\n\n  float factor_mul_opacity;\n  if constexpr (opacity_is_full)\n    factor_mul_opacity = factor * 1.0f;\n  else\n    factor_mul_opacity = factor * opacity_f;\n\n  auto opacity_simd = _mm_set1_ps(opacity_f);\n  auto factor_simd = _mm_set1_ps(factor);\n  auto factor_mul_opacity_simd = _mm_set1_ps(factor_mul_opacity);\n  auto one_ps_simd = _mm_set1_ps(1.0f);\n  const __m128i half_i_simd = _mm_set1_epi32(half_i);\n  const __m128 half_and_rounder_simd = _mm_set1_ps(half_f + 0.5f);\n  const __m128 rounder_simd = _mm_set1_ps(0.5f);\n\n  const int wMod4 = width / 4 * 4;\n\n  // start processing\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wMod4; x += 4) {\n      __m128 Y, U, V;\n      // 4 pixels at a time. 8 or 16 bits to floats\n      __m128 ovY_ps = Fourpixels_to_floats<pixel_t>(ovY + x);\n\n      // generic, 8-16 bits\n      if constexpr (has_mask) {\n        __m128 final_opacity;\n        auto overlay_opacity_minus1 = _mm_sub_ps(_mm_mul_ps(ovY_ps, factor_simd), one_ps_simd); // ovY[x] * factor - 1.0f;\n\n        __m128 maskY_ps = Fourpixels_to_floats<pixel_t>(maskY + x);\n        final_opacity = _mm_mul_ps(maskY_ps, factor_mul_opacity_simd); // maskY[x] * factor_mul_opacity;\n        auto Yfactor = _mm_add_ps(one_ps_simd, _mm_mul_ps(overlay_opacity_minus1, final_opacity)); // 1.0f + overlay_opacity_minus1 * final_opacity;\n        __m128 baseY_ps = Fourpixels_to_floats<pixel_t>(baseY + x);\n        Y = _mm_mul_ps(baseY_ps, Yfactor); // Y = (int)(baseY[x] * Yfactor);\n\n        __m128 maskU_ps = Fourpixels_to_floats<pixel_t>(maskU + x);\n        final_opacity = _mm_mul_ps(maskU_ps, factor_mul_opacity_simd); // maskY[x] * factor_mul_opacity;\n        auto Ufactor = _mm_add_ps(one_ps_simd, _mm_mul_ps(overlay_opacity_minus1, final_opacity)); // 1.0f + overlay_opacity_minus1 * final_opacity;\n        __m128 baseU_ps = FourChromapixels_to_floats<pixel_t>(baseU + x, half_i_simd);\n        U = _mm_mul_ps(baseU_ps, Ufactor); // U = (int)((baseU[x] - half_i) * Ufactor)         not yet: + half_i;\n\n        __m128 maskV_ps = Fourpixels_to_floats<pixel_t>(maskV + x);\n        final_opacity = _mm_mul_ps(maskV_ps, factor_mul_opacity_simd); // maskY[x] * factor_mul_opacity;\n        auto Vfactor = _mm_add_ps(one_ps_simd, _mm_mul_ps(overlay_opacity_minus1, final_opacity)); // 1.0f + overlay_opacity_minus1 * final_opacity;\n        __m128 baseV_ps = FourChromapixels_to_floats<pixel_t>(baseV + x, half_i_simd);\n        V = _mm_mul_ps(baseV_ps, Vfactor); // V = (int)((baseV[x] - half_i) * Vfactor)         not yet: + half_i;\n\n      }\n      else {\n        auto overlay_opacity_minus1 = _mm_sub_ps(_mm_mul_ps(ovY_ps, factor_simd), one_ps_simd); // ovY[x] * factor - 1.0f;\n        auto common_factor = _mm_add_ps(one_ps_simd, _mm_mul_ps(overlay_opacity_minus1, opacity_simd)); // 1.0f + overlay_opacity_minus1 * opacity_f;\n\n        auto Yfactor = common_factor;\n        __m128 baseY_ps = Fourpixels_to_floats<pixel_t>(baseY + x);\n        Y = _mm_mul_ps(baseY_ps, Yfactor); // Y = (int)(baseY[x] * Yfactor); \n\n        auto Ufactor = common_factor;\n        __m128 baseU_ps = FourChromapixels_to_floats<pixel_t>(baseU + x, half_i_simd);\n        U = _mm_mul_ps(baseU_ps, Ufactor); // U = (int)((baseU[x] - half_i) * Ufactor)         not yet: + half_i;\n\n        auto Vfactor = common_factor;\n        __m128 baseV_ps = FourChromapixels_to_floats<pixel_t>(baseV + x, half_i_simd);\n        V = _mm_mul_ps(baseV_ps, Vfactor); // V = (int)((baseV[x] - half_i) * Vfactor)         not yet: + half_i;\n\n      }\n\n      Store_Fourpixels<pixel_t>(baseY + x, Y, rounder_simd);\n      Store_FourChromapixels<pixel_t>(baseU + x, U, half_and_rounder_simd);\n      Store_FourChromapixels<pixel_t>(baseV + x, V, half_and_rounder_simd);\n\n    }\n\n    for (int x = wMod4; x < width; x++) {\n      // from of_mul_c\n      int Y, U, V;\n\n      // generic, 8-16 bits\n      // This part re-appears in SSE2 code (non mod4 end-of-line fragment)\n      // Unlike the old integer version here is proper rounding\n      const float overlay_opacity_minus1 = ovY[x] * factor - 1.0f;\n      if constexpr (has_mask) {\n        float final_opacity;\n\n        final_opacity = maskY[x] * factor_mul_opacity;\n        auto Yfactor = 1.0f + overlay_opacity_minus1 * final_opacity;\n        Y = (int)(baseY[x] * Yfactor + 0.5f);\n\n        final_opacity = maskU[x] * factor_mul_opacity;\n        auto Ufactor = 1.0f + overlay_opacity_minus1 * final_opacity;\n        U = (int)(((float)baseU[x] - half_f) * Ufactor + half_f + 0.5f);\n\n        final_opacity = maskV[x] * factor_mul_opacity;\n        auto Vfactor = 1.0f + overlay_opacity_minus1 * final_opacity;\n        V = (int)(((float)baseV[x] - half_f) * Vfactor + half_f + 0.5f);\n      }\n      else {\n        const float common_factor = 1.0f + overlay_opacity_minus1 * opacity_f;\n\n        auto Yfactor = common_factor;\n        Y = (int)((float)baseY[x] * Yfactor + 0.5f);\n\n        auto Ufactor = common_factor;\n        U = (int)(((float)baseU[x] - half_f) * Ufactor + half_f + 0.5f);\n\n        auto Vfactor = common_factor;\n        V = (int)(((float)baseV[x] - half_f) * Vfactor + half_f + 0.5f);\n\n      }\n\n      baseU[x] = (pixel_t)U;\n      baseV[x] = (pixel_t)V;\n      baseY[x] = (pixel_t)Y;\n    }\n\n    if constexpr (has_mask) {\n      maskY += maskpitch;\n      maskU += maskpitch;\n      maskV += maskpitch;\n    }\n\n    baseY += basepitch;\n    baseU += basepitch;\n    baseV += basepitch;\n\n    ovY += overlaypitch;\n\n  }\n}\n\n\n// instantiate\ntemplate\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid of_multiply_sse41<uint8_t, false, false>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height,\n  const uint8_t* ovY, int overlaypitch, uint8_t* baseY, uint8_t* baseU, uint8_t* baseV, int basepitch, const uint8_t* maskY, const uint8_t* maskU, const uint8_t* maskV, int maskpitch);\n\ntemplate\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid of_multiply_sse41<uint8_t, false, true>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height,\n  const uint8_t* ovY, int overlaypitch, uint8_t* baseY, uint8_t* baseU, uint8_t* baseV, int basepitch, const uint8_t* maskY, const uint8_t* maskU, const uint8_t* maskV, int maskpitch);\n\ntemplate\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid of_multiply_sse41<uint8_t, true, false>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height,\n  const uint8_t* ovY, int overlaypitch, uint8_t* baseY, uint8_t* baseU, uint8_t* baseV, int basepitch, const uint8_t* maskY, const uint8_t* maskU, const uint8_t* maskV, int maskpitch);\n\ntemplate\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid of_multiply_sse41<uint8_t, true, true>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height,\n  const uint8_t* ovY, int overlaypitch, uint8_t* baseY, uint8_t* baseU, uint8_t* baseV, int basepitch, const uint8_t* maskY, const uint8_t* maskU, const uint8_t* maskV, int maskpitch);\n\ntemplate\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid of_multiply_sse41<uint16_t, false, false>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height,\n  const uint16_t* ovY, int overlaypitch, uint16_t* baseY, uint16_t* baseU, uint16_t* baseV, int basepitch, const uint16_t* maskY, const uint16_t* maskU, const uint16_t* maskV, int maskpitch);\n\ntemplate\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid of_multiply_sse41<uint16_t, false, true>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height,\n  const uint16_t* ovY, int overlaypitch, uint16_t* baseY, uint16_t* baseU, uint16_t* baseV, int basepitch, const uint16_t* maskY, const uint16_t* maskU, const uint16_t* maskV, int maskpitch);\n\ntemplate\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid of_multiply_sse41<uint16_t, true, false>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height,\n  const uint16_t* ovY, int overlaypitch, uint16_t* baseY, uint16_t* baseU, uint16_t* baseV, int basepitch, const uint16_t* maskY, const uint16_t* maskU, const uint16_t* maskV, int maskpitch);\n\ntemplate\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid of_multiply_sse41<uint16_t, true, true>(int bits_per_pixel, const float opacity_f, const int opacity, int width, int height,\n  const uint16_t* ovY, int overlaypitch, uint16_t* baseY, uint16_t* baseU, uint16_t* baseV, int basepitch, const uint16_t* maskY, const uint16_t* maskU, const uint16_t* maskV, int maskpitch);\n"
  },
  {
    "path": "avs_core/filters/overlay/intel/OF_multiply_sse.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __of_multiply_sse_h\n#define __of_multiply_sse_h\n\n#include <avs/types.h>\n\ntemplate<typename pixel_t, bool opacity_is_full, bool has_mask>\nvoid of_multiply_sse41(\n  int bits_per_pixel,\n  const float opacity_f,\n  const int opacity,\n  int width, int height,\n  const pixel_t* ovY,\n  int overlaypitch,\n  pixel_t* baseY, pixel_t* baseU, pixel_t* baseV,\n  int basepitch,\n  const pixel_t* maskY, const pixel_t* maskU, const pixel_t* maskV,\n  int maskpitch\n);\n\n#endif // __of_multiply_sse_h\n"
  },
  {
    "path": "avs_core/filters/overlay/intel/blend_common_avx2.cpp",
    "content": "// Avisynth+\n// https://avs-plus.net\n//\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include \"avisynth.h\"\n#include \"blend_common_avx2.h\"\n#include \"../blend_common.h\"\n\n#include <stdint.h>\n\n#ifdef _MSC_VER\n#include <intrin.h>\n#else\n#include <x86intrin.h>\n#endif\n#include  <immintrin.h>\n\n\n\n\ntemplate<bool has_mask, typename pixel_t, bool lessthan16bits>\nvoid overlay_blend_avx2_uint(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch,\n  const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel)\n{\n  const auto rounder = _mm256_set1_ps(0.5f);\n  const int max_pixel_value = (1 << bits_per_pixel) - 1;\n  const auto factor = has_mask ? opacity_f / max_pixel_value : opacity_f;\n  const auto factor_v = _mm256_set1_ps(factor);\n\n  constexpr int pixels_per_cycle = 16;\n  constexpr int bytes_per_cycle = pixels_per_cycle * sizeof(pixel_t);\n  const int wMod = (width * sizeof(pixel_t) / bytes_per_cycle) * bytes_per_cycle;\n\n  // key formula: p1*(1-factor)+p2*factor -> p1 + (p2 - p1) * factor \n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wMod; x += bytes_per_cycle) {\n      if constexpr (lessthan16bits) {\n        // 8-14 bits: int16 delta -> float factor -> int16 delta_scaled -->\n        // int16 result = p1 + delta_scaled (all in int16 domain except factor!)\n        __m256i p1_i16, p2_i16, delta_i16;\n        __m256i mask_i16;\n\n        if constexpr (sizeof(pixel_t) == 1) {\n          // 8 bits\n          __m128i p1_u8 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(p1 + x));\n          __m128i p2_u8 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(p2 + x));\n\n          p1_i16 = _mm256_cvtepu8_epi16(p1_u8);\n          p2_i16 = _mm256_cvtepu8_epi16(p2_u8);\n\n          if constexpr (has_mask) {\n            __m128i mask_u8 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(mask + x));\n            mask_i16 = _mm256_cvtepu8_epi16(mask_u8);\n          }\n        }\n        else { // 10/12/14 bits\n          p1_i16 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(p1 + x));\n          p2_i16 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(p2 + x));\n\n          if constexpr (has_mask) {\n            mask_i16 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(mask + x));\n          }\n        }\n\n        delta_i16 = _mm256_sub_epi16(p2_i16, p1_i16);\n\n        // split for 32-bit processing\n        __m128i delta_i16_lo = _mm256_castsi256_si128(delta_i16);\n        __m128i delta_i16_hi = _mm256_extracti128_si256(delta_i16, 1);\n\n        // convert _only_ delta and mask to 32-bit\n        __m256i delta_lo_i32 = _mm256_cvtepi16_epi32(delta_i16_lo);\n        __m256i delta_hi_i32 = _mm256_cvtepi16_epi32(delta_i16_hi);\n\n        // convert _only_ delta to float\n        __m256 delta_lo_f = _mm256_cvtepi32_ps(delta_lo_i32);\n        __m256 delta_hi_f = _mm256_cvtepi32_ps(delta_hi_i32);\n\n        __m256 delta_scaled_lo, delta_scaled_hi;\n\n        if constexpr (has_mask) {\n          __m128i mask_i16_lo = _mm256_castsi256_si128(mask_i16);\n          __m128i mask_i16_hi = _mm256_extracti128_si256(mask_i16, 1);\n\n          __m256i mask_lo_i32 = _mm256_cvtepu16_epi32(mask_i16_lo);\n          __m256i mask_hi_i32 = _mm256_cvtepu16_epi32(mask_i16_hi);\n\n          __m256 mask_lo_f = _mm256_cvtepi32_ps(mask_lo_i32);\n          __m256 mask_hi_f = _mm256_cvtepi32_ps(mask_hi_i32);\n\n          __m256 new_factor_lo = _mm256_mul_ps(mask_lo_f, factor_v);\n          __m256 new_factor_hi = _mm256_mul_ps(mask_hi_f, factor_v);\n\n          // scale delta: delta * factor\n          delta_scaled_lo = _mm256_mul_ps(delta_lo_f, new_factor_lo);\n          delta_scaled_hi = _mm256_mul_ps(delta_hi_f, new_factor_hi);\n        }\n        else {\n          delta_scaled_lo = _mm256_mul_ps(delta_lo_f, factor_v);\n          delta_scaled_hi = _mm256_mul_ps(delta_hi_f, factor_v);\n        }\n\n        // round and truncate to int32\n        delta_scaled_lo = _mm256_add_ps(delta_scaled_lo, rounder);\n        delta_scaled_hi = _mm256_add_ps(delta_scaled_hi, rounder);\n        __m256i delta_scaled_i32_lo = _mm256_cvttps_epi32(delta_scaled_lo);\n        __m256i delta_scaled_i32_hi = _mm256_cvttps_epi32(delta_scaled_hi);\n\n        // scaled delta back to int16\n        __m256i delta_scaled_i16 = _mm256_packs_epi32(delta_scaled_i32_lo, delta_scaled_i32_hi);\n        delta_scaled_i16 = _mm256_permute4x64_epi64(delta_scaled_i16, 0xD8);\n\n        // +p1\n        __m256i result_i16 = _mm256_add_epi16(p1_i16, delta_scaled_i16);\n\n        if constexpr (sizeof(pixel_t) == 1) {\n          __m128i i16_lo_128 = _mm256_castsi256_si128(result_i16);\n          __m128i i16_hi_128 = _mm256_extracti128_si256(result_i16, 1);\n          __m128i result_u8 = _mm_packus_epi16(i16_lo_128, i16_hi_128);\n\n          _mm_storeu_si128(reinterpret_cast<__m128i*>(p1 + x), result_u8);\n        }\n        else {\n          _mm256_storeu_si256(reinterpret_cast<__m256i*>(p1 + x), result_i16);\n        }\n      }\n      else { // 16-bit overflow-safe, int32 and float\n        static_assert(sizeof(pixel_t) == 2, \"lessthan16bits=false only for uint16_t\");\n\n        // 16xuint16_t pixels\n        __m256i p1_u16 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(p1 + x));\n        __m256i p2_u16 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(p2 + x));\n\n        __m128i p1_u16_lo = _mm256_castsi256_si128(p1_u16);\n        __m128i p1_u16_hi = _mm256_extracti128_si256(p1_u16, 1);\n        __m128i p2_u16_lo = _mm256_castsi256_si128(p2_u16);\n        __m128i p2_u16_hi = _mm256_extracti128_si256(p2_u16, 1);\n\n        // to int32 (8 pixels per __m256i)\n        __m256i p1_i32_lo = _mm256_cvtepu16_epi32(p1_u16_lo);\n        __m256i p1_i32_hi = _mm256_cvtepu16_epi32(p1_u16_hi);\n        __m256i p2_i32_lo = _mm256_cvtepu16_epi32(p2_u16_lo);\n        __m256i p2_i32_hi = _mm256_cvtepu16_epi32(p2_u16_hi);\n\n        // p2-p1 in int32 and only then float\n        __m256i delta_lo_32 = _mm256_sub_epi32(p2_i32_lo, p1_i32_lo);\n        __m256i delta_hi_32 = _mm256_sub_epi32(p2_i32_hi, p1_i32_hi);\n        __m256 delta_f_lo = _mm256_cvtepi32_ps(delta_lo_32);\n        __m256 delta_f_hi = _mm256_cvtepi32_ps(delta_hi_32);\n\n        __m256 delta_scaled_lo, delta_scaled_hi;\n        if constexpr (has_mask) {\n          __m256i mask_u16 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(mask + x));\n          __m128i mask_u16_lo = _mm256_castsi256_si128(mask_u16);\n          __m128i mask_u16_hi = _mm256_extracti128_si256(mask_u16, 1);\n\n          __m256i mask_i32_lo = _mm256_cvtepu16_epi32(mask_u16_lo);\n          __m256i mask_i32_hi = _mm256_cvtepu16_epi32(mask_u16_hi);\n          __m256 mask_f_lo = _mm256_cvtepi32_ps(mask_i32_lo);\n          __m256 mask_f_hi = _mm256_cvtepi32_ps(mask_i32_hi);\n\n          __m256 new_factor_lo = _mm256_mul_ps(mask_f_lo, factor_v);\n          __m256 new_factor_hi = _mm256_mul_ps(mask_f_hi, factor_v);\n\n          delta_scaled_lo = _mm256_mul_ps(delta_f_lo, new_factor_lo);\n          delta_scaled_hi = _mm256_mul_ps(delta_f_hi, new_factor_hi);\n        }\n        else {\n          delta_scaled_lo = _mm256_mul_ps(delta_f_lo, factor_v);\n          delta_scaled_hi = _mm256_mul_ps(delta_f_hi, factor_v);\n        }\n\n        // round and truncate to int32\n        delta_scaled_lo = _mm256_add_ps(delta_scaled_lo, rounder);\n        delta_scaled_hi = _mm256_add_ps(delta_scaled_hi, rounder);\n        __m256i delta_scaled_i32_lo = _mm256_cvttps_epi32(delta_scaled_lo);\n        __m256i delta_scaled_i32_hi = _mm256_cvttps_epi32(delta_scaled_hi);\n\n        // p1 + delta_scaled still in int32\n        __m256i result_i32_lo = _mm256_add_epi32(p1_i32_lo, delta_scaled_i32_lo);\n        __m256i result_i32_hi = _mm256_add_epi32(p1_i32_hi, delta_scaled_i32_hi);\n\n        // 8 int32 -> 8 uint16 in lower half\n        __m256i i16_lo = _mm256_packus_epi32(result_i32_lo, result_i32_lo);\n        __m256i i16_hi = _mm256_packus_epi32(result_i32_hi, result_i32_hi);\n\n        // get correct layout\n        i16_lo = _mm256_permute4x64_epi64(i16_lo, 0xD8);\n        i16_hi = _mm256_permute4x64_epi64(i16_hi, 0xD8);\n\n        // Extract lower 128 bits from each\n        __m128i result_u16_lo = _mm256_castsi256_si128(i16_lo);\n        __m128i result_u16_hi = _mm256_castsi256_si128(i16_hi);\n\n        // Combine back into a single __m256i and store\n        __m256i result_u16 = _mm256_setr_m128i(result_u16_lo, result_u16_hi);\n        _mm256_storeu_si256(reinterpret_cast<__m256i*>(p1 + x), result_u16);\n      }\n    }\n\n    // Scalar tail\n    // Working with exact dimension, overlay is possible atop an existing frame at any position\n    for (int x = wMod / sizeof(pixel_t); x < width; x++) {\n      const float new_factor = has_mask ? static_cast<float>(reinterpret_cast<const pixel_t*>(mask)[x]) * factor : factor;\n      const pixel_t pix1 = reinterpret_cast<pixel_t*>(p1)[x];\n      const pixel_t pix2 = reinterpret_cast<const pixel_t*>(p2)[x];\n      pixel_t result = pix1 + (int)((pix2 - pix1) * new_factor + 0.5f);\n      reinterpret_cast<pixel_t*>(p1)[x] = result;\n    }\n\n    p1 += p1_pitch;\n    p2 += p2_pitch;\n    if (has_mask)\n      mask += mask_pitch;\n  }\n}\n\n// instantiate\n// mask yes/no\ntemplate void overlay_blend_avx2_uint<true, uint8_t, true>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\ntemplate void overlay_blend_avx2_uint<true, uint16_t, true>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\ntemplate void overlay_blend_avx2_uint<true, uint16_t, false>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\n//--\ntemplate void overlay_blend_avx2_uint<false, uint8_t, true>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\ntemplate void overlay_blend_avx2_uint<false, uint16_t, true>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\ntemplate void overlay_blend_avx2_uint<false, uint16_t, false>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\n\ntemplate<bool has_mask>\nvoid overlay_blend_avx2_float(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch,\n  const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel)\n{\n\n  const int realwidth = width * sizeof(float);\n\n  int wMod32 = (realwidth / 32) * 32;\n  auto opacity_v = _mm256_set1_ps(opacity_f);\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wMod32; x += 32) {\n      auto p1_f = _mm256_loadu_ps(reinterpret_cast<const float*>(p1 + x));\n      auto p2_f = _mm256_loadu_ps(reinterpret_cast<const float*>(p2 + x));\n      __m256 new_mask;\n      if constexpr (has_mask) {\n        new_mask = _mm256_loadu_ps(reinterpret_cast<const float*>(mask + x));\n        new_mask = _mm256_mul_ps(new_mask, opacity_v);\n      }\n      else {\n        new_mask = opacity_v;\n      }\n      auto result = _mm256_add_ps(p1_f, _mm256_mul_ps(_mm256_sub_ps(p2_f, p1_f), new_mask)); // p1*(1-mask) + p2*mask = p1+(p2-p1)*mask\n\n      _mm256_storeu_ps(reinterpret_cast<float*>(p1 + x), result);\n    }\n\n    // Leftover value\n    // Working with exact dimension, overlay is possible atop an existing frame at any position\n    for (int x = wMod32 / sizeof(float); x < width; x++) {\n      auto new_mask = has_mask ? reinterpret_cast<const float*>(mask)[x] * opacity_f : opacity_f;\n      auto p1x = reinterpret_cast<float*>(p1)[x];\n      auto p2x = reinterpret_cast<const float*>(p2)[x];\n      auto result = p1x + (p2x - p1x) * new_mask; // p1x*(1-new_mask) + p2x*mask\n      reinterpret_cast<float*>(p1)[x] = result;\n    }\n\n\n    p1 += p1_pitch;\n    p2 += p2_pitch;\n    if constexpr (has_mask)\n      mask += mask_pitch;\n  }\n}\n\ntemplate void overlay_blend_avx2_float<false>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\ntemplate void overlay_blend_avx2_float<true>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\n\n"
  },
  {
    "path": "avs_core/filters/overlay/intel/blend_common_avx2.h",
    "content": "// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include \"avisynth.h\"\n#include <stdint.h>\n\n#ifndef __blend_common_avx2_h\n#define __blend_common_avx2_h\n\ntemplate<bool has_mask, typename pixel_t, bool lessthan16bits>\nvoid overlay_blend_avx2_uint(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\n\ntemplate<bool has_mask>\nvoid overlay_blend_avx2_float(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\n\n#endif // __blend_common_avx2_h\n"
  },
  {
    "path": "avs_core/filters/overlay/intel/blend_common_sse.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// Overlay (c) 2003, 2004 by Klaus Post\n\n#include <avisynth.h>\n\n#include \"blend_common_sse.h\"\n#include \"../blend_common.h\"\n#include \"../../../core/internal.h\"\n\n// Intrinsics base header + really required extension headers\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n#include <smmintrin.h> // SSE4.1\n\n#include <stdint.h>\n\n/********************************\n ********* Blend Opaque *********\n ** Use for Lighten and Darken **\n ********************************/\n\n#ifdef X86_32\nAVS_FORCEINLINE __m64 overlay_blend_opaque_mmx_core(const __m64& p1, const __m64& p2, const __m64& mask) {\n  // return (mask) ? p2 : p1;\n  __m64 r1 = _mm_andnot_si64(mask, p1);\n  __m64 r2 = _mm_and_si64   (mask, p2);\n  return _mm_or_si64(r1, r2);\n}\n#endif\n\nAVS_FORCEINLINE __m128i overlay_blend_opaque_sse2_core(const __m128i& p1, const __m128i& p2, const __m128i& mask) {\n  // return (mask) ? p2 : p1;\n  __m128i r1 = _mm_andnot_si128(mask, p1);\n  __m128i r2 = _mm_and_si128   (mask, p2);\n  return _mm_or_si128(r1, r2);\n}\n\ntemplate<bool has_mask, typename pixel_t, bool lessthan16bits>\nvoid overlay_blend_sse2_uint(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch,\n  const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel)\n{\n  const auto rounder = _mm_set1_ps(0.5f);\n  const int max_pixel_value = (1 << bits_per_pixel) - 1;\n  const auto factor = has_mask ? opacity_f / max_pixel_value : opacity_f;\n  const auto factor_v = _mm_set1_ps(factor);\n  constexpr int pixels_per_cycle = 8;\n  constexpr int bytes_per_cycle = pixels_per_cycle * sizeof(pixel_t);\n  const int wMod = (width * sizeof(pixel_t) / bytes_per_cycle) * bytes_per_cycle;\n  // key formula: p1*(1-factor)+p2*factor -> p1 + (p2 - p1) * factor \n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wMod; x += bytes_per_cycle) {\n      if constexpr (lessthan16bits) {\n        // 8-14 bits: int16 delta -> float factor -> int16 delta_scaled -->\n        // int16 result = p1 + delta_scaled (all in int16 domain except factor!)\n        __m128i p1_i16, p2_i16, delta_i16;\n        __m128i mask_i16;\n        if constexpr (sizeof(pixel_t) == 1) {\n          // 8 bits - load 8 bytes\n          __m128i p1_u8 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(p1 + x));\n          __m128i p2_u8 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(p2 + x));\n          p1_i16 = _mm_unpacklo_epi8(p1_u8, _mm_setzero_si128());\n          p2_i16 = _mm_unpacklo_epi8(p2_u8, _mm_setzero_si128());\n          if constexpr (has_mask) {\n            __m128i mask_u8 = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(mask + x));\n            mask_i16 = _mm_unpacklo_epi8(mask_u8, _mm_setzero_si128());\n          }\n        }\n        else { // 10/12/14 bits\n          p1_i16 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(p1 + x));\n          p2_i16 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(p2 + x));\n          if constexpr (has_mask) {\n            mask_i16 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(mask + x));\n          }\n        }\n        delta_i16 = _mm_sub_epi16(p2_i16, p1_i16);\n\n        // Split into low and high for 32-bit processing (4 pixels each)\n        __m128i delta_i16_lo = _mm_unpacklo_epi16(delta_i16, _mm_srai_epi16(delta_i16, 15)); // sign extend\n        __m128i delta_i16_hi = _mm_unpackhi_epi16(delta_i16, _mm_srai_epi16(delta_i16, 15));\n\n        // Convert to float\n        __m128 delta_lo_f = _mm_cvtepi32_ps(delta_i16_lo);\n        __m128 delta_hi_f = _mm_cvtepi32_ps(delta_i16_hi);\n\n        __m128 delta_scaled_lo, delta_scaled_hi;\n        if constexpr (has_mask) {\n          __m128i mask_i16_lo = _mm_unpacklo_epi16(mask_i16, _mm_setzero_si128()); // zero extend\n          __m128i mask_i16_hi = _mm_unpackhi_epi16(mask_i16, _mm_setzero_si128());\n          __m128 mask_lo_f = _mm_cvtepi32_ps(mask_i16_lo);\n          __m128 mask_hi_f = _mm_cvtepi32_ps(mask_i16_hi);\n          __m128 new_factor_lo = _mm_mul_ps(mask_lo_f, factor_v);\n          __m128 new_factor_hi = _mm_mul_ps(mask_hi_f, factor_v);\n          // scale delta: delta * factor\n          delta_scaled_lo = _mm_mul_ps(delta_lo_f, new_factor_lo);\n          delta_scaled_hi = _mm_mul_ps(delta_hi_f, new_factor_hi);\n        }\n        else {\n          delta_scaled_lo = _mm_mul_ps(delta_lo_f, factor_v);\n          delta_scaled_hi = _mm_mul_ps(delta_hi_f, factor_v);\n        }\n\n        // round and truncate to int32\n        delta_scaled_lo = _mm_add_ps(delta_scaled_lo, rounder);\n        delta_scaled_hi = _mm_add_ps(delta_scaled_hi, rounder);\n        __m128i delta_scaled_i32_lo = _mm_cvttps_epi32(delta_scaled_lo);\n        __m128i delta_scaled_i32_hi = _mm_cvttps_epi32(delta_scaled_hi);\n\n        // Pack back to int16\n        __m128i delta_scaled_i16 = _mm_packs_epi32(delta_scaled_i32_lo, delta_scaled_i32_hi);\n\n        // Add to p1\n        __m128i result_i16 = _mm_add_epi16(p1_i16, delta_scaled_i16);\n\n        if constexpr (sizeof(pixel_t) == 1) {\n          __m128i result_u8 = _mm_packus_epi16(result_i16, result_i16);\n          _mm_storel_epi64(reinterpret_cast<__m128i*>(p1 + x), result_u8);\n        }\n        else {\n          _mm_storeu_si128(reinterpret_cast<__m128i*>(p1 + x), result_i16);\n        }\n      }\n      else { // 16-bit overflow-safe, int32 and float\n        static_assert(sizeof(pixel_t) == 2, \"lessthan16bits=false only for uint16_t\");\n\n        // Load 8 uint16_t pixels\n        __m128i p1_u16 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(p1 + x));\n        __m128i p2_u16 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(p2 + x));\n\n        // split into low and high halves (4 pixels each)\n        __m128i p1_u16_lo = _mm_unpacklo_epi16(p1_u16, _mm_setzero_si128()); // zero extend to 32-bit\n        __m128i p1_u16_hi = _mm_unpackhi_epi16(p1_u16, _mm_setzero_si128());\n        __m128i p2_u16_lo = _mm_unpacklo_epi16(p2_u16, _mm_setzero_si128());\n        __m128i p2_u16_hi = _mm_unpackhi_epi16(p2_u16, _mm_setzero_si128());\n\n        // Calculate delta (p2 - p1) in int32\n        __m128i delta_i32_lo = _mm_sub_epi32(p2_u16_lo, p1_u16_lo);\n        __m128i delta_i32_hi = _mm_sub_epi32(p2_u16_hi, p1_u16_hi);\n\n        // convert delta to float\n        __m128 delta_f_lo = _mm_cvtepi32_ps(delta_i32_lo);\n        __m128 delta_f_hi = _mm_cvtepi32_ps(delta_i32_hi);\n\n        __m128 delta_scaled_lo, delta_scaled_hi;\n        if constexpr (has_mask) {\n          __m128i mask_u16 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(mask + x));\n          __m128i mask_u16_lo = _mm_unpacklo_epi16(mask_u16, _mm_setzero_si128());\n          __m128i mask_u16_hi = _mm_unpackhi_epi16(mask_u16, _mm_setzero_si128());\n          __m128 mask_f_lo = _mm_cvtepi32_ps(mask_u16_lo);\n          __m128 mask_f_hi = _mm_cvtepi32_ps(mask_u16_hi);\n          __m128 new_factor_lo = _mm_mul_ps(mask_f_lo, factor_v);\n          __m128 new_factor_hi = _mm_mul_ps(mask_f_hi, factor_v);\n          delta_scaled_lo = _mm_mul_ps(delta_f_lo, new_factor_lo);\n          delta_scaled_hi = _mm_mul_ps(delta_f_hi, new_factor_hi);\n        }\n        else {\n          delta_scaled_lo = _mm_mul_ps(delta_f_lo, factor_v);\n          delta_scaled_hi = _mm_mul_ps(delta_f_hi, factor_v);\n        }\n\n        // round and truncate to int32\n        delta_scaled_lo = _mm_add_ps(delta_scaled_lo, rounder);\n        delta_scaled_hi = _mm_add_ps(delta_scaled_hi, rounder);\n        __m128i delta_scaled_i32_lo = _mm_cvttps_epi32(delta_scaled_lo);\n        __m128i delta_scaled_i32_hi = _mm_cvttps_epi32(delta_scaled_hi);\n\n        // Add p1 + delta_scaled in int32\n        __m128i result_i32_lo = _mm_add_epi32(p1_u16_lo, delta_scaled_i32_lo);\n        __m128i result_i32_hi = _mm_add_epi32(p1_u16_hi, delta_scaled_i32_hi);\n\n        // Pack back to uint16 using _MM_PACKUS_EPI32 sse4.1 simulation\n        __m128i result_u16_lo = _MM_PACKUS_EPI32(result_i32_lo, result_i32_hi);\n\n        _mm_storeu_si128(reinterpret_cast<__m128i*>(p1 + x), result_u16_lo);\n      }\n    }\n    // Scalar tail\n    // Working with exact dimension, overlay is possible atop an existing frame at any position\n    for (int x = wMod / sizeof(pixel_t); x < width; x++) {\n      const float new_factor = has_mask ? static_cast<float>(reinterpret_cast<const pixel_t*>(mask)[x]) * factor : factor;\n      const pixel_t pix1 = reinterpret_cast<pixel_t*>(p1)[x];\n      const pixel_t pix2 = reinterpret_cast<const pixel_t*>(p2)[x];\n      pixel_t result = pix1 + (int)((pix2 - pix1) * new_factor + 0.5f);\n      reinterpret_cast<pixel_t*>(p1)[x] = result;\n    }\n    p1 += p1_pitch;\n    p2 += p2_pitch;\n    if (has_mask)\n      mask += mask_pitch;\n  }\n}\n\n// instantiate\n// mask yes/no\ntemplate void overlay_blend_sse2_uint<true, uint8_t, true>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\ntemplate void overlay_blend_sse2_uint<true, uint16_t, true>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\ntemplate void overlay_blend_sse2_uint<true, uint16_t, false>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\n//--\ntemplate void overlay_blend_sse2_uint<false, uint8_t, true>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\ntemplate void overlay_blend_sse2_uint<false, uint16_t, true>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\ntemplate void overlay_blend_sse2_uint<false, uint16_t, false>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\n\n\ntemplate<bool has_mask>\nvoid overlay_blend_sse2_float(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch,\n  const int width, const int height, const int /*opacity*/, const float opacity_f, const int bits_per_pixel)\n{\n\n  const int realwidth = width * sizeof(float);\n\n  int wMod16 = (realwidth / 16) * 16;\n  auto opacity_v = _mm_set1_ps(opacity_f);\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wMod16; x += 16) {\n      auto p1_f = _mm_loadu_ps(reinterpret_cast<const float*>(p1 + x));\n      auto p2_f = _mm_loadu_ps(reinterpret_cast<const float*>(p2 + x));\n      __m128 new_mask;\n      if constexpr (has_mask) {\n        new_mask = _mm_loadu_ps(reinterpret_cast<const float*>(mask + x));\n        new_mask = _mm_mul_ps(new_mask, opacity_v);\n      }\n      else {\n        new_mask = opacity_v;\n      }\n      auto result = _mm_add_ps(p1_f, _mm_mul_ps(_mm_sub_ps(p2_f, p1_f), new_mask)); // p1*(1-mask) + p2*mask = p1+(p2-p1)*mask\n\n      _mm_storeu_ps(reinterpret_cast<float*>(p1 + x), result);\n    }\n\n    // Leftover value\n    // Working with exact dimension, overlay is possible atop an existing frame at any position\n    for (int x = wMod16 / sizeof(float); x < width; x++) {\n      auto new_mask = has_mask ? reinterpret_cast<const float*>(mask)[x] * opacity_f : opacity_f;\n      auto p1x = reinterpret_cast<float*>(p1)[x];\n      auto p2x = reinterpret_cast<const float*>(p2)[x];\n      auto result = p1x + (p2x - p1x) * new_mask; // p1x*(1-new_mask) + p2x*mask\n      reinterpret_cast<float*>(p1)[x] = result;\n    }\n\n\n    p1 += p1_pitch;\n    p2 += p2_pitch;\n    if constexpr (has_mask)\n      mask += mask_pitch;\n  }\n}\n\n// instantiate\ntemplate void overlay_blend_sse2_float<false>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int /*opacity*/, const float opacity_f, const int bits_per_pixel);\ntemplate void overlay_blend_sse2_float<true>(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch, const int width, const int height, const int /*opacity*/, const float opacity_f, const int bits_per_pixel);\n\n\n/***************************************\n ********* Mode: Lighten/Darken ********\n ***************************************/\n\ntypedef __m128i (OverlaySseBlendOpaque)(const __m128i&, const __m128i&, const __m128i&);\ntypedef __m128i (OverlaySseCompare)(const __m128i&, const __m128i&, const __m128i&);\n#ifdef X86_32\ntypedef   __m64 (OverlayMmxCompare)(const __m64&, const __m64&, const __m64&);\n#endif\n\ntypedef int (OverlayCCompare)(BYTE, BYTE);\n\n\n#ifdef X86_32\ntemplate<OverlayMmxCompare compare, OverlayCCompare compare_c>\nAVS_FORCEINLINE void overlay_darklighten_mmx(BYTE *p1Y, BYTE *p1U, BYTE *p1V, const BYTE *p2Y, const BYTE *p2U, const BYTE *p2V, int p1_pitch, int p2_pitch, int width, int height) {\n  __m64 zero = _mm_setzero_si64();\n\n  int wMod8 = (width/8) * 8;\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wMod8; x+=8) {\n      // Load Y Plane\n      __m64 p1_y = *(reinterpret_cast<const __m64*>(p1Y+x));\n      __m64 p2_y = *(reinterpret_cast<const __m64*>(p2Y+x));\n\n      // Compare\n      __m64 cmp_result = compare(p1_y, p2_y, zero);\n\n      // Process U Plane\n      __m64 result_y = overlay_blend_opaque_mmx_core(p1_y, p2_y, cmp_result);\n      *reinterpret_cast<__m64*>(p1Y+x) = result_y;\n\n      // Process U plane\n      __m64 p1_u = *(reinterpret_cast<const __m64*>(p1U+x));\n      __m64 p2_u = *(reinterpret_cast<const __m64*>(p2U+x));\n\n      __m64 result_u = overlay_blend_opaque_mmx_core(p1_u, p2_u, cmp_result);\n      *reinterpret_cast<__m64*>(p1U+x) = result_u;\n\n      // Process V plane\n      __m64 p1_v = *(reinterpret_cast<const __m64*>(p1V+x));\n      __m64 p2_v = *(reinterpret_cast<const __m64*>(p2V+x));\n\n      __m64 result_v = overlay_blend_opaque_mmx_core(p1_v, p2_v, cmp_result);\n      *reinterpret_cast<__m64*>(p1V+x) = result_v;\n    }\n\n    // Leftover value\n    for (int x = wMod8; x < width; x++) {\n      int mask = compare_c(p1Y[x], p2Y[x]);\n      p1Y[x] = overlay_blend_opaque_c_core<uint8_t>(p1Y[x], p2Y[x], mask);\n      p1U[x] = overlay_blend_opaque_c_core<uint8_t>(p1U[x], p2U[x], mask);\n      p1V[x] = overlay_blend_opaque_c_core<uint8_t>(p1V[x], p2V[x], mask);\n    }\n\n    p1Y += p1_pitch;\n    p1U += p1_pitch;\n    p1V += p1_pitch;\n\n    p2Y += p2_pitch;\n    p2U += p2_pitch;\n    p2V += p2_pitch;\n  }\n\n  _mm_empty();\n}\n#endif\n\ntemplate <OverlaySseCompare compare, OverlayCCompare compare_c>\nvoid overlay_darklighten_sse2(BYTE *p1Y, BYTE *p1U, BYTE *p1V, const BYTE *p2Y, const BYTE *p2U, const BYTE *p2V, int p1_pitch, int p2_pitch, int width, int height) {\n  __m128i zero = _mm_setzero_si128();\n\n  int wMod16 = (width/16) * 16;\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wMod16; x+=16) {\n      // Load Y Plane\n      __m128i p1_y = _mm_loadu_si128(reinterpret_cast<const __m128i*>(p1Y+x));\n      __m128i p2_y = _mm_loadu_si128(reinterpret_cast<const __m128i*>(p2Y+x));\n\n      // Compare\n      __m128i cmp_result = compare(p1_y, p2_y, zero);\n\n      // Process U Plane\n      __m128i result_y = overlay_blend_opaque_sse2_core(p1_y, p2_y, cmp_result);\n      _mm_storeu_si128(reinterpret_cast<__m128i*>(p1Y+x), result_y);\n\n      // Process U plane\n      __m128i p1_u = _mm_loadu_si128(reinterpret_cast<const __m128i*>(p1U+x));\n      __m128i p2_u = _mm_loadu_si128(reinterpret_cast<const __m128i*>(p2U+x));\n\n      __m128i result_u = overlay_blend_opaque_sse2_core(p1_u, p2_u, cmp_result);\n      _mm_storeu_si128(reinterpret_cast<__m128i*>(p1U+x), result_u);\n\n      // Process V plane\n      __m128i p1_v = _mm_loadu_si128(reinterpret_cast<const __m128i*>(p1V+x));\n      __m128i p2_v = _mm_loadu_si128(reinterpret_cast<const __m128i*>(p2V+x));\n\n      __m128i result_v = overlay_blend_opaque_sse2_core(p1_v, p2_v, cmp_result);\n      _mm_storeu_si128(reinterpret_cast<__m128i*>(p1V+x), result_v);\n    }\n\n    // Leftover value\n    for (int x = wMod16; x < width; x++) {\n      int mask = compare_c(p1Y[x], p2Y[x]);\n      p1Y[x] = overlay_blend_opaque_c_core<uint8_t>(p1Y[x], p2Y[x], mask);\n      p1U[x] = overlay_blend_opaque_c_core<uint8_t>(p1U[x], p2U[x], mask);\n      p1V[x] = overlay_blend_opaque_c_core<uint8_t>(p1V[x], p2V[x], mask);\n    }\n\n    p1Y += p1_pitch;\n    p1U += p1_pitch;\n    p1V += p1_pitch;\n\n    p2Y += p2_pitch;\n    p2U += p2_pitch;\n    p2V += p2_pitch;\n  }\n}\n\ntemplate <OverlaySseCompare compare, OverlayCCompare compare_c>\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid overlay_darklighten_sse41(BYTE *p1Y, BYTE *p1U, BYTE *p1V, const BYTE *p2Y, const BYTE *p2U, const BYTE *p2V, int p1_pitch, int p2_pitch, int width, int height)\n{\n  __m128i zero = _mm_setzero_si128();\n\n  int wMod16 = (width / 16) * 16;\n\n  for (int y = 0; y < height; y++) {\n    for (int x = 0; x < wMod16; x += 16) {\n      // Load Y Plane\n      __m128i p1_y = _mm_loadu_si128(reinterpret_cast<const __m128i*>(p1Y + x));\n      __m128i p2_y = _mm_loadu_si128(reinterpret_cast<const __m128i*>(p2Y + x));\n\n      // Compare\n      __m128i cmp_result = compare(p1_y, p2_y, zero);\n\n      // Process Y Plane\n      __m128i result_y = _mm_blendv_epi8(p1_y, p2_y, cmp_result); // SSE4.1\n      _mm_storeu_si128(reinterpret_cast<__m128i*>(p1Y + x), result_y);\n\n      // Process U plane\n      __m128i p1_u = _mm_loadu_si128(reinterpret_cast<const __m128i*>(p1U + x));\n      __m128i p2_u = _mm_loadu_si128(reinterpret_cast<const __m128i*>(p2U + x));\n\n      __m128i result_u = _mm_blendv_epi8(p1_u, p2_u, cmp_result);\n      _mm_storeu_si128(reinterpret_cast<__m128i*>(p1U + x), result_u);\n\n      // Process V plane\n      __m128i p1_v = _mm_loadu_si128(reinterpret_cast<const __m128i*>(p1V + x));\n      __m128i p2_v = _mm_loadu_si128(reinterpret_cast<const __m128i*>(p2V + x));\n\n      __m128i result_v = _mm_blendv_epi8(p1_v, p2_v, cmp_result);\n      _mm_storeu_si128(reinterpret_cast<__m128i*>(p1V + x), result_v);\n    }\n\n    // Leftover value\n    for (int x = wMod16; x < width; x++) {\n      int mask = compare_c(p1Y[x], p2Y[x]);\n      p1Y[x] = overlay_blend_opaque_c_core<uint8_t>(p1Y[x], p2Y[x], mask);\n      p1U[x] = overlay_blend_opaque_c_core<uint8_t>(p1U[x], p2U[x], mask);\n      p1V[x] = overlay_blend_opaque_c_core<uint8_t>(p1V[x], p2V[x], mask);\n    }\n\n    p1Y += p1_pitch;\n    p1U += p1_pitch;\n    p1V += p1_pitch;\n\n    p2Y += p2_pitch;\n    p2U += p2_pitch;\n    p2V += p2_pitch;\n  }\n}\n\n// Compare functions for lighten and darken mode\nAVS_FORCEINLINE static int overlay_darken_c_cmp(BYTE p1, BYTE p2) {\n  return p2 <= p1;\n}\n\n#ifdef X86_32\nAVS_FORCEINLINE __m64 overlay_darken_mmx_cmp(const __m64& p1, const __m64& p2, const __m64& zero) {\n  __m64 diff = _mm_subs_pu8(p2, p1);\n  return _mm_cmpeq_pi8(diff, zero);\n}\n#endif\n\nAVS_FORCEINLINE __m128i overlay_darken_sse_cmp(const __m128i& p1, const __m128i& p2, const __m128i& zero) {\n  __m128i diff = _mm_subs_epu8(p2, p1);\n  return _mm_cmpeq_epi8(diff, zero);\n}\n\ntemplate<typename pixel_t>\nAVS_FORCEINLINE int overlay_lighten_c_cmp(pixel_t p1, pixel_t p2) {\n  return p2 >= p1;\n}\n\n#ifdef X86_32\nAVS_FORCEINLINE __m64 overlay_lighten_mmx_cmp(const __m64& p1, const __m64& p2, const __m64& zero) {\n  __m64 diff = _mm_subs_pu8(p1, p2);\n  return _mm_cmpeq_pi8(diff, zero);\n}\n#endif\n\nAVS_FORCEINLINE __m128i overlay_lighten_sse_cmp(const __m128i& p1, const __m128i& p2, const __m128i& zero) {\n  __m128i diff = _mm_subs_epu8(p1, p2);\n  return _mm_cmpeq_epi8(diff, zero);\n}\n\n#ifdef X86_32\nvoid overlay_darken_mmx(BYTE *p1Y, BYTE *p1U, BYTE *p1V, const BYTE *p2Y, const BYTE *p2U, const BYTE *p2V, int p1_pitch, int p2_pitch, int width, int height) {\n  overlay_darklighten_mmx<overlay_darken_mmx_cmp, overlay_darken_c_cmp>(p1Y, p1U, p1V, p2Y, p2U, p2V, p1_pitch, p2_pitch, width, height);\n}\nvoid overlay_lighten_mmx(BYTE *p1Y, BYTE *p1U, BYTE *p1V, const BYTE *p2Y, const BYTE *p2U, const BYTE *p2V, int p1_pitch, int p2_pitch, int width, int height) {\n  overlay_darklighten_mmx<overlay_lighten_mmx_cmp, overlay_lighten_c_cmp>(p1Y, p1U, p1V, p2Y, p2U, p2V, p1_pitch, p2_pitch, width, height);\n}\n#endif\n\nvoid overlay_darken_sse2(BYTE *p1Y, BYTE *p1U, BYTE *p1V, const BYTE *p2Y, const BYTE *p2U, const BYTE *p2V, int p1_pitch, int p2_pitch, int width, int height) {\n  overlay_darklighten_sse2<overlay_darken_sse_cmp, overlay_darken_c_cmp>(p1Y, p1U, p1V, p2Y, p2U, p2V, p1_pitch, p2_pitch, width, height);\n}\nvoid overlay_lighten_sse2(BYTE *p1Y, BYTE *p1U, BYTE *p1V, const BYTE *p2Y, const BYTE *p2U, const BYTE *p2V, int p1_pitch, int p2_pitch, int width, int height) {\n  overlay_darklighten_sse2<overlay_lighten_sse_cmp, overlay_lighten_c_cmp>(p1Y, p1U, p1V, p2Y, p2U, p2V, p1_pitch, p2_pitch, width, height);\n}\n\nvoid overlay_darken_sse41(BYTE *p1Y, BYTE *p1U, BYTE *p1V, const BYTE *p2Y, const BYTE *p2U, const BYTE *p2V, int p1_pitch, int p2_pitch, int width, int height) {\n  overlay_darklighten_sse41<overlay_darken_sse_cmp, overlay_darken_c_cmp>(p1Y, p1U, p1V, p2Y, p2U, p2V, p1_pitch, p2_pitch, width, height);\n}\nvoid overlay_lighten_sse41(BYTE *p1Y, BYTE *p1U, BYTE *p1V, const BYTE *p2Y, const BYTE *p2U, const BYTE *p2V, int p1_pitch, int p2_pitch, int width, int height) {\n  overlay_darklighten_sse41<overlay_lighten_sse_cmp, overlay_lighten_c_cmp>(p1Y, p1U, p1V, p2Y, p2U, p2V, p1_pitch, p2_pitch, width, height);\n}\n"
  },
  {
    "path": "avs_core/filters/overlay/intel/blend_common_sse.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// Overlay (c) 2003, 2004 by Klaus Post\n\n#ifndef __blend_common_sse_h\n#define __blend_common_sse_h\n\n#include <avs/types.h>\n\n// Mode: Overlay\n\ntemplate<bool has_mask, typename pixel_t, bool lessthan16bits>\nvoid overlay_blend_sse2_uint(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch,\n  const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\n\ntemplate<bool has_mask>\nvoid overlay_blend_sse2_float(BYTE* p1, const BYTE* p2, const BYTE* mask,\n  const int p1_pitch, const int p2_pitch, const int mask_pitch,\n  const int width, const int height, const int opacity, const float opacity_f, const int bits_per_pixel);\n\n#ifdef X86_32\nvoid overlay_darken_mmx(BYTE* p1Y, BYTE* p1U, BYTE* p1V, const BYTE* p2Y, const BYTE* p2U, const BYTE* p2V, int p1_pitch, int p2_pitch, int width, int height);\nvoid overlay_lighten_mmx(BYTE* p1Y, BYTE* p1U, BYTE* p1V, const BYTE* p2Y, const BYTE* p2U, const BYTE* p2V, int p1_pitch, int p2_pitch, int width, int height);\n#endif\n\nvoid overlay_darken_sse2(BYTE* p1Y, BYTE* p1U, BYTE* p1V, const BYTE* p2Y, const BYTE* p2U, const BYTE* p2V, int p1_pitch, int p2_pitch, int width, int height);\nvoid overlay_lighten_sse2(BYTE* p1Y, BYTE* p1U, BYTE* p1V, const BYTE* p2Y, const BYTE* p2U, const BYTE* p2V, int p1_pitch, int p2_pitch, int width, int height);\n\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid overlay_darken_sse41(BYTE* p1Y, BYTE* p1U, BYTE* p1V, const BYTE* p2Y, const BYTE* p2U, const BYTE* p2V, int p1_pitch, int p2_pitch, int width, int height);\n#if defined(GCC) || defined(CLANG)\n__attribute__((__target__(\"sse4.1\")))\n#endif\nvoid overlay_lighten_sse41(BYTE* p1Y, BYTE* p1U, BYTE* p1V, const BYTE* p2Y, const BYTE* p2U, const BYTE* p2V, int p1_pitch, int p2_pitch, int width, int height);\n\n#endif // __blend_common_sse_h\n"
  },
  {
    "path": "avs_core/filters/overlay/overlay.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// Overlay (c) 2003, 2004 by Klaus Post\n#include <avisynth.h>\n#ifdef AVS_WINDOWS\n    #include <avs/win.h>\n#else\n    #include <avs/posix.h>\n#endif\n\n#include <stdlib.h>\n#include \"overlay.h\"\n#include <string>\n#include \"../core/internal.h\"\n\n/********************************************************************\n***** Declare index of new filters for Avisynth's filter engine *****\n********************************************************************/\n\nextern const AVSFunction Overlay_filters[] = {\n  { \"Overlay\", BUILTIN_FUNC_PREFIX, \"cc[x]i[y]i[mask]c[opacity]f[mode]s[greymask]b[output]s[ignore_conditional]b[PC_Range]b[use444]b[condvarsuffix]s\", Overlay::Create },\n    // 0, src clip\n    // 1, overlay clip\n    // 2, x\n    // 3, y\n    // 4, mask clip\n    // 5, overlay opacity.(0.0->1.0)\n    // 6, mode string, \"blend\", \"add\"\n    // 7, greymask bool - true = only use luma information for mask\n    // 8, output type, string\n    // 9, ignore conditional variabels\n    // 10, full YUV range.\n    // 11, ignore 4:4:4 conversion\n    // 12, conditional variable suffix AVS+\n  { 0 }\n};\n\nenum {\n  ARG_SRC = 0,\n  ARG_OVERLAY = 1,\n  ARG_X = 2,\n  ARG_Y = 3,\n  ARG_MASK = 4,\n  ARG_OPACITY = 5,\n  ARG_MODE = 6,\n  ARG_GREYMASK = 7,\n  ARG_OUTPUT = 8,\n  ARG_IGNORE_CONDITIONAL = 9,\n  ARG_FULL_RANGE = 10,\n  ARG_USE444 = 11, // 170103 possible conversionless option experimental\n  ARG_CONDVARSUFFIX = 12 // 190408\n};\n\nstatic int getPixelTypeWithoutAlpha(VideoInfo& vi)\n{\n  return (vi.IsYUVA() ? (vi.pixel_type & ~VideoInfo::CS_YUVA) | VideoInfo::CS_YUV :\n    (vi.IsPlanarRGBA() ? (vi.pixel_type & ~VideoInfo::CS_RGBA_TYPE) | VideoInfo::CS_RGB_TYPE : vi.pixel_type));\n}\n\nOverlay::Overlay(PClip _child, AVSValue args, IScriptEnvironment *env) :\nGenericVideoFilter(_child), child444(nullptr) {\n\n  // child here is always planar: no packed RGB or YUY2 allowed\n\n  full_range = args[ARG_FULL_RANGE].AsBool(false);  // Maintain CCIR601 range when converting to/from RGB.\n  bool use444_defined = args[ARG_USE444].Defined();\n  use444 = args[ARG_USE444].AsBool(true);  // avs+ option to use 444-conversionless mode\n  name = args[ARG_MODE].AsString(\"Blend\");\n  condVarSuffix = args[ARG_CONDVARSUFFIX].AsString(\"\");\n\n  // Make copy of the VideoInfo\n  inputVi = vi;\n  // by default outputVi is the same as inputVi\n  outputVi = vi;\n  viInternalWorkingFormat = vi;\n\n  opacity_f = (float)args[ARG_OPACITY].AsDblDef(1.0); // for float support\n  opacity = (int)(256.0*opacity_f + 0.5); // range is converted to 256 for all all bit_depth\n  offset_x = args[ARG_X].AsInt(0);\n  offset_y = args[ARG_Y].AsInt(0);\n\n  if (!args[ARG_OVERLAY].IsClip())\n    env->ThrowError(\"Overlay: Overlay parameter is not a clip\");\n\n  overlay = args[ARG_OVERLAY].AsClip();\n\n  overlayVi = overlay->GetVideoInfo();\n  // overlay clip to always planar\n  if (overlayVi.IsRGB() && !overlayVi.IsPlanar()) {\n    // no packed RGB allowed from now on, autoconvert from packed\n    AVSValue new_args[1] = { overlay };\n    if (overlayVi.IsRGB24() || overlayVi.IsRGB48())\n      overlay = env->Invoke(\"ConvertToPlanarRGB\", AVSValue(new_args, 1)).AsClip();\n    else\n      overlay = env->Invoke(\"ConvertToPlanarRGBA\", AVSValue(new_args, 1)).AsClip();\n    overlayVi = overlay->GetVideoInfo();\n  }\n  else if (overlayVi.IsYUY2()) {\n    // convert YUY2 to 422, keep internals simple\n    AVSValue new_args[2] = { overlay, false };\n    overlay = env->Invoke(\"ConvertToYUV422\", AVSValue(new_args, 2)).AsClip();\n    overlayVi = overlay->GetVideoInfo();\n  }\n\n  SetOfModeByName(name, env); // setting of_mode, checks valid mode strings as well\n\n  viInternalOverlayWorkingFormat = overlayVi;\n\n  greymask = args[ARG_GREYMASK].AsBool(true);  // Grey mask, default true\n  ignore_conditional = args[ARG_IGNORE_CONDITIONAL].AsBool(false);  // Don't ignore conditionals by default\n\n  mask = nullptr;\n  if (args[ARG_MASK].Defined()) {  // Mask defined\n    mask = args[ARG_MASK].AsClip();\n    maskVi = mask->GetVideoInfo();\n    if (maskVi.width!=overlayVi.width) {\n      env->ThrowError(\"Overlay: Mask and overlay must have the same image size! (Width is not the same)\");\n    }\n    if (maskVi.height!=overlayVi.height) {\n      env->ThrowError(\"Overlay: Mask and overlay must have the same image size! (Height is not the same)\");\n    }\n    if (maskVi.BitsPerComponent() != overlayVi.BitsPerComponent()) {\n      env->ThrowError(\"Overlay: Mask and overlay must have the same bit depths!\");\n    }\n  }\n\n  pixelsize = vi.ComponentSize();\n  bits_per_pixel = vi.BitsPerComponent();\n\n  if (bits_per_pixel != overlayVi.BitsPerComponent()) {\n    env->ThrowError(\"Overlay: input and overlay clip must have the same bit depths!\");\n  }\n\n  // already filled vi = child->GetVideoInfo();\n  // parse and check output format override vi\n  output_pixel_format_override = args[ARG_OUTPUT].AsString(nullptr);\n  if(output_pixel_format_override) {\n    int output_pixel_type = GetPixelTypeFromName(output_pixel_format_override);\n    if(output_pixel_type == VideoInfo::CS_UNKNOWN)\n      env->ThrowError(\"Overlay: invalid pixel_type!\");\n\n    outputVi.pixel_type = output_pixel_type; // override output pixel format\n    if(outputVi.BitsPerComponent() != inputVi.BitsPerComponent())\n      env->ThrowError(\"Overlay: output bitdepth should be the same as input's!\");\n  }\n\n  if (bits_per_pixel == 32) {\n    if (_stricmp(name, \"Blend\") != 0 && _stricmp(name, \"Luma\") != 0 && _stricmp(name, \"Chroma\") != 0\n      && _stricmp(name, \"Add\") != 0 && _stricmp(name, \"Subtract\") != 0) {\n      env->ThrowError(\"Overlay: only Blend, Luma, Chroma, Add and Subtract modes are supported for 32-bit float video\");\n    }\n  }\n\n  if (vi.Is444())\n    use444 = true; // 444 is conversionless by default\n\n  // let use444=false to go live for subfilters that are ready to use it\n  // except: RGB must be converted to 444 for Luma and Chroma operation\n  if (vi.IsRGB() && (_stricmp(name, \"Luma\") == 0 || _stricmp(name, \"Chroma\") == 0)) {\n    if (use444_defined && !use444) {\n      env->ThrowError(\"Overlay: for RGB you cannot specify use444=false for overlay mode: %s\", name);\n    }\n    use444 = true;\n  }\n  else if (!use444_defined &&\n    (vi.IsY() || vi.Is420() || vi.Is422() || vi.IsRGB()) &&\n    (_stricmp(name, \"Blend\") == 0 || _stricmp(name, \"Luma\") == 0 || _stricmp(name, \"Chroma\") == 0))\n  {\n    use444 = false; // default false for modes capable handling of use444==false, and valid formats\n  }\n  else if (!use444_defined &&\n    (vi.IsRGB()) &&\n    (_stricmp(name, \"Add\") == 0 || _stricmp(name, \"Subtract\") == 0))\n  {\n    use444 = false; // native RGB support for Add/Subtract\n  }\n\n  if (!use444) {\n    // check if we can work in conversionless mode\n    // 1.) colorspace is greyscale, 4:2:0 or 4:2:2 or any RGB\n    // 2.) mode is \"blend-like\" (at the moment)\n    if (!vi.IsY() && !vi.Is420() && !vi.Is422() && !vi.IsRGB())\n      env->ThrowError(\"Overlay: use444=false is allowed only for greyscale, 4:2:0, 4:2:2 or any RGB video formats\");\n    //if (output_pixel_format_override && outputVi->pixel_type != vi.pixel_type)\n    //  env->ThrowError(\"Overlay: use444=false is allowed only when no output pixel format is specified\");\n    if (_stricmp(name, \"Blend\") != 0 && _stricmp(name, \"Luma\") != 0 && _stricmp(name, \"Chroma\") != 0 &&\n      (_stricmp(name, \"Add\") != 0 && _stricmp(name, \"Subtract\") != 0) && !vi.IsRGB())\n      env->ThrowError(\"Overlay: cannot specify use444=false for this overlay mode: %s\", name);\n  }\n\n  bool hasAlpha = vi.IsYUVA() || vi.IsPlanarRGBA();\n\n  // set internal working format\n  if (use444) {\n    // we convert everything to 4:4:4\n    // fill yuv 444 template\n    switch (bits_per_pixel) {\n    case 8: viInternalWorkingFormat.pixel_type = hasAlpha ? VideoInfo::CS_YUVA444 : VideoInfo::CS_YV24; break;\n    case 10: viInternalWorkingFormat.pixel_type = hasAlpha ? VideoInfo::CS_YUVA444P10 : VideoInfo::CS_YUV444P10; break;\n    case 12: viInternalWorkingFormat.pixel_type = hasAlpha ? VideoInfo::CS_YUVA444P12 : VideoInfo::CS_YUV444P12; break;\n    case 14: viInternalWorkingFormat.pixel_type = hasAlpha ? VideoInfo::CS_YUVA444P14 : VideoInfo::CS_YUV444P14; break;\n    case 16: viInternalWorkingFormat.pixel_type = hasAlpha ? VideoInfo::CS_YUVA444P16 : VideoInfo::CS_YUV444P16; break;\n    case 32: viInternalWorkingFormat.pixel_type = hasAlpha ? VideoInfo::CS_YUVA444PS : VideoInfo::CS_YUV444PS; break;\n    }\n  }\n  else {\n    // keep input format for internal format. Always 4:2:0, 4:2:2 (or 4:4:4 / Planar RGB)\n    // filters have to prepare to work for these formats\n    viInternalWorkingFormat = vi;\n  }\n\n  viInternalOverlayWorkingFormat.pixel_type = viInternalWorkingFormat.pixel_type;\n\n  // Set GetFrame's real output format\n  if (outputVi.Is420() && use444)\n  {\n    // on-the-fly fast conversion at the end of GetFrame\n    switch (bits_per_pixel) {\n    case 8: vi.pixel_type = hasAlpha ? VideoInfo::CS_YUVA420 : VideoInfo::CS_YV12; break;\n    case 10: vi.pixel_type = hasAlpha ? VideoInfo::CS_YUVA420P10 : VideoInfo::CS_YUV420P10; break;\n    case 12: vi.pixel_type = hasAlpha ? VideoInfo::CS_YUVA420P12 : VideoInfo::CS_YUV420P12; break;\n    case 14: vi.pixel_type = hasAlpha ? VideoInfo::CS_YUVA420P14 : VideoInfo::CS_YUV420P14; break;\n    case 16: vi.pixel_type = hasAlpha ? VideoInfo::CS_YUVA420P16 : VideoInfo::CS_YUV420P16; break;\n    case 32: vi.pixel_type = hasAlpha ? VideoInfo::CS_YUVA420PS : VideoInfo::CS_YUV420PS; break;\n    }\n  }\n  else if (outputVi.Is422() && use444)\n  {\n    // on-the-fly fast conversion at the end of GetFrame\n    switch (bits_per_pixel) {\n    case 8: vi.pixel_type = hasAlpha ? VideoInfo::CS_YUVA422 : VideoInfo::CS_YV16; break;\n    case 10: vi.pixel_type = hasAlpha ? VideoInfo::CS_YUVA422P10 : VideoInfo::CS_YUV422P10; break;\n    case 12: vi.pixel_type = hasAlpha ? VideoInfo::CS_YUVA422P12 : VideoInfo::CS_YUV422P12; break;\n    case 14: vi.pixel_type = hasAlpha ? VideoInfo::CS_YUVA422P14 : VideoInfo::CS_YUV422P14; break;\n    case 16: vi.pixel_type = hasAlpha ? VideoInfo::CS_YUVA422P16 : VideoInfo::CS_YUV422P16; break;\n    case 32: vi.pixel_type = hasAlpha ? VideoInfo::CS_YUVA422PS : VideoInfo::CS_YUV422PS; break;\n    }\n  }\n  else if (outputVi.IsYUY2())\n  {\n    // on-the-fly fast conversion at the end of GetFrame\n    vi.pixel_type = VideoInfo::CS_YUY2;\n  } else {\n    vi.pixel_type = viInternalWorkingFormat.pixel_type;\n    // Y,420,422,444,PlanarRGB (and packed RGB converted to any intermediate)\n  }\n\n  // internal working formats:\n  // - subsampled planar: 420, 422\n  // - full info: 444, planarRGB(A)\n  // - full info 1 plane: greyscale\n  isInternalRGB = viInternalWorkingFormat.IsRGB(); // must be planar rgb\n  isInternalGrey = viInternalWorkingFormat.IsY();\n  isInternal444 = viInternalWorkingFormat.Is444();\n  isInternal422 = viInternalWorkingFormat.Is422();\n  isInternal420 = viInternalWorkingFormat.Is420();\n\n#if 0\n  // FIXME but left here: When this one is here and not in GetFrame, it's much slower.\n  // base clip conversion to internal 444 working format\n  if (inputVi.pixel_type != viInternalWorkingFormat.pixel_type &&\n    isInternal444)\n  {\n    // these two has special quick conversion in GetFrame\n    if (!inputVi.Is420() && !inputVi.Is422()) {\n      // convert input to 444\n      if (inputVi.IsRGB()) {\n        AVSValue new_args[3] = { child, false, full_range ? \"PC.601\" : \"rec601\" }; // clip, interlaced, matrix\n        child444 = env->Invoke(\"ConvertToYUV444\", AVSValue(new_args, 3)).AsClip();\n      }\n      else {\n        // Y, 411?\n        AVSValue new_args[2] = { child, false };\n        child444 = env->Invoke(\"ConvertToYUV444\", AVSValue(new_args, 2)).AsClip();\n      }\n    }\n  }\n#endif\n  // more format match of overlay\n  if (overlayVi.IsRGB()) {\n    if (isInternalGrey) {\n      AVSValue new_args[2] = { overlay, full_range ? \"PC.601\" : \"rec601\" };\n      overlay = env->Invoke(\"ConvertToY\", AVSValue(new_args, 2)).AsClip();\n      overlayVi = overlay->GetVideoInfo();\n    }\n    else if (!isInternalRGB) {\n      AVSValue new_args[3] = { overlay, false, full_range ? \"PC.601\" : \"rec601\" };\n      overlay = env->Invoke(\"ConvertToYUV444\", AVSValue(new_args, 3)).AsClip();\n      overlayVi = overlay->GetVideoInfo();\n    }\n  }\n  if (isInternal444) {\n    // 420 and 422 has quick internal conversion in GetFrame, leave them, along with 444.\n    if (!overlayVi.Is444() && !overlayVi.Is420() && !overlayVi.Is422()) {\n      // 411, Y\n      // params: clip, interlaced\n      AVSValue new_args[2] = { overlay, false };\n      overlay = env->Invoke(\"ConvertToYUV444\", AVSValue(new_args, 2)).AsClip();\n      overlayVi = overlay->GetVideoInfo();\n    }\n  }\n  else if (isInternalRGB) {\n    if (!overlayVi.IsPlanarRGB() && !overlayVi.IsPlanarRGBA()) {\n      AVSValue new_args[3] = { overlay, full_range ? \"PC.601\" : \"rec601\", false};\n      if (overlayVi.IsYUVA())\n        overlay = env->Invoke(\"ConvertToPlanarRGBA\", AVSValue(new_args, 3)).AsClip();\n      else\n        overlay = env->Invoke(\"ConvertToPlanarRGB\", AVSValue(new_args, 3)).AsClip();\n      overlayVi = overlay->GetVideoInfo();\n    }\n  }\n  else if (isInternal420) {\n    if (!overlayVi.Is420()) {\n      // convert to 444. Quick conversion further in GetFrame\n      AVSValue new_args[2] = { overlay, false };\n      overlay = env->Invoke(\"ConvertToYUV444\", AVSValue(new_args, 2)).AsClip();\n      overlayVi = overlay->GetVideoInfo();\n    }\n  }\n  else if (isInternal422) {\n    if (!overlayVi.Is422()) {\n      // convert to 444. Quick conversion further in GetFrame\n      AVSValue new_args[2] = { overlay, false };\n      overlay = env->Invoke(\"ConvertToYUV444\", AVSValue(new_args, 2)).AsClip();\n      overlayVi = overlay->GetVideoInfo();\n    }\n  }\n\n  if (mask) {\n    if (maskVi.IsY() || isInternalGrey)\n      greymask = true;\n\n    // mask to always planar\n    if (maskVi.IsRGB() && !maskVi.IsPlanar()) {\n      // no packed RGB mask allowed from now on, autoconvert from packed\n      AVSValue new_args[1] = { mask };\n      if (maskVi.IsRGB24() || maskVi.IsRGB48())\n        mask = env->Invoke(\"ConvertToPlanarRGB\", AVSValue(new_args, 1)).AsClip();\n      else\n        mask = env->Invoke(\"ConvertToPlanarRGBA\", AVSValue(new_args, 1)).AsClip();\n      maskVi = mask->GetVideoInfo();\n    }\n    else if (maskVi.IsYUY2()) {\n      // convert YUY2 mask to 422, keep internals simple\n      AVSValue new_args[2] = { mask, false };\n      mask = env->Invoke(\"ConvertToYUV422\", AVSValue(new_args, 2)).AsClip();\n      maskVi = mask->GetVideoInfo();\n    }\n\n    if (maskVi.IsRGB()) {\n      if (greymask) {\n        // Compatibility: ExtractB. See notes above.\n        // This is good, because in the old times rgb32clip.ShowAlpha() was\n        // used for feeding mask to overlay, that spreads alpha to all channels, so classic avisynth chose\n        // B channel for source. (=R=G)\n        // So we are not using greyscale conversion here at mask for compatibility reasons\n        // Still: recommended usage for mask: rgbclip.ExtractA()\n        /*\n        AVSValue new_args[2] = { mask, (full_range) ? \"PC.601\" : \"rec601\" };\n        mask2 = env->Invoke(\"ConvertToY\", AVSValue(new_args, 2)).AsClip();\n        */\n        AVSValue new_args[1] = { mask };\n        mask = env->Invoke(\"ExtractB\", AVSValue(new_args, 1)).AsClip();\n        maskVi = mask->GetVideoInfo();\n      }\n      else {\n        if (!isInternalRGB) {\n          AVSValue new_args[3] = { mask, false, full_range ? \"PC.601\" : \"rec601\" };\n          mask = env->Invoke(\"ConvertToYUV444\", AVSValue(new_args, 3)).AsClip();\n          maskVi = mask->GetVideoInfo();\n        }\n      }\n    } // RGB mask cases end\n\n    if (getPixelTypeWithoutAlpha(maskVi) != getPixelTypeWithoutAlpha(viInternalWorkingFormat))\n    {\n      if (!maskVi.IsRGB()) {\n        if (isInternalRGB) {\n          if (!greymask) {\n            // mask clip was not RGB, but our internal format is.\n            // convert from any (Y, YUV) mask format to planar RGB\n            AVSValue new_args[3] = { mask, full_range ? \"PC.601\" : \"rec601\", false };\n            mask = env->Invoke(\"ConvertToPlanarRGB\", AVSValue(new_args, 3)).AsClip();\n          }\n        }\n        else {\n          if (greymask) {\n            AVSValue new_args[1] = { mask }; // mask is not rgb here, no matrix param\n            mask = env->Invoke(\"ConvertToY\", AVSValue(new_args, 1)).AsClip();\n          }\n          else {\n            if (isInternal420) {\n              if (!maskVi.Is420()) {\n                AVSValue new_args[2] = { mask, false };\n                mask = env->Invoke(\"ConvertToYUV444\", AVSValue(new_args, 2)).AsClip();\n                // quick internal 444->420 conversion later in GetFrame\n              }\n            } \n            else if (isInternal422) {\n              if (!maskVi.Is422()) {\n                AVSValue new_args[2] = { mask, false };\n                mask = env->Invoke(\"ConvertToYUV444\", AVSValue(new_args, 2)).AsClip();\n                // quick internal 444->422 conversion later in GetFrame\n              }\n            }\n            else if (isInternal444 && (maskVi.Is420() || maskVi.Is422() || maskVi.Is444())) {\n              // do nothing, quick ->444 conversion inside GetFrame\n            }\n            else {\n              // all other !greymask cases to 444\n              AVSValue new_args[2] = { mask, false };\n                mask = env->Invoke(\"ConvertToYUV444\", AVSValue(new_args, 2)).AsClip();\n            }\n          }\n        }\n      }\n      maskVi = mask->GetVideoInfo();\n    }\n  }\n}\n\n\nOverlay::~Overlay() {\n}\n\nPVideoFrame __stdcall Overlay::GetFrame(int n, IScriptEnvironment *env) {\n  // fixme: do all necessary conversions in filter creation, not in GetFrame!\n  // 20251122: tried but for some reason it's slower!\n  int op_offset;\n  float op_offset_f;\n  int con_x_offset;\n  int con_y_offset;\n  FetchConditionals(env, &op_offset, &op_offset_f, &con_x_offset, &con_y_offset, ignore_conditional, condVarSuffix);\n\n  AVSValue child2;\n  PVideoFrame frame;\n\n  if (inputVi.pixel_type == viInternalWorkingFormat.pixel_type)\n  {\n    // get frame as is.\n    // includes 420, 422, 444, planarRGB(A)\n    frame = child->GetFrame(n, env);\n  }\n  else if (isInternal444) {\n    if (inputVi.Is420()) {\n      // use blazing fast YV12 -> YV24 converter, not exact chroma placement though\n      PVideoFrame Inframe = child->GetFrame(n, env);\n      frame = env->NewVideoFrameP(viInternalWorkingFormat, &Inframe);\n      // no fancy options for chroma resampler, etc.. simply fast\n      Convert444FromYV12(Inframe, frame, pixelsize, bits_per_pixel, env);\n    }\n    else if (inputVi.Is422()) {\n      // use blazing fast YV16 -> YV24 converter, not exact chroma placement though\n      PVideoFrame Inframe = child->GetFrame(n, env);\n      frame = env->NewVideoFrameP(viInternalWorkingFormat, &Inframe);\n      Convert444FromYV16(Inframe, frame, pixelsize, bits_per_pixel, env);\n    }\n#if 1\n    // FIXME but left here: When this one is NOT here in GetFrame, but in ctor, it's much slower.\n    else if (inputVi.IsRGB()) {\n      AVSValue new_args[3] = { child, false, full_range ? \"PC.601\" : \"rec601\" };\n      child2 = env->Invoke(\"ConvertToYUV444\", AVSValue(new_args, 3)).AsClip();\n      frame = child2.AsClip()->GetFrame(n, env);\n    }\n    else {\n      AVSValue new_args[2] = { child, false };\n      child2 = env->Invoke(\"ConvertToYUV444\", AVSValue(new_args, 2)).AsClip();\n      frame = child2.AsClip()->GetFrame(n, env);\n    }\n#else\n    else {\n      frame = child444->GetFrame(n, env);\n      // from non 420/422 such as RGB, the conversion happened already in constructor\n      // (FIXME note: slower)\n    }\n#endif\n  }\n  else if (isInternalRGB) {\n    if(inputVi.IsYUV()) {\n      // Just for the sake of completeness.\n      // when input is YUV, internal working format is never RGB\n      env->ThrowError(\"Overlay: internal error; isInternalRGB but input is YUV\");\n    }\n  }\n\n  // Fetch current frame and convert it to internal format\n  env->MakeWritable(&frame);\n\n  ImageOverlayInternal* img = new ImageOverlayInternal(frame, vi.width, vi.height, viInternalWorkingFormat, child->GetVideoInfo().IsYUVA() || child->GetVideoInfo().IsPlanarRGBA(), false, env);\n\n  PVideoFrame Oframe;\n  AVSValue overlay2;\n\n  PVideoFrame Mframe;\n  ImageOverlayInternal* maskImg = NULL;\n\n  // overlay clip should be converted to internal format if different, except for internal Y,\n  // for which original planar YUV is OK\n  if(overlayVi.pixel_type == viInternalWorkingFormat.pixel_type)\n  {\n    // don't convert is input and overlay is the same formats\n    // so we can work in YUV420 or YUV422 and Planar RGB directly besides YUV444 (use444==false)\n    Oframe = overlay->GetFrame(n, env);\n  }\n  else if (isInternal444) {\n    if (of_mode == OF_Multiply)\n    {\n      // 'multiply' is always using only Y from overlay clip, no need to match chroma\n      Oframe = overlay->GetFrame(n, env);\n    }\n    else if (overlayVi.Is420()) {\n      // use blazing fast YV12 -> YV24 converter. Note: not exact chroma placement\n      PVideoFrame frame = overlay->GetFrame(n, env);\n      Oframe = env->NewVideoFrameP(viInternalOverlayWorkingFormat, &frame);\n      // no fancy options for chroma resampler, etc.. simply fast\n      Convert444FromYV12(frame, Oframe, pixelsize, bits_per_pixel, env);\n    }\n    else if (overlayVi.Is422()) {\n      // use blazing fast YV16 -> YV24 converter\n      PVideoFrame frame = overlay->GetFrame(n, env);\n      Oframe = env->NewVideoFrameP(viInternalOverlayWorkingFormat, &frame);\n      Convert444FromYV16(frame, Oframe, pixelsize, bits_per_pixel, env);\n    }\n    else {\n      if (!overlayVi.Is444())\n        env->ThrowError(\"Overlay: internal error, wrong internal overlayVi format for internal 444, must be 420,422 or 444\");\n      Oframe = overlay->GetFrame(n, env);\n    }\n  }\n  else if(isInternalGrey) {\n    if (!overlayVi.IsY() && !overlayVi.IsYUV() && !overlayVi.IsYUVA())\n      env->ThrowError(\"Overlay: internal error, overlayVi must be Y or YUV(A) for internalGrey\");\n    // they are good as-is, we'll use only Y\n    Oframe = overlay->GetFrame(n, env);\n  }\n  else if (isInternalRGB) {\n    if (!overlayVi.IsPlanarRGB() && !overlayVi.IsPlanarRGBA())\n      env->ThrowError(\"Overlay: internal error, overlayVi must be planar RGB(A) for internalRGB\");\n    Oframe = overlay->GetFrame(n, env);\n  }\n  else if (isInternal420) {\n    if (overlayVi.Is420()) {\n      Oframe = overlay->GetFrame(n, env);\n    }\n    else if (overlayVi.Is444()) {\n      PVideoFrame frame = overlay->GetFrame(n, env);\n      Oframe = env->NewVideoFrameP(viInternalOverlayWorkingFormat, &frame);\n      // no fancy options for chroma resampler, etc.. simply fast\n      Convert444ToYV12(frame, Oframe, pixelsize, bits_per_pixel, env);\n    }\n    else {\n      env->ThrowError(\"Overlay: internal error, overlayVi must be 420 or 444 for internal420\");\n    }\n  }\n  else if (isInternal422) {\n    if (overlayVi.Is422()) {\n      Oframe = overlay->GetFrame(n, env);\n    } \n    else if(overlayVi.Is444()) {\n      PVideoFrame frame = overlay->GetFrame(n, env);\n      Oframe = env->NewVideoFrameP(viInternalOverlayWorkingFormat, &frame);\n      // no fancy options for chroma resampler, etc.. simply fast\n      Convert444ToYV16(frame, Oframe, pixelsize, bits_per_pixel, env);\n    }\n    else {\n      env->ThrowError(\"Overlay: internal error, overlayVi must be 422 or 444 for internal420\");\n    }\n  }\n  // Fetch current overlay and convert it to internal format\n  VideoInfo actual_viInternalOverlayWorkingFormat = viInternalOverlayWorkingFormat;\n  if (of_mode == OF_Multiply) {\n    // this mode does not need chroma for Overlay\n    switch (bits_per_pixel) {\n    case 8: actual_viInternalOverlayWorkingFormat.pixel_type = VideoInfo::CS_Y8; break;\n    case 10: actual_viInternalOverlayWorkingFormat.pixel_type = VideoInfo::CS_Y10; break;\n    case 12: actual_viInternalOverlayWorkingFormat.pixel_type = VideoInfo::CS_Y12; break;\n    case 14: actual_viInternalOverlayWorkingFormat.pixel_type = VideoInfo::CS_Y14; break;\n    case 16: actual_viInternalOverlayWorkingFormat.pixel_type = VideoInfo::CS_Y16; break;\n    case 32: actual_viInternalOverlayWorkingFormat.pixel_type = VideoInfo::CS_Y32; break;\n    }\n  }\n\n  ImageOverlayInternal* overlayImg = new ImageOverlayInternal(Oframe, overlayVi.width, overlayVi.height, actual_viInternalOverlayWorkingFormat, overlay->GetVideoInfo().IsYUVA() || overlay->GetVideoInfo().IsPlanarRGBA(), false, env);\n\n  // Clip overlay to original image\n  ClipFrames(img, overlayImg, offset_x + con_x_offset, offset_y + con_y_offset);\n\n  if (overlayImg->IsSizeZero()) { // Nothing to overlay\n  }\n  else {\n    // fetch current mask (if given)\n    if (mask) {\n\n      AVSValue mask2;\n      if(maskVi.IsRGB() && greymask)\n        env->ThrowError(\"Overlay: Internal error, this mask cannot be RGB here, it should be Y or 444 by now.\");\n      if (maskVi.IsRGB() && isInternal444)\n        env->ThrowError(\"Overlay: Internal error, this mask cannot be RGB here, it should be 444 by now.\");\n      if (!greymask && isInternalRGB && !maskVi.IsRGB())\n        env->ThrowError(\"Overlay: Internal error, this mask must be RGB here if greymask==false and isInternalRGB.\");\n\n      if (greymask\n        || getPixelTypeWithoutAlpha(maskVi) == getPixelTypeWithoutAlpha(viInternalWorkingFormat)\n        || (!greymask && isInternalRGB)\n        )\n      {\n        // 4:4:4,\n        // 4:2:0, 4:2:2 -> greymask uses Y\n        // internalworking format: 4:4:4, 4:2:2, 4:2:0\n        Mframe = mask->GetFrame(n, env);\n      }\n      else if (isInternal444 || greymask) {\n        if (maskVi.Is420()) {\n          // use blazing fast YV12 -> YV24 converter\n          PVideoFrame frame = mask->GetFrame(n, env);\n          Mframe = env->NewVideoFrameP(viInternalOverlayWorkingFormat, &frame);\n          // no fancy options for chroma resampler, etc.. simply fast\n          Convert444FromYV12(frame, Mframe, pixelsize, bits_per_pixel, env);\n          // convert frameSrc420 -> frame\n        }\n        else if (maskVi.Is422()) {\n          // use blazing fast YV16 -> YV24 converter\n          PVideoFrame frame = mask->GetFrame(n, env);\n          Mframe = env->NewVideoFrameP(viInternalOverlayWorkingFormat, &frame);\n          Convert444FromYV16(frame, Mframe, pixelsize, bits_per_pixel, env);\n        }\n        else \n          env->ThrowError(\"Overlay: internal error, maskVi is not 420 or 422 here\");\n      }\n      else {\n        // greymask == false\n        if (isInternal420) {\n          // mask is 444 here\n          PVideoFrame frame = mask->GetFrame(n, env);\n          Mframe = env->NewVideoFrameP(viInternalOverlayWorkingFormat, &frame);\n          // no fancy options for chroma resampler, etc.. simply fast\n          Convert444ToYV12(frame, Mframe, pixelsize, bits_per_pixel, env);\n        }\n        else if (isInternal422) {\n          // mask is 444 here\n          PVideoFrame frame = mask->GetFrame(n, env);\n          Mframe = env->NewVideoFrameP(viInternalOverlayWorkingFormat, &frame);\n          // no fancy options for chroma resampler, etc.. simply fast\n          Convert444ToYV16(frame, Mframe, pixelsize, bits_per_pixel, env);\n        }\n        else {\n          if (!maskVi.Is444())\n            env->ThrowError(\"Overlay: internal error, maskVi must be 444 here in greymask==false\");\n          Mframe = mask->GetFrame(n, env);;\n        }\n      }\n      // MFrame here is either internalWorkingFormat or Y or 4:4:4\n      maskImg = new ImageOverlayInternal(Mframe, maskVi.width, maskVi.height, viInternalOverlayWorkingFormat, mask->GetVideoInfo().IsYUVA() || mask->GetVideoInfo().IsPlanarRGBA(), greymask, env);\n\n      img->ReturnOriginal(true);\n      ClipFrames(img, maskImg, offset_x + con_x_offset, offset_y + con_y_offset);\n\n\n    }\n\n    OverlayFunction* func = SelectFunction();\n\n    // Process the image\n    func->setMode(of_mode);\n    func->setBitsPerPixel(bits_per_pixel);\n    func->setOpacity(opacity + op_offset, opacity_f + op_offset_f);\n    func->setColorSpaceInfo(viInternalWorkingFormat.IsRGB(), viInternalWorkingFormat.IsY());\n    func->setEnv(env);\n\n    if (!mask) {\n      func->DoBlendImage(img, overlayImg);\n    } else {\n      func->DoBlendImageMask(img, overlayImg, maskImg);\n    }\n\n    delete func;\n\n    // Reset overlay & image offsets\n    img->ReturnOriginal(true);\n    overlayImg->ReturnOriginal(true);\n    if (mask)\n        maskImg->ReturnOriginal(true);\n  }\n\n  // Cleanup\n  if (mask) {\n    delete maskImg;\n  }\n  delete overlayImg;\n  if (img) {\n    delete img;\n  }\n\n  // here img->frame is 444\n  // apply fast conversion\n  if(outputVi.Is420() && viInternalWorkingFormat.Is444())\n  {\n    PVideoFrame outputFrame = env->NewVideoFrameP(outputVi, &frame);\n    Convert444ToYV12(frame, outputFrame, pixelsize, bits_per_pixel, env);\n    return outputFrame;\n  } else if(outputVi.Is422() && viInternalWorkingFormat.Is444()) {\n    PVideoFrame outputFrame = env->NewVideoFrameP(outputVi, &frame);\n    Convert444ToYV16(frame, outputFrame, pixelsize, bits_per_pixel, env);\n    return outputFrame;\n  } \n  // all other cases return 4:4:4\n  // except when use444 is false\n  return frame;\n}\n\n\n/*************************\n *   Helper functions    *\n *************************/\n\nvoid Overlay::SetOfModeByName(const char* name, IScriptEnvironment* env) {\n\n  if (!lstrcmpi(name, \"Blend\")) {\n    of_mode = OF_Blend;\n  }\n  else if (!lstrcmpi(name, \"Add\")) {\n    of_mode = OF_Add;\n  }\n  else if (!lstrcmpi(name, \"Subtract\")) {\n    of_mode = OF_Subtract;\n  }\n  else if (!lstrcmpi(name, \"Multiply\")) {\n    of_mode = OF_Multiply;\n  }\n  else if (!lstrcmpi(name, \"Chroma\")) {\n    of_mode = OF_Chroma;\n  }\n  else if (!lstrcmpi(name, \"Luma\")) {\n    of_mode = OF_Luma;\n  }\n  else if (!lstrcmpi(name, \"Lighten\")) {\n    of_mode = OF_Lighten;\n  }\n  else if (!lstrcmpi(name, \"Darken\")) {\n    of_mode = OF_Darken;\n  }\n  else if (!lstrcmpi(name, \"SoftLight\")) {\n    of_mode = OF_SoftLight;\n  }\n  else if (!lstrcmpi(name, \"HardLight\")) {\n    of_mode = OF_HardLight;\n  }\n  else if (!lstrcmpi(name, \"Difference\")) {\n    of_mode = OF_Difference;\n  }\n  else if (!lstrcmpi(name, \"Exclusion\")) {\n    of_mode = OF_Exclusion;\n  }\n  else env->ThrowError(\"Overlay: Invalid 'Mode' specified.\");\n}\n\nOverlayFunction* Overlay::SelectFunction()\n{\n  switch (of_mode) {\n  case OF_Blend: return new OL_BlendImage();\n  case OF_Add: return new OL_AddImage();\n  case OF_Subtract: return new OL_AddImage(); // common with Add\n  case OF_Multiply: return new OL_MultiplyImage();\n  case OF_Chroma: return new OL_BlendImage(); // Common with BlendImage. plane range differs of_mode checked inside\n  case OF_Luma: return new OL_BlendImage(); // Common with BlendImage. plane range differs of_mode checked inside\n  case OF_Lighten: return new OL_DarkenImage(); // common with Darken\n  case OF_Darken: return new OL_DarkenImage();\n  case OF_SoftLight: return new OL_SoftLightImage();\n  case OF_HardLight: return new OL_SoftLightImage(); // Common with SoftLight\n  case OF_Difference: return new OL_DifferenceImage();\n  case OF_Exclusion: return new OL_ExclusionImage();\n  default: return nullptr; // cannot be\n  }\n}\n\nvoid Overlay::ClipFrames(ImageOverlayInternal* input, ImageOverlayInternal* overlay, int x, int y) {\n\n  input->ResetFake();\n  overlay->ResetFake();\n\n  input->ReturnOriginal(false);  // We now use cropped space\n  overlay->ReturnOriginal(false);\n\n  // Crop negative offset off overlay\n  if (x<0) {\n    overlay->SubFrame(-x,0,overlay->w()+x, overlay->h());\n    x=0;\n  }\n  if (y<0) {\n    overlay->SubFrame(0,-y, overlay->w(), overlay->h()+y);\n    y=0;\n  }\n  // Clip input-frame to topleft overlay:\n  input->SubFrame(x,y,input->w()-x, input->h()-y);\n\n  // input and overlay are now topleft aligned\n\n  // Clip overlay that is beyond the right side of the input\n\n  if (overlay->w() > input->w()) {\n    overlay->SubFrame(0,0,input->w(), overlay->h());\n  }\n\n  if (overlay->h() > input->h()) {\n    overlay->SubFrame(0,0,overlay->w(), input->h());\n  }\n\n  // Clip right/ bottom of input\n\n  if(input->w() > overlay->w()) {\n    input->SubFrame(0,0, overlay->w(), input->h());\n  }\n\n  if(input->h() > overlay->h()) {\n    input->SubFrame(0,0, input->w(), overlay->h());\n  }\n\n}\n\nvoid Overlay::FetchConditionals(IScriptEnvironment* env, int* op_offset, float* op_offset_f, int* con_x_offset, int* con_y_offset, bool ignore_conditional, const char *condVarSuffix) {\n  *op_offset = 0;\n  *op_offset_f = 0.0f;\n  *con_x_offset = 0;\n  *con_y_offset = 0;\n\n  if (!ignore_conditional) {\n    {\n      std::string s = std::string(\"OL_opacity_offset\") + condVarSuffix;\n      *op_offset = (int)(env->GetVarDouble(s.c_str(), 0.0) * 256);\n      *op_offset_f = (float)(env->GetVarDouble(s.c_str(), 0.0));\n    }\n    {\n      std::string s = std::string(\"OL_x_offset\") + condVarSuffix;\n      *con_x_offset = (int)(env->GetVarDouble(s.c_str(), 0.0));\n    }\n    {\n      std::string s = std::string(\"OL_y_offset\") + condVarSuffix;\n      *con_y_offset = (int)(env->GetVarDouble(s.c_str(), 0.0));\n    }\n  }\n}\n\n\nAVSValue __cdecl Overlay::Create(AVSValue args, void*, IScriptEnvironment* env) {\n  // provide planar-only main clip\n  PClip input = args[0].AsClip();\n  VideoInfo vi_orig = input->GetVideoInfo();\n  bool converted = false;\n\n  // input clip to always planar\n  if (vi_orig.IsRGB() && !vi_orig.IsPlanar()) {\n    // no packed RGB allowed from now on, autoconvert from packed\n    AVSValue new_args[1] = { input };\n    if(vi_orig.IsRGB24() || vi_orig.IsRGB48())\n      input = env->Invoke(\"ConvertToPlanarRGB\", AVSValue(new_args, 1)).AsClip();\n    else // RGB32, RGB64\n      input = env->Invoke(\"ConvertToPlanarRGBA\", AVSValue(new_args, 1)).AsClip();\n    converted = true;\n  }\n  else if (vi_orig.IsYUY2()) {\n    // convert YUY2 to 422, keep internals simple\n    AVSValue new_args[2] = { input, false };\n    input = env->Invoke(\"ConvertToYUV422\", AVSValue(new_args, 2)).AsClip();\n    converted = true;\n  }\n\n  // input now is always planar, overlay and mask clip converted later\n  Overlay* Result = new Overlay(input, args, env);\n\n  // where there was no output override but old formats were converted\n  // then we turn them back\n  if (Result->output_pixel_format_override == nullptr && converted) {\n    if (vi_orig.IsRGB() && !vi_orig.IsPlanar()) {\n      AVSValue new_args[1] = { Result };\n      if (vi_orig.IsRGB24())\n        return env->Invoke(\"ConvertToRGB24\", AVSValue(new_args, 1)).AsClip();\n      else if (vi_orig.IsRGB32())\n        return env->Invoke(\"ConvertToRGB32\", AVSValue(new_args, 1)).AsClip();\n      else if (vi_orig.IsRGB48())\n        return env->Invoke(\"ConvertToRGB48\", AVSValue(new_args, 1)).AsClip();\n      else // if (vi_orig.IsRGB64())\n        return env->Invoke(\"ConvertToRGB64\", AVSValue(new_args, 1)).AsClip();\n    }\n    if (vi_orig.IsYUY2()) {\n      // convert back to YUY2\n      AVSValue new_args[2] = { Result, false };\n      return env->Invoke(\"ConvertToYUY2\", AVSValue(new_args, 2)).AsClip();\n    }\n  }\n\n  if (Result->GetVideoInfo().pixel_type == Result->outputVi.pixel_type)\n     return Result;\n   // c[interlaced]b[matrix]s[ChromaInPlacement]s[chromaresample]s\n   // chromaresample = 'bicubic' default\n   // chromaresample = 'point' is faster\n   if(Result->outputVi.Is444()) {\n     // if workingFormat is not 444 but output was specified\n     AVSValue new_args[3] = { Result, false, Result->full_range ? \"PC.601\" : \"rec601\" };\n     return env->Invoke(\"ConvertToYUV444\", AVSValue(new_args, 3)).AsClip();\n   }\n   if(Result->outputVi.Is422()) {\n     AVSValue new_args[3] = { Result, false, Result->full_range ? \"PC.601\" : \"rec601\" };\n     return env->Invoke(\"ConvertToYUV422\", AVSValue(new_args, 3)).AsClip();\n   }\n   if(Result->outputVi.Is420()) {\n     AVSValue new_args[3] = { Result, false, Result->full_range ? \"PC.601\" : \"rec601\" };\n     return env->Invoke(\"ConvertToYUV420\", AVSValue(new_args, 3)).AsClip();\n   }\n   if (Result->outputVi.IsYV411()) {\n     AVSValue new_args[3] = { Result, false, Result->full_range ? \"PC.601\" : \"rec601\" };\n     return env->Invoke(\"ConvertToYUV411\", AVSValue(new_args, 3)).AsClip();\n   }\n   if(Result->outputVi.IsYUY2()) {\n     AVSValue new_args[3] = { Result, false, Result->full_range ? \"PC.601\" : \"rec601\" };\n     return env->Invoke(\"ConvertToYUY2\", AVSValue(new_args, 3)).AsClip();\n   }\n   if(Result->outputVi.IsY()) {\n     AVSValue new_args[2] = { Result, Result->full_range ? \"PC.601\" : \"rec601\" };\n     return env->Invoke(\"ConvertToY\", AVSValue(new_args, 2)).AsClip();\n   }\n   if(Result->outputVi.IsRGB()) {\n     // c[matrix]s[interlaced]b[ChromaInPlacement]s[chromaresample]s\n     AVSValue new_args[3] = { Result, Result->full_range ? \"PC.601\" : \"rec601\", false};\n     if(Result->outputVi.IsPlanarRGB()) {\n       return env->Invoke(\"ConvertToPlanarRGB\", AVSValue(new_args, 3)).AsClip();\n     }\n     if(Result->outputVi.IsPlanarRGBA()) {\n       return env->Invoke(\"ConvertToPlanarRGBA\", AVSValue(new_args, 3)).AsClip();\n     }\n     if(Result->outputVi.IsRGB24()) {\n       return env->Invoke(\"ConvertToRGB24\", AVSValue(new_args, 3)).AsClip();\n     }\n     if(Result->outputVi.IsRGB32()) {\n       return env->Invoke(\"ConvertToRGB32\", AVSValue(new_args, 3)).AsClip();\n     }\n     if(Result->outputVi.IsRGB48()) {\n       return env->Invoke(\"ConvertToRGB48\", AVSValue(new_args, 3)).AsClip();\n     }\n     if(Result->outputVi.IsRGB64()) {\n       return env->Invoke(\"ConvertToRGB64\", AVSValue(new_args, 3)).AsClip();\n     }\n   }\n   env->ThrowError(\"Overlay: Invalid output format.\");\n   return Result;\n}\n"
  },
  {
    "path": "avs_core/filters/overlay/overlay.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// Overlay (c) 2003, 2004 by Klaus Post\n\n#ifndef __Overlay_h\n#define __Overlay_h\n\n#include <avisynth.h>\n#include \"444convert.h\"\n#include \"overlayfunctions.h\"\n#include \"blend_common.h\"\n\n\nclass Overlay : public GenericVideoFilter\n/**\n  *\n**/\n{\npublic:\n  Overlay(PClip _child, AVSValue args, IScriptEnvironment *env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment *env) override;\n  ~Overlay();\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override\n  {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\nprivate:\n  void SetOfModeByName(const char* name, IScriptEnvironment* env);\n  OverlayFunction* SelectFunction();\n  static void ClipFrames(ImageOverlayInternal* input, ImageOverlayInternal* overlay, int x, int y);\n  static void FetchConditionals(IScriptEnvironment* env, int*, float *, int*, int*, bool, const char *);\n\n  VideoInfo overlayVi;\n  VideoInfo maskVi;\n  VideoInfo inputVi;\n  VideoInfo outputVi;\n  VideoInfo viInternalWorkingFormat;\n  VideoInfo viInternalOverlayWorkingFormat; // different size\n\n  PClip overlay;\n  PClip mask;\n  int opacity;\n  float opacity_f;\n  bool greymask;\n  bool ignore_conditional;\n  bool full_range;\n  int offset_x, offset_y;\n  bool use444; // conversionless support\n  const char* condVarSuffix;\n\n  const char* name; // Blend parameter\n\n  int pixelsize;\n  int bits_per_pixel;\n  int of_mode;\n\n  const char* output_pixel_format_override;\n\n  bool isInternalRGB; // must be planar rgb\n  bool isInternalGrey;\n  bool isInternal444;\n  bool isInternal422;\n  bool isInternal420;\n\n  PClip child444;\n\n};\n\n\n#endif //Overlay_h\n"
  },
  {
    "path": "avs_core/filters/overlay/overlayfunctions.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// Overlay (c) 2003, 2004 by Klaus Post\n\n#ifndef __Overlay_funcs_h\n#define __Overlay_funcs_h\n\n#include <avisynth.h>\n#include <avs/minmax.h>\n#include \"imghelpers.h\"\n#include \"blend_common.h\"\n\nenum {\n  OF_Blend = 0,\n  OF_Add,\n  OF_Subtract,\n  OF_Multiply,\n  OF_Chroma,\n  OF_Luma,\n  OF_Lighten,\n  OF_Darken,\n  OF_SoftLight,\n  OF_HardLight,\n  OF_Difference,\n  OF_Exclusion\n};\n\nclass OverlayFunction {\npublic:\n  OverlayFunction() {\n  }\n  virtual ~OverlayFunction() {};\n  void setOpacity(int _opacity, float _opacity_f) { opacity = clamp(_opacity, 0, 256); inv_opacity = 256 - opacity; opacity_f = _opacity_f; inv_opacity_f = 1.0f - _opacity_f; }\n  void setEnv(IScriptEnvironment *_env) { env = _env;}\n  void setBitsPerPixel(int _bits_per_pixel) { bits_per_pixel = _bits_per_pixel; }\n  void setMode(int _of_mode) { of_mode = _of_mode; }\n  void setColorSpaceInfo(bool _rgb, bool _greyscale) { rgb = _rgb, greyscale = _greyscale; }\n\n  virtual void DoBlendImage(ImageOverlayInternal* base, ImageOverlayInternal* overlay) = 0;\n  virtual void DoBlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask) = 0;\nprotected:\n  int opacity;\n  int inv_opacity;\n  float opacity_f;\n  float inv_opacity_f;\n  int bits_per_pixel;\n  int of_mode; // add/subtract, etc\n  bool rgb; // add/subtract... overshoot mode is different\n  bool greyscale; // having only one plane\n  IScriptEnvironment *env;\n};\n\nclass OL_BlendImage : public OverlayFunction {\n  void DoBlendImage(ImageOverlayInternal* base, ImageOverlayInternal* overlay);\n  void DoBlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask);\n  template<typename pixel_t>\n  void BlendImage(ImageOverlayInternal* base, ImageOverlayInternal* overlay);\n  template<typename pixel_t>\n  void BlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask);\nprivate:\n};\n\n// common add/subtract\nclass OL_AddImage : public OverlayFunction {\n  void DoBlendImage(ImageOverlayInternal* base, ImageOverlayInternal* overlay);\n  void DoBlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask);\n  template<typename pixel_t, bool maskMode, bool of_add>\n  void BlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask);\n  template<bool maskMode, bool of_add>\n  void BlendImageMask_float(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask);\n  template<typename pixel_t, bool maskMode, bool of_add>\n  void BlendImageMask_RGB(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask);\n  template<bool maskMode, bool of_add>\n  void BlendImageMask_RGB_float(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask);\n};\n\nclass OL_MultiplyImage : public OverlayFunction {\n  void DoBlendImage(ImageOverlayInternal* base, ImageOverlayInternal* overlay);\n  void DoBlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask);\n  template<typename pixel_t>\n  void BlendImage(ImageOverlayInternal* base, ImageOverlayInternal* overlay);\n  template<typename pixel_t>\n  void BlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask);\n};\n\n// common darken/lighten\nclass OL_DarkenImage : public OverlayFunction {\n  void DoBlendImage(ImageOverlayInternal* base, ImageOverlayInternal* overlay);\n  void DoBlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask);\n  //template<typename pixel_t>\n  //void BlendImage(Image444* base, Image444* overlay);\n  template<typename pixel_t, bool maskMode, bool of_darken>\n  void BlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask);\n};\n\nclass OL_SoftLightImage : public OverlayFunction {\n  void DoBlendImage(ImageOverlayInternal* base, ImageOverlayInternal* overlay);\n  void DoBlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask);\n  template<typename pixel_t>\n  void BlendImage(ImageOverlayInternal* base, ImageOverlayInternal* overlay);\n  template<typename pixel_t, bool maskMode, bool hardLight>\n  void BlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask);\n};\n\nclass OL_DifferenceImage : public OverlayFunction {\n  void DoBlendImage(ImageOverlayInternal* base, ImageOverlayInternal* overlay);\n  void DoBlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask);\n  //template<typename pixel_t>\n  //void BlendImage(Image444* base, Image444* overlay);\n  template<typename pixel_t, bool maskMode>\n  void BlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask);\n};\n\nclass OL_ExclusionImage : public OverlayFunction {\n  void DoBlendImage(ImageOverlayInternal* base, ImageOverlayInternal* overlay);\n  void DoBlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask);\n  // template<typename pixel_t>\n  // void BlendImage(Image444* base, Image444* overlay);\n  template<typename pixel_t, bool maskMode>\n  void BlendImageMask(ImageOverlayInternal* base, ImageOverlayInternal* overlay, ImageOverlayInternal* mask);\n};\n\n#endif  // Overlay_funcs_h\n"
  },
  {
    "path": "avs_core/filters/planeswap.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n// Avisynth filter:  Swap planes\n// by Klaus Post\n// adapted by Richard Berg (avisynth-dev@richardberg.net)\n// iSSE code by Ian Brabham\n\n#include <avs/config.h>\n#ifdef AVS_WINDOWS\n#include <avs/win.h>\n#else\n#include <avs/posix.h>\n#endif\n#include \"planeswap.h\"\n#ifdef INTEL_INTRINSICS\n#include \"intel/planeswap_sse.h\"\n#endif\n#include \"../core/internal.h\"\n#include <algorithm>\n#include <avs/alignment.h>\n#include \"../convert/convert_planar.h\"\n#include \"../convert/convert_rgb.h\"\n#include \"../convert/convert.h\"\n#include \"../convert/convert_helper.h\"\n#include \"stdint.h\"\n\n\n/********************************************************************\n***** Declare index of new filters for Avisynth's filter engine *****\n********************************************************************/\n\nextern const AVSFunction Swap_filters[] = {\n  {  \"SwapUV\", BUILTIN_FUNC_PREFIX, \"c\", SwapUV::CreateSwapUV },\n  {  \"UToY\",   BUILTIN_FUNC_PREFIX, \"c\", SwapUVToY::CreateUToY },\n  {  \"VToY\",   BUILTIN_FUNC_PREFIX, \"c\", SwapUVToY::CreateVToY },\n  {  \"UToY8\",  BUILTIN_FUNC_PREFIX, \"c\", SwapUVToY::CreateUToY8 },\n  {  \"VToY8\",  BUILTIN_FUNC_PREFIX, \"c\", SwapUVToY::CreateVToY8 },\n  {  \"ExtractY\",  BUILTIN_FUNC_PREFIX, \"c\", SwapUVToY::CreateYToY8 }, // differs, YUY2 checks inside\n  {  \"ExtractU\",  BUILTIN_FUNC_PREFIX, \"c\", SwapUVToY::CreateUToY8 }, // differs, YUY2 checks inside\n  {  \"ExtractV\",  BUILTIN_FUNC_PREFIX, \"c\", SwapUVToY::CreateVToY8 }, // differs, YUY2 checks inside\n  {  \"ExtractA\",  BUILTIN_FUNC_PREFIX, \"c\", SwapUVToY::CreateAnyToY8, (void *)SwapUVToY::AToY8 },\n  {  \"ExtractR\",  BUILTIN_FUNC_PREFIX, \"c\", SwapUVToY::CreateAnyToY8, (void *)SwapUVToY::RToY8 },\n  {  \"ExtractG\",  BUILTIN_FUNC_PREFIX, \"c\", SwapUVToY::CreateAnyToY8, (void *)SwapUVToY::GToY8 },\n  {  \"ExtractB\",  BUILTIN_FUNC_PREFIX, \"c\", SwapUVToY::CreateAnyToY8, (void *)SwapUVToY::BToY8 },\n  {  \"YToUV\",  BUILTIN_FUNC_PREFIX, \"cc\", SwapYToUV::CreateYToUV },\n  {  \"YToUV\",  BUILTIN_FUNC_PREFIX, \"ccc\", SwapYToUV::CreateYToYUV },\n  {  \"YToUV\",  BUILTIN_FUNC_PREFIX, \"cccc\", SwapYToUV::CreateYToYUVA }, // avs+ alpha planes\n  {  \"PlaneToY\",  BUILTIN_FUNC_PREFIX, \"c[plane]s\", SwapUVToY::CreatePlaneToY8 },\n  {  \"CombinePlanes\",  BUILTIN_FUNC_PREFIX, \"c[planes]s[source_planes]s[pixel_type]s[sample_clip]c\", CombinePlanes::CreateCombinePlanes, (void *)1},\n  {  \"CombinePlanes\",  BUILTIN_FUNC_PREFIX, \"cc[planes]s[source_planes]s[pixel_type]s[sample_clip]c\", CombinePlanes::CreateCombinePlanes, (void *)2},\n  {  \"CombinePlanes\",  BUILTIN_FUNC_PREFIX, \"ccc[planes]s[source_planes]s[pixel_type]s[sample_clip]c\", CombinePlanes::CreateCombinePlanes, (void *)3},\n  {  \"CombinePlanes\",  BUILTIN_FUNC_PREFIX, \"cccc[planes]s[source_planes]s[pixel_type]s[sample_clip]c\", CombinePlanes::CreateCombinePlanes, (void *)4},\n  { 0 }\n};\n\n\n/**************************************\n *  Swap - swaps UV on planar maps\n **************************************/\n\nstatic void yuy2_swap_c(const BYTE* srcp, BYTE* dstp, int src_pitch, int dst_pitch, int width, int height)\n{\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < width; x += 4) {\n      dstp[x + 0] = srcp[x + 0];\n      dstp[x + 3] = srcp[x + 1];\n      dstp[x + 2] = srcp[x + 2];\n      dstp[x + 1] = srcp[x + 3];\n    }\n    srcp += src_pitch;\n    dstp += dst_pitch;\n  }\n}\n\nAVSValue __cdecl SwapUV::CreateSwapUV(AVSValue args, void* , IScriptEnvironment* env)\n{\n  PClip p = args[0].AsClip();\n  if (p->GetVideoInfo().NumComponents() == 1)\n    return p;\n  return new SwapUV(p, env);\n}\n\n\nSwapUV::SwapUV(PClip _child, IScriptEnvironment* env) : GenericVideoFilter(_child)\n{\n  if (!vi.IsYUV() && !vi.IsYUVA())\n    env->ThrowError(\"SwapUV: YUV or YUVA data only!\");\n}\n\nPVideoFrame __stdcall SwapUV::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame src = child->GetFrame(n, env);\n\n  if (vi.IsPlanar()) {\n    // Abuse subframe to flip the UV plane pointers -- extremely fast but a bit naughty!\n    // !! if offsets would be size_t, be cautious when you subtract two unsigned size_t variables\n    const int uvoffset = src->GetOffset(PLANAR_V) - src->GetOffset(PLANAR_U); // very naughty - don't do this at home!!\n    if (vi.NumComponents() == 4) {\n      return env->SubframePlanarA(src, 0, src->GetPitch(PLANAR_Y), src->GetRowSize(PLANAR_Y), src->GetHeight(PLANAR_Y),\n        uvoffset, -uvoffset, src->GetPitch(PLANAR_V), 0);\n    }\n    else {\n      return env->SubframePlanar(src, 0, src->GetPitch(PLANAR_Y), src->GetRowSize(PLANAR_Y), src->GetHeight(PLANAR_Y),\n        uvoffset, -uvoffset, src->GetPitch(PLANAR_V));\n    }\n  }\n\n  // YUY2\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n  const BYTE* srcp = src->GetReadPtr();\n  BYTE* dstp = dst->GetWritePtr();\n  int src_pitch = src->GetPitch();\n  int dst_pitch = dst->GetPitch();\n  int rowsize = src->GetRowSize();\n#ifdef INTEL_INTRINSICS\n  if ((env->GetCPUFlags() & CPUF_SSSE3))\n    yuy2_swap_ssse3(srcp, dstp, src_pitch, dst_pitch, rowsize, vi.height);\n  else if ((env->GetCPUFlags() & CPUF_SSE2))\n    yuy2_swap_sse2(srcp, dstp, src_pitch, dst_pitch, rowsize, vi.height);\n#ifdef X86_32\n  else if (env->GetCPUFlags() & CPUF_INTEGER_SSE) // need pshufw\n    yuy2_swap_isse(srcp, dstp, src_pitch, dst_pitch, rowsize, vi.height);\n#endif\n  else\n#endif\n{\n  yuy2_swap_c(srcp, dstp, src_pitch, dst_pitch, rowsize, vi.height);\n}\n  return dst;\n}\n\n\nAVSValue __cdecl SwapUVToY::CreateUToY(AVSValue args, void* , IScriptEnvironment* env)\n{\n  return new SwapUVToY(args[0].AsClip(), UToY, env);\n}\n\nAVSValue __cdecl SwapUVToY::CreateUToY8(AVSValue args, void* , IScriptEnvironment* env)\n{\n  PClip clip = args[0].AsClip();\n  return new SwapUVToY(clip, (clip->GetVideoInfo().IsYUY2()) ? YUY2UToY8 : UToY8, env);\n}\n\nAVSValue __cdecl SwapUVToY::CreateYToY8(AVSValue args, void* , IScriptEnvironment* env)\n{\n  PClip clip = args[0].AsClip();\n  if(clip->GetVideoInfo().IsYUY2())\n    return new ConvertYUY2ToYV16_or_Y(clip, true /*to_y*/, env);\n  else\n    return new SwapUVToY(clip, YToY8, env);\n}\n\nAVSValue __cdecl SwapUVToY::CreateVToY(AVSValue args, void* , IScriptEnvironment* env)\n{\n  return new SwapUVToY(args[0].AsClip(), VToY, env);\n}\n\nAVSValue __cdecl SwapUVToY::CreateVToY8(AVSValue args, void* , IScriptEnvironment* env)\n{\n  PClip clip = args[0].AsClip();\n  return new SwapUVToY(clip, (clip->GetVideoInfo().IsYUY2()) ? YUY2VToY8 : VToY8, env);\n}\n\nAVSValue __cdecl SwapUVToY::CreateAnyToY8(AVSValue args, void* user_data, IScriptEnvironment* env)\n{\n  int mode = (int)(intptr_t)(user_data);\n  PClip clip = args[0].AsClip();\n  const VideoInfo& vi_input = clip->GetVideoInfo();\n\n  // 161205: Packed RGB PlaneToY(\"R\"),g,b,a or ExtractR,G,B,A\n  // A generic way for using these PlaneToY() or Extract... functions for packed RGB types\n  // We convert them to planar RGB (R,G,B plane reqest) or planar RGBA (only if A plane requested)\n  if (vi_input.IsRGB() && !vi_input.IsPlanarRGB() && !vi_input.IsPlanarRGBA()) {\n    if (mode == AToY8 || mode == RToY8 || mode == GToY8 || mode == BToY8) {\n      clip = new PackedRGBtoPlanarRGB(clip, vi_input.IsRGB32() || vi_input.IsRGB64(), mode == AToY8);\n    }\n  }\n\n  if(clip->GetVideoInfo().IsYUY2() && mode == YToY8)\n    return new ConvertYUY2ToYV16_or_Y(clip, true /*to_y*/, env);\n\n  if (clip->GetVideoInfo().IsY() && mode == YToY8)\n    return clip;\n\n  return new SwapUVToY(clip, mode, env);\n}\n\nAVSValue __cdecl SwapUVToY::CreatePlaneToY8(AVSValue args, void* , IScriptEnvironment* env) {\n    PClip clip = args[0].AsClip();\n\n    const VideoInfo& vi_input = clip->GetVideoInfo();\n\n    const char* plane = args[1].AsString(\"\");\n    int mode = 0;\n    // enum {UToY=1, VToY, UToY8, VToY8, YUY2UToY8, YUY2VToY8, AToY8, RToY8, GToY8, BToY8, YToY8};\n    if (!lstrcmpi(plane, \"Y\")) mode = YToY8;\n    else if (!lstrcmpi(plane, \"U\")) mode = vi_input.IsYUY2() ? YUY2UToY8 : UToY8;\n    else if (!lstrcmpi(plane, \"V\")) mode = vi_input.IsYUY2() ? YUY2VToY8 : VToY8;\n    else if (!lstrcmpi(plane, \"A\")) mode = AToY8;\n    else if (!lstrcmpi(plane, \"R\")) mode = RToY8;\n    else if (!lstrcmpi(plane, \"G\")) mode = GToY8;\n    else if (!lstrcmpi(plane, \"B\")) mode = BToY8;\n    else env->ThrowError(\"PlaneToY: Invalid plane!\");\n\n    return CreateAnyToY8(args, (void* )(intptr_t)mode, env);\n}\n\n\nSwapUVToY::SwapUVToY(PClip _child, int _mode, IScriptEnvironment* env)\n  : GenericVideoFilter(_child), mode(_mode)\n{\n  bool YUVmode = mode == YToY8 || mode == UToY8 || mode == VToY8 || mode == UToY || mode == VToY || mode == YUY2UToY8 || mode == YUY2VToY8;\n  bool RGBmode = mode == RToY8 || mode == GToY8 || mode == BToY8;\n  bool Alphamode = mode == AToY8;\n\n  if(!vi.IsYUVA() && !vi.IsPlanarRGBA() && Alphamode)\n      env->ThrowError(\"PlaneToY: Clip has no Alpha channel!\");\n\n  if (!vi.IsYUV() && !vi.IsYUVA() && YUVmode )\n    env->ThrowError(\"PlaneToY: clip is not YUV!\");\n\n  if (!vi.IsPlanarRGB() && !vi.IsPlanarRGBA() && RGBmode )\n      env->ThrowError(\"PlaneToY: clip is not planar RGB!\");\n\n  if (vi.NumComponents() == 1 && mode != YToY8)\n    env->ThrowError(\"PlaneToY: channel cannot be extracted from a greyscale clip!\");\n\n  if(YUVmode && (mode!=YToY8)){\n    vi.height >>= vi.GetPlaneHeightSubsampling(PLANAR_U);\n    vi.width  >>= vi.GetPlaneWidthSubsampling(PLANAR_U);\n  }\n\n  if (mode == YToY8 || mode == UToY8 || mode == VToY8 || mode == YUY2UToY8 || mode == YUY2VToY8 || RGBmode || Alphamode)\n  {\n    switch (vi.BitsPerComponent()) // although name is Y8, it means that greyscale stays in the same bitdepth\n    {\n    case 8: vi.pixel_type = VideoInfo::CS_Y8; break;\n    case 10: vi.pixel_type = VideoInfo::CS_Y10; break;\n    case 12: vi.pixel_type = VideoInfo::CS_Y12; break;\n    case 14: vi.pixel_type = VideoInfo::CS_Y14; break;\n    case 16: vi.pixel_type = VideoInfo::CS_Y16; break;\n    case 32: vi.pixel_type = VideoInfo::CS_Y32; break;\n    }\n  }\n}\n\nPVideoFrame __stdcall SwapUVToY::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame src = child->GetFrame(n, env);\n\n  bool NonYUY2toY8 = true;\n  int target_plane, source_plane;\n  switch (mode) {\n  case YToY8: source_plane = PLANAR_Y; target_plane = PLANAR_Y; break;\n  case UToY8: source_plane = PLANAR_U; target_plane = PLANAR_Y; break;\n  case VToY8: source_plane = PLANAR_V; target_plane = PLANAR_Y; break;\n  case RToY8: source_plane = PLANAR_R; target_plane = PLANAR_G; break; // Planar RGB: GBR!\n  case GToY8: source_plane = PLANAR_G; target_plane = PLANAR_G; break;\n  case BToY8: source_plane = PLANAR_B; target_plane = PLANAR_G; break;\n  case AToY8: source_plane = PLANAR_A; target_plane = vi.IsYUVA() ? PLANAR_Y : PLANAR_G; break; // Planar RGB: GBR!\n  default: NonYUY2toY8 = false;\n  }\n  if (NonYUY2toY8) {\n    // !! if offsets would be size_t, be cautious when you subtract two unsigned size_t variables\n    const int offset = src->GetOffset(source_plane) - src->GetOffset(target_plane); // very naughty - don't do this at home!!\n                                                                                    // Abuse Subframe to snatch the U/V/R/G/B/A plane\n    PVideoFrame sub = env->Subframe(src, offset, src->GetPitch(source_plane), src->GetRowSize(source_plane), src->GetHeight(source_plane));\n    // We have a single plane. It's safe to mod props after a subframe.\n    // Remove props that are irrelevant to a single plane.\n    // _ChromaLocation, (_Primaries, _Transfer)\n    auto props = env->getFramePropsRW(sub);\n    env->propDeleteKey(props, \"_ChromaLocation\");\n    // keep _Matrix (?) fixme: really?\n    if (mode == AToY8) // alpha is always full range, otherwise keep source\n      env->propSetInt(props, \"_ColorRange\", ColorRange_Compat_e::AVS_COLORRANGE_FULL, AVSPropAppendMode::PROPAPPENDMODE_REPLACE);\n    // else we keep _ColorRange value (if any)\n    return sub;\n  }\n\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n  if (mode == YUY2UToY8 || mode == YUY2VToY8 || vi.IsYUY2()) {\n    const BYTE* srcp = src->GetReadPtr();\n    BYTE* dstp = dst->GetWritePtr();\n    int src_pitch = src->GetPitch();\n    int dst_pitch = dst->GetPitch();\n    int pos = (mode == YUY2UToY8 || mode == UToY) ? 1 : 3; // YUYV U=offset#1 V=offset#3\n\n    if (vi.IsYUY2()) {  // YUY2 to YUY2\n      int rowsize = dst->GetRowSize();\n#ifdef INTEL_INTRINSICS\n      if (env->GetCPUFlags() & CPUF_SSE2) {\n        yuy2_uvtoy_sse2(srcp, dstp, src_pitch, dst_pitch, rowsize, vi.height, pos);\n        return dst;\n      }\n#endif\n\n      srcp += pos;\n      for (int y = 0; y < vi.height; ++y) {\n        for (int x = 0; x < rowsize; x += 2) {\n          dstp[x + 0] = srcp[2 * x];\n          dstp[x + 1] = 0x80;\n        }\n        srcp += src_pitch;\n        dstp += dst_pitch;\n      }\n      return dst;\n    }\n\n    // YUY2 to Y8\n\n    auto props = env->getFramePropsRW(dst);\n    env->propDeleteKey(props, \"_ChromaLocation\");\n\n#ifdef INTEL_INTRINSICS\n    if (env->GetCPUFlags() & CPUF_SSE2) {\n      yuy2_uvtoy8_sse2(srcp, dstp, src_pitch, dst_pitch, vi.width, vi.height, pos);\n      return dst;\n    }\n#endif\n    srcp += pos;\n    for (int y = 0; y < vi.height; ++y) {\n      for (int x = 0; x < vi.width; ++x) {\n        dstp[x] = srcp[x * 4];\n      }\n      srcp += src_pitch;\n      dstp += dst_pitch;\n    }\n    return dst;\n  }\n\n  // Planar to Planar. Only two modes possible UToY and VToY\n  // Copy U or V to Y and set the other chroma planes to grey\n  const int plane = mode == UToY ? PLANAR_U : PLANAR_V;\n  env->BitBlt(dst->GetWritePtr(PLANAR_Y), dst->GetPitch(PLANAR_Y), src->GetReadPtr(plane),\n    src->GetPitch(plane), src->GetRowSize(plane), src->GetHeight(plane));\n\n  // Clear chroma\n  int pitch = dst->GetPitch(PLANAR_U);\n  int height = dst->GetHeight(PLANAR_U);\n  int rowsize = dst->GetRowSize(PLANAR_U);\n  BYTE* dstp_u = dst->GetWritePtr(PLANAR_U);\n  BYTE* dstp_v = dst->GetWritePtr(PLANAR_V);\n\n  if (vi.ComponentSize() == 1) {  // 8bit\n    fill_chroma<BYTE>(dstp_u, dstp_v, height, rowsize, pitch, 0x80);\n  }\n  else if (vi.ComponentSize() == 2) {  // 16bit\n    uint16_t grey_val = 1 << (vi.BitsPerComponent() - 1); // 0x8000 for 16 bit\n    fill_chroma<uint16_t>(dstp_u, dstp_v, height, rowsize, pitch, grey_val);\n  }\n  else {  // 32bit(float)\n    float grey_val = uv8tof(128);\n    fill_chroma<float>(dstp_u, dstp_v, height, rowsize, pitch, grey_val);\n  }\n\n  return dst;\n}\n\n\nAVSValue __cdecl SwapYToUV::CreateYToUV(AVSValue args, void* , IScriptEnvironment* env)\n{\n  return new SwapYToUV(args[0].AsClip(), args[1].AsClip(), NULL , NULL, env);\n}\n\nAVSValue __cdecl SwapYToUV::CreateYToYUV(AVSValue args, void* , IScriptEnvironment* env)\n{\n  return new SwapYToUV(args[0].AsClip(), args[1].AsClip(), args[2].AsClip(), NULL, env);\n}\n\nAVSValue __cdecl SwapYToUV::CreateYToYUVA(AVSValue args, void* , IScriptEnvironment* env)\n{\n  return new SwapYToUV(args[0].AsClip(), args[1].AsClip(), args[2].AsClip(), args[3].AsClip(), env);\n}\n\nSwapYToUV::SwapYToUV(PClip _child, PClip _clip, PClip _clipY, PClip _clipA, IScriptEnvironment* env)\n  : GenericVideoFilter(_child), clip(_clip), clipY(_clipY), clipA(_clipA)\n{\n  if(!(vi.IsYUVA() || vi.IsY()) && clipA)\n    env->ThrowError(\"YToUV: Only Y or YUVA data accepted when alpha clip is provided\"); // Y, YUV and YUY2\n  if (!vi.IsYUV() && !vi.IsYUVA())\n  {\n    env->ThrowError(\"YToUV: Only YUV or YUVA data accepted\"); // Y, YUV and YUY2\n  }\n\n  const VideoInfo& vi2 = clip->GetVideoInfo();\n  if (vi.height != vi2.height)\n    env->ThrowError(\"YToUV: Clips do not have the same height (U & V mismatch) !\");\n  if (vi.width != vi2.width)\n    env->ThrowError(\"YToUV: Clips do not have the same width (U & V mismatch) !\");\n  if (vi.IsYUY2() != vi2.IsYUY2())\n    env->ThrowError(\"YToUV: YUY2 Clips must have same colorspace (U & V mismatch) !\");\n\n  // no third parameter: no Y clip\n  if (!clipY) {\n    if (vi.IsYUY2())\n      vi.width *= 2;\n    else if (vi.IsY()) {\n      switch(vi.BitsPerComponent()) {\n      case 8: vi.pixel_type = VideoInfo::CS_YV24; break;\n      case 10: vi.pixel_type = VideoInfo::CS_YUV444P10; break;\n      case 12: vi.pixel_type = VideoInfo::CS_YUV444P12; break;\n      case 14: vi.pixel_type = VideoInfo::CS_YUV444P14; break;\n      case 16: vi.pixel_type = VideoInfo::CS_YUV444P16; break;\n      case 32: vi.pixel_type = VideoInfo::CS_YUV444PS; break;\n      }\n    }\n    else {\n      vi.height <<= vi.GetPlaneHeightSubsampling(PLANAR_U);\n      vi.width <<= vi.GetPlaneWidthSubsampling(PLANAR_U);\n    }\n    return;\n  }\n\n  // Y clip parameter exists, Y channel will be copied from that\n  const VideoInfo& vi3 = clipY->GetVideoInfo();\n  if (vi.IsYUY2() != vi3.IsYUY2())\n    env->ThrowError(\"YToUV: YUY2 Clips must have same colorspace (UV & Y mismatch) !\");\n\n  if (vi.IsYUY2()) {\n    if (vi3.height != vi.height)\n      env->ThrowError(\"YToUV: Y clip does not have the same height of the UV clips! (YUY2 mode)\");\n    vi.width *= 2;\n    if (vi3.width != vi.width)\n      env->ThrowError(\"YToUV: Y clip does not have the double width of the UV clips!\");\n    return;\n  }\n\n  if (clipA) {\n    if(vi.IsYUY2())\n      env->ThrowError(\"YToUV: YUY2 not supported with alpha clip\");\n    const VideoInfo& vi4 = clipA->GetVideoInfo();\n    if (vi4.width != vi3.width || vi4.height != vi3.height) // Y width == A width\n      env->ThrowError(\"YToUV: different Y and A clip dimensions\");\n    if(vi4.BitsPerComponent() != vi3.BitsPerComponent())\n      env->ThrowError(\"YToUV: different Y and A clip bit depth\");\n  }\n\n  // Autogenerate destination colorformat\n  switch (vi.BitsPerComponent())\n  { // CS_Sub_Width_2 and CS_Sub_Height_2 are 0, vi bitfield can or'd if change needed\n  case  8: vi.pixel_type = clipA ? VideoInfo::CS_YUVA420 : vi.pixel_type = VideoInfo::CS_YV12; break;\n  case 10: vi.pixel_type = clipA ? VideoInfo::CS_YUVA420P10 : vi.pixel_type = VideoInfo::CS_YUV420P10; break;\n  case 12: vi.pixel_type = clipA ? VideoInfo::CS_YUVA420P12 : vi.pixel_type = VideoInfo::CS_YUV420P12; break;\n  case 14: vi.pixel_type = clipA ? VideoInfo::CS_YUVA420P14 : VideoInfo::CS_YUV420P14; break;\n  case 16: vi.pixel_type = clipA ? VideoInfo::CS_YUVA420P16 : VideoInfo::CS_YUV420P16; break;\n  case 32: vi.pixel_type = clipA ? VideoInfo::CS_YUVA420PS : VideoInfo::CS_YUV420PS; break;\n  }\n\n  if (vi3.width == vi.width) // Y width == U width -> subsampling 1:1\n    vi.pixel_type |= VideoInfo::CS_Sub_Width_1;\n  else if (vi3.width == vi.width * 2) // Y width == U width*2 -> horiz. subsampling 2\n    vi.width *= 2; // YV12 subsampling CS_Sub_Width_2 is o.k.\n  else if (vi3.width == vi.width * 4) { // Y width == U width*4 -> horiz. subsampling 4\n    vi.pixel_type |= VideoInfo::CS_Sub_Width_4;\n    vi.width *= 4; // final clip width is 3x of the U channel width\n  }\n  else\n    env->ThrowError(\"YToUV: Video width ratio does not match any internal colorspace.\");\n\n  if (vi3.height == vi.height)\n    vi.pixel_type |= VideoInfo::CS_Sub_Height_1;\n  else if (vi3.height == vi.height * 2)\n    vi.height *= 2;\n  else if (vi3.height == vi.height * 4) {\n    vi.pixel_type |= VideoInfo::CS_Sub_Height_4;\n    vi.height *= 4;\n  }\n  else\n    env->ThrowError(\"YToUV: Video height ratio does not match any internal colorspace.\");\n}\n\ntemplate <bool has_clipY>\nstatic void yuy2_ytouv_c(const BYTE* src_y, const BYTE* src_u, const BYTE* src_v, BYTE* dstp, int pitch_y, int pitch_u, int pitch_v, int dst_pitch, int dst_rowsize, int height)\n{\n  for (int y = 0; y < height; ++y) {\n    for (int x = 0; x < dst_rowsize; x += 4) {\n      dstp[x + 0] = has_clipY ? src_y[x] : 0x7e;\n      dstp[x + 1] = src_u[x / 2];\n      dstp[x + 2] = has_clipY ? src_y[x + 2] : 0x7e;\n      dstp[x + 3] = src_v[x / 2];\n    }\n    src_y += pitch_y;\n    src_u += pitch_u;\n    src_v += pitch_v;\n    dstp += dst_pitch;\n  }\n}\n\nPVideoFrame __stdcall SwapYToUV::GetFrame(int n, IScriptEnvironment* env) {\n  PVideoFrame src = child->GetFrame(n, env);\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n\n  if (vi.IsYUY2()) {\n    const BYTE* srcp_u = src->GetReadPtr();\n    const int pitch_u = src->GetPitch();\n\n    PVideoFrame srcv = clip->GetFrame(n, env);\n    const BYTE* srcp_v = srcv->GetReadPtr();\n    const int pitch_v = srcv->GetPitch();\n\n    BYTE* dstp = dst->GetWritePtr();\n    const int rowsize = dst->GetRowSize();\n    const int dst_pitch = dst->GetPitch();\n\n    if (clipY) {\n      PVideoFrame srcy = clipY->GetFrame(n, env);\n      const BYTE* srcp_y = srcy->GetReadPtr();\n      const int pitch_y = srcy->GetPitch();\n#ifdef INTEL_INTRINSICS\n      if (env->GetCPUFlags() & CPUF_SSE2)\n        yuy2_ytouv_sse2<true>(srcp_y, srcp_u, srcp_v, dstp, pitch_y, pitch_u, pitch_v, dst_pitch, rowsize, vi.height);\n      else\n#endif\n        yuy2_ytouv_c<true>(srcp_y, srcp_u, srcp_v, dstp, pitch_y, pitch_u, pitch_v, dst_pitch, rowsize, vi.height);\n    }\n    else\n      yuy2_ytouv_c<false>(nullptr, srcp_u, srcp_v, dstp, 0, pitch_u, pitch_v, dst_pitch, rowsize, vi.height);\n\n    return dst;\n  }\n\n  // Planar:\n  env->BitBlt(dst->GetWritePtr(PLANAR_U), dst->GetPitch(PLANAR_U),\n    src->GetReadPtr(PLANAR_Y), src->GetPitch(PLANAR_Y), src->GetRowSize(PLANAR_Y), src->GetHeight(PLANAR_Y));\n\n  src = clip->GetFrame(n, env);\n  env->BitBlt(dst->GetWritePtr(PLANAR_V), dst->GetPitch(PLANAR_V),\n    src->GetReadPtr(PLANAR_Y), src->GetPitch(PLANAR_Y), src->GetRowSize(PLANAR_Y), src->GetHeight(PLANAR_Y));\n\n  if (clipA) {\n    int source_plane = (clipA->GetVideoInfo().IsPlanarRGBA() ||\n      clipA->GetVideoInfo().IsYUVA()) ? PLANAR_A : PLANAR_Y;\n    src = clipA->GetFrame(n, env);\n    env->BitBlt(dst->GetWritePtr(PLANAR_A), dst->GetPitch(PLANAR_A),\n      src->GetReadPtr(source_plane), src->GetPitch(source_plane), src->GetRowSize(source_plane), src->GetHeight(source_plane));\n  }\n\n  if (clipY) {\n    src = clipY->GetFrame(n, env);\n    env->BitBlt(dst->GetWritePtr(PLANAR_Y), dst->GetPitch(PLANAR_Y),\n      src->GetReadPtr(PLANAR_Y), src->GetPitch(PLANAR_Y), src->GetRowSize(PLANAR_Y), src->GetHeight(PLANAR_Y));\n    return dst;\n  }\n\n  // if no Y script was given, fill Y plane with neutral value\n  // Luma = 126 (0x7e)\n  BYTE* dstp = dst->GetWritePtr(PLANAR_Y);\n  int rowsize = dst->GetRowSize(PLANAR_Y);\n  int pitch = dst->GetPitch(PLANAR_Y);\n\n  if (vi.ComponentSize() == 1)  // 8bit\n    fill_plane<BYTE>(dstp, vi.height, rowsize, pitch, 0x7e);\n  else if (vi.ComponentSize() == 2) { // 16bit\n    uint16_t luma_val = 0x7e << (vi.BitsPerComponent() - 8);\n    fill_plane<uint16_t>(dstp, vi.height, rowsize, pitch, luma_val);\n  }\n  else { // 32bit(float)\n    fill_plane<float>(dstp, vi.height, rowsize, pitch, 126.0f / 256);\n  }\n\n  return dst;\n}\n\n// AVS+: Combine planes free-style for all planar formats\nAVSValue __cdecl CombinePlanes::CreateCombinePlanes(AVSValue args, void* user_data, IScriptEnvironment* env)\n{\n  int mode = (int)(intptr_t)(user_data);\n  int target_planes_param = 0 + mode;\n  int source_planes_param = 1 + mode;\n  int pixel_type_param = 2 + mode;\n  int sample_clip_param = 3 + mode;\n\n  bool hasSampleClip = args[sample_clip_param].Defined();\n\n  return new CombinePlanes(args[0].AsClip(),\n    mode >= 2 ? args[1].AsClip() : nullptr,\n    mode >= 3 ? args[2].AsClip() : nullptr,\n    mode >= 4 ? args[3].AsClip() : nullptr,\n    hasSampleClip ? args[sample_clip_param].AsClip() : nullptr,\n    args[target_planes_param].AsString(\"\"),\n    args[source_planes_param].AsString(\"\"),\n    args[pixel_type_param].AsString(\"\"),\n    env);\n}\n\nCombinePlanes::CombinePlanes(PClip _child, PClip _clip2, PClip _clip3, PClip _clip4, PClip _sample,\n  const char *_target_planes_str, const char *_source_planes_str, const char *_pixel_type, IScriptEnvironment* env)\n  : GenericVideoFilter(_child)\n{\n  clips[0] = _child;\n  clips[1] = _clip2;\n  clips[2] = _clip3;\n  clips[3] = _clip4;\n  // planes(_planes), pixel_type(pixel_type)\n  // getting target video format\n  VideoInfo vi_default;\n  memset(&vi_default, 0, sizeof(VideoInfo));\n\n  bool videoFormatOverridden = false;\n\n  if (_sample) {\n    vi_default = _sample->GetVideoInfo();\n    videoFormatOverridden = true;\n  }\n  else { // no sample video: format from first clip\n    vi_default = child->GetVideoInfo();\n  }\n  // 1.) sample clip 2.) first clip 3.) pixel_type override\n  // 4.) when input clips are greyscale, automatically use YUV(A)/RGB(A) depending on \"planes\" string\n  if (*_pixel_type) {\n    int i_pixel_type = GetPixelTypeFromName(_pixel_type);\n    if (i_pixel_type == VideoInfo::CS_UNKNOWN)\n      env->ThrowError(\"CombinePlanes: unknown pixel_type %s\", _pixel_type);\n    vi_default.pixel_type = i_pixel_type;\n    videoFormatOverridden = true;\n  }\n\n  if (!vi_default.IsPlanar())\n    env->ThrowError(\"CombinePlanes: output clip video format is not planar!\");\n\n  // autoconvert packed RGB or YUY2 inputs, in order to able to extract planes\n  for (int i = 0; i < 4; i++) {\n    if (!clips[i]) continue;\n    const VideoInfo &vi_test = clips[i]->GetVideoInfo();\n    if (vi_test.IsRGB() && !vi_test.IsPlanar()) {\n      bool hasAlpha = vi_test.NumComponents() == 4;\n      clips[i] = new PackedRGBtoPlanarRGB(clips[i], hasAlpha, hasAlpha);\n    }\n    else if (vi_test.IsYUY2()) {\n      AVSValue emptyValue;\n      clips[i] = new ConvertYUY2ToYV16_or_Y(clips[i], false /*to_y*/, env);\n    }\n  }\n\n  int source_plane_count = (int)strlen(_source_planes_str); // no check here, can be 0\n  int target_plane_count = (int)strlen(_target_planes_str);\n  if (target_plane_count == 0)\n    env->ThrowError(\"CombinePlanes: no target planes given!\");\n  int clip_count = clips[3] ? 4 : clips[2] ? 3 : clips[1] ? 2 : 1;\n  if (target_plane_count < clip_count)\n    env->ThrowError(\"CombinePlanes: more clips specified than target planes\");\n\n  // If no video format was forced and no input planes were given\n  // and all the source clips are Y, then\n  // we give it a try of easy greyscale->RGB(A) or YUV(A) conversion\n  // depending on the _target_planes_str\n  bool allIsGrey = true;\n  for (int i = 0; i < clip_count; i++) {\n    if (!clips[i]->GetVideoInfo().IsY()) {\n      allIsGrey = false;\n      break;\n    }\n  }\n\n  if (!videoFormatOverridden && source_plane_count == 0) {\n    if (allIsGrey) {\n      // special case. Figure out RGB(A) or YUV(A) or Y\n      bool allIsYUV = true;\n      bool allIsRGB = true;\n      for (int i = 0; i < target_plane_count; i++) {\n        char ch = toupper(_target_planes_str[i]);\n        if (ch == 'R' || ch == 'G' || ch == 'B') allIsYUV = false;\n        if (ch == 'Y' || ch == 'U' || ch == 'V') allIsRGB = false;\n      }\n      if (allIsYUV || allIsRGB) {\n        int new_pixel_type;\n        if (allIsRGB)\n          new_pixel_type = target_plane_count == 4 ? VideoInfo::CS_GENERIC_RGBAP : VideoInfo::CS_GENERIC_RGBP;\n        else // if (allIsYUV)\n          new_pixel_type = target_plane_count == 4 ? VideoInfo::CS_GENERIC_YUVA444 : VideoInfo::CS_GENERIC_YUV444;\n        int bits_mask = clips[0]->GetVideoInfo().pixel_type & VideoInfo::CS_Sample_Bits_Mask;\n        new_pixel_type |= bits_mask; // copy bit-depth from the first clip\n        vi_default.pixel_type = new_pixel_type;\n      }\n    }\n  }\n\n  vi = vi_default;\n\n  if(!vi_default.IsPlanar())\n    env->ThrowError(\"CombinePlanes: target format must be planar!\");\n\n  if(target_plane_count > vi_default.NumComponents())\n    env->ThrowError(\"CombinePlanes: too many target planes (%d)! Target video plane count is %d!\", target_plane_count, vi_default.NumComponents());\n\n  if(source_plane_count != 0 && source_plane_count != target_plane_count)\n    env->ThrowError(\"CombinePlanes: source plane count must match with target plane count if provided!\");\n\n  // useful for later check\n  bool targetIsYUV = vi_default.IsYUV() || vi_default.IsYUVA();\n  bool targetHasAlpha = vi_default.IsYUVA() || vi_default.IsPlanarRGBA();\n  bool targetIsY = vi_default.IsY();\n\n  // class variables\n  bits_per_pixel = vi_default.BitsPerComponent();\n  pixelsize = vi_default.ComponentSize();\n  planecount = target_plane_count;\n\n  // if source plane is given, use it otherwise assume these\n  const char * rgb_source_planes_str_def = \"RGBA\";\n  const char * yuv_source_planes_str_def = allIsGrey ? \"YYYY\" : \"YUVA\";\n\n  int last_clip_index = 0;\n  for (int i = 0; i < target_plane_count; i++) {\n    char ch = toupper(_target_planes_str[i]);\n    bool isRGB = ch == 'R' || ch == 'G' || ch == 'B';\n    bool isYUV = ch == 'Y' || ch == 'U' || ch == 'V';\n    bool isAlpha = ch == 'A';\n    if(!isRGB && !isYUV && !isAlpha)\n      env->ThrowError(\"CombinePlanes: invalid plane definifion :%s\", planes);\n    if((targetIsYUV && isRGB) || (!targetIsYUV && isYUV) || (!targetHasAlpha && isAlpha) || (targetIsY && ch!='Y'))\n      env->ThrowError(\"CombinePlanes: target has no such plane %c\", ch);\n\n    int current_target_plane;\n    switch (ch) {\n    case 'R': current_target_plane = PLANAR_R; break;\n    case 'G': current_target_plane = PLANAR_G; break;\n    case 'B': current_target_plane = PLANAR_B; break;\n    case 'A': current_target_plane = PLANAR_A; break;\n    case 'Y': current_target_plane = PLANAR_Y; break;\n    case 'U': current_target_plane = PLANAR_U; break;\n    case 'V': current_target_plane = PLANAR_V; break;\n    }\n    target_planes[i] = current_target_plane;\n    int target_plane_width = vi_default.width >> vi_default.GetPlaneWidthSubsampling(current_target_plane);\n    int target_plane_height = vi_default.height >> vi_default.GetPlaneHeightSubsampling(current_target_plane);\n\n    if (clips[i]) // source clip count can be less than target planes count\n      last_clip_index = i; // last defined clip is used for the others\n\n    // check source clips and optinally their plane order\n    VideoInfo src_vi = clips[last_clip_index]->GetVideoInfo();\n\n    if(src_vi.BitsPerComponent() != bits_per_pixel)\n      env->ThrowError(\"CombinePlanes: source bit depth is different from %d\", bits_per_pixel);\n\n    bool sourceIsYUV = src_vi.IsYUV() || src_vi.IsYUVA();\n    bool sourceHasAlpha = src_vi.IsYUVA() || src_vi.IsPlanarRGBA();\n    bool sourceIsY = src_vi.IsY();\n    // check source\n    // source_plane_count is either 0 or == target_plane_count\n    {\n      char ch;\n      if (source_plane_count > 0) // optinal! defaults are filled\n        ch = toupper(_source_planes_str[i]);\n      else if (sourceIsYUV)\n        ch = toupper(yuv_source_planes_str_def[i]);\n      else // rgb\n        ch = toupper(rgb_source_planes_str_def[i]);\n      bool isRGB = ch == 'R' || ch == 'G' || ch == 'B';\n      bool isYUV = ch == 'Y' || ch == 'U' || ch == 'V';\n      bool isAlpha = ch == 'A';\n      if(!isRGB && !isYUV && !isAlpha)\n        env->ThrowError(\"CombinePlanes: invalid source plane definifion :%s\", planes);\n      if((sourceIsYUV && isRGB) || (!sourceIsYUV && isYUV) || (!sourceHasAlpha && isAlpha) || (sourceIsY && ch!='Y'))\n        env->ThrowError(\"CombinePlanes: source has no such plane %c\", ch);\n      // todo lambda\n      int current_source_plane;\n      switch (ch) {\n      case 'R': current_source_plane = PLANAR_R; break;\n      case 'G': current_source_plane = PLANAR_G; break;\n      case 'B': current_source_plane = PLANAR_B; break;\n      case 'A': current_source_plane = PLANAR_A; break;\n      case 'Y': current_source_plane = PLANAR_Y; break;\n      case 'U': current_source_plane = PLANAR_U; break;\n      case 'V': current_source_plane = PLANAR_V; break;\n      }\n      source_planes[i] = current_source_plane;\n      // check dimensions\n      int source_plane_width = src_vi.width >> src_vi.GetPlaneWidthSubsampling(current_source_plane);\n      int source_plane_height = src_vi.height >> src_vi.GetPlaneHeightSubsampling(current_source_plane);\n      if(source_plane_width != target_plane_width || source_plane_height != target_plane_height)\n        env->ThrowError(\"CombinePlanes: source and target plane dimensions are different\");\n    }\n  }\n}\n\n\nPVideoFrame __stdcall CombinePlanes::GetFrame(int n, IScriptEnvironment* env) {\n\n  VideoInfo vi_src = clips[0]->GetVideoInfo();\n\n  // check if fast Subframe magic can replace BitBlt\n  if (!clips[1] && vi.NumComponents() <= vi_src.NumComponents()) // YUV<->RGB, YUVA<->RGBA YUV->Y\n  {\n    // we have only one clip, plane shuffle is valid if target has less plane that defined in source\n    PVideoFrame src = clips[0]->GetFrame(n, env);\n\n    int planes_y[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };\n    int planes_r[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A };\n    int *planes = (vi_src.IsYUV() || vi_src.IsYUVA()) ? planes_y : planes_r;\n\n    int Offsets[4];\n    int Pitches[4], NewPitches[4];\n    int RowSizes[4], NewRowSizes[4];\n\n    int RelOffsets[4];\n\n    for (int i = 0; i < vi_src.NumComponents(); i++) {\n      Offsets[i] = src->GetOffset(planes[i]);\n      Pitches[i] = NewPitches[i] = src->GetPitch(planes[i]);\n      RowSizes[i] = NewRowSizes[i] = src->GetRowSize(planes[i]);\n      RelOffsets[i] = 0;\n    }\n\n    for (int i = 0; i < planecount; i++) {\n      int target_plane = target_planes[i];\n      int source_plane = source_planes[i];\n      int target_index, source_index;\n      switch (target_plane) {\n      case PLANAR_Y: case PLANAR_G: target_index = 0; break;\n      case PLANAR_U: case PLANAR_B: target_index = 1; break;\n      case PLANAR_V: case PLANAR_R: target_index = 2; break;\n      case PLANAR_A: target_index = 3; break;\n      }\n      switch (source_plane) {\n      case PLANAR_Y: case PLANAR_G: source_index = 0; break;\n      case PLANAR_U: case PLANAR_B: source_index = 1; break;\n      case PLANAR_V: case PLANAR_R: source_index = 2; break;\n      case PLANAR_A: source_index = 3; break;\n      }\n      // !! if offsets would be size_t, be cautious when you subtract two unsigned size_t variables\n      RelOffsets[target_index] = Offsets[source_index] - Offsets[target_index];\n      NewPitches[target_index] = Pitches[source_index];\n      NewRowSizes[target_index] = RowSizes[source_index];\n      // Y            U           V          A\n      // 10         1010        2010       3010     offsets\n      // src: AUVY target: YVUA\n      // 3010-10   2010-1010  1010-2010    10-3010\n      //  3000     =+1000      =-1000      =-3000   reloffsets\n      //  3010       2010        1010       10      new offsets inside\n    }\n\n    PVideoFrame dst;\n    if (vi.NumComponents() == 4) {\n      dst = env->SubframePlanarA(src, RelOffsets[0], NewPitches[0], NewRowSizes[0], src->GetHeight(),\n        RelOffsets[1], RelOffsets[2], NewPitches[1], RelOffsets[3]);\n    }\n    else if (vi.NumComponents() == 3) {\n      dst = env->SubframePlanar(src, RelOffsets[0], NewPitches[0], NewRowSizes[0], src->GetHeight(),\n        RelOffsets[1], RelOffsets[2], NewPitches[1]);\n    }\n    else {\n      dst = env->Subframe(src, RelOffsets[0], NewPitches[0], NewRowSizes[0], src->GetHeight());\n    }\n\n    // RGB(A)<->YUV(A) color space conversion can't be caught by Subframe...()\n    dst->AmendPixelType(vi.pixel_type);\n\n    return dst;\n  }\n\n  // check if first clip could be used as the target clip\n  PVideoFrame src = clips[0]->GetFrame(n, env);\n  PVideoFrame src1 = clips[1] ? clips[1]->GetFrame(n, env) : nullptr;\n\n  // case 1: when Y is kept from the original clip and other planes may be merged\n  if (vi_src.IsSameColorspace(vi) && target_planes[0] == source_planes[0]) {\n    // source (clip#0) has the same format as the target, and the first plane is the same\n    // luma (Y) comes w/o BitBlt. Only U and V (and optionally A) is copied.\n    if (src->IsWritable()) // we are the only one\n    {\n      src->AmendPixelType(vi.pixel_type);\n\n      PVideoFrame src_other = nullptr;\n      bool writeptr_obtained = false;\n\n      for (int i = 1; i < planecount; i++) {\n        int target_plane = target_planes[i];\n        int source_plane = source_planes[i];\n\n        if (clips[i]) { // source clips can be less than defined planes\n          if (!writeptr_obtained) {\n            src->GetWritePtr(PLANAR_Y); //Must be requested BUT only if we actually do something\n            writeptr_obtained = true;\n          }\n\n          if (i == 1)\n            src_other = src1; // already requested\n          else\n            src_other = clips[i]->GetFrame(n, env); // last defined clip is used for the others\n        }\n\n        if (src_other) {\n          env->BitBlt(src->GetWritePtr(target_plane), src->GetPitch(target_plane),\n            src_other->GetReadPtr(source_plane), src_other->GetPitch(source_plane), src_other->GetRowSize(source_plane), src_other->GetHeight(source_plane));\n        } else {\n          // we are still at the first (master) clip, no need for plane copy\n        }\n      }\n\n      return src;\n    }\n  }\n  else if (clips[1] && !clips[2]){\n    // Try to optimize a MergeLuma case, where luma comes from Y (can even be a format of single plane), \n    // Clip a's UV is kept.\n    // MergeLuma's speed gain: if 'a' is IsWritable() then there is no need for BitBlt chroma planes.\n    // We can only make a BitBlt from Y.\n    // We'd like to recognize the following scenario\n    // Output YUV:\n    // - Y from clip #0 (format:Y)\n    // - UV from clip #1 (format YUV420, same as output)\n    // planes: \"YUV\"\n    // \n    // clip #0 format does not match with the output, maybe it is a single plane\n    // let's try with the second (clip #1) if it can be used\n    if (clips[1]->GetVideoInfo().IsSameColorspace(vi) &&\n      // the rest plane IDs are matching between source and target\n      vi.NumComponents() >= 3 && target_planes[1] == source_planes[1] && target_planes[2] == source_planes[2] &&\n      (vi.NumComponents() < 4 || (vi.NumComponents() == 4 && target_planes[3] == source_planes[3])))\n    {\n      if (src1->IsWritable()) // we are the only one\n      {\n        src1->AmendPixelType(vi.pixel_type);\n\n        src1->GetWritePtr(PLANAR_Y); //Must be requested BUT only if we actually do something\n\n        int target_plane = target_planes[0];\n        int source_plane = source_planes[0];\n\n        // Copy from first clip\n        env->BitBlt(src1->GetWritePtr(target_plane), src1->GetPitch(target_plane),\n          src->GetReadPtr(source_plane), src->GetPitch(source_plane), src->GetRowSize(source_plane), src->GetHeight(source_plane));\n\n        env->copyFrameProps(src, src1);\n\n        return src1;\n      }\n    }\n  }\n\n  PVideoFrame dst = env->NewVideoFrame(vi);\n  bool propCopied = false;\n\n  for (int i = 0; i < planecount; i++) {\n    if (clips[i]) { // source clips can be less than defined planes\n      if (i > 0) { // clip #0 was already requested\n        if (i == 1) // clip #1 was already requested\n          src = src1;\n        else\n          src = clips[i]->GetFrame(n, env); // last defined clip is used for the others\n      }\n  \n      if (!propCopied) {\n        env->copyFrameProps(src, dst);\n        propCopied = true;\n      }\n    }\n\n    int target_plane = target_planes[i];\n    int source_plane = source_planes[i];\n\n    env->BitBlt(dst->GetWritePtr(target_plane), dst->GetPitch(target_plane),\n      src->GetReadPtr(source_plane), src->GetPitch(source_plane), src->GetRowSize(source_plane), src->GetHeight(source_plane));\n  }\n\n  return dst;\n}\n"
  },
  {
    "path": "avs_core/filters/planeswap.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n// Avisynth filter: Plane Swap\n// by Klaus Post\n\n\n\n#ifndef __Planeswap_H__\n#define __Planeswap_H__\n\n#include <avisynth.h>\n\n\n/****************************************************\n****************************************************/\n\nclass SwapUV : public GenericVideoFilter\n/**\n  * SwapUVs planar channels\n **/\n{\npublic:\n  SwapUV(PClip _child, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    if (cachehints == CACHE_GET_DEV_TYPE) {\n      return (vi.IsPlanar() && (child->GetVersion() >= 5)) ? child->SetCacheHints(CACHE_GET_DEV_TYPE, 0) : 0;\n    }\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl CreateSwapUV(AVSValue args, void* user_data, IScriptEnvironment* env);\n\n};\n\n\nclass SwapUVToY : public GenericVideoFilter\n/**\n  * SwapUVToYs planar channels\n **/\n{\npublic:\n  SwapUVToY(PClip _child, int _mode, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    if (cachehints == CACHE_GET_DEV_TYPE) {\n      return (!vi.IsYUY2() && (child->GetVersion() >= 5)) ? child->SetCacheHints(CACHE_GET_DEV_TYPE, 0) : 0;\n    }\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl CreateUToY(AVSValue args, void* user_data, IScriptEnvironment* env);\n  static AVSValue __cdecl CreateVToY(AVSValue args, void* user_data, IScriptEnvironment* env);\n  static AVSValue __cdecl CreateYToY8(AVSValue args, void* user_data, IScriptEnvironment* env);\n  static AVSValue __cdecl CreateUToY8(AVSValue args, void* user_data, IScriptEnvironment* env);\n  static AVSValue __cdecl CreateVToY8(AVSValue args, void* user_data, IScriptEnvironment* env);\n  static AVSValue __cdecl CreateAnyToY8(AVSValue args, void* user_data, IScriptEnvironment* env);\n  static AVSValue __cdecl CreatePlaneToY8(AVSValue args, void* user_data, IScriptEnvironment* env);\n\n  enum {UToY=1, VToY, UToY8, VToY8, YUY2UToY8, YUY2VToY8, AToY8, RToY8, GToY8, BToY8, YToY8};\n\nprivate:\n  int mode;\n};\n\n\nclass SwapYToUV : public GenericVideoFilter\n/**\n  * SwapYToYUVs planar channels\n **/\n{\npublic:\n  SwapYToUV(PClip _child, PClip _clip, PClip _clipY, PClip _clipA, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl CreateYToUV(AVSValue args, void* user_data, IScriptEnvironment* env);\n  static AVSValue __cdecl CreateYToYUV(AVSValue args, void* user_data, IScriptEnvironment* env);\n  static AVSValue __cdecl CreateYToYUVA(AVSValue args, void* user_data, IScriptEnvironment* env);\n\n\nprivate:\n  PClip clip, clipY, clipA;\n};\n\nclass CombinePlanes : public GenericVideoFilter\n  /**\n  * SwapYToYUVs planar channels\n  **/\n{\npublic:\n  CombinePlanes(PClip _child, PClip _clip2, PClip _clip3, PClip _clip4, PClip _sample, const char *_target_planes_str, const char *_source_planes_str, const char *_pixel_type, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl CreateCombinePlanes(AVSValue args, void* user_data, IScriptEnvironment* env);\n\n\nprivate:\n  PClip clips[4];\n  int pixelsize;\n  int bits_per_pixel;\n  int planecount;\n  char planes[4];\n  int source_planes[4];\n  int target_planes[4];\n};\n\n#endif  // __Planeswap_H__\n"
  },
  {
    "path": "avs_core/filters/resample.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include \"resample.h\"\n#ifdef INTEL_INTRINSICS\n#include \"intel/resample_sse.h\"\n#include \"intel/resample_avx2.h\"\n#ifdef INTEL_INTRINSICS_AVX512\n#include \"intel/resample_avx512.h\"\n#endif\n#include \"intel/turn_sse.h\"\n#include \"intel/turn_avx2.h\"\n#endif\n#ifdef NEON_INTRINSICS\n#include \"aarch64/turn_neon.h\"\n#endif\n\n#include <avs/config.h>\n\n#include \"transform.h\"\n#include \"turn.h\"\n#include <avs/alignment.h>\n#include <avs/minmax.h>\n#include \"../convert/convert_planar.h\"\n#include \"../convert/convert_helper.h\"\n\n#include <type_traits>\n#include <algorithm>\n\n#include \"../core/avs_simd_c.h\"\n#include <cassert>\n\n// Prepares resampling coefficients for end conditions and/or SIMD processing by:\n// 1. Sets a \"real-life\" size for the filter, which at small dimensions can be less than the original\n// 2. Aligning filter_size to 8 or 16 boundary for SIMD efficiency\n// 3. Right-aligning coefficients within padded arrays to ensure valid access at boundaries\n//\n// Before:                After right-alignment (filter_size=4, kernel_size=2):\n//\n// offset->|            offset-2 ->|         \n//        [x][y][  ][  ]          [0][0][x][y]\n//         ^ ^   ^   ^             ^         ^\n//         | |   Off-boundary      |         |\n//     Values used                 Values used\n//\n// This ensures SIMD instructions can safely load full vectors even at image boundaries\n// while maintaining correct coefficient positioning and proper zero padding.\n\n\nstatic void checkAndSetOverread(int end_pos, SafeLimit& safelimit, int start_pos, int i, int source_size) {\n  if (end_pos >= source_size) {\n    if (!safelimit.overread_possible) {\n      safelimit.overread_possible = true;\n      safelimit.source_overread_offset = start_pos;\n      safelimit.source_overread_beyond_targetx = i;\n    }\n  }\n}\n\n\nvoid resize_prepare_coeffs(ResamplingProgram* p, IScriptEnvironment* env, int filter_size_alignment) {\n  p->filter_size_alignment = filter_size_alignment;\n  p->safelimit_filter_size_aligned.overread_possible = false;\n  p->safelimit_4_pixels.overread_possible = false;\n  p->safelimit_8_pixels.overread_possible = false;\n  p->safelimit_16_pixels.overread_possible = false;\n  p->safelimit_32_pixels.overread_possible = false;\n  p->safelimit_8_pixels_each8th_target.overread_possible = false;\n  p->safelimit_16_pixels_each16th_target.overread_possible = false;\n  p->safelimit_64_pixels_each32th_target.overread_possible = false; // avx512 uint16_t 32 target pixels, handling 64 source pixels in permutex-based resizers\n  p->safelimit_128_pixels_each64th_target.overread_possible = false; // avx512 uint8_t 64 target pixels, handling 128 source pixels in permutex-based resizers\n  // FIXME: found out how to make it general safelimit_SOURCEREADPIXELS_pixels_each_TARGETPIXELSATATIME. Not here, in each frame proecssing for sure.\n\n  // note: filter_size_real was the max(kernel_sizes[])\n  int filter_size_aligned = AlignNumber(p->filter_size_real, p->filter_size_alignment);\n  // FIXME: really this needs to be dynamic based on SIMD used in resizer\n\n  int target_size_aligned = AlignNumber(p->target_size, ALIGN_RESIZER_TARGET_SIZE);\n\n  // align target_size to X units to allow safe, up to X pixels/cycle in H resizers.\n  // also, this is the coeff table Y-size.\n  // e.g. ALIGN_RESIZER_TARGET_SIZE = 64 allows to access coefficient table elements at\n  // current_coeff + filter_size * 63, if we step current_coeff by 64 * filter_size\n  p->target_size_alignment = ALIGN_RESIZER_TARGET_SIZE;\n\n  // Common variables for both float and integer paths\n  void* new_coeff = nullptr;\n  void* src_coeff = nullptr;\n  size_t element_size = 0;\n\n  // allocate for a larger target_size area and nullify the coeffs.\n  // Even between target_size and target_size_aligned.\n  if (p->bits_per_pixel == 32) {\n    element_size = sizeof(float);\n    src_coeff = p->pixel_coefficient_float;\n    new_coeff = env->Allocate(element_size * target_size_aligned * filter_size_aligned, 64, AVS_NORMAL_ALLOC);\n    if (!new_coeff) {\n      env->Free(new_coeff);\n      env->ThrowError(\"Could not reserve memory in a resampler.\");\n    }\n    std::fill_n((float*)new_coeff, target_size_aligned * filter_size_aligned, 0.0f);\n  }\n  else {\n    element_size = sizeof(short);\n    src_coeff = p->pixel_coefficient;\n    new_coeff = env->Allocate(element_size * target_size_aligned * filter_size_aligned, 64, AVS_NORMAL_ALLOC);\n    if (!new_coeff) {\n      env->Free(new_coeff);\n      env->ThrowError(\"Could not reserve memory in a resampler.\");\n    }\n    memset(new_coeff, 0, element_size * target_size_aligned * filter_size_aligned);\n  }\n\n  const int last_line = p->source_size - 1;\n\n  // Process coefficients - common code for both types\n  for (int i = 0; i < p->target_size; i++) {\n    const int kernel_size = p->kernel_sizes[i];\n    const int offset = p->pixel_offset[i];\n    const int last_coeff_index = offset + p->filter_size_real - 1;\n    const int shift_needed = last_coeff_index > last_line ? p->filter_size_real - kernel_size : 0;\n\n    // In order to be able to read 'filter_size_real' number of coefficients safely at the\n    // image boundaries, we right-align the actual coefficients within the allocated filter\n    // size. This will require adjusting (shifting) the pixel offsets as well, and increasing\n    // the smaller kernel sizes, to reflect the new effective size: filter_size_real.\n\n    // Copy coefficients with appropriate shift\n    if (p->bits_per_pixel == 32) {\n      float* dst = (float*)new_coeff + i * filter_size_aligned;\n      float* src = (float*)src_coeff + i * p->filter_size;\n      for (int j = 0; j < kernel_size; j++) {\n        dst[j + shift_needed] = src[j];\n      }\n    }\n    else {\n      short* dst = (short*)new_coeff + i * filter_size_aligned;\n      short* src = (short*)src_coeff + i * p->filter_size;\n      for (int j = 0; j < kernel_size; j++) {\n        dst[j + shift_needed] = src[j];\n      }\n    }\n\n    // Update offsets and kernel sizes\n    p->pixel_offset[i] -= shift_needed;\n    p->kernel_sizes[i] += shift_needed;\n\n    // left side, already right padded with zero coeffs, we can\n    // change to actual width to the common one\n    if(p->kernel_sizes[i] < p->filter_size_real)\n      p->kernel_sizes[i] = p->filter_size_real;\n\n    // In a horizontal resizer, when reading filter_size_alignment pixels,\n    // we must protect against source scanline overread.\n    // Using this not in only 32-bit float resizers is new in 3.7.4.\n    const int start_pos = p->pixel_offset[i];\n    const int end_pos = start_pos + p->filter_size_real - 1;\n    if (end_pos >= p->source_size) {\n      // This issue has already been fixed, so it cannot occur.\n    }\n\n    // Check for SIMD optimization limits and record first danger positions.\n    // If reading N pixels starting from `start_pos` would reach past the end\n    // of the source (>= source_size), register that first occurrence for\n    // the corresponding SafeLimit entry so resizers can avoid unsafe wide loads.\n\n    checkAndSetOverread(start_pos + filter_size_aligned - 1, p->safelimit_filter_size_aligned, start_pos, i, p->source_size);\n    checkAndSetOverread(start_pos + 4 - 1, p->safelimit_4_pixels, start_pos, i, p->source_size);\n    checkAndSetOverread(start_pos + 8 - 1, p->safelimit_8_pixels, start_pos, i, p->source_size);\n    checkAndSetOverread(start_pos + 16 - 1, p->safelimit_16_pixels, start_pos, i, p->source_size);\n    checkAndSetOverread(start_pos + 32 - 1, p->safelimit_32_pixels, start_pos, i, p->source_size);\n    // for permutex-based AVX2 ks4 float H resizers, where we read 8 pixels at a time exactly from\n    // start_pos of each Nth pixel output block\n    if (i % 8 == 0)\n      checkAndSetOverread(start_pos + 8 - 1, p->safelimit_8_pixels_each8th_target, start_pos, i, p->source_size);\n    if (i % 16 == 0)\n      checkAndSetOverread(start_pos + 16 - 1, p->safelimit_16_pixels_each16th_target, start_pos, i, p->source_size);\n    if (i % 32 == 0) // avx512 uint16_t 32 target pixels, handling 64 source pixels\n      checkAndSetOverread(start_pos + 64 - 1, p->safelimit_64_pixels_each32th_target, start_pos, i, p->source_size);\n    if (i % 64 == 0) // avx512 uint8_t 64 target pixels, handling 128 source pixels\n      checkAndSetOverread(start_pos + 128 - 1, p->safelimit_128_pixels_each64th_target, start_pos, i, p->source_size);\n\n      }\n\n  // from now on, kernel_sizes[] has no role, each is filter_size_real\n  p->kernel_sizes.clear();\n\n  // Fill the extra offset after target_size with fake values.\n  // Our aim is to have a safe, up to 8-32 pixels/cycle simd loop for V and specific H resizers.\n  // Their coeffs will be 0, so they don't count if such coeffs\n  // are multiplied with invalid, though existing pixels.\n  if (p->target_size < target_size_aligned) {\n    p->pixel_offset.resize(target_size_aligned);\n    int last_offset = p->pixel_offset[p->target_size - 1];\n    for (int i = p->target_size; i < target_size_aligned; ++i) {\n      p->pixel_offset[i] = last_offset; // repeat last valid offset, helps permutex-based H resizers to stay within valid distances\n    }\n  }\n\n  // Free old coefficients and assign new ones\n  if (p->bits_per_pixel == 32) {\n    env->Free(p->pixel_coefficient_float);\n    p->pixel_coefficient_float = (float*)new_coeff;\n  }\n  else {\n    env->Free(p->pixel_coefficient);\n    p->pixel_coefficient = (short*)new_coeff;\n  }\n\n  p->filter_size = filter_size_aligned;\n  // by now coeffs[old_filter_size][target_size] was copied and padded into coeffs[new_filter_size][target_size]\n}\n\n/***************************************\n ***** Vertical Resizer Assembly *******\n ***************************************/\n\ntemplate<typename pixel_t>\nstatic void resize_v_planar_pointresize(BYTE* dst, const BYTE* src, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel)\n{\n  AVS_UNUSED(bits_per_pixel);\n\n  pixel_t* src0 = (pixel_t*)src;\n  pixel_t* dst0 = (pixel_t*)dst;\n  src_pitch = src_pitch / sizeof(pixel_t);\n  dst_pitch = dst_pitch / sizeof(pixel_t);\n\n  for (int y = 0; y < target_height; y++) {\n    int offset = program->pixel_offset[y];\n    const pixel_t* src_ptr = src0 + src_pitch * offset;\n\n    memcpy(dst0, src_ptr, width * sizeof(pixel_t));\n\n    dst0 += dst_pitch;\n  }\n}\n\n// This C implementation isn't optimized for auto-vectorization,\n// But on x86 MSVC SSE2 settings for 8 bit pixel types it performs better than our \n// vectorizer-friendly version.\n// Other compilers benefit from vectorizing by a huge margin for every case.\n// The vector code which replaced this is already 2x faster for 10-16 bits processing\n// and achieves a 6x speedup for 32-bit operations. LLVM has even an additional 1.5x-4x speedup \n// compared to MSVC.\n// Kept for reference, supports 8, 10-16 and 32 bit pixel types.\ntemplate<typename pixel_t, bool lessthan16bit>\nstatic void resize_v_c_planar(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel)\n{\n\n  int filter_size = program->filter_size;\n\n  typedef typename std::conditional < std::is_floating_point<pixel_t>::value, float, short>::type coeff_t;\n  coeff_t* current_coeff;\n\n  if (!std::is_floating_point<pixel_t>::value)\n    current_coeff = (coeff_t*)program->pixel_coefficient;\n  else\n    current_coeff = (coeff_t*)program->pixel_coefficient_float;\n\n  pixel_t* src = (pixel_t*)src8;\n  pixel_t* dst = (pixel_t*)dst8;\n  src_pitch = src_pitch / sizeof(pixel_t);\n  dst_pitch = dst_pitch / sizeof(pixel_t);\n\n  pixel_t limit = 0;\n  if (!std::is_floating_point<pixel_t>::value) {  // floats are unscaled and uncapped\n    if constexpr (sizeof(pixel_t) == 1) limit = 255;\n    else if constexpr (sizeof(pixel_t) == 2) limit = pixel_t((1 << bits_per_pixel) - 1);\n  }\n\n  // for 16 bits only\n  const short shifttosigned_short = -32768;\n  const int shiftfromsigned_int = 32768 << FPScale16bits;\n\n  for (int y = 0; y < target_height; y++) {\n    int offset = program->pixel_offset[y];\n    const int kernel_size = program->kernel_sizes[y];\n    const pixel_t* src_ptr = src + src_pitch * offset;\n\n    // perhaps helps vectorizing decision\n    const int ksmod4 = kernel_size / 4 * 4;\n\n    for (int x = 0; x < width; x++) {\n      if constexpr (std::is_floating_point<pixel_t>::value) {\n        const float* src2_ptr = src_ptr + x;\n\n        float result = 0;\n        for (int i = 0; i < ksmod4; i += 4) {\n          result += *(src2_ptr + 0 * src_pitch) * current_coeff[i + 0];\n          result += *(src2_ptr + 1 * src_pitch) * current_coeff[i + 1];\n          result += *(src2_ptr + 2 * src_pitch) * current_coeff[i + 2];\n          result += *(src2_ptr + 3 * src_pitch) * current_coeff[i + 3];\n          src2_ptr += 4 * src_pitch;\n        }\n        for (int i = ksmod4; i < kernel_size; i++) {\n          result += *src2_ptr * current_coeff[i];\n          src2_ptr += src_pitch;\n        }\n        dst[x] = result;\n      }\n      else if constexpr (sizeof(pixel_t) == 2) {\n        // theoretically, no need for int64 accumulator,\n        // sum of coeffs is 1.0 that is (1 << FPScale16bits) in integer arithmetic\n        const uint16_t* src2_ptr = src_ptr + x;\n        int result = 1 << (FPScale16bits - 1); // rounder;\n        for (int i = 0; i < ksmod4; i += 4) {\n          int val;\n          val = *(src2_ptr + 0 * src_pitch);\n          if constexpr (!lessthan16bit)\n            val = val + shifttosigned_short;\n          result += val * current_coeff[i + 0];\n\n          val = *(src2_ptr + 1 * src_pitch);\n          if constexpr (!lessthan16bit)\n            val = val + shifttosigned_short;\n          result += val * current_coeff[i + 1];\n\n          val = *(src2_ptr + 2 * src_pitch);\n          if constexpr (!lessthan16bit)\n            val = val + shifttosigned_short;\n          result += val * current_coeff[i + 2];\n\n          val = *(src2_ptr + 3 * src_pitch);\n          if constexpr (!lessthan16bit)\n            val = val + shifttosigned_short;\n          result += val * current_coeff[i + 3];\n\n          src2_ptr += 4 * src_pitch;\n        }\n        for (int i = ksmod4; i < kernel_size; i++) {\n          int val = *src2_ptr;\n          if constexpr (!lessthan16bit)\n            val = val + shifttosigned_short;\n          result += val * current_coeff[i];\n          src2_ptr += src_pitch;\n        }\n        if constexpr (!lessthan16bit)\n          result = result + shiftfromsigned_int;\n        result = result >> FPScale16bits;\n        result = result > limit ? limit : result < 0 ? 0 : result; // clamp 10..16 bits\n        dst[x] = (uint16_t)result;\n      }\n      else if constexpr (sizeof(pixel_t) == 1) {\n        const uint8_t* src2_ptr = src_ptr + x;\n        int result = 1 << (FPScale8bits - 1); // rounder;\n        for (int i = 0; i < ksmod4; i += 4) {\n          short val;\n          val = *(src2_ptr + 0 * src_pitch);\n          result += val * current_coeff[i + 0];\n\n          val = *(src2_ptr + 1 * src_pitch);\n          result += val * current_coeff[i + 1];\n\n          val = *(src2_ptr + 2 * src_pitch);\n          result += val * current_coeff[i + 2];\n\n          val = *(src2_ptr + 3 * src_pitch);\n          result += val * current_coeff[i + 3];\n\n          src2_ptr += 4 * src_pitch;\n        }\n        for (int i = ksmod4; i < kernel_size; i++) {\n          short val = *src2_ptr;\n          result += val * current_coeff[i];\n          src2_ptr += src_pitch;\n        }\n        result = result >> FPScale8bits;\n        result = result > limit ? limit : result < 0 ? 0 : result; // clamp 8 bits\n        dst[x] = (uint8_t)result;\n      }\n    }\n\n    dst += dst_pitch;\n    current_coeff += filter_size;\n  }\n}\n\n\n/*\n\nBenchmarks.\n\n  SetMaxCPU(\"none\")\n  #SetMaxCPU(\"SSSE3\")\n  #SetMaxCPU(\"AVX2\")\n  ColorbarsHD(200,200, pixel_type=\"YUV444P8\") # P8, P10, P16, PS\n\n  wmul=2 # >1: horizontal resizer test\n  hmul=1 # >1: vertical resizer test\n\n  avs=LanczosResize(width*wmul, height*hmul, taps=16)\n  avsr=z_ConvertFormat(width=width*wmul, height=height*hmul, resample_filter=\"lanczos\", filter_param_a=16)\n  fmtconv=fmtc_resample(w=width*wmul, h=height*hmul, kernel=\"lanczos\", taps=16)\n  avs\n\nFigures in general has no place in source code but it is useful to have a clue \nand see the huge differences between compilers and code variants.\nAlso, only mazochists want to test integer optimization with MSVC (x86). Wasted time.\nUse llvm on Arm, clangcl/llvm on Windows x86.\n\nHorizontals                Hor+Vert    Verticals\n [8]  [10-14]  [16]  [32]  [8]  [10]   [8]  [10-14] [16] [32]\n 177     170    101  208               262   486    417   217    C-RaspberryPi5 gcc 12.2 (code variant)\n 137     469     88  208                                         C-RaspberryPi5 gcc 12.2 (code variant)\n 227     218    147  178                                         C-RaspberryPi5 gcc 12.2 no vector attrib ??! Quicker than vector attrib version gcc not recommended\n 416     611    579  404    128  186   362   609    556   624    C-RaspberryPi5 llvm 14 vector attrib\n  90     185     94  403                                         C-RaspberryPi5 llvm 14 vector attrib + integer madd@H\n 180     182    162          67        213   212    206   639    C-RaspberryPi5 llvm 14 no vector attrib\n 942     985    982  993               976  1114    982  1920    C-ClangCl in 3.7.6 VS2026 SSE2 (MSVC tuned simd_c and even more tuned vector-friendly code)\n1270    1238   1186                   1550  1555   1560  3670    C-ClangCl in VS2022 AVX2\n1051    1126   1102                                              C-Intel ICX 2025 SSE2\n1513    2355   1560 1128                                 1969    C-Intel ICX 2025 SSE4.2  smart madd!\n1938    2413   1775 1061    442  453  1136  1126   1037  3511    C-Intel ICX 2025 AVX2\n 212     188    187  264     73   64   223   195    198   268    C-MSVC SSE2 3.7.3\n 417     463    360                    449   424    384   352    C-MSVC SSE2 3.7.4 (some unrolling vs. 3.7.3)\n 215     215     97  928     79   79   220   744     96  1951    C-MSVC SSE2 (zero optim seen in asm on 8-16, did not tolerate vector-friendly code)\n 595     638    634  976               552   382     95  1940    C-MSVC SSE2 3.7.6 (MSVC tuned simd_c and vector-friendly code)\n 591     616    620                    700   670    518  1950    C-MSVC SSE2 3.7.6 (MSVC tuned simd_c and even more tuned vector-friendly code)\n 853     913    924 1107               880   860    713  3777    C-MSVC AVX2 3.7.6 (MSVC tuned simd_c and vector-friendly code)\n 201     206     99                                              C-MSVC AVX2 3.7.4 (zero optim seen in asm also on 8-16, not even using SSE2 xmm registers)\n 597     631    651                                              C-Intel SSE4.2  3.7.4 code\n1183    1193    889                                              C-Intel AVX2    3.7.4 code\n5600                       2140                                  SIMD-avsresize (AVX2 or AVX512?)\n2260                        840                                  SIMD-fmtconv (16 bit output for 8 bits)\n4578    2614   2560 2250   1490       4220  4534   3887  3570    SIMD-MSVC AVX2 3.7.3 (horizontal was memory-boundary unsafe)\n3631    3505   3221 2344   1291 1354  3804  4466   3855  2260    SIMD-MSVC AVX2 3.7.4 Float vertical regression - no time to finish\n3720    3478   3130 2385   1566 1480  5014  5288   5077  3810    SIMD-MSVC AVX2 + incrementing offsets in V, 20-25% gain in integer verticals\n4730    4612   4233 2487   1390 1471  3792  4476   4380  3942    SIMD-ClangCl AVX2, verticals behind MSVC by surprise\n2373    2181   1893 1306    868  723  2660  2137   2670  1886    SIMD-MSVC SSSE3 + incrementing offsets in V, 20-25% gain in integer verticals\n2294    2979   2595 1460    859  976  2623  2865   2625  1962    SIMD-Intel ICX 2025 SSSE3\n4395    4616   4160 2570   1664 1720  5110  5870   5085  2999    SIMD-Intel ICX 2025 AVX2 Surprisingly slow at vertical float FIXME, slower than C :)\n4755    4453   4255 3540   1447 1537  3560  4592   3920  7837    SIMD-ClangCL 3.7.6\n\n* float has different optimization: 8 pixels 2 coeffs\n** on aarch64 the float benchmarks included a ConvertBits(8) at the end.\n\nNon-x86 platforms are the focus of this comparison, as they lack SIMD optimized paths.\nx86 platforms have their own SIMD optimized paths and do not use C.\n\nCompilers can give totally different results even after some reordering of the code,\nSee gcc aarch64: the 8 bit case dropped to 2/3 speed while 16 bits increased by a factor of 250%\ndepending on where I put a line.\n\nConsiderations for aarch64 (Armv8a, includes neon, e.g. RPi5 with gcc 12.2, llvm 14.0.6)\n- gcc is not recommended, their vectorizer is either broken or not yet ready.\n  Using vector attribute gave slower code.\n- llvm gave consistent fast results.\n- Vertical resampler: aarch64 + GCC, (8-16 bits) the 4-pixel 4-coefficient version performs best.\n\nOn x86 platforms MSVC is unusable regarding integer vectorization, the more the code helps to\nrecognize vectorization patterns the slower assembly it produces, e.g. horizontal resizer AVX2 16 bit: \nMSVC 99 fps (634 after tuning), MSVC+clangcl: 1186 fps, Intel+LLVM: 1775 fps. Joke. We use\nonly for internal testing and reference, not for actual builds, everithing is SIMD optimized in Avisynth for x86.\n\nMSVC on x86 is only capable of vectorizing 32 bit float code, and even then it is not the fastest.\nThere is no reason to not use clangcl for x86 Visual Studio builds. It comes officially with VS2022 for free.\n2026 update: simd_c was tuned for better MSVC auto-vectorization.\n\n*/\n\n// This is a vectorizer-friendly version of the above function.\ntemplate<typename pixel_t, bool lessthan16bit>\nvoid resize_v_c_planar_uint8_16_t_auto_vectorized(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel) {\n\n  const short* AVS_RESTRICT current_coeff = program->pixel_coefficient;\n\n  auto src = reinterpret_cast<const pixel_t*>(src8);\n  auto dst = reinterpret_cast<pixel_t * AVS_RESTRICT>(dst8);\n  src_pitch = src_pitch / sizeof(pixel_t);\n  dst_pitch = dst_pitch / sizeof(pixel_t);\n\n  int limit = 0;\n  if constexpr (sizeof(pixel_t) == 1) limit = 255;\n  else if constexpr (sizeof(pixel_t) == 2) limit = pixel_t((1 << bits_per_pixel) - 1);\n\n  // for 16 bits only\n  [[maybe_unused]] Int16x8 shifttosigned_short(-32768);\n  [[maybe_unused]] const Int32x4 shiftfromsigned_int(32768 << FPScale16bits);\n\n  const int filter_size = program->filter_size;\n  constexpr int fixpoint_scaler_bits = sizeof(pixel_t) == 2 ? FPScale16bits : FPScale8bits;\n  const int rounder = 1 << (fixpoint_scaler_bits - 1);\n\n  // 8-16 SIMD padding of coeffs is not usable here, work with single coeffs\n\n  const int kernel_size = program->filter_size_real;\n\n  const int ksmod4 = kernel_size / 4 * 4;\n\n  for (int y = 0; y < target_height; y++) {\n    int offset = program->pixel_offset[y];\n    const pixel_t* src_ptr = src + offset * src_pitch;\n\n    // 4 pixels at a time\n    for (int x = 0; x < width; x += 4) {\n      Int32x4 result(rounder); // master accumulator and the initial first coeff part\n      Int32x4 result_2(0);\n      Int32x4 result_3(0);\n      Int32x4 result_4(0);\n      const pixel_t* AVS_RESTRICT src2_ptr = src_ptr + x; // __restrict here\n      int i = 0;\n      // Process coefficients in pairs or quads for better instruction parallelism.\n      // Depending on platform and compiler, results may vary.\n      // Since on Intel we have SIMD optimized paths, we decide on the\n      // results of a not-yet-optimized aarch64 platform: takeout is 4 pix 4 coeff\n      for (; i < ksmod4; i += 4) {\n\n        Int32x4 src_1, src_2, src_3, src_4;\n\n        const int coeff_1 = current_coeff[i];\n        const int coeff_2 = current_coeff[i + 1];\n        const int coeff_3 = current_coeff[i + 2];\n        const int coeff_4 = current_coeff[i + 3];\n\n        if constexpr (sizeof(pixel_t) == 1) {\n          // uint8_t\n          auto src8_1 = Uint8x4::from_ptr(src2_ptr);\n          auto src8_2 = Uint8x4::from_ptr(src2_ptr + src_pitch);\n          auto src8_3 = Uint8x4::from_ptr(src2_ptr + 2 * src_pitch);\n          auto src8_4 = Uint8x4::from_ptr(src2_ptr + 3 * src_pitch);\n\n          src_1 = Int32x4::convert_from(src8_1);\n          src_2 = Int32x4::convert_from(src8_2);\n          src_3 = Int32x4::convert_from(src8_3);\n          src_4 = Int32x4::convert_from(src8_4);\n        }\n        else {\n          // uint16_t\n          // only lo 64 bit (4x16) is used\n          auto src16_1 = Int16x8::from_ptr_lo(reinterpret_cast<const short* AVS_RESTRICT>(src2_ptr));\n          auto src16_2 = Int16x8::from_ptr_lo(reinterpret_cast<const short* AVS_RESTRICT>(src2_ptr + src_pitch));\n          auto src16_3 = Int16x8::from_ptr_lo(reinterpret_cast<const short* AVS_RESTRICT>(src2_ptr + 2 * src_pitch));\n          auto src16_4 = Int16x8::from_ptr_lo(reinterpret_cast<const short* AVS_RESTRICT>(src2_ptr + 3 * src_pitch));\n\n          // Turn unsigned to signed 16 bit, will be adjusted back before scaling back and storing.\n          // Since there's a little hope that short*short pattern is recognized by the compiler, though \n          // this is different from the horizontal case where hadd can be used.\n          if constexpr (!lessthan16bit) {\n            src16_1 += shifttosigned_short;\n            src16_2 += shifttosigned_short;\n            src16_3 += shifttosigned_short;\n            src16_4 += shifttosigned_short;\n          }\n          // widen short->int\n          src_1 = Int32x4::convert_from_lo(src16_1);\n          src_2 = Int32x4::convert_from_lo(src16_2);\n          src_3 = Int32x4::convert_from_lo(src16_3);\n          src_4 = Int32x4::convert_from_lo(src16_4);\n        }\n\n        result += src_1 * coeff_1;\n        result_2 += src_2 * coeff_2;\n        result_3 += src_3 * coeff_3;\n        result_4 += src_4 * coeff_4;\n\n        src2_ptr += 4 * src_pitch;\n      }\n\n      result += result_2;\n      result_3 += result_4;\n      result += result_3;\n\n      // rest zero or one\n      for (; i < kernel_size; ++i) {\n        Int32x4 src;\n        const int a_coeff = current_coeff[i];\n        if constexpr (sizeof(pixel_t) == 1) {\n          // uint8_t\n          src.load_from_any_intptr(src2_ptr);\n        }\n        else {\n          // uint16_t\n          auto src16 = Int16x8::from_ptr_lo(reinterpret_cast<const short* AVS_RESTRICT>(src2_ptr));\n          if constexpr (!lessthan16bit) {\n            src16 += shifttosigned_short;\n          }\n          src = Int32x4::convert_from_lo(src16); // widen short->int\n        }\n\n        result += src * a_coeff;\n\n        src2_ptr += src_pitch;\n      }\n\n      // back to unsigned 16 bit for exact 16 bit source\n      if constexpr (sizeof(pixel_t) == 2 && !lessthan16bit) {\n        result += shiftfromsigned_int;\n      }\n\n      result >>= fixpoint_scaler_bits;\n\n      if constexpr (sizeof(pixel_t) == 1) {\n        Uint8x4 result8;\n        convert_and_saturate_int32x4_to_uint8x4(result, result8);\n        result8.store(dst + x);\n      }\n      else {\n        Uint16x4 result16;\n        if constexpr (lessthan16bit) {\n          convert_and_saturate_int32x4_to_uint16x4_limit(result, result16, limit);\n        }\n        else {\n          convert_and_saturate_int32x4_to_uint16x4(result, result16);\n        }\n        result16.store(dst + x);\n      }\n    }\n\n    dst += dst_pitch;\n    current_coeff += filter_size;\n  }\n}\n\n\nstatic void resize_v_c_planar_float_auto_vectorized(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel) {\n\n  const float* AVS_RESTRICT current_coeff = program->pixel_coefficient_float;\n\n  auto src = reinterpret_cast<const float*>(src8);\n  auto dst = reinterpret_cast<float* AVS_RESTRICT>(dst8);\n  src_pitch = src_pitch / sizeof(float);\n  dst_pitch = dst_pitch / sizeof(float);\n\n  const int filter_size = program->filter_size;\n\n  // 8-16 SIMD padding of coeffs is not usable here, work with single coeffs\n  const int kernel_size = program->filter_size_real;\n  const int ksmod2 = kernel_size / 2 * 2; // Ensure kernel_size is processed in multiples of 2\n\n  for (int y = 0; y < target_height; y++) {\n    int offset = program->pixel_offset[y];\n    const float* src_ptr = src + offset * src_pitch;\n\n    for (int x = 0; x < width; x += 8) {\n      // This function written in vectorizer-friendly C unexpectedly outperformed \n      // our hand-written SSE2 version.\n      // The reason: Float8 class is probably using two 128-bit XMM registers\n      // when compiled with SSE2 enabled by MSVC, processing 8 floats per iteration.\n      // Our original SSE2 function only processed 4 pixels at once, explaining the\n      // performance difference. We've since updated the SSE2 version to also process\n      // 8 pixels simultaneously using two XMM registers.\n      // Processing two coefficients further increases the throughput.\n      Float8 result(0.f);\n      Float8 result_2(0.f);\n      const float* AVS_RESTRICT src2_ptr = src_ptr + x;\n\n      for (int i = 0; i < ksmod2; i += 2) {\n        const float coeff_1 = current_coeff[i];\n        const float coeff_2 = current_coeff[i + 1];\n        Float8 src_1 = Float8::from_ptr(src2_ptr);\n        Float8 src_2 = Float8::from_ptr(src2_ptr + src_pitch);\n        result += src_1 * coeff_1;\n        result_2 += src_2 * coeff_2;\n\n        src2_ptr += 2 * src_pitch;\n      }\n\n      result += result_2;\n\n      // Process remaining coefficients if kernel_size is odd\n      if (ksmod2 < kernel_size) {\n        const float a_coeff = current_coeff[ksmod2];\n        Float8 src = Float8::from_ptr(src2_ptr);\n        result += src * a_coeff;\n      }\n\n      // no rounding, no clamp\n      result.store(dst + x);\n    }\n\n    dst += dst_pitch;\n    current_coeff += filter_size;\n  }\n}\n\n\n/***************************************\n ********* Horizontal Resizer** ********\n ***************************************/\n\n// Only <float> is used, which got some SIMD-C optimizations.\n// On x86 MSVC the 8-16 bit versions may perform better due to their extremely poor integer \n// vectorization capabilities.\n// But gcc and llvm (clangcl) compilers perform very good, their code from the other,\n// vector-fiendly versions are excellent, as expected in 2025.\n// Luckily, on x86 there are handcrafted SIMD versions for all 8, 10-16 and 32 bit pixel types.\n\ntemplate<typename pixel_t, bool lessthan16bit>\nstatic void resize_h_c_planar(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n  int filter_size = program->filter_size;\n\n  typedef typename std::conditional < std::is_floating_point<pixel_t>::value, float, short>::type coeff_t;\n  const coeff_t* AVS_RESTRICT current_coeff;\n\n  pixel_t limit = 0;\n  if (!std::is_floating_point<pixel_t>::value) {  // floats are unscaled and uncapped\n    if constexpr (sizeof(pixel_t) == 1) limit = 255;\n    else if constexpr (sizeof(pixel_t) == 2) limit = pixel_t((1 << bits_per_pixel) - 1);\n  }\n\n  src_pitch = src_pitch / sizeof(pixel_t);\n  dst_pitch = dst_pitch / sizeof(pixel_t);\n\n  pixel_t* src = (pixel_t*)src8;\n  pixel_t* dst = (pixel_t*)dst8;\n\n  // for 16 bits only\n  const short shifttosigned_short = -32768;\n  const int shiftfromsigned_int = 32768 << FPScale16bits;\n\n  // perhaps helps vectorizing decision\n  const int kernel_size = program->filter_size_real;\n  const int ksmod4 = kernel_size / 4 * 4;\n  const int ksmod8 = kernel_size / 8 * 8;\n\n  // external loop y is much faster\n  for (int y = 0; y < height; y++) {\n    if (!std::is_floating_point<pixel_t>::value)\n      current_coeff = (const coeff_t* AVS_RESTRICT)program->pixel_coefficient;\n    else\n      current_coeff = (const coeff_t* AVS_RESTRICT)program->pixel_coefficient_float;\n\n    pixel_t* AVS_RESTRICT dst2_ptr = dst + y * dst_pitch;\n    const pixel_t* src_ptr = src + y * src_pitch;\n\n    for (int x = 0; x < width; x++) {\n      int begin = program->pixel_offset[x];\n      const pixel_t* AVS_RESTRICT src2_ptr = src_ptr + begin;\n\n      if constexpr (std::is_floating_point<pixel_t>::value) {\n        Float4 result(0.f);\n        for (int i = 0; i < ksmod4; i += 4) {\n          Float4 src = Float4::from_ptr(src2_ptr + i);\n          Float4 coeff = Float4::from_ptr(current_coeff + i);\n          result += src * coeff;\n        }\n        float result_single = result.horiz_add_float();\n        for (int i = ksmod4; i < kernel_size; i++) {\n          result_single += src2_ptr[i] * current_coeff[i];\n        }\n        dst2_ptr[x] = result_single;\n      }\n      else if constexpr (sizeof(pixel_t) == 2) {\n        // theoretically, no need for int64 accumulator,\n        // sum of coeffs is 1.0 that is (1 << FPScale16bits) in integer arithmetic\n        int result = 1 << (FPScale16bits - 1); // rounder;\n        for (int i = 0; i < ksmod4; i += 4) {\n          int val;\n          val = src2_ptr[i+0];\n          if constexpr (!lessthan16bit)\n            val = val + shifttosigned_short;\n          result += val * current_coeff[i+0];\n\n          val = src2_ptr[i+1];\n          if constexpr (!lessthan16bit)\n            val = val + shifttosigned_short;\n          result += val * current_coeff[i+1];\n\n          val = src2_ptr[i + 2];\n          if constexpr (!lessthan16bit)\n            val = val + shifttosigned_short;\n          result += val * current_coeff[i + 2];\n\n          val = src2_ptr[i + 3];\n          if constexpr (!lessthan16bit)\n            val = val + shifttosigned_short;\n          result += val * current_coeff[i + 3];\n        }\n        for (int i = ksmod4; i < kernel_size; i++) {\n          int val = src2_ptr[i];\n          if constexpr (!lessthan16bit)\n            val = val + shifttosigned_short;\n          result += val * current_coeff[i];\n        }\n        if constexpr (!lessthan16bit)\n          result = result + shiftfromsigned_int;\n        result = result >> FPScale16bits;\n        result = result > limit ? limit : result < 0 ? 0 : result; // clamp 10..16 bits\n        dst2_ptr[x] = (uint16_t)result;\n      }\n      else if constexpr (sizeof(pixel_t) == 1) {\n        int result = 1 << (FPScale8bits - 1); // rounder;\n        for (int i = 0; i < ksmod8; i += 8) {\n          short val;\n          val = src2_ptr[i + 0];\n          result += val * current_coeff[i + 0];\n          val = src2_ptr[i + 1];\n          result += val * current_coeff[i + 1];\n          val = src2_ptr[i + 2];\n          result += val * current_coeff[i + 2];\n          val = src2_ptr[i + 3];\n          result += val * current_coeff[i + 3];\n          val = src2_ptr[i + 4];\n          result += val * current_coeff[i + 4];\n          val = src2_ptr[i + 5];\n          result += val * current_coeff[i + 5];\n          val = src2_ptr[i + 6];\n          result += val * current_coeff[i + 6];\n          val = src2_ptr[i + 7];\n          result += val * current_coeff[i + 7];\n        }\n        for (int i = ksmod8; i < ksmod4; i += 4) {\n          short val;\n          val = src2_ptr[i + 0];\n          result += val * current_coeff[i + 0];\n          val = src2_ptr[i + 1];\n          result += val * current_coeff[i + 1];\n          val = src2_ptr[i + 2];\n          result += val * current_coeff[i + 2];\n          val = src2_ptr[i + 3];\n          result += val * current_coeff[i + 3];\n          val = src2_ptr[i + 4];\n        }\n        for (int i = ksmod4; i < kernel_size; i++) {\n          short val = src2_ptr[i];\n          result += val * current_coeff[i];\n        }\n        result = result >> FPScale8bits;\n        result = result > limit ? limit : result < 0 ? 0 : result; // clamp 8 bits\n        dst2_ptr[x] = (uint8_t)result;\n      }\n      current_coeff += filter_size;\n    }\n  }\n}\n\n// Vectorizer-friendly 8-16 bit horizontal resampler\n\n// 8 pixel instead of real-SIMD 16 to ease register pressure \n// and the make the compiler task easier\ntemplate<typename pixel_t, bool lessthan16bit>\nAVS_FORCEINLINE static void process_two_8pixels_h_uint8_16_core(const pixel_t* AVS_RESTRICT src_ptr, const short* AVS_RESTRICT current_coeff, Int32x4& AVS_RESTRICT result, const Int16x8& shifttosigned_8xshort) {\n\n  Int16x8 data;\n  // using signed int16 (short) until the coeff multiplication\n  if constexpr (sizeof(pixel_t) == 1) {\n    // pixel_t is uint8_t\n    Uint8x8 src = Uint8x8::from_ptr(src_ptr);\n    data = Int16x8::convert_from(src); // 8 pixels uint8_t->int16\n  }\n  else {\n    // pixel_t is uint16_t, at exact 16 bit bit depth unsigned -> signed 16 bit conversion needed\n    // this mimics the behavior of the SIMD version, which processes signed 16 bit input\n    // data.load(reinterpret_cast<const short * AVS_RESTRICT>(src_ptr));\n    Uint16x8 src = Uint16x8::from_ptr(src_ptr);\n    data = Int16x8::convert_from(src); // 8 pixels uint8_t->int16\n\n    if constexpr (!lessthan16bit) {\n      data += shifttosigned_8xshort; // 16 bit addition is invariant regarding overflow\n    }\n  }\n\n  Int16x8 coeff = Int16x8::from_ptr(current_coeff); // 8 coeffs\n\n  // no need real intel-like madd, but intel compiler can use it (experienced)\n#if defined(__INTEL_LLVM_COMPILER)\n  // Intel proc + LLVM: only this compiler combo is compiling into madd,which is much faster.\n  Int32x4 madd_result = simul_madd_epi16(data, coeff);\n#else\n  Int32x4 madd_result = mul16x16_reduce_to_Int32x4(data, coeff);\n#endif\n  result += madd_result;\n  // later, the four 32 bit results will be further reduced and added together (hadd)\n}\n\n\ntemplate<typename pixel_t, bool lessthan16bit>\nAVS_FORCEINLINE static void process_two_4pixels_h_uint8_16_core(const pixel_t* AVS_RESTRICT src_ptr, const short* AVS_RESTRICT current_coeff, Int32x4& AVS_RESTRICT result, const Int32x4& shifttosigned_4xint) {\n  Int32x4 data;\n\n  // this one is using full int32 internally\n\n  if constexpr (sizeof(pixel_t) == 1) {\n    data.load_from_any_intptr(src_ptr); // 4 pixels uint8_t->int32\n  }\n  else {\n    // pixel_t is uint16_t, at exact 16 bit bit depth an unsigned -> signed 16 bit conversion needed\n    data.load_from_any_intptr(src_ptr); // 4 pixels uint16_t->int32\n\n    if constexpr (!lessthan16bit) {\n      data += shifttosigned_4xint;\n    }\n  }\n\n  // 4x signed 16 bit coeffs to int32\n  Int32x4 coeff_int;\n  coeff_int.load_from_any_intptr(current_coeff);\n\n  result += data * coeff_int;\n  // later, the four 32 bit results will be added together (hadd)\n}\n\ntemplate<bool safe_aligned_mode, typename pixel_t, bool lessthan16bit>\nAVS_FORCEINLINE static void process_two_pixels_h_uint8_16(const pixel_t* AVS_RESTRICT src_ptr, const int begin1, const int begin2, const short* AVS_RESTRICT current_coeff, const int filter_size,\n  Int32x4& _result1, Int32x4& _result2, const int kernel_size,\n  const Int16x8& shifttosigned)\n{\n  // Reference parameters (_result1, _result2) have known addresses, so MSVC\n  // treats them as aliased memory and emits scalar extract+writeback on every\n  // loop iteration (movd/vpextrd to memory after each vpaddd).\n  // By copying to local variables, MSVC gains full ownership and keeps the\n  // accumulators in XMM registers for the entire loop, writing back only once\n  // at the end. This alone gave a ~25% speedup (106 -> 183 fps on MSVC).\n  // this problem with Clang/GCC was not observed.\n  Int32x4 result1 = _result1;\n  Int32x4 result2 = _result2;\n\n  int ksmod8;\n  // 16 is too much for C optimizer\n  if constexpr (safe_aligned_mode)\n    ksmod8 = filter_size / 8 * 8;\n  else\n    ksmod8 = kernel_size / 8 * 8; // danger zone, scanline overread possible. Use exact unaligned kernel_size\n  const pixel_t* src_ptr1 = src_ptr + begin1;\n  const pixel_t* src_ptr2 = src_ptr + begin2;\n  int i = 0;\n\n  // Process 16 elements at a time\n  for (; i < ksmod8; i += 8) {\n    process_two_8pixels_h_uint8_16_core<pixel_t, lessthan16bit>(src_ptr1 + i, current_coeff + i, result1, shifttosigned);\n    process_two_8pixels_h_uint8_16_core<pixel_t, lessthan16bit>(src_ptr2 + i, current_coeff + filter_size + i , result2, shifttosigned);\n  }\n\n  if constexpr (!safe_aligned_mode) {\n    // working with the original, unaligned kernel_size\n    if (i == kernel_size) {\n      _result1 = result1;\n      _result2 = result2;\n      return;\n    }\n\n    const int ksmod4 = kernel_size / 4 * 4;\n    // Process 4 elements if needed\n    if (i < ksmod4) {\n      Int32x4 shifttosigned_4;\n      shifttosigned_4.convert_from_lo(shifttosigned); // copy lower half of 8xshort, 4xshort to 4xint\n      process_two_4pixels_h_uint8_16_core<pixel_t, lessthan16bit>(src_ptr1 + i, current_coeff + i, result1, shifttosigned_4);\n      process_two_4pixels_h_uint8_16_core<pixel_t, lessthan16bit>(src_ptr2 + i, current_coeff + filter_size + i, result2, shifttosigned_4);\n      i += 4;\n      if (i == kernel_size) {\n        _result1 = result1;\n        _result2 = result2;\n        return;\n    }\n    }\n\n    // Process remaining 1-3 elements with scalar operations\n    if (i < kernel_size) {\n      Int32x4 scalar_sum1(0); // like an __m128i\n      Int32x4 scalar_sum2(0);\n\n      int index = 0;\n      for (; i < kernel_size; i++, index++) {\n\n        if constexpr (sizeof(pixel_t) == 1) {\n          scalar_sum1.set(index, scalar_sum1[index] + src_ptr1[i] * current_coeff[i]);\n          scalar_sum2.set(index, scalar_sum2[index] + src_ptr2[i] * current_coeff[filter_size + i]);\n        }\n        else {\n          // pixel_t is uint16_t\n          short val = src_ptr1[i];\n          if constexpr (!lessthan16bit)\n            val = val + shifttosigned[0]; // still short\n          scalar_sum1.set(index, scalar_sum1[index] + val * current_coeff[i]);\n\n          val = src_ptr2[i];\n          if constexpr (!lessthan16bit)\n            val = val + shifttosigned[0]; // still short\n          scalar_sum2.set(index, scalar_sum2[index] + val * current_coeff[filter_size + i]);\n        }\n      }\n\n      // update result vectors\n      result1 += scalar_sum1;\n      result2 += scalar_sum2;\n\n    }\n  }\n\n  _result1 = result1;\n  _result2 = result2;\n}\n\n\n// NO Forceinline! Helps MSVC, by starting a new stack trame and have enough registers again.\ntemplate<bool is_safe, typename pixel_t, bool lessthan16bit>\nstatic void process_eight_pixels_h_uint8_16(const pixel_t * AVS_RESTRICT src, int x, const short* current_coeff_base, int filter_size,\n  const Int32x4& rounder128, const Int16x8& shifttosigned, const uint16_t clamp_limit,\n  pixel_t* AVS_RESTRICT dst,\n  ResamplingProgram* program)\n{\n  assert(program->filter_size_alignment >= 16); // code assumes this\n\n  const short* AVS_RESTRICT current_coeff = current_coeff_base + x * filter_size;\n  const int unaligned_kernel_size = program->filter_size_real;\n\n  // Unrolled processing of all 8 pixels\n\n  // 0 & 1\n  Int32x4 result0 = rounder128;\n  Int32x4 result1 = rounder128;\n  int begin0 = program->pixel_offset[x + 0];\n  int begin1 = program->pixel_offset[x + 1];\n  process_two_pixels_h_uint8_16<is_safe, pixel_t, lessthan16bit>(src, begin0, begin1, current_coeff, filter_size, result0, result1, unaligned_kernel_size, shifttosigned);\n  current_coeff += 2 * filter_size;\n\n  // 2 & 3\n  Int32x4 result2 = rounder128;\n  Int32x4 result3 = rounder128;\n  begin0 = program->pixel_offset[x + 2];\n  begin1 = program->pixel_offset[x + 3];\n  process_two_pixels_h_uint8_16<is_safe, pixel_t, lessthan16bit>(src, begin0, begin1, current_coeff, filter_size, result2, result3, unaligned_kernel_size, shifttosigned);\n  current_coeff += 2 * filter_size;\n\n  Int32x4 sumQuad1234;\n  sumQuad1234 = make_from_horiz_sums(result0, result1, result2, result3);\n  /* provided and optimized from simd_c.h\n  sumQuad1234.set(0, result1.horiz_add_int32());\n  sumQuad1234.set(1, result1.horiz_add_int32());\n  sumQuad1234.set(2, result2.horiz_add_int32());\n  sumQuad1234.set(3, result3.horiz_add_int32());\n  */\n\n  // 4 & 5\n  result0 = rounder128;\n  result1 = rounder128;\n  begin0 = program->pixel_offset[x + 4];\n  begin1 = program->pixel_offset[x + 5];\n  process_two_pixels_h_uint8_16<is_safe, pixel_t, lessthan16bit>(src, begin0, begin1, current_coeff, filter_size, result0, result1, unaligned_kernel_size, shifttosigned);\n  current_coeff += 2 * filter_size;\n\n  // 6 & 7\n  result2 = rounder128;\n  result3 = rounder128;\n  begin0 = program->pixel_offset[x + 6];\n  begin1 = program->pixel_offset[x + 7];\n  process_two_pixels_h_uint8_16<is_safe, pixel_t, lessthan16bit>(src, begin0, begin1, current_coeff, filter_size, result2, result3, unaligned_kernel_size, shifttosigned);\n  // current_coeff += 2 * filter_size; // not needed anymore\n\n  Int32x4 sumQuad5678;\n  sumQuad5678 = make_from_horiz_sums(result0, result1, result2, result3);\n\n  // correct if signed, scale back, store\n  if constexpr (sizeof(pixel_t) == 2 && !lessthan16bit) {\n    const Int32x4 shiftfromsigned(32768 << FPScale16bits);\n    sumQuad1234 += shiftfromsigned;\n    sumQuad5678 += shiftfromsigned;\n  }\n\n  const int current_fp_scale_bits = (sizeof(pixel_t) == 1) ? FPScale8bits : FPScale16bits;\n  // scale back, store\n  sumQuad1234 >>= current_fp_scale_bits;\n  sumQuad5678 >>= current_fp_scale_bits;\n \n  if constexpr (sizeof(pixel_t) == 1) {\n    Uint8x8 result_2x4x_uint8;\n    convert_and_saturate_int32x4x2_to_uint8x8(sumQuad1234, sumQuad5678, result_2x4x_uint8);\n    result_2x4x_uint8.store(&dst[x]);\n  }\n  else {\n    // uint16_t 10-16 bit\n    Uint16x8 result_2x4x_uint16_128;\n    if constexpr (lessthan16bit) {\n      convert_and_saturate_int32x4x2_to_uint16x8_limit(sumQuad1234, sumQuad5678, result_2x4x_uint16_128, clamp_limit);\n    }\n    else {\n      convert_and_saturate_int32x4x2_to_uint16x8(sumQuad1234, sumQuad5678, result_2x4x_uint16_128);\n    }\n    result_2x4x_uint16_128.store(&dst[x]);\n  \n  }\n}\n\n//-------- uint8/16_t Horizontal\n// 4 pixels at a time. \ntemplate<typename pixel_t, bool lessthan16bit>\nvoid resizer_h_c_generic_uint8_16_vectorized(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel) {\n\n  const int filter_size = program->filter_size;\n  const int current_fp_scale_bits = (sizeof(pixel_t) == 1) ? FPScale8bits : FPScale16bits;\n  const Int32x4 rounder128 = { 1 << (current_fp_scale_bits - 1), 0, 0, 0 };\n\n  const Int16x8 shifttosigned_or_zero128(sizeof(pixel_t) == 1 ? 0 : -32768);\n\n  const uint16_t clamp_limit = (1 << bits_per_pixel) - 1;\n\n  const pixel_t* AVS_RESTRICT src = reinterpret_cast<const pixel_t*>(src8);\n  pixel_t* AVS_RESTRICT dst = reinterpret_cast<pixel_t*>(dst8);\n  dst_pitch /= sizeof(pixel_t);\n  src_pitch /= sizeof(pixel_t);\n\n  const int w_safe_mod8 = (program->safelimit_filter_size_aligned.overread_possible ? program->safelimit_filter_size_aligned.source_overread_beyond_targetx : width) / 8 * 8;\n\n  for (int y = 0; y < height; y++) {\n    const short* current_coeff_base = program->pixel_coefficient;\n\n    // Process safe aligned pixels\n    for (int x = 0; x < w_safe_mod8; x += 8) {\n      process_eight_pixels_h_uint8_16<true, pixel_t, lessthan16bit>(src, x, current_coeff_base, filter_size, rounder128, shifttosigned_or_zero128, clamp_limit, dst, program);\n    }\n\n    // Process up to the actual kernel size instead of the aligned filter_size to prevent overreading beyond the last source pixel.\n    // We assume extra offset entries were added to the p->pixel_offset array (aligned to 8 during initialization).\n    // This may store 1-7 false pixels but it still remain in alignment-safe area.\n    for (int x = w_safe_mod8; x < width; x += 8) {\n      process_eight_pixels_h_uint8_16<false, pixel_t, lessthan16bit>(src, x, current_coeff_base, filter_size, rounder128, shifttosigned_or_zero128, clamp_limit, dst, program);\n    }\n\n    dst += dst_pitch;\n    src += src_pitch;\n  }\n}\n\n// 16 bit Horizontal\n\ntemplate void resizer_h_c_generic_uint8_16_vectorized<uint8_t, true>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resizer_h_c_generic_uint8_16_vectorized<uint16_t, false>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\ntemplate void resizer_h_c_generic_uint8_16_vectorized<uint16_t, true>(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel);\n\n/********************************************************************\n***** Declare index of new filters for Avisynth's filter engine *****\n********************************************************************/\n\nextern const AVSFunction Resample_filters[] = {\n  { \"PointResize\",    BUILTIN_FUNC_PREFIX, \"cii[src_left]f[src_top]f[src_width]f[src_height]f[force]i[keep_center]b[placement]s\", FilteredResize::Create_PointResize },\n  { \"BilinearResize\", BUILTIN_FUNC_PREFIX, \"cii[src_left]f[src_top]f[src_width]f[src_height]f[force]i[keep_center]b[placement]s\", FilteredResize::Create_BilinearResize },\n  { \"BicubicResize\",  BUILTIN_FUNC_PREFIX, \"cii[b]f[c]f[src_left]f[src_top]f[src_width]f[src_height]f[force]i[keep_center]b[placement]s\", FilteredResize::Create_BicubicResize },\n  { \"LanczosResize\",  BUILTIN_FUNC_PREFIX, \"cii[src_left]f[src_top]f[src_width]f[src_height]f[taps]i[force]i[keep_center]b[placement]s\", FilteredResize::Create_LanczosResize},\n  { \"Lanczos4Resize\", BUILTIN_FUNC_PREFIX, \"cii[src_left]f[src_top]f[src_width]f[src_height]f[force]i[keep_center]b[placement]s\", FilteredResize::Create_Lanczos4Resize},\n  { \"BlackmanResize\", BUILTIN_FUNC_PREFIX, \"cii[src_left]f[src_top]f[src_width]f[src_height]f[taps]i[force]i[keep_center]b[placement]s\", FilteredResize::Create_BlackmanResize},\n  { \"Spline16Resize\", BUILTIN_FUNC_PREFIX, \"cii[src_left]f[src_top]f[src_width]f[src_height]f[force]i[keep_center]b[placement]s\", FilteredResize::Create_Spline16Resize},\n  { \"Spline36Resize\", BUILTIN_FUNC_PREFIX, \"cii[src_left]f[src_top]f[src_width]f[src_height]f[force]i[keep_center]b[placement]s\", FilteredResize::Create_Spline36Resize},\n  { \"Spline64Resize\", BUILTIN_FUNC_PREFIX, \"cii[src_left]f[src_top]f[src_width]f[src_height]f[force]i[keep_center]b[placement]s\", FilteredResize::Create_Spline64Resize},\n  { \"GaussResize\",    BUILTIN_FUNC_PREFIX, \"cii[src_left]f[src_top]f[src_width]f[src_height]f[p]f[b]f[s]f[force]i[keep_center]b[placement]s\", FilteredResize::Create_GaussianResize},\n  { \"SincResize\",     BUILTIN_FUNC_PREFIX, \"cii[src_left]f[src_top]f[src_width]f[src_height]f[taps]i[force]i[keep_center]b[placement]s\", FilteredResize::Create_SincResize},\n  { \"SinPowerResize\", BUILTIN_FUNC_PREFIX, \"cii[src_left]f[src_top]f[src_width]f[src_height]f[p]f[force]i[keep_center]b[placement]s\", FilteredResize::Create_SinPowerResize},\n  { \"SincLin2Resize\", BUILTIN_FUNC_PREFIX, \"cii[src_left]f[src_top]f[src_width]f[src_height]f[taps]i[force]i[keep_center]b[placement]s\", FilteredResize::Create_SincLin2Resize},\n  { \"UserDefined2Resize\", BUILTIN_FUNC_PREFIX, \"cii[b]f[c]f[s]f[src_left]f[src_top]f[src_width]f[src_height]f[force]i[keep_center]b[placement]s\", FilteredResize::Create_UserDefined2Resize},\n  /**\n    * Resize(PClip clip, dst_width, dst_height [src_left, src_top, src_width, int src_height,] )\n    *\n    * src_left et al.   =  when these optional arguments are given, the filter acts just like\n    *                      a Crop was performed with those parameters before resizing, only faster\n   **/\n\n  { 0 }\n};\n\n// Borrowed from fmtconv\n// ChromaPlacement.cpp\n// Author : Laurent de Soras, 2015\n\n// Fixes the vertical chroma placement when the picture is interlaced.\n// ofs = ordinate to skip between TFF and BFF, relative to the chroma grid. A\n// single line of full-res picture is 0.25.\nstatic inline void ChromaPlacement_fix_itl(double& cp_v, bool interlaced_flag, bool top_flag, double ofs = 0.5)\n{\n  assert(cp_v >= 0);\n\n  if (interlaced_flag)\n  {\n    cp_v *= 0.5;\n    if (!top_flag)\n    {\n      cp_v += ofs;\n    }\n  }\n}\n/*\nss_h and ss_v are log2(subsampling)\nrgb_flag actually means that chroma subsampling doesn't apply.\n\nhttp://www.mir.com/DMG/chroma.html\n\ncp_* is the position of the sampling point relative to the frame\ntop/left border, in the plane coordinates. For reference, the border\nof the frame is at 0.5 units of luma from the first luma sampling point.\nI. e., the luma sampling point is at the pixel's center.\n*/\n\n// PF added BOTTOM, BOTTOM_LEFT, TOP\n// Pass ChromaLocation_e::AVS_CHROMA_UNUSED for defaults\n// plane index 0:Y, 1:U, 2:V\n// cplace is a ChromaLocation_e constant\nstatic void ChromaPlacement_compute_cplace(double& cp_h, double& cp_v, int cplace, int plane_index, int ss_h, int ss_v, bool rgb_flag, bool interlaced_flag, bool top_flag)\n{\n  assert(cplace >= 0 || cplace == ChromaLocation_e::AVS_CHROMA_UNUSED);\n  assert(cplace < ChromaLocation_e::AVS_CHROMA_DV);\n  assert(ss_h >= 0);\n  assert(ss_v >= 0);\n  assert(plane_index >= 0);\n\n  // Generic case for luma, non-subsampled chroma and center (MPEG-1) chroma.\n  cp_h = 0.5;\n  cp_v = 0.5;\n  ChromaPlacement_fix_itl(cp_v, interlaced_flag, top_flag);\n\n  // Subsampled chroma\n  if (!rgb_flag && plane_index > 0)\n  {\n    if (ss_h > 0) // horizontal subsampling 420 411\n    {\n      if (cplace == ChromaLocation_e::AVS_CHROMA_LEFT // mpeg2\n        || cplace == ChromaLocation_e::AVS_CHROMA_DV\n        || cplace == ChromaLocation_e::AVS_CHROMA_TOP_LEFT\n        || cplace == ChromaLocation_e::AVS_CHROMA_BOTTOM_LEFT\n        )\n      {\n        cp_h = 0.5 / (1 << ss_h);\n      }\n    }\n\n    if (ss_v == 1) // vertical subsampling 420, 422\n    {\n      if (cplace == ChromaLocation_e::AVS_CHROMA_LEFT)\n      {\n        cp_v = 0.5;\n        ChromaPlacement_fix_itl(cp_v, interlaced_flag, top_flag);\n      }\n      else if (cplace == ChromaLocation_e::AVS_CHROMA_DV\n        || cplace == ChromaLocation_e::AVS_CHROMA_TOP_LEFT\n        || cplace == ChromaLocation_e::AVS_CHROMA_TOP\n        )\n      {\n        cp_v = 0.25;\n        ChromaPlacement_fix_itl(cp_v, interlaced_flag, top_flag, 0.25);\n\n        if (cplace == ChromaLocation_e::AVS_CHROMA_DV && plane_index == 2) // V\n        {\n          cp_v += 0.5;\n        }\n      }\n      else if (cplace == ChromaLocation_e::AVS_CHROMA_BOTTOM_LEFT\n        || cplace == ChromaLocation_e::AVS_CHROMA_BOTTOM\n        )\n      {\n        cp_v = 0.75;\n        ChromaPlacement_fix_itl(cp_v, interlaced_flag, top_flag, 0.25);\n      }\n    }  // ss_v == 1\n  }\n}\n\n\n// returns the requested horizontal or vertical pixel center position\nstatic void GetCenterShiftForResizers(double& center_pos_luma, double& center_pos_chroma, bool preserve_center, int chroma_placement, VideoInfo &vi, bool for_horizontal) {\n  double center_pos_h_luma = 0.0;\n  double center_pos_v_luma = 0.0;\n  // if not needed, these won't be used\n  double center_pos_h_chroma = 0.0;\n  double center_pos_v_chroma = 0.0;\n\n  // chroma, only if applicable\n  if (vi.IsPlanar() && vi.NumComponents() > 1 && !vi.IsRGB()) {\n    double cp_s_h = 0;\n    double cp_s_v = 0;\n\n    if (preserve_center) {\n      // same for source and destination\n      int plane_index = 1; // U\n      int src_ss_h = vi.GetPlaneWidthSubsampling(PLANAR_U);\n      int src_ss_v = vi.GetPlaneHeightSubsampling(PLANAR_U);\n\n      // int chromaplace = ChromaLocation_e::AVS_CHROMA_CENTER; // MPEG1\n\n      ChromaPlacement_compute_cplace(\n        cp_s_h, cp_s_v, chroma_placement, plane_index, src_ss_h, src_ss_v,\n        vi.IsRGB(),\n        false, // interlacing flag, we don't handle it here\n        false  // top_flag, we don't handle it here\n      );\n    }\n\n    center_pos_h_chroma = cp_s_h;\n    center_pos_v_chroma = cp_s_v;\n  }\n\n  // luma/rgb planes\n  if (preserve_center) {\n    center_pos_h_luma = 0.5;\n    center_pos_v_luma = 0.5;\n  }\n  else {\n    center_pos_h_luma = 0.0;\n    center_pos_v_luma = 0.0;\n  }\n\n  // fill return ref values\n  if (for_horizontal) {\n    center_pos_luma = center_pos_h_luma;\n    center_pos_chroma = center_pos_h_chroma;\n  }\n  else {\n    // vertical\n    center_pos_luma = center_pos_v_luma;\n    center_pos_chroma = center_pos_v_chroma;\n  }\n\n}\n\nFilteredResizeH::FilteredResizeH(PClip _child, double subrange_left, double subrange_width,\n  int target_width, ResamplingFunction* func, bool preserve_center, int chroma_placement, IScriptEnvironment* env)\n  : GenericVideoFilter(_child),\n  resampling_program_luma(nullptr), resampling_program_chroma(nullptr), \n  resampler_h_luma(nullptr), resampler_h_chroma(nullptr),\n  resampler_h_luma_mt(nullptr), resampler_h_chroma_mt(nullptr),\n  resampler_luma(nullptr), resampler_chroma(nullptr),\n  num_threads(0)\n\n{\n  src_width = vi.width;\n  src_height = vi.height;\n  dst_width = target_width;\n  dst_height = vi.height;\n\n  pixelsize = vi.ComponentSize(); // AVS16\n  bits_per_pixel = vi.BitsPerComponent();\n  grey = vi.IsY();\n\n  bool isRGBPfamily = vi.IsPlanarRGB() || vi.IsPlanarRGBA();\n\n  if (target_width <= 0) {\n    env->ThrowError(\"Resize: Width must be greater than 0.\");\n  }\n\n  if (vi.IsPlanar() && !grey && !isRGBPfamily) {\n    const int mask = (1 << vi.GetPlaneWidthSubsampling(PLANAR_U)) - 1;\n\n    if (target_width & mask)\n      env->ThrowError(\"Resize: Planar destination height must be a multiple of %d.\", mask + 1);\n  }\n\n  double center_pos_h_luma;\n  double center_pos_h_chroma;\n  GetCenterShiftForResizers(center_pos_h_luma, center_pos_h_chroma, preserve_center, chroma_placement, vi, true /* for horizontal */);\n  // 3.7.4- parameter, old Avisynth behavior: 0.5, 0.5\n\n  // Main resampling program\n  resampling_program_luma = func->GetResamplingProgram(vi.width, subrange_left, subrange_width, target_width, bits_per_pixel, \n    center_pos_h_luma, center_pos_h_luma, // for resizing it's the same for source and dest\n    env);\n  if (vi.IsPlanar() && !grey && !isRGBPfamily) {\n    const int shift = vi.GetPlaneWidthSubsampling(PLANAR_U);\n    const int div = 1 << shift;\n\n\n    resampling_program_chroma = func->GetResamplingProgram(\n      vi.width >> shift,\n      subrange_left / div,\n      subrange_width / div,\n      target_width >> shift,\n      bits_per_pixel,\n      center_pos_h_chroma, center_pos_h_chroma, // horizontal\n      env);\n  }\n\n// when not fast_resize, then we use vertical resizers between turnleft/turnright\n#ifdef INTEL_INTRINSICS\n  int cpu = env->GetCPUFlags();\n  bool has_sse2 = (cpu & CPUF_SSE2) != 0;\n  bool has_avx2 = (cpu & CPUF_AVX2) != 0;\n#elif defined(NEON_INTRINSICS)\n  int cpu = env->GetCPUFlags();\n  bool has_neon = (cpu & CPUF_ARM_NEON) != 0;\n#else\n  int cpu = 0;\n#endif\n\n  fast_resize = vi.IsPlanar();\n  // PF 2025: H is not slower than V in C implementation.\n  // Still, H resizers are incompatible with packed RGB formats\n\n    if (!fast_resize) {\n\n      // nonfast-resize: using V resizer for horizontal resizing between a turnleft/right\n      // For packed RGB formats this is the only way\n\n      resampler_luma = FilteredResizeV::GetResampler(cpu, pixelsize, bits_per_pixel, resampling_program_luma, env);\n\n      if (vi.IsPlanar() && !grey && !isRGBPfamily) {\n        resampler_chroma = FilteredResizeV::GetResampler(cpu, pixelsize, bits_per_pixel, resampling_program_chroma, env);\n      }\n\n      // Temporary buffer size for turns\n      temp_1_pitch = AlignNumber(vi.BytesFromPixels(src_height), FRAME_ALIGN);\n      temp_2_pitch = AlignNumber(vi.BytesFromPixels(dst_height), FRAME_ALIGN);\n\n      // Initialize Turn function\n      // see turn.cpp\n      if (vi.IsRGB24()) {\n#ifdef INTEL_INTRINSICS\n        // no intel intentionally\n#endif\n        turn_left = turn_left_rgb24;\n        turn_right = turn_right_rgb24;\n      }\n      else if (vi.IsRGB32()) {\n#ifdef INTEL_INTRINSICS\n      if (has_avx2) {\n        turn_left = turn_left_rgb32_avx2;\n        turn_right = turn_right_rgb32_avx2;\n      }\n      else if (has_sse2) {\n          turn_left = turn_left_rgb32_sse2;\n          turn_right = turn_right_rgb32_sse2;\n        }\n        else\n#elif NEON_INTRINSICS\n        if (has_neon) {\n          turn_left = turn_left_rgb32_neon;\n          turn_right = turn_right_rgb32_neon;\n        }\n        else\n#endif\n        {\n          turn_left = turn_left_rgb32_c;\n          turn_right = turn_right_rgb32_c;\n        }\n      }\n      else if (vi.IsRGB48()) {\n#ifdef INTEL_INTRINSICS\n        // no intel intentionally\n#endif\n        turn_left = turn_left_rgb48_c;\n        turn_right = turn_right_rgb48_c;\n      }\n      else if (vi.IsRGB64()) {\n#ifdef INTEL_INTRINSICS\n      if (has_avx2) {\n        turn_left = turn_left_rgb64_avx2;\n        turn_right = turn_right_rgb64_avx2;\n      }\n      else if (has_sse2) {\n          turn_left = turn_left_rgb64_sse2;\n          turn_right = turn_right_rgb64_sse2;\n        }\n        else\n#elif defined(NEON_INTRINSICS)\n        if (has_neon) {\n          turn_left = turn_left_rgb64_neon;\n          turn_right = turn_right_rgb64_neon;\n        }\n        else\n#endif\n        {\n          turn_left = turn_left_rgb64_c;\n          turn_right = turn_right_rgb64_c;\n        }\n      }\n      else {\n        switch (vi.ComponentSize()) {// AVS16\n        case 1: // 8 bit\n#ifdef INTEL_INTRINSICS\n        if (has_avx2) {\n          turn_left = turn_left_plane_8_avx2;\n          turn_right = turn_right_plane_8_avx2;\n        }\n        else if (has_sse2) {\n            turn_left = turn_left_plane_8_sse2;\n            turn_right = turn_right_plane_8_sse2;\n          }\n          else\n#elif defined(NEON_INTRINSICS)\n          if (has_neon) {\n            turn_left = turn_left_plane_8_neon;\n            turn_right = turn_right_plane_8_neon;\n          }\n          else\n#endif\n          {\n            turn_left = turn_left_plane_8_c;\n            turn_right = turn_right_plane_8_c;\n          }\n          break;\n        case 2: // 16 bit\n#ifdef INTEL_INTRINSICS\n        if (has_avx2) {\n          turn_left = turn_left_plane_16_avx2;\n          turn_right = turn_right_plane_16_avx2;\n        }\n        else if (has_sse2) {\n            turn_left = turn_left_plane_16_sse2;\n            turn_right = turn_right_plane_16_sse2;\n          }\n          else\n#elif defined(NEON_INTRINSICS)\n          if (has_neon) {\n            turn_left = turn_left_plane_16_neon;\n            turn_right = turn_right_plane_16_neon;\n          }\n          else\n#endif\n          {\n            turn_left = turn_left_plane_16_c;\n            turn_right = turn_right_plane_16_c;\n          }\n          break;\n        default: // 32 bit\n#ifdef INTEL_INTRINSICS\n        if (has_avx2) {\n          turn_left = turn_left_plane_32_avx2;\n          turn_right = turn_right_plane_32_avx2;\n        }\n        else if (has_sse2) {\n            turn_left = turn_left_plane_32_sse2;\n            turn_right = turn_right_plane_32_sse2;\n          }\n          else\n#endif\n          {\n            turn_left = turn_left_plane_32_c;\n            turn_right = turn_right_plane_32_c;\n          }\n        }\n      }\n    }\n    else {\n      // planar format (or Y)\n      resampler_h_luma = GetResampler(cpu, pixelsize, bits_per_pixel, resampling_program_luma, /*out*/resampler_h_luma_mt, env);\n\n      if (!grey && !isRGBPfamily) {\n        resampler_h_chroma = GetResampler(cpu, pixelsize, bits_per_pixel, resampling_program_chroma, /*out*/resampler_h_chroma_mt, env);\n      }\n    }\n  // Change target video info size\n  vi.width = target_width;\n}\n\nPVideoFrame __stdcall FilteredResizeH::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame src = child->GetFrame(n, env);\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n\n  bool isRGBPfamily = vi.IsPlanarRGB() || vi.IsPlanarRGBA();\n\n  if (!fast_resize) {\n    // e.g. not aligned, not mod4\n    // temp_1_pitch and temp_2_pitch is pixelsize-aware\n    BYTE* temp_1 = static_cast<BYTE*>(env->Allocate(temp_1_pitch * src_width, FRAME_ALIGN, AVS_POOLED_ALLOC));\n    BYTE* temp_2 = static_cast<BYTE*>(env->Allocate(temp_2_pitch * dst_width, FRAME_ALIGN, AVS_POOLED_ALLOC));\n    if (!temp_1 || !temp_2) {\n      env->Free(temp_1);\n      env->Free(temp_2);\n      env->ThrowError(\"Could not reserve memory in a resampler.\");\n    }\n\n    if (!vi.IsRGB() || isRGBPfamily) {\n      // Y/G Plane\n      turn_right(src->GetReadPtr(), temp_1, src_width * pixelsize, src_height, src->GetPitch(), temp_1_pitch); // * pixelsize: turn_right needs GetPlaneWidth full size\n      resampler_luma(temp_2, temp_1, temp_2_pitch, temp_1_pitch, resampling_program_luma, src_height, dst_width, bits_per_pixel);\n      turn_left(temp_2, dst->GetWritePtr(), dst_height * pixelsize, dst_width, temp_2_pitch, dst->GetPitch());\n\n      if (isRGBPfamily)\n      {\n        turn_right(src->GetReadPtr(PLANAR_B), temp_1, src_width * pixelsize, src_height, src->GetPitch(PLANAR_B), temp_1_pitch); // * pixelsize: turn_right needs GetPlaneWidth full size\n        resampler_luma(temp_2, temp_1, temp_2_pitch, temp_1_pitch, resampling_program_luma, src_height, dst_width, bits_per_pixel);\n        turn_left(temp_2, dst->GetWritePtr(PLANAR_B), dst_height * pixelsize, dst_width, temp_2_pitch, dst->GetPitch(PLANAR_B));\n\n        turn_right(src->GetReadPtr(PLANAR_R), temp_1, src_width * pixelsize, src_height, src->GetPitch(PLANAR_R), temp_1_pitch); // * pixelsize: turn_right needs GetPlaneWidth full size\n        resampler_luma(temp_2, temp_1, temp_2_pitch, temp_1_pitch, resampling_program_luma, src_height, dst_width, bits_per_pixel);\n        turn_left(temp_2, dst->GetWritePtr(PLANAR_R), dst_height * pixelsize, dst_width, temp_2_pitch, dst->GetPitch(PLANAR_R));\n      }\n      else if (!grey) {\n        const int shift = vi.GetPlaneWidthSubsampling(PLANAR_U);\n        const int shift_h = vi.GetPlaneHeightSubsampling(PLANAR_U);\n\n        const int src_chroma_width = src_width >> shift;\n        const int dst_chroma_width = dst_width >> shift;\n        const int src_chroma_height = src_height >> shift_h;\n        const int dst_chroma_height = dst_height >> shift_h;\n\n        // turn_xxx: width * pixelsize: needs GetPlaneWidth-like full size\n        // U Plane\n        turn_right(src->GetReadPtr(PLANAR_U), temp_1, src_chroma_width * pixelsize, src_chroma_height, src->GetPitch(PLANAR_U), temp_1_pitch);\n        resampler_luma(temp_2, temp_1, temp_2_pitch, temp_1_pitch, resampling_program_chroma, src_chroma_height, dst_chroma_width, bits_per_pixel);\n        turn_left(temp_2, dst->GetWritePtr(PLANAR_U), dst_chroma_height * pixelsize, dst_chroma_width, temp_2_pitch, dst->GetPitch(PLANAR_U));\n\n        // V Plane\n        turn_right(src->GetReadPtr(PLANAR_V), temp_1, src_chroma_width * pixelsize, src_chroma_height, src->GetPitch(PLANAR_V), temp_1_pitch);\n        resampler_luma(temp_2, temp_1, temp_2_pitch, temp_1_pitch, resampling_program_chroma, src_chroma_height, dst_chroma_width, bits_per_pixel);\n        turn_left(temp_2, dst->GetWritePtr(PLANAR_V), dst_chroma_height * pixelsize, dst_chroma_width, temp_2_pitch, dst->GetPitch(PLANAR_V));\n      }\n      if (vi.IsYUVA() || vi.IsPlanarRGBA())\n      {\n        turn_right(src->GetReadPtr(PLANAR_A), temp_1, src_width * pixelsize, src_height, src->GetPitch(PLANAR_A), temp_1_pitch); // * pixelsize: turn_right needs GetPlaneWidth full size\n        resampler_luma(temp_2, temp_1, temp_2_pitch, temp_1_pitch, resampling_program_luma, src_height, dst_width, bits_per_pixel);\n        turn_left(temp_2, dst->GetWritePtr(PLANAR_A), dst_height * pixelsize, dst_width, temp_2_pitch, dst->GetPitch(PLANAR_A));\n      }\n\n    }\n    else {\n      // packed RGB\n      // First left, then right. Reason: packed RGB bottom to top. Right+left shifts RGB24/RGB32 image to the opposite horizontal direction\n      turn_left(src->GetReadPtr(), temp_1, vi.BytesFromPixels(src_width), src_height, src->GetPitch(), temp_1_pitch);\n      resampler_luma(temp_2, temp_1, temp_2_pitch, temp_1_pitch, resampling_program_luma, vi.BytesFromPixels(src_height) / pixelsize, dst_width, bits_per_pixel);\n      turn_right(temp_2, dst->GetWritePtr(), vi.BytesFromPixels(dst_height), dst_width, temp_2_pitch, dst->GetPitch());\n    }\n\n    env->Free(temp_1);\n    env->Free(temp_2);\n  }\n  else {\n    // depending on MT or not, select proper resizer if alternative is available\n    ResamplerH current_resampler_h_luma = (num_threads > 1 && resampler_h_luma_mt != nullptr) ? resampler_h_luma_mt : resampler_h_luma;\n    ResamplerH current_resampler_h_chroma = (num_threads > 1 && resampler_h_chroma_mt != nullptr) ? resampler_h_chroma_mt : resampler_h_chroma;\n\n    // Y Plane\n    current_resampler_h_luma(dst->GetWritePtr(), src->GetReadPtr(), dst->GetPitch(), src->GetPitch(), resampling_program_luma, dst_width, dst_height, bits_per_pixel);\n\n    if (isRGBPfamily) {\n      current_resampler_h_luma(dst->GetWritePtr(PLANAR_B), src->GetReadPtr(PLANAR_B), dst->GetPitch(PLANAR_B), src->GetPitch(PLANAR_B), resampling_program_luma, dst_width, dst_height, bits_per_pixel);\n      current_resampler_h_luma(dst->GetWritePtr(PLANAR_R), src->GetReadPtr(PLANAR_R), dst->GetPitch(PLANAR_R), src->GetPitch(PLANAR_R), resampling_program_luma, dst_width, dst_height, bits_per_pixel);\n    }\n    else if (!grey) {\n      const int dst_chroma_width = dst_width >> vi.GetPlaneWidthSubsampling(PLANAR_U);\n      const int dst_chroma_height = dst_height >> vi.GetPlaneHeightSubsampling(PLANAR_U);\n\n      // U Plane\n      current_resampler_h_chroma(dst->GetWritePtr(PLANAR_U), src->GetReadPtr(PLANAR_U), dst->GetPitch(PLANAR_U), src->GetPitch(PLANAR_U), resampling_program_chroma, dst_chroma_width, dst_chroma_height, bits_per_pixel);\n\n      // V Plane\n      current_resampler_h_chroma(dst->GetWritePtr(PLANAR_V), src->GetReadPtr(PLANAR_V), dst->GetPitch(PLANAR_V), src->GetPitch(PLANAR_V), resampling_program_chroma, dst_chroma_width, dst_chroma_height, bits_per_pixel);\n    }\n    if (vi.IsYUVA() || vi.IsPlanarRGBA())\n    {\n      current_resampler_h_luma(dst->GetWritePtr(PLANAR_A), src->GetReadPtr(PLANAR_A), dst->GetPitch(PLANAR_A), src->GetPitch(PLANAR_A), resampling_program_luma, dst_width, dst_height, bits_per_pixel);\n    }\n\n  }\n\n  return dst;\n}\n\n//#define SPEEDTEST_MPZ 1\n//#define USE_MPZ_VNNI 1\n\nResamplerH FilteredResizeH::GetResampler(int CPU, int pixelsize, int bits_per_pixel, ResamplingProgram* program, ResamplerH &out_resampler_h_alternative_for_mt, IScriptEnvironment* env)\n{\n  out_resampler_h_alternative_for_mt = nullptr;\n  int simd_coeff_count_padding = 8; // even for _ks16_float this is enough, it works differently inside\n\n  // Both 8-bit and 16-bit SSSE3 and AVX2 horizontal resizers benefit from processing 16 pixels per cycle.\n  // Floats also use 32 bytes, but since 32/sizeof(float) = 8, processing 16 pixels is unnecessary.\n  // Even in C, the code is optimized to be vector-friendly.\n  if (pixelsize == 1 || pixelsize == 2)\n    simd_coeff_count_padding = 16;\n\n  // Not only does it prepare and pad for SIMD/vector code, but it also corrects, reorders, and equalizes coefficients \n  // at the right and bottom ends, since we may have variable kernel sizes due to boundary conditions.\n  resize_prepare_coeffs(program, env, simd_coeff_count_padding);\n\n#ifdef INTEL_INTRINSICS_AVX512\n  const bool has_AVX512_base = (CPU & CPUF_AVX512_BASE) == CPUF_AVX512_BASE; // group flag!\n  const bool has_AVX512_fast = (CPU & CPUF_AVX512_FAST) == CPUF_AVX512_FAST; // group flag!\n#endif\n\n  if (pixelsize == 1)\n  {\n#ifdef INTEL_INTRINSICS\n#ifdef INTEL_INTRINSICS_AVX512\n    if (has_AVX512_base) {\n#ifdef PF_GENERIC_UINT_TEST\n      return resizer_h_avx512_generic_uint8_t; // PF debug\n#endif\n      // feature flag, grouping many avx512 features\n      // in case of optimized avx512_permutex_vstripe resizer found, set alternative resizer for MT use\n        out_resampler_h_alternative_for_mt = resizer_h_avx2_generic_uint8_t; // AVX2 should present if AVX512 present\n      if (program->filter_size_real <= 4) {\n        if (!program->resize_h_planar_gather_permutex_vstripe_check(64/*iSamplesInTheGroup*/, 128/*permutex_index_diff_limit*/, 4/*kernel_size*/)) {\n          /*\n            (Rocket Lake i7 - 11700, Expr-vertical-stripes + BicubicResize(width*2,height))\n            Contenders\n            AVX512 Fast\n            resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_vnni  2760fps (VNNI is not even really used in clangcl)\n            resize_h_planar_uint8_avx512_permutex_vstripe_ks4_vbmi      2548fps\n            AVX512 base; No VNNI, No VBMI, both simulating the 8 bit VBMI shuffle\n            resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_base  1478fps (register pressure - twice as much _mm512_permutex2var_epi8 simulation than non-mpz)\n            resize_h_planar_uint8_avx512_permutex_vstripe_ks4_base      2493fps (despite the _mm512_permutex2var_epi8 simulation, this is only 2-3% slower than vbmi version\n            resizer_h_avx2_generic_uint8_t                               752fps\n\n            Winners: (Fast) resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_vnni (Base) resize_h_planar_uint8_avx512_permutex_vstripe_ks4_base\n          */\n#ifdef SPEEDTEST_MPZ\n#ifdef USE_MPZ_VNNI\n          if(has_AVX512_fast)\n            return resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_vnni; // Chosen for CPUF_AVX512_FAST\n          else\n            return resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_base; // Huge register pressure, -50% compared to resize_h_planar_uint8_avx512_permutex_vstripe_ks4_base\n#else\n          if(has_AVX512_fast)\n            return resize_h_planar_uint8_avx512_permutex_vstripe_ks4_vbmi;\n          else\n            return resize_h_planar_uint8_avx512_permutex_vstripe_ks4_base; // Chosen for CPUF_AVX512_BASE\n#endif\n#else\n          if (has_AVX512_fast)\n            return resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_vnni;\n          else\n            return resize_h_planar_uint8_avx512_permutex_vstripe_ks4_base;\n#endif\n      }\n      }\n      if (program->filter_size_real <= 8) {\n        /*\n          resize_h_planar_uint8_avx512_permutex_vstripe_2s32_ks8\n          - support more downsampling ratios, like\n            Bicubic/BilinearResize(width/2) and even SinPowResize(width/2) for downsampling of UHD 4k to FHD is working.\n          - Expected to support scaling ratios from about a bit below 0.5 to infinity (with filter support <=2).\n\n          resize_h_planar_uint8_avx512_permutex_vstripe_ks8\n          - faster with scale ratios from about 1.0 to infinity (with filter support <=4).\n\n          These two functions selected in order from faster to slower.\n        */\n        if (!program->resize_h_planar_gather_permutex_vstripe_check(64/*iSamplesInTheGroup*/, 128/*permutex_index_diff_limit*/, 8/*kernel_size*/)) { // first try faster ks8\n          /*\n          Contenders\n          AVX512 Fast\n          resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_vnni  3420fps\n          resize_h_planar_uint8_avx512_permutex_vstripe_ks8_vbmi      3240fps\n          AVX512 base\n          resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_base  1720fps (register pressure)\n          resize_h_planar_uint8_avx512_permutex_vstripe_ks8_base      2940fps\n\n          Winners: (Fast) resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_vnni (Base) resize_h_planar_uint8_avx512_permutex_vstripe_ks8_base\n          */\n#ifdef SPEEDTEST_MPZ\n#ifdef USE_MPZ_VNNI\n          if (has_AVX512_fast)\n            return resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_vnni;\n          else\n            return resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_base;\n#else\n          if (has_AVX512_fast)\n            return resize_h_planar_uint8_avx512_permutex_vstripe_ks8_vbmi;\n          else\n            return resize_h_planar_uint8_avx512_permutex_vstripe_ks8_base;\n#endif\n#else\n          if (has_AVX512_fast)\n            return resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_vnni;\n          else\n            return resize_h_planar_uint8_avx512_permutex_vstripe_ks8_base;\n\n#endif\n    }\n        if (!program->resize_h_planar_gather_permutex_vstripe_check(32/*iSamplesInTheGroup*/, 128/*permutex_index_diff_limit*/, 8/*kernel_size*/)) { // slower ks8 but more downsample ratio for /2\n          if (has_AVX512_fast)\n            return resize_h_planar_uint8_avx512_permutex_vstripe_2s32_ks8_vbmi;\n          else\n            return resize_h_planar_uint8_avx512_permutex_vstripe_2s32_ks8_base;\n        }\n      }\n      if (program->filter_size_real <= 16) {\n        // yes: LanczosResize(int(width*0.9 + 0.5), height, taps=4) kernel size 9 (K)\n        // yes: LanczosResize(int(width*1.1 + 0.5), height, taps=5) kernel size 10 (L)\n        // yes: LanczosResize(int(width*1.1 + 0.5), height, taps=6) kernel size 12 (M)\n        // yes: LanczosResize(int(width*0.5 + 0.5), height, taps=3) kernel size 12 (N) (in float only 2s8_ks16 covered this resampling ratio)\n        if (!program->resize_h_planar_gather_permutex_vstripe_check(32/*iSamplesInTheGroup*/, 128/*permutex_index_diff_limit*/, 16/*kernel_size*/)) {\n          /*\n          Contenders:\n          AVX512 fast\n          resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_vnni  3440fps\n          resize_h_planar_uint8_avx512_permutex_vstripe_ks16_vbmi      3037fps\n          AVX512 base\n          resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_base  1686fps (register pressure)\n          resize_h_planar_uint8_avx512_permutex_vstripe_ks16_base      2909fps\n\n          Winners: (Fast) resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_vnni (Base) resize_h_planar_uint8_avx512_permutex_vstripe_ks16_base\n          */\n#ifdef SPEEDTEST_MPZ\n#ifdef USE_MPZ_VNNI\n          if (has_AVX512_fast)\n            return resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_vnni;\n          else\n            return resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_base;\n#else\n          if (has_AVX512_fast)\n            return resize_h_planar_uint8_avx512_permutex_vstripe_ks16_vbmi;\n          else\n            return resize_h_planar_uint8_avx512_permutex_vstripe_ks16_base;\n#endif\n#else\n          if (has_AVX512_fast)\n            return resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_vnni;\n          else\n            return resize_h_planar_uint8_avx512_permutex_vstripe_ks16_base;\n#endif\n      }\n      }\n      out_resampler_h_alternative_for_mt = nullptr; // not needed\n    }\n#endif\n    if (CPU & CPUF_AVX2) {\n      return resizer_h_avx2_generic_uint8_t;\n    }\n    if (CPU & CPUF_SSSE3) {\n      return resizer_h_ssse3_generic_uint8_16<uint8_t, true>;\n    }\n#endif\n    return resizer_h_c_generic_uint8_16_vectorized<uint8_t, true>;\n    //return resize_h_c_planar<uint8_t, 1>;\n  }\n  else if (pixelsize == 2) {\n#ifdef INTEL_INTRINSICS\n#ifdef INTEL_INTRINSICS_AVX512\n    if (has_AVX512_base) {\n#ifdef PF_GENERIC_UINT_TEST\n      if (bits_per_pixel < 16)\n        return resizer_h_avx512_generic_uint16_t<true>; // PF debug\n      else\n        return resizer_h_avx512_generic_uint16_t<false>; // PF debug\n#endif\n      if (bits_per_pixel < 16)\n        out_resampler_h_alternative_for_mt = resizer_h_avx2_generic_uint16_t<true>; // AVX2 should present if AVX512 present\n      else\n        out_resampler_h_alternative_for_mt = resizer_h_avx2_generic_uint16_t<false>;\n\n      // feature flag, grouping many avx512 features\n      if (program->filter_size_real <= 4) {\n        if (!program->resize_h_planar_gather_permutex_vstripe_check(32/*iSamplesInTheGroup*/, 64/*permutex_index_diff_limit*/, 4/*kernel_size*/))\n        {\n          /*\n            Contenders :\n            AVX512 Fast\n            resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks4_vnni 2578fps\n            resize_h_planar_uint16_avx512_permutex_vstripe_ks4         2310fps (only base)\n            AVX512 Base\n            resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks4_base 2556fps\n            resize_h_planar_uint16_avx512_permutex_vstripe_ks4         2310fps (only base)\n            Fazit: The MP versions' difference is only two VNNI instructions between BASE/FAST, in benchmarks zero visible speed benefit is seen.\n            Winners: (Both mp) (Fast) resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks4_vnni (Base) resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks4_base\n          */\n#ifdef SPEEDTEST_MPZ\n#ifdef USE_MPZ_VNNI\n          if (bits_per_pixel < 16) {\n            if (has_AVX512_fast)\n              return resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks4_vnni<true>; // true: lessthan16bit\n            else\n              return resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks4_base<true>;\n          } \n          else {\n            if (has_AVX512_fast)\n              return resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks4_vnni<false>;\n            else\n              return resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks4_base<false>;\n          }\n#else\n          if (bits_per_pixel < 16) {\n            return resize_h_planar_uint16_avx512_permutex_vstripe_ks4<true>;\n          }\n          else {\n            return resize_h_planar_uint16_avx512_permutex_vstripe_ks4<false>;\n          }\n#endif\n#else\n          if (bits_per_pixel < 16) {\n            if (has_AVX512_fast)\n              return resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks4_vnni<true>; // true: lessthan16bit\n            else\n              return resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks4_base<true>;\n          }\n          else {\n            if (has_AVX512_fast)\n              return resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks4_vnni<false>;\n            else\n              return resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks4_base<false>;\n          }\n#endif\n        }\n      }\n      if (program->filter_size_real <= 8) {\n        if (!program->resize_h_planar_gather_permutex_vstripe_check(32/*iSamplesInTheGroup*/, 64/*permutex_index_diff_limit*/, 8/*kernel_size*/)) {\n          /*\n            Contenders:\n            resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks8_vnni\n            resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks8_base\n            resize_h_planar_uint16_avx512_permutex_vstripe_ks8  (base avx512 only, no special intructions)\n            Fazit: The MP versions' difference is only two VNNI instructions between BASE/FAST, in benchmarks 1-2% visible speed benefit is seen.\n            Winners: (Both mp) (Fast) resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks8_vnni (Base) resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks8_base\n          */\n#ifdef SPEEDTEST_MPZ\n#ifdef USE_MPZ_VNNI\n          if (bits_per_pixel < 16) {\n            if (has_AVX512_fast)\n              return resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks8_vnni<true>; // true: lessthan16bit\n            else\n              return resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks8_base<true>;\n          } \n          else {\n            if (has_AVX512_fast)\n              return resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks8_vnni<false>;\n            else\n              return resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks8_base<false>;\n          }\n#else\n          if (bits_per_pixel < 16)\n            return resize_h_planar_uint16_avx512_permutex_vstripe_ks8<true>;\n          else\n            return resize_h_planar_uint16_avx512_permutex_vstripe_ks8<false>;\n#endif\n#else\n          if (bits_per_pixel < 16) {\n            if (has_AVX512_fast)\n              return resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks8_vnni<true>; // true: lessthan16bit\n            else\n              return resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks8_base<true>;\n          }\n          else {\n            if (has_AVX512_fast)\n              return resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks8_vnni<false>;\n            else\n              return resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks8_base<false>;\n          }\n#endif\n        }\n        if (!program->resize_h_planar_gather_permutex_vstripe_check(32/*iSamplesInTheGroup*/, 128/*permutex_index_diff_limit*/, 8/*kernel_size*/)) { // slower ks8 but more downsample ratio for /2\n          if (bits_per_pixel < 16)\n            return resize_h_planar_uint16_avx512_permutex_vstripe_2s16_ks8<true>;\n          else\n            return resize_h_planar_uint16_avx512_permutex_vstripe_2s16_ks8<false>;\n        }\n      }\n      if (program->filter_size_real <= 16) {\n        if (!program->resize_h_planar_gather_permutex_vstripe_check(32/*iSamplesInTheGroup*/, 64/*permutex_index_diff_limit*/, 16/*kernel_size*/))\n        {\n          // yes: LanczosResize(int(width*0.9 + 0.5), height, taps=4) kernel size 9 (K)\n          // yes: LanczosResize(int(width*1.1 + 0.5), height, taps=5) kernel size 10 (L)\n          // yes: LanczosResize(int(width*1.1 + 0.5), height, taps=6) kernel size 12 (M)\n          // no:  LanczosResize(int(width*0.5 + 0.5), height, taps=3) kernel size 12 (N) (in float only 2s8_ks16 covered this resampling ratio)\n          /*\n            Contenders (none):\n            AVX512 Fast\n            resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_vnni 1851 1853 2189\n            AVX512 Base\n            resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_base 1889 1869 2203 (? within measurement error, but quicker than VNNI??)\n            resizer_h_avx2_generic_uint16_t (fallback)                  1156 1085 1292\n            Winners: (Both mp) (Fast) resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks8_vnni (Base) resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks8_base\n          */\n          if (bits_per_pixel < 16) {\n            if (has_AVX512_fast)\n              return resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_vnni<true>; // true: lessthan16bit\n            else\n              return resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_base<true>;\n    }\n          else {\n            if (has_AVX512_fast)\n              return resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_vnni<false>;\n            else\n              return resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_base<false>;\n          }\n        }\n      }\n      out_resampler_h_alternative_for_mt = nullptr; // not needed\n    } // has_AVX512_base\n#endif\n    if (CPU & CPUF_AVX2) {\n      if (bits_per_pixel < 16)\n        return resizer_h_avx2_generic_uint16_t<true>;\n      else\n        return resizer_h_avx2_generic_uint16_t<false>;\n    }\n    if (CPU & CPUF_SSSE3) {\n      if (bits_per_pixel < 16)\n        return resizer_h_ssse3_generic_uint8_16<uint16_t, true>;\n      else\n        return resizer_h_ssse3_generic_uint8_16<uint16_t, false>;\n    }\n#endif\n    if (bits_per_pixel == 16)\n      return resizer_h_c_generic_uint8_16_vectorized<uint16_t, false>;\n      // return resize_h_c_planar<uint16_t, 0>;\n    else\n      return resizer_h_c_generic_uint8_16_vectorized<uint16_t, true>;\n      // return resize_h_c_planar<uint16_t, 1>;\n  }\n  else { //if (pixelsize == 4)\n#ifdef INTEL_INTRINSICS\n#ifdef INTEL_INTRINSICS_AVX512\n    if (has_AVX512_base) {\n      // feature flag, grouping many avx512 features\n\n      // these perform very poorly in Prefetch, so we provide alternative generic version for MT\n\n      if (program->filter_size_real <= 4) {\n        // up to 4 coeffs it can be highly optimized with transposes, gather/permutex choice\n        out_resampler_h_alternative_for_mt = resizer_h_avx512_generic_float_pix16_sub4_ks_4_8_16; // jolly joker\n        if (!program->resize_h_planar_gather_permutex_vstripe_check(16 /*iSamplesInTheGroup*/, 32 /*permutex_index_diff_limit*/, 4 /*kernel_size*/)) {\n          return resize_h_planar_float_avx512_permutex_vstripe_ks4;\n        }\n          return resize_h_planar_float_avx512_transpose_vstripe_ks4;\n        }\n      if (program->filter_size_real <= 8) {\n        // up to 8 coeffs it can be highly optimized with transposes, gather/permutex choice\n        out_resampler_h_alternative_for_mt = resizer_h_avx512_generic_float_pix16_sub4_ks_4_8_16; // jolly joker\n        // first check 16 pixels per cycle version, probably resize_h_planar_float_avx512_permutex_vstripe_2s8_ks8 is faster,\n        // if not possible, then 8 pixels per cycle\n        if (program->resize_h_planar_gather_permutex_vstripe_check(16/*iSamplesInTheGroup*/, 32/*permutex_index_diff_limit*/, 8/*kernel_size*/)) {\n          // 16 pixels per cycle version of permutex was not possible, try 2x8 version\n          if (!program->resize_h_planar_gather_permutex_vstripe_check(8/*iSamplesInTheGroup*/, 32/*permutex_index_diff_limit*/, 8/*kernel_size*/)) {\n            return resize_h_planar_float_avx512_permutex_vstripe_2s8_ks8; // 2x8 output version: better than transpose and generic\n          }\n          return resize_h_planar_float_avx512_transpose_vstripe_ks8;\n          // Speed ranking fps, just to have a clue, higher is better.\n          // resize_h_planar_float_avx512_permutex_vstripe_2s8_ks8:        3482\n          // resize_h_planar_float_avx512_transpose_vstripe_ks8:           3186\n          // generic resizer_h_avx512_generic_float_pix16_sub4_ks_4_8_16:  2772\n        }\n        // Speed ranking fps, just to have a clue, higher is better.\n        // resize_h_planar_float_avx512_permutex_vstripe_2s8_ks8:  2040 2390 1221\n        // resize_h_planar_float_avx512_permutex_vstripe_ks8:      2847 3236 1775\n        return resize_h_planar_float_avx512_permutex_vstripe_ks8;\n      }\n\n      if (program->filter_size_real <= 16) {\n        // up to 16 coeffs it can be highly optimized with transposes, gather/permutex choice\n        out_resampler_h_alternative_for_mt = resizer_h_avx512_generic_float_pix16_sub4_ks_4_8_16; // jolly joker\n        if (program->resize_h_planar_gather_permutex_vstripe_check(16/*iSamplesInTheGroup*/, 32/*permutex_index_diff_limit*/, 16/*kernel_size*/)) {\n          if (!program->resize_h_planar_gather_permutex_vstripe_check(8/*iSamplesInTheGroup*/, 32/*permutex_index_diff_limit*/, 16/*kernel_size*/)) {\n            // LanczosResize(int(width * 0.9 + 0.5), height, taps = 4) # case K: H kernel size 9\n            // LanczosResize(int(width * 0.5 + 0.5), height, taps = 3) # case N: H kernel size 12\n\n            // Speed ranking fps, just to have a clue, higher is better.\n            // 1902 2809 resize_h_planar_float_avx512_permutex_vstripe_ks16 (invalid here, but for reference)\n            // 1356 2137 resizer_h_avx512_generic_float_pix16_sub4_ks_4_8_16 \n            // 1278 1997 resize_h_planar_float_avx512_permutex_vstripe_2s8_ks16 test 2x8 output version\n\n            // return resize_h_planar_float_avx512_permutex_vstripe_2s8_ks16; // This one is slower than the generic version\n            // Anyway we keep this branch, maybe in future 2s8_ks16 can be optimized better, till then, use generic.\n      return resizer_h_avx512_generic_float_pix16_sub4_ks_4_8_16;\n          }\n          return resizer_h_avx512_generic_float_pix16_sub4_ks_4_8_16; // todo: _ks16 transpose-based version to be designed and checked \n        }\n        return resize_h_planar_float_avx512_permutex_vstripe_ks16;\n      }\n      \n      return resizer_h_avx512_generic_float_pix16_sub4_ks_4_8_16;\n      // other candidates were tested:\n      // return resizer_h_avx512_generic_float_pix8_sub8_ks16;\n      // return resizer_h_avx512_generic_float_pix16_sub16_ks8;\n      // return resizer_h_avx512_generic_float_pix32_sub8_ks8;\n      // return resizer_h_avx2_generic_float_pix8_sub2; // like AVX2 version\n      // return resizer_h_avx512_generic_float_pix8_sub2; // like AVX2 version\n      // return resizer_h_avx512_generic_float_pix8_sub4_ks8;\n      // return resizer_h_avx512_generic_float_pix16_sub4_ks4;\n      // return resizer_h_avx512_generic_float_pix16_sub4_ks8;\n      // return resizer_h_avx2_generic_float;\n    }\n#endif\n    if (CPU & CPUF_AVX2) {\n      // up to 4 coeffs it can be highly optimized with transposes, gather/permutex choice\n      // These perform very poorly in Prefetch, so we provide alternative generic version for MT\n      out_resampler_h_alternative_for_mt = resize_h_planar_float_avx2_permutex_vstripe_ks4; // jolly joker\n      if (program->filter_size_real <= 4) {\n        if (program->resize_h_planar_gather_permutex_vstripe_check(8 /*iSamplesInTheGroup*/, 8 /*permutex_index_diff_limit*/, 4 /*kernel_size*/)) {\n      switch (program->filter_size_real) {\n          case 1: return resize_h_planar_float_avx2_transpose_vstripe_ks4<1>; break;\n          case 2: return resize_h_planar_float_avx2_transpose_vstripe_ks4<2>; break;\n          case 3: return resize_h_planar_float_avx2_transpose_vstripe_ks4<3>; break;\n          case 4: return resize_h_planar_float_avx2_transpose_vstripe_ks4<0>; break;\n          }\n        }\n        return resize_h_planar_float_avx2_permutex_vstripe_ks4;\n      }\n      return resizer_h_avx2_generic_float_pix16_sub4_ks_4_8_16; // new generic, like avx512 version\n      // return resizer_h_avx2_generic_float; old generic would be named pix8_sub2_ks8\n    }\n    if (CPU & CPUF_SSSE3) {\n      // up to 4 coeffs it can be highly optimized with transposes\n      // These perform very poorly in Prefetch, so we provide alternative generic version for MT\n      if (program->filter_size_real <= 4)\n        out_resampler_h_alternative_for_mt = resizer_h_ssse3_generic_float; // jolly joker\n      switch (program->filter_size_real) {\n      case 1: return resize_h_planar_float_sse_transpose_vstripe_ks4<1>; break;\n      case 2: return resize_h_planar_float_sse_transpose_vstripe_ks4<2>; break;\n      case 3: return resize_h_planar_float_sse_transpose_vstripe_ks4<3>; break;\n      case 4: return resize_h_planar_float_sse_transpose_vstripe_ks4<0>; break;\n      default: return resizer_h_ssse3_generic_float;\n      }\n    }\n#endif\n    return resize_h_c_planar<float, 0>;\n  }\n}\n\nFilteredResizeH::~FilteredResizeH(void)\n{\n  if (resampling_program_luma) { delete resampling_program_luma; }\n  if (resampling_program_chroma) { delete resampling_program_chroma; }\n}\n\n/***************************************\n ***** Filtered Resize - Vertical ******\n ***************************************/\n\nFilteredResizeV::FilteredResizeV(PClip _child, double subrange_top, double subrange_height,\n  int target_height, ResamplingFunction* func, \n  bool preserve_center, int chroma_placement,\n  IScriptEnvironment* env)\n  : GenericVideoFilter(_child),\n  resampling_program_luma(0), resampling_program_chroma(0)\n{\n  if (target_height <= 0)\n    env->ThrowError(\"Resize: Height must be greater than 0.\");\n\n  pixelsize = vi.ComponentSize(); // AVS16\n  bits_per_pixel = vi.BitsPerComponent();\n  grey = vi.IsY();\n  bool isRGBPfamily = vi.IsPlanarRGB() || vi.IsPlanarRGBA();\n\n  if (vi.IsPlanar() && !grey && !isRGBPfamily) {\n    const int mask = (1 << vi.GetPlaneHeightSubsampling(PLANAR_U)) - 1;\n\n    if (target_height & mask)\n      env->ThrowError(\"Resize: Planar destination height must be a multiple of %d.\", mask + 1);\n  }\n\n  if (vi.IsRGB() && !isRGBPfamily)\n    subrange_top = vi.height - subrange_top - subrange_height; // packed RGB upside down\n\n#ifdef INTEL_INTRINSICS\n  int cpu = env->GetCPUFlags();\n#else\n  int cpu = 0;\n#endif\n\n  double center_pos_v_luma;\n  double center_pos_v_chroma;\n  GetCenterShiftForResizers(center_pos_v_luma, center_pos_v_chroma, preserve_center, chroma_placement, vi, false /* for vertical */);\n  // 3.7.4- parameter, old Avisynth behavior: 0.5, 0.5\n\n  // Create resampling program and pitch table\n  resampling_program_luma = func->GetResamplingProgram(vi.height, subrange_top, subrange_height, target_height, bits_per_pixel, \n    center_pos_v_luma, center_pos_v_luma, // for resizing it's the same for source and dest\n    env);\n  resampler_luma = GetResampler(cpu, pixelsize, bits_per_pixel, resampling_program_luma, env);\n\n  if (vi.IsPlanar() && !grey && !isRGBPfamily) {\n    const int shift = vi.GetPlaneHeightSubsampling(PLANAR_U);\n    const int div = 1 << shift;\n\n    resampling_program_chroma = func->GetResamplingProgram(\n      vi.height >> shift,\n      subrange_top / div,\n      subrange_height / div,\n      target_height >> shift,\n      bits_per_pixel,\n      center_pos_v_chroma, center_pos_v_chroma, // for resizing it's the same for source and dest\n      env);\n\n    resampler_chroma = GetResampler(cpu, pixelsize, bits_per_pixel, resampling_program_chroma, env);\n  }\n\n  // Change target video info size\n  vi.height = target_height;\n}\n\nPVideoFrame __stdcall FilteredResizeV::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame src = child->GetFrame(n, env);\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n  int src_pitch = src->GetPitch();\n  int dst_pitch = dst->GetPitch();\n  const BYTE* srcp = src->GetReadPtr();\n  BYTE* dstp = dst->GetWritePtr();\n\n  bool isRGBPfamily = vi.IsPlanarRGB() || vi.IsPlanarRGBA();\n\n  // Do resizing\n  int work_width = vi.IsPlanar() ? vi.width : vi.BytesFromPixels(vi.width) / pixelsize; // packed RGB: or vi.width * vi.NumComponent()\n  resampler_luma(dstp, srcp, dst_pitch, src_pitch, resampling_program_luma, work_width, vi.height, bits_per_pixel);\n  if (isRGBPfamily)\n  {\n    src_pitch = src->GetPitch(PLANAR_B);\n    dst_pitch = dst->GetPitch(PLANAR_B);\n    srcp = src->GetReadPtr(PLANAR_B);\n    dstp = dst->GetWritePtr(PLANAR_B);\n    \n    resampler_luma(dstp, srcp, dst_pitch, src_pitch, resampling_program_luma, work_width, vi.height, bits_per_pixel);\n    \n    src_pitch = src->GetPitch(PLANAR_R);\n    dst_pitch = dst->GetPitch(PLANAR_R);\n    srcp = src->GetReadPtr(PLANAR_R);\n    dstp = dst->GetWritePtr(PLANAR_R);\n\n    resampler_luma(dstp, srcp, dst_pitch, src_pitch, resampling_program_luma, work_width, vi.height, bits_per_pixel);\n  }\n  else if (!grey && vi.IsPlanar()) {\n    int width = vi.width >> vi.GetPlaneWidthSubsampling(PLANAR_U);\n    int height = vi.height >> vi.GetPlaneHeightSubsampling(PLANAR_U);\n\n    // Plane U resizing\n    src_pitch = src->GetPitch(PLANAR_U);\n    dst_pitch = dst->GetPitch(PLANAR_U);\n    srcp = src->GetReadPtr(PLANAR_U);\n    dstp = dst->GetWritePtr(PLANAR_U);\n\n    resampler_chroma(dstp, srcp, dst_pitch, src_pitch, resampling_program_chroma, width, height, bits_per_pixel);\n\n    // Plane V resizing\n    src_pitch = src->GetPitch(PLANAR_V);\n    dst_pitch = dst->GetPitch(PLANAR_V);\n    srcp = src->GetReadPtr(PLANAR_V);\n    dstp = dst->GetWritePtr(PLANAR_V);\n\n    resampler_chroma(dstp, srcp, dst_pitch, src_pitch, resampling_program_chroma, width, height, bits_per_pixel);\n  }\n\n  if (vi.IsYUVA() || vi.IsPlanarRGBA()) {\n    src_pitch = src->GetPitch(PLANAR_A);\n    dst_pitch = dst->GetPitch(PLANAR_A);\n    srcp = src->GetReadPtr(PLANAR_A);\n    dstp = dst->GetWritePtr(PLANAR_A);\n    resampler_luma(dstp, srcp, dst_pitch, src_pitch, resampling_program_luma, work_width, vi.height, bits_per_pixel);\n  }\n\n  return dst;\n}\n\nResamplerV FilteredResizeV::GetResampler(int CPU, int pixelsize, int bits_per_pixel, ResamplingProgram* program, IScriptEnvironment* env)\n{\n\n  resize_prepare_coeffs(program, env, 8); \n  // for SIMD friendliness and more: consolidate the kernel_size vs filter_size at the end.\n  // See comments at FilteredResizeH::GetResampler\n\n#ifdef INTEL_INTRINSICS_AVX512\n  const bool has_AVX512_base = (CPU & CPUF_AVX512_BASE) == CPUF_AVX512_BASE;\n#endif\n\n  if (program->filter_size == 1) {\n    // Fast pointresize\n    switch (pixelsize) // AVS16\n    {\n    case 1: return resize_v_planar_pointresize<uint8_t>;\n    case 2: return resize_v_planar_pointresize<uint16_t>;\n    default: // case 4:\n      return resize_v_planar_pointresize<float>;\n    }\n  }\n  else {\n    // Other resizers\n    if (pixelsize == 1)\n    {\n#ifdef INTEL_INTRINSICS\n#ifdef INTEL_INTRINSICS_AVX512\n      if (has_AVX512_base)\n        return resize_v_avx512_planar_uint8_t_w_sr;\n#endif\n      if (CPU & CPUF_AVX2)\n        return resize_v_avx2_planar_uint8_t;\n      if (CPU & CPUF_SSE2)\n        return resize_v_sse2_planar;\n#ifdef X86_32\n      if (CPU & CPUF_MMX)\n        return resize_v_mmx_planar;\n#endif\n#endif\n      // C version\n      return resize_v_c_planar_uint8_16_t_auto_vectorized<uint8_t, true>;\n    }\n    else if (pixelsize == 2)\n    {\n#ifdef INTEL_INTRINSICS\n#ifdef INTEL_INTRINSICS_AVX512\n      if (has_AVX512_base) {\n        if (bits_per_pixel < 16)\n          return resize_v_avx512_planar_uint16_t_w_sr<true>;\n        else\n          return resize_v_avx512_planar_uint16_t_w_sr<false>;\n      }\n#endif\n      if (CPU & CPUF_AVX2) {\n        if (bits_per_pixel < 16)\n          return resize_v_avx2_planar_uint16_t<true>;\n        else\n          return resize_v_avx2_planar_uint16_t<false>;\n      }\n      if (CPU & CPUF_SSE2) {\n        if (bits_per_pixel < 16)\n          return resize_v_sse2_planar_uint16_t<true>;\n        else\n          return resize_v_sse2_planar_uint16_t<false>;\n      }\n#endif\n      // C version\n      if(bits_per_pixel == 16)\n        return resize_v_c_planar_uint8_16_t_auto_vectorized<uint16_t, false>;\n      else\n        return resize_v_c_planar_uint8_16_t_auto_vectorized<uint16_t, true>;\n    }\n    else // pixelsize== 4\n    {\n#ifdef INTEL_INTRINSICS\n#ifdef INTEL_INTRINSICS_AVX512\n      if (has_AVX512_base) {\n        // return resize_v_avx512_planar_float; // Old, base version, quicker than avx2 version\n        // This one is about equal to avx2 version, but only with clang,\n        // it seems that clang is too good and, probably unrolls the old function version\n        // out-of-box so much better than MSVC, that it competes with the _w_sr version.\n        // With MSVC its no-brainer to use avx512\n        return resize_v_avx512_planar_float_w_sr;\n      }\n#endif\n      if (CPU & CPUF_AVX2) {\n        return resize_v_avx2_planar_float_w_sr;\n        // a memory-optimized version of resize_v_avx2_planar_float\n      }\n      if (CPU & CPUF_SSE2) {\n        return resize_v_sse2_planar_float;\n      }\n#endif\n      return resize_v_c_planar_float_auto_vectorized;\n    }\n  }\n}\n\nFilteredResizeV::~FilteredResizeV(void)\n{\n  if (resampling_program_luma) { delete resampling_program_luma; }\n  if (resampling_program_chroma) { delete resampling_program_chroma; }\n}\n\n\n/**********************************************\n *******   Resampling Factory Methods   *******\n **********************************************/\n\nPClip FilteredResize::CreateResizeH(PClip clip, double subrange_left, double subrange_width, int target_width, bool force,\n  ResamplingFunction* func, bool preserve_center, int chroma_placement, IScriptEnvironment* env)\n{\n  const VideoInfo& vi = clip->GetVideoInfo();\n  if (!force && subrange_left == 0 && subrange_width == target_width && subrange_width == vi.width) {\n    return clip;\n  }\n  /*\n  // intentionally left here: don't use crop at special edge cases to avoid inconsistent results across params/color spaces\n  if (subrange_left == int(subrange_left) && subrange_width == target_width\n   && subrange_left >= 0 && subrange_left + subrange_width <= vi.width) {\n    const int mask = ((vi.IsYUV() || vi.IsYUVA()) && !vi.IsY()) ? (1 << vi.GetPlaneWidthSubsampling(PLANAR_U)) - 1 : 0;\n\n    if (((int(subrange_left) | int(subrange_width)) & mask) == 0)\n      return new Crop(int(subrange_left), 0, int(subrange_width), vi.height, 0, clip, env);\n  }\n  */\n  // Convert interleaved yuv to planar yuv\n  PClip result = clip;\n  if (vi.IsYUY2()) {\n    result = new ConvertYUY2ToYV16_or_Y(result, false /*to_y*/, env);\n  }\n\n  result = new FilteredResizeH(result, subrange_left, subrange_width, target_width, func, preserve_center, chroma_placement, env);\n  \n  if (vi.IsYUY2()) {\n    result = new ConvertYV16ToYUY2(result, env);\n  }\n\n  return result;\n}\n\n\nPClip FilteredResize::CreateResizeV(PClip clip, double subrange_top, double subrange_height, int target_height, bool force,\n  ResamplingFunction* func, bool preserve_center, int chroma_placement, IScriptEnvironment* env)\n{\n  const VideoInfo& vi = clip->GetVideoInfo();\n  if (!force && subrange_top == 0 && subrange_height == target_height && subrange_height == vi.height) {\n    return clip;\n  }\n  /*\n  // intentionally left here: don't use crop at special edge cases to avoid inconsistent results across params/color spaces\n  if (subrange_top == int(subrange_top) && subrange_height == target_height\n   && subrange_top >= 0 && subrange_top + subrange_height <= vi.height) {\n    const int mask = ((vi.IsYUV() || vi.IsYUVA()) && !vi.IsY()) ? (1 << vi.GetPlaneHeightSubsampling(PLANAR_U)) - 1 : 0;\n\n    if (((int(subrange_top) | int(subrange_height)) & mask) == 0)\n      return new Crop(0, int(subrange_top), vi.width, int(subrange_height), 0, clip, env);\n  }\n  */\n  return new FilteredResizeV(clip, subrange_top, subrange_height, target_height, func, preserve_center, chroma_placement, env);\n}\n\n\nPClip FilteredResize::CreateResize(PClip clip, int target_width, int target_height, const AVSValue* args, int force,\n  ResamplingFunction* f, \n  bool preserve_center, const char* placement_name, const int forced_chroma_placement,\n  IScriptEnvironment* env)\n{\n  // args 0-1-2-3: left-top-width-height\n  VideoInfo vi = clip->GetVideoInfo();\n  const double subrange_left = args[0].AsFloat(0), subrange_top = args[1].AsFloat(0);\n\n  double subrange_width = args[2].AsDblDef(vi.width), subrange_height = args[3].AsDblDef(vi.height);\n  // Crop style syntax\n  if (subrange_width <= 0.0) subrange_width = vi.width - subrange_left + subrange_width;\n  if (subrange_height <= 0.0) subrange_height = vi.height - subrange_top + subrange_height;\n\n  PClip result;\n  // ensure that the intermediate area is maximal\n\n  const double area_FirstH = subrange_height * target_width;\n  const double area_FirstV = subrange_width * target_height;\n\n  // \"minimal area\" logic is not necessarily faster because H and V resizers are not the same speed.\n  // so we keep the traditional max area logic, which is for quality\n\n  // use forced_chroma_placement >= 0 and placement_name == nullptr together\n  int chroma_placement = forced_chroma_placement >= 0 ? forced_chroma_placement : ChromaLocation_e::AVS_CHROMA_UNUSED;\n  if (placement_name) {\n    // no format-oriented defaults\n    if (vi.IsYV411() || vi.Is420() || vi.Is422()) {\n      // placement explicite parameter like in ConvertToXXX or Text\n      // input frame properties, if \"auto\"\n      // When called from ConvertToXXX, chroma is not involved.\n      auto frame0 = clip->GetFrame(0, env);\n      const AVSMap* props = env->getFramePropsRO(frame0);\n      chromaloc_parse_merge_with_props(vi, placement_name, props, /* ref*/chroma_placement, ChromaLocation_e::AVS_CHROMA_UNUSED /*default*/, env);\n    }\n\n  }\n\n  // 0 - return unchanged if no resize needed\n  // 1 - force H\n  // 2 - force V\n  // 3 - force H and V\n  const bool force_H = force == 1 || force == 3;\n  const bool force_V = force == 2 || force == 3;\n  if (area_FirstH < area_FirstV)\n  {\n    result = CreateResizeV(clip, subrange_top, subrange_height, target_height, force_V, f, preserve_center, chroma_placement, env);\n    result = CreateResizeH(result, subrange_left, subrange_width, target_width, force_H, f, preserve_center, chroma_placement, env);\n  }\n  else\n  {\n    result = CreateResizeH(clip, subrange_left, subrange_width, target_width, force_H, f, preserve_center, chroma_placement, env);\n    result = CreateResizeV(result, subrange_top, subrange_height, target_height, force_V, f, preserve_center, chroma_placement, env);\n  }\n  return result;\n}\n\nAVSValue __cdecl FilteredResize::Create_PointResize(AVSValue args, void*, IScriptEnvironment* env)\n{\n  auto f = PointFilter();\n  const int force = args[7].AsInt(0);\n\n  bool preserve_center = args[8].AsBool(true); // [keep_center] default Avisynth\n  const char* placement_name = args[9].AsString(\"auto\"); // [placement]s\n  const int forced_chroma_placement = -1; // no force, used internally\n\n  return CreateResize(args[0].AsClip(), args[1].AsInt(), args[2].AsInt(), &args[3], force, &f, preserve_center, placement_name, forced_chroma_placement, env);\n}\n\n\nAVSValue __cdecl FilteredResize::Create_BilinearResize(AVSValue args, void*, IScriptEnvironment* env)\n{\n  auto f = TriangleFilter();\n  const int force = args[7].AsInt(0);\n\n  bool preserve_center = args[8].AsBool(true); // [keep_center] default Avisynth\n  const char* placement_name = args[9].AsString(\"auto\"); // [placement]s\n  const int forced_chroma_placement = -1; // no force, used internally\n\n  return CreateResize(args[0].AsClip(), args[1].AsInt(), args[2].AsInt(), &args[3], force, &f, preserve_center, placement_name, forced_chroma_placement, env);\n}\n\n\nAVSValue __cdecl FilteredResize::Create_BicubicResize(AVSValue args, void*, IScriptEnvironment* env)\n{\n  auto f = MitchellNetravaliFilter(args[3].AsDblDef(1. / 3.), args[4].AsDblDef(1. / 3.));\n  const int force = args[9].AsInt(0);\n\n  bool preserve_center = args[10].AsBool(true); // [keep_center] default Avisynth\n  const char* placement_name = args[11].AsString(\"auto\"); // [placement]s\n  const int forced_chroma_placement = -1; // no force, used internally\n\n  return CreateResize(args[0].AsClip(), args[1].AsInt(), args[2].AsInt(), &args[5], force, &f, preserve_center, placement_name, forced_chroma_placement, env);\n}\n\nAVSValue __cdecl FilteredResize::Create_LanczosResize(AVSValue args, void*, IScriptEnvironment* env)\n{\n  auto f = LanczosFilter(args[7].AsInt(3));\n  const int force = args[8].AsInt(0);\n\n  bool preserve_center = args[9].AsBool(true); // [keep_center] default Avisynth\n  const char* placement_name = args[10].AsString(\"auto\"); // [placement]s\n  const int forced_chroma_placement = -1; // no force, used internally\n\n  return CreateResize(args[0].AsClip(), args[1].AsInt(), args[2].AsInt(), &args[3], force, &f, preserve_center, placement_name, forced_chroma_placement, env);\n}\n\nAVSValue __cdecl FilteredResize::Create_Lanczos4Resize(AVSValue args, void*, IScriptEnvironment* env)\n{\n  auto f = LanczosFilter(4);\n  const int force = args[7].AsInt(0);\n\n  bool preserve_center = args[8].AsBool(true); // [keep_center] default Avisynth\n  const char* placement_name = args[9].AsString(\"auto\"); // [placement]s\n  const int forced_chroma_placement = -1; // no force, used internally\n\n  return CreateResize(args[0].AsClip(), args[1].AsInt(), args[2].AsInt(), &args[3], force, &f, preserve_center, placement_name, forced_chroma_placement, env);\n}\n\nAVSValue __cdecl FilteredResize::Create_BlackmanResize(AVSValue args, void*, IScriptEnvironment* env)\n{\n  auto f = BlackmanFilter(args[7].AsInt(4));\n  const int force = args[8].AsInt(0);\n\n  bool preserve_center = args[8].AsBool(true); // [keep_center] default Avisynth\n  const char* placement_name = args[9].AsString(\"auto\"); // [placement]s\n  const int forced_chroma_placement = -1; // no force, used internally\n\n  return CreateResize(args[0].AsClip(), args[1].AsInt(), args[2].AsInt(), &args[3], force, &f, preserve_center, placement_name, forced_chroma_placement, env);\n}\n\nAVSValue __cdecl FilteredResize::Create_Spline16Resize(AVSValue args, void*, IScriptEnvironment* env)\n{\n  auto f = Spline16Filter();\n  const int force = args[7].AsInt(0);\n\n  bool preserve_center = args[8].AsBool(true); // [keep_center] default Avisynth\n  const char* placement_name = args[9].AsString(\"auto\"); // [placement]s\n  const int forced_chroma_placement = -1; // no force, used internally\n\n  return CreateResize(args[0].AsClip(), args[1].AsInt(), args[2].AsInt(), &args[3], force, &f, preserve_center, placement_name, forced_chroma_placement, env);\n}\n\nAVSValue __cdecl FilteredResize::Create_Spline36Resize(AVSValue args, void*, IScriptEnvironment* env)\n{\n  auto f = Spline36Filter();\n  const int force = args[7].AsInt(0);\n\n  bool preserve_center = args[8].AsBool(true); // [keep_center] default Avisynth\n  const char* placement_name = args[9].AsString(\"auto\"); // [placement]s\n  const int forced_chroma_placement = -1; // no force, used internally\n\n  return CreateResize(args[0].AsClip(), args[1].AsInt(), args[2].AsInt(), &args[3], force, &f, preserve_center, placement_name, forced_chroma_placement, env);\n}\n\nAVSValue __cdecl FilteredResize::Create_Spline64Resize(AVSValue args, void*, IScriptEnvironment* env)\n{\n  auto f = Spline64Filter();\n  const int force = args[7].AsInt(0);\n\n  bool preserve_center = args[8].AsBool(true); // [keep_center] default Avisynth\n  const char* placement_name = args[9].AsString(\"auto\"); // [placement]s\n  const int forced_chroma_placement = -1; // no force, used internally\n\n  return CreateResize(args[0].AsClip(), args[1].AsInt(), args[2].AsInt(), &args[3], force, &f, preserve_center, placement_name, forced_chroma_placement, env);\n}\n\nAVSValue __cdecl FilteredResize::Create_GaussianResize(AVSValue args, void*, IScriptEnvironment* env)\n{\n  auto f = GaussianFilter(args[7].AsFloat(30.0f), args[8].AsFloat(2.0f), args[9].AsFloat(4.0f)); // defaults at two more places\n  const int force = args[10].AsInt(0);\n\n  bool preserve_center = args[11].AsBool(true); // [keep_center] default Avisynth\n  const char* placement_name = args[12].AsString(\"auto\"); // [placement]s\n  const int forced_chroma_placement = -1; // no force, used internally\n\n  return CreateResize(args[0].AsClip(), args[1].AsInt(), args[2].AsInt(), &args[3], force, &f, preserve_center, placement_name, forced_chroma_placement, env);\n}\n\nAVSValue __cdecl FilteredResize::Create_SincResize(AVSValue args, void*, IScriptEnvironment* env)\n{\n  auto f = SincFilter(args[7].AsInt(4));\n  const int force = args[8].AsInt(0);\n \n  bool preserve_center = args[9].AsBool(true); // [keep_center] default Avisynth\n  const char * placement_name = args[10].AsString(\"auto\"); // [placement]s\n  const int forced_chroma_placement = -1; // no force, used internally\n\n  return CreateResize(args[0].AsClip(), args[1].AsInt(), args[2].AsInt(), &args[3], force, &f, preserve_center, placement_name, forced_chroma_placement, env);\n}\n\n// like GaussianFilter(); optional P\nAVSValue __cdecl FilteredResize::Create_SinPowerResize(AVSValue args, void*, IScriptEnvironment* env)\n{\n  auto f = SinPowerFilter(args[7].AsFloat(2.5f));\n  const int force = args[8].AsInt(0);\n\n  bool preserve_center = args[9].AsBool(true); // [keep_center] default Avisynth\n  const char* placement_name = args[10].AsString(\"auto\"); // [placement]s\n  const int forced_chroma_placement = -1; // no force, used internally\n\n  return CreateResize(args[0].AsClip(), args[1].AsInt(), args[2].AsInt(), &args[3], force, &f, preserve_center, placement_name, forced_chroma_placement, env);\n}\n\n// like SincFilter or LanczosFilter: optional Taps\nAVSValue __cdecl FilteredResize::Create_SincLin2Resize(AVSValue args, void*, IScriptEnvironment* env)\n{\n  auto f = SincLin2Filter(args[7].AsInt(15));\n  const int force = args[8].AsInt(0);\n\n  bool preserve_center = args[9].AsBool(true); // [keep_center] default Avisynth\n  const char* placement_name = args[10].AsString(\"auto\"); // [placement]s\n  const int forced_chroma_placement = -1; // no force, used internally\n\n  return CreateResize(args[0].AsClip(), args[1].AsInt(), args[2].AsInt(), &args[3], force, &f, preserve_center, placement_name, forced_chroma_placement, env);\n}\n\n// like bicubic, plus 's'upport: optional B and C and S\nAVSValue __cdecl FilteredResize::Create_UserDefined2Resize(AVSValue args, void*, IScriptEnvironment* env)\n{\n  auto f = UserDefined2Filter(args[3].AsFloat(121.0f), args[4].AsFloat(19.0f), args[5].AsFloat(2.3f));\n  const int force = args[10].AsInt(0);\n\n  bool preserve_center = args[11].AsBool(true); // [keep_center] default Avisynth\n  const char* placement_name = args[12].AsString(\"auto\"); // [placement]s\n  const int forced_chroma_placement = -1; // no force, used internally\n\n  return CreateResize(args[0].AsClip(), args[1].AsInt(), args[2].AsInt(), &args[6], force, &f, preserve_center, placement_name, forced_chroma_placement, env);\n}\n\n"
  },
  {
    "path": "avs_core/filters/resample.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Resample_H__\n#define __Resample_H__\n\n#include <avisynth.h>\n#include \"resample_functions.h\"\n\nvoid resize_prepare_coeffs(ResamplingProgram* p, IScriptEnvironment* env, int alignFilterSize8or16);\n\n// Resizer function pointer\ntypedef void (*ResamplerV)(BYTE* dst, const BYTE* src, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel);\ntypedef void (*ResamplerH)(BYTE* dst, const BYTE* src, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int target_height, int bits_per_pixel);\n\n// Turn function pointer -- copied from turn.h\ntypedef void (*TurnFuncPtr) (const BYTE* srcp, BYTE* dstp, int width, int height, int src_pitch, int dst_pitch);\n\n/**\n  * Class to resize in the horizontal direction using a specified sampling filter\n  * Helper for resample functions\n **/\nclass FilteredResizeH : public GenericVideoFilter\n{\npublic:\n  FilteredResizeH(PClip _child, double subrange_left, double subrange_width, int target_width, ResamplingFunction* func, \n    bool preserve_center, int chroma_placement, IScriptEnvironment* env);\n  virtual ~FilteredResizeH(void);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    if (cachehints == CACHE_GET_MTMODE) return MT_NICE_FILTER;\n    if (cachehints == CACHE_INFORM_NUM_THREADS) {\n      num_threads = frame_range;\n    }\n    return 0;\n  }\n\n  static ResamplerH GetResampler(int CPU, int pixelsize, int bits_per_pixel, ResamplingProgram* program, ResamplerH& resampler_h_alternative_for_mt, IScriptEnvironment* env);\n\nprivate:\n  // Resampling\n  ResamplingProgram* resampling_program_luma;\n  ResamplingProgram* resampling_program_chroma;\n\n  int temp_1_pitch, temp_2_pitch;\n\n  int src_width, src_height, dst_width, dst_height;\n  bool grey;\n  int pixelsize; // AVS16\n  int bits_per_pixel;\n\n  ResamplerH resampler_h_luma;\n  ResamplerH resampler_h_chroma;\n  // if the base version performs poorly, we decide to use MT version\n  // Unfortunately the information about number of threads is not available at construction time\n  // we get num_threads later via SetCacheHints callback with constants CACHE_INFORM_NUM_THREADS.\n  ResamplerH resampler_h_luma_mt;\n  ResamplerH resampler_h_chroma_mt;\n  bool fast_resize;\n\n  ResamplerV resampler_luma;\n  ResamplerV resampler_chroma;\n\n  TurnFuncPtr turn_left, turn_right;\n\n  int num_threads; // set by MTGuard by calling SetCacheHints(CACHE_INFORM_NUM_THREADS, n)\n};\n\n\n/**\n  * Class to resize in the vertical direction using a specified sampling filter\n  * Helper for resample functions\n **/\nclass FilteredResizeV : public GenericVideoFilter\n{\npublic:\n  FilteredResizeV(PClip _child, double subrange_top, double subrange_height, int target_height, ResamplingFunction* func, \n    bool preserve_center, int chroma_placement, IScriptEnvironment* env);\n  virtual ~FilteredResizeV(void);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static ResamplerV GetResampler(int CPU, int pixelsize, int bits_per_pixel, ResamplingProgram* program, IScriptEnvironment* env);\n\nprivate:\n  bool grey;\n  int pixelsize; // AVS16\n  int bits_per_pixel;\n\n  ResamplingProgram* resampling_program_luma;\n  ResamplingProgram* resampling_program_chroma;\n\n  ResamplerV resampler_luma;\n  ResamplerV resampler_chroma;\n};\n\n\n/*** Resample factory methods ***/\n\nclass FilteredResize\n  /**\n    * Helper for resample functions\n   **/\n{\npublic:\n  static PClip CreateResizeH(PClip clip, double subrange_left, double subrange_width, int target_width, bool force,\n    ResamplingFunction* func, \n    bool preserve_center, int chroma_placement,\n    IScriptEnvironment* env);\n\n  static PClip CreateResizeV(PClip clip, double subrange_top, double subrange_height, int target_height, bool force,\n    ResamplingFunction* func, \n    bool preserve_center, int chroma_placement,\n    IScriptEnvironment* env);\n\n  static PClip CreateResize(PClip clip, int target_width, int target_height, const AVSValue* args, int force,\n    ResamplingFunction* f, \n    bool preserve_center, const char *placement_name, int forced_chroma_placement,\n    IScriptEnvironment* env);\n\n  static AVSValue __cdecl Create_PointResize(AVSValue args, void*, IScriptEnvironment* env);\n\n  static AVSValue __cdecl Create_BilinearResize(AVSValue args, void*, IScriptEnvironment* env);\n\n  static AVSValue __cdecl Create_BicubicResize(AVSValue args, void*, IScriptEnvironment* env);\n\n  // 09-14-2002 - Vlad59 - Lanczos3Resize -\n  static AVSValue __cdecl Create_LanczosResize(AVSValue args, void*, IScriptEnvironment* env);\n\n  static AVSValue __cdecl Create_Lanczos4Resize(AVSValue args, void*, IScriptEnvironment* env);\n\n  static AVSValue __cdecl Create_BlackmanResize(AVSValue args, void*, IScriptEnvironment* env);\n\n  static AVSValue __cdecl Create_Spline16Resize(AVSValue args, void*, IScriptEnvironment* env);\n\n  static AVSValue __cdecl Create_Spline36Resize(AVSValue args, void*, IScriptEnvironment* env);\n\n  static AVSValue __cdecl Create_Spline64Resize(AVSValue args, void*, IScriptEnvironment* env);\n\n  static AVSValue __cdecl Create_GaussianResize(AVSValue args, void*, IScriptEnvironment* env);\n\n  static AVSValue __cdecl Create_SincResize(AVSValue args, void*, IScriptEnvironment* env);\n\n  static AVSValue __cdecl Create_SinPowerResize(AVSValue args, void*, IScriptEnvironment* env);\n  \n  static AVSValue __cdecl Create_SincLin2Resize(AVSValue args, void*, IScriptEnvironment* env);\n\n  static AVSValue __cdecl Create_UserDefined2Resize(AVSValue args, void*, IScriptEnvironment* env);\n};\n\n\n\n#endif // __Resample_H__\n"
  },
  {
    "path": "avs_core/filters/resample_functions.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include \"resample_functions.h\"\n#include <cmath>\n#include <vector>\n#include <algorithm>\n#include <avs/minmax.h>\n#include <avs/alignment.h>\n\n\n/*******************************************\n   ***************************************\n   **  Helper classes for resample.cpp  **\n   ***************************************\n *******************************************/\n\n/***************************\n ***** Point filter *****\n **************************/\n\ndouble PointFilter::f(double x) {\n  AVS_UNUSED(x);\n  return 1.0;\n}\n\n\n/***************************\n ***** Triangle filter *****\n **************************/\n\ndouble TriangleFilter::f(double x) {\n  x = fabs(x);\n  return (x<1.0) ? 1.0-x : 0.0;\n}\n\n\n\n\n\n/*********************************\n *** Mitchell-Netravali filter ***\n *********************************/\n\nMitchellNetravaliFilter::MitchellNetravaliFilter (double b, double c) {\n  p0 = (   6. -  2.*b            ) / 6.;\n  p2 = ( -18. + 12.*b +  6.*c    ) / 6.;\n  p3 = (  12. -  9.*b -  6.*c    ) / 6.;\n  q0 = (            8.*b + 24.*c ) / 6.;\n  q1 = (         - 12.*b - 48.*c ) / 6.;\n  q2 = (            6.*b + 30.*c ) / 6.;\n  q3 = (      -     b -  6.*c    ) / 6.;\n}\n\ndouble MitchellNetravaliFilter::f (double x) {\n  x = fabs(x);\n  return (x<1) ? (p0+x*x*(p2+x*p3)) : (x<2) ? (q0+x*(q1+x*(q2+x*q3))) : 0.0;\n}\n\n\n/***********************\n *** Lanczos3 filter ***\n ***********************/\nLanczosFilter::LanczosFilter(int _taps) {\n   taps = (double)clamp(_taps, 1, 100);\n}\n\ndouble LanczosFilter::sinc(double value) {\n  if (value > 0.000001) {\n    value *= M_PI;\n    return sin(value) / value;\n  } else {\n    return 1.0;\n  }\n}\n\ndouble LanczosFilter::f(double value) {\n   value = fabs(value);\n\n  if (value < taps) {\n    return (sinc(value) * sinc(value / taps));\n  } else {\n    return 0.0;\n  }\n}\n\n\n/***********************\n *** Blackman filter ***\n ***********************/\nBlackmanFilter::BlackmanFilter(int _taps) {\n   taps = (double)clamp(_taps, 1, 100);\n   rtaps = 1.0/taps;\n}\n\ndouble BlackmanFilter::f(double value) {\n   value = fabs(value);\n\n  if (value < taps) {\n    if (value > 0.000001) {\n      value *= M_PI;\n      return (sin(value) / value) * (0.42 + 0.5*cos(value*rtaps) + 0.08*cos(2*value*rtaps));\n    } else {\n      return 1.0;\n    }\n  } else {\n    return 0.0;\n  }\n}\n\n\n/***********************\n *** Spline16 filter ***\n ***********************/\n\ndouble Spline16Filter::f(double value) {\n  value = fabs(value);\n\n  if (value < 1.0) {\n    return ( ( value - 9.0/5.0 ) * value - 1.0/5.0 ) * value + 1.0;\n  } else if (value < 2.0) {\n    return ( ( -1.0/3.0 * (value-1.0) + 4.0/5.0 ) * (value-1.0) - 7.0/15.0 ) * (value-1.0);\n  }\n  return 0.0;\n}\n\n/***********************\n *** Spline36 filter ***\n ***********************/\n\ndouble Spline36Filter::f(double value) {\n  value = fabs(value);\n\n  if        (value < 1.0) {\n    return ( ( 13.0/11.0  * (value    ) - 453.0/ 209.0 ) * (value    ) -   3.0/ 209.0 ) *(value    ) + 1.0;\n  } else if (value < 2.0) {\n    return ( ( -6.0/11.0  * (value-1.0) + 270.0/ 209.0 ) * (value-1.0) - 156.0/ 209.0 ) *(value-1.0);\n  } else if (value < 3.0) {\n    return  ( ( 1.0/11.0  * (value-2.0) -  45.0/ 209.0 ) * (value-2.0) +  26.0/ 209.0 ) *(value-2.0);\n  }\n  return 0.0;\n}\n\n/***********************\n *** Spline64 filter ***\n ***********************/\n\ndouble Spline64Filter::f(double value) {\n  value = fabs(value);\n\n  if        (value < 1.0) {\n    return (( 49.0/41.0 * (value    ) - 6387.0/2911.0) * (value    ) -    3.0/2911.0) * (value    ) + 1.0;\n  } else if (value < 2.0) {\n    return ((-24.0/41.0 * (value-1.0) + 4032.0/2911.0) * (value-1.0) - 2328.0/2911.0) * (value-1.0);\n  } else if (value < 3.0) {\n    return ((  6.0/41.0 * (value-2.0) - 1008.0/2911.0) * (value-2.0) +  582.0/2911.0) * (value-2.0);\n  } else if (value < 4.0) {\n    return ((- 1.0/41.0 * (value-3.0) +  168.0/2911.0) * (value-3.0) -   97.0/2911.0) * (value-3.0);\n  }\n  return 0.0;\n}\n\n/***********************\n *** Gaussian filter ***\n ***********************/\n\n/* Solve taps from p*value*value < 9 as pow(2.0, -9.0) == 1.0/512.0 i.e 0.5 bit\n                     value*value < 9/p       p = param*0.1;\n                     value*value < 90/param\n                     value*value < 90/{0.1, 22.5, 30.0, 100.0}\n                     value*value < {900, 4.0, 3.0, 0.9}\n                     value       < {30, 2.0, 1.73, 0.949}         */\n\nGaussianFilter::GaussianFilter(double p, double _b, double _s) {\n  param = clamp(p, 0.01, 100.0);\n  b = clamp(_b, 1.5, 3.5);\n  s = _s;\n  if (_s == 0) // auto-support signal\n  {\n    // get support from b and param for 0.01 of resudual kernel value\n    // equatiion is s = sqrt(-ln(0.01)/(param*ln(b))\n    // where ln(0.01) is about -4.6 and -ln(0.01) is 4.6\n    s = sqrt(4.6 / ((param * 0.1) * log(b)));\n  }\n  s = clamp(s, 0.1, 150.0);\n}\n\ndouble GaussianFilter::f(double value) {\n  double p = param * 0.1;\n  return pow(b, -p * value * value); // <3.7.4: b was fixed at 2.0\n}\n\n/***********************\n *** Sinc filter ***\n ***********************/\nSincFilter::SincFilter(int _taps) {\n   taps = (double)clamp(_taps, 1, 150);\n}\n\ndouble SincFilter::f(double value) {\n  value = fabs(value);\n\n  if (value > 0.000001) {\n    value *= M_PI;\n    return sin(value)/value;\n  } else {\n    return 1.0;\n  }\n}\n\n\n/**********************\n*** SinPower filter ***\n***********************/\n\nSinPowerFilter::SinPowerFilter(double p) {\n  param = clamp(p, 1.0, 10.0);\n}\n\ndouble SinPowerFilter::f(double value) {\n  value = fabs(value);\n  value *= M_PI / param;\n\n  if (value < (M_PI / 2)) return pow(cos(value), 1.8);\n  else\n  {\n    if (value < M_PI) return -(cos(value) * cos(value)) / (0.9 * value);\n    else return 0;\n  }\n}\n\n/***********************\n*** SincLin2 filter ***\n***********************/\n\nSincLin2Filter::SincLin2Filter(int _taps)\n{\n  taps = (double)clamp(_taps, 1, 30);\n}\n\ndouble SincLin2Filter::sinc(double value)\n{\n  if (value > 0.000001)\n  {\n    value *= M_PI;\n    return sin(value) / value;\n  }\n  else return 1.0;\n}\n\ndouble SincLin2Filter::f(double value)\n{\n  value = fabs(value);\n\n  if (value < (taps / 2.0)) return sinc(value);\n  else return sinc(value) * ((2.0 - (2.0 * value / taps)));\n\n}\n\n\n/*********************************\n *** UserDefined2 filter ***\n *********************************/\n\nUserDefined2Filter::UserDefined2Filter(double _b, double _c, double _s)\n{\n  a = 1.0; // 0 sample = 1\n  b = (double)clamp(_b, -50.0, 250.0); // 1 and -1  sample\n  c = (double)clamp(_c, -50.0, 250.0); // 2 and -2 sample\n  b = (b - 16.0) / 219.0;\n  c = (c - 16.0) / 219.0;\n  s = (double)clamp(_s, 1.5, 15.0); // filter support for resampler\n}\n\ndouble UserDefined2Filter::sinc(double value)\n{\n\n  if (fabs(value) > 0.000001)\n  {\n    value *= M_PI;\n    return sin(value) / value;\n  }\n  else return 1.0;\n}\n\ndouble UserDefined2Filter::f(double x)\n{\n  x = fabs(x);\n\n  return c * sinc(x + 2) + b * sinc(x + 1) + a * sinc(x) + b * sinc(x - 1) + c * sinc(x - 2);\n}\n\n/*\n * OPTIMAL SCANLINE CALCULATION NOTES (L2 CACHE BLOCKING)\n *\n * This function calculates the optimal vertical strip size (max_scanline)\n * to be processed in a cache-blocked horizontal resizing operation.\n *\n * CONTEXT: Single-threaded, high-throughput workload with private L2 cache.\n * The high FPS target justifies a more aggressive cache reservation factor.\n *\n * 1. COEFFICIENT TABLE EXCLUSION (Horizontal 2x resize of fullhd content):\n * The coefficient table (~245 KB) is excluded from the calculation. It is\n * treated as a streamed resource due to its size relative to L2 (512 KB).\n * The hardware prefetcher is expected to handle its sequential access pattern\n * efficiently without residing fully in the reserved L2 working set.\n *\n * 2. CACHE RESERVATION HEURISTIC:\n * A factor of 0.75 (3/4) is reserved for the working set. This is an aggressive\n * approach for a single-threaded task with a private L2 cache, minimizing\n * cache thrashing risk from OS context switches while maximizing block size.\n *\n * 3. CONCRETE SCENARIO (512 KB L2, 1920->3840 upscale):\n * Reserved L2 space: 512 KB * 0.75 = 384 KB (393,216 bytes).\n * One scanline strip (src + tgt) is 23,040 bytes.\n * The resulting max_scanline is 17 (393,216 / 23,040 ~ 17.06).\n */\nint ResamplingProgram::resampler_h_detect_optimal_scanline(int src_width, int tgt_width, size_t l2_cache_size_bytes, size_t pixel_size) {\n  constexpr double CACHE_RESERVE_FACTOR = 0.75;\n\n  // Calculate the bytes needed for one (Source + Destination) scanline strip\n  size_t scanline_bytes = (static_cast<size_t>(src_width) + static_cast<size_t>(tgt_width)) * pixel_size;\n\n  // Calculate the reserved bytes based on the aggressive factor\n  // Use floating point math for precision, then cast to size_t\n  size_t reserved_l2_bytes = static_cast<size_t>(\n    static_cast<double>(l2_cache_size_bytes) * CACHE_RESERVE_FACTOR\n    );\n\n  // Calculate max_scanline (integer division for floor)\n  int max_scanline = static_cast<int>(reserved_l2_bytes / scanline_bytes);\n\n  // Clamp to practical bounds (4 to 64 is typical range for strip size)\n  // Dynamic by sample_size. For float32 (size=4) was 4 min and 64 max, so for uint8_t size=1 it will be 4x times more.\n  // Heuristic limits to avoid too small or too large strip sizes.\n  int iMinLimit;\n  int iMaxLimit;\n\n  switch (pixel_size)\n  {\n  case 4: // float\n    iMinLimit = 4;\n    iMaxLimit = 64;\n    break;\n  case 2: // uint16_t\n    iMinLimit = 8;\n    iMaxLimit = 128;\n    break;\n  case 1: // uint8_t\n    iMinLimit = 16;\n    iMaxLimit = 256;\n    break;\n  default: // should never happen\n    iMinLimit = 4;\n    iMaxLimit = 64;\n    break;\n  }\n\n  max_scanline = std::min(std::max(max_scanline, iMinLimit), iMaxLimit);\n\n  return max_scanline;\n}\n\n/**\n * @brief Checks if the data access pattern for horizontal resampling requires the slower Transpose method,\n * or if the faster Permutex approach can be used.\n *\n * This function determines the feasibility of using vector instructions (like AVX2/AVX-512 Permutex)\n * to load the source samples required for a group of output samples. This method is preferred when\n * the total spread of necessary source samples is small.\n *\n * @note This check is performed for methods that process multiple output sample groups per loop pass\n * (e.g., loading 2 groups of 8 samples for AVX-512).\n *\n * @param iSamplesInTheGroup       The number of output samples processed in one vector iteration (e.g., 8, 16, 64).\n * (Usually referred to as PIXELS_AT_A_TIME).\n * @param permutex_index_diff_limit The maximum byte/element difference allowed between the earliest and latest\n * required source sample for Permutex to be viable. This limit is dictated\n * by the specific Permutex intrinsic used (e.g., 8 for _mm256_permutevar8x32_ps).\n * @param kernel_size              The size of the resampling filter kernel (number of coefficients).\n * @return true                    If the source sample spread is too large, meaning only the Transpose method is allowed.\n * @return false                   If the source sample spread is small enough, meaning the Permutex method can be used.\n */\nbool ResamplingProgram::resize_h_planar_gather_permutex_vstripe_check(int iSamplesInTheGroup, int permutex_index_diff_limit, int kernel_size)\n{\n  // iSamplesInTheGroup is usually denoted as PIXELS_AT_A_TIME in H resampler code\n  // permutex_index_diff_limit is like iAccessibleSourceSamplesToGroup\n\n  // Alignment checks ensure safe access to pre-calculated arrays for the entire vector block.\n\n  // 'target_size_alignment' ensures safe access for the entire group (x to x + iSamplesInTheGroup - 1)\n  // Example: for iSamplesInTheGroup = 8, we need to ensure that\n  // - program->pixel_offset[x + 0] to program->pixel_offset[x + 7] and\n  // - corresponding coefficients (spread over coeff-strides like current_coeff + filter_size*0 to filter_size*7), where filter_size is the aligned coefficient stride.\n  // are valid if iSamplesInTheGroup = 8.\n  assert(target_size_alignment >= iSamplesInTheGroup);\n\n  // Ensure that coefficient loading is safe for \"kernel_size\" element loads.\n  // But this is not true. For float pixel types, we can keep the alignment to 8, which can be less than kernel_size.\n  // It's because it depends on the filter's implementation. E.g. resize_h_planar_float_avx512_permutex_vstripe_ks16 has kernel_size=16.\n  // However, it uses gather loads from coeffs, which do not need to be aligned to kernel_size.\n  // uint8_t avx512 versions with ks16 do need 32 byte alignment, the 'short' coefficients stride is aligned to 32 bytes, that is 16 coeffs.\n  // So in this case, we need the alignment.\n  // The check cannot be generalized here, it is put in the specific resampler implementations if needed.\n  // assert(filter_size_alignment >= kernel_size);\n\n  for (int x = 0; x < target_size; x += iSamplesInTheGroup) // check each group\n  {\n    // Get the index of the first required source sample for this group.\n    int start_off = pixel_offset[x + 0];\n\n    // Get the index of the last required source sample. This is the offset for the last\n    // output pixel in the group (x + iSamplesInTheGroup - 1) plus the last kernel tap (kernel_size - 1).\n    // Note: pixel_offset[] values for x >= target_size are pre-padded to match target_size-1 (ensured by resize_prepare_coeffs()).\n    const int end_off = pixel_offset[x + (iSamplesInTheGroup - 1)] + (kernel_size - 1);\n\n    // Check the total spread (difference) in source sample indices.\n    // This difference must be less than the limit imposed by the Permutex intrinsic's addressing capability.\n    // Examples of permutex_index_diff_limit:\n    // - 8 for _mm256_permutevar8x32_ps (float, avx2)\n    // - 32 for _mm512_permutex2var_ps (float, avx512)\n    // - 64 for _mm512_permutex2var_epi16 (uint16_t, avx512)\n    // - 128 for _mm512_permutex2var_epi8 (uint8_t, avx512)\n    if ((end_off - start_off) >= permutex_index_diff_limit) {\n      return true; // spread is too wide; only the transpose method is allowed.\n    }\n  }\n  return false; // Spread is acceptable; Permutex is OK.\n}\n\n\n/******************************\n **** Resampling Patterns  ****\n *****************************/\n\nResamplingProgram* ResamplingFunction::GetResamplingProgram(int source_size, double crop_start, double crop_size, int target_size, int bits_per_pixel, \n  double center_pos_src, double center_pos_dst,\n  IScriptEnvironment* env)\n{\n  // edge condition ideas from fmtconv, thanks.\n  double src_step = crop_size / double(target_size); // Distance between source pixels for adjacent dest pixels\n  double zc_size = std::max(src_step, 1.0) / 1.0;    // Size of filter unit step (kernel_scale=1.0 in our case)\n  double imp_step = 1.0 / zc_size;                   // Corresponding distance in the impulse\n  double filter_support = support() * zc_size;       // Number of source pixels covered by the FIR\n\n  int fir_filter_size = std::max(int(std::ceil(filter_support * 2)), 1);\n  int max_kernel_size = 0;\n\n  const int last_line = source_size - 1;\n\n  ResamplingProgram* program = new ResamplingProgram(fir_filter_size, source_size, target_size, crop_start, crop_size, bits_per_pixel, env);\n\n  // Initial position calculation\n\n  double pos = crop_start;\n\n  /*\n  pre 3.7.4 logic:\n\n  Now in 2025, let's fact-check this comment.\n\n    pos = crop_start + ((crop_size - target_size) / (target_size*2)); // TODO this look wrong, gotta check\n    ==>\n    pos = crop_start + 1/2 * (crop_size / target_size - 1)\n    ==>\n    pos = crop_start + src_step * 0.5 - 1 * 0.5\n\n    fmtconv generic formula:\n\n    pos = crop_start + src_step * center_pos_dst - 1 * center_pos_src; // 3.7.4- fmtconv\n\n    Solved: center_pos_dst = 0.5, center_pos_src = 0.5 in old Avisynth\n\n  */\n  \n  // Introduces an offset because samples are located at the center of the\n  // pixels, not on their boundaries. Excepted for pointresize.\n  if (filter_support > 0)\n  {\n    // Pre 3.7.4 Avisynth worked with fixed center_pos_dst = center_pos_src = 0.5\n    // Now it's externally configurable. In our use case they are always the same.\n    pos += src_step * center_pos_dst - 1 * center_pos_src;\n  }\n  else\n  {\n    // In case of PointResize(), which now returns real 0 for support().\n    // Avisynth heritage.\n    filter_support = 0.0001;\n  }\n\n  const int current_FPScale = (bits_per_pixel > 8 && bits_per_pixel <= 16) ? FPScale16 : FPScale;\n\n  std::vector<double> coef_tmp;\n  for (int i = 0; i < target_size; ++i) {\n    coef_tmp.clear();\n\n    int start_pos = (int)(pos + filter_support) - fir_filter_size + 1;\n    program->pixel_offset[i] = clamp(start_pos, 0, last_line);\n\n    // First pass: Accumulate all coefficients for weighting\n    double total = 0.0;\n    for (int k = 0; k < fir_filter_size; ++k) {\n      const int p = start_pos + k;\n      double val = f((pos - p) * imp_step);\n      coef_tmp.push_back(val);\n      total += val;\n    }\n\n    if (total == 0.0) {\n      // Shouldn't happen for valid positions.\n      total = 1.0;\n    }\n\n    const int coeff_arr_base_index = i * fir_filter_size;\n\n    // Second pass: Generate real coefficients, handling edge conditions\n    double accu = 0.0;\n    double prev_value = 0.0;\n\n    int kernel_size = 0;\n\n    if (bits_per_pixel == 32) {\n      // Float version\n      for (int k = 0; k < fir_filter_size; ++k) {\n        const int p = start_pos + k;\n        double val = coef_tmp[k];\n        accu += val;\n        if (p >= 0 && p <= last_line) {\n          program->pixel_coefficient_float[coeff_arr_base_index + kernel_size] = float(accu / total);\n          ++kernel_size;\n          accu = 0;\n        }\n      }\n    }\n    else {\n      // Integer version - using upscaled integer arithmetic (FPScale/FPScale16)\n      for (int k = 0; k < fir_filter_size; ++k) {\n        const int p = start_pos + k;\n        double val = coef_tmp[k];\n        accu += val;\n        if (p >= 0 && p <= last_line) {\n          double new_value = prev_value + accu / total;\n          // differential approach ensures the filter coefficients sum to exactly FPScale) \n          // The subtraction method guarantees that no matter how many terms we add, the \n          // final sum will be exactly equal to the fixed-point representation of 1.0.\n          program->pixel_coefficient[coeff_arr_base_index + kernel_size] = (short)((int)(new_value * current_FPScale + 0.5) - int(prev_value * current_FPScale + 0.5));\n          prev_value = new_value;\n          ++kernel_size;\n          accu = 0;\n        }\n      }\n    }\n\n    // We even haven't reached any valid line, \n    // or gathered accu values from past last line.\n    if (accu != 0)\n    {\n      if (kernel_size > 0) {\n        // Assign the remaining accumulator to the last line, just like we put \n        // the accumulator before the first valid line to the first line.\n        if (bits_per_pixel == 32)\n          program->pixel_coefficient_float[coeff_arr_base_index + kernel_size - 1] += float(accu / total);\n        else {\n          double new_value = prev_value + accu / total;\n          program->pixel_coefficient[coeff_arr_base_index + kernel_size - 1] += (short)((int)(new_value * current_FPScale + 0.5) - int(prev_value * current_FPScale + 0.5));\n        }\n        // no change in kernel_size\n      }\n      else\n      {\n        // new entry, accu/total must be 1.0 here (we always normalize)\n        if (bits_per_pixel == 32)\n          program->pixel_coefficient_float[coeff_arr_base_index + kernel_size] = float(accu / total);\n        else\n          program->pixel_coefficient[coeff_arr_base_index + kernel_size] = (short)((int)(accu / total * current_FPScale + 0.5));\n        ++kernel_size;\n      }\n    }\n\n    if (kernel_size == 0) {\n      // write a single 1.0 coeff entry\n      if (bits_per_pixel == 32)\n        program->pixel_coefficient_float[coeff_arr_base_index + kernel_size] = 1.0f;\n      else\n        program->pixel_coefficient[coeff_arr_base_index + kernel_size] = (short)((int)(1.0 * current_FPScale + 0.5));\n      ++kernel_size;\n    }\n\n    program->kernel_sizes[i] = kernel_size;\n    if (kernel_size > max_kernel_size) max_kernel_size = kernel_size;\n\n    pos += src_step;\n  }\n\n  // the different kernel sizes and coeff table will be later postprocessed\n  // to have aligned and equally sized coefficients.\n\n  program->filter_size_real = max_kernel_size; \n  // can be less than original filter size if source dimensions are small\n  \n  return program;\n}\n\n\n#if 0\n// old pre 3.7.4, kept for reference\nResamplingProgram* ResamplingFunction::GetResamplingProgram(int source_size, double crop_start, double crop_size, int target_size, int bits_per_pixel, IScriptEnvironment* env)\n{\n  double filter_scale = double(target_size) / crop_size;\n  double filter_step = min(filter_scale, 1.0);\n  double filter_support = support() / filter_step;\n  int fir_filter_size = int(ceil(filter_support*2));\n\n  ResamplingProgram* program = new ResamplingProgram(fir_filter_size, source_size, target_size, crop_start, crop_size, bits_per_pixel, env);\n\n  // this variable translates such that the image center remains fixed\n  double pos;\n  double pos_step = crop_size / target_size;\n\n  if (source_size <= filter_support) {\n    env->ThrowError(\"Resize: Source image too small for this resize method. Width=%d, Support=%d\", source_size, int(ceil(filter_support)));\n  }\n\n  if (fir_filter_size == 1) // PointResize\n    pos = crop_start;\n  else\n    pos = crop_start + ((crop_size - target_size) / (target_size*2)); // TODO this look wrong, gotta check\n\n  const int current_FPScale = (bits_per_pixel > 8 && bits_per_pixel <= 16) ? FPScale16 : FPScale;\n\n  for (int i = 0; i < target_size; ++i) {\n    // Clamp start and end position such that it does not exceed frame size\n    int end_pos = int(pos + filter_support);\n\n    if (end_pos > source_size-1)\n      end_pos = source_size-1;\n\n    int start_pos = end_pos - fir_filter_size + 1;\n\n    if (start_pos < 0)\n      start_pos = 0;\n\n    program->pixel_offset[i] = start_pos;\n\n    // check the simd-optimized (8 pixels and filter coefficients at a time) limit to not reach beyond the last pixel\n    // in order not to have NaN floats\n    if (start_pos + AlignNumber(fir_filter_size, ALIGN_FLOAT_RESIZER_COEFF_SIZE) - 1 > source_size - 1)\n    {\n      if (!program->overread_possible_filter_size_aligned) {\n        // register the first occurance\n        program->overread_possible_filter_size_aligned = true;\n        program->source_overread_offset = start_pos;\n        program->source_overread_beyond_targetx = i;\n      }\n    }\n\n    // the following code ensures that the coefficients add to exactly FPScale or FPScale16\n    double total = 0.0;\n\n    // Ensure that we have a valid position\n    double ok_pos = clamp(pos, 0.0, (double)(source_size-1));\n\n    // Accumulate all coefficients for weighting\n    for (int j = 0; j < fir_filter_size; ++j) {\n      total += f((start_pos+j - ok_pos) * filter_step);\n    }\n\n    if (total == 0.0) {\n      // Shouldn't happened for valid positions.\n      total = 1.0;\n    }\n\n    double value = 0.0;\n\n    // Now we generate real coefficient\n    if (bits_per_pixel == 32) {\n      // float\n      for (int k = 0; k < fir_filter_size; ++k) {\n        double new_value = value + f((start_pos + k - ok_pos) * filter_step) / total;\n        program->pixel_coefficient_float[i*fir_filter_size + k] = float(new_value - value); // no scaling for float\n        value = new_value;\n      }\n    }\n    else {\n      for (int k = 0; k < fir_filter_size; ++k) {\n        double new_value = value + f((start_pos + k - ok_pos) * filter_step) / total;\n        // FIXME: is it correct to round negative values upwards?\n        // Answer : No with int cast, yes with floor() instead.\n        program->pixel_coefficient[i*fir_filter_size + k] = (short)((int)(new_value*current_FPScale + 0.5) - int(value*current_FPScale + 0.5)); // to make it round across pixels\n        value = new_value;\n      }\n    }\n\n    pos += pos_step;\n  }\n\n  // aligned as 8, now fill with safe values for 8 pixels/cycle simd loop\n  for (int i = target_size; i < AlignNumber(target_size, ALIGN_RESIZER_TARGET_SIZE); ++i)\n    program->pixel_offset[i] = source_size - fir_filter_size;\n\n  return program;\n}\n#endif\n"
  },
  {
    "path": "avs_core/filters/resample_functions.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Resample_Functions_H__\n#define __Resample_Functions_H__\n\n#include <avisynth.h>\n#include \"avs/alignment.h\"\n#include <vector>\n#include <stdint.h>\n\n// Original value: 65536\n// 2 bits sacrificed because of 16 bit signed MMX multiplication\n// NOTE: Don't change this value. It's hard-coded in SIMD code.\nconstexpr int FPScale8bits = 14; // fixed point scaler 14 bit\nconstexpr int FPScale = 1 << FPScale8bits; // fixed point scaler (1<<14)\n// for 16 bits: one bit less\nconstexpr int FPScale16bits = 13;\nconstexpr int FPScale16 = 1 << FPScale16bits; // fixed point scaler for 10-16 bit SIMD signed operation\n// 16: fits even avx512 32-bit float Horizontal\n// but not AVX512 uint8 case, where we process 64 pixels at a time\nconstexpr int ALIGN_RESIZER_TARGET_SIZE = 64;\nstruct SafeLimit {\n  bool overread_possible;\n  int source_overread_offset;\n  int source_overread_beyond_targetx;\n};\n#define M_PI 3.14159265358979323846\n\nstruct ResamplingProgram {\n  IScriptEnvironment * Env;\n  int source_size, target_size;\n  double crop_start, crop_size;\n  int filter_size;\n  int filter_size_real; // maybe less than filter_size if dimensions are small\n  int filter_size_alignment; // for info, 1 (C, nonvector-friendly), 8 (sse or avx2) or 16 (avx2)\n  int target_size_alignment; // coeff table exists (and containt zero coeffs) even beyond target_size. Helps alternative H resizers.\n\n  // Array of Integer indicate starting point of sampling\n  std::vector<int> pixel_offset;\n\n  int bits_per_pixel;\n\n  // Array of array of coefficient for each pixel\n  // {{pixel[0]_coeff}, {pixel[1]_coeff}, ...}\n  short* pixel_coefficient;\n  float* pixel_coefficient_float;\n  // Array of real kernel size, handles edge cases! <= filter_size\n  // for SIMD, coefficients are copied over a padded aligned storage\n  std::vector<short> kernel_sizes; // temporary, used during setup only\n  // 3.7.4- can be different for each line but then they get equalized and aligned.\n\n  size_t cache_size_L2; // in bytes, for possible use in resizers\n  int max_scanlines; // recommended vertical stripe for h resamplers\n\n  // In H resizers, when using SIMD loads for speed, these is a \"danger zone\".\n  // If SIMD load from source pixels (src+offset) over reads beyond the allocated\n  // source buffer (image scanline width), it can cause access violation.\n  // The following SafeLimit structures indicate such cases for various SIMD sizes.\n  // and how much to adjust the source pointer to avoid access violation\n  // or stop using large SIMD loads after this limit.\n  // Depending on the pixel actual size (1, 2 or 4 bytes) and filter size,\n  // the overread size can be calculated and the appropriate SafeLimit entry is used\n  // by the actual implementation of the resizer.\n  SafeLimit safelimit_filter_size_aligned = { false, -1, -1 };\n  SafeLimit safelimit_4_pixels = { false, -1, -1 };\n  SafeLimit safelimit_8_pixels = { false, -1, -1 };\n  SafeLimit safelimit_16_pixels = { false, -1, -1 };\n  SafeLimit safelimit_32_pixels = { false, -1, -1 };\n  SafeLimit safelimit_8_pixels_each8th_target = { false, -1, -1 };\n  SafeLimit safelimit_16_pixels_each16th_target = { false, -1, -1 };\n  SafeLimit safelimit_64_pixels_each32th_target = { false, -1, -1 };\n  SafeLimit safelimit_128_pixels_each64th_target = { false, -1, -1 };\n\n  int resampler_h_detect_optimal_scanline(int src_width, int tgt_width, size_t l2_cache_size_bytes, size_t pixel_size);\n  bool resize_h_planar_gather_permutex_vstripe_check(int iSamplesInTheGroup, int permutex_index_diff_limit, int kernel_size);\n\n\n  ResamplingProgram(int filter_size, int source_size, int target_size, double crop_start, double crop_size, int bits_per_pixel, IScriptEnvironment* env)\n    : Env(env), source_size(source_size), target_size(target_size), crop_start(crop_start), crop_size(crop_size), filter_size(filter_size), filter_size_real(filter_size),\n    bits_per_pixel(bits_per_pixel), pixel_coefficient(0), pixel_coefficient_float(0), cache_size_L2(0), max_scanlines(0)\n  {\n\n    filter_size_alignment = 1;\n    // align target_size to 8 units to allow safe up to 8 pixels/cycle in H resizers. modded later.\n    target_size_alignment = 1;\n    // resize_prepare_coeff can override and realign the size of coefficient table\n    if (bits_per_pixel < 32)\n      pixel_coefficient = (short*)Env->Allocate(sizeof(short) * target_size * filter_size, 64, AVS_NORMAL_ALLOC);\n    else\n      pixel_coefficient_float = (float*)Env->Allocate(sizeof(float) * target_size * filter_size, 64, AVS_NORMAL_ALLOC);\n\n    pixel_offset.resize(target_size);\n    kernel_sizes.resize(target_size);\n\n    if ((pixel_coefficient == nullptr && bits_per_pixel < 32) ||\n        (pixel_coefficient_float == nullptr && bits_per_pixel == 32)) {\n      Env->Free(pixel_coefficient);\n      Env->Free(pixel_coefficient_float);\n      Env->ThrowError(\"ResamplingProgram: Could not reserve memory.\");\n    }\n\n    cache_size_L2 = env->GetEnvProperty(AEP_CACHESIZE_L2);\n    const int pixel_size_bytes = (bits_per_pixel + 7) / 8;\n    max_scanlines = resampler_h_detect_optimal_scanline(source_size, target_size, cache_size_L2, pixel_size_bytes);\n\n  };\n\n  ~ResamplingProgram() {\n    Env->Free(pixel_coefficient);\n    Env->Free(pixel_coefficient_float);\n  };\n};\n\ntypedef struct ResamplingProgram ResamplingProgram;\n\n\n/*******************************************\n   ***************************************\n   **  Helper classes for resample.cpp  **\n   ***************************************\n *******************************************/\n\n\nclass ResamplingFunction\n/**\n  * Pure virtual base class for resampling functions\n  */\n{\npublic:\n  virtual double f(double x) = 0;\n  virtual double support() = 0;\n\n  virtual ResamplingProgram* GetResamplingProgram(int source_size, double crop_start, double crop_size, int target_size, int bits_per_pixel, \n    double center_pos_src, double center_pos_dst,\n    IScriptEnvironment* env);\n  virtual ~ResamplingFunction() = default;\n  // virtual bool CheckValidity(int source_size, double crop_size, int target_size);\n};\n\nclass PointFilter : public ResamplingFunction\n/**\n  * Nearest neighbour (point sampler), used in PointResize\n **/\n{\npublic:\n  double f(double x);\n  double support() { return 0; }  \n  // Pre 3.7.4 : 0.0001. Comment: 0.0 crashes it. \n  // 3.7.4- this 0 is specially handled in GetResamplingProgram\n};\n\n\nclass TriangleFilter : public ResamplingFunction\n/**\n  * Simple triangle filter, used in BilinearResize\n **/\n{\npublic:\n  double f(double x);\n  double support() { return 1.0; }\n};\n\n\nclass MitchellNetravaliFilter : public ResamplingFunction\n/**\n  * Mitchell-Netraveli filter, used in BicubicResize\n **/\n{\npublic:\n  MitchellNetravaliFilter(double b = 1. / 3., double c = 1. / 3.);\n  double f(double x);\n  double support() { return 2.0; }\n\nprivate:\n  double p0,p2,p3,q0,q1,q2,q3;\n};\n\nclass LanczosFilter : public ResamplingFunction\n/**\n  * Lanczos filter, used in LanczosResize\n **/\n{\npublic:\n  LanczosFilter(int _taps = 3);\n\tdouble f(double x);\n\tdouble support() { return taps; };\n\nprivate:\n\tdouble sinc(double value);\n  double taps;\n};\n\nclass BlackmanFilter : public ResamplingFunction\n/**\n  * Blackman filter, used in BlackmanResize\n **/\n{\npublic:\n  BlackmanFilter(int _taps = 4);\n\tdouble f(double x);\n\tdouble support() { return taps; };\n\nprivate:\n  double taps, rtaps;\n};\n\n// Spline16\nclass Spline16Filter : public ResamplingFunction\n/**\n  * Spline16 of Panorama Tools is a cubic-spline, with derivative set to 0 at the edges (4x4 pixels).\n **/\n{\npublic:\n\tdouble f(double x);\n\tdouble support() { return 2.0; };\n\nprivate:\n};\n\n// Spline36\nclass Spline36Filter : public ResamplingFunction\n/**\n  * Spline36 is like Spline16,  except that it uses 6x6=36 pixels.\n **/\n{\npublic:\n\tdouble f(double x);\n\tdouble support() { return 3.0; };\n\nprivate:\n};\n\n// Spline64\nclass Spline64Filter : public ResamplingFunction\n/**\n  * Spline64 is like Spline36,  except that it uses 8x8=64 pixels.\n **/\n{\npublic:\n\tdouble f(double x);\n\tdouble support() { return 4.0; };\n\nprivate:\n};\n\n\nclass GaussianFilter : public ResamplingFunction\n/**\n  * GaussianFilter, from swscale.\n **/\n{\npublic:\n  GaussianFilter(double p = 30.0, double _b = 2.0, double _s = 4.0);\n  double f(double x);\n  double support() { return s; }; // <3.7.4 was fixed at 4.0\n\nprivate:\n  double param;\n  double b; // base value since 3.7.4\n  double s; // variable support since 3.7.4\n};\n\nclass SincFilter : public ResamplingFunction\n/**\n  * Sinc filter, used in SincResize\n **/\n{\npublic:\n  SincFilter(int _taps = 4);\n\tdouble f(double x);\n\tdouble support() { return taps; };\n\nprivate:\n  double taps;\n};\n\nclass SinPowerFilter : public ResamplingFunction\n  // SinPow kernel, used in SinPowResize\n{\npublic:\n  SinPowerFilter(double p = 2.5);\n  double f(double x);\n  double support() { return 2.0; }; // 2 very important, 4 cause bugs\n\nprivate:\n  double param;\n};\n\nclass SincLin2Filter : public ResamplingFunction\n  /**\n  * SincLin2 filter, used in SincLin2Resize\n  **/\n{\npublic:\n  SincLin2Filter(int _taps = 15);\n  double f(double x);\n  double support() { return taps; };\n\nprivate:\n  double sinc(double value);\n  double taps;\n};\n\nclass UserDefined2Filter : public ResamplingFunction\n\t/**\n\t  * User-defined by 2 samples filter, used in UDef2Resize\n\t **/\n{\npublic:\n\tUserDefined2Filter(double _b, double _c, double _s);\n\tdouble f(double x);\n\tdouble support() { return s; }\n\nprivate:\n\tdouble sinc(double value);\n  double a, b, c;\n  double s; // 'support' as a parameter\n};\n\n#endif  // __Reample_Functions_H__\n"
  },
  {
    "path": "avs_core/filters/resize.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include \"resize.h\"\n#ifdef INTEL_INTRINSICS\n#include \"intel/resize_sse.h\"\n#endif\n#include \"../core/internal.h\"\n#include <avs/alignment.h>\n#include <stdint.h>\n#include <type_traits>\n\n\n/********************************************************************\n***** Declare index of new filters for Avisynth's filter engine *****\n********************************************************************/\n\nextern const AVSFunction Resize_filters[] = {\n  { \"VerticalReduceBy2\",   BUILTIN_FUNC_PREFIX, \"c\", VerticalReduceBy2::Create },        // src clip\n  { \"HorizontalReduceBy2\", BUILTIN_FUNC_PREFIX, \"c\", HorizontalReduceBy2::Create },    // src clip\n  { \"ReduceBy2\",           BUILTIN_FUNC_PREFIX, \"c\", Create_ReduceBy2 },                         // src clip\n  { 0 }\n};\n\ntemplate<typename pixel_t>\nstatic void vertical_reduce_c(BYTE* _dstp, const BYTE* _srcp, int _dst_pitch, int _src_pitch, size_t row_size, size_t height) {\n  size_t width = row_size / sizeof(pixel_t);\n  int dst_pitch = _dst_pitch / sizeof(pixel_t);\n  int src_pitch = _src_pitch / sizeof(pixel_t);\n  const pixel_t* srcp = reinterpret_cast<const pixel_t*>(_srcp);\n  pixel_t* dstp = reinterpret_cast<pixel_t*>(_dstp);\n\n  const pixel_t* srcp_next = srcp + src_pitch;\n  const pixel_t* srcp_next2 = srcp + src_pitch * 2;\n\n  pixel_t rounding;\n  if (!std::is_floating_point<pixel_t>::value)\n    rounding = 2;\n  else\n    rounding = 0; // float: no rounding\n\n  for (size_t y = 0; y < height - 1; ++y) {\n    for (size_t x = 0; x < width; ++x) {\n      dstp[x] = (srcp[x] + 2 * srcp_next[x] + srcp_next2[x] + rounding) / 4; // >> 2; /4 float friendly\n    }\n    dstp += dst_pitch;\n    srcp += src_pitch * 2;\n    srcp_next += src_pitch * 2;\n    srcp_next2 += src_pitch * 2;\n  }\n  for (size_t x = 0; x < width; ++x) {\n    dstp[x] = (srcp[x] + 3 * srcp_next[x] + rounding) / 4; // >> 2; /4 float friendly\n  }\n}\n\nvoid vertical_reduce_core(BYTE* dstp, const BYTE* srcp, int dst_pitch, int src_pitch, int row_size, int height, int pixelsize, IScriptEnvironment* env) {\n  if (!srcp) {\n    return;\n  }\n#ifdef INTEL_INTRINSICS\n  if (pixelsize == 1 && (env->GetCPUFlags() & CPUF_SSE2) && IsPtrAligned(srcp, 16) && row_size >= 16) {\n    vertical_reduce_sse2(dstp, srcp, dst_pitch, src_pitch, row_size, height);\n  }\n  else\n#ifdef X86_32\n    if (pixelsize == 1 && (env->GetCPUFlags() & CPUF_MMX) && row_size >= 8) {\n      vertical_reduce_mmx(dstp, srcp, dst_pitch, src_pitch, row_size, height);\n    }\n    else\n#endif\n#endif\n      switch (pixelsize) {\n      case 1: vertical_reduce_c<uint8_t>(dstp, srcp, dst_pitch, src_pitch, row_size, height); break;\n      case 2: vertical_reduce_c<uint16_t>(dstp, srcp, dst_pitch, src_pitch, row_size, height); break;\n      default: //case 4:\n        vertical_reduce_c<float>(dstp, srcp, dst_pitch, src_pitch, row_size, height); break;\n      }\n\n}\n\n\n/*************************************\n ******* Vertical 2:1 Reduction ******\n ************************************/\n\n\nVerticalReduceBy2::VerticalReduceBy2(PClip _child, IScriptEnvironment* env)\n  : GenericVideoFilter(_child)\n{\n  if (vi.IsPlanar() && (vi.IsYUV() || vi.IsYUVA()) && (vi.NumComponents() > 1)) {\n    const int mod = 2 << vi.GetPlaneHeightSubsampling(PLANAR_U);\n    const int mask = mod - 1;\n    if (vi.height & mask)\n      env->ThrowError(\"VerticalReduceBy2: Planar source height must be divisible by %d.\", mod);\n  }\n\n  if (vi.height & 1)\n    env->ThrowError(\"VerticalReduceBy2: Image height must be even\");\n\n  original_height = vi.height;\n  vi.height >>= 1;\n\n  if (vi.height < 3) {\n    env->ThrowError(\"VerticalReduceBy2: Image too small to be reduced by 2.\");\n  }\n}\n\n\nPVideoFrame VerticalReduceBy2::GetFrame(int n, IScriptEnvironment* env) {\n  PVideoFrame src = child->GetFrame(n, env);\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n  int pixelsize = vi.ComponentSize();\n\n  if (vi.IsPlanar()) {\n    int planesYUV[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };\n    int planesRGB[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A };\n    int* planes = vi.IsYUV() || vi.IsYUVA() ? planesYUV : planesRGB;\n    for (int p = 0; p < vi.NumComponents(); p++)\n    {\n      int plane = planes[p];\n      vertical_reduce_core(dst->GetWritePtr(plane), src->GetReadPtr(plane), dst->GetPitch(plane), src->GetPitch(plane), dst->GetRowSize(plane), dst->GetHeight(plane), pixelsize, env);\n    }\n  }\n  else {\n    int src_pitch = src->GetPitch();\n    int dst_pitch = dst->GetPitch();\n    int row_size = src->GetRowSize();\n    BYTE* dstp = dst->GetWritePtr();\n    const BYTE* srcp = src->GetReadPtr();\n    vertical_reduce_core(dstp, srcp, dst_pitch, src_pitch, row_size, vi.height, pixelsize, env);\n  }\n  return dst;\n}\n\n\n/************************************\n **** Horizontal 2:1 Reduction ******\n ***********************************/\n\nHorizontalReduceBy2::HorizontalReduceBy2(PClip _child, IScriptEnvironment* env)\n  : GenericVideoFilter(_child)\n{\n  if (vi.IsPlanar() && (vi.IsYUV() || vi.IsYUVA()) && (vi.NumComponents() > 1)) {\n    const int mod = 2 << vi.GetPlaneWidthSubsampling(PLANAR_U);\n    const int mask = mod - 1;\n    if (vi.width & mask)\n      env->ThrowError(\"HorizontalReduceBy2: Planar source width must be divisible by %d.\", mod);\n  }\n\n  if (vi.width & 1)\n    env->ThrowError(\"HorizontalReduceBy2: Image width must be even\");\n\n  if (vi.IsYUY2() && (vi.width & 3))\n    env->ThrowError(\"HorizontalReduceBy2: YUY2 output image width must be even\");\n\n  pixelsize = vi.ComponentSize();\n  source_width = vi.width;\n  vi.width >>= 1;\n}\n\ntemplate<typename pixel_t>\nstatic void horizontal_reduce_core(PVideoFrame& dst, PVideoFrame& src, int plane) {\n\n  pixel_t rounding;\n  if (!std::is_floating_point<pixel_t>::value)\n    rounding = 1;\n  else\n    rounding = 0; // float: no rounding\n\n  const pixel_t* srcp = reinterpret_cast<const pixel_t*>(src->GetReadPtr(plane));\n  pixel_t* dstp = reinterpret_cast<pixel_t*>(dst->GetWritePtr(plane));\n  int src_gap = (src->GetPitch(plane) - src->GetRowSize(plane)) / sizeof(pixel_t);  //aka 'modulo' in VDub filter terminology\n  int dst_gap = (dst->GetPitch(plane) - dst->GetRowSize(plane)) / sizeof(pixel_t);\n  int yloops = dst->GetHeight(plane);\n  int xloops = dst->GetRowSize(plane) / sizeof(pixel_t) - 1;\n  for (int y = 0; y < yloops; y++) {\n    for (int x = 0; x < xloops; x++) {\n      *dstp = (srcp[0] + 2 * srcp[1] + srcp[2] + rounding * 2) / 4; // >> 2; float-friendly\n      dstp++;\n      srcp += 2;\n    }\n    *dstp = (srcp[0] + srcp[1] + rounding) / 2; // >> 1; float-friendly\n    dstp += dst_gap + 1;\n    srcp += src_gap + 2;\n  }\n}\n\nPVideoFrame HorizontalReduceBy2::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame src = child->GetFrame(n, env);\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n  if (vi.IsPlanar()) {\n\n    int planesYUV[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };\n    int planesRGB[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A };\n    int* planes = vi.IsYUV() || vi.IsYUVA() ? planesYUV : planesRGB;\n    for (int p = 0; p < vi.NumComponents(); p++)\n    {\n      int plane = planes[p];\n      switch (pixelsize) {\n      case 1: horizontal_reduce_core<uint8_t>(dst, src, plane); break;\n      case 2: horizontal_reduce_core<uint16_t>(dst, src, plane); break;\n      default: // case 4:\n        horizontal_reduce_core<float>(dst, src, plane); break;\n      }\n    }\n    return dst;\n  }\n\n  int src_gap = src->GetPitch() - src->GetRowSize();  //aka 'modulo' in VDub filter terminology\n  int dst_gap = dst->GetPitch() - dst->GetRowSize();\n\n  BYTE* dstp = dst->GetWritePtr();\n\n  if (vi.IsYUY2() && (!(vi.width & 1))) {\n\n    const BYTE* srcp = src->GetReadPtr();\n    for (int y = vi.height; y > 0; --y) {\n      for (int x = (vi.width >> 1) - 1; x; --x) {\n        dstp[0] = (srcp[0] + 2 * srcp[2] + srcp[4] + 2) >> 2;\n        dstp[1] = (srcp[1] + 2 * srcp[5] + srcp[9] + 2) >> 2;\n        dstp[2] = (srcp[4] + 2 * srcp[6] + srcp[8] + 2) >> 2;\n        dstp[3] = (srcp[3] + 2 * srcp[7] + srcp[11] + 2) >> 2;\n        dstp += 4;\n        srcp += 8;\n      }\n      dstp[0] = (srcp[0] + 2 * srcp[2] + srcp[4] + 2) >> 2;\n      dstp[1] = (srcp[1] + srcp[5] + 1) >> 1;\n      dstp[2] = (srcp[4] + srcp[6] + 1) >> 1;\n      dstp[3] = (srcp[3] + srcp[7] + 1) >> 1;\n      dstp += dst_gap + 4;\n      srcp += src_gap + 8;\n\n    }\n  }\n  else if (vi.IsRGB24() || vi.IsRGB48()) {\n    const BYTE* srcp = src->GetReadPtr();\n    if (pixelsize == 1) {\n      for (int y = vi.height; y > 0; --y) {\n        for (int x = (source_width - 1) >> 1; x; --x) {\n          dstp[0] = (srcp[0] + 2 * srcp[3] + srcp[6] + 2) >> 2;\n          dstp[1] = (srcp[1] + 2 * srcp[4] + srcp[7] + 2) >> 2;\n          dstp[2] = (srcp[2] + 2 * srcp[5] + srcp[8] + 2) >> 2;\n          dstp += 3;\n          srcp += 6;\n        }\n        if (source_width & 1) {\n          dstp += dst_gap;\n          srcp += src_gap + 3;\n        }\n        else {\n          dstp[0] = (srcp[0] + srcp[3] + 1) >> 1;\n          dstp[1] = (srcp[1] + srcp[4] + 1) >> 1;\n          dstp[2] = (srcp[2] + srcp[5] + 1) >> 1;\n          dstp += dst_gap + 3;\n          srcp += src_gap + 6;\n        }\n      }\n    }\n    else { // pixelsize==2 RGB48\n      uint16_t* dstp16 = reinterpret_cast<uint16_t*>(dstp);\n      const uint16_t* srcp16 = reinterpret_cast<const uint16_t*>(srcp);\n      dst_gap /= sizeof(uint16_t);\n      src_gap /= sizeof(uint16_t);\n      for (int y = vi.height; y > 0; --y) {\n        for (int x = (source_width - 1) >> 1; x; --x) {\n          dstp16[0] = (srcp16[0] + 2 * srcp16[3] + srcp16[6] + 2) >> 2;\n          dstp16[1] = (srcp16[1] + 2 * srcp16[4] + srcp16[7] + 2) >> 2;\n          dstp16[2] = (srcp16[2] + 2 * srcp16[5] + srcp16[8] + 2) >> 2;\n          dstp16 += 3;\n          srcp16 += 6;\n        }\n        if (source_width & 1) {\n          dstp16 += dst_gap;\n          srcp16 += src_gap + 3;\n        }\n        else {\n          dstp16[0] = (srcp16[0] + srcp16[3] + 1) >> 1;\n          dstp16[1] = (srcp16[1] + srcp16[4] + 1) >> 1;\n          dstp16[2] = (srcp16[2] + srcp16[5] + 1) >> 1;\n          dstp16 += dst_gap + 3;\n          srcp16 += src_gap + 6;\n        }\n      }\n    }\n  }\n  else if (vi.IsRGB32() || vi.IsRGB64()) {  //rgb32\n    const BYTE* srcp = src->GetReadPtr();\n    if (pixelsize == 1) {\n      for (int y = vi.height; y > 0; --y) {\n        for (int x = (source_width - 1) >> 1; x; --x) {\n          dstp[0] = (srcp[0] + 2 * srcp[4] + srcp[8] + 2) >> 2;\n          dstp[1] = (srcp[1] + 2 * srcp[5] + srcp[9] + 2) >> 2;\n          dstp[2] = (srcp[2] + 2 * srcp[6] + srcp[10] + 2) >> 2;\n          dstp[3] = (srcp[3] + 2 * srcp[7] + srcp[11] + 2) >> 2;\n          dstp += 4;\n          srcp += 8;\n        }\n        if (source_width & 1) {\n          dstp += dst_gap;\n          srcp += src_gap + 4;\n        }\n        else {\n          dstp[0] = (srcp[0] + srcp[4] + 1) >> 1;\n          dstp[1] = (srcp[1] + srcp[5] + 1) >> 1;\n          dstp[2] = (srcp[2] + srcp[6] + 1) >> 1;\n          dstp[3] = (srcp[3] + srcp[7] + 1) >> 1;\n          dstp += dst_gap + 4;\n          srcp += src_gap + 8;\n        }\n      }\n    }\n    else { // pixelsize==2 rgb64\n      uint16_t* dstp16 = reinterpret_cast<uint16_t*>(dstp);\n      const uint16_t* srcp16 = reinterpret_cast<const uint16_t*>(srcp);\n      dst_gap /= sizeof(uint16_t);\n      src_gap /= sizeof(uint16_t);\n      for (int y = vi.height; y > 0; --y) {\n        for (int x = (source_width - 1) >> 1; x; --x) {\n          dstp16[0] = (srcp16[0] + 2 * srcp16[4] + srcp16[8] + 2) >> 2;\n          dstp16[1] = (srcp16[1] + 2 * srcp16[5] + srcp16[9] + 2) >> 2;\n          dstp16[2] = (srcp16[2] + 2 * srcp16[6] + srcp16[10] + 2) >> 2;\n          dstp16[3] = (srcp16[3] + 2 * srcp16[7] + srcp16[11] + 2) >> 2;\n          dstp16 += 4;\n          srcp16 += 8;\n        }\n        if (source_width & 1) {\n          dstp16 += dst_gap;\n          srcp16 += src_gap + 4;\n        }\n        else {\n          dstp16[0] = (srcp16[0] + srcp16[4] + 1) >> 1;\n          dstp16[1] = (srcp16[1] + srcp16[5] + 1) >> 1;\n          dstp16[2] = (srcp16[2] + srcp16[6] + 1) >> 1;\n          dstp16[3] = (srcp16[3] + srcp16[7] + 1) >> 1;\n          dstp16 += dst_gap + 4;\n          srcp16 += src_gap + 8;\n        }\n      }\n    }\n  }\n  return dst;\n}\n\n/**************************************\n *****  ReduceBy2 Factory Method  *****\n *************************************/\n\n\nAVSValue __cdecl Create_ReduceBy2(AVSValue args, void*, IScriptEnvironment* env)\n{\n  return new HorizontalReduceBy2(new VerticalReduceBy2(args[0].AsClip(), env), env);\n}\n\n\n\n"
  },
  {
    "path": "avs_core/filters/resize.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Resize_H__\n#define __Resize_H__\n\n#include <avisynth.h>\n\n/********************************************************************\n********************************************************************/\n\nclass VerticalReduceBy2 : public GenericVideoFilter\n/**\n  * This class exposes a video filter for reducing a video's height by half.  Input is one clip,\n  * output is another.\n **/\n{\npublic:\n  VerticalReduceBy2(PClip _child, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env)  {\n    return new VerticalReduceBy2(args[0].AsClip(),env);\n  }\n\nprivate:\n  int original_height;\n};\n\n\nclass HorizontalReduceBy2 : public GenericVideoFilter\n/**\n  * This class exposes a video filter for reducing a video's width by half.  Input is one clip,\n  * output is another.\n **/\n{\npublic:\n  HorizontalReduceBy2(PClip _child, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env) {\n    return new HorizontalReduceBy2(args[0].AsClip(), env);\n  }\n\nprivate:\n  int source_width;\n  int pixelsize;\n};\n\n\nstatic AVSValue __cdecl Create_ReduceBy2(AVSValue args, void*, IScriptEnvironment* env);\n\n\n#endif  // __Resize_H__"
  },
  {
    "path": "avs_core/filters/source.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include \"../core/internal.h\"\n#include \"../convert/convert_matrix.h\"\n#include \"../convert/convert_helper.h\"\n#include \"colorbars_const.h\"\n#include \"transform.h\"\n#ifdef AVS_WINDOWS\n#include \"AviSource/avi_source.h\"\n#endif\n#include \"../convert/convert_planar.h\"\n\n#define PI 3.1415926535897932384626433832795\n#include <ctime>\n#include <cmath>\n#include <new>\n#include <cassert>\n#include <stdint.h>\n#include <algorithm>\n\n#define XP_LAMBDA_CAPTURE_FIX(x) (void)(x)\n\n/********************************************************************\n********************************************************************/\n\nenum {\n    COLOR_MODE_RGB = 0,\n    COLOR_MODE_YUV\n};\n\nclass StaticImage : public IClip {\n  const VideoInfo vi;\n  const PVideoFrame frame;\n  bool parity;\n\npublic:\n  StaticImage(const VideoInfo& _vi, const PVideoFrame& _frame, bool _parity)\n    : vi(_vi), frame(_frame), parity(_parity) {}\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) {\n    AVS_UNUSED(n);\n    AVS_UNUSED(env);\n    return frame;\n  }\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) {\n    AVS_UNUSED(start);\n    AVS_UNUSED(env);\n    memset(buf, 0, (size_t)vi.BytesFromAudioSamples(count));\n  }\n  const VideoInfo& __stdcall GetVideoInfo() { return vi; }\n  bool __stdcall GetParity(int n) { return (vi.IsFieldBased() ? (n&1) : false) ^ parity; }\n  int __stdcall SetCacheHints(int cachehints,int frame_range)\n  {\n    AVS_UNUSED(frame_range);\n    switch (cachehints)\n    {\n    case CACHE_DONT_CACHE_ME:\n      return 1;\n    case CACHE_GET_MTMODE:\n      return MT_NICE_FILTER;\n    case CACHE_GET_DEV_TYPE:\n       return DEV_TYPE_CPU;\n    case CACHE_GET_CHILD_DEV_TYPE:\n       return DEV_TYPE_ANY; // any type is ok because this clip does not require child's frames.\n    default:\n      return 0;\n    }\n  }\n};\n\n// For any frame number, this clip returns the first frame of a child clip .\n// This clip makes cache effective and reduce unnecessary frame transfer.\nclass SingleFrame : public GenericVideoFilter {\npublic:\n  SingleFrame(PClip _child) : GenericVideoFilter(_child) {}\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) { return child->GetFrame(0, env); }\n  int __stdcall SetCacheHints(int cachehints, int frame_range)\n  {\n    switch (cachehints)\n    {\n    case CACHE_DONT_CACHE_ME:\n      return 1;\n    case CACHE_GET_MTMODE:\n      return MT_NICE_FILTER;\n    case CACHE_GET_DEV_TYPE:\n      return (child->GetVersion() >= 5) ? child->SetCacheHints(CACHE_GET_DEV_TYPE, 0) : 0;\n    default:\n      return 0;\n    }\n  }\n};\n\n\nstatic PVideoFrame CreateBlankFrame(const VideoInfo& vi, int color, int mode, const int *colors, const float *colors_f, bool color_is_array, IScriptEnvironment* env) {\n\n  if (!vi.HasVideo()) return 0;\n\n  PVideoFrame frame = env->NewVideoFrame(vi);\n  // no frame property origin\n\n  // but we set Rec601 (ST170) if YUV\n  auto props = env->getFramePropsRW(frame);\n  int theMatrix = vi.IsRGB() ? Matrix_e::AVS_MATRIX_RGB : Matrix_e::AVS_MATRIX_ST170_M;\n  int theColorRange = vi.IsRGB() ? ColorRange_Compat_e::AVS_COLORRANGE_FULL : ColorRange_Compat_e::AVS_COLORRANGE_LIMITED;\n  update_Matrix_and_ColorRange(props, theMatrix, theColorRange, env);\n\n  // RGB 8->16 bit: not << 8 like YUV but 0..255 -> 0..65535 or 0..1023 for 10 bit\n  int pixelsize = vi.ComponentSize();\n  int bits_per_pixel = vi.BitsPerComponent();\n  int max_pixel_value = (1 << bits_per_pixel) - 1;\n  auto rgbcolor8to16 = [](uint8_t color8, int max_pixel_value) { return (uint16_t)(color8 * max_pixel_value / 255); };\n\n  // int color holds the \"old\" 8 bit color values that are scaled automatically to the right bitmap\n  // new in avs+: if color_is_array, color values are filled as-is, no conversion or any shift occurs\n\n  if (vi.IsPlanar()) {\n\n    bool isyuvlike = vi.IsYUV() || vi.IsYUVA();\n\n    if (color_is_array) {\n          // works from colors or colors_f: as-is\n          // color order in the array: RGBA or YUVA\n      int planes_y[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };\n      int planes_r[4] = { PLANAR_R, PLANAR_G, PLANAR_B, PLANAR_A };\n      int *planes = isyuvlike ? planes_y : planes_r;\n\n      for (int p = 0; p < vi.NumComponents(); p++)\n      {\n        int plane = planes[p];\n        BYTE *dstp = frame->GetWritePtr(plane);\n        int rowsize = frame->GetRowSize(plane);\n        int pitch = frame->GetPitch(plane);\n        int height = frame->GetHeight(plane);\n        switch (pixelsize) {\n        case 1: fill_plane<uint8_t>(dstp, height, rowsize, pitch, clamp(colors[p], 0, 0xFF)); break;\n        case 2: fill_plane<uint16_t>(dstp, height, rowsize, pitch, clamp(colors[p], 0, (1 << vi.BitsPerComponent()) - 1)); break;\n        case 4: fill_plane<float>(dstp, height, rowsize, pitch, colors_f[p]); break;\n        }\n      }\n    }\n    else {\n      int color_yuv = (mode == COLOR_MODE_YUV) ? color : RGB2YUV_Rec601(color);\n\n      int val_i = 0;\n\n      int planes_y[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };\n      int planes_r[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A };\n      int *planes = isyuvlike ? planes_y : planes_r;\n\n      for (int p = 0; p < vi.NumComponents(); p++)\n      {\n        int plane = planes[p];\n        // color order: ARGB or AYUV\n        // (8)-8-8-8 bit color from int parameter\n        if (isyuvlike) {\n          switch (plane) {\n          case PLANAR_A: val_i = (color >> 24) & 0xff; break;\n          case PLANAR_Y: val_i = (color_yuv >> 16) & 0xff; break;\n          case PLANAR_U: val_i = (color_yuv >> 8) & 0xff; break;\n          case PLANAR_V: val_i = color_yuv & 0xff; break;\n          }\n          if (bits_per_pixel != 32)\n            val_i = val_i << (bits_per_pixel - 8);\n        }\n        else {\n         // planar RGB\n          switch (plane) {\n          case PLANAR_A: val_i = (color >> 24) & 0xff; break;\n          case PLANAR_R: val_i = (color >> 16) & 0xff; break;\n          case PLANAR_G: val_i = (color >> 8) & 0xff; break;\n          case PLANAR_B: val_i = color & 0xff; break;\n          }\n          if (bits_per_pixel != 32)\n            val_i = rgbcolor8to16(val_i, max_pixel_value);\n        }\n\n\n        BYTE *dstp = frame->GetWritePtr(plane);\n        int size = frame->GetPitch(plane) * frame->GetHeight(plane);\n\n        switch (pixelsize) {\n        case 1:\n          memset(dstp, val_i, size);\n          break;\n        case 2:\n          val_i = clamp(val_i, 0, (1 << vi.BitsPerComponent()) - 1);\n          std::fill_n((uint16_t *)dstp, size / sizeof(uint16_t), (uint16_t)val_i);\n          break; // 2 pixels at a time\n        default: // case 4:\n          float val_f;\n          if (plane == PLANAR_U || plane == PLANAR_V) {\n            float shift = 0.0f;\n            val_f = float(val_i - 128) / 255.0f + shift; // 32 bit float chroma 128=0.5\n          }\n          else {\n            val_f = float(val_i) / 255.0f;\n          }\n          std::fill_n((float *)dstp, size / sizeof(float), val_f);\n        }\n      }\n    }\n    return frame;\n  } // if planar\n\n  BYTE* p = frame->GetWritePtr();\n  int size = frame->GetPitch() * frame->GetHeight();\n\n  if (vi.IsYUY2()) {\n    int color_yuv =(mode == COLOR_MODE_YUV) ? color : RGB2YUV_Rec601(color);\n    if (color_is_array) {\n      color_yuv = (clamp(colors[0], 0, max_pixel_value) << 16) | (clamp(colors[1], 0, max_pixel_value) << 8) | (clamp(colors[2], 0, max_pixel_value));\n    }\n    uint32_t d = ((color_yuv>>16)&255) * 0x010001 + ((color_yuv>>8)&255) * 0x0100 + (color_yuv&255) * 0x01000000;\n    for (int i=0; i<size; i+=4)\n      *(uint32_t *)(p+i) = d;\n  } else if (vi.IsRGB24()) {\n    const uint8_t color_b = color_is_array ? clamp(colors[2], 0, max_pixel_value) : (uint8_t)(color & 0xFF);\n    const uint8_t color_g = color_is_array ? clamp(colors[1], 0, max_pixel_value) : (uint8_t)(color >> 8);\n    const uint8_t color_r = color_is_array ? clamp(colors[0], 0, max_pixel_value) : (uint8_t)(color >> 16);\n    const int rowsize = frame->GetRowSize();\n    const int pitch = frame->GetPitch();\n    for (int y=frame->GetHeight();y>0;y--) {\n      for (int i=0; i<rowsize; i+=3) {\n        p[i] = color_b;\n        p[i+1] = color_g;\n        p[i+2] = color_r;\n      }\n      p+=pitch;\n    }\n  } else if (vi.IsRGB32()) {\n    uint32_t c;\n    c = color;\n    if (color_is_array) {\n      uint32_t r = clamp(colors[0], 0, max_pixel_value);\n      uint32_t g = clamp(colors[1], 0, max_pixel_value);\n      uint32_t b = clamp(colors[2], 0, max_pixel_value);\n      uint32_t a = clamp(colors[3], 0, max_pixel_value);\n      c = (a << 24) + (r << 16) + (g << 8) + (b);\n    }\n    std::fill_n((uint32_t *)p, size / 4, c);\n    //for (int i=0; i<size; i+=4)\n    //  *(unsigned*)(p+i) = color;\n  } else if (vi.IsRGB48()) {\n      const uint16_t color_b  = color_is_array ? clamp(colors[2], 0, max_pixel_value) : rgbcolor8to16(color & 0xFF, max_pixel_value);\n      uint16_t r = color_is_array ? clamp(colors[0], 0, max_pixel_value) : rgbcolor8to16((color >> 16) & 0xFF, max_pixel_value);\n      uint16_t g = color_is_array ? clamp(colors[1], 0, max_pixel_value) : rgbcolor8to16((color >> 8 ) & 0xFF, max_pixel_value);\n      const uint32_t color_rg = (r << 16) + (g);\n      const int rowsize = frame->GetRowSize() / sizeof(uint16_t);\n      const int pitch = frame->GetPitch() / sizeof(uint16_t);\n      uint16_t* p16 = reinterpret_cast<uint16_t*>(p);\n      for (int y=frame->GetHeight();y>0;y--) {\n          for (int i=0; i<rowsize; i+=3) {\n              p16[i] = color_b;   // b\n              *reinterpret_cast<uint32_t*>(p16+i+1) = color_rg; // gr\n          }\n          p16 += pitch;\n      }\n  } else if (vi.IsRGB64()) {\n    uint64_t r, g, b, a;\n    r = color_is_array ? clamp(colors[0], 0, max_pixel_value) : rgbcolor8to16((color >> 16) & 0xFF, max_pixel_value);\n    g = color_is_array ? clamp(colors[1], 0, max_pixel_value) : rgbcolor8to16((color >> 8 ) & 0xFF, max_pixel_value);\n    b = color_is_array ? clamp(colors[2], 0, max_pixel_value) : rgbcolor8to16((color      ) & 0xFF, max_pixel_value);\n    a = color_is_array ? clamp(colors[3], 0, max_pixel_value) : rgbcolor8to16((color >> 24) & 0xFF, max_pixel_value);\n    uint64_t color64 = (a << 48) + (r << 32) + (g << 16) + (b);\n    std::fill_n(reinterpret_cast<uint64_t*>(p), size / sizeof(uint64_t), color64);\n  }\n  return frame;\n}\n\n\nstatic AVSValue __cdecl Create_BlankClip(AVSValue args, void*, IScriptEnvironment* env) {\n  VideoInfo vi_default;\n  memset(&vi_default, 0, sizeof(VideoInfo));\n\n  VideoInfo vi = vi_default;\n\n  vi_default.fps_denominator=1;\n  vi_default.fps_numerator=24;\n  vi_default.height=480;\n  vi_default.pixel_type=VideoInfo::CS_BGR32;\n  vi_default.num_frames=240;\n  vi_default.width=640;\n  vi_default.audio_samples_per_second=44100;\n  vi_default.nchannels=1;\n  vi_default.num_audio_samples=44100*10;\n  vi_default.sample_type=SAMPLE_INT16;\n  vi_default.SetFieldBased(false);\n  bool parity=false;\n\n  AVSValue args0 = args[0];\n\n  // param#12: \"clip\" overrides\n  if (args0.Defined() && args0.ArraySize() == 1 && !args[12].Defined()) {\n    vi_default = args0[0].AsClip()->GetVideoInfo();\n    parity = args0[0].AsClip()->GetParity(0);\n  }\n  else if (args0.Defined() && args0.ArraySize() != 0) {\n    // when \"clip\" is defined then beginning clip parameter is forbidden\n    env->ThrowError(\"BlankClip: Only 1 Template clip allowed.\");\n  }\n  else if (args[12].Defined()) {\n    // supplied \"clip\" parameter\n    vi_default = args[12].AsClip()->GetVideoInfo();\n    parity = args[12].AsClip()->GetParity(0);\n  }\n\n  bool defHasVideo = vi_default.HasVideo();\n  bool defHasAudio = vi_default.HasAudio();\n\n  // If no default video\n  if ( !defHasVideo ) {\n    vi_default.fps_numerator=24;\n    vi_default.fps_denominator=1;\n\n    vi_default.num_frames = 240;\n\n    // If specify Width    or Height            or Pixel_Type\n    if ( args[2].Defined() || args[3].Defined() || args[4].Defined() ) {\n      vi_default.width=640;\n      vi_default.height=480;\n      vi_default.pixel_type=VideoInfo::CS_BGR32;\n\n      vi_default.SetFieldBased(false);\n      parity=false;\n    }\n  }\n\n  // If no default audio but specify Audio_rate or Channels     or Sample_Type\n  if ( !defHasAudio && ( args[7].Defined() || args[8].Defined() || args[9].Defined() ) ) {\n    vi_default.audio_samples_per_second=44100;\n    vi_default.nchannels=1;\n    vi_default.sample_type=SAMPLE_INT16;\n  }\n\n  vi.width = args[2].AsInt(vi_default.width);\n  vi.height = args[3].AsInt(vi_default.height);\n\n  if (args[4].Defined()) {\n      int pixel_type = GetPixelTypeFromName(args[4].AsString());\n      if(pixel_type == VideoInfo::CS_UNKNOWN)\n      {\n          env->ThrowError(\"BlankClip: pixel_type must be \\\"RGB32\\\", \\\"RGB24\\\", \\\"YV12\\\", \\\"YV24\\\", \\\"YV16\\\", \\\"Y8\\\", \\n\"\\\n              \"\\\"YUV420P?\\\",\\\"YUV422P?\\\",\\\"YUV444P?\\\",\\\"Y?\\\",\\n\"\\\n              \"\\\"RGB48\\\",\\\"RGB64\\\",\\\"RGBP\\\",\\\"RGBP?\\\",\\n\"\\\n              \"\\\"YV411\\\" or \\\"YUY2\\\"\");\n      }\n      vi.pixel_type = pixel_type;\n  }\n  else {\n    vi.pixel_type = vi_default.pixel_type;\n  }\n\n  if (!vi.pixel_type)\n    vi.pixel_type = VideoInfo::CS_BGR32;\n\n\n  double n = args[5].AsDblDef(double(vi_default.fps_numerator));\n\n  if (args[5].Defined() && !args[6].Defined()) {\n    unsigned d = 1;\n    while (n < 16777216 && d < 16777216) { n*=2; d*=2; }\n    vi.SetFPS(int(n+0.5), d);\n  } else {\n    vi.SetFPS(int(n+0.5), args[6].AsInt(vi_default.fps_denominator));\n  }\n\n  vi.image_type = vi_default.image_type; // Copy any field sense from template\n\n  vi.audio_samples_per_second = args[7].AsInt(vi_default.audio_samples_per_second);\n\n  if (args[8].IsBool())\n    vi.nchannels = args[8].AsBool() ? 2 : 1; // stereo=True\n  else if (args[8].IsInt())\n    vi.nchannels = args[8].AsInt();          // channels=2\n  else\n    vi.nchannels = vi_default.nchannels;\n\n  if (args[9].IsBool())\n    vi.sample_type = args[9].AsBool() ? SAMPLE_INT16 : SAMPLE_FLOAT; // sixteen_bit=True\n  else if (args[9].IsString()) {\n    const char* sample_type_string = args[9].AsString();\n    if        (!lstrcmpi(sample_type_string, \"8bit\" )) {  // sample_type=\"8Bit\"\n      vi.sample_type = SAMPLE_INT8;\n    } else if (!lstrcmpi(sample_type_string, \"16bit\")) {  // sample_type=\"16Bit\"\n      vi.sample_type = SAMPLE_INT16;\n    } else if (!lstrcmpi(sample_type_string, \"24bit\")) {  // sample_type=\"24Bit\"\n      vi.sample_type = SAMPLE_INT24;\n    } else if (!lstrcmpi(sample_type_string, \"32bit\")) {  // sample_type=\"32Bit\"\n      vi.sample_type = SAMPLE_INT32;\n    } else if (!lstrcmpi(sample_type_string, \"float\")) {  // sample_type=\"Float\"\n      vi.sample_type = SAMPLE_FLOAT;\n    } else {\n      env->ThrowError(\"BlankClip: sample_type must be \\\"8bit\\\", \\\"16bit\\\", \\\"24bit\\\", \\\"32bit\\\" or \\\"float\\\"\");\n    }\n  } else\n    vi.sample_type = vi_default.sample_type;\n\n  // If we got an Audio only default clip make the default duration the same\n  if (!defHasVideo && defHasAudio) {\n    const int64_t denom = Int32x32To64(vi.fps_denominator, vi_default.audio_samples_per_second);\n    vi_default.num_frames = int((vi_default.num_audio_samples * vi.fps_numerator + denom - 1) / denom); // ceiling\n  }\n\n  vi.num_frames = args[1].AsInt(vi_default.num_frames);\n\n  vi.width++; // cheat HasVideo() call for Audio Only clips\n  vi.num_audio_samples = vi.AudioSamplesFromFrames(vi.num_frames);\n  vi.width--;\n\n  int color = args[10].AsInt(0);\n  int mode = COLOR_MODE_RGB;\n  if (args[11].Defined()) {\n    if (color != 0) // Not quite 100% test\n      env->ThrowError(\"BlankClip: color and color_yuv are mutually exclusive\");\n    if (!vi.IsYUV() && !vi.IsYUVA())\n      env->ThrowError(\"BlankClip: color_yuv only valid for YUV color spaces\");\n    color = args[11].AsInt();\n    mode=COLOR_MODE_YUV;\n  }\n\n  int colors[4] = { 0 };\n  float colors_f[4] = { 0.0 };\n  bool color_is_array = false;\n\n  if (args.ArraySize() >= 14) {\n    // new colors parameter\n    if (args[13].Defined()) // colors\n    {\n      if (!args[13].IsArray())\n        env->ThrowError(\"BlankClip: colors must be an array\");\n      int color_count = args[13].ArraySize();\n      if (color_count < vi.NumComponents())\n        env->ThrowError(\"BlankClip: 'colors' size %d is less than component count %d\", color_count, vi.NumComponents());\n      int pixelsize = vi.ComponentSize();\n      int bits_per_pixel = vi.BitsPerComponent();\n      for (int i = 0; i < color_count; i++) {\n        const float c = args[13][i].AsFloatf(0.0);\n        if (pixelsize == 4)\n          colors_f[i] = c;\n        else {\n          const int color = (int)(c + 0.5f);\n          if (color >= (1 << bits_per_pixel) || color < 0)\n            env->ThrowError(\"BlankClip: invalid color value (%d) for %d-bit video format\", color, bits_per_pixel);\n          colors[i] = color;\n        }\n      }\n      color_is_array = true;\n    }\n  }\n\n  PClip clip = new StaticImage(vi, CreateBlankFrame(vi, color, mode, colors, colors_f, color_is_array, env), parity);\n\n  // wrap in OnCPU to support multi devices\n  AVSValue arg[2]{ clip, 1 }; // prefetch=1: enable cache but not thread\n  return new SingleFrame(env->Invoke(\"OnCPU\", AVSValue(arg, 2)).AsClip());\n}\n\n\n/********************************************************************\n********************************************************************/\n\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n// in text-overlay.cpp\nextern bool GetTextBoundingBox(const char* text, const char* fontname,\n  int size, bool bold, bool italic, int align, int* width, int* height, bool utf8);\n#endif\n\nextern bool GetTextBoundingBoxFixed(const char* text, const char* fontname, int size, bool bold,\n  bool italic, int align, int& width, int& height, bool utf8);\n\n\nPClip Create_MessageClip(const char* message, int width, int height, int pixel_type, bool shrink,\n                         int textcolor, int halocolor, int bgcolor,\n                         int fps_numerator, int fps_denominator, int num_frames,\n                         bool utf8,\n                         IScriptEnvironment* env) {\n  int size;\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  // MessageClip produces a clip containing a text message.Used internally for error reporting.\n  // The font face is \"Arial\".\n  // The font size is between 24 points and 9 points - chosen to fit, if possible,\n  // in the width by height clip.\n  // The pixeltype is RGB32.\n\n  for (size = 24*8; /*size>=9*8*/; size-=4) {\n    int text_width, text_height;\n    GetTextBoundingBox(message, \"Arial\", size, true, false, TA_TOP | TA_CENTER, &text_width, &text_height, utf8);\n    text_width = ((text_width>>3)+8+7) & ~7; // mod 8\n    text_height = ((text_height>>3)+8+1) & ~1; // mod 2\n    if (size <= 9 * 8 || ((width <= 0 || text_width <= width) && (height <= 0 || text_height <= height))) {\n      if (width <= 0 || (shrink && width > text_width))\n        width = text_width;\n      if (height <= 0 || (shrink && height > text_height))\n        height = text_height;\n      break;\n    }\n  }\n#else\n  constexpr int MAX_SIZE = 24; // Terminus 12,14,16,18,20,22,24,28,32\n  constexpr int MIN_SIZE = 12;\n  for (size = MAX_SIZE; /*size>=9*/; size -= 2) {\n    int text_width, text_height;\n#ifdef AVS_POSIX\n    bool utf8 = true;\n#endif\n    GetTextBoundingBoxFixed(message, \"Terminus\", size, true, false, 0 /* align */, text_width, text_height, utf8);\n    text_width = (text_width + 8 + 7) & ~7; // mod 8\n    text_height = (text_height + 8 + 1) & ~1; // mod 2\n    if (size <= MIN_SIZE || ((width <= 0 || text_width <= width) && (height <= 0 || text_height <= height))) {\n      if (width <= 0 || (shrink && width > text_width))\n        width = text_width;\n      if (height <= 0 || (shrink && height > text_height))\n        height = text_height;\n      break;\n    }\n  }\n\n  size *= 8; // back to GDI units\n#endif\n\n  VideoInfo vi;\n  memset(&vi, 0, sizeof(vi));\n  vi.width = width;\n  vi.height = height;\n  vi.pixel_type = pixel_type;\n  vi.fps_numerator = fps_numerator > 0 ? fps_numerator : 24;\n  vi.fps_denominator = fps_denominator > 0 ? fps_denominator : 1;\n  vi.num_frames = num_frames > 0 ? num_frames : 240;\n\n  PVideoFrame frame = CreateBlankFrame(vi, bgcolor, COLOR_MODE_RGB, nullptr, nullptr, false, env);\n  env->ApplyMessageEx(&frame, vi, message, size, textcolor, halocolor, bgcolor, utf8);\n  PClip clip = new StaticImage(vi, frame, false);\n\n  // wrap in OnCPU to support multi devices\n  AVSValue args[2]{ clip, 1 }; // prefetch=1: enable cache but not thread\n  return new SingleFrame(env->Invoke(\"OnCPU\", AVSValue(args, 2)).AsClip());\n};\n\nAVSValue __cdecl Create_MessageClip(AVSValue args, void*, IScriptEnvironment* env) {\n  const bool utf8_default =\n#ifdef AVS_POSIX\n    true\n#else\n    false\n#endif\n    ;\n\n  return Create_MessageClip(args[0].AsString(), args[1].AsInt(-1),\n    args[2].AsInt(-1), VideoInfo::CS_BGR32, args[3].AsBool(false),\n    args[4].AsInt(0xFFFFFF), args[5].AsInt(0), args[6].AsInt(0),\n    -1, -1, -1, // fps_numerator, fps_denominator, num_frames: auto\n    args[7].AsBool(utf8_default), // utf8\n    env);\n}\n\n\n/*******************************************************************\n*\n* ColorBarsHD for YUV 444 formats (Rec.709)\n*\n*********************************************************************/\n\nstatic void GetYUVRec709fromRGB(double R, double G, double B, double& dY, double& dU, double& dV)\n{\n  // See 3.2 from https://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.709-6-201506-I!!PDF-E.pdf\n  double Kr, Kb;\n  GetKrKb(AVS_MATRIX_BT709, Kr, Kb);\n  dY = Kr * R + (1.0 - Kr - Kb) * G + Kb * B;\n  dU = (B - dY) / (2.0 * (1.0 - Kb));\n  dV = (R - dY) / (2.0 * (1.0 - Kr));\n}\n\ntemplate<typename pixel_t>\nstatic void draw_colorbarsHD_444(uint8_t *pY8, uint8_t *pU8, uint8_t *pV8, int pitchY, int pitchUV, int w, int h, int bits_per_pixel)\n{\n  pixel_t *pY = reinterpret_cast<pixel_t *>(pY8);\n  pixel_t *pU = reinterpret_cast<pixel_t *>(pU8);\n  pixel_t *pV = reinterpret_cast<pixel_t *>(pV8);\n  pitchY /= sizeof(pixel_t);\n  pitchUV /= sizeof(pixel_t);\n\n  const int shift = sizeof(pixel_t) == 4 ? 0 : (bits_per_pixel - 8);\n\n  // Also for float target we make \"limited\" range\n  bits_conv_constants luma, chroma;\n  // RGB is source, YUV is destination\n  // For RGB source / Y destination (both luma-like):\n  const bool full_scale_s = true; // full scale reference\n  const bool full_scale_d = false; // narrow range reference\n  get_bits_conv_constants(luma, false, full_scale_s, full_scale_d, 32, 32);\n  // For UV destination (chroma behavior):\n  // Note: we only need dst_span for UV, so we use full_scale_d for both params\n  get_bits_conv_constants(chroma, true, full_scale_s, full_scale_d, 32, 32);\n\n  double float_offset = luma.dst_offset;\n  double float_scale = luma.mul_factor; // 219.0 / 255.0;\n  double float_uv_scale = chroma.mul_factor;\n\n//\t\tNearest 16:9 pixel exact sizes\n//\t\t56*X x 12*Y\n//\t\t 728 x  480  ntsc anamorphic\n//\t\t 728 x  576  pal anamorphic\n//\t\t 840 x  480\n//\t\t1008 x  576\n//\t\t1288 x  720 <- default\n//\t\t1456 x 1080  hd anamorphic\n//\t\t1904 x 1080\n/*\n  ARIB STD-B28  Version 1.0-E1\n\n  *1: 75W/100W/I+: Choice from 75% white, 100% white and +I signal. Avisynth: I+.\n  *2: can be changed to any value other than the standard values in accordance with the operation purpose by the user\n\n              |<-------------------------------------------------------- a -------------------------------------------------->|\n              |             |<------------------------------------------3/4 a --------------------------------->|             |\n              |<---- d ---->|<--- c --->|<--- c --->|<--- c --->|<--- c --->|<--- c --->|<--- c --->|<--- c --->|<---- d ---->|\n\n              +-------------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-------------+  -----------\n              |             |           |           |           |           |           |           |           |             |      ^   ^\n              |             |           |           |           |           |           |           |           |             |      |   |\nPattern 1     |     40%     |    75%    |    75%    |    75%    |    75%    |    75%    |    75%    |    75%    |    40%      |      |   |\n              |    Grey     |   White   |   Yellow  |   Cyan    |   Green   |  Magenta  |   Red     |   Blue    |    Grey     | 7/12b|   |\n              |     *2      |           |           |           |           |           |           |           |    *2       |      |   |\n              |             |           |           |           |           |           |           |           |             |      V   |\n              +-------------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-------------+ -------  |\nPattern 2     | 100% Cyan   |75W/100W/I+|                          75% white (chroma set signal)                | 100% blue   | 1/12b|   | b\n              +-------------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-------------+ ------   |\nPattern 3     | 100% Yellow |                                       Y ramp                                      | 100% red    | 1/12b|   |\n              +-------------+-----------------+-----------+-----------+-------+----+----+---+---+---+-----------+-------------+ -------  |\n              |     *2      |                 |                       |       |    |    |   |   |   |           |      *2     |      ^   |\nPattern 4     |     15%     |        0%       |          100%         |   0%  |-2% | 0  |+2%| 0 |+4%|     0%    |     15%     | 3/12 |   |\n              |    Grey     |       Black     |         White         | Black |    |    |   |   |   |   Black   |    Grey     |  b   V   V\n              +-------------+-----------------+-----------+-----------+-------+----+----+---+---+---+-----------+-------------+  -----------\n\n              |<---- d ---->|<---- 3/2 c ---->|<--------- 2c -------->|<5/6c->|1/3c|1/3c|1/3|1/3|1/3|<--- c --->|<---- d ---->|\n\n              a:b = 16:9\n\n\n  2021: SMPTE RP 219-1:2014\n  *1: can be changed to any value other than the standard values in accordance with the operation purpose by the user\n  *2: 75W/100W/+I/-I: Choice from 75% white, 100% white and +I or -I signal. Avisynth: 100% White.\n  *3: Choice from 0% Black or +Q (Left from Y ramp) Avisynth: 0% Black.\n  *4: can be changed to any value other than the standard values in accordance with the operation purpose by the user\n  *5: Choice from 0% Black, Sub-black valley. Avisynth: 0% Black.\n      The sub-black valley signal shall begin at the 0% black level, shall decrease in a linear ramp to the minimum permitted level at the mid-point,\n      and shall increase in a linear ramp to the 0% black level at the end of the black bar.\n  *6: Choice from 100% White, Super-white Peak. Avisynth: 100% White.\n      The super-white peak signal shall begin at the 100% white level, shall increase in a linear ramp to the maximum permitted level at the midpoint, \n      and shall decrease in a linear ramp to the 100% white level at the end of the white bar. \n\n                            |<-------------------------------------------------------- a -------------------------------------------------->|\n              |             |<------------------------------------------3/4 a --------------------------------->|             |\n              |<---- d ---->|<--- c --->|<--- c --->|<--- c --->|<--- c --->|<--- c --->|<--- c --->|<--- c --->|<---- d ---->|\n\n              +-------------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-------------+  -----------\n              |             |           |           |           |           |           |           |           |             |      ^   ^\n              |             |           |           |           |           |           |           |           |             |      |   |\nPattern 1     |     40%     |    75%    |    75%    |    75%    |    75%    |    75%    |    75%    |    75%    |    40%      |      |   |\n              |    Grey     |   White   |   Yellow  |   Cyan    |   Green   |  Magenta  |   Red     |   Blue    |    Grey     | 7/12b|   |\n              |     *1      |           |           |           |           |           |           |           |    *1       |      |   |\n              |             |           |           |           |           |           |           |           |             |      V   |\n              +-------------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-------------+ -------  |\nPattern 2     | 100% Cyan   |75/100W/I-+|                          75% white (chroma set signal)                | 100% blue   | 1/12b|   | b\n              +-------------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-------------+ ------   |\nPattern 3     | 100% Yellow |0%Blk or +Q|                           Y ramp                          | 100% White| 100% red    | 1/12b|   |\n              +-------------+-----------+-----+-----------+-----------+-------+----+----+---+---+---+-----------+-------------+ -------  |\n              |     *4      |   0% Black    *5|      100% White     *6|       |    |    |   |   |   |           |      *4     |      ^   |\nPattern 4     |     15%     |0% Blk or SubBlck|100%White/SuperWhtePeak|   0%  |-2% | 0  |+2%| 0 |+4%|     0%    |     15%     | 3/12 |   |\n              |    Grey     |   0%  Black     |      100% White       | Black |    |    |   |   |   |   Black   |    Grey     |  b   V   V\n              +-------------+-----------------+-----------+-----------+-------+----+----+---+---+---+-----------+-------------+  -----------\n\n              |<---- d ---->|<---- 3/2 c ---->|<--------- 2c -------->|<5/6c->|1/3c|1/3c|1/3|1/3|1/3|<--- c --->|<---- d ---->|\n\n              a:b = 16:9\n\n*/\n\n  int y = 0;\n\n  const int c = (w * 3 + 14) / 28; // 1/7th of 3/4 of width\n  const int d = (w - c * 7 + 1) / 2; // remaining 1/8th of width\n\n  const int p4 = (3 * h + 6) / 12; // 3/12th of height\n  const int p23 = (h + 6) / 12;  // 1/12th of height\n  const int p1 = h - p23 * 2 - p4; // remaining 7/12th of height\n\n  /*\n  //               75%  Rec709 -- Grey40 Grey75 Yellow  Cyan   Green Magenta  Red   Blue\n  static const BYTE pattern1Y[] = { 104,   180,   168,   145,   133,    63,    51,    28 };\n  static const BYTE pattern1U[] = { 128,   128,    44,   147,    63,   193,   109,   212 };\n  static const BYTE pattern1V[] = { 128,   128,   136,    44,    52,   204,   212,   120 };\n  // 3.7.6: replaced the 8 bit table (inaccurate base for higher bitdepths) with accurate \n  // RGB values with double precision RGB to YUV conversion.\n  */\n\n  // Define as double-precision gamma-encoded signal levels (E'R, E'G, E'B).\n  // 0.75 = 75% of encoded signal swing, not a linear-light value.\n  // Convert to Rec.709 YUV for target bitdepth and limited/full range later.\n  static const double pattern1R[] = { 0.4, 0.75, 0.75, 0.00, 0.00, 0.75, 0.75, 0.00 };\n  static const double pattern1G[] = { 0.4, 0.75, 0.75, 0.75, 0.75, 0.00, 0.00, 0.00 };\n  static const double pattern1B[] = { 0.4, 0.75, 0.00, 0.75, 0.00, 0.75, 0.00, 0.75 };\n\n  // Helper to process and write a pixel based on RGB input\n  auto ProcessPixel = [&](double r, double g, double b, int targetX) {\n    XP_LAMBDA_CAPTURE_FIX(float_scale);\n    XP_LAMBDA_CAPTURE_FIX(float_offset);\n    XP_LAMBDA_CAPTURE_FIX(float_uv_scale);\n    XP_LAMBDA_CAPTURE_FIX(shift);\n    double dY, dU, dV;\n    GetYUVRec709fromRGB(r, g, b, dY, dU, dV);\n\n    if constexpr (std::is_same<pixel_t, float>::value) {\n      pY[targetX] = (pixel_t)(dY * float_scale + float_offset);\n      pU[targetX] = (pixel_t)(dU * float_uv_scale);\n      pV[targetX] = (pixel_t)(dV * float_uv_scale);\n    }\n    else {\n      // High-precision calculation for 10/12/16-bit\n      pY[targetX] = (pixel_t)(((dY * 219.0 + 16.0) * (1 << shift)) + 0.5);\n      pU[targetX] = (pixel_t)(((dU * 224.0 + 128.0) * (1 << shift)) + 0.5);\n      pV[targetX] = (pixel_t)(((dV * 224.0 + 128.0) * (1 << shift)) + 0.5);\n    }\n    };\n\n  // ColorbarsHD produces \"limited\", and since Avisynth handles \"limited\" 32 bit float, so we adjust it as well.\n\n  // Pattern 1\n\n  for (; y < p1; ++y) {\n    int x = 0;\n    // 40% grey\n    for (; x < d; ++x) {\n      ProcessPixel(pattern1R[0], pattern1G[0], pattern1B[0], x);\n    }\n    // 75% White, Yellow, Cyan, Green, Magenta, Red, Blue\n    for (int i = 1; i < 8; i++) {\n      for (int j = 0; j < c; ++j, ++x) {\n        ProcessPixel(pattern1R[i], pattern1G[i], pattern1B[i], x);\n      }\n    }\n    for (; x < w; ++x) {\n      ProcessPixel(pattern1R[0], pattern1G[0], pattern1B[0], x);\n    }\n    pY += pitchY; pU += pitchUV; pV += pitchUV;\n  }\n\n  /*\n  SMPTE RP 219 / EG 1: +I Signal Reference (Rec. 709 / HD)\n  * The +I (In-phase) signal is defined by its analog IRE levels:\n    R = 41.2545 IRE, G = 16.6946 IRE, B = 0 IRE.\n  * Normalized Linear RGB (IRE/100): R: 0.412545, G: 0.166946, B: 0.000000\n  -----------------------------------------------------------\n  Bit-Depth | Y (Luma)      | U (Cb)        | V (Cr)        |\n  -----------------------------------------------------------\n  8-bit     | 61   (3D)     | 103  (67)     | 157  (9D)     |\n  10-bit    | 245  (0F5)    | 412  (19C)    | 629  (275)    |\n  16-bit    | 15707 (3D5B)  | 26368 (6700)  | 40249 (9D39)  |\n  -----------------------------------------------------------\n  See also https://www.arib.or.jp/english/html/overview/doc/6-STD-B28v1_0-E1.pdf\n  and\n  Wikipedia (https://en.wikipedia.org/wiki/SMPTE_color_bars) (2026)\n\n  Pre 3.7.6 old table, containing precalculated 8 bit values\n  //              100% Rec709       Cyan  Blue Yellow  Red    +I Grey75  White\n  static const BYTE pattern23Y[] = { 188,   32,  219,   63,   61,  180,  235 };\n  static const BYTE pattern23U[] = { 154,  240,   16,  102,  103,  128,  128 };\n  static const BYTE pattern23V[] = {  16,  118,  138,  240,  157,  128,  128 };\n\n  */\n  // Pattern 2\n\n  // 0: Cyan100, 1: Blue100, 2: Yellow100, 3: Red100, 4: +I, 5: Grey75, 6: White100\n  static const double pattern23R[] = { 0.0, 0.0, 1.0, 1.0, PLUS_I_R_YUV, 0.75, 1.0 };\n  static const double pattern23G[] = { 1.0, 0.0, 1.0, 0.0, PLUS_I_G_YUV, 0.75, 1.0 };\n  static const double pattern23B[] = { 1.0, 1.0, 0.0, 0.0, PLUS_I_B_YUV, 0.75, 1.0 };\n\n  // For pattern 2 and 3\n  auto ProcessBar = [&](int index, int endX, int& currentX) {\n    XP_LAMBDA_CAPTURE_FIX(float_scale);\n    XP_LAMBDA_CAPTURE_FIX(float_offset);\n    XP_LAMBDA_CAPTURE_FIX(float_uv_scale);\n    XP_LAMBDA_CAPTURE_FIX(shift);\n    double dY, dU, dV;\n    GetYUVRec709fromRGB(pattern23R[index], pattern23G[index], pattern23B[index], dY, dU, dV);\n\n    for (; currentX < endX && currentX < w; ++currentX) {\n      if constexpr(std::is_same<pixel_t, float>::value) {\n        pY[currentX] = (pixel_t)(dY * float_scale + float_offset);\n        pU[currentX] = (pixel_t)(dU * float_uv_scale);\n        pV[currentX] = (pixel_t)(dV * float_uv_scale);\n      }\n      else {\n        pY[currentX] = (pixel_t)(((dY * 219.0 + 16.0) * (1 << shift)) + 0.5);\n        pU[currentX] = (pixel_t)(((dU * 224.0 + 128.0) * (1 << shift)) + 0.5);\n        pV[currentX] = (pixel_t)(((dV * 224.0 + 128.0) * (1 << shift)) + 0.5);\n      }\n    }\n    };\n\n  for (; y < p1 + p23; ++y) {\n    int x = 0;\n\n    // 1. Left Padding (100% Cyan) - Index 0\n    ProcessBar(0, d, x);\n    // 2. The +I Bar - Index 4 (+I or Grey75 or White)\n    ProcessBar(4, c + d, x);\n    // 3. 75% White (Grey75) - Index 5\n    ProcessBar(5, c * 7 + d, x);\n    // 4. Remaining width (100% Blue) - Index 1\n    ProcessBar(1, w, x);\n\n    pY += pitchY; pU += pitchUV; pV += pitchUV;\n  }\n\n  // Pattern 3\n\n  for (; y < p1 + p23 * 2; ++y) {\n    int x = 0;\n\n    ProcessBar(2, d, x); // 100% Yellow\n\n    // Y ramp section: 0% Black, Ramp, 100% White\n    // FIXED in 3.7.6: Y-ramp to conform SMPTE RP 219-1:2014, put 0% Black before and 100% White after\n    // Divide the c * 7 area: \n    // - 1x - 0% Black (or optional +Q)\n    // - 5x - Ramp\n    // - 1x - 100% White\n\n    int rampStartX = x + c;         // End of Black (+Q) step\n    int rampEndX = x + (c * 6);     // Start of White step\n    int sectionEndX = x + (c * 7);  // End of this whole middle section\n\n    // A. 0% black (or optional +Q) step\n    for (; x < rampStartX; ++x) {\n      ProcessPixel(0.0, 0.0, 0.0, x);\n      // ProcessPixel(PLUS_Q_R_YUV, PLUS_Q_G_YUV, PLUS_Q_B_YUV, x); // For +Q instead of 0% Black\n    }\n\n    // B. Y-ramp (0.0 to 1.0) - 5 units wide\n    int rampWidth = rampEndX - rampStartX;\n    for (int j = 0; x < rampEndX; ++x, ++j) {\n      double v = (double)j / (rampWidth - 1);\n      ProcessPixel(v, v, v, x); // For a grayscale ramp, R=G=B\n    }\n\n    // C. 100% White\n    for (; x < sectionEndX; ++x) {\n      ProcessPixel(1.0, 1.0, 1.0, x);\n    }\n    // end of Ramp section\n\n    ProcessBar(3, w, x); // 100% Red\n    pY += pitchY; pU += pitchUV; pV += pitchUV;\n  }\n\n  // Pattern 4\n\n  // Normalized RGB for Pattern 4: 15% Grey, Black, White, Black, -2%, Black, +2%, Black, +4%, Black\n  /* old table, precalculated 8 bit values\n  //                             Grey15 Black White Black   -2% Black   +2% Black   +4% Black\n  static const BYTE pattern4Y[] = { 49,   16,  235,   16,   12,   16,   20,   16,   25,   16 };\n  U and V are 128\n  */\n\n  static const double pattern4RGB[] = { 0.15, 0.0, 1.0, 0.0, -0.02, 0.0, 0.02, 0.0, 0.04, 0.0 };\n  static const BYTE pattern4W[]     = { 0,    9,   21,  26,  28,    30,  32,   34,  36,   42 }; // in 6th's\n  for (; y < h; ++y) {\n    int x = 0;\n\n    // 1. Left Padding (15% Grey)\n    for (; x < d; ++x) {\n      ProcessPixel(pattern4RGB[0], pattern4RGB[0], pattern4RGB[0], x);\n    }\n\n    // 2. PLUGE and Bars (Indices 1 through 9)\n    for (int i = 1; i <= 9; i++) {\n      int endX = d + (pattern4W[i] * c + 3) / 6;\n      for (; x < endX && x < w; ++x) {\n        ProcessPixel(pattern4RGB[i], pattern4RGB[i], pattern4RGB[i], x);\n      }\n    }\n\n    // 3. Right Padding (15% Grey)\n    for (; x < w; ++x) {\n      ProcessPixel(pattern4RGB[0], pattern4RGB[0], pattern4RGB[0], x);\n    }\n\n    pY += pitchY; pU += pitchUV; pV += pitchUV;\n  }\n} // ColorBarsHD\n\n/*******************************************************************\n*\n* ColorBars for YUV formats (BT.601) and and RGB\n*\n*********************************************************************/\n// See also: http://avisynth.nl/index.php/ColorBars_theory\n// and https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/corefilters/colorbars.html\n\n/*\n* Integer 8 bit tables not used anymore, replaced by double-precision RGB tables with\n* accurate RGB and RGB->YUV conversion for better precision and correctness, especially\n* for higher bitdepths.\n\n// Studio RGB constants for ColorBars\nstatic const uint32_t bottom_quarter[] =\n// RGB[16..235]     -I     white        +Q     Black     -4% Black     Black     +4% Black     Black\n               { 0x10466a, 0xebebeb, 0x481076, 0x101010,  0x070707, 0x101010, 0x191919,  0x101010 }; // Qlum=Ilum=13.4%\nstatic const int two_thirds_to_three_quarters[] =\n// RGB[16..235]   Blue     Black  Magenta      Black      Cyan     Black    LtGrey\n               { 0x1010b4, 0x101010, 0xb410b4, 0x101010, 0x10b4b4, 0x101010, 0xb4b4b4 };\nstatic const int top_two_thirds[] =\n// RGB[16..235] LtGrey    Yellow      Cyan     Green   Magenta       Red      Blue\n               { 0xb4b4b4, 0xb4b410, 0x10b4b4, 0x10b410, 0xb410b4, 0xb41010, 0x1010b4 };\n*/\n\n// Ground truth gamma-encoded RGB for ColorBars (Rec. ITU-R BT.801-1).\n// Normalised limited-range signal levels [0.0..1.0]: 0.0 = code 16, 1.0 = code 235.\n// 0.75 = 75% encoded signal swing (E'R/G'B, not linear light).\n// 8-bit studio value: (int)(R * 219.0 + 16.0 + 0.5)\n\n// Top 2/3: LtGrey, Yellow, Cyan, Green, Magenta, Red, Blue\nstatic const double top_two_thirdsR[] = { 0.75, 0.75, 0.0,  0.0,  0.75, 0.75, 0.0 };\nstatic const double top_two_thirdsG[] = { 0.75, 0.75, 0.75, 0.75, 0.0,  0.0,  0.0 };\nstatic const double top_two_thirdsB[] = { 0.75, 0.0,  0.75, 0.0,  0.75, 0.0,  0.75 };\n\n// 2/3 to 3/4: Blue, Black, Magenta, Black, Cyan, Black, LtGrey\nstatic const double two_thirds_to_three_quartersR[] = { 0.0,  0.0, 0.75, 0.0, 0.0,  0.0, 0.75 };\nstatic const double two_thirds_to_three_quartersG[] = { 0.0,  0.0, 0.0,  0.0, 0.75, 0.0, 0.75 };\nstatic const double two_thirds_to_three_quartersB[] = { 0.75, 0.0, 0.75, 0.0, 0.75, 0.0, 0.75 };\n\n/*\n   BOTTOM QUARTER BAR DEFINITIONS (-I, White, +Q, Black, -4%, Black, +4%, Black)\n\n   ============================================================================\n   DERIVATION OF -I AND +Q VALUES\n   ============================================================================\n\n   The -I and +Q signals are defined in the YIQ colorspace as pure chroma-axis\n   signals with zero luma and 20 IRE saturation (0.2162 normalized):\n\n     -I:  I = -0.2162,  Q = 0\n     +Q:  I = 0,        Q = +0.2162\n\n   Converting via the BT.601 UV rotation (Poynton eq. 33, with UV swap):\n\n     -I raw RGB (Y=0):  R = -0.2067,  G = +0.0588,  B = +0.2394\n     +Q raw RGB (Y=0):  R = +0.1343,  G = -0.1400,  B = +0.3685\n\n   Both signals contain out-of-range (negative) RGB components. Three\n   interpretations exist in the literature:\n\n   ---------------------------------------------------------------------------\n   OPTION 1 — Zero-luma, lift to studio black (legacy YUV implementation)\n   ---------------------------------------------------------------------------\n   Y = 16 (studio black). The most negative RGB component is left negative\n   and will encode to a super-black code (0-15 range), or must be clipped\n   when rendering as RGB, distorting the color.\n\n   This is a HACK that had to be applied differently for RGB vs YUV:\n\n   For YUV output (bottom_quarterR/G/B_for_YUV):\n     No lift applied - use raw zero-luma RGB values\n     Result: Y = 16, perfectly preserved chroma-axis definition\n     Consequence: RGB contains super-black components (codes < 16)\n\n   For RGB output (legacy AviSynth approach, NOT current implementation):\n     Each component individually clamped/adjusted to avoid codes < 16\n     Result: RGB codes all ≥ 16, but YUV back-conversion doesn't match\n     Consequence: Loss of theoretical purity, inconsistent RGB↔YUV round-trip\n\n   This was the legacy AviSynth ColorBars implementation:\n     RGB path used bitmap-derived values:  -I = RGB(16, 70, 106)\n     YUV path used zero-luma calculation:  -I = Y16 Cb158 Cr95\n     These two specifications are fundamentally incompatible.\n\n   ---------------------------------------------------------------------------\n   OPTION 2 — Luma-corrected to studio black (CURRENT RGB IMPLEMENTATION)\n   ---------------------------------------------------------------------------\n   Luma is raised until the most negative component reaches code 16\n   (studio black). The lift calculation:\n\n     For -I: Y_lift = 0.2067 - 16/219 = 0.13364\n     For +Q: Y_lift = 0.1400 - 16/219 = 0.06694\n\n   After lifting (bottom_quarterR/G/B arrays, RGB-native):\n     -I: R = 16 (studio black), G = 90, B = 130, Y ≈ 77\n     +Q: R = 92, G = 16 (studio black), B = 143, Y ≈ 63\n\n   This gives a consistent, broadcast-safe signal for RGB output with all\n   components within valid studio range (16-235), but produces different\n   YUV values than the legacy zero-luma specification (Y=77/63 vs Y=16).\n\n   We maintain TWO separate ground truth tables to preserve legacy compatibility:\n\n   1. bottom_quarterR/G/B (Option 2):\n      - Used for RGB output formats\n      - all I and Q codes >= 16\n      - Colorimetrically consistent RGB↔YUV conversion\n\n   2. bottom_quarterR/G/B_for_YUV (Option 1 YUV side):\n      - Used for YUV output formats\n      - Produces exact legacy values: -I Y=16, +Q Y=16\n      - Contains out-of-range RGB components (will clip if rendered as RGB)\n\n   This dual-table approach acknowledges the historical reality: the original\n   AviSynth ColorBars had two independent specifications that don't convert\n   to each other via standard matrix math. The -I and +Q signals were analog\n   broadcast test signals (voltage levels), not digital RGB/YUV values, and\n   their digital representation requires compromises.\n\n   So we use different linear RGB tables for -I and +Q bars, depending on whether\n   the target is RGB or YUV, to best match legacy values in each domain.\n   Note that moving I and Q values to provide legal RGB and YUV values is a \"hack\".\n   These values match the legacy Avisynth.\n*/\n\n// ===== RGB-NATIVE GROUND TRUTH =====\n// For RGB output formats only.\n// Luma-corrected: most negative component lifted to studio black (code 16).\n// -I: R lifted to code 16  ->  RGB(16, 90, 130) at 8-bit\n// +Q: G lifted to code 16  ->  RGB(92, 16, 143) at 8-bit\n// Convention: 0.0 = code 16 (studio black), 1.0 = code 235 (studio white)\nstatic const double bottom_quarterR[] = { MINUS_I_R, 1.0, PLUS_Q_R, 0.0, -0.04, 0.0, 0.04, 0.0 };\nstatic const double bottom_quarterG[] = { MINUS_I_G, 1.0, PLUS_Q_G, 0.0, -0.04, 0.0, 0.04, 0.0 };\nstatic const double bottom_quarterB[] = { MINUS_I_B, 1.0, PLUS_Q_B, 0.0, -0.04, 0.0, 0.04, 0.0 };\n\n// ===== YUV-TARGETED RGB GROUND TRUTH =====\n// For YUV output formats only.\n// When converted via GetYUVBT601fromRGB, produces legacy YUV values:\n// -I: Y=16, Cb=158, Cr=95   (zero-luma, pure chroma definition)\n// +Q: Y=16, Cb=174, Cr=149  (zero-luma, pure chroma definition)\n// Note: Contains out-of-range values (R < 0 for -I, G < 0 for +Q)\n//       which will be clamped when rendering RGB formats.\n// Convention: 0.0 = code 16 (studio black), 1.0 = code 235 (studio white)\nstatic const double bottom_quarterR_for_YUV[] = { MINUS_I_R_YUV, 1.0, PLUS_Q_R_YUV, 0.0, -0.04, 0.0, 0.04, 0.0 };\nstatic const double bottom_quarterG_for_YUV[] = { MINUS_I_G_YUV, 1.0, PLUS_Q_G_YUV, 0.0, -0.04, 0.0, 0.04, 0.0 };\nstatic const double bottom_quarterB_for_YUV[] = { MINUS_I_B_YUV, 1.0, PLUS_Q_B_YUV, 0.0, -0.04, 0.0, 0.04, 0.0 };\n\n/*******************************************************************\n* ColorBars for YUV \n*********************************************************************/\n\nstatic void GetYUVBT601fromRGB(double R, double G, double B, double& dY, double& dU, double& dV)\n{\n  // See https://www.itu.int/rec/R-REC-BT.601/en\n  double Kr, Kb;\n  GetKrKb(AVS_MATRIX_ST170_M, Kr, Kb); // BT601: Kr=0.299, Kb=0.114\n  dY = Kr * R + (1.0 - Kr - Kb) * G + Kb * B;\n  dU = (B - dY) / (2.0 * (1.0 - Kb));\n  dV = (R - dY) / (2.0 * (1.0 - Kr));\n}\n\n// BT.601 YUV conversion constants for ColorBars (Rec. ITU-R BT.801-1)\n// Ground truth linear RGB -> BT.601 YUV, integer and float limited range output.\n// Replaces the old hardcoded 8-bit tables.\n\n// Bar boundaries are computed in chroma coordinates so that color transitions\n// always fall on chroma-aligned luma positions (a multiple of the horizontal\n// subsampling factor). This satisfies the requirement from Rec. ITU-R BT.801-1\n// that transitions occur on chroma-aligned boundaries.\n// Note: due to integer rounding, boundary positions may differ by +/-1 luma pixel\n// compared to a 4:4:4 or RGB rendering of the same width, which is unavoidable\n// when 7 bars do not divide evenly into the frame width.\ntemplate<typename pixel_t, bool is420, bool is422, bool is411>\nstatic void draw_colorbars_yuv(uint8_t* pY8, uint8_t* pU8, uint8_t* pV8, int pitchY, int pitchUV, int w, int h, int bits_per_pixel)\n{\n  pixel_t* pY = reinterpret_cast<pixel_t*>(pY8);\n  pixel_t* pU = reinterpret_cast<pixel_t*>(pU8);\n  pixel_t* pV = reinterpret_cast<pixel_t*>(pV8);\n  pitchY /= sizeof(pixel_t);\n  pitchUV /= sizeof(pixel_t);\n\n  const int shift = sizeof(pixel_t) == 4 ? 0 : (bits_per_pixel - 8);\n\n  // Pre-compute conversion constants for float limited range,\n  // using the same centralized function as ColorbarsHD.\n\n  // Also for float target we make \"limited\" range\n  bits_conv_constants luma, chroma;\n  // RGB is source, YUV is destination\n  // For RGB source / Y destination (both luma-like):\n  const bool full_scale_s = true; // full scale reference\n  const bool full_scale_d = false; // narrow range reference\n  get_bits_conv_constants(luma, false, full_scale_s, full_scale_d, 32, 32);\n  // For UV destination (chroma behavior):\n  // Note: we only need dst_span for UV, so we use full_scale_d for both params\n  get_bits_conv_constants(chroma, true, full_scale_s, full_scale_d, 32, 32);\n\n  double float_offset = luma.dst_offset;\n  double float_scale = luma.mul_factor; // 219.0 / 255.0;\n  double float_uv_scale = chroma.mul_factor;\n\n  // Convert one RGB triplet to a YUV pixel triplet at target bit depth.\n  struct YUV3 { pixel_t y, u, v; };\n\n  // Helper to process and write a pixel based on RGB input\n  // Convention: encoded signal levels; 0.0 = code 16 (studio black), 1.0 = code 235 (studio white)\n\n  auto make_yuv = [&](double r, double g, double b) -> YUV3 {\n    XP_LAMBDA_CAPTURE_FIX(float_scale);\n    XP_LAMBDA_CAPTURE_FIX(float_offset);\n    XP_LAMBDA_CAPTURE_FIX(float_uv_scale);\n    XP_LAMBDA_CAPTURE_FIX(shift);\n    double dY, dU, dV;\n    GetYUVBT601fromRGB(r, g, b, dY, dU, dV);\n\n    if constexpr (std::is_same<pixel_t, float>::value) {\n      return {\n        (pixel_t)(dY * float_scale + float_offset),\n        (pixel_t)(dU * float_uv_scale),\n        (pixel_t)(dV * float_uv_scale)\n      };\n    }\n    else {\n      // High-precision calculation for 10/12/16-bit\n      return {\n        (pixel_t)(((dY * 219.0 + 16.0) * (1 << shift)) + 0.5),\n        (pixel_t)(((dU * 224.0 + 128.0) * (1 << shift)) + 0.5),\n        (pixel_t)(((dV * 224.0 + 128.0) * (1 << shift)) + 0.5)\n      };\n    }\n    };\n\n  // Pre-compute all bar entries from ground truth RGB tables.\n  YUV3 bq[8], ttq[7], ttt[7];\n  for (int i = 0; i < 8; ++i)\n    bq[i] = make_yuv(bottom_quarterR_for_YUV[i], bottom_quarterG_for_YUV[i], bottom_quarterB_for_YUV[i]);\n  for (int i = 0; i < 7; ++i)\n    ttq[i] = make_yuv(two_thirds_to_three_quartersR[i], two_thirds_to_three_quartersG[i], two_thirds_to_three_quartersB[i]);\n  for (int i = 0; i < 7; ++i)\n    ttt[i] = make_yuv(top_two_thirdsR[i], top_two_thirdsG[i], top_two_thirdsB[i]);\n\n  // Write luma for one chroma-sample position x.\n  // For subsampled formats, each chroma x covers multiple luma pixels.\n  // For 444, chromaX == lumaX directly.\n  auto write_luma = [&](int x, pixel_t yval) {\n    XP_LAMBDA_CAPTURE_FIX(pitchY);\n    if constexpr (is420)\n      pY[x * 2 + 0] = pY[x * 2 + 1] = pY[x * 2 + pitchY] = pY[x * 2 + 1 + pitchY] = yval;\n    else if constexpr (is422)\n      pY[x * 2 + 0] = pY[x * 2 + 1] = yval;\n    else if constexpr (is411)\n      pY[x * 4 + 0] = pY[x * 4 + 1] = pY[x * 4 + 2] = pY[x * 4 + 3] = yval;\n    else // 444\n      pY[x] = yval;\n    };\n\n  auto write_yuv = [&](int x, const YUV3& c) {\n    write_luma(x, c.y);\n    pU[x] = c.u;\n    pV[x] = c.v;\n    };\n\n  // For subsampled formats the chroma plane is narrower/shorter.\n  // We iterate in chroma coordinates; write_luma expands to luma coordinates.\n  int wUV = w;\n  int hUV = h;\n  if constexpr (is420 || is422) wUV >>= 1;\n  if constexpr (is411)          wUV >>= 2;\n  if constexpr (is420)          hUV >>= 1;\n\n  int y = 0;\n\n  // Top 2/3\n  for (; y * 3 < hUV * 2; ++y) {\n    int x = 0;\n    for (int i = 0; i < 7; ++i)\n      for (; x < (wUV * (i + 1) + 3) / 7; ++x)\n        write_yuv(x, ttt[i]);\n    if constexpr (is420)\n      pY += pitchY * 2;\n    else\n      pY += pitchY;\n    pU += pitchUV; pV += pitchUV;\n  }\n\n  // Middle band (2/3 to 3/4)\n  for (; y * 4 < hUV * 3; ++y) {\n    int x = 0;\n    for (int i = 0; i < 7; ++i)\n      for (; x < (wUV * (i + 1) + 3) / 7; ++x)\n        write_yuv(x, ttq[i]);\n    if constexpr (is420)\n      pY += pitchY * 2;\n    else\n      pY += pitchY;\n    pU += pitchUV; pV += pitchUV;\n  }\n\n  // Bottom quarter\n  for (; y < hUV; ++y) {\n    int x = 0;\n    for (int i = 0; i < 4; ++i)\n      for (; x < (wUV * (i + 1) * 5 + 14) / 28; ++x)\n        write_yuv(x, bq[i]);\n    for (int j = 4; j < 7; ++j)\n      for (; x < (wUV * (j + 12) + 10) / 21; ++x)\n        write_yuv(x, bq[j]);\n    for (; x < wUV; ++x)\n      write_yuv(x, bq[7]);\n    if constexpr (is420)\n      pY += pitchY * 2;\n    else\n      pY += pitchY;\n    pU += pitchUV; pV += pitchUV;\n  }\n}\n\n/*******************************************************************\n* ColorBars for RGB (packed 32/64, 24/48, planar RGB)\n*********************************************************************/\n\n// Convert normalised linear RGB [0.0..1.0] to integer studio/limited RGB at any bit depth.\n// Limited range: black = 16 << (bpp-8), white = 235 << (bpp-8)\n// Values outside [0.0..1.0] (e.g. PLUGE -4%, +4%) are handled naturally.\nstatic int studio_rgb_to_integer(double value, int bits_per_pixel)\n{\n  const int offset = 16 << (bits_per_pixel - 8);\n  const int range = 219 << (bits_per_pixel - 8);\n  return (int)(value * range + offset + 0.5);\n}\n\ntemplate<typename pixel_t>\nstatic void draw_colorbars_rgb3264(uint8_t* p8, int pitch, int w, int h)\n{\n  typedef typename std::conditional<sizeof(pixel_t) == 2, uint64_t, uint32_t>::type internal_pixel_t;\n  internal_pixel_t* p = reinterpret_cast<internal_pixel_t*>(p8);\n  pitch /= sizeof(pixel_t);\n\n  // Pre-compute packed pixel values from ground truth double tables at target bit depth.\n  // Pack order in uint32: 0x00RRGGBB, in uint64: RR(16)GG(16)BB(16) (alpha/padding zero)\n  // RGB32/64 pixel layout (bottom byte = B, then G, then R, then pad/alpha)\n  auto make_pixel = [&](double r, double g, double b) -> internal_pixel_t {\n    if constexpr (sizeof(pixel_t) == 1) {\n      // RGB32: 8-bit per channel, packed as 0x00RRGGBB\n      uint32_t ri = (uint32_t)studio_rgb_to_integer(r, 8);\n      uint32_t gi = (uint32_t)studio_rgb_to_integer(g, 8);\n      uint32_t bi = (uint32_t)studio_rgb_to_integer(b, 8);\n      return (internal_pixel_t)((ri << 16) | (gi << 8) | bi);\n    }\n    else {\n      // RGB64: 16-bit per channel\n      uint64_t ri = (uint64_t)studio_rgb_to_integer(r, 16);\n      uint64_t gi = (uint64_t)studio_rgb_to_integer(g, 16);\n      uint64_t bi = (uint64_t)studio_rgb_to_integer(b, 16);\n      return (internal_pixel_t)((ri << 32) | (gi << 16) | bi);\n    }\n    };\n\n  // Pre-compute all entries (bottom->top scan order matches original)\n  internal_pixel_t bq[8], ttq[7], ttt[7];\n  for (int i = 0; i < 8; ++i)\n    bq[i] = make_pixel(bottom_quarterR[i], bottom_quarterG[i], bottom_quarterB[i]);\n  for (int i = 0; i < 7; ++i)\n    ttq[i] = make_pixel(two_thirds_to_three_quartersR[i], two_thirds_to_three_quartersG[i], two_thirds_to_three_quartersB[i]);\n  for (int i = 0; i < 7; ++i)\n    ttt[i] = make_pixel(top_two_thirdsR[i], top_two_thirdsG[i], top_two_thirdsB[i]);\n\n  // note we go bottom->top\n  int y = 0;\n  for (; y < h / 4; ++y) {\n    int x = 0;\n    for (int i = 0; i < 4; ++i)\n      for (; x < (w * (i + 1) * 5 + 14) / 28; ++x)\n        p[x] = bq[i];\n    for (int j = 4; j < 7; ++j)\n      for (; x < (w * (j + 12) + 10) / 21; ++x)\n        p[x] = bq[j];\n    for (; x < w; ++x)\n      p[x] = bq[7];\n    p += pitch;\n  }\n  for (; y < h / 3; ++y) {\n    int x = 0;\n    for (int i = 0; i < 7; ++i)\n      for (; x < (w * (i + 1) + 3) / 7; ++x)\n        p[x] = ttq[i];\n    p += pitch;\n  }\n  for (; y < h; ++y) {\n    int x = 0;\n    for (int i = 0; i < 7; ++i)\n      for (; x < (w * (i + 1) + 3) / 7; ++x)\n        p[x] = ttt[i];\n    p += pitch;\n  }\n}\n\n\ntemplate<typename pixel_t>\nstatic void draw_colorbars_rgb2448(uint8_t* p8, int pitch, int w, int h)\n{\n  pixel_t* p = reinterpret_cast<pixel_t*>(p8);\n  pitch /= sizeof(pixel_t);\n\n  // Pre-computed triplets from ground truth double tables\n  struct RGB3 { pixel_t r, g, b; };\n\n  auto make_rgb3 = [&](double r, double g, double b) -> RGB3 {\n    return {\n      (pixel_t)studio_rgb_to_integer(r, sizeof(pixel_t) == 1 ? 8 : 16),\n      (pixel_t)studio_rgb_to_integer(g, sizeof(pixel_t) == 1 ? 8 : 16),\n      (pixel_t)studio_rgb_to_integer(b, sizeof(pixel_t) == 1 ? 8 : 16)\n    };\n    };\n\n  // Pre-compute all entries (bottom->top scan order matches original)\n  RGB3 bq[8], ttq[7], ttt[7];\n  for (int i = 0; i < 8; ++i)\n    bq[i] = make_rgb3(bottom_quarterR[i], bottom_quarterG[i], bottom_quarterB[i]);\n  for (int i = 0; i < 7; ++i)\n    ttq[i] = make_rgb3(two_thirds_to_three_quartersR[i], two_thirds_to_three_quartersG[i], two_thirds_to_three_quartersB[i]);\n  for (int i = 0; i < 7; ++i)\n    ttt[i] = make_rgb3(top_two_thirdsR[i], top_two_thirdsG[i], top_two_thirdsB[i]);\n\n  auto write_pixel = [&](int x, const RGB3& c) {\n    p[x * 3 + 0] = c.b;  // RGB24/48 memory layout: B, G, R\n    p[x * 3 + 1] = c.g;\n    p[x * 3 + 2] = c.r;\n    };\n\n  // note we go bottom->top\n  int y = 0;\n  for (; y < h / 4; ++y) {\n    int x = 0;\n    for (int i = 0; i < 4; ++i)\n      for (; x < (w * (i + 1) * 5 + 14) / 28; ++x)\n        write_pixel(x, bq[i]);\n    for (int j = 4; j < 7; ++j)\n      for (; x < (w * (j + 12) + 10) / 21; ++x)\n        write_pixel(x, bq[j]);\n    for (; x < w; ++x)\n      write_pixel(x, bq[7]);\n    p += pitch;\n  }\n  for (; y < h / 3; ++y) {\n    int x = 0;\n    for (int i = 0; i < 7; ++i)\n      for (; x < (w * (i + 1) + 3) / 7; ++x)\n        write_pixel(x, ttq[i]);\n    p += pitch;\n  }\n  for (; y < h; ++y) {\n    int x = 0;\n    for (int i = 0; i < 7; ++i)\n      for (; x < (w * (i + 1) + 3) / 7; ++x)\n        write_pixel(x, ttt[i]);\n    p += pitch;\n  }\n}\n\ntemplate<typename pixel_t>\nstatic void draw_colorbars_rgbp(uint8_t* pR8, uint8_t* pG8, uint8_t* pB8, int pitch, int w, int h, int bits_per_pixel)\n{\n  pixel_t* pR = reinterpret_cast<pixel_t*>(pR8);\n  pixel_t* pG = reinterpret_cast<pixel_t*>(pG8);\n  pixel_t* pB = reinterpret_cast<pixel_t*>(pB8);\n  pitch /= sizeof(pixel_t);\n\n  struct RGB3 { pixel_t r, g, b; };\n\n  bits_conv_constants rgb_luma_f;\n  // source: full range [0..1] RGB, destination: limited range float\n  // rgb_luma_f.mul_factor = 219.0/255.0\n  // rgb_luma_f.dst_offset = 16.0/255.0\n  get_bits_conv_constants(rgb_luma_f, false /*use_chroma*/, true /*fulls*/, false/*fulld*/, 32, 32);\n\n  auto make_rgb3 = [&](double r, double g, double b) -> RGB3 {\n\n    if constexpr(std::is_same<pixel_t, float>::value) {\n      return {\n        (float)(r * rgb_luma_f.mul_factor + rgb_luma_f.dst_offset),\n        (float)(g * rgb_luma_f.mul_factor + rgb_luma_f.dst_offset),\n        (float)(b * rgb_luma_f.mul_factor + rgb_luma_f.dst_offset)\n      };\n    }\n    else {\n      return {\n        (pixel_t)studio_rgb_to_integer(r, bits_per_pixel),\n        (pixel_t)studio_rgb_to_integer(g, bits_per_pixel),\n        (pixel_t)studio_rgb_to_integer(b, bits_per_pixel)\n      };\n    }\n    };\n\n  RGB3 bq[8], ttq[7], ttt[7];\n  for (int i = 0; i < 8; ++i)\n    bq[i] = make_rgb3(bottom_quarterR[i], bottom_quarterG[i], bottom_quarterB[i]);\n  for (int i = 0; i < 7; ++i)\n    ttq[i] = make_rgb3(two_thirds_to_three_quartersR[i], two_thirds_to_three_quartersG[i], two_thirds_to_three_quartersB[i]);\n  for (int i = 0; i < 7; ++i)\n    ttt[i] = make_rgb3(top_two_thirdsR[i], top_two_thirdsG[i], top_two_thirdsB[i]);\n\n  auto write_pixel = [&](int x, const RGB3& c) {\n    pR[x] = c.r;\n    pG[x] = c.g;\n    pB[x] = c.b;\n    };\n\n  // Planar RGB is top-to-bottom natively, no bottom-up workaround needed.\n  // layout top->bottom: top_two_thirds, two_thirds_to_three_quarters, bottom_quarter\n  int y = 0;\n\n  // Top 2/3\n  for (; y * 3 < h * 2; ++y) {\n    int x = 0;\n    for (int i = 0; i < 7; ++i)\n      for (; x < (w * (i + 1) + 3) / 7; ++x)\n        write_pixel(x, ttt[i]);\n    pR += pitch; pG += pitch; pB += pitch;\n  }\n\n  // Middle band (2/3 to 3/4)\n  for (; y * 4 < h * 3; ++y) {\n    int x = 0;\n    for (int i = 0; i < 7; ++i)\n      for (; x < (w * (i + 1) + 3) / 7; ++x)\n        write_pixel(x, ttq[i]);\n    pR += pitch; pG += pitch; pB += pitch;\n  }\n\n  // Bottom quarter\n  for (; y < h; ++y) {\n    int x = 0;\n    for (int i = 0; i < 4; ++i)\n      for (; x < (w * (i + 1) * 5 + 14) / 28; ++x)\n        write_pixel(x, bq[i]);\n    for (int j = 4; j < 7; ++j)\n      for (; x < (w * (j + 12) + 10) / 21; ++x)\n        write_pixel(x, bq[j]);\n    for (; x < w; ++x)\n      write_pixel(x, bq[7]);\n    pR += pitch; pG += pitch; pB += pitch;\n  }\n}\n\n/*******************************************************************\n*\n* ColorBarsUHD for YUV 444 formats (BT.2100 / BT.2111-3)\n*\n* Implements Recommendation ITU-R BT.2111-3 (05/2025):\n* \"Specification of color bar test pattern for HDR television systems\"\n*\n* Three subtypes (BT.2111-3 Annex 1, §4):\n*   subtype 0: HLG narrow range  (Fig. 1, Table 2)\n*   subtype 1: PQ narrow range   (Fig. 2, Table 3)\n*   subtype 2: PQ full range     (Fig. 3, Table 4)\n*\n* ColorBarsUHD approach: BT.2111-3 hands you the exact 10-bit R'G'B' integer code values directly in Tables 2/3/4. You do not derive them from floating-point primaries. The flow is:\n* - Look up 10-bit R'G'B' from the table\n* - Scale to target bit depth (10->12 is << 2; 10->16 is << 6; 10->8 is >> 2 with rounding)\n* - Convert R'G'B' -> YCbCr using BT.2020 NCL matrix (Kr=0.2627, Kb=0.0593) for YUV output\n* - For float: normalise to limited-range float\n* Source code values are 10-bit integers taken directly from BT.2111-3 Tables 2/3/4.\n* 12-bit values are derived by left-shifting 10-bit values by 2 (BT.2111-3 §5).\n* Other bit depths are scaled proportionally from the 10-bit reference.\n*\n* Unlike ColorBars/ColorBarsHD, no floating-point RGB primaries are stored here.\n* BT.2111-3 specifies the signal levels directly as R'G'B' code values in the\n* transfer-function-encoded (non-linear) domain. There is no Kr/Kb matrix\n* derivation step — the standard pre-computes everything including the\n* BT.709-equivalent bars (via the proper linear-light BT.2407 matrix path).\n*\n* YCbCr output uses BT.2100 NCL matrix: Kr=0.2627, Kb=0.0593 (same as BT.2020).\n*\n* Layout dimensions (Table 1):\n*   a = frame width  (1920 / 3840 / 7680 for 2K/4K/8K)\n*   b = frame height (1080 / 2160 / 4320)\n*   c = a/8 = color bar unit width\n*   d = left/right optional grey pad (from Table 1)\n*   e,f,g,h,i,j,k = row heights and ramp geometry (from Table 1)\n*\n* Ramp (Tables 5/6): full sweep from -7%(min) to 109%(max) of the encoded range.\n*   Positioned so that 0% aligns with the left edge of the Green color bar.\n* Stair: 12 steps (0%,10%,...,100%,109%), each c/2 wide.\n*   Left edge of 0% step aligns with left edge of Yellow bar.\n* PLUGE: 0%, -2%, 0%, +2%, 0%, +4%, 0% black levels (bottom row).\n*\n* The critical signal level difference between subtypes is:\n* \n* HLG: primary bars are 75% (code 721 at 10-bit narrow)\n* PQ narrow/full: primary bars are 100% top row + 58% second row (58% = 203 cd/m² = equivalent to 75% HLG)\n* Full range: black = code 0, white = 1023; narrow range: black = 64, white = 940\n* \n*********************************************************************/\n\n// BT.2100 NCL (= BT.2020) matrix coefficients\nstatic void GetYUVBT2020fromRGB(double R, double G, double B, double& dY, double& dU, double& dV)\n{\n  // BT.2100 / BT.2020 NCL: Kr=0.2627, Kb=0.0593\n  // See https://www.itu.int/rec/R-REC-BT.2100/en\n  double Kr, Kb;\n  GetKrKb(AVS_MATRIX_BT2020_NCL, Kr, Kb);\n  dY = Kr * R + (1.0 - Kr - Kb) * G + Kb * B;\n  dU = (B - dY) / (2.0 * (1.0 - Kb));\n  dV = (R - dY) / (2.0 * (1.0 - Kr));\n}\n\n/*\n  BT.2111-3 Layout (same spatial structure for HLG, PQ narrow, PQ full range):\n          2K     4K     8K\n  a     1920   3840   7680 full width, a = 2c + 6d + e\n  b     1080   2160   4320 full height\n  c      240    480    960 left/right grey pad width  (a/8)\n  d      206    412    824 standard color bar width  (most bars)\n  e      204    408    816 green bar width            (wider than d)\n  f      136    272    544\n  g       70    140    280\n  h       68    136    272\n  i      238    476    952\n  j      438    876   1752\n  k      282    564   1128\n\n  NOTE: d > e at 2K (206 > 204). The green bar is narrower than the others, absorbs the rounding differences.\n\n  ←—————————————————————————— a ———-—————————————————————→\n  +--d--+--c---+--c--+--c--+--e--+--c--+--c--+--c--+--d--+\n  |     |100%  |100% |100% |100% |100% |100% |100% |     |  height = b/12 (100% bars)\n  |     |White |Yell |Cyan |Green|Mag  |Red  |Blue |     |\n  + Grey+------+-----+-----+-----+-----+-----+-----+ Grey+\n  | 40% |      |     |     |     |     |     |     | 40% |\n  |     |75%   |75%  |75%  |75%  |75%  |75%  |75%  |     |  height = b/2 (HLG: 75%; PQ: 58% bars)\n  |     |White |Yell |Cyan |Green|Mag  |Red  |Blue |     |\n  +-----+------+-----+-----+-----+-----+-----+-----+-----+\n  |     |      |  |  |  |  |  |  |  |  |  |  | 1|1 |     |  Stair\n  | 75% |-7%   |0%|10|20|30|40|50|60|70|80|90| 0|0 | 75% |  height: b/12\n  |White|step  |step |step |step |step |step | 0|9 |White|  PQ Full: 0%/100% instead of -7/109%\n  +-----+------+-----+-----+-----+-----+-----+-----+-----+\n  | 0%  |←—————————————————— ramp -—————————————————————→|  Black, lead-in, ramp, lead-out\n  | Blk | HLG/PQ-narrow:-7 to 109% PQ-full:0 to 100%     |  height = b/12\n  +-+-+-+----+-+-+-+-+-+------+-----------+--------+-+-+-+\n  | | | | 0% | | | | | |  0%  |    75%    |   0%   | | | | BT.709 bars, Black, PLUGE, Black, White, Black, BT.709 bars\n  | | | |Blk | | | | | |Black |   White   | Black  | | | | height = b/4\n  |BT709|    | pluge   |      |           |        |BT709| Bars: Yellow,Cyan, Green (left), Magenta, Red, Blue (right)\n  +-+-+-+----+-+-+-+-+-+------+-----------+--------+-+-+-+\n   c c c   f  g h g h g    i        j          k    c c c \n   / / /                                            / / /\n   3 3 3                                            3 3 3\n\n  NOTE: \"It is desirable that implementers should include in this test signal some\n  visual identification of the signal format (HLG narrow range, PQ narrow range, or\n  PQ full range). The test pattern includes grey bars (top right and top left) that\n  may optionally be used for this and/or other purposes.\"\n  We fill them with 40% Grey.\n\n  Ramp and stair are placed so they do NOT overlap on a waveform monitor:\n  - Ramp: positioned so 0% aligns with left edge of Green bar (Table 5/6 column B/C/D)\n  - Stair: left edge of 0% step aligns with left edge of Yellow bar\n  - Each stair step is half a color bar (c/2) wide, 11 steps: 0%,10%,...,100%.\n*/\ntemplate<typename pixel_t, bool is_rgb>\nstatic void draw_colorbarsUHD_444_rgb(uint8_t* pY8, uint8_t* pU8, uint8_t* pV8,\n  int pitchY, int pitchUV,\n  int w, int h, int bits_per_pixel, int subtype)\n{\n  pixel_t* pYG = reinterpret_cast<pixel_t*>(pY8); // Y plane, or G plane for RGB (GBR order)\n  pixel_t* pUB = reinterpret_cast<pixel_t*>(pU8); // U plane, or B plane for RGB\n  pixel_t* pVR = reinterpret_cast<pixel_t*>(pV8); // V plane, or R plane for RGB\n  pitchY /= sizeof(pixel_t);\n  pitchUV /= sizeof(pixel_t);\n\n  // -- Bit-depth scaling via get_bits_conv_constants -------------------------\n  //\n  // BT.2111-3 §5: 10-bit is the primary reference for narrow range.\n  // YUV is derived via BT.2020 NCL matrix, then scaled to target bit depth.\n  // Narrow range (subtypes 0/1): black=64, white=940, limited swing.\n  //   Integer scaling: pure bit-shift (limited->limited is exact per §5).\n  // Full range (subtype 2): black=0, white=1023/4095, full swing.\n  //   10-bit AND 12-bit are INDEPENDENTLY specified by ITU (Table 4).\n  //   Neither is derivable from the other by simple bit-shift.\n  //   Other depths: scale from 12-bit ITU reference via round(code12/4095*(vmax-1)).\n  // Float (any subtype): normalised via get_bits_conv_constants to Avisynth's\n  //   float convention (luma 0.0..1.0 maps to black..white).\n  //   Float always uses full-range normalisation; external tools use this convention.\n  //\n  // Pre-compute conversion constants for luma and chroma.\n  // Source: 10-bit reference. Destination: target depth and range.\n  constexpr bool is_float_output = std::is_same<pixel_t, float>::value;\n  const bool is_full_range = subtype == 2;\n  // Float output always uses full-range normalisation regardless of subtype.\n  const bool is_full_range_target = is_full_range || is_float_output;\n  constexpr int src_bits = 10;\n\n  bits_conv_constants luma_c, chroma_c;\n  bits_conv_constants luma_c_from_float, chroma_c_from_float;\n\n  // Used by make_yuv to normalise native pixel_t RGB before BT.2020 matrix.\n  // src: target bit depth and range. dst: float full range.\n  bits_conv_constants luma_c_to_float;\n  if constexpr (!is_rgb) {\n  }\n\n  get_bits_conv_constants(luma_c, false, is_full_range, is_full_range_target, src_bits, bits_per_pixel);\n  if constexpr (!is_rgb) {\n    // YUV output helpers\n    get_bits_conv_constants(luma_c_to_float, false,\n      is_full_range_target,  // src range matches target\n      true,                  // dst is float full range [0..1]\n      bits_per_pixel, 32);\n\n    // luma_c_from_float: float BT.2020 matrix luma output [0..1] → target depth\n    get_bits_conv_constants(luma_c_from_float, false,\n      true,\n      is_full_range_target, 32, bits_per_pixel);\n    // chroma_c_from_float: float BT.2020 matrix chroma output [-0.5..+0.5] → target depth\n    get_bits_conv_constants(chroma_c_from_float, true,\n      true,                  // src is always full-range float\n      is_full_range_target,  // dst matches target signal range\n      32, bits_per_pixel);\n    get_bits_conv_constants(chroma_c, true, is_full_range, is_full_range_target, src_bits, bits_per_pixel);\n  }\n\n  // -- Bar geometry from BT.2111-3 Table 1 ----------------------------------\n  // All values scaled from 2K reference (a=1920, c=240, d=206).\n  const int c_bar = (240 * w + 960) / 1920; // left/right grey pad\n  const int d_bar = (206 * w + 960) / 1920; // standard bar width\n  const int e_bar = w - 2 * c_bar - 6 * d_bar;  // green bar (remainder, absorbs rounding)\n  const int bar_White = c_bar;\n  const int bar_Yellow = c_bar + d_bar;\n  const int bar_Cyan = c_bar + 2 * d_bar;\n  const int bar_Green = c_bar + 3 * d_bar;\n  const int bar_Magenta = c_bar + 3 * d_bar + e_bar;\n  const int bar_Red = c_bar + 4 * d_bar + e_bar;\n  const int bar_Blue = c_bar + 5 * d_bar + e_bar;\n  const int bar_RightC = c_bar + 6 * d_bar + e_bar; // = w - c_bar\n  const int barend_White = bar_Yellow;\n  const int barend_Yellow = bar_Cyan;\n  const int barend_Cyan = bar_Green;\n  const int barend_Green = bar_Magenta;\n  const int barend_Magenta = bar_Red;\n  const int barend_Red = bar_Blue;\n  const int barend_Blue = bar_RightC;\n\n  // -- Vertical row heights --------------------------------------------------\n  const int row1 = (h + 6) / 12;      // b/12: 100% bars\n  const int row2 = (h * 6 + 6) / 12;  // b/2:  75%/58% bars\n  const int row3 = (h + 6) / 12;      // b/12: stair\n  const int row4 = (h + 6) / 12;      // b/12: ramp\n  const int y1 = row1;\n  const int y2 = y1 + row2;\n  const int y3 = y2 + row3;\n  const int y4 = y3 + row4;\n\n  // -- Bottom row geometry --------------------------------------------------\n  const int bt709_bar_w = c_bar / 3;\n  const int f_pluge = (136 * w + 960) / 1920;\n  const int g_pluge = (70 * w + 960) / 1920;\n  const int h_pluge = (68 * w + 960) / 1920;\n  const int i_span = (238 * w + 960) / 1920;\n  const int j_span = (438 * w + 960) / 1920;\n  const int k_span = (282 * w + 960) / 1920;\n\n  // =========================================================================\n  // -- Signal level tables (BT.2111-3) — ITU source values ------------------\n  // =========================================================================\n  // color bar order in Tables 2/3/4:\n  //   [0]=White [1]=Yellow [2]=Cyan [3]=Green [4]=Magenta [5]=Red [6]=Blue\n  //\n  // 100% bars — narrow range 10-bit (Tables 2/3):\n  static const int bars100_R_narrow_10[] = { 940, 940,  64,  64, 940, 940,  64 };\n  static const int bars100_G_narrow_10[] = { 940, 940, 940, 940,  64,  64,  64 };\n  static const int bars100_B_narrow_10[] = { 940,  64, 940,  64, 940,  64, 940 };\n  // 100% bars — full range 10-bit (Table 4): 0=black, 1023=white\n  static const int bars100_R_fr10[] = { 1023, 1023,    0,    0, 1023, 1023,    0 };\n  static const int bars100_G_fr10[] = { 1023, 1023, 1023, 1023,    0,    0,    0 };\n  static const int bars100_B_fr10[] = { 1023,    0, 1023,    0, 1023,    0, 1023 };\n  // 100% bars — full range 12-bit (Table 4): 0=black, 4095=white\n  static const int bars100_R_fr12[] = { 4095, 4095,    0,    0, 4095, 4095,    0 };\n  static const int bars100_G_fr12[] = { 4095, 4095, 4095, 4095,    0,    0,    0 };\n  static const int bars100_B_fr12[] = { 4095,    0, 4095,    0, 4095,    0, 4095 };\n\n  // 75% HLG primary bars — narrow range 10-bit (Table 2):\n  static const int bars75hlg_R_10[] = { 721, 721,  64,  64, 721, 721,  64 };\n  static const int bars75hlg_G_10[] = { 721, 721, 721, 721,  64,  64,  64 };\n  static const int bars75hlg_B_10[] = { 721,  64, 721,  64, 721,  64, 721 };\n\n  // 58% PQ primary bars — narrow range 10-bit (Table 3):\n  static const int bars58pq_R_10[] = { 573, 573,  64,  64, 573, 573,  64 };\n  static const int bars58pq_G_10[] = { 573, 573, 573, 573,  64,  64,  64 };\n  static const int bars58pq_B_10[] = { 573,  64, 573,  64, 573,  64, 573 };\n  // 58% PQ primary bars — full range 10-bit (Table 4):\n  static const int bars58pq_R_fr10[] = { 594, 594,    0,    0, 594, 594,    0 };\n  static const int bars58pq_G_fr10[] = { 594, 594, 594, 594,    0,    0,    0 };\n  static const int bars58pq_B_fr10[] = { 594,    0, 594,    0, 594,    0, 594 };\n  // 58% PQ primary bars — full range 12-bit (Table 4):\n  static const int bars58pq_R_fr12[] = { 2378, 2378,    0,    0, 2378, 2378,    0 };\n  static const int bars58pq_G_fr12[] = { 2378, 2378, 2378, 2378,    0,    0,    0 };\n  static const int bars58pq_B_fr12[] = { 2378,    0, 2378,    0, 2378,    0, 2378 };\n\n  // BT.709-equivalent bars — order: [0]=Yellow [1]=Cyan [2]=Green [3]=Magenta [4]=Red [5]=Blue\n  // Pre-computed via BT.2111-3 Attachment 1 / BT.2407 colorimetric conversion.\n  // Full range 10-bit and 12-bit are independently rounded from the underlying\n  // colorimetric float — neither reproduces the other by simple bit-scaling.\n  // Calculations done by ITU, we just using their tables.\n  // Subtype 0 — HLG narrow 10-bit (Table 2):\n  static const int bt709_hlg_R[] = { 713, 538, 512, 651, 639, 227 };\n  static const int bt709_hlg_G[] = { 719, 709, 706, 286, 269, 147 };\n  static const int bt709_hlg_B[] = { 316, 718, 296, 705, 164, 702 };\n  // Subtype 1 — PQ narrow 10-bit (Table 3):\n  static const int bt709_pq_narrow_R_10[] = { 569, 485, 474, 537, 531, 318 };\n  static const int bt709_pq_narrow_G_10[] = { 572, 566, 565, 362, 351, 236 };\n  static const int bt709_pq_narrow_B_10[] = { 381, 571, 368, 564, 257, 563 };\n  // Subtype 2 — PQ full range 10-bit (Table 4):\n  static const int bt709_pq_R_fr10[] = { 589, 491, 479, 552, 545, 296 };\n  static const int bt709_pq_G_fr10[] = { 593, 586, 585, 348, 335, 201 };\n  static const int bt709_pq_B_fr10[] = { 370, 592, 355, 584, 225, 582 };\n  // Subtype 2 — PQ full range 12-bit (Table 4): independently specified,\n  // e.g. bt709_pq_G_fr10[1] 586 and 2348 cannot be calculated from each other by scaling\n  static const int bt709_pq_R_fr12[] = { 2359, 1967, 1918, 2209, 2181, 1186 };\n  static const int bt709_pq_G_fr12[] = { 2373, 2348, 2342, 1391, 1339,  806 };\n  static const int bt709_pq_B_fr12[] = { 1483, 2371, 1423, 2339,  901, 2331 };\n\n  // non-RGB, simply grey levels:\n\n  // 40% Grey:\n  //   Narrow (subtypes 0/1): 414 at 10-bit (primary). 12-bit = 414<<2 = 1656 (exact shift).\n  //   Full   (subtype 2):    409 at 10-bit, 1638 at 12-bit — independently rounded from ~0.4.\n  static const int grey40_narrow = 414;\n  static const int grey40_fr10 = 409;\n  static const int grey40_fr12 = 1638;\n\n  // PLUGE levels — derived from BT.814-4 Table 3 \"Slightly lighter/darker level\".\n  // BT.814-4 defines: Slightly lighter=80, Slightly darker=48 at 10-bit narrow.\n  // The naming of 2% and 4% levels are just approximations.\n  // Full range values were probably independently derived from narrow float.\n  //   lighter_float = (80-64)/876 ≈ 0.01826 → 10-bit (*1023): 19, 12-bit (*4096): 75\n  //   +4%_float     = (99-64)/876 ≈ 0.03995 → 10-bit: 41, 12-bit: 164\n  // Narrow: { 0%, -2%, 0%, +2%, 0%, +4%, 0% }\n  static const int pluge_narrow[] = { 64, 48, 64, 80, 64,  99, 64 };\n  // Full range 10-bit (Table 4): no -2% (no sub-black in full range per Table 4 footnote)\n  static const int pluge_fr10[] = { 0,  0,  0, 19,  0,  41,  0 };\n  // Full range 12-bit (Table 4)\n  static const int pluge_fr12[] = { 0,  0,  0, 75,  0, 164,  0 };\n\n  // Stair step values (10-bit), BT.2111-3 Tables 2/3/4:\n  // 13 steps: -7%, 0%, 10%..100%, 109%\n  // Narrow (subtypes 0/1):\n  static const int steps_narrow[] = { 4, 64, 152, 239, 327, 414, 502, 590, 677, 765, 852,  940, 1019 };\n  // Full range (subtype 2): no -7% (clamped to 0) and no 109% (clamped to 1023)\n  static const int steps_fr10[] = { 0,  0, 102, 205, 307, 409, 512, 614, 716, 818, 921, 1023, 1023 };\n  static const int steps_fr12[] = { 0,  0, 410, 819, 1229, 1638, 2048, 2457, 2867, 3276, 3686, 4095, 4095 };\n\n  // narrow range is always 10-bit reference\n  // Reference anchor points at 10/12-bits (used for stair/ramp generation):\n  const int ref_black_narrow = 64; // at 10 bits\n  const int ref_black_fr10 = 0;\n  const int ref_black_fr12 = 0;\n  const int ref_white_narrow = 940; // at 10 bits\n  const int ref_white_fr10 = 1023;\n  const int ref_white_fr12 = 4095;\n  const int ref_min_narrow = 4;    // -7% step\n  const int ref_min_fr10 = 0;      // 0% step\n  const int ref_min_fr12 = 0;      // 0% step\n  const int ref_max_narrow = 1019; // at 10 bits, +109% step\n  const int ref_max_fr10 = 1023;   // at 10 bits, +100% step (full range)\n  const int ref_max_fr12 = 4095;   // at 12 bits, +100% step (full range)\n\n  // Code value 4 = approx −7% = minimum permitted narrow range value (BT.2100).\n  // Code value 1019 = approx +109% = maximum permitted narrow range value (BT.2100).\n\n  // =========================================================================\n  // -- Native pixel_t table pre-computation ---------------------------------\n  // =========================================================================\n  // All ITU source values (int) are converted once to pixel_t here.\n  // Drawing code then reads pre-computed pixel_t values directly with no\n  // per-pixel scaling. This replaces the mixed fill_span/fill_span_native/\n  // fill_bar dispatch logic.\n  //\n  // pixel_t: the element type of all pre-computed tables.\n  //   float output → float (normalised via scale_y)\n  //   integer output → pixel_t (= uint8_t, uint16_t)\n  // All tables are indexed exactly as their ITU int counterparts.\n\n  // -- scale_y: convert one 10-bit source code to pixel_t -------------------\n  // Narrow range: limited->limited pure bit-shift (exact per BT.2111-3 §5).\n  // Full range:   full->full rational rescale via luma_c constants.\n  // Float:        normalised via luma_c.mul_factor + luma_c.dst_offset.\n  auto scale_y = [&](int code10) -> pixel_t {\n    XP_LAMBDA_CAPTURE_FIX(is_float_output);\n    XP_LAMBDA_CAPTURE_FIX(is_full_range);\n#ifdef XP_TLS\n    if (is_float_output)\n#else\n    if constexpr (is_float_output)\n#endif\n    {\n      return (pixel_t)((code10 - luma_c.src_offset_i) * luma_c.mul_factor + luma_c.dst_offset);\n    }\n    else {\n      if (!is_full_range) {\n        const int shift = bits_per_pixel - src_bits;\n        if (shift >= 0) return (pixel_t)(code10 << shift);\n        else            return (pixel_t)((code10 + (1 << (-shift - 1))) >> (-shift));\n      }\n      else {\n        const int dst_max = (1 << bits_per_pixel) - 1;\n        const int result = (int)((code10 - luma_c.src_offset_i) * luma_c.mul_factor\n          + luma_c.dst_offset + 0.5f);\n        return (pixel_t)(std::max(0, std::min(dst_max, result)));\n      }\n    }\n    };\n\n  // -- fr_native12: convert full-range value to pixel_t from 12-bit reference\n  // For full range non-10/12-bit integer depths: scale from 12-bit ITU value.\n  // For 10-bit: use code10 directly.\n  // For 12-bit: use code12 directly.\n  // For float:  use code10 via scale_y (same as narrow — scale_y handles float normalisation).\n  // This ensures ITU-specified 10 and 12-bit values are reproduced exactly,\n  // while other depths get the best approximation from the 12-bit reference.\n  auto fr_native12 = [&](int code10, int code12) -> pixel_t {\n#ifdef XP_TLS\n    if (is_float_output)\n#else\n    if constexpr (is_float_output)\n#endif\n    {\n      return scale_y(code10); // float always uses 10-bit ref via scale_y\n    }\n    else {\n      if (bits_per_pixel == 10) return (pixel_t)code10;\n      if (bits_per_pixel == 12) return (pixel_t)code12;\n      const int vmax = (1 << bits_per_pixel) - 1;\n      return (pixel_t)(int)round((double)code12 / 4095.0 * vmax);\n    }\n    };\n\n  // Helper: build a pixel_t value from a 10-bit code via scale_y.\n  // For narrow range: bit-shift. For full range: rational rescale. For float: normalise.\n  // Used for all grey/luma-only values (grey40, PLUGE, stair, black, white).\n  auto make_luma = [&](int code10) -> pixel_t { return scale_y(code10); };\n\n  // Helper: build a pixel_t value from paired 10/12-bit full-range codes.\n  // Selects ITU exact value at 10/12-bit, scales from 12-bit for other depths.\n  // Float always uses 10-bit reference via scale_y.\n  auto make_luma_fr = [&](int code10, int code12) -> pixel_t {\n    return fr_native12(code10, code12);\n    };\n\n  // -- Pre-compute black and white pixel_t values ---------------------------\n  // Used for i/j/k blocks in row 5, left pad, ramp B/D sections.\n  const pixel_t t_black = is_full_range\n    ? make_luma_fr(ref_black_fr10, ref_black_fr12) // 0 for full range\n    : make_luma(ref_black_narrow);\n  const pixel_t t_white = is_full_range\n    ? make_luma_fr(ref_white_fr10, ref_white_fr12) // 100% for full range\n    : make_luma(ref_white_narrow);\n  const pixel_t t_ramp_min = is_full_range\n    ? make_luma_fr(ref_min_fr10, ref_min_fr12) // -7% for ramp/stair B section\n    : make_luma(ref_min_narrow);\n  const pixel_t t_ramp_max = is_full_range\n    ? make_luma_fr(ref_max_fr10, ref_max_fr12) // +109% for ramp D section\n    : make_luma(ref_max_narrow);\n\n\n  // =========================================================================\n  // -- Pre-compute all native pixel_t bar tables ----------------------------\n  // =========================================================================\n  // All tables are pre-computed once here. Drawing loops read pixel_t values\n  // directly — no per-pixel scaling, no dispatch on range/depth at draw time.\n  //\n  // Naming: t_* = pre-computed pixel_t table.\n  //\n  // RGB tables: 3 planes × N bars, stored as separate arrays.\n  //   t_R100[i]/t_G100[i]/t_B100[i] = 100% bar i, target pixel_t for R/G/B plane.\n  // YUV tables: stored as YCbCr triplets via pre_yuv helper below.\n  //\n  // Table sizes:\n  //   100% and primary bars: 7 entries [0..6]\n  //   BT.709-equivalent bars: 6 entries [0..5]\n  //   PLUGE: 7 entries [0..6]\n  //   Stair steps: 13 entries [0..12]\n  //   Grey40: scalar\n  //   Black/white: scalar\n\n  // -- Pre-compute grey40 ---------------------------------------------------\n  // Narrow: 414 (10-bit primary, scale_y handles all depths via bit-shift).\n  // Full:   409 (10-bit ITU), 1638 (12-bit ITU) — independently rounded from 0.4.\n  //         409<<2=1636≠1638: confirms independent specification.\n  //         fr_native12 selects exact ITU value at 10/12-bit, scales from 12-bit otherwise.\n  const pixel_t t_grey40 = is_full_range\n    ? make_luma_fr(grey40_fr10, grey40_fr12)\n    : make_luma(grey40_narrow);\n\n  // Neutral chroma value (mid-point for YUV, unused for RGB).\n  const pixel_t t_chroma_mid = is_rgb ? pixel_t{} : (pixel_t)chroma_c.dst_offset;\n\n  // -- Helper: write a solid luma+neutral-chroma span (grey) ----------------\n  // All grey fills use pre-computed pixel_t values — no per-pixel scaling.\n  auto fill_grey_px = [&](int x0, int x1, pixel_t luma) {\n    XP_LAMBDA_CAPTURE_FIX(t_chroma_mid);\n    for (int x = x0; x < x1 && x < w; ++x) {\n      if constexpr (is_rgb) { pYG[x] = luma; pUB[x] = luma; pVR[x] = luma; }\n      else { pYG[x] = luma; pUB[x] = t_chroma_mid; pVR[x] = t_chroma_mid; }\n    }\n    };\n\n  // -- Pre-compute PLUGE pixel_t values -------------------------------------\n  // pluge_px[0..6] correspond to pluge_narrow[] / pluge_fr10[] / pluge_fr12[].\n  // Narrow: scale_y(pluge_narrow[s]) — bit-shift from 10-bit.\n  // Full:   fr_native12(pluge_fr10[s], pluge_fr12[s]) — ITU-exact at 10/12-bit.\n  pixel_t t_pluge[7];\n  for (int s = 0; s < 7; ++s) {\n    t_pluge[s] = is_full_range\n      ? make_luma_fr(pluge_fr10[s], pluge_fr12[s])\n      : make_luma(pluge_narrow[s]);\n  }\n\n  // -- Pre-compute stair step pixel_t values --------------------------------\n  // steps_narrow/steps_fr10/steps_fr12 are 10-bit source values.\n  // Narrow: scale_y(steps_narrow[s]) — bit-shift from 10-bit.\n  // Full:   fr_native12(steps_fr10[s], steps_fr12[s]) — ITU-exact at 10/12-bit.\n  pixel_t t_steps[13];\n  for (int s = 0; s < 13; ++s)\n    t_steps[s] = is_full_range\n      ? make_luma_fr(steps_fr10[s], steps_fr12[s])\n    : make_luma(steps_narrow[s]);\n\n  // For YUV output, each bar is stored as a pre-computed YCbCr triplet\n  // in three parallel arrays.\n  struct YUVPixel { pixel_t y, cb, cr; };\n\n  // make_yuv: convert native pixel_t R/G/B → YCbCr pixel_t.\n    // Input is already at target bit depth and range — no further scaling needed.\n    // Normalises to [0..1] float using the native range (full or limited),\n    // applies BT.2020 NCL matrix, then encodes to target depth.\n    // luma_c_to_float converts native pixel_t luma → [0..1] float.\n  auto make_yuv = [&](pixel_t r_px, pixel_t g_px, pixel_t b_px) -> YUVPixel {\n    // Convert native pixel_t to normalised float [0..1].\n    // luma_c_to_float: native target depth → float [0..1] over signal range.\n    // (src=bits_per_pixel full/limited, dst=float full range)\n    const double R = ((double)r_px - luma_c_to_float.src_offset_i) * luma_c_to_float.mul_factor;\n    const double G = ((double)g_px - luma_c_to_float.src_offset_i) * luma_c_to_float.mul_factor;\n    const double B = ((double)b_px - luma_c_to_float.src_offset_i) * luma_c_to_float.mul_factor;\n    double dY, dU, dV;\n    GetYUVBT2020fromRGB(R, G, B, dY, dU, dV);\n    pixel_t sy, scb, scr;\n#ifdef XP_TLS\n    if (is_float_output) {\n#else\n    if constexpr (is_float_output) {\n#endif\n      sy = (pixel_t)(dY * luma_c_from_float.mul_factor + luma_c_from_float.dst_offset);\n      scb = (pixel_t)(dU * chroma_c_from_float.mul_factor);\n      scr = (pixel_t)(dV * chroma_c_from_float.mul_factor);\n    }\n    else {\n      const int dst_max = (1 << bits_per_pixel) - 1;\n      sy = (pixel_t)std::max(0, std::min(dst_max,\n        (int)(dY * luma_c_from_float.mul_factor + luma_c_from_float.dst_offset + 0.5)));\n      scb = (pixel_t)std::max(0, std::min(dst_max,\n        (int)(dU * chroma_c_from_float.mul_factor + chroma_c_from_float.dst_offset + 0.5)));\n      scr = (pixel_t)std::max(0, std::min(dst_max,\n        (int)(dV * chroma_c_from_float.mul_factor + chroma_c_from_float.dst_offset + 0.5)));\n    }\n    return { sy, scb, scr };\n    };\n\n  // BarEntry: always store r/g/b at native pixel_t precision.\n  // For RGB output: r/g/b are written directly to planes.\n  // For YUV output: y/cb/cr are derived from r/g/b via make_yuv.\n  // Having r/g/b always present unifies make_bar and make_bar_fr —\n  // no if constexpr(is_rgb) split needed.\n  struct BarEntry {\n    pixel_t r, g, b;   // native pixel_t — always computed\n    pixel_t y, cb, cr; // YUV planes — computed from r/g/b via make_yuv\n  };\n\n  // make_bar_from_px: build BarEntry from native pixel_t R/G/B values.\n  // Always computes r/g/b. Derives y/cb/cr via make_yuv if !is_rgb.\n  auto make_bar_from_px = [&](pixel_t r_px, pixel_t g_px, pixel_t b_px) -> BarEntry {\n    XP_LAMBDA_CAPTURE_FIX(make_yuv);\n    BarEntry e{};\n    e.r = r_px; e.g = g_px; e.b = b_px;\n    if constexpr (!is_rgb) {\n      auto yuv = make_yuv(r_px, g_px, b_px);\n      e.y = yuv.y; e.cb = yuv.cb; e.cr = yuv.cr;\n    }\n    return e;\n    };\n\n  // make_bar: build BarEntry from 10-bit source codes (narrow range or full range 10-bit).\n  // Converts via scale_y to native pixel_t, then derives YUV from native values.\n  auto make_bar = [&](int r10, int g10, int b10) -> BarEntry {\n    return make_bar_from_px(scale_y(r10), scale_y(g10), scale_y(b10));\n    };\n\n  // make_bar_fr: build BarEntry for full range using paired 10/12-bit ITU values.\n  // RGB path: fr_native12 gives ITU-exact native pixel_t at 10/12-bit, scaled otherwise.\n  // YUV path: make_yuv receives the same native pixel_t values — more accurate than\n  //   passing code10 directly since fr_native12 may differ from code10 at 12/other depths.\n  //   Previously YUV used code10 only; now it uses the fr_native12-derived pixel_t,\n  //   giving correct matrix input at all bit depths.\n  auto make_bar_fr = [&](int r10, int g10, int b10,\n    int r12, int g12, int b12) -> BarEntry {\n      return make_bar_from_px(\n        fr_native12(r10, r12),\n        fr_native12(g10, g12),\n        fr_native12(b10, b12));\n    };\n\n  // -- 100% bars (7 entries) ------------------------------------------------\n  BarEntry t_bars100[7];\n  for (int i = 0; i < 7; ++i) {\n    if (is_full_range)\n      t_bars100[i] = make_bar_fr(bars100_R_fr10[i], bars100_G_fr10[i], bars100_B_fr10[i],\n        bars100_R_fr12[i], bars100_G_fr12[i], bars100_B_fr12[i]);\n    else\n      t_bars100[i] = make_bar(bars100_R_narrow_10[i], bars100_G_narrow_10[i], bars100_B_narrow_10[i]);\n  }\n\n  // -- Primary bars (7 entries): 75% HLG or 58% PQ -------------------------\n  BarEntry t_bpri[7];\n  for (int i = 0; i < 7; ++i) {\n    if (subtype == 0)       // HLG narrow\n      t_bpri[i] = make_bar(bars75hlg_R_10[i], bars75hlg_G_10[i], bars75hlg_B_10[i]);\n    else if (subtype == 1)  // PQ narrow\n      t_bpri[i] = make_bar(bars58pq_R_10[i], bars58pq_G_10[i], bars58pq_B_10[i]);\n    else                    // PQ full range\n      t_bpri[i] = make_bar_fr(bars58pq_R_fr10[i], bars58pq_G_fr10[i], bars58pq_B_fr10[i],\n        bars58pq_R_fr12[i], bars58pq_G_fr12[i], bars58pq_B_fr12[i]);\n  }\n\n  // -- BT.709-equivalent bars (6 entries) -----------------------------------\n  BarEntry t_b709[6];\n  for (int i = 0; i < 6; ++i) {\n    if (subtype == 0)       // HLG narrow\n      t_b709[i] = make_bar(bt709_hlg_R[i], bt709_hlg_G[i], bt709_hlg_B[i]);\n    else if (subtype == 1)  // PQ narrow\n      t_b709[i] = make_bar(bt709_pq_narrow_R_10[i], bt709_pq_narrow_G_10[i], bt709_pq_narrow_B_10[i]);\n    else                    // PQ full range\n      t_b709[i] = make_bar_fr(bt709_pq_R_fr10[i], bt709_pq_G_fr10[i], bt709_pq_B_fr10[i],\n        bt709_pq_R_fr12[i], bt709_pq_G_fr12[i], bt709_pq_B_fr12[i]);\n  }\n\n  // =========================================================================\n  // -- Drawing helpers (all operate on pre-computed pixel_t values) ---------\n  // =========================================================================\n\n  // fill_grey_px: fill span with a pre-computed luma + neutral chroma.\n  // (defined above)\n\n  // fill_bar_px: fill span with a pre-computed BarEntry.\n  // Direct pixel_t write — no scaling at draw time.\n  auto fill_bar_px = [&](int x0, int x1, const BarEntry& e) {\n    for (int x = x0; x < x1 && x < w; ++x) {\n      if constexpr (is_rgb) {\n        pYG[x] = e.g; pUB[x] = e.b; pVR[x] = e.r; // Avisynth GBR order\n      }\n      else {\n        pYG[x] = e.y; pUB[x] = e.cb; pVR[x] = e.cr;\n      }\n    }\n    };\n\n  // =========================================================================\n  // -- Draw rows ------------------------------------------------------------\n  // =========================================================================\n  int y = 0;\n\n  // -- Row 1: b/12 — 100% colour bars ---------------------------------------\n  for (; y < y1; ++y) {\n    fill_grey_px(0, c_bar, t_grey40);\n    fill_bar_px(bar_White, barend_White, t_bars100[0]); // White\n    fill_bar_px(bar_Yellow, barend_Yellow, t_bars100[1]); // Yellow\n    fill_bar_px(bar_Cyan, barend_Cyan, t_bars100[2]); // Cyan\n    fill_bar_px(bar_Green, barend_Green, t_bars100[3]); // Green\n    fill_bar_px(bar_Magenta, barend_Magenta, t_bars100[4]); // Magenta\n    fill_bar_px(bar_Red, barend_Red, t_bars100[5]); // Red\n    fill_bar_px(bar_Blue, barend_Blue, t_bars100[6]); // Blue\n    fill_grey_px(bar_RightC, w, t_grey40);\n    pYG += pitchY; pUB += pitchUV; pVR += pitchUV;\n  }\n\n  // -- Row 2: b/2 — 75% HLG or 58% PQ primary colour bars ------------------\n  for (; y < y2; ++y) {\n    fill_grey_px(0, c_bar, t_grey40);\n    fill_bar_px(bar_White, barend_White, t_bpri[0]);\n    fill_bar_px(bar_Yellow, barend_Yellow, t_bpri[1]);\n    fill_bar_px(bar_Cyan, barend_Cyan, t_bpri[2]);\n    fill_bar_px(bar_Green, barend_Green, t_bpri[3]);\n    fill_bar_px(bar_Magenta, barend_Magenta, t_bpri[4]);\n    fill_bar_px(bar_Red, barend_Red, t_bpri[5]);\n    fill_bar_px(bar_Blue, barend_Blue, t_bpri[6]);\n    fill_grey_px(bar_RightC, w, t_grey40);\n    pYG += pitchY; pUB += pitchUV; pVR += pitchUV;\n  }\n\n  // -- Row 3: b/12 — stair --------------------------------------------------\n  // Layout: primary-white(c) | -7%or0%(d) | 12 steps | primary-white(c)\n  // Steps: 0%,10%..100%,109% (narrow) or 0%,10%..100%,100% (full range)\n  // Under each d-width bar: 2 steps of d/2. Under green (e_bar): 2 steps of e/2.\n  // All steps pre-computed in t_steps[0..12].\n  for (; y < y3; ++y) {\n    fill_bar_px(0, bar_White, t_bpri[0]); // primary white left pad\n    fill_grey_px(bar_White, bar_Yellow, t_steps[0]); // pre-step: -7% or 0%\n    // 6 bars × 2 half-steps each = steps[1..12]\n    const int bar_starts[6] = { bar_Yellow, bar_Cyan, bar_Green, bar_Magenta, bar_Red, bar_Blue };\n    const int bar_widths[6] = { d_bar, d_bar, e_bar, d_bar, d_bar, d_bar };\n    for (int b = 0; b < 6; ++b) {\n      const int half = bar_widths[b] / 2;\n      fill_grey_px(bar_starts[b], bar_starts[b] + half, t_steps[1 + b * 2]);\n      fill_grey_px(bar_starts[b] + half, bar_starts[b] + bar_widths[b], t_steps[2 + b * 2]);\n    }\n    fill_bar_px(bar_RightC, w, t_bpri[0]); // primary white right pad\n    pYG += pitchY; pUB += pitchUV; pVR += pitchUV;\n  }\n\n  // -- Row 4: b/12 — ramp ---------------------------------------------------\n  // Ramp is NOT pre-computed (gradient changes per pixel).\n  // Uses the existing real-valued step computation for correctness at all depths.\n  // Section layout:\n  //   left pad (black) | B (constant min) | C (linear ramp) | D (constant max)\n  // Narrow: ramp -7% → +109%    (B=ref_min, D=ref_max)\n  // Full:   ramp  0% → 100%     (B=black,   D=white)\n  {\n    const int A_px = (1680 * w + 960) / 1920;\n    const int left_pad_end = w - A_px;\n    int B_px, C_px, D_px;\n    if (!is_full_range) {\n      B_px = (559 * w + 960) / 1920;\n      D_px = (107 * w + 960) / 1920;\n    }\n    else {\n      B_px = (618 * w + 960) / 1920;\n      D_px = (40 * w + 960) / 1920;\n    }\n    C_px = A_px - B_px - D_px;\n    const int B_start = left_pad_end;\n    const int C_start = B_start + B_px;\n    const int D_start = C_start + C_px;\n\n    if constexpr (is_float_output) {\n      // Float: compute B/D levels in float via scale_y, then step linearly.\n      const int B_code = !is_full_range ? ref_min_narrow : ref_black_fr10;\n      const int D_code = !is_full_range ? ref_max_narrow : ref_white_fr10;\n      const double B_lf = (double)((B_code - luma_c.src_offset_i) * luma_c.mul_factor + luma_c.dst_offset);\n      const double D_lf = (double)((D_code - luma_c.src_offset_i) * luma_c.mul_factor + luma_c.dst_offset);\n      const double step_f = C_px > 0 ? (D_lf - B_lf) / C_px : luma_c.mul_factor;\n      const pixel_t chroma_val = (pixel_t)chroma_c.dst_offset;\n      for (; y < y4; ++y) {\n        fill_grey_px(0, B_start, t_black);\n        fill_grey_px(B_start, C_start, is_full_range ? t_black : t_ramp_min);\n        for (int x = C_start; x < D_start; ++x) {\n          const pixel_t val = (pixel_t)(B_lf + step_f * (x - C_start + 1));\n          if constexpr (is_rgb) { pYG[x] = val; pUB[x] = val; pVR[x] = val; }\n          else { pYG[x] = val; pUB[x] = chroma_val; pVR[x] = chroma_val; }\n        }\n        fill_grey_px(D_start, w, is_full_range ? t_white : t_ramp_max);\n        pYG += pitchY; pUB += pitchUV; pVR += pitchUV;\n      }\n    }\n    else {\n      // Integer: compute native B/D levels, then step with real-valued step.\n      // similar to make_luma_fr but with separate narrow/full logic since we need the 10-bit code for the step calculation below.\n      const int B_level = t_black;\n      const int D_level = t_white;\n      const double real_step = C_px > 0 ? (double)(D_level - B_level) / C_px : 1.0;\n      // Verify against ITU table notes (see Table 5/6 comments above):\n      // 10-bit narrow 2K: B=4,  D=1019, step≈1.001 → first=5,  last=1019\n      // 12-bit narrow 2K: B=16, D=4076, step=4.000 → first=20, last=4076\n      // 10-bit full  2K:  B=0,  D=1023, step≈1.001 → first=1,  last=1023\n      // 12-bit full  2K:  B=0,  D=4092, step=4.000 → first=4,  last=4092\n      for (; y < y4; ++y) {\n        fill_grey_px(0, B_start, t_black);\n        fill_grey_px(B_start, C_start, is_full_range ? t_black : t_ramp_min);\n        for (int x = C_start; x < D_start; ++x) {\n          const pixel_t val = (pixel_t)(int)(B_level + real_step * (x - C_start + 1) + 0.5);\n          if constexpr (is_rgb) { pYG[x] = val; pUB[x] = val; pVR[x] = val; }\n          else { pYG[x] = val; pUB[x] = t_chroma_mid; pVR[x] = t_chroma_mid; }\n        }\n        fill_grey_px(D_start, w, is_full_range ? t_white : t_ramp_max);\n        pYG += pitchY; pUB += pitchUV; pVR += pitchUV;\n      }\n    }\n  }\n\n  // -- Row 5: b/4 — bottom section ------------------------------------------\n  // Left:   BT.709 Yellow, Cyan, Green   (each c/3 wide)\n  // PLUGE:  f(0%) | g(-2%) | h(0%) | g(+2%) | h(0%) | g(+4%) | i(0%) | j(white) | k(0%)\n  // Right:  BT.709 Magenta, Red, Blue    (each c/3 wide)\n  // Full range PQ: no -2% sub-black level (clamped to 0% per Table 4 footnote).\n  // All PLUGE values pre-computed in t_pluge[0..6].\n  {\n    const int pluge_x0 = 3 * bt709_bar_w;\n    const int pluge_f_end = pluge_x0 + f_pluge;\n    const int seg[5] = { g_pluge, h_pluge, g_pluge, h_pluge, g_pluge };\n    // pluge indices: 0=f(0%), 1=-2%, 2=0%, 3=+2%, 4=0%, 5=+4%, 6=0%\n    int pluge_x = pluge_f_end;\n    int seg_ends[5];\n    for (int s = 0; s < 5; ++s) { pluge_x += seg[s]; seg_ends[s] = pluge_x; }\n    const int i_start = pluge_x;\n    const int j_start = i_start + i_span;\n    const int k_start = j_start + j_span;\n    const int k_end = k_start + k_span;\n\n    for (; y < h; ++y) {\n      fill_bar_px(0, bt709_bar_w, t_b709[0]); // BT.709 Yellow\n      fill_bar_px(bt709_bar_w, 2 * bt709_bar_w, t_b709[1]); // BT.709 Cyan\n      fill_bar_px(2 * bt709_bar_w, 3 * bt709_bar_w, t_b709[2]); // BT.709 Green\n      // f block: 0% black\n      fill_grey_px(pluge_x0, pluge_f_end, t_pluge[0]);\n      // 5 PLUGE segments: -2%(g), 0%(h), +2%(g), 0%(h), +4%(g)\n      {\n        int px = pluge_f_end;\n        for (int s = 0; s < 5; ++s) { fill_grey_px(px, seg_ends[s], t_pluge[1 + s]); px = seg_ends[s]; }\n      }\n      // i: 0% black  j: 75%/58% white (primary white = t_bpri[0])  k: 0% black\n      fill_grey_px(i_start, j_start, t_black);\n      fill_bar_px(j_start, k_start, t_bpri[0]); // 75%/58% white patch\n      fill_grey_px(k_start, k_end, t_black);\n      fill_bar_px(k_end, k_end + bt709_bar_w, t_b709[3]); // BT.709 Magenta\n      fill_bar_px(k_end + bt709_bar_w, k_end + 2 * bt709_bar_w, t_b709[4]); // BT.709 Red\n      fill_bar_px(k_end + 2 * bt709_bar_w, w, t_b709[5]); // BT.709 Blue\n      pYG += pitchY; pUB += pitchUV; pVR += pitchUV;\n    }\n  }\n} // draw_colorbarsUHD_444_rgb\n\n\nclass ColorBars : public IClip {\n  VideoInfo vi;\n  PVideoFrame frame;\n  SFLOAT *audio;\n  unsigned nsamples;\n  bool staticframes; // false: re-draw each frame. Defaults to true (one pre-computed static frame is served).\n  int subtype; // for UHD\n\n  enum { Hz = 440 } ;\n\npublic:\n\n  ~ColorBars() {\n    delete audio;\n  }\n\n  ColorBars(int w, int h, const char* pixel_type, bool _staticframes, int type, int _subtype, IScriptEnvironment* env) : subtype(_subtype) {\n    memset(&vi, 0, sizeof(VideoInfo));\n    staticframes = _staticframes;\n    vi.width = w;\n    vi.height = h;\n    vi.fps_numerator = 30000;\n    vi.fps_denominator = 1001;\n    vi.num_frames = 107892;   // 1 hour\n    int i_pixel_type = GetPixelTypeFromName(pixel_type);\n    vi.pixel_type = i_pixel_type;\n    int bits_per_pixel = vi.BitsPerComponent();\n\n    const bool IsColorbars = (type == 0);\n    const bool IsColorbarsHD = (type == 1);\n    const bool IsColorbarsUHD = (type == 2);\n\n    if (IsColorbarsUHD) {\n      if (!vi.Is444() && !vi.IsPlanarRGB())\n        env->ThrowError(\"ColorBarsUHD: pixel_type must be a planar RGB or 4:4:4 video format\");\n    }\n    else if (IsColorbarsHD) { // ColorbarsHD\n      if (!vi.Is444())\n        env->ThrowError(\"ColorBarsHD: pixel_type must be \\\"YV24\\\" or other 4:4:4 video format\");\n    }\n    else if (vi.IsRGB32() || vi.IsRGB64() || vi.IsRGB24() || vi.IsRGB48()) {\n      // no special check\n    }\n    else if (vi.IsRGB() && vi.IsPlanar()) { // planar RGB\n      // no special check\n    }\n    else if (vi.IsYUY2()) { // YUY2\n      if (w & 1)\n        env->ThrowError(\"ColorBars: YUY2 width must be even!\");\n    }\n    else if (vi.Is420()) { // 4:2:0\n      if ((w & 1) || (h & 1))\n        env->ThrowError(\"ColorBars: for 4:2:0 both height and width must be even!\");\n    }\n    else if (vi.Is422()) { // 4:2:2\n      if (w & 1)\n        env->ThrowError(\"ColorBars: for 4:2:2 width must be even!\");\n    }\n    else if (vi.IsYV411()) { // 4:1:1\n      if (w & 3)\n        env->ThrowError(\"ColorBars: for 4:1:1 width must be divisible by 4!\");\n    }\n    else if (vi.Is444()) { // 4:4:4\n      // no special check\n    }\n    else {\n      env->ThrowError(\"ColorBars: this pixel_type not supported\");\n    }\n    vi.sample_type = SAMPLE_FLOAT;\n    vi.nchannels = 2;\n    vi.audio_samples_per_second = 48000;\n    vi.num_audio_samples = vi.AudioSamplesFromFrames(vi.num_frames);\n\n    frame = env->NewVideoFrame(vi);\n\n    uint32_t* p = (uint32_t*)frame->GetWritePtr();\n\n    // set basic frame properties\n    auto props = env->getFramePropsRW(frame);\n    int theMatrix;\n    int theColorRange;\n    int theTransfer;\n    int thePrimaries;\n    if (IsColorbarsUHD) {\n      // subtypes 0,1,2: HLG narrow, PQ narrow, PQ full range (BT.2111-3)\n\n      // ColorBarsUHD RGB or YUV444\n      // For YUV BT.2100 uses Y'CbCr NCL (identical Kr/Kb to BT.2020 NCL).\n      theMatrix = vi.IsRGB() ? Matrix_e::AVS_MATRIX_RGB : Matrix_e::AVS_MATRIX_BT2020_NCL; // = 0/9\n      // HLG narrow (0) and PQ narrow (1) use limited swing (64–940 at 10-bit).\n      // PQ full range (subtype 2) uses full swing (0–1023 at 10-bit).\n      // Note: AVS_COLORRANGE_LIMITED = 1, AVS_COLORRANGE_FULL = 0 in the Compat enum\n      // (inverted from the ITU-T H.265 / AVS_RANGE_* convention).\n      // Float output is always full range, tools usually do not support Avisynth's style \"limited float\"\n      theColorRange = (subtype == 2 || bits_per_pixel == 32)\n        ? ColorRange_Compat_e::AVS_COLORRANGE_FULL\n        : ColorRange_Compat_e::AVS_COLORRANGE_LIMITED;\n      // Transfer: HLG (subtype 0) = ARIB B67 (= 18), PQ (subtypes 1/2) = ST2084 (= 16).\n      theTransfer = (subtype == 0) ? Transfer_e::AVS_TRANSFER_ARIB_B67 : Transfer_e::AVS_TRANSFER_ST2084;\n      thePrimaries = Primaries_e::AVS_PRIMARIES_BT2020;\n    }\n    else if (IsColorbarsHD) {\n      // ColorBarsHD 444 only\n      theMatrix = Matrix_e::AVS_MATRIX_BT709;\n      theColorRange = ColorRange_Compat_e::AVS_COLORRANGE_LIMITED;\n      theTransfer = Transfer_e::AVS_TRANSFER_BT709;    // = 1\n      thePrimaries = Primaries_e::AVS_PRIMARIES_BT709; // = 1\n    }\n    else {\n      // ColorBars RGB or YUV\n      // RGB output has no YCbCr matrix, but still carries BT.601 (ST170-M) primaries and transfer.\n      theMatrix = vi.IsRGB() ? Matrix_e::AVS_MATRIX_RGB : Matrix_e::AVS_MATRIX_ST170_M;\n      // Studio RGB: limited!\n      // Unlike UHD, float is Avisynth's \"limited float\"\n      theColorRange = vi.IsRGB() ? ColorRange_Compat_e::AVS_COLORRANGE_LIMITED : ColorRange_Compat_e::AVS_COLORRANGE_LIMITED;\n      theTransfer = Transfer_e::AVS_TRANSFER_BT601;      // = 6, same gamma curve as BT.709\n      thePrimaries = Primaries_e::AVS_PRIMARIES_ST170_M; // = 6, BT.601-525 (NTSC)\n    }\n    update_Matrix_and_ColorRange(props, theMatrix, theColorRange, env);\n    update_Transfer_and_Primaries(props, theTransfer, thePrimaries, env);\n\n    if (IsColorbarsUHD) { // ColorbarsUHD\n      // UHD colorbars BT.2111-3 (05/2025)\n      // https://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.2111-3-202505-I!!PDF-E.pdf\n      // RECOMMENDATION ITU-R BT.2111-3\n      // Specification of color bar test pattern for high dynamic range television systems (2017-2019-2020-2025)\n      // subtype=0: hybrid log-gamma (HLG) system with narrow range coding\n      // subtype=1: perceptual quantization (PQ) system with narrow range coding\n      // subtype=2: PQ system with full range coding\n      const bool isRGB = vi.IsRGB();\n      BYTE* p1 = (BYTE*)frame->GetWritePtr(isRGB ? PLANAR_G : PLANAR_Y);\n      BYTE* p2 = (BYTE*)frame->GetWritePtr(isRGB ? PLANAR_B : PLANAR_U);\n      BYTE* p3 = (BYTE*)frame->GetWritePtr(isRGB ? PLANAR_R : PLANAR_V);\n      const int pitch1 = frame->GetPitch(isRGB ? PLANAR_G : PLANAR_Y);\n      const int pitch23 = frame->GetPitch(isRGB ? PLANAR_G : PLANAR_U); // all pitches equal in planar RGB\n\n      if (bits_per_pixel == 8) {\n        if (isRGB)\n          draw_colorbarsUHD_444_rgb<uint8_t, true>(p1, p2, p3, pitch1, pitch23, w, h, 8, subtype);\n        else\n          draw_colorbarsUHD_444_rgb<uint8_t, false>(p1, p2, p3, pitch1, pitch23, w, h, 8, subtype);\n      }\n      else if (bits_per_pixel <= 16) {\n        if (isRGB)\n          draw_colorbarsUHD_444_rgb<uint16_t, true>(p1, p2, p3, pitch1, pitch23, w, h, bits_per_pixel, subtype);\n        else\n          draw_colorbarsUHD_444_rgb<uint16_t, false>(p1, p2, p3, pitch1, pitch23, w, h, bits_per_pixel, subtype);\n      }\n      else if (bits_per_pixel == 32) {\n        if (isRGB)\n          draw_colorbarsUHD_444_rgb<float, true>(p1, p2, p3, pitch1, pitch23, w, h, 32, subtype);\n        else\n          draw_colorbarsUHD_444_rgb<float, false>(p1, p2, p3, pitch1, pitch23, w, h, 32, subtype);\n      }\n    }\n    else if (IsColorbarsHD) { // ColorbarsHD\n      // HD colorbars arib_std_b28\n      // Rec709 yuv values\n      BYTE* pY = (BYTE*)frame->GetWritePtr(PLANAR_Y);\n      BYTE* pU = (BYTE*)frame->GetWritePtr(PLANAR_U);\n      BYTE* pV = (BYTE*)frame->GetWritePtr(PLANAR_V);\n      const int pitchY = frame->GetPitch(PLANAR_Y);\n      const int pitchUV = frame->GetPitch(PLANAR_U);\n\n      if (bits_per_pixel == 8)\n        draw_colorbarsHD_444<uint8_t>(pY, pU, pV, pitchY, pitchUV, w, h, 8);\n      else if (bits_per_pixel <= 16)\n        draw_colorbarsHD_444<uint16_t>(pY, pU, pV, pitchY, pitchUV, w, h, bits_per_pixel);\n      else if (bits_per_pixel == 32)\n        draw_colorbarsHD_444<float>(pY, pU, pV, pitchY, pitchUV, w, h, 32);\n    }\n    else if (IsColorbars) {\n      // Rec. ITU-R BT.801-1\n      // \"ColorBars\" pattern is defined in Rec. ITU-R BT.801-1, with studio RGB values that are then converted to YUV for YUV formats.\n      // Optional YUV output calculation uses 170_ST (601) independent from the actual frame dimensions.\n      if (vi.IsRGB() && vi.IsPlanar()) {\n        BYTE* pG = (BYTE*)frame->GetWritePtr(PLANAR_G);\n        BYTE* pB = (BYTE*)frame->GetWritePtr(PLANAR_B);\n        BYTE* pR = (BYTE*)frame->GetWritePtr(PLANAR_R);\n        const int pitch = frame->GetPitch(PLANAR_G);\n\n        if (bits_per_pixel == 8)\n          draw_colorbars_rgbp<uint8_t>(pR, pG, pB, pitch, w, h, 8);\n        else if (bits_per_pixel <= 16)\n          draw_colorbars_rgbp<uint16_t>(pR, pG, pB, pitch, w, h, bits_per_pixel);\n        else if (bits_per_pixel == 32)\n          draw_colorbars_rgbp<float>(pR, pG, pB, pitch, w, h, 32);\n      }\n      else if (vi.IsRGB32() || vi.IsRGB64()) {\n        const int pitch = frame->GetPitch() / 4;\n        switch (bits_per_pixel) {\n        case 8: draw_colorbars_rgb3264<uint8_t>((uint8_t*)p, pitch, w, h); break;\n        case 16: draw_colorbars_rgb3264<uint16_t>((uint8_t*)p, pitch, w, h); break;\n        }\n      }\n      else if (vi.IsRGB24() || vi.IsRGB48()) {\n        const int pitch = frame->GetPitch();\n        switch (bits_per_pixel) {\n        case 8: draw_colorbars_rgb2448<uint8_t>((uint8_t*)p, pitch, w, h); break;\n        case 16: draw_colorbars_rgb2448<uint16_t>((uint8_t*)p, pitch, w, h); break;\n        }\n      }\n      else if (vi.IsYUY2()) {\n        // YUY2 is a packed 4:2:2 format: Y0 U0 Y1 V0 (alternating luma/chroma samples)\n        // We treat it as planar internally, then pack the results\n        const int pitch = frame->GetPitch();\n        uint8_t* dst = frame->GetWritePtr();\n\n        // Allocate temporary planar buffers for 8-bit YUV\n        std::vector<uint8_t> tempY(w * h);\n        std::vector<uint8_t> tempU((w >> 1) * h);\n        std::vector<uint8_t> tempV((w >> 1) * h);\n\n        // Use the unified YUV drawing function to generate planar data\n        draw_colorbars_yuv<uint8_t, false, true, false>(\n          tempY.data(), tempU.data(), tempV.data(),\n          w, w >> 1, w, h, 8\n        );\n\n        // Pack planar YUV 4:2:2 into YUY2 format (Y0 U0 Y1 V0)\n        for (int y = 0; y < h; ++y) {\n          const uint8_t* srcY = tempY.data() + y * w;\n          const uint8_t* srcU = tempU.data() + y * (w >> 1);\n          const uint8_t* srcV = tempV.data() + y * (w >> 1);\n          uint8_t* dstRow = dst + y * pitch;\n\n          for (int x = 0; x < w >> 1; ++x) {\n            dstRow[x * 4 + 0] = srcY[x * 2 + 0];  // Y0\n            dstRow[x * 4 + 1] = srcU[x];          // U0\n            dstRow[x * 4 + 2] = srcY[x * 2 + 1];  // Y1\n            dstRow[x * 4 + 3] = srcV[x];          // V0\n          }\n        }\n      }\n      if (vi.Is444()) {\n        BYTE* pY = (BYTE*)frame->GetWritePtr(PLANAR_Y);\n        BYTE* pU = (BYTE*)frame->GetWritePtr(PLANAR_U);\n        BYTE* pV = (BYTE*)frame->GetWritePtr(PLANAR_V);\n        const int pitchY = frame->GetPitch(PLANAR_Y);\n        const int pitchUV = frame->GetPitch(PLANAR_U);\n        if (bits_per_pixel == 8)\n          draw_colorbars_yuv<uint8_t, false, false, false>(pY, pU, pV, pitchY, pitchUV, w, h, 8);\n        else if (bits_per_pixel <= 16)\n          draw_colorbars_yuv<uint16_t, false, false, false>(pY, pU, pV, pitchY, pitchUV, w, h, bits_per_pixel);\n        else\n          draw_colorbars_yuv<float, false, false, false>(pY, pU, pV, pitchY, pitchUV, w, h, 32);\n      }\n      else if (vi.Is420()) {\n        BYTE* pY = (BYTE*)frame->GetWritePtr(PLANAR_Y);\n        BYTE* pU = (BYTE*)frame->GetWritePtr(PLANAR_U);\n        BYTE* pV = (BYTE*)frame->GetWritePtr(PLANAR_V);\n        const int pitchY = frame->GetPitch(PLANAR_Y);\n        const int pitchUV = frame->GetPitch(PLANAR_U);\n        if (bits_per_pixel == 8)\n          draw_colorbars_yuv<uint8_t, true, false, false>(pY, pU, pV, pitchY, pitchUV, w, h, 8);\n        else if (bits_per_pixel <= 16)\n          draw_colorbars_yuv<uint16_t, true, false, false>(pY, pU, pV, pitchY, pitchUV, w, h, bits_per_pixel);\n        else\n          draw_colorbars_yuv<float, true, false, false>(pY, pU, pV, pitchY, pitchUV, w, h, 32);\n      }\n      else if (vi.Is422()) {\n        BYTE* pY = (BYTE*)frame->GetWritePtr(PLANAR_Y);\n        BYTE* pU = (BYTE*)frame->GetWritePtr(PLANAR_U);\n        BYTE* pV = (BYTE*)frame->GetWritePtr(PLANAR_V);\n        const int pitchY = frame->GetPitch(PLANAR_Y);\n        const int pitchUV = frame->GetPitch(PLANAR_U);\n        if (bits_per_pixel == 8)\n          draw_colorbars_yuv<uint8_t, false, true, false>(pY, pU, pV, pitchY, pitchUV, w, h, 8);\n        else if (bits_per_pixel <= 16)\n          draw_colorbars_yuv<uint16_t, false, true, false>(pY, pU, pV, pitchY, pitchUV, w, h, bits_per_pixel);\n        else\n          draw_colorbars_yuv<float, false, true, false>(pY, pU, pV, pitchY, pitchUV, w, h, 32);\n      }\n      else if (vi.IsYV411()) {\n        BYTE* pY = (BYTE*)frame->GetWritePtr(PLANAR_Y);\n        BYTE* pU = (BYTE*)frame->GetWritePtr(PLANAR_U);\n        BYTE* pV = (BYTE*)frame->GetWritePtr(PLANAR_V);\n        const int pitchY = frame->GetPitch(PLANAR_Y);\n        const int pitchUV = frame->GetPitch(PLANAR_U);\n        // YV411 is 8-bit only\n        draw_colorbars_yuv<uint8_t, false, false, true>(pY, pU, pV, pitchY, pitchUV, w, h, 8);\n      }\n    } // \"ColorBars\" pattern generation\n    else {\n      // future other ColorBars types can be added here\n    }\n\n    // Alpha cnannel - if any - is common. RGB32/64 has already filled alpha.\n    if (vi.IsYUVA() || vi.IsPlanarRGBA()) {\n      // initialize planar alpha planes with zero (no transparency), like RGB32 does\n      BYTE* dstp = frame->GetWritePtr(PLANAR_A);\n      int rowsize = frame->GetRowSize(PLANAR_A);\n      int pitch = frame->GetPitch(PLANAR_A);\n      int height = frame->GetHeight(PLANAR_A);\n      switch (bits_per_pixel) {\n      case 8: fill_plane<uint8_t>(dstp, height, rowsize, pitch, 0); break;\n      case 10: case 12: case 14: case 16: fill_plane<uint16_t>(dstp, height, rowsize, pitch, 0); break;\n      case 32: fill_plane<float>(dstp, height, rowsize, pitch, 0.0f); break;\n      }\n    }\n\n    // Generate Audio buffer\n    {\n      unsigned x = vi.audio_samples_per_second, y = Hz;\n      while (y) {     // find gcd\n        unsigned t = x % y; x = y; y = t;\n      }\n      nsamples = vi.audio_samples_per_second / x; // 1200\n      const unsigned ncycles = Hz / x; // 11\n\n      audio = new(std::nothrow) SFLOAT[nsamples];\n      if (!audio)\n        env->ThrowError(\"ColorBars: insufficient memory\");\n\n      const double add_per_sample = ncycles / (double)nsamples;\n      double second_offset = 0.0;\n      for (unsigned i = 0; i < nsamples; i++) {\n        audio[i] = (SFLOAT)sin(PI * 2.0 * second_offset);\n        second_offset += add_per_sample;\n      }\n    }\n  }\n\n  // By the new \"staticframes\" parameter: colorbars we generate (copy) real new frames instead of a ready-to-use static one\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env)\n  {\n    AVS_UNUSED(n);\n    if (staticframes)\n      return frame; // original default method returns precomputed static frame.\n    else {\n      PVideoFrame result = env->NewVideoFrameP(vi, &frame);\n      // BitBlts are safe to call on all planes, planes with zero-size height or row-size are ignored.\n      env->BitBlt(result->GetWritePtr(), result->GetPitch(), frame->GetReadPtr(), frame->GetPitch(), frame->GetRowSize(), frame->GetHeight());\n      env->BitBlt(result->GetWritePtr(PLANAR_V), result->GetPitch(PLANAR_V), frame->GetReadPtr(PLANAR_V), frame->GetPitch(PLANAR_V), frame->GetRowSize(PLANAR_V), frame->GetHeight(PLANAR_V));\n      env->BitBlt(result->GetWritePtr(PLANAR_U), result->GetPitch(PLANAR_U), frame->GetReadPtr(PLANAR_U), frame->GetPitch(PLANAR_U), frame->GetRowSize(PLANAR_U), frame->GetHeight(PLANAR_U));\n      env->BitBlt(result->GetWritePtr(PLANAR_A), result->GetPitch(PLANAR_A), frame->GetReadPtr(PLANAR_A), frame->GetPitch(PLANAR_A), frame->GetRowSize(PLANAR_A), frame->GetHeight(PLANAR_A));\n      return result;\n    }\n  }\n\n  bool __stdcall GetParity(int n) {\n    AVS_UNUSED(n);\n    return false;\n  }\n  const VideoInfo& __stdcall GetVideoInfo() { return vi; }\n  int __stdcall SetCacheHints(int cachehints,int frame_range)\n  {\n    AVS_UNUSED(frame_range);\n    switch (cachehints)\n      {\n      case CACHE_GET_MTMODE:\n          return MT_NICE_FILTER;\n      case CACHE_DONT_CACHE_ME:\n          return 1;\n      default:\n          return 0;\n      }\n  };\n\n  void FillAudioZeros(void* buf, int start_offset, int count) {\n    const int bps = vi.BytesPerAudioSample();\n    unsigned char* byte_buf = (unsigned char*)buf;\n    memset(byte_buf + start_offset * bps, 0, count * bps);\n  }\n\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) {\n    AVS_UNUSED(env);\n#if 1\n    // This filter is non-cached so we guard against negative start and overread, like in Cache::GetAudio\n    if ((start + count <= 0) || (start >= vi.num_audio_samples)) {\n      // Completely skip.\n      FillAudioZeros(buf, 0, (int)count);\n      count = 0;\n      return;\n    }\n\n    if (start < 0) {  // Partial initial skip\n      FillAudioZeros(buf, 0, (int)-start);  // Fill all samples before 0 with silence.\n      count += start;  // Subtract start bytes from count.\n      buf = ((BYTE*)buf) - (int)(start * vi.BytesPerAudioSample());\n      start = 0;\n    }\n\n    if (start + count > vi.num_audio_samples) {  // Partial ending skip\n      FillAudioZeros(buf, (int)(vi.num_audio_samples - start), (int)(count - (vi.num_audio_samples - start)));  // Fill end samples\n      count = (vi.num_audio_samples - start);\n    }\n\n  const int d_mod = vi.audio_samples_per_second*2;\n  float* samples = (float*)buf;\n\n  unsigned j = (unsigned)(start % nsamples);\n  for (int i=0;i<count;i++) {\n    samples[i*2]=audio[j];\n    if (((start+i)%d_mod)>vi.audio_samples_per_second) {\n    samples[i*2+1]=audio[j];\n    } else {\n    samples[i*2+1]=0;\n    }\n    if (++j >= nsamples) j = 0;\n  }\n#else\n    int64_t Hz=440;\n    // Calculate what start equates in cycles.\n    // This is the number of cycles (rounded down) that has already been taken.\n    int64_t startcycle = (start*Hz) /  vi.audio_samples_per_second;\n\n    // Move offset down - this is to avoid float rounding errors\n    int start_offset = (int)(start - ((startcycle * vi.audio_samples_per_second) / Hz));\n\n    double add_per_sample=Hz/(double)vi.audio_samples_per_second;\n    double second_offset=((double)start_offset*add_per_sample);\n    int d_mod=vi.audio_samples_per_second*2;\n    float* samples = (float*)buf;\n\n    for (int i=0;i<count;i++) {\n        samples[i*2]=(SFLOAT)sin(PI * 2.0 * second_offset);\n        if (((start+i)%d_mod)>vi.audio_samples_per_second) {\n          samples[i*2+1]=samples[i*2];\n        } else {\n          samples[i*2+1]=0;\n        }\n        second_offset+=add_per_sample;\n    }\n#endif\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void* _type, IScriptEnvironment* env) {\n    const int type = (int)(size_t)_type;\n    enum { typeColorBars = 0, typeColorBarsHD = 1, typeColorBarsUHD = 2 };\n    // 0: ColorBars, 1: ColorBarsHD, 2: ColorBarsUHD\n\n    // { \"ColorBars\", BUILTIN_FUNC_PREFIX, \"[width]i[height]i[pixel_type]s[staticframes]b\", ColorBars::Create, (void*)0 },\n    // { \"ColorBarsHD\", BUILTIN_FUNC_PREFIX, \"[width]i[height]i[pixel_type]s[staticframes]b\", ColorBars::Create, (void*)1 },\n    // { \"ColorBarsUHD\", BUILTIN_FUNC_PREFIX, \"[width]i[height]i[pixel_type]s[staticframes]b[mode]i\", ColorBars::Create, (void*)2 }, // BT-2111-3\n\n    bool staticframes = args[3].AsBool(true);\n\n    const int default_width =\n      type == typeColorBarsUHD ? 3840 :\n      type == typeColorBarsHD ? 1288 :\n      640; // typeColorBars\n    int width = args[0].AsInt(default_width);\n    // for UHD the default height is adaptive\n    // ColorBarsUHD width may imply the height:\n    // 1920x1080, 3840x2160 or 7680x4320, but user can override it. For non-UHD types the default height is fixed.\n    const int default_height =\n      type == typeColorBarsUHD ? (width * 2160) / 3840 :\n      type == typeColorBarsHD ? 720 :\n      480; // typeColorBars\n\n    const char* default_pixel_type =\n      type == typeColorBarsUHD ? \"RGBP10\" :\n      type == typeColorBarsHD ? \"YV24\" :\n      \"RGB32\"; // typeColorBars\n\n    int UHD_subType = 0;\n    if (type == typeColorBarsUHD) {\n      UHD_subType = args[4].AsInt(0);\n    }\n\n    PClip clip = new ColorBars(width,\n                         args[1].AsInt(default_height),\n                         args[2].AsString(default_pixel_type),\n                         staticframes,\n                         type,\n                         UHD_subType,\n                         env);\n    // wrap in OnCPU to support multi devices\n    AVSValue arg[2]{ clip, 1 }; // prefetch=1: enable cache but not thread\n    AVSValue ret = env->Invoke(\"OnCPU\", AVSValue(arg, 2));\n    if (staticframes) {\n      return new SingleFrame(ret.AsClip());\n    }\n    return ret;\n  }\n};\n\n/********************************************************************\n********************************************************************/\n\n#ifdef AVS_WINDOWS\n// AviSource is Windows-only, because it explicitly relies on Video for Windows\nAVSValue __cdecl Create_SegmentedSource(AVSValue args, void* use_directshow, IScriptEnvironment* env) {\n  bool bAudio = !use_directshow && args[1].AsBool(true);\n  const char* pixel_type = 0;\n  const char* fourCC = 0;\n  int vtrack = 0;\n  int atrack = 0;\n  bool utf8;\n  const int inv_args_count = args.ArraySize();\n  AVSValue inv_args[9];\n  if (!use_directshow) {\n    pixel_type = args[2].AsString(\"\");\n    fourCC = args[3].AsString(\"\");\n    vtrack = args[4].AsInt(0);\n    atrack = args[5].AsInt(0);\n    utf8 = args[6].AsBool(false);\n  }\n  else {\n    for (int i=1; i<inv_args_count ;i++)\n      inv_args[i] = args[i];\n  }\n  args = args[0];\n  PClip result = 0;\n  const char* error_msg=0;\n  for (int i = 0; i < args.ArraySize(); ++i) {\n    char basename[260];\n    strcpy(basename, args[i].AsString());\n    char* extension = strrchr(basename, '.');\n    if (extension)\n      *extension++ = 0;\n    else\n      extension[0] = 0;\n    for (int j = 0; j < 100; ++j) {\n      char filename[260];\n      wsprintf(filename, \"%s.%02d.%s\", basename, j, extension);\n      if (GetFileAttributes(filename) != (DWORD)-1) {   // check if file exists\n          PClip clip;\n        try {\n          if (use_directshow) {\n            inv_args[0] = filename;\n            clip = env->Invoke(\"DirectShowSource\",AVSValue(inv_args, inv_args_count)).AsClip(); // no utf8 yet\n          } else {\n            clip =  (IClip*)(new AVISource(filename, bAudio, pixel_type, fourCC, vtrack, atrack, AVISource::MODE_NORMAL, utf8, env));\n          }\n          AVSValue arg[3] = { result, clip, 0 };\n          result = !result ? clip : env->Invoke(\"UnalignedSplice\", AVSValue(arg, 3)).AsClip();\n        } catch (const AvisynthError &e) {\n          error_msg=e.msg;\n        }\n      }\n    }\n  }\n  if (!result) {\n    if (!error_msg) {\n      env->ThrowError(\"Segmented%sSource: no files found!\", use_directshow ? \"DirectShow\" : \"AVI\");\n    } else {\n      env->ThrowError(\"Segmented%sSource: decompressor returned error:\\n%s!\", use_directshow ? \"DirectShow\" : \"AVI\",error_msg);\n    }\n  }\n  return result;\n}\n#endif\n\n/**********************************************************\n *                         TONE                           *\n **********************************************************/\nclass SampleGenerator {\npublic:\n  SampleGenerator() {}\n  virtual SFLOAT getValueAt(double where) {\n    AVS_UNUSED(where);\n    return 0.0f;}\n};\n\nclass SineGenerator : public SampleGenerator {\npublic:\n  SineGenerator() {}\n  SFLOAT getValueAt(double where) {return (SFLOAT)sin(PI * where * 2.0);}\n};\n\n\nclass NoiseGenerator : public SampleGenerator {\npublic:\n  NoiseGenerator() {\n    srand( (unsigned)time( NULL ) );\n  }\n\n  SFLOAT getValueAt(double where) {\n    AVS_UNUSED(where);\n    return (float) rand()*(2.0f/RAND_MAX) -1.0f;}\n};\n\nclass SquareGenerator : public SampleGenerator {\npublic:\n  SquareGenerator() {}\n\n  SFLOAT getValueAt(double where) {\n    if (where<=0.5) {\n      return 1.0f;\n    } else {\n      return -1.0f;\n    }\n  }\n};\n\nclass TriangleGenerator : public SampleGenerator {\npublic:\n  TriangleGenerator() {}\n\n  SFLOAT getValueAt(double where) {\n    if (where<=0.25) {\n      return (SFLOAT)(where*4.0);\n    } else if (where<=0.75) {\n      return (SFLOAT)((-4.0*(where-0.50)));\n    } else {\n      return (SFLOAT)((4.0*(where-1.00)));\n    }\n  }\n};\n\nclass SawtoothGenerator : public SampleGenerator {\npublic:\n  SawtoothGenerator() {}\n\n  SFLOAT getValueAt(double where) {\n    return (SFLOAT)(2.0*(where-0.5));\n  }\n};\n\n\nclass Tone : public IClip {\n  VideoInfo vi;\n  SampleGenerator *s;\n  const double freq;            // Frequency in Hz\n  const double samplerate;      // Samples per second\n  const int ch;                 // Number of channels\n  const double add_per_sample;  // How much should we add per sample in seconds\n  const float level;\n\npublic:\n\n  Tone(double _length, double _freq, int _samplerate, int _ch, const char* _type, float _level, IScriptEnvironment* env):\n             freq(_freq), samplerate(_samplerate), ch(_ch), add_per_sample(_freq/_samplerate), level(_level) {\n    memset(&vi, 0, sizeof(VideoInfo));\n    vi.sample_type = SAMPLE_FLOAT;\n    vi.nchannels = _ch;\n    vi.audio_samples_per_second = _samplerate;\n    vi.num_audio_samples=(int64_t)(_length*vi.audio_samples_per_second+0.5);\n\n    if (!lstrcmpi(_type, \"Sine\"))\n      s = new SineGenerator();\n    else if (!lstrcmpi(_type, \"Noise\"))\n      s = new NoiseGenerator();\n    else if (!lstrcmpi(_type, \"Square\"))\n      s = new SquareGenerator();\n    else if (!lstrcmpi(_type, \"Triangle\"))\n      s = new TriangleGenerator();\n    else if (!lstrcmpi(_type, \"Sawtooth\"))\n      s = new SawtoothGenerator();\n    else if (!lstrcmpi(_type, \"Silence\"))\n      s = new SampleGenerator();\n    else\n      env->ThrowError(\"Tone: Type was not recognized!\");\n  }\n\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) {\n    AVS_UNUSED(env);\n    // Where in the cycle are we in?\n    const double cycle = (freq * start) / samplerate;\n    double period_place = cycle - floor(cycle);\n\n    SFLOAT* samples = (SFLOAT*)buf;\n\n    for (int i=0;i<count;i++) {\n      SFLOAT v = s->getValueAt(period_place) * level;\n      for (int o=0;o<ch;o++) {\n        samples[o+i*ch] = v;\n      }\n      period_place += add_per_sample;\n      if (period_place >= 1.0)\n        period_place -= floor(period_place);\n    }\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env)\n  {\n    return new Tone(args[0].AsFloat(10.0f), args[1].AsFloat(440.0f), args[2].AsInt(48000),\n          args[3].AsInt(2), args[4].AsString(\"Sine\"), args[5].AsFloatf(1.0f), env);\n  }\n\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) {\n    AVS_UNUSED(n);\n    AVS_UNUSED(env);\n    return NULL; }\n  const VideoInfo& __stdcall GetVideoInfo() { return vi; }\n  bool __stdcall GetParity(int n) {\n    AVS_UNUSED(n);\n    return false; }\n  int __stdcall SetCacheHints(int cachehints,int frame_range) {\n    AVS_UNUSED(cachehints);\n    AVS_UNUSED(frame_range);\n    return 0; };\n\n};\n\n\nAVSValue __cdecl Create_Version(AVSValue args, void*, IScriptEnvironment* env) {\n  //     0       1       2           3         4\n  // [length]i[width]i[height]i[pixel_type]s[clip]c\n  VideoInfo vi_default;\n\n  int i_pixel_type = VideoInfo::CS_BGR24;\n\n  const bool has_clip = args[4].Defined();\n  if (has_clip) {\n    // clip overrides\n    vi_default = args[4].AsClip()->GetVideoInfo();\n    i_pixel_type = vi_default.pixel_type;\n  }\n\n  if (args[3].Defined()) {\n    i_pixel_type = GetPixelTypeFromName(args[3].AsString());\n    if (i_pixel_type == VideoInfo::CS_UNKNOWN)\n      env->ThrowError(\"Version: invalid 'pixel_type'\");\n  }\n\n  int num_frames = args[0].AsInt(has_clip ? vi_default.num_frames : -1); // auto (240)\n  int w = args[1].AsInt(has_clip ? vi_default.width : -1); // auto\n  int h = args[2].AsInt(has_clip ? vi_default.height : -1); // auto\n  const bool shrink = false;\n  const int textcolor = 0xECF2BF;\n  const int halocolor = 0;\n  const int bgcolor = 0x404040;\n\n  const int fps_numerator = has_clip ? vi_default.fps_numerator :-1; // auto\n  const int fps_denominator = has_clip ? vi_default.fps_denominator : -1; // auto\n\n  return Create_MessageClip(\n    AVS_FULLVERSION AVS_DEVELOPMENT_BUILD AVS_DEVELOPMENT_BUILD_GIT AVS_COPYRIGHT_UTF8,\n    w, h, i_pixel_type, shrink, textcolor, halocolor, bgcolor, fps_numerator, fps_denominator, num_frames,\n    true, // utf8\n    env);\n}\n\n\nextern const AVSFunction Source_filters[] = {\n#ifdef AVS_WINDOWS\n  { \"AVISource\",     BUILTIN_FUNC_PREFIX, \"s+[audio]b[pixel_type]s[fourCC]s[vtrack]i[atrack]i[utf8]b\", AVISource::Create, (void*) AVISource::MODE_NORMAL },\n  { \"AVIFileSource\", BUILTIN_FUNC_PREFIX, \"s+[audio]b[pixel_type]s[fourCC]s[vtrack]i[atrack]i[utf8]b\", AVISource::Create, (void*) AVISource::MODE_AVIFILE },\n  { \"WAVSource\",     BUILTIN_FUNC_PREFIX, \"s+[utf8]b\", AVISource::Create, (void*) AVISource::MODE_WAV },\n  { \"OpenDMLSource\", BUILTIN_FUNC_PREFIX, \"s+[audio]b[pixel_type]s[fourCC]s[vtrack]i[atrack]i[utf8]b\", AVISource::Create, (void*) AVISource::MODE_OPENDML },\n  { \"SegmentedAVISource\", BUILTIN_FUNC_PREFIX, \"s+[audio]b[pixel_type]s[fourCC]s[vtrack]i[atrack]i[utf8]b\", Create_SegmentedSource, (void*)0 },\n  { \"SegmentedDirectShowSource\", BUILTIN_FUNC_PREFIX,\n// args               0      1      2       3       4            5          6         7            8\n                     \"s+[fps]f[seek]b[audio]b[video]b[convertfps]b[seekzero]b[timeout]i[pixel_type]s\",\n                     Create_SegmentedSource, (void*)1 },\n// args             0         1       2        3            4     5                 6            7        8             9       10          11     12\n#endif\n  { \"BlankClip\", BUILTIN_FUNC_PREFIX, \"[]c*[length]i[width]i[height]i[pixel_type]s[fps]f[fps_denominator]i[audio_rate]i[stereo]b[sixteen_bit]b[color]i[color_yuv]i[clip]c\", Create_BlankClip },\n  { \"BlankClip\", BUILTIN_FUNC_PREFIX, \"[]c*[length]i[width]i[height]i[pixel_type]s[fps]f[fps_denominator]i[audio_rate]i[channels]i[sample_type]s[color]i[color_yuv]i[clip]c\", Create_BlankClip },\n  { \"BlankClip\", BUILTIN_FUNC_PREFIX, \"[]c*[length]i[width]i[height]i[pixel_type]s[fps]f[fps_denominator]i[audio_rate]i[stereo]b[sixteen_bit]b[color]i[color_yuv]i[clip]c[colors]f+\", Create_BlankClip },\n  { \"BlankClip\", BUILTIN_FUNC_PREFIX, \"[]c*[length]i[width]i[height]i[pixel_type]s[fps]f[fps_denominator]i[audio_rate]i[channels]i[sample_type]s[color]i[color_yuv]i[clip]c[colors]f+\", Create_BlankClip },\n  { \"Blackness\", BUILTIN_FUNC_PREFIX, \"[]c*[length]i[width]i[height]i[pixel_type]s[fps]f[fps_denominator]i[audio_rate]i[stereo]b[sixteen_bit]b[color]i[color_yuv]i[clip]c\", Create_BlankClip },\n  { \"Blackness\", BUILTIN_FUNC_PREFIX, \"[]c*[length]i[width]i[height]i[pixel_type]s[fps]f[fps_denominator]i[audio_rate]i[channels]i[sample_type]s[color]i[color_yuv]i[clip]c\", Create_BlankClip },\n  { \"MessageClip\", BUILTIN_FUNC_PREFIX, \"s[width]i[height]i[shrink]b[text_color]i[halo_color]i[bg_color]i[utf8]b\", Create_MessageClip },\n  { \"ColorBars\", BUILTIN_FUNC_PREFIX, \"[width]i[height]i[pixel_type]s[staticframes]b\", ColorBars::Create, (void*)0 },\n  { \"ColorBarsHD\", BUILTIN_FUNC_PREFIX, \"[width]i[height]i[pixel_type]s[staticframes]b\", ColorBars::Create, (void*)1 },\n  { \"ColorBarsUHD\", BUILTIN_FUNC_PREFIX, \"[width]i[height]i[pixel_type]s[staticframes]b[mode]i\", ColorBars::Create, (void*)2 }, // BT-2111-3\n  { \"Tone\", BUILTIN_FUNC_PREFIX, \"[length]f[frequency]f[samplerate]i[channels]i[type]s[level]f\", Tone::Create },\n\n  { \"Version\", BUILTIN_FUNC_PREFIX, \"[length]i[width]i[height]i[pixel_type]s[clip]c\", Create_Version },\n\n  { NULL }\n};\n\n#undef XP_LAMBDA_CAPTURE_FIX\n"
  },
  {
    "path": "avs_core/filters/text-overlay.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include <avs/config.h>\n#ifdef AVS_WINDOWS\n#include <avs/win.h>\n#else\n#include <avs/posix.h>\n#endif\n\n#include \"text-overlay.h\"\n#ifdef INTEL_INTRINSICS\n#include \"intel/text-overlay_sse.h\"\n#endif\n#include \"../convert/convert_matrix.h\"  // for RGB2YUV_Rec601\n#include \"../convert/convert_helper.h\"  // chroma location\n\n#define __STDC_FORMAT_MACROS\n#include <inttypes.h>\n#include <sstream>\n#include <cstdint>\n#include <cmath>\n#include <algorithm>\n#include <avs/minmax.h>\n#include \"../core/internal.h\"\n#include \"../core/info.h\"\n#include \"../core/strings.h\"\n#include \"../core/audio.h\"\n\n\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\nstatic HFONT LoadFont(const char name[], int size, bool bold, bool italic, int width=0, int angle=0)\n{\n  return CreateFont( size, width, angle, angle, bold ? FW_BOLD : FW_NORMAL,\n                     italic, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,\n                     CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE | FIXED_PITCH /*FF_DONTCARE | DEFAULT_PITCH*/, name );\n  // avs+: force fixed pitch when font is not found by name\n}\n#endif\n\n/********************************************************************\n***** Declare index of new filters for Avisynth's filter engine *****\n********************************************************************/\n\nextern const AVSFunction Text_filters[] = {\n  { \"ShowFrameNumber\",BUILTIN_FUNC_PREFIX,\n  \"c[scroll]b[offset]i[x]f[y]f[font]s[size]f[text_color]i[halo_color]i[font_width]f[font_angle]f[bold]b[italic]b[noaa]b\",\n  ShowFrameNumber::Create },\n\n  { \"ShowCRC32\",BUILTIN_FUNC_PREFIX,\n        \"c[scroll]b[offset]i[x]f[y]f[font]s[size]f[text_color]i[halo_color]i[font_width]f[font_angle]f[bold]b[italic]b[noaa]b\",\n        ShowCRC32::Create },\n\n  { \"ShowSMPTE\",BUILTIN_FUNC_PREFIX,\n  \"c[fps]f[offset]s[offset_f]i[x]f[y]f[font]s[size]f[text_color]i[halo_color]i[font_width]f[font_angle]f[bold]b[italic]b[noaa]b\",\n  ShowSMPTE::CreateSMTPE },\n\n  { \"ShowTime\",BUILTIN_FUNC_PREFIX,\n  \"c[offset_f]i[x]f[y]f[font]s[size]f[text_color]i[halo_color]i[font_width]f[font_angle]f[bold]b[italic]b[noaa]b\",\n  ShowSMPTE::CreateTime },\n\n  { \"Info\", BUILTIN_FUNC_PREFIX, \"c[font]s[size]f[text_color]i[halo_color]i[bold]b[italic]b[noaa]b[cpu]b[x]f[y]f[align]i\", FilterInfo::Create },  // clip\n\n  { \"Subtitle\",BUILTIN_FUNC_PREFIX,\n  \"cs[x]f[y]f[first_frame]i[last_frame]i[font]s[size]f[text_color]i[halo_color]i\"\n  \"[align]i[spc]i[lsp]i[font_width]f[font_angle]f[interlaced]b[font_filename]s[utf8]b[bold]b[italic]b[noaa]b\",\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n    Subtitle::Create\n#else\n    SimpleText::Create // poor man's SubTitle, it's simulated with SimpleText\n#endif\n},       // see docs!\n\n  { \"Compare\",BUILTIN_FUNC_PREFIX,\n  \"cc[channels]s[logfile]s[show_graph]b\",\n  Compare::Create },\n\n  { \"Text\",BUILTIN_FUNC_PREFIX,\n  \"cs[x]f[y]f[first_frame]i[last_frame]i[font]s[size]f[text_color]i[halo_color]i\"\n  \"[align]i[spc]i[lsp]i[font_width]f[font_angle]f[interlaced]b[font_filename]s[utf8]b[bold]b[italic]b[noaa]b[placement]s\",\n    SimpleText::Create },\n\n  { 0 }\n};\n\n\n\n\n\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n/******************************\n *******   Anti-alias    ******\n *****************************/\n\nAntialiaser::Antialiaser(int width, int height, const char fontname[], int size, int _textcolor, int _halocolor, bool _bold, bool _italic, bool _noaa, int font_width, int font_angle, bool _interlaced) :\n  alpha_calcs(0), w(width), h(height), textcolor(_textcolor), halocolor(_halocolor),\n  dirty(true), interlaced(_interlaced),\n  bold(_bold), italic(_italic), noaa(_noaa)\n{\n  struct {\n    BITMAPINFOHEADER bih;\n    RGBQUAD clr[2];\n  } b;\n\n  b.bih.biSize                    = sizeof(BITMAPINFOHEADER);\n  b.bih.biWidth                   = width * 8 + 32;\n  b.bih.biHeight                  = height * 8 + 32;\n  b.bih.biBitCount                = 1;\n  b.bih.biPlanes                  = 1;\n  b.bih.biCompression             = BI_RGB;\n  b.bih.biXPelsPerMeter   = 0;\n  b.bih.biYPelsPerMeter   = 0;\n  b.bih.biClrUsed                 = 2;\n  b.bih.biClrImportant    = 2;\n  b.clr[0].rgbBlue = b.clr[0].rgbGreen = b.clr[0].rgbRed = 0;\n  b.clr[1].rgbBlue = b.clr[1].rgbGreen = b.clr[1].rgbRed = 255;\n\n  hdcAntialias = CreateCompatibleDC(NULL);\n  if (hdcAntialias) {\n  hbmAntialias = CreateDIBSection\n    ( hdcAntialias,\n    (BITMAPINFO *)&b,\n    DIB_RGB_COLORS,\n    &lpAntialiasBits,\n    NULL,\n    0 );\n  if (hbmAntialias) {\n    hbmDefault = (HBITMAP)SelectObject(hdcAntialias, hbmAntialias);\n    HFONT newfont = LoadFont(fontname, size, bold, italic, font_width, font_angle);\n    hfontDefault = newfont ? (HFONT)SelectObject(hdcAntialias, newfont) : 0;\n\n    SetMapMode(hdcAntialias, MM_TEXT);\n    SetTextColor(hdcAntialias, 0xffffff);\n    SetBkColor(hdcAntialias, 0);\n\n    alpha_calcs = new(std::nothrow) unsigned short[width*height*4];\n    if (!alpha_calcs) FreeDC();\n  }\n  }\n}\n\n\nAntialiaser::~Antialiaser() {\n  FreeDC();\n  delete[] alpha_calcs;\n}\n\n\nHDC Antialiaser::GetDC() {\n  dirty = true;\n  return hdcAntialias;\n}\n\n\nvoid Antialiaser::FreeDC() {\n  if (hdcAntialias) { // :FIXME: Interlocked\n    if (hbmDefault) {\n    DeleteObject(SelectObject(hdcAntialias, hbmDefault));\n    hbmDefault = 0;\n  }\n    if (hfontDefault) {\n    DeleteObject(SelectObject(hdcAntialias, hfontDefault));\n    hfontDefault = 0;\n  }\n    DeleteDC(hdcAntialias);\n    hdcAntialias = 0;\n  }\n}\n\n\nvoid Antialiaser::Apply( const VideoInfo& vi, PVideoFrame* frame, int pitch)\n{\n  if (!alpha_calcs) return;\n\n  if (vi.IsRGB32())\n    ApplyRGB_packed<uint8_t, true>((*frame)->GetWritePtr(), pitch);\n  else if (vi.IsRGB64())\n    ApplyRGB_packed<uint16_t, true>((*frame)->GetWritePtr(), pitch);\n  else if (vi.IsRGB24())\n    ApplyRGB_packed<uint8_t, false>((*frame)->GetWritePtr(), pitch);\n  else if (vi.IsRGB48())\n    ApplyRGB_packed<uint16_t, false>((*frame)->GetWritePtr(), pitch);\n  else if (vi.IsYUY2())\n    ApplyYUY2((*frame)->GetWritePtr(), pitch);\n  else if (vi.IsYV12()) // YUV420 16/32 bit goes to generic path\n    ApplyYV12((*frame)->GetWritePtr(), pitch,\n              (*frame)->GetPitch(PLANAR_U),\n              (*frame)->GetWritePtr(PLANAR_U),\n              (*frame)->GetWritePtr(PLANAR_V) );\n  else if (vi.NumComponents() == 1) // Y8, Y16, Y32\n    ApplyPlanar((*frame)->GetWritePtr(), pitch, 0, 0, 0, 0, 0, vi.BitsPerComponent(), vi.IsRGB());\n  else if (vi.IsPlanar()) {\n      if(vi.IsPlanarRGB() || vi.IsPlanarRGBA())\n          // internal buffer: Y-R, U-G, V-B\n        ApplyPlanar((*frame)->GetWritePtr(PLANAR_R), pitch,\n            (*frame)->GetPitch(PLANAR_G),\n            (*frame)->GetWritePtr(PLANAR_G),\n            (*frame)->GetWritePtr(PLANAR_B),\n            vi.GetPlaneWidthSubsampling(PLANAR_G),  // no subsampling\n            vi.GetPlaneHeightSubsampling(PLANAR_G),\n            vi.BitsPerComponent(), vi.IsRGB() );\n      else\n        ApplyPlanar((*frame)->GetWritePtr(), pitch,\n            (*frame)->GetPitch(PLANAR_U),\n            (*frame)->GetWritePtr(PLANAR_U),\n            (*frame)->GetWritePtr(PLANAR_V),\n            vi.GetPlaneWidthSubsampling(PLANAR_U),\n            vi.GetPlaneHeightSubsampling(PLANAR_U),\n            vi.BitsPerComponent(), vi.IsRGB());\n  }\n}\n\n\nvoid Antialiaser::ApplyYV12(BYTE* buf, int pitch, int pitchUV, BYTE* bufU, BYTE* bufV) {\n  if (dirty) {\n    GetAlphaRect();\n  xl &= -2; xr |= 1;\n  yb &= -2; yt |= 1;\n  }\n  const int w4 = w*4;\n  unsigned short* alpha = alpha_calcs + yb*w4;\n  buf  += pitch*yb;\n  bufU += (pitchUV*yb)>>1;\n  bufV += (pitchUV*yb)>>1;\n\n  for (int y=yb; y<=yt; y+=2) {\n    for (int x=xl; x<=xr; x+=2) {\n      const int x4 = x<<2;\n      const int basealpha00 = alpha[x4+0];\n      const int basealpha10 = alpha[x4+4];\n      const int basealpha01 = alpha[x4+0+w4];\n      const int basealpha11 = alpha[x4+4+w4];\n      const int basealphaUV = basealpha00 + basealpha10 + basealpha01 + basealpha11;\n\n      if (basealphaUV != 1024) {\n        buf[x+0]       = BYTE((buf[x+0]       * basealpha00 + alpha[x4+3]   ) >> 8);\n        buf[x+1]       = BYTE((buf[x+1]       * basealpha10 + alpha[x4+7]   ) >> 8);\n        buf[x+0+pitch] = BYTE((buf[x+0+pitch] * basealpha01 + alpha[x4+3+w4]) >> 8);\n        buf[x+1+pitch] = BYTE((buf[x+1+pitch] * basealpha11 + alpha[x4+7+w4]) >> 8);\n\n        const int au  = alpha[x4+2] + alpha[x4+6] + alpha[x4+2+w4] + alpha[x4+6+w4];\n        bufU[x>>1] = BYTE((bufU[x>>1] * basealphaUV + au) >> 10);\n\n        const int av  = alpha[x4+1] + alpha[x4+5] + alpha[x4+1+w4] + alpha[x4+5+w4];\n        bufV[x>>1] = BYTE((bufV[x>>1] * basealphaUV + av) >> 10);\n      }\n    }\n    buf += pitch<<1;\n    bufU += pitchUV;\n    bufV += pitchUV;\n    alpha += w<<3;\n  }\n}\n\n\ntemplate<int shiftX, int shiftY, int bits_per_pixel>\nvoid Antialiaser::ApplyPlanar_core(BYTE* buf, int pitch, int pitchUV, BYTE* bufU, BYTE* bufV, bool isRGB)\n{\n  const int stepX = 1<<shiftX;\n  const int stepY = 1<<shiftY;\n\n  if (dirty) {\n    GetAlphaRect();\n    xl &= -stepX; xr |= stepX-1;\n    yb &= -stepY; yt |= stepY-1;\n  }\n  const int w4 = w*4;\n  unsigned short* alpha = alpha_calcs + yb*w4;\n  buf += pitch*yb;\n\n  // Apply Y\n  // different paths for different bitdepth\n  // todo PF 161208 shiftX shiftY bits_per_pixel templates\n  // perpaps int->byte, short (faster??)\n  if constexpr(bits_per_pixel == 8) {\n    for (int y=yb; y<=yt; y+=1) {\n      for (int x=xl; x<=xr; x+=1) {\n        const int x4 = x<<2;\n        const int basealpha = alpha[x4+0];\n        if (basealpha != 256) {\n          buf[x] = BYTE((buf[x] * basealpha + alpha[x4 + 3]) >> 8);\n        }\n      }\n      buf += pitch;\n      alpha += w4;\n    }\n  }\n  else if constexpr(bits_per_pixel >= 10 && bits_per_pixel <= 16) { // uint16_t\n    for (int y=yb; y<=yt; y+=1) {\n      for (int x=xl; x<=xr; x+=1) {\n        const int x4 = x<<2;\n        const int basealpha = alpha[x4+0];\n        if (basealpha != 256) {\n          reinterpret_cast<uint16_t *>(buf)[x] = (uint16_t)((reinterpret_cast<uint16_t *>(buf)[x] * basealpha + ((int)alpha[x4 + 3] << (bits_per_pixel-8))) >> 8);\n        }\n      }\n      buf += pitch;\n      alpha += w4;\n    }\n  }\n  else if constexpr(bits_per_pixel == 32) { // float assume 0..1.0 scale\n    for (int y=yb; y<=yt; y+=1) {\n      for (int x=xl; x<=xr; x+=1) {\n        const int x4 = x<<2;\n        const int basealpha = alpha[x4+0];\n        if (basealpha != 256) {\n          reinterpret_cast<float *>(buf)[x] = reinterpret_cast<float *>(buf)[x] * basealpha / 256.0f + alpha[x4 + 3] / 65536.0f;\n        }\n      }\n      buf += pitch;\n      alpha += w4;\n    }\n  }\n\n  if (!bufU) return;\n\n  // This will not be fast, but it will be generic.\n  const int skipThresh = 256 << (shiftX+shiftY);\n  const int shifter = 8+shiftX+shiftY;\n  const int UVw4 = w<<(2+shiftY);\n  const int xlshiftX = xl>>shiftX;\n\n  alpha = alpha_calcs + yb*w4;\n  bufU += (pitchUV*yb)>>shiftY;\n  bufV += (pitchUV*yb)>>shiftY;\n\n  // different paths for different bitdepth\n  if constexpr(bits_per_pixel == 8) {\n    for (int y=yb; y<=yt; y+=stepY) {\n      for (int x=xl, xs=xlshiftX; x<=xr; x+=stepX, xs+=1) {\n        unsigned short* UValpha = alpha + x*4;\n        int basealphaUV = 0;\n        int au = 0;\n        int av = 0;\n        for (int i = 0; i<stepY; i++) {\n          for (int j = 0; j<stepX; j++) {\n            basealphaUV += UValpha[0 + j*4];\n            av          += UValpha[1 + j*4];\n            au          += UValpha[2 + j*4];\n          }\n          UValpha += w4;\n        }\n        if (basealphaUV != skipThresh) {\n          bufU[xs] = BYTE((bufU[xs] * basealphaUV + au) >> shifter);\n          bufV[xs] = BYTE((bufV[xs] * basealphaUV + av) >> shifter);\n        }\n      }// end for x\n      bufU  += pitchUV;\n      bufV  += pitchUV;\n      alpha += UVw4;\n    }//end for y\n  }\n  else if constexpr(bits_per_pixel >= 10 && bits_per_pixel <= 16) { // uint16_t\n    for (int y=yb; y<=yt; y+=stepY) {\n      for (int x=xl, xs=xlshiftX; x<=xr; x+=stepX, xs+=1) {\n        unsigned short* UValpha = alpha + x*4;\n        int basealphaUV = 0;\n        int au = 0;\n        int av = 0;\n        for (int i = 0; i<stepY; i++) {\n          for (int j = 0; j<stepX; j++) {\n            basealphaUV += UValpha[0 + j*4];\n            av          += UValpha[1 + j*4];\n            au          += UValpha[2 + j*4];\n          }\n          UValpha += w4;\n        }\n        if (basealphaUV != skipThresh) {\n          reinterpret_cast<uint16_t *>(bufU)[xs] = (uint16_t)((reinterpret_cast<uint16_t *>(bufU)[xs] * basealphaUV + (au << (bits_per_pixel-8))) >> shifter);\n          reinterpret_cast<uint16_t *>(bufV)[xs] = (uint16_t)((reinterpret_cast<uint16_t *>(bufV)[xs] * basealphaUV + (av << (bits_per_pixel-8))) >> shifter);\n        }\n      }// end for x\n      bufU  += pitchUV;\n      bufV  += pitchUV;\n      alpha += UVw4;\n    }//end for y\n  }\n  else if constexpr(bits_per_pixel == 32) { // float. assume 0..1.0 scale\n    const float shifter_inv_f = 1.0f / (1 << shifter);\n    const float a_factor = shifter_inv_f / 256.0f;\n#ifdef FLOAT_CHROMA_IS_HALF_CENTERED\n    const float middle_shift_f = 0.0f;\n#else\n    const float middle_shift_f = isRGB ? 0.0f : 0.5f; // yes, correction needed in and out\n#endif\n    for (int y=yb; y<=yt; y+=stepY) {\n      for (int x=xl, xs=xlshiftX; x<=xr; x+=stepX, xs+=1) {\n        unsigned short* UValpha = alpha + x*4;\n        int basealphaUV = 0;\n        int au = 0;\n        int av = 0;\n        for (int i = 0; i<stepY; i++) {\n          for (int j = 0; j<stepX; j++) {\n            basealphaUV += UValpha[0 + j*4];\n            av          += UValpha[1 + j*4];\n            au          += UValpha[2 + j*4];\n          }\n          UValpha += w4;\n        }\n        if (basealphaUV != skipThresh) {\n          const float basealphaUV_f = (float)basealphaUV * shifter_inv_f;\n          reinterpret_cast<float *>(bufU)[xs] = (reinterpret_cast<float *>(bufU)[xs] + middle_shift_f) * basealphaUV_f + au * a_factor - middle_shift_f;\n          reinterpret_cast<float *>(bufV)[xs] = (reinterpret_cast<float *>(bufV)[xs] + middle_shift_f) * basealphaUV_f + av * a_factor - middle_shift_f;\n        }\n      }// end for x\n      bufU  += pitchUV;\n      bufV  += pitchUV;\n      alpha += UVw4;\n    }//end for y\n  }\n}\n\nvoid Antialiaser::ApplyPlanar(BYTE* buf, int pitch, int pitchUV, BYTE* bufU, BYTE* bufV, int shiftX, int shiftY, int bits_per_pixel, bool isRGB) {\n  const int stepX = 1 << shiftX;\n  const int stepY = 1 << shiftY;\n  switch (bits_per_pixel) {\n  case 8:\n    if (shiftX == 0 && shiftY == 0) {\n      ApplyPlanar_core<0, 0, 8>(buf, pitch, pitchUV, bufU, bufV, isRGB); // 4:4:4\n      return;\n    }\n    else if (shiftX == 1 && shiftY == 0) {\n      ApplyPlanar_core<1, 0, 8>(buf, pitch, pitchUV, bufU, bufV, isRGB); // 4:2:2\n      return;\n    }\n    else if (shiftX == 1 && shiftY == 1) {\n      ApplyPlanar_core<1, 1, 8>(buf, pitch, pitchUV, bufU, bufV, isRGB); // 4:2:0\n      return;\n    }\n    break;\n  case 10:\n    if (shiftX == 0 && shiftY == 0) {\n      ApplyPlanar_core<0, 0, 10>(buf, pitch, pitchUV, bufU, bufV, isRGB); // 4:4:4\n      return;\n    }\n    else if (shiftX == 1 && shiftY == 0) {\n      ApplyPlanar_core<1, 0, 10>(buf, pitch, pitchUV, bufU, bufV, isRGB); // 4:2:2\n      return;\n    }\n    else if (shiftX == 1 && shiftY == 1) {\n      ApplyPlanar_core<1, 1, 10>(buf, pitch, pitchUV, bufU, bufV, isRGB); // 4:2:0\n      return;\n    }\n    break;\n  case 12:\n    if (shiftX == 0 && shiftY == 0) {\n      ApplyPlanar_core<0, 0, 12>(buf, pitch, pitchUV, bufU, bufV, isRGB); // 4:4:4\n      return;\n    }\n    else if (shiftX == 1 && shiftY == 0) {\n      ApplyPlanar_core<1, 0, 12>(buf, pitch, pitchUV, bufU, bufV, isRGB); // 4:2:2\n      return;\n    }\n    else if (shiftX == 1 && shiftY == 1) {\n      ApplyPlanar_core<1, 1, 12>(buf, pitch, pitchUV, bufU, bufV, isRGB); // 4:2:0\n      return;\n    }\n    break;\n  case 14:\n    if (shiftX == 0 && shiftY == 0) {\n      ApplyPlanar_core<0, 0, 14>(buf, pitch, pitchUV, bufU, bufV, isRGB); // 4:4:4\n      return;\n    }\n    else if (shiftX == 1 && shiftY == 0) {\n      ApplyPlanar_core<1, 0, 14>(buf, pitch, pitchUV, bufU, bufV, isRGB); // 4:2:2\n      return;\n    }\n    else if (shiftX == 1 && shiftY == 1) {\n      ApplyPlanar_core<1, 1, 14>(buf, pitch, pitchUV, bufU, bufV, isRGB); // 4:2:0\n      return;\n    }\n    break;\n  case 16:\n    if (shiftX == 0 && shiftY == 0) {\n      ApplyPlanar_core<0, 0, 16>(buf, pitch, pitchUV, bufU, bufV, isRGB); // 4:4:4\n      return;\n    }\n    else if (shiftX == 1 && shiftY == 0) {\n      ApplyPlanar_core<1, 0, 16>(buf, pitch, pitchUV, bufU, bufV, isRGB); // 4:2:2\n      return;\n    }\n    else if (shiftX == 1 && shiftY == 1) {\n      ApplyPlanar_core<1, 1, 16>(buf, pitch, pitchUV, bufU, bufV, isRGB); // 4:2:0\n      return;\n    }\n    break;\n  case 32:\n    if (shiftX == 0 && shiftY == 0) {\n      ApplyPlanar_core<0, 0, 32>(buf, pitch, pitchUV, bufU, bufV, isRGB); // 4:4:4\n      return;\n    }\n    else if (shiftX == 1 && shiftY == 0) {\n      ApplyPlanar_core<1, 0, 32>(buf, pitch, pitchUV, bufU, bufV, isRGB); // 4:2:2\n      return;\n    }\n    else if (shiftX == 1 && shiftY == 1) {\n      ApplyPlanar_core<1, 1, 32>(buf, pitch, pitchUV, bufU, bufV, isRGB); // 4:2:0\n      return;\n    }\n    break;\n  }\n  // keep old path for for any nonstandard surprise\n\n  if (dirty) {\n    GetAlphaRect();\n    xl &= -stepX; xr |= stepX-1;\n    yb &= -stepY; yt |= stepY-1;\n  }\n  const int w4 = w*4;\n  unsigned short* alpha = alpha_calcs + yb*w4;\n  buf += pitch*yb;\n\n  // Apply Y\n  // different paths for different bitdepth\n  // todo PF 161208 shiftX shiftY bits_per_pixel templates\n  // perpaps int->byte, short (faster??)\n  if(bits_per_pixel == 8) {\n      for (int y=yb; y<=yt; y+=1) {\n          for (int x=xl; x<=xr; x+=1) {\n              const int x4 = x<<2;\n              const int basealpha = alpha[x4+0];\n              if (basealpha != 256) {\n                  buf[x] = BYTE((buf[x] * basealpha + alpha[x4 + 3]) >> 8);\n              }\n          }\n          buf += pitch;\n          alpha += w4;\n      }\n  }\n  else if (bits_per_pixel >= 10 && bits_per_pixel <= 16) { // uint16_t\n      for (int y=yb; y<=yt; y+=1) {\n          for (int x=xl; x<=xr; x+=1) {\n              const int x4 = x<<2;\n              const int basealpha = alpha[x4+0];\n              if (basealpha != 256) {\n                  reinterpret_cast<uint16_t *>(buf)[x] = (uint16_t)((reinterpret_cast<uint16_t *>(buf)[x] * basealpha + ((int)alpha[x4 + 3] << (bits_per_pixel-8))) >> 8);\n              }\n          }\n          buf += pitch;\n          alpha += w4;\n      }\n  }\n  else { // float assume 0..1.0 scale\n      for (int y=yb; y<=yt; y+=1) {\n          for (int x=xl; x<=xr; x+=1) {\n              const int x4 = x<<2;\n              const int basealpha = alpha[x4+0];\n              if (basealpha != 256) {\n                  reinterpret_cast<float *>(buf)[x] = reinterpret_cast<float *>(buf)[x] * basealpha / 256.0f + alpha[x4 + 3] / 65536.0f;\n              }\n          }\n          buf += pitch;\n          alpha += w4;\n      }\n  }\n\n  if (!bufU) return;\n\n  // This will not be fast, but it will be generic.\n  const int skipThresh = 256 << (shiftX+shiftY);\n  const int shifter = 8+shiftX+shiftY;\n  const int UVw4 = w<<(2+shiftY);\n  const int xlshiftX = xl>>shiftX;\n\n  alpha = alpha_calcs + yb*w4;\n  bufU += (pitchUV*yb)>>shiftY;\n  bufV += (pitchUV*yb)>>shiftY;\n\n  // different paths for different bitdepth\n  if(bits_per_pixel == 8) {\n      for (int y=yb; y<=yt; y+=stepY) {\n          for (int x=xl, xs=xlshiftX; x<=xr; x+=stepX, xs+=1) {\n              unsigned short* UValpha = alpha + x*4;\n              int basealphaUV = 0;\n              int au = 0;\n              int av = 0;\n              for (int i = 0; i<stepY; i++) {\n                  for (int j = 0; j<stepX; j++) {\n                      basealphaUV += UValpha[0 + j*4];\n                      av          += UValpha[1 + j*4];\n                      au          += UValpha[2 + j*4];\n                  }\n                  UValpha += w4;\n              }\n              if (basealphaUV != skipThresh) {\n                  bufU[xs] = BYTE((bufU[xs] * basealphaUV + au) >> shifter);\n                  bufV[xs] = BYTE((bufV[xs] * basealphaUV + av) >> shifter);\n              }\n          }// end for x\n          bufU  += pitchUV;\n          bufV  += pitchUV;\n          alpha += UVw4;\n      }//end for y\n  }\n  else if (bits_per_pixel >= 10 && bits_per_pixel <= 16) { // uint16_t\n      for (int y=yb; y<=yt; y+=stepY) {\n          for (int x=xl, xs=xlshiftX; x<=xr; x+=stepX, xs+=1) {\n              unsigned short* UValpha = alpha + x*4;\n              int basealphaUV = 0;\n              int au = 0;\n              int av = 0;\n              for (int i = 0; i<stepY; i++) {\n                  for (int j = 0; j<stepX; j++) {\n                      basealphaUV += UValpha[0 + j*4];\n                      av          += UValpha[1 + j*4];\n                      au          += UValpha[2 + j*4];\n                  }\n                  UValpha += w4;\n              }\n              if (basealphaUV != skipThresh) {\n                  reinterpret_cast<uint16_t *>(bufU)[xs] = (uint16_t)((reinterpret_cast<uint16_t *>(bufU)[xs] * basealphaUV + (au << (bits_per_pixel-8))) >> shifter);\n                  reinterpret_cast<uint16_t *>(bufV)[xs] = (uint16_t)((reinterpret_cast<uint16_t *>(bufV)[xs] * basealphaUV + (av << (bits_per_pixel-8))) >> shifter);\n              }\n          }// end for x\n          bufU  += pitchUV;\n          bufV  += pitchUV;\n          alpha += UVw4;\n      }//end for y\n  }\n  else { // float. assume 0..1.0 scale\n#ifdef FLOAT_CHROMA_IS_HALF_CENTERED\n      const float middle_shift_f = 0.0f;\n#else\n      const float middle_shift_f = isRGB ? 0.0f : 0.5f; // yes, correction needed in and out\n#endif\n      const float shifter_inv_f = 1.0f / (1 << shifter);\n      const float a_factor = shifter_inv_f / 256.0f;\n      for (int y=yb; y<=yt; y+=stepY) {\n          for (int x=xl, xs=xlshiftX; x<=xr; x+=stepX, xs+=1) {\n              unsigned short* UValpha = alpha + x*4;\n              int basealphaUV = 0;\n              int au = 0;\n              int av = 0;\n              for (int i = 0; i<stepY; i++) {\n                  for (int j = 0; j<stepX; j++) {\n                      basealphaUV += UValpha[0 + j*4];\n                      av          += UValpha[1 + j*4];\n                      au          += UValpha[2 + j*4];\n                  }\n                  UValpha += w4;\n              }\n              if (basealphaUV != skipThresh) {\n                  const float basealphaUV_f = (float)basealphaUV * shifter_inv_f;\n                  reinterpret_cast<float *>(bufU)[xs] = (reinterpret_cast<float *>(bufU)[xs] + middle_shift_f) * basealphaUV_f + au * a_factor - middle_shift_f;\n                  reinterpret_cast<float *>(bufV)[xs] = (reinterpret_cast<float *>(bufV)[xs] + middle_shift_f) * basealphaUV_f + av * a_factor - middle_shift_f;\n              }\n          }// end for x\n          bufU  += pitchUV;\n          bufV  += pitchUV;\n          alpha += UVw4;\n      }//end for y\n  }\n}\n\n\nvoid Antialiaser::ApplyYUY2(BYTE* buf, int pitch) {\n  if (dirty) {\n    GetAlphaRect();\n  xl &= -2; xr |= 1;\n  }\n  unsigned short* alpha = alpha_calcs + yb*w*4;\n  buf += pitch*yb;\n\n  for (int y=yb; y<=yt; ++y) {\n    for (int x=xl; x<=xr; x+=2) {\n      const int basealpha0  = alpha[x*4+0];\n      const int basealpha1  = alpha[x*4+4];\n      const int basealphaUV = basealpha0 + basealpha1;\n\n      if (basealphaUV != 512) {\n        buf[x*2+0] = BYTE((buf[x*2+0] * basealpha0 + alpha[x*4+3]) >> 8);\n        buf[x*2+2] = BYTE((buf[x*2+2] * basealpha1 + alpha[x*4+7]) >> 8);\n\n        const int au  = alpha[x*4+2] + alpha[x*4+6];\n        buf[x*2+1] = BYTE((buf[x*2+1] * basealphaUV + au) >> 9);\n\n        const int av  = alpha[x*4+1] + alpha[x*4+5];\n        buf[x*2+3] = BYTE((buf[x*2+3] * basealphaUV + av) >> 9);\n      }\n    }\n    buf += pitch;\n    alpha += w*4;\n  }\n}\n\n\ntemplate<typename pixel_t, bool has_alpha>\nvoid Antialiaser::ApplyRGB_packed(BYTE* buf, int pitch)\n{\n  if (dirty) GetAlphaRect();\n  unsigned short* alpha = alpha_calcs + yb * w * 4;\n  buf += pitch * (h - yb - 1);\n\n  constexpr int pixel_step = has_alpha ? 4 : 3; // RGB32/64, RGB24/48\n  constexpr int alpha_shift = sizeof(pixel_t) == 1 ? 0 : 8; // RGB32/64, RGB24/48\n  for (int y = yb; y <= yt; ++y) {\n    for (int x = xl; x <= xr; ++x) {\n      pixel_t* buf2 = reinterpret_cast<pixel_t*>(buf) + (x * pixel_step);\n      const int basealpha = alpha[x * 4 + 0];\n      if (basealpha != 256) {\n        buf2[0] = (pixel_t)((buf2[0] * basealpha + (alpha[x*4+1] << alpha_shift)) >> 8);\n        buf2[1] = (pixel_t)((buf2[1] * basealpha + (alpha[x*4+2] << alpha_shift)) >> 8);\n        buf2[2] = (pixel_t)((buf2[2] * basealpha + (alpha[x*4+3] << alpha_shift)) >> 8);\n      }\n    }\n    buf -= pitch;\n    alpha += w*4;\n  }\n}\n\n\nvoid Antialiaser::GetAlphaRect()\n{\n  dirty = false;\n\n  static BYTE bitcnt[256],    // bit count\n              bitexl[256],    // expand to left bit\n              bitexr[256];    // expand to right bit\n  static bool fInited = false;\n  static unsigned short gamma[129]; // Gamma lookups\n\n  if (!fInited) {\n    fInited = true;\n\n    const double scale = 516*64/sqrt(128.0);\n    {for(int i=0; i<=128; i++)\n      gamma[i]=uint16_t(sqrt((double)i) * scale + 0.5); // Gamma = 2.0\n    }\n\n  {for(int i=0; i<256; i++) {\n      BYTE b=0, l=0, r=0;\n\n      if (i&  1) { b=1; l|=0x01; r|=0xFF; }\n      if (i&  2) { ++b; l|=0x03; r|=0xFE; }\n      if (i&  4) { ++b; l|=0x07; r|=0xFC; }\n      if (i&  8) { ++b; l|=0x0F; r|=0xF8; }\n      if (i& 16) { ++b; l|=0x1F; r|=0xF0; }\n      if (i& 32) { ++b; l|=0x3F; r|=0xE0; }\n      if (i& 64) { ++b; l|=0x7F; r|=0xC0; }\n      if (i&128) { ++b; l|=0xFF; r|=0x80; }\n\n      bitcnt[i] = b;\n      bitexl[i] = l;\n      bitexr[i] = r;\n    }}\n  }\n\n  const int RYtext = ((textcolor>>16)&255), GUtext = ((textcolor>>8)&255), BVtext = (textcolor&255);\n  const int RYhalo = ((halocolor>>16)&255), GUhalo = ((halocolor>>8)&255), BVhalo = (halocolor&255);\n\n  // Scaled Alpha\n  const int Atext = 255 - ((textcolor >> 24) & 0xFF);\n  const int Ahalo = 255 - ((halocolor >> 24) & 0xFF);\n\n  const int srcpitch = (w+4+3) & -4;\n\n  xl=0;\n  xr=w+1;\n  yt=-1;\n  yb=h;\n\n  unsigned short* dest = alpha_calcs;\n  for (int y=0; y<h; ++y) {\n    BYTE* src = (BYTE*)lpAntialiasBits + ((h-y-1)*8 + 20) * srcpitch + 2;\n    int wt = w;\n    do {\n      int i;\n\n#pragma warning(push)\n#pragma warning(disable: 4068)\n      DWORD tmp = 0;\n\n      if (interlaced) {\n#pragma unroll\n        for (int ii = -8; ii < 16; ++ii) {\n          tmp |= *reinterpret_cast<int*>(src + srcpitch*ii - 1);\n        }\n      } else {\n#if 0\n#pragma unroll\n\n        for (int i = -12; i < 20; ++i) {\n          tmp |= *reinterpret_cast<int*>(src + srcpitch*i - 1);\n        }\n#else\n        BYTE *tmpsrc = src + srcpitch*(-12) - 1;\n#pragma unroll\n        // PF 161208 speedup test manual unroll, no pragma in VS\n        for (int ii = -12; ii < 20; ii+=4) { // 0..31\n          tmp |= *reinterpret_cast<int*>(tmpsrc) |\n            *reinterpret_cast<int*>(tmpsrc+srcpitch*1) |\n            *reinterpret_cast<int*>(tmpsrc+srcpitch*2) |\n            *reinterpret_cast<int*>(tmpsrc+srcpitch*3)/* |\n            *reinterpret_cast<int*>(tmpsrc+srcpitch*4) |\n            *reinterpret_cast<int*>(tmpsrc+srcpitch*5) |\n            *reinterpret_cast<int*>(tmpsrc+srcpitch*6) |\n            *reinterpret_cast<int*>(tmpsrc+srcpitch*7)*/\n            ;\n          tmpsrc += srcpitch*4;\n        }\n#endif\n      }\n\n      tmp &= 0x00FFFFFF;\n#pragma warning(pop)\n\n\n      if (tmp != 0) {     // quick exit in a common case\n        if (wt >= xl) xl=wt;\n        if (wt <= xr) xr=wt;\n        if (y  >= yt) yt=y;\n        if (y  <= yb) yb=y;\n\n        int alpha1, alpha2;\n\n        alpha1 = alpha2 = 0;\n\n        if (interlaced) {\n          BYTE topmask=0, cenmask=0, botmask=0;\n          BYTE hmasks[16], mask;\n\n          for(i=-4; i<12; i++) {// For interlaced include extra half cells above and below\n            mask = src[srcpitch*i];\n            // How many lit pixels in the centre cell?\n            alpha1 += bitcnt[mask];\n            // turn on all halo bits if cell has any lit pixels\n            mask = - !! mask;\n            // Check left and right neighbours, extend the halo\n            // mask 8 pixels in from the nearest lit pixels.\n            mask |= bitexr[src[srcpitch*i-1]];\n            mask |= bitexl[src[srcpitch*i+1]];\n            hmasks[i+4] = mask;\n          }\n\n          // Extend halo vertically to 8x8 blocks\n          for(i=-4; i<4;  i++) topmask |= hmasks[i+4];\n          for(i=0;  i<8;  i++) cenmask |= hmasks[i+4];\n          for(i=4;  i<12; i++) botmask |= hmasks[i+4];\n          // Check the 3x1.5 cells above\n          for(mask = topmask, i=-4; i<4; i++) {\n            mask |= bitexr[ src[srcpitch*(i+8)-1] ];\n            mask |=    - !! src[srcpitch*(i+8)  ];\n            mask |= bitexl[ src[srcpitch*(i+8)+1] ];\n            hmasks[i+4] |= mask;\n          }\n          for(mask = cenmask, i=0; i<8; i++) {\n            mask |= bitexr[ src[srcpitch*(i+8)-1] ];\n            mask |=    - !! src[srcpitch*(i+8)  ];\n            mask |= bitexl[ src[srcpitch*(i+8)+1] ];\n            hmasks[i+4] |= mask;\n          }\n          for(mask = botmask, i=4; i<12; i++) {\n            mask |= bitexr[ src[srcpitch*(i+8)-1] ];\n            mask |=    - !! src[srcpitch*(i+8)  ];\n            mask |= bitexl[ src[srcpitch*(i+8)+1] ];\n            hmasks[i+4] |= mask;\n          }\n          // Check the 3x1.5 cells below\n          for(mask = botmask, i=11; i>=4; i--) {\n            mask |= bitexr[ src[srcpitch*(i-8)-1] ];\n            mask |=    - !! src[srcpitch*(i-8)  ];\n            mask |= bitexl[ src[srcpitch*(i-8)+1] ];\n            hmasks[i+4] |= mask;\n          }\n          for(mask = cenmask,i=7; i>=0; i--) {\n            mask |= bitexr[ src[srcpitch*(i-8)-1] ];\n            mask |=    - !! src[srcpitch*(i-8)  ];\n            mask |= bitexl[ src[srcpitch*(i-8)+1] ];\n            hmasks[i+4] |= mask;\n          }\n          for(mask = topmask, i=3; i>=-4; i--) {\n            mask |= bitexr[ src[srcpitch*(i-8)-1] ];\n            mask |=    - !! src[srcpitch*(i-8)  ];\n            mask |= bitexl[ src[srcpitch*(i-8)+1] ];\n            hmasks[i+4] |= mask;\n          }\n          // count the halo pixels\n          for(i=0; i<16; i++)\n            alpha2 += bitcnt[hmasks[i]];\n        }\n        else {\n          // How many lit pixels in the centre cell?\n          for(i=0; i<8; i++)\n            alpha1 += bitcnt[src[srcpitch*i]];\n          alpha1 *=2;\n\n          if (alpha1) {\n            // If we have any lit pixels we fully occupy the cell.\n            alpha2 = 128;\n          }\n          else {\n            // No lit pixels here so build the halo mask from the neighbours\n            BYTE cenmask = 0;\n\n            // Check left and right neighbours, extend the halo\n            // mask 8 pixels in from the nearest lit pixels.\n            for(i=0; i<8; i++) {\n              cenmask |= bitexr[src[srcpitch*i-1]];\n              cenmask |= bitexl[src[srcpitch*i+1]];\n            }\n\n            if (cenmask == 0xFF) {\n              // If we have hard adjacent lit pixels we fully occupy this cell.\n              alpha2 = 128;\n            }\n            else {\n              BYTE hmasks[8], mask;\n\n              mask = cenmask;\n#if 1\n              { // PF 161208 speedup test get first two bytes as word\n                int index = srcpitch*(0 + 8);\n                for (int ii = 0; ii < 8; ii++) {\n                  // Check the 3 cells above\n                  const uint16_t ab = *reinterpret_cast<uint16_t *>(src + index - 1);\n                  mask |= bitexr[ab & 0xFF];\n                  mask |= -!!(ab >> 8);\n                  mask |= bitexl[src[index + 1]];\n                  hmasks[ii] = mask;\n                  index += srcpitch;\n                }\n              }\n#else\n              for(i=0; i<8; i++) {\n                // Check the 3 cells above\n                mask |= bitexr[ src[srcpitch*(i+8)-1] ];\n                mask |=    - !! src[srcpitch*(i+8)  ];\n                mask |= bitexl[ src[srcpitch*(i+8)+1] ];\n                hmasks[i] = mask;\n              }\n#endif\n\n              mask = cenmask;\n#if 1\n              { // PF 161208 speedup test get first two bytes as word\n                int index = srcpitch*(7 - 8);\n                for (int ii = 7; ii >= 0; ii--) {\n                  // Check the 3 cells below\n                  const uint16_t ab = *reinterpret_cast<uint16_t *>(src + index - 1);\n                  mask |= bitexr[ab & 0xFF];\n                  mask |= -!!(ab >> 8);\n                  mask |= bitexl[src[index + 1]];\n                  alpha2 += bitcnt[hmasks[ii] | mask];\n                  index -= srcpitch;\n                }\n              }\n#else\n              for (i = 7; i >= 0; i--) {\n                // Check the 3 cells below\n                mask |= bitexr[src[srcpitch*(i - 8) - 1]];\n                mask |= -!!src[srcpitch*(i - 8)];\n                mask |= bitexl[src[srcpitch*(i - 8) + 1]];\n\n                alpha2 += bitcnt[hmasks[i] | mask];\n              }\n            }\n#endif\n              alpha2 *=2;\n            }\n          }\n        }\n\n        if (noaa)\n        {\n          // now many pixels are occupied from the 128\n          constexpr int lit_if_eq_or_morethan = 1; // if at least 1 pixel is lit: draw pixel\n          if (alpha1 >= lit_if_eq_or_morethan) {\n            alpha1 = 64 * 516 * Atext;\n            alpha2 = 0;\n          }\n          else {\n            if (alpha2 > alpha1 && alpha2 >= lit_if_eq_or_morethan) {\n              alpha1 = 0;\n              alpha2 = 64 * 516 * Ahalo;\n            }\n            else {\n              alpha1 = 0;\n              alpha2 = 0;\n            }\n          }\n        }\n        else\n        {\n          alpha2 = gamma[alpha2];\n          alpha1 = gamma[alpha1];\n          alpha2 -= alpha1;\n          alpha2 *= Ahalo;\n          alpha1 *= Atext;\n        }\n\n        // Pre calculate table for quick use  --  Pc = (Pc * dest[0] + dest[c]) >> 8;\n\n    dest[0] = (unsigned short)((64*516*255 - alpha1 -          alpha2)>>15);\n    dest[1] = (unsigned short)((    BVtext * alpha1 + BVhalo * alpha2)>>15);\n    dest[2] = (unsigned short)((    GUtext * alpha1 + GUhalo * alpha2)>>15);\n    dest[3] = (unsigned short)((    RYtext * alpha1 + RYhalo * alpha2)>>15);\n      }\n      else {\n        dest[0] = 256;\n        dest[1] = 0;\n        dest[2] = 0;\n        dest[3] = 0;\n      }\n\n      dest += 4;\n      ++src;\n    } while(--wt);\n  }\n\n  xl=w-xl;\n  xr=w-xr;\n}\n\n#endif // #if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n\n\n\n/*************************************\n *******   Show Frame Number    ******\n ************************************/\n\nShowFrameNumber::ShowFrameNumber(PClip _child, bool _scroll, int _offset, int _x, int _y, const char _fontname[],\n                                 int _size, int _textcolor, int _halocolor, int font_width, int font_angle, \n                                 bool _bold, bool _italic, bool _noaa, IScriptEnvironment* env)\n : GenericVideoFilter(_child),\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  antialiaser(vi.width, vi.height, _fontname, _size,\n    vi.IsYUV() || vi.IsYUVA() ? RGB2YUV_Rec601(_textcolor) : _textcolor,\n    vi.IsYUV() || vi.IsYUVA() ? RGB2YUV_Rec601(_halocolor) : _halocolor,\n    _bold, _italic, _noaa,\n    font_width, font_angle),\n#endif\n  scroll(_scroll), offset(_offset), size(_size), x(_x), y(_y),\n  textcolor(vi.IsYUV() || vi.IsYUVA() ? RGB2YUV_Rec601(_textcolor) : _textcolor),\n  halocolor(vi.IsYUV() || vi.IsYUVA() ? RGB2YUV_Rec601(_halocolor) : _halocolor),\n  bold(_bold), italic(_italic), noaa(_noaa)\n{\n  AVS_UNUSED(env);\n\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n#else\n  // internal font\n  current_font = GetBitmapFont(size, \"Terminus\", bold, false);\n  chromaplacement = ChromaLocation_e::AVS_CHROMA_LEFT;\n  if (current_font == nullptr)\n  {\n    // size\n    current_font = GetBitmapFont(size, \"\", bold, false);\n    if (current_font == nullptr)\n      current_font = GetBitmapFont(size, \"\", !bold, false);\n  }\n#endif\n}\n\nenum { DefXY = (int)0x80000000 };\n\nPVideoFrame ShowFrameNumber::GetFrame(int n, IScriptEnvironment* env) {\n  PVideoFrame frame = child->GetFrame(n, env);\n  n+=offset;\n  if (n < 0) return frame;\n\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  HDC hdc = antialiaser.GetDC();\n  if (!hdc) return frame;\n#else\n  if (current_font == nullptr)\n    return frame;\n#endif\n  env->MakeWritable(&frame);\n\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  RECT r = { 0, 0, 32767, 32767 };\n  FillRect(hdc, &r, (HBRUSH)GetStockObject(BLACK_BRUSH));\n#endif\n  char text[16];\n  snprintf(text, sizeof(text), \"%05d\", n);\n  text[15] = 0;\n  if (x!=DefXY || y!=DefXY) {\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n    SetTextAlign(hdc, TA_BASELINE|TA_LEFT);\n    TextOut(hdc, x+16, y+16, text, (int)strlen(text));\n#else\n    std::string s_utf8 = charToUtf8(text, true);\n    SimpleTextOutW(current_font.get(), vi, frame, x, y, s_utf8, false, textcolor, halocolor, true, 1, chromaplacement);\n#endif\n  } else if (scroll) {\n    int n1 = vi.IsFieldBased() ? (n/2) : n;\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n    int y2 = size + size * (n1 % (vi.height * 8 / size));\n    SetTextAlign(hdc, TA_BASELINE | (child->GetParity(n) ? TA_LEFT : TA_RIGHT));\n    TextOut(hdc, child->GetParity(n) ? 32 : vi.width*8+8, y2, text, (int)strlen(text));\n#else\n    int y2 = size + size * (n1 % (vi.height / size));\n    std::string s_utf8 = charToUtf8(text, true);\n    if(child->GetParity(n))\n      SimpleTextOutW(current_font.get(), vi, frame, 4, y2, s_utf8, false, textcolor, halocolor, true, 1, chromaplacement); // left\n    else\n      SimpleTextOutW(current_font.get(), vi, frame, vi.width - 1, y2, s_utf8, false, textcolor, halocolor, true, 3, chromaplacement); // right\n#endif\n\n  }\n  else {\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n    SetTextAlign(hdc, TA_BASELINE | (child->GetParity(n) ? TA_LEFT : TA_RIGHT));\n    int text_len = (int)strlen(text);\n    for (int y2 = size; y2 < vi.height * 8; y2 += size)\n      TextOut(hdc, child->GetParity(n) ? 32 : vi.width * 8 + 8, y2, text, text_len);\n#else\n    std::string s_utf8 = charToUtf8(text, true);\n    // size-1 because of bottom alignment\n    for (int y2 = size - 1; y2 < vi.height; y2 += size) {\n      if (child->GetParity(n))\n        SimpleTextOutW(current_font.get(), vi, frame, 4, y2, s_utf8, false, textcolor, halocolor, true, 1, chromaplacement); // bottom-left\n      else\n        SimpleTextOutW(current_font.get(), vi, frame, vi.width - 1, y2, s_utf8, false, textcolor, halocolor, true, 3,chromaplacement); // bottom-right\n    }\n#endif\n  }\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  GdiFlush();\n\n  antialiaser.Apply(vi, &frame, frame->GetPitch());\n#endif\n  return frame;\n}\n\n\nAVSValue __cdecl ShowFrameNumber::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  PClip clip = args[0].AsClip();\n  bool scroll = args[1].AsBool(false);\n  const int offset = args[2].AsInt(0);\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  const int x = args[3].IsFloat() ? int(args[3].AsFloat() * 8 + 0.5) : DefXY;\n  const int y = args[4].IsFloat() ? int(args[4].AsFloat() * 8 + 0.5) : DefXY;\n  const char* font = args[5].AsString(\"Arial\");\n  const int size = int(args[6].AsFloat(24)*8+0.5);\n  const int font_width = int(args[9].AsFloat(0) * 8 + 0.5);\n#else\n  const int x = args[3].IsFloat() ? int(args[3].AsFloat() + 0.5) : DefXY;\n  const int y = args[4].IsFloat() ? int(args[4].AsFloat() + 0.5) : DefXY;\n  const char* font = args[5].AsString(\"Terminus\");\n  const int size = int(args[6].AsFloat(24) + 0.5);\n  const int font_width = int(args[9].AsFloat(0) + 0.5);\n#endif\n  const int text_color = args[7].AsInt(0xFFFF00);\n  const int halo_color = args[8].AsInt(0);\n  const int font_angle = int(args[10].AsFloat(0) * 10 + 0.5);\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  const bool bold = args[11].AsBool(true);\n#else\n  const bool bold = args[11].AsBool(false); // intentionally different\n#endif\n  const bool italic = args[12].AsBool(false);\n  const bool noaa = args[13].AsBool(false);\n\n  if ((x==DefXY) ^ (y==DefXY))\n  env->ThrowError(\"ShowFrameNumber: both x and y position must be specified\");\n\n  return new ShowFrameNumber(clip, scroll, offset, x, y, font, size, text_color, halo_color, font_width, font_angle, bold, italic, noaa, env);\n}\n\n\n\n\n\n/*************************************\n *******   Show CRC32 Number    ******\n ************************************/\n\nShowCRC32::ShowCRC32(PClip _child, bool _scroll, int _offset, int _x, int _y, const char _fontname[],\n  int _size, int _textcolor, int _halocolor, int font_width, int font_angle, \n  bool _bold, bool _italic, bool _noaa, IScriptEnvironment* env)\n  : GenericVideoFilter(_child),\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  antialiaser(vi.width, vi.height, _fontname, _size,\n    vi.IsYUV() || vi.IsYUVA() ? RGB2YUV_Rec601(_textcolor) : _textcolor,\n    vi.IsYUV() || vi.IsYUVA() ? RGB2YUV_Rec601(_halocolor) : _halocolor,\n    _bold, _italic, _noaa,\n    font_width, font_angle),\n#endif\n  scroll(_scroll), offset(_offset), size(_size), x(_x), y(_y),\n  textcolor(vi.IsYUV() || vi.IsYUVA() ? RGB2YUV_Rec601(_textcolor) : _textcolor),\n  halocolor(vi.IsYUV() || vi.IsYUVA() ? RGB2YUV_Rec601(_halocolor) : _halocolor),\n  bold(_bold), italic(_italic), noaa(_noaa)\n{\n  AVS_UNUSED(env);\n  \n  build_crc32_table();\n\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n#else\n  // internal font\n  current_font = GetBitmapFont(size, \"Terminus\", bold, false);\n  chromaplacement = ChromaLocation_e::AVS_CHROMA_LEFT;\n  if (current_font == nullptr)\n  {\n    // size\n    current_font = GetBitmapFont(size, \"\", bold, false);\n    if (current_font == nullptr)\n      current_font = GetBitmapFont(size, \"\", !bold, false);\n  }\n#endif\n}\n\nvoid ShowCRC32::build_crc32_table(void) {\n  for (uint32_t i = 0; i < 256; i++) {\n    uint32_t ch = i;\n    uint32_t crc = 0;\n    for (size_t j = 0; j < 8; j++) {\n      uint32_t b = (ch ^ crc) & 1;\n      crc >>= 1;\n      if (b) crc = crc ^ 0xEDB88320;\n      ch >>= 1;\n    }\n    crc32_table[i] = crc;\n  }\n}\n\n\nPVideoFrame ShowCRC32::GetFrame(int n, IScriptEnvironment* env) {\n  PVideoFrame frame = child->GetFrame(n, env);\n  n += offset;\n  if (n < 0) return frame;\n\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  HDC hdc = antialiaser.GetDC();\n  if (!hdc) return frame;\n#else\n  if (current_font == nullptr)\n    return frame;\n#endif\n  env->MakeWritable(&frame);\n\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  RECT r = { 0, 0, 32767, 32767 };\n  FillRect(hdc, &r, (HBRUSH)GetStockObject(BLACK_BRUSH));\n#endif\n\n  auto ptr = frame->GetReadPtr();\n  auto pitch = frame->GetPitch();\n  auto width = frame->GetRowSize();\n  auto height = frame->GetHeight();\n  uint32_t crc = 0xFFFFFFFF;;\n\n  for (int yy = 0; yy < height; yy++) {\n    for (int xx = 0; xx < width; xx++)\n    {\n      uint8_t b = ptr[xx];\n      uint32_t t = (b ^ crc) & 0xFF;\n      crc = (crc >> 8) ^ crc32_table[t];\n    }\n    ptr += pitch;\n  }\n  crc = ~crc;\n\n  char text[16];\n  snprintf(text, sizeof(text), \"%08X\", (int)crc);\n  text[15] = 0;\n\n  if (x != DefXY || y != DefXY) {\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n    SetTextAlign(hdc, TA_BASELINE | TA_LEFT);\n    TextOut(hdc, x + 16, y + 16, text, (int)strlen(text));\n#else\n    std::string s_utf8 = charToUtf8(text, true);\n    SimpleTextOutW(current_font.get(), vi, frame, x, y, s_utf8, false, textcolor, halocolor, true, 1, chromaplacement);\n#endif\n  }\n  else if (scroll) {\n    int n1 = vi.IsFieldBased() ? (n / 2) : n;\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n    int y2 = size + size * (n1 % (vi.height * 8 / size));\n    SetTextAlign(hdc, TA_BASELINE | (child->GetParity(n) ? TA_LEFT : TA_RIGHT));\n    TextOut(hdc, child->GetParity(n) ? 32 : vi.width * 8 + 8, y2, text, (int)strlen(text));\n#else\n    int y2 = size + size * (n1 % (vi.height / size));\n    std::string s_utf8 = charToUtf8(text, true);\n    if (child->GetParity(n))\n      SimpleTextOutW(current_font.get(), vi, frame, 4, y2, s_utf8, false, textcolor, halocolor, true, 1, chromaplacement); // left\n    else\n      SimpleTextOutW(current_font.get(), vi, frame, vi.width - 1, y2, s_utf8, false, textcolor, halocolor, true, 3, chromaplacement); // right\n#endif\n\n  }\n  else {\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n    SetTextAlign(hdc, TA_BASELINE | (child->GetParity(n) ? TA_LEFT : TA_RIGHT));\n    int text_len = (int)strlen(text);\n    for (int y2 = size; y2 < vi.height * 8; y2 += size)\n      TextOut(hdc, child->GetParity(n) ? 32 : vi.width * 8 + 8, y2, text, text_len);\n#else\n    std::string s_utf8 = charToUtf8(text, true);\n    for (int y2 = size; y2 < vi.height; y2 += size) {\n      if (child->GetParity(n))\n        SimpleTextOutW(current_font.get(), vi, frame, 4, y2, s_utf8, false, textcolor, halocolor, true, 1, chromaplacement); // left\n      else\n        SimpleTextOutW(current_font.get(), vi, frame, vi.width - 1, y2, s_utf8, false, textcolor, halocolor, true, 3, chromaplacement); // right\n    }\n#endif\n  }\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  GdiFlush();\n\n  antialiaser.Apply(vi, &frame, frame->GetPitch());\n#endif\n  return frame;\n}\n\n\nAVSValue __cdecl ShowCRC32::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  PClip clip = args[0].AsClip();\n  bool scroll = args[1].AsBool(false);\n  const int offset = args[2].AsInt(0);\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  const int x = args[3].IsFloat() ? int(args[3].AsFloat() * 8 + 0.5) : DefXY;\n  const int y = args[4].IsFloat() ? int(args[4].AsFloat() * 8 + 0.5) : DefXY;\n  const char* font = args[5].AsString(\"Arial\");\n  const int size = int(args[6].AsFloat(24) * 8 + 0.5);\n  const int font_width = int(args[9].AsFloat(0) * 8 + 0.5);\n#else\n  const int x = args[3].IsFloat() ? int(args[3].AsFloat() + 0.5) : DefXY;\n  const int y = args[4].IsFloat() ? int(args[4].AsFloat() + 0.5) : DefXY;\n  const char* font = args[5].AsString(\"Terminus\");\n  const int size = int(args[6].AsFloat(24) + 0.5);\n  const int font_width = int(args[9].AsFloat(0) + 0.5);\n#endif\n  const int text_color = args[7].AsInt(0xFFFF00);\n  const int halo_color = args[8].AsInt(0);\n  const int font_angle = int(args[10].AsFloat(0) * 10 + 0.5);\n\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  const bool bold = args[11].AsBool(true);\n#else\n  const bool bold = args[11].AsBool(false); // intentionally different\n#endif\n  const bool italic = args[12].AsBool(false);\n  const bool noaa = args[13].AsBool(false);\n\n  if ((x == DefXY) ^ (y == DefXY))\n    env->ThrowError(\"ShowCRC32: both x and y position must be specified\");\n\n  return new ShowCRC32(clip, scroll, offset, x, y, font, size, text_color, halo_color, font_width, font_angle, bold, italic, noaa, env);\n}\n\n\n\n\n\n\n\n/***********************************\n *******   Show SMPTE code    ******\n **********************************/\n\nShowSMPTE::ShowSMPTE(PClip _child, double _rate, const char* offset, int _offset_f, int _x, int _y, const char _fontname[],\n                     int _size, int _textcolor, int _halocolor, int font_width, int font_angle, bool _bold, bool _italic, bool _noaa, IScriptEnvironment* env)\n  : GenericVideoFilter(_child),\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  antialiaser(vi.width, vi.height, _fontname, _size,\n      vi.IsYUV() || vi.IsYUVA() ? RGB2YUV_Rec601(_textcolor) : _textcolor,\n      vi.IsYUV() || vi.IsYUVA() ? RGB2YUV_Rec601(_halocolor) : _halocolor,\n      _bold, _italic, _noaa, // bold, italic, noaa; no params atm\n      font_width, font_angle),\n#endif\n  x(_x), y(_y),\n  textcolor(vi.IsYUV() || vi.IsYUVA() ? RGB2YUV_Rec601(_textcolor) : _textcolor),\n  halocolor(vi.IsYUV() || vi.IsYUVA() ? RGB2YUV_Rec601(_halocolor) : _halocolor),\n  bold(_bold), italic(_italic), noaa(_noaa)\n{\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n#else\n  current_font = GetBitmapFont(_size, \"Terminus\", bold, false);\n  if (current_font == nullptr)\n  {\n    // size\n    current_font = GetBitmapFont(_size, \"\", bold, false);\n    if (current_font == nullptr)\n      current_font = GetBitmapFont(_size, \"\", !bold, false);\n  }\n#endif\n  int off_f, off_sec, off_min, off_hour;\n\n  rate = int(_rate + 0.5);\n  dropframe = false;\n  if (_rate > 23.975 && _rate < 23.977) { // Pulldown drop frame rate\n    rate = 24;\n    dropframe = true;\n  }\n  else if (_rate > 29.969 && _rate < 29.971) {\n    rate = 30;\n    dropframe = true;\n  }\n  else if (_rate > 47.951 && _rate < 47.953) {\n    rate = 48;\n    dropframe = true;\n  }\n  else if (_rate > 59.939 && _rate < 59.941) {\n    rate = 60;\n    dropframe = true;\n  }\n  else if (_rate > 119.879 && _rate < 119.881) {\n    rate = 120;\n    dropframe = true;\n  }\n  else if (fabs(_rate - rate) > 0.001) {\n    env->ThrowError(\"ShowSMPTE: rate argument must be 23.976, 29.97 or an integer\");\n  }\n\n  if (offset) {\n  if (strlen(offset)!=11 || offset[2] != ':' || offset[5] != ':' || offset[8] != ':')\n    env->ThrowError(\"ShowSMPTE:  offset should be of the form \\\"00:00:00:00\\\" \");\n  if (!isdigit(offset[0]) || !isdigit(offset[1]) || !isdigit(offset[3]) || !isdigit(offset[4])\n   || !isdigit(offset[6]) || !isdigit(offset[7]) || !isdigit(offset[9]) || !isdigit(offset[10]))\n    env->ThrowError(\"ShowSMPTE:  offset should be of the form \\\"00:00:00:00\\\" \");\n\n  off_hour = atoi(offset);\n\n  off_min = atoi(offset+3);\n  if (off_min > 59)\n    env->ThrowError(\"ShowSMPTE:  make sure that the number of minutes in the offset is in the range 0..59\");\n\n  off_sec = atoi(offset+6);\n  if (off_sec > 59)\n    env->ThrowError(\"ShowSMPTE:  make sure that the number of seconds in the offset is in the range 0..59\");\n\n  off_f = atoi(offset+9);\n  if (off_f >= rate)\n    env->ThrowError(\"ShowSMPTE:  make sure that the number of frames in the offset is in the range 0..%d\", rate-1);\n\n  offset_f = off_f + rate*(off_sec + 60*off_min + 3600*off_hour);\n  if (dropframe) {\n    if (rate == 30) {\n    int c = 0;\n    c = off_min + 60*off_hour;  // number of drop events\n    c -= c/10; // less non-drop events on 10 minutes\n    c *=2; // drop 2 frames per drop event\n    offset_f -= c;\n    }\n    else {\n//  Need to cogitate with the guys about this\n//  gotta drop 86.3 counts per hour. So until\n//  a proper formula is found, just wing it!\n    offset_f -= 2 * ((offset_f+1001)/2002);\n    }\n  }\n  }\n  else {\n  offset_f = _offset_f;\n  }\n}\n\n\nPVideoFrame __stdcall ShowSMPTE::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame frame = child->GetFrame(n, env);\n  n+=offset_f;\n  if (n < 0) return frame;\n\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  HDC hdc = antialiaser.GetDC();\n  if (!hdc) return frame;\n#else\n  if (current_font == nullptr)\n    return frame;\n#endif\n\n  env->MakeWritable(&frame);\n\n  if (dropframe) {\n    if ((rate == 30) || (rate == 60) || (rate == 120)) {\n  // at 10:00, 20:00, 30:00, etc. nothing should happen if offset=0\n    const int f = rate/30;\n    const int r = n % f;\n    n /= f;\n\n    const int high = n / 17982;\n    int low = n % 17982;\n    if (low>=2)\n    low += 2 * ((low-2) / 1798);\n    n = high * 18000 + low;\n\n    n = f*n + r;\n  }\n  else {\n//  Needs some cogitating\n    n += 2 * ((n+1001)/2002);\n  }\n  }\n\n  char text[32];\n\n  if (rate > 0) {\n    int frames = n % rate;\n    int sec = n/rate;\n    int min = sec/60;\n    int hour = sec/3600;\n\n    snprintf(text, sizeof(text),\n              rate>99 ? \"%02d:%02d:%02d:%03d\" : \"%02d:%02d:%02d:%02d\",\n              hour, min%60, sec%60, frames);\n  }\n  else {\n    int ms = (int)(((int64_t)n * vi.fps_denominator * 1000 / vi.fps_numerator)%1000);\n    int sec = (int)((int64_t)n * vi.fps_denominator / vi.fps_numerator);\n    int min = sec/60;\n    int hour = sec/3600;\n\n    snprintf(text, sizeof(text), \"%02d:%02d:%02d.%03d\", hour, min%60, sec%60, ms);\n  }\n  text[15] = 0;\n\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  SetTextAlign(hdc, TA_BASELINE|TA_CENTER);\n  TextOut(hdc, x+16, y+16, text, (int)strlen(text));\n  GdiFlush();\n\n  antialiaser.Apply(vi, &frame, frame->GetPitch());\n#else\n  const bool utf8 = true;\n  auto s_utf8 = charToUtf8(text, utf8);\n  SimpleTextOutW(current_font.get(), vi, frame, x + 2, y + 2, s_utf8, true, textcolor, halocolor, false, 2 /* V baseline H center */, chromaplacement);\n#endif\n\n  return frame;\n}\n\nAVSValue __cdecl ShowSMPTE::CreateSMTPE(AVSValue args, void*, IScriptEnvironment* env)\n{\n  PClip clip = args[0].AsClip();\n  const VideoInfo& arg0vi = args[0].AsClip()->GetVideoInfo();\n  double def_rate = (double)arg0vi.fps_numerator / arg0vi.fps_denominator;\n  double dfrate = args[1].AsDblDef(def_rate);\n  const char* offset = args[2].AsString(0);\n  const int offset_f = args[3].AsInt(0);\n  const int xreal = arg0vi.width/2;\n  const int yreal = arg0vi.height-8;\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  const int x = int(args[4].AsDblDef(xreal)*8+0.5);\n  const int y = int(args[5].AsDblDef(yreal)*8+0.5);\n  const char* font = args[6].AsString(\"Arial\");\n  const int size = int(args[7].AsFloat(24)*8+0.5);\n  const int font_width = int(args[10].AsFloat(0) * 8 + 0.5);\n#else\n  const int x = int(args[4].AsDblDef(xreal) + 0.5);\n  const int y = int(args[5].AsDblDef(yreal) + 0.5);\n  const char* font = args[6].AsString(\"Terminus\");\n  const int size = int(args[7].AsFloat(24) + 0.5);\n  const int font_width = int(args[10].AsFloat(0) + 0.5);\n#endif\n  const int text_color = args[8].AsInt(0xFFFF00);\n  const int halo_color = args[9].AsInt(0);\n  const int font_angle = int(args[11].AsFloat(0)*10+0.5);\n\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  const bool bold = args[12].AsBool(true);\n#else\n  const bool bold = args[12].AsBool(false); // intentionally different\n#endif\n  const bool italic = args[13].AsBool(false);\n  const bool noaa = args[14].AsBool(false);\n\n  return new ShowSMPTE(clip, dfrate, offset, offset_f, x, y, font, size, text_color, halo_color, font_width, font_angle, bold, italic, noaa, env);\n}\n\nAVSValue __cdecl ShowSMPTE::CreateTime(AVSValue args, void*, IScriptEnvironment* env)\n{\n  PClip clip = args[0].AsClip();\n  const int offset_f = args[1].AsInt(0);\n  const int xreal = args[0].AsClip()->GetVideoInfo().width/2;\n  const int yreal = args[0].AsClip()->GetVideoInfo().height-8;\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  const int x = int(args[2].AsDblDef(xreal)*8+0.5);\n  const int y = int(args[3].AsDblDef(yreal)*8+0.5);\n  const char* font = args[4].AsString(\"Arial\");\n  const int size = int(args[5].AsFloat(24)*8+0.5);\n  const int font_width = int(args[8].AsFloat(0) * 8 + 0.5);\n#else\n  const int x = int(args[2].AsDblDef(xreal) + 0.5);\n  const int y = int(args[3].AsDblDef(yreal) + 0.5);\n  const char* font = args[4].AsString(\"Terminus\");\n  const int size = int(args[5].AsFloat(24) + 0.5);\n  const int font_width = int(args[8].AsFloat(0) + 0.5);\n#endif\n  const int text_color = args[6].AsInt(0xFFFF00);\n  const int halo_color = args[7].AsInt(0);\n  const int font_angle = int(args[9].AsFloat(0)*10+0.5);\n\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  const bool bold = args[10].AsBool(true);\n#else\n  const bool bold = args[10].AsBool(false); // intentionally different\n#endif\n  const bool italic = args[11].AsBool(false);\n  const bool noaa = args[12].AsBool(false);\n\n  return new ShowSMPTE(clip, 0.0, NULL, offset_f, x, y, font, size, text_color, halo_color, font_width, font_angle, bold, italic, noaa, env);\n}\n\n\n\n\n\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n\n/***********************************\n *******   Subtitle Filter    ******\n **********************************/\n\nSubtitle::Subtitle( PClip _child, const char _text[], int _x, int _y, int _firstframe,\n                    int _lastframe, const char _fontname[], int _size, int _textcolor,\n                    int _halocolor, int _align, int _spc, bool _multiline, int _lsp,\n                    int _font_width, int _font_angle, bool _interlaced, const char _font_filename[], const bool _utf8, \n                    const bool _bold, const bool _italic, const bool _noaa, IScriptEnvironment* env)\n : GenericVideoFilter(_child),\n  x(_x), y(_y),\n  firstframe(_firstframe), lastframe(_lastframe), size(_size),\n  lsp(_lsp), font_width(_font_width), font_angle(_font_angle), multiline(_multiline), interlaced(_interlaced),\n  textcolor(vi.IsYUV() || vi.IsYUVA() ? RGB2YUV_Rec601(_textcolor) : _textcolor),\n  halocolor(vi.IsYUV() || vi.IsYUVA() ? RGB2YUV_Rec601(_halocolor) : _halocolor),\n  align(_align), spc(_spc),\n  fontname(_fontname), text(_text), font_filename(_font_filename), utf8(_utf8),\n  bold(_bold), italic(_italic), noaa(_noaa),\n  antialiaser(nullptr)\n{\n  if (*font_filename) {\n    int added_font_count = AddFontResourceEx(\n      font_filename, // font file name\n      FR_PRIVATE,    // font characteristics\n      NULL);\n    // If the function succeeds, the return value specifies the number of fonts added.\n    if (added_font_count == 0) {\n      env->ThrowError(\"SubTitle: font %s not found\", font_filename);\n    }\n  }\n}\n\n\n\nSubtitle::~Subtitle(void)\n{\n  delete antialiaser;\n  if (font_filename) {\n    // same as in AddFontResourceEx\n    BOOL b = RemoveFontResourceEx(\n      font_filename, // name of font file\n      FR_PRIVATE,    // font characteristics\n      NULL           // Reserved.\n    );\n    if (!b) {\n      // we can't do anything\n    }\n  }\n}\n\n\n\nPVideoFrame Subtitle::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame frame = child->GetFrame(n, env);\n\n  if (n >= firstframe && n <= lastframe) {\n    env->MakeWritable(&frame);\n    if (!antialiaser) // :FIXME: CriticalSection\n    InitAntialiaser(env);\n    if (antialiaser) {\n    antialiaser->Apply(vi, &frame, frame->GetPitch());\n    // Release all the windows drawing stuff\n    // and just keep the alpha calcs\n    antialiaser->FreeDC();\n  }\n  }\n  // if we get far enough away from the frames we're supposed to\n  // subtitle, then junk the buffered drawing information\n  if (antialiaser && (n < firstframe-10 || n > lastframe+10 || n == vi.num_frames-1)) {\n  delete antialiaser;\n  antialiaser = 0; // :FIXME: CriticalSection\n  }\n\n  return frame;\n}\n\nAVSValue __cdecl Subtitle::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n    PClip clip = args[0].AsClip();\n    const char* text = args[1].AsString();\n    const int first_frame = args[4].AsInt(0);\n    const int last_frame = args[5].AsInt(clip->GetVideoInfo().num_frames-1);\n    const char* font = args[6].AsString(\"Arial\");\n    const int size = int(args[7].AsFloat(18)*8+0.5);\n    const int text_color = args[8].AsInt(0xFFFF00);\n    const int halo_color = args[9].AsInt(0);\n    const int align = args[10].AsInt(args[2].AsFloat(0)==-1?2:7);\n    const int spc = args[11].AsInt(0);\n    const bool multiline = args[12].Defined();\n    const int lsp = args[12].AsInt(0);\n    const int font_width = int(args[13].AsFloat(0)*8+0.5);\n    const int font_angle = int(args[14].AsFloat(0)*10+0.5);\n    const bool interlaced = args[15].AsBool(false);\n    const char* font_filename = args[16].AsString(\"\");\n    const bool utf8 = args[17].AsBool(false);\n    const bool bold = args[18].AsBool(true);\n    const bool italic = args[19].AsBool(false);\n    const bool noaa = args[20].AsBool(false);\n\n    if ((align < 1) || (align > 9))\n     env->ThrowError(\"Subtitle: Align values are 1 - 9 mapped to your numeric pad\");\n\n    const int subtitle_default_x = 8;\n\n    int defx, defy;\n    bool x_center = false;\n    bool y_center = false;\n\n    switch (align) {\n    case 1: case 4: case 7: defx = subtitle_default_x; break;\n    case 2: case 5: case 8:\n      defx = 0; // n/a if not set later\n      x_center = true;\n      break;\n    case 3: case 6: case 9: defx = clip->GetVideoInfo().width - subtitle_default_x; break;\n    default: defx = subtitle_default_x; break;\n    }\n\n    switch (align) {\n    case 1: case 2: case 3: defy = clip->GetVideoInfo().height - 2; break; // bottom alignment 2 pixel above\n    case 4: case 5: case 6:\n      defy = 0; // n/a if not set later\n      y_center = true;\n      break;\n    case 7: case 8: case 9: defy = 0; break;\n    default: defy = (size + 4) / 8; break;\n    }\n\n    const bool isXdefined = args[2].Defined();\n    const bool isYdefined = args[3].Defined();\n\n    int x = int(args[2].AsDblDef(defx)*8+0.5);\n    int y = int(args[3].AsDblDef(defy)*8+0.5);\n\n    if (!isXdefined && x_center)\n      x = (clip->GetVideoInfo().width >> 1) * 8;\n\n    if (!isYdefined && y_center)\n      y = (clip->GetVideoInfo().height >> 1) * 8;\n\n    return new Subtitle(clip, text, x, y, first_frame, last_frame, font, size, text_color,\n                      halo_color, align, spc, multiline, lsp, font_width, font_angle, interlaced, font_filename, utf8, \n                      bold, italic, noaa, env);\n}\n\n// multiline separator: string contains '\\' and 'n' characters explicitely\n// SubTitle compatibility: literal \"\\n\" means line break, but \"\\\\n\" means that literal \"\\n\" will be printed\n// Since 3.7.4 the C style LF '\\n' or CR LF ('\\r' and '\\n') always results in new line\nstatic std::vector<std::string> SplitLines(const char* text, bool multiline_by_param) {\n  std::string s = text;\n  std::vector<std::string> lines;\n  size_t start = 0;\n  size_t length = s.length();\n\n  for (size_t i = 0; i < length; ++i) {\n\n    if (multiline_by_param && s[i] == '\\\\') {\n      if (i + 1 < length && s[i + 1] == 'n') {\n        if (i > 0 && s[i - 1] == '\\\\') {\n          // \"\\\\n\" case: keep as literal \"\\n\"\n          i++;\n        }\n        else {\n          // \"\\n\" case: split the line\n          lines.push_back(s.substr(start, i - start));\n          start = i + 2;\n          i++;\n        }\n      }\n    }\n    else if (s[i] == '\\n') {\n      // Usual line feed '\\n' case: split the line\n      lines.push_back(s.substr(start, i - start));\n      start = i + 1;\n    }\n    else if (s[i] == '\\r' && i + 1 < length && s[i + 1] == '\\n') {\n      // Windows-style CR LF case: split the line\n      lines.push_back(s.substr(start, i - start));\n      start = i + 2;\n      i++;\n    }\n  }\n\n  // Add the last line if it's not empty\n  if (start < length) {\n    lines.push_back(s.substr(start));\n  }\n\n  return lines;\n}\n\nstatic int CorrectYbyTextAndAlignment(int real_y, int align, int fontsize, int lsp, size_t line_count)\n{\n  // note: we do not really have a vertical center alignment for multiline strings since it means not centering.\n  // TA_BASELINE is aligning (x,y) to the character's baseline: letters like g, y and q would reach below that baseline)\n\n  // when multiline, bottom and vertically centered cases affect starting y\n  if (align == 1 || align == 2 || align == 3) // bottom\n    real_y -= (fontsize + lsp) * ((int)line_count - 1);\n  else if (align == 4 || align == 5 || align == 6)\n    real_y -= ((fontsize + lsp) * ((int)line_count - 1) + 1) / 2;\n  return real_y;\n}\n\nvoid Subtitle::InitAntialiaser(IScriptEnvironment* env)\n{\n  antialiaser = new Antialiaser(vi.width, vi.height, fontname, size, textcolor, halocolor, bold, italic, noaa,\n                                font_width, font_angle, interlaced);\n\n  int real_x = x;\n  int real_y = y;\n  unsigned int al = 0;\n  std::vector<std::string> lines;\n\n  HDC hdcAntialias = antialiaser->GetDC();\n  if (!hdcAntialias) goto GDIError;\n\n  switch (align) // This spec where [X, Y] is relative to the text (inverted logic)\n  { case 1: al = TA_BOTTOM   | TA_LEFT; break;\t\t// .----\n    case 2: al = TA_BOTTOM   | TA_CENTER; break;\t// --.--\n    case 3: al = TA_BOTTOM   | TA_RIGHT; break;\t\t// ----.\n    case 4: al = TA_BASELINE | TA_LEFT; break;\t\t// .____\n    case 5: al = TA_BASELINE | TA_CENTER; break;\t// __.__\n    case 6: al = TA_BASELINE | TA_RIGHT; break;\t\t// ____.\n    case 7: al = TA_TOP      | TA_LEFT; break;\t\t// `----\n    case 8: al = TA_TOP      | TA_CENTER; break;\t// --`--\n    case 9: al = TA_TOP      | TA_RIGHT; break;\t\t// ----`\n    default: al= TA_BASELINE | TA_LEFT; break;\t\t// .____\n  }\n  if (SetTextCharacterExtra(hdcAntialias, spc) == 0x80000000) goto GDIError;\n  if (SetTextAlign(hdcAntialias, al) == GDI_ERROR) goto GDIError;\n\n  // multiline is filter parameter, true when lsp is given.\n  // 3.7.4 real LF or CR LF breaks line unconditionally.\n  lines = SplitLines(text, multiline);\n  if (lines.size() == 0) return;\n  real_y = CorrectYbyTextAndAlignment(real_y, align, size, lsp, lines.size()); // find literal \\ n for LF, not real LF 0x0A\n\n  if (utf8) {\n    // Test:\n    // Title=\"Cherry blossom \"+CHR($E6)+CHR($A1)+CHR($9C)+CHR($E3)+CHR($81)+CHR($AE)+CHR($E8)+CHR($8A)+CHR($B1)\n    // SubTitle(Title, utf8 = true)\n    int y_inc = real_y + 16;\n    for(auto s : lines) {\n      auto textw = Utf8ToWideChar(s.c_str());\n      if (!TextOutW(hdcAntialias, real_x + 16, y_inc, textw.get(), (int)wcslen(textw.get())))\n        goto GDIError;\n      y_inc += size + lsp;\n    }\n\n  }\n  else {\n    int y_inc = real_y + 16;\n    for (auto s : lines) {\n      if (!TextOut(hdcAntialias, real_x + 16, y_inc, s.c_str(), (int)s.length()))\n        goto GDIError;\n      y_inc += size + lsp;\n    }\n  }\n  if (!GdiFlush()) goto GDIError;\n  return;\n\nGDIError:\n  delete antialiaser;\n  antialiaser = 0;\n\n  env->ThrowError(\"Subtitle: GDI or Insufficient Memory Error\");\n}\n\n\n\n#endif\n\nstatic int CalcFontSizeForInfo(int w, int h, bool autolarge, int upper_limit)\n{\n  // if frame is smaller than minimum then font size will be decreased proportionally\n  // normalized to 640x480 @fontsize=15:\n  // 14 lines @height=15 takes ~480/2 pixels (half vertical screens)\n  // Info screen takes horizontally ~0.6 * 640 pixels at font size 15\n\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  const int min_font_size = 1;\n  const int max_font_size = 255; // n/a\n  const int reference_font_size = 15;\n  const int reference_font_width = 8;\n#else\n  const int min_font_size = 12;\n  const int max_font_size = 32;\n  const int reference_font_size = 18; // 16x8 or 18x10, latter is more visible\n  const int reference_font_width = 10;\n#endif\n  // knowing that a usual Info() is 45x15 characters, plus a margin\n  const int reference_min_height = 15 * reference_font_size;\n  const int reference_min_width = 48 * reference_font_width; // (45 + margin) characters\n\n  // 0..reference_min_width      :decrease (as always in Avs)\n  // reference_min_width ... 640 : constant size\n  // 640+                        : enlarge when autolarge is enabled or else constant size\n\n  int w_restricted_font_size;\n  if (w < reference_min_width)\n    w_restricted_font_size = (reference_font_size * w) / reference_min_width;\n  else if (w >= 640 && autolarge)\n    w_restricted_font_size = reference_font_size * w / 640;\n  else\n    w_restricted_font_size = reference_font_size;\n\n  int h_restricted_font_size;\n  if (h < reference_min_height)\n    h_restricted_font_size = (reference_font_size * h) / reference_min_height;\n  else if (h >= 480 && autolarge)\n    h_restricted_font_size = reference_font_size * h / 480;\n  else\n    h_restricted_font_size = reference_font_size;\n\n  int effective_font_size = (w_restricted_font_size < h_restricted_font_size) ? w_restricted_font_size : h_restricted_font_size;\n\n  effective_font_size = std::max(effective_font_size, min_font_size);\n  if (upper_limit > 0)\n    effective_font_size = std::min(effective_font_size, max_font_size);\n\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  return effective_font_size * 8; // GDI takes *8\n#else\n  return effective_font_size / 2 * 2; // no odd sized fixed fonts atm.\n#endif\n\n}\n\n/***********************************\n *******   SimpleText Filter   *****\n ***********************************/\n\nSimpleText::SimpleText(PClip _child, const char _text[], int _x, int _y, int _firstframe,\n  int _lastframe, const char _fontname[], int _size, int _textcolor,\n  int _halocolor, int _align, int _spc, bool _multiline, int _lsp,\n  int _font_width, int _font_angle, bool _interlaced, const char _font_filename[],\n  const bool _utf8, const bool _bold, const int _chromalocation,\n  IScriptEnvironment* env)\n  : GenericVideoFilter(_child),\n  x(_x), y(_y),\n  firstframe(_firstframe), lastframe(_lastframe), size(_size), lsp(_lsp),\n  multiline(_multiline),\n  textcolor(vi.IsYUV() || vi.IsYUVA() ? RGB2YUV_Rec601(_textcolor) : _textcolor),\n  halocolor(vi.IsYUV() || vi.IsYUVA() ? RGB2YUV_Rec601(_halocolor) : _halocolor), // not supported\n  align(_align),\n  halocolor_orig(_halocolor),\n  fontname(_fontname),\n  text(_text),\n  // spc(_spc), font_width(_font_width), font_angle(_font_angle), interlaced(_interlaced),\n  font_filename(_font_filename), utf8(_utf8),\n  bold(_bold),\n  chromalocation(_chromalocation)\n{\n\n  if (*font_filename) {\n    // external font file\n    bool debugSave = size < 0;\n    current_font = GetBitmapFont(0, font_filename, false, debugSave); // 0: size n/a\n    if (current_font == nullptr)\n      env->ThrowError(\"SimpleText: file %s not found or unknown file format\", font_filename);\n  }\n  else\n  {\n    // internal font\n    if (fontname) {\n      current_font = GetBitmapFont(size, fontname, bold, false); // 12, \"Terminus\"\n      if (current_font == nullptr)\n        env->ThrowError(\"SimpleText: internal font name %s in size %d not found\", fontname, size);\n    }\n    else {\n      // size\n      current_font = GetBitmapFont(size, \"\", bold, false); // 12, \"\"\n      if (current_font == nullptr)\n        env->ThrowError(\"SimpleText: fixed font size %d not found\", size);\n    }\n  }\n}\n\n\n\nSimpleText::~SimpleText(void)\n{\n  // nothing here yet\n}\n\n\nPVideoFrame SimpleText::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame frame = child->GetFrame(n, env);\n\n  if (n >= firstframe && n <= lastframe) {\n    env->MakeWritable(&frame);\n\n    int real_x = x;\n    int real_y = y;\n\n    // Test:\n    // Title=\"Cherry blossom \"+CHR($E6)+CHR($A1)+CHR($9C)+CHR($E3)+CHR($81)+CHR($AE)+CHR($E8)+CHR($8A)+CHR($B1)\n    std::string s(text);\n\n    if (multiline) { // filter parameter, true when lsp is given\n      // multiline case: string contains '\\' and 'n' characters explicitely\n      // SubTitle compatibility: literal \"\\n\" means line break, but \"\\\\n\" means that literal \"\\n\" will be printed\n      // Thus we replace two-character literal \"\\n\" to \\n (0x0A) then when \"\\\" and \\n found, we change it back to literal \"\\n\"\n      size_t index = 0;\n      while (true) {\n        index = s.find(\"\\\\n\", index);\n        if (index == std::string::npos) break;\n        s.replace(index, 1, \"\\n\");\n        s.erase(index + 1, 1); // two characters replaced by a single one, erase at the second position\n        index += 1; // length of the string to replace\n      }\n      // '\\' and '\\n' back to literal \"\\n\"\n      index = 0;\n      while (true) {\n        index = s.find(\"\\\\\\n\", index); // yes, \\ and \\n\n        if (index == std::string::npos) break;\n        s.replace(index, 2, \"\\\\n\"); // back to \"\\\" + \"n\"\n        index += 2; // length of the string to replace\n      }\n    }\n\n    std::string s_utf8 = charToUtf8(s.c_str(), utf8); // to wchar_t either from utf8 (win/linux) or ansi (win)\n\n    // halocolor MSB\n    // FF: fadeIt, no halo\n    // FE: fadeIt, use halocolor\n    // 01-FD: no halo\n    // 00: use halocolor\n    int halocolor_msb = (halocolor_orig & 0xFF000000) >> 24;\n    SimpleTextOutW_multi(current_font.get(), vi, frame, real_x, real_y, s_utf8,\n      halocolor_msb == 0xFF || halocolor_msb == 0xFE, // fadeIt, special halocolor, when MSB byte is FF or FE\n      textcolor, halocolor,\n      halocolor_msb == 0x00 || halocolor_msb == 0xFE, // use halocolor when MSB byte is 00 or FE\n      align, lsp, chromalocation);\n  }\n\n  return frame;\n}\n\nAVSValue __cdecl SimpleText::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  PClip clip = args[0].AsClip();\n  VideoInfo vi = clip->GetVideoInfo();\n\n  const char* text = args[1].AsString();\n  const int first_frame = args[4].AsInt(0);\n  const int last_frame = args[5].AsInt(vi.num_frames - 1);\n  const char* font = args[6].AsString(\"Terminus\"); // Terminus, info_h are embedded\n  const int size = int(args[7].AsFloat(18)); // height 12, 14, 16, 18, 20, 24, 28, 32\n  const int text_color = args[8].AsInt(0xFFFF00);\n  const int halo_color = args[9].AsInt(0);\n  // Warning: if x=-1 passed + no align specified: sets bottom center alignment.\n  // This is why: SubTitle definition: Can be set to -1 to automatically center the text horizontally or vertically, respectively. \n  // Negative values of x and y not equal to -1 can be used to move subtitles partially off the screen.\n  // Contrary to the documentation, y=-1 is not checked at all\n  const int align = args[10].AsInt(args[2].AsFloat(0) == -1 ? 2 : 7);\n  const int spc = args[11].AsInt(0);\n  const bool multiline = args[12].Defined();\n  const int lsp = args[12].AsInt(0); // line spacing if multiline\n  const int font_width = int(args[13].AsFloat(0) * 8 + 0.5); // n/a\n  const int font_angle = int(args[14].AsFloat(0) * 10 + 0.5); // n/a\n  const bool interlaced = args[15].AsBool(false); // n/a\n  const char* font_filename = args[16].AsString(\"\");\n  const bool utf8 = args[17].AsBool(false); // linux: n/a\n  const bool bold = args[18].AsBool(false); // valid SubTitle parameter since v3.7.3\n  [[maybe_unused]] const bool italic = args[19].AsBool(false); // valid SubTitle parameter since v3.7.3, but in \"Text\" not implemented\n  [[maybe_unused]] const bool noaa = args[20].AsBool(false); // valid SubTitle parameter since v3.7.3, but in \"Text\" not implemented\n  // \"placement\" as chroma location, only \"Text\"\n  const char* placement_name = args.ArraySize() >= 23 ? args[22].AsString(nullptr) : nullptr; // different from SubTitle, guard array access of extra parameter\n\n  // parameters marked with n/a are ignored; parameter list is currently the same as SubTitle\n\n  if ((align < 1) || (align > 9))\n    env->ThrowError(\"SimpleText: Align values are 1 - 9 mapped to your numeric pad\");\n\n  int defx, defy;\n  bool x_center = false;\n  bool y_center = false;\n\n  switch (align) {\n  case 1: case 4: case 7: defx = 8; break;\n  case 2: case 5: case 8:\n    defx = 0; // n/a if not set later\n    x_center = true;\n    break;\n  case 3: case 6: case 9: defx = clip->GetVideoInfo().width - 8; break;\n  default: defx = 8; break;\n  }\n  switch (align) {\n  case 1: case 2: case 3: defy = clip->GetVideoInfo().height - 2; break;\n  case 4: case 5: case 6:\n    defy = 0; // n/a if not set later\n    y_center = true;\n    break;\n  case 7: case 8: case 9: defy = 0; break;\n  default: defy = /*(size + 4) / 8;*/ (size + 1) / 2; break; // no mul 8\n  }\n\n  const bool isXdefined = args[2].Defined();\n  const bool isYdefined = args[3].Defined();\n  // prevent turning exactly given x or y == -1 into 0, use lround instead of int cast. int(-1 + 0.5) --> 0 :(\n  const int x = std::lround(args[2].AsDblDef(defx));\n  const int y = std::lround(args[3].AsDblDef(defy));\n\n  int real_x = x;\n  int real_y = y;\n\n  // center check\n  if (!isXdefined && x_center)\n    real_x = (clip->GetVideoInfo().width >> 1) /* * 8 */; // no mul 8 like in SubTitle\n\n  if (!isYdefined && y_center)\n    real_y = (clip->GetVideoInfo().height >> 1) /* * 8 */; // no mul 8 like in SubTitle\n\n  // anyway, we accept any chroma location here.\n  // \"Text\" filter will ignore invalid/not used definitions and use its defaults\n  int ChromaLocation_In = -1; // invalid\n\n  if (vi.IsYV411()) {\n    // placement parameter exists, (default none/-1) + input frame properties; 'left'-ish _ChromaLocation is allowed, checked later\n    auto frame0 = clip->GetFrame(0, env);\n    const AVSMap* props = env->getFramePropsRO(frame0);\n    chromaloc_parse_merge_with_props(vi, placement_name, props, /* ref*/ChromaLocation_In, -1 /*default none chromaloc */, env);\n  }\n  else if (vi.Is420() || vi.Is422() || vi.IsYUY2()) {\n    // placement parameter is valid + input frame properties\n    auto frame0 = clip->GetFrame(0, env);\n    const AVSMap* props = env->getFramePropsRO(frame0);\n    chromaloc_parse_merge_with_props(vi, placement_name, props, /* ref*/ChromaLocation_In, ChromaLocation_e::AVS_CHROMA_LEFT /*default*/, env);\n  }\n\n  return new SimpleText(clip, text, real_x, real_y, first_frame, last_frame, font, size, text_color,\n    halo_color, align, spc, multiline, lsp, font_width, font_angle, interlaced, font_filename, utf8, bold, ChromaLocation_In, env);\n}\n\n\n\n/***********************************\n *******   FilterInfo Filter    ******\n **********************************/\n\nFilterInfo::FilterInfo( PClip _child, const char _fontname[], int _size, int _textcolor, int _halocolor, bool _bold, bool _italic, bool _noaa, \n  bool _cpu, int _x, int _y, int _align, IScriptEnvironment* env)\n  : GenericVideoFilter(_child), vii(AdjustVi()), size(_size),\n  text_color(vi.IsYUV() || vi.IsYUVA() ? RGB2YUV_Rec601(_textcolor) : _textcolor),\n  halo_color(vi.IsYUV() || vi.IsYUVA() ? RGB2YUV_Rec601(_halocolor) : _halocolor)\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  ,antialiaser(vi.width, vi.height, _fontname, size,\n    vi.IsYUV() || vi.IsYUVA() ? RGB2YUV_Rec601(_textcolor) : _textcolor,\n    vi.IsYUV() || vi.IsYUVA() ? RGB2YUV_Rec601(_halocolor) : _halocolor,\n    _bold, _italic, _noaa)\n#endif\n  , bold(_bold), italic(_italic), noaa(_noaa),\n  cpu(_cpu), x(_x), y(_y), align(_align)\n{\n  AVS_UNUSED(env);\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n#else\n  // internal font\n  chromaplacement = ChromaLocation_e::AVS_CHROMA_LEFT;\n  current_font = GetBitmapFont(size, \"Terminus\", bold, false);\n  if (current_font == nullptr)\n  {\n    current_font = GetBitmapFont(size, \"\", bold, false);\n    if (current_font == nullptr)\n      current_font = GetBitmapFont(size, \"\", !bold, false);\n  }\n#endif\n\n}\n\n\nFilterInfo::~FilterInfo(void)\n{\n}\n\n\nconst VideoInfo& FilterInfo::AdjustVi()\n{\n  if ( !vi.HasVideo() ) {\n    vi.fps_denominator=1;\n    vi.fps_numerator=24;\n    vi.height=480;\n    vi.num_frames=240;\n    vi.pixel_type=VideoInfo::CS_BGR32;\n    vi.width=640;\n    vi.SetFieldBased(false);\n  }\n  return child->GetVideoInfo();\n}\n\n\nconst char* const t_INT8=\"Integer 8 bit\";\nconst char* const t_INT16=\"Integer 16 bit\";\nconst char* const t_INT24=\"Integer 24 bit\";\nconst char* const t_INT32=\"Integer 32 bit\";\nconst char* const t_FLOAT32=\"Float 32 bit\";\nconst char* const t_YES=\"YES\";\nconst char* const t_NO=\"NO\";\nconst char* const t_NONE=\"NONE\";\nconst char* const t_TFF =\"Top Field First            \";\nconst char* const t_BFF =\"Bottom Field First         \";\nconst char* const t_ATFF=\"Assumed Top Field First    \";\nconst char* const t_ABFF=\"Assumed Bottom Field First \";\nconst char* const t_STFF=\"Top Field (Separated)      \";\nconst char* const t_SBFF=\"Bottom Field (Separated)   \";\n\nstatic std::string GetCacheInfo(IScriptEnvironment* env)\n{\n  std::stringstream ss;\n  size_t l2_cache_size = env->GetEnvProperty(AEP_CACHESIZE_L2);\n  if (l2_cache_size > 0)\n    ss << \"L2 Cache Size: \" << l2_cache_size << \" bytes\";\n  return ss.str();\n}\n\n#ifdef INTEL_INTRINSICS\nstd::string GetCpuMsg(IScriptEnvironment * env, bool avx512)\n{\n  int64_t flags = env->GetCPUFlagsEx();\n  std::stringstream ss;\n\n  if (!avx512) {\n#ifndef _M_X64\n    // don't display old capabilities when at least AVX is used\n    if (!(flags & CPUF_AVX)) {\n    //if (flags & CPUF_FPU)\n    //  ss << \"x87 \";\n      if (flags & CPUF_MMX)\n        ss << \"MMX \";\n      if (flags & CPUF_INTEGER_SSE)\n        ss << \"ISSE \";\n\n      if (flags & CPUF_3DNOW_EXT)\n        ss << \"3DNOW_EXT\";\n      else if (flags & CPUF_3DNOW)\n        ss << \"3DNOW \";\n    }\n\n    if (flags & CPUF_SSE)\n      ss << \"SSE \";\n#endif\n    if (flags & CPUF_SSE2)\n      ss << \"SSE2 \";\n    if (flags & CPUF_SSE3)\n      ss << \"SSE3 \";\n    if (flags & CPUF_SSSE3)\n      ss << \"SSSE3 \";\n    if (flags & CPUF_SSE4_1)\n      ss << \"SSE4.1 \";\n    if (flags & CPUF_SSE4_2)\n      ss << \"SSE4.2 \";\n\n    if (flags & CPUF_AVX)\n      ss << \"AVX \";\n    if (flags & CPUF_AVX2)\n      ss << \"AVX2 \";\n    if (flags & CPUF_FMA3)\n      ss << \"FMA3 \";\n    if (flags & CPUF_FMA4)\n      ss << \"FMA4 \";\n    if (flags & CPUF_F16C)\n      ss << \"F16C \";\n  }\n  else {\n\n    if (flags & CPUF_AVX512_MASK)\n      ss << \"AVX512 \";\n    // Core AVX-512 Extensions as a distinct flag (F, CD, BW, DQ, VL)\n    if (flags & CPUF_AVX512_BASE)\n      ss << \"BASE (\";\n\n    // Base part (F, CD, BW, DQ, VL)\n    if (flags & CPUF_AVX512F) ss << \"F \";\n    if (flags & CPUF_AVX512CD) ss << \"CD \";\n    if (flags & CPUF_AVX512BW) ss << \"BW \";\n    if (flags & CPUF_AVX512DQ) ss << \"DQ \";\n    if (flags & CPUF_AVX512VL) {\n      if (flags & CPUF_AVX512_BASE)\n        ss << \"VL) \";\n      else\n        ss << \"VL \";\n    }\n\n    // ICL part as a distinct flag:\n    if (flags & CPUF_AVX512_FAST) // Ice Lake/Rocket Lake extensions; usable avx-512\n      ss << \"FAST (\";\n    if (flags & CPUF_AVX512VNNI) ss << \"VNNI \";\n    if (flags & CPUF_AVX512VBMI) ss << \"VBMI \";\n    if (flags & CPUF_AVX512VBMI2) ss << \"VBMI2 \";\n    if (flags & CPUF_AVX512BITALG) ss << \"BITALG \";\n    if (flags & CPUF_AVX512VPOPCNTDQ) {\n      if (flags & CPUF_AVX512_FAST)\n        ss << \"VPOPCNTDQ) \";\n      else\n        ss << \"VPOPCNTDQ \";\n    }\n\n    // rest of AVX-512 extensions:\n    if (flags & CPUF_AVX512IFMA) ss << \"IFMA \";\n    if (flags & CPUF_AVX512BF16) ss << \"BF16 \";\n    if (flags & CPUF_AVX512FP16) ss << \"FP16 \";\n    if (flags & CPUF_AVX512PF) ss << \"PF \";\n    if (flags & CPUF_AVX512ER) ss << \"ER \";\n\n    // Crypto (VAES, VPCLMULQDQ, GFNI) and deprecated (VP2INTERSECT, 4VNNIW, 4FMAPS) extensions excluded\n  }\n  return ss.str();\n}\n#elif defined(ARM64)\n// aarch64 ARMv8-A flags\nstd::string GetCpuMsg(IScriptEnvironment* env)\n{\n  int64_t flags = env->GetCPUFlagsEx();\n  std::stringstream ss;\n\n  // Tier 1: CPUF_ARM_NEON (Baseline)\n  if (flags & CPUF_ARM_NEON)\n    ss << \"NEON \";\n\n  if (flags & CPUF_ARM_DOTPROD)\n    ss << \"DOTPROD \";\n\n  if (flags & CPUF_ARM_I8MM)\n    ss << \"I8MM \";\n\n  if (flags & CPUF_ARM_SVE2)\n    ss << \"SVE2 \";\n\n  if (flags & CPUF_ARM_SVE2_1)\n    ss << \"SVE2.1 \";\n\n  return ss.str();\n}\n#else\nstd::string GetCpuMsg(IScriptEnvironment * env)\n{\n  std::stringstream ss;\n\n  return ss.str();\n}\n#endif\n\nbool FilterInfo::GetParity(int n)\n{\n  return vii.HasVideo() ? child->GetParity(n) : false;\n}\n\n\nPVideoFrame FilterInfo::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame frame = vii.HasVideo() ? child->GetFrame(n, env) : env->NewVideoFrame(vi);\n\n  if ( !vii.HasVideo() ) {\n    memset(frame->GetWritePtr(), 0, frame->GetPitch()*frame->GetHeight()); // Blank frame\n  }\n\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  HDC hdcAntialias = antialiaser.GetDC();\n  if (!hdcAntialias)\n    return frame;\n#else\n  if (current_font == nullptr)\n    return frame;\n#endif\n    const char* c_space = \"Unknown\";\n    const char* s_type = t_NONE;\n    const char* s_parity;\n    char text[1024];\n    int tlen;\n    std::string chn_layout_str;\n\n    if (vii.HasVideo()) {\n      c_space = GetPixelTypeName(vii.pixel_type);\n      if (*c_space == '\\0')\n        c_space = \"Unknown\";\n      if (vii.IsFieldBased()) {\n        if (child->GetParity(n)) {\n          s_parity = t_STFF;\n        }\n        else {\n          s_parity = t_SBFF;\n        }\n      }\n      else {\n        if (child->GetParity(n)) {\n          s_parity = vii.IsTFF() ? t_ATFF : t_TFF;\n        }\n        else {\n          s_parity = vii.IsBFF() ? t_ABFF : t_BFF;\n        }\n      }\n      uint64_t vLenInMsecs = (uint64_t)(1000.0 * (double)vii.num_frames * (double)vii.fps_denominator / (double)vii.fps_numerator);\n      uint64_t cPosInMsecs = (uint64_t)(1000.0 * (double)n * (double)vii.fps_denominator / (double)vii.fps_numerator);\n\n      tlen = snprintf(text, sizeof(text),\n        \"Frame: %8u of %-8u\\n\"                                //  28\n        \"Time: %02\" PRIu64 \":%02d:%02d.%03d of %02\" PRIu64 \":%02d:%02d.%03d\\n\"  //  35\n        \"ColorSpace: %s, BitsPerComponent: %u\\n\"              //  18=13+5\n//        \"Bits per component: %2u\\n\"                           //  22\n        \"Width:%4u pixels, Height:%4u pixels\\n\"              //  39\n        \"Frames per second: %7.4f (%u/%u)\\n\"                  //  51=31+20\n        \"FieldBased (Separated) Video: %s\\n\"                  //  35=32+3\n        \"Parity: %s\\n\"                                        //  35=9+26\n        \"Video Pitch: %5u bytes.\\n\"                           //  25\n        \"Has Audio: %s\\n\"                                     //  15=12+3\n//        \"123456789012345678901234567890123456789012345678901234567890\\n\"         // test\n, n, vii.num_frames\n, (cPosInMsecs / (60 * 60 * 1000)), (int)((cPosInMsecs / (60 * 1000)) % 60), (int)((cPosInMsecs / 1000) % 60), (int)(cPosInMsecs % 1000),\n(vLenInMsecs / (60 * 60 * 1000)), (int)((vLenInMsecs / (60 * 1000)) % 60), (int)((vLenInMsecs / 1000) % 60), (int)(vLenInMsecs % 1000)\n, c_space\n, vii.BitsPerComponent()\n, vii.width, vii.height\n, (float)vii.fps_numerator / (float)vii.fps_denominator, vii.fps_numerator, vii.fps_denominator\n, vii.IsFieldBased() ? t_YES : t_NO\n, s_parity\n, frame->GetPitch()\n, vii.HasAudio() ? t_YES : t_NO\n);\n    }\n    else {\n      tlen = snprintf(text, sizeof(text),\n        \"Frame: %8u of %-8u\\n\"\n        \"Has Video: NO\\n\"\n        \"Has Audio: %s\\n\"\n        , n, vi.num_frames\n        , vii.HasAudio() ? t_YES : t_NO\n      );\n    }\n    if (vii.HasAudio()) {\n      if (vii.SampleType() == SAMPLE_INT8)  s_type = t_INT8;\n      else if (vii.SampleType() == SAMPLE_INT16) s_type = t_INT16;\n      else if (vii.SampleType() == SAMPLE_INT24) s_type = t_INT24;\n      else if (vii.SampleType() == SAMPLE_INT32) s_type = t_INT32;\n      else if (vii.SampleType() == SAMPLE_FLOAT) s_type = t_FLOAT32;\n\n      uint64_t aLenInMsecs = static_cast<uint64_t>(1000.0 * (double)vii.num_audio_samples / (double)vii.audio_samples_per_second);\n      tlen += snprintf(text + tlen, sizeof(text) - tlen,\n        \"Audio Channels: %-8u\\n\"                              //  25\n        \"Sample Type: %s\\n\"                                   //  28=14+14\n        \"Samples Per Second: %5d\\n\"                           //  26\n        \"Audio length: %\" PRIu64 \" samples. %02\" PRIu64 \":%02d:%02d.%03d\\n\"  //  57=37+20\n        , vii.AudioChannels()\n        , s_type\n        , vii.audio_samples_per_second\n        , vii.num_audio_samples,\n        (aLenInMsecs / (60 * 60 * 1000)), (int)((aLenInMsecs / (60 * 1000)) % 60), (int)((aLenInMsecs / 1000) % 60), (int)(aLenInMsecs % 1000)\n      );\n      if (vi.IsChannelMaskKnown()) {\n        chn_layout_str = channel_layout_to_str(vi.GetChannelMask());\n        tlen += snprintf(text + tlen, sizeof(text) - tlen,\n          \"Channel mask: %s\\n\", chn_layout_str.c_str());\n      }\n    }\n    else {\n      if (cpu) {\n        strcpy(text + tlen, \"\\n\");\n        tlen += 1;\n      }\n    }\n    if (cpu) {\n      // CPU capabilities\n      tlen += snprintf(text + tlen, sizeof(text) - tlen,\n        \"CPU: %s\\n\"\n#ifdef INTEL_INTRINSICS\n        , GetCpuMsg(env, false).c_str()\n#else\n        , GetCpuMsg(env).c_str()\n#endif\n      );\n#ifdef INTEL_INTRINSICS\n      // AVX512 flags in new line (too long)\n      std::string avx512 = GetCpuMsg(env, true);\n      if (avx512.length() > 0) {\n        tlen += snprintf(text + tlen, sizeof(text) - tlen,\n          \"%s\\n\"\n          , avx512.c_str()\n        );\n      }\n#endif\n      // Cache size info in new line\n      std::string cache_info = GetCacheInfo(env);\n      if (cache_info.length() > 0) {\n        tlen += snprintf(text + tlen, sizeof(text) - tlen,\n          \"%s\\n\",\n          cache_info.c_str()\n        );\n      }\n    } // show cpu capabilities\n\n    // Windows GDI: aligns the whole box, its content is kept top left aligned\n    // \"Text\" fixed font mode: individual lines are aligned as well\n\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n    // So far RECT dimensions were hardcoded: RECT r = { 32, 16, min(3440,vi.width * 8), 900*2 };\n    // More flexible way: get text extent\n    RECT r;\n\n    // DrawText calculates the extent as plus one line if text ends with an empty \\n\n    // thus calculation of vertical center and bottom aligned text would be wrong.\n    // Cut ending LFs\n    while (tlen > 1 && text[tlen - 1] == '\\n') {\n      text[tlen - 1] = 0;\n      tlen--;\n    }\n\n    RECT r0 = { 0, 0, 100, 100 };\n\n    // always draw box at top left aligned, we calculate coordinates instead\n    // depending on the given alignment\n    SetTextAlign(hdcAntialias, TA_TOP | TA_LEFT);\n    // calculate box extent without drawing\n    DrawText(hdcAntialias, text, -1, &r0, DT_CALCRECT | DT_NOCLIP);\n\n    // correct top left and right bottom of the whole info box\n    int real_x = x;\n    int real_y = y;\n    // align vertical center\n    if (align == 4 || align == 5 || align == 6) {\n      real_y -= (int)((r0.bottom- r0.top) / 2.0 + 0.5);\n    }\n    // align vertical bottom\n    if (align == 1 || align == 2 || align == 3) {\n      real_y -= (r0.bottom - r0.top);\n    }\n    // align horizontal center\n    if (align == 8 || align == 5 || align == 2) {\n      real_x -= (int)((r0.right - r0.left) / 2.0 + 0.5);\n    }\n    // align horizontal right\n    if (align == 9 || align == 6 || align == 3) {\n      real_x -= (r0.right - r0.left);\n    }\n\n    int right = real_x + (int)r0.right;\n    int bottom = real_y + (int)r0.bottom;\n    // not left aligned: crop to visible right\n    if (!(align == 9 || align == 6 || align == 3))\n      right = min(right, vi.width * 8 - 1);\n    // not bottom aligned: crop to visible bottom\n    if (!(align == 1 || align == 2 || align == 3))\n      bottom = min(bottom, vi.height * 8 - 1);\n\n    r = { real_x, real_y, right, bottom };\n\n    // NOCLIP: draw lines if they are partially visible\n    DrawText(hdcAntialias, text, -1, &r, DT_NOCLIP);\n    GdiFlush();\n\n    env->MakeWritable(&frame);\n    frame->GetWritePtr(); // Bump sequence_number\n    int dst_pitch = frame->GetPitch();\n    antialiaser.Apply(vi, &frame, dst_pitch);\n#else\n    env->MakeWritable(&frame);\n    frame->GetWritePtr(); // Bump sequence_number\n\n    // AVS_POSIX: utf8 is always true, here n/a\n    bool utf8 = false;\n    std::string s_utf8 = charToUtf8(text, utf8);\n\n    int lsp = 0; // line spacing n/a\n\n    const int chromaplacement = ChromaLocation_e::AVS_CHROMA_LEFT;\n    SimpleTextOutW_multi(current_font.get(), vi, frame, x, y, s_utf8, false, text_color, halo_color, true, align, lsp, chromaplacement);\n#endif\n  return frame;\n}\n\nAVSValue __cdecl FilterInfo::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n    // 0   1      2       3             4         5       6      7       8    9  10    11\n    // c[font]s[size]f[text_color]i[halo_color]i[bold]b[italic]b[noaa]b[cpu]b[x]f[y]f[align]\n    PClip clip = args[0].AsClip();\n    // new parameters 20160823\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n    const char* font = args[1].AsString(\"Courier New\");\n    int size = int(args[2].AsFloat(0) * 8 + 0.5);\n    const int upper_limit = -1; // no limit\n#else\n    const char* font = args[1].AsString(\"Terminus\");\n    int size = int(args[2].AsFloat(0));\n    const int upper_limit = 32; // max terminus font size is 32\n#endif\n    if (!args[2].Defined() || size < 0)\n      size = CalcFontSizeForInfo(clip->GetVideoInfo().width, clip->GetVideoInfo().height, size < 0, upper_limit);\n    // size <= 0 means autolarge over 640x480. Fixed font: up to size 32\n    const int text_color = args[3].AsInt(0xFFFF00);\n    const int halo_color = args[4].AsInt(0);\n    const bool bold = args[5].AsBool(true); // bold has better visibility on NO_WIN_GDI terminus was well\n    const bool italic = args[6].AsBool(false);\n    const bool noaa = args[7].AsBool(false);\n    const bool cpu = args[8].AsBool(true);\n\n    const int align = args[11].AsInt(7); // default top left\n\n    const int info_default_x = 4; // subtitle: 8\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n    const int PIXEL_MUL_FACTOR = 8;\n#else\n    const int PIXEL_MUL_FACTOR = 1;\n#endif\n    // similar to SubTitle\n    int defx, defy;\n    bool x_center = false;\n    bool y_center = false;\n\n    switch (align) {\n    case 1: case 4: case 7: defx = 8; break;\n    case 2: case 5: case 8:\n      defx = 0; // n/a if not set later\n      x_center = true;\n      break;\n    case 3: case 6: case 9: defx = clip->GetVideoInfo().width - info_default_x; break; // subtitle: 8\n    default: defx = info_default_x; break;\n    }\n\n    switch (align) {\n    case 1: case 2: case 3: defy = clip->GetVideoInfo().height - 2; break; // bottom alignment 2 pixel above\n    case 4: case 5: case 6:\n      defy = 0; // n/a if not set later\n      y_center = true;\n      break;\n    case 7: case 8: case 9: defy = 0; break;\n    default: defy = (size + 4) / 8; break;\n    }\n\n    const bool isXdefined = args[9].Defined();\n    const bool isYdefined = args[10].Defined();\n\n    int x = int(args[9].AsDblDef(defx) * PIXEL_MUL_FACTOR + 0.5);\n    int y = int(args[10].AsDblDef(defy) * PIXEL_MUL_FACTOR + 0.5);\n\n    if (!isXdefined && x_center)\n      x = (clip->GetVideoInfo().width >> 1) * PIXEL_MUL_FACTOR;\n\n    if (!isYdefined && y_center)\n      y = (clip->GetVideoInfo().height >> 1) * PIXEL_MUL_FACTOR;\n\n\n    if ((align < 1) || (align > 9))\n      env->ThrowError(\"Info: Align values are 1 - 9 mapped to your numeric pad\");\n\n    return new FilterInfo(clip, font, size, text_color, halo_color, bold, italic, noaa, cpu, x, y, align, env);\n}\n\n\n\n/************************************\n *******    Compare Filter    *******\n ***********************************/\n\nCompare::Compare(PClip _child1, PClip _child2, const char* channels, const char *fname, bool _show_graph, IScriptEnvironment* env)\n  : GenericVideoFilter(_child1),\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  antialiaser(vi.width, vi.height, \"Courier New\", 16 * 8,\n    (vi.IsYUV() || vi.IsYUVA()) ? 0xD21092 : 0xFFFF00,\n    (vi.IsYUV() || vi.IsYUVA()) ? 0x108080 : 0,\n    true, false, false // bold, italic, noaa\n  ),\n#endif\n  child2(_child2),\n  log(nullptr),\n  show_graph(_show_graph),\n  framecount(0),\n  text_color((vi.IsYUV() || vi.IsYUVA()) ? 0xD21092 : 0xFFFF00),\n  halo_color((vi.IsYUV() || vi.IsYUVA()) ? 0x108080 : 0)\n{\n  const VideoInfo& vi2 = child2->GetVideoInfo();\n  psnrs = 0;\n\n  if (!vi.IsSameColorspace(vi2))\n    env->ThrowError(\"Compare: Clips are not same colorspace.\");\n\n  if (vi.width != vi2.width || vi.height != vi2.height)\n    env->ThrowError(\"Compare: Clips must have same size.\");\n\n  if (!(vi.IsRGB24() || vi.IsYUY2() || vi.IsRGB32() || vi.IsPlanar() || vi.IsRGB48() || vi.IsRGB64()))\n    env->ThrowError(\"Compare: Clips have unknown pixel format. RGB24/32/48/64, YUY2 and YUV/RGB Planar supported.\");\n\n  pixelsize = vi.ComponentSize();\n  bits_per_pixel = vi.BitsPerComponent();\n\n  if (pixelsize == 4)\n      env->ThrowError(\"Compare: Float pixel format not supported.\");\n\n  if (channels[0] == 0) {\n    if (vi.IsRGB())\n      channels = \"RGB\";\n    else if (vi.IsY())\n      channels = \"Y\";\n    else if (vi.IsYUV() || vi.IsYUVA())\n      channels = \"YUV\";\n    else env->ThrowError(\"Compare: Clips have unknown colorspace. RGB and YUV supported.\");\n  }\n\n  planar_plane = 0;\n  mask = 0;\n  const size_t length = strlen(channels);\n  for (size_t i = 0; i < length; i++) {\n    if (vi.IsRGB() && !vi.IsPlanar()) {\n      switch (channels[i]) {\n      case 'b':\n      case 'B': mask |= 0x000000ff; mask64 |= 0x000000000000ffffull; break;\n      case 'g':\n      case 'G': mask |= 0x0000ff00; mask64 |= 0x00000000ffff0000ull; break;\n      case 'r':\n      case 'R': mask |= 0x00ff0000; mask64 |= 0x0000ffff00000000ull; break;\n      case 'a':\n      case 'A': mask |= 0xff000000; mask64 |= 0xffff000000000000ull;  if (vi.IsRGB32() || vi.IsRGB64()) break; // else no alpha -> fall thru\n      default: env->ThrowError(\"Compare: invalid channel: %c\", channels[i]);\n      }\n      if (vi.IsRGB24() || vi.IsRGB48()) mask &= 0x00ffffff;   // no alpha channel in RGB24\n    } else if (vi.IsPlanar()) {\n        if(vi.IsYUV() || vi.IsYUVA()) {\n          switch (channels[i]) {\n          case 'y':\n          case 'Y': mask |= 0xffffffff; planar_plane |= PLANAR_Y; break;\n          case 'u':\n          case 'U': mask |= 0xffffffff; planar_plane |= PLANAR_U; break;\n          case 'v':\n          case 'V': mask |= 0xffffffff; planar_plane |= PLANAR_V; break;\n          case 'a':\n          case 'A': mask |= 0xffffffff; planar_plane |= PLANAR_A; if (vi.IsYUVA()) break;  // else no alpha -> fall thru\n          default: env->ThrowError(\"Compare: invalid channel: %c\", channels[i]);\n          }\n          if (vi.IsY() && ((planar_plane & PLANAR_U) || (planar_plane & PLANAR_V))) {\n              env->ThrowError(\"Compare: invalid channel: %c for greyscale clip\", channels[i]);\n          }\n        } else {\n            // planar RGB, planar RGBA\n            switch (channels[i]) {\n            case 'r':\n            case 'R': mask |= 0xffffffff; planar_plane |= PLANAR_R; break;\n            case 'g':\n            case 'G': mask |= 0xffffffff; planar_plane |= PLANAR_G; break;\n            case 'b':\n            case 'B': mask |= 0xffffffff; planar_plane |= PLANAR_B; break;\n            case 'a':\n            case 'A': mask |= 0xffffffff; planar_plane |= PLANAR_A; if (vi.IsPlanarRGBA()) break;  // else no alpha -> fall thru\n            default: env->ThrowError(\"Compare: invalid channel: %c\", channels[i]);\n            }\n        }\n    } else {  // YUY2\n      switch (channels[i]) {\n      case 'y':\n      case 'Y': mask |= 0x00ff00ff; break;\n      case 'u':\n      case 'U': mask |= 0x0000ff00; break;\n      case 'v':\n      case 'V': mask |= 0xff000000; break;\n      default: env->ThrowError(\"Compare: invalid channel: %c\", channels[i]);\n      }\n    }\n  }\n\n  masked_bytes = 0;\n  for (uint32_t temp = mask; temp != 0; temp >>=8)\n    masked_bytes += (temp & 1);\n\n  if (fname[0] != 0) {\n    log = fopen(fname, \"wt\");\n    if (log) {\n      fprintf(log,\"Comparing channel(s) %s\\n\\n\",channels);\n      fprintf(log,\"           Mean               Max    Max             \\n\");\n      fprintf(log,\"         Absolute     Mean    Pos.   Neg.            \\n\");\n      fprintf(log,\" Frame     Dev.       Dev.    Dev.   Dev.  PSNR (dB) \\n\");\n      fprintf(log,\"-----------------------------------------------------\\n\");\n    } else\n      env->ThrowError(\"Compare: unable to create file %s\", fname);\n  } else {\n    psnrs = new(std::nothrow) int[vi.num_frames];\n    if (psnrs)\n      for (int i = 0; i < vi.num_frames; i++)\n        psnrs[i] = 0;\n  }\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n#else\n  // internal font\n  const bool bold = false;\n  const int size = 16;\n  current_font = GetBitmapFont(size, \"Terminus\", bold, false);\n  chromaplacement = ChromaLocation_e::AVS_CHROMA_LEFT;\n  if (current_font == nullptr)\n  {\n    // size\n    current_font = GetBitmapFont(size, \"\", bold, false);\n    if (current_font == nullptr)\n      current_font = GetBitmapFont(size, \"\", !bold, false);\n  }\n#endif\n}\n\n\nCompare::~Compare()\n{\n  if (log) {\n    fprintf(log,\"\\n\\n\\nTotal frames processed: %d\\n\\n\", framecount);\n    fprintf(log,\"                           Minimum   Average   Maximum\\n\");\n    fprintf(log,\"Mean Absolute Deviation: %9.4f %9.4f %9.4f\\n\", MAD_min, MAD_tot/framecount, MAD_max);\n    fprintf(log,\"         Mean Deviation: %+9.4f %+9.4f %+9.4f\\n\", MD_min, MD_tot/framecount, MD_max);\n    fprintf(log,\"                   PSNR: %9.4f %9.4f %9.4f\\n\", PSNR_min, PSNR_tot/framecount, PSNR_max);\n    double factor = (1 << bits_per_pixel) - 1;\n    double PSNR_overall = 10.0 * log10(bytecount_overall * factor * factor / SSD_overall);\n    fprintf(log,\"           Overall PSNR: %9.4f\\n\", PSNR_overall);\n    fclose(log);\n  }\n  delete[] psnrs;\n}\n\n\nAVSValue __cdecl Compare::Create(AVSValue args, void*, IScriptEnvironment *env)\n{\n  return new Compare( args[0].AsClip(),     // clip\n            args[1].AsClip(),     // base clip\n            args[2].AsString(\"\"),   // channels\n            args[3].AsString(\"\"),   // logfile\n            args[4].AsBool(true),   // show_graph\n            env);\n}\n\nstatic void compare_planar_c(\n    const BYTE * f1ptr, int pitch1,\n    const BYTE * f2ptr, int pitch2,\n    int rowsize, int height,\n    int &SAD_sum, int &SD_sum, int &pos_D,  int &neg_D, double &SSD_sum)\n{\n    int row_SSD;\n\n    for (int y = 0; y < height; y++) {\n        row_SSD = 0;\n        for (int x = 0; x < rowsize; x += 1) {\n            int p1 = *(f1ptr + x);\n            int p2 = *(f2ptr + x);\n            int d0 = p1 - p2;\n            SD_sum += d0;\n            SAD_sum += abs(d0);\n            row_SSD += d0 * d0;\n            pos_D = max(pos_D, d0);\n            neg_D = min(neg_D, d0);\n        }\n        SSD_sum += row_SSD;\n        f1ptr += pitch1;\n        f2ptr += pitch2;\n    }\n}\n\nstatic void compare_planar_uint16_t_c(\n    const BYTE * f1ptr8, int pitch1,\n    const BYTE * f2ptr8, int pitch2,\n    int rowsize, int height,\n    int64_t&SAD_sum, int64_t &SD_sum, int &pos_D,  int &neg_D, double &SSD_sum)\n{\n    int64_t row_SSD;\n\n    const uint16_t *f1ptr = reinterpret_cast<const uint16_t *>(f1ptr8);\n    const uint16_t *f2ptr = reinterpret_cast<const uint16_t *>(f2ptr8);\n    pitch1 /= sizeof(uint16_t);\n    pitch2 /= sizeof(uint16_t);\n    rowsize /= sizeof(uint16_t);\n\n\n    for (int y = 0; y < height; y++) {\n        row_SSD = 0;\n        for (int x = 0; x < rowsize; x += 1) {\n            int p1 = *(f1ptr + x);\n            int p2 = *(f2ptr + x);\n            int d0 = p1 - p2;\n            SD_sum += d0;\n            SAD_sum += abs(d0);\n            row_SSD += d0 * d0;\n            pos_D = max(pos_D, d0);\n            neg_D = min(neg_D, d0);\n        }\n        SSD_sum += row_SSD;\n        f1ptr += pitch1;\n        f2ptr += pitch2;\n    }\n}\n\n\nstatic void compare_c(uint32_t mask, int increment,\n    const BYTE * f1ptr, int pitch1,\n    const BYTE * f2ptr, int pitch2,\n    int rowsize, int height,\n    int &SAD_sum, int &SD_sum, int &pos_D,  int &neg_D, double &SSD_sum)\n{\n    int row_SSD;\n\n    for (int y = 0; y < height; y++) {\n        row_SSD = 0;\n        for (int x = 0; x < rowsize; x += increment) {\n            uint32_t p1 = *(uint32_t*)(f1ptr + x) & mask;\n            uint32_t p2 = *(uint32_t*)(f2ptr + x) & mask;\n            int d0 = (p1 & 0xff) - (p2 & 0xff);\n            int d1 = ((p1 >> 8) & 0xff) - ((p2 & 0xff00) >> 8); // ?PF why not (p2 >> 8) & 0xff as for p1?\n            int d2 = ((p1 >> 16) & 0xff) - ((p2 & 0xff0000) >> 16);\n            int d3 = (p1 >> 24) - (p2 >> 24);\n            SD_sum += d0 + d1 + d2 + d3;\n            SAD_sum += abs(d0) + abs(d1) + abs(d2) + abs(d3);\n            row_SSD += d0 * d0 + d1 * d1 + d2 * d2 + d3 * d3;\n            pos_D = max(max(max(max(pos_D, d0), d1), d2), d3);\n            neg_D = min(min(min(min(neg_D, d0), d1), d2), d3);\n        }\n        SSD_sum += row_SSD;\n        f1ptr += pitch1;\n        f2ptr += pitch2;\n    }\n}\n\nstatic void compare_uint16_t_c(uint64_t mask64, int increment,\n    const BYTE * f1ptr8, int pitch1,\n    const BYTE * f2ptr8, int pitch2,\n    int rowsize, int height,\n    int64_t& SAD_sum, int64_t &SD_sum, int &pos_D, int &neg_D, double &SSD_sum)\n{\n    int64_t row_SSD;\n\n    const uint16_t *f1ptr = reinterpret_cast<const uint16_t *>(f1ptr8);\n    const uint16_t *f2ptr = reinterpret_cast<const uint16_t *>(f2ptr8);\n    pitch1 /= sizeof(uint16_t);\n    pitch2 /= sizeof(uint16_t);\n    rowsize /= sizeof(uint16_t);\n\n    for (int y = 0; y < height; y++) {\n        row_SSD = 0;\n        for (int x = 0; x < rowsize; x += increment) {\n            uint64_t p1 = *(uint64_t *)(f1ptr + x) & mask64;\n            uint64_t p2 = *(uint64_t *)(f2ptr + x) & mask64;\n            int d0 = (p1 & 0xffff) - (p2 & 0xffff);\n            int d1 = ((p1 >> 16) & 0xffff) - ((p2 & 0xffff0000) >> 16);     // ?PF why not (p2 >> 16) & 0xffff as for p1?\n            int d2 = ((p1 >> 32) & 0xffff) - ((p2 & 0xffff00000000ull) >> 32);\n            int d3 = (p1 >> 48) - (p2 >> 48);\n            SD_sum += d0 + d1 + d2 + d3;\n            SAD_sum += abs(d0) + abs(d1) + abs(d2) + abs(d3);\n            row_SSD += d0 * d0 + d1 * d1 + d2 * d2 + d3 * d3;\n            pos_D = max(max(max(max(pos_D, d0), d1), d2), d3);\n            neg_D = min(min(min(min(neg_D, d0), d1), d2), d3);\n        }\n        SSD_sum += row_SSD;\n        f1ptr += pitch1;\n        f2ptr += pitch2;\n    }\n}\n\n\n\nPVideoFrame __stdcall Compare::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame f1 = child->GetFrame(n, env);\n  PVideoFrame f2 = child2->GetFrame(n, env);\n\n  int SD = 0;\n  int64_t SD_64 = 0;\n  int SAD = 0;\n  int64_t SAD_64 = 0;\n  int pos_D = 0;\n  int neg_D = 0;\n  double SSD = 0;\n\n  int bytecount = 0;\n\n  const int incr = (vi.IsRGB24() || vi.IsRGB48()) ? 3 : 4;\n\n  if (vi.IsRGB24() || vi.IsYUY2() || vi.IsRGB32() || vi.IsRGB48() || vi.IsRGB64()) {\n\n    const BYTE* f1ptr = f1->GetReadPtr();\n    const BYTE* f2ptr = f2->GetReadPtr();\n    const int pitch1 = f1->GetPitch();\n    const int pitch2 = f2->GetPitch();\n    const int rowsize = f1->GetRowSize();\n    const int height = f1->GetHeight();\n\n    bytecount = (rowsize / pixelsize) * height * masked_bytes / 4;\n#ifdef INTEL_INTRINSICS\n\n    if (((vi.IsRGB32() && (rowsize % 16 == 0)) || (vi.IsRGB24() && (rowsize % 12 == 0)) || (vi.IsYUY2() && (rowsize % 16 == 0))) &&\n      (pixelsize == 1) && (env->GetCPUFlags() & CPUF_SSE2)) // only for uint8_t (pixelsize==1), todo\n    {\n\n      compare_sse2(mask, incr, f1ptr, pitch1, f2ptr, pitch2, rowsize, height, SAD, SD, pos_D, neg_D, SSD);\n    }\n    else\n#ifdef X86_32\n      if (((vi.IsRGB32() && (rowsize % 8 == 0)) || (vi.IsRGB24() && (rowsize % 6 == 0)) || (vi.IsYUY2() && (rowsize % 8 == 0))) &&\n        (pixelsize == 1) && (env->GetCPUFlags() & CPUF_INTEGER_SSE)) // only for uint8_t (pixelsize==1), todo\n      {\n        compare_isse(mask, incr, f1ptr, pitch1, f2ptr, pitch2, rowsize, height, SAD, SD, pos_D, neg_D, SSD);\n      }\n      else\n#endif\n#endif\n      {\n\n        if (pixelsize == 1)\n          compare_c(mask, incr, f1ptr, pitch1, f2ptr, pitch2, rowsize, height, SAD, SD, pos_D, neg_D, SSD);\n        else\n          compare_uint16_t_c(mask64, incr, f1ptr, pitch1, f2ptr, pitch2, rowsize, height, SAD_64, SD_64, pos_D, neg_D, SSD);\n      }\n  }\n  else { // Planar\n\n    int planes_y[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };\n    int planes_r[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A };\n    int* planes = (vi.IsYUV() || vi.IsYUVA()) ? planes_y : planes_r;\n    for (int p = 0; p < 4; p++) {\n      const int plane = planes[p];\n\n      if (planar_plane & plane) {\n\n        const BYTE* f1ptr = f1->GetReadPtr(plane);\n        const BYTE* f2ptr = f2->GetReadPtr(plane);\n        const int pitch1 = f1->GetPitch(plane);\n        const int pitch2 = f2->GetPitch(plane);\n        const int rowsize = f1->GetRowSize(plane);\n        const int height = f1->GetHeight(plane);\n\n        bytecount += (rowsize / pixelsize) * height;\n#ifdef INTEL_INTRINSICS\n\n        if ((pixelsize == 1) && (rowsize % 16 == 0) && (env->GetCPUFlags() & CPUF_SSE2))\n        {\n          compare_sse2(mask, incr, f1ptr, pitch1, f2ptr, pitch2, rowsize, height, SAD, SD, pos_D, neg_D, SSD);\n        }\n        else\n#ifdef X86_32\n          if ((pixelsize == 1) && (rowsize % 8 == 0) && (env->GetCPUFlags() & CPUF_INTEGER_SSE))\n          {\n            compare_isse(mask, incr, f1ptr, pitch1, f2ptr, pitch2, rowsize, height, SAD, SD, pos_D, neg_D, SSD);\n          }\n          else\n#endif\n#endif\n          {\n\n            if (pixelsize == 1)\n              compare_planar_c(f1ptr, pitch1, f2ptr, pitch2, rowsize, height, SAD, SD, pos_D, neg_D, SSD);\n            else\n              compare_planar_uint16_t_c(f1ptr, pitch1, f2ptr, pitch2, rowsize, height, SAD_64, SD_64, pos_D, neg_D, SSD);\n          }\n      }\n    }\n  }\n\n  double MAD = ((pixelsize==1) ? (double)SAD : (double)SAD_64) / bytecount;\n  double MD = ((pixelsize==1) ? (double)SD : (double)SD_64) / bytecount;\n  if (SSD == 0.0) SSD = 1.0;\n  const int max_pixel_value = (1 << bits_per_pixel) - 1;\n  double factor = (double)(max_pixel_value);\n  double PSNR = 10.0 * log10(bytecount * factor * factor / SSD);\n\n  framecount++;\n  if (framecount == 1) {\n    MAD_min = MAD_tot = MAD_max = MAD;\n    MD_min = MD_tot = MD_max = MD;\n    PSNR_min = PSNR_tot = PSNR_max = PSNR;\n    bytecount_overall = double(bytecount);\n    SSD_overall = SSD;\n  } else {\n    MAD_min = min(MAD_min, MAD);\n    MAD_tot += MAD;\n    MAD_max = max(MAD_max, MAD);\n    MD_min = min(MD_min, MD);\n    MD_tot += MD;\n    MD_max = max(MD_max, MD);\n    PSNR_min = min(PSNR_min, PSNR);\n    PSNR_tot += PSNR;\n    PSNR_max = max(PSNR_max, PSNR);\n    bytecount_overall += double(bytecount);\n    SSD_overall += SSD;\n  }\n\n  if (log) {\n    if (pixelsize == 1)\n      fprintf(log,\"%6u  %8.4f  %+9.4f  %3d    %3d    %8.4f\\n\", (unsigned int)n, MAD, MD, pos_D, neg_D, PSNR);\n    else\n      fprintf(log,\"%6u  %11.4f  %+12.4f  %7d    %7d    %8.4f\\n\", (unsigned int)n, MAD, MD, pos_D, neg_D, PSNR);\n  } else {\n    env->MakeWritable(&f1);\n    BYTE* dstp = f1->GetWritePtr();\n    int dst_pitch = f1->GetPitch();\n\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n    HDC hdc = antialiaser.GetDC();\n    if (hdc)\n#else\n    if(current_font != nullptr)\n#endif\n    {\n        char text[600];\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n        RECT r = { 32, 16, min((51+(pixelsize==1 ? 0: 12))*67,vi.width * 8), 768 + 128 }; // orig: 3440: 51*67, not enough for 16 bit data\n#endif\n        double PSNR_overall = 10.0 * log10(bytecount_overall * factor * factor / SSD_overall);\n        if (pixelsize == 1)\n            snprintf(text, sizeof(text),\n                \"       Frame:  %-8u(   min  /   avg  /   max  )\\n\"\n                \"Mean Abs Dev:%8.4f  (%7.3f /%7.3f /%7.3f )\\n\"\n                \"    Mean Dev:%+8.4f  (%+7.3f /%+7.3f /%+7.3f )\\n\"\n                \" Max Pos Dev:%4d  \\n\"\n                \" Max Neg Dev:%4d  \\n\"\n                \"        PSNR:%6.2f dB ( %6.2f / %6.2f / %6.2f )\\n\"\n                \"Overall PSNR:%6.2f dB\\n\",\n                n,\n                MAD, MAD_min, MAD_tot / framecount, MD_max,\n                MD, MD_min, MD_tot / framecount, MD_max,\n                pos_D,\n                neg_D,\n                PSNR, PSNR_min, PSNR_tot / framecount, PSNR_max,\n                PSNR_overall\n            );\n        else\n            snprintf(text, sizeof(text),\n                \"       Frame:  %-8u   (     min   /     avg   /     max   )\\n\"\n                \"Mean Abs Dev:%11.4f  (%10.3f /%10.3f /%10.3f )\\n\"\n                \"    Mean Dev:%+11.4f  (%+10.3f /%+10.3f /%+10.3f )\\n\"\n                \" Max Pos Dev:%7d  \\n\"\n                \" Max Neg Dev:%7d  \\n\"\n                \"        PSNR:%6.2f dB    (   %6.2f  /   %6.2f  /   %6.2f  )\\n\"\n                \"Overall PSNR:%6.2f dB\\n\",\n                n,\n                MAD, MAD_min, MAD_tot / framecount, MD_max,\n                MD, MD_min, MD_tot / framecount, MD_max,\n                pos_D,\n                neg_D,\n                PSNR, PSNR_min, PSNR_tot / framecount, PSNR_max,\n                PSNR_overall\n            );\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n        DrawText(hdc, text, -1, &r, 0);\n        GdiFlush();\n\n        antialiaser.Apply(vi, &f1, dst_pitch);\n#else\n        bool utf8 = true;\n        auto s_utf8 = charToUtf8(text, utf8);\n        const int chromaplacement = ChromaLocation_e::AVS_CHROMA_LEFT;\n        SimpleTextOutW_multi(current_font.get(), vi, f1, 2, 1, s_utf8, true, text_color, halo_color, false, 0 /* no align */, 0 /*lsp*/, chromaplacement);\n#endif\n    }\n\n    if (show_graph) {\n      // original idea by Marc_FD\n      // PF remark: show-graph (and file logging) is not for multitask\n      // psnrs array is instance specific\n      psnrs[n] = min((int)(PSNR + 0.5), 100);\n      if (vi.height > 196) {\n        if (vi.IsYUY2()) {\n          dstp += (vi.height - 1) * dst_pitch;\n          for (int y = 0; y <= 100; y++) {\n            for (int x = max(0, vi.width - n - 1); x < vi.width; x++) {\n              if (y <= psnrs[n - vi.width + 1 + x]) {\n                if (y <= psnrs[n - vi.width + 1 + x] - 2) {\n                  dstp[x << 1] = 16;                // Y\n                  dstp[((x & -1) << 1) + 1] = 0x80; // U\n                  dstp[((x & -1) << 1) + 3] = 0x80; // V\n                } else {\n                  dstp[x << 1] = 235;               // Y\n                  dstp[((x & -1) << 1) + 1] = 0x80; // U\n                  dstp[((x & -1) << 1) + 3] = 0x80; // V\n                }\n              }\n            } // for x\n            dstp -= dst_pitch;\n          } // for y\n        }\n    else if (vi.IsPlanar()) {\n            if (vi.IsPlanarRGB() || vi.IsPlanarRGBA())\n            {\n                BYTE* dstp_RGBP[3] = { f1->GetWritePtr(PLANAR_G), f1->GetWritePtr(PLANAR_B),f1->GetWritePtr(PLANAR_R) };\n                int dst_pitch_RGBP[3] = { f1->GetPitch(PLANAR_G), f1->GetPitch(PLANAR_B), f1->GetPitch(PLANAR_R) };\n\n                dstp_RGBP[0] += (vi.height - 1) * dst_pitch_RGBP[0];\n                dstp_RGBP[1] += (vi.height - 1) * dst_pitch_RGBP[1];\n                dstp_RGBP[2] += (vi.height - 1) * dst_pitch_RGBP[2];\n                for (int y = 0; y <= 100; y++) {\n                    for (int x = max(0, vi.width - n - 1); x < vi.width; x++) {\n                        if (y <= psnrs[n - vi.width + 1 + x]) {\n                            if (y <= psnrs[n - vi.width + 1 + x] - 2) {\n                                if(pixelsize==1) {\n                                    dstp_RGBP[0][x] = 0;\n                                    dstp_RGBP[1][x] = 0;\n                                    dstp_RGBP[2][x] = 0;\n                                } else {\n                                    reinterpret_cast<uint16_t *>(dstp_RGBP[0])[x] = 0;\n                                    reinterpret_cast<uint16_t *>(dstp_RGBP[1])[x] = 0;\n                                    reinterpret_cast<uint16_t *>(dstp_RGBP[2])[x] = 0;\n                                }\n                            } else {\n                                if(pixelsize==1) {\n                                    dstp_RGBP[0][x] = 0xFF;\n                                    dstp_RGBP[1][x] = 0xFF;\n                                    dstp_RGBP[2][x] = 0xFF;\n                                } else {\n                                    reinterpret_cast<uint16_t *>(dstp_RGBP[0])[x] = max_pixel_value;\n                                    reinterpret_cast<uint16_t *>(dstp_RGBP[1])[x] = max_pixel_value;\n                                    reinterpret_cast<uint16_t *>(dstp_RGBP[2])[x] = max_pixel_value;\n                                }\n                            }\n                        }\n                    } // for x\n                    dstp_RGBP[0] -= dst_pitch_RGBP[0];\n                    dstp_RGBP[1] -= dst_pitch_RGBP[1];\n                    dstp_RGBP[2] -= dst_pitch_RGBP[2];\n                }\n            } else {\n                // planar YUV\n                dstp += (vi.height - 1) * dst_pitch;\n                const int black = 16 << (bits_per_pixel - 8);\n                const int white = 235 << (bits_per_pixel - 8);\n                for (int y = 0; y <= 100; y++) {\n                    for (int x = max(0, vi.width - n - 1); x < vi.width; x++) {\n                        if (y <= psnrs[n - vi.width + 1 + x]) {\n                            if (y <= psnrs[n - vi.width + 1 + x] - 2) {\n                                if(pixelsize==1)\n                                    dstp[x] = 16; // Y\n                                else\n                                    reinterpret_cast<uint16_t *>(dstp)[x] = black; // Y\n                            } else {\n                                if(pixelsize==1)\n                                    dstp[x] = 235; // Y\n                                else\n                                    reinterpret_cast<uint16_t *>(dstp)[x] = white; // Y\n                            }\n                        }\n                    } // for x\n                    dstp -= dst_pitch;\n            }\n          } // for y\n        } else {  // packed RGB 8 or 16 bits\n          for (int y = 0; y <= 100; y++) {\n            for (int x = max(0, vi.width - n - 1); x < vi.width; x++) {\n              if (y <= psnrs[n - vi.width + 1 + x]) {\n                const int xx = x * incr;\n                if (y <= psnrs[n - vi.width + 1 + x] -2) {\n                    if(pixelsize==1) {\n                      dstp[xx] = 0x00;        // B\n                      dstp[xx + 1] = 0x00;    // G\n                      dstp[xx + 2] = 0x00;    // R\n                    }\n                    else {\n                      reinterpret_cast<uint16_t *>(dstp)[xx] = 0x00;        // B\n                      reinterpret_cast<uint16_t *>(dstp)[xx + 1] = 0x00;    // G\n                      reinterpret_cast<uint16_t *>(dstp)[xx + 2] = 0x00;    // R\n                    }\n                } else {\n                    if(pixelsize==1) {\n                        dstp[xx] = 0xFF;        // B\n                        dstp[xx + 1] = 0xFF;    // G\n                        dstp[xx + 2] = 0xFF;    // R\n                    }\n                    else {\n                        reinterpret_cast<uint16_t *>(dstp)[xx] = 0xFFFF;        // B\n                        reinterpret_cast<uint16_t *>(dstp)[xx + 1] = 0xFFFF;    // G\n                        reinterpret_cast<uint16_t *>(dstp)[xx + 2] = 0xFFFF;    // R\n                    }\n                }\n              }\n            } // for x\n            dstp += dst_pitch;\n          } // for y\n        } // RGB\n      } // height > 100\n    } // show_graph\n  } // no logfile\n\n  return f1;\n}\n\n\n\n\n\n\n\n\n\n\n\n/************************************\n *******   Helper Functions    ******\n ***********************************/\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\nbool GetTextBoundingBox(const char* text, const char* fontname, int size, bool bold,\n  bool italic, int align, int* width, int* height, bool utf8)\n{\n  HFONT hfont = LoadFont(fontname, size, bold, italic);\n  if (hfont == NULL)\n    return false;\n  HDC hdc = GetDC(NULL);\n  if (hdc == NULL)\n    return false;\n  HFONT hfontDefault = (HFONT)SelectObject(hdc, hfont);\n  int old_map_mode = SetMapMode(hdc, MM_TEXT);\n  UINT old_text_align = SetTextAlign(hdc, align);\n\n  // Initialize width and height with base value (8 GDI units)\n  *height = 8;\n  *width = 8;\n\n  bool success = true;\n  const char* current_text_ptr = text;\n\n  // Handle empty string case immediately\n  if (text == nullptr || *text == '\\0') {\n    // Already initialized to 8, so nothing more to do for empty text\n  }\n  else {\n    // Loop through lines\n\n    while (*current_text_ptr != '\\0')\n    {\n      // Find the end of the current line segment (first CR or LF)\n      const char* line_end_ptr = current_text_ptr;\n      while (*line_end_ptr != '\\0' && *line_end_ptr != '\\r' && *line_end_ptr != '\\n') {\n        line_end_ptr++;\n      }\n\n      const char* next_segment_start;\n      std::unique_ptr<wchar_t[]> wide_line; // Used for converting a substring\n      std::string temp_line;\n\n      if (*line_end_ptr != '\\0') // Found a line break character\n      {\n        // Extract the current line segment\n        temp_line.assign(current_text_ptr, (size_t)(line_end_ptr - current_text_ptr));\n        wide_line = utf8 ? Utf8ToWideChar(temp_line.c_str()) : AnsiToWideChar(temp_line.c_str());\n\n        // Advance pointer past the line break(s)\n        next_segment_start = line_end_ptr;\n        if (*next_segment_start == '\\r' && *(next_segment_start + 1) == '\\n') {\n          next_segment_start += 2;\n        }\n        else {\n          next_segment_start += 1;\n        }\n      }\n      else // End of string\n      {\n        // Process the rest of the string as the last line\n        wide_line = utf8 ? Utf8ToWideChar(current_text_ptr) : AnsiToWideChar(current_text_ptr);\n        next_segment_start = current_text_ptr + strlen(current_text_ptr);\n      }\n\n      if (!wide_line) {\n        success = false;\n        break;\n      }\n\n      RECT r = { 0, 0, 0, 0 };\n      // Use DrawTextW for wide characters with DT_CALCRECT and DT_SINGLELINE\n      success = (DrawTextW(hdc, wide_line.get(), (int)(wcslen(wide_line.get())), &r, DT_CALCRECT | DT_NOPREFIX | DT_SINGLELINE) != 0);\n\n      if (!success)\n        break;\n\n      // +8 GDI units to the right side (width) as well\n      *width = std::max(*width, (int)r.right + 8); // Update max width encountered\n      *height += r.bottom;                     // Add this line's height\n\n      if (*next_segment_start != '\\0')\n        current_text_ptr = next_segment_start;// Move past the newline character\n      else\n        break; // No more newlines, end of text\n    }\n  }\n\n  // Clean up GDI objects\n  SetTextAlign(hdc, old_text_align);\n  SetMapMode(hdc, old_map_mode);\n  SelectObject(hdc, hfontDefault);\n  DeleteObject(hfont);\n  ReleaseDC(NULL, hdc);\n\n  return success;\n}\n#endif\n\nbool GetTextBoundingBoxFixed(const char* text, const char* fontname, int size, bool bold,\n  bool italic, int align, int& width, int& height, bool utf8)\n{\n  std::unique_ptr<BitmapFont> current_font;\n  /*\n  if (*font_filename) {\n    // external font file\n    const bool debugSave = false;\n    current_font = GetBitmapFont(0, font_filename, false, debugSave); // 0: size n/a\n    if (current_font == nullptr)\n      env->ThrowError(\"SimpleText: file %s not found or unknown file format\", font_filename);\n  }\n  else\n  */\n  {\n    // internal font\n    if (fontname) {\n      current_font = GetBitmapFont(size, fontname, bold, false); // 12, \"Terminus\"\n      if (current_font == nullptr)\n        return false; // (\"internal font name %s in size %d not found\", fontname, size\n    }\n    else {\n      // size\n      current_font = GetBitmapFont(size, \"\", bold, false); // 12, \"\"\n      if (current_font == nullptr)\n        return false; // \"fixed font size %d not found\", size\n    }\n  }\n\n  size_t max_width = 1;\n  height = 1;\n\n  // make list governed by LF separator\n  std::string temp;\n  std::stringstream ss(text);\n  while (std::getline(ss, temp, '\\n')) {\n    // does not recognize combined unicode sequences, \n    // e.g. U: is len=2 and not len=1 like Ü\n\n    // We no longer assume fixed width for all chars in BDF, must calculate width by adding each characters' real width\n    // max_width = std::max(max_width, real_len * current_font->global_bbx.width);\n    // cannot do simple len * FONT_WIDTH, because characters can have different widths\n\n    std::string s_utf8 = charToUtf8(temp.c_str(), utf8);\n    // map an utf8 string to a sequence of character map indexes\n    auto s_remapped = current_font->remap(s_utf8); // array of font table indexes\n    size_t total_width = 0;\n    for (int i = 0; i < (int)s_remapped.size(); i++) {\n      // bbx_array is the array of bounding boxes for each character\n      // s[i] is the index to the fontbitmap array\n      total_width += current_font->bbx_array[s_remapped[i]].width;\n    }\n    max_width = std::max(max_width, total_width);\n    height += current_font->global_bbx.height;\n  }\n\n  width = (int)max_width;\n\n  return true;\n}\n\n// old ApplyMessage with an extra utf8 parameter\nvoid ApplyMessageEx(PVideoFrame* frame, const VideoInfo& vi, const char* message, int size,\n  int textcolor, int halocolor, int bgcolor, bool utf8, IScriptEnvironment* env)\n{\n  AVS_UNUSED(bgcolor);\n  AVS_UNUSED(env);\n  if (vi.IsYUV() || vi.IsYUVA()) {\n    textcolor = RGB2YUV_Rec601(textcolor);\n    halocolor = RGB2YUV_Rec601(halocolor);\n  }\n\n  const bool bold = true;\n  const bool italic = false;\n  const bool noaa = false;\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  Antialiaser antialiaser(vi.width, vi.height, \"Arial\", size, textcolor, halocolor, bold, italic, noaa);\n  HDC hdcAntialias = antialiaser.GetDC();\n  if (hdcAntialias)\n  {\n    RECT r = { 4 * 8, 4 * 8, vi.width * 8, vi.height * 8 };\n\n    auto utf8Message = utf8 ? Utf8ToWideChar(message) : AnsiToWideChar(message);\n    DrawTextW(hdcAntialias, utf8Message.get(), (int)wcslen(utf8Message.get()), &r, DT_NOPREFIX | DT_CENTER);\n\n    GdiFlush();\n    antialiaser.Apply(vi, frame, (*frame)->GetPitch());\n  }\n#else\n  std::unique_ptr<BitmapFont> current_font;\n\n  size = size / 8; // size comes in GDI units (*8)\n\n  // internal font\n  current_font = GetBitmapFont(size, \"Terminus\", bold, false);\n  if (current_font == nullptr)\n  {\n    // size\n    current_font = GetBitmapFont(size, \"\", bold, false);\n    if (current_font == nullptr)\n      current_font = GetBitmapFont(size, \"\", !bold, false);\n    if (current_font == nullptr)\n      return;\n  }\n\n  // AVS_POSIX: utf8 is always true\n  std::string s_utf8 = charToUtf8(message, utf8);\n\n  int align = 7;\n  int lsp = 0;\n  int x = 4;\n  int y = 4;\n\n  const int chromaplacement = ChromaLocation_e::AVS_CHROMA_LEFT;\n  SimpleTextOutW_multi(current_font.get(), vi, *frame, x, y, s_utf8, false, textcolor, halocolor, true, align, lsp, chromaplacement);\n\n#endif\n}\n\nvoid ApplyMessage(PVideoFrame* frame, const VideoInfo& vi, const char* message, int size,\n  int textcolor, int halocolor, int bgcolor, IScriptEnvironment* env) {\n  // Simply call ApplyMessageEx with utf8=false\n  ApplyMessageEx(frame, vi, message, size, textcolor, halocolor, bgcolor, false /*utf8*/, env);\n}\n\n"
  },
  {
    "path": "avs_core/filters/text-overlay.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Text_overlay_H__\n#define __Text_overlay_H__\n\n#include <avisynth.h>\n\n#ifdef AVS_WINDOWS\n    #include <avs/win.h>\n#else\n    #include <avs/posix.h>\n#endif\n\n#include <cstdio>\n#include <stdint.h>\n#include <string>\n#include \"../core/info.h\"\n\n\n/********************************************************************\n********************************************************************/\n\n\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\nclass Antialiaser\n/**\n  * Helper class to anti-alias text\n **/\n{\npublic:\n  Antialiaser(int width, int height, const char fontname[], int size, \n    int textcolor, int halocolor, bool _bold, bool _italic, bool _noaa, int font_width=0, int font_angle=0, bool _interlaced=false);\n  virtual ~Antialiaser();\n  HDC GetDC();\n  void FreeDC();\n\n  void Apply(const VideoInfo& vi, PVideoFrame* frame, int pitch);\n\nprivate:\n  void ApplyYV12(BYTE* buf, int pitch, int UVpitch,BYTE* bufV,BYTE* bufU);\n  template<int shiftX, int shiftY, int bits_per_pixel>\n  void ApplyPlanar_core(BYTE* buf, int pitch, int UVpitch,BYTE* bufV,BYTE* bufU,bool isRGB);\n  void ApplyPlanar(BYTE* buf, int pitch, int UVpitch,BYTE* bufV,BYTE* bufU, int shiftX, int shiftY, int pixelsize, bool isRGB);\n  void ApplyYUY2(BYTE* buf, int pitch);\n\n  template<typename pixel_t, bool has_alpha>\n  void ApplyRGB_packed(BYTE* buf, int pitch);\n\n  void* lpAntialiasBits;\n  unsigned short* alpha_calcs;\n  HDC hdcAntialias;\n  HBITMAP hbmAntialias;\n  HFONT hfontDefault;\n  HBITMAP hbmDefault;\n  const int w, h;\n  const int textcolor, halocolor;\n  int xl, yt, xr, yb; // sub-rectangle containing live text\n  bool dirty, interlaced;\n  bool bold, italic;\n  bool noaa;\n\n  void GetAlphaRect();\n};\n#endif\n\n\nclass ShowFrameNumber : public GenericVideoFilter\n/**\n  * Class to display frame number on a video clip\n **/\n{\npublic:\n  ShowFrameNumber(PClip _child, bool _scroll, int _offset, int _x, int _y, const char _fontname[], int _size,\n      int _textcolor, int _halocolor, int font_width, int font_angle, bool _bold, bool _italic, bool _noaa, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_MULTI_INSTANCE : 0;\n      // Antialiaser usage -> MT_MULTI_INSTANCE (with NICE_FILTER rect area conflicts)\n  }\n\nprivate:\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  Antialiaser antialiaser;\n#else\n  std::unique_ptr<BitmapFont> current_font;\n  int chromaplacement;\n#endif\n  const bool scroll;\n  const int offset;\n  const int size, x, y;\n  const int textcolor, halocolor;\n  [[maybe_unused]] const bool bold;\n  [[maybe_unused]] const bool italic; // n/a in NO_WIN_GDI\n  [[maybe_unused]] const bool noaa; // n/a in NO_WIN_GDI\n};\n\nclass ShowCRC32 : public GenericVideoFilter\n  /**\n    * Class to display frame number on a video clip\n   **/\n{\n  uint32_t crc32_table[256];\n\n  void build_crc32_table(void);\n\npublic:\n  ShowCRC32(PClip _child, bool _scroll, int _offset, int _x, int _y, const char _fontname[], int _size,\n            int _textcolor, int _halocolor, int font_width, int font_angle, bool _bold, bool _italic, bool _noaa, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_MULTI_INSTANCE : 0;\n    // Antialiaser usage -> MT_MULTI_INSTANCE (with NICE_FILTER rect area conflicts)\n  }\n\nprivate:\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  Antialiaser antialiaser;\n#else\n  std::unique_ptr<BitmapFont> current_font;\n  int chromaplacement;\n#endif\n  const bool scroll;\n  const int offset;\n  const int size, x, y;\n  const int textcolor, halocolor;\n  [[maybe_unused]] const bool bold;\n  [[maybe_unused]] const bool italic; // n/a in NO_WIN_GDI\n  [[maybe_unused]] const bool noaa; // n/a in NO_WIN_GDI\n};\n\n\n\nclass ShowSMPTE : public GenericVideoFilter\n/**\n  * Class to display SMPTE codes on a video clip\n **/\n{\npublic:\n  ShowSMPTE(PClip _child, double _rate, const char* _offset, int _offset_f, int _x, int _y, const char _fontname[], int _size,\n            int _textcolor, int _halocolor, int font_width, int font_angle, bool _bold, bool _italic, bool _noaa, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  static AVSValue __cdecl CreateSMTPE(AVSValue args, void*, IScriptEnvironment* env);\n  static AVSValue __cdecl CreateTime(AVSValue args, void*, IScriptEnvironment* env);\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_MULTI_INSTANCE : 0;\n      // Antialiaser usage -> MT_MULTI_INSTANCE (with NICE_FILTER rect area conflicts)\n  }\n\nprivate:\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  Antialiaser antialiaser;\n#else\n  std::unique_ptr<BitmapFont> current_font;\n  int chromaplacement;\n#endif\n  int rate;\n  int offset_f;\n  const int x, y;\n  bool dropframe;\n  const int textcolor, halocolor;\n  [[maybe_unused]] const bool bold;\n  [[maybe_unused]] const bool italic; // n/a in NO_WIN_GDI\n  [[maybe_unused]] const bool noaa; // n/a in NO_WIN_GDI\n};\n\n\n\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\nclass Subtitle : public GenericVideoFilter\n/**\n  * Subtitle creation class\n **/\n{\npublic:\n  Subtitle( PClip _child, const char _text[], int _x, int _y, int _firstframe, int _lastframe,\n            const char _fontname[], int _size, int _textcolor, int _halocolor, int _align,\n            int _spc, bool _multiline, int _lsp, int _font_width, int _font_angle, bool _interlaced, const char _font_filename[], const bool _utf8,\n            const bool _bold, const bool _italic, const bool _noaa, IScriptEnvironment* env);\n  virtual ~Subtitle(void);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_MULTI_INSTANCE : 0;\n      // Antialiaser usage -> MT_MULTI_INSTANCE (with NICE_FILTER rect area conflicts)\n  }\n\nprivate:\n  void InitAntialiaser(IScriptEnvironment* env);\n\n  const int x, y, firstframe, lastframe, size, lsp, font_width, font_angle;\n  const bool multiline, interlaced;\n  const int textcolor, halocolor, align, spc;\n  const char* const fontname;\n  const char* const text;\n  const char* const font_filename;\n  const bool utf8;\n  const bool bold;\n  const bool italic;\n  const bool noaa;\n  Antialiaser* antialiaser;\n};\n#endif\n\nclass SimpleText : public GenericVideoFilter\n  /**\n    * SimpleText creation class\n   **/\n{\npublic:\n  SimpleText(PClip _child, const char _text[], int _x, int _y, int _firstframe, int _lastframe,\n    const char _fontname[], int _size, int _textcolor, int _halocolor, int _align,\n    int _spc, bool _multiline, int _lsp, int _font_width, int _font_angle, bool _interlaced, const char _font_filename[],\n    const bool _utf8, const bool _bold, const int _chromalocation,\n    IScriptEnvironment* env);\n  virtual ~SimpleText(void);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\nprivate:\n  const int x, y, firstframe, lastframe;\n  const int size;\n  const int lsp;\n  // const int font_width, font_angle; // n/a\n  const bool multiline;\n  // const bool interlaced; // n/a\n  const int textcolor, halocolor, align;\n  // const int spc; // n/a\n  const int halocolor_orig;\n  const char* const fontname; // Terminus or info_h\n  const char* const text;\n  const char* const font_filename; // .BDF files\n  const bool utf8;\n  const bool bold;\n  const int chromalocation;\n  std::unique_ptr<BitmapFont> current_font;\n};\n\nclass FilterInfo : public GenericVideoFilter\n/**\n  * FilterInfo creation class\n **/\n{\npublic:\n  FilterInfo( PClip _child, const char _fontname[], int _size, int _textcolor, int _halocolor, bool _bold, bool _italic, bool _noaa, bool _cpu, int _x, int _y, int _align, IScriptEnvironment* env);\n  virtual ~FilterInfo(void);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n  bool __stdcall GetParity(int n) override;\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_MULTI_INSTANCE : 0;\n      // Antialiaser usage -> MT_MULTI_INSTANCE (with NICE_FILTER rect area conflicts)\n  }\n\nprivate:\n  const VideoInfo& AdjustVi();\n\n  const VideoInfo &vii;\n\n  const int size;\n\n  const int text_color, halo_color;\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  Antialiaser antialiaser;\n#else\n  std::unique_ptr<BitmapFont> current_font;\n  int chromaplacement;\n#endif\n  [[maybe_unused]] const bool bold;\n  [[maybe_unused]] const bool italic;\n  [[maybe_unused]] const bool noaa;\n  const bool cpu;\n  const int x, y;\n  const int align;\n};\n\n\nclass Compare : public GenericVideoFilter\n/**\n  * Compare two clips frame by frame and display fidelity measurements (with optionnal logging to file)\n **/\n{\npublic:\n  Compare(PClip _child1, PClip _child2, const char* channels, const char *fname, bool _show_graph, IScriptEnvironment* env);\n  ~Compare();\n  static AVSValue __cdecl Create(AVSValue args, void* , IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_SERIALIZED : 0;\n      // Antialiaser usage -> MT_MULTI_INSTANCE (with NICE_FILTER rect area conflicts)\n      // show_graph gathers data of last n frames inside class -> conditional MT_SERIALIZED\n      // logfile writing: if log -> conditional MT_SERIALIZED\n      // display of global counters -> MT_SERIALIZED\n      // So least common multiple -> MT_SERIALIZED\n  }\n\n\nprivate:\n#if defined(AVS_WINDOWS) && !defined(NO_WIN_GDI)\n  Antialiaser antialiaser;\n#else\n  std::unique_ptr<BitmapFont> current_font;\n  int chromaplacement;\n#endif\n  PClip child2;\n  uint32_t mask;\n  uint64_t mask64;\n  int masked_bytes;\n  FILE* log;\n  int* psnrs;\n  bool show_graph;\n  double PSNR_min, PSNR_tot, PSNR_max;\n  double MAD_min, MAD_tot, MAD_max;\n  double MD_min, MD_tot, MD_max;\n  double bytecount_overall, SSD_overall;\n  int framecount;\n  int planar_plane;\n  int pixelsize;\n  int bits_per_pixel;\n  const int text_color, halo_color;\n\n};\n\n\n\n/**** Helper functions ****/\n\nvoid ApplyMessage( PVideoFrame* frame, const VideoInfo& vi, const char* message, int size,\n                   int textcolor, int halocolor, int bgcolor, IScriptEnvironment* env );\n\nbool GetTextBoundingBox( const char* text, const char* fontname, int size, bool bold,\n                         bool italic, int align, int* width, int* height );\n\nbool GetTextBoundingBoxFixed(const char* text, const char* fontname, int size, bool bold,\n  bool italic, int align, int& width, int& height, bool utf8);\n\n#endif  // __Text_overlay_H__\n"
  },
  {
    "path": "avs_core/filters/transform.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include \"transform.h\"\n#include \"../convert/convert_matrix.h\"\n#include \"../convert/convert_helper.h\"\n#include <avs/minmax.h>\n#include \"../core/bitblt.h\"\n#include <stdint.h>\n#include \"resample_functions.h\"\n#include \"../convert/convert_planar.h\"\n#include \"combine.h\"\n#include <vector>\n#include <cmath>\n\n\n\n/********************************************************************\n***** Declare index of new filters for Avisynth's filter engine *****\n********************************************************************/\n\nextern const AVSFunction Transform_filters[] = {\n  { \"FlipVertical\",   BUILTIN_FUNC_PREFIX, \"c\", FlipVertical::Create },\n  { \"FlipHorizontal\", BUILTIN_FUNC_PREFIX, \"c\", FlipHorizontal::Create },\n  { \"Crop\",           BUILTIN_FUNC_PREFIX, \"ciiii[align]b\", Crop::Create },              // left, top, width, height *OR*\n                                                  //  left, top, -right, -bottom (VDub style)\n  { \"CropBottom\", BUILTIN_FUNC_PREFIX, \"ci\", Create_CropBottom },      // bottom amount\n  { \"AddBorders\", BUILTIN_FUNC_PREFIX, \"ciiii[color]i[color_yuv]i[resample]s[param1]f[param2]f[param3]f[r]i\", AddBorders::Create },  // left, top, right, bottom [,color] [,color_yuv]\n  { \"Letterbox\",  BUILTIN_FUNC_PREFIX, \"cii[x1]i[x2]i[color]i[color_yuv]i[resample]s[param1]f[param2]f[param3]f[r]i\", Create_Letterbox },       // top, bottom, [left], [right] [,color] [,color_yuv]\n  { 0 }\n};\n\n\n\n\n\n/********************************\n *******   Flip Vertical   ******\n ********************************/\n\nPVideoFrame FlipVertical::GetFrame(int n, IScriptEnvironment* env) {\n  PVideoFrame src = child->GetFrame(n, env);\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n  const BYTE* srcp = src->GetReadPtr();\n  BYTE* dstp = dst->GetWritePtr();\n  int row_size = src->GetRowSize();\n  int src_pitch = src->GetPitch();\n  int dst_pitch = dst->GetPitch();\n  env->BitBlt(dstp, dst_pitch, srcp + (vi.height-1) * src_pitch, -src_pitch, row_size, vi.height);\n\n  bool isRGBPfamily = vi.IsPlanarRGB() || vi.IsPlanarRGBA();\n  int planeUB = isRGBPfamily ? PLANAR_B : PLANAR_U;\n  int planeVR = isRGBPfamily ? PLANAR_R : PLANAR_V;\n\n  if (src->GetPitch(planeUB)) {\n    srcp = src->GetReadPtr(planeUB);\n    dstp = dst->GetWritePtr(planeUB);\n    row_size = src->GetRowSize(planeUB);\n    src_pitch = src->GetPitch(planeUB);\n    dst_pitch = dst->GetPitch(planeUB);\n    env->BitBlt(dstp, dst_pitch, srcp + (src->GetHeight(planeUB)-1) * src_pitch, -src_pitch, row_size, src->GetHeight(planeUB));\n\n    srcp = src->GetReadPtr(planeVR);\n    dstp = dst->GetWritePtr(planeVR);\n    env->BitBlt(dstp, dst_pitch, srcp + (src->GetHeight(planeVR)-1) * src_pitch, -src_pitch, row_size, src->GetHeight(planeVR));\n\n    if (vi.IsYUVA() || vi.IsPlanarRGBA())\n    {\n      srcp = src->GetReadPtr(PLANAR_A);\n      dstp = dst->GetWritePtr(PLANAR_A);\n      row_size = src->GetRowSize(PLANAR_A);\n      src_pitch = src->GetPitch(PLANAR_A);\n      dst_pitch = dst->GetPitch(PLANAR_A);\n      env->BitBlt(dstp, dst_pitch, srcp + (src->GetHeight(PLANAR_A)-1) * src_pitch, -src_pitch, row_size, src->GetHeight(PLANAR_A));\n    }\n  }\n  return dst;\n}\n\nAVSValue __cdecl FlipVertical::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  AVS_UNUSED(env);\n  return new FlipVertical(args[0].AsClip());\n}\n\n\n\n/********************************\n *******   Flip Horizontal   ******\n ********************************/\n\ntemplate<typename pixel_t>\nstatic void flip_horizontal_plane_c(BYTE* dstp, const BYTE* srcp, int dst_pitch, int src_pitch, int width, int height) {\n  width = width / sizeof(pixel_t); // width is called with GetRowSize value\n  dstp += (width - 1) * sizeof(pixel_t);\n  for (int y = 0; y < height; y++) { // Loop planar luma.\n    for (int x = 0; x < width; x++) {\n      (reinterpret_cast<pixel_t *>(dstp))[-x] = (reinterpret_cast<const pixel_t *>(srcp))[x];\n    }\n    srcp += src_pitch;\n    dstp += dst_pitch;\n  }\n}\n\nPVideoFrame FlipHorizontal::GetFrame(int n, IScriptEnvironment* env) {\n  PVideoFrame src = child->GetFrame(n, env);\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n  const BYTE* srcp = src->GetReadPtr();\n  BYTE* dstp = dst->GetWritePtr();\n  int width = src->GetRowSize();\n  int src_pitch = src->GetPitch();\n  int dst_pitch = dst->GetPitch();\n  int height = src->GetHeight();\n  if (vi.IsYUY2()) { // Avoid flipping UV in YUY2 mode.\n    srcp += width;\n    srcp -= 4;\n    for (int y = 0; y<height; y++) {\n      for (int x = 0; x<width; x += 4) {\n        dstp[x] = srcp[-x+2];\n        dstp[x+1] = srcp[-x+1];\n        dstp[x+2] = srcp[-x];\n        dstp[x+3] = srcp[-x+3];\n      }\n      srcp += src_pitch;\n      dstp += dst_pitch;\n    }\n    return dst;\n  }\n\n  typedef void(*FlipFuncPtr) (BYTE * dstp, const BYTE * srcp, int dst_pitch, int src_pitch, int width, int height);\n  FlipFuncPtr flip_h_func;\n\n  if (vi.IsPlanar()) {\n    switch (vi.ComponentSize()) // AVS16\n    {\n    case 1: flip_h_func = flip_horizontal_plane_c<uint8_t>; break;\n    case 2: flip_h_func = flip_horizontal_plane_c<uint16_t>; break;\n    default: // 4 float\n       flip_h_func = flip_horizontal_plane_c<float>; break;\n    }\n    flip_h_func(dstp, srcp, dst_pitch, src_pitch, width, height);\n\n    bool isRGBPfamily = vi.IsPlanarRGB() || vi.IsPlanarRGBA();\n    int planeUB = isRGBPfamily ? PLANAR_B : PLANAR_U;\n    int planeVR = isRGBPfamily ? PLANAR_R : PLANAR_V;\n\n    if (src->GetPitch(planeUB)) {\n      srcp = src->GetReadPtr(planeUB);\n      dstp = dst->GetWritePtr(planeUB);\n      width = src->GetRowSize(planeUB);\n      src_pitch = src->GetPitch(planeUB);\n      dst_pitch = dst->GetPitch(planeUB);\n      height = src->GetHeight(planeUB);\n      flip_h_func(dstp, srcp, dst_pitch, src_pitch, width, height);\n\n      srcp = src->GetReadPtr(planeVR);\n      dstp = dst->GetWritePtr(planeVR);\n\n      flip_h_func(dstp, srcp, dst_pitch, src_pitch, width, height);\n\n      if (vi.IsYUVA() || vi.IsPlanarRGBA())\n      {\n        srcp = src->GetReadPtr(PLANAR_A);\n        dstp = dst->GetWritePtr(PLANAR_A);\n        width = src->GetRowSize(PLANAR_A);\n        src_pitch = src->GetPitch(PLANAR_A);\n        dst_pitch = dst->GetPitch(PLANAR_A);\n        height = src->GetHeight(PLANAR_A);\n        flip_h_func(dstp, srcp, dst_pitch, src_pitch, width, height);\n      }\n    }\n    return dst;\n  }\n\n  // width is GetRowSize\n  if (vi.IsRGB32()) { // fast method\n    flip_h_func = flip_horizontal_plane_c<uint32_t>;\n    flip_h_func(dstp, srcp, dst_pitch, src_pitch, width, height);\n  }\n  else if (vi.IsRGB64()) {\n    flip_h_func = flip_horizontal_plane_c<uint64_t>;\n    flip_h_func(dstp, srcp, dst_pitch, src_pitch, width, height);\n  }\n  else if (vi.IsRGB24()) {\n    dstp += width - 3;\n    for (int y = 0; y < height; y++) {\n      for (int x = 0; x < width; x += 3) {\n          dstp[-x + 0] = srcp[x + 0];\n          dstp[-x + 1] = srcp[x + 1];\n          dstp[-x + 2] = srcp[x + 2];\n      }\n      srcp += src_pitch;\n      dstp += dst_pitch;\n    }\n  }\n  else if (vi.IsRGB48()) {\n    dstp += width - 3 * sizeof(uint16_t);\n    for (int y = 0; y < height; y++) {\n      for (int x = 0; x < width / 2 /*sizeof(uint16_t)*/; x += 3) {\n        reinterpret_cast<uint16_t*>(dstp)[-x + 0] = reinterpret_cast<const uint16_t*>(srcp)[x + 0];\n        reinterpret_cast<uint16_t*>(dstp)[-x + 1] = reinterpret_cast<const uint16_t*>(srcp)[x + 1];\n        reinterpret_cast<uint16_t*>(dstp)[-x + 2] = reinterpret_cast<const uint16_t*>(srcp)[x + 2];\n      }\n      srcp += src_pitch;\n      dstp += dst_pitch;\n    }\n  }\n  return dst;\n}\n\n\nAVSValue __cdecl FlipHorizontal::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  AVS_UNUSED(env);\n  return new FlipHorizontal(args[0].AsClip());\n}\n\n\n\n\n\n/******************************\n *******   Crop Filter   ******\n *****************************/\n\nCrop::Crop(int _left, int _top, int _width, int _height, bool _align, PClip _child, IScriptEnvironment* env)\n : GenericVideoFilter(_child), align(FRAME_ALIGN - 1), xsub(0), ysub(0)\n{\n  AVS_UNUSED(_align);\n  // _align parameter exists only for the backward compatibility.\n\n  /* Negative values -> VDub-style syntax\n     Namely, Crop(a, b, -c, -d) will crop c pixels from the right and d pixels from the bottom.\n     Flags on 0 values too since AFAICT it's much more useful to this syntax than the standard one. */\n  if ( (_left<0) || (_top<0) )\n    env->ThrowError(\"Crop: Top and Left must be more than 0\");\n\n  if (_width <= 0)\n      _width = vi.width - _left + _width;\n  if (_height <= 0)\n      _height = vi.height - _top + _height;\n\n  if (_width <=0)\n    env->ThrowError(\"Crop: Destination width is 0 or less.\");\n\n  if (_height<=0)\n    env->ThrowError(\"Crop: Destination height is 0 or less.\");\n\n  if (_left + _width > vi.width || _top + _height > vi.height)\n    env->ThrowError(\"Crop: you cannot use crop to enlarge or 'shift' a clip\");\n\n  isRGBPfamily = vi.IsPlanarRGB() || vi.IsPlanarRGBA();\n  hasAlpha = vi.IsPlanarRGBA() || vi.IsYUVA();\n\n  if (vi.IsYUV() || vi.IsYUVA()) {\n    if (vi.NumComponents() > 1) {\n      xsub=vi.GetPlaneWidthSubsampling(PLANAR_U);\n      ysub=vi.GetPlaneHeightSubsampling(PLANAR_U);\n    }\n    const int xmask = (1 << xsub) - 1;\n    const int ymask = (1 << ysub) - 1;\n\n    // YUY2, etc, ... can only crop to even pixel boundaries horizontally\n    if (_left   & xmask)\n      env->ThrowError(\"Crop: YUV image can only be cropped by Mod %d (left side).\", xmask+1);\n    if (_width  & xmask)\n      env->ThrowError(\"Crop: YUV image can only be cropped by Mod %d (right side).\", xmask+1);\n    if (_top    & ymask)\n      env->ThrowError(\"Crop: YUV image can only be cropped by Mod %d (top).\", ymask+1);\n    if (_height & ymask)\n      env->ThrowError(\"Crop: YUV image can only be cropped by Mod %d (bottom).\", ymask+1);\n  } else if (!isRGBPfamily) {\n    // RGB is upside-down\n    _top = vi.height - _height - _top;\n  }\n\n  left_bytes = vi.BytesFromPixels(_left);\n  top = _top;\n  vi.width = _width;\n  vi.height = _height;\n\n}\n\n\nPVideoFrame Crop::GetFrame(int n, IScriptEnvironment* env_)\n{\n  InternalEnvironment* IEnv = GetAndRevealCamouflagedEnv(env_); // though here a static cast would do\n  IScriptEnvironment* env = static_cast<IScriptEnvironment*>(IEnv);\n\n  PVideoFrame frame = child->GetFrame(n, env);\n\n  int plane0 = isRGBPfamily ? PLANAR_G : PLANAR_Y;\n  int plane1 = isRGBPfamily ? PLANAR_B : PLANAR_U;\n  int plane2 = isRGBPfamily ? PLANAR_R : PLANAR_V;\n\n  const BYTE* srcp0 = frame->GetReadPtr(plane0) + top *  frame->GetPitch(plane0) + left_bytes;\n  const BYTE* srcp1 = frame->GetReadPtr(plane1) + (top>>ysub) *  frame->GetPitch(plane1) + (left_bytes>>xsub);\n  const BYTE* srcp2 = frame->GetReadPtr(plane2) + (top>>ysub) *  frame->GetPitch(plane2) + (left_bytes>>xsub);\n\n  size_t _align;\n\n  if (frame->GetPitch(plane1) && (!vi.IsYV12() || env->PlanarChromaAlignment(IScriptEnvironment::PlanarChromaAlignmentTest)))\n    _align = this->align & ((size_t)srcp0|(size_t)srcp1|(size_t)srcp2);\n  else\n    _align = this->align & (size_t)srcp0;\n\n  // Ignore alignment for CUDA. Clip should be explicitly aligned by Align()\n  if (0 != _align && (IEnv->GetDeviceType() == DEV_TYPE_CPU)) {\n    PVideoFrame dst = env->NewVideoFrameP(vi, &frame, (int)align+1);\n\n    env->BitBlt(dst->GetWritePtr(plane0), dst->GetPitch(plane0), srcp0,\n      frame->GetPitch(plane0), dst->GetRowSize(plane0), dst->GetHeight(plane0));\n\n    env->BitBlt(dst->GetWritePtr(plane1), dst->GetPitch(plane1), srcp1,\n      frame->GetPitch(plane1), dst->GetRowSize(plane1), dst->GetHeight(plane1));\n\n    env->BitBlt(dst->GetWritePtr(plane2), dst->GetPitch(plane2), srcp2,\n      frame->GetPitch(plane2), dst->GetRowSize(plane2), dst->GetHeight(plane2));\n\n    if(hasAlpha)\n      env->BitBlt(dst->GetWritePtr(PLANAR_A), dst->GetPitch(PLANAR_A), frame->GetReadPtr(PLANAR_A) + top *  frame->GetPitch(PLANAR_A) + left_bytes,\n        frame->GetPitch(PLANAR_A), dst->GetRowSize(PLANAR_A), dst->GetHeight(PLANAR_A));\n\n    return dst;\n  }\n\n  // subframe is preserving frame properties\n  if (!frame->GetPitch(plane1))\n    return env->Subframe(frame, top * frame->GetPitch() + left_bytes, frame->GetPitch(), vi.RowSize(), vi.height);\n  else {\n    if (hasAlpha) {\n\n      return env->SubframePlanarA(frame, top * frame->GetPitch() + left_bytes, frame->GetPitch(), vi.RowSize(), vi.height,\n        (top >> ysub) * frame->GetPitch(plane1) + (left_bytes >> xsub),\n        (top >> ysub) * frame->GetPitch(plane2) + (left_bytes >> xsub),\n        frame->GetPitch(plane1), top * frame->GetPitch(PLANAR_A) + left_bytes);\n    }\n    else {\n      return env->SubframePlanar(frame, top * frame->GetPitch() + left_bytes, frame->GetPitch(), vi.RowSize(), vi.height,\n        (top >> ysub) * frame->GetPitch(plane1) + (left_bytes >> xsub),\n        (top >> ysub) * frame->GetPitch(plane2) + (left_bytes >> xsub),\n        frame->GetPitch(plane1));\n    }\n  }\n}\n\nint __stdcall Crop::SetCacheHints(int cachehints, int frame_range) {\n  AVS_UNUSED(frame_range);\n  switch (cachehints) {\n  case CACHE_GET_MTMODE:\n    return MT_NICE_FILTER;\n  case CACHE_GET_DEV_TYPE:\n    return GetDeviceTypes(child) & (DEV_TYPE_CPU | DEV_TYPE_CUDA);\n  }\n  return 0;\n}\n\n\nAVSValue __cdecl Crop::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  return new Crop( args[1].AsInt(), args[2].AsInt(), args[3].AsInt(), args[4].AsInt(), args[5].AsBool(true),\n                   args[0].AsClip(), env );\n}\n\n\n\n\n\n/******************************\n *******   Add Borders   ******\n *****************************/\n\nAddBorders::AddBorders(int _left, int _top, int _right, int _bot, int _clr, bool _force_color_as_yuv, PClip _child, IScriptEnvironment* env)\n  : GenericVideoFilter(_child),\n  left(max(0, _left)), top(max(0, _top)), right(max(0, _right)), bot(max(0, _bot)),\n  clr(_clr),\n  xsub(0), ysub(0),\n  force_color_as_yuv(_force_color_as_yuv)\n\n{\n  if (vi.IsYUV() || vi.IsYUVA()) {\n    if (vi.NumComponents() > 1) {\n      xsub=vi.GetPlaneWidthSubsampling(PLANAR_U);\n      ysub=vi.GetPlaneHeightSubsampling(PLANAR_U);\n    }\n\n    const int xmask = (1 << xsub) - 1;\n    const int ymask = (1 << ysub) - 1;\n\n    // YUY2, etc, ... can only add even amounts\n    if (_left  & xmask)\n      env->ThrowError(\"AddBorders: YUV image can only add by Mod %d (left side).\", xmask+1);\n    if (_right & xmask)\n      env->ThrowError(\"AddBorders: YUV image can only add by Mod %d (right side).\", xmask+1);\n\n    if (_top   & ymask)\n      env->ThrowError(\"AddBorders: YUV image can only add by Mod %d (top).\", ymask+1);\n    if (_bot   & ymask)\n      env->ThrowError(\"AddBorders: YUV image can only add by Mod %d (bottom).\", ymask+1);\n  } else if (!vi.IsPlanarRGB() && !vi.IsPlanarRGBA()){\n    // RGB is upside-down\n    int t = top; top = bot; bot = t;\n  }\n  vi.width += left+right;\n  vi.height += top+bot;\n}\n\ntemplate<typename pixel_t>\nstatic inline pixel_t GetHbdColorFromByte(uint8_t color, bool fullscale, int bits_per_pixel, bool chroma)\n{\n  if constexpr(sizeof(pixel_t) == 1) return color;\n  else if constexpr(sizeof(pixel_t) == 2) return (pixel_t)(fullscale ? (color * ((1 << bits_per_pixel)-1)) / 255 : (int)color << (bits_per_pixel - 8));\n  else {\n    if (chroma)\n      return (pixel_t)uv8tof(color);  // float, scale, 128=0.0f\n    else\n      return (pixel_t)c8tof(color); // float, scale to [0..1]\n  }\n}\n\ntemplate<typename pixel_t>\nstatic void addborders_planar(PVideoFrame &dst, PVideoFrame &src, VideoInfo &vi, int top, int bot, int left, int right, int color, bool isYUV, bool force_color_as_yuv, int bits_per_pixel)\n{\n  const unsigned int colr = isYUV && !force_color_as_yuv ? RGB2YUV_Rec601(color) : color;\n  const unsigned char YBlack=(unsigned char)((colr >> 16) & 0xff);\n  const unsigned char UBlack=(unsigned char)((colr >>  8) & 0xff);\n  const unsigned char VBlack=(unsigned char)((colr      ) & 0xff);\n  const unsigned char ABlack=(unsigned char)((colr >> 24) & 0xff);\n\n  int planesYUV[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };\n  int planesRGB[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A };\n  int *planes = isYUV ? planesYUV : planesRGB;\n  uint8_t colorsYUV[4] = { YBlack, UBlack, VBlack, ABlack };\n  uint8_t colorsRGB[4] = { UBlack, VBlack, YBlack, ABlack }; // mapping for planar RGB\n  uint8_t *colors = isYUV ? colorsYUV : colorsRGB;\n  for (int p = 0; p < vi.NumComponents(); p++)\n  {\n    int plane = planes[p];\n    int src_pitch = src->GetPitch(plane);\n    int src_rowsize = src->GetRowSize(plane);\n    int src_height = src->GetHeight(plane);\n\n    int dst_pitch = dst->GetPitch(plane);\n\n    int xsub=vi.GetPlaneWidthSubsampling(plane);\n    int ysub=vi.GetPlaneHeightSubsampling(plane);\n\n    const int initial_black = (top >> ysub) * dst_pitch + vi.BytesFromPixels(left >> xsub);\n    const int middle_black = dst_pitch - src_rowsize;\n    const int final_black = (bot >> ysub) * dst_pitch + vi.BytesFromPixels(right >> xsub) +\n                             (dst_pitch - dst->GetRowSize(plane));\n\n    const bool chroma = plane == PLANAR_U || plane == PLANAR_V;\n\n    pixel_t current_color = GetHbdColorFromByte<pixel_t>(colors[p], !isYUV, bits_per_pixel, chroma);\n\n    BYTE *dstp = dst->GetWritePtr(plane);\n    // copy original\n    BitBlt(dstp+initial_black, dst_pitch, src->GetReadPtr(plane), src_pitch, src_rowsize, src_height);\n    // add top\n    for (size_t a = 0; a<initial_black / sizeof(pixel_t); a++) {\n      reinterpret_cast<pixel_t *>(dstp)[a] = current_color;\n    }\n    // middle right + left (fill overflows from right to left)\n    dstp += initial_black + src_rowsize;\n    for (int y = src_height-1; y>0; --y) {\n      for (size_t b = 0; b<middle_black / sizeof(pixel_t); b++) {\n        reinterpret_cast<pixel_t *>(dstp)[b] = current_color;\n      }\n      dstp += dst_pitch;\n    }\n    // bottom\n    for (size_t c = 0; c<final_black / sizeof(pixel_t); c++)\n      reinterpret_cast<pixel_t *>(dstp)[c] = current_color;\n  }\n}\n\nPVideoFrame AddBorders::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame src = child->GetFrame(n, env);\n  PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n\n  if (vi.IsPlanar()) {\n    int bits_per_pixel = vi.BitsPerComponent();\n    bool isYUV = vi.IsYUV() || vi.IsYUVA();\n    switch(vi.ComponentSize()) {\n    case 1: addborders_planar<uint8_t>(dst, src, vi, top, bot, left, right, clr, isYUV, force_color_as_yuv /*like MODE_COLOR_YUV in BlankClip */, bits_per_pixel); break;\n    case 2: addborders_planar<uint16_t>(dst, src, vi, top, bot, left, right,  clr, isYUV, force_color_as_yuv, bits_per_pixel); break;\n    default: //case 4:\n      addborders_planar<float>(dst, src, vi, top, bot, left, right, clr, isYUV, force_color_as_yuv, bits_per_pixel); break;\n    }\n    return dst;\n  }\n\n  const BYTE* srcp = src->GetReadPtr();\n  BYTE* dstp = dst->GetWritePtr();\n  const int src_pitch = src->GetPitch();\n  const int dst_pitch = dst->GetPitch();\n  const int src_row_size = src->GetRowSize();\n  const int dst_row_size = dst->GetRowSize();\n  const int src_height = src->GetHeight();\n\n  const int initial_black = top * dst_pitch + vi.BytesFromPixels(left);\n  const int middle_black = dst_pitch - src_row_size;\n  const int final_black = bot * dst_pitch + vi.BytesFromPixels(right)\n    + (dst_pitch - dst_row_size);\n\n  if (vi.IsYUY2()) {\n    const unsigned int colr = force_color_as_yuv ? clr : RGB2YUV_Rec601(clr);\n    const uint32_t black = (colr>>16) * 0x010001 + ((colr>>8)&255) * 0x0100 + (colr&255) * 0x01000000;\n\n    BitBlt(dstp+initial_black, dst_pitch, srcp, src_pitch, src_row_size, src_height);\n    for (int a = 0; a<initial_black; a += 4) {\n      *(uint32_t*)(dstp+a) = black;\n    }\n    dstp += initial_black + src_row_size;\n    for (int y = src_height-1; y>0; --y) {\n      for (int b = 0; b<middle_black; b += 4) {\n        *(uint32_t*)(dstp+b) = black;\n      }\n      dstp += dst_pitch;\n    }\n    for (int c = 0; c<final_black; c += 4) {\n      *(uint32_t*)(dstp+c) = black;\n    }\n  } else if (vi.IsRGB24()) {\n    const unsigned char  clr0 = (unsigned char)(clr & 0xFF);\n    const unsigned short clr1 = (unsigned short)(clr >> 8);\n    const int leftbytes = vi.BytesFromPixels(left);\n    const int leftrow = src_row_size + leftbytes;\n    const int rightbytes = vi.BytesFromPixels(right);\n    const int rightrow = dst_pitch - dst_row_size + rightbytes;\n\n    BitBlt(dstp+initial_black, dst_pitch, srcp, src_pitch, src_row_size, src_height);\n    /* Cannot use *_black optimisation as pitch may not be mod 3 */\n    for (int y = top; y>0; --y) {\n      for (int i = 0; i<dst_row_size; i += 3) {\n        dstp[i] = clr0;\n        *(uint16_t*)(dstp+i+1) = clr1;\n      }\n      dstp += dst_pitch;\n    }\n    for (int y = src_height; y>0; --y) {\n      for (int i = 0; i<leftbytes; i += 3) {\n        dstp[i] = clr0;\n        *(uint16_t*)(dstp+i+1) = clr1;\n      }\n      dstp += leftrow;\n      for (int i = 0; i<rightbytes; i += 3) {\n        dstp[i] = clr0;\n        *(uint16_t*)(dstp+i+1) = clr1;\n      }\n      dstp += rightrow;\n    }\n    for (int y = bot; y>0; --y) {\n      for (int i = 0; i<dst_row_size; i += 3) {\n        dstp[i] = clr0;\n        *(uint16_t*)(dstp+i+1) = clr1;\n      }\n      dstp += dst_pitch;\n    }\n  }\n  else if (vi.IsRGB32()) {\n    BitBlt(dstp+initial_black, dst_pitch, srcp, src_pitch, src_row_size, src_height);\n    for (int i = 0; i<initial_black; i += 4) {\n      *(uint32_t*)(dstp+i) = clr;\n    }\n    dstp += initial_black + src_row_size;\n    for (int y = src_height-1; y>0; --y) {\n      for (int i = 0; i<middle_black; i += 4) {\n        *(uint32_t*)(dstp+i) = clr;\n      }\n      dstp += dst_pitch;\n    } // for y\n    for (int i = 0; i<final_black; i += 4) {\n      *(uint32_t*)(dstp+i) = clr;\n    }\n  } else if (vi.IsRGB48()) {\n    const uint16_t  clr0 = GetHbdColorFromByte<uint16_t>(clr & 0xFF, true, 16, false);\n    uint32_t clr1 =\n      ((uint32_t)GetHbdColorFromByte<uint16_t>((clr >> 16) & 0xFF, true, 16, false) << (8 * 2)) +\n      ((uint32_t)GetHbdColorFromByte<uint16_t>((clr >> 8) & 0xFF, true, 16, false));\n    const int leftbytes = vi.BytesFromPixels(left);\n    const int leftrow = src_row_size + leftbytes;\n    const int rightbytes = vi.BytesFromPixels(right);\n    const int rightrow = dst_pitch - dst_row_size + rightbytes;\n\n    BitBlt(dstp+initial_black, dst_pitch, srcp, src_pitch, src_row_size, src_height);\n    /* Cannot use *_black optimisation as pitch may not be mod 3 */\n    for (int y = top; y>0; --y) {\n      for (int i = 0; i<dst_row_size; i += 6) {\n        *(uint16_t*)(dstp+i) = clr0;\n        *(uint32_t*)(dstp+i+2) = clr1;\n      }\n      dstp += dst_pitch;\n    }\n    for (int y = src_height; y>0; --y) {\n      for (int i = 0; i<leftbytes; i += 6) {\n        *(uint16_t*)(dstp+i) = clr0;\n        *(uint32_t*)(dstp+i+2) = clr1;\n      }\n      dstp += leftrow;\n      for (int i = 0; i<rightbytes; i += 6) {\n        *(uint16_t*)(dstp+i) = clr0;\n        *(uint32_t*)(dstp+i+2) = clr1;\n      }\n      dstp += rightrow;\n    }\n    for (int y = bot; y>0; --y) {\n      for (int i = 0; i<dst_row_size; i += 6) {\n        *(uint16_t*)(dstp+i) = clr0;\n        *(uint32_t*)(dstp+i+2) = clr1;\n      }\n      dstp += dst_pitch;\n    }\n  } else if (vi.IsRGB64()) {\n    BitBlt(dstp+initial_black, dst_pitch, srcp, src_pitch, src_row_size, src_height);\n\n    uint64_t clr64 =\n      ((uint64_t)GetHbdColorFromByte<uint16_t>((clr >> 24) & 0xFF, true, 16, false) << (24 * 2)) +\n      ((uint64_t)GetHbdColorFromByte<uint16_t>((clr >> 16) & 0xFF, true, 16, false) << (16 * 2)) +\n      ((uint64_t)GetHbdColorFromByte<uint16_t>((clr >> 8) & 0xFF, true, 16, false) << (8 * 2)) +\n      ((uint64_t)GetHbdColorFromByte<uint16_t>((clr) & 0xFF, true, 16, false));\n\n    for (int i = 0; i<initial_black; i += 8) {\n      *(uint64_t*)(dstp+i) = clr64;\n    }\n    dstp += initial_black + src_row_size;\n    for (int y = src_height-1; y>0; --y) {\n      for (int i = 0; i<middle_black; i += 8) {\n        *(uint64_t*)(dstp+i) = clr64;\n      }\n      dstp += dst_pitch;\n    } // for y\n    for (int i = 0; i<final_black; i += 8) {\n      *(uint64_t*)(dstp+i) = clr64;\n    }\n  }\n\n  return dst;\n}\n\n// Optional transient area filtering when radius > 0\n// The primary aim to blur the border neighborhood to prevent excessive ringing on\n// a following upscaleing process\nstatic PClip AddBorderPostProcess(PClip child,\n  int left, int top, int right, int bottom,\n  const AVSValue& _resample, const AVSValue& _param1, const AVSValue& _param2, const AVSValue& _param3, const AVSValue& _flt_rad,\n  int forced_chroma_placement,\n  IScriptEnvironment* env) {\n\n  // filtering radius, default 0: no transient area filtering\n  int r = _flt_rad.AsInt(0);\n\n  if (r == 0)\n    return child;\n\n  // Default: only the border side gets the blur treatment\n  // Minus \"r\": only the outer - added border - part is blurred\n  // though this is usually not enough to prevent ringing when upscaling.\n  const bool both_side = (r > 0);\n  if (r < 0)\n    r = -r;\n\n  const VideoInfo& vi = child->GetVideoInfo();\n\n  /*if (vi.IsYUY2())\n    env->ThrowError(\"AddBorders: YUY2 transient filtering not supported, use YV16.\");\n    */\n\n  AVSValue param1 = _param1;\n  AVSValue param2 = _param2;\n  AVSValue param3 = _param3;\n\n  // evaluate resample parameters only radius > 0\n  const char* resampler_name = _resample.AsString(\"gauss\");\n  if (_stricmp(resampler_name, \"gauss\") == 0) {\n    // for gauss, defaults are different from what we use in chroma resamplers.\n    // here we use this filter for blurring (convolution use)\n    // p = 10, b = 2.71828, s = 0\n    param1 = _param1.AsDblDef(10); // p\n    param2 = _param2.AsDblDef(2.718281828); // b\n    param3 = _param3.AsDblDef(0); // 0\n  }\n  ResamplingFunction* filter = getResampler(resampler_name, param1, param2, param3, false, env);\n  if (filter == nullptr)\n    env->ThrowError(\"AddBorders: unknown resampler name: %s\", resampler_name);\n\n  const bool grey = vi.IsY();\n  const bool isRGBPfamily = vi.IsPlanarRGB() || vi.IsPlanarRGBA();\n\n  const int shift_w = (vi.IsPlanar() && !grey && !isRGBPfamily) ? vi.GetPlaneWidthSubsampling(PLANAR_U) : 0;\n  const int shift_h = (vi.IsPlanar() && !grey && !isRGBPfamily) ? vi.GetPlaneHeightSubsampling(PLANAR_U) : 0;\n  const int shift = max(shift_w, shift_h); // worst case\n\n  // adjust radius for worst case chroma\n  r = (r + (1 << shift) - 1) & ~((1 << shift) - 1); // chroma friendly\n\n  const int MIN_FILTERING_EXTENT = 10; // +/-\n  // but if one of the margins are smaller, e.g. 5, the the 2*10 is achieved as 5+15 pixel wide (high) parts\n  // We always filter a larger area, but only copy the 2*radius (r) pixels from it.\n  // a radius plus the filter support size overrides\n  int filtering_width = max(MIN_FILTERING_EXTENT, r + (int)std::ceil(filter->support()));\n\n  // adjust the filtering width for the worst case, considering the chroma subsampling\n  filtering_width = (filtering_width + (1 << shift) - 1) & ~((1 << shift) - 1);\n  // active area before adding the new borders\n  const int orig_width = vi.width - left - right;\n  const int orig_height = vi.height - top - bottom;\n\n  // End of safety adjustments\n  // Radius \"r\" and \"filtering_width\" are both +/- values and are chroma and resizer friendly.\n  // left, right, top, bottom are already chroma subsample friendly values\n\n  /*\n  Create up to 8 sections.\n  \n  left, top, right, bottom and the four corner bars mark the convolution (blur) area.\n  - left and right needs only force horizontal resizer\n  - top and bottom bars force vertical resizer\n  - corners force both H and V resizer\n  +---+-------------------+\n  | oo|ooooooooooooooo|oo |\n  +-o-+-----------------o-+\n  | o |               | o |\n  | o |               | o |\n  | o |               | o |\n  | o |               | o |\n  | o |               | o |\n  | o |               | o |\n  +-o-+---------------+-o-+\n  | oo|ooooooooooooooo|oo |\n  +---+---------------+---+\n  */\n\n  typedef struct {\n    PClip clip; // a smart pointer\n    int extent_outer_horiz, extent_inner_horiz; // may not be symmetric\n    int extent_outer_vert, extent_inner_vert;\n    int crop_x, crop_y;\n    int target_x, target_y;\n    int target_width, target_height;\n    int src_x, src_y;\n    int src_width, src_height;\n    int force;\n    //  0 - return unchanged if no resize needed\n    //  1 - force H - Horizontal resizing phase, For vertical bars\n    //  2 - force V - Vertical resizing phase, For horizontal bars\n    //  3 - force H and V for corner rectangles\n  } BarSection;\n\n  std::vector<BarSection> bars;\n\n  /* Example on LEFT and RIGHT vertical bar\n  \n    extent_outer extent_inner                extent_inner extent_outer\n        <------>|<--------->                  <------>|<--------->\n\n              r*2                                   r*2 \n             |<>|<>|           orig_width          |<>|<>|\n                 <------------------------------------>\n        +----+--|--+-------+  ^               +----+--|--+-------+\n        |    |  |  |       |  |               |    |  |  |       |\n        |    |  |  |       |  |orig_height    |    |  |  |       |\n        |    |  |  |       |  |               |    |  |  |       |\n        |    |  |  |       |  |               |    |  |  |       |\n        |    |  |  |       |  |               |    |  |  |       |\n        +----+--|--+-------+  V               +----+--|--+-------+\n\n  The extent_inner+extent_outer area is cropped and blurred (filtered) with the given algoritm, e.g \"gauss\".\n  From this blurred Clip only the (2*r) * orig_height rectangle is copied back onto the transient area.\n  */\n\n  // Define bar sections data for iteration\n\n  struct BarSectionTemplate {\n    int side;           // 0=left, 1=right, 2=top, 3=bottom 4=top-left 5=top-right 6=bottom-left 7=bottom-right\n    int direction;      // 1=horizontally, 2=vertically filtere, 3=both (corners)\n  };\n\n  const BarSectionTemplate templates[] = {\n    {0, 1}, // left bar (horizontally filtered)\n    {1, 1}, // right bar (horizontally filtered)\n    {2, 2}, // top bar (vertically filtered)\n    {3, 2}, // bottom bar (vertically filtered)\n    {4, 3}, // top left rectangle (H-V filtered)\n    {5, 3}, // top right rectangle (H-V filtered)\n    {6, 3}, // bottom left rectangle (H-V filtered)\n    {7, 3}  // bottom right rectangle (H-V filtered)\n  };\n\n  // First cycle: initialize common parameters and calculate dimensions\n  for (int i = 0; i < 8; i++) {\n    BarSection bar = {};\n\n    const bool isHorizontallyFiltered = (templates[i].direction == 1) || (templates[i].direction == 3);\n    const bool isVerticallyFiltered = (templates[i].direction == 2) || (templates[i].direction == 3);\n    const int side = templates[i].side;\n\n    // Calculate border to use based on side\n    int borderSize, borderSize2;\n    switch (side) {\n    case 0: borderSize = left; borderSize2 = 0;  break;\n    case 1: borderSize = right; borderSize2 = 0; break;\n    case 2: borderSize = 0; borderSize2 = top; break;\n    case 3: borderSize = 0; borderSize2 = bottom; break;\n    case 4: borderSize = left; borderSize2 = top; break;\n    case 5: borderSize = right; borderSize2 = top; break;\n    case 6: borderSize = left;  borderSize2 = bottom; break;\n    case 7: borderSize = right; borderSize2 = bottom; break;\n    }\n\n    int safe_flt_rad = r;\n    if (borderSize > 0) { // same as isHorizontallyFiltered\n      bar.extent_outer_horiz = std::min(filtering_width, borderSize);\n      bar.extent_inner_horiz = 2 * filtering_width - bar.extent_outer_horiz;\n    }\n    if (borderSize2 > 0) { // same as(isVerticallyFiltered\n      bar.extent_outer_vert = std::min(filtering_width, borderSize2);\n      bar.extent_inner_vert = 2 * filtering_width - bar.extent_outer_vert;\n    }\n\n    if (isHorizontallyFiltered) {\n      safe_flt_rad = std::min(safe_flt_rad, borderSize);\n      bar.extent_inner_horiz = std::min(bar.extent_inner_horiz, orig_width);\n    }\n    if (isVerticallyFiltered) {\n      safe_flt_rad = std::min(safe_flt_rad, borderSize2);\n      bar.extent_inner_vert = std::min(bar.extent_inner_vert, orig_height);\n    }\n\n    int safe_flt_rad_inner = both_side ? safe_flt_rad : 0;\n\n    int safe_flt_rad_inner_horiz = std::min(bar.extent_inner_horiz, safe_flt_rad_inner);\n    int safe_flt_rad_inner_vert = std::min(bar.extent_inner_vert, safe_flt_rad_inner);\n\n    // Set force direction\n    bar.force = templates[i].direction;\n\n    // Set dimensions based on direction and side\n    if (isHorizontallyFiltered && isVerticallyFiltered) { // corners\n      bar.target_width = bar.extent_outer_horiz + bar.extent_inner_horiz;\n      bar.target_height = bar.extent_outer_vert + bar.extent_inner_vert;\n      bar.src_width = safe_flt_rad + safe_flt_rad_inner_horiz;\n      bar.src_height = safe_flt_rad + safe_flt_rad_inner_vert;\n\n      if (side == 4 || side == 6) {  // Top Left Bottom Left\n        bar.crop_x = left - bar.extent_outer_horiz;\n        bar.target_x = left - safe_flt_rad;\n        bar.src_x = bar.extent_outer_horiz - safe_flt_rad;\n      }\n      else {  // Top Right Bottom Right\n        bar.crop_x = left + orig_width - bar.extent_inner_horiz;\n        bar.target_x = left + orig_width - safe_flt_rad_inner_horiz;\n        bar.src_x = bar.extent_inner_horiz - safe_flt_rad_inner_horiz;\n      }\n\n      if (side == 4 || side == 5) {  // Top Left Top Right\n        bar.crop_y = top - bar.extent_outer_vert;\n        bar.target_y = top - safe_flt_rad;\n        bar.src_y = bar.extent_outer_vert - safe_flt_rad;\n      }\n      else {  // Bottom Left Bottom Right\n        bar.crop_y = top + orig_height - bar.extent_inner_vert;\n        bar.target_y = top + orig_height - safe_flt_rad_inner_vert;\n        bar.src_y = bar.extent_inner_vert - safe_flt_rad_inner_vert;\n      }\n    }\n    else if (isHorizontallyFiltered) {\n      // Vertical but horizontally filtered bars on the left/right side\n      bar.target_width = bar.extent_outer_horiz + bar.extent_inner_horiz;\n      bar.target_height = orig_height;\n      bar.src_width = safe_flt_rad + safe_flt_rad_inner_horiz;\n      bar.src_height = orig_height;\n\n      if (side == 0) {  // Left\n        bar.crop_x = left - bar.extent_outer_horiz;;\n        bar.crop_y = top;\n        bar.target_x = left - safe_flt_rad;\n        bar.target_y = top;\n        bar.src_x = bar.extent_outer_horiz - safe_flt_rad;\n\n      }\n      else {  // Right\n        bar.crop_x = left + orig_width - bar.extent_inner_horiz;\n        bar.crop_y = top;\n        bar.target_x = left + orig_width - safe_flt_rad_inner_horiz;\n        bar.target_y = top;\n        bar.src_x = bar.extent_inner_horiz - safe_flt_rad_inner_horiz;\n      }\n     \n      bar.src_y = 0;\n    }\n    else {\n      // Horizontal, but vertically filtered bars (top/bottom)\n      bar.target_width = orig_width;\n      bar.target_height = bar.extent_outer_vert + bar.extent_inner_vert;\n      bar.src_width = orig_width;\n      bar.src_height = safe_flt_rad + safe_flt_rad_inner_vert;\n\n      if (side == 2) {  // Top\n        bar.crop_x = left;\n        bar.crop_y = top - bar.extent_outer_vert;\n        bar.target_x = left;\n        bar.target_y = top - safe_flt_rad;\n        bar.src_y = bar.extent_outer_vert - safe_flt_rad;\n      }\n      else {  // Bottom\n        bar.crop_x = left;\n        bar.crop_y = top + orig_height - bar.extent_inner_vert;\n        bar.target_x = left;\n        bar.target_y = top + orig_height - safe_flt_rad_inner_vert;\n        bar.src_y = bar.extent_inner_vert - safe_flt_rad_inner_vert;\n      }\n\n      bar.src_x = 0;\n    }\n\n    // avoid \"Resize: Source image too small for this resize method. Width=%d, Support=%d\", source_size, int(ceil(filter_support))\"\n    // int source_size, double crop_size, int target_size\n    // all are the same here\n    // whether H or V resizing is forced, only check for that dimension\n    bool ok = true;\n    if (isHorizontallyFiltered && bar.target_width <= 0) ok = false;\n    if (isVerticallyFiltered && bar.target_height <= 0) ok = false;\n    // size is indifferent since avs 3.7.4, resizers are robust, accept anything, \n    // no other size constraint check is needed.\n\n    if(ok)\n      bars.push_back(bar);\n  }\n\n  std::vector<PClip> child_array = { child };\n  std::vector<int> position_array = { };\n\n  const bool preserve_center = true;\n  const char* placement_name = nullptr; \n  // along with forced_chroma_placement, does not read frame props again in eight child resizers\n  // _ChromaLocation - if any - was read in AddBorders - once - and passed here\n\n  for (auto& bar : bars) {\n    // or use [src_left]f[src_top]f[src_width]f[src_height]f\n    // resizer parameters set for convolution (unchanged dimensions) filter\n    /* When we directly pass source position, it's not possible to govern the directional \"force\", anyway, it would just call crop as well.\n    AVSValue args_left_top_w_h[4] = {bar.crop_x, bar.crop_y, bar.target_width, bar.target_height}; // left, top, width (auto), height (auto)\n    bar.clip = FilteredResize::CreateResize(child, bar.target_width, bar.target_height, args_left_top_w_h, bar.force, filter, env);\n    */\n    AVSValue args_left_top_w_h[4] = { 0, 0, AVSValue(), AVSValue() }; // left, top, width (auto), height (auto)\n\n    bar.clip = FilteredResize::CreateResize(\n      new Crop(bar.crop_x, bar.crop_y, bar.target_width, bar.target_height, 0, child, env),\n      bar.target_width, bar.target_height, args_left_top_w_h, bar.force, filter, \n      preserve_center, placement_name, forced_chroma_placement,\n      env);\n\n\n    // Add to vector\n    child_array.push_back(bar.clip);\n    position_array.push_back(bar.target_x);\n    position_array.push_back(bar.target_y);\n    // we can copy only a smaller part from the filtered area\n    // After blurring e.g. a 10x10 rectangle, we'd copy only from a radius of +/-1 or +/-2\n    position_array.push_back(bar.src_x);\n    position_array.push_back(bar.src_y);\n    position_array.push_back(bar.src_width);\n    position_array.push_back(bar.src_height);\n  }\n\n  PClip clip = new MultiOverlay(child_array, position_array, env);\n\n  delete filter;\n\n  return clip;\n}\n\n\nAVSValue __cdecl AddBorders::Create(AVSValue args, void*, IScriptEnvironment* env)\n{\n  // [0][1][2][3][4]  [5]       [6]        [7]       [8]       [9]      [10]  [11]\n  //  c  i  i  i  i [color]i[color_yuv]i[resample]s[param1]f[param2]f[param3]f[r]i\n  // int left, int top, int right, int bottom\n\n  // similar to BlankClip\n  int color = args[5].AsInt(0);\n  bool color_as_yuv = false;\n\n  const VideoInfo& vi = args[0].AsClip()->GetVideoInfo();\n\n  if (args[6].Defined()) {\n    if (color != 0) // Not quite 100% test\n      env->ThrowError(\"AddBorders: color and color_yuv are mutually exclusive\");\n\n    if (!vi.IsYUV() && !vi.IsYUVA())\n      env->ThrowError(\"AddBorders: color_yuv only valid for YUV color spaces\");\n    color = args[6].AsInt(); // override\n    color_as_yuv = true;\n  }\n\n  const int left = max(0, args[1].AsInt());\n  const int top = max(0, args[2].AsInt());\n  const int right = max(0, args[3].AsInt());\n  const int bottom = max(0, args[4].AsInt());\n\n  int forced_chroma_placement = ChromaLocation_e::AVS_CHROMA_UNUSED;\n  if (vi.IsYV411() || vi.Is420() || vi.Is422()) {\n     auto frame0 = args[0].AsClip()->GetFrame(0, env);\n    const AVSMap* props = env->getFramePropsRO(frame0);\n    if (props) {\n      if (env->propNumElements(props, \"_ChromaLocation\") > 0) {\n        forced_chroma_placement = (int)env->propGetIntSaturated(props, \"_ChromaLocation\", 0, nullptr);\n      }\n    }\n  }\n\n  // here we have read _ChromaLocation, in order to pass it directly to the many blurring resizers to prevent them\n  // to read up to 8x GetFrame(0) in their init for getting the same frame properties like we had.\n\n  PClip clip = new AddBorders( left, top, right, bottom, color, color_as_yuv, args[0].AsClip(), env);\n\n  // args[7], args[8], args[9], args[10], args[11], // [resample]s[param1]f[param2]f[param3]f[r]i\n\n  clip = AddBorderPostProcess(clip, left, top, right, bottom, args[7], args[8], args[9], args[10], args[11], forced_chroma_placement, env);\n\n  return clip;\n}\n\n\n/**********************************\n *******   Factory Methods   ******\n *********************************/\n\n\nAVSValue __cdecl Create_Letterbox(AVSValue args, void*, IScriptEnvironment* env)\n{\n  PClip clip = args[0].AsClip();\n  int top = args[1].AsInt();\n  int bottom = args[2].AsInt();\n  int left = args[3].AsInt(0);\n  int right = args[4].AsInt(0);\n  int color = args[5].AsInt(0);\n  const VideoInfo& vi = clip->GetVideoInfo();\n\n  // [0][1][2][3]   [4]   [5]        [6]          [7]       [8]       [9]      [10]  [11]\n  //  c  i  i [x1]i [x2]i [color]i [color_yuv]i[resample]s[param1]f[param2]f[param3]f[r]i\n  //   top, bottom, [left], [right] [,color] [,color_yuv]\n\n  // similar to BlankClip/AddBorders\n  bool color_as_yuv = false;\n  if (args[6].Defined()) {\n    if (color != 0) // Not quite 100% test\n      env->ThrowError(\"LetterBox: color and color_yuv are mutually exclusive\");\n\n    if (!vi.IsYUV() && !vi.IsYUVA())\n      env->ThrowError(\"LetterBox: color_yuv only valid for YUV color spaces\");\n    color = args[6].AsInt(); // override\n    color_as_yuv = true;\n  }\n\n  if ( (top<0) || (bottom<0) || (left<0) || (right<0) )\n    env->ThrowError(\"LetterBox: You cannot specify letterboxing less than 0.\");\n  if (top+bottom>=vi.height) // Must be >= otherwise it is interpreted wrong by crop()\n    env->ThrowError(\"LetterBox: You cannot specify letterboxing that is bigger than the picture (height).\");\n  if (right+left>=vi.width) // Must be >= otherwise it is interpreted wrong by crop()\n    env->ThrowError(\"LetterBox: You cannot specify letterboxing that is bigger than the picture (width).\");\n\n  if (vi.IsYUV() || vi.IsYUVA()) {\n    int xsub = 0;\n    int ysub = 0;\n\n    if (vi.NumComponents() > 1) {\n      xsub=vi.GetPlaneWidthSubsampling(PLANAR_U);\n      ysub=vi.GetPlaneHeightSubsampling(PLANAR_U);\n    }\n    const int xmask = (1 << xsub) - 1;\n    const int ymask = (1 << ysub) - 1;\n\n    // YUY2, etc, ... can only operate to even pixel boundaries\n    if (left  & xmask)\n      env->ThrowError(\"LetterBox: YUV images width must be divideable by %d (left side).\", xmask+1);\n    if (right & xmask)\n      env->ThrowError(\"LetterBox: YUV images width must be divideable by %d (right side).\", xmask+1);\n\n    if (top & ymask)\n      env->ThrowError(\"LetterBox: YUV images height must be divideable by %d (top).\", ymask+1);\n    if (bottom & ymask)\n      env->ThrowError(\"LetterBox: YUV images height must be divideable by %d (bottom).\", ymask+1);\n  }\n\n  left = max(0, left);\n  top = max(0, top);\n  right = max(0, right);\n  bottom = max(0, bottom);\n\n  int forced_chroma_placement = ChromaLocation_e::AVS_CHROMA_UNUSED;\n  if (vi.IsYV411() || vi.Is420() || vi.Is422()) {\n    auto frame0 = clip->GetFrame(0, env);\n    const AVSMap* props = env->getFramePropsRO(frame0);\n    if (props) {\n      if (env->propNumElements(props, \"_ChromaLocation\") > 0) {\n        forced_chroma_placement = (int)env->propGetIntSaturated(props, \"_ChromaLocation\", 0, nullptr);\n      }\n    }\n  }\n\n  clip = new AddBorders(left, top, right, bottom, color, color_as_yuv, new Crop(left, top, vi.width-left-right, vi.height-top-bottom, 0, clip, env), env);\n\n  // args[7], args[8], args[9], args[10], args[11], // [resample]s[param1]f[param2]f[param3]f[r]i\n\n  clip = AddBorderPostProcess(clip, left, top, right, bottom, args[7], args[8], args[9], args[10], args[11], forced_chroma_placement, env);\n\n  return clip;\n\n}\n\n\nAVSValue __cdecl Create_CropBottom(AVSValue args, void*, IScriptEnvironment* env)\n{\n  PClip clip = args[0].AsClip();\n  const VideoInfo& vi = clip->GetVideoInfo();\n  return new Crop(0, 0, vi.width, vi.height - args[1].AsInt(), 0, clip, env);\n}\n"
  },
  {
    "path": "avs_core/filters/transform.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Transform_H__\n#define __Transform_H__\n\n#include <avisynth.h>\n\n\n/********************************************************************\n********************************************************************/\n\n\nclass FlipVertical : public GenericVideoFilter\n/**\n  * Class to vertically flip a video\n **/\n{\npublic:\n  FlipVertical(PClip _child) : GenericVideoFilter(_child) {}\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n};\n\n\nclass FlipHorizontal : public GenericVideoFilter\n/**\n  * Class to Horizontally flip a video\n **/\n{\npublic:\n  FlipHorizontal(PClip _child) : GenericVideoFilter(_child) {}\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n};\n\n\nclass Crop : public GenericVideoFilter\n/**\n  * Class to crop a video\n **/\n{\npublic:\n  Crop(int _left, int _top, int _width, int _height, bool _align, PClip _child, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override;\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\nprivate:\n  /*const*/ int left_bytes, top, align;\n  int xsub, ysub;\n  bool isRGBPfamily;\n  bool hasAlpha;\n};\n\n\n\nclass AddBorders : public GenericVideoFilter\n/**\n  * Class to add borders to a video\n **/\n{\npublic:\n  AddBorders(int _left, int _top, int _right, int _bot, int _clr, bool _force_color_as_yuv, PClip _child, IScriptEnvironment* env);\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n\n  int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n    AVS_UNUSED(frame_range);\n    return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\nprivate:\n  /*const*/ int left, top, right, bot, clr;\n  int xsub, ysub;\n  bool force_color_as_yuv;\n};\n\n\n\n\n\n\n/**** Factory methods ****/\n\nAVSValue __cdecl Create_Letterbox(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue __cdecl Create_CropBottom(AVSValue args, void*, IScriptEnvironment* env);\n\n\n\n#endif  // __Transform_H__\n"
  },
  {
    "path": "avs_core/filters/turn.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n/*\n** Turn. version 0.1\n** (c) 2003 - Ernst Peché\n**\n*/\n\n#include \"turn.h\"\n#ifdef INTEL_INTRINSICS\n#include \"intel/turn_sse.h\"\n#include \"intel/turn_avx2.h\"\n#endif\n#ifdef NEON_INTRINSICS\n#include \"aarch64/turn_neon.h\"\n#endif\n#include \"resample.h\"\n#include \"planeswap.h\"\n#include \"../core/internal.h\"\n#include <stdint.h>\n#include \"../convert/convert_helper.h\"\n\n\nextern const AVSFunction Turn_filters[] = {\n    { \"TurnLeft\",  BUILTIN_FUNC_PREFIX, \"c\", Turn::create_turnleft },\n    { \"TurnRight\", BUILTIN_FUNC_PREFIX, \"c\", Turn::create_turnright },\n    { \"Turn180\",   BUILTIN_FUNC_PREFIX, \"c\", Turn::create_turn180 },\n    { 0 }\n};\n\nenum TurnDirection\n{\n  DIRECTION_LEFT = 0,\n  DIRECTION_RIGHT = 1,\n  DIRECTION_180 = 2\n};\n\n\n// TurnLeft() is FlipVertical().TurnRight().FlipVertical().\n// Therefore, we don't have to implement both TurnRight() and TurnLeft().\n\ntemplate <typename T>\nvoid turn_right_plane_c(const BYTE* srcp, BYTE* dstp, int src_rowsize, int height, int src_pitch, int dst_pitch)\n{\n    const BYTE* AVS_RESTRICT s0 = srcp + src_pitch * (height - 1);\n\n    for (int y = 0; y < height; ++y)\n    {\n        BYTE* AVS_RESTRICT d0 = dstp;\n        for (int x = 0; x < src_rowsize; x += sizeof(T))\n        {\n            *reinterpret_cast<T*>(d0) = *reinterpret_cast<const T*>(s0 + x);\n            d0 += dst_pitch;\n        }\n        s0 -= src_pitch;\n        dstp += sizeof(T);\n    }\n}\n\n\n// Explicit instantiation, can be used from other modules.\ntemplate void turn_right_plane_c<uint64_t>(const BYTE*, BYTE*, int, int, int, int);\n\n\nvoid turn_right_plane_8_c(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    turn_right_plane_c<BYTE>(srcp, dstp, src_rowsize, src_height, src_pitch, dst_pitch);\n}\n\n\nvoid turn_left_plane_8_c(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    turn_right_plane_c<BYTE>(srcp + src_pitch * (src_height - 1), dstp + dst_pitch * (src_rowsize - 1), src_rowsize, src_height, -src_pitch, -dst_pitch);\n}\n\n\nvoid turn_right_plane_16_c(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    turn_right_plane_c<uint16_t>(srcp, dstp, src_rowsize, src_height, src_pitch, dst_pitch);\n}\n\n\nvoid turn_left_plane_16_c(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    turn_right_plane_c<uint16_t>(srcp + src_pitch * (src_height - 1), dstp + dst_pitch * (src_rowsize / 2 - 1), src_rowsize, src_height, -src_pitch, -dst_pitch);\n}\n\n\nvoid turn_right_plane_32_c(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    turn_right_plane_c<uint32_t>(srcp, dstp, src_rowsize, src_height, src_pitch, dst_pitch);\n}\n\n\nvoid turn_left_plane_32_c(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    turn_right_plane_c<uint32_t>(srcp + src_pitch * (src_height - 1), dstp + dst_pitch * (src_rowsize / 4 - 1), src_rowsize, src_height, -src_pitch, -dst_pitch);\n}\n\n\n// on RGB, TurnLeft and TurnRight are reversed.\nvoid turn_left_rgb32_c(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    turn_right_plane_32_c(srcp, dstp, src_rowsize, src_height, src_pitch, dst_pitch);\n}\n\n\nvoid turn_right_rgb32_c(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    turn_left_plane_32_c(srcp, dstp, src_rowsize, src_height, src_pitch, dst_pitch);\n}\n\n\nstruct Rgb24 {\n    BYTE b, g, r;\n};\n\n\nvoid turn_left_rgb24(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    turn_right_plane_c<Rgb24>(srcp, dstp, src_rowsize, src_height, src_pitch, dst_pitch);\n}\n\n\nvoid turn_right_rgb24(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    turn_right_plane_c<Rgb24>(srcp + src_pitch * (src_height - 1), dstp + dst_pitch * (src_rowsize / 3 - 1), src_rowsize, src_height, -src_pitch, -dst_pitch);\n}\n\n\nstruct Rgb48 {\n    uint16_t b, g, r;\n};\n\n\nvoid turn_left_rgb48_c(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    turn_right_plane_c<Rgb48>(srcp, dstp, src_rowsize, src_height, src_pitch, dst_pitch);\n}\n\n\nvoid turn_right_rgb48_c(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    turn_right_plane_c<Rgb48>(srcp + src_pitch * (src_height - 1), dstp + dst_pitch * (src_rowsize / 6 - 1), src_rowsize, src_height, -src_pitch, -dst_pitch);\n}\n\n\nvoid turn_left_rgb64_c(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    turn_right_plane_c<uint64_t>(srcp, dstp, src_rowsize, src_height, src_pitch, dst_pitch);\n}\n\n\nvoid turn_right_rgb64_c(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    turn_right_plane_c<uint64_t>(srcp + src_pitch * (src_height - 1), dstp + dst_pitch * (src_rowsize / 8 - 1), src_rowsize, src_height, -src_pitch, -dst_pitch);\n}\n\n\nstatic void turn_right_yuy2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    dstp += (src_height - 2) * 2;\n\n    for (int y = 0; y < src_height; y += 2)\n    {\n        BYTE* d0 = dstp - y * 2;\n        for (int x = 0; x < src_rowsize; x += 4)\n        {\n            int u = (srcp[x + 1] + srcp[x + 1 + src_pitch] + 1) / 2;\n            int v = (srcp[x + 3] + srcp[x + 3 + src_pitch] + 1) / 2;\n\n            d0[0] = srcp[x + src_pitch];\n            d0[1] = u;\n            d0[2] = srcp[x];\n            d0[3] = v;\n            d0 += dst_pitch;\n\n            d0[0] = srcp[x + src_pitch + 2];\n            d0[1] = u;\n            d0[2] = srcp[x + 2];\n            d0[3] = v;\n            d0 += dst_pitch;\n        }\n        srcp += src_pitch * 2;\n    }\n}\n\n\nstatic void turn_left_yuy2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    turn_right_yuy2(srcp + src_pitch * (src_height - 1), dstp + dst_pitch * (src_rowsize / 2 - 1), src_rowsize, src_height, -src_pitch, -dst_pitch);\n}\n\n\ntemplate <typename T>\nvoid turn_180_plane_c(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    dstp += dst_pitch * (src_height - 1) + src_rowsize - sizeof(T);\n    src_rowsize /= sizeof(T);\n\n    for (int y = 0; y < src_height; ++y)\n    {\n        const T* AVS_RESTRICT s0 = reinterpret_cast<const T*>(srcp);\n        T* AVS_RESTRICT d0 = reinterpret_cast<T*>(dstp);\n\n        for (int x = 0; x < src_rowsize; ++x)\n        {\n            d0[-x] = s0[x];\n        }\n        srcp += src_pitch;\n        dstp -= dst_pitch;\n    }\n}\n\nstatic void turn_180_yuy2(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch)\n{\n    dstp += dst_pitch * (src_height - 1) + src_rowsize - 4;\n\n    for (int y = 0; y < src_height; ++y)\n    {\n        for (int x = 0; x < src_rowsize; x += 4)\n        {\n            dstp[-x + 2] = srcp[x + 0];\n            dstp[-x + 1] = srcp[x + 1];\n            dstp[-x + 0] = srcp[x + 2];\n            dstp[-x + 3] = srcp[x + 3];\n        }\n        srcp += src_pitch;\n        dstp -= dst_pitch;\n    }\n}\n\n\nTurn::Turn(PClip c, int direction, IScriptEnvironment* env) : GenericVideoFilter(c), u_or_b_source(nullptr), v_or_r_source(nullptr)\n{\n    if (vi.pixel_type & VideoInfo::CS_INTERLEAVED) {\n        num_planes = 1;\n    } else if (vi.IsPlanarRGBA() || vi.IsYUVA()) {\n        num_planes = 4;\n    } else {\n        num_planes = 3;\n    }\n\n    splanes[0] = vi.IsRGB() ? PLANAR_G : PLANAR_Y;\n    splanes[1] = vi.IsRGB() ? PLANAR_B : PLANAR_U;\n    splanes[2] = vi.IsRGB() ? PLANAR_R : PLANAR_V;\n    splanes[3] = PLANAR_A;\n\n    if (direction != DIRECTION_180)\n    {\n        if (vi.IsYUY2() && (vi.height & 1))\n        {\n            env->ThrowError(\"Turn: YUY2 data must have mod2 height.\");\n        }\n        if (num_planes > 1) {\n            int mod_h = vi.IsRGB() ? 1 : (1 << vi.GetPlaneWidthSubsampling(PLANAR_U));\n            int mod_v = vi.IsRGB() ? 1 : (1 << vi.GetPlaneHeightSubsampling(PLANAR_U));\n            if (mod_h != mod_v)\n            {\n                if (vi.width % mod_h)\n                {\n                    env->ThrowError(\"Turn: Planar data must have MOD %d height.\", mod_h);\n                }\n                if (vi.height % mod_v)\n                {\n                    env->ThrowError(\"Turn: Planar data must have MOD %d width.\", mod_v);\n                }\n                SetUVSource(mod_h, mod_v, env);\n            }\n        }\n        int t = vi.width;\n        vi.width = vi.height;\n        vi.height = t;\n    }\n\n    SetTurnFunction(direction, env);\n}\n\n\nvoid Turn::SetUVSource(int mod_h, int mod_v, IScriptEnvironment* env)\n{\n    MitchellNetravaliFilter filter(1.0 / 3, 1.0 / 3);\n    AVSValue subs[4] = { 0.0, 0.0, 0.0, 0.0 };\n\n    bool isRGB = vi.IsRGB(); // can be planar\n\n    u_or_b_source = new SwapUVToY(child, isRGB ? SwapUVToY::BToY8 : SwapUVToY::UToY8, env); // Y16 and Y32 capable\n    v_or_r_source = new SwapUVToY(child, isRGB ? SwapUVToY::RToY8 : SwapUVToY::VToY8, env);\n\n    const VideoInfo& vi_u = u_or_b_source->GetVideoInfo();\n\n    const int uv_height = vi_u.height * mod_v / mod_h;\n    const int uv_width  = vi_u.width  * mod_h / mod_v;\n\n    const int force = 0;\n    const bool preserve_center = true;\n    const char* placement_name = \"\"; // n/a\n    const int forced_chroma_placement = -1; // n/a\n    // chroma planes are extracted, behave like Y when resized, no chroma is involved\n\n    u_or_b_source = FilteredResize::CreateResize(u_or_b_source, uv_width, uv_height, subs, force, &filter, preserve_center, placement_name, forced_chroma_placement, env);\n    v_or_r_source = FilteredResize::CreateResize(v_or_r_source, uv_width, uv_height, subs, force, &filter, preserve_center, placement_name, forced_chroma_placement, env);\n\n    splanes[1] = 0;\n    splanes[2] = 0;\n}\n\n\nvoid Turn::SetTurnFunction(int direction, IScriptEnvironment* env)\n{\n#ifdef INTEL_INTRINSICS\n  const int cpu = env->GetCPUFlags();\n  const bool sse2 = cpu & CPUF_SSE2;\n  const bool ssse3 = cpu & CPUF_SSSE3;\n  const bool avx2 = cpu & CPUF_AVX2;\n#endif\n\n#ifdef NEON_INTRINSICS\n  const bool neon = env->GetCPUFlags() & CPUF_ARM_NEON;\n  const bool dotprod = env->GetCPUFlags() & CPUF_ARM_DOTPROD;\n#endif\n\n  TurnFuncPtr funcs[3];\n  auto set_funcs = [&funcs](TurnFuncPtr tleft, TurnFuncPtr tright, TurnFuncPtr t180) {\n    funcs[0] = tleft;\n    funcs[1] = tright;\n    funcs[2] = t180;\n  };\n\n  if (vi.IsRGB64())\n  {\n#ifdef INTEL_INTRINSICS\n    if (avx2)\n      set_funcs(turn_left_rgb64_avx2, turn_right_rgb64_avx2, turn_180_plane_avx2<uint64_t>);\n    else if (sse2)\n      set_funcs(turn_left_rgb64_sse2, turn_right_rgb64_sse2, turn_180_plane_sse2<uint64_t>);\n    else\n#elif defined(NEON_INTRINSICS)\n    if (neon)\n      set_funcs(turn_left_rgb64_neon, turn_right_rgb64_neon, turn_180_plane_neon<uint64_t>);\n    else\n#endif\n    {\n      set_funcs(turn_left_rgb64_c, turn_right_rgb64_c, turn_180_plane_c<uint64_t>);\n    }\n\n  }\n  else if (vi.IsRGB48())\n  {\n    set_funcs(turn_left_rgb48_c, turn_right_rgb48_c, turn_180_plane_c<Rgb48>);\n  }\n  else if (vi.IsRGB32())\n  {\n#ifdef INTEL_INTRINSICS\n    if (avx2)\n      set_funcs(turn_left_rgb32_avx2, turn_right_rgb32_avx2, turn_180_plane_avx2<uint32_t>);\n    else if (sse2)\n      set_funcs(turn_left_rgb32_sse2, turn_right_rgb32_sse2, turn_180_plane_sse2<uint32_t>);\n    else\n#elif defined(NEON_INTRINSICS)\n    if (neon)\n      set_funcs(turn_left_rgb32_neon, turn_right_rgb32_neon, turn_180_plane_neon<uint32_t>);\n    else\n#endif\n    {\n      set_funcs(turn_left_rgb32_c, turn_right_rgb32_c, turn_180_plane_c<uint32_t>);\n    }\n  }\n  else if (vi.IsRGB24())\n  {\n    set_funcs(turn_left_rgb24, turn_right_rgb24, turn_180_plane_c<Rgb24>);\n  }\n  else if (vi.IsYUY2())\n  {\n    set_funcs(turn_left_yuy2, turn_right_yuy2, turn_180_yuy2);\n  }\n  else if (vi.ComponentSize() == 1) // 8 bit\n  {\n#ifdef INTEL_INTRINSICS\n    if(avx2)\n    {\n      set_funcs(turn_left_plane_8_avx2, turn_right_plane_8_avx2, turn_180_plane_avx2<BYTE>);\n    }\n    else if (sse2)\n    {\n      set_funcs(turn_left_plane_8_sse2, turn_right_plane_8_sse2,\n        ssse3 ? turn_180_plane_ssse3<BYTE> : turn_180_plane_sse2<BYTE>);\n    }\n    else\n#elif defined(NEON_INTRINSICS)\n    if (neon)\n    {\n      set_funcs(turn_left_plane_8_neon, turn_right_plane_8_neon, turn_180_plane_neon<BYTE>);\n    }\n    else\n#endif\n    {\n      set_funcs(turn_left_plane_8_c, turn_right_plane_8_c, turn_180_plane_c<BYTE>);\n    }\n  }\n  else if (vi.ComponentSize() == 2) // 16 bit\n  {\n#ifdef INTEL_INTRINSICS\n    if (avx2)\n    {\n      set_funcs(turn_left_plane_16_avx2, turn_right_plane_16_avx2, turn_180_plane_avx2<uint16_t>);\n    }\n    else if (sse2)\n    {\n      set_funcs(turn_left_plane_16_sse2, turn_right_plane_16_sse2,\n        ssse3 ? turn_180_plane_ssse3<uint16_t> : turn_180_plane_sse2<uint16_t>);\n    }\n    else\n#elif defined(NEON_INTRINSICS)\n    if (neon)\n    {\n      set_funcs(turn_left_plane_16_neon, turn_right_plane_16_neon, turn_180_plane_neon<uint16_t>);\n    }\n    else\n#endif\n    {\n      set_funcs(turn_left_plane_16_c, turn_right_plane_16_c, turn_180_plane_c<uint16_t>);\n    }\n  }\n  else if (vi.ComponentSize() == 4) // 32 bit\n  {\n#ifdef INTEL_INTRINSICS\n    if(avx2) {\n      set_funcs(turn_left_plane_32_avx2, turn_right_plane_32_avx2, turn_180_plane_avx2<uint32_t>);\n    }\n    else if (sse2) {\n      set_funcs(turn_left_plane_32_sse2, turn_right_plane_32_sse2, turn_180_plane_sse2<uint32_t>);\n    }\n    else\n#elif defined(NEON_INTRINSICS)\n    if (neon) {\n      set_funcs(turn_left_plane_32_neon, turn_right_plane_32_neon, turn_180_plane_neon<uint32_t>);\n    }\n    else\n#endif\n    {\n      set_funcs(turn_left_plane_32_c, turn_right_plane_32_c, turn_180_plane_c<uint32_t>);\n    }\n  }\n  else env->ThrowError(\"Turn: Image format not supported!\");\n\n  turn_function = funcs[direction];\n}\n\n\nint __stdcall Turn::SetCacheHints(int cachehints, int frame_range)\n{\n  AVS_UNUSED(frame_range);\n  return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n}\n\n\nPVideoFrame __stdcall Turn::GetFrame(int n, IScriptEnvironment* env)\n{\n    const int dplanes[] = {\n        0,\n        vi.IsRGB() ? PLANAR_B : PLANAR_U,\n        vi.IsRGB() ? PLANAR_R : PLANAR_V,\n        PLANAR_A,\n    };\n\n    auto src = child->GetFrame(n, env);\n    auto dst = env->NewVideoFrameP(vi, &src);\n\n    PVideoFrame srcs[4] = {\n        src,\n        u_or_b_source ? u_or_b_source->GetFrame(n, env) : src,\n        v_or_r_source ? v_or_r_source->GetFrame(n, env) : src,\n        src,\n    };\n\n    for (int p = 0; p < num_planes; ++p) {\n        const int splane = splanes[p];\n        const int dplane = dplanes[p];\n        turn_function(srcs[p]->GetReadPtr(splane), dst->GetWritePtr(dplane),\n                      srcs[p]->GetRowSize(splane), srcs[p]->GetHeight(splane),\n                      srcs[p]->GetPitch(splane), dst->GetPitch(dplane));\n    }\n\n    return dst;\n}\n\n\nAVSValue __cdecl Turn::create_turnleft(AVSValue args, void* , IScriptEnvironment* env)\n{\n    return new Turn(args[0].AsClip(), DIRECTION_LEFT, env);\n}\n\n\nAVSValue __cdecl Turn::create_turnright(AVSValue args, void* , IScriptEnvironment* env)\n{\n    return new Turn(args[0].AsClip(), DIRECTION_RIGHT, env);\n}\n\n\nAVSValue __cdecl Turn::create_turn180(AVSValue args, void* , IScriptEnvironment* env)\n{\n    return new Turn(args[0].AsClip(), DIRECTION_180, env);\n}\n"
  },
  {
    "path": "avs_core/filters/turn.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef _AVS_TURN_H\n#define _AVS_TURN_H\n\n#include <avisynth.h>\n\ntypedef void (*TurnFuncPtr)(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\n\nclass Turn : public GenericVideoFilter {\n\n    TurnFuncPtr turn_function;\n    PClip u_or_b_source;\n    PClip v_or_r_source;\n\n    int num_planes;\n    int splanes[4];\n\n    void SetUVSource(int mul_h, int mul_v, IScriptEnvironment* env);\n    void SetTurnFunction(int direction, IScriptEnvironment* env);\n\n\npublic:\n    Turn(PClip _child, int direction, IScriptEnvironment* env);\n\n    PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override;\n    int __stdcall SetCacheHints(int cachehints, int frame_range) override;\n\n    static AVSValue __cdecl create_turnleft(AVSValue args, void* user_data, IScriptEnvironment* env);\n    static AVSValue __cdecl create_turnright(AVSValue args, void* user_data, IScriptEnvironment* env);\n    static AVSValue __cdecl create_turn180(AVSValue args, void* user_data, IScriptEnvironment* env);\n\n};\n\n// Other filters (e.g. resampler) might also use these functions\nvoid turn_left_plane_8_c(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\nvoid turn_left_plane_16_c(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\nvoid turn_left_plane_32_c(const BYTE *srcp, BYTE *dstp, int src_rowsize, int height, int src_pitch, int dst_pitch);\nvoid turn_left_rgb24(const BYTE *srcp, BYTE *dstp, int src_rowsize, int height, int src_pitch, int dst_pitch);\nvoid turn_left_rgb32_c(const BYTE *srcp, BYTE *dstp, int src_rowsize, int height, int src_pitch, int dst_pitch);\nvoid turn_left_rgb48_c(const BYTE *srcp, BYTE *dstp, int src_rowsize, int height, int src_pitch, int dst_pitch);\nvoid turn_left_rgb64_c(const BYTE *srcp, BYTE *dstp, int src_rowsize, int height, int src_pitch, int dst_pitch);\nvoid turn_right_plane_8_c(const BYTE *srcp, BYTE *dstp, int src_rowsize, int height, int src_pitch, int dst_pitch);\nvoid turn_right_plane_16_c(const BYTE *srcp, BYTE *dstp, int src_rowsize, int height, int src_pitch, int dst_pitch);\nvoid turn_right_plane_32_c(const BYTE *srcp, BYTE *dstp, int width, int height, int src_pitch, int dst_pitch);\nvoid turn_right_rgb24(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\nvoid turn_right_rgb32_c(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\nvoid turn_right_rgb48_c(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\nvoid turn_right_rgb64_c(const BYTE *srcp, BYTE *dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\ntemplate <typename T>\nvoid turn_right_plane_c(const BYTE* srcp, BYTE* dstp, int src_rowsize, int height, int src_pitch, int dst_pitch);\ntemplate <typename T>\nvoid turn_180_plane_c(const BYTE* srcp, BYTE* dstp, int src_rowsize, int src_height, int src_pitch, int dst_pitch);\n\n#endif  // _AVS_TURN_H\n"
  },
  {
    "path": "avs_core/include/avisynth.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// Avisynth v2.6.  Copyright 2006 Klaus Post.\n// Avisynth v2.6.  Copyright 2009 Ian Brabham.\n// Avisynth+ project\n// 20160613: new 16 bit planar pixel_type constants go live!\n// 20160725: pixel_type constants 10-12-14 bit + planar RGB + BRG48/64\n// 20161005: Fallback of VideoInfo functions to defaults if no function exists\n// 20170117: global variables for VfW output OPT_xxxx\n// 20170310: new MT mode: MT_SPECIAL_MT\n// 20171103: (test with SIZETMOD define: Videoframe offsets to size_t, may affect x64)\n// 20171207: C++ Standard Conformance (no change for plugin writers)\n// 20180525: AVS_UNUSED define to supress parameter not used warnings\n// 2020xxxx: AVS_WINDOWS and AVS_POSIX option see avs/config.h\n// 20200305: ScriptEnvironment::VSprintf parameter (void *) changed back to va_list\n// 20200330: removed __stdcall from variadic argument functions (Sprintf)\n//           (remove test SIZETMOD define for clarity)\n//           Integrate Avisynth Neo structures and interface, PFunction, PDevice\n// 20200501: frame property support (NewVideoFrameP and other helpers) to legacy IScriptEnvironment.\n//           move some former IScriptEnvironment2 functions to IScriptEnvironment:\n//           GetEnvProperty (system prop), Allocate, Free (buffer pool)\n//           GetVarTry, GetVarBool/Int/String/Double/Long\n//           Invoke2, Invoke3, InvokeTry, Invoke2Try, Invoke3Try\n//           Interface Version to 8 (classic 2.6 = 6)\n// 20200527  Add IScriptEnvironment_Avs25, used internally\n// 20200607  AVS frame property enums to match existing Avisynth enum style\n// 202112xx  V9-MakePropertyWritable, IsPropertyWritable\n// 2023      V10\n//           prop_src parameter made as const in NewVideoFrameP (non-breaking cosmetics)\n//           Add all enums of public C++ API a name\n//           Add DEFAULT_PLANE as 0 to AvsPlane enum\n//           Made `VideoFrameBuffer` destructor public\n//           Introduce pixel_type to VideoFrame struct\n//           VideoFrame::GetPixelType,VideoFrame::AmendPixelType\n//           AVSValue::GetType\n//           Add enum AvsChannelMask::MASK_SPEAKER_xxx, AvsImageTypeFlags::IT_SPEAKER_xxx\n//           Audio channel mask support for VideoInfo: \n//           Use 20 bits in VideoInfo::image_type for channel mask mapping\n//           IsChannelMaskKnown, SetChannelMask, GetChannelMask in VideoInfo\n// 20250214  V11\n//           64 bit data types in AVSValue: double and long (int64_t), also for 32 bit Avisynth!\n//           changed: AVSValue::IsFloat true for any 32/64 bit floating point or integer types\n//           changed: AVSValue::IsInt true for any 32/64 bit integer types\n//           new: AVSValue::IsFloatfStrict: returns true only if AVSValue is strictly 32 bit float\n//           new: AVSValue::IsLongStrict : returns true only if AVSValue is strictly 64 bit integer\n//           new: AVSValue::AsLong  : returns int64_t\n//           new: AVSValue::AsLong(int64_t def)\n//           (AsFloat returned double --> no AsDouble needed)\n//           new AVSValue constructors for 64 bit types\n//           Simplify this header, remove internally used IScriptEnvironment_Avs25 from here\n//           Frame property changes backported from VapourSynth API4\n//           - New propGetIntSaturated and propGetFloatSaturated\n//           - New enum: AVSPropDataTypeHint (VSAPI4: VSDataTypeHint)\n//           - New propGetDataTypeHint (VSAPI4: mapGetDataTypeHint)\n//           - New propSetDataH, like propSetData but with optional data type hint (byte/string)\n//             (VSAPI4: mapSetData, our propSetData became VSAPI4: mapSetData3)\n// 20250415  V11.1 Fix AVS_Value 64 bit data member declaration for 64-bit non Intel (other than X86_X64) systems.\n// 20250601  V12 Global lock aquire and release: AcquireGlobalLock, ReleaseGlobalLock\n//               New ApplyMessageEx\n// 20251127  V12 CACHE_INFORM_NUM_THREADS CachePolicyHint enum to inform the filter about the number of threads by SetCacheHints\n//               New env property AEP_CACHESIZE_L2\n// 20251202      GetCPUFlagsEx returning full 64 bit flags, new AVX-512 group flags, ARM64 CPU flags.\n\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making\n// a combined work based on Avisynth.  Thus, the terms and conditions of\n// the GNU General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate\n// with Avisynth solely through the interfaces defined in avisynth.h,\n// regardless of the license terms of these independent modules, and to\n// copy and distribute the resulting combined work under terms of your\n// choice, provided that every copy of the combined work is accompanied\n// by a complete copy of the source code of Avisynth (the version of\n// Avisynth used to produce the combined work), being distributed under\n// the terms of the GNU General Public License plus this exception.  An\n// independent module is a module which is not derived from or based on\n// Avisynth, such as 3rd-party filters, import and export plugins, or\n// graphical user interfaces.\n\n\n#ifndef __AVISYNTH_12_H__\n#define __AVISYNTH_12_H__\n\n#include \"avs/config.h\"\n#include \"avs/capi.h\"\n#include \"avs/types.h\"\n\n#ifdef AVS_POSIX\n# include \"avs/posix.h\"\n#endif\n\n#if defined(AVS_POSIX)\n#if defined(AVS_HAIKU)\n#undef __stdcall\n#undef __cdecl\n#endif\n#define __stdcall\n#define __cdecl\n#endif\n\n// Important note on AVISYNTH_INTERFACE_VERSION V6->V8 change:\n// Note 1: Those few plugins which were using earlier IScriptEnvironment2 despite the big Warning will crash have to be rebuilt.\n// Note 2: How to support earlier avisynth interface with an up-to-date avisynth.h:\n//         Use the new frame property features adaptively after querying that at least v8 is supported\n//         AviSynth property support can be queried (cpp iface example):\n//           has_at_least_v8 = true;\n//           try { env->CheckVersion(8); } catch (const AvisynthError&) { has_at_least_v8 = false; }\n//         and use it:\n//           if (has_at_least_v8) dst = env->NewVideoFrameP(vi, &src); else dst = env->NewVideoFrame(vi);\n\nenum AvsVersion {\n  AVISYNTH_CLASSIC_INTERFACE_VERSION_25 = 3,\n  AVISYNTH_CLASSIC_INTERFACE_VERSION_26BETA = 5,\n  AVISYNTH_CLASSIC_INTERFACE_VERSION = 6,\n  AVISYNTH_INTERFACE_VERSION = 12,\n  AVISYNTHPLUS_INTERFACE_BUGFIX_VERSION = 0 // reset to zero whenever the normal interface version bumps\n};\n\n/* Compiler-specific crap */\n\n// Tell MSVC to stop precompiling here\n#if defined(_MSC_VER) && !defined(__clang__)\n  #pragma hdrstop\n#endif\n\n// Set up debugging macros for MS compilers; for others, step down to the\n// standard <assert.h> interface\n#ifdef _MSC_VER\n  #include <crtdbg.h>\n#else\n  #undef _RPT0\n  #undef _RPT1\n  #undef _RPT2\n  #undef _RPT3\n  #undef _RPT4\n  #undef _RPT5\n  #define _RPT0(a,b) ((void)0)\n  #define _RPT1(a,b,c) ((void)0)\n  #define _RPT2(a,b,c,d) ((void)0)\n  #define _RPT3(a,b,c,d,e) ((void)0)\n  #define _RPT4(a,b,c,d,e,f) ((void)0)\n  #define _RPT5(a,b,c,d,e,f,g) ((void)0)\n\n  #include <cassert>\n  #undef _ASSERTE\n  #undef _ASSERT\n  #define _ASSERTE(x) assert(x)\n  #define _ASSERT(x) assert(x)\n#endif\n\n\n\n// I had problems with Premiere wanting 1-byte alignment for its structures,\n// so I now set the Avisynth struct alignment explicitly here.\n#pragma pack(push,8)\n\n// The VideoInfo struct holds global information about a clip (i.e.\n// information that does not depend on the frame number).  The GetVideoInfo\n// method in IClip returns this struct.\n\nenum AvsSampleType {\n  SAMPLE_INT8  = 1 << 0,\n  SAMPLE_INT16 = 1 << 1,\n  SAMPLE_INT24 = 1 << 2,  // Int24 is a very stupid thing to code, but it's supported by some hardware.\n  SAMPLE_INT32 = 1 << 3,\n  SAMPLE_FLOAT = 1 << 4\n};\n\nenum AvsPlane {\n  DEFAULT_PLANE = 0,\n  PLANAR_Y = 1 << 0,\n  PLANAR_U = 1 << 1,\n  PLANAR_V = 1 << 2,\n  PLANAR_ALIGNED = 1 << 3,\n  PLANAR_Y_ALIGNED = PLANAR_Y | PLANAR_ALIGNED,\n  PLANAR_U_ALIGNED = PLANAR_U | PLANAR_ALIGNED,\n  PLANAR_V_ALIGNED = PLANAR_V | PLANAR_ALIGNED,\n  PLANAR_A = 1 << 4,\n  PLANAR_R = 1 << 5,\n  PLANAR_G = 1 << 6,\n  PLANAR_B = 1 << 7,\n  PLANAR_A_ALIGNED = PLANAR_A | PLANAR_ALIGNED,\n  PLANAR_R_ALIGNED = PLANAR_R | PLANAR_ALIGNED,\n  PLANAR_G_ALIGNED = PLANAR_G | PLANAR_ALIGNED,\n  PLANAR_B_ALIGNED = PLANAR_B | PLANAR_ALIGNED,\n};\n\nclass AvisynthError /* exception */ {\npublic:\n  const char* const msg;\n  AvisynthError(const char* _msg) : msg(_msg) {}\n\n// Ensure AvisynthError cannot be publicly assigned!\nprivate:\n  AvisynthError& operator=(const AvisynthError&);\n}; // end class AvisynthError\n\nenum AvsDeviceType {\n  DEV_TYPE_NONE = 0,\n  DEV_TYPE_CPU = 1,\n  DEV_TYPE_CUDA = 2,\n  DEV_TYPE_ANY = 0xFFFF\n};\n\nenum AvsValueType {\n  VALUE_TYPE_UNDEFINED = 'v',\n  VALUE_TYPE_BOOL = 'b',\n  VALUE_TYPE_INT = 'i',\n  VALUE_TYPE_LONG = 'l',\n  VALUE_TYPE_FLOAT = 'f',\n  VALUE_TYPE_DOUBLE = 'd',\n  VALUE_TYPE_STRING = 's',\n  VALUE_TYPE_CLIP = 'c',\n  VALUE_TYPE_FUNCTION = 'n',\n  VALUE_TYPE_ARRAY = 'a'\n};\n\n/* Forward references */\n#if defined(MSVC)\n    #define SINGLE_INHERITANCE __single_inheritance\n#else\n    #define SINGLE_INHERITANCE\n#endif\nstruct SINGLE_INHERITANCE VideoInfo;\nclass SINGLE_INHERITANCE VideoFrameBuffer;\nclass SINGLE_INHERITANCE VideoFrame;\nclass IClip;\nclass SINGLE_INHERITANCE PClip;\nclass SINGLE_INHERITANCE PVideoFrame;\nclass IScriptEnvironment;\nclass SINGLE_INHERITANCE AVSValue;\nclass INeoEnv;\nclass IFunction;\nclass SINGLE_INHERITANCE PFunction;\nclass Device;\nclass SINGLE_INHERITANCE PDevice;\nstruct AVSMap;\n\n\n\n/*\n * Avisynth C++ plugin API code function pointers.\n *\n * In order to maintain binary compatibility with\n * future version do not change the order of the\n * existing function pointers. It will be baked\n * into all existing plugins.\n *\n * Add new function pointers to the end of the\n * structure. The linkage macros generate some\n * protection code to ensure newer plugin do not\n * call non-existing functions in an older host.\n */\n\nstruct AVS_Linkage {\n\n  int Size;\n\n/**********************************************************************/\n\n// struct VideoInfo\n  bool    (VideoInfo::*HasVideo)() const;\n  bool    (VideoInfo::*HasAudio)() const;\n  bool    (VideoInfo::*IsRGB)() const;\n  bool    (VideoInfo::*IsRGB24)() const;\n  bool    (VideoInfo::*IsRGB32)() const;\n  bool    (VideoInfo::*IsYUV)() const;\n  bool    (VideoInfo::*IsYUY2)() const;\n  bool    (VideoInfo::*IsYV24)() const;\n  bool    (VideoInfo::*IsYV16)() const;\n  bool    (VideoInfo::*IsYV12)() const;\n  bool    (VideoInfo::*IsYV411)() const;\n  bool    (VideoInfo::*IsY8)() const;\n  bool    (VideoInfo::*IsColorSpace)(int c_space) const;\n  bool    (VideoInfo::*Is)(int property) const;\n  bool    (VideoInfo::*IsPlanar)() const;\n  bool    (VideoInfo::*IsFieldBased)() const;\n  bool    (VideoInfo::*IsParityKnown)() const;\n  bool    (VideoInfo::*IsBFF)() const;\n  bool    (VideoInfo::*IsTFF)() const;\n  bool    (VideoInfo::*IsVPlaneFirst)() const;\n  int     (VideoInfo::*BytesFromPixels)(int pixels) const;\n  int     (VideoInfo::*RowSize)(int plane) const;\n  int     (VideoInfo::*BMPSize)() const;\n  int64_t (VideoInfo::*AudioSamplesFromFrames)(int frames) const;\n  int     (VideoInfo::*FramesFromAudioSamples)(int64_t samples) const;\n  int64_t (VideoInfo::*AudioSamplesFromBytes)(int64_t bytes) const;\n  int64_t (VideoInfo::*BytesFromAudioSamples)(int64_t samples) const;\n  int     (VideoInfo::*AudioChannels)() const;\n  int     (VideoInfo::*SampleType)() const;\n  bool    (VideoInfo::*IsSampleType)(int testtype) const;\n  int     (VideoInfo::*SamplesPerSecond)() const;\n  int     (VideoInfo::*BytesPerAudioSample)() const;\n  void    (VideoInfo::*SetFieldBased)(bool isfieldbased);\n  void    (VideoInfo::*Set)(int property);\n  void    (VideoInfo::*Clear)(int property);\n  int     (VideoInfo::*GetPlaneWidthSubsampling)(int plane) const;\n  int     (VideoInfo::*GetPlaneHeightSubsampling)(int plane) const;\n  int     (VideoInfo::*BitsPerPixel)() const;\n  int     (VideoInfo::*BytesPerChannelSample)() const;\n  void    (VideoInfo::*SetFPS)(unsigned numerator, unsigned denominator);\n  void    (VideoInfo::*MulDivFPS)(unsigned multiplier, unsigned divisor);\n  bool    (VideoInfo::*IsSameColorspace)(const VideoInfo& vi) const;\n// end struct VideoInfo\n\n/**********************************************************************/\n\n// class VideoFrameBuffer\n  const BYTE* (VideoFrameBuffer::*VFBGetReadPtr)() const;\n  BYTE*       (VideoFrameBuffer::*VFBGetWritePtr)();\n  int         (VideoFrameBuffer::*GetDataSize)() const;\n  int         (VideoFrameBuffer::*GetSequenceNumber)() const;\n  int         (VideoFrameBuffer::*GetRefcount)() const;\n// end class VideoFrameBuffer\n\n/**********************************************************************/\n\n// class VideoFrame\n  int               (VideoFrame::*GetPitch)(int plane) const;\n  int               (VideoFrame::*GetRowSize)(int plane) const;\n  int               (VideoFrame::*GetHeight)(int plane) const;\n  VideoFrameBuffer* (VideoFrame::*GetFrameBuffer)() const;\n  int               (VideoFrame::*GetOffset)(int plane) const;\n  const BYTE*       (VideoFrame::*VFGetReadPtr)(int plane) const;\n  bool              (VideoFrame::*IsWritable)() const;\n  BYTE*             (VideoFrame::*VFGetWritePtr)(int plane) const;\n  void              (VideoFrame::*VideoFrame_DESTRUCTOR)();\n// end class VideoFrame\n\n/**********************************************************************/\n\n// class IClip\n  /* nothing */\n// end class IClip\n\n/**********************************************************************/\n\n// class PClip\n  void (PClip::*PClip_CONSTRUCTOR0)();\n  void (PClip::*PClip_CONSTRUCTOR1)(const PClip& x);\n  void (PClip::*PClip_CONSTRUCTOR2)(IClip* x);\n  void (PClip::*PClip_OPERATOR_ASSIGN0)(IClip* x);\n  void (PClip::*PClip_OPERATOR_ASSIGN1)(const PClip& x);\n  void (PClip::*PClip_DESTRUCTOR)();\n// end class PClip\n\n/**********************************************************************/\n\n// class PVideoFrame\n  void (PVideoFrame::*PVideoFrame_CONSTRUCTOR0)();\n  void (PVideoFrame::*PVideoFrame_CONSTRUCTOR1)(const PVideoFrame& x);\n  void (PVideoFrame::*PVideoFrame_CONSTRUCTOR2)(VideoFrame* x);\n  void (PVideoFrame::*PVideoFrame_OPERATOR_ASSIGN0)(VideoFrame* x);\n  void (PVideoFrame::*PVideoFrame_OPERATOR_ASSIGN1)(const PVideoFrame& x);\n  void (PVideoFrame::*PVideoFrame_DESTRUCTOR)();\n// end class PVideoFrame\n\n/**********************************************************************/\n\n// class AVSValue\n  void            (AVSValue::*AVSValue_CONSTRUCTOR0)();\n  void            (AVSValue::*AVSValue_CONSTRUCTOR1)(IClip* c);\n  void            (AVSValue::*AVSValue_CONSTRUCTOR2)(const PClip& c);\n  void            (AVSValue::*AVSValue_CONSTRUCTOR3)(bool b);\n  void            (AVSValue::*AVSValue_CONSTRUCTOR4)(int i);\n  void            (AVSValue::*AVSValue_CONSTRUCTOR5)(float f);\n  void            (AVSValue::*AVSValue_CONSTRUCTOR6)(double f);\n  void            (AVSValue::*AVSValue_CONSTRUCTOR7)(const char* s);\n  void            (AVSValue::*AVSValue_CONSTRUCTOR8)(const AVSValue* a, int size);\n  void            (AVSValue::*AVSValue_CONSTRUCTOR9)(const AVSValue& v);\n  void            (AVSValue::*AVSValue_DESTRUCTOR)();\n  AVSValue&       (AVSValue::*AVSValue_OPERATOR_ASSIGN)(const AVSValue& v);\n  const AVSValue& (AVSValue::*AVSValue_OPERATOR_INDEX)(int index) const;\n  bool            (AVSValue::*Defined)() const;\n  bool            (AVSValue::*IsClip)() const;\n  bool            (AVSValue::*IsBool)() const;\n  bool            (AVSValue::*IsInt)() const;\n  bool            (AVSValue::*IsFloat)() const;\n  bool            (AVSValue::*IsString)() const;\n  bool            (AVSValue::*IsArray)() const;\n  PClip           (AVSValue::*AsClip)() const;\n  bool            (AVSValue::*AsBool1)() const;\n  int             (AVSValue::*AsInt1)() const;\n  const char*     (AVSValue::*AsString1)() const;\n  double          (AVSValue::*AsFloat1)() const; // AsDouble1\n  bool            (AVSValue::*AsBool2)(bool def) const;\n  int             (AVSValue::*AsInt2)(int def) const;\n  double          (AVSValue::*AsDblDef)(double def) const; // AsDouble2\n  double          (AVSValue::*AsFloat2)(float def) const;\n  const char*     (AVSValue::*AsString2)(const char* def) const;\n  int             (AVSValue::*ArraySize)() const;\n  // v11\n  bool            (AVSValue::*IsLongStrict)() const;\n  bool            (AVSValue::*IsFloatfStrict)() const;\n  int64_t         (AVSValue::*AsLong1)() const;\n  int64_t         (AVSValue::*AsLong2)(int64_t def) const;\n  void            (AVSValue::*AVSValue_CONSTRUCTOR12)(int64_t l);\n// end class AVSValue\n\n/**********************************************************************/\n  // Reserve pointer space, once used to keep compatibility with Avs \"classic\" even if it adds functions on its own\n  void    (VideoInfo::*reserved[27])();\n/**********************************************************************/\n  // AviSynth+ additions\n  int     (VideoInfo::*NumComponents)() const;\n  int     (VideoInfo::*ComponentSize)() const;\n  int     (VideoInfo::*BitsPerComponent)() const;\n  bool    (VideoInfo::*Is444)() const;\n  bool    (VideoInfo::*Is422)() const;\n  bool    (VideoInfo::*Is420)() const;\n  bool    (VideoInfo::*IsY)() const;\n  bool    (VideoInfo::*IsRGB48)() const;\n  bool    (VideoInfo::*IsRGB64)() const;\n  bool    (VideoInfo::*IsYUVA)() const;\n  bool    (VideoInfo::*IsPlanarRGB)() const;\n  bool    (VideoInfo::*IsPlanarRGBA)() const;\n  /**********************************************************************/\n\n  // frame property access\n  AVSMap& (VideoFrame::* getProperties)();\n  const AVSMap& (VideoFrame::* getConstProperties)();\n  void (VideoFrame::* setProperties)(const AVSMap& properties);\n\n  // PFunction\n  void          (AVSValue::* AVSValue_CONSTRUCTOR11)(const PFunction& o);\n  bool          (AVSValue::* IsFunction)() const;\n  void          (PFunction::* PFunction_CONSTRUCTOR0)();\n  void          (PFunction::* PFunction_CONSTRUCTOR1)(IFunction* p);\n  void          (PFunction::* PFunction_CONSTRUCTOR2)(const PFunction& p);\n  PFunction&    (PFunction::* PFunction_OPERATOR_ASSIGN0)(IFunction* other);\n  PFunction&    (PFunction::* PFunction_OPERATOR_ASSIGN1)(const PFunction& other);\n  void          (PFunction::* PFunction_DESTRUCTOR)();\n  // end PFunction\n\n  // extra VideoFrame functions\n  int           (VideoFrame::* VideoFrame_CheckMemory)() const;\n  PDevice       (VideoFrame::* VideoFrame_GetDevice)() const;\n\n  // class PDevice, even if only CPU device\n  void          (PDevice::* PDevice_CONSTRUCTOR0)();\n  void          (PDevice::* PDevice_CONSTRUCTOR1)(Device* p);\n  void          (PDevice::* PDevice_CONSTRUCTOR2)(const PDevice& p);\n  PDevice&      (PDevice::* PDevice_OPERATOR_ASSIGN0)(Device* other);\n  PDevice&      (PDevice::* PDevice_OPERATOR_ASSIGN1)(const PDevice& other);\n  void          (PDevice::* PDevice_DESTRUCTOR)();\n  AvsDeviceType (PDevice::* PDevice_GetType)() const;\n  int           (PDevice::* PDevice_GetId)() const;\n  int           (PDevice::* PDevice_GetIndex)() const;\n  const char*   (PDevice::* PDevice_GetName)() const;\n  // end class PDevice\n\n  // V9: VideoFrame helper\n  bool          (VideoFrame::*IsPropertyWritable)() const;\n\n  // V10\n  int           (VideoFrame::*VideoFrame_GetPixelType)() const;\n  void          (VideoFrame::*VideoFrame_AmendPixelType)(int new_pixel_type);\n  void          (VideoFrameBuffer::*VideoFrameBuffer_DESTRUCTOR)();\n  AvsValueType  (AVSValue::*AVSValue_GetType)() const;\n\n  // V10.1\n  bool          (VideoInfo::* IsChannelMaskKnown)() const;\n  void          (VideoInfo::* SetChannelMask)(bool isChannelMaskKnown, unsigned int dwChannelMask);\n  unsigned int  (VideoInfo::* GetChannelMask)() const;\n\n  /**********************************************************************/\n  // Reserve pointer space for Avisynth+\n  void          (VideoInfo::* reserved2[64 - 31])();\n  /**********************************************************************/\n\n  // AviSynth Neo additions\n  INeoEnv*      (__stdcall *GetNeoEnv)(IScriptEnvironment* env);\n  // As of V8 most PDevice, PFunction linkage entries are moved to standard avs+ place.\n  /**********************************************************************/\n\n  // This part should be identical with AVS_Linkage entries in interface.cpp\n};\n\n#if defined(BUILDING_AVSCORE) || defined(AVS_STATIC_LIB)\n/* Macro resolution for code inside Avisynth.dll */\n# define AVS_BakedCode(arg) ;\n# define AVS_LinkCall(arg)\n# define AVS_LinkCallV(arg)\n# define AVS_LinkCallOpt(arg, argOpt) AVSLinkCall(arg)\n# define AVS_LinkCallOptDefault(arg, argDefaultValue) AVSLinkCall(arg())\n# define CALL_MEMBER_FN(object,ptrToMember)\n\n#else\n/* Macro resolution for code inside user plugin */\n# ifdef AVS_LINKAGE_DLLIMPORT\nextern __declspec(dllimport) const AVS_Linkage* const AVS_linkage;\n# else\nextern const AVS_Linkage* AVS_linkage;\n# endif\n\n# ifndef offsetof\n#  include <stddef.h>\n# endif\n\n# define AVS_BakedCode(arg) { arg ; }\n# define AVS_LinkCall(arg)  !AVS_linkage || offsetof(AVS_Linkage, arg) >= (size_t)AVS_linkage->Size ?     0 : (this->*(AVS_linkage->arg))\n# define AVS_LinkCall_Void(arg)  !AVS_linkage || offsetof(AVS_Linkage, arg) >= (size_t)AVS_linkage->Size ?     (void)0 : (this->*(AVS_linkage->arg))\n# define AVS_LinkCallV(arg) !AVS_linkage || offsetof(AVS_Linkage, arg) >= (size_t)AVS_linkage->Size ? *this : (this->*(AVS_linkage->arg))\n// Helper macros for fallback option when a function does not exists\n#define CALL_MEMBER_FN(object,ptrToMember)  ((object)->*(ptrToMember))\n#define AVS_LinkCallOpt(arg, argOpt)  !AVS_linkage ? 0 : \\\n                                      ( offsetof(AVS_Linkage, arg) >= (size_t)AVS_linkage->Size ? \\\n                                        (offsetof(AVS_Linkage, argOpt) >= (size_t)AVS_linkage->Size ? 0 : CALL_MEMBER_FN(this, AVS_linkage->argOpt)() ) : \\\n                                        CALL_MEMBER_FN(this, AVS_linkage->arg)() )\n// AVS_LinkCallOptDefault puts automatically () only after arg\n# define AVS_LinkCallOptDefault(arg, argDefaultValue)  !AVS_linkage || offsetof(AVS_Linkage, arg) >= (size_t)AVS_linkage->Size ? (argDefaultValue) : ((this->*(AVS_linkage->arg))())\n\n#endif\n\nclass PDevice\n{\npublic:\n  PDevice() AVS_BakedCode(AVS_LinkCall_Void(PDevice_CONSTRUCTOR0)())\n    PDevice(Device* p) AVS_BakedCode(AVS_LinkCall_Void(PDevice_CONSTRUCTOR1)(p))\n    PDevice(const PDevice& p) AVS_BakedCode(AVS_LinkCall_Void(PDevice_CONSTRUCTOR2)(p))\n    PDevice& operator=(Device* p) AVS_BakedCode(return AVS_LinkCallV(PDevice_OPERATOR_ASSIGN0)(p))\n    PDevice& operator=(const PDevice& p) AVS_BakedCode(return AVS_LinkCallV(PDevice_OPERATOR_ASSIGN1)(p))\n    ~PDevice() AVS_BakedCode(AVS_LinkCall_Void(PDevice_DESTRUCTOR)())\n\n    int operator!() const { return !e; }\n  operator void*() const { return e; }\n  Device* operator->() const { return e; }\n\n  AvsDeviceType GetType() const AVS_BakedCode(return AVS_LinkCallOptDefault(PDevice_GetType, DEV_TYPE_NONE))\n    int GetId() const AVS_BakedCode(return AVS_LinkCall(PDevice_GetId)())\n    int GetIndex() const AVS_BakedCode(return AVS_LinkCall(PDevice_GetIndex)())\n    const char* GetName() const AVS_BakedCode(return AVS_LinkCall(PDevice_GetName)())\n\nprivate:\n  Device * e;\n\n#ifdef BUILDING_AVSCORE\npublic:\n  void CONSTRUCTOR0();  /* Damn compiler won't allow taking the address of reserved constructs, make a dummy interlude */\n  void CONSTRUCTOR1(Device* p);\n  void CONSTRUCTOR2(const PDevice& p);\n  PDevice& OPERATOR_ASSIGN0(Device* p);\n  PDevice& OPERATOR_ASSIGN1(const PDevice& p);\n  void DESTRUCTOR();\n#endif\n};\n\n// Unshifted channel mask constants like in WAVEFORMATEXTENSIBLE\n// in AvsImageTypeFlags they are shifted by 4 bits\nenum AvsChannelMask {\n  MASK_SPEAKER_FRONT_LEFT = 0x1,\n  MASK_SPEAKER_FRONT_RIGHT = 0x2,\n  MASK_SPEAKER_FRONT_CENTER = 0x4,\n  MASK_SPEAKER_LOW_FREQUENCY = 0x8,\n  MASK_SPEAKER_BACK_LEFT = 0x10,\n  MASK_SPEAKER_BACK_RIGHT = 0x20,\n  MASK_SPEAKER_FRONT_LEFT_OF_CENTER = 0x40,\n  MASK_SPEAKER_FRONT_RIGHT_OF_CENTER = 0x80,\n  MASK_SPEAKER_BACK_CENTER = 0x100,\n  MASK_SPEAKER_SIDE_LEFT = 0x200,\n  MASK_SPEAKER_SIDE_RIGHT = 0x400,\n  MASK_SPEAKER_TOP_CENTER = 0x800,\n  MASK_SPEAKER_TOP_FRONT_LEFT = 0x1000,\n  MASK_SPEAKER_TOP_FRONT_CENTER = 0x2000,\n  MASK_SPEAKER_TOP_FRONT_RIGHT = 0x4000,\n  MASK_SPEAKER_TOP_BACK_LEFT = 0x8000,\n  MASK_SPEAKER_TOP_BACK_CENTER = 0x10000,\n  MASK_SPEAKER_TOP_BACK_RIGHT = 0x20000,\n  // Bit mask locations used up for the above positions\n  MASK_SPEAKER_DEFINED = 0x0003FFFF,\n  // Bit mask locations reserved for future use\n  MASK_SPEAKER_RESERVED = 0x7FFC0000,\n  // Used to specify that any possible permutation of speaker configurations\n  // Due to lack of available bits this one is put differently into image_type\n  MASK_SPEAKER_ALL = 0x80000000\n};\n\nstruct VideoInfo {\n  int width, height;    // width 0 means no video\n  unsigned fps_numerator, fps_denominator;\n  int num_frames;\n  // This is more extensible than previous versions. More properties can be added seamlessly.\n\n  // Colorspace properties.\n  /*\n    Planar match mask  1111.1000.0000.0111.0000.0111.0000.0111\n    Planar signature   10xx.1000.0000.00xx.0000.00xx.00xx.00xx ?\n    Planar signature   10xx.1000.0000.0xxx.0000.00xx.000x.x0xx ? *new\n    Planar filter mask 1111.1111.1111.1111.1111.1111.1110.0111 (typo from old header fixed)\n    \n    pixel_type mapping\n    ==================\n    pixel_type bit-map PIYB.Z000.0???.0SSS.0000.0???.????.????\n            planar YUV            CCC            HHH.000u.vWWW\n         planar RGB(A)            CCC                       AR\n             nonplanar            CCC            000.00wx xyAR\n    Legend\n    ======\n    Planar YUV:\n      Code Bits Remark\n      W    0-2  Planar Width Subsampling bits\n                Use (X+1) & 3 for GetPlaneWidthSubsampling\n                  000 => 1        YV12, YV16, YUV420, YUV422\n                  001 => 2        YV411, YUV9\n                  010 => reserved\n                  011 => 0        YV24, YUV444, RGBP\n                  1xx => reserved\n      v    3    VPlaneFirst YV12, YV16, YV24, YV411, YUV9\n      u    4    UPlaneFirst I420\n      H    7-9  Planar Height Subsampling bits\n                Use ((X>>8)+1) & 3 for GetPlaneHeightSubsampling\n                  000 => 1        YV12, YUV420\n                  001 => 2        YUV9\n                  010 => reserved\n                  011 => 0        YV16, YV24, YV411, YUV422, YUV444, RGBP\n                  1xx => reserved\n    \n    Planar RGB\n     Code Bits Remark\n       R   0   BGR,  (with SSS bits for 8/16 bit/sample or float)\n       A   1   BGRA, (with SSS bits for 8/16 bit/sample or float)\n    \n    \n    Not Planar, Interleaved (I flag)\n    Code Bits Remark\n      R   0   BGR24, and BGRx in future (with SSS bits for 8/16 bit/sample or float)\n      A   1   BGR32, and BGRAx in future (with SSS bits for 8/16 bit/sample or float)\n      y   2   YUY2\n      x   3-4 reserved\n      w   5   Raw32\n    \n    General\n    Code Bits Remark\n      S 16-18 Sample resolution bits\n              000 => 8\n              001 => 16\n              010 => 32 (float)\n              011,100 => reserved\n              101 => 10 bits\n              110 => 12 bits\n              111 => 14 bits\n    for packed RGB(A): only 8 and 16 bits are valid\n    \n    Other YV12 specific (will never be used)\n      C  20-23 Chroma Placement values 0-4; see CS_xxx_CHROMA_PLACEMENT\n    \n    Color family and layout\n                           Packed      Planar               Planar  Planar\n    Code Bits Remark       RGB/RGBA     YUV  YUY2  Y_Grey  RGB/RGBA  YUVA\n      R   0                  1/0         -    0      -       1/0       -\n      A   1                  0/1         -    0      -       0/1       -\n      y   2                   -          -    1      -        0        -\n      Z  27   YUVA            0          0    0      0        1        1\n      B  28   BGR             1          0    0      0        1*       0\n      Y  29   YUV             0          1    1      1        0        0\n      I  30   Interleaved     1          0    1      1        0        0\n      P  31   Planar          0          1    0      1        1        1\n    * Planar RGB plane order: G,B,R(,A)\n  */\n  enum AvsColorFormat {\n    CS_YUVA        = 1 << 27,\n    CS_BGR         = 1 << 28,\n    CS_YUV         = 1 << 29,\n    CS_INTERLEAVED = 1 << 30,\n    CS_PLANAR      = 1 << 31,\n\n    CS_Shift_Sub_Width   =  0,\n    CS_Shift_Sub_Height  =  8,\n    CS_Shift_Sample_Bits = 16,\n\n    CS_Sub_Width_Mask    = 7 << CS_Shift_Sub_Width,\n    CS_Sub_Width_1       = 3 << CS_Shift_Sub_Width, // YV24\n    CS_Sub_Width_2       = 0 << CS_Shift_Sub_Width, // YV12, I420, YV16\n    CS_Sub_Width_4       = 1 << CS_Shift_Sub_Width, // YUV9, YV411\n\n    CS_VPlaneFirst       = 1 << 3, // YV12, YV16, YV24, YV411, YUV9\n    CS_UPlaneFirst       = 1 << 4, // I420\n\n    CS_Sub_Height_Mask   = 7 << CS_Shift_Sub_Height,\n    CS_Sub_Height_1      = 3 << CS_Shift_Sub_Height, // YV16, YV24, YV411\n    CS_Sub_Height_2      = 0 << CS_Shift_Sub_Height, // YV12, I420\n    CS_Sub_Height_4      = 1 << CS_Shift_Sub_Height, // YUV9\n\n    CS_Sample_Bits_Mask  = 7 << CS_Shift_Sample_Bits,\n    CS_Sample_Bits_8     = 0 << CS_Shift_Sample_Bits,\n    CS_Sample_Bits_10    = 5 << CS_Shift_Sample_Bits,\n    CS_Sample_Bits_12    = 6 << CS_Shift_Sample_Bits,\n    CS_Sample_Bits_14    = 7 << CS_Shift_Sample_Bits,\n    CS_Sample_Bits_16    = 1 << CS_Shift_Sample_Bits,\n    CS_Sample_Bits_32    = 2 << CS_Shift_Sample_Bits,\n\n    CS_PLANAR_MASK       = CS_PLANAR | CS_INTERLEAVED | CS_YUV | CS_BGR | CS_YUVA\n                           | CS_Sample_Bits_Mask | CS_Sub_Width_Mask | CS_Sub_Height_Mask,\n    CS_PLANAR_FILTER     = ~(CS_VPlaneFirst | CS_UPlaneFirst),\n\n    CS_RGB_TYPE  = 1 << 0,\n    CS_RGBA_TYPE = 1 << 1,\n\n    // Specific colorformats\n    CS_UNKNOWN = 0,\n\n    CS_BGR24 = CS_RGB_TYPE  | CS_BGR | CS_INTERLEAVED,\n    CS_BGR32 = CS_RGBA_TYPE | CS_BGR | CS_INTERLEAVED,\n    CS_YUY2  = 1 << 2 | CS_YUV | CS_INTERLEAVED,\n    //  CS_YV12  = 1 << 3  Reserved\n    //  CS_I420  = 1 << 4  Reserved\n    CS_RAW32 = 1 << 5 | CS_INTERLEAVED,\n\n    //  YV12 must be 0xA0000008. v2.5 Baked API will see all new planar as YV12.\n    //  I420 must be 0xA0000010.\n\n    CS_GENERIC_YUV444  = CS_PLANAR | CS_YUV | CS_VPlaneFirst | CS_Sub_Width_1 | CS_Sub_Height_1,  // 4:4:4 planar\n    CS_GENERIC_YUV422  = CS_PLANAR | CS_YUV | CS_VPlaneFirst | CS_Sub_Width_2 | CS_Sub_Height_1,  // 4:2:2 planar\n    CS_GENERIC_YUV420  = CS_PLANAR | CS_YUV | CS_VPlaneFirst | CS_Sub_Width_2 | CS_Sub_Height_2,  // 4:2:0 planar\n    CS_GENERIC_Y       = CS_PLANAR | CS_INTERLEAVED | CS_YUV,                                     // Y only (4:0:0)\n    CS_GENERIC_RGBP    = CS_PLANAR | CS_BGR | CS_RGB_TYPE,                                        // planar RGB. Though name is RGB but plane order G,B,R\n    CS_GENERIC_RGBAP   = CS_PLANAR | CS_BGR | CS_RGBA_TYPE,                                       // planar RGBA\n    CS_GENERIC_YUVA444 = CS_PLANAR | CS_YUVA | CS_VPlaneFirst | CS_Sub_Width_1 | CS_Sub_Height_1, // 4:4:4:A planar\n    CS_GENERIC_YUVA422 = CS_PLANAR | CS_YUVA | CS_VPlaneFirst | CS_Sub_Width_2 | CS_Sub_Height_1, // 4:2:2:A planar\n    CS_GENERIC_YUVA420 = CS_PLANAR | CS_YUVA | CS_VPlaneFirst | CS_Sub_Width_2 | CS_Sub_Height_2, // 4:2:0:A planar\n\n    CS_YV24  = CS_GENERIC_YUV444 | CS_Sample_Bits_8,  // YVU 4:4:4 planar\n    CS_YV16  = CS_GENERIC_YUV422 | CS_Sample_Bits_8,  // YVU 4:2:2 planar\n    CS_YV12  = CS_GENERIC_YUV420 | CS_Sample_Bits_8,  // YVU 4:2:0 planar\n    CS_I420  = CS_PLANAR | CS_YUV | CS_Sample_Bits_8 | CS_UPlaneFirst | CS_Sub_Width_2 | CS_Sub_Height_2,  // YUV 4:2:0 planar\n    CS_IYUV  = CS_I420,\n    CS_YUV9  = CS_PLANAR | CS_YUV | CS_Sample_Bits_8 | CS_VPlaneFirst | CS_Sub_Width_4 | CS_Sub_Height_4,  // YUV 4:1:0 planar\n    CS_YV411 = CS_PLANAR | CS_YUV | CS_Sample_Bits_8 | CS_VPlaneFirst | CS_Sub_Width_4 | CS_Sub_Height_1,  // YUV 4:1:1 planar\n\n    CS_Y8    = CS_GENERIC_Y | CS_Sample_Bits_8,                                                            // Y   4:0:0 planar\n\n    //-------------------------\n    // AVS16: new planar constants go live! Experimental PF 160613\n    // 10-12-14 bit + planar RGB + BRG48/64 160725\n\n    CS_YUV444P10 = CS_GENERIC_YUV444 | CS_Sample_Bits_10, // YUV 4:4:4 10bit samples\n    CS_YUV422P10 = CS_GENERIC_YUV422 | CS_Sample_Bits_10, // YUV 4:2:2 10bit samples\n    CS_YUV420P10 = CS_GENERIC_YUV420 | CS_Sample_Bits_10, // YUV 4:2:0 10bit samples\n    CS_Y10 = CS_GENERIC_Y | CS_Sample_Bits_10,            // Y   4:0:0 10bit samples\n\n    CS_YUV444P12 = CS_GENERIC_YUV444 | CS_Sample_Bits_12, // YUV 4:4:4 12bit samples\n    CS_YUV422P12 = CS_GENERIC_YUV422 | CS_Sample_Bits_12, // YUV 4:2:2 12bit samples\n    CS_YUV420P12 = CS_GENERIC_YUV420 | CS_Sample_Bits_12, // YUV 4:2:0 12bit samples\n    CS_Y12 = CS_GENERIC_Y | CS_Sample_Bits_12,            // Y   4:0:0 12bit samples\n\n    CS_YUV444P14 = CS_GENERIC_YUV444 | CS_Sample_Bits_14, // YUV 4:4:4 14bit samples\n    CS_YUV422P14 = CS_GENERIC_YUV422 | CS_Sample_Bits_14, // YUV 4:2:2 14bit samples\n    CS_YUV420P14 = CS_GENERIC_YUV420 | CS_Sample_Bits_14, // YUV 4:2:0 14bit samples\n    CS_Y14 = CS_GENERIC_Y | CS_Sample_Bits_14,            // Y   4:0:0 14bit samples\n\n    CS_YUV444P16 = CS_GENERIC_YUV444 | CS_Sample_Bits_16, // YUV 4:4:4 16bit samples\n    CS_YUV422P16 = CS_GENERIC_YUV422 | CS_Sample_Bits_16, // YUV 4:2:2 16bit samples\n    CS_YUV420P16 = CS_GENERIC_YUV420 | CS_Sample_Bits_16, // YUV 4:2:0 16bit samples\n    CS_Y16 = CS_GENERIC_Y | CS_Sample_Bits_16,            // Y   4:0:0 16bit samples\n\n    // 32 bit samples (float)\n    CS_YUV444PS = CS_GENERIC_YUV444 | CS_Sample_Bits_32,  // YUV 4:4:4 32bit samples\n    CS_YUV422PS = CS_GENERIC_YUV422 | CS_Sample_Bits_32,  // YUV 4:2:2 32bit samples\n    CS_YUV420PS = CS_GENERIC_YUV420 | CS_Sample_Bits_32,  // YUV 4:2:0 32bit samples\n    CS_Y32 = CS_GENERIC_Y | CS_Sample_Bits_32,            // Y   4:0:0 32bit samples\n\n    // RGB packed\n    CS_BGR48 = CS_RGB_TYPE  | CS_BGR | CS_INTERLEAVED | CS_Sample_Bits_16, // BGR 3x16 bit\n    CS_BGR64 = CS_RGBA_TYPE | CS_BGR | CS_INTERLEAVED | CS_Sample_Bits_16, // BGR 4x16 bit\n    // no packed 32 bit (float) support for these legacy types\n\n    // RGB planar\n    CS_RGBP   = CS_GENERIC_RGBP | CS_Sample_Bits_8,  // Planar RGB 8 bit samples\n    CS_RGBP8  = CS_GENERIC_RGBP | CS_Sample_Bits_8,  // Planar RGB 8 bit samples\n    CS_RGBP10 = CS_GENERIC_RGBP | CS_Sample_Bits_10, // Planar RGB 10bit samples\n    CS_RGBP12 = CS_GENERIC_RGBP | CS_Sample_Bits_12, // Planar RGB 12bit samples\n    CS_RGBP14 = CS_GENERIC_RGBP | CS_Sample_Bits_14, // Planar RGB 14bit samples\n    CS_RGBP16 = CS_GENERIC_RGBP | CS_Sample_Bits_16, // Planar RGB 16bit samples\n    CS_RGBPS  = CS_GENERIC_RGBP | CS_Sample_Bits_32, // Planar RGB 32bit samples\n\n    // RGBA planar\n    CS_RGBAP   = CS_GENERIC_RGBAP | CS_Sample_Bits_8,  // Planar RGBA 8 bit samples\n    CS_RGBAP8  = CS_GENERIC_RGBAP | CS_Sample_Bits_8,  // Planar RGBA 8 bit samples\n    CS_RGBAP10 = CS_GENERIC_RGBAP | CS_Sample_Bits_10, // Planar RGBA 10bit samples\n    CS_RGBAP12 = CS_GENERIC_RGBAP | CS_Sample_Bits_12, // Planar RGBA 12bit samples\n    CS_RGBAP14 = CS_GENERIC_RGBAP | CS_Sample_Bits_14, // Planar RGBA 14bit samples\n    CS_RGBAP16 = CS_GENERIC_RGBAP | CS_Sample_Bits_16, // Planar RGBA 16bit samples\n    CS_RGBAPS  = CS_GENERIC_RGBAP | CS_Sample_Bits_32, // Planar RGBA 32bit samples\n\n    // Planar YUVA\n    CS_YUVA444    = CS_GENERIC_YUVA444 | CS_Sample_Bits_8,  // YUVA 4:4:4 8bit samples\n    CS_YUVA422    = CS_GENERIC_YUVA422 | CS_Sample_Bits_8,  // YUVA 4:2:2 8bit samples\n    CS_YUVA420    = CS_GENERIC_YUVA420 | CS_Sample_Bits_8,  // YUVA 4:2:0 8bit samples\n\n    CS_YUVA444P10 = CS_GENERIC_YUVA444 | CS_Sample_Bits_10, // YUVA 4:4:4 10bit samples\n    CS_YUVA422P10 = CS_GENERIC_YUVA422 | CS_Sample_Bits_10, // YUVA 4:2:2 10bit samples\n    CS_YUVA420P10 = CS_GENERIC_YUVA420 | CS_Sample_Bits_10, // YUVA 4:2:0 10bit samples\n\n    CS_YUVA444P12 = CS_GENERIC_YUVA444 | CS_Sample_Bits_12, // YUVA 4:4:4 12bit samples\n    CS_YUVA422P12 = CS_GENERIC_YUVA422 | CS_Sample_Bits_12, // YUVA 4:2:2 12bit samples\n    CS_YUVA420P12 = CS_GENERIC_YUVA420 | CS_Sample_Bits_12, // YUVA 4:2:0 12bit samples\n\n    CS_YUVA444P14 = CS_GENERIC_YUVA444 | CS_Sample_Bits_14, // YUVA 4:4:4 14bit samples\n    CS_YUVA422P14 = CS_GENERIC_YUVA422 | CS_Sample_Bits_14, // YUVA 4:2:2 14bit samples\n    CS_YUVA420P14 = CS_GENERIC_YUVA420 | CS_Sample_Bits_14, // YUVA 4:2:0 14bit samples\n\n    CS_YUVA444P16 = CS_GENERIC_YUVA444 | CS_Sample_Bits_16, // YUVA 4:4:4 16bit samples\n    CS_YUVA422P16 = CS_GENERIC_YUVA422 | CS_Sample_Bits_16, // YUVA 4:2:2 16bit samples\n    CS_YUVA420P16 = CS_GENERIC_YUVA420 | CS_Sample_Bits_16, // YUVA 4:2:0 16bit samples\n\n    CS_YUVA444PS  = CS_GENERIC_YUVA444 | CS_Sample_Bits_32,  // YUVA 4:4:4 32bit samples\n    CS_YUVA422PS  = CS_GENERIC_YUVA422 | CS_Sample_Bits_32,  // YUVA 4:2:2 32bit samples\n    CS_YUVA420PS  = CS_GENERIC_YUVA420 | CS_Sample_Bits_32,  // YUVA 4:2:0 32bit samples\n  };\n\n  int pixel_type;                // changed to int as of 2.5\n\n  int audio_samples_per_second;   // 0 means no audio\n  int sample_type;                // as of 2.5\n  int64_t num_audio_samples;      // changed as of 2.5\n  int nchannels;                  // as of 2.5\n\n  // BFF, TFF, FIELDBASED. Also used for storing Channel Mask\n  int image_type;\n\n  enum AvsImageTypeFlags {\n    IT_BFF = 1 << 0,\n    IT_TFF = 1 << 1,\n    IT_FIELDBASED = 1 << 2,\n\n    // Audio channel mask support\n    IT_HAS_CHANNELMASK = 1 << 3,\n    // shifted by 4 bits compared to WAVEFORMATEXTENSIBLE dwChannelMask\n    // otherwise same as AvsChannelMask\n    IT_SPEAKER_FRONT_LEFT = 0x1 << 4,\n    IT_SPEAKER_FRONT_RIGHT = 0x2 << 4,\n    IT_SPEAKER_FRONT_CENTER = 0x4 << 4,\n    IT_SPEAKER_LOW_FREQUENCY = 0x8 << 4,\n    IT_SPEAKER_BACK_LEFT = 0x10 << 4,\n    IT_SPEAKER_BACK_RIGHT = 0x20 << 4,\n    IT_SPEAKER_FRONT_LEFT_OF_CENTER = 0x40 << 4,\n    IT_SPEAKER_FRONT_RIGHT_OF_CENTER = 0x80 << 4,\n    IT_SPEAKER_BACK_CENTER = 0x100 << 4,\n    IT_SPEAKER_SIDE_LEFT = 0x200 << 4,\n    IT_SPEAKER_SIDE_RIGHT = 0x400 << 4,\n    IT_SPEAKER_TOP_CENTER = 0x800 << 4,\n    IT_SPEAKER_TOP_FRONT_LEFT = 0x1000 << 4,\n    IT_SPEAKER_TOP_FRONT_CENTER = 0x2000 << 4,\n    IT_SPEAKER_TOP_FRONT_RIGHT = 0x4000 << 4,\n    IT_SPEAKER_TOP_BACK_LEFT = 0x8000 << 4,\n    IT_SPEAKER_TOP_BACK_CENTER = 0x10000 << 4,\n    IT_SPEAKER_TOP_BACK_RIGHT = 0x20000 << 4,\n    // End of officially defined speaker bits\n    // The next one is special, since cannot shift SPEAKER_ALL 0x80000000 further.\n    // Set mask and get mask handles it.\n    IT_SPEAKER_ALL = 0x40000 << 4,\n    // Mask for the defined 18 bits + SPEAKER_ALL\n    IT_SPEAKER_BITS_MASK = (AvsChannelMask::MASK_SPEAKER_DEFINED << 4) | IT_SPEAKER_ALL,\n    IT_NEXT_AVAILABLE = 1 << 23\n  };\n\n  // Chroma placement bits 20 -> 23  ::FIXME:: Really want a Class to support this\n  enum AvsChromaPlacement {\n    CS_UNKNOWN_CHROMA_PLACEMENT = 0 << 20,\n    CS_MPEG1_CHROMA_PLACEMENT   = 1 << 20,\n    CS_MPEG2_CHROMA_PLACEMENT   = 2 << 20,\n    CS_YUY2_CHROMA_PLACEMENT    = 3 << 20,\n    CS_TOPLEFT_CHROMA_PLACEMENT = 4 << 20\n  };\n\n  // useful functions of the above\n  bool HasVideo() const AVS_BakedCode(return AVS_LinkCall(HasVideo)())\n  bool HasAudio() const AVS_BakedCode(return AVS_LinkCall(HasAudio)())\n  bool IsRGB() const AVS_BakedCode(return AVS_LinkCall(IsRGB)())\n  bool IsRGB24() const AVS_BakedCode(return AVS_LinkCall(IsRGB24)())\n  bool IsRGB32() const AVS_BakedCode(return AVS_LinkCall(IsRGB32)())\n  bool IsYUV() const AVS_BakedCode(return AVS_LinkCall(IsYUV)())\n  bool IsYUY2() const AVS_BakedCode(return AVS_LinkCall(IsYUY2)())\n\n  bool IsYV24()  const AVS_BakedCode(return AVS_LinkCall(IsYV24)())\n  bool IsYV16()  const AVS_BakedCode(return AVS_LinkCall(IsYV16)())\n  bool IsYV12()  const AVS_BakedCode(return AVS_LinkCall(IsYV12)())\n  bool IsYV411() const AVS_BakedCode(return AVS_LinkCall(IsYV411)())\n  //bool IsYUV9()  const;\n  bool IsY8()    const AVS_BakedCode(return AVS_LinkCall(IsY8)())\n\n  bool IsColorSpace(int c_space) const AVS_BakedCode(return AVS_LinkCall(IsColorSpace)(c_space))\n\n  bool Is(int property) const AVS_BakedCode(return AVS_LinkCall(Is)(property))\n  bool IsPlanar() const AVS_BakedCode(return AVS_LinkCall(IsPlanar)())\n  bool IsFieldBased() const AVS_BakedCode(return AVS_LinkCall(IsFieldBased)())\n  bool IsParityKnown() const AVS_BakedCode(return AVS_LinkCall(IsParityKnown)())\n  bool IsBFF() const AVS_BakedCode(return AVS_LinkCall(IsBFF)())\n  bool IsTFF() const AVS_BakedCode(return AVS_LinkCall(IsTFF)())\n\n  bool IsVPlaneFirst() const AVS_BakedCode(return AVS_LinkCall(IsVPlaneFirst)())  // Don't use this\n  // Will not work on planar images, but will return only luma planes\n  int BytesFromPixels(int pixels) const AVS_BakedCode(return AVS_LinkCall(BytesFromPixels)(pixels))\n  int RowSize(int plane = DEFAULT_PLANE) const AVS_BakedCode(return AVS_LinkCall(RowSize)(plane))\n  int BMPSize() const AVS_BakedCode(return AVS_LinkCall(BMPSize)())\n\n  int64_t AudioSamplesFromFrames(int frames) const AVS_BakedCode(return AVS_LinkCall(AudioSamplesFromFrames)(frames))\n  int FramesFromAudioSamples(int64_t samples) const AVS_BakedCode(return AVS_LinkCall(FramesFromAudioSamples)(samples))\n  int64_t AudioSamplesFromBytes(int64_t bytes) const AVS_BakedCode(return AVS_LinkCall(AudioSamplesFromBytes)(bytes))\n  int64_t BytesFromAudioSamples(int64_t samples) const AVS_BakedCode(return AVS_LinkCall(BytesFromAudioSamples)(samples))\n  int AudioChannels() const AVS_BakedCode(return AVS_LinkCall(AudioChannels)())\n  int SampleType() const AVS_BakedCode(return AVS_LinkCall(SampleType)())\n  bool IsSampleType(int testtype) const AVS_BakedCode(return AVS_LinkCall(IsSampleType)(testtype))\n  int SamplesPerSecond() const AVS_BakedCode(return AVS_LinkCall(SamplesPerSecond)())\n  int BytesPerAudioSample() const AVS_BakedCode(return AVS_LinkCall(BytesPerAudioSample)())\n  void SetFieldBased(bool isfieldbased) AVS_BakedCode(AVS_LinkCall_Void(SetFieldBased)(isfieldbased))\n  void Set(int property) AVS_BakedCode(AVS_LinkCall_Void(Set)(property))\n  void Clear(int property) AVS_BakedCode(AVS_LinkCall_Void(Clear)(property))\n  // Subsampling in bitshifts!\n  int GetPlaneWidthSubsampling(int plane) const AVS_BakedCode(return AVS_LinkCall(GetPlaneWidthSubsampling)(plane))\n  int GetPlaneHeightSubsampling(int plane) const AVS_BakedCode(return AVS_LinkCall(GetPlaneHeightSubsampling)(plane))\n  int BitsPerPixel() const AVS_BakedCode(return AVS_LinkCall(BitsPerPixel)())\n\n  int BytesPerChannelSample() const AVS_BakedCode(return AVS_LinkCall(BytesPerChannelSample)())\n\n  // useful mutator\n  void SetFPS(unsigned numerator, unsigned denominator) AVS_BakedCode(AVS_LinkCall_Void(SetFPS)(numerator, denominator))\n\n  // Range protected multiply-divide of FPS\n  void MulDivFPS(unsigned multiplier, unsigned divisor) AVS_BakedCode(AVS_LinkCall_Void(MulDivFPS)(multiplier, divisor))\n\n  // Test for same colorspace\n  bool IsSameColorspace(const VideoInfo& vi) const AVS_BakedCode(return AVS_LinkCall(IsSameColorspace)(vi))\n\n  // AVS+ extensions\n  // 20161005:\n  //   Mapping of AVS+ extensions to classic 2.6 functions.\n  //   In order to use these extended AVS+ functions for plugins that should work\n  //   either with AVS+ or with Classic (8 bit) Avs 2.6 ans earlier AVS+ versions, there is an\n  //   automatic fallback mechanism.\n  //   From AVS+'s point of view these are not \"baked\" codes, the primary functions should exist.\n  //   Examples:\n  //   Is444() is mapped to IsYV24() for classic AVS2.6\n  //   ComponentSize() returns constant 1 (1 bytes per pixel component)\n  //   BitsPerComponent() returns constant 8 (Classic AVS2.6 is 8 bit only)\n\n  // Returns the number of color channels or planes in a frame\n  int NumComponents() const AVS_BakedCode(return AVS_LinkCallOptDefault(NumComponents, (((AVS_LinkCall(IsYUV)()) && !(AVS_LinkCall(IsY8)())) ? 3 : AVS_LinkCall(BytesFromPixels)(1)) ) )\n\n  // Returns the size in bytes of a single component of a pixel\n  int ComponentSize() const AVS_BakedCode(return AVS_LinkCallOptDefault(ComponentSize, 1))\n\n  // Returns the bit depth of a single component of a pixel\n  int BitsPerComponent() const AVS_BakedCode(return AVS_LinkCallOptDefault(BitsPerComponent, 8))\n\n  // like IsYV24, but bit-depth independent also for YUVA\n  bool Is444() const AVS_BakedCode(return AVS_LinkCallOpt(Is444, IsYV24) )\n\n  // like IsYV16, but bit-depth independent also for YUVA\n  bool Is422() const AVS_BakedCode(return AVS_LinkCallOpt(Is422, IsYV16) )\n\n  // like IsYV12, but bit-depth independent also for YUVA\n  bool Is420() const AVS_BakedCode( return AVS_LinkCallOpt(Is420, IsYV12) )\n\n  // like IsY8, but bit-depth independent\n  bool IsY()   const AVS_BakedCode( return AVS_LinkCallOpt(IsY, IsY8) )\n\n  // like IsRGB24 for 16 bit samples\n  bool IsRGB48() const AVS_BakedCode( return AVS_LinkCallOptDefault(IsRGB48, false) )\n\n  // like IsRGB32 for 16 bit samples\n  bool IsRGB64() const AVS_BakedCode( return AVS_LinkCallOptDefault(IsRGB64, false) )\n\n  // YUVA?\n  bool IsYUVA() const AVS_BakedCode( return AVS_LinkCallOptDefault(IsYUVA, false) )\n\n  // Planar RGB?\n  bool IsPlanarRGB() const AVS_BakedCode( return AVS_LinkCallOptDefault(IsPlanarRGB, false) )\n\n  // Planar RGBA?\n  bool IsPlanarRGBA() const AVS_BakedCode( return AVS_LinkCallOptDefault(IsPlanarRGBA, false) )\n\n  // v10.1 interface: audio channel masks\n  bool IsChannelMaskKnown() const AVS_BakedCode(return AVS_LinkCallOptDefault(IsChannelMaskKnown, false) )\n  void SetChannelMask(bool isChannelMaskKnown, unsigned int dwChannelMask) AVS_BakedCode(AVS_LinkCall_Void(SetChannelMask)(isChannelMaskKnown, dwChannelMask))\n  unsigned int GetChannelMask() const AVS_BakedCode(return AVS_LinkCallOptDefault(GetChannelMask, 0) )\n\n}; // end struct VideoInfo\n\n\n\n\n// VideoFrameBuffer holds information about a memory block which is used\n// for video data.  For efficiency, instances of this class are not deleted\n// when the refcount reaches zero; instead they're stored in a linked list\n// to be reused.  The instances are deleted when the corresponding AVS\n// file is closed.\n\nclass VideoFrameBuffer {\n  BYTE* data;\n  int data_size;\n  // sequence_number is incremented every time the buffer is changed, so\n  // that stale views can tell they're no longer valid.\n  volatile long sequence_number;\n\n  friend class VideoFrame;\n  friend class AvsCache;\n  friend class ScriptEnvironment;\n  volatile long refcount;\n\n  // AVS+CUDA extension, does not break plugins if appended here\n  Device* device;\n\nprotected:\n  VideoFrameBuffer(int size, int margin, Device* device);\n  VideoFrameBuffer();\n\npublic:\n  ~VideoFrameBuffer() AVS_BakedCode(AVS_LinkCall_Void(VideoFrameBuffer_DESTRUCTOR)())\n\n  const BYTE* GetReadPtr() const AVS_BakedCode( return AVS_LinkCall(VFBGetReadPtr)() )\n  BYTE* GetWritePtr() AVS_BakedCode( return AVS_LinkCall(VFBGetWritePtr)() )\n  int GetDataSize() const AVS_BakedCode( return AVS_LinkCall(GetDataSize)() )\n  int GetSequenceNumber() const AVS_BakedCode( return AVS_LinkCall(GetSequenceNumber)() )\n  int GetRefcount() const AVS_BakedCode( return AVS_LinkCall(GetRefcount)() )\n\n// Ensure VideoFrameBuffer cannot be publicly assigned\nprivate:\n  VideoFrameBuffer& operator=(const VideoFrameBuffer&);\n\n#ifdef BUILDING_AVSCORE\npublic:\n    void DESTRUCTOR();  /* Damn compiler won't allow taking the address of reserved constructs, make a dummy interlude */\n#endif\n}; // end class VideoFrameBuffer\n\n\n// smart pointer to VideoFrame\nclass PVideoFrame {\n\n  VideoFrame* p;\n\n  void Init(VideoFrame* x);\n  void Set(VideoFrame* x);\n\npublic:\n  PVideoFrame() AVS_BakedCode(AVS_LinkCall_Void(PVideoFrame_CONSTRUCTOR0)())\n    PVideoFrame(const PVideoFrame& x) AVS_BakedCode(AVS_LinkCall_Void(PVideoFrame_CONSTRUCTOR1)(x))\n    PVideoFrame(VideoFrame* x) AVS_BakedCode(AVS_LinkCall_Void(PVideoFrame_CONSTRUCTOR2)(x))\n    void operator=(VideoFrame* x) AVS_BakedCode(AVS_LinkCall_Void(PVideoFrame_OPERATOR_ASSIGN0)(x))\n    void operator=(const PVideoFrame& x) AVS_BakedCode(AVS_LinkCall_Void(PVideoFrame_OPERATOR_ASSIGN1)(x))\n\n    VideoFrame* operator->() const { return p; }\n\n  // for conditional expressions\n  operator void*() const { return p; }\n  bool operator!() const { return !p; }\n\n  ~PVideoFrame() AVS_BakedCode(AVS_LinkCall_Void(PVideoFrame_DESTRUCTOR)())\n#ifdef BUILDING_AVSCORE\npublic:\n  void CONSTRUCTOR0();  /* Damn compiler won't allow taking the address of reserved constructs, make a dummy interlude */\n  void CONSTRUCTOR1(const PVideoFrame& x);\n  void CONSTRUCTOR2(VideoFrame* x);\n  void OPERATOR_ASSIGN0(VideoFrame* x);\n  void OPERATOR_ASSIGN1(const PVideoFrame& x);\n  void DESTRUCTOR();\n#endif\n}; // end class PVideoFrame\n\n\n// VideoFrame holds a \"window\" into a VideoFrameBuffer.  Operator new\n// is overloaded to recycle class instances.\n\nclass VideoFrame {\n  volatile long refcount;\n  VideoFrameBuffer* vfb;\n\n  // Due to technical reasons these members are not const, but should be treated as such.\n  // That means do not modify them once the class has been constructed.\n  int offset;\n  int pitch, row_size, height;\n  int offsetU, offsetV;  // U&V offsets are from top of picture.\n  int pitchUV, row_sizeUV, heightUV; // for Planar RGB offsetU, offsetV is for the 2nd and 3rd Plane.\n                            // for Planar RGB pitchUV and row_sizeUV = 0, because when no VideoInfo (MakeWriteable)\n                            // the decision on existance of UV is checked by zero pitch\n  // AVS+ extension, does not break plugins if appended here\n  int offsetA;\n  int pitchA, row_sizeA; // 4th alpha plane support, pitch and row_size is 0 is none\n\n  AVSMap *properties;\n\n  // this one is changable by AmendPixelType in rare cases\n  int pixel_type; // V10 - Copy from VideoInfo\n\n  friend class PVideoFrame;\n  void AddRef();\n  void Release();\n\n  friend class ScriptEnvironment;\n  friend class AvsCache;\n\n  VideoFrame(VideoFrameBuffer* _vfb, AVSMap* avsmap, int _offset, int _pitch, int _row_size, int _height, int _pixel_type);\n  VideoFrame(VideoFrameBuffer* _vfb, AVSMap* avsmap, int _offset, int _pitch, int _row_size, int _height, int _offsetU, int _offsetV, int _pitchUV, int _row_sizeUV, int _heightUV, int _pixel_type);\n  // for Alpha\n  VideoFrame(VideoFrameBuffer* _vfb, AVSMap* avsmap, int _offset, int _pitch, int _row_size, int _height, int _offsetU, int _offsetV, int _pitchUV, int _row_sizeUV, int _heightUV, int _offsetA, int _pixel_type);\n  void* operator new(size_t size);\n// TESTME: OFFSET U/V may be switched to what could be expected from AVI standard!\npublic:\n  int GetPitch(int plane = DEFAULT_PLANE) const AVS_BakedCode( return AVS_LinkCall(GetPitch)(plane) )\n  int GetRowSize(int plane = DEFAULT_PLANE) const AVS_BakedCode( return AVS_LinkCall(GetRowSize)(plane) )\n  int GetHeight(int plane = DEFAULT_PLANE) const AVS_BakedCode( return AVS_LinkCall(GetHeight)(plane) )\n\n  // generally you shouldn't use these three\n  VideoFrameBuffer* GetFrameBuffer() const AVS_BakedCode( return AVS_LinkCall(GetFrameBuffer)() )\n  int GetOffset(int plane = DEFAULT_PLANE) const AVS_BakedCode( return AVS_LinkCall(GetOffset)(plane) )\n\n  // in plugins use env->SubFrame() -- because implementation code is only available inside avisynth.dll. Doh!\n  VideoFrame* Subframe(int rel_offset, int new_pitch, int new_row_size, int new_height) const;\n  VideoFrame* Subframe(int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int pitchUV) const;\n  // for Alpha\n  VideoFrame* Subframe(int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int pitchUV, int rel_offsetA) const;\n\n  const BYTE* GetReadPtr(int plane = DEFAULT_PLANE) const AVS_BakedCode( return AVS_LinkCall(VFGetReadPtr)(plane) )\n  bool IsWritable() const AVS_BakedCode( return AVS_LinkCall(IsWritable)() )\n  BYTE* GetWritePtr(int plane = DEFAULT_PLANE) const AVS_BakedCode( return AVS_LinkCall(VFGetWritePtr)(plane) )\n\n  AVSMap& getProperties() AVS_BakedCode(return AVS_LinkCallOptDefault(getProperties, (AVSMap&)*(AVSMap*)0))\n  const AVSMap& getConstProperties() AVS_BakedCode(return AVS_LinkCallOptDefault(getConstProperties, (const AVSMap&)*(const AVSMap*)0))\n  void setProperties(const AVSMap & _properties) AVS_BakedCode(AVS_LinkCall_Void(setProperties)(_properties))\n\n  PDevice GetDevice() const AVS_BakedCode(return AVS_LinkCall(VideoFrame_GetDevice)())\n\n  // 0: OK, 1: NG, -1: disabled or non CPU frame\n  int CheckMemory() const AVS_BakedCode(return AVS_LinkCall(VideoFrame_CheckMemory)())\n\n  bool IsPropertyWritable() const AVS_BakedCode(return AVS_LinkCall(IsPropertyWritable)())\n\n  ~VideoFrame() AVS_BakedCode( AVS_LinkCall_Void(VideoFrame_DESTRUCTOR)() )\n\n  int GetPixelType() const AVS_BakedCode(return AVS_LinkCall(VideoFrame_GetPixelType)())\n  // Changes the color format metadata on this frame. Using it on a frame that isn't writable leads\n  // to an inconsistent state, because other filters depend on it. So, use MakeWritable() before.\n  // Only for rare cases where a plugin makes frame bytes pose as another color format.\n  void AmendPixelType(int new_pixel_type) AVS_BakedCode(return AVS_LinkCall_Void(VideoFrame_AmendPixelType)(new_pixel_type))\n\n#ifdef BUILDING_AVSCORE\npublic:\n  void DESTRUCTOR();  /* Damn compiler won't allow taking the address of reserved constructs, make a dummy interlude */\n#endif\n\n// Ensure VideoFrame cannot be publicly assigned\nprivate:\n    VideoFrame& operator=(const VideoFrame&);\n\n}; // end class VideoFrame\n\nenum CachePolicyHint {\n  CACHE_25_NOTHING_26_UNUSED_0 = 0,\n  // Values 0 to 5 are reserved for old 2.5 plugins\n  // do not use them in new plugins\n\n  // New 2.6 explicitly defined cache hints.\n  CACHE_NOTHING = 10, // Do not cache video.\n  CACHE_WINDOW = 11, // Hard protect upto X frames within a range of X from the current frame N.\n  CACHE_GENERIC = 12, // LRU cache upto X frames.\n  CACHE_FORCE_GENERIC = 13, // LRU cache upto X frames, override any previous CACHE_WINDOW.\n\n  CACHE_GET_POLICY = 30, // Get the current policy.\n  CACHE_GET_WINDOW = 31, // Get the current window h_span.\n  CACHE_GET_RANGE = 32, // Get the current generic frame range.\n\n  // Set Audio cache mode and answers to CACHE_GETCHILD_AUDIO_MODE\n  CACHE_AUDIO = 50, // Explicitly cache audio, X byte cache.\n  CACHE_AUDIO_NOTHING = 51, // Explicitly do not cache audio.\n  CACHE_AUDIO_NONE = 52, // Audio cache off (auto mode), X byte initial cache.\n  CACHE_AUDIO_AUTO_START_OFF = 52, // synonym\n  CACHE_AUDIO_AUTO = 53, // Audio cache on (auto mode), X byte initial cache.\n  CACHE_AUDIO_AUTO_START_ON = 53, // synonym\n\n  // These just returns actual value if clip is cached\n  CACHE_GET_AUDIO_POLICY = 70, // Get the current audio policy.\n  CACHE_GET_AUDIO_SIZE = 71, // Get the current audio cache size.\n\n  CACHE_PREFETCH_FRAME = 100, // n/a Queue request to prefetch frame N.\n  CACHE_PREFETCH_GO = 101, // n/a Action video prefetches.\n\n  CACHE_PREFETCH_AUDIO_BEGIN = 120, // n/a Begin queue request transaction to prefetch audio (take critical section).\n  CACHE_PREFETCH_AUDIO_STARTLO = 121, // n/a Set low 32 bits of start.\n  CACHE_PREFETCH_AUDIO_STARTHI = 122, // n/a Set high 32 bits of start.\n  CACHE_PREFETCH_AUDIO_COUNT = 123, // n/a Set low 32 bits of length.\n  CACHE_PREFETCH_AUDIO_COMMIT = 124, // n/a Enqueue request transaction to prefetch audio (release critical section).\n  CACHE_PREFETCH_AUDIO_GO = 125, // n/a Action audio prefetches.\n\n  CACHE_GETCHILD_CACHE_MODE = 200, // n/a Cache ask Child for desired video cache mode.\n  CACHE_GETCHILD_CACHE_SIZE = 201, // n/a Cache ask Child for desired video cache size.\n\n  // Filters are queried about their desired audio cache mode.\n  // Child can answer them with CACHE_AUDIO_xxx\n  CACHE_GETCHILD_AUDIO_MODE = 202, // Cache ask Child for desired audio cache mode.\n  CACHE_GETCHILD_AUDIO_SIZE = 203, // Cache ask Child for desired audio cache size.\n\n  CACHE_GETCHILD_COST = 220, // n/a Cache ask Child for estimated processing cost.\n    CACHE_COST_ZERO = 221, // n/a Child response of zero cost (ptr arithmetic only).\n    CACHE_COST_UNIT = 222, // n/a Child response of unit cost (less than or equal 1 full frame blit).\n    CACHE_COST_LOW = 223, // n/a Child response of light cost. (Fast)\n    CACHE_COST_MED = 224, // n/a Child response of medium cost. (Real time)\n    CACHE_COST_HI = 225, // n/a Child response of heavy cost. (Slow)\n\n  CACHE_GETCHILD_THREAD_MODE = 240, // n/a Cache ask Child for thread safetyness.\n    CACHE_THREAD_UNSAFE = 241, // n/a Only 1 thread allowed for all instances. 2.5 filters default!\n    CACHE_THREAD_CLASS = 242, // n/a Only 1 thread allowed for each instance. 2.6 filters default!\n    CACHE_THREAD_SAFE = 243, // n/a Allow all threads in any instance.\n    CACHE_THREAD_OWN = 244, // n/a Safe but limit to 1 thread, internally threaded.\n\n  CACHE_GETCHILD_ACCESS_COST = 260, // n/a Cache ask Child for preferred access pattern.\n    CACHE_ACCESS_RAND = 261, // n/a Filter is access order agnostic.\n    CACHE_ACCESS_SEQ0 = 262, // n/a Filter prefers sequential access (low cost)\n    CACHE_ACCESS_SEQ1 = 263, // n/a Filter needs sequential access (high cost)\n\n  CACHE_AVSPLUS_CONSTANTS = 500,    // Smaller values are reserved for classic Avisynth\n\n  CACHE_DONT_CACHE_ME,              // Filters that don't need caching (eg. trim, cache etc.) should return 1 to this request\n  CACHE_SET_MIN_CAPACITY,\n  CACHE_SET_MAX_CAPACITY,\n  CACHE_GET_MIN_CAPACITY,\n  CACHE_GET_MAX_CAPACITY,\n  CACHE_GET_SIZE,\n  CACHE_GET_REQUESTED_CAP,\n  CACHE_GET_CAPACITY,\n  CACHE_GET_MTMODE,                 // Filters specify their desired MT mode, see enum MtMode\n\n  // By returning IS_CACHE_ANS to IS_CACHE_REQ, we tell the caller we are a cache\n  CACHE_IS_CACHE_REQ,\n  CACHE_IS_CACHE_ANS,\n  // By returning IS_MTGUARD_ANS to IS_MTGUARD_REQ, we tell the caller we are an mt guard\n  CACHE_IS_MTGUARD_REQ,\n  CACHE_IS_MTGUARD_ANS,\n\n  // v12\n  CACHE_INFORM_NUM_THREADS, // Allows a filter to receive the number of prefetch threads via SetCacheHints\n\n  CACHE_AVSPLUS_CUDA_CONSTANTS = 600,\n\n  CACHE_GET_DEV_TYPE,          // Device types a filter can return\n  CACHE_GET_CHILD_DEV_TYPE,    // Device types a filter can receive\n\n  CACHE_USER_CONSTANTS = 1000       // Smaller values are reserved for the core\n};\n\n// Base class for all filters.\nclass IClip {\n  friend class PClip;\n  friend class AVSValue;\n  volatile long refcnt;\n  void AddRef();\n#if BUILDING_AVSCORE\npublic:\n#endif\n  void Release();\npublic:\n  IClip() : refcnt(0) {}\n  virtual int __stdcall GetVersion() { return AVISYNTH_INTERFACE_VERSION; }\n  virtual PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) = 0;\n  virtual bool __stdcall GetParity(int n) = 0;  // return field parity if field_based, else parity of first field in frame\n  virtual void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) = 0;  // start and count are in samples\n  /* Need to check GetVersion first, pre v5 will return random crap from EAX reg. */\n  virtual int __stdcall SetCacheHints(int cachehints,int frame_range) = 0 ;  // We do not pass cache requests upwards, only to the next filter.\n  virtual const VideoInfo& __stdcall GetVideoInfo() = 0;\n  virtual ~IClip() {}\n}; // end class IClip\n\n\n// smart pointer to IClip\nclass PClip {\n\n  IClip* p;\n\n  IClip* GetPointerWithAddRef() const;\n  friend class AVSValue;\n  friend class VideoFrame;\n\n  void Init(IClip* x);\n  void Set(IClip* x);\n\npublic:\n  PClip() AVS_BakedCode( AVS_LinkCall_Void(PClip_CONSTRUCTOR0)() )\n  PClip(const PClip& x) AVS_BakedCode( AVS_LinkCall_Void(PClip_CONSTRUCTOR1)(x) )\n  PClip(IClip* x) AVS_BakedCode( AVS_LinkCall_Void(PClip_CONSTRUCTOR2)(x) )\n  void operator=(IClip* x) AVS_BakedCode( AVS_LinkCall_Void(PClip_OPERATOR_ASSIGN0)(x) )\n  void operator=(const PClip& x) AVS_BakedCode( AVS_LinkCall_Void(PClip_OPERATOR_ASSIGN1)(x) )\n\n  IClip* operator->() const { return p; }\n\n  // useful in conditional expressions\n  operator void*() const { return p; }\n  bool operator!() const { return !p; }\n\n  ~PClip() AVS_BakedCode( AVS_LinkCall_Void(PClip_DESTRUCTOR)() )\n#ifdef BUILDING_AVSCORE\npublic:\n  void CONSTRUCTOR0();  /* Damn compiler won't allow taking the address of reserved constructs, make a dummy interlude */\n  void CONSTRUCTOR1(const PClip& x);\n  void CONSTRUCTOR2(IClip* x);\n  void OPERATOR_ASSIGN0(IClip* x);\n  void OPERATOR_ASSIGN1(const PClip& x);\n  void DESTRUCTOR();\n#endif\n}; // end class PClip\n\nenum AVSPropTypes {\n  PROPTYPE_UNSET = 'u', // ptUnset\n  PROPTYPE_INT = 'i', // ptInt\n  PROPTYPE_FLOAT = 'f', // ptFloat\n  PROPTYPE_DATA = 's', // ptData\n  PROPTYPE_CLIP = 'c', // ptClip\n  PROPTYPE_FRAME = 'v' // ptFrame\n  //  ptFunction = 'm'\n};\n\nenum AVSGetPropErrors {\n  GETPROPERROR_SUCCESS = 0,\n  GETPROPERROR_UNSET = 1, // peUnset\n  GETPROPERROR_TYPE = 2, // peType\n  GETPROPERROR_ERROR = 3, // map has error state set\n  GETPROPERROR_INDEX = 4 // peIndex\n};\n\nenum AVSPropAppendMode {\n  PROPAPPENDMODE_REPLACE = 0, // paReplace\n  PROPAPPENDMODE_APPEND = 1, // paAppend\n  PROPAPPENDMODE_TOUCH = 2 // paTouch\n};\n\nenum AVSPropDataTypeHint {\n  PROPDATATYPEHINT_UNKNOWN = -1, // dtUnknown = -1,\n  PROPDATATYPEHINT_BINARY = 0, // dtBinary = 0,\n  PROPDATATYPEHINT_UTF8 = 1 // dtUtf8 = 1\n};\n\nclass AVSValue {\npublic:\n\n  AVSValue() AVS_BakedCode( AVS_LinkCall_Void(AVSValue_CONSTRUCTOR0)() )\n  AVSValue(IClip* c) AVS_BakedCode( AVS_LinkCall_Void(AVSValue_CONSTRUCTOR1)(c) )\n  AVSValue(const PClip& c) AVS_BakedCode( AVS_LinkCall_Void(AVSValue_CONSTRUCTOR2)(c) )\n  AVSValue(bool b) AVS_BakedCode( AVS_LinkCall_Void(AVSValue_CONSTRUCTOR3)(b) )\n  AVSValue(int i) AVS_BakedCode( AVS_LinkCall_Void(AVSValue_CONSTRUCTOR4)(i) )\n  AVSValue(float f) AVS_BakedCode( AVS_LinkCall_Void(AVSValue_CONSTRUCTOR5)(f) )\n  AVSValue(double f) AVS_BakedCode( AVS_LinkCall_Void(AVSValue_CONSTRUCTOR6)(f) )\n  AVSValue(const char* s) AVS_BakedCode( AVS_LinkCall_Void(AVSValue_CONSTRUCTOR7)(s) )\n  AVSValue(const AVSValue* a, int size) AVS_BakedCode( AVS_LinkCall_Void(AVSValue_CONSTRUCTOR8)(a, size) )\n  AVSValue(const AVSValue& a, int size) AVS_BakedCode( AVS_LinkCall_Void(AVSValue_CONSTRUCTOR8)(&a, size) )\n  AVSValue(const AVSValue& v) AVS_BakedCode( AVS_LinkCall_Void(AVSValue_CONSTRUCTOR9)(v) )\n  AVSValue(const PFunction& n) AVS_BakedCode(AVS_LinkCall_Void(AVSValue_CONSTRUCTOR11)(n))\n  AVSValue(int64_t l) AVS_BakedCode(AVS_LinkCall_Void(AVSValue_CONSTRUCTOR12)(l))\n\n  ~AVSValue() AVS_BakedCode( AVS_LinkCall_Void(AVSValue_DESTRUCTOR)() )\n  AVSValue& operator=(const AVSValue& v) AVS_BakedCode( return AVS_LinkCallV(AVSValue_OPERATOR_ASSIGN)(v) )\n\n  // Transparently allow 'long' (v11) and 'int' to be treated as 'float'.\n  // v11: Transparently allow 'long', 'int' and 'float' to be treated as 'double'.\n  // There are no int<->bool conversions, though.\n\n  bool Defined() const AVS_BakedCode( return AVS_LinkCall(Defined)() )\n  bool IsClip() const AVS_BakedCode( return AVS_LinkCall(IsClip)() )\n  bool IsBool() const AVS_BakedCode( return AVS_LinkCall(IsBool)() )\n  bool IsInt() const AVS_BakedCode( return AVS_LinkCall(IsInt)() )\n  bool IsLongStrict() const AVS_BakedCode(return AVS_LinkCall(IsLongStrict)()) // v11\n  bool IsFloat() const AVS_BakedCode( return AVS_LinkCall(IsFloat)() )\n  bool IsFloatfStrict() const AVS_BakedCode( return AVS_LinkCall(IsFloatfStrict)() ) // v11\n  bool IsString() const AVS_BakedCode( return AVS_LinkCall(IsString)() )\n  bool IsArray() const AVS_BakedCode( return AVS_LinkCall(IsArray)() )\n  bool IsFunction() const AVS_BakedCode( return AVS_LinkCall(IsFunction)() )\n\n  PClip AsClip() const AVS_BakedCode( return AVS_LinkCall(AsClip)() )\n  bool AsBool() const AVS_BakedCode( return AVS_LinkCall(AsBool1)() )\n  int AsInt() const AVS_BakedCode( return AVS_LinkCall(AsInt1)() )\n  int64_t AsLong() const AVS_BakedCode(return AVS_LinkCall(AsLong1)()) // v11\n  const char* AsString() const AVS_BakedCode( return AVS_LinkCall(AsString1)() )\n  double AsFloat() const AVS_BakedCode( return AVS_LinkCall(AsFloat1)() )\n  float AsFloatf() const AVS_BakedCode( return float( AVS_LinkCall(AsFloat1)() ) )\n\n  bool AsBool(bool def) const AVS_BakedCode( return AVS_LinkCall(AsBool2)(def) )\n  int AsInt(int def) const AVS_BakedCode( return AVS_LinkCall(AsInt2)(def) )\n  int64_t AsLong(int64_t def) const AVS_BakedCode( return AVS_LinkCall(AsLong2)(def) ) // v11\n  double AsDblDef(double def) const AVS_BakedCode( return AVS_LinkCall(AsDblDef)(def) )\n  double AsFloat(float def) const AVS_BakedCode( return AVS_LinkCall(AsFloat2)(def) )\n  float AsFloatf(float def) const AVS_BakedCode( return float( AVS_LinkCall(AsFloat2)(def) ) )\n  const char* AsString(const char* def) const AVS_BakedCode( return AVS_LinkCall(AsString2)(def) )\n  PFunction AsFunction() const; // internal use only\n\n  int ArraySize() const AVS_BakedCode( return AVS_LinkCall(ArraySize)() )\n\n  const AVSValue& operator[](int index) const AVS_BakedCode( return AVS_LinkCallV(AVSValue_OPERATOR_INDEX)(index) )\n\nprivate:\n\n  short type;  // 'a'rray, 'c'lip, 'b'ool, 'i'nt, 'f'loat, 's'tring, 'v'oid, fu'n'ction, 'l'ong, 'd'ouble\n  short array_size;\n  union {\n    IClip* clip;\n    bool boolean;\n    int integer;\n    float floating_pt;\n    const char* string;\n    const AVSValue* array;\n    IFunction* function;\n    #if UINTPTR_MAX >= 0xffffffffffffffff\n    int64_t longlong; // 8 bytes\n    double double_pt; // 8 bytes\n    #else\n    // 32 bit support trick, pointers dont't break struct size on 32 bit\n    int64_t* longlong_ptr;\n    double* double_pt_ptr;\n    #endif\n  };\n\n  void Assign(const AVSValue* src, bool init);\n\npublic:\n  AvsValueType GetType() const AVS_BakedCode( return AVS_LinkCallOptDefault(AVSValue_GetType, VALUE_TYPE_UNDEFINED) )\n\n#ifdef BUILDING_AVSCORE\npublic:\n  void            CONSTRUCTOR0();  /* Damn compiler won't allow taking the address of reserved constructs, make a dummy interlude */\n  void            CONSTRUCTOR1(IClip* c);\n  void            CONSTRUCTOR2(const PClip& c);\n  void            CONSTRUCTOR3(bool b);\n  void            CONSTRUCTOR4(int i);\n  void            CONSTRUCTOR5(float f);\n  void            CONSTRUCTOR6(double f);\n  void            CONSTRUCTOR7(const char* s);\n  void            CONSTRUCTOR8(const AVSValue* a, int size);\n  void            CONSTRUCTOR9(const AVSValue& v);\n  void            CONSTRUCTOR11(const PFunction& n);\n  void            CONSTRUCTOR12(int64_t l);\n  void            DESTRUCTOR();\n  AVSValue&       OPERATOR_ASSIGN(const AVSValue& v);\n  const AVSValue& OPERATOR_INDEX(int index) const;\n\n  bool            AsBool1() const;\n  int             AsInt1() const;\n  const char*     AsString1() const;\n  double          AsFloat1() const; // AsDouble1\n  int64_t         AsLong1() const; // v11\n\n  bool            AsBool2(bool def) const;\n  int             AsInt2(int def) const;\n  double          AsFloat2(float def) const;\n  const char*     AsString2(const char* def) const;\n  int64_t         AsLong2(int64_t def) const; // v11\n\n  void            MarkArrayAsNonDeepCopy(); // for Avs25 compatibility interface, no deep-copy and deep-free\n  void            CONSTRUCTOR10(const AVSValue& v, bool no_deep_arrays);\n  AVSValue(const AVSValue& v, bool no_deep_arrays);\n  void            Assign2(const AVSValue* src, bool init, bool no_deep_arrays);\n\n#endif\n}; // end class AVSValue\n\n#define AVS_UNUSED(x) (void)(x)\n\n// instantiable null filter\nclass GenericVideoFilter : public IClip {\nprotected:\n  PClip child;\n  VideoInfo vi;\npublic:\n  GenericVideoFilter(PClip _child) : child(_child) { vi = child->GetVideoInfo(); }\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) { return child->GetFrame(n, env); }\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) { child->GetAudio(buf, start, count, env); }\n  const VideoInfo& __stdcall GetVideoInfo() { return vi; }\n  bool __stdcall GetParity(int n) { return child->GetParity(n); }\n  int __stdcall SetCacheHints(int cachehints, int frame_range) { AVS_UNUSED(cachehints); AVS_UNUSED(frame_range); return 0; }  // We do not pass cache requests upwards, only to the next filter.\n};\n\n\nclass PFunction\n{\npublic:\n  PFunction() AVS_BakedCode(AVS_LinkCall_Void(PFunction_CONSTRUCTOR0)())\n  PFunction(IFunction* p) AVS_BakedCode(AVS_LinkCall_Void(PFunction_CONSTRUCTOR1)(p))\n  PFunction(const PFunction& p) AVS_BakedCode(AVS_LinkCall_Void(PFunction_CONSTRUCTOR2)(p))\n  PFunction& operator=(IFunction* p) AVS_BakedCode(return AVS_LinkCallV(PFunction_OPERATOR_ASSIGN0)(p))\n  PFunction& operator=(const PFunction& p) AVS_BakedCode(return AVS_LinkCallV(PFunction_OPERATOR_ASSIGN1)(p))\n  ~PFunction() AVS_BakedCode(AVS_LinkCall_Void(PFunction_DESTRUCTOR)())\n\n  int operator!() const { return !e; }\n  operator void*() const { return e; }\n  IFunction* operator->() const { return e; }\n\nprivate:\n  IFunction * e;\n\n  friend class AVSValue;\n  IFunction * GetPointerWithAddRef() const;\n  void Init(IFunction* p);\n  void Set(IFunction* p);\n\n#ifdef BUILDING_AVSCORE\npublic:\n  void CONSTRUCTOR0();  /* Damn compiler won't allow taking the address of reserved constructs, make a dummy interlude */\n  void CONSTRUCTOR1(IFunction* p);\n  void CONSTRUCTOR2(const PFunction& p);\n  PFunction& OPERATOR_ASSIGN0(IFunction* p);\n  PFunction& OPERATOR_ASSIGN1(const PFunction& p);\n  void DESTRUCTOR();\n#endif\n};\n\n\n#undef CALL_MEMBER_FN\n#undef AVS_LinkCallOptDefault\n#undef AVS_LinkCallOpt\n#undef AVS_LinkCallV\n#undef AVS_LinkCall\n#undef AVS_BakedCode\n\n\n#include \"avs/cpuid.h\"\n\n// IScriptEnvironment GetEnvProperty\nenum AvsEnvProperty {\n  AEP_PHYSICAL_CPUS = 1,\n  AEP_LOGICAL_CPUS = 2,\n  AEP_THREADPOOL_THREADS = 3,\n  AEP_FILTERCHAIN_THREADS = 4,\n  AEP_THREAD_ID = 5,\n  AEP_VERSION = 6,\n  AEP_HOST_SYSTEM_ENDIANNESS = 7,\n  AEP_INTERFACE_VERSION = 8,\n  AEP_INTERFACE_BUGFIX = 9,\n  AEP_CACHESIZE_L2 = 10,\n\n  // Neo additionals\n  AEP_NUM_DEVICES = 901,\n  AEP_FRAME_ALIGN = 902,\n  AEP_PLANE_ALIGN = 903,\n\n  AEP_SUPPRESS_THREAD = 921,\n  AEP_GETFRAME_RECURSIVE = 922,\n};\n\n// IScriptEnvironment::Allocate()\nenum AvsAllocType {\n  AVS_NORMAL_ALLOC = 1,\n  AVS_POOLED_ALLOC = 2\n};\n\n\n// Important note (Windows, MSVC): \n// When extending IScriptEnvironment, do not declare existing names again\n// with different parameters. Methods with the same name will be grouped \n// together in the vtable. This results in shifting all vtable method pointers\n// after such grouping and breaks all plugins who expect the old order.\n// E.g. ApplyMessage will be called instead of GetAVSLinkage.\n// As long as the declaration is compatible with COM interop, the order of \n// declaration is sequential. But if not, overloads in the same class are grouped\n// together in the vtable in the reverse order of declaration.\nclass IScriptEnvironment {\npublic:\n  virtual ~IScriptEnvironment() {}\n\n  virtual /*static*/ int __stdcall GetCPUFlags() = 0;\n\n  virtual char* __stdcall SaveString(const char* s, int length = -1) = 0;\n  virtual char* Sprintf(const char* fmt, ...) = 0;\n  // note: val is really a va_list; I hope everyone typedefs va_list to a pointer\n  // 20200305: (void *) changed back to va_list\n  virtual char* __stdcall VSprintf(const char* fmt, va_list val) = 0;\n\n#ifdef AVS_WINDOWS\n  __declspec(noreturn) virtual void ThrowError(const char* fmt, ...) = 0;\n#else\n  virtual void ThrowError(const char* fmt, ...) = 0;\n#endif\n\n  class NotFound /*exception*/ {};  // thrown by Invoke and GetVar\n\n  typedef AVSValue (__cdecl *ApplyFunc)(AVSValue args, void* user_data, IScriptEnvironment* env);\n\n  virtual void __stdcall AddFunction(const char* name, const char* params, ApplyFunc apply, void* user_data) = 0;\n  virtual bool __stdcall FunctionExists(const char* name) = 0;\n  virtual AVSValue __stdcall Invoke(const char* name, const AVSValue args, const char* const* arg_names = 0) = 0;\n\n  virtual AVSValue __stdcall GetVar(const char* name) = 0;\n  virtual bool __stdcall SetVar(const char* name, const AVSValue& val) = 0;\n  virtual bool __stdcall SetGlobalVar(const char* name, const AVSValue& val) = 0;\n\n  virtual void __stdcall PushContext(int level = 0) = 0;\n  virtual void __stdcall PopContext() = 0;\n\n  // note v8: use NewVideoFrameP is possible\n  virtual PVideoFrame __stdcall NewVideoFrame(const VideoInfo& vi, int align = FRAME_ALIGN) = 0;\n\n  virtual bool __stdcall MakeWritable(PVideoFrame* pvf) = 0;\n\n  virtual void __stdcall BitBlt(BYTE* dstp, int dst_pitch, const BYTE* srcp, int src_pitch, int row_size, int height) = 0;\n\n  typedef void (__cdecl *ShutdownFunc)(void* user_data, IScriptEnvironment* env);\n  virtual void __stdcall AtExit(ShutdownFunc function, void* user_data) = 0;\n\n  virtual void __stdcall CheckVersion(int version = AVISYNTH_INTERFACE_VERSION) = 0;\n\n  virtual PVideoFrame __stdcall Subframe(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height) = 0;\n\n  virtual int __stdcall SetMemoryMax(int mem) = 0;\n\n  virtual int __stdcall SetWorkingDir(const char * newdir) = 0;\n\n  virtual void* __stdcall ManageCache(int key, void* data) = 0;\n\n  enum PlanarChromaAlignmentMode {\n    PlanarChromaAlignmentOff,\n    PlanarChromaAlignmentOn,\n    PlanarChromaAlignmentTest\n  };\n\n  virtual bool __stdcall PlanarChromaAlignment(PlanarChromaAlignmentMode key) = 0;\n\n  virtual PVideoFrame __stdcall SubframePlanar(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size,\n                                               int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV) = 0;\n\n  // **** AVISYNTH_INTERFACE_VERSION 5 **** defined since classic Avisynth 2.6 beta\n  virtual void __stdcall DeleteScriptEnvironment() = 0;\n\n  virtual void __stdcall ApplyMessage(PVideoFrame* frame, const VideoInfo& vi, const char* message, int size,\n                                     int textcolor, int halocolor, int bgcolor) = 0;\n\n  virtual const AVS_Linkage* __stdcall GetAVSLinkage() = 0;\n\n  // **** AVISYNTH_INTERFACE_VERSION 6 **** defined since classic Avisynth 2.6\n  // noThrow version of GetVar\n  virtual AVSValue __stdcall GetVarDef(const char* name, const AVSValue& def = AVSValue()) = 0;\n\n  // **** AVISYNTH_INTERFACE_VERSION 8 **** AviSynth+ 3.6.0-\n  virtual PVideoFrame __stdcall SubframePlanarA(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size,\n    int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV, int rel_offsetA) = 0;\n\n  virtual void __stdcall copyFrameProps(const PVideoFrame& src, PVideoFrame& dst) = 0;\n  virtual const AVSMap* __stdcall getFramePropsRO(const PVideoFrame& frame) = 0;\n  virtual AVSMap* __stdcall getFramePropsRW(PVideoFrame& frame) = 0;\n\n  virtual int __stdcall propNumKeys(const AVSMap* map) = 0;\n\n  virtual const char* __stdcall propGetKey(const AVSMap* map, int index) = 0;\n  virtual int __stdcall propNumElements(const AVSMap* map, const char* key) = 0;\n  virtual char __stdcall propGetType(const AVSMap* map, const char* key) = 0;\n\n  virtual int64_t __stdcall propGetInt(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual double __stdcall propGetFloat(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual const char* __stdcall propGetData(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual int __stdcall propGetDataSize(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual PClip __stdcall propGetClip(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual const PVideoFrame __stdcall propGetFrame(const AVSMap* map, const char* key, int index, int* error) = 0;\n\n  virtual int __stdcall propDeleteKey(AVSMap* map, const char* key) = 0;\n\n  virtual int __stdcall propSetInt(AVSMap* map, const char* key, int64_t i, int append) = 0;\n  virtual int __stdcall propSetFloat(AVSMap* map, const char* key, double d, int append) = 0;\n  virtual int __stdcall propSetData(AVSMap* map, const char* key, const char* d, int length, int append) = 0;\n  virtual int __stdcall propSetClip(AVSMap* map, const char* key, PClip& clip, int append) = 0;\n  virtual int __stdcall propSetFrame(AVSMap* map, const char* key, const PVideoFrame& frame, int append) = 0;\n\n  virtual const int64_t* __stdcall propGetIntArray(const AVSMap* map, const char* key, int* error) = 0;\n  virtual const double* __stdcall propGetFloatArray(const AVSMap* map, const char* key, int* error) = 0;\n  virtual int __stdcall propSetIntArray(AVSMap* map, const char* key, const int64_t* i, int size) = 0;\n  virtual int __stdcall propSetFloatArray(AVSMap* map, const char* key, const double* d, int size) = 0;\n\n  virtual AVSMap* __stdcall createMap() = 0;\n  virtual void __stdcall freeMap(AVSMap* map) = 0;\n  virtual void __stdcall clearMap(AVSMap* map) = 0;\n\n  // NewVideoFrame with frame property source.\n  virtual PVideoFrame __stdcall NewVideoFrameP(const VideoInfo& vi, const PVideoFrame* prop_src, int align = FRAME_ALIGN) = 0;\n\n  // Generic query to ask for various system properties\n  virtual size_t  __stdcall GetEnvProperty(AvsEnvProperty prop) = 0;\n\n  // Support functions\n  virtual void* __stdcall Allocate(size_t nBytes, size_t alignment, AvsAllocType type) = 0;\n  virtual void __stdcall Free(void* ptr) = 0;\n\n  // these GetVar versions (renamed differently) were moved from IScriptEnvironment2\n\n  // Returns TRUE and the requested variable. If the method fails, returns FALSE and does not touch 'val'.\n  virtual bool  __stdcall GetVarTry(const char* name, AVSValue* val) const = 0; // ex virtual bool  __stdcall GetVar(const char* name, AVSValue* val) const = 0;\n  // Return the value of the requested variable.\n  // If the variable was not found or had the wrong type,\n  // return the supplied default value.\n  virtual bool __stdcall GetVarBool(const char* name, bool def) const = 0;\n  virtual int  __stdcall GetVarInt(const char* name, int def) const = 0;\n  virtual double  __stdcall GetVarDouble(const char* name, double def) const = 0;\n  virtual const char* __stdcall GetVarString(const char* name, const char* def) const = 0;\n  // brand new in v8 - v11: real int64 support\n  virtual int64_t __stdcall GetVarLong(const char* name, int64_t def) const = 0;\n\n  // 'Invoke' functions moved here from internal ScriptEnvironments are renamed in order to keep vtable order\n  // Invoke functions with 'Try' will return false instead of throwing NotFound().\n  // ex-IScriptEnvironment2\n  virtual bool __stdcall InvokeTry(AVSValue* result, const char* name, const AVSValue& args, const char* const* arg_names = 0) = 0;\n  // Since V8\n  virtual AVSValue __stdcall Invoke2(const AVSValue& implicit_last, const char* name, const AVSValue args, const char* const* arg_names = 0) = 0;\n  // Ex-INeo\n  virtual bool __stdcall Invoke2Try(AVSValue* result, const AVSValue& implicit_last, const char* name, const AVSValue args, const char* const* arg_names = 0) = 0;\n  virtual AVSValue __stdcall Invoke3(const AVSValue& implicit_last, const PFunction& func, const AVSValue args, const char* const* arg_names = 0) = 0;\n  virtual bool __stdcall Invoke3Try(AVSValue* result, const AVSValue& implicit_last, const PFunction& func, const AVSValue args, const char* const* arg_names = 0) = 0;\n\n  // V9\n  virtual bool __stdcall MakePropertyWritable(PVideoFrame* pvf) = 0;\n\n  // V11\n  virtual int __stdcall propGetIntSaturated(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual float __stdcall propGetFloatSaturated(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual int __stdcall propGetDataTypeHint(const AVSMap* map, const char* key, int index, int* error) = 0; // returns AVSPropDataTypeHint\n  virtual int __stdcall propSetDataH(AVSMap* map, const char* key, const char* d, int length, int type, int append) = 0;\n\n  // V12\n  // New Global Lock API for cross-plugin synchronization.\n  // Plugins must ensure these calls are balanced (acquire followed by release),\n  virtual bool __stdcall AcquireGlobalLock(const char* name) = 0;\n  virtual void __stdcall ReleaseGlobalLock(const char* name) = 0;\n  virtual void __stdcall ApplyMessageEx(PVideoFrame* frame, const VideoInfo& vi, const char* message, int size,\n    int textcolor, int halocolor, int bgcolor, bool utf8) = 0;\n  virtual int64_t __stdcall GetCPUFlagsEx() = 0;\n}; // end class IScriptEnvironment. Order is important. Avoid overloads with the same name.\n\n\n\n// Multithreading behaviour. IClip SetCacheHints can return them on CACHE_GET_MTMODE query\nenum MtMode {\n  MT_INVALID = 0,\n  MT_NICE_FILTER = 1,\n  MT_MULTI_INSTANCE = 2,\n  MT_SERIALIZED = 3,\n  MT_SPECIAL_MT = 4,\n  MT_MODE_COUNT = 5\n};\n\nclass IJobCompletion\n{\npublic:\n\n  virtual ~IJobCompletion() {}\n  virtual void __stdcall Wait() = 0;\n  virtual AVSValue __stdcall Get(size_t i) = 0;\n  virtual size_t __stdcall Size() const = 0;\n  virtual size_t __stdcall Capacity() const = 0;\n  virtual void __stdcall Reset() = 0;\n  virtual void __stdcall Destroy() = 0;\n};\n\nclass IScriptEnvironment2;\nclass IScriptEnvironment_Avs25;\nclass IScriptEnvironment_AvsPreV11C;\nclass Prefetcher;\ntypedef AVSValue (*ThreadWorkerFuncPtr)(IScriptEnvironment2* env, void* data);\n\n\n/* -----------------------------------------------------------------------------\n   Note to plugin authors: The interface in IScriptEnvironment2 is\n      preliminary / under construction / only for testing / non-final etc.!\n      As long as you see this note here, IScriptEnvironment2 might still change,\n      in which case your plugin WILL break. This also means that you are welcome\n      to test it and give your feedback about any ideas, improvements, or issues\n      you might have.\n   ----------------------------------------------------------------------------- */\nclass IScriptEnvironment2 : public IScriptEnvironment{\npublic:\n  virtual ~IScriptEnvironment2() {}\n\n  // Plugin functions\n  virtual bool __stdcall LoadPlugin(const char* filePath, bool throwOnError, AVSValue *result) = 0;\n  virtual void __stdcall AddAutoloadDir(const char* dirPath, bool toFront) = 0;\n  virtual void __stdcall ClearAutoloadDirs() = 0;\n  virtual void __stdcall AutoloadPlugins() = 0;\n  virtual void __stdcall AddFunction(const char* name, const char* params, ApplyFunc apply, void* user_data, const char *exportVar) = 0;\n  virtual bool __stdcall InternalFunctionExists(const char* name) = 0;\n\n  // Threading\n  virtual void __stdcall SetFilterMTMode(const char* filter, MtMode mode, bool force) = 0; // If filter is \"DEFAULT_MT_MODE\", sets the default MT mode\n  virtual IJobCompletion* __stdcall NewCompletion(size_t capacity) = 0;\n  virtual void __stdcall ParallelJob(ThreadWorkerFuncPtr jobFunc, void* jobData, IJobCompletion* completion) = 0;\n\n  // These lines are needed so that we can overload the older functions from IScriptEnvironment.\n  using IScriptEnvironment::Invoke;\n  using IScriptEnvironment::AddFunction;\n\n}; // end class IScriptEnvironment2\n\n\n// To allow Avisynth+ add functions to IScriptEnvironment2,\n// Neo defines another new interface, INeoEnv.\n// INeoEnv and the legacy interfaces (IScriptEnvironment/IScriptEnvironment2)\n// share the same ScriptEnvironment instance. The function with the same signature\n// is exactly identical and there is no limitation to switch interfaces.\n// You can use any interface you like.\n// Note to plugin authors : The interface is not stable, see comments in IScriptEnvironment2\n\n// The order of functions are arbitrary, no need to keep the VMT table compatibility and match \n// with the strict IScriptEnvironment order.\nclass INeoEnv {\npublic:\n  virtual ~INeoEnv() {}\n\n  typedef IScriptEnvironment::NotFound NotFound;\n  typedef IScriptEnvironment::ApplyFunc ApplyFunc;\n  typedef IScriptEnvironment::ShutdownFunc ShutdownFunc;\n\n  virtual void __stdcall DeleteScriptEnvironment() = 0;\n\n  virtual const AVS_Linkage* __stdcall GetAVSLinkage() = 0;\n\n  // Get legacy interface (Avisynth+)\n  virtual IScriptEnvironment2* __stdcall GetEnv2() = 0;\n  // Get compatibility interface for AVS CPP 2.5 plugins\n  virtual IScriptEnvironment_Avs25* __stdcall GetEnv25() = 0;\n  // Get compatibility interface for older AVS C plugins\n  virtual IScriptEnvironment_AvsPreV11C* __stdcall GetEnvPreV11C() = 0;\n\n  // Generic system to ask for various properties\n  virtual size_t  __stdcall GetEnvProperty(AvsEnvProperty prop) = 0;\n  virtual int __stdcall GetCPUFlags() = 0;\n\n  // Plugin functions\n  virtual bool __stdcall LoadPlugin(const char* filePath, bool throwOnError, AVSValue *result) = 0;\n  virtual void __stdcall AddAutoloadDir(const char* dirPath, bool toFront) = 0;\n  virtual void __stdcall ClearAutoloadDirs() = 0;\n  virtual char* __stdcall ListAutoloadDirs() = 0;\n  virtual void __stdcall AutoloadPlugins() = 0;\n\n  virtual void __stdcall AddFunction(\n    const char* name, const char* params, ApplyFunc apply, void* user_data) = 0;\n  virtual void __stdcall AddFunction(\n    const char* name, const char* params, ApplyFunc apply, void* user_data, const char *exportVar) = 0;\n  virtual bool __stdcall FunctionExists(const char* name) = 0;\n  virtual bool __stdcall InternalFunctionExists(const char* name) = 0;\n\n  // Invoke function. Throws NotFound exception when the specified function does not exist.\n  virtual AVSValue __stdcall Invoke(\n    const char* name, const AVSValue args, const char* const* arg_names = 0) = 0;\n  virtual AVSValue __stdcall Invoke2(\n    const AVSValue& implicit_last, const char* name, const AVSValue args, const char* const* arg_names = 0) = 0;\n  virtual AVSValue __stdcall Invoke3(\n    const AVSValue& implicit_last,\n    const PFunction& func, const AVSValue args, const char* const* arg_names = 0) = 0;\n\n  // These versions of Invoke will return false instead of throwing NotFound().\n  virtual bool __stdcall InvokeTry(\n    AVSValue* result, const char* name, const AVSValue& args, const char* const* arg_names = 0) = 0;\n  virtual bool __stdcall Invoke2Try(\n    AVSValue* result, const AVSValue& implicit_last,\n    const char* name, const AVSValue args, const char* const* arg_names = 0) = 0;\n  virtual bool __stdcall Invoke3Try(\n    AVSValue* result, const AVSValue& implicit_last,\n    const PFunction& func, const AVSValue args, const char* const* arg_names = 0) = 0;\n\n  // V9\n  virtual bool __stdcall MakePropertyWritable(PVideoFrame* pvf) = 0;\n\n  // Throws exception when the requested variable is not found.\n  virtual AVSValue __stdcall GetVar(const char* name) = 0;\n\n  // noThrow version of GetVar\n  virtual AVSValue __stdcall GetVarDef(const char* name, const AVSValue& def = AVSValue()) = 0;\n\n  // Returns TRUE and the requested variable. If the method fails, returns FALSE and does not touch 'val'.\n  virtual bool  __stdcall GetVarTry(const char* name, AVSValue* val) const = 0;\n\n  // Return the value of the requested variable.\n  // If the variable was not found or had the wrong type,\n  // return the supplied default value.\n  virtual bool __stdcall GetVarBool(const char* name, bool def) const = 0;\n  virtual int  __stdcall GetVarInt(const char* name, int def) const = 0;\n  virtual double  __stdcall GetVarDouble(const char* name, double def) const = 0;\n  virtual const char* __stdcall GetVarString(const char* name, const char* def) const = 0;\n  virtual int64_t __stdcall GetVarLong(const char* name, int64_t def) const = 0;\n\n  virtual bool __stdcall SetVar(const char* name, const AVSValue& val) = 0;\n  virtual bool __stdcall SetGlobalVar(const char* name, const AVSValue& val) = 0;\n\n  // Switch local variables\n  virtual void __stdcall PushContext(int level = 0) = 0;\n  virtual void __stdcall PopContext() = 0;\n\n  // Global variable frame support\n  virtual void __stdcall PushContextGlobal() = 0;\n  virtual void __stdcall PopContextGlobal() = 0;\n\n  // Allocate new video frame\n  // in PNeoEnv: align parameter is no longer supported\n  virtual PVideoFrame __stdcall NewVideoFrame(const VideoInfo& vi) = 0; // current device is used\n  virtual PVideoFrame __stdcall NewVideoFrame(const VideoInfo& vi, const PDevice& device) = 0;\n  // as above but with property sources\n  virtual PVideoFrame __stdcall NewVideoFrame(const VideoInfo& vi, const PVideoFrame *prop_src) = 0; // current device is used + frame property source\n  virtual PVideoFrame __stdcall NewVideoFrame(const VideoInfo& vi, const PDevice& device, const PVideoFrame* prop_src) = 0; // current device is used + frame property source\n\n  // Frame related operations\n  virtual bool __stdcall MakeWritable(PVideoFrame* pvf) = 0;\n  virtual void __stdcall BitBlt(BYTE* dstp, int dst_pitch, const BYTE* srcp, int src_pitch, int row_size, int height) = 0;\n\n  virtual PVideoFrame __stdcall Subframe(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height) = 0;\n  virtual PVideoFrame __stdcall SubframePlanar(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size,\n    int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV) = 0;\n  virtual PVideoFrame __stdcall SubframePlanarA(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size,\n    int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV, int rel_offsetA) = 0;\n\n  // frame properties support\n  virtual void __stdcall copyFrameProps(const PVideoFrame& src, PVideoFrame& dst) = 0;\n  virtual const AVSMap* __stdcall getFramePropsRO(const PVideoFrame& frame) = 0;\n  virtual AVSMap* __stdcall getFramePropsRW(PVideoFrame& frame) = 0;\n\n  virtual int __stdcall propNumKeys(const AVSMap* map) = 0;\n  virtual const char* __stdcall propGetKey(const AVSMap* map, int index) = 0;\n  virtual int __stdcall propNumElements(const AVSMap* map, const char* key) = 0;\n  virtual char __stdcall propGetType(const AVSMap* map, const char* key) = 0;\n\n  virtual int64_t __stdcall propGetInt(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual double __stdcall propGetFloat(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual const char* __stdcall propGetData(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual int __stdcall propGetDataSize(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual PClip __stdcall propGetClip(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual const PVideoFrame __stdcall propGetFrame(const AVSMap* map, const char* key, int index, int* error) = 0;\n\n  virtual int __stdcall propDeleteKey(AVSMap* map, const char* key) = 0;\n\n  virtual int __stdcall propSetInt(AVSMap* map, const char* key, int64_t i, int append) = 0;\n  virtual int __stdcall propSetFloat(AVSMap* map, const char* key, double d, int append) = 0;\n  virtual int __stdcall propSetData(AVSMap* map, const char* key, const char* d, int length, int append) = 0;\n  virtual int __stdcall propSetClip(AVSMap* map, const char* key, PClip& clip, int append) = 0;\n  virtual int __stdcall propSetFrame(AVSMap* map, const char* key, const PVideoFrame& frame, int append) = 0;\n\n  virtual const int64_t *__stdcall propGetIntArray(const AVSMap* map, const char* key, int* error) = 0;\n  virtual const double *__stdcall propGetFloatArray(const AVSMap* map, const char* key, int* error) = 0;\n  virtual int __stdcall propSetIntArray(AVSMap* map, const char* key, const int64_t* i, int size) = 0;\n  virtual int __stdcall propSetFloatArray(AVSMap* map, const char* key, const double* d, int size) = 0;\n\n  virtual int __stdcall propGetIntSaturated(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual float __stdcall propGetFloatSaturated(const AVSMap* map, const char* key, int index, int* error) = 0;\n  virtual int __stdcall propGetDataTypeHint(const AVSMap* map, const char* key, int index, int* error) = 0; /* returns AVSPropDataTypeHint */\n  virtual int __stdcall propSetDataH(AVSMap* map, const char* key, const char* d, int length, int type, int append) = 0;\n\n  virtual AVSMap* __stdcall createMap() = 0;\n  virtual void __stdcall freeMap(AVSMap* map) = 0;\n  virtual void __stdcall clearMap(AVSMap* map) = 0;\n\n  // Support functions\n  virtual void* __stdcall Allocate(size_t nBytes, size_t alignment, AvsAllocType type) = 0;\n  virtual void __stdcall Free(void* ptr) = 0;\n\n  virtual bool __stdcall AcquireGlobalLock(const char* name) = 0;\n  virtual void __stdcall ReleaseGlobalLock(const char* name) = 0;\n\n  virtual char* __stdcall SaveString(const char* s, int length = -1) = 0;\n  virtual char* __stdcall SaveString(const char* s, int length, bool escape) = 0;\n  virtual char* Sprintf(const char* fmt, ...) = 0;\n  virtual char* __stdcall VSprintf(const char* fmt, va_list val) = 0;\n\n  __declspec(noreturn) virtual void ThrowError(const char* fmt, ...) = 0;\n\n  virtual void __stdcall ApplyMessage(PVideoFrame* frame, const VideoInfo& vi, const char* message, int size,\n    int textcolor, int halocolor, int bgcolor) = 0;\n  // V12\n  virtual void __stdcall ApplyMessageEx(PVideoFrame* frame, const VideoInfo& vi, const char* message, int size,\n    int textcolor, int halocolor, int bgcolor, bool utf8) = 0;\n\n  // Setting\n  virtual int __stdcall SetMemoryMax(int mem) = 0;\n  virtual int __stdcall SetMemoryMax(AvsDeviceType type, int index, int mem) = 0;\n\n  virtual bool __stdcall PlanarChromaAlignment(IScriptEnvironment::PlanarChromaAlignmentMode key) = 0;\n  virtual int __stdcall SetWorkingDir(const char * newdir) = 0;\n  virtual void* __stdcall ManageCache(int key, void* data) = 0;\n\n  virtual void __stdcall AtExit(ShutdownFunc function, void* user_data) = 0;\n  virtual void __stdcall CheckVersion(int version = AVISYNTH_INTERFACE_VERSION) = 0;\n\n  // Threading\n  virtual void __stdcall SetFilterMTMode(const char* filter, MtMode mode, bool force) = 0;\n  virtual IJobCompletion* __stdcall NewCompletion(size_t capacity) = 0;\n  virtual void __stdcall ParallelJob(ThreadWorkerFuncPtr jobFunc, void* jobData, IJobCompletion* completion) = 0;\n\n  // CUDA Support\n  virtual PDevice __stdcall GetDevice(AvsDeviceType dev_type, int dev_index) const = 0;\n  virtual PDevice __stdcall GetDevice() const = 0; // get current device\n  virtual AvsDeviceType __stdcall GetDeviceType() const = 0;\n  virtual int __stdcall GetDeviceId() const  = 0;\n  virtual int __stdcall GetDeviceIndex() const  = 0;\n  virtual void* __stdcall GetDeviceStream() const = 0;\n  virtual void __stdcall DeviceAddCallback(void(*cb)(void*), void* user_data) = 0;\n\n  virtual PVideoFrame __stdcall GetFrame(PClip c, int n, const PDevice& device) = 0;\n\n};\n\n// support interface conversion\nstruct PNeoEnv {\n  INeoEnv* p;\n  PNeoEnv() : p() { }\n  PNeoEnv(IScriptEnvironment* env)\n#if defined(BUILDING_AVSCORE) || defined(AVS_STATIC_LIB)\n    ;\n#else\n  : p(!AVS_linkage || offsetof(AVS_Linkage, GetNeoEnv) >= (size_t)AVS_linkage->Size ? 0 : AVS_linkage->GetNeoEnv(env)) { }\n#endif\n\n  int operator!() const { return !p; }\n  operator void*() const { return p; }\n  INeoEnv* operator->() const { return p; }\n#ifdef BUILDING_AVSCORE\n  inline operator IScriptEnvironment2*();\n  inline operator IScriptEnvironment_Avs25* ();\n  inline operator IScriptEnvironment_AvsPreV11C* ();\n#else\n  operator IScriptEnvironment2*() { return p->GetEnv2(); }\n  operator IScriptEnvironment_Avs25* () { return p->GetEnv25(); }\n  operator IScriptEnvironment_AvsPreV11C* () { return p->GetEnvPreV11C(); }\n#endif\n};\n\n\n// avisynth.dll exports this; it's a way to use it as a library, without\n// writing an AVS script or without going through AVIFile.\nAVSC_API(IScriptEnvironment*, CreateScriptEnvironment)(int version = AVISYNTH_INTERFACE_VERSION);\n\n\n// These are some global variables you can set in your script to change AviSynth's behavior.\n#define VARNAME_AllowFloatAudio   \"OPT_AllowFloatAudio\"   // Allow WAVE_FORMAT_IEEE_FLOAT audio output\n#define VARNAME_VDubPlanarHack    \"OPT_VDubPlanarHack\"    // Hack YV16 and YV24 chroma plane order for old VDub's\n#define VARNAME_AVIPadScanlines   \"OPT_AVIPadScanlines\"   // Have scanlines mod4 padded in all pixel formats\n#define VARNAME_UseWaveExtensible \"OPT_UseWaveExtensible\" // Use WAVEFORMATEXTENSIBLE when describing audio to Windows\n#define VARNAME_dwChannelMask     \"OPT_dwChannelMask\"     // Integer audio channel mask. See description of WAVEFORMATEXTENSIBLE for more info.\n#define VARNAME_Enable_V210       \"OPT_Enable_V210\"       // AVS+ use V210 instead of P210 (VfW)\n#define VARNAME_Enable_Y3_10_10   \"OPT_Enable_Y3_10_10\"   // AVS+ use Y3[10][10] instead of P210 (VfW)\n#define VARNAME_Enable_Y3_10_16   \"OPT_Enable_Y3_10_16\"   // AVS+ use Y3[10][16] instead of P216 (VfW)\n#define VARNAME_Enable_b64a       \"OPT_Enable_b64a\"       // AVS+ use b64a instead of BRA[64] (VfW)\n#define VARNAME_Enable_PlanarToPackedRGB \"OPT_Enable_PlanarToPackedRGB\" // AVS+ convert Planar RGB to packed RGB (VfW)\n\n// C exports\n#include \"avs/capi.h\"\nAVSC_API(IScriptEnvironment2*, CreateScriptEnvironment2)(int version = AVISYNTH_INTERFACE_VERSION);\n\n#ifndef BUILDING_AVSCORE\n#undef AVS_UNUSED\n#endif\n\n#pragma pack(pop)\n\n#endif //__AVISYNTH_12_H__\n"
  },
  {
    "path": "avs_core/include/avisynth_c.h",
    "content": "// Avisynth C Interface Version 0.20\n// Copyright 2003 Kevin Atkinson\n\n// Copyright 2020 AviSynth+ project\n// Actual C Interface version follows the global Avisynth+ IF version numbers.\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n// MA 02110-1301 USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// As a special exception, I give you permission to link to the\n// Avisynth C interface with independent modules that communicate with\n// the Avisynth C interface solely through the interfaces defined in\n// avisynth_c.h, regardless of the license terms of these independent\n// modules, and to copy and distribute the resulting combined work\n// under terms of your choice, provided that every copy of the\n// combined work is accompanied by a complete copy of the source code\n// of the Avisynth C interface and Avisynth itself (with the version\n// used to produce the combined work), being distributed under the\n// terms of the GNU General Public License plus this exception.  An\n// independent module is a module which is not derived from or based\n// on Avisynth C Interface, such as 3rd-party filters, import and\n// export plugins, or graphical user interfaces.\n\n// NOTE: this is a partial update of the Avisynth C interface to recognize\n// new color spaces and interface elements added in Avisynth 2.60 and AviSynth+.\n// This interface is not 100% Avisynth+ CPP interface equivalent.\n\n// 170103: added new CPU constants (FMA4, AVX512xx)\n// 171102: define SIZETMOD. do not use yet, experimental. Offsets are size_t instead of int. Affects x64.\n// 171106: avs_get_row_size calls into avs_get_row_size_p, instead of direct field access\n// 171106: avs_get_height calls into avs_get_row_size_p, instead of direct field access\n// 180524: AVSC_EXPORT to dllexport in capi.h for avisynth_c_plugin_init\n// 180524: avs_is_same_colorspace VideoInfo parameters to const\n// 181230: Readability: functions regrouped to mix less AVSC_API and AVSC_INLINE, put together Avisynth+ specific stuff\n// 181230: use #ifndef AVSC_NO_DECLSPEC for AVSC_INLINE functions which are calling API functions\n// 181230: comments on avs_load_library (helper for loading API entries dynamically into a struct using AVSC_NO_DECLSPEC define)\n// 181230: define alias AVS_FRAME_ALIGN as FRAME_ALIGN\n// 181230: remove unused form of avs_get_rowsize and avs_get_height (kept earlier for reference)\n// 190104: avs_load_library: smart fallback mechanism for Avisynth+ specific functions:\n//         if they are not loadable, they will work in a classic Avisynth compatible mode\n//         Example#1: e.g. avs_is_444 will call the existing avs_is_yv24 instead\n//         Example#2: avs_bits_per_component will return 8 for all colorspaces (Classic Avisynth supports only 8 bits/pixel)\n//         Thus the Avisynth+ specific API functions are safely callable even when connected to classic Avisynth DLL\n// 2002xx  non-Windows friendly additions\n// 200305  avs_vsprintf parameter type change: (void *) to va_list\n// 200330: (remove test SIZETMOD define for clarity)\n// 200513: user must use explicite #define AVS26_FALLBACK_SIMULATION for having fallback helpers in dynamic loaded library section\n// 200513: Follow AviSynth+ V8 interface additions\n//         AVS_VideoFrame struct extended with placeholder for frame property pointer\n//         avs_subframe_planar_a\n//         avs_copy_frame_props\n//         avs_get_frame_props_ro, avs_get_frame_props_rw\n//         avs_prop_num_keys, avs_prop_get_key, avs_prop_num_elements, avs_prop_get_type, avs_prop_get_data_size\n//         avs_prop_get_int, avs_prop_get_float, avs_prop_get_data, avs_prop_get_clip, avs_prop_get_frame, avs_prop_get_int_array, avs_prop_get_float_array\n//         avs_prop_set_int, avs_prop_set_float, avs_prop_set_data, avs_prop_set_clip, avs_prop_set_frame, avs_prop_set_int_array, avs_prop_set_float_array\n//         avs_prop_delete_key, avs_clear_map\n//         avs_new_video_frame_p, avs_new_video_frame_p_a\n//         avs_get_env_property (internal system properties), AVS_AEP_xxx (AvsEnvProperty) enums\n//         avs_get_var_try, avs_get_var_bool, avs_get_var_int, avs_get_var_double, avs_get_var_string, avs_get_var_long\n//         avs_pool_allocate, avs_pool_free\n// 2021:   Follow AviSynth+ V9 interface additions\n//         avs_is_property_writable, avs_make_property_writable\n//         Add enum AVISYNTHPLUS_INTERFACE_BUGFIX_VERSION (AVISYNTH_INTERFACE_VERSION still exists)\n//         Add enum AVS_AEP_HOST_SYSTEM_ENDIANNESS to system property request types (avs_get_env_property)\n//         Add enums AVS_AEP_INTERFACE_VERSION and AVS_AEP_INTERFACE_BUGFIX for direct interface version system property request types (avs_get_env_property)\n//         Bugfix 9.1: fix avs_prop_get_data\n// 2023:   Follow AviSynth+ V10 interface additions\n//         Add enum AVS_DEFAULT_PLANE (as 0) to plane constants \n//         prop_src argument now const in avs_new_video_frame_p and avs_new_video_frame_p_a (no change in use)\n//         Add pixel_type to struct AVS_VideoFrame\n//         Add avs_video_frame_get_pixel_type and avs_video_frame_amend_pixel_type for getting and setting AVS_VideoFrame pixel_type\n//         Additional AviSynth+ V10 interface additions:\n//         Add enum AVS_SPEAKER_xxx, AVS_IT_SPEAKER_xxx\n//         Audio channel mask support API: avs_is_channel_mask_known, avs_set_channel_mask, avs_get_channel_mask\n\n// 2025    Follow AviSynth+ V11 interface additions (AVSValue new 64-bit types); \n//         Setters are all accept AVS_Value by reference, like avs_set_to_clip did so far. (unlike avs_new_xxx inline helpers, which returns AVS_Value directly)\n//         - avs_val_defined = avs_defined\n//         - avs_val_is_xxx = avs_is_xxx (bool, clip, int, long_strict, string, float_strict, float, error, array)\n//         - avs_set_to_xxx ~avs_new_value_xxx (bool, clip, int, long, string, float, double, error, array)\n//         - avs_set_to_void = AVS_void constant direct assignment\n//         - avs_get_as_xxx = avs_as_xxx   (bool, clip, int, long, string, float, error, array)\n//         - avs_get_array_size = avs_array_size\n//         - avs_get_array_elt = avs_array_elt\n//         Including:\n//         Modified INLINE typecheck and getter helpers for 64-bit data type awareness:\n//         - avs_is_int, avs_is_float\n//         - avs_as_int, avs_as_float\n//         Strict type checkers\n//         - avs_val_is_long_strict, avs_val_is_floatf_strict\n//         New INLINE getter helpers for 64-bit data (prefer using API calls):\n//         - avs_as_long\n//         New optional plugin entry point: avisynth_c_plugin_init2\n//         - A C plugin signals to AviSynth that it is V11 interface (64-bit data) ready by implementing avisynth_c_plugin_init2 as well.\n//           avisynth_c_plugin_init2 has the same signature as avisynth_c_plugin_init and can\n//           simply call forward to the old avisynth_c_plugin_init entry point. Both entry points can be implemented; \n//           AviSynth+ will first check avisynth_c_plugin_init2, then avisynth_c_plugin_init.\n//           Don't forget to add a new \n//             avisynth_c_plugin_init2@4 = _avisynth_c_plugin_init2@4\n//           line to your existing .def file on Win32.\n//         Deprecated inline helper functions, which in turn would call API.\n//         - avs_get_pitch => avs_get_pitch_p(p, AVS_DEFAULT_PLANE)\n//           avs_get_row_size => avs_get_row_size_p(p, AVS_DEFAULT_PLANE)\n//           avs_get_height => avs_get_height_p(p, AVS_DEFAULT_PLANE)\n//           avs_get_read_ptr => avs_get_read_ptr_p(p, AVS_DEFAULT_PLANE)\n//           avs_get_write_ptr => vs_get_write_ptr_p(p, AVS_DEFAULT_PLANE)\n//           avs_release_frame => avs_release_video_frame\n//           avs_copy_frame => avs_copy_video_frame\n//         - Use #define AVSC_ALLOW_DEPRECATED if they still need for you, \n//           but better fix your code: use the recommended replacements.\n//         Intentionally renamed AVS_VideoFrame internal fields, direct access was always prohibited, next API will remove the access.\n//         Add missing AVS_MT_xxxx mode constants to header like c++ header enum MtMode\n//         Add AVS_PROPDATATYPEHINT_xxx for AVSPropDataTypeHint\n//         New avs_prop_get_int_saturated and avs_prop_get_float_saturated\n//         New avs_prop_get_data_type_hint\n//         New avs_prop_set_data_h\n//         New avs_add_func_r: alternative avs_add_func which returns the result in a byref parameter\n//         New AVS_ApplyFuncR type\n// 20250415 V11.1 Fix AVS_Value 64 bit data member declaration for 64-bit non Intel (other than X86_X64) systems.\n// 20250601 V12 Global lock acquire and release: avs_acquire_global_lock, avs_release_global_lock\n// 20251127 V12 AVS_CACHE_INFORM_NUM_THREADS constant to inform the filter about the number of threads by avs_set_cache_hints\n//              Add const AVS_AEP_CACHESIZE_L2 for avs_get_env_property level 2 cache size query,\n// 20251202     Add avs_get_cpu_flags_ex returning full 64 bit flags, new AVX-512 group flags, ARM64 CPU flags.\n\n// Notes.\n// Choose either method:\n// By loading avisynth.dll/.so/.dylib dinamically, AviSynth versions with different API level can be supported.\n// - Use #define AVSC_NO_DECLSPEC for function pointer definitions only.\n// - Load the library dynamically and get the necessary API functions as needed.\n// - Earlier AviSynth versions may contain fewer API functions.\n//   By detecting the loaded AviSynth/interface version, it's the caller's responsibility \n//   to call only those API functions which have valid function pointers and are documented to work.\n//   E.g., you should only use frame property-related functions when lib.avs_get_version(clip) >= 9.\n// For linking avisynth.lib/libavisynth directly to your module:\n// - Leave AVSC_NO_DECLSPEC undefined.\n// - Link the provided .lib to your module.\n// - Your plugin/software won't work with older AviSynth instances if it uses newer API functions.\n//   The plugin DLL won't load due to dependency issues. (On Windows: platform returned code 127)\n\n\n#ifndef __AVISYNTH_C__\n#define __AVISYNTH_C__\n\n#include \"avs/config.h\"\n#include \"avs/capi.h\"\n#include \"avs/types.h\"\n\n#define AVS_FRAME_ALIGN FRAME_ALIGN\n/////////////////////////////////////////////////////////////////////\n//\n// Constants\n//\n\n#ifndef __AVISYNTH_12_H__\nenum {\n  AVISYNTH_INTERFACE_CLASSIC_VERSION = 6,\n  AVISYNTH_INTERFACE_VERSION = 12,\n  AVISYNTHPLUS_INTERFACE_BUGFIX_VERSION = 0 // reset to zero whenever the normal interface version bumps\n};\n#endif\n\nenum {\n  AVS_SAMPLE_INT8  = 1 << 0,\n  AVS_SAMPLE_INT16 = 1 << 1,\n  AVS_SAMPLE_INT24 = 1 << 2,\n  AVS_SAMPLE_INT32 = 1 << 3,\n  AVS_SAMPLE_FLOAT = 1 << 4\n};\n\nenum {\n  AVS_DEFAULT_PLANE = 0,\n  AVS_PLANAR_Y = 1 << 0,\n  AVS_PLANAR_U = 1 << 1,\n  AVS_PLANAR_V = 1 << 2,\n  AVS_PLANAR_ALIGNED = 1 << 3,\n  AVS_PLANAR_Y_ALIGNED = AVS_PLANAR_Y | AVS_PLANAR_ALIGNED,\n  AVS_PLANAR_U_ALIGNED = AVS_PLANAR_U | AVS_PLANAR_ALIGNED,\n  AVS_PLANAR_V_ALIGNED = AVS_PLANAR_V | AVS_PLANAR_ALIGNED,\n  AVS_PLANAR_A = 1 << 4,\n  AVS_PLANAR_R = 1 << 5,\n  AVS_PLANAR_G = 1 << 6,\n  AVS_PLANAR_B = 1 << 7,\n  AVS_PLANAR_A_ALIGNED = AVS_PLANAR_A | AVS_PLANAR_ALIGNED,\n  AVS_PLANAR_R_ALIGNED = AVS_PLANAR_R | AVS_PLANAR_ALIGNED,\n  AVS_PLANAR_G_ALIGNED = AVS_PLANAR_G | AVS_PLANAR_ALIGNED,\n  AVS_PLANAR_B_ALIGNED = AVS_PLANAR_B | AVS_PLANAR_ALIGNED\n};\n\n// Colorspace properties.\nenum {\n  AVS_CS_YUVA = 1 << 27,\n  AVS_CS_BGR = 1 << 28,\n  AVS_CS_YUV = 1 << 29,\n  AVS_CS_INTERLEAVED = 1 << 30,\n  AVS_CS_PLANAR = 1 << 31,\n\n  AVS_CS_SHIFT_SUB_WIDTH = 0,\n  AVS_CS_SHIFT_SUB_HEIGHT = 8,\n  AVS_CS_SHIFT_SAMPLE_BITS = 16,\n\n  AVS_CS_SUB_WIDTH_MASK = 7 << AVS_CS_SHIFT_SUB_WIDTH,\n  AVS_CS_SUB_WIDTH_1 = 3 << AVS_CS_SHIFT_SUB_WIDTH, // YV24\n  AVS_CS_SUB_WIDTH_2 = 0 << AVS_CS_SHIFT_SUB_WIDTH, // YV12, I420, YV16\n  AVS_CS_SUB_WIDTH_4 = 1 << AVS_CS_SHIFT_SUB_WIDTH, // YUV9, YV411\n\n  AVS_CS_VPLANEFIRST = 1 << 3, // YV12, YV16, YV24, YV411, YUV9\n  AVS_CS_UPLANEFIRST = 1 << 4, // I420\n\n  AVS_CS_SUB_HEIGHT_MASK = 7 << AVS_CS_SHIFT_SUB_HEIGHT,\n  AVS_CS_SUB_HEIGHT_1 = 3 << AVS_CS_SHIFT_SUB_HEIGHT, // YV16, YV24, YV411\n  AVS_CS_SUB_HEIGHT_2 = 0 << AVS_CS_SHIFT_SUB_HEIGHT, // YV12, I420\n  AVS_CS_SUB_HEIGHT_4 = 1 << AVS_CS_SHIFT_SUB_HEIGHT, // YUV9\n\n  AVS_CS_SAMPLE_BITS_MASK = 7 << AVS_CS_SHIFT_SAMPLE_BITS,\n  AVS_CS_SAMPLE_BITS_8 = 0 << AVS_CS_SHIFT_SAMPLE_BITS,\n  AVS_CS_SAMPLE_BITS_10 = 5 << AVS_CS_SHIFT_SAMPLE_BITS,\n  AVS_CS_SAMPLE_BITS_12 = 6 << AVS_CS_SHIFT_SAMPLE_BITS,\n  AVS_CS_SAMPLE_BITS_14 = 7 << AVS_CS_SHIFT_SAMPLE_BITS,\n  AVS_CS_SAMPLE_BITS_16 = 1 << AVS_CS_SHIFT_SAMPLE_BITS,\n  AVS_CS_SAMPLE_BITS_32 = 2 << AVS_CS_SHIFT_SAMPLE_BITS,\n\n  AVS_CS_PLANAR_MASK = AVS_CS_PLANAR | AVS_CS_INTERLEAVED | AVS_CS_YUV | AVS_CS_BGR | AVS_CS_YUVA\n                       | AVS_CS_SAMPLE_BITS_MASK | AVS_CS_SUB_WIDTH_MASK | AVS_CS_SUB_HEIGHT_MASK,\n  AVS_CS_PLANAR_FILTER = ~(AVS_CS_VPLANEFIRST | AVS_CS_UPLANEFIRST),\n\n  AVS_CS_RGB_TYPE  = 1 << 0,\n  AVS_CS_RGBA_TYPE = 1 << 1,\n\n  AVS_CS_GENERIC_YUV444  = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_VPLANEFIRST | AVS_CS_SUB_WIDTH_1 | AVS_CS_SUB_HEIGHT_1,  // 4:4:4 planar\n  AVS_CS_GENERIC_YUV422  = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_VPLANEFIRST | AVS_CS_SUB_WIDTH_2 | AVS_CS_SUB_HEIGHT_1,  // 4:2:2 planar\n  AVS_CS_GENERIC_YUV420  = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_VPLANEFIRST | AVS_CS_SUB_WIDTH_2 | AVS_CS_SUB_HEIGHT_2,  // 4:2:0 planar\n  AVS_CS_GENERIC_Y       = AVS_CS_PLANAR | AVS_CS_INTERLEAVED | AVS_CS_YUV,                                             // Y only (4:0:0)\n  AVS_CS_GENERIC_RGBP    = AVS_CS_PLANAR | AVS_CS_BGR | AVS_CS_RGB_TYPE,                                                // planar RGB\n  AVS_CS_GENERIC_RGBAP   = AVS_CS_PLANAR | AVS_CS_BGR | AVS_CS_RGBA_TYPE,                                               // planar RGBA\n  AVS_CS_GENERIC_YUVA444 = AVS_CS_PLANAR | AVS_CS_YUVA | AVS_CS_VPLANEFIRST | AVS_CS_SUB_WIDTH_1 | AVS_CS_SUB_HEIGHT_1, // 4:4:4:A planar\n  AVS_CS_GENERIC_YUVA422 = AVS_CS_PLANAR | AVS_CS_YUVA | AVS_CS_VPLANEFIRST | AVS_CS_SUB_WIDTH_2 | AVS_CS_SUB_HEIGHT_1, // 4:2:2:A planar\n  AVS_CS_GENERIC_YUVA420 = AVS_CS_PLANAR | AVS_CS_YUVA | AVS_CS_VPLANEFIRST | AVS_CS_SUB_WIDTH_2 | AVS_CS_SUB_HEIGHT_2  // 4:2:0:A planar\n};\n\n// Specific color formats\nenum {\n  AVS_CS_UNKNOWN = 0,\n  AVS_CS_BGR24 = AVS_CS_RGB_TYPE  | AVS_CS_BGR | AVS_CS_INTERLEAVED,\n  AVS_CS_BGR32 = AVS_CS_RGBA_TYPE | AVS_CS_BGR | AVS_CS_INTERLEAVED,\n  AVS_CS_YUY2 = 1 << 2 | AVS_CS_YUV | AVS_CS_INTERLEAVED,\n  // AVS_CS_YV12 = 1 << 3   Reserved\n  // AVS_CS_I420 = 1 << 4   Reserved\n  AVS_CS_RAW32 = 1 << 5 | AVS_CS_INTERLEAVED,\n\n  AVS_CS_YV24  = AVS_CS_GENERIC_YUV444 | AVS_CS_SAMPLE_BITS_8,  // YUV 4:4:4 planar\n  AVS_CS_YV16  = AVS_CS_GENERIC_YUV422 | AVS_CS_SAMPLE_BITS_8,  // YUV 4:2:2 planar\n  AVS_CS_YV12  = AVS_CS_GENERIC_YUV420 | AVS_CS_SAMPLE_BITS_8,  // YUV 4:2:0 planar\n  AVS_CS_I420  = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_UPLANEFIRST | AVS_CS_SUB_WIDTH_2 | AVS_CS_SUB_HEIGHT_2,  // YUV 4:2:0 planar\n  AVS_CS_IYUV  = AVS_CS_I420,\n  AVS_CS_YV411 = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_VPLANEFIRST | AVS_CS_SUB_WIDTH_4 | AVS_CS_SUB_HEIGHT_1,  // YUV 4:1:1 planar\n  AVS_CS_YUV9  = AVS_CS_PLANAR | AVS_CS_YUV | AVS_CS_SAMPLE_BITS_8 | AVS_CS_VPLANEFIRST | AVS_CS_SUB_WIDTH_4 | AVS_CS_SUB_HEIGHT_4,  // YUV 4:1:0 planar\n  AVS_CS_Y8    = AVS_CS_GENERIC_Y | AVS_CS_SAMPLE_BITS_8,       // Y   4:0:0 planar\n\n  //-------------------------\n  // AVS16: new planar constants go live! Experimental PF 160613\n  // 10-12-14-16 bit + planar RGB + BGR48/64 160725\n  AVS_CS_YUV444P10 = AVS_CS_GENERIC_YUV444 | AVS_CS_SAMPLE_BITS_10, // YUV 4:4:4 10bit samples\n  AVS_CS_YUV422P10 = AVS_CS_GENERIC_YUV422 | AVS_CS_SAMPLE_BITS_10, // YUV 4:2:2 10bit samples\n  AVS_CS_YUV420P10 = AVS_CS_GENERIC_YUV420 | AVS_CS_SAMPLE_BITS_10, // YUV 4:2:0 10bit samples\n  AVS_CS_Y10       = AVS_CS_GENERIC_Y | AVS_CS_SAMPLE_BITS_10,      // Y   4:0:0 10bit samples\n\n  AVS_CS_YUV444P12 = AVS_CS_GENERIC_YUV444 | AVS_CS_SAMPLE_BITS_12, // YUV 4:4:4 12bit samples\n  AVS_CS_YUV422P12 = AVS_CS_GENERIC_YUV422 | AVS_CS_SAMPLE_BITS_12, // YUV 4:2:2 12bit samples\n  AVS_CS_YUV420P12 = AVS_CS_GENERIC_YUV420 | AVS_CS_SAMPLE_BITS_12, // YUV 4:2:0 12bit samples\n  AVS_CS_Y12       = AVS_CS_GENERIC_Y | AVS_CS_SAMPLE_BITS_12,      // Y   4:0:0 12bit samples\n\n  AVS_CS_YUV444P14 = AVS_CS_GENERIC_YUV444 | AVS_CS_SAMPLE_BITS_14, // YUV 4:4:4 14bit samples\n  AVS_CS_YUV422P14 = AVS_CS_GENERIC_YUV422 | AVS_CS_SAMPLE_BITS_14, // YUV 4:2:2 14bit samples\n  AVS_CS_YUV420P14 = AVS_CS_GENERIC_YUV420 | AVS_CS_SAMPLE_BITS_14, // YUV 4:2:0 14bit samples\n  AVS_CS_Y14       = AVS_CS_GENERIC_Y | AVS_CS_SAMPLE_BITS_14,      // Y   4:0:0 14bit samples\n\n  AVS_CS_YUV444P16 = AVS_CS_GENERIC_YUV444 | AVS_CS_SAMPLE_BITS_16, // YUV 4:4:4 16bit samples\n  AVS_CS_YUV422P16 = AVS_CS_GENERIC_YUV422 | AVS_CS_SAMPLE_BITS_16, // YUV 4:2:2 16bit samples\n  AVS_CS_YUV420P16 = AVS_CS_GENERIC_YUV420 | AVS_CS_SAMPLE_BITS_16, // YUV 4:2:0 16bit samples\n  AVS_CS_Y16       = AVS_CS_GENERIC_Y | AVS_CS_SAMPLE_BITS_16,      // Y   4:0:0 16bit samples\n\n  // 32 bit samples (float)\n  AVS_CS_YUV444PS = AVS_CS_GENERIC_YUV444 | AVS_CS_SAMPLE_BITS_32,  // YUV 4:4:4 32bit samples\n  AVS_CS_YUV422PS = AVS_CS_GENERIC_YUV422 | AVS_CS_SAMPLE_BITS_32,  // YUV 4:2:2 32bit samples\n  AVS_CS_YUV420PS = AVS_CS_GENERIC_YUV420 | AVS_CS_SAMPLE_BITS_32,  // YUV 4:2:0 32bit samples\n  AVS_CS_Y32      = AVS_CS_GENERIC_Y | AVS_CS_SAMPLE_BITS_32,       // Y   4:0:0 32bit samples\n\n  // RGB packed\n  AVS_CS_BGR48 = AVS_CS_RGB_TYPE | AVS_CS_BGR | AVS_CS_INTERLEAVED | AVS_CS_SAMPLE_BITS_16,    // BGR 3x16 bit\n  AVS_CS_BGR64 = AVS_CS_RGBA_TYPE | AVS_CS_BGR | AVS_CS_INTERLEAVED | AVS_CS_SAMPLE_BITS_16,    // BGR 4x16 bit\n  // no packed 32 bit (float) support for these legacy types\n\n  // RGB planar\n  AVS_CS_RGBP   = AVS_CS_GENERIC_RGBP | AVS_CS_SAMPLE_BITS_8,  // Planar RGB 8 bit samples\n  AVS_CS_RGBP10 = AVS_CS_GENERIC_RGBP | AVS_CS_SAMPLE_BITS_10, // Planar RGB 10bit samples\n  AVS_CS_RGBP12 = AVS_CS_GENERIC_RGBP | AVS_CS_SAMPLE_BITS_12, // Planar RGB 12bit samples\n  AVS_CS_RGBP14 = AVS_CS_GENERIC_RGBP | AVS_CS_SAMPLE_BITS_14, // Planar RGB 14bit samples\n  AVS_CS_RGBP16 = AVS_CS_GENERIC_RGBP | AVS_CS_SAMPLE_BITS_16, // Planar RGB 16bit samples\n  AVS_CS_RGBPS  = AVS_CS_GENERIC_RGBP | AVS_CS_SAMPLE_BITS_32, // Planar RGB 32bit samples\n\n  // RGBA planar\n  AVS_CS_RGBAP   = AVS_CS_GENERIC_RGBAP | AVS_CS_SAMPLE_BITS_8,  // Planar RGBA 8 bit samples\n  AVS_CS_RGBAP10 = AVS_CS_GENERIC_RGBAP | AVS_CS_SAMPLE_BITS_10, // Planar RGBA 10bit samples\n  AVS_CS_RGBAP12 = AVS_CS_GENERIC_RGBAP | AVS_CS_SAMPLE_BITS_12, // Planar RGBA 12bit samples\n  AVS_CS_RGBAP14 = AVS_CS_GENERIC_RGBAP | AVS_CS_SAMPLE_BITS_14, // Planar RGBA 14bit samples\n  AVS_CS_RGBAP16 = AVS_CS_GENERIC_RGBAP | AVS_CS_SAMPLE_BITS_16, // Planar RGBA 16bit samples\n  AVS_CS_RGBAPS  = AVS_CS_GENERIC_RGBAP | AVS_CS_SAMPLE_BITS_32, // Planar RGBA 32bit samples\n\n  // Planar YUVA\n  AVS_CS_YUVA444    = AVS_CS_GENERIC_YUVA444 | AVS_CS_SAMPLE_BITS_8,  // YUVA 4:4:4 8bit samples\n  AVS_CS_YUVA422    = AVS_CS_GENERIC_YUVA422 | AVS_CS_SAMPLE_BITS_8,  // YUVA 4:2:2 8bit samples\n  AVS_CS_YUVA420    = AVS_CS_GENERIC_YUVA420 | AVS_CS_SAMPLE_BITS_8,  // YUVA 4:2:0 8bit samples\n\n  AVS_CS_YUVA444P10 = AVS_CS_GENERIC_YUVA444 | AVS_CS_SAMPLE_BITS_10, // YUVA 4:4:4 10bit samples\n  AVS_CS_YUVA422P10 = AVS_CS_GENERIC_YUVA422 | AVS_CS_SAMPLE_BITS_10, // YUVA 4:2:2 10bit samples\n  AVS_CS_YUVA420P10 = AVS_CS_GENERIC_YUVA420 | AVS_CS_SAMPLE_BITS_10, // YUVA 4:2:0 10bit samples\n\n  AVS_CS_YUVA444P12 = AVS_CS_GENERIC_YUVA444 | AVS_CS_SAMPLE_BITS_12, // YUVA 4:4:4 12bit samples\n  AVS_CS_YUVA422P12 = AVS_CS_GENERIC_YUVA422 | AVS_CS_SAMPLE_BITS_12, // YUVA 4:2:2 12bit samples\n  AVS_CS_YUVA420P12 = AVS_CS_GENERIC_YUVA420 | AVS_CS_SAMPLE_BITS_12, // YUVA 4:2:0 12bit samples\n\n  AVS_CS_YUVA444P14 = AVS_CS_GENERIC_YUVA444 | AVS_CS_SAMPLE_BITS_14, // YUVA 4:4:4 14bit samples\n  AVS_CS_YUVA422P14 = AVS_CS_GENERIC_YUVA422 | AVS_CS_SAMPLE_BITS_14, // YUVA 4:2:2 14bit samples\n  AVS_CS_YUVA420P14 = AVS_CS_GENERIC_YUVA420 | AVS_CS_SAMPLE_BITS_14, // YUVA 4:2:0 14bit samples\n\n  AVS_CS_YUVA444P16 = AVS_CS_GENERIC_YUVA444 | AVS_CS_SAMPLE_BITS_16, // YUVA 4:4:4 16bit samples\n  AVS_CS_YUVA422P16 = AVS_CS_GENERIC_YUVA422 | AVS_CS_SAMPLE_BITS_16, // YUVA 4:2:2 16bit samples\n  AVS_CS_YUVA420P16 = AVS_CS_GENERIC_YUVA420 | AVS_CS_SAMPLE_BITS_16, // YUVA 4:2:0 16bit samples\n\n  AVS_CS_YUVA444PS  = AVS_CS_GENERIC_YUVA444 | AVS_CS_SAMPLE_BITS_32,  // YUVA 4:4:4 32bit samples\n  AVS_CS_YUVA422PS  = AVS_CS_GENERIC_YUVA422 | AVS_CS_SAMPLE_BITS_32,  // YUVA 4:2:2 32bit samples\n  AVS_CS_YUVA420PS  = AVS_CS_GENERIC_YUVA420 | AVS_CS_SAMPLE_BITS_32,  // YUVA 4:2:0 32bit samples\n};\n\n// AvsChannelMask enum: Unshifted channel mask constants like in WAVEFORMATEXTENSIBLE\n// in AvsImageTypeFlags they are shifted by 4 bits\nenum {\n  AVS_MASK_SPEAKER_FRONT_LEFT = 0x1,\n  AVS_MASK_SPEAKER_FRONT_RIGHT = 0x2,\n  AVS_MASK_SPEAKER_FRONT_CENTER = 0x4,\n  AVS_MASK_SPEAKER_LOW_FREQUENCY = 0x8,\n  AVS_MASK_SPEAKER_BACK_LEFT = 0x10,\n  AVS_MASK_SPEAKER_BACK_RIGHT = 0x20,\n  AVS_MASK_SPEAKER_FRONT_LEFT_OF_CENTER = 0x40,\n  AVS_MASK_SPEAKER_FRONT_RIGHT_OF_CENTER = 0x80,\n  AVS_MASK_SPEAKER_BACK_CENTER = 0x100,\n  AVS_MASK_SPEAKER_SIDE_LEFT = 0x200,\n  AVS_MASK_SPEAKER_SIDE_RIGHT = 0x400,\n  AVS_MASK_SPEAKER_TOP_CENTER = 0x800,\n  AVS_MASK_SPEAKER_TOP_FRONT_LEFT = 0x1000,\n  AVS_MASK_SPEAKER_TOP_FRONT_CENTER = 0x2000,\n  AVS_MASK_SPEAKER_TOP_FRONT_RIGHT = 0x4000,\n  AVS_MASK_SPEAKER_TOP_BACK_LEFT = 0x8000,\n  AVS_MASK_SPEAKER_TOP_BACK_CENTER = 0x10000,\n  AVS_MASK_SPEAKER_TOP_BACK_RIGHT = 0x20000,\n  // Bit mask locations used up for the above positions\n  AVS_MASK_SPEAKER_DEFINED = 0x0003FFFF,\n  // Bit mask locations reserved for future use\n  AVS_MASK_SPEAKER_RESERVED = 0x7FFC0000,\n  // Used to specify that any possible permutation of speaker configurations\n  // Due to lack of available bits this one is put differently into image_type\n  AVS_MASK_SPEAKER_ALL = 0x80000000\n};\n\n// AvsImageTypeFlags\nenum {\n  AVS_IT_BFF = 1 << 0,\n  AVS_IT_TFF = 1 << 1,\n  AVS_IT_FIELDBASED = 1 << 2,\n\n  // Audio channel mask support\n  AVS_IT_HAS_CHANNELMASK = 1 << 3,\n  // shifted by 4 bits compared to WAVEFORMATEXTENSIBLE dwChannelMask\n  // otherwise same as AvsChannelMask\n  AVS_IT_SPEAKER_FRONT_LEFT = 0x1 << 4,\n  AVS_IT_SPEAKER_FRONT_RIGHT = 0x2 << 4,\n  AVS_IT_SPEAKER_FRONT_CENTER = 0x4 << 4,\n  AVS_IT_SPEAKER_LOW_FREQUENCY = 0x8 << 4,\n  AVS_IT_SPEAKER_BACK_LEFT = 0x10 << 4,\n  AVS_IT_SPEAKER_BACK_RIGHT = 0x20 << 4,\n  AVS_IT_SPEAKER_FRONT_LEFT_OF_CENTER = 0x40 << 4,\n  AVS_IT_SPEAKER_FRONT_RIGHT_OF_CENTER = 0x80 << 4,\n  AVS_IT_SPEAKER_BACK_CENTER = 0x100 << 4,\n  AVS_IT_SPEAKER_SIDE_LEFT = 0x200 << 4,\n  AVS_IT_SPEAKER_SIDE_RIGHT = 0x400 << 4,\n  AVS_IT_SPEAKER_TOP_CENTER = 0x800 << 4,\n  AVS_IT_SPEAKER_TOP_FRONT_LEFT = 0x1000 << 4,\n  AVS_IT_SPEAKER_TOP_FRONT_CENTER = 0x2000 << 4,\n  AVS_IT_SPEAKER_TOP_FRONT_RIGHT = 0x4000 << 4,\n  AVS_IT_SPEAKER_TOP_BACK_LEFT = 0x8000 << 4,\n  AVS_IT_SPEAKER_TOP_BACK_CENTER = 0x10000 << 4,\n  AVS_IT_SPEAKER_TOP_BACK_RIGHT = 0x20000 << 4,\n  // End of officially defined speaker bits\n  // The next one is special, since cannot shift SPEAKER_ALL 0x80000000 further.\n  // Set mask and get mask handles it.\n  AVS_IT_SPEAKER_ALL = 0x40000 << 4,\n  // Mask for the defined 18 bits + SPEAKER_ALL\n  AVS_IT_SPEAKER_BITS_MASK = (AVS_MASK_SPEAKER_DEFINED << 4) | AVS_IT_SPEAKER_ALL,\n  AVS_IT_NEXT_AVAILABLE = 1 << 23\n};\n\nenum {\n  AVS_FILTER_TYPE = 1,\n  AVS_FILTER_INPUT_COLORSPACE = 2,\n  AVS_FILTER_OUTPUT_TYPE = 9,\n  AVS_FILTER_NAME = 4,\n  AVS_FILTER_AUTHOR = 5,\n  AVS_FILTER_VERSION = 6,\n  AVS_FILTER_ARGS = 7,\n  AVS_FILTER_ARGS_INFO = 8,\n  AVS_FILTER_ARGS_DESCRIPTION = 10,\n  AVS_FILTER_DESCRIPTION = 11\n};\n\nenum {  // SUBTYPES\n  AVS_FILTER_TYPE_AUDIO = 1,\n  AVS_FILTER_TYPE_VIDEO = 2,\n  AVS_FILTER_OUTPUT_TYPE_SAME = 3,\n  AVS_FILTER_OUTPUT_TYPE_DIFFERENT = 4\n};\n\nenum {\n  AVS_CACHE_25_NOTHING_26_UNUSED = 0,\n  // New 2.6 explicitly defined cache hints.\n  AVS_CACHE_NOTHING = 10, // Do not cache video.\n  AVS_CACHE_WINDOW = 11, // Hard protect up to X frames within a range of X from the current frame N.\n  AVS_CACHE_GENERIC = 12, // LRU cache up to X frames.\n  AVS_CACHE_FORCE_GENERIC = 13, // LRU cache up to X frames, override any previous CACHE_WINDOW.\n\n  AVS_CACHE_GET_POLICY = 30, // Get the current policy.\n  AVS_CACHE_GET_WINDOW = 31, // Get the current window h_span.\n  AVS_CACHE_GET_RANGE = 32, // Get the current generic frame range.\n\n  // Set Audio cache mode and answers to CACHE_GETCHILD_AUDIO_MODE\n  AVS_CACHE_AUDIO = 50, // Explicitly do cache audio, X byte cache.\n  AVS_CACHE_AUDIO_NOTHING = 51, // Explicitly do not cache audio.\n  AVS_CACHE_AUDIO_NONE = 52, // Audio cache off (auto mode), X byte initial cache.\n  AVS_CACHE_AUDIO_AUTO_START_OFF = 52, // synonym\n  AVS_CACHE_AUDIO_AUTO = 53, // Audio cache on (auto mode), X byte initial cache.\n  AVS_CACHE_AUDIO_AUTO_START_ON = 53, // synonym\n\n  // These just returns actual value if clip is cached\n  AVS_CACHE_GET_AUDIO_POLICY = 70, // Get the current audio policy.\n  AVS_CACHE_GET_AUDIO_SIZE = 71, // Get the current audio cache size.\n\n  AVS_CACHE_PREFETCH_FRAME = 100, // n/a Queue request to prefetch frame N.\n  AVS_CACHE_PREFETCH_GO = 101, // n/a Action video prefetches.\n\n  AVS_CACHE_PREFETCH_AUDIO_BEGIN = 120, // n/a Begin queue request transaction to prefetch audio (take critical section).\n  AVS_CACHE_PREFETCH_AUDIO_STARTLO = 121, // n/a Set low 32 bits of start.\n  AVS_CACHE_PREFETCH_AUDIO_STARTHI = 122, // n/a Set high 32 bits of start.\n  AVS_CACHE_PREFETCH_AUDIO_COUNT = 123, // n/a Set low 32 bits of length.\n  AVS_CACHE_PREFETCH_AUDIO_COMMIT = 124, // n/a Enqueue request transaction to prefetch audio (release critical section).\n  AVS_CACHE_PREFETCH_AUDIO_GO = 125, // n/a Action audio prefetches.\n\n  AVS_CACHE_GETCHILD_CACHE_MODE = 200, // n/a Cache ask Child for desired video cache mode.\n  AVS_CACHE_GETCHILD_CACHE_SIZE = 201, // n/a Cache ask Child for desired video cache size.\n\n  // Filters are queried about their desired audio cache mode.\n  // Child can answer them with CACHE_AUDIO_xxx\n  AVS_CACHE_GETCHILD_AUDIO_MODE = 202, // Cache ask Child for desired audio cache mode.\n  AVS_CACHE_GETCHILD_AUDIO_SIZE = 203, // Cache ask Child for desired audio cache size.\n\n  AVS_CACHE_GETCHILD_COST = 220, // n/a Cache ask Child for estimated processing cost.\n  AVS_CACHE_COST_ZERO = 221, // n/a Child response of zero cost (ptr arithmetic only).\n  AVS_CACHE_COST_UNIT = 222, // n/a Child response of unit cost (less than or equal 1 full frame blit).\n  AVS_CACHE_COST_LOW = 223, // n/a Child response of light cost. (Fast)\n  AVS_CACHE_COST_MED = 224, // n/a Child response of medium cost. (Real time)\n  AVS_CACHE_COST_HI = 225, // n/a Child response of heavy cost. (Slow)\n\n  AVS_CACHE_GETCHILD_THREAD_MODE = 240, // n/a Cache ask Child for thread safety.\n  AVS_CACHE_THREAD_UNSAFE = 241, // n/a Only 1 thread allowed for all instances. 2.5 filters default!\n  AVS_CACHE_THREAD_CLASS = 242, // n/a Only 1 thread allowed for each instance. 2.6 filters default!\n  AVS_CACHE_THREAD_SAFE = 243, // n/a Allow all threads in any instance.\n  AVS_CACHE_THREAD_OWN = 244, // n/a Safe but limit to 1 thread, internally threaded.\n\n  AVS_CACHE_GETCHILD_ACCESS_COST = 260, // Cache ask Child for preferred access pattern.\n  AVS_CACHE_ACCESS_RAND = 261, // Filter is access order agnostic.\n  AVS_CACHE_ACCESS_SEQ0 = 262, // Filter prefers sequential access (low cost)\n  AVS_CACHE_ACCESS_SEQ1 = 263, // Filter needs sequential access (high cost)\n\n  AVS_CACHE_AVSPLUS_CONSTANTS = 500,    // Smaller values are reserved for classic Avisynth\n\n  AVS_CACHE_DONT_CACHE_ME = 501,              // Filters that don't need caching (eg. trim, cache etc.) should return 1 to this request\n  AVS_CACHE_SET_MIN_CAPACITY = 502,\n  AVS_CACHE_SET_MAX_CAPACITY = 503,\n  AVS_CACHE_GET_MIN_CAPACITY = 504,\n  AVS_CACHE_GET_MAX_CAPACITY = 505,\n  AVS_CACHE_GET_SIZE = 506,\n  AVS_CACHE_GET_REQUESTED_CAP = 507,\n  AVS_CACHE_GET_CAPACITY = 508,\n  AVS_CACHE_GET_MTMODE = 509,                 // Filters specify their desired MT mode, see enum MtMode\n\n  // By returning IS_CACHE_ANS to IS_CACHE_REQ, we tell the caller we are a cache\n  AVS_CACHE_IS_CACHE_REQ = 510,\n  AVS_CACHE_IS_CACHE_ANS = 511,\n  // By returning IS_MTGUARD_ANS to IS_MTGUARD_REQ, we tell the caller we are an mt guard\n  AVS_CACHE_IS_MTGUARD_REQ = 512,\n  AVS_CACHE_IS_MTGUARD_ANS = 513,\n\n  // v12\n  AVS_CACHE_INFORM_NUM_THREADS = 514, // Allows a filter to receive the number of prefetch threads via set_cache_hints\n\n\n  AVS_CACHE_AVSPLUS_CUDA_CONSTANTS = 600,\n\n  AVS_CACHE_GET_DEV_TYPE = 601,          // Device types a filter can return\n  AVS_CACHE_GET_CHILD_DEV_TYPE = 602,    // Device types a fitler can receive\n\n  AVS_CACHE_USER_CONSTANTS = 1000       // Smaller values are reserved for the core\n};\n\n\n\n// enums for frame property functions\n// AVSPropTypes\nenum {\n  AVS_PROPTYPE_UNSET = 'u',\n  AVS_PROPTYPE_INT = 'i',\n  AVS_PROPTYPE_FLOAT = 'f',\n  AVS_PROPTYPE_DATA = 's',\n  AVS_PROPTYPE_CLIP = 'c',\n  AVS_PROPTYPE_FRAME = 'v'\n};\n\n// AVSGetPropErrors for avs_prop_get_...\nenum {\n  AVS_GETPROPERROR_SUCCESS = 0,\n  AVS_GETPROPERROR_UNSET = 1,\n  AVS_GETPROPERROR_TYPE = 2,\n  AVS_GETPROPERROR_ERROR = 3,\n  AVS_GETPROPERROR_INDEX = 4\n};\n\n// AVSPropAppendMode for avs_prop_set_...\nenum {\n  AVS_PROPAPPENDMODE_REPLACE = 0,\n  AVS_PROPAPPENDMODE_APPEND = 1,\n  AVS_PROPAPPENDMODE_TOUCH = 2 // n/a\n};\n\n// AVSPropDataTypeHint, used with prop_set_data_h\nenum {\n  AVS_PROPDATATYPEHINT_UNKNOWN = -1, // dtUnknown = -1,\n  AVS_PROPDATATYPEHINT_BINARY = 0, // dtBinary = 0,\n  AVS_PROPDATATYPEHINT_UTF8 = 1 // dtUtf8 = 1\n};\n\n\n// AvsEnvProperty for avs_get_env_property\nenum {\n  AVS_AEP_PHYSICAL_CPUS = 1,\n  AVS_AEP_LOGICAL_CPUS = 2,\n  AVS_AEP_THREADPOOL_THREADS = 3,\n  AVS_AEP_FILTERCHAIN_THREADS = 4,\n  AVS_AEP_THREAD_ID = 5,\n  AVS_AEP_VERSION = 6,\n  AVS_AEP_HOST_SYSTEM_ENDIANNESS = 7,\n  AVS_AEP_INTERFACE_VERSION = 8,\n  AVS_AEP_INTERFACE_BUGFIX = 9,\n  AVS_AEP_CACHESIZE_L2 = 10, // v12\n\n  // Neo additionals\n  AVS_AEP_NUM_DEVICES = 901,\n  AVS_AEP_FRAME_ALIGN = 902,\n  AVS_AEP_PLANE_ALIGN = 903,\n\n  AVS_AEP_SUPPRESS_THREAD = 921,\n  AVS_AEP_GETFRAME_RECURSIVE = 922\n};\n\n// enum AvsAllocType for avs_allocate\nenum {\n  AVS_ALLOCTYPE_NORMAL_ALLOC = 1,\n  AVS_ALLOCTYPE_POOLED_ALLOC = 2\n};\n\n// Multithreading behaviour. AVS_Clip avs_set_cache_hints can return them on AVS_CACHE_GET_MTMODE query\nenum {\n  AVS_MT_INVALID = 0,\n  AVS_MT_NICE_FILTER = 1,\n  AVS_MT_MULTI_INSTANCE = 2,\n  AVS_MT_SERIALIZED = 3,\n  AVS_MT_SPECIAL_MT = 4,\n  AVS_MT_MODE_COUNT = 5\n};\n\n\n#ifdef BUILDING_AVSCORE\nAVSValue create_c_video_filter(AVSValue args, void * user_data, IScriptEnvironment * e0);\n\nstruct AVS_ScriptEnvironment {\n        IScriptEnvironment * env;\n        const char * error;\n        AVS_ScriptEnvironment(IScriptEnvironment * e = 0)\n                : env(e), error(0) {}\n};\n#endif\n\ntypedef struct AVS_Clip AVS_Clip;\ntypedef struct AVS_ScriptEnvironment AVS_ScriptEnvironment;\n\n/////////////////////////////////////////////////////////////////////\n//\n// AVS_VideoInfo\n//\n\n// AVS_VideoInfo is laid out identically to VideoInfo\ntypedef struct AVS_VideoInfo {\n  int width, height;    // width=0 means no video\n  unsigned fps_numerator, fps_denominator;\n  int num_frames;\n\n  int pixel_type;\n\n  int audio_samples_per_second;   // 0 means no audio\n  int sample_type;\n  int64_t num_audio_samples;\n  int nchannels;\n\n  // Image type properties\n  // BFF, TFF, FIELDBASED. Also used for storing Channel Mask\n  // Manipulate it through the channelmask interface calls \n  int image_type;\n} AVS_VideoInfo;\n\n// useful functions of the above\nAVSC_INLINE int avs_has_video(const AVS_VideoInfo * p)\n        { return (p->width!=0); }\n\nAVSC_INLINE int avs_has_audio(const AVS_VideoInfo * p)\n        { return (p->audio_samples_per_second!=0); }\n\nAVSC_INLINE int avs_is_rgb(const AVS_VideoInfo * p)\n        { return !!(p->pixel_type&AVS_CS_BGR); }\n\nAVSC_INLINE int avs_is_rgb24(const AVS_VideoInfo * p)\n        { return ((p->pixel_type&AVS_CS_BGR24)==AVS_CS_BGR24) && ((p->pixel_type & AVS_CS_SAMPLE_BITS_MASK) == AVS_CS_SAMPLE_BITS_8); }\n\nAVSC_INLINE int avs_is_rgb32(const AVS_VideoInfo * p)\n       { return ((p->pixel_type&AVS_CS_BGR32)==AVS_CS_BGR32) && ((p->pixel_type & AVS_CS_SAMPLE_BITS_MASK) == AVS_CS_SAMPLE_BITS_8); }\n\nAVSC_INLINE int avs_is_yuv(const AVS_VideoInfo * p)\n        { return !!(p->pixel_type&AVS_CS_YUV ); }\n\nAVSC_INLINE int avs_is_yuy2(const AVS_VideoInfo * p)\n        { return (p->pixel_type & AVS_CS_YUY2) == AVS_CS_YUY2; }\n\nAVSC_API(int, avs_is_yv24)(const AVS_VideoInfo * p); // avs+: for generic 444 check, use avs_is_yuv444\n\nAVSC_API(int, avs_is_yv16)(const AVS_VideoInfo * p); // avs+: for generic 422 check, use avs_is_yuv422\n\nAVSC_API(int, avs_is_yv12)(const AVS_VideoInfo * p) ; // avs+: for generic 420 check, use avs_is_yuv420\n\nAVSC_API(int, avs_is_yv411)(const AVS_VideoInfo * p);\n\nAVSC_API(int, avs_is_y8)(const AVS_VideoInfo * p); // avs+: for generic grayscale, use avs_is_y\n\nAVSC_API(int, avs_get_plane_width_subsampling)(const AVS_VideoInfo * p, int plane);\n\nAVSC_API(int, avs_get_plane_height_subsampling)(const AVS_VideoInfo * p, int plane);\n\nAVSC_API(int, avs_bits_per_pixel)(const AVS_VideoInfo * p);\n\nAVSC_API(int, avs_bytes_from_pixels)(const AVS_VideoInfo * p, int pixels);\n\nAVSC_API(int, avs_row_size)(const AVS_VideoInfo * p, int plane);\n\nAVSC_API(int, avs_bmp_size)(const AVS_VideoInfo * vi);\n\nAVSC_API(int, avs_is_color_space)(const AVS_VideoInfo * p, int c_space);\n\n// no API for these, inline helper functions\n\n// this is _not_ for frame properties\nAVSC_INLINE int avs_is_property(const AVS_VideoInfo * p, int property)\n{\n  return ((p->image_type & property) == property);\n}\n\nAVSC_INLINE int avs_is_planar(const AVS_VideoInfo * p)\n{\n  return !!(p->pixel_type & AVS_CS_PLANAR);\n}\n\nAVSC_INLINE int avs_is_field_based(const AVS_VideoInfo * p)\n{\n  return !!(p->image_type & AVS_IT_FIELDBASED);\n}\n\nAVSC_INLINE int avs_is_parity_known(const AVS_VideoInfo * p)\n{\n  return ((p->image_type & AVS_IT_FIELDBASED) && (p->image_type & (AVS_IT_BFF | AVS_IT_TFF)));\n}\n\nAVSC_INLINE int avs_is_bff(const AVS_VideoInfo * p)\n{\n  return !!(p->image_type & AVS_IT_BFF);\n}\n\nAVSC_INLINE int avs_is_tff(const AVS_VideoInfo * p)\n{\n  return !!(p->image_type & AVS_IT_TFF);\n}\n\nAVSC_INLINE int avs_samples_per_second(const AVS_VideoInfo * p)\n        { return p->audio_samples_per_second; }\n\nAVSC_INLINE int avs_bytes_per_channel_sample(const AVS_VideoInfo * p)\n{\n    switch (p->sample_type) {\n      case AVS_SAMPLE_INT8:  return sizeof(signed char);\n      case AVS_SAMPLE_INT16: return sizeof(signed short);\n      case AVS_SAMPLE_INT24: return 3;\n      case AVS_SAMPLE_INT32: return sizeof(signed int);\n      case AVS_SAMPLE_FLOAT: return sizeof(float);\n      default: return 0;\n    }\n}\n\nAVSC_INLINE int avs_bytes_per_audio_sample(const AVS_VideoInfo * p)\n        { return p->nchannels*avs_bytes_per_channel_sample(p);}\n\nAVSC_INLINE int64_t avs_audio_samples_from_frames(const AVS_VideoInfo * p, int64_t frames)\n        { return ((int64_t)(frames) * p->audio_samples_per_second * p->fps_denominator / p->fps_numerator); }\n\nAVSC_INLINE int avs_frames_from_audio_samples(const AVS_VideoInfo * p, int64_t samples)\n        { return (int)(samples * (int64_t)p->fps_numerator / (int64_t)p->fps_denominator / (int64_t)p->audio_samples_per_second); }\n\nAVSC_INLINE int64_t avs_audio_samples_from_bytes(const AVS_VideoInfo * p, int64_t bytes)\n        { return bytes / avs_bytes_per_audio_sample(p); }\n\nAVSC_INLINE int64_t avs_bytes_from_audio_samples(const AVS_VideoInfo * p, int64_t samples)\n        { return samples * avs_bytes_per_audio_sample(p); }\n\nAVSC_INLINE int avs_audio_channels(const AVS_VideoInfo * p)\n        { return p->nchannels; }\n\nAVSC_INLINE int avs_sample_type(const AVS_VideoInfo * p)\n        { return p->sample_type;}\n\n// useful mutator\n// Note: these are video format properties, neither frame properties, nor system properties\nAVSC_INLINE void avs_set_property(AVS_VideoInfo * p, int property)\n        { p->image_type|=property; }\n\nAVSC_INLINE void avs_clear_property(AVS_VideoInfo * p, int property)\n        { p->image_type&=~property; }\n\nAVSC_INLINE void avs_set_field_based(AVS_VideoInfo * p, int isfieldbased)\n        { if (isfieldbased) p->image_type|=AVS_IT_FIELDBASED; else p->image_type&=~AVS_IT_FIELDBASED; }\n\nAVSC_INLINE void avs_set_fps(AVS_VideoInfo * p, unsigned numerator, unsigned denominator)\n{\n    unsigned x=numerator, y=denominator;\n    while (y) {   // find gcd\n      unsigned t = x%y; x = y; y = t;\n    }\n    p->fps_numerator = numerator/x;\n    p->fps_denominator = denominator/x;\n}\n\n#ifndef AVSC_NO_DECLSPEC\n// this inline function is calling an API function\nAVSC_INLINE int avs_is_same_colorspace(const AVS_VideoInfo * x, const AVS_VideoInfo * y)\n{\n        return (x->pixel_type == y->pixel_type)\n                || (avs_is_yv12(x) && avs_is_yv12(y));\n}\n#endif\n\n// AviSynth+ extensions\nAVSC_API(int, avs_is_rgb48)(const AVS_VideoInfo * p);\n\nAVSC_API(int, avs_is_rgb64)(const AVS_VideoInfo * p);\n\nAVSC_API(int, avs_is_yuv444p16)(const AVS_VideoInfo * p); // deprecated, use avs_is_yuv444\nAVSC_API(int, avs_is_yuv422p16)(const AVS_VideoInfo * p); // deprecated, use avs_is_yuv422\nAVSC_API(int, avs_is_yuv420p16)(const AVS_VideoInfo * p); // deprecated, use avs_is_yuv420\nAVSC_API(int, avs_is_y16)(const AVS_VideoInfo * p); // deprecated, use avs_is_y\nAVSC_API(int, avs_is_yuv444ps)(const AVS_VideoInfo * p); // deprecated, use avs_is_yuv444\nAVSC_API(int, avs_is_yuv422ps)(const AVS_VideoInfo * p); // deprecated, use avs_is_yuv422\nAVSC_API(int, avs_is_yuv420ps)(const AVS_VideoInfo * p); // deprecated, use avs_is_yuv420\nAVSC_API(int, avs_is_y32)(const AVS_VideoInfo * p); // deprecated, use avs_is_y\n\nAVSC_API(int, avs_is_444)(const AVS_VideoInfo * p);\n\nAVSC_API(int, avs_is_422)(const AVS_VideoInfo * p);\n\nAVSC_API(int, avs_is_420)(const AVS_VideoInfo * p);\n\nAVSC_API(int, avs_is_y)(const AVS_VideoInfo * p);\n\nAVSC_API(int, avs_is_yuva)(const AVS_VideoInfo * p);\n\nAVSC_API(int, avs_is_planar_rgb)(const AVS_VideoInfo * p);\n\nAVSC_API(int, avs_is_planar_rgba)(const AVS_VideoInfo * p);\n\nAVSC_API(int, avs_num_components)(const AVS_VideoInfo * p);\n\nAVSC_API(int, avs_component_size)(const AVS_VideoInfo * p);\n\nAVSC_API(int, avs_bits_per_component)(const AVS_VideoInfo * p);\n\n// V10\nAVSC_API(bool, avs_is_channel_mask_known)(const AVS_VideoInfo* p);\n\nAVSC_API(void, avs_set_channel_mask)(const AVS_VideoInfo* p, bool isChannelMaskKnown, unsigned int dwChannelMask);\n\nAVSC_API(unsigned int, avs_get_channel_mask)(const AVS_VideoInfo* p);\n\n// end of Avisynth+ specific\n\n/////////////////////////////////////////////////////////////////////\n//\n// AVS_VideoFrame\n//\n\n// VideoFrameBuffer holds information about a memory block which is used\n// for video data.  For efficiency, instances of this class are not deleted\n// when the refcount reaches zero; instead they're stored in a linked list\n// to be reused.  The instances are deleted when the corresponding AVS\n// file is closed.\n\n// DEPRECATION WARNING\n// Note: The V12 API will only define\n// typedef struct AVS_VideoFrame AVS_VideoFrame;\n// without including any internals of AVS_VideoFrame and AVS_VideoFrameBuffer.\n\n// AVS_VideoFrameBuffer is laid out identically to VideoFrameBuffer\n// DO NOT USE THIS STRUCTURE DIRECTLY\ntypedef struct AVS_VideoFrameBuffer {\n  BYTE * data;\n  int data_size;\n  // sequence_number is incremented every time the buffer is changed, so\n  // that stale views can tell they're no longer valid.\n  volatile long sequence_number;\n\n  volatile long refcount;\n\n  void* device; // avs+\n} AVS_VideoFrameBuffer;\n\n// VideoFrame holds a \"window\" into a VideoFrameBuffer.\n\n// AVS_VideoFrame is laid out identically to VideoFrame\n// DO NOT USE THIS STRUCTURE DIRECTLY\n// In V11 header a leading '_' was added to member names intentionally.\n// Stop direct access and use avs_get_xxx API calls instead!\ntypedef struct AVS_VideoFrame {\n  volatile long _refcount;\n  AVS_VideoFrameBuffer * _vfb;\n  int _offset;\n  // DO NOT USE THEM DIRECTLY\n  // Use avs_get_pitch_p, avs_get_row_size_p, avs_get_height_p\n  int _pitch, _row_size, _height;\n  int _offsetU, _offsetV;\n  int _pitchUV;  // U&V offsets are from top of picture.\n  int _row_sizeUV, _heightUV; // for Planar RGB offsetU, offsetV is for the 2nd and 3rd Plane.\n                            // for Planar RGB pitchUV and row_sizeUV = 0, because when no VideoInfo (MakeWriteable)\n                            // the decision on existence of UV is checked by zero pitch\n  // AVS+ extension, avisynth.h: class does not break plugins if appended here\n  int _offsetA;\n  int _pitchA, _row_sizeA; // 4th alpha plane support, pitch and row_size is 0 is none\n  void* _properties; // interface V8: frame properties\n  // DO NOT USE DIRECTLY\n  // Use avs_video_frame_get_pixel_type (and avs_video_frame_amend_pixel_type in special cases)\n  int _pixel_type; // Interface V10: an automatically maintained copy from AVS_VideoInfo\n} AVS_VideoFrame;\n\n// Access functions for AVS_VideoFrame\nAVSC_API(int, avs_get_pitch_p)(const AVS_VideoFrame * p, int plane);\n\nAVSC_API(int, avs_get_row_size_p)(const AVS_VideoFrame * p, int plane);\n\nAVSC_API(int, avs_get_height_p)(const AVS_VideoFrame * p, int plane);\n\nAVSC_API(const BYTE *, avs_get_read_ptr_p)(const AVS_VideoFrame * p, int plane);\n\nAVSC_API(int, avs_is_writable)(const AVS_VideoFrame * p);\n\n// V9\nAVSC_API(int, avs_is_property_writable)(const AVS_VideoFrame* p);\n\nAVSC_API(BYTE *, avs_get_write_ptr_p)(const AVS_VideoFrame * p, int plane);\n\nAVSC_API(void, avs_release_video_frame)(AVS_VideoFrame *);\n// makes a shallow copy of a video frame\nAVSC_API(AVS_VideoFrame *, avs_copy_video_frame)(AVS_VideoFrame *);\n\n// V10\nAVSC_API(int, avs_video_frame_get_pixel_type)(const AVS_VideoFrame* p);\n\nAVSC_API(void, avs_video_frame_amend_pixel_type)(AVS_VideoFrame* p, int new_pixel_type);\n\n#ifndef AVSC_NO_DECLSPEC\n#ifdef AVSC_ALLOW_DEPRECATED\n// Old inline helper functions which are named differently but eventually call API.\n// Deprecated. If possible, do not use them any more\n// Get data for plane AVS_DEFAULT_PLANE (Y or packed rgb):\nAVSC_INLINE int avs_get_pitch(const AVS_VideoFrame * p) { return avs_get_pitch_p(p, AVS_DEFAULT_PLANE); }\nAVSC_INLINE int avs_get_row_size(const AVS_VideoFrame * p) { return avs_get_row_size_p(p, AVS_DEFAULT_PLANE); }\nAVSC_INLINE int avs_get_height(const AVS_VideoFrame * p) { return avs_get_height_p(p, AVS_DEFAULT_PLANE); }\nAVSC_INLINE const BYTE* avs_get_read_ptr(const AVS_VideoFrame * p) { return avs_get_read_ptr_p(p, AVS_DEFAULT_PLANE); }\nAVSC_INLINE BYTE* avs_get_write_ptr(const AVS_VideoFrame * p) { return avs_get_write_ptr_p(p, AVS_DEFAULT_PLANE); }\n// named alternatively:\nAVSC_INLINE void avs_release_frame(AVS_VideoFrame* f) { avs_release_video_frame(f); }\nAVSC_INLINE AVS_VideoFrame* avs_copy_frame(AVS_VideoFrame* f) { return avs_copy_video_frame(f); }\n#endif\n#endif\n\n// Interface V8: frame properties\n// AVS_Map is just a placeholder for AVSMap\ntypedef struct AVS_Map {\n  void* data;\n} AVS_Map;\n\n\n/////////////////////////////////////////////////////////////////////\n//\n// AVS_Value\n//\n\n// Treat AVS_Value as a fat pointer.  That is use avs_copy_value\n// and avs_release_value appropriately as you would if AVS_Value was\n// a pointer.\n\n// To maintain source code compatibility with future versions of the\n// avisynth_c API don't use the AVS_Value directly.  Use the helper\n// functions below.\n\n// AVS_Value is laid out identically to AVSValue\ntypedef struct AVS_Value AVS_Value;\nstruct AVS_Value {\n  short type;  // 'a'rray, 'c'lip, 'b'ool, 'i'nt, 'f'loat, 'd'ouble, 's'tring, 'v'oid, or 'l'ong, or fu'n'ction\n               // for some function 'e'rror\n  short array_size;\n  union {\n    void * clip; // do not use directly, use avs_take_clip\n    char boolean;\n    int integer;\n    float floating_pt;\n    const char * string;\n    const AVS_Value * array;\n    void * function; // not supported on C interface\n#if UINTPTR_MAX >= 0xffffffffffffffff\n    // if ever, only x64 will support. It breaks struct size on 32 bit\n    int64_t longlong; // 8 bytes\n    double double_pt; // 8 bytes\n#else\n    // 32 bit support workaround, pointers dont't break struct size on 32 bit\n    int64_t *longlong_ptr;\n    double *double_pt_ptr;\n#endif\n  } d;\n};\n\n// AVS_Value should be initialized with avs_void.\n// Should also set to avs_void after the value is released\n// with avs_copy_value.  Consider it the equivalent of setting\n// a pointer to NULL\nstatic const AVS_Value avs_void = {'v', 0, {0}};\n// see also avs_set_to_void v11 API\n\n/*******************************\n* AVS_Value copy through API\n*******************************/\n// requires avs_release_value! Can deep copy dyn_arrays.\nAVSC_API(void, avs_copy_value)(AVS_Value * dest, AVS_Value src);\n\n/*******************************\n* AVS_Value release through API\n*******************************/\nAVSC_API(void, avs_release_value)(AVS_Value);\n\n/*************************************************\n* AVS_Value -> AVS_Clip get reference through API\n*************************************************/\n// requires avs_release_clip!\nAVSC_API(AVS_Clip *, avs_take_clip)(AVS_Value, AVS_ScriptEnvironment *);\n\n/****************************************************************************\n* AVS_Value type testers avs_is_xxxx (\"baked\" inline code) - NOT through API\n****************************************************************************/\nAVSC_INLINE int avs_defined(AVS_Value v) { return v.type != 'v'; }\nAVSC_INLINE int avs_is_clip(AVS_Value v) { return v.type == 'c'; }\nAVSC_INLINE int avs_is_bool(AVS_Value v) { return v.type == 'b'; }\n// v11: changed: for 32-bit 'int' or 64-bit 'long' as well\nAVSC_INLINE int avs_is_int(AVS_Value v) { return v.type == 'i' || v.type == 'l'; }\n// v11: new: for strict 64-bit 'long' content only\nAVSC_INLINE int avs_is_long_strict(AVS_Value v) { return v.type == 'l'; }\n// v11: changed: for 'double' and 'l'ong along with 'float' and 'int'\nAVSC_INLINE int avs_is_float(AVS_Value v) { return v.type == 'd' || v.type == 'f' || v.type == 'i' || v.type == 'l'; }\n// v11: new: for strict 64-bit 'long' content only\nAVSC_INLINE int avs_is_floatf_strict(AVS_Value v) { return v.type == 'f'; }\nAVSC_INLINE int avs_is_string(AVS_Value v) { return v.type == 's'; }\nAVSC_INLINE int avs_is_array(AVS_Value v) { return v.type == 'a'; }\nAVSC_INLINE int avs_is_error(AVS_Value v) { return v.type == 'e'; }\n\n/****************************************************************************\n* AVS_Value type testers avs_val_is_xxxx (API)\n****************************************************************************/\nAVSC_API(int, avs_val_defined)(AVS_Value v);\nAVSC_API(int, avs_val_is_clip)(AVS_Value v);\nAVSC_API(int, avs_val_is_bool)(AVS_Value v);\n// v11: changed: for 32-bit 'int' or 64-bit 'long' as well\nAVSC_API(int, avs_val_is_int)(AVS_Value v);\n// v11: new: for strict 64-bit 'long' content only\nAVSC_API(int, avs_val_is_long_strict)(AVS_Value v);\n// v11: changed: for 'double' and 'l'ong along with 'float' and 'int'\nAVSC_API(int, avs_val_is_float)(AVS_Value v);\n// v11: new: for strict 32-bit 'float' content only\nAVSC_API(int, avs_val_is_floatf_strict)(AVS_Value v);\nAVSC_API(int, avs_val_is_string)(AVS_Value v);\nAVSC_API(int, avs_val_is_array)(AVS_Value v);\nAVSC_API(int, avs_val_is_error)(AVS_Value v);\n\n/***********************************************************\n* AVS_Value getters (\"baked\" inline code) - NOT through API\n***********************************************************/\nAVSC_INLINE int avs_as_bool(AVS_Value v) { return v.d.boolean; }\n// v11: avs_as_int also valid for 64-bit 'l'ong, but it gets truncated\nAVSC_INLINE int avs_as_int(AVS_Value v)\n{\n  // we'll return a casted int64_t as-is\n#if UINTPTR_MAX >= 0xffffffffffffffff\n  return v.type == 'l' ? (int)v.d.longlong : v.d.integer;\n#else\n  return v.type == 'l' ? (int)*v.d.longlong_ptr : v.d.integer;\n#endif\n}\n// v11: new, returns true 64 bit value, even for 32 bit content\nAVSC_INLINE int64_t avs_as_long(AVS_Value v)\n{\n#if UINTPTR_MAX >= 0xffffffffffffffff\n  return v.type == 'l' ? v.d.longlong : v.d.integer;\n#else\n  return v.type == 'l' ? *v.d.longlong_ptr : v.d.integer;\n#endif\n}\nAVSC_INLINE const char * avs_as_string(AVS_Value v)\n        { return avs_is_error(v) || avs_is_string(v) ? v.d.string : 0; }\n\n// v11: Extended for 'double' and 'l'ong\nAVSC_INLINE double avs_as_float(AVS_Value v)\n{\n#if UINTPTR_MAX >= 0xffffffffffffffff\n  return v.type == 'i' ? v.d.integer : v.type=='l' ? v.d.longlong : v.type == 'd' ? v.d.double_pt : v.d.floating_pt;\n#else\n  return v.type == 'i' ? v.d.integer : v.type == 'l' ? *v.d.longlong_ptr : v.type == 'd' ? *v.d.double_pt_ptr : v.d.floating_pt;\n#endif\n}\nAVSC_INLINE const char * avs_as_error(AVS_Value v)\n        { return avs_is_error(v) ? v.d.string : 0; }\nAVSC_INLINE const AVS_Value * avs_as_array(AVS_Value v)\n        { return v.d.array; }\n\n/***********************************************************\n* AVS_Value getters - using API v11\n***********************************************************/\n// API versions of the above. The AVS_Value is passed by reference everywhere\nAVSC_API(int, avs_get_as_bool)(AVS_Value v);\nAVSC_API(AVS_Clip *, avs_get_as_clip)(AVS_Value v, AVS_ScriptEnvironment* env); // similar to avs_take_clip\nAVSC_API(int, avs_get_as_int)(AVS_Value v);\nAVSC_API(int64_t, avs_get_as_long)(AVS_Value v);\nAVSC_API(const char*, avs_get_as_string)(AVS_Value v);\nAVSC_API(double, avs_get_as_float)(AVS_Value v);\nAVSC_API(const char*, avs_get_as_error)(AVS_Value v);\nAVSC_API(const AVS_Value*, avs_get_as_array)(AVS_Value v);\n\n/***********************************************************\n* AVS_Value array access - using API v11\n***********************************************************/\nAVSC_API(AVS_Value, avs_get_array_elt)(AVS_Value v, int index);\nAVSC_API(int, avs_get_array_size)(AVS_Value v);\n\n/***********************************************************\n* AVS_Value array access - (\"baked\" inline code) - NOT through API\n***********************************************************/\nAVSC_INLINE int avs_array_size(AVS_Value v)\n        { return avs_is_array(v) ? v.array_size : 1; }\nAVSC_INLINE AVS_Value avs_array_elt(AVS_Value v, int index)\n        { return avs_is_array(v) ? v.d.array[index] : v; }\n\n/*******************************\n* AVS_Value setters through API\n*******************************/\nAVSC_API(void, avs_set_to_clip)(AVS_Value*, AVS_Clip*);\n// v11 provides setter APIs for all types beyond 'clip'\nAVSC_API(void, avs_set_to_error)(AVS_Value*, const char* v0);\nAVSC_API(void, avs_set_to_bool)(AVS_Value*, int v0);\nAVSC_API(void, avs_set_to_int)(AVS_Value*, int v0);\nAVSC_API(void, avs_set_to_float)(AVS_Value*, float v0);\nAVSC_API(void, avs_set_to_string)(AVS_Value*, const char* v0);\nAVSC_API(void, avs_set_to_double)(AVS_Value*, double d); // requires avs_release_value, especially on 32 bit proc\nAVSC_API(void, avs_set_to_long)(AVS_Value*, int64_t l); // requires avs_release_value, especially on 32 bit proc\nAVSC_API(void, avs_set_to_array)(AVS_Value*, AVS_Value* src, int size); // requires avs_release_value, multi-nested deep copied arrays\nAVSC_API(void, avs_set_to_void)(AVS_Value*); // void\n/***********************************************************\n* AVS_Value setters (\"baked\" inline code) - NOT through API\n***********************************************************/\n// Each of these inline 'baked code' setters has API counterparts:\n// avs_set_to_error, avs_set_to_bool, avs_set_to_int, avs_set_to_string, avs_set_to_float.\n// Only use these functions on an AVS_Value that does not already have\n// an active value.  Remember, treat AVS_Value as a fat pointer.\n// These do not require avs_release_value\nAVSC_INLINE AVS_Value avs_new_value_bool(int v0)\n        { AVS_Value v; v.type = 'b'; v.d.boolean = v0 == 0 ? 0 : 1; return v; }\nAVSC_INLINE AVS_Value avs_new_value_int(int v0)\n        { AVS_Value v; v.type = 'i'; v.d.integer = v0; return v; }\nAVSC_INLINE AVS_Value avs_new_value_string(const char * v0)\n        { AVS_Value v; v.type = 's'; v.d.string = v0; return v; }\nAVSC_INLINE AVS_Value avs_new_value_float(float v0)\n        { AVS_Value v; v.type = 'f'; v.d.floating_pt = v0; return v;}\nAVSC_INLINE AVS_Value avs_new_value_error(const char * v0)\n        { AVS_Value v; v.type = 'e'; v.d.string = v0; return v; }\nAVSC_INLINE AVS_Value avs_new_value_array(AVS_Value * v0, int size)\n        { AVS_Value v; v.type = 'a'; v.d.array = v0; v.array_size = (short)size; return v; }\n/***********************************************************\n* AVS_Value setters - inline wrappers using API\n***********************************************************/\n#ifndef AVSC_NO_DECLSPEC\n// Use avs_release_value / avs_copy_value\nAVSC_INLINE AVS_Value avs_new_value_clip(AVS_Clip* v0)\n        { AVS_Value v; avs_set_to_clip(&v, v0); return v; }\n#endif\n/***********************************************************\n* AVS_Value setters - inline wrappers using API v11\n* None of them. For Avisynth arrays, 64 bit long and double use API\n***********************************************************/\n// No avs_new_value_double => use avs_set_to_double API instead\n// No avs_new_value_long => use avs_set_to_long API instead\n// for arrays use avs_set_to_array API call for Avisynth deep smart arrays\n\n/////////////////////////////////////////////////////////////////////\n//\n// AVS_Clip\n//\n\nAVSC_API(void, avs_release_clip)(AVS_Clip *);\nAVSC_API(AVS_Clip *, avs_copy_clip)(AVS_Clip *);\n\nAVSC_API(const char *, avs_clip_get_error)(AVS_Clip *); // return 0 if no error\n\nAVSC_API(const AVS_VideoInfo *, avs_get_video_info)(AVS_Clip *);\n\nAVSC_API(int, avs_get_version)(AVS_Clip *);\n\nAVSC_API(AVS_VideoFrame *, avs_get_frame)(AVS_Clip *, int n);\n// The returned video frame must be released with avs_release_video_frame\n\nAVSC_API(int, avs_get_parity)(AVS_Clip *, int n);\n// return field parity if field_based, else parity of first field in frame\n\nAVSC_API(int, avs_get_audio)(AVS_Clip *, void * buf,\n                             int64_t start, int64_t count);\n// start and count are in samples\n\nAVSC_API(int, avs_set_cache_hints)(AVS_Clip *,\n                                   int cachehints, int frame_range);\n\n// This is the callback type used by avs_add_function\ntypedef AVS_Value (AVSC_CC * AVS_ApplyFunc)\n                        (AVS_ScriptEnvironment *, AVS_Value args, void * user_data);\n\n// v11 alternative of avs_add_function with return value by reference\n// This is the callback type used by avs_add_function_r\ntypedef void(AVSC_CC* AVS_ApplyFuncR)\n(AVS_ScriptEnvironment*, AVS_Value* ret, AVS_Value args, void* user_data);\n\ntypedef struct AVS_FilterInfo AVS_FilterInfo;\nstruct AVS_FilterInfo\n{\n  // these members should not be modified outside of the AVS_ApplyFunc or AVS_ApplyFuncR callback\n  AVS_Clip * child;\n  AVS_VideoInfo vi;\n  AVS_ScriptEnvironment * env;\n  AVS_VideoFrame * (AVSC_CC * get_frame)(AVS_FilterInfo *, int n);\n  int (AVSC_CC * get_parity)(AVS_FilterInfo *, int n);\n  int (AVSC_CC * get_audio)(AVS_FilterInfo *, void * buf,\n                                  int64_t start, int64_t count);\n  int (AVSC_CC * set_cache_hints)(AVS_FilterInfo *, int cachehints,\n                                        int frame_range);\n  void (AVSC_CC * free_filter)(AVS_FilterInfo *);\n\n  // Should be set when ever there is an error to report.\n  // It is cleared before any of the above methods are called\n  const char * error;\n  // this is to store whatever and may be modified at will\n  void * user_data;\n};\n\n// Create a new filter\n// 'fi' is set to point to the AVS_FilterInfo so that you can\n//   modify it once it is initialized.\n// 'store_child' should generally be set to true.  If it is not\n//   set then ALL methods (the function pointers) must be defined\n// If it is set then you do not need to worry about freeing the child\n//    clip.\nAVSC_API(AVS_Clip *, avs_new_c_filter)(AVS_ScriptEnvironment * e,\n                                       AVS_FilterInfo * * fi,\n                                       AVS_Value child, int store_child);\n\n/////////////////////////////////////////////////////////////////////\n//\n// AVS_ScriptEnvironment\n//\n\n// For GetCPUFlags.\n\n// Intel/AMD x86/x86-64 flags\n\n// start with enum, until we reach 32-bit limit\nenum {\n                                /* slowest CPU to support extension */\n  AVS_CPU_FORCE = 0x01,   // N/A\n  AVS_CPU_FPU = 0x02,   // 386/486DX\n  AVS_CPU_MMX = 0x04,   // P55C, K6, PII\n  AVS_CPU_INTEGER_SSE = 0x08,   // PIII, Athlon\n  AVS_CPU_SSE = 0x10,   // PIII, Athlon XP/MP\n  AVS_CPU_SSE2 = 0x20,   // PIV, Hammer\n  AVS_CPU_3DNOW = 0x40,   // K6-2\n  AVS_CPU_3DNOW_EXT = 0x80,   // Athlon\n  AVS_CPU_X86_64 = 0xA0,   // Hammer (note: equiv. to 3DNow + SSE2,\n                                 // which only Hammer will have anyway)\n  AVS_CPUF_SSE3 = 0x100,   //  PIV+, K8 Venice\n  AVS_CPUF_SSSE3 = 0x200,   //  Core 2\n  AVS_CPUF_SSE4 = 0x400,   //  Penryn, Wolfdale, Yorkfield\n  AVS_CPUF_SSE4_1 = 0x400,\n  AVS_CPUF_AVX = 0x800,   //  Sandy Bridge, Bulldozer\n  AVS_CPUF_SSE4_2 = 0x1000,   //  Nehalem\n  // AVS+\n  AVS_CPUF_AVX2 = 0x2000,   //  Haswell\n  AVS_CPUF_FMA3 = 0x4000,\n  AVS_CPUF_F16C = 0x8000,\n  AVS_CPUF_MOVBE = 0x10000,   // Big Endian Move\n  AVS_CPUF_POPCNT = 0x20000,\n  AVS_CPUF_AES = 0x40000,\n  AVS_CPUF_FMA4 = 0x80000,\n\n  // AVX-512\n  AVS_CPUF_AVX512F = 0x100000,    // F Foundation.\n  AVS_CPUF_AVX512DQ = 0x200000,    // DQ (Double/Quad granular) Instructions\n  AVS_CPUF_AVX512PF = 0x400000,    // PF Prefetch\n  AVS_CPUF_AVX512ER = 0x800000,    // ER Exponential and Reciprocal\n  AVS_CPUF_AVX512CD = 0x1000000,   // CD Conflict Detection\n  AVS_CPUF_AVX512BW = 0x2000000,   // BW (Byte/Word granular) Instructions\n  AVS_CPUF_AVX512VL = 0x4000000,   // VL (128/256 Vector Length) Extensions\n  AVS_CPUF_AVX512IFMA = 0x8000000,   // IFMA integer 52 bit\n  AVS_CPUF_AVX512VBMI = 0x10000000,  // VBMI, byte/word shuffling, sign/zero extension, and general pixel manipulation\n  // Group feature flags for convenience: checking a single flag for \"base\" and \"fast\" AVX512 feature sets.\n  AVS_CPUF_AVX512_BASE = 0x20000000,  // F, CD, BW, DQ, VL all set.\n  AVS_CPUF_AVX512_FAST = 0x40000000,   // Base + VNNI, VBMI, VBMI2, BITALG, VPOPCNTDQ. Spec detection logic excludes older/throttling models that also have these features.\n  // Last 32-bit flag reserved for future use:\n  // AVS_CPUF_AVX10    = 0x80000000LL; // AVX10 as one flag, version query needed in distinct function.\n\n  // The enum must stop here to remain compatible with a 32-bit int/enum.\n};\n\n// features beyond the initial 32 bits(0xFFFFFFFF) must be defined as 64 - bit constants\n// and can be returned only by avs_get_cpu_flags_ex (which returns int64_t)\n\n// Intel/AMD x86/x86-64 flags (Continued from 32-bit limit)\n#define AVS_CPUF_AVX512VNNI             0x00100000000LL\n#define AVS_CPUF_AVX512VBMI2            0x00200000000LL\n#define AVS_CPUF_AVX512BITALG           0x00400000000LL\n#define AVS_CPUF_AVX512VPOPCNTDQ        0x00800000000LL\n#define AVS_CPUF_AVX512FP16             0x01000000000LL\n#define AVS_CPUF_AVX512BF16             0x02000000000LL\n\n// ARMv8-A flags\nenum {\n  AVS_CPUF_ARM_NEON = 0x01,\n  AVS_CPUF_ARM_DOTPROD = 0x02,\n  AVS_CPUF_ARM_SVE2 = 0x04,\n  AVS_CPUF_ARM_I8MM = 0x08,\n  AVS_CPUF_ARM_SVE2_1 = 0x10,\n};\n\n\nAVSC_API(const char *, avs_get_error)(AVS_ScriptEnvironment *); // return 0 if no error\n\nAVSC_API(int, avs_get_cpu_flags)(AVS_ScriptEnvironment *);\nAVSC_API(int64_t, avs_get_cpu_flags_ex)(AVS_ScriptEnvironment *); // V12\nAVSC_API(int, avs_check_version)(AVS_ScriptEnvironment *, int version);\n\nAVSC_API(char *, avs_save_string)(AVS_ScriptEnvironment *, const char* s, int length);\nAVSC_API(char *, avs_sprintf)(AVS_ScriptEnvironment *, const char * fmt, ...);\n\nAVSC_API(char *, avs_vsprintf)(AVS_ScriptEnvironment *, const char * fmt, va_list val);\n\n// avs_add_function, the callback (apply) returns result as return value (AVS_Value)\nAVSC_API(int, avs_add_function)(AVS_ScriptEnvironment *,\n                                const char * name, const char * params,\n                                AVS_ApplyFunc apply, void * user_data);\n\n// v11 avs_add_function_r, the callback (apply) returns result in byref parameter (AVS_Value *)\nAVSC_API(int, avs_add_function_r)(AVS_ScriptEnvironment*,\n  const char* name, const char* params,\n  AVS_ApplyFuncR apply, void* user_data);\n\nAVSC_API(int, avs_function_exists)(AVS_ScriptEnvironment *, const char * name);\n\nAVSC_API(AVS_Value, avs_invoke)(AVS_ScriptEnvironment *, const char * name,\n                               AVS_Value args, const char** arg_names);\n// The returned value must be be released with avs_release_value\n\nAVSC_API(AVS_Value, avs_get_var)(AVS_ScriptEnvironment *, const char* name);\n// The returned value must be be released with avs_release_value\n\nAVSC_API(int, avs_set_var)(AVS_ScriptEnvironment *, const char* name, AVS_Value val);\n\nAVSC_API(int, avs_set_global_var)(AVS_ScriptEnvironment *, const char* name, const AVS_Value val);\n\n//void avs_push_context(AVS_ScriptEnvironment *, int level=0);\n//void avs_pop_context(AVS_ScriptEnvironment *);\n\n// partially deprecated, from V8 use avs_new_video_frame_p_a (frame property copy)\nAVSC_API(AVS_VideoFrame *, avs_new_video_frame_a)(AVS_ScriptEnvironment *,\n                                          const AVS_VideoInfo * vi, int align);\n// align should be at least 16 for classic Avisynth\n// Avisynth+: any value, Avs+ ensures a minimum alignment if too small align is provided\n\n// no API for these, inline helper functions\n#ifndef AVSC_NO_DECLSPEC\n// partially deprecated, from V8 use avs_new_video_frame_p (frame property copy)\n// this inline function is calling an API function\nAVSC_INLINE AVS_VideoFrame * avs_new_video_frame(AVS_ScriptEnvironment * env,\n                                     const AVS_VideoInfo * vi)\n  {return avs_new_video_frame_a(env,vi,AVS_FRAME_ALIGN);}\n\n// an older compatibility alias\n// this inline function is calling an API function\nAVSC_INLINE AVS_VideoFrame * avs_new_frame(AVS_ScriptEnvironment * env,\n                               const AVS_VideoInfo * vi)\n  {return avs_new_video_frame_a(env,vi,AVS_FRAME_ALIGN);}\n#endif\n// end of inline helper functions\n\nAVSC_API(int, avs_make_writable)(AVS_ScriptEnvironment *, AVS_VideoFrame * * pvf);\n\n// V9\nAVSC_API(int, avs_make_property_writable)(AVS_ScriptEnvironment*, AVS_VideoFrame** pvf);\n\nAVSC_API(void, avs_bit_blt)(AVS_ScriptEnvironment *, BYTE* dstp, int dst_pitch, const BYTE* srcp, int src_pitch, int row_size, int height);\n\ntypedef void (AVSC_CC *AVS_ShutdownFunc)(void* user_data, AVS_ScriptEnvironment * env);\nAVSC_API(void, avs_at_exit)(AVS_ScriptEnvironment *, AVS_ShutdownFunc function, void * user_data);\n\nAVSC_API(AVS_VideoFrame *, avs_subframe)(AVS_ScriptEnvironment *, AVS_VideoFrame * src, int rel_offset, int new_pitch, int new_row_size, int new_height);\n// The returned video frame must be be released\nAVSC_API(AVS_VideoFrame*, avs_subframe_planar)(AVS_ScriptEnvironment*, AVS_VideoFrame* src, int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV);\n// The returned video frame must be be released\n// see also avs_subframe_planar_a in interface V8\n\nAVSC_API(int, avs_set_memory_max)(AVS_ScriptEnvironment *, int mem);\n\nAVSC_API(int, avs_set_working_dir)(AVS_ScriptEnvironment *, const char * newdir);\n\n// V12\n// Acquire a global named lock.\n// 'env' is the environment handle, 'name' is the lock identifier (e.g., \"fftw\").\n// Returns 1 on success, 0 on failure.\nAVSC_API(int, avs_acquire_global_lock)(AVS_ScriptEnvironment *, const char* name);\n// V12\n// Release a global named lock.\n// 'env' is the environment handle, 'name' is the lock identifier.\nAVSC_API(void, avs_release_global_lock)(AVS_ScriptEnvironment *, const char* name);\n\n// avisynth.dll exports this; it's a way to use it as a library, without\n// writing an AVS script or without going through AVIFile.\nAVSC_API(AVS_ScriptEnvironment *, avs_create_script_environment)(int version);\n\n// This symbol serves as the entry point for the plugin (up to Avisynth 3.7.3, non-64-bit aware)\nAVSC_EXPORT\nconst char* AVSC_CC avisynth_c_plugin_init(AVS_ScriptEnvironment* env);\n\n// This symbol serves as the entry point for the 64-bit aware plugin. Since V11\nAVSC_EXPORT\nconst char* AVSC_CC avisynth_c_plugin_init2(AVS_ScriptEnvironment* env);\n\n// Either one or both must be defined for a plugin\n// avisynth_c_plugin_init2 is checked before avisynth_c_plugin_init\n\nAVSC_API(void, avs_delete_script_environment)(AVS_ScriptEnvironment *);\n\n///////////////////////////////////////////////////////////////////////////////\n//\n// Avisynth+ V8 interface elements\n//\n\nAVSC_API(AVS_VideoFrame*, avs_subframe_planar_a)(AVS_ScriptEnvironment*, AVS_VideoFrame* src, int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV, int rel_offsetA);\n// The returned video frame must be be released\n\nAVSC_API(void, avs_copy_frame_props)(AVS_ScriptEnvironment* p, const AVS_VideoFrame* src, AVS_VideoFrame* dst);\nAVSC_API(const AVS_Map*, avs_get_frame_props_ro)(AVS_ScriptEnvironment* p, const AVS_VideoFrame* frame);\nAVSC_API(AVS_Map*, avs_get_frame_props_rw)(AVS_ScriptEnvironment* p, AVS_VideoFrame* frame);\nAVSC_API(int, avs_prop_num_keys)(AVS_ScriptEnvironment* p, const AVS_Map* map);\nAVSC_API(const char*, avs_prop_get_key)(AVS_ScriptEnvironment* p, const AVS_Map* map, int index);\nAVSC_API(int, avs_prop_num_elements)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key);\n\n// see AVS_PROPTYPE_... enums\nAVSC_API(char, avs_prop_get_type)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key);\n\n// see AVS_GETPROPERROR_... enums\nAVSC_API(int64_t, avs_prop_get_int)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error);\nAVSC_API(double, avs_prop_get_float)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error);\n// Note: avs_prop_get_data was fixed in interface V9.1\nAVSC_API(const char*, avs_prop_get_data)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error);\nAVSC_API(int, avs_prop_get_data_size)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error);\n// V11\nAVSC_API(int, avs_prop_get_data_type_hint)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error);\nAVSC_API(AVS_Clip*, avs_prop_get_clip)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error);\nAVSC_API(const AVS_VideoFrame*, avs_prop_get_frame)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error);\n// V11\nAVSC_API(int, avs_prop_get_int_saturated)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error);\n// V11\nAVSC_API(float, avs_prop_get_float_saturated)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int index, int* error);\n\nAVSC_API(int, avs_prop_delete_key)(AVS_ScriptEnvironment* p, AVS_Map* map, const char* key);\n\n// see AVS_PROPAPPENDMODE_... enums\nAVSC_API(int, avs_prop_set_int)(AVS_ScriptEnvironment* p, AVS_Map* map, const char* key, int64_t i, int append);\nAVSC_API(int, avs_prop_set_float)(AVS_ScriptEnvironment* p, AVS_Map* map, const char* key, double d, int append);\nAVSC_API(int, avs_prop_set_data)(AVS_ScriptEnvironment* p, AVS_Map* map, const char* key, const char* d, int length, int append);\n// v11\n// SEE AVS_PROPDATATYPEHINT_... enums\nAVSC_API(int, avs_prop_set_data_h)(AVS_ScriptEnvironment* p, AVS_Map* map, const char* key, const char* d, int length, int type, int append);\nAVSC_API(int, avs_prop_set_clip)(AVS_ScriptEnvironment* p, AVS_Map* map, const char* key, AVS_Clip* clip, int append);\nAVSC_API(int, avs_prop_set_frame)(AVS_ScriptEnvironment* p, AVS_Map* map, const char* key, const AVS_VideoFrame* frame, int append);\n\nAVSC_API(const int64_t*, avs_prop_get_int_array)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int* error);\nAVSC_API(const double*, avs_prop_get_float_array)(AVS_ScriptEnvironment* p, const AVS_Map* map, const char* key, int* error);\nAVSC_API(int, avs_prop_set_int_array)(AVS_ScriptEnvironment* p, AVS_Map* map, const char* key, const int64_t* i, int size);\nAVSC_API(int, avs_prop_set_float_array)(AVS_ScriptEnvironment* p, AVS_Map* map, const char* key, const double* d, int size);\n\nAVSC_API(void, avs_clear_map)(AVS_ScriptEnvironment* p, AVS_Map* map);\n\n// with frame property source\nAVSC_API(AVS_VideoFrame*, avs_new_video_frame_p)(AVS_ScriptEnvironment*,\n  const AVS_VideoInfo* vi, const AVS_VideoFrame* prop_src);\n\n// with frame property source\nAVSC_API(AVS_VideoFrame*, avs_new_video_frame_p_a)(AVS_ScriptEnvironment*,\n  const AVS_VideoInfo* vi, const AVS_VideoFrame* prop_src, int align);\n\n// Generic query to ask for various system properties, see AVS_AEP_xxx enums\nAVSC_API(size_t, avs_get_env_property)(AVS_ScriptEnvironment*, int avs_aep_prop);\n\n// buffer pool, see AVS_ALLOCTYPE enums\nAVSC_API(void *, avs_pool_allocate)(AVS_ScriptEnvironment*, size_t nBytes, size_t alignment, int avs_alloc_type);\nAVSC_API(void, avs_pool_free)(AVS_ScriptEnvironment*, void *ptr);\n\n// Interface V8\n// Returns TRUE (1) and the requested variable. If the method fails, returns 0 (FALSE) and does not touch 'val'.\n// The returned AVS_Value *val value must be be released with avs_release_value only on success\n// AVS_Value *val is not caller allocated\nAVSC_API(int, avs_get_var_try)(AVS_ScriptEnvironment*, const char* name, AVS_Value* val);\n\n// Interface V8\n// Return the value of the requested variable.\n// If the variable was not found or had the wrong type,\n// return the supplied default value.\nAVSC_API(int, avs_get_var_bool)(AVS_ScriptEnvironment*, const char* name, int def);\nAVSC_API(int, avs_get_var_int)(AVS_ScriptEnvironment*, const char* name, int def);\nAVSC_API(double, avs_get_var_double)(AVS_ScriptEnvironment*, const char* name, double def);\nAVSC_API(const char*, avs_get_var_string)(AVS_ScriptEnvironment*, const char* name, const char* def);\nAVSC_API(int64_t, avs_get_var_long)(AVS_ScriptEnvironment*, const char* name, int64_t def);\n\n// This is an example of dynamically loading Avisynth function addresses\n// instead of statically linked library. (Windows API)\n// In general: define AVSC_NO_DECLSPEC for only API prototypes, then manually load and get\n// function addresses from avisynth.dll/libavisynth.so\n\n#if defined(AVS_WINDOWS)\n// The following stuff is only relevant for Windows DLL handling; Linux does it completely differently.\n#ifdef AVSC_NO_DECLSPEC\n// This part uses LoadLibrary and related functions to dynamically load Avisynth instead of declspec(dllimport)\n// When AVSC_NO_DECLSPEC is defined, you can use avs_load_library to populate API functions into a struct\n// AVSC_INLINE functions which call onto an API functions should be treated specially (todo)\n\n/*\n  The following functions needs to have been declared, probably from windows.h\n\n  void* malloc(size_t)\n  void free(void*);\n\n  HMODULE LoadLibraryA(const char*);\n  void* GetProcAddress(HMODULE, const char*);\n  FreeLibrary(HMODULE);\n*/\n\n#ifndef EXTERNAL_AVS_C_API_LOADER // If external loader is NOT active, then define these helpers\n\ntypedef struct AVS_Library AVS_Library;\n\n#define AVSC_DECLARE_FUNC(name) name##_func name\n\n// AVSC_DECLARE_FUNC helps keeping naming convention: type is xxxxx_func, function name is xxxxx\n// e.g. \"AVSC_DECLARE_FUNC(avs_add_function);\"\n// is a shortcut for \"avs_add_function_func avs_add_function;\"\n\n// Note: AVSC_INLINE functions, which call into API,\n// are guarded by #ifndef AVSC_NO_DECLSPEC.\n// They should call the appropriate library-> API entry.\n\nstruct AVS_Library {\n  HMODULE handle;\n\n  AVSC_DECLARE_FUNC(avs_add_function);\n  AVSC_DECLARE_FUNC(avs_at_exit);\n  AVSC_DECLARE_FUNC(avs_bit_blt);\n  AVSC_DECLARE_FUNC(avs_check_version);\n  AVSC_DECLARE_FUNC(avs_clip_get_error);\n  AVSC_DECLARE_FUNC(avs_copy_clip);\n  AVSC_DECLARE_FUNC(avs_copy_value);\n  AVSC_DECLARE_FUNC(avs_copy_video_frame);\n  AVSC_DECLARE_FUNC(avs_create_script_environment);\n  AVSC_DECLARE_FUNC(avs_delete_script_environment);\n  AVSC_DECLARE_FUNC(avs_function_exists);\n  AVSC_DECLARE_FUNC(avs_get_audio);\n  AVSC_DECLARE_FUNC(avs_get_cpu_flags);\n  AVSC_DECLARE_FUNC(avs_get_frame);\n  AVSC_DECLARE_FUNC(avs_get_parity);\n  AVSC_DECLARE_FUNC(avs_get_var);\n  AVSC_DECLARE_FUNC(avs_get_version);\n  AVSC_DECLARE_FUNC(avs_get_video_info);\n  AVSC_DECLARE_FUNC(avs_invoke);\n  AVSC_DECLARE_FUNC(avs_make_writable);\n  AVSC_DECLARE_FUNC(avs_new_c_filter);\n  AVSC_DECLARE_FUNC(avs_new_video_frame_a);\n  AVSC_DECLARE_FUNC(avs_release_clip);\n  AVSC_DECLARE_FUNC(avs_release_value);\n  AVSC_DECLARE_FUNC(avs_release_video_frame);\n  AVSC_DECLARE_FUNC(avs_save_string);\n  AVSC_DECLARE_FUNC(avs_set_cache_hints);\n  AVSC_DECLARE_FUNC(avs_set_global_var);\n  AVSC_DECLARE_FUNC(avs_set_memory_max);\n  AVSC_DECLARE_FUNC(avs_set_to_clip);\n  AVSC_DECLARE_FUNC(avs_set_var);\n  AVSC_DECLARE_FUNC(avs_set_working_dir);\n  AVSC_DECLARE_FUNC(avs_sprintf);\n  AVSC_DECLARE_FUNC(avs_subframe);\n  AVSC_DECLARE_FUNC(avs_subframe_planar);\n  AVSC_DECLARE_FUNC(avs_take_clip);\n  AVSC_DECLARE_FUNC(avs_vsprintf);\n\n  AVSC_DECLARE_FUNC(avs_get_error);\n  AVSC_DECLARE_FUNC(avs_is_yv24);\n  AVSC_DECLARE_FUNC(avs_is_yv16);\n  AVSC_DECLARE_FUNC(avs_is_yv12);\n  AVSC_DECLARE_FUNC(avs_is_yv411);\n  AVSC_DECLARE_FUNC(avs_is_y8);\n  AVSC_DECLARE_FUNC(avs_is_color_space);\n\n  AVSC_DECLARE_FUNC(avs_get_plane_width_subsampling);\n  AVSC_DECLARE_FUNC(avs_get_plane_height_subsampling);\n  AVSC_DECLARE_FUNC(avs_bits_per_pixel);\n  AVSC_DECLARE_FUNC(avs_bytes_from_pixels);\n  AVSC_DECLARE_FUNC(avs_row_size);\n  AVSC_DECLARE_FUNC(avs_bmp_size);\n  AVSC_DECLARE_FUNC(avs_get_pitch_p);\n  AVSC_DECLARE_FUNC(avs_get_row_size_p);\n  AVSC_DECLARE_FUNC(avs_get_height_p);\n  AVSC_DECLARE_FUNC(avs_get_read_ptr_p);\n  AVSC_DECLARE_FUNC(avs_is_writable);\n  AVSC_DECLARE_FUNC(avs_get_write_ptr_p);\n\n  // Avisynth+ specific\n  // Note: these functions are simulated/use fallback to existing functions\n  AVSC_DECLARE_FUNC(avs_is_rgb48);\n  AVSC_DECLARE_FUNC(avs_is_rgb64);\n  AVSC_DECLARE_FUNC(avs_is_yuv444p16);\n  AVSC_DECLARE_FUNC(avs_is_yuv422p16);\n  AVSC_DECLARE_FUNC(avs_is_yuv420p16);\n  AVSC_DECLARE_FUNC(avs_is_y16);\n  AVSC_DECLARE_FUNC(avs_is_yuv444ps);\n  AVSC_DECLARE_FUNC(avs_is_yuv422ps);\n  AVSC_DECLARE_FUNC(avs_is_yuv420ps);\n  AVSC_DECLARE_FUNC(avs_is_y32);\n  AVSC_DECLARE_FUNC(avs_is_444);\n  AVSC_DECLARE_FUNC(avs_is_422);\n  AVSC_DECLARE_FUNC(avs_is_420);\n  AVSC_DECLARE_FUNC(avs_is_y);\n  AVSC_DECLARE_FUNC(avs_is_yuva);\n  AVSC_DECLARE_FUNC(avs_is_planar_rgb);\n  AVSC_DECLARE_FUNC(avs_is_planar_rgba);\n  AVSC_DECLARE_FUNC(avs_num_components);\n  AVSC_DECLARE_FUNC(avs_component_size);\n  AVSC_DECLARE_FUNC(avs_bits_per_component);\n\n  ///////////////////////////////////////////////////////////////////////////////\n  // Avisynth+ new interface elements from interface version 8\n  // avs_subframe_planar with alpha support\n  AVSC_DECLARE_FUNC(avs_subframe_planar_a);\n\n  // frame properties\n  AVSC_DECLARE_FUNC(avs_copy_frame_props);\n  AVSC_DECLARE_FUNC(avs_get_frame_props_ro);\n  AVSC_DECLARE_FUNC(avs_get_frame_props_rw);\n  AVSC_DECLARE_FUNC(avs_prop_num_keys);\n  AVSC_DECLARE_FUNC(avs_prop_get_key);\n  AVSC_DECLARE_FUNC(avs_prop_num_elements);\n  AVSC_DECLARE_FUNC(avs_prop_get_type);\n  AVSC_DECLARE_FUNC(avs_prop_get_int);\n  AVSC_DECLARE_FUNC(avs_prop_get_float);\n  AVSC_DECLARE_FUNC(avs_prop_get_data);\n  AVSC_DECLARE_FUNC(avs_prop_get_data_size);\n  AVSC_DECLARE_FUNC(avs_prop_get_clip);\n  AVSC_DECLARE_FUNC(avs_prop_get_frame);\n  AVSC_DECLARE_FUNC(avs_prop_delete_key);\n  AVSC_DECLARE_FUNC(avs_prop_set_int);\n  AVSC_DECLARE_FUNC(avs_prop_set_float);\n  AVSC_DECLARE_FUNC(avs_prop_set_data);\n  AVSC_DECLARE_FUNC(avs_prop_set_clip);\n  AVSC_DECLARE_FUNC(avs_prop_set_frame);\n\n  AVSC_DECLARE_FUNC(avs_prop_get_int_array);\n  AVSC_DECLARE_FUNC(avs_prop_get_float_array);\n  AVSC_DECLARE_FUNC(avs_prop_set_int_array);\n  AVSC_DECLARE_FUNC(avs_prop_set_float_array);\n\n  AVSC_DECLARE_FUNC(avs_clear_map);\n\n  // NewVideoFrame with frame properties\n  AVSC_DECLARE_FUNC(avs_new_video_frame_p);\n  AVSC_DECLARE_FUNC(avs_new_video_frame_p_a);\n\n  AVSC_DECLARE_FUNC(avs_get_env_property);\n\n  AVSC_DECLARE_FUNC(avs_get_var_try);\n  AVSC_DECLARE_FUNC(avs_get_var_bool);\n  AVSC_DECLARE_FUNC(avs_get_var_int);\n  AVSC_DECLARE_FUNC(avs_get_var_double);\n  AVSC_DECLARE_FUNC(avs_get_var_string);\n  AVSC_DECLARE_FUNC(avs_get_var_long);\n\n  AVSC_DECLARE_FUNC(avs_pool_allocate);\n  AVSC_DECLARE_FUNC(avs_pool_free);\n\n  // V9\n  AVSC_DECLARE_FUNC(avs_is_property_writable);\n  AVSC_DECLARE_FUNC(avs_make_property_writable);\n\n  // V10\n  AVSC_DECLARE_FUNC(avs_video_frame_get_pixel_type);\n  AVSC_DECLARE_FUNC(avs_video_frame_amend_pixel_type);\n\n  AVSC_DECLARE_FUNC(avs_is_channel_mask_known);\n  AVSC_DECLARE_FUNC(avs_set_channel_mask);\n  AVSC_DECLARE_FUNC(avs_get_channel_mask);\n\n  // V11\n  // setters for all types (except clip, which have already existed)\n  AVSC_DECLARE_FUNC(avs_set_to_error);\n  AVSC_DECLARE_FUNC(avs_set_to_bool);\n  AVSC_DECLARE_FUNC(avs_set_to_int);\n  AVSC_DECLARE_FUNC(avs_set_to_string);\n  AVSC_DECLARE_FUNC(avs_set_to_float);\n  AVSC_DECLARE_FUNC(avs_set_to_long);\n  AVSC_DECLARE_FUNC(avs_set_to_double);\n  AVSC_DECLARE_FUNC(avs_set_to_array);\n  AVSC_DECLARE_FUNC(avs_set_to_void);\n  // getters for all basic types. note: avs_get_as_float returns double\n  AVSC_DECLARE_FUNC(avs_get_as_error);\n  AVSC_DECLARE_FUNC(avs_get_as_array);\n  AVSC_DECLARE_FUNC(avs_get_as_bool);\n  AVSC_DECLARE_FUNC(avs_get_as_clip);\n  AVSC_DECLARE_FUNC(avs_get_as_int);\n  AVSC_DECLARE_FUNC(avs_get_as_string);\n  AVSC_DECLARE_FUNC(avs_get_as_float);\n  AVSC_DECLARE_FUNC(avs_get_as_long);\n  AVSC_DECLARE_FUNC(avs_get_array_size);\n  AVSC_DECLARE_FUNC(avs_get_array_elt);\n  // frame props\n  AVSC_DECLARE_FUNC(avs_prop_get_int_saturated);\n  AVSC_DECLARE_FUNC(avs_prop_get_float_saturated);\n  AVSC_DECLARE_FUNC(avs_prop_get_data_type_hint);\n  AVSC_DECLARE_FUNC(avs_prop_set_data_h);\n  // alternative add_function returning data in byref AVS_Value\n  AVSC_DECLARE_FUNC(avs_add_function_r);\n  // API AVS_Value type checkers\n  AVSC_DECLARE_FUNC(avs_val_defined);\n  AVSC_DECLARE_FUNC(avs_val_is_clip);\n  AVSC_DECLARE_FUNC(avs_val_is_bool);\n  AVSC_DECLARE_FUNC(avs_val_is_int);\n  AVSC_DECLARE_FUNC(avs_val_is_long_strict);\n  AVSC_DECLARE_FUNC(avs_val_is_float);\n  AVSC_DECLARE_FUNC(avs_val_is_floatf_strict);\n  AVSC_DECLARE_FUNC(avs_val_is_string);\n  AVSC_DECLARE_FUNC(avs_val_is_array);\n  AVSC_DECLARE_FUNC(avs_val_is_error);\n  // V12\n  AVSC_DECLARE_FUNC(avs_acquire_global_lock);\n  AVSC_DECLARE_FUNC(avs_release_global_lock);\n  AVSC_DECLARE_FUNC(avs_get_cpu_flags_ex);\n};\n\n#undef AVSC_DECLARE_FUNC\n\n#ifdef AVS26_FALLBACK_SIMULATION\n// Helper functions for fallback simulation\n// Avisynth+ extensions do not exist in classic Avisynth so they are simulated\nAVSC_INLINE int avs_is_xx_fallback_return_false(const AVS_VideoInfo * p)\n{\n  return 0;\n}\n\n// Avisynth+ extensions do not exist in classic Avisynth so they are simulated\nAVSC_INLINE int avs_num_components_fallback(const AVS_VideoInfo * p)\n{\n  switch (p->pixel_type) {\n  case AVS_CS_UNKNOWN:\n    return 0;\n  case AVS_CS_RAW32:\n  case AVS_CS_Y8:\n    return 1;\n  case AVS_CS_BGR32:\n    return 4; // not planar but return the count\n  default:\n    return 3;\n  }\n}\n\n// Avisynth+ extensions do not exist in classic Avisynth so they are simulated\nAVSC_INLINE int avs_component_size_fallback(const AVS_VideoInfo * p)\n{\n  return 1;\n}\n\n// Avisynth+ extensions do not exist in classic Avisynth so they are simulated\nAVSC_INLINE int avs_bits_per_component_fallback(const AVS_VideoInfo * p)\n{\n  return 8;\n}\n// End of helper functions for fallback simulation\n#endif // AVS26_FALLBACK_SIMULATION\n\n// avs_load_library() allocates an array for API procedure entries\n// reads and fills the entries with live procedure addresses.\n// AVSC_INLINE helpers which are calling into API procedures are not treated here (todo)\n\nAVSC_INLINE AVS_Library * avs_load_library() {\n  AVS_Library *library = (AVS_Library *)malloc(sizeof(AVS_Library));\n  if (library == NULL)\n    return NULL;\n  library->handle = LoadLibraryA(\"avisynth\");\n  if (library->handle == NULL)\n    goto fail;\n\n#define __AVSC_STRINGIFY(x) #x\n#define AVSC_STRINGIFY(x) __AVSC_STRINGIFY(x)\n#define AVSC_DO_LOAD_FUNC(name, allow_missing) {\\\n  library->name = (name##_func) GetProcAddress(library->handle, AVSC_STRINGIFY(name));\\\n  if (!allow_missing && library->name == NULL)\\\n    goto fail;\\\n}\n#define AVSC_LOAD_FUNC(name) AVSC_DO_LOAD_FUNC(name, 0)\n#define AVSC_LOAD_FUNC_OPT(name) AVSC_DO_LOAD_FUNC(name, 1)\n\n#ifdef AVS26_FALLBACK_SIMULATION\n// When an API function is not loadable, let's try a replacement\n// Missing Avisynth+ functions will be substituted with classic Avisynth compatible methods\n/*\nAvisynth+                 When method is missing (classic Avisynth)\navs_is_rgb48              constant false\navs_is_rgb64              constant false\navs_is_444                avs_is_yv24\navs_is_422                avs_is_yv16\navs_is_420                avs_is_yv12\navs_is_y                  avs_is_y8\navs_is_yuva               constant false\navs_is_planar_rgb         constant false\navs_is_planar_rgba        constant false\navs_num_components        special: avs_num_components_fake Y8:1 RGB32:4 else 3\navs_component_size        constant 1 (1 bytes/component)\navs_bits_per_component    constant 8 (8 bits/component)\n*/\n\n  // try to load an alternative function\n#define AVSC_LOAD_FUNC_FALLBACK(name,name2) {\\\n  library->name = (name##_func) GetProcAddress(library->handle, AVSC_STRINGIFY(name));\\\n  if (library->name == NULL)\\\n    library->name = (name##_func) GetProcAddress(library->handle, AVSC_STRINGIFY(name2));\\\n  if (library->name == NULL)\\\n    goto fail;\\\n}\n\n  // try to assign a replacement function\n#define AVSC_LOAD_FUNC_FALLBACK_SIMULATED(name,name2) {\\\n  library->name = (name##_func) GetProcAddress(library->handle, AVSC_STRINGIFY(name));\\\n  if (library->name == NULL)\\\n    library->name = name2;\\\n  if (library->name == NULL)\\\n    goto fail;\\\n}\n#endif // AVS26_FALLBACK_SIMULATION\n\n  AVSC_LOAD_FUNC(avs_add_function);\n  AVSC_LOAD_FUNC(avs_at_exit);\n  AVSC_LOAD_FUNC(avs_bit_blt);\n  AVSC_LOAD_FUNC(avs_check_version);\n  AVSC_LOAD_FUNC(avs_clip_get_error);\n  AVSC_LOAD_FUNC(avs_copy_clip);\n  AVSC_LOAD_FUNC(avs_copy_value);\n  AVSC_LOAD_FUNC(avs_copy_video_frame);\n  AVSC_LOAD_FUNC(avs_create_script_environment);\n  AVSC_LOAD_FUNC(avs_delete_script_environment);\n  AVSC_LOAD_FUNC(avs_function_exists);\n  AVSC_LOAD_FUNC(avs_get_audio);\n  AVSC_LOAD_FUNC(avs_get_cpu_flags);\n  AVSC_LOAD_FUNC(avs_get_frame);\n  AVSC_LOAD_FUNC(avs_get_parity);\n  AVSC_LOAD_FUNC(avs_get_var);\n  AVSC_LOAD_FUNC(avs_get_version);\n  AVSC_LOAD_FUNC(avs_get_video_info);\n  AVSC_LOAD_FUNC(avs_invoke);\n  AVSC_LOAD_FUNC(avs_make_writable);\n  AVSC_LOAD_FUNC(avs_new_c_filter);\n  AVSC_LOAD_FUNC(avs_new_video_frame_a);\n\n  AVSC_LOAD_FUNC(avs_release_clip);\n  AVSC_LOAD_FUNC(avs_release_value);\n  AVSC_LOAD_FUNC(avs_release_video_frame);\n  AVSC_LOAD_FUNC(avs_save_string);\n  AVSC_LOAD_FUNC(avs_set_cache_hints);\n  AVSC_LOAD_FUNC(avs_set_global_var);\n  AVSC_LOAD_FUNC(avs_set_memory_max);\n  AVSC_LOAD_FUNC(avs_set_to_clip);\n  AVSC_LOAD_FUNC(avs_set_var);\n  AVSC_LOAD_FUNC(avs_set_working_dir);\n  AVSC_LOAD_FUNC(avs_sprintf);\n  AVSC_LOAD_FUNC(avs_subframe);\n  AVSC_LOAD_FUNC(avs_subframe_planar);\n  AVSC_LOAD_FUNC(avs_take_clip);\n  AVSC_LOAD_FUNC(avs_vsprintf);\n\n  AVSC_LOAD_FUNC(avs_get_error);\n  AVSC_LOAD_FUNC(avs_is_yv24);\n  AVSC_LOAD_FUNC(avs_is_yv16);\n  AVSC_LOAD_FUNC(avs_is_yv12);\n  AVSC_LOAD_FUNC(avs_is_yv411);\n  AVSC_LOAD_FUNC(avs_is_y8);\n  AVSC_LOAD_FUNC(avs_is_color_space);\n\n  AVSC_LOAD_FUNC(avs_get_plane_width_subsampling);\n  AVSC_LOAD_FUNC(avs_get_plane_height_subsampling);\n  AVSC_LOAD_FUNC(avs_bits_per_pixel);\n  AVSC_LOAD_FUNC(avs_bytes_from_pixels);\n  AVSC_LOAD_FUNC(avs_row_size);\n  AVSC_LOAD_FUNC(avs_bmp_size);\n  AVSC_LOAD_FUNC(avs_get_pitch_p);\n  AVSC_LOAD_FUNC(avs_get_row_size_p);\n  AVSC_LOAD_FUNC(avs_get_height_p);\n  AVSC_LOAD_FUNC(avs_get_read_ptr_p);\n  AVSC_LOAD_FUNC(avs_is_writable);\n  AVSC_LOAD_FUNC(avs_get_write_ptr_p);\n\n  // Avisynth+ specific\n#ifdef AVS26_FALLBACK_SIMULATION\n  // replace with fallback fn when does not exist\n  AVSC_LOAD_FUNC_FALLBACK_SIMULATED(avs_is_rgb48, avs_is_xx_fallback_return_false);\n  AVSC_LOAD_FUNC_FALLBACK_SIMULATED(avs_is_rgb64, avs_is_xx_fallback_return_false);\n  AVSC_LOAD_FUNC_FALLBACK(avs_is_444, avs_is_yv24);\n  AVSC_LOAD_FUNC_FALLBACK(avs_is_422, avs_is_yv16);\n  AVSC_LOAD_FUNC_FALLBACK(avs_is_420, avs_is_yv12);\n  AVSC_LOAD_FUNC_FALLBACK(avs_is_y, avs_is_y8);\n  AVSC_LOAD_FUNC_FALLBACK_SIMULATED(avs_is_yuva, avs_is_xx_fallback_return_false);\n  AVSC_LOAD_FUNC_FALLBACK_SIMULATED(avs_is_planar_rgb, avs_is_xx_fallback_return_false);\n  AVSC_LOAD_FUNC_FALLBACK_SIMULATED(avs_is_planar_rgba, avs_is_xx_fallback_return_false);\n  AVSC_LOAD_FUNC_FALLBACK_SIMULATED(avs_num_components, avs_num_components_fallback);\n  AVSC_LOAD_FUNC_FALLBACK_SIMULATED(avs_component_size, avs_component_size_fallback);\n  AVSC_LOAD_FUNC_FALLBACK_SIMULATED(avs_bits_per_component, avs_bits_per_component_fallback);\n#else\n  // Avisynth+ specific\n  AVSC_LOAD_FUNC_OPT(avs_is_rgb48);\n  AVSC_LOAD_FUNC_OPT(avs_is_rgb64);\n  AVSC_LOAD_FUNC_OPT(avs_is_444);\n  AVSC_LOAD_FUNC_OPT(avs_is_422);\n  AVSC_LOAD_FUNC_OPT(avs_is_420);\n  AVSC_LOAD_FUNC_OPT(avs_is_y);\n  AVSC_LOAD_FUNC_OPT(avs_is_yuva);\n  AVSC_LOAD_FUNC_OPT(avs_is_planar_rgb);\n  AVSC_LOAD_FUNC_OPT(avs_is_planar_rgba);\n  AVSC_LOAD_FUNC_OPT(avs_num_components);\n  AVSC_LOAD_FUNC_OPT(avs_component_size);\n  AVSC_LOAD_FUNC_OPT(avs_bits_per_component);\n#endif\n  // Avisynth+ interface V8, no backward compatible simulation\n  AVSC_LOAD_FUNC_OPT(avs_subframe_planar_a);\n  // frame properties\n  AVSC_LOAD_FUNC_OPT(avs_copy_frame_props);\n  AVSC_LOAD_FUNC_OPT(avs_get_frame_props_ro);\n  AVSC_LOAD_FUNC_OPT(avs_get_frame_props_rw);\n  AVSC_LOAD_FUNC_OPT(avs_prop_num_keys);\n  AVSC_LOAD_FUNC_OPT(avs_prop_get_key);\n  AVSC_LOAD_FUNC_OPT(avs_prop_num_elements);\n  AVSC_LOAD_FUNC_OPT(avs_prop_get_type);\n  AVSC_LOAD_FUNC_OPT(avs_prop_get_int);\n  AVSC_LOAD_FUNC_OPT(avs_prop_get_float);\n  AVSC_LOAD_FUNC_OPT(avs_prop_get_data);\n  AVSC_LOAD_FUNC_OPT(avs_prop_get_data_size);\n  AVSC_LOAD_FUNC_OPT(avs_prop_get_clip);\n  AVSC_LOAD_FUNC_OPT(avs_prop_get_frame);\n  AVSC_LOAD_FUNC_OPT(avs_prop_delete_key);\n  AVSC_LOAD_FUNC_OPT(avs_prop_set_int);\n  AVSC_LOAD_FUNC_OPT(avs_prop_set_float);\n  AVSC_LOAD_FUNC_OPT(avs_prop_set_data);\n  AVSC_LOAD_FUNC_OPT(avs_prop_set_clip);\n  AVSC_LOAD_FUNC_OPT(avs_prop_set_frame);\n\n  AVSC_LOAD_FUNC_OPT(avs_prop_get_int_array);\n  AVSC_LOAD_FUNC_OPT(avs_prop_get_float_array);\n  AVSC_LOAD_FUNC_OPT(avs_prop_set_int_array);\n  AVSC_LOAD_FUNC_OPT(avs_prop_set_float_array);\n\n  AVSC_LOAD_FUNC_OPT(avs_clear_map);\n\n  // NewVideoFrame with frame properties\n  AVSC_LOAD_FUNC_OPT(avs_new_video_frame_p);\n  AVSC_LOAD_FUNC_OPT(avs_new_video_frame_p_a);\n\n  AVSC_LOAD_FUNC_OPT(avs_get_env_property);\n\n  AVSC_LOAD_FUNC_OPT(avs_get_var_try);\n  AVSC_LOAD_FUNC_OPT(avs_get_var_bool);\n  AVSC_LOAD_FUNC_OPT(avs_get_var_int);\n  AVSC_LOAD_FUNC_OPT(avs_get_var_double);\n  AVSC_LOAD_FUNC_OPT(avs_get_var_string);\n  AVSC_LOAD_FUNC_OPT(avs_get_var_long);\n\n  AVSC_LOAD_FUNC_OPT(avs_pool_allocate);\n  AVSC_LOAD_FUNC_OPT(avs_pool_free);\n\n  // V9\n  AVSC_LOAD_FUNC_OPT(avs_make_property_writable);\n  AVSC_LOAD_FUNC_OPT(avs_is_property_writable);\n\n  // V10\n  AVSC_LOAD_FUNC_OPT(avs_video_frame_get_pixel_type);\n  AVSC_LOAD_FUNC_OPT(avs_video_frame_amend_pixel_type);\n  AVSC_LOAD_FUNC_OPT(avs_is_channel_mask_known);\n  AVSC_LOAD_FUNC_OPT(avs_set_channel_mask);\n  AVSC_LOAD_FUNC_OPT(avs_get_channel_mask);\n\n  // V11\n  // setters for all types (avs_set_to_clip already existed)\n  AVSC_LOAD_FUNC_OPT(avs_set_to_error);\n  AVSC_LOAD_FUNC_OPT(avs_set_to_bool);\n  AVSC_LOAD_FUNC_OPT(avs_set_to_int);\n  AVSC_LOAD_FUNC_OPT(avs_set_to_string);\n  AVSC_LOAD_FUNC_OPT(avs_set_to_float);\n  AVSC_LOAD_FUNC_OPT(avs_set_to_long);\n  AVSC_LOAD_FUNC_OPT(avs_set_to_double);\n  AVSC_LOAD_FUNC_OPT(avs_set_to_array);\n  AVSC_LOAD_FUNC_OPT(avs_set_to_void);\n  // these have inline equivalents as well\n  AVSC_LOAD_FUNC_OPT(avs_get_as_error);\n  AVSC_LOAD_FUNC_OPT(avs_get_as_array);\n  AVSC_LOAD_FUNC_OPT(avs_get_as_bool);\n  AVSC_LOAD_FUNC_OPT(avs_get_as_clip);\n  AVSC_LOAD_FUNC_OPT(avs_get_as_int);\n  AVSC_LOAD_FUNC_OPT(avs_get_as_string);\n  AVSC_LOAD_FUNC_OPT(avs_get_as_float);\n  AVSC_LOAD_FUNC_OPT(avs_get_as_long);\n  AVSC_LOAD_FUNC_OPT(avs_get_array_size);\n  AVSC_LOAD_FUNC_OPT(avs_get_array_elt);\n  // frame property\n  AVSC_LOAD_FUNC_OPT(avs_prop_get_int_saturated);\n  AVSC_LOAD_FUNC_OPT(avs_prop_get_float_saturated);\n  AVSC_LOAD_FUNC_OPT(avs_prop_get_data_type_hint);\n  AVSC_LOAD_FUNC_OPT(avs_prop_set_data_h);\n  // alternative add_function\n  AVSC_LOAD_FUNC_OPT(avs_add_function_r);\n  // API AVS_Value type checkers\n  AVSC_LOAD_FUNC_OPT(avs_val_defined);\n  AVSC_LOAD_FUNC_OPT(avs_val_is_clip);\n  AVSC_LOAD_FUNC_OPT(avs_val_is_bool);\n  AVSC_LOAD_FUNC_OPT(avs_val_is_int);\n  AVSC_LOAD_FUNC_OPT(avs_val_is_long_strict);\n  AVSC_LOAD_FUNC_OPT(avs_val_is_float);\n  AVSC_LOAD_FUNC_OPT(avs_val_is_floatf_strict);\n  AVSC_LOAD_FUNC_OPT(avs_val_is_string);\n  AVSC_LOAD_FUNC_OPT(avs_val_is_array);\n  AVSC_LOAD_FUNC_OPT(avs_val_is_error);\n  // V12\n  AVSC_LOAD_FUNC_OPT(avs_acquire_global_lock);\n  AVSC_LOAD_FUNC_OPT(avs_release_global_lock);\n  AVSC_LOAD_FUNC_OPT(avs_get_cpu_flags_ex);\n\n#undef __AVSC_STRINGIFY\n#undef AVSC_STRINGIFY\n#undef AVSC_DO_LOAD_FUNC\n#undef AVSC_LOAD_FUNC\n#undef AVSC_LOAD_FUNC_OPT\n#undef AVSC_LOAD_FUNC_FALLBACK\n#undef AVSC_LOAD_FUNC_FALLBACK_SIMULATED\n\n  return library;\n\nfail:\n  free(library);\n  return NULL;\n}\n\nAVSC_INLINE void avs_free_library(AVS_Library *library) {\n  if (library == NULL)\n    return;\n  FreeLibrary(library->handle);\n  free(library);\n}\n\n#endif // EXTERNAL_AVS_C_API_LOADER\n\n#endif // AVSC_NO_DECLSPEC\n\n#endif // AVS_WINDOWS\n\n#endif\n"
  },
  {
    "path": "avs_core/include/avs/alignment.h",
    "content": "// Avisynth C Interface Version 0.20\n// Copyright 2003 Kevin Atkinson\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// As a special exception, I give you permission to link to the\n// Avisynth C interface with independent modules that communicate with\n// the Avisynth C interface solely through the interfaces defined in\n// avisynth_c.h, regardless of the license terms of these independent\n// modules, and to copy and distribute the resulting combined work\n// under terms of your choice, provided that every copy of the\n// combined work is accompanied by a complete copy of the source code\n// of the Avisynth C interface and Avisynth itself (with the version\n// used to produce the combined work), being distributed under the\n// terms of the GNU General Public License plus this exception.  An\n// independent module is a module which is not derived from or based\n// on Avisynth C Interface, such as 3rd-party filters, import and\n// export plugins, or graphical user interfaces.\n\n#ifndef AVS_ALIGNMENT_H\n#define AVS_ALIGNMENT_H\n\n// Functions and macros to help work with alignment requirements.\n\n// Tells if a number is a power of two.\n#define IS_POWER2(n) ((n) && !((n) & ((n) - 1)))\n\n// Tells if the pointer \"ptr\" is aligned to \"align\" bytes.\n#define IS_PTR_ALIGNED(ptr, align) (((uintptr_t)ptr & ((uintptr_t)(align-1))) == 0)\n\n// Rounds up the number \"n\" to the next greater multiple of \"align\"\n#define ALIGN_NUMBER(n, align) (((n) + (align)-1) & (~((align)-1)))\n\n// Rounds up the pointer address \"ptr\" to the next greater multiple of \"align\"\n#define ALIGN_POINTER(ptr, align) (((uintptr_t)(ptr) + (align)-1) & (~(uintptr_t)((align)-1)))\n\n#ifdef __cplusplus\n\n#include <cassert>\n#include <cstdlib>\n#include <cstdint>\n#include \"config.h\"\n\n#if defined(MSVC) && _MSC_VER<1400\n    // needed for VS2013, otherwise C++11 'alignas' works\n    #define avs_alignas(x) __declspec(align(x))\n#else\n    // assumes C++11 support\n    #define avs_alignas(x) alignas(x)\n#endif\n\ntemplate<typename T>\nstatic bool IsPtrAligned(T* ptr, size_t align)\n{\n  assert(IS_POWER2(align));\n  return (bool)IS_PTR_ALIGNED(ptr, align);\n}\n\ntemplate<typename T>\nstatic T AlignNumber(T n, T align)\n{\n  assert(IS_POWER2(align));\n  return ALIGN_NUMBER(n, align);\n}\n\ntemplate<typename T>\nstatic T* AlignPointer(T* ptr, size_t align)\n{\n  assert(IS_POWER2(align));\n  return (T*)ALIGN_POINTER(ptr, align);\n}\n\nextern \"C\"\n{\n#else\n#include <stdlib.h>\n#endif  // __cplusplus\n\n// Returns a new buffer that is at least the size \"nbytes\".\n// The buffer will be aligned to \"align\" bytes.\n// Returns NULL on error. On successful allocation,\n// the returned buffer must be freed using \"avs_free\".\ninline void* avs_malloc(size_t nbytes, size_t align)\n{\n  if (!IS_POWER2(align))\n    return NULL;\n\n  size_t offset = sizeof(void*) + align - 1;\n\n  void *orig = malloc(nbytes + offset);\n  if (orig == NULL)\n   return NULL;\n\n  void **aligned = (void**)(((uintptr_t)orig + (uintptr_t)offset) & (~(uintptr_t)(align-1)));\n  aligned[-1] = orig;\n  return aligned;\n}\n\n// Buffers allocated using \"avs_malloc\" must be freed\n// using \"avs_free\" instead of \"free\".\ninline void avs_free(void *ptr)\n{\n  // Mirroring free()'s semantic requires us to accept NULLs\n  if (ptr == NULL)\n    return;\n\n  free(((void**)ptr)[-1]);\n}\n\n#ifdef __cplusplus\n} // extern \"C\"\n\n// The point of these undef's is to force using the template functions\n// if we are in C++ mode. For C, the user can rely only on the macros.\n#undef IS_PTR_ALIGNED\n#undef ALIGN_NUMBER\n#undef ALIGN_POINTER\n\n#endif  // __cplusplus\n\n#endif  //AVS_ALIGNMENT_H\n"
  },
  {
    "path": "avs_core/include/avs/capi.h",
    "content": "// Avisynth C Interface Version 0.20\n// Copyright 2003 Kevin Atkinson\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// As a special exception, I give you permission to link to the\n// Avisynth C interface with independent modules that communicate with\n// the Avisynth C interface solely through the interfaces defined in\n// avisynth_c.h, regardless of the license terms of these independent\n// modules, and to copy and distribute the resulting combined work\n// under terms of your choice, provided that every copy of the\n// combined work is accompanied by a complete copy of the source code\n// of the Avisynth C interface and Avisynth itself (with the version\n// used to produce the combined work), being distributed under the\n// terms of the GNU General Public License plus this exception.  An\n// independent module is a module which is not derived from or based\n// on Avisynth C Interface, such as 3rd-party filters, import and\n// export plugins, or graphical user interfaces.\n\n#ifndef AVS_CAPI_H\n#define AVS_CAPI_H\n\n#include \"config.h\"\n\n#ifdef AVS_POSIX\n// this is also defined in avs/posix.h\n#ifndef AVS_HAIKU\n#define __declspec(x)\n#endif\n#endif\n\n#ifdef __cplusplus\n#  define AVS_EXTERN_C extern \"C\"\n#else\n#  define AVS_EXTERN_C\n#endif\n\n#ifdef AVS_WINDOWS\n#ifdef BUILDING_AVSCORE\n#  if defined(GCC) && defined(X86_32)\n#    define AVSC_CC\n#  else // MSVC builds and 64-bit GCC\n#    ifndef AVSC_USE_STDCALL\n#      define AVSC_CC __cdecl\n#    else\n#      define AVSC_CC __stdcall\n#    endif\n#  endif\n#else // needed for programs that talk to AviSynth+\n#  ifndef AVSC_WIN32_GCC32 // see comment below\n#    ifndef AVSC_USE_STDCALL\n#      define AVSC_CC __cdecl\n#    else\n#      define AVSC_CC __stdcall\n#    endif\n#  else\n#    define AVSC_CC\n#  endif\n#endif\n#  else\n#    define AVSC_CC\n#endif\n\n// On 64-bit Windows, there's only one calling convention,\n// so there is no difference between MSVC and GCC. On 32-bit,\n// this isn't true. The convention that GCC needs to use to\n// even build AviSynth+ as 32-bit makes anything that uses\n// it incompatible with 32-bit MSVC builds of AviSynth+.\n// The AVSC_WIN32_GCC32 define is meant to provide a user\n// switchable way to make builds of FFmpeg to test 32-bit\n// GCC builds of AviSynth+ without having to screw around\n// with alternate headers, while still default to the usual\n// situation of using 32-bit MSVC builds of AviSynth+.\n\n// Hopefully, this situation will eventually be resolved\n// and a broadly compatible solution will arise so the\n// same 32-bit FFmpeg build can handle either MSVC or GCC\n// builds of AviSynth+.\n\n#define AVSC_INLINE static __inline\n\n#ifdef BUILDING_AVSCORE\n#ifdef AVS_WINDOWS\n#  ifndef AVS_STATIC_LIB\n#    define AVSC_EXPORT __declspec(dllexport)\n#  else\n#    define AVSC_EXPORT\n#  endif\n#  define AVSC_API(ret, name) AVS_EXTERN_C AVSC_EXPORT ret AVSC_CC name\n#else\n#  define AVSC_EXPORT AVS_EXTERN_C\n#  define AVSC_API(ret, name) AVS_EXTERN_C ret AVSC_CC name\n#endif\n#else\n#  define AVSC_EXPORT AVS_EXTERN_C __declspec(dllexport)\n#  ifndef AVS_STATIC_LIB\n#    define AVSC_IMPORT __declspec(dllimport)\n#  else\n#    define AVSC_IMPORT\n#  endif\n#  ifndef AVSC_NO_DECLSPEC\n#    define AVSC_API(ret, name) AVS_EXTERN_C AVSC_IMPORT ret AVSC_CC name\n#  else\n#    define AVSC_API(ret, name) typedef ret (AVSC_CC *name##_func)\n#  endif\n#endif\n\n#endif //AVS_CAPI_H\n"
  },
  {
    "path": "avs_core/include/avs/config.h",
    "content": "// Avisynth C Interface Version 0.20\n// Copyright 2003 Kevin Atkinson\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// As a special exception, I give you permission to link to the\n// Avisynth C interface with independent modules that communicate with\n// the Avisynth C interface solely through the interfaces defined in\n// avisynth_c.h, regardless of the license terms of these independent\n// modules, and to copy and distribute the resulting combined work\n// under terms of your choice, provided that every copy of the\n// combined work is accompanied by a complete copy of the source code\n// of the Avisynth C interface and Avisynth itself (with the version\n// used to produce the combined work), being distributed under the\n// terms of the GNU General Public License plus this exception.  An\n// independent module is a module which is not derived from or based\n// on Avisynth C Interface, such as 3rd-party filters, import and\n// export plugins, or graphical user interfaces.\n\n#ifndef AVS_CONFIG_H\n#define AVS_CONFIG_H\n\n// Undefine this to get cdecl calling convention\n#define AVSC_USE_STDCALL 1\n\n// NOTE TO PLUGIN AUTHORS:\n// Because FRAME_ALIGN can be substantially higher than the alignment\n// a plugin actually needs, plugins should not use FRAME_ALIGN to check for\n// alignment. They should always request the exact alignment value they need.\n// This is to make sure that plugins work over the widest range of AviSynth\n// builds possible.\n#define FRAME_ALIGN 64\n\n#if   defined(_M_AMD64) || defined(__x86_64)\n#   define X86_64\n#elif defined(_M_IX86) || defined(__i386__)\n#   define X86_32\n#elif defined(_M_ARM64) || defined(__aarch64__)\n// _M_ARM64: MSVC; __aarch64__: GCC and Clang\n#   define ARM64\n#elif defined(_M_ARM) || defined(__arm__)\n#   define ARM32\n#elif defined(__PPC64__)\n#   define PPC64\n#elif defined(_M_PPC) || defined(__PPC__) || defined(__POWERPC__)\n#   define PPC32\n#elif defined(__riscv)\n#   define RISCV\n#elif defined(__loongarch__)\n#   define LOONGARCH\n#elif defined(__sparc_v9__)\n#   define SPARC\n#elif defined(__mips__)\n#   define MIPS\n#elif defined(__s390x__)\n#   define S390X\n#else\n#   error Unsupported CPU architecture.\n#endif\n\n//            VC++  LLVM-Clang-cl   MinGW-Gnu\n// MSVC        x          x\n// MSVC_PURE   x\n// CLANG                  x\n// GCC                                  x\n\n#if defined(__clang__)\n// Check clang first. clang-cl also defines __MSC_VER\n// We set MSVC because they are mostly compatible\n#   define CLANG\n#if defined(_MSC_VER)\n#   define MSVC\n#endif\n#   define AVS_FORCEINLINE __attribute__((always_inline)) inline\n#elif defined(_MSC_VER)\n#   define MSVC\n#   define MSVC_PURE\n#   define AVS_FORCEINLINE __forceinline\n#elif defined(__GNUC__)\n#   define GCC\n#   define AVS_FORCEINLINE __attribute__((always_inline)) inline\n#elif defined(__INTEL_COMPILER) || defined(__INTEL_LLVM_COMPILER)\n// Intel C++ Compilers with MSVC command line interface will not appear here rather at _MSC_VER\n#   define AVS_FORCEINLINE inline\n#   undef __forceinline\n#   define __forceinline inline\n#else\n#   error Unsupported compiler.\n#   define AVS_FORCEINLINE inline\n#   undef __forceinline\n#   define __forceinline inline\n#endif\n\n#if defined(_WIN32)\n#   define AVS_WINDOWS\n#elif defined(__linux__)\n#   define AVS_LINUX\n#   define AVS_POSIX\n#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)\n#   define AVS_BSD\n#   define AVS_POSIX\n#elif defined(__APPLE__)\n#   define AVS_MACOS\n#   define AVS_POSIX\n#elif defined(__HAIKU__)\n#   define AVS_HAIKU\n#   define AVS_POSIX\n#else\n#   error Operating system unsupported.\n#endif\n\n#if defined(AVS_WINDOWS)\n#  if defined(X86_32) || defined(X86_64)\n#    define AVS_WINDOWS_X86\n#  elif defined(ARM64) || defined(ARM32)\n#    define AVS_WINDOWS_ARM\n#  endif\n#endif\n\n#if defined(MSVC) && !defined(AVS_WINDOWS_X86) && !(defined(AVS_WINDOWS_ARM) && defined(ARM64))\n#    error Unsupported combination of compiler, operating system, and machine architecture.\n#endif\n\n/* A kinda portable definition of the C99 restrict keyword (or its unofficial C++ equivalent) */\n#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* Available in C99 */\n#define AVS_RESTRICT restrict\n#elif defined(__cplusplus) || defined(_MSC_VER) /* Almost all relevant C++ compilers support it so just assume it works */\n#define AVS_RESTRICT __restrict\n#else /* Not supported */\n#define AVS_RESTRICT\n#endif\n\n// useful warnings disabler macros for supported compilers\n\n#if defined(_MSC_VER)\n#define DISABLE_WARNING_PUSH           __pragma(warning( push ))\n#define DISABLE_WARNING_POP            __pragma(warning( pop ))\n#define DISABLE_WARNING(warningNumber) __pragma(warning( disable : warningNumber ))\n\n#define DISABLE_WARNING_UNREFERENCED_LOCAL_VARIABLE      DISABLE_WARNING(4101)\n#define DISABLE_WARNING_UNREFERENCED_FUNCTION            DISABLE_WARNING(4505)\n// other warnings you want to deactivate...\n\n#elif defined(__GNUC__) || defined(__clang__)\n#define DO_PRAGMA(X) _Pragma(#X)\n#define DISABLE_WARNING_PUSH           DO_PRAGMA(GCC diagnostic push)\n#define DISABLE_WARNING_POP            DO_PRAGMA(GCC diagnostic pop)\n#define DISABLE_WARNING(warningName)   DO_PRAGMA(GCC diagnostic ignored #warningName)\n\n#define DISABLE_WARNING_UNREFERENCED_LOCAL_VARIABLE      DISABLE_WARNING(-Wunused-variable)\n#define DISABLE_WARNING_UNREFERENCED_FUNCTION            DISABLE_WARNING(-Wunused-function)\n// other warnings you want to deactivate...\n\n#else\n#define DISABLE_WARNING_PUSH\n#define DISABLE_WARNING_POP\n#define DISABLE_WARNING_UNREFERENCED_LOCAL_VARIABLE\n#define DISABLE_WARNING_UNREFERENCED_FUNCTION\n// other warnings you want to deactivate...\n\n#endif\n\n#if defined(AVS_WINDOWS) && defined(_USING_V110_SDK71_)\n// Windows XP does not have proper initialization for\n// thread local variables.\n// Use workaround instead __declspec(thread)\n#define XP_TLS\n#endif\n\n#ifndef MSVC\n// GCC and Clang can be used on big endian systems, MSVC can't.\n#  if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__\n#    define AVS_ENDIANNESS \"little\"\n#  elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__\n#    define AVS_ENDIANNESS \"big\"\n#  else\n#    define AVS_ENDIANNESS \"middle\"\n#  endif\n#else\n#define AVS_ENDIANNESS \"little\"\n#endif\n\n#endif //AVS_CONFIG_H\n"
  },
  {
    "path": "avs_core/include/avs/cpuid.h",
    "content": "// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef AVSCORE_CPUID_H\n#define AVSCORE_CPUID_H\n\n#include <cstdint>\n#include <cstddef>\n\n// For GetCPUFlags/GetCPUFlagsEx.\n// These are backwards-compatible with those in VirtualDub ending with SSE4_2\n// For emulation see https://software.intel.com/en-us/articles/intel-software-development-emulator\n\n// enum changed to constexpr since we need 64-bit constants and enum types are limited to int size\n#ifndef AVS_CPU_FLAG_CONSTANT\n\n#if (defined(__cplusplus) && __cplusplus >= 201103L) || \\\n    (defined(_MSC_VER) && _MSC_VER >= 1700) // MSVC 2012+ supports basic constexpr\n    // Use constexpr for C++11 and later (resolves unused variable warnings)\n#define AVS_CPU_FLAG_CONSTANT constexpr\n#else\n    // Fallback to static const for pre-C++11 legacy compilers\n#define AVS_CPU_FLAG_CONSTANT static const\n#endif\n\n#endif // CPU_FLAG_CONSTANT\n\n// Intel/AMD x86/x86-64 flags\n\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_FORCE = 0x01;    // N/A\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_FPU = 0x02;    // 386/486DX\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_MMX = 0x04;    // P55C, K6, PII\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_INTEGER_SSE = 0x08;    // PIII, Athlon\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_SSE = 0x10;    // PIII, Athlon XP/MP\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_SSE2 = 0x20;    // PIV, K8\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_3DNOW = 0x40;    // K6-2\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_3DNOW_EXT = 0x80;    // Athlon\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_X86_64 = 0xA0;    // Hammer\n\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_SSE3 = 0x100;   // PIV+, K8 Venice\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_SSSE3 = 0x200;   // Core 2\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_SSE4 = 0x400;\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_SSE4_1 = 0x400;   // Penryn, Wolfdale, Yorkfield\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_AVX = 0x800;   // Sandy Bridge, Bulldozer\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_SSE4_2 = 0x1000;  // Nehalem\n\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_AVX2 = 0x2000;  // Haswell\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_FMA3 = 0x4000;\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_F16C = 0x8000;\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_MOVBE = 0x10000; // Big Endian move\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_POPCNT = 0x20000;\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_AES = 0x40000;\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_FMA4 = 0x80000;\n\n// AVX-512\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_AVX512F     = 0x00100000; // F Foundation.\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_AVX512DQ    = 0x00200000; // DQ (Double/Quad granular) Instructions\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_AVX512PF    = 0x00400000; // PF Prefetch\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_AVX512ER    = 0x00800000; // ER Exponential and Reciprocal\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_AVX512CD    = 0x01000000; // CD Conflict Detection\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_AVX512BW    = 0x02000000; // BW (Byte/Word granular) Instructions\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_AVX512VL    = 0x04000000; // VL (128/256 Vector Length) Extensions\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_AVX512IFMA  = 0x08000000; // IFMA integer 52 bit\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_AVX512VBMI  = 0x10000000; // VBMI, byte/word shuffling, sign/zero extension, and general pixel manipulation\n\n// Group feature flags for convenience: checking a single flag for \"base\" and \"fast\" AVX512 feature sets.\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_AVX512_BASE = 0x20000000; // F, CD, BW, DQ, VL all set.\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_AVX512_FAST = 0x40000000; // Base + VNNI, VBMI, VBMI2, BITALG, VPOPCNTDQ. Spec detection logic excludes older/throttling models that also have these features.\n\n// Last 32-bit flag reserved for future use:\n// AVS_CPU_FLAG_CONSTANT int64_t CPUF_AVX10       = 0x80000000LL; // AVX10 as one flag, version query needed in distinct function.\n\n// Flags exceeding the 32-bit limit (0xFFFFFFFF):\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_AVX512VNNI         = 0x00100000000LL; // VNNI, accumulated dot product on 8/16 bit integers\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_AVX512VBMI2        = 0x00200000000LL; // VBMI2: Byte/word load, store, & concatenation with shift for unaligned memory and packed data re-arrangement.\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_AVX512BITALG       = 0x00400000000LL; // BITALG, Bit Manipulation Instructions\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_AVX512VPOPCNTDQ    = 0x00800000000LL; // VPOPCNTDQ, Vector Population Count Double/Quadword\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_AVX512FP16         = 0x01000000000LL; // FP16, C++23 std::float16_t, S1E5M10, Limited range, higher precision (~3.3 decimal digits)\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_AVX512BF16         = 0x02000000000LL; // BF16, C++23 std::bfloat16_t, S1E8M7, Wide range (same as float); low precision (~2.3 decimal digits)\n\n// We intentionally don't pollute the flag space with AVX512 crypto (VAES, VPCLMULQDQ, GFNI) and deprecated (VP2INTERSECT, 4VNNIW, 4FMAPS) features\n\n// ARMv8-A flags (Values shared with X86 flags, usage guarded by platform macros)\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_ARM_NEON = 0x01; // NEON flag, minimum for aarch64\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_ARM_DOTPROD = 0x02; // Dot Product\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_ARM_SVE2 = 0x04; // SVE2\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_ARM_I8MM = 0x08; // I8MM\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_ARM_SVE2_1 = 0x10; // SVE2.1\n\n#ifdef BUILDING_AVSCORE\n\n// composite flags for feature group flags.\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_AVX512_BASE_ALL =\nCPUF_AVX512F | CPUF_AVX512CD | CPUF_AVX512BW | CPUF_AVX512DQ | CPUF_AVX512VL |\nCPUF_AVX512_BASE; // and the base single feature flag itself\n\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_AVX512_FAST_ALL =\nCPUF_AVX512_BASE_ALL |\nCPUF_AVX512VNNI | CPUF_AVX512VBMI | CPUF_AVX512VBMI2 | CPUF_AVX512BITALG | CPUF_AVX512VPOPCNTDQ |\nCPUF_AVX512_FAST; // and the FAST single feature flag itself\n\n// Mask for all AVX-512 features listed here\nAVS_CPU_FLAG_CONSTANT int64_t CPUF_AVX512_MASK =\nCPUF_AVX512_FAST_ALL | CPUF_AVX512IFMA | CPUF_AVX512BF16 | CPUF_AVX512FP16 | CPUF_AVX512PF | CPUF_AVX512ER;\n\nint GetCPUFlags();\nint64_t GetCPUFlagsEx(); // more CPU flags, 32-bit was not enough\nsize_t GetL2CacheSize(); // in bytes\n#endif\n\n#endif // AVSCORE_CPUID_H\n"
  },
  {
    "path": "avs_core/include/avs/filesystem.h",
    "content": "#pragma once\n\n// Snippet copied from filesystem/README.md\n\n#if defined(__cplusplus) && __cplusplus >= 201703L && defined(__has_include)\n#if __has_include(<filesystem>)\n#define GHC_USE_STD_FS\n#include <filesystem>\nnamespace fs = std::filesystem;\n#endif\n#endif\n#ifndef GHC_USE_STD_FS\n#include <ghc/filesystem.hpp>\nnamespace fs = ghc::filesystem;\n#endif\n"
  },
  {
    "path": "avs_core/include/avs/minmax.h",
    "content": "// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef AVSCORE_MINMAX_H\n#define AVSCORE_MINMAX_H\n\ntemplate<typename T>\nT min(T v1, T v2)\n{\n  return v1 < v2 ? v1 : v2;\n}\n\ntemplate<typename T>\nT max(T v1, T v2)\n{\n  return v1 > v2 ? v1 : v2;\n}\n\ntemplate<typename T>\nT clamp(T n, T min, T max)\n{\n    n = n > max ? max : n;\n    return n < min ? min : n;\n}\n\n#endif // AVSCORE_MINMAX_H\n"
  },
  {
    "path": "avs_core/include/avs/posix.h",
    "content": "// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifdef AVS_POSIX\n#ifndef AVSCORE_POSIX_H\n#define AVSCORE_POSIX_H\n\n#ifdef __cplusplus\n#include <cstring>\n#endif\n#include <strings.h>\n#include <unistd.h>\n\n// Define these MSVC-extension used in Avisynth\n#define __single_inheritance\n\n// These things don't exist in Linux\n#if defined(AVS_HAIKU)\n#undef __declspec\n#endif\n#define __declspec(x)\n#define lstrlen strlen\n#define lstrcmp strcmp\n#define lstrcmpi strcasecmp\n#define _stricmp strcasecmp\n#define _strnicmp strncasecmp\n#define _strdup strdup\n#define SetCurrentDirectory(x) chdir(x)\n#define SetCurrentDirectoryW(x) chdir(x)\n#define GetCurrentDirectoryW(x) getcwd(x)\n#define _putenv putenv\n#define _alloca alloca\n\n// Borrowing some compatibility macros from AvxSynth, slightly modified\n#define UInt32x32To64(a, b) ((uint64_t)(((uint64_t)((uint32_t)(a))) * ((uint32_t)(b))))\n#define Int64ShrlMod32(a, b) ((uint64_t)((uint64_t)(a) >> (b)))\n#define Int32x32To64(a, b)  ((int64_t)(((int64_t)((long)(a))) * ((long)(b))))\n\n#define InterlockedIncrement(x) __sync_add_and_fetch((x), 1)\n#define InterlockedDecrement(x) __sync_sub_and_fetch((x), 1)\n#define InterlockedExchangeAdd(x, v) __sync_add_and_fetch((x), (v))\n\n#define MulDiv(nNumber, nNumerator, nDenominator)   (int32_t) (((int64_t) (nNumber) * (int64_t) (nNumerator) + (int64_t) ((nDenominator)/2)) / (int64_t) (nDenominator))\n\n#ifndef TRUE\n#define TRUE  true\n#endif\n\n#ifndef FALSE\n#define FALSE false\n#endif\n\n#define S_FALSE       (0x00000001)\n#define E_FAIL        (0x80004005)\n#define FAILED(hr)    ((hr) & 0x80000000)\n#define SUCCEEDED(hr) (!FAILED(hr))\n\n// Statuses copied from comments in exception.cpp\n#define STATUS_GUARD_PAGE_VIOLATION 0x80000001\n#define STATUS_DATATYPE_MISALIGNMENT 0x80000002\n#define STATUS_BREAKPOINT 0x80000003\n#define STATUS_SINGLE_STEP 0x80000004\n#define STATUS_ACCESS_VIOLATION 0xc0000005\n#define STATUS_IN_PAGE_ERROR 0xc0000006\n#define STATUS_INVALID_HANDLE 0xc0000008\n#define STATUS_NO_MEMORY 0xc0000017\n#define STATUS_ILLEGAL_INSTRUCTION 0xc000001d\n#define STATUS_NONCONTINUABLE_EXCEPTION 0xc0000025\n#define STATUS_INVALID_DISPOSITION 0xc0000026\n#define STATUS_ARRAY_BOUNDS_EXCEEDED 0xc000008c\n#define STATUS_FLOAT_DENORMAL_OPERAND 0xc000008d\n#define STATUS_FLOAT_DIVIDE_BY_ZERO 0xc000008e\n#define STATUS_FLOAT_INEXACT_RESULT 0xc000008f\n#define STATUS_FLOAT_INVALID_OPERATION 0xc0000090\n#define STATUS_FLOAT_OVERFLOW 0xc0000091\n#define STATUS_FLOAT_STACK_CHECK 0xc0000092\n#define STATUS_FLOAT_UNDERFLOW 0xc0000093\n#define STATUS_INTEGER_DIVIDE_BY_ZERO 0xc0000094\n#define STATUS_INTEGER_OVERFLOW 0xc0000095\n#define STATUS_PRIVILEGED_INSTRUCTION 0xc0000096\n#define STATUS_STACK_OVERFLOW 0xc00000fd\n\n// Calling convension\n#ifndef AVS_HAIKU\n#define __stdcall\n#define __cdecl\n#endif\n\n// PowerPC OS X is really niche these days, but this painless equivocation\n// of the function/macro names used in posix_get_available_memory()\n// is all it takes to let it work.  The G5 was 64-bit, and if 10.5 Leopard\n// can run in native 64-bit, it probably uses the names in that block as-is.\n#ifdef AVS_MACOS\n#ifdef PPC32\n#define vm_statistics64_data_t vm_statistics_data_t\n#define HOST_VM_INFO64_COUNT HOST_VM_INFO_COUNT\n#define HOST_VM_INFO64 HOST_VM_INFO\n#define host_statistics64 host_statistics\n#endif // PPC32\n#endif // AVS_MACOS\n\n#endif // AVSCORE_POSIX_H\n#endif // AVS_POSIX\n"
  },
  {
    "path": "avs_core/include/avs/types.h",
    "content": "// Avisynth C Interface Version 0.20\n// Copyright 2003 Kevin Atkinson\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// As a special exception, I give you permission to link to the\n// Avisynth C interface with independent modules that communicate with\n// the Avisynth C interface solely through the interfaces defined in\n// avisynth_c.h, regardless of the license terms of these independent\n// modules, and to copy and distribute the resulting combined work\n// under terms of your choice, provided that every copy of the\n// combined work is accompanied by a complete copy of the source code\n// of the Avisynth C interface and Avisynth itself (with the version\n// used to produce the combined work), being distributed under the\n// terms of the GNU General Public License plus this exception.  An\n// independent module is a module which is not derived from or based\n// on Avisynth C Interface, such as 3rd-party filters, import and\n// export plugins, or graphical user interfaces.\n\n#ifndef AVS_TYPES_H\n#define AVS_TYPES_H\n\n// Define all types necessary for interfacing with avisynth.dll\n#include <stdint.h>\n#include <stdbool.h>\n#ifdef __cplusplus\n  #include <cstddef>\n  #include <cstdarg>\n#else\n  #include <stddef.h>\n  #include <stdarg.h>\n#endif\n\n// Raster types used by VirtualDub & Avisynth\ntypedef uint32_t Pixel32;\ntypedef uint8_t  BYTE;\n\n// Audio Sample information\ntypedef float SFLOAT;\n\n#endif //AVS_TYPES_H\n"
  },
  {
    "path": "avs_core/include/avs/win.h",
    "content": "// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef AVSCORE_WIN_H\n#define AVSCORE_WIN_H\n\n// Whenever you need windows headers, start by including this file, then the rest.\n\n// WWUUT? We require XP now?\n#if !defined(NTDDI_VERSION) && !defined(_WIN32_WINNT)\n  #define NTDDI_VERSION 0x05020000\n  #define _WIN32_WINNT  0x0502\n#endif\n\n#define WIN32_LEAN_AND_MEAN\n#define STRICT\n#if !defined(NOMINMAX)\n    #define NOMINMAX\n#endif\n\n#include <windows.h>\n\n// Provision for UTF-8 max 4 bytes per code point\n#define AVS_MAX_PATH MAX_PATH*4\n\n#endif // AVSCORE_WIN_H\n"
  },
  {
    "path": "cmake_uninstall.cmake.in",
    "content": "if(NOT EXISTS \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\")\n  message(FATAL_ERROR \"Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\")\nendif(NOT EXISTS \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\")\n\nfile(READ \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\" files)\nstring(REGEX REPLACE \"\\n\" \";\" files \"${files}\")\nforeach(file ${files})\n  message(STATUS \"Uninstalling $ENV{DESTDIR}${file}\")\n  if(IS_SYMLINK \"$ENV{DESTDIR}${file}\" OR EXISTS \"$ENV{DESTDIR}${file}\")\n    exec_program(\n      \"@CMAKE_COMMAND@\" ARGS \"-E remove \\\"$ENV{DESTDIR}${file}\\\"\"\n      OUTPUT_VARIABLE rm_out\n      RETURN_VALUE rm_retval\n      )\n    if(NOT \"${rm_retval}\" STREQUAL 0)\n      message(FATAL_ERROR \"Problem when removing $ENV{DESTDIR}${file}\")\n    endif(NOT \"${rm_retval}\" STREQUAL 0)\n  else(IS_SYMLINK \"$ENV{DESTDIR}${file}\" OR EXISTS \"$ENV{DESTDIR}${file}\")\n    message(STATUS \"File $ENV{DESTDIR}${file} does not exist.\")\n  endif(IS_SYMLINK \"$ENV{DESTDIR}${file}\" OR EXISTS \"$ENV{DESTDIR}${file}\")\nendforeach(file)\n"
  },
  {
    "path": "distrib/AviSynth_Template.reg",
    "content": "Windows Registry Editor Version 5.00\n\n[HKEY_CLASSES_ROOT\\CLSID\\{E6D6B700-124D-11D4-86F3-DB80AFD98778}]\n@=\"AviSynth\"\n\n[HKEY_CLASSES_ROOT\\CLSID\\{E6D6B700-124D-11D4-86F3-DB80AFD98778}\\InProcServer32]\n@=\"%INSTALLDIR%\\AviSynth.dll\"\n\"ThreadingModel\"=\"Apartment\"\n\n[HKEY_CLASSES_ROOT\\Media Type\\Extensions\\.avs]\n@=\"\"\n\"Source Filter\"=\"{D3588AB0-0781-11CE-B03A-0020AF0BA770}\"\n\n[HKEY_CLASSES_ROOT\\.avs]\n@=\"avsfile\"\n\n[HKEY_CLASSES_ROOT\\avsfile]\n@=\"AviSynth Script\"\n\n[HKEY_CLASSES_ROOT\\avsfile\\DefaultIcon]\n@=\"%INSTALLDIR%\\AviSynth.dll,0\"\n\n[HKEY_CLASSES_ROOT\\.avsi]\n@=\"avs_auto_file\"\n\n[HKEY_CLASSES_ROOT\\avs_auto_file]\n@=\"AviSynth Autoload Script\"\n\n[HKEY_CLASSES_ROOT\\avs_auto_file\\DefaultIcon]\n@=\"%INSTALLDIR%\\AviSynth.dll,0\"\n\n[HKEY_CLASSES_ROOT\\AVIFile\\Extensions\\AVS]\n@=\"{E6D6B700-124D-11D4-86F3-DB80AFD98778}\"\n\n[HKEY_LOCAL_MACHINE\\SOFTWARE\\Avisynth]\n@=\"%INSTALLDIR%\"\n\"PluginDir+\"=\"%INSTALLDIR%\\plugins+\"\n\"PluginDir2_5\"=\"%INSTALLDIR%\\plugins\"\n\n[HKEY_CURRENT_USER\\Software\\AviSynth]\n@=\"%INSTALLDIR%\"\n\"PluginDir+\"=\"%INSTALLDIR%\\plugins+\"\n\"PluginDir2_5\"=\"%INSTALLDIR%\\plugins\"\n\n"
  },
  {
    "path": "distrib/ColorPresets/colors_rgb.avsi",
    "content": "# list of common colors (rgb values)\n\n# source:\n# http://en.wikipedia.org/wiki/List_of_colors\n# http://en.wikipedia.org/wiki/X11_color_names\n# http://www.cryer.co.uk/resources/javascript/html2.htm\n\nglobal color_aliceblue              = $F0F8FF\nglobal color_antiquewhite           = $FAEBD7\nglobal color_aqua                   = $00FFFF\nglobal color_aquamarine             = $7FFFD4\nglobal color_azure                  = $F0FFFF\nglobal color_beige                  = $F5F5DC\nglobal color_bisque                 = $FFE4C4\nglobal color_black                  = $000000\nglobal color_blanchedalmond         = $FFEBCD\nglobal color_blue                   = $0000FF\nglobal color_blueviolet             = $8A2BE2\nglobal color_brown                  = $A52A2A\nglobal color_burlywood              = $DEB887\nglobal color_cadetblue              = $5F9EA0\nglobal color_chartreuse             = $7FFF00\nglobal color_chocolate              = $D2691E\nglobal color_coral                  = $FF7F50\nglobal color_cornflowerblue         = $6495ED\nglobal color_cornsilk               = $FFF8DC\nglobal color_crimson                = $DC143C\nglobal color_cyan                   = $00FFFF\nglobal color_darkblue               = $00008B\nglobal color_darkcyan               = $008B8B\nglobal color_darkgoldenrod          = $B8860B\nglobal color_darkgray               = $A9A9A9\nglobal color_darkgreen              = $006400\nglobal color_darkkhaki              = $BDB76B\nglobal color_darkmagenta            = $8B008B\nglobal color_darkoliveGreen         = $556B2F\nglobal color_darkorange             = $FF8C00\nglobal color_darkorchid             = $9932CC\nglobal color_darkred                = $8B0000\nglobal color_darksalmon             = $E9967A\nglobal color_darkseaGreen           = $8FBC8F\nglobal color_darkslateBlue          = $483D8B\nglobal color_darkslateGray          = $2F4F4F\nglobal color_darkturquoise          = $00CED1\nglobal color_darkviolet             = $9400D3\nglobal color_deeppink               = $FF1493\nglobal color_deepskyblue            = $00BFFF\nglobal color_dimgray                = $696969\nglobal color_dodgerblue             = $1E90FF\nglobal color_firebrick              = $B22222\nglobal color_floralwhite            = $FFFAF0\nglobal color_forestgreen            = $228B22\nglobal color_fuchsia                = $FF00FF\nglobal color_gainsboro              = $DCDCDC\nglobal color_ghostwhite             = $F8F8FF\nglobal color_gold                   = $FFD700\nglobal color_goldenrod              = $DAA520\nglobal color_gray                   = $808080\nglobal color_green                  = $008000\nglobal color_greenyellow            = $ADFF2F\nglobal color_honeydew               = $F0FFF0\nglobal color_hotpink                = $FF69B4\nglobal color_indianred              = $CD5C5C\nglobal color_indigo                 = $4B0082\nglobal color_ivory                  = $FFFFF0\nglobal color_khaki                  = $F0E68C\nglobal color_lavender               = $E6E6FA\nglobal color_lavenderblush          = $FFF0F5\nglobal color_lawngreen              = $7CFC00\nglobal color_lemonchiffon           = $FFFACD\nglobal color_lightblue              = $ADD8E6\nglobal color_lightcoral             = $F08080\nglobal color_lightcyan              = $E0FFFF\nglobal color_lightgoldenrodyellow   = $FAFAD2\nglobal color_lightgreen             = $90EE90\nglobal color_lightgrey              = $D3D3D3\nglobal color_lightpink              = $FFB6C1\nglobal color_lightsalmon            = $FFA07A\nglobal color_lightseagreen          = $20B2AA\nglobal color_lightskyblue           = $87CEFA\nglobal color_lightslategray         = $778899\nglobal color_lightsteelblue         = $B0C4DE\nglobal color_lightyellow            = $FFFFE0\nglobal color_lime                   = $00FF00\nglobal color_limegreen              = $32CD32\nglobal color_linen                  = $FAF0E6\nglobal color_magenta                = $FF00FF\nglobal color_maroon                 = $800000\nglobal color_mediumaquamarine       = $66CDAA\nglobal color_mediumblue             = $0000CD\nglobal color_mediumorchid           = $BA55D3\nglobal color_mediumpurple           = $9370DB\nglobal color_mediumseagreen         = $3CB371\nglobal color_mediumslatenlue        = $7B68EE\nglobal color_mediumspringgreen      = $00FA9A\nglobal color_mediumturquoise        = $48D1CC\nglobal color_mediumvioletred        = $C71585\nglobal color_midnightblue           = $191970\nglobal color_mintcream              = $F5FFFA\nglobal color_mistyrose              = $FFE4E1\nglobal color_moccasin               = $FFE4B5\nglobal color_navajowhite            = $FFDEAD\nglobal color_navy                   = $000080\nglobal color_oldlace                = $FDF5E6\nglobal color_olive                  = $808000\nglobal color_olivedrab              = $6B8E23\nglobal color_orange                 = $FFA500\nglobal color_orangered              = $FF4500\nglobal color_orchid                 = $DA70D6\nglobal color_palegoldenrod          = $EEE8AA\nglobal color_palegreen              = $98FB98\nglobal color_paleturquoise          = $AFEEEE\nglobal color_palevioletred          = $DB7093\nglobal color_papayawhip             = $FFEFD5\nglobal color_peachpuff              = $FFDAB9\nglobal color_peru                   = $CD853F\nglobal color_pink                   = $FFC0CB\nglobal color_plum                   = $DDA0DD\nglobal color_powderblue             = $B0E0E6\nglobal color_purple                 = $800080\nglobal color_red                    = $FF0000\nglobal color_rosybrown              = $BC8F8F\nglobal color_royalblue              = $4169E1\nglobal color_saddlebrown            = $8B4513\nglobal color_salmon                 = $FA8072\nglobal color_sandybrown             = $F4A460\nglobal color_seagreen               = $2E8B57\nglobal color_seashell               = $FFF5EE\nglobal color_sienna                 = $A0522D\nglobal color_silver                 = $C0C0C0\nglobal color_skyblue                = $87CEEB\nglobal color_slateblue              = $6A5ACD\nglobal color_slategray              = $708090\nglobal color_snow                   = $FFFAFA\nglobal color_springgreen            = $00FF7F\nglobal color_steelblue              = $4682B4\nglobal color_tan                    = $D2B48C\nglobal color_teal                   = $008080\nglobal color_thistle                = $D8BFD8\nglobal color_tomato                 = $FF6347\nglobal color_turquoise              = $40E0D0\nglobal color_violet                 = $EE82EE\nglobal color_wheat                  = $F5DEB3\nglobal color_white                  = $FFFFFF\nglobal color_whitesmoke             = $F5F5F5\nglobal color_yellow                 = $FFFF00\nglobal color_yellowgreen            = $9ACD32\n\n#Gray colors\nglobal color_gray10 = $191919\nglobal color_gray20 = $323232\nglobal color_gray30 = $4b4b4b\nglobal color_gray40 = $656565\nglobal color_gray50 = $7f7f7f\nglobal color_gray60 = $989898\nglobal color_gray70 = $b1b1b1\nglobal color_gray80 = $cacaca\nglobal color_gray90 = $e4e4e4\n\n"
  },
  {
    "path": "distrib/ColorPresets/colors_rgb.txt",
    "content": "# list of common colors (rgb values)\n\n# source:\n# http://en.wikipedia.org/wiki/List_of_colors\n# http://en.wikipedia.org/wiki/X11_color_names\n# http://www.cryer.co.uk/resources/javascript/html2.htm\n\n## Name \tHex \tRGB\naliceblue \t#F0F8FF \t240, 248, 255\nantiquewhite \t#FAEBD7 \t250, 235, 215\naqua \t#00FFFF \t0, 255, 255\naquamarine \t#7FFFD4 \t127, 255, 212\nazure \t#F0FFFF \t240, 255, 255\nbeige \t#F5F5DC \t245, 245, 220\nbisque \t#FFE4C4 \t255, 228, 196\nblack \t#000000 \t0, 0, 0\nblanchedalmond \t#FFEBCD \t255, 235, 205\nblue \t#0000FF \t0, 0, 255\nblueviolet \t#8A2BE2 \t138, 43, 226\nbrown \t#A52A2A \t165, 42, 42\nburlywood \t#DEB887 \t222, 184, 135\ncadetblue \t#5F9EA0 \t95, 158, 160\nchartreuse \t#7FFF00 \t127, 255, 0\nchocolate \t#D2691E \t210, 105, 30\ncoral \t#FF7F50 \t255, 127, 80\ncornflowerblue \t#6495ED \t100, 149, 237\ncornsilk \t#FFF8DC \t255, 248, 220\ncrimson \t#DC143C \t220, 20, 60\ncyan \t#00FFFF \t0, 255, 255\ndarkblue \t#00008B \t0, 0, 139\ndarkcyan \t#008B8B \t0, 139, 139\ndarkgoldenrod \t#B8860B \t184, 134, 11\ndarkgray \t#A9A9A9 \t169, 169, 169\ndarkgreen \t#006400 \t0, 100, 0\ndarkkhaki \t#BDB76B \t189, 183, 107\ndarkmagenta \t#8B008B \t139, 0, 139\ndarkoliveGreen \t#556B2F \t85, 107, 47\ndarkorange \t#FF8C00 \t255, 140, 0\ndarkorchid \t#9932CC \t153, 50, 204\ndarkred \t#8B0000 \t139, 0, 0\ndarksalmon \t#E9967A \t233, 150, 122\ndarkseaGreen \t#8FBC8F \t143, 188, 143\ndarkslateBlue \t#483D8B \t72, 61, 139\ndarkslateGray \t#2F4F4F \t47, 79, 79\ndarkturquoise \t#00CED1 \t0, 206, 209\ndarkviolet \t#9400D3 \t148, 0, 211\ndeeppink \t#FF1493 \t255, 20, 147\ndeepskyblue \t#00BFFF \t0, 191, 255\ndimgray \t#696969 \t105, 105, 105\ndodgerblue \t#1E90FF \t30, 144, 255\nfirebrick \t#B22222 \t178, 34, 34\nfloralwhite \t#FFFAF0 \t255, 250, 240\nforestgreen \t#228B22 \t34, 139, 34\nfuchsia \t#FF00FF \t255, 0, 255\ngainsboro \t#DCDCDC \t220, 220, 220\nghostwhite \t#F8F8FF \t248, 248, 255\ngold \t#FFD700 \t255, 215, 0\ngoldenrod \t#DAA520 \t218, 165, 32\ngray \t#808080 \t128, 128, 128\ngreen \t#008000 \t0, 128, 0\ngreenyellow \t#ADFF2F \t173, 255, 47\nhoneydew \t#F0FFF0 \t240, 255, 240\nhotpink \t#FF69B4 \t255, 105, 180\nindianred \t#CD5C5C \t205, 92, 92\nindigo \t#4B0082 \t75, 0, 130\nivory \t#FFFFF0 \t255, 255, 240\nkhaki \t#F0E68C \t240, 230, 140\nlavender \t#E6E6FA \t230, 230, 250\nlavenderblush \t#FFF0F5 \t255, 240, 245\nlawngreen \t#7CFC00 \t124, 252, 0\nlemonchiffon \t#FFFACD \t255, 250, 205\nlightblue \t#ADD8E6 \t173, 216, 230\nlightcoral \t#F08080 \t240, 128, 128\nlightcyan \t#E0FFFF \t224, 255, 255\nlightgoldenrodyellow \t#FAFAD2 \t250, 250, 210\nlightgreen \t#90EE90 \t144, 238, 144\nlightgrey \t#D3D3D3 \t211, 211, 211\nlightpink \t#FFB6C1 \t255, 182, 193\nlightsalmon \t#FFA07A \t255, 160, 122\nlightseagreen \t#20B2AA \t32, 178, 170\nlightskyblue \t#87CEFA \t135, 206, 250\nlightslategray \t#778899 \t119, 136, 153\nlightsteelblue \t#B0C4DE \t176, 196, 222\nlightyellow \t#FFFFE0 \t255, 255, 224\nlime \t#00FF00 \t0, 255, 0\nlimegreen \t#32CD32 \t50, 205, 50\nlinen \t#FAF0E6 \t250, 240, 230\nmagenta \t#FF00FF \t255, 0, 255\nmaroon \t#800000 \t128, 0, 0\nmediumaquamarine \t#66CDAA \t102, 205, 170\nmediumblue \t#0000CD \t0, 0, 205\nmediumorchid \t#BA55D3 \t186, 85, 211\nmediumpurple \t#9370DB \t147, 112, 219\nmediumseagreen \t#3CB371 \t60, 179, 113\nmediumslatenlue \t#7B68EE \t123, 104, 238\nmediumspringgreen \t#00FA9A \t0, 250, 154\nmediumturquoise \t#48D1CC \t72, 209, 204\nmediumvioletred \t#C71585 \t199, 21, 133\nmidnightblue \t#191970 \t25, 25, 112\nmintcream \t#F5FFFA \t245, 255, 250\nmistyrose \t#FFE4E1 \t255, 228, 225\nmoccasin \t#FFE4B5 \t255, 228, 181\nnavajowhite \t#FFDEAD \t255, 222, 173\nnavy \t#000080 \t0, 0, 128\noldlace \t#FDF5E6 \t253, 245, 230\nolive \t#808000 \t128, 128, 0\nolivedrab \t#6B8E23 \t107, 142, 35\norange \t#FFA500 \t255, 165, 0\norangered \t#FF4500 \t255, 69, 0\norchid \t#DA70D6 \t218, 112, 214\npalegoldenrod \t#EEE8AA \t238, 232, 170\npalegreen \t#98FB98 \t152, 251, 152\npaleturquoise \t#AFEEEE \t175, 238, 238\npalevioletred \t#DB7093 \t219, 112, 147\npapayawhip \t#FFEFD5 \t255, 239, 213\npeachpuff \t#FFDAB9 \t255, 218, 185\nperu \t#CD853F \t205, 133, 63\npink \t#FFC0CB \t255, 192, 203\nplum \t#DDA0DD \t221, 160, 221\npowderblue \t#B0E0E6 \t176, 224, 230\npurple \t#800080 \t128, 0, 128\nred \t#FF0000 \t255, 0, 0\nrosybrown \t#BC8F8F \t188, 143, 143\nroyalblue \t#4169E1 \t65, 105, 225\nsaddlebrown \t#8B4513 \t139, 69, 19\nsalmon \t#FA8072 \t250, 128, 114\nsandybrown \t#F4A460 \t244, 164, 96\nseagreen \t#2E8B57 \t46, 139, 87\nseashell \t#FFF5EE \t255, 245, 238\nsienna \t#A0522D \t160, 82, 45\nsilver \t#C0C0C0 \t192, 192, 192\nskyblue \t#87CEEB \t135, 206, 235\nslateblue \t#6A5ACD \t106, 90, 205\nslategray \t#708090 \t112, 128, 144\nsnow \t#FFFAFA \t255, 250, 250\nspringgreen \t#00FF7F \t0, 255, 127\nsteelblue \t#4682B4 \t70, 130, 180\ntan \t#D2B48C \t210, 180, 140\nteal \t#008080 \t0, 128, 128\nthistle \t#D8BFD8 \t216, 191, 216\ntomato \t#FF6347 \t255, 99, 71\nturquoise \t#40E0D0 \t64, 224, 208\nviolet \t#EE82EE \t238, 130, 238\nwheat \t#F5DEB3 \t245, 222, 179\nwhite \t#FFFFFF \t255, 255, 255\nwhitesmoke \t#F5F5F5 \t245, 245, 245\nyellow \t#FFFF00 \t255, 255, 0\nyellowgreen \t#9ACD32 \t154, 205, 50"
  },
  {
    "path": "distrib/Examples/Audio.avs",
    "content": "# Generates colorbar image at the size 320x240, Adds a 440Hz tone that pulses in the right speaker\n\nColorbars(320,240)\n\n# Selects the right channel\n\nGetRightChannel()\n\n# Amplifies the signal down 3DB, and puts the result into the variable 'signal'\n\nsignal = AmplifyDB(-3)\n\n# Puts the new signal as right channel, leaving the sound from GetRightChannel as new left channel.\n\nMonoToStereo(signal)\n\n# Left channel now contains a pulsing signal (from ColorBars).\n# Right channel now contains the same signal at -3dB."
  },
  {
    "path": "distrib/Examples/Authors.avs",
    "content": "ovText = \"AviSynth Authors:\"+chr(13)+\n\t\\ \"----------------------------\"+chr(13)+\n\t\\ \"Ben Rudiak-Gould\"+chr(13)+\n\t\\ \"Klaus Post\"+chr(13)+\n\t\\ \"Richard Berg\"+chr(13)+\n\t\\ \"Dividee\"+chr(13)+\n\t\\ \"Ian Brabham\"+chr(13)+\n\t\\ \"David Pierre\"+chr(13)+chr(13)+\n\t\\ \"Documentation:\"+chr(13)+\n\t\\ \"----------------------------\"+chr(13)+\n\t\\ \"Wilbert Dijkhof\"+chr(13)+\n\t\\ \"Jonathan Ernst\"+chr(13)+\n\t\\ \"Ernst Peche\"+chr(13)+\n\t\\ \"Alexander Balakhnin\"+chr(13)+\n\t\\ \"Alex_e_Basta\"+chr(13)+\n\t\\ \"Arne Stcker\"+chr(13)+chr(13)+\n\t\\ \"Contributions by:\"+chr(13)+\n\t\\ \"----------------------------\"+chr(13)+\n\t\\ \"Avery Lee, Milan, Naoki Shibata, \"+chr(13)+\n\t\\ \"Peter Pawlowski, Olli Parviainen,\"+chr(13)+\n\t\\ \"Nicolas Capens, DevIL team,\"+chr(13)+\n\t\\ \"Donald Graft, poptones, ARDA\"+chr(13)+\n\t\\ \"Kevin Atkinson, tritical, many more...\"+chr(13)+chr(13)+\n\t\\ \"Thanks to:\"+chr(13)+\n\t\\ \"----------------------------\"+chr(13)+\n\t\\ \"Everyone contributing to the project,\"+chr(13)+\n\t\\ \"Doom9 & team, kwag, stickboy\"+chr(13)+\n\t\\ \"\"\n\n\nBlankclip(length=128, width=32,height=32, fps=25)\nconverttoyuy2()\nColoryuv(showyuv=true)\nbg = loop(last + reverse(), 10)\n\nc = framecount(bg)\nt_mask = messageclip(ovText, height=c).converttoyv12().coloryuv(levels=\"tv->pc\").trim(0,1)\nt_blank = blankclip(t_mask, color=$ffffff)\n\nt_mask_bl = t_mask.blur(1.0).blur(1.0).blur(1.0)\n\noverlay(bg, t_mask_bl, mode=\"subtract\")\noverlay(t_blank, mode=\"blend\", mask=t_mask)\n\nframeevaluate(\"ol_x_offset = 40\")\nframeevaluate(\"ol_y_offset = 256 - (current_frame)\")\n\nfadeio(15)\nconverttoyuy2()\n\nvideo = last\n\n##############################################################\n######################### AUDIO ##############################\n##############################################################\n\ns_type= \"square\"\nfreq_mul = 1.25\nlen_16 = 0.13\n\ndis_16 = tone(len_16, 311/freq_mul, 44100, 1, s_type)   #   D#\ncis_16 = tone(len_16, 277/freq_mul, 44100, 1, s_type)\t#   C#\nsil_16 = dis_16.amplify(0.0)\t\t\t\t# Silence\ne_16 = tone(len_16, 329.5/freq_mul, 44100, 1, s_type)\t#   E\nd_16 = tone(len_16, 293.7/freq_mul, 44100, 1, s_type)\t#   D\nc_16 = tone(len_16, 261.6/freq_mul, 44100, 1, s_type)\t#   C\n\np1 = dis_16 ++ sil_16 ++ e_16 ++ dis_16 ++ dis_16 ++ e_16 ++ dis_16 ++ dis_16 ++ e_16 ++ dis_16 ++ dis_16 ++ dis_16 ++ d_16 ++ dis_16 ++ dis_16 ++ dis_16\np2= cis_16 ++ sil_16 ++ d_16 ++ cis_16 ++ cis_16 ++ d_16 ++ cis_16 ++ cis_16 ++ d_16 ++ cis_16 ++ cis_16 ++ cis_16 ++ c_16 ++ cis_16 ++ cis_16 ++ cis_16\n\np1 ++ p1 ++ p2 ++ p2\nlast ++ last ++ last\n#convertaudioto16bit()\nv_low = timestretch(pitch=50).amplifydb(-6)\nv_high = timestretch(pitch=200).amplifydb(-12)\nmergechannels(last, v_low, v_high)\nconverttomono()\namplifydb(-12)\naudio = last\n\n###################################################################\n\naudiodub (video, audio)\n"
  },
  {
    "path": "distrib/Examples/Editing.avs",
    "content": "# Generates colorbar image at the size 320x240\n\nColorbars(320, 240)\n\n# Converts the image to greyscale\n\nGreyscale()\n\n# Adds framenumbers to the image\n\nShowframenumber()\n\n# Selects the range 0 to 50000\n\nTrim (0, 50000)\n\n# Selects every second frame. Fps is now half of 29.97\n\nSelectEven()\n\n# Selects first 1000 frames inside the stream, and assigns it to variable substream\n\nsubstream = Trim (0, -1000)\n\n# Loop the substream 25 times\n\nsubstream = Loop(substream, 25)\n\n# Put the substream on bottom of the original\n\nStackvertical(substream)\n\n"
  },
  {
    "path": "distrib/Examples/Equalizer Presets/1965.feq",
    "content": "-20\n-16\n-7\n-4\n-4\n-4\n-7\n-7\n3\n3\n-2\n-4\n4\n1\n1\n-4\n-6\n-12\n"
  },
  {
    "path": "distrib/Examples/Equalizer Presets/Air.feq",
    "content": "0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n3\n2\n"
  },
  {
    "path": "distrib/Examples/Equalizer Presets/Brittle.feq",
    "content": "-12\n-10\n-9\n-8\n-7\n-6\n-5\n-3\n-2\n-2\n-2\n-2\n-1\n1\n4\n4\n1\n0\n"
  },
  {
    "path": "distrib/Examples/Equalizer Presets/Car Stereo.feq",
    "content": "-5\n0\n1\n0\n0\n-4\n-4\n-5\n-5\n-5\n-3\n-2\n-2\n0\n1\n0\n-2\n-5\n"
  },
  {
    "path": "distrib/Examples/Equalizer Presets/Classic V.feq",
    "content": "5\n2\n0\n-2\n-5\n-6\n-8\n-8\n-7\n-7\n-4\n-3\n-1\n1\n3\n5\n5\n4\n"
  },
  {
    "path": "distrib/Examples/Equalizer Presets/Clear.feq",
    "content": "1\n1\n0\n0\n0\n-3\n0\n0\n0\n0\n0\n0\n0\n0\n2\n2\n2\n1\n"
  },
  {
    "path": "distrib/Examples/Equalizer Presets/DEATH.feq",
    "content": "20\n17\n12\n8\n4\n0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n"
  },
  {
    "path": "distrib/Examples/Equalizer Presets/Dark.feq",
    "content": "-6\n-2\n-2\n-2\n-2\n-2\n-2\n-2\n-2\n-2\n-2\n-5\n-8\n-10\n-12\n-14\n-18\n-18\n"
  },
  {
    "path": "distrib/Examples/Equalizer Presets/Drums.feq",
    "content": "2\n1\n0\n0\n0\n-2\n0\n-2\n0\n0\n0\n0\n2\n0\n0\n3\n0\n0\n"
  },
  {
    "path": "distrib/Examples/Equalizer Presets/Flat.feq",
    "content": "0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n"
  },
  {
    "path": "distrib/Examples/Equalizer Presets/Home Theater.feq",
    "content": "5\n2\n0\n-2\n-3\n-5\n-6\n-6\n-5\n-2\n-1\n0\n-1\n-3\n3\n4\n3\n0\n"
  },
  {
    "path": "distrib/Examples/Equalizer Presets/Loudness.feq",
    "content": "4\n4\n4\n2\n-2\n-2\n-2\n-2\n-2\n-2\n-2\n-4\n-10\n-7\n0\n3\n4\n4\n"
  },
  {
    "path": "distrib/Examples/Equalizer Presets/Pop.feq",
    "content": "6\n5\n3\n0\n-2\n-4\n-4\n-6\n-3\n1\n0\n0\n2\n1\n2\n4\n5\n6\n"
  },
  {
    "path": "distrib/Examples/Equalizer Presets/Premaster.feq",
    "content": "0\n1\n3\n0\n-3\n-3\n0\n0\n0\n2\n0\n0\n3\n0\n3\n1\n3\n2\n"
  },
  {
    "path": "distrib/Examples/Equalizer Presets/Presence.feq",
    "content": "0\n0\n0\n0\n0\n0\n0\n0\n0\n3\n5\n4\n3\n2\n0\n0\n0\n0\n"
  },
  {
    "path": "distrib/Examples/Equalizer Presets/Punch & Sparkle.feq",
    "content": "3\n5\n3\n-1\n-3\n-5\n-5\n-3\n-2\n1\n1\n1\n0\n2\n1\n3\n5\n3\n"
  },
  {
    "path": "distrib/Examples/Equalizer Presets/Shimmer.feq",
    "content": "0\n0\n0\n-2\n-2\n-7\n-5\n0\n0\n0\n0\n0\n4\n1\n3\n3\n4\n0\n"
  },
  {
    "path": "distrib/Examples/Equalizer Presets/Soft Bass.feq",
    "content": "3\n5\n4\n0\n-13\n-7\n-5\n-5\n-1\n2\n5\n1\n-1\n-1\n-2\n-7\n-9\n-14\n"
  },
  {
    "path": "distrib/Examples/Equalizer Presets/Strings.feq",
    "content": "-3\n-4\n-4\n-5\n-5\n-4\n-4\n-3\n-2\n-2\n-2\n-2\n-1\n2\n3\n0\n-2\n-2\n"
  },
  {
    "path": "distrib/Examples/Processing.avs",
    "content": "# Generates colorbar image at the size 512x384\n\nColorbars(512,384)\n\n# Resizes the image using the lanczos3 algorithm\n\nLanczosResize(640,480)\n\n# Now the image is 640x480\n# Now crop 16 pixels off the entire image all the way around.\n\nCrop(16, 16, -16, -16)\n\n# Convert to greyscale\n\nGreyscale()\n\n"
  },
  {
    "path": "distrib/Examples/Syntax.avs",
    "content": "# Generates colorbar image and converts it to YUY2\n# The image and sound is now \"current clip\"\n\nColorbars(320,240)\nConvertToYUY2()\n\n# Take the \"current clip\", and add greayscale to this.\n# The result is now in the variable Grey.\n# Current clip is still the original Colorbars(320,240)\n\nGrey = Greyscale()\n\n# Now you can use Grey as an alternative clip, instead if the current clip\n# This creates a new variable called Grey_Half_Size, that contains the grey colorbar at half the height.\n# Current clip is still the original Colorbars(320,240)\n\nGrey_Half_Size = VerticalReduceBy2(Grey)\n\n# If we specify more parameters, but don't want it used on the current clip,\n#  we can either specify the clip in front of the filter, using '.'\n#  or specify the clip as the first parameter.\n\nGrey_Same_Size = Grey_half_size.AddBorders(0,60,0,60)\n\n# which is the same as:\n\nGrey_Same_Size = AddBorders(Grey_half_size,0,60,0,60)\n\n# More examples:\n\nCombined = MergeLuma(grey_same_size)\n#Combined = MergeChroma(Combined, grey_same_size)\n#Grey_same_size=mergeluma(combined)\n# Add titles to clips:\n\nThisclip = Subtitle(\"Current Clip\")\nGrey_Half_size = Subtitle(Grey_Half_size,\"Grey_Half_size\")\nGrey_Same_size = Subtitle(Grey_Same_size,\"Grey_Same_size\")\nCombined = Subtitle(Combined,\"Combined\")\n\n# Put them on top of eachother\n\nStackvertical(thisclip, Grey_Half_size, Grey_Same_size, Combined)\n"
  },
  {
    "path": "distrib/Examples/Version.avs",
    "content": "# Prints out version information\n\nVersion()\n"
  },
  {
    "path": "distrib/OFL.TXT",
    "content": "Copyright (c) 2019 Dimitar Toshkov Zhekov,\nwith Reserved Font Name \"Terminus Font\".\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttp://scripts.sil.org/OFL\n\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "distrib/Prerequisites/keep.me",
    "content": "This folder is a placeholder for installer prerequisites, which has to be updated before creating the installer\nSuch as Microsoft Visual C++ Redistributable packages for Visual Studio 2015, 2017, 2019, and 2022: VC_redist.x64.exe and VC_redist.x86.exe \n\nInstaller searches for XP redistributables under specific names: \nVC_redist_14.27.29114.0.x86.exe and VC_redist_14.27.29114.0.x64.exe\nWhen you download these, rename VC_redist.x86.exe and VC_redist.x64.exe if XP specific builds are set in installer script\n\nhttps://docs.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170\n\nImportant note:\n  Windows XP Support: Microsoft ended support for Windows XP on April 8, 2014\n  As of 2021, XP-specific AviSynth builds still require a _compatible_ (=not latest) Visual C++ runtime.\n\n  Runtime library support for Windows XP is no longer available in the latest Visual C++ Redistributable for Visual Studio 2015, 2017, 2019, and 2022.\n  The last redistributable to support Windows XP is version 16.7 (file version 14.27.29114.0*).\n  If Windows XP apps are deployed with or updated to a later version of the redistributable, the apps won't run.\n\n  As discussed in issue: https://github.com/AviSynth/AviSynthPlus/issues/241\n  https://my.visualstudio.com/downloads?Visual%20Studio%202019%20version%2016.7\n\n  *Others experienced that the latest XP compatible version is 14.28.29213.0.\n  Links to official installers for last XP compatible Microsoft Visual C++ 2015-2019 Redistributable (version 14.28.29213):\n  x64 - https://download.visualstudio.microsoft.com/download/pr/566435ac-4e1c-434b-b93f-aecc71e8cffc/B75590149FA14B37997C35724BC93776F67E08BFF9BD5A69FACBF41B3846D084/VC_redist.x64.exe\n  x86 - https://download.visualstudio.microsoft.com/download/pr/566435ac-4e1c-434b-b93f-aecc71e8cffc/0D59EC7FDBF05DE813736BF875CEA5C894FFF4769F60E32E87BD48406BBF0A3A/VC_redist.x86.exe "
  },
  {
    "path": "distrib/Readme/readme_history.txt",
    "content": "Avisynth Plus change log\n------------------------\nSource: https://github.com/AviSynth/AviSynthPlus\n\nThis file contains all change log, with detailed examples and explanations.\nThe \"rst\" version of the documentation just lists changes in brief.\nFor online documentation check https://avisynthplus.readthedocs.io/en/latest/\n\nActual:\nhttps://avisynthplus.readthedocs.io/en/latest/avisynthdoc/changelist376.html\n20260331 3.7.5.r45XX (pre 3.7.6)\n--------------------------------\n- SetFilterProp: new conditional form — inject a frame property only when a named call argument\n  equals a given match value or any element of an alias array (e.g. all equivalent string\n  representations of the same colorspace constant). String comparison is case-insensitive.\n  Both positional and named call sites are matched.\n  Syntax: SetFilterProp(filter, param_name, param_match_or_array, key, value [, mode])\n- SetFilterProp: capture mode (undefined() value) — capture the actual call-time argument\n  value and stamp it as a frame property of the same name. Works for positional and named calls.\n- SetFilterPropPassthrough(filter) — compatibility shim for old filters that predate frame\n  property support (e.g. ColorMatrix). Copies all input frame properties to the filter's output.\n  Self-healing: becomes a no-op per frame once the plugin is updated to use NewVideoFrameP.\n  Must be combined with SetFilterProp rules if specific properties should override the inherited\n  values (passthrough runs first, injections run after).\n- GetFilterProps() — returns all registered SetFilterProp rules as a JSON string (diagnostics).\n- doc: add SetFilterProp / SetFilterPropPassthrough documentation page.\n  Addresses https://github.com/AviSynth/AviSynthPlus/issues/393 and more.\n\n20260328 3.7.5.r4565 (pre 3.7.6)\n--------------------------------\n- Add ColorbarsUHD\n- Fix: LruCache self-tuning cache resize: raised ghost-hit threshold from ghosted>0 to ghosted>1,\n  preventing unbounded cache growth during backward seeking (Issue #379) and Bob/SeparateFields\n  access patterns (Issue #270).\n- Fix: VideoFrame::Release() race condition in frame property cleanup under multi-threaded use\n  (stability fix for static-frame sources such as ColorBars, BlankClip).\n- Histogram \"color\"/\"color2\": add targets100 parameter: the 6 ColorBars target boxes at 100% luma scale.\n- Fix: YUV<->RGB conversion with quality=true at 10-14 bit sources (regression).\n- Fix: Histogram \"color\"/\"color2\": \"target\" parameter no longer acts as master switch for \"axes\".\n\n20260306 3.7.5.r4554 (pre 3.7.6)\n--------------------------------\n- Reenable YUY2 in planar target conversions as source (disabled in r4549)\n- ConvertToY also gets bits and quality parameters, latter is used when source is RGB.\n\n20260305 3.7.5.r4549 (pre 3.7.6)\n--------------------------------\n- Fix: memory leak in Subframe/MakePropertyWritable after static-frame sources (ColorBars, BlankClip)\n- any->YUV conversions (See https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/corefilters/convert.html`.\n  - accept bits and quality parameters, similar to ConvertToPlanarRGB\n  - the legacy 8-bit-named functions (``ConvertToYV12``, ``ConvertToYV16``, \n    ``ConvertToYV24``) allowing high-depth sources.\n  - \"ConvertToYUY2\": rewritten to route all conversions through YV16.\n  - \"ConvertToYUY2\": ``ChromaOutPlacement`` parameter added (was missing, present in ConvertToYV16).\n  - \"ConvertBackToYUY2\": kept for backward compatibility; now forwards to ``ConvertToYUY2``. The pre-2.5 left-pixel-only chroma hack is no longer\n    needed or applied; the YV16 lossless repack path avoids chroma resampling loss entirely for roundtrip workflows.\n  - 8 bit packed RGB formats are converted to planar RGB before 444 conversion.\n    Utilizing the optimized planar RGB infrastructure.\n  - Fix: \"ConvertToYUY2\" / \"ConvertToYV12\": progressive YV12<->YUY2 conversion (use generic YV16/YV12 path)\n  - Fix: \"ConvertToYUY2\": ``_ChromaLocation``, ``_Matrix`` and ``_ColorRange``\n    frame properties were not read from YV12 source frames and not written to YUY2 output frames \n    in the old legacy direct conversion path.\n  - Fix: \"ConvertToYUY2\": SSE2 interlaced upsampling used wrong weighting direction, differing from the C reference implementation.\n- Update https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/corefilters/convert.html`\n  - matrix syntax\n  - ConvertToYUY2\n  - ``bits`` and ``quality`` parameters\n- Update Sampling https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/advancedtopics/sampling.html with historical content notes \n  on legacy ``YUY2`` handling.\n\n20260220 3.7.5.r4529 (pre 3.7.6)\n--------------------------------\n- Fix Colorbars inaccurate 10+ bit, by using ground truth linear RGB, similarly to ColorBarsHD.\n  - Full refactoring.\n  - update doc: https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/corefilters/colorbars.html\n- Histogram \"color\" and \"color2\" (Vectorscope modes) \n  - full refactoring.\n  - Drawing is now matrix and color range aware. target positions (75%) +-I and +Q.\n  - add individual overlay options:\n    added ``matrix``, ``graticule``, ``targets``, ``axes``, ``iq``, ``iq_lines``, ``circle``\n    parameters\n  - Fix: copy alpha from clip, initialize alpha to zero in the histogram area. \n  - Accurate pixel positioning and scaling to the active histogram area, \n    limited/full range aware.\n  - update doc: https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/corefilters/histogram.html\n\n\n20260216 3.7.5.r4523 (pre 3.7.6)\n--------------------------------\n- Fix r4504 regression YUV->RGBP bit-depth changing full-scale SSE2/AVX2 bug (exchanged G,B storage)\n- \"Layer\" YUV mul/add/subtract/lighten/darken: refactor chroma placement calculation, allowing SIMD optimization in the main frame processing\n- \"Layer\" YUV/RGBP mul/add/subtract/lighten/darken: refactor function dispatchers, add AVX2 path (LLVM/clangcl recommended)\n- Fix C-only vertical resampling code which added more rounding than needed (regression since pre-3.7.5 20250427)\n- Invert: per-plane processing for planar formats, use C even in AVX2, proper chroma inversion\n- New: AddAlphaPlane opacity parameter\n- New: ResetMask opacity parameter\n- rstdoc: document \"opacity\" in AddAlphaPlane and ResetMask\n- rstdoc: detail Layer \"use_chroma\" and opacity\n- Overlay \"Blend\": more speed, but keep accuracy, use float only where really needed\n- Layer: use YV16 internally for YUY2 (lessen source code bloat)\n\n20260213 3.7.5.r4507 (pre 3.7.6)\n--------------------------------\nFix Layer \"add\" 8 bit, regression in r4504\n\n20260212 3.7.5.r4504 (pre 3.7.6)\n--------------------------------\n* Fix: inaccurate ColorBarsHD 10+ bit values. Now they are derived from the 32-bit float \n  RGB definitions instead of upscaling a 8 bit precalculated YUV value.\n  Fix ColorbarsHD Ramp right side to 100 %White\n* Fix: GreyScale + SSE2 + RGB32 + matrix=\"RGB\" overflow. \n  Rare usage; \"RGB\" matrix (Identity) uses a 1.0 coefficient which exceeds the signed 16-bit \n  SIMD limit of 32767 at 15-bit precision. Added bounds checking to fallback to C-code for any \n  coefficients >= 1.0 or < −1.0.\n* Fix: YUV->RGB limited range matrix accuracy for 10-16 bits.\n* Use a different rounding in matrix coefficient's integer approximation.\n* \"ConvertToPlanarRGB\": ``bits`` parameter: on-the-fly bit-depth conversions to YUV->RGB conversion. \n  - Full range target: 8-16 bits internal calculation is in 32-bit float.\n  - Limited range target: a quicker, bit accuracy optimized integer calculation path.\n* Not Fixed: Speed degradation when in-constructor GetFrame(0) (e.g. frame-property getter) \n  is used. Disable internal Cache object creation. Does not work in complex scripts, preparation \n  is 5-10 min instead of <1 sec. Investigation continues (Issue #476: https://github.com/AviSynth/AviSynthPlus/issues/476)\n* Avoid MTGuard and CacheGuard creation if filter returns one of its clip parameter unaltered.\n* Add some avx2 stuff to Layer and Invert\n* Optimization: Overlay \"Blend\": aarch64 NEON optimization\n\n20260203 3.7.5.r4483 (pre 3.7.6)\n--------------------------------\n* rst documentation update: RGBAdjust https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/corefilters/adjust.html\n* rst documentation update: ColorYUV https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/corefilters/coloryuv.html\n* optimization: add AVX2 TurnLeft/TurnRight/Turn180 (R/L: 1,5-3x speed).\n* optimization: ConvertBits AVX2 integer->float\n* optimization: ConvertToPlanarRGB(A): YUV->RGB add AVX2 (2-3x speed)\n* optimization: ConvertToPlanarRGB(A): YUV->RGB 16 bit: a quicker way (1,5x)\n* Fix: C version of 32-bit ConvertToPlanarRGB YUV->RGB to not clamp output RGB values.\n* ConvertToPlanarRGB(A): add bits parameter to alter target bit-depth.\n* ConvertToPlanarRGB(A): from YUV->RGB full range output: optimized in-process when bits=32, other cases call ConvertBits internally.\n* Fix: Packed RGB conversions altering the bit-depth (e.g. rgb32->ConvertToRGB64() worked always in full range.\n* Add more AVX512 resampler code. (WIP)\n* Add more AVX512_BASE code paths (Resamplers)\n* Build: add _avx512b.cpp/hpp pattern in CMake to detect source to compile with base (F,CD,BW,DQ,VL) flags.\n  However AVX512_BASE itself is set only when AVX512_FAST found.\n  For pre-Ice Lake (older AVX512) systems you can enable it with SetMaxCPU(\"avx512base+\") and get the optimized AVX512_BASE functions.\n* Build: add new architecture z/Architecture  \n\n20260107 3.7.5.r44XX (pre 3.7.6)\n--------------------------------\n  * add AVX512 code path (tuning by DTL2020)\n  \n    - 32-bit float resamplers, verticals; horizontals up to kernel size 16.\n    - 8-16-bit horizontal resamplers,\n\n      - kernel size <= 4 and specific ratios; 300%+ !!\n      - kernel sizes up to 8 and 16 and specific ratios.\n    - 8-16-bit vertical resamplers\n\n20260105 3.7.5.r4430 (pre 3.7.6)\n--------------------------------\n- add AVX512 code path to 8-16-bit horizontal resamplers, having kernel size <= 4 and specific ratios (DTL) 300%+ !!\n- More Aarch64 (ARM64) NEON: \n  - add I8MM and SVE2_1 feature flags\n  - add NEON optimization to TurnLeft/Right/180\n\n\n20251225 3.7.5.r4403 (pre 3.7.6)\n--------------------------------\n- Fix: The `Animate()` function now explicitly clamps interpolated values to ensure they remain \n  strictly between the start and end range. Due to the high precision of 64-bit `double` introduced \n  in v3.7.5, intermediate calculations could slightly exceed the boundary (e.g., 360.00000000000006 \n  when interpolating from 0 to 360.0 in 564 steps), requiring this clamp to prevent out-of-range errors.\n  \n20251223 3.7.5.r4400 (pre 3.7.6)\n--------------------------------\n- Resamplers, horiz. float, add back DTL2020's new quick algorithms for kernel size <= 4. Since MT is not their forte, use the generic resamplers if Prefetch > 1.\n- AVX512 float resampler additions, optimize horizontal (kernelsize <= 8), add code for vertical (DTL2020)\n- Fix an ApplyMessage regression not recognizing '\\n' line ends of Authors.avs (since 20250831)\n\n20251220 3.7.5.r4392 (pre 3.7.6)\n--------------------------------\n- \"Info\": Optimize AVX512 features display, group features, make a bit more compact\n- \"Info\": add L2 cache size display\n- \"SetMaxCPU\": add \"avx512base\" and \"avx512fast\" options to enable/disable AVX512 grouped features. see SetMaxCPU .\n- ARM64 (aarch64) area:\n  - \"Info\": add ARMV8-A features display (NEON, DOTPROD, SVE2)\n  - Add ArmV8-A cpu feature detection (NEON, DOTPROD, SVE2) on ARM64 Windows/Linux/macOS builds. On Windows, only up-to DOTPROD can be detected due to OS limitations.\n  - New CPU flags in cpuid.h and avisynth_c.h: CPUF_ARM_NEON, CPUF_ARM_DOTPROD, CPUF_ARM_SVE2\n  - \"SetMaxCPU\": add \"neon\", \"dotprod\", \"sve2\" options to enable/disable ARM64 (aarch64) features.\n- New CPU flags: cpuid.h and ``avisynth_c.h - added AVX512 group feature flags CPUF_AVX512_BASE and CPUF_AVX512_FAST (Ice Lake, usable AVX-512 since that point). - added many new AVX512 individual feature flags - added ARM64 feature flags CPUF_ARM_NEON, CPUF_ARM_DOTPROD, CPUF_ARM_SVE2 - CPUF_xxxxx flags are now 64 bit, replace enum with constexpr.\n- CMakeLists.txt: avx512 compile flag support for gcc/clang (\"fast\" Ice Lake-like feature set).\n- V12 interface: GetCPUFlagsEx returning 64 bit flags (too many AVX512 subfeatures to fit in 32 bit). C interface: avs_get_cpu_flags_ex. see GetCPUFlagsEx and GetCPUFlags\n- V12 interface: L2 cache size query support. New entry in AvsEnvProperty: AEP_CACHESIZE_L2 (C++), AVS_AEP_CACHESIZE_L2 (C) to query L2 cache size in bytes with IScriptEnvironment->GetEnvProperty(). x86/x64 architecture only for now. See AvsEnvProperty .\n- Refactor CMakeLists.txt:\n  - Correct default of ENABLE_INTEL_SIMD for cross-compiling scenarios (e.g. ARM64 target on x86_64 host) Old logic relied on the host processor: ${CMAKE_SYSTEM_PROCESSOR}\n  - Add back option to compile ARM64 builds with Visual Studio on Windows. On VS2026 even clangcl (LLVM) is supported out-of-box for ARM64 platform, easily cross-compilable way from an x64 machine.\n  - VDubFilter: allow building on Windows only x86/x64 targets (and not for ARM64).\n  - Fix LLVM/clangcl/Intel ICX compile warning: 'WIN32' macro redefined as \"#define WIN32 /D_WINDOWS /W3 /GR /EHsc 1 \", when CMake injects a command-line macro wrongly and thus redefines WIN32 . The fix: converts global add_definitions(\"/D ...\") and other option string magics into per-target target_compile_definitions() and target_compile_options(). Thus removing the accidental injection of ${CMAKE_CXX_FLAGS} into add_compile_options(), and prevents the WIN32 macro redefinition.\n- Change video-framebuffer over-allocation from 16 to 64 bytes. Allocate 64 bytes more than needed for video frame buffer in order to be able to read 64 bytes safely with AVX512 without risking access violation on the last pixels of the frame.\n- rst docs\n  - Update GetCPUFlags, add GetCPUFlagsEx\n  - Update CPU Feature Flags with AVX512 and ARM64 features\n  - Update SetMaxCPU with AVX512 and ARM64 features\n  - Update AvsEnvProperty with L2 cache size entry\n  - Update Russian GPL notice in UTF-8 format\n\n\n20251130 3.7.5.r4356 (pre 3.7.6)\n--------------------------------\n- v12 interface: inform plugins about the effective thread count after Prefetch() via cache hints:\n  * ``CachePolicyHint::CACHE_INFORM_NUM_THREADS`` (C++)\n  * ``AVS_CACHE_INFORM_NUM_THREADS`` (C)\n  See https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/FilterSDK/Cplusplus_api.html#cplusplus-setcachehints\n- Add CPUF_AVX512VNNI to CpuFlags, AVS_CPUF_AVX512VNNI to avisynth_c.h, optimize AVX512 features display in Info()\n- Resamplers: optimize 32-bit float, kernel size <= 4 optimized H resampling by DTL2020\n- Resamplers: optimizer 32-bit float vertical avx2 by DTL2020\n- Update Russian GPL notice in UTF-8 format\n\n20251122 3.7.5.r4335 (pre 3.7.6)\n--------------------------------\n- Fix #462: Report: \"AviSynth scripts don't work in a folder with a Unicode name.\"\n  Plugin autoload folders are internally stored in UTF-8, regardless of which Windows ANSI codepage is set.\n- AddAutoLoadDir is utf8 friendly\n  Script function: new utf8 bool (false) param, force utf8 input even on ANSI-only process\n- ListAutoLoadDirs: new utf8 bool (false) param, force utf8 input even on ANSI-only process\n- AddAutoLoadDir expands the appropriate UTF8-aware folders in windows SCRIPTDIR, MAINSCRIPTDIR, PROGRAMDIR\n- Internal IScriptEnvironment2 AddAutoLoadDir and ListAutoLoadDirs interface assumes utf8 input and output.\n  These macros: USER_PLUS_PLUGINS, MACHINE_PLUS_PLUGINS, USER_CLASSIC_PLUGINS, MACHINE_CLASSIC_PLUGINS\n  are replaced with the relevant registry content (PluginDir and PluginDir+, etc.), which now can contain\n  non-ANSI folder path characters.\n- Overlay: native RGB support for add/subtract\n- Overlay: 32-bit float support for add/subtract\n- Overlay: provide error message when 32-bit float is not supported for the specific mode.\n- rstdoc: update Overlay and change log\n- add Visual Studio 2026's new solution format \".slnx\" to .gitignore\n- rstdoc: add build instructions for Visual Studio 2026\n\n20250831 3.7.5.xxxxx\n--------------------\n\n- Build environment, Interface\n\n  * introduce AVS_RESTRICT to avs/config.h (compiler invariant c++ __restrict)\n  * AVX512: CMake to recognize *_avx512.* file pattern, add compiler specific AVX512 compile flags accordingly (foundation and bw extension assumed)\n  * AVX512 support by conditional define. Define INTEL_INTRINSICS_AVX512 if avx512 modules are enabled (The conditional is undefined for non-intel arch., 32 bit, or for pre MSVC 2019 16.2 (19.22))\n  * add .editorconfig\n  * v12 interface: Global Lock support (https://github.com/AviSynth/AviSynthPlus/issues/444), mainly for plugins using common fftw3 library:\n        env->AcquireGlobalLock, env->ReleaseGlobalLock (C++),\n        avs_acquire_global_lock, avs_release_global_lock (C)\n  * v12 interface: ApplyMessageEx supporting utf8 parameter. \n\n- Bugfixes\n\n  * Fix #448: Resolved an issue where MT_MULTI_INSTANCE filters using relative paths (e.g. \"video.mp4\" or \"../image.png\") failed under Prefetch() when used in imported scripts from different directories. The problem occurred because new thread instances did not inherit the original working directory, causing path resolution to fail. Now, the current directory is captured at filter instantiation and passed to worker threads, ensuring consistent path resolution.\n  * Fix #456: \"Reverse\" corrupts 24-bit audio (https://github.com/AviSynth/AviSynthPlus/issues/456)\n  * Fix BDF font rendering when it contains variable width characters like mixed Latin and CJK. Preparing feature request #446 (https://github.com/AviSynth/AviSynthPlus/issues/446)\n\n- WIP: resampler internals, special cases, avx512\n\n20250427 3.7.5.xxxx\n-------------------\n- SIMD C module added. Non x86 benefits. Integer C code llvm benefits on x86. Float C code benefits even for MSVC.\n- Resizers again. C code, Stepped back float vertical, quicker integer verticals, code integration, etc..\n- How-to-Build on Raspberry Pi 5 with llvm description\n\nGiga-benchmarks. Built and measured at least 1000 times.\n\nBenchmarks.\n\n  SetMaxCPU(\"none\")\n  #SetMaxCPU(\"SSSE3\")\n  #SetMaxCPU(\"AVX2\")\n  ColorbarsHD(200,200, pixel_type=\"YUV444P8\") # P8, P10, P16, PS\n\n  wmul=2 # >1: horizontal resizer test\n  hmul=1 # >1: vertical resizer test\n\n  avs=LanczosResize(width*wmul, height*hmul, taps=16)\n  avsr=z_ConvertFormat(width=width*wmul, height=height*hmul, resample_filter=\"lanczos\", filter_param_a=16)\n  fmtconv=fmtc_resample(w=width*wmul, h=height*hmul, kernel=\"lanczos\", taps=16)\n  avs\n\nFigures in general has no place in source code but it is useful to have a clue \nand see the huge differences between compilers and code variants.\nAlso, only mazochists want to test integer optimization with MSVC (x86). Wasted time.\nUse llvm on Arm, clangcl/llvm on Windows x86.\n\nHorizontals                Hor+Vert    Verticals\n [8]  [10-14]  [16]  [32]  [8]  [10]   [8]  [10-14] [16] [32]\n 177     170    101  208               262   486    417   217    C-RaspberryPi5 gcc 12.2 (code variant)\n 137     469     88  208                                         C-RaspberryPi5 gcc 12.2 (code variant)\n 227     218    147  178                                         C-RaspberryPi5 gcc 12.2 no vector attrib ??! Quicker than vector attrib version gcc not recommended\n 416     611    579  404    128  186   362   609    556   624    C-RaspberryPi5 llvm 14 vector attrib\n  90     185     94  403                                         C-RaspberryPi5 llvm 14 vector attrib + integer madd@H\n 180     182    162          67        213   212    206   639    C-RaspberryPi5 llvm 14 no vector attrib\n1230    1168   1129                                              C-ClangCl SSE2\n1270    1238   1186                   1550  1555   1560  3670    C-ClangCl AVX2\n1051    1126   1102                                              C-Intel ICX 2025 SSE2\n1513    2355   1560 1128                                 1969    C-Intel ICX 2025 SSE4.2  smart madd!\n2173    2620   1804 1283                                         C-Intel ICX 2025 AVX2    3.7.6 old tmp\n1938    2413   1775 1061    442  453  1136  1126   1037  3511    C-Intel ICX 2025 AVX2\n 212     188    187  264     73   64   223   195    198   268    C-MSVC SSE2     3.7.3 code\n 417     463    360                    449   424    384   352    C-MSVC SSE2     3.7.4 code\n 215     215     97  928     79   79   220   744     96  1951    C-MSVC SSE2 \n 201     206     99                                              C-MSVC AVX2 \n 597     631    651                                              C-Intel SSE4.2  3.7.4 code\n1183    1193    889                                              C-Intel AVX2    3.7.4 code\n5600                       2140                                  SIMD-avsresize (AVX2 or AVX512?)\n2260                        840                                  SIMD-fmtconv (16 bit output for 8 bits) \n4578    2614   2560 2250   1490       4220  4534   3887  3570    SIMD-MSVC AVX2 3.7.3 (horizontal was memory-boundary unsafe)\n3631    3505   3221 2344   1291 1354  3804  4466   3855  2260    SIMD-MSVC AVX2 3.7.4 Float vertical regression - no time to finish\n3720    3478   3130 2385   1566 1480  5014  5288   5077  3810    SIMD-MSVC AVX2 + incrementing offsets in V, 20-25% gain in integer verticals\n4730    4612   4233 2487   1390 1471  3792  4476   4380  3942    SIMD-ClangCl AVX2, verticals behind MSVC by surprise\n2373    2181   1893 1306    868  723  2660  2137   2670  1886    SIMD-MSVC SSSE3 + incrementing offsets in V, 20-25% gain in integer verticals\n2294    2979   2595 1460    859  976  2623  2865   2625  1962    SIMD-Intel ICX 2025 SSSE3\n4395    4616   4160 2570   1664 1720  5110  5870   5085  2999    SIMD-Intel ICX 2025 AVX2 Surprisingly slow at vertical float FIXME, slower than C :)\n\n* float has different optimization: 8 pixels 2 coeffs\n** on aarch64 the float benchmarks included a ConvertBits(8) at the end.\n\nNon-x86 platforms are the focus of this comparison, as they lack SIMD optimized paths.\nx86 platforms have their own SIMD optimized paths and do not use C.\n\nCompilers can give totally different results even after some reordering of the code,\nSee gcc aarch64: the 8 bit case dropped to 2/3 speed while 16 bits increased by a factor of 250%\ndepending on where I put a line.\n\nConsiderations for aarch64 (Armv8a, includes neon, e.g. RPi5 with gcc 12.2, llvm 14.0.6)\n- gcc is not recommended, their vectorizer is either broken or not yet ready.\n  Using vector attribute gave slower code.\n- llvm gave consistent fast results.\n- Vertical resampler: aarch64 + GCC, (8-16 bits) the 4-pixel 4-coefficient version performs best.\n\nOn x86 platforms MSVC is unusable regarding integer vectorization, the more the code helps to\nrecognize vectorization patterns the slower assembly it produces, e.g. horizontal resizer AVX2 16 bit: \nMSVC 99 fps, MSVC+clangcl: 1186 fps, Intel+LLVM: 1775 fps. Joke.\n\nMSVC on x86 is only capable of vectorizing 32 bit float code, and even then it is not the fastest.\nThere is no reason to not use clangcl for x86 Visual Studio builds. It comes officially with VS2022 for free.\n\n20250420 3.7.5\n--------------\n\nhttps://avisynthplus.readthedocs.io/en/latest/avisynthdoc/changelist375.html\n\nHotfix release for YtoUV and non-x86 platforms\n\n- CMakeLists.txt: if CMAKE_BUILD_TYPE isn't set, use Release\n- Update build.yml, retire unsupported 20.04, add 24.04\n- Fix an llvm syntax warning.\n- rstdoc: update change log\n- Bump to IF v11.1: Fix AVS_Value 64 bit data member declaration for 64 bit non Intel (X86_X64) systems.\n- rstdoc: open 3.7.5 change log, add Raspberry pi stuff to posix.\n- Fix gcc compilation warning\n- Fix: resizer crash for non-intel (e.g. aarch64), regression in 3.7.4\n- Fix #434: YtoUV crash, regression since 61d2c9a\n- Add pkgconf->cmake detection fallback message for SoundTouch\n- avisynth+_arm64.iss: assorted fixups\n- plugins/CMakeLists.txt: fix VDubFilter build check\n- Remove upx.exe from the source tree\n\n20250324 3.7.4\n--------------\n\n- Released\nhttps://avisynthplus.readthedocs.io/en/latest/avisynthdoc/changelist374.html\nand\nhttps://avisynthplus.readthedocs.io/en/latest/avisynthdoc/FilterSDK/FilterSDK.html#what-s-new-in-the-api-v11\n\n20250323 3.7.3 r4xxx\n--------------------\n\nResizers:\n  - ideas and some code imported from the excellent \"\"fmtconv\" image format converter.\n    (https://gitlab.com/EleonoreMizo/fmtconv) namely edge condition handling and \n    respecting chroma position.\n  - Fix: Resizers chroma shift if not chroma is not center-positioned (respect _ChromaLocation, and \"placement\" parameter)\n    (Until now Avisynth was resizing the chroma with the same center position like luma.)\n  - read \"_ChromaPlacement\" frame property (but not write it)\n  - \"keep_center\" parameter\n  - \"placement\" parameter\n  - Resizers C implementation: more vectorizer compiler friendly code (1.5 - 2.5 speed, still slooow)\n  - Quicker SSE2 horizontal and vertical resizer\n  - Fix possibly memory overread - generally rewritten resizer codebase ==>\n  - [Un-optimization]: minor speed decrease in other resizers' performance, due to healing a hidden \n    possibility which would allow over-addressing the scan-lines and frame buffer. No wonder the old\n    code, which checked nothing, did well. IMHO the code is still quick.\n  - Resizers: allow arbitrary dimensions; the filter \"support\" size does not limit usability, no more\n    \"image height is too small for this resizing method\"-like error messages.\n\n  New Parameters:\n\n  - \"placement\": Specifies chroma placement, with options such as \"auto\", \"mpeg2\", \"center\", etc., \n    similar to ConvertToXXXX and Text. The default is \"auto\", which reads the frame property \n    _ChromaLocation for 420, 422, and 411 formats.\n    The chroma placement is ignored when \"keep_center\" is set to False or in PointResizeFilter.\n    Does not write new _ChromaLocation parameter.\n  - \"keep_center\" (boolean, default: true) \n    If true, the chroma shift from \"placement\" is now considered when resizing chroma.\n    fmtconv mentiones that this must be false for convolution filter use, when no resize and \"force\" is not 0\n\n  The positions of the sampling points are relative to the frame's top/left border in plane coordinates.\n  For reference, the frame border is at 0.5 units of luma from the first luma sampling point, \n  meaning the luma sampling point is at the pixel's center.\n  For more information, visit this link. http://www.mir.com/DMG/chroma.html\n\n  Stupid example\n    ColorBarsHD(1024,768)\n    ConvertToYV16()\n    PropSet(\"_ChromaLocation\", 0) # 0 left\n    ConvertToRGB32()\n    ConvertToYV12(chromaoutplacement = \"left\")\n    propShow()\n    GaussResize(width*3, height*3) # keepc=true, placement=\"auto\"\n    GaussResize(width*3, height*3, placement=\"auto\") # the new default, read frame props\n    GaussResize(width*3, height*3, placement=\"bottom\") #center, top, etc visible differences in chroma\n    GaussResize(width*3, height*3, placement=\"center\") #legacy Avisynth worked like this\n    GaussResize(width*3, height*3, keepc=false) #dont keep pixel center, not even for the luma\n\nAddBorders, LetterBox\n\n  The resizer area is +/- (r + ceil(filter.support())\n  The internal blurring resizers take the chroma placement into account (_ChromaLocation frame prop)\n\n20250314 3.7.3 r4246\n--------------------\n- AddBorders and LetterBox: add transient filtering See :doc:`AddBorders <corefilters/addborders>`.\n- new filter: MultiOverlay. Bulk copy-paste from clips. See :doc:`MultiOverlay <corefilters/multioverlay>`.\n\n20250311 3.7.3 r4241\n--------------------\n- Animate: Custom function option\n- Animate: more precise granularity for integer interpolation, allow 64 bit input\n- Animate: add proper rounding for integer interpolation\n- Resizers: add \"force\" integer parameter to force the resizing process even if Avisynth decided it's not needed\n- GaussResize: add \"b\" and \"s\" parameters See :doc:`Resize Filters <corefilters/resize>`.\n\nMerged Windows on ARM-related fixes:\n- docs: miscellaneous updates for external dependencies guide\n- CMakeLists.txt: use extended policy version requirements\n- Restore AVS_VERSION define\n- plugin/CMakeLists: add CMake detection fallback for SoundTouch\n- buildsystem: restrict use of MSVC to x86(-64) only\n- PluginManager: indent cosmetics for clarity\n- PluginManager: only enable +GCC plugindir registry entries on X86\n- avs/config.h: add defines to separate X86 and ARM Windows variants\n- plugins/CMakeLists.txt: restrict VDubFilter to x86(-64)\n- WinInstaller: add InnoSetup script for Windows on ARM\n- Shibatch: check for GCC or Clang for MulDiv under MinGW\n\n20250309 3.7.3 r4217\n--------------------\nExpr: implement tanf in JisASM\n\n  Benchmark script\n  \n    BlankClip(1000,1280,720,pixel_type=\"Y8\")\n    # swipes the range between -Pi to +Pi\n    s = \"sxr 2 * 1 - 3.14159254 * 1 * tan 10 * 128 +\"\n    # swipes the range between -5Pi to +5Pi\n    # s = \"sxr 2 * 1 - 3.14159254 * 5 * tan 1 0 * 128 +\"\n    a= Expr(s,  optSSE2 = false, optAVX2=false, OptVectorC=False)\n    b= Expr(s,  optSSE2 = false, optAVX2=false)\n    c= Expr(s,  optSSE2 = True, optAVX2=false)\n    d= Expr(s,  optSSE2 = True, optAVX2=True)\n\n    a # or b or c or d\n\n  Results:\n\n                       MSVC Intel ICX LLVM\n    SinglePixel C    :  48   66 [fps]\n    Vector friendly C: 122  175\n    JitASM SSE       :    345  (same for both)\n    JitASM AVX       :    727  (same for both)\n\n\n20250306 3.7.3 r4212\n--------------------\nExpr: Rewrite the C (non-Intel-JIT) path to support vectorization, if the compiler is capable.\n\n    I created this for non-Intel platforms where the (Intel SSE2-AVX2) JIT compiler does not work.\n\n    Even if the compiler is not very advanced (MSVC khhhhmm..) this approach is faster because it \n    has less overhead when interpreting the instruction flow. It processes 16, 8, 4, and 1 floats\n    when handling the horizontal line, taking the largest chunks it can then finishing the rest\n    with the smaller ones.\n\n    Benchmarks (x64 bit). For comparison, I also provide the JIT results. \n\n    Script (optSSE2 = false disables JIT):\n    \n        # Mandelbrot\n        ColorBarsHD()\n        a=\"X dup * Y dup * - A + T^ X Y 2 * * B + 2 min Y^ T 2 min X^ \"\n        b=a+a\n        c=b+b\n        blankclip(width=960,height=640,length=1600,pixel_type=\"YUV420P8\")\n        Expr(\"sxr 3 * 2 - -1.2947627 - 1.01 frameno ^ / -1.2947627 + A@ X^ syr 2 * 1 - 0.4399695 \"\n        \\ + \"- 1.01 frameno ^ / 0.4399695 + B@ Y^ \"+c+c+c+c+c+b+a+\"X dup * Y dup * + 4 < 0 255 ?\",\n        \\ \"128\", \"128\",optSSE2 = false, optAVX2=false) # optVectorC=true default\n\n    MSVC: Microsoft VC, actual VS2022 version.\n    Intel: Intel C++ Compiler 2025 - LLVM based, aka ICX.\n\n    \"Base\" means the instruction set is not specified: SSE2 is the minimum for x64. \n\n    Compiler/Settings                      VectSize  FPS  \n    -------------------------------------- ---------- -----\n    MSVC debug                             1         0.27 \n    Intel (base + optional AVX2 paths)     1         1.01 (! Mixed instruction set support, slow) \n    MSVC Base                              1         1.71 VectorSize=1, not optimal :)\n    MSVC old single variable C:            -         2.82 \n    Intel old single variable C:           -         2.90 \n    MSVC Base                              16        4.47 (initial Proof of Concept version) \n    MSVC AVX2                              16        4.59 (initial PoC version) \n    MSVC Base                              16        5.94 \n    MSVC AVX2                              16        6.04 \n    Intel Base                             16        6.29 (initial PoC version) \n    Intel AVX2 optional AVX512 -Qax:AVX512 16        12.60 (! Mixed instruction set support, slow)\n    Intel Base                             16        14.70 \n    Intel AVX2                             16        19.20 \n    Intel AVX512                           16        20.10 \n    MSVC JIT SSE2                          2x4       59.00 (dual lanes, XMM regs)\n    MSVC JIT AVX2                          2x8       128.00 (dual lanes,YMM regs)\n\n    In this test, where dual processor optimization was enabled, Intel performed poorly (though \n    it still achieved twice the speed of MSVC). It seems that dynamically dispatching code fragments\n    to different instruction sets incurs significant overhead.\n\n    Conclusion: \n    \n    We should better avoid builds mixed-code sets.\n    Since AVX2 has been generally supported for at least ten years, creating a non-mixed \n    AVX2-only compilation is a reasonable enhancement.\n    \n    Looking at the numbers, achieving one-third the speed of the old SSE2 JIT, which we considered \n    fast, is quite impressive. Even x86/x64 users can benefit from this speedup. If the Expr contains\n    specific trigonometric functions (tan, asin, acos, atan) that have no JIT implementation, then \n    Avisynth cannot use JIT and falls back to the C implementation.\n    \n    Expr has now a new debug parameter: bool optVectorC (default true) which C code to run if non-JIT is used.\n\n20250304 3.7.3 r4210\n--------------------\n- New: frame property copy/delete/show name filtering: add wildcard and regex support\n\n  propDelete and propCopy: allow \"*\" wildcard or even regex (start with \"^\", end with \"$\") in property name list\n  propShow: new parameter: \"props\" string or array of string. If given, no \"Number of keys\" header is shown.\n\n  propShow() # display all properties, with header\n  propShow(props=\"*\", align=2) # display all properties, no header, bottom center\n  propShow(props=\"_*\", align=8) # display properties starting with \"_\", top center\n  propShow(props=\"^[^_].*$\", align=9) # display properties NOT starting with \"_\", , top right corner\n\n  PropDelete(\"_*\") # deletes all properties starting with \"_\"\n  b=b.PropCopy(a, merge=true, props=[\"*1\",\"*2\"]) # merge props from 2nd clip to 1st, frame props ending with 1 or 2\n\n  https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/syntax/syntax_internal_functions_frame_properties.html\n\n20250302 3.7.3 r4206\n--------------------\n- Change all references to avisynth.org to avisynth.nl (source and doc)\n- Remove the duplicated and outdated FilterSDK htmls from source tree. We have them in rst source.\n- Fix #429 CPU-CUDA transfer would copy less bytes than vfb data_size\n  (Builds with CUDA device support are not official, mainly experimental)\n- C Interface: implement API for all getter/setter/typecheck for AVS_Value\n  Setters are all accept AVS_Value by reference, like avs_set_to_clip did so far. (unlike avs_new_xxx inline helpers, which returns AVS_Value directly)\n  \n  avs_val_defined = avs_defined\n  avs_val_is_xxx = avs_is_xxx\n  avs_set_to_xxx ~ avs_new_value_xxx\n  avs_set_to_void = AVS_void constant direct assignment\n  avs_get_as_xxx = avs_as_xxx\n  avs_get_array_size = avs_array_size\n  avs_get_array_elt = avs_array_elt\n  \n  Example usage:\n  \n      AVS_Value x;\n\n      bool val_b, val_b2;\n      avs_set_to_void(&x);\n      val_b = avs_val_defined(x);\n      printf(\"defined test. defined (no) = %d\\n\", val_b);\n      avs_set_to_double(&x, 1.0);\n      val_b = avs_val_defined(x);\n      printf(\"defined test. defined (yes) = %d\\n\", val_b);\n\n      bool expected_b = true;\n      avs_set_to_bool(&x, expected_b); val_b = avs_val_is_bool(x);\n      printf(\"bool test. is_bool = %d, val (%d) = %d\\n\", val_b, expected_b, avs_get_as_bool(x));\n\n      int expected_i = -12;\n      avs_set_to_int(&x, expected_i); val_b = avs_val_is_int(x);\n      printf(\"int test. is_int = %d, val (%d) = %d\\n\", val_b, expected_i, avs_get_as_int(x));\n\n      int64_t expected_l = 0x80000000ULL; // if int: negative\n      avs_set_to_long(&x, expected_l); val_b = avs_val_is_int(x); val_b2 = avs_val_is_long_strict(x);\n      printf(\"long test. is_int = %d, is_long_strict = %d, val (%\"PRId64\") = %\"PRId64\"\\n\", val_b, val_b2, expected_l, avs_get_as_long(x));\n      avs_release_value(x); // necessary for int64_t (32 bit systems)\n\n      float expected_f = 3.141592653589793f;\n      avs_set_to_float(&x, expected_f); val_b = avs_val_is_float(x); val_b2 = avs_val_is_floatf_strict(x);\n      printf(\"float test. is_float = %d, is_floatf_strict = %d, val (%.16f) = %.16f\\n\", val_b, val_b2, expected_f, avs_get_as_float(x));\n\n      double expected_d = 3.141592653589793;\n      avs_set_to_double(&x, expected_d); val_b = avs_val_is_float(x); val_b2 = avs_val_is_floatf_strict(x);\n      printf(\"double test. is_float = %d, is_floatf_strict = %d, val (%.16f) = %.16f\\n\", val_b, val_b2, expected_d, avs_get_as_float(x));\n      avs_release_value(x); // necessary for double (32 bit systems)\n\n      const char *expected_s = \"Hello\";\n      avs_set_to_string(&x, expected_s); val_b = avs_val_is_string(x); val_b2 = avs_val_is_error(x);\n      printf(\"string test. is_string = %d, is_error = %d, val (%s) = %s\\n\", val_b, val_b2, expected_s, avs_get_as_string(x));\n\n      AVS_Clip *dstclip2;\n      dstclip2 = avs_copy_clip(DestClip);\n      avs_set_to_clip(&x, dstclip2);\n      val_b = avs_val_is_clip(x); val_b2 = avs_val_is_error(x);\n      printf(\"clip test. is_clip = %d, is_error = %d\\n\", val_b, val_b2);\n      AVS_Clip *clipback = avs_get_as_clip(x, Env);\n      avs_release_clip(clipback);\n      printf(\"released clipback\\n\");\n      avs_release_value(x);\n      printf(\"released clip-type AVS_Value\\n\");\n      avs_release_clip(dstclip2);\n      printf(\"released dstclip2\\n\");\n\n      AVS_Value tmp[2]; avs_set_to_int(&tmp[0], 111); avs_set_to_double(&tmp[1], 3.141592653589793);\n\n      // C array\n      AVS_Value args = avs_new_value_array(tmp, 2);\n      // no release, args links directly to C allocated tmp\n      printf(\"len = %d, [0] = %\"PRId64\", [1] = %lf\\n\", avs_get_array_size(args), avs_get_as_long(avs_get_array_elt(args, 0)), avs_get_as_float(avs_get_array_elt(args, 1)));\n      // Avisynth array, array is allocated, elements of tmp are copied\n      AVS_Value args_newarray;\n      avs_set_to_array(&args_newarray, tmp, 2);\n      printf(\"newarr len = %d, [0] = %\"PRId64\", [1] = %lf\\n\", avs_get_array_size(args_newarray), avs_get_as_long(avs_get_array_elt(args_newarray, 0)), avs_get_as_float(avs_get_array_elt(args_newarray, 1)));\n\n      avs_release_value(tmp[0]);\n      avs_release_value(tmp[1]);\n\n      AVS_Value argscopy;\n      avs_copy_value(&argscopy, args_newarray);\n\n      avs_release_value(args_newarray); // necessary for Avisynth allocated arrays\n      printf(\"args_newarray released\\n\");\n\n      printf(\"argscopy len = %d, [0] = %\"PRId64\", [1] = %lf\\n\", avs_get_array_size(argscopy), avs_get_as_long(avs_get_array_elt(argscopy, 0)), avs_get_as_float(avs_get_array_elt(argscopy, 1)));\n\n      avs_release_value(argscopy);\n      printf(\"argscopy released\\n\");\n\n      avs_release_value(args_newarray);\n      printf(\"args_newarray released again (crash!)\\n\");\n\n      avs_release_value(args);\n      printf(\"C array args released (crash!)\\n\");\n\n  Output\n  \n    defined test. defined (no) = 0\n    defined test. defined (yes) = 1\n    bool test. is_bool = 1, val (1) = 1\n    int test. is_int = 1, val (-12) = -12\n    long test. is_int = 1, is_long_strict = 1, val (2147483648) = 2147483648\n    float test. is_float = 1, is_floatf_strict = 1, val (3.1415927410125732) = 3.1415927410125732\n    double test. is_float = 1, is_floatf_strict = 0, val (3.1415926535897931) = 3.1415926535897931\n    string test. is_string = 1, is_error = 0, val (Hello) = Hello\n    clip test. is_clip = 1, is_error = 0\n    released clipback\n    released clip-type AVS_Value\n    released dstclip2\n    len = 2, [0] = 111, [1] = 3.141593\n    newarr len = 2, [0] = 111, [1] = 3.141593\n    args_newarray released\n    argscopy len = 2, [0] = 111, [1] = 3.141593\n    argscopy released\n    (crash) and (crash)\n\n\n20250224 3.7.3 r4198\n--------------------\n- C Interface: Add avs_add_function_r as an alternative to avs_add_function, allowing the callback to \n  return the result via a by-reference AVS_Value parameter instead of returning the AVS_Value as a struct. \n  (Use case from Python)\n\n- Fix #426: TimeStretch named parameter rate not found in a simple\n\n    a=last\n    TimeStretch(a, rate=1.11)\n\n  The erroneous message would be displayed in any function under the following conditions:\n  - The function is autoloaded (with direct LoadPlugin(\"TimeStretch.DLL\") it worked).\n  - Multiple parameter versions exist.\n  - A named argument is provided.\n  - Unnamed parameters are also provided.\n\n20250214 3.7.3 r4193\n--------------------\n\n- Fix: ScriptClip and other runtime functions / frame prop read would crash if called from C or \n  Avs2.5 plugin's IScriptEnvironment, which would happen is there is a C plugin within ScriptClip \n  (Emulgator-RIFE script, thx)\n- Interleave: internal clips - code reorg, I think nothing is affected, but maybe yes (see #386 as well)\n- Fix: audio cache would overflow over int sized count and position differences\n- Fix: \"Info\" overflowed and displayed negative hours/minutes/audio length at longer clips, use int64\n\n20250208 3.7.3 r4178\n--------------------\n- LCase: another fix as needed after 4176 changes\n\n20250207 3.7.3 r4177\n--------------------\n- C header API header fix after the recent big changes\n\n20250207 3.7.3 r4176\n--------------------\n- Fix 20240417 regression: RevStr, UCase, LCase went wrong at string cache introduction\n\n20250206 3.7.3 r4173\n-------------------------\n- API v11: 64 bit long and double\n- 64 bit related changes in script syntax\n- Saturated int and float frame property readers, data type hint (VS API 4 backport)\n- C API: move more inline functions to API\nsee online docs for changes.\n\n20250105 3.7.3 post ??\n----------------------\n- Fix #421: add safety checks to SuperEQ to match SSRC\n- Fix #418: ShowSMTPE/ShowTime alignment - NO_WIN_GDI case (e.g. Posix)\n- Bump year to 2025\n- Posix: Detect additional plugindirs from LD_LIBRARY_PATH environment variable\n- avisynth.h: add ListAutoloadDirs() to internal interface declarations\n- #413 Add ListAutoloadDirs() script function returing a LF delimited string with directory list.\n- Use system installs of DevIL and SoundTouch on all platforms, remove in-tree binaries/code\n- SubTitle to accept real LF (``\\r``) or CR LF (``\\r\\n``) control characters for line break.\n- Fix FadeIn, which behaved like FadeIn2\n- Config: add LOONGARCH support\n- SoundTouch: Increased the max number of channels to 32ch from the old limit of 16ch.\n- Make configurable user plugindir more robust.\n  There was no need for it to use ENV${HOME} in CMakeLists.txt,\n  when the usage of $HOME/.avisynth in the autoload defaults already\n  used a more robust tactic to find the value of $HOME. Switch\n  USER_AVS_PLUGINDIR_LOCATION to the same method.\n- Posix: Detect additional plugindirs from LD_LIBRARY_PATH environment variable\n- #413 Add ListAutoloadDirs() script function. Returns a string with LF (\\n) separated \n  directory list which can be displayed with Text for example.\n- Update plugins section in rst docs.\n- Intel C++ Compiler 2025 support in CMakeList.txt, update compile_avsplus.rst online docs\n\n\n20240417 3.7.3 post ??\n----------------------\n- Add \"ArraySort\" which sorts an 1D array in ascending order. supported types: bool, string and numbers (integers or floating point)\n  Strings are sorted as case sensitive (strcmp).\n  \n    a = [\"banana\", \"apple\", \"lemon\", \"aardvark\"]\n    b = arraySort(a)\n    for (i=1, ArraySize(b)) {\n      SubTitle(Format(\"Element i={i} = {0} \", b[i-1] ), x=0, y=i*20)\n    }\n\n    a = [7, 3.1, 5.1, 4, 7, 9.0]\n    c = arraySort(a)\n    for (i=1, ArraySize(c)) {\n      SubTitle(Format(\"Element i={i} = {0} \", c[i-1] ), x=300, y=i*20)\n    }\n\n- [no upstream commit yet] test build to avoid unwanted growth of memory consumption by recognizing the change in frame access pattern (order of forward/backward)\n  https://github.com/AviSynth/AviSynthPlus/issues/379\n- [no upstream commit yet] accessing frame #0 does not affect prefetch frame access \n  pattern recognition (frame #0 is usually requested for clip-property-like frame \n  properties)\n- [no upstream commit yet] requesting the same frame again does not affect \n  frame access pattern recognition in prefetch procedure\n- Improve:\n  Internal string heap to recognize duplicate string constants and store them only once on the ever-growing Avisynth heap.\n  Primarily prevents adding the same string constants from a ScriptClip in each frame, but helps in the done-once-per-script parsing phase as well.\n  https://github.com/AviSynth/AviSynthPlus/issues/389\n- Fix SetLogParams defaults. Now if parameters are omitted then stderr and LOG_INFO is used as documentation says.\n  mentioned in #391\n- #392 \"break\" and \"continue\" in for-next and while loops\n\n\n20240131 3.7.3 post 14\n----------------------\n- Fix corrupt Turn functions when a planar RGB turn would be followed by a YUV Turn.\n  Regression since TurnXXXX supports planar RGB (2016.08.23; probably since r2081 commit dba954e2de0c9c6218d17fc5c4974f4c28b627c3)\n  See VooDooFX's AvsInPaint problem at https://forum.doom9.org/showthread.php?p=1996653#post1996653\n\n(20240124 3.7.3 post 12)\n- (temporary fix for VS2022 17.8.4 compiler bug)\n- Fix #386: Interleave to call plugin destructor like StackXXXX (memory leak in case if script errors)\n\n(20240118 3.7.3 post 11)\n- Bump year to 2024, yeah :)\n- Fix #384: Planar RGB source ShowBlue and ShowGreen was swapped.\n- rst docs update\n  - Syntax sections\n    - general list\n      https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/overview.html#avisynth-syntax\n    - The full Avisynth grammar, as appears at Avisynth.nl, updated function objects, arrays\n      https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/syntax/syntax_the_full_grammar.html\n    - script variables - escaped string literals\n      https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/syntax/syntax_script_variables.html\n    - control structures if-else, do-while, for-next\n      https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/syntax/syntax_control_structures.html\n    - internal functions (most of its subsections), frame props, debug functions, multithreading\n      https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/syntax/syntax_internal_functions.html\n  - block statements, added if-else, do-while, for-next\n    https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/script_ref/script_ref_block_statements.html\n  - Arrays\n    https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/script_ref/script_ref_arrays.html\n  - Import, refresh, add utf8\n    https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/corefilters/import.html\n  - ShowAlpha/ShowGreen/.. etc.\n    https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/corefilters/showalpha.html\n(20231219 3.7.3 post ??)\n- rst docs: Conditional filters, Runtime functions\n  https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/corefilters/conditionalfilter.html\n  https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/corefilters/conditionalreader.html\n- Fix: allow use of \"local\" in ConditionalSelect string version (fixed wrong function signature)\n- DirectShowSource \"utf8\" bool (default false) parameter to accept filename in utf8 encoding\n- (#366):\n  \"propShow\" add further parameters, like in \"Text\".\n   string \"font\", int \"text_color\", int \"halo_color\", bool \"bold\", float \"x\", float \"y\", int \"align\"\n\n  full signature: c[size]i[showtype]b[font]s[text_color]i[halo_color]i[bold]b[x]f[y]f[align]i\n\n  font default: \"Terminus\" (can also be: \"info_h\")\n  bold default: false\n  x, y default: depending on the \"align\"\n  align default: 7 (top left)  valid values 1-9 (see your numeric keyboard)\n  halo color MSB = FF (e.g. FF000000) -> no outline + semi transparent background\n                   FE (e.g. FE000000) -> outline + semi transparent background\n                   01 (e.g. 01000000) -> no outline + normal display\n                   00 (e.g. 00000000) -> outline + normal display\n\n  propShow(align=1, halo_color=$FF000000)\n  propShow(size=6,bold=true, align=3, halo_color=$FE000000)  \n  propShow(size=16,bold=true, align=5, halo_color=$00000000)\n  propShow(font=\"info_h\", align=9, halo_color=$01000000)\n  See https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/corefilters/propShow.html\n- New: \"Info\" new parameter\n    bool \"cpu\" (true)\n  If set to false, displaying CPU capabilities is disabled\n- Enhancement: \"Info\" displays partially visible lines as well.\n- (#366)\n  \"Info\" new parameters, similar to SubTitle/Text: \n  int \"align\"  (default 7: top left)\n  float \"x\"    (default 4 for top left, screen center or right otherwise)\n  float \"y\"    (default 0 for top left, screen center or bottom otherwise)\n  See https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/corefilters/info.html\n- Fix #368 (https://github.com/AviSynth/AviSynthPlus/issues/368)\n  Make proper vertical alignment for multiline text (containing \"\\n\" and parameter \"lsp\" is defined) \n  in Subtitle and Text when vertical alignment is set to bottom (align=1,2,3) or center (4,5,6).\n  See also https://forum.doom9.org/showthread.php?t=185145\n  Note 1: The \"\\n\" after the last line does not result in an empty bottom line, so both \"Line1\" and \"Line1\\n\" are one-line texts.\n- Fix: \"Text\" use \"lsp\" parameter the same way as in SubTitle: in 1/8 pixel units, not in 1 pixels.\n  Historically \"lsp\" in SubTitle is measured in 1/8 pixels, so \"lsp\"=8 means 1 pixels.\n- Fix: \"Text\" vertical alignment position would be wrong for multiline strings containing even number of lines.\n- Fix #365 (https://github.com/AviSynth/AviSynthPlus/issues/365)\n  Avisynth 2.5 plugins when NICE_FILTER would crash with \"invalid response to CACHE_GETCHILD_AUDIO_MODE\".\n  Bug appeared since reintroducing audio cache in 3.7.3.\n- Fix #370: array size assert error in ConvertToYUY2 when internally ConvertTo422 is called.\n  Reason: ConvertToYUV422 has one more parameter (ChromaOutPlacement) than ConvertToYUY2 has\n- Issues mentioned in #354 https://github.com/AviSynth/AviSynthPlus/issues/354 \n  - Leave _ColorRange frame property as-is, when using matrix names \"PC.709\" or \"PC.601\", \n    for example in ConvertToRGB32.\n    Formerly _ColorRange property would always set to 0 (full range), even if a limited range \n    clip (e.g. ColorBarsHD) was inputted. Now we act as the specification \n    ( http://avisynth.nl/index.php/Convert ) says: \n    \"PC.601 and PC.709 keep the range unchanged, instead of converting between 0-255 RGB \n    and 16-235 YUV, as is the normal practice.\"\n    Now ColorBarsHD().ConvertToRGB32(matrix=\"PC.601\").propShow()\n    would display \"_ColorRange=1 (limited)\", since ColorbarsHD's output is limited as well.\n  - Studio RGB (limited) range will now be recognized (through _ColorRange=1) and utilized in \n    conversions from RGB, such as in GreyScale, ConvertToY, ConvertToYUVxxx (latter fixed in test5).\n    When input or output would require it, rgb offset of 16 (or scaled equivalents) is used \n    for supporting limited range rgb (similar to Y offset=16 used at limited range YUV conversions)\n    (added in post/test4, but a StudioRGB->YUY2 bug was fixed in 3.7.3post test11 20240118)\n\n20230715 3.7.3\n--------------\n- Fix speaker mask storage which accidentally cut off 4 bits  \n**test11**\n- Add \"bold\"=true (linux/NO_WIN_GDI: false), \"italic\"=false, \"noaa\"=false parameters to \n  \"ShowFrameNumber\", \"ShowCRC32\", \"ShowSMPTE\", \"ShowTime\" filters.\n  As noted below, \"italic\" and \"noaa\" parameters are ineffective in NO_WIN_GDI builds (e.g. Linux)\n- Add \"noaa\" parameter to SubTitle and Info. Setting it true will disable antialiasing.\n  Useful when someone would use \"VCR OSD Mono\" as-is, without beautifying the outlines,\n  as it as mentioned in https://forum.doom9.org/showthread.php?t=184627\n- Address #358, plus \"noaa\"\n  - add \"bold\", \"italic\" and \"noaa\" boolean parameters to \"SubTitle\" and \"Info\"\n  - add \"italic\" and \"noaa\" boolean parameter to \"Text\" (\"bold\" already existed)\n    \"italic\" and \"noaa\" is provided only to match the parameter list with SubTitle.\n\n  SubTitle: to mimic former working method, defaults are \"bold\"=true, \"italic\"=false, \"noaa\"=false\n  Text: \"bold\"=false (as before); \"italic\" is not handled at all, either true or false, it does not affect output. \n        \"italic\" and \"noaa\" parameters exist only because on non-Windows systems \"Subtitle\" is aliased to \"Text\"\n        (Each Subtitle parameter must exist in \"Text\" as well)\n- Fix #360: plane fill wrongly assumed that pitch is rowsize, which is not the case after a Crop\n  It would result in crash e.g. in HistogramRGBParade, when an aligned Crop was immediately followed by a GreyScale().\n- Enhancement: much quicker YV24 to RGB32/RGB24 conversion when AVX2 instruction set is supported. (+50% fps at i7-11700)\n- UserDefined2Resize got an 's' parameter (to the existing b and c): support, default value = 2.3\n  (following DTL2020's addition in jpsdr's MT resizer repo, UserDefined2ResizeMT filter)\n  \n  Now, as we have already three variable parameters to the optional chroma resamplers in ConvertToXX \n  converters, ConvertToXX family got a new float 'param3' parameter which is passed to UV resizer as \n  's', if \"userdefined2\" is specified as chroma resampler.\n  If param3 is not used in a resizer but is defined, then it is simply ignored.\n  Such as \"ConvertToYV24\" parameter signature: c[interlaced]b[matrix]s[ChromaInPlacement]s[chromaresample]s[param1]f[param2]f[param3]f\n  e.g.: ConvertToYV24(chromaresample=\"userdefined2\", param1=126, param2=22, param3=2.25)\n  \n  see also description at **test6**, which was updated with this parameter as well.\n  \n  s (support) param - controls the 'support' of filter to use by resampler engine. Float value in valid range from\n  1.5 to 15. Default 2.3. It allows to fine tune resampling result between partially non-linear but more sharper and less\n  residual ringing (at low b and c values) and more linear processing with wider 'peaking' used. Setting too high \n  in common use cases (about > 5) may visibly degrade resampler performance (fps) without any visible output changes.\n  Recommended adjustment range - between 2 and 3.\n  \n  Examples: \n  b=126 c=22 - medium soft, almost no ringing.\n  b=102 c=2 - sharper, small local peaking.\n  b=70 c=-30 s=2 - sharper, thinner 'peaking'.\n  b=70 c=-30 s=2.5 - a bit softer, more thick 'peaking'. \n  b=82 c=20 - sharp but lots of far ringing. Not for using.\n\n- Fix #350 ConvertXXX to accept YV411 clip's frame property _ChromaLocation set to 'left' \n  (and 'topleft' and 'bottomleft' which give the same result) instead of giving an error message.\n- Fix #348 bitrol/bitror functions return incorrect results when first argument is negative.\n  Regression since the asm code of Avisynth 2.6 classic was ported to C in Avisynth+ project.\n- \"Info\": if channel mask exists, then \n  - its friendly name\n  - otherwise the number of channels and the channel combinations\n  is displayed under \"AudioLength: x\".\n\n  e.g.\n  SetChannelMask(\"stereo\") --> \"Channel mask: stereo\"\n  SetChannelMask(\"stereo+LFE\") --> \"Channel mask: 2.1\"  because the combination resulted in another known channel combo name\n  SetChannelMask(\"mono+LFE\") --> \"Channel mask: 2 channels (FC+LFE)\" because the combination is unknown\n\n- Add SetChannel parameter: channel string syntax: (similar to ffmpeg)\n  a channel number followed by \"c\" for getting the default layout for a given number of channels.\n  E.g. SetChannelMask(\"3c\") will set \"2.1\" because this is the default choice for 3 channels\n- Add SetChannel parameter: channel string syntax:\n  a simple number is treated as the actual numeric mask.\n  E.g. SetChannelMask(\"3\") will set \"stereo\" because 3=1+2 that is \"FL+FR\" that is \"stereo\"\n- SetChannelMask string version: If string is other than \"\" then its set to known. It has a single string parameter.\n  SetChannelMask(\"mono\") -> mask is known: \"mono\"\n  SetChannelMask(\"\")  -> mask is unknown\n- Add \"speaker_all\" to accepted layout mask strings\n\n- Fix possible crash of LLVM builds (clang-cl, Intel nextgen) on pre-AVX (SSE4-only) CPUs.\n  (Prevent static initialization from avx2 source modules, which cause running AVX instructions on DLL load)\n- ConvertToMono, GetLeftChannel, GetRightChannel: sets channel layout AVS_SPEAKER_FRONT_CENTER (mono)\n- GetChannel, GetChannels, MergeChannels will set default channel layout if channel count is 1 to 8\n  For defaults see VfW section below\n- New Script function: SetChannelMask: string version. \n\n    SetChannelMask(clip, string ChannelDescriptor) (parameters compulsory, no names must be set) (test10)\n\n  Accepts predefined channel string or channel layout names or their combination, in ffmpeg style.\n  Numerical indexes or channel counts are not allowed.\n  String is case sensitive!\n  E.g. \"stereo+LFE+TC\" or \"FL+LR\" or \"5.1(side)\"\n    \"mono\",\n    \"stereo\",\n    \"2.1\",\n    \"3.0\",\n    \"3.0(back)\",\n    \"4.0\",\n    \"quad\",\n    \"quad(side)\",\n    \"3.1\",\n    \"5.0\",\n    \"5.0(side)\",\n    \"4.1\",\n    \"5.1\",\n    \"5.1(side)\",\n    \"6.0\",\n    \"6.0(front)\",\n    \"hexagonal\",\n    \"6.1\",\n    \"6.1(back)\",\n    \"6.1(front)\",\n    \"7.0\",\n    \"7.0(front)\",\n    \"7.1\",\n    \"7.1(wide)\",\n    \"7.1(wide-side)\",\n    \"7.1(top)\",\n    \"octagonal\",\n    \"cube\"\n    \"speaker_all\"\n  Individual Speaker Channels:\n    \"FL\",  front left\n    \"FR\",  front right\n    \"FC\",  front center\n    \"LFE\", low frequency\n    \"BL\",  back left\n    \"BR\",  back right\n    \"FLC\", front left-of-center\n    \"FRC\", front right-of-center\n    \"BC\",  back center\n    \"SL\",  side left\n    \"SR\",  side right\n    \"TC\",  top center\n    \"TFL\", top front left\n    \"TFC\", top front center\n    \"TFR\", top front right\n    \"TBL\", top back left\n    \"TBC\", top back center\n    \"TBR\", top back right\n    \n- AudioDub will inherit channel layout setting from the audio clip.\n- VfW output channel guess (when ChannelMask is not specified) changed at some points.\n  Default number of channels to channel layout guess was modified to match of ffmpeg\n    3 channels: Surround to 2.1\n    4 channels: Quad to 4.0\n    6 channels: 6.1(back) to 6.1\n  This follows ffmpeg defaults\n  Present rules:\n    const   chnls  name    layout\n    0x00004 1      mono    -- -- FC\n    0x00003 2      stereo  FL FR\n    0x0000B 3      2.1     FL FR    LFE\n    0x00107 4      4.0     FL FR FC --  -- -- -- -- BC\n    0x00037 5      5.0     FL FR FC --  BL BR\n    0x0003F 6      5.1     FL FR FC LFE BL BR\n    0x0070F 7      6.1     FL FR FC LFE -- -- -- -- BC SL SR\n    0x0063F 8      7.1     FL FR FC LFE BL BR -- -- -- SL SR\n\n**test9**\n- Add initial audio channel mask (channel layout) support (CPP and C interface, script function)\n  It still belongs to V10 changes (there were only tests since then), but it can be discussed if not.\n  Technically it is done by using another 18+2 bits in the Clip's VideoInfo.image_type field.\n  Due to lack of enough bits in this VideoInfo field, the mapping between the original dwChannelMask \n  and Avisynth's internal values are not 1:1, but all information is kept however.\n  This is because not 32 but only 18 (strictly: 18+1) bits are defining speaker locations, so\n  the remaining bits of our existing 'image_type' field can be used for this purpose.\n  Thus 20 new bits are occupied.\n  - 1 bit: marks if channel mask is valid or not\n  - 18 bits for the actually defined WAVE_FORMAT_EXTENSIBLE dwChannelMask definitions \n    (https://learn.microsoft.com/en-us/windows/win32/api/mmreg/ns-mmreg-waveformatextensible)\n  - 1 bit for the special SPEAKER_ALL value\n\n  Programmers can check AvsChannelMask and AvsImageTypeFlags in avisynth.h and avisynth_c.h\n\n  - new C++ interface functions\n    - Check for existence:\n        bool VideoInfo::IsChannelMaskKnown()\n    - Setting:\n        void VideoInfo::SetChannelMask(bool isChannelMaskKnown, unsigned int dwChannelMask)\n      Re-maps and stores channel mask into image_type, sets the 'has channel mask' flag as well\n      Note: this data can be set independently from the actual NumChannels number!\n    - Retrieving:\n        unsigned int VideoInfo::GetChannelMask()\n   \n   - new C interface functions\n       bool avs_is_channel_mask_known(const AVS_VideoInfo * p);\n       void avs_set_channel_mask(const AVS_VideoInfo * p, bool isChannelMaskKnown, unsigned int dwChannelMask);\n       unsigned int avs_get_channel_mask(const AVS_VideoInfo * p);\n       \n       Like when establishing BFF, TFF and fieldbased flags from 'image_type', technically 'image_type' can \n       be manipulated directly. See SetChannelMask and GetChannelMask in Avisynth source for \n       image_type <-> dwChannelMask conversion.\n       \n       I guess once ffmpeg will support it, it will read (or not read) channel masks such a way.\n\n   - new Script functions\n       bool IsChannelMaskKnown(clip)\n       int GetChannelMask(clip)\n       SetChannelMask(clip, bool known, int dwChannelMask) (parameters compulsory, no names must be set)\n       SetChannelMask(clip, string ChannelDescriptor) (parameters compulsory, no names must be set) (test10)\n       dwChannelMask must contain the combination of up to 18 positions or 0x80000000 for SPEAKER_ALL.\n\n   VfW export rules (included the existing sequence)\n     1.) OPT_UseWaveExtensible global variable must be 'true'\n         or\n         *new*new*new*\n         if VideoInfo::IsChannelMaskKnown is true, then fill WAVEFORMATEXTENSIBLE struct\n     2.) *new*new*new*\n         Is channel mask defined in Avisynth's VideoInfo? (VideoInfo::IsChannelMaskKnown() is true)\n         Yes -> return VideoInfo::GetChannelMask()\n     3.) No-> (Channel mask not defined in VideoInfo, guess it or set from variable)\n     3.1)Guess channel layout:\n         For 0 to 8 channels there is a predefined 'guess map':\n           #of channels dwChannelMask\n           0            0,\n           1            0x00004, // 1   -- -- Cf\n           2            0x00003, // 2   Lf Rf\n           3            0x00007, // 3   Lf Rf Cf\n           4            0x00033, // 4   Lf Rf -- -- Lr Rr\n           5            0x00037, // 5   Lf Rf Cf -- Lr Rr\n           6            0x0003F, // 5.1 Lf Rf Cf Sw Lr Rr\n           7            0x0013F, // 6.1 Lf Rf Cf Sw Lr Rr -- -- Cr\n           8            0x0063F, // 7.1 Lf Rf Cf Sw Lr Rr -- -- -- Ls Rs\n         \n         For 9-18 channels: \n           sets first 9-18 bits in dwChannelMask\n         Above:\n           SPEAKER_ALL (dword msb bit is 1)\n      3.2) if OPT_dwChannelMask global variable is defined and is different from 0, then use it.\n\n      E.g. VirtualDub2 is using VfW, so after opening the script, ended with SetChannelMask(true, $0063F),\n      one can check the value File|File Info menu, under \"compression\" line (e.g.PCM, chmask 63f).\n      SetChannels does not check against NumChannels, so you can set the 7.1 constant for a stereo\n      if you wish. Microsoft's documentation mentions the cases of what an application can do with \n      less or more than necessary defined speaker bits.\n      \n  - What to do about GetChannels, MixAudio, ConvertToMono? To be discussed.\n    KillAudio will call SetChannelMask(false, 0), nevertheless.\n\n**test8**\n- Set automatic MT mode MT_SERIALIZED to \n  ConvertToMono, EnsureVBRMP3Sync, MergeChannels, GetChannel, Normalize, MixAudio, ResampleAudio\n- Add back audio cache from classic Avisynth 2.6.\n  Believe it or not, audio cache was never ported to Avisynth+\n  - Make use of avisynth.h constants: CACHE_GETCHILD_AUDIO_MODE and CACHE_GETCHILD_AUDIO_SIZE: \n    Filters are queryed about their desired audio cache mode through their SetCacheHints (similarly to CACHE_GET_MTMODE).\n  - Filters can answer CACHE_GETCHILD_AUDIO_MODE with \n    CACHE_AUDIO: Explicitly cache audio, X byte cache.\n    CACHE_AUDIO_NOTHING: Explicitly do not cache audio.\n    CACHE_AUDIO_AUTO_START_OFF: Audio cache off (auto mode), X byte initial cache.\n    CACHE_AUDIO_AUTO_START_ON: Audio cache on (auto mode), X byte initial cache.\n  - Default value is CACHE_AUDIO_AUTO_START_OFF.\n  - Filters can specify the required cache size by returning CACHE_GETCHILD_AUDIO_SIZE.\n    Default cache size is 256kB.\n  - For custom audio cache querying example see EnsureVBRMP3Sync::SetCacheHints in source.\n  How it works: \n  - Modes CACHE_AUDIO_AUTO_START_OFF (default) and CACHE_AUDIO_AUTO_START_ON are automatic modes.\n    The decision whether the stream benefits caching or not - and how big the cache \n    size should be - is made upon continously gathering some statistics on the audio \n    stream requests (an internal score is maintained).\n    - when strict linear reading is detected. why bother with a cache, \n      mode would finally changed to CACHE_AUDIO_AUTO_START_OFF.\n    - When the requests are continously skipping chunks - a cache might not help; \n      go with CACHE_AUDIO_AUTO_START_OFF as well.\n    - When the next sample request is within the cache size, a cache could help: \n      if audio cache was swithed off Avisynth would turn it into active caching by changing \n      the working mode to CACHE_AUDIO_AUTO_START_ON.\n  - Modes CACHE_AUDIO and CACHE_AUDIO_NOTHING are explicitely enable/disable audio cache at a give size.\n\n**test7**\n- Fix Clang build AviSource crash on yuv422p10le UTVideo at specific widths (SSE2 or SSE4.1)\n- #340: stop memory leak on propSet / MakePropertyWritable;\n  A bit less memory/processing overhead in internal FrameRegistry as a side effect.\n- #282: make 32-bit MSVC build to generate both decorated and undecorated export function names for C plugins\n  C plugins built with mingw possibly expect decorated names.\n- Expr: Add remaining stack element count to \"Unbalanced stack...\" error message.\n- #306: Add ConvertToYUVA420, ConvertToYUVA422 and ConvertToYUVA444.\n  Resulting clip is always YUVA:\n  Alpha plane is kept if exists (even from packed RGB formats like RGB32/64), \n  otherwise filled with maximum transparency mask value.\n  Parameters are the same like in ConvertToYUVYUVxxx versions.\n- Update build documentation with 2023 Intel C++ tools. See Compiling Avisynth+ \n  https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/contributing/compiling_avsplus.html\n- CMakeLists.txt: add support for Intel C++ Compiler 2023.\n- Enhanced performance in ConvertBits Floyd dither (dither=1) for 10->8, 16->8 and 16->10 bit cases\n  by providing special function templates to allow compilers to optimize them much better.\n  (Both Microsoft and Intel Classic 19.2 benefits, LLVM based clangCL and IntelLLVM compilers not)\n- Fix crash when outputting VfW (e.g. VirtualDub) for YUV422P16, or P10 in Intel SSE2 optimization\n  due to aligned SIMD write to an unaligned pointer - did not affect Microsoft builds.\n  As seen in https://forum.doom9.org/showthread.php?p=1983343#post1983343\n\n**test6**\n- (#337) Add more resizers types by jpsdr's and DTL's idea: backport from https://github.com/jpsdr/ResampleMT\n  \n  SinPowerResize \"cii[src_left]f[src_top]f[src_width]f[src_height]f[p]f\"\n  parameters like GaussResize: optional \"p\"\n  Default: p=2.5\n  \n  SincLin2Resize \"cii[src_left]f[src_top]f[src_width]f[src_height]f[taps]i\"\n  parameters like SincFilter or LanczosFilter: optional \"taps\"\n  Default taps=15\n  \n  UserDefined2Resize \"cii[b]f[c]f[s]f[src_left]f[src_top]f[src_width]f[src_height]f\"\n  parameters like BicubicResize, plus an 's' - support: Optional \"b\", \"c\" and \"s\"\n  Default b=121.0, c=19.0, s=2.3\n  (\"s\" parameter is available from 3.7.3 test10)\n  \n  and their equivalent for the ConvertToXXXX family:\n  \"sinpow\",  \"sinclin2\" and \"userdefined2\"\n\n  - Add \"param1\", \"param2\" and \"param3\" (since test10) to ConvertToXXXX where \"chromaresample\" parameter exists.\n  Now it is possible to use chromaresample with nondefault settings.\n  \n  param1 will set 'taps', 'b', or 'p', while param2 sets 'c' parameter for resizers where applicable.\n  param3 (since test10) sets 's' parameter for userdefined2 (UserDefined2Resize)\n\n  b,c: bicubic (1/3.0, 1/3.0)\n  b,c,s: userdefined2 (121.0, 19.0, 2.3)\n  taps: lanczos (3), blackman (4), sinc (4), sinclin2 (15)\n  p: gauss (30.0), sinpow (2.5)\n  'param1', 'param2' and \"param3\" are always float. For 'taps' 'param1' is truncated to integer internally.\n  When a resizer does not use one or more parameters they are simply ignored.\n\n**test5**\n- Add avs_video_frame_get_pixel_type and avs_video_frame_amend_pixel_type to C interface as well \n- Fix (#327) Histogram \"color2\" markers. Fix right shifted 15 degree dots, fix square for bits>8\n- Feature (#317): (V10 interface) The color format of a VideoFrame can now be retrieved with its GetPixelType()\n  function. Before, there was no reliable way of knowing it on a frame from propGetFrame().\n  The internally stored pixel_type in VideoFrame is properly converted upon a Subframe (Y8-32), SubframePlanar (strip alpha).\n- Feature (#317): (V10 interface) added ``VideoFrame::AmendPixelType`` and ``avs_video_frame_amend_pixel_type``.\n  Introduced in order to keep VideoInfo and VideoFrame pixel_type synchronized for special cases:\n  when filter constructor would just change ``VideoInfo::pixel_type``, but the frame would be passed w/o any change, like in ``ConvertFromDoubleWidth`` or ``CombinePlanes``.\n- Feature (#314): Added AVSValue::GetType()\n  Returns an AvsValueType enum directly, one can use it instead of calling all IsXXX functions to establish the type. (Rust use case)\n- Enhancement (#314): (avisynth.h) Gave all enums of public C++ API a name, and added DEFAULT_PLANE to AvsPlane (also in C API).\n- Fix (#314): (avisynth.h) Changed NewVideoFrameP() property source argument to const in accordance with copyFrameProps(), since it's not meant to be written\n  Fixed in C interface as well: avs_new_video_frame_p and avs_new_video_frame_p_a: prop_src argument now const (no change in use)\n- Enhancement (#314): Made VideoFrameBuffer destructor public like in other classes of the public API to prevent compiler errors downstream when calling non-const member functions\n- \"Text\" new parameter: \"placement\" for chroma location hint\n  - Used in subsampled YUV formats, otherwise ignored.\n  - Valid values for \"placement\" are the same as in ChromaInPlacement and \n    ChromaOutPlacement in the Convert functions.\n  - Meaningful values: \"center\", \"left\", \"auto\" at the moment\n  - Default value is \n    - read from \"_ChromaLocation\" frame property, otherwise \"left\"\n    - override or set from \"placement\" parameter if parameter is other than \"auto\"\n    - if \"auto\" + have frame property -> use frame property\n    - if \"auto\" + no frame property -> use \"left\"\n    - no frame property and no parameter -> use \"left\"\n  - Only \"center\" and \"left\" is implemented. (center is known as jpeg or mpeg1, left is known as mpeg2)\n    If \"center\" is given directly or read from frame property, it will be used.\n    Otherwise \"Text\" renders chroma as \"left\" (mpeg2)\n- \"Text\": Almost fully rewritten. \n  (#310) Support any width of bdf fonts (but still of fixed width)\n  Render in YUY2 is as nice as in YV16\n  Halo is not limited to original character matrix boundaries\n  Halo is not character based, but rendered on the displayed string as a whole.\n  Some speed enhancements, mainly for subsampled formats and outlined (with halo) styles\n- Enhancement (#315): Show exception message as well if a v2.6-style plugin throws AvisynthError in its\n  AvisynthPluginInit3() instead of only \"'xy.dll' cannot be used as a plugin for AviSynth.\"\n- \"Text\": draw rightmost on-screen character even if only partially visible (was: not drawn at all)\n- \"Text\": support more from the BDF standard (issue #310): per-character boundary boxes and shifts\n- \"Text\" (#310): support 17-32 pixel wide external BDF fonts (issue #310)\n- Fix: \"Text\" rounding negative x or y coordinates (e.g. x=-1 resulted in 0 instead of -1)\n- Fix: \"Text\" would omit last character when x<0\n- Fix: \"Text\" halo_color needs only MSB=$FF and not the exact $FF000000 constant for fade\n- \"Text\" ``halo_color`` allows to have both halo and shaded background when halo_color MSB=$FE\n- \"Text\" much nicer rendering of subsampled formats (#308)\n- CMakeLists.txt: add support for Intel C++ Compiler 2022\n- Address Issue #305: Support for non-decorated avisynth_c_plugin_init in 32 bit C-plugins\n- Huge documentation update by Reel-Deal\n- Fix (#304): ColorYUV analyze=true was displaying wrong min-max values for YUY2\n- Fix: C API undefined behavior when upstream throw runtime error \n  (released in test2, fixed in test6 - ffdshow crash)\n- Mute compilation warnings in avisynth.h\n- CMakeLists.txt: fix clang-cl/intel with ninja generator\n- Fix (#293): \"Text\" to throw proper error message if the specified font name (e.g. Arial) is not found among internal bitmap fonts.\n- Fix (#293): \"Subtitle\" and \"Text\" filter to respect the explicitely given coorditanes for y=-1 or x=-1, \n  instead of applying vertical/horizontal center alignment.\n- Fix: C interface crash when using avs_new_video_frame_p(_a)\n- Fix (#283): broken runtime functions min/max/minmaxdifference when threshold is not 0 (returned -1). Regression in 3.7.2\n- New: add a sixth array element to PlaneMinMaxStats: average. Defines variable \"PlaneStats_average\" as well if setting variables is required.\n- Fix (#282): ConvertToRGB\n  - do check for exact 8 or 16 bit input, because packed RGB formats exist only for 8 and 16 bits\n  - keep alpha for RGBA planar - convert RGBAP8/16 to RGB32/64, while RGBP8/16 is still RGB24/48\n\n20220317 3.7.2\n--------------\n- C interface Win32 access: fix issue by adding V8 interface function names to avisynth.def\n  or else names are decorated (Issue #276) \n  e.g. DLL published _avs_get_frame_props_ro@8 instead of avs_get_frame_props_ro\n- ShowRed/Green/Blue/Alpha/Y/U/V: addition to earlier fixes:\n  When clips are planar and both source and destination format have alpha plane, \n  then it will be copied instead of filled with 255d.\n  Additional checking is done for alpha plane size when ShowU/V, because when\n  source is subsampled the original alpha plane cannot be copied (larger).\n- ConvertBits: \n  Does not get frame 0 in constructor for frame properties if 'fulls' is directly specified. (magiblot)\n  May make script initialization much quicker (Issue #275)\n  https://github.com/AviSynth/AviSynthPlus/issues/275\n- Trim, AudioTrim: bool 'cache' (default true) parameter. \n  Workaround for Issue #274, lower memory consumption but may be slower. \n  Benefits heavily depend on how trimmed clips are used later.\n- Expr: scale_inputs to case insensitive and add floatUV to error message as an allowed value.\n- propCopy: able to specify that the property list is negative.\n    bool \"exclude\" = false # default: \"props\" is positive list\n    \n    propCopy(org,true,props=[\"_Matrix\", \"_ColorRange\"], exclude=false) # merge only two properties\n    propCopy(org,true,props=[\"_Matrix\", \"_ColorRange\"], exclude=true) # merge all, except listed ones\n    propCopy(org,props=[\"_Matrix\", \"_ColorRange\"]) # erase all then copy only selected\n    propCopy(org,props=[\"_Matrix\", \"_ColorRange\"], exclude = true) # erase all, then copy all, except listed ones\n\n- Version()\n  New optional parameters \n\n    int length, int width, int height, string pixel_type, clip c\n\n  Version clip defaults: \n    length=240, width = -1, height = -1 (-1: automatically sized to fit for font size 24)\n    pixel_type = \"RGB24\"\n\n  When 'clip' (a format template) is specified then pixel_type, length, \n  fps data, width and height are defined from it.\n  If any additional 'length', 'width', 'height', 'pixel_type' parameter is given, it overrides defaults.\n  When width and height is given and is <= 0 then it is treated as 'automatic'\n\n  Covers feature request Issue #261\n\n- BlankClip: allow 'colors' with array size more than the number of actual planes.\n  If an array is larger, further values are simply ignored.\n- BlankClip, AddBorders, LetterBox: no A=0 check for non-YUVA\n- Fade filter family new parameters\n    int 'color_yuv' \n    array of float 'colors'\n  similar to BlankClip\n- MergeRGB, MergeARGB\n  - add MergeARGB parameter \"pixel_type\", similar to MergeRGB\n  - accept pixel_type other than packed RGB formats, plus a special one is \"rgb\"\n  - output format is planar rgb(a) (MergeRGB/MergeARGB) when\n    - pixel_type = \"rgb\" or\n    - pixel_type is empty and \n      - either input is planar RGB\n      - either input is different from 8 or 16 bits (no packed RGB formats there)\n    - pixel_type is explicitely set to a valid planar rgb constant e.g. \"RGBP10\"\n  - Accept planar RGB clip in place of input clips and the appropriate color plane is copied from them\n  - Fill alpha channel with zero when MergeRGB output pixel_type format is specified to have an alpha plane\n  - frame property source is the R clip; _Matrix and _ChromaLocation are removed if R is not an RGB clip\n- PropDelete: accept a non-empty array string as list of property names to remove\n  Parameter is not optional, and has no name. It can be either a string (as before) or an array of strings\n    propDelete(\"_Matrix\") # old syntax, still accepted\n    propDelete([\"_Matrix\", \"_ColorRange\"])\n- PropCopy: new string parameter \"props\" as list of property names to remove\n    \"props\": a non-empty array of strings\n    \n    old syntax, still accepted:\n      propCopy(org,true) # merge from all org's properties\n      propCopy(org,false) # erase all then copy all org's properties (exact copy)\n    new syntax\n      propCopy(org,true,props=[\"_Matrix\", \"_ColorRange\"]) # merge\n      propCopy(org,props=[\"_Matrix\", \"_ColorRange\"]) # erase all then copy only selected\n- Histogram Levels: stop using shades of grey on top of bars.\n- Histogram Levels: use bar color 255 for RGB instead of Y's 235. (and scaled eqivivalents)\n- Fix: Histogram \"Levels\": prevent crash when factor=0.0\n- Fix: Histogram \"Levels\": fix regression incorrect \"factor\" applied for U/V part drawing when format was subsampled (non-444)\n  Regression since 20160916 r2666 (commit 986e2756)\n- Histogram \"Audiolevels\" and StereoOverlay to deny planar RGB\n- Histogram \"Luma\": support 10-16 and 32 bits\n- Histogram: give parameter name \"factor\" and type 'float' for Histogram's unnamed optional parameter used in \"Level\" mode.\n  Other modes just ignore this parameter if given.\n- Fix: Histogram \"color\" may crash on certain dimensions for subsampled formats. \n  Regression since 20180301 r2632.\n- Fix: Histogram \"color\" and \"color2\" mode check and give error on Planar RGB\n- Fix: missing Histogram \"color2\" CCIR rectangle top and bottom line (black on black) \n  Regression since 3.6.2-test1 (commit 1fc82f03)\n- Fix: Compare to support 10-14 bits \n  was: factor was always using 65535 (2^16-1) instead of (2^bit depth - 1)\n  was: 16 bit luma/rgb color values were used for drawing graph\n- Fix: Compare\n  'channels' parameter default to \"Y\" when input is greyscale;\n  instead of \"YUV\" which was giving error because of U and V does not exist for this format.\n- ShowRed/Green/Blue/Alpha/Y/U/V\n  - support YUY2 input\n  - support YV411 output\n  - (not changed: ShowU/ShowV may give error for 420, 422 or 411 format outputs when clip dimensions are\n    not eligible for a given output subsampling (check for appropriate mod2 or mod4 width or height)\n  - Copy alpha from source when target is alpha-capable\n  - Fill alpha with maximum pixel value when target is alpha-capable but source ha no alpha component\n  - Delete _Matrix and _ChromaLocation frame properties when needed.\n  - More consistent behaviour for YUV and planar RGB sources.\n    \n    Default pixel_type is adaptive. If none or empty (\"\") is given for pixel_type then target format is\n    - YUV444 when source is Y, YUV or YUVA\n    - RGB32/64 (packed RGB) when source is RGB24/32/48/64\n    - RGBP (planar RGB) when source is RGBP or RGBAP\n\n    When 'rgb' is given for pixel_type then then target format is\n\n    - RGB32/64 (packed) when source is RGB24/32/48/64 - old, compatible way\n    - RGB planar when source is planar RGB(A) or YUV(A) or Y - changed from rgb32/64 because all bit depth must be supported\n\n    When 'yuv' is given (new option!) for pixel_type then then target format is\n\n    - YUV444 for all sources\n\n    Also there is a new option when pixel_type is still not exact, and is given w/o bit depth.\n    pixel_type which describes the format without bit depth is automatically extended to a valid video string constant:\n\n      y, yuv420, yuv422, yuv444, yuva420, yuva422, yuva444, rgbp, rgbap\n\n    Examples:\n\n      32 bit video and pixel_type 'y' will result in \"Y32\"\n      16 bit video and pixel_type 'yuv444' will result in \"YUV444P16\"\n      8 bit video and pixel_type 'rgbap' will result in \"RGBAP8\"\n\n- Fix #263. Escaping double-quotes results in error\n- Allow top_left (2) and bottom_left (4) chroma placements for 422 in colorspace conversions, they act as \"left\" (0, \"mpeg2\")\n  in order not to give error with video sources which have _ChromaLocation set to other than \"mpeg2\"\n  See https://trac.ffmpeg.org/ticket/9598#comment:5\n- Fix: Expr LUT operation Access Violation on x86 + AVX2 due to an unaligned internal buffer (<32 bytes)\n- Fix: Chroma full scale as ITU Rec H.273 (e.g +/-127.5 and not +/-127) in internal converters, ColorYUV and Histogram\n- Fix #257: regression in 3.7.1:  GreyScale to not convert to limited range when input is RGB. Regression in 3.7.1\n  Accepts only matrix names of limited range as it is put in the documentation.\n- Fix #256: ColorYUV(analyse=true) to not set _ColorRange property to \"full\" if input has no such \n  property and range cannot be 100% sure established. In general: when no _ColorRange for input and \n  no parameter which would rely on a supposed default (such as full range for gamma), then an\n  output frame property is not added.\n  When no _ColorRange for input and no other parameters to hint color range then \n  - gamma<>0 sets full range\n  - opt=\"coring\" sets limited range\n  - otherwise no _ColorRange for output would be set\n- Overlay (#255): \"blend\": using accurate formula using float calculation. 8 bit basic case is slower now when opacity=1.0.\n  Higher bit depths and opacity<1.0 cases are quicker.\n  Mask processing suffered from inaccuracy. For speed reasons mask value 0 to 255 were handled\n  as mask/256 instead of mask/255. Since with such calculation maximum value was not the expected 1.0 but rather 255/256 (0.996)\n  this case was specially treated as 1.0 to give Overlay proper results at least the the two extremes.\n  But for example applying mask=129 to pixel=255 resulted in result_pixel=128 instead of 129. This was valid on higher bit depths as well.\n  Note 3.7.2 Test2 has a regression of broken maskless mode for 0<opacity<1 which was fixed in 3.7.2 test 3\n- Fix: Attempt to resolve deadlock when an Eval'd (Prefetch inside) Clip result is \n  used in Invoke which calls a filter with GetFrame in its constructor.\n  (AvsPMod use case which Invokes frame prop read / ConvertToRGB32 after having the AVS script evaluated)\n  Remark: problem emerged in 3.7.1test22 which is trying to read frame properties of the 0th frame in its constructor.\n  A similar deadlock situation was already fixed earlier in Neo branch and had been backported but it did not cover this use case.\n  Note: Prefetch(1) case was fixed in 3.7.2 Test3\n\n20220122 3.7.1a\n---------------\n(no binaries)\n- Update some rst docs\n- Linux: avs_core/CMakeLists: provide version.h and arch.h with installed headers\n- Fix: Histogram AudioLevels half character upshift (regression since v3.6)\n- Bump Copyright year to 2022\n\n20211231 3.7.1\n--------------\n- Bump AVISYNTH_INTERFACE_VERSION to 9, AVISYNTHPLUS_INTERFACE_BUGFIX_VERSION to 0\n- Fix: Debug build does not crash with stack overflow when some 1000+ clips are in filter chain.\n- Fix memory and speed issues when Prefetch was not the last position or there are multiple Prefetch.\n  Thanks to magiblot for reporting the issue and pointing out the possible resolution https://github.com/AviSynth/AviSynthPlus/issues/244\n  Phenomenon: \n  - MT_MULTI_INSTANCE filters were kept multithreaded and instantiated after the Prefetch line.\n    When another Prefetch appeared later, its intended value was not set properly.\n  - MT_MULTI_INSTANCE filters were instantiated in a larger count that the actual Prefetch value.\n    E.g. Prefetch 3 created 4 filter instances, values 4 to 7 were resulting in 8 filter instances\n    and Prefetch 8 to 15 created 16 filter instances, etc.\n    When the filter was memory-allocation heavy (like DepanEstimate which allocates large fftw3 buffers in its constructor)\n    it caused excession memory consumption because unnecessary filter instances were created.\n    For example Prefetch(8) created 16 instances of which 8 was not even used.\n  \n  Fixes:\n  - limit and set proper thread count for 2nd, 3rd.. or no further Prefetch\n  - MT_MULTI_INSTANCE filter instances limited to N (Prefetch value) and not the next power of two N\n\n- CombinePlanes: a bit optimized MergeLuma-like cases. (Dogway's finding)\n  Theory behind: when a frame has exactly one 'user' (no other frames are yet referencing it) then it can \n  directly be grabbed and made writable without any frame plane content copying.\n  When this \"I'm the only one\" condition is fulfilled and the below-written conditions are set then it can be a bit quicker\n  then the ordinary \"make a new frame and copy the referenced input frames into that\" logic works.\n  1.) Source clip has the same format as the target, and the first plane ID is the same.\n      Y comes from first clip (no Y plane copy, the input frame containing Y is reused), U and V are copied\n  2.) Second clip has the same format as the target, and the 2nd and 3rd plane ID is the same\n      U and V comes from 2nd clip (no UV copy, frame containing U and V is reused), \n      while Y (or the given first plane ID) is copied from first clip. When there is a \n\nExample:\n\n    Colorbars(pixel_type=\"YV12\")\n    ConvertBits(16)\n    a=last # UV is kept\n    Blur(1)\n    #luma comes from LAST, a's UV is copied to last\n    x=MergeLuma(a,last)\n    y=CombinePlanes(last,a,planes=\"YUV\",pixel_type=\"YUV420P16\")\n    y  # or x\n    Prefetch(4)\n\n  Comparison: new CombinePlanes and the usual MergeLuma showed ~4600 fps while old CombinePlanes run at only 3540 fps\n\n- Linux: Show more information when dlopen fails\n- Fix: \"Text\" filter would crash when y coord is odd and format has vertical subsampling\n- Working on traditional rst documentation. Filter SDK, Changelog, etc.\n\n- New array modifier function: ArraySet\n\n  For memo here is the list of avaliable array manipulator functions\n  - ArrayAdd - append\n  - ArrayDel - delete at position\n  - ArrayIns - insert before position\n  - ArraySet - replace at position\n\n  ArrayIns\n  ^^^^^^^^\n\n  ArrayIns(array_to_mod, value_to_insert, index1 [, index2, index3...])\n\n      Insert a value into an array or into its subarray.\n      Returns a new array with value_to_insert inserted into array_to_mod (1D array) or array_to_mod[index1 (, index2, index3...)] (multi-dimensional array)\n      The indexes point to the insertion point. Index 0 will insert at the beginning of the array.\n      Index (ArraySize) will insert after the last element (same as ArrayAdd - append)\n      Original array (as with the other functions) remains untouched.\n\n  ArrayAdd\n  ^^^^^^^^\n\n  ArrayAdd(array_to_mod, value_to_append [, index1, index2, index3...])\n\n      Appends value to the end of an array or its subarray\n      Returns a new array with value_to_append appended to array_to_mod (1D array) or array_to_mod[index1 (, index2, index3...)] (multi-dimensional array).\n      Original array (as with the other functions) remains untouched.\n\n  ArrayDel\n  ^^^^^^^^\n\n  ArrayDel(array_to_mod, index1 (, index2, index3...])\n\n      Returns a new array in which the requested position was deleted.\n      Original array (as with the other functions) remains untouched.\n\n  ArraySet\n  ^^^^^^^^\n\n  ArraySet(array_to_mod, replacement_value, index1 [, index2, index3...])\n\n      Returns a new array with array_to_mod[index1 (, index2, index3...)] = replacement_value\n      Original array (as with the other functions) remains untouched.\n\n- Array modifier functions to allow multidimensional subarray indexes\n\nExample:\n\n    ColorbarsHD()\n    # array indexes are zero based\n    a = []\n    a=ArrayAdd(a,[1,2]) # [[1,2]]\n    a=ArrayIns(a,3,0) # [3,[1,2]]\n    a=ArrayAdd(a,\"s1\") # [3,[1,2],\"s1\"]\n    a=ArrayAdd(a,\"s2\") # [3,[1,2],\"s1\",\"s2\"]\n    a=ArrayDel(a,2) # [3,[1,2],\"s2\"]\n    a=ArraySet(a,\"g\",1,0) # [3,[\"g\",2],\"s2\"]\n    a=ArrayAdd(a,\"h\",1) # [3,[\"g\",2,\"h\"],\"s2\"]\n    a=ArrayAdd(a,[10,11,12],1) # append to (1) -> [3,[\"g\",2,\"h\",[10,11,12]],\"s2\"]\n    a=ArrayDel(a,1,3,0) # del from (1,3,0) -> [3,[\"g\",2,\"h\",[11,12]],\"s2\"]\n    a=ArrayAdd(a,\"added\") # [3,[\"g\",2,\"h\",[11,12]],\"s2\",\"added\"]\n    a=ArrayAdd(a,[\"yet\",\"another\",\"sub\"]) # [3,[\"g\",2,\"h\",[11,12]],\"s2\",\"added\",[\"yet\",\"another\",\"sub\"]]\n    x=a[0] #3\n    x=a[1,0] #g\n    x=a[1,2] #h\n    x=a[1,3,1] #12\n    x=a[3] #\"added\"\n    x=a[4,1] #\"another\"\n    SubTitle(\"x = \" + String(x) + \" Size=\" + String(a.ArraySize()))\n\n- Expr: allow auto scaling effect on pixels obtained from relative addressing\n- ConvertBits: ordered dither: possible to dither down with more than 8 bits difference like in\n    Clip16.ConvertBits(8, dither=0, dither_bits=4)\n  Such conversion is made in two phases. First the clip is converted to (dither_bits+8) bits; in the above example it is 12.\n  If the temporary bit depth would be odd (no 9 or 11 bit support in Avisynth+) then it is made even.\n  bit depth that differs in only 8 bits for the target. Then this intermediate clip is converted to the required end target.\n- Quicker ClearProperties and CopyProperties filters (by using MakePropertyWritable instead of MakeWritable).\n- Fix: MinMax runtime filter family: check plane existance (e.g. error when requesting RPlaneMinMaxDifference on YV12)\n- Fix: prevent x64 debug AviSynth builds from crashing in VirtualDub2 (opened through CAVIStreamSynth)\n- ExtractY/U/V/R/G/B/A, PlaneToY: delete _ChromaLocation property. Set _ColorRange property to \"full\" if source is Alpha plane\n- AviSynth interface additions: extend queryable internal environment properties.\n  Since Interface version 8 IScriptEnvironment::GetEnvProperty (Avisynth.h) and avs_get_env_property (avisynth_c.h)\n  interface functions can query some specific internal properties of AviSynth core. Thread count, etc..\n  These are mainly for internal use but some can be useful for plugins and external applications.\n  Each requested property has an identification number, they are found in avisynth.h and avisynth_c.h\n\n  This addition brought new properties to query: host system's endianness, interface version and bugfix subversion.\n  Relevant enum names start with AEP_ (cpp) or AVS_AEP_ (c) (AEP stands for Avisynth Environment Property)\n  \n  Details:\n  \n  AEP_HOST_SYSTEM_ENDIANNESS (c++) AVS_AEP_HOST_SYSTEM_ENDIANNESS (c)\n    Populated by 'little', 'big', or 'middle' based on what GCC and/or Clang report at compile time.\n\n  AEP_INTERFACE_VERSION (c++) AVS_AEP_INTERFACE_VERSION (c)\n    for requesting actual interface (main) version. An long awaited function. \n    So far the actual interface version could be queried only indirectly, with trial and error, by starting from e.g. 10 then\n    going back one by one until CheckVersion() did not report an exception/error code. \n\n    Even for V8 interface this was a bit tricky, the only way to detect was the infamous\n      has_at_least_v8 = true;\n      try { env->CheckVersion(8); } catch (const AvisynthError&) { has_at_least_v8 = false; }\n    method.\n    \n    Now (starting from interface version 8.1) a direct version query is supported as well.\n    Of course this (one or two direct call only) is the future.\n    Programs or plugins which would like to identify older systems still must rely partially on the CheckVersion method.\n\n    CPP interface (through avisynth.h).\n\n      IScriptEnvironment *env = ...\n      int avisynth_if_ver = 6;\n      int avisynth_bugfix_ver = 0;\n      try { \n        avisynth_if_ver = env->GetEnvProperty(AEP_INTERFACE_VERSION); \n        avisynth_bugfix_ver = env->GetEnvProperty(AEP_INTERFACE_BUGFIX);      \n      } \n      catch (const AvisynthError&) { \n        try { env->CheckVersion(8); avisynth_if_ver = 8; } catch (const AvisynthError&) { }\n      }\n      has_at_least_v8 = avisynth_if_ver >= 8; // frame properties, NewVideoFrameP, other V8 environment functions\n      has_at_least_v8_1 = avisynth_if_ver > 8 || (avisynth_if_ver == 8 && avisynth_bugfix_ver >= 1);\n      // 8.1: C interface frameprop access fixed, IsPropertyWritable/MakePropertyWritable support, extended GetEnvProperty queries\n      has_at_least_v9 = avisynth_if_ver >= 9; // future\n\n    C interface (through avisynth_c.h)\n\n      AVS_ScriptEnvironment *env = ...\n      int avisynth_if_ver = 6; // guessed minimum\n      int avisynth_bugfix_ver = 0;\n      int retval = avs_check_version(env, 8);\n      if (retval == 0) {\n        avisynth_if_ver = 8;\n        // V8 at least, we have avs_get_env_property but AVS_AEP_INTERFACE_VERSION query may not be supported\n        int retval = avs_get_env_property(env, AVS_AEP_INTERFACE_VERSION);\n        if(env->error == 0) {\n          avisynth_if_ver = retval;\n          retval = avs_get_env_property(env, AVS_AEP_INTERFACE_BUGFIX);\n          if(env->error == 0)\n            avisynth_bugfix_ver = retval;\n        }\n      }\n      has_at_least_v8 = avisynth_if_ver >= 8; // frame properties, NewVideoFrameP, other V8 environment functions\n      has_at_least_v8_1 = avisynth_if_ver > 8 || (avisynth_if_ver == 8 && avisynth_bugfix_ver >= 1);\n      // 8.1: C interface frameprop access fixed, IsPropertyWritable/MakePropertyWritable support, extended GetEnvProperty queries\n      has_at_least_v9 = avisynth_if_ver >= 9; // future\n \n\n  AEP_INTERFACE_BUGFIX (c++) AVS_AEP_INTERFACE_BUGFIX (c)\n    Denotes situations where there isn't a breaking change to the API,\n    but we need to identify when a particular change, fix or addition\n    to various API-adjacent bits might have occurred.  Could also be\n    used when any new functions get added.\n\n    Since the number is modelled as 'changes since API bump' and\n    intended to be used in conjunction with checking the main\n    AVISYNTH_INTERFACE_VERSION, whenever the main INTERFACE_VERSION\n    gets raised, the value of INTERFACE_BUGFIX should be reset to zero.\n\n    The BUGFIX version is added here with already incremented once,\n    both because the addition of AVISYNTH_INTERFACE_BUGFIX_VERSION\n    itself would require it, but also because it's intended to signify\n    the fix to the C interface allowing frame properties to be read\n    back (which was the situation that spurred this define to exist\n    in the first place).\n\n- CMake build environment:\n  While we do need the compiler to support C++17 features, we can \n  get by on older GCC using CMake 3.6 and -std=c++-1z with some other fixes.\n  CMAKE_CXX_STANDARD can be raised intelligently to 17 based on whether we detect CMake 3.8 or higher.\n- Add AVISYNTHPLUS_INTERFACE_BUGFIX_VERSION\n\n- Avisynth programming interface V8.1 or V9(?)):\n  Add 'MakePropertyWritable' to the IScriptEnvironment (CPP interface), avs_make_property_writable (C interface)\n  Add 'VideoFrame::IsPropertyWritable' (CPP interface), avs_is_property_writable (C interface)\n  (AviSynth interface version will be stepped to V9 in the release version?)\n\n    bool env->MakePropertyWritable(PVideoFrame *);\n    bool VideoFrame::IsPropertyWritable();\n  \n  'MakePropertyWritable' is similar to 'MakeWritable' but it does not copy all bytes of the frame content in order to have a writable property set.\n  \n  Reason: 'propSet' is a filter which does not alter frame content, but sets the given frame property in its each GetFrame.\n  So far it used MakeWritable to obtain a safely modifiable copy of frame properties, however - as a side-effect - full copy of frame content was performed.\n  (env->getFramePropsRW alone does not ensure a uniquely modifiable property set, it just obtains a pointer which can be used in the property setter functions)\n  (Note: frame properties of frames obtained by NewVideoFrame, MakeWritable and SubFrame are still safe to modify)\n- Expr: when actual bit depth is too large for building LUT table, fallback to realtime mode.\n  lut_x 1D (realtime when 32 bit) \n  lut_xy 2D (realtime when 16 or 32 bits)\n- Expr: allow 'f32' as internal autoscale target (was: i8, i10, i12, i14, i16 were accepted, only integers)\n  affects: 'scale_inputs' when \"int\", \"intf\", \"all\", \"allf\"\n  more on that (todo: refresh docs) http://avisynth.nl/index.php/Expr\n- Expr: fix conversion factor (+correct chroma scaling) when integer-to-integer full-scale automatic range scaling was required\n- New: Expr: new parameter integer 'lut'\n  integer 'lut' (default 0)\n    0: realtime expression\n    1: expression is converted to 1D lut (lut_x)\n    2: expression is converted to 2D lut (lut_xy)\n   Valid bit depths: lut=1 : 8-16 bits. lut=2 : 8-14 bits. Note: a 14 bit 2D lut needs (2^14)*(2^14)*2 bytes buffer in memory per plane (~1GByte)\n   In lut mode some keywords are forbidden in the expression: sx, sy, sxr, syr, frameno, time, relative pixel addressing\n- New: ArrayAdd(a, b): appends b to the end of a (a is array, b any value to append)\n  Example:\n    a = []\n    a=ArrayAdd(a,[1,2]) # [[1,2]]\n    a=ArrayIns(a,3,0) # [3,[1,2]]\n    a=ArrayAdd(a,\"s1\") # [3,[1,2],\"s1\"]\n    a=ArrayAdd(a,\"s2\") # [3,[1,2],\"s1\",\"s2\"]\n    a=ArrayDel(a,2) # [3,[1,2],\"s2\"]\n- New: ArrayIns(a, b, n): inserts b into a to position n (a is array, b is the value to insert, n is a zero based index. 0: inserts at the beginning, array_size: inserts after the last element)\n- New: ArrayDel(a, n): removes the n-th element from a (a is array, n is a zero based index, must be a valid index between 0 and arraysize-1)\n- Enhancement: xPlaneMin/Max/Median/MinMaxDifference runtime functions to accept old packed formats (RGB24/32/48/64 and YUY2)\n  (By autoconverting them to Planar RGB or YV16)\n- New runtime function: PlaneMinMaxStats(clip, float \"threshold\", int \"offset\", int \"plane\", bool \"setvar\")\n  Returns an 5-element array with [min,max,thresholded minimum,thresholded maximum,median]\n  Parameters:\n    float 'threshold': a percent number between 0.0 and 100.0%\n    int 'offset': if not 0, they can be used for pulling statistics from a frame number relative to the actual one\n    int 'plane' (default 0): \n         0, 1, 2 or 3 \n         for YUV inputs they mean Y=0,U=1,V=2,A=3 planes\n         for RGB inputs R=0,G=1,B=2 and A=3 planes\n    bool 'setvar' (default false): \n         when true then it writes a global variables named \n        \"PlaneStats_min\" \"PlaneStats_max\" \"PlaneStats_thmin\" \"PlaneStats_thmax\" \"PlaneStats_median\"\n\n  Note: using global variables are thread safe from ScriptClip only when used with 'function'-syntax call with its default 'local'=true\n\n  Example:\n\n  # function-syntax ScriptClip + runtime function call + dedicated global var demo\n  # Here 'local'=true (for the sake of the demo; this is the default for this mode).\n  # 'local'=true makes a dedicated global variable area, in which 'last' and 'current frame'\n  # A function can see only global variables. 'last' and 'current_frame' are available here - they are global variables which were\n  # set by ScriptClip after creating a safe global variable stack.\n  # PlaneMinMaxStats writes five global variables \"PlaneStats_min\", \"PlaneStats_max\", \"PlaneStats_thmin\", \"PlaneStats_thmax\", \"PlaneStats_median\"\n  ScriptClip( function [] () {\n    x=PlaneMinMaxStats(threshold=30, offset=0, plane=1, setvar=true)\n    subtitle(\"min=\" + string(PlaneStats_min) + \" thmax\" + String(PlaneStats_thmax) + \" median = \" + String(PlaneStats_Median) + \" median_too=\" + String(x[4]))\n    } , local = true) \n\n- Language syntax: accept arrays in the place of \"val\" script function parameter type regardless of being named or unnamed. \n  (Note: \"val\" is \".\" in internal function signatures)\n  Example:\n    BlankClip(pixel_type=\"yv12\")\n    r([1, 2, 3])\n    r(n=[10,11,[12,13]])\n    r(\"hello\")\n    function r(clip c, val \"n\")\n    {\n      if (IsArray(n)) {\n       if (IsArray(n[2])) {\n         return Subtitle(c, String(n[2,1]), align=8) #13 at the top\n       } else {\n         return Subtitle(c, String(n[2]), align=2) #3 at the bottom\n       }\n      } else {\n        return Subtitle(c, String(n), align=5) #hello in the center\n      }\n    }\n\n- Histogram \"Levels\": more precise drawing when bit depth is different from histogram's resolution bit depth\n- Expr: no more banker's rounding when converting back float result to integer pixels. Using the usual truncate(x+0.5) rounding method\n- ColorYUV: fix 32 bit float output\n- ColorYUV: More consistent and accurate output across different color spaces, match with ConvertBits fulls-fulld conversions\n- ColorYUV: set _ColorRange frame property\n  levels = \"TV->PC\" -> full\n  levels = \"PC->TV\" or \"PC->TV.Y\" or \"TV\" -> limited\n  levels = (not given) and _ColorRange property exists -> keeps _ColorRange \n  levels = (not given) and no _ColorRange property  -> full range (old default behaviour)\n- ColorYUV: when no hint is given by parameter \"levels\" then use _ColorRange (limited/full) frame property for establishing source range \n  If _ColorRange does not exist, it treats input as full range (old default behaviour)\n  Why: when there is no limited<->full conversion, but gamma is provided then this info is still used in gamma calculation.\n- ColorYUV: fixes for showyuv=true:\n  - fix display when bits=32\n  - \"showyuv_fullrange\"=true case: U and V range is chroma center +/- span (1..max) for integer bit depths instead of 0..max\n    Shown ranges:\n    For bits=8: 128 +/- 127 (range 1..255 is shown) (UV size is 255x255 -> 510x510 image YV12)\n    bits=10: range 512 +/- 511 (UV size is 1023x1023 -> 2046x2046 image YUV420P10)\n    bits=12: range 2048 +/- 2047 (UV size is same as 10 bits 1023x1023 -> 2046x2046 image YUV420P12)\n    bits=14: range 8192 +/- 8191 (UV size is same as 10 bits 1023x1023 -> 2046x2046 image YUV420P14)\n    bits=16: range 32768 +/- 32767 (UV size is same as 10 bits 1023x1023 -> 2046x2046 image YUV420P16)\n    bits=32: range 0.0 +/- 0.5 (UV size is same as 10 bits 1023x1023 -> 2046x2046 image YUV420PS)\n    In general: chroma center is 2^(N-1); span is (2^(N-1))-1 where N is the bit depth\n- propShow: display _Matrix, _ColorRange and _ChromaLocation constants with friendly names\n- Info on Wincows XP compatibility (Microsoft side)\n  Avisynth+ can be build to be XP compatible (VS2019): v141_xp toolset and -Z-threadSafeInit flag.\n  But in order to work, a _compatible_ (=not latest) Visual C++ runtime is still needed (XP support has been stopped by MS meanwhile)\n  As experienced here: https://github.com/AviSynth/AviSynthPlus/issues/241\n  The latest XP compatible version is probably 14.28.29213.0.\n  Links to official installers for last XP compatible Microsoft Visual C++ 2015-2019 Redistributable (version 14.28.29213):\n  x64 - https://download.visualstudio.microsoft.com/download/pr/566435ac-4e1c-434b-b93f-aecc71e8cffc/B75590149FA14B37997C35724BC93776F67E08BFF9BD5A69FACBF41B3846D084/VC_redist.x64.exe\n  x86 - https://download.visualstudio.microsoft.com/download/pr/566435ac-4e1c-434b-b93f-aecc71e8cffc/0D59EC7FDBF05DE813736BF875CEA5C894FFF4769F60E32E87BD48406BBF0A3A/VC_redist.x86.exe \n\n- Expr: new function \"sgn\". Returns -1 when x is negative; 0 if zero; 1 when x is positive\n- Expr: atan2 to SSE2 and AVX2. Up to 20x speed.\n  Reference: https://stackoverflow.com/questions/46210708/atan2-approximation-with-11bits-in-mantissa-on-x86with-sse2-and-armwith-vfpv4\n  max relative error = 3.53486939e-5\n  Its only protection that atan2(0,0) returns 0 instead on NaN.\n\n    ColorbarsHD(pixel_type=\"YUV444PS\")\n    x=ExtractU\n    y=ExtractV\n    clip_C = Expr(x,y,\"y x atan2\", optSSE2=false) # 52 fps\n    clip_SSE2 = Expr(x,y,\"y x atan2\", optAVX2=false) # 484 fps\n    clip_AVX2 = Expr(x,y,\"y x atan2\") # 1000 fps\n    clip_AVX2\n\n  (Hint: in actual AvsPMod you can check actual 16 bit or even float Y-U-V values with its color-picker)\n  \n- Expr: add \"neg\": negates stack top: a = -a\n- Floyd dither (\"dither\"=1)\n  - add native fulls-fulld support, add special chroma handling when full-range = true involved\n  - valid \"dither_bits\" parameter 1 to 16 (similar to ordered dither)\n  - special handling of low (1-7 bits) \"dither_bits\" => result looks nice, same as at ordered dither\n  - more optimized to frequently used source and dither target bits differences: 2,4,6 and 8\n    (covers typical 16->8, 10->8, 16->10 bit conversions; others have ~-10% speed, less than 8 bit targets are -20-25% )\n- (fix YV411 to and from conversion - regression since recent chroma placement addition)\n- ConvertBits: Support YUY2 (by autoconverting to and from YV16), support YV411\n- ConvertBits: \"bits\" parameter is not compulsory, since the dit depths can stay as it was before. One can call like ConvertBits(fulld=true)\n- ConvertBits: \"dither\" parameter: type changed to integer. Why was it float? :) valid values were 0 and 1\n- ConvertBits: source: dither almost full refactor\n- ConvertBits: allow dithering down from 8 bit sources (use case: specify parameter \"dither_bits\" less than 8)\n  Example: My8bitVideo.ConvertBits(8, fulls=true, fulld=true, dither = 0, dither_bits=1)\n- ConvertBits: ordered dither (dither_type=0) new features\n  - add AVX2\n  - allow odd dither_bits values, 1-16 bits (was: 2,4,6,8,..). The difference is still maximum 8, so dither_bits=1 is available\n    only for 8 bit sources. (memo: for Floyd (dither=1) the minimum remained 0, allowed range is 0-16)\n  - correct conversion of full-range chroma at 8-16 bits, keeping center\n  - fulls-fulld mix support (conversion - if any - happens before dithering)\n  - when dither target bitdepth is less than 8, then special measures are taken in order to show 'nice' output;\n    using dither_bits=1 would be especially ugly without this. (dither table is treated as signed float, autocorrect levels)\n    Why autocorrect? Ordered dither produces (2^dither_bits) different pixel values.\n    e.g. dither_bits=1 results in pixel values 0 and 1; dither_bits=2 => 0 to 3, and so on, dither_bits=7 => 0 to 127\n    When these dithered pixel values are scaled back to 8 bits, Avisynth stretches the upper extremes to 255 (8 bit case).\n    At dither_bits=1 instead of 0, 128 we get 0 and 255. Or at dither_bits=2 the values 0, 64, 128, 192 are translated to 0, 85, 170, 255.\n    Note: for low dither targets RGB definitely looks better.\n\n- Use _Matrix name \"bt470m\" for value=4 (\"fcc\" is still kept)\n  Source: Rename AVS_MATRIX_FCC to AVS_MATRIX_BT470_M \n- ConvertBits: Correct conversion of full-range chroma at 8-16 bits, keeping center (32 bit float was O.K.) (ditherless case)\n- ConvertBits: Direct, much quicker conversions between 8-16 bit formats when either source or target is full range, avx2 support (ditherless case)\n               Special even quicker case: 8->16 bit fulls=true, fulld=true (simply *257)\n- ConvertBits: Fix: fulls=true->fulld=true 16->8 bit missing rounding\n- CMake/source: Intel C++ Compiler 2021 and Intel C++ Compiler 19.2 support\n  With the help of CMake GUI:\n  - Generator: \"Visual Studio 16 2019\"\n  - Optional toolset to use (-T option): (type to the editbox)\n    For LLVM based icx: Intel C++ Compiler 2021\n    For classic 19.2 icl: Intel C++ Compiler 19.2\n  - Specify native compilers (choose radiobutton),\n    then browse for the appropriate compiler executable path. For example:\n    icx: C:\\Program Files (x86)\\Intel\\oneAPI\\compiler\\latest\\windows\\bin\\icx.exe\n    icl: C:\\Program Files (x86)\\Intel\\oneAPI\\compiler\\latest\\windows\\bin\\intel64\\icl.exe\n  There are some bugs in the Intel-VS integration: \n  If you have errors like \"xilink: : error : Assertion failed (shared/driver/drvutils.c, line 312\" then\n  as a workaround you must copy clang.exe (by default it is located in C:\\Program Files (x86)\\Intel\\oneAPI\\compiler\\latest\\windows\\bin)\n  to the folder beside xilink (for x64 configuration it is in C:\\Program Files (x86)\\Intel\\oneAPI\\compiler\\latest\\windows\\bin\\intel64).\n- CMake/source: Intel C++ Compiler 2021 and Intel C++ Compiler 19.2 support\n- ConvertBits: allow dither from 32 bits to 8-16 bits (through an internal 16 bit intermediate clip)\n- ConvertBits: allow different fulls fulld when converting between integer bit depths\n- ConvertBits: allow 32 bit to 32 bit conversion\n\n    ColorbarsHD()\n    # another method for converting to full range\n    ConvertToRGB(matrix=\"709:f\")\n    ConvertToYUV444(matrix=\"709:l\")\n    # 8 to 32 bits\n    ConvertBits(32, fulls=true, fulld=false)\n    ConvertBits(32, fulld=true) # fulls=false: auto from frame prop _ColorRange\n    ConvertBits(8, fulld=false, dither = 1, dither_bits=1) # low dither_bits just for fun :)\n    Histogram(\"levels\")\n\n- Expr: consume less bytes on stack. 48x Expr call in sequence caused stack overflow\n- frame property support: _ChromaLocation in various filters (e.g. ConvertToYUV422)\n  New location parameter values: \"top\", \"bottom_left\", \"bottom\", \"auto\"\n  \"ChromaInLocation\" rules:\n  - if source has _ChromaLocation frame property it will be used else the default is \"mpeg2\" (\"left\")\n  - if parameter is \"auto\" or not given at all, ChromaInLocation will be set to the above mentioned default value\n  - if parameter is explicitely given, it will be used\n  \"ChromaOutLocation\" rules:\n  - default is \"mpeg2\" (\"left\")\n  - if parameter is \"auto\" or not given at all, ChromaOutLocation will be set to the above mentioned default value\n  - if parameter is explicitely given, it will be used\n  \n  Accepted values for \"ChromaInLocation\" and \"ChromaOutLocation\" (when source/target is a chroma subsampled format)\n  (full list):\n  - \"left\" or \"mpeg2\"\n  - \"center\" or \"jpeg\" or \"mpeg1\"\n  - \"top_left\"\n  - \"dv\"\n  - \"top\" \n  - \"bottom_left\"\n  - \"bottom\"\n\n  _ChromaLocation constants - as seen in propShow()\n  \n  AVS_CHROMA_LEFT        = 0\n  AVS_CHROMA_CENTER      = 1\n  AVS_CHROMA_TOP_LEFT    = 2 (4:2:0 only)\n  AVS_CHROMA_TOP         = 3 (4:2:0 only)\n  AVS_CHROMA_BOTTOM_LEFT = 4 (4:2:0 only)\n  AVS_CHROMA_BOTTOM      = 5 (4:2:0 only)\n  AVS_CHROMA_DV          = 6  Special to Avisynth\n\n  _ChromaLocation property will be cleared when the result clip is not a chroma subsampled format (4:4:4 or RGB)\n\n- frame propery support: preliminary _Matrix and _ColorRange in various filters\n \n  Summary:\n\n  _Matrix constants - as seen in propShow()\n\n  AVS_MATRIX_RGB            0\n  AVS_MATRIX_BT709          1\n  AVS_MATRIX_UNSPECIFIED    2\n  AVS_MATRIX_BT470_M        4 (instead of AVS_MATRIX_FCC)\n  AVS_MATRIX_BT470_BG       5 (BT601)\n  AVS_MATRIX_ST170_M        6 (practically same as 5)\n  AVS_MATRIX_ST240_M        7\n  AVS_MATRIX_YCGCO          8 (not supported by internal converters)\n  AVS_MATRIX_BT2020_NCL     9\n  AVS_MATRIX_BT2020_CL      10 (same as 9)\n  AVS_MATRIX_CHROMATICITY_DERIVED_NCL 12 (not supported by internal converters)\n  AVS_MATRIX_CHROMATICITY_DERIVED_CL  13 (not supported by internal converters)\n  AVS_MATRIX_ICTCP          14 (not supported by internal converters)\n\n  _ColorRange constants:\n\n  AVS_RANGE_FULL    = 0\n  AVS_RANGE_LIMITED = 1\n\n  string \"matrix\" parameter possible values and their mapping (used in YUV-RGB converters)\n\n  \"rgb\"          AVS_MATRIX_RGB\n  \"709\"          AVS_MATRIX_BT709\n  \"unspec\"       AVS_MATRIX_UNSPECIFIED\n  \"170m\"         AVS_MATRIX_ST170_M\n  \"240m\"         AVS_MATRIX_ST240_M\n  \"470bg\"        AVS_MATRIX_BT470_BG\n  \"fcc\"          AVS_MATRIX_BT470_M\n  \"bt470m\"       AVS_MATRIX_BT470_M\n  \"ycgco\"        AVS_MATRIX_YCGCO      not supported\n  \"2020ncl\"      AVS_MATRIX_BT2020_NCL\n  \"2020cl\"       AVS_MATRIX_BT2020_CL  same as 2020ncl\n  \"chromacl\"     AVS_MATRIX_CHROMATICITY_DERIVED_CL  not supported\n  \"chromancl\"    AVS_MATRIX_CHROMATICITY_DERIVED_NCL not supported\n  \"ictcp\"        AVS_MATRIX_ICTCP      not supported\n  \"601\"          AVS_MATRIX_BT470_BG   compatibility alias\n  \"2020\"         AVS_MATRIX_BT2020_NCL compatibility alias\n\n  the above \"matrix\" parameters can be followed by a \"full\" or \"f\" and \"limited\" or \"l\" or \"auto\" marker after a \":\"\n  e.g. \"709:f\" means the same as the old \"PC.709\"\n  When there is no limited-ness marker, or is set to \"auto\" then value of _ColorRange frame property is used\n\n  old-style \"matrix\" parameters are kept, their name indicate the full/limited\n  For memo and the similar new string\n  \"rec601\" same as         \"170m:l\"\n  \"rec709\"                 \"709:l\" \n  \"pc.601\" and \"pc601\"     \"170m:f\"\n  \"pc.709\" and \"pc709\"     \"709:f\" \n  \"average\"                - kept for compatibility, really it has no standard _Matrix equivalent\n  \"rec2020\"                \"2020cl:l\"\n  \"pc.2020\" and \"pc2020\"   \"2020cl:f\"\n  \n- RGB<->YUV (YUY2) conversions: frame property support _Matrix and _ColorRange\n  Unlike smart external plugins, in Avisynth there is a single \"matrix\" parameter,\n  since the function names explicitely tell whether we are converting from RGB or to RGB.\n\n  New: additional \"matrix\" parameter values: see table above.\n  With a new syntax \"170m\", \"240m\", \"bt470m\" are newly available matrixes.\n  New-style matrix name can be: \n    matrix name\n  or\n    matrix name : full_or_limited_marker\n  \"auto\" can appear on before and after the \":\" character, e.g. \"auto:full\" will take matrix from frame property or default\n  When converting to RGB the _Matrix parameter is set to 0 (\"rgb\")\n- ConvertBits: frame property support: _ColorRange \n  When parameter \"fulls\" is not specified, whether the source clip is full or limited is decided on _ColorRange frame property.\n  When no property available, then RGB clips are treated as fulls=true, while YUV are fulls=false.\n  If not specified, \"fulld\" parameter will inherit the value of the established fulls\n- ColorBars: frame property support: writes _Matrix and _ColorRange. \n  RGB: _ColorRange = 1 (\"limited\") - ColorBars is using studio RGB values\n       _Matrix = 0 (\"rgb\")\n- ColorBarsHD: frame property support:\n        _ColorRange = 1 (\"limited\"), _Matrix = 1 (\"709\")\n- BlankClip: frame property support:\n   RGB: _ColorRange = 0 (\"full\"), _Matrix = 0 (\"RGB\")\n   YUV: _ColorRange = 1 (\"limited\"), _Matrix = 6 (\"170m\") aka old Rec601\n\n- Fix: Planar RGB 32 bit -> YUV matrix=\"PC.709\"/\"PC.601\"/\"PC.2020\" resulted in greyscale image\n- New function: propCopy(clip, clip [,bool 'merge'])\n  Copies the frame properties of the second clip to the first.\n  Parameter 'merge' (default false):\n    when false: exact copy (original target properties will be lost)\n    when true: keeps original properties, appends all parameters from source but overwrite if a parameter with the same name already exists.\n- xxxPlaneMin xxxPlaneMax, xxxPlaneMinMaxDifference:\n  - 32 bit float formats: when threshold is 0 then return real values instead of 0..1 (chroma -0.5..0.5) clamped histogram-based result\n  - for threshold 0 they also became a bit quicker for 8-16 bit formats (~10% on i7-7700)\n- Allow propGetXXX property getter functions called as normal functions, outside runtime\n  By default frame property values are read from frame#0 which index can be overridden by the offset parameter\n\n  Example:\n    Colorbars()\n    PropSet(last, \"hello\", 1) # Set to 1 for all frames\n    # Override to 2 with runtime function except for frameNo=1\n    ScriptClip(\"\"\"if(current_frame!=1) {propSet(\"hello\",2)}\"\"\")\n    n0 = propGetInt(\"hello\") # same as propGetInt(\"hello\",offset=0)\n    # or get the frame property from the Nth frame\n    n1 = propGetInt(\"hello\",offset=1)\n    n2 = propGetInt(\"hello\",offset=2)\n    # n0 and n2 is 2 (overridden in runtime)\n    # n1 will be 1 (keeps global setting)\n    SubTitle(\"n0/n1/n2=\" + \"{n0}/{n1}/{n2}\".Format)\n\n- Add parameter string \"ChromaOutPlacement\" in ConvertToYV16 and ConvertToYUV422 similar to YV12/420 conversions\n  4:2:2 conversions now allow ChromaInPlacement and ChromaOutPlacement parameters\n  \"left\" (\"mpeg2\") and \"center\" (\"mpeg1\", \"jpeg\").\n  Note 1: \"top_left\" and \"dv\" is still valid only for 4:2:0\n  Note 2: \"mpeg2\" (sale as \"left\") was so far the default for 4:2:0 and 4:2:2 sources as well.\n- Source code: use common YUV-RGB conversion matrix values and generation throughout the project\n  Was: constants and calculations and inline code here and there.\n  New: YUY2 RGB conversions now allow matrix \"PC.2020\" and \"Rec2020\" (as a side effect)\n- 4:2:0 conversions: ChromaInPlacement and ChromaOutPlacement parameters: (see http://avisynth.nl/index.php/Convert)\n  add \"top_left\" (new)\n  add \"center\" and \"jpeg\" (as an alternative to \"mpeg1\"), \"left\" (as an alternative to \"mpeg2\")\n- Expr: sin and cos SIMD acceleration (SSE2 and AVX2) port from VapourSynth (Akarin et al.)\n- SelectRangeEvery: experimental fix on getting audio part (TomArrow; https://github.com/AviSynth/AviSynthPlus/issues/232)\n- Expr: implement atan2(y,x). \"yvalue xvalue atan2\"\n  Similarly to other trigonometric functions, function is C-only at the moment, SIMD acceleration is disabled when used in an expression.\n  Returns values in the range -PI .. +PI (see C++ std::atan2 rules)\n- Expr: allow x.framePropName syntax (Akarin's idea)\n  Where x is the usual clip identifier letter, and after the . is the name of the frame property.\n  Nonexistent or non-number frame properties return with 0.0 value\n  Example (increasing brightness until frame nunmber 255)\n    ColorbarsHD()\n    ScriptClip(\"\"\"propset(\"medi\", current_frame)\"\"\")\n    expr(\"x.medi\",\"\",\"\")\n\n- More checks on array parameters in user defined functions.\n  Array-typed parameters with \"name\" have the value \"Undefined\" when they are not passed.\n  Note: but the value is defined and is a zero-sized array if the parameter is unnamed, like in other Avisynth functions.\n\n  Warning for resolving parameter handling for array of anything parameter when array(s) would be passed directly.\n  Memo:\n  - Avisynth signature: .+/.*\n  - Script function specifier val_array or val_array_nz\n\n  When parameter signature is array of anything (.+/.*) and the\n  parameter is passed unnamed (even if it is a named parameter) then\n  there is an ambiguos situation.\n  Example:\n    1,2,3 will be detected as [1,2,3] (compatibility)\n    1 will be detected as [1] (compatibility)\n    (nothing) will be detected as [], but marked in order to override it later directly by name\n  Following the rule:\n    Passing there a direct script array [1,2,3] will be detected as [[1,2,3]], because unnamed and untyped parameters are\n    put together into an array, which has the size of the list. This is a list of 1 element which happens to be an array.\n    Avisynth cannot 'guess' whether we want to define a single array directly or this array is the only one part of the list.\n    [1,2,3] or [ [1,2,3] ]\n  Syntax hint:\n    When someone would like to pass a directly specified array (e.g. [1,2,3] instead of 1,2,3) to a .+ or .* parameter\n    the parameter must be passed by name!\n    Because of the existing avisynth syntax rule: arguments given as unnamed in the place of an array-of-anything parameter\n    are considered to be list elements from which Avisynth creates an array\n\n    function foo(val_array \"n\")\n      Call                          n\n      foo()                   O.K.  Undefined\n      foo(1)                  O.K.  [1] (compatible Avisynth way)\n      foo(1,2,3)              O.K.  [1,2,3] (compatible Avisynth way)\n      foo([1,2,3])            !     [[1,2,3]] (compatible Avisynth way)\n      foo([1,2,3],[4,5])      !     [[1,2,3],[4,5]] (compatible Avisynth way)\n      foo(n=[1,2,3])          O.K.  [1,2,3]\n      foo(n=[[1,2,3],[4,5]])  O.K.  [[1,2,3],[4,5]]\n      foo(n=[])               O.K.  []\n      foo(n=\"hello\")          Syntax error, \"hello\" is not an array\n\n      // unnamed signature\n    function foo(val_array n)\n      Call                          n\n      foo()                   O.K.  [] (defined and array size is zero) Avisynth compatible behaviour\n\n- New: script functions now supports avisynth function array signature '+' (one or more) with _nz type suffix.\n  Previously only '*' style (zero or more) was supported by the original naming.\n  E.g.: val_array -> .* val_array_nz -> .+, int_array -> i* int_array_nz -> i+\n  Others: bool_array_nz, float_array_nz, string_array_nz, clip_array_nz, func_array_nz.\n- Fix: Overlay \"blend\" 10+ bit clips and \"opacity\"<1 would leave rightmost non-mod8 (10-16 bit format) or non-mod4 (32 bit format) pixels unprocessed.\n- Fix: Overlay \"blend\" with exactly 16 bit clips and \"opacity\"<1 would treat large mask values as zero (when proc>=SSE4.1)\n- Parser: proper error message when a script array is passed to a non-array named function argument\n  (e.g. foo(sigma=[1.1,1.1]) to [foo]f parameter signature)\n- Expr: allow arbitrary variable names (instead of single letters A..Z), up to 256 different one. \n  Do not use existing keywords.\n  Variable names must start with '_' or alpha, continued with '_' or alphanumeric characters.\n- Expr: add 'round', 'floor', 'ceil', 'trunc' operators (nearest integer, round down, round up, round to zero)\n  Acceleration requires at least SSE4.1 capable processor or else the whole expression is running in C mode.\n- Fix: Expr: wrong constant folding optimization when ternary operator and Store-Only (like M^) operator is used together.\n  For the expression \"sxr 0.5 < 128 192 M^ 255 ?\" the expected result must be the same as for \"sxr 0.5 < 128 255 ?\"\n  Since 192 M^ is no-op regarding the expression parts.\n- Recognize \\' and \\b and \\v in escaped (e\"somethg\") string literals (see http://avisynth.nl/index.php/The_full_AviSynth_grammar#Literals)\n- Expr: allow TAB, CR and LF characters as whitespace in expression strings\n- Enable propSet to accept Clips from function type input, add propSetClip for direct parameter\n  Enable propGet to return Clip, add propGetClip for direct parameter\n  Clip content support for propGetAsArray propSetArray and propGetAll\n- Add \"PC.2020\" to YUV-RGB conversion matrix set\n- ColorBarsHD: use BT.709-2 for +I (Pattern 2), not BT.601\n  These are from the SMPTE RP 219-1:2014, but those are also on Wikipedia now: https://en.wikipedia.org/wiki/SMPTE_color_bars\n  Former values used BT.601 matrix coeff., which is wrong.\n  Also fixed Pattern 1 Green.Y to conform to SMPTE RP 219-1:2014 (133, not 134).\n  ColorBars: fixed studio RGB values for -I and +Q for rgb pixel types\n- Speedup: Overlay mode \"multiply\": overlay clip is not converted to 4:4:4 internally when 420 or 422 subsampled format \n  (since only Y is used from that clip)\n- Speedup: Overlay mode \"multiply\": SSE4.1 and AVX2 code (was: C only)\n  Proper rounding in internal calculations\n\n  SSE4.1: ~1.2-2.5X speed, AVX2: ~2-3.5X speed (i7700 x64 single thread, depending on opacity full/not, mask clip yes/no)\n  # results for opacity:0.2 8/16 bit opacity:1.0 8/16 bit\n  Overlay(last, ovr, mask=mask, mode = \"multiply\", opacity = 0.2 /*or 1.0*/)\n  # 962/562/952/571 # new C\n  # 934/490/1080/596 # old c\n  # 1700/1370/1770/1350 # SSE4.1\n  # 3050/1850/3111/1876 # AVX2\n\n  # with no mask\n  Overlay(last, ovr, mode = \"multiply\", opacity = 0.2 /*or 1.0*/)\n  # 1330/800/2000/830 # new C\n  # 1200/830/2030/1200 # old C\n  # 2400/2055/2400/2060 # SSE4.1\n  # 3900/3000/4100/3220 # AVX2\n\n- Fix: ConvertAudio integer 32-to-8 bits C code garbage (regression in 3.7)\n- ConvertAudio: Add direct Float from/to 8/16 conversions (C,SSE2,AVX2)\n- Fix: ConvertAudio: float to 32 bit integer conversion max value glitch (regression in 3.7)\n- Fix: Crash in ColorBars very first frame when followed by ResampleAudio\n  Colorbars did not tolerate negative audio sample index requests which can happen at the very first frame of ResampleAudio.\n- Fix: frame property access from C interface\n  Unfortunately you cannot access frame properties with version <= 3.7, it will crash in those releases.\n\n  Test sequence:\n  \n  AVS_VideoFrame* AVSC_CC demoCfilter_get_frame(AVS_FilterInfo* p, int n)\n  {\n    AVS_VideoFrame* src = avs_get_frame(p->child, n);\n\n    avs_make_writable(p->env, &src);\n\n    // src is an AVS_VideoFrame* \n    AVS_Map* avsmap;\n    avsmap = avs_get_frame_props_rw(p->env, src);\n    int error; // needed for error report, for now we'll ignore it\n    // read existing propery. For test, we set it by to 77 by propSet(\"TestIntKey\", 77) in Avisynth script\n    int64_t testvalue = avs_prop_get_int(p->env, avsmap, \"TestIntKey\", 0, &error);\n\n    // set new frame properties (by using the just-read integer property)\n    avs_prop_set_int(p->env, avsmap, \"TestIntKey2\", testvalue * 2, AVS_PROPAPPENDMODE_REPLACE);\n    avs_prop_set_float(p->env, avsmap, \"TestFloatKey2\", (testvalue * 2.0f), AVS_PROPAPPENDMODE_REPLACE);\n    // store string (in general: any data), by specifying length = -1 we'll notify set_data to have strlen for getting its real size\n    avs_prop_set_data(p->env, avsmap, \"TestStringKey2\", \"testStringvalue\", -1, AVS_PROPAPPENDMODE_REPLACE);\n\n    // array test (double). Note: we can have double here, contrary to the fact that Avisynth scripts can handle only floats.\n    const double test_d_array[] = { 0.5, 1.1 };\n    avs_prop_set_float_array(p->env, avsmap, \"TestFloatArray\", test_d_array, 2);\n\n    // array test (integer). Note: we can have int64 here, contrary to the fact that Avisynth scripts can handle only 32 bit integers.\n    const int64_t test_i_array[] = { -1, 0, 1 };\n    avs_prop_set_int_array(p->env, avsmap, \"TestIntArray\", test_i_array, 3);\n\n    // read back the array size of a property (single properties are an 1-element arrays)\n    int numElementsOfIntArray = avs_prop_num_elements(p->env, avsmap, \"TestIntArray\");\n    avs_prop_set_int(p->env, avsmap, \"TestNumElementsOfIntArray\", numElementsOfIntArray, AVS_PROPAPPENDMODE_REPLACE);\n\n    // Int property array: read back one-by-one, mul by 2, and put into another array\n    int64_t test_i_array_clone[3];\n    for (auto i = 0; i < numElementsOfIntArray; i++) {\n      test_i_array_clone[i] = avs_prop_get_int(p->env, avsmap, \"TestIntArray\", i, &error) * 2;\n    }\n    avs_prop_set_int_array(p->env, avsmap, \"TestIntArrayCloneMul2\", test_i_array_clone, 3);\n    \n    // double property array read back as a whole, div by 3, and put into another array\n    int numElementsOfFloatArray = avs_prop_num_elements(p->env, avsmap, \"TestFloatArray\");\n    const double * tmpdarray = avs_prop_get_float_array(p->env, avsmap, \"TestFloatArray\", &error);\n    for (auto i = 0; i < numElementsOfFloatArray; i++) {\n      double tmp_d = tmpdarray[i] / 3.0;\n      // first element: replace frameprop data, next ones: append new element one by one\n      avs_prop_set_float(p->env, avsmap, \"TestFloatArrayCloneDiv3\", tmp_d, i == 0 ? AVS_PROPAPPENDMODE_REPLACE : AVS_PROPAPPENDMODE_APPEND);\n    }\n\n    // delete the key, we defined in Avisynth script\n    avs_prop_delete_key(p->env, avsmap, \"TestIntKey\");\n\n    // count all keys (frame property count) and put it into another frame property\n    int numOfKeys = avs_prop_num_keys(p->env, avsmap);\n    avs_prop_set_int(p->env, avsmap, \"TestNumKeysWithoutThisOne\", numOfKeys, AVS_PROPAPPENDMODE_REPLACE);\n\n    return src;\n\n  }\n\n\n- Fix: StackVertical and packed RGB formats: get audio and parity from the first and not the last clip\n- RGBAdjust: analyse=true 32 bit float support\n- experimental! Fix CUDA support on specific builds (apply lost-during-merge differences from Nekopanda branch), add CMake support for the option.\n- Fixes for building the core as a static library\n- RGBAdjust: analyse=true 32 bit float support\n- experimental! Fix CUDA support on specific builds (apply lost-during-merge differences from Nekopanda branch), add CMake support for the option.\n- Fixes for building the core as a static library\n\n20210111 3.7.0\n--------------\n- Haiku support\n- PowerPC support\n- Support for building the core as a static library (mcmtroffaes)\n- Fixes for MinGW-w64 compilation\n- Shibatch, TimeStretch, and ImageSeq GCC build support\n- Shibatch, TimeStretch, and ImageSeq non-Windows support\n\n20201214 3.6.2-WIP\n- Fix: AddBorders did not pass frame properties\n\n20201211 3.6.2-test7\n--------------------\n- Fix: propSet, propDelete and propClearAll not to ruin visibility of variables\n  (property read functions are still kept being runtime only)\n\n20201210 3.6.2-test6\n-----------------------\n- AviSource: fix test5 regression which refused handling old formats like YV24\n\n20201208 3.6.2-test5\n-----------------------\n- Resizers: throw error on too small dimensions vs. taps\n- Add ShowCRC32 debug filter. Parameters are the same as in ShowFrameNumber\n- Overlay: allow 4:1:1 input\n- Overlay: fix crash when mask is YUV411 and greymask=false\n- Overlay: may work quicker, most input/overlay/mask/output clip format conversions moved to filter constructor\n- RemoveAlphaPlane: do nothing on YUY2 instead of throwing an error message\n- AviSource: support non-printing characters in fourCC code: allow [number] style, e.g. G3[0][16]\n- AviSource: add Y410 (YUVA444P10) format support. Allow 'Y410' pixel_type hints.\n- AviSource: decode b64a, b48r, v210, P210, P010, P016, P216, v410, Y416, r210, R10k, v308, v408, Y410 fourCCs natively.\n- Fix: Average...: check for valid colorspace (e.g. no AverageB for a YUV clip)\n- Add: AverageA\n- New: Average...: allow YUY2, RGB24/32/48/64 inputs\n\n20201112 3.6.2-test4\n--------------------\n- Fix: Overlay: Actual frame of a mask clip would be freed up too early in MT environment\n- Fix: ConvertBits to ignore dither parameter instead of throwing error, in a 8 to 8 bit case\n\n20201020 3.6.2-test3\n--------------------\n- Fix: GeneralConvolution missing internal rounding on 8-16 bit formats\n\n20200831 3.6.2-test2\n--------------------\n- support for Win10 long file path option\n- project: Improve inclusion of the ghc filesystem helper library\n- project: Add a GitHub action workflow\n- posix: fix crash when autoloading imports\n- internally refactored ConvertAudio\n- ConvertBits(8): fix dither=1 (floyd) for RGB48/RGB64\n- Fix: Blur right side garbage: 16 bit+AVX2+non mod32 width\n- Fix: check fn signature with implicite \"last\" first (3.6 regression)\n- Fix: function parameters provided as arrays (e.g. GrunT callback of WriteFileIf)\n\n20200624 3.6.2-test1\n------------------\n- Fix: ConvertBits (YUV): proper rounding when bit depth is reduced and origin is 10-16 bits\n  (added rounder before bit-shift)\n- New: Histogram(\"color2\") to support 10+ bits.\n  Allow bits=x (x=8,9,10,11,12) parameter for this kind of histogram as well.\n\n20200619 3.6.1\n--------------\n\nUse the installer or copy files directly\n- 64 bit OS:\n  copy Avisynth.dll from x86 folder to the windows SysWOW64 folder\n  copy Avisynth.dll from x64 folder to the windows System32 folder\n- 32 bit OS\n  copy Avisynth.dll from x86 folder to the windows System32 folder\n- All OS: Copy appropriate files from the plugins+/plugins64+ to the appropriate Avisynth+ folder\n\nUseful links:\n-------------\nSource (from 3.4): https://github.com/AviSynth/AviSynthPlus\nSource (before 3.4): https://github.com/pinterf/AviSynthPlus/tree/MT\nForum: https://forum.doom9.org/showthread.php?t=168856\nForum on some avs+ filters: https://forum.doom9.org/showthread.php?t=169832\nAvisynth+ info page: http://avisynth.nl/index.php/AviSynth%2B\nInfo on Avisynth+ new color spaces: https://forum.doom9.org/showthread.php?p=1783714#post1783714\nAvisynth Universal Installer by Groucho2004: https://forum.doom9.org/showthread.php?t=172124\n\nShort info for plugin writers\n-----------------------------\n  Avisynth+ header (and helper headers) are available here, or choose SDK during install:\n  https://github.com/AviSynth/AviSynthPlus/tree/master/avs_core/include\n\n  Use these headers for building x86/x64 plugins, and to use Avisynth+'s high-bitdepth related VideoInfo functions\n  without any concern. When a VideoInfo function is non-existant on a system that uses your plugin,\n  it won't crash, just fall back to a default behaviour. E.g. VideoInfo.BitsPerComponent() will always return 8\n  when your plugin calls it on a Classic Avisynth, or pre-high bit depth Avisynth+ host.\n\n(see readme_history.txt for details, syntax element, etc. They also appear on avisynth.nl)\n\n20200619 3.6.1\n--------------\n(summary of test versions since 3.6.0)\n\n- Fix: proper handling of autoload directories precedence:\n    PluginDir+ in Software/Avisynth in HKEY_CURRENT_USER (highest priority)\n    PluginDir+ in Software/Avisynth in HKEY_LOCAL_MACHINE\n    PluginDir2_5 in Software/Avisynth in HKEY_CURRENT_USER\n    PluginDir2_5 in Software/Avisynth in HKEY_LOCAL_MACHINE (lowest priority)\n  Plugin (dll file name) found in a lower priority folder will not load if a similarly named plugin \n  already existed earlier.\n- fix: GeneralConvolution: incorrect parse of negative integer coefficient (added +1)\n  Regression since r2772.\n- Fix: GeneralConvolution: possible crash when chroma=true for 420 and 422 formats\n- Fix: ScriptClip + Runtime function object (which are new in 3.6) under heavy multithreading\n- New: Histogram(\"levels\") to allow greyscale\n- Fix 3.6 regressions\n  - when explicit \"return last\" was needed when followed by legacy function definition.\n  - Windows XP is supported again (thread local storage workaround)\n  - Stabilize CPP 2.5 plugins\n  - allow forced named arrays usage again from plugins (MP_PipeLine)\n- Frame property related constants to match existing enum style in avisynth.h.\n  Plus they are not colliding now with VapourSynth's definitions.\n\n\n20200607 3.6.1-test8\n--------------------\n- fix: GeneralConvolution: incorrect parse of negative integer coefficient (+1)\n  regression since r2772\n- fix: GeneralConvolution: possible crash when chroma=true for 420 and 422 formats\n- Frame property related constant to match existing enum style in avisynth.h\n\n20200605 3.6.1-test7 (internal)\n- pass V3 (2.5) IScriptEnvironment for CPP plugins which directly load avisynth.dll and\n  request CreateScriptEnvironment with version <= 3 \n\n20200604 3.6.1-test6\n- Fix a 3.6 regression when explicit \"return last\" was needed when followed by legacy function definition.\n- Further Cpp 2.5 plugin compatibility fix: when a v2.5 filter is calling GetFrame from its constructor\n  (hdragc)\n\n20200603 3.6.1-test5\n- Histogram(\"levels\") to allow greyscale\n- Fix 3.6 regression: CPP 2.5 interface runtime functions\n- Fix 3.6 regression: forced named arrays usage from plugins (MP_PipeLine)\n\n20200531 3.6.1-test4\n- Avisynth CPP 2.5 plugin compatibility patch.\n- Windows XP patch (thread local storage workaround)\n- Fix: proper handling of autoload directories precedence:\n    PluginDir+ in Software/Avisynth in HKEY_CURRENT_USER (highest priority)\n    PluginDir+ in Software/Avisynth in HKEY_LOCAL_MACHINE\n    PluginDir2_5 in Software/Avisynth in HKEY_CURRENT_USER\n    PluginDir2_5 in Software/Avisynth in HKEY_LOCAL_MACHINE (lowest priority)\n  Plugin (dll file name) found in a lower priority folder will not load if a similarly named plugin already existed earlier.\n- Fix: ScriptClip + Runtime function object crash under multithreading\n  e.g. script was crashing with high confidence:\n    ColorBars(width=640, height=480, pixel_type=\"yv12\")\n    ScriptClip(function[](clip c) { propSetInt(\"s\",function[](clip c) { return current_frame }) })\n    Prefetch(100)\n\n20200520 3.6.0\n--------------\n- Added predefined macros for ARM processors. Tested on Raspberry Pi 4B with the aarch64 image of Ubuntu 20.04.\n- Added support for disabling the Intel SIMD intrinsics. Gets automatically disabled on non-x86 targets.\n- Added submodule to allow macOS 10.13 and 10.14 to build AviSynth+ with the native Clang compiler\n- Fixed some warnings on GCC (wangqr)\n- Implemented GetNumPhysicalCPUs on Linux and macOS (wangqr)\n- Scripts arrays (Info for plugin writers)\n  Plugin parameter definition: allow type+'.' and type+'*' syntax for named array parameters\n\n  Example:\n    BlankClip has a named \"colors\" parameter which accepts one or more \"float\".\n    Definition in function signature:\n      [colors]f+\n    Usage on the caller side: pass [235.0, 128, 128].\n    Checking the proper array size is the plugin's task.\n\n  Note:\n    Plugins with named array parameter definition syntax will not work for non-array-aware AviSynth versions.\n\n  Note2:\n    Type-free unnamed arrays \".+\" or \".*\" cannot be followed by additional parameters\n\n  Note3:\n    A backward compatible way (AVS 2.6 and non-script-array AviSynth+ versions) of using named or unnamed arrays is to specify a single type as \".\" and\n    the plugin would check the argument type for IsArray\n\n- User defined functions:\n  Add array parameter types:\n\n  \"array\" or \"val_array\": array of any type.\n    When unnamed, then this kind of parameter must be the very last one.\n    Unnamed free-typed parametes cannot be followed by any other parameter.\n    Translates to \".*\" in a plugin parameter definition rule.\n\n  \"bool_array\" \"int_array\", \"float_array\", \"string_array\", \"clip_array\", \"func_array\"\n    Translates to \"b*\", \"i*\", \"f*\", \"s*\", \"c*\", \"f*\" in a plugin parameter definition rule.\n\n  Example:\n\n    '''\n    a = [1.0, 2.0, 4.2]\n    b = [3, 4, 5]\n    multi = [a,b]\n\n    sum = Summa(multi[0], multi[1], 2)\n    SubTitle(Format({sum}))\n\n    Function Summa(array \"x\", array \"y\", int \"N\")\n    {\n      sum = 0.0\n      FOR(i=0,N-1) {\n        sum = sum + x[i] * y[i]\n      }\n      return sum\n    }\n\n    or\n\n    Function Summa(float_array x, float_array y, int \"N\")\n    {\n      sum = 0.0\n      FOR(i=0,N-1) {\n        sum = sum + x[i] * y[i]\n      }\n      return sum\n    }\n    '''\n\n- IScriptEnvironment new additions\n  Ex-IScriptEnvironment2: no-throw version of Invoke name change to -> InvokeTry\n  Ex-INeo Invoke versions to -> Invoke2Try, Invoke3, Invoke3Try\n  New (was not implemented in any former Interface): Invoke2 (Exception Thrower version of Invoke2Try)\n\n- Test build published on (20200428)\n\n20200428 3.6.0\n--------------\n- New: Format function\n\n  Syntax:\n    string Format(string format, [value1, value2, ...])\n\n  Parameters\n    - string format\n      unnamed parameter, the format string\n    - zero or more values for format replacement\n      Single values are converted to string like in AviSynth String() function.\n      If a value is a two dimensional array (only with AviSynth+ arrays enabled) then it can be\n      used by a named lookup in the format expression.\n\n  Returns\n    formatted string\n\n  Description:\n\n    The format string consists of\n\n        ordinary characters (except { and }), which are copied unchanged to the output,\n        escape sequences {{ and }}, which are replaced with { and } respectively in the output, and\n        replacement fields.\n\n    Each replacement field has the following format:\n\n        introductory { character;\n\n        (optional)\n        arg-id, a non-negative number;\n        or:\n        identifier which is used for lookup named parameters. ([\"name\", value] construction)\n        or:\n        valid AviSynth variable name\n\n        final } character.\n\n    If arg-id is a number it specifies the index of the argument in args whose value is to be used for formatting;\n    Index is zero based.\n\n    If arg-id is string then it serves as a lookup key from the parameters list given as an array [\"name\",value] pair.\n    If not found, then arg-id is searched among Avisynth variables.\n\n    If arg-id is omitted, the arguments are used in order.\n    Mixing manual and automatic indexing is not an error.\n\n    Notes\n\n    It is not an error to provide more arguments than the format string requires:\n\n    Format(\"{} {}!\", \"Hello\", \"world\", \"something\"); // OK, produces \"Hello world!\"\n\n  Examples:\n    By Avisynth variable\n      max_pixel_value = 255\n      SubTitle(Format(\"max={max_pixel_value}!\"))\n\n    By index:\n      SubTitle(Format(\"{0} {1} {0}\", \"Home\", \"sweet\"))\n\n    In order:\n      SubTitle(Format(\"{} {} {}\", \"AviSynth\", \"+\", 2020))\n\n    Array name-value pairs\n      SubTitle(Format(\"maximum={max} minimum={min} max again {max}!\", [\"max\",255], [\"min\",0]))\n\n- frame properties framework, IScriptEnvironment extension\n  - Core and concept ported from VapourSynth - thank you\n  - Frame properties are really per-frame data which can only be read and written within runtime functions.\n    Source filters can feed into frame properties useful data such as information on colorimetry.\n  - frame properties are key-value(s) pairs\n    - Key is an alphanumeric identifier.\n    - Values can be of single value or array of type\n      - 64 bit integers (32 bit integer when converted to AVSValue inside Avisynth+, AVSValue limitation)\n      - 64 bit doubles (32 bit float when converted to AVSValue inside Avisynth+, AVSValue limitation)\n      - strings (or data) with given length. strings are null terminated\n      - frame references (PVideoFrame)\n      - clip references (PClip)\n    - property setting has 3 modes: 0-replace 1-append 2-touch (see AVSPropAppendMode in avisynth.h)\n      0 - single value for that key is replaced\n      1 - property is appended (make arrays by calling with mode=1 consecutively)\n      2 - touch\n  - from plugin writer's point of view:\n    - new field in internal VideoFrame struct:\n      properties, type is AVSMap* which is basically a reference counting struct for holding array of variants\n    - frame property passing along the filter chain\n      If your filter is not an in-place one (works with NewVideoFrame instead of MakeWritable) then\n      you have to pass properties programatically by using a new version of env->NewVideoFrame: NewVideoFrameP.\n      This alternative version of NewVideoFrame has a second PVideoFrame* parameter from which properties will be\n      copied upon creating an empty VideoFrame.\n\n      Unfortunately if even one filter in the chain is not passing frame properties then it is a dead end on the info.\n\n      Whether you can (should) use it or not, the Avisynth interface version will tell you. (e.g. >= 8) which should be\n      queried (best place: filter constructor)\n      Unless you drop support for older avs+ or classic Avisynth 2.6, there will be a transient time when you have to support both world.\n      Example:\n        Check it:\n          has_at_least_v8 = true;\n          try { env->CheckVersion(8); } catch (const AvisynthError&) { has_at_least_v8 = false; }\n        and use it:\n          if (has_at_least_v8) dst = env->NewVideoFrameP(vi, &src); else dst = env->NewVideoFrame(vi);\n\n      Another approach VideoFrame is created as before and later 'copyFrameProps' is used.\n\n    - support functions\n    In C interface:\n      use avs_new_video_frame_p instead of avs_new_video_frame\n      use avs_new_video_frame_p_a instead of avs_new_video_frame_a\n\n      AVS_VideoFrame * AVSC_CC avs_new_video_frame_p(AVS_ScriptEnvironment * p, const AVS_VideoInfo * vi, AVS_VideoFrame * propSrc)\n      AVS_VideoFrame * AVSC_CC avs_new_video_frame_p_a(AVS_ScriptEnvironment * p, const AVS_VideoInfo * vi, AVS_VideoFrame *propSrc, int align)\n\n    In avisynth.h:\n      enums AVSPropTypes, AVSGetPropErrors and AVSPropAppendMode\n      AVSMap* is just a pointer which holds the actual list and values of frame properties.\n      You don't need to know what's inside. Access its content through IScriptEnvironment or C interface calls\n\n  - IScriptEnvironment interface is extended! For the first time since classic Avisynth 2.6 moved to IF version 6.\n    AVISYNTH_INTERFACE_VERION supporting frame properties is: 8.\n\n    [CPP interface]\n    - Summary:\n      New: frame propery support with NewVideoFrameP and property getter/setter/info helpers\n      Old-New: moved from IScriptEnvironment2:\n        GetEnvProperty (note: this is for system properties)\n        Allocate, Free (buffer pools)\n        GetVar versions distinctly named: GetVarTry, GetVarBool, GetVarInt, GetVarDouble, GetVarString, GetVarLong\n      Old-New: moved from IScriptEnvironment2 and INeoEnv\n        InvokeTry, Invoke2, Invoke2Try, Invoke3, Invoke3Try\n        The \"xxxTry\" versions are returning bool instead of throwing NotFound if specified function does not exist\n\n        IScriptEnvironment V6 contained only:\n          AVSValue Invoke(const char* name, const AVSValue args, const char* const* arg_names = 0)\n        New content, different parameter list, non-exception thrower versions\n          These versions of Invoke will throw NotFound() exception like \"Invoke\" does\n            AVSValue Invoke2(const AVSValue& implicit_last, const char* name, const AVSValue args, const char* const* arg_names = 0)\n            AVSValue Invoke3(const AVSValue& implicit_last, const PFunction& func, const AVSValue args, const char* const* arg_names = 0)\n          These versions of Invoke will return false instead of throwing NotFound().\n            bool InvokeTry(AVSValue* result, const char* name, const AVSValue& args, const char* const* arg_names = 0)\n            bool Invoke2Try(AVSValue* result, const AVSValue& implicit_last, const char* name, const AVSValue args, const char* const* arg_names = 0)\n            bool Invoke3Try(AVSValue* result, const AVSValue& implicit_last, const PFunction& func, const AVSValue args, const char* const* arg_names = 0)\n\n    - NewVideoFrame with frame property source:\n        PVideoFrame NewVideoFrameP(const VideoInfo& vi, PVideoFrame* propSrc, int align = FRAME_ALIGN);\n\n      Instead of using\n        PVideoFrame src = child->GetFrame(n, env);\n        PVideoFrame frame = env->NewVideoFrame(vi)\n\n      create new video frame with passing properties by giving a source video frame\n        PVideoFrame src = child->GetFrame(n, env);\n        PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n\n      All core functions in Avisynth support passing frame properties as a first step.\n      (Second and further steps for Avisynth core: use \"standardized\" frame properties for color matrix and primaries info,\n      for field based flag, etc...)\n\n      Note: MakeWritable preserves frame properties\n\n    - copy frame properties from one frame to another: copyFrameProps\n    - get property pointer for readonly access: getFramePropsRO\n    - get property pointer for read/write access: getFramePropsRW\n    - property count helper functions\n    - clear of individual properties by key or clear everything\n    - property getter and setter functions (by key, key+index, by index). Indexes are starting with 0.\n    - examples in conditional.cpp, conditional_functions.cpp\n\n      void copyFrameProps(const PVideoFrame& src, PVideoFrame& dst);\n        copies frame properties from source to destination frame\n\n      const AVSMap* getFramePropsRO(const PVideoFrame& frame);\n      AVSMap* getFramePropsRW(PVideoFrame& frame);\n        get pointer to the property struct for readonly or read/write purposes.\n        A single frame can have one set of frame properties, but the set can be shared by multiple frames.\n\n      int propNumKeys(const AVSMap* map);\n        returns the number of frame properties for a given AVSMap. Each entry have a unique alphanumeric key.\n        Key is the identifier name of the frame property.\n\n      const char* propGetKey(const AVSMap* map, int index);\n        Retrieves the key (property identifier / property name) by index. 0 <= index < propNumKeys\n\n      int propDeleteKey(AVSMap* map, const char* key);\n        Delete an entry. Returns 0 if O.K.\n\n      int propNumElements(const AVSMap* map, const char* key);\n        Queries the internal counter for a given property. Properties can be arrays,\n        returned value means the array size. Non array properties return 1.\n        Returns -1 if property does not exists.\n\n      char propGetType(const AVSMap* map, const char* key);\n        returns the data type.\n        Type Enums are avaliable here:\n          avisynth.h CPP interface:\n            '''\n            typedef enum AVSPropTypes {\n              ptUnset = 'u',\n              ptInt = 'i',\n              ptFloat = 'f',\n              ptData = 's',\n              ptClip = 'c',\n              ptFrame = 'v',\n            } AVSPropTypes;\n            '''\n          avisynth_c.h C interface:\n            '''\n            enum {\n              AVS_PROPTYPE_UNSET = 'u',\n              AVS_PROPTYPE_INT = 'i',\n              AVS_PROPTYPE_FLOAT = 'f',\n              AVS_PROPTYPE_DATA = 's',\n              AVS_PROPTYPE_CLIP = 'c',\n              AVS_PROPTYPE_FRAME = 'v'\n            };\n            '''\n\n      int64_t propGetInt(const AVSMap* map, const char* key, int index, int* error);\n      double propGetFloat(const AVSMap* map, const char* key, int index, int* error);\n      const char* propGetData(const AVSMap* map, const char* key, int index, int* error);\n      PClip propGetClip(const AVSMap* map, const char* key, int index, int* error);\n      const PVideoFrame propGetFrame(const AVSMap* map, const char* key, int index, int* error);\n\n        Property read functions.\n        Since properties can be arrays, index should be specified.\n        Use index = 0 for getting the value for a non-array property, in reality these\n        properties are a size=1 arrays.\n        Funtion 'propGetData' can be used for both strings and for generic byte arrays.\n        Variable 'error' returns an error code of failure (0=success):\n          peUnset: key does not exists\n          peType: e.g read integer from a float property,\n          peIndex: property array index out of range)\n        Error enums are defined here:\n          avisynth.h CPP interface:\n            typedef enum AVSGetPropErrors {\n              peUnset = 1,\n              peType = 2,\n              peIndex = 4\n            } AVSGetPropErrors;\n          avisynth_c.h C interface:\n            enum {\n              AVS_GETPROPERROR_UNSET = 1,\n              AVS_GETPROPERROR_TYPE = 2,\n              AVS_GETPROPERROR_INDEX = 4\n            };\n\n      int propGetDataSize(const AVSMap* map, const char* key, int index, int* error);\n        returns the string length or data size of a ptData typed element\n\n      int propSetInt(AVSMap* map, const char* key, int64_t i, int append);\n      int propSetFloat(AVSMap* map, const char* key, double d, int append);\n      int propSetData(AVSMap* map, const char* key, const char* d, int length, int append);\n      int propSetClip(AVSMap* map, const char* key, PClip& clip, int append);\n      int propSetFrame(AVSMap* map, const char* key, const PVideoFrame& frame, int append);\n        Property setter functions.\n        propSetData is used for strings or for real generic byte data.\n        propSetData has an extra length parameter, specify -1 for automatic string length.\n        Data bytes will be copied into the property (no need to keep data for the given pointer)\n        Three propery set modes supported.\n        - paReplace: adds if not exists, replaces value is it already exists, losing its old value.\n        - paAppend: appends to the existing property (note: they are basically arrays)\n        - paTouch: do nothing if the key exists. Otherwise, the key is added to the map, with no values associated.\n        See mode enums in:\n          avisynth.h CPP interface:\n            '''\n            typedef enum AVSPropAppendMode {\n              paReplace = 0,\n              paAppend = 1,\n              paTouch = 2\n            } AVSPropAppendMode;\n            '''\n          or\n          avisynth_c.h C interface:\n            '''\n            enum {\n              AVS_PROPAPPENDMODE_REPLACE = 0,\n              AVS_PROPAPPENDMODE_APPEND = 1,\n              AVS_PROPAPPENDMODE_TOUCH = 2\n            };\n            '''\n\n      const int64_t *propGetIntArray(const AVSMap* map, const char* key, int* error);\n      const double *propGetFloatArray(const AVSMap* map, const char* key, int* error);\n        Get the pointer to the first element of array of the given key.\n        Use 'propNumElements' for establishing array size and valid index ranges.\n\n      int propSetIntArray(AVSMap* map, const char* key, const int64_t* i, int size);\n      int propSetFloatArray(AVSMap* map, const char* key, const double* d, int size);\n        If an array is already available in the application, these functions provide\n        a quicker way for setting the properties than to insert them one by one.\n        No append mode can be specified, if property already exists it will be overwritten.\n        Return value: 0 on success, 1 otherwise\n\n      void clearMap(AVSMap* map);\n        Removes all content from the property set.\n\n      AVSMap* createMap();\n      void freeMap(AVSMap* map);\n        these are for internal use only\n\n    [C interface]\n    - Functions and enums are defined avisynth_c.h\n    - New: frame propery support with NewVideoFrameP and property getter/setter/info helpers\n    - Old-New: moved from IScriptEnvironment2:\n        avs_get_env_property (note: this is for system properties)\n        avs_pool_allocate, avs_pool_free (buffer pools)\n        avs_get_var versions distinctly named: avs_get_var_try, avs_get_var_bool,\n        avs_get_var_int, avs_get_var_double, avs_get_var_string, avs_get_var_long\n\n    - new video frame creator functions:\n        avs_new_video_frame_p\n        avs_new_video_frame_p_a\n\n      They return and empty video frame but with frame properties copied from the source parameter.\n\n        AVS_VideoFrame * AVSC_CC avs_new_video_frame_p(const AVS_VideoInfo* vi, AVS_VideoFrame *propSrc)\n        AVS_VideoFrame * AVSC_CC avs_new_video_frame_p_a(AVS_ScriptEnvironment * p, const AVS_VideoInfo * vi, AVS_VideoFrame *propSrc, int align)\n\n      NULL as propSrc will behave like old avs_new_video_frame and avs_new_video_frame_a\n\n    - AVS_VideoFrame struct extended with a placeholder field for 'properties' pointer\n    - avs_copyFrameProps\n    - avs_getFramePropsRO, avs_getFramePropsRW\n    - avs_propNumKeys, avs_propGetKey, avs_propNumElements, avs_propGetType, avs_propGetDataSize\n    - avs_propGetInt, avs_propGetFloat, avs_propGetData, avs_propGetClip, avs_propGetFrame, avs_propGetIntArray, avs_propGetFloatArray\n    - avs_propSetInt, avs_propSetFloat, avs_propSetData, avs_propSetClip, avs_propSetFrame, avs_propSetIntArray, avs_propSetFloatArray\n    - avs_propDeleteKey, avs_clearMap\n\n    See their descriptions above, names are similar to the CPP ones.\n\n    [AviSynth scripting language]\n\n    Frame properties read-write possible only within runtime functions.\n    Input value of setter functions are to be come from the return value of \"function objects\"\n\n    Property setter function names begin with propSet\n      - property value is given by the return value of a function object\n        Parameters:\n          clip c,\n          string key_name,\n          function object,\n          int \"mode\"\n            0=replace (default), 1=append, 2=touch\n            There is no append mode for inserting a full array into the property.\n\n          \"propSet\" csn[mode]i\n            generic property setter, automatic type recognition\n          \"propSetInt\" csn[mode]i\n            accepts only integer results from function\n          \"propSetFloat\" csn[mode]i\n            accepts only float results from function\n          \"propSetString\" csn[mode]i\n            accepts only string results from function\n          \"propSetArray\" csn\n            accepts only array type results from function\n\n      - Sets a property, its value is given directly\n\n        \"propSet\" csi[mode]i\n        \"propSet\" csf[mode]i\n        \"propSet\" css[mode]i\n        \"propSet\" csa\n          note: array must contain only the similarly typed values, e.g. cannot mix strings with integers.\n\n        Parameters:\n          clip c,\n          string key_name,\n          value (type of integer, float, string and array respectively),\n          int \"mode\"\n            0=replace (default), 1=append, 2=touch\n            There is no append mode for inserting a full array into the property.\n\n    Delete a specific property entry\n      \"propDelete\" cs\n\n       parameters:\n         clip c,\n         string key_name,\n\n    Clear all properties for a given video frame\n      \"propClearAll\" c\n\n       parameters:\n         clip c\n\n    Reading properties\n       Common parameters:\n         clip c,\n         string key_name,\n         integer \"index\", (default 0): for zero based indexing array access\n         integer \"offset\" (default 0), similar to the other runtime functions: frame offset (e.g. -1: previous, 2: next next)\n\n      \"propGetAny\" cs[index]i[offset]i\n        returns the automatically detected type\n      \"propGetInt\" cs[index]i[offset]i\n        returns only if value is integer, throws an error otherwise\n      \"propGetFloat\" cs[index]i[offset]i\n        returns only if value is float, throws an error otherwise\n      \"propGetString\"cs[index]i[offset]i\n        returns only if value is string, throws an error otherwise\n      \"propGetAsArray\" cs[offset]i\n        returns an array. For a single property array size will be 1. (only in array-aware AviSynth+ versions)\n\n\n    Reading all properties\n      \"propGetAll\" c[offset]i\n\n      (Only in array-aware AviSynth+ versions)\n      Returns all frame properties in an array of [key-value] pairs. Array size will be 'numProps'\n      Each key-value pair is contained in a two dimensional subarray.\n      If the property value for a given key is an array again then \"value\" will be an array as well.\n      Once you have the array with all properties you can access them with the \"associative\" feature of AviSynth array access\n\n      ScriptClip(\"\"\"last.propSet(\"cica\",\"hello\"+String(current_frame)).\\\n        propSetInt(\"test_i1\",function[](clip c) { return current_frame*3 }).\\\n        propSet(\"test_i2\", current_frame * 2) \"\"\")\n      ScriptClip(\"\"\"p = propGetAll() \\\n        SubTitle(\"size:\" + String(p.ArraySize()) + \" \" + \\\n                           String(p[\"test_i1\"]) + \" \" + \\\n                           String(p[\"cica\"]) + \" \" + \\\n                           String(p[\"test_i2\"]))\"\"\")\n      ScriptClip(\"\"\"p = propGetAll() \\\n        SubTitle(\"size:\" + String(p.ArraySize()) + \" \" + \\\n        String(p[0,1]) + \" \" + \\\n        String(p[1,1]) + \" \" + \\\n        String(p[2,1]), x=0, y=20)\"\"\")\n\n    Lists all properties to screen (a debug filter)\n      \"propShow\" c[size]i[showtype]b\n\n      integer \"size\" default(16)\n        font size to use (the \"Text\" filter is used for display, sizes are of limited set)\n\n      bool \"showtype\" default (false)\n        if true, the data type in parenthesis appears next to the property key name\n\n      Listing appears as a name = value list. Arrays values are put between [ and ]\n      Top line contains number is properties. If no properties found, nothing is displayed.\n\n    Other helper function\n      \"propGetDataSize\" cs[index]i[offset]i\n        returns the size of the string or underlying data array\n\n      \"propNumElements\" cs[offset]i\n        returns the array size of a given property. 1=single value\n\n      \"propNumKeys\" c[offset]i\n        returns number of entries (keys) for a frame\n\n      \"propGetKeyByIndex\" c[index]i[offset]i\n        returns the key name for the Nth property (zero based, 0<=index<propNumKeys)\n\n      \"propGetType\" cs[offset]i\n        returns the type of the given key\n            unset: 0\n            integer: 1\n            float: 2\n            string: 3\n            clip: 4\n            frame: 5\n\n  Example 1:\n  '''\n    ColorBars()\n\n    # just practicing with function objects\n    ScriptClip(function[](clip c) { c.Subtitle(String(current_frame)) })\n\n    # write frame properties with function object\n    ScriptClip(\"\"\"propSetInt(\"frameprop_from_str\",func(YPlaneMax))\"\"\")\n    # write frame properties with traditional script string\n    ScriptClip(function[](clip c) { propSetInt(\"frameluma_sc_func\",func(AverageLuma)) })\n\n    # read frame properties (function object, string)\n    ScriptClip(function[](clip c) { SubTitle(string(propGetInt(\"frameprop_from_str\")), y=20) })\n    ScriptClip(\"\"\"SubTitle(string(propGetInt(\"frameluma_sc_func\")), y=40)\"\"\")\n\n    return last\n  '''\n\n  Example 2: (long - require NEW_AVSVALUE build - default on POSIX - becasue of arrays)\n      '''\n      ColorBars(width=640, height=480, pixel_type=\"yv12\", staticframes=true)\n\n      ScriptClip(function[](clip c) { propSetString(\"s\",function[](clip c) { return \"Hello \" + string(current_frame) }) })\n      ScriptClip(function[](clip c) { propSetString(\"s\",function[](clip c) { return \"Hello array element #2 \" }, mode=1) })\n      ScriptClip(function[](clip c) { propSetString(\"s\",function[](clip c) { return \"Hello array element #3 \"}, mode=1 ) })\n\n      ScriptClip(function[](clip c) { propSetString(\"s2\",function[](clip c) { return \"Another property \"} ) })\n\n      ScriptClip(function[](clip c) { propSetInt(\"s_int\",function[](clip c) { return current_frame*1 }) })\n      ScriptClip(function[](clip c) { propSetInt(\"s_int\",function[](clip c) { return current_frame*2 }, mode=1) })\n      ScriptClip(function[](clip c) { propSetInt(\"s_int\",function[](clip c) { return current_frame*4 }, mode=1 ) })\n\n      ScriptClip(function[](clip c) { propSetFloat(\"s_float\",function[](clip c) { return current_frame*1*3.14 }) })\n      ScriptClip(function[](clip c) { propSetFloat(\"s_float\",function[](clip c) { return current_frame*2*3.14 }, mode=1) })\n      ScriptClip(function[](clip c) { propSetFloat(\"s_float\",function[](clip c) { return current_frame*3*3.14 }, mode=1 ) })\n\n      ScriptClip(function[](clip c) { propSetArray(\"s_float_arr\",function[](clip c) { return [1.1, 2.2] } ) })\n      ScriptClip(function[](clip c) { propSetArray(\"s_int_arr\",function[](clip c) { return [-1,-2,-5] } ) })\n      ScriptClip(function[](clip c) { propSetArray(\"s_string\",function[](clip c) { return [\"ArrayElementS_1\", \"ArrayElementS_2\"] } ) })\n      #ScriptClip(\"\"\"propDelete(\"s\")\"\"\")\n      ScriptClip(function[](clip c) {\n        y = 0\n        SubTitle(\"Prop Key count =\" + String(propNumKeys), y=y)\n        y = y + 15\n        numKeys = propNumKeys() - 1\n        for ( i = 0 , numKeys) {\n          propName = propGetKeyByIndex(index = i)\n          propType = propGetType(propName)\n          SubTitle(\"#\"+String(i) + \" property: '\" + propName + \"', Type = \" + String(propType) , y=y)\n          y = y + 15\n\n          for(j=0, propNumElements(propName) - 1) {\n            SubTitle(\"element #\" + String(j) + \", size = \" + String(propType == 3 ? propGetDataSize(propName, index=j) : 0) + \", Value = \" + String(propGetAny(propName, index=j)), y = y)\n            #SubTitle(\"element #\" + String(j) + \" size = \" + String(propType == 3 ? propGetDataSize(propName, index=j) : 0) + \", Value = \" + String(propGetAny(propName, index=j)), y = y)\n            y = y + 15\n          }\n\n        }\n        return last\n      })\n\n      ScriptClip(function[](clip c) {\n        a = propGetAsArray(\"s\")\n        y = 100\n        x = 400\n        SubTitle(string(a.ArraySize()), x=x, y=y)\n        for(i=0, a.ArraySize()-1) {\n          SubTitle(\"[\"+String(i)+\"]=\"+ String(a[i]),x=x,y=y)\n          y = y + 15\n        }\n      return last\n      })\n\n      # get int array one pass\n      ScriptClip(function[](clip c) {\n        a = propGetAsArray(\"s_int\")\n        y = 440\n        x = 400\n        SubTitle(\"Array size=\" + string(a.ArraySize()), x=x, y=y)\n        y = y + 15\n        for(i=0, a.ArraySize()-1) {\n          SubTitle(\"[\"+String(i)+\"]=\"+ String(a[i]),x=x,y=y)\n          y = y + 15\n        }\n      return last\n      })\n\n      # get float array one pass\n      ScriptClip(function[](clip c) {\n        a = propGetAsArray(\"s_float\")\n        y = 440\n        x = 200\n        SubTitle(\"Array size=\" + string(a.ArraySize()), x=x, y=y)\n        y = y + 15\n        for(i=0, a.ArraySize()-1) {\n          SubTitle(\"[\"+String(i)+\"]=\"+ String(a[i]),x=x,y=y)\n          y = y + 15\n        }\n      return last\n      })\n\n      # get string array\n      ScriptClip(function[](clip c) {\n        a = propGetAsArray(\"s_stringa\")\n        y = 440\n        x = 000\n        SubTitle(\"Array size=\" + string(a.ArraySize()), x=x, y=y)\n        y = y + 15\n        for(i=0, a.ArraySize()-1) {\n          SubTitle(\"[\"+String(i)+\"]=\"+ String(a[i]),x=x,y=y)\n          y = y + 15\n        }\n      return last\n      })\n    '''\n\n- New function:\n  SetMaxCPU(string feature)\n\n  string \"feature\"\n\n    \"\" or \"none\" for zero SIMD support, no processor flags are reported\n    \"mmx\", \"sse\", \"sse2\", \"sse3\", \"ssse3\", \"sse4\" or \"sse4.1\", \"sse4.2\", \"avx, \"avx2\"\n\n    parameter is case insensitive.\n    Note: \"avx2\" triggers FMA3 flag as well.\n\n  Processor options w/o any modifier will limit the CPU flag report to at most the processor level.\n  When \"feature\" is ended by '+', relevant processor feature flag will be switched on\n  When \"feature\" is ended by '-', relevant processor feature flag will be removed\n  Multiple options can be put in a comma separated list. They will evaluated in that order.\n\n  Examples:\n    SetMaxCPU(\"SSE2\") reports at most SSE2 processor (even if AVX2 is available)\n    SetMaxCPU(\"avx,sse4.1-\") limits to avx2 but explicitely removes reporting sse4.1 support\n    SetMaxCPU(\"none,avx2+\") limits to plain C, then switches on AVX2-only support\n\n- Script array for NEW_AVSVALUE define are working again. (default in Linux build - experimental)\n  Memo:\n    Compiler define NEW_AVSVALUE means script arrays\n    - AVSValue deep copy for arrays (arrays in arrays in ...)\n    - untyped and unconstrained element number\n    - access with indexes or in a dictionary-like associative way\n      array_variable = [[1, 2, 3], [4, 5, 8], \"hello\"]\n      dictionary = [[\"one\", 1], [\"two\", 2]]\n      empty = []\n      subarray = array_variable[0]\n      val = subarray[2]\n      val2 = array_variable[1, 3]\n      str = array_variable[2]\n      n = ArraySize(array_variable) #3\n      n2 = ArraySize(empty) #0\n      val3 = dictionary[\"two\"]\n    - arrays as filter parameters(named and unnamed)\n      new 'a' type or use '.+' or '.*' and check AVSValue IsArray()\n    - Concept is incompatible with avs 2.5 plugins due to their 'baked' interface code\n    - Demo script (to be cleaned up)\n      '''\n      ColorBars()\n      clip=last\n      a = [[1,2],[3,4]]\n      aa = [1]\n      b = a[1,1] + ArrayGet(a, 1,0) + aa[0]\n\n      empty_array = []\n      empty_array_2 = empty_array\n      #n3 = empty_array_2.ArrayGet(0) # array index out out range error!\n\n      black_yuv_16 = [0,32768,32768]\n      grey_yuv_16 = [32768,32768,32768]\n      white_yuv_16 = [65535,32768,32768]\n      aSelectColors = [\\\n        [\"black\", black_yuv_16],\\\n        [\"grey\", grey_yuv_16],\\\n        [\"white\",white_yuv_16],\\\n        [\"empty\",empty_array]\\\n      ]\n      test_array = [99, 1.0, \"this is a string\"] # mixed types\n      test_array2 = [199, 2.0, \"This is a string\"]\n\n      n = ArraySize(test_array) # 3\n      n2 = ArraySize(empty_array_2) # 0\n      sum = FirstNSum(grey_yuv_16,2)\n      b = b\n\n      clip = clip.Text(e\"Array size = \" + String(n) +\\\n       e\"\\n Empty array size = \" + String(n2) +\\\n       e\"\\n sum = \" + String(sum) +\\\n       e\"\\n b = \" + String(b) +\\\n       e\"\\n white_yuv_16[1]=\" + String(aSelectColors[\"white\"][1]) + \\\n       e\"\\n [0]=\" + String(ArrayGet(test_array,0)) + \\\n       e\"\\n [1]=\" + String(ArrayGet(test_array,1)) + \\\n       e\"\\n [2]=\" + ArrayGet(test_array,2), lsp=0, bold=true, font=\"info_h\")\n\n      return clip\n\n      function FirstNSum(array x, int n)\n      {\n        a = 0\n        for (i=0, x.ArraySize()-1) {\n          a = a + x[i]\n        }\n        return a\n      }\n      '''\n- Fix: Mix/Max Runtime function 32bit float chroma: return -0.5..0.5 range (was: 0..1 range)\n- AviSynth+ enhancements by Nekopanda (Neo fork)\n  - Allow multiple prefetchers (MT) (mentioned earlier)\n  - Multithreading and deadlock fixes for ScriptClip\n    (originally I intended to pull only Neo changes which were fixing an old AVS+ bug,\n     namely ScriptClip and multithreading. But I was not able to do that without pulling\n     nearly everything from Neo)\n  - Caching enhancements.\n    SetCacheMode(0) or SetCacheMode(CACHE_FAST_START) start up time and size balanced mode\n    SetCacheMode(1) or SetCacheMode(CACHE_OPTIMAL_SIZE) slow start up but optimal speed and cache size\n    Latter can do wonders especially at really low memory environment\n  - ScriptClip and variable stability in multithreading.\n    Compared to Neo, I extended it a bit.\n    Regarding visibility of variables: I had to change back from Neo's new default behaviour,\n    which was similar to GRunT's local=true and yielded incompatibility with the past.\n    So scripts written on the assumption of local = false did not work.\n    Neo's (valid) point: they would not allow the following script to show the behavior to print \"3\".\n    '''\n      # prints 3 - Avisynth default but seems incorrect\n      global foo=2\n      function PrintFoo(clip c)\n      { c.ScriptClip(\"Subtitle(string(foo))\", local = false) }\n      Version()\n      PrintFoo()\n      foo = 3\n      last\n\n      # prints 2 - Neo's default behaviour\n      global foo=2\n      function PrintFoo(clip c)\n      { c.ScriptClip(\"Subtitle(string(foo))\", local = true) }\n      Version()\n      PrintFoo()\n      foo = 3\n      last\n    '''\n\n    So all runtime filters* got a bool \"local\" parameter which acts same as in GRunT\n    * ConditionalSelect, ConditionalFilter, ScriptClip, ConditionalReader, FrameEvaluate,\n      WriteFile, WriteFileIf, WriteFileStart, WriteFileEnd\n\n    If local=true the filter will evaluate its run-time script in a new variable scope,\n    avoiding unintended sharing of variables between run-time scripts.\n    (As of current state (20200328): Neo's WriteFileStart and WriteFileEnd works like\n    local=false, in Avisynth compatible mode; all other runtime filters work in local=true mode in Neo)\n\n    In our present Avisynth+ all runtime filters are compatible with the usual behaviour,\n    but one can set the other mode by \"local=true\" parameter. This is when script is passed as string\n    Except: when the script parameter is not a string but a function (yes! Nekopanda made it available!)\n    then we in classic Avs! (haha, Classic+) kept Neo's new recommendation\n    and the default value of \"local\" is true.\n\n    (as a memo, ConditionalFilter still has the GRunT-like \"shortcut\" style parameter for bool results which implies \"=\" and \"true\"\n     and parameter \"condvarsuffix\" for ConditionalReader)\n  - UseVar, special filter, opens a clean variable environment in which only the\n    variables in the parameter list can be seen.\n\n  - \"escaped\" string constants: with e prefix right before the quotation mask\n    n\"Hello \\n\" will store actual LF (10) control character into the string\n    \\n \\r \\t \\0 \\a \\f \\\\ and \\\" are converted\n  - Introduce function objects into scripts\n    Functions can appear as standard Avisynth variables and parameters (AVSValue type='n')\n    https://github.com/nekopanda/AviSynthPlus/wiki/Language-New-Features\n    Even with variable capture [] (like in GRuntT args)\n\n  - Filter graph. Switch it on by putting SetGraphAnalysis(true) at the beginning of the script.\n    Dump to text file with DumpFilterGraph. E.g. DumpFilterGraph(\"graph.txt\", mode=2)\n    Output is in \"dot\" format, it can be converted to an image with Graphviz as follows:\n    '''\n    dot -Tsvg graph.txt -o graph.svg\n    '''\n\n    SetGraphAnalysis (bool)\n\n      Enables (True) or disables (False) graph node insertion into the instantiated filter.\n      To output a filter graph, a graph node must be inserted in the filter.\n      When a graph node is inserted, performance may decrease slightly due to the increase of internal function calls.\n      (In most cases, there is no observable performance degradation.)\n\n    DumpFilterGraph (clip, string \"outfile\", int \"mode\", int \"nframes\", bool \"repeat\")\n\n      Outputs a filter graph.\n\n      clip\n          Clip to output filter graph\n      string outfile = \"\"\n          Output file path\n      int mode = 0 *\n      int nframes = -1\n          Outputs the filter graph when processing the specified frame. The cache size and memory usage of each filter at that time are output together. This is effective when you want to know the memory usage of each filter. If -1, output when DumpFilterGraph is called (before the frame is processed).\n      bool repeat = false\n          Valid only when nframes> 0. Outputs a filter graph repeatedly at nframes intervals.\n\n  - Frame properties (still from Neo!)\n    (experimental, we have planned it in Avs+, probably we'll try to follow the\n    VapourSynth methods(?))\n\n20200322 3.6.0\n--------------\n- Fix: Multithreading enhancements and fixes (Nekopanda, from Neo fork)\n  - Fix old ScriptClip (runtime filters) issue\n    In this example \"current_frame\" variable was not seen by YDifferenceFromPrevious scripted within SubTitle\n    resulting in \"ERROR: Plane Difference: This filter can only be used within run-time filters\" message\n    Now this script finally works:\n      SetLogParams(\"log.txt\", LOG_DEBUG)\n      ColorBars(width=640, height=480, pixel_type=\"yv12\")\n      ScriptClip(last, \"Subtitle(String(YDifferenceFromPrevious))\")\n      Prefetch(4)\n  - Fix deadlock of ScriptClip on MT\n  - MT improvement\n    - Allow multiple Prefetchers\n    - Add argument to Prefetch to change # of prefetch frames without changing # of threads\n\n    Prefetch (clip c, int threads, int \"frames\")\n\n    In the original Plus, you could use only one Prefetch, but you can use any number of CUDA versions.\n    Also, an argument has been added to specify the number of frames to prefetch.\n    Prefetch (1,4) # Make 1 thread stand and prefetch 4 frames\n    By doing so, flexible parallelization configuration is possible, such as pipeline parallelization.\n\n    threads\n    Number of threads. If it is 0, it passes without doing anything.\n\n    frames\n    Number of frames to prefetch.\n    Again, if it is 0, it passes without doing anything.\n\n- Fix: BuildPixelType: chroma subsampling of sample clip was ignored.\n- POSIX: better behaviour under non-Windows because of having multiple sized fixed fonts, not only a single size=20 one.\n  e.g. MessageClip(), Info(), Version(), ColorYUV \"show\", internal ApplyMessage\n- Text filter:\n  - font types with\n    - \"Terminus\" fixed fonts added (12-14-16-18-20-22-24-28-32, regular + bold)\n    - \"Info_h\" good old 10x20 fixed font kept under this name\n  - much more international unicode characters (1354), use utf8=true under Windows\n  - use fontname parameter (default \"Terminus\", other choice is \"info_h\")\n  - use font_filename parameter (accepts BDF fonts at the moment - import is probably not too smart but worked for Terminus)\n  - use size parameter (12 to 32, if no size is available, a smaller one is chosen but at least the smallest one)\n  - new parameter: bold (default false)\n- Info() filter: when parameter \"size\" < 0, font is automatically enlarged over 640x480\n  (POSIX limit: minimum size is 12, maximum size is 32 - limited by available fixed fonts)\")\n- SIL OPEN FONT LICENSE added because of usage of Terminus fonts)\n- able to build w/o GDI and font rendering engine under Windows, so that text-overlay filters\n  work like in POSIX version of AviSynth+ (mainly for my development test)\n  Use with NO_WIN_GDI define.\n- Fix: ReplaceStr when the pattern string to be replaced is empty\n- New:\n  Exist() to have bool utf8 parameter\n  This is another function to have utf8 option:\n  Usage: b = Exist(\"Здравствуй.mkv\",utf8=true). Avs file is saved as utf8 w/o BOM\n- Fix: broken Exist for directories (regression appeared in 3.5.0)\n- Fix: ColorYUV: really disable variable search when parameter \"conditional\" is false\n- Development:\n  ScriptEnvironment::VSprintf: parameter (void *) is changed back to va_list.\n  May affect C interface (avs_vsprintf) and CPP interface (ScriptEnvironment::VSprintf)\n- Enhanced: Planar RGB to YUV 444 10-14 bits: more precision (32 bit float internally)\n- Enhanced: Planar RGB to YUV 444 10-16 bits: AVX2 (speed improvement)\n\n20200302 3.5.0\n--------------\n- New: Native Linux, macOS, and BSD support.\n- Fix: ConvertBits 32->8 for extremely out of range float pixel values.\n  When pixel value in a 32 bit float format video was way out of range and greater than 128 (e.g. instead of 0 to 1.0 for Y plane) then the ConvertBits(8) had artifacts.\n- Fix potential crash on exit or cache shrink (linux/gcc only?)\n- Layer: support RGB24 and RGB48 (internally processed as Planar RGB - lossless pre and post conversion)\n- Fix: RGBP to 444 8-14bit right side artifacts at specific widths\n- Fix: \"scalef\" and \"scaleb\" for 32 bit input, when scale_inputs=\"floatf\" produced wrong result\n- Fix: missing rounder in V channel calculation of PlanarRGB->YUV 8-14bits SSE2 code\n- Overlay: show error when Overlay is fed with clips with different bit depths\n- New function:\n  bool IsVersionOrGreater(int majorVersion, int minorVersion [,int bugfixVersion]) function\n  Returns true if the current version is equal or greater than the required one in the parameters.\n  The function is checking the current version against the given parameters (similar to a Windows API function)\n  e.g. IsVersionOrGreater(3, 4) or IsVersionOrGreater(3, 5, 8)\n- New: \"Expr\" helpers:\n  - Constants \"yrange_min\", \"yrange_half\", \"yrange_max\"\n    Unlike the luma/chroma plane adaptive \"range_min\", \"range_half\", \"range_max\" these constants always report the luma (Y) values\n  - new parameter: bool clamp_float_UV (default false)\n    this parameter affects clamping of chroma planes: chroma is clamped between 0..1.0 instead of -0.5..0.5s\n  - \"clamp_float\" is not ignored (and set to true) when parameter \"scale_inputs\" auto-scales 32 bit float type pixels\n  - New \"yscalef\" and \"yscaleb\" keywords similar to \"scalef\" and \"scaleb\" but scaling is forced to use rules for Y (non-UV) planes\n  - new allowed value \"floatUV\" for scale_inputs.\n    In short: chroma pre-shift by 0.5 for 32 bit float pixels\n    Affects the chroma plane expressions of 32 bit float formats.\n    Shifts the input up by 0.5 before processing it in the expression, thus values from -0.5..0.5 (zero centered) range are converted to the 0..1 (0.5 centered) one.\n    Since the expression result internally has 0..1.0 range, this then is shifted back to the original -0.5..0.5 range. (since 2.2.20)\n    Note: predefined constants such as cmin, cmax, range_min, range_max and range_half will be shifted as well, e.g. the expression will see range_half = 0.5\n  - These modifications are similar to Masktools2 2.2.20+\n- Fix: TemporalSoften possible access violation after SeparateFields (in general: after filters that only change frame pitch)\n- Fix: Shibatch.DLL Access Violation crash when exit when target rate is the same as vi.audio_samples_per_second or audio_samples_per_second is 0\n- Build system: Cmake: use platform toolset \"ClangCL\" for using built-in Clang support of Visual Studio.\n  Since VS2019 v16.4 there is LLVM 9.0 support.\n  Use: Tools|Get Tools and Features|Add Individual Components|Compilers, build tools, and runtimes\n       [X] C++ Clang compiler for Windows\n       [X] C++ Clang-cl for v142 build tools (x64/x86)\n  (for LLVM Clang installed separately, please use llvm or LLVM - no change in its usage)\n- New: AddBorders, LetterBox: new color_yuv parameter like in BlankClip\n- Fix: Resizers to really resize alpha channel (YUVA, RGBPA)\n- Fix: crash when outputting VfW (e.g. VirtualDub) for YUV444P16, other fixes for r210 and R10k formats\n- WavSource: really use \"utf8\" parameter, fix some debug asserts\n- TimeStrech: pass internal errors as Avisynth exception text (e.g. proper \"Excessive sample rate!\" instead of \"unhandled C++ error\")\n\n20191021 3.4.0\n--------------\n\n- Merges in the MT branch, the current state of pinterf/MT, and packaging fixes\n- Development HEAD is the master repo again in https://github.com/AviSynth/AviSynthPlus\n- Bumps version to 3.4\n\n20190829 r2915\n--------------\n- Changed: Trim, FreezeFrame, DeleteFrame, DuplicateFrame, Reverse and Loop are using frame cache again (similar to classic Avs 2.6)\n- Enhanced: Expr: faster exp, log, pow for AVX2 (sekrit-twc)\n- ConditionalReader: allow empty value in text file when TYPE string\n- Fix: Expr: fix non-mod-8 issues for forced RGB output and YUV inputs\n- New: AviSource support v308 and v408 format (packed 8 bit 444 and 4444)\n- Fix: AviSource v410 source garbage (YUV444P10)\n- Fix: Expr: when using parameter \"scale_inputs\" and the source bit depth conversion occured, predefined constants\n  (ymin/max, cmin/max, range_min/max/half) would not follow the new bit depth\n- Fix: ConvertToRGB from 32bit float YUV w/ full scale matrixes (pc.601, pc.709, average)\n- Fix: FlipHorizontal RGB48/64 artifacts\n- Enhanced: a bit quicker FlipHorizontal\n- Fix: RGB64 Blur leftmost column artifact\n- Enhanced: quicker RGB24/48 to Planar RGB for AVX2 capable processors\n- Fix: Strip alpha channel when origin is YUVA and using ConvertToYV12/ConvertToYV16/ConvertToYV24 funtions\n- Fix: garbage with ConvertToYUY2 from 8 bit YUVA colorspaces\n- Enhanced: Colorbars to accept RGB24, RGB48, YV411 and 4:2:2 formats for pixel_type (now all colorspaces are supported)\n- Fix: shifted chroma in ColorBars and ColorBarsHD for YUV444PS\n- Fix: ConvertToY8, ConvertToYV12, ConvertToYV16, ConvertToYV24 are now allowed only for 8 bit inputs.\n  Formerly these functions were allowed for 10+ bit colorspaces but were not converted to real 8 bit Y8/YV12/16/24.\n  Use ConvertToY, ConvertToYUV420, ConvertToYUV422, ConvertToYUV444 instead which are bit depth independent\n- New parameter in ColorYUV, RGBAdjust, Overlay, ConditionalReader.\n    string \"condvarsuffix\"\n  Allows multiple filter instances to use differently named conditional parameters.\n  Prevents collision and overwrite of variables which are used by different ConditionalReader instances.\n  See Conditional Variables section of http://avisynth.nl/index.php/ColorYUV.\n  How does it work: when reading the global variables, the \"condvarsuffix\" parameter is appended to the variable name.\n  E.g. ColorYUV will read \"coloryuv_gain_y_a\" instead of \"coloryuv_gain_y\" when condvarsuffix = \"_a\" is provided for ColorYUV.\n  In the matching ConditionalReader one have to use the modified name as well:\n      ConditionalReader(\"coloryuvoffset.txt\", \"coloryuv_gain_y\", false, CondVarSuffix = \"_a\") # \"_a\" is added here by parameter\n  or specify the suffixed name directly:\n      ConditionalReader(\"coloryuvoffset.txt\", \"coloryuv_gain_y_a\", false) # \"_a\" is added here manually\n\n  Example:\n    Colorbars(512,256).ConvertToYV12.Trim(0,299)\n    ConditionalReader(\"coloryuvoffset.txt\", \"coloryuv_gain_y\", false)\n    a=ColorYUV(cont_y=10, conditional=true)\n\n    Colorbars(512,256).ConvertToYV12.Trim(0,299)\n    ConditionalReader(\"coloryuvoffset2.txt\", \"coloryuv_gamma_y\", false, condvarsuffix=\"_a\")\n    b=ColorYUV(cont_y=10, conditional=true, condvarsuffix=\"_a\") # will read coloryuv_gain_y_a, coloryuv_gamma_y_a, etc.\n\n    Stackvertical(a,b)\n\n- Fix: ColorBars: pixel_type planar RGB will set alpha to 0 instead of 255, consistent with RGB32 Alpha channel\n- Fix: text colors for YUV422PS - regression since r2728 (zero-centered chroma)\n- New: VirtualDub2 to display 8 bit planar RGB (needs up-to-date VirtualDub2 as well)\n  VfW interface to negotiate 8 bit Planar RGB(A) with FourCCs: G3[0][8] and G4[0][8], similar to the 10-16 bit logic\n  (When you would still stick with RGB24/RGB32/RGB64 export, use OPT_Enable_PlanarToPackedRGB = true)\n- Fix: planar RGBA Alpha on VfW was uninitialized because it wasn't filled.\n- Layer: big update\n  Previously Layer was working only for RGB32 and YUY2. Overlay was used primarily for YUV. Now Layer accepts practically all formats (no RGB24).\n  Note that some modes can be similar to Overlay, but the two filters are still different.\n  Overlay accepts mask clip, Layer would use existing A plane.\n  Overlay \"blend\" is Layer \"add\", Overlay \"add\" is different.\n  Lighten and darken is a bit different in Overlay.\n  Layer has \"placement\" parameter for proper mask positioning over chroma.\n\n  - Support for all 8-32 bit Y and planar YUV/YUVA and planar RGB/RGBA formats\n    When overlay clip is YUVA and RGBA, then alpha channels of overlay clip are used (similarly to RGB32 and RGB64 formats)\n    Non-alpha plane YUV/planar RGB color spaces act as having a fully transparent alpha channel (like the former YUY2 only working mode)\n\n    Note: now if destination is YUVA/RGBA, the overlay clip also has to be Alpha-aware type.\n    Now A channel is not updated for YUVA targets, but RGBA targets do get the Alpha updated (like the old RGB32 mode did)\n    Todo: allow non-Alpha destination and Alpha-Overlay\n  - New parameter: float \"opacity\" (0.0 .. 1.0) optionally replaces the previous \"level\". Similar to \"opacity\" in \"Overlay\"\n    For usage of \"level\" see http://avisynth.nl/index.php/Layer\n    \"opacity\" parameter is bit depth independent, one does not have to fiddle with it like had to with level (which was maxed with level=257 when RGB32 but level=256 for YUY2/YUV)\n  - threshold parameter (used for lighten/darken) is autoscaled.\n    Keep it between 0 and 255, same as it was used for 8 bit videos.\n  - new parameter: string \"placement\" default \"mpeg2\".\n    Possible values: \"mpeg2\" (default), \"mpeg1\".\n    Used in \"mul\", \"darken\" and \"lighten\", \"add\" and \"subtract\" modes with planar YUV 4:2:0 or 4:2:2 color spaces (not available for YUY2)\n    in order to properly apply luma/overlay mask on U and V chroma channels.\n  - Fix some out-of-frame memory access in YUY2 C code\n  - Fix: Add proper rounding for add/subtract/lighten/darken calculations. (YUY2, RGB32, 8 bit YUV and 8 bit Planar RGB)\n  - Fix: \"lighten\" and \"darken\" gave different results between yuy2 and rgb32 when Threshold<>0\n    Fixed \"darken\" for RGB32 when Threshold<>0\n    Fixed \"lighten\" and \"darken\" for YUY2 when Threshold<>0\n    All the above was done by specification:\n    Add: \"Where overlay is brigher by threshold\" => e.g. Where overlay is brigther by 10 => Where overlay > src + 10\n    Calculation: alpha_mask = ovr > (src + thresh) ? level : 0;\n    Add: \"Where overlay is darker by threshold\" => e.g. Where overlay is darker by 10 => Where overlay < src - 10\n    Calculation: alpha_mask = ovr < (src - thresh) ? level : 0;\n    The only correct case of the above was \"lighten\" for RGB32, even in Classic Avisynth. Note: Threshold=0 was O.K.\n  - (Just an info: existing lighten/darken code for YUY2 is still not correct, messing up chroma a bit,\n     since it uses weights from even luma positions (0,2,4,...) for U, and odd luma positions (1,3,5,...) for V)\n- Avisynth C interface header (avisynth_c.h):\n  - cosmetics: functions regrouped to mix less AVSC_API and AVSC_INLINE, put together Avisynth+ specific stuff\n  - cosmetics: remove unused form of avs_get_rowsize and avs_get_height (kept earlier for reference)\n  - use #ifndef AVSC_NO_DECLSPEC for AVSC_INLINE functions which are calling API functions\n  - define alias AVS_FRAME_ALIGN as FRAME_ALIGN (keep the AVS_xxxx naming convention)\n  - dynamic loader (avs_load_library) uses fallback mechanism for non-existant Avisynth+ specific functions,\n    in order to have Avisynth+ specific API functions safely callable even when connected to classic Avisynth DLL\n    The smart fallback mechanism for Avisynth+ specific functions ensures that if the functions are not loadable,\n    they will work in a classic Avisynth compatible mode:\n    Example#1: e.g. avs_is_444 will call the existing avs_is_yv24 instead\n    Example#2: avs_bits_per_component will return 8 for all colorspaces (Classic Avisynth supports only 8 bits/pixel)\n    Affected functions and mapping:\n      avs_is_rgb48, avs_is_rgb64, avs_is_yuv444p16, avs_is_yuv422p16, avs_is_yuv420p16, avs_is_y16: returns false (0)\n      avs_is_yuv444ps, avs_is_yuv422ps, avs_is_yuv420ps, avs_is_y32: returns false (0)\n      avs_is_yuva, avs_is_planar_rgb, avs_is_planar_rgba: returns false (0)\n      avs_is_444: calls avs_is_yv24 instead\n      avs_is_422: calls avs_is_yv16 instead\n      avs_is_420: calls avs_is_yv12 instead\n      avs_is_y: calls avs_is_y8 instead\n      avs_num_components: returns 1 for y8, 4 for RGB32, 3 otherwise\n      avs_component_size: returns 1 (1 bytes)\n      avs_bits_per_component: returns 8 (8 bits)\n- filter \"Version\": update year, removed avs-plus.net link\n- Updated: TimeStretch plugin with SoundTouch 2.1.3 (as of 07.Jan 2019)\n- Source/Build system\n  - rst documentation update (qyot27) in distrib\\docs\\english\\source\\avisynthdoc\\contributing\\compiling_avsplus.rst\n  - GCC-MinGW build (huge thanks to qyot27)\n    - various source fixes for MinGW builds,\n      Avisynth core compiles fine, except external plugins Shibatch and DirectShowSource\n    - CMakeLists.txt updates (user selecteble CPU arch, MinGW things)\n    - PluginManager.cpp: [MSVC|GCC] should only load [MSVC|GCC] plugins (qyot27)\n      This commit simply tells GCC builds of AviSynth to use the value\n      of the PluginDir+GCC registry entry to find plugins, and ignore\n      PluginDir and PluginDir+.  Vice-versa for MSVC builds.\n      C plugins are an exception to this, since those can be loaded with\n      either MSVC- or GCC-built AviSynth+.\n    - GCC 8.3 support\n      (see in distrib\\docs\\english\\source\\avisynthdoc\\contributing\\compiling_avsplus.rst)\n      - Howto: MSYS2/GCC: for windows based build environment see step-by-step instructions:\n        https://github.com/orlp/dev-on-windows/wiki/Installing-GCC--&-MSYS2\n      - CMake: choose generator \"MinGW Makefiles\" from CMakeGUI or\n          del CMakeCache.txt\n          \"c:\\Program Files\\CMake\\bin\\cmake.exe\" -G \"MinGW Makefiles\" .\n        then build with\n          mingw32-make -f makefile\n      - todo: fix plugin DLL names\n  - CMake: Visual Studio 2019 generator support, please update to CMake to 3.14.1\n  - Clang (LLVM) support with Visual Studio 2019 (16.0) / 2017 (15.9.9) (Latest Clang is 8.0 at the moment)\n    - CMakeLists.txt update\n    - Additional source fixes.\n    - Source lines for different processor targets (SSSE3 and SSE4.1) are now separated and are compiled using function attributes.\n    Clang howto:\n    - Install LLVM 8.0 or later (http://releases.llvm.org/download.html, Windows pre-built libraries)\n    - Install Clang Power Tools & LLVM Compiler Toolchain (thx fuchanghao)\n      - https://marketplace.visualstudio.com/items?itemName=caphyon.ClangPowerTools\n      - https://marketplace.visualstudio.com/items?itemName=LLVMExtensions.llvm-toolchain\n    - (When using CMakeGUI) After Configure/Specify generator for this project, type LLVM for \"Optional Toolset to use (-T option)\"\n    - Known issues:\n      - compiling Avisynth only .lib is generated (used for C api), .exp is missing\n      - When generating assembler output linking or other errors can happen\n      - LLVM 8.0 has sub-optimal avg_epu8 intrinsic \"optimization\", which is fixed in LLVM 9.0 (e.g. in snapshot build 21 June 2019)\n\n20181220 r2772\n--------------\n- Fix: Expr: possible Expr x64 crash under specific memory circumstances\n- Fix: Expr: safer code for internal variables \"Store and pop from stack\" (see: Internal variables at http://avisynth.nl/index.php/Expr)\n\n20181218 r2768\n--------------\n- New: Expr: allow input clips to have more planes than an implicitely specified output format\n  Expr(aYV12Clip, \"x 255.0 /\", format=\"Y32\") # target is Y only which needs only Y plane from YV12 -> no error\n- New: Expr: Y-plane-only clip(s) can be used as source planes when a non-subsampled (rgb or 444) output format implicitely specified\n  Expr(Y, \"x\", \"x 2.0 /\", \"x 3.0 /\", format=\"RGBPS\") # r, g and b expression uses Y plane\n  Expr(Grey_r, Grey_g, Grey_b, \"x\", \"y 2.0 /\", \"z 3.0 /\", format=\"RGBPS\") # r, g and b expression uses Y plane\n- Fix: ConvertToYUY2() error message for non-8 bit sources.\n- Fix: Y32 source to 32 bit 420,422,444 (introduced in big the zero-chroma-center transition)\n- Fix: ShowY, ShowU, ShowV crash for YUV (non-YUVA) sources\n- Speedup: ConvertToY12/16... for RGB or YUY2 sources where 4:4:4 or YV16 intermediate clip was used internally\n  (~1.5-2x speed, was a regression in Avs+, use intermediate cache again)\n- Fix: Allow ExtractY on greyscale clips\n- ImageReader/ImageSource: use cache before FreezeFrame when result is a multiframe clip (fast again, regression since an early AVS+ version)\n- Resizers: don't use crop at special edge cases to avoid inconsistent results across different parameters/color spaces\n- Fix: Histogram 'classic': rare incomplete histogram shown in multithreading environment\n- Fix: ImageReader and ImageWriter: if path is \"\" then it works from/to the current directory.\n- GeneralConvolution: Allow 7x7 and 9x9 matrices (was: 3x3 and 5x5)\n- GeneralConvolution: All 8-32 bit formats (was: RGB32 only): YUY2 is converted to/from YV16, RGB24/32/48/64 are treated as planar RGB internally\n  Since 32 bit float input is now possible, matrix elements and bias parameter now is of float type.\n  For 8-16 bit clips the matrix is converted to integer before use.\n- GeneralConvolution: Allow chroma subsampled formats to have their luma _or_ chroma processed. E.g. set chroma=false for a YV12 input.\n- GeneralConvolution: new parameters: boolean luma (true), boolean chroma(true), boolean alpha(true)\n    Default: process all planes. For RGB: luma and chroma parameters are ignored.\n    Unprocessed planes are copied. Using alpha=false makes RGB32 processing faster, usually A channel is not needed.\n- GeneralConvolution: MT friendly parameter parsing\n- New: UTF8 filename support in AviSource, AVIFileSource, WAVSource, OpenDMLSource and SegmentedAVISource\n  All functions above have a new bool utf8 parameter. Default value is false.\n- Experimental: new syntax element (by addewyd): assignment operator \":=\" which returns the assigned value itself.\n  (Assignment within an expression)\n  Examples:\n    w := h := 256\n\n    b := blankclip(width=w * 2, height = h * 3, length=40, pixel_type=\"yv12\")\n    bm = blankclip(width=w, height = w).letterbox(2,0,2,0, color=$ff)\n    b\n\n    for(j = 0, 1, 1) {\n        for(i = 0, 1, 1) {\n            e = 0 + i * 16 + j * 16 * 4\n            ce = string(e)\n            c = bm.subtitle(\"Y = 0x\" + hex(e) + \" \" + ce)\n            eval(\"c\" + string(i) + string(j) + \" := c\")\n            b := b.overlay(c, x = i * w, y = j * h)\n        }\n    }\n\n    cx = c00.trim(0, 9) + c01.trim(0, 9) + c10.trim(0, 9) + c11.trim(0, 9)\n\n    b := overlay(cx, x = 0, y = w * 2)\n\n     /* defined NEW_AVSVALUE at build */\n    array = [99, 101, \"303\", cnt := 4]\n\n    for(j = 0, cnt - 1, 1) {\n        b := subtitle(string(array[ind := j]), x = 100, y=(j+1) * 20)\n    }\n\n    g := b.tstfunc(kf := \"first\", ks := \"second\")\n\n    g := subtitle((s := 4) > 0 ? t := \"left\" : t := \"right\", y = 100)\n    g := subtitle(string(s) + \" \" + t + \" \" + ks, y = 150)\n\n    eval(\"\"\"h := g.subtitle(\"G\", x=200, y = 20)\"\"\")\n\n    h.subtitle(\"H \" + string(ind), x = 300, y = 20)\n\n\n    function tstfunc(c, d, e) {\n        if (f := 1 < 2) {\n            c.subtitle(string(f) + e, y = 50)\n        } else {\n            c.subtitle(d, y = 50)\n        }\n    }\n\n\n\n20180702 r2728\n--------------\n- New: Expr: implement 'clip' three operand operator like in masktools2\n  Description: clips (clamps) value: x minvalue maxvalue clip -> max(min(x, maxvalue), minvalue)\n- New: Expr: Parameter \"clamp_float\"\n    True: clamps 32 bit float to valid ranges, which is 0..1 for Luma or for RGB color space and -0.5..0.5 for YUV chroma UV channels\n    Default false, ignored (treated as true) when scale_inputs scales float\n- New: Expr: parameter \"scale_inputs\" (default \"none\")\n\n    Autoscale any input bit depths to 8-16 bit for internal expression use, the conversion method is either full range or limited YUV range.\n\n    Feature is similar to the one in masktools2 v2.2.15\n\n    The primary reason of this feature is the \"easy\" usage of formerly written expressions optimized for 8 bits.\n\n    Use\n    - \"int\" : scales limited range videos, only integer formats (8-16bits) to 8 (or bit depth specified by 'i8'..'i16')\n    - \"intf\": scales full range videos, only integer formats (8-16bits) to 8 (or bit depth specified by 'i8'..'i16')\n    - \"float\" or \"floatf\" : only scales 32 bit float format to 8 bit range (or bit depth specified by 'i8'..'i16')\n    - \"all\": scales videos to 8 (or bit depth specified by 'i8'..'i16') - conversion uses limited_range logic (mul/div by two's power)\n    - \"allf\": scales videos to 8 (or bit depth specified by 'i8'..'i16') - conversion uses full scale logic (stretch)\n    - \"none\": no magic\n\n    Usually limited range is for normal YUV videos, full scale is for RGB or known-to-be-fullscale YUV\n\n    By default the internal conversion target is 8 bits, so old expressions written for 8 bit videos will probably work.\n    This internal working bit-depth can be overwritten by the i8, i10, i12, i14, i16 specifiers.\n\n    When using autoscale mode, scaleb and scalef keywords are meaningless, because there is nothing to scale.\n\n    How it works:\n    - This option scales all 8-32 bit inputs to a common bit depth value, which bit depth is 8 by default and can be\n      set to 10, 12, 14 and 16 bits by the 'i10'..'i16' keywords\n      For example: scale_inputs=\"all\" converts any inputs to 8 bit range. No truncation occurs however (no precision loss),\n      because even a 16 bit data is converted to 8 bit in floating point precision, using division by 256.0 (2^16/2^8).\n      So the conversion is _not_ a simple shift-right-8 in the integer domain, which would lose precision.\n    - Calculates expression (lut, lut_xy, lut_xyz, lut_xyza)\n    - Scales the result back to the original video bit depth.\n      Clamping (clipping to valid range) and converting to integer occurs here.\n\n    The predefined constants such as 'range_max', etc. will behave according to the internal working bit depth\n\n    Warning#1\n    This feature was created for easy porting earlier 8-bit-video-only lut expressions.\n    You have to understand how it works internally.\n\n    Let's see a 16bit input in \"all\" and \"allf\" mode (target is the default 8 bits)\n\n    Limited range 16->8 bits conversion has a factor of 1/256.0 (Instead of shift right 8 in integer domain, float-division is used or else it would lose presision)\n\n    Full range 16->8 bits conversion has a factor of 255.0/65535\n\n    Using bit shifts (really it's division and multiplication by 2^8=256.0):\n      result = calculate_lut_value(input / 256.0) * 256.0\n    Full scale 16-8-16 bit mode ('intf', 'allf')\n      result = calculate_lut_value(input / 65535.0 * 255.0 ) / 255.0 * 65535.0\n\n    Use scale_inputs = \"all\" (\"int\", \"float\") for YUV videos with 'limited' range e.g. in 8 bits: Y=16..235, UV=16..240).\n    Use scale_inputs = \"allf\" (intf, floatf) for RGB or YUV videos with 'full' range e.g. in 8 bits: channels 0..255.\n\n    When input is 32bit float, the 0..1.0 (luma) and -0.5..0.5 (chroma) channel is scaled\n    to 0..255 (8 bits), 0..1023 (i10 mode), 0..4095 (i12 mode), 0..16383(i14 mode), 0..65535(i16 mode) then back.\n\n    Warning#2\n    One cannot specify different conversion methods for converting before and after the expression.\n    Neither can you specify different methods for different input clips (e.g. x is full, y is limited is not supported).\n\n- Fix: Expr: expression string order for planar RGB is properly r-g-b like in original VapourSynth version, instead of counter-intuitive g-b-r.\n- Fix: Expr: check subsampling when a different output pixel format is given\n- Fix: ColorYUV: round to avoid green cast on consecutive TV<>PC\n- Enhanced: Limiter to work with 32 bit float clips\n- Enhanced: Limiter new parameter bool 'autoscale' default false.\n  If set, minimum/maximum luma/chroma values are treated as they were in 8 bit range (but non-integer values are allowed), limiter will autoscale it.\n  Default: does not scale at all, parameters are used as-is. Parameters now are of float type to handle 32 bit float values.\n- New: function bool VarExist(String variable_name)\n  Checks if a variable exists\n  Returns true if variable exists even if it holds 'Undefined', false otherwise\n- Fix: RGBAdjust memory leak when used in ScriptClip\n- Enhanced: RGBAdjust new parameter: conditional (like in ColorYUV)\n  The global variables \"rgbadjust_xxx\" with xxx = r, g, b, a, rb, gb, bb, ab, rg, gg, bg, ag are read each frame, and applied.\n  It is possible to modify these variables using FrameEvaluate or ConditionalReader.\n- Enhanced: RGBAdjust: support 32 bit float ('analyze' not supported, 'dither' silently ignored)\n- Enhanced: AviSource to support more formats with 10+ bit depth.\n  http://avisynth.nl/index.php/AviSource\n\n  When pixel_type is not specified or set to \"FULL\", AviSource will try to request the formats one-by-one in the order shown in the table below.\n\n  When a classic 'pixel_type' shares more internal formats (such as YUV422P10 first tries to request the v210 then P210 format)\n  you can specify one of the specific format directly. Note that high bit-depth RGBP is prioritized against packed RGB48/64.\n\n  The 'FourCCs for ICDecompressQuery' column means that when a codec supports the format, it will serve the frame in that one, Avisource then will convert it to the proper colorspace.\n\n  Full support list (* = already supported):\n  'pixel_type' Avs+ Format   FourCC(s) for ICDecompressQuery\n  YV24         YV24          *YV24\n  YV16         YV16          *YV16\n  YV12         YV12          *YV12\n  YV411        YV411         *Y41B\n  YUY2         YUY2          *YUY2\n  RGBP10       RGBP10        G3[0][10]  r210  R10k\n  r210         RGBP10        r210\n  R10k         RGBP10        R10k\n  RGBP         RGBP10        G3[0][10]  r210  R10k\n               RGBP12        G3[0][12]\n               RGBP14        G3[0][14]\n               RGBP16        G3[0][16]\n               RGBAP10       G4[0][10]\n               RGBAP12       G4[0][12]\n               RGBAP14       G4[0][14]\n               RGBAP16       G4[0][16]\n  RGB32        RGB32         *BI_RGB internal constant (0) with bitcount=32\n  RGB24        RGB24         *BI_RGB internal constant (0) with bitcount=24\n  RGB48        RGB48         BGR[48]    b48r\n  RGB64        RGB64         *BRA[64]   b64a\n  Y8           Y8            Y800       Y8[32][32]   GREY\n  Y            Y8            Y800       Y8[32][32]   GREY\n               Y10           Y1[0][10]\n               Y12           Y1[0][12]\n               Y14           Y1[0][14]\n               Y16           Y1[0][16]\n  YUV422P10    YUV422P10     v210       P210\n  v210         YUV422P10     v210\n  P210         YUV422P10     P210\n  YUV422P16    YUV422P16     P216\n  P216         YUV422P16     P216\n  YUV420P10    YUV420P10     P010\n  P010         YUV422P10     P010\n  YUV420P16    YUV420P16     P016\n  P016         YUV422P16     P016\n  YUV444P10    YUV444P10     v410\n  v410         YUV444P10     v410\n- Changed (finally): 32bit float YUV colorspaces: zero centered chroma channels.\n  U and V channels are now -0.5..+0.5 (if converted to full scale before) instead of 0..1\n  Note: filters that relied on having the U and V channel center as 0.5 will fail.\n  Why: the old UV 0..1 range was a very-very early decision in the high-bitdepth transition project. Also it is now\n  compatible with z_XXXXX resizers (zimg image library, external plugin at the moment).\n- New function: bool IsFloatUvZeroBased()\n  For plugin or script writers who want to be compatible with pre r2672 Avisynth+ float YUV format:\n    Check function availablity with FunctionExists(\"IsFloatUvZeroBased\").\n    When the function does not exists, the center value of 32 bit float U and V channel is 0.5\n    When IsFloatUvZeroBased function exists, it will return true (always for official releases) if U and V is 0 based (+/-0.5)\n- Fix: RGB64 Turnleft/Turnright (which are also used in RGB64 Resizers)\n- Fix: Rare crash in FrameRegistry\n- Enhanced: Allow ConvertToRGB24-32-48-64 functions for any source bit depths\n- Enhanced: ConvertBits: allow fulls-fulld combinations when either clip is 32bits\n  E.g. after a 8->32 bit fulls=false fulld=true:\n  Y: 16..235 -> 0..1\n  U/V: 16..240 -> -0.5..+0.5\n  Note: now ConvertBits does not assume full range for YUV 32 bit float.\n  Default values of fulls and fulld are now true only for RGB colorspaces.\n- Fix: couldn't see variables in avsi before plugin autoloads (colors_rgb.avsi issue)\n- Fix: LoadVirtualdubPlugin: Fix crash on exit when more than one instances of a filter was used in a script\n- New: LoadVirtualdubPlugin update:\n  - Update from interface V6 to V20, and Filtermod version 6 (partial)\n  - VirtualDub2 support with extended colorspaces\n    Allow RGB24, RGB48, RGB64 besides RGB32\n    AutoConvert 8 bit Planar RGB to/from RGB24, RGBPA to/from RGB32 (lossless)\n    AutoConvert RGB48 and 16 bit Planar RGB(A) to/from RGB64 (lossless)\n    Support YUV(A) 8 bits: YV12, YV16, YV24, YV411, YUVA420P8, YUVA422P8, YUVA444P8\n    Support YUV(A) 10-16 bits (properly set \"ref_x\" maximum levels, no autoconvert)\n  - Supports prefetchProc2 callback (API >= V14 and prefetchProc2 is defined) for multiple input frames from one input clip\n    PrefetchFrameDirect and PrefetchFrame are supported. PrefetchFrameSymbolic not supported\n  - Supports prefetchProc callback (API >= V12 and prefetchProc is defined)\n  - Supports when filter changes frame count of the output clip\n  - Extra filter parameter added at the end of filter's (unnamed) parameter list\n    Imported Virtualdub filters are getting and extra named parameter to the end:\n      String [rangehint]\n    This parameter can tell the filter about a YUV-type clip colorspace info\n    Allowed values:\n      \"rec601\": limited range + 601\n      \"rec709\": limited range + 709\n      \"PC.601\": full range + 601\n      \"PC.709\": full range + 709\n      \"\"      : not defined (same as not given)\n    Parameter will be ignored when clip is non-YUV\n    How it works: the hint will _not_ change the internal VirtualDub colorspace\n    constant (e.g. kPixFormat_YUV420_Planar -> kPixFormat_YUV420_Planar_709 will not happen).\n    Instead the base color space is kept and colorSpaceMode and colorRangeMode will set in PixmapLayout.formatEx.\n    Filter can either use this information or not, depending on supported API version and its implementation.\n    E.g. Crossfade(20,30) -> Crossfade(20,30,\"rec601\") though this specific filter won't use it.\n- New function: BuildPixelType\n\n  Creates a video format (pixel_type) string by giving a colorspace family, bit depth, optional chroma subsampling and/or a\n  template clip, from which the undefined format elements are inherited.\n  \"[family]s[bits]i[chroma]i[compat]b[oldnames]b[sample_clip]c\"\n\n  string family: YUV, YUVA, RGB, RGBA, Y\n  int bits: 8, 10, 12, 14, 16, 32\n  string chroma: for YUV(A) 420,422,444,411. Ignored for RGB(A) and Y\n  bool compat (default false): returns packed rgb formats for 8/16 bits (RGB default: planar RGB)\n  bool oldnames (default false): returns YV12/YV16/YV24 instead of YUV420P8/YUV422P8/YUV444P8\n  clip sample_clip: when supported, its format is overridden by specified parameters (e.g. only change bits=10)\n\n  Example#1: define YUV 444 P 10\n\n    family = \"YUV\"\n    bits = 10\n    chroma = 444\n    compat = false\n    oldformat = false\n    s = BuildPixelType(family, bits, chroma, compat, oldformat)\n    BlankClip(width=320,height=200,length=len,pixel_type=s,color=$008080).Info()\n\n  Example#2: Change only the bit depth of the format to 16\n\n    newbits = 16\n    c = last\n    s = BuildPixelType(bits=newbits, sample_clip=c)\n    BlankClip(width=320,height=200,length=len,pixel_type=s,color=$008080).Info()\n\n- Source: move to c++17, 'if constexpr' requires. Use Visual Studio 2017 (or GCC 7?). CMakeLists.txt changed.\n- Source: C api: AVSC_EXPORT to dllexport in capi.h for avisynth_c_plugin_init\n- Source: C api: avs_is_same_colorspace VideoInfo parameters to const\n- Project struct: changelog to git.\n- Include current avisynth header files and def/exp file in installer, when SDK is chosen\n\n20180328 r2664\n--------------\n-   Fix: YUY2 Sharpen overflow artifacts - e.g. Sharpen(0.6)\n-   Fix: Levels: 32 bit float shift in luma\n-   Fix: Merge sse2 for 10-14bits (regression)\n-   Fix: AVX2 resizer possible access violation in extreme resizes (e.g. 600->20)\n-   Fix: 32bit float PlanarRGB<->YUV conversion matrix\n-   Fix: VfW: fix b64a output for OPT_Enable_b64a=true\n-   Enhanced: VfW output P010 and P016 conversion to SSE2 (VfW output is used by VirtualDub for example)\n-   Enhanced: ColorYUV: recalculate 8-16 bit LUT in GetFrame only when changed frame-by-frame (e.g. in autowhite)\n-   Enhanced: ConvertBits 32->8 sse2/avx2 and 32->10..16 sse41/avx2 (8-15x speed)\n\nNot included, preliminary for the near future:\n-   Big change: 32 bit float YUV formats, U and V are now zero based.\n    Internally YUV 32 bit float chroma center became 0.0 (the neutral value which is 128 in the 8-bit world)\n    Like in VapourSynth or in avsresizer using z.lib image library.\n    'Expr' changes are affecting built-in constants/operators when used in chroma plane of a 32bit clip.\n    - 'cmin', 'cmax' return the zero-based shifted versions of the 16 and 240 (8 bit) values\n    - For U and V planes, constant 'range_half' results in 0.0 instead of the old 0.5\n    - 'scaleb' will also give zero-based result when found in an expression for chroma plane\n      (e.g. for a 32 bit float clip the '128 scaleb' will result in 0.0 instead of 128/255 for U and V planes)\n      But 'scalef' when the target or source of the constant conversion is 32bits, remains independent from the plane type.\n    - 'range_max' is 0.5 for 32 bit float chroma\n    - new constant 'range_min', which is -0.5 for 32 bit float chroma, (0 otherwise)\n\n    Additional warning: when you move 32bit float U or V plane to Y using CombinePlane, you have to be sure\n    that your filters do not rely on this new Y plane being in 0..1 range. Or else convert it by using Expr(\"x 0.5 +\") to the 0..1 range\n    Similarly: ExtractU and ExtractV will simply return the unaltered chroma planes, which are now zero-centered\n\n\n20180302 r2636\n--------------\n-   Fix: Blur/Sharpen crashed when YUY2.width<8, RGB32.width<4, RGB64.width<2\n-   ColorYUV: don't apply TV range gamma for opt=\"coring\" when explicit \"PC->TV\" is given\n-   ColorbarsHD: 32bit float properly zero (0.5)-centered chroma\n\n20180301 r2632\n--------------\n  - Fix: IsInterleaved returned false for RGB48 and RGB64 (raffriff42)\n  - Fix: SubTitle for Planar RGB/RGBA: wrong text colors (raffriff42)\n  - Fix: Packed->Planar RGB conversion failed on SSE2-only computers (SSSE3 instruction used)\n  - Enhanced: Blur, Sharpen\n    AVX2 for 8-16 bit planar colorspaces (>1.35x speed on i7-7770)\n    SSE2 for 32 bit float formats (>1.5x speed on i7-7770)\n  - Fix: Resizers for 32 bit float rare random garbage on right pixels (simd code NaN issue)\n  - Enhanced: Completely rewritten 16bit and float resizers, much faster (and not only with AVX2)\n  - Enhanced: 8 bit resizers: AVX2 support\n  - Enhanced: Speed up converting from RGB24/RGB48 to Planar RGB(A) - SSSE3, approx. doubled fps\n  - New: ConvertFPS supports 10-32 bits, planar RGB(A), YUV(A)\n  - New script function: int BitSetCount(int[, int, int, ...])\n    Function accepts one or more integer parameters\n    Returns the number of bits set to 1 in the number or the total number of '1' bits in the supplied integers.\n  - Cherry-picking from StainlessS' great RT_xxxx collection/and raffriff42 utils\n  - Modded script function: Hex(int , int \"width\"=0)\n    - New \"width\" parameter\n    - result is in uppercase\n    Width is 0 to 8, the _minimum_ width of the returned string. (8 hex digit is the max of Avisynth32 bit integer)\n    When width is 0 or not supplied then string length is a minimum needed.\n    Function now returns hex string in uppercase, instead of lowercase.\n    Example: Hex(255,4) returns \"00FF\".\n  - Modded script function: HexValue(String, \"pos\"=1)\n    - new pos parameter\n    Returns an int conversion of the supplied hexadecimal string.\n    Conversion will cease at the first non legal number base digit, without producing an error\n    Added optional pos arg default=1, start position in string of the HexString, 1 denotes the string beginning.\n    Will return 0 if error in 'pos' ie if pos is less than 1 or greater than string length.\n  - Modded script function: ReplaceStr(String, String, String[, Boolean \"sig\"=false])\n    - New parameter: sig for case insensitive search (Default false: exact search)\n      The uppercase/lowercase rules come from the current active code page of the OS.\n  - New script functions: TrimLeft, TrimRight, TrimAll for removing beginning/trailing whitespaces from a string.\n    Whitespaces: Tab (9), space (32), nbsp (160)\n  - New in ColorYUV:\n    New parameter: bool f2c=\"false\".\n    When f2c=true, the function accepts the Tweak-like parameters for gain, gamma and contrast\n    E.g. use 0/0.5/1.0/1.5/2.0/3.0 instead of -256/-128/0/128/256/512\n  - New/Fixed in ColorYUV:\n    Parameter \"levels\" accepts \"TV\". (can be \"TV->PC\", \"PC->TV\", \"PC->TV.Y\")\n    Now gamma calculation is TV-range aware when either\n    - levels is \"TV->PC\" or\n    - coring = true or\n    - levels is \"TV\" (new - no level conversion but gamma will know proper handling)\n    Previously gamma was properly calculated only for PC range.\n  - New in ColorYUV:\n    32 bit float support.\n    - 32 bit float uses the Expr filter (8-16 bits is LUT-based). The expression is dynamically assembled for each plane, internal precision is float.\n    - One can specify bits=32 when showyuv=true -> test clip in YUV420PS format\n    For 32 bit clips \"loose min\" and \"loose_max\" (omitting the extreme 1/256 population from dark and bright pixels) statistics are computed\n    by splitting the 0..1 into 65536 uniform ranges.\n - Modded: remove \"scale\" parameter from ConvertBits.\n   It was introduced at the very beginning of the 10+bit development, for 32bit float conversion - never used\n - Enhanced: VfW: exporting Y416 (YUV444P16) to SSE2.\n - 8-16 bit YUV chroma to 32 bit float: keep middle chroma level (e.g. 128 in 8 bits) at 0.5.\n   Calculate chroma as (x-128)/255.0 + 0.5 and not x/255.0 (Note: 32 bit float chroma center will be 0.0 in the future)\n - New: Histogram parameter \"keepsource\"=true (raffriff42)\n   keepsource = false returns only the Histogram w/o the original picture.\n   Affects \"classic\", \"levels\" and \"color\", \"color2\", ignored (n/a) for the other modes\n - New: Histogram type \"color\" to accept 8-32bit input and \"bits\"=8,9,..12 display range\n - New: Histogram parameter \"markers\"=true\n   When markers = false:\n   For \"classic\": no \"half\" level line and no invalid luma zone coloring\n   For \"levels\":  no \"half\" dotted line, no coloring (neither for YUV nor for RGB)\n   Ignored for the others at the moment.\n\n20171226 r2580\n----------------\n  - Fix (workaround): Merge: Visual Studio 2017 15.5.1/2 generated invalid AVX2 code\n    The x86 path of Merge Average was crashing due to bad code generation in the 8 bit version. Seems that thought\n    Visual Studio Team was proudly announcing optimizations in their compiler (15.5.x line), it had victims.\n  - Fix: Temporalsoften 10-14 bits: an SSE 4.1 instruction was used for SSE2-only CPU-s (Illegal Instruction on Athlon XP)\n\n20171219 r2574\n----------------\n  - Fix: MaskHS created inverse mask. Regression after r2173\n  - Build: changed avisynth.h, strict C++ conformity with Visual Studio 2017 /permissive- flag\n  - Installer (finally)\n  - Expr:\n    - new: Indexable source clip pixels by relative x,y positions like x[-1,1]\n    - new functions: sin cos tan asin acos atan\n    - new operator: % (modulo)\n    - new: Variables: uppercase letters A..Z for storing and reuse temporary results, frequently used computations.\n    - new: predefined expr variables 'frameno', 'time', 'width', 'height'\n    - fix: jitasm code generation at specific circumstances\n\n20171115 r2544\n  - Expr: fix \"scalef\" for 10-16 bits\n  - Expr optimization: eliminate ^1 +0 -0 *1 /1\n\n20171114 r2542\n  - New filter: Expr\n    Ported from Vapoursynth, with a lot of additional tweaks\n    e.g. AVX2, recognize constant fill, spatial absolute and relative coordinates as input, recognize plane copy,\n         no GetFrame for unused clips, converts ^2, ^3, ^4 into faster multiplication,\n         converts x^0.5 into sqrt(x), borrow specific syntax elements from masktools2 (scaling, operators - but not all of them) to have partial\n         compatibility in widely used existing expression strings (see readme.txt)\n\n    clip Expr(clip c[,clip c2, ...], string expr [, string expr2[, string expr3[, string expr4]]] [, string format]\n        [, bool optSSE2][, bool optAVX2][, bool optSingleMode])\n\n  Clip and Expr parameters are unnamed\n  'format' overrides the output video format\n  'optSSE2' to disable simd optimizations (use C code)\n  'optAVX2' to disable AVX2 optimizations (use SSE2 code)\n  'optSingleMode' default false, to generate simd instructions for one XMM/YMM wide data instead of two. Experimental.\n     One simd cycle processes 8 pixels (SSE2) or 16 pixels (AVX2) at a time by using two XMM/YMM registers as working set.\n     Very-very complex expressions would use too many XMM/YMM registers which are then \"swapped\" to memory slots, that can be slow.\n     Using optSingleMode = true may result in using less registers with no need for swapping them to memory slots.\n\n  Expr accepts 1 to 26 clips as inputs and up to four expression strings, an optional video format overrider, and some debug parameters.\n  Output video format is inherited from the first clip, when no format override.\n  All clips have to match their dimensions and plane subsamplings.\n\n  Expressions are evaluated on each plane, Y, U, V (and A) or R, G, B (,A).\n  When an expression string is not specified, the previous expression is used for that plane. Except for plane A (alpha) which is copied by default.\n  When an expression is an empty string (\"\") then the relevant plane will be copied (if the output clip bit depth is similar).\n  When an expression is a single clip reference letter (\"x\") and the source/target bit depth is similar, then the relevant plane will be copied.\n  When an expression is constant, then the relevant plane will be filled with an optimized memory fill method.\n  Expressions are written in Reverse Polish Notation (RPN).\n\n  Expressions use 32 bit float precision internally\n\n  For 8..16 bit formats output is rounded and clamped from the internal 32 bit float representation to valid 8, 10, ... 16 bits range.\n  32 bit float output is not clamped at all.\n\n  - Clips: letters x, y, z, a, ... w. x is the first clip parameter, y is the second one, etc.\n  - Math: * / + -\n  - Math constant: pi\n  - Functions: min, max, sqrt, abs, neg, exp, log, pow ^ (synonyms: \"pow\" and \"^\")\n  - Logical: > < = >= <= and or xor not == & | != (synonyms: \"==\" and \"=\", \"&\" and \"and\", \"|\" and \"or\")\n  - Ternary operator: ?\n  - Duplicate stack: dup, dupN (dup1, dup2, ...)\n  - Swap stack elements: swap, swapN (swap1, swap2, ...)\n  - Scale by bit shift: scaleb (operand is treated as being a number in 8 bit range unless i8..i16 or f32 is specified)\n\n  - Scale by full scale stretch: scalef (operand is treated as being a number in 8 bit range unless i8..i16 or f32 is specified)\n\n  - Bit-depth aware constants\n    ymin, ymax (ymin_a .. ymin_z for individual clips) - the usual luma limits (16..235 or scaled equivalents)\n\n    cmin, cmax (cmin_a .. cmin_z) - chroma limits (16..240 or scaled equivalents)\n\n    range_half (range_half_a .. range_half_z) - half of the range, (128 or scaled equivalents)\n\n    range_size, range_half, range_max (range_size_a .. range_size_z , etc..)\n\n  - Keywords for modifying base bit depth for scaleb and scalef: i8, i10, i12, i14, i16, f32\n\n  - Spatial input variables in expr syntax:\n    sx, sy (absolute x and y coordinates, 0 to width-1 and 0 to height-1)\n    sxr, syr (relative x and y coordinates, from 0 to 1.0)\n\n  Additions and differences to VS r39 version:\n\n  ------------------------------\n--------------\n  (similar features to the masktools mt_lut family syntax)\n\n  Aliases:\n\n    introduced \"^\", \"==\", \"&\", \"|\"\n  New operator: != (not equal)\n\n  Built-in constants\n\n    ymin, ymax (ymin_a .. ymin_z for individual clips) - the usual luma limits (16..235 or scaled equivalents)\n\n    cmin, cmax (cmin_a .. cmin_z) - chroma limits (16..240 or scaled equivalents)\n\n    range_half (range_half_a .. range_half_z) - half of the range, (128 or scaled equivalents)\n\n    range_size, range_half, range_max (range_size_a .. range_size_z , etc..)\n\n  Autoscale helper functions (operand is treated as being a number in 8 bit range unless i8..i16 or f32 is specified)\n\n    scaleb (scale by bit shift - mul or div by 2, 4, 6, 8...)\n\n    scalef (scale by stretch full scale - mul or div by source_max/target_max\n\n  Keywords for modifying base bit depth for scaleb and scalef\n: i8, i10, i12, i14, i16, f32\n\n  Built-in math constant\n\n    pi\n\n  Alpha plane handling\n. When no separate expression is supplied for alpha, plane is copied instead of reusing last expression parameter.\n  Proper clamping when storing 10, 12 or 14 bit outputs\n\n  (Faster storing of results for 8 and 10-16 bit outputs, fixed in VS r40)\n  16 pixels/cycle instead of 8 when avx2, with fallback to 8-pixel case on the right edge. Thus no need for 64 byte alignment for 32 bit float.\n  (Load zeros for nonvisible pixels, when simd block size goes beyond image width, to prevent garbage input for simd calculation)\n\n\n  Optimizations: x^0.5 is sqrt, ^1 +0 -0 *1 /1 to nothing, ^2, ^3, ^4 is done by faster and more precise multiplication\n  Spatial input variables in expr syntax:\n    sx, sy (absolute x and y coordinates, 0 to width-1 and 0 to height-1)\n    sxr, syr (relative x and y coordinates, from 0 to 1.0)\n  Optimize: recognize constant plane expression: use fast memset instead of generic simd process. Approx. 3-4x (32 bits) to 10-12x (8 bits) speedup\n  Optimize: Recognize single clip letter in expression: use fast plane copy (BitBlt)\n    (e.g. for 8-16 bits: instead of load-convert_to_float-clamp-convert_to_int-store). Approx. 1.4x (32 bits), 3x (16 bits), 8-9x (8 bits) speedup\n\n  Optimize: do not call GetFrame for input clips that are not referenced or plane-copied\n\n  Recognize constant expression: use fast memset instead of generic simd process. Approx. 3-4x (32 bits) to 10-12x (8 bits) speedup\n    Example: Expr(clip,\"128\",\"128,\"128\")\n\n  Differences from masktools 2.2.10\n  --------------------------------\n-\n  Up to 26 clips are allowed (x,y,z,a,b,...w). Masktools handles only up to 4 clips with its mt_lut, my_lutxy, mt_lutxyz, mt_lutxyza\n\n  Clips with different bit depths are allowed\n\n  Works with 32 bit floats instead of 64 bit double internally\n\n  Less functions (e.g. no bit shifts)\n\n  No float clamping and float-to-8bit-and-back load/store autoscale magic\n\n  Logical 'false' is 0 instead of -1\n\n  The ymin, ymax, etc built-in constants can have a _X suffix, where X is the corresponding clip designator letter. E.g. cmax_z, range_half_x\n\n  mt_lutspa-like functionality is available through \"sx\", \"sy\", \"sxr\", \"syr\"\n\n  No y= u= v= parameters with negative values for filling plane with constant value, constant expressions are changed into optimized \"fill\" mode\n\n  Sample:\n\n  Average three clips:\n  c = Expr(clip1, clip2, clip3, \"x y + z + 3 /\")\n  using spatial feature:\n  c = Expr(clip1, clip2, clip3, \"sxr syr 1 sxr - 1 syr - * * * 4096 scaleb *\", \"\", \"\")\n\n  - Add: Levels: 32 bit float format support\n  - Fix: RGB (full scale) conversion: 10-16 bits to 8 bits rounding issue; pic got darker in repeated 16<->8 bit conversion chain\n  - Fix: ConvertToY: remove unnecessary clamp for Planar RGB 32 bit float\n  - Fix: RGB ConvertToY when rec601, rec709 (limited range) matrix. Regression since r2266\n  - Optimized: Faster RGB (full scale) 10-16 bits to 8 bits conversion when dithering\n  - Other: Default frame alignment is 64 bytes (was: 32 bytes). (independently of AVX512 support)\n  - Build:\n    Built with Visual Studio 2017, v141_xp toolset\n    Note that DLL will work When you have VS2015 Update 3 redistributable.\n\n    Download Visual Studio 2017 Redistributable from here (replaces and compatible with VS2015 redist)\n\n    X64:\n    https://go.microsoft.com/fwlink/?LinkId=746572\n\n    x86:\n    https://go.microsoft.com/fwlink/?LinkId=746571\n\n  - Experimental x64 builds for test (internal offsets from int to size_t)\n    (later note: idea was dropped because of incompatibility; too many x64 plugins out there)\n  - Source: avisynth_c.h (C interface header file) changed:\n    Optional define SIZETMOD. Experimental. Offsets are size_t instead of int (x64 is different!)\n    Fix: avs_get_row_size calls into avs_get_row_size_p, instead of direct field access\n    Fix: avs_get_height calls into avs_get_row_size_p, instead of direct field access.\n\n20170629 r2508\n  - Fix TemporalSoften: threshold < 255 (probably since r1576)\n\n20170608 r2506\n  - Fix CombinePlanes: feeding YV16 or YV411 target with Y8 sources\n\n20170603 r2504\n  - fix XP support broken in r2502\n\n20170602 r2502\n  - fix: (Important!) MT_SERIALIZED mode did not always protect filters (regression since r2069)\n    Such filters sometimes were called in a reentrant way (like being MT_NICE_FILTER), which\n    possibly resulted in using their internal buffers parallel.\n  - Fix: ImageWriter crash when no '.' in provided filename\n  - Fix: Overlay: correct masked blend: keep exact clip1 or clip2 pixel values for mask extremes 255 or 0.\n    Previously 0 became 1 for zero mask, similarly 255 changed into 254 for full transparency (255) mask\n  - New: script functions: StrToUtf8, StrFromUtf8: Converting a 8 bit (Ansi) string to UTF8 and back.\n  - New: PluginManager always throws error on finding wrong bitness DLL in the autoload directories\n  - Modified: increased x64 default MemoryMax from 1GB to 4GB, but physicalRAM/4 is still limiting\n  - Modified: allow conversions between RGB24/32/48/64 (8<->16 bits) w/o ConvertBits\n  - Added VS2017 and v141_xp to CMakeList.txt\n\n20170529 r2489\n  - fix: memory leak in CAVIStreamSynth (e.g. feeding vdub)\n  - fix: ConvertToY for RGB64 and RGB48\n\n20170528 r2487\n  - Blur, Sharpen 10-16 bits planar and RGB64: SSE2/SSE4 (2x-4x speed)\n  - New script function: int GetProcessInfo([int type = 0])\n    Without parameter or type==0 the current bitness of Avisynth DLL is returned (32 or 64)\n    With type=1 the function can return a bit more detailed info:\n    -1: error, can't establish\n    0: 32 bit DLL on 32 bit OS\n    1: 32 bit DLL on 64 bit OS (WoW64 process)\n    2: 64 bit DLL\n  - Fix: Blur width=16 (YV12 width=32)\n  - Fix: Overlay Lighten: artifacts when base clip and overlay clip have different widths (regression since r2290)\n  - Fix: YUY2 HorizontalReduceBy2 did nothing if target width was not mod4\n  - ImageReader: 16 bit support; \"pixel_type\" parameter new formats \"RGB48\", \"RGB64\" and \"Y16\"\n  - ImageWriter: 16 bit support; save RGB48, RGB64, Y16, planar RGB(A) 8 and 16 bit formats\n    (note: greyscale through devIL can be corrupt with some formats, use png)\n  - ImageWriter: flip greyscale images vertically (except \"raw\" format)\n  - SubTitle: new parameter \"font_filename\" allows using non-installed fonts\n  - (project can be compiled using gcc)\n  - Allows opening unicode filenames through VfW interface (virtualdub, MPC-HC)\n  - Script function Import: new parameter bool \"utf8\" to treat the filenames as UTF8 encoded\n    (not the script text!)\n  - SubTitle: new parameter bool \"utf8\" for drawing strings encoded in UTF8.\n      Title=\"Cherry blossom \"+CHR($E6)+CHR($A1)+CHR($9C)+CHR($E3)+CHR($81)+CHR($AE)+CHR($E8)+CHR($8A)+CHR($B1)\n      SubTitle(Title,utf8=true)\n  - New script functions: ScriptNameUtf8(), ScriptFileUtf8(), ScriptDirUtf8(),\n    they return variables $ScriptNameUtf8$, $ScriptFileUtf8$ and $ScriptDirUtf8$ respectively\n\n  Known issues:\n  - Filters with MT_SERIALIZED sometimes can get called in a reentrant way\n  - Runtime Script functions under MT\n\n\n20170316 r2455\n  - Fix: IsY() script function returned IsY8() (VideoInfo::IsY was not affected)\n  - New: ConvertBits, dither=1 (Floyd-Steinberg): allow any dither_bits value between 0 and 8 (0=b/w)\n\n20170310 r2440\n  - Fix Merge for float formats\n  - Fix error text formatting under wine (_vsnprintf_l issue)\n  - Fix Regression: YUY2 UToY copied V instead of U, since August, 2016 (v2150)\n\n  - faster Merge: float to sse2 (both weighted and average)\n  - faster ordered dither to 8bit: SSE2 (10x speed)\n\n  - ColorBars allows any 4:2:0, 4:4:4 formats, RGB64 and all planar RGB formats\n  - ColorBarsHD accepts any 4:4:4 formats\n  - Dithering: Floyd-Steinberg\n    Use convertBits parameter dither=1: Floyd-Steinberg (was: dither=0 for ordered dither)\n  - Dithering: parameter \"dither_bits\"\n    For dithering to lower bit depths than the target clip format\n    Usage: ConvertBits(x, dither=n [, dither_bits=y])\n    - ordered dither: dither_bits 2, 4, 6, ... but maximum difference between target bitdepth and dither_bits is 8\n    - Floyd-Steinberg: dither_bits 1, 2, 4, 6, ... up to target bitdepth - 2\n    (Avisynth+ low bitdepth, Windows 3.1 16 bit feeling I was astonished that dither_bits=6 still resulted in a quite usable image)\n  - Dithering is allowed from 10-16 -> 10-16 bits (was: only 8 bit targets)\n  - Dithering is allowed while keeping original bit-depth. clip10 = clip10.ConvertBits(10, dither=0, dither_bits=8)\n    (you still cannot dither from 8 or 32 bit source)\n  - ConditionalFilter syntax extension like Gavino's GConditional: no \"=\" \"true\" needed\n  - Revert: don't give error for interlaced=true for non 4:2:0 sources (compatibility, YATTA)\n  - CombinePlanes: silently autoconvert packed RGB/YUY2 inputs to planar\n  - ConvertBits: show error message on YV411 conversion attempt: 8 bit only\n  - ConvertBits: Don't give error message if dither=-1 (no dithering) is given for currently non-ditherable target formats\n  - Script function: IsVideoFloat. returns True if clip format is 32 bit float. For convenience, same as BitsPerComponent()==32\n  - ConvertToDoubleWidth and ConvertFromDoubleWidth: RGB24<->RGB48, RGB32<->RGB64\n  - New MT mode: MT_SPECIAL_MT. Specify it for MP_Pipeline like filters, even if no Prefetch is used (MP_Pipeline issue, 2 fps instead of 20)\n\n\n20170202 r2420\n  - CombinePlanes:\n    When there is only one input clip, zero-cost BitBlt-less subframes are used, which is much faster.\n\n    e.g.: casting YUV to RGB, shuffle RGBA to ABGR, U to Y, etc..\n    Target planes that are not specified, preserve their content.\n\n    Examples:\n    combineplanes(clipRGBP, planes=\"RGB\",source_planes=\"BGR\") # swap R and B\n    combineplanes(clipYUV, planes=\"GBRA\",source_planes=\"YUVA\",pixel_type=\"RGBAP8\") # cast YUVA to planar RGBA\n    combineplanes(clipYUV, planes=\"Y\",source_planes=\"U\",pixel_type=\"Y8\") # extract U\n\n  - fix: SubframePlanarA (available in IScriptEnvironment2)\n  - faster: Difference-type conditional functions: Simd for 10-16 bits\n  - Fix: MinMax-type conditional functions (min, max, median): return float value for float clips\n  - ConvertToPlanarRGB(A):\n    PlanarRGB <-> PlanarRGBA is now allowed\n  - ConvertToPlanarRGB(A):\n    YUY2 source is now allowed (through automatic ConvertToRGB proxy)\n  - faster: RemoveAlphaPlane (subframe instead of BitBlt copy)\n  - Overlay: \"Blend\" native greyscale mode: process y plane only w/o conversion\n  - Overlay: automatic use444=false for \"blend\"/\"luma\"/\"chroma\"\n    for inputs: 420/422/444 and any RGB, lossless Planar RGB intermediate for PackedRGB\n    Overlay/mask auto-follows input clip format.\n    For compatibility: when greymask=true (default) and mask is RGB then mask source is the B channel\n  - faster: RGB48->RGB64 SSSE3 (1,6x), RGB64->RGB48 SSSE3 (1.5x speed)\n  - faster: RGB24,RGB48->PlanarRGB: uses RGB32/64 intermediate clip\n  - Histogram \"levels\": allow RGB24/32/48/64 input.\n    Display R, G and B channels instead of Y, U and V\n    Reminder 1: \"levels\" for Planar RGB was working already\n    Reminder 2: Histogram \"levels\" and \"Classic\" allows bits=xx parameter, xx=8..12\n                If \"bits\" is specified then Histogram is drawn with 9..12 bits precision. Get a wide monitor though :)\n  - ConvertBits: new parameters, partially for the future.\n    bool fulls, bool fulld\n\n    For YUV and greyscale clips the bit-depth conversion uses simple bit-shifts by default.\n    YUV default is fulls=false\n\n    RGB is converted as full-stretch (e.g. 0..255->0..65535)\n    RGB default is fulls=true\n\n    If fulld is not specified, it takes the value of fulls.\n    Use case: override greyscale conversion to fullscale instead of bit-shifts\n\n    Note 1: conversion from and to float is always full-scale\n    Note 2: alpha plane is always treated as full scale\n    Note 3: At the moment you cannot specify fulld to be different from fulls.\n\n\n20170119 r2397\n  - TemporalSoften: Planar RGB support\n  - TemporalSoften: much faster average mode (thres=255)\n    radius=1 +70%, radius=2 +45%,\n    16bit: generally 7-8x speed (SSE2/4 instead of C)\n  - SeparateColumns: 10-16bit,float,RGB48/64\n  - WeaveColumns: 10-16bit,float,RGB48/64,PlanarRGB(A)\n  - AddAlphaPlane: fix function parameter type list, clip type did not work\n  - Internals: add SubframePlanarA to IScriptEnvirontment2 for frames with alpha plane\n    General note: unlike IScriptEnvironment (that is rock solid for the time beeing), IScriptEnvironment2 is still not final.\n    It is used within Avisynth+ core, but is also published in avisynth.h.\n    It contains avs+ specific functions, that could not be stuffed into IScriptEnvironment without killing compatibility.\n    Although it changes rarely, your plugin may not work with Avisynth+ versions after a change\n\n  - SwapUV: YUVA support\n  - ConvertToRGB32/64: copy alpha from YUVA\n  - SeparateRows,SeparateFields: PlanarRGB(A),YUVA support\n  - WeaveRows: PlanarRGB(A), YUVA\n  - Weave (fields,frames): YUVA,PlanarRGB(A)\n  - Crop: Fast crop possible for frames with alpha plane (subframe)\n  - AddBorders missing l/r/top/bottom vs. subsampling check for YUVA\n  - Fix: YUVA->PlanarRGBA and YUVA42x->444 missing alpha plane copy\n  - YUV444->RGB48/64: fast intermediate PlanarRGB(A) then RGB48/64 (not C path)\n  - RGB48/64->YUV4xx target: Planar RGB intermediate (instead of C, 10x faster)\n\n20170111 r2380\n  - Overlay: Merge the source of Chroma and Luma modes into Blend mode\n             Modes Blend,Luma and Chroma now support all bit depths and 444 conversionless (use444=false) mode\n  - Overlay: fix SSE2 Blend for mask+opacity for 10-16 bits\n  - VfW: (vdubmod14 VfW test)\n    Fix: YUV444P16 or YUVA444P16 to fourcc Y416\n         if alpha channel is present, it will we copied, else filled with FFFF\n    Fix: VDubPlanarHack is checked only for 8 bit YUV planar sources\n20170110 r2372  (vdubmod14 VfW test)\n  - New: SSE2/SSE4 for 10-16 bit <-> 10-16 bit Planar RGB (and Alpha plane) full scale conversions\n    (needed for automatic planar RGB -> packed RGB VfW conversions)\n  - VfW:\n    Fixed: Y3[10][10],Y3[10][16] fourcc's byte order\n    New: Planar RGB(A) (MagicYUV)\n         10,12,14,16 bits: G3[0][10], G4[0][10], G3[0][12], G4[0][12], G3[0][14], G4[0][14], G3[0][16], G4[0][16]\n    New: YUV444P16 to fourcc Y416\n    New: Automatic conversion of 12, 14 and float YUV formats to 16 bit for 4:2:0 and 4:2:2\n         Note: OPT_Enable_Y3_10_16 is still valid as if format was originally 16 bits\n    New: Automatic conversion of 10, 12, 14 and float YUV formats to 16 bit for 4:4:4\n    New: Conversion of 10, 12, 14 and float planar RGB formats to RGB64\n         when global Avisynth variable Enable_PlanarToPackedRGB is true\n    New: Conversion of 8 bit planar RGB formats to RGB24\n         when global Avisynth variable Enable_PlanarToPackedRGB is true\n    New: Conversion of 8 bit planar RGBA formats to RGB32\n         when global Avisynth variable Enable_PlanarToPackedRGB is true\n\n    Note: use OPT_VDubPlanarHack=true for YV16 and YV24 for old VirtualDub\n\n    Supported formats:\n    BRA[64],b64a,BGR[48],P010,P016,P210,P216,Y3[10][10],Y3[10][16],v210,Y416\n    G3[0][10], G4[0][10], G3[0][12], G4[0][12], G3[0][14], G4[0][14], G3[0][16], G4[0][16]\n\n    Default format FourCCs:\n    Avisynth+ will report these FourCC-s, override them with defining OPT_xxx global variables\n    RGB64: BRA[64]\n    RGB48: BGR[48]\n    YUV420P10: P010\n    YUV420P16: P016\n    YUV422P10: P210\n    YUV422P16: P216\n    YUV444P16 and YUVA444P16: Y416\n    Planar RGB  10,12,14,16 bits: G3[0][10], G3[0][12], G3[0][14], G3[0][16]\n    Planar RGBA 10,12,14,16 bits: G4[0][10], G4[0][12], G4[0][14], G4[0][16]\n\n    Global variables to override default formats:\n    Put them at the beginning of avs script.\n    OPT_Enable_V210 = true --> v210 for YUV422P10\n    OPT_Enable_Y3_10_10 = true --> Y3[10][10] for YUV422P10\n    OPT_Enable_Y3_10_16 = true --> Y3[10][16] for YUV422P16\n    OPT_Enable_b64a = true --> b64a for RGB64\n    Enable_PlanarToPackedRGB = true --> RGBP8->RGB24, RGBAP8->RGB32, all other bit depths to RGB64\n\n20170109 r2367dev\n  - VfW: BRA[64],b64a,BGR[48],P010,P016,P210,P216,Y3[10][10],Y3[10][16],v210\n    experimental!\n    Default format FourCCs:\n    RGB64: BRA[64]\n    RGB48: BGR[48]\n    YUV420P10: P010\n    YUV420P16: P016\n    YUV422P10: P210\n    YUV422P16: P216\n    Global variables to override default formats:\n    OPT_Enable_V210 = true --> v210 for YUV422P10\n    OPT_Enable_Y3_10_10 = true --> Y3[10][10] for YUV422P10\n    OPT_Enable_Y3_10_16 = true --> Y3[10][16] for YUV422P16\n    OPT_Enable_b64a = true --> b64a for RGB64\n  - Overlay: blend for float format\n  - Overlay: blend: SSE4 for 10-16 bit, SSE2 for float\n  - AddAlphaPlane: also accepts clip with Y-only or alpha (YUVA/PRGBA/RGB32/64) for alpha source\n    (was: optional int/float mask value)\n\n20170104 r2359dev\n  - Overlay:\n    new parameter: bool use444 (default true for compatibility)\n\n    Parameter is valid only for \"blend\" at the moment\n\n    When set to false, and base clip/overlay clip is 420/422/Planar RGB, the overlay core\n    does not convert to and back from YV24 (4:4:4 in general)\n\n    mask can be either greyscale or can be any planar YUV when greymask=true (default)\n\n    Works for Planar RGB, so blending is basically lossless for this format (no YUV conversion)\n\n    todo: support for other modes, convert packed RGB to planar RGB internally instead of YUV\n  - Overlay:\n    Add fast 4:2:0<->4:4:4 conversion, e.g. YV16<->YV24 (only fast YUY2 and YV12 existed so far)\n    instead of invoking generic core conversion\n  - Overlay:\n    10-16bit SSE2/SSE4 for 420/422<->444 conversions\n  - Info() made a bit more compact.\n    Bit depth info moved after color space info\n    Does not display pre-SSE2 CPU flags when at least AVX is available\n    Display AVX512 flags in separate line (would be too long)\n\n    Reminder: Info() now has more parameters than is classic Avisynth:\n      Info(): c[font]s[size]f[text_color]i[halo_color]i\n    Added font (default Courier New), size (default 18), text_color and halo_color parameters, similar to (but less than) e.g. in ShowFrameNumber.\n\n  - new CPU feature constants (see cpuid.h and avisynth_c.h)\n    Detect FMA4 and AVX512F,DQ,PF,ER,CD,BW,VL,IFMA,VBMI\n  - new script function:\n    string ReplaceStr(string s, string pattern, string replacement)\n    Function is case sensitive, parameters are unnamed\n  - new script function\n    int NumComponents(clip)\n    returns 1 for grayscale, 3 for YUVxxx, YUY2, planar RGB or RGB24/RGB48, 4 for YUVAxxx, Planar RGBA or RGB32/64\n  - new script function:\n    bool HasAlpha(clip)\n    returns true when clip is YUVA, Planar RGBA, or packed RGB32 or RGB64\n\n20161222 r2347dev\n  - CombinePlanes addition: setting target to default RGBP(A)/YUV(A), when inputs are greyscale and no source planes are given\n    Decision is made by the target plane characters, if they are like R,G,B then target video format will be planar RGB\n    Same logic applies for YUV.\n    Example:\n    Y1, Y2 and Y3 are greyscale clips\n    Old, still valid: combineplanes(Y1, Y2, Y3, planes=\"RGB\", source_planes=\"YYY\", pixel_type=\"RGBP8\")\n    New:              combineplanes(Y1, Y2, Y3, planes=\"RGB\") # result: Planar RGB\n  - Fix: ScriptClip would show garbage text when internal exception occurs instead of the error message\n\n20161211 r2343dev\n  - Overlay: use y offset when greymask=true (fix)\n  - Fix DV chroma positioning (UV swapped), interlaced parameter check for 4:2:0\n    (fix by IanB in classic Avisynth)\n  - BitBlt in 32 bit Avisynth:\n    for processors with AVX or better ignore tricky isse memcpy replacement, trust in memcpy (test)\n    (x64 is O.K., it always used memcpy)\n  - Merge: use stream_load for AVX2\n  - VDubFilter.dll:\n    convert 'd' double and 'l' long typed parameters to 'f' float and 'i' int for poor AviSynth\n    thus allowing the usage of such virtualdub filters\n  - remove script array (new AVSValue schema) feature, cannot make it compatible with Invoke from v2.5 plugins\n    until I figure out a workaround or such plugins would slowly distinct.\n\n20161208 r2337dev\n  - [feature temporarily removed, script arrays are incompatible until 2.5 plugins are supported]\n    C interface array compatibility vol#2 (zero size arrays)\n    (new AVSValue schema problem)\n  - Merge, MergeChroma, MergeLuma: AVX2 (planar)\n  - Possibly a bit faster text overlay\n\n20161207 r2333dev\n  - Overlay fix\n\n20161206 r2331dev\n  - YUY2 PlaneToY finally works\n  - C interface compatible array-type AVSValue handling (new AVSValue schema problem)\n\n20161205 r2327dev\n  - [feature temporarily removed, script arrays are incompatible until 2.5 plugins are supported]\n    BlankClip parameter \"colors\" accepts exact color values to use\n    Color order: Y,U,V,A or R,G,B(,A)\n    These color values are used as-is, not scaled or converted in any way.\n    Reason: old colors parameter is int (32 bit) cannot hold three or four 16 bit or float values\n    Example: BlankClip(width=1920,height=1080,length=1000,pixel_type=\"RGB64\", colors=[64000,32768,1231,65535])\n  - ExtractY, PlaneToY(\"Y\") accepts YUY2 clip\n  - ExtractR, ExtractG, ExtractB, ExtractA,\n    and\n    PlaneToY(\"R\"), PlaneToY(\"G\"), PlaneToY(\"B\"), PlaneToY(\"A\")\n    functions are accepting packed RGB input (RGB24/32/48/64)\n    They are converted to planar RGB on-the-fly before plane extraction\n  - Histogram \"levels\" works from Planar RGB.\n    Color legends show R, G and B.\n    bits=8..12 parameter is still available for finer ultra-wide histogram display\n\n20161201 r2322dev\n  - [feature temporarily removed, script arrays are incompatible until 2.5 plugins are supported]\n    constant script arrays\n    (note: feature was temporarily removed in r2443)\n    array_variable = [[1,2,3],[4,5,8],\"hello\"]\n    dictionary = [[\"one\",1],[\"two\",2]]\n    empty = []\n    subarray = array_variable[0]\n    val = subarray[2]\n    val2 = array_variable[1,3]\n    str = array_variable[2]\n    n = ArraySize(array_variable) #3\n    n2 = ArraySize(empty) #0\n    val3 = dictionary[\"two\"]\n  - arrays as filter parameters (named and unnamed):\n    new 'a' type or use '.' (any) and check AVSValue IsArray()\n    todo: maybe .+ or *+ syntax?\n    (note: feature was temporarily removed in r2443)\n  - Planar RGB <-> YUV: SSE2 (SSE4)\n  - Planar RGB <-> Packed RGB32/64: SSE2\n\n20161120:\n  make PlanarRGB TurnLeft, TurnRight work again.\n  (stricter check in PlaneToY)\n\n20161119\n  Fix: PlaneToY(\"Y\")\n\n20161116\n\n  Replaced AToY8, GToY8, BToY8, RToY8\n  We have ExtractX, (X = R,G,B,Y,U,V,A) instead.\n  That Y8 ending was too confusing.\n  See new test build\n\n20161110 Avisynth plus additions\nNew functions\n\n  AToY8 , same as PlaneToY(\"A\") for planar RGBA or YUVA\n  RToY8 , same as PlaneToY(\"R\") for planar RGB\n  GToY8 , same as PlaneToY(\"G\") for planar RGB\n  BToY8 , same as PlaneToY(\"B\") for planar RGB\n\n  They work the same way as UToY8 and VToY8 and ConvertToY did.\n  They convert to greyscale keeping the original bit-depth, not only 8 bit!\n  Y8 naming was kept, because UToY and VToY already existed.\n\nExtended function\n  old: YToUV(clip clipU, clip clipV [, clip clipY ] )\n  new: YToUV(clip clipU, clip clipV [, clip clipY [, clip clipA] ] )\n\n  YToUV accepts optional alpha clip after Y clip\n\n  Example\n    U = source.UToY8()\n    V = source.VToY8()\n    Y = source.ConvertToY()\n    A = source.AddAlphaPlane(128).AToY8()\n    # swaps V, U and A, Y\n    YToUV(V,U,A,Y).Histogram(\"levels\").Info().RemoveAlphaPlane()\n\nNew function\n  CombinePlanes(clip1 [,clip2, clip3, clip4], string planes [, string source_planes, string pixel_type, string sample_clip])\n\n  Combines planes of source clip(s) into a target clip\n\n  If sample_clip is given, target clip properties are copied from that clip\n  If no sample_clip is provided, then clip1 provides the template for target clip\n  An optional pixel_type string (e.g.\"YV24\", \"YUV420PS\", \"RGBP8\") can override the base video format.\n\n  If the source clip count is less than the given planes defined, then the last available clip is\n  used as a source.\n\n  string planes\n    the target plane order (e.g. \"YVU\", \"YYY\", \"RGB\")\n    missing target planes will be undefined in the target\n\n  string source_planes (optional)\n    the source plane order, defaulting to \"YUVA\" or \"RGBA\" depending on the video format\n\n  Examples#1\n    #combine greyscale clips into YUVA clip\n    U8 = source.UToY8()\n    V8 = source.VToY8()\n    Y8 = source.ConvertToY()\n    A8 = source.AddAlphaPlane(128).AToY8()\n    CombinePlanes(Y8, U8, V8, A8, planes=\"YUVA\", source_planes=\"YYYY\", sample_clip=source) #pixel_type=\"YUV444P8\"\n\n  Examples#2\n    # Copy planes between planar RGB(A) and YUV(A) without any conversion\n    # yuv 4:4:4 <-> planar rgb\n    source = last.ConvertBits(32) # 4:4:4\n    cast_to_planarrgb = CombinePlanes(source, planes=\"RGB\", source_planes=\"YUV\", pixel_type=\"RGBPS\")\n    # get back a clip identical with \"source\"\n    cast_to_yuv = CombinePlanes(cast_to_planarrgb, planes=\"YUV\", source_planes=\"RGB\", pixel_type=\"YUV444PS\")\n\n  Examples#3\n    #create a black and white planar RGB clip using Y channel\n    #source is a YUV clip\n    grey = CombinePlanes(source, planes=\"RGB\", source_planes=\"YYY\", pixel_type=\"RGBP8\")\n\n  Examples#4\n    #copy luma from one clip, U and V from another\n    #source is the template\n    #sourceY is a Y or YUV clip\n    #sourceUV is a YUV clip\n    grey = CombinePlanes(sourceY, sourceUV, planes=\"YUV\", source_planes=\"YUV\", sample_clip = source)\n\n  Remark:\n    When there is only one input clip, zero-cost BitBlt-less subframes are used, which is much faster.\n\n    e.g.: casting YUV to RGB, shuffle RGBA to ABGR, U to Y, etc..\n    Target planes that are not specified, preserve their content.\n\n    Examples:\n    combineplanes(clipRGBP, planes=\"RGB\",source_planes=\"BGR\") # swap R and B\n    combineplanes(clipYUV, planes=\"GBRA\",source_planes=\"YUVA\",pixel_type=\"RGBAP8\") # cast YUVA to planar RGBA\n    combineplanes(clipYUV, planes=\"Y\",source_planes=\"U\",pixel_type=\"Y8\") # extract U\n\n\nEarlier (pre v2294) modifications and informations on behaviour of existing filter\n----------------------------------------------------------------------------------\n[ColorSpaceNameToPixelType]\nNew script function: ColorSpaceNameToPixelType()\nParameter: video colorspace string\nReturns: Integer\n\nReturns a VideoInfo::pixel_type integer from a valid colorspace string\n\nIn Avisynth+ we have way too many pixel_type's now, this function can be useful for plugins for parsing a target colorspace string parameter.\n\nEarlier I made this function available from within avisynth core, as I made one function from the previous 3-4 different places where colorspace name parameters were parsed in a copy-paste code.\n\nIn Avisynth the existing PixelType script function returns the pixeltype name of the current clip.\nThis function reverses this.\n\nIt has the advantage that it returns the same (for example) YV24 constant from \"YV24\" or \"YUV444\" or \"Yuv444p8\", so it recognizes some possible naming variants.\n\ncsp_name = \"YUV422P8\"\ncsp_name2 = \"YV16\"\nSubTitle(\"PixelType value of \" + csp_name + \" = \" + String(ColorSpaceNameToPixelType(csp_name))\\\n+ \" and \" + csp_name2 + \" = \" + String(ColorSpaceNameToPixelType(csp_name2)) )\n\n[New conditional functions]\n\nConditional runtime functions have 10-16 bit/float support for YUV, PlanarRGB and 16 bit packed RGB formats.\n\nSince RGB is also available as a planar colorspace, the plane statistics functions logically were expanded.\n\nNew functions\n• AverageR, AverageG AverageB like AverageLuma\n• RDifference, GDifference, BDifference like LumaDifference(clip1, clip2)\n• RDifferenceFromPrevious, GDifferenceFromPrevious, BDifferenceFromPrevious\n• RDifferenceToNext, GDifferenceToNext, BDifferenceToNext\n• RPlaneMin, GPlaneMin BPlaneMin like YPlaneMin(clip [, float threshold = 0, int offset = 0])\n• RPlaneMax, GPlaneMax BPlaneMax like YPlaneMax(clip [, float threshold = 0, int offset = 0])\n• RPlaneMinMaxDifference, GPlaneMinMaxDifference BPlaneMinMaxDifference like YPlaneMinMaxDifference(clip [, float threshold = 0, int offset = 0])\n• RPlaneMedian, GPlaneMedian, BPlaneMedian like YPlaneMedian(clip [, int offset = 0])\n\nFor float colorspaces the Min, Max, MinMaxDifference and Median functions populate pixel counts for the internal statistics at a 16 bit resolution internally.\n\n[Tweak]\nSee original doc: http://avisynth.nl/index.php/Tweak\nThe original 8 bit tweak worked with internal LUT both for luma and chroma conversion.\nChroma LUT requires 2D LUT table, thus only implemented for 10 bit clips for memory reasons.\nLuma LUT is working at 16 bits (1D table)\n\nAbove these limits the calculations are realtime, and done pixel by pixel.\nYou can use a new parameter to force ignoring LUT usage (calculate each pixel on-the-fly)\nFor this purpose use realcalc=true.\n\n[MaskHS]\nWorks for 10-16bit,float.\n\nMaskHS uses LUT for 10/12 bits. Above this (no memory for fast LUTs) the calculation is done realtime for each.\nTo override LUT for 10-12 bits use new parameter realcalc=true\n\n[ColorKeyMask]:\nWorks for RGB64, Planar RGBA 8-16,float.\nColorKeyMask color and tolerance parameters are the same as for 8 bit RGB32.\nInternally they are automatically scaled to the current bit-depth\n\n[ResetMask]\nNew extension.\nAccepts parameter (Mask=xxx) which is used for setting the alpha plane for a given value.\nDefault value for Mask is 255 for RGB32, 65535 for RGB64 and full 16 bit, 1.0 for float.\nFor 10-12-14 bit it is set to 1023, 4095 and 16383 respectively.\n\nParameter type is float, it can be applied to the alpha plane of a float-type YUVA or Planar RGBA clip.\n\n[Layer]\nLayer() now works for RGB64.\nOriginal documentation: http://avisynth.nl/index.php/Layer\n\nBy avisynth documentation: for full strength Level=257 (default) should be given.\nFor RGB64 this magic number is Level=65537 (this is the default when RGB64 is used)\n\nSample:\nlsmashvideosource(\"test.mp4\", format=\"YUV420P8\")\nx=last\nx = x.Spline16Resize(800,250).ColorYUV(levels=\"TV->PC\")\nx = x.ConvertToRGB32()\n\ntransparency0_255 = 128 # ResetMask's new parameter. Also helps testing :)\nx2 = ColorBars().ConvertToRGB32().ResetMask(transparency0_255)\n\nx_64 = x.ConvertToRGB32().ConvertBits(16)\nx2_64 = ColorBars().ConvertToRGB32().ConvertBits(16).ResetMask(transparency0_255 / 255.0 * 65535.0 )\n\n#For pixel-wise transparency information the alpha channel of an RGB32 overlay_clip is used as a mask.\n\nop = \"darken\" # subtract lighten darken mul fast\nlevel=257         # 0..257\nlevel64=65537     # 0..65537\nthreshold=128                   # 0..255   Changes the transition point of op = \"darken\", \"lighten.\"\nthreshold64=threshold*65535/255 # 0..65535 Changes the transition point of op = \"darken\", \"lighten.\"\nuse_chroma = true\nrgb32=Layer(x,x2,op=op,level=level,x=0,y=0,threshold=threshold,use_chroma=use_chroma )\nrgb64=Layer(x_64,x2_64,op=op,level=level64,x=0,y=0,threshold=threshold64,use_chroma=use_chroma ).ConvertBits(8)\nStackVertical(rgb32, rgb64)\n\n[Levels]\nLevels: 10-16 bit support for YUV(A), PlanarRGB(A), 16 bits for RGB48/64\nNo float support yet\n\nLevel values are not scaled, they are accepted as-is for 8+ bit depths\n\nTest scripts for Levels\n# Gamma, ranges (YUV):\nx=ConvertToYUV420()\ndither=true\ncoring=true\ngamma=2.2\noutput_low = 55\noutput_high = 198\nclip8 = x.Levels(0, gamma, 255, output_low, output_high , dither=dither, coring=coring)\nclip10 = x.ConvertBits(10).Levels(0,gamma,1023,output_low *4,(output_high +1)*4 - 1, dither=dither, coring=coring)\nclip16 = x.ConvertBits(16).Levels(0,gamma,65535,output_low *256,(output_high+1) *256 -1,dither=dither, coring=coring)\nstackvertical(clip8.Histogram(\"levels\"), clip10.ConvertBits(8).Histogram(\"levels\"), Clip16.ConvertBits(8).Histogram(\"levels\"))\n\n# packed RGB 32/64\nxx = ConvertToRGB32()\ndither=false\ncoring=false\ngamma=1.4\nclip8 = xx.Levels(0, gamma, 255, 0, 255, dither=dither, coring=coring)\nclip16 = xx.ConvertBits(16).Levels(0,gamma,65535,0,65535,dither=dither, coring=coring)\nstackvertical(clip8.ConvertToYUV444().Histogram(\"levels\"), Clip16.ConvertBits(8).ConvertToYUV444().Histogram(\"levels\"))\n\n[ColorYUV]\nNow it works for 10-16 bit clips\n\n• Slightly modified \"demo\" mode when using ColorYUV(showyuv=true)\n\n#old: draws YV12 with 16-239 U/V image (448x448)\n#new: draws YV12 with 16-240 U/V image (450x450)\n\n• New options for \"demo\" mode when using ColorYUV(showyuv=true)\nNew parameter: bool showyuv_fullrange.\nDescription: Draws YV12 with 0-255 U/V image (512x512)\nUsage: ColorYUV(showyuv=true, showyuv_fullrange=true)\n\nNew parameter: bits=10,12,14,16\nResult clip is the given bit depth for YUV420Pxx format.\nAs image size is limited (for 10 bits the range 64-963 requires big image size), color resolution is 10 bits maximum.\n#This sample draws YUV420P10 with 64-963 U/V image\nColorYUV(showyuv=true, bits=10).Info()\n\nLuma steps are 16-235-16../0-255-0.. up to 0-65535-0... when bits=16\n\n• Additional infos for ColorYUV\n\n- Fixed an uninitialized internal variable regarding pc<->tv conversion,\n  resulting in clips sometimes were expanding to pc range when it wasn't asked.\n- No parameter scaling needed for high bit depth clips.\n  For 8+ bit clips parameter ranges are the same as for the 8 bit clips.\n  They will be scaled properly for 10-16 bitdepths.\n  e.g. off_u=-20 will be converted to -204 for 10 bits, -20256 for 16 bits\n- ColorYUV uses 8-10-12-14-16 bit lut.\n- ColorYUV is not available for 32 bit (float) clips at the moment\n\n[Other things you may have not known]\nSource filters are automatically detected, specifying MT_SERIALIZED is not necessary for them.\n\n[Known issues/things]\nGRunT in MT modes (Avs+ specific)\n[done: v2502] Overlay blend with fully transparent mask is incorrect, overlaying pixel=0 becomes 1, overlaying pixel=255 becomes 254.\n[done: v2676-] Float-type clips: chroma should be zero based: +/-0.5 instead of 0..1\n"
  },
  {
    "path": "distrib/WinInstaller/Translations/cs.isl",
    "content": "; *******************************************************\n; ***                                                 ***\n; *** Inno Setup version 5.5.3+ Czech messages        ***\n; ***                                                 ***\n; *** Original Author:                                ***\n; ***                                                 ***\n; ***   Ivo Bauer (bauer@ozm.cz)                      ***\n; ***                                                 ***\n; *** Contributors:                                   ***\n; ***                                                 ***\n; ***   Lubos Stanek (lubek@users.sourceforge.net)    ***\n; ***   Vitezslav Svejdar (vitezslav.svejdar@cuni.cz) ***\n; ***                                                 ***\n; *******************************************************\n;\n; Copyright (C) 1997-2012 Jordan Russell. All rights reserved.\n; Translations (C) 2002-2012 Original Author and Contributors. All rights reserved.\n;\n; The contents of this file are subject to the Inno Setup License (the \"License\").\n; You may obtain a copy of the License at http://www.jrsoftware.org/files/is/license.txt\n;\n; $jrsoftware: issrc/Files/Languages/Czech.isl,v 1.18 2007/02/27 18:22:41 jr Exp $\n\n[LangOptions]\nLanguageName=<010C>e<0161>tina\nLanguageID=$0405\nLanguageCodePage=1250\n\n[Messages]\n\n; *** Application titles\nSetupAppTitle=Prvodce instalac\nSetupWindowTitle=Prvodce instalac - %1\nUninstallAppTitle=Prvodce odinstalac\nUninstallAppFullTitle=Prvodce odinstalac - %1\n\n; *** Misc. common\nInformationTitle=Informace\nConfirmTitle=Potvrzen\nErrorTitle=Chyba\n\n; *** SetupLdr messages\nSetupLdrStartupMessage=Vt Vs prvodce instalac produktu %1. Chcete pokraovat?\nLdrCannotCreateTemp=Nelze vytvoit doasn soubor. Prvodce instalac bude ukonen\nLdrCannotExecTemp=Nelze spustit soubor v doasn sloce. Prvodce instalac bude ukonen\n\n; *** Startup error messages\nLastErrorMessage=%1.%n%nChyba %2: %3\nSetupFileMissing=Instalan sloka neobsahuje soubor %1. Opravte prosm tuto chybu nebo si opatete novou kopii tohoto produktu.\nSetupFileCorrupt=Soubory prvodce instalac jsou pokozeny. Opatete si prosm novou kopii tohoto produktu.\nSetupFileCorruptOrWrongVer=Soubory prvodce instalac jsou pokozeny nebo se nesluuj s touto verz prvodce instalac. Opravte prosm tuto chybu nebo si opatete novou kopii tohoto produktu.\nInvalidParameter=Pkazov dka obsahuje neplatn parametr:%n%n%1\nSetupAlreadyRunning=Prvodce instalac je ji sputn.\nWindowsVersionNotSupported=Tento produkt nepodporuje verzi MS Windows, kter b na Vaem potai.\nWindowsServicePackRequired=Tento produkt vyaduje %1 Service Pack %2 nebo vy.\nNotOnThisPlatform=Tento produkt nelze spustit ve %1.\nOnlyOnThisPlatform=Tento produkt mus bt sputn ve %1.\nOnlyOnTheseArchitectures=Tento produkt lze nainstalovat pouze ve verzch MS Windows s podporou architektury procesor:%n%n%1\nMissingWOW64APIs=Aktuln verze MS Windows postrd funkce, kter vyaduje prvodce instalac pro 64-bitovou instalaci. Opravte prosm tuto chybu nainstalovnm aktualizace Service Pack %1.\nWinVersionTooLowError=Tento produkt vyaduje %1 verzi %2 nebo vy.\nWinVersionTooHighError=Tento produkt nelze nainstalovat ve %1 verzi %2 nebo vy.\nAdminPrivilegesRequired=K instalaci tohoto produktu muste bt pihleni s prvy administrtora.\nPowerUserPrivilegesRequired=K instalaci tohoto produktu muste bt pihleni s prvy administrtora nebo lena skupiny Power Users.\nSetupAppRunningError=Prvodce instalac zjistil, e produkt %1 je nyn sputn.%n%nZavete prosm vechny instance tohoto produktu a pak pokraujte klepnutm na tlatko OK, nebo ukonete instalaci tlatkem Storno.\nUninstallAppRunningError=Prvodce odinstalac zjistil, e produkt %1 je nyn sputn.%n%nZavete prosm vechny instance tohoto produktu a pak pokraujte klepnutm na tlatko OK, nebo ukonete odinstalaci tlatkem Storno.\n\n; *** Misc. errors\nErrorCreatingDir=Prvodci instalac se nepodailo vytvoit sloku \"%1\"\nErrorTooManyFilesInDir=Nelze vytvoit soubor ve sloce \"%1\", protoe tato sloka ji obsahuje pli mnoho soubor\n\n; *** Setup common messages\nExitSetupTitle=Ukonit prvodce instalac\nExitSetupMessage=Instalace nebyla zcela dokonena. Jestlie nyn prvodce instalac ukonte, produkt nebude nainstalovn.%n%nPrvodce instalac mete znovu spustit kdykoliv jindy a instalaci dokonit.%n%nChcete prvodce instalac ukonit?\nAboutSetupMenuItem=&O prvodci instalac...\nAboutSetupTitle=O prvodci instalac\nAboutSetupMessage=%1 verze %2%n%3%n%n%1 domovsk strnka:%n%4\nAboutSetupNote=\nTranslatorNote=Czech translation maintained by Ivo Bauer (bauer@ozm.cz), Lubos Stanek (lubek@users.sourceforge.net) and Vitezslav Svejdar (vitezslav.svejdar@cuni.cz)\n\n; *** Buttons\nButtonBack=< &Zpt\nButtonNext=&Dal >\nButtonInstall=&Instalovat\nButtonOK=OK\nButtonCancel=Storno\nButtonYes=&Ano\nButtonYesToAll=Ano &vem\nButtonNo=&Ne\nButtonNoToAll=N&e vem\nButtonFinish=&Dokonit\nButtonBrowse=&Prochzet...\nButtonWizardBrowse=&Prochzet...\nButtonNewFolder=&Vytvoit novou sloku\n\n; *** \"Select Language\" dialog messages\nSelectLanguageTitle=Vbr jazyka prvodce instalac\nSelectLanguageLabel=Zvolte jazyk, kter se m pout bhem instalace:\n\n; *** Common wizard text\nClickNext=Pokraujte klepnutm na tlatko Dal, nebo ukonete prvodce instalac tlatkem Storno.\nBeveledLabel=\nBrowseDialogTitle=Vyhledat sloku\nBrowseDialogLabel=Z ne uvedenho seznamu vyberte sloku a klepnte na tlatko OK.\nNewFolderName=Nov sloka\n\n; *** \"Welcome\" wizard page\nWelcomeLabel1=Vt Vs prvodce instalac produktu [name].\nWelcomeLabel2=Produkt [name/ver] bude nainstalovn na V pota.%n%nDve ne budete pokraovat, doporuuje se zavt veker sputn aplikace.\n\n; *** \"Password\" wizard page\nWizardPassword=Heslo\nPasswordLabel1=Tato instalace je chrnna heslem.\nPasswordLabel3=Zadejte prosm heslo a pokraujte klepnutm na tlatko Dal. Pi zadvn hesla rozliujte mal a velk psmena.\nPasswordEditLabel=&Heslo:\nIncorrectPassword=Zadan heslo nen sprvn. Zkuste to prosm znovu.\n\n; *** \"License Agreement\" wizard page\nWizardLicense=Licenn smlouva\nLicenseLabel=Dve ne budete pokraovat, pette si prosm pozorn nsledujc dleit informace.\nLicenseLabel3=Pette si prosm tuto licenn smlouvu. Muste souhlasit s podmnkami tto smlouvy, aby instalace mohla pokraovat.\nLicenseAccepted=&Souhlasm s podmnkami licenn smlouvy\nLicenseNotAccepted=&Nesouhlasm s podmnkami licenn smlouvy\n\n; *** \"Information\" wizard pages\nWizardInfoBefore=Informace\nInfoBeforeLabel=Dve ne budete pokraovat, pette si prosm pozorn nsledujc dleit informace.\nInfoBeforeClickLabel=Pokraujte v instalaci klepnutm na tlatko Dal.\nWizardInfoAfter=Informace\nInfoAfterLabel=Dve ne budete pokraovat, pette si prosm pozorn nsledujc dleit informace.\nInfoAfterClickLabel=Pokraujte v instalaci klepnutm na tlatko Dal.\n\n; *** \"User Information\" wizard page\nWizardUserInfo=Informace o uivateli\nUserInfoDesc=Zadejte prosm poadovan daje.\nUserInfoName=&Uivatelsk jmno:\nUserInfoOrg=&Spolenost:\nUserInfoSerial=S&riov slo:\nUserInfoNameRequired=Muste zadat uivatelsk jmno.\n\n; *** \"Select Destination Location\" wizard page\nWizardSelectDir=Zvolte clov umstn\nSelectDirDesc=Kam m bt produkt [name] nainstalovn?\nSelectDirLabel3=Prvodce nainstaluje produkt [name] do nsledujc sloky.\nSelectDirBrowseLabel=Pokraujte klepnutm na tlatko Dal. Chcete-li zvolit jinou sloku, klepnte na tlatko Prochzet.\nDiskSpaceMBLabel=Instalace vyaduje nejmn [mb] MB volnho msta na disku.\nCannotInstallToNetworkDrive=Prvodce instalac neme instalovat do sov jednotky.\nCannotInstallToUNCPath=Prvodce instalac neme instalovat do cesty UNC.\nInvalidPath=Muste zadat plnou cestu vetn psmene jednotky; napklad:%n%nC:\\Aplikace%n%nnebo cestu UNC ve tvaru:%n%n\\\\server\\sdlen sloka\nInvalidDrive=Vmi zvolen jednotka nebo cesta UNC neexistuje nebo nen dostupn. Zvolte prosm jin umstn.\nDiskSpaceWarningTitle=Nedostatek msta na disku\nDiskSpaceWarning=Prvodce instalac vyaduje nejmn %1 KB volnho msta pro instalaci produktu, ale na zvolen jednotce je dostupnch pouze %2 KB.%n%nChcete pesto pokraovat?\nDirNameTooLong=Nzev sloky nebo cesta jsou pli dlouh.\nInvalidDirName=Nzev sloky nen platn.\nBadDirName32=Nzev sloky neme obsahovat dn z nsledujcch znak:%n%n%1\nDirExistsTitle=Sloka existuje\nDirExists=Sloka:%n%n%1%n%nji existuje. M se pesto instalovat do tto sloky?\nDirDoesntExistTitle=Sloka neexistuje\nDirDoesntExist=Sloka:%n%n%1%n%nneexistuje. M bt tato sloka vytvoena?\n\n; *** \"Select Components\" wizard page\nWizardSelectComponents=Zvolte sousti\nSelectComponentsDesc=Jak sousti maj bt nainstalovny?\nSelectComponentsLabel2=Zakrtnte sousti, kter maj bt nainstalovny; sousti, kter se nemaj instalovat, ponechte nezakrtnut. Pokraujte klepnutm na tlatko Dal.\nFullInstallation=pln instalace\n; if possible don't translate 'Compact' as 'Minimal' (I mean 'Minimal' in your language)\nCompactInstallation=Kompaktn instalace\nCustomInstallation=Voliteln instalace\nNoUninstallWarningTitle=Sousti existuj\nNoUninstallWarning=Prvodce instalac zjistil, e nsledujc sousti jsou ji na Vaem potai nainstalovny:%n%n%1%n%nNezahrnete-li tyto sousti do vbru, nebudou nyn odinstalovny.%n%nChcete pesto pokraovat?\nComponentSize1=%1 KB\nComponentSize2=%1 MB\nComponentsDiskSpaceMBLabel=Vybran sousti vyaduj nejmn [mb] MB msta na disku.\n\n; *** \"Select Additional Tasks\" wizard page\nWizardSelectTasks=Zvolte dal lohy\nSelectTasksDesc=Kter dal lohy maj bt provedeny?\nSelectTasksLabel2=Zvolte dal lohy, kter maj bt provedeny v prbhu instalace produktu [name], a pak pokraujte klepnutm na tlatko Dal.\n\n; *** \"Select Start Menu Folder\" wizard page\nWizardSelectProgramGroup=Vyberte sloku v nabdce Start\nSelectStartMenuFolderDesc=Kam m prvodce instalac umstit zstupce aplikace?\nSelectStartMenuFolderLabel3=Prvodce instalac vytvo zstupce aplikace v nsledujc sloce nabdky Start.\nSelectStartMenuFolderBrowseLabel=Pokraujte klepnutm na tlatko Dal. Chcete-li zvolit jinou sloku, klepnte na tlatko Prochzet.\nMustEnterGroupName=Muste zadat nzev sloky.\nGroupNameTooLong=Nzev sloky nebo cesta jsou pli dlouh.\nInvalidGroupName=Nzev sloky nen platn.\nBadGroupName=Nzev sloky neme obsahovat dn z nsledujcch znak:%n%n%1\nNoProgramGroupCheck2=&Nevytvet sloku v nabdce Start\n\n; *** \"Ready to Install\" wizard page\nWizardReady=Instalace je pipravena\nReadyLabel1=Prvodce instalac je nyn pipraven nainstalovat produkt [name] na V pota.\nReadyLabel2a=Pokraujte v instalaci klepnutm na tlatko Instalovat. Pejete-li si zmnit nkter nastaven instalace, klepnte na tlatko Zpt.\nReadyLabel2b=Pokraujte v instalaci klepnutm na tlatko Instalovat.\nReadyMemoUserInfo=Informace o uivateli:\nReadyMemoDir=Clov umstn:\nReadyMemoType=Typ instalace:\nReadyMemoComponents=Vybran sousti:\nReadyMemoGroup=Sloka v nabdce Start:\nReadyMemoTasks=Dal lohy:\n\n; *** \"Preparing to Install\" wizard page\nWizardPreparing=Pprava k instalaci\nPreparingDesc=Prvodce instalac pipravuje instalaci produktu [name] na V pota.\nPreviousInstallNotCompleted=Instalace/odinstalace pedchozho produktu nebyla zcela dokonena. Aby mohla bt dokonena, muste restartovat V pota.%n%nPo restartovn Vaeho potae spuste znovu prvodce instalac, aby bylo mon dokonit instalaci produktu [name].\nCannotContinue=Prvodce instalac neme pokraovat. Ukonete prosm prvodce instalac klepnutm na tlatko Storno.\nApplicationsFound=Nsledujc aplikace pistupuj k souborm, kter je teba bhem instalace aktualizovat. Doporuuje se povolit prvodci instalac, aby tyto aplikace automaticky zavel.\nApplicationsFound2=Nsledujc aplikace pistupuj k souborm, kter je teba bhem instalace aktualizovat. Doporuuje se povolit prvodci instalac, aby tyto aplikace automaticky zavel. Po dokonen instalace se prvodce instalac pokus aplikace restartovat.\nCloseApplications=&Zavt aplikace automaticky\nDontCloseApplications=&Nezavrat aplikace\nErrorCloseApplications=Prvodci instalac se nepodailo automaticky zavt vechny aplikace. Dve ne budete pokraovat, doporuuje se zavt veker aplikace pistupujc k souborm, kter je teba bhem instalace aktualizovat.\n\n; *** \"Installing\" wizard page\nWizardInstalling=Instalovn\nInstallingLabel=ekejte prosm, dokud prvodce instalac nedokon instalaci produktu [name] na V pota.\n\n; *** \"Setup Completed\" wizard page\nFinishedHeadingLabel=Dokonuje se instalace produktu [name]\nFinishedLabelNoIcons=Prvodce instalac dokonil instalaci produktu [name] na V pota.\nFinishedLabel=Prvodce instalac dokonil instalaci produktu [name] na V pota. Produkt lze spustit pomoc nainstalovanch zstupc.\nClickFinish=Ukonete prvodce instalac klepnutm na tlatko Dokonit.\nFinishedRestartLabel=K dokonen instalace produktu [name] je nezbytn, aby prvodce instalac restartoval V pota. Chcete jej nyn restartovat?\nFinishedRestartMessage=K dokonen instalace produktu [name] je nezbytn, aby prvodce instalac restartoval V pota.%n%nChcete jej nyn restartovat?\nShowReadmeCheck=Ano, chci zobrazit dokument \"TIMNE\"\nYesRadio=&Ano, chci nyn restartovat pota\nNoRadio=&Ne, pota restartuji pozdji\n; used for example as 'Run MyProg.exe'\nRunEntryExec=Spustit %1\n; used for example as 'View Readme.txt'\nRunEntryShellExec=Zobrazit %1\n\n; *** \"Setup Needs the Next Disk\" stuff\nChangeDiskTitle=Prvodce instalac vyaduje dal disk\nSelectDiskLabel2=Vlote prosm disk %1 a klepnte na tlatko OK.%n%nPokud se soubory na tomto disku nachzej v jin sloce ne v t, kter je zobrazena ne, pak zadejte sprvnou cestu nebo ji zvolte klepnutm na tlatko Prochzet.\nPathLabel=&Cesta:\nFileNotInDir2=Soubor \"%1\" nelze najt v \"%2\". Vlote prosm sprvn disk nebo zvolte jinou sloku.\nSelectDirectoryLabel=Specifikujte prosm umstn dalho disku.\n\n; *** Installation phase messages\nSetupAborted=Instalace nebyla zcela dokonena.%n%nOpravte prosm chybu a spuste prvodce instalac znovu.\nEntryAbortRetryIgnore=Akci zopakujete klepnutm na tlatko Opakovat. Tento krok vynechte klepnutm na tlatko Peskoit. Instalaci stornujete klepnutm na tlatko Peruit.\n\n; *** Installation status messages\nStatusClosingApplications=Zavraj se aplikace...\nStatusCreateDirs=Vytvej se sloky...\nStatusExtractFiles=Extrahuj se soubory...\nStatusCreateIcons=Vytvej se zstupci...\nStatusCreateIniEntries=Vytvej se zznamy v inicializanch souborech...\nStatusCreateRegistryEntries=Vytvej se zznamy v systmovm registru...\nStatusRegisterFiles=Registruj se soubory...\nStatusSavingUninstall=Ukldaj se informace pro odinstalaci produktu...\nStatusRunProgram=Dokonuje se instalace...\nStatusRestartingApplications=Restartuj se aplikace...\nStatusRollback=Proveden zmny se vracej zpt...\n\n; *** Misc. errors\nErrorInternal2=Intern chyba: %1\nErrorFunctionFailedNoCode=%1 selhala\nErrorFunctionFailed=%1 selhala; kd %2\nErrorFunctionFailedWithMessage=%1 selhala; kd %2.%n%3\nErrorExecutingProgram=Nelze spustit soubor:%n%1\n\n; *** Registry errors\nErrorRegOpenKey=Dolo k chyb pi otevrn kle systmovho registru:%n%1\\%2\nErrorRegCreateKey=Dolo k chyb pi vytven kle systmovho registru:%n%1\\%2\nErrorRegWriteKey=Dolo k chyb pi zpisu do kle systmovho registru:%n%1\\%2\n\n; *** INI errors\nErrorIniEntry=Dolo k chyb pi vytven zznamu v inicializanm souboru \"%1\".\n\n; *** File copying errors\nFileAbortRetryIgnore=Akci zopakujete klepnutm na tlatko Opakovat. Tento soubor peskote klepnutm na tlatko Peskoit (nedoporuuje se). Instalaci stornujete klepnutm na tlatko Peruit.\nFileAbortRetryIgnore2=Akci zopakujete klepnutm na tlatko Opakovat. Pokraujete klepnutm na tlatko Peskoit (nedoporuuje se). Instalaci stornujete klepnutm na tlatko Peruit.\nSourceIsCorrupted=Zdrojov soubor je pokozen\nSourceDoesntExist=Zdrojov soubor \"%1\" neexistuje\nExistingFileReadOnly=Existujc soubor je uren pouze pro ten.%n%nAtribut \"pouze pro ten\" odstrante a akci zopakujete klepnutm na tlatko Opakovat. Tento soubor peskote klepnutm na tlatko Peskoit. Instalaci stornujete klepnutm na tlatko Peruit.\nErrorReadingExistingDest=Dolo k chyb pi pokusu o ten existujcho souboru:\nFileExists=Soubor ji existuje.%n%nM bt prvodcem instalace pepsn?\nExistingFileNewer=Existujc soubor je novj ne ten, kter se prvodce instalac pokou nainstalovat. Doporuuje se ponechat existujc soubor.%n%nChcete jej ponechat?\nErrorChangingAttr=Dolo k chyb pi pokusu o zmnu atribut existujcho souboru:\nErrorCreatingTemp=Dolo k chyb pi pokusu o vytvoen souboru v clov sloce:\nErrorReadingSource=Dolo k chyb pi pokusu o ten zdrojovho souboru:\nErrorCopying=Dolo k chyb pi pokusu o zkoprovn souboru:\nErrorReplacingExistingFile=Dolo k chyb pi pokusu o nahrazen existujcho souboru:\nErrorRestartReplace=Funkce \"RestartReplace\" prvodce instalac selhala:\nErrorRenamingTemp=Dolo k chyb pi pokusu o pejmenovn souboru v clov sloce:\nErrorRegisterServer=Nelze zaregistrovat DLL/OCX: %1\nErrorRegSvr32Failed=Voln RegSvr32 selhalo s nvratovm kdem %1\nErrorRegisterTypeLib=Nelze zaregistrovat typovou knihovnu: %1\n\n; *** Post-installation errors\nErrorOpeningReadme=Dolo k chyb pi pokusu o oteven dokumentu \"TIMNE\".\nErrorRestartingComputer=Prvodci instalac se nepodailo restartovat V pota. Restartujte jej prosm run.\n\n; *** Uninstaller messages\nUninstallNotFound=Soubor \"%1\" neexistuje. Produkt nelze odinstalovat.\nUninstallOpenError=Soubor \"%1\" nelze otevt. Produkt nelze odinstalovat.\nUninstallUnsupportedVer=Formt souboru se zznamy k odinstalaci produktu \"%1\" nebyl touto verz prvodce odinstalac rozpoznn. Produkt nelze odinstalovat\nUninstallUnknownEntry=V souboru obsahujcm informace k odinstalaci produktu byla zjitna neznm poloka (%1)\nConfirmUninstall=Jste si opravdu jisti, e chcete produkt %1 a vechny jeho sousti odinstalovat?\nUninstallOnlyOnWin64=Tento produkt lze odinstalovat pouze v 64-bitovch verzch MS Windows.\nOnlyAdminCanUninstall=K odinstalaci tohoto produktu muste bt pihleni s prvy administrtora.\nUninstallStatusLabel=ekejte prosm, dokud produkt %1 nebude odinstalovn z Vaeho potae.\nUninstalledAll=Produkt %1 byl z Vaeho potae spn odinstalovn.\nUninstalledMost=Produkt %1 byl odinstalovn.%n%nNkter jeho sousti se odinstalovat nepodailo. Mete je vak odstranit run.\nUninstalledAndNeedsRestart=K dokonen odinstalace produktu %1 je nezbytn, aby prvodce odinstalac restartoval V pota.%n%nChcete jej nyn restartovat?\nUninstallDataCorrupted=Soubor \"%1\" je pokozen. Produkt nelze odinstalovat\n\n; *** Uninstallation phase messages\nConfirmDeleteSharedFileTitle=Odebrat sdlen soubor?\nConfirmDeleteSharedFile2=Systm indikuje, e nsledujc sdlen soubor nen pouvn dnmi jinmi aplikacemi. M bt tento sdlen soubor prvodcem odinstalac odstrann?%n%nPokud nkter aplikace tento soubor pouvaj, pak po jeho odstrann nemusej pracovat sprvn. Pokud si nejste jisti, zvolte Ne. Ponechn tohoto souboru ve Vaem systmu nezpsob dnou kodu.\nSharedFileNameLabel=Nzev souboru:\nSharedFileLocationLabel=Umstn:\nWizardUninstalling=Stav odinstalace\nStatusUninstalling=Probh odinstalace produktu %1...\n\n; *** Shutdown block reasons\nShutdownBlockReasonInstallingApp=Probh instalace produktu %1.\nShutdownBlockReasonUninstallingApp=Probh odinstalace produktu %1.\n\n; The custom messages below aren't used by Setup itself, but if you make\n; use of them in your scripts, you'll want to translate them.\n\n[CustomMessages]\n\nNameAndVersion=%1 verze %2\nAdditionalIcons=Dal zstupci:\nCreateDesktopIcon=Vytvoit zstupce na &ploe\nCreateQuickLaunchIcon=Vytvoit zstupce na panelu &Snadn sputn\nProgramOnTheWeb=Aplikace %1 na internetu\nUninstallProgram=Odinstalovat aplikaci %1\nLaunchProgram=Spustit aplikaci %1\nAssocFileExtension=Vytvoit &asociaci mezi soubory typu %2 a aplikac %1\nAssocingFileExtension=Vytv se asociace mezi soubory typu %2 a aplikac %1...\nAutoStartProgramGroupDescription=Po sputn:\nAutoStartProgram=Spoutt aplikaci %1 automaticky\nAddonHostProgramNotFound=Aplikace %1 nebyla ve Vmi zvolen sloce nalezena.%n%nChcete pesto pokraovat?\n\n; *** AviSynth+ custom messages\n\nFullInstallation=pln instalace\n;CompactInstallation=Recommended installation\nCustomInstallation=Voliteln instalace\n\nCmpMain=Zklad %1\nCmpDocs=Dokumentace\nCmpDocsEn=Anglick\nCmpDocsCs=Cesk\nCmpDocsFr=Francouzsk\nCmpDocsDe=Nimeck\nCmpDocsIt=Italsk\nCmpDocsJa=Japonsk\nCmpDocsPl=Polsk\nCmpDocsPt=Portugalsk\nCmpDocsRu=Rusk\n;CmpDocsExamples=Scripting Examples\nCmpSdk=Filter SDK\n;CmpMig=Legacy AviSynth migration\n;CmpMigUninstall=Uninstall and move plugins to %1\n;CmpMigBackup=Backup legacy AviSynth\n;CmpCustomizePluginPaths=Customize Plugin Paths\n\n;FileTypeDescAvs=%1 Script\n;FileTypeDescAvsi=%1 Autoload Script\n\n;InstallStatusRuntime = Installing %1 (%2).%nThis may take up to 5 minutes... \n;UninstallStatusLegacyRestore = Restoring legacy AviSynth...\n;BackupRestoreFailed=An error occured while trying to restore your previous AviSynth installation:%n%1\n\n;MigPageCaption=Upgrade Options\n;MigPageDescription=How should %1 handle your existing AviSynth installation?\n;MigPageSubCaption=Setup has detected that AviSynth is already installed in:%n%n%2%n%nAvisynth and %1 cannot be run alongside each other. However, setup can preserve your legacy AviSynth installation in case you want to downgrade later.\n;MigPageOptionBackup=Keep the existing AviSynth program directory and backup its system components overwritten by %1.%n%1 will still load your existing plugins and restore your previous AviSynth installation upon uninstall.\n;MigPageOptionUninstall=Uninstall AviSynth now and migrate compatible plugins to the %1 plugin directory.\n;MigPageUninstallFailed=AviSynth Uninstall failed: %n%1\n \n;PlugPageCaption=%1 Plugin Folders\n;PlugPageDescription=Where should %1 autoload plugins from?\n;PlugPageSubCaption=%1 will install bundled plugins to the its own autoload directory, but also autoload from the legacy plugin directory.\n;PlugPagePlugDirPlus=%2 %1-bit plugin directory:\n;PlugPagePlugDirLegacy=AviSynth %1-bit plugin directory:"
  },
  {
    "path": "distrib/WinInstaller/Translations/de.isl",
    "content": "; ******************************************************\n; ***                                                ***\n; *** Inno Setup version 5.5.3+ German messages      ***\n; ***                                                ***\n; *** Changes 5.5.3+ Author:                         ***\n; ***                                                ***\n; ***   Peter Stadler(Peter.Stadler@univie.ac.at)    ***\n; *** Original Author:                               ***\n; ***                                                ***\n; ***   Michael Reitz (innosetup@assimilate.de)      ***\n; ***                                                ***\n; *** Contributors:                                  ***\n; ***                                                ***\n; ***   Roland Ruder (info@rr4u.de)                  ***\n; ***   Hans Sperber (Hans.Sperber@de.bosch.com)     ***\n; ***   LaughingMan (puma.d@web.de)                  ***\n; ***                                                ***\n; ******************************************************\n;\n; Diese bersetzung hlt sich an die neue deutsche Rechtschreibung.\n\n[LangOptions]\nLanguageName=Deutsch\nLanguageID=$0407\nLanguageCodePage=1252\n; If the language you are translating to requires special font faces or\n; sizes, uncomment any of the following entries and change them accordingly.\n;DialogFontName=\n;DialogFontSize=8\n;WelcomeFontName=Verdana\n;WelcomeFontSize=12\n;TitleFontName=Arial\n;TitleFontSize=29\n;CopyrightFontName=Arial\n;CopyrightFontSize=8\n\n[Messages]\n\n; *** Application titles\nSetupAppTitle=Setup\nSetupWindowTitle=Setup - %1\nUninstallAppTitle=Entfernen\nUninstallAppFullTitle=%1 entfernen\n\n; *** Misc. common\nInformationTitle=Information\nConfirmTitle=Besttigen\nErrorTitle=Fehler\n\n; *** SetupLdr messages\nSetupLdrStartupMessage=%1 wird jetzt installiert. Mchten Sie fortfahren?\nLdrCannotCreateTemp=Es konnte keine temporre Datei erstellt werden. Das Setup wurde abgebrochen\nLdrCannotExecTemp=Die Datei konnte nicht im temporren Ordner ausgefhrt werden. Das Setup wurde abgebrochen\n\n; *** Startup error messages\nLastErrorMessage=%1.%n%nFehler %2: %3\nSetupFileMissing=Die Datei %1 fehlt im Installations-Ordner. Bitte beheben Sie das Problem, oder besorgen Sie sich eine neue Kopie des Programms.\nSetupFileCorrupt=Die Setup-Dateien sind beschdigt. Besorgen Sie sich bitte eine neue Kopie des Programms.\nSetupFileCorruptOrWrongVer=Die Setup-Dateien sind beschdigt oder inkompatibel zu dieser Version des Setups. Bitte beheben Sie das Problem, oder besorgen Sie sich eine neue Kopie des Programms.\nInvalidParameter=Ein ungltiger Paramter wurde auf der Kommandozeile bergeben:%n%n%1\nSetupAlreadyRunning=Setup luft bereits.\nWindowsVersionNotSupported=Dieses Programm untersttzt die auf Ihrem Computer installierte Windows-Version nicht.\nWindowsServicePackRequired=Dieses Programm bentigt %1 Service Pack %2 oder hher.\nNotOnThisPlatform=Dieses Programm kann nicht unter %1 ausgefhrt werden.\nOnlyOnThisPlatform=Dieses Programm muss unter %1 ausgefhrt werden.\nOnlyOnTheseArchitectures=Dieses Programm kann nur auf Windows-Versionen installiert werden, die folgende Prozessor-Architekturen untersttzen:%n%n%1\nMissingWOW64APIs=Ihre Windows-Version enthlt nicht die Funktionen, die vom Setup fr eine 64-bit Installation bentigt werden. Installieren Sie bitte Service Pack %1, um dieses Problem zu beheben.\nWinVersionTooLowError=Dieses Programm bentigt %1 Version %2 oder hher.\nWinVersionTooHighError=Dieses Programm kann nicht unter %1 Version %2 oder hher installiert werden.\nAdminPrivilegesRequired=Sie mssen als Administrator angemeldet sein, um dieses Programm installieren zu knnen.\nPowerUserPrivilegesRequired=Sie mssen als Administrator oder als Mitglied der Hauptbenutzer-Gruppe angemeldet sein, um dieses Programm installieren zu knnen.\nSetupAppRunningError=Das Setup hat entdeckt, dass %1 zur Zeit ausgefhrt wird.%n%nBitte schlieen Sie jetzt alle laufenden Instanzen, und klicken Sie auf \"OK\", um fortzufahren, oder auf \"Abbrechen\", um zu beenden.\nUninstallAppRunningError=Die Deinstallation hat entdeckt, dass %1 zur Zeit ausgefhrt wird.%n%nBitte schlieen Sie jetzt alle laufenden Instanzen, und klicken Sie auf \"OK\", um fortzufahren, oder auf \"Abbrechen\", um zu beenden.\n\n; *** Misc. errors\nErrorCreatingDir=Das Setup konnte den Ordner \"%1\" nicht erstellen\nErrorTooManyFilesInDir=Das Setup konnte eine Datei im Ordner \"%1\" nicht erstellen, weil er zu viele Dateien enthlt\n\n; *** Setup common messages\nExitSetupTitle=Setup verlassen\nExitSetupMessage=Das Setup ist noch nicht abgeschlossen. Wenn Sie jetzt beenden, wird das Programm nicht installiert.%n%nSie knnen das Setup zu einem spteren Zeitpunkt nochmals ausfhren, um die Installation zu vervollstndigen.%n%nSetup verlassen?\nAboutSetupMenuItem=&ber das Setup ...\nAboutSetupTitle=ber das Setup\nAboutSetupMessage=%1 Version %2%n%3%n%n%1 Internet-Seite:%n%4\nAboutSetupNote=\nTranslatorNote=German translation maintained by Peter Stadler (Peter.Stadler@univie.ac.at)\n\n; *** Buttons\nButtonBack=< &Zurck\nButtonNext=&Weiter >\nButtonInstall=&Installieren\nButtonOK=OK\nButtonCancel=Abbrechen\nButtonYes=&Ja\nButtonYesToAll=J&a fr Alle\nButtonNo=&Nein\nButtonNoToAll=N&ein fr Alle\nButtonFinish=&Fertigstellen\nButtonBrowse=&Durchsuchen ...\nButtonWizardBrowse=Du&rchsuchen ...\nButtonNewFolder=&Neuen Ordner erstellen\n\n; *** \"Select Language\" dialog messages\nSelectLanguageTitle=Sprache auswhlen\nSelectLanguageLabel=Whlen Sie eine Sprache fr die Installation von AviSynth+ aus:\n\n; *** Common wizard text\nClickNext=\"Weiter\" zum Fortfahren, \"Abbrechen\" zum Verlassen.\nBeveledLabel=\nBrowseDialogTitle=Ordner suchen\nBrowseDialogLabel=Whlen Sie einen Ordner aus, und klicken Sie danach auf \"OK\".\nNewFolderName=Neuer Ordner\n\n; *** \"Welcome\" wizard page\nWelcomeLabel1=Willkommen zum [name] Setup-Assistenten\nWelcomeLabel2=Dieser Assistent wird jetzt [name/ver] auf Ihrem Computer installieren.%n%nSie sollten alle anderen Anwendungen beenden, bevor Sie mit dem Setup fortfahren.\n\n; *** \"Password\" wizard page\nWizardPassword=Passwort\nPasswordLabel1=Diese Installation wird durch ein Passwort geschtzt.\nPasswordLabel3=Bitte geben Sie das Passwort ein, und klicken Sie danach auf \"Weiter\". Achten Sie auf korrekte Gro-/Kleinschreibung.\nPasswordEditLabel=&Passwort:\nIncorrectPassword=Das eingegebene Passwort ist nicht korrekt. Bitte versuchen Sie es noch einmal.\n\n; *** \"License Agreement\" wizard page\nWizardLicense=Lizenzvereinbarung\nLicenseLabel=Lesen Sie bitte folgende, wichtige Informationen bevor Sie fortfahren.\nLicenseLabel3=Lesen Sie bitte die folgenden Lizenzvereinbarungen. Benutzen Sie bei Bedarf die Bildlaufleiste oder drcken Sie die \"Bild Ab\"-Taste.\nLicenseAccepted=Ich &akzeptiere die Vereinbarung\nLicenseNotAccepted=Ich &lehne die Vereinbarung ab\n\n; *** \"Information\" wizard pages\nWizardInfoBefore=Information\nInfoBeforeLabel=Lesen Sie bitte folgende, wichtige Informationen bevor Sie fortfahren.\nInfoBeforeClickLabel=Klicken Sie auf \"Weiter\", sobald Sie bereit sind mit dem Setup fortzufahren.\nWizardInfoAfter=Information\nInfoAfterLabel=Lesen Sie bitte folgende, wichtige Informationen bevor Sie fortfahren.\nInfoAfterClickLabel=Klicken Sie auf \"Weiter\", sobald Sie bereit sind mit dem Setup fortzufahren.\n\n; *** \"User Information\" wizard page\nWizardUserInfo=Benutzerinformationen\nUserInfoDesc=Bitte tragen Sie Ihre Daten ein.\nUserInfoName=&Name:\nUserInfoOrg=&Organisation:\nUserInfoSerial=&Seriennummer:\nUserInfoNameRequired=Sie mssen einen Namen eintragen.\n\n; *** \"Select Destination Location\" wizard page\nWizardSelectDir=Ziel-Ordner whlen\nSelectDirDesc=Wohin soll [name] installiert werden?\nSelectDirLabel3=Das Setup wird [name] in den folgenden Ordner installieren.\nSelectDirBrowseLabel=Klicken Sie auf \"Weiter\", um fortzufahren. Klicken Sie auf \"Durchsuchen\", falls Sie einen anderen Ordner auswhlen mchten.\nDiskSpaceMBLabel=Mindestens [mb] MB freier Speicherplatz ist erforderlich.\nCannotInstallToNetworkDrive=Das Setup kann nicht in einen Netzwerk-Pfad installieren.\nCannotInstallToUNCPath=Das Setup kann nicht in einen UNC-Pfad installieren. Wenn Sie auf ein Netzlaufwerk installieren mchten, mssen Sie dem Netzwerkpfad einen Laufwerksbuchstaben zuordnen.\nInvalidPath=Sie mssen einen vollstndigen Pfad mit einem Laufwerksbuchstaben angeben; z.B.:%n%nC:\\Beispiel%n%noder einen UNC-Pfad in der Form:%n%n\\\\Server\\Freigabe\nInvalidDrive=Das angegebene Laufwerk bzw. der UNC-Pfad existiert nicht oder es kann nicht darauf zugegriffen werden. Whlen Sie bitte einen anderen Ordner.\nDiskSpaceWarningTitle=Nicht genug freier Speicherplatz\nDiskSpaceWarning=Das Setup bentigt mindestens %1 KB freien Speicherplatz zum Installieren, aber auf dem ausgewhlten Laufwerk sind nur %2 KB verfgbar.%n%nMchten Sie trotzdem fortfahren?\nDirNameTooLong=Der Ordnername/Pfad ist zu lang.\nInvalidDirName=Der Ordnername ist nicht gltig.\nBadDirName32=Ordnernamen drfen keine der folgenden Zeichen enthalten:%n%n%1\nDirExistsTitle=Ordner existiert bereits\nDirExists=Der Ordner:%n%n%1%n%n existiert bereits. Mchten Sie trotzdem in diesen Ordner installieren?\nDirDoesntExistTitle=Ordner ist nicht vorhanden\nDirDoesntExist=Der Ordner:%n%n%1%n%nist nicht vorhanden. Soll der Ordner erstellt werden?\n\n; *** \"Select Components\" wizard page\nWizardSelectComponents=Komponenten auswhlen\nSelectComponentsDesc=Welche Komponenten sollen installiert werden?\nSelectComponentsLabel2=Whlen Sie die Komponenten aus, die Sie installieren mchten. Klicken Sie auf \"Weiter\", wenn sie bereit sind fortzufahren.\nFullInstallation=Vollstndige Installation\n; if possible don't translate 'Compact' as 'Minimal' (I mean 'Minimal' in your language)\nCompactInstallation=Kompakte Installation\nCustomInstallation=Benutzerdefinierte Installation\nNoUninstallWarningTitle=Komponenten vorhanden\nNoUninstallWarning=Das Setup hat festgestellt, dass die folgenden Komponenten bereits auf Ihrem Computer installiert sind:%n%n%1%n%nDiese nicht mehr ausgewhlten Komponenten werden nicht vom Computer entfernt.%n%nMchten Sie trotzdem fortfahren?\nComponentSize1=%1 KB\nComponentSize2=%1 MB\nComponentsDiskSpaceMBLabel=Die aktuelle Auswahl erfordert min. [mb] MB Speicherplatz.\n\n; *** \"Select Additional Tasks\" wizard page\nWizardSelectTasks=Zustzliche Aufgaben auswhlen\nSelectTasksDesc=Welche zustzlichen Aufgaben sollen ausgefhrt werden?\nSelectTasksLabel2=Whlen Sie die zustzlichen Aufgaben aus, die das Setup whrend der Installation von [name] ausfhren soll, und klicken Sie danach auf \"Weiter\".\n\n; *** \"Select Start Menu Folder\" wizard page\nWizardSelectProgramGroup=Startmen-Ordner auswhlen\nSelectStartMenuFolderDesc=Wo soll das Setup die Programm-Verknpfungen erstellen?\nSelectStartMenuFolderLabel3=Das Setup wird die Programm-Verknpfungen im folgenden Startmen-Ordner erstellen.\nSelectStartMenuFolderBrowseLabel=Klicken Sie auf \"Weiter\", um fortzufahren. Klicken Sie auf \"Durchsuchen\", falls Sie einen anderen Ordner auswhlen mchten.\nMustEnterGroupName=Sie mssen einen Ordnernamen eingeben.\nGroupNameTooLong=Der Ordnername/Pfad ist zu lang.\nInvalidGroupName=Der Ordnername ist nicht gltig.\nBadGroupName=Der Ordnername darf keine der folgenden Zeichen enthalten:%n%n%1\nNoProgramGroupCheck2=&Keinen Ordner im Startmen erstellen\n\n; *** \"Ready to Install\" wizard page\nWizardReady=Bereit zur Installation.\nReadyLabel1=Das Setup ist jetzt bereit, [name] auf Ihrem Computer zu installieren.\nReadyLabel2a=Klicken Sie auf \"Installieren\", um mit der Installation zu beginnen, oder auf \"Zurck\", um Ihre Einstellungen zu berprfen oder zu ndern.\nReadyLabel2b=Klicken Sie auf \"Installieren\", um mit der Installation zu beginnen.\nReadyMemoUserInfo=Benutzerinformationen:\nReadyMemoDir=Ziel-Ordner:\nReadyMemoType=Setup-Typ:\nReadyMemoComponents=Ausgewhlte Komponenten:\nReadyMemoGroup=Startmen-Ordner:\nReadyMemoTasks=Zustzliche Aufgaben:\n\n; *** \"Preparing to Install\" wizard page\nWizardPreparing=Vorbereitung der Installation\nPreparingDesc=Das Setup bereitet die Installation von [name] auf diesen Computer vor.\nPreviousInstallNotCompleted=Eine vorherige Installation/Deinstallation eines Programms wurde nicht abgeschlossen. Der Computer muss neu gestartet werden, um die Installation/Deinstallation zu beenden.%n%nStarten Sie das Setup nach dem Neustart Ihres Computers erneut, um die Installation von [name] durchzufhren.\nCannotContinue=Das Setup kann nicht fortfahren. Bitte klicken Sie auf \"Abbrechen\" zum Verlassen.\nApplicationsFound=Die folgenden Anwendungen benutzen Dateien, die aktualisiert werden mssen. Es wird empfohlen, Setup zu erlauben, diese Anwendungen zu schlieen.\nApplicationsFound2=Die folgenden Anwendungen benutzen Dateien, die aktualisiert werden mssen. Es wird empfohlen, Setup zu erlauben, diese Anwendungen zu schlieen. Nachdem die Installation fertiggestellt wurde, versucht Setup diese Anwendungen wieder zu starten.\nCloseApplications=&Schliee automatisch die Anwendungen\nDontCloseApplications=&Schliee die Anwendungen nicht\nErrorCloseApplications=Das Setup konnte nicht alle Anwendungen automatisch schlieen. Es wird empfohlen, alle Anwendungen zu schlieen, die Dateien benutzen, die vom Setup vor einer Fortsetzung aktualisiert werden mssen.  \n\n; *** \"Installing\" wizard page\nWizardInstalling=Installiere ...\nInstallingLabel=Warten Sie bitte whrend [name] auf Ihrem Computer installiert wird.\n\n; *** \"Setup Completed\" wizard page\nFinishedHeadingLabel=Beenden des [name] Setup-Assistenten\nFinishedLabelNoIcons=Das Setup hat die Installation von [name] auf Ihrem Computer abgeschlossen.\nFinishedLabel=Das Setup hat die Installation von [name] auf Ihrem Computer abgeschlossen. Die Anwendung kann ber die installierten Programm-Verknpfungen gestartet werden.\nClickFinish=Klicken Sie auf \"Fertigstellen\", um das Setup zu beenden.\nFinishedRestartLabel=Um die Installation von [name] abzuschlieen, muss das Setup Ihren Computer neu starten. Mchten Sie jetzt neu starten?\nFinishedRestartMessage=Um die Installation von [name] abzuschlieen, muss das Setup Ihren Computer neu starten.%n%nMchten Sie jetzt neu starten?\nShowReadmeCheck=Ja, ich mchte die LIESMICH-Datei sehen\nYesRadio=&Ja, Computer jetzt neu starten\nNoRadio=&Nein, ich werde den Computer spter neu starten\n; used for example as 'Run MyProg.exe'\nRunEntryExec=%1 starten\n; used for example as 'View Readme.txt'\nRunEntryShellExec=%1 anzeigen\n\n; *** \"Setup Needs the Next Disk\" stuff\nChangeDiskTitle=Nchste Diskette einlegen\nSelectDiskLabel2=Legen Sie bitte Diskette %1 ein, und klicken Sie auf \"OK\".%n%nWenn sich die Dateien von dieser Diskette in einem anderen als dem angezeigten Ordner befinden, dann geben Sie bitte den korrekten Pfad ein oder klicken auf \"Durchsuchen\".\nPathLabel=&Pfad:\nFileNotInDir2=Die Datei \"%1\" befindet sich nicht in \"%2\". Bitte Ordner ndern oder richtige Diskette einlegen.\nSelectDirectoryLabel=Geben Sie bitte an, wo die nchste Diskette eingelegt wird.\n\n; *** Installation phase messages\nSetupAborted=Das Setup konnte nicht abgeschlossen werden.%n%nBeheben Sie bitte das Problem, und starten Sie das Setup erneut.\nEntryAbortRetryIgnore=Klicken Sie auf \"Wiederholen\" fr einen weiteren Versuch, \"Ignorieren\", um trotzdem fortzufahren, oder \"Abbrechen\", um die Installation abzubrechen.\n\n; *** Installation status messages\nStatusClosingApplications=Anwendungen werden geschlossen...\nStatusCreateDirs=Ordner werden erstellt ...\nStatusExtractFiles=Dateien werden entpackt ...\nStatusCreateIcons=Verknpfungen werden erstellt ...\nStatusCreateIniEntries=INI-Eintrge werden erstellt ...\nStatusCreateRegistryEntries=Registry-Eintrge werden erstellt ...\nStatusRegisterFiles=Dateien werden registriert ...\nStatusSavingUninstall=Deinstallations-Informationen werden gespeichert ...\nStatusRunProgram=Installation wird beendet ...\nStatusRestartingApplications=Neustart der Anwendungen...\nStatusRollback=nderungen werden rckgngig gemacht ...\n\n; *** Misc. errors\nErrorInternal2=Interner Fehler: %1\nErrorFunctionFailedNoCode=%1 schlug fehl\nErrorFunctionFailed=%1 schlug fehl; Code %2\nErrorFunctionFailedWithMessage=%1 schlug fehl; Code %2.%n%3\nErrorExecutingProgram=Datei kann nicht ausgefhrt werden:%n%1\n\n; *** Registry errors\nErrorRegOpenKey=Registry-Schlssel konnte nicht geffnet werden:%n%1\\%2\nErrorRegCreateKey=Registry-Schlssel konnte nicht erstellt werden:%n%1\\%2\nErrorRegWriteKey=Fehler beim Schreiben des Registry-Schlssels:%n%1\\%2\n\n; *** INI errors\nErrorIniEntry=Fehler beim Erstellen eines INI-Eintrages in der Datei \"%1\".\n\n; *** File copying errors\nFileAbortRetryIgnore=Klicken Sie auf \"Wiederholen\" fr einen weiteren Versuch, \"Ignorieren\", um diese Datei zu berspringen (nicht empfohlen), oder \"Abbrechen\", um die Installation abzubrechen.\nFileAbortRetryIgnore2=Klicken Sie auf \"Wiederholen\" fr einen weiteren Versuch, \"Ignorieren\", um trotzdem fortzufahren (nicht empfohlen), oder \"Abbrechen\", um die Installation abzubrechen.\nSourceIsCorrupted=Die Quelldatei ist beschdigt\nSourceDoesntExist=Die Quelldatei \"%1\" existiert nicht\nExistingFileReadOnly=Die vorhandene Datei ist schreibgeschtzt.%n%nKlicken Sie auf \"Wiederholen\", um den Schreibschutz zu entfernen, \"Ignorieren\", um die Datei zu berspringen, oder \"Abbrechen\", um die Installation abzubrechen.\nErrorReadingExistingDest=Lesefehler in Datei:\nFileExists=Die Datei ist bereits vorhanden.%n%nSoll sie berschrieben werden?\nExistingFileNewer=Die vorhandene Datei ist neuer als die Datei, die installiert werden soll. Es wird empfohlen die vorhandene Datei beizubehalten.%n%n Mchten Sie die vorhandene Datei beibehalten?\nErrorChangingAttr=Fehler beim ndern der Datei-Attribute:\nErrorCreatingTemp=Fehler beim Erstellen einer Datei im Ziel-Ordner:\nErrorReadingSource=Fehler beim Lesen der Quelldatei:\nErrorCopying=Fehler beim Kopieren einer Datei:\nErrorReplacingExistingFile=Fehler beim Ersetzen einer vorhandenen Datei:\nErrorRestartReplace=\"Ersetzen nach Neustart\" fehlgeschlagen:\nErrorRenamingTemp=Fehler beim Umbenennen einer Datei im Ziel-Ordner:\nErrorRegisterServer=DLL/OCX konnte nicht registriert werden: %1\nErrorRegSvr32Failed=RegSvr32-Aufruf scheiterte mit Exit-Code %1\nErrorRegisterTypeLib=Typen-Bibliothek konnte nicht registriert werden: %1\n\n; *** Post-installation errors\nErrorOpeningReadme=Fehler beim ffnen der LIESMICH-Datei.\nErrorRestartingComputer=Das Setup konnte den Computer nicht neu starten. Bitte fhren Sie den Neustart manuell durch.\n\n; *** Uninstaller messages\nUninstallNotFound=Die Datei \"%1\" existiert nicht. Entfernen der Anwendung fehlgeschlagen.\nUninstallOpenError=Die Datei \"%1\" konnte nicht geffnet werden. Entfernen der Anwendung fehlgeschlagen.\nUninstallUnsupportedVer=Das Format der Deinstallations-Datei \"%1\" konnte nicht erkannt werden. Entfernen der Anwendung fehlgeschlagen\nUninstallUnknownEntry=In der Deinstallations-Datei wurde ein unbekannter Eintrag (%1) gefunden\nConfirmUninstall=Sind Sie sicher, dass Sie %1 und alle zugehrigen Komponenten entfernen mchten?\nUninstallOnlyOnWin64=Diese Installation kann nur unter 64-bit Windows-Versionen entfernt werden.\nOnlyAdminCanUninstall=Diese Installation kann nur von einem Benutzer mit Administrator-Rechten entfernt werden.\nUninstallStatusLabel=Warten Sie bitte whrend %1 von Ihrem Computer entfernt wird.\nUninstalledAll=%1 wurde erfolgreich von Ihrem Computer entfernt.\nUninstalledMost=Entfernen von %1 beendet.%n%nEinige Komponenten konnten nicht entfernt werden. Diese knnen von Ihnen manuell gelscht werden.\nUninstalledAndNeedsRestart=Um die Deinstallation von %1 abzuschlieen, muss Ihr Computer neu gestartet werden.%n%nMchten Sie jetzt neu starten?\nUninstallDataCorrupted=\"%1\"-Datei ist beschdigt. Entfernen der Anwendung fehlgeschlagen.\n\n; *** Uninstallation phase messages\nConfirmDeleteSharedFileTitle=Gemeinsame Datei entfernen?\nConfirmDeleteSharedFile2=Das System zeigt an, dass die folgende gemeinsame Datei von keinem anderen Programm mehr benutzt wird. Mchten Sie diese Datei entfernen lassen?%nSollte es doch noch Programme geben, die diese Datei benutzen, und sie wird entfernt, funktionieren diese Programme vielleicht nicht mehr richtig. Wenn Sie unsicher sind, whlen Sie \"Nein\" um die Datei im System zu belassen. Es schadet Ihrem System nicht, wenn Sie die Datei behalten.\nSharedFileNameLabel=Dateiname:\nSharedFileLocationLabel=Ordner:\nWizardUninstalling=Entfernen (Status)\nStatusUninstalling=Entferne %1 ...\n\n; *** Shutdown block reasons\nShutdownBlockReasonInstallingApp=Installation von %1.\nShutdownBlockReasonUninstallingApp=Deinstallation von %1.\n\n; The custom messages below aren't used by Setup itself, but if you make\n; use of them in your scripts, you'll want to translate them.\n\n[CustomMessages]\n\nNameAndVersion=%1 Version %2\nAdditionalIcons=Zustzliche Symbole:\nCreateDesktopIcon=&Desktop-Symbol erstellen\nCreateQuickLaunchIcon=Symbol in der Schnellstartleiste erstellen\nProgramOnTheWeb=%1 im Internet\nUninstallProgram=%1 entfernen\nLaunchProgram=%1 starten\nAssocFileExtension=&Registriere %1 mit der %2-Dateierweiterung\nAssocingFileExtension=%1 wird mit der %2-Dateierweiterung registriert...\nAutoStartProgramGroupDescription=Beginn des Setups:\nAutoStartProgram=Starte automatisch%1\nAddonHostProgramNotFound=%1 konnte im ausgwhlten Ordner nicht gefunden werden.%n%nMchten Sie dennoch fortfahren?\n\n; *** AviSynth+ custom messages\n\nFullInstallation=Vollstndige Installation\nCompactInstallation=Empfohlene Installation\nCustomInstallation=Benutzerdefinierte Installation\n\nCmpMain=%1-Basis\nCmpDocs=Dokumentation\nCmpDocsEn=Englisch\nCmpDocsCs=Tschechisch\nCmpDocsDe=Deutsch\nCmpDocsFr=Franzsisch\nCmpDocsIt=Italienisch\nCmpDocsJa=Japanisch\nCmpDocsPl=Polnisch\nCmpDocsPt=Portugiesisch\nCmpDocsRu=Russisch\nCmpDocsExamples=Beispielskripte\nCmpSdk=Filter-SDK\nCmpMig=Upgrade von frherer AviSynth-Version\nCmpMigUninstall=Deinstallieren und Plugins zu %1 migrieren\nCmpMigBackup=AviSynth fr sptere Wiederherstellung sichern\nCmpCustomizePluginPaths=Plugin-Pfade anpassen\n\nFileTypeDescAvs=%1-Skript\nFileTypeDescAvsi=%1-Skript (autoload)\n\nInstallStatusRuntime = Installiere %1 (%2)...%nDies kann bis zu 5 Minuten beanspruchen...\nUninstallStatusLegacyRestore = Stelle frhere AviSynth-Installation wieder her...\nBackupRestoreFailed=Whrend der Wiederherstellung Ihrer frheren AviSynth-Installation ist ein Fehler aufgetreten:%n%1\n\nMigPageCaption=Upgrade-Optionen\nMigPageDescription=Wie soll %1 mit ihrer bestehenden AviSynth-Installation vorgehen?\nMigPageSubCaption=Das Setup hat eine bestehende AviSynth-Installation in folgendem Ordner gefunden:%n%n%2%n%nAus technischen Grnden knnen Avisynth und %1 aber nicht gleichzeitig installiert sein. Fr den Fall, dass sie ihre frhere AviSynth-Installation spter wiederhestellen mchten, kann das Setup diese jetzt sichern.\nMigPageOptionBackup=Von %1 berschriebene Avisynth-Systemkomponenten zur Wiederherstellung bei der %1-Deinstallation sichern. Plugins werden sowohl aus den bestehenden, von AviSynth angelegten Plugin-Ordnern, als auch aus %1's eigenen Ordnern automatisch geladen.\nMigPageOptionUninstall=AviSynth vor der Installation von %1 deinstallieren und bestehende Plugins zu %1 migrieren.\nMigPageUninstallFailed=Deinstallation von AviSynth ist fehlgeschlagen: %n%1\n \nPlugPageCaption=%1 Plugin-Ordner\nPlugPageDescription=Aus welchen Ordnern soll %1 Plugins automatisch laden?\nPlugPageSubCaption=Setup installiert die mitgelieferten Plugins in die %1-Plugin-Ordner. Plugins aus den Ordnern fr AviSynth 2.5/2.6-Plugins werden ebenfalls automatisch geladen.\nPlugPagePlugDirPlus=%2 %1-bit Plugin-Pfad:\nPlugPagePlugDirLegacy=AviSynth %1-bit Plugin-Pfad:"
  },
  {
    "path": "distrib/WinInstaller/Translations/en.isl",
    "content": "; *** Inno Setup version 5.5.3+ English messages ***\n;\n; To download user-contributed translations of this file, go to:\n;   http://www.jrsoftware.org/files/istrans/\n;\n; Note: When translating this text, do not add periods (.) to the end of\n; messages that didn't have them already, because on those messages Inno\n; Setup adds the periods automatically (appending a period would result in\n; two periods being displayed).\n\n[LangOptions]\n; The following three entries are very important. Be sure to read and \n; understand the '[LangOptions] section' topic in the help file.\nLanguageName=English\nLanguageID=$0409\nLanguageCodePage=0\n; If the language you are translating to requires special font faces or\n; sizes, uncomment any of the following entries and change them accordingly.\n;DialogFontName=\n;DialogFontSize=8\n;WelcomeFontName=Verdana\n;WelcomeFontSize=12\n;TitleFontName=Arial\n;TitleFontSize=29\n;CopyrightFontName=Arial\n;CopyrightFontSize=8\n\n[Messages]\n\n; *** Application titles\nSetupAppTitle=Setup\nSetupWindowTitle=Setup - %1\nUninstallAppTitle=Uninstall\nUninstallAppFullTitle=%1 Uninstall\n\n; *** Misc. common\nInformationTitle=Information\nConfirmTitle=Confirm\nErrorTitle=Error\n\n; *** SetupLdr messages\nSetupLdrStartupMessage=This will install %1. Do you wish to continue?\nLdrCannotCreateTemp=Unable to create a temporary file. Setup aborted\nLdrCannotExecTemp=Unable to execute file in the temporary directory. Setup aborted\n\n; *** Startup error messages\nLastErrorMessage=%1.%n%nError %2: %3\nSetupFileMissing=The file %1 is missing from the installation directory. Please correct the problem or obtain a new copy of the program.\nSetupFileCorrupt=The setup files are corrupted. Please obtain a new copy of the program.\nSetupFileCorruptOrWrongVer=The setup files are corrupted, or are incompatible with this version of Setup. Please correct the problem or obtain a new copy of the program.\nInvalidParameter=An invalid parameter was passed on the command line:%n%n%1\nSetupAlreadyRunning=Setup is already running.\nWindowsVersionNotSupported=This program does not support the version of Windows your computer is running.\nWindowsServicePackRequired=This program requires %1 Service Pack %2 or later.\nNotOnThisPlatform=This program will not run on %1.\nOnlyOnThisPlatform=This program must be run on %1.\nOnlyOnTheseArchitectures=This program can only be installed on versions of Windows designed for the following processor architectures:%n%n%1\nMissingWOW64APIs=The version of Windows you are running does not include functionality required by Setup to perform a 64-bit installation. To correct this problem, please install Service Pack %1.\nWinVersionTooLowError=This program requires %1 version %2 or later.\nWinVersionTooHighError=This program cannot be installed on %1 version %2 or later.\nAdminPrivilegesRequired=You must be logged in as an administrator when installing this program.\nPowerUserPrivilegesRequired=You must be logged in as an administrator or as a member of the Power Users group when installing this program.\nSetupAppRunningError=Setup has detected that %1 is currently running.%n%nPlease close all instances of it now, then click OK to continue, or Cancel to exit.\nUninstallAppRunningError=Uninstall has detected that %1 is currently running.%n%nPlease close all instances of it now, then click OK to continue, or Cancel to exit.\n\n; *** Misc. errors\nErrorCreatingDir=Setup was unable to create the directory \"%1\"\nErrorTooManyFilesInDir=Unable to create a file in the directory \"%1\" because it contains too many files\n\n; *** Setup common messages\nExitSetupTitle=Exit Setup\nExitSetupMessage=Setup is not complete. If you exit now, the program will not be installed.%n%nYou may run Setup again at another time to complete the installation.%n%nExit Setup?\nAboutSetupMenuItem=&About Setup...\nAboutSetupTitle=About Setup\nAboutSetupMessage=%1 version %2%n%3%n%n%1 home page:%n%4\nAboutSetupNote=\nTranslatorNote=\n\n; *** Buttons\nButtonBack=< &Back\nButtonNext=&Next >\nButtonInstall=&Install\nButtonOK=OK\nButtonCancel=Cancel\nButtonYes=&Yes\nButtonYesToAll=Yes to &All\nButtonNo=&No\nButtonNoToAll=N&o to All\nButtonFinish=&Finish\nButtonBrowse=&Browse...\nButtonWizardBrowse=B&rowse...\nButtonNewFolder=&Make New Folder\n\n; *** \"Select Language\" dialog messages\nSelectLanguageTitle=Select Language\nSelectLanguageLabel=Select the language to install AviSynth+ in:\n\n; *** Common wizard text\nClickNext=Click Next to continue, or Cancel to exit Setup.\nBeveledLabel=\nBrowseDialogTitle=Browse For Folder\nBrowseDialogLabel=Select a folder in the list below, then click OK.\nNewFolderName=New Folder\n\n; *** \"Welcome\" wizard page\nWelcomeLabel1=Welcome to the [name] Setup\nWelcomeLabel2=This will install [name/ver] on your computer.%n%nIt is recommended that you close all other applications before continuing.\n\n; *** \"Password\" wizard page\nWizardPassword=Password\nPasswordLabel1=This installation is password protected.\nPasswordLabel3=Please provide the password, then click Next to continue. Passwords are case-sensitive.\nPasswordEditLabel=&Password:\nIncorrectPassword=The password you entered is not correct. Please try again.\n\n; *** \"License Agreement\" wizard page\nWizardLicense=License Agreement\nLicenseLabel=Please read the following important information before continuing.\nLicenseLabel3=You must accept the terms of this agreement before continuing with the installation.\nLicenseAccepted=I &accept the agreement\nLicenseNotAccepted=I &do not accept the agreement\n\n; *** \"Information\" wizard pages\nWizardInfoBefore=Information\nInfoBeforeLabel=Please read the following important information before continuing.\nInfoBeforeClickLabel=When you are ready to continue with Setup, click Next.\nWizardInfoAfter=Information\nInfoAfterLabel=Please read the following important information before continuing.\nInfoAfterClickLabel=When you are ready to continue with Setup, click Next.\n\n; *** \"User Information\" wizard page\nWizardUserInfo=User Information\nUserInfoDesc=Please enter your information.\nUserInfoName=&User Name:\nUserInfoOrg=&Organization:\nUserInfoSerial=&Serial Number:\nUserInfoNameRequired=You must enter a name.\n\n; *** \"Select Destination Location\" wizard page\nWizardSelectDir=Select Destination Location\nSelectDirDesc=Where should [name] be installed?\nSelectDirLabel3=Setup will install [name] into the following folder.\nSelectDirBrowseLabel=To continue, click Next. If you would like to select a different folder, click Browse.\nDiskSpaceMBLabel=At least [mb] MB of free disk space is required.\nCannotInstallToNetworkDrive=Setup cannot install to a network drive.\nCannotInstallToUNCPath=Setup cannot install to a UNC path.\nInvalidPath=You must enter a full path with drive letter; for example:%n%nC:\\APP%n%nor a UNC path in the form:%n%n\\\\server\\share\nInvalidDrive=The drive or UNC share you selected does not exist or is not accessible. Please select another.\nDiskSpaceWarningTitle=Not Enough Disk Space\nDiskSpaceWarning=Setup requires at least %1 KB of free space to install, but the selected drive only has %2 KB available.%n%nDo you want to continue anyway?\nDirNameTooLong=The folder name or path is too long.\nInvalidDirName=The folder name is not valid.\nBadDirName32=Folder names cannot include any of the following characters:%n%n%1\nDirExistsTitle=Folder Exists\nDirExists=The folder:%n%n%1%n%nalready exists. Would you like to install to that folder anyway?\nDirDoesntExistTitle=Folder Does Not Exist\nDirDoesntExist=The folder:%n%n%1%n%ndoes not exist. Would you like the folder to be created?\n\n; *** \"Select Components\" wizard page\nWizardSelectComponents=Select Components\nSelectComponentsDesc=Which components should be installed?\nSelectComponentsLabel2=Select the components you want to install; clear the components you do not want to install. Click Next when you are ready to continue.\nFullInstallation=Full installation\n; if possible don't translate 'Compact' as 'Minimal' (I mean 'Minimal' in your language)\nCompactInstallation=Recommended installation\nCustomInstallation=Custom installation\nNoUninstallWarningTitle=Components Exist\nNoUninstallWarning=Setup has detected that the following components are already installed on your computer:%n%n%1%n%nDeselecting these components will not uninstall them.%n%nWould you like to continue anyway?\nComponentSize1=%1 KB\nComponentSize2=%1 MB\nComponentsDiskSpaceMBLabel=Current selection requires at least [mb] MB of disk space.\n\n; *** \"Select Additional Tasks\" wizard page\nWizardSelectTasks=Select Additional Tasks\nSelectTasksDesc=Which additional tasks should be performed?\nSelectTasksLabel2=Select the additional tasks you would like Setup to perform while installing [name], then click Next.\n\n; *** \"Select Start Menu Folder\" wizard page\nWizardSelectProgramGroup=Select Start Menu Folder\nSelectStartMenuFolderDesc=Where should Setup place the program's shortcuts?\nSelectStartMenuFolderLabel3=Setup will create the program's shortcuts in the following Start Menu folder.\nSelectStartMenuFolderBrowseLabel=To continue, click Next. If you would like to select a different folder, click Browse.\nMustEnterGroupName=You must enter a folder name.\nGroupNameTooLong=The folder name or path is too long.\nInvalidGroupName=The folder name is not valid.\nBadGroupName=The folder name cannot include any of the following characters:%n%n%1\nNoProgramGroupCheck2=&Don't create a Start Menu folder\n\n; *** \"Ready to Install\" wizard page\nWizardReady=Ready to Install\nReadyLabel1=Setup is now ready to begin installing [name] on your computer.\nReadyLabel2a=Click Install to continue with the installation, or click Back if you want to review or change any settings.\nReadyLabel2b=Click Install to continue with the installation.\nReadyMemoUserInfo=User information:\nReadyMemoDir=Destination location:\nReadyMemoType=Setup type:\nReadyMemoComponents=Selected components:\nReadyMemoGroup=Start Menu folder:\nReadyMemoTasks=Additional tasks:\n\n; *** \"Preparing to Install\" wizard page\nWizardPreparing=Preparing to Install\nPreparingDesc=Setup is preparing to install [name] on your computer.\nPreviousInstallNotCompleted=The installation/removal of a previous program was not completed. You will need to restart your computer to complete that installation.%n%nAfter restarting your computer, run Setup again to complete the installation of [name].\nCannotContinue=Setup cannot continue. Please click Cancel to exit.\nApplicationsFound=The following applications are using files that need to be updated by Setup. It is recommended that you allow Setup to automatically close these applications.\nApplicationsFound2=The following applications are using files that need to be updated by Setup. It is recommended that you allow Setup to automatically close these applications. After the installation has completed, Setup will attempt to restart the applications.\nCloseApplications=&Automatically close the applications\nDontCloseApplications=&Do not close the applications\nErrorCloseApplications=Setup was unable to automatically close all applications. It is recommended that you close all applications using files that need to be updated by Setup before continuing.\n\n; *** \"Installing\" wizard page\nWizardInstalling=Installing\nInstallingLabel=Please wait while Setup installs [name] on your computer.\n\n; *** \"Setup Completed\" wizard page\nFinishedHeadingLabel=Completing the [name] Setup Wizard\nFinishedLabelNoIcons=Setup has finished installing [name] on your computer.\nFinishedLabel=Setup has finished installing [name] on your computer. The application may be launched by selecting the installed icons.\nClickFinish=Click Finish to exit Setup.\nFinishedRestartLabel=To complete the installation of [name], Setup must restart your computer. Would you like to restart now?\nFinishedRestartMessage=To complete the installation of [name], Setup must restart your computer.%n%nWould you like to restart now?\nShowReadmeCheck=Yes, I would like to view the README file\nYesRadio=&Yes, restart the computer now\nNoRadio=&No, I will restart the computer later\n; used for example as 'Run MyProg.exe'\nRunEntryExec=Run %1\n; used for example as 'View Readme.txt'\nRunEntryShellExec=View %1\n\n; *** \"Setup Needs the Next Disk\" stuff\nChangeDiskTitle=Setup Needs the Next Disk\nSelectDiskLabel2=Please insert Disk %1 and click OK.%n%nIf the files on this disk can be found in a folder other than the one displayed below, enter the correct path or click Browse.\nPathLabel=&Path:\nFileNotInDir2=The file \"%1\" could not be located in \"%2\". Please insert the correct disk or select another folder.\nSelectDirectoryLabel=Please specify the location of the next disk.\n\n; *** Installation phase messages\nSetupAborted=Setup was not completed.%n%nPlease correct the problem and run Setup again.\nEntryAbortRetryIgnore=Click Retry to try again, Ignore to proceed anyway, or Abort to cancel installation.\n\n; *** Installation status messages\nStatusClosingApplications=Closing applications...\nStatusCreateDirs=Creating directories...\nStatusExtractFiles=Extracting files...\nStatusCreateIcons=Creating shortcuts...\nStatusCreateIniEntries=Creating INI entries...\nStatusCreateRegistryEntries=Creating registry entries...\nStatusRegisterFiles=Registering files...\nStatusSavingUninstall=Saving uninstall information...\nStatusRunProgram=Finishing installation...\nStatusRestartingApplications=Restarting applications...\nStatusRollback=Rolling back changes...\n\n; *** Misc. errors\nErrorInternal2=Internal error: %1\nErrorFunctionFailedNoCode=%1 failed\nErrorFunctionFailed=%1 failed; code %2\nErrorFunctionFailedWithMessage=%1 failed; code %2.%n%3\nErrorExecutingProgram=Unable to execute file:%n%1\n\n; *** Registry errors\nErrorRegOpenKey=Error opening registry key:%n%1\\%2\nErrorRegCreateKey=Error creating registry key:%n%1\\%2\nErrorRegWriteKey=Error writing to registry key:%n%1\\%2\n\n; *** INI errors\nErrorIniEntry=Error creating INI entry in file \"%1\".\n\n; *** File copying errors\nFileAbortRetryIgnore=Click Retry to try again, Ignore to skip this file (not recommended), or Abort to cancel installation.\nFileAbortRetryIgnore2=Click Retry to try again, Ignore to proceed anyway (not recommended), or Abort to cancel installation.\nSourceIsCorrupted=The source file is corrupted\nSourceDoesntExist=The source file \"%1\" does not exist\nExistingFileReadOnly=The existing file is marked as read-only.%n%nClick Retry to remove the read-only attribute and try again, Ignore to skip this file, or Abort to cancel installation.\nErrorReadingExistingDest=An error occurred while trying to read the existing file:\nFileExists=The file already exists.%n%nWould you like Setup to overwrite it?\nExistingFileNewer=The existing file is newer than the one Setup is trying to install. It is recommended that you keep the existing file.%n%nDo you want to keep the existing file?\nErrorChangingAttr=An error occurred while trying to change the attributes of the existing file:\nErrorCreatingTemp=An error occurred while trying to create a file in the destination directory:\nErrorReadingSource=An error occurred while trying to read the source file:\nErrorCopying=An error occurred while trying to copy a file:\nErrorReplacingExistingFile=An error occurred while trying to replace the existing file:\nErrorRestartReplace=RestartReplace failed:\nErrorRenamingTemp=An error occurred while trying to rename a file in the destination directory:\nErrorRegisterServer=Unable to register the DLL/OCX: %1\nErrorRegSvr32Failed=RegSvr32 failed with exit code %1\nErrorRegisterTypeLib=Unable to register the type library: %1\n\n; *** Post-installation errors\nErrorOpeningReadme=An error occurred while trying to open the README file.\nErrorRestartingComputer=Setup was unable to restart the computer. Please do this manually.\n\n; *** Uninstaller messages\nUninstallNotFound=File \"%1\" does not exist. Cannot uninstall.\nUninstallOpenError=File \"%1\" could not be opened. Cannot uninstall\nUninstallUnsupportedVer=The uninstall log file \"%1\" is in a format not recognized by this version of the uninstaller. Cannot uninstall\nUninstallUnknownEntry=An unknown entry (%1) was encountered in the uninstall log\nConfirmUninstall=Are you sure you want to completely remove %1 and all of its components?\nUninstallOnlyOnWin64=This installation can only be uninstalled on 64-bit Windows.\nOnlyAdminCanUninstall=This installation can only be uninstalled by a user with administrative privileges.\nUninstallStatusLabel=Please wait while %1 is removed from your computer.\nUninstalledAll=%1 was successfully removed from your computer.\nUninstalledMost=%1 uninstall complete.%n%nSome elements could not be removed. These can be removed manually.\nUninstalledAndNeedsRestart=To complete the uninstallation of %1, your computer must be restarted.%n%nWould you like to restart now?\nUninstallDataCorrupted=\"%1\" file is corrupted. Cannot uninstall\n\n; *** Uninstallation phase messages\nConfirmDeleteSharedFileTitle=Remove Shared File?\nConfirmDeleteSharedFile2=The system indicates that the following shared file is no longer in use by any programs. Would you like for Uninstall to remove this shared file?%n%nIf any programs are still using this file and it is removed, those programs may not function properly. If you are unsure, choose No. Leaving the file on your system will not cause any harm.\nSharedFileNameLabel=File name:\nSharedFileLocationLabel=Location:\nWizardUninstalling=Uninstall Status\nStatusUninstalling=Uninstalling %1...\n\n; *** Shutdown block reasons\nShutdownBlockReasonInstallingApp=Installing %1.\nShutdownBlockReasonUninstallingApp=Uninstalling %1.\n\n; The custom messages below aren't used by Setup itself, but if you make\n; use of them in your scripts, you'll want to translate them.\n\n[CustomMessages]\n\nNameAndVersion=%1 version %2\nAdditionalIcons=Additional icons:\nCreateDesktopIcon=Create a &desktop icon\nCreateQuickLaunchIcon=Create a &Quick Launch icon\nProgramOnTheWeb=%1 on the Web\nUninstallProgram=Uninstall %1\nLaunchProgram=Launch %1\nAssocFileExtension=&Associate %1 with the %2 file extension\nAssocingFileExtension=Associating %1 with the %2 file extension...\nAutoStartProgramGroupDescription=Startup:\nAutoStartProgram=Automatically start %1\nAddonHostProgramNotFound=%1 could not be located in the folder you selected.%n%nDo you want to continue anyway?\n\nFullInstallation=Full installation\nCompactInstallation=Recommended installation\nCustomInstallation=Custom installation\n\n; *** AviSynth+ custom messages\n\nCmpMain=%1 Base\nCmpDocs=Documentation\nCmpDocsEn=English\nCmpDocsCs=Czech\nCmpDocsFr=French\nCmpDocsDe=German\nCmpDocsIt=Italian\nCmpDocsJa=Japanese\nCmpDocsPl=Polish\nCmpDocsPt=Portuguese\nCmpDocsRu=Russian\nCmpDocsExamples=Scripting Examples\nCmpSdk=Filter SDK\nCmpMig=Legacy AviSynth Upgrade\nCmpMigUninstall=Uninstall and move plugins to %1\nCmpMigBackup=Backup legacy AviSynth\nCmpCustomizePluginPaths=Customize Plugin Paths\n\nFileTypeDescAvs=%1 Script\nFileTypeDescAvsi=%1 Autoload Script\n\nSelectAssoc=Select Association\nSelectAssocNotepadOpen=Associate AVS and AVSI with Notepad (open)\nSelectAssocAddShellNew=Add Avisynth Script to New items menu\nSelectAssocMplayer=Associate AVS with Windows Media Player 6.4 (play)\nSelectAssocWMplayer=Associate AVS with Windows Media Player (play)\n\nInstallStatusRuntime = Installing %1 (%2).%nThis may take up to 5 minutes... \nUninstallStatusLegacyRestore = Restoring legacy AviSynth...\nBackupRestoreFailed=An error occured while trying to restore your previous AviSynth installation:%n%1\n\nMigPageCaption=Upgrade Options\nMigPageDescription=How should %1 handle your existing AviSynth installation?\nMigPageSubCaption=Setup has detected that AviSynth is already installed in:%n%n%2%n%nAvisynth and %1 cannot be run alongside each other. However, setup can preserve your legacy AviSynth installation in case you want to downgrade later.\nMigPageOptionBackup=Keep the existing AviSynth program directory and backup its system components overwritten by %1.%n%1 will still load your existing plugins and restore your previous AviSynth installation upon uninstall.\nMigPageOptionUninstall=Uninstall AviSynth now and migrate compatible plugins to the %1 plugin directory.\nMigPageUninstallFailed=AviSynth Uninstall failed: %n%1\n \nPlugPageCaption=%1 Plugin Folders\nPlugPageDescription=Where should %1 autoload plugins from?\nPlugPageSubCaption=%1 will install bundled plugins to the its own autoload directory, but also autoload from the legacy plugin directory.\nPlugPagePlugDirPlus=%2 %1-bit plugin directory:\nPlugPagePlugDirLegacy=AviSynth %1-bit plugin directory:\n\n"
  },
  {
    "path": "distrib/WinInstaller/Translations/fr.isl",
    "content": "; *** Inno Setup version 5.5.3+ French messages ***\n;\n; To download user-contributed translations of this file, go to:\n;   http://www.jrsoftware.org/files/istrans/\n;\n; Note: When translating this text, do not add periods (.) to the end of\n; messages that didn't have them already, because on those messages Inno\n; Setup adds the periods automatically (appending a period would result in\n; two periods being displayed).\n;\n; Maintained by Pierre Yager (pierre@levosgien.net)\n;\n; Contributors : Frdric Bonduelle, Francis Pallini, Lumina, Pascal Peyrot\n;\n; Changes :\n; + Accents on uppercase letters\n;      http://www.academie-francaise.fr/langue/questions.html#accentuation (lumina)\n; + Typography quotes [see ISBN: 978-2-7433-0482-9]\n;      http://fr.wikipedia.org/wiki/Guillemet (lumina)\n; + Binary units (Kio, Mio) [IEC 80000-13:2008]\n;      http://fr.wikipedia.org/wiki/Octet (lumina)\n; + Reverted to standard units (Ko, Mo) to follow Windows Explorer Standard\n;      http://blogs.msdn.com/b/oldnewthing/archive/2009/06/11/9725386.aspx\n; + Use more standard verbs for click and retry\n;     \"click\": \"Clicker\" instead of \"Appuyer\" \n;     \"retry\": \"Recommencer\" au lieu de \"Ressayer\"\n\n[LangOptions]\n; The following three entries are very important. Be sure to read and \n; understand the '[LangOptions] section' topic in the help file.\nLanguageName=Fran<00E7>ais\nLanguageID=$040C\nLanguageCodePage=1252\n; If the language you are translating to requires special font faces or\n; sizes, uncomment any of the following entries and change them accordingly.\n;DialogFontName=\n;DialogFontSize=8\n;WelcomeFontName=Verdana\n;WelcomeFontSize=12\n;TitleFontName=Arial\n;TitleFontSize=29\n;CopyrightFontName=Arial\n;CopyrightFontSize=8\n\n[Messages]\n\n; *** Application titles\nSetupAppTitle=Installation\nSetupWindowTitle=Installation - %1\nUninstallAppTitle=Dsinstallation\nUninstallAppFullTitle=Dsinstallation - %1\n\n; *** Misc. common\nInformationTitle=Information\nConfirmTitle=Confirmation\nErrorTitle=Erreur\n\n; *** SetupLdr messages\nSetupLdrStartupMessage=Cet assistant va installer %1. Voulez-vous continuer ?\nLdrCannotCreateTemp=Impossible de crer un fichier temporaire. Abandon de l'installation\nLdrCannotExecTemp=Impossible d'excuter un fichier depuis le dossier temporaire. Abandon de l'installation\n\n; *** Startup error messages\nLastErrorMessage=%1.%n%nErreur %2 : %3\nSetupFileMissing=Le fichier %1 est absent du dossier d'installation. Veuillez corriger le problme ou vous procurer une nouvelle copie du programme.\nSetupFileCorrupt=Les fichiers d'installation sont altrs. Veuillez vous procurer une nouvelle copie du programme.\nSetupFileCorruptOrWrongVer=Les fichiers d'installation sont altrs ou ne sont pas compatibles avec cette version de l'assistant d'installation. Veuillez corriger le problme ou vous procurer une nouvelle copie du programme.\nInvalidParameter=Un paramtre non valide a t pass  la ligne de commande :%n%n%1\nSetupAlreadyRunning=L'assistant d'installation est dj en cours d'excution.\nWindowsVersionNotSupported=Ce programme n'est pas prvu pour fonctionner avec la version de Windows utilise sur votre ordinateur.\nWindowsServicePackRequired=Ce programme a besoin de %1 Service Pack %2 ou d'une version plus rcente.\nNotOnThisPlatform=Ce programme ne fonctionne pas sous %1.\nOnlyOnThisPlatform=Ce programme ne peut fonctionner que sous %1.\nOnlyOnTheseArchitectures=Ce programme ne peut tre install que sur des versions de Windows qui supportent ces architectures : %n%n%1\nMissingWOW64APIs=La version de Windows que vous utilisez ne dispose pas des fonctionnalits ncessaires pour que l'assistant puisse raliser une installation 64 bits. Pour corriger ce problme vous devez installer le Service Pack %1.\nWinVersionTooLowError=Ce programme requiert la version %2 ou suprieure de %1.\nWinVersionTooHighError=Ce programme ne peut pas tre install sous %1 version %2 ou suprieure.\nAdminPrivilegesRequired=Vous devez disposer des droits d'administration de cet ordinateur pour installer ce programme.\nPowerUserPrivilegesRequired=Vous devez disposer des droits d'administration ou faire partie du groupe  Utilisateurs avec pouvoir  de cet ordinateur pour installer ce programme.\nSetupAppRunningError=L'assistant d'installation a dtect que %1 est actuellement en cours d'excution.%n%nVeuillez fermer toutes les instances de cette application puis cliquer sur OK pour continuer, ou bien cliquer sur Annuler pour abandonner l'installation.\nUninstallAppRunningError=La procdure de dsinstallation a dtect que %1 est actuellement en cours d'excution.%n%nVeuillez fermer toutes les instances de cette application  puis cliquer sur OK pour continuer, ou bien cliquer sur Annuler pour abandonner la dsinstallation.\n\n; *** Misc. errors\nErrorCreatingDir=L'assistant d'installation n'a pas pu crer le dossier \"%1\"\nErrorTooManyFilesInDir=L'assistant d'installation n'a pas pu crer un fichier dans le dossier \"%1\" car celui-ci contient trop de fichiers\n\n; *** Setup common messages\nExitSetupTitle=Quitter l'installation\nExitSetupMessage=L'installation n'est pas termine. Si vous abandonnez maintenant, le programme ne sera pas install.%n%nVous devrez relancer cet assistant pour finir l'installation.%n%nVoulez-vous quand mme quitter l'assistant d'installation ?\nAboutSetupMenuItem=& propos...\nAboutSetupTitle= Propos de l'assistant d'installation\nAboutSetupMessage=%1 version %2%n%3%n%nPage d'accueil de %1 :%n%4\nAboutSetupNote=\nTranslatorNote=Traduction franaise maintenue par Pierre Yager (pierre@levosgien.net)\n\n; *** Buttons\nButtonBack=< &Prcdent\nButtonNext=&Suivant >\nButtonInstall=&Installer\nButtonOK=OK\nButtonCancel=Annuler\nButtonYes=&Oui\nButtonYesToAll=Oui pour &tout\nButtonNo=&Non\nButtonNoToAll=N&on pour tout\nButtonFinish=&Terminer\nButtonBrowse=Pa&rcourir...\nButtonWizardBrowse=Pa&rcourir...\nButtonNewFolder=Nouveau &dossier\n\n; *** \"Select Language\" dialog messages\nSelectLanguageTitle=Langue de l'assistant d'installation\nSelectLanguageLabel=Veuillez slectionner la langue qui sera utilise par l'assistant d'installation :\n\n; *** Common wizard text\nClickNext=Cliquez sur Suivant pour continuer ou sur Annuler pour abandonner l'installation.\nBeveledLabel=\nBrowseDialogTitle=Parcourir les dossiers\nBrowseDialogLabel=Veuillez choisir un dossier de destination, puis cliquez sur OK.\nNewFolderName=Nouveau dossier\n\n; *** \"Welcome\" wizard page\nWelcomeLabel1=Bienvenue dans l'assistant d'installation de [name]\nWelcomeLabel2=Cet assistant va vous guider dans l'installation de [name/ver] sur votre ordinateur.%n%nIl est recommand de fermer toutes les applications actives avant de continuer.\n\n; *** \"Password\" wizard page\nWizardPassword=Mot de passe\nPasswordLabel1=Cette installation est protge par un mot de passe.\nPasswordLabel3=Veuillez saisir le mot de passe (attention  la distinction entre majuscules et minuscules) puis cliquez sur Suivant pour continuer.\nPasswordEditLabel=&Mot de passe :\nIncorrectPassword=Le mot de passe saisi n'est pas valide. Veuillez essayer  nouveau.\n\n; *** \"License Agreement\" wizard page\nWizardLicense=Accord de licence\nLicenseLabel=Les informations suivantes sont importantes. Veuillez les lire avant de continuer.\nLicenseLabel3=Veuillez lire le contrat de licence suivant. Vous devez en accepter tous les termes avant de continuer l'installation.\nLicenseAccepted=Je comprends et j'&accepte les termes du contrat de licence\nLicenseNotAccepted=Je &refuse les termes du contrat de licence\n\n; *** \"Information\" wizard pages\nWizardInfoBefore=Information\nInfoBeforeLabel=Les informations suivantes sont importantes. Veuillez les lire avant de continuer.\nInfoBeforeClickLabel=Lorsque vous tes prt  continuer, cliquez sur Suivant.\nWizardInfoAfter=Information\nInfoAfterLabel=Les informations suivantes sont importantes. Veuillez les lire avant de continuer.\nInfoAfterClickLabel=Lorsque vous tes prt  continuer, cliquez sur Suivant.\n\n; *** \"User Information\" wizard page\nWizardUserInfo=Informations sur l'Utilisateur\nUserInfoDesc=Veuillez saisir les informations qui vous concernent.\nUserInfoName=&Nom d'utilisateur :\nUserInfoOrg=&Organisation :\nUserInfoSerial=Numro de &srie :\nUserInfoNameRequired=Vous devez au moins saisir un nom.\n\n; *** \"Select Destination Location\" wizard page\nWizardSelectDir=Dossier de destination\nSelectDirDesc=O [name] doit-il tre install ?\nSelectDirLabel3=L'assistant va installer [name] dans le dossier suivant.\nSelectDirBrowseLabel=Pour continuer, cliquez sur Suivant. Si vous souhaitez choisir un dossier diffrent, cliquez sur Parcourir.\nDiskSpaceMBLabel=Le programme requiert au moins [mb] Mo d'espace disque disponible.\nCannotInstallToNetworkDrive=L'assistant ne peut pas installer sur un disque rseau.\nCannotInstallToUNCPath=L'assistant ne peut pas installer sur un chemin UNC.\nInvalidPath=Vous devez saisir un chemin complet avec sa lettre de lecteur ; par exemple :%n%nC:\\APP%n%nou un chemin rseau de la forme :%n%n\\\\serveur\\partage\nInvalidDrive=L'unit ou l'emplacement rseau que vous avez slectionn n'existe pas ou n'est pas accessible. Veuillez choisir une autre destination.\nDiskSpaceWarningTitle=Espace disponible insuffisant\nDiskSpaceWarning=L'assistant a besoin d'au moins %1 Ko d'espace disponible pour effectuer l'installation, mais l'unit que vous avez slectionne ne dispose que de %2 Ko d'espace disponible.%n%nSouhaitez-vous continuer malgr tout ?\nDirNameTooLong=Le nom ou le chemin du dossier est trop long.\nInvalidDirName=Le nom du dossier est invalide.\nBadDirName32=Le nom du dossier ne doit contenir aucun des caractres suivants :%n%n%1\nDirExistsTitle=Dossier existant\nDirExists=Le dossier :%n%n%1%n%nexiste dj. Souhaitez-vous installer dans ce dossier malgr tout ?\nDirDoesntExistTitle=Le dossier n'existe pas\nDirDoesntExist=Le dossier %n%n%1%n%nn'existe pas. Souhaitez-vous que ce dossier soit cr ?\n\n; *** \"Select Components\" wizard page\nWizardSelectComponents=Composants  installer\nSelectComponentsDesc=Quels composants de l'application souhaitez-vous installer ?\nSelectComponentsLabel2=Slectionnez les composants que vous dsirez installer ; dcochez les composants que vous ne dsirez pas installer. Cliquez ensuite sur Suivant pour continuer l'installation.\nFullInstallation=Installation complte\n; if possible don't translate 'Compact' as 'Minimal' (I mean 'Minimal' in your language)\nCompactInstallation=Installation compacte\nCustomInstallation=Installation personnalise\nNoUninstallWarningTitle=Composants existants\nNoUninstallWarning=L'assistant d'installation a dtect que les composants suivants sont dj installs sur votre systme :%n%n%1%n%nDslectionner ces composants ne les dsinstallera pas pour autant.%n%nVoulez-vous continuer malgr tout ?\nComponentSize1=%1 Ko\nComponentSize2=%1 Mo\nComponentsDiskSpaceMBLabel=Les composants slectionns ncessitent au moins [mb] Mo d'espace disponible.\n\n; *** \"Select Additional Tasks\" wizard page\nWizardSelectTasks=Tches supplmentaires\nSelectTasksDesc=Quelles sont les tches supplmentaires qui doivent tre effectues ?\nSelectTasksLabel2=Slectionnez les tches supplmentaires que l'assistant d'installation doit effectuer pendant l'installation de [name], puis cliquez sur Suivant.\n\n; *** \"Select Start Menu Folder\" wizard page\nWizardSelectProgramGroup=Slection du dossier du menu Dmarrer\nSelectStartMenuFolderDesc=O l'assistant d'installation doit-il placer les raccourcis du programme ?\nSelectStartMenuFolderLabel3=L'assistant va crer les raccourcis du programme dans le dossier du menu Dmarrer indiqu ci-dessous.\nSelectStartMenuFolderBrowseLabel=Cliquez sur Suivant pour continuer. Cliquez sur Parcourir si vous souhaitez slectionner un autre dossier du menu Dmarrer.\nMustEnterGroupName=Vous devez saisir un nom de dossier du menu Dmarrer.\nGroupNameTooLong=Le nom ou le chemin du dossier est trop long.\nInvalidGroupName=Le nom du dossier n'est pas valide.\nBadGroupName=Le nom du dossier ne doit contenir aucun des caractres suivants :%n%n%1\nNoProgramGroupCheck2=Ne pas crer de &dossier dans le menu Dmarrer\n\n; *** \"Ready to Install\" wizard page\nWizardReady=Prt  installer\nReadyLabel1=L'assistant dispose  prsent de toutes les informations pour installer [name] sur votre ordinateur.\nReadyLabel2a=Cliquez sur Installer pour procder  l'installation ou sur Prcdent pour revoir ou modifier une option d'installation.\nReadyLabel2b=Cliquez sur Installer pour procder  l'installation.\nReadyMemoUserInfo=Informations sur l'utilisateur :\nReadyMemoDir=Dossier de destination :\nReadyMemoType=Type d'installation :\nReadyMemoComponents=Composants slectionns :\nReadyMemoGroup=Dossier du menu Dmarrer :\nReadyMemoTasks=Tches supplmentaires :\n\n; *** \"Preparing to Install\" wizard page\nWizardPreparing=Prparation de l'installation\nPreparingDesc=L'assistant d'installation prpare l'installation de [name] sur votre ordinateur.\nPreviousInstallNotCompleted=L'installation ou la suppression d'un programme prcdent n'est pas totalement acheve. Veuillez redmarrer votre ordinateur pour achever cette installation ou suppression.%n%nUne fois votre ordinateur redmarr, veuillez relancer cet assistant pour reprendre l'installation de [name].\nCannotContinue=L'assistant ne peut pas continuer. Veuillez cliquer sur Annuler pour abandonner l'installation.\nApplicationsFound=Les applications suivantes utilisent des fichiers qui doivent tre mis  jour par l'assistant. Il est recommand d'autoriser l'assistant  fermer ces applications automatiquement.\nApplicationsFound2=Les applications suivantes utilisent des fichiers qui doivent tre mis  jour par l'assistant. Il est recommand d'autoriser l'assistant  fermer ces applications automatiquement. Une fois l'installation termine, l'assistant essaiera de relancer ces applications.\nCloseApplications=&Arrter les applications automatiquement\nDontCloseApplications=&Ne pas arrter les applications\nErrorCloseApplications=L'assistant d'installation n'a pas pu arrter toutes les applications automatiquement. Nous vous recommandons de fermer toutes les applications qui utilisent des fichiers devant tre mis  jour par l'assistant d'installation avant de continuer.\n\n; *** \"Installing\" wizard page\nWizardInstalling=Installation en cours\nInstallingLabel=Veuillez patienter pendant que l'assistant installe [name] sur votre ordinateur.\n\n; *** \"Setup Completed\" wizard page\nFinishedHeadingLabel=Fin de l'installation de [name]\nFinishedLabelNoIcons=L'assistant a termin l'installation de [name] sur votre ordinateur.\nFinishedLabel=L'assistant a termin l'installation de [name] sur votre ordinateur. L'application peut tre lance  l'aide des icnes cres sur le Bureau par l'installation.\nClickFinish=Veuillez cliquer sur Terminer pour quitter l'assistant d'installation.\nFinishedRestartLabel=L'assistant doit redmarrer votre ordinateur pour terminer l'installation de [name].%n%nVoulez-vous redmarrer maintenant ?\nFinishedRestartMessage=L'assistant doit redmarrer votre ordinateur pour terminer l'installation de [name].%n%nVoulez-vous redmarrer maintenant ?\nShowReadmeCheck=Oui, je souhaite lire le fichier LISEZMOI\nYesRadio=&Oui, redmarrer mon ordinateur maintenant\nNoRadio=&Non, je prfre redmarrer mon ordinateur plus tard\n; used for example as 'Run MyProg.exe'\nRunEntryExec=Excuter %1\n; used for example as 'View Readme.txt'\nRunEntryShellExec=Voir %1\n\n; *** \"Setup Needs the Next Disk\" stuff\nChangeDiskTitle=L'assistant a besoin du disque suivant\nSelectDiskLabel2=Veuillez insrer le disque %1 et cliquer sur OK.%n%nSi les fichiers de ce disque se trouvent  un emplacement diffrent de celui indiqu ci-dessous, veuillez saisir le chemin correspondant ou cliquez sur Parcourir.\nPathLabel=&Chemin :\nFileNotInDir2=Le fichier \"%1\" ne peut pas tre trouv dans \"%2\". Veuillez insrer le bon disque ou slectionner un autre dossier.\nSelectDirectoryLabel=Veuillez indiquer l'emplacement du disque suivant.\n\n; *** Installation phase messages\nSetupAborted=L'installation n'est pas termine.%n%nVeuillez corriger le problme et relancer l'installation.\nEntryAbortRetryIgnore=Cliquez sur Recommencer pour essayer  nouveau, Ignorer pour continuer malgr tout, ou Abandonner pour annuler l'installation.\n\n; *** Installation status messages\nStatusClosingApplications=Ferme les applications...\nStatusCreateDirs=Cration des dossiers...\nStatusExtractFiles=Extraction des fichiers...\nStatusCreateIcons=Cration des raccourcis...\nStatusCreateIniEntries=Cration des entres du fichier INI...\nStatusCreateRegistryEntries=Cration des entres de registre...\nStatusRegisterFiles=Enregistrement des fichiers...\nStatusSavingUninstall=Sauvegarde des informations de dsinstallation...\nStatusRunProgram=Finalisation de l'installation...\nStatusRestartingApplications=Relance les applications...\nStatusRollback=Annulation des modifications...\n\n; *** Misc. errors\nErrorInternal2=Erreur interne : %1\nErrorFunctionFailedNoCode=%1 a chou\nErrorFunctionFailed=%1 a chou ; code %2\nErrorFunctionFailedWithMessage=%1 a chou ; code %2.%n%3\nErrorExecutingProgram=Impossible d'excuter le fichier :%n%1\n\n; *** Registry errors\nErrorRegOpenKey=Erreur lors de l'ouverture de la cl de registre :%n%1\\%2\nErrorRegCreateKey=Erreur lors de la cration de la cl de registre :%n%1\\%2\nErrorRegWriteKey=Erreur lors de l'criture de la cl de registre :%n%1\\%2\n\n; *** INI errors\nErrorIniEntry=Erreur d'criture d'une entre dans le fichier INI \"%1\".\n\n; *** File copying errors\nFileAbortRetryIgnore=Cliquez sur Recommencer pour essayer  nouveau, Ignorer pour passer ce fichier (dconseill), ou Abandonner pour annuler l'installation.\nFileAbortRetryIgnore2=Cliquez sur Recommencer pour essayer  nouveau, Ignorer pour continuer malgr tout (dconseill), ou Abandonner pour annuler l'installation.\nSourceIsCorrupted=Le fichier source est altr\nSourceDoesntExist=Le fichier source \"%1\" n'existe pas\nExistingFileReadOnly=Le fichier existant est protg en lecture seule.%n%nCliquez sur Recommencer pour enlever la protection et essayer  nouveau, Ignorer pour passer ce fichier, ou Abandonner pour annuler l'installation.\nErrorReadingExistingDest=Une erreur s'est produite lors de la tentative de lecture du fichier existant :\nFileExists=Le fichier existe dj.%n%nSouhaitez-vous que l'installation le remplace ?\nExistingFileNewer=Le fichier existant est plus rcent que celui que l'assistant essaie d'installer. Il est recommand de conserver le fichier existant.%n%nSouhaitez-vous conserver le fichier existant ?\nErrorChangingAttr=Une erreur est survenue en essayant de modifier les attributs du fichier existant :\nErrorCreatingTemp=Une erreur est survenue en essayant de crer un fichier dans le dossier de destination :\nErrorReadingSource=Une erreur est survenue lors de la lecture du fichier source :\nErrorCopying=Une erreur est survenue lors de la copie d'un fichier :\nErrorReplacingExistingFile=Une erreur est survenue lors du remplacement d'un fichier existant :\nErrorRestartReplace=Le marquage d'un fichier pour remplacement au redmarrage de l'ordinateur a chou :\nErrorRenamingTemp=Une erreur est survenue en essayant de renommer un fichier dans le dossier de destination :\nErrorRegisterServer=Impossible d'enregistrer la bibliothque DLL/OCX : %1\nErrorRegSvr32Failed=RegSvr32 a chou et a retourn le code d'erreur %1\nErrorRegisterTypeLib=Impossible d'enregistrer la bibliothque de type : %1\n\n; *** Post-installation errors\nErrorOpeningReadme=Une erreur est survenue  l'ouverture du fichier LISEZMOI.\nErrorRestartingComputer=L'installation n'a pas pu redmarrer l'ordinateur. Merci de bien vouloir le faire vous-mme.\n\n; *** Uninstaller messages\nUninstallNotFound=Le fichier \"%1\" n'existe pas. Impossible de dsinstaller.\nUninstallOpenError=Le fichier \"%1\" n'a pas pu tre ouvert. Impossible de dsinstaller\nUninstallUnsupportedVer=Le format du fichier journal de dsinstallation \"%1\" n'est pas reconnu par cette version de la procdure de dsinstallation. Impossible de dsinstaller\nUninstallUnknownEntry=Une entre inconnue (%1) a t rencontre dans le fichier journal de dsinstallation\nConfirmUninstall=Voulez-vous vraiment dsinstaller compltement %1 ainsi que tous ses composants ?\nUninstallOnlyOnWin64=La dsinstallation de ce programme ne fonctionne qu'avec une version 64 bits de Windows.\nOnlyAdminCanUninstall=Ce programme ne peut tre dsinstall que par un utilisateur disposant des droits d'administration.\nUninstallStatusLabel=Veuillez patienter pendant que %1 est retir de votre ordinateur.\nUninstalledAll=%1 a t correctement dsinstall de cet ordinateur.\nUninstalledMost=La dsinstallation de %1 est termine.%n%nCertains lments n'ont pas pu tre supprims automatiquement. Vous pouvez les supprimer manuellement.\nUninstalledAndNeedsRestart=Vous devez redmarrer l'ordinateur pour terminer la dsinstallation de %1.%n%nVoulez-vous redmarrer maintenant ?\nUninstallDataCorrupted=Le ficher \"%1\" est altr. Impossible de dsinstaller\n\n; *** Uninstallation phase messages\nConfirmDeleteSharedFileTitle=Supprimer les fichiers partags ?\nConfirmDeleteSharedFile2=Le systme indique que le fichier partag suivant n'est plus utilis par aucun programme. Souhaitez-vous que la dsinstallation supprime ce fichier partag ?%n%nSi des programmes utilisent encore ce fichier et qu'il est supprim, ces programmes ne pourront plus fonctionner correctement. Si vous n'tes pas sr, choisissez Non. Laisser ce fichier dans votre systme ne posera pas de problme.\nSharedFileNameLabel=Nom du fichier :\nSharedFileLocationLabel=Emplacement :\nWizardUninstalling=tat de la dsinstallation\nStatusUninstalling=Dsinstallation de %1...\n\n; *** Shutdown block reasons\nShutdownBlockReasonInstallingApp=Installe %1.\nShutdownBlockReasonUninstallingApp=Dsinstalle %1.\n\n; Les messages personnaliss suivants ne sont pas utilis par l'installation\n; elle-mme, mais si vous les utilisez dans vos scripts, vous devez les\n; traduire\n\n[CustomMessages]\n\nNameAndVersion=%1 version %2\nAdditionalIcons=Icnes supplmentaires :\nCreateDesktopIcon=Crer une icne sur le &Bureau\nCreateQuickLaunchIcon=Crer une icne dans la barre de &Lancement rapide\nProgramOnTheWeb=Page d'accueil de %1\nUninstallProgram=Dsinstaller %1\nLaunchProgram=Excuter %1\nAssocFileExtension=&Associer %1 avec l'extension de fichier %2\nAssocingFileExtension=Associe %1 avec l'extension de fichier %2...\nAutoStartProgramGroupDescription=Dmarrage :\nAutoStartProgram=Dmarrer automatiquement %1\nAddonHostProgramNotFound=%1 n'a pas t trouv dans le dossier que vous avez choisi.%n%nVoulez-vous continuer malgr tout ?\n\n; *** AviSynth+ custom messages\n\nFullInstallation=Installation complte\n;CompactInstallation=Recommended installation\nCustomInstallation=Installation personnalise\n\nCmpMain=%1 Base\nCmpDocs=Documentation\nCmpDocsEn=Anglais\nCmpDocsCs=Tchque\nCmpDocsFr=Franais\nCmpDocsDe=Allemand\nCmpDocsIt=Italien\nCmpDocsJa=Japonais\nCmpDocsPl=Polonais\nCmpDocsPt=Portugais\nCmpDocsRu=Russe\n;CmpDocsExamples=Scripting Examples\nCmpSdk=FilterSDK (pour le dveloppement de plugins %1)\n;CmpMig=Legacy AviSynth Upgrade\n;CmpMigUninstall=Uninstall and move plugins to %1\n;CmpMigBackup=Backup legacy AviSynth\n;CmpCustomizePluginPaths=Customize Plugin Paths\n\n;FileTypeDescAvs=%1 Script\n;FileTypeDescAvsi=%1 Autoload Script\n\n;InstallStatusRuntime = Installing %1 (%2).%nThis may take up to 5 minutes... \n;UninstallStatusLegacyRestore = Restoring legacy AviSynth...\n;BackupRestoreFailed=An error occured while trying to restore your previous AviSynth installation:%n%1\n\n;MigPageCaption=Upgrade Options\n;MigPageDescription=How should %1 handle your existing AviSynth installation?\n;MigPageSubCaption=Setup has detected that AviSynth is already installed in:%n%n%2%n%nAvisynth and %1 cannot be run alongside each other. However, setup can preserve your legacy AviSynth installation in case you want to downgrade later.\n;MigPageOptionBackup=Keep the existing AviSynth program directory and backup its system components overwritten by %1.%n%1 will still load your existing plugins and restore your previous AviSynth installation upon uninstall.\n;MigPageOptionUninstall=Uninstall AviSynth now and migrate compatible plugins to the %1 plugin directory.\n;MigPageUninstallFailed=AviSynth Uninstall failed: %n%1\n \n;PlugPageCaption=%1 Plugin Folders\n;PlugPageDescription=Where should %1 autoload plugins from?\n;PlugPageSubCaption=%1 will install bundled plugins to the its own autoload directory, but also autoload from the legacy plugin directory.\n;PlugPagePlugDirPlus=%2 %1-bit plugin directory:\n;PlugPagePlugDirLegacy=AviSynth %1-bit plugin directory:"
  },
  {
    "path": "distrib/WinInstaller/Translations/it.isl",
    "content": "; *** Inno Setup version 5.5.3+ Italian messages ***\n;\n; To download user-contributed translations of this file, go to:\n;   http://www.jrsoftware.org/files/istrans/\n;\n; Note: When translating this text, do not add periods (.) to the end of\n; messages that didn't have them already, because on those messages Inno\n; Setup adds the periods automatically (appending a period would result in\n; two periods being displayed).\n;\n; Italian.isl - Last Update December 15, 2012  (based on ale5000 5.1.11+ translation)\n;\n; Translator name: Rinaldo M. aka Whiteshark\n; Translator e-mail: dad428(X)hotmail.com   (replace (X) with @ )\n;\n[LangOptions]\n; The following three entries are very important. Be sure to read and \n; understand the '[LangOptions] section' topic in the help file.\nLanguageName=Italiano\nLanguageID=$0410\nLanguageCodePage=1252\n; If the language you are translating to requires special font faces or\n; sizes, uncomment any of the following entries and change them accordingly.\n;DialogFontName=\n;DialogFontSize=8\n;WelcomeFontName=Verdana\n;WelcomeFontSize=12\n;TitleFontName=Arial\n;TitleFontSize=29\n;CopyrightFontName=Arial\n;CopyrightFontSize=8\n\n[Messages]\n\n; *** Application titles\nSetupAppTitle=Installazione\nSetupWindowTitle=Installazione di %1\nUninstallAppTitle=Disinstallazione\nUninstallAppFullTitle=Disinstallazione di %1\n\n; *** Misc. common\nInformationTitle=Informazioni\nConfirmTitle=Conferma\nErrorTitle=Errore\n\n; *** SetupLdr messages\nSetupLdrStartupMessage=Questa  l'installazione di %1. Si desidera continuare?\nLdrCannotCreateTemp=Impossibile creare un file temporaneo. Installazione annullata\nLdrCannotExecTemp=Impossibile eseguire un file nella cartella temporanea. Installazione annullata\n\n; *** Startup error messages\nLastErrorMessage=%1.%n%nErrore %2: %3\nSetupFileMissing=File %1 non trovato nella cartella di installazione. Correggere il problema o richiedere una nuova copia del software.\nSetupFileCorrupt=I file di installazione sono danneggiati. Richiedere una nuova copia del software.\nSetupFileCorruptOrWrongVer=I file di installazione sono danneggiati, o sono incompatibili con questa versione del programma di installazione. Correggere il problema o richiedere una nuova copia del software.\nInvalidParameter=Un parametro non valido  stato immesso sulla riga di comando:%n%n%1\nSetupAlreadyRunning=Il processo di installazione  gi in funzione.\nWindowsVersionNotSupported=Questo programma non supporta la versione di Windows installata sul computer.\nWindowsServicePackRequired=Questo programma richiede %1 Service Pack %2 o successivo.\nNotOnThisPlatform=Questo programma non  compatibile con %1.\nOnlyOnThisPlatform=Questo programma richiede %1.\nOnlyOnTheseArchitectures=Questo programma pu essere installato solo su versioni di Windows progettate per le seguenti architetture del processore:%n%n%1\nMissingWOW64APIs=La versione di Windows utilizzata non include la funzionalit richiesta dal programma di installazione per realizzare un'installazione a 64-bit. Per correggere questo problema, installare il Service Pack %1.\nWinVersionTooLowError=Questo programma richiede %1 versione %2 o successiva.\nWinVersionTooHighError=Questo programma non pu essere installato su %1 versione %2 o successiva.\nAdminPrivilegesRequired=Sono richiesti privilegi di amministratore per installare questo programma.\nPowerUserPrivilegesRequired=Sono richiesti privilegi di amministratore o di Power Users per poter installare questo programma.\nSetupAppRunningError=%1  attualmente in esecuzione.%n%nChiudere adesso tutte le istanze del programma e poi premere OK, oppure premere Annulla per uscire.\nUninstallAppRunningError=%1  attualmente in esecuzione.%n%nChiudere adesso tutte le istanze del programma e poi premere OK, oppure premere Annulla per uscire.\n\n; *** Misc. errors\nErrorCreatingDir=Impossibile creare la cartella \"%1\"\nErrorTooManyFilesInDir=Impossibile creare i file nella cartella \"%1\" perch contiene troppi file\n\n; *** Setup common messages\nExitSetupTitle=Uscita dall'installazione\nExitSetupMessage=L'installazione non  completa. Uscendo dall'installazione in questo momento, il programma non sar installato.%n%n possibile eseguire l'installazione in un secondo tempo.%n%nUscire dall'installazione?\nAboutSetupMenuItem=&Informazioni sull'installazione...\nAboutSetupTitle=Informazioni sull'installazione\nAboutSetupMessage=%1 versione %2%n%3%n%n%1 sito web:%n%4\nAboutSetupNote=\nTranslatorNote=Traduzione italiana a cura di Rinaldo M. aka Whiteshark\n\n; *** Buttons\nButtonBack=< &Indietro\nButtonNext=&Avanti >\nButtonInstall=Inst&alla\nButtonOK=OK\nButtonCancel=Annulla\nButtonYes=&Si\nButtonYesToAll=Si a &tutto\nButtonNo=&No\nButtonNoToAll=N&o a tutto\nButtonFinish=&Fine\nButtonBrowse=&Sfoglia...\nButtonWizardBrowse=S&foglia...\nButtonNewFolder=&Crea nuova cartella\n\n; *** \"Select Language\" dialog messages\nSelectLanguageTitle=Selezionare la lingua dell'installazione\nSelectLanguageLabel=Selezionare la lingua da utilizzare durante l'installazione:\n\n; *** Common wizard text\nClickNext=Premere Avanti per continuare, o Annulla per uscire.\nBeveledLabel=\nBrowseDialogTitle=Sfoglia per cartelle\nBrowseDialogLabel=Selezionare una cartella dalla lista, poi premere OK.\nNewFolderName=Nuova cartella\n\n; *** \"Welcome\" wizard page\nWelcomeLabel1=Benvenuti nel programma di installazione di [name]\nWelcomeLabel2=[name/ver] sar installato sul computer.%n%nSi consiglia di chiudere tutte le applicazioni attive prima di procedere.\n\n; *** \"Password\" wizard page\nWizardPassword=Password\nPasswordLabel1=Questa installazione  protetta da password.\nPasswordLabel3=Inserire la password, poi premere Avanti per continuare. Le password sono sensibili alle maiuscole/minuscole.\nPasswordEditLabel=&Password:\nIncorrectPassword=La password inserita non  corretta, riprovare.\n\n; *** \"License Agreement\" wizard page\nWizardLicense=Contratto di licenza\nLicenseLabel=Leggere con attenzione le informazioni che seguono prima di procedere.\nLicenseLabel3=Leggere il seguente contratto di licenza.  necessario accettare tutti i termini del contratto per procedere con l'installazione.\nLicenseAccepted=Accetto i termini del &contratto di licenza \nLicenseNotAccepted=&Non accetto i termini del contratto di licenza\n\n; *** \"Information\" wizard pages\nWizardInfoBefore=Informazioni\nInfoBeforeLabel=Leggere le importanti informazioni che seguono prima di procedere.\nInfoBeforeClickLabel=Quando si  pronti per proseguire, premere Avanti.\nWizardInfoAfter=Informazioni\nInfoAfterLabel=Leggere le importanti informazioni che seguono prima di procedere.\nInfoAfterClickLabel=Quando si  pronti per proseguire, premere Avanti.\n\n; *** \"User Information\" wizard page\nWizardUserInfo=Informazioni utente\nUserInfoDesc=Inserire le seguenti informazioni.\nUserInfoName=&Nome:\nUserInfoOrg=&Societ:\nUserInfoSerial=&Numero di serie:\nUserInfoNameRequired= necessario inserire un nome.\n\n; *** \"Select Destination Location\" wizard page\nWizardSelectDir=Selezione della cartella di installazione\nSelectDirDesc=Dove si vuole installare [name]?\nSelectDirLabel3=[name] sar installato nella seguente cartella.\nSelectDirBrowseLabel=Per continuare, premere Avanti. Per scegliere un'altra cartella, premere Sfoglia.\nDiskSpaceMBLabel=Sono richiesti almeno [mb] MB di spazio sul disco.\nCannotInstallToNetworkDrive=Non  possibile effettuare l'installazione su un drive in rete.\nCannotInstallToUNCPath=Non  possibile effettuare l'installazione su un percorso UNC.\nInvalidPath=Si deve inserire un percorso completo di lettera di unit; per esempio:%n%nC:\\APP%n%no un percorso di rete nella forma:%n%n\\\\server\\condivisione\nInvalidDrive=L'unit o il percorso di rete selezionato non esiste o non  accessibile. Selezionarne un'altro.\nDiskSpaceWarningTitle=Spazio su disco insufficiente\nDiskSpaceWarning=L'installazione richiede almeno %1 KB di spazio libero per eseguire l'installazione, ma l'unit selezionata ha solo %2 KB disponibili.%n%nSi desidera continuare comunque?\nDirNameTooLong=Il nome della cartella o il percorso sono troppo lunghi.\nInvalidDirName=Il nome della cartella non  valido.\nBadDirName32=Il nome della cartella non pu includere nessuno dei caratteri seguenti:%n%n%1\nDirExistsTitle=Cartella gi esistente\nDirExists=La cartella:%n%n%1 esiste gi.%n%nSi desidera utilizzarla comunque?\nDirDoesntExistTitle=Cartella inesistente\nDirDoesntExist=La cartella:%n%n%1 non esiste.%n%nSi desidera crearla?\n\n; *** \"Select Components\" wizard page\nWizardSelectComponents=Selezione componenti\nSelectComponentsDesc=Quali componenti devono essere installati?\nSelectComponentsLabel2=Selezionare i componenti da installare, deselezionare quelli che non si desidera installare. Premere Avanti per continuare.\nFullInstallation=Installazione completa\n; if possible don't translate 'Compact' as 'Minimal' (I mean 'Minimal' in your language)\nCompactInstallation=Installazione compatta\nCustomInstallation=Installazione personalizzata\nNoUninstallWarningTitle=Componente esistente\nNoUninstallWarning=I seguenti componenti sono gi installati sul computer:%n%n%1%n%nDeselezionando questi componenti essi non verranno rimossi.%n%nSi desidera continuare comunque?\nComponentSize1=%1 KB\nComponentSize2=%1 MB\nComponentsDiskSpaceMBLabel=La selezione corrente richiede almeno [mb] MB di spazio su disco.\n\n; *** \"Select Additional Tasks\" wizard page\nWizardSelectTasks=Selezione processi addizionali\nSelectTasksDesc=Quali processi aggiuntivi si vogliono avviare?\nSelectTasksLabel2=Selezionare i processi aggiuntivi che verranno eseguiti durante l'installazione di [name], poi premere Avanti.\n\n; *** \"Select Start Menu Folder\" wizard page\nWizardSelectProgramGroup=Selezione della cartella nel Menu Avvio/Start\nSelectStartMenuFolderDesc=Dove si vuole inserire i collegamenti al programma?\nSelectStartMenuFolderLabel3=Saranno creati i collegamenti al programma nella seguente cartella del Menu Avvio/Start.\nSelectStartMenuFolderBrowseLabel=Per continuare, premere Avanti. Per selezionare un'altra cartella, premere Sfoglia.\nMustEnterGroupName=Si deve inserire il nome della cartella.\nGroupNameTooLong=Il nome della cartella o il percorso sono troppo lunghi.\nInvalidGroupName=Il nome della cartella non  valido.\nBadGroupName=Il nome della cartella non pu includere nessuno dei caratteri seguenti:%n%n%1\nNoProgramGroupCheck2=&Non creare una cartella nel Menu Avvio/Start\n\n; *** \"Ready to Install\" wizard page\nWizardReady=Pronto per l'installazione\nReadyLabel1=Il programma di installazione  pronto per iniziare l'installazione di [name] sul computer.\nReadyLabel2a=Premere Installa per continuare con l'installazione, o Indietro per rivedere o modificare le impostazioni.\nReadyLabel2b=Premere Installa per procedere con l'installazione.\nReadyMemoUserInfo=Informazioni utente:\nReadyMemoDir=Cartella di installazione:\nReadyMemoType=Tipo di installazione:\nReadyMemoComponents=Componenti selezionati:\nReadyMemoGroup=Cartella del menu Avvio/Start:\nReadyMemoTasks=Processi addizionali:\n\n; *** \"Preparing to Install\" wizard page\nWizardPreparing=Preparazione all'installazione\nPreparingDesc=Preparazione all'installazione di [name] sul computer.\nPreviousInstallNotCompleted=L'installazione/rimozione precedente del programma non  stata completata.  necessario riavviare il sistema per completare l'installazione.%n%nDopo il riavvio del sistema eseguire di nuovo l'installazione di [name].\nCannotContinue=L'installazione non pu continuare. Premere Annulla per uscire.\nApplicationsFound=Le seguenti applicazioni stanno usando file che devono essere aggiornati dall'installazione. Si consiglia di permettere al processo di chiudere automaticamente queste applicazioni.\nApplicationsFound2=Le seguenti applicazioni stanno usando file che devono essere aggiornati dall'installazione. Si consiglia di permettere al processo di chiudere automaticamente queste applicazioni. Al completamento dell'installazione, il processo tenter di riavviare le applicazioni.\nCloseApplications=Chiudi &automaticamente le applicazioni\nDontCloseApplications=&Non chiudere le applicazioni\nErrorCloseApplications=L'installazione non  riuscita a chiudere automaticamente tutte le applicazioni.Si raccomanda di chiuderetutte le applicazioni che usano file che devono essere aggiornatidurante l'installazione prima di proseguire.\n\n; *** \"Installing\" wizard page\nWizardInstalling=Installazione in corso\nInstallingLabel=Attendere il completamento dell'installazione di [name] sul computer.\n\n; *** \"Setup Completed\" wizard page\nFinishedHeadingLabel=Completamento dell'installazione di [name]\nFinishedLabelNoIcons=L'installazione di [name]  stata completata con successo.\nFinishedLabel=L'installazione di [name]  stata completata con successo. L'applicazione pu essere eseguita selezionando le relative icone.\nClickFinish=Premere Fine per uscire dall'installazione.\nFinishedRestartLabel=Per completare l'installazione di [name],  necessario riavviare il sistema. Si desidera riavviare adesso?\nFinishedRestartMessage=Per completare l'installazione di [name],  necessario riavviare il sistema.%n%nSi desidera riavviare adesso?\nShowReadmeCheck=Si, desidero vedere il file LEGGIMI adesso\nYesRadio=&Si, riavvia il sistema adesso\nNoRadio=&No, riavvia il sistema pi tardi\n; used for example as 'Run MyProg.exe'\nRunEntryExec=Avvia %1\n; used for example as 'View Readme.txt'\nRunEntryShellExec=Visualizza %1\n\n; *** \"Setup Needs the Next Disk\" stuff\nChangeDiskTitle=L'installazione necessita del disco successivo\nSelectDiskLabel2=Inserire il disco %1 e premere OK.%n%nSe i file su questo disco si trovano in una cartella diversa da quella visualizzata sotto, inserire il percorso corretto o premere Sfoglia.\nPathLabel=&Percorso:\nFileNotInDir2=Il file \"%1\" non  stato trovato in \"%2\". Inserire il disco corretto o selezionare un'altra cartella.\nSelectDirectoryLabel=Specificare il percorso del prossimo disco.\n\n; *** Installation phase messages\nSetupAborted=L'installazione non  stata completata.%n%nCorreggere il problema e rieseguire nuovamente l'installazione.\nEntryAbortRetryIgnore=Premere Riprova per ritentare nuovamente, Ignora per procedere in ogni caso, o Interrompi per terminare l'installazione.\n\n; *** Installation status messages\nStatusClosingApplications=Chiusura applicazioni...\nStatusCreateDirs=Creazione cartelle...\nStatusExtractFiles=Estrazione file...\nStatusCreateIcons=Creazione icone...\nStatusCreateIniEntries=Creazione voci nei file INI...\nStatusCreateRegistryEntries=Creazione voci di registro...\nStatusRegisterFiles=Registrazione file...\nStatusSavingUninstall=Salvataggio delle informazioni di disinstallazione...\nStatusRunProgram=Termine dell'installazione...\nStatusRestartingApplications=Riavvio applicazioni...\nStatusRollback=Recupero delle modifiche...\n\n; *** Misc. errors\nErrorInternal2=Errore Interno %1\nErrorFunctionFailedNoCode=%1 fallito\nErrorFunctionFailed=%1 fallito; codice %2\nErrorFunctionFailedWithMessage=%1 fallito; codice %2.%n%3\nErrorExecutingProgram=Impossibile eseguire il file:%n%1\n\n; *** Registry errors\nErrorRegOpenKey=Errore di apertura della chiave di registro:%n%1\\%2\nErrorRegCreateKey=Errore di creazione della chiave di registro:%n%1\\%2\nErrorRegWriteKey=Errore di scrittura della chiave di registro:%n%1\\%2\n\n; *** INI errors\nErrorIniEntry=Errore nella creazione delle voci INI nel file \"%1\".\n\n; *** File copying errors\nFileAbortRetryIgnore=Premere Riprova per tentare di nuovo, Ignora per saltare questo file (sconsigliato), o Interrompi per terminare l'installazione.\nFileAbortRetryIgnore2=Premere Riprova per tentare di nuovo, Ignora per proseguire comunque (sconsigliato), o Interrompi per terminare l'installazione.\nSourceIsCorrupted=Il file sorgente  danneggiato\nSourceDoesntExist=Il file sorgente \"%1\" non esiste\nExistingFileReadOnly=Il file esistente ha l'attributo di sola lettura.%n%nPremere Riprova per rimuovere l'attributo di sola lettura e ritentare, Ignora per saltare questo file, o Interrompi per terminare l'installazione.\nErrorReadingExistingDest=Si  verificato un errore durante la lettura del file esistente:\nFileExists=Il file esiste gi.%n%nDesideri sovrascriverlo?\nExistingFileNewer=Il file esistente  pi recente di quello che si st installando. Si raccomanda di mantenere il file esistente.%n%nSi desidera mantenere il file esistente?\nErrorChangingAttr=Si  verificato un errore durante il tentativo di modifica dell'attributo del file esistente:\nErrorCreatingTemp=Si  verificato un errore durante la creazione di un file nella cartella di installazione:\nErrorReadingSource=Si  verificato un errore durante la lettura del file sorgente:\nErrorCopying=Si  verificato un errore durante la copia di un file:\nErrorReplacingExistingFile=Si  verificato un errore durante la sovrascrittura del file esistente:\nErrorRestartReplace=Errore durante Riavvio-Sostituzione:\nErrorRenamingTemp=Si  verificato un errore durante il tentativo di rinominare un file nella cartella di installazione:\nErrorRegisterServer=Impossibile registrare la DLL/OCX: %1\nErrorRegSvr32Failed=RegSvr32  fallito con codice di uscita %1\nErrorRegisterTypeLib=Impossibile registrare la libreria di tipo: %1\n\n; *** Post-installation errors\nErrorOpeningReadme=Si  verificato un errore durante l'apertura del file LEGGIMI.\nErrorRestartingComputer=Impossibile riavviare il sistema. Riavviare manualmente.\n\n; *** Uninstaller messages\nUninstallNotFound=Il file \"%1\" non esiste. Impossibile disinstallare.\nUninstallOpenError=Il file \"%1\" non pu essere aperto. Impossibile disinstallare\nUninstallUnsupportedVer=Il file log di disinstallazione \"%1\"  in un formato non riconosciuto da questa versione del programma di disinstallazione. Impossibile disinstallare\nUninstallUnknownEntry=Trovata una voce sconosciuta (%1) nel file log di disinstallazione\nConfirmUninstall=Si desidera rimuovere completamente %1 e tutti i suoi componenti?\nUninstallOnlyOnWin64=Questa applicazione pu essere disinstallata solo su Windows a 64-bit.\nOnlyAdminCanUninstall=Questa applicazione pu essere disinstallata solo da un utente con privilegi di amministratore.\nUninstallStatusLabel=Attendere fino a che %1  stato rimosso dal computer.\nUninstalledAll=%1  stato rimosso con successo dal computer.\nUninstalledMost=Disinstallazione di %1 completata.%n%nAlcuni elementi non possono essere rimossi. Dovranno essere rimossi manualmente.\nUninstalledAndNeedsRestart=Per completare la disinstallazione di %1,  necessario riavviare il sistema.%n%nSi desidera riavviare adesso?\nUninstallDataCorrupted=Il file \"%1\"  danneggiato. Impossibile disinstallare\n\n; *** Uninstallation phase messages\nConfirmDeleteSharedFileTitle=Rimuovere il file condiviso?\nConfirmDeleteSharedFile2=Il sistema indica che il seguente file condiviso non  pi usato da nessun programma. Rimuovere questo file condiviso?%n%nSe qualche programma usasse questo file, potrebbe non funzionare pi correttamente. Se non si  sicuri, scegliere No. Lasciare il file nel sistema non pu causare danni.\nSharedFileNameLabel=Nome del file:\nSharedFileLocationLabel=Percorso:\nWizardUninstalling=Stato della disinstallazione\nStatusUninstalling=Disinstallazione di %1 in corso...\n\n; *** Shutdown block reasons\nShutdownBlockReasonInstallingApp=Installazione di %1.\nShutdownBlockReasonUninstallingApp=Disinstallazione di %1.\n\n; The custom messages below aren't used by Setup itself, but if you make\n; use of them in your scripts, you'll want to translate them.\n\n[CustomMessages]\n\nNameAndVersion=%1 versione %2\nAdditionalIcons=Icone aggiuntive:\nCreateDesktopIcon=Crea un'icona sul &desktop\nCreateQuickLaunchIcon=Crea un'icona nella &barra Avvio veloce\nProgramOnTheWeb=%1 sul Web\nUninstallProgram=Disinstalla %1\nLaunchProgram=Avvia %1\nAssocFileExtension=&Associa l'estensione %2 a %1\nAssocingFileExtension=Associazione dell'estensione %2 a %1 in corso...\nAutoStartProgramGroupDescription=Avvio automatico:\nAutoStartProgram=Avvia automaticamente %1\nAddonHostProgramNotFound=Impossibile individuare %1 nella cartella selezionata.%n%nProseguire ugualmente?\n\n; *** AviSynth+ custom messages\n\nFullInstallation=Installazione completa\n;CompactInstallation=Recommended installation\nCustomInstallation=Installazione personalizzata\n\nCmpMain=%1 Base\nCmpDocs=Documentazione\nCmpDocsEn=Inglese\nCmpDocsCs=Ceco\nCmpDocsFr=Francese\nCmpDocsDe=Tedesco\nCmpDocsIt=Italiano\nCmpDocsJa=Giapponese\nCmpDocsPl=Polacco\nCmpDocsPt=Portoghese\nCmpDocsRu=Russo\n;CmpDocsExamples=Scripting Examples\nCmpSdk=FilterSDK\n;CmpMig=Legacy AviSynth Upgrade\n;CmpMigUninstall=Uninstall and move plugins to %1\n;CmpMigBackup=Backup legacy AviSynth\n;CmpCustomizePluginPaths=Customize Plugin Paths\n\n;FileTypeDescAvs=%1 Script\n;FileTypeDescAvsi=%1 Autoload Script\n\n;InstallStatusRuntime = Installing %1 (%2).%nThis may take up to 5 minutes... \n;UninstallStatusLegacyRestore = Restoring legacy AviSynth...\n;BackupRestoreFailed=An error occured while trying to restore your previous AviSynth installation:%n%1\n\n;MigPageCaption=Upgrade Options\n;MigPageDescription=How should %1 handle your existing AviSynth installation?\n;MigPageSubCaption=Setup has detected that AviSynth is already installed in:%n%n%2%n%nAvisynth and %1 cannot be run alongside each other. However, setup can preserve your legacy AviSynth installation in case you want to downgrade later.\n;MigPageOptionBackup=Keep the existing AviSynth program directory and backup its system components overwritten by %1.%n%1 will still load your existing plugins and restore your previous AviSynth installation upon uninstall.\n;MigPageOptionUninstall=Uninstall AviSynth now and migrate compatible plugins to the %1 plugin directory.\n;MigPageUninstallFailed=AviSynth Uninstall failed: %n%1\n \n;PlugPageCaption=%1 Plugin Folders\n;PlugPageDescription=Where should %1 autoload plugins from?\n;PlugPageSubCaption=%1 will install bundled plugins to the its own autoload directory, but also autoload from the legacy plugin directory.\n;PlugPagePlugDirPlus=%2 %1-bit plugin directory:\n;PlugPagePlugDirLegacy=AviSynth %1-bit plugin directory:"
  },
  {
    "path": "distrib/WinInstaller/Translations/ja.isl",
    "content": "; *** Inno Setup version 5.5.3+ Japanese messages ***\n;\n; Maintained by Koichi Shirasuka (shirasuka@eugrid.co.jp)\n;\n; Translation based on Ryou Minakami (ryou32jp@yahoo.co.jp)\n;\n; $jrsoftware: issrc/Files/Languages/Japanese.isl,v 1.6 2010/03/08 07:50:01 mlaan Exp $\n\n[LangOptions]\nLanguageName=<65E5><672C><8A9E>\nLanguageID=$0411\nLanguageCodePage=65001\n\n[Messages]\n\n; *** Application titles\nSetupAppTitle=セットアップ\nSetupWindowTitle=%1 セットアップ\nUninstallAppTitle=アンインストール\nUninstallAppFullTitle=%1 アンインストール\n\n; *** Misc. common\nInformationTitle=情報\nConfirmTitle=確認\nErrorTitle=エラー\n\n; *** SetupLdr messages\nSetupLdrStartupMessage=%1 をインストールします。続行しますか？\nLdrCannotCreateTemp=一時ファイルを作成できません。セットアップを中止します。\nLdrCannotExecTemp=一時フォルダのファイルを実行できません。セットアップを中止します。\n\n; *** Startup error messages\nLastErrorMessage=%1.%n%nエラー %2: %3\nSetupFileMissing=ファイル %1 が見つかりません。問題を解決するか新しいセットアッププログラムを入手してください。\nSetupFileCorrupt=セットアップファイルが壊れています。新しいセットアッププログラムを入手してください。\nSetupFileCorruptOrWrongVer=セットアップファイルが壊れているか、このバージョンのセットアップと互換性がありません。問題を解決するか新しいセットアッププログラムを入手してください。\nInvalidParameter=コマンドラインに不正なパラメーターが渡されました:%n%n%1\nSetupAlreadyRunning=セットアップは既に実行中です。\nWindowsVersionNotSupported=このプログラムはお使いのバージョンの Windows をサポートしていません。\nWindowsServicePackRequired=このプログラムの実行には %1 Service Pack %2 以降が必要です。\nNotOnThisPlatform=このプログラムは %1 では動作しません。\nOnlyOnThisPlatform=このプログラムの実行には %1 が必要です。\nOnlyOnTheseArchitectures=このプログラムは%n%n%1プロセッサー向けの Windows にしかインストールできません。\nMissingWOW64APIs=ご使用中の 64-bit 版 Windows にはこのプログラムをインストールし、動作させる為に必要な機能が含まれていません。この問題を修正する為にはサービスパック %1 をインストールしてください。\nWinVersionTooLowError=このプログラムの実行には %1 %2 以降が必要です。\nWinVersionTooHighError=このプログラムは %1 %2 以降では動作しません。\nAdminPrivilegesRequired=このプログラムをインストールするためには管理者としてログインする必要があります。\nPowerUserPrivilegesRequired=このプログラムをインストールするためには管理者またはパワーユーザーとしてログインする必要があります。\nSetupAppRunningError=セットアップは実行中の %1 を検出しました。%n%n開いているアプリケーションをすべて閉じてから「OK」をクリックしてください。「キャンセル」をクリックすると、セットアップを終了します。\nUninstallAppRunningError=アンインストールは実行中の %1 を検出しました。%n%n開いているアプリケーションをすべて閉じてから「OK」をクリックしてください。「キャンセル」をクリックすると、セットアップを終了します。\n\n; *** Misc. errors\nErrorCreatingDir=ディレクトリ %1 を作成中にエラーが発生しました。\nErrorTooManyFilesInDir=ディレクトリ %1 にファイルを作成中にエラーが発生しました。ファイルの数が多すぎます。\n\n; *** Setup common messages\nExitSetupTitle=セットアップ終了\nExitSetupMessage=セットアップ作業は完了していません。ここでセットアップを中止するとプログラムはインストールされません。%n%n改めてインストールする場合は、もう一度セットアップを実行してください。%n%nセットアップを終了しますか？\nAboutSetupMenuItem=セットアップについて(&A)...\nAboutSetupTitle=セットアップについて\nAboutSetupMessage=%1 %2%n%3%n%n%1 ホームページ:%n%4\nAboutSetupNote=\nTranslatorNote=\n\n; *** Buttons\nButtonBack=< 戻る(&B)\nButtonNext=次へ(&N) >\nButtonInstall=インストール(&I)\nButtonOK=OK\nButtonCancel=キャンセル\nButtonYes=はい(&Y)\nButtonYesToAll=すべてはい(&A)\nButtonNo=いいえ(&N)\nButtonNoToAll=すべていいえ(&O)\nButtonFinish=完了(&F)\nButtonBrowse=参照(&B)...\nButtonWizardBrowse=参照(&R)\nButtonNewFolder=新しいフォルダー(&M)\n\n; *** \"Select Language\" dialog messages\nSelectLanguageTitle=セットアップに使用する言語の選択\nSelectLanguageLabel=インストール中に利用する言語を選んでください:\n\n; *** Common wizard text\nClickNext=続行するには「次へ」、セットアップを終了するには「キャンセル」をクリックしてください。\nBeveledLabel=\nBrowseDialogTitle=フォルダー参照\nBrowseDialogLabel=リストからフォルダーを選び OK を押してください。\nNewFolderName=新しいフォルダー\n\n; *** \"Welcome\" wizard page\nWelcomeLabel1=[name] セットアップウィザードの開始\nWelcomeLabel2=このプログラムはご使用のコンピューターへ [name/ver] をインストールします。%n%n続行する前に他のアプリケーションをすべて終了してください。\n\n; *** \"Password\" wizard page\nWizardPassword=パスワード\nPasswordLabel1=このインストールプログラムはパスワードによって保護されています。\nPasswordLabel3=パスワードを入力して「次へ」をクリックしてください。パスワードは大文字と小文字が区別されます。\nPasswordEditLabel=パスワード(&P):\nIncorrectPassword=入力されたパスワードが正しくありません。もう一度入力しなおしてください。\n\n; *** \"License Agreement\" wizard page\nWizardLicense=使用許諾契約書の同意\nLicenseLabel=続行する前に以下の重要な情報をお読みください。\nLicenseLabel3=以下の使用許諾契約書をお読みください。インストールを続行するにはこの契約書に同意する必要があります。\nLicenseAccepted=同意する(&A)\nLicenseNotAccepted=同意しない(&D)\n\n; *** \"Information\" wizard pages\nWizardInfoBefore=情報\nInfoBeforeLabel=続行する前に以下の重要な情報をお読みください。\nInfoBeforeClickLabel=セットアップを続行するには「次へ」をクリックしてください。\nWizardInfoAfter=情報\nInfoAfterLabel=続行する前に以下の重要な情報をお読みください。\nInfoAfterClickLabel=セットアップを続行するには「次へ」をクリックしてください。\n\n; *** \"User Information\" wizard page\nWizardUserInfo=ユーザー情報\nUserInfoDesc=ユーザー情報を入力してください。\nUserInfoName=ユーザー名(&U):\nUserInfoOrg=組織(&O):\nUserInfoSerial=シリアル番号(&S):\nUserInfoNameRequired=ユーザー名を入力してください。\n\n; *** \"Select Destination Location\" wizard page\nWizardSelectDir=インストール先の指定\nSelectDirDesc=[name] のインストール先を指定してください。\nSelectDirLabel3=[name] をインストールするフォルダを指定して、「次へ」をクリックしてください。\nSelectDirBrowseLabel=続けるには「次へ」をクリックしてください。別のフォルダーを選択するには「参照」をクリックしてください。\nDiskSpaceMBLabel=このプログラムは最低 [mb] MB のディスク空き領域を必要とします。\nCannotInstallToNetworkDrive=ネットワークドライブにインストールすることはできません。\nCannotInstallToUNCPath=UNC パスにインストールすることはできません。\nInvalidPath=ドライブ文字を含む完全なパスを入力してください。%n%n例：C:¥APP%n%nまたは UNC 形式のパスを入力してください。%n%n例：¥¥server¥share\nInvalidDrive=指定したドライブまたは UNC パスが見つからないかアクセスできません。別のパスを指定してください。\nDiskSpaceWarningTitle=ディスク空き領域の不足\nDiskSpaceWarning=インストールには最低 %1 KB のディスク空き領域が必要ですが、指定されたドライブには %2 KB の空き領域しかありません。%n%nこのまま続行しますか？\nDirNameTooLong=ドライブ名またはパスが長過ぎます。\nInvalidDirName=フォルダー名が無効です。\nBadDirName32=以下の文字を含むフォルダー名は指定できません。:%n%n%1\nDirExistsTitle=既存のフォルダー\nDirExists=フォルダー %n%n%1%n%nが既に存在します。このままこのフォルダーへインストールしますか？\nDirDoesntExistTitle=フォルダーが見つかりません。\nDirDoesntExist=フォルダー %n%n%1%n%nが見つかりません。新しいフォルダーを作成しますか？\n\n; *** \"Select Components\" wizard page\nWizardSelectComponents=コンポーネントの選択\nSelectComponentsDesc=インストールコンポーネントを選択してください。\nSelectComponentsLabel2=インストールするコンポーネントを選択してください。インストールする必要のないコンポーネントはチェックを外してください。続行するには「次へ」をクリックしてください。\nFullInstallation=フルインストール\n; if possible don't translate 'Compact' as 'Minimal' (I mean 'Minimal' in your language)\nCompactInstallation=コンパクトインストール\nCustomInstallation=カスタムインストール\nNoUninstallWarningTitle=既存のコンポーネント\nNoUninstallWarning=セットアップは以下のコンポーネントが既にインストールされていることを検出しました。%n%n%1%n%nこれらのコンポーネントの選択を解除してもアンインストールはされません。%n%nこのまま続行しますか？\nComponentSize1=%1 KB\nComponentSize2=%1 MB\nComponentsDiskSpaceMBLabel=現在の選択は最低 [mb] MB のディスク空き領域を必要とします。\n\n; *** \"Select Additional Tasks\" wizard page\nWizardSelectTasks=追加タスクの選択\nSelectTasksDesc=実行する追加タスクを選択してください。\nSelectTasksLabel2=[name] インストール時に実行する追加タスクを選択して、「次へ」をクリックしてください。\n\n; *** \"Select Start Menu Folder\" wizard page\nWizardSelectProgramGroup=プログラムグループの指定\nSelectStartMenuFolderDesc=プログラムアイコンを作成する場所を指定してください。\nSelectStartMenuFolderLabel3=セットアップはスタートメニューにプログラムのショートカットを作成します。\nSelectStartMenuFolderBrowseLabel=続けるには「次へ」をクリックしてください。違うディレクトリを選択するには「参照」をクリックしてください。\nMustEnterGroupName=グループ名を指定してください。\nGroupNameTooLong=フォルダー名またはパスが長過ぎます。\nInvalidGroupName=グループ名が無効です。\nBadGroupName=以下の文字を含むグループ名は指定できません。:%n%n%1\nNoProgramGroupCheck2=プログラムグループを作成しない(&D)\n\n; *** \"Ready to Install\" wizard page\nWizardReady=インストール準備完了\nReadyLabel1=ご使用のコンピュータへ [name] をインストールする準備ができました。\nReadyLabel2a=インストールを続行するには「インストール」を、設定の確認や変更を行うには「戻る」をクリックしてください。\nReadyLabel2b=インストールを続行するには「インストール」をクリックしてください。\nReadyMemoUserInfo=ユーザー情報:\nReadyMemoDir=インストール先:\nReadyMemoType=セットアップの種類:\nReadyMemoComponents=選択コンポーネント:\nReadyMemoGroup=プログラムグループ:\nReadyMemoTasks=追加タスク一覧:\n\n; *** \"Preparing to Install\" wizard page\nWizardPreparing=インストール準備中\nPreparingDesc=ご使用のコンピューターへ [name] をインストールする準備をしています。\nPreviousInstallNotCompleted=前回行ったアプリケーションのインストールまたは削除が完了していません。完了するにはコンピューターを再起動する必要があります。%n%n[name] のインストールを完了するためには、再起動後にもう一度セットアップを実行してください。\nCannotContinue=セットアップを続行できません。「キャンセル」をクリックしてセットアップを終了してください。\nApplicationsFound=以下のアプリケーションがセットアップに必要なファイルを使用しています。セットアップに自動的にアプリケーションを終了させることを推奨します。\nApplicationsFound2=以下のアプリケーションがセットアップに必要なファイルを使用しています。セットアップに自動的にアプリケーションを終了させることを推奨します。インストールの完了後、セットアップはアプリケーションの再起動を試みます。\nCloseApplications=自動的にアプリケーションを終了する(&A)\nDontCloseApplications=アプリケーションを終了しない(&D)\nErrorCloseApplications=セットアップはすべてのアプリケーションを自動的に終了することができませんでした。セットアップを続行する前に、更新の必要なファイルを使用しているすべてのアプリケーションを終了することを推奨します。\n\n; *** \"Installing\" wizard page\nWizardInstalling=インストール状況\nInstallingLabel=ご使用のコンピューターに [name] をインストールしています。しばらくお待ちください。\n\n; *** \"Setup Completed\" wizard page\nFinishedHeadingLabel=[name] セットアップウィザードの完了\nFinishedLabelNoIcons=ご使用のコンピューターに [name] がセットアップされました。\nFinishedLabel=ご使用のコンピューターに [name] がセットアップされました。アプリケーションを実行するにはインストールされたアイコンを選択してください。\nClickFinish=セットアップを終了するには「完了」をクリックしてください。\nFinishedRestartLabel=[name] のインストールを完了するためには、コンピューターを再起動する必要があります。すぐに再起動しますか？\nFinishedRestartMessage=[name] のインストールを完了するためには、コンピューターを再起動する必要があります。%n%nすぐに再起動しますか？\nShowReadmeCheck=README ファイルを表示する。\nYesRadio=すぐに再起動(&Y)\nNoRadio=後で手動で再起動(&N)\n; used for example as 'Run MyProg.exe'\nRunEntryExec=%1 の実行\n; used for example as 'View Readme.txt'\nRunEntryShellExec=%1 の表示\n\n; *** \"Setup Needs the Next Disk\" stuff\nChangeDiskTitle=ディスクの挿入\nSelectDiskLabel2=ディスク %1 を挿入し、「OK」をクリックしてください。%n%nこのディスクのファイルが下に表示されているフォルダー以外の場所にある場合は、正しいパスを入力するか「参照」ボタンをクリックしてください。\nPathLabel=パス(&P):\nFileNotInDir2=ファイル %1 が %2 に見つかりません。正しいディスクを挿入するか、別のフォルダーを指定してください。\nSelectDirectoryLabel=次のディスクのある場所を指定してください。\n\n; *** Installation phase messages\nSetupAborted=セットアップは完了していません。%n%n問題を解決してから、もう一度セットアップを実行してください。\nEntryAbortRetryIgnore=もう一度やりなおすには「再試行」、エラーを無視して続行するには「無視」、インストールを中止するには「中止」をクリックしてください。\n\n; *** Installation status messages\nStatusClosingApplications=アプリケーションを終了しています...\nStatusCreateDirs=フォルダーを作成しています...\nStatusExtractFiles=ファイルを展開しています...\nStatusCreateIcons=ショ−トカットを作成しています...\nStatusCreateIniEntries=INIファイルを設定しています...\nStatusCreateRegistryEntries=レジストリを設定しています...\nStatusRegisterFiles=ファイルを登録しています...\nStatusSavingUninstall=アンインストール情報を保存しています...\nStatusRunProgram=インストールを完了しています...\nStatusRestartingApplications=アプリケーションを再起動しています...\nStatusRollback=変更を元に戻しています...\n\n; *** Misc. errors\nErrorInternal2=内部エラー: %1\nErrorFunctionFailedNoCode=%1 エラー\nErrorFunctionFailed=%1 エラー: コード %2\nErrorFunctionFailedWithMessage=%1 エラー: コード %2.%n%3\nErrorExecutingProgram=ファイル実行エラー:%n%1\n\n; *** Registry errors\nErrorRegOpenKey=レジストリキーオープンエラー:%n%1¥%2\nErrorRegCreateKey=レジストリキー作成エラー:%n%1¥%2\nErrorRegWriteKey=レジストリキー書き込みエラー:%n%1¥%2\n\n; *** INI errors\nErrorIniEntry=INIファイルエントリ作成エラー: ファイル %1\n\n; *** File copying errors\nFileAbortRetryIgnore=もう一度やりなおすには「再試行」、このファイルをスキップして続行するには「無視」（推奨されません）、インストールを中止するには「中止」をクリックしてください。\nFileAbortRetryIgnore2=もう一度やりなおすには「再試行」、このファイルをスキップして続行するには「無視」（推奨されません）、インストールを中止するには「中止」をクリックしてください。\nSourceIsCorrupted=コピー元のファイルが壊れています。\nSourceDoesntExist=コピー元のファイル %1 が見つかりません。\nExistingFileReadOnly=既存のファイルは読み取り専用です。%n%n読み取り専用属性を解除してもう一度やりなおすには「再試行」、このファイルをスキップして続行するには「無視」、インストールを中止するには「中止」をクリックしてください。\nErrorReadingExistingDest=既存のファイルを読み込み中にエラーが発生しました。:\nFileExists=ファイルは既に存在します。%n%n上書きしますか？\nExistingFileNewer=インストールしようとしているファイルよりも新しいファイルが存在します。既存のファイルを残すことをお奨めします。%n%n既存のファイルを残しますか。\nErrorChangingAttr=既存ファイルの属性を変更中にエラーが発生しました。:\nErrorCreatingTemp=コピー先のフォルダにファイルを作成中にエラーが発生しました。:\nErrorReadingSource=コピー元のファイルを読み込み中にエラーが発生しました。:\nErrorCopying=ファイルをコピー中にエラーが発生しました。:\nErrorReplacingExistingFile=既存ファイルを置き換え中にエラーが発生しました。:\nErrorRestartReplace=置き換え再開中にエラーが発生しました。:\nErrorRenamingTemp=コピー先フォルダのファイル名を変更中にエラーが発生しました。:\nErrorRegisterServer=DLL/OCXの登録に失敗しました。: %1\nErrorRegSvr32Failed=RegSvr32はエラーコード %1 により失敗しました。\nErrorRegisterTypeLib=タイプライブラリへの登録に失敗しました。: %1\n\n; *** Post-installation errors\nErrorOpeningReadme=README ファイルのオープンに失敗しました。\nErrorRestartingComputer=コンピューターの再起動に失敗しました。手動で再起動してください。\n\n; *** Uninstaller messages\nUninstallNotFound=ファイル %1 が見つかりません。アンインストールを実行できません。\nUninstallOpenError=ファイル %1 を開けることができません。アンインストールを実行できません。\nUninstallUnsupportedVer=アンインストールログファイル %1 は、このバージョンのアンインストールプログラムが認識できない形式です。アンインストールを実行できません。\nUninstallUnknownEntry=アンインストールログに不明のエントリ %1 が見つかりました。\nConfirmUninstall=%1 とその関連コンポーネントをすべて削除します。よろしいですか？\nUninstallOnlyOnWin64=このプログラムは64-bit版Windows上でのみアンインストールすることができます。\nOnlyAdminCanUninstall=アンインストールするためには管理者権限が必要です。\nUninstallStatusLabel=ご使用のコンピューターから %1 を削除しています。しばらくお待ちください。\nUninstalledAll=%1 はご使用のコンピューターから正常に削除されました。\nUninstalledMost=%1 のアンインストールが完了しました。%n%nいくつかの項目が削除できませんでした。手動で削除してください。\nUninstalledAndNeedsRestart=%1 の削除を完了するためには、コンピューターを再起動する必要があります。すぐに再起動しますか？\nUninstallDataCorrupted=ファイル \"%1\" が壊れています。アンインストールを実行できません。\n\n; *** Uninstallation phase messages\nConfirmDeleteSharedFileTitle=共有ファイルの削除\nConfirmDeleteSharedFile2=システム上で、次の共有ファイルはどのプログラムでも使用されていません。この共有ファイルを削除しますか？%n%n他のプログラムがまだこのファイルを使用する場合、削除するとプログラムが動作しなくなる恐れがあります。あまり確実でない場合は「いいえ」を選択してください。システムにファイルを残しても問題を引き起こすことはありません。\nSharedFileNameLabel=ファイル名:\nSharedFileLocationLabel=場所:\nWizardUninstalling=アンインストール状況\nStatusUninstalling=%1 をアンインストールしています...\n\n; *** Shutdown block reasons\nShutdownBlockReasonInstallingApp=%1 をインストール中です。\nShutdownBlockReasonUninstallingApp=%1 をアンインストール中です。\n\n; The custom messages below aren't used by Setup itself, but if you make\n; use of them in your scripts, you'll want to translate them.\n\n[CustomMessages]\n\nNameAndVersion=%1 バージョン %2\nAdditionalIcons=アイコンを追加する:\nCreateDesktopIcon=デスクトップ上にアイコンを作成する(&D)\nCreateQuickLaunchIcon=クイック起動アイコンを作成する(&Q)\nProgramOnTheWeb=%1 on the Web\nUninstallProgram=%1 をアンインストールする\nLaunchProgram=%1 を実行する\nAssocFileExtension=ファイル拡張子 %2 に %1 を関連付けます。\nAssocingFileExtension=ファイル拡張子 %2 に %1 を関連付けています...\nAutoStartProgramGroupDescription=スタートアップ:\nAutoStartProgram=%1 を自動的に開始する\nAddonHostProgramNotFound=選択されたフォルダーに %1 が見つかりませんでした。%n%nこのまま続行しますか？\n\n\nFullInstallation=フルインストール\n;CompactInstallation=Recommended installation\nCustomInstallation=カスタムインストール\n\nCmpMain=%1 基本ファイル\nCmpDocs=ヘルプ\nCmpDocsEn=英語\nCmpDocsCs=チェコ語\nCmpDocsFr=フランス語\nCmpDocsDe=ドイツ語\nCmpDocsIt=イタリア語\nCmpDocsJa=日本語\nCmpDocsPl=ポーランド語\nCmpDocsPt=ポルトガル語\nCmpDocsRu=ロシア語\n;CmpDocsExamples=Scripting Examples\nCmpSdk=FilterSDK のインストール\n;CmpMig=Legacy AviSynth Upgrade\n;CmpMigUninstall=Uninstall and move plugins to %1\n;CmpMigBackup=Backup legacy AviSynth\n;CmpCustomizePluginPaths=Customize Plugin Paths\n\n;FileTypeDescAvs=%1 Script\n;FileTypeDescAvsi=%1 Autoload Script\n\n;InstallStatusRuntime = Installing %1 (%2).%nThis may take up to 5 minutes... \n;UninstallStatusLegacyRestore = Restoring legacy AviSynth...\n;BackupRestoreFailed=An error occured while trying to restore your previous AviSynth installation:%n%1\n\n;MigPageCaption=Upgrade Options\n;MigPageDescription=How should %1 handle your existing AviSynth installation?\n;MigPageSubCaption=Setup has detected that AviSynth is already installed in:%n%n%2%n%nAvisynth and %1 cannot be run alongside each other. However, setup can preserve your legacy AviSynth installation in case you want to downgrade later.\n;MigPageOptionBackup=Keep the existing AviSynth program directory and backup its system components overwritten by %1.%n%1 will still load your existing plugins and restore your previous AviSynth installation upon uninstall.\n;MigPageOptionUninstall=Uninstall AviSynth now and migrate compatible plugins to the %1 plugin directory.\n;MigPageUninstallFailed=AviSynth Uninstall failed: %n%1\n \n;PlugPageCaption=%1 Plugin Folders\n;PlugPageDescription=Where should %1 autoload plugins from?\n;PlugPageSubCaption=%1 will install bundled plugins to the its own autoload directory, but also autoload from the legacy plugin directory.\n;PlugPagePlugDirPlus=%2 %1-bit plugin directory:\n;PlugPagePlugDirLegacy=AviSynth %1-bit plugin directory:"
  },
  {
    "path": "distrib/WinInstaller/Translations/pl.isl",
    "content": "; *** Inno Setup version 5.5.3+ Polish messages ***\n; Krzysztof Cynarski <krzysztof at cynarski.net>\n;\n; To download user-contributed translations of this file, go to:\n;   http://www.jrsoftware.org/is3rdparty.php\n;\n; Note: When translating this text, do not add periods (.) to the end of\n; messages that didn't have them already, because on those messages Inno\n; Setup adds the periods automatically (appending a period would result in\n; two periods being displayed).\n;\n; $jrsoftware: issrc/Files/Languages/Polish.isl,v 1.16 2007/03/09 16:56:52 jr Exp $\n\n[LangOptions]\nLanguageName=Polski\nLanguageID=$0415\nLanguageCodePage=1250\n\n[Messages]\n\n; *** Application titles\nSetupAppTitle=Instalator\nSetupWindowTitle=Instalacja - %1\nUninstallAppTitle=Deinstalacja\nUninstallAppFullTitle=Odinstaluj %1\n\n; *** Misc. common\nInformationTitle=Informacja\nConfirmTitle=Potwierd\nErrorTitle=Bd\n\n; *** SetupLdr messages\nSetupLdrStartupMessage=Ten program zainstaluje aplikacj %1. Czy chcesz kontynuowa?\nLdrCannotCreateTemp=Nie mona utworzy pliku tymczasowego. Instalacja przerwana\nLdrCannotExecTemp=Nie mona uruchomi pliku w folderze tymczasowym. Instalacja przerwana\n\n; *** Startup error messages\nLastErrorMessage=%1.%n%nBd %2: %3\nSetupFileMissing=W folderze instalacyjnym brak pliku %1.%nProsz usun problem lub uzyska now kopi programu instalacyjnego.\nSetupFileCorrupt=Pliki skadowe Instalatora s uszkodzone. Prosz uzyska now kopi Instalatora od producenta.\nSetupFileCorruptOrWrongVer=Pliki skadowe instalatora s uszkodzone lub niezgodne z t wersj Instalatora. Prosz rozwiza ten problem lub uzyska now kopi Instalatora od producenta.\nInvalidParameter=W lini komend zosta przekazany nieprawidowy parametr:%n%n%1\nSetupAlreadyRunning=Instalator jest ju uruchomiony.\nWindowsVersionNotSupported=Ten program nie wspiera aktualnie uruchomionej na Twoim komputerze wersji Windows.\nWindowsServicePackRequired=Ten program wymaga %1 z dodatkiem Service Pack %2 lub pniejszym.\nNotOnThisPlatform=Tego programu nie mona uruchomi w systemie %1.\nOnlyOnThisPlatform=Ten program wymaga systemu %1.\nOnlyOnTheseArchitectures=Ten program moe by uruchomiony tylko w systemie Windows zaprojektowanym na procesory o architekturach:%n%n%1\nMissingWOW64APIs=Ta wersja systemu Windows nie zawiera komponentw niezbdnych do przeprowadzenia 64 bitowej instalacji. Aby usun ten problem, prosz zainstalowa Service Pack %1.\nWinVersionTooLowError=Ten program wymaga %1 w wersji %2 lub pniejszej.\nWinVersionTooHighError=Ten program nie moe by zainstalowany w wersji %2 lub pniejszej systemu %1.\nAdminPrivilegesRequired=Aby przeprowadzi instalacj tego programu, Uytkownik musi by zalogowany z uprawnieniami administratora.\nPowerUserPrivilegesRequired=Aby przeprowadzi instalacj tego programu, Uytkownik musi by zalogowany z uprawnieniami administratora lub uytkownika zaawansowanego.\nSetupAppRunningError=Instalator wykry, e %1 jest aktualnie uruchomiony.%n%nZamknij wszystkie okienka tej aplikacji, a potem wybierz przycisk OK, aby kontynuowa, lub Anuluj, aby przerwa instalacj.\nUninstallAppRunningError=Deinstalator wykry, e %1 jest aktualnie uruchomiony.%n%nZamknij teraz wszystkie okna tej aplikacji, a nastpnie wybierz przycisk OK, aby kontynuowa, lub Anuluj, aby przerwa deinstalacje.\n\n; *** Misc. errors\nErrorCreatingDir=Instalator nie mg utworzy foldera \"%1\"\nErrorTooManyFilesInDir=Nie mona utworzy pliku w folderze %1, poniewa zawiera on za duo plikw\n\n; *** Setup common messages\nExitSetupTitle=Zakocz instalacj\nExitSetupMessage=Instalacja nie jest zakoczona. Jeeli przerwiesz j teraz, program nie zostanie zainstalowany. Mona ponowi instalacj pniej, uruchamiajc pakiet Instalatora.%n%nCzy chcesz przerwa instalacj ?\nAboutSetupMenuItem=&O Instalatorze...\nAboutSetupTitle=O Instalatorze\nAboutSetupMessage=%1 wersja %2%n%3%n%n Strona domowa %1:%n%4\nAboutSetupNote=\nTranslatorNote=Wersja Polska: Krzysztof Cynarski%n<krzysztof at cynarski.net>\n\n; *** Buttons\nButtonBack=< &Wstecz\nButtonNext=&Dalej >\nButtonInstall=&Instaluj\nButtonOK=OK\nButtonCancel=Anuluj\nButtonYes=&Tak\nButtonYesToAll=Tak na &wszystkie\nButtonNo=&Nie\nButtonNoToAll=N&ie na wszystkie\nButtonFinish=&Zakocz\nButtonBrowse=&Przegldaj...\nButtonWizardBrowse=P&rzegldaj...\nButtonNewFolder=&Utwrz nowy folder\n\n; *** \"Select Language\" dialog messages\nSelectLanguageTitle=Wybierz jzyk instalacji\nSelectLanguageLabel=Wybierz jzyk uywany podczas instalacji:\n\n; *** Common wizard text\nClickNext=Wybierz przycisk Dalej, aby kontynuowa, lub Anuluj, aby zakoczy instalacj.\nBeveledLabel=\nBrowseDialogTitle=Wska folder\nBrowseDialogLabel=Wybierz folder z poniszej listy, a nastpnie wybierz przycisk OK.\nNewFolderName=Nowy folder\n\n; *** \"Welcome\" wizard page\nWelcomeLabel1=Witamy w Kreatorze instalacji programu [name].\nWelcomeLabel2=Instalator zainstaluje teraz program [name/ver] na Twoim komputerze.%n%nZalecane jest zamknicie wszystkich innych uruchomionych programw przed rozpoczciem procesu instalacji.\n\n; *** \"Password\" wizard page\nWizardPassword=Haso\nPasswordLabel1=Ta instalacja jest zabezpieczona hasem.\nPasswordLabel3=Podaj haso, potem wybierz przycisk Dalej, aby kontynuowa. W hasach rozrniane s due i mae litery.\nPasswordEditLabel=&Haso:\nIncorrectPassword=Wprowadzone haso nie jest poprawne. Sprbuj ponownie.\n\n; *** \"License Agreement\" wizard page\nWizardLicense=Umowa Licencyjna\nLicenseLabel=Przed kontynuacj prosz przeczyta ponisze wane informacje.\nLicenseLabel3=Prosz przeczyta tekst Umowy Licencyjnej. Musisz zgodzi si na warunki tej umowy przed kontynuacj instalacji.\nLicenseAccepted=&Akceptuj warunki umowy\nLicenseNotAccepted=&Nie akceptuj warunkw umowy\n\n; *** \"Information\" wizard pages\nWizardInfoBefore=Informacja\nInfoBeforeLabel=Przed przejciem do dalszego etapu instalacji, prosz przeczyta ponisz informacj.\nInfoBeforeClickLabel=Kiedy bdziesz gotowy do instalacji, kliknij przycisk Dalej.\nWizardInfoAfter=Informacja\nInfoAfterLabel=Przed przejciem do dalszego etapu instalacji, prosz przeczyta ponisz informacj.\nInfoAfterClickLabel=Gdy bdziesz gotowy do zakoczenia instalacji, kliknij przycisk Dalej.\n\n; *** \"User Information\" wizard page\nWizardUserInfo=Dane Uytkownika\nUserInfoDesc=Prosz poda swoje dane.\nUserInfoName=&Nazwisko:\nUserInfoOrg=&Organizacja:\nUserInfoSerial=Numer &seryjny:\nUserInfoNameRequired=Musisz poda nazwisko.\n\n; *** \"Select Destination Location\" wizard page\nWizardSelectDir=Wybierz docelow lokalizacj\nSelectDirDesc=Gdzie ma by zainstalowany program [name]?\nSelectDirLabel3=Instalator zainstaluje program [name] do poniszego folderu.\nSelectDirBrowseLabel=Kliknij przycisk Dalej, aby kontynuowa. Jeli chcesz okreli inny folder, kliknij przycisk Przegldaj.\nDiskSpaceMBLabel=Potrzeba przynajmniej [mb] MB wolnego miejsca na dysku.\nCannotInstallToNetworkDrive=Instalator nie moe zainstalowa programu na dysku sieciowym.\nCannotInstallToUNCPath=Instalator nie moe zainstalowa programu w ciece UNC.\nInvalidPath=Musisz wprowadzi pen ciek wraz z liter dysku, np.:%n%nC:\\PROGRAM%n%nlub sciek sieciow (UNC) w formacie:%n%n\\\\serwer\\udzia\nInvalidDrive=Wybrany dysk lub udostpniony folder sieciowy nie istnieje. Prosz wybra inny.\nDiskSpaceWarningTitle=Niewystarczajca ilo wolnego miejsca na dysku\nDiskSpaceWarning=Instalator wymaga co najmniej %1 KB wolnego miejsca na dysku. Wybrany dysk posiada tylko %2 KB dostpnego miejsca.%n%nCzy pomimo to chcesz kontynuowa?\nDirNameTooLong=Nazwa folderu lub cieki jest za duga.\nInvalidDirName=Niepoprawna nazwa folderu.\nBadDirName32=Nazwa folderu nie moe zawiera adnego z nastpujcych znakw:%n%n%1\nDirExistsTitle=Ten folder ju istnieje\nDirExists=Folder%n%n%1%n%nju istnieje. Czy pomimo to chcesz zainstalowa program w tym folderze?\nDirDoesntExistTitle=Nie ma takiego folderu\nDirDoesntExist=Folder:%n%n%1%n%nnie istnieje. Czy chcesz, aby zosta utworzony?\n\n; *** \"Select Components\" wizard page\nWizardSelectComponents=Zaznacz komponenty\nSelectComponentsDesc=Ktre komponenty maj by zainstalowane?\nSelectComponentsLabel2=Zaznacz komponenty, ktre chcesz zainstalowa, odznacz te, ktrych nie chcesz zainstalowa. Kliknij przycisk Dalej, aby kontynuowa.\nFullInstallation=Instalacja pena\n; if possible don't translate 'Compact' as 'Minimal' (I mean 'Minimal' in your language)\nCompactInstallation=Instalacja podstawowa\nCustomInstallation=Instalacja uytkownika\nNoUninstallWarningTitle=Zainstalowane komponenty\nNoUninstallWarning=Instalator wykry, e w twoim komputerze s ju zainstalowane nastpujce komponenty:%n%n%1%n%nOdznaczenie ktregokolwiek z nich nie spowoduje ich deinstalacji.%n%nCzy pomimo tego chcesz kontynuowa?\nComponentSize1=%1 KB\nComponentSize2=%1 MB\nComponentsDiskSpaceMBLabel=Wybrane komponenty wymagaj co najmniej [mb] MB na dysku.\n\n; *** \"Select Additional Tasks\" wizard page\nWizardSelectTasks=Zaznacz dodatkowe zadania\nSelectTasksDesc=Ktre dodatkowe zadania maj by wykonane?\nSelectTasksLabel2=Zaznacz dodatkowe zadania, ktre Instalator ma wykona podczas instalacji programu [name], a nastpnie kliknij przycisk Dalej, aby kontynuowa.\n\n; *** \"Select Start Menu Folder\" wizard page\nWizardSelectProgramGroup=Wybierz folder Menu Start\nSelectStartMenuFolderDesc=Gdzie maj by umieszczone skrty do programu?\nSelectStartMenuFolderLabel3=Instalator stworzy skrty do programu w poniszym folderze Menu Start.\nSelectStartMenuFolderBrowseLabel=Kliknij przycisk Dalej, aby kontynuowa. Jeli chcesz okreli inny folder, kliknij przycisk Przegldaj.\nMustEnterGroupName=Musisz wprowadzi nazw folderu.\nGroupNameTooLong=Nazwa folderu lub cieki jest za duga.\nInvalidGroupName=Niepoprawna nazwa folderu.\nBadGroupName=Nazwa folderu nie moe zawiera adnego z nastpujcych znakw:%n%n%1\nNoProgramGroupCheck2=Nie twrz folderu w &Menu Start\n\n; *** \"Ready to Install\" wizard page\nWizardReady=Gotowy do rozpoczcia instalacji\nReadyLabel1=Instalator jest ju gotowy do rozpoczcia instalacji programu [name] na twoim komputerze.\nReadyLabel2a=Kliknij przycisk Instaluj, aby rozpocz instalacj lub Wstecz, jeli chcesz przejrze lub zmieni ustawienia.\nReadyLabel2b=Kliknij przycisk Instaluj, aby kontynuowa instalacj.\nReadyMemoUserInfo=Informacje uytkownika:\nReadyMemoDir=Lokalizacja docelowa:\nReadyMemoType=Rodzaj instalacji:\nReadyMemoComponents=Wybrane komponenty:\nReadyMemoGroup=Folder w Menu Start:\nReadyMemoTasks=Dodatkowe zadania:\n\n; *** \"Preparing to Install\" wizard page\nWizardPreparing=Przygotowanie do instalacji\nPreparingDesc=Instalator przygotowuje instalacj programu [name] na Twoim komputerze.\nPreviousInstallNotCompleted=Instalacja (usunicie) poprzedniej wersji programu nie zostaa zakoczona. Bdziesz musia ponownie uruchomi komputer, aby zakoczy instalacj. %n%nPo ponownym uruchomieniu komputera uruchom ponownie instalatora, aby zakoczy instalacj aplikacji [name].\nCannotContinue=Instalator nie moe kontynuowa. Kliknij przycisk Anuluj, aby przerwa instalacj.\nApplicationsFound=Ponisze aplikacje uywaj plikw, ktre musz by uaktualnione przez Instalator. Zalecane jest aby pozwoli Instalatorowi automatycznie zamkn te aplikacje.\nApplicationsFound2=Ponisze aplikacje uywaj plikw, ktre musz by uaktualnione przez Instalator. Zalecane jest aby pozwoli Instalatorowi automatycznie zamkn te aplikacje. Po zakoczonej instalacji Instalator podejmie prb ich ponownego uruchomienia.\nCloseApplications=&Automatycznie zamknij aplikacje\nDontCloseApplications=&Nie zamykaj aplikacji\nErrorCloseApplications=Instalator nie by w stanie zamkn automatycznie wszystkich aplikacji. Zalecane jest zamknicie wszystkich tych aplikacji, ktre akualnie uywaj uakutalnianych przez Instalator plikw.\n\n; *** \"Installing\" wizard page\nWizardInstalling=Instalacja\nInstallingLabel=Poczekaj, a instalator zainstaluje aplikacj [name] na Twoim komputerze.\n\n; *** \"Setup Completed\" wizard page\nFinishedHeadingLabel=Zakoczono instalacj programu [name]\nFinishedLabelNoIcons=Instalator zakoczy instalacj programu [name] na Twoim komputerze.\nFinishedLabel=Instalator zakoczy instalacj programu [name] na Twoim komputerze. Aplikacja moe by uruchomiona poprzez uycie zainstalowanych skrtw.\nClickFinish=Kliknij przycisk Zakocz, aby zakoczy instalacj.\nFinishedRestartLabel=Aby zakoczy instalacj programu [name], Instalator musi ponownie uruchomi Twj komputer. Czy chcesz teraz wykona restart komputera?\nFinishedRestartMessage=Aby zakoczy instalacj programu [name], Instalator musi ponownie uruchomi Twj komputer.%n%nCzy chcesz teraz wykona restart komputera?\nShowReadmeCheck=Tak, chc przeczyta dodatkowe informacje\nYesRadio=&Tak, teraz uruchom ponownie\nNoRadio=&Nie, sam zrestartuj pniej\n; used for example as 'Run MyProg.exe'\nRunEntryExec=Uruchom %1\n; used for example as 'View Readme.txt'\nRunEntryShellExec=Poka %1\n\n; *** \"Setup Needs the Next Disk\" stuff\nChangeDiskTitle=Instalator potrzebuje nastpnej dyskietki\nSelectDiskLabel2=Prosz woy dyskietk %1 i klikn przycisk OK.%n%nJeli pokazany poniej folder nie okrela pooenia plikw z tej dyskietki, wprowad poprawn ciek lub kliknij przycisk Przegldaj.\nPathLabel=&cieka:\nFileNotInDir2=Plik \"%1\" nie zosta znaleziony na dyskietce \"%2\". Prosz woy waciw dyskietk lub wybra inny folder.\nSelectDirectoryLabel=Prosz okreli lokalizacj nastpnej dyskietki.\n\n; *** Installation phase messages\nSetupAborted=Instalacja nie zostaa zakoczona.%n%nProsz rozwiza problem i ponownie rozpocz instalacj.\nEntryAbortRetryIgnore=Moesz ponowi nieudan czynno, zignorowa j (nie zalecane) lub przerwa instalacj.\n\n; *** Installation status messages\nStatusClosingApplications=Zamykanie aplikacji...\nStatusCreateDirs=Tworzenie folderw...\nStatusExtractFiles=Dekompresja plikw...\nStatusCreateIcons=Tworzenie ikon aplikacji...\nStatusCreateIniEntries=Tworzenie zapisw w plikach INI...\nStatusCreateRegistryEntries=Tworzenie zapisw w rejestrze...\nStatusRegisterFiles=Rejestracja plikw...\nStatusSavingUninstall=Zachowanie informacji deinstalatora...\nStatusRunProgram=Koczenie instalacji...\nStatusRestartingApplications=Ponowne uruchamianie aplikacji...\nStatusRollback=Cofanie zmian...\n\n; *** Misc. errors\nErrorInternal2=Wewntrzny bd: %1\nErrorFunctionFailedNoCode=Bd podczas wykonywania %1\nErrorFunctionFailed=Bd podczas wykonywania %1; kod %2\nErrorFunctionFailedWithMessage=Bd podczas wykonywania %1; code %2.%n%3\nErrorExecutingProgram=Nie mona uruchomi:%n%1\n\n; *** Registry errors\nErrorRegOpenKey=Bd podczas otwierania klucza rejestru:%n%1\\%2\nErrorRegCreateKey=Bd podczas tworzenia klucza rejestru:%n%1\\%2\nErrorRegWriteKey=Bd podczas zapisu do klucza rejestru:%n%1\\%2\n\n; *** INI errors\nErrorIniEntry=Bd podczas tworzenia pozycji w pliku INI: \"%1\".\n\n; *** File copying errors\nFileAbortRetryIgnore=Moesz ponowi nieudan czynno, zignorowa j, aby omin ten plik (nie zalecane), lub przerwa instalacj.\nFileAbortRetryIgnore2=Moesz ponowi nieudan czynno, zignorowa j (nie zalecane) lub przerwa instalacj.\nSourceIsCorrupted=Plik rdowy jest uszkodzony\nSourceDoesntExist=Plik rdowy \"%1\" nie istnieje\nExistingFileReadOnly=Istniejcy plik jest oznaczony jako tylko-do-odczytu.%n%nMoesz ponowi (aby usun oznaczenie) zignorowa (aby omin ten plik) lub przerwa instalacj.\nErrorReadingExistingDest=Wystpi bd podczas prby odczytu istniejcego pliku:\nFileExists=Plik ju istnieje.%n%nCzy chcesz, aby Instalator zamieni go na nowy?\nExistingFileNewer=Istniejcy plik jest nowszy ni ten, ktry Instalator prbuje skopiowa. Zalecanym jest zachowanie istniejcego pliku.%n%nCzy chcesz zachowa istniejcy plik?\nErrorChangingAttr=Wystpi bd podczas prby zmiany atrybutw docelowego pliku:\nErrorCreatingTemp=Wystpi bd podczas prby utworzenia pliku w folderze docelowym:\nErrorReadingSource=Wystpi bd podczas prby odczytu pliku rdowego:\nErrorCopying=Wystpi bd podczas prby kopiowania pliku:\nErrorReplacingExistingFile=Wystpi bd podczas prby zamiany istniejcego pliku:\nErrorRestartReplace=Prba zastpienia plikw podczas restartu komputera nie powioda si.\nErrorRenamingTemp=Wystpi bd podczas prby zmiany nazwy pliku w folderze docelowym:\nErrorRegisterServer=Nie mona zarejestrowa DLL/OCX: %1\nErrorRegSvr32Failed=Funkcja RegSvr32 zakoczya sie z kodem bdu %1\nErrorRegisterTypeLib=Nie mog zarejestrowa biblioteki typw: %1\n\n; *** Post-installation errors\nErrorOpeningReadme=Wystpi bd podczas prby otwarcia pliku README.\nErrorRestartingComputer=Instalator nie mg zrestartowa tego komputera. Prosz zrobi to samodzielnie.\n\n; *** Uninstaller messages\nUninstallNotFound=Plik \"%1\" nie istnieje. Nie mona go odinstalowa.\nUninstallOpenError=Plik \"%1\" nie mg by otwarty. Nie mona odinstalowa\nUninstallUnsupportedVer=Ta wersja programu deinstalacyjnego nie rozpoznaje formatu logu deinstalacji. Nie mona odinstalowa\nUninstallUnknownEntry=W logu deinstalacji wystpia nieznana pozycja (%1)\nConfirmUninstall=Czy na pewno chcesz usun program %1 i wszystkie jego skadniki?\nUninstallOnlyOnWin64=Ten program moze by odinstalowany tylo w 64 bitowej wersji systemu Windows.\nOnlyAdminCanUninstall=Ta instalacja moe by odinstalowana tylko przez uytkownika z prawami administratora.\nUninstallStatusLabel=Poczekaj a program %1 zostanie usunity z Twojego komputera.\nUninstalledAll=%1 zosta usunity z Twojego komputera.\nUninstalledMost=Odinstalowywanie programu %1 zakoczone.%n%nNiektre elementy nie mogy by usunite. Moesz je usun rcznie.\nUninstalledAndNeedsRestart=Twj komputer musi by ponownie uruchomiony, aby zakoczy odinstalowywanie %1.%n%nCzy chcesz teraz ponownie uruchomi komputer?\nUninstallDataCorrupted=Plik \"%1\" jest uszkodzony. Nie mona odinstalowa\n\n; *** Uninstallation phase messages\nConfirmDeleteSharedFileTitle=Usun plik wspdzielony?\nConfirmDeleteSharedFile2=System wykry, e nastpujcy plik nie jest ju uywany przez aden program. Czy chcesz odinstalowa ten plik wspdzielony?%n%nJeli inne programy nadal uywaj tego pliku, a zostanie on usunity, mog one przesta dziaa prawidowo. Jeli nie jeste pewny, wybierz przycisk Nie. Pozostawienie tego pliku w Twoim systemie nie spowoduje adnych szkd.\nSharedFileNameLabel=Nazwa pliku:\nSharedFileLocationLabel=Pooenie:\nWizardUninstalling=Stan deinstalacji\nStatusUninstalling=Deinstalacja %1...\n\n; *** Shutdown block reasons\t\nShutdownBlockReasonInstallingApp=Intstalacja %1.\nShutdownBlockReasonUninstallingApp=Dezinstalacja %1.\n\n; The custom messages below aren't used by Setup itself, but if you make\n; use of them in your scripts, you'll want to translate them.\n\n[CustomMessages]\n\nNameAndVersion=%1 wersja %2\nAdditionalIcons=Dodatkowe ikony:\nCreateDesktopIcon=Utwrz ikon na &pulpicie\nCreateQuickLaunchIcon=Utwrz ikon na pasku &szybkiego uruchamiania\nProgramOnTheWeb=Strona WWW programu %1\nUninstallProgram=Deinstalacja programu %1\nLaunchProgram=Uruchom program %1\nAssocFileExtension=&Przypisz program %1 do rozszerzenia pliku %2\nAssocingFileExtension=Przypisywanie programu %1 do rozszerzenia pliku %2...\nAutoStartProgramGroupDescription=Autostart:\nAutoStartProgram=Automatycznie uruchamiaj %1\nAddonHostProgramNotFound=%1 nie zosta znaleziony we wskazanym przez Ciebie folderze.%n%nCzy pomimo tego chcesz kontynuowa?\n\n; *** AviSynth+ custom messages\n\nFullInstallation=Instalacja pena\n;CompactInstallation=Recommended installation\nCustomInstallation=Instalacja uytkownika\n\nCmpMain=Podstawa %1\nCmpDocs=Dokumentacja\nCmpDocsEn=Angielska\nCmpDocsCs=Czeska\nCmpDocsFr=Francuska\nCmpDocsDe=Niemiecka\nCmpDocsIt=Woska\nCmpDocsJa=Japoska\nCmpDocsPl=Polska\nCmpDocsPt=Portugalska\nCmpDocsRu=Rosyjska\n;CmpDocsExamples=Scripting Examples\nCmpSdk=FilterSDK\n;CmpMig=Legacy AviSynth Upgrade\n;CmpMigUninstall=Uninstall and move plugins to %1\n;CmpMigBackup=Backup legacy AviSynth\n;CmpCustomizePluginPaths=Customize Plugin Paths\n\n;FileTypeDescAvs=%1 Script\n;FileTypeDescAvsi=%1 Autoload Script\n\n;InstallStatusRuntime = Installing %1 (%2).%nThis may take up to 5 minutes... \n;UninstallStatusLegacyRestore = Restoring legacy AviSynth...\n;BackupRestoreFailed=An error occured while trying to restore your previous AviSynth installation:%n%1\n\n;MigPageCaption=Upgrade Options\n;MigPageDescription=How should %1 handle your existing AviSynth installation?\n;MigPageSubCaption=Setup has detected that AviSynth is already installed in:%n%n%2%n%nAvisynth and %1 cannot be run alongside each other. However, setup can preserve your legacy AviSynth installation in case you want to downgrade later.\n;MigPageOptionBackup=Keep the existing AviSynth program directory and backup its system components overwritten by %1.%n%1 will still load your existing plugins and restore your previous AviSynth installation upon uninstall.\n;MigPageOptionUninstall=Uninstall AviSynth now and migrate compatible plugins to the %1 plugin directory.\n;MigPageUninstallFailed=AviSynth Uninstall failed: %n%1\n \n;PlugPageCaption=%1 Plugin Folders\n;PlugPageDescription=Where should %1 autoload plugins from?\n;PlugPageSubCaption=%1 will install bundled plugins to the its own autoload directory, but also autoload from the legacy plugin directory.\n;PlugPagePlugDirPlus=%2 %1-bit plugin directory:\n;PlugPagePlugDirLegacy=AviSynth %1-bit plugin directory:"
  },
  {
    "path": "distrib/WinInstaller/Translations/pt.isl",
    "content": "; *** Inno Setup version 5.5.3+ Portuguese (Portugal) messages ***\n;\n; Maintained by Nuno Silva (nars AT gmx.net)\n\n[LangOptions]\nLanguageName=Portugu<00EA>s (Portugal)\nLanguageID=$0816\nLanguageCodePage=1252\n\n[Messages]\n\n; *** Application titles\nSetupAppTitle=Instalao\nSetupWindowTitle=%1 - Instalao\nUninstallAppTitle=Desinstalao\nUninstallAppFullTitle=%1 - Desinstalao\n\n; *** Misc. common\nInformationTitle=Informao\nConfirmTitle=Confirmao\nErrorTitle=Erro\n\n; *** SetupLdr messages\nSetupLdrStartupMessage=Ir ser instalado o %1. Deseja continuar?\nLdrCannotCreateTemp=No foi possvel criar um ficheiro temporrio. Instalao cancelada\nLdrCannotExecTemp=No foi possvel executar um ficheiro na directoria temporria. Instalao cancelada\n\n; *** Startup error messages\nLastErrorMessage=%1.%n%nErro %2: %3\nSetupFileMissing=O ficheiro %1 no foi encontrado na pasta de instalao. Corrija o problema ou obtenha uma nova cpia do programa.\nSetupFileCorrupt=Os ficheiros de instalao esto corrompidos. Obtenha uma nova cpia do programa.\nSetupFileCorruptOrWrongVer=Os ficheiros de instalao esto corrompidos, ou so incompatveis com esta verso do Assistente de Instalao. Corrija o problema ou obtenha uma nova cpia do programa.\nInvalidParameter=Foi especificado um parmetro invlido na linha de comando:%n%n%1\nSetupAlreadyRunning=A instalao j est em execuo.\nWindowsVersionNotSupported=Este programa no suporta a verso do Windows que est a utilizar.\nWindowsServicePackRequired=Este programa necessita de %1 Service Pack %2 ou mais recente.\nNotOnThisPlatform=Este programa no pode ser executado no %1.\nOnlyOnThisPlatform=Este programa deve ser executado no %1.\nOnlyOnTheseArchitectures=Este programa s pode ser instalado em verses do Windows preparadas para as seguintes arquitecturas:%n%n%1\nMissingWOW64APIs=A verso do Windows que est a utilizar no dispe das funcionalidades necessrias para o Assistente de Instalao poder realizar uma instalao de 64-bit's. Para corrigir este problema, por favor instale o Service Pack %1.\nWinVersionTooLowError=Este programa necessita do %1 verso %2 ou mais recente.\nWinVersionTooHighError=Este programa no pode ser instalado no %1 verso %2 ou mais recente.\nAdminPrivilegesRequired=Deve iniciar sesso como administrador para instalar este programa.\nPowerUserPrivilegesRequired=Deve iniciar sesso como administrador ou membro do grupo de Super Utilizadores para instalar este programa.\nSetupAppRunningError=O Assistente de Instalao detectou que o %1 est em execuo. Feche-o e de seguida clique em OK para continuar, ou clique em Cancelar para cancelar a instalao.\nUninstallAppRunningError=O Assistente de Desinstalao detectou que o %1 est em execuo. Feche-o e de seguida clique em OK para continuar, ou clique em Cancelar para cancelar a desinstalao.\n\n; *** Misc. errors\nErrorCreatingDir=O Assistente de Instalao no consegue criar a directoria \"%1\"\nErrorTooManyFilesInDir=No  possvel criar um ficheiro na directoria \"%1\" porque esta contm demasiados ficheiros\n\n; *** Setup common messages\nExitSetupTitle=Terminar a instalao\nExitSetupMessage=A instalao no est completa. Se terminar agora, o programa no ser instalado.%n%nMais tarde poder executar novamente este Assistente de Instalao e concluir a instalao.%n%nDeseja terminar a instalao?\nAboutSetupMenuItem=&Acerca de...\nAboutSetupTitle=Acerca do Assistente de Instalao\nAboutSetupMessage=%1 verso %2%n%3%n%n%1 home page:%n%4\nAboutSetupNote=\nTranslatorNote=Portuguese translation maintained by NARS (nars@gmx.net)\n\n; *** Buttons\nButtonBack=< &Anterior\nButtonNext=&Seguinte >\nButtonInstall=&Instalar\nButtonOK=OK\nButtonCancel=Cancelar\nButtonYes=&Sim\nButtonYesToAll=Sim para &todos\nButtonNo=&No\nButtonNoToAll=N&o para todos\nButtonFinish=&Concluir\nButtonBrowse=&Procurar...\nButtonWizardBrowse=P&rocurar...\nButtonNewFolder=&Criar Nova Pasta\n\n; *** \"Select Language\" dialog messages\nSelectLanguageTitle=Seleccione o Idioma do Assistente de Instalao\nSelectLanguageLabel=Seleccione o idioma para usar durante a Instalao:\n\n; *** Common wizard text\nClickNext=Clique em Seguinte para continuar ou em Cancelar para cancelar a instalao.\nBeveledLabel=\nBrowseDialogTitle=Procurar Pasta\nBrowseDialogLabel=Seleccione uma pasta na lista abaixo e clique em OK.\nNewFolderName=Nova Pasta\n\n; *** \"Welcome\" wizard page\nWelcomeLabel1=Bem-vindo ao Assistente de Instalao do [name]\nWelcomeLabel2=O Assistente de Instalao ir instalar o [name/ver] no seu computador.%n%n recomendado que feche todas as outras aplicaes antes de continuar.\n\n; *** \"Password\" wizard page\nWizardPassword=Palavra-passe\nPasswordLabel1=Esta instalao est protegida por palavra-passe.\nPasswordLabel3=Insira a palavra-passe e de seguida clique em Seguinte para continuar. Na palavra-passe existe diferena entre maisculas e minsculas.\nPasswordEditLabel=&Palavra-passe:\nIncorrectPassword=A palavra-passe que introduziu no est correcta. Tente novamente.\n\n; *** \"License Agreement\" wizard page\nWizardLicense=Contrato de licena\nLicenseLabel= importante que leia as seguintes informaes antes de continuar.\nLicenseLabel3=Leia atentamente o seguinte contrato de licena. Deve aceitar os termos do contrato antes de continuar a instalao.\nLicenseAccepted=A&ceito o contrato\nLicenseNotAccepted=&No aceito o contrato\n\n; *** \"Information\" wizard pages\nWizardInfoBefore=Informao\nInfoBeforeLabel= importante que leia as seguintes informaes antes de continuar.\nInfoBeforeClickLabel=Quando estiver pronto para continuar clique em Seguinte.\nWizardInfoAfter=Informao\nInfoAfterLabel= importante que leia as seguintes informaes antes de continuar.\nInfoAfterClickLabel=Quando estiver pronto para continuar clique em Seguinte.\n\n; *** \"User Information\" wizard page\nWizardUserInfo=Informaes do utilizador\nUserInfoDesc=Introduza as suas informaes.\nUserInfoName=Nome do &utilizador:\nUserInfoOrg=&Organizao:\nUserInfoSerial=&Nmero de srie:\nUserInfoNameRequired=Deve introduzir um nome.\n\n; *** \"Select Destination Location\" wizard page\nWizardSelectDir=Seleccione a localizao de destino\nSelectDirDesc=Onde dever ser instalado o [name]?\nSelectDirLabel3=O [name] ser instalado na seguinte pasta.\nSelectDirBrowseLabel=Para continuar, clique em Seguinte. Se desejar seleccionar uma pasta diferente, clique em Procurar.\nDiskSpaceMBLabel= necessrio pelo menos [mb] MB de espao livre em disco.\nCannotInstallToNetworkDrive=O Assistente de Instalao no pode instalar numa unidade de rede.\nCannotInstallToUNCPath=O Assistente de Instalao no pode instalar num caminho UNC.\nInvalidPath= necessrio indicar o caminho completo com a letra de unidade; por exemplo:%n%nC:\\APP%n%nou um caminho UNC no formato:%n%n\\\\servidor\\partilha\nInvalidDrive=A unidade ou partilha UNC seleccionada no existe ou no est acessvel. Seleccione outra.\nDiskSpaceWarningTitle=No h espao suficiente no disco\nDiskSpaceWarning=O Assistente de Instalao necessita de pelo menos %1 KB de espao livre, mas a unidade seleccionada tem apenas %2 KB disponveis.%n%nDeseja continuar de qualquer forma?\nDirNameTooLong=O nome ou caminho para a pasta  demasiado longo.\nInvalidDirName=O nome da pasta no  vlido.\nBadDirName32=O nome da pasta no pode conter nenhum dos seguintes caracteres:%n%n%1\nDirExistsTitle=A pasta j existe\nDirExists=A pasta:%n%n%1%n%nj existe. Pretende instalar nesta pasta?\nDirDoesntExistTitle=A pasta no existe\nDirDoesntExist=A pasta:%n%n%1%n%nno existe. Pretende que esta pasta seja criada?\n\n; *** \"Select Components\" wizard page\nWizardSelectComponents=Seleccione os componentes\nSelectComponentsDesc=Que componentes devero ser instalados?\nSelectComponentsLabel2=Seleccione os componentes que quer instalar e desseleccione os componentes que no quer instalar. Clique em Seguinte quando estiver pronto para continuar.\nFullInstallation=Instalao Completa\n; if possible don't translate 'Compact' as 'Minimal' (I mean 'Minimal' in your language)\nCompactInstallation=Instalao Compacta\nCustomInstallation=Instalao Personalizada\nNoUninstallWarningTitle=Componentes Encontrados\nNoUninstallWarning=O Assistente de Instalao detectou que os seguintes componentes esto instalados no seu computador:%n%n%1%n%nSe desseleccionar estes componentes eles no sero desinstalados.%n%nDeseja continuar?\nComponentSize1=%1 KB\nComponentSize2=%1 MB\nComponentsDiskSpaceMBLabel=A seleco actual necessita de pelo menos [mb] MB de espao em disco.\n\n; *** \"Select Additional Tasks\" wizard page\nWizardSelectTasks=Seleccione tarefas adicionais\nSelectTasksDesc=Que tarefas adicionais devero ser executadas?\nSelectTasksLabel2=Seleccione as tarefas adicionais que deseja que o Assistente de Instalao execute na instalao do [name] e em seguida clique em Seguinte.\n\n; *** \"Select Start Menu Folder\" wizard page\nWizardSelectProgramGroup=Seleccione a pasta do Menu Iniciar\nSelectStartMenuFolderDesc=Onde devero ser colocados os cones de atalho do programa?\nSelectStartMenuFolderLabel3=Os cones de atalho do programa sero criados na seguinte pasta do Menu Iniciar.\nSelectStartMenuFolderBrowseLabel=Para continuar, clique em Seguinte. Se desejar seleccionar uma pasta diferente, clique em Procurar.\nMustEnterGroupName= necessrio introduzir um nome para a pasta.\nGroupNameTooLong=O nome ou caminho para a pasta  demasiado longo.\nInvalidGroupName=O nome da pasta no  vlido.\nBadGroupName=O nome da pasta no pode conter nenhum dos seguintes caracteres:%n%n%1\nNoProgramGroupCheck2=&No criar nenhuma pasta no Menu Iniciar\n\n; *** \"Ready to Install\" wizard page\nWizardReady=Pronto para Instalar\nReadyLabel1=O Assistente de Instalao est pronto para instalar o [name] no seu computador.\nReadyLabel2a=Clique em Instalar para continuar a instalao, ou clique em Anterior se desejar rever ou alterar alguma das configuraes.\nReadyLabel2b=Clique em Instalar para continuar a instalao.\nReadyMemoUserInfo=Informaes do utilizador:\nReadyMemoDir=Localizao de destino:\nReadyMemoType=Tipo de instalao:\nReadyMemoComponents=Componentes seleccionados:\nReadyMemoGroup=Pasta do Menu Iniciar:\nReadyMemoTasks=Tarefas adicionais:\n\n; *** \"Preparing to Install\" wizard page\nWizardPreparing=Preparando-se para instalar\nPreparingDesc=Preparando-se para instalar o [name] no seu computador.\nPreviousInstallNotCompleted=A instalao/remoo de um programa anterior no foi completada. Necessitar de reiniciar o computador para completar essa instalao.%n%nDepois de reiniciar o computador, execute novamente este Assistente de Instalao para completar a instalao do [name].\nCannotContinue=A instalao no pode continuar. Clique em Cancelar para sair.\nApplicationsFound=As seguintes aplicaes esto a utilizar ficheiros que necessitam ser actualizados pelo Assistente de Instalao.  recomendado que permita que o Assistente de Instalao feche estas aplicaes.\nApplicationsFound2=As seguintes aplicaes esto a utilizar ficheiros que necessitam ser actualizados pelo Assistente de Instalao.  recomendado que permita que o Assistente de Instalao feche estas aplicaes. Depois de completar a instalao, o Assistente de Instalao tentar reiniciar as aplicaes.\nCloseApplications=&Fechar as aplicaes automaticamente\nDontCloseApplications=&No fechar as aplicaes\nErrorCloseApplications=O Assistente de Instalao no conseguiu fechar todas as aplicaes automaticamente. Antes de continuar  recomendado que feche todas as aplicaes que utilizem ficheiros que necessitem de ser actualizados pelo Assistente de Instalao.\n\n; *** \"Installing\" wizard page\nWizardInstalling=A instalar\nInstallingLabel=Aguarde enquanto o Assistente de Instalao instala o [name] no seu computador.\n\n; *** \"Setup Completed\" wizard page\nFinishedHeadingLabel=Instalao do [name] concluda\nFinishedLabelNoIcons=O Assistente de Instalao concluiu a instalao do [name] no seu computador.\nFinishedLabel=O Assistente de Instalao concluiu a instalao do [name] no seu computador. A aplicao pode ser iniciada atravs dos cones instalados.\nClickFinish=Clique em Concluir para finalizar o Assistente de Instalao.\nFinishedRestartLabel=Para completar a instalao do [name], o Assistente de Instalao dever reiniciar o seu computador. Deseja reiniciar agora?\nFinishedRestartMessage=Para completar a instalao do [name], o Assistente de Instalao dever reiniciar o seu computador.%n%nDeseja reiniciar agora?\nShowReadmeCheck=Sim, desejo ver o ficheiro LEIAME\nYesRadio=&Sim, desejo reiniciar o computador agora\nNoRadio=&No, desejo reiniciar o computador mais tarde\n; used for example as 'Run MyProg.exe'\nRunEntryExec=Executar %1\n; used for example as 'View Readme.txt'\nRunEntryShellExec=Visualizar %1\n\n; *** \"Setup Needs the Next Disk\" stuff\nChangeDiskTitle=O Assistente de Instalao precisa do disco seguinte\nSelectDiskLabel2=Introduza o disco %1 e clique em OK.%n%nSe os ficheiros deste disco estiverem num local diferente do mostrado abaixo, indique o caminho correcto ou clique em Procurar.\nPathLabel=&Caminho:\nFileNotInDir2=O ficheiro \"%1\" no foi encontrado em \"%2\". Introduza o disco correcto ou seleccione outra pasta.\nSelectDirectoryLabel=Indique a localizao do disco seguinte.\n\n; *** Installation phase messages\nSetupAborted=A instalao no est completa.%n%nCorrija o problema e execute o Assistente de Instalao novamente.\nEntryAbortRetryIgnore=Clique em Repetir para tentar novamente, Ignorar para continuar de qualquer forma, ou Abortar para cancelar a instalao.\n\n; *** Installation status messages\nStatusClosingApplications=A fechar aplicaes...\nStatusCreateDirs=A criar directorias...\nStatusExtractFiles=A extrair ficheiros...\nStatusCreateIcons=A criar atalhos...\nStatusCreateIniEntries=A criar entradas em INI...\nStatusCreateRegistryEntries=A criar entradas no registo...\nStatusRegisterFiles=A registar ficheiros...\nStatusSavingUninstall=A guardar informaes para desinstalao...\nStatusRunProgram=A concluir a instalao...\nStatusRestartingApplications=A reiniciar aplicaes...\nStatusRollback=A anular as alteraes...\n\n; *** Misc. errors\nErrorInternal2=Erro interno: %1\nErrorFunctionFailedNoCode=%1 falhou\nErrorFunctionFailed=%1 falhou; cdigo %2\nErrorFunctionFailedWithMessage=%1 falhou; cdigo %2.%n%3\nErrorExecutingProgram=No  possvel executar o ficheiro:%n%1\n\n; *** Registry errors\nErrorRegOpenKey=Erro ao abrir a chave de registo:%n%1\\%2\nErrorRegCreateKey=Erro ao criar a chave de registo:%n%1\\%2\nErrorRegWriteKey=Erro ao escrever na chave de registo:%n%1\\%2\n\n; *** INI errors\nErrorIniEntry=Erro ao criar entradas em INI no ficheiro \"%1\".\n\n; *** File copying errors\nFileAbortRetryIgnore=Clique em Repetir para tentar novamente, Ignorar para ignorar este ficheiro (no recomendado), ou Abortar para cancelar a instalao.\nFileAbortRetryIgnore2=Clique em Repetir para tentar novamente, Ignorar para continuar de qualquer forma (no recomendado), ou Abortar para cancelar a instalao.\nSourceIsCorrupted=O ficheiro de origem est corrompido\nSourceDoesntExist=O ficheiro de origem \"%1\" no existe\nExistingFileReadOnly=O ficheiro existente tem o atributo \"s de leitura\".%n%nClique em Repetir para remover o atributo \"s de leitura\" e tentar novamente, Ignorar para ignorar este ficheiro, ou Abortar para cancelar a instalao.\nErrorReadingExistingDest=Ocorreu um erro ao tentar ler o ficheiro existente:\nFileExists=O ficheiro j existe.%n%nDeseja substitu-lo?\nExistingFileNewer=O ficheiro existente  mais recente que o que est a ser instalado.  recomendado que mantenha o ficheiro existente.%n%nDeseja manter o ficheiro existente?\nErrorChangingAttr=Ocorreu um erro ao tentar alterar os atributos do ficheiro existente:\nErrorCreatingTemp=Ocorreu um erro ao tentar criar um ficheiro na directoria de destino:\nErrorReadingSource=Ocorreu um erro ao tentar ler o ficheiro de origem:\nErrorCopying=Ocorreu um erro ao tentar copiar um ficheiro:\nErrorReplacingExistingFile=Ocorreu um erro ao tentar substituir o ficheiro existente:\nErrorRestartReplace=RestartReplace falhou:\nErrorRenamingTemp=Ocorreu um erro ao tentar mudar o nome de um ficheiro na directoria de destino:\nErrorRegisterServer=No  possvel registar o DLL/OCX: %1\nErrorRegSvr32Failed=O RegSvr32 falhou com o cdigo de sada %1\nErrorRegisterTypeLib=No foi possvel registar a livraria de tipos: %1\n\n; *** Post-installation errors\nErrorOpeningReadme=Ocorreu um erro ao tentar abrir o ficheiro LEIAME.\nErrorRestartingComputer=O Assistente de Instalao no consegue reiniciar o computador. Por favor reinicie manualmente.\n\n; *** Uninstaller messages\nUninstallNotFound=O ficheiro \"%1\" no existe. No  possvel desinstalar.\nUninstallOpenError=No foi possvel abrir o ficheiro \"%1\". No  possvel desinstalar.\nUninstallUnsupportedVer=O ficheiro log de desinstalao \"%1\" est num formato que no  reconhecido por esta verso do desinstalador. No  possvel desinstalar\nUninstallUnknownEntry=Foi encontrada uma entrada desconhecida (%1) no ficheiro log de desinstalao\nConfirmUninstall=Tem a certeza que deseja remover completamente o %1 e todos os seus componentes?\nUninstallOnlyOnWin64=Esta desinstalao s pode ser realizada na verso de 64-bit's do Windows.\nOnlyAdminCanUninstall=Esta desinstalao s pode ser realizada por um utilizador com privilgios administrativos.\nUninstallStatusLabel=Por favor aguarde enquanto o %1 est a ser removido do seu computador.\nUninstalledAll=O %1 foi removido do seu computador com sucesso.\nUninstalledMost=A desinstalao do %1 est concluda.%n%nAlguns elementos no puderam ser removidos. Estes elementos podem ser removidos manualmente.\nUninstalledAndNeedsRestart=Para completar a desinstalao do %1, o computador deve ser reiniciado.%n%nDeseja reiniciar agora?\nUninstallDataCorrupted=O ficheiro \"%1\" est corrompido. No  possvel desinstalar\n\n; *** Uninstallation phase messages\nConfirmDeleteSharedFileTitle=Remover ficheiro partilhado?\nConfirmDeleteSharedFile2=O sistema indica que o seguinte ficheiro partilhado j no est a ser utilizado por nenhum programa. Deseja remov-lo?%n%nSe algum programa ainda necessitar deste ficheiro, poder no funcionar correctamente depois de o remover. Se no tiver a certeza, seleccione No. Manter o ficheiro no causar nenhum problema.\nSharedFileNameLabel=Nome do ficheiro:\nSharedFileLocationLabel=Localizao:\nWizardUninstalling=Estado da desinstalao\nStatusUninstalling=A desinstalar o %1...\n\n; *** Shutdown block reasons\nShutdownBlockReasonInstallingApp=A instalar %1.\nShutdownBlockReasonUninstallingApp=A desinstalar %1.\n\n; The custom messages below aren't used by Setup itself, but if you make\n; use of them in your scripts, you'll want to translate them.\n\n[CustomMessages]\n\nNameAndVersion=%1 verso %2\nAdditionalIcons=cones adicionais:\nCreateDesktopIcon=Criar cone no Ambiente de &Trabalho\nCreateQuickLaunchIcon=&Criar cone na barra de Iniciao Rpida\nProgramOnTheWeb=%1 na Web\nUninstallProgram=Desinstalar o %1\nLaunchProgram=Executar o %1\nAssocFileExtension=Associa&r o %1 aos ficheiros com a extenso %2\nAssocingFileExtension=A associar o %1 aos ficheiros com a extenso %2...\nAutoStartProgramGroupDescription=Inicializao Automtica:\nAutoStartProgram=Iniciar %1 automaticamente\nAddonHostProgramNotFound=No foi possvel localizar %1 na pasta seleccionada.%n%nDeseja continuar de qualquer forma?\n\n; *** AviSynth+ custom messages\n\nFullInstallation=Instalao Completa\n;CompactInstallation=Recommended installation\nCustomInstallation=Instalao Personalizada\n\nCmpMain=%1 Bsico\nCmpDocs=Documentao\nCmpDocsEn=Ingls\nCmpDocsCs=Tcheco\nCmpDocsFr=Francs\nCmpDocsDe=Alemo\nCmpDocsIt=Italiano\nCmpDocsJa=Japons\nCmpDocsPl=Polons\nCmpDocsPt=Portugus\nCmpDocsRu=Russo\n;CmpDocsExamples=Scripting Examples\nCmpSdk=FilterSDK\n;CmpMig=Legacy AviSynth Upgrade\n;CmpMigUninstall=Uninstall and move plugins to %1\n;CmpMigBackup=Backup legacy AviSynth\n;CmpCustomizePluginPaths=Customize Plugin Paths\n\n;FileTypeDescAvs=%1 Script\n;FileTypeDescAvsi=%1 Autoload Script\n\n;InstallStatusRuntime = Installing %1 (%2).%nThis may take up to 5 minutes... \n;UninstallStatusLegacyRestore = Restoring legacy AviSynth...\n;BackupRestoreFailed=An error occured while trying to restore your previous AviSynth installation:%n%1\n\n;MigPageCaption=Upgrade Options\n;MigPageDescription=How should %1 handle your existing AviSynth installation?\n;MigPageSubCaption=Setup has detected that AviSynth is already installed in:%n%n%2%n%nAvisynth and %1 cannot be run alongside each other. However, setup can preserve your legacy AviSynth installation in case you want to downgrade later.\n;MigPageOptionBackup=Keep the existing AviSynth program directory and backup its system components overwritten by %1.%n%1 will still load your existing plugins and restore your previous AviSynth installation upon uninstall.\n;MigPageOptionUninstall=Uninstall AviSynth now and migrate compatible plugins to the %1 plugin directory.\n;MigPageUninstallFailed=AviSynth Uninstall failed: %n%1\n \n;PlugPageCaption=%1 Plugin Folders\n;PlugPageDescription=Where should %1 autoload plugins from?\n;PlugPageSubCaption=%1 will install bundled plugins to the its own autoload directory, but also autoload from the legacy plugin directory.\n;PlugPagePlugDirPlus=%2 %1-bit plugin directory:\n;PlugPagePlugDirLegacy=AviSynth %1-bit plugin directory:"
  },
  {
    "path": "distrib/WinInstaller/Translations/pt_br.isl",
    "content": "; ***************************************************************\n; ***                                                         ***\n; *** Inno Setup version 5.5.3+ Portuguese (Brazil) messages ***\n; ***                                                         ***\n; *** Original Author:                                        ***\n; ***                                                         ***\n; ***   Paulo Andre Rosa (parosa@gmail.com)                   ***\n; ***                                                         ***\n; *** Maintainer:                                             ***\n; ***                                                         ***\n; ***   Eduardo Mauro (emauro@acabit.com.br)                  ***\n; ***                                                         ***\n; *** Contributors:                                           ***\n; ***                                                         ***\n; ***   Felipe (felipefpl@ig.com.br)                          ***\n; ***   Jeferson Oliveira (jefersonfoliveira@gmail.com)       ***\n; ***                                                         ***\n; ***************************************************************\n\n; To download user-contributed translations of this file, go to:\n;   http://www.jrsoftware.org/is3rdparty.php\n;\n; Note: When translating this text, do not add periods (.) to the end of\n; messages that didn't have them already, because on those messages Inno\n; Setup adds the periods automatically (appending a period would result in\n; two periods being displayed).\n\n[LangOptions]\n; The following three entries are very important. Be sure to read and \n; understand the '[LangOptions] section' topic in the help file.\nLanguageName=Portugu<00EA>s (Brasil)\nLanguageID=$0416\nLanguageCodePage=1252\n\n; If the language you are translating to requires special font faces or\n; sizes, uncomment any of the following entries and change them accordingly.\n;DialogFontName=\n;DialogFontSize=8\n;WelcomeFontName=Verdana\n;WelcomeFontSize=12\n;TitleFontName=Arial\n;TitleFontSize=29\n;CopyrightFontName=Arial\n;CopyrightFontSize=8\n\n[Messages]\n\n; *** Application titles\nSetupAppTitle=Programa de Instalao\nSetupWindowTitle=%1 - Programa de Instalao\nUninstallAppTitle=Desinstalar\nUninstallAppFullTitle=Desinstalar %1\n\n; *** Misc. common\nInformationTitle=Informao\nConfirmTitle=Confirmao\nErrorTitle=Erro\n\n; *** SetupLdr messages\nSetupLdrStartupMessage=Este programa instalar %1. Voc quer continuar?\nLdrCannotCreateTemp=No foi possvel criar um arquivo temporrio. Instalao cancelada\nLdrCannotExecTemp=No foi possvel executar um arquivo na pasta de arquivos temporrios. Instalao cancelada\n\n; *** Startup error messages\nLastErrorMessage=%1.%n%nErro %2: %3\nSetupFileMissing=O arquivo %1 no se encontra no diretrio de instalao. Por favor, corrija o problema ou obtenha uma nova cpia do programa.\nSetupFileCorrupt=Os arquivos de instalao esto corrompidos. Por favor, obtenha uma nova cpia do programa.\nSetupFileCorruptOrWrongVer=Os arquivos de instalao esto corrompidos ou so incompatveis com esta verso do Instalador. Por favor, corrija o problema ou obtenha uma nova cpia do programa.\nInvalidParameter=Um parmetro invlido foi passado na linha de comando:%n%n%1\nSetupAlreadyRunning=O programa de instalao j est sendo executado.\nWindowsVersionNotSupported=Este programa no suporta a verso do Windows instalada em seu computador.\nWindowsServicePackRequired=Este programa necessita %1 Service Pack %2 ou posterior.\nNotOnThisPlatform=Este programa no executar no %1.\nOnlyOnThisPlatform=Este programa deve ser executado no %1.\nOnlyOnTheseArchitectures=Este programa s pode ser instalado em verses do Windows projetadas para as seguintes arquiteturas de processador:%n%n%1\nMissingWOW64APIs=A verso do Windows que voc est executando no inclui a funcionalidade requerida pelo Programa de Instalao para realizar uma instalao de 64 bits. Para corrigir este problema, por favor instale o Service Pack %1.\nWinVersionTooLowError=Este programa requer %1 verso %2 ou posterior.\nWinVersionTooHighError=Este programa no pode ser instalado em %1 verso %2 ou posterior.\nAdminPrivilegesRequired=Voc deve estar logado como um administrador para instalar este programa.\nPowerUserPrivilegesRequired=Voc deve estar logado como um administrador ou como membro do grupo Usurios Avanados para instalar este programa.\nSetupAppRunningError=O Programa de Instalao detectou que %1 est sendo executado.%n%nPor favor, feche todas as instncias do programa agora e clique em OK para continuar, ou em Cancelar para sair.\nUninstallAppRunningError=O Desinstalador detectou que %1 est em execuo atualmente.%n%nPor favor, feche todas as instncias dele agora, ento clique em OK para continuar, ou em Cancelar para sair.\n\n; *** Misc. errors\nErrorCreatingDir=O Programa de Instalao foi incapaz de criar o diretrio \"%1\"\nErrorTooManyFilesInDir=Incapaz de criar um arquivo no diretrio \"%1\" porque ele contm arquivos demais\n\n; *** Setup common messages\nExitSetupTitle=Sair do Programa de Instalao\nExitSetupMessage=A Instalao no foi concluda. Se voc sair agora, o programa no ser instalado.%n%nVoc pode executar o Programa de instalao novamente em outra hora, para concluir a instalao.%n%nSair do Programa de Instalao?\nAboutSetupMenuItem=&Sobre o Programa de Instalao...\nAboutSetupTitle=Sobre o Programa de Instalao\nAboutSetupMessage=%1 verso %2%n%3%n%n%1 pgina na internet:%n%4\nAboutSetupNote=\nTranslatorNote=\n\n; *** Buttons\nButtonBack=< &Voltar\nButtonNext=&Avanar >\nButtonInstall=&Instalar\nButtonOK=OK\nButtonCancel=Cancelar\nButtonYes=&Sim\nButtonYesToAll=Sim para &Todos\nButtonNo=&No\nButtonNoToAll=N&o para Todos\nButtonFinish=&Concluir\nButtonBrowse=&Procurar...\nButtonWizardBrowse=P&rocurar...\nButtonNewFolder=&Criar Nova Pasta\n\n; *** \"Select Language\" dialog messages\nSelectLanguageTitle=Selecionar Idioma do Programa de Instalao\nSelectLanguageLabel=Selecione o idioma a ser utilizado durante a instalao:\n\n; *** Common wizard text\nClickNext=Clique em Avanar para continuar, ou em Cancelar para sair do Programa de Instalao.\nBeveledLabel=\nBrowseDialogTitle=Procurar Pasta\nBrowseDialogLabel=Selecione uma pasta na lista abaixo e clique em OK.\nNewFolderName=Nova Pasta\n\n; *** \"Welcome\" wizard page\nWelcomeLabel1=Bem-vindo ao Assistente de Instalao de [name]\nWelcomeLabel2=Este Assistente instalar [name/ver] no seu computador.%n%n recomendado que voc feche todos os outros aplicativos antes de continuar.\n\n; *** \"Password\" wizard page\nWizardPassword=Senha\nPasswordLabel1=Esta instalao  protegida por senha.\nPasswordLabel3=Por favor, fornea a senha e clique em Avanar para continuar. As senhas diferenciam maisculas de minsculas.\nPasswordEditLabel=&Senha:\nIncorrectPassword=A senha que voc informou no  correta. Por favor, tente novamente.\n\n; *** \"License Agreement\" wizard page\nWizardLicense=Contrato de Licena de Uso\nLicenseLabel=Por favor, leia as seguintes informaes importantes antes de continuar.\nLicenseLabel3=Por favor, leia o seguinte Contrato de Licena de Uso. Voc deve aceitar os termos do Contrato antes de prosseguir com a instalao.\nLicenseAccepted=Eu aceito os termos do &Contrato\nLicenseNotAccepted=Eu &no aceito os termos do Contrato\n\n; *** \"Information\" wizard pages\nWizardInfoBefore=Informao\nInfoBeforeLabel=Por favor, leia as seguintes informaes importantes antes de continuar.\nInfoBeforeClickLabel=Quando voc estiver pronto para continuar, clique em Avanar.\nWizardInfoAfter=Informao\nInfoAfterLabel=Por favor, leia as seguintes informaes importantes antes de continuar.\nInfoAfterClickLabel=Quando voc estiver pronto para continuar, clique Avanar.\n\n; *** \"User Information\" wizard page\nWizardUserInfo=Informaes do Usurio\nUserInfoDesc=Por favor, insira suas informaes.\nUserInfoName=&Nome do Usurio:\nUserInfoOrg=&Empresa:\nUserInfoSerial=Nmero de &Srie:\nUserInfoNameRequired=Voc deve informar um nome.\n\n; *** \"Select Destination Location\" wizard page\nWizardSelectDir=Selecione o Local de Destino\nSelectDirDesc=Onde [name] deve ser instalado?\nSelectDirLabel3=O Programa de Instalao instalar [name] na seguinte pasta.\nSelectDirBrowseLabel=Para continuar, clique em Avanar. Se voc deseja escolher uma pasta diferente, clique em Procurar.\nDiskSpaceMBLabel=So necessrios pelo menos [mb] MB de espao livre em disco.\nCannotInstallToNetworkDrive=O programa de instalao no pode fazer a instalao em uma unidade de rede.\nCannotInstallToUNCPath=O programa de instalao no fazer a instalao num caminhho de rede UNC.\nInvalidPath=Voc deve informar um caminho completo, incluindo a letra da unidade de disco; por exemplo:%n%nC:\\APP%n%e no um caminho de rede UNC na forma:%n%n\\\\servidor\\compartilhamento\nInvalidDrive=A unidade de disco ou compartilhamento de rede UNC que voc selecionou no existe ou no est acessvel. Por favor, selecione outro local.\nDiskSpaceWarningTitle=Espao em Disco Insuficiente\nDiskSpaceWarning=O Programa de Instalao requer pelo menos %1 KB de espao livre, mas a unidade de disco selecionada tem apenas %2 KB disponveis.%n%nVoc quer continuar assim mesmo?\nDirNameTooLong=O nome da pasta ou caminho  muito longo.\nInvalidDirName=O nome da pasta no  vlido.\nBadDirName32=Nomes de pastas no podem incluir quaisquer dos seguintes caracteres:%n%n%1\nDirExistsTitle=A Pasta Existe\nDirExists=A pasta:%n%n%1%n%nj existe. Voc quer instalar nesta pasta assim mesmo?\nDirDoesntExistTitle=A Pasta No Existe\nDirDoesntExist=A pasta:%n%n%1%n%nno existe. Voc gostaria que a pasta fosse criada?\n\n; *** \"Select Components\" wizard page\nWizardSelectComponents=Selecionar Componentes\nSelectComponentsDesc=Quais componentes devem ser instalados?\nSelectComponentsLabel2=Selecione os componentes que voc quer instalar; desmarque os componentes que voc no quer instalar. Clique em Avanar quando estiver pronto para continuar.\nFullInstallation=Instalao completa\n; if possible don't translate 'Compact' as 'Minimal' (I mean 'Minimal' in your language)\nCompactInstallation=Instalao compacta\nCustomInstallation=Instalao personalizada\nNoUninstallWarningTitle=Componente Existe\nNoUninstallWarning=O Programa de Instalao detectou que os seguintes componentes j esto instalados em seu computador:%n%n%1%n%nDesmarcar estes componentes, no ir desinstalar eles.%n%nVoc quer continuar assim mesmo?\nComponentSize1=%1 KB\nComponentSize2=%1 MB\nComponentsDiskSpaceMBLabel=A seleo atual requer pelo menos [mb] MB de espao em disco.\n\n; *** \"Select Additional Tasks\" wizard page\nWizardSelectTasks=Selecionar Tarefas Adicionais\nSelectTasksDesc=Quais tarefas adicionais devem ser executadas?\nSelectTasksLabel2=Selecione as tarefas adicionais que voc deseja que o Programa de Instalao execute enquanto instala [name] e clique em Avanar.\n\n; *** \"Select Start Menu Folder\" wizard page\nWizardSelectProgramGroup=Selecionar a Pasta do Menu Iniciar\nSelectStartMenuFolderDesc=Onde o Programa de Instalao deve colocar os atalhos do programa?\nSelectStartMenuFolderLabel3=O Programa de Instalao ir criar os atalhos do programa na seguinte pasta do Menu Iniciar.\nSelectStartMenuFolderBrowseLabel=Clique em Avanar para continuar. Se voc quiser escolher outra pasta, clique em Procurar.\nMustEnterGroupName=Voc deve informar um nome de pasta.\nGroupNameTooLong=O nome da pasta ou caminho  muito longo.\nInvalidGroupName=O nome da pasta no  vlido.\nBadGroupName=O nome da pasta no pode incluir quaisquer dos seguintes caracteres:%n%n%1\nNoProgramGroupCheck2=&No criar uma pasta no Menu Iniciar\n\n; *** \"Ready to Install\" wizard page\nWizardReady=Pronto para Instalar\nReadyLabel1=O Programa de Instalao est pronto para comear a instalao de [name] no seu computador.\nReadyLabel2a=Clique Instalar para iniciar a instalao, ou clique em Voltar se voc quer revisar ou alterar alguma configurao.\nReadyLabel2b=Clique em Instalar para iniciar a instalao.\nReadyMemoUserInfo=Dados do Usurio:\nReadyMemoDir=Local de destino:\nReadyMemoType=Tipo de Instalao:\nReadyMemoComponents=Componentes selecionados:\nReadyMemoGroup=Pasta do Menu Iniciar:\nReadyMemoTasks=Tarefas adicionais:\n\n; *** \"Preparing to Install\" wizard page\nWizardPreparing=Preparando para Instalar\nPreparingDesc=O Programa de Instalao est se preparando para instalar [name] no seu computador.\nPreviousInstallNotCompleted=A instalao/remoo de um programa anterior no foi concluda. Voc precisar reiniciar seu computador para finaliz-la.%n%nAps reiniciar o computador, execute novamente o Programa de Instalao para concluir a instalao de [name].\nCannotContinue=O Programa de Instalao no pode continuar. Por favor, clique em Cancelar para sair.\nApplicationsFound=As seguintes aplicaes estap usando arquivos que necessitam ser atualizados pelo programa de instalao.  recomendvel que voc permita que o programa da instalao encerre automaticamente estas aplicaes.\nApplicationsFound2=As seguintes aplicaes esto usandos arquivos que necessitam ser atualizados pelo programa de instalao.  recomendvel que voc permita que o programa da instalao encerre automaticamente estas aplicaes. Aps a instalao estar completa, o programa de instalao tentar iniciar novamente as aplicaes.\nCloseApplications=&Automaticamente encerre as aplicaes\nDontCloseApplications=&No encerre as aplicaes\nErrorCloseApplications=O instalador foi incapaz de fechar automaticamente todos os aplicativos.  recomendado que voc feche todos os aplicativos usando os arquivos que precisam ser atualizados pelo Instalador antes de continuar.\n\n; *** \"Installing\" wizard page\nWizardInstalling=Instalando\nInstallingLabel=Por favor, aguarde enquanto o Programa de Instalao instala [name] no seu computador.\n\n; *** \"Setup Completed\" wizard page\nFinishedHeadingLabel=Finalizando o Assistente de Instalao de [name]\nFinishedLabelNoIcons=O Programa de Instalao finalizou a instalao de [name] no seu computador.\nFinishedLabel=O Programa de Instalao terminou de instalar [name] no seu computador. O programa pode ser iniciado clicando nos cones instalados.\nClickFinish=Clique em Concluir para sair do Programa de Instalao.\nFinishedRestartLabel=Para concluir a instalao de [name], o Programa de Instalao deve reiniciar o computador. Voc gostaria de reiniciar agora?\nFinishedRestartMessage=Para concluir a instalao de [name], o Programa de Instalao deve reiniciar o computador.%n%nVoc gostaria de reiniciar agora?\nShowReadmeCheck=Sim, eu quero visualizar o arquivo LEIA-ME\nYesRadio=&Sim, reiniciar o computador agora\nNoRadio=&No, eu vou reiniciar o computador depois\n; used for example as 'Run MyProg.exe'\nRunEntryExec=Executar %1\n; used for example as 'View Readme.txt'\nRunEntryShellExec=Visualizar %1\n\n; *** \"Setup Needs the Next Disk\" stuff\nChangeDiskTitle=O Programa de Instalao Precisa do Prximo Disco\nSelectDiskLabel2=Por favor, insira o Disco %1 e clique em OK.%n%nSe os arquivos deste disco esto numa pasta diferente da indicada abaixo, informe o caminho correto ou clique em Procurar.\nPathLabel=&Caminho:\nFileNotInDir2=O arquivo \"%1\" no pde ser encontrado em \"%2\". Por favor, insira o disco correto ou escolha outra pasta.\nSelectDirectoryLabel=Por favor, informe o local do prximo disco.\n\n; *** Installation phase messages\nSetupAborted=A instalao no foi concluda.%n%nPor favor, corrija o problema e execute novamente o Programa de Instalao.\nEntryAbortRetryIgnore=Clique Repetir para tentar novamente, Ignorar para continuar assim mesmo, or Cancelar para cancelar a instalao.\n\n; *** Installation status messages\nStatusClosingApplications=Encerrando aplicaes...\nStatusCreateDirs=Criando diretrios...\nStatusExtractFiles=Extraindo arquivos...\nStatusCreateIcons=Criando atalhos...\nStatusCreateIniEntries=Criando entradas INI...\nStatusCreateRegistryEntries=Criando entradas no Registro...\nStatusRegisterFiles=Registrando arquivos...\nStatusSavingUninstall=Salvando informaes de desinstalao...\nStatusRunProgram=Finalizando a instalao...\nStatusRestartingApplications=Reiniciando applicaes...\nStatusRollback=Desfazendo as alteraes efetuadas...\n\n; *** Misc. errors\nErrorInternal2=Erro interno: %1\nErrorFunctionFailedNoCode=%1 falhou\nErrorFunctionFailed=%1 falhou; cdigo %2\nErrorFunctionFailedWithMessage=%1 falhou; cdigo %2.%n%3\nErrorExecutingProgram=No foi possvel executar o arquivo:%n%1\n\n; *** Registry errors\nErrorRegOpenKey=Erro ao abrir a chave do registro:%n%1\\%2\nErrorRegCreateKey=Erro ao criar a chave do registro:%n%1\\%2\nErrorRegWriteKey=Erro ao escrever na chave do registro:%n%1\\%2\n\n; *** INI errors\nErrorIniEntry=Erro ao criar entrada INI no arquivo \"%1\".\n\n; *** File copying errors\nFileAbortRetryIgnore=Clique em Repetir para tentar novamente, em Ignorar para ignorar este arquivo (no recomendado) ou em Cancelar para cancelar a instalao.\nFileAbortRetryIgnore2=Clique em Repetir para tentar novamente, em Ignorar para ignorar este arquivo (no recomendado) ou em Cancelar para cancelar a instalao.\nSourceIsCorrupted=O arquivo de origem est corrompido\nSourceDoesntExist=O arquivo de origem \"%1\" no existe\nExistingFileReadOnly=O arquivo existente est marcado como somente leitura.%n%nClique em Repetir para remover o atributo de somente leitura e tentar novamente, em Ignorar para ignorar este arquivo, ou em Anular para cancelar a instalao.\nErrorReadingExistingDest=Ocorreu um erro ao tentar ler o arquivo existente:\nFileExists=O arquivo j existe.%n%nVoc quer que o Programa de Instalao sobrescreva o arquivo?\nExistingFileNewer=O arquivo j existente  mais recente do que o arquivo que o Programa de Instalao est tentando instalar. Recomenda-se que voc mantenha o arquivo existente.%n%nVoc quer manter o arquivo existente?\nErrorChangingAttr=Ocorreu um erro ao tentar modificar os atributos do arquivo existente:\nErrorCreatingTemp=Ocorreu um erro ao tentar criar um arquivo nao diretrio de destino:\nErrorReadingSource=Ocorreu um erro ao tentar ler o arquivo de origem:\nErrorCopying=Ocorreu um erro ao tentar copiar um arquivo:\nErrorReplacingExistingFile=Ocorreu um erro ao tentar substituir o arquivo existente:\nErrorRestartReplace=Reiniciar/Substituir falhou:\nErrorRenamingTemp=Ocorreu um erro ao tentar renomear um arquivo no diretrio de destino:\nErrorRegisterServer=No foi possvel registrar a DLL/OCX: %1\nErrorRegSvr32Failed=RegSvr32 falhou com o cdigo de sada %1\nErrorRegisterTypeLib=No foi possvel registrar a biblioteca de tipos: %1\n\n; *** Post-installation errors\nErrorOpeningReadme=Ocorreu um erro ao tentar abrir o arquivo LEIA-ME.\nErrorRestartingComputer=O Programa de Instalao no conseguiu reiniciar o computador. Por favor, reinicie o computador manualmente.\n\n; *** Uninstaller messages\nUninstallNotFound=O arquivo \"%1\" no existe. No  possvel desinstalar.\nUninstallOpenError=O arquivo \"%1\" no pode ser aberto. No  possvel desinstalar\nUninstallUnsupportedVer=O arquivo de log de desinstalao \"%1\" est num formato no reconhecido por esta verso do desinstalador. No  possvel desinstalar\nUninstallUnknownEntry=Foi encontrada uma entrada desconhecida (%1) no arquivo de log de desinstalao\nConfirmUninstall=Voc tem certeza que deseja remover completamente %1 e todos os seus componentes?\nUninstallOnlyOnWin64=Esta instalao no pode ser desinstalada em Windows 64 bits.\nOnlyAdminCanUninstall=Esta instalao s pode ser desinstalada por usurios com direitos administrativos.\nUninstallStatusLabel=Por favor, aguarde enquanto %1  removido do seu computador.\nUninstalledAll=%1 foi removido com sucesso do seu computador.\nUninstalledMost=A desinstalao de %1 foi concluda.%n%nAlguns elementos no puderam ser removidos. Estes podem ser removidos manualmente.\nUninstalledAndNeedsRestart=Para concluir a desinstalao de %1, o computador deve ser reiniciado.%n%nVoc quer que o computador seja reiniciado agora?\nUninstallDataCorrupted=O arquivo \"%1\" est corrompido. No  possvel desinstalar\n\n; *** Uninstallation phase messages\nConfirmDeleteSharedFileTitle=Remover Arquivo Compartilhado?\nConfirmDeleteSharedFile2=O sistema indica que o seguinte arquivo compartilhado no est mais em uso por nenhum outro programa. Voc quer que a desinstalao remova este arquivo compartilhado?%n%nSe ainda houver programas utilizando este arquivo e ele for removido, esses programas podero no funcionar corretamente. Se voc no tem certeza, escolha No. Manter o arquivo no seu computador no trar prejuzo algum.\nSharedFileNameLabel=Nome do arquivo:\nSharedFileLocationLabel=Local:\nWizardUninstalling=Status da Desinstalao\nStatusUninstalling=Desinstalando %1...\n\n; *** Shutdown block reasons\nShutdownBlockReasonInstallingApp=Instalando %1.\nShutdownBlockReasonUninstallingApp=Removendo %1.\n\n; The custom messages below aren't used by Setup itself, but if you make\n; use of them in your scripts, you'll want to translate them.\n\n[CustomMessages]\n\nNameAndVersion=%1 verso %2\nAdditionalIcons=cones adicionais:\nCreateDesktopIcon=Criar um cone na rea de &Trabalho\nCreateQuickLaunchIcon=Criar um cone na &Barra de Inicializao Rpida\nProgramOnTheWeb=%1 na Internet\nUninstallProgram=Desinstalar %1\nLaunchProgram=Executar %1\nAssocFileExtension=Associar %1 com a e&xtenso de arquivo %2\nAssocingFileExtension=Associando %1 com a extenso de arquivo...\nAutoStartProgramGroupDescription=Startup:\nAutoStartProgram=Iniciar automaticamente %1\nAddonHostProgramNotFound=%1 no pde ser localizado na pasta que voc selecionou.%n%nVoc deseja continuar assim mesmo?\n\n; *** AviSynth+ custom messages\n\nFullInstallation=Instalao completa\n;CompactInstallation=Recommended installation\nCustomInstallation=Instalao personalizada\n\nCmpMain=%1 Bsico\nCmpDocs=Documentao\nCmpDocsEn=Ingls\nCmpDocsCs=Tcheco\nCmpDocsFr=Francs\nCmpDocsDe=Alemo\nCmpDocsIt=Italiano\nCmpDocsJa=Japons\nCmpDocsPl=Polons\nCmpDocsPt=Portugus\nCmpDocsRu=Russo\n;CmpDocsExamples=Scripting Examples\nCmpSdk=FilterSDK\n;CmpMig=Legacy AviSynth Upgrade\n;CmpMigUninstall=Uninstall and move plugins to %1\n;CmpMigBackup=Backup legacy AviSynth\n;CmpCustomizePluginPaths=Customize Plugin Paths\n\n;FileTypeDescAvs=%1 Script\n;FileTypeDescAvsi=%1 Autoload Script\n\n;InstallStatusRuntime = Installing %1 (%2).%nThis may take up to 5 minutes... \n;UninstallStatusLegacyRestore = Restoring legacy AviSynth...\n;BackupRestoreFailed=An error occured while trying to restore your previous AviSynth installation:%n%1\n\n;MigPageCaption=Upgrade Options\n;MigPageDescription=How should %1 handle your existing AviSynth installation?\n;MigPageSubCaption=Setup has detected that AviSynth is already installed in:%n%n%2%n%nAvisynth and %1 cannot be run alongside each other. However, setup can preserve your legacy AviSynth installation in case you want to downgrade later.\n;MigPageOptionBackup=Keep the existing AviSynth program directory and backup its system components overwritten by %1.%n%1 will still load your existing plugins and restore your previous AviSynth installation upon uninstall.\n;MigPageOptionUninstall=Uninstall AviSynth now and migrate compatible plugins to the %1 plugin directory.\n;MigPageUninstallFailed=AviSynth Uninstall failed: %n%1\n \n;PlugPageCaption=%1 Plugin Folders\n;PlugPageDescription=Where should %1 autoload plugins from?\n;PlugPageSubCaption=%1 will install bundled plugins to the its own autoload directory, but also autoload from the legacy plugin directory.\n;PlugPagePlugDirPlus=%2 %1-bit plugin directory:\n;PlugPagePlugDirLegacy=AviSynth %1-bit plugin directory:"
  },
  {
    "path": "distrib/WinInstaller/Translations/ru.isl",
    "content": "; *** Inno Setup version 5.5.3+ Russian messages ***\n;\n; Translated from English by Dmitry Kann, http://yktoo.com/\n;\n; Note: When translating this text, do not add periods (.) to the end of\n; messages that didn't have them already, because on those messages Inno\n; Setup adds the periods automatically (appending a period would result in\n; two periods being displayed).\n\n[LangOptions]\nLanguageName=<0420><0443><0441><0441><043A><0438><0439>\nLanguageID=$0419\nLanguageCodePage=65001\n\n[Messages]\n\n; *** Application titles\nSetupAppTitle=Установка\nSetupWindowTitle=Установка — %1\nUninstallAppTitle=Деинсталляция\nUninstallAppFullTitle=Деинсталляция — %1\n\n; *** Misc. common\nInformationTitle=Информация\nConfirmTitle=Подтверждение\nErrorTitle=Ошибка\n\n; *** SetupLdr messages\nSetupLdrStartupMessage=Данная программа установит %1 на ваш компьютер, продолжить?\nLdrCannotCreateTemp=Невозможно создать временный файл. Установка прервана\nLdrCannotExecTemp=Невозможно выполнить файл во временном каталоге. Установка прервана\n\n; *** Startup error messages\nLastErrorMessage=%1.%n%nОшибка %2: %3\nSetupFileMissing=Файл %1 отсутствует в папке установки. Пожалуйста, устраните проблему или получите новую версию программы.\nSetupFileCorrupt=Установочные файлы повреждены. Пожалуйста, получите новую копию программы.\nSetupFileCorruptOrWrongVer=Эти установочные файлы повреждены или несовместимы с данной версией программы установки. Пожалуйста, устраните проблему или получите новую копию программы.\nInvalidParameter=Командная строка содержит недопустимый параметр:%n%n%1\nSetupAlreadyRunning=Программа установки уже запущена.\nWindowsVersionNotSupported=Эта программа не поддерживает версию Windows, установленную на этом компьютере.\nWindowsServicePackRequired=Эта программа требует %1 Service Pack %2 или более позднюю версию.\nNotOnThisPlatform=Эта программа не будет работать в %1.\nOnlyOnThisPlatform=Эту программу можно запускать только в %1.\nOnlyOnTheseArchitectures=Установка этой программы возможна только в версиях Windows для следующих архитектур процессоров:%n%n%1\nMissingWOW64APIs=В версии Windows, в которой вы работаете, отсутствуют функции, необходимые для выполнения 64-битной установки. Чтобы устранить эту проблему, вам необходимо установить пакет обновления (Service Pack) %1.\nWinVersionTooLowError=Эта программа требует %1 версии %2 или выше.\nWinVersionTooHighError=Программа не может быть установлена в %1 версии %2 или выше.\nAdminPrivilegesRequired=Чтобы установить данную программу, вы должны выполнить вход в систему как Администратор.\nPowerUserPrivilegesRequired=Чтобы установить эту программу, вы должны выполнить вход в систему как Администратор или член группы «Опытные пользователи» (Power Users).\nSetupAppRunningError=Обнаружен запущенный экземпляр %1.%n%nПожалуйста, закройте все экземпляры приложения, затем нажмите «OK», чтобы продолжить, или «Отмена», чтобы выйти.\nUninstallAppRunningError=Деинсталлятор обнаружил запущенный экземпляр %1.%n%nПожалуйста, закройте все экземпляры приложения, затем нажмите «OK», чтобы продолжить, или «Отмена», чтобы выйти.\n\n; *** Misc. errors\nErrorCreatingDir=Невозможно создать папку \"%1\"\nErrorTooManyFilesInDir=Невозможно создать файл в каталоге \"%1\", так как в нём слишком много файлов\n\n; *** Setup common messages\nExitSetupTitle=Выход из программы установки\nExitSetupMessage=Установка не завершена. Если вы выйдете, программа не будет установлена.%n%nВы сможете завершить установку, запустив программу установки позже.%n%nВыйти из программы установки?\nAboutSetupMenuItem=&О программе...\nAboutSetupTitle=О программе\nAboutSetupMessage=%1, версия %2%n%3%n%nСайт %1:%n%4\nAboutSetupNote=\nTranslatorNote=Russian translation by Dmitry Kann, http://www.dk-soft.org/\n\n; *** Buttons\nButtonBack=< &Назад\nButtonNext=&Далее >\nButtonInstall=&Установить\nButtonOK=OK\nButtonCancel=Отмена\nButtonYes=&Да\nButtonYesToAll=Да для &Всех\nButtonNo=&Нет\nButtonNoToAll=Н&ет для Всех\nButtonFinish=&Завершить\nButtonBrowse=&Обзор...\nButtonWizardBrowse=&Обзор...\nButtonNewFolder=&Создать папку\n\n; *** \"Select Language\" dialog messages\nSelectLanguageTitle=Выберите язык установки\nSelectLanguageLabel=Выберите язык, который будет использован в  процессе установки:\n\n; *** Common wizard text\nClickNext=Нажмите «Далее», чтобы продолжить, или «Отмена», чтобы выйти из программы установки.\nBeveledLabel=\nBrowseDialogTitle=Обзор папок\nBrowseDialogLabel=Выберите папку из списка и нажмите «ОК».\nNewFolderName=Новая папка\n\n; *** \"Welcome\" wizard page\nWelcomeLabel1=Вас приветствует Мастер установки [name]\nWelcomeLabel2=Программа установит [name/ver] на ваш компьютер.%n%nРекомендуется закрыть все прочие приложения перед тем, как продолжить.\n\n; *** \"Password\" wizard page\nWizardPassword=Пароль\nPasswordLabel1=Эта программа защищена паролем.\nPasswordLabel3=Пожалуйста, наберите пароль, потом нажмите «Далее». Пароли необходимо вводить с учётом регистра.\nPasswordEditLabel=&Пароль:\nIncorrectPassword=Введенный вами пароль неверен. Пожалуйста, попробуйте снова.\n\n; *** \"License Agreement\" wizard page\nWizardLicense=Лицензионное Соглашение\nLicenseLabel=Пожалуйста, прочтите следующую важную информацию перед тем, как продолжить.\nLicenseLabel3=Пожалуйста, прочтите следующее Лицензионное Соглашение. Вы должны принять условия этого соглашения перед тем, как продолжить.\nLicenseAccepted=Я &принимаю условия соглашения\nLicenseNotAccepted=Я &не принимаю условия соглашения\n\n; *** \"Information\" wizard pages\nWizardInfoBefore=Информация\nInfoBeforeLabel=Пожалуйста, прочитайте следующую важную информацию перед тем, как продолжить.\nInfoBeforeClickLabel=Когда вы будете готовы продолжить установку, нажмите «Далее».\nWizardInfoAfter=Информация\nInfoAfterLabel=Пожалуйста, прочитайте следующую важную информацию перед тем, как продолжить.\nInfoAfterClickLabel=Когда вы будете готовы продолжить установку, нажмите «Далее».\n\n; *** \"User Information\" wizard page\nWizardUserInfo=Информация о пользователе\nUserInfoDesc=Пожалуйста, введите данные о себе.\nUserInfoName=&Имя и фамилия пользователя:\nUserInfoOrg=&Организация:\nUserInfoSerial=&Серийный номер:\nUserInfoNameRequired=Вы должны ввести имя.\n\n; *** \"Select Destination Location\" wizard page\nWizardSelectDir=Выбор папки установки\nSelectDirDesc=В какую папку вы хотите установить [name]?\nSelectDirLabel3=Программа установит [name] в следующую папку.\nSelectDirBrowseLabel=Нажмите «Далее», чтобы продолжить. Если вы хотите выбрать другую папку, нажмите «Обзор».\nDiskSpaceMBLabel=Требуется как минимум [mb] Мб свободного дискового пространства.\nCannotInstallToNetworkDrive=Установка не может производиться на сетевой диск.\nCannotInstallToUNCPath=Установка не может производиться в папку по UNC-пути.\nInvalidPath=Вы должны указать полный путь с буквой диска; например:%n%nC:\\APP%n%nили в форме UNC:%n%n\\\\имя_сервера\\имя_ресурса\nInvalidDrive=Выбранный вами диск или сетевой путь не существует или недоступен. Пожалуйста, выберите другой.\nDiskSpaceWarningTitle=Недостаточно места на диске\nDiskSpaceWarning=Установка требует не менее %1 Кб свободного места, а на выбранном вами диске доступно только %2 Кб.%n%nВы желаете тем не менее продолжить установку?\nDirNameTooLong=Имя папки или путь к ней превышают допустимую длину.\nInvalidDirName=Указанное имя папки недопустимо.\nBadDirName32=Имя папки не может содержать символов: %n%n%1\nDirExistsTitle=Папка существует\nDirExists=Папка%n%n%1%n%nуже существует. Всё равно установить в эту папку?\nDirDoesntExistTitle=Папка не существует\nDirDoesntExist=Папка%n%n%1%n%nне существует. Вы хотите создать её?\n\n; *** \"Select Components\" wizard page\nWizardSelectComponents=Выбор компонентов\nSelectComponentsDesc=Какие компоненты должны быть установлены?\nSelectComponentsLabel2=Выберите компоненты, которые вы хотите установить; снимите флажки с компонентов, устанавливать которые не требуется. Нажмите «Далее», когда вы будете готовы продолжить.\nFullInstallation=Полная установка\n; if possible don't translate 'Compact' as 'Minimal' (I mean 'Minimal' in your language)\nCompactInstallation=Компактная установка\nCustomInstallation=Выборочная установка\nNoUninstallWarningTitle=Установленные компоненты\nNoUninstallWarning=Программа установки обнаружила, что следующие компоненты уже установлены на вашем компьютере:%n%n%1%n%nОтмена выбора этих компонент не удалит их.%n%nПродолжить?\nComponentSize1=%1 Кб\nComponentSize2=%1 Мб\nComponentsDiskSpaceMBLabel=Текущий выбор требует не менее [mb] Мб на диске.\n\n; *** \"Select Additional Tasks\" wizard page\nWizardSelectTasks=Выберите дополнительные задачи\nSelectTasksDesc=Какие дополнительные задачи необходимо выполнить?\nSelectTasksLabel2=Выберите дополнительные задачи, которые должны выполниться при установке [name], после этого нажмите «Далее»:\n\n; *** \"Select Start Menu Folder\" wizard page\nWizardSelectProgramGroup=Выберите папку в меню «Пуск»\nSelectStartMenuFolderDesc=Где программа установки должна создать ярлыки?\nSelectStartMenuFolderLabel3=Программа создаст ярлыки в следующей папке меню «Пуск».\nSelectStartMenuFolderBrowseLabel=Нажмите «Далее», чтобы продолжить. Если вы хотите выбрать другую папку, нажмите «Обзор».\nMustEnterGroupName=Вы должны ввести имя папки.\nGroupNameTooLong=Имя папки группы или путь к ней превышают допустимую длину.\nInvalidGroupName=Указанное имя папки недопустимо.\nBadGroupName=Имя папки не может содержать символов:%n%n%1\nNoProgramGroupCheck2=&Не создавать папку в меню «Пуск»\n\n; *** \"Ready to Install\" wizard page\nWizardReady=Всё готово к установке\nReadyLabel1=Программа установки готова начать установку [name] на ваш компьютер.\nReadyLabel2a=Нажмите «Установить», чтобы продолжить, или «Назад», если вы хотите просмотреть или изменить опции установки.\nReadyLabel2b=Нажмите «Установить», чтобы продолжить.\nReadyMemoUserInfo=Информация о пользователе:\nReadyMemoDir=Папка установки:\nReadyMemoType=Тип установки:\nReadyMemoComponents=Выбранные компоненты:\nReadyMemoGroup=Папка в меню «Пуск»:\nReadyMemoTasks=Дополнительные задачи:\n\n; *** \"Preparing to Install\" wizard page\nWizardPreparing=Подготовка к установке\nPreparingDesc=Программа установки подготавливается к установке [name] на ваш компьютер.\nPreviousInstallNotCompleted=Установка или удаление предыдущей программы не были завершены. Вам потребуется перезагрузить компьютер, чтобы завершить ту установку.%n%nПосле перезагрузки запустите вновь Программу установки, чтобы завершить установку [name].\nCannotContinue=Невозможно продолжить установку. Нажмите «Отмена» для выхода из программы.\nApplicationsFound=Следующие приложения используют файлы, которые программа установки должна обновить. Рекомендуется позволить программе установки автоматически закрыть эти приложения.\nApplicationsFound2=Следующие приложения используют файлы, которые программа установки должна обновить. Рекомендуется позволить программе установки автоматически закрыть эти приложения. Когда установка будет завершена, программа установки попытается вновь запустить их.\nCloseApplications=&Автоматически закрыть эти приложения\nDontCloseApplications=&Не закрывать эти приложения\nErrorCloseApplications=Программе установки не удалось автоматически закрыть все приложения. Рекомендуется закрыть все приложения, которые используют подлежащие обновлению файлы, прежде чем продолжить установку.\n\n; *** \"Installing\" wizard page\nWizardInstalling=Установка...\nInstallingLabel=Пожалуйста, подождите, пока [name] установится на ваш компьютер.\n\n; *** \"Setup Completed\" wizard page\nFinishedHeadingLabel=Завершение Мастера установки [name]\nFinishedLabelNoIcons=Программа [name] установлена на ваш компьютер.\nFinishedLabel=Программа [name] установлена на ваш компьютер. Приложение можно запустить с помощью соответствующего значка.\nClickFinish=Нажмите «Завершить», чтобы выйти из программы установки.\nFinishedRestartLabel=Для завершения установки [name] требуется перезагрузить компьютер. Произвести перезагрузку сейчас?\nFinishedRestartMessage=Для завершения установки [name] требуется перезагрузить компьютер.%n%nПроизвести перезагрузку сейчас?\nShowReadmeCheck=Я хочу просмотреть файл README\nYesRadio=&Да, перезагрузить компьютер сейчас\nNoRadio=&Нет, я произведу перезагрузку позже\n; used for example as 'Run MyProg.exe'\nRunEntryExec=Запустить %1\n; used for example as 'View Readme.txt'\nRunEntryShellExec=Просмотреть %1\n\n; *** \"Setup Needs the Next Disk\" stuff\nChangeDiskTitle=Необходимо вставить следующий диск\nSelectDiskLabel2=Пожалуйста, вставьте диск %1 и нажмите «OK».%n%nЕсли файлы этого диска могут быть найдены в папке, отличающейся от показанной ниже, введите правильный путь или нажмите «Обзор».\nPathLabel=&Путь:\nFileNotInDir2=Файл \"%1\" не найден в \"%2\". Пожалуйста, вставьте правильный диск или выберите другую папку.\nSelectDirectoryLabel=Пожалуйста, укажите путь к следующему диску.\n\n; *** Installation phase messages\nSetupAborted=Установка не была завершена.%n%nПожалуйста, устраните проблему и запустите установку снова.\nEntryAbortRetryIgnore=Нажмите «Повтор», чтобы повторить попытку, «Пропустить», чтобы пропустить файл, или «Отказ» для отмены установки.\n\n; *** Installation status messages\nStatusClosingApplications=Закрытие приложений...\nStatusCreateDirs=Создание папок...\nStatusExtractFiles=Распаковка файлов...\nStatusCreateIcons=Создание ярлыков программы...\nStatusCreateIniEntries=Создание INI-файлов...\nStatusCreateRegistryEntries=Создание записей реестра...\nStatusRegisterFiles=Регистрация файлов...\nStatusSavingUninstall=Сохранение информации для деинсталляции...\nStatusRunProgram=Завершение установки...\nStatusRestartingApplications=Перезапуск приложений...\nStatusRollback=Откат изменений...\n\n; *** Misc. errors\nErrorInternal2=Внутренняя ошибка: %1\nErrorFunctionFailedNoCode=%1: сбой\nErrorFunctionFailed=%1: сбой; код %2\nErrorFunctionFailedWithMessage=%1: сбой; код %2.%n%3\nErrorExecutingProgram=Невозможно выполнить файл:%n%1\n\n; *** Registry errors\nErrorRegOpenKey=Ошибка открытия ключа реестра:%n%1\\%2\nErrorRegCreateKey=Ошибка создания ключа реестра:%n%1\\%2\nErrorRegWriteKey=Ошибка записи в ключ реестра:%n%1\\%2\n\n; *** INI errors\nErrorIniEntry=Ошибка создания записи в INI-файле \"%1\".\n\n; *** File copying errors\nFileAbortRetryIgnore=Нажмите «Повтор», чтобы повторить, «Пропустить», чтобы пропустить файл (не рекомендуется) или «Отказ» для выхода.\nFileAbortRetryIgnore2=Нажмите «Повтор», чтобы повторить, «Пропустить», чтобы игнорировать ошибку (не рекомендуется) или «Отказ» для выхода.\nSourceIsCorrupted=Исходный файл поврежден\nSourceDoesntExist=Исходный файл \"%1\" не существует\nExistingFileReadOnly=Существующий файл помечен как «файл только для чтения».%n%nНажмите «Повтор» для удаления атрибута «только для чтения», «Пропустить», чтобы пропустить файл или «Отказ» для выхода.\nErrorReadingExistingDest=Произошла ошибка при попытке чтения существующего файла:\nFileExists=Файл уже существует.%n%nПерезаписать его?\nExistingFileNewer=Существующий файл более новый, чем устанавливаемый. Рекомендуется сохранить существующий файл.%n%nВы хотите сохранить существующий файл?\nErrorChangingAttr=Произошла ошибка при попытке изменения атрибутов существующего файла:\nErrorCreatingTemp=Произошла ошибка при попытке создания файла в папке назначения:\nErrorReadingSource=Произошла ошибка при попытке чтения исходного файла:\nErrorCopying=Произошла ошибка при попытке копирования файла:\nErrorReplacingExistingFile=Произошла ошибка при попытке замены существующего файла:\nErrorRestartReplace=Ошибка RestartReplace:\nErrorRenamingTemp=Произошла ошибка при попытке переименования файла в папке назначения:\nErrorRegisterServer=Невозможно зарегистрировать DLL/OCX: %1\nErrorRegSvr32Failed=Ошибка при выполнении RegSvr32, код возврата %1\nErrorRegisterTypeLib=Невозможно зарегистрировать библиотеку типов (Type Library): %1\n\n; *** Post-installation errors\nErrorOpeningReadme=Произошла ошибка при попытке открытия файла README.\nErrorRestartingComputer=Программе установки не удалось перезапустить компьютер. Пожалуйста, выполните это самостоятельно.\n\n; *** Uninstaller messages\nUninstallNotFound=Файл \"%1\" не существует, деинсталляция невозможна.\nUninstallOpenError=Невозможно открыть файл \"%1\". Деинсталляция невозможна\nUninstallUnsupportedVer=Файл протокола для деинсталляции \"%1\" не распознан данной версией программы-деинсталлятора. Деинсталляция невозможна\nUninstallUnknownEntry=Встретился неизвестный пункт (%1) в файле протокола для деинсталляции\nConfirmUninstall=Вы действительно хотите удалить %1 и все компоненты программы?\nUninstallOnlyOnWin64=Данную программу возможно деинсталлировать только в среде 64-битной Windows.\nOnlyAdminCanUninstall=Эта программа может быть деинсталлирована только пользователем с административными привилегиями.\nUninstallStatusLabel=Пожалуйста, подождите, пока %1 будет удалена с вашего компьютера.\nUninstalledAll=Программа %1 была полностью удалена с вашего компьютера.\nUninstalledMost=Деинсталляция %1 завершена.%n%nЧасть элементов не удалось удалить. Вы можете удалить их самостоятельно.\nUninstalledAndNeedsRestart=Для завершения деинсталляции %1 необходимо произвести перезагрузку вашего компьютера.%n%nВыполнить перезагрузку сейчас?\nUninstallDataCorrupted=Файл \"%1\" поврежден. Деинсталляция невозможна\n\n; *** Uninstallation phase messages\nConfirmDeleteSharedFileTitle=Удалить совместно используемый файл?\nConfirmDeleteSharedFile2=Система указывает, что следующий совместно используемый файл больше не используется никакими другими приложениями. Подтверждаете удаление файла?%n%nЕсли какие-либо программы всё еще используют этот файл, и он будет удалён, они не смогут работать правильно. Если Вы не уверены, выберите «Нет». Оставленный файл не навредит вашей системе.\nSharedFileNameLabel=Имя файла:\nSharedFileLocationLabel=Расположение:\nWizardUninstalling=Состояние деинсталляции\nStatusUninstalling=Деинсталляция %1...\n\n\n; *** Shutdown block reasons\nShutdownBlockReasonInstallingApp=Установка %1.\nShutdownBlockReasonUninstallingApp=Деинсталляция %1.\n\n; The custom messages below aren't used by Setup itself, but if you make\n; use of them in your scripts, you'll want to translate them.\n\n[CustomMessages]\n\nNameAndVersion=%1, версия %2\nAdditionalIcons=Дополнительные значки:\nCreateDesktopIcon=Создать значок на &Рабочем столе\nCreateQuickLaunchIcon=Создать значок в &Панели быстрого запуска\nProgramOnTheWeb=Сайт %1 в Интернете\nUninstallProgram=Деинсталлировать %1\nLaunchProgram=Запустить %1\nAssocFileExtension=Св&язать %1 с файлами, имеющими расширение %2\nAssocingFileExtension=Связывание %1 с файлами %2...\nAutoStartProgramGroupDescription=Автозапуск:\nAutoStartProgram=Автоматически запускать %1\nAddonHostProgramNotFound=%1 не найден в указанной вами папке.%n%nВы всё равно хотите продолжить?\n\n; *** AviSynth+ custom messages\n; translated by Leonid Sinev\n\nFullInstallation=Полная установка\n;CompactInstallation=Рекомендованный набор компонентов\nCustomInstallation=Выборочная установка\n\nCmpMain=%1 база\nCmpDocs=Документация\nCmpDocsEn=Английская\nCmpDocsCs=Чешская\nCmpDocsFr=Французская\nCmpDocsDe=Немецкая\nCmpDocsIt=Итальянская\nCmpDocsJa=Японская\nCmpDocsPl=Польская\nCmpDocsPt=Португальская\nCmpDocsRu=Русская\nCmpDocsExamples=Примеры скриптов\nCmpSdk=FilterSDK (pour le developpement de plugins %1)\nCmpMig=Обновление имеющейся установки AviSynth\nCmpMigUninstall=Деинсталлировать, а плагины переместить в %1\nCmpMigBackup=Сделать бэкап имеющейся установки AviSynth\nCmpCustomizePluginPaths=Настроить расположение плагинов\n\n;FileTypeDescAvs=%1 Script\n;FileTypeDescAvsi=%1 Autoload Script\n\nInstallStatusRuntime=Устанавливаем %1 (%2).%nЭто может занять до 5 минут…\nUninstallStatusLegacyRestore=Восстанавливаем предшествующую установку AviSynth…\nBackupRestoreFailed=Возникла ошибка во время восстановления предшествующей установки AviSynth:%n%1\n\nMigPageCaption=Опции обновления\nMigPageDescription=Как следует %1 обойтись с Вашей имеющейся установкой AviSynth?\nMigPageSubCaption=Установщик обнаружил, что в%n%n%2%n%nуже установлен AviSynth.%nAvisynth и %1 не могут располагаться в одном месте на диске. Однако, установщик может сохранить имеющуюся у Вас установку AviSynth с тем, чтобы у Вас была возможность вернуть её обратно.\n;MigPageOptionBackup=Keep the existing AviSynth program directory and backup its system components overwritten by %1.%n%1 will still load your existing plugins and restore your previous AviSynth installation upon uninstall.\n;MigPageOptionUninstall=Uninstall AviSynth now and migrate compatible plugins to the %1 plugin directory.\nMigPageUninstallFailed=Удаление AviSynth не завершено: %n%1\n \nPlugPageCaption=Папки с плагинами %1\nPlugPageDescription=Откуда %1 должен проводить автозагрузку плагинов?\n;PlugPageSubCaption=%1 will install bundled plugins to the its own autoload directory, but also autoload from the legacy plugin directory.\nPlugPagePlugDirPlus=Папка с %1-битными плагинами %2:\nPlugPagePlugDirLegacy=Папка с %1-битными плагинами AviSynth:"
  },
  {
    "path": "distrib/WinInstaller/avisynth+.iss",
    "content": "﻿;!!!Conditional!!!  comment out the following define to ignore VS redistributables\n;#define WITH_VC_REDIST\n#define WITH_VC_REDIST_XP\n;Note 1: do not enable both.\n;Note 2: XP: Though Microsoft Visual C++ Redistributable (2015-2022) still installs on older OS's,\n;XP support has been ended, an older redistributable (officially 14.27.29114.0) needed for XP\n;along with a specially built version of Avisynth+ (v141_xp toolset, /Zc:threadSafeInit-).\n;XP version of redistributable must be renamed to VC_redist_14.27.29114.0.x86.exe and VC_redist_14.27.29114.0.x64.exe\n\n;headers and c lib are OK, but documentation is not up to date, anyway we include them\n#define WITH_SDK\n\n;this section is not up to date, don't include them\n#define WITH_DOCS\n\n;!!!Conditional!!!  comment out the following define to include project web url\n;original Avs+ project page is not maintained at the moment (Dec. 2017) and contains very old content\n;#define WITH_AVSPLUS_URL\n\n#define AvsName \"AviSynth+\"\n#define AvsFriendlyName \"AviSynthPlus\"\n#define AvsPublisher \"The Public\"\n#define AppId \"{AC78780F-BACA-4805-8D4F-AE1B52B7E7D3}\"\n#define AvsGitURL \"https://github.com/AviSynth/AviSynthPlus/\"\n\n#ifdef WITH_AVSPLUS_URL\n#define AvsWebURL \"https://github.com/AviSynth/AviSynthPlus/\"\n#endif\n\n;There is no specific x86/x64 output directory.\n;folders must be created relative to the folder of iss script.\n;Build x86 avs+ then copy the Output folder (with the folder itself) here\n#define BuildDir32 \"x86\"\n;Build x64 avs+ then copy the Output folder (with the folder itself) here\n#define BuildDir64 \"x64\"\n;.\\x86\\Output\\...\n;.\\x64\\Output\\...\n\n#ifdef WITH_VC_REDIST_XP\n#define VcVersion \"Microsoft Visual C++ Redistributable for Visual Studio 2015-2019 (latest XP compatible)\"\n#else\n#define VcVersion \"Microsoft Visual C++ Redistributable for Visual Studio 2015-2022\"\n#endif\n\n#define BuildDate GetFileDateTimeString(AddBackslash(BuildDir32) + \"Output\\AviSynth.dll\", 'yyyy/mm/dd', '-',);\n\n#expr Exec(\"powershell\", \"-ExecutionPolicy unrestricted -File update_git_rev.ps1\", SourcePath, 1)\n#define IniFile AddBackslash(SourcePath) + \"git_rev.ini\"\n#define RevisionNumber  ReadIni(IniFile, \"Version\", \"RevisionNumber\" )\n#define Revision        ReadIni(IniFile, \"Version\", \"Revision\"       )\n#define IsRelease       ReadIni(IniFile, \"Version\", \"IsRelease\"      )\n#define Version         ReadIni(IniFile, \"Version\", \"Version\"        )\n#define Branch          ReadIni(IniFile, \"Version\", \"Branch\"         )\n\n[Setup]\nAppId={{#AppId}\nAppName={#AvsName}\nAppVersion={#Version}.{#RevisionNumber}\n#if IsRelease == \"True\"\n  AppVerName={#AvsName} {#Version}\n  OutputBaseFilename={#AvsFriendlyName}_{#Version}\n#else\n  AppVerName={#AvsName} {#Version} r{#RevisionNumber}\n  OutputBaseFilename={#AvsFriendlyName}-r{#RevisionNumber}-{#Branch}-{#Revision}\n#endif\nAppPublisher={#AvsPublisher}\n#ifdef WITH_AVSPLUS_URL\nAppPublisherURL={#AvsWebURL}\nAppSupportURL={#AvsWebURL}/get_started.html\n#endif\nAppUpdatesURL={#AvsGitURL}/releases\nAppReadmeFile={#AvsGitURL}/blob/master/README.rst\nVersionInfoVersion={#Version}.{#RevisionNumber}\nDefaultDirName={pf}\\{#AvsName}\nDefaultGroupName={#AvsName}\nDisableWelcomePage=no\nDisableProgramGroupPage=yes\nOutputDir={#BuildDir32}\\..\nSetupIconFile=..\\Icons\\Ico\\InstIcon.ico\nUninstallDisplayIcon=..\\Icons\\Ico\\InstIcon.ico\nWizardImageFile=WizardImageBig.bmp\nWizardSmallImageFile=WizardImageSmall.bmp\nChangesAssociations=yes\nChangesEnvironment=yes\n;Compression=lzma2/max\nCompression=lzma2/ultra\nSolidCompression=yes\nSetupLogging=yes\nMinVersion=5.1sp3\n\n[Types]\nName: \"compact\"; Description: \"{cm:CompactInstallation}\"\nName: \"full\"; Description: \"{cm:FullInstallation}\"\nName: \"custom\"; Description: \"{cm:CustomInstallation}\"; Flags: iscustom\n\n[Languages]\nName: \"en\"; MessagesFile: \"Translations\\en.isl\"; LicenseFile: ..\\gpl.txt\nName: \"pt_br\"; MessagesFile: \"Translations\\pt_br.isl\"; LicenseFile: ..\\gpl-pt_br.txt\nName: \"cs\"; MessagesFile: \"Translations\\cs.isl\"; LicenseFile: ..\\gpl-cs.txt\nName: \"fr\"; MessagesFile: \"Translations\\fr.isl\"; LicenseFile: ..\\gpl-fr.txt\nName: \"de\"; MessagesFile: \"Translations\\de.isl\"; LicenseFile: ..\\gpl-de.txt\n;Name: \"gr\"; MessagesFile: \"compiler:Languages\\Greek.isl\"\nName: \"it\"; MessagesFile: \"Translations\\it.isl\"; LicenseFile: ..\\gpl-it.txt\nName: \"ja\"; MessagesFile: \"Translations\\ja.isl\"; LicenseFile: ..\\gpl-ja.txt\nName: \"pl\"; MessagesFile: \"Translations\\pl.isl\"; LicenseFile: ..\\gpl-pl.txt\nName: \"pt\"; MessagesFile: \"Translations\\pt.isl\"; LicenseFile: ..\\gpl-pt.txt\nName: \"ru\"; MessagesFile: \"Translations\\ru.isl\"; LicenseFile: ..\\gpl-ru.txt\n\n[Components]\nName: \"main\"; Description: \"{cm:CmpMain,{#AvsName}}\"; Types: full compact custom; Flags: fixed\nName: \"main\\avs32\"; Description: \"{#AvsName} (x86)\"; Types: full compact custom\nName: \"main\\avs64\"; Description: \"{#AvsName} (x64)\"; Types: full compact custom; Check: IsWin64\n\n#ifdef WITH_DOCS\nName: \"docs\"; Description: \"{cm:CmpDocs}\";\nName: \"docs\\enall\"; Description: \"{cm:CmpDocsEn}\"; Types: full; Languages: not en\nName: \"docs\\en\"; Description: \"{cm:CmpDocsEn}\"; Types: full compact custom; Languages: en\n;Name: \"docs\\cs\"; Description: \"{cm:CmpDocsCs}\"; Types: full compact custom; Languages: cs\n;Name: \"docs\\de\"; Description: \"{cm:CmpDocsDe}\"; Types: full compact custom; Languages: de\n;Name: \"docs\\fr\"; Description: \"{cm:CmpDocsFr}\"; Types: full compact custom; Languages: fr\n;Name: \"docs\\it\"; Description: \"{cm:CmpDocsIt}\"; Types: full compact custom; Languages: it\n;Name: \"docs\\ja\"; Description: \"{cm:CmpDocsJa}\"; Types: full compact custom; Languages: ja\n;Name: \"docs\\pl\"; Description: \"{cm:CmpDocsPl}\"; Types: full compact custom; Languages: pl\n;Name: \"docs\\pt\"; Description: \"{cm:CmpDocsPt}\"; Types: full compact custom; Languages: pt pt_br\n;Name: \"docs\\ru\"; Description: \"{cm:CmpDocsRu}\"; Types: full compact custom; Languages: ru\n#endif\n\nName: \"associations\"; Description: \"{cm:SelectAssoc}\"; Types: full custom\nName: \"associations\\openwithnotepad\"; Description: \"{cm:SelectAssocNotepadOpen}\"; Types: full custom\nName: \"associations\\shellnew\"; Description: \"{cm:SelectAssocAddShellNew}\"; Types: full custom\nName: \"associations\\mplayer\"; Description: \"{cm:SelectAssocMplayer}\"; Types: full custom; Check: ExistsMPlayer2\nName: \"associations\\wmplayer\"; Description: \"{cm:SelectAssocWMplayer}\"; Types: full custom; Check: ExistsWMPlayer\n\nName: \"examples\"; Description: \"{cm:CmpDocsExamples}\"; Types: full compact custom\n#ifdef WITH_SDK\nName: \"sdk\"; Description: \"{cm:CmpSdk,{#AvsName}}\"; Types: full custom\n#endif\n\nName: \"avsmig\"; Description: \"{cm:CmpMig}\"; Types: full compact custom; Flags: fixed; Check: IsLegacyAvsInstalled('32')\nName: \"avsmig\\uninst\"; Description: \"{cm:CmpMigUninstall,{#AvsName}}\"; Flags: fixed exclusive\nName: \"avsmig\\backup\"; Description: \"{cm:CmpMigBackup}\"; Flags: fixed exclusive\n\nName: \"custplug\"; Description: \"{cm:CmpCustomizePluginPaths}\"; Types: custom \n\n[Dirs]\nName: \"{code:GetAvsDirsPlus|Plug32}\"; Components: main\\avs32\nName: \"{code:GetAvsDirsPlus|PlugPlus32}\"; Components: main\\avs32\nName: \"{code:GetAvsDirsPlus|Plug64}\"; Components: main\\avs64\nName: \"{code:GetAvsDirsPlus|PlugPlus64}\"; Components: main\\avs64\n \n[Files]\nSource: \"{code:GetAvsDirsLegacy|Plug32}\\*\"; DestDir:{code:GetAvsDirsPlus|Plug32}; Components: avsmig\\uninst; ExternalSize: 0; Check: IsValidPluginMigration('32'); AfterInstall: WipeLegacyPluginDirs('32'); Flags: external recursesubdirs createallsubdirs uninsneveruninstall onlyifdoesntexist skipifsourcedoesntexist   \nSource: \"{code:GetAvsDirsLegacy|Plug64}\\*\"; DestDir:{code:GetAvsDirsPlus|Plug64}; Components: avsmig\\uninst; ExternalSize: 0; Check: IsValidPluginMigration('64'); AfterInstall: WipeLegacyPluginDirs('64'); Flags: external recursesubdirs createallsubdirs uninsneveruninstall 64bit onlyifdoesntexist skipifsourcedoesntexist  \n\nSource: \"{sys}\\AviSynth.dll\"; DestDir:{code:GetAvsDirsLegacy|Prog}\\PlusBackup\\sys32; Components: avsmig\\backup; ExternalSize: 0; Flags: external onlyifdoesntexist skipifsourcedoesntexist uninsneveruninstall   \nSource: \"{sys}\\DevIL.dll\"; DestDir:{code:GetAvsDirsLegacy|Prog}\\PlusBackup\\sys32; Components: avsmig\\backup; ExternalSize: 0; Flags: external onlyifdoesntexist skipifsourcedoesntexist uninsneveruninstall   \nSource: \"{sys}\\AviSynth.dll\"; DestDir:{code:GetAvsDirsLegacy|Prog}\\PlusBackup\\sys64; Components: avsmig\\backup; ExternalSize: 0; Flags: 64bit external onlyifdoesntexist skipifsourcedoesntexist uninsneveruninstall; Check: IsWin64\nSource: \"{sys}\\DevIL.dll\"; DestDir:{code:GetAvsDirsLegacy|Prog}\\PlusBackup\\sys64; Components: avsmig\\backup; ExternalSize: 0; Flags: 64bit external onlyifdoesntexist skipifsourcedoesntexist uninsneveruninstall; Check: IsWin64  \nSource: \"{commonprograms}\\AviSynth 2.5\\*\"; DestDir:{code:GetAvsDirsLegacy|Prog}\\PlusBackup\\StartMenu; Components: avsmig\\backup; ExternalSize: 0; AfterInstall: WipeLegacyStartMenu; Flags: external onlyifdoesntexist skipifsourcedoesntexist uninsneveruninstall  \n\nSource: \"..\\gpl*.txt\"; DestDir: \"{app}\\License\"; Components: main; Flags: ignoreversion\nSource: \"..\\lgpl_for_used_libs.txt\"; DestDir: \"{app}\\License\"; Components: main; Flags: ignoreversion\n\n;Source: \"..\\Readme\\readme.txt\"; DestDir: \"{app}\"; Components: main; Flags: ignoreversion\nSource: \"..\\Readme\\readme_history.txt\"; DestDir: \"{app}\"; Components: main; Flags: ignoreversion\n\nSource: \"{#BuildDir32}\\Output\\AviSynth.dll\"; DestDir:{sys}; Components: main\\avs32; Flags: 32bit ignoreversion \nSource: \"{#BuildDir32}\\Output\\System\\DevIL.dll\"; DestDir:{sys}; Components: main\\avs32; Flags: 32bit ignoreversion \nSource: \"{#BuildDir32}\\Output\\Plugins\\*.dll\"; DestDir:{code:GetAvsDirsPlus|PlugPlus32}; Components: main\\avs32; Flags: ignoreversion \nSource: \"..\\ColorPresets\\*\"; DestDir:{code:GetAvsDirsPlus|PlugPlus32}; Components: main\\avs32; Flags: ignoreversion \n#ifdef WITH_VC_REDIST_XP\nSource: \"..\\Prerequisites\\VC_redist_14.27.29114.0.x86.exe\"; DestDir: {app}; Components: main\\avs32; Flags: deleteafterinstall; Check: IncludeVcRedist()\n#endif\n#ifdef WITH_VC_REDIST\n;get latest from https://www.visualstudio.com/downloads/\nSource: \"..\\Prerequisites\\VC_redist.x86.exe\"; DestDir: {app}; Components: main\\avs32; Flags: deleteafterinstall; Check: IncludeVcRedist()\n#endif\n\nSource: \"{#BuildDir64}\\Output\\AviSynth.dll\"; DestDir:{sys}; Components: main\\avs64; Flags: 64bit ignoreversion \nSource: \"{#BuildDir64}\\Output\\System\\DevIL.dll\"; DestDir:{sys}; Components: main\\avs64; Flags: 64bit ignoreversion \nSource: \"{#BuildDir64}\\Output\\Plugins\\*.dll\"; DestDir:{code:GetAvsDirsPlus|PlugPlus64}; Components: main\\avs64; Flags: ignoreversion \nSource: \"..\\ColorPresets\\*\"; DestDir:{code:GetAvsDirsPlus|PlugPlus64}; Components: main\\avs64; Flags: ignoreversion\n#ifdef WITH_VC_REDIST_XP\nSource: \"..\\Prerequisites\\VC_redist_14.27.29114.0.x64.exe\"; DestDir: {app}; Components: main\\avs64; Flags: deleteafterinstall; Check: IncludeVcRedist()\n#endif\n#ifdef WITH_VC_REDIST\n;get latest from https://www.visualstudio.com/downloads/\nSource: \"..\\Prerequisites\\VC_redist.x64.exe\"; DestDir: {app}; Components: main\\avs64; Flags: deleteafterinstall; Check: IncludeVcRedist()\n#endif\n\n#ifdef WITH_DOCS\n;don't forget to render .rst sources into html-format by issuing 'make html'. E.g. in the ..\\docs\\english\\\n;You needed a working python sphinx-build. https://www.sphinx-doc.org/\nSource: \"..\\docs\\*.css\"; DestDir: \"{app}\\docs\"; Components: docs; Flags: ignoreversion\n;Source: \"..\\docs\\czech\\*\"; DestDir: \"{app}\\docs\\Czech\"; Components: docs\\cs; Flags: ignoreversion recursesubdirs \nSource: \"..\\docs\\english\\build\\html\\*\"; DestDir: \"{app}\\docs\\English\"; Components: docs\\en docs\\enall; Flags: ignoreversion recursesubdirs \n;Source: \"..\\docs\\french\\*\"; DestDir: \"{app}\\docs\\French\"; Components: docs\\fr; Flags: ignoreversion recursesubdirs \n;Source: \"..\\docs\\german\\*\"; DestDir: \"{app}\\docs\\German\"; Components: docs\\de; Flags: ignoreversion recursesubdirs \n;Source: \"..\\docs\\italian\\*\"; DestDir: \"{app}\\docs\\Italian\"; Components: docs\\it; Flags: ignoreversion recursesubdirs \n;Source: \"..\\docs\\japanese\\*\"; DestDir: \"{app}\\docs\\Japanese\"; Components: docs\\ja; Flags: ignoreversion recursesubdirs \n;Source: \"..\\docs\\polish\\*\"; DestDir: \"{app}\\docs\\Polish\"; Components: docs\\pl; Flags: ignoreversion recursesubdirs \n;Source: \"..\\docs\\portugese\\*\"; DestDir: \"{app}\\docs\\Portuguese\"; Components: docs\\pt; Flags: ignoreversion recursesubdirs \n;Source: \"..\\docs\\russian\\*\"; DestDir: \"{app}\\docs\\Russian\"; Components: docs\\ru; Flags: ignoreversion recursesubdirs \n#endif\n\n#ifdef WITH_SDK\nSource: \"..\\FilterSDK\\*\"; DestDir: \"{app}\\FilterSDK\"; Components: sdk; Flags: ignoreversion recursesubdirs\nSource: \"{#BuildDir32}\\Output\\include\\*\"; DestDir: \"{app}\\FilterSDK\\include\\x86\"; Components: sdk; Flags: ignoreversion recursesubdirs\nSource: \"{#BuildDir64}\\Output\\include\\*\"; DestDir: \"{app}\\FilterSDK\\include\\x64\"; Components: sdk; Flags: ignoreversion recursesubdirs\nSource: \"{#BuildDir32}\\Output\\c_api\\*\"; DestDir: \"{app}\\FilterSDK\\lib\\x86\"; Components: sdk; Flags: ignoreversion recursesubdirs\nSource: \"{#BuildDir64}\\Output\\c_api\\*\"; DestDir: \"{app}\\FilterSDK\\lib\\x64\"; Components: sdk; Flags: ignoreversion recursesubdirs\n#endif\n\nSource: \"..\\Examples\\*\"; DestDir: \"{app}\\Examples\"; Components: examples; Flags: recursesubdirs \n\n[Registry]\nRoot: HKLM32; Subkey: \"Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\"; Flags: uninsdeletekey; Components: main\\avs32\nRoot: HKLM32; Subkey: \"Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\"; ValueName: \"\"; ValueType: string; ValueData: \"{#AvsName}\"; Components: main\\avs32\nRoot: HKLM32; Subkey: \"Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\\InProcServer32\"; ValueName: \"\"; ValueType: string; ValueData: \"AviSynth.dll\"; Components: main\\avs32\nRoot: HKLM32; Subkey: \"Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\\InProcServer32\"; ValueName: \"ThreadingModel\"; ValueType: string; ValueData: \"Apartment\"; Components: main\\avs32\n\nRoot: HKLM64; Subkey: \"Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\"; Flags: uninsdeletekey; Check:IsWin64; Components: main\\avs64\nRoot: HKLM64; Subkey: \"Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\"; ValueName: \"\"; ValueType: string; ValueData: \"{#AvsName}\"; Check:IsWin64; Components: main\\avs64\nRoot: HKLM64; Subkey: \"Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\\InProcServer32\"; ValueName: \"\"; ValueType: string; ValueData: \"AviSynth.dll\"; Check:IsWin64; Components: main\\avs64\nRoot: HKLM64; Subkey: \"Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\\InProcServer32\"; ValueName: \"ThreadingModel\"; ValueType: string; ValueData: \"Apartment\"; Check:IsWin64; Components: main\\avs64\n\nRoot: HKLM32; Subkey: \"Software\\Classes\\Media Type\\Extensions\\.avs\"; Flags: uninsdeletekey; Components: main\\avs32\nRoot: HKLM32; Subkey: \"Software\\Classes\\Media Type\\Extensions\\.avs\"; ValueName: \"Source Filter\"; ValueType: string; ValueData: \"{{D3588AB0-0781-11CE-B03A-0020AF0BA770}\"; Components: main\\avs32\nRoot: HKLM64; Subkey: \"Software\\Classes\\Media Type\\Extensions\\.avs\"; Flags: uninsdeletekey; Check:IsWin64; Components: main\\avs64\nRoot: HKLM64; Subkey: \"Software\\Classes\\Media Type\\Extensions\\.avs\"; ValueName: \"Source Filter\"; ValueType: string; ValueData: \"{{D3588AB0-0781-11CE-B03A-0020AF0BA770}\"; Check:IsWin64; Components: main\\avs64\n\nRoot: HKLM; Subkey: \"Software\\Classes\\.avs\"; ValueName: \"\"; ValueType: string; ValueData: \"avsfile\"; Flags: uninsdeletekey; Components: main\nRoot: HKLM; Subkey: \"Software\\Classes\\.avsi\"; ValueName: \"\"; ValueType: string; ValueData: \"avs_auto_file\"; Flags: uninsdeletekey; Components: main\n\nRoot: HKLM; Subkey: \"Software\\Classes\\.avs\\OpenWithList\\notepad.exe\"; Flags: uninsdeletekey; Components: associations\\openwithnotepad\nRoot: HKLM; Subkey: \"Software\\Classes\\avsfile\\OpenWithList\\notepad.exe\"; Flags: uninsdeletekey; Components: associations\\openwithnotepad\nRoot: HKLM; Subkey: \"Software\\Classes\\.avsi\\OpenWithList\\notepad.exe\"; Flags: uninsdeletekey; Components: associations\\openwithnotepad\nRoot: HKLM; Subkey: \"Software\\Classes\\avs_auto_file\\OpenWithList\\notepad.exe\"; Flags: uninsdeletekey; Components: associations\\openwithnotepad\nRoot: HKLM; Subkey: \"Software\\Classes\\.avs\\ShellNew\"; ValueName: \"NullFile\"; ValueType: string; ValueData: \"\"; Flags: uninsdeletekey; Components: associations\\shellnew\nRoot: HKLM; Subkey: \"Software\\Classes\\avsfile\\ShellNew\"; ValueName: \"NullFile\"; ValueType: string; ValueData: \"\"; Flags: uninsdeletekey; Components: associations\\shellnew\nRoot: HKLM; Subkey: \"Software\\Classes\\avsfile\\shell\\play\\command\"; ValueName: \"\"; ValueType: string; ValueData: \"\"\"{pf}\\Windows Media Player\\mplayer2.exe\"\" /Play \"\"%L\"\"\"; Flags: uninsdeletekey; Components: associations\\mplayer; Check: ExistsMPlayer2\nRoot: HKLM; Subkey: \"Software\\Classes\\avsfile\\shell\\play\\command\"; ValueName: \"\"; ValueType: string; ValueData: \"\"\"{pf}\\Windows Media Player\\wmplayer.exe\"\" \"\"%1\"\"\"; Flags: uninsdeletekey; Components: associations\\wmplayer; Check: ExistsWMPlayer\n\nRoot: HKLM; Subkey: \"Software\\Classes\\avsfile\"; ValueName: \"\"; ValueType: string; ValueData: \"{cm:FileTypeDescAvs,{#AvsName}}\"; Components: main; Flags: uninsdeletekey\nRoot: HKLM; Subkey: \"Software\\Classes\\avsfile\\DefaultIcon\"; ValueName: \"\"; ValueType: string; ValueData: \"{sys}\\AviSynth.dll,0\"; Components: main\\avs32\nRoot: HKLM; Subkey: \"Software\\Classes\\avsfile\\DefaultIcon\"; ValueName: \"\"; ValueType: string; ValueData: \"{win}\\system32\\AviSynth.dll,0\"; Components: main\\avs64 and not main\\avs32 \nRoot: HKLM; Subkey: \"Software\\Classes\\avs_auto_file\"; ValueName: \"\"; ValueType: string; ValueData: \"{cm:FileTypeDescAvsi,{#AvsName}}\"; Components: main; Flags: uninsdeletekey\nRoot: HKLM; Subkey: \"Software\\Classes\\avs_auto_file\\DefaultIcon\"; ValueName: \"\"; ValueType: string; ValueData: \"{sys}\\AviSynth.dll,1\"; Components: main\\avs32\nRoot: HKLM; Subkey: \"Software\\Classes\\avs_auto_file\\DefaultIcon\"; ValueName: \"\"; ValueType: string; ValueData: \"{win}\\system32\\AviSynth.dll,1\"; Components: main\\avs64 and not main\\avs32\n\nRoot: HKLM32; Subkey: \"Software\\Classes\\AVIFile\\Extensions\\AVS\"; ValueName: \"\"; ValueType: string; ValueData: \"{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\"; Components: main\\avs32; Flags: uninsdeletekey\nRoot: HKLM64; Subkey: \"Software\\Classes\\AVIFile\\Extensions\\AVS\"; ValueName: \"\"; ValueType: string; ValueData: \"{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\"; Components: main\\avs64; Flags: uninsdeletekey; Check:IsWin64\n\nRoot: HKLM32; Subkey: \"Software\\AviSynth\"; ValueName:\"\"; ValueType: string; ValueData: \"{app}\"; Components: main\\avs32; Flags: uninsdeletevalue uninsdeletekeyifempty\nRoot: HKLM32; Subkey: \"Software\\AviSynth\"; ValueName:\"plugindir2_5\"; ValueType: string; ValueData: \"{code:GetAvsDirsPlus|Plug32}\"; Components: main\\avs32; Flags: uninsdeletevalue\nRoot: HKLM32; Subkey: \"Software\\AviSynth\"; ValueName:\"plugindir+\"; ValueType: string; ValueData: \"{code:GetAvsDirsPlus|PlugPlus32}\"; Components: main\\avs32; Flags: uninsdeletevalue\n\nRoot: HKLM64; Subkey: \"Software\\AviSynth\"; ValueName:\"\"; ValueType: string; ValueData: \"{app}\"; Components: main\\avs64; Flags: uninsdeletevalue uninsdeletekeyifempty; Check:IsWin64\nRoot: HKLM64; Subkey: \"Software\\AviSynth\"; ValueName:\"plugindir2_5\"; ValueType: string; ValueData: \"{code:GetAvsDirsPlus|Plug64}\"; Components: main\\avs64; Check:IsWin64; Flags: uninsdeletevalue\nRoot: HKLM64; Subkey: \"Software\\AviSynth\"; ValueName:\"plugindir+\"; ValueType: string; ValueData: \"{code:GetAvsDirsPlus|PlugPlus64}\"; Components: main\\avs64; Check:IsWin64; Flags: uninsdeletevalue\n\n#ifdef WITH_SDK\n;Set SDK Environment Variable\nRoot: HKLM; Subkey: \"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment\"; ValueName: \"AVISYNTH_SDK_PATH\"; ValueType: string; ValueData: \"{app}\\FilterSDK\"; Components: sdk; Flags: uninsdeletevalue\n#endif\n;Delete Legacy AVS Install Entry\nRoot: HKLM32; Subkey: \"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\AviSynth\"; Flags: deletekey; Components: avsmig\\backup\n;Add entry for legacy AviSynth Program Folder\nRoot: HKLM32; Subkey: \"Software\\AviSynth\"; ValueName: \"LegacyDir\"; ValueType: string; ValueData: \"{code:GetAvsDirsLegacy|Prog}\"; Components: avsmig\\backup;\n\n[UninstallDelete]\nType: files; Name: \"{app}\\Setup Log*.txt\"\n\n[Run]\nFilename: \"{app}\\VC_redist.x86.exe\"; Parameters: \"/q /norestart\"; Components: main\\avs32 ;Description: \"{#VcVersion} (x86)\"; StatusMsg: \"{cm:InstallStatusRuntime,{#VcVersion},x86}\"; Check: IncludeVcRedist()\nFilename: \"{app}\\VC_redist.x64.exe\"; Parameters: \"/q /norestart\"; Components: main\\avs64 ;Description: \"{#VcVersion} (x64)\"; StatusMsg: \"{cm:InstallStatusRuntime,{#VcVersion},x64}\"; Check: IncludeVcRedist()\n\n[Ini]\n;Backup legacy AviSynth registry entries to .reg file\n#define BReg \"{code:GetAvsDirsLegacy|Prog}\\PlusBackup\\PlusBackup.reg\"\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\"; Key: \"@\"; String: \"{code:GetKey|HKLM32^Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778%7d}\"; Components: avsmig\\backup  \nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\\InProcServer32\"; Key: \"@\"; String: \"{code:GetKey|HKLM32^Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778%7d\\InProcServer32}\"; Components: avsmig\\backup  \nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\\InProcServer32\"; Key: \"\"\"ThreadingModel\"\"\"; String: \"{code:GetKey|HKLM32^Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778%7d\\InProcServer32^ThreadingModel}\"; Components: avsmig\\backup  \nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM64}\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\"; Key: \"@\"; String: \"{code:GetKey|HKLM64^Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778%7d}\"; Components: avsmig\\backup; Check:IsLegacyAvsInstalled('64')  \nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM64}\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\\InProcServer32\"; Key: \"@\"; String: \"{code:GetKey|HKLM64^Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778%7d\\InProcServer32}\"; Components: avsmig\\backup; Check:IsLegacyAvsInstalled('64')\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM64}\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\\InProcServer32\"; Key: \"\"\"ThreadingModel\"\"\"; String: \"{code:GetKey|HKLM64^Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778%7d\\InProcServer32^ThreadingModel}\"; Components: avsmig\\backup; Check:IsLegacyAvsInstalled('64')\n\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\Classes\\Media Type\\Extensions\\.avs\"; Key: \"@\"; String: \"{code:GetKey|HKLM32^Software\\Classes\\Media Type\\Extensions\\.avs}\"; Components: avsmig\\backup  \nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\Classes\\Media Type\\Extensions\\.avs\"; Key: \"\"\"Source Filter\"\"\"; String: \"{code:GetKey|HKLM32^Software\\Classes\\Media Type\\Extensions\\.avs^Source Filter}\"; Components: avsmig\\backup  \n\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\Classes\\.avs\"; Key: \"@\"; String: \"{code:GetKey|HKLM32^Software\\Classes\\.avs}\"; Components: avsmig\\backup  \nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\Classes\\.avsi\"; Key: \"@\"; String: \"{code:GetKey|HKLM32^Software\\Classes\\.avsi}\"; Components: avsmig\\backup  \nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\Classes\\avsfile\"; Key: \"@\"; String: \"{code:GetKey|HKLM32^Software\\Classes\\avsfile}\"; Components: avsmig\\backup  \nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\Classes\\avsfile\\DefaultIcon\"; Key: \"@\"; String: \"{code:GetKey|HKLM32^Software\\Classes\\avsfile\\DefaultIcon}\"; Components: avsmig\\backup  \nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\Classes\\avs_auto_file\"; Key: \"@\"; String: \"{code:GetKey|HKLM32^Software\\Classes\\avs_auto_file}\"; Components: avsmig\\backup  \nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\Classes\\avs_auto_file\\DefaultIcon\"; Key: \"@\"; String: \"{code:GetKey|HKLM32^Software\\Classes\\avs_auto_file\\DefaultIcon}\"; Components: avsmig\\backup\n\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\Classes\\AVIFile\\Extensions\\AVS\"; Key: \"@\"; String: \"{code:GetKey|HKLM32^Software\\Classes\\AVIFile\\Extensions\\AVS}\"; Components: avsmig\\backup\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM64}\\Classes\\AVIFile\\Extensions\\AVS\"; Key: \"@\"; String: \"{code:GetKey|HKLM64^Software\\Classes\\AVIFile\\Extensions\\AVS}\"; Components: avsmig\\backup; Check:IsLegacyAvsInstalled('64')\n\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\AviSynth\"; Key: \"@\"; String: \"{code:GetAvsDirsLegacyFmt|Prog}\"; Components: avsmig\\backup\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\AviSynth\"; Key: \"\"\"plugindir2_5\"\"\"; String: \"{code:GetAvsDirsLegacyFmt|Plug32}\"; Components: avsmig\\backup\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM64}\\AviSynth\"; Key: \"@\"; String: \"{code:GetAvsDirsLegacyFmt|Prog}\"; Components: avsmig\\backup; Check:IsLegacyAvsInstalled('64')\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM64}\\AviSynth\"; Key: \"\"\"plugindir2_5\"\"\"; String: \"{code:GetAvsDirsLegacyFmt|Plug64}\"; Components: avsmig\\backup; Check:IsLegacyAvsInstalled('64')\n\n#define LIns \"\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\AviSynth\"\n;Backup legacy AviSynth installer registry entries\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}{#LIns}\"; Key: \"\"\"DisplayIcon\"\"\"; String: \"{code:GetKey|HKLM32^Software{#LIns}^DisplayIcon}\"; Components: avsmig\\backup\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}{#LIns}\"; Key: \"\"\"DisplayName\"\"\"; String: \"{code:GetKey|HKLM32^Software{#LIns}^DisplayName}\"; Components: avsmig\\backup\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}{#LIns}\"; Key: \"\"\"DisplayVersion\"\"\"; String: \"{code:GetKey|HKLM32^Software{#LIns}^DisplayVersion}\"; Components: avsmig\\backup\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}{#LIns}\"; Key: \"\"\"Publisher\"\"\"; String: \"{code:GetKey|HKLM32^Software{#LIns}^Publisher}\"; Components: avsmig\\backup\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}{#LIns}\"; Key: \"\"\"UninstallString\"\"\"; String: \"{code:GetKey|HKLM32^Software{#LIns}^UninstallString}\"; Components: avsmig\\backup\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}{#LIns}\"; Key: \"\"\"URLInfoAbout\"\"\"; String: \"{code:GetKey|HKLM32^Software{#LIns}^URLInfoAbout}\"; Components: avsmig\\backup; AfterInstall: FixRegFile\n\n[Code]\ntype\n  TAvsDirs = record\n    IsSet: Boolean;\n    Prog: String;\n    Plug32: String;\n    PlugPlus32:String;\n    Plug64: String;\n    PlugPlus64: String;\n  end;\n\nvar\n  PluginPage: TInputDirWizardPage;\n  MigrationPage: TInputOptionWizardPage;\n  AvsDirsPlus, AvsDirsDefault, AvsDirsReg: TAvsDirs;\n  MigrationState: (miNotStarted, miPickedBackup, miPickedUninst, miFailedUninst);\n\nconst\n  AVSUNINST_YES = 6;\n  AVSUNINST_OK = 2;\n  LogIndent = '--- ';\n\nprocedure LogVal(Prefix, Val: String);\nbegin\n  Log(Prefix + ': ' + Val);\nend;\n\nprocedure LogValInd(Prefix, Val: String);\nbegin\n  Log(LogIndent + Prefix + ': ' + Val);\nend;\n\nprocedure LogAvsDirectories(AvsDir: TAvsDirs);\nbegin\n  with AvsDir do begin \n    LogValInd('Program',Prog);\n    LogValInd('Plugins',Plug32);\n    LogValInd('Plugins+',PlugPlus32);\n    LogValInd('Plugins64',Plug64);\n    LogValInd('Plugins64+',PlugPlus64);\n  end;\nend;\n\n// Directory handling                                                              \nprocedure SetAvsDirsDefault;\nbegin\n  if not AvsDirsDefault.IsSet then begin\n    AvsDirsDefault.Plug32 := '\\plugins';\n    AvsDirsDefault.PlugPlus32 := '\\plugins+';\n    AvsDirsDefault.Plug64 := '\\plugins64';\n    AvsDirsDefault.PlugPlus64 := '\\plugins64+';\n    AvsDirsDefault.IsSet := True;\n  end;\nend;\n\nprocedure SetAvsDirsReg;\nbegin\n  if not AvsDirsReg.IsSet then begin\n    RegQueryStringValue(HKLM32, 'Software\\AviSynth', '', AvsDirsReg.Prog);\n    RegQueryStringValue(HKLM32, 'Software\\AviSynth', 'PluginDir2_5', AvsDirsReg.Plug32);\n    RegQueryStringValue(HKLM32, 'Software\\AviSynth', 'PluginDir+', AvsDirsReg.PlugPlus32);\n    AvsDirsReg.IsSet := True; \n    if IsWin64 then begin\n      RegQueryStringValue(HKLM64, 'Software\\AviSynth', 'PluginDir2_5', AvsDirsReg.Plug64);\n      RegQueryStringValue(HKLM64, 'Software\\AviSynth', 'PluginDir+', AvsDirsReg.PlugPlus64);\n    end;\n  end;\nend;\n\nprocedure SetAvsDirsPlus;\nbegin\n  SetAvsDirsDefault();\n  SetAvsDirsReg();\n\n  if not AvsDirsPlus.IsSet or (AvsDirsPlus.Prog <> WizardDirValue()) then begin\n    with AvsDirsPlus do begin\n      Prog := WizardDirValue();\n      if DirExists(AvsDirsReg.Plug32) then \n        Plug32 := AvsDirsReg.Plug32\n      else Plug32 := AvsDirsPlus.Prog + AvsDirsDefault.Plug32;\n\n      if DirExists(AvsDirsReg.PlugPlus32) then \n        PlugPlus32 := AvsDirsReg.PlugPlus32\n      else PlugPlus32 := AvsDirsPlus.Prog + AvsDirsDefault.PlugPlus32;\n\n      if DirExists(AvsDirsReg.Plug64) then \n        Plug64 := AvsDirsReg.Plug64\n      else Plug64 := AvsDirsPlus.Prog + AvsDirsDefault.Plug64;\n\n      if DirExists(AvsDirsReg.PlugPlus64) then \n        PlugPlus64 := AvsDirsReg.PlugPlus64\n      else PlugPlus64 := AvsDirsPlus.Prog + AvsDirsDefault.PlugPlus64;    \n    end;\n    AvsDirsPlus.IsSet := True;\n  end;\n\n  if IsComponentSelected('avsmig\\uninst') then begin\n    AvsDirsPlus.Plug32 := AvsDirsPlus.Prog + AvsDirsDefault.Plug32;\n    AvsDirsPlus.Plug64 := AvsDirsPlus.Prog + AvsDirsDefault.Plug64;\n  end else if IsComponentSelected('avsmig\\backup') then begin\n    if DirExists(AvsDirsReg.Plug32) then\n      AvsDirsPlus.Plug32 := AvsDirsReg.Plug32;\n    if DirExists(AvsDirsReg.Plug64) then  \n      AvsDirsPlus.Plug64 := AvsDirsReg.Plug64; \n  end;\nend;\n\nprocedure UpdatePluginDirPage(Mode: String);\nbegin\n  if Mode = 'read' then begin\n    PluginPage.Values[0] := AvsDirsPlus.Plug32;\n    PluginPage.Values[1] := AvsDirsPlus.PlugPlus32;\n    PluginPage.Values[2] := AvsDirsPlus.Plug64;\n    PluginPage.Values[3] := AvsDirsPlus.PlugPlus64;\n  end else if Mode = 'write' then begin\n    AvsDirsPlus.Plug32 := PluginPage.Values[0];\n    AvsDirsPlus.PlugPlus32 := PluginPage.Values[1];\n    AvsDirsPlus.Plug64 := PluginPage.Values[2];\n    AvsDirsPlus.PlugPlus64 := PluginPage.Values[3];\n  end;\nend;\n\n// Helper functions\n\nfunction BoolToStr(Param: Boolean): String;\nbegin\n  if Param then\n    Result := 'Yes'\n  else\n    Result := 'No';\nend;\n\nprocedure CloseAvsUninstDialog(BtnId: WORD);\nvar\n  Wnd: HWND;\n  WM_COMMAND: Longint;\n  BN_CLICKED: Longint;\n  WParam: Longint;\n  UninstTimeout: Integer;\n  WndTitle: String;\n\nbegin\n  WM_COMMAND := $0111;\n  BN_CLICKED := 245;\n  UninstTimeout := 10000;\n  case GetUILanguage() of\n    $0409,$0809,$0109,$0C09: WndTitle := 'AviSynth Uninstall';\n    $0405: WndTitle := 'Odinstalovat AviSynth';\n    $0407,$0807,$0C07: WndTitle := 'AviSynth Deinstallation';\n    $040C,$080C,$0C0C,$140C: WndTitle := 'Désinstallation de AviSynth';\n    $0410: WndTitle := 'Disinstallazione di AviSynth';\n    $0411: WndTitle := 'AviSynth アンインストール';\n    $0816: WndTitle := 'Desinstalação de AviSynth';\n    $0416: WndTitle := 'Desinstalação do AviSynth';\n    $0419: WndTitle := 'Удаление AviSynth';\n    $0408: WndTitle := 'Απεγκατάσταση του ''AviSynth''';\n  else WndTitle := 'AviSynth Uninstall';\n  end;\n\n  repeat\n    Sleep(300);\n    Wnd := FindWindowByWindowName(WndTitle);\n    UninstTimeout := UninstTimeout - 500;  \n  until (Wnd <> 0) or (UninstTimeout <= 0);\n  if Wnd <> 0 then begin\n    WParam := (BN_CLICKED shl 16) or BtnId;\n    SendMessage(Wnd, WM_COMMAND, WParam, Wnd);\n  end;\nend;\n\nfunction IsSamePath(Path1, Path2: String): Boolean;\nvar \n  Path1Sanitized, Path2Sanitized: String;\nbegin\n  Path1Sanitized := Lowercase(RemoveBackslashUnlessRoot(Trim(Path1)));\n  Path2Sanitized := Lowercase(RemoveBackslashUnlessRoot(Trim(Path2)));\nResult := Path1Sanitized = Path2Sanitized\nend;\n\nprocedure Explode(var Dest: TArrayOfString; Text: String; Separator: String);\nvar\n\ti: Integer;\nbegin\n\ti := 0;\n\trepeat\n\t\tSetArrayLength(Dest, i+1);\n\t\tif Pos(Separator,Text) > 0 then\tbegin\n\t\t\tDest[i] := Copy(Text, 1, Pos(Separator, Text)-1);\n\t\t\tText := Copy(Text, Pos(Separator,Text) + Length(Separator), Length(Text));\n\t\t\ti := i + 1;\n\t\tend else begin\n\t\t\t Dest[i] := Text;\n\t\t\t Text := '';\n\t\tend;\n\tuntil Length(Text)=0;\nend;\n\nfunction FmtRegFileString(Param: String): String;\nbegin\n  StringChangeEx(Param,'\\','\\\\', True);\n  StringChangeEx(Param,'\"','\\\"', True);\n  Result := '\"' + Param + '\"';\nend;\n\nfunction IsAvsPlusInstalled: Boolean;\nbegin\n  Result := RegValueExists(HKLM32,'Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{#AppId}_is1', 'UninstallString');\nend;\n\nfunction IsLegacyAvsInstalled(Param: String): Boolean;\nbegin\n  case Param of\n    '32': Result := DirExists(AvsDirsReg.Prog) and not IsAvsPlusInstalled;\n    '64': Result := IsWin64 and DirExists(AvsDirsReg.Plug64) and not IsAvsPlusInstalled;\n  end;\nend;\n\nprocedure SetInputs(ID: Integer; State: Boolean);\nbegin\n  PluginPage.Edits[ID].Enabled := State\n  PluginPage.PromptLabels[ID].Enabled := State\n  PluginPage.Buttons[ID].Enabled := State\nend;\n\nprocedure SetMigrationComponent();\nvar\n  Index: Integer;\nbegin\n  Index := WizardForm.ComponentsList.Items.IndexOf(FmtMessage(CustomMessage('CmpMigUninstall'),['{#AvsName}']));\n  if Index <> -1 then\n    WizardForm.ComponentsList.Checked[Index] := MigrationState = miPickedUninst;\n  \n  Index := WizardForm.ComponentsList.Items.IndexOf(FmtMessage(CustomMessage('CmpMigBackup'),['{#AvsName}']));\n  if Index <> -1 then\n    WizardForm.ComponentsList.Checked[Index] := MigrationState = miPickedBackup;\nend;\n\n\n// Event functions\n\nfunction InitializeSetup(): Boolean;\nbegin\n  SetAvsDirsReg();\n  SetAvsDirsDefault();\n  Result := True\nend;\n\nprocedure InitializeWizard;\nbegin\n  WizardForm.Bevel.Visible := False;\n  WizardForm.Bevel1.Visible := False;\n  WizardForm.MainPanel.Color := $a35460;\n  WizardForm.MainPanel.Font.Color := $fcfcfc;\n  WizardForm.PageNameLabel.Font.Color := $fcfcfc;\n  //WizardForm.InnerPage.Color := $ffffff;\n  WizardForm.WelcomePage.Color := $fcfcfc;\n  WizardForm.ReadyMemo.ScrollBars:= ssVertical;\n \n  \n\n  MigrationPage := CreateInputOptionPage(wpSelectDir, CustomMessage('MigPageCaption'), FmtMessage(CustomMessage('MigPageDescription'),['{#AvsName}']),\n                   FmtMessage(CustomMessage('MigPageSubCaption'),['{#AvsName}',AvsDirsReg.Prog]), True, False)\n  \n  MigrationPage.Add(FmtMessage(CustomMessage('MigPageOptionBackup'),['{#AvsName}']))\n  MigrationPage.Add(FmtMessage(CustomMessage('MigPageOptionUninstall'),['{#AvsName}']))\n  MigrationPage.SelectedValueIndex := 0;\n\n  PluginPage := CreateInputDirPage(wpSelectComponents,\n    FmtMessage(CustomMessage('PlugPageCaption'),['{#AvsName}']),FmtMessage(CustomMessage('PlugPageDescription'),['{#AvsName}']),\n    FmtMessage(CustomMessage('PlugPageSubCaption'),['{#AvsName}']), true, '');\n  PluginPage.Add(FmtMessage(CustomMessage('PlugPagePlugDirLegacy'),['32']));\n  PluginPage.Add(FmtMessage(CustomMessage('PlugPagePlugDirPlus'),['32','{#AvsName}']));  \n  PluginPage.Add(FmtMessage(CustomMessage('PlugPagePlugDirLegacy'),['64']));\n  PluginPage.Add(FmtMessage(CustomMessage('PlugPagePlugDirPlus'),['64','{#AvsName}']));\nend;\n\nfunction NextButtonClick(CurPageID: Integer): Boolean;\nvar\n  I: Integer;\nbegin\n  if CurPageID = wpSelectDir then begin\n    SetAvsDirsPlus()\n    Result := True\n\n  end else if CurpageID = MigrationPage.ID then begin\n    if MigrationPage.SelectedValueIndex = 1 then \n      MigrationState := miPickedUninst\n    else\n      MigrationState := miPickedBackup;\n    SetMigrationComponent()\n    SetAvsDirsPlus()\n    Result := True\n\n  end else if CurPageID = wpSelectComponents then begin\n    SetAvsDirsPlus();\n    UpdatePluginDirPage('read');\n    if IsComponentSelected('main\\avs64') then begin                                                       \n      if IsComponentSelected('avsmig\\backup') and IsLegacyAvsInstalled('64') then\n        SetInputs(2,false)\n      else SetInputs(2,true);\n      SetInputs(3,true);\n    end else begin\n      SetInputs(2,false);\n      SetInputs(3,false);\n    end;\n    if IsComponentSelected('main\\avs32') then begin\n      if IsComponentSelected('avsmig\\backup') and DirExists(AvsDirsReg.Plug32) then\n        SetInputs(0,false)\n      else SetInputs(0,true);\n      SetInputs(1,true);\n    end else begin\n      SetInputs(0,false);\n      SetInputs(1,false);\n    end;\n    Result := True\n\n  end else if CurPageID = PluginPage.ID then begin\n    UpdatePluginDirPage('write');\n    Result := True;\n  end else\n    Result := True;\nend;\n\nprocedure CurStepChanged(CurStep: TSetupStep);\nvar\n  ResultCode: Integer;\n  LogFilePath: String;\n\nbegin\n  if CurStep = ssInstall then begin\n    LogVal('Installing components', WizardSelectedComponents(false));\n    LogVal('Legacy x86 AviSynth installed', BoolToStr(IsLegacyAvsInstalled('32')));\n    LogVal('Legacy x64 AviSynth installed', BoolToStr(IsLegacyAvsInstalled('64')));\n    LogVal('AviSynth+ installed', BoolToStr(IsAvsPlusInstalled));\n    Log('RegDirectories:');\n    LogAvsDirectories(AvsDirsReg);\n    Log('AvsPlusDirectories:');\n    LogAvsDirectories(AvsDirsPlus);\n\n    if MigrationState = miPickedUninst then begin\n      Log('Uninstalling legacy AviSynth');\n      if Exec(AvsDirsReg.Prog+'\\Uninstall.exe', '/S', '', SW_SHOW, ewWaitUntilIdle, ResultCode) then begin\n        CloseAvsUninstDialog(AVSUNINST_YES)\n        CloseAvsUninstDialog(AVSUNINST_OK)\n      end else begin\n        MigrationState := miFailedUninst;\n         SuppressibleMsgBox(FmtMessage(CustomMessage('MigPageUninstallFailed'),[SysErrorMessage(ResultCode)]), mbError, MB_OK, -1);\n      end;\n    end;\n    end else if CurStep = ssDone then begin\n    LogFilePath := ExpandConstant('{log}');\n    FileCopy(LogFilePath, WizardDirValue + '\\' + ExtractFileName(LogFilePath) , false); \n  end;\nend;\n\nfunction ShouldSkipPage(PageID: Integer): Boolean;\nbegin\n  if (PageID = MigrationPage.ID) and not IsLegacyAvsInstalled('32') then\n    Result := True                    \n  else if (PageID = PluginPage.ID) and not IsComponentSelected('custplug') then\n    Result := True\n  else Result := False\nend;\n\nprocedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);\nvar\n  AvsDirLegacyUninst: String;\n  ResultCode: Integer;\nbegin\n  if (CurUninstallStep = usPostUninstall) and RegQueryStringValue(HKLM32, 'Software\\AviSynth', 'LegacyDir', AvsDirLegacyUninst) then begin\n    RenameFile(AvsDirLegacyUninst + '\\PlusBackup\\sys32\\AviSynth.dll', ExpandConstant('{sys}\\AviSynth.dll'))\n    RenameFile(AvsDirLegacyUninst + '\\PlusBackup\\sys32\\DevIL.dll', ExpandConstant('{sys}\\DevIL.dll'));\n    RenameFile(AvsDirLegacyUninst + '\\PlusBackup\\StartMenu', ExpandConstant('{commonprograms}\\AviSynth 2.5'));\n    if IsWin64 then begin\n      EnableFsRedirection(False);\n      { Since the installer runs in x86 mode we need redirection to be disabled here for 2 reasons:\n          1. To make [sys] expand to the System32, not SysWoW64.\n          2. To run the correct x64 regedit.exe on x64 systems to import our backup regfile.\n             Using the x86 regedit.exe would cause HKLM\\Software\\AviSynth to be redirected to HKLM\\Software\\WoW6432Node\\AviSynth,\n             which would potentially cause the x86 plugins folder value to be overwritten by its x64 counterpart.\n      }\n      RenameFile(AvsDirLegacyUninst + '\\PlusBackup\\sys64\\AviSynth.dll', ExpandConstant('{sys}\\AviSynth.dll')); \n      RenameFile(AvsDirLegacyUninst + '\\PlusBackup\\sys64\\DevIL.dll', ExpandConstant('{sys}\\DevIL.dll'));\n    end;\n    if Exec(ExpandConstant('{win}\\regedit.exe'), '/s \"'+ AvsDirLegacyUninst +'\\PlusBackup\\PlusBackup.reg\"', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then begin\n      DelTree(AvsDirLegacyUninst + '\\PlusBackup', True, True, True);\n      RegDeleteValue(HKLM32, 'Software\\AviSynth', 'LegacyDir');\n    end else\n       SuppressibleMsgBox(FmtMessage(CustomMessage('BackupRestoreFailed'),[SysErrorMessage(ResultCode)]), mbError, MB_OK,-1);\n    EnableFsRedirection(True);\n  end;  \nend;\n\n// Checks and {code ...} snippets \nProcedure FixRegFile;\nvar\n  FileContent: Array of String;\n  RegFile: String;\nbegin\n  RegFile := AvsDirsReg.Prog + '\\PlusBackup\\PlusBackup.reg';\n  LoadStringsFromFile(RegFile, FileContent);\n  SaveStringToFile(RegFile, 'Windows Registry Editor Version 5.00', False);\n  SaveStringsToFile(RegFile, FileContent, True);\nend;\n\nfunction GetKey(Param: String): String;\nvar\n  RootKey: Integer;\n  Value, ValueName: String;\n  Params: Array of String;\nbegin\n  Explode(Params, Param, '^');\n  case Params[0] of\n    'HKLM32': RootKey := HKLM32;\n    'HKLM64': RootKey := HKLM64;\n    'HKCU32': RootKey := HKCU32;\n    'HKCU64': RootKey := HKCU64;\n  end;\n  if GetArrayLength(Params) = 3 then ValueName  := Params[2] else ValueName := ''; \n  RegQueryStringValue(RootKey, Params[1], ValueName, Value);\n  Result := FmtRegFileString(Value)\nend;\n\nfunction GetAvsDirsLegacy(Param: String): String;\nbegin\n    case Param of\n      'Prog': Result := AvsDirsReg.Prog;\n      'Plug32': Result := AvsDirsReg.Plug32;\n      'Plug64': Result := AvsDirsReg.Plug64;\n    end;\nend;\n\nfunction GetAvsDirsLegacyFmt(Param: String): String;\nbegin\n  Result := FmtRegFileString(GetAvsDirsLegacy(Param));\nend;\n\nfunction GetAvsDirsPlus(Param: String): String;\nbegin\n    case Param of \n      'Plug32': Result := AvsDirsPlus.Plug32;                       \n      'PlugPlus32': Result := AvsDirsPlus.PlugPlus32;\n      'Plug64': Result := AvsDirsPlus.Plug64;\n      'PlugPlus64': Result := AvsDirsPlus.PlugPlus64;\n    end;\nend;\n\nfunction GetRegSoft(Param: String): String;\nbegin\n  if IsWin64 then begin\n    case Param of\n      'HKLM32': Result := 'HKEY_LOCAL_MACHINE\\Software\\Wow6432Node';\n      'HKLM64': Result := 'HKEY_LOCAL_MACHINE\\Software';\n      'HKCU32': Result := 'HKEY_CURRENT_USER\\Software\\Wow6432Node';\n      'HKCU64': Result := 'HKEY_CURRENT_USER\\Software';\n    end;\n  end else begin\n    case Param of\n      'HKLM32': Result := 'HKEY_LOCAL_MACHINE\\Software';\n      'HKCU32': Result := 'HKEY_CURRENT_USER\\Software';\n    end;\n  end;\nend;\n\nfunction IsValidPluginMigration(Param: String): Boolean;\nbegin\n  case Param of\n    '32': Result := IsLegacyAvsInstalled('32') and DirExists(AvsDirsReg.Plug32) and not IsSamePath(AvsDirsReg.Plug32,AvsDirsPlus.Plug32);\n    '64': Result := IsLegacyAvsInstalled('64') and not IsSamePath(AvsDirsReg.Plug64,AvsDirsPlus.Plug64);\n  end;\nend;\n\nprocedure WipeLegacyPluginDirs(Param: String);\nbegin\n  case Param of\n    '32': DelTree(AvsDirsReg.Plug32, True, True, False);\n    '64': DelTree(AvsDirsReg.Plug64, True, True, False);\n  end;\n  LogVal('Wiping legacy AviSynth Plugin Directory',Param);\n  RemoveDir(AvsDirsReg.Prog);\nend;\n\nprocedure WipeLegacyStartMenu;\nbegin\n  DelTree(ExpandConstant('{commonprograms}\\AviSynth 2.5'), True, True, False);\nend;\n\nfunction IncludeVcRedist(): boolean;\nbegin\n  #ifdef WITH_VC_REDIST\n  Result := True;\n  #else\n  Result := False;\n  #endif\nend;\n\nfunction ExistsMPlayer2(): boolean;\nbegin\n  Result := FileExists(ExpandConstant('{pf}\\Windows Media Player\\mplayer2.exe'));\nend;\n\nfunction ExistsWMPlayer(): boolean;\nbegin\n  Result := FileExists(ExpandConstant('{pf}\\Windows Media Player\\wmplayer.exe'));\nend;\n"
  },
  {
    "path": "distrib/WinInstaller/avisynth+_arm64.iss",
    "content": "﻿;!!!Conditional!!!  comment out the following define to ignore VS redistributables\n;#define WITH_VC_REDIST\n\n;headers and c lib are OK, but documentation is not up to date, anyway we include them\n;#define WITH_SDK\n\n;this section is not up to date, don't include them\n;#define WITH_DOCS\n\n;!!!Conditional!!!  comment out the following define to include project web url\n;original Avs+ project page is not maintained at the moment (Dec. 2017) and contains very old content\n;#define WITH_AVSPLUS_URL\n\n#define AvsName \"AviSynth+\"\n#define AvsFriendlyName \"AviSynthPlus\"\n#define AvsPublisher \"The Public\"\n#define AppId \"{AC78780F-BACA-4805-8D4F-AE1B52B7E7D3}\"\n#define AvsGitURL \"https://github.com/AviSynth/AviSynthPlus/\"\n\n#ifdef WITH_AVSPLUS_URL\n#define AvsWebURL \"https://github.com/AviSynth/AviSynthPlus/\"\n#endif\n\n;There is no specific x86/x64 output directory.\n;folders must be created relative to the folder of iss script.\n;Build x64 avs+ then copy the Output folder (with the folder itself) here\n#define BuildDir64 \"arm64\"\n;.\\arm64\\usr\\...\n\n#define VcVersion \"Microsoft Visual C++ Redistributable for Visual Studio 2015-2022\"\n\n#define BuildDate GetFileDateTimeString(AddBackslash(BuildDir64) + \"usr\\aarch64-w64-mingw32\\bin\\AviSynth.dll\", 'yyyy/mm/dd', '-',);\n\n#expr Exec(\"powershell\", \"-ExecutionPolicy unrestricted -File update_git_rev.ps1\", SourcePath, 1)\n#define IniFile AddBackslash(SourcePath) + \"git_rev.ini\"\n#define RevisionNumber  ReadIni(IniFile, \"Version\", \"RevisionNumber\" )\n#define Revision        ReadIni(IniFile, \"Version\", \"Revision\"       )\n#define IsRelease       ReadIni(IniFile, \"Version\", \"IsRelease\"      )\n#define Version         ReadIni(IniFile, \"Version\", \"Version\"        )\n#define Branch          ReadIni(IniFile, \"Version\", \"Branch\"         )\n\n[Setup]\nAppId={{#AppId}\nAppName={#AvsName}\nAppVersion={#Version}.{#RevisionNumber}\n#if IsRelease == \"True\"\n  AppVerName={#AvsName} {#Version}\n  OutputBaseFilename={#AvsFriendlyName}_{#Version}\n#else\n  AppVerName={#AvsName} {#Version} r{#RevisionNumber}\n  OutputBaseFilename={#AvsFriendlyName}-r{#RevisionNumber}-{#Branch}-{#Revision}\n#endif\nAppPublisher={#AvsPublisher}\n#ifdef WITH_AVSPLUS_URL\nAppPublisherURL={#AvsWebURL}\nAppSupportURL={#AvsWebURL}/get_started.html\n#endif\nAppUpdatesURL={#AvsGitURL}/releases\nAppReadmeFile={#AvsGitURL}/blob/master/README.rst\nVersionInfoVersion={#Version}.{#RevisionNumber}\nDefaultDirName={pf}\\{#AvsName}\nDefaultGroupName={#AvsName}\nDisableWelcomePage=no\nDisableProgramGroupPage=yes\nSetupIconFile=..\\Icons\\Ico\\InstIcon.ico\nUninstallDisplayIcon=..\\Icons\\Ico\\InstIcon.ico\nWizardImageFile=WizardImageBig.bmp\nWizardSmallImageFile=WizardImageSmall.bmp\nChangesAssociations=yes\nChangesEnvironment=yes\n;Compression=lzma2/max\nCompression=lzma2/ultra\nSolidCompression=yes\nSetupLogging=yes\nMinVersion=10.0.16299\n\n[Types]\nName: \"compact\"; Description: \"{cm:CompactInstallation}\"\nName: \"full\"; Description: \"{cm:FullInstallation}\"\nName: \"custom\"; Description: \"{cm:CustomInstallation}\"; Flags: iscustom\n\n[Languages]\nName: \"en\"; MessagesFile: \"Translations\\en.isl\"; LicenseFile: ..\\gpl.txt\nName: \"pt_br\"; MessagesFile: \"Translations\\pt_br.isl\"; LicenseFile: ..\\gpl-pt_br.txt\nName: \"cs\"; MessagesFile: \"Translations\\cs.isl\"; LicenseFile: ..\\gpl-cs.txt\nName: \"fr\"; MessagesFile: \"Translations\\fr.isl\"; LicenseFile: ..\\gpl-fr.txt\nName: \"de\"; MessagesFile: \"Translations\\de.isl\"; LicenseFile: ..\\gpl-de.txt\n;Name: \"gr\"; MessagesFile: \"compiler:Languages\\Greek.isl\"\nName: \"it\"; MessagesFile: \"Translations\\it.isl\"; LicenseFile: ..\\gpl-it.txt\nName: \"ja\"; MessagesFile: \"Translations\\ja.isl\"; LicenseFile: ..\\gpl-ja.txt\nName: \"pl\"; MessagesFile: \"Translations\\pl.isl\"; LicenseFile: ..\\gpl-pl.txt\nName: \"pt\"; MessagesFile: \"Translations\\pt.isl\"; LicenseFile: ..\\gpl-pt.txt\nName: \"ru\"; MessagesFile: \"Translations\\ru.isl\"; LicenseFile: ..\\gpl-ru.txt\n\n[Components]\nName: \"main\"; Description: \"{cm:CmpMain,{#AvsName}}\"; Types: full compact custom; Flags: fixed\n;Name: \"main\\avs32\"; Description: \"{#AvsName} (x86)\"; Types: full compact custom\nName: \"main\\avs64\"; Description: \"{#AvsName} (arm64)\"; Types: full compact custom; Check: IsWin64\n\n#ifdef WITH_DOCS\nName: \"docs\"; Description: \"{cm:CmpDocs}\";\nName: \"docs\\enall\"; Description: \"{cm:CmpDocsEn}\"; Types: full; Languages: not en\nName: \"docs\\en\"; Description: \"{cm:CmpDocsEn}\"; Types: full compact custom; Languages: en\n;Name: \"docs\\cs\"; Description: \"{cm:CmpDocsCs}\"; Types: full compact custom; Languages: cs\n;Name: \"docs\\de\"; Description: \"{cm:CmpDocsDe}\"; Types: full compact custom; Languages: de\n;Name: \"docs\\fr\"; Description: \"{cm:CmpDocsFr}\"; Types: full compact custom; Languages: fr\n;Name: \"docs\\it\"; Description: \"{cm:CmpDocsIt}\"; Types: full compact custom; Languages: it\n;Name: \"docs\\ja\"; Description: \"{cm:CmpDocsJa}\"; Types: full compact custom; Languages: ja\n;Name: \"docs\\pl\"; Description: \"{cm:CmpDocsPl}\"; Types: full compact custom; Languages: pl\n;Name: \"docs\\pt\"; Description: \"{cm:CmpDocsPt}\"; Types: full compact custom; Languages: pt pt_br\n;Name: \"docs\\ru\"; Description: \"{cm:CmpDocsRu}\"; Types: full compact custom; Languages: ru\n#endif\n\nName: \"associations\"; Description: \"{cm:SelectAssoc}\"; Types: full custom\nName: \"associations\\openwithnotepad\"; Description: \"{cm:SelectAssocNotepadOpen}\"; Types: full custom\nName: \"associations\\shellnew\"; Description: \"{cm:SelectAssocAddShellNew}\"; Types: full custom\nName: \"associations\\mplayer\"; Description: \"{cm:SelectAssocMplayer}\"; Types: full custom; Check: ExistsMPlayer2\nName: \"associations\\wmplayer\"; Description: \"{cm:SelectAssocWMplayer}\"; Types: full custom; Check: ExistsWMPlayer\n\nName: \"examples\"; Description: \"{cm:CmpDocsExamples}\"; Types: full compact custom\n#ifdef WITH_SDK\nName: \"sdk\"; Description: \"{cm:CmpSdk,{#AvsName}}\"; Types: full custom\n#endif\n\nName: \"avsmig\"; Description: \"{cm:CmpMig}\"; Types: full compact custom; Flags: fixed; Check: IsLegacyAvsInstalled('32')\nName: \"avsmig\\uninst\"; Description: \"{cm:CmpMigUninstall,{#AvsName}}\"; Flags: fixed exclusive\nName: \"avsmig\\backup\"; Description: \"{cm:CmpMigBackup}\"; Flags: fixed exclusive\n\nName: \"custplug\"; Description: \"{cm:CmpCustomizePluginPaths}\"; Types: custom\n\n[Dirs]\n;Name: \"{code:GetAvsDirsPlus|Plug32}\"; Components: main\\avs32\n;Name: \"{code:GetAvsDirsPlus|PlugPlus32}\"; Components: main\\avs32\nName: \"{code:GetAvsDirsPlus|Plug64}\"; Components: main\\avs64\nName: \"{code:GetAvsDirsPlus|PlugPlus64}\"; Components: main\\avs64\n\n[Files]\n;Source: \"{code:GetAvsDirsLegacy|Plug32}\\*\"; DestDir:{code:GetAvsDirsPlus|Plug32}; Components: avsmig\\uninst; ExternalSize: 0; Check: IsValidPluginMigration('32'); AfterInstall: WipeLegacyPluginDirs('32'); Flags: external recursesubdirs createallsubdirs uninsneveruninstall onlyifdoesntexist skipifsourcedoesntexist\nSource: \"{code:GetAvsDirsLegacy|Plug64}\\*\"; DestDir:{code:GetAvsDirsPlus|Plug64}; Components: avsmig\\uninst; ExternalSize: 0; Check: IsValidPluginMigration('64'); AfterInstall: WipeLegacyPluginDirs('64'); Flags: external recursesubdirs createallsubdirs uninsneveruninstall 64bit onlyifdoesntexist skipifsourcedoesntexist\n\n;Source: \"{sys}\\AviSynth.dll\"; DestDir:{code:GetAvsDirsLegacy|Prog}\\PlusBackup\\sys32; Components: avsmig\\backup; ExternalSize: 0; Flags: external onlyifdoesntexist skipifsourcedoesntexist uninsneveruninstall\n;Source: \"{sys}\\DevIL.dll\"; DestDir:{code:GetAvsDirsLegacy|Prog}\\PlusBackup\\sys32; Components: avsmig\\backup; ExternalSize: 0; Flags: external onlyifdoesntexist skipifsourcedoesntexist uninsneveruninstall\nSource: \"{sys}\\AviSynth.dll\"; DestDir:{code:GetAvsDirsLegacy|Prog}\\PlusBackup\\sys64; Components: avsmig\\backup; ExternalSize: 0; Flags: 64bit external onlyifdoesntexist skipifsourcedoesntexist uninsneveruninstall; Check: IsWin64\nSource: \"{sys}\\DevIL.dll\"; DestDir:{code:GetAvsDirsLegacy|Prog}\\PlusBackup\\sys64; Components: avsmig\\backup; ExternalSize: 0; Flags: 64bit external onlyifdoesntexist skipifsourcedoesntexist uninsneveruninstall; Check: IsWin64\nSource: \"{commonprograms}\\AviSynth 2.5\\*\"; DestDir:{code:GetAvsDirsLegacy|Prog}\\PlusBackup\\StartMenu; Components: avsmig\\backup; ExternalSize: 0; AfterInstall: WipeLegacyStartMenu; Flags: external onlyifdoesntexist skipifsourcedoesntexist uninsneveruninstall\n\nSource: \"..\\gpl*.txt\"; DestDir: \"{app}\\License\"; Components: main; Flags: ignoreversion\nSource: \"..\\lgpl_for_used_libs.txt\"; DestDir: \"{app}\\License\"; Components: main; Flags: ignoreversion\n\n;Source: \"..\\Readme\\readme.txt\"; DestDir: \"{app}\"; Components: main; Flags: ignoreversion\nSource: \"..\\Readme\\readme_history.txt\"; DestDir: \"{app}\"; Components: main; Flags: ignoreversion\n\nSource: \"{#BuildDir64}\\usr\\aarch64-w64-mingw32\\bin\\AviSynth.dll\"; DestDir:{sys}; Components: main\\avs64; Flags: 64bit ignoreversion\n;Source: \"{#BuildDir64}\\usr\\aarch64-w64-mingw32\\bin\\DevIL.dll\"; DestDir:{sys}; Components: main\\avs64; Flags: 64bit ignoreversion\nSource: \"{#BuildDir64}\\usr\\aarch64-w64-mingw32\\lib\\avisynth\\*.dll\"; DestDir:{code:GetAvsDirsPlus|PlugPlus64}; Components: main\\avs64; Flags: ignoreversion\nSource: \"..\\ColorPresets\\*\"; DestDir:{code:GetAvsDirsPlus|PlugPlus64}; Components: main\\avs64; Flags: ignoreversion\n#ifdef WITH_VC_REDIST\n;get latest from https://www.visualstudio.com/downloads/\nSource: \"..\\Prerequisites\\VC_redist.arm64.exe\"; DestDir: {app}; Components: main\\avs64; Flags: deleteafterinstall; Check: IncludeVcRedist()\n#endif\n\n#ifdef WITH_DOCS\n;don't forget to render .rst sources into html-format by issuing 'make html'. E.g. in the ..\\docs\\english\\\n;You needed a working python sphinx-build. https://www.sphinx-doc.org/\n;Source: \"..\\docs\\*.css\"; DestDir: \"{app}\\docs\"; Components: docs; Flags: ignoreversion\n;Source: \"..\\docs\\czech\\*\"; DestDir: \"{app}\\docs\\Czech\"; Components: docs\\cs; Flags: ignoreversion recursesubdirs\nSource: \"..\\docs\\english\\build\\html\\*\"; DestDir: \"{app}\\docs\\English\"; Components: docs\\en docs\\enall; Flags: ignoreversion recursesubdirs\n;Source: \"..\\docs\\french\\*\"; DestDir: \"{app}\\docs\\French\"; Components: docs\\fr; Flags: ignoreversion recursesubdirs\n;Source: \"..\\docs\\german\\*\"; DestDir: \"{app}\\docs\\German\"; Components: docs\\de; Flags: ignoreversion recursesubdirs\n;Source: \"..\\docs\\italian\\*\"; DestDir: \"{app}\\docs\\Italian\"; Components: docs\\it; Flags: ignoreversion recursesubdirs\n;Source: \"..\\docs\\japanese\\*\"; DestDir: \"{app}\\docs\\Japanese\"; Components: docs\\ja; Flags: ignoreversion recursesubdirs\n;Source: \"..\\docs\\polish\\*\"; DestDir: \"{app}\\docs\\Polish\"; Components: docs\\pl; Flags: ignoreversion recursesubdirs\n;Source: \"..\\docs\\portugese\\*\"; DestDir: \"{app}\\docs\\Portuguese\"; Components: docs\\pt; Flags: ignoreversion recursesubdirs\n;Source: \"..\\docs\\russian\\*\"; DestDir: \"{app}\\docs\\Russian\"; Components: docs\\ru; Flags: ignoreversion recursesubdirs\n#endif\n\n#ifdef WITH_SDK\nSource: \"..\\docs\\english\\build\\html\\avisynthdoc\\FilterSDK\\*\"; DestDir: \"{app}\\FilterSDK\"; Components: sdk; Flags: ignoreversion recursesubdirs\nSource: \"{#BuildDir64}\\usr\\aarch64-w64-mingw32\\include\\*\"; DestDir: \"{app}\\FilterSDK\\include\\arm64\"; Components: sdk; Flags: ignoreversion recursesubdirs\nSource: \"{#BuildDir64}\\usr\\aarch64-w64-mingw32\\lib\\*.a\"; DestDir: \"{app}\\FilterSDK\\lib\\arm64\"; Components: sdk; Flags: ignoreversion recursesubdirs\n#endif\n\nSource: \"..\\Examples\\*\"; DestDir: \"{app}\\Examples\"; Components: examples; Flags: recursesubdirs\n\n[Registry]\n;Root: HKLM32; Subkey: \"Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\"; Flags: uninsdeletekey; Components: main\\avs32\n;Root: HKLM32; Subkey: \"Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\"; ValueName: \"\"; ValueType: string; ValueData: \"{#AvsName}\"; Components: main\\avs32\n;Root: HKLM32; Subkey: \"Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\\InProcServer32\"; ValueName: \"\"; ValueType: string; ValueData: \"AviSynth.dll\"; Components: main\\avs32\n;Root: HKLM32; Subkey: \"Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\\InProcServer32\"; ValueName: \"ThreadingModel\"; ValueType: string; ValueData: \"Apartment\"; Components: main\\avs32\n\nRoot: HKLM64; Subkey: \"Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\"; Flags: uninsdeletekey; Check:IsWin64; Components: main\\avs64\nRoot: HKLM64; Subkey: \"Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\"; ValueName: \"\"; ValueType: string; ValueData: \"{#AvsName}\"; Check:IsWin64; Components: main\\avs64\nRoot: HKLM64; Subkey: \"Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\\InProcServer32\"; ValueName: \"\"; ValueType: string; ValueData: \"AviSynth.dll\"; Check:IsWin64; Components: main\\avs64\nRoot: HKLM64; Subkey: \"Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\\InProcServer32\"; ValueName: \"ThreadingModel\"; ValueType: string; ValueData: \"Apartment\"; Check:IsWin64; Components: main\\avs64\n\n;Root: HKLM32; Subkey: \"Software\\Classes\\Media Type\\Extensions\\.avs\"; Flags: uninsdeletekey; Components: main\\avs32\n;Root: HKLM32; Subkey: \"Software\\Classes\\Media Type\\Extensions\\.avs\"; ValueName: \"Source Filter\"; ValueType: string; ValueData: \"{{D3588AB0-0781-11CE-B03A-0020AF0BA770}\"; Components: main\\avs32\nRoot: HKLM64; Subkey: \"Software\\Classes\\Media Type\\Extensions\\.avs\"; Flags: uninsdeletekey; Check:IsWin64; Components: main\\avs64\nRoot: HKLM64; Subkey: \"Software\\Classes\\Media Type\\Extensions\\.avs\"; ValueName: \"Source Filter\"; ValueType: string; ValueData: \"{{D3588AB0-0781-11CE-B03A-0020AF0BA770}\"; Check:IsWin64; Components: main\\avs64\n\nRoot: HKLM; Subkey: \"Software\\Classes\\.avs\"; ValueName: \"\"; ValueType: string; ValueData: \"avsfile\"; Flags: uninsdeletekey; Components: main\nRoot: HKLM; Subkey: \"Software\\Classes\\.avsi\"; ValueName: \"\"; ValueType: string; ValueData: \"avs_auto_file\"; Flags: uninsdeletekey; Components: main\n\nRoot: HKLM; Subkey: \"Software\\Classes\\.avs\\OpenWithList\\notepad.exe\"; Flags: uninsdeletekey; Components: associations\\openwithnotepad\nRoot: HKLM; Subkey: \"Software\\Classes\\avsfile\\OpenWithList\\notepad.exe\"; Flags: uninsdeletekey; Components: associations\\openwithnotepad\nRoot: HKLM; Subkey: \"Software\\Classes\\.avsi\\OpenWithList\\notepad.exe\"; Flags: uninsdeletekey; Components: associations\\openwithnotepad\nRoot: HKLM; Subkey: \"Software\\Classes\\avs_auto_file\\OpenWithList\\notepad.exe\"; Flags: uninsdeletekey; Components: associations\\openwithnotepad\nRoot: HKLM; Subkey: \"Software\\Classes\\.avs\\ShellNew\"; ValueName: \"NullFile\"; ValueType: string; ValueData: \"\"; Flags: uninsdeletekey; Components: associations\\shellnew\nRoot: HKLM; Subkey: \"Software\\Classes\\avsfile\\ShellNew\"; ValueName: \"NullFile\"; ValueType: string; ValueData: \"\"; Flags: uninsdeletekey; Components: associations\\shellnew\nRoot: HKLM; Subkey: \"Software\\Classes\\avsfile\\shell\\play\\command\"; ValueName: \"\"; ValueType: string; ValueData: \"\"\"{pf}\\Windows Media Player\\mplayer2.exe\"\" /Play \"\"%L\"\"\"; Flags: uninsdeletekey; Components: associations\\mplayer; Check: ExistsMPlayer2\nRoot: HKLM; Subkey: \"Software\\Classes\\avsfile\\shell\\play\\command\"; ValueName: \"\"; ValueType: string; ValueData: \"\"\"{pf}\\Windows Media Player\\wmplayer.exe\"\" \"\"%1\"\"\"; Flags: uninsdeletekey; Components: associations\\wmplayer; Check: ExistsWMPlayer\n\nRoot: HKLM; Subkey: \"Software\\Classes\\avsfile\"; ValueName: \"\"; ValueType: string; ValueData: \"{cm:FileTypeDescAvs,{#AvsName}}\"; Components: main; Flags: uninsdeletekey\n;Root: HKLM; Subkey: \"Software\\Classes\\avsfile\\DefaultIcon\"; ValueName: \"\"; ValueType: string; ValueData: \"{sys}\\AviSynth.dll,0\"; Components: main\\avs32\n;Root: HKLM; Subkey: \"Software\\Classes\\avsfile\\DefaultIcon\"; ValueName: \"\"; ValueType: string; ValueData: \"{win}\\system32\\AviSynth.dll,0\"; Components: main\\avs64 and not main\\avs32\nRoot: HKLM; Subkey: \"Software\\Classes\\avs_auto_file\"; ValueName: \"\"; ValueType: string; ValueData: \"{cm:FileTypeDescAvsi,{#AvsName}}\"; Components: main; Flags: uninsdeletekey\n;Root: HKLM; Subkey: \"Software\\Classes\\avs_auto_file\\DefaultIcon\"; ValueName: \"\"; ValueType: string; ValueData: \"{sys}\\AviSynth.dll,1\"; Components: main\\avs32\n;Root: HKLM; Subkey: \"Software\\Classes\\avs_auto_file\\DefaultIcon\"; ValueName: \"\"; ValueType: string; ValueData: \"{win}\\system32\\AviSynth.dll,1\"; Components: main\\avs64 and not main\\avs32\n\n;Root: HKLM32; Subkey: \"Software\\Classes\\AVIFile\\Extensions\\AVS\"; ValueName: \"\"; ValueType: string; ValueData: \"{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\"; Components: main\\avs32; Flags: uninsdeletekey\nRoot: HKLM64; Subkey: \"Software\\Classes\\AVIFile\\Extensions\\AVS\"; ValueName: \"\"; ValueType: string; ValueData: \"{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\"; Components: main\\avs64; Flags: uninsdeletekey; Check:IsWin64\n\n;Root: HKLM32; Subkey: \"Software\\AviSynth\"; ValueName:\"\"; ValueType: string; ValueData: \"{app}\"; Components: main\\avs32; Flags: uninsdeletevalue uninsdeletekeyifempty\n;Root: HKLM32; Subkey: \"Software\\AviSynth\"; ValueName:\"plugindir2_5\"; ValueType: string; ValueData: \"{code:GetAvsDirsPlus|Plug32}\"; Components: main\\avs32; Flags: uninsdeletevalue\n;Root: HKLM32; Subkey: \"Software\\AviSynth\"; ValueName:\"plugindir+\"; ValueType: string; ValueData: \"{code:GetAvsDirsPlus|PlugPlus32}\"; Components: main\\avs32; Flags: uninsdeletevalue\n\nRoot: HKLM64; Subkey: \"Software\\AviSynth\"; ValueName:\"\"; ValueType: string; ValueData: \"{app}\"; Components: main\\avs64; Flags: uninsdeletevalue uninsdeletekeyifempty; Check:IsWin64\nRoot: HKLM64; Subkey: \"Software\\AviSynth\"; ValueName:\"plugindir2_5\"; ValueType: string; ValueData: \"{code:GetAvsDirsPlus|Plug64}\"; Components: main\\avs64; Check:IsWin64; Flags: uninsdeletevalue\nRoot: HKLM64; Subkey: \"Software\\AviSynth\"; ValueName:\"plugindir+\"; ValueType: string; ValueData: \"{code:GetAvsDirsPlus|PlugPlus64}\"; Components: main\\avs64; Check:IsWin64; Flags: uninsdeletevalue\n\n#ifdef WITH_SDK\n;Set SDK Environment Variable\nRoot: HKLM; Subkey: \"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment\"; ValueName: \"AVISYNTH_SDK_PATH\"; ValueType: string; ValueData: \"{app}\\FilterSDK\"; Components: sdk; Flags: uninsdeletevalue\n#endif\n;Delete Legacy AVS Install Entry\nRoot: HKLM32; Subkey: \"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\AviSynth\"; Flags: deletekey; Components: avsmig\\backup\n;Add entry for legacy AviSynth Program Folder\nRoot: HKLM32; Subkey: \"Software\\AviSynth\"; ValueName: \"LegacyDir\"; ValueType: string; ValueData: \"{code:GetAvsDirsLegacy|Prog}\"; Components: avsmig\\backup;\n\n[UninstallDelete]\nType: files; Name: \"{app}\\Setup Log*.txt\"\n\n[Run]\n;Filename: \"{app}\\VC_redist.x86.exe\"; Parameters: \"/q /norestart\"; Components: main\\avs32 ;Description: \"{#VcVersion} (x86)\"; StatusMsg: \"{cm:InstallStatusRuntime,{#VcVersion},x86}\"; Check: IncludeVcRedist()\n;Filename: \"{app}\\VC_redist.x64.exe\"; Parameters: \"/q /norestart\"; Components: main\\avs64 ;Description: \"{#VcVersion} (x64)\"; StatusMsg: \"{cm:InstallStatusRuntime,{#VcVersion},x64}\"; Check: IncludeVcRedist()\n\n[Ini]\n;Backup legacy AviSynth registry entries to .reg file\n#define BReg \"{code:GetAvsDirsLegacy|Prog}\\PlusBackup\\PlusBackup.reg\"\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\"; Key: \"@\"; String: \"{code:GetKey|HKLM32^Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778%7d}\"; Components: avsmig\\backup\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\\InProcServer32\"; Key: \"@\"; String: \"{code:GetKey|HKLM32^Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778%7d\\InProcServer32}\"; Components: avsmig\\backup\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\\InProcServer32\"; Key: \"\"\"ThreadingModel\"\"\"; String: \"{code:GetKey|HKLM32^Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778%7d\\InProcServer32^ThreadingModel}\"; Components: avsmig\\backup\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM64}\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\"; Key: \"@\"; String: \"{code:GetKey|HKLM64^Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778%7d}\"; Components: avsmig\\backup; Check:IsLegacyAvsInstalled('64')\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM64}\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\\InProcServer32\"; Key: \"@\"; String: \"{code:GetKey|HKLM64^Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778%7d\\InProcServer32}\"; Components: avsmig\\backup; Check:IsLegacyAvsInstalled('64')\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM64}\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778}\\InProcServer32\"; Key: \"\"\"ThreadingModel\"\"\"; String: \"{code:GetKey|HKLM64^Software\\Classes\\CLSID\\{{E6D6B700-124D-11D4-86F3-DB80AFD98778%7d\\InProcServer32^ThreadingModel}\"; Components: avsmig\\backup; Check:IsLegacyAvsInstalled('64')\n\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\Classes\\Media Type\\Extensions\\.avs\"; Key: \"@\"; String: \"{code:GetKey|HKLM32^Software\\Classes\\Media Type\\Extensions\\.avs}\"; Components: avsmig\\backup\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\Classes\\Media Type\\Extensions\\.avs\"; Key: \"\"\"Source Filter\"\"\"; String: \"{code:GetKey|HKLM32^Software\\Classes\\Media Type\\Extensions\\.avs^Source Filter}\"; Components: avsmig\\backup\n\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\Classes\\.avs\"; Key: \"@\"; String: \"{code:GetKey|HKLM32^Software\\Classes\\.avs}\"; Components: avsmig\\backup\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\Classes\\.avsi\"; Key: \"@\"; String: \"{code:GetKey|HKLM32^Software\\Classes\\.avsi}\"; Components: avsmig\\backup\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\Classes\\avsfile\"; Key: \"@\"; String: \"{code:GetKey|HKLM32^Software\\Classes\\avsfile}\"; Components: avsmig\\backup\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\Classes\\avsfile\\DefaultIcon\"; Key: \"@\"; String: \"{code:GetKey|HKLM32^Software\\Classes\\avsfile\\DefaultIcon}\"; Components: avsmig\\backup\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\Classes\\avs_auto_file\"; Key: \"@\"; String: \"{code:GetKey|HKLM32^Software\\Classes\\avs_auto_file}\"; Components: avsmig\\backup\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\Classes\\avs_auto_file\\DefaultIcon\"; Key: \"@\"; String: \"{code:GetKey|HKLM32^Software\\Classes\\avs_auto_file\\DefaultIcon}\"; Components: avsmig\\backup\n\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\Classes\\AVIFile\\Extensions\\AVS\"; Key: \"@\"; String: \"{code:GetKey|HKLM32^Software\\Classes\\AVIFile\\Extensions\\AVS}\"; Components: avsmig\\backup\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM64}\\Classes\\AVIFile\\Extensions\\AVS\"; Key: \"@\"; String: \"{code:GetKey|HKLM64^Software\\Classes\\AVIFile\\Extensions\\AVS}\"; Components: avsmig\\backup; Check:IsLegacyAvsInstalled('64')\n\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\AviSynth\"; Key: \"@\"; String: \"{code:GetAvsDirsLegacyFmt|Prog}\"; Components: avsmig\\backup\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}\\AviSynth\"; Key: \"\"\"plugindir2_5\"\"\"; String: \"{code:GetAvsDirsLegacyFmt|Plug32}\"; Components: avsmig\\backup\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM64}\\AviSynth\"; Key: \"@\"; String: \"{code:GetAvsDirsLegacyFmt|Prog}\"; Components: avsmig\\backup; Check:IsLegacyAvsInstalled('64')\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM64}\\AviSynth\"; Key: \"\"\"plugindir2_5\"\"\"; String: \"{code:GetAvsDirsLegacyFmt|Plug64}\"; Components: avsmig\\backup; Check:IsLegacyAvsInstalled('64')\n\n#define LIns \"\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\AviSynth\"\n;Backup legacy AviSynth installer registry entries\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}{#LIns}\"; Key: \"\"\"DisplayIcon\"\"\"; String: \"{code:GetKey|HKLM32^Software{#LIns}^DisplayIcon}\"; Components: avsmig\\backup\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}{#LIns}\"; Key: \"\"\"DisplayName\"\"\"; String: \"{code:GetKey|HKLM32^Software{#LIns}^DisplayName}\"; Components: avsmig\\backup\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}{#LIns}\"; Key: \"\"\"DisplayVersion\"\"\"; String: \"{code:GetKey|HKLM32^Software{#LIns}^DisplayVersion}\"; Components: avsmig\\backup\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}{#LIns}\"; Key: \"\"\"Publisher\"\"\"; String: \"{code:GetKey|HKLM32^Software{#LIns}^Publisher}\"; Components: avsmig\\backup\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}{#LIns}\"; Key: \"\"\"UninstallString\"\"\"; String: \"{code:GetKey|HKLM32^Software{#LIns}^UninstallString}\"; Components: avsmig\\backup\nFilename: \"{#BReg}\"; Section:\"{code:GetRegSoft|HKLM32}{#LIns}\"; Key: \"\"\"URLInfoAbout\"\"\"; String: \"{code:GetKey|HKLM32^Software{#LIns}^URLInfoAbout}\"; Components: avsmig\\backup; AfterInstall: FixRegFile\n\n[Code]\ntype\n  TAvsDirs = record\n    IsSet: Boolean;\n    Prog: String;\n    Plug32: String;\n    PlugPlus32:String;\n    Plug64: String;\n    PlugPlus64: String;\n  end;\n\nvar\n  PluginPage: TInputDirWizardPage;\n  MigrationPage: TInputOptionWizardPage;\n  AvsDirsPlus, AvsDirsDefault, AvsDirsReg: TAvsDirs;\n  MigrationState: (miNotStarted, miPickedBackup, miPickedUninst, miFailedUninst);\n\nconst\n  AVSUNINST_YES = 6;\n  AVSUNINST_OK = 2;\n  LogIndent = '--- ';\n\nprocedure LogVal(Prefix, Val: String);\nbegin\n  Log(Prefix + ': ' + Val);\nend;\n\nprocedure LogValInd(Prefix, Val: String);\nbegin\n  Log(LogIndent + Prefix + ': ' + Val);\nend;\n\nprocedure LogAvsDirectories(AvsDir: TAvsDirs);\nbegin\n  with AvsDir do begin\n    LogValInd('Program',Prog);\n    LogValInd('Plugins',Plug32);\n    LogValInd('Plugins+',PlugPlus32);\n    LogValInd('Plugins64',Plug64);\n    LogValInd('Plugins64+',PlugPlus64);\n  end;\nend;\n\n// Directory handling\nprocedure SetAvsDirsDefault;\nbegin\n  if not AvsDirsDefault.IsSet then begin\n    AvsDirsDefault.Plug32 := '\\plugins';\n    AvsDirsDefault.PlugPlus32 := '\\plugins+';\n    AvsDirsDefault.Plug64 := '\\plugins64';\n    AvsDirsDefault.PlugPlus64 := '\\plugins64+';\n    AvsDirsDefault.IsSet := True;\n  end;\nend;\n\nprocedure SetAvsDirsReg;\nbegin\n  if not AvsDirsReg.IsSet then begin\n    RegQueryStringValue(HKLM32, 'Software\\AviSynth', '', AvsDirsReg.Prog);\n    RegQueryStringValue(HKLM32, 'Software\\AviSynth', 'PluginDir2_5', AvsDirsReg.Plug32);\n    RegQueryStringValue(HKLM32, 'Software\\AviSynth', 'PluginDir+', AvsDirsReg.PlugPlus32);\n    AvsDirsReg.IsSet := True;\n    if IsWin64 then begin\n      RegQueryStringValue(HKLM64, 'Software\\AviSynth', 'PluginDir2_5', AvsDirsReg.Plug64);\n      RegQueryStringValue(HKLM64, 'Software\\AviSynth', 'PluginDir+', AvsDirsReg.PlugPlus64);\n    end;\n  end;\nend;\n\nprocedure SetAvsDirsPlus;\nbegin\n  SetAvsDirsDefault();\n  SetAvsDirsReg();\n\n  if not AvsDirsPlus.IsSet or (AvsDirsPlus.Prog <> WizardDirValue()) then begin\n    with AvsDirsPlus do begin\n      Prog := WizardDirValue();\n      if DirExists(AvsDirsReg.Plug32) then\n        Plug32 := AvsDirsReg.Plug32\n      else Plug32 := AvsDirsPlus.Prog + AvsDirsDefault.Plug32;\n\n      if DirExists(AvsDirsReg.PlugPlus32) then\n        PlugPlus32 := AvsDirsReg.PlugPlus32\n      else PlugPlus32 := AvsDirsPlus.Prog + AvsDirsDefault.PlugPlus32;\n\n      if DirExists(AvsDirsReg.Plug64) then\n        Plug64 := AvsDirsReg.Plug64\n      else Plug64 := AvsDirsPlus.Prog + AvsDirsDefault.Plug64;\n\n      if DirExists(AvsDirsReg.PlugPlus64) then\n        PlugPlus64 := AvsDirsReg.PlugPlus64\n      else PlugPlus64 := AvsDirsPlus.Prog + AvsDirsDefault.PlugPlus64;\n    end;\n    AvsDirsPlus.IsSet := True;\n  end;\n\n  if IsComponentSelected('avsmig\\uninst') then begin\n    AvsDirsPlus.Plug32 := AvsDirsPlus.Prog + AvsDirsDefault.Plug32;\n    AvsDirsPlus.Plug64 := AvsDirsPlus.Prog + AvsDirsDefault.Plug64;\n  end else if IsComponentSelected('avsmig\\backup') then begin\n    if DirExists(AvsDirsReg.Plug32) then\n      AvsDirsPlus.Plug32 := AvsDirsReg.Plug32;\n    if DirExists(AvsDirsReg.Plug64) then\n      AvsDirsPlus.Plug64 := AvsDirsReg.Plug64;\n  end;\nend;\n\nprocedure UpdatePluginDirPage(Mode: String);\nbegin\n  if Mode = 'read' then begin\n    PluginPage.Values[0] := AvsDirsPlus.Plug32;\n    PluginPage.Values[1] := AvsDirsPlus.PlugPlus32;\n    PluginPage.Values[2] := AvsDirsPlus.Plug64;\n    PluginPage.Values[3] := AvsDirsPlus.PlugPlus64;\n  end else if Mode = 'write' then begin\n    AvsDirsPlus.Plug32 := PluginPage.Values[0];\n    AvsDirsPlus.PlugPlus32 := PluginPage.Values[1];\n    AvsDirsPlus.Plug64 := PluginPage.Values[2];\n    AvsDirsPlus.PlugPlus64 := PluginPage.Values[3];\n  end;\nend;\n\n// Helper functions\n\nfunction BoolToStr(Param: Boolean): String;\nbegin\n  if Param then\n    Result := 'Yes'\n  else\n    Result := 'No';\nend;\n\nprocedure CloseAvsUninstDialog(BtnId: WORD);\nvar\n  Wnd: HWND;\n  WM_COMMAND: Longint;\n  BN_CLICKED: Longint;\n  WParam: Longint;\n  UninstTimeout: Integer;\n  WndTitle: String;\n\nbegin\n  WM_COMMAND := $0111;\n  BN_CLICKED := 245;\n  UninstTimeout := 10000;\n  case GetUILanguage() of\n    $0409,$0809,$0109,$0C09: WndTitle := 'AviSynth Uninstall';\n    $0405: WndTitle := 'Odinstalovat AviSynth';\n    $0407,$0807,$0C07: WndTitle := 'AviSynth Deinstallation';\n    $040C,$080C,$0C0C,$140C: WndTitle := 'Désinstallation de AviSynth';\n    $0410: WndTitle := 'Disinstallazione di AviSynth';\n    $0411: WndTitle := 'AviSynth アンインストール';\n    $0816: WndTitle := 'Desinstalação de AviSynth';\n    $0416: WndTitle := 'Desinstalação do AviSynth';\n    $0419: WndTitle := 'Удаление AviSynth';\n    $0408: WndTitle := 'Απεγκατάσταση του ''AviSynth''';\n  else WndTitle := 'AviSynth Uninstall';\n  end;\n\n  repeat\n    Sleep(300);\n    Wnd := FindWindowByWindowName(WndTitle);\n    UninstTimeout := UninstTimeout - 500;\n  until (Wnd <> 0) or (UninstTimeout <= 0);\n  if Wnd <> 0 then begin\n    WParam := (BN_CLICKED shl 16) or BtnId;\n    SendMessage(Wnd, WM_COMMAND, WParam, Wnd);\n  end;\nend;\n\nfunction IsSamePath(Path1, Path2: String): Boolean;\nvar\n  Path1Sanitized, Path2Sanitized: String;\nbegin\n  Path1Sanitized := Lowercase(RemoveBackslashUnlessRoot(Trim(Path1)));\n  Path2Sanitized := Lowercase(RemoveBackslashUnlessRoot(Trim(Path2)));\nResult := Path1Sanitized = Path2Sanitized\nend;\n\nprocedure Explode(var Dest: TArrayOfString; Text: String; Separator: String);\nvar\n\ti: Integer;\nbegin\n\ti := 0;\n\trepeat\n\t\tSetArrayLength(Dest, i+1);\n\t\tif Pos(Separator,Text) > 0 then\tbegin\n\t\t\tDest[i] := Copy(Text, 1, Pos(Separator, Text)-1);\n\t\t\tText := Copy(Text, Pos(Separator,Text) + Length(Separator), Length(Text));\n\t\t\ti := i + 1;\n\t\tend else begin\n\t\t\t Dest[i] := Text;\n\t\t\t Text := '';\n\t\tend;\n\tuntil Length(Text)=0;\nend;\n\nfunction FmtRegFileString(Param: String): String;\nbegin\n  StringChangeEx(Param,'\\','\\\\', True);\n  StringChangeEx(Param,'\"','\\\"', True);\n  Result := '\"' + Param + '\"';\nend;\n\nfunction IsAvsPlusInstalled: Boolean;\nbegin\n  Result := RegValueExists(HKLM32,'Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{#AppId}_is1', 'UninstallString');\nend;\n\nfunction IsLegacyAvsInstalled(Param: String): Boolean;\nbegin\n  case Param of\n    '32': Result := DirExists(AvsDirsReg.Prog) and not IsAvsPlusInstalled;\n    '64': Result := IsWin64 and DirExists(AvsDirsReg.Plug64) and not IsAvsPlusInstalled;\n  end;\nend;\n\nprocedure SetInputs(ID: Integer; State: Boolean);\nbegin\n  PluginPage.Edits[ID].Enabled := State\n  PluginPage.PromptLabels[ID].Enabled := State\n  PluginPage.Buttons[ID].Enabled := State\nend;\n\nprocedure SetMigrationComponent();\nvar\n  Index: Integer;\nbegin\n  Index := WizardForm.ComponentsList.Items.IndexOf(FmtMessage(CustomMessage('CmpMigUninstall'),['{#AvsName}']));\n  if Index <> -1 then\n    WizardForm.ComponentsList.Checked[Index] := MigrationState = miPickedUninst;\n\n  Index := WizardForm.ComponentsList.Items.IndexOf(FmtMessage(CustomMessage('CmpMigBackup'),['{#AvsName}']));\n  if Index <> -1 then\n    WizardForm.ComponentsList.Checked[Index] := MigrationState = miPickedBackup;\nend;\n\n\n// Event functions\n\nfunction InitializeSetup(): Boolean;\nbegin\n  SetAvsDirsReg();\n  SetAvsDirsDefault();\n  Result := True\nend;\n\nprocedure InitializeWizard;\nbegin\n  WizardForm.Bevel.Visible := False;\n  WizardForm.Bevel1.Visible := False;\n  WizardForm.MainPanel.Color := $a35460;\n  WizardForm.MainPanel.Font.Color := $fcfcfc;\n  WizardForm.PageNameLabel.Font.Color := $fcfcfc;\n  //WizardForm.InnerPage.Color := $ffffff;\n  WizardForm.WelcomePage.Color := $fcfcfc;\n  WizardForm.ReadyMemo.ScrollBars:= ssVertical;\n\n\n\n  MigrationPage := CreateInputOptionPage(wpSelectDir, CustomMessage('MigPageCaption'), FmtMessage(CustomMessage('MigPageDescription'),['{#AvsName}']),\n                   FmtMessage(CustomMessage('MigPageSubCaption'),['{#AvsName}',AvsDirsReg.Prog]), True, False)\n\n  MigrationPage.Add(FmtMessage(CustomMessage('MigPageOptionBackup'),['{#AvsName}']))\n  MigrationPage.Add(FmtMessage(CustomMessage('MigPageOptionUninstall'),['{#AvsName}']))\n  MigrationPage.SelectedValueIndex := 0;\n\n  PluginPage := CreateInputDirPage(wpSelectComponents,\n    FmtMessage(CustomMessage('PlugPageCaption'),['{#AvsName}']),FmtMessage(CustomMessage('PlugPageDescription'),['{#AvsName}']),\n    FmtMessage(CustomMessage('PlugPageSubCaption'),['{#AvsName}']), true, '');\n  PluginPage.Add(FmtMessage(CustomMessage('PlugPagePlugDirLegacy'),['32']));\n  PluginPage.Add(FmtMessage(CustomMessage('PlugPagePlugDirPlus'),['32','{#AvsName}']));\n  PluginPage.Add(FmtMessage(CustomMessage('PlugPagePlugDirLegacy'),['64']));\n  PluginPage.Add(FmtMessage(CustomMessage('PlugPagePlugDirPlus'),['64','{#AvsName}']));\nend;\n\nfunction NextButtonClick(CurPageID: Integer): Boolean;\nvar\n  I: Integer;\nbegin\n  if CurPageID = wpSelectDir then begin\n    SetAvsDirsPlus()\n    Result := True\n\n  end else if CurpageID = MigrationPage.ID then begin\n    if MigrationPage.SelectedValueIndex = 1 then\n      MigrationState := miPickedUninst\n    else\n      MigrationState := miPickedBackup;\n    SetMigrationComponent()\n    SetAvsDirsPlus()\n    Result := True\n\n  end else if CurPageID = wpSelectComponents then begin\n    SetAvsDirsPlus();\n    UpdatePluginDirPage('read');\n    if IsComponentSelected('main\\avs64') then begin\n      if IsComponentSelected('avsmig\\backup') and IsLegacyAvsInstalled('64') then\n        SetInputs(2,false)\n      else SetInputs(2,true);\n      SetInputs(3,true);\n    end else begin\n      SetInputs(2,false);\n      SetInputs(3,false);\n    end;\n    if IsComponentSelected('main\\avs32') then begin\n      if IsComponentSelected('avsmig\\backup') and DirExists(AvsDirsReg.Plug32) then\n        SetInputs(0,false)\n      else SetInputs(0,true);\n      SetInputs(1,true);\n    end else begin\n      SetInputs(0,false);\n      SetInputs(1,false);\n    end;\n    Result := True\n\n  end else if CurPageID = PluginPage.ID then begin\n    UpdatePluginDirPage('write');\n    Result := True;\n  end else\n    Result := True;\nend;\n\nprocedure CurStepChanged(CurStep: TSetupStep);\nvar\n  ResultCode: Integer;\n  LogFilePath: String;\n\nbegin\n  if CurStep = ssInstall then begin\n    LogVal('Installing components', WizardSelectedComponents(false));\n    LogVal('Legacy x86 AviSynth installed', BoolToStr(IsLegacyAvsInstalled('32')));\n    LogVal('Legacy x64 AviSynth installed', BoolToStr(IsLegacyAvsInstalled('64')));\n    LogVal('AviSynth+ installed', BoolToStr(IsAvsPlusInstalled));\n    Log('RegDirectories:');\n    LogAvsDirectories(AvsDirsReg);\n    Log('AvsPlusDirectories:');\n    LogAvsDirectories(AvsDirsPlus);\n\n    if MigrationState = miPickedUninst then begin\n      Log('Uninstalling legacy AviSynth');\n      if Exec(AvsDirsReg.Prog+'\\Uninstall.exe', '/S', '', SW_SHOW, ewWaitUntilIdle, ResultCode) then begin\n        CloseAvsUninstDialog(AVSUNINST_YES)\n        CloseAvsUninstDialog(AVSUNINST_OK)\n      end else begin\n        MigrationState := miFailedUninst;\n         SuppressibleMsgBox(FmtMessage(CustomMessage('MigPageUninstallFailed'),[SysErrorMessage(ResultCode)]), mbError, MB_OK, -1);\n      end;\n    end;\n    end else if CurStep = ssDone then begin\n    LogFilePath := ExpandConstant('{log}');\n    FileCopy(LogFilePath, WizardDirValue + '\\' + ExtractFileName(LogFilePath) , false);\n  end;\nend;\n\nfunction ShouldSkipPage(PageID: Integer): Boolean;\nbegin\n  if (PageID = MigrationPage.ID) and not IsLegacyAvsInstalled('32') then\n    Result := True\n  else if (PageID = PluginPage.ID) and not IsComponentSelected('custplug') then\n    Result := True\n  else Result := False\nend;\n\nprocedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);\nvar\n  AvsDirLegacyUninst: String;\n  ResultCode: Integer;\nbegin\n  if (CurUninstallStep = usPostUninstall) and RegQueryStringValue(HKLM32, 'Software\\AviSynth', 'LegacyDir', AvsDirLegacyUninst) then begin\n    RenameFile(AvsDirLegacyUninst + '\\PlusBackup\\sys32\\AviSynth.dll', ExpandConstant('{sys}\\AviSynth.dll'))\n    RenameFile(AvsDirLegacyUninst + '\\PlusBackup\\sys32\\DevIL.dll', ExpandConstant('{sys}\\DevIL.dll'));\n    RenameFile(AvsDirLegacyUninst + '\\PlusBackup\\StartMenu', ExpandConstant('{commonprograms}\\AviSynth 2.5'));\n    if IsWin64 then begin\n      EnableFsRedirection(False);\n      { Since the installer runs in x86 mode we need redirection to be disabled here for 2 reasons:\n          1. To make [sys] expand to the System32, not SysWoW64.\n          2. To run the correct x64 regedit.exe on x64 systems to import our backup regfile.\n             Using the x86 regedit.exe would cause HKLM\\Software\\AviSynth to be redirected to HKLM\\Software\\WoW6432Node\\AviSynth,\n             which would potentially cause the x86 plugins folder value to be overwritten by its x64 counterpart.\n      }\n      RenameFile(AvsDirLegacyUninst + '\\PlusBackup\\sys64\\AviSynth.dll', ExpandConstant('{sys}\\AviSynth.dll'));\n      RenameFile(AvsDirLegacyUninst + '\\PlusBackup\\sys64\\DevIL.dll', ExpandConstant('{sys}\\DevIL.dll'));\n    end;\n    if Exec(ExpandConstant('{win}\\regedit.exe'), '/s \"'+ AvsDirLegacyUninst +'\\PlusBackup\\PlusBackup.reg\"', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then begin\n      DelTree(AvsDirLegacyUninst + '\\PlusBackup', True, True, True);\n      RegDeleteValue(HKLM32, 'Software\\AviSynth', 'LegacyDir');\n    end else\n       SuppressibleMsgBox(FmtMessage(CustomMessage('BackupRestoreFailed'),[SysErrorMessage(ResultCode)]), mbError, MB_OK,-1);\n    EnableFsRedirection(True);\n  end;\nend;\n\n// Checks and {code ...} snippets\nProcedure FixRegFile;\nvar\n  FileContent: Array of String;\n  RegFile: String;\nbegin\n  RegFile := AvsDirsReg.Prog + '\\PlusBackup\\PlusBackup.reg';\n  LoadStringsFromFile(RegFile, FileContent);\n  SaveStringToFile(RegFile, 'Windows Registry Editor Version 5.00', False);\n  SaveStringsToFile(RegFile, FileContent, True);\nend;\n\nfunction GetKey(Param: String): String;\nvar\n  RootKey: Integer;\n  Value, ValueName: String;\n  Params: Array of String;\nbegin\n  Explode(Params, Param, '^');\n  case Params[0] of\n    'HKLM32': RootKey := HKLM32;\n    'HKLM64': RootKey := HKLM64;\n    'HKCU32': RootKey := HKCU32;\n    'HKCU64': RootKey := HKCU64;\n  end;\n  if GetArrayLength(Params) = 3 then ValueName  := Params[2] else ValueName := '';\n  RegQueryStringValue(RootKey, Params[1], ValueName, Value);\n  Result := FmtRegFileString(Value)\nend;\n\nfunction GetAvsDirsLegacy(Param: String): String;\nbegin\n    case Param of\n      'Prog': Result := AvsDirsReg.Prog;\n      'Plug32': Result := AvsDirsReg.Plug32;\n      'Plug64': Result := AvsDirsReg.Plug64;\n    end;\nend;\n\nfunction GetAvsDirsLegacyFmt(Param: String): String;\nbegin\n  Result := FmtRegFileString(GetAvsDirsLegacy(Param));\nend;\n\nfunction GetAvsDirsPlus(Param: String): String;\nbegin\n    case Param of\n      'Plug32': Result := AvsDirsPlus.Plug32;\n      'PlugPlus32': Result := AvsDirsPlus.PlugPlus32;\n      'Plug64': Result := AvsDirsPlus.Plug64;\n      'PlugPlus64': Result := AvsDirsPlus.PlugPlus64;\n    end;\nend;\n\nfunction GetRegSoft(Param: String): String;\nbegin\n  if IsWin64 then begin\n    case Param of\n      'HKLM32': Result := 'HKEY_LOCAL_MACHINE\\Software\\Wow6432Node';\n      'HKLM64': Result := 'HKEY_LOCAL_MACHINE\\Software';\n      'HKCU32': Result := 'HKEY_CURRENT_USER\\Software\\Wow6432Node';\n      'HKCU64': Result := 'HKEY_CURRENT_USER\\Software';\n    end;\n  end else begin\n    case Param of\n      'HKLM32': Result := 'HKEY_LOCAL_MACHINE\\Software';\n      'HKCU32': Result := 'HKEY_CURRENT_USER\\Software';\n    end;\n  end;\nend;\n\nfunction IsValidPluginMigration(Param: String): Boolean;\nbegin\n  case Param of\n    '32': Result := IsLegacyAvsInstalled('32') and DirExists(AvsDirsReg.Plug32) and not IsSamePath(AvsDirsReg.Plug32,AvsDirsPlus.Plug32);\n    '64': Result := IsLegacyAvsInstalled('64') and not IsSamePath(AvsDirsReg.Plug64,AvsDirsPlus.Plug64);\n  end;\nend;\n\nprocedure WipeLegacyPluginDirs(Param: String);\nbegin\n  case Param of\n    '32': DelTree(AvsDirsReg.Plug32, True, True, False);\n    '64': DelTree(AvsDirsReg.Plug64, True, True, False);\n  end;\n  LogVal('Wiping legacy AviSynth Plugin Directory',Param);\n  RemoveDir(AvsDirsReg.Prog);\nend;\n\nprocedure WipeLegacyStartMenu;\nbegin\n  DelTree(ExpandConstant('{commonprograms}\\AviSynth 2.5'), True, True, False);\nend;\n\nfunction IncludeVcRedist(): boolean;\nbegin\n  #ifdef WITH_VC_REDIST\n  Result := True;\n  #else\n  Result := False;\n  #endif\nend;\n\nfunction ExistsMPlayer2(): boolean;\nbegin\n  Result := FileExists(ExpandConstant('{pf}\\Windows Media Player\\mplayer2.exe'));\nend;\n\nfunction ExistsWMPlayer(): boolean;\nbegin\n  Result := FileExists(ExpandConstant('{pf}\\Windows Media Player\\wmplayer.exe'));\nend;\n"
  },
  {
    "path": "distrib/WinInstaller/update_git_rev.ps1",
    "content": "﻿$revNum = (git rev-list --reverse HEAD | measure).count\n$isTagged = (git name-rev --name-only --tags HEAD) -ne \"undefined\"\n$branch = git rev-parse --abbrev-ref HEAD\n$shortHash = git rev-parse --short HEAD\n\necho \"Version matching in progress\"\n$x = 0\ndo {\n    $closestTag = git describe --abbrev=0 --tags HEAD~$x\n    $versionMatch = $closestTag | sls \"^v?(\\d+\\.\\d+\\.\\d+(?:\\-.*)?$)\"\n    $x++\n} until ($versionMatch -or -not $closestTag)\necho \"Version matching done\"\n\n@\"\n[Version]\nBranch=$branch\nRevision=g$shortHash\nRevisionNumber=$revNum\nIsTagged=$isTagged\nIsRelease=$($isTagged -and $versionMatch)\nVersion=$(if($versionMatch) {$versionMatch.Matches.Groups[1].Value} else {\"0.1.0\"} )\n\"@>git_rev.ini"
  },
  {
    "path": "distrib/docs/english/make.bat",
    "content": "@ECHO OFF\n\nREM Command file for Sphinx documentation\n\nif \"%SPHINXBUILD%\" == \"\" (\n\tset SPHINXBUILD=sphinx-build\n)\nset BUILDDIR=build\nset ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source\nset I18NSPHINXOPTS=%SPHINXOPTS% source\nif NOT \"%PAPER%\" == \"\" (\n\tset ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%\n\tset I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%\n)\n\nif \"%1\" == \"\" goto help\n\nif \"%1\" == \"help\" (\n\t:help\n\techo.Please use `make ^<target^>` where ^<target^> is one of\n\techo.  html       to make standalone HTML files\n\techo.  dirhtml    to make HTML files named index.html in directories\n\techo.  singlehtml to make a single large HTML file\n\techo.  pickle     to make pickle files\n\techo.  json       to make JSON files\n\techo.  htmlhelp   to make HTML files and a HTML help project\n\techo.  qthelp     to make HTML files and a qthelp project\n\techo.  devhelp    to make HTML files and a Devhelp project\n\techo.  epub       to make an epub\n\techo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter\n\techo.  text       to make text files\n\techo.  man        to make manual pages\n\techo.  texinfo    to make Texinfo files\n\techo.  gettext    to make PO message catalogs\n\techo.  changes    to make an overview over all changed/added/deprecated items\n\techo.  xml        to make Docutils-native XML files\n\techo.  pseudoxml  to make pseudoxml-XML files for display purposes\n\techo.  linkcheck  to check all external links for integrity\n\techo.  doctest    to run all doctests embedded in the documentation if enabled\n\tgoto end\n)\n\nif \"%1\" == \"clean\" (\n\tfor /d %%i in (%BUILDDIR%\\*) do rmdir /q /s %%i\n\tdel /q /s %BUILDDIR%\\*\n\tgoto end\n)\n\n\n%SPHINXBUILD% 2> nul\nif errorlevel 9009 (\n\techo.\n\techo.The 'sphinx-build' command was not found. Make sure you have Sphinx\n\techo.installed, then set the SPHINXBUILD environment variable to point\n\techo.to the full path of the 'sphinx-build' executable. Alternatively you\n\techo.may add the Sphinx directory to PATH.\n\techo.\n\techo.If you don't have Sphinx installed, grab it from\n\techo.http://sphinx-doc.org/\n\texit /b 1\n)\n\nif \"%1\" == \"html\" (\n\t%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The HTML pages are in %BUILDDIR%/html.\n\tgoto end\n)\n\nif \"%1\" == \"dirhtml\" (\n\t%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.\n\tgoto end\n)\n\nif \"%1\" == \"singlehtml\" (\n\t%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.\n\tgoto end\n)\n\nif \"%1\" == \"pickle\" (\n\t%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished; now you can process the pickle files.\n\tgoto end\n)\n\nif \"%1\" == \"json\" (\n\t%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished; now you can process the JSON files.\n\tgoto end\n)\n\nif \"%1\" == \"htmlhelp\" (\n\t%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished; now you can run HTML Help Workshop with the ^\n.hhp project file in %BUILDDIR%/htmlhelp.\n\tgoto end\n)\n\nif \"%1\" == \"qthelp\" (\n\t%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished; now you can run \"qcollectiongenerator\" with the ^\n.qhcp project file in %BUILDDIR%/qthelp, like this:\n\techo.^> qcollectiongenerator %BUILDDIR%\\qthelp\\AviSynth.qhcp\n\techo.To view the help file:\n\techo.^> assistant -collectionFile %BUILDDIR%\\qthelp\\AviSynth.ghc\n\tgoto end\n)\n\nif \"%1\" == \"devhelp\" (\n\t%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished.\n\tgoto end\n)\n\nif \"%1\" == \"epub\" (\n\t%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The epub file is in %BUILDDIR%/epub.\n\tgoto end\n)\n\nif \"%1\" == \"latex\" (\n\t%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished; the LaTeX files are in %BUILDDIR%/latex.\n\tgoto end\n)\n\nif \"%1\" == \"latexpdf\" (\n\t%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex\n\tcd %BUILDDIR%/latex\n\tmake all-pdf\n\tcd %BUILDDIR%/..\n\techo.\n\techo.Build finished; the PDF files are in %BUILDDIR%/latex.\n\tgoto end\n)\n\nif \"%1\" == \"latexpdfja\" (\n\t%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex\n\tcd %BUILDDIR%/latex\n\tmake all-pdf-ja\n\tcd %BUILDDIR%/..\n\techo.\n\techo.Build finished; the PDF files are in %BUILDDIR%/latex.\n\tgoto end\n)\n\nif \"%1\" == \"text\" (\n\t%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The text files are in %BUILDDIR%/text.\n\tgoto end\n)\n\nif \"%1\" == \"man\" (\n\t%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The manual pages are in %BUILDDIR%/man.\n\tgoto end\n)\n\nif \"%1\" == \"texinfo\" (\n\t%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.\n\tgoto end\n)\n\nif \"%1\" == \"gettext\" (\n\t%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The message catalogs are in %BUILDDIR%/locale.\n\tgoto end\n)\n\nif \"%1\" == \"changes\" (\n\t%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.The overview file is in %BUILDDIR%/changes.\n\tgoto end\n)\n\nif \"%1\" == \"linkcheck\" (\n\t%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Link check complete; look for any errors in the above output ^\nor in %BUILDDIR%/linkcheck/output.txt.\n\tgoto end\n)\n\nif \"%1\" == \"doctest\" (\n\t%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Testing of doctests in the sources finished, look at the ^\nresults in %BUILDDIR%/doctest/output.txt.\n\tgoto end\n)\n\nif \"%1\" == \"xml\" (\n\t%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The XML files are in %BUILDDIR%/xml.\n\tgoto end\n)\n\nif \"%1\" == \"pseudoxml\" (\n\t%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.\n\tgoto end\n)\n\n:end\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/AMDOptimizationGuide.rst",
    "content": "\nAMDOptimizationGuide\n====================\n\nTo many people this is considered the bible of Assembler optimizing.\n\nThe 'AMD64 Architecture Programmer's Manual Volume 1-5' can be\ndownloaded from the `Developer Guides & Manuals`_ section.\n\n----\n\nBack to :doc:`AssemblerOptimizing <AssemblerOptimizing>`\n\n$Date: 2014/10/27 22:04:54 $\n\n.. _Developer Guides & Manuals:\n    http://developer.amd.com/resources/documentation-articles/developer-guides-manuals/\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/AVSLinkage.rst",
    "content": "\nAVS Linkage\n===========\n\nRemoval of backed code\n----------------------\n\nThe plugin api v3 contains baked code (see avisynth.h from v2.58 and\nolder versions) which is code that is included inline. The result is\nall that code is \"baked\" into all and every plugin instead being called\nfrom avisynth.dll. The problem with baked code is that it cannot be\nchanged without recompiling the plugin. (If it were just a declaration\nonly then the active code would be whatever is in the current\navisynth.dll.) This is a problem if the plugin api will be changed\nagain in the future (and it probably will one day) and this issue is\nsolved in 2.6.\n\nStarting from 2.6 the version 2.5 plugins are supported directly (with\ncurrent baked code; meaning that plugins compiled for 2.5 can be loaded\nwhen using 2.6) and all the baked code from 2.6+ plugins is removed and\nthe plugins are still source compatible. Note that the baked code is\nmoved to interface.cpp, where also the structure AVS_Linkage is\ndefined.\n\nAVS_Linkage is a mechanism to initialize the function table with the\nentry points for an alternate server. Server here means something that\nloads and executes an avisynth.h api plugin. This is normally\navisynth.dll but Avery Lee has expressed a desire to be able to load\nand execute avisynth plugins directly in VirtualDub. Much the same way\nAvisynth can currently load VirtualDub plugins today.\n\nThe implementation solution\n---------------------------\n\nOn the user plugin side the entry-point is now called\nAvisynthPluginInit3 and it take 2 arguments, an IScriptEnvironment* and\nan AVS_Linkage*. The user needs to declare static storage for\nAVS_Linkage* AVS_linkage; and in their AvisynthPluginInit3 code save\nthe supplied 2nd value to the AVS_linkage variable. The rest of the\ncode should be the same as for 2.5 plugins, i.e. env->AddFunction, etc.\n\nIn avisynth.h the type AVS_Linkage structure is declared and macros\nemit stub baked code that calls the appropriate code in the server via\nthe AVS_Linkage function pointers. The stub code checks to make sure\nAVS_linkage is not Null and the offset of the function pointer is\nwithin the current size of the structure. If okay the function is\ncalled otherwise it evaluates as 0. Within the Avisynth.dll project\nthese macros resolve to a simple \";\" so no stub code is emitted just\ndeclarations occur, this is triggered by the definition of the reserved\nsymbol AVISYNTH_CORE.\n\nIn interface.cpp the real code is defined and the instance of the\nAVS_Linkage structure is declared and initialised. In plugins.cpp the\naddress of this is passed to the users AvisynthPluginInit3 code along\nwith the ScriptEnvironment address. A minor hurdle was that you may not\ntake the address of constructor or destructor routines in C++ so I to\nmove forward I just nested the appropriate code for these down one\nmethod and used the address of the nested method. I unimaginatively\ncalled these CONSTRUCTORn() and DESTRUCTOR() [edit: shouldn't this be\nDESTRUCTORn()???].\n\nIn your plugin source file the changes are trivial. Declare the storage\nfor AVS_linkage, rename the .dll entrypoint from AvisynthPluginInit2 to\nAvisynthPluginInit3 and add the extra AVS_Linkage* argument.\n\n`discussion on Doom9 <http://forum.doom9.org/showthread.php?t=101730>`_ (in\nparticular\n`this post <http://forum.doom9.org/showthread.php?p=1567792#post1567792>`__ and\n`this post <http://forum.doom9.org/showthread.php?p=1631250#post1631250>`__).\n\n____\n\nBack to :doc:`FilterSDK`\n\n$Date: 2014/10/27 22:04:54 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/AssemblerOptimizing.rst",
    "content": "\nAssemblerOptimizing\n===================\n\nThis section contains information on various experiences and information on\nassembler writing. This will mostly cover information on :doc:`MMX <MMX>` and\n:doc:`IntegerSSE <IntegerSSE>`.\n\n-   Beginner? Read some info about :doc:`SimpleMmxOptimization <SimpleMmxOptimization>`.\n-   Not a beginner? :doc:`Try a more complex example <IntermediateMmxOptimization>`.\n-   Read about :doc:`InstructionPairing <InstructionPairing>`.\n-   Read about :doc:`DataAlignment <DataAlignment>`.\n-   Read about transfering data from :doc:`GeneralPurposeToMMXRegisters <GeneralPurposeToMMXRegisters>`.\n-   :doc:`IsMovntqFaster <IsMovntqFaster>`?\n-   A link to the :doc:`AMDOptimizationGuide <AMDOptimizationGuide>`.\n-   A link to the :doc:`IntelOptimizationGuide <IntelOptimizationGuide>`.\n\n----\n\nBack to :doc:`FilterSDK <FilterSDK>`\n\n$Date: 2025-02-24 21:13:22-05:00 $\n\n.. _AssemblerOptimizing: http://avisynth.nl/index.php/Filter_SDK/Assembler_optimizing\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/AviSynthInterfaceVersion.rst",
    "content": "\nAviSynth Interface Version\n==========================\n\nThe AVISYNTH_INTERFACE_VERSION describes the level of features\navailable, both in the core avisynth.dll and the third party plugin.\n\nFor a plugin author it describes what the core IScriptEnvironment\nvtable contains and the what behaviour the core expects of their\nplugin.\n\n- Version 1 is Avisynth 2.0\n- Version 2 is Avisynth 2.5, with the vtable having members up to\n  IScriptEnvironment::SetWorkingDir(const char * newdir)\n- Version 3 is Avisynth 2.5.6, with the IScriptEnvironment vtable\n  adding 3 new members ManageCache, PlanarChromaAlignment and\n  SubframePlanar.\n- Version 4 is reserved and does not apply to any released Avisynth\n  version. It's only significance is it greater then 3 and less then\n  6. No public core provides this version, plugins that report this\n  version are treated as if they reported version 3.\n- Version 5 is the alpha development releases of Avisynth 2.6.0a1-a5,\n  with the IScriptEnvironment vtable adding 3 more new members\n  DeleteScriptEnvironment, ApplyMessage and GetAVSLinkage. Also with\n  version 5 some core versions provides AVS_Linkage support for baked\n  code replacement. The IClip::SetCacheHints member was changed to\n  return an int. Some core versions demand this behaviour, but early\n  adopter plugins may not conform. This has caused some confusion.\n- Version 6 is the production releases of Avisynth 2.6.0, with the\n  IScriptEnvironment vtable adding one more new member GetVarDef. It\n  also formally uses type size_t in place of type int for things that\n  are memory sizes, ready for a 64 bit port. Version 6 relaxes the\n  requirement for IClip::SetCacheHints of version 5 plugins to return\n  an int. All version 6 and later plugins are expected to honour this\n  requirement.\n- Version 8 and up is Avisynth+.\n  See :doc:`C++ API <Cplusplus_api>`\n\nWhen using the raw IClip interface it is the authors responsibility to\ndeclare the level of support the plugin provides. The\nGenericVideoFilter class provides this:\n::\n\n    int __stdcall UserClass::GetVersion() { return AVISYNTH_INTERFACE_VERSION; }\n\n\n- Version 1 is Avisynth 2.0\n- Version 2 and 3 are Avisynth 2.5, supporting YV12, YUY2, RGB32 and\n  RGB24 colour spaces.\n- Version 4 is reserved and does not apply to any Avisynth version.\n  It's significance is it greater then 3 and less then 6.\n- Version 5 is for early adopter alpha release of Avisynth 2.6.\n- Version 6 is Avisynth 2.6, and the IClip interface must support\n  this update:\n\n::\n\n    /* Plugins that do not implement the interface must always return zero. */\n    virtual int __stdcall IClip::SetCacheHints(int cachehints,int frame_range);\n\n____\n\nBack to :doc:`FilterSDK`\n\n$Date: 2025/02/06 07:37:50 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/AviSynthTwoFiveAudio.rst",
    "content": "\n`AviSynthTwoFiveAudio`_\n=======================\n\nMost sample handling has been completely rewritten. And most notably, the way\nof fetching samples has changed slightly. The old way of fetching:\n\n``virtual void __stdcall GetAudio(void* buf, int start, int count,\nIScriptEnvironment* env);``\n\nhas been replaced by:\n\n``virtual void __stdcall GetAudio(void* buf, __int64 start, __int64 count,\nIScriptEnvironment* env);``\n\nThis has been done to support longer samples. If you extend PClip instead of\nGenericVideoFilter, you will have to change this. If you extend\nGenericVideoFilter, and don't change it, samples will go through your filter\nuntouched (as if it wasn't there).\n\nAn automatic audio type converter has been added, and is available to all\nfilters. This enables you to recieve samples only in supported formats. Use\nlike this:\n\n``PClip ok_clip = ConvertAudio::Create(_clip, SAMPLE_INT16|SAMPLE_FLOAT,\nSAMPLE_FLOAT);``\n\nIt accepts two parameters besides the original clip - they are accepted\nformats and prefered format. If the samples are already in one of the\naccepted formats, they will be returned untouched. If they are not, all\nsamples will be converted to the prefered format. This makes it possible for\nyour filter to only support a subrange of sample-types without having to\nworry about conversion or error messages.\n\nThe currently supported sampletypes are:\n\n-   SAMPLE_INT8\n-   SAMPLE_INT16\n-   SAMPLE_INT24\n-   SAMPLE_INT32\n-   SAMPLE_FLOAT\n\nvi.sample_type contains one of the types above. The sample type should be\nread by calling vi.SampleType(). You should only directly refer to\nsample_type, when writing to it (which should only be necessary on sources,\nsince all convertion is can be done by AviSynth internally).\n\nYou can no longer refer to vi.stereo or vi.sixteen_bit. The number of\nchannels can be retrieved by using vi.AudioChannels(), and it can now contain\nany number. The channels are still interleaved, so if vi.AudioChannels()is 4\nthe samples will be delivered like this:\n\n``[ch1-s1][ch2-s1][ch3-s1][ch4-s1][ch1-s2][ch2-s2][ch3-s2][ch4-s2][ch1-s3][ch\n2-s3][ch3-s3][ch4-s3]``\n\nch is channel and s sample.\n\nFor more info, refer to the new audio.cpp and avisynth.h\n\n\nBack to :doc:`AviSynthTwoFiveSDK <AviSynthTwoFiveSDK>`\n\n$Date: 2025-02-24 21:30:24-05:00 $\n\n.. _AviSynthTwoFiveAudio:\n    http://avisynth.nl/index.php/Filter_SDK/Two-Five_Audio\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/AviSynthTwoFivePixelType.rst",
    "content": "\n`AviSynthTwoFivePixelType`_\n===========================\n\nThe internals of VideoInfo.pixel_type has been completely changed. The type\nhas been changed from byte to int, and now contains different information\nthan before. This is important when building a Source filter, when you have\nto set the pixel_type. You have to change your constants to reflect this\nchange.\n\nIn general filters should not care about these values at all - only if they\nset or modify them. For checking what colorspace the video material is in,\nuse one of the following functions in VideoInfo.\n\n-   bool IsRGB()\n-   bool IsRGB24()\n-   bool IsRGB32()\n-   bool IsYUV()\n-   bool IsYUY2()\n-   bool IsYV12()\n-   bool IsPlanar()\n\nIf you need to set the pixel type, use a syntax like:\n\n``vi.pixel_type = VideoInfo::CS_YUY2; // Version 2.5 syntax``\n\ninstead of:\n\n``vi.pixel_type = VideoInfo::YUY2; // Version 2.0 syntax``\n\nOther possibilities are:\n\n-   CS_BGR24,\n-   CS_BGR32,\n-   CS_YUY2,\n-   CS_YV12, // y-v-u, planar\n-   CS_I420, // y-u-v, planar\n-   CS_IYUV // same as above\n\nThe last two are automatically converted to YV12, so filter writers should\nnot worry about these.\n\nSee also :doc:`WorkingWithImages <WorkingWithImages>`.\n\n\nBack to :doc:`AviSynthTwoFiveSDK <AviSynthTwoFiveSDK>`\n\n$Date: 2025-02-24 21:25:59-05:00 $\n\n.. _AviSynthTwoFivePixelType:\n    http://avisynth.nl/index.php/Filter_SDK/Two-Five_pixel_type\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/AviSynthTwoFiveSDK.rst",
    "content": "\n`AviSynthTwoFiveSDK`_\n=====================\n\nThis will list the main changes between 1.x, 2.0x and 2.5. Not all changes\nare listed here, but the new methods can be found in the new avisynth.h.\n\n-   See information on :doc:`WorkingWithPlanarImages <WorkingWithPlanarImages>`.\n-   The converted :doc:`TwoFiveInvert <TwoFiveInvert>` plugin filter source it here.\n-   The same algorithm demonstrating how to speed up the processing\n    (using PLANAR_Y_ALIGNED, etc.) can be seen at :doc:`TwoFiveFastInvert <TwoFiveFastInvert>` plugin\n    source.\n-   Pixel type has changed in AviSynth 2.5. See more in\n    :doc:`AviSynthTwoFivePixelType <AviSynthTwoFivePixelType>`.\n-   For working with audio, see :doc:`AviSynthTwoFiveAudio <AviSynthTwoFiveAudio>`.\n\n\nBack to :doc:`FilterSDK <FilterSDK>`\n\n$Date: 2025-02-24 20:58:32-05:00 $\n\n.. _AviSynthTwoFiveSDK: http://avisynth.nl/index.php/Filter_SDK/Two-Five_SDK\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/BensAviSynthDocs.rst",
    "content": "\nBensAviSynthDocs\n================\n\nThis is a text of the original documentation written for AviSynth 1.0 by Ben\nRudiak-Gould - copied from `<http://math.berkeley.edu/~benrg/avisynth-extensions.html>`_.\nNow (November 2006) it is available online at the `mirror.`_\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\nWriting Avisynth plugins\n------------------------\n\n\nAn example\n~~~~~~~~~~\n\nI'll start off with a complete, working Avisynth plugin. It's called\n\"Invert,\" and it produces a photo-negative of the input clip.\n\n**Here's Invert.cpp**::\n\n    #include \"avisynth.h\"\n\n\n    class Invert : public GenericVideoFilter {\n    public:\n        Invert(PClip _child) : GenericVideoFilter(_child) {}\n        PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment*\n        env);\n    };\n\n\n    PVideoFrame __stdcall Invert::GetFrame(int n, IScriptEnvironment*\n    env) {\n\n        PVideoFrame src = child->GetFrame(n, env);\n        PVideoFrame dst = env->NewVideoFrame(vi);\n\n        const unsigned char* srcp = src->GetReadPtr();\n        unsigned char* dstp = dst->GetWritePtr();\n\n        const int src_pitch = src->GetPitch();\n        const int dst_pitch = dst->GetPitch();\n        const int row_size = dst->GetRowSize();\n        const int height = dst->GetHeight();\n\n        for (int y = 0; y < height; y++) {\n            for (int x = 0; x < row_size; x++)\n                dstp[x] = srcp[x] ^ 255;\n            srcp += src_pitch;\n            dstp += dst_pitch;\n        }\n\n        return dst;\n    }\n\n\n    AVSValue __cdecl Create_Invert(AVSValue args, void* user_data,\n    IScriptEnvironment* env) {\n        return new Invert(args[0].AsClip());\n    }\n\n\n    extern \"C\" __declspec(dllexport) const char* __stdcall\n    AvisynthPluginInit(IScriptEnvironment* env) {\n        env->AddFunction(\"Invert\", \"c\", Create_Invert, 0);\n        return \"`Invert' sample plugin\";\n    }\n\n\nCompile this file into a DLL named Invert.dll. Now create an\nAvisynth script which looks something like this::\n\n    LoadPlugin(\"d:\\path\\Invert.dll\")\n    clip = AVISource(\"d:\\path2\\video.avi\")\n    return clip.Invert()\n\nIf all is well, you should see a photo negative of your video clip\nwhen you open this script.\n\nHow it works\n~~~~~~~~~~~~\n\nHere's a line-by-line breakdown of Invert.cpp.\n::\n\n    #include \"avisynth.h\"\n\nThis header declares all the classes and miscellaneous constants that you\nmight need when writing a plugin. All external plugins should #include it.\n\nExternal plugins do not link with ``avisynth.dll``, so they can't directly\naccess functions that are defined in the main Avisynth source code.\nTherefore, every important function in ``avisynth.h`` is either defined\ninline or declared as ``virtual``. The virtual functions act as callbacks for\nexternal DLLs.\n::\n\n    class Invert : public GenericVideoFilter {\n\nAn Avisynth filter is simply a C++ class implementing the ``IClip``\ninterface. ``IClip`` has four pure virtual methods: ``GetVideoInfo``,\n``GetFrame``, ``GetParity``, and ``GetAudio``.\n\nThe class ``GenericVideoFilter`` is a simple do-nothing filter defined in\n``avisynth.h``. It derives from ``IClip`` and implements all four methods.\nMost filters can inherit from ``GenericVideoFilter`` rather than directly\nfrom ``IClip``; this saves you from having to implement methods that you\ndon't care about, like ``GetAudio``.\n::\n\n    Invert(PClip _child) : GenericVideoFilter(_child) {}\n\nA ``PClip`` is a \"smart pointer\" to an ``IClip``. It maintains a reference\ncount on the IClip object and automagically deletes it when the last PClip\nreferencing it goes away. For obvious reasons, you should always use PClip\nrather than IClip* to refer to clips.\n\nLike a genuine pointer, a ``PClip`` is only four bytes long, so you can pass\nit around by value. Also like a pointer, a ``PClip`` can be assigned a null\nvalue (0), which is often useful as a sentinel. Unlike a pointer, ``PClip``\nis initialized to 0 by default.\n\nYou'll need to make sure your class doesn't contain any circular ``PClip``\nreferences, or any ``PClip``s sitting in dynamically allocated memory that\nyou forget to ``delete``. Other than that, you don't have to worry about the\nreference-counting machinery.\n\nAvisynth filters have a standardized output channel via ``IClip``, but\n(unlike VirtualDub filters) no standardized input channel. Each filter is\nresponsible for obtaining its own source material -- usually (as in this\ncase) from another clip, but sometimes from several different clips, or from\na file.\n\n``GenericVideoFilter`` has a single constructor taking a single clip, which\nit then simply passes through to its output. We will override the\n``GetFrame`` method to do something more useful, while leaving the other\nthree methods as-is to pass through aspects of the clip that we don't need to\nchange.\n::\n\n    PVideoFrame Invert::GetFrame(int n, IScriptEnvironment* env) {\n\nThis method is called to make our filter produce frame ``n`` of its output.\nThe second argument, ``env``, is for our purposes simply a callback suite. It\nis actually implemented in Avisynth by a class called ``ScriptEnvironment``.\nOne instance of this class is created for each opened AVS script, so there\nmay sometimes be several instances active at once. It is important that the\ncallback functions be called through the proper instance. A particular\ninstance of your class will only be used in one ScriptEnvironment, but\ndifferent instances might be used in different ScriptEnvironments.\n\nThis method returns a PVideoFrame, which is a smart pointer like PClip.\n::\n\n    PVideoFrame src = child->GetFrame(n, env);\n\n\"``child``\" is a protected member of ``GenericVideoFilter``, of type PClip.\nIt contains the clip that was passed to the constructor. For our filter to\nproduce frame ``n`` we need the corresponding frame of the input. If you need\na different frame from the input, all you have to do is pass a different\nframe number to ``child->GetFrame``.\n\n``GetFrame`` calls are usually intercepted by Avisynth's internal caching\ncode, so the frame request may never actually reach the child filter.\n::\n\n    PVideoFrame dst = env->NewVideoFrame(vi);\n\nThe ``NewVideoFrame`` callback allocates space for a video frame of the\nsupplied size. (In this case it will hold our filter's output.) The frame\nbuffer is uninitialized raw memory (except that in the debug build it gets\nfilled with the repeating byte pattern 0A 11 0C A7 ED, which is easy to\nrecognize because it looks like \"ALLOCATED\").\n\n\"``vi``\" is another protected member of ``GenericVideoFilter`` (the only\nother member, actually). It is a struct of type ``VideoInfo``, which contains\ninformation about the clip (like frame size, frame rate, pixel format, audio\nsample rate, etc.). ``NewVideoFrame`` uses the information in this struct to\nreturn a frame buffer of the appropriate size.\n\nFrame buffers are reused once all the PVideoFrame references to them go away.\nSo usually ``NewVideoFrame`` won't actually need to allocate any memory from\nthe heap.\n::\n\n    const unsigned char* srcp = src->GetReadPtr();\n    unsigned char* dstp = dst->GetWritePtr();\n\nAll frame buffers are readable, but not all are writable.\n\nThe rule about writability is this: *A buffer is writable if and only if\nthere is exactly one PVideoFrame pointing to it.* In other words, you can\nonly write to a buffer if no one else might be reading it. This rule\nguarantees that as long as you hold on to a PVideoFrame and don't write to it\nyourself, that frame will remain unchanged. The only drawback is that you\ncan't have two PVideoFrames pointing to a writable buffer. This can sometimes\nbe an inconvenience, as I'll explain later.\n\nAny buffer you get from ``NewVideoFrame`` is guaranteed to be writable (as\nlong as you only assign it to one PVideoFrame!). Our filter's ``dst`` came\nfrom NewVideoFrame, so we can safely call dst->GetWritePtr(). However, frames\nyou get from other clips via ``GetFrame`` may not be writable, in which case\nGetWritePtr() will return a null pointer.\n\nThere is an ``IsWritable()`` method which you can call to find out if a\nbuffer is writable or not, and there's a ``MakeWritable`` callback (described\nbelow) to ensure that it is.\n::\n\n    const int src_pitch = src->GetPitch();\n    const int dst_pitch = dst->GetPitch();\n\nJust as in VirtualDub, the \"pitch\" of a frame buffer is the offset (in bytes)\nfrom the beginning of one scan line to the beginning of the next. The source\nand destination buffers won't necessarily have the same pitch.\n\nBuffers created by ``NewVideoFrame`` are always quadword (8-byte) aligned and\nalways have a pitch that is a multiple of 8.\n::\n\n    const int row_size = dst->GetRowSize();\n\nThe row size is the length of each row in bytes (not pixels). It's usually\nequal to the pitch or slightly less, but it may be significantly less if the\nframe in question has been through ``Crop``.\n\nSince our source and destination frames have the same width and pixel format,\nthey will always have the same row size. Thus I only need one row_size\nvariable, and I could just as well have called src->GetRowSize().\n::\n\n    const int height = dst->GetHeight();\n\nThe height is the height. (In pixels.) Again, for our filter this is the same\nfor the source and the destination.\n::\n\n        for (int y = 0; y < height; y++) {\n            for (int x = 0; x < row_size; x++)\n                dstp[x] = srcp[x] ^ 255;\n            srcp += src_pitch;\n            dstp += dst_pitch;\n        }\n\nThis is the code that does the actual work. The \"srcp += src_pitch; dstp +=\ndst_pitch;\" idiom is a useful way of dealing with potentially differing\npitches without too much grief.\n::\n\n    return dst;\n\n``GetFrame`` returns the newly-created frame. Our own references to this\nframe and to the source frame will go away with the ``src`` and ``dst``\nvariables. Our caller will become sole owner of the destination frame (which\ntherefore will still be writable), and the source frame will be retained in\nthe cache and eventually recycled. All through the magic of C++ classes.\n::\n\n    AVSValue __cdecl Create_Invert(AVSValue args, void* user_data, IScriptEnvironment* env) {\n\nIn order to use our new filter, we need a scripting-language function which\ncreates an instance of it. This is that function.\n\nScript functions written in C++ take three arguments. ``args`` contains all\nthe arguments passed to the function by the script. ``user_data`` contains\nthe void pointer which you passed to ``AddFunction`` (see below). Usually you\nwon't need this. ``env`` contains the same IScriptEnvironment pointer that\nwill later be passed to ``GetFrame``.\n\n``AVSValue`` is a variant type which can hold any one of the following: a\nboolean value (true/false); an integer; a floating-point number; a string; a\nvideo clip (PClip); an array of AVSValues; or nothing (\"undefined\"). You can\ntest which one it is with the methods ``IsBool()``, ``IsInt()``,\n``IsFloat()``, ``IsString()``, ``IsClip()``, ``IsArray()``, and ``Defined()``\n(which returns true if the AVSValue is not \"undefined\"). You can get the\nvalue with ``AsBool()``, ``AsInt()``, etc. For arrays, you can use the\n``ArraySize()`` method to get the number of elements, and ``[]`` indexing to\nget the elements themselves. For convenience, ``IsFloat()`` and ``AsFloat()``\nwill work with integers also. But boolean values are not treated as numeric\n(unlike C).\n\nThe name \"Create_Invert\" is arbitrary. This function will actually be known\nas \"Invert\" in scripts, because that's the name we pass to ``AddFunction``\nbelow.\n::\n\n    return new Invert(args[0].AsClip());\n\nThe ``args`` argument passed to a script function will always be an array.\nThe return value should be any one of the other types (never an array).\n\nThe types of the values in the ``args`` array are guaranteed to match one of\nthe function signatures that you pass to ``AddFunction``, just as in\nVirtualDub. Therefore, there's no need to worry about ``IsClip`` here.\n\n``Create_Invert`` simply creates and returns a filter instance; it is\nautomatically converted to an AVSValue via the constructor\n``AVSValue(IClip*)``.\n::\n\n    extern \"C\" __declspec(dllexport) const char* __stdcall AvisynthPluginInit(IScriptEnvironment* env) {\n\nThis is the only function which gets exported from the DLL. It is called by\nthe script function ``LoadPlugin`` the first time this plugin in loaded *in a\nparticular script*. If several scripts are open at once and more than one of\nthem loads this plugin, ``AvisynthPluginInit`` may be called more than once\nwith different IScriptEnvironments. Therefore:\n\n-   You should not save the ``env`` parameter in a global variable.\n-   If you need to initialize any static data, you should do it in\n    ``DLLMain``, not in this function.\n\nThe main purpose of the ``AvisynthPluginInit`` function is to call\n``env->AddFunction``.\n::\n\n    env->AddFunction(\"Invert\", \"c\", Create_Invert, 0);\n\nAs promised, we now call ``AddFunction`` to let Avisynth know of the\nexistence of our filter. This function takes four arguments: the name of the\nnew script function; the parameter-type string; the C++ function implementing\nthe script function; and the ``user_data`` cookie.\n\nThe parameter-type string is similar to the corresponding entity in\nVirtualDub, except that:\n\n-   No return type is given. Function return values are not type-checked;\n    you can return anything you like.\n-   There are more types: along with 'i'nt and 's'tring you can specify\n    'b'ool, 'f'loat, and 'c'lip.\n-   You can follow any type with '*' or '+' to indicate \"zero or more\" or\n    \"one or more\" respectively. In this case all the matching arguments will\n    be gathered into a sub-array. For example, if your type string is \"is+f\",\n    then the integer argument will be args[0], the string arguments will be\n    args[1][0], args[1][1], etc. (and there will be args[1].ArraySize() of\n    them), and the float argument will be args[2].\n-   '.' matches a *single* argument of any type. To match multiple\n    arguments of any type, use \".*\" or \".+\".\n-   You can have named arguments, by specifying the name in [brackets]\n    before the type. Named arguments are also optional arguments; if the user\n    omits them, they will be of the undefined type instead of the type you\n    specify. For convenience, ``AVSValue`` offers a set of ``As...()``\n    functions which take default values. See ``avisynth.h``.\n\n::\n\n    return \"`Invert' sample plugin\";\n\nThe return value of ``AvisynthPluginInit`` is a string which can contain any\nmessage you like, such as a notice identifying the version and author of the\nplugin. This string becomes the return value of ``LoadPlugin``, and will\nalmost always be ignored. You can also just return 0 if you prefer.\n\n\nVariations\n~~~~~~~~~~\n\nAn in-place filter\n^^^^^^^^^^^^^^^^^^\n\nThe ``Invert`` filter could easily do its work in a single buffer, rather\nthan copying from one buffer to another. Here's a new implementation of\n``GetFrame`` that does this.\n::\n\n    PVideoFrame Invert::GetFrame(int n, IScriptEnvironment* env) {\n\n        PVideoFrame frame = child->GetFrame(n, env);\n\n        env->MakeWritable(&frame);\n\n        unsigned char* p = frame->GetWritePtr();\n        const int pitch = frame->GetPitch();\n        const int row_size = frame->GetRowSize();\n        const int height = frame->GetHeight();\n\n        for (int y = 0; y < height; y++) {\n            for (int x = 0; x < row_size; x++)\n                p[x] ^= 255;\n            p += pitch;\n        }\n\n        return frame;\n    }\n\nThe key difference between this version of the function and the original\nversion is the presence of the ``MakeWritable`` callback. This is necessary\nbecause this time \"we don't know where that frame's been.\" Someone else in\nthe filter chain may be holding a reference to it, in which case we won't be\nallowed to write to it.\n\n``MakeWritable`` is a simple solution to this problem. It is implemented as\nfollows (in avisynth.cpp):\n::\n\n    bool ScriptEnvironment::MakeWritable(PVideoFrame* pvf) {\n      const PVideoFrame& vf = *pvf;\n\n      // If the frame is already writable, do nothing.\n\n      if (vf->IsWritable()) {\n        return false;\n      }\n\n      // Otherwise, allocate a new frame (using NewVideoFrame) and\n      // copy the data into it.  Then modify the passed PVideoFrame\n      // to point to the new buffer.\n\n      else {\n        const int row_size = vf->GetRowSize();\n        const int height = vf->GetHeight();\n        PVideoFrame dst = NewVideoFrame(row_size, height);\n        BitBlt(dst->GetWritePtr(), dst->GetPitch(), vf->GetReadPtr(),\n        vf->GetPitch(), row_size, height);\n        *pvf = dst;\n        return true;\n      }\n    }\n\n\nA filter that changes the frame size\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nIn order to effect a change in frame size, two things must happen:\n\n-   your ``GetVideoInfo`` method must return a ``VideoInfo`` struct with\n    the appropriate size, and\n-   your ``GetFrame`` method must return video frames of the appropriate\n    size.\n\nIf you derive your filter class from ``GenericVideoFilter``, then a\nconvenient way to achieve both of these things is to assign the new values to\n``vi.width`` and ``vi.height`` in your class constructor. This way you won't\nhave to override ``GetVideoInfo``, since ``GenericVideoFilter``'s\nimplementation just returns ``vi``. And if you allocate your output frames\nusing ``env->NewVideoFrame(vi)``, then they will be of the appropriate size\nas well.\n\nFor an example of a simple filter which does this, see ``Crop`` or\n``StackVertical``.\n\n\nA filter which processes audio\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nAudio processing is handled through the ``GetAudio`` method, which has the\nfollowing prototype:\n::\n\n    void GetAudio(void* buf, int start, int count, IScriptEnvironment* env);\n\nYou must fill in the ``buf``fer with ``count`` samples beginning with sample\nnumber ``start``. A sample may vary from one to four bytes, depending on\nwhether the audio is 8- or 16-bit and mono or stereo. The flags ``vi.stereo``\nand ``vi.sixteen_bit`` will tell you this.\n\nIf you cannot do your audio processing in-place, you must allocate your own\nbuffer for the source audio using ``new`` or ``malloc``.\n\n\nA filter which rearranges frames\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nMany of the built-in filters do nothing more than rearrange video frames (for\nexample ``Trim``, ``Splice``, ``SelectEvery``, ``Interleave``, ``Reverse``,\nand ``ChangeFPS``). If you want to do this, you can write a ``GetFrame``\nmethod like this:\n::\n\n    PVideoFrame GetFrame(int n, IScriptEnvironment* env) {\n        return child->GetFrame(ConvertFrameNumber(n), env);\n    }\n\nBut you must also do three other things:\n\n-   Write a companion ``GetParity`` method so that field information is\n    preserved; for example, **``bool GetParity(int n) { return\n    child->GetParity(ConvertFrameNumber(n)); }``**;\n-   Set ``vi.num_frames`` and/or call ``vi.SetFPS`` at instance\n    construction time, if you change the frame count or frame rate;\n-   Decide what you want to do with the audio track, and write a\n    ``GetAudio`` method if necessary.\n\n\nOther useful methods in IScriptEnvironment\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n::\n\n    __declspec(noreturn) virtual void ThrowError(const char* fmt, ...);\n\nThis function throws an exception (of type ``AvisynthError``). Usually, your\nerror message will end up being displayed on the user's screen in lieu of the\nvideo clip they were expecting.\n\nYou can safely call ``ThrowError`` from anywhere except inside ``GetParity``\nand ``GetVideoInfo``.\n\nI declared this function as ``__declspec(noreturn)`` to prevent \"not all\ncontrol paths return a value\" warnings. But it didn't work -- I still get the\nwarnings. Go figure.\n::\n\n    virtual long GetCPUFlags();\n\nThis is exactly the same as the corresponding VirtualDub function (to the\npoint of being implemented with code taken directly from VirtualDub -- sorry\nAvery ;-) ).\n\nTo find out if you're running on a CPU that supports MMX, test\n``env->GetCPUFlags() & CPUF_MMX``. There's a complete list of flags in\n``avisynth.h``.\n::\n\n    virtual char* SaveString(const char* s, int length = -1);\n\nThis function copies its argument to a safe \"permanent\" location and returns\na pointer to the new location.\n\nEach ``ScriptEnvironment`` instance has a buffer set aside for storing\nstrings, which is expanded as needed. The strings are not deleted until the\n``ScriptEnvironment`` instance goes away (when the script file is closed,\nusually). This is usually all the permanence that is needed, since all\nrelated filter instances will already be gone by then.\n\nThe returned pointer is not const-qualified, and you're welcome to write to\nit, as long as you don't stray beyond the bounds of the string.\n::\n\n    virtual char* Sprintf(const char* fmt, ...);\n\n    virtual char* VSprintf(const char* fmt, char* val);\n\nThese store strings away in the same way as ``SaveString``, but they treat\ntheir arguments like ``printf`` and ``vprintf``.\n\nCurrently there's a size limit of 4096 characters on strings created this\nway. (The implementation uses ``_vsnprintf``, so you don't need to worry\nabout buffer overrun.)\n::\n\n    virtual AVSValue Invoke(const char* name, const AVSValue args, const char** arg_names=0);\n\nYou can use this to call a script function. There are many script functions\nwhich can be useful from other filters; for example, the ``Bob`` filter uses\n``SeparateFields``, and several source filters use ``UnalignedSplice``. Some\nfunctions, like ``Weave``, are implemented entirely in terms of other\nfunctions.\n\nIf you're calling a function taking exactly one argument, you can simply pass\nit in the ``args`` parameter; ``Invoke`` will convert it into an array for\nyou. In order to call a function taking multiple arguments, you will need to\ncreate the array yourself; it can be done like this:\n::\n\n        AVSValue args[5] = { clip, 0, true, 4.7, \"my hovercraft is\n        full of eels\" };\n        env->Invoke(\"Frob\", AVSValue(args, 5));\n\n\nIn this case ``Frob`` would need to have a parameter-type string like \"cibfs\"\nor \"cfbfs\" or \"cf.*\".\n\nThe ``arg_names`` parameter can be used to specify named arguments. Named\narguments can also be given positionally, if you prefer.\n\n``Invoke`` throws ``IScriptEnvironment::NotFound`` if it can't find a\nmatching function prototype. You should be prepared to catch this unless you\nknow that the function exists and will accept the given arguments.\n::\n\n    virtual void BitBlt(unsigned char* dstp, int dst_pitch, const unsigned char* srcp,\n                        int src_pitch, int row_size, int height);\n\nThis brilliantly-named function does a line-by-line copy from the source to\nthe destination. It's useful for quite a number of things; the built-in\nfilters ``DoubleWeave``, ``FlipVertical``, ``AddBorders``, ``PeculiarBlend``,\n``StackVertical``, ``StackHorizontal``, and ``ShowFiveVersions`` all use it\nto do their dirty work.\n::\n\n    typedef void (__cdecl *ShutdownFunc)(void* user_data, IScriptEnvironment* env);\n    virtual void AtExit(ShutdownFunc function, void* user_data);\n\nIf you find yourself wanting an ``AvisynthPluginShutdown`` export, this is\nthe way to get that effect. Functions added through ``AtExit`` are called (in\nthe opposite order that they were added) when the corresponding\nScriptEnvironment goes away.\n\n--------\n\n.. image:: sig.gif\n    :alt: Ben Rudiak-Gould\n\n\n--------\n\n\nNotes to Ben's docs\n^^^^^^^^^^^^^^^^^^^\n\nPlugin exported function name is replaced from ``AvisynthPluginInit`` for\nAviSynth 1.0-2.0 to ``AvisynthPluginInit2`` for AviSynth 2.5. For other\nchanges see :doc:`AviSynthTwoFiveSDK. <AviSynthTwoFiveSDK>`\n\nFor AviSynth 2.5, the converted :doc:`TwoFiveInvert <TwoFiveInvert>` plugin filter source.\n\n\nBack to :doc:`FilterSDK <FilterSDK>`\n\n$Date: 2006/11/08 20:40:16 $\n\n.. _mirror.: http://www.neuron2.net/www.math.berkeley.edu/benrg/avisynth-extensions.html\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/C_api.rst",
    "content": "\nC API\n=====\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\nPreface\n~~~~~~~\n\nThe ABI closely mirrors the native C++ ABI. It should provide all the functionality \nof C++. The main differences from the C++ ABI are:\n\n- The way a new filter is created since virtual functions can't be used.\n- Error handling since exceptions can't be used.\n- Memory management since smart pointers can't be used.\n\nThe header, ``avisynth_c.h``, and some of its helpers in the ``avs/`` folder, declare \nall the classes, structures, and miscellaneous constants that you might need when \nwriting a plugin or a client. All external plugins should ``#include`` it (which \nincludes some more helper headers from the ``avs/`` directory)::\n\n    #include \"avisynth_c.h\"\n\nor if proper paths are set to the installed package and SDK include files::\n\n    #include <avisynth_c.h>\n\nUsing C interface is an option, you can use it from C++ programs.\n\nThe Avisynth library can be used in two ways:\n\nDynamic loading\n----------------\n\n- Dynamic loading ``AviSynth.dll``/``libavisynth.so``/``.dylib``.\n\n  Advantage: independence of the actual AviSynth version.\n\n  AviSynth versions with different API levels can be supported, because we can detect \n  on loading the necessary API methods whether they exist or not. Earlier AviSynth \n  versions may contain fewer API functions. By detecting the loaded AviSynth/interface \n  version, it's the caller's responsibility to call only those API functions which \n  have valid function pointers and are documented to work. For example, you should \n  only use frame property-related functions when ``lib.avs_get_version(clip) >= 9``.\n\n  - Use ``#define AVSC_NO_DECLSPEC`` for function pointer definitions only. \n    (``avisynth_c.h`` provides prototypes and a helper function for loading the \n    library in Windows.)\n  - Load the library dynamically and get the necessary API functions as needed.\n\nStatic linking\n--------------\n\n- Static linking ``avisynth.lib``/``libavisynth``.\n\n  - Leave ``AVSC_NO_DECLSPEC`` undefined.\n  - Provide ``avisynth.lib`` to the linker.\n\n  Drawback: Your plugin/software won't work with older AviSynth instances. If your \n  plugin/client is using newer API functions, your plugin or client will fail to \n  start due to dependency issues. (On Windows: platform returned code 127.)\n\nNote: The library name for Windows is ``avisynth.lib``. On Unix-like systems, it is \ncalled ``libavisynth.so``, and on macOS, it is called ``libavisynth.dylib``.\n\n\n\nUseful source links\n~~~~~~~~~~~~~~~~~~~\n\nNote from 2025: until this part is updated properly, check these excellent\nexamples for using C API as a client or in a plugin:\n\n- ffmpeg (client)\n\n  https://github.com/FFmpeg/FFmpeg/blob/release/7.1/libavformat/avisynth.c\n\n- x265mod (client)\n\n  https://github.com/Patman86/x265-Mod-by-Patman/blob/master/source/input/avs.cpp\n\n- x264 (client)\n\n  https://code.videolan.org/videolan/x264/-/blob/master/input/avs.c?ref_type=heads\n  \n- avs2yuv (client)\n\n  https://github.com/DJATOM/avs2yuv\n  \n- Many-many plugins from Asd-g:\n\n  https://github.com/Asd-g/\n  \n- AvsInPaint plugin\n\n  https://github.com/pinterf/AvsInpaint\n  \n- AssRender plugin\n\n  https://github.com/pinterf/assrender\n\n\nQuick list\n~~~~~~~~~~\n\n+-------------------------------------+-----------------------+-------+\n| Function                            | Area                  | ver   |\n+-------------------------------------+-----------------------+-------+\n| avs_add_function                    | AVS_ScriptEnvironment | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_at_exit                         | AVS_ScriptEnvironment | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_bit_blt                         | AVS_ScriptEnvironment | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_check_version                   | AVS_ScriptEnvironment | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_clip_get_error                  | AVS_Clip              | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_copy_clip                       | AVS_Clip              | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_copy_value                      | AVS_Value             | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_copy_video_frame                | AVS_VideoFrame        | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_create_script_environment       | AVS_ScriptEnvironment | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_function_exists                 | AVS_ScriptEnvironment | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_get_audio                       | AVS_Clip              | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_get_cpu_flags                   | AVS_ScriptEnvironment | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_get_frame                       | AVS_Clip              | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_get_parity                      | AVS_Clip              | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_get_var                         | AVS_ScriptEnvironment | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_get_version                     | AVS_Clip              | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_get_video_info                  | AVS_Clip              | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_invoke                          | AVS_ScriptEnvironment | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_make_writable                   | AVS_VideoFrame        | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_new_c_filter                    | AVS_ScriptEnvironment | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_new_video_frame_a               | AVS_VideoFrame        | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_release_clip                    | AVS_Clip              | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_release_value                   | AVS_Value             | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_release_video_frame             | AVS_VideoFrame        | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_save_string                     | AVS_ScriptEnvironment | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_set_cache_hints                 | AVS_Clip              | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_set_global_var                  | AVS_ScriptEnvironment | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_set_memory_max                  | AVS_ScriptEnvironment | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_set_to_clip                     | AVS_Value             | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_set_var                         | AVS_ScriptEnvironment | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_set_working_dir                 | AVS_ScriptEnvironment | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_subframe                        | AVS_VideoFrame        | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_take_clip                       | AVS_Value             | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_vsprintf                        | AVS_ScriptEnvironment | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_sprintf                         | AVS_ScriptEnvironment | 3     |\n+-------------------------------------+-----------------------+-------+\n| avs_delete_script_environment       | AVS_ScriptEnvironment | 6     |\n+-------------------------------------+-----------------------+-------+\n| avs_subframe_planar                 | AVS_VideoFrame        | 6     |\n+-------------------------------------+-----------------------+-------+\n| avs_get_error                       | AVS_ScriptEnvironment | 6     |\n+-------------------------------------+-----------------------+-------+\n| avs_is_yv24                         | AVS_VideoInfo         | 6     |\n+-------------------------------------+-----------------------+-------+\n| avs_is_yv16                         | AVS_VideoInfo         | 6     |\n+-------------------------------------+-----------------------+-------+\n| avs_is_yv12                         | AVS_VideoInfo         | 6     |\n+-------------------------------------+-----------------------+-------+\n| avs_is_yv411                        | AVS_VideoInfo         | 6     |\n+-------------------------------------+-----------------------+-------+\n| avs_is_y8                           | AVS_VideoInfo         | 6     |\n+-------------------------------------+-----------------------+-------+\n| avs_is_color_space                  | AVS_VideoInfo         | 6     |\n+-------------------------------------+-----------------------+-------+\n| avs_get_plane_width_subsampling     | AVS_VideoInfo         | 6     |\n+-------------------------------------+-----------------------+-------+\n| avs_get_plane_height_subsampling    | AVS_VideoInfo         | 6     |\n+-------------------------------------+-----------------------+-------+\n| avs_bits_per_pixel                  | AVS_VideoInfo         | 6     |\n+-------------------------------------+-----------------------+-------+\n| avs_bytes_from_pixels               | AVS_VideoInfo         | 6     |\n+-------------------------------------+-----------------------+-------+\n| avs_row_size                        | AVS_VideoFrame        | 6     |\n+-------------------------------------+-----------------------+-------+\n| avs_bmp_size                        | AVS_VideoInfo         | 6     |\n+-------------------------------------+-----------------------+-------+\n| avs_get_pitch_p                     | AVS_VideoFrame        | 6     |\n+-------------------------------------+-----------------------+-------+\n| avs_get_row_size_p                  | AVS_VideoFrame        | 6     |\n+-------------------------------------+-----------------------+-------+\n| avs_get_height_p                    | AVS_VideoFrame        | 6     |\n+-------------------------------------+-----------------------+-------+\n| avs_get_read_ptr_p                  | AVS_VideoFrame        | 6     |\n+-------------------------------------+-----------------------+-------+\n| avs_is_writable                     | AVS_VideoFrame        | 6     |\n+-------------------------------------+-----------------------+-------+\n| avs_get_write_ptr_p                 | AVS_VideoFrame        | 6     |\n+-------------------------------------+-----------------------+-------+\n| avs_is_yuv444p16                    | AVS_VideoInfo         | 6+  X |\n+-------------------------------------+-----------------------+-------+\n| avs_is_yuv422p16                    | AVS_VideoInfo         | 6+  X |\n+-------------------------------------+-----------------------+-------+\n| avs_is_yuv420p16                    | AVS_VideoInfo         | 6+  X |\n+-------------------------------------+-----------------------+-------+\n| avs_is_y16                          | AVS_VideoInfo         | 6+  X |\n+-------------------------------------+-----------------------+-------+\n| avs_is_yuv444ps                     | AVS_VideoInfo         | 6+  X |\n+-------------------------------------+-----------------------+-------+\n| avs_is_yuv422ps                     | AVS_VideoInfo         | 6+  X |\n+-------------------------------------+-----------------------+-------+\n| avs_is_yuv420ps                     | AVS_VideoInfo         | 6+  X |\n+-------------------------------------+-----------------------+-------+\n| avs_is_y32                          | AVS_VideoInfo         | 6+  X |\n+-------------------------------------+-----------------------+-------+\n| avs_num_components                  | AVS_VideoInfo         | 6+    |\n+-------------------------------------+-----------------------+-------+\n| avs_component_size                  | AVS_VideoInfo         | 6+    |\n+-------------------------------------+-----------------------+-------+\n| avs_bits_per_component              | AVS_VideoInfo         | 6+    |\n+-------------------------------------+-----------------------+-------+\n| avs_is_444                          | AVS_VideoInfo         | 6+    |\n+-------------------------------------+-----------------------+-------+\n| avs_is_422                          | AVS_VideoInfo         | 6+    |\n+-------------------------------------+-----------------------+-------+\n| avs_is_420                          | AVS_VideoInfo         | 6+    |\n+-------------------------------------+-----------------------+-------+\n| avs_is_y                            | AVS_VideoInfo         | 6+    |\n+-------------------------------------+-----------------------+-------+\n| avs_is_yuva                         | AVS_VideoInfo         | 6+    |\n+-------------------------------------+-----------------------+-------+\n| avs_is_planar_rgb                   | AVS_VideoInfo         | 6+    |\n+-------------------------------------+-----------------------+-------+\n| avs_is_planar_rgba                  | AVS_VideoInfo         | 6+    |\n+-------------------------------------+-----------------------+-------+\n| avs_is_rgb48                        | AVS_VideoInfo         | 6+    |\n+-------------------------------------+-----------------------+-------+\n| avs_is_rgb64                        | AVS_VideoInfo         | 6+    |\n+-------------------------------------+-----------------------+-------+\n| avs_subframe_planar_a               | AVS_VideoFrame        | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_copy_frame_props                | AVS_VideoFrame        | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_get_frame_props_ro              | AVS_VideoFrame        | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_get_frame_props_rw              | AVS_VideoFrame        | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_prop_num_keys                   | AVS_Map               | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_prop_get_key                    | AVS_Map               | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_prop_num_elements               | AVS_Map               | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_prop_get_type                   | AVS_Map               | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_prop_get_int                    | AVS_Map               | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_prop_get_float                  | AVS_Map               | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_prop_get_data                   | AVS_Map               | 9.1 ! |\n+-------------------------------------+-----------------------+-------+\n| avs_prop_get_data_size              | AVS_Map               | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_prop_get_clip                   | AVS_Map               | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_prop_get_frame                  | AVS_Map               | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_prop_delete_key                 | AVS_Map               | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_prop_set_int                    | AVS_Map               | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_prop_set_float                  | AVS_Map               | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_prop_set_data                   | AVS_Map               | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_prop_set_clip                   | AVS_Map               | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_prop_set_frame                  | AVS_Map               | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_prop_get_int_array              | AVS_Map               | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_prop_get_float_array            | AVS_Map               | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_prop_set_int_array              | AVS_Map               | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_prop_set_float_array            | AVS_Map               | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_clear_map                       | AVS_Map               | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_new_video_frame_p               | AVS_ScriptEnvironment | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_new_video_frame_p_a             | AVS_ScriptEnvironment | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_get_env_property                | AVS_ScriptEnvironment | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_pool_allocate                   | AVS_ScriptEnvironment | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_pool_free                       | AVS_ScriptEnvironment | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_get_var_try                     | AVS_ScriptEnvironment | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_get_var_bool                    | AVS_ScriptEnvironment | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_get_var_int                     | AVS_ScriptEnvironment | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_get_var_double                  | AVS_ScriptEnvironment | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_get_var_string                  | AVS_ScriptEnvironment | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_get_var_long                    | AVS_ScriptEnvironment | 8     |\n+-------------------------------------+-----------------------+-------+\n| avs_is_property_writable            | AVS_VideoFrame        | 9     |\n+-------------------------------------+-----------------------+-------+\n| avs_make_property_writable          | AVS_VideoFrame        | 9     |\n+-------------------------------------+-----------------------+-------+\n| avs_video_frame_get_pixel_type      | AVS_VideoFrame        | 10    |\n+-------------------------------------+-----------------------+-------+\n| avs_video_frame_amend_pixel_type    | AVS_VideoFrame        | 10    |\n+-------------------------------------+-----------------------+-------+\n| avs_is_channel_mask_known           | AVS_VideoInfo         | 10.1  |\n+-------------------------------------+-----------------------+-------+\n| avs_set_channel_mask                | AVS_VideoInfo         | 10.1  |\n+-------------------------------------+-----------------------+-------+\n| avs_get_channel_mask                | AVS_VideoInfo         | 10.1  |\n+-------------------------------------+-----------------------+-------+\n| avs_set_to_void                     | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_set_to_error                    | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_set_to_bool                     | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_set_to_int                      | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_set_to_string                   | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_set_to_float                    | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_set_to_double                   | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_set_to_long                     | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_set_to_array                    | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_get_as_bool                     | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_get_as_int                      | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_get_as_long                     | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_get_as_string                   | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_get_as_float                    | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_get_as_error                    | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_get_as_array                    | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_get_array_elt                   | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_get_array_size                  | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_val_defined                     | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_val_is_error                    | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_val_is_bool                     | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_val_is_int                      | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_val_is_string                   | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_val_is_float                    | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_val_is_floatf_strict            | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_val_is_long_strict              | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_val_is_array                    | AVS_Value             | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_prop_get_int_saturated          | AVS_Map               | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_prop_get_float_saturated        | AVS_Map               | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_prop_get_data_type_hint         | AVS_Map               | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_prop_set_data_h                 | AVS_Map               | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_add_function_r                  | AVS_ScriptEnvironment | 11    |\n+-------------------------------------+-----------------------+-------+\n| avs_get_cpu_flags_ex                | AVS_ScriptEnvironment | 12    |\n+-------------------------------------+-----------------------+-------+\n\n\nReference\n~~~~~~~~~\n\n.. _c_avs_add_function:\n\navs_add_function\n----------------\n\n\n::\n\n    int avs_add_function(AVS_ScriptEnvironment *, \n                         const char * name, const char * params,\n                         AVS_ApplyFunc apply, void * user_data);\n\n    int avs_add_function_r(AVS_ScriptEnvironment *, \n                         const char * name, const char * params,\n                         AVS_ApplyFuncR apply, void * user_data);\n\n\nBoth forms define the function name, parameter signature, and the callback function itself. The \ndifference lies in the type of the callback function (apply).\n\n``avs_add_function`` and ``avs_add_function_r`` are used to inform AviSynth of the existence of\nour filter. These functions register a function with AviSynth's internal function table.\n\nThe base ``avs_add_function`` takes four arguments: the name of the new script function, the \nparameter-type string, the C function (callback) implementing the script function, and the \nuser_data cookie.\n\nThe added function returns a type ``AVS_Value`` and can therefore return any AVS_Value type, Clip, string, \ninteger, double, etc.. In this version the function returns AVS_Value directly.\n\nThe second form, ``avs_add_function_r``, is an alternative approach where the function result is \nprovided by filling the ``AVS_Value`` result into a passed pointer.\n\nThis is particularly useful when interfacing with Python. In Python 3.13 (as of 2025), our callback\nwritten in Python cannot return structs (like ``AVS_Value``) directly to the C caller via a function \nreturn value. However, it can accept and fill an ``AVS_Value`` C struct passed as a pointer.\n\nThe first form avs_add_function, the callback (``apply``) returns result as return value (``AVS_Value``).\nThis is the callback type used by ``avs_add_function``:\n::\n\n    typedef AVS_Value (AVSC_CC * AVS_ApplyFunc)(AVS_ScriptEnvironment *, \n                                                AVS_Value args, void * user_data);\n\nInt the alternative form, the callback (``apply``) returns result in byref parameter (``AVS_Value *``)\nThis is the callback type used by ``avs_add_function_r``:\n::\n\n    typedef void(AVSC_CC* AVS_ApplyFuncR)(AVS_ScriptEnvironment*, \n                                          AVS_Value* ret, AVS_Value args, void* user_data);\n\nIts main purpose in ``avisynth_c_plugin_init`` or ``avisynth_c_plugin_init2`` to add and define plugin filters.\nBut a client or a plugin can define its own functions or filters as well.\n\nExample:\n::\n\n    static AVS_Value AVSC_CC Create_JincResize(AVS_ScriptEnvironment* env, AVS_Value args, void* param) {\n    ...\n    }\n\n    avs_add_function(env, \"JincResize\", \"cii[src_left]f[src_top]f[src_width]f[src_height]f[quant_x]i[quant_y]i\"\n                                        \"[tap]i[blur]f[cplace]s[threads]i[opt]i\", Create_JincResize, 0);\n\nExample (alternative version): a simple (non-Clip oriented) example which would add X to the input.\n::\n\n    static void AVSC_CC Create_IncreaseBy(AVS_ScriptEnvironment* env, AVS_Value *retval, AVS_Value args, void* param) {\n    ...\n    }\n\n    avs_add_function_r(env, \"IncreaseBy\", \"[delta]i\", Create_IncreaseBy, 0);\n\n\nThe added function is of type AVSValue and can therefore return any AVSValue. \n\nFor more info and examples see also :ref:`cplusplus_addfunction` in C++ API.\n\nRelated also :ref:`c_callbacks`\n\n\n.. _c_avs_at_exit:\n\navs_at_exit\n-----------\n\nSets the callback, which will be called when the ``AVS_ScriptEnvironment`` is destroyed by Avisynth core.\n\nRelated also :ref:`c_at_exit`\nSee also: :ref:`cplusplus_atexit`\n\n.. _c_avs_bit_blt:\n\navs_bit_blt\n-----------\n\nSee also: :ref:`cplusplus_bitblt`\n\n.. _c_avs_check_version:\n\navs_check_version\n-----------------\n\nSee also: :ref:`cplusplus_checkversion`\n\n.. _c_avs_clip_get_error:\n\navs_clip_get_error\n------------------\n\nUse this after an avs_get_frame, there is no other way to check if GetFrame was successful.\nNo c++ API equivalent.\n\n.. _c_avs_copy_clip:\n\navs_copy_clip\n-------------\n\nClones an ``AVS_Clip`` variable, this is important because clip objects are reference counted. When the reference\ncount reaches zero, the clip is destroyed from memory.\n\nThis clip must be released manually by ``avs_release_clip``.\n\nIn c++ a simple PClip clip = clip2 assignment does this task, PClip is a smart pointers in C++.\n\nSee also: :ref:`cplusplus_pclip`\n\n.. _c_avs_copy_value:\n\navs_copy_value\n--------------\n\nClones an ``AVS_Value`` variable, this is important because AVS_Value objects can be reference counted (clip, function object - latter \nis not available in the C interface), or resource is allocated for them in Avisynth core (for 64 bit long, double and (dynamic) arrays, \nmaybe strings in the future). \n\nAt clip content, its reference count is increased by one.\n\nThis ``avs_copy_value`` is the _proper_ copy of an ``AVS_Value``. See also ``avs_array_elt`` which obtains an ``AVS_Value`` element from\nan array; but it just gets a duplicate (field-by-field single AVS_Value copy, no reference counts are affected) from its ``AVS_Value`` \ncontent. \n\nThe variable obtained with ``avs_copy_value`` must be released with ``avs_release_value``.\n\nThe function performs deep-copy if the source is an array, the result is a dynamic array (managed by Avisynth) in this case.\n\nAs mentioned above, avs_copy_value results must be released, unlike ``array_elt``'d values, which must not be freed; \nas a best practice, keep the array_elt'd value as-is and always free the original C array elements.\n\nIf array is an Avisynth+ ``dynamic array`` (all arrays are smart dynamic arrays in script and C++ AVSValue), then \ncall ``avs_release_value`` for the array alone would deep-free the whole content. \nBut when the array is a C allocated one, free their elements with ``avs_release_value`` one by one \n(except if the value is another C array). You can do anyhow, but remember, release only once. Calling avs_release_value\non a C array would result in crash.\n\nIn c++ a simple ``AVSValue var1 = var2`` assignment does this task, ``AVSValue`` is a smart pointer in C++.\n\nSee also: :ref:`cplusplus_avsvalue`\n\n.. _c_avs_copy_video_frame:\n\navs_copy_video_frame\n--------------------\n\nClones an ``AVS_VideoFrame`` variable, but not only copies a single pointer but increases the frame's reference counter.\nThis is important because video frame objects are reference counted. On release the reference count is decreased by one.\nWhen the reference count reaches zero, the video frame is destroyed from memory.\n\nThe obtained video frame must be released manually by ``avs_release_video_frame``.\n\nIn c++ a simple ``PVideoFrame frame_dst = frame_src`` assignment does this task, ``PVideoFrame`` is a smart pointers in C++.\n\nSee also: :ref:`cplusplus_videoframe`\n\n.. _c_avs_create_script_environment:\n\navs_create_script_environment\n-----------------------------\n\nSee also: :ref:`cplusplus_createscriptenvironment`\n\n.. _c_avs_function_exists:\n\navs_function_exists\n-------------------\n\nSee also: :ref:`cplusplus_functionexists`\n\n.. _c_avs_get_audio:\n\navs_get_audio\n-------------\n\nSee also: :ref:`cplusplus_getaudio`\n\n.. _c_avs_get_cpu_flags:\n\navs_get_cpu_flags\n-----------------\n\nSee also: :ref:`cplusplus_getcpuflags`\n\n.. _c_avs_get_cpu_flags_ex:\n\navs_get_cpu_flags_ex\n--------------------\n\nSee also: :ref:`cplusplus_getcpuflagsex`\n\n.. _c_avs_get_frame:\n\navs_get_frame\n-------------\n\nThe obtained video frame must be released with avs_release_video_frame.\n\nSee also: :ref:`cplusplus_getframe`\n\n.. _c_avs_get_parity:\n\navs_get_parity\n--------------\n\nSee also: :ref:`cplusplus_getparity`\n\n.. _c_avs_get_var:\n\navs_get_var\n-----------\n\nSee also: :ref:`cplusplus_getvar`\n\n.. _c_avs_get_version:\n\navs_get_version\n---------------\n\nFor checking the actual Avisynth interface version, use the ``avs_check_version`` and \nthe ``avs_get_env_property`` functions with AVS_AEP_xxx query values.\n\nSee also: :ref:`cplusplus_getversion`\n\n.. _c_avs_get_video_info:\n\navs_get_video_info\n------------------\n\nSee also: :ref:`GetVideoInfo<cplusplus_getvideoinfo>`\n\n.. _c_avs_invoke:\n\navs_invoke\n----------\n\nSee also: :ref:`cplusplus_invoke`\n\n.. _c_avs_make_writable:\n\navs_make_writable\n-----------------\n\nSee also: :ref:`cplusplus_makewritable`\n\n.. _c_avs_new_c_filter:\n\navs_new_c_filter\n----------------\n\n::\n\n    // This is the callback type used by avs_add_function\n    typedef AVS_Value (AVSC_CC * AVS_ApplyFunc)\n                            (AVS_ScriptEnvironment *, AVS_Value args, void * user_data);\n\n    // v11 alternative of avs_add_function with return value by reference\n    // This is the callback type used by avs_add_function_r\n    typedef void(AVSC_CC* AVS_ApplyFuncR)\n    (AVS_ScriptEnvironment*, AVS_Value* ret, AVS_Value args, void* user_data);\n\n    typedef struct AVS_FilterInfo AVS_FilterInfo;\n    struct AVS_FilterInfo\n    {\n      // these members should not be modified outside of the AVS_ApplyFunc or AVS_ApplyFuncR callback\n      AVS_Clip * child;\n      AVS_VideoInfo vi;\n      AVS_ScriptEnvironment * env;\n      AVS_VideoFrame * (AVSC_CC * get_frame)(AVS_FilterInfo *, int n);\n      int (AVSC_CC * get_parity)(AVS_FilterInfo *, int n);\n      int (AVSC_CC * get_audio)(AVS_FilterInfo *, void * buf,\n                                      int64_t start, int64_t count);\n      int (AVSC_CC * set_cache_hints)(AVS_FilterInfo *, int cachehints,\n                                            int frame_range);\n      void (AVSC_CC * free_filter)(AVS_FilterInfo *);\n\n      // Should be set when ever there is an error to report.\n      // It is cleared before any of the above methods are called\n      const char * error;\n      // this is to store whatever and may be modified at will\n      void * user_data;\n    };\n\n    // Create a new filter\n    // 'fi' is set to point to the AVS_FilterInfo so that you can\n    //   modify it once it is initialized.\n    // 'store_child' should generally be set to true.  If it is not\n    //   set then ALL methods (the function pointers) must be defined\n    // If it is set then you do not need to worry about freeing the child\n    //    clip.\n    AVSC_API(AVS_Clip *, avs_new_c_filter)(AVS_ScriptEnvironment * e,\n                                           AVS_FilterInfo * * fi,\n                                           AVS_Value child, int store_child);\n\nIn a filter defintion lifetime ``avs_add_function`` defines a filter with its name, parameter signature, and a \ncallback (APPLYFUNC/APPLYFUNCR) function, which is called by Avisynth when it instantiates the filter: when founds \nits name in the script and parameters are matching and their values are known. When a script contains multiple\noccurances in the filter, each with different parameter list, this APPLYFUNC is called for each occurances.\n\n``avs_new_c_filter`` must be called from inside this filter creating ``APPLYFUNC`` or ``APPLYFUNCR`` type function. \nDynamic resource allocation for a struct for holding the filter actual parameters can also be done, typically \naddress of this struct is passed as a ``(void *)`` cookie in user_data in filter defition, in e.g. the ``get_frame`` \ncallback, and accesible at the end of the filter liferime: in free_filter callback.\n\nThrough the ``AVS_FilterInfo`` struct the callbacks ``get_frame``, ``get_audio``, ``set_cache_hints``, ``get_parity`` \ncan be set. Yes, ``avs_new_c_filter`` passes a pointer to pointer of ``AVS_FilterInfo``.\n\n``free_filter`` is a callback, practically serves as the desctructor, like the desctructor of C++ IClip descendant).\nResources allocated at filter creation can be released in there.\n\nErrors during APPLYFUNC/APPYFUNCR must be signed with a filled ``const char* error`` field in ``AVS_FilterInfo``\n\nC++ equivalent: no. It's much different. C++ works with ``IClip`` descendants, like ``GenericVideoFilter`` or\n``NonCachedGenericVideoFilter`` classes.\n\n.. _c_avs_new_video_frame_a:\n\navs_new_video_frame_a\n---------------------\n\n.. _c_avs_release_clip:\n\navs_release_clip\n----------------\n\nDecreases the ``AVS_Clip`` reference count by one. When it reaches zero, the underlying PClip object is destroyed.\nWhen there was a C function (filter) associated with it, its ``free_filter`` callback is called.\n\nIn C++ PClip is a smart pointer: reference counting and release is automatically done.\n\nSee also: :ref:`c_avs_new_c_filter`\nSee also: :ref:`c_avs_take_clip`\nSee also: :ref:`c_avs_copy_clip`\nSee also: :ref:`cplusplus_pclip`\n\n.. _c_avs_release_value:\n\navs_release_value\n-----------------\n\nIf the AVS_Value holds a clip or video frame, their reference is decreased by one. When a clip or video_frame\nreference count reaches zero, it will be also freed up.\n\nIf the AVS_Value holds an array, Avisynth will try to deep-free the elements then deallocates\nthe occupied memory. DO NOT call avs_release_value to a preallocated array from your C or C++ code.\n\nResource freeing can happen for 64 bit long and double types on 32-bit systems.\nAnd maybe on strings in the future.\n\nSo as a best practice, call avs_release_value for all types, except a C array variable itself, as necessary.\nTake care of value obtained by ``avs_array_elt``, since this does not do real resource duplication. Either the\nobtained value, or the AVS_Value in the original C array must be freed.\n\nIn C++ AVSValue is a smart pointer, its desctructor is called automatically.\n\nSee also: :ref:`cplusplus_avsvalue`\n\n.. _c_avs_release_video_frame:\n\navs_release_video_frame\n-----------------------\n\nVideoframe objects are created by ``get_frame`` (its return value), ``avs_copy_video_frame``, ``avs_new_video_frame_a``, \n``avs_new_video_frame_p``, ``avs_new_video_frame_p_a``, ``avs_subframe_planar`` and ``avs_subframe_planar_a``.\n\nThe function decreases the ``AVS_VideoFrame`` reference count by one. When it reaches zero, the underlying PVideoFrame object is destroyed.\n\nExcept when it serves as the filter return value, AVS_VideoFrame must be released.\n\nIn C++ PVideoFrame is a smart pointer: reference counting and release is automatically done.\n\nSee also: :ref:`cplusplus_videoframe`\n\n.. _c_avs_save_string:\n\navs_save_string\n---------------\n\nAvisynth must make copy of a volatile string, in order able to pass them further on in the filter chain.\nIf a function would just fill a local string buffer with text, the content disappears after the function exit.\nWith avs_save_string Avisynth with take a static copy of the string, preserving it for good (until the ScriptEnvironment lives).\n\nSee also: :ref:`cplusplus_savestring`\n\n.. _c_avs_set_cache_hints:\n\navs_set_cache_hints\n-------------------\n\nSee also: :ref:`cplusplus_setcachehints`\n\n.. _c_avs_set_global_var:\n\navs_set_global_var\n------------------\n\nSee also: :ref:`cplusplus_setglobalvar`\n\n.. _c_avs_set_memory_max:\n\navs_set_memory_max\n------------------\n\nSee also: :ref:`cplusplus_setmemorymax`\n\n.. _c_avs_set_to_clip:\n\navs_set_to_clip\n---------------\n\nStuffs an AVS_Clip into an AVS_Value. Clip reference count is increased by one. After this, the original\nAVS_Clip can be released with avs_release_clip.\n\nIn C++ a simple direct assignment is done: ``PClip clip = ... ; AVSValue retval = clip;``\n\nSee also: :ref:`c_avs_take_clip`\nSee also: :ref:`cplusplus_pclip`\n\n.. _c_avs_set_var:\n\navs_set_var\n-----------\n\n.. _c_avs_set_working_dir:\n\navs_set_working_dir\n-------------------\n\n.. _c_avs_subframe:\n\navs_subframe\n------------\n\nSee also: :ref:`cplusplus_subframe`\n\n.. _c_avs_take_clip:\n\navs_take_clip\n-------------\n\nReverse of ``avs_set_to_clip``. Extracts an ``AVS_Clip`` from an ``AVS_Value``. Clip reference count is increased by\none. After this, the original ``AVS_Value`` can be released with ``avs_release_value``.\n\nIn C++ a simple direct assignment is done: ``AVSValue val = args[0]; PClip retval = val``\n\nSee also: :ref:`c_avs_set_to_clip`\nSee also: :ref:`cplusplus_pclip`\n\n.. _c_avs_vsprintf:\n\navs_vsprintf\n------------\n\n.. _c_avs_sprintf:\n\navs_sprintf\n-----------\n\n.. _c_avs_delete_script_environment:\n\navs_delete_script_environment\n-----------------------------\n\nEnd of the world, end of everything. AtExit procedures are called during the destroy as a side effect.\n\nSee also: :ref:`cplusplus_deletescriptenvironment`\n\n.. _c_avs_subframe_planar:\n\navs_subframe_planar\n-------------------\n\nSee also: :ref:`cplusplus_subframeplanar`\n\n.. _c_avs_get_error:\n\navs_get_error\n-------------\n\n.. _c_avs_is_yv24:\n\navs_is_yv24\n-----------\n\n.. _c_avs_is_yv16:\n\navs_is_yv16\n-----------\n\n.. _c_avs_is_yv12:\n\navs_is_yv12\n-----------\n\n.. _c_avs_is_yv411:\n\navs_is_yv411\n------------\n\n.. _c_avs_is_y8:\n\navs_is_y8\n---------\n\n.. _c_avs_is_color_space:\n\navs_is_color_space\n------------------\n\n.. _c_avs_get_plane_width_subsampling:\n\navs_get_plane_width_subsampling\n-------------------------------\n\n.. _c_avs_get_plane_height_subsampling:\n\navs_get_plane_height_subsampling\n--------------------------------\n\n.. _c_avs_bits_per_pixel:\n\navs_bits_per_pixel\n------------------\n\n.. _c_avs_bytes_from_pixels:\n\navs_bytes_from_pixels\n---------------------\n\n.. _c_avs_row_size:\n\navs_row_size\n------------\n\n.. _c_avs_bmp_size:\n\navs_bmp_size\n------------\n\n.. _c_avs_get_pitch_p:\n\navs_get_pitch_p\n---------------\n\n.. _c_avs_get_row_size_p:\n\navs_get_row_size_p\n------------------\n\n.. _c_avs_get_height_p:\n\navs_get_height_p\n----------------\n\n.. _c_avs_get_read_ptr_p:\n\navs_get_read_ptr_p\n------------------\n\n.. _c_avs_is_writable:\n\navs_is_writable\n---------------\n\n.. _c_avs_get_write_ptr_p:\n\navs_get_write_ptr_p\n-------------------\n\n.. _c_avs_is_yuv444p16:\n\navs_is_yuv444p16\n----------------\n\n.. _c_avs_is_yuv422p16:\n\navs_is_yuv422p16\n----------------\n\n.. _c_avs_is_yuv420p16:\n\navs_is_yuv420p16\n----------------\n\n.. _c_avs_is_y16:\n\navs_is_y16\n----------\n\n.. _c_avs_is_yuv444ps:\n\navs_is_yuv444ps\n---------------\n\n.. _c_avs_is_yuv422ps:\n\navs_is_yuv422ps\n---------------\n\n.. _c_avs_is_yuv420ps:\n\navs_is_yuv420ps\n---------------\n\n.. _c_avs_is_y32:\n\navs_is_y32\n----------\n\n.. _c_avs_num_components:\n\navs_num_components\n------------------\n\nSee also: :doc:`VideoInfo struct <VideoInfo>`\n\n.. _c_avs_component_size:\n\navs_component_size\n------------------\n\nSee also: :doc:`VideoInfo struct <VideoInfo>`\n\n.. _c_avs_bits_per_component:\n\navs_bits_per_component\n----------------------\n\nSee also: :doc:`VideoInfo struct <VideoInfo>`\n\n.. _c_avs_is_444:\n\navs_is_444\n----------\n\nSee also: :doc:`VideoInfo struct <VideoInfo>`\n\n.. _c_avs_is_422:\n\navs_is_422\n----------\n\n.. _c_avs_is_420:\n\navs_is_420\n----------\n\n.. _c_avs_is_y:\n\navs_is_y\n--------\n\n.. _c_avs_is_yuva:\n\navs_is_yuva\n-----------\n\n.. _c_avs_is_planar_rgb:\n\navs_is_planar_rgb\n-----------------\n\n.. _c_avs_is_planar_rgba:\n\navs_is_planar_rgba\n------------------\n\n.. _c_avs_is_rgb48:\n\navs_is_rgb48\n------------\n\n.. _c_avs_is_rgb64:\n\navs_is_rgb64\n------------\n\n.. _c_avs_subframe_planar_a:\n\navs_subframe_planar_a\n---------------------\n\nSee also: :ref:`cplusplus_subframeplanara`\n\n.. _c_avs_copy_frame_props:\n\navs_copy_frame_props\n--------------------\n\n.. _c_avs_get_frame_props_ro:\n\navs_get_frame_props_ro\n----------------------\n\n.. _c_avs_get_frame_props_rw:\n\navs_get_frame_props_rw\n----------------------\n\n.. _c_avs_prop_num_keys:\n\navs_prop_num_keys\n-----------------\n\n.. _c_avs_prop_get_key:\n\navs_prop_get_key\n----------------\n\n.. _c_avs_prop_num_elements:\n\navs_prop_num_elements\n---------------------\n\n.. _c_avs_prop_get_type:\n\navs_prop_get_type\n-----------------\n\n.. _c_avs_prop_get_int:\n\navs_prop_get_int\n----------------\n\n.. _c_avs_prop_get_float:\n\navs_prop_get_float\n------------------\n\n.. _c_avs_prop_get_data:\n\navs_prop_get_data\n-----------------\n\n.. _c_avs_prop_get_data_size:\n\navs_prop_get_data_size\n----------------------\n\n.. _c_avs_prop_get_clip:\n\navs_prop_get_clip\n-----------------\n\n.. _c_avs_prop_get_frame:\n\navs_prop_get_frame\n------------------\n\n.. _c_avs_prop_delete_key:\n\navs_prop_delete_key\n-------------------\n\n.. _c_avs_prop_set_int:\n\navs_prop_set_int\n----------------\n\n.. _c_avs_prop_set_float:\n\navs_prop_set_float\n------------------\n\n.. _c_avs_prop_set_data:\n\navs_prop_set_data\n-----------------\n\n.. _c_avs_prop_set_clip:\n\navs_prop_set_clip\n-----------------\n\n.. _c_avs_prop_set_frame:\n\navs_prop_set_frame\n------------------\n\n.. _c_avs_prop_get_int_array:\n\navs_prop_get_int_array\n----------------------\n\n.. _c_avs_prop_get_float_array:\n\navs_prop_get_float_array\n------------------------\n\n.. _c_avs_prop_set_int_array:\n\navs_prop_set_int_array\n----------------------\n\n.. _c_avs_prop_set_float_array:\n\navs_prop_set_float_array\n------------------------\n\n.. _c_avs_clear_map:\n\navs_clear_map\n-------------\n\n.. _c_avs_new_video_frame_p:\n\navs_new_video_frame_p\n---------------------\n\n.. _c_avs_new_video_frame_p_a:\n\navs_new_video_frame_p_a\n-----------------------\n\n.. _c_avs_get_env_property:\n\navs_get_env_property\n--------------------\n\n.. _c_avs_pool_allocate:\n\navs_pool_allocate\n-----------------\n\n.. _c_avs_pool_free:\n\navs_pool_free\n-------------\n\n.. _c_avs_get_var_try:\n\navs_get_var_try\n---------------\n\n.. _c_avs_get_var_bool:\n\navs_get_var_bool\n----------------\n\n.. _c_avs_get_var_int:\n\navs_get_var_int\n---------------\n\n.. _c_avs_get_var_double:\n\navs_get_var_double\n------------------\n\n.. _c_avs_get_var_string:\n\navs_get_var_string\n------------------\n\n.. _c_avs_get_var_long:\n\navs_get_var_long\n----------------\n\n.. _c_avs_is_property_writable:\n\navs_is_property_writable\n------------------------\n\n.. _c_avs_make_property_writable:\n\navs_make_property_writable\n--------------------------\n\n.. _c_avs_video_frame_get_pixel_type:\n\navs_video_frame_get_pixel_type\n------------------------------\n\n.. _c_avs_video_frame_amend_pixel_type:\n\navs_video_frame_amend_pixel_type\n--------------------------------\n\n.. _c_avs_is_channel_mask_known:\n\navs_is_channel_mask_known\n-------------------------\n\n.. _c_avs_set_channel_mask:\n\navs_set_channel_mask\n--------------------\n\n.. _c_avs_get_channel_mask:\n\navs_get_channel_mask\n--------------------\n\n.. _c_avs_set_to_void:\n\navs_set_to_void\n---------------\n\n.. _c_avs_set_to_error:\n\navs_set_to_error\n----------------\n\n.. _c_avs_set_to_bool:\n\navs_set_to_bool\n---------------\n\n.. _c_avs_set_to_int:\n\navs_set_to_int\n--------------\n\n.. _c_avs_set_to_string:\n\navs_set_to_string\n-----------------\n\n.. _c_avs_set_to_float:\n\navs_set_to_float\n----------------\n\n.. _c_avs_set_to_double:\n\navs_set_to_double\n-----------------\n\n.. _c_avs_set_to_long:\n\navs_set_to_long\n---------------\n\n.. _c_avs_set_to_array:\n\navs_set_to_array\n--------------------\n\n.. _c_avs_get_as_bool:\n\navs_get_as_bool\n---------------\n\n.. _c_avs_get_as_int:\n\navs_get_as_int\n--------------\n\n.. _c_avs_get_as_long:\n\navs_get_as_long\n---------------\n\n.. _c_avs_get_as_string:\n\navs_get_as_string\n-----------------\n\n.. _c_avs_get_as_float:\n\navs_get_as_float\n----------------\n\n.. _c_avs_get_as_error:\n\navs_get_as_error\n----------------\n\n.. _c_avs_get_as_array:\n\navs_get_as_array\n----------------\n\n.. _c_avs_get_array_elt:\n\navs_get_array_elt\n-----------------\n\n.. _c_avs_get_array_size:\n\navs_get_array_size\n------------------\n\n.. _c_avs_val_defined:\n\navs_val_defined\n---------------\n\n.. _c_avs_val_is_clip:\n\navs_val_is_clip\n---------------\n\n.. _c_avs_val_is_bool:\n\navs_val_is_bool\n---------------\n\n.. _c_avs_val_is_int:\n\navs_val_is_int\n--------------\n\n.. _c_avs_val_is_long_strict:\n\navs_val_is_long_strict\n----------------------\n\n.. _c_avs_val_is_float:\n\navs_val_is_float\n----------------\n\n.. _c_avs_val_is_floatf_strict:\n\navs_val_is_floatf_strict\n------------------------\n\n.. _c_avs_val_is_string:\n\navs_val_is_string\n-----------------\n\n.. _c_avs_val_is_array:\n\navs_val_is_array\n----------------\n\n.. _c_avs_val_is_error:\n\navs_val_is_error\n----------------\n\n.. _c_avs_prop_get_int_saturated:\n\navs_prop_get_int_saturated\n--------------------------\n\n.. _c_avs_prop_get_float_saturated:\n\navs_prop_get_float_saturated\n----------------------------\n\n.. _c_avs_prop_get_data_type_hint:\n\navs_prop_get_data_type_hint\n---------------------------\n\n.. _c_avs_prop_set_data_h:\n\navs_prop_set_data_h\n-------------------\n\n.. _c_avs_add_function_r:\n\navs_add_function_r\n------------------\n\nSee :ref:`c_avs_add_function`\n\n\n.. _c_avs_scriptenvironment:\n\nAVS_ScriptEnvironment\n~~~~~~~~~~~~~~~~~~~~~\n\nIn C++ terminology: ``IScriptEnvironment``.\n\nSee at :ref:`cplusplus_createscriptenvironment`.\n\n\nAVS_Value\n~~~~~~~~~\n\nIn C++ terminology: ``AVSValue``.\n\nSee at :ref:`cplusplus_avsvalue`.\n\nAVS_VideoInfo\n~~~~~~~~~~~~~\n\nIn C++ terminology: ``VideoInfo``.\n::\n\n    // AVS_VideoInfo is laid out identically to VideoInfo\n    typedef struct AVS_VideoInfo {\n      int width, height;    // width=0 means no video\n      unsigned fps_numerator, fps_denominator;\n      int num_frames;\n\n      int pixel_type;\n\n      int audio_samples_per_second;   // 0 means no audio\n      int sample_type;\n      int64_t num_audio_samples;\n      int nchannels;\n\n      // Image type properties\n      // BFF, TFF, FIELDBASED. Also used for storing Channel Mask\n      // Manipulate it through the channelmask interface calls \n      int image_type;\n    } AVS_VideoInfo;\n\n\nSee at :doc:`VideoInfo <VideoInfo>`.\n\n\nAVS_VideoFrame\n~~~~~~~~~~~~~~\n\nIn C++ terminology: ``PVideoFrame``.\n\nInternal AVS structure which holds the frame buffer and the plane pointers, and the frame property data pointer.\n\nSee at :ref:`cplusplus_videoframe`.\n\n\nAVS_Clip\n~~~~~~~~~~~~~~\n\nIn C++ terminology: ``PClip``.\n\nSee at :ref:`cplusplus_pclip`.\n\n\n.. _c_callbacks:\n\nCallbacks\n~~~~~~~~~\n\nFunctions, filters\n------------------\n\n::\n\n    typedef AVS_Value (AVSC_CC * AVS_ApplyFunc) (AVS_ScriptEnvironment *, AVS_Value args, void * user_data)\n    int avs_add_function(AVS_ScriptEnvironment *, const char * name, const char * params, AVS_ApplyFunc apply, void * user_data) \n\n    typedef void (AVSC_CC * AVS_ApplyFuncR) (AVS_ScriptEnvironment *, AVS_Value *retval, AVS_Value args, void * user_data)\n    int avs_add_function_r(AVS_ScriptEnvironment *, const char * name, const char * params, AVS_ApplyFuncR apply, void * user_data) \n\nSee also at :ref:`c_avs_add_function`.\n\nIn order to create a new filter ``avs_add_function`` or ``avs_add_function_r`` must be used to register \na call back function of type ``AVS_ApplyFunc`` or ``AVS_ApplyFuncR``\n::\n\n    typedef struct AVS_FilterInfo AVS_FilterInfo;\n    struct AVS_FilterInfo\n    {\n      // these members should not be modified outside of the AVS_ApplyFunc or AVS_ApplyFuncR callback\n      AVS_Clip * child;\n      AVS_VideoInfo vi;\n      AVS_ScriptEnvironment * env;\n      AVS_VideoFrame * (AVSC_CC * get_frame)(AVS_FilterInfo *, int n);\n      int (AVSC_CC * get_parity)(AVS_FilterInfo *, int n);\n      int (AVSC_CC * get_audio)(AVS_FilterInfo *, void * buf,\n                                      int64_t start, int64_t count);\n      int (AVSC_CC * set_cache_hints)(AVS_FilterInfo *, int cachehints,\n                                            int frame_range);\n      void (AVSC_CC * free_filter)(AVS_FilterInfo *);\n\n      // Should be set when ever there is an error to report.\n      // It is cleared before any of the above methods are called\n      const char * error;\n      // this is to store whatever and may be modified at will\n      void * user_data;\n    };\n\nThis is the structure that contains the essence of a filter. The ``AVS_ApplyFunc`` or ``AVS_ApplyFuncR`` \ncallback must manipulate it appropriately.\n\n::\n\n    AVS_Clip * avs_new_c_filter(AVS_ScriptEnvironment * e, AVS_FilterInfo * * fi,\n                                AVS_Value child, int store_child)\n\n``avs_new_c_filter`` creates a new filter. It should be called inside the ``AVS_ApplyFunc`` or ``AVS_ApplyFuncR`` callback. \n``fi`` is set to point to the ``AVS_FilterInfo`` so that you can modify it once it is initialized. ``store_child`` should \ngenerally be set to ``true``. If it is not set, then ALL methods (the function pointers) must be defined. \nIf it is set, then you do not need to worry about freeing the child clip.\n\nIn your ``FilterInfo`` the ``free_filter`` callback is a function which is called when the clip (AVS_Clip) is destroyed, that is its reference count\nreaches zero. In C++ terminology, this is the destructor of your filter.\n\n\n.. _c_at_exit:\n\nat_exit\n-------\n\n::\n\n    typedef void (AVSC_CC *AVS_ShutdownFunc)(void* user_data, AVS_ScriptEnvironment * env)\n    void avs_at_exit(AVS_ScriptEnvironment *, AVS_ShutdownFunc function, void * user_data)\n\nThis is a callback, which is called when the AVS_ScriptEnvironment is destroyed by Avisynth core.\n\nClient can be set with ``avs_at_exit`` : :ref:`c_avs_at_exit`\n\n\nplugin initializers\n-------------------\n::\n\n    const char * AVSC_CC avisynth_c_plugin_init(AVS_ScriptEnvironment* env)\n    const char * AVSC_CC avisynth_c_plugin_init2(AVS_ScriptEnvironment* env)\n\n``avisynth_c_plugin_init`` and/or ``avisynth_c_plugin_init2`` is the entry point for the plugin and must be defined. \nThe latter is supported from V11 interface, Avisynth+ 3.7.4 (3.7.3.r4198 test).\n\nWhen Avisynth 'pings' a DLL, it will search for an init function.\n\nAvisynth version 3.7.4 tries ``avisynth_c_plugin_init2`` first. If found Avisynth+ will know that the plugin is v11 \n(64-bit data) capable. When a plugin only has ``avisynth_c_plugin_init``, then 64-bit int and double parameter values \nwill be truncated to int and float (32-bit data types) when Avisynth calls the plugin/function. This is a compatibility\nmeasure because internally AviSynth can have 64 bit long and double data types.\n\nWhen you want to be sure that your DLL will surely be found, don't forget to update the .def file as follows:\n\n::\n\n    LIBRARY AvsInpaint\n    EXPORTS\n      avisynth_c_plugin_init@4 = _avisynth_c_plugin_init@4\n      avisynth_c_plugin_init2@4 = _avisynth_c_plugin_init2@4\n\n**Example**\n\n::\n\n    AVSC_EXPORT const char * AVSC_CC avisynth_c_plugin_init(AVS_ScriptEnvironment * Env)\n    {\n      avs_add_function(Env, \"InpaintLogo\", \"c[Mask]c[Radius]f[Sharpness]f[PreBlur]f[PostBlur]f\n                      [ChromaWeight]f[PreBlurSize]f[PostBlurSize]f[ChromaTensor]b[PixelAspect]f\n                      [Steps]i\", Inpaint_Create, 0);\n      avs_add_function(Env, \"DeblendLogo\", \"cc[Alpha]c\", Deblend_Create, 0);\n      avs_add_function(Env, \"AnalyzeLogo\", \"c[Mask]c[ComputeAlpha]b[DeviationWeight]f\n                      [SubsamplingWeight]f\", Analyze_Create, 0);\n      avs_add_function(Env, \"DistanceFunction\", \"c[Scale]f[PixelAspect]f\", DistanceFunction_Create, 0);\n      return \"Logo Inpainting Filter\";\n    }\n\n    // can co-exist with avisynth_c_plugin_init\n    AVSC_EXPORT const char* AVSC_CC avisynth_c_plugin_init2(AVS_ScriptEnvironment* Env)\n    {\n      return avisynth_c_plugin_init(Env);\n    }\n\nHistorical content\n~~~~~~~~~~~~~~~~~~\n\n* to be checked and updated *\n\nsource: http://forum.doom9.org/showthread.php?p=1464911#post1464911\n\ncompiling plugins: http://forum.doom9.org/showthread.php?p=1092380#post1092380\n\nexample: http://forum.doom9.org/showthread.php?p=1001260#post1001260\n\n| For now the api is described here:\n| http://www.kevina.org/avisynth_c/api.html.\n\n| An example is given here:\n| http://www.kevina.org/avisynth_c/example.html.\n\nIn v2.60 (AVISYNTH_INTERFACE_VERSION = 6) the following functions are\nadded to the C interface:\n::\n\n    avs_is_yv24\n    avs_is_yv16\n    avs_is_yv12\n    avs_is_yv411\n    avs_is_y8\n    avs_is_color_space\n    avs_get_plane_width_subsampling\n    avs_get_plane_height_subsampling\n    avs_bits_per_pixel\n    avs_bytes_from_pixels\n    avs_row_size\n    avs_bmp_size\n    avs_get_row_size_p\n    avs_get_height_p\n\n____\n\nBack to :doc:`FilterSDK`\n\n$Date: 2025/02/24 13:53:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/ChangeFrameSize.rst",
    "content": "\nChangeFrameSize\n===============\n\nThe following example code shows how to double the width of the destination\nframe.\n::\n\n    public:\n        ShowPixelValues(PClip _child, IScriptEnvironment* env) :\n        GenericVideoFilter(_child)\n        {\n        // constructor code\n\n            vi.width = vi.width*2; // width is doubled here\n            vi.height = vi.height * 2;  // height is also\n            multiplied by 2\n        }\n        PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n    };\n\n    PVideoFrame __stdcall ShowPixelValues::GetFrame(int n, IScriptEnvironment* env)\n    {\n        PVideoFrame src = child->GetFrame(n, env);\n        PVideoFrame dst = env->NewVideoFrame(vi); // new frame is double the size of src\n    ...\n\n\nA Similar approach has to be used for changing colorspace, framerate etc.\nThere is a bit more information at :doc:`WorkingWithImages <WorkingWithImages>`.\n\n----\n\nBack to :doc:`FilterSDK`\n\nDate: 2014/10/27 22:04:54 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/ColorSpaces.rst",
    "content": "\nColorSpaces\n===========\n\n\nRGB and YUV colorspaces\n-----------------------\n\nRGB and YUV are two different ways to represent colors. In YUV colorspace\nthere is one component that represent lightness (luma) and two other\ncomponents that represent color (chroma). As long as the luma is conveyed\nwith full detail, detail in the chroma components can be reduced by\nsubsampling (filtering, or averaging) which can be done in several ways (thus\nthere are multiple formats for storing a picture in YUV colorspace). In RGB\ncolorspace there are three components, one for the amount of Red, one for the\namount of Green and one for the amount of Blue. Also in this colorspace there\nare multiple formats for storing a picture which differ in the amount of\nsamples are used for one of the three colors.\n\n\nRGB Colorspaces\n~~~~~~~~~~~~~~~\n\nThere are several RGB formats, but the two most widely used are known as\nRGB24 and RGB32.\n\nBoth of them contain three components, R,G and B - short for Red, Green and\nBlue.\n\nRGB24 and RGB32 are both an :doc:`InterleavedImageFormat <InterleavedImageFormat>`. The only difference\nbetween the two are that RGB32 contains an extra byte for each pixel.\n\nThe extra byte RGB32 contains is known as an alpha pixel, but it is actually\nquite seldom used. The reason RGB32 is considered the \"best\" format is purely\nfrom a programmers view. Handling RGB32 material is much easier than RGB24\nmaterial, because most processors operate on 32bits at the time, and not 24.\n\n\nYUV colorspace\n--------------\n\nThere are several YUV formats. There are :doc:`interleaved formats <InterleavedImageFormat>`\nand :doc:`planar formats <PlanarImageFormat>` (also called packed formats). The main\ndifference is how they are stored in memory.\n\nInterleaved images have all color components needed to represent a pixel\nplaced at the same place in memory. For planar formats the data is not\ninterleaved, but stored separately for each color channel (also called color\nplane). For filter writers this means that they can write one simple function\nthat is called three times, one for each color channel, assuming that the\noperations are channel-independent (which is not always the case). Again,\nusing aligned for both color and luma channels will allow easy memory access.\nThe use of a planar format gives in most cases a significant speedup, since\nall bytes of each plane can be treated the same way. It can also give a\nspeedup because your filter doesn't have to work on all planes, if it only\nmodifies one or two of them.\n\n\nYUY2 Colorformat\n~~~~~~~~~~~~~~~~\n\nYUY2 is an :doc:`Interleaved Image Format<InterleavedImageFormat>`. Bytes are arranged in memory like this:\n\n``YUYV|YUYV|YUYV|YUYV|YUYV|YUYV|...``\n\n``^first byte in a row.``\n\nSo each pixel horizontally shares UV (chroma) information with a neighboring\npixel.\n\n\nYV12 Colorformat\n~~~~~~~~~~~~~~~~\n\nThe YV12 colorformat is very different from RGB and YUY2 colorformats. The\nmain difference is that it is a :doc:`PlanarImageFormat <PlanarImageFormat>`. That means that the\ndifferent color components are lying separate in memory.\n\nThis can in most cases give a significant speedup, since all bytes of each\nplane can be treated the same way. It can also give a speedup because your\nfilter doesn't have to work on all planes, if it only modifies one or two of\nthem.\n\nAll images are given a pitch. The pitch is basically what can be described as\n\"length of a line\". What's funny is that the pitch does not have to be equal\nto the width of the image.\n\nFor instance, if you crop something off your image, the only thing that\nchanges is the width of your image; the pitch and the actual byte-count of a\nline remains the same.\n\nThe image is then laid out like this:\n\n``rrrrrrrrrrrrrrrrpppp``\n\n``rrrrrrrrrrrrrrrrpppp``\n\n``rrrrrrrrrrrrrrrrpppp``\n\n\nWhere 'r' are the pixels inside the image used, and 'p' is the padding\ninserted after each line.\n\nIn YV12 the Y-plane always has a byte-count that is a multiple of 16, but it\nis still possible to have mod2 width images, because the rowsize is different\nfrom the pitch. Similar the UV-planes always have a pitch that is a multiple\nof 8.\n\nWhen you request ``frame->GetRowSize(PLANAR_Y)`` you will get the rowsize of\nthe pixels _inside_ the image. When you request\n``frame->GetRowSize(PLANAR_Y_ALIGNED)`` you will ALWAYS get a rowsize that is\na multiple of 16 (multiple of 8 on UV planes).\n\nThe reason for you to use pitch to get from one line to another is that pitch\ncan be even larger than the aligned rowsize - for instance after a crop.\n\nSo what you should do is:\n\n- Get a rowsize.\n\n- For each line in the image:\n\n- Process (aligned) rowsize pixels.\n\n- Skip to next line, by adding pitch for the current plane.\n\n\nYV12 interlacing\n::::::::::::::::\n\nYV12 handles interlaced chroma differently than compared to YUY2, since YV12\nonly contains chroma information for every second line.\n\nTo enable interlacing, chroma is stretched across two luma lines in the same\nfield! That means that luma and chroma aren't directly mappable to lumaline/2\nand lumaline/2+1 as with frame based images.\n\nline 0: Chroma for interlaced luma lines 0+2\n\nline 1: Chroma for interlaced luma lines 1+3\n\nline 2: Chroma for interlaced luma lines 4+6\n\nline 3: Chroma for interlaced luma lines 5+7\n\n...etc!\n\nWhen viewing the individual lines in each plane this maps to:\n\nConsider the separate planes:\n\nLuma:\n\n``L1L1L1L1L1L1L1L1L1L1L1L1L1L1L1L1L1L1L1L1L1L1``\n\n``L2L2L2L2L2L2L2L2L2L2L2L2L2L2L2L2L2L2L2L2L2L2``\n\n``L3L3L3L3L3L3L3L3L3L3L3L3L3L3L3L3L3L3L3L3L3L3``\n\n``L4L4L4L4L4L4L4L4L4L4L4L4L4L4L4L4L4L4L4L4L4L4``\n\nChroma that maps to luma plane above:\n\n``C1C1C1C1C1C1C1C1C1C1C1``\n\n``C2C2C2C2C2C2C2C2C2C2C2``\n\nSince luma L1 and L3 are in the same field, the chroma information in C1 is\nused for these lines and NOT line L1 + L2 as when the image is frame-based.\nC2 is used for lines 2+4 and so on.\n\nThis is something that deinterlacers and similar programs need to take into\nconsideration. Other filters might rely on the use of Separatefields() and\nWeave(), to produce framebased images. You can use the\nVideoInfo.IsFieldBased() to check your source, and maybe decide to throw an\nerror, or shift to another processing mode.\n\nIf your video is fieldbased your vertical resolution (height) must be\ndivisible by 4, otherwise AviSynth will not create a new VideoFrame, but will\nthrow an error.\n\n\nLinks\n~~~~~\n\nSee more about :doc:`DataStorageInAviSynth <DataStorageInAviSynth>`.\n\nSee a general introduction to :doc:`WorkingWithImages <WorkingWithImages>`.\n\n----\n\nBack to :doc:`FilterSDK`\n\n$Date: 2014/10/27 22:04:54 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/ColorspaceProperties.rst",
    "content": "\nColorspace properties\n=====================\n\nIn AviSynth v2.60, the colorspace properties are:\n::\n\n    // Colorspace properties.\n    enum {\n        CS_BGR               = 1<<28,\n        CS_YUV               = 1<<29,\n        CS_INTERLEAVED       = 1<<30,\n        CS_PLANAR            = 1<<31,\n\n        CS_VPlaneFirst       = 1<<3\n        CS_UPlaneFirst       = 1<<4\n\n        CS_Shift_Sub_Width   =  0\n        CS_Shift_Sub_Height  =  8\n        CS_Shift_Sample_Bits = 16\n\n        CS_Sub_Width_1       = 3 << CS_Shift_Sub_Width, // YV24\n        CS_Sub_Width_2       = 0 << CS_Shift_Sub_Width, // YV12, I420, YV16\n        CS_Sub_Width_4       = 1 << CS_Shift_Sub_Width, // YUV9, YV411\n\n        CS_Sub_Height_1      = 3 << CS_Shift_Sub_Height, // YV16, YV24, YV411\n        CS_Sub_Height_2      = 0 << CS_Shift_Sub_Height, // YV12, I420\n        CS_Sub_Height_4      = 1 << CS_Shift_Sub_Height, // YUV9\n\n        CS_Sample_Bits_8     = 0 << CS_Shift_Sample_Bits,\n        CS_Sample_Bits_16    = 1 << CS_Shift_Sample_Bits,\n        CS_Sample_Bits_32    = 2 << CS_Shift_Sample_Bits,\n    };\n\n    // Specific colorformats\n    enum {\n        CS_UNKNOWN = 0,\n        CS_BGR24 = 1<<0 | CS_BGR | CS_INTERLEAVED,\n        CS_BGR32 = 1<<1 | CS_BGR | CS_INTERLEAVED,\n        CS_YUY2  = 1<<2 | CS_YUV | CS_INTERLEAVED,\n        CS_RAW32 = 1<<5 | CS_INTERLEAVED,\n        CS_YV24  = CS_PLANAR | CS_YUV | CS_Sample_Bits_8 | CS_VPlaneFirst | CS_Sub_Height_1 | CS_Sub_Width_1,  // YUV 4:4:4 planar\n        CS_YV16  = CS_PLANAR | CS_YUV | CS_Sample_Bits_8 | CS_VPlaneFirst | CS_Sub_Height_1 | CS_Sub_Width_2,  // YUV 4:2:2 planar\n        CS_YV12  = CS_PLANAR | CS_YUV | CS_Sample_Bits_8 | CS_VPlaneFirst | CS_Sub_Height_2 | CS_Sub_Width_2,  // y-v-u, 4:2:0 planar\n        CS_I420  = CS_PLANAR | CS_YUV | CS_Sample_Bits_8 | CS_UPlaneFirst | CS_Sub_Height_2 | CS_Sub_Width_2,  // y-u-v, 4:2:0 planar\n        CS_IYUV  = CS_I420,\n        CS_YUV9  = CS_PLANAR | CS_YUV | CS_Sample_Bits_8 | CS_VPlaneFirst | CS_Sub_Height_4 | CS_Sub_Width_4,  // YUV 4:1:0 planar\n        CS_YV411 = CS_PLANAR | CS_YUV | CS_Sample_Bits_8 | CS_VPlaneFirst | CS_Sub_Height_1 | CS_Sub_Width_4,  // YUV 4:1:1 planar\n        CS_Y8    = CS_PLANAR | CS_INTERLEAVED | CS_YUV | CS_Sample_Bits_8,                                     // Y   4:0:0 planar\n    };\n\n\nThus CS_YV12 gives for example:\n::\n\n    CS_YV12 = CS_PLANAR | CS_YUV | CS_Sample_Bits_8 | CS_VPlaneFirst | CS_Sub_Height_2 | CS_Sub_Width_2\n            = 1<<31 | 1<<29 | 0<<16 | 1<<3 | 0<<8 | 0<<0\n            = 1010.0000.0000.0000.0000.1000\n\n\nBack to :doc:`FilterSDK` | :doc:`VideoInfo <VideoInfo>`\n\n$Date: 2015/01/13 00:24:50 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/CompilingAvisynthPlugins.rst",
    "content": "\nCompilingAviSynthPlugins\n========================\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\n.. _Introduction:\n\nIntroduction\n------------\n\nThe Avisynth API is a C++ API, but that doesn't mean that you can use\nevery C++ compiler to compile your plugin. Unfortunately compilers have\ndifferent ideas about what the C++ ABI should look like. In practice,\nthis means that if you want things to work 100% as expected, you must\ncompile your plugin with the same compiler that was used to compile\nAviSynth. That's MSVC 6.0 for official builds. Later versions of MSVC\nwill kinda sorta work, as will ICL (up to ICL10.1), but there are\ncaveats (for example, you must never allow any C++ exceptions to escape\nyour plugin ever - use ThrowError() instead - and you must always make\nsure memory allocated by AviSynth is freed by AviSynth itself and not\nby your plugin). So unfortunately it matters what C++ compiler will be\nused to compile a plugin.\n\nAn application binary interface (`ABI`_) specifies how software\ncomponents should interact with each other at the binary level (in this\ncase AviSynth and a plugin). ABIs cover details such as the sizes,\nlayout, and alignment of data types, the calling convention of\nfunctions' arguments that are passed and returned. It standardizes\ndetails such as the `C++ name mangling`_ and exception propagation.\nThe problem is that there are different C++ ABIs.\n\nMicrosoft set their general C++ ABI with their first C++ compilers, and\nit has had some changes along the years and versions of their compiler\nsuite. Intel and Borland, among others, support the Microsoft ABI, and\nthus things built with the other generally work, just like with Linux\nand the ABI used by GCC. Enter MinGW.\n\nInstead of implementing the Microsoft ABI, the people at GCC and MinGW\ndecided to just use the same C++ ABI on Windows as they use everywhere\nelse. And thus we have two groups of compilers that use a different\nABI, and thus we have problems. If you try to load a mingw-built C++\nAPI DLL from a MSVC-built Avisynth. The opposite will not work, either.\nThe C interface was made exactly for this reason, as pretty much by\nchance the ABI for C is (more or less) set, and thus it is generally OK\nto mix binaries created by different C compilers.\n\nThis is why the Avisynth C API exists: if you want a portable API, you\nwant a C API. C++ API's are more or less by definition unportable.\n\nIf you want extra reading regarding calling conventions and name\nmangling and such ABI-related things, you can read the following PDF\nthat lists quite a few things of various implementations. Available\n`here`_. Basically these things in general are not fixable by a mere\nheader, you would have to patch a compiler for the other calling\nconvention, as well as handle exceptions so that the other side would\nunderstand it as well. And so forth, and so forth. (source: Doom9 forum\nposts: `[1]`_, `[2]`_.)\n\n\n.. _Compiling AviSynth Plugins step by step instructions (for MS VC++ 6.0):\n\nCompiling AviSynth Plugins step by step instructions (for MS VC++ 6.0)\n----------------------------------------------------------------------\n\nBe sure to start with the :doc:`necessary software <SDKNecessaries>`.\n\nOpen VC++. Select a new project: Go to the File tab -> New. Select a Win32\nDynamic-Link Library in the Projects tab:\n\n.. image:: Pictures/compiling_plugins.png\n\n\nAdd the location of your project and the Project Name. The location is the\nproject folder where the source of your project will be.\n\nSelect \"An empty DLL project\":\n\n.. image:: Pictures/compiling_plugins2.png\n\n\nCopy existing source files (*.cpp), headers (*.h) and avisynth.h in your\nproject folder. If you started from scratch, you only need to copy avisynth.h\nin your project folder.\n\nGo to the Project tab -> Add To Project -> Files:\n\n.. image:: Pictures/compiling_plugins3.png\n\n\nAdd the existing source files (*.cpp), headers (*.h) and avisynth.h to your\nproject. If you start from scratch, you need to a new files to your project:\n\nGo to the Project tab -> Add To project -> New:\n\n| 1) Select C++ source file, and give it a name.\n| 2) Select C/C++ header file (if you are going to use one), and give it a name.\n\nGo to the Build tab -> Set Active Configuration -> select the release build.\n\nIf you go to the Project tab again -> Settings. Then you should see something\nsimilar as this:\n\n.. image:: Pictures/compiling_plugins4.png\n\n\nSave your workspace: File -> Save Workspace.\n\nFinally, code your source/header files, and compile your plugin. Go to the\nBuild tab -> Build (...)\n\n.. image:: Pictures/compiling_plugins5.png\n\n\n\n.. _How to debug AviSynth plugins:\n\nHow to debug AviSynth plugins\n-----------------------------\n\nTwo ways are described to debug your plugin. An easy way using DebugView and\nthe use of VC++6's debugger. In both case, the sample code :doc:`SimpleSample v1.6 <SimpleSample16>` is used.\n\n\n.. _How to debug AviSynth plugins (the short way):\n\nHow to debug AviSynth plugins (the short way)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nAn easy way to debug AviSynth plugin is to use a utility called `DebugView\nfor Windows`_ which captures OutputDebugString's output from your code\n(OutputDebugString sends a string to your debugger). It's a bit limited. So,\nif this is not sufficient, you should use a debugger as described in the next\nsection.\n\n| 1) Open Dbgview.exe. Make sure that ``Capture Win32`` under the Capture tab is selected.\n\n| 2) Add the following line at the start of your code:\n\n::\n\n    #include <stdio.h> /* for using sprintf */\n\n\nAdd, for example, the following lines in your code to check whether certain parameters are passed to the code path which comes after it:\n::\n\n    char BUF[256];\n    sprintf(BUF, \"framenr %d, text %s, height %d, pi %f\\n\", n, \"hey\",\n    src_height, 3.14);\n    OutputDebugString(BUF);\n\n\nThus:\n\n.. image:: Pictures/debugging_plugins1a.png\n\n::\n\n    Nb, %d means integer, %s means string and %f means float/double. \\n means add a new line.\n\n| 3) Compile a release build of your plugin.\n\n| 4) Open your script and scroll through it. You will see the following output in DebugView:\n\n.. image:: Pictures/debugging_plugins1b.png\n\n\nIn the example the script is loaded in line 26. After that some AviSynth\noutput is captured. In the lines 57 and 58 the output of OutputDebugString is\nwritten.\n\nIf your script crashes somewhere, you should put these lines just before the\ncrash (it may take a few attempts to find that point). Then you should pass\nthe values of the relevant parameters and check whether they are correct.\nApparently there is some parameter whose value is empty or invalid.\n\n\n.. _How to debug Avisynth plugins (for MS VC++ 6.0):\n\nHow to debug Avisynth plugins (for MS VC++ 6.0)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThese are the steps to debug an AviSynth plugin in VC++ 6:\n\n| 1. Go to the build tab and set the Active configuration to the Debug version of your plugin.\n\n| 2. Build the debug version of your plugin. Thus go to the build tab and ``Build (...)``.\n\n| 3. We will use VirtualDub.exe to debug your plugin. Go to Project tab, then select Settings -> Debug -> General -> Executable for debug session -> browse to a version of VirtualDub.exe and specify that:\n\n.. image:: Pictures/debugging_plugins2.png\n\n\n| 4. Go to Project tab, then select Settings -> Debug -> Additional DLLs, and browse to the filter DLL in the Debug directory:\n\n.. image:: Pictures/debugging_plugins3.png\n\n\n| 5. Make an AviSynth script that loads and uses your filter. Make sure to load the Debug version of your plugin! Thus for example:\n\n::\n\n    LoadPlugin(\"F:\\CompilingPlugins\\SimpleSample\\Debug\\simplesample.dll\")\n    Colorbars().Trim(0,1)\n    ConvertTORGB24()\n    SimpleSample(100)\n\n| 6. Set breakpoints as required. You can do this by clicking with the right mouse button next to a statement in your code (in the grey section). For example:\n\n.. image:: Pictures/debugging_plugins4.png\n\n\nSelect the option: Insert/Remove Breakpoint:\n\n.. image:: Pictures/debugging_plugins5.png\n\n\n| 7. Go to the Build tab, and select Start Debug -> Go (or the shortcut F5). VirtualDub will execute. Open the AviSynth script in that VirtualDub instance. The code will execute up to your first breakpoint (at least if it follows that code path):\n\n.. image:: Pictures/debugging_plugins6.png\n\n\nYou will see a yellow arrow through your breakpoint.\n\nAbove I also opened the 'variables output window'. It is under the View tab\n-> Debug Windows -> Variables. You can view the value of the variables when\nstepping through your code. Use Debug -> Step Into (or the shortcut F11) to\nstep through your code. Use Debug -> Step Over (or the shortcut F10) to step\nover function calls.\n\nWhen moving your mouse over a variable, you can also see the value of it:\n\n.. image:: Pictures/debugging_plugins7.png\n\n\nIf you want to set a breakpoint somewhere else, just remove the existing one\n(by right clicking on it). Put a new one somewhere and press F5.\n\nIf you want to stop debugging, go to the Debug tab -> Stop Debugging.\n\n\n.. _Debug info from MAP file:\n\nDebug info from MAP file\n------------------------\n\nIanB `wrote`_: Recent versions of Avisynth now ship with an avisynth.map! You\ncan use this accurately get routine addresses. Avisynth preferably loads at\n0x10000000, use the debugger loaded module display to check this.\n\nBuild your plugin in debug mode. If you can, build yourself a Debug or Relsym\navisynth.dll and debug it, if not the use the .map file provided to\ninterprete the Call stack addresses.\n\n\n.. _Compiling AviSynth Plugins step by step instructions (for MS VC++ 2005 Express Edition):\n\nCompiling AviSynth Plugins step by step instructions (for MS VC++ 2005 Express Edition)\n---------------------------------------------------------------------------------------\n\n\n.. _Setup VC++ 2005 Express Edition environment:\n\nSetup VC++ 2005 Express Edition environment\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n-   Install MS VC++ 2005 Express Edition.\n\n| http://www.microsoft.com/express/2005/\n| It is web-based install, but you need to register (which you can do freely).\n\n| I prefer manual installation with full CD image download. It may be used on computer without Internet access.\n| http://go.microsoft.com/fwlink/?linkid=57034\n\nRun it at least once before installing the SDK\n\n-   Install Microsoft Platform SDK\n\nLast version is at http://www.microsoft.com/downloads/details.aspx?FamilyId=0BAF2B35-C656-4969-ACE8-E4C0C0716ADB\n\nPrevious versions works fine too (and older February 2003).\n\nhttp://www.microsoft.com/msdownload/platformsdk/sdkupdate/\n\nhttp://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm\n\nIt seems, you need install Core component only with Web install, but you may\nprefer full or ISO download for offline computer.\n\n-   Update the Visual C++ directories in the Projects and Solutions\n    section in the Options dialog box.\n\nAdd the paths to the appropriate subsection (change 'Microsoft Platform SDK\nfor Windows Server 2003 R2' in following strings by your real path of\ninstalled version of Microsoft SDK):\n\nAdd to Executable files: ``C:\\Program Files\\Microsoft Platform SDK for Windows\nServer 2003 R2\\Bin``\n\nAdd to Include files: ``C:\\Program Files\\Microsoft Platform SDK for Windows\nServer 2003 R2\\Include``\n\nAdd to Library files: ``C:\\Program Files\\Microsoft Platform SDK for Windows\nServer 2003 R2\\Lib``\n\nSee http://msdn.microsoft.com/vstudio/express/visualc/usingpsdk/\n\n-   Update the corewin_express.vsprops file.\n\nTo make the Win32 template work in Visual C++ Express you need to edit the\ncorewin_express.vsprops file (found in ``C:\\Program Files\\Microsoft Visual\nStudio 8\\VC\\VCProjectDefaults``) and change the string that reads:\n\nAdditionalDependencies=\"kernel32.lib\" to\n\nAdditionalDependencies=\"kernel32.lib user32.lib gdi32.lib winspool.lib\ncomdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib\"\n\nThis step is usually not needed for most AviSynth plugins (kernel.lib is\nenough), but sometimes you may need in some other library, in particular\nUser.Lib for debug.\n\n-   Enable Win32 Windows Application type in the Win32 Application\n    Wizard.\n\nTo enable that type, you need to edit the file AppSettings.htm file located\nin the folder ``%ProgramFiles%/Microsoft Visual Studio 8/VC/VCWizards/AppWiz/Generic/Application/html/1033/``.\n\nIn a text editor comment out lines 441 - 444 by putting a // in front of them\nas shown here:\n\n// WIN_APP.disabled = true;\n\n// WIN_APP_LABEL.disabled = true;\n\n// DLL_APP.disabled = true;\n\n// DLL_APP_LABEL.disabled = true;\n\nSave and close the file and open Visual C++ Express.\n\nThis step is optional if you have project file for plugin (new or old C++\nversion) and do not create new plugin from scratch.\n\n\n.. _How to compile existant (old MS VC 6.0) plugin with MS VC++ 2005:\n\nHow to compile existant (old MS VC 6.0) plugin with MS VC++ 2005\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n-   Start VC++ 2005, go to folder with old plugin (e.g. :doc:`SimpleSample <SimpleSample>`)\n    unpacked zip file with full source codes and project files, and open\n    plugin workspace file SimpleSample.dsw.\n\n-   Agree in dialog to convert and open this project.\n\n-   Go to menu Build -> Configuration Manager, Set active solution\n    configuration to Release (or Debug if you want firsly debug it).\n\n-   Go to Build -> Build Solution (F7) to compile and create\n    SimpleSample.dll\n\n-   If you get fatal error LNK1181: cannot open input file 'odbc32.lib',\n    then go to menu Project -> SimpleSample Properties. Select Configuration\n    Properties -> Linker -> Input -> Additional Dependencies, and remove\n    extra unneeded libraries like odbc32.lib, odbccp32.lib.\n\n-   Also check Linker -> Output File option there and set approriate\n    pathname (or Inherit From Process default).\n\n-   You can make some changes (edit) of source codes if you want.\n\n-   Repeat command Build -> Build Solution (F7) to compile and create\n    SimpleSample.dll\n\n\n.. _How to create new plugin from scratch with MS VC++ 2005:\n\nHow to create new plugin from scratch with MS VC++ 2005\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n-   Start VC++2005.\n-   Menu: fiIe -> Create new project.\n-   Select Win32 console appication.\n-   Enter name of your new project and press OK.\n-   You will in Win32 Appcilation Wizard. Press Application Settings\n    (left panel).\n-   Select Application Type as DLL (but it may be console too).\n-   At Additional options select \"Empty project\"\n-   Copy files to project folder with Explorer.\n-   Add header file avisynth.h to the project: Menu Project -> Add\n    existent item. Also add existant (e.g. simplesample.cpp) or create new\n    CPP files by Project -> Add new item.\n-   Go to menu Build -> Configuration Manager, Set active solution\n    configuration to Release (or Debug if you want firsly debug it).\n-   Make some changes (edit) of source codes to implement your algorithm.\n    See :doc:`SimpleSample <SimpleSample>` or some other open source plugin source code and\n    Avisynth :doc:`FilterSDK <FilterSDK>` for details.\n-   Go to Build -> Build Solution (F7) to compile and create plugin\n    SimpleSample.dll\n\n\n.. _Compiling AviSynth Plugins step by step instructions (for MS VC++ 2008 Professional Edition):\n\nCompiling AviSynth Plugins step by step instructions (for MS VC++ 2008 Professional Edition)\n--------------------------------------------------------------------------------------------\n\n-   In this guide, we will compile the Example plugin from CPP for C\n    programmers, from\n    http://forum.doom9.org/showthread.php?p=1538557#post1538557 or\n    directly from http://www.mediafire.com/download.php?tc61m9otustmy29\n-   Start Microsoft Visual Studio 2008\n-   Upon first start, you are asked to set up your environment. You may\n    choose the typical Visual C++ option\n-   Choose File->New->Project or click the New Project icon\n-   On the left pane, under Project Types, expand Visual C++ and select\n    Win32\n-   On the right pane, choose Win32 Console Application\n-   Enter a name for your project (in this example we will use Example),\n    click OK\n-   You may get an error: An error has occurred in this dialog, Error:\n    54, Unspecified Error. This may be because you installed some windows\n    updates but didn't reboot yet. Click OK.\n-   You are shown the current project settings. Click Next.\n-   Under Application Type, click the DLL option. Under Additional\n    options, check the Empty project box.\n-   A new directory is created, ``My Documents\\Visual Studio\n    2008\\Projects\\Example``\n-   You need to extract the files from our example plugin into\n    ``My Documents\\Visual Studio 2008\\Projects\\Example\\Example``\n-   In the default layout, there is a Solution Explorer pane on the left\n    side. Right click Header Files, and select Add->Existing Item, select\n    avisynth.h and click Add\n-   Continue to add the other files, Info.h and InfoF.h\n-   Right click Source Files, select Add->Existing Item, and select\n    Example.cpp\n-   Click Build->Build Solution (this will give errors!)\n-   There's a lot of errors about OutputDebugStringW. To fix this, select\n    Project->Example Properties\n-   In the left pane, Expand Configuration Properties, select General\n-   In the right pane, click Character Set. Use the drop-down to select\n    Use Multi-Byte Character Set. Click OK.\n-   Click Build->Build Solution (this may give errors!)\n-   In the version 0.3 of the plugin, there was an error,\n    ``example.cpp(610) : error C4430: missing type specifier - int assumed``.\n    To fix this, double-click that error line to highlight it's location in\n    the example.cpp source file. Change ``const wstep = (vi.IsRGB24()) ? 3 :\n    4; // 3 bytes for RGB24, & 4 for RGB32.`` to ``const int wstep =\n    (vi.IsRGB24()) ? 3 : 4; // 3 bytes for RGB24, & 4 for RGB32.``\n-   Click Build->Build Solution\n-   If you get an error ``unresolved external symbol _main referenced in\n    function ___tmainCRTStartup``, then you're trying to build an .exe. Use\n    Project->Example Properties, Configuration Properties, General, set\n    Configuration Type to Dynamic Library (.dll)\n-   By default, a debug version is made. To change this,\n    Build->Configuration Manager, select Release in the left drop-down\n-   You will have to re-apply the configuration changes: Project->Example\n    Properties, Configuration Properties, General, Configuration Type=Dynamic\n    Library (.dll) and Character Set=Use Multi-Byte Character Set\n-   The following file should appear: ``My Documents\\Visual Studio\n    2008\\Projects\\Example\\Release\\Example.dll``. Note that there is also a\n    directory ``My Documents\\Visual Studio\n    2008\\Projects\\Example\\Example\\Release`` which contains only tempory files,\n    but not the dll. This is set under Project->Example Properties, General,\n    Output Directory=$(SolutionDir)$(ConfigurationName), Intermediate\n    Directory=$(ConfigurationName). In this case ``$(SolutionDir)=My\n    Documents\\Visual Studio 2008\\Projects\\Example``,\n    $(ConfigurationName)=Release.\n-   You need to copy Example.dll to your Avisynth plugins directory, and\n    then test it with the Example.avs file.\n-   If everything worked, you can proceed to modify the example by\n    following the comments, or also using the SimnpleSample included in the\n    Avisynth distribution.\n\n\n.. _Compiling AviSynth Plugins or Console Applications step by step instructions (for MS VC++ 2010 Express and Professional Edition):\n\nCompiling AviSynth Plugins or Console Applications step by step instructions (for MS VC++ 2010 Express and Professional Edition)\n--------------------------------------------------------------------------------------------------------------------------------\n\nThese instructions are also valid for the 2008 editions. Be sure to\nstart with the :doc:`necessary software <SDKNecessaries>`.\n\n\n.. _Creating a new project:\n\nCreating a new project\n~~~~~~~~~~~~~~~~~~~~~~\n\nOpen MSVC++ 2010. Select a new project:\n\n.. image:: Pictures/Compiling_plugins_msvc2010_001.jpg\n\nSelect a Win32 Console Application. Add the location of your project\nand the project name. The Location\\Name will be the project folder (or\nSolution Directory as MSVC++ 2010 calls it) where the source of your\nproject will be. If the folder \"Name\" already exists the 'Create\ndirectory for solution' box should be left unchecked, otherwise it will\ncreate as a subfolder regardless.\n\n.. image:: Pictures/Compiling_plugins_msvc2010_002.jpg\n\nSelect application settings. When creating a plugin check the\napplication type 'DLL' and when creating a console application (such as\navs2wav.exe for example) check the application type 'Console\napplication'. Also check the additional option 'Empty project' boxes.\nClick on finish:\n\n.. image:: Pictures/Compiling_plugins_msvc2010_003.jpg\n\nIn the Solution Explorer window, the solution has the 'folders'\nExternal Dependencies, Header Files, Resource Files and Source Files:\n\n.. image:: Pictures/Compiling_plugins_msvc2010_004.jpg\n\nCopy existing source files (*.cpp), headers (*.h) and avisynth.h in\nyour project folder. If you started from scratch, you only need to copy\navisynth.h in your project folder.\n\nYou can add the source and header files to your project by\nright-clicking on a 'folder' (say Header Files as in the screenshot\nbelow), select Add and Existing Item (or New Item if you start from\nscratch):\n\n.. image:: Pictures/Compiling_plugins_msvc2010_005.jpg\n\nSelect the release build, since we are building the release build.\n\n\n.. _General settings:\n\nGeneral settings\n~~~~~~~~~~~~~~~~\n\nIf it's your first time you need to select the expert settings to make\nthe build tab visible:\n\nTools > Settings > Expert Settings\n\n.. image:: Pictures/Compiling_plugins_msvc2010_006.jpg\n\nIn the property page you can see (and change) the location of the DLL\nthat will be build:\n\nRight click on the project name (InvertNeg in our case) > Properties >\nConfiguration Properties > General\n\nThe default location is $(SolutionDir)$(Configuration)\\. You have set\nthe 'SolutionDir' when defining the project\n(``D:\\AviSynth\\Plugins|InvertNeg`` in our case). 'Configuration' will be\nthe Release or Debug folder depending on which configuration you have\nselected.\n\n.. image:: Pictures/Compiling_plugins_msvc2010_007.jpg\n\nNext you need to be aware of the VC++ Directories and change them if\nnecessary:\n\nRight click on the project name (InvertNeg in our case) > Properties >\nConfiguration Properties > VC++ Directories\n\nHere you will find the location of the 'Include Directories' and\nothers. $(VCInstallDir)include points to the include folder of MSVC++\n2010 and $(WindowsSdkDir)include to the include folder of the Microsoft\nPlatform SDK. When including headers (such as windows.h) in your\nproject they will be searched for in the include folders (unless you\nexplicitly add its location when including them). So both of them\nshould point to the correct folders.\n\nNote that in general windows.h should be included in your project. It\nis the header file for accessing the Win32 API through C/C++ and it is\nlocated in the include folder of the Microsoft Platform SDK.\n\n.. image:: Pictures/Compiling_plugins_msvc2010_008.jpg\n\nYou can see the values of VCInstallDir and WindowsSdkDir when opening\nthe VS command prompt:\n\nTools > Visual Studio > Command Prompt\n\nThe VS command prompt will be loaded. Type set and you will see the\nvariables. They will be set when starting MSVC++ 2010 (by vsvars32.bat\nwhich is located in your ``<VisualStudioInstallDir>\\Common7\\Tools``\nfolder).\n\n\n.. _Building the plugin or console application:\n\nBuilding the plugin or console application\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nNow you are ready to build you DLL/EXE. Go to\n\nBuild > Build Solution\n\nAnd you will find your compiled plugin in the Location\\Name\\Folder.\n\n.. image:: Pictures/Compiling_plugins_msvc2010_009.jpg\n\n----\n\nBack to :doc:`FilterSDK <FilterSDK>`\n\n$Date: 2014/10/27 22:04:54 $\n\n.. _DebugView for Windows:\n    http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx\n.. _wrote:\n    http://forum.doom9.org/showthread.php?p=1041578#post1041578\n.. _ABI: http://en.wikipedia.org/wiki/Application_binary_interface\n.. _C++ name mangling: http://en.wikipedia.org/wiki/Name_mangling#Name_mangling_in_C.2B.2B\n.. _here: http://www.agner.org/optimize/calling_conventions.pdf\n.. _[1]: http://forum.doom9.org/showthread.php?p=1653392#post1653392\n.. _[2]: http://forum.doom9.org/showthread.php?p=1653737#post1653737\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/Cplusplus_api.rst",
    "content": "C++ API\n=======\n\nThe header, avisynth.h, declares all the classes, structures and\nmiscellaneous constants of the C++ API that you might need when writing\na plugin. All external plugins should #include it:\n::\n\n    #include \"avisynth.h\"\n\nNote, sometimes there is a reference to a version number of the plugin\napi (for example v3, v6, v8, v10). This refers to the value of\n:doc:`AVISYNTH_INTERFACE_VERSION <AviSynthInterfaceVersion>`. The\nclasses and miscellaneous constants are described below.\n\n\n.. toctree::\n    :maxdepth: 4\n\n.. contents:: Table of contents\n\n\n.. _cplusplus_createscriptenvironment:\n\nCreateScriptEnvironment\n-----------------------\n\n::\n\n    IScriptEnvironment* __stdcall CreateScriptEnvironment(int version = AVISYNTH_INTERFACE_VERSION);\n\n\nAviSynth exports this. It enables you to use AviSynth as a library,\nwithout writing an AviSynth script or without going through AVIFile.\n[todo add link]\n\n\nClasses\n-------\n\n\n.. _cplusplus_avisyntherror:\n\nAvisynthError\n~~~~~~~~~~~~~\n\n::\n\n    AvisynthError(const char* _msg)\n\n\nWrap your code in try/catch statements to enable exception handling.\nAvisynthError will tell you what's wrong.\n::\n\n    try\n    {\n        Val = Env->Invoke(\"Import\", Args, 0);\n        Clip = Val.AsClip();\n        VidInfo = Clip->GetVideoInfo();\n        Frame = Clip->GetFrame( 1, Env);\n    }\n     catch (AvisynthError err)\n    {\n        printf(\"%s\\n\", err.msg);\n        return 1;\n    }\n\n\n.. _cplusplus_videoframebuffer:\n\nVideoFrameBuffer\n~~~~~~~~~~~~~~~~\n\nVideoFrameBuffer (VFB) holds information about a memory block which is\nused for video data. For efficiency, instances of this class are not\ndeleted when the refcount reaches zero; instead they are stored in a\nlinked list to be reused. In Avisynth+ this is called frame registry.\nThe instances are deleted when the corresponding AVS file is closed.\nOr more accurately, a VideoFrameBuffer once new'd generally is not \nreleased until the IScriptEnvironment is deleted, except if SetMemoryMax\nis exceeded by too much then not in use VideoFrameBuffer's are forcible\ndeleted until SetMemoryMax is satisfied.\n\n\n.. _cplusplus_videoframe:\n\nVideoFrame\n~~~~~~~~~~\n\nVideoFrame holds a \"window\" into a VideoFrameBuffer, and since v10 it can\nstore the exact underlying video format as well. Operator new is\noverloaded to recycle class instances. Its members can be called by:\n::\n\n    PVideoFrame src = child->GetFrame(n, env);\n    src->GetReadPtr(..)\n\n\nVideoFrame has the following members: GetPitch, GetRowSize, GetHeight,\nGetReadPtr, GetWritePtr, IsWritable, IsPropertyWritable (v9),\nGetPixelType (v10) and AmendPixelType (v10).\n\nThe getter functions (except GetPixelType) will give you a property (pitch,\nrowsize, etc ...) of a plane (of the frame it points to). The\ninterleaved formats (BGR(A) or YUY2) consist of one plane, and the\nplanar formats consists of one (Y), three (YUV, planar RGB) or four \n(YUVA, planar RGBA) planes. The default plane is just the first plane\nwhich is plane Y for the planar YUV formats (and G for planar RGB).\n\nGetPixelType was introduced in v10, the exact video format of the frame\nis now stored in VideoFrame::pixel_type. Before, there was no reliable way\nof knowing it on a frame from propGetFrame.\n\nThe pixel_type is automatically maintained behind the scenes.\n\npixel_type is set on calling NewVideoFrame, and is kept with MakeWritable.\nCalling SubFrame will automatically convert the format to a single plane\ngreyscale Y8-Y32 from planar origins. Calling SubframePlanar will strip\nalpha from the format specifier.\n\nAmendPixelType can be used in special cases, to override the pixel_type.\nE.g. when a filter just overrides the format of VideoInfo in its constructor\nbut would return the frame unaltered, which would inherit a wrong pixel_type.\n\n\n.. _cplusplus_getpitch:\n\nGetPitch\n^^^^^^^^\n\n::\n\n    int GetPitch(int plane=0) const;\n\n\nThe \"pitch\" (also called stride) of a frame buffer is the offset (in\nbytes) from the beginning of one scan line to the beginning of the\nnext. The source and destination buffers won't necessarily have the\nsame pitch. The pitch can vary among frames in a clip, and it can\ndiffer from the width of the clip. [todo add link]\n\n| The scan line will be padded to a multiple of 8 or 16 (classic Avisynth) \n  or even 64 bytes (Avisynth+) due to speed reasons, so the pitch will \n  always be a multiple of that (e.g. mod64). Image processing is expensive, \n  so SIMD instructions are used to speed tasks up:\n\n| SSE uses 128 bit = 16 byte registers, so 16 byte-pixels (4 floats) can be processed\n  the same time.\n\n| AVX uses 256 bit = 32 byte registers, so 32 byte-pixels (8 floats) can be\n  processed the same time.\n\n| AVX512 uses 512 bit = 64 byte registers, so 64 byte-pixels (16 floats) can be\n  processed the same time.\n\nNOTE that the pitch can change anytime, so in most use cases you must\nrequest the pitch dynamically.\n\n\nUsage:\n\nGetPitch must be used on every plane (interleaved like YUY2 means 1\nplane...) of every PVideoFrame that you want to read or write to. It is\nthe only way to get the size of the Video Buffer (e.g. get the size of\nPVideoFrame):\n::\n\n    int buffer_size = src->GetPitch() * src->GetHeight(); //YUY2, interleaved\n\n\nThis will give you the pitch of the U-plane (it will be zero if the\nplane doesn't exist):\n::\n\n    PVideoFrame src = child->GetFrame(n, env);\n    const int src_pitchUV = src->GetPitch(PLANAR_U);\n\n\n.. _cplusplus_getrowsize:\n\nGetRowSize\n^^^^^^^^^^\n\n::\n\n    int GetRowSize(int plane=0) const;\n\n\nGetRowSize gives the length of each row in bytes (thus not in pixels).\nIt's usually equal to the pitch or slightly less, but it may be\nsignificantly less if the frame in question has been through Crop. This\nwill give you the rowsize of a frame for the interleaved formats, or\nthe rowsize of the Y-plane for the planar formats (being the default\nplane).\n::\n\n    const int src_width = src->GetRowSize();\n\n\n.. _cplusplus_getheight:\n\nGetHeight\n^^^^^^^^^\n\n::\n\n    int GetHeight(int plane=0) const;\n\n\nGetHeight gives the height of the plane in pixels.\n\n\n.. _cplusplus_getreadptr:\n\nGetReadPtr\n^^^^^^^^^^\n\n::\n\n    const BYTE* GetReadPtr(int plane=0) const;\n\n\nGetReadPtr gives you a read pointer to a plane. This will give a read\npointer to the default plane:\n::\n\n    PVideoFrame src = child->GetFrame(n, env);\n    const unsigned char* srcp = src->GetReadPtr()\n\n\n.. _cplusplus_getwriteptr:\n\nGetWritePtr\n^^^^^^^^^^^\n\n::\n\n    BYTE* GetWritePtr(int plane=0) const;\n\n\nGetWritePtr gives you a write pointer to a plane.\n\nAny buffer you get from NewVideoFrame is guaranteed to be writable (as\nlong as you only assign it to one PVideoFrame). Our filter's dst came\nfrom NewVideoFrame, so we can safely call dst->GetWritePtr(). However,\nframes you get from other clips via GetFrame may not be writable, in\nwhich case GetWritePtr() will return a null pointer.\n::\n\n    PVideoFrame dst = env->NewVideoFrame(vi);\n    unsigned char* dstp = dst->GetWritePtr();\n\n\nIf you want to write a frame which is not new (the source frame for\nexample), you will have to call MakeWritable first:\n::\n\n    PVideoFrame src = child->GetFrame(n, env);\n    env->MakeWritable(&src);\n    unsigned char* srcp = src->GetWritePtr(PLANAR_Y);\n\n\nSee IsWritable for more details.\n\n\n.. _cplusplus_iswritable:\n\nIsWritable\n^^^^^^^^^^\n\n::\n\n    bool IsWritable() const;\n\n\nAll frame buffers are readable, but not all are writable. This method\ncan be used to find out if a buffer is writable or not, and there's a\nMakeWritable callback (described below) to ensure that it is.\n\nThe rule about writability is this: A buffer is writable if and only if\nthere is exactly one PVideoFrame pointing to it. In other words, you\ncan only write to a buffer if no one else might be reading it. This\nrule guarantees that as long as you hold on to a PVideoFrame and don't\nwrite to it yourself, that frame will remain unchanged. The only\ndrawback is that you can't have two PVideoFrames pointing to a writable\nbuffer.\n\nMakeWritable makes the properties writable as well.\n::\n\n    PVideoFrame src = child->GetFrame(n, env);\n    if (src->IsWritetable()) {...}\n\n\n.. _cplusplus_ispropertywritable:\n\nIsPropertyWritable V9\n^^^^^^^^^^^^^^^^^^^^^\n\n::\n\n    bool IsPropertyWritable() const;\n\n\nAll frame properties connected to frame buffers are readable, but not all are writable.\nThis method can be used to find out if a property set is writable or not.\n\nThe rule about writability is this: A buffer is writable if and only if\nthere is exactly one PVideoFrame pointing to it. In other words, you\ncan only write to a buffer if no one else might be reading it. This\nrule guarantees that as long as you hold on to a PVideoFrame and don't\nwrite to it yourself, that frame will remain unchanged.\n\nSee also :ref:`getFramePropsRW <cplusplus_getframepropsrw>`.\n\n::\n\n    PVideoFrame src = child->GetFrame(n, env);\n    if (!src->IsPropertyWritable())\n      env->MakePropertyWritable(&src);\n    }\n    AVSMap *props = env->getFramePropsRW(dst);\n\n\n.. _cplusplus_getpixeltype:\n\nGetPixelType V10\n^^^^^^^^^^^^^^^^\n\n::\n\n    int GetPixelType() const;\n\n\nSince v10 a Videoframe can store the exact underlying video format in \nVideoFrame::pixel_type. Before, there was no reliable way of knowing it on a \nframe from :ref:`propGetFrame <cplusplus_propgetframe>`.\n\nThe pixel_type is automatically maintained behind the scenes.\n\npixel_type is set on calling :ref:`NewVideoFrame <cplusplus_newvideoframe>` or \n:ref:`NewVideoFrameP <cplusplus_newvideoframep>`, and is kept with\n:ref:`MakeWritable <cplusplus_makewritable>`.\n\nCalling :ref:`SubFrame <cplusplus_subframe>` will automatically convert \nthe format to a single plane greyscale Y8-Y32 from planar origins.\n\nCalling :ref:`SubFramePlanar <cplusplus_subframeplanar>` will strip alpha\nfrom the format specifier.\n\n\n.. _cplusplus_amendpixeltype:\n\nAmendPixelType V10\n^^^^^^^^^^^^^^^^^^\n\n::\n\n    void AmendPixelType(int new_pixel_type);\n\n\nAmendPixelType can be used in special cases, to override the pixel_type.\nE.g. when a filter just overrides the format (VideoInfo::pixel_type) in its constructor\nbut otherwise would return the frame unaltered, this results in an inconsistent\nformat between the actual VideoFrame and VideoInfo.\n(Filters which are now using AmendPixelType are ConvertFromDoubleWidth, ConvertToDoubleWidth,\nConvertBits and CombinePlanes)\n\n\nChanges the color format metadata on this frame. Using it on a frame that isn't\nwritable leads to an inconsistent state, because other filters depend on it.\nSo, use :ref:`MakeWritable <cplusplus_makewritable>` before.\n\n::\n\n    PVideoFrame src = child->GetFrame(n, env);\n    if (format_change_only)\n    {\n      // for 10-16 bit: simple format override in constructor\n      env->MakeWritable(&src);\n      src->AmendPixelType(vi.pixel_type);\n      return src;\n    }\n\n\n.. _cplusplus_alignplanar:\n\nAlignPlanar\n~~~~~~~~~~~\n\n::\n\n    AlignPlanar(PClip _clip);\n\n\nAlignPlanar does nothing, if the pitch of a frame is at least mod16 (16\nbytes, being the default frame alignment for luma and chroma).\nOtherwise it realigns the image, by blitting it to a larger buffer.\n\nFilters can enforce a lower pitch, but they must always apply the\nAlignPlanar filter after itself, if they intend to return a frame with\na lower pitch. VFW delivers a 4 byte alignment for example, so the\nAlignPlanar filters needs to be applied on all frames when using\nAviSource.\n\n\n\n.. _cplusplus_iscriptenvironment:\n\nIScriptEnvironment\n~~~~~~~~~~~~~~~~~~\n\nAviSynth exports an IScriptEnvironment interface. It enables you to use\nAviSynth as a library, without writing an AVS script or without going\nthrough AVIFile. Its members can be called by:\n::\n\n    IScriptEnvironment* env\n    env->Invoke(..)\n\n\nIScriptEnvironment has the following members: ThrowError, GetCPUFlags,\nSaveString, Sprintf, VSprintf, Invoke, BitBlt, AtExit, AddFunction,\nMakeWritable, FunctionExists, GetVar, GetVarDef, SetVar, SetGlobalVar,\nPushContext, PopContext, NewVideoFrame, CheckVersion, Subframe,\nSubframePlanar, SetMemoryMax, SetWorkingDir, DeleteScriptEnvironment\nand ApplyMessage and many others They are described in the following \nsubsections.\n\n\n.. _cplusplus_throwerror:\n\nThrowError\n^^^^^^^^^^\n\n::\n\n    __declspec(noreturn) virtual void __stdcall ThrowError(const char* fmt, ...) = 0;\n\n\nThrowError throws an exception (of type AvisynthError). Usually, your\nerror message will end up being displayed on the user's screen in lieu\nof the video clip they were expecting:\n::\n\n    if (!vi.IsRGB()) {\n        env->ThrowError(\"RGBAdjust requires RGB input\");\n    }\n\n\n.. _cplusplus_getcpuflags:\n.. _cplusplus_getcpuflagsex:\n\nGetCPUFlags\n^^^^^^^^^^^\nGetCPUFlagsEx (v12)\n^^^^^^^^^^^^^^^^^^^\n\n::\n\n    virtual int GetCPUFlags();\n    virtual int64_t GetCPUFlagsEx();\n\n\nGetCPUFlagsEx (and the old GetCPUFlags) returns the instruction set of your CPU. \nInterface V12 introduced the Ex version which returns 64 bit flags.\nReason: the many Intel AVX512 subfeatures did not fit in the 32 bits int returned by the original function.\n\n** Intel architecture flags: **\n\nThough individual AVX512 features can be tested, the recommended way is to\ntest for group of features. Avisynth supports the following AVX512 group feature flags:\nCPUF_AVX512_BASE, CPUF_AVX512_FAST, and later probably: CPUF_AVX10 with version>=2.\n\nThe GetCPUFlags() - the old 32 bit version - is still usable up to AVX512_FAST group feature set.\nOther future group features and individual flags will only be available through GetCPUFlagsEx.\n\nFor features up to AVX2 and some AVX512 exensions, both functions return the same flags.\n\nTo find out if you're running for example on a CPU that supports AVX2, test:\n::\n\n    env->GetCPUFlags() & CPUF_AVX2\n\nTo test against the default Avisynth+ \"fast\" flags, test:\n::\n\n    if ((env->GetCPUFlags() & CPUF_AVX512_FAST) == CPUF_AVX512_FAST) {\n        // all \"fast\" AVX512 features supported (in AviSynth: *_avx512.cpp)\n        // function dispatch here\n    } else if ((env->GetCPUFlags() & CPUF_AVX512_BASE) == CPUF_AVX512_BASE)) {\n        // \"base\" AVX512 features supported (in AviSynth: *_avx512b.cpp)\n        // function dispatch here\n    } else if (env->GetCPUFlags() & CPUF_AVX2) {\n        // AVX2 path\n    } else if (env->GetCPUFlags() & CPUF_SSE2) {\n        // SSE2 path\n    } else {\n        // simple C++ path\n    }\n\nIn Avisynth AVX512 function dispatchers check for CPUF_AVX512_BASE and CPUF_AVX512_FAST for calling function from \n``*_avx512b.cpp`` or ``*_avx512.cpp`` files, repectively.\n\nCompiler flags for ``*_avx512b.cpp`` and ``*_avx512.cpp`` files are automatically set for MSVC as ``/arch:AVX512``.\n\nFor gcc or LLVM (clang-cl) builds the relevant flags in CMakeLists.txt are set as\n\n* \"Base\" (``*_avx512b.cpp``) : ``\" -mfma -mbmi2 -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl \"``\n* \"Fast\" (``*_avx512.cpp``) : ``\" -mfma -mbmi2 -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl -mavx512vnni -mavx512vbmi -mavx512vbmi2 -mavx512bitalg -mavx512vpopcntdq \"``\n\nSimilar to AVX2, FMA must be added explicitly for GCC/Clang. We also enable BMI2, as it is standard since AVX2 and useful for \nAVX512 mask operations like _bzhi_u64/u32. The core subsets (F, CD, BW, DQ, VL) comprising the CPUF_AVX512_BASE \nflag are present on all AVX-512-capable architectures.\n\nWe note again: early Xeon (e.g., Skylake-X/Cascadelake) may exhibit severe thermal throttling even on a single thread. \nIn AviSynth+, AVX512_BASE must be manually enabled in-script unless ``CPUF_AVX512_FAST`` is also detected.\nFunctions in ``*_avx512b.cpp`` should be dispatched on ``CPUF_AVX512_BASE``.\nFunctions in ``*_avx512.cpp`` should be dispatched on ``CPUF_AVX512_FAST``.\n\nAVX512 is considered to be \"Fast\" when either \n\n- pre AVX10, and minimum Ice Lake architecture is found (VNNI, VBMI, VBMI2, BITALG, VPOPCNTDQ and three crypto flags).\n- or AVX10 (any version) is found.\n\nIce Lake and AVX10 common flags are: VNNI, VBMI, VBMI2, BITALG, VPOPCNTDQ; this is what you can expect from CPUF_AVX512_FAST feature flag.\n\n** Aarch64 architecture flags: **\n\nSee :ref:`Aarch64 (ARM64) SIMD tiers<aarch64_simd_tiers>` for details about ARMv8/v9 CPU feature flags.\n\n\n\nThere's a complete list of flags in ``avs/cpuid.h`` (C++) or in ``avisynth_c.h`` (C).\n\nSee also :ref:`CPU Feature Flags<cplusplus_cpufeatureflags>`.\n\n\n.. _cplusplus_savestring:\n\nSaveString\n^^^^^^^^^^\n\n::\n\n    virtual char* SaveString(const char* s, int length = -1);\n\n\nThis function copies its argument to a safe \"permanent\" location and\nreturns a pointer to the new location. Each ScriptEnvironment instance\nhas a buffer set aside for storing strings, which is expanded as\nneeded. The strings are not deleted until the ScriptEnvironment\ninstance goes away (when the script file is closed, usually). This is\nusually all the permanence that is needed, since all related filter\ninstances will already be gone by then.\n\nThough the returned pointer is not const-qualified, don't overwrite the buffer,\ndue to the string cacheing introduced after Avisynth 3.7.3. \n\nUntil Avisynth 3.7.3 you could safely do this, the documentation said:\n\"you're welcome to write to it, as long as you don't stray beyond the \nbounds of the string.\"\n\nThis (formerly valid) example usage is no longer safe (converting a string to upper case)\nand was replaced in Avisynth core:\n::\n\n    AVSValue UCase(AVSValue args, void*, IScriptEnvironment* env) {\n        return _strupr(env->SaveString(args[0].AsString()));\n    }\n\n\n.. _cplusplus_sprintf_vsprintf:\n\nSprintf and VSprintf\n^^^^^^^^^^^^^^^^^^^^\n\n::\n\n    virtual char* Sprintf(const char* fmt, ...);\n    virtual char* VSprintf(const char* fmt, char* val);\n\n\nThese store strings away in the same way as SaveString, but they treat\ntheir arguments like printf and vprintf. Currently there's a size limit\nof 4096 characters on strings created this way. (The implementation\nuses _vsnprintf, so you don't need to worry about buffer overrun.)\n\n\n.. _cplusplus_invoke:\n\nInvoke\n^^^^^^\n\n::\n\n    virtual AVSValue Invoke(const char* name, const AVSValue args, const char** arg_names=0);\n\n\nYou can use this to call a script function. There are many script\nfunctions which can be useful from other filters; for example, the Bob\nfilter uses SeparateFields, and several source filters use\nUnalignedSplice. Some functions, like Weave, are implemented entirely\nin terms of other functions. If you're calling a function taking\nexactly one argument, you can simply pass it in the args parameter;\nInvoke will convert it into an array for you. In order to call a\nfunction taking multiple arguments, you will need to create the array\nyourself; it can be done like this:\n::\n\n    AVSValue up_args[3] = {child, 384, 288};\n    PClip resized = env->Invoke(\"LanczosResize\", AVSValue(up_args,3)).AsClip();\n\n\nIn this case LanczosResize would need to have a parameter-type string\nlike \"cii\".\n\nThe arg_names parameter can be used to specify named arguments. Named\narguments can also be given positionally, if you prefer.\n\nInvoke throws IScriptEnvironment::NotFound if it can't find a matching\nfunction prototype. You should be prepared to catch this unless you\nknow that the function exists and will accept the given arguments.\n\n\n.. _cplusplus_bitblt:\n\nBitBlt\n^^^^^^\n\n::\n\n    virtual void BitBlt(unsigned char* dstp, int dst_pitch, const unsigned char* srcp, int src_pitch, int row_size, int height);\n\n\nThis brilliantly-named function does a line-by-line copy from the\nsource to the destination. It's useful for quite a number of things;\nthe built-in filters DoubleWeave, FlipVertical, AddBorders,\nPeculiarBlend, StackVertical, StackHorizontal, and ShowFiveVersions all\nuse it to do their dirty work.\n\nIn AddBorders it's to copy the Y-plane from the source to the\ndestination frame (for planar formats):\n::\n\n    const int initial_black = top*dst_pitch + vi.BytesFromPixels(left);\n    if (vi.IsPlanar()) {\n        BitBlt(dstp+initial_black, dst_pitch, srcp, src_pitch, src_row_size, src_height);\n        ...\n    }\n\n\nleft is the number of pixels which is added to the left, top the number\nwhich is added to the top. So the first source pixel, srcp[0], is\ncopied to its new location dstp[x], and so on. The remaining bytes are\nzeroed and can be refilled later on.\n\n\n.. _cplusplus_atexit:\n\nAtExit\n^^^^^^\n\n::\n\n    virtual void AtExit(ShutdownFunc function, void* user_data);\n\n\nWhen IScriptEnvironment is deleted on script close the AtExit functions\nget run. When you register the function you can optionally provide some\nuser data. When the function is finally called this data will be\nprovided as the argument to the procedure.\n\nThe example below (thanks to tsp) loads a library and automatically\nunloads it (by using AtExit) after the script is closed. It can be\nuseful when your plugin depends on a library and you want to load the\nlibrary in your script (the plugin fft3dfilter.dll depends on the\nlibrary fftw3.dll for example):\n::\n\n    void __cdecl UnloadDll(void* hinst, IScriptEnvironment* env) {\n        if (hinst)\n        FreeLibrary(static_cast<HMODULE>(hinst));\n    }\n\n    AVSValue __cdecl LoadDll(AVSValue args, void* user_data, IScriptEnvironment* env){\n        HMODULE hinst = 0;\n        hinst = LoadLibrary(args[0].AsString()); // loads a library\n        env->AtExit(UnloadDll, hinst); // calls UnloadDll to unload the library upon script exit\n        return hinst!=NULL;\n    }\n\n\n.. _cplusplus_addfunction:\n\nAddFunction\n^^^^^^^^^^^\n\n::\n\n    virtual void __stdcall AddFunction(const char* name, const char* params, ApplyFunc apply, void* user_data) = 0;\n\n\nThe main purpose of the AvisynthPluginInit2 (or AvisynthPluginInit3)\nfunction is to call env->AddFunction.\n::\n\n    env->AddFunction(\"Sepia\", \"c[color]i[mode]s\", Create_Sepia, 0);\n\n\nAddFunction is called to let Avisynth know of the existence of our\nfilter. It just registers a function with Avisynth's internal function\ntable. This function takes four arguments: the name of the new script\nfunction; the parameter-type string; the C++ function implementing the\nscript function; and the user_data cookie.\n\nThe added function is of type AVSValue and can therefore return any\nAVSValue. Here are a few options how to return from the \"added\"\nfunction:\n::\n\n    AVSValue __cdecl returnSomething(AVSValue args, void* user_data, IScriptEnvironment* env){\n\n    char *strlit = \"AnyOldName\";\n    int len = strlen(strlit);\n    char *s = new char[len+1];\n\n    if (s==NULL)\n        env->ThrowError(\"Cannot allocate string mem\");\n\n    strcpy(s, strlit); // duplicate\n    char *e = s+len; // point at null\n\n    // make safe copy of string (memory is freed on Avisynth closure)\n    AVSValue ret = env->SaveString(s,e-s); // e-s is text len only (excl null) {SaveString uses memcpy)\n\n    // alternative, Avisynth uses strlen to ascertain length\n    // AVSValue ret = env->SaveString(s);\n\n    delete []s; // delete our temp s buffer\n    return ret; // return saved string as AVSValue\n\n    // alternative to MOST of above code char* converted to AVSValue.\n    // return strlit;\n\n    // alternative to ALL of above code char* converted to AVSValue.\n    // return \"AnyOldName\";\n\n    // String literals are read only and at constant address and so need not be saved.\n    }\n\nsee also :ref:`c_avs_add_function` and :ref:`c_avs_add_function_r` in C API\n\n\n.. _cplusplus_makewritable:\n\nMakeWritable\n^^^^^^^^^^^^\n\n::\n\n    virtual bool __stdcall MakeWritable(PVideoFrame* pvf) = 0;\n\n\nMakeWritable only copies the active part of the frame to a completely\nnew frame with a default pitch. You need this to recieve a valid write\npointer to an existing frame.\n::\n\n    PVideoFrame src = child->GetFrame(n, env);\n    env->MakeWritable(&src);\n\n\n.. _cplusplus_functionexists:\n\nFunctionExists\n^^^^^^^^^^^^^^\n\n::\n\n    virtual bool __stdcall FunctionExists(const char* name) = 0;\n\n\nFunctionExists returns true if the specified filter exists, otherwise\nreturns false:\n::\n\n    if (env->FunctionExists(\"Import\")) {\n        env->ThrowError(\"Yes, the IMPORT function exist.\");\n    } else {\n        env->ThrowError(\"No, the IMPORT function don't exist.\");\n    }\n\n\n.. _cplusplus_getvar:\n\nGetVar\n^^^^^^\n\n::\n\n    virtual AVSValue __stdcall GetVar(const char* name) = 0;\n\n\nGetVar can be used to access AviSynth variables. It will throw an error\nif the variable doesn't exist.\n\nInternal and external (plugin) functions are, for example, exported as\nAviSynth variables:\n\n* $InternalFunctions$ Should contain a string consisting of function\n  names of all internal functions.\n* $InternalFunctions!Functionname!Param$ Should contain all\n  parameters for each internal function.\n* $PluginFunctions$ Should contain a string of all plugins in your\n  autoloading plugin folder.\n* $Plugin!Functionname!Param$ Should contain all parameters.\n\nUse env->GetVar() to access them. This example returns a string\nconsisting of all parameters of ConvertToYV12:\n::\n\n    const char* plugin_dir;\n    plugin_dir = env->GetVar(\"$Plugin!ConverttoYV12!Param$\").AsString();\n\n\nThis example returns the plugin folder which is used to autoload your\nplugins (and returns an error if it's not set):\n::\n\n    try {\n        const char* plugin_dir;\n        plugin_dir = env->GetVar(\"$PluginDir$\").AsString();\n        env->ThrowError(plugin_dir);\n    } catch(...) {\n        env->ThrowError(\"Plugin directory not set.\");\n    }\n\n\nIf you are making a conditional filter you can use it to get the\ncurrent framenumber:\n::\n\n    // Get current frame number\n    AVSValue cf = env->GetVar(\"current_frame\");\n    if (!cf.IsInt())\n        env->ThrowError(\"MinMaxAudio: This filter can only be used within ConditionalFilter\");\n    int n = cf.AsInt();\n    PVideoFrame src = child->GetFrame(n, env);\n\n\n.. _cplusplus_getvardef:\n\nGetVarDef, v6\n^^^^^^^^^^^^^\n\n::\n\n    virtual AVSValue __stdcall GetVarDef(const char* name, const AVSValue& def=AVSValue()) = 0;\n\n\nGetVarDef can be used to access AviSynth variables. It will return\n'def' if the variable doesn't exist (instead of throwing an error):\n::\n\n    int error;\n    AVSValue error = env->GetVarDef(\"VarUnknown\", AVSValue(-1)); // returns -1 when 'VarUnknown' doesn't exist\n    if (error==-1)\n        env->ThrowError(\"Plugin: The variable 'VarUnknown' doesn't exist!\");\n\n\n.. _cplusplus_setvar:\n\nSetVar\n^^^^^^\n\n::\n\n    virtual bool __stdcall SetVar(const char* name, const AVSValue& val) = 0;\n\n\nIt will return true if the variable was created and filled with the\ngiven value. It will return false in case the variable was already\nthere and we just updated its value.\n\nSetVar can be used to set/create AviSynth variables. The created\nvariables are only visible in the local scope, e.g. script functions\nhave a new scope.\n\nThis example sets the autoloading plugin folder to ``\"C:\\\\\"``\n::\n\n    if (env->SetVar(\"$PluginDir$\", AVSValue(\"C:\\\\\"))) {\n        //variable was created\n    } else {\n        //variable was already existing and updated\n    }\n\n\nThis example sets variables in GetFrame which can be accessed later on\nin a script within the conditional environment:\n::\n\n    // saves the blue value of a pixel\n    int BlueValue;\n    BlueValue = srcp[x];\n    env->SetVar(\"BlueValue\", AVSValue(BlueValue));\n\n\n.. _cplusplus_setglobalvar:\n\nSetGlobalVar\n^^^^^^^^^^^^\n\n::\n\n    virtual bool __stdcall SetGlobalVar(const char* name, const AVSValue& val) = 0;\n\n\nUsage:\n\nSetGlobalVar can be used to create or set AviSynth variables that are\nvisible within global scope. It is possible that a single filter may\nwant to use SetVar in order to exchange signals to possible other\ninstances of itself.\n\nThere are at least 4 different components that make use of\nSet(Global)Var functions:\n\n* the core itself\n* the user within the avs script\n* filters/plugins\n* a custom application that invoked the environment\n\nAll of above may have their own requirements for the SetVar function.\nSome may want to be visible globally, others may not.\n\n\n.. _cplusplus_pushcontext:\n\nPushContext\n^^^^^^^^^^^\n\n::\n\n    virtual void __stdcall PushContext(int level=0) = 0;\n\nUsage:\n\nPushContext and PopContext are used to implement local script function\nname space contexts. A plugin could use these to create a new local name \nspace before Invoke'ing or Eval'ing script expressions in order to avoid \nclashes with similarly named variables in the calling script.\n\nPushContext() and PopContext() should always be used in matched pairs, and \nthe code region of interest be try/catch protected with a PopContext() in \nthe catch case.\n\nExample from ``ScriptFunction::Execute``:\n::\n\n    env->PushContext();\n    for (int i=0; i<args.ArraySize(); ++i)\n      env->SetVar(self->param_names[i], // Force float args that are actually int to be float\n        (self->param_floats[i] && args[i].IsInt()) ? float(args[i].AsInt()) : args[i]);\n    AVSValue result;\n    try {\n      result = self->body->Evaluate(env);\n    }\n    catch (...) {\n      env->PopContext();\n      throw;\n    }\n    env->PopContext();\n\n| // TODO - see (also similar functions)\n| http://forum.doom9.org/showthread.php?p=1595750#post1595750\n\n\n.. _cplusplus_popcontext:\n\nPopContext\n^^^^^^^^^^\n\n::\n\n    virtual void __stdcall PopContext() = 0;\n\nUsage:\n\nSee PopContext\n\n\n.. _cplusplus_newvideoframe:\n\nNewVideoFrame\n^^^^^^^^^^^^^\n\n::\n\n    virtual PVideoFrame __stdcall NewVideoFrame(const VideoInfo& vi, int align=FRAME_ALIGN) = 0;\n    // default align is 16\n\nSee also :ref:`NewVideoFrameP <cplusplus_newvideoframep>`.\n\nThe NewVideoFrame callback allocates space for a video frame of the\nsupplied size. (In this case it will hold our filter's output.) The\nframe buffer is uninitialized raw memory (except that in the debug\nbuild it gets filled with the repeating byte pattern 0A 11 0C A7 ED,\nwhich is easy to recognize because it looks like \"ALLOCATED\"). \"vi\" is\na protected member of GenericVideoFilter. It is a structure of type\nVideoInfo, which contains information about the clip (like frame size,\nframe rate, pixel format, audio sample rate, etc.). NewVideoFrame uses\nthe information in this structure to return a frame buffer of the\nappropriate size.\n\nThe following example creates a new VideoInfo structure and creates a\nnew video frame from it:\n::\n\n    VideoInfo vi;\n    PVideoFrame frame;\n    memset(&vi, 0, sizeof(VideoInfo));\n    vi.width = 640;\n    vi.height = 480;\n    vi.fps_numerator = 30000;\n    vi.fps_denominator = 1001;\n    vi.num_frames = 107892; // 1 hour\n    vi.pixel_type = VideoInfo::CS_BGR32;\n    vi.sample_type = SAMPLE_FLOAT;\n    vi.nchannels = 2;\n    vi.audio_samples_per_second = 48000;\n    vi.num_audio_samples = vi.AudioSamplesFromFrames(vi.num_frames);\n    frame = env->NewVideoFrame(vi);\n\n\n\n.. _cplusplus_checkversion:\n\nCheckVersion\n^^^^^^^^^^^^\n\n::\n\n    virtual void __stdcall CheckVersion(int version = AVISYNTH_INTERFACE_VERSION) = 0;\n\n\nCheckVersion checks the interface version (avisynth.h). It throws an\nerror if 'version' is bigger than the used interface version. The\nfollowing interface versions are in use:\n\nAVISYNTH_INTERFACE_VERSION = 1 (v1.0-v2.0.8), 2 (v2.5.0-v2.5.5), 3\n(v2.5.6-v2.5.8), 5 (v2.6.0a1-v2.6.0a5), 6 (v2.6.0), 8 (Avisynth+) from a specific build [version 4 doesn't exist].\n\nThis example will throw an error if v2.5x or an older AviSynth version\nis being used:\n::\n\n    env->CheckVersion(5)\n\n\nThis can be used in a plugin, for example, if it needs at least a\ncertain interface version for it to work.\n\nInterface V9 (8.1) introduced new methods for establishing actual interface version both on C++ and C interfaces.\nSee :ref:`GetEnvProperty <cplusplus_getenvproperty>`\n\nInterface V9.1 introduced important fixes for C interface methods: avs_new_video_frame_p(_a), avs_prop_get_data\n\nInterface V12 introduced global locks, GetCPUFlagsEx, query L2 cache size\n\n::\n\n    Example of usage with CPP interface (through avisynth.h).\n\n    IScriptEnvironment *env = ...\n    avisynth_if_ver = 6; // guessed minimum\n    avisynth_bugfix_ver = 0;\n    try { env->CheckVersion(8); avisynth_if_ver = 8; }\n    catch (const AvisynthError&) {}\n    try { \n      env->CheckVersion(9); // if this works, we are at least V9, can use GetEnvProperty with AEP_INTERFACE_VERSION\n      avisynth_if_ver = env->GetEnvProperty(AEP_INTERFACE_VERSION); // only since V9!\n      avisynth_bugfix_ver = env->GetEnvProperty(AEP_INTERFACE_BUGFIX);      \n    } \n    catch (const AvisynthError&) {}\n    \n    has_at_least_v8 = avisynth_if_ver >= 8; // frame properties, NewVideoFrameP, other V8 environment functions\n    has_at_least_v8_1 = avisynth_if_ver > 8 || (avisynth_if_ver == 8 && avisynth_bugfix_ver >= 1);\n    // 8.1: C interface frameprop access fixed, IsPropertyWritable/MakePropertyWritable support, extended GetEnvProperty queries\n    has_at_least_v9 = avisynth_if_ver >= 9; // future\n    has_at_least_v9_1 = avisynth_if_ver > 9 || (avisynth_if_ver == 9 && avisynth_bugfix_ver >= 1);\n    // 9.1: C interface fixes: avs_new_video_frame_p(_a), avs_prop_get_data\n    has_at_least_v12 = avisynth_if_ver >= 12; // global locks, GetCPUFlagsEx, query L2 cache size\n    \n\n.. _cplusplus_subframe:\n\nSubframe\n^^^^^^^^\n\n::\n\n    virtual PVideoFrame __stdcall Subframe(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height) = 0;\n\n\nSubframe (for interleaved formats) extracts a part of a video frame.\nFor planar formats use SubframePlanar. For examples see SubframePlanar.\n\n\n.. _cplusplus_subframeplanar:\n\nSubframePlanar\n^^^^^^^^^^^^^^\n\n::\n\n    virtual PVideoFrame __stdcall SubframePlanar(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV) = 0;\n\n\nSubframePlanar (for planar formats) extracts a part of a video frame.\nThe example below returns the first field of a frame:\n::\n\n    vi.height >>= 1; // sets new height in the constructor\n    PVideoFrame frame = child->GetFrame(n, env);\n    if (vi.IsPlanar()) { // SubframePlanar works on planar formats only\n        const int frame_pitch = frame->GetPitch(PLANAR_Y);\n        const int frame_width = frame->GetRowSize(PLANAR_Y);\n        const int frame_height = frame->GetHeight(PLANAR_Y);\n        const int frame_pitchUV = frame->GetPitch(PLANAR_U);\n        return env->SubframePlanar(frame, 0, 2*frame_pitch, frame_width, frame_height>>1, 0, 0, 2*frame_pitchUV);\n    }\n\n\nNote that it copies the first row of pixels and moves on to the third\nrow (by moving the offset by '2*frame_pitch'). After frame_height/2 it\nstops reading.\n\nThe following example keeps the left 100 pixels of a clip (it leaves\nthe height unaltered) and throws away the rest:\n::\n\n    vi.width = 100; // sets new width in the constructor\n    PVideoFrame frame = child->GetFrame(n, env);\n    if (vi.IsPlanar()) { // SubframePlanar works on planar formats only\n        const int frame_pitch = frame->GetPitch(PLANAR_Y);\n        const int frame_height = frame->GetHeight(PLANAR_Y);\n        const int frame_pitchUV = frame->GetPitch(PLANAR_U);\n        return env->SubframePlanar(frame, 0, frame_pitch, 100, frame_height, 0, 0, frame_pitchUV);\n    }\n\n\nNote that it copies 100 pixels and moves on to the next row (by moving\nthe offset by 'frame_pitch').\n\nYou need to check somewhere that the source frames is more than 100\npixels wide, otherwise throw an error.\n\n\n.. _cplusplus_setmemorymax:\n\nSetMemoryMax\n^^^^^^^^^^^^\n\n::\n\n    virtual int __stdcall SetMemoryMax(int mem) = 0;\n\n\nThere is a builtin cache automatically inserted in between all filters.\nYou can use SetmemoryMax to increase the size.\n\nSetMemoryMax only sets the size of the frame buffer cache. It is\nindependent of any other memory allocation. Memory usage due to the\nframe cache should ramp up pretty quickly to the limited value and stay\nthere. Setting a lower SetMemoryMax value will make more memory\navailable for other purposes and provide less cache buffer frames. It\nis pointless having more buffers available than are needed by the\nscripts temporal requirements. If each and every frame generated at\neach and every stage of a script is only ever used once then the cache\nis entirely useless. By definition a cache is only useful if a\ngenerated element is needed a second or subsequent time.\n\n\n.. _cplusplus_setworkingdir:\n\nSetWorkingDir\n^^^^^^^^^^^^^\n\n::\n\n    virtual int __stdcall SetWorkingDir(const char * newdir) = 0;\n\n\nSets the default directory for AviSynth.\n\n\n.. _cplusplus_deletescriptenvironment:\n\nDeleteScriptEnvironment, v5\n^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n::\n\n    virtual void __stdcall DeleteScriptEnvironment() = 0;\n\n\nProvides a method to delete the ScriptEnvironment which is created with\nCreateScriptEnvironment. End of the world, end of everything. AtExit procedures are \ncalled during the destroy as a side effect.\n\n\n.. _cplusplus_applymessage:\n\nApplyMessage, v5\n^^^^^^^^^^^^^^^^\nApplyMessageEx, v12\n^^^^^^^^^^^^^^^^^^^\n\n::\n\n    virtual void _stdcall ApplyMessage(PVideoFrame* frame, const VideoInfo& vi, const char* message, int size, int textcolor, int halocolor, int bgcolor) = 0;\n    virtual void _stdcall ApplyMessageEx(PVideoFrame* frame, const VideoInfo& vi, const char* message, int size, int textcolor, int halocolor, int bgcolor, bool utf8) = 0;\n\n\nApplyMessage writes text on a frame. For example:\n::\n\n    char BUF[256];\n    PVideoFrame src = child->GetFrame(n, env);\n    env->MakeWritable(&src);\n    sprintf(BUF, \"Filter: Frame %d is processed.\", n);\n    env->ApplyMessage(&src, vi, BUF, vi.width/4, 0xf0f080, 0, 0);\n\n\nWith ApplyMessageEx you can use UTF-8 encoded strings on Windows ANSI code pages. On Posix, or on Windows set to \"utf8 (beta)\" everything is UTF-8 already.\n\n\n.. _cplusplus_getavslinkage:\n\nGetAVSLinkage, v5\n^^^^^^^^^^^^^^^^^\n\n::\n\n    virtual const AVS_Linkage* const __stdcall GetAVSLinkage() = 0;\n\nReturns the :doc:`AVSLinkage <AVSLinkage>`.\n\ntodo: how and when to use that ...\n\n\n.. _cplusplus_subframeplanara:\n\nSubframePlanarA, v8\n^^^^^^^^^^^^^^^^^^^\n\n::\n\n    virtual PVideoFrame __stdcall SubframePlanarA(PVideoFrame src, int rel_offset, int new_pitch, int new_row_size, int new_height, int rel_offsetU, int rel_offsetV, int new_pitchUV, int rel_offsetA) = 0;\n\nAlpha plane aware version of SubframePlanar.\n\n\n.. _cplusplus_copyframeprops:\n\ncopyFrameProps, v8\n^^^^^^^^^^^^^^^^^^\n\n::\n\n    virtual void __stdcall copyFrameProps(const PVideoFrame& src, PVideoFrame& dst) = 0;\n\ncopy frame properties between video frames.\n\n\n.. _cplusplus_getframepropsro:\n\ngetFramePropsRO, v8\n^^^^^^^^^^^^^^^^^^^\n\n::\n\n    virtual const AVSMap* __stdcall getFramePropsRO(const PVideoFrame& frame) = 0;\n\nget pointer for reading frame properties\n\n\n.. _cplusplus_getframePropsrw:\n\ngetFramePropsRW, v8\n^^^^^^^^^^^^^^^^^^^\n\n::\n\n    virtual AVSMap* __stdcall getFramePropsRW(PVideoFrame& frame) = 0;\n\nget pointer for reading/writing frame properties.\n\nImportant note: a frame property set is safely writable if\n\n- frame is just obtained with NewVideoFrame\n- frame is obtained with SubFrame, SubFramePlanar or SubFramePlanarA\n- env->MakeWritable is used\n- or env->MakePropertyWritable is used\n\nMakePropertyWritable (v9) vs MakeWritable: MakePropertyWritable does not make\na full copy of video buffer content, just re-references the frame (internally\nis working like SubFramePlanarA)\n\n.. _cplusplus_propnumkeys:\n\npropNumKeys, v8\n^^^^^^^^^^^^^^^\n\n::\n\n    virtual int __stdcall propNumKeys(const AVSMap* map) = 0;\n\n get number of frame properties for a frame.\n\n\n.. _cplusplus_propgetkey:\n\npropGetKey, v8\n^^^^^^^^^^^^^^\n\n::\n\n    virtual const char* __stdcall propGetKey(const AVSMap* map, int index) = 0;\n\n get name of key by index.\n\n\n.. _cplusplus_propnumelements:\n\npropNumElements, v8\n^^^^^^^^^^^^^^^^^^^\n\n::\n\n    virtual int __stdcall propNumElements(const AVSMap* map, const char* key) = 0;\n\nget array size of a property\n\n\n.. _cplusplus_propGetType:\n\npropGetType, v8\n^^^^^^^^^^^^^^^\n\n::\n\n    virtual char __stdcall propGetType(const AVSMap* map, const char* key) = 0;\n\nget property data type.\n\n::\n\n    // enums for frame property types\n    enum AVSPropTypes {\n      PROPTYPE_UNSET = 'u', // ptUnset\n      PROPTYPE_INT = 'i', // peType\n      PROPTYPE_FLOAT = 'f', // ptFloat\n      PROPTYPE_DATA = 's', // ptData\n      PROPTYPE_CLIP = 'c', // ptClip\n      PROPTYPE_FRAME = 'v' // ptFrame\n      //  ptFunction = 'm'\n    };\n\n\n.. _cplusplus_propgetint:\n\npropGetInt, v8\n^^^^^^^^^^^^^^\n\n::\n\n    virtual int64_t __stdcall propGetInt(const AVSMap* map, const char* key, int index, int* error) = 0;\n\nget property value as integer (int64).\nYou can pass nullptr to error, but if given, the following error codes are set (0 = O.K.)\nThough AVSValue in Avisynth does not support int64_t (as of December 2021), you can freely\nuse int64_t frame property values in plugins. Internally there is no special 32 bit integer\nversion, only 64 bit integer exists.\n\nPossible error codes defined in Avisynth.h:\n\n::\n\n  enum AVSGetPropErrors {\n    GETPROPERROR_SUCCESS = 0,\n    GETPROPERROR_UNSET = 1, // peUnset\n    GETPROPERROR_TYPE = 2, // peType\n    GETPROPERROR_ERROR = 3, // map has error state set\n    GETPROPERROR_INDEX = 4 // peIndex\n  };\n\n.. _cplusplus_propgetintsaturated:\n\npropGetIntSaturated, v11\n^^^^^^^^^^^^^^^^^^^^^^^^\n\n::\n\n    virtual int __stdcall propGetIntSaturated(const AVSMap* map, const char* key, int index, int* error) = 0;\n\nget property value as integer (and _not_ int64).\n\nThe same as propGetInt, but clamps the underlying int64 values to valid integer ranges.\n\nBackported from VapourSynth API 4.\n\n\n.. _cplusplus_propgetfloat:\n\npropGetFloat, v8\n^^^^^^^^^^^^^^^^\n\n::\n\n    virtual double __stdcall propGetFloat(const AVSMap* map, const char* key, int index, int* error) = 0;\n\nGet property value as float (double).\nNo special 32 bit float is handled for frame properties, only 64 bit double,\nbut from v11 the value can be requested in float, see propGetFloatSaturated.\n\n\n.. _cplusplus_propgetfloatsaturated:\n\npropGetFloatSaturated, v11\n^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n::\n\n    virtual float __stdcall propGetFloatSaturated(const AVSMap* map, const char* key, int index, int* error) = 0;\n\nGet property value as float (and _not_ double).\n\nThe same as propGetFloat, but clamps the underlying double value to valid 32 bit float range.\n\nBackported from VapourSynth API 4.\n\n\n.. _cplusplus_propgetdata:\n\npropGetData, v8\n^^^^^^^^^^^^^^^\n\n::\n\n    virtual const char* __stdcall propGetData(const AVSMap* map, const char* key, int index, int* error) = 0;\n\nget property value as string buffer.\n\nNote: C interface counterpart avs_prop_get_data behaviour was fixed and made similar to C++ propGetData in interface version 9.1\n\n\n.. _cplusplus_propgetdatasize:\n\npropGetDataSize, v8\n^^^^^^^^^^^^^^^^^^^\n\n::\n\n    virtual int __stdcall propGetDataSize(const AVSMap* map, const char* key, int index, int* error) = 0;\n\nget string/data buffer size.\nString length is without the terminating 0.\n\n.. _cplusplus_propgetdatatypehint:\n\npropGetDataTypeHint, v11\n^^^^^^^^^^^^^^^^^^^^^^^^\n\n::\n\n    virtual int __stdcall propGetDataTypeHint(const AVSMap* map, const char* key, int index, int* error) = 0;\n\nget string/data type, given by a hint earlier.\n\nThe result is one of AVSPropDataTypeHint enums: unknown, binary or string data.\n\nBackported from VapourSynth API4: VSDataTypeHint\n\n.. _cplusplus_propgetclip:\n\npropGetClip, v8\n^^^^^^^^^^^^^^^\n\n::\n\n    virtual PClip __stdcall propGetClip(const AVSMap* map, const char* key, int index, int* error) = 0;\n\nget property value as Clip.\n\n\n.. _cplusplus_propgetframe:\n\npropGetFrame, v8\n^^^^^^^^^^^^^^^^\n\n::\n\n    virtual const PVideoFrame __stdcall propGetFrame(const AVSMap* map, const char* key, int index, int* error) = 0;\n\nget property value as Frame.\n\n\n.. _cplusplus_propdeletekey:\n\npropDeleteKey, v8\n^^^^^^^^^^^^^^^^^\n\n::\n\n    virtual int __stdcall propDeleteKey(AVSMap* map, const char* key) = 0;\n\nremoves a frame property by name (key).\n\n\n.. _cplusplus_propsetint:\n\npropSetInt, v8\n^^^^^^^^^^^^^^\n\n::\n\n    virtual int __stdcall propSetInt(AVSMap* map, const char* key, int64_t i, int append) = 0;\n\nsets integer (int64) frame property.\nIn setter function the append parameter rules that the key is replaced if exists, added otherwise (PROPAPPENDMODE_REPLACE).\nFor populating an array use PROPAPPENDMODE_APPEND. For just creating the key use PROPAPPENDMODE_TOUCH.\n\n::\n\n  enum AVSPropAppendMode {\n    PROPAPPENDMODE_REPLACE = 0, // paReplace\n    PROPAPPENDMODE_APPEND = 1, // paAppend\n    PROPAPPENDMODE_TOUCH = 2 // paTouch\n  };\n\n\n.. _cplusplus_propsetfloat:\n\npropSetFloat, v8\n^^^^^^^^^^^^^^^^\n\n::\n\n    virtual int __stdcall propSetFloat(AVSMap* map, const char* key, double d, int append) = 0;\n\nsets float (double) frame property.\n\n\n.. _cplusplus_propsetdata:\n\npropSetData, v8\n^^^^^^^^^^^^^^^\n\n::\n\n    virtual int __stdcall propSetData(AVSMap* map, const char* key, const char* d, int length, int append) = 0;\n\nsets string (byte buffer) frame property.\n\nUse propSetDataH instead, available from v11 (3.7.4). \n\n\n.. _cplusplus_propsetdatah:\n\npropSetDataH, v11\n^^^^^^^^^^^^^^^^^\n\n::\n\n    virtual int __stdcall propSetDataH(AVSMap* map, const char* key, const char* d, \n                                       int length, int type, int append) = 0;\n\nsets string (byte buffer) frame property along with a type hint: binary or string. \nHint is then used as display (propShow) or serialization (to json) helper.\n\nFor type hints see AvsPropDataTypeHint enum:\n::\n\n  enum AVSPropDataTypeHint {\n    PROPDATATYPEHINT_UNKNOWN = -1, // dtUnknown = -1,\n    PROPDATATYPEHINT_BINARY = 0, // dtBinary = 0,\n    PROPDATATYPEHINT_UTF8 = 1 // dtUtf8 = 1\n  };\n\nBackported from VapourSynth API4: ``mapSetData`` (their API however defines the hintless version as ``mapSetData3``)\n\n.. _cplusplus_propsetclip:\n\npropSetClip, v8\n^^^^^^^^^^^^^^^\n\n::\n\n    virtual int __stdcall propSetClip(AVSMap* map, const char* key, PClip& clip, int append) = 0;\n\nsets PClip type frame property.\n\n\n.. _cplusplus_propsetframe:\n\npropSetFrame, v8\n^^^^^^^^^^^^^^^^\n\n::\n\n    virtual int __stdcall propSetFrame(AVSMap* map, const char* key, const PVideoFrame& frame, int append) = 0;\n\nsets PVideoFrame type frame property..\n\n\n.. _cplusplus_propgetintarray:\n\npropGetIntArray, v8\n^^^^^^^^^^^^^^^^^^^\n\n::\n\n    virtual const int64_t* __stdcall propGetIntArray(const AVSMap* map, const char* key, int* error) = 0;\n\narray version of propGetInt.\n\n\n.. _cplusplus_propgetfloatarray:\n\npropGetFloatArray, v8\n^^^^^^^^^^^^^^^^^^^^^\n\n::\n\n    virtual const double* __stdcall propGetFloatArray(const AVSMap* map, const char* key, int* error) = 0;\n\narray version of propGetFloat.\n\n\n.. _cplusplus_propsetintarray:\n\npropSetIntArray, v8\n^^^^^^^^^^^^^^^^^^^\n\n::\n\n    virtual int __stdcall propSetIntArray(AVSMap* map, const char* key, const int64_t* i, int size) = 0;\n\narray version of propSetInt.\n\n\n.. _cplusplus_propsetfloatarray:\n\npropSetFloatArray, v8\n^^^^^^^^^^^^^^^^^^^^^\n\n::\n\n    virtual int __stdcall propSetFloatArray(AVSMap* map, const char* key, const double* d, int size) = 0;\n\narray version of propSetFloat.\n\n\n.. _cplusplus_createmap:\n\ncreateMap, v8\n^^^^^^^^^^^^^\n\n::\n\n    virtual AVSMap* __stdcall createMap() = 0;\n\ninternal use only, creating frame property buffer.\n\n\n.. _cplusplus_freemap:\n\nfreeMap, v8\n^^^^^^^^^^^\n\n::\n\n    virtual void __stdcall freeMap(AVSMap* map) = 0;\n\ninternal use only, frees up frame property buffer.\n\n\n.. _cplusplus_clearmap:\n\nclearMap, v8\n^^^^^^^^^^^^\n\n::\n\n    virtual void __stdcall clearMap(AVSMap* map) = 0;\n\nclears all properties for a frame.\n\n\n.. _cplusplus_newvideoframep:\n\nNewVideoFrameP, v8\n^^^^^^^^^^^^^^^^^^\n\n::\n\n    virtual PVideoFrame __stdcall NewVideoFrameP(const VideoInfo& vi, const PVideoFrame* prop_src, int align = FRAME_ALIGN) = 0;\n\nNewVideoFrame with frame property source.\n\nNote: C interface counterpart avs_new_video_frame_p(_a) crash was fixed in interface version 9.1\n\n\n.. _cplusplus_getenvproperty:\n\nGetEnvProperty, v8\n^^^^^^^^^^^^^^^^^^\n\n::\n\n    virtual size_t  __stdcall GetEnvProperty(AvsEnvProperty prop) = 0;\n\nQuery to ask for various system (not frame!) properties.\n\n::\n\n    // IScriptEnvironment GetEnvProperty\n    enum AvsEnvProperty\n    {\n      AEP_PHYSICAL_CPUS = 1,\n      AEP_LOGICAL_CPUS = 2,\n      AEP_THREADPOOL_THREADS = 3,\n      AEP_FILTERCHAIN_THREADS = 4,\n      AEP_THREAD_ID = 5,\n      AEP_VERSION = 6,\n      AEP_HOST_SYSTEM_ENDIANNESS = 7, // V9\n      AEP_INTERFACE_VERSION = 8, // V9\n      AEP_INTERFACE_BUGFIX = 9,  // V9\n      AEP_CACHESIZE_L2 = 10, // v12\n\n      // Neo additionals\n      AEP_NUM_DEVICES = 901,\n      AEP_FRAME_ALIGN = 902,\n      AEP_PLANE_ALIGN = 903,\n\n      AEP_SUPPRESS_THREAD = 921,\n      AEP_GETFRAME_RECURSIVE = 922,\n    };\n\n\nAEP_HOST_SYSTEM_ENDIANNESS (c++) AVS_AEP_HOST_SYSTEM_ENDIANNESS (c)\n...................................................................\n\nPopulated by 'little', 'big', or 'middle' based on what GCC and/or Clang report at compile time.\n\nAEP_INTERFACE_VERSION (c++) AVS_AEP_INTERFACE_VERSION (c)\n.........................................................\n\nFor requesting actual interface (main) version. An long awaited function. \nSo far the actual interface version could be queried only indirectly, with trial and error, by starting from e.g. 10 then\ngoing back one by one until CheckVersion() did not report an exception/error code. \n\nEven for V8 interface this was a bit tricky, the only way to detect was the infamous\n\n::\n\n      has_at_least_v8 = true;\n      try { env->CheckVersion(8); } catch (const AvisynthError&) { has_at_least_v8 = false; }\n\nmethod.\n\nNow (starting from interface version 8.1) a direct version query is supported as well.\nOf course this (one or two direct call only) is the future.\nPrograms or plugins which would like to identify older systems still must rely partially on the CheckVersion method.\n\nCPP interface (through avisynth.h).\n\n::\n\n    IScriptEnvironment *env = ...\n    avisynth_if_ver = 6; // guessed minimum\n    avisynth_bugfix_ver = 0;\n    try { env->CheckVersion(8); avisynth_if_ver = 8; }\n    catch (const AvisynthError&) {}\n    try { \n      env->CheckVersion(9); // if this works, we are at least V9, can use GetEnvProperty with AEP_INTERFACE_VERSION\n      avisynth_if_ver = env->GetEnvProperty(AEP_INTERFACE_VERSION); // only since V9!\n      avisynth_bugfix_ver = env->GetEnvProperty(AEP_INTERFACE_BUGFIX);      \n    } \n    catch (const AvisynthError&) {}\n    \n    has_at_least_v8 = avisynth_if_ver >= 8; // frame properties, NewVideoFrameP, other V8 environment functions\n    has_at_least_v8_1 = avisynth_if_ver > 8 || (avisynth_if_ver == 8 && avisynth_bugfix_ver >= 1);\n    // 8.1: C interface frameprop access fixed, IsPropertyWritable/MakePropertyWritable support, extended GetEnvProperty queries\n    has_at_least_v9 = avisynth_if_ver >= 9;\n    has_at_least_v12 = avisynth_if_ver >= 12; // global locks, GetCPUFlagsEx, query L2 cache size\n\nC interface (through avisynth_c.h)\n\n::\n\n    AVS_ScriptEnvironment *env = ...\n    int avisynth_if_ver = 6; // guessed minimum\n    int avisynth_bugfix_ver = 0;\n    int retval = avs_check_version(env, 8);\n    if (retval == 0) {\n      avisynth_if_ver = 8;\n      retval = avs_check_version(env, 9);\n      if (retval == 0) {\n        // V9 at least, we have AVS_AEP_INTERFACE_VERSION supported\n        size_t retval_getenv = avs_get_env_property(env, AVS_AEP_INTERFACE_VERSION);\n      if(env->error == 0) {\n          avisynth_if_ver = retval_getenv;\n          retval_getenv = avs_get_env_property(env, AVS_AEP_INTERFACE_BUGFIX);\n        if(env->error == 0)\n            avisynth_bugfix_ver = retval_getenv;\n      }\n    }\n    }\n    has_at_least_v8 = avisynth_if_ver >= 8; // frame properties, NewVideoFrameP, other V8 environment functions\n    has_at_least_v8_1 = avisynth_if_ver > 8 || (avisynth_if_ver == 8 && avisynth_bugfix_ver >= 1);\n    // 8.1: C interface frameprop access fixed, IsPropertyWritable/MakePropertyWritable support, extended GetEnvProperty queries\n    has_at_least_v9 = avisynth_if_ver >= 9;\n    has_at_least_v12 = avisynth_if_ver >= 12; // global locks, avs_get_cpu_flags_ex, query L2 cache size\n\n\nAEP_INTERFACE_BUGFIX (c++) AVS_AEP_INTERFACE_BUGFIX (c)\n.......................................................\n\nDenotes situations where there isn't a breaking change to the API,\nbut we need to identify when a particular change, fix or addition\nto various API-adjacent bits might have occurred.  Could also be\nused when any new functions get added.\n\nSince the number is modelled as 'changes since API bump' and\nintended to be used in conjunction with checking the main\nAVISYNTH_INTERFACE_VERSION, whenever the main INTERFACE_VERSION\ngets raised, the value of INTERFACE_BUGFIX should be reset to zero.\n\nThe BUGFIX version is added here with already incremented once,\nboth because the addition of AVISYNTH_INTERFACE_BUGFIX_VERSION\nitself would require it, but also because it's intended to signify\nthe fix to the C interface allowing frame properties to be read\nback (which was the situation that spurred this define to exist\nin the first place).\n\n\nAEP_CACHESIZE_L2 (c++) AVS_AEP_CACHESIZE_L2 (c)\n...............................................\n\nSince V12. Returns the size of the L2 CPU cache in bytes.\n\n::\n\n    size_t l2_cache_size = env->GetEnvProperty(AEP_CACHESIZE_L2);\n    // or in C interface\n    size_t l2_cache_size = avs_get_env_property(env, AVS_AEP_CACHESIZE_L2);\n    if (env->error == 0) {\n      // l2_cache_size is valid\n    }\n\n\n.. _cplusplus_allocate:\n\nAllocate, v8\n^^^^^^^^^^^^\n\n::\n\n    virtual void* __stdcall Allocate(size_t nBytes, size_t alignment, AvsAllocType type) = 0;\n\nbuffer pool allocate.\n\nPrimary goal of ``AVS_NORMAL_ALLOC`` was to have the Avisynth-reserved memory \ncounter up-to-date and to take into account this memory area as well. \nThus when reaching the MemoryMax limit the core would free up memory from \nthis resource as well (along with frame registry and cache entries).\nWorks like a normal _aligned_alloc.\n\nBut ``AVS_POOLED_ALLOC`` has (or had) a lot more important benefit. Pooled allocations \nare meant for filters that don't need the buffers between frames and can free \nthem between calls to ``GetFrame()``. Then multiple filters can use the same buffers \ninstead of each filter unnecessarily clinging onto them even while a different filter \nis executing. This resulted in tons of memory savings, which was really useful, as most \nof the complex scripts on HD material used to be memory-bound in that era (around 2015).\nThe main reason ``env->Allocate`` and ``env->Free`` were created at all was to support these \npooled allocations and memory re-use between filters. Adding ``AVS_NORMAL_ALLOC`` was just a bonus.\n\nThe memory savings might not be that important today (as of 2025) since PCs now have a lot \nmore RAM, but the savings are still there.\n\n::\n\n    // IScriptEnvironment Allocate\n    enum AvsAllocType\n    {\n      AVS_NORMAL_ALLOC = 1,\n      AVS_POOLED_ALLOC = 2\n    };\n\n\n.. _cplusplus_free:\n\nFree, v8\n^^^^^^^^\n\n::\n\n    virtual void __stdcall Free(void* ptr) = 0;\n\nbuffer pool free. Pair of ``Allocate``.\n\n\n.. _cplusplus_getvartry:\n\nGetVarTry, v8\n^^^^^^^^^^^^^\n\n::\n\n    virtual bool  __stdcall GetVarTry(const char* name, AVSValue* val) const = 0;\n\nget variable with success indicator.\nReturns true and the requested variable. If the method fails, returns false and does not touch 'val'.\n\n\n.. _cplusplus_getvarbool:\n\nGetVarBool, v8\n^^^^^^^^^^^^^^\n\n::\n\n    virtual bool __stdcall GetVarBool(const char* name, bool def) const = 0;\n\nGet bool value with default.\nReturn the value of the requested variable. If the variable was not found or had the wrong type, return the supplied default value.\n\n\n.. _cplusplus_getvarint:\n\nGetVarInt, v8\n^^^^^^^^^^^^^\n\n::\n\n    virtual int  __stdcall GetVarInt(const char* name, int def) const = 0;\n\nGet int value with default.\nReturn the value of the requested variable. If the variable was not found or had the wrong type, return the supplied default value.\n\n\n.. _cplusplus_getvardouble:\n\nGetVarDouble, v8\n^^^^^^^^^^^^^^^^\n\n::\n\n    virtual double  __stdcall GetVarDouble(const char* name, double def) const = 0;\n\nGet floating point value with default. As of 2021 there is no double support for variables, 32 bit float only.\nReturn the value of the requested variable. If the variable was not found or had the wrong type, return the supplied default value.\n\n\n.. _cplusplus_getvarstring:\n\nGetVarString, v8\n^^^^^^^^^^^^^^^^\n\n::\n\n    virtual const char* __stdcall GetVarString(const char* name, const char* def) const = 0;\n\nGet string with default.\nReturn the value of the requested variable. If the variable was not found or had the wrong type, return the supplied default value.\n\n\n.. _cplusplus_getvarlong:\n\nGetVarLong, v8\n^^^^^^^^^^^^^^\n\n::\n\n    virtual int64_t __stdcall GetVarLong(const char* name, int64_t def) const = 0;\n\nGet int64 with default. As of 2021 there is no int64 support for variables. On Windows it is 32 bit int.\nReturn the value of the requested variable. If the variable was not found or had the wrong type, return the supplied default value.\n\n\n.. _cplusplus_makepropertywritable:\n\nMakePropertyWritable v9\n^^^^^^^^^^^^^^^^^^^^^^^\n\n::\n\n    virtual bool __stdcall MakePropertyWritable(PVideoFrame* pvf) = 0;\n\nlike MakeWritable but for frame properties only.\nSee also \n- :ref:`IsPropertyWritable <cplusplus_ispropertywritable>` like IsWritable but for frame properties only.\n- :ref:`getFramePropsRW <cplusplus_getframepropsrw>`.\n\n\n.. _cplusplus_acquiregloballock:\n.. _cplusplus_releasegloballock:\n\nAcquireGlobalLock, v12\n^^^^^^^^^^^^^^^^^^^^^^\nReleaseGlobalLock, v12\n^^^^^^^^^^^^^^^^^^^^^^\n\n::\n\n    // C++ interface (IScriptEnvironment virtual methods)\n    virtual bool __stdcall AcquireGlobalLock(const char* name) = 0;\n    virtual void __stdcall ReleaseGlobalLock(const char* name) = 0;\n\n    // C interface (global avs_ functions)\n    AVS_EXPORT int __stdcall avs_acquire_global_lock(AVS_ScriptEnvironment* env, const char* name);\n    AVS_EXPORT void __stdcall avs_release_global_lock(AVS_ScriptEnvironment* env, const char* name);\n\nThese functions provide a global, named mutex mechanism to synchronize access to shared \nresources across different plugins within the same Avisynth process. This is essential for \nlibraries like fftw3 that have non-thread-safe global state (e.g., their planner functions).\n\nWhen AcquireGlobalLock (or avs_acquire_global_lock) is called, the calling thread will block \nuntil the named lock is available. The lock is then exclusively held by that thread until \nReleaseGlobalLock (or avs_release_global_lock) is called.\n\nThe name parameter allows for different independent global locks.\nFor FFTW, the recommended name is \"fftw\".\n\nFor safe use, set and check ``has_at_least_v12``, see interface version check methods above.\n\n**Example#1 RAII for C++ interface plugins**\n\nC++ plugins, which operate with the IScriptEnvironment* interface, should use a \nResource Acquisition Is Initialization (RAII) wrapper. This GlobalLockGuard class example \nensures the lock is automatically released when the guarding object goes out of scope,\neven if exceptions occur.\n\nThe constructor of this GlobalLockGuard expects an IScriptEnvironment* directly, \nas C++ plugins will have access to this pointer.\n::\n\n    // FFTW is not thread-safe, need to guard around its functions (except fftw_execute).\n    // http://www.fftw.org/fftw3_doc/Thread-safety.html#Thread-safety\n    // Pre V12, not 100%, does not guard locks from multiple plugins using FFTW at the same time.\n    static std::mutex fftw_legacy_mutex; // defined as static\n\n    // Since Avisynth IF v12 use global lock which handles fftw locks for different plugins which use the same FFTW library.\n    class GlobalLockGuard\n    {\n    public:\n      // env_ptr should be the IScriptEnvironment* received by the plugin's function.\n      // lock_name is the name of the lock (e.g., \"fftw\").\n      // use_v12_if_available: If true, tries V12. If false or V12 not available, falls back to legacy mutex.\n      GlobalLockGuard(IScriptEnvironment* env_ptr, const char* lock_name, bool use_v12_global_lock)\n        : m_env_ptr(env_ptr), m_lockName(lock_name), m_acquired(false), m_is_legacy_lock(false)\n      {\n        if (!m_env_ptr || !m_lockName) {\n          // Invalid parameters, cannot acquire lock.\n          return;\n        }\n\n        // Attempt to acquire V12 global lock if requested and available.\n        // This assumes IScriptEnvironment provides a way to check its version.\n        if (use_v12_global_lock)\n        {\n          // We must use a try-catch block if AcquireGlobalLock can throw,\n          // or just assume it blocks and returns success/failure.\n          // Assuming it blocks and returns true/false for success.\n          m_acquired = m_env_ptr->AcquireGlobalLock(m_lockName);\n          if (m_acquired) {\n            m_is_legacy_lock = false; // Successfully acquired V12 lock\n            return; // Lock acquired, exit constructor\n          }\n        }\n\n        // If we reach here, V12 lock wasn't used/acquired, fall back to legacy mutex.\n        if (strcmp(m_lockName, \"fftw\") == 0) {\n          fftw_legacy_mutex.lock(); // Acquire the legacy mutex\n          m_acquired = true;\n          m_is_legacy_lock = true; // Acquired legacy lock\n        }\n        // else { // Handle unrecognized lock_name for legacy fallback if needed }\n      }\n\n      // Destructor releases the lock.\n      ~GlobalLockGuard()\n      {\n        if (m_acquired) // Only attempt to release if successfully acquired\n        {\n          if (m_is_legacy_lock) {\n            fftw_legacy_mutex.unlock(); // Release legacy mutex\n          }\n          else {\n            // Release V12 global lock\n            if (m_env_ptr) { // Safety check\n              m_env_ptr->ReleaseGlobalLock(m_lockName);\n            }\n          }\n        }\n      }\n\n      bool is_acquired() const { return m_acquired; }\n\n      // Disallow copying and assignment to prevent common errors with mutexes.\n      GlobalLockGuard(const GlobalLockGuard&) = delete;\n      GlobalLockGuard& operator=(const GlobalLockGuard&) = delete;\n\n    private:\n      IScriptEnvironment* m_env_ptr; // Store the C++ interface pointer directly\n      const char* m_lockName;\n      bool m_acquired;\n      bool m_is_legacy_lock; // true if legacy mutex was used, false if V12 global lock was used\n    };\n\n**Example for lock, C++ plugin using RAII**\n\n::\n\n    // In a C++ plugin's source file (e.g., fft3dfilter, dfttest.cpp)\n    #include \"AvsLockGuard.h\" // Assuming GlobalLockGuard is in this header\n\n    // ... plugin setup ...\n\n    // Use a scope to define the critical section for FFTW planning.\n    {\n        // Acquire the global \"fftw\" lock. It's automatically released when this scope exits.\n        GlobalLockGuard fftw_lock(env, \"fftw\", has_at_least_v12);\n\n        // --- CRITICAL SECTION START ---\n        // Code here is protected by the global \"fftw\" lock.\n        // Only one thread across all dynamically linked FFTW plugins\n        // within this process can execute this section concurrently.\n        fftwf_plan my_plan = fftwf_plan_dft_r2c_3d(...); // Perform FFTW planning\n        // --- CRITICAL SECTION END ---\n\n    } // `fftw_lock` goes out of scope here, automatically releasing the lock.\n\n\nNote that when the lock is used in plan destroying, in a class destructror, we don't have\n``env`` as a parameter, so we must use an an ``env_saved`` pointer stored earlier.\n\n**Example#2 RAII for C++ plugins using C-Compatible interface**\n\nC-compatible plugins, which receive an ``AVS_ScriptEnvironment*``, should also use an \nRAII wrapper for safe lock management. This ``GlobalLockGuardC`` will internally call \nthe ``avs_`` C functions for acquiring and releasing the lock.\n\n::\n\n    // Note: no pre-V12 fallback is shown here\n\n    // It operates on the AVS_ScriptEnvironment* handle and calls the C-interface functions.\n    class GlobalLockGuardC\n    {\n    public:\n        // env_handle should be the AVS_ScriptEnvironment* received by the plugin's function.\n        GlobalLockGuardC(AVS_ScriptEnvironment* env_handle, const char* lock_name)\n            : m_env_handle(env_handle), m_lockName(lock_name), m_acquired(false)\n        {\n            if (m_env_handle && m_lockName)\n            {\n                m_acquired = (avs_acquire_global_lock(m_env_handle, m_lockName) == 1);\n            }\n        }\n\n        // Destructor releases the lock using the C-interface functions.\n        ~GlobalLockGuardC()\n        {\n            if (m_acquired && m_env_handle && m_lockName)\n            {\n                avs_release_global_lock(m_env_handle, m_lockName);\n            }\n        }\n\n        bool is_acquired() const { return m_acquired; }\n\n        // Disallow copying and assignment to prevent common errors with mutexes.\n        GlobalLockGuardC(const GlobalLockGuardC&) = delete;\n        GlobalLockGuardC& operator=(const GlobalLockGuardC&) = delete;\n\n    private:\n        AVS_ScriptEnvironment* m_env_handle; // Store the C-compatible handle\n        const char* m_lockName;\n        bool m_acquired;\n    };\n\n\n\n**Example for lock, C++ interface, with above RAII**\n::\n\n    // In a C-compatible plugin's source file (e.g., myfilter.cpp that uses C++ features)\n    // You'd typically also include the C-compatible RAII wrapper\n\n    // Plugin function signature for C-compatible plugins (receives AVS_ScriptEnvironment*)\n    static AVS_Value AVSC_CC Create_xxxx(AVS_ScriptEnvironment* env, AVS_Value args, void* param)\n    {\n        // ... plugin setup ...\n\n        // Use a scope to define the critical section for FFTW planning.\n        {\n            // Acquire the global \"fftw\" lock using the C-compatible RAII wrapper.\n            GlobalLockGuardC fftw_lock(env, \"fftw\");\n\n            // You might want to check if the lock was acquired, though avs_acquire_global_lock\n            // will typically block until successful.\n            // If you need to handle acquisition failure, you would check fftw_lock.is_acquired().\n            // In a pure C plugin, you would return an error AVS_Value.\n\n            // --- CRITICAL SECTION START ---\n            // Code here is protected by the global \"fftw\" lock.\n            fftwf_plan my_plan = fftwf_plan_dft_r2c_3d(...); // Perform FFTW planning\n            // --- CRITICAL SECTION END ---\n\n        } // `fftw_lock` goes out of scope here, automatically releasing the lock.\n\n        // ... rest of the plugin logic ...\n    }\n\n\n**Example for use from pure C-compatible**\n\nPure C plugins do not have access to C++ RAII. They must manually call ``avs_acquire_global_lock``\nand ``avs_release_global_lock``, ensuring that every acquisition has a corresponding release.\n\n::\n\n    fftwf_plan my_plan = NULL;\n    int lock_acquired = 0; // Flag to track if lock was acquired\n\n    // Acquire the lock\n    lock_acquired = avs_acquire_global_lock(env, \"fftw\");\n    if (!lock_acquired) {\n        // Handle error: Return an error AVS_Value.\n        return avs_new_error(clip, \"MyCFilter: Failed to acquire global FFTW planner lock!\");\n    }\n\n    // --- CRITICAL SECTION START ---\n    // Code here is protected by the global \"fftw\" lock.\n    my_plan = fftwf_plan_dft_r2c_3d(...); // Perform FFTW planning\n    // --- CRITICAL SECTION END ---\n\n    // Release the lock manually\n    avs_release_global_lock(env, \"fftw\");\n\n\n\nSee also https://github.com/AviSynth/AviSynthPlus/issues/444\nand https://www.fftw.org/doc/Thread-safety.html \n\n\n.. _cplusplus_pvideoframe:\n\nPVideoFrame\n~~~~~~~~~~~\n\nPVideoFrame is a smart pointer to VideoFrame.\n\nIn this example it gives a pointer to frame 'n' from child:\n::\n\n    PVideoFrame src = child->GetFrame(n, env);\n\n\n\"child\" is a protected member of GenericVideoFilter, of type PClip. It\ncontains the clip that was passed to the constructor. For our filter to\nproduce frame n we need the corresponding frame of the input. If you\nneed a different frame from the input, all you have to do is pass a\ndifferent frame number to child->GetFrame.\n\nIn this example it gives a pointer to a new created VideoFrame from vi\n(which is a VideoInfo structure):\n::\n\n    PVideoFrame dst = env->NewVideoFrame(vi);\n\nInterface V8 introduced frame properties. One can create a new frame with\nspecifying a source frame from which the frame properties are copied.\n\nIn this example it gives a pointer to a new created VideoFrame from vi,\nwith the actual child clip as frame property source:\n::\n\n    PVideoFrame src = child->GetFrame(n, env);\n    PVideoFrame dst = env->NewVideoFrameP(vi, src);\n\n\n\"vi\" is another protected member of GenericVideoFilter (the only other\nmember, actually). It is a structure of type VideoInfo, which contains\ninformation about the clip (like frame size, frame rate, pixel format,\naudio sample rate, etc.). NewVideoFrame uses the information in this\nstruct to return a frame buffer of the appropriate size.\n\n\n.. _cplusplus_iclip:\n\nIClip\n~~~~~\n\nAn Avisynth filter is simply a C++ class implementing the IClip\ninterface. IClip has four pure virtual methods: GetVideoInfo, GetFrame,\nGetParity, and GetAudio. The class GenericVideoFilter is a simple\ndo-nothing filter defined in avisynth.h. It derives from IClip and\nimplements all four methods. Most filters can inherit from\nGenericVideoFilter rather than directly from IClip; this saves you from\nhaving to implement methods that you don't care about, like GetAudio.\n\nIClip has the following members: GetVersion, GetFrame, GetParity,\nGetAudio, SetCacheHints and GetVideoInfo. They are described in the\nfollowing subsections.\n\n\n.. _cplusplus_getversion:\n\nGetVersion\n^^^^^^^^^^\n\n::\n\n    virtual int __stdcall GetVersion() { return AVISYNTH_INTERFACE_VERSION; }\n\n\nGetVersion returns the interface version of the Clip instance, but\nit would show, against which avisynth.h version was the filter built.\n\nAVISYNTH_INTERFACE_VERSION = 1 (v1.0-v2.0.8), 2 (v2.5.0-v2.5.5), 3\n(v2.5.6-v2.5.8), 5 (v2.6.0a1-v2.6.0a5), 6 (v2.6.0), 8 (Avisynth+ from a specific build on) [version 4 doesn't exist].\n\nThis only returns the interface version of how the plugin was built against \nan actual avisynth header.\n\nSince in Avisynth the closest (pseudo) clip is Avisynth's internal MT or cache-guard clip,\nit usually returns the real Avisynth version, but for non-cached, non-MT  filters it may \nshow the filter's avisynth header version.\n\nIn interface V9 (working version 8.1) use GetEnvProperty(AEP_INTERFACE_VERSION) and GetEnvProperty(AEP_INTERFACE_BUGFIX) for this task.\n\n\n.. _cplusplus_getframe:\n\nGetFrame\n^^^^^^^^\n\n::\n\n    virtual PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) = 0;\n\n\nGetFrame returns a video frame. In this example, the even frames (0, 2,\n4, ...) of 'child' are returned:\n::\n\n    PVideoFrame src = child->GetFrame(2*n, env);\n\n\nYou should do all the GetFrame() calls BEFORE you get any pointers and\nstart manipulating any data.\n\n\n.. _cplusplus_getparity:\n\nGetParity\n^^^^^^^^^\n\n::\n\n    virtual bool __stdcall GetParity(int n) = 0;\n\n\nGetParity returns the field parity if the clip is field-based,\notherwise it returns the parity of first field of a frame. In other\nwords, it distinguishes between top field first (TFF) and bottom field\nfirst (BFF). When it returns true, it means that this frame should be\nconsidered TFF, otherwise it should be considered BFF.\n\n\n.. _cplusplus_getaudio:\n\nGetAudio\n^^^^^^^^\n\n::\n\n    virtual void __stdcall GetAudio(void* buf, __int64 start, __int64 count, IScriptEnvironment* env) = 0;\n\n\nAudio processing is handled through the GetAudio method. You must fill\nin the buffer with count samples beginning at the sample start. A\nsample may vary from one to four bytes, depending on whether the audio\nis 8, 16, 24 or 32-bit (float is also 32-bit). The flag vi.SampleType()\nwill tell you this.\n\nIf you cannot do your audio processing in-place, you must allocate your\nown buffer for the source audio using new or malloc.\n\nIn this example, the audio of frame 'n' is returned (in the buffer\n'samples'):\n::\n\n    VideoInfo vi = child->GetVideoInfo();\n    PVideoFrame src = child->GetFrame(n, env);\n    const __int64 start = vi.AudioSamplesFromFrames(n);\n    const __int64 count = vi.AudioSamplesFromFrames(1);\n    SFLOAT* samples = new SFLOAT[count*vi.AudioChannels()];\n    child->GetAudio(samples, max(0,start), count, env);\n\n\n.. _cplusplus_setcachehints:\n\nSetCacheHints\n^^^^^^^^^^^^^\n\n::\n\n    int __stdcall SetCacheHints(int cachehints, int frame_range) = 0 ;\n    // We do not pass cache requests upwards, only to the next filter.\n\n\nSee ``CachePolicyHint`` enum in ``avisynth.h`` for possible cachehints values,\nor AVS_CACHE_* defines in avisynth_c.h for C interface.\n\nSome use cases from the filter side:\n\n\nCACHE_GET_MTMODE\n................\n\nFilter specifies its required MT (multithread) mode.\n\nA filter when requested with CACHE_GET_MTMODE can return its \nmultithreaded model to the core. MT_NICE_FILTER (fully reentrant), \nMT_MULTI_INSTANCE and MT_SERIALIZED (not MT friendly) can be returned.\n\n::\n\n    class ConvertToRGB : public GenericVideoFilter {\n      ...\n    int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n      AVS_UNUSED(frame_range);\n      return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n    }\n\n::\n\n    enum MtMode\n    {\n      MT_INVALID = 0,\n      MT_NICE_FILTER = 1,\n      MT_MULTI_INSTANCE = 2,\n      MT_SERIALIZED = 3,\n      MT_SPECIAL_MT = 4, // do not use, test only\n      MT_MODE_COUNT = 5\n    }; \n\n\nCACHE_INFORM_NUM_THREADS\n........................\n\nFilter is informed about about the number or threads which was set by Prefetch.\n\nSince v12.\n\nAvisynth core uses the ``CachePolicyHint::CACHE_INFORM_NUM_THREADS`` enum to inform the filter \nabout the number of threads by ``SetCacheHints`` when ``Prefetch`` is applied to that script section.\n\nThe parameter specifies the thread count.\n\nFor ``MT_MULTI_INSTANCE`` filters it is called for each instance.\nFor ``MT_NICE_FILTER`` or ``MT_SERIALIZED`` only once.\nNot called if no ``Prefetch`` is used for that script section.\n\nPossible use cases: \n\n- filter may disable its internal MT if received thread count > 1.\n- for ``num_threads`` > 1, in Intel intrinsics optimization, the code can \n  use ``_mm_stream_si128`` which does not pollute caches, when writing output frames. \n  For ``num_threads`` = 1 your code version can use functions optimized for single thread \n  and can use ``_mm_store_si128``.\n\n::\n\n    class ConvertToRGB : public GenericVideoFilter {\n      private:\n        int num_threads; // initialize it, since CACHE_INFORM_NUM_THREADS is not called if no Prefetch is used\n      ...\n      int __stdcall SetCacheHints(int cachehints, int frame_range) override {\n        if (cachehints == CACHE_GET_MTMODE) return MT_NICE_FILTER;\n        if (cachehints == CACHE_INFORM_NUM_THREADS) {\n          num_threads = frame_range;\n        }\n        return 0;\n      }\n\n\nCACHE_DONT_CACHE_ME\n...................\n\nFilter specifies that it needs no caching.\n\nFilter returns 1 to the CACHE_DONT_CACHE_ME query.\n\n::\n\n    int __stdcall NonCachedGenericVideoFilter::SetCacheHints(int cachehints, int frame_range)\n    {\n      switch(cachehints)\n      {\n        case CACHE_DONT_CACHE_ME:\n          return 1;\n        case CACHE_GET_MTMODE:\n          return MT_NICE_FILTER;\n\n        case CACHE_GET_DEV_TYPE:\n          return (child->GetVersion() >= 5) ? child->SetCacheHints(CACHE_GET_DEV_TYPE, 0) : 0;\n\n        default:\n          return GenericVideoFilter::SetCacheHints(cachehints, frame_range);\n      }\n    }\n\n\n\nOld, up to Avisynth 2.6\n.......................\n\nIn Avisynth+ frame cacheing was completely rewritten compared to Avisynth 5 or 6.\nSpecifying cache ranges are no longer relevant. The following part describes\nthe old behaviour for historical reasons only.\n\nSetCacheHints could be used in filters that request multiple frames\nfrom any single PClip source per input GetFrame call. frame_range is\nmaximal 21.\n\nThe possible values of cachehints are:\n::\n\n    CACHE_NOTHING=0    // Filter requested no caching.\n    CACHE_RANGE=1      // An explicit cache of \"frame_range\" frames around the current frame.\n    CACHE_ALL=2        // This is default operation, a simple LRU cache.\n    CACHE_AUDIO=3      // Audio caching.\n    CACHE_AUDIO_NONE=4 // Filter requested no audio caching.\n    CACHE_AUDIO_AUTO=5 // Audio caching (difference with CACHE_AUDIO?).\n\n\nWhen caching video frames (cachehints=0, 1, 2), frame_range is the\nradius around the current frame. When caching audio samples\n(cachehints=3, 4, 5), the value 0 creates a default buffer of 64kb and\npositive values allocate frame_range bytes for the cache.\n\nE.g. If you have a single PClip source, i.e. child and you get asked\nfor frame 100 and you in turn then ask for frames 98, 99, 100, 101 and\n102 then you need to call CACHE_RANGE with frame_range set to 3:\n::\n\n    child->SetCacheHints(CACHE_RANGE, 3);\n\nFrames outside the specified radius are candidate for normal LRU\ncaching.\n\n\n.. _cplusplus_getvideoinfo:\n\nGetVideoInfo\n^^^^^^^^^^^^\n\n::\n\n    virtual const VideoInfo& __stdcall GetVideoInfo() = 0;\n\n\nGetVideoInfo returns a :doc:`VideoInfo <VideoInfo>` structure.\n\n\n.. _cplusplus_pfunction:\n\nPFunction v8\n~~~~~~~~~~~~\n\nPFunction is a smart pointer to an IFunction, and IFunction is a generic abstract\nclass.. It maintains a reference count on the IFunction object and\nautomagically deletes it when the last PFunction referencing it goes away.\nFor obvious reasons, you should always use PFunction rather than IFunction* to\nrefer to function.\n\nLike a genuine pointer, a PFunction is only four/eight bytes long, so you can\npass it around by value. Also like a pointer, a PFunction can be assigned a\nnull value (0), which is often useful as a sentinel. Unlike a pointer,\nPFunction is initialized to 0 by default.\n\nA function is a new object type in Avisynth+ since V8, originally introduced in Neo fork.\n\n\n.. _cplusplus_pclip:\n\nPClip\n~~~~~\n\nPClip is a smart pointer to an IClip, and IClip is a generic abstract\nclass.. It maintains a reference count on the IClip object and\nautomagically deletes it when the last PClip referencing it goes away.\nFor obvious reasons, you should always use PClip rather than IClip* to\nrefer to clips.\n\nLike a genuine pointer, a PClip is only four bytes long, so you can\npass it around by value. Also like a pointer, a PClip can be assigned a\nnull value (0), which is often useful as a sentinel. Unlike a pointer,\n\nPClip is initialized to 0 by default.\n\nYou'll need to make sure your class doesn't contain any circular PClip\nreferences, or any PClips sitting in dynamically allocated memory that\nyou forget to delete. Other than that, you don't have to worry about\nthe reference-counting machinery.\n\nAviSynth filters have a standardized output channel via IClip, but\n(unlike VirtualDub filters) no standardized input channel. Each filter\nis responsible for obtaining its own source material -- usually (as in\nthis case) from another clip, but sometimes from several different\nclips, or from a file.\n\nThe clip functionality must be provided by some concrete subclass of\nIClip which implements the functions GetFrame(), etc. So you cannot\ncreate a PClip without having an appropriate IClip subclass. For most\nfilters, the GenericVideoFilter class provides the basis for this, but\n'source' filters (which is basically what you have) do not have a\nparent clip and so GenericVideoFilter is not appropriate.\n\n\n.. _cplusplus_avsvalue:\n\nAVSValue\n~~~~~~~~\n\nAVSValue is a variant type which can hold any one of the following\ntypes: a boolean value (true/false); an integer; a floating-point\nnumber; a string; a video clip (PClip); an array of AVSValues; \na function (Avisynth+) or nothing (\"undefined\").\n\nIt holds an array of AVSValues in the following way:\n::\n\n    AVSValue(const AVSValue* a, int size) { type = 'a'; array = a; array_size = size; }\n\n\nFor example:\n::\n\n    AVSValue up_args[3] = {child, 384, 288};\n    PClip resized = env->Invoke(\"LanczosResize\", AVSValue(up_args,3)).AsClip();\n\n\nNote that\n::\n\n    AVSValue(up_args,3)\n\n\nreturns the following:\n::\n\n    {'a'; {child, 384, 288}; 3}\n\n\nAlso Invoke returns an AVSValue (see its declaration) which in that\ncase is a PClip.\n\n\n.. _cplusplus_avsvaluegettype:\n\nGetType V10\n^^^^^^^^^^^\n\n::\n\n    AvsValueType GetType() const;\n\n\nAVSValue::GetType returns the underlying type of the variant.\n\nReturns an ``AvsValueType`` enum directly, one can use it instead of calling\nall IsXXX functions to establish the exact type.\n\nNote that although 'l'ong and 'd'ouble are defined, 64 bit data is not\n(and in 32 bit Avisynth will never be) supported.\n\nFrom v11 interface version (3.7.4) 64 bit 'l'ong and 'd'ouble data \ntypes are supported even on 32-bit systems,\ndespite the rather pessimistic \"never be supported\" note.\n\n(Unlike frame properties, which support them by design).\n\n::\n\n    enum AvsValueType {\n      VALUE_TYPE_UNDEFINED = 'v',\n      VALUE_TYPE_BOOL = 'b',\n      VALUE_TYPE_INT = 'i',\n      VALUE_TYPE_LONG = 'l',\n      VALUE_TYPE_FLOAT = 'f',\n      VALUE_TYPE_DOUBLE = 'd',\n      VALUE_TYPE_STRING = 's',\n      VALUE_TYPE_CLIP = 'c',\n      VALUE_TYPE_FUNCTION = 'n',\n      VALUE_TYPE_ARRAY = 'a'\n    };\n\n\n.. _cplusplus_structures:\n\nStructures\n----------\n\nThe following structure is available: VideoInfo structure. It holds\nglobal information about a clip (i.e. information that does not depend\non the framenumber). The GetVideoInfo method in IClip returns this\nstructure. A description (for AVISYNTH_INTERFACE_VERSION=6, 8 and above) of it can\nbe found :doc:`here <VideoInfo>`.\n\n\n.. _cplusplus_constants:\n\nConstants\n---------\n\nThe following constants are defined in avisynth.h:\n::\n\n    // Audio Sample information\n    typedef float SFLOAT;\n\n\n::\n\n    enum AvsSampleType {\n      SAMPLE_INT8  = 1 << 0,\n      SAMPLE_INT16 = 1 << 1,\n      SAMPLE_INT24 = 1 << 2,  // Int24 is a very stupid thing to code, but it's supported by some hardware.\n      SAMPLE_INT32 = 1 << 3,\n      SAMPLE_FLOAT = 1 << 4\n    };\n\n\n::\n\n    enum AvsPlane {\n      DEFAULT_PLANE = 0,\n      PLANAR_Y = 1 << 0,\n      PLANAR_U = 1 << 1,\n      PLANAR_V = 1 << 2,\n      PLANAR_ALIGNED = 1 << 3,\n      PLANAR_Y_ALIGNED = PLANAR_Y | PLANAR_ALIGNED,\n      PLANAR_U_ALIGNED = PLANAR_U | PLANAR_ALIGNED,\n      PLANAR_V_ALIGNED = PLANAR_V | PLANAR_ALIGNED,\n      PLANAR_A = 1 << 4,\n      PLANAR_R = 1 << 5,\n      PLANAR_G = 1 << 6,\n      PLANAR_B = 1 << 7,\n      PLANAR_A_ALIGNED = PLANAR_A | PLANAR_ALIGNED,\n      PLANAR_R_ALIGNED = PLANAR_R | PLANAR_ALIGNED,\n      PLANAR_G_ALIGNED = PLANAR_G | PLANAR_ALIGNED,\n      PLANAR_B_ALIGNED = PLANAR_B | PLANAR_ALIGNED,\n    };\n\n\n::\n\n    enum CachePolicyHint {\n      CACHE_25_NOTHING_26_UNUSED_0 = 0,\n      // Values 0 to 5 are reserved for old 2.5 plugins\n      // do not use them in new plugins\n\n      // New 2.6 explicitly defined cache hints.\n      CACHE_NOTHING=10, // Do not cache video.\n      CACHE_WINDOW=11, // Hard protect upto X frames within a range of X from the current frame N.\n      CACHE_GENERIC=12, // LRU cache upto X frames.\n      CACHE_FORCE_GENERIC=13, // LRU cache upto X frames, override any previous CACHE_WINDOW.\n\n      CACHE_GET_POLICY=30, // Get the current policy.\n      CACHE_GET_WINDOW=31, // Get the current window h_span.\n      CACHE_GET_RANGE=32, // Get the current generic frame range.\n\n      CACHE_AUDIO=50, // Explicitly cache audio, X byte cache.\n      CACHE_AUDIO_NOTHING=51, // Explicitly do not cache audio.\n      CACHE_AUDIO_NONE=52, // Audio cache off (auto mode), X byte intial cache.\n      CACHE_AUDIO_AUTO=53, // Audio cache on (auto mode), X byte intial cache.\n\n      CACHE_GET_AUDIO_POLICY=70, // Get the current audio policy.\n      CACHE_GET_AUDIO_SIZE=71, // Get the current audio cache size.\n\n      CACHE_PREFETCH_FRAME=100, // Queue request to prefetch frame N.\n      CACHE_PREFETCH_GO=101, // Action video prefetches.\n\n      CACHE_PREFETCH_AUDIO_BEGIN=120, // Begin queue request transaction to prefetch audio (take critical section).\n      CACHE_PREFETCH_AUDIO_STARTLO=121, // Set low 32 bits of start.\n      CACHE_PREFETCH_AUDIO_STARTHI=122, // Set high 32 bits of start.\n      CACHE_PREFETCH_AUDIO_COUNT=123, // Set low 32 bits of length.\n      CACHE_PREFETCH_AUDIO_COMMIT=124, // Enqueue request transaction to prefetch audio (release critical section).\n      CACHE_PREFETCH_AUDIO_GO=125, // Action audio prefetches.\n\n      CACHE_GETCHILD_CACHE_MODE=200, // Cache ask Child for desired video cache mode.\n      CACHE_GETCHILD_CACHE_SIZE=201, // Cache ask Child for desired video cache size.\n      CACHE_GETCHILD_AUDIO_MODE=202, // Cache ask Child for desired audio cache mode.\n      CACHE_GETCHILD_AUDIO_SIZE=203, // Cache ask Child for desired audio cache size.\n\n      CACHE_GETCHILD_COST=220, // Cache ask Child for estimated processing cost.\n        CACHE_COST_ZERO=221, // Child response of zero cost (ptr arithmetic only).\n        CACHE_COST_UNIT=222, // Child response of unit cost (less than or equal 1 full frame blit).\n        CACHE_COST_LOW=223, // Child response of light cost. (Fast)\n        CACHE_COST_MED=224, // Child response of medium cost. (Real time)\n        CACHE_COST_HI=225, // Child response of heavy cost. (Slow)\n\n      CACHE_GETCHILD_THREAD_MODE=240, // Cache ask Child for thread safetyness.\n        CACHE_THREAD_UNSAFE=241, // Only 1 thread allowed for all instances. 2.5 filters default!\n        CACHE_THREAD_CLASS=242, // Only 1 thread allowed for each instance. 2.6 filters default!\n        CACHE_THREAD_SAFE=243, //  Allow all threads in any instance.\n        CACHE_THREAD_OWN=244, // Safe but limit to 1 thread, internally threaded.\n\n      CACHE_GETCHILD_ACCESS_COST=260, // Cache ask Child for preferred access pattern.\n        CACHE_ACCESS_RAND=261, // Filter is access order agnostic.\n        CACHE_ACCESS_SEQ0=262, // Filter prefers sequential access (low cost)\n        CACHE_ACCESS_SEQ1=263, // Filter needs sequential access (high cost)\n\n      CACHE_AVSPLUS_CONSTANTS = 500,    // Smaller values are reserved for classic Avisynth\n\n      CACHE_DONT_CACHE_ME,              // Filters that don't need caching (eg. trim, cache etc.) should return 1 to this request\n      CACHE_SET_MIN_CAPACITY,\n      CACHE_SET_MAX_CAPACITY,\n      CACHE_GET_MIN_CAPACITY,\n      CACHE_GET_MAX_CAPACITY,\n      CACHE_GET_SIZE,\n      CACHE_GET_REQUESTED_CAP,\n      CACHE_GET_CAPACITY,\n      CACHE_GET_MTMODE,\n\n      CACHE_IS_CACHE_REQ,\n      CACHE_IS_CACHE_ANS,\n      CACHE_IS_MTGUARD_REQ,\n      CACHE_IS_MTGUARD_ANS,\n\n      CACHE_AVSPLUS_CUDA_CONSTANTS = 600,\n\n      CACHE_GET_DEV_TYPE,           // Device types a filter can return\n      CACHE_GET_CHILD_DEV_TYPE,    // Device types a fitler can receive\n\n      CACHE_USER_CONSTANTS = 1000       // Smaller values are reserved for the core\n\n    };  \n\n\n.. _cplusplus_cpufeatureflags:\n\nCPU Feature Flags\n-----------------\n\nIn ``avs/cpuid.h`` (C++) or in ``avisynth_c.h`` (C).\nThe ``LL`` suffix indicates these are 64-bit values; at least the last ones exceed 32 bits.\n\nFrom Interface version V12 you can use :ref:`GetCPUFlagsEx<cplusplus_getcpuflagsex>` which returns a 64-bit integer\nwith all CPU feature flags, unlike GetCPUFlags() which returns only a 32-bit integer, thus missing some AVX512 flags.\n\nSee also :ref:`SetMaxCPU <setmaxcpu>`.\n\nIntel x86 and AMD64 CPU feature flags\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. table:: CPU Feature Flags - Intel (used in Avisynth+ for optimized code paths)\n   :align: center\n\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | C++ name                     | Flag value         | Remark                                                                                                                    |\n   +==============================+====================+===========================================================================================================================+\n   | ``CPUF_SSE2``                | ``0x20``           | PIV, K8                                                                                                                   |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_SSE3``                | ``0x100``          | PIV+, K8 Venice                                                                                                           |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_SSSE3``               | ``0x200``          | Core 2                                                                                                                    |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_SSE4``                | ``0x400``          |                                                                                                                           |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_SSE4_1``              | ``0x400``          | Penryn, Wolfdale, Yorkfield                                                                                               |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_AVX``                 | ``0x800``          | Sandy Bridge, Bulldozer                                                                                                   |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_SSE4_2``              | ``0x1000``         | Nehalem                                                                                                                   |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_AVX2``                | ``0x2000``         | Haswell                                                                                                                   |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_FMA3``                | ``0x4000``         |                                                                                                                           |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_F16C``                | ``0x8000``         |                                                                                                                           |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_MOVBE``               | ``0x10000``        | Big Endian move                                                                                                           |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_POPCNT``              | ``0x20000``        |                                                                                                                           |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_AES``                 | ``0x40000``        |                                                                                                                           |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_FMA4``                | ``0x80000``        |                                                                                                                           |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_AVX512F``             | ``0x00100000``     | AVX-512 Foundation.                                                                                                       |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_AVX512DQ``            | ``0x00200000``     | AVX-512 DQ (Double/Quad granular) Instructions                                                                            |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_AVX512PF``            | ``0x00400000``     | AVX-512 Prefetch                                                                                                          |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_AVX512ER``            | ``0x00800000``     | AVX-512 Exponential and Reciprocal                                                                                        |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_AVX512CD``            | ``0x01000000``     | AVX-512 Conflict Detection                                                                                                |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_AVX512BW``            | ``0x02000000``     | AVX-512 BW (Byte/Word granular) Instructions                                                                              |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_AVX512VL``            | ``0x04000000``     | AVX-512 VL (128/256 Vector Length) Extensions                                                                             |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_AVX512IFMA``          | ``0x08000000``     | AVX-512 IFMA integer 52 bit                                                                                               |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_AVX512VBMI``          | ``0x10000000``     | AVX-512 VBMI, byte/word shuffling, sign/zero extension, and general pixel manipulation                                    |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_AVX512_BASE``         | ``0x20000000``     | AVX-512 Base group feature set. When F, CD, BW, DQ, VL flags exist. Avisynth sets it only if CPUF_AVX512_FAST exists      |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_AVX512_FAST``         | ``0x40000000``     | Base + VNNI, VBMI, VBMI2, BITALG, VPOPCNTDQ. Spec detection logic excludes older/throttling models that also have these   |\n   |                              |                    | features                                                                                                                  |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_AVX10`` (?)           | ``0x80000000LL``   | RFU: AVX10 group feature set: version query not from flags                                                                |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_AVX512VNNI``          | ``0x00100000000LL``| VNNI, accumulated dot product on 8/16 bit integers                                                                        |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_AVX512VBMI2``         | ``0x00200000000LL``| VBMI2: Byte/word load, store, & concatenation with shift for unaligned memory and packed data re-arrangement.             |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_AVX512BITALG``        | ``0x00400000000LL``| BITALG, Bit Manipulation Instructions                                                                                     |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_AVX512VPOPCNTDQ``     | ``0x00800000000LL``| VPOPCNTDQ, Vector Population Count Double/Quadword                                                                        |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_AVX512FP16``          | ``0x01000000000LL``| FP16, Half-precision floating-point operations                                                                            |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_AVX512BF16``          | ``0x02000000000LL``| Bfloat16 floating-point operations                                                                                        |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n\nAVX-512 features are grouped into two categories:\n\n- CPUF_AVX512_BASE: Base (F, CD, BW, DQ, VL)\n- CPUF_AVX512_FAST: The \"usable\" AVX-512, starting with Intel's 10th gen Ice Lake, incl. AMD Zen4/5. The features Base + (VNNI, VBMI, VBMI2, BITALG, VPOPCNTDQ) are guaranteed.\n\nImportant note for user of old AVX512 CPUs, where only the Base flags exist (not an Ice Lake or better level CPU): \nthe \"Base\" group flag ``CPUF_AVX512_BASE`` is not enabled automatically, even if the individual base flags exist!\nThe reason is to prevent the AVX512 Base-only optimizations in Avisynth for possibly old AVX512 systems.\nHowever when users know what they are doing (know they do have non-throttling old CPU), they can enable it with ``SetMaxCPU(\"avx512base+\")``\n\n\"Fast\" means a usable AVX-512 implementation without severe throttling penalties on client CPUs. It basically guarantees a feature set \nsimilar to Intel Ice Lake/Rocket Lake and AMD Zen4/Zen5 and excludes older AVX-512 implementations (Skylake-X, Cascade Lake, Ice Lake-SP) \nwhich have severe throttling issues on client CPUs.\n\nThe categorization \"Fast\" mainly follows the ffmpeg project's \"ICL\" (Ice Lake arch.) approach.\n\nBesides the group feature flags Avisynth provides detailed individual flags as well, some of them accessible only via GetCPUFlagsEx() due to\nthe shortage of 32 bits in GetCPUFlags().\n\nRegarding the CMake-based build process: compiler flags for ``*_avx512.cpp`` files are automatically set to match with \"CPUF_AVX512_FAST\" for gcc \nor LLVM (clang-cl) builds in CMakeLists.txt. These are equivalent to using the following flags:\nas ``\"-mfma -mavx512f -mavx512cd -mavx512bw -mavx512dq -mavx512vl -mavx512vnni -mavx512vbmi -mavx512vbmi2 -mavx512bitalg -mavx512vpopcntdq \"`` .\n\nDue to the large number of AVX-512 sub-features, the following group and composite flags are defined (mentioned already in the full list above):\n\n.. table:: AVX-512 Group Feature Flags\n   :align: center\n\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_AVX512_BASE``         | ``0x20000000``     | AVX-512 Base group feature set. When F, CD, BW, DQ, VL flags. Avisynth sets it only if CPUF_AVX512_FAST exists            |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n   | ``CPUF_AVX512_FAST``         | ``0x40000000``     | AVX-512 Advance group FAST (Ice Lake/Rocket Lake/Zen4/Zen5) feature set: Base + VNNI, VBMI, VBMI2, BITALG, VPOPCNTDQ.     |\n   +------------------------------+--------------------+---------------------------------------------------------------------------------------------------------------------------+\n\n.. note::\n\n    **Usability of AVX-512 and Throttling**\n\n    While AVX-512 features were first introduced with Skylake-SP (Intel Xeon), the earliest client CPUs\n    to implement a *truly usable* 512-bit wide vector unit were **Ice Lake (10th Generation Mobile) and \n    Rocket Lake (11th Generation Desktop)**. These later microarchitectures significantly reduced the severe \n    clock-speed throttling penalty and the voltage/frequency impact (AVX-512 down-binning) that plagued \n    earlier implementations.\n\n    For this reason, high-performance projects like **FFmpeg** often use feature checks similar to ``\"avx512fast\"`` \n    to classify a processor as having \"good\" or \"usable\" AVX-512 support. Like ICL CPU feature flag in ffmpeg.\n    Compiling code solely with checking only ``\"avx512base\"`` (which often only implies first-generation AVX-512) \n    can lead to poor performance due to aggressive clock throttling on older hardware.\n\n    Developers should generally use ``\"avx512fast\"`` group in their optimizer function dispatchers, as a minimum for \n    realistic performance testing of 512-bit code paths. Avisynth (e.g. in resamplers) has both base and fast optimizations\n    implemented. However for accessing the optimizations for \"Base\" AVX512 on old CPUs, ``SetMaxCPU(\"avx512base+\")`` script \n    command must be used to re-enable AVX512 on these systems.\n\n\n.. note::\n\n    **The transition to AVX10.1 and standardization with AVX10.2**\n\n    Intel Advanced Vector Extensions 10 (Intel AVX10) is the successor to AVX-512, aiming to address the very \n    performance and consistency issues noted above. The new ISA is designed to create a **converged vector ISA** supported \n    consistently across all future Intel cores, including **Performance-cores (P-cores) and Efficient-cores (E-cores)** \n    For video filter developers, this means simplifying the instruction set selection process.\n\n    * **AVX10.1: The Transitional Version (Server-focused):** This initial version was announced in 2023 and first \n        supported by server processors (e.g., 6th Generation Intel Xeon \"Granite Rapids\"). It is primarily a \n        transitional layer, and **does not provide the key performance guarantee** sought by desktop/client developers.\n        As of late 2025, no consumer CPUs currently support AVX10.1 in general availability. It also does not natively \n        include the new FP8/BF16 data types or the full feature set of AVX10.2.\n\n    * **AVX10.2: The Standardized Converged ISA (Future Client/Server):** The significant standardization that \n        removes frequency throttling uncertainty, is found in **AVX10.2**. This version mandates **512-bit vector length (VLEN)** support \n        for all cores (P-core and E-core) on a processor that reports AVX10.2 capability.\n\n        This standardization ensures:\n\n        1.  **Reliable Performance (Predictable Latency):** It addresses the AVX-512 hybrid core issue by forcing a consistent 512-bit \n            execution environment across all supported cores. This consistency is vital for real-time video processing and \n            decoding/encoding pipelines.\n        2.  **Standardization and Modern Features:** It establishes the new, clean vector programming model. \n            AVX10.2 is designed to be binary-compatible with existing AVX-512 code, though recompilation is recommended to leverage new \n            features and the simplified CPUID check. It also introduces new instructions and data types, such as those for FP8 and BFloat16 conversions,\n            beneficial for AI-driven filters and specialized media processing.\n        3.  **Targeting:** Developers should target AVX10.2 as the minimum version for future consistent, \n            high-performance 512-bit code paths.\n\n    * **Current Outlook:** The first consumer desktop CPUs (e.g., \"Nova Lake\") supporting the standardized \n        **AVX10.2** are generally expected in the **late 2026** timeframe. For the current Avisynth user base, \n        existing robust AVX-512 checks (like ``\"avx512fast\"``) remain the relevant method for detecting modern \n        vector capability.\n\n\n.. table:: CPU Feature Flags (obsolete ones)\n   :align: center\n\n   +--------------------------+--------------------+------------------------------+\n   | C++ name                 |  Flag value        | Remark                       |\n   +==========================+====================+==============================+\n   | ``CPUF_FORCE``           |  ``0x01``          | N/A                          |\n   +--------------------------+--------------------+------------------------------+\n   | ``CPUF_FPU``             |  ``0x02``          | 386/486DX                    |\n   +--------------------------+--------------------+------------------------------+\n   | ``CPUF_MMX``             |  ``0x04``          | P55C, K6, PII                |\n   +--------------------------+--------------------+------------------------------+\n   | ``CPUF_INTEGER_SSE``     |  ``0x08``          | PIII, Athlon                 |\n   +--------------------------+--------------------+------------------------------+\n   | ``CPUF_SSE``             |  ``0x10``          | PIII, Athlon XP/MP           |\n   +--------------------------+--------------------+------------------------------+\n   | ``CPUF_3DNOW``           |  ``0x40``          | K6-2                         |\n   +--------------------------+--------------------+------------------------------+\n   | ``CPUF_3DNOW_EXT``       |  ``0x80``          | Athlon                       |\n   +--------------------------+--------------------+------------------------------+\n   | ``CPUF_X86_64``          |  ``0xA0``          | Hammer                       |\n   +--------------------------+--------------------+------------------------------+\n\nNote: \"C\" interface names are the same but with ``AVS_CPUF_`` prefix instead of ``CPUF_``.\nThey are defined in ``avisynth_c.h``.\n\n.. _aarch64_simd_tiers:\n\nAvisynth Aarch64 SIMD feature tiers\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nFirst: a useful link about AArch64 architecture and its SIMD capabilities:\n`Developer documentation at ARM <https://developer.arm.com/documentation/>`__\n\nAvisynth defines multiple categories for AArch64 (mentioned also as ARM64, ARMv8/v9) SIMD support, allowing for feature-based dispatch similar\nto the x86 SSE2/AVX2.\n\nThe implementation relies on runtime detection of hardware capabilities (using Linux's ``getauxval`` and ``hwcap``, or macOS's ``sysctl``).\nUnlike x86, AArch64 (ARM64) is using a feature-based approach rather than relying solely on CPU model strings. Features are not\nnecessarily tied to specific CPU models and levels, feature become optional at a specific ARMv8 revision, then it becomes mandatory in a later revision.\nBy detecting a feature flag, we can only be sure, that the CPU level is at least the one where the feature was introduced as optional.\n\nAvisynth header ``avs/config.h`` defines ``ARM64`` when it detects ``aarch64`` platform through the actual compiler's predefined macros.\nWhen ``ARM64`` is defined, we can assume we are compiling for ARMv8-A (AArch64) architecture, regardless of actual OS or compiler.\nAs of late 2025 Avisynth supports aarch64 with Linux, Windows, BSD and macOS. gcc, llvm, clang-cl and MSVC compilers are supported.\n\nAvisynth currently defines only a few ARM SIMD tiers, focusing on the most relevant features for video processing workloads, instead of\ntrying to cover every possible ARM extension (50+ different ones).\n\nThe ARMv8-A flag values shared with X86 flags, their usage can be guarded by platform macros.\n\n.. table:: CPU Feature Flags - aarch64 (ARM64)\n   :align: center\n\n   +------------------------------+---------------+-----------------------------------------------------------+\n   | C++ name                     | Flag value    | Remark                                                    |\n   +==============================+===============+===========================================================+\n   | ``CPUF_ARM_NEON``            | ``0x01``      | NEON flag, minimum for aarch64                            |\n   +------------------------------+---------------+-----------------------------------------------------------+\n   | ``CPUF_ARM_DOTPROD``         | ``0x02``      |                                                           |\n   +------------------------------+---------------+-----------------------------------------------------------+\n   | ``CPUF_ARM_SVE2``            | ``0x04``      |                                                           |\n   +------------------------------+---------------+-----------------------------------------------------------+\n   | ``CPUF_ARM_I8MM``            | ``0x08``      |                                                           |\n   +------------------------------+---------------+-----------------------------------------------------------+\n   | ``CPUF_ARM_SSE2_1``          | ``0x10``      |                                                           |\n   +------------------------------+---------------+-----------------------------------------------------------+\n\nThese are in ``avs/cpuid.h`` (C++) or in ``avisynth_c.h`` (C).\n\nUsage:\n::\n\n    #include <avisynth.h>\n    #include <avs/cpuid.h>\n    #ifdef NEON_INTRINSICS\n    if (env->GetCPUFlags() & CPUF_ARM_DOTPROD) {\n        // Use DOTPROD optimized code path\n    } else {\n        // Fallback to NEON baseline\n    } else \n    #endif\n    {\n        // Plain c++ non-ARM64 code path\n    }\n\n\nAArch64 Versioning Scheme (v8.x-A, v9.x-A)\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nAArch64 is a living standard. Key features relevant to Avisynth are introduced in minor revisions:\n\n* **ARMv8.0-A:** The baseline for AArch64. **NEON is mandatory.**\n* **ARMv8.1-A:** Introduces optional ``DOTPROD`` (Dot Product)\n* **ARMv8.2-A:** Introduces optional ``I8MM`` (8-bit Matrix Multiply).\n* **ARMv8.4-A:** Makes ``DOTPROD`` mandatory.\n* **ARMv8.5-A:** Introduces optional ``SVE2`` (Scalable Vector Extension 2).\n* **ARMv8.6-A:** Makes ``I8MM`` (8-bit Matrix Multiply) mandatory.\n* **ARMv9.0-A:** Compulsory ``SVE2`` support for ARMv9-A compliant CPUs.\n* **ARMv9.1-A:** Introduces further ``SVE2`` extensions (``FEAT_SVE2p1``).\n\n\n\nAvisynth ARM SIMD Tiers\n^^^^^^^^^^^^^^^^^^^^^^^\n\n- CPUF_ARM_NEON (Baseline SIMD)\n\n    This is the foundational level required for any optimized Avisynth kernel on ARM.\n\n    * **Minimum Requirement:** ARMv8.0-A (AArch64).\n    * **Register Width:** Fixed **128-bit** (V-registers V0-V31).\n    * **x86 Analogy:** Comparable to **SSE2**. It establishes 128-bit wide floating-point and \n      integer vector processing.\n    * **Usable Instruction Sets:** All basic NEON operations (addition, subtraction, multiplication, \n      shuffle, load/store).\n    * Compilers with aarch64 support automatically set Armv8.0-a baseline which includes 'fp' and 'neon' (SIMD).\n\n- CPUF_ARM_DOTPROD (Advanced 128-bit)\n\n    This tier represents the first major performance jump for modern video encoding and processing. It is \n    defined by the availability of specialized multiply-accumulate instructions.\n\n    * **Minimum Requirement:** ARMv8.1-A (where the **DOTPROD** feature flag became optional).\n    * **Register Width:** Still fixed **128-bit** (V-registers).\n    * **x86 Analogy:** Comparable to **SSSE3** or **SSE4.1** maybe a little **AVX2**, since v8.1-A introduced other new instructions as well.\n        * Unlike AVX2 which doubled the register width (128-bit to 256-bit), this ARM tier provides the *instructions* without changing the physical register width.\n    * **Usable Instruction Sets:** The **DOTPROD** instructions (e.g., ``SDOT`` and ``UDOT``) for integer dot product operations.\n    * **Video Processing Relevance:** Absolutely critical for accelerating modern video codecs (HEVC/VVC/AV1) by providing highly efficient paths for:\n        * Motion Compensation\n        * Intra-Prediction\n        * Integer Matrix Operations (analogous to x86's VNNI).\n    * Compiler flags: ``-march=armv8.1-a+dotprod`` (gcc/clang-cl) or ``/arch:ARMv8.1`` (MSVC).\n      Since dotprod is a feature, if it exists, we can only be sure that an armv8.1-a system is used.\n\nSee also:\n`The-Armv8-1-architecture-extension <https://developer.arm.com/documentation/109697/2025_12/Feature-descriptions/The-Armv8-1-architecture-extension?lang=en>`__\nand\n`The-Armv8-4-architecture-extension <https://developer.arm.com/documentation/109697/2025_12/Feature-descriptions/The-Armv8-4-architecture-extension?lang=en>`__\n\n- CPUF_ARM_I8MM (8 bit matrix multiplication)\n\n    Another useful instruction set, optional since v8.2-a, mandatory in v8.6-a.\n\nSee also:\n`The-Armv8-2-architecture-extension <https://developer.arm.com/documentation/109697/2025_12/Feature-descriptions/The-Armv8-2-architecture-extension?lang=en#md447-the-armv82-architecture-extension__feat_FEAT_I8MM>`__\nand\n`SIMD-FP-Instructions/USDOT <https://developer.arm.com/documentation/ddi0602/2025-12/SIMD-FP-Instructions/USDOT--vector---Dot-product-with-unsigned-and-signed-integers--vector--?lang=en>`__\n\n- CPUF_ARM_SVE2 (Scalable Vector Extension 2)\n\n    A next leap to scalable vector architecture, we skipped simple SVE in Avisynth.\n\n    * **Minimum Requirement:** ARMv8.5-A (SVE2 feature flag).\n    * **Register Width:** **Scalable Vector Length (SVL)**. This register length is defined by the hardware \n      (e.g., 256-bit or 512-bit) and is uniform across a single processor.\n    * **x86 Analogy:** Comparable to **AVX-512** or **AVX10.2**. Both represent a significant shift to \n      very wide vector processing.\n    * **Usable Instruction Sets:** All SVE2 instructions, which extend SVE with NEON-style operations, \n      providing masked, predicated, and full vector operations.\n    * **Video Processing Relevance:** Designed for maximum performance in HPC and deep learning workloads, \n      this tier offers the largest data throughput per clock cycle for highly parallel operations like \n      convolutions.\n\n- CPUF_ARM_SVE2_1 (Scalable Vector Extension 2.1 FEAT_SVE2p1)\n\n    Even more useful instructions added in ARMv9.1-A\n\n\n.. _AArch64_SIMD_Compilation:\n\nAArch64 SIMD Compilation and Source Code Rules\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nAviSynth utilizes file naming conventions within its source tree to automatically apply the correct, feature-specific compiler flags for AArch64 (ARM64) architectures, \nensuring optimal SIMD performance while maintaining wide compatibility.\n\n1. Source File Location\n.......................\n\nThis is how Avisynth source code is organized for AArch64-specific SIMD implementations:\n\nAll AArch64-specific SIMD C++ files must be located within the **aarch64** subdirectory, parallel to any existing ``intel`` optimization folders.\nCMakeLists.txt is configured to include this directory when building for ARM64 targets and the ``ENABLE_NEON_SIMD`` option is enabled for CMake.\nIn source code we should check ``NEON_INTRINSICS`` define for NEON specific code.\nLike this:\n::\n\n    #include \"turn.h\"\n    #ifdef INTEL_INTRINSICS\n    #include \"intel/turn_sse.h\"\n    #endif\n    #ifdef NEON_INTRINSICS\n    #include \"aarch64/turn_neon.h\"\n    #endif\n\n\n2. File Patterns and Automatic Compiler Options Rule\n....................................................\n\nThe build system (via CMake) uses the file name suffix to select the appropriate compiler flags for the target feature. This ensures that only the intended instructions are generated for each source file.\n\n+-------------------+--------------------------------------------------+------------------------------------+------------------------------------+\n| File Pattern      | Feature / Minimum Arch                           | Compiler Flag (GCC/Clang)          | Compiler Flag (MSVC)               |\n+===================+==================================================+====================================+====================================+\n| ``*_neon.cpp``    | Baseline NEON (ASIMD)                            | Implicit (or ``-march=armv8-a``)   | ``/arch:armv8.0``                  |\n+-------------------+--------------------------------------------------+------------------------------------+------------------------------------+\n| ``*_dp.cpp``      | Dot Product (``FEAT_DotProd``) / ARMv8.1-A       | ``-march=armv8.1-a+dotprod``       | ``/arch:armv8.1``                  |\n+-------------------+--------------------------------------------------+------------------------------------+------------------------------------+\n| ``*_i8mm.cpp``    | Int8 Matrix Multiply (``FEAT_I8MM``) / ARMv8.5-A | ``-march=armv8.2-a+i8mm``          | ``/arch:armv8.2``                  |\n+-------------------+--------------------------------------------------+------------------------------------+------------------------------------+\n| ``*_sve2.cpp``    | Scalable Vector Extension 2                      | ``-march=armv8.5-a+sve2``          | ``/arch:armv8.5``                  |\n|                   | (``FEAT_SVE2``) / ARMv8.5-A                      |                                    |                                    |\n+-------------------+--------------------------------------------------+------------------------------------+------------------------------------+\n| ``*_sve2_1.cpp``  | Scalable Vector Extension 2.1                    | ``-march=armv9.1-a+sve2.1``        | ``/arch:armv9.1``                  |\n|                   | (``FEAT_SVE2p1``) / ARMv9.1-A                    |                                    |                                    |\n+-------------------+--------------------------------------------------+------------------------------------+------------------------------------+\n\n.. note::\n    * MSVC supports the ``/arch:armvX.X`` syntax for convenience, individual features are not supported as separate flags.\n    * This distinction is necessary when targeting features for Clang-cl and gcc, the allowed C++ intrinsics are stricter\n      than in MSVC where if a more modern instruction is used, MSVC will compile it without error. For gcc/llvm/Clang-cl, so-called function attributes \n      (like ``__attribute__((target(\"...\")))`` can enable additional features in a lower-architecture targeted context.\n\n3. Compiler Knowledge of Minimum Version\n........................................\n\nThe flags above explicitly define the minimum architectural version (e.g., ``armv8.2-a``, ``armv8.5-a``) rather than just the baseline ``armv8-a`` plus the feature.\n\n* While modern compilers (GCC, Clang) are generally smart enough to know that the ``+dotprod`` feature only \n  appeared in ``ARMv8.1-A`` (and thus implicitly set the target baseline higher), using the explicit flag (e.g., ``-march=armv8.1-a+dotprod``) \n  provides clarity.\n* **Compiler's Internal Logic:** When a feature flag like ``+dotprod`` is used, the compiler consults its internal definition of the Arm architecture. \n  Since ``dotprod`` instructions are not part of the ``ARMv8.0-A`` baseline, the compiler must allow *all* instructions mandated by the version where \n  the feature first appeared (v8.1-A). Explicitly stating the version ensures all other non-feature-specific architectural improvements are also made \n  available to the compiler.\n\n4. Source Code and Dispatch\n...........................\n\nSpecialized files contain the highly optimized code using the respective **ACLE Intrinsics** (Arm C Language Extensions).\n\n* **Runtime Dispatch:** To correctly use these files, the main filter logic must include runtime CPU feature detection to check the capabilities \n  of the host CPU, Avisynth has its own CPUFlags feature set, which relies on the OS reported hardware capabilities. (e.g., via the Linux ``getauxval()`` \n  or Windows ``IsProcessorFeaturePresent()`` functions).\n* The dispatcher function will then call the appropriate implementation available: ``SVE2 or I8MM -> DOTPROD -> NEON (ASIMD)``.\n\n5. Useful tutorial videos\n.........................\nLVC21-309 SVE & SVE2 in LLVM \nhttps://www.youtube.com/watch?v=v6NmKOkQ2LE\n\nMSVC ARM64 optimization in Visual Studio:\nhttps://www.youtube.com/watch?v=O5XAdeMTRWk\n\nReal-World Use Case: FFmpeg Categorization\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nProjects like FFmpeg use similar feature checks to manage their optimized assembly code paths.\nFFmpeg primarily checks for individual ``hwcap`` bits, which map directly to some of our tiers:\n\n1.  **Baseline:** Determined by the presence of **NEON** (mandatory).\n2.  **Advanced 128-bit:** Primarily determined by the **DOTPROD** flag.\n3.  **I8MM:** Checked via dedicated **I8MM** flags.\n\nThe **DOTPROD** flag is often the most important threshold for enabling the fastest H.264/HEVC/VVC assembly functions.\n\nRaspberry Pi Feature Support\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nFor common single-board computers, the support is as follows:\n\n* **Raspberry Pi 4 (Broadcom BCM2711):** * **CPU:** Quad-core Arm Cortex-A72.\n    * **Architecture:** Supports **ARMv8.2-A**.\n    * **Extensions:** It supports the **DOTPROD** (Dot Product) extension, though it is optional there.\n    * **Category:** Belongs to **CPUF_ARM_DOTPROD**.\n\n* **Raspberry Pi 5 (Broadcom BCM2712):**\n    * **CPU:** Quad-core Arm Cortex-A76.\n    * **Architecture:** Supports **ARMv8.2-A** up to **ARMv8.5-A** features.\n    * **SVE/SVE2 Support:** **The Cortex-A76 core does not support SVE/SVE2.** \n      It supports **DOTPROD** and other extensions that are part of the newer ARMv8.x standards.\n    * **Category:** Belongs to **CPUF_ARM_DOTPROD**, but **NOT CPUF_ARM_SVE2**.\n\n____\n\nBack to :doc:`FilterSDK`\n\n$Date: 2025/12/31 17:40:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/DataAlignment.rst",
    "content": "\n`DataAlignment`_\n================\n\n(Until something more AviSynth related can be written this is from the\n:doc:`AMDOptimizationGuide <AMDOptimizationGuide>`)\n\n\nMemory alignment\n----------------\n\nIn general, avoid misaligned data references. All data whose size is a power\nof two is considered aligned if it is naturally aligned.\n\nFor example:\n\n-   Word accesses are aligned if they access an address divisible by two.\n-   Doubleword accesses are aligned if they access an address divisible\n    by four.\n-   Quadword accesses are aligned if they access an address divisible by\n    eight.\n-   TBYTE accesses are aligned if they access an address divisible by\n    eight.\n\nIn AviSynth each frame is most of the time aligned to an address divideable\nby 16. The exception for this rule is when crop() has been used. Furthermore\neach line is also most of the time aligned to an address divideable by 16 (or\n8 for planar chroma).\n\n\nStore to Load Forwarding\n------------------------\n\nWhenever some data is written to memory it is put in the cache. It is however\npossible for the processor to access this data quite fast after it has been\nwritten. This is called Store To Load forwarding.\n\nAvoid memory-size mismatches when different instructions operate on the same\ndata. When an instruction stores and another instruction reloads the same\ndata, keep their operands aligned and keep the loads/stores of each operand\nthe same size.\n\nThe following code examples result in a store-to-loadforwarding (STLF) stall:\n\n**Example (avoid):**\n\n``MOV [FOO], EAX`` ``MOV [FOO+4], EDX`` ``...`` ``MOVQ MM0, [FOO]``\n\n**Example (preferred):**\n\n``MOV [FOO], EAX`` ``MOV [FOO+4], EDX`` ``...`` ``MOVD MM0, [FOO]``\n``PUNPCKLDQ MM0, [FOO+4]``\n\n**Example (avoid):**\n\n``MOVQ [foo], MM0`` ``...`` ``MOV EAX, [foo]`` ``MOV EDX, [foo+4]``\n\n**Example (preferred):**\n\n``MOVD [foo], MM0`` ``PSWAPD MM0, MM0`` ``MOVD [foo+4], MM0`` ``PSWAPD MM0,\nMM0`` ``...`` ``MOV EAX, [foo]`` ``MOV EDX, [foo+4]``\n\nBack to :doc:`AssemblerOptimizing <AssemblerOptimizing>`\n\n$Date: 2025-02-24 21:32:57-05:00 $\n\n.. _DataAlignment: http://avisynth.nl/index.php/Filter_SDK/Data_alignment\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/DataStorageInAviSynth.rst",
    "content": "\nDataStorageInAviSynth\n=====================\n\n\nPart 1: Actual memory storage\n-----------------------------\n\n**Warning:** *technical.* Most users will only need to read (and understand)\nPart 2.\n\nIn AviSynth, we process pixels of video data. These are stored in the memory\nin the form of data arrays. As noted elsewhere (like the :doc:`AviSynth FAQ <../faq/faq_sections>`)\nthere are two different colorspaces in v1.0x/2.0x, RGB and YUY2, with a third\nYV12 added in v2.5. These colorspaces store their data in different ways.\n\n\nInterleaved formats\n~~~~~~~~~~~~~~~~~~~\n\n**RGB** (also known as RGB24): Every pixel is associated with three bytes of\ndata: one red, one green, and one blue. They are interleaved (mixed) in the\nmemory like this ``RGBRGBRGBRGB``. Since data is most easily read in words of\nfour bytes, most functions actually process 4 pixels at the same time in\norder to be able to read 3 words in a row. Usually memory is allocated as\n``aligned`` which means that it always allocate memory in words of 4 bytes.\nSince the 3 to 4 relation isn't easy to map, RGB24 is very difficult to work\nwith, and in general isn't recommended.\n\n**RGBA** (also known as RGB32): This is an extension of RGB where a fourth\ncolor channel has been added. This is called the alpha channel, and is a\ndefinition of transparency in the pixel. For an explanation of how the alpha\nchannel is used see :doc:`Mask and Layer <../corefilters/layer>`. In general however, you shouldn't rely\non filters processing alpha correctly - in some cases filters will even\nproduce garbage in this channel.\n\nRGBA also makes this a lot easier as it requires four bytes per pixel, and\nthus each memory access of a word, will correspond to exactly one pixel. In\nfact, RGB will only be used if you have a source that returns RGB or if you\nexplicitly use (ConvertToRGB24). :doc:`ConvertToRGB <../corefilters/convert>` will by default create RGBA.\nThis is the recommended format for RGB-data.\n\n**YUY2**: In this colorspace each pair of pixels will share the color data,\nas well as the data being interleaved like this ``YUYV|YUYV|YUYV|YUYV``. A\nmemory access of one word will get all data for **two** pixels. A pair should\nnever be split, as this can create strange artifacts when almost all\nfunctions in YUY2 assumes that they should read a full word and process that.\nEven if they return the right width when they are done, they will most likely\nhave used invalid data when processing valid pixels.\n\n\nPlanar formats\n~~~~~~~~~~~~~~\n\nNow the real fun begins as this is a :doc:`PlanarImageFormat <PlanarImageFormat>`. This means that\ndata is not :doc:`interleaved <InterleavedImageFormat>`, but stored separately for each color channel\n(also called color plane). For filter writers this means that they can write\none simple function that is called three times, one for each color channel,\nassuming that the operations are channel-independent (which is not always the\ncase). Again, using ``aligned`` for both color and luma channels will allow\neasy memory access.\n\n**Y8**: This colorformat is greyscale, i.e. contains no color. It is the only\nformat which is both planar and interleaved.\n\n**YV12**: Four pixels share the color data. These four pixels are a 2x2\nblock, i.e. two pairs on adjacent lines in the same field. As fields\nthemselves are interleaved, this means that for field-based video line 1&3\nshare color data, as well as line 2&4. Frame-based video though has the more\ninstinctive way of sharing color, line 1&2 share just as line 3&4 does. The\n2x2 block should never be split as this may create strange artifacts.\n\n**YV411**: Four pixels share the color data. These four pixels are a 1x4\nblock, i.e. a quadruple. The 1x4 block should never be split as this may\ncreate strange artifacts.\n\n**YV16**: In this colorspace each pair of pixels will share the color data.\nThe pair should never be split as this may create strange artifacts. It is a\nplanar version of YUY2.\n\n**YV24**: This color format has full color, i.e. each pixel has a unique\ncolor (just like RGB and RGBA).\n\n\nPart 2: How does this affect me as a user?\n------------------------------------------\n\n1.  As long as you don't split a colorsharing unit it's up to the\n    filterwriters to take care of problems with memory reading at end of\n    lines.\n2.  Interlaced (fieldbased) video requires double mod on height.\n3.  Required modulos in different colorspaces.\n\n    -   **RGB(A)**\n\n        -   width mod-1 (no restriction)\n        -   height mod-1 (no restriction) *if progressive*\n        -   height mod-2 (even values) *if interlaced*\n\n    -   **YUY2**\n\n        -   width mod-2 (even values)\n        -   height mod-1 (no restriction) *if progressive*\n        -   height mod-2 (even values) *if interlaced*\n\n    -   **Y8**\n\n        -   width mod-1 (no restriction)\n        -   height mod-1 (no restriction) *if progressive*\n        -   height mod-2 (even values) *if interlaced*\n\n    -   **YV411**\n\n        -   width mod-4\n        -   height mod-1 (no restriction) *if progressive*\n        -   height mod-2 (even values) *if interlaced*\n\n    -   **YV12**\n\n        -   width mod-2 (even values)\n        -   height mod-2 (even values) *if progressive*\n        -   height mod-4 *if interlaced*\n\n    -   **YV16**\n\n        -   width mod-2 (even values)\n        -   height mod-1 (no restriction) *if progressive*\n        -   height mod-2 (even values) *if interlaced*\n\n    -   **YV24**\n\n        -   width mod-1 (no restriction)\n        -   height mod-1 (no restriction) *if progressive*\n        -   height mod-2 (even values) *if interlaced*\n\n4.  Examples of valid :doc:`Crops <../corefilters/crop>` with input 320x240 progressive\n\n    -   **RGB(A)**\n\n        -   Crop(1,7,-32,-19)\n        -   Crop(2,4,300,196)\n\n    -   **YUY2**\n\n        -   Crop(2,7,-32,-19)\n        -   Crop(2,4,300,196)\n\n    -   **YV12**\n\n        -   Crop(2,8,-32,-18)\n        -   Crop(2,4,300,196)\n\n5.  Note that final video may have other restrictions, most MPEG-n\n    implementations want mod-16 on all resolutions etc.\n\n\nMore information\n----------------\n\nSee more about :doc:`ColorSpaces <ColorSpaces>`.\n\nSee a general introduction to :doc:`WorkingWithImages <WorkingWithImages>`.\n\n----\n\nThis page is a edited summary of `[this thread at Doom9's forum]`_\n\n----\n\nBack to :doc:`FilterSDK`\n\n$Date: 2025-02-24 21:29:46-05:00 $\n\n.. _DataStorageInAviSynth:\n    http://avisynth.nl/index.php/Filter_SDK/Data_storage\n.. _[this thread at Doom9's forum]:\n    http://forum.doom9.org/showthread.php?s=&threadid=40413&highlight=YV12\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/DebuggingAvisynthPlugins.rst",
    "content": "\nDebugging instructions\n======================\n\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\nHow to debug AviSynth\n---------------------\n\nxx\n\n\nHow to debug AviSynth plugins\n-----------------------------\n\nTwo ways are described to debug your plugin. An easy way using\nDebugView and the use of VC++6's debugger. In both cases, the sample\ncode :doc:`SimpleSample <SimpleSample>` is used.\n\n\nHow to debug AviSynth plugins (the short way)\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nAn easy way to debug AviSynth plugin is to use a utility called\n`DebugView`_ for Windows which captures OutputDebugString's output from\nyour code (OutputDebugString sends a string to your debugger). It's a\nbit limited. So, if this is not sufficient, you should use a debugger\nas described in the next section.\n\n1) Open Dbgview.exe. Make sure that 'Capture Win32' under the Capture\ntab is selected.\n\n2) Add the following line at the start of your code:\n::\n\n    #include <stdio.h> /* for using sprintf */\n\nAdd, for example, the following lines in your code to check whether\ncertain parameters are passed to the code path which comes after it:\n::\n\n    char BUF[256];\n    sprintf(BUF, \"framenr %d, text %s, height %d, pi %f\\n\", n, \"hey\", src_height, 3.14);\n    OutputDebugString(BUF);\n\n\nThus:\n\n.. image:: Pictures/debugging_plugins1a.png\n\nNb, %d means integer, %s means string and %f means float/double. \\n\nmeans add a new line.\n\n| 3) Compile a release build of your plugin.\n\n4) Open your script and scroll through it. You will see the following\noutput in DebugView:\n\n.. image:: Pictures/debugging_plugins1b.png\n\nIn the example the script is loaded in line 26. After that some\nAviSynth output is captured. In the lines 57 and 58 the output of\nOutputDebugString is written.\n\nIf your script crashes somewhere, you should put these lines just\nbefore the crash (it may take a few attempts to find that point). Then\nyou should pass the values of the relevant parameters and check whether\nthey are correct. Apparently there is some parameter whose value is\nempty or invalid.\n\n\nHow to debug Avisynth plugins (for MS VC++ 6.0)\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThese are the steps to debug an AviSynth plugin in VC++ 6:\n\n1. Go to the build tab and set the Active configuration to the Debug\nversion of your plugin.\n\n2. Build the debug version of your plugin. Thus go to the build tab and\nBuild (...).\n\n3. We will use VirtualDub.exe to debug your plugin. Go to Project tab,\nthen select Settings -> Debug -> General -> Executable for debug\nsession -> browse to a version of VirtualDub.exe and specify that:\n\n.. image:: Pictures/debugging_plugins2.png\n\n4. Go to Project tab, then select Settings -> Debug -> Additional DLLs,\nand browse to the filter DLL in the Debug directory:\n\n.. image:: Pictures/debugging_plugins3.png\n\n5. Make an AviSynth script that loads and uses your filter. Make sure\nto load the Debug version of your plugin! Thus for example:\n::\n\n    LoadPlugin(\"F:\\CompilingPlugins\\SimpleSample\\Debug\\simplesample.dll\")\n    Colorbars().Trim(0,1)\n    ConvertTORGB24()\n    SimpleSample(100)\n\n\n6. Set breakpoints as required. You can do this by clicking with the\nright mouse button next to a statement in your code (in the grey\nsection). For example:\n\n.. image:: Pictures/debugging_plugins4.png\n\nSelect the option: Insert/Remove Breakpoint:\n\n.. image:: Pictures/debugging_plugins5.png\n\n7. Go to the Build tab, and select Start Debug -> Go (or the shortcut\nF5). VirtualDub will execute. Open the AviSynth script in that\nVirtualDub instance. The code will execute up to your first breakpoint\n(at least if it follows that code path):\n\n.. image:: Pictures/debugging_plugins6.png\n\nYou will see a yellow arrow through your breakpoint.\n\nAbove I also opened the 'variables output window'. It is under the View\ntab -> Debug Windows -> Variables. You can view the value of the\nvariables when stepping through your code. Use Debug -> Step Into (or\nthe shortcut F11) to step through your code. Use Debug -> Step Over (or\nthe shortcut F10) to step over function calls.\n\nWhen moving your mouse over a variable, you can also see the value of\nit:\n\n.. image:: Pictures/debugging_plugins7.png\n\nIf you want to set a breakpoint somewhere else, just remove the\nexisting one (by right clicking on it). Put a new one somewhere and\npress F5.\n\nIf you want to stop debugging, go to the Debug tab -> Stop Debugging.\n\n\nHow to debug Avisynth plugins (for MS VC++ 2010)\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nOpen your project. Select the debug build and build it. Make sure that\nyou load the debug build in your script.\n\nOpen Virtualdub and attach is to the debugger:\n\nDebug > Attach to Process\n\n.. image:: Pictures/Debugging_plugins_msvc2010_001.jpg\n\nSelect VirtualDub.exe and press attach:\n\n.. image:: Pictures/Debugging_plugins_msvc2010_002.jpg\n\nSet a breakpoint somewhere. You can do this by clicking with the right\nmouse button next to a statement in your code (in the grey section):\n\n.. image:: Pictures/Debugging_plugins_msvc2010_004.jpg\n\nOpen the script in Virtualdub and the code will be executed up to point\nwhere you set the breakpoint.\n\n.. image:: Pictures/Debugging_plugins_msvc2010_005.jpg\n\nInstead of attaching Virtualdub to the debugger every time, you can\nalso do the following:\n\nRight click on the project name (Kuwahara in our case) > Properties >\nConfiguration Properties > Debug\n\nEnter the location of Virtualdub in the debug command:\n\n.. image:: Pictures/Debugging_plugins_msvc2010_003.jpg\n\nIf you set a breakpoint somewhere and start the debugger:\n\nDebug > Start Debugging\n\nIt will open Virtualdub and you can open your script to start the\ndebugging session.\n\n\nHow to debug Avisynth console applications (for MS VC++ 2010)\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nOpen your project. Select the debug build and build it. Make sure that\nyou load the debug build in your script.\n\nRight click on the project name (Kuwahara in our case) > Properties >\nConfiguration Properties > Debug\n\nEnter the location of your console application and its arguments in the\ndebug command (in our case: avs2yuv.exe example.avs clip.raw):\n\n.. image:: Pictures/Debugging_con_applications_msvc2010_001.jpg\n\n.. image:: Pictures/Debugging_con_applications_msvc2010_002.jpg\n\nSet a breakpoint somewhere and start the debugger:\n\nDebug > Start Debugging\n\nIt will open the command prompt and start the console application. The\nscript will be executed to start the debugging session.\n\n\nDebug info from MAP file\n------------------------\n\nIanB `wrote`_: Recent versions of Avisynth now ship with an\navisynth.map! You can use this accurately get routine addresses.\nAvisynth preferably loads at 0x10000000, use the debugger loaded module\ndisplay to check this.\n\nBuild your plugin in debug mode. If you can, build yourself a Debug or\nRelsym avisynth.dll and debug it, if not the use the .map file provided\nto interprete the Call stack addresses.\n\n____\n\nBack to :doc:`FilterSDK`\n\n$Date: 2014/10/27 22:04:54 $\n\n.. _DebugView: http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx\n.. _wrote: http://forum.doom9.org/showthread.php?p=1041578#post1041578\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/DualPlugins.rst",
    "content": "\nDualPlugins\n===========\n\nThere are three ways to make dual plugins. That is 2.6 plugins\n(compiled with plugin api v5) that also work with AviSynth 2.5. They\nare described here below.\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\nThe InvertNeg example\n---------------------\n\nFor InvertNeg it's straightforward to make it as a dual plugin, since\nthe code uses the 2.5 feature set. When using the 2.5+ feature set it\nbecomes more elaborate (and it might not always be possible). See\nSimplesample for such an example.\n\n\nBrute force solution one\n~~~~~~~~~~~~~~~~~~~~~~~~\n\nThis solution doubles all the code. You need to rename avisynth.h (v3)\nto avisynth25.h and avisynth.h (v5) to avisynth26.h and add them both\nto your project. You also need to add the following two source files to\nyour project:\n::\n\n   /* InvertNeg25.cpp */\n\n   #include <windows.h>\n   #include \"avisynth25.h\"\n\n   class InvertNeg25 : public GenericVideoFilter {\n   public:\n      InvertNeg25(PClip _child, IScriptEnvironment* env);\n      PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n   };\n\n   InvertNeg25::InvertNeg25(PClip _child, IScriptEnvironment* env) :\n      GenericVideoFilter(_child) {\n      if (!vi.IsPlanar() || !vi.IsYUV()) {\n         env->ThrowError(\"InvertNeg: planar YUV data only!\");\n      }\n   }\n\n   PVideoFrame __stdcall InvertNeg25::GetFrame(int n, IScriptEnvironment* env) {\n\n      PVideoFrame src = child->GetFrame(n, env);\n      PVideoFrame dst = env->NewVideoFrame(vi);\n\n      const unsigned char* srcp;\n      unsigned char* dstp;\n      int src_pitch, dst_pitch, row_size, height;\n      int p, x, y;\n\n      int planes[] = {PLANAR_Y, PLANAR_V, PLANAR_U};\n\n      for (p=0; p<3; p++) {\n         srcp = src->GetReadPtr(planes[p]);\n         dstp = dst->GetWritePtr(planes[p]);\n\n         src_pitch = src->GetPitch(planes[p]);\n         dst_pitch = dst->GetPitch(planes[p]);\n         row_size = dst->GetRowSize(planes[p]);\n         height = dst->GetHeight(planes[p]);\n\n         for (y = 0; y < height; y++) {\n            for (x = 0; x < row_size; x++) {\n               dstp[x] = srcp[x] ^ 255;\n            }\n            srcp += src_pitch;\n            dstp += dst_pitch;\n         }\n      }\n      return dst;\n   }\n\n   AVSValue __cdecl Create_InvertNeg25(AVSValue args, void* user_data, IScriptEnvironment* env) {\n      return new InvertNeg25(args[0].AsClip(), env);\n   }\n\n   extern \"C\" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env) {\n      env->AddFunction(\"InvertNeg\", \"c\", Create_InvertNeg25, 0);\n      return \"InvertNeg sample plugin\";\n   }\n\n\n::\n\n   /* InvertNeg26.cpp */\n\n   #include <windows.h>\n   #include \"avisynth26.h\"\n\n   class InvertNeg26 : public GenericVideoFilter {\n   public:\n      InvertNeg26(PClip _child, IScriptEnvironment* env);\n      PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n   };\n\n   InvertNeg26::InvertNeg26(PClip _child, IScriptEnvironment* env) :\n      GenericVideoFilter(_child) {\n      if (!vi.IsPlanar() || !vi.IsYUV()) {\n         env->ThrowError(\"InvertNeg: planar YUV data only!\");\n      }\n   }\n\n   PVideoFrame __stdcall InvertNeg26::GetFrame(int n, IScriptEnvironment* env) {\n\n      PVideoFrame src = child->GetFrame(n, env);\n      PVideoFrame dst = env->NewVideoFrame(vi);\n\n      const unsigned char* srcp;\n      unsigned char* dstp;\n      int src_pitch, dst_pitch, row_size, height;\n      int p, x, y;\n\n      int planes[] = {PLANAR_Y, PLANAR_V, PLANAR_U};\n\n      for (p=0; p<3; p++) {\n         srcp = src->GetReadPtr(planes[p]);\n         dstp = dst->GetWritePtr(planes[p]);\n\n         src_pitch = src->GetPitch(planes[p]);\n         dst_pitch = dst->GetPitch(planes[p]);\n         row_size = dst->GetRowSize(planes[p]);\n         height = dst->GetHeight(planes[p]);\n\n         for (y = 0; y < height; y++) {\n            for (x = 0; x < row_size; x++) {\n               dstp[x] = srcp[x] ^ 255;\n            }\n            srcp += src_pitch;\n            dstp += dst_pitch;\n         }\n      }\n      return dst;\n   }\n\n   AVSValue __cdecl Create_InvertNeg26(AVSValue args, void* user_data, IScriptEnvironment* env) {\n      return new InvertNeg26(args[0].AsClip(), env);\n   }\n\n   const AVS_Linkage *AVS_linkage = 0;\n\n   extern \"C\" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors) {\n      AVS_linkage = vectors;\n      env->AddFunction(\"InvertNeg\", \"c\", Create_InvertNeg26, 0);\n      return \"InvertNeg sample plugin\";\n   }\n\n\nNote that both functions Create_InvertNeg25 and Create_InvertNeg26 are\nadded in the function table (by AddFunction) as InvertNeg. Which one is\ncalled by your script will be decided by the AvisynthPluginInit2 and\nAvisynthPluginInit3 entry points (and thus your AviSynth version).\n\nCompile both files into a DLL named InvertNeg.dll. See\n:doc:`compiling instructions <CompilingAvisynthPlugins>`. Now create an\nAviSynth script which looks something like this:\n::\n\n    LoadPlugin(\"d:\\path\\InvertNeg.dll\")\n    clip = BlankClip().ConvertToYV12()\n    return clip.InvertNeg()\n\n\nThe script should work both for AviSynth 2.5 and 2.6.\n\n\nBrute force solution two\n~~~~~~~~~~~~~~~~~~~~~~~~\n\nTo stop having to double your source code you could use the namespace\ntrick the 2.0 import wrapper uses.\n\nPlace all the filter generic code into a separate file,\n\"InvertNeg.hpp\", and #include it twice. Technically you have two copies\nof everything binary, but only a single source code. Note: outside the\nnamespace you uniquely access object names as avs25::name or\navs26::name.\n::\n\n   /* InvertNeg.cpp */\n\n   #include <windows.h>\n\n   namespace avs25 {\n      #include \"avisynth25.h\"\n      #include \"InvertNeg.hpp\"\n   }\n\n   #undef __AVISYNTH_H__ // name must not be included twice in the inclusions\n\n   namespace avs26 {\n      #include \"avisynth26.h\"\n      const AVS_Linkage *AVS_linkage = 0;\n      #include \"InvertNeg.hpp\"\n   }\n\n   extern \"C\" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(avs25::IScriptEnvironment* env) {\n      env->AddFunction(\"InvertNeg\", \"c\", avs25::Create_InvertNeg, 0);\n      return \"InvertNeg sample plugin\";\n   }\n\n   extern \"C\" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(avs26::IScriptEnvironment* env, const avs26::AVS_Linkage* const vectors) {\n      avs26::AVS_linkage = vectors;\n      env->AddFunction(\"InvertNeg\", \"c\", avs26::Create_InvertNeg, 0);\n      return \"InvertNeg sample plugin\";\n   }\n\n\n::\n\n   /* InvertNeg.hpp */\n\n   class InvertNeg : public GenericVideoFilter {\n   public:\n      InvertNeg(PClip _child, IScriptEnvironment* env);\n      PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n   };\n\n   InvertNeg::InvertNeg(PClip _child, IScriptEnvironment* env) :\n      GenericVideoFilter(_child) {\n      if (!vi.IsPlanar() || !vi.IsYUV()) {\n         env->ThrowError(\"InvertNeg: planar YUV data only!\");\n      }\n   }\n\n   PVideoFrame __stdcall InvertNeg::GetFrame(int n, IScriptEnvironment* env) {\n\n      PVideoFrame src = child->GetFrame(n, env);\n      PVideoFrame dst = env->NewVideoFrame(vi);\n\n      const unsigned char* srcp;\n      unsigned char* dstp;\n      int src_pitch, dst_pitch, row_size, height;\n      int p, x, y;\n\n      int planes[] = {PLANAR_Y, PLANAR_V, PLANAR_U};\n\n      for (p=0; p<3; p++) {\n         srcp = src->GetReadPtr(planes[p]);\n         dstp = dst->GetWritePtr(planes[p]);\n\n         src_pitch = src->GetPitch(planes[p]);\n         dst_pitch = dst->GetPitch(planes[p]);\n         row_size = dst->GetRowSize(planes[p]);\n         height = dst->GetHeight(planes[p]);\n\n         for (y = 0; y < height; y++) {\n            for (x = 0; x < row_size; x++) {\n               dstp[x] = srcp[x] ^ 255;\n            }\n            srcp += src_pitch;\n            dstp += dst_pitch;\n         }\n      }\n      return dst;\n   }\n\n   AVSValue __cdecl Create_InvertNeg(AVSValue args, void* user_data, IScriptEnvironment* env) {\n      return new InvertNeg(args[0].AsClip(), env);\n   }\n\n\nCompile this file into a DLL named InvertNeg.dll. See\n:doc:`compiling instructions <CompilingAvisynthPlugins>`. Now create an AviSynth script which\nlooks something like this:\n::\n\n   LoadPlugin(\"d:\\path\\InvertNeg.dll\")\n   clip = BlankClip().ConvertToYV12()\n   return clip.InvertNeg()\n\n\nxxx\n~~~\n\nhttp://forum.doom9.org/showthread.php?p=1641346#post1641346 and\nsubsequent posts ....\n\n\nThe SimpleSample example\n------------------------\n\nThe SimpleSample code uses the 2.5+ feature set, since it uses\nGetPlaneWidthSubsampling and GetPlaneHeightSubsampling. These are\nfunctions of :doc:`VideoInfo`. One way to get it to work is to add these\nfunctions in avisynth25.h in the :doc:`VideoInfo` structure. Note that in\nthis case they are only used for YV12:\n::\n\n   /* avisynth25.h */\n\n   struct VideoInfo {\n      ...\n      // mimics 2.6 functionality for YV12\n      int GetPlaneWidthSubsampling(int plane) const {\n         switch(plane) {\n         case PLANAR_Y:\n            return 0;\n         case PLANAR_U:\n            return 1;\n         case PLANAR_V:\n            return 1;\n         default:\n            return 0;\n         }\n      }\n\n      int GetPlaneHeightSubsampling(int plane) const {\n         switch(plane) {\n         case PLANAR_Y:\n            return 0;\n         case PLANAR_U:\n            return 1;\n         case PLANAR_V:\n            return 1;\n         default:\n            return 0;\n         }\n      }\n   };\n\n\nNow we can place all the filter generic code into a separate file,\n\"simplesample.hpp\", #include it twice, and access object names as\navs25::name or avs26::name.\n::\n\n    /* simplesample.cpp */\n\n    /*\n        SimpleSample plugin for Avisynth -- a simple sample\n        Copyright (C) 2002-2013 Simon Walters, Wilbert Dijkhof, All Rights Reserved\n\n        This program is free software; you can redistribute it and/or modify\n        it under the terms of the GNU General Public License as published by\n        the Free Software Foundation.\n\n        This program is distributed in the hope that it will be useful,\n        but WITHOUT ANY WARRANTY; without even the implied warranty of\n        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n        GNU General Public License for more details.\n\n        You should have received a copy of the GNU General Public License\n        along with this program; if not, write to the Free Software\n        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n        The author can be contacted at:\n        wilbertdijkhof at yahoo.com\n\n        v2.0 - AviSynth 2.6 api (based on v1.6 of Simon Walters)\n        v2.1 - Dual plugin for 2.5 and 2.6\n    */\n\n    #include <windows.h>\n\n    namespace avs25 {\n        #include \"avisynth25.h\"\n        #include \"simplesample.hpp\"\n    }\n\n    #undef __AVISYNTH_H__ // name must not be included twice in the inclusions\n\n    namespace avs26 {\n        #include \"avisynth26.h\"\n        const AVS_Linkage *AVS_linkage = 0;\n        #include \"simplesample.hpp\"\n    }\n\n    extern \"C\" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(avs25::IScriptEnvironment* env) {\n        env->AddFunction(\"SimpleSample\", \"c[size]i\", avs25::Create_SimpleSample, 0);\n        return \"SimpleSample plugin\";\n    }\n\n    extern \"C\" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(avs26::IScriptEnvironment* env, const avs26::AVS_Linkage* const vectors) {\n        avs26::AVS_linkage = vectors;\n        env->AddFunction(\"SimpleSample\", \"c[size]i\", avs26::Create_SimpleSample, 0);\n        return \"SimpleSample plugin\";\n    }\n\n\n::\n\n    /* simplesample.hpp */\n\n    class SimpleSample : public GenericVideoFilter {\n        int SquareSize;\n    public:\n        SimpleSample(PClip _child, int _SquareSize, IScriptEnvironment* env);\n        ~SimpleSample();\n        PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n    };\n\n    SimpleSample::SimpleSample(PClip _child, int _SquareSize, IScriptEnvironment* env) :\n        GenericVideoFilter(_child), SquareSize(_SquareSize) {\n        if (vi.width<SquareSize || vi.height<SquareSize) {\n            env->ThrowError(\"SimpleSample: square doesn't fit into the clip!\");\n        }\n    }\n\n    SimpleSample::~SimpleSample() {}\n\n    PVideoFrame __stdcall SimpleSample::GetFrame(int n, IScriptEnvironment* env) {\n\n        PVideoFrame src = child->GetFrame(n, env);\n        env->MakeWritable(&src);\n\n        unsigned char* srcp = src->GetWritePtr();\n        int src_pitch = src->GetPitch();\n        int src_width = src->GetRowSize();\n        int src_height = src->GetHeight();\n\n        int w, h, woffset;\n\n        if (vi.IsRGB24()) {\n            srcp = srcp + (src_height/2 - SquareSize/2) * src_pitch;\n\n            woffset = src_width/2 - 3*SquareSize/2;\n\n            for (h=0; h<SquareSize; h++) {\n                for (w=0; w<3*SquareSize; w+=3) {\n                    *(srcp + woffset + w) = 255;\n                    *(srcp + woffset + w + 1) = 255;\n                    *(srcp + woffset + w + 2) = 255;\n                }\n                srcp += src_pitch;\n            }\n        }\n        if (vi.IsRGB32()) {\n            srcp = srcp + (src_height/2 - SquareSize/2) * src_pitch;\n\n            woffset = src_width/2 - 4*SquareSize/2;\n\n            for (h=0; h<SquareSize; h++) {\n                for (w=0; w<4*SquareSize; w+=4) {\n                    *(srcp + woffset + w) = 255;\n                    *(srcp + woffset + w + 1) = 255;\n                    *(srcp + woffset + w + 2) = 255;\n                }\n                srcp += src_pitch;\n            }\n        }\n    /*\n        if (vi.IsRGB32()) { // variant 1 - processing a pixel at once\n            srcp = srcp + (src_height/2 - SquareSize/2) * src_pitch;\n\n            woffset = src_width/8 - SquareSize/2;\n\n            for (h=0; h<SquareSize; h++) {\n                for (w=0; w<SquareSize; w++) {\n                    *((unsigned int *)srcp + woffset + w) = 0x00FFFFFF;\n                }\n                srcp += src_pitch;\n            }\n        }\n    */\n    /*\n        if (vi.IsRGB32()) { // variant 2 - processing a pixel at once\n            unsigned int* srcp = (unsigned int*)src->GetWritePtr();\n\n            srcp = srcp + (src_height/2 - SquareSize/2) * src_pitch/4;\n\n            woffset = src_width/8 - SquareSize/2;\n\n            for (h=0; h<SquareSize; h++) {\n                for (w=0; w<SquareSize; w++) {\n                    srcp[woffset + w] = 0x00FFFFFF;\n                }\n                srcp += src_pitch/4;\n            }\n        }\n    */\n        if (vi.IsYUY2()) {\n            srcp = srcp + (src_height/2 - SquareSize/2) * src_pitch;\n\n            woffset = src_width/8 - SquareSize/4;\n\n            for (h=0; h<SquareSize; h++) {\n                for (w=0; w<SquareSize/2; w++) {\n                    *((unsigned int *)srcp + woffset + w) = 0x80EB80EB;\n                }\n                srcp += src_pitch;\n            }\n        }\n        if (vi.IsPlanar() && vi.IsYUV()) {\n\n            int planes[] = {PLANAR_Y, PLANAR_U, PLANAR_V};\n            int square_value[] = {235, 128, 128};\n            int p;\n            int width_sub, height_sub;\n\n            for (p=0; p<3; p++) {\n                srcp = src->GetWritePtr(planes[p]);\n                src_pitch = src->GetPitch(planes[p]);\n                src_width = src->GetRowSize(planes[p]);\n                src_height = src->GetHeight(planes[p]);\n                width_sub = vi.GetPlaneWidthSubsampling(planes[p]);\n                height_sub = vi.GetPlaneHeightSubsampling(planes[p]);\n\n                srcp = srcp + (src_height/2 - (SquareSize>>height_sub)/2) * src_pitch;\n\n                woffset = src_width/2 - (SquareSize>>width_sub)/2;\n\n                for (h=0; h<(SquareSize>>height_sub); h++) {\n                    for (w=0; w<(SquareSize>>width_sub); w++) {\n                        srcp[woffset + w] = square_value[p];\n                    }\n                    srcp += src_pitch;\n                }\n            }\n        }\n\n        return src;\n    }\n\n    AVSValue __cdecl Create_SimpleSample(AVSValue args, void* user_data, IScriptEnvironment* env) {\n        return new SimpleSample(args[0].AsClip(),\n                                args[1].AsInt(100),\n                                env);\n    }\n\n\nCompile this file into a DLL named SimpleSample.dll. See\n:doc:`compiling instructions <CompilingAvisynthPlugins>`. Now create an Avisynth script which\nlooks something like this:\n::\n\n    LoadPlugin(\"d:\\path\\simplesample.dll\")\n    Colorbars().Trim(0,1)\n    ConvertToYV12()\n    # ConvertToYV411() # requires AviSynth 2.6\n    SimpleSample(100)\n\n\n____\n\nBack to :doc:`FilterSDK`\n\n$Date: 2014/10/27 22:04:54 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/EnvInvoke.rst",
    "content": "\nEnvInvoke\n=========\n\n::\n\n  virtual AVSValue Invoke(const char* name, const AVSValue args, const char** arg_names=0);\n\n\nYou can use this to call a script function. There are many script functions\nwhich can be useful from other filters; for example, the Bob filter uses\nSeparateFields, and several source filters use UnalignedSplice. Some\nfunctions, like Weave, are implemented entirely in terms of other functions.\n\nIf you're calling a function taking exactly one argument, you can simply pass\nit in the args parameter; Invoke will convert it into an array for you. In\norder to call a function taking multiple arguments, you will need to create\nthe array yourself; it can be done like this:\n::\n\n  AVSValue args[5] = { clip, 0, true, 4.7, \"my hovercraft is full of eels\" };\n    env->Invoke(\"Frob\", AVSValue(args, 5));\n\nIn this case Frob would need to have a parameter-type string like \"cibfs\" or\n\"cfbfs\" or \"cf.*\".\n\nThe arg_names parameter can be used to specify named arguments. Named\narguments can also be given positionally, if you prefer.\n\nInvoke throws ``IScriptEnvironment :: NotFound`` if it can't find a matching\nfunction prototype. You should be prepared to catch this unless you know that\nthe function exists and will accept the given arguments.\n\nA few examples (grabbed from MipSmooth - it uses invoke a lot):\n::\n\n  try {\n          AVSValue args[1] = { child };\n          PClip reduced =\n          env->Invoke(\"Reduceby2\",AVSValue(args,1)).AsClip();\n      } catch (IScriptEnvironment::NotFound) {\n          env->ThrowError(\"MyFilterError: Whoa! Could not Invoke\n          reduce!\");\n      }\n\n\nThis piece of code calls *ReduceBy2(child)*, and places the result in\n*reduced*. If you need the videoinfo (for whatever reason), you can get by\nrequesting:\n\n::\n\n      VideoInfo reduced_vi = reduced->GetVideoInfo();\n\n\nAnother example (using a resizer)\n\n::\n\n  try {\n          upsizerString=\"LanczosResize\";\n          AVSValue up_args[3] = { child, 384, 288 };\n          PClip resized = env->Invoke(upsizerString,\n          AVSValue(up_args,3)).AsClip();\n      } catch (IScriptEnvironment::NotFound) {\n          env->ThrowError(\"MyFilterError: Whoa! Could not Invoke\n          the resizer!\");\n      }\n\n\nIn general, avoid invoking \"Invoke\" as much as possible. If it can be\navoided, try not to do it every frame, but do it in the constructor, if the\nfilter parameters doesn't change. Invoking on every frame usually brings down\nthe speed of the filter to a fraction of a static filter, at it has to be\ncreated and destroyed every frame.\n\n\nCaching frames from Invoked filters\n-----------------------------------\n\nenv->Invoke does **not** automatically insert a cache after the filter you\ninvoke. That means that each time you request a frame (using GetFrame) from\nthe invoked filter the filter will need to generate the frame. This is not a\nproblem if your filter only requests one unique frame per frame it generates.\n\nIf your filter however needs both the previous, the current and the next\nframe to generate the current frame, the invoked filter will get called three\n(3) times per frame you return.\n\nIt really only needs to be invoked to create the next frame (as the current\nand previous frame can be reused).\n\nTo avoid this scenario, the internal cache filter has been exposed from\nAviSynth 2.5.3, and is available to plugin writers.\n\nTo insert a invoke the cache, invoke it like this:\n\n::\n\n  // We are assuming your invoked filter to be placed in \"PClip resized\" as above.\n      try {\n          AVSValue up_args[1] = { resized };\n          resized = env->Invoke(\"InternalCache\",\n          AVSValue(up_args,1)).AsClip();\n      } catch (IScriptEnvironment::NotFound) {\n         // If the AviSynth version is too low, and the internal\n         cache isn't exposed, we just ignore this situation.\n      }\n\n\nYou can also set cache hints. In the scenario above, where we need one frame\nprior and one frame after the current one, use:\n\n::\n\n        resized->SetCacheHints(CACHE_RANGE,1);\n\n\nUpdate: since AviSynth 2.5.6 the cache range parameter is considered as a\n'diameter'=1+radius*2. It equal to 3 in the scenario above (previous, current\nand next frame), so use:\n\n::\n\n        resized->SetCacheHints(CACHE_RANGE,3);\n\n----\n\nBack to :doc:`FilterSDK`\n\n$Date: 2014/10/27 22:04:54 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/EnvSaveString.rst",
    "content": "\nEnvSaveString\n=============\n\n**env->SaveString** is given to allow users to pass strings to AVSValue, and\nensure that they are being deallocated on unload.\n\nAn Example:\n\n::\n\n    fnpluginnew = new char[string_len];\n    strcpy(fnpluginnew, fnplugin.AsString());\n    strcat(fnpluginnew, \" \");\n    strcat(fnpluginnew, name);\n\n    env->SetGlobalVar(\"$PluginFunctions$\", AVSValue(env->SaveString(fnpluginnew, string_len)));\n\n    // Since fnpluginnew has now been saved it can safely be deleted.\n    delete[] fnpluginnew;\n\n\nBut you must still remember that these strings are not deallocated until the\nfilter is unloaded.\n\nSo in general if you don't want your filter to be allocating more memory on\neach load, try avoiding using non-const strings.\n\n----\n\nBack to :doc:`FilterSDK`\n\n$Date: 2006/11/24 18:21:26 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/FilterSDK.rst",
    "content": "\nAviSynth FilterSDK\n==================\n\nNote: May not fully up-to-date\n\nAviSynth external Filter SDK is a package for developers to create your own\nfilters (plugins and console applications) for AviSynth.\n\nThe package consists of:\n\n-   these documentation text files (in HTML or Wiki format);\n-   the header file 'avisynth.h' (recent version) with all declarations\n    to include in plugin source code;\n-   several plugin and console application source codes;\n-   some extra files in 'Extra' folder.\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\nNecessary software\n------------------\n\nYou must have some :doc:`necessary software. <SDKNecessaries>`\n\nWriting a plugin\n----------------\n\nWe will start by writing some simple plugins to show you the basics.\n\nProcessing video\n~~~~~~~~~~~~~~~~\n\n* :doc:`InvertNeg` produces a photo-negative of the input clip.\n* :doc:`SimpleSample` has some very simple examples covering development\n  of a filter that draws a variable sized square, in the middle of\n  the screen. It does so for all color formats.\n\nOne thing not covered in SimpleSample, is how to :doc:`change frame size <ChangeFrameSize>` in a\nfilter.\n\nProcessing audio\n~~~~~~~~~~~~~~~~\n\n* xxx\n\nAlso have a look at :doc:`Getting started with Audio <GettingStartedWithAudio>`.\n\nRuntime functions\n~~~~~~~~~~~~~~~~~\n\nSee :doc:`Non-clip sample <Non-ClipSample>` how to create runtime AviSynth functions.\n\nSource filters\n~~~~~~~~~~~~~~\n\n* :doc:`GradientMask <GradientMask>` creates a simple Gradient. The example explains a\n  few things how source filters work.\n\nSpeeding up your plugin using assembler\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\ntodo: having SIMD intrinsic widespread this topic is a bit outdated:\nYou can also browse various topic on :doc:`Assembler Optimizing <AssemblerOptimizing>`.\n\nMaking dual plugins\n~~~~~~~~~~~~~~~~~~~\n\nThis old topic once was about making dual 2.5 and 2.6 plugins.\nNow in 2020 it is still important to give support earlier (now it's the 2.6) interface\nwhich is used by earlier Avisynth+ and classic Avisynth 2.6.\n\nOne of the features of AviSynth+ is that 2.6 plugins (plugins compiled with plugin\napi v6) can still be used in AviSynth+.\nAvisynth+ evolved from classic Avisynth 2.6 so this is no wonder.\nThere are differences though since AviSynth+ introduced high bit depth\nvideo handling and there came new support functions. AviSynth+'s avisynth.h is\nresponsible for the compatibility, functions which did not exist in classic Avisynth\n(such as BitsPerComponent() for VideoInfo) return a compatible value (8 in this\ncase since Avisynth 2.6 handled only 8 bit videos)\n\nBeginning with the v8 (v8.1 for C interface due to early bugs) interface - frame property \nsupport - dual interfaces became important again. Plugins have to be able to detect the \navailability of v8 interface and behave accordingly.\n\n(todo: They are described :doc:`here <DualPlugins>`).\n\nWriting console applications that access AviSynth\n-------------------------------------------------\n\nWhen writing console applications (commandline programs) it is possible\nto access AviSynth in two ways.\n\nThe first one is to use the VfW api (using the `AVIFile library`_)\nlike is done in avs2avi (see `[1]`_ or `[2]`_), avs2yuv (`using\nthe C api`_, or `using the C++ api`_), or `avs2wav`_ for example. See\nalso `here`_ to get you going.\n\nThe second one is to call AviSynth directly like is done in\n`avs2pipe`_ for example (it uses the C api). It's a tool to output y4m\nvideo or wav audio to stdout. The way to do this is importing\navisynth.dll via loadlibrary() and getprocaddress(). Then creating a\nscriptenvironment and importing a script using invoke(). At that point\nyou will have a clip from which you can call getframe() to access the\nvideo and getaudio() to access the audio.\n\nFor C api clients see the examples (ffmpeg, x265, x264, avs2yuv) here:\n:doc:`Introducing to C API <C_api>`.\n\nBelow are some examples that have a script as input and raw video or\naudio as output:\n\n* :doc:`avs2yuv` reads a script and outputs raw video.\n* :doc:`avs2pcm` reads a script and outputs raw audio.\n\nCompiling plugins and console applications that access AviSynth\n---------------------------------------------------------------\n\nHow to compile plugins and console applications that access AviSynth is\ndescribed :doc:`here <CompilingAvisynthPlugins>`.\n\nDebugging plugins and console applications that access AviSynth\n---------------------------------------------------------------\n\nHow to debug plugins and console applications that access AviSynth is\ndescribed :doc:`here <DebuggingAvisynthPlugins>`.\n\nAviSynth and its plugin api's\n-----------------------------\n\nAviSynth exists as an instance of the ScriptEnvironment class, that\nimplements the IScriptEnvironment interface. The IScriptEnvironment\ninterface is defined in avisynth.h (and avisynth_c.h) and it is the\nonly way for plugins and external applications to communicate with\nAviSynth. A pointer to ScriptEnvironment object is passed along to all\nplugins, so that they can use AviSynth facilities. Plugins are\nforbidden from storing this pointer. AviSynth creates one\nScriptEnvironment object when Windows attempts to use AviSynth to open\na script via AVIFile API.\n\nWhen ScriptEnvironment is created, it checks for CPU extensions (to\nprovide this information to filters that are able to use CPU\nextensions), sets up memory limits for itself and performs pre-scanning\nof all plugins.\n\nAviSynth has the capability to load third-party libraries that include\ntheir own video and audio filters. It comes with two language\ninterfaces (or plugin api's):\n\n* C++ API (through avisynth.h) - The classes and miscellaneous\n  constants are described in :doc:`here <Cplusplus_api>`.\n* C API (through avisynth_c.h) - The classes and miscellaneous\n  constants are described in :doc:`here <C_api>`.\n\nThe built-in filters use the C++ API. This Filter SDK (or Source\nDevelopment Kit) describes how to create plugins using both interfaces.\n\nAlthough not included in AviSynth itself, several people wrote other\nlanguage interfaces in Delphi, Purebasic, NET and Java. They can be\nfound `here <http://forum.doom9.org/showthread.php?p=566904#post566904>`__.\n(comment from 2025: update needed)\n\n...\n\nThere are several different Colorspaces in AviSynth. See more information\nabout :doc:`Color Spaces <ColorSpaces>` and :doc:`Working With Images <WorkingWithImages>`.\n\nWhat's new in the 2.6 api\n-------------------------\n\n- C++ API (AVISYNTH_INTERFACE_VERSION = 6):\n\n    - Plugin api v3 and older contained :doc:`baked code <AVSLinkage>` meaning code\n      that is \"baked\" into all and every plugin instead being called\n      from avisynth.dll. Starting from 2.6 the version 2.5 plugins\n      are supported directly (with current baked code; meaning that\n      plugins compiled for 2.5 can be loaded when using 2.6) and all\n      the baked code from 2.6+ plugins is removed and the plugins\n      are still source compatible. Note that the baked code is moved\n      to interface.cpp, where also the structure :doc:`AVS_Linkage <AVSLinkage>` is\n      defined.\n    - The :ref:`IScriptEnvironment <cplusplus_iscriptenvironment>` interface has several new members:\n\n        - :ref:`ApplyMessage <cplusplus_applymessage>` writes text on a frame.\n        - :ref:`DeleteScriptEnvironment <cplusplus_deletescriptenvironment>` provides a method to delete\n          the ScriptEnvironment which is created with\n          CreateScriptEnvironment.\n        - :ref:`GetAVSLinkage <cplusplus_getavslinkage>` returns the AVSLinkage.\n        - :ref:`GetVarDef <cplusplus_getvardef>` can be used to access AviSynth variables.\n          It will not throw an error if the variable doesn't exist.\n\n    - Avisynth+ header still uses integer for things that are memory sizes (e.g. pitch)\n      This only affects x64 versions.\n      (Although Avisynth 2.6 defined them as size_t, AviSynth+ developers have left it as integer.\n      AviSynth 2.6 had never reached a widespread x64 version so AviSynth+ variant \"won\")\n    - New colorformats are added: Y8, YV411, YV16 and YV24.\n      AviSynth+ extended these formats with 10, 12, 14, 16 bit integer and 32 bit floating point formats.\n      Aside from 411, all other 4:2:0, 4:2:2 and 4:4:4 formats are available at higher bit depths.\n      AviSynth+ introduced planar RGB formats for all the above mentioned bit depths.\n      RGB48 and RGB64 is available as the 16 bit variants of RGB24 and RGB32 packed RGB formats.\n      Alpha plane option was added for YUV (YUVA) and planar RGB formats (Planar RGBA).\n    - :doc:`VideoInfo` has several new constants and functions (the\n      ones relating to the new colorformats, the chroma placement\n      constants, GetPlaneHeightSubsampling,\n      GetPlaneWidthSubsampling).\n      And in AviSynth+:\n      BitsPerComponent, NumComponents, ComponentSize\n      IsRGB48, IsRGB64, Is420, Is422, Is444, IsY,\n      IsYUVA, IsPlanarRGB, IsPlanarRGBA\n    - Some new cache and cpu constants for GetCPUFlags (the v5/v6 ones).\n      In AviSynth+: CPU constants up to AVX512F, AVX512BW and on.\n    - SetCacheHints changed from void to int.\n    - AviSynth+: SetCacheHints constants helping automatic MT mode registration for plugins\n\n- C API (AVISYNTH_INTERFACE_VERSION = 6):\n    - The following functions are added to the interface:\n      avs_is_yv24, avs_is_yv16, avs_is_yv12, avs_is_yv411,\n      avs_is_y8, avs_is_color_space,\n      avs_get_plane_width_subsampling,\n      avs_get_plane_height_subsampling, avs_bits_per_pixel,\n      avs_bytes_from_pixels, avs_row_size, avs_bmp_size,\n      avs_get_row_size_p, avs_get_height_p and\n      avs_delete_script_environment.\n    - And in AviSynth+:\n      avs_is_rgb48, avs_is_rgb64,\n      avs_is_444, avs_is_422, avs_is_420, avs_is_y,\n      avs_is_yuva, avs_is_planar_rgb, avs_is_planar_rgba\n      avs_num_components, avs_component_size and avs_bits_per_component\n      (and others which are not mentioned because they are deprecated)\n\nWhat's new in the api V8\n------------------------\n\n- C++ API (AVISYNTH_INTERFACE_VERSION = 8):\n    - The :ref:`IScriptEnvironment <cplusplus_iscriptenvironment>` interface has several new members:\n\n        - :ref:`SubframePlanarA <cplusplus_subframeplanara>` alpha aware version of SubframePlanar.\n\n        - :ref:`copyFrameProps <cplusplus_copyframeprops>` copy frame properties between video frames.\n        - :ref:`getFramePropsRO <cplusplus_getframepropsro>` get pointer for reading frame properties\n        - :ref:`getFramePropsRW <cplusplus_getframePropsrw>` get pointer for reading/writing frame properties.\n\n        - :ref:`propNumKeys <cplusplus_propnumkeys>` get number of frame properties for a frame.\n\n        - :ref:`propGetKey <cplusplus_propgetkey>` get name of key by index.\n        - :ref:`propNumElements <cplusplus_propnumelements>` get array size of a property.\n        - :ref:`propGetType <cplusplus_propGetType>` get property data type.\n\n        - :ref:`propGetInt <cplusplus_propgetint>` get property value as integer (int64).\n        - :ref:`propGetFloat <cplusplus_propgetfloat>` get property value as float (double).\n        - :ref:`propGetData <cplusplus_propgetdata>` get property value as string buffer.\n        - :ref:`propGetDataSize <cplusplus_propgetdatasize>` get string/data buffer size.\n        - :ref:`propGetClip <cplusplus_propgetclip>` get property value as Clip.\n        - :ref:`propGetFrame <cplusplus_propgetframe>` get property value as Frame.\n\n        - :ref:`propDeleteKey <cplusplus_propdeletekey>` removes a frame property by name (key).\n\n        - :ref:`propSetInt <cplusplus_propsetint>` sets integer (int64) frame property.\n        - :ref:`propSetFloat <cplusplus_propsetfloat>` sets float (double) frame property.\n        - :ref:`propSetData <cplusplus_propsetdata>` sets string (byte buffer) frame property.\n        - :ref:`propSetClip <cplusplus_propsetclip>` sets PClip type frame property.\n        - :ref:`propSetFrame <cplusplus_propsetframe>` sets PVideoFrame type frame property..\n\n        - :ref:`propGetIntArray <cplusplus_propgetintarray>` array version of propGetInt.\n        - :ref:`propGetFloatArray <cplusplus_propgetfloatarray>` array version of propGetFloat.\n        - :ref:`propSetIntArray <cplusplus_propsetintarray>` array version of propSetInt.\n        - :ref:`propSetFloatArray <cplusplus_propsetfloatarray>` array version of propSetFloat.\n\n        - :ref:`createMap <cplusplus_createmap>` internal use only, creating frame property buffer.\n        - :ref:`freeMap <cplusplus_freemap>` internal use only, frees up frame property buffer.\n        - :ref:`clearMap <cplusplus_clearmap>` clears all properties for a frame.\n\n        - :ref:`NewVideoFrameP <cplusplus_newvideoframep>` NewVideoFrame with frame property source.\n\n        - :ref:`GetEnvProperty <cplusplus_getenvproperty>` Query to ask for various system (not frame!) properties.\n\n        - :ref:`Allocate <cplusplus_allocate>` buffer pool allocate.\n        - :ref:`Free <cplusplus_free>` buffer pool free.\n\n        - :ref:`GetVarTry <cplusplus_getvartry>` get variable with success indicator.\n        - :ref:`GetVarBool <cplusplus_getvarbool>` get bool value with default.\n        - :ref:`GetVarInt <cplusplus_getvarint>` get int value with default.\n        - :ref:`GetVarDouble <cplusplus_getvardouble>` get floating point value with default.\n        - :ref:`GetVarString <cplusplus_getvarstring>` get string with default.\n        - :ref:`GetVarLong <cplusplus_getvarlong>` get int64 with default.\n\n        - enumeration constants for frame property, system property access\n        - various other constants (MT modes, cache modes)\n\n- C API (AVISYNTH_INTERFACE_VERSION = 8):\n        - mostly the same functions as provided in C++ interface.\n          Naming convention is kept. E.g. propSetFloat in C++ is prop_set_float in C\n        - Important note: frame property access in V8 is broken. Safely available since V8.1.\n          or check simply for V9 like ffmpeg does.\n\n- C API (AVISYNTH_INTERFACE_VERSION = 8, AVISYNTH_INTERFACE_BUGFIX = 1):\n        - working frame property access (see v9 comments for fixes)\n\nWhat's new in the API V9\n------------------------\n\n- C and C++ API (AVISYNTH_INTERFACE_VERSION = 9):\n        - :ref:`MakePropertyWritable <cplusplus_makepropertywritable>` like MakeWritable but for frame properties only.\n        - :ref:`IsPropertyWritable <cplusplus_ispropertywritable>` like IsWritable but for frame properties only.\n        - C interface equivalents: avs_make_property_writable and avs_is_property_writable\n\n- C API (AVISYNTH_INTERFACE_VERSION = 9, AVISYNTH_INTERFACE_BUGFIX = 1):\n        - Fix: C interface crash when using avs_new_video_frame_p(_a)\n        - Fix: C interface avs_prop_get_data behave like C++ counterpart.\n\n- C API (AVISYNTH_INTERFACE_VERSION = 9, AVISYNTH_INTERFACE_BUGFIX = 2):\n        - Fix: C API undefined behavior when upstream throw runtime error\n\nWhat's new in the API V10\n-------------------------\n\n- C and C++ API (AVISYNTH_INTERFACE_VERSION = 10):\n        - Technical fix: made ``VideoFrameBuffer`` destructor public like in other classes of the public API to prevent compiler errors downstream when calling non-const member functions\n        - New: :ref:`VideoFrame <cplusplus_videoframe>` (c++) and AVS_VideoFrame (c) now have its own pixel_type field. Before, there was no reliable way of knowing it on a frame from :ref:`propGetFrame <cplusplus_propgetframe>`.\n        - New: :ref:`VideoFrame::GetPixelType <cplusplus_getpixeltype>` (avs_video_frame_get_pixel_type) returns the video format of a VideoFrame, ideally kept in sync with VideoInfo::pixel_type.\n        - New: :ref:`VideoFrame::AmendPixelType <cplusplus_amendpixeltype>` (avs_video_frame_amend_pixel_type) changes the pixel_type field of a VideoFrame (special cases)\n\n          C interface equivalents: avs_video_frame_get_pixel_type and avs_video_frame_amend_pixel_type\n        - New: :ref:`AVSValue::GetType <cplusplus_avsvaluegettype>` returns the underlying type directly\n        - Added ``AvsValueType`` enum for the above case to avisynth.h\n        - Added DEFAULT_PLANE and AVS_DEFAULT_PLANE to plane enum (avisynth.h, avisynth_c.h)\n        - Gave all enums of public C++ API a name (avisynth.h): AvsVersion, AvsSampleType, AvsPlane, AvsColorFormat, AvsImageTypeFlags, AvsChromaPlacement\n        - prop_src argument of :ref:`NewVideoFrameP <cplusplus_newvideoframep>` (c++) and of 'avs_new_video_frame_p' (c) is now const\n        - New: :ref:`VideoInfo::GetChannelMask <videoinfo_getchannelmask>` (c++) and 'avs_get_channel_mask' (c) Audio channel layout support. returns the channel mask stored in VideoInfo struct\n        - New: :ref:`VideoInfo::SetChannelMask <videoinfo_setchannelmask>` (c++) and 'avs_set_channel_mask' Audio channel layout support. sets the validity and the layout mask value into VideoInfo\n        - New: :ref:`VideoInfo::IsChannelMaskKnown <videoinfo_ischannelmaskknown>` (c++) and 'avs_is_channel_mask_known' (c) Audio channel layout support. Returns if clip has valid channel mask in its VideoInfo\n\n.. _api_v11_whats_new:\n\nWhat's new in the API V11\n-------------------------\n\n- C and C++ API (AVISYNTH_INTERFACE_VERSION = 11):\n        - General: support 64 bit data types in ``AVSValue``/``AVS_Value``: ``double`` and ``long`` (``int64_t``), also for 32 bit Avisynth!\n        - C++ interface\n        \n          - changed: ``AVSValue::IsFloat`` true for any 32/64 bit floating point or integer types\n          - changed: ``AVSValue::IsInt`` true for any 32/64 bit integer types\n          - new: ``AVSValue::IsFloatfStrict`` : returns true only if AVSValue is stricly 32 bit float\n          - new: ``AVSValue::IsLongStrict`` : returns true only if AVSValue is stricly 64 bit integer\n          - new: ``AVSValue::AsLong`` : returns int64_t\n          - new: ``AVSValue::AsLong(int64_t def)``\n          - No change: since AsFloat return type was double --> no change, it retrieves double values as well\n          - new AVSValue constructors for 64 bit types\n          - new: ``IScriptInterface::propGetIntSaturated`` and ``IScriptInterface::propGetFloatSaturated``\n          - new: ``IScriptInterface::propGetDataTypeHint`` and ``IScriptInterface::propSetDataH``\n          - New enum ``AVSPropDataTypeHint``: ``DATATYPEHINT_UNKNOWN``, ``DATATYPEHINT_BINARY`` and ``DATATYPEHINT_UTF8``.\n          \n        - C interface\n\n          - New getter API calls: ``avs_get_as_long``, ``avs_get_as_int``, ``avs_get_as_float``\n            and the rest: ``avs_get_as_bool``, ``avs_get_as_string``, ``avs_get_as_error``, ``avs_get_as_array``\n          \n          - New API call for array size query: ``avs_get_array_size``\n          - New API call for array (or array-like value) content: ``avs_get_array_elt``\n          - Modified INLINE typecheck and getter helpers for 64-bit data type awareness:\n            \n            * ``avs_is_int``, ``avs_is_float``\n            * ``avs_as_int``, ``avs_as_float``\n          \n          - New INLINE type check helpers:\n            \n            * ``avs_is_long_strict``, ``avs_is_floatf_strict``\n\n          - New INLINE getter helpers for 64-bit data (prefer using API calls):\n\n            * ``avs_as_long``, ``avs_as_float``\n          - New setter API calls: \n            \n            * ``avs_set_to_double``, ``avs_set_to_long``\n            * ``avs_set_to_array`` (deep arrays, deep copy, standard in AviSynth+)\n              (Note: avs_release_value and avs_copy_value are required for destruct or copy arrays)\n          - API version of existing INLINE value setters (``new_value_xxx``) for the rest value types, to make the world round:\n            \n            * ``avs_set_to_error``, ``avs_set_to_bool``, ``avs_set_to_int``, ``avs_set_to_float``, ``avs_set_to_string``\n            \n          - new API function for assign a 'v'oid undefined value to AVS_Value\n          \n            * ``avs_set_to_void``\n            \n          - API version of existing INLINE type checks\n          \n            * ``avs_val_defined``, ``avs_val_is_error``, ``avs_val_is_bool``, ``avs_val_is_int``, ``avs_val_is_string``,\n              ``avs_val_is_float``, ``avs_val_is_floatf_strict``, ``avs_val_is_long_strict``, ``avs_val_is_array``\n           \n          - New optional plugin entry point: ``avisynth_c_plugin_init2``\n            \n            * A C plugin signals to AviSynth that it is V11 interface (64-bit data) ready by implementing ``avisynth_c_plugin_init2`` as well.\n            * ``avisynth_c_plugin_init2`` has the same signature as ``avisynth_c_plugin_init`` and can\n              simply call forward to the old ``avisynth_c_plugin_init`` entry point. Both entry points can be implemented; \n              AviSynth+ will first check ``avisynth_c_plugin_init2``, then ``avisynth_c_plugin_init``.\n              Don't forget to add a new \n              ::\n              \n                avisynth_c_plugin_init2@4 = _avisynth_c_plugin_init2@4\n                \n              line to your existing .def file on Win32.\n              \n          - New ``avs_prop_get_int_saturated`` and ``avs_prop_get_float_saturated``\n          - New ``avs_prop_get_data_type_hint`` and ``avs_prop_set_data_h``\n          - New constants AVS_PROPDATATYPEHINT_UNKNOWN, AVS_PROPDATATYPEHINT_BINARY and AVS_PROPDATATYPEHINT_UTF8\n          \n          - New alternative avs_add_function_r and APPLYFUNCR functions for cases where the callback cannot return \n            AVS_Value struct (functions/filters written Python / ctypes)\n\n          - Deprecated inline helper functions. \n            \n            * ``avs_get_pitch`` => ``avs_get_pitch_p(p, AVS_DEFAULT_PLANE)``\n            * ``avs_get_row_size`` => ``avs_get_row_size_p(p, AVS_DEFAULT_PLANE``)\n            * ``avs_get_height`` => ``avs_get_height_p(p, AVS_DEFAULT_PLANE)``\n            * ``avs_get_read_ptr`` => ``avs_get_read_ptr_p(p, AVS_DEFAULT_PLANE)``\n            * ``avs_get_write_ptr`` => ``avs_get_write_ptr_p(p, AVS_DEFAULT_PLANE)``\n            * ``avs_release_frame`` => ``avs_release_video_frame``\n            * ``avs_copy_frame`` => ``avs_copy_video_frame``\n            * Use ``#define AVSC_ALLOW_DEPRECATED`` before including ``avisynth_c.h`` if they still need for you, \n              but better fix your code: use the recommended replacements.\n              \n          - Add missing ``AVS_MT_xxxx mode`` constants to ``avisynth_c.h`` (similar to c++ ``avisynth.h`` header ``enum MtMode``)\n\n.. _api_v12_whats_new:\n\nWhat's new in the API V12\n-------------------------\n\n- C and C++ API (AVISYNTH_INTERFACE_VERSION = 12):\n        - Global Lock support: \n\n          * ``env->AcquireGlobalLock``, ``env->ReleaseGlobalLock`` (C++),\n          * ``avs_acquire_global_lock``, ``avs_release_global_lock`` (C)\n          \n          See :ref:`global lock support<cplusplus_acquiregloballock>`\n\n        - new ``CachePolicyHint::CACHE_INFORM_NUM_THREADS`` enum to inform the filter about the \n          number of threads by ``SetCacheHints`` (C interface: ``AVS_CACHE_INFORM_NUM_THREADS`` \n          and ``avs_set_cache_hints``).\n          See :ref:`SetCacheHints<cplusplus_setcachehints>` .\n\n        - wider GetCPUFlagsEx() \n\n          * ``env->GetCPUFlagsEx`` (C++),\n          * ``avs_get_cpu_flags_ex`` (C)\n\n          See :ref:`Getting CPU Flags<cplusplus_getcpuflags>`\n\n        - L2 query with new ``AvsEnvProperty``:\n        \n          * ``AEP_CACHESIZE_L2`` (C++), \n          * ``AVS_AEP_CACHESIZE_L2`` (C) \n          \n          to query L2 cache size in bytes by ``IScriptEnvironment->GetEnvProperty()``.\n          x86/x64 architecture only for now. See :ref:`AvsEnvProperty<cplusplus_getenvproperty>` .\n\n          See :ref:`GetEnvProperty<cplusplus_getenvproperty>` .\n\n        - ARM64 (aarch64) CPU flags\n\n- C++ API\n\n          * ``env->ApplyMessageEx`` (C++),\n          \n          see :ref:`ApplyMessageEx<cplusplus_applymessage>`\n\nSome history\n------------\n\n:doc:`Ben's AviSynth Docs <BensAviSynthDocs>` is the documentation written for AviSynth 1.0\nby Ben Rudiak-Gould, in its original form.\n\nSee more about the modifications for AviSynth 2.5 in the :doc:`AviSynth Two-Five SDK <AviSynthTwoFiveSDK>`.\n\nPlease read AviSynth :doc:`SDK History <SDKHistory>`. ---\n\nOther sources ???\n-----------------\n\nOnce you've got the basics down on AVS development (Ben's text is quite\ngood), the `[SDK]`_ for VirtualDub is also a good read. Good news is you\nwon't have to worry about writing `[function pointers]`_ and `[raw Win32]`_;\nmeanwhile, Avery knows his stuff when it comes to video & CPU optimization\ntechniques, so you better pay attention.\n\nSome video related ebooks (PDF) can be downloaded freely from `[Snell & Wilcox]`_. edit -\n`this`_???\n\nLicense terms\n-------------\n\nNote: Avisynth Filter SDK parts are under specific :doc:`SDK license <SDKLicense>` terms.\n\n$Date: 2025/12/02 15:36:00 $\n\nLatest online Avisynth+ version is at https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/FilterSDK/FilterSDK.html\nThis one is maintained properly.\n\nLatest online mediaWiki version is at http://avisynth.nl/index.php/Filter_SDK\n\n.. _[SDK]: http://virtualdub.org/filtersdk\n.. _[function pointers]: http://function-pointer.org/\n.. _[raw Win32]: http://www.charlespetzold.com/pw5/index.html\n.. _[Snell & Wilcox]: http://www.snellwilcox.com/reference.html\n.. _[AviSynth Development forum]:\n    http://forum.doom9.org/forumdisplay.php?s=&f=69\n.. _AVIFile library: http://msdn.microsoft.com/en-us/library/windows/desktop/dd756808(v=vs.85).aspx\n.. _[1]: http://forum.doom9.org/showthread.php?t=71493\n.. _[2]: http://www.avisynth.info/?%E3%82%A2%E3%83%BC%E3%82%AB%E3%82%A4%E3%83%96#t952b3b1\n.. _using the C api: http://komisar.gin.by/tools/avs2yuv/avs2yuv-0.24bm2.zip\n.. _using the C++ api: http://kemuri9.net/dev/avs/avs2yuv/avs2yuv.zip\n.. _avs2wav: http://forum.doom9.org/showthread.php?p=1502613#post1502613\n.. _here: http://forum.doom9.org/showthread.php?p=589781#post589781\n.. _avs2pipe: http://forum.doom9.org/showthread.php?t=160383\n.. _this: http://www.snellgroup.com/support/documentation/engineering-guides\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/GeneralPurposeToMMXRegisters.rst",
    "content": "\nGeneral Purpose To MMX Registers\n================================\n\n\nOverview\n--------\n\nIt might be necessary to move data back and forth between a general purpose\nregister (EAX for instance) to an MMX register. This can be done by:\n\n``movd eax,mm0``\n\n``movd mm0,eax``\n\n``pinsrw mm0,eax,0``\n\n``pextrw eax,mm0,0``\n\n``movmskb eax,mm0``\n\nThese instructions should however **be avoided as much as possible** since\nthey are executing very slow. It seems like there are severe penalties when\nmoving data between the MMX registers and the general purpose registers. Most\nof these instructions take more than 16 cycles to execute, which is more than\n8 times the cyclecount of normal MMX instructions.\n\nIn many cases it is actually faster to write the data to a temporary memory\nlocation, using movd, and move the data back into the registry. For much data\nit is actually often faster to process the data one line at the time, and\nstore all data in a temporary space, and process the data in a separate loop.\n\n----\n\n*phaeron writes:*\n\nNote that the Microsoft Visual C++ compiler will give you trouble here if you\nare using MMX intrinsics, as it is unable to directly generate ``movd\nmmreg,mem`` and ``movd mem,mmreg`` instructions for the ``_m_to_int()`` and\n``_m_from_int()`` intrinsics. Instead, the values trampoline off of the\ngeneral purpose registers, triggering the undesirable performance behavior\ndescribed above. This is true even with the Visual Studio .NET 2003 compiler\n(VC7.1), which fixed most of the MMX code generation embarrassments from the\nVC6PP and VC7 compilers, most notably MOVQ hell. As such, you're still better\noff sticking with inline or explicit assembly than using MMX intrinsics with\nMSVC.\n\n----\n\nBack to :doc:`AssemblerOptimizing <AssemblerOptimizing>`\n\n$Date: 2006/11/08 20:40:17 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/GettingStartedWithAudio.rst",
    "content": "\nGetting started with audio\n==========================\n\nThe best filters to take a look at if you are searching for a way to get\nstarted with an audio filter is the internal audio filters of AviSynth.\nMainly `audio.cpp`_ is interesting.\n\nBasically you override GetAudio(...) instead of GetFrame, and fill the buffer\nwith data. A simple filter could look like this:\n\n\nFilter creation - skip if no audio:\n:::::::::::::::::::::::::::::::::::\n\n::\n\n    AVSValue __cdecl HalfVolume::Create(AVSValue args, void*, IScriptEnvironment* env) {\n        if (!args[0].AsClip()->GetVideoInfo().HasAudio())\n            return args[0];\n\n        // Auto convert audio to a compatible format.\n        AVSValue CA_args[3] = { args[0], SAMPLE_INT16 | SAMPLE_FLOAT, SAMPLE_FLOAT };\n        PClip clip = env->Invoke(\"ConvertAudio\", AVSValue(CA_args, 3)).AsClip();\n\n        return new HalfVolume(clip);\n    }\n\n\nWhat ConvertAudio() does is, that you tell it that your filter supports\nSAMPLE_INT16 and SAMPLE_FLOAT, and that it prefers SAMPLE_FLOAT. If the\ninput isn't 16 bit or float, it'll be converted to float, otherwise the\noriginal PClip is returned.\n\n\nConstructor\n-----------\n\n::\n\n    HalfVolume::HalfVolume(PClip _child)\n        : GenericVideoFilter(_child) { // Provide null GetFrame, GetParity, etc\n    }\n\n\nGetAudio override\n-----------------\n\n::\n\n    void __stdcall HalfVolume::GetAudio(void* buf, __int64 start, __int64\n    count, IScriptEnvironment* env) {\n      child->GetAudio(buf, start, count, env);\n      int channels = vi.AudioChannels();\n\n      if (vi.SampleType() == SAMPLE_INT16) {\n        short* samples = (short*)buf;\n        for (int i=0; i< count; i++) {\n          for(int j=0;j< channels;j++) {\n            samples[i*channels+j] += 1; // Round\n            samples[i*channels+j] /= 2; // Halve\n          }\n        }\n      } else if (vi.SampleType() == SAMPLE_FLOAT) {\n        SFLOAT* samples = (SFLOAT*)buf;\n        for (int i=0; i< count; i++) {\n          for(int j=0;j< channels;j++) {\n             samples[i*channels+j] /= 2.0f; // Halve, rounding not needed\n          }\n        }\n      }\n    }\n\n\nImplementation of a half volume filter. Very explicit, so it isn't going to\nbe the fastest possible, but it should serve the purpose. Furthermore have a\nlook `discussion here`_ and look also at `audio.cpp`_ for a bunch of more\nadvanced stuff. A lot of technical details are also to be found in\n:doc:`AviSynth Two-Five Audio <AviSynthTwoFiveAudio>`.\n\n----\n\nSince we are invoking ConvertAudio() you might wonder whether it is\npossible to call it in a script. That is indeed possible, but not\ndocumented since it is not very practical to do so. You need to know\nthat:\n\n::\n\n    SAMPLE_INT8  = 1b     = 1,\n    SAMPLE_INT16 = 10b    = 2,\n    SAMPLE_INT24 = 100b   = 4,\n    SAMPLE_INT32 = 1000b  = 8,\n    SAMPLE_FLOAT = 10000b = 16\n\n(although these values might change some day).\n\nIn the example above we call ConvertAudio() with\n\n::\n\n    SAMPLE_INT16\n    SAMPLE_FLOAT = 10b\n    10000b = 10010b = 18,\n\nso you need to call it as ConvertAudio(clip, 18, 16).\n\nYou should realise that float audio will be converted to 16 bit when\nfeeding it to the encoder. At least unless you have set :doc:`global\nOPT_AllowFloatAudio = True <../syntax/syntax_internal_functions_control>` in your script.\n__________________________________________________________________\n\nBack to :doc:`FilterSDK`\n\n$Date: 2023/03/21 14:46:51 $\n\n.. _audio.cpp: https://github.com/AviSynth/AviSynthPlus/blob/master/avs_core/core/audio.cpp\n.. _ConvertAudio.cpp: https://github.com/AviSynth/AviSynthPlus/blob/master/avs_core/convert/convert_audio.cpp\n.. _discussion here: http://forum.doom9.org/showthread.php?s=&threadid=72760&highlight=ConvertAudiohere\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/GradientMask.rst",
    "content": "\nGradientMask\n============\n\nI'll start off with a simple source filter. It's called \"GradientMask\",\nand it produces a gradient.\n\nHere's GradientMask.cpp\n\n::\n\n    #include <windows.h>\n    #include \"avisynth.h\"\n\n    class GradientMask : public IClip {\n    public:\n      GradientMask(int _w, int _h, int _color, IScriptEnvironment* env);\n      PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n      void __stdcall GetAudio(void* buf, __int64 start, __int64 count, IScriptEnvironment* env) {};\n      bool __stdcall GetParity(int n) { return false; };\n      int __stdcall SetCacheHints(int cachehints, int frame_range) { return 0; };\n      const VideoInfo& __stdcall GetVideoInfo() { return vi; };\n    private:\n      int w;\n      int h;\n      int color;\n      VideoInfo vi;\n      PVideoFrame frame;\n    };\n\n    GradientMask::GradientMask(int _w, int _h, int _color, IScriptEnvironment* env) :\n                               w(_w), h(_h), color(_color) {\n      memset(&vi, 0, sizeof(VideoInfo));\n      vi.width = w;\n      vi.height = h;\n      vi.fps_numerator = 30000;\n      vi.fps_denominator = 1001;\n      vi.num_frames = 1;\n      vi.pixel_type = VideoInfo::CS_BGR24;\n\n      frame = env->NewVideoFrame(vi);\n\n      int y, i;\n      BYTE* p;\n      int fpitch, fheight, fwidth;\n      float red, green, blue, luma;\n\n      static const int col[] = {(color >> 16) & 0xff, (color >> 8) & 0xff, (color >> 0) & 0xff};\n      luma = float((col[0]+col[1]+col[2])/3.0);\n\n      blue = max(col[2] - luma,0);\n      green = max(col[1] - luma,0);\n      red = max(col[0] - luma,0);\n\n      p = frame->GetWritePtr();\n      fpitch = frame->GetPitch();\n      fwidth = frame->GetRowSize(); // in bytes\n      fheight = frame->GetHeight(); // in pixels\n\n      for (y=0; y<fheight; y++) {\n        for (i=0; i<fwidth; i+=3) {\n          p[i] = int(min(i * 255.0/float(fwidth) + blue,255));\n          p[i+1] = int(min(i * 255.0/float(fwidth) + green,255));\n          p[i+2] = int(min(i * 255.0/float(fwidth) + red,255));\n        }\n        p += fpitch;\n      }\n    }\n\n    PVideoFrame __stdcall GradientMask::GetFrame(int n, IScriptEnvironment* env) { return frame; }\n\n    static AVSValue __cdecl Create_GradientMask(AVSValue args, void* user_data, IScriptEnvironment* env) {\n      return new GradientMask(args[0].AsInt(640), args[1].AsInt(480), args[2].AsInt(0), env);\n    }\n\n    const AVS_Linkage *AVS_linkage = 0;\n\n    extern \"C\" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors) {\n      AVS_linkage = vectors;\n      env->AddFunction(\"GradientMask\", \"[width]i[height]i[color]i\", Create_GradientMask, 0);\n      return \"GradientMask sample plugin\";\n    }\n\nCompile this file into a DLL named GradientMask.dll. See :doc:`compiling\ninstructions <CompilingAvisynthPlugins>`. Now create an Avisynth\nscript which looks something like this:\n\n::\n\n    LoadPlugin(\"d:\\path\\GradientMask.dll\")\n    # GradientMask(width=1024, height=768)\n    GradientMask(color=$FF0000)\n\nLine by line breakdown\n----------------------\n\nHere's a line-by-line breakdown of GradientMask.cpp.\n\nAs explained in the :doc:`InvertNeg <InvertNeg>` filter, an Avisynth\nfilter is simply a C++ class implementing the IClip interface. The class\nGenericVideoFilter is a simple do-nothing filter defined in avisynth.h.\nIt derives from IClip and implements all four methods (being being\nGetFrame, GetAudio, GetParity and SetCacheHints). Filters that have a\nparent clip and thus can inherit from GenericVideoFilter rather than\ndirectly from IClip; this saves you from having to implement methods\nthat you don't care about. Source filters don't have a parent clip and\nneed to derive them from IClip.\n\nSince we are developing a source filter we need to derive from IClip,\nfill out a VideoInfo and implement all four methods (instead of\noverriding the ones we need).\n\nIn the example below a gradientmask is created. It fades from a fully\nsaturated color to white. The gradientmask will be created in the\nconstructor and returned only once.\n\n::\n\n    class GradientMask : public IClip {\n\nAs stated we need to inherit from IClip directly ...\n\n::\n\n    public:\n      GradientMask(int _w, int _h, int _color, IScriptEnvironment* env);\n\nThis filter has three input parameters (being the width, height and\ncolor).\n\n::\n\n      PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n\nGetFrame will be overridden below and will be filled with our Gradient.\n\n::\n\n      void __stdcall GetAudio(void* buf, __int64 start, __int64 count, IScriptEnvironment* env) {};\n\nOur filter will not return any audio. Have a look at the internal filter\n:doc:`Tone <../corefilters/tone>` how this is done.\n\n::\n\n      bool __stdcall GetParity(int n) { return false; };\n\nGetParity will return false.\n\n::\n\n      int __stdcall SetCacheHints(int cachehints, int frame_range) { return 0; };\n\nSetCacheHints will return 0.\n\n::\n\n      const VideoInfo& __stdcall GetVideoInfo() { return vi; };\n\nvi needs to be filled in the constructor.\n\n::\n\n    private:\n      int w;\n      int h;\n      int color;\n      VideoInfo vi;\n      PVideoFrame frame;\n    };\n\n    GradientMask::GradientMask(int _w, int _h, int _color, IScriptEnvironment* env) :\n                               w(_w), h(_h), color(_color) {\n      memset(&vi, 0, sizeof(VideoInfo));\n      vi.width = w;\n      vi.height = h;\n      vi.fps_numerator = 30000;\n      vi.fps_denominator = 1001;\n      vi.num_frames = 1;\n      vi.pixel_type = VideoInfo::CS_BGR24;\n\nFirst memory is allocated for VideoInfo and then the video parameters of\nvi are filled. In our example, the width and height are taken from the\ninput parameters and the remaining ones are given default values. So an\none-frame RGB24 gradient will be returned with width 'w' and height 'h'.\n\nIn our example, the frame is filled here in the constructor since the\nclip consists of only one frame. If it would have multiple different\nframes you should fill them in GetFrame().\n\n::\n\n      frame = env->NewVideoFrame(vi);\n\n      int y, i;\n      BYTE* p;\n      int fpitch, fheight, fwidth;\n      float red, green, blue, luma;\n\n      static const int col[] = {(color >> 16) & 0xff, (color >> 8) & 0xff, (color >> 0) & 0xff};\n      luma = float((col[0]+col[1]+col[2])/3.0);\n\n      blue = max(col[2] - luma,0);\n      green = max(col[1] - luma,0);\n      red = max(col[0] - luma,0);\n\nFirst we calculate the luma (being the average of the color components\nand subtract it from the color components. So we get the fully saturated\ncolor.\n\n::\n\n      p = frame->GetWritePtr();\n      fpitch = frame->GetPitch();\n      fwidth = frame->GetRowSize(); // in bytes\n      fheight = frame->GetHeight(); // in pixels\n\nThe gradients runs from the fully saturated color ((red,green,blue; for\ni=0) to white ((255,255,255) for i=fwidht):\n\n::\n\n      for (y=0; y<fheight; y++) {\n        for (i=0; i<fwidth; i+=3) {\n          p[i] = int(min(i * 255.0/float(fwidth) + blue,255));\n          p[i+1] = int(min(i * 255.0/float(fwidth) + green,255));\n          p[i+2] = int(min(i * 255.0/float(fwidth) + red,255));\n        }\n        p += fpitch;\n      }\n    }\n\n    PVideoFrame __stdcall GradientMask::GetFrame(int n, IScriptEnvironment* env) { return frame; }\n\nHere our gradient frame is returned.\n\n::\n\n    static AVSValue __cdecl Create_GradientMask(AVSValue args, void* user_data, IScriptEnvironment* env) {\n      return new GradientMask(args[0].AsInt(640), args[1].AsInt(480), args[2].AsInt(0), env);\n    }\n\n    const AVS_Linkage *AVS_linkage = 0;\n\n    extern \"C\" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors) {\n      AVS_linkage = vectors;\n      env->AddFunction(\"GradientMask\", \"[width]i[height]i[color]i\", Create_GradientMask, 0);\n      return \"GradientMask sample plugin\";\n    }\n\n--------------\n\n| Back to :doc:`FilterSDK <FilterSDK>`\n\n$Date: 2015/09/14 20:23:59 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/InstructionPairing.rst",
    "content": "\n`InstructionPairing`_\n=====================\n\nInstruction pairing can almost double the performance of you filter. There\nare two execution pipes for :doc:`MMX <MMX>` code, which means that two instructions\ncan be executed at the same time. Certain instructions can only be issued in\nthe U pipeline, and certain instructions can only be issued in the V\npipeline. Most MMX instructions can be issued in either\n\nThe original pairing rules for MMX code is as follows:\n\n1)  The second instruction does not read or write a register which the\n    first instruction writes to.  2) MMX shift, pack or unpack instructions\n    can execute in either pipe but cannot pair with other MMX shift, pack or\n    unpack instructions.  3) MMX multiply instructions can execute in either\n    pipe but cannot pair with other MMX multiply instructions. They take 3\n    clock cycles and the last 2 clock cycles can overlap with subsequent\n    instructions.  4) an MMX instruction which accesses memory or integer\n    registers can execute only in the U-pipe and cannot pair with a non-MMX\n    instruction.\n\n**Ad. 1)**\n\nThis is the most important rule of them all. Instruction two should never be\ndependant on information from instruction one. The formal definition is \"The\ndestination of the first operand should not be used as source or destination\nof the second operand\".\n\nConsider the following code (paired instructions are in bold):\n\n``movq mm0,[eax]``\n\n``movq mm1,mm0 *; depends on mm0*``\n\n``pavgb mm1,mm7 *; depends on mm1*``\n\n``por mm0,mm1 *; depends on mm1*``\n\n``movq [eax],mm0 *; depends on mm0*``\n\n``**movq mm0,[eax+ebx]**``\n\n``movq mm1,mm0 *; depends on mm0*``\n\n``punpcklwd mm1,mm7 *; depends on mm1*``\n\n``por mm0,mm1 *; depends on mm1*``\n\n``movq [eax+ebx],mm0 *; depends on mm0*``\n\nRearrange the code to:\n\n``movq mm0,[eax]``\n\n``**movq mm2,[eax+ebx]**``\n\n``movq mm1,mm0``\n\n``**movq mm3,mm0**``\n\n``pavgb mm1,mm7``\n\n``**pavgb mm3,mm7**``\n\n``por mm0,mm1``\n\n``**por mm2,mm3**``\n\n``movq [eax],mm0``\n\n``**movq [eax+ebx],mm2**``\n\nThe latter code executes twice as fast as the upper code!\n\n**Ad. 2)**\n\nIt seems like this restriction has been loosened on Athlon and P3. Apparently\npack does no longer use the shifter unit. So now only shifts are not\npairable!\n\n**Ad. 3)**\n\nEven though these numbers have changed slighly on Athlon, it still seems like\na good idea to put in two MMX instructions before depending on the result of\na multiply. On AMD Athlon a multiply takes 3 cycles, whereas most other\ninstructions take 2. See appendix F in the :doc:`AMDOptimizationGuide <AMDOptimizationGuide>`.\n\n--------\n\n*phaeron writes:*\n\nThis information is very old -- it applies to the superscalar pipelines of\nthe original Pentium. Beginning with the Pentium II instruction decode and\nexecution are decoupled, so the dependency restrictions outlined above likely\ndon't apply to any modern CPU which does out-of-order (OOO) execution. Also,\nthe Pentium II, Pentium III, and Pentium-M have a 4-1-1 uop decoder pattern,\nnot the UV pairing described above. So while this sequence will ideally\ndecode on a Pentium MMX:\n\n``{movd mm0,[eax]}``\n\n``{pxor mm7,mm7}``\n\n``{movd mm1,[eax+esi]}``\n\n``{punpcklbw mm1,mm7}``\n\n``{movd mm2,[eax+esi]}``\n\n``{punpcklbw mm2,mm7}``\n\nPPro architectures will instead decode the above at **3** instructions/cycle.\n\nI don't think packs are any better on PIII than on Pentium/PII. `[Agner Fog's\noptimization tome]`_ says that shifts still only issue in port 1, meaning\nthat you still can't execute more than one per cycle. This seems to be borne\nout in tests as well, as I can get a PADDW loop to execute MMX ops twice as\nfast as a PUNPCKLBW loop on a PIII.\n\nPerhaps more dangerous than decoding rules on PII/PIII is the register\nrenaming limitation:\n\n--------\n\n\nIntel P4 specifics\n~~~~~~~~~~~~~~~~~~\n\nAccording to the :doc:`IntelOptimizationGuide <IntelOptimizationGuide>`:\n\n**MMX multiply:**\n\nP4 - 8 cycles, K7 - 3 cycles.\n\nMMX multiply now takes 4 times as many cycles as other MMX commands -\nactually quite a big problem when having to pair them. Therefore there should\nideally now be at least 4 instructions that doesn't mulitply between two\nmultiply instructions.\n\n**MMX shifter restrictions:**\n\nIt seems like there are still issues with one shifter on the P4 - this is\n(alongside the MMX multiplier) one of the biggest problems. I can see that\npshufw is actually done in the MMX shifter - in contrast to the K7, where\nthis restriction has been lifted.\n\nThis means that on P4, none of these instructions are pairable: Pack, unpack,\nshift, shuffle. This is a problem, since it will stall the processor, if any\nof these two instructions follow eachother - even if they are not depending\non eachother. This is however too often the case.\n\nIn case I'm being too crypitic above: None of the instructions marked with\nMMX_SHFT can be paired with eachother, just as two instructions with FP_MUL\ncannot be paired with eachother. Therefore to have efficient code, the second\npipe should have code that doesn't use the same part of the CPU - and doesn't\ndepend on the result from the other pipe. The ISSE code above is a perfect\nexample of this - almost none of the instructions pair on P4.\n\n--------\n\n*phaeron writes:*\n\nI wouldn't worry about having only one shifter on P4. Intel balanced this out\nby removing the second MMX ALU, so you can only do one PADDW per cycle now\ntoo.\n\nA much bigger worry with respect to P4 MMX performance is that register-to-\nregister MOVQs aren't handled entirely by register renaming anymore, and have\na 6 clock latency! It can be *much* faster to move via the ALU (pxor mm1,mm1\n/ por mm1, mm0) or the shifter (pshufw mm1, mm0, 0) than via MOVQ. For a sad\njoke, benchmark this in a loop:\n\n``movq mm1, mm0``\n\n``movq mm2, mm1``\n\n``movq mm3, mm2``\n\n``movq mm4, mm3``\n\n``movq mm5, mm4``\n\n``movq mm6, mm5``\n\n``movq mm7, mm6``\n\n``movq mm0, mm7``\n\nagainst this on a P4:\n\n``pxor mm1, mm1``\n\n``por mm1, mm0``\n\n``pxor mm2, mm2``\n\n``por mm2, mm1``\n\n``pxor mm3, mm3``\n\n``por mm3, mm2``\n\n``pxor mm4, mm4``\n\n``por mm4, mm3``\n\n``pxor mm5, mm5``\n\n``por mm5, mm4``\n\n``pxor mm6, mm6``\n\n``por mm6, mm5``\n\n``pxor mm7, mm7``\n\n``por mm7, mm6``\n\n``pxor mm0, mm0``\n\n``por mm0, mm7``\n\nand watch the second loop run **three times faster** than the first. The\nreason is that both loops end up being one huge dependency chain, for which\nthe first takes 8*6 = 48 cycles per iteration, and the second takes 8*2 = 16\ncycles per iteration.\n\n(Be careful with the pxor trick. It breaks dependency chains on P4, but has a\nfalse dependency on the source register on PIII and Athlon.)\n\n\nBack to :doc:`AssemblerOptimizing <AssemblerOptimizing>`\n\n$Date: 2025-02-24 21:07:58-05:00 $\n\n.. _InstructionPairing: http://avisynth.nl/index.php/Filter_SDK/Instruction_pairing\n.. _[Agner Fog's optimization tome]: http://www.agner.org/assem/\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/IntegerSSE.rst",
    "content": "\nIntegerSSE\n==========\n\nInteger SSE is a set of instructions found in most modern processors.\nIntegerSSE is an extension of :doc:`MMX <MMX>`.\n\nSSE: New commands present in P3, P4, newer Celerons, Athlon XP, MP.\n\nInteger SSE: A *subset* of the SSE command set, mostly used for video\nprocessing. These instructions are also present in AMD Athlon (all versions),\nAMD Duron (all versions).\n\nInteger SSE instructions:\n\n``MASKMOVQ`` *mmreg1, mmreg2*\n\n``MOVNTQ`` *mem64, mmreg*\n\n``PAVGB`` *mmreg1, mmreg2*\n\n``PAVGB`` *mmreg, mem64*\n\n``PAVGW`` *mmreg1, mmreg2*\n\n``PAVGW`` *mmreg, mem64*\n\n``PEXTRW`` *reg32, mmreg, imm8*\n\n``PINSRW`` *mmreg, reg32, imm8*\n\n``PINSRW`` *mmreg, mem16, imm8*\n\n``PMAXSW`` *mmreg1, mmreg2*\n\n``PMAXSW`` *mmreg, mem64*\n\n``PMAXUB`` *mmreg1, mmreg2*\n\n``PMAXUB`` *mmreg, mem64*\n\n``PMINSW`` *mmreg1, mmreg2*\n\n``PMINSW`` *mmreg, mem64*\n\n``PMINUB`` *mmreg1, mmreg2*\n\n``PMINUB`` *mmreg, mem64*\n\n``PMOVMSKB`` *reg32, mmreg*\n\n``PMULHUW`` *mmreg1, mmreg2*\n\n``PMULHUW`` *mmreg, mem64*\n\n``PSADBW`` *mmreg1, mmreg2*\n\n``PSADBW`` *mmreg, mem64*\n\n``PSHUFW`` *mmreg1, mmreg2, imm8*\n\n``PSHUFW`` *mmreg, mem64, imm8*\n\n``PREFETCHNTA`` *mem8*\n\n``PREFETCHT0`` *mem8*\n\n``PREFETCHT1`` *mem8*\n\n``PREFETCHT2`` *mem8*\n\n``SFENCE``\n\n----\n\nBack to :doc:`AssemblerOptimizing <AssemblerOptimizing>`\n\n$Date: 2014/10/27 22:04:54 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/IntelOptimizationGuide.rst",
    "content": "\nIntelOptimizationGuide\n======================\n\nIntels optimization guide can be downloaded from:\n\nhttp://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html\n\n----\n\nBack to :doc:`AssemblerOptimizing <AssemblerOptimizing>`\n\n$Date: 2014/10/27 22:04:54 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/InterleavedImageFormat.rst",
    "content": "\nInterleavedImageFormat\n======================\n\nWhen talking about interleaved and :doc:`PlanarImageFormat <PlanarImageFormat>` the main difference\nis how they are stored in memory.\n\nInterleaved images have all color components needed to represent a pixel\nplaced at the same place in memory.\n\nSupported interleaved formats in AviSynth 2.5/2.6: RGB24, RGB32, YUY2.\n\nRelated links:\n\n- `RGB pixel formats`_\n- `Packed YUV Formats`_\n- `Recommended 8-Bit YUV Formats for Video Rendering`_ | `archived`_\n\n----\n\nBack to :doc:`FilterSDK`\n\n$Date: 2015/01/13 00:24:50 $\n\n.. _RGB pixel formats: http://www.fourcc.org/rgb.php\n.. _Packed YUV Formats: http://www.fourcc.org/yuv.php#Packed YUV Formats\n.. _Recommended 8-bit YUV Formats for Video Rendering: http://msdn.microsoft.com/en-us/library/windows/desktop/dd206750(v=vs.85).aspx\n.. _archived:\n    http://web.archive.org/web/20131206041437/http://msdn.microsoft.com/en-us/library/windows/desktop/dd206750(v=vs.85).aspx\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/IntermediateMmxOptimization.rst",
    "content": "\n`IntermediateMmxOptimization`_\n==============================\n\n*phaeron writes*:\n\nAdditive blending is a relatively simple, common, and useful operation. It\ntakes two images and adds them together, saturating the result to white. It's\nuseful for some kinds of overlays, as well as incrementally building a final\nimage from components. We'll start with a simple scalar version:\n\n::\n\n    void additiveblend1(unsigned char *dst, const unsigned char *src, int quads) {\n        int bytes = quads << 2;\n\n        do {\n            unsigned v = (unsigned)src[0] + dst[0];\n            if (v >= 256)\n                v = 255;\n            dst[0] = v;\n            ++src;\n            ++dst;\n        } while(--bytes);\n    }\n\n\nThis code works a byte at a time and works equally well for any byte-per-\nchannel format, including RGB24, RGB32, YUY2, and YV12. It runs at a dismal\n16 clocks/byte on a 1.6GHz Pentium 4.\n\n**Tip:** The CPU's time stamp counter, accessible via the RDTSC instruction,\nis a great way to benchmark small pieces of code. However, the results can be\nheavily affected by cache effects. For code that is deterministic and quick,\nrunning the test twice in a row and taking the second timing can eliminate\nmost cache effects.\n\nNow, let's rewrite it in MMX.\n\n::\n\n    void additiveblend2(unsigned char *dst, const unsigned char *src, int quads) {\n        __asm {\n            mov     ecx, src\n            mov     edx, dst\n            mov     eax, quads\n            pxor        mm7, mm7\n    top:\n            movd        mm0, [ecx]     ;load four source bytes\n            movd        mm1, [edx]     ;load four destination\n            bytes\n            punpcklbw   mm0, mm7       ;unpack source bytes to\n            words\n            punpcklbw   mm1, mm7       ;unpack destination bytes\n            to words\n            paddw       mm0, mm1       ;add words together\n            packuswb    mm0, mm1       ;pack words with\n            saturation\n            movd        [edx], mm0     ;store blended result\n            add     ecx, 4             ;advance source pointer\n            add     edx, 4             ;advance destination\n            pointer\n            dec     eax                ;loop back until done\n            jne     top\n            emms\n        }\n    }\n\n\nThis version runs *much* better on a random 1K sample, at 1.64 clocks/byte.\nHowever, we can do better. Unpacking to 16-bit words is generally required in\nmost MMX routines but it's a total waste here, as the CPU has saturating add\ninstructions that work directly on bytes. We can use those instead.\n\n**Tip:** MMX has a lot of interesting instructions, such as saturating adds\nand subtracts, clamping packs, and multiply-plus-shift instructions. Learning\nto use these effectively can improve the performance of your code. However,\nthere are a few omissions in the basic MMX set, including unsigned\nmultiplies, byte shifts, and saturating 32-bit operations, that you should be\naware of.\n\nSo here's the version using the saturating PADDUSB (packed add with unsigned\nbyte saturation) instruction:\n\n::\n\n    void additiveblend3(unsigned char *dst, const unsigned char *src, int quads) {\n        __asm {\n            mov     ecx, src\n            mov     edx, dst\n            mov     eax, quads\n    top:\n            movd        mm0, [ecx]\n            movd        mm1, [edx]\n            paddusb     mm0, mm1\n            movd        [edx], mm0\n            add     ecx, 4\n            add     edx, 4\n            dec     eax\n            jne     top\n            emms\n        }\n    }\n\n\nThis version is still faster at 1.27 clocks/byte and is simpler, too. But why\nare we still doing 4 bytes at a time, when we could be doing 8?\n\n::\n\n    void additiveblend4(unsigned char *dst, const unsigned char *src, int quads) {\n        __asm {\n            mov     ecx, src\n            mov     edx, dst\n            mov     eax, quads\n            pxor        mm7, mm7\n    top:\n            movq        mm0, [ecx]\n            paddusb     mm0, [edx]\n            movq        [edx], mm0\n            add     ecx, 8\n            add     edx, 8\n            sub     eax, 2\n            jne     top\n            emms\n        }\n    }\n\n\nAlthough we only doubled the parallism of the loop, this change makes a huge\ndifference and kicks us all the way up to 0.49 clocks/pixel. Now notice that\nthe scalar code is beginning to take a lot of the inner loop -- in fact, half\nof it. We can eliminate the pointer updates by switching to array notation:\n\n::\n\n    void additiveblend5(unsigned char *dst, const unsigned char *src, int quads) {\n        __asm {\n            mov     ecx, src\n            mov     edx, dst\n            mov     eax, quads\n            shl     eax, 2\n            add     ecx, eax\n            add     edx, eax\n            neg     eax\n    top:\n            movq        mm0, [ecx+eax]\n            paddusb     mm0, [edx+eax]\n            movq        [edx+eax], mm0\n            add     eax, 8\n            jne     top\n            emms\n        }\n    }\n\n\nThere is a slight trick here, in that we index negatively from the end of the\narrays rather than positively from the start, and count up instead of down.\nRemoving the pointer operations trims execution time by a tiny amount, down\nto 0.48 clocks/pixel. We're still not done yet, though. Let's unroll the\nloop. That way, the CPU has less loop overhead instructions to execute, and\nalso relaxes the loop-carried dependency on the loop count (EAX in a loop\niteration is dependent on the last loop's EAX, which is dependent on EAX from\nthe loop before that, etc).\n\n::\n\n    void additiveblend6(unsigned char *dst, const unsigned char *src, int quads) {\n        __asm {\n            mov     ecx, src\n            mov     edx, dst\n            mov     eax, quads\n            shl     eax, 2\n            add     ecx, eax\n            add     edx, eax\n            neg     eax\n    top:\n            movq        mm0, [ecx+eax]\n            movq        mm1, [ecx+eax+8]\n            paddusb     mm0, [edx+eax]\n            paddusb     mm1, [edx+eax+8]\n            movq        [edx+eax], mm0\n            movq        [edx+eax+8], mm1\n            add     eax, 16\n            jne     top\n            emms\n        }\n    }\n\n\nThis version now runs at 0.42 clocks/pixel, about 38x faster than the\noriginal scalar version. That's fast enough, right? Well, yes, except for one\nproblem: it's wrong. Namely, this routine handles 16 bytes at a time instead\nof 4 bytes at a time, so if the quad count isn't divisible by 4, this routine\ndoesn't work properly. Whoops.\n\n**Tip:** Faster code is generally less desirable than working code.\n\n::\n\n    void additiveblend7(unsigned char *dst, const unsigned char *src, int quads) {\n        __asm {\n                mov             ecx, src\n                mov             edx, dst\n                mov             eax, quads\n                shl             eax, 2\n                lea             ecx, [ecx+eax-12]\n                lea             edx, [edx+eax-12]\n                neg             eax\n                add             eax, 12\n                jc              look_for_oddballs\n    top:\n                movq            mm0, [ecx+eax]\n                movq            mm1, [ecx+eax+8]\n                paddusb         mm0, [edx+eax]\n                paddusb         mm1, [edx+eax+8]\n                movq            [edx+eax], mm0\n                movq            [edx+eax+8], mm1\n                add             eax, 16\n                jnc             top\n    look_for_oddballs:\n                sub             eax, 12\n                jnc             no_oddballs\n    oddball_loop:\n                movd            mm0, [ecx+eax+12]\n                movd            mm1, [edx+eax+12]\n                paddusb         mm0, mm1\n                movd            [edx+eax+12], mm0\n                add             eax, 4\n                jne             oddball_loop\n    no_oddballs:\n                emms\n        }\n    }\n\n\nHere is the final version. It's probably still not as fast as it could be but\nfor most uses it's fast enough. Unfortunately, the code to handle odd fixups\nat the end of the line takes more code than the optimized version. It is\noften the case that handling odd cases will greatly complicate an optimized\nroutine. There is an trick to handle odd widths that unfortunately cannot be\nused here, but is useful when the destination and sources don't overlap: back\noff the source and destination pointers and redo some bytes that have already\nbeen done. For instance, if a routine handles 8 bytes at a time and is asked\nto do 21 bytes, do 16 bytes in the fast loop, then do 8 unaligned bytes at\nthe end with bytes 13-15 getting redone. This can let you handle odd widths\nwith very little code.\n\n--------\n\n\nOmake\n~~~~~\n\nRemember that scalar version at the top that ran at 16 clocks/pixel? Well,\nthat was a pretty bad scalar version. Try this one:\n\n::\n\n    void additiveblend1s(unsigned char *dst, const unsigned char *src, int quads) {\n        unsigned *dst2 = (unsigned *)dst;\n        const unsigned *src2 = (const unsigned *)src;\n\n        do {\n                unsigned a = src2[0];\n                unsigned b = dst2[0];\n                unsigned sats = ((a&b) + (((a^b)&0xfefefefe)>>1)) &\n    0x80808080;\n                sats = sats + sats - (sats >> 7);\n\n                dst2[0] = (a|sats) + (b&~sats);\n\n                ++src2;\n                ++dst2;\n        } while(--quads);\n    }\n\n\nThis version handles 32 bits at a time, and runs at 3.43 clocks/byte. MMX is\nstill faster here, but there are some cases in which it isn't -- for\ninstance, when I tried writing an HSV filter, an optimized scalar version\nturned out to be faster than an optimized MMX version. So don't think that\nMMX is always the best way.\n\n\nBack to :doc:`AssemblerOptimizing <AssemblerOptimizing>`\n\n$Date: 2025-02-24 21:03:21-05:00 $\n\n.. _IntermediateMmxOptimization:\n    http://avisynth.nl/index.php/Filter_SDK/Intermediate_MMX_optimization\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/InternalFunctions.rst",
    "content": "\nInternalFunctions\n=================\n\nRead about :doc:`VideoInfo <VideoInfo>`\n\nRead about using internal filters, using ``env->Invoke`` in :doc:`EnvInvoke <EnvInvoke>`.\n\nUse :doc:`EnvSaveString <EnvSaveString>` to avoid strings leaking.\n\n----\n\nBack to :doc:`FilterSDK <FilterSDK>`\n\n$Date: 2006/11/24 18:21:26 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/InvertNeg.rst",
    "content": "\nInvertNeg\n=========\n\nI'll start off with a complete, working Avisynth plugin. It's called\n\"InvertNeg\", and it produces a photo-negative of the input clip.\n\nHere's InvertNeg.cpp:\n::\n\n    #include <windows.h>\n    #include \"avisynth.h\"\n\n    class InvertNeg : public GenericVideoFilter {\n    public:\n        InvertNeg(PClip _child, IScriptEnvironment* env);\n        PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n    };\n\n    InvertNeg::InvertNeg(PClip _child, IScriptEnvironment* env) :\n        GenericVideoFilter(_child) {\n        if (!vi.IsPlanar() || !vi.IsYUV()) {\n            env->ThrowError(\"InvertNeg: planar YUV data only!\");\n        }\n    }\n\n    PVideoFrame __stdcall InvertNeg::GetFrame(int n, IScriptEnvironment* env) {\n\n        PVideoFrame src = child->GetFrame(n, env);\n        PVideoFrame dst = env->NewVideoFrame(vi);\n\n        const unsigned char* srcp;\n        unsigned char* dstp;\n        int src_pitch, dst_pitch, row_size, height;\n        int p, x, y;\n\n        int planes[] = {PLANAR_Y, PLANAR_V, PLANAR_U};\n\n        for (p=0; p<3; p++) {\n            srcp = src->GetReadPtr(planes[p]);\n            dstp = dst->GetWritePtr(planes[p]);\n\n            src_pitch = src->GetPitch(planes[p]);\n            dst_pitch = dst->GetPitch(planes[p]);\n            row_size = dst->GetRowSize(planes[p]);\n            height = dst->GetHeight(planes[p]);\n\n            for (y = 0; y < height; y++) {\n                for (x = 0; x < row_size; x++) {\n                    dstp[x] = srcp[x] ^ 255;\n                }\n                srcp += src_pitch; // or srcp = srcp + src_pitch;\n                dstp += dst_pitch; // or dstp = dstp + dst_pitch;\n            }\n        }\n        return dst;\n    }\n\n    AVSValue __cdecl Create_InvertNeg(AVSValue args, void* user_data, IScriptEnvironment* env) {\n        return new InvertNeg(args[0].AsClip(), env);\n    }\n\n    const AVS_Linkage *AVS_linkage = 0;\n\n    extern \"C\" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors) {\n        AVS_linkage = vectors;\n        env->AddFunction(\"InvertNeg\", \"c\", Create_InvertNeg, 0);\n        return \"InvertNeg sample plugin\";\n    }\n\n\nCompile this file into a DLL named InvertNeg.dll. See\n:doc:`compiling instructions <CompilingAvisynthPlugins>`. Now create an\nAvisynth script which looks something like this:\n::\n\n    LoadPlugin(\"d:\\path\\InvertNeg.dll\")\n    clip = BlankClip().ConvertToYV12()\n    return clip.InvertNeg()\n\nLine by line breakdown\n----------------------\n\nHere's a line-by-line breakdown of InvertNeg.cpp.\n::\n\n    #include \"avisynth.h\"\n\n\nThis header declares all the classes and miscellaneous constants that\nyou might need when writing a plugin. All external plugins should\n#include it.\n\nExternal plugins do not link with avisynth.dll, so they can't directly\naccess functions that are defined in the main Avisynth source code.\nTherefore, every important function in avisynth.h is either defined\ninline or declared as virtual. The virtual functions act as callbacks\nfor external DLLs.\n::\n\n    class InvertNeg : public GenericVideoFilter {\n\n\nAn Avisynth filter is simply a C++ class implementing the :ref:`IClip <cplusplus_iclip>`\ninterface. More about classes can be found in this `tutorial`_. IClip\nhas four pure virtual methods: :ref:`GetVideoInfo <cplusplus_getvideoinfo>`,\n:ref:`GetFrame <cplusplus_getframe>`, :ref:`GetParity <cplusplus_getparity>`,\nand :ref:`GetAudio <cplusplus_getaudio>`.\n\nThe class GenericVideoFilter is a simple do-nothing filter defined in\navisynth.h. It derives from IClip and implements all four methods. Most\nfilters can inherit from GenericVideoFilter rather than directly from\nIClip; this saves you from having to implement methods that you don't\ncare about, like GetAudio in this example. More about inheritance can\nbe found in this `tutorial <http://www.cplusplus.com/doc/tutorial/inheritance>`__. In our case two functions are defined in\nthe class: the constructor (InvertNeg()) and GetFrame.\n::\n\n    InvertNeg(PClip _child, IScriptEnvironment* env);\n\n\nThis is our constructor. It can be used to initialize variables, create\nlook up tables (LUTs) and to check whether the source clips (if there\nis one) have the desired properties. In our example it is taking a\nsingle clip, does some property checking and then simply passes through\nto its output.\n\nA PClip is a \"smart pointer\" to an IClip. It maintains a reference\ncount on the IClip object and automagically deletes it when the last\nPClip referencing it goes away. For obvious reasons, you should always\nuse PClip rather than IClip* to refer to clips.\n\nLike a genuine pointer, a PClip is only four bytes long, so you can\npass it around by value. Also like a pointer, a PClip can be assigned a\nnull value (0), which is often useful as a sentinel. Unlike a pointer,\nPClip is initialized to 0 by default.\n\nYou'll need to make sure your class doesn't contain any circular PClip\nreferences, or any PClips sitting in dynamically allocated memory that\nyou forget to delete. Other than that, you don't have to worry about\nthe reference-counting machinery.\n\nAvisynth filters have a standardized output channel via IClip, but\n(unlike for example `VirtualDub`_ filters) no standardized input\nchannel. Each filter is responsible for obtaining its own source\nmaterial -- usually (as in this case) from another clip, but sometimes\nfrom several different clips, or from a file.\n\nWe will override the GetFrame method to do something more useful, while\nleaving the other three methods as-is to pass through aspects of the\nclip that we don't need to change.\n::\n\n    PVideoFrame InvertNeg::GetFrame(int n, IScriptEnvironment* env) {\n\n\nThis method is called to make our filter produce frame n of its output.\nThe second argument, env, is for our purposes simply a callback suite.\nIt is actually implemented in Avisynth by a class called ScriptEnvironment.\nOne :ref:`instance of this class <cplusplus_iscriptenvironment>` is created for each\nopened AVS script, so there may sometimes be several instances active\nat once. It is important that the callback functions be called through\nthe proper instance. A particular instance of your class will only be\nused in one ScriptEnvironment, but different instances might be used in\ndifferent ScriptEnvironments.\n::\n\n    InvertNeg::InvertNeg(PClip _child, IScriptEnvironment* env) :\n        GenericVideoFilter(_child) {\n\n\nThis is the class constructor and it is called when a filter instance\nis being created (see Create_InvertNeg()).\n::\n\n    if (!vi.IsPlanar() || !vi.IsYUV()) {\n        env->ThrowError(\"InvertNeg: planar YUV data only!\");\n    }\n\n\n\"vi\" is a protected member of GenericVideoFilter. It is a structure of\ntype :doc:`VideoInfo <VideoInfo>`, and it contains information about the clip (like\nframe size, frame rate, pixel format, audio sample rate, etc.). In our\nexample, when the image format of the clip is not planar or the\ncolorspace of the clip is not YUV, an error is returned using\n:ref:`ThrowError <cplusplus_throwerror>`. As of writing this document there is no planar RGB, but\nthat might very well change in the future.\n::\n\n    PVideoFrame src = child->GetFrame(n, env);\n\n\nThis method returns a PVideoFrame, which is a smart pointer like PClip.\n\n\"child\" is the other protected member of GenericVideoFilter, of type\nPClip. It contains the clip that was passed to the constructor. For our\nfilter to produce frame n we need the corresponding frame of the input.\nIf you need a different frame from the input, all you have to do is\npass a different frame number to child->GetFrame.\n\nGetFrame calls are usually intercepted by Avisynth's internal caching\ncode, so the frame request may never actually reach the child filter.\n::\n\n    PVideoFrame dst = env->NewVideoFrame(vi);\n\n\nThe NewVideoFrame callback allocates space for a video frame of the\nsupplied size. In this case it will hold our filter's output. The frame\nbuffer is uninitialized raw memory (except that in the debug build it\ngets filled with the repeating byte pattern 0A 11 0C A7 ED, which is\neasy to recognize because it looks like \"ALLOCATED\").\n\nAs already explained, \"vi\" contains information about the properties of\nthe clip. NewVideoFrame uses the information in this structure to\nreturn a frame buffer of the appropriate size.\n\nFrame buffers are reused once all the PVideoFrame references to them go\naway. So usually NewVideoFrame won't actually need to allocate any\nmemory from the heap.\n::\n\n    const unsigned char* srcp;\n    unsigned char* dstp;\n    int src_pitch, dst_pitch, row_size, height;\n    int p, x, y;\n\n    int planes[] = {PLANAR_Y, PLANAR_V, PLANAR_U};\n\n\nThis is the declaration of the used variables. Note that we will modify\none color component (instead of an entire pixel) at the same time. Such\na component (for example an U sample) has a value between 0 and 255\n(exactly one byte). Hence srcp and dstp needs to be declared as\nunsigned char (or BYTE would have been possible too).\n\nNote that in the constructor we excluded the formats which are not\nplanar or not YUV. For filter writers this means that they can write\none simple function that is called three times, one for each color\nchannel, assuming that the operations are channel-independent (which is\nnot always the case). This is what I have done here. Note it also works\nfor Y8 since these functions return zero if the plane (PLANAR_U,\nPLANAR_V) doesn't exist. In our case the operations are\nchannel-independent so it doesn't matter which plane is processed\nfirst.\n::\n\n    for (p=0; p<3; p++) {\n        srcp = src->GetReadPtr(planes[p]);\n        dstp = dst->GetWritePtr(planes[p]);\n\n\nAll frame buffers are readable, but not all are writable.\n\nThe rule about writability is this: A buffer is writable if and only if\nthere is exactly one PVideoFrame pointing to it. In other words, you\ncan only write to a buffer if no one else might be reading it. This\nrule guarantees that as long as you hold on to a PVideoFrame and don't\nwrite to it yourself, that frame will remain unchanged. The only\ndrawback is that you can't have two PVideoFrames pointing to a writable\nbuffer. This can sometimes be an inconvenience, as I'll explain later.\n\nAny buffer you get from NewVideoFrame is guaranteed to be writable (as\nlong as you only assign it to one PVideoFrame!). Our filter's dst came\nfrom NewVideoFrame, so we can safely call dst->GetWritePtr(). However,\nframes you get from other clips via GetFrame may not be writable, in\nwhich case GetWritePtr() will return a null pointer.\n\nThere is an :ref:`IsWritable() <cplusplus_iswritable>` method which you can call to find out if a\nbuffer is writable or not, and there's a :ref:`MakeWritable <cplusplus_makewritable>` callback to\nensure that it is.\n::\n\n    src_pitch = src->GetPitch(planes[p]);\n    dst_pitch = dst->GetPitch(planes[p]);\n\n\nJust as in VirtualDub, the \"pitch\" of a frame buffer is the offset (in\nbytes) from the beginning of one scan line to the beginning of the\nnext. The source and destination buffers won't necessarily have the\nsame pitch.\n\nBuffers created by NewVideoFrame are always quadword (8-byte) aligned\nand always have a pitch that is a multiple of 8. (*i think it's 16 now,\nneed to check ???*)\n::\n\n    row_size = dst->GetRowSize(planes[p]);\n\n\nThe row size is the length of each row in bytes (not pixels) of plane\np. It's usually equal to the pitch or slightly less, but it may be\nsignificantly less if the frame in question has been through Crop.\n\nSince our source and destination frames have the same width and pixel\nformat, they will always have the same row size. Thus I only need one\nrow_size variable, and I could just as well have called\nsrc->GetRowSize().\n::\n\n    height = dst->GetHeight(planes[p]);\n\n\nThe height is the height in samples of the plane p. Again, for our\nfilter this is the same for the source and the destination.\n::\n\n    for (y = 0; y < height; y++) {\n        for (x = 0; x < row_size; x++) {\n            dstp[x] = srcp[x] ^ 255;\n        }\n        srcp += src_pitch;\n        dstp += dst_pitch;\n    }\n\n\nThis is the code that does the actual work. The \"srcp += src_pitch;\ndstp += dst_pitch;\" idiom is a useful way of dealing with potentially\ndiffering pitches without too much grief.\n::\n\n    return dst;\n\n\nGetFrame returns the newly-created frame. Our own references to this\nframe and to the source frame will go away with the src and dst\nvariables. Our caller will become sole owner of the destination frame\n(which therefore will still be writable), and the source frame will be\nretained in the cache and eventually recycled. All through the magic of\nC++ classes.\n::\n\n    AVSValue __cdecl Create_InvertNeg(AVSValue args, void* user_data, IScriptEnvironment* env) {\n\n\nIn order to use our new filter, we need a scripting-language function\nwhich creates an instance of it. This is that function.\n\nScript functions written in C++ take three arguments. args contains all\nthe arguments passed to the function by the script. user_data contains\nthe void pointer which you passed to AddFunction (see below). Usually\nyou won't need this. env contains the same IScriptEnvironment pointer\nthat will later be passed to GetFrame.\n\nAVSValue is a variant type which can hold any one of the following: a\nboolean value (true/false); an integer; a floating-point number; a\nstring; a video clip (PClip); an array of AVSValues; or nothing\n(\"undefined\"). You can test which one it is with the methods IsBool(),\nIsInt(), IsFloat(), IsString(), IsClip(), IsArray(), and Defined()\n(which returns true if the AVSValue is not \"undefined\"). You can get\nthe value with AsBool(), AsInt(), etc. For arrays, you can use the\nArraySize() method to get the number of elements, and [] indexing to\nget the elements themselves. For convenience, IsFloat() and AsFloat()\nwill work with integers also. But boolean values are not treated as\nnumeric (unlike C).\n\nThe name \"Create_InvertNeg\" is arbitrary. This function will actually\nbe known as \"InvertNeg\" in scripts, because that's the name we pass to\n:ref:`AddFunction <cplusplus_addfunction>` below.\n::\n\n    return new InvertNeg(args[0].AsClip(), env);\n\n\nThe args argument passed to a script function will always be an array.\nThe return value should be any one of the other types (never an array).\n\nThe types of the values in the args array are guaranteed to match one\nof the function signatures that you pass to AddFunction, just as in\nVirtualDub. Therefore, there's no need to worry about IsClip here.\n\nCreate_InvertNeg simply creates and returns a filter instance; it is\nautomatically converted to an AVSValue via the constructor\nAVSValue(IClip*).\n::\n\n    const AVS_Linkage *AVS_linkage = 0;\n\n\nThis declares and initializes the server pointers static storage\n:doc:`AVS_Linkage <AVSLinkage>`.\n::\n\n    extern \"C\" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors) {\n\n\nThis is the only function which gets exported from the DLL. It is\ncalled by the script function LoadPlugin the first time this plugin in\nloaded in a particular script. If several scripts are open at once and\nmore than one of them loads this plugin, AvisynthPluginInit3 may be\ncalled more than once with different IScriptEnvironments. Therefore:\n\n* You should not save the env parameter in a global variable.\n* If you need to initialize any static data, you should do it in\n  DLLMain, not in this function.\n\n::\n\n    AVS_linkage = vectors;\n\n\nThis saves the server pointers.\n\nThe main purpose of the AvisynthPluginInit3 function is to call\nenv->AddFunction.\n::\n\n    env->AddFunction(\"InvertNeg\", \"c\", Create_InvertNeg, 0);\n\n\nAs promised, we now call AddFunction to let Avisynth know of the\nexistence of our filter. This function takes four arguments: the name\nof the new script function; the parameter-type string; the C++ function\nimplementing the script function; and the user_data cookie.\n\nThe parameter-type string can be specified as follows:\n\n* No return type is given. Function return values are not\n  type-checked; you can return anything you like.\n* There are more types: along with 'i'nt and 's'tring you can specify\n  'b'ool, 'f'loat, and 'c'lip.\n* The following types are available:\n    + c - clip\n    + i - integer\n    + f - float\n    + s - string\n    + b - boolean\n* You can follow any type with '*' or '+' to indicate \"zero or more\"\n  or \"one or more\" respectively. In this case all the matching\n  arguments will be gathered into a sub-array.\n\n  * For example, if your type string is \"is+f\", then the\n    integer argument will be args[0], the string arguments\n    will be args[1][0], args[1][1], etc. (and there will be\n    args[1].ArraySize() of them), and the float argument will\n    be args[2].\n\n* '.' matches a single argument of any type. To match multiple\n  arguments of any type, use \".*\" or \".+\".\n* You can have named arguments, by specifying the name in [brackets]\n  before the type. Named arguments are also optional arguments; if\n  the user omits them, they will be of the undefined type instead of\n  the type you specify. For convenience, AVSValue offers a set of\n  As...() functions which take default values. See avisynth.h.\n\n::\n\n    return \"InvertNeg sample plugin\";\n\n\nThe return value of AvisynthPluginInit3 is a string which can contain\nany message you like, such as a notice identifying the version and\nauthor of the plugin. This string becomes the return value of\nLoadPlugin, and will almost always be ignored. You can also just return\n0 if you prefer.\n\n\nA variation as an in place filter\n---------------------------------\n\nThe Invert filter could easily do its work in a single buffer, rather\nthan copying from one buffer to another. Here's a new implementation of\nGetFrame that does this.\n::\n\n    #include <windows.h>\n    #include \"avisynth.h\"\n\n    class InvertNeg : public GenericVideoFilter {\n    public:\n        InvertNeg(PClip _child, IScriptEnvironment* env);\n        PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n    };\n\n    InvertNeg::InvertNeg(PClip _child, IScriptEnvironment* env) :\n        GenericVideoFilter(_child) {\n        if (!vi.IsPlanar() || !vi.IsYUV()) {\n            env->ThrowError(\"InvertNeg: planar YUV data only!\");\n        }\n    }\n\n    PVideoFrame __stdcall InvertNeg::GetFrame(int n, IScriptEnvironment* env) {\n\n        PVideoFrame src = child->GetFrame(n, env);\n        env->MakeWritable(&src);\n\n        unsigned char* srcp;\n        int src_pitch, row_size, height;\n        int p, x, y;\n\n        int planes[] = {PLANAR_Y, PLANAR_V, PLANAR_U};\n\n        for (p=0; p<3; p++) {\n            srcp = src->GetWritePtr(planes[p]);\n\n            src_pitch = src->GetPitch(planes[p]);\n            row_size = src->GetRowSize(planes[p]);\n            height = src->GetHeight(planes[p]);\n\n            for (y = 0; y < height; y++) {\n                for (x = 0; x < row_size; x++) {\n                    srcp[x] = srcp[x] ^ 255;\n                    // even shorter would be srcp[x] ^= 255;\n                }\n                srcp += src_pitch;\n            }\n        }\n        return src;\n    }\n\n    AVSValue __cdecl Create_InvertNeg(AVSValue args, void* user_data, IScriptEnvironment* env) {\n        return new InvertNeg(args[0].AsClip(), env);\n    }\n\n    const AVS_Linkage *AVS_linkage = 0;\n\n    extern \"C\" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors) {\n        AVS_linkage = vectors;\n        env->AddFunction(\"InvertNeg\", \"c\", Create_InvertNeg, 0);\n        return \"InvertNeg sample plugin\";\n    }\n\n\nThe key difference between this version of the function and the\noriginal version is the presence of the :ref:`MakeWritable <cplusplus_makewritable>` callback. This\nis necessary because this time \"we don't know where that source frame\nhas been.\" Someone else in the filter chain may be holding a reference\nto it, in which case we won't be allowed to write to it.\n\nOld versions\n\n:doc:`Ben's AviSynth Docs <BensAviSynthDocs>` is the documentation written for AviSynth 1.0\nby Ben Rudiak-Gould, in its original form.\n\nSee more about the modifications for AviSynth 2.5 in the :doc:`AviSynth\nTwo-Five SDK <AviSynthTwoFiveSDK>`. (need to adjust the two-five version using the code above\n...)\n\n____\n\nBack to :doc:`FilterSDK`\n\n$Date: 2015/09/14 20:23:59 $\n\n.. _tutorial: http://www.cplusplus.com/doc/tutorial/classes\n.. _VirtualDub: http://avisynth.nl/index.php/VirtualDub\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/IsMovntqFaster.rst",
    "content": "\n`IsMovntqFaster`_\n=================\n\n*sh0dan writes:*\n\nIt seems movntq is only suited for direct memory copies - otherwise the\npenalty is simply too big.\n\nThe movntq was a big surprise for me too. It is definately faster in direct\ncopying (BitBlt) for instance, but not very useful in routines that actually\ndo some processing.\n\nThe data is not read again, and it is 8-byte aligned. But I guess the problem\nlies in the fast, that movntq cannot be defered. A movq to memory can be\nstored in the data cache for later storage, whereas movntq must be dispatched\ndirectly. When doing some processing the processor can take time to do the\nwrite.\n\nI saw some really big penalties in the AMD Pipeline analysis tool (most\nmovntq's took an average of 60 cycles!) It showed penalties for Data Cache\nmiss, and the Load/Store Queue being full. Using movq's, the average\ncycle/instruction was about 2-4, with the load-store queue doing ok.\n\nIt should be noted that the system I tested on were Athlon Tbird 1200, and an\nAthlon XP 2200+ - both with DDR RAM.\n\n**The conclusion can only be to benchmark your code, to be sure if you are\nactually gaining something from using movntq.**\n\n--------\n\n*phaeron writes:*\n\nMOVNTQ can be a win even in non-trivial routines if used carefully --\nVirtualDub's YCbCr-to-RGB conversions use it for a significant gain on large\nMPEG-1 files (around 640x360). However, it is definitely not to be used\nlightly.\n\nThe purpose of MOVNTQ is to defeat a cache optimization known as write-back.\nThe early caches introduced into x86 systems were initially write-through,\nmeaning that writes to memory not present in the cache went directly to main\nmemory. This led to some interesting behavior on Pentium systems where doing\ndummy reads periodically during heavy write loops would boost throughput,\nbecause the reads would pull memory into cache, the writes would then be\ncombined in the cache, and a lot more burst transfers would occur over the\nbus.\n\nBeginning with the Pentium Pro, Intel started using write-back as the L1\ncache strategy. Whenever a write occurs to an uncached location, the CPU\npulls an entire cache line of data from main memory, pushes the writes into\nthe L1 cache, and then later writes the line back to main memory. This is\ntypically a win as burst transfers to and from the cache are generally faster\nthan piecemeal 32-bit accesses. Where write-back hurts is when code is only\nwriting to memory -- in this case, the initial read is a waste as all of the\ncache line is going to be overwritten anyway.\n\nThe MOVNTQ instruction tells the CPU to use write combining (WC) instead of\nwrite-back (WB) as the mode for memory. Writes are then collected in write\ncombining buffers, which are bursted out to memory once full. This can be\nmuch, much faster than traditional methods  large memcpy() operations in\nparticular can be more than twice as fast  but there are a few caveats, as\nyou noticed. The biggest is that MOVNTQ is only efficient when data must be\nbounced back to main memory anyway; it is a loss when data can stay within\nthe caches, as otherwise without MOVNTQ the data would stay within the much\nfaster L1 and L2 caches. It is never a good idea to use MOVNTQ when you know\nthe target is in the cache. Another is that you **must** write all bytes in a\ncache line. Piecemeal writes with MOVNTQ result in partial bus transactions,\nwhich means that instead of a nice long burst, you get a bunch of small\nwrites. In a WB scenario the CPU already has all the data in the cache line\nand can rewrite the unwritten parts with the same data, but it can't do this\nwhen streaming writes are involved. Processing vertical columns of single\npixels at a time with MOVNTQ involved, for example, would be a bad idea.\n\nProfiling MOVNTQ can be tricky. A memcpy() rewritten to use block prefetching\nand streaming stores can execute more than twice as fast as REP MOVSD. What\nthe profile won't tell you is that by converting your memcpy() to streaming,\nyou slowed down the routine right after it that now suffers lots of cache\nmisses pulling the data back into memory. MOVNTQ is thus most useful when you\nare already suffering cache misses because your buffers are way too big, sit\ntoo long between the write and the next read, or need to bounce between CPUs.\nSometimes an even better idea than streaming stores is to block the various\npipeline stages into strips, thus keeping each strip in cache -- Intel calls\nthis \"strip mining.\" However, it is very difficult to do when many different\nmodules are involved, such as in an Avisynth filter graph.\n\n--------\n\n\nBack to :doc:`AssemblerOptimizing <AssemblerOptimizing>`\n\n$Date: 2025-02-24 21:31:01-05:00 $\n\n.. _IsMovntqFaster: http://avisynth.nl/index.php/Filter_SDK/Is_movntq_faster\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/MMX.rst",
    "content": "\nMMX\n===\n\nMMX is short for MultiMedia Extensions and was developed by Intel for Pentium MMX.\n\nIt contains a set of instructions that allows the programmers to operate on 8\nbytes (64 bits) in 8 registers. AviSynth uses this technology to speed up\nmany of the internal filters.\n\nFurthermore see :doc:`IntegerSSE <IntegerSSE>`.\n\nBack to :doc:`AssemblerOptimizing`\n\n$Date: 2014/10/27 22:04:54 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/Non-ClipSample.rst",
    "content": "\nNon-clip Sample\n===============\n\n\nNon-clip functions in plugins\n-----------------------------\n\nUnlike usual clip functions, non-clip functions return not frames of clip but\nsingle (scalar) value as AVSValue (variant of float, integer, boolean,\nstring).\n\nNumeric function example\n------------------------\n\nHere's a sample from script.cpp, edited for external use (by foxyshadis, see `discussion <http://forum.doom9.org/showthread.php?t=132026>`_):\n::\n\n     AVSValue Sin(AVSValue args, void* user_data, IScriptEnvironment*\n     env) { return sin(args[0].AsFloat()); }\n\n     extern \"C\" __declspec(dllexport) const char* __stdcall\n     AvisynthPluginInit2(IScriptEnvironment* env) {\n        env->AddFunction(\"sin\", \"f\", Sin, 0);\n        return \"sin\";\n     }\n\n\nYou don't even need a class/constructor, come to think of it.\nInclude avisynth.h and that could be a whole plugin right there. (If not\na terribly useful one.)\n\nClip to float function example\n------------------------------\n\nThere are Avisynth :ref:`Runtime functions <conditional-runtime-functions>` that evaluated at every frame. They\ncan be used inside the scripts passed to runtime filters (:doc:`ConditionalFilter, ScriptClip, FrameEvaluate <../corefilters/conditionalfilter>`) to return information for a\nframe. Here is sample code of plugin with non-clip function:\n::\n\n     /*\n        NonClipSample plugin for Avisynth -- a non-clip sample function for Conditional Filter\n\n        Copyright (C) 2007 Alexander Balakhnin 'Fizick' http://avisynth.org.ru\n\n        This program is free software; you can redistribute it and/or modify\n        it under the terms of the GNU General Public License as published by\n        the Free Software Foundation.\n\n        This program is distributed in the hope that it will be useful,\n        but WITHOUT ANY WARRANTY; without even the implied warranty of\n        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n        GNU General Public License for more details.\n\n        You should have received a copy of the GNU General Public License\n        along with this program; if not, write to the Free Software\n        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n        V1.0. Based on AverageLuma internal filter and SimpleSample\n\n        Usage:\n        ScriptClip(\" Subtitle(String(NonClipSample())) \")\n     */\n\n     //following 2 includes needed\n     #include \"windows.h\"\n     #include \"avisynth.h\"\n\n     // The function is called for every frame in conditional environment.\n     // Unlike usual clip functions, it returns not frames of clip but single (scalar) value\n     // as AVSValue (variant of float, integer, boolean, string)\n\n     AVSValue __cdecl NonClipSample(AVSValue args, void* user_data, IScriptEnvironment* env)\n     {\n        // This sample function calculate mean luma value for currect frame plane\n\n        // Get function paramenters from input args array\n\n                if (!args[0].IsClip()) // check validity\n                        env->ThrowError(\"NonClipSample: No clip supplied!\");\n\n                PClip child = args[0].AsClip(); // very first parameter is source clip\n\n        // Get clip video information\n                VideoInfo vi = child->GetVideoInfo();\n\n                if (!vi.IsPlanar())\n                        env->ThrowError(\"NonClipSample: Only planar images (as YV12) supported!\");\n\n        // get current frame number\n\n                AVSValue cn = env->GetVar(\"current_frame\");\n                if (!cn.IsInt())\n                        env->ThrowError(\"NonClipSample: This filter can only be used within Conditional Filter\");\n\n                int n = cn.AsInt(); // frame number\n\n        // Get source frame and its properties\n\n                PVideoFrame src = child->GetFrame(n,env); // source frame (smart pointer)\n                int plane = PLANAR_Y; // set plane to PLANAR_Y\n                const BYTE* srcp = src->GetReadPtr(plane); // pointer to plane data (framebuffer)\n                int height = src->GetHeight(plane);\n                int width = src->GetRowSize(plane);\n                int pitch = src->GetPitch(plane);\n\n        // calculate result of our function\n                unsigned int sum = 0; // init sum\n\n                for (int h=0; h < height; h++) {\n                        for (int w = 0; w < width; w++) {\n                                sum += srcp[w];          // sum each byte from source\n                        }\n                        srcp = srcp + pitch; // to next line\n                }\n                float average = (float)sum / (float)(height * width); // normalize sum to get average\n        // return float result as AVSValue\n                return (AVSValue)average;\n     }\n\n\n     // The following function is the function that actually registers the filter in AviSynth\n     // It is called automatically, when the plugin is loaded to see which functions this filter contains.\n\n     extern \"C\" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env) {\n         env->AddFunction(\"NonClipSample\", \"c\", NonClipSample, 0);\n        // The AddFunction has the following paramters:\n        // AddFunction(Filtername , Arguments, Function to call,0);\n\n        // Arguments is a string that defines the types and optional names of the arguments for you filter.\n        // c - Video Clip\n        // i - Integer number\n        // f - Float number\n        // s - String\n        // b - boolean\n\n         // The word inside the [ ] lets you used named parameters in your script\n\n        return \"NonClipSample plugin\";\n        // A freeform name of the plugin.\n     }\n\n\nCompile it as DLL like other AviSynth plugins\n\nNot processing frames plugin with Avisynth AtExit function\n----------------------------------------------------------\n\nThis plugin does not process frames. It loads a font into Windows and\nautomatically unloads it after avisynth is done running. To run code at the\nend of the script, it registers an ``env->AtExit`` procedure. See\n`this discussion <http://forum.doom9.org/showthread.php?t=130383>`_.\n::\n\n     /* LoadFont for avisynth\n\n       Created by Shin-san of Ishin Digital Anime Fansubbing\n       Special thanks to stickboy, Leak, and IanB of the doom9.org forums for the help\n       Special thanks to sh0dan for his simple sample script, which this file is based on\n\n       This code, if made public, is protected by the GPLv3, which can be found at\n       www.gnu.org. I'm too lazy to copy/paste it in here\n\n       Purpose: to make it so I can load a font into Windows and automatically unload it\n       after avisynth is done running\n     */\n\n     #include\n     #include \"avisynth.h\"\n\n     void __cdecl UnLoadFont(void* user_data, IScriptEnvironment* env);\n\n     AVSValue __cdecl Create_LoadFont(AVSValue args, void* user_data, IScriptEnvironment* env) {\n\n       char *file = args[1].AsString(\"\");\n\n       // and now load the font\n       if ( (AddFontResource( file )) > 0 )\n       {\n          SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);\n\n          env->AtExit(UnLoadFont, strdup(file) ); // register the procedure\n       }\n       else\n       {\n          env->ThrowError(\"LoadFont: Font load '%s' failed.\", file);\n       }\n       return args[0];\n     }\n\n     extern \"C\" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env)\n     {\n        env->AddFunction(\"LoadFont\", \"c[FONT]s\", Create_LoadFont, 0);\n\n        return \"'LoadFont' LoadFont plugin\";\n        // A freeform name of the plugin.\n     }\n\n     void __cdecl UnLoadFont(void* user_data, IScriptEnvironment* env)\n     {\n       char *loadedFont = (char*)user_data;\n\n       if (loadedFont && *loadedFont)\n       {\n          if ( RemoveFontResource(loadedFont) > 0 )\n          {\n             SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);\n          }\n          free(loadedFont);\n       }\n       return;\n     }\n\n\n----\n\nBack to :doc:`FilterSDK <FilterSDK>`\n\n$Date: 2014/11/12 06:57:07 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/PlanarImageFormat.rst",
    "content": "\nPlanarImageFormat\n=================\n\nWhen talking about planar and an :doc:`InterleavedImageFormat <InterleavedImageFormat>` the main\ndifference is how they are store in memory.\n\nPlanar images are stored with each color component separate.\n\nSome examples of planar formats are I420, YV12.\n\nFor more information these URL's:\n\n`<http://www.fourcc.org/fccyuv.htm#Planar%20YUV%20Formats>`_\n\n`<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/YUVFormats.asp>`_\n\n`<http://search.microsoft.com/gomsuri.asp?n=1&c=rp_Results&siteid=us/dev&target=http://msdn.microsoft.com/library/en-us/graphics/hh/graphics/dxvapxlfmt_7xgn.asp>`_\n\n----\n\nBack to :doc:`FilterSDK`\n\n$Date: 2014/10/27 22:04:54 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/SDKHistory.rst",
    "content": "\nSDK History\n===========\n\n\"Writing Avisynth plugins\" article was written by Ben Rudiak-Gould (Avisynth\ncreator).\n\n| It is taken from AviSynth 1.0 documentation as was (2000) at\n| `<http://math.berkeley.edu/~benrg/avisynth-extensions.html>`_.\n\n| The current (November 2006) mirror is at :\n| `<http://www.neuron2.net/www.math.berkeley.edu/benrg/avisynth-extensions.html>`_\n\n\nPreliminary version of AviSynth 2.0-2.5 FilterSDK documentation has been\ncreated at 2003 as a section of AviSynth online (wiki) documentation at the\nofficial AviSynth site `<http://avisynth.nl/index.php/Main_Page>`_.\n\nDevelopers:\n\nKlaus Post 'sh0dan' (AviSynthTwoFiveAudio, AviSynthTwoFivePixelType,\nAviSynthTwoFiveSDK, ChangeFrameSize, ColorSpaces, DataAlignment,\nDataStorageInAviSynth, EnvInvoke, EnvSaveString, SimpleMmxOptimization,\nTwoFiveInvert, TwoFiveFastInvert and some other wiki pages)\n\nWilbert Dijkhof 'Wilbert' (\"CompilingAvisynth\" and some other wiki pages).\n\nContributors:\nSimon Walters 'SiWalters' (SimpleSample 1.0 to 1.7 wiki pages)\n\n'trevlac' (\"SimpleSampleClass\" wiki page)\n\nAvery Lee 'phaeron' (some texts in \"AssemblerOptimizing\" wiki pages, \"as\nfreely available for any use\")\n\nThanks to other Avisynth community people for wiki pages\nimproving/correction!\n\nThe package of off-line AviSynth external FilterSDK documentation version\n2.5.7 was created at 2006 at sourceforge.net CVS for distribution with\nAviSynth v2.5.7 installation.\n\nMost documents were converted from wiki pages (some modifyed/updated). Some\nnew documents are added too.\n\nDevelopers:\n\nAlexander Balakhnin 'Fizick' (SDKNecessaries, SDKLicense, SDKHistory, wiki\npages converting/editing)\n\nIan Brabham 'IanB' (he promised to write something under GPL :)\n\nWilbert Dijkhof 'Wilbert' (at least he promised to edit \"CompilingPlugins\"\nsometimes :)\n...\n\n----\n\nBack to :doc:`FilterSDK <FilterSDK>`\n\n$Date: 2025-02-21 17:26:22-05:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/SDKLicense.rst",
    "content": "\nSDKLicense\n==========\n\n\nLicense terms of AviSynth external filter SDK distribution\n----------------------------------------------------------\n\n(draft until released)\n\nAviSynth External Filter SDK package (compilation)\nis Copyright (c)2003-2006 Avisynth rev.2 Developers Team,\nhttp://sourceforge.net/projects/avisynth2, http://avisynth.nl/index.php/Main_Page.\nIt is released with NO WARRANTY and freely usable/distributable\nunder terms of GNU General Public License (GPL) version 2 or later.\nSee full text of the license in `gpl.txt <../License/gpl.txt>`_ file.\nIt should have been included; if not, you may receive a copy at\nhttp://www.gnu.org/copyleft/gpl.html or by writing\nto the Free Software Foundation, Inc., 675 Mass Ave., Cambridge, MA 02139,\nUSA.\n\n\nHere are specific license terms of some parts of this package\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe header file 'avisynth.h' is a part of current release of Avisynth\nCopyright (c)2002 Ben Rudiak-Gould et al. http://avisynth.nl/index.php/Main_Page.\nIt is distributed under terms of GNU General Public License (GPL)\nand contains license exceptions giving you additional permissions\nbesides those granted in the GNU GPL.\nConsult the license block at the top of the file for information.\n\n\"Writing Avisynth plugins\" article is Copyright (c)2000 Ben Rudiak-Gould.\nWhole AviSynth v1.0 was distributed under terms of GNU GPL.\nFrom Bens's message (not directly related to the article and sample code\nthough):\n\"...regardless of my moral/ethical views, I don't think I have any legal\nbasis\nfor restricting the licensing terms of these plugins (and I never intended to\ndo so)...\"\n\n\nTwoFiveInvert, TwoFiveFastInvert, Limiter code samples, most other\ncode snippets in this package are Copyright (c)2003 Klaus Post ('sh0dan').\nDistributed under terms of GNU GPL with additional permission:\nYou may freely copy and modify these code samples and\ndistribute resulting work under terms of your choice provided that\nthis resulting work is independent module that communicates with Avisynth\nunder conditions defined in avisynth.h license block.\n\nAvisynth.def, avisynth.lib, avisynth.map and possible other extra files\nare distributed as part of current version of AviSynth\nCopyright(c)2002 Ben Rudiak-Gould et al. under terms of GNU GPL.\n\nSeveral versions of SimpleSample plugin source code are\nCopyright(c)2002 Simon Walters and distributed under terms of GNU GPL.\n\nAdditiveblend code samples and some other texts (signed 'phaeron')\nabout assembler optimization are Copyright (c)2003 Avery Lee. License terms\nare:\nYou may consider the text added by me to that article to be freely available\nfor any use.\n\nAny trademarks mentioned here are the property of their owners.\nTo the our knowledge no trademark or patent infringement exists in this\ndocument or this distribution; any such infringement is purely unintentional.\n\nIn a case of some copyright or other questions, please contact us\nat sourceforge.net/projects/avisynth2 or at Avisynth Development forum at\ndoom9.org.\n\nSee :doc:`SDK History <SDKHistory>` for some details.\n\n\nAppeal to plugin authors\n------------------------\n\n::\n\n    We invite you to distrubute your AviSynth plugins under\n    GNU GPL license in the spirit of open source AviSynth project.\n    Whole AviSynth community will help you in plugin development and\n    improving.\n    To do it, simply place your copyright statement and GNU GPL license\n    comment block at the top of your souce code (see SimpleSample code\n    for example)\n    and release your plugin with the source code (and gpl.txt) included.\n    (You may not act differently if your plugin contains some source code\n    under GNU GPL.)\n\n          With best personal regards,\n          Avisynth rev.2 Developers Team\n          http://sourceforge.net/projects/avisynth2,\n          http://avisynth.nl/index.php/Main_Page\n\n----\n\nBack to :doc:`FilterSDK <FilterSDK>`\n\n$Date: 2025-02-21 17:28:23-05:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/SDKNecessaries.rst",
    "content": "\nSDKNecessaries\n==============\n\nYou must have some compatible development tool\n----------------------------------------------\n\n- Historically there were Microsoft Visual C/C++ 9 (2008), 10 (2010),\n  11 (2012), 12 (2013), 14 (2017), 15 (2019) versions.\n- Actual source requires c++ 17. (or c++1z for gcc 7.0)\n- Microsoft compilers:\n\n  As of March 2023 the latest one is Microsoft Visual C++ 2022 (v16) and \n  Microsoft Visual C++ 2019 (v15)\n\n  Community Edition is free for open source development.\n  (`free download <http://www.visualstudio.com/en-us/downloads/>`__\n  (web version is fine); )\n  \n  Both 2019 and 2022 versions still support Windows XP when you include Visual Studio 2017 XP (v141_xp) platform toolset in the customized installation.\n  (Though user must not update their VC++ redistributables after a specific version point, when XP support has been stopped)\n  \n- Intel ICX NextGen 2024.1, 2023, 2021.4 or ICL 2021.4 (19.2 Classic)\n\n  You need either or both Intel C++ compiler engine:\n  \n  - Intel C++ 2021, 2023, 2024 (ICX: LLVM based NextGen) in Base Kit\n  \n    Intel oneAPI Base Kit `download <https://www.intel.com/content/www/us/en/developer/articles/news/free-intel-software-developer-tools.html>`__\n\n    We need it for Intel® oneAPI DPC++/C++ Compiler. It includes DPC++ but this flavour of compiler is not suitable for Avisynth+.\n\n  - Intel C++ Classic (ICL 19.2) addon in HPC toolkit\n\n    From Intel oneAPI toolkit explorer homepage choose Intel® oneAPI HPC Toolkit\n    <https://www.intel.com/content/www/us/en/developer/tools/oneapi/toolkits.html#hpc-kit>\n    \n    The oneAPI HPC Toolkit is an addon (complements) to the base toolkit.\n    For less disk space and omit unnecassary components, choose Custom Installation (Fortran support not needed)\n\n  During installation they integrate with Visual Studio IDE (2017, 2019 and 2022). \n  The Intel 2024 compiler version no longer supports VS2017.\n  Note: when you install VS2022 after installing base toolkit,\n  you'll need to install the toolkit again to have VS2022 integration.\n\n- LLVM 9 and up, or use LLVM (clang-cl) platform toolset integrated into Visual Studio\n- Gnu C++ 9.0 (7.0 with special flags is working as well)\n\nNotes\n\n- AviSynth+ is no longer restricted to Windows and Intel processors.\n  It runs under several platforms: Linux, Haiku, MacOS.\n  Either gcc or clang compilers are used for them.\n\n  See also:\n\n  :doc:`Contributing with git <../contributing/contributing_with_git>`,\n  :doc:`Compiling AviSynth+ <../contributing/compiling_avsplus>` and\n  :doc:`posix <../contributing/posix>`.\n\n- Free registration is mandatory to use Community Edition versions\n- Targeting Windows XP requires v141_xp (Visual Studio 2017 - XP) platform toolset\n  along with a special compiler flag. Moreover XP requires that running system must not have the latest VC++ redistributable but the last XP compatible one.\n\nOur aim is that sources can be built with all these compilers.\nThough AviSynth+ itself requires c++17, plugins are not obeyed to use it.\n\n\nYou also need in Microsoft Platform SDK (if it is not included with compiler)\n-----------------------------------------------------------------------------\n\nFor MS VC++ 2008 or more recent it is included in the compiler (?) (and\nit is called Windows PSK).\n\nFor some very special plugins (GPU) you might need the DirectX SDK\n(when compiling AviSynth itself you will need it).\n\n\nFinally, you must include the main header file 'avisynth.h'\n------------------------------------------------------------\n\nAvisynth+ source code can be found on github.\n`github repository <https://github.com/AviSynth/AviSynthPlus>`__\n\nFor plugin development you can get the header with this FilterSDK, or download \nwith AviSynth source code, or take from some plugin source package.\nThere are several versions of this header file from various AviSynth versions.\n\nHeader file avisynth.h from v1.0.x to v2.0.x have\n``AVISYNTH_INTERFACE_VERSION = 1.`` Plugins compiled with them will not be\n(natively) compatible with AviSynth 2.5.x.\n\nHeader file avisynth.h from v2.5.0 to v2.5.5 have\n``AVISYNTH_INTERFACE_VERSION = 2.`` Plugins compiled with them will\n(generally) work in AviSynth v2.5.0 to v2.5.7 (and above). But avisynth.h\nfiles from versions v2.5.0 - v2.5.5 (and betas) are not identical. We\nrecommend to use avisynth.h from versions 2.5.5 or later. Previous versions\nof avisynth.h are obsolete and have some bugs.\n\nHeader file avisynth.h from v2.5.6 to v2.5.8 are almost identical and have\n``AVISYNTH_INTERFACE_VERSION = 3.`` Plugins compliled with them will work in\nv2.5.6 and up, and v2.5.5 and below if you do not use new\ninterface features and do not call ``env->CheckVersion`` function.\n\nAviSynth version 2.6 and Avisynth+ versions up to 3.5.1 are using\ncurrently ``AVISYNTH_INTERFACE_VERSION = 6.`` Plugins compiled with\nAviSynth v2.5.x header will work in AviSynth 2.6.x and specific\n(without script array support) Avisynth+ versions.\n\nNote: since Avisynth+ ``avisynth.h`` alone is not enough, some other helper headers\nexist under ``avs`` folder.\n\nAvisynth+ version (though a bit late) changed version to\n``AVISYNTH_INTERFACE_VERSION = 7.``\n\nFrom AviSynth+ version 3.6.0 new interface functions arrived\nalong with frame properties support\n``AVISYNTH_INTERFACE_VERSION = 8.``\n\nFrom AviSynth+ version 3.7.1.test.32 new interface functions arrived\n``AVISYNTH_INTERFACE_VERSION = 8`` ``AVISYNTH_INTERFACE_BUGFIX = 1``\nor ``AVISYNTH_INTERFACE_VERSION = 9``\n\nFrom AviSynth+ version 3.7.3 new interface functions arrived\n``AVISYNTH_INTERFACE_VERSION = 10``\n\nGenerally good start is to take some similar plugin source code as a draft\nfor improving or own development. Attention: there are many old plugins\nsource code packages with older avisynth.h included. Simply replace it by new one.\n\n\n\nCompiling options\n-----------------\n\nOn Windows plugin CPP source code must be compiled as Win32 or x64 DLL (multi-threaded (MT) or\nmulti-threaded DLL (MD)) without MFC. Latter is recommended in general and\nrequires the actual Microsoft Visual C++ redistributables.\n\nIn Visual Studio Windows XP builds require v141_xp platform toolset \n(Visual Studio 2022's default is v143, Visual Studio 2019's default is v142) along \nwith compiler option /Zc:threadSafeInit-\n\nNote that GCC and the other builds cannot be mixed due to the different ABI.\nThis affects \"only\" C++ (and not C) interface but since 99% of plugins are using C++ \ninterfaces we can say that GCC Avisynth host and non-GCC user plugins are fully incompatible.\n\nOf course, use Release build with optimization.\n\nUse CMake make environment, for MSVC it generates the solution file as well\n(note: you cannot have both x86 and x64 configured in the solution at the same time)\n\nSee step by step :doc:`compiling instructions. <CompilingAvisynthPlugins>`\n\n\nOther compilers\n---------------\nnote from 2021: this section maybe a bit outdated.\n\nSince v2.5.7, AviSynth includes an updated version of Kevin Atkinson's\nAviSynth C API you can use to create \"C-Plugins\" with compilers such as\nGNU C++, Visual Basic and Delphi.\n\nYou can NOT use the C++ API with compilers like GNU C++ to create\nplugins, because of :doc:`binary incompatibilities <CompilingAvisynthPlugins>`.\n\nThere is also `Pascal conversion of avisynth_c.h`_ by Myrsloik\n\nSome info about `Using in Visual Basic`_\n\n`PureBasic port of the Avisynth C Interface`_ by Inc\n\nThere is also `AvsFilterNet`_ wrapper for Avisynth in .NET (any .NET\nlanguage) by SAPikachu, see `discussion`_\n\n----\n\nBack to :doc:`FilterSDK <FilterSDK>`\n\n$Date: 2024/05/02 10:19 $\n\n.. _[1]:\n   http://www.google.nl/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&ved=0CCoQFjAA&url=http://go.microsoft.com/?linkid=7729279&ei=HfWhUuTjL8Og0wW7wYDwBw&usg=AFQjCNEulTGchEeozkLGRH8LZELiTKlC5A&sig2=Mi7Rwn_jNL5Qffi7LiGS3w&bvm=bv.57752919,d.d2k\n.. _[5]: http://www.visualstudio.com/en-us/downloads/\n.. _[7]: http://www.microsoft.com/en-us/download/details.aspx?id=15656\n.. _LLVM / clang: https://releases.llvm.org/download.html\n.. _CodeBlocks: http://www.codeblocks.org\n.. _Microsoft site: http://www.microsoft.com/downloads/details.aspx?familyid=EBA0128F-A770-45F1-86F3-7AB010B398A3&displaylang=en\n.. _Pascal conversion of avisynth_c.h:\n    http://forum.doom9.org/showthread.php?t=98327\n.. _Using in Visual Basic: http://forum.doom9.org/showthread.php?t=125370\n.. _PureBasic port of the Avisynth C Interface:\n    http://forum.doom9.org/showthread.php?t=126530\n.. _AvsFilterNet: http://www.codeplex.com/AvsFilterNet\n.. _discussion: http://forum.doom9.org/showthread.php?t=144663\n.. _direct link: http://go.microsoft.com/?linkid=9709949\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/SimpleMmxOptimization.rst",
    "content": "\nSimpleMmxOptimization\n=====================\n\nThis will cover some basics in assembler optimization, and the syntax to use\nin Visual Studio C++ for inline assembler.\n\nThis will cover a basic routine in C++, and how it is converted to MMX. The\nexample is from an actual filter in AviSynth, with only minor changes.\n\nConsider the following C-routing:\n::\n\n  void Limiter::c_limiter(BYTE* p, int row_size, int height, int modulo, int cmin, int cmax) {\n\n      for(y = 0; y < height; y++) {\n          for(int x = 0; x < row_size; x++) {\n              if(p[x] < cmin)\n                  p[x] = cmin;\n              else if(p[x] > cmax)\n                  p[x] = cmax;\n          }\n\n          p += row_size+modulo;\n\n          }\n      }\n\nThe parameters of this routine is:\n\n-   *p* - a pointer to the information being processed.\n-   *row_size* - the width of a row in bytes.\n-   *height* - the height of the image in bytes.\n-   *modulo* - the difference between the pitch and the rowsize (pitch -\n    rowsize).\n-   *cmin, cmax* - the maximum and minimum values of a pixel.\n\nWhen converting to :doc:`MMX <MMX>` and :doc:`IntegerSSE <IntegerSSE>` it is a good thing to look at\nwhich commands are available for the task needed. In this case we choose to\nfocus on :doc:`IntegerSSE <IntegerSSE>`, because it contains pminub and pmaxub, which selects\nthe minimum and maximum bytes of two packed registers. It is always a good\nidea to support plain MMX, since there are still many machines out there,\nthat only support these instructions.\n\nAn important aspect of MMX is parallel processing. That means processing\nseveral bytes at once. The MMX instructions all work on 8 bytes at the time,\nbut in many cases, you have to unpack these bytes to words (8 to 16 bits) to\nbe able to do things like additions, etc.)\n\nThe equivalent of the routine above in :doc:`IntegerSSE <IntegerSSE>` looks like this:\n::\n\n  void Limiter::isse_limiter_mod8(BYTE* p, int row_size, int height, int modulo, int cmin, int cmax) {\n\n      cmax|=(cmax<<8);\n\n      cmin|=(cmin<<8);\n\n      __asm {\n          mov eax, [height]\n          mov ebx, p\n          mov ecx, [modulo]\n          movd mm7,[cmax]\n          movd mm6,[cmin]\n          pshufw mm7,mm7,0\n          pshufw mm6,mm6,0\n\n          yloop:\n          mov edx,[row_size]\n\n          align 16\n          xloop:\n          movq mm0,[ebx]\n          pminub mm0,mm7\n          pmaxub mm0,mm6\n          movq [ebx],mm0\n          add ebx,8\n          sub edx,8\n          jnz xloop\n          add ebx,ecx;\n          dec eax\n          jnz yloop\n          emms\n      }\n  }\n\n\nThis routine performs the same task as the routine above. The filter requires\nmod8 rowsize, because it processes 8 pixels in parallel.\n\nLet's go through the code, line by line.\n\n``cmax|=(cmax<<8);``\n\n``cmin|=(cmin<<8);``\n\nThis is code is plain C,\nand can be seen as preparation for the assembler. Writing the same code is of\ncourse possible in assembler, but there is no speed gain at all, since this\nis only used once.\n\n``__asm {``\n\nThis shows MSVC, that an assembler block\nis coming. When you enter an assembler block you have to assume that all your\nregisters contain garbage. There are 6 general purpose 32-bit registers, that\ncan be used freely within the assembler block, these are *eax, ebx, ecx, edx,\nesi* and *edi*.\n\n``mov eax, [height]``\n\n``mov ebx, p``\n\n``mov ecx, [modulo]``\n\nIn these lines we put data into the registers. eax contains the\nheight, ebx contains a pointer to the plane we are processing, ecx contains\nthe modulo information. Note that the destination is always written FIRST. So\nthe first line translates to \"move height into eax\".\n\n``movd mm7,[cmax]``\n\n``movd mm6,[cmin]``\n\nThese two lines move data into the mmx registers - there are 8 mmx registers, named from mm0 to mm7.\n\nmm7 now contains \"0x0000|0000|0000|cmcm\" (| on inserted for readability).\nRemember we duplicated the max and min values in the C-part.\n\n``pshufw mm7,mm7,0``\n\n``pshufw mm6,mm6,0``\n\nThese commands are\n:doc:`IntegerSSE <IntegerSSE>` commands. They can shuffle around words in the mmx registers,\nbased on the last number.\n\nIn this example it results in mm7 containing \"0xcmcm|cmcm|cmcm|cmcm\". So\nbasically cmax and cmin are now placed in all 8 bytes in the mm6 and mm7\nregisters.\n\n``yloop:``\n\nThis is a jump destination for a jump routine.\n\n``mov edx,[row_size]``\n\nEvery time we are looping on y, the rowsize is moved into edx.\n\n``align 16``\n\n``xloop:``\n\nThe \"align 16\" is to be used before any loop destination, that will be\nfrequently used. It inserts commands that doesn't do anything, and ensures\nthat the xloop destination will be aligned on a 16 byte boundary.\n\n``movq mm0,[ebx]``\n\nThis command moves 8 bytes from the memory location in ebx into the mm0 register.\n\nmm0 now contains 0xp8p7|p6p5|p4p3|p2p1, where p1 is the leftmost pixel\nonscreen. This may look a bit backwards at first, but you'll get used to it.\n\n``pminub mm0,mm7``\n\n``pmaxub mm0,mm6``\n\nThese commands compares each byte, and take the minimum and maximum and place it in mm0. (Remember -\nresult is always placed in the first register).\n\n``movq [ebx],mm0``\n\nThis will put back the new values into the memory location that ebx points to.\n\n``add ebx,8``\n\nThis command will add 8 to the pointer in ebx - making it\nmove on to the next 8 pixels. Remember: This is only the pointer we are\nincrementing - we are not actually reading it, so even if this values gets\nout of bounds nothing will happend here.\n\n``sub edx,8``\n\n``jnz xloop``\n\nHere we subtract 8 from edx, and jump to the xloop location if the\nvalues in edx isn't 0 (jump if not zero).\n\n``add ebx,ecx;``\n\n``dec eax``\n\n``jnz yloop``\n\nThis is the code that gets executed whenever the xloop\nis finished. Here we add modulo to the ebx-pointer, decrements height and\njumps to the yloop as long as there are still pixels left to process.\n\n``emms``\n\nThis instruction must be placed after all mmx code. It reenabled\nfloat point code, which is disabled by mmx code.\n\n----\n\nBack to :doc:`AssemblerOptimizing <AssemblerOptimizing>`\n\n$Date: 2014/10/27 22:04:54 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/SimpleSample.rst",
    "content": "\nSimpleSample\n============\n\nHere are the sources for the series of examples developed in `[this]`_ thread.\n\nNote: the samples are for version 2.5\n\n:doc:`SimpleSample 1.0b <SimpleSample10b>` - simple documented sample that just copies the source\nframe to the destination in RGB and YUV colourspaces.\n\n:doc:`SimpleSample 1.1 <SimpleSample11>` - additions to handle planar colourspaces (e.g. YV12).\n\n:doc:`SimpleSample 1.2 <SimpleSample12>` - Revert to RGB24 colourspace only to show simple pixel\nmanipulation.\n\n:doc:`SimpleSample 1.3a <SimpleSample13a>` - Add in code to handle parameters in filters.\n\n:doc:`SimpleSample 1.4 <SimpleSample14>` - Add in RGB32 colourspace code.\n\n:doc:`SimpleSample 1.5a <SimpleSample15a>` - Add in YUY2 code.\n\n:doc:`SimpleSample 1.6 <SimpleSample16>` - and finally YV12 as well.\n\n:doc:`SimpleSample 1.7 <SimpleSample17>` - Add in ability to use info from 2 clips only the YUY2\ncolorspace code altered.\n\n:doc:`Classes and function calls in AviSynth plugins <SimpleSampleClass>` - about classes and\nfunction calls in AviSynth plugins.\n\n:doc:`SimpleSample for AviSynth 2.6 <SimpleSample26>` - a rewritten version that supports all of\n2.6's color formats.\n\n----\n\nBack to :doc:`FilterSDK <FilterSDK>`\n\n$Date: 2006/11/24 18:21:26 $\n\n.. _[this]: http://forum.doom9.org/showthread.php?s=&threadid=48261\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/SimpleSample10b.rst",
    "content": "\n`SimpleSample 1.0b`_\n====================\n\n`SimpleSample 1.0b: <http://www.geocities.com/siwalters_uk/SimpleSample10b.zip>`_\n\nHere is the code:-\n\n::\n\n    /*    SimpleSample plugin for Avisynth -- a simple sample\n\n        Copyright (C) 2002-2003 Simon Walters, All Rights Reserved\n\n        This program is free software; you can redistribute it and/or\n    modify\n        it under the terms of the GNU General Public License as published\n    by\n        the Free Software Foundation.\n\n        This program is distributed in the hope that it will be useful,\n        but WITHOUT ANY WARRANTY; without even the implied warranty of\n        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n        GNU General Public License for more details.\n\n\n        You should have received a copy of the GNU General Public License\n        along with this program; if not, write to the Free Software\n        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n        The author can be contacted at:\n        Simon Walters\n        siwalters@hotmail.com\n\n        V1.0 - 1st release.\n        V1.0a - Revised version to put colourspace checking in the right\n    place.\n      V1.0b - Added detailed comments.  // sh0dan\n\n    */\n    //following 2 includes needed\n    #include \"windows.h\"\n    #include \"avisynth.h\"\n\n    /****************************\n     * The following is the header definitions.\n     * For larger projects, move this into a .h file\n     * that can be included.\n     ****************************/\n\n\n    class SimpleSample : public GenericVideoFilter {\n      // SimpleSample defines the name of your filter class.\n      // This name is only used internally, and does not affect the name of your filter or similar.\n      // This filter extends GenericVideoFilter, which incorporates basic functionality.\n      // All functions present in the filter must also be present here.\n\n    public:\n      // This defines that these functions are present in your class.\n      // These functions must be that same as those actually implemented.\n      // Since the functions are \"public\" they are accessible to other classes.\n      // Otherwise they can only be called from functions within the class itself.\n\n        SimpleSample(PClip _child, IScriptEnvironment* env);\n      // This is the constructor. It does not return eny value, and is always used,\n      //  when an instance of the class is created.\n      // Since there is no code in this, this is the definition.\n\n        PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n      // This is the function that AviSynth calls to get a given frame.\n      // So when this functions gets called, the filter is supposed to return frame n.\n    };\n\n    /***************************\n     * The following is the implementation\n     * of the defined functions.\n     ***************************/\n\n    SimpleSample::SimpleSample(PClip _child, IScriptEnvironment* env) :\n    GenericVideoFilter(_child) {\n      // This is the implementation of the constructor.\n      // The child clip (source clip) is inherited by the GenericVideoFilter,\n      //  where the following variables gets defined:\n      //   PClip child;   // Contains the source clip.\n      //   VideoInfo vi;  // Contains videoinfo on the source clip.\n\n        if (vi.IsPlanar()) // is input planar?\n                env->ThrowError(\"SimpleSample: input to filter must be in YUY2 or RGB\");\n        // This filter does not not support planar images.\n    }\n\n\n\n    PVideoFrame __stdcall SimpleSample::GetFrame(int n,\n    IScriptEnvironment* env) {\n    // This is the implementation of the GetFrame function.\n    // See the header definition for further info.\n\n        PVideoFrame src = child->GetFrame(n, env);\n       // Request frame 'n' from the child (source) clip.\n        PVideoFrame dst = env->NewVideoFrame(vi);\n       // Construct a frame based on the information of the current frame\n       // contained in the \"vi\" struct.\n\n        const unsigned char* srcp = src->GetReadPtr();\n      // Request a Read pointer from the source frame.\n      // This will return the position of the upperleft pixel in YUY2 images,\n      // and return the lower-left pixel in RGB.\n      // RGB images are stored upside-down in memory.\n      // You should still process images from line 0 to height.\n\n        unsigned char* dstp = dst->GetWritePtr();\n        // Request a Write pointer from the newly created destination image.\n      // You can request a writepointer to images that have just been\n      // created by NewVideoFrame. If you recieve a frame from\n      PClip->GetFrame(...)\n      // you must call env->MakeWritable(&frame) be recieve a valid write pointer.\n\n        const int dst_pitch = dst->GetPitch();\n      // Requests pitch (length of a line) of the destination image.\n      // For more information on pitch see:\n      // http://avisynth.nl/index.php/Filter_SDK/Working_with_images\n\n        const int dst_width = dst->GetRowSize();\n      // Requests rowsize (number of used bytes in a line.\n      // See the link above for more information.\n\n        const int dst_height = dst->GetHeight();\n      // Requests the height of the destination image.\n\n        const int src_pitch = src->GetPitch();\n        const int src_width = src->GetRowSize();\n        const int src_height = src->GetHeight();\n\n        int w, h;\n\n      for (h=0; h < src_height;h++) {               // Loop from top line to bottom line.\n                for (w = 0; w < src_width; w++)     // Loop from left side of the image to the right side.\n                        *(dstp + w) = *(srcp + w);  // Copy each byte from source to destination.\n                srcp = srcp + src_pitch;            // Add the width of one line (in bytes) to the source image.\n                dstp = dstp + dst_pitch;            // Add the width of one line (in bytes) to the destination.\n        }\n        // end copy src to dst\n\n      // As we now are finished processing the image, we return the destination image.\n        return dst;\n    }\n\n\n    // This is the function that created the filter, when the filter has been called.\n    // This can be used for simple parameter checking, so it is possible to create different filters,\n    // based on the arguments recieved.\n\n    AVSValue __cdecl Create_SimpleSample(AVSValue args, void* user_data,\n    IScriptEnvironment* env) {\n        return new SimpleSample(args[0].AsClip(),env);\n        // Calls the constructor with the arguments provied.\n    }\n\n\n    // The following function is the function that actually registers the filter in AviSynth\n    // It is called automatically, when the plugin is loaded to see which functions this filter contains.\n\n    extern \"C\" __declspec(dllexport) const char* __stdcall\n    AvisynthPluginInit2(IScriptEnvironment* env) {\n        env->AddFunction(\"SimpleSample\", \"c\", Create_SimpleSample,\n        0);\n        // The AddFunction has the following paramters:\n        // AddFunction(Filtername , Arguments, Function to call,0);\n\n        // Arguments is a string that defines the types and optional names of the arguments for you filter.\n        // c - Video Clip\n        // i - Integer number\n        // f - Float number\n        // s - String\n        // b - boolean\n\n        return \"`SimpleSample' SimpleSample plugin\";\n        // A freeform name of the plugin.\n    }\n\n\n$Date: 2025-02-24 21:05:09-05:00 $\n\n.. _SimpleSample 1.0b: http://avisynth.nl/index.php/Filter_SDK/Simple_sample_1.0b\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/SimpleSample11.rst",
    "content": "\n`SimpleSample 1.1`_\n===================\n\n`SimpleSample 1.1: <http://www.geocities.com/siwalters_uk/simplesample11.zip>`_\n\n::\n\n    /*\n        SimpleSample plugin for Avisynth -- a simple sample\n\n        Copyright (C) 2002-2003 Simon Walters, All Rights Reserved\n\n        This program is free software; you can redistribute it and/or\n    modify\n        it under the terms of the GNU General Public License as published\n    by\n        the Free Software Foundation.\n\n        This program is distributed in the hope that it will be useful,\n        but WITHOUT ANY WARRANTY; without even the implied warranty of\n        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n        GNU General Public License for more details.\n\n        You should have received a copy of the GNU General Public License\n        along with this program; if not, write to the Free Software\n        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n        The author can be contacted at:\n        Simon Walters\n        siwalters@hotmail.com\n\n        V1.0 - 1st release.\n        V1.0a - Revised version to put colourspace checking in the right\n    place.\n      V1.0b - Added detailed comments.  // sh0dan\n        V1.1 - Added sh0dan's planar (YV12) code\n\n    */\n    //following 2 includes needed\n    #include \"windows.h\"\n    #include \"avisynth.h\"\n\n    /****************************\n     * The following is the header definitions.\n     * For larger projects, move this into a .h file\n     * that can be included.\n     ****************************/\n\n\n    class SimpleSample : public GenericVideoFilter {\n      // SimpleSample defines the name of your filter class.\n      // This name is only used internally, and does not affect the name of your filter or similar.\n      // This filter extends GenericVideoFilter, which incorporates basic functionality.\n      // All functions present in the filter must also be present here.\n\n    public:\n      // This defines that these functions are present in your class.\n      // These functions must be that same as those actually implemented.\n      // Since the functions are \"public\" they are accessible to other classes.\n      // Otherwise they can only be called from functions within the class itself.\n\n        SimpleSample(PClip _child, IScriptEnvironment* env);\n      // This is the constructor. It does not return eny value, and is always used,\n      //  when an instance of the class is created.\n      // Since there is no code in this, this is the definition.\n\n        PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n      // This is the function that AviSynth calls to get a given frame.\n      // So when this functions gets called, the filter is supposed to return frame n.\n    };\n\n    /***************************\n     * The following is the implementation\n     * of the defined functions.\n     ***************************/\n\n    SimpleSample::SimpleSample(PClip _child, IScriptEnvironment* env) :\n    GenericVideoFilter(_child) {\n      // This is the implementation of the constructor.\n      // The child clip (source clip) is inherited by the GenericVideoFilter,\n      //  where the following variables gets defined:\n      //   PClip child;   // Contains the source clip.\n      //   VideoInfo vi;  // Contains videoinfo on the source clip.\n      // There is no colourspace code check code here now as this version copes with all\n      // Avisynth 2.5 colourspaces\n    }\n\n\n\n    PVideoFrame __stdcall SimpleSample::GetFrame(int n,\n    IScriptEnvironment* env) {\n    // This is the implementation of the GetFrame function.\n    // See the header definition for further info.\n\n        PVideoFrame src = child->GetFrame(n, env);\n       // Request frame 'n' from the child (source) clip.\n        PVideoFrame dst = env->NewVideoFrame(vi);\n       // Construct a frame based on the information of the current frame\n       // contained in the \"vi\" struct.\n\n        const unsigned char* srcp = src->GetReadPtr();\n      // Request a Read pointer from the source frame.\n      // This will return the position of the upperleft pixel in YUY2 images,\n      // and return the lower-left pixel in RGB.\n      // RGB images are stored upside-down in memory.\n      // You should still process images from line 0 to height.\n\n        unsigned char* dstp = dst->GetWritePtr();\n        // Request a Write pointer from the newly created destination image.\n      // You can request a writepointer to images that have just been\n      // created by NewVideoFrame. If you recieve a frame from\n      PClip->GetFrame(...)\n      // you must call env->MakeWritable(&frame) be recieve a valid write pointer.\n\n        const int dst_pitch = dst->GetPitch();\n      // Requests pitch (length of a line) of the destination image.\n      // For more information on pitch see:\n      // http://avisynth.nl/index.php/Filter_SDK/Working_with_images\n        // (short version - pitch is always equal to or greater than width to allow for seriously fast assembly code)\n\n        const int dst_width = dst->GetRowSize();\n      // Requests rowsize (number of used bytes in a line.\n      // See the link above for more information.\n\n        const int dst_height = dst->GetHeight();\n      // Requests the height of the destination image.\n\n        const int src_pitch = src->GetPitch();\n        const int src_width = src->GetRowSize();\n        const int src_height = src->GetHeight();\n\n        int w, h;\n\n      for (h=0; h < src_height;h++) {               // Loop from starting line to last line.\n                                                    // (Bottom to top line if RGB space, top to bottom line all others\n                for (w = 0; w < src_width; w++)     // Loop from left side of the image to the right side.\n                        *(dstp + w) = *(srcp + w);  // Copy each byte from source to destination.\n                srcp = srcp + src_pitch;            // Add the pitch (note use of pitch and not width) of one line (in bytes) to the source image.\n                dstp = dstp + dst_pitch;            // Add the pitch of one line (in bytes) to the destination.\n        }\n        // end copy src to dst\n\n      // The preceding code deals with all colourspaces but only copies the Y (luma) information\n      // of planar colourspaces. This new section of code deals with the U and V planes of planar\n      // formats (e.g. YV12).  The code is functionally identical with the previous code above.\n\n        const int dst_pitchUV = dst->GetPitch(PLANAR_U);        // The pitch,height and width information\n        const int dst_widthUV = dst->GetRowSize(PLANAR_U);      // is guaranted to be the same for both\n        const int dst_heightUV = dst->GetHeight(PLANAR_U);      // the U and V planes so we only the U\n        const int src_pitchUV = src->GetPitch(PLANAR_U);        // plane values and use them for V as\n        const int src_widthUV = src->GetRowSize(PLANAR_U);      // well\n        const int src_heightUV = src->GetHeight(PLANAR_U);      //\n\n        //Copy U plane src to dst\n        srcp = src->GetReadPtr(PLANAR_U);\n        dstp = dst->GetWritePtr(PLANAR_U);\n\n        for (h=0; h < src_heightUV;h++) {\n                for (w = 0; w < src_widthUV; w++)\n                        *(dstp + w) = *(srcp + w);\n                srcp = srcp + src_pitchUV;\n                dstp = dstp + dst_pitchUV;\n        }\n        // end copy U plane src to dst\n\n        //Copy V plane src to dst\n        srcp = src->GetReadPtr(PLANAR_V);\n        dstp = dst->GetWritePtr(PLANAR_V);\n\n        for (h=0; h < src_heightUV;h++) {\n                for (w = 0; w < src_widthUV; w++)\n                        *(dstp + w) = *(srcp + w);\n                srcp = srcp + src_pitchUV;\n                dstp = dstp + dst_pitchUV;\n        }\n        // end copy V plane src to dst\n\n\n      // As we now are finished processing the image, we return the destination image.\n        return dst;\n    }\n\n\n    // This is the function that created the filter, when the filter has been called.\n    // This can be used for simple parameter checking, so it is possible to create different filters,\n    // based on the arguments recieved.\n\n    AVSValue __cdecl Create_SimpleSample(AVSValue args, void* user_data,\n    IScriptEnvironment* env) {\n        return new SimpleSample(args[0].AsClip(),env);\n        // Calls the constructor with the arguments provied.\n    }\n\n\n    // The following function is the function that actually registers the filter in AviSynth\n    // It is called automatically, when the plugin is loaded to see which functions this filter contains.\n\n    extern \"C\" __declspec(dllexport) const char* __stdcall\n    AvisynthPluginInit2(IScriptEnvironment* env) {\n        env->AddFunction(\"SimpleSample\", \"c\", Create_SimpleSample,\n        0);\n        // The AddFunction has the following paramters:\n        // AddFunction(Filtername , Arguments, Function to call,0);\n\n        // Arguments is a string that defines the types and optional names of the arguments for you filter.\n        // c - Video Clip\n        // i - Integer number\n        // f - Float number\n        // s - String\n        // b - boolean\n\n        return \"`SimpleSample' SimpleSample plugin\";\n        // A freeform name of the plugin.\n    }\n\nBack to :doc:`SimpleSample <SimpleSample>`\n\n$Date: 2025-02-24 21:14:09-05:00 $\n\n.. _SimpleSample 1.1: http://avisynth.nl/index.php/Filter_SDK/Simple_sample_1.1\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/SimpleSample12.rst",
    "content": "\n`SimpleSample 1.2`_\n===================\n\n`SimpleSample 1.2: <http://www.geocities.com/siwalters_uk/simplesample12.zip>`_\n\n::\n\n    /*\n        SimpleSample plugin for Avisynth -- a simple sample\n\n        Copyright (C) 2002-2003 Simon Walters, All Rights Reserved\n\n        This program is free software; you can redistribute it and/or\n    modify\n        it under the terms of the GNU General Public License as published\n    by\n        the Free Software Foundation.\n\n        This program is distributed in the hope that it will be useful,\n        but WITHOUT ANY WARRANTY; without even the implied warranty of\n        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n        GNU General Public License for more details.\n\n        You should have received a copy of the GNU General Public License\n        along with this program; if not, write to the Free Software\n        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n        The author can be contacted at:\n        Simon Walters\n        siwalters@hotmail.com\n\n        V1.0 - 1st release.\n        V1.0a - Revised version to put colourspace checking in the right\n    place.\n      V1.0b - Added detailed comments.  // sh0dan\n        V1.1 - Added sh0dan's planar (YV12) code\n        V1.2 - Revert to RGB24 colourspace only to show simple pixel\n    manipulation;\n\n    */\n    //following 2 includes needed\n    #include \"windows.h\"\n    #include \"avisynth.h\"\n\n    /****************************\n     * The following is the header definitions.\n     * For larger projects, move this into a .h file\n     * that can be included.\n     ****************************/\n\n\n    class SimpleSample : public GenericVideoFilter {\n      // SimpleSample defines the name of your filter class.\n      // This name is only used internally, and does not affect the name of your filter or similar.\n      // This filter extends GenericVideoFilter, which incorporates basic functionality.\n      // All functions present in the filter must also be present here.\n\n    public:\n      // This defines that these functions are present in your class.\n      // These functions must be that same as those actually implemented.\n      // Since the functions are \"public\" they are accessible to other classes.\n      // Otherwise they can only be called from functions within the class itself.\n\n        SimpleSample(PClip _child, IScriptEnvironment* env);\n      // This is the constructor. It does not return eny value, and is always used,\n      //  when an instance of the class is created.\n      // Since there is no code in this, this is the definition.\n\n        PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n      // This is the function that AviSynth calls to get a given frame.\n      // So when this functions gets called, the filter is supposed to return frame n.\n    };\n\n    /***************************\n     * The following is the implementation\n     * of the defined functions.\n     ***************************/\n\n    SimpleSample::SimpleSample(PClip _child, IScriptEnvironment* env) :\n    GenericVideoFilter(_child) {\n      // This is the implementation of the constructor.\n      // The child clip (source clip) is inherited by the GenericVideoFilter,\n      //  where the following variables gets defined:\n      //   PClip child;   // Contains the source clip.\n      //   VideoInfo vi;  // Contains videoinfo on the source clip.\n        if (!vi.IsRGB24()) // is input not RGB24\n                env->ThrowError(\"SimpleSample: input to filter must be in RGB24 colourspace\");\n    }\n\n\n\n    PVideoFrame __stdcall SimpleSample::GetFrame(int n,\n    IScriptEnvironment* env) {\n    // This is the implementation of the GetFrame function.\n    // See the header definition for further info.\n\n        PVideoFrame src = child->GetFrame(n, env);\n       // Request frame 'n' from the child (source) clip.\n        PVideoFrame dst = env->NewVideoFrame(vi);\n       // Construct a frame based on the information of the current frame\n       // contained in the \"vi\" struct.\n\n        const unsigned char* srcp = src->GetReadPtr();\n      // Request a Read pointer from the source frame.\n      // This will return the position of the upperleft pixel in YUY2 images,\n      // and return the lower-left pixel in RGB.\n      // RGB images are stored upside-down in memory.\n      // You should still process images from line 0 to height.\n\n        unsigned char* dstp = dst->GetWritePtr();\n        // Request a Write pointer from the newly created destination image.\n      // You can request a writepointer to images that have just been\n      // created by NewVideoFrame. If you recieve a frame from\n      PClip->GetFrame(...)\n      // you must call env->MakeWritable(&frame) be recieve a valid write pointer.\n\n        const int dst_pitch = dst->GetPitch();\n      // Requests pitch (length of a line) of the destination image.\n      // For more information on pitch see:\n      // http://avisynth.nl/index.php/Filter_SDK/Working_with_images\n        // (short version - pitch is always equal to or greater than width to allow for seriously fast assembly code)\n\n        const int dst_width = dst->GetRowSize();\n      // Requests rowsize (number of used bytes in a line.\n      // See the link above for more information.\n\n        const int dst_height = dst->GetHeight();\n      // Requests the height of the destination image.\n\n        const int src_pitch = src->GetPitch();\n        const int src_width = src->GetRowSize();\n        const int src_height = src->GetHeight();\n\n        int w, h;\n\n        // This version of SimpleSample is intended to show some simple pixel manipulation.\n        // It is designed purely for clarity and not as good or clever code :-)\n\n\n\n        // The code just deals with RGB24 colourspace where each pixel is represented by\n        // 3 bytes, Blue, Green and Red.\n        // Although this colourspace is the easiest to understand, it is very rarely used because\n        // a 3 byte sequence (24bits) cannot be processed easily using normal 32 bit registers.\n\n        for (h=0; h < src_height;h++) {                     // Loop from bottom line to top line.\n                for (w = 0; w < src_width; w+=3) {          // Loop from left side of the image to the right side 1 pixel (3 bytes) at a time\n                                                            // stepping 3 bytes (a pixel width in RGB24 space)\n\n                        *(dstp + w) = *(srcp + w);          // Copy each Blue byte from source to destination.\n                        *(dstp + w + 1) = *(srcp + w + 1);  // Copy Green.\n                        *(dstp + w + 2) = *(srcp + w + 2);  // Copy Red\n                }\n\n                srcp = srcp + src_pitch; // Add the pitch (note use of pitch and not width) of one line (in bytes) to the source pointer\n                dstp = dstp + dst_pitch; // Add the pitch to the destination pointer.\n        }\n        // end copy src to dst\n\n        //Now draw a white square in the middle of the frame\n        // Normally you'd do this code within the loop above but here it is in a separate loop for clarity;\n\n        dstp = dst->GetWritePtr();                                             // reset the destination pointer to the bottom, left pixel. (RGB colourspaces only)\n        dstp = dstp + (dst_height/2 -50)*dst_pitch;                            // move pointer to 50 lines from the middle of the frame;\n        for (h=0; h < 100;h++) {                                               // only scan 100 lines\n                for (w = (dst_width/2 -50)*3; w < (dst_width/2 +50)*3; w+=3) { // only scan the middle 100 pixels of a line\n                        *(dstp + w) = 255;                                     // Set Blue to maximum value.\n                        *(dstp + w + 1) = 255;                                 // and Green.\n                        *(dstp + w + 2) = 255;                                 // and Red - therefore the whole pixel is now white.\n                }\n                dstp = dstp + dst_pitch;\n        }\n\n\n      // As we now are finished processing the image, we return the destination image.\n        return dst;\n    }\n\n\n    // This is the function that created the filter, when the filter has been called.\n    // This can be used for simple parameter checking, so it is possible to create different filters,\n    // based on the arguments recieved.\n\n    AVSValue __cdecl Create_SimpleSample(AVSValue args, void* user_data,\n    IScriptEnvironment* env) {\n        return new SimpleSample(args[0].AsClip(),env);\n        // Calls the constructor with the arguments provied.\n    }\n\n\n    // The following function is the function that actually registers the filter in AviSynth\n    // It is called automatically, when the plugin is loaded to see which functions this filter contains.\n\n    extern \"C\" __declspec(dllexport) const char* __stdcall\n    AvisynthPluginInit2(IScriptEnvironment* env) {\n        env->AddFunction(\"SimpleSample\", \"c\", Create_SimpleSample, 0);\n        // The AddFunction has the following paramters:\n        // AddFunction(Filtername , Arguments, Function to call,0);\n\n        // Arguments is a string that defines the types and optional names of the arguments for you filter.\n        // c - Video Clip\n        // i - Integer number\n        // f - Float number\n        // s - String\n        // b - boolean\n\n        return \"`SimpleSample' SimpleSample plugin\";\n        // A freeform name of the plugin.\n    }\n\nBack to :doc:`SimpleSample <SimpleSample>`\n\n$Date: 2025-02-24 21:12:30-05:00 $\n\n.. _SimpleSample 1.2: http://avisynth.nl/index.php/Filter_SDK/Simple_sample_1.2\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/SimpleSample13a.rst",
    "content": "\n`SimpleSample 1.3a`_\n====================\n\n`SimpleSample 1.3a: <http://www.geocities.com/siwalters_uk/simplesample13a.zip>`_\n\n::\n\n    /*\n        SimpleSample plugin for Avisynth -- a simple sample\n\n        Copyright (C) 2002-2003 Simon Walters, All Rights Reserved\n\n        This program is free software; you can redistribute it and/or\n    modify\n        it under the terms of the GNU General Public License as published\n    by\n        the Free Software Foundation.\n\n        This program is distributed in the hope that it will be useful,\n        but WITHOUT ANY WARRANTY; without even the implied warranty of\n        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n        GNU General Public License for more details.\n\n        You should have received a copy of the GNU General Public License\n        along with this program; if not, write to the Free Software\n        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n        The author can be contacted at:\n        Simon Walters\n        siwalters@hotmail.com\n\n        V1.0 - 1st release.\n        V1.0a - Revised version to put colourspace checking in the right\n    place.\n      V1.0b - Added detailed comments.  // sh0dan\n        V1.1 - Added sh0dan's planar (YV12) code\n        V1.2 - Revert to RGB24 colourspace only to show simple pixel\n    manipulation;\n        V1.3 - add in a parameter to vary the size of the square.\n        V1.3a - bug fix in innner loop processing\n\n    */\n    //following 2 includes needed\n    #include \"windows.h\"\n    #include \"avisynth.h\"\n\n    /****************************\n     * The following is the header definitions.\n     * For larger projects, move this into a .h file\n     * that can be included.\n     ****************************/\n\n\n    class SimpleSample : public GenericVideoFilter {\n      // SimpleSample defines the name of your filter class.\n      // This name is only used internally, and does not affect the name of your filter or similar.\n      // This filter extends GenericVideoFilter, which incorporates basic functionality.\n      // All functions present in the filter must also be present here.\n        int SquareSize;\n\n    public:\n      // This defines that these functions are present in your class.\n      // These functions must be that same as those actually implemented.\n      // Since the functions are \"public\" they are accessible to other classes.\n      // Otherwise they can only be called from functions within the class itself.\n\n        SimpleSample(PClip _child, int _SquareSize, IScriptEnvironment* env);\n      // This is the constructor. It does not return any value, and is always used,\n      //  when an instance of the class is created.\n      // Since there is no code in this, this is the definition.\n\n      ~SimpleSample();\n      // The is the destructor definition. This is called when the filter is destroyed.\n\n\n        PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n      // This is the function that AviSynth calls to get a given frame.\n      // So when this functions gets called, the filter is supposed to return frame n.\n    };\n\n    /***************************\n     * The following is the implementation\n     * of the defined functions.\n     ***************************/\n\n    //Here is the acutal constructor code used\n    SimpleSample::SimpleSample(PClip _child, int _SquareSize,\n    IScriptEnvironment* env) :\n        GenericVideoFilter(_child), SquareSize(_SquareSize) {\n      // This is the implementation of the constructor.\n      // The child clip (source clip) is inherited by the GenericVideoFilter,\n      //  where the following variables gets defined:\n      //   PClip child;   // Contains the source clip.\n      //   VideoInfo vi;  // Contains videoinfo on the source clip.\n        if (!vi.IsRGB24()) // is input not RGB24\n                env->ThrowError(\"SimpleSample: input to filter must be in RGB24 colourspace\");\n    }\n\n    // This is where any actual destructor code used goes\n    SimpleSample::~SimpleSample() {\n      // This is where you can deallocate any memory you might have used.\n    }\n\n\n\n\n    PVideoFrame __stdcall SimpleSample::GetFrame(int n,\n    IScriptEnvironment* env) {\n    // This is the implementation of the GetFrame function.\n    // See the header definition for further info.\n\n        PVideoFrame src = child->GetFrame(n, env);\n       // Request frame 'n' from the child (source) clip.\n        PVideoFrame dst = env->NewVideoFrame(vi);\n       // Construct a frame based on the information of the current frame\n       // contained in the \"vi\" struct.\n\n        const unsigned char* srcp = src->GetReadPtr();\n      // Request a Read pointer from the source frame.\n      // This will return the position of the upperleft pixel in YUY2 images,\n      // and return the lower-left pixel in RGB.\n      // RGB images are stored upside-down in memory.\n      // You should still process images from line 0 to height.\n\n        unsigned char* dstp = dst->GetWritePtr();\n        // Request a Write pointer from the newly created destination image.\n      // You can request a writepointer to images that have just been\n      // created by NewVideoFrame. If you recieve a frame from\n      PClip->GetFrame(...)\n      // you must call env->MakeWritable(&frame) be recieve a valid write pointer.\n\n        const int dst_pitch = dst->GetPitch();\n      // Requests pitch (length of a line) of the destination image.\n      // For more information on pitch see:\n      // http://avisynth.nl/index.php/Filter_SDK/Working_with_images\n        // (short version - pitch is always equal to or greater than width to allow for seriously fast assembly code)\n\n        const int dst_width = dst->GetRowSize();\n      // Requests rowsize (number of used bytes in a line.\n      // See the link above for more information.\n\n        const int dst_height = dst->GetHeight();\n      // Requests the height of the destination image.\n\n        const int src_pitch = src->GetPitch();\n        const int src_width = src->GetRowSize();\n        const int src_height = src->GetHeight();\n\n        int w, h;\n\n        // This version of SimpleSample is intended to show some simple pixel manipulation.\n        // It is designed purely for clarity and not as good or clever code :-)\n\n\n\n        // The code just deals with RGB24 colourspace where each pixel is represented by\n        // 3 bytes, Blue, Green and Red.\n        // Although this colourspace is the easiest to understand, it is very rarely used because\n        // a 3 byte sequence (24bits) cannot be processed easily using normal 32 bit registers.\n\n        for (h=0; h < src_height;h++) {                       // Loop from bottom line to top line.\n                for (w = 0; w < src_width; w+=3) {            // Loop from left side of the image to the right side 1 pixel (3 bytes) at a time\n                                                              // stepping 3 bytes (a pixel width in RGB24 space)\n\n                        *(dstp + w) = *(srcp + w);            // Copy each Blue byte from source to destination.\n                        *(dstp + w + 1) = *(srcp + w + 1);    // Copy Green.\n                        *(dstp + w + 2) = *(srcp + w + 2);    // Copy Red\n                }\n\n                srcp = srcp + src_pitch; // Add the pitch (note use of pitch and not width) of one line (in bytes) to the source pointer\n                dstp = dstp + dst_pitch; // Add the pitch to the destination pointer.\n        }\n        // end copy src to dst\n\n        //Now draw a white square in the middle of the frame\n        // Normally you'd do this code within the loop above but here it is in a separate loop for clarity;\n\n        dstp = dst->GetWritePtr();                                                               // reset the destination pointer to the bottom, left pixel. (RGB colourspaces only)\n        dstp = dstp + (dst_height/2 - SquareSize/2)*dst_pitch;                                   // move pointer to SquareSize/2 lines from the middle of the frame;\n        for (h=0; h < SquareSize;h++) {                                                          // only scan SquareSize number of lines\n                for (w = dst_width/2 - SquareSize*3/2; w < dst_width/2 + SquareSize*3/2; w+=3) { // only scans the middle SquareSize number of pixels of a line\n                        *(dstp + w) = 255;                                                       // Set Blue to maximum value.\n                        *(dstp + w + 1) = 255;                                                   // and Green.\n                        *(dstp + w + 2) = 255;                                                   // and Red - therefore the whole pixel is now white.\n                }\n                dstp = dstp + dst_pitch;\n        }\n\n\n      // As we now are finished processing the image, we return the destination image.\n        return dst;\n    }\n\n\n    // This is the function that created the filter, when the filter has been called.\n    // This can be used for simple parameter checking, so it is possible to create different filters,\n    // based on the arguments recieved.\n\n    AVSValue __cdecl Create_SimpleSample(AVSValue args, void* user_data,\n    IScriptEnvironment* env) {\n        return new SimpleSample(args[0].AsClip(),\n                 args[1].AsInt(0),      // Corresponds to our 1st parameter - the size of the square in pixels.\n                 env);                  // Calls the constructor with the arguments provied.\n    }\n\n\n    // The following function is the function that actually registers the filter in AviSynth\n    // It is called automatically, when the plugin is loaded to see which functions this filter contains.\n\n    extern \"C\" __declspec(dllexport) const char* __stdcall\n    AvisynthPluginInit2(IScriptEnvironment* env) {\n        env->AddFunction(\"SimpleSample\", \"c[SIZE]i\",\n        Create_SimpleSample, 0);\n        // The AddFunction has the following paramters:\n        // AddFunction(Filtername , Arguments, Function to call,0);\n\n        // Arguments is a string that defines the types and optional names of the arguments for you filter.\n        // c - Video Clip\n        // i - Integer number\n        // f - Float number\n        // s - String\n        // b - boolean\n\n         // The word inside the [ ] lets you used named parameters in your script\n         // e.g last=SimpleSample(last,size=100).\n         // but last=SimpleSample(last,100) will also work automagically\n\n        return \"`SimpleSample' SimpleSample plugin\";\n        // A freeform name of the plugin.\n    }\n\nBack to :doc:`SimpleSample <SimpleSample>`\n\n$Date: 2025-02-24 21:27:50-05:00 $\n\n.. _SimpleSample 1.3a: http://avisynth.nl/index.php/Filter_SDK/Simple_sample_1.3a\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/SimpleSample14.rst",
    "content": "\n`SimpleSample 1.4`_\n===================\n\n`SimpleSample 1.4: <http://www.geocities.com/siwalters_uk/simplesample14.zip>`_\n\n::\n\n    /*\n        SimpleSample plugin for Avisynth -- a simple sample\n\n        Copyright (C) 2002-2003 Simon Walters, All Rights Reserved\n\n        This program is free software; you can redistribute it and/or\n    modify\n        it under the terms of the GNU General Public License as published\n    by\n        the Free Software Foundation.\n\n        This program is distributed in the hope that it will be useful,\n        but WITHOUT ANY WARRANTY; without even the implied warranty of\n        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n        GNU General Public License for more details.\n\n        You should have received a copy of the GNU General Public License\n        along with this program; if not, write to the Free Software\n        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n        The author can be contacted at:\n        Simon Walters\n        siwalters@hotmail.com\n\n        V1.0 - 1st release.\n        V1.0a - Revised version to put colourspace checking in the right\n    place.\n      V1.0b - Added detailed comments.  // sh0dan\n        V1.1 - Added sh0dan's planar (YV12) code\n        V1.2 - Revert to RGB24 colourspace only to show simple pixel\n    manipulation;\n        V1.3 - add in a parameter to vary the size of the square.\n        V1.4 - Add in RGB32 colourspace code\n\n    */\n    //following 2 includes needed\n    #include \"windows.h\"\n    #include \"avisynth.h\"\n\n    /****************************\n     * The following is the header definitions.\n     * For larger projects, move this into a .h file\n     * that can be included.\n     ****************************/\n\n\n    class SimpleSample : public GenericVideoFilter {\n      // SimpleSample defines the name of your filter class.\n      // This name is only used internally, and does not affect the name of your filter or similar.\n      // This filter extends GenericVideoFilter, which incorporates basic functionality.\n      // All functions present in the filter must also be present here.\n        int SquareSize;\n\n    public:\n      // This defines that these functions are present in your class.\n      // These functions must be that same as those actually implemented.\n      // Since the functions are \"public\" they are accessible to other classes.\n      // Otherwise they can only be called from functions within the class itself.\n\n        SimpleSample(PClip _child, int _SquareSize, IScriptEnvironment* env);\n      // This is the constructor. It does not return any value, and is always used,\n      //  when an instance of the class is created.\n      // Since there is no code in this, this is the definition.\n\n      ~SimpleSample();\n      // The is the destructor definition. This is called when the filter is destroyed.\n\n\n        PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n      // This is the function that AviSynth calls to get a given frame.\n      // So when this functions gets called, the filter is supposed to return frame n.\n    };\n\n    /***************************\n     * The following is the implementation\n     * of the defined functions.\n     ***************************/\n\n    //Here is the acutal constructor code used\n    SimpleSample::SimpleSample(PClip _child, int _SquareSize,\n    IScriptEnvironment* env) :\n        GenericVideoFilter(_child), SquareSize(_SquareSize) {\n      // This is the implementation of the constructor.\n      // The child clip (source clip) is inherited by the GenericVideoFilter,\n      //  where the following variables gets defined:\n      //   PClip child;   // Contains the source clip.\n      //   VideoInfo vi;  // Contains videoinfo on the source clip.\n        if (!vi.IsRGB()) // is input not RGB (24 or 32)\n                env->ThrowError(\"SimpleSample: input to filter must be in an RGB colourspace\");\n    }\n\n    // This is where any actual destructor code used goes\n    SimpleSample::~SimpleSample() {\n      // This is where you can deallocate any memory you might have used.\n    }\n\n\n\n\n    PVideoFrame __stdcall SimpleSample::GetFrame(int n,\n    IScriptEnvironment* env) {\n    // This is the implementation of the GetFrame function.\n    // See the header definition for further info.\n\n        PVideoFrame src = child->GetFrame(n, env);\n       // Request frame 'n' from the child (source) clip.\n        PVideoFrame dst = env->NewVideoFrame(vi);\n       // Construct a frame based on the information of the current frame\n       // contained in the \"vi\" struct.\n\n        const unsigned char* srcp = src->GetReadPtr();\n      // Request a Read pointer from the source frame.\n      // This will return the position of the upperleft pixel in YUY2 images,\n      // and return the lower-left pixel in RGB.\n      // RGB images are stored upside-down in memory.\n      // You should still process images from line 0 to height.\n\n        unsigned char* dstp = dst->GetWritePtr();\n        // Request a Write pointer from the newly created destination image.\n      // You can request a writepointer to images that have just been\n      // created by NewVideoFrame. If you recieve a frame from\n      PClip->GetFrame(...)\n      // you must call env->MakeWritable(&frame) be recieve a valid write pointer.\n\n        const int dst_pitch = dst->GetPitch();\n      // Requests pitch (length of a line) of the destination image.\n      // For more information on pitch see:\n      // http://avisynth.nl/index.php/Filter_SDK/Working_with_images\n        // (short version - pitch is always equal to or greater than width to allow for seriously fast assembly code)\n\n        const int dst_width = dst->GetRowSize();\n      // Requests rowsize (number of used bytes in a line.\n      // See the link above for more information.\n\n        const int dst_height = dst->GetHeight();\n      // Requests the height of the destination image.\n\n        const int src_pitch = src->GetPitch();\n        const int src_width = src->GetRowSize();\n        const int src_height = src->GetHeight();\n\n        int w, h;\n\n        // This version of SimpleSample is intended to show some simple pixel manipulation.\n        // It is designed purely for clarity and not as good or clever code :-)\n\n\n\n        if (vi.IsRGB24()) {\n                // The code just deals with RGB24 colourspace where each pixel is represented by\n                // 3 bytes, Blue, Green and Red.\n                // Although this colourspace is the easiest to understand, it is very rarely used because\n                // a 3 byte sequence (24bits) cannot be processed easily using normal 32 bit registers.\n\n                for (h=0; h < src_height;h++) {                       // Loop from bottom line to top line.\n                        for (w = 0; w < src_width; w+=3) {            // Loop from left side of the image to the right side 1 pixel (3 bytes) at a time\n                                                                      // stepping 3 bytes (a pixel width in RGB24 space)\n\n                                *(dstp + w) = *(srcp + w);            // Copy each Blue byte from source to destination.\n                                *(dstp + w + 1) = *(srcp + w + 1);    // Copy Green.\n                                *(dstp + w + 2) = *(srcp + w + 2);    // Copy Red\n                        }\n\n                        srcp = srcp + src_pitch; // Add the pitch (note use of pitch and not width) of one line (in bytes) to the source pointer\n                        dstp = dstp + dst_pitch; // Add the pitch to the destination pointer.\n                }\n                // end copy src to dst\n\n                //Now draw a white square in the middle of the frame\n                // Normally you'd do this code within the loop above but here it is in a separate loop for clarity;\n\n                dstp = dst->GetWritePtr();                                                               // reset the destination pointer to the bottom, left pixel. (RGB colourspaces only)\n                dstp = dstp + (dst_height/2 - SquareSize/2)*dst_pitch;                                   // move pointer to SquareSize/2 lines from the middle of the frame;\n                for (h=0; h < SquareSize;h++) {                                                          // only scan 100 lines\n                        for (w = dst_width/2 - SquareSize*3/2; w < dst_width/2 + SquareSize*3/2; w+=3) { // only scans the middle SquareSize pixels of a line\n                                *(dstp + w) = 255;                                                       // Set Blue to maximum value.\n                                *(dstp + w + 1) = 255;                                                   // and Green.\n                                *(dstp + w + 2) = 255;                                                   // and Red - therefore the whole pixel is now white.\n                        }\n                        dstp = dstp + dst_pitch;\n                }\n        }\n\n        if (vi.IsRGB32()) {\n                // This code deals with RGB32 colourspace where each pixel is represented by\n                // 4 bytes, Blue, Green and Red and \"spare\" byte that could/should be used for alpha\n                // keying but usually isn't.\n\n                // Although this colourspace isn't memory efficient, code end ups running much\n                // quicker than RGB24 as you can deal with whole 32bit variables at a time\n                // and easily work directly and quickly in assembler (if you know how to that is :-)\n\n                for (h=0; h < src_height;h++) {                                                 // Loop from bottom line to top line.\n                        for (w = 0; w < src_width/4; w+=1) {                                    // and from leftmost pixel to rightmost one.\n                                *((unsigned int *)dstp + w) = *((unsigned int *)srcp + w);      // Copy each whole pixel from source to destination.\n                        }                                                                       // by temporarily treating the src and dst pointers as\n                                                                                                // pixel pointers intead of byte pointers\n                        srcp = srcp + src_pitch; // Add the pitch (note use of pitch and not width) of one line (in bytes) to the source pointer\n                        dstp = dstp + dst_pitch; // Add the pitch to the destination pointer.\n                }\n                // end copy src to dst\n\n                //Now draw a white square in the middle of the frame\n                // Normally you'd do this code within the loop above but here it is in a separate loop for clarity;\n\n                dstp = dst->GetWritePtr();                                // reset the destination pointer to the bottom, left pixel. (RGB colourspaces only)\n                dstp = dstp + (dst_height/2 - SquareSize/2)*dst_pitch;    // move pointer to SquareSize/2 lines from the middle of the frame;\n\n                int woffset = dst_width/8 - SquareSize/2;  // lets precalulate the width offset like we do for the lines.\n\n                for (h=0; h < SquareSize;h++) {                                     // only scan SquareSize number of lines\n                        for (w = 0; w < SquareSize; w+=1) {                         // only scans the middle SquareSize pixels of a line\n                                *((unsigned int *)dstp + woffset + w) = 0x00FFFFFF; // Set Red,Green and Blue to maximum value in 1 instruction.\n                        }\n                        dstp = dstp + dst_pitch;\n                }\n      }\n\n      // As we now are finished processing the image, we return the destination image.\n        return dst;\n    }\n\n\n    // This is the function that created the filter, when the filter has been called.\n    // This can be used for simple parameter checking, so it is possible to create different filters,\n    // based on the arguments recieved.\n\n    AVSValue __cdecl Create_SimpleSample(AVSValue args, void* user_data,\n    IScriptEnvironment* env) {\n        return new SimpleSample(args[0].AsClip(),\n                 args[1].AsInt(0),      // Corresponds to our 1st parameter - the size of the square in pixels.\n                 env);                  // Calls the constructor with the arguments provied.\n    }\n\n\n    // The following function is the function that actually registers the filter in AviSynth\n    // It is called automatically, when the plugin is loaded to see which functions this filter contains.\n\n    extern \"C\" __declspec(dllexport) const char* __stdcall\n    AvisynthPluginInit2(IScriptEnvironment* env) {\n        env->AddFunction(\"SimpleSample\", \"c[SIZE]i\",\n        Create_SimpleSample, 0);\n        // The AddFunction has the following paramters:\n        // AddFunction(Filtername , Arguments, Function to call,0);\n\n        // Arguments is a string that defines the types and optional names of the arguments for you filter.\n        // c - Video Clip\n        // i - Integer number\n        // f - Float number\n        // s - String\n        // b - boolean\n\n         // The word inside the [ ] lets you used named parameters in your script\n         // e.g last=SimpleSample(last,size=100).\n         // but last=SimpleSample(last,100) will also work automagically\n\n        return \"`SimpleSample' SimpleSample plugin\";\n        // A freeform name of the plugin.\n    }\n\nBack to :doc:`SimpleSample <SimpleSample>`\n\n$Date: 2025-02-24 21:06:05-05:00 $\n\n.. _SimpleSample 1.4: http://avisynth.nl/index.php/Filter_SDK/Simple_sample_1.4\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/SimpleSample15a.rst",
    "content": "\n`SimpleSample 1.5a`_\n====================\n\n`SimpleSample 1.5a: <http://www.geocities.com/siwalters_uk/simplesample15a.zip>`_\n\n::\n\n    /*\n        SimpleSample plugin for Avisynth -- a simple sample\n\n        Copyright (C) 2002-2003 Simon Walters, All Rights Reserved\n\n        This program is free software; you can redistribute it and/or\n    modify\n        it under the terms of the GNU General Public License as published\n    by\n        the Free Software Foundation.\n\n        This program is distributed in the hope that it will be useful,\n        but WITHOUT ANY WARRANTY; without even the implied warranty of\n        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n        GNU General Public License for more details.\n\n        You should have received a copy of the GNU General Public License\n        along with this program; if not, write to the Free Software\n        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n        The author can be contacted at:\n        Simon Walters\n        siwalters@hotmail.com\n\n        V1.0 - 1st release.\n        V1.0a - Revised version to put colourspace checking in the right\n    place.\n      V1.0b - Added detailed comments.  // sh0dan\n        V1.1 - Added sh0dan's planar (YV12) code\n        V1.2 - Revert to RGB24 colourspace only to show simple pixel\n    manipulation;\n        V1.3 - add in a parameter to vary the size of the square.\n        V1.4 - Add in RGB32 colourspace code\n        V1.5 - Add in YUY2 colourspace code\n        V1.5a - bug fix in max Y1 and Y2 values\n\n    */\n    //following 2 includes needed\n    #include \"windows.h\"\n    #include \"avisynth.h\"\n\n    /****************************\n     * The following is the header definitions.\n     * For larger projects, move this into a .h file\n     * that can be included.\n     ****************************/\n\n\n    class SimpleSample : public GenericVideoFilter {\n      // SimpleSample defines the name of your filter class.\n      // This name is only used internally, and does not affect the name of your filter or similar.\n      // This filter extends GenericVideoFilter, which incorporates basic functionality.\n      // All functions present in the filter must also be present here.\n        int SquareSize;\n\n    public:\n      // This defines that these functions are present in your class.\n      // These functions must be that same as those actually implemented.\n      // Since the functions are \"public\" they are accessible to other classes.\n      // Otherwise they can only be called from functions within the class itself.\n\n        SimpleSample(PClip _child, int _SquareSize, IScriptEnvironment* env);\n      // This is the constructor. It does not return any value, and is always used,\n      //  when an instance of the class is created.\n      // Since there is no code in this, this is the definition.\n\n      ~SimpleSample();\n      // The is the destructor definition. This is called when the filter is destroyed.\n\n\n        PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n      // This is the function that AviSynth calls to get a given frame.\n      // So when this functions gets called, the filter is supposed to return frame n.\n    };\n\n    /***************************\n     * The following is the implementation\n     * of the defined functions.\n     ***************************/\n\n    //Here is the acutal constructor code used\n    SimpleSample::SimpleSample(PClip _child, int _SquareSize,\n    IScriptEnvironment* env) :\n        GenericVideoFilter(_child), SquareSize(_SquareSize) {\n      // This is the implementation of the constructor.\n      // The child clip (source clip) is inherited by the GenericVideoFilter,\n      //  where the following variables gets defined:\n      //   PClip child;   // Contains the source clip.\n      //   VideoInfo vi;  // Contains videoinfo on the source clip.\n    }\n\n    // This is where any actual destructor code used goes\n    SimpleSample::~SimpleSample() {\n      // This is where you can deallocate any memory you might have used.\n    }\n\n\n\n\n    PVideoFrame __stdcall SimpleSample::GetFrame(int n,\n    IScriptEnvironment* env) {\n    // This is the implementation of the GetFrame function.\n    // See the header definition for further info.\n\n        PVideoFrame src = child->GetFrame(n, env);\n       // Request frame 'n' from the child (source) clip.\n        PVideoFrame dst = env->NewVideoFrame(vi);\n       // Construct a frame based on the information of the current frame\n       // contained in the \"vi\" struct.\n\n        const unsigned char* srcp = src->GetReadPtr();\n      // Request a Read pointer from the source frame.\n      // This will return the position of the upperleft pixel in YUY2 images,\n      // and return the lower-left pixel in RGB.\n      // RGB images are stored upside-down in memory.\n      // You should still process images from line 0 to height.\n\n        unsigned char* dstp = dst->GetWritePtr();\n        // Request a Write pointer from the newly created destination image.\n      // You can request a writepointer to images that have just been\n      // created by NewVideoFrame. If you recieve a frame from PClip->GetFrame(...)\n      // you must call env->MakeWritable(&frame) be recieve a valid write pointer.\n\n        const int dst_pitch = dst->GetPitch();\n      // Requests pitch (length of a line) of the destination image.\n      // For more information on pitch see:\n      // http://avisynth.nl/index.php/Filter_SDK/Working_with_images\n        // (short version - pitch is always equal to or greater than width to allow for seriously fast assembly code)\n\n        const int dst_width = dst->GetRowSize();\n      // Requests rowsize (number of used bytes in a line.\n      // See the link above for more information.\n\n        const int dst_height = dst->GetHeight();\n      // Requests the height of the destination image.\n\n        const int src_pitch = src->GetPitch();\n        const int src_width = src->GetRowSize();\n        const int src_height = src->GetHeight();\n\n        int w, h;\n\n        // This version of SimpleSample is intended to show some simple pixel manipulation.\n        // It is designed purely for clarity and not as good or clever code :-)\n\n\n        if (vi.IsRGB24()) {\n                // The code just deals with RGB24 colourspace where each pixel is represented by\n                // 3 bytes, Blue, Green and Red.\n                // Although this colourspace is the easiest to understand, it is very rarely used because\n                // a 3 byte sequence (24bits) cannot be processed easily using normal 32 bit registers.\n\n                for (h=0; h < src_height;h++) {                       // Loop from bottom line to top line.\n                        for (w = 0; w < src_width; w+=3) {            // Loop from left side of the image to the right side 1 pixel (3 bytes) at a time\n                                                                      // stepping 3 bytes (a pixel width in RGB24 space)\n\n                                *(dstp + w) = *(srcp + w);            // Copy each Blue byte from source to destination.\n                                *(dstp + w + 1) = *(srcp + w + 1);    // Copy Green.\n                                *(dstp + w + 2) = *(srcp + w + 2);    // Copy Red\n                        }\n\n                        srcp = srcp + src_pitch; // Add the pitch (note use of pitch and not width) of one line (in bytes) to the source pointer\n                        dstp = dstp + dst_pitch; // Add the pitch to the destination pointer.\n                }\n                // end copy src to dst\n\n                //Now draw a white square in the middle of the frame\n                // Normally you'd do this code within the loop above but here it is in a separate loop for clarity;\n\n                dstp = dst->GetWritePtr();                                                               // reset the destination pointer to the bottom, left pixel. (RGB colourspaces only)\n                dstp = dstp + (dst_height/2 - SquareSize/2)*dst_pitch;                                   // move pointer to SquareSize/2 lines from the middle of the frame;\n                for (h=0; h < SquareSize;h++) {                                                          // only scan 100 lines\n                        for (w = dst_width/2 - SquareSize*3/2; w < dst_width/2 + SquareSize*3/2; w+=3) { // only scans the middle SquareSize pixels of a line\n                                *(dstp + w) = 255;                                                       // Set Blue to maximum value.\n                                *(dstp + w + 1) = 255;                                                   // and Green.\n                                *(dstp + w + 2) = 255;                                                   // and Red - therefore the whole pixel is now white.\n                        }\n                        dstp = dstp + dst_pitch;\n                }\n        }\n\n        if (vi.IsRGB32()) {\n                // This code deals with RGB32 colourspace where each pixel is represented by\n                // 4 bytes, Blue, Green and Red and \"spare\" byte that could/should be used for alpha\n                // keying but usually isn't.\n\n                // Although this colourspace isn't memory efficient, code end ups running much\n                // quicker than RGB24 as you can deal with whole 32bit variables at a time\n                // and easily work directly and quickly in assembler (if you know how to that is :-)\n\n                for (h=0; h < src_height;h++) {                                            // Loop from bottom line to top line.\n                        for (w = 0; w < src_width/4; w+=1) {                               // and from leftmost pixel to rightmost one.\n                                *((unsigned int *)dstp + w) = *((unsigned int *)srcp + w); // Copy each whole pixel from source to destination.\n                        }                                                                  // by temporarily treating the src and dst pointers as\n                                                                                           // pixel pointers intead of byte pointers\n                        srcp = srcp + src_pitch;                                           // Add the pitch (note use of pitch and not width) of one line (in bytes) to the source pointer\n                        dstp = dstp + dst_pitch;                                           // Add the pitch to the destination pointer.\n                }\n                // end copy src to dst\n\n                //Now draw a white square in the middle of the frame\n                // Normally you'd do this code within the loop above but here it is in a separate loop for clarity;\n\n                dstp = dst->GetWritePtr();                                          // reset the destination pointer to the bottom, left pixel. (RGB colourspaces only)\n                dstp = dstp + (dst_height/2 - SquareSize/2)*dst_pitch;              // move pointer to SquareSize/2 lines from the middle of the frame;\n\n                int woffset = dst_width/8 - SquareSize/2;                           // lets precalulate the width offset like we do for the lines.\n\n                for (h=0; h < SquareSize;h++) {                                     // only scan SquareSize number of lines\n                        for (w = 0; w < SquareSize; w+=1) {                         // only scans the middle SquareSize pixels of a line\n                                *((unsigned int *)dstp + woffset + w) = 0x00FFFFFF; // Set Red,Green and Blue to maximum value in 1 instruction.\n                                                                                    // LSB = Blue, MSB = \"spare\" byte\n                        }\n                        dstp = dstp + dst_pitch;\n                }\n      }\n\n        if (vi.IsYUY2()) {\n                // This code deals with YUY2 colourspace where each 4 byte sequence represents\n                // 2 pixels, (Y1, U, Y2 and then V).\n\n                // This colourspace is more memory efficient than RGB32 but can be more awkward to use sometimes.\n                // However, it can still be manipulated 32bits at a time depending on the\n                // type of filter you are writing\n\n                // There is no difference in code for this loop and the RGB32 code due to a coincidence :-)\n                // 1) YUY2 frame_width is half of an RGB32 one\n                // 2) But in YUY2 colourspace, a 32bit variable holds 2 pixels instead of the 1 in RGB32 colourspace.\n\n                for (h=0; h < src_height;h++) {                                            // Loop from top line to bottom line (opposite of RGB colourspace).\n                        for (w = 0; w < src_width/4; w+=1) {                               // and from leftmost double-pixel to rightmost one.\n                                *((unsigned int *)dstp + w) = *((unsigned int *)srcp + w); // Copy 2 pixels worth of information from source to destination.\n                        }                                                                  // at a time by temporarily treating the src and dst pointers as\n                                                                                           // 32bit (4 byte) pointers intead of 8 bit (1 byte) pointers\n                        srcp = srcp + src_pitch;                                           // Add the pitch (note use of pitch and not width) of one line (in bytes) to the source pointer\n                        dstp = dstp + dst_pitch;                                           // Add the pitch to the destination pointer.\n                }\n                // end copy src to dst\n\n                //Now draw a white square in the middle of the frame\n                // Normally you'd do this code within the loop above but here it is in a separate loop for clarity;\n\n                dstp = dst->GetWritePtr();                                          // reset the destination pointer to the top, left pixel. (YUY2 colourspace only)\n                dstp = dstp + (dst_height/2 - SquareSize/2)*dst_pitch;              // move pointer to SquareSize/2 lines from the middle of the frame;\n\n                int woffset = dst_width/8 - SquareSize/4;                           // lets precalulate the width offset like we do for the lines.\n                for (h=0; h < SquareSize;h++) {                                     // only scan SquareSize number of lines\n                        for (w = 0; w < SquareSize/2; w+=1) {                       // only scans the middle SquareSize pixels of a line\n                                *((unsigned int *)dstp + woffset + w) = 0x80EB80EB; // Set Y1 and Y2 to max, U and V to no colour.\n                        }                                                           // LSB = Y1, MSB = V\n                        dstp = dstp + dst_pitch;\n                }\n      }\n\n      // As we now are finished processing the image, we return the destination image.\n        return dst;\n    }\n\n\n    // This is the function that created the filter, when the filter has been called.\n    // This can be used for simple parameter checking, so it is possible to create different filters,\n    // based on the arguments recieved.\n\n    AVSValue __cdecl Create_SimpleSample(AVSValue args, void* user_data,\n    IScriptEnvironment* env) {\n        return new SimpleSample(args[0].AsClip(),\n                 args[1].AsInt(0),      // Corresponds to our 1st parameter - the size of the square in pixels.\n                 env);                  // Calls the constructor with the arguments provied.\n    }\n\n\n    // The following function is the function that actually registers the filter in AviSynth\n    // It is called automatically, when the plugin is loaded to see which functions this filter contains.\n\n    extern \"C\" __declspec(dllexport) const char* __stdcall\n    AvisynthPluginInit2(IScriptEnvironment* env) {\n        env->AddFunction(\"SimpleSample\", \"c[SIZE]i\",\n        Create_SimpleSample, 0);\n        // The AddFunction has the following paramters:\n        // AddFunction(Filtername , Arguments, Function to call,0);\n\n        // Arguments is a string that defines the types and optional names of the arguments for you filter.\n        // c - Video Clip\n        // i - Integer number\n        // f - Float number\n        // s - String\n        // b - boolean\n\n         // The word inside the [ ] lets you used named parameters in your script\n         // e.g last=SimpleSample(last,size=100).\n         // but last=SimpleSample(last,100) will also work automagically\n\n        return \"`SimpleSample' SimpleSample plugin\";\n        // A freeform name of the plugin.\n    }\n\nBack to :doc:`SimpleSample <SimpleSample>`\n\n$Date: 2025-02-24 21:09:29-05:00 $\n\n.. _SimpleSample 1.5a: http://avisynth.nl/index.php/Filter_SDK/Simple_sample_1.5a\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/SimpleSample16.rst",
    "content": "\n`SimpleSample 1.6`_\n===================\n\n`SimpleSample 1.6: <http://www.geocities.com/siwalters_uk/simplesample16.zip>`_\n\n::\n\n    /*\n        SimpleSample plugin for Avisynth -- a simple sample\n\n        Copyright (C) 2002-2003 Simon Walters, All Rights Reserved\n\n        This program is free software; you can redistribute it and/or\n    modify\n        it under the terms of the GNU General Public License as published\n    by\n        the Free Software Foundation.\n\n        This program is distributed in the hope that it will be useful,\n        but WITHOUT ANY WARRANTY; without even the implied warranty of\n        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n        GNU General Public License for more details.\n\n        You should have received a copy of the GNU General Public License\n        along with this program; if not, write to the Free Software\n        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n        The author can be contacted at:\n        Simon Walters\n        siwalters@hotmail.com\n\n        V1.0 - 1st release.\n        V1.0a - Revised version to put colourspace checking in the right\n    place.\n      V1.0b - Added detailed comments.  // sh0dan\n        V1.1 - Added sh0dan's planar (YV12) code\n        V1.2 - Revert to RGB24 colourspace only to show simple pixel\n    manipulation;\n        V1.3 - add in a parameter to vary the size of the square.\n        V1.4 - Add in RGB32 colourspace code\n        V1.5 - Add in YUY2 colourspace code\n        V1.5a - bug fix in max Y1 and Y2 values\n        V1.6 - Add in YV12 colourspace - yippee.\n\n    */\n    //following 2 includes needed\n    #include \"windows.h\"\n    #include \"avisynth.h\"\n\n    /****************************\n     * The following is the header definitions.\n     * For larger projects, move this into a .h file\n     * that can be included.\n     ****************************/\n\n\n    class SimpleSample : public GenericVideoFilter {\n      // SimpleSample defines the name of your filter class.\n      // This name is only used internally, and does not affect the name of your filter or similar.\n      // This filter extends GenericVideoFilter, which incorporates basic functionality.\n      // All functions present in the filter must also be present here.\n\n        // define the parameter variable\n        int SquareSize;\n\n    public:\n      // This defines that these functions are present in your class.\n      // These functions must be that same as those actually implemented.\n      // Since the functions are \"public\" they are accessible to other classes.\n      // Otherwise they can only be called from functions within the class itself.\n\n        SimpleSample(PClip _child, int _SquareSize, IScriptEnvironment* env);\n      // This is the constructor. It does not return any value, and is always used,\n      //  when an instance of the class is created.\n      // Since there is no code in this, this is the definition.\n\n      ~SimpleSample();\n      // The is the destructor definition. This is called when the filter is destroyed.\n\n\n        PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n      // This is the function that AviSynth calls to get a given frame.\n      // So when this functions gets called, the filter is supposed to return frame n.\n    };\n\n    /***************************\n     * The following is the implementation\n     * of the defined functions.\n     ***************************/\n\n    //Here is the acutal constructor code used\n    SimpleSample::SimpleSample(PClip _child, int _SquareSize,\n    IScriptEnvironment* env) :\n        GenericVideoFilter(_child), SquareSize(_SquareSize) {\n      // This is the implementation of the constructor.\n      // The child clip (source clip) is inherited by the GenericVideoFilter,\n      //  where the following variables gets defined:\n      //   PClip child;   // Contains the source clip.\n      //   VideoInfo vi;  // Contains videoinfo on the source clip.\n    }\n\n    // This is where any actual destructor code used goes\n    SimpleSample::~SimpleSample() {\n      // This is where you can deallocate any memory you might have used.\n    }\n\n\n\n\n    PVideoFrame __stdcall SimpleSample::GetFrame(int n,\n    IScriptEnvironment* env) {\n    // This is the implementation of the GetFrame function.\n    // See the header definition for further info.\n\n        PVideoFrame src = child->GetFrame(n, env);\n       // Request frame 'n' from the child (source) clip.\n        PVideoFrame dst = env->NewVideoFrame(vi);\n       // Construct a frame based on the information of the current frame\n       // contained in the \"vi\" struct.\n\n        const unsigned char* srcp = src->GetReadPtr();\n      // Request a Read pointer from the source frame.\n      // This will return the position of the upperleft pixel in YUY2 images,\n      // and return the lower-left pixel in RGB.\n      // RGB images are stored upside-down in memory.\n      // You should still process images from line 0 to height.\n\n        unsigned char* dstp = dst->GetWritePtr();\n        // Request a Write pointer from the newly created destination image.\n      // You can request a writepointer to images that have just been\n      // created by NewVideoFrame. If you recieve a frame from PClip->GetFrame(...)\n      // you must call env->MakeWritable(&frame) be recieve a valid write pointer.\n\n        const int dst_pitch = dst->GetPitch();\n      // Requests pitch (length of a line) of the destination image.\n      // For more information on pitch see:\n      // http://avisynth.nl/index.php/Filter_SDK/Working_with_images\n        // (short version - pitch is always equal to or greater than width to allow for seriously fast assembly code)\n\n        const int dst_width = dst->GetRowSize();\n      // Requests rowsize (number of used bytes in a line.\n      // See the link above for more information.\n\n        const int dst_height = dst->GetHeight();\n      // Requests the height of the destination image.\n\n        const int src_pitch = src->GetPitch();\n        const int src_width = src->GetRowSize();\n        const int src_height = src->GetHeight();\n\n        int w, h;\n\n        // This version of SimpleSample is intended to show some simple pixel manipulation.\n        // It is designed purely for clarity and not as good or clever code :-)\n\n\n        if (vi.IsRGB24()) {\n                // The code just deals with RGB24 colourspace where each pixel is represented by\n                // 3 bytes, Blue, Green and Red.\n                // Although this colourspace is the easiest to understand, it is very rarely used because\n                // a 3 byte sequence (24bits) cannot be processed easily using normal 32 bit registers.\n\n                for (h=0; h < src_height;h++) {                       // Loop from bottom line to top line.\n                        for (w = 0; w < src_width; w+=3) {            // Loop from left side of the image to the right side 1 pixel (3 bytes) at a time\n                                                                      // stepping 3 bytes (a pixel width in RGB24 space)\n\n                                *(dstp + w) = *(srcp + w);            // Copy each Blue byte from source to destination.\n                                *(dstp + w + 1) = *(srcp + w + 1);    // Copy Green.\n                                *(dstp + w + 2) = *(srcp + w + 2);    // Copy Red\n                        }\n\n                        srcp = srcp + src_pitch; // Add the pitch (note use of pitch and not width) of one line (in bytes) to the source pointer\n                        dstp = dstp + dst_pitch; // Add the pitch to the destination pointer.\n                }\n                // end copy src to dst\n\n                //Now draw a white square in the middle of the frame\n                // Normally you'd do this code within the loop above but here it is in a separate loop for clarity;\n\n                dstp = dst->GetWritePtr();                                                               // reset the destination pointer to the bottom, left pixel. (RGB colourspaces only)\n                dstp = dstp + (dst_height/2 - SquareSize/2)*dst_pitch;                                   // move pointer to SquareSize/2 lines from the middle of the frame;\n                for (h=0; h < SquareSize;h++) {                                                          // only scan 100 lines\n                        for (w = dst_width/2 - SquareSize*3/2; w < dst_width/2 + SquareSize*3/2; w+=3) { // only scans the middle SquareSize pixels of a line\n                                *(dstp + w) = 255;                                                       // Set Blue to maximum value.\n                                *(dstp + w + 1) = 255;                                                   // and Green.\n                                *(dstp + w + 2) = 255;                                                   // and Red - therefore the whole pixel is now white.\n                        }\n                        dstp = dstp + dst_pitch;\n                }\n        }\n\n        if (vi.IsRGB32()) {\n                // This code deals with RGB32 colourspace where each pixel is represented by\n                // 4 bytes, Blue, Green and Red and \"spare\" byte that could/should be used for alpha\n                // keying but usually isn't.\n\n                // Although this colourspace isn't memory efficient, code end ups running much\n                // quicker than RGB24 as you can deal with whole 32bit variables at a time\n                // and easily work directly and quickly in assembler (if you know how to that is :-)\n\n                for (h=0; h < src_height;h++) {                                            // Loop from bottom line to top line.\n                        for (w = 0; w < src_width/4; w+=1) {                               // and from leftmost pixel to rightmost one.\n                                *((unsigned int *)dstp + w) = *((unsigned int *)srcp + w); // Copy each whole pixel from source to destination.\n                        }                                                                  // by temporarily treating the src and dst pointers as\n                                                                                           // pixel pointers intead of byte pointers\n                        srcp = srcp + src_pitch;                                           // Add the pitch (note use of pitch and not width) of one line (in bytes) to the source pointer\n                        dstp = dstp + dst_pitch;                                           // Add the pitch to the destination pointer.\n                }\n                // end copy src to dst\n\n                //Now draw a white square in the middle of the frame\n                // Normally you'd do this code within the loop above but here it is in a separate loop for clarity;\n\n                dstp = dst->GetWritePtr();                                // reset the destination pointer to the bottom, left pixel. (RGB colourspaces only)\n                dstp = dstp + (dst_height/2 - SquareSize/2)*dst_pitch;    // move pointer to SquareSize/2 lines from the middle of the frame;\n\n                int woffset = dst_width/8 - SquareSize/2;                           // lets precalulate the width offset like we do for the lines.\n\n                for (h=0; h < SquareSize;h++) {                                     // only scan SquareSize number of lines\n                        for (w = 0; w < SquareSize; w+=1) {                         // only scans the middle SquareSize pixels of a line\n                                *((unsigned int *)dstp + woffset + w) = 0x00FFFFFF; // Set Red,Green and Blue to maximum value in 1 instruction.\n                                                                                    // LSB = Blue, MSB = \"spare\" byte\n                        }\n                        dstp = dstp + dst_pitch;\n                }\n      }\n\n        if (vi.IsYUY2()) {\n                // This code deals with YUY2 colourspace where each 4 byte sequence represents\n                // 2 pixels, (Y1, U, Y2 and then V).\n\n                // This colourspace is more memory efficient than RGB32 but can be more awkward to use sometimes.\n                // However, it can still be manipulated 32bits at a time depending on the\n                // type of filter you are writing\n\n                // There is no difference in code for this loop and the RGB32 code due to a coincidence :-)\n                // 1) YUY2 frame_width is half of an RGB32 one\n                // 2) But in YUY2 colourspace, a 32bit variable holds 2 pixels instead of the 1 in RGB32 colourspace.\n\n                for (h=0; h < src_height;h++) {                                            // Loop from top line to bottom line (opposite of RGB colourspace).\n                        for (w = 0; w < src_width/4; w+=1) {                               // and from leftmost double-pixel to rightmost one.\n                                *((unsigned int *)dstp + w) = *((unsigned int *)srcp + w); // Copy 2 pixels worth of information from source to destination.\n                        }                                                                  // at a time by temporarily treating the src and dst pointers as\n                                                                                           // 32bit (4 byte) pointers intead of 8 bit (1 byte) pointers\n                        srcp = srcp + src_pitch;                                           // Add the pitch (note use of pitch and not width) of one line (in bytes) to the source pointer\n                        dstp = dstp + dst_pitch;                                           // Add the pitch to the destination pointer.\n                }\n                // end copy src to dst\n\n                //Now draw a white square in the middle of the frame\n                // Normally you'd do this code within the loop above but here it is in a separate loop for clarity;\n\n                dstp = dst->GetWritePtr();                                // reset the destination pointer to the top, left pixel. (YUY2 colourspace only)\n                dstp = dstp + (dst_height/2 - SquareSize/2)*dst_pitch;    // move pointer to SquareSize/2 lines from the middle of the frame;\n\n                int woffset = dst_width/8 - SquareSize/4;                           // lets precalulate the width offset like we do for the lines.\n                for (h=0; h < SquareSize;h++) {                                     // only scan SquareSize number of lines\n                        for (w = 0; w < SquareSize/2; w+=1) {                       // only scans the middle SquareSize pixels of a line\n                                *((unsigned int *)dstp + woffset + w) = 0x80EB80EB; // Set Y1 and Y2 to max, U and V to no colour.\n                        }                                                           // LSB = Y1, MSB = V\n                        dstp = dstp + dst_pitch;\n                }\n      }\n\n        if (vi.IsYV12()) {\n\n                // This code deals with YV12 colourspace where the Y, U and V information are\n                // stored in completely separate memory areas\n\n                // This colourspace is the most memory efficient but usually requires 3 separate loops\n                // However, it can actually be easier to deal with than YUY2 depending on your filter algorithim\n\n                // So first of all deal with the Y Plane\n\n                for (h=0; h < src_height;h++) {             // Loop from top line to bottom line (Sames as YUY2.\n                        for (w = 0; w < src_width; w++)     // Loop from left side of the image to the right side.\n                                *(dstp + w) = *(srcp + w);  // Copy each byte from source to destination.\n                        srcp = srcp + src_pitch;            // Add the pitch (note use of pitch and not width) of one line (in bytes) to the source image.\n                        dstp = dstp + dst_pitch;            // Add the pitch of one line (in bytes) to the destination.\n                }                                           // end copy Y Plane src to dst\n\n                //Now set the Y plane bytes to maximum in the middle of the frame\n                // Normally you'd do this code within the loop above but here it is in a separate loop for clarity;\n\n                dstp = dst->GetWritePtr();                                // reset the destination pointer to the top, left pixel.\n                dstp = dstp + (dst_height/2 - SquareSize/2)*dst_pitch;    // move pointer to SquareSize/2 lines from the middle of the frame;\n\n                int woffset = dst_width/2 - SquareSize/2;  // lets precalulate the width offset like we do for the lines.\n\n                for (h=0; h < SquareSize;h++) {              // only scan SquareSize number of lines\n                        for (w = 0; w < SquareSize; w+=1) {  // only scans the middle SquareSize pixels of a line\n                                *(dstp + woffset + w) = 235; // Set Y values to maximum\n                        }\n                        dstp = dstp + dst_pitch;\n                }\n                // end of Y plane Code\n\n                // This section of code deals with the U and V planes of planar formats (e.g. YV12)\n                // So first of all we have to get the additional info on the U and V planes\n\n                const int dst_pitchUV = dst->GetPitch(PLANAR_U);    // The pitch,height and width information\n                const int dst_widthUV = dst->GetRowSize(PLANAR_U);  // is guaranted to be the same for both\n                const int dst_heightUV = dst->GetHeight(PLANAR_U);  // the U and V planes so we only the U\n                const int src_pitchUV = src->GetPitch(PLANAR_U);    // plane values and use them for V as\n                const int src_widthUV = src->GetRowSize(PLANAR_U);  // well\n                const int src_heightUV = src->GetHeight(PLANAR_U);  //\n\n                //Copy U plane src to dst\n                srcp = src->GetReadPtr(PLANAR_U);\n                dstp = dst->GetWritePtr(PLANAR_U);\n\n                for (h=0; h < src_heightUV;h++) {\n                        for (w = 0; w < src_widthUV; w++)\n                                *(dstp + w) = *(srcp + w);\n                        srcp = srcp + src_pitchUV;\n                        dstp = dstp + dst_pitchUV;\n                }\n                // end copy U plane src to dst\n\n                //Now set the U plane bytes to no colour in the middle of the frame\n                // Normally you'd do this code within the loop above but here it is in a separate loop for clarity;\n\n                dstp = dst->GetWritePtr(PLANAR_U);                          // reset the destination pointer to the top, left pixel.\n                dstp = dstp + (dst_heightUV/2 - SquareSize/4)*dst_pitchUV;  // note change in how much we dived SquareSize by\n                                                                            // as the U plane height is half the Y plane\n\n                woffset = dst_widthUV/2 - SquareSize/4;  // And the divisor changes here as well compared to Y plane code.\n\n                for (h=0; h < SquareSize/2;h++) {             // only scan SquareSize/2 number of lines (because the U plane height is half the Y)\n                        for (w = 0; w < SquareSize/2; w+=1) { // only scans the middle SquareSize/2 bytes of a line because ... U=Y/2 :-)\n                                *(dstp + woffset + w) = 128;  // Set U Value to no colour\n                        }\n                        dstp = dstp + dst_pitchUV;\n                }\n                // end of U plane Code\n\n\n\n                //Copy V plane src to dst\n                srcp = src->GetReadPtr(PLANAR_V);\n                dstp = dst->GetWritePtr(PLANAR_V);\n\n                for (h=0; h < src_heightUV;h++) {\n                        for (w = 0; w < src_widthUV; w++)\n                                *(dstp + w) = *(srcp + w);\n                        srcp = srcp + src_pitchUV;\n                        dstp = dstp + dst_pitchUV;\n                }\n                // end copy V plane src to dst\n\n                //Now set the V plane bytes to no colour in the middle of the frame\n                // the code is identical to the code for U plane apart from getting the frame start pointer.\n                // Normally you'd do this code within the loop above but here it is in a separate loop for clarity;\n\n                dstp = dst->GetWritePtr(PLANAR_V);                         // reset the destination pointer to the top, left pixel.\n                dstp = dstp + (dst_heightUV/2 - SquareSize/4)*dst_pitchUV; // note change in how much we dived SquareSize by\n                                                                           // as the V plane height is half the Y plane\n\n                woffset = dst_widthUV/2 - SquareSize/4;  // And the divisor changes here as well compared to Y plane code.\n\n                for (h=0; h < SquareSize/2;h++) {             // only scan SquareSize/2 number of lines (because the V plane height is half the Y)\n                        for (w = 0; w < SquareSize/2; w+=1) { // only scans the middle SquareSize/2 bytes of a line because ... V=Y/2 :-)\n                                *(dstp + woffset + w) = 128;  // Set V Value to no colour\n                        }\n                        dstp = dstp + dst_pitchUV;\n                }\n                // end of U plane Code\n\n        }\n\n      // As we now are finished processing the image, we return the destination image.\n        return dst;\n    }\n\n\n    // This is the function that created the filter, when the filter has been called.\n    // This can be used for simple parameter checking, so it is possible to create different filters,\n    // based on the arguments recieved.\n\n    AVSValue __cdecl Create_SimpleSample(AVSValue args, void* user_data,\n    IScriptEnvironment* env) {\n        return new SimpleSample(args[0].AsClip(),\n                 args[1].AsInt(0),      // Corresponds to our 1st parameter - the size of the square in pixels.\n                 env);                  // Calls the constructor with the arguments provied.\n    }\n\n\n    // The following function is the function that actually registers the filter in AviSynth\n    // It is called automatically, when the plugin is loaded to see which functions this filter contains.\n\n    extern \"C\" __declspec(dllexport) const char* __stdcall\n    AvisynthPluginInit2(IScriptEnvironment* env) {\n        env->AddFunction(\"SimpleSample\", \"c[SIZE]i\",\n        Create_SimpleSample, 0);\n        // The AddFunction has the following paramters:\n        // AddFunction(Filtername , Arguments, Function to call,0);\n\n        // Arguments is a string that defines the types and optional names of the arguments for you filter.\n        // c - Video Clip\n        // i - Integer number\n        // f - Float number\n        // s - String\n        // b - boolean\n\n         // The word inside the [ ] lets you used named parameters in your script\n         // e.g last=SimpleSample(last,size=100).\n         // but last=SimpleSample(last,100) will also work automagically\n\n        return \"`SimpleSample' SimpleSample plugin\";\n        // A freeform name of the plugin.\n    }\n\nBack to :doc:`SimpleSample <SimpleSample>`\n\n$Date: 2025-02-24 21:01:51-05:00 $\n\n.. _SimpleSample 1.6: http://avisynth.nl/index.php/Filter_SDK/Simple_sample_1.6\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/SimpleSample17.rst",
    "content": "\n`SimpleSample 1.7`_\n===================\n\n`SimpleSample 1.7: <http://www.geocities.com/siwalters_uk/simplesample17.zip>`_\n\n::\n\n    /*\n        SimpleSample plugin for Avisynth -- a simple sample\n\n        Copyright (C) 2002-2003 Simon Walters, All Rights Reserved\n\n        This program is free software; you can redistribute it and/or\n    modify\n        it under the terms of the GNU General Public License as published\n    by\n        the Free Software Foundation.\n\n        This program is distributed in the hope that it will be useful,\n        but WITHOUT ANY WARRANTY; without even the implied warranty of\n        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n        GNU General Public License for more details.\n\n        You should have received a copy of the GNU General Public License\n        along with this program; if not, write to the Free Software\n        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n        The author can be contacted at:\n        Simon Walters\n        siwalters@hotmail.com\n\n        V1.0 - 1st release.\n        V1.0a - Revised version to put colourspace checking in the right\n    place.\n      V1.0b - Added detailed comments.  // sh0dan\n        V1.1 - Added sh0dan's planar (YV12) code\n        V1.2 - Revert to RGB24 colourspace only to show simple pixel\n    manipulation;\n        V1.3 - add in a parameter to vary the size of the square.\n        V1.4 - Add in RGB32 colourspace code\n        V1.5 - Add in YUY2 colourspace code\n        V1.5a - bug fix in max Y1 and Y2 values\n        V1.6 - Add in YV12 colourspace - yippee.\n        V1.7 - add in ability to use info from 2 clips only the YUY2\n    colorspace code altered\n\n    */\n    //following 2 includes needed\n    #include \"windows.h\"\n    #include \"avisynth.h\"\n\n    /****************************\n     * The following is the header definitions.\n     * For larger projects, move this into a .h file\n     * that can be included.\n     ****************************/\n\n\n    class SimpleSample : public GenericVideoFilter {\n      // SimpleSample defines the name of your filter class.\n      // This name is only used internally, and does not affect the name of your filter or similar.\n      // This filter extends GenericVideoFilter, which incorporates basic functionality.\n      // All functions present in the filter must also be present here.\n\n\n        PClip WindowVideo; // define the secondary video clip parameter variable\n        int SquareSize; // define thesquare size parameter variable\n\n\n    public:\n      // This defines that these functions are present in your class.\n      // These functions must be that same as those actually implemented.\n      // Since the functions are \"public\" they are accessible to other classes.\n      // Otherwise they can only be called from functions within the class itself.\n\n        SimpleSample(PClip _child,      PClip _WindowVideo, int _SquareSize,  IScriptEnvironment* env);\n      // This is the constructor. It does not return any value, and is always used,\n      //  when an instance of the class is created.\n      // Since there is no code in this, this is the definition.\n\n      ~SimpleSample();\n      // The is the destructor definition. This is called when the filter is destroyed.\n\n\n        PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n      // This is the function that AviSynth calls to get a given frame.\n      // So when this functions gets called, the filter is supposed to return frame n.\n    };\n\n    /***************************\n     * The following is the implementation\n     * of the defined functions.\n     ***************************/\n\n    //Here is the acutal constructor code used\n    SimpleSample::SimpleSample(PClip _child, PClip _WindowVideo, int _SquareSize,  IScriptEnvironment* env) :\n        GenericVideoFilter(_child), WindowVideo(_WindowVideo), SquareSize(_SquareSize){\n      // This is the implementation of the constructor.\n      // The child clip (source clip) is inherited by the GenericVideoFilter,\n      //  where the following variables gets defined:\n      //   PClip child;   // Contains the source clip.\n      //   VideoInfo vi;  // Contains videoinfo on the source clip.\n    }\n\n    // This is where any actual destructor code used goes\n    SimpleSample::~SimpleSample() {\n      // This is where you can deallocate any memory you might have used.\n    }\n\n\n\n\n    PVideoFrame __stdcall SimpleSample::GetFrame(int n,\n    IScriptEnvironment* env) {\n    // This is the implementation of the GetFrame function.\n    // See the header definition for further info.\n\n        PVideoFrame src = child->GetFrame(n, env);\n       // Request frame 'n' from the child (source) clip.\n        PVideoFrame window = WindowVideo->GetFrame(n, env);\n        // Request frame \"'n\" from the WindowVideo clip\n        PVideoFrame dst = env->NewVideoFrame(vi);\n       // Construct a frame based on the information of the current frame\n       // contained in the \"vi\" struct.\n\n        const unsigned char* srcp = src->GetReadPtr();\n      // Request a Read pointer from the source frame.\n      // This will return the position of the upperleft pixel in YUY2 images,\n      // and return the lower-left pixel in RGB.\n      // RGB images are stored upside-down in memory.\n      // You should still process images from line 0 to height.\n\n        unsigned char* dstp = dst->GetWritePtr();\n        // Request a Write pointer from the newly created destination image.\n      // You can request a writepointer to images that have just been\n      // created by NewVideoFrame. If you recieve a frame from PClip->GetFrame(...)\n      // you must call env->MakeWritable(&frame) be recieve a valid write pointer.\n\n        const int dst_pitch = dst->GetPitch();\n      // Requests pitch (length of a line) of the destination image.\n      // For more information on pitch see:\n      // http://avisynth.nl/index.php/Filter_SDK/Working_with_images\n        // (short version - pitch is always equal to or greater than width to allow for seriously fast assembly code)\n\n        const int dst_width = dst->GetRowSize();\n      // Requests rowsize (number of used bytes in a line.\n      // See the link above for more information.\n\n        const int dst_height = dst->GetHeight();\n      // Requests the height of the destination image.\n\n        const int src_pitch = src->GetPitch();\n        const int src_width = src->GetRowSize();\n        const int src_height = src->GetHeight();\n\n        const unsigned char* windowp=window->GetReadPtr();\n        const int window_pitch = window->GetPitch();\n        const int window_width = window->GetRowSize();\n        const int window_height = window->GetHeight();\n        // Get info on the Windowed Clip (see src definitions for more information)\n\n\n        int w, h;\n\n        // This version of SimpleSample is intended to show how to utilise information from 2 clips in YUY2\n        // colourspace only.  The original V1.6 code has been left in place fro all other\n        // colourspaces.\n        // It is designed purely for clarity and not as good or clever code :-)\n\n\n        if (vi.IsRGB24()) {\n                // The code just deals with RGB24 colourspace where each pixel is represented by\n                // 3 bytes, Blue, Green and Red.\n                // Although this colourspace is the easiest to understand, it is very rarely used because\n                // a 3 byte sequence (24bits) cannot be processed easily using normal 32 bit registers.\n\n                for (h=0; h < src_height;h++) {                       // Loop from bottom line to top line.\n                        for (w = 0; w < src_width; w+=3) {            // Loop from left side of the image to the right side 1 pixel (3 bytes) at a time\n                                                                      // stepping 3 bytes (a pixel width in RGB24 space)\n\n                                *(dstp + w) = *(srcp + w);            // Copy each Blue byte from source to destination.\n                                *(dstp + w + 1) = *(srcp + w + 1);    // Copy Green.\n                                *(dstp + w + 2) = *(srcp + w + 2);    // Copy Red\n                        }\n\n                        srcp = srcp + src_pitch; // Add the pitch (note use of pitch and not width) of one line (in bytes) to the source pointer\n                        dstp = dstp + dst_pitch; // Add the pitch to the destination pointer.\n                }\n                // end copy src to dst\n\n                //Now draw a white square in the middle of the frame\n                // Normally you'd do this code within the loop above but here it is in a separate loop for clarity;\n\n                dstp = dst->GetWritePtr();                                                               // reset the destination pointer to the bottom, left pixel. (RGB colourspaces only)\n                dstp = dstp + (dst_height/2 - SquareSize/2)*dst_pitch;                                   // move pointer to SquareSize/2 lines from the middle of the frame;\n                for (h=0; h < SquareSize;h++) {                                                          // only scan 100 lines\n                        for (w = dst_width/2 - SquareSize*3/2; w < dst_width/2 + SquareSize*3/2; w+=3) { // only scans the middle SquareSize pixels of a line\n                                *(dstp + w) = 255;                                                       // Set Blue to maximum value.\n                                *(dstp + w + 1) = 255;                                                   // and Green.\n                                *(dstp + w + 2) = 255;                                                   // and Red - therefore the whole pixel is now white.\n                        }\n                        dstp = dstp + dst_pitch;\n                }\n        }\n\n        if (vi.IsRGB32()) {\n                // This code deals with RGB32 colourspace where each pixel is represented by\n                // 4 bytes, Blue, Green and Red and \"spare\" byte that could/should be used for alpha\n                // keying but usually isn't.\n\n                // Although this colourspace isn't memory efficient, code end ups running much\n                // quicker than RGB24 as you can deal with whole 32bit variables at a time\n                // and easily work directly and quickly in assembler (if you know how to that is :-)\n\n                for (h=0; h < src_height;h++) {                                            // Loop from bottom line to top line.\n                        for (w = 0; w < src_width/4; w+=1) {                               // and from leftmost pixel to rightmost one.\n                                *((unsigned int *)dstp + w) = *((unsigned int *)srcp + w); // Copy each whole pixel from source to destination.\n                        }                                                                  // by temporarily treating the src and dst pointers as\n                                                                                           // pixel pointers intead of byte pointers\n                        srcp = srcp + src_pitch;                                           // Add the pitch (note use of pitch and not width) of one line (in bytes) to the source pointer\n                        dstp = dstp + dst_pitch;                                           // Add the pitch to the destination pointer.\n                }\n                // end copy src to dst\n\n                //Now draw a white square in the middle of the frame\n                // Normally you'd do this code within the loop above but here it is in a separate loop for clarity;\n\n                dstp = dst->GetWritePtr();                                // reset the destination pointer to the bottom, left pixel. (RGB colourspaces only)\n                dstp = dstp + (dst_height/2 - SquareSize/2)*dst_pitch;    // move pointer to SquareSize/2 lines from the middle of the frame;\n\n                int woffset = dst_width/8 - SquareSize/2;                 // lets precalulate the width offset like we do for the lines.\n\n                for (h=0; h < SquareSize;h++) {                                     // only scan SquareSize number of lines\n                        for (w = 0; w < SquareSize; w+=1) {                         // only scans the middle SquareSize pixels of a line\n                                *((unsigned int *)dstp + woffset + w) = 0x00FFFFFF; // Set Red,Green and Blue to maximum value in 1 instruction.\n                                                                                    // LSB = Blue, MSB = \"spare\" byte\n                        }\n                        dstp = dstp + dst_pitch;\n                }\n      }\n\n        if (vi.IsYUY2()) {\n                // This code deals with YUY2 colourspace where each 4 byte sequence represents\n                // 2 pixels, (Y1, U, Y2 and then V).\n\n                // This colourspace is more memory efficient than RGB32 but can be more awkward to use sometimes.\n                // However, it can still be manipulated 32bits at a time depending on the\n                // type of filter you are writing\n\n                // There is no difference in code for this loop and the RGB32 code due to a coincidence :-)\n                // 1) YUY2 frame_width is half of an RGB32 one\n                // 2) But in YUY2 colourspace, a 32bit variable holds 2 pixels instead of the 1 in RGB32 colourspace.\n\n                for (h=0; h < src_height;h++) {                                            // Loop from top line to bottom line (opposite of RGB colourspace).\n                        for (w = 0; w < src_width/4; w+=1) {                               // and from leftmost double-pixel to rightmost one.\n                                *((unsigned int *)dstp + w) = *((unsigned int *)srcp + w); // Copy 2 pixels worth of information from source to destination.\n                        }                                                                  // at a time by temporarily treating the src and dst pointers as\n                                                                                           // 32bit (4 byte) pointers intead of 8 bit (1 byte) pointers\n                        srcp = srcp + src_pitch;                                           // Add the pitch (note use of pitch and not width) of one line (in bytes) to the source pointer\n                        dstp = dstp + dst_pitch;                                           // Add the pitch to the destination pointer.\n                }\n                // end copy src to dst\n\n                //Now draw the other clip inside a square in the middle of the frame\n                // Normally you'd do this code within the loop above but here it is in a separate loop for clarity;\n\n                dstp = dst->GetWritePtr();                                // reset the destination pointer to the top, left pixel. (YUY2 colourspace only)\n                dstp = dstp + (dst_height/2 - SquareSize/2)*dst_pitch;    // move pointer to SquareSize/2 lines from the middle of the frame;\n\n                windowp = window->GetReadPtr();\n\n                int woffset = dst_width/8 - SquareSize/4;                                               // lets precalulate the width offset like we do for the lines.\n                for (h=0; h < SquareSize;h++) {                                                         // only scan SquareSize number of lines\n                        for (w = 0; w < SquareSize/2; w+=1) {                                           // only scans the middle SquareSize pixels of a line\n                                *((unsigned int *)dstp + woffset + w) = *((unsigned int *)windowp + w); // Pixels to come from top left of WindowVideo\n                        }\n                        dstp = dstp + dst_pitch;\n                        windowp = windowp + window_pitch;\n                }\n      }\n\n        if (vi.IsYV12()) {\n\n                // This code deals with YV12 colourspace where the Y, U and V information are\n                // stored in completely separate memory areas\n\n                // This colourspace is the most memory efficient but usually requires 3 separate loops\n                // However, it can actually be easier to deal with than YUY2 depending on your filter algorithim\n\n                // So first of all deal with the Y Plane\n\n                for (h=0; h < src_height;h++) {       // Loop from top line to bottom line (Sames as YUY2.\n                        for (w = 0; w < src_width; w++)       // Loop from left side of the image to the right side.\n                                *(dstp + w) = *(srcp + w);          // Copy each byte from source to destination.\n                        srcp = srcp + src_pitch;            // Add the pitch (note use of pitch and not width) of one line (in bytes) to the source image.\n                        dstp = dstp + dst_pitch;            // Add the pitch of one line (in bytes) to the destination.\n                }\n                // end copy Y Plane src to dst\n\n                //Now set the Y plane bytes to maximum in the middle of the frame\n                // Normally you'd do this code within the loop above but here it is in a separate loop for clarity;\n\n                dstp = dst->GetWritePtr();                                // reset the destination pointer to the top, left pixel.\n                dstp = dstp + (dst_height/2 - SquareSize/2)*dst_pitch;    // move pointer to SquareSize/2 lines from the middle of the frame;\n\n                int woffset = dst_width/2 - SquareSize/2;                 // lets precalulate the width offset like we do for the lines.\n\n                for (h=0; h < SquareSize;h++) {                           // only scan SquareSize number of lines\n                        for (w = 0; w < SquareSize; w+=1) {               // only scans the middle SquareSize pixels of a line\n                                *(dstp + woffset + w) = 235;              // Set Y values to maximum\n                        }\n                        dstp = dstp + dst_pitch;\n                }\n                // end of Y plane Code\n\n                // This section of code deals with the U and V planes of planar formats (e.g. YV12)\n                // So first of all we have to get the additional info on the U and V planes\n\n                const int dst_pitchUV = dst->GetPitch(PLANAR_U);    // The pitch,height and width information\n                const int dst_widthUV = dst->GetRowSize(PLANAR_U);  // is guaranted to be the same for both\n                const int dst_heightUV = dst->GetHeight(PLANAR_U);  // the U and V planes so we only the U\n                const int src_pitchUV = src->GetPitch(PLANAR_U);    // plane values and use them for V as\n                const int src_widthUV = src->GetRowSize(PLANAR_U);  // well\n                const int src_heightUV = src->GetHeight(PLANAR_U);  //\n\n                //Copy U plane src to dst\n                srcp = src->GetReadPtr(PLANAR_U);\n                dstp = dst->GetWritePtr(PLANAR_U);\n\n                for (h=0; h < src_heightUV;h++) {\n                        for (w = 0; w < src_widthUV; w++)\n                                *(dstp + w) = *(srcp + w);\n                        srcp = srcp + src_pitchUV;\n                        dstp = dstp + dst_pitchUV;\n                }\n                // end copy U plane src to dst\n\n                //Now set the U plane bytes to no colour in the middle of the frame\n                // Normally you'd do this code within the loop above but here it is in a separate loop for clarity;\n\n                dstp = dst->GetWritePtr(PLANAR_U);                          // reset the destination pointer to the top, left pixel.\n                dstp = dstp + (dst_heightUV/2 - SquareSize/4)*dst_pitchUV;  // note change in how much we dived SquareSize by\n                                                                            // as the U plane height is half the Y plane\n\n                woffset = dst_widthUV/2 - SquareSize/4;                     // And the divisor changes here as well compared to Y plane code.\n\n                for (h=0; h < SquareSize/2;h++) {                           // only scan SquareSize/2 number of lines (because the U plane height is half the Y)\n                        for (w = 0; w < SquareSize/2; w+=1) {               // only scans the middle SquareSize/2 bytes of a line because ... U=Y/2 :-)\n                                *(dstp + woffset + w) = 128;                // Set U Value to no colour\n                        }\n                        dstp = dstp + dst_pitchUV;\n                }\n                // end of U plane Code\n\n\n\n                //Copy V plane src to dst\n                srcp = src->GetReadPtr(PLANAR_V);\n                dstp = dst->GetWritePtr(PLANAR_V);\n\n                for (h=0; h < src_heightUV;h++) {\n                        for (w = 0; w < src_widthUV; w++)\n                                *(dstp + w) = *(srcp + w);\n                        srcp = srcp + src_pitchUV;\n                        dstp = dstp + dst_pitchUV;\n                }\n                // end copy V plane src to dst\n\n                //Now set the V plane bytes to no colour in the middle of the frame\n                // the code is identical to the code for U plane apart from getting the frame start pointer.\n                // Normally you'd do this code within the loop above but here it is in a separate loop for clarity;\n\n                dstp = dst->GetWritePtr(PLANAR_V);                          // reset the destination pointer to the top, left pixel.\n                dstp = dstp + (dst_heightUV/2 - SquareSize/4)*dst_pitchUV;  // note change in how much we dived SquareSize by\n                                                                            // as the V plane height is half the Y plane\n\n                woffset = dst_widthUV/2 - SquareSize/4;                     // And the divisor changes here as well compared to Y plane code.\n\n                for (h=0; h < SquareSize/2;h++) {                           // only scan SquareSize/2 number of lines (because the V plane height is half the Y)\n                        for (w = 0; w < SquareSize/2; w+=1) {               // only scans the middle SquareSize/2 bytes of a line because ... V=Y/2 :-)\n                                *(dstp + woffset + w) = 128;                // Set V Value to no colour\n                        }\n                        dstp = dstp + dst_pitchUV;\n                }\n                // end of U plane Code\n\n        }\n\n      // As we now are finished processing the image, we return the destination image.\n        return dst;\n    }\n\n\n    // This is the function that created the filter, when the filter has been called.\n    // This can be used for simple parameter checking, so it is possible to create different filters,\n    // based on the arguments recieved.\n\n    AVSValue __cdecl Create_SimpleSample(AVSValue args, void* user_data,\n    IScriptEnvironment* env) {\n        return new SimpleSample(args[0].AsClip(), // the 0th parameter is the source clip\n                 args[1].AsClip(),                // Corresponds to our 1st parameter - the WindowedVideo\n                 args[2].AsInt(0),                // Corresponds to our 2nd parameter - the size of the square in pixels.\n                 env);                            // Calls the constructor with the arguments provied.\n    }\n\n\n    // The following function is the function that actually registers the filter in AviSynth\n    // It is called automatically, when the plugin is loaded to see which functions this filter contains.\n\n    extern \"C\" __declspec(dllexport) const char* __stdcall\n    AvisynthPluginInit2(IScriptEnvironment* env) {\n        env->AddFunction(\"SimpleSample\", \"cc[SIZE]i\",\n        Create_SimpleSample, 0);\n        // The AddFunction has the following paramters:\n        // AddFunction(Filtername , Arguments, Function to call,0);\n\n        // Arguments is a string that defines the types and optional names of the arguments for you filter.\n        // c - Video Clip\n        // i - Integer number\n        // f - Float number\n        // s - String\n        // b - boolean\n\n         // The word inside the [ ] lets you used named parameters in your script\n         // e.g last=SimpleSample(last,windowclip,size=100).\n         // but last=SimpleSample(last,windowclip, 100) will also work\n\n        return \"`SimpleSample' SimpleSample plugin\";\n        // A freeform name of the plugin.\n    }\n\n\nBack to :doc:`SimpleSample <SimpleSample>`\n\n$Date: 2025-02-24 21:07:02-05:00 $\n\n.. _SimpleSample 1.7: http://avisynth.nl/index.php/Filter_SDK/Simple_sample_1.7\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/SimpleSample26.rst",
    "content": "\nSimpleSample\n============\n\nI have rewritten SimpleSample for AviSynth 2.6. I changed it into an in\nplace filter (so the source is overwritten). It draws a white square in\nthe center of the clip and it supports all colorformats.\n\nHere's simplesample.cpp:\n::\n\n    #include <windows.h>\n    #include \"avisynth.h\"\n\n    class SimpleSample : public GenericVideoFilter {\n       int SquareSize;\n    public:\n       SimpleSample(PClip _child, int _SquareSize, IScriptEnvironment* env);\n       ~SimpleSample();\n       PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n    };\n\n    SimpleSample::SimpleSample(PClip _child, int _SquareSize, IScriptEnvironment* env) :\n       GenericVideoFilter(_child), SquareSize(_SquareSize) {\n       if (vi.width<SquareSize || vi.height<SquareSize) {\n          env->ThrowError(\"SimpleSample: square doesn't fit into the clip!\");\n       }\n    }\n\n    SimpleSample::~SimpleSample() {}\n\n    PVideoFrame __stdcall SimpleSample::GetFrame(int n, IScriptEnvironment* env) {\n\n       PVideoFrame src = child->GetFrame(n, env);\n       env->MakeWritable(&src);\n\n       unsigned char* srcp = src->GetWritePtr();\n       int src_pitch = src->GetPitch();\n       int src_width = src->GetRowSize();\n       int src_height = src->GetHeight();\n\n       int w, h, woffset;\n\n       if (vi.IsRGB24()) {\n          srcp = srcp + (src_height/2 - SquareSize/2) * src_pitch;\n\n          woffset = src_width/2 - 3*SquareSize/2;\n\n          for (h=0; h<SquareSize; h++) {\n             for (w=0; w<3*SquareSize; w+=3) {\n                *(srcp + woffset + w) = 255;\n                *(srcp + woffset + w + 1) = 255;\n                *(srcp + woffset + w + 2) = 255;\n             }\n             srcp += src_pitch;\n          }\n       }\n       if (vi.IsRGB32()) {\n          srcp = srcp + (src_height/2 - SquareSize/2) * src_pitch;\n\n          woffset = src_width/2 - 4*SquareSize/2;\n\n          for (h=0; h<SquareSize; h++) {\n             for (w=0; w<4*SquareSize; w+=4) {\n                *(srcp + woffset + w) = 255;\n                *(srcp + woffset + w + 1) = 255;\n                *(srcp + woffset + w + 2) = 255;\n             }\n             srcp += src_pitch;\n          }\n       }\n    /*\n       if (vi.IsRGB32()) { // variant 1 - processing a pixel at once\n          srcp = srcp + (src_height/2 - SquareSize/2) * src_pitch;\n\n          woffset = src_width/8 - SquareSize/2;\n\n          for (h=0; h<SquareSize; h++) {\n             for (w=0; w<SquareSize; w++) {\n                *((unsigned int *)srcp + woffset + w) = 0x00FFFFFF;\n             }\n             srcp += src_pitch;\n          }\n       }\n    */\n    /*\n       if (vi.IsRGB32()) { // variant 2 - processing a pixel at once\n          unsigned int* srcp = (unsigned int*)src->GetWritePtr();\n\n          srcp = srcp + (src_height/2 - SquareSize/2) * src_pitch/4;\n\n          woffset = src_width/8 - SquareSize/2;\n\n          for (h=0; h<SquareSize; h++) {\n             for (w=0; w<SquareSize; w++) {\n                srcp[woffset + w] = 0x00FFFFFF;\n             }\n             srcp += src_pitch/4;\n          }\n       }\n    */\n       if (vi.IsYUY2()) {\n          srcp = srcp + (src_height/2 - SquareSize/2) * src_pitch;\n\n          woffset = src_width/8 - SquareSize/4;\n\n          for (h=0; h<SquareSize; h++) {\n             for (w=0; w<SquareSize/2; w++) {\n                *((unsigned int *)srcp + woffset + w) = 0x80EB80EB;\n             }\n             srcp += src_pitch;\n          }\n       }\n       if (vi.IsPlanar() && vi.IsYUV()) {\n\n          int planes[] = {PLANAR_Y, PLANAR_U, PLANAR_V};\n          int square_value[] = {235, 128, 128};\n          int p;\n          int width_sub, height_sub;\n\n          for (p=0; p<3; p++) {\n             srcp = src->GetWritePtr(planes[p]);\n             src_pitch = src->GetPitch(planes[p]);\n             src_width = src->GetRowSize(planes[p]);\n             src_height = src->GetHeight(planes[p]);\n             width_sub = vi.GetPlaneWidthSubsampling(planes[p]);\n             height_sub = vi.GetPlaneHeightSubsampling(planes[p]);\n\n             srcp = srcp + (src_height/2 - (SquareSize>>height_sub)/2) * src_pitch;\n\n             woffset = src_width/2 - (SquareSize>>width_sub)/2;\n\n             for (h=0; h<(SquareSize>>height_sub); h++) {\n                for (w=0; w<(SquareSize>>width_sub); w++) {\n                   srcp[woffset + w] = square_value[p];\n                }\n                srcp += src_pitch;\n             }\n          }\n       }\n\n       return src;\n    }\n\n    AVSValue __cdecl Create_SimpleSample(AVSValue args, void* user_data, IScriptEnvironment* env) {\n       return new SimpleSample(args[0].AsClip(),\n                               args[1].AsInt(100),\n                               env);\n    }\n\n    const AVS_Linkage *AVS_linkage = 0;\n\n    extern \"C\" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors) {\n       AVS_linkage = vectors;\n       env->AddFunction(\"SimpleSample\", \"c[size]i\", Create_SimpleSample, 0);\n       return \"SimpleSample plugin\";\n    }\n\n\nCompile this file into a DLL named InvertNeg.dll. See :doc:`compiling instructions <CompilingAvisynthPlugins>`.\nNow create an Avisynth script which looks something like this:\n::\n\n    LoadPlugin(\"d:\\path\\simplesample.dll\")\n    Colorbars().Trim(0,1)\n    ConvertTORGB32()\n    # ConvertTOYV411()\n    SimpleSample(100)\n\n\nLine by line breakdown\n----------------------\n\nHere's a line-by-line breakdown of simplesample.cpp. I won't repeat the\ncomments in the previous example InvertNeg.cpp, so read that first if\nneeded. The declaration of the class is as follows\n::\n\n    class SimpleSample : public GenericVideoFilter {\n       int SquareSize;\n    public:\n       SimpleSample(PClip _child,   int _SquareSize, IScriptEnvironment* env);\n       ~SimpleSample();\n       PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n    };\n\n\nWith respect to our previous example there are two differences. It\ncontains a private data member 'SquareSize' (members are private by\ndefault). Note that this is our parameter variable. These have to be\ndeclared here.\n\nThe member function ~SimpleSample() is the declaration of the\ndestructor. It fulfills the opposite functionality as the constructor.\nIt is automatically called when the filter is destroyed. It is used to\nrelease allocated memory when the filter is destroyed. This is needed\nwhen there is memory allocated in the constructor. This is not the case\nin our filter, so we didn't need to declare it.\n::\n\n    SimpleSample::~SimpleSample() {}\n\nThis is the actual destructor. You can release allocated memory here\nusing the operator delete.\n::\n\n    SimpleSample::SimpleSample(PClip _child, int _SquareSize, IScriptEnvironment* env) :\n       GenericVideoFilter(_child), SquareSize(_SquareSize) {\n       if (vi.width<SquareSize || vi.height<SquareSize) {\n          env->ThrowError(\"SimpleSample: square doesn't fit into the clip!\");\n       }\n    }\n\n\nThis is the constructor. It initializes the value of SquareSize with\nthe parameter that is passed to it (which is called _SquareSize here).\nIt also checks whether the square which will be drawn fits in the\nframe, otherwise it will return an error.\n::\n\n       unsigned char* srcp = src->GetWritePtr();\n       int src_pitch = src->GetPitch();\n       int src_width = src->GetRowSize();\n       int src_height = src->GetHeight();\n\n\nThe default value of plane is PLANAR_Y (= 0) for the functions\nGetReadPtr, GetWritePtr, GetPitch, GetRowSize and GetHeight. For planar\nformats this is the luma plane and for interleaved formats this is the\nwhole frame.\n::\n\n       if (vi.IsRGB24()) {\n\n\nWhen the clip has color format RGB24 the code path is taken. For RGB24\neach pixel is represented by three bytes, blue, green and red (in that\norder). RGB is up side down, so srcp[0] will be the bottom-left pixel.\n::\n\n          srcp = srcp + (src_height/2 - SquareSize/2) * src_pitch;\n\n\nThe pointer is moved to the lower line of the square that will be\ndrawn. Remember that src_height is the height in pixels.\n::\n\n          woffset = src_width/2 - 3*SquareSize/2;\n\nThe offset is calculated of the left most byte of the square that will\nbe drawn. Remember that src_width is the width in bytes. Since\nSquareSize is specified in pixels, the corresponding number of bytes is\n3*SquareSize.\n::\n\n          for (h=0; h<SquareSize; h++) {         // Loop from bottom line to top line.\n             for (w=0; w<3*SquareSize; w+=3) {   // Loop from left side of the image to the right side 1 pixel (3 bytes) at a time\n                *(srcp + woffset + w) = 255;     // this is the same as srcp[woffset+w]=255;\n                *(srcp + woffset + w + 1) = 255; // this is the same as srcp[woffset+w+1]=255;\n                *(srcp + woffset + w + 2) = 255; // this is the same as srcp[woffset+w+2]=255;\n             }\n\n             srcp += src_pitch;\n          }\n       }\n\n\nHere the white square is drawn. Each color component is set to 255.\n\nFor RGB32 the following code path is taken\n::\n\n       if (vi.IsRGB32()) {\n          srcp = srcp + (src_height/2 - SquareSize/2) * src_pitch;\n\n          woffset = src_width/2 - 4*SquareSize/2;\n\n          for (h=0; h<SquareSize; h++) {\n             for (w=0; w<4*SquareSize; w+=4) {\n                *(srcp + woffset + w) = 255;\n                *(srcp + woffset + w + 1) = 255;\n                *(srcp + woffset + w + 2) = 255;\n             }\n             srcp += src_pitch;\n          }\n       }\n\n\nIt's the same as for RGB24, except a pixel is represented by four\nbytes, blue, green, red and alpha (in that order). Since SquareSize is\nspecified in pixels, the corresponding number of bytes is ``4*SquareSize``.\nThe fourth color component, the alpha channel, ``*(srcp + woffset + w + 3)``\nis left untouched.\n\nIt is possible to speed the code above up a bit since you can deal with\nwhole 32bit variables at a time. This can be done in several ways:\n::\n\n       if (vi.IsRGB32()) { // variant 1 - processing a pixel at once\n          srcp = srcp + (src_height/2 - SquareSize/2) * src_pitch;\n\n          woffset = src_width/8 - SquareSize/2;   // src_width/2 bytes equals src_width/8 pixels\n\n          for (h=0; h<SquareSize; h++) {\n             for (w=0; w<SquareSize; w++) {\n                *((unsigned int *)srcp + woffset + w) = 0x00FFFFFF;\n             }\n             srcp += src_pitch;\n          }\n       }\n\n\nYou need to cast srcp as unsigned int (instead of unsigned char).\nunsigned int is 4 bytes or 32 bits (it runs from 0 to 2^32-1), which is\nexactly what we need for one pixel. The casting is done in this line\n::\n\n                *((unsigned int *)srcp + woffset + w) = 0x00FFFFFF;\n\n\nThe value of a white pixel is 0x00FFFFFF (where the alpha pixel is set\nto black). When writing several bytes at once, you need to write the\nright one first and the left one last.\n\nIt is also possible to declare srcp as unsigned int when defining it,\nbut you have to take it into account in the rest of the code:\n::\n\n       if (vi.IsRGB32()) { // variant 2 - processing a pixel at once\n          unsigned int* srcp = (unsigned int*)src->GetWritePtr();\n\n          srcp = srcp + (src_height/2 - SquareSize/2) * src_pitch/4;\n\n          woffset = src_width/8 - SquareSize/2;\n\n          for (h=0; h<SquareSize; h++) {\n             for (w=0; w<SquareSize; w++) {\n                srcp[woffset + w] = 0x00FFFFFF;\n             }\n             srcp += src_pitch/4;\n          }\n       }\n\n\nRemember that src_pitch is given in bytes and it is equal to\nsrc_pitch/4 pixels.\n\nFor YUY2, each 4 byte sequence represents 2 pixels, (Y1, U, Y2 and then\nV). So we can write two pixels at once by recasting again.\n::\n\n       if (vi.IsYUY2()) {\n          srcp = srcp + (src_height/2 - SquareSize/2) * src_pitch;\n\n          woffset = src_width/8 - SquareSize/4;\n\n          for (h=0; h<SquareSize; h++) {\n             for (w=0; w<SquareSize/2; w++) {   // we are writing two pixels at once\n                *((unsigned int *)srcp + woffset + w) = 0x80EB80EB;   // VY2UY1; Y1=Y2=0xEB=235, U=V=0x80=128\n             }\n             srcp += src_pitch;\n          }\n       }\n\n\nAt last we move on to the YUV planar formats. Since we are processing\nthe color components independently we can loop over the planes.\n::\n\n       if (vi.IsPlanar() && vi.IsYUV()) {\n\nAll planar YUV formats in the 2.6 api are: YV24, YV16, YV12, YV411 and Y8.\n::\n\n          int planes[] = {PLANAR_Y, PLANAR_U, PLANAR_V};\n          int square_value[] = {235, 128, 128};\n          int p;\n          int width_sub, height_sub;\n\n          for (p=0; p<3; p++) {\n             srcp = src->GetWritePtr(planes[p]);\n             src_pitch = src->GetPitch(planes[p]);\n             src_width = src->GetRowSize(planes[p]);\n             src_height = src->GetHeight(planes[p]);\n             width_sub = vi.GetPlaneWidthSubsampling(planes[p]);\n             height_sub = vi.GetPlaneHeightSubsampling(planes[p]);\n\n\nSince the planes have unequal width (measured in bytes; same for\nheight) we will need their subsampling. The functions\n:doc:`GetPlaneWidthSubsampling <VideoInfo>` and :doc:`GetPlaneHeightSubsampling <VideoInfo>` are new in\nthe 2.6 api. They return the horizontal and vertical subsampling of the\nplane compared to the luma plane. The subsampling of the formats is:\n\n+--------------+------------------------------------+-------------------------------------+\n| color format | GetPlaneWidthSubsampling(PLANAR_U) | GetPlaneHeightSubsampling(PLANAR_U) |\n+==============+====================================+=====================================+\n| YV24         | 0                                  | 0                                   |\n+--------------+------------------------------------+-------------------------------------+\n| YV16         | 1                                  | 0                                   |\n+--------------+------------------------------------+-------------------------------------+\n| YV12         | 1                                  | 1                                   |\n+--------------+------------------------------------+-------------------------------------+\n| YV411        | 2                                  | 1                                   |\n+--------------+------------------------------------+-------------------------------------+\n| Y8           | 0 ?                                | 0 ?                                 |\n+--------------+------------------------------------+-------------------------------------+\n\n\nThe chroma planes PLANAR_U and PLANAR_V have the same subsampling. Also\nGetPlaneWidthSubsampling(PLANAR_Y) =\nGetPlaneHeightSubsampling(PLANAR_Y) = 0 since PLANAR_Y is not\nsubsampled.\n::\n\n             srcp = srcp + (src_height/2 - (SquareSize>>height_sub)/2) * src_pitch;\n\nNote SquareSize is specified in pixels and src_height the height of the\nsamples of plane p. Let's look at YV12 for example. For the luma plane\nwe have SquareSize>>0 = SquareSize since there is no subsampling and\nfor the chroma planes we have SquareSize>>1 = SquareSize/2 since there\nare twice as many luma samples as chroma samples horizontally.\n::\n\n             woffset = src_width/2 - (SquareSize>>width_sub)/2;\n\nThe vertical subsampling is taken into account again.\n::\n\n             for (h=0; h<(SquareSize>>height_sub); h++) {\n                for (w=0; w<(SquareSize>>width_sub); w++) {\n                   srcp[woffset + w] = square_value[p];\n                }\n                srcp += src_pitch;\n             }\n          }\n       }\n\n\nHere the white square is drawn. The luma pixels will get the value\nsquare_value[PLANAR_Y] = 235, and the chroma pixels will get the value\nsquare_value[PLANAR_U] = 128 (idem for PLANAR_V).\n::\n\n    AVSValue __cdecl Create_SimpleSample(AVSValue args, void* user_data, IScriptEnvironment* env) {\n       return new SimpleSample(args[0].AsClip(),\n                               args[1].AsInt(100),\n                               env);\n    }\n\n\nargs[0], args[1], ... are the arguments of the filter. Here there are\ntwo arguments. The first one is of type clip and the second one of type\nint (with default value 100). You can pre-process or post-process your\nvariables (and clips) here too. See DirectShowSource for some examples.\n::\n\n    extern \"C\" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors) {\n       AVS_linkage = vectors;\n       env->AddFunction(\"SimpleSample\", \"c[size]i\", Create_SimpleSample, 0);\n       return \"SimpleSample plugin\";\n    }\n\n\nThe :ref:`AddFunction <cplusplus_addfunction>` has the following parameters:\n::\n\n    AddFunction(Filtername, Arguments, Function to call, 0);\n\n\n*Arguments* is a string that defines the types and optional names of the\narguments for your filter. The possible types are:\n\n+---------------------------------+\n| Argument type specifier strings |\n+=================================+\n+ c - clip                        +\n+---------------------------------+\n+ i - integer                     +\n+---------------------------------+\n+ f - float                       +\n+---------------------------------+\n+ s - string                      +\n+---------------------------------+\n+ b - boolean                     +\n+---------------------------------+\n+ . - Any type (dot)              +\n+---------------------------------+\n\n+-----------------------------------+\n+ Array Specifiers                  +\n+===================================+\n+ i* - Integer Array, zero or more  +\n+-----------------------------------+\n+ i+ - Integer Array, one or more   +\n+-----------------------------------+\n+ .* - Any type Array, zero or more +\n+-----------------------------------+\n+ .+ - Any type Array, one or more  +\n+-----------------------------------+\n\n(have a look at StackVertical and SelectEvery for example as to how access such arrays)\n\nThe text inside the [ ] lets you used named parameters in your script. Thus\n::\n\n    clip = ...\n    SimpleSample(clip, size=100)\n\n\nbut\n::\n\n    clip = ...\n    SimpleSample(clip, 100)\n\n\nworks as well. See :doc:`InvertNeg` for more information.\n\n____\n\nBack to :doc:`FilterSDK`\n\n$Date: 2015/09/14 20:23:59 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/SimpleSampleClass.rst",
    "content": "\n`SimpleSampleClass`_\n=====================\n\n\n:doc:`SimpleSample <SimpleSample>` with an explanation of the used classes and function calls:\n\n::\n\n    /*\n        SimpleSample plugin for Avisynth -- a simple sample\n\n        Copyright (C) 2002-2003 Simon Walters, All Rights Reserved\n\n        This program is free software; you can redistribute it and/or\n    modify\n        it under the terms of the GNU General Public License as published\n    by\n        the Free Software Foundation.\n\n        This program is distributed in the hope that it will be useful,\n        but WITHOUT ANY WARRANTY; without even the implied warranty of\n        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n        GNU General Public License for more details.\n\n        You should have received a copy of the GNU General Public License\n        along with this program; if not, write to the Free Software\n        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n\n        2005 - trevlac added comments.\n    */\n\n    //=============== SECTION #1: Includes and Prototypes =================\n\n    //following two includes are needed\n    #include \"windows.h\"\n    #include \"avisynth.h\"\n\n\n\n    //------------ Prototype the functions, ect. So we can call/use them later.\n\n    //--------------------------------------------------------------\n    // Prototype AvisynthPluginInit2()\n    //\n    // Avisynth calls this when you do LoadPlugin(\"c:\\myplugin.dll\").\n    // All the fancy stuff on the front is for the external call to your dll.\n    // Basically you use this to add your function to Avisynth.\n    //\n    // Parms:\n    //          env - This is a pointer back to Avisynth so you can setup your filter.\n    //                          It's type is a class defined in avisynth.h.  Basically it lets\n    //                          you call functions to set things up.\n    //\n    // Returns - Looks like it returns a string.  Did you know?\n    //\n    //---------------------------------------------------------------\n\n    extern \"C\" __declspec(dllexport) const char* __stdcall\n    AvisynthPluginInit2(IScriptEnvironment* env);\n\n\n\n\n    //---------------------------------------------\n    // Prototype Create_SimpleSample()\n    //\n    // Avisynth calls this when a script runs your function.\n    //\n    // Parms:\n    //          args - contains all the arguments passed to the function by the script\n    //\n    //          user_data - can be used to pass in a chunk of filter info.  This data pointer\n    //                                  comes from you when you setup your function in AvisynthPluginInit2()\n    //\n    //          env - Pointer back to Avisynth so you can call it's functions.\n    //\n    // Return - AVSValue can take on many types.  It's not quite a void pointer.  It's a class\n    //                  defined in the avisynth.h file, but it lets you return anything a script might need.\n    //                  After all, this is where you get called and return to a script.\n    //\n    //---------------------------------------------------------------\n\n    AVSValue __cdecl Create_SimpleSample(AVSValue args, void* user_data,\n    IScriptEnvironment* env);\n\n\n\n\n    //---------------------------------------------\n    // Prototype SimpleSample Class\n    //\n    // This is your class.  If you don't know classes, think of it as\n    // a structure with function pointers.  There are only two functions\n    // here; SimpleSample() (the constructor) and GetFrame().  This is the\n    // Prototype so we can use it later.  The details of the functions are not\n    // here.  Just enough info to create the class structure.\n    //\n    // SimpleSample is based on the GenericVideoFilter class which is defined in\n    // the avisynth.h file.  GenericVideoFilter is based on another class.  This just\n    // means your class 'structure' already comes with a few function pointers.\n    // you can then replace the ones you want with your own functionality.  If you\n    // don't care about the other ones, you get the built in functionality ... which\n    // probably does things like return zero.\n    //\n    // At the risk of repeating ... we really only care about two functions.\n    // SimpleSample() and GetFrame()\n    //\n    //---------------------------------------------------------------\n\n    class SimpleSample : public GenericVideoFilter {\n    public:\n        SimpleSample(PClip _child);\n        PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n    };\n\n\n\n\n\n    //=============== SECTION #2:  The functions Avisynth Calls =================\n\n    //--------------------------------------------------------------\n    // AvisynthPluginInit2()\n    //\n    // Avisynth calls this when you do LoadPlugin(\"c:\\myplugin.dll\").\n    // All the fancy stuff on the front is for the external call to your dll.\n    // Basically you use this to add your function to Avisynth.\n    //\n    // Parms:\n    //          env - This is a pointer back to Avisynth so you can setup your filter.\n    //                          It's type is a class defined in avisynth.h.  Basically it lets\n    //                          you call functions to set things up.\n    //\n    // Returns - Looks like it returns a string.  Did you know?\n    //\n    //---------------------------------------------------------------\n    extern \"C\" __declspec(dllexport) const char* __stdcall\n    AvisynthPluginInit2(IScriptEnvironment* env) {\n\n        //--- We use the pointer back to Avisynth to call its 'AddFunction' function.\n        //--- Add just one function which a script will call as \"SimpleSample\",\n\n        //--- takes a single argument which is a video [c]lip\n        //--- There are more types: along with 'i'nt and 's'tring you can specify 'b'ool, 'f'loat, and 'c'lip\n        //--- Avisynth checks these types and complains to the user if they are not using the right kind.\n\n        //--- Here, Avisynth will call the function in this dll called Create_SimpleSample\n        //--- when it 1st encounters SimpleSample in a script.\n\n        //--- That last 0 is where you could pass a pointer to a bunch of data.  The pointer\n        //--- would be passed back to you when Avisynth calls Create_SimpleSample.\n\n        env->AddFunction(\"SimpleSample\", \"c\", Create_SimpleSample, 0);\n\n\n        //--- Did you know LoadPlugin() returns a string?  Do you think you favorite plugins\n        //--- pass back secret messages?  Who checks ?\n\n\n        return \"`SimpleSample' SimpleSample plugin\";\n    }\n\n\n\n    //---------------------------------------------\n    // Create_SimpleSample()\n    //\n    // Avisynth calls this when a script runs your function.\n    //\n    // Parms:\n    //          args - contains all the arguments passed to the function by the script\n    //\n    //          user_data - can be used to pass in a chunk of filter info.  This data pointer\n    //                                  comes from you when you setup your function in AvisynthPluginInit2()\n    //\n    //          env - Pointer back to avisynth so you can call it's functions.\n    //\n    // Return - AVSValue can take on many types.  It's not quite a void pointer.  It's a class\n    //                  defined in the avisynth.h file, but it lets you return anything a script might need.\n    //                  After all, this is where you get called and return to a script.\n    //\n    //---------------------------------------------------------------\n    AVSValue __cdecl Create_SimpleSample(AVSValue args, void* user_data,\n    IScriptEnvironment* env) {\n\n        //--- As stated ... this is where we get to if someone puts our function in a script.\n        //--- Here we call our class constructor and pass it the first arg as a clip.\n        //--- That effectively allocates space in memory for our class structure ... which is a\n        //--- glorified structure with a bunch of function pointers.  :)\n\n        //--- Note that a constructor function does not return a type ... but we are returning a pointer\n        //--- to our newly allocated class structure.\n\n        return new SimpleSample(args[0].AsClip());\n    }\n\n\n\n\n\n\n    //---------------------------------------------\n    // SimpleSample::SimpleSample()\n    //\n    // This the class constructor and what gets called when we do 'new SimpleSample()' just above.\n    //\n    // It's sorta interesting that our function does nothing.  {}  That is because we are based\n    // on the GenericVideoFilter class structure, which is based on another class structure.\n    // Those guys allocate some space for a few important variables like vi and child.  So if\n    // you wonder where the heck these came from ... we got them for free from GenericVideoFilter.\n    //\n    // Parms:\n    //          _child - That's that video clip we got passed from above. We effectively call\n    //                          GenericVideoFilter and pass it that same clip.\n    //\n    // Return - not supposed to. We are a new class structure.\n    //\n    //---------------------------------------------------------------\n\n    SimpleSample::SimpleSample(PClip _child) : GenericVideoFilter(_child)\n    {}\n\n\n\n    //---------------------------------------------\n    // SimpleSample::GetFrame()\n    //\n    // What we've all been waiting for!  All the frames come here.  The other junk just sets things up.\n    // Avisynth has a reference to our class structure (aka we are in the filter chain)\n    // Our class is based on a GenericVideoFilter, which has a dummy GetFrame() function.\n    // We defined our own GetFrame() so Avisynth calls here.\n    //\n    // Parms:\n    //          n - The frame we are supposed to return.\n    //\n    //          env - Pointer back to avisynth so you can call it's functions.\n    //\n    // Return - PVideoFrame - This is a pointer to a class structure that effectively holds the\n    //                  frame you were messing with.\n    //\n    //---------------------------------------------------------------\n\n    PVideoFrame __stdcall SimpleSample::GetFrame(int n,\n    IScriptEnvironment* env) {\n\n\n        //--- That mysterious vi is there from GenericVideoFilter.\n        //--- It is a structure of info about the frame which is filled by Avisynth.\n        //--- If you use VC++, add avisynth.h to your project and look in classView for the details.\n        //--- Below ... we report an error back to Avisynth ... we only do YUY2 data.\n\n        if (vi.IsYV12()) // is input not YUY2\n                env->ThrowError(\"SimpleSample: input to filter must be in YUY2\");\n\n\n        //--- That mysterious child is there from GenericVideoFilter.\n        //--- It is a clip variable which is filled by Avisynth.\n        //--- We need to produce frame n, so we get that from the child clip.\n        //--- That's our input frame src.\n        //--- We need a place to build our output frame before we pass it back.\n        //--- Avisynth has a handy built in method.  Just call it and tell it what type of frame\n        //--- we want ... and we get one we can muck with.  vi defines the input type.  If we want another\n        //--- type like RGB at 1/2 the size, we make a different videoInfo structure and\n        //--- use that instead to create our output.\n\n        PVideoFrame src = child->GetFrame(n, env);\n        PVideoFrame dst = env->NewVideoFrame(vi);\n\n\n        //--- Gotta do this to read and write from/to the source and destination.  src and dst are classes.\n        //--- We can't just change their data.  We need to call their functions to change them.  The ones\n        //--- below give us pointers to their main pixel data.\n\n        const unsigned char* srcp = src->GetReadPtr();\n        unsigned char* dstp = dst->GetWritePtr();\n\n\n        //--- We want to know the width (in bytes) and height (in pixels) of the source and dest frames so\n        //--- we can loop thru their pixels.  Pitch is the number of bytes from the start of one\n        //--- image row to the start of the next.  This may be different than width because there\n        //--- may be space at the end of each row that pads for better memory alignment.\n\n        const int dst_pitch = dst->GetPitch();\n        const int dst_width = dst->GetRowSize();\n        const int dst_height = dst->GetHeight();\n        const int src_pitch = src->GetPitch();\n        const int src_width = src->GetRowSize();\n        const int src_height = src->GetHeight();\n\n\n\n        //--- FINALLY !!!! --------\n        //--- We loop through the bytes and copy from source to destination.\n\n        for (int h=0; h < src_height;h++) {\n                for (int w = 0; w < src_width; w++) {\n\n                        //--- Put your code here to muck with the frame\n                        *(dstp + w) = *(srcp + w);\n                }\n\n                //--- This moves us to the next line\n                srcp = srcp + src_pitch;\n                dstp = dstp + dst_pitch;\n        }\n\n        return dst; //-- return the frame\n\n\nBack to :doc:`SimpleSample <SimpleSample>`\n\n$Date: 2025-02-24 21:02:41-05:00 $\n\n.. _SimpleSampleClass : http://avisynth.nl/index.php/Filter_SDK/SimpleSample\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/TwoFiveFastInvert.rst",
    "content": "\n`TwoFiveFastInvert`_\n====================\n\nPlease not that the code below may not actually be faster than the\n:doc:`TwoFiveInvert <TwoFiveInvert>` sample, because the compiler doesn't handle 64 bit integers\nvery well. However this is not the case when using :doc:`MMX <MMX>` or :doc:`IntegerSSE <IntegerSSE>`.\n::\n\n    #include \"avisynth.h\"\n\n    class Invert : public GenericVideoFilter {\n\n        public:\n            Invert(PClip _child) : GenericVideoFilter(_child) {}\n            PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n    };\n\n    PVideoFrame __stdcall Invert::GetFrame(int n, IScriptEnvironment* env) {\n\n    PVideoFrame src = child->GetFrame(n, env);\n\n    PVideoFrame dst = env->NewVideoFrame(vi);\n\n    const __int64* srcpY = (__int64*)src->GetReadPtr(PLANAR_Y);\n\n    const __int64* srcpV = (__int64*)src->GetReadPtr(PLANAR_V);\n\n    const __int64* srcpU = (__int64*)src->GetReadPtr(PLANAR_U);\n\n    __int64* dstpY = (__int64*)dst->GetWritePtr(PLANAR_Y);\n\n    __int64* dstpV = (__int64*)dst->GetWritePtr(PLANAR_V);\n\n    __int64* dstpU = (__int64*)dst->GetWritePtr(PLANAR_U);\n\n    const int src_pitchY = src->GetPitch(PLANAR_Y)/8; // 8 bytes per loop\n\n    const int src_pitchUV = src->GetPitch(PLANAR_V)/8;\n\n    const int dst_pitchY = dst->GetPitch(PLANAR_Y)/8;\n\n    const int dst_pitchUV = dst->GetPitch(PLANAR_U)/8;\n\n    const int row_sizeY = dst->GetRowSize(PLANAR_Y_ALIGNED)/8; // Mod 16 size\n\n    const int row_sizeUV = dst->GetRowSize(PLANAR_U_ALIGNED)/8; // Mod 8 size\n\n    const int heightY = dst->GetHeight(PLANAR_Y);\n\n    const int heightUV = dst->GetHeight(PLANAR_U);\n\n    __int64 inv = 0xffffffffffffffff;\n\n    for (int y = 0; y < heightY; y++) {\n\n        for (int x = 0; x < row_sizeY; x++)\n            dstpY[x] = srcpY[x] ^ inv;\n            srcpY += src_pitchY;\n            dstpY += dst_pitchY;\n    }\n\n    for (int y = 0; y < heightUV; y++) {\n\n        for (int x = 0; x < row_sizeUV; x++) {\n                dstpU[x] = srcpU[x] ^ inv;\n                dstpV[x] = srcpV[x] ^ inv;\n        }\n\n        srcpU += src_pitchUV;\n        dstpU += dst_pitchUV;\n        srcpV += src_pitchUV;\n        dstpV += dst_pitchUV;\n    }\n    return dst;\n    }\n\n    AVSValue __cdecl Create_Invert(AVSValue args, void* user_data, IScriptEnvironment* env) {\n        return new Invert(args[0].AsClip());\n    }\n\n    extern \"C\" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env) {\n        env->AddFunction(\"Invert\", \"c\", Create_Invert, 0);  return \"`Invert' sample plugin\";\n    }\n\nBack to :doc:`AviSynthTwoFiveSDK <AviSynthTwoFiveSDK>`\n\n$Date: 2025-02-24 21:10:18-05:00 $\n\n.. _TwoFiveFastInvert: http://avisynth.nl/index.php/Filter_SDK/Two-Five_fast_Invert\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/TwoFiveInvert.rst",
    "content": "\n`TwoFiveInvert`_\n================\n\n::\n\n    #include \"avisynth.h\"\n\n    class Invert : public GenericVideoFilter {\n\n        public:\n            Invert(PClip _child) : GenericVideoFilter(_child) {}\n            PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n    };\n\n    PVideoFrame __stdcall Invert::GetFrame(int n, IScriptEnvironment* env) {\n\n    PVideoFrame src = child->GetFrame(n, env);\n\n    PVideoFrame dst = env->NewVideoFrame(vi);\n\n    const unsigned char* srcpY = src->GetReadPtr(PLANAR_Y);\n\n    const unsigned char* srcpV = src->GetReadPtr(PLANAR_V);\n\n    const unsigned char* srcpU = src->GetReadPtr(PLANAR_U);\n\n    unsigned char* dstpY = dst->GetWritePtr(PLANAR_Y);\n\n    unsigned char* dstpV = dst->GetWritePtr(PLANAR_V);\n\n    unsigned char* dstpU = dst->GetWritePtr(PLANAR_U);\n\n    const int src_pitchY = src->GetPitch(PLANAR_Y);\n\n    const int src_pitchUV = src->GetPitch(PLANAR_V);\n\n    const int dst_pitchY = dst->GetPitch(PLANAR_Y);\n\n    const int dst_pitchUV = dst->GetPitch(PLANAR_U);\n\n    const int row_sizeY = dst->GetRowSize(PLANAR_Y); // Could also be PLANAR_Y_ALIGNED which would return a mod16 rowsize\n\n    const int row_sizeUV = dst->GetRowSize(PLANAR_U); // Could also be PLANAR_U_ALIGNED which would return a mod8 rowsize\n\n    const int heightY = dst->GetHeight(PLANAR_Y);\n\n    const int heightUV = dst->GetHeight(PLANAR_U);\n\n    for (int y = 0; y < heightY; y++) {\n        for (int x = 0; x < row_sizeY; x++)\n            dstpY[x] = srcpY[x] ^ 255;\n            srcpY += src_pitchY;\n            dstpY += dst_pitchY;\n    }\n\n    for (int y = 0; y < heightUV; y++) {\n        for (int x = 0; x < row_sizeUV; x++) {\n            dstpU[x] = srcpU[x] ^ 255;\n            dstpV[x] = srcpV[x] ^ 255;\n        }\n\n        srcpU += src_pitchUV;\n        dstpU += dst_pitchUV;\n        srcpV += src_pitchUV;\n        dstpV += dst_pitchUV;\n    }\n\n    return dst;\n\n    }\n\n    AVSValue __cdecl Create_Invert(AVSValue args, void* user_data, IScriptEnvironment* env) {\n        return new Invert(args[0].AsClip());\n    }\n\n    extern \"C\" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env) {\n        env->AddFunction(\"Invert\", \"c\", Create_Invert, 0);\n        return \"`Invert' sample plugin\";\n    }\n\nBack to :doc:`AviSynthTwoFiveSDK <AviSynthTwoFiveSDK>`\n\n$Date: 2025-02-24 20:59:36-05:00 $\n\n.. _TwoFiveInvert: http://avisynth.nl/index.php/Filter_SDK/Two-Five_Invert\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/VideoInfo.rst",
    "content": "\nVideoInfo\n=========\n\nThe VideoInfo structure holds global information about a clip (i.e.\ninformation that does not depend on the frame number). The GetVideoInfo\nmethod in IClip returns this structure. Below is a description of it\n(for AVISYNTH_INTERFACE_VERSION=6 and above).\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\nProperties and constants\n------------------------\n\n**General properties:**\n::\n\n    int width, height; // width=0 means no video\n    unsigned fps_numerator, fps_denominator;\n    int num_frames; // max. num_frames = 2,147,483,647 (signed int32)\n    int audio_samples_per_second; // audio_samples_per_second=0 means no audio\n    int sample_type; // samples types are defined in avisynth.h\n    uint64_t num_audio_samples;\n    int nchannels;\n\n\n**Colorspace properties and constants:**\n::\n\n    int pixel_type;\n    \n    // Colorspace properties.\n    /*\n      Planar match mask  1111.1000.0000.0111.0000.0111.0000.0111\n      Planar signature   10xx.1000.0000.00xx.0000.00xx.00xx.00xx ?\n      Planar signature   10xx.1000.0000.0xxx.0000.00xx.000x.x0xx ? *new\n      Planar filter mask 1111.1111.1111.1111.1111.1111.1110.0111 (typo from old header fixed)\n      \n      pixel_type mapping\n      ==================\n      pixel_type bit-map PIYB.Z000.0???.0SSS.0000.0???.????.????\n              planar YUV            CCC            HHH.000u.vWWW\n           planar RGB(A)            CCC                       AR\n               nonplanar            CCC            000.00wx xyAR\n      Legend\n      ======\n      Planar YUV:\n        Code Bits Remark\n        W    0-2  Planar Width Subsampling bits\n                  Use (X+1) & 3 for GetPlaneWidthSubsampling\n                    000 => 1        YV12, YV16, YUV420, YUV422\n                    001 => 2        YV411, YUV9\n                    010 => reserved\n                    011 => 0        YV24, YUV444, RGBP\n                    1xx => reserved\n        v    3    VPlaneFirst YV12, YV16, YV24, YV411, YUV9\n        u    4    UPlaneFirst I420\n        H    7-9  Planar Height Subsampling bits\n                  Use ((X>>8)+1) & 3 for GetPlaneHeightSubsampling\n                    000 => 1        YV12, YUV420\n                    001 => 2        YUV9\n                    010 => reserved\n                    011 => 0        YV16, YV24, YV411, YUV422, YUV444, RGBP\n                    1xx => reserved\n      \n      Planar RGB\n       Code Bits Remark\n         R   0   BGR,  (with SSS bits for 8/16 bit/sample or float)\n         A   1   BGRA, (with SSS bits for 8/16 bit/sample or float)\n      \n      \n      Not Planar, Interleaved (I flag)\n      Code Bits Remark\n        R   0   BGR24, and BGRx in future (with SSS bits for 8/16 bit/sample or float)\n        A   1   BGR32, and BGRAx in future (with SSS bits for 8/16 bit/sample or float)\n        y   2   YUY2\n        x   3-4 reserved\n        w   5   Raw32\n      \n      General\n      Code Bits Remark\n        S 16-18 Sample resolution bits\n                000 => 8\n                001 => 16\n                010 => 32 (float)\n                011,100 => reserved\n                101 => 10 bits\n                110 => 12 bits\n                111 => 14 bits\n      for packed RGB(A): only 8 and 16 bits are valid\n      \n      Other YV12 specific (will never be used)\n        C  20-23 Chroma Placement values 0-4; see CS_xxx_CHROMA_PLACEMENT\n      \n      Color family and layout\n                             Packed      Planar               Planar  Planar\n      Code Bits Remark       RGB/RGBA     YUV  YUY2  Y_Grey  RGB/RGBA  YUVA\n        R   0                  1/0         -    0      -       1/0       -\n        A   1                  0/1         -    0      -       0/1       -\n        y   2                   -          -    1      -        0        -\n        Z  27   YUVA            0          0    0      0        1        1\n        B  28   BGR             1          0    0      0        1*       0\n        Y  29   YUV             0          1    1      1        0        0\n        I  30   Interleaved     1          0    1      1        0        0\n        P  31   Planar          0          1    0      1        1        1\n      * Planar RGB plane order: G,B,R(,A)\n    */\n    enum AvsColorFormat {\n      CS_YUVA        = 1 << 27,\n      CS_BGR         = 1 << 28,\n      CS_YUV         = 1 << 29,\n      CS_INTERLEAVED = 1 << 30,\n      CS_PLANAR      = 1 << 31,\n    \n      CS_Shift_Sub_Width   =  0,\n      CS_Shift_Sub_Height  =  8,\n      CS_Shift_Sample_Bits = 16,\n    \n      CS_Sub_Width_Mask    = 7 << CS_Shift_Sub_Width,\n      CS_Sub_Width_1       = 3 << CS_Shift_Sub_Width, // YV24\n      CS_Sub_Width_2       = 0 << CS_Shift_Sub_Width, // YV12, I420, YV16\n      CS_Sub_Width_4       = 1 << CS_Shift_Sub_Width, // YUV9, YV411\n    \n      CS_VPlaneFirst       = 1 << 3, // YV12, YV16, YV24, YV411, YUV9\n      CS_UPlaneFirst       = 1 << 4, // I420\n    \n      CS_Sub_Height_Mask   = 7 << CS_Shift_Sub_Height,\n      CS_Sub_Height_1      = 3 << CS_Shift_Sub_Height, // YV16, YV24, YV411\n      CS_Sub_Height_2      = 0 << CS_Shift_Sub_Height, // YV12, I420\n      CS_Sub_Height_4      = 1 << CS_Shift_Sub_Height, // YUV9\n    \n      CS_Sample_Bits_Mask  = 7 << CS_Shift_Sample_Bits,\n      CS_Sample_Bits_8     = 0 << CS_Shift_Sample_Bits,\n      CS_Sample_Bits_10    = 5 << CS_Shift_Sample_Bits,\n      CS_Sample_Bits_12    = 6 << CS_Shift_Sample_Bits,\n      CS_Sample_Bits_14    = 7 << CS_Shift_Sample_Bits,\n      CS_Sample_Bits_16    = 1 << CS_Shift_Sample_Bits,\n      CS_Sample_Bits_32    = 2 << CS_Shift_Sample_Bits,\n    \n      CS_PLANAR_MASK       = CS_PLANAR | CS_INTERLEAVED | CS_YUV | CS_BGR | CS_YUVA\n                             | CS_Sample_Bits_Mask | CS_Sub_Width_Mask | CS_Sub_Height_Mask,\n      CS_PLANAR_FILTER     = ~(CS_VPlaneFirst | CS_UPlaneFirst),\n    \n      CS_RGB_TYPE  = 1 << 0,\n      CS_RGBA_TYPE = 1 << 1,\n    \n      // Specific colorformats\n      CS_UNKNOWN = 0,\n    \n      CS_BGR24 = CS_RGB_TYPE  | CS_BGR | CS_INTERLEAVED,\n      CS_BGR32 = CS_RGBA_TYPE | CS_BGR | CS_INTERLEAVED,\n      CS_YUY2  = 1 << 2 | CS_YUV | CS_INTERLEAVED,\n      //  CS_YV12  = 1 << 3  Reserved\n      //  CS_I420  = 1 << 4  Reserved\n      CS_RAW32 = 1 << 5 | CS_INTERLEAVED,\n    \n      //  YV12 must be 0xA0000008. v2.5 Baked API will see all new planar as YV12.\n      //  I420 must be 0xA0000010.\n    \n      CS_GENERIC_YUV444  = CS_PLANAR | CS_YUV | CS_VPlaneFirst | CS_Sub_Width_1 | CS_Sub_Height_1,  // 4:4:4 planar\n      CS_GENERIC_YUV422  = CS_PLANAR | CS_YUV | CS_VPlaneFirst | CS_Sub_Width_2 | CS_Sub_Height_1,  // 4:2:2 planar\n      CS_GENERIC_YUV420  = CS_PLANAR | CS_YUV | CS_VPlaneFirst | CS_Sub_Width_2 | CS_Sub_Height_2,  // 4:2:0 planar\n      CS_GENERIC_Y       = CS_PLANAR | CS_INTERLEAVED | CS_YUV,                                     // Y only (4:0:0)\n      CS_GENERIC_RGBP    = CS_PLANAR | CS_BGR | CS_RGB_TYPE,                                        // planar RGB. Though name is RGB but plane order G,B,R\n      CS_GENERIC_RGBAP   = CS_PLANAR | CS_BGR | CS_RGBA_TYPE,                                       // planar RGBA\n      CS_GENERIC_YUVA444 = CS_PLANAR | CS_YUVA | CS_VPlaneFirst | CS_Sub_Width_1 | CS_Sub_Height_1, // 4:4:4:A planar\n      CS_GENERIC_YUVA422 = CS_PLANAR | CS_YUVA | CS_VPlaneFirst | CS_Sub_Width_2 | CS_Sub_Height_1, // 4:2:2:A planar\n      CS_GENERIC_YUVA420 = CS_PLANAR | CS_YUVA | CS_VPlaneFirst | CS_Sub_Width_2 | CS_Sub_Height_2, // 4:2:0:A planar\n    \n      CS_YV24  = CS_GENERIC_YUV444 | CS_Sample_Bits_8,  // YVU 4:4:4 planar\n      CS_YV16  = CS_GENERIC_YUV422 | CS_Sample_Bits_8,  // YVU 4:2:2 planar\n      CS_YV12  = CS_GENERIC_YUV420 | CS_Sample_Bits_8,  // YVU 4:2:0 planar\n      CS_I420  = CS_PLANAR | CS_YUV | CS_Sample_Bits_8 | CS_UPlaneFirst | CS_Sub_Width_2 | CS_Sub_Height_2,  // YUV 4:2:0 planar\n      CS_IYUV  = CS_I420,\n      CS_YUV9  = CS_PLANAR | CS_YUV | CS_Sample_Bits_8 | CS_VPlaneFirst | CS_Sub_Width_4 | CS_Sub_Height_4,  // YUV 4:1:0 planar\n      CS_YV411 = CS_PLANAR | CS_YUV | CS_Sample_Bits_8 | CS_VPlaneFirst | CS_Sub_Width_4 | CS_Sub_Height_1,  // YUV 4:1:1 planar\n    \n      CS_Y8    = CS_GENERIC_Y | CS_Sample_Bits_8,                                                            // Y   4:0:0 planar\n    \n      //-------------------------\n      // AVS16: new planar constants go live! Experimental PF 160613\n      // 10-12-14 bit + planar RGB + BRG48/64 160725\n    \n      CS_YUV444P10 = CS_GENERIC_YUV444 | CS_Sample_Bits_10, // YUV 4:4:4 10bit samples\n      CS_YUV422P10 = CS_GENERIC_YUV422 | CS_Sample_Bits_10, // YUV 4:2:2 10bit samples\n      CS_YUV420P10 = CS_GENERIC_YUV420 | CS_Sample_Bits_10, // YUV 4:2:0 10bit samples\n      CS_Y10 = CS_GENERIC_Y | CS_Sample_Bits_10,            // Y   4:0:0 10bit samples\n    \n      CS_YUV444P12 = CS_GENERIC_YUV444 | CS_Sample_Bits_12, // YUV 4:4:4 12bit samples\n      CS_YUV422P12 = CS_GENERIC_YUV422 | CS_Sample_Bits_12, // YUV 4:2:2 12bit samples\n      CS_YUV420P12 = CS_GENERIC_YUV420 | CS_Sample_Bits_12, // YUV 4:2:0 12bit samples\n      CS_Y12 = CS_GENERIC_Y | CS_Sample_Bits_12,            // Y   4:0:0 12bit samples\n    \n      CS_YUV444P14 = CS_GENERIC_YUV444 | CS_Sample_Bits_14, // YUV 4:4:4 14bit samples\n      CS_YUV422P14 = CS_GENERIC_YUV422 | CS_Sample_Bits_14, // YUV 4:2:2 14bit samples\n      CS_YUV420P14 = CS_GENERIC_YUV420 | CS_Sample_Bits_14, // YUV 4:2:0 14bit samples\n      CS_Y14 = CS_GENERIC_Y | CS_Sample_Bits_14,            // Y   4:0:0 14bit samples\n    \n      CS_YUV444P16 = CS_GENERIC_YUV444 | CS_Sample_Bits_16, // YUV 4:4:4 16bit samples\n      CS_YUV422P16 = CS_GENERIC_YUV422 | CS_Sample_Bits_16, // YUV 4:2:2 16bit samples\n      CS_YUV420P16 = CS_GENERIC_YUV420 | CS_Sample_Bits_16, // YUV 4:2:0 16bit samples\n      CS_Y16 = CS_GENERIC_Y | CS_Sample_Bits_16,            // Y   4:0:0 16bit samples\n    \n      // 32 bit samples (float)\n      CS_YUV444PS = CS_GENERIC_YUV444 | CS_Sample_Bits_32,  // YUV 4:4:4 32bit samples\n      CS_YUV422PS = CS_GENERIC_YUV422 | CS_Sample_Bits_32,  // YUV 4:2:2 32bit samples\n      CS_YUV420PS = CS_GENERIC_YUV420 | CS_Sample_Bits_32,  // YUV 4:2:0 32bit samples\n      CS_Y32 = CS_GENERIC_Y | CS_Sample_Bits_32,            // Y   4:0:0 32bit samples\n    \n      // RGB packed\n      CS_BGR48 = CS_RGB_TYPE  | CS_BGR | CS_INTERLEAVED | CS_Sample_Bits_16, // BGR 3x16 bit\n      CS_BGR64 = CS_RGBA_TYPE | CS_BGR | CS_INTERLEAVED | CS_Sample_Bits_16, // BGR 4x16 bit\n      // no packed 32 bit (float) support for these legacy types\n    \n      // RGB planar\n      CS_RGBP   = CS_GENERIC_RGBP | CS_Sample_Bits_8,  // Planar RGB 8 bit samples\n      CS_RGBP8  = CS_GENERIC_RGBP | CS_Sample_Bits_8,  // Planar RGB 8 bit samples\n      CS_RGBP10 = CS_GENERIC_RGBP | CS_Sample_Bits_10, // Planar RGB 10bit samples\n      CS_RGBP12 = CS_GENERIC_RGBP | CS_Sample_Bits_12, // Planar RGB 12bit samples\n      CS_RGBP14 = CS_GENERIC_RGBP | CS_Sample_Bits_14, // Planar RGB 14bit samples\n      CS_RGBP16 = CS_GENERIC_RGBP | CS_Sample_Bits_16, // Planar RGB 16bit samples\n      CS_RGBPS  = CS_GENERIC_RGBP | CS_Sample_Bits_32, // Planar RGB 32bit samples\n    \n      // RGBA planar\n      CS_RGBAP   = CS_GENERIC_RGBAP | CS_Sample_Bits_8,  // Planar RGBA 8 bit samples\n      CS_RGBAP8  = CS_GENERIC_RGBAP | CS_Sample_Bits_8,  // Planar RGBA 8 bit samples\n      CS_RGBAP10 = CS_GENERIC_RGBAP | CS_Sample_Bits_10, // Planar RGBA 10bit samples\n      CS_RGBAP12 = CS_GENERIC_RGBAP | CS_Sample_Bits_12, // Planar RGBA 12bit samples\n      CS_RGBAP14 = CS_GENERIC_RGBAP | CS_Sample_Bits_14, // Planar RGBA 14bit samples\n      CS_RGBAP16 = CS_GENERIC_RGBAP | CS_Sample_Bits_16, // Planar RGBA 16bit samples\n      CS_RGBAPS  = CS_GENERIC_RGBAP | CS_Sample_Bits_32, // Planar RGBA 32bit samples\n    \n      // Planar YUVA\n      CS_YUVA444    = CS_GENERIC_YUVA444 | CS_Sample_Bits_8,  // YUVA 4:4:4 8bit samples\n      CS_YUVA422    = CS_GENERIC_YUVA422 | CS_Sample_Bits_8,  // YUVA 4:2:2 8bit samples\n      CS_YUVA420    = CS_GENERIC_YUVA420 | CS_Sample_Bits_8,  // YUVA 4:2:0 8bit samples\n    \n      CS_YUVA444P10 = CS_GENERIC_YUVA444 | CS_Sample_Bits_10, // YUVA 4:4:4 10bit samples\n      CS_YUVA422P10 = CS_GENERIC_YUVA422 | CS_Sample_Bits_10, // YUVA 4:2:2 10bit samples\n      CS_YUVA420P10 = CS_GENERIC_YUVA420 | CS_Sample_Bits_10, // YUVA 4:2:0 10bit samples\n    \n      CS_YUVA444P12 = CS_GENERIC_YUVA444 | CS_Sample_Bits_12, // YUVA 4:4:4 12bit samples\n      CS_YUVA422P12 = CS_GENERIC_YUVA422 | CS_Sample_Bits_12, // YUVA 4:2:2 12bit samples\n      CS_YUVA420P12 = CS_GENERIC_YUVA420 | CS_Sample_Bits_12, // YUVA 4:2:0 12bit samples\n    \n      CS_YUVA444P14 = CS_GENERIC_YUVA444 | CS_Sample_Bits_14, // YUVA 4:4:4 14bit samples\n      CS_YUVA422P14 = CS_GENERIC_YUVA422 | CS_Sample_Bits_14, // YUVA 4:2:2 14bit samples\n      CS_YUVA420P14 = CS_GENERIC_YUVA420 | CS_Sample_Bits_14, // YUVA 4:2:0 14bit samples\n    \n      CS_YUVA444P16 = CS_GENERIC_YUVA444 | CS_Sample_Bits_16, // YUVA 4:4:4 16bit samples\n      CS_YUVA422P16 = CS_GENERIC_YUVA422 | CS_Sample_Bits_16, // YUVA 4:2:2 16bit samples\n      CS_YUVA420P16 = CS_GENERIC_YUVA420 | CS_Sample_Bits_16, // YUVA 4:2:0 16bit samples\n    \n      CS_YUVA444PS  = CS_GENERIC_YUVA444 | CS_Sample_Bits_32,  // YUVA 4:4:4 32bit samples\n      CS_YUVA422PS  = CS_GENERIC_YUVA422 | CS_Sample_Bits_32,  // YUVA 4:2:2 32bit samples\n      CS_YUVA420PS  = CS_GENERIC_YUVA420 | CS_Sample_Bits_32,  // YUVA 4:2:0 32bit samples\n    };\n\n\n**Image_type and audio channel layout properties and constants:**\n::\n\n    int image_type;\n\n    enum AvsImageTypeFlags {\n      IT_BFF        = 1 << 0,\n      IT_TFF        = 1 << 1,\n      IT_FIELDBASED = 1 << 2\n      \n      // Audio channel mask support\n      IT_HAS_CHANNELMASK = 1 << 3,\n      // shifted by 4 bits compared to WAVEFORMATEXTENSIBLE dwChannelMask\n      // otherwise same as AvsChannelMask\n      IT_SPEAKER_FRONT_LEFT = 0x1 << 4,\n      IT_SPEAKER_FRONT_RIGHT = 0x2 << 4,\n      IT_SPEAKER_FRONT_CENTER = 0x4 << 4,\n      IT_SPEAKER_LOW_FREQUENCY = 0x8 << 4,\n      IT_SPEAKER_BACK_LEFT = 0x10 << 4,\n      IT_SPEAKER_BACK_RIGHT = 0x20 << 4,\n      IT_SPEAKER_FRONT_LEFT_OF_CENTER = 0x40 << 4,\n      IT_SPEAKER_FRONT_RIGHT_OF_CENTER = 0x80 << 4,\n      IT_SPEAKER_BACK_CENTER = 0x100 << 4,\n      IT_SPEAKER_SIDE_LEFT = 0x200 << 4,\n      IT_SPEAKER_SIDE_RIGHT = 0x400 << 4,\n      IT_SPEAKER_TOP_CENTER = 0x800 << 4,\n      IT_SPEAKER_TOP_FRONT_LEFT = 0x1000 << 4,\n      IT_SPEAKER_TOP_FRONT_CENTER = 0x2000 << 4,\n      IT_SPEAKER_TOP_FRONT_RIGHT = 0x4000 << 4,\n      IT_SPEAKER_TOP_BACK_LEFT = 0x8000 << 4,\n      IT_SPEAKER_TOP_BACK_CENTER = 0x10000 << 4,\n      IT_SPEAKER_TOP_BACK_RIGHT = 0x20000 << 4,\n      // End of officially defined speaker bits\n      // The next one is special, since cannot shift SPEAKER_ALL 0x80000000 further.\n      // Set mask and get mask handles it.\n      IT_SPEAKER_ALL = 0x40000 << 4,\n      // Mask for the defined 18 bits + SPEAKER_ALL\n      IT_SPEAKER_BITS_MASK = (AvsChannelMask::MASK_SPEAKER_DEFINED << 4) | IT_SPEAKER_ALL,\n      IT_NEXT_AVAILABLE = 1 << 23\n    };\n\n\n**Chroma placement constants (bits 20 -> 23):**\n::\n\n    enum AvsChromaPlacement {\n      CS_UNKNOWN_CHROMA_PLACEMENT = 0 << 20,\n      CS_MPEG1_CHROMA_PLACEMENT   = 1 << 20,\n      CS_MPEG2_CHROMA_PLACEMENT   = 2 << 20,\n      CS_YUY2_CHROMA_PLACEMENT    = 3 << 20,\n      CS_TOPLEFT_CHROMA_PLACEMENT = 4 << 20\n    };\n\n\nFunctions [need to add examples]\n--------------------------------\n\nHasVideo\n~~~~~~~~\n\n::\n\n    bool HasVideo();\n\n\nThis will return true if there is any video in the given clip.\n\n\nIsRGB / IsRGB24 / IsRGB32\n~~~~~~~~~~~~~~~~~~~~~~~~~\n\n::\n\n    bool IsRGB();\n    bool IsRGB24();\n    bool IsRGB32();\n\n\nThis will return true if the colorspace is `RGB`_ (in any way). The first two\nreturn true if the clip has the specific RGB colorspace (:doc:`RGB24 <ColorSpaces>` and\n:doc:`RGB32 <ColorSpaces>`). The third returns true for any RGB colorspace; future formats\ncould also apply.\n\n\nIsRGB48 / IsRGB64 (AviSynth+)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n::\n\n    bool IsRGB48() const;\n    bool IsRGB64() const;\n\nThese functions are for 16 bit packed RGB formats, similar to\nIsRGB24 and IsRGB32 for 8 bits.\n\n\nIsYUV / IsYUY2 / IsYV24 / IsYV16 / IsYV12 / IsYV411 / IsY8\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n::\n\n    bool IsYUV() const;\n\nThis will return true if the colorspace is :doc:`YUV <ColorSpaces>` (in any way).\nNote: Y8-Y32 returns true as well. (Y formats are set both as YUV and Interleaved)\n\n::\n\n    bool IsYUY2() const;\n    bool IsYV24() const;  // v5\n    bool IsYV16() const;  // v5\n    bool IsYV12() const;\n    bool IsYV411() const; // v5\n    bool IsY8() const;    // v5\n\nThey will return true if the clip has the specific YUV colorspace (e.g. :doc:`YUY2 <ColorSpaces>` and\n:doc:`YV12 <ColorSpaces>`). Note that I420 is also reported as YV12, because planes are\nautomatically swapped.\n\n\nIs444 / Is422 / Is420 / IsY (AviSynth+)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n::\n\n    bool Is444() const;\n    bool Is422() const;\n    bool Is420() const;\n    bool IsY() const;\n\nThese functions are the bit depth independent versions of\nIsYV24, IsYV16, IsYV12 and IsY8.\n\n\nIsYUVA / IsPlanarRGB / IsPlanarRGBA (AviSynth+)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n::\n\n  bool    (VideoInfo::*IsYUVA)() const;\n  bool    (VideoInfo::*IsPlanarRGB)() const;\n  bool    (VideoInfo::*IsPlanarRGBA)() const;\n\n\nFor checking further Avisynth+ specific formats:\nYUV with alpha plane, planar RGB with and without an alpha plane.\n\n\nIsColorSpace / IsSameColorspace / IsPlanar\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n::\n\n    bool IsColorSpace(int c_space);\n\n\nThis function will check if the colorspace (VideoInfo.pixel_type) is the same\nas given c_space (or more general it checks for a :doc:`Colorspace property <ColorspaceProperties>` (see\navisynth.h)).\n\n\n::\n\n    bool IsSameColorspace(const VideoInfo& vi2);\n\n\nThis function will compare two VideoInfos, and check if the colorspace is the\nsame. Note: It does not check imagesize or similar properties.\n\n\n::\n\n    bool IsPlanar();\n\n\nThis will return true if the video is planar: Y, YUV(A) and planar RGBP(A).\nSee the :doc:`Planar <PlanarImageFormat>` image format.\n\n\nIs / IsFieldBased / IsParityKnown / IsBFF / IsTFF\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n::\n\n    bool Is(int property);\n\n\nFrom v6 this will return true if the image type (VideoInfo.image_type)\nis the same as the given property (being IT_BFF, IT_TFF or\nIT_FIELDBASED).\n\n\n::\n\n    bool IsFieldBased();\n\n\nThis will return true if the video has been through a :doc:`SeparateFields <../corefilters/separatefields>`, and\nthe video has not been :doc:`weaved <../corefilters/weave>` yet. Otherwise it will return false.\n\n::\n\n    bool IsParityKnown();\n\n\nThis will return true if the video parity is known.\n\n::\n\n    bool IsBFF();\n    bool IsTFF();\n\n\nThis will return true if the video is bottom-field-first or top-field-first\nrespectively.\n\n\nSetFieldBased / Set / Clear\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n::\n\n    void SetFieldBased(bool isfieldbased);\n\n\nThis will set the field-based property to true (respectively false) if\nisfieldbased=true (respectively false).\n\n::\n\n    void Set(int property);\n    void Clear(int property);\n\n\nThis sets respectively clears an image_type property like: IT_BFF, IT_TFF or\nIT_FIELDBASED. See field.h for examples.\n\n\nBitsPerPixel\n~~~~~~~~~~~~\n\n::\n\n    int BitsPerPixel();\n\n\nThis will return the number of bits per pixel. This can be:\n\n+------------------+------------+\n| pixel_type       | nr of bits |\n+==================+============+\n| CS_BGR24         | 24         |\n+------------------+------------+\n| CS_BGR32         | 32         |\n+------------------+------------+\n| CS_YUY2          | 16         |\n+------------------+------------+\n| CS_YV12, CS_I420 | 12         |\n+------------------+------------+\n\nNote: This is not the BitsPerComponent which is the bit depth of the format.\nThe calculation returns an average storage size of a pixel.\n\n\nSetFPS / MulDivFPS\n~~~~~~~~~~~~~~~~~~\n\n::\n\n    void SetFPS(unsigned numerator, unsigned denominator);\n\n\nThis will set the framerate.\n\n::\n\n    void MulDivFPS(unsigned multiplier, unsigned divisor);\n\n\nThis will multiply the denominator by *multiplier* and scale the numerator\nand modified denominator.\n\nThere is some other useful information in VideoInfo structure (width, height,\nfps_numerator, fps_denominator, num_frames, pixel_type and image_type). See\n'avisynth.h' header file.\n\n\nBytesFromPixels\n~~~~~~~~~~~~~~~\n\n::\n\n    int BytesFromPixels(int pixels) const;\n\n\nFor interleaved formats it will return the number of bytes from the\nspecified number of pixels. For planar formats it will do the same\nexcept it operates on the first plane.\n\n\nRowSize / BMPSize\n~~~~~~~~~~~~~~~~~\n\n::\n\n    int RowSize(int plane=0) const;\n\n\nFor interleaved formats it will return the width of the frame in bytes.\nFor planar formats it will return the width of the specified plane in\nbytes.\n\nexamples:\n\n| 640x480 RGB24: RowSize() = 3*640 = 1920\n\n| 640x480 YV12: RowSize(PLANAR_Y) = 640\n| 640x480 YV12: RowSize(PLANAR_U) = 320\n\n::\n\n    int BMPSize() const;\n\nFor interleaved formats it will return the size of the frame in bytes\nwhere the width is rounded up to a multiple of 4 bytes. For planar\nformats it will do the same for the luma plane then add the two chroma\nplanes scaled by the subsampling. So, it's the number of bytes of a\nframe as if it was a `BMP frame`_.\n\nexamples:\n\n| 640x480 RGB24: BMPSize() = 480 * 3*640 = 921600\n| 643x480 RGB24: BMPSize() = 480 * 3*644 = 927360\n\n| 640x480 YV12: BMPSize() = 480 * 640 * (1+2*0.25) = 460800\n| 640x480 YV16: BMPSize() = 480 * 640 * (1+2*0.5) = 614400\n| 640x480 YV24: BMPSize() = 480 * 640 * (1+2*1) = 921600\n| 643x480 YV24: BMPSize() = 480 * 644 * (1+2*1) = 927360\n\n\nGetPlaneWidthSubsampling / GetPlaneHeightSubsampling\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n::\n\n    int GetPlaneWidthSubsampling(int plane) const; // v5\n\nThis will return the subsampling of the width in bitshifts.\n\nexamples:\n\n| YV24: GetPlaneWidthSubsampling(PLANAR_U) = 0 // since there is no\n  horizontal subsampling on a chroma plane\n| YV16: GetPlaneWidthSubsampling(PLANAR_U) = 0 // since there is no\n  horizontal subsampling on a chroma plane\n\n::\n\n    int GetPlaneHeightSubsampling(int plane) const; // v5\n\nThis will return the subsampling of the height in bitshifts.\n\nexamples:\n\n| YV24: GetPlaneHeightSubsampling(PLANAR_U) = 0 // since there is no\n  vertical subsampling on a chroma plane\n| YV16: GetPlaneHeightSubsampling(PLANAR_U) = 1 // since vertically there\n  are two times less samples on a chroma plane compared to a plane which\n  is not subsampled\n\n+----------------------+------------------------------------+-------------------------------------+\n| color format         | GetPlaneWidthSubsampling(PLANAR_U) | GetPlaneHeightSubsampling(PLANAR_U) |\n+======================+====================================+=====================================+\n| YV24, YUV(A)444      | 0                                  | 0                                   |\n+----------------------+------------------------------------+-------------------------------------+\n| YV16/YUY2, YUV(A)422 | 1                                  | 0                                   |\n+----------------------+------------------------------------+-------------------------------------+\n| YV12, YUV(A)420      | 1                                  | 1                                   |\n+----------------------+------------------------------------+-------------------------------------+\n| YV411                | 2                                  | 1                                   |\n+----------------------+------------------------------------+-------------------------------------+\n| Y8-Y32               | Error thrown                       | Error thrown                        |\n+----------------------+------------------------------------+-------------------------------------+\n\n\nHasAudio\n~~~~~~~~\n\n::\n\n    bool HasAudio();\n\n\nThis will return true if there is any audio in the given clip.\n\n\nAudioChannels / SampleType\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n::\n\n    int AudioChannels();\n\n\nThis will return the number of audio channels.\n\n\n::\n\n    int SampleType();\n\n\nThis will return the sampletype. This can be:\n\n+--------------+------------+\n| pixel_type   | nr of bits |\n+==============+============+\n| SAMPLE_INT8  | 1<<0       |\n+--------------+------------+\n| SAMPLE_INT16 | 1<<1       |\n+--------------+------------+\n| SAMPLE_INT24 | 1<<2       |\n+--------------+------------+\n| SAMPLE_INT32 | 1<<3       |\n+--------------+------------+\n| SAMPLE_FLOAT | 1<<4       |\n+--------------+------------+\n\n\nIsSampleType\n~~~~~~~~~~~~\n\n::\n\n    bool IsSampleType(int testtype);\n\n\nThis function will check if the sampletype (VideoInfo.sample_type) is the\nsame as testtype.\n\n\nSamplesPerSecond / BytesPerAudioSample / BytesPerChannelSample\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n::\n\n    int SamplesPerSecond();\n\n\nThis will return the number of bytes per second.\n\n::\n\n    int BytesPerAudioSample();\n\n\nThis will return the number of bytes per sample:\n\n::\n\n    int BytesPerChannelSample()\n\n\nThis will return the number of bytes per channel-sample. This can be:\n\n+--------------+----------------------+\n| sample       | nr of bytes          |\n+==============+======================+\n| SAMPLE_INT8  | sizeof(signed char)  |\n+--------------+----------------------+\n| SAMPLE_INT16 | sizeof(signed short) |\n+--------------+----------------------+\n| SAMPLE_INT24 | 3                    |\n+--------------+----------------------+\n| SAMPLE_INT32 | sizeof(signed int)   |\n+--------------+----------------------+\n| SAMPLE_FLOAT | sizeof(SFLOAT)       |\n+--------------+----------------------+\n\n\nAudioSamplesFromFrames / FramesFromAudioSamples / AudioSamplesFromBytes / BytesFromAudioSamples\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n::\n\n    int64_t AudioSamplesFromFrames(int64_t frames);\n\n\nThis returns the number of audiosamples from the first *frames* frames.\n\n::\n\n    int FramesFromAudioSamples(int64_t samples);\n\n\nThis returns the number of frames from the first *samples* audiosamples.\n\n::\n\n    int64_t AudioSamplesFromBytes(int64_t bytes);\n\n\nThis returns the number of audiosamples from the first *bytes* bytes.\n\n::\n\n    int64_t BytesFromAudioSamples(int64_t samples);\n\n\nThis returns the number of bytes from the first *samples* audiosamples.\n\nThere is some other useful information in VideoInfo structure\n(audio_samples_per_second, sample_type, num_audio_samples and nchannels). See\n'avisynth.h' header file.\n\n.. _videoinfo_getchannelmask:\n.. _videoinfo_setchannelmask:\n.. _videoinfo_ischannelmaskknown:\n\nIsChannelMaskKnown / SetChannelMask / GetChannelMask (Avisynth+ 3.7.3)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n::\n\n    bool IsChannelMaskKnown();\n\nThis returns if channel layout info is set or not.\n\n\n::\n\n    void SetChannelMask(bool isChannelMaskKnown, unsigned int dwChannelMask);\n\nThis sets the channel layout validity and the layout mask.\n\nValidity bit occupies the 3rd bit of image_type (starting from 0).\nActual mask is stored on 4-21 bits, \"speaker all\" case is on bit 22.\n\nNote that this mask is stuffed into 'image_type', which had already some\nbits used in it.\n\nThe given value thus will be stored differently: shifted by 4 bits, while special \n0x80000000 \"speaker all\" case is handled on a separate bit. Valid dwChannelMask values are \nusing 0-17 lsb bits, or is set to 0x80000000 to mask \"speaker all\".\n\nInput bit mask is following the specification of WAVE_FORMAT_EXTENSIBLE speaker bits.\nSee https://learn.microsoft.com/en-us/windows/win32/api/mmreg/ns-mmreg-waveformatextensible)\n\n\n::\n\n    unsigned int GetChannelMask();\n\nReturns the channel mask (same as it was set by SetChannelMask) if mask is valid, 0 otherwise.\n\n**Channel layout mask constants**\n\navisynth.h and avisynth_c.h contain the mask bit descriptions. In the actual layout they are or'd together.\nThe AvsChannelMask enum values are the channel mask constants similar to  \nWAVE_FORMAT_EXTENSIBLE speaker bits. 18 bits starting from MASK_SPEAKER_FRONT_LEFT to MASK_SPEAKER_TOP_BACK_RIGHT.\n\n+------------------------------------+----------------------+\n| MASK_SPEAKER_FRONT_LEFT            | 0x1                  |\n+------------------------------------+----------------------+\n| MASK_SPEAKER_FRONT_RIGHT           | 0x2                  |\n+------------------------------------+----------------------+\n| MASK_SPEAKER_FRONT_CENTER          | 0x4                  |\n+------------------------------------+----------------------+\n| MASK_SPEAKER_LOW_FREQUENCY         | 0x8                  |\n+------------------------------------+----------------------+\n| MASK_SPEAKER_BACK_LEFT             | 0x10                 |\n+------------------------------------+----------------------+\n| MASK_SPEAKER_BACK_RIGHT            | 0x20                 |\n+------------------------------------+----------------------+\n| MASK_SPEAKER_FRONT_LEFT_OF_CENTER  | 0x40                 |\n+------------------------------------+----------------------+\n| MASK_SPEAKER_FRONT_RIGHT_OF_CENTER | 0x80                 |\n+------------------------------------+----------------------+\n| MASK_SPEAKER_BACK_CENTER           | 0x100                |\n+------------------------------------+----------------------+\n| MASK_SPEAKER_SIDE_LEFT             | 0x200                |\n+------------------------------------+----------------------+\n| MASK_SPEAKER_SIDE_RIGHT            | 0x400                |\n+------------------------------------+----------------------+\n| MASK_SPEAKER_TOP_CENTER            | 0x800                |\n+------------------------------------+----------------------+\n| MASK_SPEAKER_TOP_FRONT_LEFT        | 0x1000               |\n+------------------------------------+----------------------+\n| MASK_SPEAKER_TOP_FRONT_CENTER      | 0x2000               |\n+------------------------------------+----------------------+\n| MASK_SPEAKER_TOP_FRONT_RIGHT       | 0x4000               |\n+------------------------------------+----------------------+\n| MASK_SPEAKER_TOP_BACK_LEFT         | 0x8000               |\n+------------------------------------+----------------------+\n| MASK_SPEAKER_TOP_BACK_CENTER       | 0x10000              |\n+------------------------------------+----------------------+\n| MASK_SPEAKER_TOP_BACK_RIGHT        | 0x20000              |\n+------------------------------------+----------------------+\n| MASK_SPEAKER_DEFINED               | 0x0003FFFF           |\n+------------------------------------+----------------------+\n| MASK_SPEAKER_RESERVED              | 0x7FFC0000           |\n+------------------------------------+----------------------+\n| MASK_SPEAKER_ALL                   | 0x80000000           |\n+------------------------------------+----------------------+\n\nIn the actual storage, in VideoInfo::image_type, they are shifted by 4 bits, except MASK_SPEAKER_ALL,\nwhich is handled specially, due to lack of available bits.\nSee VideoInfo::AvsImageTypeFlags enum in Avisynth.h .\n\n\nNumComponents (AviSynth+)\n~~~~~~~~~~~~~~~~~~~~~~~~~\n\n::\n\n    int NumComponents() const;\n\nThis will return the number of logical pixel components.\nFor Y and planar formats this is the actual number of valid planes.\n\n+--------------------+------------------+\n| color format       | nr of components |\n+====================+==================+\n| Y                  | 1                |\n+--------------------+------------------+\n| YUY2               | 3                |\n+--------------------+------------------+\n| planar YUV, RGBP   | 3                |\n+--------------------+------------------+\n| planar YUVA, RGBPA | 4                |\n+--------------------+------------------+\n| RGB24, RGB48       | 3                |\n+--------------------+------------------+\n| RGB32, RGB64       | 4                |\n+--------------------+------------------+\n\n\nComponentSize (AviSynth+)\n~~~~~~~~~~~~~~~~~~~~~~~~~\n\n::\n\n    int ComponentSize() const;\n\nThis will return the number bytes occupied for a component.\nBasically this depends on the bit depth.\n\n+----------------------+---------------+\n| bit depth            | ComponentSize |\n+======================+===============+\n| 8                    | 1             |\n+----------------------+---------------+\n| 10-16                | 2             |\n+----------------------+---------------+\n| 32 bit float         | 4             |\n+----------------------+---------------+\n\n\nBitsPerComponent (AviSynth+)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n::\n\n    int BitsPerComponent() const;\n\nThis will return the bit depth: 8-16 or 32.\n\nNote: Avisynth+ does not support all bit depths: \nonly 8, 10, 12, 14, 16 and 32.\n\n\n\n----\n\nBack to :doc:`FilterSDK`\n\n$Date: 2023/02/15 12:28:50 $\n\n.. _RGB: http://avisynth.nl/index.php/RGB\n.. _BMP frame: http://en.wikipedia.org/wiki/BMP_file_format\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/WorkingWithImages.rst",
    "content": "\nWorkingWithImages\n=================\n\nAll images are given a pitch. The pitch is basically what can be described as\n\"length of a line\". What's funny is that the pitch does not have to be equal\nto the width of the image.\n\nFor instance, if you crop something off your image, the only thing that\nchanges is the width of your image; the pitch and the actual byte-count of a\nline remains the same.\n\nThe image is then laid out like this:\n\n``rrrrrrrrrrrrrrrrpppp``\n\n``rrrrrrrrrrrrrrrrpppp``\n\n``rrrrrrrrrrrrrrrrpppp``\n\nWhere 'r' are the pixels inside the image used, and 'p' is the padding\ninserted after each line.\n\n\nFast Information\n----------------\n\n*Width* = width in pixels.\n\n*Rowsize* = number of bytes in one line.\n\n*Pitch* = distance from start of one line to the next in bytes.\n\n*vi->BytesFromPixels(n)* = size of n pixels in bytes - does NOT take pitch into\nconsideration, so can only be used within a line.\n\nFor the :doc:`PlanarImageFormat <PlanarImageFormat>`:\n\nAligned rowsize = width in bytes, always divisible with 8.\n\n\nVideoInfo vs. PVideoFrame\n-------------------------\n\nVideoInfo is considered the \"constant\" video info. This cannot change in any\nway. The information such as width, height and colorspace cannot change. So\nthe information you get from this can be trusted to be the same from all\nframes you recieve. If you change the VideoInfo you have received it will not\nchange the frames you receive, but a modified 'VideoInfo vi' can be sent to\nenv->NewVideoFrame(vi) and a new frame with the changed parameters will be\ncreated. Only your own filter can modify the VideoInfo given to your filter.\n\nPVideoFrame contains information about a particular frame you requested.\nHeight and Rowsize should not change (this can be considered a bug). Pitch\ncan change, so **you cannot rely on pitch being the same for all frames you\nrecieve**.\n\n\nMore Information\n----------------\n\nSee more about :doc:`DataStorageInAviSynth <DataStorageInAviSynth>`.\n\nSee more about :doc:`ColorSpaces <ColorSpaces>`.\n\n----\n\nBack to :doc:`FilterSDK`\n\n$Date: 2014/10/27 22:04:54 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/WorkingWithPlanarImages.rst",
    "content": "\n`WorkingWithPlanarImages`_\n==========================\n\nAdditional functions have been put in to support planar images. They are the\nfollowing:\n\nVideoFrame:\n\n``int GetPitch(int plane)``\n\n``int GetRowSize(int plane)``\n\n``int GetHeight(int plane)``\n\n``VideoFrame* Subframe(int rel_offset, int new_pitch, int new_row_size, int new_height, int !rel_offsetU, int !rel_offsetV, int !pitchUV)``\n\n``const BYTE* GetReadPtr(int plane)``\n\n``BYTE* GetWritePtr(int plane)``\n\n\nWhere plane can be:\n\n* ``PLANAR_Y``\n* ``PLANAR_U``\n* ``PLANAR_V``\n\nPLANAR_Y is equivalent to calling the old functions.\n\nIt can be determined whether or not you are dealing with a planar images by\nusing vi.IsPlanar(). This will return true, if image is planar. Using\nvi.RowSize()from VideoInfo only provides you with correct numbers for the\nfirst plane. Use RowSize(int plane) from VideoFrame to obtain the proper\nresults. The same goes for vi.BytesFromPixels(), which also only returns\ncorrect results for the first plane.\n\nWhat can be safely assumed for planar images is:\n\n* Pitch U = Pitch V.  * RowSize U = RowSize V  * Height U = Height V\n\nYou should consider the planes as seperate memory regions, and you shouldn't\nbegin guessing where \"U would be relative to Y\", since it might as well\nchange.\n\nThe general guideline should (as always) be: Use the functions - never\ndirectly access the members of VideoInfo or VideoFrameBuffer or VideoFrame\nstructs directly, unless you are creating an input source. Always use the\nsupplied funtions! This is the only way for us to be able to maintain\ncompatibility with future releases. All processing filters should be able to\nuse the methods exclusively.\n\nGetRowSize() is special, since it can return mod16 widths for Luma and mod8\naligned widths for chroma planes. When you request the rowsize, you can add\nthe parameter \"PLANAR_Y_ALIGNED\" or \"PLANAR_U_ALIGNED\"/\"PLANAR_V_ALIGNED\".\nThis will give you the width of the image, rounded up to nearest mod16 (or if\nalready mod16, just rowsize as usual).\n\nThis means that you can request an image larger than the actual image,\nwithout risking to write or read into the next line. You can safely do\nwhatever you like with this data, since AviSynth completely ignores it. This\nwill enable you to operate on 8 bytes (1 quadword) at the time for all\nplanes.\n\nSome (producing) filters may want to set a forced pitch. Per default, when\nyou request a videoframe with a specific modX pitch it might be overruled by\nAviSynth. (You do this by using env->NewVideoFrame(VideoInfo, [alignment]))\nIn this (very rare case), you can use a negative alignment. This will make\nthe alignment forced.\n\nIf you force an alignment you MUST also apply the AlignPlanar(!PClip) filter\nafter your own, otherwise your filter will not produce valid output. See\nsource.cpp for examples.\n\n\nSee:\n::::\n\nThe example of an AviSynyh :doc:`TwoFiveInvert <TwoFiveInvert>` filter.\n\nSomething about the specific :doc:`ColorSpaces <ColorSpaces>`.\n\nMore about :doc:`DataStorageInAviSynth <DataStorageInAviSynth>`.\n\nA general introduction to :doc:`WorkingWithImages <WorkingWithImages>`.\n\n\nBack to :doc:`AviSynthTwoFiveSDK <AviSynthTwoFiveSDK>`\n\n$Date: 2025-02-24 21:11:35-05:00 $\n\n.. _WorkingWithPlanarImages:\n    http://avisynth.nl/index.php/Filter_SDK/Working_with_Planar_Images\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/avs2pcm.rst",
    "content": "\navs2pcm\n=======\n\navs2pcm reads a script and outputs raw audio (`lpcm`_, that is lineair\npcm). The byte order will be little endian, the sign (signed or\nunsiged) will depend on the bith depth and the channels will be\ninterleaved.\n\nHere's avs2pcm.cpp:\n::\n\n    #include <stdio.h>\n    #include <Windows.h>\n    #include \"avisynth.h\"\n\n    #define MY_VERSION \"Avs2PCM 0.01\"\n\n    const AVS_Linkage *AVS_linkage = 0;\n\n    int __cdecl main(int argc, const char* argv[])\n    {\n        const char* infile = NULL;\n        const char* outfile = NULL;\n        FILE* out_fh;\n\n        if (!strcmp(argv[1], \"-h\")) {\n            fprintf(stderr, MY_VERSION \"\\n\"\n            \"Usage: avs2pcm in.avs out.pcm\\n\");\n            return 2;\n        } else {\n            infile = argv[1];\n            outfile = argv[2];\n        }\n\n        try {\n            char* sample_type;\n            typedef IScriptEnvironment* (__stdcall *DLLFUNC)(int);\n            IScriptEnvironment* env;\n            HMODULE avsdll = LoadLibrary(\"avisynth.dll\");\n            if (!avsdll) {\n                fprintf(stderr, \"failed to load avisynth.dll\\n\");\n                return 2;\n            }\n\n            DLLFUNC CreateEnv = (DLLFUNC)GetProcAddress(avsdll, \"CreateScriptEnvironment\");\n            if (!CreateEnv) {\n                fprintf(stderr, \"failed to load CreateScriptEnvironment()\\n\");\n                FreeLibrary(avsdll);\n                return 1;\n            }\n\n            env = CreateEnv(AVISYNTH_INTERFACE_VERSION);\n            AVS_linkage = env->GetAVSLinkage();\n            AVSValue arg(infile);\n            AVSValue res = env->Invoke(\"Import\", AVSValue(&arg, 1));\n            if (!res.IsClip()) {\n                fprintf(stderr, \"Error: '%s' didn't return a video clip.\\n\", infile);\n                FreeLibrary(avsdll);\n                return 1;\n            }\n\n            PClip clip = res.AsClip();\n\n            if (clip->GetVersion() < 5) {\n                fprintf(stderr, \"Error: too old version ('%d') of avisynth.dll loaded.\\nplease install v2.60 or later.\\n\",\n                    clip->GetVersion());\n                return 1;\n            }\n\n            VideoInfo vi = clip->GetVideoInfo();\n\n            if (!vi.HasAudio()) {\n                fprintf(stderr, \"Error: '%s' video only clip.\\n\", infile);\n                FreeLibrary(avsdll);\n                return 1;\n            }\n\n            fprintf(stderr, \" %s:\\n\", infile);\n            fprintf(stderr, \" %d Herz,\\n\", vi.audio_samples_per_second);\n            fprintf(stderr, \" %d channels,\\n\", vi.nchannels);\n            fprintf(stderr, \" %I64d audio samples,\\n\", vi.num_audio_samples);\n\n            switch(vi.SampleType()) {\n            case SAMPLE_INT8 : sample_type = \"8 bit\";\n                break;\n            case SAMPLE_INT16 : sample_type = \"16 bit\";\n                break;\n            case SAMPLE_INT24 : sample_type = \"24 bit\";\n                break;\n            case SAMPLE_INT32 :\n            case SAMPLE_FLOAT : sample_type = \"32 bit\";\n                break;\n            default: sample_type = \"unknown sample type\";\n                break;\n            }\n\n            fprintf(stderr, \" %s\", sample_type);\n\n            out_fh = fopen(outfile, \"wb\");\n            if (!out_fh) {\n                fprintf(stderr, \"fopen(\\\"%s\\\") failed\", outfile);\n                FreeLibrary(avsdll);\n                return 1;\n            }\n\n            const __int64 start = 0;\n            const __int64 count = vi.num_audio_samples;\n            const int channels = vi.AudioChannels();\n            __int64 bytes = vi.BytesFromAudioSamples(count);\n            int BlockAlign = vi.AudioChannels() * vi.BytesPerAudioSample();\n\n            unsigned char* samples = new unsigned char[BlockAlign*count];\n            clip->GetAudio(samples, start, count, env);\n            fwrite(samples, bytes, 1, out_fh);\n\n            delete[] samples;\n            env->DeleteScriptEnvironment();\n            FreeLibrary(avsdll);\n            AVS_linkage = 0;\n\n        } catch(AvisynthError err) {\n            fprintf(stderr, \"\\nAvisynth error:\\n%s\\n\", err.msg);\n            return 1;\n        }\n\n        fclose(out_fh);\n        return 0;\n    }\n\n\nCompile this file into an EXE named avs2pcm.exe. See\n:doc:`compiling instructions <CompilingAvisynthPlugins>`. Now open the\ncommand line and go to the folder where avs2pcm.exe and your script\n(called example.avs here) are located. Our script:\n::\n\n    Tone(length=1, frequency=2, samplerate=48000, channels=1, type=\"square\", level=1.0) # float\n    ConvertAudioTo16Bit()\n\n\nType the following on the command line (the name of the output clip can\nbe arbitrary in our application):\n::\n\n    avs2pcm.exe example.avs output.pcm\n\nSo the output file will contain 48000 samples of 16-bit data (at 48\nkHz, one channel). You can import it in AviSynth using the plugin\nNicAudio:\n::\n\n    v = Blankclip(1000)\n    a = RaWavSource(\"D:\\AviSynth\\Plugins\\avs2pcm\\output.pcm\", 48000, 16, 1) # little-endian\n    Audiodub(v,a).ConvertAudioTo16Bit().GetChannels(1) # Audiograph doesn't support 24/32bit nor multichannel\n    Audiograph(20)\n\n\nLine by line breakdown\n----------------------\n\nHere's a line-by-line breakdown of avs2pcm.cpp:\n::\n\n    #include <stdio.h>\n    #include <Windows.h>\n    #include \"avisynth.h\"\n\n    #define MY_VERSION \"Avs2PCM 0.01\"\n\n    const AVS_Linkage *AVS_linkage = 0;\n\n    int __cdecl main(int argc, const char* argv[])\n    {\n        const char* infile = NULL;\n        const char* outfile = NULL;\n        FILE* out_fh;\n\n        if (!strcmp(argv[1], \"-h\")) {\n            fprintf(stderr, MY_VERSION \"\\n\"\n            \"Usage: avs2pcm in.avs out.pcm\\n\");\n            return 2;\n        } else {\n            infile = argv[1];\n            outfile = argv[2];\n        }\n\n        try {\n            char* sample_type;\n            typedef IScriptEnvironment* (__stdcall *DLLFUNC)(int);\n            IScriptEnvironment* env;\n            HMODULE avsdll = LoadLibrary(\"avisynth.dll\");\n            if (!avsdll) {\n                fprintf(stderr, \"failed to load avisynth.dll\\n\");\n                return 2;\n            }\n\n            DLLFUNC CreateEnv = (DLLFUNC)GetProcAddress(avsdll, \"CreateScriptEnvironment\");\n            if (!CreateEnv) {\n                fprintf(stderr, \"failed to load CreateScriptEnvironment()\\n\");\n                FreeLibrary(avsdll);\n                return 1;\n            }\n\n            env = CreateEnv(AVISYNTH_INTERFACE_VERSION);\n            AVS_linkage = env->GetAVSLinkage();\n            AVSValue arg(infile);\n            AVSValue res = env->Invoke(\"Import\", AVSValue(&arg, 1));\n            if (!res.IsClip()) {\n                fprintf(stderr, \"Error: '%s' didn't return a clip.\\n\", infile);\n                FreeLibrary(avsdll);\n                return 1;\n            }\n\n            PClip clip = res.AsClip();\n\n            if (clip->GetVersion() < 5) {\n                fprintf(stderr, \"Error: too old version ('%d') of avisynth.dll loaded.\\nplease install v2.60 or later.\\n\",\n                    clip->GetVersion());\n                return 1;\n            }\n\n            VideoInfo vi = clip->GetVideoInfo();\n\n\nThe lines above are explained in :doc:`avs2yuv <avs2yuv>`, so they won't be repeated\nhere.\n::\n\n        if (!vi.HasAudio()) {\n            fprintf(stderr, \"Error: '%s' video only clip.\\n\", infile);\n            FreeLibrary(avsdll);\n            return 1;\n        }\n\n\nReturns an error if the clip doesn't contain audio.\n::\n\n        fprintf(stderr, \" %s:\\n\", infile);\n        fprintf(stderr, \" %d Herz,\\n\", vi.audio_samples_per_second);\n        fprintf(stderr, \" %d channels,\\n\", vi.nchannels);\n        fprintf(stderr, \" %I64d audio samples,\\n\", vi.num_audio_samples);\n\n        switch(vi.SampleType()) {\n        case SAMPLE_INT8 : sample_type = \"8 bit\";\n            break;\n        case SAMPLE_INT16 : sample_type = \"16 bit\";\n            break;\n        case SAMPLE_INT24 : sample_type = \"24 bit\";\n            break;\n        case SAMPLE_INT32 :\n        case SAMPLE_FLOAT : sample_type = \"32 bit\";\n            break;\n        default: sample_type = \"unknown sample type\";\n            break;\n        }\n\n        fprintf(stderr, \" %s\", sample_type);\n\n\nSome information about the clip is written to the console.\n::\n\n        out_fh = fopen(outfile, \"wb\");\n\n\nCreates an empty binary file and opens it for writing. It returns a\nfile pointer called 'out_fh' here. Nb, 'wb' means write mode and\nbinary.\n::\n\n        if (!out_fh) {\n            fprintf(stderr, \"fopen(\\\"%s\\\") failed\", outfile);\n            FreeLibrary(avsdll);\n            return 1;\n        }\n\n\nWhen failing (thus when out_fh is NULL) an error is written to the\nconsole.\n::\n\n        const __int64 start = 0;\n        const __int64 count = vi.num_audio_samples;\n\n\nThis gives the number of audio samples in our stream.\n::\n\n        const int channels = vi.AudioChannels();\n\n\nThis gives the number of audio channels of our stream.\n::\n\n        __int64 bytes = vi.BytesFromAudioSamples(count);\n\n\nWe will use `fwrite`_ to write 'count' audio samples to a file. So we\nwill need to know the corresponding number of bytes which needs to be\nwritten. :doc:`BytesFromAudioSamples <VideoInfo>` gives the number of bytes and it is\ncalculated internally as follows:\n\n+-------------------------+-------------------------------------------+--------------------------------------+\n| function                | value                                     | size                                 |\n+=========================+===========================================+======================================+\n| BytesPerChannelSample() || = sizeof(unsigned char)                  || = 1 byte [for 8 bitaudio],          |\n|                         || = sizeof(signed short)                   || = 2 bytes [for 16 bit audio],       |\n|                         |                                           || = 3 bytes [for 24 bit audio],       |\n|                         || = sizeof(signed int)                     || = 4 bytes [for 32 bit audio],       |\n|                         || = sizeof(SFLOAT)                         || = 4 bytes [for float audio;         |\n|                         |                                           |  this is also 32 bit audio]          |\n+-------------------------+-------------------------------------------+--------------------------------------+\n| BytesPerAudioSample()   | AudioChannels() * BytesPerChannelSample() |                                      |\n+-------------------------+-------------------------------------------+--------------------------------------+\n| BytesFromAudioSamples() | num_audio_samples * BytesPerAudioSample() |                                      |\n+-------------------------+-------------------------------------------+--------------------------------------+\n\n\n::\n\n        int BlockAlign = vi.BytesPerAudioSample();\n        unsigned char* samples = new unsigned char[BlockAlign*count];\n        clip->GetAudio(samples, start, count, env);\n        fwrite(samples, bytes, 1, out_fh);\n        delete[] samples;\n\n\nThere are a few ways to write audio to a file. The simpliest one is the\none above. Let's look at what happens with our data with an example:\n::\n\n    Tone(length=1, frequency=2, samplerate=48000, channels=1, type=\"square\", level=1.0) # float\n    ConvertAudioTox() // x = 8Bit, 16Bit, 24Bit, 32Bit and Float\n\n\nThe samples are always written to the pcm file as `little endian`_. So\nthis means the bytes are written in reversed order (thus the least\nsignificant byte first and the most significant byte last).\n\n+--------------------------------------------------+-------------------------------------------------------------------------------------------------------+-------------------------------+\n| type (x)                                         | value of samples                                                                                      | bytes written in file         |\n+==================================================+=======================================================================================================+===============================+\n| 8Bit (samples between 0 and 2^8-1)               || s[0] = 255;                                                                                          | FF .. 00 ..                   |\n|                                                  || s[count-1] = 0                                                                                       |                               |\n+--------------------------------------------------+-------------------------------------------------------------------------------------------------------+-------------------------------+\n| 16Bit (samples between -2^15 and 2^15-1)         || s[1]*256+s[0] = 127*256+255 = 32767;                                                                 | FF 7F .. 00 80 ..             |\n|                                                  || s[count-1]*256+s[count-2] = 128*256+0 = 32768 (= -32768)                                             |                               |\n+--------------------------------------------------+-------------------------------------------------------------------------------------------------------+-------------------------------+\n| 24Bit (samples between -2^23 and 2^23-1)         || s[2]*16^4+s[1]*16^2+s[0] = 8388607;                                                                  | FF FF 7F .. 00 00 80 ..       |\n|                                                  || s[count-1]*16^4+s[count-2]*16^2+s[count-3] = 8388608 (= -8388608)                                    |                               |\n+--------------------------------------------------+-------------------------------------------------------------------------------------------------------+-------------------------------+\n| 32Bit (samples between -2^31 and 2^31-1)         || s[3]*16^6+s[2]*16^4+s[1]*16^2+s[0] = 2147483647;                                                     | FF FF FF 7F .. 00 00 00 80 .. |\n|                                                  || s[count-1]*16^6+s[count-2]*16^4+s[count-3]*16^2+s[count-4] = 2147483648 (= -2147483648)              |                               |\n+--------------------------------------------------+-------------------------------------------------------------------------------------------------------+-------------------------------+\n| `Float`_ (samples between -1.00000 and 1.000000) || s[3]*16^6+s[2]*16^4+s[1]*16^2+s[0] = 63*16^6+128*16^4+0*16^2+0 = 106535321;                          | 00 00 80 3F .. 00 00 80 BF .. |\n|                                                  || s[count-1]*16^6+s[count-2]*16^4+s[count-3]*16^2+s[count-4] = 191*16^6+128*16^4+0*16^2+0 = 3212836864 |                               |\n+--------------------------------------------------+-------------------------------------------------------------------------------------------------------+-------------------------------+\n\n\nAbove the samples are declared as unsigned char (regardless of the\nnumber of bits in a sample), but they are filled by GetAudio as\nexplained above. Thus an audio sample is stored in multiple samples\n(each sample having the size of a byte). This is the simpliest and\ncleanest way to do, but you could also have done the following instead:\n::\n\n    int BlockAlign = vi.BytesPerAudioSample();\n\n    switch (vi.SampleType()) {\n    case SAMPLE_INT8 : {\n        unsigned char* samples = new unsigned char[BlockAlign*count];\n        clip->GetAudio(samples, start, count, env);\n        fwrite(samples, bytes, 1, out_fh);\n        delete[] samples;\n        break;\n        }\n    case SAMPLE_INT16 : {\n        signed short* samples = new signed short[channels*count];\n        clip->GetAudio(samples, start, count, env);\n        fwrite(samples, bytes, 1, out_fh);\n        delete[] samples;\n        break;\n        }\n    case SAMPLE_INT24 : {\n        unsigned char* samples = new unsigned char[3*channels*count];\n        clip->GetAudio(samples, start, count, env);\n        fwrite(samples, bytes, 1, out_fh);\n        delete[] samples;\n        break;\n        }\n    case SAMPLE_INT32 : {\n        signed int* samples = new signed int[channels*count];\n        clip->GetAudio(samples, start, count, env);\n        fwrite(samples, bytes, 1, out_fh);\n        delete[] samples;\n        break;\n        }\n    case SAMPLE_FLOAT : {\n        SFLOAT* samples = new SFLOAT[channels*count];\n        clip->GetAudio(samples, start, count, env);\n        fwrite(samples, bytes, 1, out_fh);\n        delete[] samples;\n        break;\n        }\n    }\n\n\nHere an audio sample is stored in one sample (having the size of a\nmultiple bytes), but fwrite will write the same bytes to the file as\nearlier.\n\nAt first glance it seems possible to simplify the code above by moving\nthe lines \"clip .. delete[] samples\" outside the switch statement, but\nthat's not possible. The reason is that each code-block corresponding\nto a label has its own scope. So the variable samples doesn't exist\noutside the switch statement and can't be used there for further\nprocessing. See `here`_ for more information.\n::\n\n        env->DeleteScriptEnvironment();\n        FreeLibrary(avsdll);\n        AVS_linkage = 0;\n\n        } catch(AvisynthError err) {\n            fprintf(stderr, \"\\nAvisynth error:\\n%s\\n\", err.msg);\n            return 1;\n        }\n\n        fclose(out_fh);\n        return 0;\n    }\n\n\nThe remaining lines above are explained in :doc:`avs2yuv <avs2yuv>`, so they won't be\nrepeated here.\n\n____\n\nBack to :doc:`FilterSDK`\n\n$Date: 2014/10/27 22:04:54 $\n\n.. _lpcm: http://wiki.multimedia.cx/index.php?title=PCM\n.. _fwrite: http://www.cplusplus.com/reference/cstdio/fwrite/\n.. _little endian: http://en.wikipedia.org/wiki/Endianness\n.. _Float: http://avisynth.nl/index.php/Float\n.. _here: http://stackoverflow.com/questions/92396/why-cant-variables-be-declared-in-a-switch-statement\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/FilterSDK/avs2yuv.rst",
    "content": "\navs2yuv\n=======\n\navs2yuv reads a script and outputs raw video (YUV or RGB). It's a\nstripped down version of the famous avs2yuv.\n\nHere's avs2yuv.cpp:\n::\n\n    #include <stdio.h>\n    #include <Windows.h>\n    #include \"avisynth.h\"\n\n    #define MY_VERSION \"Avs2YUV 0.24\"\n\n    const AVS_Linkage *AVS_linkage = 0;\n\n    int __cdecl main(int argc, const char* argv[])\n    {\n    const char* infile = NULL;\n    const char* outfile = NULL;\n    FILE* out_fh;\n\n    if (!strcmp(argv[1], \"-h\")) {\n        fprintf(stderr, MY_VERSION \"\\n\"\n            \"Usage: avs2yuv.exe in.avs out.raw\\n\");\n        return 2;\n    } else {\n        infile = argv[1];\n        outfile = argv[2];\n    }\n\n    try {\n        char* colorformat;\n        typedef IScriptEnvironment* (__stdcall *DLLFUNC)(int);\n        IScriptEnvironment* env;\n        HMODULE avsdll = LoadLibrary(\"avisynth.dll\");\n        if (!avsdll) {\n            fprintf(stderr, \"failed to load avisynth.dll\\n\");\n            return 2;\n        }\n\n        DLLFUNC CreateEnv = (DLLFUNC)GetProcAddress(avsdll, \"CreateScriptEnvironment\");\n        if (!CreateEnv) {\n            fprintf(stderr, \"failed to load CreateScriptEnvironment()\\n\");\n            FreeLibrary(avsdll);\n            return 1;\n        }\n\n        env = CreateEnv(AVISYNTH_INTERFACE_VERSION);\n\n        AVS_linkage = env->GetAVSLinkage();\n        AVSValue arg(infile);\n        AVSValue res = env->Invoke(\"Import\", AVSValue(&arg, 1));\n        if (!res.IsClip()) {\n            fprintf(stderr, \"Error: '%s' didn't return a video clip.\\n\", infile);\n            FreeLibrary(avsdll);\n            return 1;\n        }\n\n        PClip clip = res.AsClip();\n\n        if (clip->GetVersion() < 5) {\n            fprintf(stderr, \"Error: too old version ('%d') of avisynth.dll loaded.\\nplease install v2.60 or later.\\n\",\n                clip->GetVersion());\n            return 1;\n        }\n\n        VideoInfo vi = clip->GetVideoInfo();\n\n        if (!vi.HasVideo()) {\n            fprintf(stderr, \"Error: '%s' audio only clip.\\n\", infile);\n            FreeLibrary(avsdll);\n            return 1;\n        }\n\n        fprintf(stderr, \" %s:\\n\", infile);\n        fprintf(stderr, \" %dx%d,\\n\", vi.width, vi.height);\n        fprintf(stderr, \" %d/%d fps,\\n\", vi.fps_numerator, vi.fps_denominator);\n        fprintf(stderr, \" %d frames,\\n\", vi.num_frames);\n        if (vi.IsYUV()) {\n            colorformat = \"YUV\";\n        } else {\n            colorformat = \"RGB\";\n        }\n        fprintf(stderr, \" %s color format\", colorformat);\n\n        out_fh = fopen(outfile, \"wb\");\n        if (!out_fh) {\n            fprintf(stderr, \"fopen(\\\"%s\\\") failed\", outfile);\n            FreeLibrary(avsdll);\n            return 1;\n        }\n\n        static const int planes[] = {PLANAR_Y, PLANAR_U, PLANAR_V};\n\n        for (int frm = 0; frm < vi.num_frames; ++frm) {\n            PVideoFrame f = clip->GetFrame(frm, env);\n\n            for (int p=0; p<3; p++) { // for interleaved formats only the first plane (being the whole frame) is written\n                int height = f->GetHeight(planes[p]);\n                int rowsize = f->GetRowSize(planes[p]);\n                int pitch = f->GetPitch(planes[p]);\n                const BYTE* data = f->GetReadPtr(planes[p]);\n                for (int y=0; y<height; y++) {\n                    fwrite(data, 1, rowsize, out_fh);\n                    data += pitch;\n                }\n            }\n        }\n\n        env->DeleteScriptEnvironment();\n        FreeLibrary(avsdll);\n        AVS_linkage = 0;\n\n    } catch(AvisynthError err) {\n        fprintf(stderr, \"\\nAvisynth error:\\n%s\\n\", err.msg);\n        return 1;\n    }\n\n    fclose(out_fh);\n    return 0;\n    }\n\n\nCompile this file into an EXE named avs2yuv.exe. See\n:doc:`compiling instructions <CompilingAvisynthPlugins>`. Now open the\ncommand line and go to the folder where avs2yuv.exe and your script (called\nexample.avs here) are located. Our script:\n::\n\n    ColorBars()\n    ConvertToYV12()\n    Trim(0,4)\n    Showframenumber()\n\n\nType the following on the command line (the name of the output clip can\nbe arbitrary in our application):\n::\n\n    avs2yuv.exe example.avs output.raw\n\n\nSo the output file will contain five frames of YV12 data (640x480). The\nraw stream can be played with `YUVtoolkit`_ for example. You can also\nimport it in AviSynth using the plugin RawSource.\n\nLine by line breakdown\n----------------------\n\nHere's a line-by-line breakdown of avs2yuv.cpp.\n::\n\n    #include <stdio.h>\n\n\nThe header stdio.h contains objects like `stderr`_ (a pointer to a FILE\nobject) and functions like `fprintf`_, `fopen`_ and `fwrite`_. Those\nwill be used later on.\n\nThe standard error stream (*stderr*) is the default destination for error\nmessages and other diagnostic warnings. Like stdout, it is usually also\ndirected by default to the text console (generally, on the screen).\n\n*fprintf* writes formatted data to stream.\n\n*fopen* opens the file whose name is specified in the parameter filename\nand associates it with a stream that can be identified in future\noperations by the FILE pointer returned.\n\n*fwrite* writes data to a file which is opened bij *fopen*.\n::\n\n    #include <Windows.h>\n\n\n::\n\n    #include \"avisynth.h\"\n\n\nThis header declares all the classes and miscellaneous constants that\nyou might need when accessing avisynth.dll.\n::\n\n    #define MY_VERSION \"Avs2YUV 0.24\"\n\n\nDefines the version number which will be printed (using the \"-h\"\noption) later on.\n::\n\n    const AVS_Linkage *AVS_linkage = 0;\n\n\nThis declares and initializes the server pointers static storage\n:doc:`AVS_Linkage <AVSLinkage>`.\n::\n\n    int __cdecl main(int argc, const char* argv[])\n\n\nargv and argc are how command line arguments are passed to main() in C\nand C++ (you can name them the way you want to). argc will be the\nnumber of strings pointed to by the array argv. This will be one plus\nthe number of arguments, with the first one being the name of the\napplication. Thus when using the command line \"avs2yuv.exe in.avs\nout.raw\" we have argv[0]=\"avs2yuv.exe\", argv[1]=\"in.avs\",\nargv[2]=\"out.raw\" and argc=2.\n::\n\n    const char* infile = NULL;\n    const char* outfile = NULL;\n\n\ninitialize infile and outfile as null pointers by setting them to\n`NULL`_. We could have set them to 0 too since that's the same in\nC/C++.\n::\n\n    FILE* out_fh;\n\n\nout_fh is declared as a pointer to a `FILE`_ object.\n::\n\n    if (!strcmp(argv[1], \"-h\")) {\n        fprintf(stderr, MY_VERSION \"\\n\"\n            \"Usage: avs2yuv.exe in.avs out.raw\\n\");\n        return 2;\n\n\nWhen using the command line \"avs2yuv.exe -h\" it will print to the\nconsole how the application should be used ('h' from help). The\n`return`_ terminates the function main() (and thus the application).\nreturning 0 means that your program executed without errors and\nreturning a different int means it executed with errors.\n\n\"Avs2YUV 0.24\" (followed by an enter) \"Usage: avs2yuv.exe in.avs\nout.raw\" (followed by an enter)\n::\n\n    } else {\n        infile = argv[1];\n        outfile = argv[2];\n    }\n\n\nWhen the second argument (argv[1]) is not '-h' it will set infile to\nthe name of the input file (being argv[1]) and outfile to the name of\nthe output file (being argv[2]).\n::\n\n    try {\n        char* colorformat;\n        IScriptEnvironment* env;\n\n\nenv returns a pointer to the :ref:`IScriptEnvironment <cplusplus_iscriptenvironment>` interface.\n::\n\n    HMODULE avsdll = LoadLibrary(\"avisynth.dll\");\n\n\n`LoadLibrary`_ loads the specified module (which is avisynth.dll here)\ninto the address space of the process (the process being avs2yuv.exe\nhere). When successful avsdll will be the handle to the module, else it\nwill be NULL.\n::\n\n    if (!avsdll) {\n        fprintf(stderr, \"failed to load avisynth.dll\\n\");\n        return 2;\n    }\n\n\nWhen avsdll is NULL (thus 0), !avsdll evaluates to one, and the error\n\"failed to load avisynth.dll\" is printed to the console.\n::\n\n    typedef IScriptEnvironment* (__stdcall *DLLFUNC)(int);\n    DLLFUNC CreateEnv = (DLLFUNC)GetProcAddress(avsdll, \"CreateScriptEnvironment\");\n\n\n:ref:`CreateScriptEnvironment <cplusplus_createscriptenvironment>` is exported by avisynth.dll and it is a\npointer to the :ref:`IScriptEnvironment <cplusplus_iscriptenvironment>` interface. `GetProcAddress`_\nwill retrieve the address of the exported function (when failing it\nwill return NULL).\n\nIn order to do so you must declare a function pointer (called 'DLLFUNC'\nhere) with *exactly* the same prototype as the function it is supposed\nto represent. This is done in the first line (note that\n:ref:`CreateScriptEnvironment <cplusplus_createscriptenvironment>` has one parameter of type 'int')\n::\n\n    typedef IScriptEnvironment* (__stdcall *DLLFUNC)(int);\n\nThe `typedef`_ declaration is used to construct shorter or more\nmeaningful names (like 'DLLFUNC' here) for types that are already\ndefined (like 'IScriptEnvironment*' here).\n\nIn the second line the value of GetProcAddress is cast to the correct\nfunction pointer type.\n::\n\n    ... = (DLLFUNC)GetProcAddress(...);\n\n\nWe could also have used\n::\n\n    IScriptEnvironment* (__stdcall *CreateEnv)(int) = NULL;\n    CreateEnv = (IScriptEnvironment* (__stdcall *)(int))GetProcAddress(avsdll, \"CreateScriptEnvironment\");\n\n\nor shorter and less readable\n::\n\n    IScriptEnvironment* (__stdcall *CreateEnv)(int) = (IScriptEnvironment* (__stdcall *)(int))GetProcAddress(avsdll, \"CreateScriptEnvironment\");\n\n\n::\n\n    if (!CreateEnv) {\n        fprintf(stderr, \"failed to load CreateScriptEnvironment()\\n\");\n        FreeLibrary(avsdll);\n        return 1;\n    }\n\n\nWhen CreateEnv is NULL (so GetProcAddress failed to retrieve the\nexported function) an error is written to the console. `FreeLibrary`_\nfrees the module from your memory.\n::\n\n    env = CreateEnv(AVISYNTH_INTERFACE_VERSION);\n\n\nThis creates the script environment. Its members can be accessed by\n:ref:`env->... <cplusplus_iscriptenvironment>`.\n::\n\n    AVS_linkage = env->GetAVSLinkage();\n\n\nThis gets the server pointers static storage :doc:`AVS_Linkage <AVSLinkage>`.\n::\n\n    AVSValue arg(infile);\n    AVSValue res = env->Invoke(\"Import\", AVSValue(&arg, 1));\n\n\nThis calls the `Import`_ function on the input file infile. So the\nscript is loaded.\n::\n\n    if (!res.IsClip()) {\n        fprintf(stderr, \"Error: '%s' didn't return a video clip.\\n\", infile);\n        FreeLibrary(avsdll);\n        return 1;\n    }\n\n\nf the return value of the script is not a clip an error is written to\nthe console.\n::\n\n    PClip clip = res.AsClip();\n\n    if (clip->GetVersion() < 5) {\n        fprintf(stderr, \"Error: too old version ('%d') of avisynth.dll loaded.\\nplease install v2.60 or later.\\n\",\n            clip->GetVersion());\n        return 1;\n    }\n\n\nIf the loaded avisynth.dll has an api version earlier than 5 an error\nis thrown. This is needed if you used functionality which doesn't exist\nin older versions. Like using DeleteScriptEnvironment down the road to\ndelete the script environment (yes it is easy to make it compatible\nwith older api versions, but this is just for illustration). So it can\nbe used to force a specific version.\n::\n\n    VideoInfo vi = clip->GetVideoInfo();\n\n\n:ref:`GetVideoInfo <cplusplus_getvideoinfo>` returns a :doc:`VideoInfo <VideoInfo>` structure of the clip.\n::\n\n    if (!vi.HasVideo()) {\n        fprintf(stderr, \"Error: '%s' audio only clip.\\n\", infile);\n        FreeLibrary(avsdll);\n        return 1;\n    }\n\n\nReturns an error if the clip doesn't contain video (in case it contains\nonly audio for example).\n::\n\n    fprintf(stderr, \" %s:\\n\", infile);\n    fprintf(stderr, \" %dx%d,\\n\", vi.width, vi.height);\n    fprintf(stderr, \" %d/%d fps,\\n\", vi.fps_numerator, vi.fps_denominator);\n    fprintf(stderr, \" %d frames,\\n\", vi.num_frames);\n    if (vi.IsYUV()) {\n        colorformat = \"YUV\";\n    } else {\n        colorformat = \"RGB\";\n    }\n    fprintf(stderr, \" %s color format\", colorformat);\n\n\nSome information about the clip is written to the console.\n::\n\n    out_fh = fopen(outfile, \"wb\");\n\n\nCreates an empty binary file and opens it for writing. It returns a\nfile pointer called 'out_fh' here. Nb, 'wb' means write mode and\nbinary.\n::\n\n    if (!out_fh) {\n        fprintf(stderr, \"fopen(\\\"%s\\\") failed\", outfile);\n        FreeLibrary(avsdll);\n        return 1;\n    }\n\n\nWhen failing (thus when out_fh is NULL) an error is written to the\nconsole.\n::\n\n    static const int planes[] = {PLANAR_Y, PLANAR_U, PLANAR_V};\n\n\nAll three planes will be processed. For interleaved formats,\nautomatically, only the first plane (being the whole frame) will be\nwritten to the output file.\n::\n\n    for (int frm = 0; frm < vi.num_frames; ++frm) {\n\n\nRun to all frames in the input file.\n::\n\n    PVideoFrame f = clip->GetFrame(frm, env);\n\n\nGets frame 'frm'.\n::\n\n    for (int p=0; p<3; p++) {\n        int height = f->GetHeight(planes[p]);\n        int rowsize = f->GetRowSize(planes[p]);\n        int pitch = f->GetPitch(planes[p]);\n        const BYTE* data = f->GetReadPtr(planes[p]);\n\n\nGets the height, rowsize, pitch and a read pointer 'data' to the plane.\nSee :doc:`InvertNeg <InvertNeg>` for more information.\n::\n\n    for (int y=0; y<height; y++) {\n        fwrite(data, 1, rowsize, out_fh);\n\n\nWrites 'rowsize' bytes from the block of memory pointed by 'data' to\nthe current position in the file pointer 'out_fh'.\n::\n\n        data += pitch;\n\nMove the read pointer to the next line.\n::\n\n    env->DeleteScriptEnvironment();\n\n\nWhen all frames are processed the script environment is deleted.\n::\n\n    FreeLibrary(avsdll);\n\n\nFrees the library (avisynth.dll) from memory.\n::\n\n    AVS_linkage = 0;\n\n\n::\n\n    } catch(AvisynthError err) {\n        fprintf(stderr, \"\\nAvisynth error:\\n%s\\n\", err.msg);\n        return 1;\n\n\nIf a runtime error occurs, the `try-catch statement`_ catches the\nerror, and it is written to the console.\n::\n\n    fclose(out_fh);\n\n\nCloses the file.\n::\n\n    return 0;\n\n\nThe application executed succesfully, so we return zero.\n\n| todo - static and dynamic linking (see above) -\n| http://msdn.microsoft.com/en-us/library/windows/desktop/ms685090%28v=vs.85%29.aspx\n| http://msdn.microsoft.com/en-us/library/d14wsce5.aspx\n\n____\n\nBack to :doc:`FilterSDK`\n\n$Date: 2014/10/27 22:04:54 $\n\n.. _YUVtoolkit: http://www.yuvtoolkit.com/\n.. _stderr: http://www.cplusplus.com/reference/cstdio/stderr/\n.. _fprintf: http://www.cplusplus.com/reference/cstdio/fprintf/\n.. _fopen: http://www.cplusplus.com/reference/cstdio/fopen/\n.. _fwrite: http://www.cplusplus.com/reference/cstdio/fwrite/\n.. _NULL: http://www.cplusplus.com/reference/cstddef/NULL/\n.. _FILE: http://www.cplusplus.com/reference/cstdio/FILE/\n.. _return: http://www.cplusplus.com/doc/tutorial/functions/\n.. _LoadLibrary: http://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx\n.. _GetProcAddress: http://msdn.microsoft.com/en-us/library/windows/desktop/ms683212(v=vs.85).aspx\n.. _typedef: http://www.cplusplus.com/doc/tutorial/other_data_types/\n.. _FreeLibrary: http://msdn.microsoft.com/en-us/library/windows/desktop/ms683152(v=vs.85).aspx\n.. _Import: http://avisynth.nl/index.php/Import\n.. _try-catch statement: http://avisynth.nl/index.php/Control_structures\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/advancedtopics/color_conversions.rst",
    "content": "\nColor conversions\n=================\n\nwork under construction.\n\nto do:\n`<http://forum.doom9.org/showthread.php?p=1084293#post1084293>`_\n\nShould cover RGB->YUV conversions and lumarange scaling/preservation and when\nto use which conversion.\n\n\nColor conversions\n-----------------\n\n+--------------------------------+---------+---------+------+\n| coefficients                   | Rec.601 | Rec.709 | FCC  |\n+================================+=========+=========+======+\n| Kr : Red channel coefficient   | 0.299   | 0.2125  | 0.3  |\n+--------------------------------+---------+---------+------+\n| Kg : Green channel coefficient | 0.587   | 0.7154  | 0.59 |\n+--------------------------------+---------+---------+------+\n| Kb : Blue channel coefficient  | 0.114   | 0.0721  | 0.11 |\n+--------------------------------+---------+---------+------+\n\n(0.0 <= [Y,R,G,B] <= 1.0) ; (-1.0 < [U,V] < 1.0)\n\nKg = 1 - Kr - Kb\n\n| Y = Kr*R + Kg*G + Kb*B\n| V = (R - Y)/(1-Kr) = R - G * Kg/(1-Kr) - B * Kb/(1-Kr)\n| U = (B - Y)/(1-Kb) = - R * Kr/(1-Kb) - G * Kg/(1-Kb) + B\n\nR = Y + V*(1-Kr)\nG = Y - U*(1-Kb)*Kb/Kg - V*(1-Kr)*Kr/Kg\nB = Y + U*(1-Kb)\n\n\nConverting to programming values\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n**YUV [0,255] <-> RGB [0,255]** (0 <= [r,g,b] <= 255, 0 <= y <= 255, 0 <\n[u,v] < 255)\n\n| y = Y * 255\n| v = V * 127.5 + 128\n| u = U * 127.5 + 128\n| r = R * 255\n| g = G * 255\n| b = B * 255\n\nSubstituting (Y,V,U,R,G,B) in the equations above and multiplying with 127.5\nand respectively 255 gives\n\n| y = Kr*r + Kg*g + Kb*b\n| v - 128 = 0.5*(r - y)/(1-Kr) = 0.5 * r - 0.5 * g * Kg/(1-Kr) - 0.5 * b * Kb/(1-Kr)\n| u - 128 = 0.5*(b - y)/(1-Kb) = - 0.5 * r * Kr/(1-Kb) - 0.5 * g * Kg/(1-Kb) + 0.5 * b\n\n| r = y + 2*(v-128)*(1-Kr)\n| g = y - 2*(u-128)*(1-Kb)*Kb/Kg - 2*(v-128)*(1-Kr)*Kr/Kg\n| b = y + 2*(u-128)*(1-Kb)\n\n**YUV [16,235] <-> RGB [0,255]** (0 <= [r,g,b] <= 255, 16 <= y <= 235, 16 <=\n[u,v] <= 240)\n\n| y = Y * 219 + 16\n| u = U * 112 + 128\n| v = V * 112 + 128\n| r = R * 255\n| g = G * 255\n| b = B * 255\n\n\nReferences\n----------\n\n| http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html\n| ITU BT.601 ...\n| ITU BT.709 ...\n\n$Date: 2010/02/27 14:45:12 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/advancedtopics/colorimetry.rst",
    "content": "\nColorimetry\n===========\n\nWhen playing back video content, several issues might go wrong. The levels\ncould be wrong, resulting in washed out colors (black is displayed as dark\ngray and white is displayed as light gray). This is described in more detail\n`here <http://avisynth.nl/index.php/Luminance_levels>`_. The other issue is\na slight distortion in color (which often looks like a small change in\nbrightness) and this will be described here.\n\nThe problem could arise if your content is created in a different colorspace\nas it is stored later on. Usually it is created in RGB, but stored as YCbCr.\nUpon display it will be converted back again to RGB. This means that two\ncolor conversions will take place. The problem is that there are different\nways of doing this conversion. If the two color conversions are not the same,\nthe displayed content won't be the same as the original content. There are\nmany other colorspaces, but they won't be discussed here. See for example\n`this FAQ <http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html>`_.\n\nSo when converting YCbCr to RGB upon display, the correct color conversion\nstandard (Rec.601 or Rec.709) must be used, namely the one which was used\nwhen storing the content. (Rec.709 and Rec.601 are short for ITU-R BT.709 and\nITU-R BT.601.)\n\n\n----\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\n\nWhat are color conversion standards?\n------------------------------------\n\nThere are multiple ways of doing the YCbCr <-> RGB conversion. The general\nconversion is given by\n\n| ``Y = Kr*R + Kg*G + Kb*B``\n| ``Cb = (B-Y)/(1-Kb)``\n| ``Cr = (R-Y)/(1-Kr) = R - G * Kg/(1-Kr) - B * Kb/(1-Kr)``\n\nand the other way around:\n\n| ``R = Y + Cr*(1-Kr)``\n| ``G = Y - Cb*(1-Kb)*Kb/Kg - Cr*(1-Kr)*Kr/Kg``\n| ``B = Y + Cb*(1-Kb)``\n\nwith (0.0 <= [Y,R,G,B] <= 1.0) ; (-1.0 <= [Cb,Cr] <= 1.0) and Kr + Kg + Kb =\n1.\n\nThe red, green and blue coefficients (Kr,Kg,Kb) are standardized in\nspecifications and there are several of them. Have a look at\n:doc:`Color_conversions <color_conversions>` for examples.\n\n\nHow can I see if the correct standard is used upon playback?\n------------------------------------------------------------\n\nThat's a tough question, because it's hardly possible to notice if the wrong\nstandard is used upon playback. In fact, it's hard to see any difference at\nall between them. Take a look at the following screenshot:\n\n.. image:: pictures/colorimetry.jpg\n\nThe upper picture is shown correctly (using Rec.601), and for the lower one\nthe incorrect standard (Rec.709) is used upon playback. What you notice is\nthat the lower picture is more saturated (i.e. more colorful). But also that\nthe red is shifted a bit to yellow. [The other way around results in a less\nsaturated clip, red shifting towards magenta and blue shifting to cyan.]\n\nSo, how do you know then, which standard to choose upon playback? Well that's\nnot always possible, but you have to know the origin of your file. Also, in\nsome cases, that information can be stored in the header of the file. You\nshould stick to the following guideline:\n\n**If your content is Standard Definition (SD) content use Rec.601 and if your\ncontent is High Definition (HD) content use Rec.709, unless the header of the\ncontent specifies otherwise.** I will elaborate on this in the following\nsections.\n\n\nShould I correct anything when processing my content?\n-----------------------------------------------------\n\nYes, you should correct for it in some cases. It depends on your end format\nand how it is played back. In general, it is save to assume that Rec.601 is\nused for Standard Definition content and Rec.709 for High Definition content\nupon playback. That means that often any specific header information\nregarding colorimetry will be ignored. It will be assumed here that you are\nprocessing with AviSynth.\n\nSuppose you want to encode your content as Standard Definition content (that\nis, height of the encoded video < 720p (720 vertical lines)). If you source\nis MPEG-2 (then the colorimetry information can be stored in its header), get\nthe ColorMatrix plugin, and create the following script:\n::\n\n    # ColorMatrix does a Rec.709 -> Rec.601 conversion, if your source is Rec.709:\n    DGDecode_mpeg2source(\"D:\\source.d2v\", info=3)\n    ColorMatrix(hints=true, dest=2, interlace=false) # use interlace=true for interlaced content\n\nSuppose you want to encode your content as High Definition content (that is,\nheight of the encoded video >= 720p). Create the following script:\n::\n\n    # ColorMatrix does a Rec.601 -> Rec.709 conversion, if your source is Rec.601:\n    DGDecode_mpeg2source(\"D:\\source.d2v\", info=3)\n    ColorMatrix(hints=true, dest=0, interlace=false) # use interlace=true for interlaced content\n\nIf the colorimetry information is not stored in the header (as with DivX/XviD\nfor example), it is not really possible to tell which colorimetry is used to\ncreate it. All that you can do is assume Rec.601 is used for SD content and\nRec.709 is used for HD content, and hope that the assumption is correct. In\nthis case, you can't use the *hints* parameter of ColorMatrix, but you need\nto give the conversion explicitly using the *mode* parameter.\n\n\nHow can I use the correct standard upon playback?\n-------------------------------------------------\n\nWhether this is possible (provided that the wrong standard is used upon play\nback) depends on how your content is being played back. If you use a software\nplayer you need to check whether it has an option to correct it. If you use a\ndirectshow based player (such as WMP or MPC) there are different\npossibilities which are explained below. If the renderer does the YCbCr->RGB\nconversion, you should keep in mind that (as found are out in this\n`thread`_):\n\n-   Windowed/renderless VMR7 and VMR9 use BT.601 for video < 720p (720\n    vertical lines)\n-   Windowed/renderless VMR7 and VMR9 use BT.709 for video >= 720p (720\n    vertical lines)\n\nIf you are using Haali's Video Renderer (get `Haali Media Splitter`_ in order\nto install it) you can choose the color standard.\n\nHave a look `at this thread <http://forum.doom9.org/showthread.php?t=134735>`_ for information about the different renderers.\n\n\nMethod #1: Adjusting graphics driver settings\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nI'm not sure whether this is possible. I need to ask someone ...\n\n\nMethod #2: Convert to RGB32 with ffdshow\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nForcing ffdshow to output RGB32 can help prevent colorimetry issues. Downside\nof this method is that doing this conversion in software increases CPU usage.\n\nTo force RGB32 output in ffdshow, you should uncheck all colorspaces except\nRGB32 on the Output page in ffdshow configuration. It is also recommended to\nenable \"High quality YV12 to RGB conversion\". On the RGB conversion page, you\ncan choose which standard should be assumed, BT.601 or BT709. Choose the\nfirst for SD material, and the latter for HD video.\n\n\nMethod #3: Pixelshader in Media Player Classic\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA pixelshader is a small program that runs on your graphics card and\nprocesses some graphic data. In this case each frame of your video.\n\nMedia Player Classic has a shader called \"BT.601 -> BT.709\". A shader which\ndoes the conversion the other way around is still not available. Use this\nwhen needed.\n\nSome requirements for the pixelshaders in MPC:\n\n-   You need to use a compatible video renderer: VMR-7 (renderless),\n    VMR-9 (renderless), or EVR Custom Presenter.\n-   Surface setting must be set to \"3D surfaces\".\n-   It requires some DirectX components that are not included with a\n    default Windows installation. Run the DirectX Web Installer to get the\n    required DirectX updates.\n\n\nMethod #4: Use AviSynth script in ffdshow video decoder\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThere are two ways to do this. The first one is to use the ColorMatrix\nplugin, as explained in one of the previous sections, and the other one is to\nconvert to RGB using the appropriate matrix:\n\n.. image:: pictures/ffdshow_avisynth2.jpg\n\n\nHere ffdshow will convert your content to RGB using Rec.601.\n\n\nWhat do the specifications say about which colorimetry is supported in a particular format?\n-------------------------------------------------------------------------------------------\n\n\nVCD/MPEG-1\n~~~~~~~~~~\n\nPart 2 of the MPEG-1 standard covers video and is defined in ISO/IEC-11172-2.\nIt is heavily based on H.261. The colorimetry information is not written into\nthe header.\n\n\nDVD/MPEG-2\n~~~~~~~~~~\n\nThe DVD specs are not publicly available for free, and I don't know people\nwho have read those specs. The DVD specs should be a subset of the MPEG-2\nspecs (yes I know, that's a big assumption), and the latter is available for\nfree. It says the following:\n\n*The older 1995 MPEG-2 spec (ISO/IEC 13818-2: 1995 (E)) says*\n\n\"In the case that sequence_display_extension() is not present in the\nbitstream or colour_description is zero the matrix coefficients are assumed\nto be those corresponding to matrix_coefficients having the value 1.\" The\nvalue 1 stands for \"1 Recommendation ITU-R BT.709\". Note that in 1995 the\nfirst DVD titles came out, so when making those specs, the DVD didn't exist\nyet. In 2000, the MPEG-2 specs have changed with respect to this:\n\n*The newer `2000 MPEG-2 spec (ITU-T Rec.H262 (2000 E))`_ says*\n\n\"In the case that sequence_display_extension() is not present in the\nbitstream or colour_description is zero the matrix coefficients are assumed\nto be implicitly defined by the application.\" The matrix coefficients are\ndescribed in \"Table 6-9 - Matrix Coefficients\".\n\nIn other words if sequence_display_extension is not present, the colorimetry\ncan be anything.\n\n\nThe ATSC standard\n~~~~~~~~~~~~~~~~~\n\n*Just for kicks,* `ATSC standard on page 18`_ *talks about colorimetry and the\nassumptions to make when 'sequence_display_extension' does not tell you what\nto do*:\n\n   \"The values for color_primaries, transfer_characteristics, and\n   matrix_coefficients shall be explicitly indicated in the\n   sequence_display_extension. While all values for color_primaries,\n   transfer_characteristics, and matrix_coefficients defined in Tables 6-7, 6-8,\n   and 6-9 of ISO/IEC 13818-2 [16, 18] are allowed in the transmitted bit\n   stream, it is noted that ITU-R BT.709 [27] and SMPTE 170M are the most likely\n   to be in common use.\n\nNote: Some previously-encoded legacy material may not have the colorimetry\n(i.e., color_primaries, transfer_characteristics, and matrix_coefficients)\nexplicitly indicated in the sequence_display_extension, in which case the\ncolorimetry is most likely ITU-R BT.709 for all formats except those formats\nwith vertical_size_value = 480, which are most likely to have colorimetry\naccording to SMPTE 170M.\" *As noted by* `hkazemi <http://forum.doom9.org/showthread.php?p=1089854#post1089854>`_\n\n\nMPEG-4/ASP\n~~~~~~~~~~\n\nThe colorimetry information is not written into the header.\n\n\nMPEG-4/AVC\n~~~~~~~~~~\n\n*ITU-T Rec. H.264 (2005)/Amd.1 (06/2006) says*\n\n\"When the matrix_coefficients syntax element is not present, the value of\nmatrix_coefficients shall be inferred to be equal to 2. That is: Image\ncharacteristics are unknown or are determined by the application.\" The matrix\ncoefficients are described in \"Table E-5 - Matrix coefficients\".\n\n\nApplication defaults\n~~~~~~~~~~~~~~~~~~~~\n\nIn `Video Mystified`_, the author Keith Jack gives the following table (as\nnoted by `ariga`_; see: Table 13.16. MPEG-2 matrix_coefficients Codewords.)\n::\n\n    Sequence Display Extension:\n\n    Color_primaries\n    This optional 8-bit codeword describes the chromaticity coordinates of the source\n    primaries, as shown in table. If sequence_display_extension is not present, or\n    color_description = 0, the indicated default value must be used. This information\n    may be used to adjust the color processing after MPEG-2 decoding to compensate for\n    the color primaries of the display.\n\n     -----------------------------------------------------------------------------------\n    |    Color Primaries     |    Code     |          Application Default               |\n    |------------------------|-------------|--------------------------------------------|\n    | forbidden              |  0000 0000  |                                            |\n    | BT.709, SMPTE 274M     |  0000 0001  | MPEG-2, ATSC, DVB 25Hz HDTV, DVB 30Hz HDTV |\n    | unspecified            |  0000 0010  |                                            |\n    | reserved               |  0000 0011  |                                            |\n    | BT.470 system M        |  0000 0100  | DVD-Video 30 Hz                            |\n    | BT.470 system B, G, I  |  0000 0101  | DVD-Video 25 Hz, DVB 25Hz SDTV             |\n    | SMPTE 170M             |  0000 0110  | DVD-Video 30 Hz, DVB 30Hz SDTV             |\n    | SMPTE 240M             |  0000 0111  |                                            |\n    | reserved               |  0000 1000  |                                            |\n    | :                      |      :      |                                            |\n    | reserved               |  1111 1111  |                                            |\n     -----------------------------------------------------------------------------------\n\n| `dragongodz`_ claims this table should be interpreted as follows:\n| *Having finally heard back from a person who is in the professional encoder\n  industry (no I will not say who), I have more reliable information.: \"The\n  table is actually the limitation of what you can use. In other words if you\n  set the sequence_display_extension to Rec.709 for dvd it is illegal. That\n  doesn't mean it will not play etc it just means that it is not supported and\n  any player that strictly follows the specs is more likely just to ignore it\n  as if no value was set at all.\"*\n\n\nReferences\n----------\n\n-   `<http://forum.doom9.org/showthread.php?t=131169>`_\n-   `<http://forum.doom9.org/showthread.php?t=133982>`_\n-   `<http://forum.doom9.org/showthread.php?p=1089979>`_\n-   `<http://forum.doom9.org/showthread.php?t=133982#post1090068>`_\n\n$Date: 2025-02-25 17:29:24-05:00 $\n\n.. _thread: http://forum.doom9.org/showthread.php?t=82217&page=24\n.. _Haali Media Splitter: http://haali.cs.msu.ru/mkv/\n.. _2000 MPEG-2 spec (ITU-T Rec.H262 (2000 E)):\n    http://www.itu.int/rec/T-REC-H.262/en\n.. _ATSC standard on page 18:\n    http://www.atsc.org/standards/a_81.pdf\n.. _Video Mystified: http://www.amazon.com/Video-Demystified-Keith-Jack/dp/187870723X\n.. _ariga: http://forum.doom9.org/showthread.php?p=1075105#post1075105\n.. _dragongodz: http://forum.doom9.org/showthread.php?p=1089979#post1089979\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/advancedtopics/hybrid_video.rst",
    "content": "\nAviSynth, variable framerate (vfr) video and hybrid video\n=========================================================\n\nThere are two kinds of video when considering framerate, constant framerate\n(cfr) video and variable framerate (vfr) video. For cfr video the frames have\na constant duration, and for vfr video the frames have a non-constant\nduration. Many editing programs (including VirtualDub and AviSynth) assume\nthat the video is cfr, partly because avi doesn't support vfr. This won't\nchange in the near future for `various reasons`_. Although the avi container\ndoesn't support vfr, there are several containers (mkv, mp4 and wmv/asf for\nexample) which do support vfr.\n\nHybrid video is commonly defined as being a mix of pulled-down material and\nnon-pulled-down material (where the pulldown can be of fields, as in standard\n3:2 pulldown, or full frames). It's not relevant whether the pulldown is hard\n(the fields/frames are duplicated before the encoding) or soft (adding the\nappriopriate flags in the stream which indicate which fields/frames should be\nduplicated during playback). So, it can be either cfr or vfr. Thus hybrid\nvideo is simply video with different base framerates (for example 8, 12, and\n16 fps at which anime is often drawn). The base framerate is the rate before\nany pulldown. What makes hybrids challenging is the need to decide what final\nframerate to use.\n\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\n\nVariable framerate and hybrid video\n-----------------------------------\n\nIt's important to understand that usually video is cfr. There is one example\nwhere converting to vfr can be very useful, which is hybrid video. Hybrid\nvideo is video with different base framerates (for example 8, 12, and 16 fps\nat which anime is often drawn). The most common example of hybrid video\nconsists of parts that are interlaced/progressive NTSC (29.97 fps) and other\nparts which are FILM (telecined from 23.976 fps to 29.97 fps). For soft\npulldown, the NTSC part (also called video part) is played back at 29.97 fps\nand the telecined part also by duplicating fields (to go from 23.976 fps to\n29.97 fps). For hard pulldown, it is played back at 29.97 fps without adding\nany fields. Other examples of hybrid video include many of the modern anime\nTV Series, many of the Sci-Fi TV Series, such as Stargate: SG1, Star Trek:\nTNG, and Babylon 5), and many of the \"Making Of\" documentaries included on\nDVD.\n\nExamples of hybrid video include many of the modern anime TV Series, many of\nthe Sci-Fi TV Series (such as Stargate: SG1, Star Trek: TNG, and Babylon 5),\nand many of the \"Making Of\" documentaries included on DVD.\n\nThe TIVTC package is designed to work with hybrid video losslessly, while the\nDecomb package has routines to convert to cfr via blending.\n\n\nHow to recognize vfr content (mkv/mp4)\n--------------------------------------\n\nHere are some ways to determine if the mkv/mp4 is vfr:\n\n*mpeg-2:* DGIndex will report a Film/Video percentage, which can tell you\nmuch hybrid content a soft-pulldowned file has. It will not work with hard\npulldown, and isn't always accurate if hard/soft are mixed.\n\n*mkv:* get timecodes file using `mkv2vfr`_ to check this.\n\n*mp4:* this can be found out by using mp4dump (from the `MPEG4 tools by\nMPEG4ip package`_). Open a dos prompt and type (using appropriate paths)\n::\n\n    mp4dump -verbose=2 holly_xvid.mp4 > log.txt\n\nOpen the log file, and look for output like this (look up the stts atom to\nfigure out the length of each frame):\n\n::\n\n    type stts\n           version = 0 (0x00)\n           flags = 0 (0x000000)\n           entryCount = 41 (0x00000029)\n            sampleCount = 3 (0x00000003)\n            sampleDelta = 1000 (0x000003e8)\n            sampleCount[1] = 1 (0x00000001)\n            sampleDelta[1] = 2000 (0x000007d0)\n            sampleCount[2] = 3 (0x00000003)\n            sampleDelta[2] = 1000 (0x000003e8)\n            sampleCount[3] = 1 (0x00000001)\n            sampleDelta[3] = 2000 (0x000007d0)\n            etc ...\n\n| *sampleDelta* indicates how long the frames get displayed and *sampleCount*\n  tells how many frames. Thus on the example above:\n| 3 frames are displayed with length 1000\n| 1 frame are displayed with length 2000\n| 3 frames with length 1000\n| 1 frame with length 2000\n| etc ...\n\nThe time values are not seconds, but \"ticks\", which you have to calculate\ninto seconds via the \"timescale\" value.  This \"timescale\" is stored in\ntimescale atom for the video track (make sure that you look at the right\ntimescale for your track, cause every track has its own timescale). Look for\noutput like this:\n\n::\n\n    type mdia\n        type mdhd\n    ...\n         timeScale = 24976 (0x00006190)\n         duration = 208000 (0x00032c80)\n         language = 21956 (0x55c4)\n         reserved = <2 bytes> 00 00\n\nIn this example the timeScale is 24976. Most of the frames have a length of\n1000. 1000/24976 = 0.04 which means each frame of the first 3 gets displayed\nwith a length of 0.04 seconds, which is the equivalent to 25 fps (1/25 =\n0.04). The next frame has a length of 2000. 2000/24976 = 0.08 which means\nthat it is displayed with a length of 0.08, which is the equivalent to 12.5\nfps (1/12.5 = 0.08). etc ...\n\nThe log file above comes from a video which is in fact hybrid.\n\n\nOpening MPEG-2 hybrid video in AviSynth and re-encoding\n-------------------------------------------------------\n\nAssuming you have hybrid video, there are several ways to encode it. They are\nlisted below. The first method is to convert it to cfr video (either 23.976\nor 29.97 fps). The second one is to encode it at 120 fps using avi and\ndropped frames (where duplicate frames are dropped upon playback). The third\none is to create true vfr using the mkv or mp4 container.\n\n\nencoding to cfr (23.976 fps or 29.97 fps)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nIf we choose the video rate, the video sequences will be OK, but the FILM\nsequences will not be decimated, appearing slightly jumpy (due to the\nduplicated frames). On the other hand, if we choose the FILM rate, the FILM\nsequences will be OK, but the video sequences will be decimated, appearing\njumpy (due to the \"missing\" frames). Additionally, when encoding to 29.97\nfps, you will get lower quality for the same file size, because of the 25%\ngreater number of frames. It's a tough decision which to choose. If the clip\nis mostly FILM you might choose 23.976 fps, and if the clip is mostly video\nyou might choose 29.97 fps. The source also is a factor. If the majority of\nthe video portions are fairly static \"talking heads\", for example, you might\nbe able to decimate them to 23.976 fps without any obvious stutter on\nplayback.\n\nWhen you create your d2v project file you will see whether the clip is mostly\nvideo (NTSC) or FILM (in the information box). However, many of these hybrids\nare encoded entirely as NTSC, with the film portions being \"hard telecined\"\n(the already telecined extra fields having also been encoded) so you'll have\nto examine the source carefully to determine what you have, and how you wish\nto treat it.\n\nThe AviSynth plugins Decomb and TIVTC provide two special decimation modes to\nbetter handle hybrid clips by blending. This will eat bitrate quickly, but it\nappears very smooth. Here is a typical script to enable this mode of\noperation:\n\n::\n\n    Telecide(order=0, guide=1)\n    Decimate(mode=X) # tweak \"threshold\" for film/video detection\n\nor\n\n::\n\n    TFM(mode=1)\n    TDecimate(mode=0,hybrid=X) # tweak \"vidThresh\" for film/video detection\n\nThere are 2 factors that enable Decimate to treat the film and nonfilm\nportions appropriately. First, when Telecide declares guide=1, it is able to\npass information to Decimate about which frames are derived from film and\nwhich from video. For this mechanism to work, Decimate must immediately\nfollow Telecide. Clearly, the better job you do with pattern locking in\nTelecide (by tweaking parameters as required), the better job Decimate can\ndo.\n\nThe second factor is the threshold. If a cycle of frames is seen that does\nnot have a duplicate, then the cycle is treated as video. The threshold\ndetermines what percentage of frame difference is considered to be a\nduplicate. Note that threshold=0 disables the second factor.\n\nMake sure to get the field order correct - DVDs are generally order=1, and\ncaptured video is generally order=0. The included DecombTutorial?.html\nexplains how to determine the field order.\n\n*Mostly Film Clips (mode=3)*\n\nWhen the clip is mostly film, we want to decimate the film portions normally\nso they will be smooth. For the nonfilm portions, we want to reduce their\nframe rate by blend decimating each cycle of frames from 5 frames to 4\nframes. Video sequences so rendered appear smoother than when they are\ndecimated as film. Set Decimate to mode=3, or TDecimate to hybrid=1 for this\nbehavior.\n\nAnother IVTC was developed specifically to handle hybrid material without\nblended frames: SmartDecimate. While you do get \"clean\" frames as a result,\nit also may play with slightly more stutter than does Decomb's result. A\ntypical script might go:\n\n::\n\n    B = TDeint(mode=1) # or KernelBob(order=1)\n    SmartDecimate(24, 60, B)\n\nIn order to keep the result as smooth playing as possible, it will insert the\n\"Smart Bobbed\" frames from time to time.\n\n*Mostly Video Clips (mode=1)*\n\nWhen the clip is mostly video, we want to avoid decimating the video portions\nin order to keep playback as smooth as possible. For the film portions, we\nwant to leave them at the video rate but change the duplicated frames into\nframe blends so it is not so obvious. Set Decimate to mode=1, or TDecimate to\nhybrid=3 for this behavior.\n\nIn this case you may also consider leaving it interlaced and encoding as\nsuch, especially if you'll be watching on a TV later.\n\n\nencoding to cfr - 120 fps\n~~~~~~~~~~~~~~~~~~~~~~~~~\n\nFor this you'll need `TIVTC and avi_tc`_. Start by creating a\n`decimated avi with timecodes.txt <http://avisynth.nl/index.php/VFR>`_,\nbut skip the muxing. Then open tc-gui's tc2cfr tab and add your files or\nuse this command line:\n\n::\n\n    tc2cfr 120000/1001 c:\\video\\video.avi c:\\video\\timecodes.txt c:\\video\\video-120.avi\n\nThen mux with your audio. This works because tc2cfr creates an avi with drop\nframes filling in the extra space with drop frames to create a smooth 120fps\navi.\n\n\n.. _create-vfr-mkv:\n\nencoding to vfr (mkv)\n~~~~~~~~~~~~~~~~~~~~~\n\nFirst download `mkvtoolnix`_. We will use this to mux our video into the MKV\ncontainer WITH a timecode adjustment file. Make sure that you have the latest\nversion (4.9.1 as of this writing), as older ones read timecodes incorrectly.\n\nThere are several AviSynth plugins that you can use to generate the VFR video\nand required timecode file. An example is given below using the\n`Decomb521VFR`_ plugin. Another alternative is the TDecimate plugin contained\nin the `TIVTC`_ package. See their respective documentations to learn more\nabout tweaking them.\n\nThe `DeDup <https://web.archive.org/web/20230116225249/http://avisynth.nl/users/warpenterprises/>`_ plugin removes duplicate frames but does not change the\nframerate (leaving jerky video if not decimated first), so it won't be\nincluded. It can still be used after either method by using their timecodes\nas input to DeDup.\n\n*Decomb521VFR*\n\nAdd this to your script:\n\n::\n\n    Decomb521VFR_Decimate(mode=4, threshold=1.0, progress=true, timecodes=\"timecodes.txt\", vfrstats=\"stats.txt\")\n\nOpen this script in VirtualDub, it will create the timecodes and stats files,\nthen encode. It will seem to freeze at first, because it examines every frame\non the first load.\n\n*TIVTC*\n\nThis is a 2-pass mode. Add this to your script:\n\n::\n\n    TFM(mode=1, output=\"tfm.txt\")\n    TDecimate(mode=4, output=\"stats.txt\")\n\nOpen this and play through it in VirtualDub. Then close it, comment those\nlines out (or start a second script) and add:\n\n::\n\n    TFM(mode=1, input=\"tfm.txt\")\n    TDecimate(mode=5, hybrid=2, dupthresh=1.0, input=\"stats.txt\", tfmin=\"tfm.txt\", mkvout=\"timecodes.txt\")\n\nLoad and encode.\n\n*framerate*\n\nIf you're encoding to a specific size using a bitrate calculator, vfr\ndecimation will mess up the calculations. To make them work again add these\nto your script:\n\nBefore decimation:\n\n::\n\n    oldcount = framecount # this line must be before decimation\n    oldfps = framerate\n\nEnd of script:\n\n::\n\n    averagefps = (float(framecount)/float(oldcount))*oldfps\n    AssumeFPS(averagefps)\n\nNow mux to MKV:\n\n1.  Open mmg.exe (mkvmerge gui)\n2.  Add your video stream file\n3.  Add your audio stream file\n4.  Click on the imported video track\n5.  Browse for the \"timecodes.txt\" timecode file\n6.  Click on the audio track\n7.  If your audio already needs a delay, set one\n8.  Start muxing\n\nTo play it you need a Matroska splitter. For AVC you will need `Haali's\nSplitter`_, but for ASP you can use it or `Gabest's Splitter`_.\n\n\nencoding to vfr (mp4)\n~~~~~~~~~~~~~~~~~~~~~\n\nIf you create a 120 fps avi with drop-frames, however, the mp4 muxed from it\nwill remove them along with any n-vops the encoder creates, leaving vfr. A\nmore laborous way is to encode multiple cfr avi files (some with 23.976 fps\nfilm and some with 29.97 fps video) and join them directly into one vfr mp4\nfile with mp4box and the -cat option.\n\nA third, much easier, method is to encode using the MKV method and then\nprocessing the video with tc2mp4: more details on tc2mp4 can be found on the\n[`Doom9 forums`_].\n\n\nsummary of the methods\n~~~~~~~~~~~~~~~~~~~~~~\n\nSumming up the advantages and disadvantages of the above mentioned methods.\nWhen encoding to 23.976 or 29.97 fps the clip will be cfr (which editors like\nAviSynth and Virtualdub need), but it may look jumpy on playback due to\nduplicated or missing frames. That can be avoided with blending, but encoders\ncan't work as well with that. When encoding to 120 fps using drop frames, the\nclip is cfr, not jumpy on playback, and very compatible. Encoding to mkv\nusing true vfr (using timecodes) neither loses nor duplicates frames, however\nit is not nearly as broadly supported as AVI.\n\n\nOpening non MPEG-2 hybrid video in AviSynth and re-encoding\n-----------------------------------------------------------\n\nIt is possible to open vfr video in AviSynth without losing sync:\nDirectShowSource. The most common formats that support hybrid video (vfr) are\n**mkv**, **mp4**, **wmv**, and **rmvb**, and the methods below work for all\nof them; however, if the source is mkv, you can also use  `mkv2vfr`_ and\nAviSource.\n\n\nopening non-avi vfr content in AviSynth\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe best way to get all frames while keeping sync and timing is to convert to\na common framerate, such as 120 fps for 24/30 (or rather 119.88). (Always use\nconvertfps=true, which adds frames like ChangeFPS, or your audio * will* go\nout of sync.)\n\n::\n\n    DirectShowSource(\"F:\\Hybrid\\vfr.mp4\", fps=119.88, convertfps=true)\n\nYou can also open it as 30p, which then has to be re-decimated but has less\nframes to deal with, or 24p, breaking any 30p sections:\n\nRe-encoding to 23.976 or 29.97 fps:\n\n::\n\n    DirectShowSource(\"F:\\Hybrid\\vfr.mkv\", fps=29.97, convertfps=true) # or fps=23.976\n\nor\n\n::\n\n    DirectShowSource(\"F:\\Hybrid\\vfr_startrek.mkv\", fps=119.88, convertfps=true)\n    FDecimate(29.97) # or FDecimate(23.976)\n\nAnother way is to find out the average framerate (by dividing the total\nnumber of frames by the duration in seconds) and use this rate in\nDirectShowSource. Depending on the duration of a frame, frames will be added\nor dropped to keep sync, and it's almost guaranteed to stutter.\nDirectShowSource will not telecine.\n\n\nre-encoding 120 fps video\n~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe easiest way to convert vfr sources back into vfr in AviSynth is by using\n`DeDup. <http://akuvian.org/src/avisynth/dedup/>`_\n\n1st pass:\n\n::\n\n    DupMC(log=\"stats.txt\")\n\n2nd pass:\n\n::\n\n    DeDup(threshold=.1,maxcopies=4,maxdrops=4,dec=true,log=\"stats.txt\",times=\"timecodes.txt\")\n\nTIVTC can also do this:\n\n1st pass:\n\n::\n\n    TFM(mode=0,pp=0)\n    TDecimate(mode=4,output=\"stats.txt\")\n\n2nd pass:\n\n::\n\n    TFM(mode=0,pp=0)\n    TDecimate(mode=6,hybrid=2,input=\"stats.txt\",mkvout=\"timecodes.txt\")\n\nOnce you've encoded your file, mux back to mkv or 120 fps avi.\n\nThis will chop out all the duplicate frames directshowsource inserts, while\nkeeping framecount and timing nearly identical. But do not use the timecode\nfile from the input video, use the new one. They may not be identical. (Of\ncourse you can play with parameters if you want to use more of the\nfunctionality of dedup.)\n\n\nconverting vfr to cfr avi for AviSynth\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nYou can avoid analysing and decimating by using special tools to get a\nminimal constant-rate avi to feed avisynth. After processing and re-encoding,\nuse tc2cfr or mmg on the output with the original timecodes to regain vfr and\nfull sync. (If you perform any kind of decimation or frame-rate change you'll\nhave to edit the timecode file yourself, although dedup does have a timesin\nparameter.)\n\n*avi*\n\n`avi_tc`_ will create a timecode and normal video, if the avi uses drop\nframes and not n-vops or fully encoded frames. It also requires that no audio\nor secondary tracks are present. To use it, open tc-gui and add your file, or\nuse the following command line:\n\n::\n\n    cfr2tc c:\\video\\video-120.avi c:\\video\\video.avi c:\\video\\timecodes.txt 1\n\n*mkv*\n\n`mkv2vfr`_ extracts all video frames from Matroska to a normal AVI file and a\ntimecode file. This will only work if the mkv is in vfw-mode. The command-\nline to use it is:\n\n::\n\n    mkv2vfr.exe input.mkv output.avi timecodes.txt\n\nencoding to MPEG-2 vfr video\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n`<http://forum.doom9.org/showthread.php?t=93691>`_\n\nI didn't look at it yet, so i can't give any comments/hints.\n\n\nAudio synchronization\n---------------------\n\nSeveral methods are discussed to encode your video (at 23.976, 29.97 or vfr\nvideo). You might wonder why your audio stays in sync regardless of the\nmethod you used to encode your video. Prior to encoding, the video and audio\nhave the same duration, so they start out in sync. The following two\nsituations might occur:\n\n-   you change the framerate of the stream by speeding it up or slowing\n    it down (as is often done by PAL-FILM conversions). This implies that the\n    duration of the video stream will change, and hence the audio stream will\n    become out of sync.\n-   you change the framerate of the stream by adding or removing frames.\n    This implies that the duration of the video stream will remain the same,\n    and hence the audio stream will be in sync.\n\nIf you encode the video stream at 23.976 or 29.97 fps (both cfr) by using\nDecimate(mode=3, threshold=1.0) or Decimate(mode=1, threshold=1.0), frames\nwill be removed or added, and thus your audio stream will be in sync. By a\nsimilar reasoning the vfr encoding will be in sync.\n\nFinally, suppose you open vfr video in AviSynth with DirectShowSource.\nCompare the following\n\n::\n\n    DirectShowSource(\"F:\\Hybrid\\vfr_startrek.mkv\", fps=29.97) # or fps=23.976\n\nand\n\n::\n\n    DirectShowSource(\"F:\\Hybrid\\vfr_startrek.mkv\", fps=29.97, convertfps=true) # or fps=23.976\n\nThe former will be out of sync since 24p sections are speeded up, and the\nlatter will be in sync since frames are added to convert it to cfr.\n\n**To Do:**\n\n-   tc2mp4, subs/Aegisub and ffmpegsource for timecode file:\n    `<http://forums.animesuki.com/showthread.php?t=34738>`_\n    `<http://forum.doom9.org/showthread.php?t=112199>`_\n-   download `WMVTIMES.exe`_.\n-   `subs also <http://forum.doom9.org/showthread.php?t=135889&page=2>`_\n-   `how to determine whether a video (MP4) is vfr or not? <http://forum.doom9.org/showthread.php?t=137899>`_\n-   Wilbert: I don't understand the comment about DeDup in \"encoding to\n    vfr (mkv)\": need to investigate.\n\n\nReferences\n----------\n\nEssential reading:\n\n- `Force Film, IVTC, and Deinterlacing and more`_ (an article written by some people from at doom9).\n- Creating `120 fps video`_.\n- Documentation of `Decomb521VFR`_.\n- About `Decomb521VFR1.0`_ mod for automated Matroska VFR.\n- `Mkvextract GUI`_ by DarkDudae.\n\n*Besides all people who contributed to the tools mentioned in this guide, the\nauthor of this tutorial (Wilbert) would like to thank bond, manono, tritical\nand foxyshadis for their useful suggestions and corrections of this\ntutorial.*\n\n$Date: 2011/12/04 15:28:20 $\n\n.. _various reasons:\n    http://forum.doom9.org/showthread.php?s=&threadid=69132\n.. _mkv2vfr: http://haali.cs.msu.ru/mkv/mkv2vfr.exe\n.. _MPEG4 tools by MPEG4ip package: http://www.rarewares.org/mp4.html\n.. _TIVTC and avi_tc: http://bengal.missouri.edu/~kes25c/\n.. _avi_tc: http://bengal.missouri.edu/~kes25c/\n.. _mkvtoolnix: http://www.bunkus.org/videotools/mkvtoolnix/downloads.html\n.. _Decomb521VFR: http://webpages.charter.net/falconx/decombvfrmod.html\n.. _TIVTC: http://www.missouri.edu/~kes25c/\n.. _Haali's Splitter: http://haali.cs.msu.ru/mkv/\n.. _Gabest's Splitter: http://sourceforge.net/projects/guliverkli/\n.. _Doom9 forums: http://forum.doom9.org/showthread.php?t=112199\n.. _WMVTIMES.exe: http://fcchandler.home.comcast.net/WMVTIMES.exe\n.. _Force Film, IVTC, and Deinterlacing and more:\n    http://www.doom9.org/ivtc-tut.htm\n.. _120 fps video: http://www.masteryoshidino.com/hentai/anime-encoding.htm\n.. _Decomb521VFR1.0:\n    http://forum.doom9.org/showthread.php?s=&threadid=80673\n.. _Mkvextract GUI: http://forum.doom9.org/showthread.php?t=73819\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/advancedtopics/importing_media.rst",
    "content": "\nImporting media into AviSynth\n=============================\n\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\n\nLoading clips into AviSynth\n---------------------------\n\nMost video/audio formats can be loaded into AviSynth, but there are some\nexceptions like swf video, flv4 (VP6) and dvr-ms. If it is not possible to\nload a clip into AviSynth, you will have to convert it into some other format\nwhich can be loaded. Remember to choose a format for which you will have a\nminimal downgrade in quality as a result of the conversion.\n\nIn general there are two ways to load your video into AviSynth:\n\n1.  using an AviSynth filter or plugin which is designed to open some\n    specific format.\n2.  using the :doc:`DirectShowSource <../corefilters/directshowsource>` plugin.\n\nMake sure that your clip contains maximal one video and or one audio stream\n(thus remove the subtitles and remove other video/audio streams). If you want\nto load a clip which contains both video and audio, you have two options:\n\n-   Demux the audio stream and load the streams separately in AviSynth.\n-   Try to load the clip in AviSynth. This might or might not work. For\n    AVIs, make sure you have a good AVI splitter installed [`Gabest AVI\n    splitter`_]. (Yes, Windows comes with an own AVI splitter, which will\n    work in most cases.)\n\nWhen loading a clip into AviSynth it is adviced to follow the following\nguidelines:\n\n-   When it is possible to load your clip into AviSynth using either\n    AviSource or a specific plugin then do so, since this is more reliable\n    than the two alternatives which are listed below.\n-   If the above fails, load your clip using the DirectShowSource plugin.\n-   If the above fails, convert your clip into a different format (into\n    one which is supported by AviSynth).\n\nFor many formats it is explained how to load them in AviSynth, but if your\nformat is not discussed here, there should be enough discussion of how to get\nyou starting. *There are often multiple ways to load your format into\nAviSynth, so if one of them doesn't work, don't forget to try the other ones.\nAs an example, suppose you got an AVI with 5.1 DTS, but it doesn't open as\n5.1 with AviSource. Try other ways, like opening it with DirectShowSource\n(using AC3filter), or demux the audio and load the dts with NicAudio.*\n\n\nLoading clips with video and audio into AviSynth\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n\nAVI with audio\n::::::::::::::\n\nFor loading your AVI with audio you need (1) a VfW (`Video for Windows`_)\ncodec to open (that is decode) your video in AviSynth and an ACM (`Audio\nCompression Manager`_) codec to open your audio in AviSynth. For many video\nand audio format such codecs are available, but certainly not for all of\nthem. Some possible formats (as well as where to download the required\ncodecs) are given below:\n\n+---------+----------------------------------+\n| Format  | ACM codec                        |\n+=========+==================================+\n| MP2     | `QDesign`_                       |\n+---------+----------------------------------+\n| MP3     | `Radium Codec`_ or `Lame ACM`_   |\n+---------+----------------------------------+\n| AC3     | `AC3 ACM codec`_                 |\n+---------+----------------------------------+\n| AC3/DTS | `AC3Filter`_ (The ACM codec      |\n|         | used to return 2 channel output. |\n|         | Dunno if that's still the case.) |\n+---------+----------------------------------+\n| AAC     | `AAC ACM Codec`_                 |\n+---------+----------------------------------+\n| FLAC    | `CoreFLAC ACM`_                  |\n+---------+----------------------------------+\n\nExamples:\n\n::\n\n    AviSource(\"d:\\xvid_dts.avi\")\n\nAlternatively, use DirectShowSource with an AC3/DTS directshow filter like\n`AC3Flter`_ (make sure that downmixing is turned off, unless you want it to\nbe downmixed or it is stereo/mono) and an `AVI-AC3/DTS splitter`_, or\nffdshow (with DTS set to libdts). Use AC3Filter and create the script:\n\n::\n\n    DirectShowSource(\"d:\\xvid_dts.avi\")\n\nFor AAC, use a directshow filter like CoreAAC (make sure downmixing is turned\noff, unless you want it to be downmixed) or ffdshow (with AAC set to libfaad2\nor realaac). We used ffdshow here:\n\n.. image:: pictures/ffdshow_avi_aac.jpg\n\n\nuse the script\n\n::\n\n    DirectShowSource(\"d:\\xvid_aac.avi\")\n\nto load your AVI.\n\nThe number of different video formats which can be found in an AVI is pretty\nlimited. A selection of them:\n\n-   MPEG-4 ASP (install XviD or DivX to decode this format).\n-   MPEG-4 AVC (to be more accurate; video encoded where a subset of the\n    properties of MPEG-4 AVC has been used to create it can be placed into\n    AVI; as far as I know there is no specific x264 VfW DEcoder so you need\n    to open those files with DirectShowSource).\n-   DV (install the `Cedocida codec`_ [`link to codec`_]).\n-   MJPEG: as far as I know there is no free VfW MJPEG decoder (ffdshow\n    can decode them though).\n-   WMV (install the `WM9/VC-1 codecs`_).\n-   `VP7`_.\n\n\n.. _Other containers with audio:\n\nOther containers with audio\n:::::::::::::::::::::::::::\n\nIt is not always possible to load your clips in AviSynth using AviSource (or\none of the specific plugins which will be discussed below). Examples are non-\nAVIs which are clips contained inside a different container, like MKV, MP4,\nRMVB, OGM or ASF/WMV. In that case DirectShowSource is your last bet. It\nmight also be possible that you have an AVI, with an appropriate VfW codec\ninstalled, but you want to use DirectShow codecs to open them in AviSynth. In\nthat case you should also use DirectShowSource.\n\nWhen playing a clip in WMP6.4 (``mplayer2.exe``), DirectShow filters (``*.ax``) are\nused to play it. Those are the same ones which are \"used\" by\nDirectShowSource. So you need to be sure that you have the appropriate\nDirectShow filters installed. To find out which filters are used to play the\nclip, open the clip in WMP6.4 and check under: file -> properties ->\nAdvanced. Here you can also change the settings of the filters. You will get\nmore information about the filters when you open the clip in for example\n`GSpot`_. Just open the clip and press \"1\" under A/V in the \"Proposed Codec\nSolutions and Tests\" box. A \"graph\" is contructed which the filters which are\nused to play it:\n\n.. image:: pictures/directshow_avi_aac.jpg\n\n\n(In case you are wondering, due to my settings in AC3Filter it always shows\nup in the filter chain. But in this example it shouldn't be loaded because it\ndoesn't support AAC.)\n\nIf you got the message \"rendering failed (...)\", it means that the\nappropriate DirectShow filters are not installed. Make also sure the file is\nplaying correctly by pressing the \"2\" under the \"1\". Because if it is not\nplaying, DirectShowSource can't load the clip. In general, you can have the\nfollowing problem with this approach: **other DirectShow filters are used to\nplay the media file than the ones you installed or you want to use. This can\nhappen because the used filters have a higher merit (playing priority) than\nthe ones you want to use**. There are two solutions for this problem:\n\n1.  change the merit of the used filter using `Radlight Filter Manager`_.\n2.  use `GraphEdit (last post of the thread)`_ to contruct a graph using\n    the DirectShow filters of your choice and load that graph with\n    DirectShowSource.\n\nThis will be discussed in the sections \":ref:`Changing the merit of DirectShow\nFilters <merit>`\". and \":ref:`Using GraphEdit to make graphs of DirectShow filters and how\ndo I load these graphs in AviSynth <graphs>`\".\n\nLuckily you can install `ffdshow`_ (which comes with several DirectShow\ndecoders), which is able to decode many formats. For example:\n\n-   MPEG1/2: enable mpeg1/2 by selecting the libavcodec or libmpeg2\n    library:\n\n.. image:: pictures/ffdshow_m2p.jpg\n\n-   MJPEG in AVI: enable mjpeg by selecting the libavcodec library.\n-   DV in AVI: enable DV by selecting the libavcodec library.\n-   MPEG-4 ASP in OGM: xxx\n-   MKV / MP4 / TS\n-   h.264 in MKV/MP4: install xxx and use ffdshow\n-   h.264 in TS: install Haali splitter and use ffdshow (or CoreAVC)\n-   h.263 in FLV1: get the [`flv splitter`_] and enable h.263 playback by\n    selecting the libavcodec library.\n\nExample:\n\nLoad MP4 (video: h.264, audio: aac) using DirectShowSource and ffdshow (aac\ndecoding enabled in ffdshow; when the audio is AC3 or DTS you can also use\nAC3Filter instead). Your script becomes for example:\n\n::\n\n    # adjust fps if necessary\n    DirectShowSource(\"d:\\x264_aac.mp4\", fps=25, convertfps=true)\n\n*some other formats:*\n\n* RM/RMVB (RealMedia / RealMedia Variable Bitrate; usually containing Real\n  Video/Audio): install the `rmvb splitter`_ and the Real codecs by installing\n  RealPlayer/`RealAlternative`_. Create the script:\n\n::\n\n    # adjust fps if necessary\n    DirectShowSource(\"d:\\clip.rmvb\", fps=25, convertfps=true)\n\n* WMV/ASF (Windows Media Video / Advanced Systems Format; usually containing\n  WMV/WMA): this format is not fully supported by ffdshow, so you will have to\n  install wmv codecs. Get `WMF SDK v9 for W2K or later for XP/Vista`_ which\n  contains the codecs (and the DMO wrappers necessary to use DMO filters in\n  DirectShow). (Note that Microsoft's own VC1 codec is not supported in W2K\n  since you need WMF SDK v11.) Create the script:\n\n::\n\n    # adjust fps if necessary\n    DirectShowSource(\"d:\\clip.wmv\", fps=25, convertfps=true)\n\nIf the source material has variable framerate video, read this helpful\n:doc:`guide <hybrid_video>`.\n\n\nLoading video clips into AviSynth\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nAs already explained, in general there are two ways to load your video into\nAviSynth:\n\n1.  using an AviSynth plugin which is designed to open some specific\n    format.\n2.  using the DirectShowSource plugin.\n\nA list of all these plugins and their accepted formats is given below.\n\n*1) AviSynth filters and plugins which are designed to open specific\nformats:*\n\n*AviSource - AVI/VDR:*\n\n:doc:`AviSource <../corefilters/avisource>` supports all kind of AVIs with MP3 (VBR MP3) or AC3 audio. It\nalso supports DV type 1 and type 2, and VirtualDub frameserver files (VDR).\n\nAn AVI can be loaded in AviSynth provided you have an appropriate VfW codec\ninstalled which can be used to decode the AVI. The default codec which is\nused to decode the AVI is specified in the beginning of the media file (in\nits header) itself as the FourCC (FOUR Character Code). From v2.55, an option\nfourCC is added, which lets you use other codecs to load your AVI in\nAviSynth.\n\nA few examples:\n\n::\n\n    AviSource(\"d:\\filename.avi\")\n\nor without the audio:\n\n::\n\n    AviSource(\"d:\\filename.avi\", false)\n\nForcing a decoder being used for loading the clip into AviSynth:\n\n::\n\n    # load your avi using the XviD codec:\n    # opens an avi (for example DivX3) using the XviD Codec\n    AviSource(\"d:\\filename.avi\", fourCC=\"XVID\")\n\n    # load your dv-avi using the Canopus DV Codec:\n    AviSource(\"d:\\filename.avi\", fourCC=\"CDVC\")\n\n    # vdr-files (VirtualDub frameserver files):\n    AviSource(\"d:\\filename.vdr\")\n\nIf AviSynth is complaining about not being able to load your avi  (couldn't\ndecompress ...) you need to install an appropriate codec. GSpot, for example,\nwill tell you what codec you need to install in order to be able to play your\navi.\n\n*Mpeg2Source/DGDecode - MPEG1/MPEG2/VOB/TS/PVA:*\n\nDGDecode (old version Mpeg2Dec3) is an external plugin and supports MPEG-1,\nMPEG-2 / VOB, TS and PVA streams. Open them into DGIndex (or Dvd2avi\n1.76/1.77.3 for Mpeg2Dec3) first and create a d2v script which can be opened\nin AviSynth (note that it will only open the video into AviSynth):\n\nA few examples:\n\n::\n\n    # old Mpeg2dec3; if you need a d2v script\n    # which is created with dvd2avi 1.76/1.77.3\n    LoadPlugin(\"d:\\mpeg2dec3.dll\")\n    mpeg2source(\"d:\\filename.d2v\")\n\n    # DGDecode:\n    LoadPlugin(\"d:\\dgecode.dll\")\n    mpeg2source(\"d:\\filename.d2v\")\n\nNote that Mpeg2Dec3 is very limited compared to DGDecode, because it's\nactually an old version of DGDecode and it only supports MPEG-2 / VOB.\n\n*DGAVCDec - raw AVC/H.264 elementary streams* `[1]`_\n\nDGAVCIndex: Index your raw AVC/H.264 stream.\n\nMake an Avisynth script to frameserve the video:\n\n::\n\n    LoadPlugin(\"d:\\DGAVCDecode.dll\")\n    AVCSource(\"d:\\file.dga\")\n\n*RawSource - raw formats with/without header:*\n\nThe external plugin RawSource supports all kinds of raw video files with the\nYUV4MPEG2 header and without header (video files which contains YUV2, YV16,\nYV12, RGB or Y8 video data).\n\nExamples:\n\n::\n\n    # This assumes there is a valid YUV4MPEG2-header inside:\n    RawSource(\"d:\\yuv4mpeg.yuv\")\n\n    # A raw file with RGBA data:\n    RawSource(\"d:\\src6_625.raw\",720,576,\"BGRA\")\n\n    # You can enter the byte positions of the video frames\n    # directly (which can be found with yuvscan.exe).  This\n    # is useful if it's not really raw video, but e.g.\n    # uncompressed MOV files or a file with some kind of header:\n    RawSource(\"d:\\yuv.mov\", 720, 576, \"UYVY\", \\\n        index=\"0:192512 1:1021952 25:21120512 50:42048512 75:62976512\")\n\n*QTSource (with QuickTime 6 or 7) and QTReader - MOV/QT:*\n\nThere are two ways to load your quicktime movies into AviSynth (and also\nRawSource for uncompressed movs): QTSource and QTReader. The former one is\nvery recent and able to open many quicktime formats (with the possibility to\nopen them as YUY2), but you need to install QuickTime player in order to be\nable to use this plugin. The latter one is very old, no installation of a\nplayer is required in order to be able to open quicktime formats in AviSynth.\n\n*QTSource:*\n\nYou will need Quicktime 6 for getting video only or Quicktime 7 for getting\naudio and video.\n\n::\n\n    # YUY2 (default):\n    QTInput(\"FileName.mov\", color=2)\n\n    # with audio (in many cases possible with QuickTime 7)\n    QTInput(\"FileName.mov\", color=2, audio=1)\n\n    # raw (with for example a YUYV format):\n    QTInput(\"FileName.mov\", color=2, mode=1, raw=\"yuyv\")\n\n    # dither = 1; converts raw 10bit to 8bit video (v210 = 10bit uyvy):\n    QTInput(\"FileName.mov\", color=2, dither=1, raw=\"v210\")\n\n*QTReader:*\n\n::\n\n    # If that doesn't work, or you don't have QuickTime,\n    # download the QTReader plugin (can be found in\n    # Dooms download section):\n    LoadVFAPIPlugin(\"C:\\QTReader\\QTReader.vfp\", \"QTReader\")\n    QTReader(\"C:\\quicktime.mov\")\n\n*Import filter - AviSynth scripts:*\n\nJust import the script using :doc:`Import <../corefilters/import>` at the beginning of your script:\n\n::\n\n    Import(\"d:\\filename.avs\")\n\nIn v2.05 or more recent version you can use the autoplugin loading. Just move\nyour AVS-file in the plugin folder containing the other (external) plugins,\nand rename the extension to 'avsi'. See also :doc:`FAQ <../faq/faq_sections>` for more discussion.\n\n*2) DirectShowSource:*\n\nHave a look at section \":ref:`Other containers with audio`\"\nfor more information.\n\n\nLoading audio clips into AviSynth\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nMost audio formats can be loaded in AviSynth, but there are some exceptions\nlike MPL or multichannel WMA using W98/W2K. If it is not possible to load a\nclip in AviSynth, you will have to convert it to some other format which can\nbe loaded. Remember to choose a format for which you will have a minimal\ndowngrade in quality as a result of the conversion.\n\nIn general there are two ways to load your audio into AviSynth:\n\n1.  using an AviSynth plugin which is designed to open some specific\n    format.\n2.  using the DirectShowSource plugin.\n\nA list of all these plugins and their accepted formats are given below, but\nit is advised to load your clips using a specific format plugin (thus option\n(1)), because it is more reliable than using the DirectShowSource plugin.\n\n\nAviSynth filters and plugins which are designed to open specific formats\n::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\n\n\nWavSource - WAV\n...............\n\n:doc:`WavSource <../corefilters/avisource>` supports all kind of WAVs, such as uncompressed WAV or\nMP3/MP3/AC3/DTS audio with a WAVE header. A WAV can be loaded in AviSynth\nprovided you have an appropriate `ACM codec`_ installed which can be used to\ndecode the WAV. The default codec which is used to decode the WAV is\nspecified in the beginning of the media file (in its header; a bit similar as\nfourCC for video codecs).\n\n\nAudio: MP2/MP3 with a WAVE header\n.................................\n\nThere is an ACM codec for MP2 called [`QDesign`_]. There are  ACM codecs for\nMP3 [`Radium Codec`_] or [`Lame ACM`_].\n\n\nAudio: AC3/DTS with a WAVE header (also called DD-AC3 and DTSWAV)\n.................................................................\n\nThere is an ACM codec for AC3 called [`AC3 ACM codec`_]. There is an ACM\ncodec for AC3/DTS called [`AC3Filter`_].\n\nExample:\n\n::\n\n    # DTS in WAV:\n    V = BlankClip(height=576, width=720, fps=25)\n    A = WAVSource(\"D:\\audio_dts.wav\")\n    AudioDub(V, A)\n\nor if you have WinDVD platinum, install `hypercube's DTSWAV filter`_.\n\nMPASource - MP1/MP2/MP3/MPA\n...........................\n\nExample:\n\n::\n\n    LoadPlugin(\"C:\\Program Files\\AviSynth25\\plugins\\mpasource.dll\")\n    V = BlankClip(height=576, width=720, fps=25)\n    A = MPASource(\"D:\\audio.mp3\", normalize = false)\n    AudioDub(V, A)\n\nNicAudio - MP1/MP2/MP3/MPA/AC3/DTS/LPCM\n.......................................\n\nSome examples:\n\n::\n\n    LoadPlugin(\"C:\\Program Files\\AviSynth25\\plugins\\NicAudio.dll\")\n\n    # AC3 audio:\n    V = BlankClip(height=576, width=720, fps=25)\n    A = NicAC3Source(\"D:\\audio.AC3\")\n    #A = NicAC3Source(\"D:\\audio.AC3\", downmix=2) # downmix to stereo\n    AudioDub(V, A)\n\n    # LPCM audio (48 kHz, 16 bit and stereo):\n    V = BlankClip(height=576, width=720, fps=25)\n    A = NicLPCMSource(\"D:\\audio.lpcm\", 48000, 16, 2)\n    AudioDub(V, A)\n\nBassAudio - MP3/MP2/MP1/OGG/WAV/AIFF/WMA/FLAC/WavPack/Speex/Musepack/AAC/M4A/APE/CDA\n....................................................................................\n\nBassAudio can be downloaded `from here`_. Some examples:\n\n::\n\n    # FLAC files:\n    bassAudioSource(\"C:\\ab\\Dido\\001 Here With Me.flc\")\n\n    # OGG files:\n    bassAudioSource(\"C:\\ab\\Dido\\001 Here With Me.ogg\")\n\n    # AAC files:\n    bassAudioSource(\"C:\\ab\\Dido\\001 Here With Me.aac\")\n\n    # Audio-CD Ripping using this plugin\n    # Download BASSCD 2.2 from official BASS homepage\n    # Extract basscd.dll and rename it to bass_cd.dll\n    # Place bass_cd.dll in the same folder as bassAudio.dll\n    bassAudioSource(\"D:\\Track01.cda\")\n\nDirectShowSource\n::::::::::::::::\n\nHave a look at section \"`Other containers with audio`_\" for more\ninformation. Some directshow filters (besides the ones available in ffdshow)\nfor Ogg Vorbis, Speex, Theora and FLAC can be found `here`_.\n\n\nAudio: MP2/MP3 with a WAVE header\n.................................\n\nUse ffdshow: MP1/2/3 decoding enabled and select mp3lib or libmad.\n\n\nAudio: AC3/DTS with a WAVE header (also called DD-AC3 and DTSWAV)\n.................................................................\n\nUse ffdshow: DTS decoding enabled and uncompressed: support all formats.\n\nExample:\n\n::\n\n    # DTS in WAV:\n    V = BlankClip(height=576, width=720, fps=25)\n    A = DirectShowSource(\"D:\\audio_dts.wav\")\n    AudioDub(V, A)\n\nor making a graph:\n\n::\n\n    # DTS in WAV:\n    # use WAVE parser and ffdshow or AC3filter: [add screenshots]\n    V = BlankClip(height=576, width=720, fps=25)\n    A = DirectShowSource(\"D:\\audio_dts_wav.grf\", video=false)\n    AudioDub(V, A)\n\nAAC\n...\n\nGet an AAC directshow filter like CoreAAC (make sure downmixing is turned\noff, unless you want it to be downmixed;) or ffdshow (with AAC set to libfaad\nor realaac), and use\n\n::\n\n    DirectShowSource(\"d:\\audio.aac\")\n\nto load your AAC. You might need an AAC parser filter for DirectShow. Get one\nhere `[2]`_.\n\n\nLoading images into AviSynth\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n1) Use ImageReader or ImageSource to load your pictures into AviSynth\n   (can load the most popular formats, except GIF and animated formats). See\n   :doc:`internal documentation <../corefilters/imagesource>` for information.\n\n2) Use the Immaavs plugin for GIF, animated formats and other type of\n   pictures.\n\n::\n\n    # single picture:\n    immareadpic(\"x:\\path\\pic.bmp\")\n\n    # animated gif:\n    immareadanim(\"x:\\path\\anim.gif\")\n\n\n.. _merit:\n\nChanging the merit of DirectShow Filters\n----------------------------------------\n\nOpen Radlight Filter Manager and check which of the filters which can be used\nto play your clip has a higher merit. Change the merit of the filter you want\nto use for playback, for example:\n\n.. image:: pictures/filtermanager_ac3.jpg\n\n\nand restart your PC. In my experience this won't always work. In AC3Filter,\nfor example, there is setting called 'Filter Merit\" which is set to 'Prefer\nAC3Filter' by default. Although in my case the merit for AC3Filter was set\nlower than the merit for Moonlight Odio Dekoda (MERIT_NORMAL versus\nMERIT_NORMAL+1), the former was used to play my AC3 (I assume as a result of\nthat 'Prefer AC3Filter' setting in AC3Filter; setting it to 'Prefer other\ndecoder' solves this problem). Other filters might have such settings too.\n\n\n.. _graphs:\n\nUsing GraphEdit to make graphs of DirectShow filters and loading these graphs in AviSynth\n-----------------------------------------------------------------------------------------\n\nAs an example it will be shown how to make a graph where CoreAAC Audio\nDecoder will be used to render the audio in an AVI-AAC file. More accurately\nit will be shown how the ffdshow Audio decoder should be replaced by the\nCoreAAC Audio Decoder, where the former has a higher merit (which implies\nthat filter will be used when playing the clip in a DirectShow based player\nlike WMP6.4 or when opening the AVI directly in AviSynth by using\nDirectShowSource):\n\nOpen GraphEdit and open your clip: File tab -> Open Graph -> Select All Files\n-> open your clip:\n\n.. image:: pictures/directshow_avi_aac2.jpg\n\n\nRight-click on the filter (ffdshow Audio decoder) -> Filter Properties ->\nchange settings if necessary.\n\nGraph tab -> Insert Filters -> under DirectShow Filters -> select CoreAAC\nAudio Decoder:\n\n.. image:: pictures/directshow_avi_aac3.jpg\n\n\nPress Insert Filter. Remove the ffdshow Audio decoder by selecting it and\npressing Delete:\n\n.. image:: pictures/directshow_avi_aac4.jpg\n\n\nFinally, connect the CoreAAC Audio Decoder, by connecting the pins with your\nleft mouse button (arrows will be drawn automatically):\n\n.. image:: pictures/directshow_avi_aac5.jpg\n\n\nCheck and adjust the Filter Properties if necessary. Press play to check that\nthe clip is playable by the selected combation of DirectShow filters. This is\nvery important, because if it's not playable, AviSynth will not be able to\nopen the clip. In that case you should select and or install other filters\nwhich can play the clip.\n\nFinally remove the WaveOut Device and the video filters, because AviSynth\nneeds a free pin to connect itself when DirectShowSource is called in a\nscript.\n\n.. image:: pictures/directshow_avi_aac6.jpg\n\n\nSave the graph as audio.grf. If you want to load the video too in AviSynth,\nit should be loaded separetely, using a different graph (where the audio part\nand the Video Renderer is removed):\n\n.. image:: pictures/directshow_avi.jpg\n\n\nSave the graph as video.grf. Your script becomes:\n\n::\n\n    # change fps if necessary\n    vid = DirectShowSource(\"D:\\video.grf\",\\\n                  fps=25, convertfps=true, audio=false)\n    aud = DirectShowSource(\"D:\\audio.grf\", video=false)\n    AudioDub(vid, aud)\n\nTo Do\n-----\n\n-   The following should be added: tpr, aup, RaWav (>4 GB WAVE files),\n    ffmpegsource,\n-   :ref:`How do I load MP4/MKV/M2TS/EVO into AviSynth`\n-   swf (ffmpegsource) should be added.\n\n$Date: 2013/03/19 18:10:47 $\n\n.. _Gabest AVI splitter:\n    http://sourceforge.net/project/showfiles.php?group_id=82303\n.. _Video for Windows: http://en.wikipedia.org/wiki/Video_for_Windows\n.. _Audio Compression Manager:\n    http://en.wikipedia.org/wiki/Audio_Compression_Manager\n.. _QDesign: http://www.wilbertdijkhof.com/qmpeg_mp2.zip\n.. _Radium Codec: http://www.free-codecs.com/MPEG_Layer_3_Codec_download.htm\n.. _Lame ACM: http://www.free-codecs.com/LAME_ACM_Codec_download.htm\n.. _AC3 ACM codec: http://fcchandler.home.comcast.net/~fcchandler/AC3ACM/\n.. _AC3Filter: http://ac3filter.net/wiki/Download_AC3Filter\n.. _AAC ACM Codec: http://fcchandler.home.comcast.net/~fcchandler/AACACM/\n.. _CoreFLAC ACM: http://www.jorystone.com/2004/09/flac-acm.html\n.. _AC3Flter: http://sourceforge.net/project/showfiles.php?group_id=66022\n.. _AVI-AC3/DTS splitter: http://sourceforge.net/project/showfiles.php?group_id=82303\n.. _Cedocida codec: http://www-user.rhrk.uni-kl.de/~dittrich/cedocida/index.html\n.. _link to codec: http://forum.doom9.org/showthread.php?t=94458\n.. _WM9/VC-1 codecs: http://nic.dnsalias.com/wm9enc.html\n.. _VP7: http://forum.doom9.org/showthread.php?t=97877\n.. _GSpot: http://www.headbands.com/gspot/\n.. _Radlight Filter Manager: http://www.free-codecs.com/download/RadLight_Filter_Manager.htm\n.. _GraphEdit (last post of the thread):\n    http://forum.doom9.org/showthread.php?t=104234\n.. _ffdshow: http://sourceforge.net/project/showfiles.php?group_id=173941\n.. _flv splitter: http://sourceforge.net/project/showfiles.php?group_id=82303\n.. _rmvb splitter: http://sourceforge.net/projects/guliverkli/\n.. _RealAlternative: http://www.free-codecs.com/download/Real_Alternative.htm\n.. _WMF SDK v9 for W2K or later for XP/Vista:\n    http://msdn.microsoft.com/windowsmedia/downloads/default.aspx\n.. _[1]: http://neuron2.net/dgavcdec/dgavcdec.html\n.. _ACM codec:\n    http://en.wikipedia.org/wiki/Audio_Compression_Manager\n.. _hypercube's DTSWAV filter:\n    http://forum.doom9.org/showthread.php?s=&threadid=52692\n.. _from here: http://forum.doom9.org/showthread.php?t=108254\n.. _here: http://www.illiminable.com/ogg/\n.. _[2]: http://www.rarewares.org/aac-decoders.php#aac_parser\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/advancedtopics/interlaced_fieldbased.rst",
    "content": "\nInterlaced and Field-based video\n================================\n\nCurrently (v2.5x and older versions), AviSynth has no interlaced flag which\ncan be used for interlaced video. There is a field-based flag, but contrary\nto what you might expect, this flag is not related to interlaced video. In\nfact, all video (progressive or interlaced) is frame-based, unless you use\nAviSynth filters to change that. There are two filter who turn frame-based\nvideo into field-based video: :doc:`SeparateFields <../corefilters/separatefields>` and :doc:`AssumeFieldBased <../corefilters/parity>`.\n\n-   SeparateFields / Weave\n\n    -   SeparateFields: If needed (for example when denoisers require\n        progressive input), you can split up interlaced streams in their fields\n        by using SeparateFields. The output clip will have twice the framerate of\n        the original clip.\n    -   Weave: After applying a spatial denoiser (for temporal denoisers\n        the situation is a bit more [`involved`_]), the filter Weave can be used\n        to combine the fields again to produce interlaced frames.\n\n-   AssumeFieldBased / AssumeFrameBased\n\n    -   AssumeFieldBased: Applying this filter results in a field-based\n        clip. This can be useful when making \"artificial\" field-based clips.\n    -   AssumeFrameBased: Applying this filter results in a frame-based\n        clip. This can be useful when making \"artificial\" frame-based clips.\n\n\nColor conversions and interlaced / field-based video\n----------------------------------------------------\n\nLet's assume you have **interlaced video**, you want to work in field-based\nmode (to apply some filtering for example) and you also need to do some color\nconversion. Do you need to do the conversion on the frame-based clip or can\nyou do it on the field-based clip? Well, that depends on the\n:doc:`color conversion <../corefilters/convert>` you want to apply:\n\n* YUY2<->RGB conversions can be done on either of them. (Note, that in this\n  case, the setting interlaced=true/false doesn't do anything. It's simply\n  ignored.)\n* YV12<->YUY2/RGB conversions should be done on the frame-based clip (with\n  the **interlaced=true** setting). Doing them on the field-based clip will\n  yield incorrect results. The exact reason of this is outside the scope of\n  this page, but it is a consequence of how the color format YV12 is defined.\n  The main issue is that chroma is shared between pixels on two different lines\n  in a frame. More information can be found here :doc:`Sampling <sampling>`.\n\nThe more experienced users should consider the following. In general,\ninterlaced video has parts where there is no or little movement. Thus, you\nwon't hardly see any interlacing effects (also called combing) in these\nparts. They can be considered progressive, and when doing a YV12<->YUY2/RGB\nconversion on a progressive video you should use the **interlaced=false**\nsetting to get better results. It is possible to the YV12<->YUY2/RGB\nconversion on frame basis while switching between interlaced=true and\ninterlaced=false. Here's how to do it (you will need to have decomb installed\nin order to be able to use the function IsCombed)\n\n::\n\n    function ConvertHybridToYUY2(clip a, int \"threshold\", bool \"debug\")\n    {\n    debug = default(debug, false)\n    global threshold = default(threshold, 20)\n\n    b = ConvertToYUY2(a, interlaced=false)\n    c = ConvertToYUY2(a, interlaced=true)\n    ConditionalFilter(a, b, c, \"IsCombed(threshold)\", \"equals\", \"true\",\n    show=debug)\n    }\n\n    function ConvertHybridToRGB(clip a, int \"threshold\", bool \"debug\")\n    {\n    debug = default(debug, false)\n    global threshold = default(threshold, 20)\n\n    b = ConvertToYUY2(a, interlaced=false)\n    c = ConvertToYUY2(a, interlaced=true)\n    ConditionalFilter(a, b, c, \"IsCombed(threshold)\", \"equals\", \"true\",\n    show=debug)\n    }\n\n    AviSource(\"D:\\captures\\interlaced-clip.avi\") # interlaced YV12\n    #ConvertHybridToYUY2(debug=true)\n    ConvertHybridToYUY2()\n\nHowever, the downside of this is that it may lead to [`chroma shimmering`_]\nin the combed-progressive frame transitions. So, it's not a perfect solution.\n\n\nColor conversions, interlaced / field-based video and the interlaced flag of dvd2avi\n------------------------------------------------------------------------------------\n\nFor the more experienced users. Dvd2avi keeps track of whether a frame is\ninterlaced or progressive (by using the interlaced flag). In principle,\ndvd2avi can be modified to store this in a text-file and AviSynth can read\nand use it on frame-basis. However, it's useless. The problem is that\nsometimes progressive video is encoded as interlaced, and thus is detected as\ninterlaced by dvd2avi. In the previous section, it is explained, that in that\ncase you should use interlaced=false during the YV12<->YUY2/RGB conversion\n(since there's no movement) to get more accurate results. **So, it's the\npresence of combing which is important for the YV12<->YUY2/RGB conversion,\nand not whether a frame is interlaced.**\n\n\nChanging the order of the fields of a clip\n------------------------------------------\n\nThere is a filter which swaps the even/odd fields :doc:`SwapFields <../corefilters/swapfields>`, and a plugin\nwhich reverses the field dominance [`ReverseFieldDominance`_]. The former\nchanges the spatial order and the latter the temporal order.\n\n\nSwapping fields\n^^^^^^^^^^^^^^^\n\nbefore using SwapFields:\n\n+------+---------+\n| line | frame 0 |\n+======+=========+\n| 0    | t0      |\n+------+---------+\n| 1    | b1      |\n+------+---------+\n| 2    | t2      |\n+------+---------+\n| 3    | b3      |\n+------+---------+\n| 4    | t4      |\n+------+---------+\n| 5    | b5      |\n+------+---------+\n\nfield order (top field first then bottom field):\n\n+------+---------+---------+\n| line | field 0 | field 1 |\n+======+=========+=========+\n| 0    | t0      |         |\n+------+---------+---------+\n| 1    |         | b1      |\n+------+---------+---------+\n| 2    | t2      |         |\n+------+---------+---------+\n| 3    |         | b3      |\n+------+---------+---------+\n| 4    | t4      |         |\n+------+---------+---------+\n| 5    |         | b5      |\n+------+---------+---------+\n\nafter using SwapFields:\n\n+------+---------+\n| line | frame 0 |\n+======+=========+\n| 0    | b1      |\n+------+---------+\n| 1    | t0      |\n+------+---------+\n| 2    | b3      |\n+------+---------+\n| 3    | t2      |\n+------+---------+\n| 4    | b5      |\n+------+---------+\n| 5    | t4      |\n+------+---------+\n\nfield order (top field first then bottom field):\n\n+------+---------+---------+\n| line | field 0 | field 1 |\n+======+=========+=========+\n| 0    |         | b1      |\n+------+---------+---------+\n| 1    | t0      |         |\n+------+---------+---------+\n| 2    |         | b3      |\n+------+---------+---------+\n| 3    | t2      |         |\n+------+---------+---------+\n| 4    |         | b5      |\n+------+---------+---------+\n| 5    | t4      |         |\n+------+---------+---------+\n\nNote that the even and odd lines are swapped, so you can call the Top Field\nas Bottom Field, and vice versa.\n\n\nReversing field dominance\n^^^^^^^^^^^^^^^^^^^^^^^^^\n\nbefore reversing the field dominance:\n\n+------+---------+\n| line | frame 0 |\n+======+=========+\n| 0    | t0      |\n+------+---------+\n| 1    | b1      |\n+------+---------+\n| 2    | t2      |\n+------+---------+\n| 3    | b3      |\n+------+---------+\n| 4    | t4      |\n+------+---------+\n| 5    | b5      |\n+------+---------+\n\nfield order (top field first then bottom field):\n\n+------+---------+---------+\n| line | field 0 | field 1 |\n+======+=========+=========+\n| 0    | t0      |         |\n+------+---------+---------+\n| 1    |         | b1      |\n+------+---------+---------+\n| 2    | t2      |         |\n+------+---------+---------+\n| 3    |         | b3      |\n+------+---------+---------+\n| 4    | t4      |         |\n+------+---------+---------+\n| 5    |         | b5      |\n+------+---------+---------+\n\nafter reversing the field dominance (assuming the lines will be shifted up,\nand the last one will be duplicated):\n\n+------+---------+\n| line | frame 0 |\n+======+=========+\n| 0    | b1      |\n+------+---------+\n| 1    | t2      |\n+------+---------+\n| 2    | b3      |\n+------+---------+\n| 3    | t4      |\n+------+---------+\n| 4    | b5      |\n+------+---------+\n| 5    | b5      |\n+------+---------+\n\nfield order (bottom field first then top field):\n\n+------+---------+---------+\n| line | field 0 | field 1 |\n+======+=========+=========+\n| 0    | b1      |         |\n+------+---------+---------+\n| 1    |         | t2      |\n+------+---------+---------+\n| 2    | b3      |         |\n+------+---------+---------+\n| 3    |         | t4      |\n+------+---------+---------+\n| 4    | b5      |         |\n+------+---------+---------+\n| 5    |         | b5      |\n+------+---------+---------+\n\nNote that the top and bottom fields are swapped, but the even and odd lines\nare not swapped.\n\n\nThe parity (= order) of the fields in AviSynth\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nIf a clip is field-based AviSynth keeps track of the parity of each field\n(that is, whether it's the top or the bottom field of a frame). If the clip\nis frame-based it keeps track of the dominant field in each frame (that is,\nwhich field in the frame comes first when they're separated).\n\nHowever, this information isn't necessarily correct, because field\ninformation usually isn't stored in video files and AviSynth's source filters\njust normally default to assuming bottom field first (with the exception of\nthe MPEG2Source plugin which gets it right!).\n\n\nAbout DV / DVD in relation to field dominance\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThe field dominance is not the same for every source. DV (with interlaced\ncontent) has bottom field first, while DVD (or CVD/SVCD) has top field first.\nThus when convert between those two, you need to change the field dominance.\nThis can be done in AviSynth (see above), but also in the encoder itself (for\nbff material like DV footage, you need to set the Upper field first flag).\nSome comments on other [`methods`_].\n\n\nReferences\n^^^^^^^^^^\n\n| [`DV / DVD and field dominance`_]\n| About [`field dominance`_].\n| [`Doom thread`_] about swapped fields and field dominance.\n| [`ReverseFieldDominance`_ plugin]\n\n$Date: 2006/12/15 19:29:25 $\n\n.. _involved:\n    http://www.doom9.org/index.html?/capture/postprocessing_avisynth.html\n.. _chroma shimmering:\n    http://forum.doom9.org/showthread.php?s=&postid=476199#post476199\n.. _ReverseFieldDominance:\n    http://www.geocities.com/siwalters_uk/reversefielddominance.html\n.. _methods:\n    http://forum.doom9.org/showthread.php?s=&postid=410692#post410692\n.. _DV / DVD and field dominance:\n    http://forum.doom9.org/showthread.php?s=&threadid=47393\n.. _field dominance: http://www.lurkertech.com/lg/dominance.html\n.. _Doom thread: http://forum.doom9.org/showthread.php?s=&postid=268353\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/advancedtopics/luminance_levels.rst",
    "content": "\nLuminance levels\n================\n\nWrong levels is a common playback problem. It is a subject that gets\ndiscussed over and over again. The purpose of this topic is to centralize the\ncollective knowledge of the Doom9 community regarding this subject. Everyone\nplease share your knowledge. I'll update the information below to include\nyour wisdom.\n\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\n\nWhat are luminance levels?\n--------------------------\n\nDigital video is typically encoded in a YCbCr format. YCbCr is a family of\ncolor spaces (YV12, YUY2, etc), that encode color information (chroma)\nseparately from brightness information (luma).\n\nThere are two standards for the encoding of luminance. For standard-\ndefinition TV (SDTV) the standard is BT.601, and for high-definition TV\n(HDTV) the standard is BT.709.\n\nLuma values fall in a range. Unfortunately this range is not always the same.\nThere are two commonly used ranges: 0-255 (aka PC levels) and 16-235 (aka TV\nlevels). 'TV levels' were originally created to allow for analog overshoot\nand undershoot `[1]`_. This holds for both the YCbCr and the RGB format.\nUsually, your video is stored in 16-235 YCbCr, but it is played back at 0-255\nRGB. This implies that the levels need to be expanded at some point. But in\nsome cases your video will be stored as 0-255 YCbCr (DV is an example of\nthis), and no expansion is needed.\n\nThus when converting a YCbCr colorspace to RGB, the correct standard (BT.601\nor BT.709) must be used and the correct range (TV or PC levels) must be used.\n\nThe above is not always done correctly. It can go wrong with certain\ncombinations of video renderers, video resolutions and graphics driver\nsettings.\n\n\nHow can I see if the levels are wrong?\n--------------------------------------\n\nThe video looks washed out and the colors are not vivid. Black is displayed\nas dark gray. White is displayed as light gray.\n\nThe opposite is also possible, but more rare. In that case dark colors are\ndisplayed too dark, and light colors are displayed too bright.\n\n\nWhich combinations give wrong levels?\n-------------------------------------\n\nMany factors play a role, so it is not possible to give a list of\ncombinations that always gives wrong levels for everyone. Below is an\n(incomplete) list of situations in which wrong levels are likely to occur\n(when outputting to a PC monitor). This means they will convert YCbCr\n[16,235] to RGB [16,235] (so the levels are not expanded). But in general,\njust trust your eyes.\n\n-   Windows Vista + EVR CP + SD video + ATI\n-   Windows Vista + EVR CP + SD video + NVIDIA\n-   Windows XP + VMR-7 (renderless) + SD video + ATI\n-   Windows XP + VMR-9 (windowed) + SD video + ATI\n-   Windows XP + VMR-9 (renderless) + SD video + ATI\n-   Windows XP + EVR + SD video + ATI\n-   Windows XP + EVR CP + SD video + ATI\n\n(if you have additions to this list, then please post them)\n\n\nHow can I correct the levels?\n-----------------------------\n\nThe methods below assume that you are outputting the video (stored as 16-235\nYCbCr) to a PC monitor or LCD TV, meaning a device that needs full range RGB\n(0-255). If you are using a CRT TV, then read the comments at methods 2 and\n3.\n\n\nMethod #1: Adjusting graphics driver settings\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n**NVIDIA**\n\nSince version 177.84, the NVIDIA drivers have an option for configuring the\nluma range.\n\nYou can find the option here: NVIDIA Control Panel -> Video & Television ->\nAdjust video color settings -> Select \"With the NVIDIA settings\" -> Advanced\ntab -> Set Dynamic Range to \"Full (0-255)\".\n\n.. image:: pictures/nvidia_control_panel.jpg\n\n\n**ATI**\n\nThe ATI driver requires a Registry tweak. With the tweak applied, the driver\nwill convert TV levels to PC levels for SD resolution video. It already does\nthat by default for HD video.\n\nToDo: include idiot proof solution for applying the tweak\n\nSeveral ATI driver tweaks can be found `in this thread`_. The UseBT601CSC setting is\nthe one related to luminance levels.\n\n\nMethod #2: Convert to RGB32 with ffdshow\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nForcing ffdshow to output RGB32 can help prevent luminance level issues.\nDownside of this method is that doing this conversion in software increases\nCPU usage.\n\nTo force RGB32 output in ffdshow, you should uncheck all colorspaces except\nRGB32 on the Output page in ffdshow configuration. It is also recommended to\nenable \"High quality YV12 to RGB conversion\". On the RGB conversion page, you\ncan choose which standard should be assumed, BT.601 or BT709. Choose the\nfirst for low resolution material, and the latter for HD video.\n\nNote: an automatic selection option based on the video resolution will\nhopefully be added in the near future.\n\nTip: the Profiles/Presets feature in ffdshow can be used to create different\nsets of settings. You can even auto-load profiles based on conditions like\nresolution of video format. You could for example create a profile\nspecifically for HD resolution video, and use the 'standard' profile for low\nresolution videos.\n\nNote: When outputting to a CRT TV, you need to select \"Full Range\" contrast.\nFor PC monitors and LCD TVs, the default \"Standard\" contrast setting is\ncorrect.\n\n\nMethod #3: Levels filter in ffdshow video decoder\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nffdshow has a special filter for adjusting (luminance) levels. To correct\nwrong luminance levels for a PC monitor or LCD TV you usually need to convert\nto PC levels. To correct wrong levels for a CRT TV, you usually need to\nconvert to TV levels.\n\nTo convert from TV levels to PC levels use 16-235 as input range and 0-255 as\noutput range. To convert from PC levels to TV levels use 0-255 as input range\nand 16-235 as output range.\n\n\nMethod #4: Pixelshader in Media Player Classic\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA pixelshader is a small program that runs on your graphics card and\nprocesses some graphic data. In this case each frame of your video.\n\nMedia Player Classic has a special pixelshader called \"16-235 -> 0-255\" for\nconverting TV levels to PC levels. This shader only adjusts luma values.\nThere also is a shader called \"BT.601 -> BT.709\". That one is more advanced\nand also adjust chroma values.\n\nNote: the current shaders in MPC always behave the same, regardless of the\nvideo resolution. Since wrong levels may not occur at all resolutions, it is\nnot recommended to have the shaders enabled all the time. Adjusting levels\nwhen no adjustment is needed will lead to suboptimal results.\n\nSome requirements for the pixelshaders in MPC:\n\n-   You need to use a compatible video renderer: VMR-7 (renderless),\n    VMR-9 (renderless), or EVR Custom Presenter.\n-   Surface setting must be set to \"3D surfaces\".\n-   It requires some DirectX components that are not included with a\n    default Windows installation. Run the DirectX Web Installer to get the\n    required DirectX updates.\n\n\nMethod #5: Use AviSynth script in ffdshow video decoder\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nAdjusting levels or conversion to RGB32 can also be done through an AviSynth\nscript in ffdshow. This is for advanced users.\n\nIf your video is stored as 16-235 YCbCr, open the video decoder tab of\nffdshow (here this is done for MPC):\n\n.. image:: pictures/ffdshow_avisynth.jpg\n\n\nCheck the AviSynth box, and create the following script\n\n.. image:: pictures/ffdshow_avisynth2.jpg\n\n\nffdshow will add itself as source. More information can be found `here`_.\n\nIf your video is stored as 0-255 YCbCr, create the following script:\n\n::\n\n    ConvertToRGB(matrix=\"PC.601\") # keep full range video (use matrix=\"PC.709\" when appropriate)\n\nIf your video is stored as 0-255 YCbCr and you want to pass 16-235 YCbCr to\nyour renderer, use\n\n::\n\n    ColorYUV(levels=\"PC->TV\") # convert to TV-levels\n\nMethod #6: Monitor settings\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nSome monitors can be calibrated to assume a certain luminance level as input.\n\n\nMethod #7: Resize in software\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nIf wrong levels occur only with SD video resolutions and not with high\nresolutions, then another solution would be to resize the video in software.\nFor example ffdshow can be used for resizing the video.\n\n\nTest files\n----------\n\nHere are some nice test clips to test your setup: `Test clips`_ (thanks to\nlittleD for making them).\n\n*Thanks `clsid`_ for writing this great article.*\n\n$Date: 2013/03/19 18:10:47 $\n\n.. _[1]: http://en.wikipedia.org/wiki/Rec._601\n.. _in this thread: http://www.avsforum.com/avs-vb/showpost.php?p=11622510&postcount=2011\n.. _here: http://ffdshow-tryout.sourceforge.net/wiki/video:avisynth\n.. _Test clips:\n    http://forum.doom9.org/showthread.php?p=1230259#post1230259\n.. _clsid: http://forum.doom9.org/showthread.php?t=143689\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/advancedtopics/sampling.rst",
    "content": "Sampling\n========\n\n.. note::\n   This page describes the state of AviSynth as of circa 2010, when the only\n   relevant formats were YUY2, YV12 and RGB24/32, and VirtualDub was the\n   primary preview host. Several aspects are now outdated:\n\n   - **YV16 (YUV422P8) and YV24 (YUV444P8)** were introduced in AviSynth 2.6,\n     making YUY2 a legacy compatibility format. Use ``ConvertToYV16`` instead\n     of ``ConvertToYUY2`` where possible.\n   - **Chroma placement-aware resampling** was introduced in AviSynth 2.6 via\n     ``ConvertToPlanarGeneric``, replacing the fixed 0.75/0.25 and 0.5/0.5\n     averaging kernels described in the Upsampling section. The ``chromaresample``,\n     ``ChromaInPlacement`` and ``ChromaOutPlacement`` parameters give full\n     control over the conversion geometry.\n   - **Frame properties** (``_ChromaLocation``, ``_Matrix``, ``_ColorRange``)\n     were introduced in AviSynth+, allowing filters to carry and respect chroma\n     placement metadata automatically.\n   - **The VirtualDub codec upsampling problem** described in the CUE section\n     is specific to the 2010 workflow of delivering YV12 to VirtualDub via a\n     codec. Modern preview and encoding tools handle colorspace conversion\n     independently of AviSynth.\n   - As of AviSynth+ 3.7.6, ``ConvertToYUY2`` and ``ConvertToYV12`` route all\n     conversions through ``ConvertToPlanarGeneric``, so the specific kernel\n     weights (0.75/0.25 interlaced, 0.5/0.5 progressive) documented in the\n     Upsampling section no longer reflect actual AviSynth behavior. The\n     default resampler is bicubic (b=1/3, c=1/3) with MPEG-2 left chroma\n     placement, which is geometrically correct and of higher quality than the\n     historical approximations.\n   - ``ConvertBackToYUY2`` is now an alias for ``ConvertToYUY2``; the\n     left-pixel-only hack described in the RGB→YUY2 subsampling section no\n     longer applies. It is kept for backward compatibility with pre-2.5 scripts.\n     It is now equivalent to ``ConvertToYUY2``, and still accepts only a single \n     ``matrix`` parameter and does not support interlaced material.\n\n   The theoretical sections on color format layouts, chroma subsampling\n   geometry, MPEG-1 vs MPEG-2 sampling, and DV sampling remain accurate\n   and are not affected by the above changes.\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\nColor format conversions and the Chroma Upsampling Error\n--------------------------------------------------------\n\nThe following figures show errors, which are examples of **the Chroma\nUpsampling Error**, called this way because the video is upsampled\nincorrectly (interlaced YV12 upsampled as progressive or vice versa). As a\nresult, you will often see gaps on the top and bottom of colored objects and\n\"ghost\" lines floating above or below the objects.\n\n+---------------------------------------------------------------------------------------------------------------------------+\n| .. image:: pictures/badchroma.jpg                                                                                         |\n+---------------------------------------------------------------------------------------------------------------------------+\n| figure 1a: example of interlaced source (YV12) being upsampled as progressive video (YUY2) (from http://zenaria.com/gfx/) |\n+---------------------------------------------------------------------------------------------------------------------------+\n| .. image:: pictures/goodchroma.jpg                                                                                        |\n+---------------------------------------------------------------------------------------------------------------------------+\n| figure 1b: the same image with correct chroma upsampling (from http://zenaria.com/gfx/)                                   |\n+---------------------------------------------------------------------------------------------------------------------------+\n| .. image:: pictures/badchroma2.jpg                                                                                        |\n+---------------------------------------------------------------------------------------------------------------------------+\n| figure 2a: example of progressive source (YV12) being upsampled as interlaced video (YUY2)                                |\n+---------------------------------------------------------------------------------------------------------------------------+\n| .. image:: pictures/goodchroma2.jpg                                                                                       |\n+---------------------------------------------------------------------------------------------------------------------------+\n| figure 2b: the same image with correct chroma upsampling                                                                  |\n+---------------------------------------------------------------------------------------------------------------------------+\n\nIn this section, it will be shown what causes it, and how to fix it. Where\nfixing mean making it less visible, because it's not possible to correct it\ncompletely.\n\n| References:\n| [`The Chroma Upsampling Error`_]\n| [`The Chroma Upsampling Error - Television and Video Advice`_]\n\n\nChroma Upsampling Error (or CUE)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nAs previously stated, the Chroma Upsampling Error occurs when you convert\nfrom (trully) interlaced YV12 to mostly any other format and the converter\nthinks the video is progressive. Or, the other way around, if material is\nprogressive (or interlaced encoded as progressive), and upsampled as\ninterlaced. This is however not as bad as the other way around.\n\nWhen VDub previews your video, it will need to convert it to RGB. Since\nAviSynth delivers YV12, it asks the codec (for example XviD or DivX) to\nconvert YV12 to RGB. The codec however ALWAYS upsamples progressively. Hence\nyou will get artifacts in VDub preview on interlaced YV12 material. This is\nhowever not present in the YV12 video (or in the resulting encoding). To\nconfirm this, let AviSynth do the conversion by adding\nConvertToRGB(interlaced=true) at the end of your script.\n\n\nCorrecting video having the Chroma Upsampling Error\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nYou will have to blur the chroma in some way (leaving the luma intact).\n\nFor example (using tomsmocomp.dll):\n\n::\n\n    AviSource(...)\n    MergeChroma(TomsMoComp(-1,5,0))\n\nTheoretical Aspects\n-------------------\n\nIn this section, the chroma placement will be explained, how this is related\nto subsampling (RGB -> YUY2 -> YV12) and how the upsampling is done in\nAviSynth.\n\nIt should also explain in detail why the CUE occurs. To summarize the latter,\nthe problem is that there is a difference between YV12 progressive and YV12\ninterlaced, because the chroma is shared vertically between neighboring\npixels.\n\nSee also `<http://forum.doom9.org/showthread.php?s=&threadid=52151&highlight=upsampling>`_.\n\n\nThe color formats: RGB, YUY2 and YV12\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nIn order to be able to understand how YV12 <-> YUY2 sampling works and why it\nmatters whether your source is interlaced or progressive, the YV12/YUY2 color\nformats will be discussed first. It's not important here how they are stored\nin your memory. Information about that can be found in :ref:`Section 2.4 References <References>`.\n\n\nYUV 4:4:4 color format\n::::::::::::::::::::::\n\nThe term 4:4:4 denotes that for every four samples of the luminance (Y),\nthere are four samples each of U and V. Thus each pixel has a luminance value\n(Y), a U value (blue difference sample or Cb) and a V value (red difference\nsample or Cr). Note, \"C\" is just a chroma sample (UV-sample).\n\nThe layout of a 4:4:4 encoded image looks as follows\n\n+-------------+--------+\n| frame       | line   |\n+=============+========+\n| YC YC YC YC | line 1 |\n+-------------+--------+\n| YC YC YC YC | line 2 |\n+-------------+--------+\n| YC YC YC YC | line 3 |\n+-------------+--------+\n| YC YC YC YC | line 4 |\n+-------------+--------+\n\nYUY2 color format\n:::::::::::::::::\n\nYUY2 (or YUYV) is a 4:2:2 format. The term 4:2:2 denotes that for every four\nsamples of the luminance (Y), there are two samples each of U and V, giving\nless chrominance (color) bandwidth in relation to luminance. So for each\npixel, it is horizontally sharing UV (chroma) with a neighboring pixel.\n\nThe layout of a 4:2:2 encoded image looks as follows\n\n+-------------+--------+\n| frame       | line   |\n+=============+========+\n| YC Y YC Y   | line 1 |\n+-------------+--------+\n| YC Y YC Y   | line 2 |\n+-------------+--------+\n| YC Y YC Y   | line 3 |\n+-------------+--------+\n| YC Y YC Y   | line 4 |\n+-------------+--------+\n\nYV12 color format\n:::::::::::::::::\n\nFor the YV12 color format, there's a difference between progressive and\ninterlaced. The cause is that chroma values are also shared vertically\nbetween two neighboring lines.\n\nYV12 is a 4:2:0 format. The term 4:2:0 denotes that for every four samples\n(two horizontal and two vertical) of the luminance (Y), there is one sample\neach of U and V, giving less chrominance (color) bandwidth in relation to\nluminance.\n\n**YV12 progressive**\n\nFor each pixel, it is horizontally sharing UV (chroma or C) with a\nneighboring pixel and vertically sharing UV with the neighboring line (thus\nline 1 with line 2, line 3 with 4, etc).\n\nThe layout of a progressive 4:2:0 encoded image looks as follows (MPEG 2\nscheme - see below)\n\n+-------------+--------+\n| frame       | line   |\n+=============+========+\n| Y_Y_Y_Y     | line 1 |\n+-------------+        +\n| C___C__     |        |\n+-------------+--------+\n| Y_Y_Y_Y     | line 2 |\n+-------------+        +\n|             |        |\n+-------------+--------+\n| Y_Y_Y_Y     | line 3 |\n+-------------+        +\n| C___C__     |        |\n+-------------+--------+\n| Y_Y_Y_Y     | line 4 |\n+-------------+        +\n|             |        |\n+-------------+--------+\n\n\n**YV12 interlaced**\n\nFor each pixel, it is horizontally sharing UV (chroma or C) with a\nneighboring pixel and vertically sharing UV with the next to neighboring line\n(thus line 1t with line 3t, line 2b with 4b, etc).\n\nThe layout of a interlaced 4:2:0 encoded image looks as follows (MPEG 2\nscheme - see below)\n\n+-------------+---------+\n| frame       | line    |\n+=============+=========+\n| Y_Y_Y_Y     | line 1t |\n+-------------+         +\n| C___C__     |         |\n+-------------+---------+\n| Y_Y_Y_Y     | line 2b |\n+-------------+         +\n|             |         |\n+-------------+---------+\n| Y_Y_Y_Y     | line 3t |\n+-------------+         +\n| C___C__     |         |\n+-------------+---------+\n| Y_Y_Y_Y     | line 4b |\n+-------------+         +\n|             |         |\n+-------------+---------+\n\n\nor\n\n+-----------+---------+---------+\n| field 1   | field 2 | line    |\n+===========+=========+=========+\n| Y_Y_Y_Y   |         | line 1t |\n+-----------+---------+---------+\n| C___C__   |         |         |\n+-----------+---------+---------+\n|           | Y_Y_Y_Y | line 2b |\n+-----------+---------+---------+\n|           |         |         |\n+-----------+---------+---------+\n| Y_Y_Y_Y   |         | line 3t |\n+-----------+---------+---------+\n|           | C___C__ |         |\n+-----------+---------+---------+\n|           | Y_Y_Y_Y | line 4b |\n+-----------+---------+---------+\n|           |         |         |\n+-----------+---------+---------+\n\n\nSubsampling\n~~~~~~~~~~~\n\nSubsampling is used to reduce the storage and broadcast bandwidth\nrequirements for digital video. This is effective for a !YCbCr signal because\nthe human eye is more sensitive for changes in black and white than for\nchanges in color. So drastically reducing the color info shows very little\ndifference. YUY2 and YV12 are examples of reduced color formats.\n\n\nRGB -> YUY2 conversion\n::::::::::::::::::::::\n\n| More about RGB -> YUV color conversions can be found here: :doc:`ColorConversions <color_conversions>`.\n| Recall the layout of a 4:4:4 encoded image\n\n+-----------------+--------+\n| frame           | line   |\n+=================+========+\n| YC1 YC2 YC3 YC4 | line 1 |\n+-----------------+--------+\n| YC1 YC2 YC3 YC4 | line 2 |\n+-----------------+--------+\n| YC1 YC2 YC3 YC4 | line 3 |\n+-----------------+--------+\n| YC1 YC2 YC3 YC4 | line 4 |\n+-----------------+--------+\n\nIn AviSynth, the default mode is using a 1-2-1 kernel to interpolate chroma,\nthat is\n\n| C1x = (C1+C1+C1+C2)/4 (C1 is used three times, since this is the border)\n| C3x = (C2+C3+C3+C4)/4\n| C5x = (C4+C5+C5+C6)/4\n\nThe 4:2:2 encoded image becomes\n\n+-------------------+--------+\n| frame             | line   |\n+===================+========+\n| Y1C1x Y2 Y3C3x Y4 | line 1 |\n+-------------------+--------+\n| Y1C1x Y2 Y3C3x Y4 | line 2 |\n+-------------------+--------+\n| Y1C1x Y2 Y3C3x Y4 | line 3 |\n+-------------------+--------+\n| Y1C1x Y2 Y3C3x Y4 | line 4 |\n+-------------------+--------+\n\nThe other mode :doc:`ConvertBackToYUY2 <../corefilters/convert>` uses chroma from the left pixel, thus\n\n+-------------------+--------+\n| frame             | line   |\n+===================+========+\n| Y1C1 Y2 Y3C3 Y4   | line 1 |\n+-------------------+--------+\n| Y1C1 Y2 Y3C3 Y4   | line 2 |\n+-------------------+--------+\n| Y1C1 Y2 Y3C3 Y4   | line 3 |\n+-------------------+--------+\n| Y1C1 Y2 Y3C3 Y4   | line 4 |\n+-------------------+--------+\n\n*Note (as with the layout of other formats) the position of the chroma\nvalues, represent the WEIGHT result of the subsampling.*\n\n**YUY2 -> YV12 interlaced conversion**\n\nRecall the layout of a interlaced 4:2:0 encoded image, but with the weights\nincluded:\n\n+---------+---------+------------------------+\n| frame   | line    | weights                |\n+=========+=========+========================+\n| Y_Y_Y_Y | line 1t |                        |\n+---------+         +------------------------+\n| C___C__ |         || chroma of YUY2_lines  |\n|         |         || (0.75)*1t + (0.25)*3t |\n+---------+---------+------------------------+\n| Y_Y_Y_Y | line 2b |                        |\n+---------+         +------------------------+\n|         |         |                        |\n+---------+---------+------------------------+\n| Y_Y_Y_Y | line 3t |                        |\n+---------+         +------------------------+\n| C___C__ |         || chroma of YUY2_lines  |\n|         |         || (0.25)*2b + (0.75)*4b |\n+---------+---------+------------------------+\n| Y_Y_Y_Y | line 4b |                        |\n+---------+         +------------------------+\n|         |         |                        |\n+---------+---------+------------------------+\n\nor\n\n+---------+---------+---------+------------------------+\n| field 1 | field 2 | line    | weights                |\n+=========+=========+=========+========================+\n| Y_Y_Y_Y |         | line 1t |                        |\n+---------+---------+         +------------------------+\n| C___C__ |         |         || chroma of YUY2_lines  |\n|         |         |         || (0.75)*1t + (0.25)*3t |\n+---------+---------+---------+------------------------+\n|         | Y_Y_Y_Y | line 2b |                        |\n+---------+---------+         +------------------------+\n|         |         |         |                        |\n+---------+---------+---------+------------------------+\n| Y_Y_Y_Y |         | line 3t |                        |\n+---------+---------+         +------------------------+\n|         | C___C__ |         || chroma of YUY2_lines  |\n|         |         |         || (0.25)*2b + (0.75)*4b |\n+---------+---------+---------+------------------------+\n|         | Y_Y_Y_Y | line 4b |                        |\n+---------+---------+         +------------------------+\n|         |         |         |                        |\n+---------+---------+---------+------------------------+\n\n\n*Note (as with the layout of other formats) the position of the chroma\nvalues, represent the WEIGHT as a result of the subsampling.*\n\nThus the chroma is stretched across two luma lines in the same field!\n\n**YUY2 -> YV12 progressive conversion**\n\nRecall the layout of a 4:2:0 encoded image\n\n+---------+--------+-----------------------+\n| frame   | line   | weights               |\n+=========+========+=======================+\n| Y_Y_Y_Y | line 1 |                       |\n+---------+        +-----------------------+\n| C___C__ |        || chroma of YUY2_lines |\n|         |        || (0.5)*1 + (0.5)*2    |\n+---------+--------+-----------------------+\n| Y_Y_Y_Y | line 2 |                       |\n+---------+        +-----------------------+\n|         |        |                       |\n+---------+--------+-----------------------+\n| Y_Y_Y_Y | line 3 |                       |\n+---------+        +-----------------------+\n| C___C__ |        || chroma of YUY2_lines |\n|         |        || (0.5)*3 + (0.5)*4    |\n+---------+--------+-----------------------+\n| Y_Y_Y_Y | line 4 |                       |\n+---------+        +-----------------------+\n|         |        |                       |\n+---------+--------+-----------------------+\n\n\n*Note (as with the layout of other formats) the position of the chroma\nvalues, represent the WEIGHT result of the subsampling.*\n\nThus the chroma is stretched across two luma lines in the same frame!\n\n\nUpsampling\n~~~~~~~~~~\n\n\nYUY2 conversion -> RGB\n::::::::::::::::::::::\n\nRecall the layout of a 4:2:2 encoded image\n\n+-------------------+--------+\n| frame             | line   |\n+===================+========+\n| Y1C1 Y2 Y3C3 Y4   | line 1 |\n+-------------------+--------+\n| Y1C1 Y2 Y3C3 Y4   | line 2 |\n+-------------------+--------+\n| Y1C1 Y2 Y3C3 Y4   | line 3 |\n+-------------------+--------+\n| Y1C1 Y2 Y3C3 Y4   | line 4 |\n+-------------------+--------+\n\nThe C++ and the ASM code use different sampling methods.\n\nFor the C++ code ConvertToRGB uses the same chroma for two RGB pixels using\nleft point upsampling. Thus the 4:4:4 encoded image becomes\n\n+---------------------+--------+\n| frame               | line   |\n+=====================+========+\n| Y1C1 Y2C1 Y3C3 Y4C3 | line 1 |\n+---------------------+--------+\n| Y1C1 Y2C1 Y3C3 Y4C3 | line 2 |\n+---------------------+--------+\n| Y1C1 Y2C1 Y3C3 Y4C3 | line 3 |\n+---------------------+--------+\n| Y1C1 Y2C1 Y3C3 Y4C3 | line 4 |\n+---------------------+--------+\n\nFor the ASM code ConvertToRGB the missing chroma samples are interpolated\n(using a [1 1] kernel), that is\n\n| C2x = (C1+C3)/2\n| C4x = (C3+C5)/2\n\nand the existing chroma samples are just copied.\n\nThe 4:4:4 encoded image becomes\n\n+-----------------------+--------+\n| frame                 | line   |\n+=======================+========+\n| Y1C1 Y2C2x Y3C3 Y4C4x | line 1 |\n+-----------------------+--------+\n| Y1C1 Y2C2x Y3C3 Y4C4x | line 2 |\n+-----------------------+--------+\n| Y1C1 Y2C2x Y3C3 Y4C4x | line 3 |\n+-----------------------+--------+\n| Y1C1 Y2C2x Y3C3 Y4C4x | line 4 |\n+-----------------------+--------+\n\nThe ASM code is the one which is actually used in AviSynth.\n\n\nYV12 interlaced conversion -> YUY2\n::::::::::::::::::::::::::::::::::\n\nIn AviSynth, the missing chroma samples are interpolated as follows\n\n+---------+---------+-------------------------+\n| frame   | line    | weights                 |\n+=========+=========+=========================+\n| Y_Y_Y_Y | line 1t | chroma of YV12_lines 1t |\n+---------+         +-------------------------+\n| C___C__ |         |                         |\n+---------+---------+-------------------------+\n| Y_Y_Y_Y | line 2b | chroma of YV12_lines 4b |\n+---------+         +-------------------------+\n|         |         |                         |\n+---------+---------+-------------------------+\n| Y_Y_Y_Y | line 3t || chroma of YV12_lines   |\n|         |         || (0.75)*1t + (0.25)*5t  |\n+---------+         +-------------------------+\n| C___C__ |         |                         |\n+---------+---------+-------------------------+\n| Y_Y_Y_Y | line 4b || chroma of YV12_lines   |\n|         |         || (0.75)*4b + (0.25)*8b  |\n+---------+         +-------------------------+\n|         |         |                         |\n+---------+---------+-------------------------+\n| Y_Y_Y_Y | line 5t || chroma of YV12_lines   |\n|         |         || (0.25)*1t + (0.75)*5t  |\n+---------+         +-------------------------+\n| C___C__ |         |                         |\n+---------+---------+-------------------------+\n| Y_Y_Y_Y | line 6b || chroma of YV12_lines   |\n|         |         || (0.25)*4b + (0.75)*8b  |\n+---------+         +-------------------------+\n|         |         |                         |\n+---------+---------+-------------------------+\n| Y_Y_Y_Y | line 7t || chroma of YV12_lines   |\n|         |         || (0.75)*5t + (0.25)*9t  |\n+---------+         +-------------------------+\n| C___C__ |         |                         |\n+---------+---------+-------------------------+\n| Y_Y_Y_Y | line 8b || chroma of YV12_lines   |\n|         |         || (0.75)*8b + (0.25)*12b |\n+---------+         +-------------------------+\n|         |         |                         |\n+---------+---------+-------------------------+\n\nor\n\n+---------+---------+---------+-------------------------+\n| field 1 | field 2 | line    | weights                 |\n+=========+=========+=========+=========================+\n| Y_Y_Y_Y |         | line 1t | chroma of YV12_lines 1t |\n+---------+---------+         +-------------------------+\n| C___C__ |         |         |                         |\n+---------+---------+---------+-------------------------+\n|         | Y_Y_Y_Y | line 2b | chroma of YV12_lines 4b |\n+---------+---------+         +-------------------------+\n|         |         |         |                         |\n+---------+---------+---------+-------------------------+\n| Y_Y_Y_Y |         | line 3t || chroma of YV12_lines   |\n|         |         |         || (0.75)*1t + (0.25)*5t  |\n+---------+---------+         +-------------------------+\n|         | C___C__ |         |                         |\n+---------+---------+---------+-------------------------+\n|         | Y_Y_Y_Y | line 4b || chroma of YV12_lines   |\n|         |         |         || (0.75)*4b + (0.25)*8b  |\n+---------+---------+         +-------------------------+\n|         |         |         |                         |\n+---------+---------+---------+-------------------------+\n| Y_Y_Y_Y |         | line 5t || chroma of YV12_lines   |\n|         |         |         || (0.25)*1t + (0.75)*5t  |\n+---------+---------+         +-------------------------+\n| C___C__ |         |         |                         |\n+---------+---------+---------+-------------------------+\n|         | Y_Y_Y_Y | line 6b || chroma of YV12_lines   |\n|         |         |         || (0.25)*4b + (0.75)*8b  |\n+---------+---------+         +-------------------------+\n|         |         |         |                         |\n+---------+---------+---------+-------------------------+\n| Y_Y_Y_Y |         | line 7t || chroma of YV12_lines   |\n|         |         |         || (0.75)*5t + (0.25)*9t  |\n+---------+---------+         +-------------------------+\n|         | C___C__ |         |                         |\n+---------+---------+---------+-------------------------+\n|         | Y_Y_Y_Y | line 8b || chroma of YV12_lines   |\n|         |         |         || (0.75)*8b + (0.25)*12b |\n+---------+---------+         +-------------------------+\n|         |         |         |                         |\n+---------+---------+---------+-------------------------+\n\nThis implementation results in a `chroma shift`_. AviSynth uses a different\ninterpolation as the one suggested by the mpeg2 specs (perhaps due to speed\nissues). The latter is\n\n+---------+---------+---------+-------------------------+\n| field 1 | field 2 | line    | weights                 |\n+=========+=========+=========+=========================+\n| Y_Y_Y_Y |         | line 1t | chroma of YV12_lines 1t |\n+---------+---------+         +-------------------------+\n| C___C__ |         |         |                         |\n+---------+---------+---------+-------------------------+\n|         | Y_Y_Y_Y | line 2b | chroma of YV12_lines 4b |\n+---------+---------+         +-------------------------+\n|         |         |         |                         |\n+---------+---------+---------+-------------------------+\n| Y_Y_Y_Y |         | line 3t || chroma of YV12_lines   |\n|         |         |         || (5/8)*1t + (3/8)*5t    |\n+---------+---------+         +-------------------------+\n|         | C___C__ |         |                         |\n+---------+---------+---------+-------------------------+\n|         | Y_Y_Y_Y | line 4b || chroma of YV12_lines   |\n|         |         |         || (7/8)*4b + (1/8)*8b    |\n+---------+---------+         +-------------------------+\n|         |         |         |                         |\n+---------+---------+---------+-------------------------+\n| Y_Y_Y_Y |         | line 5t || chroma of YV12_lines   |\n|         |         |         || (1/8)*1t + (7/8)*5t    |\n+---------+---------+         +-------------------------+\n| C___C__ |         |         |                         |\n+---------+---------+---------+-------------------------+\n|         | Y_Y_Y_Y | line 6b || chroma of YV12_lines   |\n|         |         |         || (3/8)*4b + (5/8)*8b    |\n+---------+---------+         +-------------------------+\n|         |         |         |                         |\n+---------+---------+---------+-------------------------+\n| Y_Y_Y_Y |         | line 7t || chroma of YV12_lines   |\n|         |         |         || (5/8)*5t + (3/8)*9t    |\n+---------+---------+         +-------------------------+\n|         | C___C__ |         |                         |\n+---------+---------+---------+-------------------------+\n|         | Y_Y_Y_Y | line 8b || chroma of YV12_lines   |\n|         |         |         || (7/8)*8b + (1/8)*12b   |\n+---------+---------+         +-------------------------+\n|         |         |         |                         |\n+---------+---------+---------+-------------------------+\n\n**YV12 progressive conversion -> YUY2**\n\nThe missing chroma samples are interpolated as follows\n\n+---------+--------+------------------------+\n| frame   | line   | weights                |\n+=========+========+========================+\n| Y_Y_Y_Y | line 1 | chroma of YV12_lines 1 |\n+---------+        +------------------------+\n| C___C__ |        |                        |\n+---------+--------+------------------------+\n| Y_Y_Y_Y | line 2 || chroma of YV12_lines  |\n|         |        || (0.75)*1 + (0.25)*3   |\n+---------+        +------------------------+\n|         |        |                        |\n+---------+--------+------------------------+\n| Y_Y_Y_Y | line 3 || chroma of YV12_lines  |\n|         |        || (0.25)*1 + (0.75)*3   |\n+---------+        +------------------------+\n| C___C__ |        |                        |\n+---------+--------+------------------------+\n| Y_Y_Y_Y | line 4 || chroma of YV12_lines  |\n|         |        || (0.75)*3 + (0.25)*5   |\n+---------+        +------------------------+\n|         |        |                        |\n+---------+--------+------------------------+\n| Y_Y_Y_Y | line 5 || chroma of YV12_lines  |\n|         |        || (0.25)*3 + (0.75)*5   |\n+---------+        +------------------------+\n| C___C__ |        |                        |\n+---------+--------+------------------------+\n| Y_Y_Y_Y | line 6 || chroma of YV12_lines  |\n|         |        || (0.75)*5 + (0.25)*7   |\n+---------+        +------------------------+\n|         |        |                        |\n+---------+--------+------------------------+\n\n.. _References:\n\nReferences\n~~~~~~~~~~\n\n| :doc:`ColorSpaces <../FilterSDK/ColorSpaces>`\n| [`4:4:4`_] sampling\n| [`4:2:2`_] sampling\n| [`4:2:0`_] sampling\n| [`Chroma Upsampling`_]\n| [`Chroma Subsampling Standards`_]\n\nFormat-specific sampling\n------------------------\n\nMPEG-1 versus MPEG-2 sampling\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThere are two common variants of 4:2:0 sampling. One of these is used in\nMPEG-2 (and CCIR-601) video, and the other is used in MPEG-1. **The MPEG-2\nscheme is how AviSynth samples 4:2:0 video**, because it completely avoids\nhorizontal resampling in 4:2:0 <-> 4:2:2 conversions.\n\nThe layout of a progressive MPEG-1 4:2:0 encoded image\n\n+---------+--------+-----------------------+\n| frame   | line   | weights               |\n+=========+========+=======================+\n| Y_Y_Y_Y | line 1 |                       |\n+---------+        +-----------------------+\n| _C__C_  |        || chroma of YUY2_lines |\n|         |        || (0.5)*1 + (0.5)*2    |\n+---------+--------+-----------------------+\n| Y_Y_Y_Y | line 2 |                       |\n+---------+        +-----------------------+\n|         |        |                       |\n+---------+--------+-----------------------+\n| Y_Y_Y_Y | line 3 |                       |\n+---------+        +-----------------------+\n| _C__C_  |        || chroma of YUY2_lines |\n|         |        || (0.5)*3 + (0.5)*4    |\n+---------+--------+-----------------------+\n| Y_Y_Y_Y | line 4 |                       |\n+---------+        +-----------------------+\n|         |        |                       |\n+---------+--------+-----------------------+\n\nThe layout of a MPEG-2 4:2:0 encoded image\n\n+---------+--------+-----------------------+\n| frame   | line   | weights               |\n+=========+========+=======================+\n| Y_Y_Y_Y | line 1 |                       |\n+---------+        +-----------------------+\n| C___C__ |        || chroma of YUY2_lines |\n|         |        || (0.5)*1 + (0.5)*2    |\n+---------+--------+-----------------------+\n| Y_Y_Y_Y | line 2 |                       |\n+---------+        +-----------------------+\n|         |        |                       |\n+---------+--------+-----------------------+\n| Y_Y_Y_Y | line 3 |                       |\n+---------+        +-----------------------+\n| C___C__ |        || chroma of YUY2_lines |\n|         |        || (0.5)*3 + (0.5)*4    |\n+---------+--------+-----------------------+\n| Y_Y_Y_Y | line 4 |                       |\n+---------+        +-----------------------+\n|         |        |                       |\n+---------+--------+-----------------------+\n\n\nDV sampling\n~~~~~~~~~~~\n\nFor completeness, we will mention DV sampling. DV is 4:2:0 (PAL) and 4:1:1\n(NTSC). Note, that the sample positioning of the former is different from the\n4:2:0 chroma in MPEG-1/MPEG-2!\n\nThe layout of a 4:2:0 encoded image (field-based)\n\n+---------------------+--------+\n| field               | line   |\n+=====================+========+\n| YV Y YV Y YV Y YV Y | line 1 |\n+---------------------+--------+\n| YU Y YU Y YU Y YU Y | line 2 |\n+---------------------+--------+\n| YV Y YV Y YV Y YV Y | line 3 |\n+---------------------+--------+\n| YU Y YU Y YU Y YU Y | line 4 |\n+---------------------+--------+\n\nThe layout of a 4:1:1 encoded image (field-based)\n\n+-------------------+--------+\n| field             | line   |\n+===================+========+\n| YC Y Y Y YC Y Y Y | line 1 |\n+-------------------+--------+\n| YC Y Y Y YC Y Y Y | line 2 |\n+-------------------+--------+\n| YC Y Y Y YC Y Y Y | line 3 |\n+-------------------+--------+\n| YC Y Y Y YC Y Y Y | line 4 |\n+-------------------+--------+\n\nSome comments about this formats:\n\n- 4:1:1 is supported natively in AviSynth v2.6.\n- DV decoders all output YUY2 or RGB (with the exception of ffdshow when YV12\n  is enabled).\n- When outputting YUY2/RGB (NTSC), the MainConcept codec duplicates the\n  chroma samples instead of interpolating. The [`ReInterpolate411 plugin`_] can\n  be used to correct for this, resulting in better quality.\n\n\nReferences\n~~~~~~~~~~\n\n| [`MSDN: YUV sampling <http://http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/YUVFormats.asp>`_] Describes the most common YUV sampling techniques.\n| [`DV sampling`_]\n\n\n4:2:0 Interlaced Chroma Problem (or ICP)\n----------------------------------------\n\nIn general interlaced content will have static parts. If it is upsampled\ncorrectly using interlaced upsampling, it will still have *chroma problems on\ndiagonal edges of bright-colored objects in static parts of a frame*. The\nreason is that \"When the two fields are put back together later by a\ndeinterlacer (or by your eye and brain, if you watch it on an interlaced TV),\nthe relatively smooth gradations and contours of each field are broken up by\na slightly different set of gradations and contours from the other field.\"\n(quote from first reference). This is called **the Interlaced Chroma\nProblem**. The \"solution\" is a motion-adaptive upsampler, but such an\nAviSynth/VDub filter which attempts to do this doesn't exist yet.\n\n| References:\n| [`The 4:2:0 Interlaced Chroma Problem <http://www.hometheaterhifi.com/volume_8_2/dvd-benchmark-special-report-chroma-bug-4-2001.html>`_]\n| [`The 4:2:0 Interlaced Chroma Problem - Television and Video Advice <http://members.aol.com/ajaynejr/vidbug2.htm>`_]\n\n$Date: 2026/03/02 21:16:00 $\n\n.. _The Chroma Upsampling Error:\n    http://www.hometheaterhifi.com/volume_8_2/dvd-benchmark-special-report-chroma-bug-4-2001.html\n.. _Chroma Upsampling:\n    http://www.hometheaterhifi.com/volume_8_2/dvd-benchmark-special-report-chroma-bug-4-2001.html\n.. _The Chroma Upsampling Error - Television and Video Advice:\n    http://members.aol.com/ajaynejr/vidbug2.htm\n.. _chroma shift:\n    http://forum.doom9.org/showthread.php?p=1294886#post1294886\n.. _4:4:4:\n    http://www.quantel.com/domisphere/infopool.nsf/HTML/dfb444?OpenDocument\n.. _4:2:2:\n    http://www.quantel.com/domisphere/infopool.nsf/HTML/dfb422?OpenDocument\n.. _4:2:0:\n    http://www.quantel.com/domisphere/infopool.nsf/HTML/dfb420?OpenDocument\n.. _Chroma Subsampling Standards: http://www.mir.com/DMG/chroma.html\n.. _ReInterpolate411 plugin:\n    http://mywebpages.comcast.net/trbarry/downloads.htm\n.. _DV sampling: http://www.adamwilt.com/pix-sampling.html\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/advancedtopics.rst",
    "content": "\nAdvanced Topics\n===============\n\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\n.. _Interlaced and field-based video:\n\nInterlaced and field-based video\n--------------------------------\n\nCurrently (v2.5x and older versions), AviSynth has no interlaced flag which\ncan be used for interlaced video. There is a field-based flag, but contrary\nto what you might expect, *this flag is not related to interlaced video*. In\nfact, all video (progressive or interlaced) is frame-based, unless you use\nAviSynth filters to change that. There are two filters who turn frame-based\nvideo into field-based video: :doc:`SeparateFields <corefilters/separatefields>`\nand :doc:`AssumeFieldBased <corefilters/parity>`.\n\nMore information about this can be found :doc:`here <advancedtopics/interlaced_fieldbased>`\n\n\n.. _Video Sampling:\n\nColor format conversions, the Chroma Upsampling Error and the 4:2:0 Interlaced Chroma Problem\n---------------------------------------------------------------------------------------------\n\nThe *Chroma Upsampling Error* is the result of your video is upsampled\nincorrectly (interlaced YV12 upsampled as progressive or vice versa).\nVisually, it means that you will often see gaps on the top and bottom of\ncolored objects and \"ghost\" lines floating above or below the objects. The\n*4:2:0 Interlaced Chroma Problem* is the problem that 4:2:0 Interlaced itself\nis flawed. The cause is that frames which show both moving parts and static\nparts are upsampled using interlaced upsampling. This result in chroma\nproblems which are visible on bright-colored diagonal edges (in the static\nparts of the frame). More about these issues can be found :doc:`here <advancedtopics/sampling>`.\n\n\n.. _ColorSpace Conversions:\n\nColorspace Conversions\n----------------------\n\nAbout the different RGB <-> YUV :doc:`color conversions <advancedtopics/color_conversions>`.\n\n\n.. _Wrong levels:\n\nWrong levels and colors upon playback\n-------------------------------------\n\nWhen playing back video content, several issues might go wrong. The levels\ncould be wrong, resulting in washed out colors (black is displayed as dark\ngray and white is displayed as light gray). This is described in more detail\n:doc:`here <advancedtopics/luminance_levels>`. The other issue is a slight\ndistortion in color (which often looks like a small change in brightness) and\nthis is described :doc:`here <advancedtopics/colorimetry>`.\n\n\n.. _Hybrid Video:\n\nAviSynth, variable framerate (vfr) video and Hybrid video\n---------------------------------------------------------\n\nThere are two kinds of video when considering framerate. Constant framerate\n(cfr) video and variable framerate (vfr) video. For cfr video the frames have\na constant duration, and for vfr video the frames have a non-constant\nduration. Many editing programs (including VirtualDub and AviSynth) assume\nthat the video has cfr. One of the reasons is that avi doesn't support vfr.\nThis won't change in the near future for `various reasons`_. Although the avi\ncontainer doesn't support vfr, there are several contains (mkv, mp4 and wmv\nfor example) which do support vfr.\n\nIt's important to realize that in general video is intrinsically cfr (at\nleast in the capping video or ripping dvds arena). There is one exception\nwhere converting to vfr is very useful, which is hybrid video. Hybrid video\nconsists of parts which are interlaced/progressive NTSC (29.97 fps) and FILM\n(which is telecined to 29.97 fps). When playing hybrid video the NTSC part\n(also called video part) is played back at 29.97 fps and the telecined part\nat 23.976 fps.  Examples of hybrid video include some of the anime and Star\nTrek stuff.\n\nMore info about creating vfr video and opening it in AviSynth can be found\n:doc:`here <advancedtopics/hybrid_video>`.\n\n\n.. _Importing Media into AviSynth:\n\nImporting your media in AviSynth\n--------------------------------\n\nA lot of media formats (video, audio and images) can be imported into\nAviSynth by using one of AviSynth's internal filters, specific plugins or\nDirectShowSource in combination with the appropriate DirectShow filters. It\nis not always trivial to import your media into AviSynth, because there are\noften many ways to do so, and for each way you need to have some specific\ncodecs installed. :doc:`This document <advancedtopics/importing_media>`\ndescribes which formats can be imported in AviSynth and how they should be\nimported. Also a short summary is included about how to make graphs (graphs\nof approriate DirectShow filters which can be used to play you media file)\nin Graphedit and how to open the graphs in AviSynth.\n\n\n.. _Resizing:\n\nResizing\n--------\n\nResampling is the process of converting a signal from one sampling rate to\nanother, while changing the information carried by the signal as little as\npossible. When applied to an image, this process is sometimes called image\nscaling. More about image scaling, various resampling kernels and the\nimplementation in AviSynth can be found `on avisynth.nl`_ (...).\n\n$Date: 2010/02/28 14:31:47 $\n\n.. _various reasons:\n    http://forum.doom9.org/showthread.php?s=&threadid=69132\n.. _on avisynth.nl: http://avisynth.nl/index.php/Resampling\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/avisynthplus.rst",
    "content": "\nAviSynth+\n=========\n\n\nNew Video Features\n------------------\n\n-   High bit depth support 10, 12, 14 and 16 bits and 32 bit float.\n-   Planar RGB\n-   Planar Alpha-plane formats\n-   Frame properties\n\nNew Audio Features\n------------------\n\n-   none\n\n\nNew Internal Features\n---------------------\n\n-   64 bit with no compromises\n-   Source on github\n-   CMake build environment\n-   No internal assembler (only a few is left in some special windows 32 bit modes), SIMD intrinsics everywhere.\n-   Source supports C++ only: supports non-Intel x86/x64 platforms.\n-   Support for various OS's: not Windows-only\n-   Rewritten multithreading support\n-   New language elements: function objects, arrays\n-   A bunch of new and extended internal filters and accepted formats\n-   Experimental host of direct CUDA-plugins in specific builds.\n    (but note that core does not use any CUDA though, just provides a framework through IScriptEnvironment)\n\n$Date: 2009/09/12 20:57:20 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/changelist.rst",
    "content": "\n2.58 Changes\n============\n\n\nChanges from 2.57\n-----------------\n\n\nAdditions\n~~~~~~~~~\n\n* Added Czech doc translation.\n* Added Polish doc translation (by Slim, Krismen & Co).\n* Added Japanese doc translation (by niiyan).\n* Installer standalone option for putting avisynth.dll, etc into install directory and NOT updating registry.\n* Blankclip added audio channels= and sample_type= arguments.\n* ConvertAudio(cii) available to plugins via env->Invoke().\n* Added font aspect, rotation and alpha to text routines.\n* Added ``/* xxx */`` block comments.\n* Added ``[* [* xxx *] *]`` nestable block comments.\n* SetMemoryMax(0) to just return current Memory Max value.\n* Added planar YV12 color format to Compare() [Fizick].\n* ColorKeyMask: Allow independant tolerance levels for each channel.\n* Added Tweak Hue/Saturation range limiting.\n* Added AudioLevels and Color2 modes to Histogram.\n* Adding **global OPT_UseWaveExtensible=True** to your script enables WAVE_FORMAT_EXTENSIBLE audio output.\n* Added ShowTime() script verb, like ShowSMPTE() but with milliseconds.\n* Added BlackmanResize() and Spline64Resize().\n* Modified DeleteFrame()/DuplicateFrame() to process multiple arguments.\n* Added Min()/Max() script functions.\n\n\nBugfixes\n~~~~~~~~\n\n* Fixed ShowFiveVersions() YV12 chroma position in bottom half. Regression.\n* Fixed Histogram() Classic mode restore graph brightness. Regression.\n* Fixed Compare() graph pixel values exceeding YUV limits.\n* Fixed AddBorders() args negative value clamping.\n* Fixed AviSource() decoding to RGB24 logic regression.\n* Added workaround for HuffYUV, Xvid reading past end of input buffer.\n* Fixed current_frame value in nested runtime script invocations (Gavino).\n* Fixed Dissolve overlap arg range checking (gzarkadas).\n* Fixed OpenDMLSource() multithreading race problem (QuaddiMM).\n* Fixed unsaved variableName string in ConditionalReader.\n* Fixed Parser FunctionTable::TypeMatch() missing compulsory arguments.\n* Dissolve bug (Various).\n* Fixed DirectShowSource() convertfps=false logic regression.\n* Fixed DirectShowSource() Flush task interlock race.\n* Fixed DirectShowSource() QueryId() use CoTaskMemAlloc for returned value (Dean Pavlekovic).\n* Fixed DirectShowSource() use GraphBuilder object for media control (Avery Lee).\n* Fixed DirectShowSource() remove PulseEvent calls (Avery Lee).\n* Fixed DirectShowSource() QueryAccept() modifying VideoInfo in running script (Haali).\n* Fixed Blankclip clip= argument parsing.\n* Fixed trashed GPF report, i.e reading 0x0 at 0x0 exception reporting.\n* Fixed and refactored Overlay RGB<->YUV conversion routines.\n* Fixed ImageReader incompletely inited videoInfo.\n* Fixed Layer RGB32 100% alpha implementation, use level=257 (new default).\n* Fixed avisynth_c.h avs_is_parity_known().\n* Fixed C++ ConvertAudio::Saturate_int32() rounding.\n* Fixed WriteFile(), Now remembers absolute path to file.\n* Fixed Info() frame pitch, reports pitch of input frame.\n* Fixed Invert() right edge memory overrun/corruption.\n* Fixed Histogram() Classic mode pixel values exceeding YUV limits.\n* Fixed Histogram() chroma plane initialization to 128.\n* Fixed Conditional reader/writer illegally saving IScriptEnvironment pointer.\n* Fixed YV12 Blur()/Sharpen() right edge pixel corruption with non-writable input frames.\n* Fixed MMX Blur()/Sharpen() code to full 8 bit precision.\n* Fixed IsAudioFloat()/IsAudioInt() script functions.\n* Fixed Cache memory oversubscription of SetMemoryMax() limit.\n\n\nOptimizations\n~~~~~~~~~~~~~\n\n* DirectShowSource() convertfps=true add 0.5ms rounding to expected sample time. Improves performance with millisecond based DS spliters.\n* DirectShowSource() FPS detection as last attempt try getting the duration of 1st frame.\n* DirectShowSource() convertfps=true rely only on sample start time.\n* Cache: Trap returned NULL PVideoFrames, i.e. Don't crash, Winge about it!.\n* Refactor horizontal planar resizer, no width restrictions or 2 byte overwrite.\n* Provide a simple and fast text writing primatives, see info.h\n* Make audio cache actually functional.\n* Tweak() speed improvements.\n* Subtract() speed improvements.\n* Tuneup Overlay() ISSE Convert444ChromaToYV12 and also provide MMX version.\n* PokeCache internal interface implemented.\n* Cache and Memory management enhancements.\n\n\nChanges\n~~~~~~~\n\n* Initial Memory Max value clamped to 512MB.\n* Default Memory Max value restored to quarter of Free memory. Minimum 16Mb. As per 2.5.7.\n* Test VFB data buffer for NULL malloc's, if so then Throw!\n* Installer Start menu shortcut names translated.\n* Test for UTF-8 and Unicode BOM prefixes and issue a useful warning.\n* Removed useless current_sample from runtime script environment.\n* Added critical section to CAVIFileSynth class.\n* Enable Installer multi language support, thanks go to Fizick, gzarkadas, Malow, manusse, M.T, niiyan, talen9, TiGR, Underground78, WarpEnterprises, Wracko.\n* FunctionTable::Lookup() now considers named arguments in making its selection.\n* ImageWriter supports negative values as -count for End argument.\n* ChangeFPS() use floor instead of round in source frame number calculation.\n* Update usage of correct (updated) Rec.709 coefficients.\n* Add TCPDeliver.map and DirectShowSource.map to releases.\n* Convert to Dynamic Assembled rgb to yuy2 code.\n* Avisynth_c.h boolean functions return 1 for true instead of arbitrary non-zero.\n* Internal RGB2YUV() now copies Alpha top byte through.\n* CoUninitialize() done immediately for S_FALSE CoInitialize() returns, i.e we do not hold a COM use count.\n* Pfc, Softwire and SoundTouch updated and added as dependency projects.\n* UPX updated to version 2.03 (2006-11-07).\n* AVISource/WavSource map WAVEFORMATEXTENSIBLE back to equivalent WAVEFORMATEX.\n* DirectShowSource() now recognises incorrect AM_MEDIA_TYPE subtype for WAVE_FORMAT_EXTENSIBLE audio and corrects the data and accepts it.\n* DirectShowSource() now attempts to use partial graph from failing RenderFile call.\n* DirectShowSource() now detects and handles non 32 bit aligned picture lines from dud codecs.\n* Crop(align=true) tests actual alignment in each GetFrame call.\n* Relax YV12 resizer width restriction, now mod 2 was mod 4.\n* .AVSI failures during env->CreateScriptEnvironment() are now available to the GetError() interface.\n* SetCacheHints(CACHE_RANGE, n) will now surrender frames to satisfy SetMemoryMax().\n* CoInitialize()/CoUninitialize() now done as part of ScriptEnvironment creation/deletion.\n* Much code from 2.6 base included. Typically IsYV12() changed to IsPlanar().\n\n\nIssues\n~~~~~~\n\nPlease report bugs and problems at `Sourceforge Avisynth2 page`_ - or - `Doom9's Avisynth Developer Forum`_\n\n\nChanges from 2.56\n-----------------\n\n\nAdditions\n~~~~~~~~~\n\n* Blur()/Sharpen() MMX=False option to force use of C++ routines.\n* Explicitly try to request input sample rate from the audio codec (Tritical).\n* Installer option for avisynth.lib, avisynth.exp and avisynth.map files.\n* DirectShowSource() now sets _HIRESOUTPUT property of WMAudio Decoder DMO. Allows 24 bit samples and 6 channel decoding.\n* Avisynth COM object now supports IAVIStreaming interface. Many apps blindly expect it and subsequently failed to load AVS scripts.\n* Conditional Reader now also accepts T, F, Yes and No for bool data.\n* DirectShowSource() log debug messages to file.\n* DirectShowSource() force set framecount.\n* DirectShowSource() accept audio streams of type WAVE_FORMAT_IEEE_FLOAT.\n* Added KillVideo() verb.\n* TimeStretch now exposes the tuning parameter of the SoundTouch library.\n* Adding **global OPT_AllowFloatAudio=True** to your script enables WAVE_FORMAT_IEEE_FLOAT audio output.\n* Explicitly request all the channels available in the audio stream [acm AC3]\n* Explicitly try to request float, 32 bit then 24 bit samples from the audio codec.\n* Accept uncompressed audio streams of type WAVE_FORMAT_IEEE_FLOAT.\n* Added installer option to add \"Avisynth Script\" item to Explorer shell for new .avs file creation.\n* Added avs_delete_script_environment and avs_subframe_planar to avisynth_c interface.\n* Hack to allow Fraunhoffer MP3 codec to work when wBitPerSample==16. (Squid_80)\n* Added portugese translation (by RoLon), and partly french translation (by JasonFly)\n* Subtitle multi line text, set LSP arg and use \\n. (foxyshadis, tateu)\n* xxxFPS(\"preset\") string preset FPS values. (Tritical)\n* Better avisynth_c cdecl/stdcall mismatch detection and protection (Tritical).\n\n\nBugfixes\n~~~~~~~~\n\n* Fixed Tritcal bracketless call multiple cache over cache regression.\n* Fixed DirectShowSource greyframe regression.\n* Fixed DirectShowSource audio format negotiation regression.\n* Fixed TCPDeliver YV12 transfer 50% to much data.\n* Fixed TCPDeliver do Makewritable before getting params.\n* Fixed TCPDeliver audio transfer off by 4 bytes.\n* Fixed resizer core boundary condition crashes/errors/glitches.\n* Fixed Invert() crash with small widths.\n* Fixed small memory leak Amplify().\n* Fixed grey frames with internal start, stop, start while DSS is initializing.\n* Fixed AudioChannels() returning non-zero when no audio (Tritical).\n* Fixed ConvertFPS() blend mode mix_ratio was wrong.\n* Fixed AviSource() handling of dud AVI files that start with drop frames, just return the first key frame.\n* Fixed DirectShowSource() handling of pin renegotiation.\n* Fixed Overlay() \"PC_Range\" argument handling.\n* Fixed SubTitle() crash when resources exhausted.\n* Fixed Resizers cropping argument validation.\n* Fixed % operator bad argument text message.\n* Fixed stuffing Audio buffer with video graphics on Exception. Now returns E_FAIL. Video stream subsequently will return error text in graphic form.\n* Fixed KillAudio() resetting nchannels and sample type to 0.\n* Fixed Conditional Reader sscanf buffer overrun.\n* Fixed Version() and VersionString() timestamp discrepancies.\n* Fixed Serious inaccuracies in TimeStretch. It is still not sample exact!\n* Fixed Negative int arg handling for ApplyRange() and Animate().\n* Fixed Installer handling of readonly target files.\n* Fixed ConvertAudio SSE2 to Float alignment test.\n* Fixed (auto)LoadPlugin altname generation. (Tritical)\n* Fixed SaveString memory block overrun.\n* Fixed $Plugin!Functionname!Param$ bug. (Fizick)\n* Fixed registry handle leak on $PluginDir$ lookup. (Dave Brueck)\n* Fixed memory leaks avisynth_c.\n* Fixed returning locked/protected VBF's to LRU. (Tritical)\n* Fixed runtime mixed SEH/C++ exception handling for XPsp2. (Tritical)\n* Fixed CAVIStreamSynth::Read audio buffer overrun. (Avery Lee)\n* Fixed DLL handle leak in LoadPlugin. (Tritical)\n* Fixed Assert(\"text\") no longer parses % args.\n* Fixed number parser returning inaccurate float conversions.\n* Fixed ConvertFPS() blend mode not processing of chroma planes.\n* Fixed resizer resampling pattern attempted use after deletion.\n* Fixed resizer subpixel shifting functionality being a noop.\n* Fixed Info() auto font selection metric.\n* Fixed Conditional error checking of float RHS.\n* Corrected colours in YUV ColorBars, Now match BT.801-1.\n* TCPDeliver updates: Client: Fixed crash if client gets disconnected.\n* TCPDeliver updates: Server: Remember to disconnect clients when shutdown.\n* Fixed Turn*() YUY2 mod 2 height test.\n* Fixed AVISource() corrupted error messages.\n* Fixed AVISource() direct input drop frame handling.\n\n\nOptimizations\n~~~~~~~~~~~~~\n\n* Parser tries to prevent adding a cache of a cache to graph.\n* ImageSource() no longer use static buffer, uses cache and freezeframe.\n* TCPDeliver big buffer enhancement (retro from 2.6 stream).\n* SubTitle() releases all resources when the last frame of the clip is rendered.\n* SubTitle() releases GDI resources after text map is created.\n* ApplyRange() only builds 2 chains instead of 3.\n\n\nChanges\n~~~~~~~\n\n* TCPDeliver add icon, make all resource US English.\n* Map file is now generated for release builds.\n* ConvertTo*() and GreyScale() now accept \"Rec601\" as a valid matrix.\n* DirectShowSource.dll upx'ed.\n* Upgrade internal copy of SoundTouch library to 1.3.1.\n* SoundTouch now available in RelSym build.\n* Animate Integer arg enumeration no longer rounds toward positive infinity. Both positive and negative enumerations are identical. i.e. For Animate(0, 10, \"Foo\", 0, 0, 10, -10), Foo's arg1 = -arg2 for all frames.\n* Selecting associate open with Notepad with .avs files in the installer now also includes .avsi files.\n* The Installer now pushes a recovery dialog box when unwritable files are encountered during an install. The user may manually correct the problem and retry installing that file.\n* SetMemoryMax() minimum now 4Mb instead of 16. (Tritical)\n* Remove 50 plugin auto prescan load limit. (Tritical)\n* COM QueryInterface calls now return S_OK instead of NULL.\n* Bracketless call of functions without arguments now get a cache (Tritical).\n* Over-range numbers now raise a compile time exception.\n* xxxFPS(float) now uses continued fraction to generate a minimal rational pair (Raymod2).\n* ChangeFPS(linear) now raises a compile time exception if the speed change ratio is > 10.\n* ConvertFPS() blend mode works for all pixel formats. (Tritical)\n* Info() retrofit of 2.60 updates.\n* TCPDeliver.dll upx'ed.\n* RGB ColorBars +Q and -I bars, Hue is now correct, Luma is NOT zero to achive this.\n* AVISource Audio no longer limited to 2 channels.\n* SaveString memory blocks are now 32 bit aligned.\n* Default planar chroma planes mod 16 aligned. See SetPlanarLegacyAlignment().\n\n\nChanges from 2.55\n-----------------\n\n\nAdditions\n~~~~~~~~~\n\n* SSE3 capable CPU detection in env->GetCPUFlags and Info().\n* RGB32 mode in TemporalSoften.\n* ``*Resize()``, src_height and src_width when negative work as in crop.\n* Added options to DirectShowSource (seekzero, timeout and pixel_type).\n* Added AudioDubEx(), blindly accepts video and audio streams.\n* Added Load_Stdcall_Plugin(), alias for LoadCPlugin() (won't disappear when avisynth_c.dll is loaded)\n* Added DevIL support for RGB32 to ImageSource.\n* Added Russian language documentation. Thanks to Fizick and his team. Well done.\n* Added Merge() filter. Includes very fast iSSE pavgb code for weight=0.5.\n* Added MergeARGB(), MergeRGB() filter.\n* Added ShowRed(), ShowGreen(), ShowBlue() filters.\n* Added Planar version of env-&gtgSubFrame() (thanks TSP).\n* Added SetPlanarLegacyAlignment() to select Planar alignment algorithm.\n* Added Audio padding control to Trim().\n* Added operator muldiv(multiplicand, multiplier, divisor).\n* Added AssumeScaledFPS(multiplier, divisor, sync_audio) maps vi.MulDivFPS.\n* Added method VideoInfo.MulDivFPS(unsigned multiplier, unsigned divisor) does rational scaling with normalizing and overflow protection of FPS property.\n* Added offsets, gamma and analyze option (ala ColorYUV) in RGBAdjust.\n* Added preliminary 23.976fps film drop frame support to ShowSMPTE(), Anyone know the proposed SMPTE algorithm?\n* Added Spline16Resize, Spline36Resize, GaussResize and LanczosResize(tap=xx)\n* Added options to ShowFrameNumber: ShowFrameNumber(offset=10, x=360, y=576, font=\"georgia\", size=24, text_color=$ff0000)\n* Added integer offset to ShowSMPTE: ShowSMPTE(offset_f=10)\n* Added options to ShowSMPTE: ShowSMPTE(offset=\"00:00:00:30\", x=360, y=576, font=\"georgia\", size=24, text_color=$ff0000)\n* Added Optional FPS=24 parameter to Dissolve and Fade*() for processing audio only clips.\n* Added FadeIn0(), FadeOut0(), FadeIO0() variants that don't add an extra frame.\n* Added Fractional resampling support in ResampleAudio().\n* Added HasVideo() and HasAudio() script functions.\n* Added Level option to Tone().\n* Added SFloat support in ResampleAudio().\n* Added ColorBars(pixel_type=\"YUY2, YV12\").\n* Added env->ManageCache() interface in AviSynth.h.\n* Added VideoFrameBuffer 16 byte guardband protection/detection in Debug mode.\n* Added EBX compiler bug protection/short circuiting to Cache::GetFrame().\n* Added YV12 support for ShowFiveVersions().\n* Added \"[sse]b\" option to Tweak to re-enable the (slow) SSE code (maybe AMD's might run it faster).\n* Added Limiter(show=show_luma/show_luma_grey/show_chroma/show_chroma_grey) shows out of bound luma/chroma; ``*_grey`` makes the rest of the pixels greyscale.\n* ConvertTo*(Matrix=\"Rec709, PC.709, PC.601\") conversions supported.\n* ConvertFPS()/ChangeFPS() copies FPS from a 2nd clip.\n* GreyScale() RGB supports Matrix=\"Rec709, Average\".\n\n\nBugfixes\n~~~~~~~~\n\n* Fixed corruption at the end of the IScriptEnvironment vtable.\n* Fixed memory leaks in Overlay and AVSChar/AVSTime.\n* Fixed End_of_Stream reset on seek in AudioStreamSource:\n* Fixed SegmentedDirectShowSource() argument parsing.\n* Fixed ``*Resize()``, src_height and src_width when negative work correctly.\n* Fixed minor memory leak in env.VSprintf(), [ul]case() and ``*str()`` also remove 4k limits, thanks Tritical.\n* Fixed Normalize scribling into memory for float samples.\n* Masked \"Evaluate: System Exception - Access Violation\" in :- FadeIO*(), RGBAdjust(), Tweak(), Lanczos*Resize() and GaussResize().\n* Fixed rounding in YUY2 turnleft/right chroma.\n* Fixed AVSC_USE_STDCALL declaration in avisynth_c.h (was ACSC_USE_STDCALL).\n* Fixed BlankClip(clip) now competely duplicates the donor clip's VI including parity.\n* Fixed AssumeTFF/BFF() to correctly update internal parity state.\n* Fixed Animate audio switching.\n* Fixed aligned UVpitch from width rounding.\n* Fixed 2 bit crosstalk in YUV horizontal resizers, thanks Squid.\n* Fixed resource leak in DirectShowSource(), thanks Tritical.\n* Fixed minor memory leak in Subtitle() and string(), thanks Tritical.\n* Fixed global clip close down problem, thanks Tritical.\n* Uninstaller now remove Docs\\pictures directory and DirectShowSource and TCPDeliver plugins.\n* Fixed ImageReader single file handling.\n* Fixed ImageWriter info==false no longer write status text onto frame.\n* Trap .WAV clsid handler GPF with filenames gt 47 chars.\n* Fixed YUV text access violation, correct bounds alignment tests. (Regression)\n* Fixed ExpFunctionCall::Call memory leak, thanks Tritical.\n* Fixed PClip leak in MergeChannels(). Destructor chain not called.\n* Fixed RGB text alignment inversion. Regression in May 5th ver.\n* Fixed vfw resource leaks when opening bad AVI files.\n* Fixed rmvb stuck at 100% during encoding (thx stevencover).\n* Fixed Loop audio processing.\n* Fixed GeneralConvolution crash with cropped input.\n* Restored forced (negative) planar luma alignment functionality.\n* Fixed a stack of memory leaks, thanks Tritical.\n* Fixed Direct AVISource input of raw YV12 and I420 sources.\n* Fixed (fingers crossed) \"Evaluate: Recognized exception!\" Problems with XPsp2 hard terminate.\n* Fixed CACHE_RANGE internal scope test, thanks Tritical.\n* Fixed Mask() calc of greyscale, red/blue swapped.\n* Fixed FPS overflow with Select...(), Interleave() and variants.\n* Fixed subtract mode in Overlay (chroma is correctly subtracted).\n* Fixed align parameter in Subtitle.\n* Windout code is working again (broking in the previous betas).\n* Corrected multi-channel audio fading.\n* Dissolve and Fade*() process audio only clips, assumes 24fps for position calcs.\n* Fixed wrong chroma in DoubleWeave() of FrameBased YV12 material.\n* Fixed crash from BlankClip() with an audio only clip template.\n* Fixed AudioCache corruption on buffer resize.\n* Fixed ResampleAudio() clicks/pops due to creeping error.\n* Fixed SSE/SSE2 ConvertAudioTo16/32Bit() positive value saturation.\n* Masked EBX compiler bug in :- audio.cpp converaudio.cpp convert_yv12.cpp memcpy_amd.cpp focus.cpp layer.cpp merge.cpp resample.cpp resize.cpp text_overlay.cpp conditional_functions.cpp 444convert.cpp blend_asm.cpp\n* Fixed ConvertToRGB() src->rowsize==8 crash.\n* Fixed Memory leak, deleted VideoFrameBuffers.\n* Fixed env->NewVideoFrame() returning short frame buffer.\n* Fixed vi.FrameFromAudioSamples() truncation.\n* Fixed ShowFiveVersions() unused corner rectangles had random contents. Now grey filled\n* Fixed YUV plane swapper reports corect name.\n* Fixed MergeChroma reporting itself as MergeLuma.\n* Fixed MergeChroma doing MakeWriteable() on the wrong clip.\n* Fixed Normalize (it was only sampling half of the samples per mouthful; it was ignoring the scaling factor).\n* Fixed GreyScale() EBX compiler bug.\n* Fixed flipped frame on imagesources.\n* PlaneDifference in ConditionalFilter was not reporting exactly 0, if the planes were the same.\n* Fixed big bug in compressed YV12 TCPSource / TCPClient in TCPDeliver.\n* Increased stringbuffers, 4K to 32K (WarpSharp problem).\n* Fixed Overlay(softlight/hardlight) overflow.\n* Masked \"Unknown exception\" in :- audio.cpp avs_soundtouch.cpp color.cpp field.cpp focus.cpp fps.cpp levels.cpp resample.cpp source.cpp\n* Fixed WavSource() leaving .WAV files open.\n* Fixed glitches in multichannel audio transitions in Dissolve() and Fade*()\n* Fixed Green/Blue channel swap in C version of Layer()\n* Restored GreyScale() RGB C code.\n* Fixed MMX YV12 Blur() double blurring every 8th pixel.\n* Blur()/Sharpen() Edges all processed consistantly (edges are reflected).\n* Fixed YV12 Blur() width < 16 fatal crash.\n\n\nOptimizations\n~~~~~~~~~~~~~\n\n* Performance improvents in transfer functions in TCPDeliver.\n* Normalize() for 16 bit stop when a max-int value sample is seen.\n* Run sort -unique|detab on color_rgb.avsi, got rid of all the duplicates.\n* YV12 MergeLuma(), MergeChroma() include very fast iSSE pavgb code for weight=0.5.\n* Cleanup VideoFrame garbage collection on script close (Thanks TSP).\n* Text overlay antialiaser tweaked, 8% faster.\n* RGB32 FlipHorizontal() code tweaked.\n* ResampleAudio() MMX for int16 samples, approx 3.25 times faster.\n* ResampleAudio() reworked C++ int16 code, approx 35% faster.\n* ResampleAudio() reworked buffer management, now linearly accesses child->GetAudio().\n* Cache and Memory Managment have been reworked.\n* ConvertAudioToFloat() fast SSE and very fast SSE2, opt/skip redundant output copy.\n* ConvertAudioTo16,32Bit() very fast SSE2.\n* SwapUV() YV12 swaps pointers in PVideoFrame, zero cost!, YUY2 fast iSSE code.\n* UtoY(), VtoY(), YtoUV() YUY2 faster C++ code.\n* MergeLuma(), MergeChroma() now MMX (not iSSE), has C++ versions, YV12 BlendPlane now does 8 pixels per loop almost 2x faster!.\n* ColorBars() generates Tone in constructor buffer, copied out in GetAudio(), avoid 48000 sin(double) per second.\n* EnsureVBRMP3Sync() uses 256K transfer buffer when seeking (should be > 5 times faster now.)\n* Normalize() uses 256K transfer buffer to analyze peaks (should be > 5 times faster now).\n* Tweak: added C++ code (lookup table), which is now faster than the old iSSE code.\n* Audio.cpp reworked code in audio filters which do 64 bit operations (most routines are between 2 and 5 times faster).\n* ConvertToRGB32() MMX RGB24 -> RGB32.\n* Blur()/Sharpen() when H or V = 0 skips that pass.\n* GreyScale() MMX YUY2.\n* Blur()/Sharpen() now MMX (not iSSE), faster, fewer mod(2^n) restrictions.\n\n\nChanges\n~~~~~~~\n\n* Stop extra search of LIBC, add relsym build - Release with Symbols.\n* The avisynth_c plugin entry point is now officially \"avisynth_c_plugin_init@4\" (don't include @4 anywhere the compiler does it for you), this is not actually a change due to a bug in avisynth_c.h, which incidently caused it to be this already.\n* Info() now autoselects a smaller font to fit info in small frames.\n* Info() now distinguishes between \"assumed\" field parity and field parity.\n* Animate now selects parity through the filter chain.\n* New improved cache!\n* Installer now populates \"All Users\" shell tree on NT variants. Admin/Uninstaller stuff is only added to current user.\n* Uninstaller now deletes DirectShowSource.dll and TCPDeliver.dll from plugin directory.\n* ImageReader doesn't auto fail over to DevIL for DIB/BMP type files. (DevIL crashs on palletted BMP's)\n* ImageWriter now throws an exception for non RGB24 format with DevIL processing.\n* ImageReader/Writer info text colour now pale yellow $f0f080.\n* Replaced VideoFrame::SubFrame() with env->SubFrame() (Ready for MultiThreading, Thanks TSP).\n* Option for planar alignment (default 16 bytes) to be based on chroma planes, luma alignment is (still) 2x chroma. Will become the default in the next version.\n* Support for `vfr content in DSS`_:\n\n::\n\n    DirectShowSource(\"F:\\Guides\\Hybrid\\vfr_startrek.mkv\", fps=119.88, convertfps=true) turns vfr into cfr stream by duplicating frames.\n\n* Histrogram: in color_mode - YUY2: Invalid values (below 16 and above 235) will be colored brown/yellow-ish. Made those values more visible.\n* Evaluate: Now breaks outs and reports system exceptions instead of reporting the useless \"Evaluate: Unrecognized exception!\".\n* BlankClip() no longer gobbles any implicit last clip as the template clip. You have to explicitly declare you want a template clip i.e. BlankCLip(Last). \"BlankClip()\" now always returns the default blank clip.\n* Avisynth.h FrameFromAudioSamples/AudioSamplesFromFrames() now test for divide by zero and return zero when encountered instead of crashing.\n* SeparateFields() now throws an exception for an IsFieldBased() source.\n* Weave() now throws an exception for an IsFrameBased() source.\n* Cache policy CACHE_NOTHING currently no long returns all VFB's. Under review.\n* Avisynth.h SetFPS() now test for zero numerator or denominator if found it sets num=0, den=1.\n* Audio Cache Autodetect lower metric from 25 to 5 on skip forward (step back still 25).\n* ConvertAudio() include the prefered type as an acceptable type.\n* ConvertAudio() passes SetCacheHints() thru to grandchild.\n* Normalize() displays the frame number of the peak.\n\n\nChanges from 2.54\n-----------------\n\n\nAdditions\n~~~~~~~~~\n\n* Added a huge list of color presets, that can be used instead of colors (which can be found in the plugins folder: colors_rgb.avsi).\n* Added: BlankClip now has color_yuv, that allows setting and YUV color for YUV clips.\n* Added GZIP huffman compression to TCPDeliver.\n* Added AssumeFPS(clip1, clip2 [, sync_audio=true/false]) (stickboy again)\n* Added audio=true/false to SelectRangeEvery. This will optionally also cut up audio according to the select. Default: true.\n* Added Turn180().\n* Added IsAudioFloat() and IsAudioInt() as clip properties.\n* Added FrameRateNumerator() and FrameRateDenominator() as clip properties.\n* Added AudioLenghtF() as clip property.\n* Added experimental \"after_frame=true/false\" to ScriptClip.\n* Added FOURCC parameter to AviSource by stickboy.\n* Added Lanczos4Resize().\n* Added french documentation.\n* Added float audio and multiple channels support to Dissolve.\n* Added WriteFile, WriteFileIf, WriteFileStart, WriteFileEnd. (WarpE)\n* Added dll-name prefix to plugins as per http://forum.doom9.org/showthread.php?s=&threadid=72235.\n* * Syntax is DLLNAME_function(), where DLLNAME is the filename of the dll containing the function.\n* Added automatic audio cache.\n* Added dotted lines at zero levels to view bias in Histogram(mode=\"stereo\").\n* Added CPU stuff to Info().\n* Added GeneralConvolution divisor, auto.\n* Added audio cache after EnsureVBRMp3Sync.\n* Added TimeStretch(). This filter can change speed of the sound without changing the pitch, and change the pitch of a sound without changing the length of a sound.\n\n\nBugfixes\n~~~~~~~~\n\n* Fixed \"Unknown exception\" in conditional filter expressions. (August 17th regression)\n* Fixed: DirectShowSource properly releasing filters on unload.\n* Fixed: Huge stability fix by IanB. This should remove a bunch of \"Evaluate: Unregnized exception\", and crashes on reload in vdub.\n* Fixed: ImageReader/ImageSource flipped error messages and info overlay.\n* Fixed MergeLuma not always updating properly.\n* TCPDeliver should compile now.\n* AssumeFPS: Added sanity check to ensure that denominator isn't zero.\n* Fixed Loop() when called with no video (stickboy)\n* Fixed error not being thrown in Conditionalfilter on an invalid operator.\n* Proposed fix for zero coefficient.\n* Fixed crash on certain resolutions in Resize.\n* Made TCPDeliver compile without complaining about missing files.\n* Fixed linecount on multiline strings (Bug ID 989276]\n* Fix VideoFrameBuffer cache corruption\n* Fixed VideoFrameBuffer cache corruption during \"Plan C\" memory recovery.\n* The problem with ApplyRange/Animate's inability to use functions that take no additional arguments should be fixed.\n* Removed overflow bug in ssrc upsampler.\n* Fixed Audio cache crash if no audio.\n* Cleaned up ApplyYV12 in textoverlay.\n* Fixed float audio in Dissolve.\n* Fixed audiobits clip properties now returning bits and not bytes.\n* Fixed ConditionalReader inaccuracies on integer interpolation.\n* Fixed Mask() problem with footage with different pitches.\n* Subtract now clamps errors instead of overflowing.\n* Fixed old plugin names actually working.\n* Added specific (and simpler) stereo mode to TimeStretch - no more drifting.\n* Made ISSE YUY2 HorizontalReduceBy2() more \"safe\".\n* Fixed missing plane in TemporalSoften.\n* Corrected some quirks in TemporalSoften scenechange on artificial sources.\n* Fixed IsParityKnown() in avisynth.h - thanks to stickboy.\n* Random in scalemode is not returning limit value - thanks you stickboy!\n* Fixed: Trim audio could crash, if sample types were different.\n* Fixed crash-on-exit in SSRC, if rateconversion was skipped.\n* Fixed one frame missing in TemporalSoften.\n* Fixed chroma moving half a pel in Overlay() with YV12-input mode.\n* Fixed Trim audio crash if sample types were different.\n* Fixed crash-on-exit in SSRC, if rateconversion was skipped.\n* Fixed minor glitches in audio cache (out of range requests)\n* Fixed ConvertToYV12(interlaced) incorrect sampling for top field chroma.\n* Fixed Memory leak in Vertical Resizer.\n* Fixed PointResize() exact odd sub/multiple width/height returning trash frames.\n* Fixed PointResize() image not centred when expanding.\n* Fixed TurnLeft()/TurnRight() crash with multiple colour spaces in same script.\n* Fixed TurnLeft() in yuy2 colour space off by 1 pixel down.\n\n\nOptimizations\n~~~~~~~~~~~~~\n\n* SSRC now has aligned data (slightly faster and SSE ready).\n* Added MMX optimizations to Overlay mode lighten+darken with opacity=1.0, with no mask.\n* Added SSE float to int audioconversion.\n* Added 3DNOW! optimizations to sample-type conversions int to float, and float to int. Much faster.\n* Added faster MMX to Invert by ARDA.\n* Added RGB24, YUY2 and YV12 MMX Invert() function.\n* Added MMX/ISSE chroma convertion to Overlay with YV12 input.\n* Added MMX function for Overlay(mode=\"blend\"), when a mask is used and opacity = 1.0.\n* Removed unneeded DevIL components\n\n\nChanges\n~~~~~~~\n\n* TCPDeliver: Simplification and cleanup. Planar pitches handled more consistently.\n* DirectShowSource now requests interlaced material to avoid internal (crappy) WMV9 deinterlacer. (Thanks to Russel Lang)\n* ImageReader/ImageSource now accepts relative paths in all configurations.\n* Adjust audio length in SelectRangeEvery to match new video length.\n* Updated installer.\n* ImageReader: tweaked default parameters.\n* ImageReader: made ColorBars parameters optional (like docs claim!)\n* ImageReader: No more \"Image not in range\". First frame is ALWAYS frame 0.\n* Updated SoftWire codegenerator to latest version.\n* ImageReader: Static image support, Floating-point FPS, aliased to ImageSource, frames automatically flipped when necessary.\n* ImageWriter: Optional \"info\" parameter to show filename.\n* ImageReader / ImageWriter: All errors returned as text clips.\n* AviSynth will longer resize to non-mod4 widths in YV12 mode!\n* Dissolve can now handle audio input with different sample types.\n* Dissolve now checks if samplerates are the same.\n* Trim/Dissolve: Better error reporting.\n* Updated DevIL libs; removed unneeded !DevIL components; improved error reporting in ImageReader / ImageWriter.\n* Updated Overlay(mode=\"multiply\") to work more logical. Old functionality is no more!\n* DirectShowSource() is now a plugin, and is automatically placed in the plugin directory by the installer.\n* Disabled avisynth_c plugin autoloading (no longer a compatible way to do so).\n* FrameRate() now calcs as (double)numerator/(double)denominator. (still returns a float)\n\n\nChanges from 2.53\n-----------------\n\n\nAdditions\n~~~~~~~~~\n\n* Added ConditionalReader(). This enables users to load per frame settings into variables accessible to conditional variables.\n* Added \"Hardlight\", \"SoftLight\", \"Difference\" and \"Exclusion\" as Overlay blend modes.\n* Added mode=\"chroma\", \"luma\", \"lighten\", \"darken\" to Overlay.\n* Overlay() now accepts RGB24/32 output.\n* Added \"pc_range=true/false\" parameter to overlay(). This will make all RGB<->YUV conversions inside Overlay assume [0->255] YUV range, and not CCIR 601 [16->235] range. Default is false.\n* Added RGB input conversion to overlay.\n* ShowAlpha now returns RGB, YUY2, or YV12 via the pixel_type argument. The latter two can be used to layer an RGB clip with alpha transparency data onto a YUV clip using the 3-argument form of Overlay().\n* Added Overlay() for doing advanced video overlays/layers.\n* Added SuperEQ(). SuperEQ is a very precise 16 band equalizer.\n* Added IsYUV(clip) to script (it was only present in the documentation). (Party Time)\n* Added internal audiocache by [WarpEnterprises]. Added automatically by the filters that need it.\n* Added fast=true/false mode to SSRC. This will use a faster mode for resampling. Default is false.\n* Added Histogram(mode=\"stereo\") shows a clasic stereo graph (I guess) from the audio in the clip. Some may know these from recording studios. Quite nice actually.\n* Added Histogram(mode=\"stereooverlay\"). Draws the stereograph on top of the original image. YV12 only.\n* Added ChangeFPS(linear=true/false). This will make AviSynth request frames in a linear fashion, when skipping frames. Default:true.\n* Added SSRC(int samplerate) SSRC resampling. Note that it only downsamples. Audio is always converted to float.\n* Added Tone(float length, float frequency, int samplerate, int channels, string type). This will generate sound.\n* *   Length is in seconds. Type can be \"Silence\", \"Sine\" (default), \"Noise\", \"Square\", \"Triangle\" or \"Sawtooth\".\n* *   Defaults are Tone(10.0, 440, 48000, 2, \"sine\").\n\n\nBugfixes\n~~~~~~~~\n\n* Fixed out-of-bounds read in Normalize.\n* Fixed compiler warnings in avisynth_c\n* Fixed very small sample corruption in SSRC.\n* Fixed audio corruption problem if audio with start < 0 was requested. (introduced in Dec. 30th binary).\n* Fixed very small sample corruption in SSRC.\n* Better seeking precision in audio in DirectShowSource.\n* Fixed crashes and Audio corruption in ConvertToMono().\n* Fixed UnalignedSplice if only audio was present.\n* Fixed Trim crash, if only audio was present (throws an error).\n* Fixed slowdown on multiple Directshow Sources.\n* Fixed green bars in small video with mode=\"levels\" and mode=\"color\". For Histogram\n\n\nOptimizations\n~~~~~~~~~~~~~\n\n* Internal audio cache now has better efficiency.\n* Optimization: MMX in Dissolve.\n\nChanges\n~~~~~~~\n\n* Added Kevin Atkinsons avisynth_c 0.20 (stdcall) API.\n* Updated installer. Removed the old one.\n* SSRC: \"fast\" is now true per default. This setting is recommended, unless you are doing a big samplerate adjustment (not just 48000 -> 44100).\n* Updated installer. (Thanks to V_ICE for inspiration).\n* Re-Added German documentation.\n* EMMS is now executed between all filters to avoid potential FPU-states to be carried from one filter to the next.\n* Reimplemented SSRC. It is now capable of running multiple instances, it has been better tested (occational strange sample should be eliminated). This version support both upsampling and downsampling with very high precision.\n* If any filter should request audio that is out of bounds, if will no longer be passed to the filter above, but the invalid parts will be filled with silence.\n* Documentation restructured and much has been updated.\n* Added C-versions of conditional planedifference filters, for non-ISSE machines (not well tested though).\n\n\nChanges from 2.52\n-----------------\n\n\nAdditions\n~~~~~~~~~\n\n* Added audio support to DirectShowSource.\n* Added seeking support to DirectShowSource.\n* Added .GRF file loading to load filter graphs from GraphEdit. Be sure there is an open pin, to which AviSynth is able to connect, otherwise expect \"the filter graph won't talk to me\".\n* Added optional coring=true/false to Levels and Tweak. both true by default, as previously.\n* German documentation.\n* Added DV type 1 video input, using AviSource(). Video only!\n* DirectShowSource() is now capable of properly opening audio with more than 2 channels. Tested with AC3Filter.\n* DirectShowSource() now accepts and properly decodes float-precision samples. Tested with AC3Filter.\n* Added checks for samplerate and framerate in Splice.\n* SwapUV(), UToY(), VToY() and YToUV() now also works in YUY2 mode.\n* Added C-style plugin support (still in testing) to allow plugin writers to use other compilers than MSVC. See this thread for further info.\n* Added Invert(), ShowAlpha().\n* Added default parameters to ColorBars.\n* Extensive updates of German documentation.\n* DirectShowSource capable of opening audio only. WAV/AC3/MP3 can be opened using DirectshowSource.\n* Added experimental \"align=true/false\" to crop - this will realign frames if they aren't already. Alignement is 16 for SSE2 machines, 8 for others.\n* Added \"Overall PSNR for Compare()\" - thanks to temporance.\n* ResampleAudio now accepts any number of channels.\n* Added \"after_frame=true/false\" option to FrameEvaluate. This determines if the script should be evaluated before (default operation) or after the frame has been fetched from the filters above.\n\n\nBugfixes\n~~~~~~~~\n\n* Fixed memory leak in Plugin name export.\n* Incorporated file lock fix in AviSource by WarpEnterprises.\n* Minor fixes to field information in Info().\n* Fixed occational hang in DirectShowSource (this might lead to leaks on unload/load!)\n* Fixed crashbug in Compare, when logfile was specified.\n* Fixed distortion on Crop(align=true).\n* Fixed overflow in ResampleAudio (Thanks to IanB!). [Bug 770853].\n* Fixed Mergechannel broken with more than 2 channels.\n* Made adjustments for longer sample support in ResampleAudio.\n* Fixed crash in ResampleAudio, if no audio was present.\n* Fixed crash in MonoToStereo().\n* Fixed: Normalize(show = true) displaying invalid value, and added a dB amplification indication.\n* Fixed minor issues in audio routines with very long samples.\n* Fixed wrong colors in ShowSMPTE YV12 mode.\n* Corrected several performance problems in Limiter, YUY2 mode (thanks again ARDA!).\n* Fixed YUY2 FlipHorizontal giving garbage/crashing.\n* General Convolution now properly processes 5x5 matrices. Thanks IanB for the patch.\n* Fixed minor stuff in TemporalSoften.\n* (Hopefully) fixed precision in PointResize.\n\n\nOptimizations\n~~~~~~~~~~~~~\n\n* Added heavily optimized memory copy mode, that will be used in some blits.\n* Conditional unroll of fetch/unpack loop in dynamic compiled resizer. Now only unrolls if 1) Athlon 2) Source width < 512.\n\n\nChanges\n~~~~~~~\n\n* Further clarification in Info() regarding field information.\n* Minor changes to Limiter code (block prefetch).\n* ApplyRange now accepts startframe = stopframe. This will only process the specified frame.\n* ApplyRange now supports audio and processes it to the end of stopframe.\n* Updated avisynth_c API to v0.14.\n* Reenabled function name export for VDubMod syntax highlighting - I'm not sure if it had much effect on stability.\n* Corrected ParseMultiplication so it parses from left to right.\n* The default luma range in Limiter is corrected to 16-235 (it was 16-236).\n* Temporarily disabled plugin function export for VDubMod. I'm suspecting this of the \"crash+disappear\" of VdubMod.\n* Removed HSIAdjust().\n* Removed ffvfw from installation.\n* ShowSMPTE does no longer require fps parameter - only if the current fps cannot be used.\n\nChanges from 2.51 beta\n----------------------\n\n\nAdditions\n~~~~~~~~~\n\n* Added light version of \"ffvfw\" to the installer. No \"Cannot locate decompressor (YV12)\" messages.\n* Added ConditionalFilter, that returns one of two sources based on an expression.\n* Added conditional filters:\n* * AverageLuma(), AverageChromaU(), AverageChromaV() functions. ''Returns a float from 0 to 255 based on the average pixel values of a plane.''\n* * YDifferenceFromPrevious(), UDifferenceFromPrevious(), VDifferenceFromPrevious() and YDifferenceToNext(), UDifferenceToNext(), VDifferenceToNext()'''.\n* * LumaDifference(clip,clip), ChromaUDifference(clip,clip), ChromaUDifference(clip,clip). ''They return a float value between 0 and 255 of the absolute difference.''\n* * RGBDifference(clip1,clip2), RGBDifferenceFromPrevious(clip), RGBDifferenceToNext(clip).\n* * YPlaneMax(clip, float threshold), YPlaneMin(clip, float threshold), YPlaneMedian(clip), YPlaneMinMaxDifference(clip, float threshold).\n* * Threshold is a percentage, on how many percent of the pixels are allowed above or below minimum. The threshold is optional and defaults to 0. There are similar funtions for U and V.''\n* Added ScriptClip(clip, string function, [show=true/false]). This will return the clip returned by the function evaluated on every frame.\n* Added FrameEvaluate(clip, script) - Similar to ScriptClip, except the output of the filter is ignored. This can be used for assigning variables, etc.\n* YV12 <-> RGB conversions now use an intermediate YUY2 conversion to achieve better chroma upsamplig. As a result of this ConvertToRGB now also take an \"interlaced=true/false\" parameter.\n* Added ImageWriter.\n* Added \"show\" parameter to ConditionalFilter. This will overlay the results on the screen.\n* Added dynamic compiled limiter.\n* Implemented Belgabors patch for exporting plugin functions.\n* Build date is now (semi)automatically updated in version.\n* Added script functions: IsYV12(clip), IsPlanar(clip), IsInterleaved(clip)\n* Loads of documentation updates.\n\n\nBugfixes\n~~~~~~~~\n\n* Fixed cache hints a bit up.\n* Hopefully fixed jumping frame bugs in temporalsoften.\n* Fixed crashed in temporalsoften on some setups.\n* Fixed I420 / YV12 mismatch in Interleave.\n* Fixed problems with implicit last giving problem with multiple filter instances of ScriptClip/ConditionalFilter.\n* Many ImageReader/Writer fixes and updates.\n* Fixed bug when height > 512 in RGB -> YV12 conversion.\n* AviSynth now mimics VDubs way of handling dropped frames to avoid problems with buggy codecs.\n* Trim now returns (x-1) frames as supposed.\n* Fixed stereo setting in BlankClip\n\n\nOptimizations\n~~~~~~~~~~~~~\n\n* Added MMX RGB24->YUY2 conversion.\n* Minor changes to existing RGB32 -> YUY2 MMX.\n* Minor speedup to ISSE limiter.\n* Added SoftWire dynamic compiled horizontal resizer. Approximately 10-15% faster - maybe even more on P4.\n\n\nChanges\n~~~~~~~\n\n* AviSynth will now attempt to deallocate framebuffers, if memory usage is 25% above default values or SetMemoryMax().\n* Improved rounding precision in ISSE YV12 <-> YUY2 conversions.\n* Improved chroma upsampling quality in planar YV12 -> YUY2.\n* Better chroma alignment on interlaced YUY2 ->YV12.\n* Slightly better precision in audio conversion.\n* ApplyRange now checks if size and colorspace are the same.\n* Fixed float point exceptions being thrown in some applications, based on the CPU register settings. (Especially Delphi-based apps).\n\n\nChanges from 2.50 beta\n----------------------\n\n\nAdditions\n~~~~~~~~~\n\n* Added start/end parameters to ImageWriter.\n* Added Chr, Time and Spline script functions.\n* Added ISSE and MMX YUY2->YV12 conversions. Faster than XviD - and both interlaced and noninterlaced modes supported. Use ConvertToYV12(interlaced=true).\n* Added rewritten YV12->YUY2 (progressive) conversion to avoid using buggy XviD conversion. It also has better quality as it properly interpolates chromas as opposed to simply copying it. Speed should be the same. Use ConvertToYUY2(interlaced=true).\n* Added TurnLeft /TurnRight.\n* YToUV() now takes an optional third parameter, that contains luma for the final clip.\n* AudioLength() now returns the size in samples (do however beware of overflows on very long clips)\n* Added ApplyRange.\n\n\nBugfixes\n~~~~~~~~\n\n* Fixed Splice problems with YV12 from different sources. Audio is now automatically converted to the same format.\n* Fixed bug in YV12 stackvertical, causing corrupt images.\n* Fixed memory exception problem in Blur.\n* Fixed non-matching image type in Stack.\n* Fixed rounding in Temporalsoften mode 2.\n* Fixed crashbug in YUY2 mergechroma.\n* Fix bug in C version of YUY2->RGB24.\n* Fixed bug with uninitialized data in AviSource.\n* Fixed wrong pitch being used in Temporalsoften scenechange - could in rare cases lead to unexpected results.\n* Fixed rounding in some cases in Temporalsoften.\n* Doesn't add audio to track, if there is no present in AssumeSampleRate().\n* Fixed isBFF() and isTFF().\n\n\nOptimizations\n~~~~~~~~~~~~~\n\n* Put in Steady's new BitBlt code, and enabled it for ISSE capable processors.\n* Much \"conservative\" code removed. A general speedup should be expected.\n* Made SwapUV faster.\n\n\nChanges\n~~~~~~~\n\n* Removed all fieldbased/mod 4 checks.\n* Restored how fieldbased/framebased works.\n* Removed startup Box from installer.\n* Greyscale inserts value 128, instead of 127. Some users have reported a greenish tint.\n* Updated AssumeTFF and BFF to also write the information to VideoInfo.\n* Updated icons.\n* BMP support (output only) in ImageWriter.\n\nMajor changes from the 2.0.x line\n---------------------------------\n\n-   Native planar YV12 support.\n-   Multiple audiochannels. Unlimited number of channels is now\n    supported.\n-   Float samples support. AviSynth is now capable of processing samples\n    as floats.\n-   Automatic sample conversion. If some filters doesn't support a\n    specific sample type, they are converted to the format preserving most\n    quality (most often floats).\n-   Optimizations. Many basic features has been optimized, and now\n    performs much better than previous versions.\n-   Temporalsoften has a significant speed improvement, scenechange\n    detection and a new improved blend mode.\n-   Limiter can limit the YUV ranges, to avoid invalid color values and\n    improve compression.\n-   ColorYUV makes it possible to do very exact color corrections.\n    ColorYUV has built-in auto-whitebalance and auto-gain features.\n-   Select separate planes using UToY, VToY and merge them together\n    again, using YToUV.\n-   Fliphorizontal. implemented.\n-   SelectRangeEvery is now part of the core functions.\n-   Blur, Sharpen, Resize optimized.\n-   Fast XviD colorspace conversions.\n-   See clip info using the info() command.\n\n\nChanges from 2.07\n-----------------\n\n- Fixed crashbug in resize.\n- AviSynth now only includes ``\"*.avsi\"`` from the plugin directory\n- Changed maximum number of arguments from 40 to 1024.\n- Resampleaudio() caused crashes, if no audio was present.\n- Fixed: Exist() didn't work.\n\n\nChanges from 2.06\n-----------------\n\n- Script extensions:\n- - ``LeftStr(string, int size), RightStr(string, int size), MidStr(string,\n    int first, int length), FindStr(string, string), RevStr(string),\n    StrLen(string)``\n- - ``Sign(int), sign(float), Nop, Rand([int limit]), Select(index, item0\n    [,item1...]), Exist(string filename)``\n- - ``VersionNumber(), VersionString()``\n- - ``IsRGB24(clip), IsRGB32(clip), Int(float), Frac(float), Float(int),\n    Value(string), HexValue(string).``\n- Strings can be compared using \"<\" ,\">\",\"<=\",\">=\" operators (case insensitive).\n- Color option for Fades , Letterbox, and Addborders.\n- Subtitle alignment and spacing options, added y=-1 centering support (x=-1\n  undocumented support remains) and defaults for x,y and align vary depending\n  on each other's settings.\n- Optimization for recent BlankClip() RGB24 bug fix.\n- Fixed ceil, floor and round functions.\n- Fixed BlankClip RGB24 with odd widths.\n- Fixed DB scale off by 2x in volume.\n- Added FadeIn / FadeIn2 to fade in video and audio.\n- Added AssumeSampleRate to change the samplerate without resampling (yes,\n  this will lead to desync!).\n- Fixed one frame wrong offset in trim, when second argument is negative.\n- Added abs(integer) and abs(float).\n- Fixed '%' (mod) in scripts, so it returns absolute values.\n- Added a boolean to DirectShowSource, so seeking can be manually disabled,\n  if it works very slowly.\n- Added PointResize() function. Resamples as \"Nearest Neighbour\" in VirtualDub.\n- Added SetWorkingDir() function.\n- Fixed Normalize crashes.\n- Added German documentation.\n\nChanges from 2.05\n-----------------\n\n- Fixed potential crashbug in Resize - real fix instead of previous hack.\n- Default alignment is now 16 bytes, which should be faster on P4.\n- Fixed bug in RGB32 greyscale, when with not divideable with 2.\n- Added example scripts. - Added installer/uninstaller. No more need to\n  fiddle with .reg files and regedit.\n- Fixed Trim, so negative values works as documented.\n- Fixes to plugin autoloading: - freezed when invalid dll encountered, was\n  locking files unnecessarily, now also loads avisynth plugins with VDF\n  extension.\n- Made forward seeking fallback code in DirectShowSource files - it will not\n  freeze anymore, just be very slow, since it has to decode all inbetween\n  frames!\n- Added LanczosResize which uses the Lanczos3 algorithm - it provides better\n  quality than BicubicResize in many cases.\n- Better rounding precision in BicubicResize/BilinearResize.\n- Optimizations to YUY2 BicubicResize/BilinearResize.\n- New ResetMask() filter: sets the mask to \"all-opaque\" (RGB32 only).\n- ChangeFPS() now changes the framecount (thanks to Xesdeeni).\n- AVI files, that contains an invalid first frame are now rejected - there is\n  no way of handling this situation gracefully. Segmented AVI's automatically\n  skip these segments, and will NOT return an error.\n- Better parameter checks on Crop() and LetterBox().\n- Fixed wrap at right side of picture in RGB\n  BicubicResize()/BilinearResize().\n- Fixed another Chroma wrap issue in BicubicResize()\n- Added optional pixel_type parameter to AVISource and siblings to force a\n  decompression format (YUY2, RGB32 or RGB24).\n- Added optional left and right parameters to Letterbox - parameters are\n  placed after the existing to preserve compatibility.\n- Added EnsureVBRMP3Sync(clip), to avoid desync of VBR-compressed\n  mp3-soundtrack. This will slow seeking down considerably, but is very useful\n  when using trim() for instance. Always use before trim().\n- BugFix: Fixed crashbug in Resize functions on some machines.\n- AviSource always returns last valid frame on decompression errors.\n- Added check for invalid frame 0 (mostly seen in SegmentedAviSource()).\n\nChanges from 2.04\n-----------------\n\n- Additions to the Compare filter (Statistics over several frames)\n- Reorder function loading to hopefully give plugins precedence over filters\n- Added LowPassAudio(frequency) and HighPassAudio(frequency)\n- Many updates and additions to documentation.\n- New function: String(value) - converts any AVSValue to string.\n- Bumped number of plugins to 50 from 30\n- Avisynth now allocates minimum 16MB cache, or otherwise 1/4th of free\n  physical memory.\n- Plugin autoloading (Create string regkey:\n  HKEY_LOCAL_MACHINE\\Software\\Avisynth\\PluginDir) (still in alpha)\n- Crash-on-exit bugfix in SegmentedAviSource.\n- Audio-related bugfix in AVISource.\n- Bugfix in FilteredResizeH (see bug [ 588402 ]) minor optimizations too.\n- Bugfix: TemporalSoften\n- Bugfix: dropped frame (introduced in 2.04).\n- Fixed bug in Pow(x,y)\n\nChanges from 2.03\n-----------------\n\n- Compressed audio support in AVISource, AVIFileSource and OpenDMLSource.\n  Boolean parameter after clip turns it off.\n- Compile fix in temporalsoften.\n\nChanges from 2.02\n-----------------\n\n- Fixed EMMS bug in ColorKeyMask\n- Fixed YUY2 detection issues in Layer\n- Added friendly error message for Layer ops\n- GetLeftChannel - Returns left channel.\n- GetRightChannel - Returns right channel.\n- MonoToStereo(clip1_left,clip2_right) - muxes two clips together as one\n  stereo clip.\n- MixAudio(clip_1,clip_2,float clip1_volume, float clip2_volume) Mixes two\n  audio sources together.\n- Added ConvertBackToYUY2() That only uses chroma from the left pixel to\n  avoid shifting chroma color by multiple YUY2->RGB>YUY2 conversions.\n  ConvertToYUY2 remains unchanged.\n- Added Documentation for new parameters\n- Added sound to Loop() function.\n- New function ConvertToMono(clip) - convert stereo to mono.\n- New function KillAudio(clip) removes audio from clip. Use this if you get\n  crashes with compressed AVI sound.\n- new filter: ColorKeyMask + bugfix in Layer\n- New function Normalize(clip, float max_left, float max_right). Normalizes\n  audio. Both floats are optional. If maximum values (0 to 1) are used, the\n  stream will peak at this level, otherwise the peak will at full volume.\n- TemporalSoften (MMX & C ) (previously released as plugin TemporalSoften2)\n- MMX optimized HorizontalReduceBy2() in YUY2 mode.\n- Corrected one pixel offset bug in VerticalReduceby2().\n- MMX is now pixelperfect in compare with C implementations.\n- Changed order in ReduceBy2() since VerticalReduceBy2 is faster.\n- VerticalReduceBy2() has been MMX optimized. More than twice as fast. Filter\n  checks if image is too small to be reduced.\n- Colorbars() now also generates a test tone. Test tone is a 440Hz sine at\n  48KHz, 16 bit, stereo. The tone pulses in the RIGHT speaker, being turned on\n  and off once every second.\n- ResampleAudio() now skips conversion, if samplerate is already at the given\n  rate.\n- No athlon codes in merge.\n- Converttoyuy2 MMX optimized.\n- Fixes in greyscale() in RGB mode.\n- Optimized layer() and decomb-filters.\n- Compare(clip filtered, clip original, string channels=\"\", string\n  logfile=\"\", bool show_graph=true)\n- AssumeTFF() and AssumeBFF() to force parity\n- Documentation restructured and updated.\n\nPlease report bugs at `Sourceforge Avisynth2 page`_ - or - `Doom9's Avisynth Developer Forum`_\n\n$Date: 2008/12/22 01:26:05 $\n\n.. _Sourceforge Avisynth2 page:\n    http://sourceforge.net/projects/avisynth2\n.. _Doom9's Avisynth Developer Forum:\n    http://forum.doom9.org/forumdisplay.php?s=&forumid=69\n.. _vfr content in DSS:\n    http://forum.doom9.org/showthread.php?s=&threadid=90938\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/changelist26.rst",
    "content": "\nChanges from 2.5 to 2.6\n-----------------------\n\n\nAdditions\n~~~~~~~~~\n\n-   DirectShowSource support non-standard pixel types \"YV24\" and \"YV16\".\n-   Info: Audio only clip now creates its own canvas video.\n-   AviSource: Include packed/padded processing and -ve biHeight logic\n    for compressed input.\n-   Add Script Functions :- BitLRotate, BitRRotate, BitChange, BitClear,\n    BitSet, BitTest and their asm aliases.\n-   Add WeaveRows (blit cost) and WeaveColumns (slow) frame combining\n    filters.\n-   Add AudioDuration() [as float seconds], IsY8(), IsYV411() &\n    PixelType() [as a string] script functions.\n-   Add Echo and Preroll filters.\n-   Add IScriptEnvironment::GetAVSLinkage() and DLLExport AVS_linkage for\n    host usage of avisynth.dll.\n-   DirectShowSource, 2.6 plugin, support pixel types \"AYUV\" as YV24,\n    \"Y41P\" and \"Y411\" as YV411.\n-   AviSource: Add Full and Auto pseudo pixel_types. Full is all\n    supported. Auto is YV12, YUY2, RGB32, RGB24 & Y8.\n-   Add \"AudioLengthS\" [as a string], \"Ord\" & \"FillStr\" script functions.\n-   Add AudioTrim(clip, float, float) audio priority trimming, args in\n    fractional seconds.\n-   Add Trim(M, Length=N[, Pad=False]) and Trim(M, End=N[, Pad=False])\n    function overloads for explicit Trimming. Length=0 means zero frame clip.\n    End=0 means end at frame 0.\n-   Add SeparateRows (zero cost) and SeparateColumns (slow) frame\n    slashing filters.\n-   Add Script Functions :- Acos, Asin, Atan, Atan2, Cosh, Sinh, Tanh,\n    Fmod, Log10, BitLShift, BitRShiftS, BitRShiftU and Hex.\n-   Add \"ConditionalSelect\",\"csc+[show]b\" runtime filter.\n-   Add dither option to Levels, RGBAdjust & Tweak.\n-   Add BitAnd(), BitNot(), BitOr() & BitXor() script functions.\n-   Add StrCmp() & StrCmpI() script functions.\n-   Add YV24 support for Limiter show option.\n-   Add \"Global OPT_dwChannelMask={int}\"\n-   Add 0x0063F speaker mask for 7.1 WAVE_FORMAT_EXTENSIBLE.\n-   Add .dll DelayLoad exception texts to crash message formatter.\n-   ImageWriter, add support for printf formating of filename string,\n    default is (\"%06d.%s\", n, ext);\n-   Add avs_get_error(AVS_ScriptEnvironment*); to avisynth_c interface.\n-   Catch and save AvisynthError text in more avisynth_c entry points,\n    for kemuri-_9.\n-   Add ScriptName(), ScriptFile(), ScriptDir() functions\n    (WarpEnterprises).\n-   Add SkewRows filter.\n-   Histogram, Levels mode, Improve colour of chroma legends.\n-   ConditionalFilter, teach about string results.\n-   Add some more \"Add/Remove Software\" registry keys to the Installer\n    (XhmikosR).\n-   AviSource: Support both packed and DWORD padded raw planar input like\n    with DSS.\n-   Add IScriptEnvironment::ApplyMessage()\n-   Add ImageSourceAnim (Wilbert)\n-   Support user upgrade to 178 DevIL.dll (They need to manage CRT\n    dependancies).\n-   ImageSource: palette and compressed bmp images load correctly now\n    (issue 894702) [need 178 DevIL.dll]\n-   ImageSource: support for other formats like: gif, exr, jp2, psd, hdr\n    [need 178 DevIL.dll]\n-   Add YV24 mode to ColorBars.\n-   Add ColorBarsHD based on arib_std_b28.\n-   C-api usability enhancements from kemuri9 [Work in progress!]\n-   Add Undefined(), AudioLengthLo(), AudioLengthHi(), IsYV16() &\n    IsYV24() script functions\n-   Allow newlines (and hence comments) before '{' -- Gavino\n-   Added IScriptEnvironment::DeleteScriptEnvironment()\n-   Added Histogram, population clamp % factor for \"Levels\" mode,\n-   Histogram, revert \"Stereo\" mode to YV12, Add \"StereoY8\" mode,\n-   AviSource: Support fourcc \"GREY\" as Y8\n-   Added support for argument passing and EAX return value to\n    SoftwireHelper.\n-   Added \"Global OPT_VDubPlanarHack=True\" to flip YV24 and YV16 chroma\n    planes for old VDub's.\n-   Added \"Global OPT_AVIPadScanlines=True\" option for DWORD aligned\n    planar padding\n-   Added Matrix=\"AVERAGE\" mode.\n-   Added ContinuedDenominator/ContinuedNumerator(f[]i[limit]i) script\n    functions.\n-   Tweak: fix MaskPointResizing + put back Dividee ISSE code (use\n    sse=true).\n-   Added ChromaInPlacement, ChromaOutPlacement and ChromaResample\n    options to planar colour conversions.\n-   Added MaskHS.\n-   Source tweaks to get ready for VC8.\n-   Add Y8 for DevIL, planarize EBMP.\n-   Planar support for many filters.\n-   Added Info() time indicator on audio length and video (current frame\n    & total). (2.5.8)\n-   Added UtoY8 and VtoY8.\n-   Added more info to Info(). (2.5.8)\n-   ColorYUV: Added all adjustment parameters as conditional variables\n    \"coloryuv_SETTING\". Enable by setting conditional=true.\n-   ConditionalReader: Added support for type String.\n-   ConditionalReader: Added offset keyword to offset all frame numbers\n    after the keyword.\n-   Added SincResize() with optional taps parameter (default is 4).\n-   Added Custom band setting to SuperEQ to allow all 16 bands to be set\n    from script. Usage: SuperEQ(clip,band1, band2, band3....) values are dB\n    in float.\n-   Added fast 0-1-0 kernel for YV24 to ConvertBacktoYUY2().\n-   Added core formats: YV24, YV16, Y8, YV411.\n\n\nBugfixes\n~~~~~~~~\n\n-   Fixed DirectShowSource incorrect byte order for unpacking of pixel\n    type \"AYUV\".\n-   Fixed HexValue parsing values greater than 7FFFFFFF, now as unsigned\n    hex.\n-   Fixed ConditionalReader memory overrun parsing bools.\n-   Fixed ResampleAudio NOP test to compare vi.num_audio_samples, not\n    sample rate.\n-   Fixed YV24 -> RGB24 overrun cleanup for widths%16 == 5.\n-   Fixed RGB24 AddBorders with right=0.\n-   Fixed conditional_functions error message names (Wilbert).\n-   Fixed Audio cache ac_expected_next regression.\n-   Fixed ImageSource deal with add 1 to IL_NUM_IMAGES bug (Wilbert)\n-   Fixed Overlay YV24 V plane conversion.\n-   Fixed Overlay YV24 mode with shared input clip, needed a\n    MakeWritable.\n-   Fixed ImageReader upside down TIFF in 178 DevIL. (Wilbert)\n-   Fixed string+string bug when total length is 4096*K-1.\n-   Fixed SincResize misuse of \"int abs(int)\" (Gavino). Fix Lanczos and\n    Blackman sinc use of float == 0.0, use small limit \"> 0.000001\".\n-   Fixed Classic mode legend drawing for planar right limit and yuy2\n    centre line.\n-   Fixed possible MT race. Use \"env->ManageCache(MC_IncVFBRefcount,\n    ...)\" in ProtectVFB.\n-   Fixed SwapYToUV output image size bug for 3 clip case.\n-   Fixed Crop limit tests for RGB.\n-   Fixed Overlay yellow tint on rec601 RGB import conversion.\n-   Fixed YtoUV() output image size bug for 3 clip case.\n-   Fixed ConvertToPlanar chroma alignment.\n-   Fixed Levels (RGB) change use of PixelClip(x) to min(max(x, 0), 255).\n-   Fixed SwapYtoUV yuy2 crash (StainlessS).\n-   Fixed Overlay saturate UV in add and subtract mode.\n-   Fixed Info.h range protect display characters (StainlessS).\n-   Fixed AviSource packed planar import chroma offsets.\n-   Fixed AviSource NULL GetWritePtr() failure due to premature setting\n    of last_frame.\n-   Fixed Mask rounding in greyscale calcs (Wilbert), minor refactor.\n-   Fixed SelectRangeEvery audio snafu (Gavino).\n-   Fixed LoadPlugin, SaveString of result string.\n-   Fixed LoadPlugin, use _vsnprintf.\n-   Fixed LoadVirtualdubPlugin, don't add vdub filter to chain on load\n    failure.\n-   Fixed rounding in RGB HResize (JoshyD) (affects all resizers)\n-   Fixed error message name in the filter VerticalReduceBy2\n-   Fixed SeparateFields() with variable parity input clip (Wilbert)\n-   Fixed AviSource, cannot cast__int64* to long*, it does not work!\n-   Fixed ConditionalReader: Don't allow out of range \"Range\" to\n    overwrite edge values\n-   Fixed MonoToStereo with stereo sources.\n-   Fixed MergeChannels with only 1 input clip.\n-   Fixed AviSource support for negative height DIB format AVI's.\n-   Fixed Audio cache crashes.\n-   Fixed resize with YV411, missing code.\n-   Fixed ConditionalReader rounding with integer interpolation.\n-   Fixed Softwire SSE2 bugs.\n-   Fixed SSSE3 CPU detection.\n-   Fixed SSSE3, SSE4.1 & SSE4.2 detection.\n-   Fixed Fastwire encoding of instructions that are >2 opcodes\n    (SSSE3+4).\n-   Fixed _RPT5() macro for debug builds\n\n\nOptimizations\n~~~~~~~~~~~~~\n\n-   ConvertToPlanarGeneric explicit add Cache before chroma rescaler.\n-   Overlay minor refactor YV12 -> 444 chroma\n-   Speedup ConvertToMono(), minor refactor MixAudio().\n-   Change StackVertical/Horizontal to interative instead of recursive,\n    2^N performace increase for 3 and more clips, i.e. 1 blit total instead\n    of blit(blit(blit(...\n-   RGBtoY8 Dynamic ASM code, support for RGB24.\n-   YV24backtoYUY2 Dynamic ASM code.\n-   UtoY8, VtoY8 abuse subframe, zero cost.\n-   YV24<->RGB Add SSE2 and SSSE3 code paths, get rid of wide_enough.\n-   ConvertToYUY2 Add SSE2, MMX restore full speed on platforms with poor\n    ooox.\n-   ConvertAudio, manage tempbuffer and floatbuffer independantly.\n-   ConvertAudio, prefer SSE2 over 3DNow for super AMD cores.\n-   Info.h, full refactor, a good example of \"Never look down\", thx\n    StainlessS\n-   DoubleWeaveFrames, If A not writable, try to write to B, else make\n    new frame\n-   Histogram, fix GetFrame/NewVideoFrame call order\n-   HResizer, interleave code +4% faster\n-   YtoUV() Abuse Subframe to snatch the Y plane / UV planes, Derestrict\n    destination colorformat autogeneration.\n-   ImageSource: Improve thread interlock code\n-   ConditionalReader/WriteFile: Full refactor.\n-   Replace _strdup with SaveString in AddFunction (Thanks Gavino)\n-   SuperEQ: Improve channel unpacking/packing code.\n-   H-Resize: Use SSE4.1 (movntdqa) loads for use once memory access.\n-   H-Resize: Added SSE2 horizontal unpacker.\n-   Resize: Use SSE3 (lddqu) loads for unaligned memory access.\n-   Added ultra fast vertical PointResizer (64 pixel/cycle).\n-   Added dynamic SSSE3 vertical resizer (16 pixel/cycle) ~ twice as fast\n    as old MMX.\n-   Added dynamic SSE2 vertical resizer (16 pixel/cycle).\n-   Added dynamic MMX vertical resizer (8 pixel/cycle).\n-   Added SSSE3 version for RGB<->YV24 conversions.\n-   Added dynamic compiled MMX/iSSE for RGB<->YV24 conversions. Speed is\n    approx 200% of C-code.\n\n\nChanges\n~~~~~~~\n\n-   BlankClip: Supply useful defaults for new Audio/Video when using a\n    Video/Audio only template clip.\n-   BlankClip: Use duration from Audio only template as default length\n    for new clip.\n-   Define new IClip::SetCacheHints cachehint constants.\n-   Force int call arguments to user script function float params to be\n    explicit floats.\n-   Splice pass CacheHints through to both children in + and ++ mode.\n-   WriteFileStart/End save current_frame and set Last.\n-   ConditionalReader do not ignore syntax errors in input file.\n-   ImageSourceAnim Pad/Crop images to match first frame (Wilbert)\n-   ImageSource Add version to messages (Wilbert)\n-   Initial 2.6 API entry point linkage.\n-   Use Invoke for graph tail, enhance non-clip output error reporting.\n-   PopContext when inner block Asserts/throws (maxxon).\n-   Remove duplicate definitions (Wilbert).\n-   Enhance non-clip output error reporting.\n-   Explicitly specify calling sequence as __cdecl for Avisynth softwire\n    routines, (was the compiler default)\n-   Use env->Invoke(\"Cache\", ...) everywhere instead of\n    Cache::Create_Cache(), allows for Cache to be overloaded by a plugin.\n-   ConvertToYUY2 Change from 0-1-1 kernel to 1-2-1 kernel.\n-   Tweak make Interp same units as minSat and maxSat.\n-   Check HKEY_CURRENT_USER for PluginDir first. (henktiggelaar)\n-   Make forced, -ve, planar alignment of chroma planes match\n    subsampling.\n-   Enforce planar alignment restrictions.\n-   C-api: Remove func sub-struct from AVS_Library struct\n-   Add error code to plugin load failure message\n-   Make default planar AVI output packed. Control with\n    OPT_AVIPadScanlines=True.\n-   WriteFile() now supports unlimited number of unlimited strings. (was\n    16 by 254 byte strings).\n-   ConvertToRGB*, make C++ code sample chroma the same as the MMX code\n    i.e. use both pixels.\n-   ConvertToRGB*, use YV24 path for planar, complain when options are\n    present for YUY2.\n-   ConvertToYUY2, use YV16 path for planar, complain when options are\n    present for RGB\n    -   see: http://forum.doom9.org/showthread.php?p=1378381#post1378381\n-   Thread safe code, part 2.\n-   Correct IClip baked documentation\n-   Passify compilation error/warnings (XhmikosR)\n-   for, const, extern and ansi patches for VC2008 (SEt)\n-   Disable OPT_RELS_LOGGING option\n-   Change implicit Last parsing for argless, bracketless calls to match\n    bracketed cases. (Gavino)\n-   DirectShowSource: Support last minute format renegotiation thru\n    IPin::QueryAccept() & Validate the size of the provided directshow\n    buffer.\n-   Remove non ascii chars from comments.\n-   Add core stubs for DirectShowSource, TCPServer & TCPSource, report\n    when plugins are missing.\n-   Add note for original source downloads - SoundTouch\n-   Add more lineage history to Info()\n-   Move convertaudio, alignplanar, fillborder & MIN/MAX_INT definitions.\n-   Run AtExit before dismantling world.\n-   Change setcachehints definition from void to int. Test IClip version\n    >= 5.\n-   Move PixelClip definition to avisynth.cpp\n-   SubTitle, etc, make X & Y options float (0.125 pixel granularity).\n-   ShowSMPTE() supports all integer FPS and multiplies of drop frame\n    FPS.\n-   SubTitle, stop overwriting string constants (Gavino).\n-   SubTitle, improve pixel registration (Gavino).\n-   Make Info() CPU display hierarchical.\n-   Thread safe code, part 1.\n-   SoftwireHelper: explicit hardware exception handling.\n-   Resize: Moved GetResampleFunction into Resamplefuntion, to allow\n    overrides.\n-   Resampler: Removed dead stlf code.\n-   Updated Soundtouch to 1.31 (2.5.8)\n-   Put dynamic matrix conversion into separate file.\n-   Moved chroma subsampling to image_type section.\n-   Added specific error reporting when requesting chromasubsampling with\n    Y8.\n-   Split up merge and plane Swappers.\n-   Split up Plane transfers into separate classes.\n-   Added automatic destination colorspace detection on planar YtoUV.\n-   Took out greyscale and RGB32<->RGB24 from convert.cpp and placed them\n    in separate files.\n-   All code assuming UVwidth = Ywidth/2 and similar should be gone.\n\nPlease report bugs at `Sourceforge Avisynth 2 page`_ - or - `Doom9's Avisynth\nforum`_\n\n$Date: 2013/05/01 00:21:32 $\n\n.. _Sourceforge    Avisynth 2 page:\n    http://sourceforge.net/projects/avisynth2\n.. _Doom9's    Avisynth forum:\n    http://forum.doom9.org/forumdisplay.php?s=&forumid=33\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/changelist34.rst",
    "content": "Changes from to 3.4 (20191021)\n------------------------------\n\n\nAdditions\n~~~~~~~~~\n\nBuild environment, Interface\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n- Merges in the MT branch, the current state of pinterf/MT, and packaging fixes\n- Development HEAD is the master repo again in https://github.com/AviSynth/AviSynthPlus\n- Bumps version to 3.4\n\nBugfixes\n~~~~~~~~\n\n\nOptimizations\n~~~~~~~~~~~~~\n\n\n\nPlease report bugs at `github AviSynthPlus page`_ - or - `Doom9's AviSynth+\nforum`_\n\n$Date: 2021/12/07 13:36:0 $\n\n.. _github AviSynthPlus page:\n    https://github.com/AviSynth/AviSynthPlus\n.. _Doom9's AviSynth+ forum:\n    https://forum.doom9.org/showthread.php?t=181351\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/changelist34pre.rst",
    "content": "\nChanges from to r1825 to last <3.x build\n----------------------------------------\n\nChangelog copied here as-is.\nBuilds are from pinterf's Avisynth+ branch, versioned with build numbers\n\n20190829 r2915\n--------------\n- Changed: Trim, FreezeFrame, DeleteFrame, DuplicateFrame, Reverse and Loop are using frame cache again (similar to classic Avs 2.6)\n- Enhanced: Expr: faster exp, log, pow for AVX2 (sekrit-twc)\n- ConditionalReader: allow empty value in text file when TYPE string\n- Fix: Expr: fix non-mod-8 issues for forced RGB output and YUV inputs\n- New: AviSource support v308 and v408 format (packed 8 bit 444 and 4444)\n- Fix: AviSource v410 source garbage (YUV444P10)\n- Fix: Expr: when using parameter \"scale_inputs\" and the source bit depth conversion occured, predefined constants\n  (ymin/max, cmin/max, range_min/max/half) would not follow the new bit depth\n- Fix: ConvertToRGB from 32bit float YUV w/ full scale matrixes (pc.601, pc.709, average)\n- Fix: FlipHorizontal RGB48/64 artifacts\n- Enhanced: a bit quicker FlipHorizontal\n- Fix: RGB64 Blur leftmost column artifact\n- Enhanced: quicker RGB24/48 to Planar RGB for AVX2 capable processors\n- Fix: Strip alpha channel when origin is YUVA and using ConvertToYV12/ConvertToYV16/ConvertToYV24 funtions\n- Fix: garbage with ConvertToYUY2 from 8 bit YUVA colorspaces\n- Enhanced: Colorbars to accept RGB24, RGB48, YV411 and 4:2:2 formats for pixel_type (now all colorspaces are supported)\n- Fix: shifted chroma in ColorBars and ColorBarsHD for YUV444PS\n- Fix: ConvertToY8, ConvertToYV12, ConvertToYV16, ConvertToYV24 are now allowed only for 8 bit inputs.\n  Formerly these functions were allowed for 10+ bit colorspaces but were not converted to real 8 bit Y8/YV12/16/24.\n  Use ConvertToY, ConvertToYUV420, ConvertToYUV422, ConvertToYUV444 instead which are bit depth independent\n- New parameter in ColorYUV, RGBAdjust, Overlay, ConditionalReader: \n  \n  ``string \"condvarsuffix\"``\n  \n  Allows multiple filter instances to use differently named conditional parameters.\n  \n  Prevents collision and overwrite of variables which are used by different ConditionalReader instances.\n  \n  See Conditional Variables section of http://avisynth.nl/index.php/ColorYUV.\n  \n  How does it work: when reading the global variables, the \"condvarsuffix\" parameter is appended to the variable name.\n  E.g. ColorYUV will read \"coloryuv_gain_y_a\" instead of \"coloryuv_gain_y\" when condvarsuffix = \"_a\" is provided for ColorYUV.\n  In the matching ConditionalReader one have to use the modified name as well:\n\n::\n\n      ConditionalReader(\"coloryuvoffset.txt\", \"coloryuv_gain_y\", false, CondVarSuffix = \"_a\") # \"_a\" is added here by parameter\n\nor specify the suffixed name directly:\n\n::\n\n      ConditionalReader(\"coloryuvoffset.txt\", \"coloryuv_gain_y_a\", false) # \"_a\" is added here manually\n\nExample:\n\n::\n\n    Colorbars(512,256).ConvertToYV12.Trim(0,299)\n    ConditionalReader(\"coloryuvoffset.txt\", \"coloryuv_gain_y\", false)\n    a=ColorYUV(cont_y=10, conditional=true)\n\n    Colorbars(512,256).ConvertToYV12.Trim(0,299)\n    ConditionalReader(\"coloryuvoffset2.txt\", \"coloryuv_gamma_y\", false, condvarsuffix=\"_a\")\n    b=ColorYUV(cont_y=10, conditional=true, condvarsuffix=\"_a\") # will read coloryuv_gain_y_a, coloryuv_gamma_y_a, etc.\n\n    Stackvertical(a,b)\n\n- Fix: ColorBars: pixel_type planar RGB will set alpha to 0 instead of 255, consistent with RGB32 Alpha channel\n- Fix: text colors for YUV422PS - regression since r2728 (zero-centered chroma)\n- New: VirtualDub2 to display 8 bit planar RGB (needs up-to-date VirtualDub2 as well)\n  VfW interface to negotiate 8 bit Planar RGB(A) with FourCCs: G3[0][8] and G4[0][8], similar to the 10-16 bit logic\n  (When you would still stick with RGB24/RGB32/RGB64 export, use OPT_Enable_PlanarToPackedRGB = true)\n- Fix: planar RGBA Alpha on VfW was uninitialized because it wasn't filled.\n- Layer: big update\n\n  Previously Layer was working only for RGB32 and YUY2. Overlay was used primarily for YUV. Now Layer accepts practically all formats (no RGB24).\n  \n  Note that some modes can be similar to Overlay, but the two filters are still different.\n  \n  - Overlay accepts mask clip, Layer would use existing A plane.\n  - Overlay \"blend\" is Layer \"add\", Overlay \"add\" is different.\n  - Lighten and darken is a bit different in Overlay.\n  - Layer has \"placement\" parameter for proper mask positioning over chroma.\n\n  Other news\n  \n  - Support for all 8-32 bit Y and planar YUV/YUVA and planar RGB/RGBA formats\n    - When overlay clip is YUVA and RGBA, then alpha channels of overlay clip are used (similarly to RGB32 and RGB64 formats)\n    - Non-alpha plane YUV/planar RGB color spaces act as having a fully transparent alpha channel (like the former YUY2 only working mode)\n    - Note: now if destination is YUVA/RGBA, the overlay clip also has to be Alpha-aware type.\n    - Now A channel is not updated for YUVA targets, but RGBA targets do get the Alpha updated (like the old RGB32 mode did)\n    - Todo: allow non-Alpha destination and Alpha-Overlay\n  - New parameter: float \"opacity\" (0.0 .. 1.0) optionally replaces the previous \"level\". Similar to \"opacity\" in \"Overlay\"\n    \n    For usage of \"level\" see http://avisynth.nl/index.php/Layer\n    \n    \"opacity\" parameter is bit depth independent, one does not have to fiddle with it like had to with level (which was maxed with level=257 when RGB32 but level=256 for YUY2/YUV)\n\n  - threshold parameter (used for lighten/darken) is autoscaled.\n    Keep it between 0 and 255, same as it was used for 8 bit videos.\n  - new parameter: string \"placement\" default \"mpeg2\".\n    Possible values: \"mpeg2\" (default), \"mpeg1\".\n    Used in \"mul\", \"darken\" and \"lighten\", \"add\" and \"subtract\" modes with planar YUV 4:2:0 or 4:2:2 color spaces (not available for YUY2)\n    in order to properly apply luma/overlay mask on U and V chroma channels.\n  - Fix some out-of-frame memory access in YUY2 C code\n  - Fix: Add proper rounding for add/subtract/lighten/darken calculations. (YUY2, RGB32, 8 bit YUV and 8 bit Planar RGB)\n  - Fix: \"lighten\" and \"darken\" gave different results between yuy2 and rgb32 when Threshold<>0\n    - Fixed \"darken\" for RGB32 when Threshold<>0\n    - Fixed \"lighten\" and \"darken\" for YUY2 when Threshold<>0\n    \n    All the above was done by specification:\n    \n    - Add: \"Where overlay is brigher by threshold\" => e.g. Where overlay is brigther by 10 => Where overlay > src + 10\n    \n    Calculation: alpha_mask = ovr > (src + thresh) ? level : 0;\n    \n    - Add: \"Where overlay is darker by threshold\" => e.g. Where overlay is darker by 10 => Where overlay < src - 10\n    \n    Calculation: alpha_mask = ovr < (src - thresh) ? level : 0;\n    \n    The only correct case of the above was \"lighten\" for RGB32, even in Classic Avisynth. Note: Threshold=0 was O.K.\n  - (Just an info: existing lighten/darken code for YUY2 is still not correct, messing up chroma a bit,\n    since it uses weights from even luma positions (0,2,4,...) for U, and odd luma positions (1,3,5,...) for V)\n\n- Avisynth C interface header (avisynth_c.h):\n\n  - cosmetics: functions regrouped to mix less AVSC_API and AVSC_INLINE, put together Avisynth+ specific stuff\n  - cosmetics: remove unused form of avs_get_rowsize and avs_get_height (kept earlier for reference)\n  - use #ifndef AVSC_NO_DECLSPEC for AVSC_INLINE functions which are calling API functions\n  - define alias AVS_FRAME_ALIGN as FRAME_ALIGN (keep the AVS_xxxx naming convention)\n  - dynamic loader (avs_load_library) uses fallback mechanism for non-existant Avisynth+ specific functions,\n    in order to have Avisynth+ specific API functions safely callable even when connected to classic Avisynth DLL\n    \n    The smart fallback mechanism for Avisynth+ specific functions ensures that if the functions are not loadable,\n    they will work in a classic Avisynth compatible mode:\n    \n    Example#1: e.g. avs_is_444 will call the existing avs_is_yv24 instead\n    \n    Example#2: avs_bits_per_component will return 8 for all colorspaces (Classic Avisynth supports only 8 bits/pixel)\n    \n    Affected functions and mapping:\n\n    - avs_is_rgb48, avs_is_rgb64, avs_is_yuv444p16, avs_is_yuv422p16, avs_is_yuv420p16, avs_is_y16: returns false (0)\n    - avs_is_yuv444ps, avs_is_yuv422ps, avs_is_yuv420ps, avs_is_y32: returns false (0)\n    - avs_is_yuva, avs_is_planar_rgb, avs_is_planar_rgba: returns false (0)\n    - avs_is_444: calls avs_is_yv24 instead\n    - avs_is_422: calls avs_is_yv16 instead\n    - avs_is_420: calls avs_is_yv12 instead\n    - avs_is_y: calls avs_is_y8 instead\n    - avs_num_components: returns 1 for y8, 4 for RGB32, 3 otherwise\n    - avs_component_size: returns 1 (1 bytes)\n    - avs_bits_per_component: returns 8 (8 bits)\n\n- filter \"Version\": update year, removed avs-plus.net link\n- Updated: TimeStretch plugin with SoundTouch 2.1.3 (as of 07.Jan 2019)\n- Source/Build system\n  - rst documentation update (qyot27) in distrib/docs/english/source/avisynthdoc/contributing/compiling_avsplus.rst\n  - GCC-MinGW build (huge thanks to qyot27)\n    \n    - various source fixes for MinGW builds, Avisynth core compiles fine, except external plugins Shibatch and DirectShowSource\n    - CMakeLists.txt updates (user selecteble CPU arch, MinGW things)\n    - PluginManager.cpp: [MSVC|GCC] should only load [MSVC|GCC] plugins (qyot27)\n      This commit simply tells GCC builds of AviSynth to use the value\n      of the PluginDir+GCC registry entry to find plugins, and ignore\n      PluginDir and PluginDir+.  Vice-versa for MSVC builds.\n      C plugins are an exception to this, since those can be loaded with\n      either MSVC- or GCC-built AviSynth+.\n    - GCC 8.3 support (see in distrib/docs/english/source/avisynthdoc/contributing/compiling_avsplus.rst)\n\n      - Howto: MSYS2/GCC: for windows based build environment see step-by-step instructions:\n        https://github.com/orlp/dev-on-windows/wiki/Installing-GCC--&-MSYS2\n      - CMake: choose generator \"MinGW Makefiles\" from CMakeGUI or\n\n          del CMakeCache.txt\n          \"c:\\Program Files\\CMake\\bin\\cmake.exe\" -G \"MinGW Makefiles\" .\n\n        then build with\n\n          mingw32-make -f makefile\n\n      - todo: fix plugin DLL names\n\n  - CMake: Visual Studio 2019 generator support, please update to CMake to 3.14.1\n  - Clang (LLVM) support with Visual Studio 2019 (16.0) / 2017 (15.9.9) (Latest Clang is 8.0 at the moment)\n\n    - CMakeLists.txt update\n    - Additional source fixes.\n    - Source lines for different processor targets (SSSE3 and SSE4.1) are now separated and are compiled using function attributes.\n\n    Clang howto:\n    \n    - Install LLVM 8.0 or later (http://releases.llvm.org/download.html, Windows pre-built libraries)\n    - Install Clang Power Tools & LLVM Compiler Toolchain (thx fuchanghao)\n\n      - https://marketplace.visualstudio.com/items?itemName=caphyon.ClangPowerTools\n      - https://marketplace.visualstudio.com/items?itemName=LLVMExtensions.llvm-toolchain\n\n    - (When using CMakeGUI) After Configure/Specify generator for this project, type LLVM for \"Optional Toolset to use (-T option)\"\n    - Known issues:\n    \n      - compiling Avisynth only .lib is generated (used for C api), .exp is missing\n      - When generating assembler output linking or other errors can happen\n      - LLVM 8.0 has sub-optimal avg_epu8 intrinsic \"optimization\", which is fixed in LLVM 9.0 (e.g. in snapshot build 21 June 2019)\n\n20181220 r2772\n--------------\n- Fix: Expr: possible Expr x64 crash under specific memory circumstances\n- Fix: Expr: safer code for internal variables \"Store and pop from stack\" (see: Internal variables at http://avisynth.nl/index.php/Expr)\n\n20181218 r2768\n--------------\n- New: Expr: allow input clips to have more planes than an implicitely specified output format\n  Expr(aYV12Clip, \"x 255.0 /\", format=\"Y32\") # target is Y only which needs only Y plane from YV12 -> no error\n- New: Expr: Y-plane-only clip(s) can be used as source planes when a non-subsampled (rgb or 444) output format implicitely specified\n  Expr(Y, \"x\", \"x 2.0 /\", \"x 3.0 /\", format=\"RGBPS\") # r, g and b expression uses Y plane\n  Expr(Grey_r, Grey_g, Grey_b, \"x\", \"y 2.0 /\", \"z 3.0 /\", format=\"RGBPS\") # r, g and b expression uses Y plane\n- Fix: ConvertToYUY2() error message for non-8 bit sources.\n- Fix: Y32 source to 32 bit 420,422,444 (introduced in big the zero-chroma-center transition)\n- Fix: ShowY, ShowU, ShowV crash for YUV (non-YUVA) sources\n- Speedup: ConvertToY12/16... for RGB or YUY2 sources where 4:4:4 or YV16 intermediate clip was used internally\n  (~1.5-2x speed, was a regression in Avs+, use intermediate cache again)\n- Fix: Allow ExtractY on greyscale clips\n- ImageReader/ImageSource: use cache before FreezeFrame when result is a multiframe clip (fast again, regression since an early AVS+ version)\n- Resizers: don't use crop at special edge cases to avoid inconsistent results across different parameters/color spaces\n- Fix: Histogram 'classic': rare incomplete histogram shown in multithreading environment\n- Fix: ImageReader and ImageWriter: if path is \"\" then it works from/to the current directory.\n- GeneralConvolution: Allow 7x7 and 9x9 matrices (was: 3x3 and 5x5)\n- GeneralConvolution: All 8-32 bit formats (was: RGB32 only): YUY2 is converted to/from YV16, RGB24/32/48/64 are treated as planar RGB internally\n  Since 32 bit float input is now possible, matrix elements and bias parameter now is of float type.\n  For 8-16 bit clips the matrix is converted to integer before use.\n- GeneralConvolution: Allow chroma subsampled formats to have their luma _or_ chroma processed. E.g. set chroma=false for a YV12 input.\n- GeneralConvolution: new parameters: boolean luma (true), boolean chroma(true), boolean alpha(true)\n    Default: process all planes. For RGB: luma and chroma parameters are ignored.\n    Unprocessed planes are copied. Using alpha=false makes RGB32 processing faster, usually A channel is not needed.\n- GeneralConvolution: MT friendly parameter parsing\n- New: UTF8 filename support in AviSource, AVIFileSource, WAVSource, OpenDMLSource and SegmentedAVISource\n  All functions above have a new bool utf8 parameter. Default value is false.\n- Experimental: new syntax element (by addewyd): assignment operator \":=\" which returns the assigned value itself.\n  (Assignment within an expression)\n  Examples:\n\n::\n\n      w := h := 256\n      \n      b := blankclip(width=w * 2, height = h * 3, length=40, pixel_type=\"yv12\")\n      bm = blankclip(width=w, height = w).letterbox(2,0,2,0, color=$ff)\n      b\n      \n      for(j = 0, 1, 1) {\n          for(i = 0, 1, 1) {\n              e = 0 + i * 16 + j * 16 * 4\n              ce = string(e)\n              c = bm.subtitle(\"Y = 0x\" + hex(e) + \" \" + ce)\n              eval(\"c\" + string(i) + string(j) + \" := c\")\n              b := b.overlay(c, x = i * w, y = j * h)\n          }\n      }\n      \n      cx = c00.trim(0, 9) + c01.trim(0, 9) + c10.trim(0, 9) + c11.trim(0, 9)\n      \n      b := overlay(cx, x = 0, y = w * 2)\n      \n      /* defined NEW_AVSVALUE at build */\n      array = [99, 101, \"303\", cnt := 4]\n      \n      for(j = 0, cnt - 1, 1) {\n          b := subtitle(string(array[ind := j]), x = 100, y=(j+1) * 20)\n      }\n      \n      g := b.tstfunc(kf := \"first\", ks := \"second\")\n      \n      g := subtitle((s := 4) > 0 ? t := \"left\" : t := \"right\", y = 100)\n      g := subtitle(string(s) + \" \" + t + \" \" + ks, y = 150)\n      \n      eval(\"\"\"h := g.subtitle(\"G\", x=200, y = 20)\"\"\")\n      \n      h.subtitle(\"H \" + string(ind), x = 300, y = 20)\n      \n      \n      function tstfunc(c, d, e) {\n          if (f := 1 < 2) {\n              c.subtitle(string(f) + e, y = 50)\n          } else {\n              c.subtitle(d, y = 50)\n          }\n      }\n\n\n20180702 r2728\n--------------\n- New: Expr: implement 'clip' three operand operator like in masktools2\n  Description: clips (clamps) value: x minvalue maxvalue clip -> max(min(x, maxvalue), minvalue)\n- New: Expr: Parameter \"clamp_float\"\n\n    True: clamps 32 bit float to valid ranges, which is 0..1 for Luma or for RGB color space and -0.5..0.5 for YUV chroma UV channels\n    Default false, ignored (treated as true) when scale_inputs scales float\n\n- New: Expr: parameter \"scale_inputs\" (default \"none\")\n\n    Autoscale any input bit depths to 8-16 bit for internal expression use, the conversion method is either full range or limited YUV range.\n\n    Feature is similar to the one in masktools2 v2.2.15\n\n    The primary reason of this feature is the \"easy\" usage of formerly written expressions optimized for 8 bits.\n\n    Use\n    \n    - \"int\" : scales limited range videos, only integer formats (8-16bits) to 8 (or bit depth specified by 'i8'..'i16')\n    - \"intf\": scales full range videos, only integer formats (8-16bits) to 8 (or bit depth specified by 'i8'..'i16')\n    - \"float\" or \"floatf\" : only scales 32 bit float format to 8 bit range (or bit depth specified by 'i8'..'i16')\n    - \"all\": scales videos to 8 (or bit depth specified by 'i8'..'i16') - conversion uses limited_range logic (mul/div by two's power)\n    - \"allf\": scales videos to 8 (or bit depth specified by 'i8'..'i16') - conversion uses full scale logic (stretch)\n    - \"none\": no magic\n\n    Usually limited range is for normal YUV videos, full scale is for RGB or known-to-be-fullscale YUV\n\n    By default the internal conversion target is 8 bits, so old expressions written for 8 bit videos will probably work.\n    This internal working bit-depth can be overwritten by the i8, i10, i12, i14, i16 specifiers.\n\n    When using autoscale mode, scaleb and scalef keywords are meaningless, because there is nothing to scale.\n\n    How it works:\n\n    - This option scales all 8-32 bit inputs to a common bit depth value, which bit depth is 8 by default and can be\n      set to 10, 12, 14 and 16 bits by the 'i10'..'i16' keywords\n      For example: scale_inputs=\"all\" converts any inputs to 8 bit range. No truncation occurs however (no precision loss),\n      because even a 16 bit data is converted to 8 bit in floating point precision, using division by 256.0 (2^16/2^8).\n      So the conversion is _not_ a simple shift-right-8 in the integer domain, which would lose precision.\n    - Calculates expression (lut, lut_xy, lut_xyz, lut_xyza)\n    - Scales the result back to the original video bit depth.\n      Clamping (clipping to valid range) and converting to integer occurs here.\n\n    The predefined constants such as 'range_max', etc. will behave according to the internal working bit depth\n\n    Warning#1\n    This feature was created for easy porting earlier 8-bit-video-only lut expressions.\n    You have to understand how it works internally.\n\n    Let's see a 16bit input in \"all\" and \"allf\" mode (target is the default 8 bits)\n\n    Limited range 16->8 bits conversion has a factor of 1/256.0 (Instead of shift right 8 in integer domain, float-division is used or else it would lose presision)\n\n    Full range 16->8 bits conversion has a factor of 255.0/65535\n\n    Using bit shifts (really it's division and multiplication by 2^8=256.0):\n      \n      result = calculate_lut_value(input / 256.0) * 256.0\n\n    Full scale 16-8-16 bit mode ('intf', 'allf')\n      \n      result = calculate_lut_value(input / 65535.0 * 255.0 ) / 255.0 * 65535.0\n\n    Use scale_inputs = \"all\" (\"int\", \"float\") for YUV videos with 'limited' range e.g. in 8 bits: Y=16..235, UV=16..240).\n    Use scale_inputs = \"allf\" (intf, floatf) for RGB or YUV videos with 'full' range e.g. in 8 bits: channels 0..255.\n\n    When input is 32bit float, the 0..1.0 (luma) and -0.5..0.5 (chroma) channel is scaled\n    to 0..255 (8 bits), 0..1023 (i10 mode), 0..4095 (i12 mode), 0..16383(i14 mode), 0..65535(i16 mode) then back.\n\n    Warning#2\n    One cannot specify different conversion methods for converting before and after the expression.\n    Neither can you specify different methods for different input clips (e.g. x is full, y is limited is not supported).\n\n- Fix: Expr: expression string order for planar RGB is properly r-g-b like in original VapourSynth version, instead of counter-intuitive g-b-r.\n- Fix: Expr: check subsampling when a different output pixel format is given\n- Fix: ColorYUV: round to avoid green cast on consecutive TV<>PC\n- Enhanced: Limiter to work with 32 bit float clips\n- Enhanced: Limiter new parameter bool 'autoscale' default false.\n  If set, minimum/maximum luma/chroma values are treated as they were in 8 bit range (but non-integer values are allowed), limiter will autoscale it.\n  Default: does not scale at all, parameters are used as-is. Parameters now are of float type to handle 32 bit float values.\n- New: function bool VarExist(String variable_name)\n  Checks if a variable exists\n  Returns true if variable exists even if it holds 'Undefined', false otherwise\n- Fix: RGBAdjust memory leak when used in ScriptClip\n- Enhanced: RGBAdjust new parameter: conditional (like in ColorYUV)\n  The global variables \"rgbadjust_xxx\" with xxx = r, g, b, a, rb, gb, bb, ab, rg, gg, bg, ag are read each frame, and applied.\n  It is possible to modify these variables using FrameEvaluate or ConditionalReader.\n- Enhanced: RGBAdjust: support 32 bit float ('analyze' not supported, 'dither' silently ignored)\n- Enhanced: AviSource to support more formats with 10+ bit depth.\n  http://avisynth.nl/index.php/AviSource\n\n  When pixel_type is not specified or set to \"FULL\", AviSource will try to request the formats one-by-one in the order shown in the table below.\n\n  When a classic 'pixel_type' shares more internal formats (such as YUV422P10 first tries to request the v210 then P210 format)\n  you can specify one of the specific format directly. Note that high bit-depth RGBP is prioritized against packed RGB48/64.\n\n  The 'FourCCs for ICDecompressQuery' column means that when a codec supports the format, it will serve the frame in that one, Avisource then will convert it to the proper colorspace.\n\n  Full support list (* = already supported):\n\n::\n\n      'pixel_type' Avs+ Format   FourCC(s) for ICDecompressQuery\n      YV24         YV24          *YV24\n      YV16         YV16          *YV16\n      YV12         YV12          *YV12\n      YV411        YV411         *Y41B\n      YUY2         YUY2          *YUY2\n      RGBP10       RGBP10        G3[0][10]  r210  R10k\n      r210         RGBP10        r210\n      R10k         RGBP10        R10k\n      RGBP         RGBP10        G3[0][10]  r210  R10k\n                   RGBP12        G3[0][12]\n                   RGBP14        G3[0][14]\n                   RGBP16        G3[0][16]\n                   RGBAP10       G4[0][10]\n                   RGBAP12       G4[0][12]\n                   RGBAP14       G4[0][14]\n                   RGBAP16       G4[0][16]\n      RGB32        RGB32         *BI_RGB internal constant (0) with bitcount=32\n      RGB24        RGB24         *BI_RGB internal constant (0) with bitcount=24\n      RGB48        RGB48         BGR[48]    b48r\n      RGB64        RGB64         *BRA[64]   b64a\n      Y8           Y8            Y800       Y8[32][32]   GREY\n      Y            Y8            Y800       Y8[32][32]   GREY\n                   Y10           Y1[0][10]\n                   Y12           Y1[0][12]\n                   Y14           Y1[0][14]\n                   Y16           Y1[0][16]\n      YUV422P10    YUV422P10     v210       P210\n      v210         YUV422P10     v210\n      P210         YUV422P10     P210\n      YUV422P16    YUV422P16     P216\n      P216         YUV422P16     P216\n      YUV420P10    YUV420P10     P010\n      P010         YUV422P10     P010\n      YUV420P16    YUV420P16     P016\n      P016         YUV422P16     P016\n      YUV444P10    YUV444P10     v410\n      v410         YUV444P10     v410\n\n- Changed (finally): 32bit float YUV colorspaces: zero centered chroma channels.\n  U and V channels are now -0.5..+0.5 (if converted to full scale before) instead of 0..1\n  Note: filters that relied on having the U and V channel center as 0.5 will fail.\n  Why: the old UV 0..1 range was a very-very early decision in the high-bitdepth transition project. Also it is now\n  compatible with z_XXXXX resizers (zimg image library, external plugin at the moment).\n- New function: bool IsFloatUvZeroBased()\n  For plugin or script writers who want to be compatible with pre r2672 Avisynth+ float YUV format:\n  - Check function availablity with FunctionExists(\"IsFloatUvZeroBased\").\n  - When the function does not exists, the center value of 32 bit float U and V channel is 0.5\n  - When IsFloatUvZeroBased function exists, it will return true (always for official releases) if U and V is 0 based (+/-0.5)\n\n- Fix: RGB64 Turnleft/Turnright (which are also used in RGB64 Resizers)\n- Fix: Rare crash in FrameRegistry\n- Enhanced: Allow ConvertToRGB24-32-48-64 functions for any source bit depths\n- Enhanced: ConvertBits: allow fulls-fulld combinations when either clip is 32bits\n  E.g. after a 8->32 bit fulls=false fulld=true:\n  Y: 16..235 -> 0..1\n  U/V: 16..240 -> -0.5..+0.5\n  Note: now ConvertBits does not assume full range for YUV 32 bit float.\n  Default values of fulls and fulld are now true only for RGB colorspaces.\n- Fix: couldn't see variables in avsi before plugin autoloads (colors_rgb.avsi issue)\n- Fix: LoadVirtualdubPlugin: Fix crash on exit when more than one instances of a filter was used in a script\n- New: LoadVirtualdubPlugin update:\n  - Update from interface V6 to V20, and Filtermod version 6 (partial)\n  - VirtualDub2 support with extended colorspaces\n\n    Allow RGB24, RGB48, RGB64 besides RGB32\n    AutoConvert 8 bit Planar RGB to/from RGB24, RGBPA to/from RGB32 (lossless)\n    AutoConvert RGB48 and 16 bit Planar RGB(A) to/from RGB64 (lossless)\n    Support YUV(A) 8 bits: YV12, YV16, YV24, YV411, YUVA420P8, YUVA422P8, YUVA444P8\n    Support YUV(A) 10-16 bits (properly set \"ref_x\" maximum levels, no autoconvert)\n\n  - Supports prefetchProc2 callback (API >= V14 and prefetchProc2 is defined) for multiple input frames from one input clip\n    PrefetchFrameDirect and PrefetchFrame are supported. PrefetchFrameSymbolic not supported\n  - Supports prefetchProc callback (API >= V12 and prefetchProc is defined)\n  - Supports when filter changes frame count of the output clip\n  - Extra filter parameter added at the end of filter's (unnamed) parameter list\n    Imported Virtualdub filters are getting and extra named parameter to the end:\n\n      String [rangehint]\n\n    This parameter can tell the filter about a YUV-type clip colorspace info\n    Allowed values:\n\n::\n\n      \"rec601\": limited range + 601\n      \"rec709\": limited range + 709\n      \"PC.601\": full range + 601\n      \"PC.709\": full range + 709\n      \"\"      : not defined (same as not given)\n\n    Parameter will be ignored when clip is non-YUV\n    How it works: the hint will _not_ change the internal VirtualDub colorspace\n    constant (e.g. kPixFormat_YUV420_Planar -> kPixFormat_YUV420_Planar_709 will not happen).\n    Instead the base color space is kept and colorSpaceMode and colorRangeMode will set in PixmapLayout.formatEx.\n    Filter can either use this information or not, depending on supported API version and its implementation.\n    E.g. Crossfade(20,30) -> Crossfade(20,30,\"rec601\") though this specific filter won't use it.\n\n- New function: BuildPixelType\n\n  Creates a video format (pixel_type) string by giving a colorspace family, bit depth, optional chroma subsampling and/or a\n  template clip, from which the undefined format elements are inherited.\n  \"[family]s[bits]i[chroma]i[compat]b[oldnames]b[sample_clip]c\"\n\n  string family: YUV, YUVA, RGB, RGBA, Y\n  int bits: 8, 10, 12, 14, 16, 32\n  string chroma: for YUV(A) 420,422,444,411. Ignored for RGB(A) and Y\n  bool compat (default false): returns packed rgb formats for 8/16 bits (RGB default: planar RGB)\n  bool oldnames (default false): returns YV12/YV16/YV24 instead of YUV420P8/YUV422P8/YUV444P8\n  clip sample_clip: when supported, its format is overridden by specified parameters (e.g. only change bits=10)\n\n  Example#1: define YUV 444 P 10\n\n::\n\n      family = \"YUV\"\n      bits = 10\n      chroma = 444\n      compat = false\n      oldformat = false\n      s = BuildPixelType(family, bits, chroma, compat, oldformat)\n      BlankClip(width=320,height=200,length=len,pixel_type=s,color=$008080).Info()\n\n  Example#2: Change only the bit depth of the format to 16\n\n::\n\n      newbits = 16\n      c = last\n      s = BuildPixelType(bits=newbits, sample_clip=c)\n      BlankClip(width=320,height=200,length=len,pixel_type=s,color=$008080).Info()\n\n- Source: move to c++17, 'if constexpr' requires. Use Visual Studio 2017 (or GCC 7?). CMakeLists.txt changed.\n- Source: C api: AVSC_EXPORT to dllexport in capi.h for avisynth_c_plugin_init\n- Source: C api: avs_is_same_colorspace VideoInfo parameters to const\n- Project struct: changelog to git.\n- Include current avisynth header files and def/exp file in installer, when SDK is chosen\n\n20180328 r2664\n--------------\n- Fix: YUY2 Sharpen overflow artifacts - e.g. Sharpen(0.6)\n- Fix: Levels: 32 bit float shift in luma\n- Fix: Merge sse2 for 10-14bits (regression)\n- Fix: AVX2 resizer possible access violation in extreme resizes (e.g. 600->20)\n- Fix: 32bit float PlanarRGB<->YUV conversion matrix\n- Fix: VfW: fix b64a output for OPT_Enable_b64a=true\n- Enhanced: VfW output P010 and P016 conversion to SSE2 (VfW output is used by VirtualDub for example)\n- Enhanced: ColorYUV: recalculate 8-16 bit LUT in GetFrame only when changed frame-by-frame (e.g. in autowhite)\n- Enhanced: ConvertBits 32->8 sse2/avx2 and 32->10..16 sse41/avx2 (8-15x speed)\n\nNot included, preliminary for the near future:\n\n- Big change: 32 bit float YUV formats, U and V are now zero based.\n  Internally YUV 32 bit float chroma center became 0.0 (the neutral value which is 128 in the 8-bit world)\n  Like in VapourSynth or in avsresizer using z.lib image library.\n  'Expr' changes are affecting built-in constants/operators when used in chroma plane of a 32bit clip.\n\n  - 'cmin', 'cmax' return the zero-based shifted versions of the 16 and 240 (8 bit) values\n  - For U and V planes, constant 'range_half' results in 0.0 instead of the old 0.5\n  - 'scaleb' will also give zero-based result when found in an expression for chroma plane\n    (e.g. for a 32 bit float clip the '128 scaleb' will result in 0.0 instead of 128/255 for U and V planes)\n    But 'scalef' when the target or source of the constant conversion is 32bits, remains independent from the plane type.\n  - 'range_max' is 0.5 for 32 bit float chroma\n  - new constant 'range_min', which is -0.5 for 32 bit float chroma, (0 otherwise)\n\n    Additional warning: when you move 32bit float U or V plane to Y using CombinePlane, you have to be sure\n    that your filters do not rely on this new Y plane being in 0..1 range. Or else convert it by using Expr(\"x 0.5 +\") to the 0..1 range\n    Similarly: ExtractU and ExtractV will simply return the unaltered chroma planes, which are now zero-centered\n\n\n20180302 r2636\n--------------\n- Fix: Blur/Sharpen crashed when YUY2.width<8, RGB32.width<4, RGB64.width<2\n- ColorYUV: don't apply TV range gamma for opt=\"coring\" when explicit \"PC->TV\" is given\n- ColorbarsHD: 32bit float properly zero (0.5)-centered chroma\n\n20180301 r2632\n--------------\n- Fix: IsInterleaved returned false for RGB48 and RGB64 (raffriff42)\n- Fix: SubTitle for Planar RGB/RGBA: wrong text colors (raffriff42)\n- Fix: Packed->Planar RGB conversion failed on SSE2-only computers (SSSE3 instruction used)\n- Enhanced: Blur, Sharpen\n  AVX2 for 8-16 bit planar colorspaces (>1.35x speed on i7-7770)\n  SSE2 for 32 bit float formats (>1.5x speed on i7-7770)\n- Fix: Resizers for 32 bit float rare random garbage on right pixels (simd code NaN issue)\n- Enhanced: Completely rewritten 16bit and float resizers, much faster (and not only with AVX2)\n- Enhanced: 8 bit resizers: AVX2 support\n- Enhanced: Speed up converting from RGB24/RGB48 to Planar RGB(A) - SSSE3, approx. doubled fps\n- New: ConvertFPS supports 10-32 bits, planar RGB(A), YUV(A)\n- New script function: int BitSetCount(int[, int, int, ...])\n  Function accepts one or more integer parameters\n  Returns the number of bits set to 1 in the number or the total number of '1' bits in the supplied integers.\n- Cherry-picking from StainlessS' great RT_xxxx collection/and raffriff42 utils\n- Modded script function: Hex(int , int \"width\"=0)\n  - New \"width\" parameter\n  - result is in uppercase\n  Width is 0 to 8, the _minimum_ width of the returned string. (8 hex digit is the max of Avisynth32 bit integer)\n  When width is 0 or not supplied then string length is a minimum needed.\n  Function now returns hex string in uppercase, instead of lowercase.\n  Example: Hex(255,4) returns \"00FF\".\n- Modded script function: HexValue(String, \"pos\"=1)\n  - new pos parameter\n  Returns an int conversion of the supplied hexadecimal string.\n  Conversion will cease at the first non legal number base digit, without producing an error\n  Added optional pos arg default=1, start position in string of the HexString, 1 denotes the string beginning.\n  Will return 0 if error in 'pos' ie if pos is less than 1 or greater than string length.\n- Modded script function: ReplaceStr(String, String, String[, Boolean \"sig\"=false])\n  New parameter: sig for case insensitive search (Default false: exact search)\n  The uppercase/lowercase rules come from the current active code page of the OS.\n- New script functions: TrimLeft, TrimRight, TrimAll for removing beginning/trailing whitespaces from a string.\n  Whitespaces: Tab (9), space (32), nbsp (160)\n- New in ColorYUV:\n  New parameter: bool f2c=\"false\".\n  When f2c=true, the function accepts the Tweak-like parameters for gain, gamma and contrast\n  E.g. use 0/0.5/1.0/1.5/2.0/3.0 instead of -256/-128/0/128/256/512\n- New/Fixed in ColorYUV:\n  Parameter \"levels\" accepts \"TV\". (can be \"TV->PC\", \"PC->TV\", \"PC->TV.Y\")\n  Now gamma calculation is TV-range aware when either\n  - levels is \"TV->PC\" or\n  - coring = true or\n  - levels is \"TV\" (new - no level conversion but gamma will know proper handling)\n  Previously gamma was properly calculated only for PC range.\n- New in ColorYUV:\n  32 bit float support.\n  - 32 bit float uses the Expr filter (8-16 bits is LUT-based). The expression is dynamically assembled for each plane, internal precision is float.\n  - One can specify bits=32 when showyuv=true -> test clip in YUV420PS format\n\n  For 32 bit clips \"loose min\" and \"loose_max\" (omitting the extreme 1/256 population from dark and bright pixels) statistics are computed\n  by splitting the 0..1 into 65536 uniform ranges.\n\n- Modded: remove \"scale\" parameter from ConvertBits.\n  It was introduced at the very beginning of the 10+bit development, for 32bit float conversion - never used\n- Enhanced: VfW: exporting Y416 (YUV444P16) to SSE2.\n- 8-16 bit YUV chroma to 32 bit float: keep middle chroma level (e.g. 128 in 8 bits) at 0.5.\n  Calculate chroma as (x-128)/255.0 + 0.5 and not x/255.0 (Note: 32 bit float chroma center will be 0.0 in the future)\n- New: Histogram parameter \"keepsource\"=true (raffriff42)\n  keepsource = false returns only the Histogram w/o the original picture.\n  Affects \"classic\", \"levels\" and \"color\", \"color2\", ignored (n/a) for the other modes\n- New: Histogram type \"color\" to accept 8-32bit input and \"bits\"=8,9,..12 display range\n- New: Histogram parameter \"markers\"=true\n  When markers = false:\n  For \"classic\": no \"half\" level line and no invalid luma zone coloring\n  For \"levels\":  no \"half\" dotted line, no coloring (neither for YUV nor for RGB)\n  Ignored for the others at the moment.\n\n20171226 r2580\n--------------\n- Fix (workaround): Merge: Visual Studio 2017 15.5.1/2 generated invalid AVX2 code\n  The x86 path of Merge Average was crashing due to bad code generation in the 8 bit version. Seems that thought\n  Visual Studio Team was proudly announcing optimizations in their compiler (15.5.x line), it had victims.\n- Fix: Temporalsoften 10-14 bits: an SSE 4.1 instruction was used for SSE2-only CPU-s (Illegal Instruction on Athlon XP)\n\n20171219 r2574\n--------------\n- Fix: MaskHS created inverse mask. Regression after r2173\n- Build: changed avisynth.h, strict C++ conformity with Visual Studio 2017 /permissive- flag\n- Installer (finally)\n- Expr:\n\n  - new: Indexable source clip pixels by relative x,y positions like x[-1,1]\n  - new functions: sin cos tan asin acos atan\n  - new operator: % (modulo)\n  - new: Variables: uppercase letters A..Z for storing and reuse temporary results, frequently used computations.\n  - new: predefined expr variables 'frameno', 'time', 'width', 'height'\n  - fix: jitasm code generation at specific circumstances\n\n20171115 r2544\n--------------\n- Expr: fix \"scalef\" for 10-16 bits\n- Expr optimization: eliminate ^1 +0 -0 \\*1 /1\n\n20171114 r2542\n--------------\n- New filter: Expr\n  Ported from Vapoursynth, with a lot of additional tweaks\n  e.g. AVX2, recognize constant fill, spatial absolute and relative coordinates as input, recognize plane copy,\n  no GetFrame for unused clips, converts ^2, ^3, ^4 into faster multiplication,\n  converts x^0.5 into sqrt(x), borrow specific syntax elements from masktools2 (scaling, operators - but not all of them) to have partial\n  compatibility in widely used existing expression strings (see readme.txt)\n\n::\n\n      clip Expr(clip c[,clip c2, ...], string expr [, string expr2[, string expr3[, string expr4]]] [, string format]\n          [, bool optSSE2][, bool optAVX2][, bool optSingleMode])\n\nClip and Expr parameters are unnamed\n\n  - 'format' overrides the output video format\n  - 'optSSE2' to disable simd optimizations (use C code)\n  - 'optAVX2' to disable AVX2 optimizations (use SSE2 code)\n  - 'optSingleMode' default false, to generate simd instructions for one XMM/YMM wide data instead of two. Experimental.\n\nOne simd cycle processes 8 pixels (SSE2) or 16 pixels (AVX2) at a time by using two XMM/YMM registers as working set.\nVery-very complex expressions would use too many XMM/YMM registers which are then \"swapped\" to memory slots, that can be slow.\nUsing optSingleMode = true may result in using less registers with no need for swapping them to memory slots.\n\nExpr accepts 1 to 26 clips as inputs and up to four expression strings, an optional video format overrider, and some debug parameters.\nOutput video format is inherited from the first clip, when no format override.\nAll clips have to match their dimensions and plane subsamplings.\n\nExpressions are evaluated on each plane, Y, U, V (and A) or R, G, B (,A).\nWhen an expression string is not specified, the previous expression is used for that plane. Except for plane A (alpha) which is copied by default.\nWhen an expression is an empty string (\"\") then the relevant plane will be copied (if the output clip bit depth is similar).\nWhen an expression is a single clip reference letter (\"x\") and the source/target bit depth is similar, then the relevant plane will be copied.\nWhen an expression is constant, then the relevant plane will be filled with an optimized memory fill method.\nExpressions are written in Reverse Polish Notation (RPN).\n\nExpressions use 32 bit float precision internally\n\nFor 8..16 bit formats output is rounded and clamped from the internal 32 bit float representation to valid 8, 10, ... 16 bits range.\n32 bit float output is not clamped at all.\n\n- Clips: letters x, y, z, a, ... w. x is the first clip parameter, y is the second one, etc.\n- Math: * / + -\n- Math constant: pi\n- Functions: min, max, sqrt, abs, neg, exp, log, pow ^ (synonyms: \"pow\" and \"^\")\n- Logical: > < = >= <= and or xor not == & | != (synonyms: \"==\" and \"=\", \"&\" and \"and\", \"|\" and \"or\")\n- Ternary operator: ?\n- Duplicate stack: dup, dupN (dup1, dup2, ...)\n- Swap stack elements: swap, swapN (swap1, swap2, ...)\n- Scale by bit shift: scaleb (operand is treated as being a number in 8 bit range unless i8..i16 or f32 is specified)\n\n- Scale by full scale stretch: scalef (operand is treated as being a number in 8 bit range unless i8..i16 or f32 is specified)\n\n- Bit-depth aware constants\n  ymin, ymax (ymin_a .. ymin_z for individual clips) - the usual luma limits (16..235 or scaled equivalents)\n\n  cmin, cmax (cmin_a .. cmin_z) - chroma limits (16..240 or scaled equivalents)\n\n  range_half (range_half_a .. range_half_z) - half of the range, (128 or scaled equivalents)\n\n  range_size, range_half, range_max (range_size_a .. range_size_z , etc..)\n\n- Keywords for modifying base bit depth for scaleb and scalef: i8, i10, i12, i14, i16, f32\n\n- Spatial input variables in expr syntax:\n  \n  - sx, sy (absolute x and y coordinates, 0 to width-1 and 0 to height-1)\n  - sxr, syr (relative x and y coordinates, from 0 to 1.0)\n\nAdditions and differences to VS r39 version:\n--------------------------------------------\n(similar features to the masktools mt_lut family syntax)\n\n-  Aliases:\n\n  introduced \"^\", \"==\", \"&\", \"|\"\n\n- New operator: != (not equal)\n\n- Built-in constants\n\n    ymin, ymax (ymin_a .. ymin_z for individual clips) - the usual luma limits (16..235 or scaled equivalents)\n\n    cmin, cmax (cmin_a .. cmin_z) - chroma limits (16..240 or scaled equivalents)\n\n    range_half (range_half_a .. range_half_z) - half of the range, (128 or scaled equivalents)\n\n    range_size, range_half, range_max (range_size_a .. range_size_z , etc..)\n\n- Autoscale helper functions (operand is treated as being a number in 8 bit range unless i8..i16 or f32 is specified)\n\n    scaleb (scale by bit shift - mul or div by 2, 4, 6, 8...)\n\n    scalef (scale by stretch full scale - mul or div by source_max/target_max\n\n- Keywords for modifying base bit depth for scaleb and scalef\n\n    i8, i10, i12, i14, i16, f32\n\n- Built-in math constant\n\n    pi\n\n- Alpha plane handling\n  When no separate expression is supplied for alpha, plane is copied instead of reusing last expression parameter.\n\n- Proper clamping when storing 10, 12 or 14 bit outputs\n\n- (Faster storing of results for 8 and 10-16 bit outputs, fixed in VS r40)\n- 16 pixels/cycle instead of 8 when avx2, with fallback to 8-pixel case on the right edge. Thus no need for 64 byte alignment for 32 bit float.\n  (Load zeros for nonvisible pixels, when simd block size goes beyond image width, to prevent garbage input for simd calculation)\n\n- Optimizations: x^0.5 is sqrt, ^1 +0 -0 \\*1 /1 to nothing, ^2, ^3, ^4 is done by faster and more precise multiplication\n- Spatial input variables in expr syntax:\n\n  - sx, sy (absolute x and y coordinates, 0 to width-1 and 0 to height-1)\n  - sxr, syr (relative x and y coordinates, from 0 to 1.0)\n\n- Optimize: recognize constant plane expression: use fast memset instead of generic simd process. Approx. 3-4x (32 bits) to 10-12x (8 bits) speedup\n- Optimize: Recognize single clip letter in expression: use fast plane copy (BitBlt)\n  (e.g. for 8-16 bits: instead of load-convert_to_float-clamp-convert_to_int-store). Approx. 1.4x (32 bits), 3x (16 bits), 8-9x (8 bits) speedup\n\n- Optimize: do not call GetFrame for input clips that are not referenced or plane-copied\n\n- Recognize constant expression: use fast memset instead of generic simd process. Approx. 3-4x (32 bits) to 10-12x (8 bits) speedup\n  Example: Expr(clip,\"128\",\"128,\"128\")\n\nDifferences from masktools 2.2.10\n---------------------------------\n- Up to 26 clips are allowed (x,y,z,a,b,...w). Masktools handles only up to 4 clips with its mt_lut, my_lutxy, mt_lutxyz, mt_lutxyza\n- Clips with different bit depths are allowed\n- Works with 32 bit floats instead of 64 bit double internally\n- Less functions (e.g. no bit shifts)\n- No float clamping and float-to-8bit-and-back load/store autoscale magic\n- Logical 'false' is 0 instead of -1\n- The ymin, ymax, etc built-in constants can have a _X suffix, where X is the corresponding clip designator letter. E.g. cmax_z, range_half_x\n- mt_lutspa-like functionality is available through \"sx\", \"sy\", \"sxr\", \"syr\"\n- No y= u= v= parameters with negative values for filling plane with constant value, constant expressions are changed into optimized \"fill\" mode\n\nExample:\n\n::\n\n      Average three clips:\n      c = Expr(clip1, clip2, clip3, \"x y + z + 3 /\")\n      using spatial feature:\n      c = Expr(clip1, clip2, clip3, \"sxr syr 1 sxr - 1 syr - * * * 4096 scaleb *\", \"\", \"\")\n\n\n- Add: Levels: 32 bit float format support\n- Fix: RGB (full scale) conversion: 10-16 bits to 8 bits rounding issue; pic got darker in repeated 16<->8 bit conversion chain\n- Fix: ConvertToY: remove unnecessary clamp for Planar RGB 32 bit float\n- Fix: RGB ConvertToY when rec601, rec709 (limited range) matrix. Regression since r2266\n- Optimized: Faster RGB (full scale) 10-16 bits to 8 bits conversion when dithering\n- Other: Default frame alignment is 64 bytes (was: 32 bytes). (independently of AVX512 support)\n- Build:\n  Built with Visual Studio 2017, v141_xp toolset\n  Note that DLL will work When you have VS2015 Update 3 redistributable.\n\n  Download Visual Studio 2017 Redistributable from here (replaces and compatible with VS2015 redist)\n\n  - x64: https://go.microsoft.com/fwlink/?LinkId=746572\n  - x86: https://go.microsoft.com/fwlink/?LinkId=746571\n\n- Experimental x64 builds for test (internal offsets from int to size_t)\n  (later note: idea was dropped because of incompatibility; too many x64 plugins out there)\n- Source: avisynth_c.h (C interface header file) changed:\n  Optional define SIZETMOD. Experimental. Offsets are size_t instead of int (x64 is different!)\n\n  - Fix: avs_get_row_size calls into avs_get_row_size_p, instead of direct field access\n  - Fix: avs_get_height calls into avs_get_row_size_p, instead of direct field access.\n\n20170629 r2508\n--------------\n- Fix TemporalSoften: threshold < 255 (probably since r1576)\n\n20170608 r2506\n--------------\n- Fix CombinePlanes: feeding YV16 or YV411 target with Y8 sources\n\n20170603 r2504\n--------------\n- fix XP support broken in r2502\n\n20170602 r2502\n--------------\n- fix: (Important!) MT_SERIALIZED mode did not always protect filters (regression since r2069)\n  Such filters sometimes were called in a reentrant way (like being MT_NICE_FILTER), which\n  possibly resulted in using their internal buffers parallel.\n- Fix: ImageWriter crash when no '.' in provided filename\n- Fix: Overlay: correct masked blend: keep exact clip1 or clip2 pixel values for mask extremes 255 or 0.\n  Previously 0 became 1 for zero mask, similarly 255 changed into 254 for full transparency (255) mask\n- New: script functions: StrToUtf8, StrFromUtf8: Converting a 8 bit (Ansi) string to UTF8 and back.\n- New: PluginManager always throws error on finding wrong bitness DLL in the autoload directories\n- Modified: increased x64 default MemoryMax from 1GB to 4GB, but physicalRAM/4 is still limiting\n- Modified: allow conversions between RGB24/32/48/64 (8<->16 bits) w/o ConvertBits\n- Added VS2017 and v141_xp to CMakeList.txt\n\n20170529 r2489\n--------------\n- fix: memory leak in CAVIStreamSynth (e.g. feeding vdub)\n- fix: ConvertToY for RGB64 and RGB48\n\n20170528 r2487\n--------------\n- Blur, Sharpen 10-16 bits planar and RGB64: SSE2/SSE4 (2x-4x speed)\n- New script function: int GetProcessInfo([int type = 0])\n  Without parameter or type==0 the current bitness of Avisynth DLL is returned (32 or 64)\n  With type=1 the function can return a bit more detailed info:\n  -1: error, can't establish\n  0: 32 bit DLL on 32 bit OS\n  1: 32 bit DLL on 64 bit OS (WoW64 process)\n  2: 64 bit DLL\n- Fix: Blur width=16 (YV12 width=32)\n- Fix: Overlay Lighten: artifacts when base clip and overlay clip have different widths (regression since r2290)\n- Fix: YUY2 HorizontalReduceBy2 did nothing if target width was not mod4\n- ImageReader: 16 bit support; \"pixel_type\" parameter new formats \"RGB48\", \"RGB64\" and \"Y16\"\n- ImageWriter: 16 bit support; save RGB48, RGB64, Y16, planar RGB(A) 8 and 16 bit formats\n  (note: greyscale through devIL can be corrupt with some formats, use png)\n- ImageWriter: flip greyscale images vertically (except \"raw\" format)\n- SubTitle: new parameter \"font_filename\" allows using non-installed fonts\n- (project can be compiled using gcc)\n- Allows opening unicode filenames through VfW interface (virtualdub, MPC-HC)\n- Script function Import: new parameter bool \"utf8\" to treat the filenames as UTF8 encoded\n  (not the script text!)\n- SubTitle: new parameter bool \"utf8\" for drawing strings encoded in UTF8.\n\n::\n\n      Title=\"Cherry blossom \"+CHR($E6)+CHR($A1)+CHR($9C)+CHR($E3)+CHR($81)+CHR($AE)+CHR($E8)+CHR($8A)+CHR($B1)\n      SubTitle(Title,utf8=true)\n\n- New script functions: ScriptNameUtf8(), ScriptFileUtf8(), ScriptDirUtf8(),\n  they return variables $ScriptNameUtf8$, $ScriptFileUtf8$ and $ScriptDirUtf8$ respectively\n\nKnown issues:\n- Filters with MT_SERIALIZED sometimes can get called in a reentrant way\n- Runtime Script functions under MT\n\n\n20170316 r2455\n--------------\n- Fix: IsY() script function returned IsY8() (VideoInfo::IsY was not affected)\n- New: ConvertBits, dither=1 (Floyd-Steinberg): allow any dither_bits value between 0 and 8 (0=b/w)\n\n20170310 r2440\n--------------\n- Fix Merge for float formats\n- Fix error text formatting under wine (_vsnprintf_l issue)\n- Fix Regression: YUY2 UToY copied V instead of U, since August, 2016 (v2150)\n\n- faster Merge: float to sse2 (both weighted and average)\n- faster ordered dither to 8bit: SSE2 (10x speed)\n\n- ColorBars allows any 4:2:0, 4:4:4 formats, RGB64 and all planar RGB formats\n- ColorBarsHD accepts any 4:4:4 formats\n- Dithering: Floyd-Steinberg\n\n  Use convertBits parameter dither=1: Floyd-Steinberg (was: dither=0 for ordered dither)\n\n- Dithering: parameter \"dither_bits\"\n  \n  For dithering to lower bit depths than the target clip format\n  \n  Usage: ConvertBits(x, dither=n [, dither_bits=y])\n  \n  - ordered dither: dither_bits 2, 4, 6, ... but maximum difference between target bitdepth and dither_bits is 8\n  - Floyd-Steinberg: dither_bits 1, 2, 4, 6, ... up to target bitdepth - 2\n\n  (Avisynth+ low bitdepth, Windows 3.1 16 bit feeling I was astonished that dither_bits=6 still resulted in a quite usable image)\n\n- Dithering is allowed from 10-16 -> 10-16 bits (was: only 8 bit targets)\n- Dithering is allowed while keeping original bit-depth. clip10 = clip10.ConvertBits(10, dither=0, dither_bits=8)\n  (you still cannot dither from 8 or 32 bit source)\n- ConditionalFilter syntax extension like Gavino's GConditional: no \"=\" \"true\" needed\n- Revert: don't give error for interlaced=true for non 4:2:0 sources (compatibility, YATTA)\n- CombinePlanes: silently autoconvert packed RGB/YUY2 inputs to planar\n- ConvertBits: show error message on YV411 conversion attempt: 8 bit only\n- ConvertBits: Don't give error message if dither=-1 (no dithering) is given for currently non-ditherable target formats\n- Script function: IsVideoFloat. returns True if clip format is 32 bit float. For convenience, same as BitsPerComponent()==32\n- ConvertToDoubleWidth and ConvertFromDoubleWidth: RGB24<->RGB48, RGB32<->RGB64\n- New MT mode: MT_SPECIAL_MT. Specify it for MP_Pipeline like filters, even if no Prefetch is used (MP_Pipeline issue, 2 fps instead of 20)\n\n\n20170202 r2420\n--------------\n- CombinePlanes:\n  When there is only one input clip, zero-cost BitBlt-less subframes are used, which is much faster.\n\n  e.g.: casting YUV to RGB, shuffle RGBA to ABGR, U to Y, etc..\n  Target planes that are not specified, preserve their content.\n\n  Examples:\n\n    combineplanes(clipRGBP, planes=\"RGB\",source_planes=\"BGR\") # swap R and B\n    combineplanes(clipYUV, planes=\"GBRA\",source_planes=\"YUVA\",pixel_type=\"RGBAP8\") # cast YUVA to planar RGBA\n    combineplanes(clipYUV, planes=\"Y\",source_planes=\"U\",pixel_type=\"Y8\") # extract U\n\n- fix: SubframePlanarA (available in IScriptEnvironment2)\n- faster: Difference-type conditional functions: Simd for 10-16 bits\n- Fix: MinMax-type conditional functions (min, max, median): return float value for float clips\n- ConvertToPlanarRGB(A):\n  PlanarRGB <-> PlanarRGBA is now allowed\n- ConvertToPlanarRGB(A):\n  YUY2 source is now allowed (through automatic ConvertToRGB proxy)\n- faster: RemoveAlphaPlane (subframe instead of BitBlt copy)\n- Overlay: \"Blend\" native greyscale mode: process y plane only w/o conversion\n- Overlay: automatic use444=false for \"blend\"/\"luma\"/\"chroma\"\n  for inputs: 420/422/444 and any RGB, lossless Planar RGB intermediate for PackedRGB\n  Overlay/mask auto-follows input clip format.\n  For compatibility: when greymask=true (default) and mask is RGB then mask source is the B channel\n- faster: RGB48->RGB64 SSSE3 (1,6x), RGB64->RGB48 SSSE3 (1.5x speed)\n- faster: RGB24,RGB48->PlanarRGB: uses RGB32/64 intermediate clip\n- Histogram \"levels\": allow RGB24/32/48/64 input.\n  Display R, G and B channels instead of Y, U and V\n\n  - Reminder 1: \"levels\" for Planar RGB was working already\n  - Reminder 2: Histogram \"levels\" and \"Classic\" allows bits=xx parameter, xx=8..12\n\n  If \"bits\" is specified then Histogram is drawn with 9..12 bits precision. Get a wide monitor though :)\n\n- ConvertBits: new parameters, partially for the future.\n  bool fulls, bool fulld\n\n  For YUV and greyscale clips the bit-depth conversion uses simple bit-shifts by default.\n  YUV default is fulls=false\n\n  RGB is converted as full-stretch (e.g. 0..255->0..65535)\n  RGB default is fulls=true\n\n  If fulld is not specified, it takes the value of fulls.\n  Use case: override greyscale conversion to fullscale instead of bit-shifts\n\n  - Note 1: conversion from and to float is always full-scale\n  - Note 2: alpha plane is always treated as full scale\n  - Note 3: At the moment you cannot specify fulld to be different from fulls.\n\n\n20170119 r2397\n--------------\n- TemporalSoften: Planar RGB support\n- TemporalSoften: much faster average mode (thres=255)\n\n  radius=1 +70%, radius=2 +45%,\n  \n  16bit: generally 7-8x speed (SSE2/4 instead of C)\n  \n- SeparateColumns: 10-16bit,float,RGB48/64\n- WeaveColumns: 10-16bit,float,RGB48/64,PlanarRGB(A)\n- AddAlphaPlane: fix function parameter type list, clip type did not work\n- Internals: add SubframePlanarA to IScriptEnvirontment2 for frames with alpha plane\n\n  General note: unlike IScriptEnvironment (that is rock solid for the time beeing), IScriptEnvironment2 is still not final.\n  It is used within Avisynth+ core, but is also published in avisynth.h.\n  It contains avs+ specific functions, that could not be stuffed into IScriptEnvironment without killing compatibility.\n\n  Although it changes rarely, your plugin may not work with Avisynth+ versions after a change\n\n- SwapUV: YUVA support\n- ConvertToRGB32/64: copy alpha from YUVA\n- SeparateRows,SeparateFields: PlanarRGB(A),YUVA support\n- WeaveRows: PlanarRGB(A), YUVA\n- Weave (fields,frames): YUVA,PlanarRGB(A)\n- Crop: Fast crop possible for frames with alpha plane (subframe)\n- AddBorders missing l/r/top/bottom vs. subsampling check for YUVA\n- Fix: YUVA->PlanarRGBA and YUVA42x->444 missing alpha plane copy\n- YUV444->RGB48/64: fast intermediate PlanarRGB(A) then RGB48/64 (not C path)\n- RGB48/64->YUV4xx target: Planar RGB intermediate (instead of C, 10x faster)\n\n20170111 r2380\n--------------\n- Overlay: \n  \n  - Merge the source of Chroma and Luma modes into Blend mode\n  - Modes Blend,Luma and Chroma now support all bit depths and 444 conversionless (use444=false) mode\n- Overlay: fix SSE2 Blend for mask+opacity for 10-16 bits\n- VfW: (vdubmod14 VfW test)\n  - Fix: YUV444P16 or YUVA444P16 to fourcc Y416\n  if alpha channel is present, it will we copied, else filled with FFFF\n  - Fix: VDubPlanarHack is checked only for 8 bit YUV planar sources\n\n20170110 r2372  (vdubmod14 VfW test)\n------------------------------------\n- New: SSE2/SSE4 for 10-16 bit <-> 10-16 bit Planar RGB (and Alpha plane) full scale conversions\n  (needed for automatic planar RGB -> packed RGB VfW conversions)\n- VfW:\n\n  - Fixed: Y3[10][10],Y3[10][16] fourcc's byte order\n  - New: Planar RGB(A) (MagicYUV)\n  \n    10,12,14,16 bits: G3[0][10], G4[0][10], G3[0][12], G4[0][12], G3[0][14], G4[0][14], G3[0][16], G4[0][16]\n  \n  - New: YUV444P16 to fourcc Y416\n  - New: Automatic conversion of 12, 14 and float YUV formats to 16 bit for 4:2:0 and 4:2:2\n    Note: OPT_Enable_Y3_10_16 is still valid as if format was originally 16 bits\n  - New: Automatic conversion of 10, 12, 14 and float YUV formats to 16 bit for 4:4:4\n  - New: Conversion of 10, 12, 14 and float planar RGB formats to RGB64\n    when global Avisynth variable Enable_PlanarToPackedRGB is true\n  - New: Conversion of 8 bit planar RGB formats to RGB24\n    when global Avisynth variable Enable_PlanarToPackedRGB is true\n  - New: Conversion of 8 bit planar RGBA formats to RGB32\n    when global Avisynth variable Enable_PlanarToPackedRGB is true\n\n  Note: use OPT_VDubPlanarHack=true for YV16 and YV24 for old VirtualDub\n\n  Supported formats:\n\n::\n\n      BRA[64],b64a,BGR[48],P010,P016,P210,P216,Y3[10][10],Y3[10][16],v210,Y416\n      G3[0][10], G4[0][10], G3[0][12], G4[0][12], G3[0][14], G4[0][14], G3[0][16], G4[0][16]\n\nDefault format FourCCs:\nAvisynth+ will report these FourCC-s, override them with defining OPT_xxx global variables\n\n::\n\n      RGB64: BRA[64]\n      RGB48: BGR[48]\n      YUV420P10: P010\n      YUV420P16: P016\n      YUV422P10: P210\n      YUV422P16: P216\n      YUV444P16 and YUVA444P16: Y416\n      Planar RGB  10,12,14,16 bits: G3[0][10], G3[0][12], G3[0][14], G3[0][16]\n      Planar RGBA 10,12,14,16 bits: G4[0][10], G4[0][12], G4[0][14], G4[0][16]\n\nGlobal variables to override default formats:\n\nPut them at the beginning of avs script.\n\n::\n\n      OPT_Enable_V210 = true --> v210 for YUV422P10\n      OPT_Enable_Y3_10_10 = true --> Y3[10][10] for YUV422P10\n      OPT_Enable_Y3_10_16 = true --> Y3[10][16] for YUV422P16\n      OPT_Enable_b64a = true --> b64a for RGB64\n      Enable_PlanarToPackedRGB = true --> RGBP8->RGB24, RGBAP8->RGB32, all other bit depths to RGB64\n\n20170109 r2367dev\n-----------------\n- VfW: BRA[64],b64a,BGR[48],P010,P016,P210,P216,Y3[10][10],Y3[10][16],v210 experimental!\n\n  Default format FourCCs:\n\n::\n\n      RGB64: BRA[64]\n      RGB48: BGR[48]\n      YUV420P10: P010\n      YUV420P16: P016\n      YUV422P10: P210\n      YUV422P16: P216\n      Global variables to override default formats:\n      OPT_Enable_V210 = true --> v210 for YUV422P10\n      OPT_Enable_Y3_10_10 = true --> Y3[10][10] for YUV422P10\n      OPT_Enable_Y3_10_16 = true --> Y3[10][16] for YUV422P16\n      OPT_Enable_b64a = true --> b64a for RGB64\n\n- Overlay: blend for float format\n- Overlay: blend: SSE4 for 10-16 bit, SSE2 for float\n- AddAlphaPlane: also accepts clip with Y-only or alpha (YUVA/PRGBA/RGB32/64) for alpha source\n  (was: optional int/float mask value)\n\n20170104 r2359dev\n-----------------\n- Overlay: new parameter: bool use444 (default true for compatibility)\n\n  Parameter is valid only for \"blend\" at the moment\n\n  When set to false, and base clip/overlay clip is 420/422/Planar RGB, the overlay core\n  does not convert to and back from YV24 (4:4:4 in general)\n\n  mask can be either greyscale or can be any planar YUV when greymask=true (default)\n\n  Works for Planar RGB, so blending is basically lossless for this format (no YUV conversion)\n\n  todo: support for other modes, convert packed RGB to planar RGB internally instead of YUV\n- Overlay:\n  Add fast 4:2:0<->4:4:4 conversion, e.g. YV16<->YV24 (only fast YUY2 and YV12 existed so far)\n  instead of invoking generic core conversion\n- Overlay:\n  10-16bit SSE2/SSE4 for 420/422<->444 conversions\n- Info() made a bit more compact.\n  Bit depth info moved after color space info\n  Does not display pre-SSE2 CPU flags when at least AVX is available\n  Display AVX512 flags in separate line (would be too long)\n\n  Reminder: Info() now has more parameters than is classic Avisynth: \"c[font]s[size]f[text_color]i[halo_color]i\"\n\n  Added font (default Courier New), size (default 18), text_color and halo_color parameters, similar to (but less than) e.g. in ShowFrameNumber.\n\n- new CPU feature constants (see cpuid.h and avisynth_c.h)\n\n  Detect FMA4 and AVX512F,DQ,PF,ER,CD,BW,VL,IFMA,VBMI\n\n- new script function:\n  string ReplaceStr(string s, string pattern, string replacement)\n  Function is case sensitive, parameters are unnamed\n- new script function\n  int NumComponents(clip)\n  returns 1 for grayscale, 3 for YUVxxx, YUY2, planar RGB or RGB24/RGB48, 4 for YUVAxxx, Planar RGBA or RGB32/64\n- new script function:\n  bool HasAlpha(clip)\n  returns true when clip is YUVA, Planar RGBA, or packed RGB32 or RGB64\n\n20161222 r2347dev\n-----------------\n- CombinePlanes addition: setting target to default RGBP(A)/YUV(A), when inputs are greyscale and no source planes are given\n\n  Decision is made by the target plane characters, if they are like R,G,B then target video format will be planar RGB\n  Same logic applies for YUV.\n\n  Example:\n\n  Y1, Y2 and Y3 are greyscale clips\n\n    Old, still valid: combineplanes(Y1, Y2, Y3, planes=\"RGB\", source_planes=\"YYY\", pixel_type=\"RGBP8\")\n    New:              combineplanes(Y1, Y2, Y3, planes=\"RGB\") # result: Planar RGB\n\n- Fix: ScriptClip would show garbage text when internal exception occurs instead of the error message\n\n20161211 r2343dev\n-----------------\n- Overlay: use y offset when greymask=true (fix)\n- Fix DV chroma positioning (UV swapped), interlaced parameter check for 4:2:0\n  (fix by IanB in classic Avisynth)\n- BitBlt in 32 bit Avisynth:\n  for processors with AVX or better ignore tricky isse memcpy replacement, trust in memcpy (test)\n  (x64 is O.K., it always used memcpy)\n- Merge: use stream_load for AVX2\n- VDubFilter.dll:\n  convert 'd' double and 'l' long typed parameters to 'f' float and 'i' int for poor AviSynth\n  thus allowing the usage of such virtualdub filters\n- remove script array (new AVSValue schema) feature, cannot make it compatible with Invoke from v2.5 plugins\n  until I figure out a workaround or such plugins would slowly distinct.\n\n20161208 r2337dev\n-----------------\n- [feature temporarily removed, script arrays are incompatible until 2.5 plugins are supported]\n  C interface array compatibility vol#2 (zero size arrays)\n  (new AVSValue schema problem)\n- Merge, MergeChroma, MergeLuma: AVX2 (planar)\n- Possibly a bit faster text overlay\n\n20161207 r2333dev\n-----------------\n- Overlay fix\n\n20161206 r2331dev\n-----------------\n- YUY2 PlaneToY finally works\n- C interface compatible array-type AVSValue handling (new AVSValue schema problem)\n\n20161205 r2327dev\n-----------------\n- [feature temporarily removed, script arrays are incompatible until 2.5 plugins are supported]\n  BlankClip parameter \"colors\" accepts exact color values to use\n  Color order: Y,U,V,A or R,G,B(,A)\n  These color values are used as-is, not scaled or converted in any way.\n  Reason: old colors parameter is int (32 bit) cannot hold three or four 16 bit or float values\n  Example: BlankClip(width=1920,height=1080,length=1000,pixel_type=\"RGB64\", colors=[64000,32768,1231,65535])\n- ExtractY, PlaneToY(\"Y\") accepts YUY2 clip\n- ExtractR, ExtractG, ExtractB, ExtractA,\n  and\n  PlaneToY(\"R\"), PlaneToY(\"G\"), PlaneToY(\"B\"), PlaneToY(\"A\")\n  functions are accepting packed RGB input (RGB24/32/48/64)\n  They are converted to planar RGB on-the-fly before plane extraction\n- Histogram \"levels\" works from Planar RGB.\n  Color legends show R, G and B.\n  bits=8..12 parameter is still available for finer ultra-wide histogram display\n\n20161201 r2322dev\n-----------------\n- [feature temporarily removed, script arrays are incompatible until 2.5 plugins are supported]\n  constant script arrays\n  (note: feature was temporarily removed in r2443)\n\n::\n\n      array_variable = [[1,2,3],[4,5,8],\"hello\"]\n      dictionary = [[\"one\",1],[\"two\",2]]\n      empty = []\n      subarray = array_variable[0]\n      val = subarray[2]\n      val2 = array_variable[1,3]\n      str = array_variable[2]\n      n = ArraySize(array_variable) #3\n      n2 = ArraySize(empty) #0\n      val3 = dictionary[\"two\"]\n\n- arrays as filter parameters (named and unnamed):\n  new 'a' type or use '.' (any) and check AVSValue IsArray()\n  todo: maybe .+ or \\*+ syntax?\n  (note: feature was temporarily removed in r2443)\n- Planar RGB <-> YUV: SSE2 (SSE4)\n- Planar RGB <-> Packed RGB32/64: SSE2\n\n20161120:\n---------\n- make PlanarRGB TurnLeft, TurnRight work again. (stricter check in PlaneToY)\n\n20161119\n--------\n- Fix: PlaneToY(\"Y\")\n\n20161116\n--------\n- Replaced AToY8, GToY8, BToY8, RToY8\n  We have ExtractX, (X = R,G,B,Y,U,V,A) instead.\n  Reason: Y8 ending was too confusing.\n\n20161110 Avisynth plus additions\n--------------------------------\n\nNew functions\n\n::\n\n  AToY8 , same as PlaneToY(\"A\") for planar RGBA or YUVA\n  RToY8 , same as PlaneToY(\"R\") for planar RGB\n  GToY8 , same as PlaneToY(\"G\") for planar RGB\n  BToY8 , same as PlaneToY(\"B\") for planar RGB\n\n  They work the same way as UToY8 and VToY8 and ConvertToY did.\n  They convert to greyscale keeping the original bit-depth, not only 8 bit!\n  Y8 naming was kept, because UToY and VToY already existed.\n\nExtended function\n\n::\n\n  old: YToUV(clip clipU, clip clipV [, clip clipY ] )\n  new: YToUV(clip clipU, clip clipV [, clip clipY [, clip clipA] ] )\n\n  YToUV accepts optional alpha clip after Y clip\n\n  Example\n\n::\n\n      U = source.UToY8()\n      V = source.VToY8()\n      Y = source.ConvertToY()\n      A = source.AddAlphaPlane(128).AToY8()\n      # swaps V, U and A, Y\n      YToUV(V,U,A,Y).Histogram(\"levels\").Info().RemoveAlphaPlane()\n\nNew function\n\n::\n\n  CombinePlanes(clip1 [,clip2, clip3, clip4], string planes [, string source_planes, string pixel_type, string sample_clip])\n\n  Combines planes of source clip(s) into a target clip\n\n  If sample_clip is given, target clip properties are copied from that clip\n  If no sample_clip is provided, then clip1 provides the template for target clip\n  An optional pixel_type string (e.g.\"YV24\", \"YUV420PS\", \"RGBP8\") can override the base video format.\n\n  If the source clip count is less than the given planes defined, then the last available clip is\n  used as a source.\n\n  string planes\n    the target plane order (e.g. \"YVU\", \"YYY\", \"RGB\")\n    missing target planes will be undefined in the target\n\n  string source_planes (optional)\n    the source plane order, defaulting to \"YUVA\" or \"RGBA\" depending on the video format\n\n  Example #1\n\n::\n\n      #combine greyscale clips into YUVA clip\n      U8 = source.UToY8()\n      V8 = source.VToY8()\n      Y8 = source.ConvertToY()\n      A8 = source.AddAlphaPlane(128).AToY8()\n      CombinePlanes(Y8, U8, V8, A8, planes=\"YUVA\", source_planes=\"YYYY\", sample_clip=source) #pixel_type=\"YUV444P8\"\n\n  Example #2\n\n::\n\n      # Copy planes between planar RGB(A) and YUV(A) without any conversion\n      # yuv 4:4:4 <-> planar rgb\n      source = last.ConvertBits(32) # 4:4:4\n      cast_to_planarrgb = CombinePlanes(source, planes=\"RGB\", source_planes=\"YUV\", pixel_type=\"RGBPS\")\n      # get back a clip identical with \"source\"\n      cast_to_yuv = CombinePlanes(cast_to_planarrgb, planes=\"YUV\", source_planes=\"RGB\", pixel_type=\"YUV444PS\")\n\n  Example #3\n\n::\n\n      #create a black and white planar RGB clip using Y channel\n      #source is a YUV clip\n      grey = CombinePlanes(source, planes=\"RGB\", source_planes=\"YYY\", pixel_type=\"RGBP8\")\n\n  Examples #4\n\n::\n\n      #copy luma from one clip, U and V from another\n      #source is the template\n      #sourceY is a Y or YUV clip\n      #sourceUV is a YUV clip\n      grey = CombinePlanes(sourceY, sourceUV, planes=\"YUV\", source_planes=\"YUV\", sample_clip = source)\n\n  Remark: When there is only one input clip, zero-cost BitBlt-less subframes are used, which is much faster.\n\n  e.g.: casting YUV to RGB, shuffle RGBA to ABGR, U to Y, etc..\n  Target planes that are not specified, preserve their content.\n\n  Examples:\n\n::\n\n      combineplanes(clipRGBP, planes=\"RGB\",source_planes=\"BGR\") # swap R and B\n      combineplanes(clipYUV, planes=\"GBRA\",source_planes=\"YUVA\",pixel_type=\"RGBAP8\") # cast YUVA to planar RGBA\n      combineplanes(clipYUV, planes=\"Y\",source_planes=\"U\",pixel_type=\"Y8\") # extract U\n\n\nEarlier (pre v2294) modifications and informations on behaviour of existing filter\n----------------------------------------------------------------------------------\n**[ColorSpaceNameToPixelType]**\n\nNew script function: ColorSpaceNameToPixelType()\n\nParameter: video colorspace string\n\nReturns: Integer\n\nReturns a VideoInfo::pixel_type integer from a valid colorspace string\n\nIn Avisynth+ we have way too many pixel_type's now, this function can be useful for plugins for parsing a target colorspace string parameter.\n\nEarlier I made this function available from within avisynth core, as I made one function from the previous 3-4 different places where colorspace name parameters were parsed in a copy-paste code.\n\nIn Avisynth the existing PixelType script function returns the pixeltype name of the current clip.\nThis function reverses this.\n\nIt has the advantage that it returns the same (for example) YV24 constant from \"YV24\" or \"YUV444\" or \"Yuv444p8\", so it recognizes some possible naming variants.\n\n::\n\n    csp_name = \"YUV422P8\"\n    csp_name2 = \"YV16\"\n    SubTitle(\"PixelType value of \" + csp_name + \" = \" + String(ColorSpaceNameToPixelType(csp_name))\\\n    + \" and \" + csp_name2 + \" = \" + String(ColorSpaceNameToPixelType(csp_name2)) )\n\n**[New conditional functions]**\n\nConditional runtime functions have 10-16 bit/float support for YUV, PlanarRGB and 16 bit packed RGB formats.\n\nSince RGB is also available as a planar colorspace, the plane statistics functions logically were expanded.\n\nNew functions\n\n• AverageR, AverageG AverageB like AverageLuma\n• RDifference, GDifference, BDifference like LumaDifference(clip1, clip2)\n• RDifferenceFromPrevious, GDifferenceFromPrevious, BDifferenceFromPrevious\n• RDifferenceToNext, GDifferenceToNext, BDifferenceToNext\n• RPlaneMin, GPlaneMin BPlaneMin like YPlaneMin(clip [, float threshold = 0, int offset = 0])\n• RPlaneMax, GPlaneMax BPlaneMax like YPlaneMax(clip [, float threshold = 0, int offset = 0])\n• RPlaneMinMaxDifference, GPlaneMinMaxDifference BPlaneMinMaxDifference like YPlaneMinMaxDifference(clip [, float threshold = 0, int offset = 0])\n• RPlaneMedian, GPlaneMedian, BPlaneMedian like YPlaneMedian(clip [, int offset = 0])\n\nFor float colorspaces the Min, Max, MinMaxDifference and Median functions populate pixel counts for the internal statistics at a 16 bit resolution internally.\n\n**[Tweak]**\n\nSee original doc: http://avisynth.nl/index.php/Tweak\n\nThe original 8 bit tweak worked with internal LUT both for luma and chroma conversion.\n\nChroma LUT requires 2D LUT table, thus only implemented for 10 bit clips for memory reasons.\nLuma LUT is working at 16 bits (1D table)\n\nAbove these limits the calculations are realtime, and done pixel by pixel.\nYou can use a new parameter to force ignoring LUT usage (calculate each pixel on-the-fly)\n\nFor this purpose use realcalc=true.\n\n**[MaskHS]**\n\nWorks for 10-16bit,float.\n\nMaskHS uses LUT for 10/12 bits. Above this (no memory for fast LUTs) the calculation is done realtime for each.\n\nTo override LUT for 10-12 bits use new parameter realcalc=true\n\n**[ColorKeyMask]:**\n\nWorks for RGB64, Planar RGBA 8-16,float.\n\nColorKeyMask color and tolerance parameters are the same as for 8 bit RGB32.\n\nInternally they are automatically scaled to the current bit-depth\n\n**[ResetMask]**\n\nNew extension.\n\nAccepts parameter (Mask=xxx) which is used for setting the alpha plane for a given value.\n\nDefault value for Mask is 255 for RGB32, 65535 for RGB64 and full 16 bit, 1.0 for float.\n\nFor 10-12-14 bit it is set to 1023, 4095 and 16383 respectively.\n\nParameter type is float, it can be applied to the alpha plane of a float-type YUVA or Planar RGBA clip.\n\n**[Layer]**\n\nLayer() now works for RGB64.\n\nOriginal documentation: http://avisynth.nl/index.php/Layer\n\nBy avisynth documentation: for full strength Level=257 (default) should be given.\nFor RGB64 this magic number is Level=65537 (this is the default when RGB64 is used)\n\nSample:\n\n::\n\n      lsmashvideosource(\"test.mp4\", format=\"YUV420P8\")\n      x=last\n      x = x.Spline16Resize(800,250).ColorYUV(levels=\"TV->PC\")\n      x = x.ConvertToRGB32()\n      \n      transparency0_255 = 128 # ResetMask's new parameter. Also helps testing :)\n      x2 = ColorBars().ConvertToRGB32().ResetMask(transparency0_255)\n      \n      x_64 = x.ConvertToRGB32().ConvertBits(16)\n      x2_64 = ColorBars().ConvertToRGB32().ConvertBits(16).ResetMask(transparency0_255 / 255.0 * 65535.0 )\n      \n      #For pixel-wise transparency information the alpha channel of an RGB32 overlay_clip is used as a mask.\n      \n      op = \"darken\" # subtract lighten darken mul fast\n      level=257         # 0..257\n      level64=65537     # 0..65537\n      threshold=128                   # 0..255   Changes the transition point of op = \"darken\", \"lighten.\"\n      threshold64=threshold*65535/255 # 0..65535 Changes the transition point of op = \"darken\", \"lighten.\"\n      use_chroma = true\n      rgb32=Layer(x,x2,op=op,level=level,x=0,y=0,threshold=threshold,use_chroma=use_chroma )\n      rgb64=Layer(x_64,x2_64,op=op,level=level64,x=0,y=0,threshold=threshold64,use_chroma=use_chroma ).ConvertBits(8)\n      StackVertical(rgb32, rgb64)\n\n**[Levels]**\n\nLevels: 10-16 bit support for YUV(A), PlanarRGB(A), 16 bits for RGB48/64\n\nNo float support yet\n\nLevel values are not scaled, they are accepted as-is for 8+ bit depths\n\nTest scripts for Levels\n\n::\n\n      # Gamma, ranges (YUV):\n      x=ConvertToYUV420()\n      dither=true\n      coring=true\n      gamma=2.2\n      output_low = 55\n      output_high = 198\n      clip8 = x.Levels(0, gamma, 255, output_low, output_high , dither=dither, coring=coring)\n      clip10 = x.ConvertBits(10).Levels(0,gamma,1023,output_low *4,(output_high +1)*4 - 1, dither=dither, coring=coring)\n      clip16 = x.ConvertBits(16).Levels(0,gamma,65535,output_low *256,(output_high+1) *256 -1,dither=dither, coring=coring)\n      stackvertical(clip8.Histogram(\"levels\"), clip10.ConvertBits(8).Histogram(\"levels\"), Clip16.ConvertBits(8).Histogram(\"levels\"))\n\n      # packed RGB 32/64\n      xx = ConvertToRGB32()\n      dither=false\n      coring=false\n      gamma=1.4\n      clip8 = xx.Levels(0, gamma, 255, 0, 255, dither=dither, coring=coring)\n      clip16 = xx.ConvertBits(16).Levels(0,gamma,65535,0,65535,dither=dither, coring=coring)\n      stackvertical(clip8.ConvertToYUV444().Histogram(\"levels\"), Clip16.ConvertBits(8).ConvertToYUV444().Histogram(\"levels\"))\n\n**[ColorYUV]**\n\nNow it works for 10-16 bit clips\n\n- Slightly modified \"demo\" mode when using ColorYUV(showyuv=true)\n\n::\n\n    #old: draws YV12 with 16-239 U/V image (448x448)\n    #new: draws YV12 with 16-240 U/V image (450x450)\n\nNew options for \"demo\" mode when using ColorYUV(showyuv=true)\n\nNew parameter: bool showyuv_fullrange.\n\nDescription: Draws YV12 with 0-255 U/V image (512x512)\n\nUsage: ColorYUV(showyuv=true, showyuv_fullrange=true)\n\nNew parameter: bits=10,12,14,16\n\nResult clip is the given bit depth for YUV420Pxx format.\nAs image size is limited (for 10 bits the range 64-963 requires big image size), color resolution is 10 bits maximum.\n\n::\n\n    #This sample draws YUV420P10 with 64-963 U/V image\n    ColorYUV(showyuv=true, bits=10).Info()\n\nLuma steps are 16-235-16../0-255-0.. up to 0-65535-0... when bits=16\n\nAdditional infos for ColorYUV\n\n- Fixed an uninitialized internal variable regarding pc<->tv conversion,\n  resulting in clips sometimes were expanding to pc range when it wasn't asked.\n- No parameter scaling needed for high bit depth clips.\n  For 8+ bit clips parameter ranges are the same as for the 8 bit clips.\n  They will be scaled properly for 10-16 bitdepths.\n  e.g. off_u=-20 will be converted to -204 for 10 bits, -20256 for 16 bits\n- ColorYUV uses 8-10-12-14-16 bit lut.\n- ColorYUV is not available for 32 bit (float) clips at the moment\n\n**[Other things you may have not known]**\n\nSource filters are automatically detected, specifying MT_SERIALIZED is not necessary for them.\n\n**[Known issues/things]**\n\nGRunT in MT modes (Avs+ specific)\n\n[done: v2502]\n\nOverlay blend with fully transparent mask is incorrect, overlaying pixel=0 becomes 1, overlaying pixel=255 becomes 254.\n\n[done: v2676-]\n\nFloat-type clips: chroma should be zero based: +/-0.5 instead of 0..1\n\n\n$Date: 2021/12/07 13:36:0 $\n\n.. _github AviSynthPlus page:\n    https://github.com/AviSynth/AviSynthPlus\n.. _Doom9's AviSynth+ forum:\n    https://forum.doom9.org/showthread.php?t=181351\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/changelist35.rst",
    "content": "Changes from to 3.4 to 3.5 (20200302)\n-------------------------------------\n\n\nAdditions\n~~~~~~~~~\n- Layer: support RGB24 and RGB48 (internally processed as Planar RGB - lossless pre and post conversion)\n- New bool IsVersionOrGreater(int majorVersion, int minorVersion [,int bugfixVersion]) function\n- Overlay: show error when Overlay is fed with clips with different bit depths\n- New: AddBorders, LetterBox: new color_yuv parameter like in BlankClip\n- WavSource: really use \"utf8\" parameter, fix some debug asserts\n- TimeStrech: pass internal errors as Avisynth exception text (e.g. proper \"Excessive sample rate!\" instead of \"unhandled C++ error\")\n- \"Expr\" helper constants \"yrange_min\", \"yrange_half\", \"yrange_max\"\n- \"Expr\" new parameter: bool clamp_float_UV\n- \"Expr\" \"clamp_float\" is not ignored (and set to true) when parameter \"scale_inputs\" auto-scales 32 bit float type pixels\n- \"Expr\" \"yscalef\" and \"yscaleb\" keywords similar to \"scalef\" and \"scaleb\" but scaling is forced to use rules for Y (non-UV) planes\n- \"Expr\" new allowed value \"floatUV\" for scale_inputs supporting special 32 bit chroma case\n\nBuild environment, Interface\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n- Native Linux, macOS, and BSD support.\n- Build system: Cmake: use platform toolset \"ClangCL\" for using built-in Clang support of Visual Studio (Since VS2019 v16.4 there is LLVM 9.0 support)\n\nBugfixes\n~~~~~~~~\n- Fix: ConvertBits 32->8 for extremely out of range float pixel values.\n  When pixel value in a 32 bit float format video was way out of range and greater than 128 (e.g. instead of 0 to 1.0 for Y plane) then the ConvertBits(8) had artifacts.\n- Fix potential crash on exit or cache shrink (linux/gcc only?)\n- Fix: RGBP to 444 8-14bit right side artifacts at specific widths\n- Fix: \"scalef\" and \"scaleb\" for 32 bit input, when scale_inputs=\"floatf\" produced wrong result\n- Fix: missing rounder in V channel calculation of PlanarRGB->YUV 8-14bits SSE2 code\n- Fix: TemporalSoften possible access violation after SeparateFields (in general: after filters that only change frame pitch)\n- Fix: Shibatch.DLL Access Violation crash when exit when target rate is the same as vi.audio_samples_per_second or audio_samples_per_second is 0\n- Fix: Resizers to really resize alpha channel (YUVA, RGBPA)\n- Fix: crash when outputting VfW (e.g. VirtualDub) for YUV444P16, other fixes for r210 and R10k formats\n\n\nOptimizations\n~~~~~~~~~~~~~\n\n\n\nPlease report bugs at `github AviSynthPlus page`_ - or - `Doom9's AviSynth+\nforum`_\n\n$Date: 2021/12/07 13:36:0 $\n\n.. _github AviSynthPlus page:\n    https://github.com/AviSynth/AviSynthPlus\n.. _Doom9's AviSynth+ forum:\n    https://forum.doom9.org/showthread.php?t=181351\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/changelist36.rst",
    "content": "Changes from 3.5 to 3.6 (20200520)\n----------------------------------\n\nAdditions\n~~~~~~~~~\n- User defined functions add array parameter types:\n  \"array\" or \"val_array\", \"bool_array\" \"int_array\", \"float_array\", \"string_array\", \"clip_array\", \"func_array\"\n- New: Format function\n- Add frame property getter and setter functions\n- Add SetMaxCPU to limit reported CPU level (useful for debugging)\n- Allow multiple prefetchers (MT) (from Neo fork)\n- Add argument to Prefetch to change # of prefetch frames without changing # of threads (from Neo fork)\n- Caching enhancements SetCacheMode (from Neo fork)\n- ScriptClip and variable stability in multithreading, add 'local' parameter to\n  ConditionalSelect, ConditionalFilter, ScriptClip, ConditionalReader, FrameEvaluate, WriteFile, WriteFileIf, WriteFileStart, WriteFileEnd\n- UseVar, special filter, opens a clean variable environment in which only the variables in the parameter list can be seen (from Neo fork)\n- \"escaped\" string constants: with e prefix right before the quotation mask (from Neo fork)\n- Introduce function objects into scripts (from Neo fork)\n- Filter graph to e.g. svg. SetGraphAnalysis and DumpFilterGraph. (from Neo fork)\n- POSIX: better behaviour under non-Windows because of having multiple sized fixed fonts\n- Text filter (the only way to \"SubTitle\" for non-Windows)\n- Info() filter: when parameter \"size\" < 0, font is automatically enlarged over 640x480\n- SIL OPEN FONT LICENSE added because of usage of Terminus fonts\n- Exist() to have bool utf8 parameter (file existance check)\n\nBuild environment, Interface, Internal source\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n- frame properties framework, IScriptEnvironment extension, Interface V8\n- re-enable and fix script arrays (NEW_AVSVALUE define at the moment)\n- Big Neo Merge\n- Added predefined macros for ARM processors. Tested on Raspberry Pi 4B with the aarch64 image of Ubuntu 20.04.\n- Added support for disabling the Intel SIMD intrinsics. Gets automatically disabled on non-x86 targets.\n- Added submodule to allow macOS 10.13 and 10.14 to build AviSynth+ with the native Clang compiler\n- Support for various processors and OSs\n- IScriptEnvironment new additions\n  Ex-IScriptEnvironment2: no-throw version of Invoke name change to -> InvokeTry\n  Ex-INeo Invoke versions to -> Invoke2Try, Invoke3, Invoke3Try\n  New (was not implemented in any former Interface): Invoke2 (Exception Thrower version of Invoke2Try)\n\n\nBugfixes\n~~~~~~~~\n- Fix: broken Exist for directories (regression appeared in 3.5.0)\n- Fix: ColorYUV: really disable variable search when parameter \"conditional\" is false\n- Fix: ReplaceStr when the pattern string to be replaced is empty\n- Fix: BuildPixelType: chroma subsampling of sample clip was ignored.\n- Fix: Mix/Max Runtime function 32bit float chroma: return -0.5..0.5 range (was: 0..1 range)\n- Multithreading and deadlock fixes for ScriptClip (Neo fork)\n\n\nOptimizations\n~~~~~~~~~~~~~\n- Enhanced: Planar RGB to YUV 444 10-14 bits: more precision (32 bit float internally)\n- Enhanced: Planar RGB to YUV 444 10-16 bits: AVX2 (speed improvement)\n\n\nPlease report bugs at `github AviSynthPlus page`_ - or - `Doom9's AviSynth+\nforum`_\n\n$Date: 2021/12/07 13:36:0 $\n\n.. _github AviSynthPlus page:\n    https://github.com/AviSynth/AviSynthPlus\n.. _Doom9's AviSynth+ forum:\n    https://forum.doom9.org/showthread.php?t=181351\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/changelist37.rst",
    "content": "Changes from 3.6 to 3.7 (20210111)\n----------------------------------\n\nAdditions\n~~~~~~~~~\n- Resizers: throw error on too small dimensions vs. taps\n- Add ShowCRC32 debug filter. Parameters are the same as in ShowFrameNumber\n- Overlay: allow 4:1:1 input\n- RemoveAlphaPlane: do nothing on YUY2 instead of throwing an error message\n- AviSource: support non-printing characters in fourCC code: allow [number] style, e.g. G3[0][16]\n- AviSource: add Y410 (YUVA444P10) format support. Allow 'Y410' pixel_type hints.\n- AviSource: decode b64a, b48r, v210, P210, P010, P016, P216, v410, Y416, r210, R10k, v308, v408, Y410 fourCCs natively.\n- Add: AverageA\n- New: Average...: allow YUY2, RGB24/32/48/64 inputs\n- support for Win10 long file path option\n- internally refactored ConvertAudio\n- New: Histogram(\"color2\") to support 10+ bits.\n  Allow bits=x (x=8,9,10,11,12) parameter for this kind of histogram as well.\n- pass V3 (2.5) IScriptEnvironment for CPP plugins which directly load avisynth.dll and\n  request CreateScriptEnvironment with version <= 3 \n- Histogram(\"levels\") to allow greyscale\n\n\nBuild environment, Interface, Source\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n- Haiku support\n- PowerPC support\n- Support for building the core as a static library (mcmtroffaes)\n- Fixes for MinGW-w64 compilation\n- Shibatch, TimeStretch, and ImageSeq GCC build support\n- Shibatch, TimeStretch, and ImageSeq non-Windows support\n- project: Improve inclusion of the ghc filesystem helper library\n- project: Add a GitHub action workflow\n- Make frame property related constants to not collide with VapourSynth's definitions. (favour for multi-target plugins)\n\n\nBugfixes\n~~~~~~~~\n- Fix: AddBorders did not pass frame properties\n- Fix: propSet, propDelete and propClearAll not to ruin visibility of variables (property read functions are still kept being runtime only)\n- Fix: Average...: check for valid colorspace (e.g. no AverageB for a YUV clip)\n- Fix: Overlay: Actual frame of a mask clip would be freed up too early in MT environment\n- Fix: ConvertBits to ignore dither parameter instead of throwing error, in a 8 to 8 bit case\n- Fix: GeneralConvolution missing internal rounding on 8-16 bit formats\n- posix: fix crash when autoloading imports\n- ConvertBits(8): fix dither=1 (floyd) for RGB48/RGB64\n- Fix: Blur right side garbage: 16 bit+AVX2+non mod32 width\n- Fix: check fn signature with implicite \"last\" first (3.6 regression)\n- Fix: function parameters provided as arrays (e.g. GrunT callback of WriteFileIf)\n- Fix: ConvertBits (YUV): proper rounding when bit depth is reduced and origin is 10-16 bits (added rounder before bit-shift)\n- Fix: proper handling of autoload directories precedence\n- Fix: ScriptClip + Runtime function object (which are new in 3.6) under heavy multithreading\n- fix: GeneralConvolution: incorrect parse of negative integer coefficient (+1) regression since r2772\n- fix: GeneralConvolution: possible crash when chroma=true for 420 and 422 formats\n- Fix 3.6 regressions\n  - when explicit \"return last\" was needed when followed by legacy function definition.\n  - Windows XP is supported again (thread local storage workaround)\n  - Stabilize CPP 2.5 plugins\n  - allow forced named arrays usage again from plugins (MP_PipeLine)\n\n\nOptimizations\n~~~~~~~~~~~~~\n- Overlay: may work quicker, most input/overlay/mask/output clip format conversions moved to filter constructor\n\n\n\nPlease report bugs at `github AviSynthPlus page`_ - or - `Doom9's AviSynth+\nforum`_\n\n$Date: 2021/12/07 13:36:0 $\n\n.. _github AviSynthPlus page:\n    https://github.com/AviSynth/AviSynthPlus\n.. _Doom9's AviSynth+ forum:\n    https://forum.doom9.org/showthread.php?t=181351\n\nUseful links:\n-------------\n\n- Source (from 3.4): https://github.com/AviSynth/AviSynthPlus\n- Source (before 3.4): https://github.com/pinterf/AviSynthPlus/tree/MT\n- Forum: https://forum.doom9.org/showthread.php?t=168856\n- Forum on some avs+ filters: https://forum.doom9.org/showthread.php?t=169832\n- Avisynth+ info page: http://avisynth.nl/index.php/AviSynth%2B\n- Info on Avisynth+ new color spaces: https://forum.doom9.org/showthread.php?p=1783714#post1783714\n- Avisynth Universal Installer by Groucho2004: https://forum.doom9.org/showthread.php?t=172124\n\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/changelist371.rst",
    "content": "Changes from 3.7 to 3.7.1\n-------------------------\n\nAdditions\n~~~~~~~~~\n- Bump AVISYNTH_INTERFACE_VERSION to 9, AVISYNTHPLUS_INTERFACE_BUGFIX_VERSION to 0\n- Linux: Show more information when dlopen fails\n- Expr: allow auto scaling effect on pixels obtained from relative addressing\n- New array manipulators: ArrayDel, ArrayAdd, ArrayIns, ArraySet with accepting multi dimensional indexes\n- ExtractY/U/V/R/G/B/A, PlaneToY: delete _ChromaLocation property. Set _ColorRange property to \"full\" if source is Alpha plane\n- Add new AEP (Avisynth Environtment Property) constants to directly query Avisynth interface main and bugfix version and system endianness:\n  AEP_HOST_SYSTEM_ENDIANNESS, AEP_INTERFACE_VERSION, AEP_INTERFACE_BUGFIX (c++)\n  AVS_AEP_HOST_SYSTEM_ENDIANNESS, AVS_AEP_INTERFACE_VERSION, AVS_AEP_INTERFACE_BUGFIX (c)\n- Interface: introduce AVISYNTHPLUS_INTERFACE_BUGFIX_VERSION.\n- New interface functions env->MakePropertyWritable/VideoFrame::IsPropertyWritable.\n- Expr: allow 'f32' as internal autoscale target (was: i8, i10, i12, i14, i16 were accepted, only integers)\n- Expr: LUT mode! 'lut'=1 or 2 for 1D (lut_x) and 2D (lux_xy) support\n- xPlaneMin/Max/Median/MinMaxDifference to accept old packed formats (RGB24/32/48/64 and YUY2) by autoconverting them to Planar RGB or YV16\n- New runtime function: PlaneMinMaxStats returns an array and/or set global variables.\n- Language syntax: accept arrays in the place of \"val\" script function parameter type regardless of being named or unnamed. \n- Histogram \"Levels\": more precise drawing when bit depth is different from histogram's resolution bit depth, plus using full/limited flag.\n- Expr: no more banker's rounding when converting back float result to integer pixels. Using the usual truncate(x+0.5) rounding method\n- ColorYUV: More consistent and accurate output across different color spaces, match with ConvertBits fulls-fulld conversions\n- ColorYUV: set _ColorRange frame property\n- ColorYUV: when no hint is given by parameter \"levels\" then it can use _ColorRange (limited/full) frame property for establishing source range for gamma\n- ColorYUV \"showyuv_fullrange\"=true: fix shown U and V ranges. E.g. for bits=8: 128 +/- 127 (range 1..255 is shown) instead of 0..255\n- propShow: display _Matrix, _ColorRange and _ChromaLocation constants with friendly names\n- Expr: new function \"sgn\". Returns -1 when x is negative; 0 if zero; 1 when x is positive\n- Expr: add \"neg\": negates stack top: a = -a\n- ConvertBits: Support YUY2 (by autoconverting to and from YV16), support YV411\n- ConvertBits: \"bits\" parameter is not compulsory, since bit depth can stay as it was before. Call like ConvertBits(fulld=true)\n- ConvertBits: much nicer output for low bit depth targets such as dither_bits 1 to 7.\n- ConvertBits: allow dither down from 8 bit sources by giving a lower dither_bits value\n- ConvertBits: dither=1 (Floyd-S) to support dither_bits = 1 to 16 (similar to ordered dither)\n- ConvertBits: dither=0 (ordered) to allow odd dither_bits values. Any dither_bits=1 to 16 (was: 2,4,6,8,..)\n- ConvertBits: dither=0 (ordered) allow larger than 8 bit difference when dither_bits is less than 8.\n- ConvertBits: Correct conversion of full-range chroma at 8-16 bits. Like 128+/-112 -> 128+/-127 in 8 bits\n- ConvertBits: allow dither from 32 bits to 8-16 bits\n- ConvertBits: allow different fulls fulld when converting between integer bit depths (was: they must have been the same)\n- ConvertBits: allow 32 bit to 32 bit conversion\n- frame property support: _ChromaLocation in various filters (e.g. ConvertToYUV422)\n- Support additional chroma locations \"top\", \"bottom_left\", \"bottom\"\n- New syntax for \"matrix\" parameters (e.g. in ConvertToYUV444 old:\"rec601\" new \"170m:l\") which separate matrix and full/limited marker.\n  Old syntax is still valid but does not support all new matrix values.\n- frame propery support: _Matrix and _ColorRange in various filters. New \"matrix\" string constants\n- RGB<->YUV (YUY2) conversions: frame property support _Matrix and _ColorRange (_Primaries and _Transfer is not used at all yet)\n- ConvertBits: use input frame property _ColorRange to detect full/limited range of input clip\n- ColorBars, ColorBarsHD, BlankClip: set frame properties _ColorRange and _Matrix\n- New function: propCopy to copy or merge frame properties from one clip to another.\n- xxxPlaneMin xxxPlaneMax, xxxPlaneMinMaxDifference for 32 bit float formats:\n  when threshold is 0 then return real values instead of 0..1 (chroma -0.5..0.5) clamped histogram-based result\n- Allow propGetXXX property getter functions called as normal functions, outside runtime. Frame number offset can be used.\n- YUY2 RGB conversions now allow matrix \"PC.2020\" and \"Rec2020\"\n- 4:2:2 conversions: allow ChromaInPlacement and ChromaOutPlacement:\n  Valid values: left/mpeg2, center/mpeg1/jpeg\n- 4:2:0 conversions: new ChromaInPlacement and ChromaOutPlacement values: \n  top_left, left (alias to mpeg2), center (alias to mpeg1), jpeg (alias to mpeg1) (see http://avisynth.nl/index.php/Convert)\n- Expr: atan2 (SIMD acceleration as well)\n- Expr: sin and cos SIMD acceleration (SSE2 and AVX2) port from VapourSynth (Akarin et al.)\n- Expr: x.framePropName syntax for injecting actual frame property values into expression\n- Script functions to supports arrays with _nz type suffix. (one or more)\n- Expr: arbitrary variable names (instead of single letters A..Z), up to 128 different one. \n- Expr: add 'round', 'floor', 'ceil', 'trunc' operators (nearest integer, round down, round up, round to zero)\n  Acceleration requires at least SSE4.1 capable processor or else the whole expression is running in C mode.\n- Recognize \\\\' and \\\\b and \\\\v in escaped (e\"somethg\") string literals (see http://avisynth.nl/index.php/The_full_AviSynth_grammar#Literals)\n- Expr: allow TAB, CR and LF characters as whitespace in expression strings\n- Clip types for propSet, propGet, add propSetClip, propGetClip\n- Clip content support for propGetAsArray, propSetArray and propGetAll\n- RGBAdjust: analyse=true 32 bit float support\n\n\nBuild environment, Interface\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n- Visual Studio 2022: Add /fp:contract to compilation parameters (addition to /fp:precise)\n- Check Visual Studio 2022, add build examples to documentation. Recognized: it has still an option to use v141_xp toolkit\n- CMake build environment: older GCC can be used which knows only -std=c++-1z instead of c++17\n- AviSynth programming interface V8.1 / V9:\n  Add 'MakePropertyWritable' to the IScriptEnvironment (CPP interface), avs_make_property_writable (C interface)\n  Add 'VideoFrame::IsPropertyWritable' (CPP interface), avs_is_property_writable (C interface)\n- Info on Windows XP compatibility (must revert to an older Visual C++ Redistributable)\n- CMake/source: Intel C++ Compiler 2021 and Intel C++ Compiler 19.2 support\n- experimental! Fix CUDA plugin support on specific builds, add CMake support for the option.\n- Fixes for building the core as a static library\n\n\nBugfixes\n~~~~~~~~\n- Fix: Debug build does not crash with stack overflow when some 1000+ clips are in filter chain.\n- Fix memory and speed issues when Prefetch was not the last position or there are multiple Prefetch.\n- Fix: \"Text\" filter would crash when y coord is odd and format has vertical subsampling\n- Fix: MinMax runtime filter family: check plane existance (e.g. error when requesting RPlaneMinMaxDifference on YV12)\n- Fix: prevent x64 debug AviSynth builds from crashing in VirtualDub2 (opened through CAVIStreamSynth)\n- Expr: fix conversion factor (+correct chroma scaling) when integer-to-integer full-scale automatic range scaling was required\n- ColorYUV: fix 32 bit float output\n- ColorYUV: fix display when showyuv=true and bits=32\n- ConvertBits: \"dither\" parameter: type changed to integer. Why was it float? :)\n- ConvertBits: Fix: fulls=true -> fulld=true 16->8 bit missing rounding\n- Fix: Planar RGB 32 bit -> YUV matrix=\"PC.709\"/\"PC.601\"/\"PC.2020\" resulted in greyscale image\n- SelectRangeEvery: experimental fix on getting audio part (TomArrow; https://github.com/AviSynth/AviSynthPlus/issues/232)\n- Fix: Overlay \"blend\" 10+ bit clips and \"opacity\"<1 would leave rightmost non-mod8 (10-16 bit format) or non-mod4 (32 bit format) pixels unprocessed.\n- Fix: Overlay \"blend\" with exactly 16 bit clips and \"opacity\"<1 would treat large mask values as zero (when proc>=SSE4.1)\n- Parser: proper error message when a script array is passed to a non-array named function argument\n  (e.g. foo(sigma=[1.1,1.1]) to [foo]f parameter signature)\n- Fix: Expr: wrong constant folding optimization when ternary operator and Store-Only (like M^) operator is used together.\n- ColorBars: fixed studio RGB values for -I and +Q for rgb pixel types\n- ColorBarsHD: use BT.709-2 for +I (Pattern 2), not BT.601.\n  Also fixed Pattern 1 Green.Y to conform to SMPTE RP 219-1:2014 (133, not 134).\n- Overlay mode \"multiply\": proper rounding in internal calculations\n- Fix: ConvertAudio integer 32-to-8 bits C code garbage (regression in 3.7)\n- Fix: ConvertAudio: float to 32 bit integer conversion max value glitch (regression in 3.7)\n- Fix: Crash in ColorBars very first frame when followed by ResampleAudio\n- Fix: frame property access from C interface\n- Fix: StackVertical and packed RGB formats: get audio and parity from the first and not the last clip\n\n\nOptimizations\n~~~~~~~~~~~~~\n- CombinePlanes: a bit optimized MergeLuma-like cases\n- Quicker ClearProperties and CopyProperties filters (by using MakePropertyWritable instead of MakeWritable).\n- ConvertBits: AVX2 support\n- ConvertBits: Special case for: 8->16 bit fulls=true, fulld=true\n- Expr: consume less bytes on stack. 48x Expr call in sequence caused stack overflow\n- xxxPlaneMin xxxPlaneMax, xxxPlaneMinMaxDifference for threshold 0 became a bit quicker for 8-16 bit formats (~10% on i7-7700)\n- Speedup: Overlay mode \"multiply\": overlay clip is not converted to 4:4:4 internally when 420 or 422 subsampled format \n  (since only Y is used from that clip)\n- Speedup: Overlay mode \"multiply\": SSE4.1 and AVX2 code (was: C only)\n  SSE4.1: ~1.2-2.5X speed, AVX2: ~2-3.5X speed (i7700 x64 single thread, depending on opacity full/not, mask clip yes/no)\n- ConvertAudio: Add direct Float from/to 8/16 conversions (C,SSE2,AVX2)\n\n\n\nPlease report bugs at `github AviSynthPlus page`_ - or - `Doom9's AviSynth+\nforum`_\n\n$Date: 2021/12/07 13:36:0 $\n\n.. _github AviSynthPlus page:\n    https://github.com/AviSynth/AviSynthPlus\n.. _Doom9's AviSynth+ forum:\n    https://forum.doom9.org/showthread.php?t=181351\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/changelist372.rst",
    "content": "Changes from 3.7.1 to 3.7.2\n---------------------------\n\nAdditions, changes\n~~~~~~~~~~~~~~~~~~\n- Bump copyright year to 2022\n- Allow top_left (2) and bottom_left (4) chroma placements for 422 in colorspace conversions, they act as \"left\" (0, \"mpeg2\")\n- ShowRed/Green/Blue/Alpha/Y/U/V\n  - support YUY2 input\n  - support YV411 output\n  - Copy alpha from source when target is alpha-capable\n  - Fill alpha with maximum pixel value when target is alpha-capable but source ha no alpha component\n  - Delete _Matrix and _ChromaLocation frame properties when needed.\n  - More consistent behaviour for YUV and planar RGB sources, adaptive default pixel_type (YUV, planar or packed rgb)\n- Histogram \"Luma\": support 10-16 and 32 bits\n- Histogram: give parameter name \"factor\" and type 'float' for Histogram's unnamed optional parameter used in \"Level\" mode.\n- Histogram Levels: stop using shades of grey on top of bars.\n- Histogram Levels: use bar color 255 for RGB instead of Y's 235. (and scaled eqivivalents)\n- PropCopy: new string parameter \"props\": list of property names to copy (or ignore)\n- PropCopy: new bool parameter \"exclude\": whether property list is positive (copy) or negative (do not copy; blacklist)\n- PropDelete: accept an array string parameter as list of property names to remove\n- MergeRGB, MergeARGB\n  - add MergeARGB parameter \"pixel_type\", similar to MergeRGB\n  - accept pixel_type other than packed RGB formats, plus a special one is \"rgb\"\n  - output format can be planar rgb(a)\n  - Accept planar RGB clip in place of input clips and the appropriate color plane is copied from them\n  - Fill alpha channel with zero when MergeRGB output pixel_type format is specified to have an alpha plane\n  - frame property source is the R clip; _Matrix and _ChromaLocation are removed if R is not an RGB clip\n- \"FadeX\" filter family new parameters: int 'color_yuv' and array of float 'colors' similar to BlankClip\n- BlankClip: allow 'colors' with array size more than the number of actual planes.\n- BlankClip, AddBorders, LetterBox: no \"alpha part must be zero\" check for non-YUVA\n- Version (#261): New optional parameters int length, int width, int height, string pixel_type, clip c\n- Trim, AudioTrim: (#274) bool 'cache' (default true) parameter. Lower memory consumption but may be slower\n\nBuild environment, Interface\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n- Fix (#276): C interface Win32 access: add V8 interface function names to avisynth.def to have undecorated function names\n\nBugfixes\n~~~~~~~~\n- Fix deadlock in GetFrame and Invoke (AvsPMod use case)\n- Fix Histogram AudioLevels half character upshift (regression since v3.6)\n- Fix (#255) Overlay \"blend\": using accurate formula with internal float calculation. (Issue #255)\n- Fix (#263). Escaping double-quotes in 'e' string results in error\n- Fix: Expr LUT operation Access Violation on x86 + AVX2 due to an unaligned internal buffer\n- Fix: Chroma full scale as ITU Rec H.273 (e.g +/-127.5 and not +/-127) in internal converters, ColorYUV and Histogram\n- Fix (#257): GreyScale to not convert to limited range when input is RGB. (regression in 3.7.1)\n  GreyScale accepts only matrix names of limited range as it is put in the documentation.\n- Fix (#256): ColorYUV(analyse=true) to not set _ColorRange property to \"full\" if input has no such property and range cannot be 100% surely established.\n- Fix: Histogram \"color\" may crash on certain dimensions for subsampled formats. Regression since 20180301 r2632.\n- Fix: Histogram \"color\" and \"color2\" mode check and give error on Planar RGB\n- Fix: missing Histogram \"color2\" CCIR rectangle top and bottom line (black on black). Regression since 3.6.2-test1\n- Fix: Compare support 10-14 bits \n- Fix: Compare 'channels' parameter default to \"Y\" when input is greyscale;\n- Histogram \"Audiolevels\" and StereoOverlay to deny planar RGB\n- Fix: Histogram \"Levels\": prevent crash when factor=0.0\n- Fix: Histogram \"Levels\": fix regression incorrect \"factor\" applied for U/V part drawing when format was subsampled (non-444). Regression since 20160916 r2666\n- Expr: \"scale_inputs\" values to case insensitive and add \"floatUV\" to error message as an allowed value.\n\nOptimizations\n~~~~~~~~~~~~~\n- ConvertBits: no compulsory get frame #0 in constructor for frame properties if 'fulls' is directly specified\n\n\nPlease report bugs at `github AviSynthPlus page`_ - or - `Doom9's AviSynth+\nforum`_\n\n$Date: 2022/03/17 0:0:0 $\n\n.. _github AviSynthPlus page:\n    https://github.com/AviSynth/AviSynthPlus\n.. _Doom9's AviSynth+ forum:\n    https://forum.doom9.org/showthread.php?t=181351\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/changelist373.rst",
    "content": "\nChanges from 3.7.2 to 3.7.3\n---------------------------\n\nAdditions, changes\n~~~~~~~~~~~~~~~~~~\n- MIPS build support\n- New: add a sixth array element to ``PlaneMinMaxStats``: average. Defines variable \"PlaneStats_average\" as well if setting variables is required.\n- \"Text\" ``halo_color`` allows to have both halo and shaded background when halo_color MSB=$FE\n- \"Text\" (#308) much nicer rendering of subsampled formats\n- \"Text\" (#310) Support any width of external bdf fonts (but still of fixed width)\n- \"Text\" (#310) Support more from the BDF standard: per-character boundary boxes and shifts\n- \"Text\": draw rightmost on-screen character even if only partially visible (was: not drawn at all)\n- \"Text\" Halo is not limited to original character matrix boundaries and is rendered on the displayed string as a whole.\n- \"Text\" add \"left\" chroma placement support; new ``placement`` parameter (left, center, auto), accept frame property ``_ChromaLocation`` hint\n- \"TimeStretch\" (#278) add TimeStretch overload with rational pair arguments and update SoundTouch library to v2.3.1.\n- Enhancement (#315): Show exception message as well if a v2.6-style plugin throws AvisynthError in its ``AvisynthPluginInit3`` instead of only \"'xy.dll' cannot be used as a plugin for AviSynth.\"\n- Fix (#327) Histogram \"color2\" markers. Fix right shifted 15 degree dots, fix square for bits>8\n- Feature #337: add more resizers\n\n  - filters: SinPowerResize, SincLin2Resize, UserDefined2Resize\n  - and their equivalent for the ConvertToXXXX family 'chromaresample': \"sinpow\",  \"sinclin2\" and \"userdefined2\"\n\n- Feature #337: add \"param1\", \"param2\" and \"param3\" to ConvertToXXXX where 'chromaresample' exists (b,c,s,taps and p parameters can be set, depending on the resizer).\n- #306: Add ConvertToYUVA420, ConvertToYUVA422 and ConvertToYUVA444\n- Expr: Add remaining stack element count to \"Unbalanced stack...\" error message\n- Add back audio cache from classic Avisynth 2.6. Handle modes and hints on cache audio:\n  CACHE_AUDIO, CACHE_AUDIO_NOTHING, CACHE_AUDIO_AUTO_START_OFF, CACHE_AUDIO_AUTO_START_ON,\n  CACHE_GETCHILD_AUDIO_MODE and CACHE_GETCHILD_AUDIO_SIZE\n- Set automatic MT mode MT_SERIALIZED to ConvertToMono, EnsureVBRMP3Sync, MergeChannels, GetChannel, Normalize, MixAudio, ResampleAudio\n- Alter default VfW export (e.g. VirtualDub2) channel layout mask for 3 channels (Surround to 2.1), 4 channels (Quad to 4.0) and 6 channels (6.1(back) to 6.1)\n- Add audio channel (speaker layout) support\n\n  - Implemented by using 20 bits from VideoInfo struct image_type flag\n  - Follow layout definition from WAVEFORMATEXTENSIBLE\n  - Add Script functions for audio layout support:\n\n    - bool IsChannelMaskKnown(clip)\n    - int GetChannelMask(clip)\n    - SetChannelMask(clip, bool known, int dwChannelMask)\n    - SetChannelMask(clip, string ChannelDescriptor)\n\n  - Add friendly names for the 18 speaker positions (e.g. \"FL\" for front left)\n  - Add friendly names for their frequently used combinations (e.g. \"stereo\" for \"FL+FR\")\n    to be used in SetChannelMask.\n\n  - GetChannel, GetChannels, MergeChannels: set default channel layout if channel count is 1 to 8\n  - ConvertToMono, GetLeftChannel, GetRightChannel: sets channel layout to \"mono\"\n  - AudioDub will inherit channel layout setting from the audio clip.\n  - KillAudio calls SetChannelMask(false, 0)\n  - \"Info\": displays channel mask info in the audio section when exists\n  - #358: add \"bold\" parameter to \"SubTitle\" and \"Info\"\n  - Add \"bold\", \"italic\", \"noaa\" parameters for SubTitle, Info, ShopSMTPE, ShowTime, ShowFrameNumbers, ShowCRC32\n\nBuild environment, Interface\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n- Feature (#317): (v10) The color format of a ``VideoFrame`` can now be retrieved with its ``GetPixelType()`` (CPP) and ``avs_video_frame_get_pixel_type`` (C)\n  function. Before, there was no reliable way of knowing it on a frame from ``propGetFrame()``.\n  The internally stored ``pixel_type`` in ``VideoFrame`` is properly converted upon a ``Subframe`` (Y8-32), ``SubframePlanar`` (strip alpha).\n- Feature (#317): (v10) added ``VideoFrame::AmendPixelType`` and ``avs_video_frame_amend_pixel_type``.\n  Introduced in order to keep ``VideoInfo`` and ``VideoFrame`` ``pixel_type`` synchronized for special cases:\n  when filter constructor would just change ``VideoInfo::pixel_type``, but the frame would be passed w/o any change, like in ``ConvertFromDoubleWidth`` or ``CombinePlanes``.\n- Feature (#314): Added ``AVSValue::GetType()`` (v10)\n  Returns an ``AvsValueType`` enum directly, one can use it instead of calling all IsXXX functions to establish the type. (Rust use case)\n- Fix in headers (#314): Changed ``NewVideoFrameP()`` and ``avs_new_video_frame_p()`` property source argument to const\n- Enhancement in headers (#314): Made ``VideoFrameBuffer`` destructor public like in other classes of the public API to prevent compiler errors downstream when calling non-const member functions\n- Address Issue #305: Support for non-decorated ``avisynth_c_plugin_init`` in C-plugins\n- Fix: C API undefined behavior when upstream throw runtime error\n- CMakeLists.txt: fix clang-cl/intel with ninja generator\n- Fix: C interface crash when using avs_new_video_frame_p(_a)\n- Fix: C interface avs_prop_get_data behave like C++ counterpart. Interface version is dor this fix is 9.2\n- CMakeLists.txt: add support for Intel C++ Compiler 2022\n- CMakeLists.txt: add support for Intel C++ Compiler 2023\n- Bump Interface version. Interface version is 10.0\n  AVISYNTH_INTERFACE_VERSION = 10,\n  AVISYNTHPLUS_INTERFACE_BUGFIX_VERSION = 0\n- Address #282: make 32-bit MSVC build to generate both decorated and undecorated export function names for C plugins\n- (v10) Add audio channel support to C++ interface by using 18+2 VideoInfo.image_type bits\n\n  - Check for existence: bool VideoInfo::IsChannelMaskKnown()\n  - Setting: void VideoInfo::SetChannelMask(bool isChannelMaskKnown, unsigned int dwChannelMask)\n  - Retrieving: unsigned int VideoInfo::GetChannelMask()\n  - enums AvsChannelMask and AvsImageTypeFlags \n\n- (v10) Add audio channel support to C interface\n\n  - Check for existence: bool avs_is_channel_mask_known(const AVS_VideoInfo * p);\n  - Setting: void avs_set_channel_mask(const AVS_VideoInfo * p, bool isChannelMaskKnown, unsigned int dwChannelMask);\n  - Retrieving: unsigned int avs_get_channel_mask(const AVS_VideoInfo * p);\n  - supporting enums\n\n\n\nBugfixes\n~~~~~~~~\n- Fix: \"Text\" filter negative x or y coordinates (e.g. 0 instead of -1)\n- Fix: \"Text\" filter would omit last character when x<0\n- Fix: \"Text\" ``halo_color`` needs only MSB=$FF and not the exact $FF000000 constant for background fade\n- Fix: (#304) \"ColorYUV\" analyze=true was displaying wrong min-max values for YUY2\n- Fix: (#293) \"Text\" to throw proper error message if the specified font name (e.g. Arial) is not found among internal bitmap fonts.\n- Fix: (#293) \"Subtitle\" and \"Text\" filter to respect the explicitely given coorditanes for y=-1 or x=-1, \n  instead of applying vertical/horizontal center alignment.\n- Fix (#283): broken runtime functions Min/Max/MinMaxDifference when threshold is not 0 (returned -1). Regression in 3.7.2\n- Fix (#282): ConvertToRGB\n  - do check for exact 8 or 16 bit input, because packed RGB formats exist only for 8 and 16 bits\n  - keep alpha for RGBA planar - convert RGBAP8/16 to RGB32/64, while RGBP8/16 is still RGB24/48\n- Fix crash when outputting VfW (e.g. VirtualDub) for YUV422P16, or P10 in Intel SSE2 clang builds\n- Fix Clang build AviSource crash on yuv422p10le UTVideo at specific widths (SSE2 or SSE4.1)\n- Fix: (#340): stop memory leak on propSet / MakePropertyWritable\n- Fix: (#347): possible crash of LLVM builds (clang-cl, Intel NextGen) on pre-AVX (SSE4-only) CPUs.\n- Fix: (#348): bitrol/bitror script functions return incorrect results when argument is negative (regression since ported from Avisynth 2.6 to plus)\n- Fix: (#350): ConvertXXX to accept YV411 clip's frame property _ChromaLocation set to 'left','topleft' and 'bottomleft' instead of giving an error message.\n- Fix: (#360): plane filler wrongly assumed that pitch is rowsize, would crash when aligned Crop was immediately followed by a GreyScale.\n\n\nOptimizations\n~~~~~~~~~~~~~\n- Enhanced performance in ConvertBits Floyd dither (dither=1) for 10->8, 16->8 and 16->10\n- Added AVX2 code path for YV24 to RGB24/32 conversions (+50% fps)\n\nDocumentation\n~~~~~~~~~~~~~\n- Internal plugins, syntax, ...: almost fully revised and made up-to-date. Big thanks to Reel-Deal!\n- Update build documentation with 2023 Intel C++ tools. See Compiling Avisynth+ \n\n\nPlease report bugs at `github AviSynthPlus page`_ - or - `Doom9's AviSynth+\nforum`_\n\n$Date: 2023/06/08 11:02:00 $\n\n.. _github AviSynthPlus page:\n    https://github.com/AviSynth/AviSynthPlus\n.. _Doom9's AviSynth+ forum:\n    https://forum.doom9.org/showthread.php?t=181351\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/changelist374.rst",
    "content": "Changes from 3.7.3 to 3.7.4\n---------------------------\n\nAdditions, changes\n~~~~~~~~~~~~~~~~~~\n- Bump year to 2025\n- AddBorders and LetterBox: add transient filtering See :doc:`AddBorders <corefilters/addborders>`.\n- new filter: MultiOverlay. Bulk copy-paste from clips. See :doc:`MultiOverlay <corefilters/multioverlay>`.\n- Animate: Custom function option. See :doc:`Animate <corefilters/animate>`.\n- Animate: more precise granularity for integer interpolation, allow 64 bit input\n- Animate: add proper rounding for integer interpolation\n- Resizers: add \"force\" integer parameter to force the resizing process even if Avisynth decides it is not needed\n- Resizers: respect _ChromaLocation, and \"placement\" parameter which to adjust chroma locations during resizing\n- Resizers: add \"keep_center\" parameter to disable pixel center position adjustments\n- Resizers: allow arbitrary dimensions; the filter \"support\" size does not limit usability, no more\n  \"image height is too small for this resizing method\"-like error messages.\n- GaussResize: add \"b\" and \"s\" parameters See :doc:`Resize Filters <corefilters/resize>`.\n- DirectShowSource new parameter ``utf8`` for utf8 filename support\n- \"propShow\" ``font``, ``text_color``, ``halo_color``, ``bold`` new parameters for custom style.\n- \"propShow\" (#366): ``x``, ``y``, ``align`` new parameters for custom positioning.\n- \"propShow\" ``props`` new parameter for filtering the name of property list with wildcard and regex support.\n\n  See :doc:`propShow <corefilters/propShow>`.\n- \"propDelete\" and \"propCopy\": ``props`` accepts wildcard and regex for filtering the name of property list.\n\n  See :doc:`Internal functions: frame properties <syntax/syntax_internal_functions_frame_properties>`.\n- \"Info\": ``cpu`` new parameter to disable showing CPU capabilities\n- \"Info\" (#366): ``x``, ``y``, ``align`` new parameters for custom positioning\n- Fix #368 Make proper vertical alignment for multiline text in Subtitle and Text \n  when vertical alignment is set to bottom or center.\n- Studio RGB (narrow, limited) range will now be recognized (through _ColorRange=1)\n  and utilized in conversions to and from RGB, such as in GreyScale, ConvertToY, ConvertToYUVxxx,\n  or ConvertToRGB32 with PC.xxx matrix which now keeps the limited/narrow-rangeness of the source. \n  See also BugFix section.\n- #392 \"break\" and \"continue\" in for-next and while loops\n- Add \"ArraySort\" for sorting simple bool, numeric or string arrays\n- SoundTouch: Increased the max number of channels to 32ch from the old limit of 16ch.\n- Posix: Detect additional plugindirs from LD_LIBRARY_PATH environment variable\n- #413 Add ListAutoloadDirs() script function returing a LF delimited string with directory list.\n- SubTitle to accept real LF (``\\r``) or CR LF (``\\r\\n``) control characters for line break.\n- #422 Give meaningful and stopping error message when a bad C++ plugin is throwing exception \n  during autoload (e.g. wrong function signatures, crash because of using unsupported interface calls). \n  This kind of loading error is treated similarly fatal like mixing 32 and 64 bit plugins.\n- #413 Add 64 bit data types (https://github.com/AviSynth/AviSynthPlus/issues/423)\n  \n  - (technical) Value (AVSValue) types ``i`` and ``f`` are kept and still mean 32 bit integer and float values.\n  - (technical) New value types ``l`` and ``d`` added to mark 64 bit integer and double types.\n  - Integer decimal constants are automatically promoted to long (int64_t) if they do not fit into integer.\n    Integer decimal constants are automatically promoted to 64 bit double if they do not even fit into a 64 bit long.\n    (But values stored as 'only' integers behave as 64 bit long in math operations).\n  - New syntax element ``L`` (or ``l``) suffix for hexadecimal constants for interpreting 64 bit data (``$800000001010L``)\n    Hexadecimal literals without L suffix still remain 32 bit integers. This ensures compatibility so that \n    color constants exceeding $7FFFFFFF (such as $FFFFFFFF) are still interpreted as 32-bit \n    integers and not as 64-bit long integers.\n  - Floating point constants (literals) stored as 64 bit double (formerly only with 32 bit float precision)\n  - ``IsInt()`` returns true for any 32 or 64 bit integer\n  - ``IsLongStrict()`` returns true only if underlying variable is long (64 bit integer)\n  - ``IsFloat()`` returns true for any 32 or 64 bit floating point content (float or double and for any integers - as before)\n  - ``IsFloatfStrict()`` returns true only if value is exactly a 32 bit single-precision float.\n  - ``Float()`` by default casts to double, but 32-bit floating point numbers are kept in 32-bit float format \n    (no automatic float-to-double conversion).\n  - New ``Double()`` converts always to 64 bit double\n  - New ``Floatf()`` converts always to 32 bit float\n  - New ``Long()`` converts always to 64 bit long\n  - New ``IntI()`` converts always to 32 bit integer\n  - Function ``Pi`` returns real double precision constant.\n  - ``VersionNumber()`` still returns a 32-bit float, but the exact value is adjusted slightly for compatibility \n    reasons. This is because the script constant 2.6 is now stored in 64-bit double precision, which can cause issues when \n    compared to a 32-bit float version of 2.6. For example, to ensure 2.6 (double) >= 2.6f (float) and \n    avoid breaking scripts that contain ``IsAvs26 = VersionNumber() >= 2.6`` .\n  - Floating point mathematical functions (``Sin``, etc..) return double precision results.\n  - Floating point arithmetic (addition, subtraction, multiplication, division) uses double precision, except when both operands\n    are 32-bit floats, in which case the result is also a 32-bit float. \n    (32-bit float / 32-bit float results in a 32-bit float)\n  - Integer mathematical operation operate on 64 bit data. \n    When result is within a 32 bit integer range, it is stored as 32 bit integer internally, which is \n    automatically promoted to 64 bit long if needed.\n  - ``For``-loops are using 64 bit integer for initial value, step and end-value.\n  - ``Animate``: using 64 bit precision inside.\n  - ``Bit-related`` functions now have distinctly named 64-bit integer versions, while the old ones continue to work with plain 32-bit integers.\n  \n    - ``BitAnd64``, ``BitNot64``, ``BitOr64``, ``BitXor64``,\n    - ``bitshl64``, ``bitsal64``: shift left (providing two versions; though arithmetic and logical is the same)\n    - ``bitshr64``, ``bitsar64``: shift right logical and arithmetic\n    - ``bitrol64``, ``bitror64``: 64 bit rotation left and right\n    - ``BitChg64``, ``BitClr64``, ``BitSet64``, ``BitTst64``, change, clear, set, test\n    - ``bitsetcount64`` counts the set bits (or sum of set bits) of one or more parameter values.\n  - New: ``HexValue64()`` for 64-bit long result. The original ``HexValue()`` keeps returning 32 bit integer \n    so ``HexValue(\"FFFFFFFF\")`` is still ``-1``, but ``HexValue64(\"FFFFFFFF\")`` will be ``4294967295`` (64 bit number)\n  - Integer and float frame property read and writes work on real 64 bit integers and doubles.\n  - Formatting functions (``String()``, etc.) to 64 bit data type aware.\n  - ``AudioLength()`` now returns 64 bit integer\n  - ``AudioLengthF()`` returns data to double instead of 32 bit float (though it's now useless and still can lose precision).\n  - Function parameter types (function signature) keep ``i`` and ``f``, but accept 64 bit long and double\n    precision parameters transparently.\n  - String length can exceed the value of a 32 bit int. ``StrLen()`` returns long if int cannot hold the length.\n    ``LeftStr``, ``RightStr``, ``MidStr`` length parameters accept 64 bit long values.\n  - Compatibility: 64 bit parameter values are automatically replaced with 32 bit int and 32 bit float if Avisynth 2.5 or \n    old (pre-V11, non-64-bit aware) C interface is detected. Such plugins will see the good old 32 bit data.\n  - Backport the frame property changes from VapourSynth API4\n\n    - new saturated frame property getters on API returning only 32 bit data: ``propGetIntSaturated`` and ``propGetFloatSaturated``\n    - A frame property with ``data`` type can hold a string or real binary data.\n      To distinguish between the two kinds, a hint can be set with a new API version of ``propSetDataH``, which helps visualizing and later: exporting.\n    - ``propShow`` displays binary buffer instead of string if the internal subtype is set to ``Binary``.\n      The buffer length and the first (up to) 16 bytes are displayed like this: ``Binary data. Length= xx [00,01,DD, ...]``\n      A string content is displayed otherwise.\n    - Since ``propSet`` script function in Avisynth is string-only, it sets the hint to ``DATATYPEHINT_UTF8`` \n      (utf8 just hinting that this is a string)\n\n- WinInstaller: add InnoSetup script for Windows on ARM\n- buildsystem: restrict use of MSVC to x86(-64) only\n- avs/config.h: add defines to separate X86 and ARM Windows variants\n- PluginManager: only enable +GCC plugindir registry entries on X86\n- PluginManager: indent cosmetics for clarity\n- Restore AVS_VERSION define\n\n\nBuild environment, Interface\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n- add LOONGARCH support\n- Use system installs of DevIL and SoundTouch on all platforms, remove in-tree binaries/code\n- avisynth.h: add ListAutoloadDirs() to internal interface declarations\n- CMakeList.txt to accept Intel C++ Compiler 2025\n- V11 interface: new 64 bit related AVSValue get and set function in C++ and C interface.\n- V11 interface: C Interface: implement API for all getter/setter/typecheck for AVS_Value\n- V11 interface: C interface supports Avisynth+ deep-copy dynamic arrays.\n- Added optional C plugin init function: to enable full 64 bit data to C plugins, they should implement ``avisynth_c_plugin_init2``.\n- V11: C interface add ``avs_add_function_r`` as an alternative to ``avs_add_function``, allowing the callback \n  to return the result via a by-reference AVS_Value parameter instead of returning the AVS_Value as a struct. (Use case from Python)\n  See :ref:`c_avs_add_function_r`\n- V11 interface: add saturated int (int64->int) and float (double->float) frame property reading function to \n  IScriptInterface: ``propGetIntSaturated``, ``propGetFloatSaturated``\n  and ``prop_get_int_saturated``, ``prop_get_float_saturated`` to C interface, like in VapourSynth API 4.\n- V11 interface: \"hint\" to buffer/string frame properties, like in Vapoursynth API 4.\n  IScriptInterface: ``propGetDataTypeHint``, ``propSetDataH``.\n  C interface: ``avs_prop_get_data_type_hint``, ``avs_prop_set_data_h``.\n  Equivalent functions: ``VSAPI4.mapGetDataTypeHint`` = ``Avisynth.propGetDataTypeHint``, \n  ``VSAPI4.mapSetData`` = ``Avisynth.propSetDataH``,\n  ``VSAPI4.mapSetData3`` = ``Avisynth.propSetData``.\n- V11: New enum in headers: ``AVSPropDataTypeHint`` (VSAPI4: VSDataTypeHint)\n\n- Background modification: ``env->SaveString`` can store longer strings than ``INT_MAX`` if ``len`` is ``-1`` (autodetect length by null termination).\n  Even on 32 bit systems ``size_t`` can exceed ``INT_MAX``. (nevertheless, the length parameter - when is given - is still int type)\n- Shibatch: check for GCC or Clang for MulDiv under MinGW\n- plugins/CMakeLists.txt: restrict VDubFilter to x86(-64)\n- plugin/CMakeLists: add CMake detection fallback for SoundTouch\n- CMakeLists.txt: use extended policy version requirements\n\nBugfixes\n~~~~~~~~\n- Fix ConvertBits C 16->8 bit (x+round, then bitshift) which turned 0xFFFF into 256 which is 0 (wrong)\n- Fix ConvertToRGB48/64 debug assert which passed less than adequate parameters to an internal PlanarRGb converter\n- Fix: Resizers chroma shift if not chroma is not center-positioned (respect _ChromaLocation, and \"placement\" parameter)\n- Fix #429 CPU-CUDA transfer would copy less bytes than vfb data_size\n- Fix: ScriptClip and other runtime functions / frame prop read would crash if called from Avs2.5 or Pre-v11 C \n  IScriptEnvironment, which would happen is there is an old C plugin within ScriptClip\n  The C part was an intermediate development issue, but for Avs 2.5 plugins probably it always crashed.\n- Fix: audio cache would overflow over int sized count and position differences\n- Fix: \"Info\" overflowed and displayed negative hours/minutes/audio length at longer clips, use int64\n- Fix \"SetLogParams\" defaults - mentioned in #391\n- Fix corrupt Turn functions when a planar RGB turn would be followed by a YUV Turn.\n  Regression since TurnXXXX supports planar RGB (2016.08.23; probably since r2081 commit dba954e2de0c9c6218d17fc5c4974f4c28b627c3)\n- Fix #386: Interleave to call plugin destructor like StackXXXX (memory leak in case of script errors)\n  additional code reorg in r4192\n- Fix #384: swapped ShowGreen/ShowBlue for planar RGB sources\n- Fix: allow use of \"local\" in ConditionalSelect string version (fixed wrong function signature)\n- \"Info\" now can display a line which is only partially visible (instead of not showing it at all)\n- \"Text\" use \"lsp\" parameter the same way as in SubTitle: in 1/8 pixel units, not in 1 pixels.\n- \"Text\" vertical alignment position would be wrong for multiline strings containing even number of lines.\n- Fix #365: Avisynth 2.5 plugins when NICE_FILTER would crash with \"invalid response to CACHE_GETCHILD_AUDIO_MODE\".\n  Regression in 3.7.3 reintroduced audio cache.\n- Fix #370: array size assert error in ConvertToYUY2 when internally ConvertToYUV422 is called\n- Leave _ColorRange frame property as-is, when using matrix names \"PC.709\" or \"PC.601\", for example in ConvertToRGB32.\n  This, along with narrow-range RGB support, also fixes an old glitch, when a limited range YUV Source \n  (like ColorBarsHD) would be converted to a full-range RGB (RGBs were assumed full range).\n- Narrow-range RGB support fixes the minor +/-1 bit error in YUV to RGB (and back) matrix conversions \n  for such RGB sources and targets. This error would accumulate if conversions were applied consecutively \n  or mixed with other external conversions.\n\n- Fix FadeIn, which behaved like FadeIn2\n- Fix #418: ShowSMTPE/ShowTime alignment - NO_WIN_GDI case (e.g. Posix)\n- Fix #421: add safety checks to SuperEQ to match SSRC\n- Fix #426: An autoloaded function with multiple parameter versions would produce a named parameter error \n  if unnamed parameters were given before the named parameter. For example: TimeStretch(a_clip, rate=100.1)\n\nOptimizations\n~~~~~~~~~~~~~\n- avoid storing duplicated strings in internal string heap (related to issue #389)\n- Expr: rewritten the C (non-Intel-JIT) path to support vectorization, if the compiler is capable.\n  Useful for non-Intel platforms where the (Intel SSE2-AVX2) JIT compiler does not work.\n  Expect 3-20x speedup compared to the old method.\n- Expr: implement ``tan`` in JITasm. Expect ~6-15x speed up for an expression like \"sxr 2 * 1 - 3.14159254 * 1 * tan 10 * 128 +\"\n- Resizers C implementation: more vectorizer compiler friendly code (1.5 - 2.5 speed, still slooow)\n- Quicker SSE2 horizontal and vertical resizer\n- [Un-optimization]: minor speed decrease in other resizers' performance, due to healing a hidden \n  possibility which would allow over-addressing the scan-lines and frame buffer. No wonder the old\n  code, which checked nothing, did well. IMHO the code is still quick.\n\nDocumentation\n~~~~~~~~~~~~~\n- Correct building DirectShowSource prerequisites (Release_MBCS)\n- Update \"DirectShowSource\" with utf8 parameter\n- Update \"Info\"\n- Update rst docs with control structs if/else/for/while\n- Update \"ShowTime\", \"ShowSMPTE\", \"ShowFrameNumber\" section with 3.7.3 changes\n- Update most items at Syntax and internal functions sections, add arrays, function objects, \n  escaped string literals, multithreading, frame properties, debug functions\n- Add if-else, do-while, for-next, break and continue\n- Update Import (add utf8)\n- update Conditional filters, Runtime functions\n- update ShowAlpha/Red/...\n- Update Intel 2024 compiler build process\n- Add autoload helper functions to rst docs, update content and bring syntax_plugins.rst to new format\n- update compile_avsplus.rst online docs with Intel C++ Compiler 2025\n- Interface V11 changes: see :ref:`api_v11_whats_new` for more details.\n- Document 64 bit capable functions and changes in old ones in millions of other rst pages.\n- Document C interface (in progress)\n- Revamped resizer section :doc:`Resize filters <corefilters/resize>`\n- Add instructions for building or using external system installs of SoundTouch and DevIL\n- and so on...\n\nPlease report bugs at `github AviSynthPlus page`_ - or - `Doom9's AviSynth+\nforum`_\n\n$Date: 2025/03/14 14:09:00 $\n\n.. _github AviSynthPlus page:\n    https://github.com/AviSynth/AviSynthPlus\n.. _Doom9's AviSynth+ forum:\n    https://forum.doom9.org/showthread.php?t=181351\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/changelist375.rst",
    "content": "Changes from 3.7.4 to 3.7.5\n---------------------------\n\nAdditions, changes\n~~~~~~~~~~~~~~~~~~\n\nBuild environment, Interface\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n- Fix AVS_Value 64 bit data member declaration for non Intel (X86_X64) systems.\n- v11.1: Bumped the bugfix-interface-version number from 0 to 1.\n- CMakeLists.txt: use Release for single-configuration targets if CMAKE_BUILD_TYPE isn't set\n\nBugfixes\n~~~~~~~~\n- Fix #434: YtoUV crash, regression in 3.7.4 (since commit 61d2c9a)\n- Fix: crash in (Horizontal) resizers on non-Intel (e.g. aarch64) platforms\n\nOptimizations\n~~~~~~~~~~~~~\n- (preliminary) convert source of C only horizontal and vertical resizers to \n  auto-vectorize compiler friendly (e.g. quicker on aarch64 until neon is supported)\n\nDocumentation\n~~~~~~~~~~~~~\n\n\n\nPlease report bugs at `github AviSynthPlus page`_ - or - `Doom9's AviSynth+\nforum`_\n\n$Date: 2025/04/14 14:10:00 $\n\n.. _github AviSynthPlus page:\n    https://github.com/AviSynth/AviSynthPlus\n.. _Doom9's AviSynth+ forum:\n    https://forum.doom9.org/showthread.php?t=181351\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/changelist376.rst",
    "content": "Changes from 3.7.5 to 3.7.6\n---------------------------\n\nAdditions, changes\n~~~~~~~~~~~~~~~~~~\n- Added ``SetFilterProp``, ``GetFilterProps``, and ``SetFilterPropPassthrough``:\n\n  * ``SetFilterProp`` — automatically inject a frame property on the output of a named filter\n    every time it is instantiated, without modifying the script.  Rules are typically placed in\n    an auto-loaded ``.avsi`` file.  The property value may be a static int/float/string, a\n    function object evaluated per frame (e.g. to derive ``_Matrix`` from output resolution), or\n    captured from the filter's own call argument (``undefined()`` capture mode).\n  * ``SetFilterProp`` conditional form — inject a property only when a specific named call\n    argument equals a given match value or any element of an alias array.  String comparison is\n    case-insensitive.  Both positional and named call sites are matched.\n  * ``SetFilterPropPassthrough`` — compatibility shim for old filters that predate frame-property\n    support (e.g. ``ColorMatrix``).  Copies all input frame properties to the filter's output;\n    self-healing: becomes a no-op per frame once the plugin is updated to use ``NewVideoFrameP``.\n  * ``GetFilterProps`` — returns the registered rule table as a JSON string for diagnostics.\n\n  Addresses `issue #393 <https://github.com/AviSynth/AviSynthPlus/issues/393>`_ and more.\n  See :doc:`SetFilterProp <./corefilters/setfilterprop>`.\n- Bump year to 2026\n- Overlay: \"add\" and \"subtract\" direct RGB mode\n- Overlay: \"add\" and \"subtract\" supports 32-bit float.\n- Added utf8 parameter to AddAutoLoadDir\n- Added utf8 parameter to ListAutoLoadDirs\n- Added utf8 parameter to LoadPlugin\n- Added utf8 parameter to DumpFilterGraph\n- \"Info\": Optimize AVX512 features display, group features, make a bit more compact\n- \"Info\": add L2 cache size display\n- \"SetMaxCPU\": add \"avx512base\" and \"avx512fast\" options to enable/disable AVX512 grouped features.\n  see :ref:`SetMaxCPU <setmaxcpu>` . Users of base-only AVX512 CPUs can enable Avisynth-optimizations\n  with SetMaxCPU(\"avx512base+\").\n- ARM64 (aarch64) area:\n\n  * \"Info\": add ARMV8-A features display (NEON, DOTPROD, SVE2)\n\n  * Add ArmV8-A cpu feature detection (NEON, DOTPROD, SVE2) on ARM64 Windows/Linux/macOS builds.\n    On Windows, only up-to DOTPROD can be detected due to OS limitations.\n  * New CPU flags in ``cpuid.h`` and ``avisynth_c.h``: CPUF_ARM_NEON, CPUF_ARM_DOTPROD, CPUF_ARM_SVE2\n  * \"SetMaxCPU\": add \"neon\", \"dotprod\", \"sve2\" options to enable/disable ARM64 (aarch64) features.\n- \"ConvertToPlanarRGB(A)\": ``bits`` parameter: on-the-fly bit-depth conversions to YUV->RGB conversion.\n  See :doc:`ConvertToPlanarRGB <./corefilters/convert>`.\n- ``ConvertToPlanarRGB(A)``: added ``quality`` parameter: forces 32-bit float\n  internal processing instead of S18.13 fixed-point arithmetic when converting\n  from YUV, regardless of source or target bit-depth. See :doc:`ConvertToPlanarRGB <./corefilters/convert>`.\n- \"ConvertToYUV(A)xxx\" and legacy 8 bit name versions: ``bits`` parameter: on-the-fly bit-depth conversions to RGB->YUV conversion.\n  See :doc:`ConvertToYUV444 <./corefilters/convert>`.\n- ``ConvertToYUV(A)xxx`` and legacy 8 bit name versions: added ``quality`` parameter: forces 32-bit float\n  internal processing instead of S18.13 fixed-point arithmetic when converting\n  to YUV, regardless of source or target bit-depth. See :doc:`ConvertToYUV444 <./corefilters/convert>`.\n- \"ResetMask\": add parameter float \"opacity\"\n- \"AddAlphaPlane\": add parameter float \"opacity\"\n- \"Layer\": YUY2 is handled as YV16 (lessen source code bloat)\n- \"Histogram\" Color and Color2 mode additions and fixes:\n\n  * Added ``matrix`` parameter (Color and Color2): specifies the YUV matrix for\n    chroma interpretation (BT.601, BT.709, BT.2020, etc.), following the same\n    convention as the ``ConvertToYUV`` family. If not set, the matrix is\n    read from the clip's ``_Matrix`` and ``_ColorRange`` frame properties.\n  * Added ``graticule`` string parameter (Color and Color2): controls the\n    danger zone shading (Color) or valid chroma boundary square (Color2).\n    ``\"on\"`` (default) always draws it, preserving pre-3.7.6 behavior;\n    ``\"off\"`` never draws it; ``\"auto\"`` draws it only for limited-range\n    clips and suppresses it for full-range clips.\n  * Added ``circle`` parameter (Color and Color2, default false for Color,\n    default true for Color2): draws the hue circle with 15° tick marks.\n    In Color2 mode this was previously always drawn; it can now be disabled.\n  * Added ``targets`` parameter (Color and Color2, default false): draws\n    target boxes at the six 75%-amplitude ColorBars Cb/Cr positions\n    (Yellow, Cyan, Green, Magenta, Red, Blue). Positions are computed from\n    ground-truth linear RGB values through the active matrix, giving\n    accurate coordinates at all bit depths.\n  * Added ``targets100`` parameter (Color and Color2, default false): draws\n    target boxes at the same six ColorBars Cb/Cr positions as ``targets``,\n    but placed at 100% luma level instead of 75%.\n  * Added ``axes`` parameter (Color and Color2, default false): draws\n    horizontal and vertical crosshair lines through the vectorscope center.\n  * Added ``iq`` parameter (Color and Color2, default false): draws target\n    boxes for the NTSC −I, +I and +Q chroma-phase references, using the\n    luma-corrected broadcast convention (Y raised until the most negative\n    RGB component reaches Code 0, avoiding illegal RGB values).\n  * Added ``iq_lines`` parameter (Color and Color2, default false): draws\n    radial lines at the fixed NTSC subcarrier phase angles of 33°, 123°,\n    213° and 303°, marking the I and Q chroma axes.\n  * Fix: \"Color\" and \"Color2\" modes: copy alpha channel from source for\n    alpha-carrying formats (YUVA, RGBPA, RGB32, RGB64); initialize alpha\n    to zero in the histogram panel area.\n  * Fix: accurate pixel positioning and scaling throughout the histogram\n    panel, limited/full range aware. Marker positions use the same\n    conversion path as the vectorscope signal dots, ensuring exact\n    alignment at any bit depth and color range.\n  * Vectorscope is now fully matrix-aware: all overlay marker positions are\n    computed from ground-truth linear RGB values converted through the active\n    YUV matrix, giving accurate Cb/Cr coordinates at all bit depths including\n    32-bit float.\n- \"ConvertToYUY2\": rewritten to route all conversions through YV16 as\n  intermediate format, using the full ``ConvertToPlanarGeneric`` infrastructure.\n  ``ChromaOutPlacement`` parameter added (was missing, present in ConvertToYV16).\n  All source formats (YV12, YUV420/422/444, planar/packed RGB, high bit depth)\n  are now handled correctly. ``bits`` parameter accepted; must be 8 if specified.\n  See :doc:`Convert <./corefilters/convert>`.\n- \"ConvertBackToYUY2\": kept for backward compatibility; now forwards to\n  ``ConvertToYUY2``. The pre-2.5 left-pixel-only chroma hack is no longer\n  needed or applied; the YV16 lossless repack path avoids chroma resampling\n  loss entirely for roundtrip workflows.\n- \"ConvertToYV12\" (legacy 8-bit name): the YUY2 fast-path shortcut is removed;\n  now routes directly through ``ConvertToPlanarGeneric::CreateYUV420``.\n  ``bits=`` parameter semantics corrected: the legacy 8-bit-named functions\n  (``ConvertToYV12``, ``ConvertToYV16``, ``ConvertToYV24``) now check the\n  *target* bit depth rather than the source bit depth, allowing high-depth\n  sources when ``bits=8`` is explicitly specified.\n- 8 bit packed RGB formats are converted to planar RGB before 444 conversion.\n  Stop using direct rgb-yv24 conversions (16 bits were already converted for long time).\n- Add :doc:`ColorBarsUHD <./corefilters/colorbarsuhd>` ITU-R BT.2111-3 (05/2025) with three signal variants:\n  HLG narrow range (mode=0), PQ narrow range (mode=1) and PQ full range (mode=2)\n\n\nBuild environment, Interface\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n- introduce ``AVS_RESTRICT`` to ``avs/config.h`` (compiler invariant c++ ``__restrict``)\n- AVX512: CMake to recognize ``*_avx512b.*`` and ``*_avx512.*`` file pattern, add compiler specific AVX512 \n  compile flags accordingly (AVX512 Base and Ice Lake extensions)\n- AVX512 support by conditional define.\n  Define `INTEL_INTRINSICS_AVX512` if avx512 modules are enabled and compiler supports it.\n  For MSVC,AVX512 support enabled only from MSVC 2019 16.2 (19.22) or newer.\n- add ``.editorconfig``, update .gitignore to include the new .slnx format of Visual Studio 2026\n- v12 interface: Global Lock support (https://github.com/AviSynth/AviSynthPlus/issues/444), \n  mainly for plugins using common fftw3 library:\n\n  * ``env->AcquireGlobalLock``, ``env->ReleaseGlobalLock`` (C++),\n  * ``avs_acquire_global_lock``, ``avs_release_global_lock`` (C)\n\n  see :ref:`global lock support<cplusplus_acquiregloballock>`\n- v12 interface: ApplyMessageEx supporting utf8 parameter.\n  see :ref:`ApplyMessageEx<cplusplus_applymessage>`\n- v12 interface: inform plugins about the effective thread count after Prefetch()\n  via cache hints:\n\n  * ``CachePolicyHint::CACHE_INFORM_NUM_THREADS`` (C++)\n  * ``AVS_CACHE_INFORM_NUM_THREADS`` (C)\n\n  See :ref:`SetCacheHints<cplusplus_setcachehints>` .\n- the internal IScriptEnvironment2 methods AddAutoLoadDir and ListAutoLoadDirs explicitely\n  work in UTF-8.\n- New CPU flags: ``cpuid.h and ``avisynth_c.h``\n  - added AVX512 group feature flags CPUF_AVX512_BASE and CPUF_AVX512_FAST (Ice Lake, usable AVX-512 since that point).\n  - added many new AVX512 individual feature flags\n  - added ARM64 feature flags CPUF_ARM_NEON, CPUF_ARM_DOTPROD, CPUF_ARM_SVE2\n  - CPUF_xxxxx flags are now 64 bit, replace enum with constexpr.\n- CMakeLists.txt: avx512 compile flag support for gcc/clang (\"base\" and \"fast\", latter is Ice Lake-like feature set).\n- V12 interface: ``GetCPUFlagsEx`` returning 64 bit flags (too many AVX512 subfeatures to fit in 32 bit).\n  C interface: ``avs_get_cpu_flags_ex``.\n  see :ref:`GetCPUFlagsEx<cplusplus_getcpuflagsex>` and :ref:`GetCPUFlags<cplusplus_getcpuflags>`\n- V12 interface: L2 cache size query support. New entry in ``AvsEnvProperty``: ``AEP_CACHESIZE_L2`` (C++), \n  ``AVS_AEP_CACHESIZE_L2`` (C) to query L2 cache size in bytes with ``IScriptEnvironment->GetEnvProperty()``. \n  x86/x64 architecture only for now. See :ref:`AvsEnvProperty<cplusplus_getenvproperty>` .\n\n- Refactor CMakeLists.txt: \n\n  * Correct default of ``ENABLE_INTEL_SIMD`` for cross-compiling scenarios (e.g. ``ARM64`` target on ``x86_64`` host)\n    Old logic relied on the host processor: ``${CMAKE_SYSTEM_PROCESSOR}``\n\n  * Add back option to compile ``ARM64`` builds with Visual Studio on Windows. On VS2026 even clangcl (LLVM) is supported \n    out-of-box for ARM64 platform, in an easily cross-compilable way from an x64 machine.\n  * VDubFilter: allow building on Windows only x86/x64 targets (and not for ARM64).\n  * Fix LLVM/clangcl/Intel ICX compile warning: ``'WIN32' macro redefined as \"#define WIN32 /D_WINDOWS /W3 /GR /EHsc 1 \"``,\n    when CMake injects a command-line macro wrongly and thus redefines WIN32 .\n    The fix: converts global ``add_definitions(\"/D ...\")`` and other option string magics into per-target ``target_compile_definitions()``\n    and ``target_compile_options()``. Thus removing the accidental injection of ``${CMAKE_CXX_FLAGS}`` \n    into ``add_compile_options()``, and prevents the WIN32 macro redefinition.\n\n\nBugfixes\n~~~~~~~~\n- Fix: \"ConvertToYUY2\" / \"ConvertToYV12\": YV12<->YUY2 interlaced conversion\n  used asymmetric 0.75/0.25 chroma interpolation coefficients instead of the\n  MPEG-2 specified 7/8,1/8 and 3/8,5/8 coefficients, introducing opposite-\n  direction vertical chroma shifts in top and bottom fields. First diagnosed\n  by Gavino in 2009; now resolved by routing through ``ConvertToPlanarGeneric``.\n- Fix: \"ConvertToYUY2\" / \"ConvertToYV12\": progressive YV12<->YUY2 conversion\n  used asymmetric 0.75/0.25 averaging (quarter-pixel offset) instead of the\n  correct 0.5/0.5 midpoint average for left-sited chroma, introducing a\n  1/4-pixel vertical chroma shift.\n- Fix: \"ConvertToYUY2\": ``_ChromaLocation``, ``_Matrix`` and ``_ColorRange``\n  frame properties were not read from YV12 source frames and not written to\n  YUY2 output frames in the legacy direct conversion path.\n- Fix: \"ConvertToYUY2\": SSE2 interlaced upsampling used wrong weighting\n  direction for the lower line of each field pair (75%/25% toward current\n  instead of 25%/75% toward next), differing from the C reference implementation.\n- Fix: memory leak and stability issue in frame recycling for static-frame sources (ColorBars, BlankClip):\n  subframes created by Subframe/MakePropertyWritable accumulated without bound in permanently-live\n  VFB buckets, and a race in frame property cleanup could cause access violations under multi-threaded use.\n- Fix: LruCache self-tuning cache resize: raised the ghost-hit threshold from ``ghosted > 0`` to\n  ``ghosted > 1``, preventing unbounded cache growth during backward seeking (Issue #379) and\n  Bob()/SeparateFields access patterns (Issue #270). Frames evicted only once no longer trigger\n  a resize; an undersized cache still grows once the same frame has been evicted twice.\n- Fix: \"Histogram\" Color2 mode to copy alpha channel from source for alpha-carrying formats\n  (YUVA, RGBPA, RGB32, RGB64); initialize alpha to zero in the histogram panel area.\n  (Was: garbage)\n- Fix: C-only vertical resampling code added more rounding than needed\n  (regression since pre-3.7.5 20250427).\n- Fix: \"Invert\": corrected chroma inversion to pivot around signed 0 instead\n  of XORing with max_pixel_value.\n- Fix: YUV->RGB limited range matrix accuracy for 10-16 bits, plus use a symmetric rounding in matrix \n  coefficient's integer approximation.\n- Fix: inaccurate ColorBars 10+ bit values. Now they are derived from the 32-bit float \n  RGB definitions instead of upscaling a 8 bit precalculated YUV value. -I and +Q are still kept at\n  legacy Avisynth values.\n- Fix: inaccurate ColorBarsHD 10+ bit values. Now they are derived from the 32-bit float \n  RGB definitions instead of upscaling a 8 bit precalculated YUV value. Add 100% White after \n  Ramp section.\n- Fix: GreyScale + SSE2 + RGB32 + matrix=\"RGB\" overflow. \n  Rare usage; \"RGB\" matrix (Identity) uses a 1.0 coefficient which exceeds the signed 16-bit \n  SIMD limit of 32767 at 15-bit precision. Added bounds checking to fallback to C-code for any \n  coefficients >= 1.0 or < −1.0.\n- Fix #448: Resolved an issue where MT_MULTI_INSTANCE filters using relative paths \n  (e.g. \"video.mp4\" or \"../image.png\") failed under Prefetch() when used in imported \n  scripts from different directories. The problem occurred because new thread instances did \n  not inherit the original working directory, causing path resolution to fail.\n  Now, the current directory is captured at filter instantiation and passed to worker threads, \n  ensuring consistent path resolution.\n- Fix #456: \"Reverse\" corrupts 24-bit audio (https://github.com/AviSynth/AviSynthPlus/issues/456)\n- Fix BDF font rendering when it contains variable width characters like mixed Latin and CJK. \n  Preparing feature request #446 (https://github.com/AviSynth/AviSynthPlus/issues/446)\n- Fix #462: Report: \"AviSynth scripts don't work in a folder with a Unicode name.\"\n  Plugin autoload folders are internally stored in UTF-8, regardless of which Windows ANSI codepage is set.\n\n  * Folder names used in macros in AddAutoLoadDir (SCRIPTDIR, MAINSCRIPTDIR, PROGRAMDIR) and no longer \n    restricted to contain ANSI-only characters\n  * Registry-backed macros that can contain plugin folder paths (USER_PLUS_PLUGINS, MACHINE_PLUS_PLUGINS, \n    USER_CLASSIC_PLUGINS, MACHINE_CLASSIC_PLUGINS) are read in Unicode friendly way as well. \n- Fix: Not existing registry entries won't appear as a macro string in auto-load path.\n  E.g. Avisynth would automatically add ``USER_CLASSIC_PLUGINS`` at the beginning, but if no such entry\n  exist, it kept being in the folder list as ``<current_directory>\\USER_CLASSIC_PLUGINS\\``. \n  Now this false entry is removed.\n- Fix: Overlay give proper error message if 32-bit float is not supported in that mode.\n- Change video-framebuffer over-allocation from 16 to 64 bytes. Allocate 64 bytes more than needed for \n  video frame buffer in order to be able to read 64 bytes safely with AVX512 without risking access violation \n  on the last pixels of the frame.\n- Fix: The `Animate()` function now explicitly clamps interpolated values to ensure they remain \n  strictly between the start and end range. Due to the high precision of 64-bit `double` introduced \n  in v3.7.5, intermediate calculations could slightly exceed the boundary (e.g., 360.00000000000006 \n  when interpolating from 0 to 360.0 in 564 steps), requiring this clamp to prevent out-of-range errors.\n\n\nOptimizations\n~~~~~~~~~~~~~\n- \"Layer\" YUVA/YUV/RGBP \"add\", \"subtract\", \"mul\", \"darken\", \"lighten\": refactor\n  chroma placement calculation and function dispatchers; main algorithm SIMD\n  vectorization is now possible for non-444 chroma placements by precalculating\n  a mask for the actual row. Add AVX2 path (LLVM/clangcl recommended).\n- \"Overlay\" Blend: improved speed while keeping accuracy; use float arithmetic\n  only where strictly needed.\n- \"Invert\": planar formats no longer pre-copy all planes from source before\n  conversion; only planes that are unchanged are copied, avoiding unnecessary work.\n- TurnLeft, TurnRight: AVX2 support (1,5-3x speed on i7-11700 compared to SSE2 version)\n- Turn180 AVX2 support (very slight speed gain)\n- Resamplers: \n\n  * introduce a SIMD-like C header (avs_simd_c.h) for smart auto-vectorizing compilers.\n  * restore vertical float performance (3.7.4 was slower than 3.7.3) + SSE2 special optimization\n  * further optimize verticals, use ``AVS_RESTRICT``\n  * (quicker RGB32/64 horizontal on AVX2 since TurnRigh/Left was optimized - packed RGB H-resize = TurnLeft-V-Resize-TurnRight)\n  * optimize SSSE3 and AVX2 horizontal resampler for 32-bit float for small (<=4) kernel sizes\n  * optimize 32-bit float vertical avx2\n  * add AVX512 code path \n  \n    - 32-bit float resamplers, verticals; horizontals up to kernel size 16.\n    - 8-16-bit horizontal resamplers, for kernel size <= 16 and specific ratios; speed gain up to 300%+ (DTL2020)!!\n    - 8-16-bit vertical resamplers\n  * (Work In Progress) unify horizontal and vertical plane processing flow\n\n- add NEON optimizations for ARM64 (aarch64) for TurnLeft/TurnRight/Turn180.\n  (First aarch64 code in Avisynth)\n- add NEON optimizatons for Overlay blend\n- (filter graph) avoid MTGuard and CacheGuard creation if a filter returns one of its clip parameter unaltered.\n- Add some avx2 stuff to Invert (no really gain, filter is too simple) and some Layer subfilter.\n\nDocumentation\n~~~~~~~~~~~~~\n- Build on Raspbian, Raspberry Pi 5 and llvm/gcc :doc:`This page <./contributing/posix>` \n  describes linux builds process.\n- Add to :ref:`SIMD in ARM64 (aarch64) section <aarch64_simd_tiers>`\n- Extend ``env->Allocate/Free`` see at :ref:`Allocate <cplusplus_allocate>`\n- Interface V12 changes: see :ref:`API v12 changes<api_v12_whats_new>` for more details.\n- Add folder macro description to AddAutoLoadPlugins\n- Update :doc:`Overlay <./corefilters/overlay>`\n- Update :ref:`SetCacheHints<cplusplus_setcachehints>` with ``CACHE_INFORM_NUM_THREADS``\n- Update :ref:`GetCPUFlags<cplusplus_getcpuflags>`, add :ref:`GetCPUFlagsEx<cplusplus_getcpuflagsex>`\n- Update :ref:`CPU Feature Flags<cplusplus_cpufeatureflags>` with AVX512 and ARM64 features\n- Update :ref:`SetMaxCPU <setmaxcpu>` with AVX512 and ARM64 features\n- Update :ref:`AvsEnvProperty<cplusplus_getenvproperty>` with L2 cache size entry\n- Update Russian GPL notice in UTF-8 format\n- Update :doc:`ConvertToPlanarRGB <./corefilters/convert>` with `\"bits\"` and \"matrix\" syntax `\":same\"`\n- Update :doc:`ResetMask <./corefilters/mask>` with `\"opacity\"` and additional insights\n- Update :doc:`AddAlphaPlane <./corefilters/mask>` with `\"opacity\"` and additional insights\n- Update :doc:`Overlay <./corefilters/overlay>` with \"add\" and \"subtract\"\n  direct RGB mode and 32-bit float support.\n- Update :doc:`Layer <./corefilters/layer>` with \"use_chroma\" and opacity\n  details, and YUY2/YV16 internal handling.\n- Update :doc:`Histogram <./corefilters/histogram>` with new vectorscope parameters\n- Update :doc:`ColorBars <./corefilters/colorbars>`\n- Update :ref:`matrix syntax <matrix_parameter_syntax>`\n- Update :doc:`Convert <./corefilters/convert>` with ``ConvertToYUY2``\n  ``ChromaOutPlacement`` parameter and corrected chroma placement behavior.\n- Update :doc:`Convert <./corefilters/convert>` with ``bits`` and ``quality`` parameters\n- Update :doc:`Sampling <./advancedtopics/sampling>` with historical content notes\n  on legacy ``YUY2`` handling.\n- Add another Ubuntu->Windows DLL cross-compilation guide:\n  See :ref:`Ubuntu->Windows mingw crosscompilation<compiling_avsplus_crosscompiling2>`\n- Add :doc:`ColorBarsUHD <./corefilters/colorbarsuhd>`\n- Add :doc:`SetFilterProp / SetFilterPropPassthrough <./corefilters/setfilterprop>`\n\n\nPlease report bugs at `github AviSynthPlus page`_ - or - `Doom9's AviSynth+\nforum`_\n\n$Date: 2026/03/30 12:00:00 $\n\n.. _github AviSynthPlus page:\n    https://github.com/AviSynth/AviSynthPlus\n.. _Doom9's AviSynth+ forum:\n    https://forum.doom9.org/showthread.php?t=181351\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/contributing/avsplus_external_deps_guide_manual.rst",
    "content": "\nBuilding AviSynth+'s external dependencies with Visual Studio\n=============================================================\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\nStarting with 3.7.4, we no longer ship copies of DevIL and SoundTouch inside the\nAviSynth+ git repository.  There are a couple reasons for this:\n\n1. The internal copy of DevIL was only ever used on Windows and shipped the\n   binary DevIL.dll itself rather than building it as a submodule. All of the\n   other OSes could already build against a newer version of the library or\n   build ImageSeq with DevIL linked in statically (the macOS builds in the\n   Releases are an example).\n\n2. The embedded SoundTouch code was out of date, and since it was fully possible\n   to build it against the current version (and on \\*nix, use the existing\n   package, exactly like the DevIL case), there was no harm in moving it to the\n   same model.\n\nSo those building AviSynth+ from source have much more flexibility in terms of\nmaking sure both SoundTouch and DevIL (and DevIL's dependencies) are actually\nup-to-date, and can configure the dependencies as static or shared according to\ntheir own preferences.\n\nFor building SoundTouch and DevIL on Windows using MSVC, we'll take advantage of\nthe fact that CMake's internal install processes mimic the install directories\non Linux, et al., which simplifies the ability to point at that singular spot\nand tell it to bring in the libraries we've built.\n\nMake sure that pkg-config (or pkgconf), cmake, git, 7-zip, wget, sed, bash,\nautotools, patch, and meson are somewhere on the Windows **%PATH%**.  An existing\nMSys2 MinGW64 installation that's been added to the **%PATH%** will suffice.\npkg-config is necessary for SoundTouch to be found when configuring AviSynth+;\nwe find DevIL using CMake's own **FindDevIL.cmake** script.\n\nEven though we do need to piggy-back on some of MSys2's tools, the intention is\nthat all - or at least, most - of this guide can be followed in the regular old\nWindows Terminal.\n\nWe'll use a central install spot for the libraries, by using a bit of environment\ntrickery.  Set the following variable as the root of one of your drives.\n\n::\n\n    set AVS_DEPS_BUILD_HOME=E:\n\n.. Note::\n    If you want to use a drive other than E:, change it here.  You can also set\n    this to a subdirectory on the drive, but for simplicity's sake, the guide is\n    just going with the root of the drive.\n\nThen make that setting permanent, so you can close and re-open the Command\nPrompt and not have to worry about the variable getting erased.\n\n::\n\n    setx AVS_DEPS_BUILD_HOME %AVS_DEPS_BUILD_HOME%\n\nAnd make a directory to house the downloaded sources for SoundTouch, DevIL, and\nits dependencies:\n\n::\n\n    mkdir %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\n\nTo run the build process with as many cores as you have available, set the *-j #*\nparameter when invoking *cmake --build*.  My i5-9400 has 6 cores, so I use *-j 6*.\nWhile Windows does have a CLI command to get this information, it can't be\ninjected into the CMake process the way something like this can under Bash.\n\nLaunching the VS Command Prompt can be done from an existing cmd session by\ninvoking one of the vcvarsall scripts in\n\n::\n\n    C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\n\n| The ones we're interested in on a 64-bit install of Windows 10 are\n| **vcvars64.bat**\n| **vcvars32.bat**\n\nI have a directory at ``E:\\Programs\\ScriptTools`` on my **%PATH%**, so I create\nchained launchers to these launchers there, as they aren't otherwise available\non the **%PATH%**.\n\n::\n\n    echo @ECHO OFF > E:\\Programs\\ScriptTools\\msvc64.bat\n    echo \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars64.bat\" >> E:\\Programs\\ScriptTools\\msvc64.bat\n\n    echo @ECHO OFF > E:\\Programs\\ScriptTools\\msvc32.bat\n    echo \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars32.bat\" >> E:\\Programs\\ScriptTools\\msvc32.bat\n\n.. Note::\n    Creating symlinks on Windows 10 and 11 requires Administrator privileges (Open\n    Elevated Command Prompt).\n\n    On Windows 11, this can be done from a non-Admin prompt by using sudo as one\n    would on Linux or OS X.  sudo on Windows 11 needs to be enabled by the user\n    through Developer Settings.\n\n\npkgconf\n-------\n\npkg-config is a tool used to detect and add headers and libraries from the filesystem.\npkgconf is compatible with pkg-config while both being slimmer on dependencies and adding\na couple of useful features.\n\nOn Windows, MSVC can be used to build pkgconf, but meson is required.  The quickest way\nto do this is through pip.\n\nAnyone wanting to build the AviSynth+ docs already has Python, hence they also already\nhave pip, and can install meson through there.  Or you have Python installed for other\nreasons anyway.  During Python installation it should have been added to the PATH.\n\nOpen the Visual Studio Command Prompt and install meson:\n\n    ::\n\n        pip install meson\n\nClone the source using Git:\n\n    ::\n\n        git clone https://github.com/pkgconf/pkgconf\n\nCreate the proper build directory and move into it:\n\n    ::\n\n        mkdir pkgconf\\build && ^\n        cd pkgconf\\build\n\nConfigure the pkgconf build:\n\n    ::\n\n        meson setup ../ -Dtests=disabled -Dprefix=C:\\pkgconf_for_windows\n\nBuild the source:\n\n    ::\n\n        meson compile\n\nInstall pkgconf:\n\n    ::\n\n        meson install\n\nCreate a symbolic link so pkg-config can be used as an alias for pkgconf (Windows 11 instructions shown):\n\n    ::\n\n        sudo mklink C:\\pkgconf_for_windows\\bin\\pkg-config.exe C:\\pkgconf_for_windows\\bin\\pkgconf.exe\n\nAdd the folder containing pkgconf to the PATH:\n\n    ::\n\n        setx PATH \"%PATH%;C:\\pkgconf_for_windows\\bin\"\n\nClose and re-open the Command Prompt.\n\n\nSoundTouch\n----------\n\nSoundTouch is used by the TimeStretch plugin.\n\nJump to the correct drive and source location:\n\n    ::\n\n        %AVS_DEPS_BUILD_HOME% && ^\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\n\nClone the source using Git:\n\n    ::\n\n        git clone https://codeberg.org/soundtouch/soundtouch\n\nEnter the directory and create the proper build directories:\n\n    ::\n\n        cd soundtouch && ^\n        mkdir build && ^\n        cd build && ^\n        mkdir x64 x86\n\n.. Note::\n    As demonstrated above, multiple commands can be chained by using &&:\n\n        cd soundtouch && mkdir build && cd build && mkdir x64 x86\n\n    The caret (^) is used to break to a new line in cmd.exe, the same way that\n    bash uses \\\\:\n\n        | $AVS_DEPS_BUILD_HOME && \\\\\n        | cd $AVS_DEPS_BUILD_HOME\\avsplus-build-deps\n\n    Be sure to copy the entire command wherever carets appear.\n\n\n\nx86-64\n^^^^^^\n\nEnter the build directory for x64:\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\soundtouch\\build\\x64\n\nConfigure the build:\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -A \"x64\" -T \"v141_xp\" ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64\n\nCompile and install in one step:\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nx86-32\n^^^^^^\n\nEnter the build directory for x86:\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\soundtouch\\build\\x86\n\nConfigure the build:\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -A \"Win32\" -T \"v141_xp\" ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32\n\nCompile and install in one step:\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\n.. _devil_prebuilt_sdk_section1:\n\nDevIL (using prebuilt SDK)\n--------------------------\n\nJump to the correct drive and source location:\n\n    ::\n\n        %AVS_DEPS_BUILD_HOME% && ^\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\n\nDownload the DevIL SDK zipfile:\n\n    ::\n\n        wget http://downloads.sourceforge.net/openil/DevIL-Windows-SDK-1.8.0.zip\n\nUnpack it to the build_dep destination area:\n\n    ::\n\n        7z x -o%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps DevIL-Windows-SDK-1.8.0.zip\n\nAnd then jump to the last section to build :ref:`AviSynth+`.\n\n\nBuilding DevIL's dependencies manually\n--------------------------------------\n\n\n.. WARNING::\n\n    What follows is the dependency chain for building DevIL locally, along with\n    all of its dependencies and their dependencies.  Consider this an exercise\n    for the masochistic.  It is, however, laid out in a more or less linear\n    fashion to make it easier to follow along.\n\n    Unlike the SoundTouch and DevIL SDK steps above, the reason for each step\n    won't be explained, simply because it would introduce a massive amount of\n    identical text.  Every one of these are broken up into a group of steps to\n    jump into the source download area, download the source, and create the\n    build subdirectories.  And then it breaks down the actual build steps under\n    headers for x64 and x86.\n\n    Unless there's something important to note about the options or something\n    weird to account for, the description for those steps are exactly the same.\n\n    If there are weird things to account for, they'll be noted.\n\n\nzlib-ng\n^^^^^^^\n\n    ::\n\n        %AVS_DEPS_BUILD_HOME% && ^\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps && ^\n        git clone https://github.com/zlib-ng/zlib-ng && ^\n        cd zlib-ng && ^\n        mkdir build && ^\n        cd build && ^\n        mkdir x64 x86\n\n\nx86-64\n++++++\n\n.. Note::\n    -DPKGCONFIG_INSTALL_DIR is necessary because otherwise the .pc file will install to root.\n..\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\zlib-ng\\build\\x64\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64 ^\n        -DBUILD_SHARED_LIBS:bool=off -DZLIB_COMPAT:bool=on -DZLIB_ENABLE_TESTS:bool=off ^\n        -DPKGCONFIG_INSTALL_DIR=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64\\lib\\pkgconfig\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nx86-32\n++++++\n\n.. Note::\n    -DPKGCONFIG_INSTALL_DIR is necessary because otherwise the .pc file will install to root.\n\n.. Note::\n    **-DWITH_SSE2:bool=off** exists here to disable SSE2, as the guide assumes\n    a very broad install base.  Most users don't need to worry about that option\n    and can safely remove it.\n..\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\zlib-ng\\build\\x86\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -A \"Win32\" -T \"v141_xp\" ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32 ^\n        -DBUILD_SHARED_LIBS:bool=off -DZLIB_COMPAT:bool=on -DZLIB_ENABLE_TESTS:bool=off ^\n        -DWITH_SSE2:bool=off -DCMAKE_RC_FLAGS=\"--target=pe-i386\" ^\n        -DPKGCONFIG_INSTALL_DIR=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32\\lib\\pkgconfig\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nxz-tools\n^^^^^^^^\n\n    ::\n\n        %AVS_DEPS_BUILD_HOME% && ^\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps && ^\n        wget http://tukaani.org/xz/xz-5.6.4.tar.gz -O - | tar -xzvf - && ^\n        cd xz-5.6.4 && ^\n        mkdir build && ^\n        cd build && ^\n        mkdir x64 x86\n\n\nx86-64\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\xz-5.6.4\\build\\x64\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64 ^\n        -DBUILD_SHARED_LIBS:bool=off\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nx86-32\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\xz-5.6.4\\build\\x86\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" -A Win32 ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32 ^\n        -DBUILD_SHARED_LIBS:bool=off\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nLCMS2\n^^^^^\n\nUsing meson with MSVC requires launching the VS Command Prompt.\n\n    ::\n\n        %AVS_DEPS_BUILD_HOME% && ^\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps && ^\n        git clone https://github.com/mm2/Little-CMS && ^\n        cd Little-CMS && ^\n        mkdir build && ^\n        cd build && ^\n        mkdir x64 x86\n\n\nx86-64\n++++++\n\n    ::\n\n        msvc64\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\Little-CMS\\build\\x64\n\n    ::\n\n        meson setup ../../ --prefix=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64 ^\n        --libdir=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64\\lib ^\n        --default-library static --backend vs\n\n    ::\n\n        meson compile -C .\n\n    ::\n\n        meson install --strip\n\n    ::\n\n        sudo mklink %AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64\\lib\\lcms2.lib %AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64\\lib\\liblcms2.a\n\n\nx86-32\n++++++\n\n    ::\n\n        msvc32\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\Little-CMS\\build\\x86\n\n    ::\n\n        meson setup ../../ --prefix=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32 ^\n        --libdir=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32\\lib ^\n        --default-library static --backend vs\n\n    ::\n\n        meson compile -C .\n\n    ::\n\n        meson install --strip\n\n    ::\n\n        sudo mklink %AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32\\lib\\lcms2.lib %AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32\\lib\\liblcms2.a\n\n    ::\n\n        exit\n\n.. Note::\n    Remember to exit the VS Command Prompt before continuing\n\n\nlibjpeg-turbo\n^^^^^^^^^^^^^\n\n    ::\n\n        %AVS_DEPS_BUILD_HOME% && ^\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps && ^\n        git clone https://github.com/libjpeg-turbo/libjpeg-turbo && ^\n        cd libjpeg-turbo && ^\n        mkdir build && ^\n        cd build && ^\n        mkdir x64 x86\n\n\nx86-64\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\libjpeg-turbo\\build\\x64\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64 ^\n        -DENABLE_SHARED:bool=off -DCMAKE_SYSTEM_PROCESSOR=\"x86_64\"\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nx86-32\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\libjpeg-turbo\\build\\x86\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" -A Win32 ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32 ^\n        -DENABLE_SHARED:bool=off -DCMAKE_SYSTEM_PROCESSOR=\"i686\"\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nlibpng\n^^^^^^\n\n    ::\n\n        %AVS_DEPS_BUILD_HOME% && ^\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps && ^\n        git clone git://git.code.sf.net/p/libpng/code libpng && ^\n        cd libpng && ^\n        git checkout libpng16 && ^\n        mkdir build && ^\n        cd build && ^\n        mkdir x64 x86\n\n\nx86-64\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\libpng\\build\\x64\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64 ^\n        -DPNG_SHARED:bool=off -DPNG_TESTS:bool=off ^\n        -DZLIB_INCLUDE_DIR=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64\\include ^\n        -DZLIB_LIBRARY=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64\\lib\\zlibstatic.lib\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nx86-32\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\libpng\\build\\x86\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" -A Win32 ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32 ^\n        -DPNG_SHARED:bool=off -DPNG_TESTS:bool=off ^\n        -DZLIB_INCLUDE_DIR=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32\\include ^\n        -DZLIB_LIBRARY=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32\\lib\\zlibstatic.lib\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\njbigkit\n^^^^^^^\n\n    ::\n\n        %AVS_DEPS_BUILD_HOME% && ^\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps && ^\n        git clone https://github.com/qyot27/jbigkit && ^\n        cd jbigkit && ^\n        git checkout mingw-w64 && ^\n        mkdir build && ^\n        cd build && ^\n        mkdir x64 x86\n\n\nx86-64\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\jbigkit\\build\\x64\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nx86-32\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\jbigkit\\build\\x86\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" -A Win32 ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\ndeflate\n^^^^^^^\n\n    ::\n\n        %AVS_DEPS_BUILD_HOME% && ^\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps && ^\n        git clone https://github.com/ebiggers/libdeflate && ^\n        cd libdeflate && ^\n        mkdir build && ^\n        cd build && ^\n        mkdir x64 x86\n\n\nx86-64\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\libdeflate\\build\\x64\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64 ^\n        -DLIBDEFLATE_BUILD_SHARED_LIB:bool=off\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nx86-32\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\libdeflate\\build\\x86\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" -A Win32 ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32 ^\n        -DLIBDEFLATE_BUILD_SHARED_LIB:bool=off\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nlerc\n^^^^\n\n    ::\n\n        %AVS_DEPS_BUILD_HOME% && ^\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps && ^\n        git clone https://github.com/esri/lerc/ && ^\n        cd lerc\\build && ^\n        mkdir x64 x86\n\n\nx86-64\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\lerc\\build\\x64\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64 ^\n        -DBUILD_SHARED_LIBS:bool=off\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nx86-32\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\lerc\\build\\x86\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" -A Win32 ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32 ^\n        -DBUILD_SHARED_LIBS:bool=off\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nzstd\n^^^^\n\n    ::\n\n        %AVS_DEPS_BUILD_HOME% && ^\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps && ^\n        git clone https://github.com/facebook/zstd && ^\n        cd zstd && ^\n        mkdir zstd-build && ^\n        cd zstd-build && ^\n        mkdir x64 x86\n\n\nx86-64\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\zstd\\zstd-build\\x64\n\n    ::\n\n        cmake ../../build/cmake -G \"Visual Studio 16 2019\" -T \"v141_xp\" ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64 ^\n        -DZSTD_BUILD_SHARED:bool=off\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nx86-32\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\zstd\\zstd-build\\x86\n\n    ::\n\n        cmake ../../build/cmake -G \"Visual Studio 16 2019\" -T \"v141_xp\" -A Win32 ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32 ^\n        -DZSTD_BUILD_SHARED:bool=off\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nlibwebp\n^^^^^^^\n\n    ::\n\n        %AVS_DEPS_BUILD_HOME% && ^\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps && ^\n        git clone https://chromium.googlesource.com/webm/libwebp && ^\n        cd libwebp && ^\n        mkdir build && ^\n        cd build && ^\n        mkdir x64 x86\n\n\nx86-64\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\libwebp\\build\\x64\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64 ^\n        -DCMAKE_PREFIX_PATH=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64 ^\n        -DBUILD_SHARED_LIBS:bool=off -DWEBP_ENABLE_SWAP_16BIT_CSP:bool=on\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nx86-32\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\libwebp\\build\\x86\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" -A Win32 ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32 ^\n        -DCMAKE_PREFIX_PATH=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32 ^\n        -DBUILD_SHARED_LIBS:bool=off -DWEBP_ENABLE_SWAP_16BIT_CSP:bool=on\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nlibtiff\n^^^^^^^\n\n    ::\n\n        %AVS_DEPS_BUILD_HOME% && ^\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps && ^\n        git clone https://gitlab.com/libtiff/libtiff.git && ^\n        cd libtiff && ^\n        mkdir libtiff-build && ^\n        cd libtiff-build && ^\n        mkdir x64 x86\n\n.. Note::\n    Seemingly won't link to the static webp we just built.\n\nx86-64\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\libtiff\\libtiff-build\\x64\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64 ^\n        -DCMAKE_PREFIX_PATH=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64 ^\n        -DBUILD_SHARED_LIBS:bool=off -Dtiff-docs:bool=off -Dtiff-tools:bool=off ^\n        -Dtiff-tests:bool=off -DCMAKE_C_FLAGS=\"-DLZMA_API_STATIC\"\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nx86-32\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\libtiff\\libtiff-build\\x86\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" -A Win32 ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32 ^\n        -DCMAKE_PREFIX_PATH=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32 ^\n        -DBUILD_SHARED_LIBS:bool=off -Dtiff-docs:bool=off -Dtiff-tools:bool=off ^\n        -Dtiff-tests:bool=off -DCMAKE_C_FLAGS=\"-DLZMA_API_STATIC\"\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nlibmng\n^^^^^^\n\n    ::\n\n        %AVS_DEPS_BUILD_HOME% && ^\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps && ^\n        curl -Lo libmng-2.0.3.tar.gz https://sourceforge.net/projects/libmng/files/libmng-devel/2.0.3/libmng-2.0.3.tar.gz/download && ^\n        tar -xzvf libmng-2.0.3.tar.gz && ^\n        cd libmng-2.0.3/build && ^\n        mkdir x64 x86\n\n\nx86-64\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\libmng-2.0.3\\build\\x64\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64 ^\n        -DBUILD_SHARED_LIBS:bool=off ^\n        -DCMAKE_STAGING_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64 ^\n        -DCMAKE_PREFIX_PATH=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nx86-32\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\libmng-2.0.3\\build\\x86\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" -A Win32 ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32 ^\n        -DBUILD_SHARED_LIBS:bool=off ^\n        -DCMAKE_STAGING_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32 ^\n        -DCMAKE_PREFIX_PATH=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nlibsquish\n^^^^^^^^^\n\n.. WARNING::\n    The libsquish tarball is actually a tarbomb, so we need to create a\n    directory for it first.\n..\n\n    ::\n\n        %AVS_DEPS_BUILD_HOME% && ^\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps && ^\n        mkdir libsquish && ^\n        cd libsquish && ^\n        curl -Lo libsquish-1.15.tar.gz https://sourceforge.net/projects/libsquish/files/libsquish-1.15.tgz/download && ^\n        tar -xzvf libsquish-1.15.tar.gz && ^\n        mkdir build && ^\n        cd build && ^\n        mkdir x64 x86\n\n\nx86-64\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\libsquish\\build\\x64\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64 ^\n        -DBUILD_SHARED_LIBS:bool=off\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nx86-32\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\libsquish\\build\\x86\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" -A Win32 ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32 ^\n        -DBUILD_SHARED_LIBS:bool=off\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nJasPer\n^^^^^^\n\n    ::\n\n        %AVS_DEPS_BUILD_HOME% && ^\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps && ^\n        git clone https://github.com/jasper-software/jasper.git && ^\n        cd jasper && ^\n        mkdir jasper-build && ^\n        cd jasper-build && ^\n        mkdir x64 x86\n\n\n.. Note::\n    JasPer HEAD not compatible with v141_xp due to missing sysinfoapi.h header\n    and threading library, but this can be kludged.\n..\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\jasper\n        sed -e '97s/^^/\\/\\//' -e '659,669s/^^/\\/\\//' src/libjasper/base/jas_malloc.c\n\n\nx86-64\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\jasper\\jasper-build\\x64\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64 ^\n        -DCMAKE_PREFIX_PATH=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64 ^\n        -DJAS_ENABLE_SHARED:bool=off -DJAS_ENABLE_OPENGL:bool=off ^\n        -DJAS_ENABLE_DOC:bool=off -DJAS_ENABLE_PROGRAMS:bool=off ^\n        -DALLOW_IN_SOURCE_BUILD:bool=on -DJAS_ENABLE_MULTITHREADING_SUPPORT:bool=off\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nx86-32\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\jasper\\jasper-build\\x86\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" -A Win32 ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32 ^\n        -DCMAKE_PREFIX_PATH=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32 ^\n        -DJAS_ENABLE_SHARED:bool=off -DJAS_ENABLE_OPENGL:bool=off ^\n        -DJAS_ENABLE_DOC:bool=off -DJAS_ENABLE_PROGRAMS:bool=off ^\n        -DALLOW_IN_SOURCE_BUILD:bool=on -DJAS_ENABLE_MULTITHREADING_SUPPORT:bool=off\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nOpenEXR\n^^^^^^^\n\n.. Note::\n    Not compatible with XP.\n..\n\n    ::\n\n        %AVS_DEPS_BUILD_HOME% && ^\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps && ^\n        git clone https://github.com/AcademySoftwareFoundation/openexr && ^\n        cd openexr && ^\n        mkdir build && ^\n        cd build && ^\n        mkdir x64 x86\n\n\nx86-64\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\openexr\\build\\x64\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64 ^\n        -DBUILD_SHARED_LIBS:bool=off\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nx86-32\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\openexr\\build\\x86\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" -A Win32 ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32 ^\n        -DBUILD_SHARED_LIBS:bool=off\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nDevIL\n-----\n\n    ::\n\n        %AVS_DEPS_BUILD_HOME% && ^\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps && ^\n        git clone https://github.com/DentonW/DevIL.git\n\nComment out or delete the reference to ILUT subdirectory in CMakeLists.txt:\n\n    ::\n\n        sed -i '9d' DevIL/DevIL/CMakeLists.txt\n\nRemove SHARED definition from src-ILU CMakeLists.txt to force static ILU:\n\n    ::\n\n        sed -i '46s/SHARED //' DevIL\\DevIL\\src-ILU\\CMakeLists.txt\n\nApply patch to use newer versions of JasPer:\n\n    ::\n\n        cd DevIL && ^\n        wget https://gist.githubusercontent.com/qyot27/b362b3e3834485c3e7b7e33e3b8d5049/raw/4fdcfa2b5b516f47d8ce1e967d70877f63c85497/0001-jasper-git.patch && ^\n        git am 0001-jasper-git.patch\n\nConvert .h files in ``src-ILU/include/ilu-error`` from ISO-8859-1 to UTF-8 to avoid\nbuild errors:\n\n    ::\n\n        cd DevIL\\DevIL\\src-ILU\\include\\ilu_error && ^\n        iconv -f ISO-8859-1 -t UTF-8 ilu_err-french.h | tee ilu_err-french.h && ^\n        iconv -f ISO-8859-1 -t UTF-8 ilu_err-german.h | tee ilu_err-german.h && ^\n        iconv -f ISO-8859-1 -t UTF-8 ilu_err-italian.h | tee ilu_err-italian.h && ^\n        iconv -f ISO-8859-1 -t UTF-8 ilu_err-spanish.h | tee ilu_err-spanish.h && ^\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\n\n    ::\n\n        cd DevIL/DevIL && ^\n        mkdir devil-build && ^\n        cd devil-build && ^\n        mkdir x64 x86\n\n.. Note::\n    DevIL looks for LCMS2 as lcms2.lib; use a symlink to fix that.\n\n\nx86-64\n^^^^^^\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\DevIL\\DevIL\\devil-build\\x64\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64 ^\n        -DBUILD_SHARED_LIBS:bool=off ^\n        -DCMAKE_PREFIX_PATH=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nx86-32\n^^^^^^\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\DevIL\\DevIL\\devil-build\\x86\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" -A Win32 ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32 ^\n        -DBUILD_SHARED_LIBS:bool=off ^\n        -DCMAKE_PREFIX_PATH=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\n.. _avisynth+:\n\nAviSynth+\n---------\n\n::\n\n    %AVS_DEPS_BUILD_HOME%\n    cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\n    git clone https://github.com/AviSynth/AviSynthPlus.git\n    cd AviSynthPlus\n    mkdir build && cd build\n    mkdir x64 x86\n\n\n\n.. _devil_prebuilt_sdk_section2:\n\nUsing prebuilt DevIL SDK\n^^^^^^^^^^^^^^^^^^^^^^^^\n\nx86-64\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\AviSynthPlus\\build\\x64\n\n    ::\n\n        cmake ../../  -G \"Visual Studio 16 2019\" -T \"v141_xp\" ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avisynth_build\\x86-64 ^\n        -DWINXP_SUPPORT:bool=on ^\n        -DIL_LIBRARIES=\"E:\\avsplus_build_deps\\DevIL Windows SDK\\lib\\x64\\Release\\DevIL.lib\" ^\n        -DILU_LIBRARIES=\"E:\\avsplus_build_deps\\DevIL Windows SDK\\lib\\x64\\Release\\ILU.lib\" ^\n        -DCMAKE_PREFIX_PATH=\"E:\\avsplus_build_deps\\x86-64;E:\\avsplus_build_deps\\DevIL Windows SDK\"\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\nCopy 64-bit **DevIL.dll** from the SDK into the bin directory of the AviSynth+\ninstall, using the Windows-native copy command (although if you have MSys2's\ntools on the **%PATH%**, *cp* would be usable as well):\n\n    ::\n\n        copy \"%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\DevIL Windows SDK\\lib\\x64\\Release\\DevIL.dll\" ^\n        %AVS_DEPS_BUILD_HOME%\\avisynth_build\\x86-64\\bin\n\n\nx86-32\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\AviSynthPlus\\build\\x86\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" -A \"Win32\" ^\n        -DCMAKE_INSTALL_PREFIX=E:/avisynth_build/x86-32 -DMSVC_CPU_ARCH=\"SSE\" ^\n        -DWINXP_SUPPORT:bool=on ^\n        -DIL_LIBRARIES=\"E:\\avsplus_build_deps\\DevIL Windows SDK\\lib\\x86\\Release\\DevIL.lib\" ^\n        -DILU_LIBRARIES=\"E:\\avsplus_build_deps\\DevIL Windows SDK\\lib\\x86\\Release\\ILU.lib\" ^\n        -DCMAKE_PREFIX_PATH=\"E:\\avsplus_build_deps\\x86-32;E:\\avsplus_build_deps\\DevIL Windows SDK\"\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\nCopy 32-bit **DevIL.dll** from the SDK into the bin directory of the AviSynth+\ninstall, using the Windows-native copy command (although if you have MSys2's\ntools on the **%PATH%**, *cp* would be usable as well):\n\n    ::\n\n        copy \"%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\DevIL Windows SDK\\lib\\x86\\Release\\DevIL.dll\" %AVS_DEPS_BUILD_HOME%\\avisynth_build\\x86-32\\bin\n\n\n\nUsing manually-built static DevIL\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nx86-64\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\AviSynthPlus\\build\\x64\n\n    ::\n\n        cmake ../../  -G \"Visual Studio 16 2019\" -T \"v141_xp\" ^\n        -DCMAKE_INSTALL_PREFIX=%AVS_DEPS_BUILD_HOME%\\avisynth_build\\x86-64 ^\n        -DWINXP_SUPPORT:bool=on ^\n        -DIL_LIBRARIES=\"%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64\\lib\\DevIL.lib;%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64\\lib\\jpeg-static.lib;%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64\\lib\\libpng16_static.lib;%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64\\lib\\tiff.lib;%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64\\lib\\squish.lib;%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64\\lib\\jasper.lib;%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64\\lib\\zlibstatic.lib;%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64\\lib\\lzma.lib;%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64\\lib\\jbig.lib;%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64\\lib\\deflatestatic.lib;%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64\\lib\\Lerc.lib;%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64\\lib\\zstd_static.lib\" ^\n        -DILU_LIBRARIES=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64\\lib\\ILU.lib ^\n        -DCMAKE_PREFIX_PATH=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-64 ^\n        -DCMAKE_CXX_FLAGS=\"-DIL_STATIC_LIB\"\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\n\nx86-32\n++++++\n\n    ::\n\n        cd %AVS_DEPS_BUILD_HOME%\\avsplus-build-deps\\AviSynthPlus\\build\\x86\n\n    ::\n\n        cmake ../../ -G \"Visual Studio 16 2019\" -T \"v141_xp\" -A \"Win32\" ^\n        -DCMAKE_INSTALL_PREFIX=E:/avisynth_build/x86-32 -DMSVC_CPU_ARCH=\"SSE\" ^\n        -DWINXP_SUPPORT:bool=on ^\n        -DIL_LIBRARIES=\"%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32\\lib\\DevIL.lib;%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32\\lib\\jpeg-static.lib;%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32\\lib\\libpng16_static.lib;%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32\\lib\\tiff.lib;%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32\\lib\\squish.lib;%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32\\lib\\jasper.lib;%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32\\lib\\zlibstatic.lib;%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32\\lib\\lzma.lib;%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32\\lib\\jbig.lib;%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32\\lib\\deflatestatic.lib;%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32\\lib\\Lerc.lib;%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32\\lib\\zstd_static.lib\" ^\n        -DILU_LIBRARIES=%AVS_DEPS_BUILD_HOME%\\avsplus_build_deps\\x86-32\\lib\\ILU.lib ^\n        -DCMAKE_PREFIX_PATH=\"E:\\avsplus_build_deps\\x86-32\" ^\n        -DCMAKE_CXX_FLAGS=\"-DIL_STATIC_LIB\"\n\n    ::\n\n        cmake --build . --config Release -j 6 --target install\n\nBack to the :doc:`main page <../../index>`\n\n$ Date: 2025-03-08 21:34:07-05:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/contributing/avsplus_external_deps_guide_manual_arm.rst",
    "content": "\nBuilding AviSynth+'s external dependencies for Windows on ARM\n=============================================================\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\nUnlike for x86 or x64, where we support using MSVC to build the\nAviSynth+ core, for Windows on ARM we only support using MinGW-based\ncompilers.  At present this is restricted to llvm-mingw, which\nuses Clang.  Windows on ARM support has currently (as of February of 2025)\nnot appeared in a stable version of GCC, but whenever it does, that\nwould be acceptable as well.\n\nOwing to this fact, the build process is different from the assumptions\nmade for x86/x64 with MSVC.  The easiest way is probably to cross-compile\nfrom a Linux distro (that includes WSL2, especially for running the task\ndirectly on a Windows on ARM device, since Snapdragon X support is still\nin its early stages for most/all distros).\n\nThe instructions are going to assume Ubuntu as the distro in question,\nparticularly as it relates to things like the repositories.\n\nMake sure you have a list of other necessary build system and source download\ncomponents.\n\n    ::\n\n        sudo apt-get install build-essential gcc-multilib g++-multilib \\\n        checkinstall nasm yasm cvs git gperf subversion mercurial automake* \\\n        autoconf* libtool* m4 bison flex p7zip-full lzip texinfo help2man \\\n        tofrodos texi2html docutils-common cmake pkgconf bzr autopoint meson \\\n        ninja-build gettext binfmt-support ruby doxygen gtk-doc-tools zlib1g-dev \\\n        python-is-python3 python3-setuptools\n\n\nAny time \\ is at the end of a line, it means the command spans multiple lines.\nMake sure to copy the entire command.  To make this easier to see, such\ncommands have been indented.\n\nThe '&& \\' at the end of each instruction is to allow running the\nentire piece at once.  This is for convenience, and should just work.\nIf there are errors, run each instruction one at a time and adjust\naccordingly.\n\n\nCreate staging areas and a space for constructed packages to be stored:\n\n    ::\n\n        mkdir -p ~/mingw-packages ~/mpv-build-deps ~/mingw_debs/aarch64\n\n\n\nCross-compilation Toolchain\n---------------------------\n\nLLVM/MinGW installation\n^^^^^^^^^^^^^^^^^^^^^^^\n\n.. Note:\n    If the process fails with an error related to cc1plus\n    being terminated, reduce the number of jobs by using\n    the CMAKE_BUILD_PARALLEL_LEVEL environment variable.\n..\n\n    ::\n\n        cd ~/mingw-packages && \\\n        mkdir llvm-mingw-build && \\\n        git clone https://github.com/mstorsjo/llvm-mingw && \\\n        cd llvm-mingw && \\\n        ./build-all.sh ../llvm-mingw-build\n\n\nPackaging Preparation\n^^^^^^^^^^^^^^^^^^^^^\n\nCopy NASM and pkg-config into the bin directory of the toolchain so that they\ncan easily be found when a prefixed copy of these tools are needed.\n\n    ::\n\n        cd ../llvm-mingw-build && \\\n        cp /usr/bin/pkg-config bin/aarch64-w64-mingw32-pkg-config && \\\n\nA few of these pieces require using CMake to build them. This is not as\nstraight-forward as using autotools to cross-compile, and requires some setup:\n\n    ::\n\n        cd aarch64-w64-mingw32 && \\\n        wget https://fastapi.metacpan.org/source/TOKUHIROM/mRuby-0.06/vendor/mruby/cmake/Toolchain-Ubuntu-mingw32.cmake.sample -O toolchain-aarch64-w64-mingw32.cmake && \\\n        sed -i -e 's/ ~\\/crossdev\\/w32//g' -e 's/i686/aarch64/g' -e 's/usr/usr\\/llvm-mingw/g' toolchain-aarch64-w64-mingw32.cmake\n\nSetting up meson's cross-files:\n\n    ::\n\n        cd ../ && \\\n        mkdir -p share/meson/cross/ && \\\n        wget \"https://raw.githubusercontent.com/mesonbuild/meson/master/cross/linux-mingw-w64-64bit.txt\" -O share/meson/cross/aarch64-w64-mingw32 && \\\n\n        sed -i -e 's/usr\\/bin\\/x86_64/usr\\/llvm-mingw\\/bin\\/aarch64/g' -e 's/x86_64/aarch64/g' \\\n        -e 's/wine64//g' -e 's/wine//g' \\\n        -e '13,16d' -e \"s/\\[properties\\]/\\[built-in options\\]/\" \\\n        share/meson/cross/aarch64-w64-mingw32\n\n        sed -i -e \"13ic_args = ['-I/usr/aarch64-w64-mingw32/include']\\ncpp_args = ['-I/usr/aarch64-w64-mingw32/include']\\nc_link_args = ['-L/usr/aarch64-w64-mingw32/lib']\\ncpp_link_args = ['-L/usr/aarch64-w64-mingw32/lib']\" \\\n        share/meson/cross/aarch64-w64-mingw32\n\nForce remove import libraries to prevent accidental shared linking\n(libomp.dll.a remains, because there is no static version of that library):\n\n    ::\n\n        rm aarch64-w64-mingw32/lib/lib{c++,pthread,unwind,winpthread}.dll.a\n\n\n\nInstalling the toolchain\n^^^^^^^^^^^^^^^^^^^^^^^^\n\n    ::\n\n        cd ~/mingw-packages && \\\n            sudo checkinstall --pkgname=llvm-mingw \\\n            --pkgversion=\"1:$(llvm-mingw-build/bin/x86_64-w64-mingw32-clang --version | head -1 | \\\n            cut -f3 -d ' ')\" --backup=no --deldoc=yes --delspec=yes --deldesc=yes \\\n            --strip=yes --stripso=yes --addso=yes --fstrans=no --default cp -R llvm-mingw-build /usr/llvm-mingw && \\\n        mv *.deb ~/\n\n\nAdding LLVM/MinGW to the PATH\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTo try and avoid a collision between MinGW/GCC and LLVM/MinGW,\nLLVM/MinGW should be added to the *end* of the $PATH.  Since it\nwill be the only thing providing -mingw32 prefixes for clang and aarch64,\nand the only source of clang-cl, those will go through correctly,\notherwise, the PATH ordering will prefer real GCC to the symlinks\nthat LLVM/MinGW creates.\n\n    ::\n\n        echo \"export PATH=\\$PATH:/usr/llvm-mingw/bin\" >> ~/.bashrc\n\nIn order to use checkinstall with llvm-mingw, you'll also need\nto add the PATH epxort to the root user's .bashrc.\n\n    ::\n\n        echo \"export PATH=\\$PATH:/usr/llvm-mingw/bin\" | sudo tee -a /root/.bashrc\n\nClose and re-open the Terminal.  `source ~/.bashrc` might also work, but\nwhether it also works for the root user, I don't know.\n\nThere is an issue with attempting to use some of the aarch64-w64-mingw32\ntools when checkinstall gets involved, and errors out saying that the aarch64\nbinaries can't be found, even though due to the two above commands,\nthey are on the $PATH.  This could be resolved by the user elevating\nto root with `sudo su` and then running checkinstall, but a slightly\nless cumbersome approach is to just simply symlink the tools into\n/usr/bin.\n\n    ::\n\n        sudo ln -sf /usr/llvm-mingw/bin/aarch64-w64-mingw32-ranlib /usr/bin/aarch64-w64-mingw32-ranlib && \\\n        sudo mkdir -p /usr/share/meson/cross && \\\n        sudo ln -sf /usr/llvm-mingw/share/meson/cross/aarch64-w64-mingw32 /usr/share/meson/cross/aarch64-w64-mingw32\n\n\nSoundTouch\n----------\n\nSoundTouch is used by the TimeStretch plugin.\n\nJump to the correct drive and source location:\n\n    ::\n\n        cd ~/mpv-build-deps\n\nClone the source using Git:\n\n    ::\n\n        git clone https://codeberg.org/soundtouch/soundtouch\n\nCreate the proper build directory:\n\n    ::\n\n        mkdir -p soundtouch/build\n\nEnter the build directory:\n\n    ::\n\n        cd ~/mpv-build-deps/soundtouch/build && \\\n\nConfigure the build:\n\n    ::\n\n        cmake ../../ -G \"Ninja\" -DCMAKE_INSTALL_PREFIX=/usr/aarch64-w64-mingw32 \\\n        -DCMAKE_TOOLCHAIN_FILE=\"/usr/llvm-mingw/aarch64-w64-mingw32/toolchain-aarch64-w64-mingw32.cmake\" \\\n        -DCMAKE_EXE_LINKER_FLAGS=\"-municode\" && \\\n\nCompile:\n\n    ::\n\n        ninja\n\nInstall:\n\n    ::\n\n        sudo checkinstall --pkgname=soundtouch-mingw-aarch64 --pkgversion=\"$(grep -r \\\n        Version soundtouch.pc | cut -f2 -d \" \")-$(date --rfc-3339=date | \\\n        sed 's/-//g')-git\" --backup=no --deldoc=yes --delspec=yes --deldesc=yes \\\n        --strip=yes --fstrans=no --default ninja install && \\\n\nMove the created package to the package cache:\n\n    ::\n\n        mv *.deb ~/mingw_debs/aarch64\n\n\n\nBuilding DevIL's dependencies manually\n--------------------------------------\n\n\n.. WARNING::\n\n    What follows is the dependency chain for building DevIL locally, along with\n    all of its dependencies and their dependencies.  Consider this an exercise\n    for the masochistic.  It is, however, laid out in a more or less linear\n    fashion to make it easier to follow along.\n\n    Unlike the SoundTouch steps above, the reason for each step won't be\n    explained, simply because it would introduce a massive amount of\n    identical text.  Every one of these are broken up into a group of steps\n    to jump into the source download area, download the source, and create\n    the build subdirectories.\n\n    Unless there's something important to note about the options or something\n    weird to account for, the description for those steps are exactly the same.\n\n    If there are weird things to account for, they'll be noted.\n\n\nzlib-ng\n^^^^^^^\n\n.. Note::\n    -DPKGCONFIG_INSTALL_DIR is necessary because otherwise it will\n    install to root.\n..\n\n    ::\n\n        cd ~/mpv-build-deps && \\\n        git clone https://github.com/zlib-ng/zlib-ng && \\\n        mkdir -p zlib-ng/zlib-ng-build/{i686,amd64,aarch64} && \\\n\n    ::\n\n        cd ~/mpv-build-deps/zlib-ng/zlib-ng-build/aarch64 && \\\n            cmake ../../ -G \"Ninja\" -DCMAKE_INSTALL_PREFIX=/usr/aarch64-w64-mingw32 \\\n            -DCMAKE_TOOLCHAIN_FILE=\"/usr/llvm-mingw/aarch64-w64-mingw32/toolchain-aarch64-w64-mingw32.cmake\" \\\n            -DBUILD_SHARED_LIBS:bool=off -DZLIB_COMPAT:bool=on -DZLIB_ENABLE_TESTS:bool=off \\\n            -DCMAKE_SYSTEM_PROCESSOR=aarch64 -DPKGCONFIG_INSTALL_DIR=/usr/aarch64-w64-mingw32/lib/pkgconfig && \\\n        ninja && \\\n            sudo checkinstall --pkgname=zlib-mingw-aarch64 --pkgversion=\"$(git describe \\\n            --tags)-$(date --rfc-3339=date | sed 's/-//g')-git\" --backup=no \\\n            --deldoc=yes --delspec=yes --deldesc=yes --strip=yes --fstrans=no --default \\\n            ninja install && \\\n        mv *.deb ~/mingw_debs/aarch64\n\n\nxz-tools\n^^^^^^^^\n\n    ::\n\n        cd ~/mpv-build-deps && \\\n        wget http://tukaani.org/xz/xz-5.6.4.tar.gz -O - | tar -xzvf - && \\\n        mkdir -p xz-5.6.4/xz-build/{i686,amd64,aarch64} && \\\n\n    ::\n\n        cd ~/mpv-build-deps/xz-5.6.4/xz-build/aarch64 && \\\n            ../../configure --prefix=/usr/aarch64-w64-mingw32 --disable-shared \\\n            --disable-nls --enable-silent-rules --host=aarch64-w64-mingw32 && \\\n        make -j$(nproc) && \\\n            sudo checkinstall --pkgname=xz-tools-mingw-aarch64 --pkgversion=\"$(grep Version \\\n            src/liblzma/liblzma.pc | sed 's/Version: //g')-$(date --rfc-3339=date | \\\n            sed 's/-//g')\" --backup=no --deldoc=yes --delspec=yes --deldesc=yes \\\n            --strip=yes --fstrans=no --default && \\\n        mv *.deb ~/mingw_debs/aarch64\n\n\nlcms2\n^^^^^\n\n    ::\n\n        cd ~/mpv-build-deps && \\\n        git clone https://github.com/mm2/Little-CMS && \\\n        mkdir -p Little-CMS/littlecms-build/{i686,amd64,aarch64} && \\\n\n    ::\n\n        cd ~/mpv-build-deps/Little-CMS/littlecms-build/aarch64 && \\\n            ../../configure --prefix=/usr/aarch64-w64-mingw32 \\\n            --disable-shared --without-jpeg --without-tiff --enable-silent-rules \\\n            --host=aarch64-w64-mingw32 && \\\n        make -j$(nproc) && \\\n            sudo checkinstall --pkgname=lcms2-mingw-aarch64 --pkgversion=\"1:$(grep Version \\\n            lcms2.pc | sed 's/Version: //g')-$(date --rfc-3339=date | sed 's/-//g')-git\" \\\n            --backup=no --deldoc=yes --delspec=yes --deldesc=yes --strip=yes \\\n            --fstrans=no --default && \\\n        mv *.deb ~/mingw_debs/aarch64\n\n\nlibjpeg-turbo\n^^^^^^^^^^^^^\n\n    ::\n\n        cd ~/mpv-build-deps && \\\n        git clone https://github.com/libjpeg-turbo/libjpeg-turbo && \\\n        mkdir -p libjpeg-turbo/libjpegturbo-build/{i686,amd64,aarch64} && \\\n\n    ::\n\n        cd ~/mpv-build-deps/libjpeg-turbo/libjpegturbo-build/aarch64 && \\\n            cmake ../../ -G \"Ninja\" -DCMAKE_INSTALL_PREFIX=/usr/aarch64-w64-mingw32 \\\n            -DCMAKE_TOOLCHAIN_FILE=\"/usr/llvm-mingw/aarch64-w64-mingw32/toolchain-aarch64-w64-mingw32.cmake\" \\\n            -DENABLE_SHARED:bool=off -DCMAKE_SYSTEM_PROCESSOR=\"aarch64\" && \\\n        ninja && \\\n            sudo checkinstall --pkgname=libjpeg-turbo-mingw-aarch64 --pkgversion=\"$(grep \\\n            Version pkgscripts/libturbojpeg.pc | sed 's/Version: //g')-$(date --rfc-3339=date | \\\n            sed 's/-//g')\" --backup=no --deldoc=yes --delspec=yes --deldesc=yes \\\n            --strip=yes --fstrans=no --default ninja install && \\\n        mv *.deb ~/mingw_debs/aarch64\n\n\nlibpng\n^^^^^^\n\n    ::\n\n        cd ~/mpv-build-deps && \\\n        git clone https://git.code.sf.net/p/libpng/code libpng && \\\n        cd libpng && \\\n        git checkout libpng16 && \\\n        mkdir -p libpng-build/{i686,amd64,aarch64} && \\\n\n    ::\n\n        cd ~/mpv-build-deps/libpng/libpng-build/aarch64 && \\\n            cmake ../../ -G \"Ninja\" -DCMAKE_INSTALL_PREFIX=/usr/aarch64-w64-mingw32 \\\n            -DCMAKE_TOOLCHAIN_FILE=\"/usr/llvm-mingw/aarch64-w64-mingw32/toolchain-aarch64-w64-mingw32.cmake\" \\\n            -DPNG_SHARED:bool=off -DPNG_TESTS:bool=off -DZLIB_INCLUDE_DIR=/usr/aarch64-w64-mingw32/include \\\n            -DZLIB_LIBRARY=/usr/aarch64-w64-mingw32/lib/libz.a -DCMAKE_C_FLAGS=\"-DPNG_ARM_NEON_OPT=0\" && \\\n        ninja && \\\n            sudo checkinstall --pkgname=libpng-mingw-aarch64 --pkgversion=\"$(grep Version \\\n            libpng.pc | sed 's/Version: //g')-$(date --rfc-3339=date | sed 's/-//g')\" \\\n            --backup=no --deldoc=yes --delspec=yes --deldesc=yes --strip=yes \\\n            --fstrans=no --default ninja install && \\\n        mv *.deb ~/mingw_debs/aarch64\n\n\njbigkit\n^^^^^^^\n\n    ::\n\n        cd ~/mpv-build-deps && \\\n        git clone https://github.com/qyot27/jbigkit && \\\n        cd jbigkit && \\\n        autoreconf -fiv && \\\n        mkdir -p jbigkit-build/{i686,amd64,aarch64} && \\\n\n    ::\n\n        cd ~/mpv-build-deps/jbigkit/jbigkit-build/aarch64 && \\\n            ../../configure --prefix=/usr/aarch64-w64-mingw32 \\\n            --disable-shared --enable-silent-rules --host=aarch64-w64-mingw32 && \\\n        make -j$(nproc) && \\\n            sudo checkinstall --pkgname=libjbig-mingw-aarch64 --pkgversion=\"$(grep \\\n            JBG_VERSION ../../libjbig/jbig.h | sed 's/\\\"/\\t/g' | cut -f2)-$(date \\\n            --rfc-3339=date | sed 's/-//g')-git\" --backup=no --deldoc=yes \\\n            --delspec=yes --deldesc=yes --strip=yes --fstrans=no --default && \\\n        mv *.deb ~/mingw_debs/aarch64\n\n\ndeflate\n^^^^^^^\n\n    ::\n\n        cd ~/mpv-build-deps && \\\n        git clone https://github.com/ebiggers/libdeflate && \\\n        mkdir -p libdeflate/libdeflate-build/{i686,amd64,aarch64} && \\\n\n    ::\n\n        cd ~/mpv-build-deps/libdeflate/libdeflate-build/aarch64 && \\\n            cmake ../../ -G \"Ninja\" -DCMAKE_INSTALL_PREFIX=/usr/aarch64-w64-mingw32 \\\n            -DCMAKE_TOOLCHAIN_FILE=\"/usr/llvm-mingw/aarch64-w64-mingw32/toolchain-aarch64-w64-mingw32.cmake\" \\\n            -DLIBDEFLATE_BUILD_SHARED_LIB:bool=off && \\\n        ninja && \\\n            sudo checkinstall --pkgname=libdeflate-mingw-aarch64 --pkgversion=\"$(grep -r \\\n            Version libdeflate.pc | cut -f2 -d \" \")-$(date --rfc-3339=date | \\\n            sed 's/-//g')-git\" --backup=no --deldoc=yes --delspec=yes --deldesc=yes \\\n            --strip=yes --fstrans=no --default ninja install && \\\n        mv *.deb ~/mingw_debs/aarch64\n\n\nlerc\n^^^^\n\n    ::\n\n        cd ~/mpv-build-deps && \\\n        git clone https://github.com/esri/lerc && \\\n        mkdir -p lerc/lerc-build/{i686,amd64,aarch64} && \\\n\n    ::\n\n        cd ~/mpv-build-deps/lerc/lerc-build/aarch64 && \\\n            cmake ../../ -G \"Ninja\" -DCMAKE_INSTALL_PREFIX=/usr/aarch64-w64-mingw32 \\\n            -DCMAKE_TOOLCHAIN_FILE=\"/usr/llvm-mingw/aarch64-w64-mingw32/toolchain-aarch64-w64-mingw32.cmake\" \\\n            -DBUILD_SHARED_LIBS:bool=off && \\\n        ninja && \\\n            sudo checkinstall --pkgname=lerc-mingw-aarch64 --pkgversion=\"$(grep -r \\\n            Version Lerc.pc | cut -f2 -d \" \")-$(date --rfc-3339=date | \\\n            sed 's/-//g')-git\" --backup=no --deldoc=yes --delspec=yes --deldesc=yes \\\n            --strip=yes --fstrans=no --default ninja install && \\\n        mv *.deb ~/mingw_debs/aarch64\n\n\nzstd\n^^^^\n\n    ::\n\n        cd ~/mpv-build-deps && \\\n        git clone https://github.com/facebook/zstd && \\\n        mkdir -p zstd/zstd-build/{i686,amd64,aarch64} && \\\n\n    ::\n\n        cd ~/mpv-build-deps/zstd/zstd-build/aarch64 && \\\n            cmake ../../build/cmake -G \"Ninja\" -DCMAKE_INSTALL_PREFIX=/usr/aarch64-w64-mingw32 \\\n            -DCMAKE_TOOLCHAIN_FILE=\"/usr/llvm-mingw/aarch64-w64-mingw32/toolchain-aarch64-w64-mingw32.cmake\" \\\n            -DZSTD_BUILD_SHARED:bool=off && \\\n        ninja && \\\n            sudo checkinstall --pkgname=zstd-mingw-aarch64 --pkgversion=\"$(grep -r \\\n            Version lib/libzstd.pc | cut -f2 -d \" \")-$(date --rfc-3339=date | \\\n            sed 's/-//g')-git\" --backup=no --deldoc=yes --delspec=yes --deldesc=yes \\\n            --strip=yes --fstrans=no --default ninja install && \\\n        mv *.deb ~/mingw_debs/aarch64\n\n\nlibwebp\n^^^^^^^\n\n    ::\n\n        cd ~/mpv-build-deps && \\\n        git clone https://chromium.googlesource.com/webm/libwebp && \\\n        cd libwebp && \\\n        autoreconf -fiv && \\\n        mkdir -p libwebp-build/{i686,amd64,aarch64} && \\\n\n    ::\n\n        cd ~/mpv-build-deps/libwebp/libwebp-build/aarch64 && \\\n            LIBPNG_CONFIG=\"/usr/aarch64-w64-mingw32/bin/libpng-config --static\" \\\n            PKG_CONFIG_PATH=/usr/aarch64-w64-mingw32/lib/pkgconfig \\\n            ../../configure --prefix=/usr/aarch64-w64-mingw32 --disable-shared \\\n            --enable-swap-16bit-csp --disable-tiff --enable-libwebpmux \\\n            --enable-libwebpdemux --enable-libwebpdecoder --host=aarch64-w64-mingw32 && \\\n        make -j$(nproc) && \\\n            sudo checkinstall --pkgname=libwebp-mingw-aarch64 --pkgversion=\"$(grep Version \\\n            src/libwebp.pc | sed 's/Version: //g')-$(date --rfc-3339=date | \\\n            sed 's/-//g')-git\" --backup=no --deldoc=yes --delspec=yes --deldesc=yes \\\n            --strip=yes --fstrans=no --default && \\\n        mv *.deb ~/mingw_debs/aarch64\n\n\nlibtiff\n^^^^^^^\n\n    ::\n\n        cd ~/mpv-build-deps && \\\n        git clone https://gitlab.com/libtiff/libtiff.git && \\\n        mkdir -p libtiff/libtiff-build/{i686,amd64,aarch64} && \\\n\n    ::\n\n        cd ~/mpv-build-deps/libtiff/libtiff-build/aarch64 && \\\n            cmake ../../ -G \"Ninja\" -DCMAKE_INSTALL_PREFIX=/usr/aarch64-w64-mingw32 \\\n            -DCMAKE_TOOLCHAIN_FILE=\"/usr/llvm-mingw/aarch64-w64-mingw32/toolchain-aarch64-w64-mingw32.cmake\" \\\n            -DCMAKE_STAGING_PREFIX=/usr/aarch64-w64-mingw32 -Dlerc:bool=off -DBUILD_SHARED_LIBS:bool=off && \\\n        ninja && \\\n        sed -i 's/Libs.private:  -ljbig/Libs.private: -ljbig -ljpeg -llzma/' libtiff-4.pc && \\\n            sudo checkinstall --pkgname=libtiff-mingw-aarch64 --pkgversion=\"$(grep Version \\\n            libtiff-4.pc | sed 's/Version: //g')-$(date --rfc-3339=date | \\\n            sed 's/-//g')-git\" --backup=no --deldoc=yes --delspec=yes --deldesc=yes \\\n            --strip=yes --fstrans=no --default ninja install && \\\n        mv *.deb ~/mingw_debs/aarch64\n\n\nlibmng\n^^^^^^\n\n    ::\n\n        cd ~/mpv-build-deps && \\\n        wget https://downloads.sourceforge.net/project/libmng/libmng-devel/2.0.3/libmng-2.0.3.tar.xz -O - | tar -xJvf - && \\\n        mkdir -p libmng-2.0.3/libmng-build/{i686,amd64,aarch64} && \\\n\n    ::\n\n        cd ~/mpv-build-deps/libmng-2.0.3/libmng-build/aarch64 && \\\n            cmake ../../ -G \"Ninja\" -DCMAKE_INSTALL_PREFIX=/usr/aarch64-w64-mingw32 \\\n            -DCMAKE_TOOLCHAIN_FILE=\"/usr/llvm-mingw/aarch64-w64-mingw32/toolchain-aarch64-w64-mingw32.cmake\" \\\n            -DBUILD_SHARED_LIBS:bool=off -DCMAKE_STAGING_PREFIX=/usr/aarch64-w64-mingw32 \\\n            -DCMAKE_PREFIX_PATH=/usr/aarch64-w64-mingw32 && \\\n        ninja && \\\n            sudo checkinstall --pkgname=libmng-mingw-aarch64 --pkgversion=\"$(grep -w VERSION \\\n            config.h | cut -f2 -d '\"')-$(date --rfc-3339=date | sed 's/-//g')\" --backup=no \\\n            --deldoc=yes --delspec=yes --deldesc=yes --strip=yes --fstrans=no \\\n            --default ninja install && \\\n        mv *.deb ~/mingw_debs/aarch64\n\n\nlibsquish\n^^^^^^^^^\n\n.. Note::\n    The libsquish tarball is actually a tarbomb,\n    so we need to create a directory for it first.\n..\n\n    ::\n\n        cd ~/mpv-build-deps && \\\n        mkdir libsquish && cd libsquish && \\\n        wget https://downloads.sourceforge.net/project/libsquish/libsquish-1.15.tgz -O - | tar -xzvf - && \\\n        mkdir -p libsquish-build/{i686,amd64,aarch64} && \\\n\n    ::\n\n        cd ~/mpv-build-deps/libsquish/libsquish-build/aarch64 && \\\n            cmake ../../ -G \"Ninja\" -DCMAKE_INSTALL_PREFIX=/usr/aarch64-w64-mingw32 \\\n            -DCMAKE_TOOLCHAIN_FILE=\"/usr/llvm-mingw/aarch64-w64-mingw32/toolchain-aarch64-w64-mingw32.cmake\" \\\n            -DBUILD_SHARED_LIBS:bool=off -DBUILD_SQUISH_WITH_OPENMP:bool=off && \\\n        ninja && \\\n            sudo checkinstall --pkgname=libsquish-mingw-aarch64 --pkgversion=\"$(grep -w \\\n            \"VER =\" ../../Makefile | cut -f3 -d ' ')-$(date --rfc-3339=date | \\\n            sed 's/-//g')-git\" --backup=no --deldoc=yes --delspec=yes --deldesc=yes \\\n            --strip=yes --fstrans=no --default ninja install && \\\n        mv *.deb ~/mingw_debs/aarch64\n\n\nJasPer\n^^^^^^\n\n    ::\n\n        cd ~/mpv-build-deps && \\\n        git clone https://github.com/jasper-software/jasper.git && \\\n        mkdir -p jasper/jasper-build/{i686,amd64,aarch64} && \\\n\n    ::\n\n        cd ~/mpv-build-deps/jasper/jasper-build/aarch64 && \\\n            cmake ../../ -G \"Ninja\" -DCMAKE_INSTALL_PREFIX=/usr/aarch64-w64-mingw32 \\\n            -DCMAKE_TOOLCHAIN_FILE=\"/usr/llvm-mingw/aarch64-w64-mingw32/toolchain-aarch64-w64-mingw32.cmake\" \\\n            -DCMAKE_PREFIX_PATH=/usr/aarch64-w64-mingw32 -DJAS_ENABLE_SHARED:bool=off \\\n            -DJAS_ENABLE_OPENGL:bool=off -DJAS_ENABLE_DOC:bool=off \\\n            -DJAS_ENABLE_PROGRAMS:bool=off -DALLOW_IN_SOURCE_BUILD:bool=on \\\n            -DJAS_CROSSCOMPILING:bool=on -DJAS_STDC_VERSION=0 && \\\n        ninja && \\\n            sudo checkinstall --pkgname=jasper-mingw-aarch64 --pkgversion=\"$(grep -r \\\n            Version build/pkgconfig/jasper.pc | cut -f2 -d \" \")-$(date --rfc-3339=date | \\\n            sed 's/-//g')-git\" --backup=no --deldoc=yes --delspec=yes --deldesc=yes \\\n            --strip=yes --fstrans=no --default ninja install && \\\n        mv *.deb ~/mingw_debs/aarch64\n\n\nOpenEXR\n^^^^^^^\n\n    ::\n\n        cd ~/mpv-build-deps && \\\n        git clone https://github.com/AcademySoftwareFoundation/openexr && \\\n        mkdir -p openexr/openexr-build/{i686,amd64,aarch64} && \\\n\n    ::\n\n        cd ~/mpv-build-deps/openexr/openexr-build/aarch64 && \\\n            cmake ../../ -G \"Ninja\" -DCMAKE_INSTALL_PREFIX=/usr/aarch64-w64-mingw32 \\\n            -DCMAKE_TOOLCHAIN_FILE=\"/usr/llvm-mingw/aarch64-w64-mingw32/toolchain-aarch64-w64-mingw32.cmake\" \\\n            -DBUILD_SHARED_LIBS:bool=off && \\\n        ninja && \\\n            sudo checkinstall --pkgname=openexr-mingw-aarch64 --pkgversion=\"$(grep -r \\\n            Version cmake/OpenEXR.pc | cut -f2 -d \" \")-$(date --rfc-3339=date | \\\n            sed 's/-//g')-git\" --backup=no --deldoc=yes --delspec=yes --deldesc=yes \\\n            --strip=yes --fstrans=no --default ninja install && \\\n        mv *.deb ~/mingw_debs/aarch64\n\n\nDevIL\n-----\n\n    ::\n\n        cd ~/mpv-build-deps && \\\n        git clone https://github.com/DentonW/DevIL.git && \\\n        mkdir -p DevIL/DevIL/devil-build/{i686,amd64,aarch64} && \\\n\nComment out ILUT subdirectory in CMakeLists.txt\n\n    ::\n\n        sed -i '9d' DevIL/DevIL/CMakeLists.txt && \\\n\nRemove SHARED definition from src-ILU CMakeLists.txt to force static ILU\nand avoid weird dll pointing in avsplus step\n\n    ::\n\n        sed -i '/ILU SHARED/ s/SHARED //' DevIL/DevIL/src-ILU/CMakeLists.txt && \\\n\nApply patch to use newer versions of JasPer:\n\n    ::\n\n        cd DevIL && \\\n        wget https://gist.githubusercontent.com/qyot27/b362b3e3834485c3e7b7e33e3b8d5049/raw/4fdcfa2b5b516f47d8ce1e967d70877f63c85497/0001-jasper-git.patch && \\\n        git am 0001-jasper-git.patch\n\nConvert .h files in src-ILU/include/ilu-error from\nISO-8859-1 to UTF-8 to avoid build errors\n\n    ::\n\n        for n in DevIL/src-ILU/include/ilu_error/ilu_err-{french,german,italian,spanish}.h ; do iconv -f ISO-8859-1 -t UTF-8 \"$n\" > \"$n-utf8\" && mv \"$n-utf8\" \"$n\" ; done\n\n    ::\n\n        cd ~/mpv-build-deps/DevIL/DevIL/devil-build/aarch64 && \\\n            cmake ../../ -G \"Ninja\" -DCMAKE_INSTALL_PREFIX=/usr/aarch64-w64-mingw32 \\\n            -DCMAKE_TOOLCHAIN_FILE=\"/usr/llvm-mingw/aarch64-w64-mingw32/toolchain-aarch64-w64-mingw32.cmake\" \\\n            -DBUILD_SHARED_LIBS:bool=off -DCMAKE_PREFIX_PATH=/usr/aarch64-w64-mingw32 \\\n            -DCMAKE_STAGING_PREFIX=/usr/aarch64-w64-mingw32 -DCMAKE_CXX_STANDARD=14 && \\\n        ninja && \\\n            sudo checkinstall --pkgname=devil-mingw-aarch64 --pkgversion=\"$(git describe --tags | \\\n            sed 's/^v//')-$(date --rfc-3339=date | sed 's/-//g')-git\" --backup=no --deldoc=yes \\\n            --delspec=yes --deldesc=yes --strip=yes --fstrans=no --default ninja install && \\\n        mv *.deb ~/mingw_debs/aarch64\n\n\nAviSynth+\n---------\n\n    ::\n\n        cd ~/mpv-build-deps && \\\n        git clone https://github.com/AviSynth/AviSynthPlus && \\\n        mkdir -p AviSynthPlus/avisynth-build/aarch64 && \\\n\n    ::\n\n        cd ~/mpv-build-deps/AviSynthPlus/avisynth-build/aarch64 && \\\n            cmake ../../ -G \"Ninja\" -DCMAKE_INSTALL_PREFIX=/usr/aarch64-w64-mingw32 \\\n            -DCMAKE_TOOLCHAIN_FILE=\"/usr/llvm-mingw/aarch64-w64-mingw32/toolchain-aarch64-w64-mingw32.cmake\" \\\n            -DCMAKE_SYSTEM_PROCESSOR=aarch64 -DCMAKE_PREFIX_PATH=/usr/aarch64-w64-mingw32 \\\n            -DCMAKE_STAGING_PREFIX=/usr/aarch64-w64-mingw32 -DCMAKE_CXX_FLAGS=\"-DIL_STATIC_LIB\" \\\n            -DIL_LIBRARIES=\"/usr/aarch64-w64-mingw32/lib/libIL.a;/usr/aarch64-w64-mingw32/lib/libturbojpeg.a;\\\n        /usr/aarch64-w64-mingw32/lib/libpng16.a;/usr/aarch64-w64-mingw32/lib/libtiff.a;\\\n        /usr/aarch64-w64-mingw32/lib/libsquish.a;/usr/aarch64-w64-mingw32/lib/libjasper.a;\\\n        /usr/aarch64-w64-mingw32/lib/libz.a;/usr/aarch64-w64-mingw32/lib/liblzma.a;\\\n        /usr/aarch64-w64-mingw32/lib/libjbig.a;/usr/aarch64-w64-mingw32/lib/libLerc.a;\\\n        /usr/aarch64-w64-mingw32/lib/libzstd.a;/usr/aarch64-w64-mingw32/lib/libdeflate.a;\\\n        /usr/llvm-mingw/aarch64-w64-mingw32/lib/libpthread.a\" \\\n            -DILU_LIBRARIES=/usr/aarch64-w64-mingw32/lib/libILU.a && \\\n        ninja && \\\n            sudo checkinstall --pkgname=avisynthplus-mingw-aarch64 --pkgversion=\"$(grep -r \\\n            Version avs_core/avisynth.pc | cut -f2 -d \" \")-$(date --rfc-3339=date | \\\n            sed 's/-//g')-git\" --backup=no --deldoc=yes --delspec=yes --deldesc=yes \\\n            --strip=yes --fstrans=no --default ninja install && \\\n        mv *.deb ~/mingw_debs/aarch64\n\nBack to the :doc:`main page <../../index>`\n\n$ Date: 2025-02-08 17:38:02-05:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/contributing/compiling_avsplus.rst",
    "content": "Compiling AviSynth+\n===================\n\nThis guide uses a command line-based compilation methodology, because\nit's easier to provide direct instructions for this that can just be copy/pasted.\n\nLater on some other compiling method (CMake GUI, Visual Studio solution) is shown as well with different compilers.\n\n`MSys2 <https://msys2.github.io/>`_ and `7zip <http://www.7-zip.org/>`_ should\nalready be installed, and msys2's bin directory should have been added to Windows'\n%PATH% variable.\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\n\nAviSynth+ prerequisites\n-----------------------\n\nNote that AviSynth+ is not restricted to Windows.\n\nAviSynth+ can be built by a few different compilers:\n\n* Visual Studio 2019, 2022, 2026 or higher. (May work for VS2017)\n  - native msvc or clang-cl\n* Clang 7.0.1 or higher.\n* GCC 7 or higher.\n* Intel C++ Compiler (2021-) (ICX: LLVM based NextGen)\n* Intel C++ Compiler 19.2 (ICL: classic) - discontinued by Intel\n\n\n| Download and install Visual Studio Community:\n| `<https://visualstudio.microsoft.com/downloads/>`_\n\n| Install the latest version of CMake:\n| `<http://www.cmake.org/cmake/resources/software.html>`_\n\nAfter installing MSys2, make sure to enable some convenience functions in MSys2's config files.\n\nIn msys.ini:\n::\n\n    CHERE_INVOKING=1\n    MSYS2_PATH_TYPE=inherit\n    MSYSTEM=MSYS\n\nIn mingw64.ini:\n::\n\n    CHERE_INVOKING=1\n    MSYS2_PATH_TYPE=inherit\n    MSYSTEM=MINGW64\n\nIn mingw32.ini:\n::\n\n    CHERE_INVOKING=1\n    MSYS2_PATH_TYPE=inherit\n    MSYSTEM=MINGW32\n\nAdd CMake's bin directory to the system %PATH% manually if the installer won't.\nAlso add 7zip and upx to the %PATH%.\n\n\nVisual Studio 2026 Support\n--------------------------\n\nVisual Studio 2026 support was introduced in November 2025. To use it, you must have **CMake 4.2** or higher installed.\n\nThe generator name is ``Visual Studio 18 2026``.\n\n**Solution Format (.slnx):**\nThe VS 2026 generator creates a **.slnx** file instead of the traditional .sln file. This is a new XML-based solution format. You should open the **.slnx** file in Visual Studio.\n\n**Windows XP Support:**\nVisual Studio 2026 still supports the ``v141_xp`` toolset. If you have the toolset installed, you can generate XP-compatible builds using the new generator.\n\n\nBuilding with Visual Studio\n---------------------------\n\nFor ease of use, we'll also be making use of MSys2 to streamline the build process,\neven with the VC++ compiler.\n\n\nDirectShowSource Prerequisites\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nDirectShowSource requires extra setup that building the AviSynth+ core does not.\nDirectShowSource is not a requirement for a working AviSynth+ setup, especially\nwith the options of using either FFmpegSource2 or LSMASHSource, but the guide\nwouldn't be complete otherwise.\n\n\nC++ Base Classes library\n........................\n\nDirectShowSource requires strmbase.lib, the C++ Base Classes library, which for some\nreason isn't included in a standard install of Visual Studio.  The source code for\nthe library is provided with the Windows SDK, and requires the user to build it first.\n\n| Download the Windows SDK 7.1 (Windows SDK for Windows 7 and .NET Framework 4, June 2010):\n| `<https://developer.microsoft.com/en-us/windows/downloads/sdk-archive/>`_\n\n| Download the following ISO for 32-bit Windows installations:\n| GRMSDK_EN_DVD.iso\n\n| Download the following ISO for 64-bit Windows installations:\n| GRMSDKX_EN_DVD.iso\n\nThe ISO you download is based on the version of Windows you're actually running,\n*not* on the Windows installs you're targetting.  Both ISOs include the correct\ntools to build for either 32-bit or 64-bit targets.\n\n| Verify the 32-bit ISO against CRC32 or SHA1:\n| CRC#: 0xBD8F1237\n| SHA1: 0xCDE254E83677C34C8FD509D6B733C32002FE3572\n\n| Verify the 64-bit ISO against CRC32 or SHA1:\n| CRC#: 0x04F59E55\n| SHA1: 0x9203529F5F70D556A60C37F118A95214E6D10B5A\n\nFor convenience (and on computers without an optical drive), you can use either Pismo\nFile Mount (if you've already got it installed for AVFS) or Windows 10's own Mount option\nto mount the ISO to a virtual drive. Then just launch setup.exe and follow the wizard.\n\nInstall only the Samples, uncheck everything else.\n\n| Open Visual Studio, and open the .sln file in the 7.1 SDK, at\n| ``C:\\Program Files\\Microsoft SDKs\\Windows\\v7.1\\Samples\\multimedia\\directshow\\baseclasses``\n\nAllow Visual Studio to convert the project, switch the configuration to ``Release_MBCS``,\nand enter the project Properties by right-clicking on the solution name and selecting\n``Properties``.\n\nSelect the ``Visual Studio 17 - Windows XP (v141_xp)`` option on the main Properties page\nunder ``Toolset``, and on the ``C/C++ Code Generation`` page select *Disabled* or *SSE*\nfrom the ``Enhanced Instruction Set`` option (IMO, it's safer to disable it for system\nsupport libraries like strmbase.lib), and finally, exit back to the main screen.\n\nNow select ``Build``. That's it.\n\nFor 64-bit, change to ``Release_MBCS x64`` and ``Build``. The SSE2 note isn't relevant here, since\n64-bit CPUs are required to have SSE2 support.\n\n\nMiscellaneous\n.............\n\nTo make the AviSynth+ build instructions more concise, we'll set a couple of environment\nvariables.  After starting msys2, open the file /etc/profile in Wordpad:\n::\n\n    write /etc/profile\n\nand copy the following three lines into it somewhere:\n::\n\n    export STRMBASELIB=\"C:/Program Files/Microsoft SDKs/Windows/v7.1/Samples/multimedia/directshow/baseclasses/Release/strmbase.lib\"\n    export STRMBASELIB64=\"C:/Program Files/Microsoft SDKs/Windows/v7.1/Samples/multimedia/directshow/baseclasses/x64/Release/strmbase.lib\"\n\n(64-bit Windows users should use ``Program Files (x86)``, but you probably already knew that ;P)\n\nThankfully, all of this setup only needs to be done once.\n\n\nBuilding AviSynth+\n~~~~~~~~~~~~~~~~~~\n\nStart the Visual Studio x86 Native Command Prompt.\n\nYou can use Visual Studio's compilers from MSys2 by launching MSys2 from the Visual Studio\nCommand Prompt. So type 'msys' and hit Enter.\n\nNote: in the instructions below, the ``\\`` character means the command spans more than\none line.  Make sure to copy/paste all of the lines in the command.\n\nDownload the AviSynth+ source:\n::\n\n    git clone https://github.com/AviSynth/AviSynthPlus && \\\n    cd AviSynthPlus\n\nSet up the packaging directory for later:\n::\n\n    AVSDIRNAME=avisynth+_r$(git rev-list --count HEAD)-g$(git rev-parse --short HEAD)-$(date --rfc-3339=date | sed 's/-//g') && \\\n    cd .. && \\\n    mkdir -p avisynth_build $AVSDIRNAME/32bit/dev $AVSDIRNAME/64bit/dev && \\\n    cd avisynth_build\n\nNow, we can build AviSynth+.\n\n\nUsing MSBuild\n.............\n\nNote: depending on your Visual Studio 2019, 2022 or 2026 version, choose only one cmake build block.\n**Reminder:** You need CMake 4.2+ for Visual Studio 2026.\n\nFor 32-bit (no XP, SSE2):\n::\n\n    cmake ../AviSynthPlus -G \"Visual Studio 18 2026\" -A Win32 -DMSVC_CPU_ARCH:string=\"SSE2\" -DBUILD_DIRECTSHOWSOURCE:bool=on && \\\n    cmake --build . --config Release -j $(nproc)\n\n    or\n\n    cmake ../AviSynthPlus -G \"Visual Studio 17 2022\" -A Win32 -DMSVC_CPU_ARCH:string=\"SSE2\" -DBUILD_DIRECTSHOWSOURCE:bool=on && \\\n    cmake --build . --config Release -j $(nproc)\n\n    or\n\n    cmake ../AviSynthPlus -G \"Visual Studio 16 2019\" -A Win32 -DMSVC_CPU_ARCH:string=\"SSE2\" -DBUILD_DIRECTSHOWSOURCE:bool=on && \\\n    cmake --build . --config Release -j $(nproc)\n\n\nFor 32-bit (XP, SSE):\n::\n\n    cmake ../AviSynthPlus -G \"Visual Studio 18 2026\" -A Win32 -T \"v141_xp\" -DMSVC_CPU_ARCH:string=\"SSE\" -DWINXP_SUPPORT:bool=on -DBUILD_DIRECTSHOWSOURCE:bool=on && \\\n    cmake --build . --config Release -j $(nproc)\n\n    or\n\n    cmake ../AviSynthPlus -G \"Visual Studio 17 2022\" -A Win32 -T \"v141_xp\" -DMSVC_CPU_ARCH:string=\"SSE\" -DWINXP_SUPPORT:bool=on -DBUILD_DIRECTSHOWSOURCE:bool=on && \\\n    cmake --build . --config Release -j $(nproc)\n\n    or\n\n    cmake ../AviSynthPlus -G \"Visual Studio 16 2019\" -A Win32 -T \"v141_xp\" -DMSVC_CPU_ARCH:string=\"SSE\" -DWINXP_SUPPORT:bool=on -DBUILD_DIRECTSHOWSOURCE:bool=on && \\\n    cmake --build . --config Release -j $(nproc)\n\n\nCopy the .dlls to the packaging directory:\n::\n\n    cp Output/AviSynth.dll Output/system/DevIL.dll Output/plugins/* ../$AVSDIRNAME/32bit\n\nCopy the .libs to the packaging directory:\n::\n\n    cp avs_core/Release/AviSynth.lib plugins/DirectShowSource/Release/*.lib \\\n    ../AviSynthPlus/plugins/ImageSeq/lib/DevIL_x86/DevIL.lib plugins/ImageSeq/Release/ImageSeq.lib \\\n    plugins/Shibatch/PFC/Release/PFC.lib plugins/Shibatch/Release/Shibatch.lib \\\n    plugins/TimeStretch/Release/TimeStretch.lib plugins/TimeStretch/SoundTouch/Release/SoundTouch.lib \\\n    plugins/VDubFilter/Release/VDubFilter.lib ../$AVSDIRNAME/32bit/dev\n\n\nUndo the upx packing on the 32-bit copy of DevIL.dll:\n::\n\n    upx -d ../$AVSDIRNAME/32bit/DevIL.dll\n\n\nFor 64-bit (no XP):\n::\n\n    cmake ../AviSynthPlus -G \"Visual Studio 18 2026\" -A x64 -DBUILD_DIRECTSHOWSOURCE:bool=on -DENABLE_PLUGINS:bool=on && \\\n    cmake --build . --config Release -j $(nproc)\n\n    or\n\n    cmake ../AviSynthPlus -G \"Visual Studio 17 2022\" -A x64 -DBUILD_DIRECTSHOWSOURCE:bool=on -DENABLE_PLUGINS:bool=on && \\\n    cmake --build . --config Release -j $(nproc)\n\n    or\n\n    cmake ../AviSynthPlus -G \"Visual Studio 16 2019\" -A x64 -DBUILD_DIRECTSHOWSOURCE:bool=on -DENABLE_PLUGINS:bool=on && \\\n    cmake --build . --config Release -j $(nproc)\n\n\n\nFor 64-bit (XP):\n::\n\n    cmake ../AviSynthPlus -G \"Visual Studio 18 2026\" -A x64 -T \"v141_xp\" -DWINXP_SUPPORT:bool=on -DBUILD_DIRECTSHOWSOURCE:bool=on -DENABLE_PLUGINS:bool=on && \\\n    cmake --build . --config Release -j $(nproc)\n\n    or\n\n    cmake ../AviSynthPlus -G \"Visual Studio 17 2022\" -A x64 -T \"v141_xp\" -DWINXP_SUPPORT:bool=on -DBUILD_DIRECTSHOWSOURCE:bool=on -DENABLE_PLUGINS:bool=on && \\\n    cmake --build . --config Release -j $(nproc)\n\n    or\n\n    cmake ../AviSynthPlus -G \"Visual Studio 16 2019\" -A x64 -T \"v141_xp\" -DWINXP_SUPPORT:bool=on -DBUILD_DIRECTSHOWSOURCE:bool=on -DENABLE_PLUGINS:bool=on && \\\n    cmake --build . --config Release -j $(nproc)\n\n\nCopy the .dlls to the packaging directory:\n::\n\n    cp Output/AviSynth.dll Output/system/DevIL.dll Output/plugins/* ../$AVSDIRNAME/64bit\n\nCopy the .libs to the packaging directory:\n::\n\n    cp avs_core/Release/AviSynth.lib plugins/DirectShowSource/Release/*.lib \\\n    ../AviSynthPlus/plugins/ImageSeq/lib/DevIL_x64/DevIL.lib plugins/ImageSeq/Release/ImageSeq.lib \\\n    plugins/Shibatch/PFC/Release/PFC.lib plugins/Shibatch/Release/Shibatch.lib \\\n    plugins/TimeStretch/Release/TimeStretch.lib plugins/TimeStretch/SoundTouch/Release/SoundTouch.lib \\\n    plugins/VDubFilter/Release/VDubFilter.lib ../$AVSDIRNAME/64bit/dev\n\n\nFinishing up\n~~~~~~~~~~~~\n\nPackaging up everything can be quickly done with 7-zip:\n::\n\n    cd ..\n    7z a -mx9 $AVSDIRNAME.7z $AVSDIRNAME\n\n\nBuilding with Microsoft C++ (cmake command line)\n------------------------------------------------\n\nFrom CMake GUI:\n~~~~~~~~~~~~~~~\n\n1. Delete Cache\n2. ``Where is source code`` and ``Where to build binaries``: git project folder e.g. C:/Github/AviSynthPlus\n3. Press Configure\n4. Choose an available generator:\n\n   - `Visual Studio 18 2026` (requires CMake 4.2+; generates **.slnx** file)\n   - `Visual Studio 17 2022` (solution will be generated for VS2022)\n   - `Visual Studio 16 2019` (solution will be generated for VS2019)\n5. Choose optional platform generator: default is `x64` when left empty, `Win32` is another option\n6. When you want XP compatible build, set ``Optional toolset to use (-T option)``:\n\n  - `v141_xp`\n\n  (note: for XP this is only the half of the prerequisites. Tested and working with VS 2026)\n\n7. Fill options\n\n   - ImageSeq.DLL\n\n     This plugin has external dependencies: DevIL SDK headers and libraries \n     are no longer included as a copy in Avisynth repo since 2024.\n\n     In order to be able to debug them we'd need to download and set some things manually.\n     \n     Download and extract DevIL SDK into a folder. In our example it is ``C:/avsplus_build_deps/DevIL Windows SDK/``.\n     See :ref:`devil_prebuilt_sdk_section1` and :ref:`devil_prebuilt_sdk_section2` for more details.\n\n     Manually edit CMAKE GUI options (x64 example): \n\n     * BUILD_IMAGESEQ [X]\n     * ``ILU_LIBRARIES`` ``C:/avsplus_build_deps/DevIL Windows SDK/lib/x64/Release/ILU.lib``\n     * ``IL_INCLUDE_DIR`` ``c:\\avsplus_build_deps\\DevIL Windows SDK\\include\\IL``\n     * ``IL_LIBRARIES`` ``C:/avsplus_build_deps/DevIL Windows SDK/lib/x64/Release/DevIL.lib``\n     \n   - TimeStretch.DLL\n   \n     This plugin has external dependencies: SoundTouch project. Its source snapshot is \n     no longer included as a copy in Avisynth repo since 2024.\n     \n     See the :doc:`avsplus_external_deps_guide_manual` for more details.\n\n     * BUILD_TIMESTRETCH [X]\n     * ``SOUNDTOUCH`` ``... to be filled ...``\n     * ``SOUNDTOUCH_DIR`` ``... to be filled ...``\n\n8. Generate\n\n9. Open the generated solution (**slnx for VS2026**, sln for others) with Visual Studio GUI, build/debug\n\nNote: you can't have a solution file containing both x86 and x64 configuration at a time.\n\nCommand line\n~~~~~~~~~~~~\n\nExamples (assuming we are in ``avisynth-build`` folder)\nConfig (--config parameter) can be Debug, Release, RelWithDebInfo.\n\n**Visual Studio 2026**\n\n``msvc_2026_win64_cleanfirst.bat``\n\n::\n\n      @rem cd avisynth-build\n      del .\\CMakeCache.txt\n      del ..\\CMakeCache.txt\n      cmake .. -G \"Visual Studio 18 2026\" -A x64 -DWINXP_SUPPORT:bool=off -DBUILD_DIRECTSHOWSOURCE:bool=on -DENABLE_PLUGINS:bool=on -DENABLE_INTEL_SIMD:bool=ON\n      cmake --build . --config Release --clean-first\n\n``msvc_2026_win32_xp_sse_cleanfirst.bat`` \n\n::\n\n      @rem cd avisynth-build\n      del .\\CMakeCache.txt\n      del ..\\CMakeCache.txt\n      cmake .. -G \"Visual Studio 18 2026\" -A Win32 -T \"v141_xp\" -DMSVC_CPU_ARCH:string=\"SSE\" -DWINXP_SUPPORT:bool=on -DBUILD_DIRECTSHOWSOURCE:bool=on -DENABLE_PLUGINS:bool=on -DENABLE_INTEL_SIMD:bool=ON\n      cmake --build . --config Release --clean-first\n\n\n**Visual Studio 2022**\n\n\n``msvc_2022_win64_cleanfirst.bat``\n\n::\n\n      @rem cd avisynth-build\n      del .\\CMakeCache.txt\n      cmake .. -G \"Visual Studio 17 2022\" -A x64 -DWINXP_SUPPORT:bool=off -DBUILD_DIRECTSHOWSOURCE:bool=on -DENABLE_PLUGINS:bool=on -DENABLE_INTEL_SIMD:bool=ON\n      cmake --build . --config Release --clean-first\n\n\n``msvc_2022_win64_cuda_plugins_allowed_cleanfirst.bat``\n\n::\n\n      @rem cd avisynth-build\n      del .\\CMakeCache.txt\n      cmake .. -G \"Visual Studio 17 2022\" -A x64 -DENABLE_CUDA:bool=on -DWINXP_SUPPORT:bool=off -DBUILD_DIRECTSHOWSOURCE:bool=on -DENABLE_PLUGINS:bool=on -DENABLE_INTEL_SIMD:bool=ON\n      cmake --build . --config Release --clean-first\n\n``msvc_2022_win32_xp_sse_cleanfirst.bat`` \n\n::\n\n      @rem cd avisynth-build\n      del .\\CMakeCache.txt\n      cmake .. -G \"Visual Studio 17 2022\" -A Win32 -T \"v141_xp\" -DMSVC_CPU_ARCH:string=\"SSE\" -DWINXP_SUPPORT:bool=on -DBUILD_DIRECTSHOWSOURCE:bool=on -DENABLE_PLUGINS:bool=on -DENABLE_INTEL_SIMD:bool=ON\n      cmake --build . --config Release --clean-first\n\n\n``msvc_2022_win64_xp_cleanfirst.bat``\n\n::\n\n      @rem cd avisynth-build\n      del .\\CMakeCache.txt\n      cmake .. -G \"Visual Studio 17 2022\" -A x64 -T \"v141_xp\" -DWINXP_SUPPORT:bool=on -DBUILD_DIRECTSHOWSOURCE:bool=on -DENABLE_PLUGINS:bool=on -DENABLE_INTEL_SIMD:bool=ON\n      cmake --build . --config Release --clean-first\n\n\n**Visual Studio 2019**\n\n``msvc_win64_cleanfirst.bat``\n\n::\n\n      @rem cd avisynth-build\n      del .\\CMakeCache.txt\n      cmake .. -G \"Visual Studio 16 2019\" -A x64 -DENABLE_CUDA:bool=on -DWINXP_SUPPORT:bool=off -DBUILD_DIRECTSHOWSOURCE:bool=on -DENABLE_PLUGINS:bool=on -DENABLE_INTEL_SIMD:bool=ON\n      cmake --build . --config Release --clean-first\n\n\n``msvc_win32_xp_sse_cleanfirst.bat`` \n\n::\n\n      @rem cd avisynth-build\n      del .\\CMakeCache.txt\n      cmake .. -G \"Visual Studio 16 2019\" -A Win32 -T \"v141_xp\" -DMSVC_CPU_ARCH:string=\"SSE\" -DWINXP_SUPPORT:bool=on -DBUILD_DIRECTSHOWSOURCE:bool=on -DENABLE_PLUGINS:bool=on -DENABLE_INTEL_SIMD:bool=ON\n      cmake --build . --config Release --clean-first\n\n``msvc_win64_xp_cleanfirst.bat``\n\n::\n\n      @rem cd avisynth-build\n      del .\\CMakeCache.txt\n      cmake .. -G \"Visual Studio 16 2019\" -A x64 -T \"v141_xp\" -DWINXP_SUPPORT:bool=on -DBUILD_DIRECTSHOWSOURCE:bool=on -DENABLE_PLUGINS:bool=on -DENABLE_INTEL_SIMD:bool=ON\n      cmake --build . --config Release --clean-first\n\n\n``msvc_win32_xp_nointel_cleanfirst.bat``\n\n::\n\n    @rem cd avisynth-build\n    del .\\CMakeCache.txt\n    cmake .. -G \"Visual Studio 16 2019\" -A Win32 -T \"v141_xp\" -DMSVC_CPU_ARCH:string=\"SSE\" -DWINXP_SUPPORT:bool=on -DBUILD_DIRECTSHOWSOURCE:bool=on -DENABLE_PLUGINS:bool=on -DENABLE_INTEL_SIMD:bool=OFF\n    cmake --build . --config Release --clean-first\n\n\n\n\n\nBuilding with Intel C++ Compiler ICX (IntelLLVM) or ICL (Windows)\n-----------------------------------------------------------------\n\nPrerequisites:\n~~~~~~~~~~~~~~\n\nUseful link:\n\n`<https://www.intel.com/content/www/us/en/developer/articles/news/free-intel-software-developer-tools.html>`_\n\nWe need Intel oneAPI Base Kit for LLVM based compiler and optionally oneAPI HPC Toolkit for the classic C++ compiler.\n\n- Download Intel® oneAPI DPC++/C++ Compiler\n\n  - `<https://www.intel.com/content/www/us/en/developer/tools/oneapi/toolkits.html#base-kit>`_\n\n    Download the base kit.\n\n    `<https://www.intel.com/content/www/us/en/developer/tools/oneapi/base-toolkit-download.html>`_\n\n    Choose online or offline installer.\n\n    DPC++/C++ is compulsory (we need then only Intel C++; DPC++ is not suitable for Avisynth)\n\n    Save disk space: No Math kernel Library, No Video Processing, No Deep Neural\n\n  - Choose IDE Integration: Visual Studio 2022 (or 2019)\n\n- Optionally: download component for C++\n\n  - `<https://www.intel.com/content/www/us/en/developer/tools/oneapi/toolkits.html#hpc-kit>`_\n  - Intel® oneAPI HPC Toolkit for Windows\n  - Why: Intel® C++ Compiler Classic 19.2 (will be discontinued)\n  - Choose Custom Installation (Fortran support not needed)\n\nHowto: `<https://www.intel.com/content/www/us/en/developer/articles/technical/using-oneapi-compilers-with-cmake-in-visual-studio.html>`_\n\nThere are two main flavours which we can use (DPC++ is not compatible with Avisynth)\n\n- Intel® NextGen Compiler (in base kit, LLVM based)\n\n  - TOOLSET = \"Intel C++ Compiler 2025\", COMPILER EXE NAME = icx.exe\n  - TOOLSET = \"Intel C++ Compiler 2024\", COMPILER EXE NAME = icx.exe\n  - TOOLSET = \"Intel C++ Compiler 2023\", COMPILER EXE NAME = icx.exe\n  - TOOLSET = \"Intel C++ Compiler 2022\", COMPILER EXE NAME = icx.exe\n  - TOOLSET = \"Intel C++ Compiler 2021\", COMPILER EXE NAME = icx.exe\n\n- Intel® Classic Compiler (in extra HPC kit)\n\n  - TOOLSET = \"Intel C++ Compiler 19.2\", COMPILER EXE NAME = icl.exe\n\n  Note that this classic compiler will get discontinued, as of late 2023.\n\nOnce installed first one or both, check some files.\n\nCMake integration and support files\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n1. For Intel C++ Compiler 2025:\n\n   Info from: c:\\\\Program Files (x86)\\\\Intel\\\\oneAPI\\\\compiler\\\\latest\\\\lib\\\\cmake\\\\IntelDPCPP\\\\ReadMeDPCPP.txt\n\n   Copy\n\n     c:\\\\Program Files (x86)\\\\Intel\\\\oneAPI\\\\compiler\\\\latest\\\\lib\\\\cmake\\\\IntelDPCPP\\\\IntelDPCPPConfig.cmake\n\n   and\n\n     c:\\\\Program Files (x86)\\\\Intel\\\\oneAPI\\\\compiler\\\\latest\\\\lib\\\\cmake\\\\IntelDPCPP\\\\IntelDPCPPConfigVersion.cmake\n\n   to\n\n    c:\\\\Program Files\\\\CMake\\\\share\\\\cmake-3.25\\\\Modules\\\\IntelDPCPP\\\\\n\n2. For Intel C++ Compiler 2024:\n\n   Info from: c:\\\\Program Files (x86)\\\\Intel\\\\oneAPI\\\\compiler\\\\latest\\\\lib\\\\cmake\\\\IntelDPCPP\\\\ReadMeDPCPP.txt\n\n   Copy\n\n     c:\\\\Program Files (x86)\\\\Intel\\oneAPI\\\\compiler\\\\latest\\\\windows\\\\IntelDPCPP\\\\IntelDPCPPConfig.cmake\n\n   and\n\n     c:\\\\Program Files (x86)\\\\Intel\\oneAPI\\\\compiler\\\\latest\\\\windows\\\\IntelDPCPP\\\\IntelDPCPPConfigVersion.cmake\n\n   to\n\n    c:\\\\Program Files\\\\CMake\\\\share\\\\cmake-3.25\\\\Modules\\\\\n\n\n3. For Intel C++ Compiler 2023:\n\n   Info from: c:\\\\Program Files (x86)\\\\Intel\\\\oneAPI\\\\compiler\\\\latest\\\\windows\\\\IntelDPCPP\\\\ReadMe.txt\n\n   Copy\n\n     c:\\\\Program Files (x86)\\\\Intel\\oneAPI\\\\compiler\\\\latest\\\\windows\\\\IntelDPCPP\\\\IntelDPCPPConfig.cmake\n\n   to\n\n    c:\\\\Program Files\\\\CMake\\\\share\\\\cmake-3.25\\\\Modules\\\\\n\n\n4. For Intel C++ Compiler 2021:\n\n   Info from: c:\\\\Program Files (x86)\\\\Intel\\\\oneAPI\\\\compiler\\\\latest\\\\windows\\\\cmake\\\\SYCL\\\\\n\n   Copy\n\n     c:\\\\Program Files (x86)\\\\Intel\\\\oneAPI\\\\compiler\\\\latest\\\\windows\\\\cmake\\\\SYCL\\\\FindIntelDPCPP.cmake\n\n   to\n\n     c:\\\\Program Files\\\\CMake\\\\share\\\\cmake-3.20\\\\Modules\\\\\n\nNote: Intel C++ Compilers need Cmake 3.22.3 (Windows) or 3.22.1 (Linux) as a minimum (as of Intel 2024 or 2025)\n\n\nFrom CMake GUI:\n~~~~~~~~~~~~~~~\n\n1. Delete Cache\n2. ``Where is source code`` and ``Where to build binaries``: git project folder e.g. C:/Github/AviSynthPlus\n3. Press Configure\n4. Choose an available generator:\n\n  - `Visual Studio 18 2026` (requires CMake 4.2+, solution generated for VS2026)\n  - `Visual Studio 17 2022` (solution will be generated for VS2022)\n  - `Visual Studio 16 2019` (solution will be generated for VS2019)\n\n5. Choose optional platform generator: default is `x64` when left empty, `Win32` is another option\n6. Set ``Optional toolset to use (-T option)``:\n\n  - For LLVM based icx:\n   \n    - `Intel C++ Compiler 2025` or\n    - `Intel C++ Compiler 2024` or\n    - `Intel C++ Compiler 2023` or\n    - `Intel C++ Compiler 2022` or\n    - `Intel C++ Compiler 2021`\n\n  - For classic icl:\n\n    - `Intel C++ Compiler 19.2`\n\n7. Specify native compilers (checkbox): browse for the appropriate compiler executable path.\n\n  - Intel C++ Compiler 2025:\n\n    - icx: c:\\\\Program Files (x86)\\\\Intel\\\\oneAPI\\\\compiler\\\\latest\\\\bin\\\\icx.exe\n\n  - Intel C++ Compiler 2024:\n\n    - icx: C:\\\\Program Files (x86)\\\\Intel\\\\oneAPI\\\\compiler\\\\latest\\\\windows\\\\bin\\\\icx.exe\n    - icl: C:\\\\Program Files (x86)\\\\Intel\\\\oneAPI\\\\compiler\\\\latest\\\\windows\\\\bin\\\\intel64\\\\icl.exe\n\nIf you have errors like ``xilink: : error : Assertion failed (shared/driver/drvutils.c, line 312`` then\nas a workaround you must copy clang.exe (by default it is located in C:\\\\Program Files (x86)\\\\Intel\\\\oneAPI\\\\compiler\\\\latest\\\\windows\\\\bin)\nto the folder beside xilink (for x64 configuration it is in C:\\\\Program Files (x86)\\\\Intel\\\\oneAPI\\\\compiler\\\\latest\\\\windows\\\\bin\\\\intel64).\n\nSuccessful log looks like:\n\n(Note: If CXX compiler is not the Intel one, then you probably missed step #7.)\n\n::\n\n      The CXX compiler identification is IntelLLVM 2025.0.0 with MSVC-like command-line\n      Check for working CXX compiler: C:/Program Files (x86)/Intel/oneAPI/compiler/2025.0/bin/icx.exe\n\nor\n\n::\n\n      The CXX compiler identification is IntelLLVM 2023.0.0 with MSVC-like command-line\n      Check for working CXX compiler: C:/Program Files (x86)/Intel/oneAPI/compiler/2023.0.0/windows/bin/icx.exe\n\nor\n\n::\n\n      The CXX compiler identification is IntelLLVM 2021.4.0 with MSVC-like command-line\n      Check for working CXX compiler: C:/Program Files (x86)/Intel/oneAPI/compiler/2021.4.0/windows/bin/icx.exe\n\nor (classic 19.2 version downloaded in 2023)\n\n::\n\n      The CXX compiler identification is Intel 2021.8.0.20221119\n      Check for working CXX compiler: C:/Program Files (x86)/Intel/oneAPI/compiler/2023.0.0/windows/bin/intel64/icl.exe - skipped\n\nor (classic 19.2 version downloaded in 2021)\n\n::\n\n      The CXX compiler identification is Intel 2021.4.0.20210910\n      Check for working CXX compiler: C:/Program Files (x86)/Intel/oneAPI/compiler/2021.4.0/windows/bin/intel64/icl.exe\n\n8. Fill options, Generate\n9. Open the generated solution with Visual Studio GUI, build/debug\n10. Note that the built program would need Intel redistributable components or else you may face errors that dependencies\n    could not be loaded: svml_dispmd.dll and libmmd.dll. Check Intel OneAPI Redistributable package at:\n\n    `<https://www.intel.com/content/www/us/en/developer/articles/tool/compilers-redistributable-libraries-by-version.html>`_\n\n\nCommand line\n~~~~~~~~~~~~\n\nExamples (assuming we are in ``avisynth-build`` folder). Config can be Debug, Release, RelWithDebInfo.\n\n``x_icl_cleanfirst.bat`` \n\n::\n\n      @rem cd avisynth-build\n      del .\\CMakeCache.txt\n      C:\\Program Files (x86)\\Intel\\oneAPI\\setvars.bat\n      cmake ../ -T \"Intel C++ Compiler 19.2\" -DCMAKE_CXX_COMPILER=\"icl.exe\" -DBUILD_DIRECTSHOWSOURCE:bool=off -DENABLE_PLUGINS:bool=on -DENABLE_INTEL_SIMD:bool=ON\n      cmake --build . --config Debug --clean-first\n\n``x_icx_cleanfirst.bat``\n\n::\n\n      @rem cd avisynth-build\n      del .\\CMakeCache.txt\n      C:\\Program Files (x86)\\Intel\\oneAPI\\setvars.bat\n      cmake ../ -T \"Intel C++ Compiler 2025\" -DCMAKE_CXX_COMPILER=\"icx.exe\" -DBUILD_DIRECTSHOWSOURCE:bool=off -DENABLE_PLUGINS:bool=on -DENABLE_INTEL_SIMD:bool=ON\n      cmake --build . --config Debug --clean-first\n\n``x_icx_cleanfirst_no_simd.bat``\nThis one will build only Avisynth.dll, no external plugins, plain C code (no SIMD)\n\n::\n\n      @rem cd avisynth-build\n      del .\\CMakeCache.txt\n      C:\\Program Files (x86)\\Intel\\oneAPI\\setvars.bat\n      cmake ../ -T \"Intel C++ Compiler 2025\" -DCMAKE_CXX_COMPILER=\"icx.exe\" -DBUILD_DIRECTSHOWSOURCE:bool=off -DENABLE_PLUGINS:bool=OFF -DENABLE_INTEL_SIMD:bool=OFF\n      cmake --build . --config Debug --clean-first\n\n\nBuilding with Clang\n-------------------\n\nCommand line: todo\n\nUsing Cmake GUI:\n~~~~~~~~~~~~~~~~\n\n1. Delete Cache\n2. ``Where is source code`` and ``Where to build binaries``: git project folder e.g. C:/Github/AviSynthPlus\n3. Press Configure\n4. Choose generator:\n\n   - `Visual Studio 18 2026` (solution will be generated for VS2026)\n   - `Visual Studio 17 2022` (solution will be generated for VS2022)\n   - `Visual Studio 16 2019` (solution will be generated for VS2019)\n\n5. Choose optional platform generator: default is `x64` when left empty, `Win32` is another option\n6. Set ``Optional toolset to use (-T option)``:\n\n  Type ``llvm`` or ``clangcl``\n\n  clangcl (Clang-cl) comes with Visual Studio.\n\n  for native LLVM you may need to specify native compilers (checkbox): browse for the appropriate compiler executable path.\n\n  Hint: How to install Clang-cl in Visual Studio:\n\n  Tools|Get Tools and Features|Add Individual Components|Compilers, build tools, and runtimes\n\n  For VS2026:\n    - [X] C++ Clang compiler for Windows\n    - [X] MSBuild support for LLVM (clang-cl) toolset\n\n  For VS2019/2022:\n    - [X] C++ Clang compiler for Windows\n    - [X] C++ Clang-cl for v142/v143 build tools (x64/x86)\n\n7. Fill options, Generate\n8. Open the generated solution with Visual Studio GUI, build/debug\n\n\nBuilding with GCC\n-----------------\n\nAviSynth+ can be built with GCC two different ways: using MSys2 as a native toolchain,\nor cross-compiled under another OS such as a Linux distribution.\n\nBuilding with GCC in MSys2\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nLaunch MSys2 and install GCC and Ninja:\n::\n\n    pacman -S mingw64/mingw-w64-x86_64-gcc gcc mingw64/ninja mingw32/ninja mingw32/mingw-w64-i686-gcc\n\nGrab the AviSynth+ source code:\n::\n\n    cd $HOME && \\\n    git clone https://github.com/AviSynth/AviSynthPlus && \\\n    cd AviSynthPlus && \\\n    mkdir -p avisynth-build/i686 avisynth-build/amd64\n\nIf you were in the MSys2 MSYS prompt, open the MinGW32 prompt, then navigate into\nthe build directory, build AviSynth+, and install it:\n::\n\n    cd $HOME/AviSynthPlus/avisynth-build/i686 && \\\n        cmake ../../ -G \"Ninja\" -DCMAKE_INSTALL_PREFIX=$HOME/avisynth+_build/32bit \\\n        -DBUILD_SHIBATCH:bool=off && \\\n    ninja && \\\n    ninja install\n\n(The Shibatch plugin currently has issues on GCC, so disable it for now.\nDirectShowSource also has issues, but it doesn't get built by default.)\n\nOpen the MinGW64 prompt now, navigate into the build directory, build AviSynth+, and install it:\n::\n\n    cd $HOME/AviSynthPlus && \\\n    AVSDIRNAME=avisynth+_r$(git rev-list --count HEAD)-g$(git rev-parse --short HEAD)-$(date --rfc-3339=date | sed 's/-//g') && \\\n    cd avisynth-build/amd64 && \\\n        cmake ../../ -G \"Ninja\" -DCMAKE_INSTALL_PREFIX=$HOME/avisynth+_build/64bit \\\n        -DBUILD_SHIBATCH:bool=off && \\\n    ninja && \\\n    ninja install\n\n(The Shibatch plugin currently has issues on GCC, so disable it for now.\nDirectShowSource also has issues, but it doesn't get built by default.)\n\n\nFinishing up\n............\n\nNow, without leaving the MinGW64 prompt, package the binaries up in a 7zip archive:\n::\n\n    mv $HOME/avisynth+_build $HOME/$AVSDIRNAME && \\\n    7za a -mx9 ~/$AVSDIRNAME.7z ~/$AVSDIRNAME\n\n.. _compiling_avsplus_crosscompiling1:\n\nCross-compiling with GCC (Version #1)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nFor ease of explanation, we'll assume Ubuntu Linux.  The method to cross-compile under\nmost distributions is largely the same, so don't worry about that.\n\nUbuntu's repositories lag behind upstream GCC releases, and my current build\ninstructions are built around a most-recent-stable version of GCC and MinGW.\nThe full instructions for that are contained in the first section of\n`<https://github.com/qyot27/mpv/blob/extra-new/DOCS/crosscompile-mingw-tedious.txt>`_\n\nDownload the source code and prepare the build directories:\n::\n\n    git clone https://github.com/AviSynth/AviSynthPlus && \\\n    cd AviSynthPlus && \\\n    mkdir -p avisynth-build/i686 avisynth-build/amd64 && \\\n    AVSDIRNAME=avisynth+-gcc_r$(git rev-list --count HEAD)-g$(git rev-parse --short HEAD)-$(date --rfc-3339=date | sed 's/-//g') && \\\n\n32-bit:\n::\n\n    cd avisynth-build/i686 && \\\n        cmake ../../ -G \"Ninja\" -DCMAKE_INSTALL_PREFIX=$HOME/avisynth+_build/32bit \\\n        -DCMAKE_TOOLCHAIN_FILE=\"/usr/x86_64-w64-mingw32/toolchain-x86_64-w64-mingw32.cmake\" \\\n        -DCMAKE_C_FLAGS=\"-m32\" -DCMAKE_CXX_FLAGS=\"-m32\" -DCMAKE_RC_FLAGS=\"-F pe-i386\" \\\n        -DBUILD_SHIBATCH:bool=off && \\\n    ninja && \\\n    ninja install\n\n64-bit:\n::\n\n    cd ../amd64 && \\\n        cmake ../../ -G \"Ninja\" -DCMAKE_INSTALL_PREFIX=$HOME/avisynth+_build/64bit \\\n        -DCMAKE_TOOLCHAIN_FILE=\"/usr/x86_64-w64-mingw32/toolchain-x86_64-w64-mingw32.cmake\" \\\n        -DBUILD_SHIBATCH:bool=off && \\\n    ninja && \\\n    ninja install\n\n.. _compiling_avsplus_crosscompiling2:\n\nCross-compiling with GCC (Version #2)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n**AviSynth+ cross-compilation Guide (On Ubuntu to create Windows, MinGW-w64)**\n\n**Using POSIX-threaded MinGW toolchains (x86 and x64)**\n\nThis document describes how to cross‑compile **AviSynth+** for **Windows 32-bit (x86)** and \n**Windows 64-bit (x64)** from a Linux (Ubuntu) system using the **MinGW-w64 GCC** toolchain.\n\nThe guide includes fixes for:\n\n*   `std::mutex` / POSIX thread model issues\n*   CMake/Ninja RPATH errors\n*   32-bit vs. 64-bit toolchain selection\n*   SSE2/MMX intrinsic mismatches\n*   Packaging and dependency notes\n\nThis guide is verified against Ubuntu 22.04 and MinGW-w64 POSIX compilers.\n\n\n1. Overview\n...........\n\nAviSynth+ uses C++11 threading primitives (e.g. `std::mutex`, `std::thread`), which require\nthe **POSIX** flavor of MinGW-w64. \nUbuntu provides separate cross-compilers for:\n\n*    i686-w64-mingw32        => 32-bit Windows target\n*    x86_64-w64-mingw32      => 64-bit Windows target\n\nUbuntu MinGW packages are not multilib; the 64-bit compiler cannot build 32-bit code.\nYou must use **two toolchains**.\n\n2. Prerequisites\n................\n\nInstall all needed packages:\n\n.. code-block:: bash\n\n    sudo apt update \\\n    sudo apt install git cmake ninja-build mingw-w64 p7zip-full\n\nNinja is used for fast builds; p7zip is recommended for the final package.\n\n3. About the POSIX Threading Model\n..................................\n\nMinGW-w64 provides two threading backends:\n\n*   **win32** (default on older distros)\n*   **posix** (required for `std::mutex` and modern C++ threading)\n\nEven on modern systems, *you must explicitly use the POSIX compiler variants*:\n\n*    i686-w64-mingw32-g++-posix\n*    x86_64-w64-mingw32-g++-posix\n\nYou may *optionally* configure update-alternatives:\n\n.. code-block:: bash\n\n    sudo update-alternatives --set i686-w64-mingw32-gcc /usr/bin/i686-w64-mingw32-gcc-posix \\\n    sudo update-alternatives --set i686-w64-mingw32-g++ /usr/bin/i686-w64-mingw32-g++-posix \\\n    sudo update-alternatives --set x86\\_64-w64-mingw32-gcc /usr/bin/x86\\_64-w64-mingw32-gcc-posix \\\n    sudo update-alternatives --set x86\\_64-w64-mingw32-g++ /usr/bin/x86\\_64-w64-mingw32-g++-posix\n\n.. note::\n   **This is optional.**\n   The CMake commands below explicitly select the correct compilers, so you do **not** need to modify system defaults.\n\n4. Get the Source\n.................\n\nAnd create a reproducible output directory name.\n\n.. code-block:: bash\n\n    git clone https://github.com/AviSynth/AviSynthPlus \\\n    cd AviSynthPlus \\\n    mkdir -p avisynth-build/i686 avisynth-build/amd64 \\\n    AVSDIRNAME=avisynth+-gcc\\_r$(git rev-list --count HEAD)-g$(git rev-parse --short HEAD)-$(date +%Y%m%d)\n\n5. Build for 32-bit Windows (i686)\n..................................\n\nAviSynth+ internally applies SIMD and intrinsic flags based on `CMAKE_SYSTEM_PROCESSOR`.  \nTo avoid “target-specific option mismatch” errors, explicitly set it to `i686`.\n\nUbuntu MinGW is not multilib, so you **must use** the dedicated 32-bit toolchain.\n\n.. code-block:: bash\n\n    cd avisynth-build/i686\n\n    cmake ../../ -G Ninja \\\n    -DCMAKE\\_SYSTEM\\_NAME=Windows \\\n    -DCMAKE\\_SYSTEM\\_PROCESSOR=i686 \\\n    -DCMAKE\\_BUILD\\_TYPE=Release \\\n    -DCMAKE\\_SKIP\\_RPATH=TRUE \\\n    -DCMAKE\\_INSTALL\\_PREFIX=\"$HOME/avisynth+\\_build/32bit\" \\\n    -DCMAKE\\_C\\_COMPILER=i686-w64-mingw32-gcc-posix \\\n    -DCMAKE\\_CXX\\_COMPILER=i686-w64-mingw32-g++-posix \\\n    -DBUILD\\_SHIBATCH:BOOL=off\n\n    ninja\n    ninja install\n\nNotes\n^^^^^\n\n*   `CMAKE_SKIP_RPATH=TRUE` eliminates CMake/Ninja install-RPATH relinking failures.\n*   SSE2 is always enabled via AviSynth+ internal logic for 32-bit builds.\n\n6. Build for 64-bit Windows (x86\\_64)\n.....................................\n\n.. code-block:: bash\n\n    cd ../amd64\n\n    cmake ../../ -G Ninja \\\n      -DCMAKE_SYSTEM_NAME=Windows \\\n      -DCMAKE_SYSTEM_PROCESSOR=x86_64 \\\n      -DCMAKE_BUILD_TYPE=Release \\\n      -DCMAKE_SKIP_RPATH=TRUE \\\n      -DCMAKE_INSTALL_PREFIX=\"$HOME/avisynth+_build/64bit\" \\\n      -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc-posix \\\n      -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++-posix \\\n      -DBUILD_SHIBATCH:BOOL=off\n\n    ninja\n    ninja install\n\n\nNotes\n^^^^^\n\n*   All x86-64 CPUs support SSE2, so no special flags are required.\n*   POSIX compiler ensures correct C++11 threading.\n\n7. Packaging\n............\n\n.. code-block:: bash\n\n    cd \\~ \\\n    mv avisynth+\\_build \"$AVSDIRNAME\" \\\n    7za a -mx9 \"$AVSDIRNAME.7z\" \"$AVSDIRNAME\"\n\nYou now have:\n\n    <name>.7z\n        /32bit  → aviynth.dll + includes + plugins\n        /64bit  → same for x64\n\n8. Runtime Dependencies\n.......................\n\nPOSIX thread model dependency\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nBuilds produced with the POSIX toolchain require:\n\n    libwinpthread-1.dll\n\nThis is expected and normal.\n\nPlace this DLL next to `avisynth.dll` or ship it with your application.\n\nStatic linking\n^^^^^^^^^^^^^^\n\nTo produce a DLL with no external MinGW dependencies, you can try forcing the linker to use static archives. \nNote that this may require specific library files to be present in your Ubuntu environment.\n\n.. code-block:: bash\n\n   # Add these to your CMake command:\n   -DCMAKE_CXX_FLAGS=\"-static-libgcc -static-libstdc++\" \\\n   -DCMAKE_SHARED_LINKER_FLAGS=\"-Wl,-Bstatic -lstdc++ -lwinpthread -Wl,-Bdynamic\"\n\n**This is advanced.** Fully static POSIX builds are fragile on Ubuntu. If the linker cannot \nfind ``libwinpthread.a``, the build will fail. Additionally, static linking in a DLL can cause \nissues with memory management if plugins also statically link their runtimes.\n\nShipping libwinpthread-1.dll alongside avisynth.dll is the recommended and most stable approach.\n\n9. Known Pitfalls and Fixes\n...........................\n\n9.1 Ninja RPATH errors\n^^^^^^^^^^^^^^^^^^^^^^\n\n\nIf you see:\n\n    The install of <target> requires changing an RPATH ...\n    not supported with Ninja ...\n\nAlways ensure:\n\n    -DCMAKE_SKIP_RPATH=TRUE\n\nThis avoids relinking steps which do not apply to Windows binaries.\n\n9.2 Intrinsic \"Target specific option mismatch\" errors\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nOccurs when the CPU type is not set properly.\n\nFix: set\n\n    -DCMAKE_SYSTEM_PROCESSOR=i686\n\nfor 32-bit builds.\n\n9.3 Mixing win32 and posix toolchains\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nNever mix:\n\n*    i686-w64-mingw32-g++   (win32 threading)\n*    i686-w64-mingw32-g++-posix  (POSIX threading)\n\nThis causes:\n\n*   Missing `std::mutex`\n*   ABI mismatches\n*   Linker errors involving `dllimport` or winpthreads\n\n9.4 Redefinition of CRT functions (`_strlwr`, `_strupr`, etc.)\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nMinGW-w64 already provides these.\nWhen you encounter this, MINGW was not properly detected by CMake, for example\ndue to a missing `-DCMAKE_SYSTEM_NAME=Windows`. Normally, the directory of \ncompatibility string util helpers is omitted.\n\nIf still building AviSynth+ with a compatibility layer, guard the definitions using:\n\n.. code-block::\n\n    #if !defined(MINGW32) && !defined(MINGW64)\n    /* custom implementations */\n    #endif\n\n10. **Understanding \"Install\" During Cross-Compilation**\n........................................................\n\nWhen building AviSynth+ for Windows using a Linux host system (Ubuntu), `ninja install` may \nappear confusing at first - after all, **Ubuntu cannot load or execute Windows DLLs**.\nHowever, the *install* step in a cross-compilation context **does not mean installing software \non Ubuntu**. Instead, it serves a very different and critically important purpose.\n\nThis section explains **what the install step really does**, **why it is needed**, and **how it fits into the cross-compile workflow**.\n\n10.1. What “Install” *Does NOT* Mean\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nIt does **not** mean any of the following:\n\n*   Installing AviSynth+ into Ubuntu’s system libraries\n*   Making Ubuntu able to load or use AviSynth.dll\n*   Registering anything system-wide\n*   Enabling AviSynth+ on Linux\n\nNone of that happens.\n\nUbuntu cannot run or link Windows binaries; the Windows DLLs are **not** for the host system at all.\n\n10.2. What “Install” *Actually Means* in Cross‑Compilation\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nIn a cross-build scenario, the install step simply:\n\n**Creates a Windows-style filesystem layout inside a directory on Linux**\n\nThis includes folders like:\n\n*    bin/         → Windows executables and DLLs  \n*    lib/         → import libraries, pkgconfig files  \n*    include/     → headers for Windows development  \n*    lib/avisynth/ → internal plugins  \n\n**Collects all produced build artifacts in one clean prefix**\n\nInstead of having binaries scattered through CMake’s intermediate directories, the install step:\n\n*   copies the DLL\n*   copies import libraries (`.dll.a`)\n*   copies headers\n*   copies built‑in plugins\n*   creates `pkgconfig` files\n\ninto the exact structure expected by Windows build systems.\n\n**Produces the folder you will later package or ship to Windows**\n\nYour install prefix:\n\n    ``$HOME/avisynth+_build/64bit/``\n\nis not a Linux installation - it is a **staging directory** representing what would be a real \ninstallation on a Windows filesystem.\n\nYou can zip or 7-zip this folder and distribute it.\n\n10.3. Why \"Install\" Is Required\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n**(A) To build a proper Windows release**\n\nAviSynth+, FFmpeg, Qt, LLVM, and almost all cross-built libraries **use the install phase** \nto generate their final, distributable layout.\n\nThis ensures your release archive has:\n\n*   the correct include paths\n*   the correct lib paths\n*   the correct bin path\n*   consistent plugin locations\n*   accurate metadata (`pkgconfig`, `version.h`, etc.)\n\n**(B) To separate build artifacts from install artifacts**\n\nThe **build tree** contains:\n\n*   temporary object files\n*   CMake intermediate files\n*   Ninja rules\n*   dependency databases\n*   incremental build caches\n\nThis tree is **not a clean or portable output**.\n  \nThe install tree is.\n\n**(C) For dependent projects to find AviSynth+**\n\nIf someone cross-compiles a project that depends on AviSynth+, it can use:\n\n.. code-block:: bash\n\n   pkg-config --cflags --libs avisynth``\n\nThis only works because the install step generates:\n\n    ``lib/pkgconfig/avisynth.pc``\n\ncontaining the correct Windows paths.\n\n**(D) For plugin builds**\n\nPlugins expect:\n::\n\n    include/avisynth/...\n    lib/AviSynth.dll.a\n\nThese are only collected during *install*.\n\n10.4. Example: Installed Output Structure\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nAfter:\n\n.. code-block:: bash\n\n   ninja install\n\nYou get something like (in your home directory ~):\n::\n\n    avisynth+_build/64bit/\n    ├── bin/\n    │   └── AviSynth.dll\n    ├── lib/\n    │   ├── AviSynth.dll.a\n    │   └── pkgconfig/\n    │       └── avisynth.pc\n    ├── include/\n    │   └── avisynth/\n    │       ├── avisynth.h\n    │       ├── avs/\n    │       └── ...\n    └── lib/avisynth/\n        ├── ConvertStacked.dll\n        └── ConvertStacked.dll.a\n\nAnd similarly, for 32bit.\n\nEverything here is intended to be **copied to Windows**, not used on Ubuntu.\n\n10.5. What Happens If You Skip `ninja install`?\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nYou would be left with:\n\n*   scattered build outputs\n*   missing import libraries\n*   missing pkgconfig file\n*   missing plugin installation\n*   headers buried in the source tree\n\nYour build would not be package‑ready.\n\nIn short: *you could not produce a proper Windows release.*\n\n10.6. Summary\n^^^^^^^^^^^^^\n\nThe install step is **not installation on Ubuntu**.  \nIt is:\n\n**“Exporting the Windows build into a clean, structured staging directory.”**\n\nThis directory is then:\n\n*   packaged (e.g., `.7z` or `.zip`)\n*   used by plugin developers\n*   consumed by downstream Windows projects\n*   deployed to real Windows systems\n\nIt is an essential part of cross‑compiling AviSynth+.\n\n11. Summary\n...........\n\nThis guide provides a **fully correct, stable, reproducible** method to build AviSynth+ for Windows on Ubuntu.  \nIt works reliably for:\n\n*   Modern C++17 build environments\n*   Both 32-bit and 64-bit Windows\n*   Ninja + CMake workflows\n*   POSIX-threaded MinGW toolchains\n\n.. warning::\n\n    **Note on ABI compatibility**: This build uses the MinGW-w64 (GCC) ABI. While it is fully compatible with the \n    AviSynth C-API and most existing plugins, it is not binary-compatible with C++ plugins compiled \n    specifically for the MSVC ABI.\n\nFinishing up\n............\n\nPackaging:\n::\n\n    mv $HOME/avisynth+_build $HOME/$AVSDIRNAME\n    7za a -mx9 ~/$AVSDIRNAME.7z ~/$AVSDIRNAME\n\n\nBack to the :doc:`main page <../../index>`\n\n$ Date: 2026-01-25 21:00:00 +01:00 $"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/contributing/contributing_with_git.rst",
    "content": "\nContributing to AviSynth+\n=========================\n\nAviSynth+ uses `git`_ as its distributed version control system (DVCS) of choice.\nThis document is intended as a basic primer to help users unfamiliar with git,\nwhether they have previously contributed to classic AviSynth (which uses the\nConcurrent Versions System, a.k.a. CVS), or are completely new to the project.\nIt is not intended as a thorough treatment of any of these commands.  For that,\nyou can refer to the `Pro Git book`_.\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\nInstalling git\n--------------\n\nHow to install git varies, depending on your operating system.\n\nWindows\n~~~~~~~\n\nWindows users should have installed msys2 first, as described in\n:doc:`Compiling AviSynth+ <compiling_avsplus>`\n\nWith the msys2/mintty prompt open, install git:\n\n::\n\n    pacman -S msys/git\n\nThis is not the only way to install git on Windows, but considering\nthis tutorial is meant to dovetail with the compiling tutorial, this\nis the recommended way.\n\n\nLinux\n~~~~~\n\nYou can install git through your distribution's repositories.\n\n\nOS X\n~~~~\n\nAs per the instructions on the `git main site`_:\n\nOpen a Terminal by clicking on Spotlight and typing 'Terminal' (without the quotes).\nHit Enter and the Terminal will open.  Attempt to run git:\n\n::\n\n    git --version\n\nAnd it should prompt you to install the Xcode Command Line Tools.\n\n\nConfiguring git\n~~~~~~~~~~~~~~~\n\nIn all of these cases, there's some extra set up of git's configuration\nthat's recommended to make things easier.\n\n::\n\n    git config --global user.name \"Your Name\"\n\nUse the above command to set your name.\n\n::\n\n    git config --global user.email \"email address\"\n\nAnd set your email.\n\n::\n\n    git config --global core.editor \"nano\"\n\nThis will set the default editor as nano. nano is easier for new users to\nnavigate than vim, which is the default editor git uses on some platforms.\nThe editor choice matters because when you go to make a commit, the editor\nis activated to let you type up a commit message.\n\n::\n\n    git config --global core.whitespace \"trailing-space,space-before-tab\"\n\nThis tells git to warn you about whitespace errors in commits.\n\n::\n\n    git config --global apply.whitespace \"fix\"\n\nAnd this will tell git to attempt to fix any whitespace errors that are encountered.\n\n\nGithub\n------\n\nAviSynth+ hosts its code `on Github`_.  Users wishing to contribute to AviSynth+\nshould have their own account on Github as well.  Github's own tutorials will\nassist you in setting up your account and generating the correct authentication\nsignatures, so I won't be covering that part.\n\n\nForking\n-------\n\ngit as a whole relies on the concept of \"forking is good\", even though the way\nit plays out in reality is that such forks are more akin to personal branches,\nnot to a 'fork' in the way that projects sometimes break up and part ways (see:\nAviSynth+ and classic AviSynth, Libav and FFmpeg, LibreSSL and OpenSSL, etc.).\nGithub provides a streamlined way for these personal branches to submit their\nchanges back to the upstream project for inclusion.  This is what a 'pull request'\nis.  Of course, any of these personal branches could effect a fork the way\nthat term is traditionally understood, if the changes diverge too much from upstream\nand/or if upstream rejects the changes for any number of reasons.\n\nAnyway, now that your Github account is set up, navigate to AviSynth+'s repository\nand click the Fork button.\n\n.. image:: images/github-fork.png\n\nGithub will spawn an AviSynthPlus repository under your account, and give you\nthe command to clone a copy which you can use to push your changes to your\npersonal AviSynthPlus repo on Github.\n\n::\n\n    git clone git@github.com:<username>/AviSynthPlus.git\n\nThe command 'git clone' creates a copy of the AviSynth+ source code on your local\ncomputer.\n\nEnter the newly-created repo:\n\n::\n\n    cd AviSynthPlus\n\n\nRemotes\n-------\n\ngit allows you to keep track of the changes in multiple other repositories at once;\nthese are called 'remotes'.\n\nLogically, the first remote you should track is the upstream project, so that you\ncan grab any changes that occur upstream:\n\n::\n\n    git remote add upstream https://github.com/AviSynth/AviSynthPlus\n    git fetch upstream\n\nThis is a two-step process.  Let's break it down: *git remote* is the name of the\nmain command, 'add' is the command to tell *git remote* to add a new remote,\n'upstream' is the name you're assigning this new remote, and the URL is the location\nyou want to track.\n\n+------------+------------+----------+--------------------------------------------+\n| Command    | Subcommand | Name     | URL                                        |\n+============+============+==========+============================================+\n| git remote | add        | upstream | https://github.com/AviSynth/AviSynthPlus   |\n+------------+------------+----------+--------------------------------------------+\n\nOn its own, though, this only sets up the bookmark.  It doesn't\nactually get you the record of the changes.\n\n*git fetch* is what actually pulls in the record of the changes made to upstream,\nif any have been made.  It also shows a summary of which branches in upstream's repository\nhave been added, changed, or deleted.  *git fetch* does not integrate those changes into\nthe corresponding branches in your personal repository, so you can safely ignore\nchanges that may break your own changes, or if you want to divert a branch from upstream\ninto a differently-named branch locally.\n\nSo what happens if there *are* changes you want to stay current on?  Well, let's say\nthat the 'upstream' remote has two branches: *master* (the default name for the main branch\nof a repository created with git) and *feature*, which contains some extra things in the\nprocess of being developed.\n\n::\n\n    git merge upstream/master\n\nThis will merge the contents of upstream's 'master' branch into the branch you're currently\nsitting on.  If you've not made any changes at all to that branch, it should do a simple\nfast-forward, appearing as though you'd freshly cloned the repository with those commits\nalready present.  If there are any differences, it will end up with a merge commit.  In the\nworst-case scenario, conflicts arise.  git provides the *mergetool* command to help mediate\nthis, but the workflow for handling conflicts is beyond the scope of this primer.\n\n\nCheckouts\n---------\n\nSo dealing with *master* is all good and fine, but what if you want to work with\nthe *feature* branch?  To do that:\n\n::\n\n    git checkout feature\n\nWhich will move you onto the *feature* branch.  To move back to master, just use\n*git checkout* again:\n\n::\n\n    git checkout master\n\n\nBranching\n---------\n\nNow that you have your own AviSynth+ local repository and have created a remote to\ntrack upstream, you want to get to making your changes.  To keep the commit history\nclean, create a new branch with a unique name.  While it's possible to do this in\ntwo steps by using *git branch* and then *git checkout*, it's also possible to do\nit in one step with just *git checkout*:\n\n::\n\n    git checkout -b newbranch\n\nThis will create a branch from the branch you had just been on.  So if you're on\n*master*, *newbranch* will have all of the commits on *master* up to the point it\nwas created.\n\n\nCommitting\n----------\n\nWhen you've made some changes to one or multiple files, the next step is to commit them.\nThis means that the changes are logged into the git history of the repository, and\nif warranted, a patch can be created of only *those* changes.\n\n::\n\n    git status\n\nThis will show you all files that have been changed.\n\n.. image:: images/git_status.png\n\n\n::\n\n    git add file1 file2\n\nThis command tells git to track the changes of those files, readying them for a commit.\nIf you run *git status* again, the color of the text will have changed from brown to\ngreen, with a description prefixed to it:\n\n.. image:: images/git_status2.png\n\nAlternatively,\n\n::\n\n    git add .\n\nwill add all changed files.\n\n::\n\n    git commit\n\nWill do the actual commit (you can also combine *git add .* and *git commit* into one step by\nusing *git commit -a*).  At this point, nano (or the text editor of your choice) will\nappear:\n\n.. image:: images/git_commit.png\n\nType in a descriptive message about the changes, and then tell nano to exit (Ctrl+X), which will\nprompt you to approve the changes before it commits them.  Preferably, the commit message\nshould be formatted like this:\n\n::\n\n    *area*: *short description*\n\n    *long description, if necessary*\n\nThe short description should fall below the 80-character margin the rest of the text in nano\nadheres to. It makes it nicer for those browsing the log.\n\nMake sure that changes are topical.  Don't throw unrelated changes into the same commit.\nWhitespace and formatting changes should always be in separate commits unless it happens\nto be a consequence of the exact change made (a single space or newline disappearing\namidst changes all around it is one thing, but all the rest of the whitespace in the file\nchanging at once with unrelated changes interspersed throughout it is not okay).\n\n\nPushing\n-------\n\nPushing is the act of uploading the changes you've made to your repository to the\npublically-available URL that everyone else can see (in our case, your Github account).\n\n::\n\n    git push origin <branchname>\n\nWhere <branchname> is the name of the branch you're making available or updating.\n\n\nCreating a pull request\n-----------------------\n\nNow that you have your changes pushed up onto Github, you can make a pull request of\nthese changes back to AviSynth+.\n\nOn your personal AviSynth+ repository, use the 'Branch' button (1) to select the branch\nyou want to create a pull request from.  Then hit the 'New pull request' button (2) to\nhave Github create the pull request for you.\n\n.. image:: images/pullrequest.png\n\nOn the 'Open a pull request' page you can select exactly which branch and fork\nthe pull request should go to.  Write up a short title to describe the changes\nyou've made, and in the comment box, write a longer and more thorough description\nif you feel it's necessary (or if you were overly vague in the title).  Finally,\nclick the 'Create pull request' button, and the pull request will be made.\n\nThe project administration can then review your changes and suggest fixes that\nmight be needed.  If you add additional commits to your branch that you opened\nthe pull request with, then the new commits will show up in the pull request.\n\nBack to the :doc:`main page <../../index>`\n\n$Date: 2016-07-04 16:51:06 -04:00 $\n\n.. _git: https://git-scm.com/\n.. _git main site: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git#Installing-on-Mac\n.. _Pro Git book: https://git-scm.com/book/en/v2\n.. _on Github: https://github.com/AviSynth/AviSynthPlus.git"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/contributing/posix.rst",
    "content": "\nUsing AviSynth+ on POSIX systems\n================================\n\nAs of version 3.5, AviSynth+ can now be built and used natively\non Linux, macOS, and BSD.\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\n\nAviSynth+ prerequisites\n-----------------------\n\nDepending on your OS or distribution, the commands to fetch\nthe necessary prerequisites for building AviSynth+ differ.\n\nAt a bare minimum:\n\n* CMake 3.8 or higher.\n* GCC 8 or higher, or similarly recent version of Clang or AppleClang.\n\n.. note::\n   The use of Ninja as the generator for CMake is a matter of personal preference.\n   Feel free to use GNU Make if so compelled (i.e. just a plain 'cmake ..' invocation).\n\nLinux\n^^^^^\n\nUbuntu 19.10 or higher\n~~~~~~~~~~~~~~~~~~~~~~\n\n::\n\n    sudo apt-get install build-essential cmake git ninja-build checkinstall\n\n\n::\n\n    git clone https://github.com/AviSynth/AviSynthPlus && \\\n    cd AviSynthPlus && \\\n    mkdir avisynth-build && \\\n    cd avisynth-build && \\\n\n    cmake ../ -G Ninja -DCMAKE_BUILD_TYPE=Release && \\\n    ninja && \\\n        sudo checkinstall --pkgname=avisynth --pkgversion=\"$(grep -r \\\n        Version avs_core/avisynth.pc | cut -f2 -d \" \")-$(date --rfc-3339=date | \\\n        sed 's/-//g')-git\" --backup=no --deldoc=yes --delspec=yes --deldesc=yes \\\n        --strip=yes --stripso=yes --addso=yes --fstrans=no --default ninja install\n\n\nUbuntu 18.04 LTS\n~~~~~~~~~~~~~~~~\n\n18.04 ships with GCC 7, which is not sufficient to build AviSynth+ without\nthe use of the `filesystem submodule`_.\n\n::\n\n    git clone --recursive https://github.com/AviSynth/AviSynthPlus && \\\n    cd AviSynthPlus && \\\n    mkdir avisynth-build && \\\n    cd avisynth-build && \\\n\n    cmake ../ -G Ninja -DCMAKE_BUILD_TYPE=Release && \\\n    ninja && \\\n        sudo checkinstall --pkgname=avisynth --pkgversion=\"$(grep -r \\\n        Version avs_core/avisynth.pc | cut -f2 -d \" \")-$(date --rfc-3339=date | \\\n        sed 's/-//g')-git\" --backup=no --deldoc=yes --delspec=yes --deldesc=yes \\\n        --strip=yes --stripso=yes --addso=yes --fstrans=no --default ninja install\n\nRaspbian Raspberry Pi 5 + llvm + ninja\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nRaspberry Pi 5 is an aarch64 architecture, presently comes with a gcc 14.2.0 and Clang 19.1.7 \nas of December 2025 (gcc was 12.2, Clang 14.0.6 in early 2025).\n\nVersion 12.2 was unfortunately unable to optimize well, namely it does not recognize well\nthe vectorizable code, and even produces slower code with a so-called \"vector attribute\"\nthat without it. Probably the ArmV8-a support is not perfect.\n\nit seems that using llvm instead is the way to go.\n\nThis procedure was done on a trixie version:\n::\n\n    cat /etc/os-release\n\n::\n\n    PRETTY_NAME=\"Debian GNU/Linux 13 (trixie)\"\n    NAME=\"Debian GNU/Linux\"\n    VERSION_ID=\"13\"\n    VERSION=\"13 (trixie)\"\n    VERSION_CODENAME=trixie\n    DEBIAN_VERSION_FULL=13.2\n    ID=debian\n    HOME_URL=\"https://www.debian.org/\"\n    SUPPORT_URL=\"https://www.debian.org/support\"\n    BUG_REPORT_URL=\"https://bugs.debian.org/\"\n\n\nI'm still using here the -DCMAKE_BUILD_TYPE=Release flag, but after a May 2025 source\nit is no longer needed to avoid a completely unoptimized build with Ninja.\n\nFirst, get some basic stuff.\n\n::\n\n    sudo apt-get install build-essential cmake git ninja-build checkinstall\n\n::\n\n    git clone https://github.com/AviSynth/AviSynthPlus && \\\n    cd AviSynthPlus && \\\n    mkdir avisynth-build && \\\n    cd avisynth-build\n\nFrom now on, instead of a copy-pastable content, we create script files with the following contents.\n\nCreate a suitable directory for these scripts, and save them there.\n\n*config.sh*: grabs the missing components for compiling AviSynth with llvm.\nThe prefix path is very important.\n::\n\n    #!/bin/bash\n\n    # Configuration variables for LLVM build\n    LLVM_PACKAGE=\"llvm\"\n\n    # --- AUTOMATIC VERSION DETECTION AND PATH SETUP ---\n    # Detect the full path for CMake\n    LLVM_CMAKE_PREFIX_PATH=\"$(llvm-config --prefix)\"\n    # Detect the major version for installing the specific compiler binary\n    LLVM_MAJOR_VERSION=$(llvm-config --version | cut -d. -f1 2>/dev/null)\n\n    if [ -z \"$LLVM_MAJOR_VERSION\" ]; then\n        echo \"Fatal Error: Could not determine LLVM major version. Cannot proceed.\"\n        exit 1\n    fi\n\n    echo \"Using LLVM CMake prefix path: $LLVM_CMAKE_PREFIX_PATH\"\n\n    # --- COMPLETE INSTALLATION CHECK ---\n    # Check for the *specific* versioned compiler binary (e.g., clang-19)\n    # AND the necessary libraries.\n    if ! command -v \"clang-$LLVM_MAJOR_VERSION\" &> /dev/null || ! dpkg -s libc++-dev &> /dev/null || ! dpkg -s libc++abi-dev &> /dev/null; then\n      echo \"LLVM compiler (clang-$LLVM_MAJOR_VERSION) or required libraries not found. Installing...\"\n      sudo apt update\n\n      # Install the specific versioned compiler package and libraries.\n      # This fixes the problem where the generic 'llvm' package doesn't provide 'clang-19'.\n      sudo apt install -y \"clang-$LLVM_MAJOR_VERSION\" libc++-dev libc++abi-dev\n    fi\n\n\nyou can check the installed version and the prefix with\n::\n\n    llvm-config --version\n    llvm-config --prefix\n\nOr list your all clang versions\n::\n\n    ls /usr/bin/clang*\n\nAnd query e.g. clang-19\n::\n\n    clang-19 --version\n    \n    Debian clang version 19.1.7 (3+b1)\n    Target: aarch64-unknown-linux-gnu\n    Thread model: posix\n    InstalledDir: /usr/lib/llvm-19/bin\n\n  \n*build-llvm.sh* makes an actual clean build, assumes that avisynth was cloned\nin the right folder in the previous step.\n\nYou can remove the general purge by remove the ``rm -rf *`` if everythings behaves as it should.\n\n**build-llvm.sh**:\n::\n\n    #!/bin/bash\n\n    # Source the configuration script (sets LLVM_CMAKE_PREFIX_PATH)\n    source ./config.sh\n\n    # 1. AUTOMATICALLY EXTRACT MAJOR LLVM VERSION\n    # Uses the known working '--version' output and cuts out the major number (e.g., '19').\n    LLVM_MAJOR_VERSION=$(llvm-config --version | cut -d. -f1 2>/dev/null)\n\n    if [ -z \"$LLVM_MAJOR_VERSION\" ]; then\n        echo \"Fatal Error: Could not determine LLVM major version. Please run 'llvm-config --version' manually to verify installation.\"\n        exit 1\n    fi\n\n    echo \"Detected LLVM Major Version: $LLVM_MAJOR_VERSION\"\n\n    # Navigate to the build directory and clean up. Safely.\n    BUILD_DIR=~/AviSynthPlus/avisynth-build\n    # Navigate\n    cd \"$BUILD_DIR\"\n    # Clean up (The shell expands the unquoted * to all visible contents)\n    rm -rf \"$BUILD_DIR\"/*\n\n    # 2. RUN CMAKE WITH VERSIONED COMPILERS\n    # Compilers are now set to the specific version (e.g., clang-19, clang++-19).\n    cmake ../ -G Ninja \\\n        -DCMAKE_BUILD_TYPE=Release \\\n        -DCMAKE_C_COMPILER=\"clang-$LLVM_MAJOR_VERSION\" \\\n        -DCMAKE_CXX_COMPILER=\"clang++-$LLVM_MAJOR_VERSION\" \\\n        -DCMAKE_PREFIX_PATH=\"$LLVM_CMAKE_PREFIX_PATH\"\n\n    # Check if CMake failed\n    if [ $? -ne 0 ]; then\n        echo \"CMake configuration failed. Please check the output above.\"\n        exit 1\n    fi\n\n    # 2. Build the project\n    ninja\n\n    # Check if ninja build failed\n    if [ $? -ne 0 ]; then\n        echo \"Ninja build failed. Please check the output above.\"\n        exit 1\n    fi\n\n    # 3. Prepare Package Version\n\n    # The generated avisynth.pc is in the build directory, inside the avs_core folder.\n    AVS_VERSION=$(cat avs_core/avisynth.pc | grep Version: | cut -d \" \" -f2)\n    CURRENT_DATE=$(date --rfc-3339=date | sed 's/-//g')\n    PACKAGE_VERSION=\"$AVS_VERSION-$CURRENT_DATE-git\"\n\n    echo \"Package Version: $PACKAGE_VERSION\"\n\n\n    # 4.1 Ensure symlinks are (re)created during install so checkinstall includes them\n    # Detect the SONAME from the freshly built real library (libavisynth.so.<version>)\n    # and remove both the namelink (libavisynth.so) and the SONAME symlink (libavisynth.so.<SOVERSION>)\n    # before running 'ninja install' under checkinstall. This guarantees they are recreated\n    # during install and captured in the package payload.\n    # Without this step, libavisynth.so may be missing after every second build, because\n    # CMake reports existing symlinks as \"Up-to-date\", and checkinstall does not record\n    # pre-existing filesystem items in the package payload.\n\n    LIBDIR=/usr/lib/aarch64-linux-gnu\n\n    # Find the real library we just built (e.g., libavisynth.so.3.7.5) in the target libdir\n    REAL_LIB=$(ls -1 \"$LIBDIR\"/libavisynth.so.* 2>/dev/null | grep -E '\\.so\\.[0-9]+\\.[0-9]+' | head -n1)\n\n    # If the real library is not yet present in the target libdir (first install on a clean system),\n    # try to read it from the build tree so we can still get the SONAME safely.\n    if [ -z \"$REAL_LIB\" ]; then\n      # Search in the build directory output (adjust if your library lands elsewhere during build)\n      REAL_LIB=$(ls -1 \"$BUILD_DIR\"/libavisynth.so.* 2>/dev/null | grep -E '\\.so\\.[0-9]+\\.[0-9]+' | head -n1)\n    fi\n\n    # If we managed to locate the real library, extract SONAME and remove symlinks safely.\n    if [ -n \"$REAL_LIB\" ]; then\n      SONAME=$(readelf -d \"$REAL_LIB\" 2>/dev/null | awk '/SONAME/ {print $5}' | tr -d '[]')\n      if [ -n \"$SONAME\" ]; then\n        echo \"Detected SONAME: $SONAME (from $REAL_LIB)\"\n        # Remove namelink and SONAME symlink if present; leave the real file intact.\n        sudo rm -f \"$LIBDIR/libavisynth.so\" \"$LIBDIR/$SONAME\"\n      else\n        echo \"Warning: Could not detect SONAME via readelf; skipping pre-install symlink removal.\"\n      fi\n    else\n      echo \"Note: Real library not found before install; skipping pre-install symlink removal.\"\n    fi\n\n    # 4.2 Install using checkinstall\n    sudo checkinstall --pkgname=avisynth \\\n        --pkgversion=\"$PACKAGE_VERSION\" \\\n        --backup=no \\\n        --deldoc=yes \\\n        --delspec=yes \\\n        --deldesc=yes \\\n        --strip=yes \\\n        --stripso=yes \\\n        --addso=yes \\\n        --fstrans=no \\\n        --default \\\n        ninja install\n\n    # 4.3 Refresh the dynamic linker cache\n    sudo ldconfig\n\n  \n    # Navigate to the target bin directory\n    cd ~/bin\n  \n    # 5. Success Message\n    echo \"AviSynth+ built and installed with LLVM version $LLVM_MAJOR_VERSION!\"\n\n\n\nWhen you are happy with gcc, use this script:\n\n**build-gcc.sh**:\n::\n\n    #!/bin/bash\n\n    # Navigate to the build directory and clean up. Safely.\n    BUILD_DIR=~/AviSynthPlus/avisynth-build\n    # Navigate\n    cd \"$BUILD_DIR\"\n    # Clean up (The shell expands the unquoted * to all visible contents)\n    rm -rf \"$BUILD_DIR\"/*\n\n    # ---  Get GCC Major Version ---\n    GXX_MAJOR_VERSION=$(g++ -dumpversion | cut -d. -f1 2>/dev/null)\n\n    if [ -z \"$GXX_MAJOR_VERSION\" ]; then\n        echo \"Warning: Could not determine G++ major version. Using \\\"$GXX_MAJOR_VERSION\\\".\"\n    fi\n    # -----------------------------------\n\n    # 1. Configure the build using the default system compiler (gcc/g++)\n    cmake ../ -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr\n\n    # Check if CMake failed\n    if [ $? -ne 0 ]; then\n        echo \"CMake configuration failed. Please check the output above.\"\n        exit 1\n    fi\n\n    # 2. Build the project\n    ninja\n\n    # Check if ninja build failed\n    if [ $? -ne 0 ]; then\n        echo \"Ninja build failed. Please check the output above.\"\n        exit 1\n    fi\n\n    # 3. Prepare Package Version\n\n    # The generated avisynth.pc is in the build directory, inside the avs_core folder.\n    AVS_VERSION=$(cat avs_core/avisynth.pc | grep Version: | cut -d \" \" -f2)\n    CURRENT_DATE=$(date --rfc-3339=date | sed 's/-//g')\n    PACKAGE_VERSION=\"$AVS_VERSION-$CURRENT_DATE-git\"\n\n    echo \"Package Version: $PACKAGE_VERSION\"\n\n    # 4.1 Ensure symlinks are (re)created during install so checkinstall includes them\n    # Detect the SONAME from the freshly built real library (libavisynth.so.<version>)\n    # and remove both the namelink (libavisynth.so) and the SONAME symlink (libavisynth.so.<SOVERSION>)\n    # before running 'ninja install' under checkinstall. This guarantees they are recreated\n    # during install and captured in the package payload.\n    # Without this step, libavisynth.so may be missing after every second build, because\n    # CMake reports existing symlinks as \"Up-to-date\", and checkinstall does not record\n    # pre-existing filesystem items in the package payload.\n\n    LIBDIR=/usr/lib/aarch64-linux-gnu\n\n    # Find the real library we just built (e.g., libavisynth.so.3.7.5) in the target libdir\n    REAL_LIB=$(ls -1 \"$LIBDIR\"/libavisynth.so.* 2>/dev/null | grep -E '\\.so\\.[0-9]+\\.[0-9]+' | head -n1)\n\n    # If the real library is not yet present in the target libdir (first install on a clean system),\n    # try to read it from the build tree so we can still get the SONAME safely.\n    if [ -z \"$REAL_LIB\" ]; then\n      # Search in the build directory output (adjust if your library lands elsewhere during build)\n      REAL_LIB=$(ls -1 \"$BUILD_DIR\"/libavisynth.so.* 2>/dev/null | grep -E '\\.so\\.[0-9]+\\.[0-9]+' | head -n1)\n    fi\n\n    # If we managed to locate the real library, extract SONAME and remove symlinks safely.\n    if [ -n \"$REAL_LIB\" ]; then\n      SONAME=$(readelf -d \"$REAL_LIB\" 2>/dev/null | awk '/SONAME/ {print $5}' | tr -d '[]')\n      if [ -n \"$SONAME\" ]; then\n        echo \"Detected SONAME: $SONAME (from $REAL_LIB)\"\n        # Remove namelink and SONAME symlink if present; leave the real file intact.\n        sudo rm -f \"$LIBDIR/libavisynth.so\" \"$LIBDIR/$SONAME\"\n      else\n        echo \"Warning: Could not detect SONAME via readelf; skipping pre-install symlink removal.\"\n      fi\n    else\n      echo \"Note: Real library not found before install; skipping pre-install symlink removal.\"\n    fi\n\n    # 4.2 Install using checkinstall\n    sudo checkinstall --pkgname=avisynth \\\n        --pkgversion=\"$PACKAGE_VERSION\" \\\n        --backup=no \\\n        --deldoc=yes \\\n        --delspec=yes \\\n        --deldesc=yes \\\n        --strip=yes \\\n        --stripso=yes \\\n        --addso=yes \\\n        --fstrans=no \\\n        --default \\\n        ninja install\n\n    # 4.3 Refresh the dynamic linker cache\n    sudo ldconfig\n  \n    # Navigate to the target bin directory\n    cd ~/bin\n  \n    # 5. Success Message\n    echo \"AviSynth+ built and installed using GCC/G++ version $GXX_MAJOR_VERSION!\"\n\n\nFor testing you can go on to the more advanced ffmpeg support.\n\n\nDistributions without checkinstall\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nNot all Linux distributions have checkinstall in their repositories, either due to\na lack of checkinstall working with their package management system or simply due\nto omission.  In these cases, the install step is a little different:\n\n::\n\n    sudo ninja install\n    sudo ldconfig\n\n\nmacOS\n^^^^^\n\n| Requires Homebrew:\n| `<https://brew.sh/>`_\n\n::\n\n    brew install cmake ninja gcc\n\n\nGCC isn't strictly necessary for AviSynth+, but it can side-step\nthe need to use `an external implementation`_ on High Sierra and\nMojave.\n\n\n10.13 High Sierra and 10.14 Mojave\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nApple's libc++ doesn't support the C++17 filesystem functionality\non either of these versions of macOS, so we have to resort to\nusing `an external implementation`_ as a submodule.\n\n::\n\n    git clone --recursive https://github.com/AviSynth/AviSynthPlus && \\\n    cd AviSynthPlus && \\\n    mkdir avisynth-build && \\\n    cd avisynth-build\n\n    cmake ../ -G Ninja -DCMAKE_BUILD_TYPE=Release && \\\n    ninja && \\\n    sudo ninja install\n\n\n10.15 Catalina and higher\n~~~~~~~~~~~~~~~~~~~~~~~~~\n\nC++17 filesystem support is available on Catalina, so it can\nbe built with the default Clang installation.\n\n::\n\n    cmake ../ -G Ninja -DCMAKE_BUILD_TYPE=Release && \\\n    ninja && \\\n    sudo ninja install\n\n\nFreeBSD\n^^^^^^^\n\nTested on FreeBSD 12.1.\n\n::\n\n    pkg install cmake git gmake ninja\n\n    git clone https://github.com/AviSynth/AviSynthPlus && \\\n    cd AviSynthPlus && \\\n    mkdir avisynth-build && \\\n    cd avisynth-build\n\n\nBuilding AviSynth+ (GNU Make)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n::\n\n    cmake ../ && \\\n    gmake -j$(nproc) && \\\n    gmake install\n\n\nBuilding AviSynth+ (Ninja)\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n::\n\n    cmake ../ -G Ninja && \\\n    ninja && \\\n    sudo ninja install\n\n\nFFmpeg support\n--------------\n\nOn all of these OSes, AviSynth+ can interface with FFmpeg.\nThis change was applied to the FFmpeg git master branch on\n2020-04-05.\n\nIt is always useful to check their guide before the process:\nhttps://trac.ffmpeg.org/wiki/CompilationGuide\n\n\nTo compile a basic build of FFmpeg that supports\nAviSynth+, the following steps will suffice:\n\nPrerequisites\n^^^^^^^^^^^^^\n\nLinux\n~~~~~\n\n\nUbuntu\n......\n\nFirst, enable the Sources repository by either enabling it\nusing the Software Sources dialog or by uncommenting the\nright lines in /etc/apt/sources.list.\n\n::\n\n    sudo apt-get build-dep ffmpeg\n    sudo apt-get install nasm libsdl2-dev\n\n\nmacOS\n~~~~~\n\nHomebrew prerequisites:\n\n::\n\n    brew install xz sdl2 pkg-config nasm\n\n\nFreeBSD\n~~~~~~~\n\n::\n\n    pkg install nasm sdl2\n\n\nBuilding FFmpeg\n^^^^^^^^^^^^^^^\n\n::\n\n    git clone https://git.videolan.org/git/ffmpeg.git\n    cd ffmpeg\n\n\nLinux\n~~~~~\n\nUbuntu\n......\n\n::\n\n    ./configure --prefix=$HOME/ffmpeg_build --enable-gpl --enable-version3 \\\n    --disable-doc --disable-debug --enable-pic --enable-avisynth && \\\n    make -j$(nproc) && \\\n    make install\n\n\nInstalling FFmpeg to the system can be done by leaving out the `--prefix`\noption and then using the following checkinstall command:\n\n::\n\n    sudo checkinstall --pkgname=ffmpeg --pkgversion=\"7:$(git rev-list \\\n    --count HEAD)-g$(git rev-parse --short HEAD)\" --backup=no --deldoc=yes \\\n    --delspec=yes --deldesc=yes --strip=yes --stripso=yes --addso=yes \\\n    --fstrans=no --default\n\n\nRaspbian\n........\n\nRaspberry Pi 5 is able to compile ffmpeg and its prerequisites within a reasonable time, \nwhich means 7-10 minutes (when you don't forget setting -j4 for multithreaded build process).\n\nThis is a general Ubuntu/Debian compilation guide by the ffmpeg project:\nhttps://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu\n\nYou can also refer to this video (Raspberry Pi 5 - Compile FFMPEG on Raspberry PI OS):\nhttps://www.youtube.com/live/if9UG4kJ9L4?si=Nq802tiUteRdlyHE\n\nwhich helps you through the process.\n\nImportant: you'll need some additions, like extending the configuration with \n``--enable-avisynth`` and maybe ``--disable-doc``.\n\nHere comes an all-in-one description:\n\nFirst, enable the Sources repository by either enabling it\nusing the Software Sources dialog or by uncommenting the\nright lines in /etc/apt/sources.list.\n\n::\n\n    sudo apt-get build-dep ffmpeg\n    sudo apt-get install nasm libsdl2-dev\n\nffmpeg needs at least nasm 2.14, we have 2.16.03-1 on December 2025 Raspbian.\nother prerequisites:\n\nffmpeg-pre.sh\n::\n\n    sudo apt-get update -qq && sudo apt-get -y install \\\n      autoconf \\\n      automake \\\n      build-essential \\\n      cmake \\\n      git-core \\\n      libass-dev \\\n      libfreetype6-dev \\\n      libgnutls28-dev \\\n      libmp3lame-dev \\\n      libsdl2-dev \\\n      libtool \\\n      libva-dev \\\n      libvdpau-dev \\\n      libvorbis-dev \\\n      libxcb1-dev \\\n      libxcb-shm0-dev \\\n      libxcb-xfixes0-dev \\\n      meson \\\n      ninja-build \\\n      pkg-config \\\n      texinfo \\\n      wget \\\n      yasm \\\n      zlib1g-dev\n\nIn your home directory make a new directory to put all of the source code and binaries into:\n\n::\n\n    mkdir -p ~/ffmpeg_sources ~/bin\n\nThen various features, like libx264 \n::\n\n    sudo apt-get install libx264-dev\n\nFinally FFmpeg build with avisynth, here I set only x264 and avisynth, a rather minimum setup to test.\n::\n\n    cd ~/ffmpeg_sources && \\\n    wget -O ffmpeg-snapshot.tar.bz2 https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2 && \\\n    tar xjvf ffmpeg-snapshot.tar.bz2 && \\\n    cd ffmpeg && \\\n    PATH=\"$HOME/bin:$PATH\" PKG_CONFIG_PATH=\"$HOME/ffmpeg_build/lib/pkgconfig\" ./configure \\\n      --prefix=\"$HOME/ffmpeg_build\" \\\n      --pkg-config-flags=\"--static\" \\\n      --extra-cflags=\"-I$HOME/ffmpeg_build/include\" \\\n      --extra-ldflags=\"-L$HOME/ffmpeg_build/lib\" \\\n      --extra-libs=\"-lpthread -lm\" \\\n      --ld=\"g++\" \\\n      --bindir=\"$HOME/bin\" \\\n      --enable-gpl \\\n      --enable-libx264 \\\n      --enable-avisynth && \\\n    PATH=\"$HOME/bin:$PATH\" make -j4 && \\\n    make install && \\\n    hash -r\n\n\nmacOS\n~~~~~\n\n::\n\n    ./configure --prefix=$HOME/ffmpeg_build --enable-gpl --enable-version3 --disable-doc \\\n    --disable-debug --enable-avisynth\n    make -j$(nproc)\n    make install\n\nOn Catalina, `--extra-cflags=\"-fno-stack-check\"` is necessary when using AppleClang as the compiler.\n\nFreeBSD\n~~~~~~~\n\n::\n\n    ./configure --prefix=$HOME/ffmpeg_build --enable-gpl --enable-version3 --disable-doc \\\n    --disable-debug --enable-pic --enable-avisynth --cc=cc\n    gmake -j$(nproc)\n    gmake install\n\n\nTesting the installation\n------------------------\n\nFFplay can be used to preview scripts in a pinch; if mpv or VLC is built against the patched\nversion of FFmpeg, those can be used to play back scripts in a more comfortable player\nexperience.\n\nThe easiest two scripts to test the installation are Version or Colorbars/ColorbarsHD.\n\n::\n\n    Version()\n\n\n::\n\n    Colorbars() # or ColorbarsHD()\n    Info()\n\n\nAnd running this script in the test build of FFmpeg:\n\n::\n\n    cd ~/ffmpeg_build/bin\n\nor configure the PATH Permanently:\n::\n\n    nano ~/.bashrc\n    \nMake sure this line is near the top (or uncommented and correct):\n::\n\n    export PATH=\"$HOME/bin:$PATH\"\n\nSave and close the file, then apply the change:\n::\n\n    source ~/.bashrc\n\nNow, which ffplay (or ffmpeg) should report /home/<yourhome>/bin/ffplay (/ffmpeg)\n\n\nCreate the script in a directory, for ease of testing.\n\nTo play the script::\n\n    ffplay -i test.avs\n\nTo convert as usual::\n\n    ffmpeg -i test.avs [encoding options]\n\nBenchmark::\n\n    ffmpeg -benchmark -i test.avs -f null -\n\nStream to a GUI, e.g. to VLC Media Player on a Raspberry Pi.\nChoose \"Open Network Stream\" from menu, and enter ``udp://@127.0.0.1:10000`` \nfor the network url.\n::\n\n    ffmpeg -i test.avs -pix_fmt yuv420p -f mpegts udp://127.0.0.1:10000\n\n\nTroubleshooting:\n\n- ffmpeg reports an unknown error. One possible reason is that libavisynth.so could\n  not be loaded; the ``$LD_LIBRARY_PATH`` environment variable may be empty.\n  Check with ``echo $LD_LIBRARY_PATH``.\n  Fix it by (Raspberry Pi 5 Raspbian):\n\n::\n\n    echo 'export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH' >> ~/.bashrc\n\n- ffmpeg does not recognize the AviSynth script. You probably typed ``ffmpeg`` \n  instead of ``./ffmpeg``. For example, Raspberry Pi 5 Raspbian comes with a 5.x ffmpeg \n  without AviSynth support, and your command finds that one.\n\n\n\n\n\n\nLoading actual video sources will require a source filter.  FFMS2 doesn't require any porting\nto these OSes, making it the most straightforward option at the moment.\n\n\nBuilding FFMS2\n--------------\n\nFFMS2 doesn't require any additional prerequisites, so it can be\nbuilt straight away.\n\n::\n\n    git clone https://github.com/ffms/ffms2 && \\\n    cd ffms2\n\n\nLinux\n^^^^^\n\nUbuntu\n~~~~~~\n\n::\n\n        PKG_CONFIG_PATH=$HOME/ffmpeg_build/lib/pkgconfig \\\n        CPPFLAGS=\"-I/usr/local/include/avisynth\" \\\n        ./autogen.sh --enable-shared --enable-avisynth && \\\n    make -j$(nproc) && \\\n        sudo checkinstall --pkgname=ffms2 --pkgversion=\"1:$(./version.sh)-git\" \\\n        --backup=no --deldoc=yes --delspec=yes --deldesc=yes --strip=yes --stripso=yes \\\n        --addso=yes --fstrans=no --default\n\n\nmacOS\n^^^^^\n\n::\n\n    brew install autoconf automake libtool m4\n\n        PKG_CONFIG_PATH=$HOME/ffmpeg_build/lib/pkgconfig \\\n        CPPFLAGS=\"-I/usr/local/include/avisynth\" \\\n        ./autogen.sh --enable-shared --enable-avisynth && \\\n    make -j$(nproc) && \\\n    sudo make install\n\n\nFreeBSD\n^^^^^^^\n\n::\n\n    pkg install autoconf automake libtool m4\n\n        PKG_CONFIG_PATH=$HOME/ffmpeg_build/lib/pkgconfig \\\n        CPPFLAGS=\"-I/usr/local/include/avisynth\" \\\n        ./autogen.sh --enable-shared --enable-avisynth && \\\n    gmake -j$(nproc) && \\\n    gmake install\n\n\nPlugin autoloading\n------------------\n\nAviSynth+ will use several directories for autoloading:\nthe `avisynth/` subdirectory where libavisynth.so was installed,\n`$HOME/.avisynth`, and the directory given to the USER_AVS_PLUGINDIR_LOCATION\nconfiguration option (defaults to `$HOME/.local/lib/avisynth`).\nThe latter of which can hold plugins (and symlinks to plugins)\nor AVSI files without needing root permissions.\n\nOn FreeBSD, procfs needs to be mounted first in order for\nautoloading to function.\n\n\nBack to the :doc:`main page <../../index>`\n\n$ Date: 2025-04-15 15:15:00 $\n\n.. _an external implementation: https://github.com/gulrak/filesystem\n.. _filesystem submodule: https://github.com/gulrak/filesystem\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/addborders.rst",
    "content": "==========\nAddBorders\n==========\n\nAdd black or colored borders, increasing frame size. This has several common uses:\n\n* Adjust the `aspect ratio`_ (make a 4:3 clip into 16:9 without stretching)\n* :doc:`Splice <splice>` a smaller resolution clip to a larger one without resizing\n* Together with :doc:`Crop <crop>`, shift a clip horizontally or vertically – see below.\n* Optionally filters the transient areas. (3.7.4-)\n\nSee also: :doc:`letterbox`, which adds borders without changing frame size.\n\n\nSyntax and Parameters\n---------------------\n\n::\n\n    AddBorders (clip clip, int left, int top, int right, int bottom, int \"color\", int \"color_yuv\",\n                string \"resample\", float \"param1\", float \"param2\", float \"param3\", int \"r\" )\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n.. describe:: left, top, right, bottom\n\n    Border width in pixels.\n\n    * For YUV411 sources, left and right must be `mod4`_ (divisible by 4).\n    * For YUV420 sources, all four border widths must be `mod2`_ (divisible by 2).\n    * For YUV422 sources, left and right must be mod2.\n\n.. describe:: color\n\n    | Specifies the border color; black by default.\n    | Color is specified as an RGB value in either hexadecimal or decimal notation.\n    | Hex numbers must be preceded with a $. See the\n      :doc:`colors <../syntax/syntax_colors>` page for more information on\n      specifying colors.\n\n    * For YUV clips, colors are converted from full range to limited range\n      `Rec.601`_.\n\n    * Use ``color_yuv`` to specify full range YUV values or a color with a\n      different matrix.\n\n    Default: $000000\n\n.. describe:: color_yuv\n\n    | Specifies the border color using YUV values. Input clip must be YUV;\n      otherwise an error is raised.\n    | Similar to ``color_yuv`` in :doc:`BlankClip <blankclip>` \n\n.. describe:: resample\n\n    string  resample = \"gauss\"\n\n    When `r` radius is not zero, then determines which resampler is used in the transient filtering. \n    All AviSynth :doc:`resizers <resize>` are allowed:\n    (\"point\", \"bilinear\", \"bicubic\", \"lanczos\", \"lanczos4\", \"blackman\", \"spline16\", \"spline36\", \"spline64\", \n    \"gauss\" and \"sinc\", \"sinpow\", \"sinclin2\" and \"userdefined2\"). \n    \n    Default is \"gauss\". \n\n.. describe:: param1, param2, param3\n\n    These 'float' type parameters can be the additional parameters for the\n    resampler. Some resizer algorithms would need and can be fine tuned with up to 3 parameters.\n    Their default values depend on the selected chromaresample resizer kernel.\n    \n    default (when \"gauss\"): \n    \n    * param1 (p), param2(b), param3(s): p=10, b=2.71828182, s=0\n    \n    for other resizer algoritms see  in :doc:`resizers <resize>`. \n    \n.. describe:: r\n    \n    int  r = 0\n\n    The radius of the transient treatment in pixels. The value is meant as +/- around the border line.\n\n    When `r` radius is not zero, transient filtering occurs.\n    Even ``r=1`` is giving sufficient protection for some next processing stages.\n    \n    Why: by filtering the transient areas (boundary of the new borders), we can prevent \n    artifacts e.g. ringing after a subsequent upscale.\n    \n    This is how it works:\n    \n    Eight crops are taken from around the transient areas: \n    \n    - left and right rectangles, which cover +/- 10 (but at least ``r`` + ceil(filter_support)) pixels \n      horizontally around the new border line.\n    - top and bottom rectangles, which cover +/- 10 (but at least ``r`` + ceil(filter_support)) pixels \n      vertically around the new border line.\n    - four corners, top left, top right, bottom left, bottom right, dimension rules\n      as seen above.\n    \n    These eight rectangles are \"resized\", using the given resizer in convolution mode.\n    No dimension is changed, just we'll get a blurred area.\n    \n    Since 3.7.4 resizers can accept a ``force`` parameter, so we use it internally. \n    \n    - left and right parts need only horizontal treatment.\n    - top and bottom parts need only vertical treatment.\n    - corners get both H and V processing.\n    \n    Then, from this larger area only a central ``r`` (radius)-wide rectangle is copied over the transient area.\n    \n    The left and right side will be overwritten by a ``r * original_height`` sized part.\n    At the top and bottom an ``original_width * r`` sized rectangle will be copied back.\n    And a ``r * r`` rectangle is copied over the corners.\n    \n    The exact dimensions can be a bit different, e.g. if ``r`` is larger than the actually added left border.\n    Then the radius is reduced accordingly.\n    \n    The ``r`` radius is automatically adjusted with the video format subsampling requirements.\n    AddBorders won't give error if e.g. for a YV12 ``r=1`` is given: due to the chroma subampling it will be \n    automatically promoted to 2.\n    \n    Other notes:\n    \n    - This copy-paste of the up-to eight area is using a new :doc:`MultiOverlay <multioverlay>` filter.\n    - The convolution filters (resizers) now take the chroma placement into account (``_ChromaLocation`` \n      frame property)\n    \nExamples\n--------\n\n* Add letterbox (top and bottom) borders:\n\n  .. code-block:: c++\n\n    # add dark blue borders, using hex color notation\n    AddBorders(0, 86, 0, 86, color=$00008B)\n\n    # same as above, using named preset color\n    AddBorders(0, 86, 0, 86, color=color_darkblue)\n\n    # full scale black border using color_yuv hex color notation\n    AddBorders(0, 86, 0, 86, color_yuv=$008080)\n\n* Be aware that many older lossy compression algorithms don't deal well with\n  solid-color borders, unless the border happens to fall on a `macroblock`_\n  boundary (16 pixels for MPEG).\n\n* Use **AddBorders** in combination with **Crop** to *shift* an image without\n  changing the frame size:\n\n  .. code-block:: c++\n\n    # Shift an image 2 pixels to the right\n    Crop(0, 0, Width-2, Height)\n    AddBorders(2, 0, 0, 0)\n\n  * Note, shifting this way must be done in 1- or 2-pixel increments, depending\n    on color format.\n  * You can shift in sub-pixel increments with :doc:`Resize <resize>`.\n\n* AddBorders with filtering\n\n  ::\n\n    # Add 20 black pixels around the clip, filters (blurs) 1 pixel with the default \"gauss\" method\n    AddBorders(20, 20, 20, 20, r=1)\n\n* AddBorders filtering test script\n  ::\n  \n    Function AddBordersHF(clip c, int left, int right, int flt_rad)\n    {\n      unflt=AddBorders(c, left, 0, right, 0)\n      flt=GaussResize(unflt, unflt.width, unflt.height, p=10, b=2.71828, s=0, force=1)\n      uf_internal=Crop(c, flt_rad, 0, c.width-flt_rad*2, c.height)\n      return Overlay(flt, uf_internal, x=left+flt_rad, y=0)\n    }\n\n    Function AddBordersVF(clip c, int top, int bottom, int flt_rad)\n    {\n      unflt=AddBorders(c, 0, top, 0, bottom)\n      flt=GaussResize(unflt, unflt.width, unflt.height, p=10, b=2.71828, s=0, force=2)\n      uf_internal=Crop(c, 0, flt_rad, 0, c.height - flt_rad*2)\n      return Overlay(flt, uf_internal, x=0, y=top+flt_rad)\n    }\n\n    Function Diff(clip src1, clip src2)\n    {\n      return Subtract(src1.ConvertBits(8),src2.ConvertBits(8)).Levels(120, 1, 255-120, 0, 255, coring=false)\n    }\n\n    ColorBarsHD(2000,2000)\n    UserDefined2Resize(width/10, height/10)\n\n    # filtering area, means +/- around the border boundaries\n    r1=2\n    r2=2\n\n    left=20\n    top=20\n    right=20\n    bottom=20\n\n    std=AddBorders(left, top, right, bottom)\n    a=last\n    a=AddBordersHF(a, left, right, r1)\n    a=AddBordersVF(a, top, bottom, r1).SubTitle(\"Scriptbased\", align=5)\n\n    b=last\n    b=AddBorders(b, left, top, right, bottom, param1=10, param2=2.71828, param3=0, r=r2).SubTitle(\"AVS 3.7.4\", align=5)\n\n    d1 = Diff(a,b)\n    d2 = Diff(std,a)\n    d3 = Diff(std,b)\n\n    StackHorizontal(StackVertical(std, a, b), Stackvertical(d1, d2, d3))\n\n    LanczosResize(width*4, height*2, taps=16)\n\n\n\nChangelog\n----------\n\n+-----------------+------------------------------------------------------------------+\n| Version         | Changes                                                          |\n+=================+==================================================================+\n| 3.7.4           | Add filtering. resample, param1, param2, param3, r parameters    |\n|                 | Make filtering with chroma placement aware resizers.             |\n+-----------------+------------------------------------------------------------------+\n| AviSynth+ 3.6.2 | Fix: AddBorders did not pass frame properties                    |\n+-----------------+------------------------------------------------------------------+\n| AviSynth+ 3.5.0 | New ``color_yuv`` parameter like in BlankClip                    |\n+-----------------+------------------------------------------------------------------+\n| AviSynth+ r2397 | AddBorders missing l/r/top/bottom vs. subsampling check for YUVA |\n+-----------------+------------------------------------------------------------------+\n| AviSynth 2.6.0  | Bugfix: Fixed RGB24 AddBorders with ``right=0``                  |\n+-----------------+------------------------------------------------------------------+\n| AviSynth 2.0.7  | New ``color`` parameter                                          |\n+-----------------+------------------------------------------------------------------+\n\n$Date: 2025/03/23 11:37:04 $\n\n.. _aspect ratio:\n    http://avisynth.nl/index.php/Aspect_ratios\n.. _mod2:\n    http://avisynth.nl/index.php/Modulo\n.. _mod4:\n    http://avisynth.nl/index.php/Modulo\n.. _Rec.601:\n    https://en.wikipedia.org/wiki/Rec._601\n.. _macroblock:\n    https://en.wikipedia.org/wiki/Macroblock\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/adjust.rst",
    "content": "\nRGBAdjust\n=========\n\n\nDescription\n-----------\n\nRGBAdjust has many different methods of changing the color and luminance of your RGB clips. \nGain, bias (offset) and gamma can be set independently on each channel. \nAlso included are an analysis function and a dither option.\n\nAll settings for this filter are optional. ColorYUV works in a similar manner for YUV clips.\n\nAll RGB and RGBA color formats are supported.\n\nThis filter multiplies each color channel with the given value, adds the\ngiven bias offset then adjusts the relevant gamma, clipping the result at 0\nand 255 (8 bit case).\n\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    RGBAdjust (clip, float \"r\", float \"g\", float \"b\", float \"a\", \n    float \"rb\", float \"gb\", float \"bb\", float \"ab\", \n    float \"rg\", float \"gg\", float \"bg\", float \"ag\", \n    bool \"analyze\", bool \"dither\", bool \"conditional\", bool \"condvarsuffix\")\n\n.. describe:: float r, g, b (default 1.0): \n\n  Red, green and blue scaling factor. Range 0.0 to 255.0 \n  For example, r=3.0 multiplies the red channel pixel values by 3. \n  Avisynth+ autoscales – works without changes at all bit depths, gain is bit depth independent.\n\n.. describe:: float a (default 1.0): \n\n  Alpha adjustment - the transparency information on a per-pixel basis. \n  An alpha value of zero represents full transparency, and a value of 1 represents a full opacity. \n\n.. describe:: float rb, gb, bb, ab (default 0.0): \n\n  Bias adjustment—add a fixed positive or negative value to a channel's pixel values. For example, \n\n  * rb=16 will add 16 to all red pixel values and \n  * rb=-32 will subtract 32 from all red pixel values. \n  \n  This parameter is *not* bit depth autoscaled – caller must scale arguments by 4 for 10-bit, etc. \n\n.. describe:: float rg, gg, bg, ag (default 1.0): \n\n  Gamma adjustment—an exponential gain factor. For example, \n  \n  * rg=1.2 will brighten the red pixel values and \n  * gg=0.8 will darken the green pixel values. \n\n.. describe:: bool analyze = false: \n  \n  If true, RGBAdjust will print color channel statistics on the screen (see example below)\n\n  * There are Maximum and Minimum values for all channels.\n  * There is an Average and a Standard Deviation for all channels.\n  * There is Loose Minimum and Loose Maximum which ignore the brightest and darkest 0.4% (1/256) pixels. \n\n    AVS+ parameter is supported for 32 bit float color spaces as well, but loose min/max is based on a 16-bit\n    quantized data (loose min/max is based on an internal histogram).\n\n.. describe:: bool dither = false\n\n  When set to true, `ordered dithering`_ is applied when doing the adjustment.\n  Parameter is ignored for 32 bit float color spaces \n\n.. describe:: bool conditional = false\n\n  If true, the global variables \"rgbadjust_xxx\" with xxx =\n\n  * ``r``, ``g``, ``b``, ``a``, \n  * ``rb``, ``gb``, ``bb``, ``ab``, \n  * ``rg``, ``gg``, ``bg``, ``ag``\n\n  are read each frame, and applied. \n  \n  It is possible to modify these variables using FrameEvaluate or ConditionalReader. (functionality similar to ColorYUV) \n\n.. describe:: string condvarsuffix = \"\"\n\n  This parameter works similarly in ColorYUV, RGBAdjust, Overlay, ConditionalReader. \n  Allows multiple filter instances to use differently named conditional parameters, thus preventing collision and overwrite \n  of variables which are used by different ConditionalReader instances. \n  See :ref:`Conditional Variables <conditional-variables>` section.\n\n  In the matching ConditionalReader one have to use the modified name as well: \n\n::\n\n    ConditionalReader(\"coloryuvoffset.txt\", \"coloryuv_gain_y\", false, CondVarSuffix = \"_a\") # \"_a\" is added here by parameter\n    ConditionalReader(\"rgbfix.txt\", \"rgbadjust_r\", false, CondVarSuffix = \"_1\") # \"_1\" is added here by parameter\n    ConditionalReader(\"rgbfix2.txt\", \"rgbadjust_r\", false, CondVarSuffix = \"_2\") # \"_2\" is added here by parameter\n    \nor specify the suffixed name directly: \n\n::\n\n    ConditionalReader(\"coloryuvoffset.txt\", \"coloryuv_gain_y_a\", false) # \"_a\" is added here manually\n\nNotes\n-----\n\nAll arguments default—leaves the clip untouched: \n\n::\n\n    RGBAdjust (1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1) leaves\n\nKeep in mind ALL the values are not scaled to accomodate changes to one (for\nthat you should use Levels) so doing something like:\n\n::\n\n    RGBAdjust(2, 1, 1, 1)\n\nwill get you a whole lot of clipped red. If you WANT a whole lot of clipped\nred, there you go - but if you want MORE red without clipping you should do\n\n::\n\n    Levels(0, 1, 255, 0, 128).RGBAdjust(2, 1, 1, 1)\n\nThis would scale all the levels (and average lum) by half, then double the\nred. Or more compact\n\n::\n\n    RGBAdjust(1.0, 0.5, 0.5, 1.0)\n\nThis leaves the red and halves the green and blue.\n\nTo invert the alpha channel\n\n::\n\n    RGBAdjust(a=-1.0, ab=255)\n\nThus alpha pixels values become a=(255-a)\n\nExample\n-------\n\n* Demonstrating analyze output: \n\n.. image:: ./pictures/RGBAdjust_Ex1.jpg\n\n::\n\n    FFmpegSource2(\"sintel.mp4\")\n    ConvertToRGB32\n    BicubicResize(546, 272)\n    RGBAdjust(analyze=true)\n\n\nChanges\n-------\n\n+------------+----------------------------------------+\n| Changelog: |                                        |\n+============+========================================+\n| 3.7.1      | analyze for 32bit float color spaces   |\n+------------+----------------------------------------+\n| r2915      | Added condvarsuffix                    |\n+------------+----------------------------------------+\n| r2724      | | Added 32 bit float.                  |\n|            | | Added conditional                    |\n+------------+----------------------------------------+\n| v2.56      | Added offsets, gamma, analyze.         |\n+------------+----------------------------------------+\n| v2.60      | Added dither.                          |\n+------------+----------------------------------------+\n\n$Date: 2026-01-27 12:30:00 $\n\n.. _ordered dithering: http://avisynth.nl/index.php/Ordered_dithering\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/amplify.rst",
    "content": "===================\nAmplify / AmplifydB\n===================\n\n`Amplify`_ and `AmplifydB`_ amplify the audio of the clip by the prescribed\namount. You can specify different *amount* arguments for each channel. If there\nare more arguments than there are channels, the extra ones are ignored. If there\nare fewer arguments than channels, the last one is applied to the rest of the\nchannels.\n\n.. _Amplify:\n\nAmplify\n-------\n\nAmplify the audio in linear values. See the `Examples`_ section for more\ninformation.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    Amplify (clip, float amount [, float amount ]...)\n\n.. describe:: clip\n\n    | Source clip. Supported audio sample types: 16/32-bit integer, and 32-bit\n      float.\n    | Other sample types (8 and 24-bit integer) are automatically\n      :doc:`converted <convertaudio>` to 32-bit float.\n\n.. describe:: amount\n\n    Multiply (scale) the audio by ``amount``; values are linear:\n\n    * ``amount`` > 1.0 increases volume\n    * ``amount`` < 1.0 decreases volume\n    * ``amount`` = 1.0 retains the same volume\n    * Negative scale factors will shift the `phase`_ by 180 degrees (i.e. invert\n      the samples).\n\n.. _AmplifydB:\n\nAmplifydB\n---------\n\nAmplify the audio in `decibels`_. See the `Examples`_ section for more\ninformation.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    AmplifydB (clip, float amount [, float amount ]...)\n\n.. describe:: clip\n\n    | Source clip. Supported audio sample types: 16/32-bit integer, and 32-bit\n      float.\n    | Other sample types (8 and 24-bit integer) are automatically\n      :doc:`converted <convertaudio>` to 32-bit float.\n\n.. describe:: amount\n\n    Multiply (scale) the audio by ``amount``; values are in dB (decibels):\n\n    * ``amount`` > 0.0 increases volume\n    * ``amount`` < 0.0 decreases volume\n    * ``amount`` = 0.0 retains the same volume\n\n\nExamples\n--------\n\nThe relation between *linear* and *decibel* gain control is:\n\n    **lin** = 10 :sup:`(dB/20)`\n\n    **dB** = 20·log\\ :sub:`10` \\(**lin**)\n\nFor example,\n\n* ``AmplifydB(  0.0)`` is equivalent to  ``Amplify(1.0)``  (no change)\n* ``AmplifydB(  6.0)`` is equivalent to  ``Amplify(2.0)``  (about twice as loud)\n* ``AmplifydB( -6.0)`` is equivalent to  ``Amplify(0.5)``  (about half as loud)\n* ``AmplifydB( 20.0)`` is equivalent to  ``Amplify(10)``   (much louder)\n* ``AmplifydB(-20.0)`` is equivalent to  ``Amplify(0.1)``  (much softer)\n\n\nMore examples:\n\n* ``AmplifydB(+3, 0)`` increases the volume of the left channel by a small amount.\n* ``Amplify(-1, 1)`` inverts the phase of the left channel. See\n  Wikipedia: `Out Of Phase Stereo`_.\n\n**See Also**\n\n* :doc:`Normalize <normalize>` - with *show=true*, can show the maximum\n  amplification possible without `clipping`_.\n* How the multichannels are mapped can be found in the description of\n  :doc:`GetChannel <getchannel>`.\n\n\nChangelog\n----------\n\n+-----------------+-----------------------------------------+\n| Version         | Changes                                 |\n+=================+=========================================+\n| AviSynth 2.5.7  | Fixed a small memory leak in Amplify(). |\n+-----------------+-----------------------------------------+\n| AviSynth 1.0.0  | Added Amplify and AmplifydB filters.    |\n+-----------------+-----------------------------------------+\n\n$Date: 2022/03/05 15:10:22 $\n\n.. _phase:\n    http://www.soundonsound.com/sos/apr08/articles/phasedemystified.htm\n.. _decibels:\n    http://en.wikipedia.org/wiki/Decibel\n.. _Out Of Phase Stereo:\n    http://en.wikipedia.org/wiki/Out_Of_Phase_Stereo\n.. _clipping:\n    http://en.wikipedia.org/wiki/Clipping_(audio)\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/animate.rst",
    "content": "====================\nAnimate / ApplyRange\n====================\n\nThe `Animate`_ function changes the arguments of some other function\ndynamically over a range of specified frames.\n\n`ApplyRange`_ is similar to Animate but the arguments of the specified function\nremain constant throughout the range of the specified frames.\n\nSee the `Examples`_ section.\n\n.. _Animate:\n\nAnimate\n-------\n\n**Animate** is a meta-filter which evaluates its parameter filter with\ncontinuously varying arguments. This filter will not handle a changing\nsoundtrack or different output frame sizes.\n\nThe ``filtername`` argument can even be **Animate** if you want quadratic rather\nthan linear interpolation.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    Animate (clip, int start_frame, int end_frame, string filtername, function user_fn, \n             var start_args, var end_args)\n    Animate (clip, int start_frame, int end_frame, string filtername, \n             var start_args, var end_args)\n\n\n.. describe:: clip\n\n    Source clip, sent to filter ``filtername``.\n\n.. describe:: start_frame, end_frame\n\n    | At frame ``start_frame`` and earlier, the filter is evaluated with the\n      arguments given by ``start_args``.\n    | At frame ``end_frame`` and later, the filter is evaluated with the\n      arguments given by ``end_args``.\n    | In between, the arguments are linearly or by a user defined function interpolated \n      for a smooth transition. Since v3.7.4 integer values are up to 64 bit, interpolation\n      is using a 96.32 bit integer arithmetic. Float parameters are computed with 64 bit double precision.\n\n.. describe:: filtername\n\n    Name of any filter or function accessible to your script.\n\n.. describe:: user_fn (since v3.7.4)\n\n    An optional user defined function, which replaces the classic linear interpolation logic.\n    The simplest one that acts as the classic linear interpolation is:\n    ::\n    \n        function myfuncname(float \"range\") {\n            return range\n        }\n        \n    The function can be passed as parameter after a ``Func(myfuncname)`` conversion.\n    \n    * function is called with \"stage\" from 0.0 to 1.0.\n    * Since Avisynth handles the first and last frame directly (parameter begin and finish),\n      your function may never receive 0.0 and 1.0 range values. But for proper start-end \n      conditions please keep the rule that ``f(0.0) = 0.0`` and ``f(1.0) = 1.0``.\n      The returned value may not necessary be between 0.0 and 1.0. You can return larger \n      values as well. It's your reponsibility how the interpolated parameters bahave in this case.\n\n\n.. describe:: start_args, end_args\n\n    | Two lists of arguments to ``filtername``. Data types must match. The two\n      nested argument lists are not parenthesized.\n    | Strings and video clips can't be interpolated, and therefore must be\n      identical in the two argument lists.\n\n    An important warning: If you use a clip as the first argument to **Animate**,\n    that clip shouldn't be included here. Thus, for example::\n\n        V = Version()\n        Animate(V, 0, 149, \"Crop\", V, 0, 0, 64, 32, V, 316, 0, 64, 32)\n\n    results in an error. The correct script would be::\n\n        V = Version()\n        Animate(V, 0, 149, \"Crop\", 0, 0, 64, 32, 316, 0, 64, 32)\n\n    or alternatively, ::\n\n        V = Version()\n        Animate(0, 149, \"Crop\", V, 0, 0, 64, 32, V, 316, 0, 64, 32)\n\n.. _ApplyRange:\n\nApplyRange\n----------\n\n**ApplyRange** is a special case of `Animate`_ where ``start_args`` = ``end_args``.\nIt can be used to apply a certain filter only on a certain range of frames of a\nclip. Like `Animate`_, this filter will not handle a changing soundtrack or\ndifferent output frame sizes.\n\nIn cases where a large number of ranges need processing, calling **ApplyRange**\nmany times may cause resource issues. An alternative is found here:\n:ref:`ConditionalReader: ApplyRange replacement <complicated-applyrange>`.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    ApplyRange (clip, int start_frame, int end_frame, string filtername, var args)\n\n.. describe:: clip\n\n    Source clip, sent to filter ``filtername``.\n\n.. describe:: start_frame, end_frame\n\n    | Frames outside the range ``start_frame`` to ``end_frame`` are passed\n      through untouched.\n    | Frames inside the range ``start_frame`` to ``end_frame`` (inclusive) are\n      processed by filter filtername with arguments ``args``.\n      If ``start_frame``\\ ==\\ ``end_frame``, only one frame is processed.\n\n.. describe:: filtername\n\n    Name of any filter or function accessible to your script.\n\n.. describe:: args\n\n    | List of arguments to ``filtername``. Unlike **Animate**, ``args`` can't\n      contain a clip.\n    | As with **Animate**, if you use a clip as the first argument to\n      **ApplyRange**, that clip shouldn't be included here.\n\n\nExamples\n--------\n\nAnimate Examples\n^^^^^^^^^^^^^^^^\n\n**Scrolling \"Version\" video** ::\n\n    ver = Version()\n    Animate(ver, 0, 149, \"Crop\",\n    \\    0, 0, 64, 32,\n    \\  316, 0, 64, 32)\n\n**Fade to white** ::\n\n    AviSource(\"test.avi\")\n    Animate(100, 200, \"Levels\",\n    \\  0, 1, 255,   0, 255,\n    \\  0, 1, 255, 255, 255)\n\n**Zoom In** ::\n\n    # Do a gradual zoom into the center of a 320x240 video, starting at\n    # 1:1 magnification in frame 100 and ending with 4:1 magnification\n    # in frame 200:\n    clip = AviSource(\"test.avi\")\n    Animate(100, 200, \"BicubicResize\",\n    \\ clip, 320, 240,   0,  0, 320, 240,\n    \\ clip, 320, 240, 120, 90,  80,  60)\n    # Animate(clip, 100,200,\"BicubicResize\",\n    #\\  320,240,0,0,320,240,\n    #\\  320,240,120,90,80,60) # also works\n\n**Zoom Out** ::\n\n    # Make the text \"Hello, World!\" zoom out from the center of a 320x240 video:\n    BlankClip(width=320, height=240)\n    Animate(0,48,\"Subtitle\",\n    \\  \"Hello, World!\", 160, 120, 0, 99999, \"Arial\", 0,\n    \\  \"Hello, World!\",  25, 130, 0, 99999, \"Arial\", 48)\n\n**Zoom overlay 1** ::\n\n    # Zooming clip c2 while overlaying it on c1:\n\n    function myfunc(clip c1, clip c2, int x, int y, int w, int h)\n    {\n      w = w - w % 2\n      h = h - h % 2\n      my_c2 = BicubicResize(c2, w, h)\n      Overlay(c1, my_c2, x, y)\n    }\n\n    c1 = AviSource(\"c1.avi\") # c1 is larger than c2\n    c2 = AviSource(\"c2.avi\").BicubicResize(320,240)\n    Animate(0, 1000, \"myfunc\",\n    \\  c1, c2,  10,  10,  10,  10,\n    \\  c1, c2, 300, 300, 360, 288)\n    # or\n    # Animate(c1,0,1000,\"myfunc\",\n    #\\  c2, 10, 10, 10, 10,\n    #\\  c2,300,300,360,288)\n\n    # but the following doesn't work, since three clips\n    # are passed to myfunc (c1, c1 and c2), while only two are allowed:\n    # Animate(c1,0,1000,\"myfunc\",\n    #\\  c1,c2, 10, 10, 10, 10,\n    #\\  c1,c2,300,300,360,288)\n\n**Zoom overlay 2** ::\n\n    # A small picture enlarges on a black clip until replace the main clip:\n\n    function res(clip clip, clip \"LClip\", int \"width\", int \"height\",\n    \\           int \"centerX\", int \"centerY\") {\n        LClip = BicubicResize(LClip, width, height)\n        Overlay(clip, LClip, centerX-LClip.Width/2, centerY-LClip.Height/2)\n    }\n\n    function resize(clip clip, clip \"LClip\",\n    \\               int \"start_frame\", int \"start_width\", int \"start_height\",\n    \\               int \"end_frame\", int \"end_width\", int \"end_height\",\n    \\               int \"centerX\", int \"centerY\") {\n        return Animate(start_frame, end_frame, \"res\",\n            \\       clip, LClip, start_width, start_height, centerX, centerY,\n            \\       clip, LClip, end_width, end_height, centerX, centerY)\n    }\n\n    clip = AviSource(\"test.avi\")\n    clip = clip.ConvertToRGB()\n    clip = clip.BicubicResize(640,480)\n    black = BlankClip(clip)\n\n    resize(black, clip,\n    \\      0, 120, 120*clip.Height/clip.Width,\n    \\      500, 640, 480,\n    \\      clip.Width/2, clip.Height/2)\n\nSee also, :ref:`Subtitle: Animated parameter demonstration <subtitle-animated-demo>`\n\n**Comparison of different methods, linear, exp.** ::\n\n    version.crop(8,32,16,16)\n    w=Width()\n    h=height()\n    force=3 # for both horizontal and vertical\n\n    Function Diff(clip src1, clip src2)\n    {\n      return Subtract(src1.ConvertBits(8),src2.ConvertBits(8)).Levels(120, 1, 255-120, 0, 255, coring=false)\n    }\n\n    # rules for animate callback: float param named \"stage\"\n    # stage is called for values (0.0 , 1.0)\n    # For proper start-end conditions \n    # f(0.0) = 0.0 and f(1.0) = 1.0 is a nice to have\n\n    function animhelper_lin(float \"stage\")\n    {\n        return stage # full linear\n    }\n\n    function animhelper_exp(float \"stage\")\n    {\n        return (stage*stage*stage)\n    }\n\n    fn_lin = Func(animhelper_lin)\n    fn_exp = Func(animhelper_exp)\n\n    #function\n    a=animate(0,100,\"bicubicresize\", fn_exp, \\\n    16,16,1.0/3.0,1.0/3.0,-1.0,-1.0,w,h,force,\\\n    16,16,1.0/3.0,1.0/3.0, 1.0, 1.0,w,h,force)\n\n    #function implemented as linear \n    b=animate(0,100,\"bicubicresize\", fn_lin, \\\n    16,16,1.0/3.0,1.0/3.0,-1.0,-1.0,w,h,force,\\\n    16,16,1.0/3.0,1.0/3.0, 1.0, 1.0,w,h,force)\n\n    # classic, always linear\n    c=animate(0,100,\"bicubicresize\", \\\n    16,16,1.0/3.0,1.0/3.0,-1.0,-1.0,w,h,force,\\\n    16,16,1.0/3.0,1.0/3.0, 1.0, 1.0,w,h,force)\n\n    #check\n    d=Diff(b,c) # they are the same\n\n    StackHorizontal(a,b,c,d)\n\n\n\nApplyRange Examples\n^^^^^^^^^^^^^^^^^^^\n\n::\n\n    ver = Version()\n    return ver.ApplyRange(0, 149, \"Crop\", 158, 0, 64, 32)\n    # gives an error since cannot have different frame sizes within a clip\n\n::\n\n    Version()\n    ApplyRange(100, 149, \"Blur\", 1.0) # Blur only frames 100-149\n\n::\n\n    AviSource(\"test.avi\").BicubicResize(320,240)\n    ApplyRange(0, 48, \"Subtitle\", \"Hello, World!\", 25, 130, 0, 99999, \"Arial\", 48)\n\n    # is the same as:\n    clip = AviSource(\"test.avi\").BicubicResize(320,240)\n    ApplyRange(clip, 0, 48 \"Subtitle\", \"Hello, World!\", 25, 130, 0, 99999, \"Arial\", 48)\n\n    # since the frame range can be provided to Subtitle itself, this is the same as:\n    AviSource(\"test.avi\").BicubicResize(320,240)\n    Subtitle(\"Hello, World!\", 25, 130, 0, 48, \"Arial\", 48)\n\n\nChangelog\n---------\n\n+-----------------+-------------------------------------------------------------+\n| Version         | Changes                                                     |\n+=================+=============================================================+\n| 3.7.4           || Custom function option for Animate                         |\n|                 || Animate: more precise granularity for integer interpolation|\n|                 || Animate: add proper rounding for integer interpolation     |\n+-----------------+-------------------------------------------------------------+\n| AviSynth 2.5.3  || Added ApplyRange filter.                                   |\n|                 || Added support for audio, and ``start_frame``               |\n|                 |  can be equal to ``end_frame``.                             |\n+-----------------+-------------------------------------------------------------+\n\n$Date: 2025/03/11 11:41:22 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/assumerate.rst",
    "content": "================\nAssumeSampleRate\n================\n\nChanges the sample rate of the current clip without changing the number of samples.\n\n* This changes the sample rate, pitch, playback speed and running time of the audio.\n* It will also affect synchronization with the video.\n\n\nSyntax and Parameters\n---------------------\n\n::\n\n    AssumeSampleRate (clip, int samplerate)\n\n.. describe:: clip\n\n    Source clip; all color formats and audio sample types supported.\n\n.. describe:: samplerate\n\n    New sample rate.\n\n\nExamples\n--------\n\nFix an audio sync problem::\n\n    AviSource(\"video_audio.avi\")\n    # Let's say that this clip loses audio sync:\n    # by the end, the audio is behind by 200 milliseconds.\n\n    Ar  = AudioRate()     # original audio sample rate\n    dur = AudioDuration() # total duration in seconds\n    adj = -0.200          # correction needed (decrease audio duration by 200 msec)\n\n    # Adjust audio duration:\n    AssumeSampleRate(Round(dur / (dur+adj) * Ar))\n\n    # Video and audio are now in sync.\n\n    # (optional) restore original sample rate.\n    #ResampleAudio(Ar)\n\nPlay video and audio at half speed::\n\n    AviSource(\"video_audio.avi\")\n\n    # Play video at half speed: audio will be out of sync\n    AssumeFPS(FrameRate/2)\n\n    # Play audio at half speed: (pitch will be lowered by an octave)\n    AssumeSampleRate(AudioRate/2)\n\n    # Video and audio are now in sync.\n    # Equivalent to calling AssumeFPS(..., sync_audio=true) (see below)\n\n\nSee also\n--------\n\n:doc:`AssumeFPS <fps>`: *sync_audio*\n\n    If *true*, the audio sample rate is changed by the same amount; the pitch of\n    the resulting audio is shifted.\n\n    If *false* (the default), the audio is unchanged; this means the audio will\n    lose synchronization over time.\n\n\nChangelog\n----------\n\n+-----------------+--------------+\n| Version         | Changes      |\n+=================+==============+\n| AviSynth 2.0.7  | First added  |\n+-----------------+--------------+\n\n$Date: 2022/03/17 15:28:44 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/audiodub.rst",
    "content": "=====================\nAudioDub / AudioDubEx\n=====================\n\n**AudioDub** takes the video stream from the first argument and the audio stream\nfrom the second argument and combines them into a single clip. If either track\nisn't available, it tries it the other way around, and if that doesn't work\nit returns an error.\n\n**AudioDubEx** takes the video stream from the first argument if present, the\naudio stream from the second argument if present and combines them into a single\nclip. Thus, if you feed it with two video clips, and the second one has no audio,\nthe resulting clip will have the video of the first clip and no audio. If you\nfeed it with two audio clips, the resulting clip will have the audio of the\nsecond clip and no video.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    AudioDub (clip video, clip audio)\n    AudioDubEx (clip video, clip audio)\n\n.. describe:: clip\n\n    Video clip; all color formats supported.\n\n.. describe:: clip\n\n    Audio clip; all audio sample types supported.\n\nExamples\n--------\n\n::\n\n    # Load capture segments from patched AVICAP32 which puts\n    # video in multiple AVI segments and audio in a WAV file\n    video = AVISource(\"capture1.avi\") + AVISource(\"capture2.avi\")\n    audio = WavSource(\"capture.wav\")\n    # combine them into a single clip\n    AudioDub(video, audio)\n\n\nChangelog\n----------\n\n.. table::\n    :widths: auto\n\n    +----------------+--------------------------+\n    | Version        | Changes                  |\n    +================+==========================+\n    | AviSynth 2.5.6 | Added AudioDubEx filter. |\n    +----------------+--------------------------+\n\n$Date: 2022/03/17 12:37:33 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/avisource.rst",
    "content": "=====================================================\nAVISource / OpenDMLSource / AVIFileSource / WAVSource\n=====================================================\n\n**AviSource** takes one or more files - not only `AVI`_ but also `WAV`_ (audio),\n`AVS`_ (AviSynth scripts), and `VDR`_ (`VirtualDub`_ frameserver) files. There\nis built-in `Audio Compression Manager`_ support for decoding compressed audio\ntracks (MP3, AAC, AC3, etc). If more than one file name is given, **AviSource**\nreturns a clip with all files joined end to end. For the files to be joined, the\nmedia properties must be compatible - see `Notes`_ below.\n\n    **AviSource** tries to read the file(s) using AviSynth's built-in `OpenDML`_\n    interface (derived from VirtualDub code) where possible; if the file(s) are\n    not in OpenDML format, it uses the Video for Windows `AVIFile`_ interface.\n\n    If **AviSource** has trouble with one or the other interface, **OpenDMLSource**\n    and **AviFileSource** will force the use of *OpenDML* or *AVIFile*,\n    respectively. Only *OpenDML* can read files larger than 2 GB, but only\n    *AVIFile* can read non-AVI files (odd, given its name) like the ones listed\n    in the opening paragraph. It can read any file (under 2 GB) for which there\n    exist appropriate *stream handlers*.\n\n**WavSource** will open a `WAV`_ file, or an audio-only AVI file. It will also\nreturn the audio stream from a normal video+audio AVI. This might be useful if\nyour video stream is damaged or unreadable, or simply as a shortcut for\n``AviSource(...).KillVideo()`` (:doc:`KillVideo <killaudio>`).\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    AVISource (string filename [, ...], bool \"audio\", string \"pixel_type\", string \"fourCC\", int \"vtrack\", int \"atrack\", bool \"utf8\")\n\n    OpenDMLSource (string filename [, ...], bool \"audio\", string \"pixel_type\", string \"fourCC\", int \"vtrack\", int \"atrack\", bool \"utf8\")\n\n    AVIFileSource (string filename [, ...], bool \"audio\", string \"pixel_type\", string \"fourCC\", int \"vtrack\", int \"atrack\", bool \"utf8\")\n\n    WAVSource (string filename [, ...], bool \"utf8\")\n\n.. describe:: filename\n\n    One or more file names. The files will be joined into a single clip with\n    :doc:`UnalignedSplice <splice>`. To join files, the media properties must\n    be compatible. See `Notes`_ below. `UTF-8`_ file names are supported when\n    ``utf8=true``.\n\n.. describe:: audio\n\n    If true, load the first audio stream, or the stream specified by ``atrack``\n    if present. If false, audio is disabled.\n\n    Default: true\n\n.. describe:: pixel_type\n\n    Chooses the output color format of the decompressor. Valid values are listed\n    in the table below. This argument has no effect if the video is uncompressed,\n    as no decompressor will be used in that case. See the `10+ bit inputs`_\n    section for a full list of pixel types.\n\n    * If omitted or \"FULL\", AviSynth will use the first format supported by the\n      decompressor, in the order shown in the table below.\n    * If \"AUTO\", AviSynth will use the alternate (older) order as shown.\n\n      .. table::\n          :widths: auto\n\n          +------------+-------+-------+-------+--------+-------+--------+--------+\n          | pixel_type | Color formats, listed by decoding priority (high to low) |\n          +============+=======+=======+=======+========+=======+========+========+\n          | FULL       | YV24  | YV16  | YV12  | YV411  | YUY2  | RGB32  | RGB24  |\n          +------------+-------+-------+-------+--------+-------+--------+--------+\n          | AUTO       |       |       | YV12  |        | YUY2  | RGB32  | RGB24  |\n          +------------+-------+-------+-------+--------+-------+--------+--------+\n\n\n    In other words, if you don't specify anything, it will try to output YV24;\n    if that isn't possible it tries YV16, and if that isn't possible it tries\n    YV12, etc ...\n\n    For `planar`_ color formats, adding a '+' prefix, e.g.\n    ``AviSource(..., pixel_type=\"+YV12\")``, tells AviSynth the video rows are\n    DWORD aligned in memory instead of packed. **This can fix skew or tearing of\n    the decoded video** with bad codecs when the width of the picture is not\n    divisible by 4.\n\n    Default: \"FULL\"\n\n.. describe:: fourCC\n\n    Forces AviSynth to use a specific decoder instead of the one specified in\n    the source file. See `FourCC`_ for more information.\n\n    Default: auto from source\n\n.. describe:: vtrack\n\n    Specifies a numbered video track. Track numbers start from zero, and are\n    guaranteed to be continuous (i.e. there must be a track 1 if there is a\n    track 0 and a track 2). If no video stream numbered ``vtrack`` exists, an\n    error will be raised.\n\n    Default: 0\n\n.. describe:: atrack\n\n    Specifies a numbered audio track. Track numbers start from zero, and are\n    guaranteed to be continuous (i.e. there must be a track 1 if there is a\n    track 0 and a track 2). If no audio stream numbered ``atrack`` exists, no\n    error will be raised, and no audio will be returned.\n\n    Default: 0\n\n.. describe:: utf8\n\n    If true, file name is treated as `UTF-8`_.\n\n    Default: false\n\n\nNotes\n-----\n\nJoining clips\n^^^^^^^^^^^^^\n\n* There is a limit (of about 50, sometimes fewer) **AviSource** calls in script\n  - see `discussion`_. If the limit is exceeded, you will see the error message:\n\n    *AVISource: couldn't locate a decompressor for fourcc ....*\n\n If you need to join more AVIs, try `VirtualDub`_ (limit > 700).\n\n* :doc:`Media properties <../syntax/syntax_clip_properties>` must be\n  compatible, meaning they must have:\n\n #. the same height and width;\n #. the same color format (as presented by the decoder);\n #. the same frame rate (precisely the same, not approximately); and\n #. the same audio sample rate, bit depth and number of channels.\n\n* See the VirtualDub blog post `Appending streams and mismatch errors`_ for a\n  more in-depth explanation.\n\nWindows 7 users\n^^^^^^^^^^^^^^^\n\n**WavSource** under Windows 7 is unable to load WAV files with 32-bit IEEE Float\nsamples having the `WAVEFORMAT structure`_. You can use `FFmpeg`_ to rewrite the\nheader to an extensible format (just do a stream copy; it always writes\nextensible headers) ::\n\n    ffmpeg -i \"bad.wav\" -c copy \"good.wav\"\n\nHelpful hints\n^^^^^^^^^^^^^\n\n* Sometimes the colors will be distorted when loading a `DivX`_ clip in AviSynth\n  v2.5 (the chroma channels U and V are swapped), due to a bug in DivX (5.02 and\n  older). You can use :ref:`SwapUV` to correct it.\n\n* **AVISource** can also open DV type 1 video input (only video, not audio).\n\n* Some video files get decoded with the wrong color standard ('Rec601'/'Rec709')\n  or luma range ('Full'/'TV'). This problem can arise if the input and output\n  color formats are different, forcing a :doc:`conversion <convert>`. To avoid\n  this conversion, try to specify another, compatible output format - for example:\n\n   * If the video was encoded as RGB, try ``pixel_type=\"RGB24\"`` or \"RGB32\";\n   * If the video was encoded as YUV, try ``pixel_type=\"YV12\"``, \"YUY2\" or \"YV24\".\n\n If that does not work, try `FFmpegSource`_, `LSMASHSource`_ or (if absolutely\n necessary) :doc:`DirectShowSource <directshowsource>`.\n\n.. _AVISource-hbd:\n\n10+ bit inputs\n^^^^^^^^^^^^^^\n\nWhen a classic 'pixel_type' shares more internal formats (such as YUV422P10\nfirst tries to request the v210 then P210 format) you can specify one of the\nspecific format directly. Note that high bit-depth RGBP (Planar RGB) is\nprioritized against packed RGB48/64.\n\nThe 'FourCCs for ICDecompressQuery' column means that when a codec supports the\nformat, it will serve the frame in that one, AviSource then will convert it to\nthe proper colorspace.\n\n::\n\n    Full support list.\n    Non *-marked formats (FourCC column) are supported since r2724.\n\n    'pixel_type' Avs+ Format   FourCC(s) for ICDecompressQuery\n    YV24         YV24          *YV24\n    YV16         YV16          *YV16\n    YV12         YV12          *YV12\n    YV411        YV411         *Y41B\n    YUY2         YUY2          *YUY2\n    RGBP10       RGBP10        G3[0][10]  r210  R10k\n    r210         RGBP10        r210\n    R10k         RGBP10        R10k\n    RGBP         RGBP10        G3[0][10]  r210  R10k\n                 RGBP12        G3[0][12]\n                 RGBP14        G3[0][14]\n                 RGBP16        G3[0][16]\n                 RGBAP10       G4[0][10]\n                 RGBAP12       G4[0][12]\n                 RGBAP14       G4[0][14]\n                 RGBAP16       G4[0][16]\n    RGB32        RGB32         *BI_RGB internal constant (0) with bitcount=32\n    RGB24        RGB24         *BI_RGB internal constant (0) with bitcount=24\n    RGB48        RGB48         BGR[48]    b48r\n    RGB64        RGB64         *BRA[64]   b64a\n    Y8           Y8            Y800       Y8[32][32]   GREY\n    Y            Y8            Y800       Y8[32][32]   GREY\n                 Y10           Y1[0][10]\n                 Y12           Y1[0][12]\n                 Y14           Y1[0][14]\n                 Y16           Y1[0][16]\n    YUV422P10    YUV422P10     v210       P210\n    v210         YUV422P10     v210\n    P210         YUV422P10     P210\n    YUV422P16    YUV422P16     P216\n    P216         YUV422P16     P216\n    YUV420P10    YUV420P10     P010\n    P010         YUV422P10     P010\n    YUV420P16    YUV420P16     P016\n    P016         YUV422P16     P016\n    YUV444P10    YUV444P10     v410\n    v410         YUV444P10     v410\n\nMore on codecs\n^^^^^^^^^^^^^^\n\nSome reference threads:\n\n* `MJPEG codecs`_\n* `DV codecs`_\n\n\nExamples\n--------\n\n* C programmers note: backslashes are not doubled; forward slashes work too::\n\n    AVISource(\"d:\\capture.avi\")\n    WAVSource(\"f:/soundtrack.wav\")\n\n* Splice two clips together; the following statements do the same thing::\n\n    AviSource(\"cap1.avi\") + AviSource(\"cap2.avi\")\n    AVISource(\"cap1.avi\", \"cap2.avi\")\n\n* Splice two clips together where frame rates do not match::\n\n    A = AviSource(\"FileA.avi\") # \"29.97\" fps (30000/1001)\n    B = AviSource(\"FileB.avi\") # 30.0000 fps\n    A ++ B.AssumeFPS(A)\n\n* Splice two clips together where one of them contains no audio::\n\n    A = AviSource(\"FileA.avi\") # with audio\n    B = AviSource(\"FileB.avi\") # no audio stream\n    A ++ AudioDub(B, BlankClip(A)) # insert silent audio with same format\n\n* Disable audio and request RGB32 decompression::\n\n    AVISource(\"cap.avi\", audio=false, pixel_type=\"RGB32\")\n\n* Open a DV, forcing the Canopus DV Codec::\n\n    AviSource(\"cap.avi\", fourCC=\"CDVC\")\n\n* Open a file, forcing the `XviD`_ Codec::\n\n    AviSource(\"cap.avi\", fourCC=\"XVID\")\n\n* Open a YV12 video with a bad codec where the width is not a multiple of four::\n\n    AviSource(\"test.avi\", pixel_type=\"+YV12\")\n\n* Opens the first video and second audio stream of a clip::\n\n    AviSource(\"test_multi10.avi\", vtrack=0, atrack=1)\n\n\nChangelog\n---------\n\n+-----------------+----------------------------------------------------+\n| Version         | Changes                                            |\n+=================+====================================================+\n| AviSynth+ r2768 | Added utf8 filename support.                       |\n+-----------------+----------------------------------------------------+\n| AviSynth+ r2724 || Added 10+ bits new color formats.                 |\n+-----------------+----------------------------------------------------+\n| AviSynth 2.6.0  || Added new color formats, \"AUTO\" and \"FULL\".       |\n|                 || Added multiple video and audio stream support.    |\n|                 || Add '+' to pixel_type for padded planar support.  |\n+-----------------+----------------------------------------------------+\n| AviSynth 2.5.5  | Added fourCC option.                               |\n+-----------------+----------------------------------------------------+\n\n$Date: 2022/03/14 07:32:20 $\n\n.. _AVI:\n    http://avisynth.nl/index.php/AVI\n.. _WAV:\n    http://avisynth.nl/index.php/WAV\n.. _AVS:\n    http://avisynth.nl/index.php/AVS\n.. _VDR:\n    https://www.virtualdub.org/docs_frameserver.html\n.. _VirtualDub:\n    http://avisynth.nl/index.php/VirtualDub\n.. _Audio Compression Manager:\n    https://en.wikipedia.org/wiki/Windows_legacy_audio_components#Audio_Compression_Manager\n.. _OpenDML:\n    http://www.jmcgowan.com/avitech.html#OpenDML\n.. _AVIFile:\n    http://www.jmcgowan.com/avitech.html#VFW\n.. _planar:\n    http://avisynth.nl/index.php/Planar\n.. _FourCC:\n    http://avisynth.nl/index.php/FourCC\n.. _UTF-8:\n    https://en.wikipedia.org/wiki/UTF-8\n.. _discussion:\n    https://forum.doom9.org/showthread.php?t=131687\n.. _Appending streams and mismatch errors:\n    https://www.virtualdub.org/blog2/entry_073.html\n.. _WAVEFORMAT structure:\n    https://forum.doom9.org/showthread.php?t=170444\n.. _FFmpeg:\n    https://ffmpeg.org/\n.. _DivX:\n    http://avisynth.nl/index.php/DivX\n.. _FFmpegSource:\n    http://avisynth.nl/index.php/FFmpegSource\n.. _LSMASHSource:\n    http://avisynth.nl/index.php/LSMASHSource\n.. _MJPEG codecs:\n    https://forum.doom9.org/showthread.php?s=&postid=330657\n.. _DV codecs:\n    https://forum.doom9.org/showthread.php?s=&threadid=58110\n.. _XviD:\n    http://avisynth.nl/index.php/Xvid\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/blankclip.rst",
    "content": "=====================\nBlankClip / Blackness\n=====================\n\nThe **BlankClip** filter produces a solid color, silent video clip of the\nspecified length (in frames). The *clip* passed as an argument is used as a\n*template* for frame rate, image size, and so on, but you can specify all clip\nproperties without having to provide a template. Without any arguments specified,\n**BlankClip** will produce a pitch-black 10 seconds clip (RGB32), 640x480, 24\nfps, 16 bit 44100 Hz mono.\n\nWhen supplying a template, **BlankClip** returns a clip with\n:doc:`properties <../syntax/syntax_clip_properties>` copied from that template.\nIf the template is audio-only, you get a blank audio-only clip, and if it's\nvideo-only you get a blank video-only clip. If you start to add parameters that\nforce a video track (i.e. width, height or pixel_type) or audio track\n(i.e. audio_rate, channels or sample_type), the remaining parameters\nfor that track will be the defaults.\n\n**Blackness** is an alias for **BlankClip**. The parameters are the same, minus\nthe *colors* parameter.\n\nSyntax and Parameters\n----------------------\n\n::\n\n    BlankClip (clip clip, int \"length\", int \"width\", int \"height\",\n               string \"pixel_type\", float \"fps\", int \"fps_denominator\", int \"audio_rate\",\n               int \"channels\", string \"sample_type\", int \"color\", int \"color_yuv\", float+ \"colors\")\n\n    BlankClip (clip clip, int \"length\", int \"width\", int \"height\",\n               string \"pixel_type\", float \"fps\", int \"fps_denominator\", int \"audio_rate\",\n               bool \"stereo\", bool \"sixteen_bit\", int \"color\", int \"color_yuv\", float+ \"colors\")\n\n    Blackness ( ...same parameters as BlankClip )\n\n.. describe:: clip\n\n    If present, the resulting clip will have the clip-properties of the\n    template, except for the properties you define explicitly.\n\n.. describe:: length\n\n    Length of the resulting clip (in frames).\n\n    Default: 240\n\n.. describe:: width, height\n\n    Width and height of the resulting clip.\n\n    Default: 640, 480\n\n.. describe:: pixel_type\n\n    Pixel type of the resulting clip. Valid color formats are listed in the\n    following table.\n\n    +--------+---------+------------+-------------+------------+--------+\n    | Bits   | RGB(A)  | YUV(A)444  | YUV(A)422   | YUV(A)420  | Y only |\n    +========+=========+============+=============+============+========+\n    | **8**  | RGB24   | YV24       | YV16 / YUY2 | YV12       | Y8     |\n    |        |         |            |             |            |        |\n    |        | RGBP    | YUV444     | YUV422      | YUV420     |        |\n    |        |         |            |             |            |        |\n    |        | RGBP8   | YUV444P8   | YUV422P8    | YUV420P8   |        |\n    +--------+---------+------------+-------------+------------+--------+\n    | **10** | RGBP10  | YUV444P10  | YUV422P10   | YUV420P10  | Y10    |\n    +--------+---------+------------+-------------+------------+--------+\n    | **12** | RGBP12  | YUV444P12  | YUV422P12   | YUV420P12  | Y12    |\n    +--------+---------+------------+-------------+------------+--------+\n    | **14** | RGBP14  | YUV444P14  | YUV422P14   | YUV420P14  | Y14    |\n    +--------+---------+------------+-------------+------------+--------+\n    | **16** | RGB48   | YUV444P16  | YUV422P16   | YUV420P16  | Y16    |\n    |        |         |            |             |            |        |\n    |        | RGBP16  |            |             |            |        |\n    +--------+---------+------------+-------------+------------+--------+\n    | **32** | RGBPS   | YUV444PS   | YUV422PS    | YUV420PS   | Y32    |\n    +--------+---------+------------+-------------+------------+--------+\n    | `With an alpha channel`                                           |\n    +--------+---------+------------+-------------+------------+--------+\n    | **8**  | RGB32   |            |             |            |        |\n    |        |         |            |             |            |        |\n    |        | RGBAP   | YUVA444    | YUVA422     | YUVA420    |        |\n    |        |         |            |             |            |        |\n    |        | RGBAP8  | YUVA444P8  | YUVA422P8   | YUVA420P8  |        |\n    +--------+---------+------------+-------------+------------+--------+\n    | **10** | RGBAP10 | YUVA444P10 | YUVA422P10  | YUVA420P10 |        |\n    +--------+---------+------------+-------------+------------+--------+\n    | **12** | RGBAP12 | YUVA444P12 | YUVA422P12  | YUVA420P12 |        |\n    +--------+---------+------------+-------------+------------+--------+\n    | **14** | RGBAP14 | YUVA444P14 | YUVA422P14  | YUVA420P14 |        |\n    +--------+---------+------------+-------------+------------+--------+\n    | **16** | RGB64   | YUVA444P16 | YUVA422P16  | YUVA420P16 |        |\n    |        |         |            |             |            |        |\n    |        | RGBAP16 |            |             |            |        |\n    +--------+---------+------------+-------------+------------+--------+\n    | **32** | RGBAPS  | YUVA444PS  | YUVA422PS   | YUVA420PS  |        |\n    +--------+---------+------------+-------------+------------+--------+\n    | **Note**: 8-bit color formats (``YV411, YUV411, YUV411P8``) were  |\n    | omitted from the table.                                           |\n    +--------+---------+------------+-------------+------------+--------+\n\n    Default: \"RGB32\"\n\n.. describe:: fps\n\n    The framerate of the resulting clip.\n\n    Default: 24\n\n.. describe:: fps_denominator\n\n    | You can use this option if \"fps\" is not accurate enough.\n    | For example: ``fps = 30000, fps_denominator = 1001`` (ratio = 29.97) or\n      ``fps = 24000, fps_denominator = 1001`` (ratio = 23.976).\n\n    *Note* – if ``fps_denominator`` is given (even if it is \"1\"), ``fps`` is\n    **rounded to the nearest integer**.\n\n    Default: 1\n\n.. describe:: audio_rate\n\n    | Sample rate of the (silent) audio.\n    | *Note* – ``BlankClip(audio_rate=0)`` produces the same result as\n      ``BlankClip.KillAudio()``.\n\n    Default: 44100\n\n.. describe:: channels\n\n    Specifies the number of audio channels of silent audio added to the blank clip.\n\n    Default: 1\n\n.. describe:: stereo\n\n    | **Deprecated!** Use the ``channels`` parameter instead.\n    | If true, the (silent) audio is in stereo: ``channels=2``.\n\n    Default: false\n\n.. describe:: sample_type\n\n    Specifies the audio sample type of the resulting clip. It can be \"8bit\",\n    \"16bit\", \"24bit\", \"32bit\" or \"float\".\n\n    Default: \"16bit\"\n\n.. describe:: sixteen_bit\n\n    | **Deprecated!** Use the ``sample_type`` parameter instead.\n    | True returns 16-bit audio, *false* returns 32-bit float.\n\n    Default: true\n\n.. describe:: color\n\n    | Specifies the color of the clip. Color is specified as an RGB value in\n      either hexadecimal or decimal notation.\n    | Hex numbers must be preceded with a $. See the\n      :doc:`colors <../syntax/syntax_colors>` page for more information on\n      specifying colors.\n\n    * For YUV clips, colors are converted from full range (0–255) to limited\n      range (16–235) `Rec.601`_.\n    * Use ``color_yuv`` to specify full range YUV values or a color with a\n      different matrix.\n\n    Default: $000000\n\n.. describe:: color_yuv\n\n    Specifies the color of the clip using YUV values. ``pixel_type`` must be\n    set to one of the YUV formats or a YUV reference clip provided; otherwise\n    an error is raised. See the :ref:`YUV colors <yuv-colors>` for more\n    information.\n\n.. describe:: colors\n\n    Specify the color of the clip using an array. Use this to pass exact,\n    unscaled color values.\n\n    Color order: Y,U,V,A or R,G,B,A\n\n\nExamples\n---------\n\n* Produces a black clip (3000 frames, width 720, height 576, framerate 25),\n  with a silent audio track (16-bit 44.1 kHz stereo):\n\n .. code-block:: c++\n\n    BlankClip(length=3000, width=720, height=576, fps=25, channels=2, color=$000000)\n\n* Produces a black clip (3000 frames) with the remaining clip properties of the\n  reference clip:\n\n .. code-block:: c++\n\n    video = AviSource(\"E:\\pdwork\\DO-Heaven.AVI\")\n    BlankClip(video, length=3000, color=$000000)\n\n* Adds a silent audio stream (with a samplerate of 48 kHz) to a video clip:\n\n .. code-block:: c++\n\n    video = AviSource(\"E:\\pdwork\\DO-Heaven.AVI\")\n    audio = BlankClip(video, audio_rate=48000)\n    AudioDub(video, audio)\n\n* Create an RGB64 clip and specify the colors using an array:\n\n .. code-block:: c++\n\n    BlankClip(pixel_type=\"RGB64\", colors=[64000,32768,1231,65535])\n\n* Create a full range black YUV clip using the ``color_yuv`` parameter:\n\n .. code-block:: c++\n\n    BlankClip(pixel_type=\"YUV420P8\", color_yuv=$008080)\n\n* Create a full range white YUV clip using the ``colors`` parameter:\n\n .. code-block:: c++\n\n    BlankClip(pixel_type=\"YUV420P8\", colors=[255,128,128])\n\n\nChangelog\n----------\n\n+-----------------+--------------------------------------------------------------+\n| Version         | Changes                                                      |\n+=================+==============================================================+\n| AviSynth+ r2487 || BlankClip: new ``colors`` parameter.                        |\n|                 || Added support for the remaining 10-12-14-bit color formats. |\n+-----------------+--------------------------------------------------------------+\n| AviSynth+ r2290 | Added support for RGB48/64 and Planar RGB(A)/YUV(A) color    |\n|                 | formats (16-bit and Float).                                  |\n+-----------------+--------------------------------------------------------------+\n| AviSynth 2.6.0  || Added pixel_type=\"YV24\"/\"YV16\"/\"YV411\"/\"Y8\".                |\n|                 || Supply useful defaults for new Audio/Video when using a     |\n|                 |  Video/Audio only template clip.                             |\n+-----------------+--------------------------------------------------------------+\n| AviSynth 2.5.8  | Added ``channels`` and ``sample_type`` parameters.           |\n+-----------------+--------------------------------------------------------------+\n| AviSynth 2.5.5  | Added ``color_yuv`` parameter.                               |\n+-----------------+--------------------------------------------------------------+\n\n$Date: 2022/09/17 20:09:50 $\n\n.. _Rec.601:\n    https://en.wikipedia.org/wiki/Rec._601\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/blur.rst",
    "content": "\nBlur / Sharpen\n==============\n\n| **Blur** a simple 3x3 `kernel`_ blurring filter.\n| **Sharpen** is 3×3 kernel sharpening filter; the inverse of **Blur**.\n\n\nSyntax and Parameters\n---------------------\n::\n\n    Blur (clip, float amount)\n    Blur (clip, float amountH, float amountV, bool \"mmx\")\n    Sharpen (clip, float amount)\n    Sharpen (clip, float amountH, float amountV, bool \"mmx\")\n\n.. describe:: clip\n\n    Input clip; all color formats supported.\n\n.. describe:: amount\n\n    Blurring or sharpening strength:\n\n    * **Blur**: the allowable range is from -1.0 to +1.58\n    * **Sharpen**: the allowable range  is from -1.58 to +1.0\n    * Negative **Blur** actually sharpens the image; in fact ``Sharpen(n)`` is\n      just an alias for ``Blur(-n)``.\n\n.. describe:: amountH, amountV\n\n    You can use 2 arguments to set independent vertical and horizontal blurring\n    or sharpening, for example:\n\n    * ``Blur(0,1)`` will blur vertical only, perhaps to blend interlaced lines\n      together.\n    * ``Blur(1,0)`` will blur horizontal only.\n    * If *amountV* is not specified, it defaults to *amountH*.\n\n.. describe:: mmx\n\n    **Deprecated** - this parameter is simply ignored.\n\n\nNotes\n-----\n\nIf you need a larger radius Gaussian blur, try ::\n\n    GaussResize(width, height, force=3, p=0.1, s=0) # 3.7.4-\n\nor chaining several Blurs together::\n\n    Blur(1.0).Blur(1.0).Blur(1.0)\n    \nChaining calls to **Sharpen** is not a good idea, as the image quickly deteriorates.\n\n\nDeveloper notes\n---------------\n\n**Blur** uses the kernel [(1−1/2^amount)/2, 1/2^amount, (1−1/2^amount)/2].\nThe largest allowable argument for **Blur** is log2(3) (which is about 1.58),\nwhich corresponds to a (1/3,1/3,1/3) kernel. A value of 1.0 gets you a\n(1/4,1/2,1/4) kernel for example. Likewise ``Blur(1.0).Blur(1.0)`` is a\nconvolution of the kernel (1/4,1/2,1/4) with itself, being a\n(1/4,1/2,1/4)*(1/4,1/2,1/4) = (1/16,4/16,6/16,4/16,1/16) kernel.\nIt can be read of `Pascal's triangle`_.\n\n\nChangelog\n----------\n\n+-----------------+---------------------------------------------------------------------------+\n| Version         | Changes                                                                   |\n+=================+===========================================================================+\n| AviSynth+ 3.7.0 | Fix: Blur right side garbage: 16 bit+AVX2+non mod32 width                 |\n+-----------------+---------------------------------------------------------------------------+\n| AviSynth+ r2664 | Fix: YUY2 Sharpen overflow artifacts - e.g. Sharpen(0.6)                  |\n+-----------------+---------------------------------------------------------------------------+\n| AviSynth+ r2636 | Fix: Blur/Sharpen crashed when YUY2.width<8, RGB32.width<4, RGB64.width<2 |\n+-----------------+---------------------------------------------------------------------------+\n| AviSynth+ r2632 | Enhanced: Blur, Sharpen - AVX2 for 8-16 bit planar formats and SSE2 for   |\n|                 | 32 bit float formats.                                                     |\n+-----------------+---------------------------------------------------------------------------+\n| AviSynth+ r2487 || Blur/Sharpen: support for all planar RGB(A)/YUV(A) and RGB32/64 formats. |\n|                 || Enhanced: Blur, Sharpen- SSE2/SSE4 FOR 10-16 bits planar and RGB64.      |\n|                 || Fix: Blur width=16 (YV12 width=32)                                       |\n+-----------------+---------------------------------------------------------------------------+\n| AviSynth+ r2290 | Blur/Sharpen: added 16/32 bit support.                                    |\n+-----------------+---------------------------------------------------------------------------+\n| AviSynth+ r1576 || Blur/Sharpen: ``mmx`` parameter ignored.                                 |\n|                 || Blur/Sharpen: filters now have C and SSE2 versions.                      |\n+-----------------+---------------------------------------------------------------------------+\n| AviSynth 2.6.0  | Blur/Sharpen: added support for Y8, YV411, YV16 and YV24 color formats.   |\n+-----------------+---------------------------------------------------------------------------+\n| AviSynth 2.5.8  | MMX routines fixed (have full 8 bit precision now); mmx=true by default.  |\n+-----------------+---------------------------------------------------------------------------+\n| AviSynth 2.5.7  | Added ``mmx`` option.                                                     |\n+-----------------+---------------------------------------------------------------------------+\n\n$Date: 2025/03/15 13:40:00 $\n\n.. _kernel:\n    http://en.wikipedia.org/wiki/Kernel_(image_processing)\n.. _Pascal's triangle:\n    https://en.wikipedia.org/wiki/Pascal's_triangle\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/bob.rst",
    "content": "===\nBob\n===\n\n**Bob** takes a clip and bob-deinterlaces it. This means that it enlarges each\nfield into its own frame by interpolating between the lines. The top fields are\nnudged up a little bit compared with the bottom fields, so the picture will not\nactually appear to bob up and down. However, it will appear to \"shimmer\" in\nstationary scenes because the interpolation doesn't really reconstruct the other\nfield very accurately.\n\nThis filter uses :doc:`BicubicResize <resize>` to do its dirty work. See the\n`Technical details`_ section for more information.\n\n\nSyntax and Parameters\n---------------------\n\n::\n\n    Bob (clip, float \"b\", float \"c\", int \"height\")\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n.. describe:: b, c\n\n    The default values correspond to the Mitchell-Netravali cubic filter. See\n    :doc:`BicubicResize <resize>` for more details.\n\n    Default: 1/3, 1/3\n\n.. describe:: height\n\n    Set the height of the output.\n\n    Default: field height * 2\n\n\nTechnical details\n-----------------\n\nA bob filter doesn't really move the physical position of a field. It just\nputs it back where it started. If you just use :doc:`SeparateFields <separatefields>`\nthen you have 2 half height frames: line 0 becomes line 0 of frame 0 and line 1\nbecomes line 0 of frame 1. Thus line 0 and 1 are now in the same place! Bob\nnow basically resizes each frame by a factor of two but in the first frame\nuses the original lines for the even lines and in the second frame uses the\noriginal lines for the odd lines, exactly as is supposed to be. If you just\ndid a resize vertically by a factor of 2 on each frame after doing a\n:doc:`SeparateFields <separatefields>`, then it wouldn't work right because the physical\nposition of a field moves.\n\nSchematic:\nSuppose the lines 0o, 1o, 2o, 3o, ... are original lines and 0i, 1i, 2i, 3i,\n... are the interpolated lines.\n\nStart with:\n\n.. table::\n    :widths: auto\n\n    +-------------+---------+\n    | line number | frame 0 |\n    +=============+=========+\n    | 0           | 0o      |\n    +-------------+---------+\n    | 1           | 1o      |\n    +-------------+---------+\n    | 2           | 2o      |\n    +-------------+---------+\n    | 3           | 3o      |\n    +-------------+---------+\n\nSeparate fields:\n\n.. table::\n    :widths: auto\n\n    +-------------+---------+---------+\n    | line number | frame 0 | frame 1 |\n    +=============+=========+=========+\n    | 0           | 0o      | 1o      |\n    +-------------+---------+---------+\n    | 1           | 2o      | 3o      |\n    +-------------+---------+---------+\n\nDouble size:\n\n.. table::\n    :widths: auto\n\n    +-------------+---------+---------+\n    | line number | frame 0 | frame 1 |\n    +=============+=========+=========+\n    | 0           | 0o      | 1o      |\n    +-------------+---------+---------+\n    | 1           | 1i      | 2i      |\n    +-------------+---------+---------+\n    | 2           | 2o      | 3o      |\n    +-------------+---------+---------+\n    | 3           | 3i      | 4i      |\n    +-------------+---------+---------+\n\nBut this is wrong, because the physical position of the field changed.\n\nBob does it right:\n\n.. table::\n    :widths: auto\n\n    +-------------+---------+---------+\n    | line number | frame 0 | frame 1 |\n    +=============+=========+=========+\n    | 0           | 0o      | 0i      |\n    +-------------+---------+---------+\n    | 1           | 1i      | 1o      |\n    +-------------+---------+---------+\n    | 2           | 2o      | 2i      |\n    +-------------+---------+---------+\n    | 3           | 3i      | 3o      |\n    +-------------+---------+---------+\n\n\nExamples\n--------\n\n**To strictly preserve the original fields and just fill in the missing lines.**\n\n``Bob(0.0, 1.0)`` preserves the original fields for RGB and YUV422 and preserves\nthe Luma but not the Chroma for YUV420.\n\nThe filter coefficients with b=0.0 and c=1.0 give you 0 at x=1.0/2.0 and 1 at\nx=0. Which with the +/-0.25 shift occurring on the original field locations,\nyou get a very crisp cubic filter with -1/8 5/8 5/8 -1/8 coefficients on the\nx=0.5/1.5 taps for the other field.\n\nHowever, since the shift on the chroma planes is only 0.125 for YUV420 the taps\ndon't end up on exactly the same distances. More `discussion`_.\n\n$Date: 2022/03/10 22:35:42 $\n\n.. _discussion: https://forum.doom9.org/showthread.php?p=826073#post826073\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/colorbars.rst",
    "content": "=======================\nColorBars / ColorBarsHD\n=======================\nThe `ColorBars`_. `ColorBarsHD`_ and `ColorBarsUHD`_ filters generate a video clip containing\n`SMPTE color bars`_ scaled to any image size. \n\nYou can find `ColorBarsUHD`_ in a separate document, here we describe the first two version.\nBoth filters also generate audio, see the `audio`_ section for details.\n\n.. _ColorBars:\n\nColorBars\n---------\n\n.. figure:: pictures/colorbars-320x240.png\n   :align: left\n\n**ColorBars** produces a video clip containing SMPTE color bars\n(`Rec. ITU-R BT.801-1`_) scaled to any image size. By default, a 640x480, RGB32,\n`TV range`_, 29.97 fps, 1 hour long clip is produced.\n\nThe color values are computed from ground-truth linear RGB primaries using the\n**BT.601** matrix (``AVS_MATRIX_ST170_M``). This applies to all YUV output formats.\nRGB output formats use the same primaries directly in studio-swing encoding.\n\n|clearfloat|\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    ColorBars (int \"width\", int \"height\", string \"pixel_type\", bool \"staticframes\")\n\n.. describe:: width, height\n\n    Set size of the returned clip.\n\n    Default: 640, 480\n\n.. describe:: pixel_type\n\n    Set color format of the returned clip. May be any of the following: \"RGB24\",\n    \"RGB32\", \"RGB48\", \"RGB64\", \"YUY2\", \"YV12\", \"YV16\" \"YV24\", \"YV411\", or any\n    planar RGBPx, RGBAPx, YUV4xxPx, YUVA4xxPx format.\n\n    Default: \"RGB32\"\n\n.. describe:: staticframes\n\n    If set to false, generate all frames. Default true (one static frame is served).\n\n    Default: true\n\n.. _ColorBarsHD:\n\nColorBarsHD\n-----------\n\n.. figure:: pictures/colorbarshd-320x180.png\n   :align: left\n\n**ColorBarsHD** produces a video clip containing SMPTE color bars\n(Rec. ITU-R BT.709 / `ARIB STD-B28 v1.0`_) scaled to any image size. By default,\na 1288x720, YV24, `TV range`_, 29.97 fps, 1 hour long clip is produced.\n\nThe color values are computed from ground-truth linear RGB primaries using the\n**BT.709** matrix (``AVS_MATRIX_BT709``). Output is always a YUV 4:4:4 format.\n\n|clearfloat|\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    ColorBarsHD (int \"width\", int \"height\", string \"pixel_type\", bool \"staticframes\")\n\n.. describe:: width, height\n\n    Set size of the returned clip.\n\n    Default: 1288, 720\n\n.. describe:: pixel_type\n\n    Set color format of the returned clip. Must be \"YV24\" or any YUV444Px /\n    YUVA444Px format.\n\n    Default: \"YV24\" (identical to \"YUV444P8\")\n\n.. describe:: staticframes\n\n    If set to false, generate all frames. Default true (one static frame is served).\n\n    Default: true\n\nAudio\n-----\n\nFor both filters, an audio :doc:`tone <tone>` is also generated. The tone is a\n440Hz sine at 48KHz sample rate, 32 bit (Float), stereo. The tone pulses in the\nright speaker, being turned on and off once every second. Level is `0 dBFS`_.\n\nYou can use :doc:`Amplify <amplify>` to set a softer level (0dB can be a little\ndeafening!) ::\n\n    ColorBarsHD\n    AmplifyDB(-20)\n\nBroadcasting organizations usually specify an \"alignment tone\" accompanying\ncolorbars at anywhere from -12 to -20 dBFS; if sending materials to another\nparty, be sure to get their preferred alignment tone level. The exact level\ndoesn't matter as long as all parties agree to it.\n\nA note on notation\n------------------\n\nThis page adopts the *ITU style* when discussing video levels which might be\nrepresented at different bit depths:\n\n    **\"** To avoid confusion between 8-bit and 10-bit representations, the eight\n    most-significant bits are considered to be an integer part while the two\n    additional bits, if present, are considered to be fractional part.\n    For example, the bit pattern ``10010001`` would be expressed as 145\\ |d|,\n    whereas the pattern ``1001000101`` would be expressed as 145.25\\ |d|. **\"**\n\n    `ITU-R BT.601-7 (page 4)`_\n\nVideo levels shown below with the subscript \"d\" are assumed to be scaled by 2^(bit depth-8).\nFor example, 235\\ |d| at bit depth 10 becomes 235 × 2^(10-8) = 235 × 4 = 940.\n\n* see `Deep Color`_\n* see `AviSynthPlus color formats`_\n\nTV range\n--------\n\nFor both filters, in all color formats, luminance levels are :doc:`TV (limited)\nrange <../advancedtopics/luminance_levels>`, where black=16\\ |d| and white=235\\ |d|,\nwithin a total possible range of 0-255\\ |d|.\n\nThe table below shows the TV-range values **ColorBarsHD** generates, and those\nsame values as they should be after converting to full range.\n\n:math:`\\mathtt{Y_\\text{full} = (Y_\\text{tv}-16_\\text{d})  × 255_\\text{d}/(235_\\text{d}-16_\\text{d})}` // (for R, G, B, Y)\n\n:math:`\\mathtt{U_\\text{full} = (U_\\text{tv}-128_\\text{d}) × 255_\\text{d}/(240_\\text{d}-16_\\text{d}) + 128_\\text{d}}` // (for U, V)\n\n:math:`\\mathtt{Y_\\text{tv}   = Y_\\text{full} × (235_\\text{d}-16_\\text{d})/255_\\text{d} + 16_\\text{d}} \\quad` // (for R, G, B, Y)\n\n:math:`\\mathtt{U_\\text{tv}   = (U_\\text{full}-128_\\text{d}) × (240_\\text{d}-16_\\text{d})/255_\\text{d} + 128_\\text{d}}` // (for U, V)\n\nThe table below shows the 8-bit TV-range values **ColorBarsHD** generates, and\nthose same values as they should be after converting to full range. At higher\nbit depths, values are computed directly from linear RGB primaries via the\nBT.709 matrix and are not simple left-shifts of these 8-bit codes.\n\n.. table::\n    :widths: auto\n\n    +----------------+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+\n    | Color bar      | TV range output (8-bit)                                               |     | (expanded to full range, 8-bit)                                       |\n    +================+==========+==========+==========+=====+==========+==========+==========+=====+==========+==========+==========+=====+==========+==========+==========+\n    |                | **R**    | **G**    | **B**    |     | **Y**    | **U**    | **V**    |     | **R**    | **G**    | **B**    |     | **Y**    | **U**    | **V**    |\n    +----------------+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+\n    | **75% White**  | 180      | 180      | 180      |     | 180      | 128      | 128      |     | 191      | 191      | 191      |     | 191      | 128      | 128      |\n    +----------------+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+\n    | **75% Yellow** | 180      | 180      | 16       |     | 168      | 44       | 136      |     | 191      | 191      | 0        |     | 177      | 32       | 137      |\n    +----------------+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+\n    | **75% Cyan**   | 16       | 180      | 180      |     | 145      | 147      | 44       |     | 0        | 191      | 191      |     | 150      | 149      | 32       |\n    +----------------+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+\n    | **75% Green**  | 16       | 180      | 16       |     | 133      | 63       | 52       |     | 0        | 191      | 0        |     | 136      | 54       | 41       |\n    +----------------+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+\n    | **75% Magenta**| 180      | 16       | 180      |     | 63       | 193      | 204      |     | 191      | 0        | 191      |     | 55       | 201      | 214      |\n    +----------------+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+\n    | **75% Red**    | 180      | 16       | 16       |     | 51       | 109      | 212      |     | 191      | 0        | 0        |     | 41       | 106      | 223      |\n    +----------------+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+\n    | **75% Blue**   | 16       | 16       | 180      |     | 28       | 212      | 120      |     | 0        | 0        | 191      |     | 14       | 223      | 118      |\n    +----------------+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+\n\nThese colors are at \"75%\" of maximum, per common broadcast practice. You may\noccasionally see \"100%\" color bars.\\ `[1]`_ They are rather useless, as you cannot\ndetect gain or saturation that is too high on a signal that is already at maximum.\n\nPLUGE\n-----\n\nThe lower part of the frame is called the `PLUGE`_ (also lowercase: \"pluge\")\nsignal. From left to right it consists of: `-I`_, white, `+Q`_, then a series of\nblack and near-black bars: 0, -4, 0, +4 and 0 `IRE`_ relative to black.\n\n    **Note** 'IRE' is used here to mean 'percent luminance', on a scale from\n    0 (black) to 100 (white), ignoring the varying broadcast standards where\n    black might be 0 IRE or 7.5 IRE depending on the country.\n\n    This section documents the **ColorBars** pluge only; **ColorBarsHD**'s pluge\n    is similar, but dispenses with -I and +Q.\n\nThe table below shows the 8-bit TV-range values **ColorBars** generates, and\nthose same values as they should be after converting to full range. At higher\nbit depths, values are computed directly from linear RGB primaries via the\nBT.601 (SMPTE 170M) matrix and are not simple left-shifts of these 8-bit codes.\n\n.. table::\n    :widths: auto\n\n    +----------------+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+\n    | PLUGE Element  | TV range output (8-bit)                                               |     | (expanded to full range, 8-bit)                                       |\n    +================+==========+==========+==========+=====+==========+==========+==========+=====+==========+==========+==========+=====+==========+==========+==========+\n    |                | **R**    | **G**    | **B**    |     | **Y**    | **U**    | **V**    |     | **R**    | **G**    | **B**    |     | **Y**    | **U**    | **V**    |\n    +----------------+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+\n    | **-I**         | 16       | 90       | 130      |     | 16       | 158      | 95       |     | 0        | 86       | 130      |     | 0        | 162      | 90       |\n    +----------------+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+\n    | **100% White** | 235      | 235      | 235      |     | 235      | 128      | 128      |     | 255      | 255      | 255      |     | 255      | 128      | 128      |\n    +----------------+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+\n    | **+Q**         | 92       | 16       | 143      |     | 16       | 174      | 149      |     | 88       | 0        | 148      |     | 0        | 180      | 151      |\n    +----------------+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+\n    | Black          | 16       | 16       | 16       |     | 16       | 128      | 128      |     | 0        | 0        | 0        |     | 0        | 128      | 128      |\n    +----------------+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+\n    | **-4 IRE**     | 7        | 7        | 7        |     | 7        | 128      | 128      |     | -10      | -10      | -10      |     | -10      | 128      | 128      |\n    +----------------+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+\n    | Black          | 16       | 16       | 16       |     | 16       | 128      | 128      |     | 0        | 0        | 0        |     | 0        | 128      | 128      |\n    +----------------+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+\n    | **+4 IRE**     | 25       | 25       | 25       |     | 25       | 128      | 128      |     | 10       | 10       | 10       |     | 10       | 128      | 128      |\n    +----------------+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+\n    | Black          | 16       | 16       | 16       |     | 16       | 128      | 128      |     | 0        | 0        | 0        |     | 0        | 128      | 128      |\n    +----------------+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+\n    |                                                                                        |     | *(negative values will be clipped to 0)*                              |\n    +----------------+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+-----+----------+----------+----------+\n\n**Important note on -I and +Q values:** The RGB and YUV values shown above do **not**\nconvert to each other via standard BT.601 matrix conversion. This is intentional and\nreflects the dual-specification nature of these legacy NTSC test signals:\n\n- **RGB output** uses luma-corrected values where the most negative component is lifted\n  to studio black (code 16), ensuring all RGB codes are broadcast-safe (≥16).\n\n- **YUV output** uses zero-luma pure chroma-axis values (Y=16) that preserve the\n  theoretical definition but would require super-black RGB components if converted back.\n\nThe -I and +Q bars are vestigial artifacts of NTSC analog TV and are not really used any more.\n\n    The -4, 0 and +4 IRE bars can be used to set your monitor brightness – assuming\n    your playback chain expands TV range (16-235) to full-range (0-255)\n    as shown in the images above. The -4 IRE and 0 IRE bars should have the same\n    apparent brightness (they should be as dark as the monitor can display), and the\n    +4 should be a little brighter. If you can see the -4 bar, your monitor\n    brightness is set too high; if you cannot see the +4 bar, your monitor\n    brightness is set too low.\\ `[2]`_\n\nNote that the PLUGE signal intentionally includes super-black values in the -4 IRE bar\n(code 7, below studio black at code 16). These test the full capability of the signal\nchain and cannot be accurately represented when converting to full-range 0-255.\n\nMore information about the colorbars and the PLUGE can be found on the\n`color bars theory`_ page.\n\nMiscellaneous\n-------------\n\nNote, that for example ::\n\n    ColorBars(pixel_type=\"YUV444P8\")\n\n...is equivalent to ::\n\n    ColorBars(pixel_type=\"RGB32\")\n    ConvertToYUV444(matrix=\"PC.601\")\n    # \"PC.601\" / \"PC.709\" / \"PC.2020\" don't scale the luma range\n\nWhen directly generating YUV format data, the color transitions are arranged to\noccur on a chroma-aligned boundary.\n\nAdvanced: color value derivation\n---------------------------------\n\nThis section documents the precise mathematical derivation of the color values\nused by **ColorBars** and **ColorBarsHD**, including the handling of the -I and\n+Q PLUGE components.\n\n**ColorBarsHD** derives all color values from ground-truth linear RGB primaries\nusing double-precision arithmetic and the **BT.709** RGB-to-YUV matrix:\n\n.. code-block:: none\n\n    Y  =  0.2126·R + 0.7152·G + 0.0722·B\n    Cb = (B − Y) / 1.8556\n    Cr = (R − Y) / 1.5748\n\n**ColorBars** uses the same approach with the **BT.601** (SMPTE 170M) matrix:\n\n.. code-block:: none\n\n    Y  =  0.299·R + 0.587·G + 0.114·B\n    Cb = (B − Y) / 1.772\n    Cr = (R − Y) / 1.402\n\nFor integer output at any bit depth *n*, the encoding is:\n\n.. code-block:: none\n\n    Y_encoded  = (Y  × 219 + 16 ) × 2^(n−8)   (luma,   limited range)\n    Cb_encoded = (Cb × 224 + 128) × 2^(n−8)   (chroma, limited range)\n    Cr_encoded = (Cr × 224 + 128) × 2^(n−8)   (chroma, limited range)\n\nFor 32-bit float output, the AviSynth limited-range float convention is used,\nderived from the same centralized conversion constants as all other AviSynth\nfilters:\n\n.. code-block:: none\n\n    Y_float  = Y  × (219/255) + (16/255)\n    Cb_float = Cb × (224/255)\n    Cr_float = Cr × (224/255)\n\nAll RGB output formats use studio-swing encoding with the same ground-truth\nprimaries. The helper function ``studio_rgb_to_integer`` encodes a normalized\ndouble value *v* as:\n\n.. code-block:: none\n\n    code = (int)(v × 219 × 2^(n−8) + 16 × 2^(n−8) + 0.5)\n\nwhere *v* = 0.0 maps to studio black (code 16) and *v* = 1.0 maps to\nstudio white (code 235). Convention: normalized values represent limited-range\npositions, where 0.0 = studio black (not absolute black).\n\n**-I and +Q derivation**\n\nThe -I and +Q signals are defined in the YIQ colour space as pure chroma-axis\nsignals with zero luma and 20 IRE saturation (0.2162 normalized):\n\n.. code-block:: none\n\n    -I:  I = −0.2162,  Q = 0\n    +Q:  I = 0,        Q = +0.2162\n\nConverting via the BT.601 UV rotation (Poynton eq. 33, with UV swap):\n\n.. code-block:: none\n\n    -I raw RGB (Y=0):  R = −0.2067,  G = +0.0588,  B = +0.2394\n    +Q raw RGB (Y=0):  R = +0.1343,  G = −0.1400,  B = +0.3685\n\nBoth signals contain out-of-range (negative) RGB components. Three\ninterpretations exist in the literature:\n\n* **Option 1 — Zero-luma, studio black hack** (legacy AviSynth):\n  Y = 16 (studio black). This is a HACK applied differently for RGB vs YUV:\n  \n  - YUV output: Uses raw zero-luma values (Y=16, Cb=158, Cr=95 for -I)\n  - RGB output: Individually adjusted/clipped components to avoid super-blacks\n  \n  Result: Two incompatible specifications that don't convert via standard matrices.\n\n* **Option 2 — Luma-corrected to absolute black** (valid alternative, not used):\n  Luma raised until most negative component reaches code 0 (absolute black).\n  Gives colorimetric consistency but uses super-black range (codes 0-15).\n\n* **Option 3 — Luma-corrected to studio black** *(current RGB implementation)*:\n  Luma raised until most negative component reaches code 16 (studio black).\n  \n  .. code-block:: none\n  \n      For -I: Y_lift = 0.2067 - 16/219 = 0.13364\n      For +Q: Y_lift = 0.1400 - 16/219 = 0.06694\n  \n  After lifting (RGB output):\n  \n  .. code-block:: none\n  \n      -I: R = 16 (studio black), G = 90, B = 130, Y ≈ 77\n      +Q: R = 92, G = 16 (studio black), B = 143, Y ≈ 63\n\n**Dual specification implementation**\n\nThe current implementation maintains **two separate ground-truth tables**:\n\n1. **RGB-native values** (Option 3): Used for RGB output formats\n   \n   - All components >= 16 (broadcast-safe)\n   - Colorimetrically consistent RGB↔YUV conversion\n   - -I: RGB(16, 90, 130) → Y≈77 after BT.601 conversion\n   - +Q: RGB(92, 16, 143) → Y≈63 after BT.601 conversion\n\n2. **YUV-targeted values** (Option 1): Used for YUV output formats\n   \n   - Produces exact legacy values: -I Y=16, +Q Y=16 (zero-luma)\n   - Contains out-of-range RGB components if converted back\n   - Preserves theoretical chroma-axis purity\n\nThis dual-table approach acknowledges historical reality: the original AviSynth\nColorBars had two independent specifications that don't convert to each other.\nThe -I and +Q signals were analog broadcast test signals (voltage levels), not\ndigital RGB/YUV values, and their digital representation requires compromises.\n\nHigher bit-depth output is computed directly from the double-precision ground-truth\nvalues via the full encoding formula — not by bit-shifting 8-bit codes — giving\ngreater accuracy at 10, 12, 14, 16-bit and float.\n\nChangelog\n---------\n\n+------------------+---------------------------------------------------------+\n| Version          | Changes                                                 |\n+==================+=========================================================+\n| AviSynth+ 3.7.6  || ColorBarsHD: fixed high bit-depth output (values now   |\n|                  |  computed from linear RGB primaries via BT.709 matrix   |\n|                  |  instead of upscaling 8-bit table entries).             |\n|                  || ColorBarsHD: fixed ramp in pattern 3                   |\n|                  || ColorBars: fixed high bit-depth output for all YUV     |\n|                  |  and RGB formats (same ground-truth RGB approach).      |\n|                  || ColorBars: fixed reported frame property ``_matrix``   |\n|                  |  to ``AVS_MATRIX_ST170_M`` (BT.601); was incorrectly    |\n|                  |  reporting ``AVS_MATRIX_BT709``.                        |\n|                  || ColorBars: -I and +Q values kept from legacy, but      |\n|                  |  the explanation is included in this documentation.     |\n|                  || Fix: \"staticframes\"=false parameter copied U instead   |\n|                  |  of A for alpha plane.                                  |\n+------------------+---------------------------------------------------------+\n| AviSynth+ 3.4.0  || ColorBars: add support for all YUV(A)422 formats and   |\n|                  |  RGB24, RGB48, YV411.                                   |\n+------------------+---------------------------------------------------------+\n| AviSynth+ r2487  || ColorBars: add support for all YUV(A)444/420, planar   |\n|                  |  RGB(A) formats and RGB64.                              |\n|                  || ColorBarsHD: add support for all YUV(A)444 formats.    |\n+------------------+---------------------------------------------------------+\n| AviSynth 2.6.0   || Added pixel_type=\"YV24\" to ColorBars.                  |\n|                  || Initial release of ColorBarsHD.                        |\n+------------------+---------------------------------------------------------+\n| AviSynth 2.5.6   || Added ``pixel_type`` parameter.                        |\n|                  || Added \"YUY2\" and \"YV12\" pixel types.                   |\n+------------------+---------------------------------------------------------+\n| AviSynth 2.5.5   | Width and height parameters are now named and optional. |\n+------------------+---------------------------------------------------------+\n\n$Date: 2026/02/19 09:57:00 $\n\n.. _SMPTE color bars:\n    https://en.wikipedia.org/wiki/SMPTE_color_bars\n.. _Rec. ITU-R BT.801-1:\n    https://www.itu.int/rec/R-REC-BT.801/en\n.. _ARIB STD-B28 v1.0:\n    https://www.arib.or.jp/english/html/overview/doc/6-STD-B28v1_0-E1.pdf\n.. _0 dBFS:\n    https://en.wikipedia.org/wiki/DBFS\n.. _ITU-R BT.601-7 (page 4):\n    https://www.itu.int/rec/R-REC-BT.601-7-201103-I/en\n.. _Deep Color:\n    http://avisynth.nl/index.php/High_bit-depth_Support_with_Avisynth#What_is_Deep_Color.3F\n.. _AviSynthPlus color formats:\n    http://avisynth.nl/index.php/Avisynthplus_color_formats\n.. _[1]:\n    http://trac.ffmpeg.org/wiki/FilteringGuide#multipleinputoverlayin2x2grid\n.. _PLUGE:\n    https://en.wikipedia.org/wiki/Picture_line-up_generation_equipment\n.. _-I:\n    https://en.wikipedia.org/wiki/YIQ\n.. _+Q:\n    https://en.wikipedia.org/wiki/YIQ\n.. _IRE:\n    https://en.wikipedia.org/wiki/IRE_(unit)\n.. _[2]:\n    http://spearsandmunsil.com/portfolio-item/setting-the-brightness-control-2/\n.. _color bars theory:\n    http://avisynth.nl/index.php/ColorBars_theory\n.. |d| replace:: :sub:`d`\n.. |clearfloat|  raw:: html\n\n    <div class=\"clearer\"></div>"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/colorbarsuhd.rst",
    "content": "============\nColorBarsUHD\n============\n\n.. _ColorBarsUHD:\n\n**ColorBarsUHD** generates a video clip containing UHD/HDR colour bars\nconforming to `Rec. ITU-R BT.2111-3`_ (05/2025). Three signal variants\nare available via the ``mode`` parameter, corresponding to the three\npattern subtypes defined in BT.2111-3.\n\nFor SDR color bars see :ref:`ColorBars <ColorBars>` and :ref:`ColorBarsHD <ColorBarsHD>` filters.\n\nBy default, a 3840×2160, RGBP10, limited-range, 29.97 fps, 1-hour-long\nclip is produced. The height is automatically derived from the width to\nmaintain the 16:9 aspect ratio of the standard 3840×2160 reference.\n\nAudio is also generated — see the audio section in\n:doc:`ColorBars / ColorBarsHD <colorbars>` for details.\n\n.. figure:: pictures/colorbarsuhd_mode0_hlg.png\n   :align: left\n\n   ColorBarsUHD mode=0: HLG narrow range (BT.2111-3 Table 2).\n   75% primary colour bars. RGBP10, limited range.\n   *(Rendered to 8-bit for display purposes.)*\n\n.. figure:: pictures/colorbarsuhd_mode1_pqnarrow.png\n   :align: left\n\n   ColorBarsUHD mode=1: PQ narrow range (BT.2111-3 Table 3).\n   58% primary colour bars with 100% top row. RGBP10, limited range.\n   *(Rendered to 8-bit for display purposes.)*\n\n.. figure:: pictures/colorbarsuhd_mode2_pqfull.png\n   :align: left\n\n   ColorBarsUHD mode=2: PQ full range (BT.2111-3 Table 4).\n   58% primary colour bars with 100% top row. RGBP10, full range.\n   *(Rendered to 8-bit for display purposes.)*\n\n.. figure:: pictures/colorbarsuhd_hlgtosdr.png\n   :align: left\n\n   ColorBarsUHD mode=0 (HLG) converted to SDR/BT.709 using fmtconv\n   display-referred path (ITU Fig. 12), ``lws=1000`` (γ=1.2,\n   reference 1000 cd/m² display).\n   *(Rendered to 8-bit for display purposes.)*\n\n.. figure:: pictures/colorbarsuhd_hlgtosdr10000.png\n   :align: left\n\n   ColorBarsUHD mode=0 (HLG) converted to SDR/BT.709 using fmtconv\n   display-referred path, ``lws=10000`` (γ=1.702 per fmtconv formula,\n   darker SDR result; demonstrates the effect of the ``lws`` parameter).\n   *(Rendered to 8-bit for display purposes.)*\n\n.. figure:: pictures/colorbarsuhd_pqtosdr.png\n   :align: left\n\n   ColorBarsUHD mode=1 (PQ narrow) converted to SDR/BT.709 using\n   fmtconv display-referred path (raw mapping without tone mapping).\n   *(Rendered to 8-bit for display purposes.)*\n\n|clearfloat|\n\nThe six example images above are generated by the following script.\n``ImageWriter`` writes frames 0–5 as PNG files to the ``pictures/``\nsubfolder. The fmtconv ``lws`` parameter on the first HLG transfer is\nthe only ``lw``-family parameter with any effect: it sets the HLG system\ngamma (γ=1.2 at lws=1000, the BT.2100 reference). All ``lw`` parameters\non PQ transfers and on any non-first fmtconv transfer are silently ignored.\n\n.. code-block:: none\n\n    src_hlg       = ColorBarsUHD(width=320, height=180, pixel_type=\"RGBP10\", mode=0)\n    src_pq_narrow = ColorBarsUHD(width=320, height=180, pixel_type=\"RGBP10\", mode=1)\n    src_pq_full   = ColorBarsUHD(width=320, height=180, pixel_type=\"RGBP10\", mode=2)\n\n    # HLG → SDR, lws=1000 → γ=1.2 (reference 1000 cd/m² display)\n    src_hlg.ConvertBits(32, fulld=true)\n    fmtc_transfer(transs=\"hlg\", transd=\"linear\", sceneref=false,\n        \\ fulls=true, fulld=true, lws=1000)\n    fmtc_primaries(prims=\"2020\", primd=\"709\")\n    fmtc_transfer(transs=\"linear\", transd=\"1886\", fulls=true, fulld=true)\n    sdr_hlg = last.ConvertBits(10, fulld=false)\n\n    # HLG → SDR, lws=10000 → γ=1.702 (fmtconv formula; darker; shows lws effect)\n    src_hlg.ConvertBits(32, fulld=true)\n    fmtc_transfer(transs=\"hlg\", transd=\"linear\", sceneref=false,\n        \\ fulls=true, fulld=true, lws=10000)\n    fmtc_primaries(prims=\"2020\", primd=\"709\")\n    fmtc_transfer(transs=\"linear\", transd=\"1886\", fulls=true, fulld=true)\n    sdr_hlg_mod = last.ConvertBits(10, fulld=false)\n\n    # PQ narrow → SDR (display-referred, raw mapping; all lw ignored)\n    src_pq_narrow.ConvertBits(32, fulld=true)\n    fmtc_transfer(transs=\"2084\", transd=\"linear\", sceneref=false,\n        \\ fulls=true, fulld=true)\n    fmtc_primaries(prims=\"2020\", primd=\"709\")\n    fmtc_transfer(transs=\"linear\", transd=\"1886\", fulls=true, fulld=true)\n    sdr_pq = last.ConvertBits(10, fulld=false)\n\n    function ToRGB8(clip c) { return c.ConvertBits(8).ConvertToRGB24() }\n\n    Interleave(\n        \\ ToRGB8(src_hlg), ToRGB8(src_pq_narrow), ToRGB8(src_pq_full),\n        \\ ToRGB8(sdr_hlg), ToRGB8(sdr_hlg_mod),   ToRGB8(sdr_pq))\n    Trim(0, 5).ImageWriter(\"pictures/colorbarsuhd_\", type=\"png\")\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    ColorBarsUHD (int \"width\", int \"height\", string \"pixel_type\",\n                  bool \"staticframes\", int \"mode\")\n\n.. describe:: width, height\n\n    Set the size of the returned clip. The height defaults to\n    ``width × 2160 / 3840``, preserving the standard 16:9 aspect ratio.\n    Standard resolutions supported by the ITU reference geometry are\n    1920×1080 (2K), 3840×2160 (4K) and 7680×4320 (8K), but any width\n    is accepted and the geometry is scaled accordingly.\n\n    Default: 3840, 2160\n\n.. describe:: pixel_type\n\n    Set the colour format of the returned clip. The primary intended\n    formats are:\n\n    - ``\"RGBP10\"`` — planar RGB 10-bit (default, matches ITU reference)\n    - ``\"RGBP12\"`` — planar RGB 12-bit\n\n    The following formats are also supported:\n\n    - Integer: ``\"RGBP8\"``, ``\"RGBP14\"``, ``\"RGBP16\"``\n    - Float: ``\"RGBPS\"`` (32-bit float)\n    - YUV 4:4:4: ``\"YUV444P8\"``, ``\"YUV444P10\"``, ``\"YUV444P12\"``,\n      ``\"YUV444P14\"``, ``\"YUV444P16\"``, ``\"YUV444PS\"``\n\n    YUV output uses the **BT.2020 NCL** matrix (consistent with BT.2111 recommendations)\n    BT.2020 CL (constant luminance) is intentionally not used, as CL\n    encoding computes luma from linear RGB rather than gamma-encoded RGB.\n\n    Default: ``\"RGBP10\"``\n\n.. describe:: staticframes\n\n    If set to false, all frames are generated individually. If true\n    (default), a single static frame is computed once and served for\n    every frame request.\n\n    Default: true\n\n.. describe:: mode\n\n    Selects the signal variant as defined in BT.2111-3:\n\n    - ``0`` — **HLG narrow range** (Table 2). Primary colour bars at\n      75% (code 721 at 10-bit). Transfer: ARIB B67 (HLG).\n      Range: limited (64–940 at 10-bit) for 8-16 bits. 32-bit float output is always full-range.\n    - ``1`` — **PQ narrow range** (Table 3). Primary colour bars at\n      58% (code 573 at 10-bit), 100% top row. Transfer: ST 2084 (PQ).\n      Range: limited (64–940 at 10-bit) for 8-16 bits. 32-bit float output is always full-range.\n    - ``2`` — **PQ full range** (Table 4). Primary colour bars at 58%\n      (code 594 at 10-bit), 100% top row. Transfer: ST 2084 (PQ).\n      Range: full (0–1023 at 10-bit).\n\n    Default: 0 (HLG narrow range)\n\n\nFrame Properties\n----------------\n\nColorBarsUHD sets the following frame properties on the output clip,\nallowing downstream filters such as ``z_ConvertFormat`` (zimg/avsresize)\nto auto-detect the source colour space via ``use_props=1``:\n\n.. table::\n    :widths: auto\n\n    +--------------------+---------------------------+---------------------------+---------------------------+\n    | Property           | mode=0 (HLG)              | mode=1 (PQ narrow)        | mode=2 (PQ full)          |\n    +====================+===========================+===========================+===========================+\n    | ``_Matrix``        | 0 (RGB) for RGB output    | 0 (RGB) for RGB output    | 0 (RGB) for RGB output    |\n    |                    | 9 (BT2020_NCL) for YUV    | 9 (BT2020_NCL) for YUV    | 9 (BT2020_NCL) for YUV    |\n    +--------------------+---------------------------+---------------------------+---------------------------+\n    | ``_Transfer``      | 18 (ARIB_B67 / HLG)       | 16 (ST2084 / PQ)          | 16 (ST2084 / PQ)          |\n    +--------------------+---------------------------+---------------------------+---------------------------+\n    | ``_Primaries``     | 9 (BT.2020)               | 9 (BT.2020)               | 9 (BT.2020)               |\n    +--------------------+---------------------------+---------------------------+---------------------------+\n    | ``_ColorRange``    | 1 (limited) 8-16 bits     | 1 (limited) 8-16 bits     | 0 (full)                  |\n    |                    | 0 (full)    32-bit float  | 0 (full)    32-bit float  |                           |\n    +--------------------+---------------------------+---------------------------+---------------------------+\n\n.. note::\n\n    AviSynth uses an inverted convention for ``_ColorRange`` relative to\n    ITU-T H.265: ``AVS_COLORRANGE_LIMITED = 1`` and\n    ``AVS_COLORRANGE_FULL = 0``. This is the opposite of the\n    ``AVS_RANGE_*`` convention. Inspecting ``_ColorRange`` with\n    ``propShow()`` will show ``1`` for limited-range output (modes 0\n    and 1) and ``0`` for full-range output (mode 2).\n\n\nPattern Layout\n--------------\n\nThe spatial layout follows BT.2111-3 Fig. 1 and is identical across all\nthree modes. The pattern consists of five horizontal rows:\n\n1. **Row 1** (b/12 height) — 100% luminance colour bars\n2. **Row 2** (b/2 height) — 75% (HLG) or 58% (PQ) primary colour bars\n3. **Row 3** (b/12 height) — grey staircase (12 steps)\n4. **Row 4** (b/12 height) — grey ramp (continuous)\n5. **Row 5** (b/4 height) — bottom section: BT.709-equivalent bars,\n   PLUGE, and black/white/black patches\n\nThe 2K reference width is 1920 pixels. All geometry is linearly scaled\nfor other resolutions. At 10-bit the ramp endpoints and stair steps\nmatch the ITU table note values exactly at all standard resolutions\n(2K/4K/8K) and at both 10-bit and 12-bit.\n\n\nSignal Levels\n-------------\nAll signal levels are taken directly from the BT.2111-3 integer code\nvalue tables (Tables 2, 3 and 4 for 10-bit; §5 specifies 12-bit as\n10-bit left-shifted by 2 for narrow range). Full-range signal levels\nat 12-bit have no equivalent bit-shift relationship defined in the\nstandard; the 12-bit PQ full-range tables are defined distinctly in\ntheir own right. For HLG narrow (mode 0) and PQ narrow (mode 1),\nconversion to other bit depths uses the same left-shift for integer\nformats and a normalised float representation for 32-bit float output.\nFor PQ full-range (mode 2), 10-bit and 12-bit levels are each defined\nby their own tables; other bit depths are derived from the 10-bit\nreference values scaled according to full-range rules rather than a\nsimple bit-shift.\nThe BT.709-equivalent colour bars embedded in Row 5 were derived by\nITU per BT.2111-3 Attachment 1 using the HLG OETF and the BT.2087\nlimited-precision matrix (709→2020 direction) — these are the values\nas they appear in the standard, not computed by ColorBarsUHD. This\nmeans ±1–6 code differences from conversion tools are expected and\nnormal — see the HLG-to-SDR conversion notes below.\n\n.. ColorBarsUHD_vectorscope_example_\n\nHLG-to-SDR Conversion: Tool Comparison and Accuracy Notes\n---------------------------------------------------------\n\nThis section documents the behaviour of three widely used conversion\ntools — **fmtconv**, **zimg/avsresize** and **HDRTools** — when converting the\nColorBarsUHD HLG test pattern to SDR/BT.709, and explains the sources\nof discrepancy between them and the ITU-R BT.2111-3 Table 7 reference\nvalues.\n\nUnderstanding these differences is important for anyone using\nColorBarsUHD as a validation source for HLG conversion pipelines.\nThis investigation took considerable effort and is documented here in\nfull so that future users do not need to repeat it.\n\nBoth scene referred and display referred paths were tested. HDRTools \nsupports only display-referred.\n\n\nReference: ITU-R BT.2111-3 Table 7\n------------------------------------\n\nITU-R BT.2111-3 Table 7 provides reference output signal levels for\nboth scene-referred (Fig. 10) and display-referred (Fig. 12)\nHLG-to-SDR conversion of the BT.709-equivalent colour bars in Row 5.\n\nThe ITU reference tool used the following conditions:\n\n- BT.2020-to-BT.709 primaries matrix derived from the **normative\n  3-decimal chromaticity coordinates** specified in BT.2020\n  (R: 0.708/0.292, G: 0.170/0.797, B: 0.131/0.046).\n- The embedded BT.709-equivalent bars were generated using the\n  **BT.2087 limited-precision matrix** (4 decimal places,\n  709→2020 direction). ITU itself notes that ±1–6 code differences\n  from tools using higher-precision matrices are therefore expected.\n- The display-referred path (Fig. 12) appears to have used a\n  **per-channel OOTF** rather than the luminance-weighted OOTF\n  defined in BT.2100, based on backward calculation from the\n  reference values.\n- The output re-encoding used the **BT.1886 EOTF inverse**\n  (pure power x^(1/2.4)), not the BT.709 camera OETF.\n- PLUGE reference values are **not provided** in Table 7. The\n  PLUGE levels are inherently display- and OOTF-dependent, sitting\n  at the edge of visibility where different OOTF implementations\n  diverge most. No single correct output value exists for PLUGE\n  after display-referred conversion.\n\n\nComparison of HDR source rendering by different tools\n-----------------------------------------------------\n\nThe BT.2020-to-BT.709 colour primaries matrix is derived from the\nsource and destination chromaticity coordinates (xy values). The\nITU-R BT.2020 document specifies these to **3 decimal places** as\nthe normative values. However, the underlying spectral locus primaries\ncan be expressed to higher precision (5 decimal places), and some\ntools use these higher-precision values internally.\n\nThis distinction matters critically at **gamut boundary colours** such\nas the BT.709-equivalent Magenta bar, where the green channel value\nafter matrix conversion is essentially zero — sitting right on the\nboundary between a marginally positive and a marginally negative\nnumber.\n\nWith 3-decimal normative coordinates (zimg default, ITU tool)::\n\n    After BT.2020→BT.709 matrix, Magenta green channel: +0.000184\n    → rec_1886_inverse_eotf(0.000184) = 0.02775\n    → output code ≈ 88 = 0x58  (matches ITU Table 7)\n\nWith 5-decimal high-precision coordinates (fmtconv original default)::\n\n    After BT.2020→BT.709 matrix, Magenta green channel: −0.00018\n    → clipped to 0.0 (no negative output)\n    → output code = 64 = 0x40  (diverges from ITU Table 7)\n\nA difference of only **0.00036** in the intermediate green value —\ncaused solely by chromaticity coordinate precision — determines\nwhether green survives or is clipped. This is not a bug in either\ntool; it reflects a genuine ambiguity at the gamut boundary caused\nby the choice of source chromaticity precision.\n\n\nOutput Transfer Function: BT.709 OETF vs BT.1886 EOTF Inverse\n---------------------------------------------------------------\n\nA significant source of discrepancy is the choice of **output\nre-encoding transfer function** for display-referred conversion.\n\nThe BT.709 standard defines two related but distinct curves:\n\n- **BT.709 OETF** (camera curve): encodes scene linear light to\n  signal. Contains a linear segment ``4.5x`` for values below 0.018054.\n  Correct for **scene-referred** encoding.\n- **BT.1886 EOTF inverse**: the mathematical inverse of the display\n  transfer function ``x^(1/2.4)``. This is what actual displays\n  implement, and is the correct re-encoding function for\n  **display-referred** content.\n\nzimg automatically applies the correct substitution based on the\n``scene_referred`` parameter::\n\n    // From zimg transfer.cpp:\n    case TransferCharacteristics::REC_709:\n        func.to_gamma = scene_referred ? rec_709_oetf\n                                       : rec_1886_inverse_eotf;\n\nfmtconv requires the user to explicitly request BT.1886::\n\n    # WRONG for display-referred (uses camera OETF with linear segment):\n    fmtc_transfer(transs=\"linear\", transd=\"709\", ...)\n\n    # CORRECT for display-referred (uses display EOTF inverse):\n    fmtc_transfer(transs=\"linear\", transd=\"1886\", ...)\n\nThe difference is most pronounced at **near-zero signal levels** such\nas the green channel of the BT.709-equivalent Magenta bar (~0.00018\nlinear). In the linear toe of the BT.709 OETF (``4.5 × 0.00018 =\n0.00083``), the result differs dramatically from the BT.1886 path\n(``0.000184^(1/2.4) = 0.02775``), producing output code 65 vs 88.\nThe ITU reference agrees with the BT.1886 result (code 89 = 0x59).\n\nFor **scene-referred** conversion, ``transd=\"709\"`` remains correct\nsince scene-referred encoding uses the camera OETF by definition.\n\n\n.. _ColorBarsUHD_fmtconv_float:\n\nfmtconv: Use Full Float Workflow\n---------------------------------\n\nfmtconv operates internally at **16-bit integer precision** unless the\nsource clip is 32-bit float. Different filters are used for each steps.\nWhen intermediate results are 16-bit integer, two quantisation steps \noccur — after ``fmtc_transfer`` and after ``fmtc_primaries`` — which corrupt \nnear-zero boundary values:\n\n- Marginally negative values (e.g. green = −0.00018) may be clipped\n  to zero at the wrong stage, changing the final result.\n- Marginally positive values near zero lose precision and may round\n  incorrectly.\n- Rounding errors accumulate differently across bars, producing\n  results inconsistent with the full-float path and the ITU reference.\n\n**Always pre-convert to 32-bit float before HLG conversion in\nfmtconv.** When converting a limited-range source to 32-bit float,\nuse ``ConvertBits(32, fulld=true)`` — the ``fulld=true`` parameter\nis required so that fmtconv receives the pixel values in true full\nrange (0.0–1.0) as expected for float input::\n\n    src = ColorBarsUHD(width=1920, height=1080, pixel_type=\"RGBP10\",\n        \\              mode=0)\n    src = src.ConvertBits(32, fulld=true)  # limited-to-float, full range\n    sdr = src\n        \\ .fmtc_transfer(transs=\"hlg\", transd=\"linear\",\n            \\ sceneref=false, fulls=true, fulld=true, lws=1000, lwd=100)\n        \\ .fmtc_primaries(prims=\"2020\", primd=\"709\")\n        \\ .fmtc_transfer(transs=\"linear\", transd=\"1886\",\n            \\ fulls=true, fulld=false, lw=100)\n        \\ .ConvertBits(10)\n\nThe 16-bit intermediate workflow introduces ±1–10 code differences\non boundary colours compared to the full-float path and should be\navoided for validation work.\n\n\nfmtconv HLG System Gamma: Formula and lws Values\n-------------------------------------------------\n\nThe ``lws`` parameter on the first ``fmtc_transfer`` call controls the HLG\nsystem gamma applied during display-referred conversion. The gamma determines\nhow the HLG signal is mapped to the SDR output luminance range.\n\nMeasured values via ``FmtcTransferDbg`` (fmtconv debug output):\n\n.. code-block:: none\n\n    lws = 100  cd/m²:  γ = 0.846,  scale_s = 3.076\n    lws = 1000 cd/m²:  γ = 1.200,  scale_s = 4.922  (BT.2100 reference)\n    lws = 10000 cd/m²: γ = 1.702,  scale_s = 9.592\n\nThe formula fmtconv uses (empirically derived from the debug output) is:\n\n.. code-block:: none\n\n    γ = 1.2^(1 + ln(Lw/1000) / 1.2)\n      equivalently: γ = 1.2 × (Lw/1000)^(ln(1.2)/1.2)\n                      = 1.2 × (Lw/1000)^0.15182\n\nThis differs from both formulas in BT.2100:\n\n.. code-block:: none\n\n    BT.2100 main:      γ = 1.2 + 0.42 × log₁₀(Lw/1000)  → 1.620 at 10000 cd/m²\n    BT.2100 footnote:  γ = 1.2 × 1.111^log₁₀(Lw/1000)   → 1.333 at 10000 cd/m²\n    fmtconv:           γ = 1.2 × (Lw/1000)^0.15182        → 1.702 at 10000 cd/m²\n\nAt ``lws=1000`` all three formulas agree (γ=1.2), so the choice of formula\nonly matters when using non-reference peak luminance values. For\nColorBarsUHD documentation and validation purposes, ``lws=1000`` (γ=1.2)\nis the BT.2100 reference and is the correct value for a 1000 cd/m² HLG display.\n\n\nzimg/avsresize: Required Patch for Scene-Referred HLG\n------------------------------------------------------\n\nAs of 20260319, during the ColorBardsUHD validation work, it turned out, that\nzimg's scene-referred HLG path (Z_ConvertFormat ``scene_referred=true``) contained a\nnormalisation error. The linear scene output was scaled by a hardcoded\nfactor of **12.0** rather than by the correct factor ``1.0 / OETF⁻¹(0.75)``.\n\nThis caused the HLG reference white (E'=0.75) to map to scene-linear\n**3.18** rather than **1.0**, severely overflowing the BT.709 output\nrange and producing clipped ``0x3FF`` values for most colour bars.\n\nThe fix in ``transfer.cpp``, ``select_transfer_function``::\n\n    // BEFORE (wrong): normalises to scene linear 1/12, not ref white\n    func.to_linear_scale = scene_referred ? 12.0f : ...\n\n    // AFTER:\n    if (scene_referred) {\n      // Normalise so that OETF^-1(0.75) = 1.0 (reference white = 1.0 in scene linear).\n      // The original 12.0 normalised to scene linear 1/12, not to reference white.\n      const float ref_white_scene = (std::exp((0.75f - ARIB_B67_C) / ARIB_B67_A) + ARIB_B67_B) / 12.0f; // ~0.26496..\n      func.to_linear_scale = 1.0f / ref_white_scene;\n      func.to_gamma_scale = ref_white_scene;\n    } else ...\n\nAfter this patch, zimg scene-referred results match ITU Table 7\nwithin ±1 code across all bars and agree closely with fmtconv.\n\nAdditionally, ``approximate_gamma=false`` is **mandatory** for zimg\ndisplay-referred HLG conversion. The default ``approximate_gamma=true``\napplies a simplified per-channel power function instead of the correct\nluminance-weighted OOTF, producing severely wrong results for chromatic\ncolours::\n\n    # approximate_gamma=false is mandatory — default true is wrong\n    # for display-referred HLG\n    sdr_zimg = z_ConvertFormat(src, pixel_type=\"RGBP10\",\n        \\ colorspace_op=\"auto:auto:auto:auto=>rgb:709:709:l\",\n        \\ nominal_luminance=203.15,\n        \\ use_props=1,\n        \\ approximate_gamma=false,\n        \\ scene_referred=false)\n\nzimg/avsresize: use full-range RGBP output\n------------------------------------------\n\nzimg does not clamp the float intermediate to the limited-range maximum\nbefore converting to integer RGBP output. Requesting ``=>rgb:709:709:l``\nproduces values up to code 1023 (full-range maximum) even for signal\nthat should be capped at code 940 (limited-range white). This causes\nall colour vectors to appear at inflated radii on the vectorscope.\n\nAlways request full-range output explicitly (``=>rgb:709:709:f``) and\nthen rescale to limited range via ``ConvertBits`` if needed::\n\n    # Wrong: limited-range output clamp is broken in zimg\n    sdr = z_ConvertFormat(src, pixel_type=\"RGBP10\",\n        \\ colorspace_op=\"auto:auto:auto:auto=>rgb:709:709:l\", ...)\n\n    # Correct: request full range, rescale afterwards if needed\n    sdr = z_ConvertFormat(src, pixel_type=\"RGBP10\",\n        \\ colorspace_op=\"auto:auto:auto:auto=>rgb:709:709:f\", ...)\n    sdr_limited = sdr.ConvertBits(10, fulld=false)\n\nThis applies to PQ sources. For HLG display-referred paths the 75% bar\nvalues are safely within BT.709 range so the bug has negligible impact.\n\n.. _ColorBarsUHD_hdrtools_limited:\n\nHDRTools: pre-convert input to 16-bit full range\n-------------------------------------------------\n\nHDRTools builds its internal ``lookupL_32`` transfer-function table in\nfull-range normalised units (0.0–1.0), but indexes it using limited-range\ncode values that have been bit-shifted (code × 64 instead of\ncode × 65535/1023). The mismatch scales by up to ±0.3%, but because\nthe HLG and PQ OETFs are strongly nonlinear, the error produces different\nscaling per channel depending on signal level. On the vectorscope this\nappears as a \"star scatter\": the three bars of each hue group land at\ndifferent radii instead of the same radius.\n\n**Workaround:** pre-convert the limited-range 10-bit source to 16-bit\nfull range before passing it to HDRTools. The ``Coeff_Y=1.0`` path that\nHDRTools uses for full-range input normalises correctly by dividing by 65535.0::\n\n    srcyuv.ConvertBits(16, fulld=true)\n    ConvertYUVtoXYZ(..., fullrange=true)   # fullrange=true is also required\n\nHDRTools: output scale clipping at FF00 instead of FFFF\n--------------------------------------------------------\n\nIn the unpatched HDRTools source, ``ConvertXYZtoYUV`` caps the output\nat ``255 << 8 = 0xFF00 = 65280`` instead of ``0xFFFF = 65535``. At\n10-bit limited range, 75% white should convert to code 940 (0x3AC), but\nthe capped maximum produces code 937 instead. At 100% white the\ndiscrepancy is larger.\n\nThis bug is fixed in the patched source (``data.Max_Y = vmax - 1`` for\nfull range, matching the ``0..65535`` range of ``ConvertYUVtoXYZ``).\nApplying the ``ConvertBits(16, fulld=true)`` workaround above also\navoids the issue on the input side; the output-side fix is required for\ncorrect 100% white reproduction.\n\nzimg/avsresize problems: YUV444P10 output artifacts with PQ\n-----------------------------------------------------------\n\nAt final RGB stage R=7.8 G=0 B=0 is converted then to YUV.\nFully saturated Red -> Yellow, Magenta and blue are affected as well.\n\n\nOOTF Method: Luminance-Weighted vs Per-Channel\n-----------------------------------------------\n\nBT.2100 defines the HLG OOTF as a **luminance-weighted** operation:\nthe system gamma is applied to the luminance Y only, then each RGB\nchannel is scaled proportionally, preserving chromaticity.\n\nfmtconv implements this correctly via its ``GammaY`` module, applying\ngamma to luminance Y and scaling RGB channels proportionally.\n\nzimg (with ``approximate_gamma=false``) applies the inverse OETF first\nthen scales each channel by ``Ys^(gamma-1)`` — equivalent to the\nluminance-weighted OOTF, producing results within ±1–2 codes of ITU.\n\nThe ITU Table 7 display-referred values appear to have been generated\nwith a **per-channel OOTF** (gamma applied independently to each\nchannel), which is technically non-compliant with BT.2100. For neutral\ncolours (R=G=B) all methods are identical. For chromatic colours,\nfmtconv diverges from ITU by up to ±10 codes while zimg diverges by\n±1–2 codes. Neither is incorrect — they implement different valid\ninterpretations of the OOTF, with fmtconv's luminance-weighted approach\nbeing more faithful to BT.2100.\n\nNear-black behaviour differs more sharply between tools because the\nHLG OETF uses a square root curve below E'=0.5, making the OOTF\nhighly nonlinear in that region. PLUGE levels (−2%, +2%, +4%) are\naffected most — fmtconv's approach (OETF⁻¹ first, then scale) is\nmore physically correct near black, while zimg's inside-OETF scaling\ncauses larger deviations in the toe region. Since ITU Table 7 does\nnot provide PLUGE reference values, no tool-independent ground truth\nexists for PLUGE after display-referred conversion.\n\n\nMeasurement Results Summary\n----------------------------\n\nAll measurements on BT.709-equivalent colour bars, 10-bit limited\nrange output. Input: ColorBarsUHD mode=0 (HLG narrow range), RGBP10.\nValues are R/G/B in hexadecimal. Y=Yellow, CY=Cyan, G=Green,\nMt=Magenta, R=Red, B=Blue.\n\nDisplay-referred conversion (ITU Fig. 12)::\n\n    Tool / Configuration               |  Y        |  CY       |  G       |  Mt       |  R       |  B\n    -----------------------------------|-----------|-----------|----------|-----------|----------|----------\n    ITU Table 7 reference              | 3A5 3A6 40| 40 39C 39A| 7C 393 63| 356 59 355| 343 40 40| 5D 40 300\n    fmtconv 5-digit 2020 primaries     | 3A5 3A7 40| 62 39C 39A| 78 393 69| 356 40 355| 342 40 4C| 75 40 300\n    fmtconv 3-digit 2020 primaries     | 3A5 3A7 40| 40 39C 39A| 7B 393 64| 356 58 355| 343 40 40| 5B 40 300\n    zimg (approximate_gamma=false)     | 3A5 3A7 40| 40 39C 39A| 7B 393 64| 356 58 355| 343 40 40| 5B 40 300\n    HDRTools (full-range workaround)   | 3A5 3A7 40| 40 39C 39A| 7B 393 64| 356 58 355| 343 40 40| 5B 40 300\n\nHDRTools with the full-range pre-conversion workaround matches zimg and\nfmtconv (3-digit 2020) exactly. Without it, all bars show systematically\nhigher code values due to the input normalisation mismatch described above.\n\nScene-referred conversion (ITU Fig. 10)::\n\n    Tool / Configuration               |  Y        |  CY       |  G       |  Mt       |  R       |  B\n    -----------------------------------|-----------|-----------|----------|-----------|----------|----------\n    ITU Table 7 reference              | 3AB 3AC 40| 40 3AC 3AB| 47 3AB 42| 3AC 41 3AC| 3AC 40 40| 42 40 3AC\n    fmtconv                            | 3AA 3AC 40| 42 3AC 3AB| 45 3AB 43| 3AC 40 3AC| 3AC 40 40| 48 40 3AC\n    zimg patched                       | 3AB 3AC 40| 40 3AD 3AB| 46 3AB 42| 3AD 41 3AC| 3AD 40 40| 42 40 3AC\n\nPLUGE signal levels after HLG→SDR conversion (no ITU reference values):\n\n.. code-block:: none\n\n    #                  -2%         +2%         +4%       75% white\n    # fmtc scene    40 40 40    41 42 42    47 48 48    3AC 3AC 3AC\n    # zimg scene    40 40 40    42 42 42    48 48 48    3AC 3AC 3AC\n    # fmtc display  40 40 40    40 40 40    42 42 42    3AC 3AC 3AC\n    # zimg display  40 40 40    52 52 52    67 67 67    3AC 3AC 3AC\n\nFor scene-referred conversion, fmtconv and patched zimg agree on PLUGE\nvalues (−2%=40, +2%≈42, +4%≈48) with only ±1 code difference — within\nnormal rounding tolerance.\n\nFor display-referred conversion, zimg gives significantly higher PLUGE\nvalues (+2%=52 vs fmtconv 40, +4%=67 vs fmtconv 42). This is caused by\nzimg's inside-OETF approximation in ``AribB67InverseOperationC``: it\nprescales ``E'`` by ``Ys^0.2`` *before* applying ``OETF^-1`` rather than\nafter. In the near-black square root region of the HLG OETF (``E' ≤ 0.5``)\nthis algebraic shortcut accumulates larger errors than in mid-tones or\nhighlights — precisely where the PLUGE signal lives.\n\nfmtconv applies ``OETF^-1`` first then scales by ``Ys^0.2``, correctly\nseparating the electro-optical inverse from the OOTF power law. This is\nmore physically correct for near-black display-referred content.\n\nSince ITU-R BT.2111-3 Table 7 provides no PLUGE reference values, neither\napproach can be validated against the standard. For PLUGE calibration\npurposes, fmtconv display-referred is the more trustworthy reference.\n\nHDRTools display-referred PLUGE values are not available — HDRTools applies\nits own near-black rounding which has not been measured against this pattern.\n\n.. _ColorBarsUHD_HLG_conversion_scripts:\n\nHLG→SDR Conversion Scripts\n----------------------------\n\nThe scripts below convert ColorBarsUHD mode=0 (HLG) to SDR/BT.709 and\ndisplay the result on a vectorscope. ``targets100=true`` draws the 100%\namplitude target boxes: the 75% HLG primary bars exceed BT.709 range and\nshould clip exactly to these targets.\n\n**Parameter notes for HLG conversion:**\n\n- ``fmtc_use_float = true`` — pre-converts to 32-bit float before fmtconv.\n  Required for accurate results; see :ref:`fmtconv float workflow <ColorBarsUHD_fmtconv_float>`.\n- ``lws=1000`` on the first ``fmtc_transfer`` — sets the HLG system gamma.\n  At lws=1000, γ=1.2 (the BT.2100 reference for a 1000 cd/m² display).\n  fmtconv uses γ = 1.2 × (Lw/1000)^0.15182, which differs from the BT.2100\n  main formula at non-reference values; see the gamma formula section above.\n  This is the only ``lw``-family parameter with any effect in the HLG chain.\n- ``sceneref=true`` — ITU Fig. 10 path: inverse OETF only, no OOTF.\n  Re-encodes to ``transd=\"709\"`` (camera OETF).\n- ``sceneref=false`` — ITU Fig. 12 path: inverse OETF + luminance-weighted OOTF.\n  Re-encodes to ``transd=\"1886\"`` (BT.1886 EOTF inverse, correct for display-referred).\n- ``nominal_luminance=203.15`` — anchors HLG reference white (diffuse white\n  ≈ 203.152 cd/m² at 1000 cd/m² peak) to SDR white.\n- ``approximate_gamma=false`` — mandatory for zimg display-referred HLG;\n  selects the correct luminance-weighted OOTF path.\n- ``scene_referred=false`` / ``true`` — zimg equivalent of ``sceneref``.\n- HDRTools full-range workaround: ``srcyuv.ConvertBits(16, fulld=true)`` +\n  ``fullrange=true`` — required to avoid the lookupL_32 normalisation error;\n  see :ref:`HDRTools limited-range input <ColorBarsUHD_hdrtools_limited>`.\n- ``Coeff=49.2242`` — derived from 1.0 / (OETF⁻¹(0.75)^1.2 × 0.1) = 1.0 / 0.0203152,\n  mapping the HDRTools-normalised display reference white to SDR 1.0.\n\n.. _ColorBarsUHD_HLG_vectorscope_example:\n\n.. code-block:: none\n\n    width = 480\n    fmtc_use_float = true\n\n    srcrgb = ColorBarsUHD(width=width, pixel_type=\"RGBP10\",    mode=0)\n    srcyuv = ColorBarsUHD(width=width, pixel_type=\"YUV444P10\", mode=0)\n\n    src = fmtc_use_float ? srcrgb.ConvertBits(32, fulld=true) : srcrgb\n    use_float = fmtc_use_float\n\n    # ── zimg/avsresize scene-referred (ITU Fig.10) ───────────────────────\n    # Requires patched zimg with corrected HLG scene normalisation.\n    srcrgb\n    sdr_zimg_scene = z_ConvertFormat(pixel_type=\"RGBP10\",\n        \\ colorspace_op=\"auto:auto:auto:auto=>rgb:709:709:f\",\n        \\ nominal_luminance=203.15, use_props=1, scene_referred=true)\n\n    # ── zimg/avsresize display-referred (ITU Fig.12) ─────────────────────\n    # approximate_gamma=false is mandatory — default true is wrong for HLG.\n    srcrgb\n    sdr_zimg_disp = z_ConvertFormat(pixel_type=\"RGBP10\",\n        \\ colorspace_op=\"auto:auto:auto:auto=>rgb:709:709:l\",\n        \\ nominal_luminance=203.15, use_props=1,\n        \\ approximate_gamma=false, scene_referred=false)\n\n    # ── fmtconv scene-referred (ITU Fig.10) ──────────────────────────────\n    src\n    fmtc_transfer(transs=\"hlg\", transd=\"linear\", sceneref=true,\n        \\ fulls=use_float ? true : false, fulld=true, lws=1000)\n    fmtc_primaries(prims=\"2020\", primd=\"709\")\n    fmtc_transfer(transs=\"linear\", transd=\"709\",\n        \\ fulls=true, fulld=use_float ? true : false)\n    sdr_fmtc_scene = last.ConvertBits(10, fulld=false)\n\n    # ── fmtconv display-referred (ITU Fig.12) ────────────────────────────\n    src\n    fmtc_transfer(transs=\"hlg\", transd=\"linear\", sceneref=false,\n        \\ fulls=use_float ? true : false, fulld=true, lws=1000)\n    fmtc_primaries(prims=\"2020\", primd=\"709\")\n    fmtc_transfer(transs=\"linear\", transd=\"1886\",\n        \\ fulls=true, fulld=use_float ? true : false)\n    sdr_fmtc_display = last.ConvertBits(10, fulld=false)\n\n    # ── HDRTools display-referred (ITU Fig.12) ───────────────────────────\n    # Only display-referred is supported. Pre-convert to 16-bit full range\n    # to avoid the lookupL_32 normalisation error (see HDRTools notes above).\n    srcyuv\n    ConvertBits(16, fulld=true)\n    ConvertYUVtoXYZ(Color=0, HDRMode=1, HLGLw=1000,\n        \\ OOTF=false, EOTF=true, OutputMode=2, fullrange=true)\n    ConvertXYZ_Scale_HDRtoSDR(Coeff_X=49.2242, Coeff_Y=49.2242, Coeff_Z=49.2242)\n    ConvertXYZtoYUV(Color=2, pColor=0, OOTF=false, EOTF=true, fullrange=true)\n    sdr_jpsdr_disp = last.ConvertBits(10, fulld=false)\n\n    # ── Vectorscope comparison ────────────────────────────────────────────\n    # targets100=true: 100% amplitude boxes validate that 75% HLG primary\n    # bars (which overflow BT.709) clip to exactly 100% SDR amplitude.\n    # Scene-referred: all same-hued bars should land spot-on the 100% targets.\n    # Display-referred: scatter between same-hued bars is physically correct —\n    # the luminance-weighted OOTF scales each bar differently by luminance.\n    StackVertical(\n        \\ sdr_zimg_scene.ConvertToYUV444(matrix=\"709:l\")\n            \\.Histogram(\"color\", bits=8, targets100=true)\n            \\.Subtitle(\"HLG scene-referred zimg/avsresize\"),\n        \\ sdr_fmtc_scene.ConvertToYUV444(matrix=\"709:l\")\n            \\.Histogram(\"color\", bits=8, targets100=true)\n            \\.Subtitle(\"HLG scene-referred fmtconv\"),\n        \\ sdr_zimg_disp.ConvertToYUV444(matrix=\"709:l\")\n            \\.Histogram(\"color\", bits=8, targets100=true)\n            \\.Subtitle(\"HLG display-referred zimg/avsresize\"),\n        \\ sdr_fmtc_display.ConvertToYUV444(matrix=\"709:l\")\n            \\.Histogram(\"color\", bits=8, targets100=true)\n            \\.Subtitle(\"HLG display-referred fmtconv\"),\n        \\ sdr_jpsdr_disp.Histogram(\"color\", bits=8, targets100=true)\n            \\.Subtitle(\"HLG display-referred HDRTools\")\n    \\ )\n\n.. _ColorBarsUHD_PQ_conversion_scripts:\n\nPQ→SDR Conversion Scripts\n--------------------------\n\nThe scripts below convert ColorBarsUHD mode=1 (PQ narrow) to SDR/BT.709.\n``targets=true`` draws 75% amplitude boxes (58% PQ bars should land here for\nscene-referred); ``targets100=true`` draws 100% boxes (100% top-row bars).\n\n**Parameter notes for PQ conversion:**\n\n- ``lws``, ``lwd``, ``lw`` in fmtconv — **all ignored for PQ**. PQ is an\n  absolute transfer function (1.0 = 10000 cd/m²); fmtconv always divides by\n  10000 regardless of any ``lw`` parameter.\n- ``sceneref=true`` — applies PQ EOTF⁻¹ + OOTF⁻¹ → scene-linear.\n  After scene-referred conversion, 58% PQ primary bars land on the same 75%\n  BT.709 vectorscope targets as HLG scene-referred (same scene light level\n  by ITU design). Re-encodes to ``transd=\"709\"``.\n- ``sceneref=false`` — PQ EOTF only → display-linear. Re-encodes to\n  ``transd=\"1886\"``.\n- ``nominal_luminance=203.1521`` — anchors PQ diffuse white (≈ 203.152 cd/m²,\n  the shared HDR reference white per BT.2408) to SDR white for both scene\n  and display-referred paths.\n- ``=>rgb:709:709:f`` — use full-range zimg RGBP output; limited-range zimg\n  RGBP output is broken for PQ (see zimg limited-range note above).\n- HDRTools: ``HDRMode=0`` for PQ (vs ``HDRMode=1`` for HLG). Same full-range\n  workaround required. ``Coeff=49.2242`` identical derivation as HLG.\n\n.. code-block:: none\n\n    width = 480\n    fmtc_use_float = true\n\n    src    = ColorBarsUHD(width=width, pixel_type=\"RGBP10\",    mode=1)\n    srcyuv = ColorBarsUHD(width=width, pixel_type=\"YUV444P10\", mode=1)\n\n    src = fmtc_use_float ? src.ConvertBits(32, fulld=true) : src\n    use_float = fmtc_use_float\n\n    # ── zimg/avsresize scene-referred ─────────────────────────────────────\n    # Use :f (full range) output — zimg limited-range RGBP output is broken.\n    sdr_zimg_scene = z_ConvertFormat(src, pixel_type=\"RGBP10\",\n        \\ colorspace_op=\"auto:auto:auto:auto=>rgb:709:709:f\",\n        \\ nominal_luminance=203.1521, use_props=1, scene_referred=true)\n\n    # ── zimg/avsresize display-referred ───────────────────────────────────\n    sdr_zimg_disp = z_ConvertFormat(src, pixel_type=\"RGBP10\",\n        \\ colorspace_op=\"auto:auto:auto:auto=>rgb:709:709:f\",\n        \\ nominal_luminance=203.1521, use_props=1,\n        \\ approximate_gamma=false, scene_referred=false)\n\n    # ── fmtconv scene-referred ────────────────────────────────────────────\n    # lws is ignored for PQ — no lw parameter needed anywhere in the PQ chain.\n    src\n    fmtc_transfer(transs=\"2084\", transd=\"linear\", sceneref=true,\n        \\ fulls=use_float ? true : false, fulld=true)\n    fmtc_primaries(prims=\"2020\", primd=\"709\")\n    fmtc_transfer(transs=\"linear\", transd=\"709\",\n        \\ fulls=true, fulld=use_float ? true : false)\n    sdr_fmtc_scene = last.ConvertBits(10, fulld=false)\n\n    # ── fmtconv display-referred ──────────────────────────────────────────\n    src\n    fmtc_transfer(transs=\"2084\", transd=\"linear\", sceneref=false,\n        \\ fulls=use_float ? true : false, fulld=true)\n    fmtc_primaries(prims=\"2020\", primd=\"709\")\n    fmtc_transfer(transs=\"linear\", transd=\"1886\",\n        \\ fulls=true, fulld=use_float ? true : false)\n    sdr_fmtc_display = last.ConvertBits(10, fulld=false)\n\n    # ── HDRTools display-referred ─────────────────────────────────────────\n    # HDRMode=0 for PQ. Same full-range workaround as HLG.\n    srcyuv\n    ConvertBits(16, fulld=true)\n    ConvertYUVtoXYZ(Color=0, HDRMode=0,\n        \\ OOTF=false, EOTF=true, OutputMode=2, fullrange=true)\n    ConvertXYZ_Scale_HDRtoSDR(Coeff_X=49.2242, Coeff_Y=49.2242, Coeff_Z=49.2242)\n    ConvertXYZtoYUV(Color=2, pColor=0, OOTF=false, EOTF=true, fullrange=true)\n    sdr_jpsdr_disp = last.ConvertBits(10, fulld=false)\n\n    # ── Vectorscope comparison ────────────────────────────────────────────\n    # Scene-referred: targets=true → 58% PQ bars land on 75% targets;\n    #                 targets100=true → 100% top-row bars clip to 100%.\n    # Display-referred: targets=false (75% targets not hit by 58% PQ);\n    #                   targets100=true → only 100% bars clip to 100%.\n    StackVertical(\n        \\ sdr_zimg_scene.ConvertToYUV444(matrix=\"709:l\")\n            \\.Histogram(\"color\", bits=8, targets=true, targets100=true)\n            \\.Subtitle(\"PQ scene-referred zimg/avsresize\"),\n        \\ sdr_fmtc_scene.ConvertToYUV444(matrix=\"709:l\")\n            \\.Histogram(\"color\", bits=8, targets=true, targets100=true)\n            \\.Subtitle(\"PQ scene-referred fmtconv\"),\n        \\ sdr_zimg_disp.ConvertToYUV444(matrix=\"709:l\")\n            \\.Histogram(\"color\", bits=8, targets=false, targets100=true)\n            \\.Subtitle(\"PQ display-referred zimg/avsresize\"),\n        \\ sdr_fmtc_display.ConvertToYUV444(matrix=\"709:l\")\n            \\.Histogram(\"color\", bits=8, targets=false, targets100=true)\n            \\.Subtitle(\"PQ display-referred fmtconv\"),\n        \\ sdr_jpsdr_disp.Histogram(\"color\", bits=8, targets=false, targets100=true)\n            \\.Subtitle(\"PQ display-referred HDRTools\")\n    \\ )\n\n.. warning::\n\n    When using fmtconv for PQ→SDR conversion, the 16-bit integer\n    intermediate workflow produces significantly degraded results\n    compared to the 32-bit float workflow. The difference is most\n    visible on the vectorscope for Cyan and Green bars, where the\n    integer workflow causes the colour vectors to land at\n    approximately 50% of their correct radius — far from the\n    expected 75% target positions. This is caused by two\n    quantisation steps (after ``fmtc_transfer`` and after\n    ``fmtc_primaries``) corrupting near-zero and near-gamut-boundary\n    values in the intermediate 16-bit representation.\n\n    Always use the full 32-bit float workflow for fmtconv PQ\n    conversion::\n\n        src = src.ConvertBits(32, fulld=true)  # promote to float first\n\n    The 32-bit float workflow produces results matching zimg within\n    ±1-2 codes across all bars including Cyan and Green, and all six\n    colour vectors land correctly on the 75% vectorscope targets\n    after scene-referred conversion.\n\n\n.. figure:: pictures/colorbarsuhd_pq_scene_fmtconv.png\n   :align: left\n\n   PQ scene-referred — fmtconv (32-bit float).\n\n.. figure:: pictures/colorbarsuhd_pq_scene_fmtconv_integer.png\n   :align: left\n\n   PQ scene-referred — fmtconv (16-bit integer; Cyan/Green at ~50% radius).\n\n.. figure:: pictures/colorbarsuhd_pq_scene_avsresize.png\n   :align: left\n\n   PQ scene-referred — zimg/avsresize (full-range RGBP output).\n\n.. figure:: pictures/colorbarsuhd_pq_scene_avsresize_limited.png\n   :align: left\n\n   PQ scene-referred — zimg/avsresize (limited-range RGBP output, broken).\n\n.. figure:: pictures/colorbarsuhd_pq_scene_avsresize_yuv.png\n   :align: left\n\n   PQ scene-referred — zimg/avsresize YUV444P10 output (overflow artefacts on saturated primaries).\n\n.. figure:: pictures/colorbarsuhd_pq_display_fmtconv.png\n   :align: left\n\n   PQ display-referred — fmtconv (32-bit float).\n\n.. figure:: pictures/colorbarsuhd_pq_display_avsresize.png\n   :align: left\n\n   PQ display-referred — zimg/avsresize (full-range RGBP output).\n\n.. figure:: pictures/colorbarsuhd_pq_display_avsresize_limited.png\n   :align: left\n\n   PQ display-referred — zimg/avsresize (limited-range RGBP output, broken).\n\n.. figure:: pictures/colorbarsuhd_pq_HDRTools_display_full.png\n   :align: left\n\n   PQ display-referred — HDRTools (full-range 16-bit workaround).\n\n.. figure:: pictures/colorbarsuhd_pq_HDRTools_display_limited.png\n   :align: left\n\n   PQ display-referred — HDRTools (limited-range input, broken).\n\n|clearfloat|\n\nHDR Reference White and the 203 cd/m² Value\n-------------------------------------------\n\nBoth PQ and HLG share a common *HDR reference white* — the luminance level\nthat corresponds to diffuse white (a 100% reflectance card) in the HDR signal,\nand which is mapped to SDR white (1.0 = 100 cd/m²) during HDR-to-SDR\nconversion.  The exact numeric value of this anchor depends on which standard\nis being consulted, and at what arithmetic precision the underlying formula is\nevaluated.\n\nBase Formula (HLG)\n^^^^^^^^^^^^^^^^^^\n\nThe value originates from the HLG system.  BT.2100-3 defines the HLG OETF\ninverse for signal levels ``E' >= 0.5`` as::\n\n    E  = exp((E' - c) / a) / 12  +  b / 12\n\nwith constants (BT.2100-3, Note 5c)::\n\n    a = 0.17883277\n    b = 1 - 4a         = 0.28466892\n    c = 0.5 - a*ln(4a) = 0.55991073\n\nHLG reference white sits at signal level ``E' = 0.75``.  Display luminance\nfollows from the HLG OOTF with system gamma ``γ = 1.2`` (nominal 1000 cd/m²\npeak) and peak luminance ``L_W = 1000 cd/m²``::\n\n    F_D = L_W * OETF^-1(0.75)^γ\n        = 1000 * E^1.2\n\nFor PQ the value is adopted directly — BT.2408 designates the same luminance\nas the shared diffuse-white anchor for both systems.  The oft-cited \"58% PQ\"\nfigure is simply ``PQ_OETF(203 cd/m²) ≈ 0.5807`` rounded; it is a consequence\nof the 203 cd/m² definition, not a definition in its own right.\n\nPrecision Variants\n^^^^^^^^^^^^^^^^^^\n\nEvaluating the formula above at different arithmetic precisions, and rounding\nintermediate results as different standards and tools do, yields a family of\nslightly different values:\n\n.. list-table::\n   :header-rows: 1\n   :widths: 32 18 18 32\n\n   * - Source\n     - F_D (cd/m²)\n     - Coeff (10000/F_D)\n     - Notes\n   * - BT.2408 (operational guideline)\n     - 203.0\n     - 49.2611\n     - Rounded integer; human-readable mastering target\n   * - BT.2111-3 (HDR colour bars)\n     - 203.15\n     - 49.2247\n     - Explicitly stated; more precise than BT.2408\n   * - Double precision (64-bit)\n     - 203.1521\n     - 49.2242\n     - Full evaluation of BT.2100-3 constants\n   * - Float32 strict\n     - 203.1522\n     - 49.2242\n     - Differs from double by < 0.0001 cd/m²; operationally identical\n\nBT.2408 rounds to a whole number because a 0.15 nit difference is\nimperceptible in a mastering suite.  BT.2111-3 uses 203.15 because its\ncolour-bar definitions require the value to be mathematically consistent across\nPQ and HLG signal levels to more decimal places, but it does not carry the\nfull precision of the BT.2100-3 formula.  The remaining gap between 203.15\nand 203.1521 (roughly 0.002 cd/m²) is below any meaningful display or grading\nthreshold and arises purely from how many decimal places of the BT.2100-3\nconstants were retained before rounding.\n\n\nChosen Values For Test Scripts\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n.. list-table::\n   :header-rows: 1\n   :widths: 40 15 45\n\n   * - Parameter\n     - Value\n     - Rationale\n   * - zimg / avsresize ``nominal_luminance``\n     - 203.15\n     - Matches the value explicitly stated in BT.2111-3.  Provides more\n       precision than the BT.2408 integer while resting on a direct standard\n       reference rather than a computed approximation.\n   * - HDRTools ``Coeff_X`` / ``Coeff_Y`` / ``Coeff_Z``\n     - 49.2242\n     - Derived as ``1.0 / 0.0203152`` (= ``10000 / 203.1521``), the\n       double-precision result of the BT.2100-3 formula.  Float32 evaluation\n       yields the same four significant figures, so precision mode is not a\n       factor.\n\n\nChangelog\n---------\n\n+------------------+----------------------------------------------------------+\n| Version          | Changes                                                  |\n+==================+==========================================================+\n| AviSynth+ 3.7.6  | Initial release of ColorBarsUHD. Implements              |\n|                  | ITU-R BT.2111-3 (05/2025) with three signal variants:    |\n|                  | HLG narrow range (mode=0), PQ narrow range (mode=1),     |\n|                  | and PQ full range (mode=2). Supports RGBP10/12 as        |\n|                  | primary formats plus 8/14/16-bit integer, 32-bit float,  |\n|                  | and YUV444 output. Height auto-derived from width.       |\n|                  | All frame properties set automatically.                  |\n+------------------+----------------------------------------------------------+\n\nReferences\n----------\n\n* `Rec. ITU-R BT.2111-3`_: Reference service-level HDR colour bar test patterns.\n* `Rec. ITU-R BT.2100`_: Image parameter values for high dynamic range television for use in production and international programme exchange.\n* `Rec. ITU-R BT.2020`_: Parameter values for ultra-high definition television systems for production and international programme exchange.\n* `Rec. ITU-R BT.1886`_: Reference electro-optical transfer function for flat panel displays used in HDTV studio production.\n* `Rec. ITU-R BT.2087`_: Colour conversion from Recommendation ITU-R BT.709 to Recommendation ITU-R BT.2020.\n* `Rec. ITU-R BT.814`_: Specifications of PLUGE test signals and alignment procedures for setting of brightness and contrast of displays.\n* `fmtconv (AviSynth wiki)`_: AviSynth wiki page for the fmtconv plugin.\n* `fmtconv documentation`_: Full HTML reference documentation for fmtconv.\n* `fmtconv releases (GitLab)`_: fmtconv source releases on GitLab.\n* `avsresize (AviSynth wiki)`_: AviSynth wiki page for avsresize (zimg wrapper).\n* `avsresize (Codeberg)`_: avsresize source repository on Codeberg.\n* `zimg (GitHub)`_: zimg scaling and colour space conversion library.\n* `HDRTools (AviSynth wiki)`_: AviSynth wiki page for HDRTools (jpsdr).\n* `HDRTools (GitHub)`_: HDRTools source repository on GitHub.\n\n.. _Rec. ITU-R BT.2111-3:\n    https://www.itu.int/rec/R-REC-BT.2111/en\n.. _Rec. ITU-R BT.2100:\n    https://www.itu.int/rec/R-REC-BT.2100/en\n.. _Rec. ITU-R BT.2020:\n    https://www.itu.int/rec/R-REC-BT.2020/en\n.. _Rec. ITU-R BT.1886:\n    https://www.itu.int/rec/R-REC-BT.1886/en\n.. _Rec. ITU-R BT.2087:\n    https://www.itu.int/rec/R-REC-BT.2087/en\n.. _Rec. ITU-R BT.814:\n    https://www.itu.int/rec/R-REC-BT.814-4-201807-I/en\n.. _fmtconv (AviSynth wiki):\n    http://avisynth.nl/index.php/Fmtconv\n.. _fmtconv documentation:\n    https://htmlpreview.github.io/?https://github.com/EleonoreMizo/fmtconv/blob/master/doc/fmtconv.html\n.. _fmtconv releases (GitLab):\n    https://gitlab.com/EleonoreMizo/fmtconv/-/releases\n.. _avsresize (AviSynth wiki):\n    http://avisynth.nl/index.php/Avsresize\n.. _avsresize (Codeberg):\n    https://codeberg.org/StvG/avsresize\n.. _zimg (GitHub):\n    https://github.com/sekrit-twc/zimg/\n.. _HDRTools (AviSynth wiki):\n    http://avisynth.nl/index.php/HDRTools\n.. _HDRTools (GitHub):\n    https://github.com/jpsdr/HDRTools\n\n\n.. |clearfloat|  raw:: html\n\n    <div class=\"clearer\"></div>\n    \n$Date: 2026/03/28 00:00:00 $"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/coloryuv.rst",
    "content": "\nColorYUV\n========\n\n\nDescription\n-----------\n\n``ColorYUV`` has many different methods of changing the color and luminance \nof your images. Gain, offset, gamma and contrast can be set independently on \neach channel. Also included are two 'auto' modes, an analysis function and a \ncolor gamut generator.\n\nAll settings for this filter are optional. All values are defaulting to \"0\" or false. \ngain,  off,  gamma and cont can be set independent on each channel.\n\n:doc:`RGBAdjust <adjust>` works in a similar manner for RGB clips. \n\n* In AviSynth 2.6, all YUV color formats are supported (Y8, YV12, YV16, YV24, YV411 and YUY2)\n* AVS+ all YUV and YUVA color formats are supported, including Float.\n* AVS+ all relevant parameters are autoscaling – they work without changes at all bit depths as\n  they worked for 8 bit formats.\n\n**Frame properties**\n\n`_ColorRange` property is not set to \"full\" if input has no such\nproperty and range cannot be 100% surely established. In general: when no `_ColorRange` for input and \nno parameter which would rely on a supposed default (such as full range for gamma), then an\noutput frame property is not added.\nWhen no `_ColorRange` for input and no other parameters to hint color range then \n\n- `gamma<>0` sets full range\n- `opt=\"coring\"` sets limited range\n- otherwise no `_ColorRange`   for output would be set\n\nColorYUV sets `_ColorRange` frame property:\n\n* levels = \"TV->PC\" -> full\n* levels = \"PC->TV\" or \"PC->TV.Y\" or \"TV\" -> limited\n* levels = (not given) and _ColorRange property exists -> keeps _ColorRange \n* levels = (not given) and no _ColorRange property  -> full range (old default behaviour)\n\nWhen no hint is given by parameter \"levels\" then use _ColorRange (limited/full) frame property \nfor establishing source range If _ColorRange does not exist, it treats input as full range \n(old default behaviour, gamma-only setting can be changeable with levels=\"TV\")\n\nWhy: when there is no limited<->full conversion, but gamma is provided then this info is still \nused in gamma calculation.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    ColorYUV (clip, \n    float \"gain_y\", float \"off_y\", float \"gamma_y\", float \"cont_y\", \n    float \"gain_u\", float \"off_u\", float \"gamma_u\", float \"cont_u\",\n    float \"gain_v\", float \"off_v\", float \"gamma_v\", float \"cont_v\",\n    string \"levels\", string \"opt\", \n    boolean \"showyuv\", boolean \"analyze\", boolean \"autowhite\",\n    boolean \"autogain\", boolean \"conditional\",\n    int \"bits\", bool \"showyuv_fullrange\", bool \"f2c\", string \"condvarsuffix\")\n\n.. describe:: float gain_y, gain_u, gain_v\n\n  gain_x is a multiplier for the Y, U or V value, and it stretches the signal up from the bottom.\n  \n  If `gain_y` = `k`, then `Y` becomes `Y * (k / 256 + 1)` – for example:\n  \n  (TL;DR see :ref:`Parameter Rescaling <parameter-rescaling>` below) \n\n   +--------+------------------+---------------------------------------+\n   | gain_x |                  | multiplier                            |\n   +--------+------------------+---------------------------------------+\n   |  -256  | (-256 / 256) + 1 | 0.0 (no output)                       |\n   +--------+------------------+---------------------------------------+\n   |  -128  | (-128 / 256) + 1 | 0.5 (darker)                          |\n   +--------+------------------+---------------------------------------+\n   |     0  | (   0 / 256) + 1 | 1.0 (no change)                       |\n   +--------+------------------+---------------------------------------+\n   |   256  | ( 256 / 256) + 1 | 2.0 (brighter)                        |\n   +--------+------------------+---------------------------------------+\n   |   512  | ( 512 / 256) + 1 | 3.0                                   |\n   +--------+------------------+---------------------------------------+\n\n  * `gain_x` is valid down to -256, where a gain of 0.0 is applied.\n  * Although it is possible, it doesn't make sense to apply this setting to the chroma of the signal.\n  * In order to confuse you, in the filter :doc:`Tweak <tweak>` this setting is called contrast.\n\n.. describe:: float off_y, off_u, off_v\n\n  Offset. Adds a value to the luma or chroma values. \n  \n  * An `off_x` of 16 will add 16d to all pixel values.\n  * An `off_x` of -32 will subtract 32d from all pixel values. \n  \n(The `d` suffix means the value must be interpreted as bit-depth scaled.)\n\n.. describe:: float gamma_y (,gamma_u, gamma_v)\n\n  Adjusts gamma of the specified channel, as `X^(1/g)` where `g=(gamma_x + 256) / 256`.\n  For example: \n  (TL;DR see :ref:`Parameter Rescaling <parameter-rescaling>` below) \n\n   +---------+------------------+---------------------------------------+\n   | gamma_x |                  | gamma                                 |\n   +---------+------------------+---------------------------------------+\n   |   -256  | (-256 / 256) + 1 | 0.01                                  |\n   +---------+------------------+---------------------------------------+\n   |   -128  | (-128 / 256) + 1 | 0.5 (darker)                          |\n   +---------+------------------+---------------------------------------+\n   |      0  | (   0 / 256) + 1 | 1.0 (no change)                       |\n   +---------+------------------+---------------------------------------+\n   |    256  | ( 256 / 256) + 1 | 2.0 (lighter)                         |\n   +---------+------------------+---------------------------------------+\n   |    512  | ( 512 / 256) + 1 | 3.0                                   |\n   +---------+------------------+---------------------------------------+\n\n*  gamma_x is valid down to -256, where a minimal gamma of 0.01 is applied (gamma cannot be zero)\n*  Note: gamma for chroma is not implemented (gamma_u and gamma_v are dummy parameters).\n*  will operate on TV range instead of the default PC range when the input clip is known to be in TV range:\n \n   * `levels=\"TV->PC\"`, or \n   * `opt=\"coring\"` and ˙levels` is not `\"PC->TV\"` or `\"PC->TV.Y\"`\n   * `levels=\"TV\"` (no level conversion but gamma will know proper handling)\n\n\n.. describe:: float cont_y, cont_u, cont_v\n\n  Contrast.\n\n  Like gain_X, a multiplier for the value, but stretches or shrinks the signal from the center (128d). \n  This is most useful for the chroma components, where it translates to saturation. \n  If `cont_y = k`, then Y becomes `(Y-128) * k / 256 + 128` – for example: \n  (TL;DR see :ref:`Parameter Rescaling <parameter-rescaling>` below) \n\n   +---------+------------------+---------------------------------------+\n   | cont_x  |                  | contrast                              |\n   +---------+------------------+---------------------------------------+\n   |   -256  | (-256 / 256) + 1 | 0.0 (zero contrast)                   |\n   +---------+------------------+---------------------------------------+\n   |   -128  | (-128 / 256) + 1 | 0.5 (less contrast)                   |\n   +---------+------------------+---------------------------------------+\n   |      0  | (   0 / 256) + 1 | 1.0 (no change)                       |\n   +---------+------------------+---------------------------------------+\n   |    256  | ( 256 / 256) + 1 | 2.0 (more contrast)                   |\n   +---------+------------------+---------------------------------------+\n   |    512  | ( 512 / 256) + 1 | 3.0                                   |\n   +---------+------------------+---------------------------------------+\n\n* cont_x is valid down to -256, where the signal is set to 128d.\n* Although it is possible, it doesn't make sense to apply this setting to the luma of the signal. \n\n\n.. describe:: string levels\n\n  Can be \"TV->PC\", \"PC->TV\", \"PC->TV.Y\", \"TV\" or nothing (default)\n\n  * If levels=\"TV->PC\", a 16d-235d → 0d-255d (contrast increasing) conversion is made\n  * If levels=\"PC->TV\", a 0d-255d → 16d-235d (contrast decreasing) conversion is made\n  * If levels=\"PC->TV.Y\", a 0d-255d → 16d-235d (contrast decreasing) conversion is made, on luma channel only\n  * If levels=\"TV\", no conversion is made; it only tells the filter that gamma_x will operate on a TV range clip.\n  * By default, no conversion is made \n\n.. describe:: string opt\n\n  Can be either \"coring\" or \"\" (nothing, default setting). \n  \n  Specifying \"coring\" will clip your YUV values to the \"TV\" range (luma 16d-235d, chroma 16d-240d). \n  Otherwise values outside that range will be accepted. \n\n\n.. describe:: bool showYUV\n\n  If true, this option will overwrite your image with a new 448x448 image showing all chroma values \n  along the two axes. This can be useful if you need to adjust the color of your image, but need to \n  know how the colors are arranged. At the top left of the image, the chroma values are 16d. At the \n  right side of the image, U is at maximum. At the bottom of the screen V is at its maximum. In the \n  middle both chroma is 128d (or grey). See example image below.\n\n  In Avisynth+ the size changes depending on options selected – see `showyuv_fullrange` below.\n\n  If `bits=8`, output colorspace is `YV12`, else colorspace is `YUV422Pxx` where xx the relevant bit depth.\n  For practical reasons, the image size is maximized to the 10-bit case.\n\n  When \"showyuv_fullrange\"=true case: U and V range is chroma center +/- span (1..max) for integer bit \n  depths instead of 0..max.\n  \n  Shown ranges:\n\n  * bits=8: 128 +/- 127 (range 1..255 is shown) (UV size is 255x255 -> 510x510 image YV12)\n  * bits=10: range 512 +/- 511 (UV size is 1023x1023 -> 2046x2046 image YUV420P10)\n  * bits=12: range 2048 +/- 2047 (UV size is same as 10 bits 1023x1023 -> 2046x2046 image YUV420P12)\n  * bits=14: range 8192 +/- 8191 (UV size is same as 10 bits 1023x1023 -> 2046x2046 image YUV420P14)\n  * bits=16: range 32768 +/- 32767 (UV size is same as 10 bits 1023x1023 -> 2046x2046 image YUV420P16)\n  * bits=32: range 0.0 +/- 0.5 (UV size is same as 10 bits 1023x1023 -> 2046x2046 image YUV420PS)\n  \n  In general: chroma center is 2^(N-1); span is (2^(N-1))-1 where N is the bit depth\n\n\n.. describe:: bool analyze\n\n  If true, ColorYUV will print color channel statistics on the screen (see example below)\n\n  * There is an Average for all channels.\n  * There are Minimum and Maximum values for all channels.\n  * There is Loose Minimum and Loose Maximum which ignore the brightest and darkest 0.4% (1/256) pixels. \n\n.. describe:: bool autowhite\n\n  If true, this option will use the information from the analyzer, and attempt to center the color offsets. \n  If you have recorded some material, where the colors are shifted toward one color, this filter may help. \n  But be careful - it isn't very intelligent - if your material is a clear blue sky, autowhite will make it \n  completely grey! This option overrides off_u and off_v. \n\n.. describe:: bool autogain\n\n  If true, this option will use the information from the analyzer, and attempt to create as good contrast \n  as possible. That means, it will scale up the Y (luma) values to match the minimum and maximum values. \n  This will make it act like an \"autogain\" setting on cameras, amplifying dark scenes very much, while \n  leaving scenes with good contrast alone. Some places this is also referred to as \"autolevels\". \n\n.. describe:: bool conditional\n\n  See the :ref:`Conditional Variables <conditional-variables>` section for an overview of the conditional \n  variables and their use with ColorYUV. If false (the default), ColorYUV will ignore any conditional variables. \n\n.. describe:: int bits = 8\n\n  Sets the bit depth of showyuv output. Must be 8, 10, 12, 14 or 16. \n  Size changes depending on options selected – see next item. \n\n.. describe:: bool showyuv_fullrange = false\n\n  If true, showyuv output is full range instead of TV range. \n\n  * At bits=8, size of the generated clip grows from 450x450 to 512x512.\n  * At bits>8, size of the generated clip grows from 1800x1800 to 2048x2048.\n\n.. describe:: bool f2c = false\n\n  If true, perform :ref:`parameter rescaling <parameter-rescaling>` as described below on all cont_x, gain_x and gamma_x arguments. \n  For example, with f2c=true, cont_u=1.2 results in a 20% increase in U channel \"saturation\". \n\n.. describe:: string condvarsuffix = \"\"\n\n  This parameter works similarly in ColorYUV, RGBAdjust, Overlay, ConditionalReader. \n  Allows multiple filter instances to use differently named conditional parameters, thus preventing collision and overwrite \n  of variables which are used by different ConditionalReader instances. \n  See :ref:`Conditional Variables <conditional-variables>` section.\n\n\nThe quantities *saturation*, *contrast* and *brightness* (as in :doc:`Tweak <tweak>` for\nexample) are connected with quantities in this filter by the following\nequations:\n\n::\n\n    cont_u = cont_v = (sat-1) * 256\n    gain_y = (cont-1) * 256\n    off_y = bright\n\nA saturation of 0.8 gives for example: \n::\n\n    cont_u = cont_v = - 0.2 * 256 = -51.2.\n\nNote that in Tweak your YUV values will always be clipped to valid TV-ranges, but here you \nhave to specify opt=\"coring\".\n\n\n.. _parameter-rescaling:\n\n\nParameter Rescaling\n-------------------\n\nThe quantities saturation, contrast and brightness (as in Tweak for example) are connected with quantities in this filter by the following equations:\n::\n\n    cont_u = cont_v = (sat-1) * 256\n    gain_y = (cont-1) * 256\n    off_y = bright \n\nA saturation of 0.8 gives for example: cont_u = cont_v = -0.2 * 256 = -51.2.\n\nNote that in Tweak your YUV values will always be clipped to valid TV-ranges, but here you have to specify opt=\"coring\".\n\nAvisynth+ has a dedicated bool f2c parameter, just set it true and your parameters are automatically treated like this\nin old Avisynth versions:\n\nYou can add a simple user function to rescale or translate from familiar \"Tweak-like\" units to ColorYUV units:\n::\n\n    function f2c(float f) {\n        return (f - 1.0) * 256.0\n    }\n\n::\n\n    ## usage example: \n    ColorYUV(gain_y=f2c(2.0), cont_u=f2c(1.2), cont_v=f2c(0.8)) \n    ## or:\n    ColorYUV(gain_y=2.0, cont_u=1.2, cont_v=0.8, f2c=true) \n    \n    ## that is, gain is 200%, and contrast (saturation) \n    ## is +20% in the U channel, -20% in the V channel.  \n    \n    ## ...which specified normally, would look like this: \n    ColorYUV(gain_y=256, cont_u=51.2, cont_v=-51.2)\n\n.. _conditional-variables:\n\nConditional Variables\n---------------------\n\nThe global variables ``coloryuv_xxx`` with ``xxx`` = \n\n* ``gain_y``, ``gain_u``, ``gain_v``, \n* ``bright_y``, ``bright_u``, ``bright_v``, \n* ``gamma_y``\n* ``contrast_y``, ``contrast_u`` or ``contrast_v``\n\nare read each frame, and applied. It is possible to modify these variables using \n:doc:`FrameEvaluate <conditionalfilter>` or :doc:`ConditionalReader <conditionalfilter>` .\n\nParameter ``condvarsuffix`` works similarly in ColorYUV, RGBAdjust, Overlay, ConditionalReader. \nAllows multiple filter instances to use differently named conditional parameters, thus preventing \ncollision and overwrite of variables which are used by different ConditionalReader instances. \n\nHow does it work: when reading the global variables, the `condvarsuffix` parameter is appended to \nthe variable name. E.g. ColorYUV will read ``\"coloryuv_gain_y_a\"`` instead of ``\"coloryuv_gain_y\"`` \nwhen ``condvarsuffix`` = ``\"_a\"`` is provided for ColorYUV.\n\nIn the matching ConditionalReader one have to use the modified name as well:\n::\n\n    ConditionalReader(\"coloryuvoffset.txt\", \"coloryuv_gain_y\", false, CondVarSuffix = \"_a\") # \"_a\" is added here by parameter\n    ConditionalReader(\"rgbfix.txt\", \"rgbadjust_r\", false, CondVarSuffix = \"_1\") # \"_1\" is added here by parameter\n    ConditionalReader(\"rgbfix2.txt\", \"rgbadjust_r\", false, CondVarSuffix = \"_2\") # \"_2\" is added here by parameter\n\nor specify the suffixed name directly: \n::\n\n    ConditionalReader(\"coloryuvoffset.txt\", \"coloryuv_gain_y_a\", false) # \"_a\" is added here manually\n\n\nExample:\n\ncoloryuvoffset.txt:\n\n::\n\n    Type float\n    Default 0.0\n\n    I 25 50 0.0 255.0\n    R 75 225 128.0\n    I 250 275 255.0 0.0\n\nthe script:\n\n::\n\n    Colorbars(512,256).ConvertToYV12.Trim(0,299)\n    ColorYUV(cont_y=10, conditional=true)\n    ConditionalReader(\"coloryuvoffset.txt\", \"coloryuv_gain_y\", false)\n    ShowFrameNumber()\n\nSo up to frame 25 gain_y is equal to the default (which is 0.0), for frame 25\nup to 50 the gain_y is increased from 0.0 to 255.0, etc ...\n\nThere are more examples of conditional modification at the\n:doc:`ConditionalReader <conditionalreader>` page.\n\n\nExamples\n--------\n\n::\n\n    # This will adjust gamma for luma, while making luma smaller and chroma U greater:\n    ColorYUV(gamma_y=128, off_y=-16, off_u=5)\n\n    #  Shows all colors. Frame 0 luma is 16, frame 1 luma is 17 and so on.\n    ColorYUV(showyuv=true)\n\n    #  Recovers visibility on very bad recordings.\n    ColorYUV(autogain=true, autowhite=true)\n\n* showyuv: show all colors in the YUV space. Requires a YUV clip as input. \n\n  Returns a YV12, 448x448 clip with source frame rate, duration and audio. \n  Note, not all colors are convertible to RGB - see this discussion on doom9. \n  U values run 16d-239d, left to right, and V values run from 16d-239d, top to bottom. \n  Frame 0 luma is 16d, frame 1 luma is 17d and so on. \n  AVS+ Size changes depending on options selected:\n\n  By default size is 450x450.\n  With showyuv_fullrange=true, size is 512x512.\n  With bits=10, width and height are both multiplied by 4. \n\n::\n\n   ColorYUV(showyuv=true)\n\n.. image:: ./pictures/224px-ColorYUV(showyuv=true)_fr175.png\n\n* Adjusting off_u and off_v to remove color cast (reduce yellow and magenta tints): \n\n::\n\n    ImageSource(\"Lenna.png\")\n    BicubicResize(Width/2, Height/2)\n    ColorYUV(off_u=+6, off_v=-23)\n    Histogram(\"levels\")\n\nbefore:\n\n.. image:: ./pictures/Lenna-256x256-HistogramLevels-original.png\n\nafter: note the U and V range is moved towards the center.\n\n.. image:: ./pictures/Lenna-256x256-HistogramLevels-ColorYUV-1.png\n\n\n* Demonstrating analyze output: \n\n::\n\n    FFmpegSource2(\"sintel.mp4\")\n    BicubicResize(546, 272)\n    ColorYUV(analyze=true)\n\n.. image:: ./pictures/ColorYUV_analyze_Ex1.jpg\n\n+--------------+-----------------------------------------------+\n| Changelog    |                                               |\n+==============+===============================================+\n|              | | Added bits, showyuv_fullrange, f2c          |\n| v3.4 (r2915) | | Added condvarsuffix option                  |\n+--------------+-----------------------------------------------+\n| v2.6         | Added conditional option                      |\n+--------------+-----------------------------------------------+\n\n$Date: 2026/01/27 11:11:11 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/combineplanes.rst",
    "content": "CombinePlanes\n=============\n\nMerges planes of source clip(s) into a target clip.\nIt is similar to ShufflePlanes in Vapoursynth. Performs the functionality of :doc:`SwapUV <swap>`,\n:doc:`YToUV <swap>`, :doc:`MergeChroma <merge>`, :doc:`MergeRGB <mergergb>` and more.\n\nSee also :doc:`Extract <extract>`, :doc:`AddAlphaPlane <mask>`, :doc:`RemoveAlphaPlane <mask>`,\nand :doc:`ShowU/V <showalpha>` filters.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    CombinePlanes(clip,\n        [string planes, string source_planes, string pixel_type, clip sample_clip ] )\n\n    CombinePlanes(clip, clip,\n        [string planes, string source_planes, string pixel_type, clip sample_clip ] )\n\n    CombinePlanes(clip, clip, clip,\n        [string planes, string source_planes, string pixel_type, clip sample_clip ] )\n\n    CombinePlanes(clip, clip, clip, clip,\n        [string planes, string source_planes, string pixel_type, clip sample_clip ] ) \n\n.. describe:: clip\n\n    | Source clip(s). At least one is required. Up to four clips are accepted.\n    | Each clip defines a color plane in the output, as defined by the ``planes`` and \n      ``source_planes`` arguments. \n    | If the clip count is less than the given ``planes`` defined, then the last available \n      clip is used as a source for all later planes. \n\n.. describe:: planes = \"\"\n\n    The target plane order (e.g. \"YVU\", \"YYY\", \"RGB\"); missing target planes will be undefined in the target. \n\n.. describe:: source_planes = \"YUVA\" or \"RGBA\"\n\n    The source plane order, defaulting to \"YUVA\" or \"RGBA\" depending on the video format. \n\n    Source clips can even be mixed from greyscale, YUV, YUVA or planar RGB(A) — the only rule being that the relevant source plane character should match with the clip format, respectively. \n\n.. describe:: pixel_type\n\n    Set color format of the returned clip. Supports all AVS+ color formats. \n\n.. describe:: sample_clip\n\n        If supplied, output pixel_type will match that of sample_clip. \n\n\nExamples\n--------\n\nCombine greyscale clips into YUVA clip::\n\n    U8 = source.UToY8()\n    V8 = source.VToY8()\n    Y8 = source.ConvertToY()\n    A8 = source.AddAlphaPlane(128).AToY8()\n    CombinePlanes(Y8, U8, V8, A8, planes=\"YUVA\", source_planes=\"YYYY\", \n    \\               sample_clip=source) #pixel_type=\"YUV444P8\"\n\nCopy planes between planar RGB(A) and YUV(A) without any conversion\nyuv 4:4:4 <-> planar rgb::\n\n    source = last.ConvertBits(32) # 4:4:4\n    cast_to_planarrgb = CombinePlanes(source, planes=\"RGB\", source_planes=\"YUV\", \n    \\               pixel_type=\"RGBPS\")\n    # get back a clip identical with \"source\"\n    cast_to_yuv = CombinePlanes(cast_to_planarrgb, planes=\"YUV\", source_planes=\"RGB\", \n    \\               pixel_type=\"YUV444PS\")\n\nCreate a black and white planar RGB clip using Y channel.\nSource is a YUV clip.::\n\n    grey = CombinePlanes(source, planes=\"RGB\", source_planes=\"YYY\", \n    \\               pixel_type=\"RGBP8\")\n\nCopy luma from one clip, U and V from another::\n\n    #Source is the template\n    #SourceY is a Y or YUV clip\n    #SourceUV is a YUV clip\n    grey = CombinePlanes(sourceY, sourceUV, planes=\"YUV\", \n    \\               source_planes=\"YUV\", sample_clip = source)\n\nNotes\n-----\n\nOne optimization in CombinePlanes is aimed to have one less memory (plane) copy.\n\nTheory behind: when a frame has exactly one 'user' (no other frames are yet referencing it) then it can \ndirectly be grabbed and made writable without any frame plane content copying.\nWhen this \"I'm the only one\" condition is fulfilled and the below-written conditions are set \nthen it can be a bit quicker than using the ordinary \"make a new frame and copy the referenced input\nframes into that\" logic.\n\n* Source clip has the same format as the target, and the first plane ID is the same.\n  Y comes from first clip (no Y plane copy, the input frame containing Y is reused), U and V are copied\n\n* Second clip has the same format as the target, and the 2nd and 3rd plane ID is the same\n  U and V comes from 2nd clip (no UV copy, frame containing U and V is reused), \n  while Y (or the given first plane ID) is copied from first clip. When there is a \n\nExample::\n\n    Colorbars(pixel_type=\"YV12\")\n    ConvertBits(16)\n    a=last # UV is kept\n    Blur(1)\n    #luma comes from LAST, a's UV is copied to last\n    x=MergeLuma(a,last)\n    y=CombinePlanes(last,a,planes=\"YUV\",pixel_type=\"YUV420P16\")\n    y  # or x\n    Prefetch(4)\n\nComparison: new CombinePlanes and the usual MergeLuma showed ~4600 fps while old CombinePlanes run at only 3540 fps\n\nNote 2\n------\n\nNon-planar formats such as packed RGB or YUY2 inputs will automatically converted to planar RGB or YV16 before CombinePlanes.\n\nNote 3\n------\n\nWhen there is only one input clip, a zero-cost (BitBlt-less, using \"subframes\") method is used, which is much faster.\n\nSuch cases are:\n\n* casting YUV to RGB\n\n* shuffle RGBA to ABGR\n\n* U to Y\n\n* etc..\n\nTarget planes that are not specified, preserve their content.\n\nExamples::\n\n    combineplanes(clipRGBP, planes=\"RGB\",source_planes=\"BGR\") # swap R and B\n    combineplanes(clipYUV, planes=\"GBRA\",source_planes=\"YUVA\",pixel_type=\"RGBAP8\") # cast YUVA to planar RGBA\n    combineplanes(clipYUV, planes=\"Y\",source_planes=\"U\",pixel_type=\"Y8\") # extract U\n\nChangelog\n---------\n\n.. table::\n    :widths: auto\n\n    +-----------------+----------------------------------------------+\n    | Version         | Changes                                      |\n    +=================+==============================================+\n    | AviSynth 3.7.1  | a bit optimized MergeLuma-like cases         |\n    +-----------------+----------------------------------------------+\n    | 20161110        | First added                                  |\n    +-----------------+----------------------------------------------+\n\n$Date: 2023/11/09 11:23:00 $\n\n.. _chroma subsampling:\n    https://en.wikipedia.org/wiki/Chroma_subsampling\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/compare.rst",
    "content": "\nCompare\n=======\n\nCompares two clips (the \"filtered\" clip and the \"original\" clip) and returns the \nfollowing data for each frame: \n\n    | **Mean Absolute Deviation** `[1]`_\n    |     *(minimum, average, maximum)*\n    | **Mean Deviation**\n    |     *(minimum, average, maximum)*\n    | **Max. Positive Deviation**\n    | **Max. Negative Deviation**\n    | **Peak Signal-to-Noise Ratio (PSNR)** `[2]`_\n    |     (minimum, average, maximum)\n    | **PSNR**\n    |     *(minimum, average, maximum)*\n    | **Overall PSNR**\n\nThis data is displayed on screen by default (see `Examples`_), or can \noptionally be written to a *logfile*.\n\nBy default a *PSNR graph* is displayed; this graph shows overall PSNR visually \nas a timeline that grows left-to-right along the bottom of the screen as the \nclip plays. \n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    Compare (clip filtered, clip original, string \"channels\", string \"logfile\", bool \"show_graph\")\n\n.. describe:: filtered, original\n\n    | Source clips; the \"filtered\" clip and the \"original\" clip. Size and color \n      formats must match. \n    | All color formats supported except 32-bit float.\n    | The \"filtered\" clip is returned. \n\n.. describe:: channels\n\n    | Define which color channels to be compared by their initial letters, e.g. \n      \"R\" (=red).\n    | Valid channel letters are:\n\n    * R, G, B, A for RGB(A) clips.\n    * Y, U, V, A for YUV(A) clips.\n    * Y for single channel greyscale clips.\n\n    | Letters are not case sensitive and may be given in any order. \n    | By default, all channels are compared (except for the alpha (A) channel).\n\n    Default: \"\"\n\n.. describe:: logfile\n\n    | If specified, the results will be written to a file, and not drawn on the \n      clip. \n    | Using a logfile is much faster if you need to compare a lot of frames. \n\n    Default: \"\"\n\n.. describe:: show_graph\n\n    If true, the PSNR graph is drawn on the clip.\n\n    Default: true\n\n\nExamples\n--------\n\n* Basic usage – display differences on screen::\n\n    LSMASHVideoSource(\"sintel-2048-surround.mp4\")\n    A = BicubicResize(640, 272).Crop(80, 0, -80, 0)\n    B = A.Sharpen(1.0) ## Sharpen is our filter under test\n    return Compare(B, A)\n\n .. figure:: pictures/compare-sintel-9507.jpg\n    :align: left\n\n\n* Create a log file::\n\n    Compare(clip1, clip2, log=\"compare.log\")\n\n* Compare chroma channels only::\n\n    Compare(clip1, clip2, channels=\"UV\")\n\n* See also the `Doom9 discussion`_.\n\n\nChangelog\n---------\n\n+-----------------+-------------------------------------------------------------+\n| Version         | Changes                                                     |\n+=================+=============================================================+\n| AviSynth+ 3.7.2 || Fix: ``channels`` now defaults to \"Y\" instead of \"YUV\" for |\n|                 |  greyscale input.                                           |\n|                 || Compare: fix 10-14 bit support (graph, PSNR).              |\n+-----------------+-------------------------------------------------------------+\n| AviSynth+ r2150 || Compare: port to 16 bits (RGB48/64, Planar YUV(A)/RGB(A)). |\n|                 || Fix:  Negative SAD in 8 bit SSE branches.                  |\n+-----------------+-------------------------------------------------------------+\n| AviSynth 2.5.8  | YV12 support.                                               |\n+-----------------+-------------------------------------------------------------+\n\n$Date: 2022/02/18 19:42:53 $\n\n.. _[1]:\n    https://en.wikipedia.org/wiki/Statistical_dispersion\n.. _[2]:\n    http://avisynth.nl/index.php/PSNR\n.. _Sintel:\n    https://durian.blender.org/download/\n.. _Doom9 discussion:\n    https://forum.doom9.org/showthread.php?t=29538\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/conditionalfilter.rst",
    "content": "\nConditionalFilter\n=================\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\nCommon things\n-------------\n\nRuntime filters can contain some similar parameters (when applicable)\n\n.. describe:: local\n\n    The bool *local* parameter is like in Gavino's gRunT: affects the scope of \n    variables visible inside the runtime environment. Default is ``local=false``\n    for string expressions, to be compatible with legacy Avisynth.\n\n    For function-like expressions the default is ``local=true``.\n\n    If ``local=true`` the filter will evaluate its run-time script in a new variable scope,\n    avoiding unintended sharing of variables between run-time scripts.\n\n.. describe:: show\n\n    Adding ``show=true`` will display the actual values on the screen.\n\n    default: false\n\n\n\nConditionalFilter\n-----------------\n\n::\n\n    ConditionalFilter (clip testclip, clip source1, clip source2, string expression1,\n                       string operator, string expression2, bool \"show\", bool \"local\" )\n\n    ConditionalFilter (clip testclip, clip source1, clip source2, string expression1,\n                       bool \"show\", bool \"local\" )\n\n    ConditionalFilter (clip testclip, clip source1, clip source2, function func,\n                       bool \"show\", bool \"local\" )\n\n\n``ConditionalFilter`` returns *source1* when the condition formed by\n``expression1+operator+expression2`` is met for current frame, otherwise it\nreturns *source2*. If any function in *expression1* or *expression2* is not\nexplicitly applied to a clip, it will be applied on *testclip*. The audio is\ntaken from *source1*.\n\nThe second and third form in Avisynth+ is an abbreviated version which takes \nonly four compulsory parameters, works like *operator* is ``=`` and *expression2*\nis ``\"true\"`` (similar to Gavino's GConditionalFilter)\n\nThe strings *expression1* and *expression2* can be any numeric or boolean\nexpressions, and may include internal or user functions, as well as some\nadditional functions which are predefined (:ref:`the Runtime Functions <conditional-runtime-functions>`) and the\nspecial runtime variable *current_frame* (the framenumber of the requested\nframe).\n\nThe string operator can be\n\n  * \"equals\" or \"=\", \"==\"\n  * \"greaterthan\" or \">\"\n  * \"lessthan\" or \"<\".\n\nExamples\n~~~~~~~~\n\nThis will choose frames from vid_blur when the average luma value\nof a frame is less than 20. Otherwise frames from vid will be returned.\n::\n\n    vid = AviSource(\"file\")\n    vid_blur = vid.Blur(1.5)\n    ConditionalFilter(vid, vid_blur, vid, \"AverageLuma()\", \"lessthan\", \"20\")\n\n\nConditionalSelect\n-----------------\n\n::\n\n    ConditionalSelect (clip testclip, string expression, clip source0, clip source1, clip source2, ... ,\n                       bool \"show\", bool \"local\")\n\n    ConditionalSelect (clip testclip, function func, clip source0, clip source1, clip source2, ... ,\n                       bool \"show\", bool \"local\")\n\n\n``ConditionalSelect`` returns each one frame from several source clips based\non an integer evaluator. If the expression evaluates to the integer j\n(starting at zero), the frame from the j-th source clip is returned.\n\nThe expression can be either a string or a function object.\n\nIf a frame is requested from a non-existing source clip (say the expression\nevaluates to -1 or 3 in the example above, where 3 source clips are\nsupplied), the frame of the testclip will be returned.\n\nAudio from *testclip* is passed through untouched.\n\nExamples\n~~~~~~~~\n\nThis will return a frame from vid_blur2 when the average luma value of a\nframe (of vid) is less than 15, will return a frame from vid_blur when the\naverage luma value of a frame (of vid) is higher than 15 but smaller than 25.\nOtherwise a frame from vid will be returned.\n\n::\n\n    vid = AviSource(\"file\")\n    vid_blur = vid.Blur(1.0)\n    vid_blur2 = vid.Blur(1.5)\n    ConditionalSelect(vid, \"luma_av = AverageLuma()\"+chr(13)+\"luma_av <\n    25 ? (luma_av < 15 ? 2 : 1) : 0\", vid, vid_blur, vid_blur2)\n\n\n.. _ScriptClip:\n\nScriptClip\n----------\n\n::\n\n    ScriptClip (clip, string filter, bool \"show\", bool \"after_frame\", bool \"local\")\n\n    ScriptClip (clip, function func, bool \"show\", bool \"after_frame\", bool \"local\")\n\n``ScriptClip`` returns the clip returned by the filter or the function evaluated on every\nframe. The string *filter* can be any expression returning a clip, including\ninternal or user clip functions, and may include line breaks (allowing a\nsequence of statements to be evaluated). Also, also some functions which are\npredefined (:ref:`the Runtime Functions <conditional-runtime-functions>`) and the special runtime variable\n*current_frame* (the framenumber of the requested frame) can be used in the\nfilter expression. In the function-like version the function object must return a clip.\n\nParameter ``after_frame=true/false`` option determines if the script should be evaluated \nbefore (default operation) or after the frame has been fetched from the filters above.\n\n\nExamples\n~~~~~~~~\n\n::\n\n    # This will print the difference from the previous frame onto the current one:\n    clip = AviSource(\"c:\\file.avi\")\n    ScriptClip(clip, \"Subtitle(String(YDifferenceFromPrevious))\")\n\n::\n\n    # This will apply blur on each frame based on the difference from the previous.\n    # This will also show how errors are reported on some frames :)\n    clip = AviSource(\"c:\\file.avi\")\n    ScriptClip(clip, \"Blur(YDifferenceFromPrevious/20.0)\")\n\n::\n\n    # This will apply temporalsoften to very static scenes, and apply a _variable_ blur on moving scenes.\n    # Blur is now capped properly. We also assign a variable - and this is why a line break is inserted:\n    function fmin(float f1, float f2) {\n      return (f1<f2) ? f1 : f2\n    }\n    clip = AviSource(\"c:\\file.avi\")\n    T = clip.TemporalSoften(2, 7, 7, 3, 2)\n    ScriptClip(clip, \"diff = YDifferenceToNext()\"+chr(13)+\"diff>2.5 ?\n    Blur(fmin(diff/20, 1.5)) : T\")\n\n::\n\n    # Shows the frame-number in a clip:\n    ScriptClip(\"subtitle(string(current_frame))\")\n\n::\n\n    # Shows 'frame = the frame-number' in a clip:\n    ScriptClip(\"\"\"subtitle(\"frame = \" + string(current_frame))\"\"\")\n\n\nRestrictions\n~~~~~~~~~~~~\n\nThe output of the script MUST be exactly like the clip\ndelivered to ``ScriptClip`` (same colorspace, width and height). Your\nreturned clip is allowed to have different length - but the length from\n*clip* is always used. Audio from *clip* is passed through untouched. For two\nvery different sources (MPEG2DEC3 and AviSource) - you might run into\ncolorspace mismatches. This is known quirk.\n\nMultithreading notes for ScriptClip\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThere were always problems with ScriptClip, namely variable stability in multithreading.\n\nA short history.\n\nAvisynth Neo (an Avisynth+ fork which introduced a lot of new things in Avisynth+)\nknew no mercy and made the behavior correct but incompatible with old scripts.\n\nIts correct variable scope (default ``local=true``) resulted in incompatibility with some old scripts.\nSo scripts written on the assumption of ``local=false`` (legacy Avisynth) did not work.\n\nNeo's (valid) point: they would not allow the following script to show the behavior to print \"3\".\n\n::\n\n     # prints 3 - Avisynth default but seems incorrect\n     global foo=2\n     function PrintFoo(clip c)\n     { c.ScriptClip(\"Subtitle(string(foo))\", local = false) }\n     Version()\n     PrintFoo()\n     foo = 3\n     last\n\n::\n\n     # prints 2 - correct behavior\n     global foo=2\n     function PrintFoo(clip c)\n     { c.ScriptClip(\"Subtitle(string(foo))\", local = true) }\n     Version()\n     PrintFoo()\n     foo = 3\n     last\n\nSo all runtime filters (ConditionalSelect, ConditionalFilter, ScriptClip, ConditionalReader,\nFrameEvaluate, WriteFile, WriteFileIf, WriteFileStart, WriteFileEnd ) accept a bool \"local\" \nparameter which acts same as in GRunT.\n\nIf ``local=true`` (function-syntax default) the filter will evaluate its run-time script in \na new variable scope (opens a new global variable frame), avoiding unintended sharing of variables \nbetween run-time scripts.\n\nIn our present Avisynth+ all legacy (string expression) runtime filters are compatible with the \nlegacy behaviour (``), but one can set the other mode by ``local=true`` parameter. Functions have \na stricter variable scope. See the examples below.\n\nExamples on 'after_frame' and global variable visibility\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n**Example 1**\n\n::\n\n    ColorbarsHD()\n    Expr(\"frameno\",\"\",\"\") # luma is 0..255 for the first 256 frames.\n    # A global variable which ShowChannels is overwriting in each frame\n    global SC_LMn_0 = 2 \n    # ShowChannels (an external filter) sets some global variables \n    # (frame min/max/etc. statistics) e.g. \"SC_LMn_0\" in each frame\n    ShowChannels(SetVar=True,show=false)  \n    \n    # Choose test method\n    #method=0 # String-syntax\n    method=1 # Function-Syntax\n    \n    if(method==0) {\n      # \"string\"-syntax ScriptClip\n      # 'local'=false is the default working mode for\n      # 'after_frame'=true: script should be evaluated AFTER frame has been fetched, because\n      #                     we'd like to display the values set by ShowChannels\n      ScriptClip( \"\"\"subtitle(string(SC_LMn_0) + \" current frame=\" + String(current_frame)) \"\"\", after_frame = true)\n       \n      # Example of delayed display:\n      # Statistics are from previously displayed frame which can be totally off \n      # when moving a slider in VirtualDub.\n      # The reason of this asynchronous mode is because child (upper) script \n      # - ShowChannels in this case - runs _after_ the string evaluation. 'after_frame' is \n      # false by default, it is not necessary to specify, it's here for the sake of the example.\n      # ScriptClip( \"\"\"subtitle(string(SC_LMn_0) + \" current frame=\" + String(current_frame) ) \"\"\", after_frame = false)\n    } else {\n      # function-syntax ScriptClip\n      # Here 'local'=false must be set because local=true is the default for this mode.\n      # A 'function' inside a ScriptClip should have one clip argument or no argument.\n      # 'c' is a parameter which must be passed to the function. Name is not important,\n      # it moves the actual clip into function's scope. This is why we can SubTitle on it.\n      # 'after_frame'=true: script should be evaluated AFTER frame has been fetched, because\n      # we'd like to display the values set by ShowChannels\n      # A function can see only global variables, so it will see the value of 'SC_LMn_0' which ShowChannels set previously.\n      ScriptClip( function [] (c) {c.subtitle(string(SC_LMn_0) ) } , local = false, after_frame = true)\n    }\n\nNote: messaging through global variables is dangerous.\n\nThe example above will not work in multithreaded environment.\n\nIt won't even work consistently in single threaded environment unless the filter which is writing \nthe global variables is a non-cached filter. Only non-cached type filters are ensured to be reached \nat each call from ScriptClip or else its 'GetFrame' method won't even be called.\nIt's because that when a frame is found in Avisynth's cache, it's not evaluated.\n\n**Example 2**\n\nFunction-like syntax: example on ``local=true``.\n\nSafe method: function call from ScriptClip; function which calls a _real_ runtime function.\n\n::\n\n    ColorbarsHD()\n    Trim(0,255)\n    Expr(\"frameno\",\"\",\"\") # luma is 0..255 for the first 256 frames.\n    # function-syntax ScriptClip + runtime function call + dedicated global var demo\n    # Here 'local'=true (for the sake of the demo; this is the default for this mode).\n    # 'local'=true makes a dedicated global variable area, in which 'last' and 'current frame'\n    # 'c' is a parameter which must be passed to the function. Name is not important,\n    # it moves the actual clip into function's scope.\n    # This is why we can SubTitle on it.\n    # A function can see only global variables. 'last' and 'current_frame' are available \n    # here - they are global variables which were set by ScriptClip after creating a \n    # safe global variable stack.\n    # PlaneMinMaxStats writes six global variables \"PlaneStats_min\", \"PlaneStats_max\",\n    # \"PlaneStats_thmin\", \"PlaneStats_thmax\", \"PlaneStats_median\", \"PlaneStats_average\"\n    ScriptClip( function [] () {\n      x=PlaneMinMaxStats(threshold=30, offset=0, plane=1, setvar=true)\n      subtitle(\"min=\" + string(PlaneStats_min) + \" thmax\" + String(PlaneStats_thmax) + \\\n      \" median = \" + String(PlaneStats_Median) + \" median_too=\" + String(x[4]))\n      } , local = true) \n\n**Example 3**\n\nfunction-like syntax with local=true \n\n::\n\n    # local=true -> new GlobalVar sandbox is created, 'current_frame' and 'last' global\n    #               variables are set in it, they are visible for a function\n    ScriptClip( function [] (c) {c.subtitle(string(current_frame) ) } , local = true) \n\n**Example 4**\n\nfunction-like syntax with local=false \n\n::\n\n    # Error: \"I don't know what 'current_frame' means.\n    # local=false -> 'current_frame' and 'last' are set as a simple variables,\n    # but regular variables are not visible inside the function, only globals\n    ScriptClip( function [] (c) { c.subtitle(string(current_frame) ) } , local = false) \n\nWhen the script parameter is not a string but a function (see Function Objects\nhttp://avisynth.nl/index.php/Function_objects) then Avisynth+ works in a \ncorrect way even when multithreading, since the default value of \"local\" is true. \n\n\nFrameEvaluate\n-------------\n\n``FrameEvaluate`` (clip clip, script filter, bool \"after_frame\", bool \"local\")\n\nSimilar to ``ScriptClip``, except the output of the filter is ignored. This\ncan be used for assigning variables, etc. Frames are passed directly through\nfrom the supplied clip.\n\nParameter ``after_frame=true/false`` option determines if the script should be evaluated \nbefore (default operation) or after the frame has been fetched from the filters above.\n\n\nConditionalReader\n-----------------\n\nThis filter allows you to import arbitrary information into a selectable\nvariable.\n\nSee the dedicated :doc:`ConditionalReader <conditionalreader>` page.\n\n\n.. _conditional-runtime-functions:\n\nRuntime Functions\n-----------------\n\nThese are the internal functions which are evaluated every frame.\n\n| These will return the average pixel value of a plane:\n| ``AverageLuma`` (clip)\n| ``AverageChromaU`` (clip)\n| ``AverageChromaV`` (clip)\n| ``AverageR`` (clip)\n| ``AverageG`` (clip)\n| ``AverageB`` (clip)\n| ``AverageA`` (clip)\n\n| These return a float value between 0 and 255 of the absolute difference\n  between two planes:\n| ``RGBDifference`` (clip1, clip2)\n| ``LumaDifference`` (clip1, clip2)\n| ``ChromaUDifference`` (clip1, clip2)\n| ``ChromaVDifference`` (clip1, clip2)\n| ``RDifference`` (clip1, clip2)\n| ``GDifference`` (clip1, clip2)\n| ``BDifference`` (clip1, clip2)\n\nWhen using these functions there is an \"implicit last\" clip (first parameter\ndoesn't have to be specified), so the first parameter is replaced by the\ntestclip.\n\n| These should be quite handy for detecting scene change transitions:\n| ``RGBDifferenceFromPrevious`` (clip)\n| ``YDifferenceFromPrevious`` (clip)\n| ``UDifferenceFromPrevious`` (clip)\n| ``VDifferenceFromPrevious`` (clip)\n| ``RDifferenceFromPrevious`` (clip)\n| ``GDifferenceFromPrevious`` (clip)\n| ``BDifferenceFromPrevious`` (clip)\n| ``RGBDifferenceToNext`` (clip, int \"offset\")\n| ``YDifferenceToNext`` (clip, int \"offset\")\n| ``UDifferenceToNext`` (clip, int \"offset\")\n| ``VDifferenceToNext`` (clip, int \"offset\")\n| ``RDifferenceToNext`` (clip, int \"offset\")\n| ``GDifferenceToNext`` (clip, int \"offset\")\n| ``BDifferenceToNext`` (clip, int \"offset\")\n\n::\n\n    # This will replace the last frame before a scenechange\n    # with the first frame after the scenechange:\n    ConditionalFilter(last, last, last.trim(1,0), \"YDifferenceToNext()\", \">\", \"10\", true)\n\nOther internal functions\n~~~~~~~~~~~~~~~~~~~~~~~~\n| ``PlaneMinMaxStats`` (clip, float threshold, int offset, int plane, bool setvar)\n\n| ``YPlaneMax`` (clip, float threshold, int offset)\n| ``UPlaneMax`` (clip, float threshold, int offset)\n| ``VPlaneMax`` (clip, float threshold, int offset)\n| ``RPlaneMax`` (clip, float threshold, int offset)\n| ``GPlaneMax`` (clip, float threshold, int offset)\n| ``BPlaneMax`` (clip, float threshold, int offset)\n\n| ``YPlaneMin`` (clip, float threshold, int offset)\n| ``UPlaneMin`` (clip, float threshold, int offset)\n| ``VPlaneMin`` (clip, float threshold, int offset)\n| ``RPlaneMin`` (clip, float threshold, int offset)\n| ``GPlaneMin`` (clip, float threshold, int offset)\n| ``BPlaneMin`` (clip, float threshold, int offset)\n\n| ``YPlaneMedian`` (clip, int offset)\n| ``UPlaneMedian`` (clip, int offset)\n| ``VPlaneMedian`` (clip, int offset)\n| ``RPlaneMedian`` (clip, int offset)\n| ``GPlaneMedian`` (clip, int offset)\n| ``BPlaneMedian`` (clip, int offset)\n\n| ``YPlaneMinMaxDifference`` (clip, float threshold, int offset)\n| ``UPlaneMinMaxDifference`` (clip, float threshold, int offset)\n| ``VPlaneMinMaxDifference`` (clip, float threshold, int offset)\n| ``RPlaneMinMaxDifference`` (clip, float threshold, int offset)\n| ``GPlaneMinMaxDifference`` (clip, float threshold, int offset)\n| ``BPlaneMinMaxDifference`` (clip, float threshold, int offset)\n\nThreshold is a percentage, on how many percent of the pixels are allowed\nabove or below minimum. The threshold is optional and defaults to 0.\n\nThe decision is based on creating a histogram on pixel values and counts then\nthe given threshold is checked against this pixel level-pixel count table.\n\nThis histogram cannot be done for 32 bit float data thus 32 bit float pixels\nare converted to 16 bit integer data before creating the histogram.\n\nIf you understand the stuff above, you can proceed with \"advanced conditional\nfiltering\", which tells you a little bit more about conditional filtering.\n\nPlaneMinMaxStats\n~~~~~~~~~~~~~~~~\n\n::\n\n    PlaneMinMaxStats(clip, float \"threshold\", int \"offset\", int \"plane\", bool \"setvar\")\n\nReturns an 6-element array with [min,max,thresholded minimum,thresholded maximum,median,average]\n\n.. describe:: clip\n\n    input clip\n\n.. describe:: threshold\n\n    a percent number between 0.0 and 100.0%. Threshold is a percentage, on how many percent\n    of the pixels are allowed above or below minimum. The threshold is optional and defaults to 0.\n\n    default: 0.0\n\n.. describe:: offset\n\n    if not 0, they can be used for pulling statistics from a frame number relative to the actual one\n\n    defaults: 0\n\n.. describe:: plane\n\n    0, 1, 2 or 3\n\n    * for YUV inputs they mean Y=0,U=1,V=2,A=3 plane\n    * for RGB inputs R=0,G=1,B=2 and A=3 planes\n\n    default: 0\n\n.. describe:: setvar\n\n    when true then it writes a global variables named \n    ``PlaneStats_min``, ``PlaneStats_max``, ``PlaneStats_thmin``, ``PlaneStats_thmax``,\n    ``PlaneStats_median``, ``PlaneStats_median`` and ``PlaneStats_average``\n\n    default: false\n\n\nAdvanced conditional filtering: part I\n--------------------------------------\n\nYou will have to know a few things about the functionality of AviSynth to\nunderstand this section:\nScripts are parsed from top to bottom, but when a frame is requested the last\nfilter is actually being invoked first, requesting frames upwards in the\nfilter chain. For example:\n\n::\n\n    AviSource(\"myfile.avi\")\n    ColorYUV(analyze=true)\n    Histogram() When opening the script in Vdub the following happens\n\n-   When Vdub requests a frame, AviSynth requests the frame from\n    Histogram.\n-   Histogram requests a frame from ColorYUV,\n-   ColorYUV requests a frame from AviSource, which produces the frame,\n    and delivers it to ColorYUV.\n-   ColorYUV processes the image and sends it on to Histogram, which\n    returns it to Vdub.\n\nSo the filter chain basically works backwards (the output is 'pulled' from\nbelow rather than 'pushed' from above), which gives each filter the\npossibility to request several frames from the source above. Conditional\nfilters however, need to evaluate scripts before they request frames from the\nfilter above, because they need to know which filter to call. Another\nimportant issue is that run-time scripts are evaluated in the same context as\nthe main script. Hence only global defined variables in the conditional\nfilter 'environment' can be used inside a function (and vice versa). Have a\nlook at the following script:\n\n::\n\n    v = AviSource(\"E:\\Temp\\Test3\\atomic_kitten.avi\").ConvertToYV12\n\n    function g(clip c)\n    {\n      global w = c\n      c2 = ScriptClip(c, \"subtitle(t)\")\n      c3 = FrameEvaluate(c2, \"t = String(text)\")\n      c4 = FrameEvaluate(c3, \"text = YDifferenceFromPrevious(w)\")\n      return c4\n    }\n\n    g(v)\n\nThis filter chain works like this:\n\n-   When Vdub requests a frame, AviSynth requests a frame from the second\n    FrameEvaluate, the last filter in the chain generated by g().\n-   The second FrameEvaluate evaluates YDifferenceFromPrevious(w), which\n    leads to the following actions:\n\n    -   YDifferenceFromPrevious requests a frame from ConvertToYV12;\n    -   ConvertToYV12 requests a frame from AviSource, which produces the\n        frame, and delivers it to ConvertToYV12;\n    -   ConvertToYV12 processes the image and returns it to\n        YDifferenceFromPrevious;\n    -   YDifferenceFromPrevious requests a second frame from\n        ConvertToYV12, which is obtained in a similar way to the first;\n    -   It then compares the two frames to calculate its result which it\n        delivers to FrameEvaluate.\n\n-   FrameEvaluate assigns this value to the variable text.\n-   After this a frame is requested from the first FrameEvaluate.\n-   The first FrameEvaluate, after evaluating String(text) and assigning\n    this value to the variable *t*, requests a frame from ScriptClip.\n-   ScriptClip sets *last* to the result of ConvertToYV12(), evaluates\n    Subtitle(t) (creating a new, temporary, filter chain), and requests a\n    frame from it.\n\n    -   Subtitle requests a frame from ConvertToYV12;\n    -   ConvertToYV12 requests a frame from AviSource, which produces the\n        frame, and delivers it to ConvertToYV12;\n    -   ConvertToYV12 processes the image and returns it to Subtitle;\n    -   Subtitle adds the specified text to the frame and delivers the\n        result to ScriptClip.\n\n-   ScriptClip returns the subtitled frame to the first FrameEvaluate.\n-   In turn this frame is returned to the second FrameEvaluate, and hence\n    to Avisynth which returns it to VDub.\n\nNotice how the addition of run-time filters and run-time functions makes the\ninteractions between different parts of the filter chain more complex. This\nadded complexity is managed internally by Avisynth, so you needn't worry\nabout it. However, care is required when setting and using variables, as the\norder of events can be less obvious to the script writer (you!).\n\nAs can be seen, *w* is defined as a global variable. This way we can use it\nlater in the script in the conditional environment. If we want to use the\nvariables *t* and *text* in a different function (inside or outside the\nconditional environment), they must also be defined as global variables. Thus\nfor example:\n\n::\n\n    v = AviSource(\"E:\\Temp\\Test3\\atomic_kitten.avi\").ConvertToYV12\n\n    function g(clip c)\n    {\n      global w = c\n      c2 = ScriptClip(c, \"subtitle(t)\")\n      c3 = FrameEvaluate(c2, \"me()\")\n      c4 = FrameEvaluate(c3, \"global text = YDifferenceFromPrevious(w)\")\n      return c4\n    }\n\n    function me()\n    {\n      global t = String(text)\n    }\n\ng(v) This is just an illustration to demonstrate the various\nfeatures. Much of the script above is redundant, and can be removed. The\nfollowing two scripts give the same output\n\n::\n\n    v = AviSource(\"c:\\clip.avi\")\n    # ScriptClip accepts multi-line scripts:\n    Scriptclip(v,\"\n        text = YDifferenceFromPrevious()\n        t = string(text)\n        subtitle(t)\n    \")\n\n    v = AviSource(\"c:\\clip.avi\")\n    ScriptClip(v, \"Subtitle(String(YDifferenceFromPrevious))\")\n\nIn the following section some frame dependent info will be written to a text-file.\n\nAdvanced conditional filtering: part II\n---------------------------------------\n\nIn the following example, some frame dependent info will be written to a\ntext-file. The first variable \"a\" indicates whether the frame is combed (for\na certain threshold). Note that IsCombed is a filter from the Decomb plugin.\nThe second variable \"b\" indicates whether there is \"much\" movement in the\nframe.\n\n::\n\n    global sep=\".\"\n    global combedthreshold=25\n\n    function IsMoving()\n    {\n    global b = (diff < 1.0) ? false : true\n    }\n\n    function CombingInfo(clip c)\n    {\n    file = \"F:\\interlace.log\"\n    global clip = c\n    c = WriteFile(c, file, \"a\", \"sep\", \"b\")\n    c = FrameEvaluate(c, \"global a = IsCombed(clip, combedthreshold)\")\n    c = FrameEvaluate(c, \"IsMoving\")\n    c = FrameEvaluate(c, \"global diff =\n    0.50*YDifferenceFromPrevious(clip) + 0.25*UDifferenceFromPrevious(clip) +\n    0.25*VDifferenceFromPrevious(clip)\")\n    return c\n    }\n\n    v = mpeg2source(\"F:\\From_hell\\from_hell.d2v\").trim(100,124)\n    CombingInfo(v)\n\nWe can tidy up the two functions, and remove global variables, by writing\nthem as follows:\n\n::\n\n    function IsMoving(float diff)\n    {\n     return (diff >= 1.0)\n    }\n\n    function CombingInfo(clip c)\n    {\n     file = \"F:\\interlace.log\"\n\n     c = WriteFile(c, file, \"a\", \"sep\", \"b\")\n     c = FrameEvaluate(c,\"\n           diff = 0.50*YDifferenceFromPrevious() +\n           0.25*UDifferenceFromPrevious() + 0.25*VDifferenceFromPrevious()\n           b = IsMoving(diff)\n           a = IsCombed(combedthreshold)\n         \")\n\n     return c\n    }\n\nIn the following section an example of \"adaptive motion/resizing filter\" will\nbe considered.\n\n\nAdvanced conditional filtering: part III\n----------------------------------------\n\nSome adaptive motion/resizing filters appeared on the forums. These filters\ndiscriminate between low, medium and high motion in a clip (on frame basis).\nBy doing that, different filters can be used for different kind of motion in\nthe clip. In general, one should use temporal smoothing in low motion scenes,\nspatial smoothing in high motion scenes and use spatio-temporal smoothing in\nmedium motion scenes.\n\nBelow, a simplified version of QUANTIFIED MOTION FILTER v1.5 b1 (10/07/2003)\nby HomiE FR, is given:\n\n::\n\n    ----------------------------------------------------\n    # QUANTIFIED MOTION FILTER v1.3\n    # LOADING AVISYNTH PLUGINS\n    LoadPlugin(\"C:\\PROGRA~1\\GORDIA~1\\mpeg2dec3.dll\")\n    LoadPlugin(\"C:\\PROGRA~1\\GORDIA~1\\TemporalCleaner.dll\")\n    LoadPlugin(\"C:\\PROGRA~1\\GORDIA~1\\FluxSmooth.dll\")\n    LoadPlugin(\"C:\\PROGRA~1\\GORDIA~1\\UnFilter.dll\")\n\n    # LOADING QUANTIFIED MOTION FILTER SCRIPT\n\n    Import(\"E:\\temp\\QMF\\qmf.avs\")\n\n    # LOW MOTION FILTER FUNCTION\n    # -> SHARP RESIZING + TEMPORAL ONLY\n    function Low_Motion_Filter(clip c)\n    {\n      c = TemporalCleaner(c, 5, 10)\n      c = LanczosResize(c, 512, 272)\n      return c\n    }\n\n    # MEDIUM MOTION FILTER FUNCTION\n    # -> NEUTRAL BICUBIC RESIZING + TEMPORAL & SPATIAL\n    function Medium_Motion_Filter(clip c)\n    {\n      c = FluxSmooth(c, 7, 7)\n      c = BicubicResize(c, 512, 272, 0.00, 0.50)\n      return c\n    }\n\n    # HIGH MOTION FILTER FUNCTION\n    # -> SOFT RESIZING + SPATIAL ONLY\n    function High_Motion_Filter(clip c)\n    {\n      c = FluxSmooth(c, -1, 14)\n      c = UnFilter(c, -30, -30)\n      c = BilinearResize(c, 512, 272)\n      return c\n    }\n\n    # OPENING VIDEO SOURCE\n    AviSource(\"E:\\temp\\QMF\\britney-I_love_rock_'n_roll.avi\")\n    ConvertToYV12(interlaced=true)\n    Telecide(0)\n\n    # APPLYING ADAPTATIVE RESIZING FILTER (USING QMF)\n    QMF()\n    ----------------------------------------------------\n\n    # QUANTIFIED MOTION FILTER (17/08/2003) by HomiE FR\n    (homie.fr@wanadoo.fr)\n    # MOTION ESTIMATION FUNCTION\n    function ME()\n    {\n      # SETTING MOTION LEVEL ACCORDING TO AVERAGE DIFFERENCE [1]\n      **global motion_level** = (**diff** < threshold_lm) ? 0 :\n      motion_level\n      **global motion_level** = (**diff** >= threshold_lm && **diff**\n      <= threshold_hm) ? 1 : motion_level\n      **global motion_level** = (**diff** > threshold_hm) ? 2 :\n      motion_level\n    }\n\n    # QUANTIFIED MOTION FILTER FUNCTION\n    function QMF(clip c, float \"threshold_lm\", float \"threshold_hm\", bool\n    \"debug\")\n    {\n      # SETTING MOTION LEVELS THRESHOLDS [2]\n      threshold_lm = default(threshold_lm, 4.0)\n      threshold_hm = default(threshold_hm, 12.0)\n      global threshold_lm = threshold_lm\n      global threshold_hm = threshold_hm\n\n      # ENABLING/DISABLING DEBUG INFORMATION [3]\n      debug = default(debug, false)\n\n      # INITIALIZING MOTION LEVEL\n      global motion_level = 0\n\n      # SETTING PRESENT CLIP [4]\n      global clip = c\n\n      # GETTING OUTPUT RESOLUTION [5]\n      width = Width(Low_Motion_Filter(c))\n      height = Height(Low_Motion_Filter(c))\n      global c_resized = PointResize(c, width, height)\n\n      # APPLYING MOTION FILTER ACCORDING TO MOTION LEVEL [6]\n      c = ConditionalFilter(c, Low_Motion_Filter(c), c_resized,\n      \"**motion_level**\", \"=\", \"0\")  # [6a]\n      c = ConditionalFilter(c, Medium_Motion_Filter(c), c,\n      \"**motion_level**\", \"=\", \"1\")       # [6b]\n      c = ConditionalFilter(c, High_Motion_Filter(c), c,\n      \"**motion_level**\", \"=\", \"2\")         # [6c]\n\n      # PRINTING DEBUG INFORMATION [7]\n      c = (debug == true) ? ScriptClip(c, \"Debug()\") : c\n\n      # GETTING MOTION LEVEL THROUGH MOTION ESTIMATION [8]\n      c = FrameEvaluate(c, \"ME()\")\n\n      # GETTING DIFFERENCES BETWEEN PAST/PRESENT FRAMES [9]\n      c = FrameEvaluate(c, \"**global diff** =\n      0.50*YDifferenceFromPrevious(clip) + 0.25*UDifferenceFromPrevious(clip)\n      + 0.25*VDifferenceFromPrevious(clip)\")\n      return c\n    }\n\n    # DEBUG INFORMATION FUNCTION\n    function Debug(clip c)\n    {\n      # PRINTING VERSION INFORMATION [10]\n      c = Subtitle(c, \"Quantified Motion Filter\", x=20, y=30,\n      font=\"lucida console\", size=18, text_color=$FFFFFF)\n      c = Subtitle(c, \"by HomiE FR (homie.fr@wanadoo.fr)\", x=20, y=45,\n      font=\"lucida console\", size=14, text_color=$FFFFFF)\n\n      # PRINTING MOTION ESTIMATION INFORMATION [11]\n      c = Subtitle(c, \"motion estimation\", x=20, y=85, font=\"lucida\n      console\", size=18, text_color=$FFFFFF)\n      c = Subtitle(c, \"diff = \"+string(**diff**), x=20,y=110,\n      font=\"lucida console\", size=16, text_color=$FFCCCC)\n\n      # PRINTING QUANTIFIED MOTION FILTER INFORMATION [12]\n      c = Subtitle(c, \"quantified motion filter\", x=20, y=135,\n      font=\"lucida console\", size=18, text_color=$FFFFFF)\n      c = (**motion_level** == 0) ? Subtitle(c, \"scene type = low\n      motion\", x=20, y=160, font=\"lucida console\", size=16,\n      text_color=$66FF66) : c\n      c = (**motion_level** == 1) ? Subtitle(c, \"scene type = medium\n      motion\", x=20, y=160, font=\"lucida console\", size=16,\n      text_color=$66FF66) : c\n      c = (**motion_level** == 2) ? Subtitle(c, \"scene type = high\n      motion\", x=20, y=160, font=\"lucida console\", size=16,\n      text_color=$66FF66) : c\n      return c\n    }\n    ----------------------------------------------------\n\nThis filter chain works like this:\n\n-   When Vdub requests a frame, AviSynth requests a frame from QMF.\n\n-   QMF request a frame from FrameEvaluate [9].\n-   After doing this the script [9] is evaluated, and the global variable\n    *diff* is assigned after requesting a frame from AviSource. FrameEvaluate\n    [9] requests a frame from FrameEvaluate [8].\n-   Once again the script [8] is evaluated:\n\n-   when evaluating me(), the global variable *motion_level* is assigned\n    for that frame [1]\n\n-   If debug=true, a frame is requested from ScriptClip [7], and thus\n    from Debug().\n-   After that (and also when debug was set to false) a frame is\n    requested from the last ConditionalFilter [6c], which requests a frame\n    from [6b], which in turn requests a frame from [6a].\n\n-   Note that in the end, a frame of High_Motion_filter,\n    Medium_Motion_filter, or Low_Motion_filter is requested depending on the\n    value of *motion_level*.\n\n-   QMF request a frame from Telecide, Telecide from ConvertToYV12 and\n    finally ConvertToYV12 from AviSource.\n-   AviSource produces the frame and sends it to ConvertToYV12, etc.\n\nA few details were omitted, but this is how the script basically works.\n\nChangelog\n---------\n+----------------+------------------------------------------------------------+\n| Version        | Changes                                                    |\n+================+============================================================+\n| Avisynth 3.7.4 | Fix: Allow \"local\" in the first long ConditionalFilter     |\n|                | version                                                    |\n+----------------+------------------------------------------------------------+\n| Avisynth 3.7.2 | Added a 6th element to PlaneMinMaxStats result             |\n+----------------+------------------------------------------------------------+\n| Avisynth 3.7.1 | Added PlaneMinMaxStats                                     |\n+----------------+------------------------------------------------------------+\n| Avisynth 3.6.0 | Added \"local\", added function objects                      |\n+----------------+------------------------------------------------------------+\n| Avisynth+      | Added R, G, B versions of AverageXX, Min, Max,             |\n| pre2294        | Difference and Median family.                              |\n+----------------+------------------------------------------------------------+\n| AviSynth 2.6.0 | Number of expressions changed from 16 to nearly unlimited. |\n+----------------+------------------------------------------------------------+\n\n$Date: 2023/12/19 15:11:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/conditionalreader.rst",
    "content": "\nConditionalReader\n=================\n\nImport information from a text file and assign a per-frame value to a script\nvariable.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    ConditionalReader (clip, string filename, string variablename, bool \"show\",\n                       string \"condvarsuffix\", bool \"local\")\n\n.. describe:: clip\n\n    Source clip. Not touched, unless you specify ``show=true``.\n\n.. describe:: filename\n\n    Path to the file with the per-frame values you want to set. See\n    `File format`_ below.\n\n.. describe:: variablename\n\n    Name of the variable you want the ``filename`` values assigned to. See also ``condvarsuffix``\n\n.. describe:: show\n\n    If *true*, show a text overlay with ``variablename``'s assigned value at the\n    current frame.\n\n    Default: false\n\n.. describe:: condvarsuffix\n\n    Allows multiple filter instances to use differently named conditional parameters.\n    Prevents collision and overwrite of variables which are used by different ConditionalReader \n    instances.\n\n    See also: conditional variables section of http://avisynth.nl/index.php/ColorYUV.\n\n    How does it work: when reading the global variables, the *condvarsuffix* parameter is \n    appended to the variable name. E.g. variable name \"myvar_a\" will be read instead of \n    \"myvar\" when *condvarsuffix* = \"_a\" is provided.\n    \n    Useful for ``ColorYUV``, ``RGBAdjust``, ``Overlay`` when conditional=true is set there.\n\n    In the matching ConditionalReader one have to use the modified name as well:\n\n    ::\n\n        ConditionalReader(\"coloryuvoffset.txt\", \"coloryuv_gain_y\", false, CondVarSuffix = \"_a\")\n        # \"_a\" is added here by parameter\n\n    or specify the suffixed name directly:\n\n    ::\n\n        ConditionalReader(\"coloryuvoffset.txt\", \"coloryuv_gain_y_a\", false)\n        # \"_a\" is added here manually\n\n    Default: \"\"\n\n\nFile format\n-----------\n\n* The file is plain text.\n\n  * It is not case sensitive.\n  * Each line stands alone.\n  * There are several different line types, as explained below.\n  * Blank lines are ignored.\n\n* The file may begin with one or more optional *comment* lines:\n\n  Any line is ignored if the first non-whitespace character is '#' (hash), ';'\n  (semicolon) or '%' (percent).\n\n  ::\n\n      #this line is a comment\n      ;so is this line\n           %and this one too.\n\n* The first non-*comment* line should be a *type* line, which must be one of the\n  following:\n\n    ``TYPE int``\n\n        | Tells **ConditionalReader** to expect decimal integer values.\n        | (Digits ``0-9``, optionally preceded with a ``'+'`` or ``'-'`` sign)\n\n    ``TYPE float``\n\n        | Tells **ConditionalReader** to expect floating-point values.\n        | (Decimal number with ``'.'`` decimal point, and optionally followed by\n          an ``'E'`` character and decimal exponent)\n\n    ``TYPE bool``\n\n        | Tells **ConditionalReader** to expect boolean values.\n        | (``'true'`` or ``'false'``, ``'T'`` or ``'F'``, ``'yes'`` or ``'no'``,\n          ``'1'`` or ``'0'``)\n\n    ``TYPE string``\n\n        (Any sequence of characters, including quote, backslash etc. A line\n        break ends the string.)\n\n  The *type* line defines the *data* type to be parsed from this file and\n  assigned to the variable ``variablename``. You must have one, and only one,\n  *type* line per file, and it must come before any other lines, except for\n  optional comments.\n\n* A *default* line should come next. It is optional but strongly suggested:\n\n    ``DEFAULT <value>``\n\n        | This specifies the value to be used if there is no applicable *data*\n          line for a given frame.\n        | If you do not define a default, be sure to specify a value for all\n          frames; otherwise your script variable could be |undefined| or\n          take a random value.\n\n* An optional *offset* line may appear:\n\n    ``OFFSET <integer-value>``\n\n        When specified, this will add an offset adjustment to all frame numbers\n        in the *data* lines below.\n\n* Next come the *data* line(s), which set the per-frame value(s) to be assigned\n  to the script variable. There are three styles:\n\n    *Single-frame* style:\n\n            ``<framenumber> <value>``\n\n            Set value for frame *framenumber* only.\n\n    *Range* style:\n\n            ``R <startframe> <endframe> <value>``\n\n            | Apply value to a range of frames.\n            | Note that both startframe and endframe are included in the range.\n\n    *Interpolated* style:\n\n            ``I <startframe> <endframe> <start-value> <stop-value>``\n\n            | Interpolate between *start-value* and *stop-value* over a range of\n              frames. This only works on *int* and *float* types.\n            | Note that both *startframe* and *endframe* are included in the range.\n\n  | Later data lines in the file overrule earlier ones. Styles may be\n    mixed-and-matched; see the examples below.\n  | All *data* and *default* values must be valid for the defined *type*, as\n    defined above, or an error will be raised.\n\n\nExamples\n--------\n\nBasic usage\n~~~~~~~~~~~\n\nFile *Basic.txt*:\n::\n\n    Type float\n    Default 3.45567\n\n    R 45 300 76.5654\n    2 -671.454\n    72 -671.454\n\nThe file above will return float values. It will by default return 3.45567.\nHowever, frames 45 to 300 it will return 76.5654. And frame 2 and 72 will\nreturn -671.454.\n\nLater data lines in the file overrule earlier ones. This is illustrated by the\n'72' line: even though frame 72 is inside the range of 45-300, frame 72 will use\nthe value -671.454, not 76.5654. If the 'R' line had been placed after the '72'\nline, the range value would have had priority.\n\nA script to invoke this file could be:\n::\n\n    ColorBars(512,512)\n    Trim(0,500)\n    ScriptClip(\"subtitle(string(myvar))\")\n    ConditionalReader(\"file.txt\", \"myvar\", false)\n\nThis will put the values into the variable called *\"myvar\"*, which is used by\n:doc:`Subtitle <subtitle>`, invoked by :ref:`ScriptClip` to display the\n:doc:`runtime <../syntax/syntax_runtime_environment>` value.\n\n**Note** the **ConditionalReader** line comes *after* any use of *\"myvar\"* in\nthe script.\n\n\nString values\n~~~~~~~~~~~~~\n\nFile *Strings.txt:*\n::\n\n    Type string\n    Default\n    # (default=empty string)\n\n    R  45  99 this is a string\n    R 100 199 \"quoted string\"\n    R 200 299 w:\\xyz.txt\n\nTry the above :doc:`Subtitle <subtitle>` script with *Strings.txt*. You will see\nthe strings displayed verbatim.\n\nUsage of condvarsuffix\n~~~~~~~~~~~~~~~~~~~~~~\n\n::\n\n    Colorbars(512,256).ConvertToYV12.Trim(0,299)\n    ConditionalReader(\"coloryuvoffset.txt\", \"coloryuv_gain_y\", false)\n    a=ColorYUV(cont_y=10, conditional=true)\n    \n    Colorbars(512,256).ConvertToYV12.Trim(0,299)\n    ConditionalReader(\"coloryuvoffset2.txt\", \"coloryuv_gamma_y\", false, condvarsuffix=\"_a\")\n    # this will read coloryuv_gain_y_a, coloryuv_gamma_y_a, etc.\n    b=ColorYUV(cont_y=10, conditional=true, condvarsuffix=\"_a\")\n    \n    Stackvertical(a,b)\n\nAdjusting Overlay\n~~~~~~~~~~~~~~~~~\n\nScript:\n::\n\n    ColorBars(512,256)\n    a1 = Trim(0,600)\n    a2 = MessageClip(\"Text clip\")\n    Overlay(a1,a2, y = 100, x = 110, mode=\"subtract\", opacity=0, pc_range=true)\n    ConditionalReader(\"opacity.txt\", \"ol_opacity_offset\", false)\n    ConditionalReader(\"xoffset.txt\", \"ol_x_offset\", false)\n\nFile *xoffset.txt:*\n::\n\n    Type int\n    Default -50\n\n    I 25 50 -50 100\n    R 50 250 100\n    I 250 275 100 250\n\nFile *opacity.txt:*\n::\n\n    Type float\n    Default 0.0\n\n    I 25 50 0.0 1.0\n    R 50 250 1.0\n    I 250 275 1.0 0.0\n\nIt is easier to watch the clip above than completely describe what it does.\nBasically, this example defines *keyframes* for an :doc:`overlay` x-offset and\nopacity. For frames 25-50 the opacity is scaled from 0.0 to 1.0, while the text\nis moving from left to right. The text is then kept steady from frame 50-250,\nand thereafter it moves further to the right, while fading out.\n\n\n.. _complicated-applyrange:\n\nApplyRange replacement\n~~~~~~~~~~~~~~~~~~~~~~\n\nUsing a large number of :doc:`ApplyRange <animate>` calls in a script can lead\nto resource issues. **ConditionalReader** together with\n:doc:`ConditionalFilter <conditionalfilter>` can be used instead, leading to an\nefficient solution:\n\nFile.txt:\n::\n\n    Type Bool\n    Default False\n\n    2 True\n    R 45 60 True\n    72 True\n    R 200 220 True\n    210 False\n    315 True\n\nBy default, the script value will be False. However, for frames 2, 45-60, 72,\n200-220 and 315, except for 210, it will be True. Later data lines in the file\noverrule earlier ones. This is illustrated by frame '210': even though it is\ninside the range of 200-220, the later value, False, will be used.\n\nA script to make use of this file could be:\n::\n\n    Colorbars(512,512)\n    Trim(0,500)\n    A=Last\n    FlipHorizontal() # Add a complex filter chain\n    B=Last\n    ConditionalFilter(A, B, \"MyVar\", \"==\", \"False\", false)\n    ConditionalReader(\"File.txt\", \"MyVar\", false)\n\nThis will put the values into the variable called *\"MyVar\"*, which is used by\n:doc:`ConditionalFilter <conditionalfilter>` to select between the unprocessed\nand flipped version of the source.\n\n\nStrings values in v2.58\n~~~~~~~~~~~~~~~~~~~~~~~\n\n**ConditionalReader** cannot return strings prior to AviSynth v2.60, but one\nsolution is to create a list of variables with corresponding string assignments,\nand |Eval| the indexed solution. For example:\n\n::\n\n    Import(\"strings.txt\")\n    ScriptClip(\"\"\"subtitle(Eval(\"n\"+string(mystringindex)))\"\"\")\n    ConditionalReader(\"range_string.txt\", \"mystringindex\")\n\n\nFile *strings.txt*\n\n::\n\n    n0=\"\"\n    n1=\"Intro\"\n    n2=\"Main\"\n    n3=\"Credits\"\n\nFile *range_string.txt*\n\n::\n\n    Type int\n    Default 0\n\n    R 10 1000 1\n    R 1005 3000 2\n    R 3200 3800 3\n\nObviously *strings.txt* does not need to be a separate file, but this solution\nis sometimes appropriate in some multilingual applications, e.g., multilingual\napplications:\n\n::\n\n    language=\"spanish\"\n    Import(language + \"_strings.txt\")\n\n\nChangelog\n---------\n+----------------+----------------------------------+\n| Version        | Changes                          |\n+================+==================================+\n| Avisynth 3.6.0 | Added \"local\"                    |\n+----------------+----------------------------------+\n| Avisynth+r2915 | Added \"condvarsuffix\"            |\n| 20190829       |                                  |\n+----------------+----------------------------------+\n| AviSynth 2.6.0 | Added OFFSET, Added Type=string. |\n+----------------+----------------------------------+\n\n$Date: 2023/12/19 16:27:00 $\n\n.. |Eval| replace:: :doc:`Eval <../syntax/syntax_internal_functions_control>`\n.. |undefined| replace:: :doc:`undefined  <../syntax/syntax_internal_functions_boolean>`\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/convert.rst",
    "content": "\nConvertToXXXX function\n======================\n\n*RGB interleaved (packed)*\n::\n\n  ConvertToRGB(clip [, string matrix, bool interlaced,\n         string ChromaInPlacement,\n         string chromaresample, float param1, float param2, float param3,\n         int bits, bool quality] )\n\n  ConvertToRGB24(clip [, string matrix, bool interlaced,\n         string ChromaInPlacement,\n         string chromaresample, float param1, float param2, float param3,\n         int bits, bool quality] )\n\n  ConvertToRGB32(clip [, string matrix, bool interlaced,\n         string ChromaInPlacement,\n         string chromaresample, float param1, float param2, float param3,\n         int bits, bool quality] )\n\n  ConvertToRGB48(clip, [ string matrix, bool interlaced,\n         string ChromaInPlacement,\n         string chromaresample, float param1, float param2, float param3,\n         int bits, bool quality] )\n       \n  ConvertToRGB64(clip, [ string matrix, bool interlaced,\n         string ChromaInPlacement,\n         string chromaresample, float param1, float param2, float param3,\n         int bits, bool quality] )\n\n\n*RGB planar*\n::\n\n    ConvertToPlanarRGB(clip, [ string matrix, bool interlaced,\n         string ChromaInPlacement,\n         string chromaresample, float param1, float param2, float param3,\n         int bits, bool quality] )\n    ConvertToPlanarRGBA(clip, [ string matrix, bool interlaced,\n         string ChromaInPlacement,\n         string chromaresample, float param1, float param2, float param3,\n         int bits, bool quality] )\n\n\n*YUV444, YUVA444*\n::\n\n    ConvertToYV24(clip [, bool interlaced, string matrix,\n         string ChromaInPlacement,\n         string chromaresample, float param1, float param2, float param3,\n         int bits, bool quality] )\n    ConvertToYUV444(clip, [ string matrix, bool interlaced,\n         string ChromaInPlacement,\n         string chromaresample, float param1, float param2, float param3,\n         int bits, bool quality] )\n    ConvertToYUVA444(clip, [ string matrix, bool interlaced,\n         string ChromaInPlacement,\n         string chromaresample, float param1, float param2, float param3,\n         int bits, bool quality] )\n\n\n*YUV422, YUVA422*\n::\n\n    ConvertToYV16(clip [, bool interlaced, string matrix,\n         string ChromaInPlacement,\n         string chromaresample,\n         string ChromaOutPlacement\n         float param1, float param2, float param3,\n         int bits, bool quality] )\n\n    ConvertToYUV422(clip, [ string matrix, bool interlaced,\n         string ChromaInPlacement,\n         string chromaresample,\n         string ChromaOutPlacement,\n         float param1, float param2, float param3,\n         int bits, bool quality] )\n    ConvertToYUVA422(clip, [ string matrix, bool interlaced,\n         string ChromaInPlacement,\n         string chromaresample,\n         string ChromaOutPlacement,\n         float param1, float param2, float param3,\n         int bits, bool quality] )\n\n*YUY2*\n::\n\n    ConvertToYUY2(clip [, bool interlaced, string matrix,\n         string ChromaInPlacement,\n         string chromaresample,\n         string ChromaOutPlacement,\n         float param1, float param2, float param3,\n         int bits, bool quality] )\n    ConvertBackToYUY2(clip [, string matrix ] )\n\n*YUV420, YUVA420*\n::\n\n    ConvertToYV12(clip [, bool interlaced, string matrix,\n         string ChromaInPlacement,\n         string chromaresample,\n         string ChromaOutPlacement,\n         float param1, float param2, float param3,\n         int bits, bool quality] )\n    ConvertToYUV420(clip, [ string matrix, bool interlaced,\n         string ChromaInPlacement,\n         string chromaresample,\n         string ChromaOutPlacement,\n         float param1, float param2, float param3,\n         int bits, bool quality] )\n    ConvertToYUVA420(clip, [ string matrix, bool interlaced,\n         string ChromaInPlacement,\n         string chromaresample,\n         string ChromaOutPlacement,\n         float param1, float param2, float param3,\n         int bits, bool quality] )\n\n\n*YUV411*\n::\n\n    ConvertToYV411(clip [, bool interlaced, string matrix,\n         string ChromaInPlacement,\n         string chromaresample,\n         float param1, float param2, float param3,\n         int bits, bool quality] )\n    ConvertToYUV411(clip [, bool interlaced, string matrix,\n         string ChromaInPlacement,\n         string chromaresample,\n         float param1, float param2, float param3,\n         int bits, bool quality] )\n\n(the 2nd one is just an alias)\n\n*Y-only*\n::\n\n    ConvertToY8(clip [, string matrix, int bits, bool quality] )] )\n    ConvertToY(clip [, string matrix, int bits, bool quality] ) ] )\n\n\nColor formats\n-------------\n\nThe following formats can be converted to and from.\n\nNotes:\n\n- Interleaved RGB formats (RGB24/32/48/64) are kept for compatibility, they come with fixed 8 and 16 bits.\n- The successor RGB format is planar RGB/RGBA, which support any Avisynth+ high bit depth format.\n- 8 bit YUV formats has their own old names, but can be written in the generic naming convention: \n  YV12=YUV420P8, YV16=YUV422P8, YV24=YUV444P8\n- If possible, avoid using YUY2 which is kept for compatibility. Use YV16 instead.\n  YUY2 is always 8-bit and packed; YV16 is the planar equivalent supporting all\n  bit depths and is handled more efficiently throughout the filter chain.\n\n+----------------+-----------+--------------+---------------------------------------------------------------+-------------+\n| Color formats  | Bit depth | Sample ratio | Description                                                   | planar/     |\n|                |           |              |                                                               | interleaved |\n+================+===========+==============+===============================================================+=============+\n| RGB24, RGB48   | 8, 16     | 4:4:4        | full chroma                                                   | interleaved |\n+----------------+-----------+--------------+---------------------------------------------------------------+-------------+\n| RGB32, RGB64   | 8, 16     | 4:4:4:4      | full chroma + alpha                                           | interleaved |\n+----------------+-----------+--------------+---------------------------------------------------------------+-------------+\n| RGBPxx         | 8-16, 32  | 4:4:4        | full chroma - known as planar RGB                             | planar      |\n+----------------+-----------+--------------+---------------------------------------------------------------+-------------+\n| RGBAPxx        | 8-16, 32  | 4:4:4:4      | full chroma + alpha - known as planar RGBA                    | planar      |\n+----------------+-----------+--------------+---------------------------------------------------------------+-------------+\n| YV24,YUV444Pxx | 8-16, 32  | 4:4:4        | full chroma                                                   | planar      |\n+----------------+-----------+--------------+---------------------------------------------------------------+-------------+\n| YUVA444Pxx     | 8-16, 32  | 4:4:4:4      | full chroma + alpha                                           | planar      |\n+----------------+-----------+--------------+---------------------------------------------------------------+-------------+\n| YV16,YUV422Pxx | 8-16, 32  | 4:2:2        | chroma shared between 2 pixels                                | planar      |\n+----------------+-----------+--------------+---------------------------------------------------------------+-------------+\n| YUVA422Pxx     | 8-16, 32  | 4:2:2:4      | chroma shared between 2 pixels + alpha                        | planar      |\n+----------------+-----------+--------------+---------------------------------------------------------------+-------------+\n| YV12,YUV420Pxx | 8-16, 32  | 4:2:0        | chroma shared between 2x2 pixels                              | planar      |\n+----------------+-----------+--------------+---------------------------------------------------------------+-------------+\n| YUVA420Pxx     | 8-16, 32  | 4:2:0:4      | chroma shared between 2x2 pixels + alpha                      | planar      |\n+----------------+-----------+--------------+---------------------------------------------------------------+-------------+\n| YV411,YUV411P8 | 8         | 4:1:1        | chroma shared between 4 pixels                                | planar      |\n+----------------+-----------+--------------+---------------------------------------------------------------+-------------+\n| Y8,Y10-16,Y32  | 8-16, 32  | 4:0:0        | no chroma                                                     | both        |\n+----------------+-----------+--------------+---------------------------------------------------------------+-------------+\n| YUY2           | 8         | 4:2:2        | chroma shared between 2 pixels. Deprecated format, use YV16   | interleaved |\n+----------------+-----------+--------------+---------------------------------------------------------------+-------------+\n| xx refers to the bit depth, where                                                                                       |\n| 8-16 = 8,10,12,14,16 bit integer; S or 32 is the 32 bit float. Use \"S\" in format names, except for Y, where Y32 is used.|\n+----------------+-------------+-----------+--------------+---------------------------------------------------------------+\n\nWhen the target format is the same as the source format, the original clip will be returned unchanged, \nexcept for the cases where the ``ChromaInPlacement`` and ``ChromaOutPlacement`` parameters are different,\nor the target placement is different from the source chroma placement read from ``_ChromaLocation`` frame property.\n\nSuch functions are ``ConvertToYV12``/``ConvertToYUV420``/``ConvertToYUVA420`` or \n``ConvertToYV16``/``ConvertToYUV422``/``ConvertToYUVA422``.\n\n``ConvertToRGB`` (without numeric suffix) is adaptive:\n\n- **Packed RGB source** (RGB24/32/48/64): returned unchanged.\n- **Planar RGB source**: converted to the matching packed format,\n  preserving bit depth and alpha capability. PlanarRGBA converts to\n  RGB32/64 (with alpha); PlanarRGB converts to RGB24/48 (without alpha).\n- **YUV 8-bit source**: converted to RGB32.\n- **YUV 16-bit source**: converted to RGB64.\n- **YUV 10/12/14-bit or float source**: not supported; use\n  ``ConvertToRGB64`` or ``ConvertToPlanarRGB`` explicitly, or reduce\n  bit depth with ``ConvertBits(8)`` / ``ConvertBits(16)`` first.\n\nThe ``bits`` parameter (8 or 16) overrides ConvertToRGB's adaptive target bit depth,\nallowing for example a 16-bit source to be converted to an 8-bit packed\nRGB output. Values other than 8 or 16 are not accepted.\n\nFor explicit control of output format use ``ConvertToRGB24``,\n``ConvertToRGB32``, ``ConvertToRGB48`` or ``ConvertToRGB64``.\n\nSyntax and operation of ``ConvertToRGB24`` is identical to ``ConvertToRGB``,\nexcept that the output format is 24-bit; if the source is RGB32 or planar RGBA, \nthe alpha channel will be stripped.\n\n``ConvertBackToYUY2`` is kept for backward compatibility with 2.5x scripts.\nIt is now equivalent to ``ConvertToYUY2``. It was an old hack. See \"History\" section at the end of this document.\n\nThere is no unique way of converting YUV to RGB or vice-versa. There are different conversion matrices in use.\nThe following should be correct in most cases, see \n`here <http://avisynth.nl/index.php/Colorimetry#How_can_I_see_if_the_correct_standard_is_used_upon_playback>`_ for more.\n\n- Rec.601 should be used when your source is standard definition (usually defined as smaller than 720p): \n  ``ConvertToRGB(clip) (using default \"Rec601\")``\n\n- Rec.709 should be used when your source is DVD or HDTV: \n  ``ConvertToRGB(clip, matrix=\"Rec709\")``\n\n- The special-purpose matrices PC.601 and PC.709 keep the range unchanged (!), \n  instead of converting between 0d-255d RGB and 16d-235d YUV, as is the normal practice. \n  Note that if you want to convert from Y and no ``_ColorRange`` frame property present then it will treat it as\n  limited range.\n\n- The special-purpose matrix AVERAGE is used for (rarely found) sources with unweighted luma, \n  where ``Y = (R + G + B) / 3``. \n\nHow conversion detects whether full or limited (narrow range for RGB) conversion needed:\n\n- Avisynth can use the ``_ColorRange`` frame property to detect whether the source clip is of full or limited (narrow) range.\n- If frame property ``_ColorRange`` is not present, then\n  \n  - ``full`` for RGB sources\n  - ``limited`` for YUV or Y (greyscale) sources\n  \n  is assumed.\n- Along with frame properties, the matrix string can contain additional \"hints\", such as ``:f``, ``:l``, , ``:auto``, ``:same``.\n- When no other hint is given, some old-style Avisynth matrix name can specify limited/full: e.g. ``\"Rec.709\"`` implies limited range.\n  Note: unlike ``PC.709`` or ``PC.601``: these matrix names do not force the clip being full or limited.\n\nSee also: :doc:`ConvertBits <convertbits>` to convert between bit depths and/or between full-limited range. \n\nSyntax and parameters\n---------------------\n\n.. _matrix_parameter_syntax:\n\n\n.. describe:: matrix\n\n    ``string  matrix = \"Rec601\"``\n\n    Controls the colour coefficients and scaling factors used in colour space conversions.\n\n    **Old-style constants (still valid):**\n\n    These names remain fully supported for backward compatibility.\n\n    - ``\"Rec601\"``               : Rec.601 coefficients; limited-range YUV ↔ full-range RGB.\n    - ``\"Rec709\"``               : Rec.709 (HD) coefficients; limited-range YUV ↔ full-range RGB.\n    - ``\"Rec2020\"``              : Rec.2020 (UHD) coefficients; limited-range YUV ↔ full-range RGB.\n    - ``\"PC.601\"``, ``\"PC601\"``  : Rec.601 coefficients; range unchanged (passes through as-is).\n    - ``\"PC.709\"``, ``\"PC709\"``  : Rec.709 (HD) coefficients; range unchanged.\n    - ``\"PC.2020\"``, ``\"PC2020\"``: Rec.2020 (UHD) coefficients; range unchanged.\n    - ``\"Average\"``              : Averaged luma (``Y = (R+G+B)/3``); range unchanged.\n\n    Using old-style matrix names implies the full/limited range behaviour described above.\n    ``PC.601``, ``PC.709`` and ``PC.2020`` do not force a range conversion: the input range\n    is passed through to the output unchanged, equivalent to the new-style ``\":same\"``\n    modifier (see below).\n\n    **New-style syntax:**\n\n    Two forms are available::\n\n        \"matrixname[:rangehint]\"\n        \"matrixname:rangehint=>matrixname:rangehint\"\n\n    The first (single) form covers all common RGB ↔ YUV conversions.\n    The second (two-part) form is required when independent control of both sides is needed,\n    in particular for YUV → YUV conversions or when the RGB side needs an explicit range\n    different from its default.\n\n    *matrixname* can be one of:\n\n    +----------------+-------+--------------------------------------------------------------+\n    | Name           | Int   | Description                                                  |\n    +================+=======+==============================================================+\n    | ``rgb``        | 0     | Identity / RGB (valid on either side of ``=>``)              |\n    +----------------+-------+--------------------------------------------------------------+\n    | ``709``        | 1     | BT.709 (HD)                                                  |\n    +----------------+-------+--------------------------------------------------------------+\n    | ``unspec``     | 2     | Unspecified                                                  |\n    +----------------+-------+--------------------------------------------------------------+\n    | ``470bg``      | 5     | BT.470 BG (same coefficients as Rec.601)                     |\n    +----------------+-------+--------------------------------------------------------------+\n    | ``601``        | 5     | Alias for ``470bg``                                          |\n    +----------------+-------+--------------------------------------------------------------+\n    | ``fcc``        | 4     | BT.470 M / FCC                                               |\n    +----------------+-------+--------------------------------------------------------------+\n    | ``bt470m``     | 4     | Alias for ``fcc``                                            |\n    +----------------+-------+--------------------------------------------------------------+\n    | ``170m``       | 6     | SMPTE 170M                                                   |\n    +----------------+-------+--------------------------------------------------------------+\n    | ``240m``       | 7     | SMPTE 240M                                                   |\n    +----------------+-------+--------------------------------------------------------------+\n    | ``2020ncl``    | 9     | BT.2020 Non-Constant Luminance                               |\n    +----------------+-------+--------------------------------------------------------------+\n    | ``2020``       | 9     | Alias for ``2020ncl``                                        |\n    +----------------+-------+--------------------------------------------------------------+\n    | ``2020cl``     | 10    | BT.2020 Constant Luminance (treated as NCL internally)       |\n    +----------------+-------+--------------------------------------------------------------+\n    | ``ycgco``      | 8     | YCgCo *(not supported)*                                      |\n    +----------------+-------+--------------------------------------------------------------+\n    | ``chromancl``  | 12    | Chromaticity Derived NCL *(not supported)*                   |\n    +----------------+-------+--------------------------------------------------------------+\n    | ``chromacl``   | 13    | Chromaticity Derived CL *(not supported)*                    |\n    +----------------+-------+--------------------------------------------------------------+\n    | ``ictcp``      | 14    | ICtCp *(not supported)*                                      |\n    +----------------+-------+--------------------------------------------------------------+\n\n    *rangehint* specifies the colour range for that side of the conversion:\n\n    - ``full`` or ``f``    — force full range\n    - ``limited`` or ``l`` — force limited range\n    - ``auto``             — use ``_ColorRange`` frame property if present, otherwise use\n                             the format default (full for RGB, limited for YUV/Y)\n    - ``same``             — **output side only** in the two-part form; copies the resolved\n                             input range to the output. Invalid on the input (left) side.\n\n    When no rangehint is given at all, ``auto`` behaviour applies.\n\n    **Single form — the range hint refers to the YUV side:**\n\n    In the single ``\"matrixname:rangehint\"`` form the range hint always describes the\n    **YUV side** of the conversion, whichever side that is:\n\n    - **YUV → RGB**: the hint describes the *input* (YUV) range.\n      The RGB output defaults to full range independently of the hint.\n    - **RGB → YUV**: the hint describes the *output* (YUV) range.\n      The RGB input defaults to full range independently of the hint,\n      unless overridden by a ``_ColorRange`` frame property on the source.\n\n    This means ``\"709:l\"`` is unambiguous regardless of direction: the YUV side is\n    limited, using BT.709 coefficients. The RGB side resolves its range independently.\n\n    The special value ``same`` in the single form propagates from the *input* to the\n    output, regardless of direction. For YUV → RGB, the YUV input range (from frame\n    property or default) is copied to the RGB output. For RGB → YUV, the RGB input range\n    is copied to the YUV output. In both cases the net effect is range pass-through,\n    equivalent to the legacy ``PC.709`` / ``PC.601`` behaviour.\n\n    .. note::\n\n       For **RGB → YUV** with an explicit range hint, the hint sets the YUV *output*\n       range only. The RGB input range is always resolved independently from the\n       ``_ColorRange`` frame property (defaulting to full if absent) and cannot be\n       overridden by the hint. Use the two-part form if you need to declare both sides\n       explicitly.\n\n    **Two-part form** ``\"matrixname:rangehint=>matrixname:rangehint\"``:\n\n    Both sides must specify a matrixname and a rangehint. No implicit defaults apply\n    across the ``=>``. The ``same`` modifier is only valid on the *right (output)* side;\n    using it on the left side is an error.\n\n    This form is used when:\n\n    - A **YUV → YUV** conversion is needed. Internally the two matrices are combined and\n      applied as a single pass in the 32-bit float unclipped domain, so any out-of-range\n      RGB intermediate values that would arise from a naïve chained conversion are handled\n      safely without clipping artefacts.\n\n      YUV→RGB→YUV conversion using the specified matrix and range for each leg::\n\n          ConvertToYUV444(clip, matrix=\"601:l=>709:l\")\n          # SD limited input, HD limited output\n\n          ConvertToYUV444(clip, matrix=\"709:auto=>2020:same\")\n          # detect input range from frame prop; output matches resolved input range\n\n          ConvertToYUV444(clip, matrix=\"709:f=>709:l\")\n          # full-range YUV input, limited-range YUV output, same matrix\n\n    - An **RGB side range** needs to be declared explicitly, overriding the default.\n      The matrixname ``\"rgb\"`` is valid on either side::\n\n          ConvertToPlanarRGB(clip, matrix=\"709:auto=>rgb:limited\")\n          # detect YUV input range from frame prop; RGB output is forced limited\n\n          ConvertToYUV444(clip, matrix=\"rgb:limited=>709:l\")\n          # explicitly declare limited RGB input; limited YUV output\n\n    .. note::\n\n       In the two-part form, ``same`` on the right side resolves relative to the *left\n       side's resolved range*, not relative to the source clip's format default.\n       For example, ``\"709:f=>2020:same\"`` produces full-range output because the left\n       side resolved to full, regardless of what the default for the output format would\n       otherwise be.\n\n    **Equivalence table** — old-style names and their new-style equivalents:\n\n    +--------------------+-------------------------------+------------------------------------------+\n    | Old name           | New equivalent                | Notes                                    |\n    +====================+===============================+==========================================+\n    | ``Rec601``         | ``470bg:l``                   | limited YUV ↔ full RGB                   |\n    +--------------------+-------------------------------+------------------------------------------+\n    | ``Rec709``         | ``709:l``                     | limited YUV ↔ full RGB                   |\n    +--------------------+-------------------------------+------------------------------------------+\n    | ``Rec2020``        | ``2020ncl:l``                 | limited YUV ↔ full RGB                   |\n    +--------------------+-------------------------------+------------------------------------------+\n    | ``PC.601``         | ``470bg:same``                | range preserved                          |\n    +--------------------+-------------------------------+------------------------------------------+\n    | ``PC.709``         | ``709:same``                  | range preserved                          |\n    +--------------------+-------------------------------+------------------------------------------+\n    | ``PC.2020``        | ``2020ncl:same``              | range preserved                          |\n    +--------------------+-------------------------------+------------------------------------------+\n    | ``Average``        | ``average``                   | no standard ``_Matrix`` equivalent       |\n    +--------------------+-------------------------------+------------------------------------------+\n\n    **Range detection defaults summary:**\n\n    +--------------------+----------------------------+----------------------------------------------------------+\n    | Side               | Default range              | Notes                                                    |\n    +====================+============================+==========================================================+\n    | YUV / Y input      | limited                    | overridden by ``_ColorRange`` frame prop                 |\n    +--------------------+----------------------------+----------------------------------------------------------+\n    | YUV / Y output     | limited                    | overridden by rangehint or ``same`` or two-part form     |\n    +--------------------+----------------------------+----------------------------------------------------------+\n    | RGB input          | full                       | overridden by ``_ColorRange`` frame prop                 |\n    +--------------------+----------------------------+----------------------------------------------------------+\n    | RGB output         | full                       | overridden by ``same`` or two-part form                  |\n    +--------------------+----------------------------+----------------------------------------------------------+\n\n\n\n.. describe:: interlaced\n\n    bool  interlaced = false \n    \n    If true, it is assumed that clip is interlaced; by default, it is assumed to be progressive. \n    This option is needed because for example, the following (assuming clip is interlaced YV12):\n    ::\n\n        SeparateFields(clip)\n        ConvertToYV16\n        Weave\n\n\n    ...is upsampled incorrectly. Instead it is better to use: \n    ::\n\n        ConvertToYV16(clip, interlaced=true)\n\n\n    Note, interlaced=true has an effect only on YV12 <-> YV16/YUY2 or YV12 <-> RGB conversions.\n    (and their high bit depth equivalents).\n    More about that can be found here: \n    :doc:`Color conversions and interlaced / field-based video <../advancedtopics/interlaced_fieldbased>`.\n\n.. describe:: ChromaInPlacement, ChromaOutPlacement\n\n    string  ChromaInPlacement = \"MPEG2\"\n    \n    string  ChromaOutPlacement = \"MPEG2\"\n\n    ChromaInPlacement determines the chroma placement in the clip when converting from YV12/YUV420 or YV16/YUV422.\n    ChromaOutPlacement determines the chroma placement in the clip when converting to YV12/YUV420 or YV16/YUV422.\n    \n    The placement can be one of these strings: \n\n    - ``\"MPEG2\"`` (synonyms: ``\"left\"``)\n      Subsampling used in MPEG-2 4:2:x and most other formats. Chroma samples are located on the left pixel column of the group (default).\n    - ``\"MPEG1\"`` (synonyms: ``\"jpeg\"``, ``\"center\"``)\n      Subsampling used in MPEG-1 4:2:0. Chroma samples are located on the center of each group of 4 pixels.\n    - ``\"DV\"``\n      Like MPEG-2, but U and V channels are co-sited vertically: V on the top row, and U on the bottom row. For 4:1:1, chroma is located on the leftmost column.\n    - ``\"top_left\"``\n      Subsampling used in UHD 4:2:0. Chroma samples are located on the top left pixel column of the group.\n    - ``bottom_left`` 4:2:0 only\n    - ``bottom``   4:2:0 only \n\n   See also the Frame properties section below.\n\n\n.. describe:: chromaresample\n\n    string  chromaresample = \"bicubic\"\n\n    Determines which chroma resampler is used in the conversion. Only used when the chroma resolutions \n    of the source and target are different. All AviSynth :doc:`resizers <resize>` are allowed \n    (\"point\", \"bilinear\", \"bicubic\", \"lanczos\", \"lanczos4\", \"blackman\", \"spline16\", \"spline36\", \"spline64\", \n    \"gauss\" and \"sinc\", \"sinpow\", \"sinclin2\" and \"userdefined2\"). \n    \n    Default is \"bicubic\". \n\n.. describe:: param1, param2, param3\n\n    These 'float' type parameters can be the additional parameters for the chroma\n    resamplers. Some resizer algorithms would need and can be fine tuned with up to 3 parameters.\n    Their default values depend on the selected chromaresample resizer kernel,\n\n.. describe:: bits\n\n    Used to perform output bit-depth conversion. Between Planar RGB and YUV/Y formats the conversion\n    is single-pass. When intermediate format conversion is needed (e.g. RGB64->YUV444P8 is RGB64->PlanarRGB16->YUV444P8, \n    the bit-depth conversion occurs in the RGBP->YUV part.\n\n    **Internal calculation methods of 8-16 bit sources** (when conversion is needed)\n\n    ========================  ===================  ===============  ================================\n    Target Range              Internal Math        Internal Math    Output Handling\n                                                   (quality=true)\n    ========================  ===================  ===============  ================================\n    Full-range                32-bit float         32-bit float     Direct output\n    Limited-range → integer   S18.13 fixed-point   32-bit float     Truncated to target bit depth\n    Limited-range → float     S18.13 fixed-point   32-bit float     Converted to float (no truncation)\n    ========================  ===================  ===============  ================================\n\n    When ``quality=true`` (see below), the S18.13 fixed-point path is replaced by\n    32-bit float processing regardless of target range or bit depth.\n\n    Note: Limited-range to float conversion preserves the full precision of the\n    S18.13 fixed-point calculation by converting directly to 32-bit float without\n    the truncation that occurs with integer targets.\n\n.. describe:: quality\n\n    ``bool  quality = false``\n\n    Only affects YUV (Y) - RGB conversions, where matrix operation is involved.\n\n    When ``false`` (default), the internal calculation method is chosen automatically\n    based on the target range and bit depth, as described in the ``bits`` table above:\n    full-range targets use 32-bit float, limited-range targets use the faster S18.13\n    scaled integer path.\n\n    When ``true``, all internal processing is forced to 32-bit float regardless of\n    target range or bit depth. This avoids the rounding that occurs when the S18.13\n    fixed-point path truncates to an integer target, at the cost of slightly more\n    computation. Recommended when the output will undergo further processing and\n    maximum precision is desired.\n\n\nFrame properties\n----------------\n\nSince Avisynth v3.7.1 frame property (_ChromaLocation) support appears in selected filters (e.g. ConvertToYUV422). \nProperty can be read and/or set. A frame property can replace default behaviour of location parameters and is set \n(or deleted) upon finishing conversion. Since a format without subsampling - such as 4:4:4 (YV24) - does not have \nchroma location, the property is deleted automatically when converting to YUV444 or RGB.\n\n- \"ChromaInPlacement\" rules:\n\n    * if source has _ChromaLocation frame property it will be used else the default is \"mpeg2\" (\"left\")\n    * if parameter is \"auto\" or not given at all, ChromaInLocation will be set to the above mentioned default value\n    * if parameter is explicitely given, it will be used \n\n- \"ChromaOutPlacement\" rules:\n\n    * default is \"mpeg2\" (\"left\")\n    * if parameter is \"auto\" or not given at all, ChromaOutLocation will be set to the above mentioned default value\n    * if parameter is explicitely given, it will be used \n\n    Accepted values for \"ChromaInPlacement\" and \"ChromaOutPlacement\" (when source/target is a chroma subsampled format) \n    (full list):\n\n    * \"left\" or \"mpeg2\"\n    * \"center\" or \"jpeg\" or \"mpeg1\"\n    * \"top_left\"\n    * \"dv\"\n    * \"top\"\n    * \"bottom_left\"\n    * \"bottom\"\n\n- _ChromaLocation constants - just for info: as seen in propShow\n\n    * AVS_CHROMA_LEFT = 0\n    * AVS_CHROMA_CENTER = 1\n    * AVS_CHROMA_TOP_LEFT = 2 (4:2:0 only)\n    * AVS_CHROMA_TOP = 3 (4:2:0 only)\n    * AVS_CHROMA_BOTTOM_LEFT = 4 (4:2:0 only)\n    * AVS_CHROMA_BOTTOM = 5 (4:2:0 only)\n    * AVS_CHROMA_DV = 6 Special to Avisynth \n\n\nConversion paths\n----------------\n\n-   The *ChromaInPlacement*, *chromaresample* and *ChromaOutPlacement*\n    options are only used in the 'planar conversion part' of the conversion\n    path, and they process the chroma of the clip.\n\nThe following conversion paths occur\n\n-   411/420/422 YUV planar -> RGB via YUV444\n-   YUV planar -> YUY2 via YV16 (8 bit YUV422)\n-   YUV planar -> Y: direct\n-   Planar RGB -> 444: direct\n-   Planar RGB -> Y planar: direct\n-   Packed RGB -> Y/YUV planar: via Planar RGB(A) (A: depending on the target YUV's alpha-needs)\n-   Any RGB -> 411/420/422 YUV planar via YUV444\n-   YUY2 -> Y: direct\n-   YUY2 -> Any: via YV16\n-   Any -> YUY2: via YV16\n-   YV24 -> packed RGB24/32: (quality=false): direct conversion.\n-   YV24 -> packed RGB24/32: (quality=true): via planar RGB.\n-   YUV planar -> packed RGB48/64: via planar RGB\n\nWhen bit depth change needed, and the transformation does not integrate bit-depth conversion \n(E.g. clipYUV.ConvertToPlanarRGB(bits=xxx) does include, but clipY8bit.ConvertToY(bits=yyy) does not).\nthen an extra ConvertBits() is called internally.\n\nSuppose you have a YUY2 clip for example and you convert it to YV24.\n\nThe YUY2 will be converted to YV16 first without applying *ChromaInPlacement*,\n*chromaresample* and *ChromaOutPlacement*. \n\nThen YV16 will be converted to YV24 while applying *chromaresample*. \n*ChromaOutPlacement* won't be used since our target is YV24.\n\nHistory\n'''''''\n``ConvertBackToYUY2`` was introduced in Avisynth 2.02 (circa 2002) as an explicit\nworkaround for a horizontal chroma shift introduced by ``ConvertToYUY2``'s 1-2-1\naveraging kernel in the ``YUY2 → RGB → YUY2`` roundtrip workflow that was common\nbefore native YUV processing was available.\n\nWhen Avisynth 2.50 added YV12 support, the YV12↔YUY2 conversion used XviD's\nroutines, which were later replaced in 2.51 with custom SSE/iSSE code using a\n0.75/0.25 weighted vertical kernel — faster than a correct resampler but\ngeometrically wrong: it introduced a quarter-pixel vertical chroma shift for\nprogressive material, and asymmetric opposite-direction shifts for top and bottom\nfields in interlaced material. This was diagnosed precisely by Gavino in 2009\n(Doom9 thread #147629), who showed the round-trip kernel was ``[3,12,1]/16`` and\n``[1,12,3]/16`` for top and bottom fields respectively, where the correct MPEG-2\nkernel would give ``[3,26,3]/32``. The speed rationale for the approximation was\nconfirmed by Tritical: the double-``pavgb`` trick with a subtract-one correction\nwas the fastest available implementation at the time.\n\nWhen ``ConvertToPlanarGeneric`` was introduced with AviSynth+ (based on the 2.60\ndevelopment work by IanB), the correct infrastructure — placement-aware resampling\nwith proper ``_ChromaLocation`` frame property handling — became available. However\nthe legacy fast-path shortcuts were preserved alongside it, meaning most scripts\ncontinued to hit the old buggy kernels unless explicit options were passed.\n\nIn 3.7.6 the legacy direct conversion kernels are removed entirely. All\n``ConvertToYUY2`` paths now route through YV16 via ``ConvertToPlanarGeneric``,\ngiving correct chroma placement, full frame property support, and access to the\nAVX2/AVX512 resampler paths in Intel. ``ConvertBackToYUY2`` forwards to ``ConvertToYUY2``;\nthe left-pixel-only hack is no longer needed since the YV16 lossless repack path\neliminates chroma resampling loss entirely for roundtrip workflows.\n\n\nSampling\n--------\n\n:doc:`This part of the documentation <../advancedtopics/sampling>` covers the sampling methods and color formats in more detail.\n\n\nColor conversions\n-----------------\n\n:doc:`This page <../advancedtopics/color_conversions>` covers the color conversions, \"YUV <-> RGB\", in more detail.\n\n+----------+------------------------------------------------------------+\n| Changes: |                                                            |\n+==========+============================================================+\n| v3.7.6   || Add \"quality\" parameter to ConvertToXXXX                  |\n|          || Add \"bits\" parameter to ConvertToXXXX                     |\n|          || Document \":same\" in matrix specifier                      |\n+----------+------------------------------------------------------------+\n| v3.7.3   || Added \"sinpow\",  \"sinclin2\" and \"userdefined2\" to         |\n|          |  chromaresampler options                                   |\n|          || Add \"param1\", \"param2\" and \"param3\" to ConvertToXXXX where|\n|          |  'chromaresample' exists (b,c,s,taps and p parameters can  |\n|          |  be set, depending on the resizer.)                        |\n|          || Add ConvertToYUVA420, ConvertToYUVA422, ConvertToYUVA444  |\n+----------+------------------------------------------------------------+\n| v3.7.1   || Added ChromaOutPlacement to 4:2:2 related functions       |\n|          || Added new matrix constants, optional new syntax           |\n|          || Added new chroma location constants                       |\n|          || Added _ChromaLocation frame property                      |\n+----------+------------------------------------------------------------+\n| v2.60    || Added: ConvertToY8, ConvertToYV411,                       |\n|          |  ConvertToYV16, ConvertToYV24,                             |\n|          || Added ChromaInPlacement, ChromaOutPlacement and           |\n|          |  chromaresample, matrix=\"AVERAGE\"                          |\n+----------+------------------------------------------------------------+\n| v2.50    | ConvertToYV12                                              |\n+----------+------------------------------------------------------------+\n\n$Date: 2026/03/06 20:20:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/convertaudio.rst",
    "content": "\nConvertAudio\n============\n\nSet of filters to convert the audio sample type to 8, 16, 24, 32 integer bits, \nand Float. \n\nSee Wikipedia: `audio bit depth`_\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    ConvertAudioTo8bit (clip)\n    ConvertAudioTo16bit (clip)\n    ConvertAudioTo24bit (clip)\n    ConvertAudioTo32bit (clip)\n    ConvertAudioToFloat (clip)\n\n.. describe:: clip\n\n    Source clip to convert; all sample types supported.\n\n.. note::\n    The sample types supported by the AviSynth audio filters are listed \n    :ref:`here <Audio processing filters>`, in the **Sample type** column. \n    If a filter doesn't support the type of sample it is given, it will throw \n    an error. Use **ConvertAudio** to convert the audio clip to the supported \n    format.\n\n\nChangelog\n----------\n\n.. table::\n    :widths: 20 80\n\n    +------------------+------------------------------------------------------------+\n    | Version          | Changes                                                    |\n    +==================+============================================================+\n    | AviSynth+ 3.7.1  || Fix: ConvertAudio integer 32-to-8 bits C code garbage     |\n    |                  |  (regression in 3.7.0).                                    |\n    |                  || Fix: ConvertAudio: float to 32 bit integer conversion max |\n    |                  |  value glitch (regression in 3.7.0).                       |\n    |                  || Add direct Float from/to 8/16 conversions (C,SSE2,AVX2)   |\n    +------------------+------------------------------------------------------------+\n    | AviSynth+ 3.7.0  |  Internally refactored ConvertAudio.                       |\n    +------------------+------------------------------------------------------------+\n\n$Date: 2022/02/08 22:00:52 $\n\n.. _audio bit depth:\n    https://en.wikipedia.org/wiki/Audio_bit_depth\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/convertbits.rst",
    "content": "ConvertBits\n===========\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    ConvertBits(clip, int bits [, int dither, int dither_bits, bool fulls, bool fulld ] )\n\nChanges bit depth while keeping color format the same, if possible.\nIf the conversion is not possible – for example, converting RGB32 to 14bit – an error is raised.\n\n\n.. describe:: clip   = (required)\n\n        Source clip. \n\n.. describe:: bits\n\n     int  bits = (actual bit depth)\n\n        Bit depth of output clip. If provided valid values are: 8, 10, 12, 14, 16 (integer) or 32 (floating point). \n        Parameter is optional when no bitdepth change is needed but doing only range conversion (fulls-fulld) \n        or artistic dithering (dither_bits<bit depth).\n\n.. describe:: dither\n\n    int  dither = -1\n\n            If -1 (default), do not add dither;\n            If 0, add ordered dither;\n            If 1, add error diffusion (Floyd-Steinberg) dither doom9 \n\n        Dithering is allowed only for scaling down (bit depth reduction), not up. Bit depth can be kept though\n        if a smaller dither_bits is given. \n        \n        Note: (behind the scenes) 32 bit float clips are first converted down to 16 (or less if needed) bits, \n        then are further dithered down from this intermediate clip. \n\n.. describe:: dither_bits\n\n    int  dither_bits = bits\n\n        Exaggerated dither effect: dither to a lower color depth than required by bits argument. \n        The parameter has no effect if dither=-1 (off).\n\n        Arbitrary number from 1 to bits, inclusive. dither_bits = 1 means black and white.\n        \n        ConvertBits(8, dither=1, dither_bits=2);\n\n.. describe:: fulls\n\n    bool  fulls = (auto)\n\n        Use the default value unless you know what you are doing. \n        Default value can come from _ChromaRange frame property \n        If true (RGB default), scale by multiplication: 0-255 → 0-65535;\n\n        Note: full scale U and V chroma is specially handled\n        if false (YUV default), scale by bit-shifting. \n        Use case: override greyscale conversion to fullscale instead of bit-shifts. \n        Conversion from and to float is always full-scale. \n        Alpha plane is always treated as full scale. \n\n.. describe:: fulld\n\n    bool  fulld = fulls\n\n        Use the default value unless you know what you are doing. \n\n\nConvertBits writes _ChromaRange frame property (0-full or 1-limited) \n\nExamples\n--------\n\nConvert to 16 bits from whatever bit depth.\n::\n\n    clip16 = source.ConvertBits(16)\n\nConvert to 8 bits source is full, target is limited rage\n::\n\n    clip = source.ConvertBits(8, fulls=true, fulld=false)\n\nConvert to 8 bits source to 32 bit\n::\n\n  clip = source.ConvertBits(32,fulls=false, fulld=true)\n  # Y: 16..235 -> 0..1\n  # U/V: 16..240 -> -0.5..+0.5\n  # Note: now ConvertBits does not assume full range for YUV 32 bit float.\n  # Default values of fulls and fulld are now true only for RGB colorspaces. Frame prop can help.\n\nChangelog\n---------\n\n.. table::\n    :widths: auto\n\n    +-----------------+---------------------------------------------------------------------------+\n    | Version         | Changes                                                                   | \n    +=================+===========================================================================+\n    | 3.7.1           || Support YUY2 (by autoconverting to and from YV16), support YV411         |\n    |                 || \"bits\" parameter is not compulsory, bit depth can stay as it was         |\n    |                 || much nicer output for low bit depth targets (dither_bits 1 to 7)         |\n    |                 || allow dither down from 8 bit sources by giving a lower dither_bits value |\n    |                 || dither=1 (Floyd-S) to support dither_bits = 1 to 16 (similar to ordered) |\n    |                 || dither=0 (ordered) to allow odd dither_bits values.                      |\n    |                 |  Any dither_bits=1 to 16 (was: 2,4,6,8,..)                                |\n    |                 || dither=0 (ordered) allow larger than 8 bit difference when dither_bits<8 |\n    |                 || Correct conversion of full-range chroma at 8-16 bits.                    |\n    |                 |  Like 128+/-112 -> 128+/-127 in 8 bits                                    |\n    |                 || allow dither from 32 bits to 8-16 bits                                   |\n    |                 || allow different fulls fulld when converting between integer bit depths   |\n    |                 || allow 32 bit to 32 bit conversion                                        |\n    |                 || use input frame property _ColorRange to detect full/limited input        |\n    +-----------------+---------------------------------------------------------------------------+\n    | 3.4             | allow fulls-fulld combinations when either clip is 32bits                 |\n    +-----------------+---------------------------------------------------------------------------+\n    | r2455           | dither=1 (Floyd-Steinberg): allow any dither_bits value between           |\n    |                 | 0 and 8 (0=b/w)                                                           |\n    +-----------------+---------------------------------------------------------------------------+\n    | r2440 20170310  | new: dither=1: Floyd-Steinberg (was: dither=0 for ordered dither)         |\n    +-----------------+---------------------------------------------------------------------------+\n    | Avisynth+       | First added                                                               |\n    +-----------------+---------------------------------------------------------------------------+\n\n$Date: 2024/12/18 14:38:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/convertstacked.rst",
    "content": "==============\nConvertStacked\n==============\n\nThese compatibility conversion filters are to allow filters that `use 16-bit\nvideo in a pseudo-8-bit colorspace`_ aka stacked (or lsb) and interleaved format\nto interact with `AviSyth+ high bit depth formats`_ aka HBD.\n\n* :ref:`ConvertToStacked` converts a native 16-bit clip to the stacked or double\n  width format.\n* :ref:`ConvertFromStacked` converts a stacked or double width clip back to a\n  native high bit depth format.\n\n**These filters are intended to serve as a stopgap for plugins that are not\nsupporting true high bit depth yet so you shouldn't use them nowadays unless\nwith some rare filters that work only with these High-bit-depth hacks.**\n\n**Notes**\n\n* In `Stack16`_ (Stacked 16-bit) aka Double Height, the picture is made of two\n  parts: one containing the highest 8 bits (MSB) for each pixel, stacked on top\n  of another containing the lowest 8 bits (LSB), hence the name \"Double Height\".\n  It's used in `Dither tools`_ and many others. (Sometimes in filters is referred\n  as \"lsb\" only).\n\n* The Interleaved 16-bit aka Double Width is similar to Stack16, but the MSBs and\n  LSBs are horizontally interleaved which is like Native HBD, and it's faster\n  than lsb. It's used in [HDRCore] and it was also used in `flash3kyuu_deband`_,\n  `LSMASHSource`_ and other filters before they were updated to support 16-bit\n  planar (native HBD).\n\n* Both can be between 10-16 bits not only 16-bit.\n\n.. _ConvertToStacked:\n.. _ConvertToDoubleWidth:\n\nConvertToStacked / ConvertToDoubleWidth\n---------------------------------------\n\n**ConvertToStacked** accepts a 16-bit (HBD) clip and returns 16-bit stacked\n(MSB and LSB stacked one on top of the other in a fake double height \"8-bit\" stream).\n\n**ConvertToDoubleWidth** accepts a 16-bit (HBD) clip and returns 16-bit interleaved\n(MSB and LSB interleaved together in a fake double width \"8-bit\" stream).\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    ConvertToStacked (clip clip)\n    ConvertToDoubleWidth (clip clip)\n\n.. describe:: clip\n\n    Source clip. Must be native 16-bit: YUV420P16, YUV422P16, YUV444P16, Y16.\n\n.. _ConvertFromStacked:\n.. _ConvertFromDoubleWidth:\n\nConvertFromStacked / ConvertFromDoubleWidth\n-------------------------------------------\n\n**ConvertFromStacked** accepts a stacked clip and returns a HBD clip.\n\n**ConvertFromDoubleWidth** accepts a Double-Width clip and returns a HBD clip.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    ConvertFromStacked (clip clip, int \"bits\")\n    ConvertFromDoubleWidth (clip clip, int \"bits\")\n\n.. describe:: clip\n\n    Source clip. Must be YV12, YV16, YV24 or Y8.\n\n.. describe:: bits\n\n    Bit depth of returned clip. Must match the original bit depth.\n    See the 1st examples of both Stacked and DoubleWidth below.\n\n    Default: 16\n\n\nExamples\n--------\n\nStacked / LSB\n^^^^^^^^^^^^^\n\n1st example,\n\n::\n\n    ## Decoding 10bit, YUV 4:2:0 source\n    ## this is not needed nowadays since LSMASHSource added HBD support\n    ## so nowadays only LWLibavVideoSource(<path>) will did the job\n    ## but just for example, keep in mind that lsb is the slowest\n    LWLibavVideoSource(<path>, stacked=true, format=\"YUV420P10\")\n    ConvertFromStacked(bits=10)\n    ## the line below is only if you need to down to 8bit\n    ConvertBits(8, dither=0) # '0' means on, '-1' means off\n\n\n2nd example,\n\n::\n\n    ## this not needed since Dfttest support HBD, but just for example\n    ## some 16bit HBD clip here\n    ConvertToStacked()\n    Dfttest(lsb_in=true, lsb=true)\n    ConvertFromStacked()\n    ## Continue filtering with 16bit HBD\n\n\nDouble-Width / Interleaved Format\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n1st example (F3KDB can work with lsb but Double-Width is faster than lsb),\n\n::\n\n    ## this not needed since neo_f3kdb support HBD, but just for example\n    ## 10bit clip here\n    ConvertBits(16, truerange=false) #convey 10bit clip on 16bit clip with truerange=false\n    ConvertToDoubleWidth()\n    f3kdb(input_mode=2, input_depth=10, output_mode=2, output_depth=10)\n    ConvertFromDoubleWidth(bits=10)\n\n2nd example,\n\n::\n\n    ## 16bit clip here\n    ConvertToDoubleWidth()\n    Hqdn3d16Y()\n    ConvertFromDoubleWidth()\n\n\nChangelog\n---------\n\n+-----------------+------------------------------------------------------------+\n| Version         | Changes                                                    |\n+=================+============================================================+\n| AviSynth+ r2150 || Added 10/12/14 bit support to ConvertFrom* functions.     |\n|                 || Added ``bits`` parameter to ConvertFrom* functions.       |\n+-----------------+------------------------------------------------------------+\n| AviSynth+ r2043 || ConvertTo/From* functions moved to their own plugin.      |\n|                 || Added the ConvertTo/FromDoubleWidth functions.            |\n+-----------------+------------------------------------------------------------+\n| AviSynth+ r2022 | ConvertHbd*() functions renamed to ConvertToStacked and    |\n|                 | ConvertFromStacked.                                        |\n+-----------------+------------------------------------------------------------+\n| AviSynth+ r2003 | Added ConvertHbdFromStacked/ConvertHbdToStacked functions. |\n+-----------------+------------------------------------------------------------+\n\n$Date: 2022/03/07 03:39:14 $\n\n.. _use 16-bit video in a pseudo-8-bit colorspace:\n    http://avisynth.nl/index.php/High_bit-depth_Support_with_Avisynth#Processing_High_Bit-depth_Video_with_AviSynth\n.. _AviSyth+ high bit depth formats:\n    http://avisynth.nl/index.php/Avisynthplus_color_formats\n.. _Stack16:\n    http://avisynth.nl/index.php/Stack16\n.. _Dither tools:\n    http://avisynth.nl/index.php/Dither_tools\n.. _flash3kyuu_deband:\n    http://avisynth.nl/index.php/Flash3kyuu_deband\n.. _LSMASHSource:\n    http://avisynth.nl/index.php/LSMASHSource\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/converttomono.rst",
    "content": "\nConvertToMono\n=============\n\nConverts a multichannel audio signal to mono by averaging all channels with \nequal weights. If the signal is already in mono, it is returned untouched. \n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    ConvertToMono (clip)\n\n.. describe:: clip\n\n    | Source clip. Supported audio sample types: 16-bit integer and 32-bit float. \n    | Other sample types (8-, 24- and 32-bit integer) are automatically \n      :doc:`converted <convertaudio>` to 32-bit float. \n\n\n$Date: 2022/02/05 22:44:06 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/convolution.rst",
    "content": "==================\nGeneralConvolution\n==================\nPerforms a matrix convolution on any format clip.\n\n\nSyntax and Parameters\n---------------------\n\n::\n\n    GeneralConvolution (clip clip, float \"bias\", string \"matrix\", float \"divisor\", bool \"auto\",\n                        bool \"luma\", bool \"chroma\", bool \"alpha\")\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n.. describe:: bias\n\n    Additive bias to adjust the total output intensity.\n\n    Default: 0.0\n\n.. describe:: matrix\n\n    A 3×3, 5×5, 7×7 or 9×9 matrix with 3\\ :sup:`2` (9), 5\\ :sup:`2` (25),\n    7\\ :sup:`2` (49), 9\\ :sup:`2` (81) float or integer values. Float values are\n    converted to integers for 8-16 bit clips.\n\n    Default: \"0 0 0 0 1 0 0 0 0\"\n\n.. describe:: divisor\n\n    Divides the output of the convolution before adding bias.\n\n    Default: 1.0\n\n.. describe:: auto\n\n    Enables auto scaling. Auto scaling divides the output of the convolution by\n    the sum of the elements of the ``matrix``. The value of ``divisor`` is applied\n    in addition to this auto scaling factor. If the sum of elements is zero, auto\n    scaling is disabled.\n\n    Default: true\n\n.. describe:: luma, chroma, alpha\n\n    Enables processing only selected planes. For RGB clips ``luma`` and ``chroma``\n    setting is ignored. Unprocessed planes are simply copied. E.g. ``alpha=false``\n    can speed up RGBA/YUVA processing, usually the alpha channel is not used.\n\n    Default: true, true, true\n\n.. note:: The ``divisor`` is usually the sum of the elements of the ``matrix``.\n    But when the sum is zero, you can leave ``divisor=1`` and use the bias setting\n    to correct the pixel values. The ``bias`` could be useful if the pixel values\n    are negative due to the convolution. After adding ``bias``, the pixels are\n    clipped to the range 0-255 or the appropriate min-max range of the specific\n    bit depth. In 32 bit float formats no clamp happens.\n\n    Around the borders the edge pixels are simply repeated to service the matrix.\n\n\nExamples\n--------\n\n* Blur::\n\n    GeneralConvolution(0, \"\n       10 10 10 10 10\n       10 10 10 10 10\n       10 10 16 10 10\n       10 10 10 10 10\n       10 10 10 10 10 \", 256, False)\n\n* Horizontal (Sobel) edge detection::\n\n    GeneralConvolution(128, \"\n        1  2  1\n        0  0  0\n       -1 -2 -1 \", 8)\n\n* Vertical (Sobel) Edge Detection::\n\n    GeneralConvolution(128, \"\n       1  0 -1\n       2  0 -2\n       1  0 -1 \", 8)\n\n* Displacement (simply move the position of the \"1\" for left, right, up, down)::\n\n    GeneralConvolution(0,\"\n       0 1 0\n       0 0 0\n       0 0 0 \")\n\n* Displacement by half pixel up (auto scaling)::\n\n    GeneralConvolution(0,\"\n       0 1 0\n       0 1 0\n       0 0 0 \")\n\n* Displacement by half pixel right (manual scaling)::\n\n    GeneralConvolution(0,\"\n       0   0   0\n       0 128 128\n       0   0   0 \", 256, False)\n\n* Sharpness filter::\n\n    GeneralConvolution(0,\"\n       0   -1   0\n      -1    5  -1\n       0   -1   0 \", 1, True)\n\n    # In this case, the new pixel values y(m,n) are given by\n    # y(m,n) = (-1*x(m-1,n) - 1*x(m,n-1) + 5*x(m,n) - 1*x(m,n+1)\n    #          - 1*x(m+1,n))/(-1-1+5-1-1)/1.0 + 0\n\n* Slight blur filter with black level clipping and 25% brightening::\n\n    GeneralConvolution(-16,\"\n       0   12   0\n      12  256  12\n       0   12   0 \", 0.75, True)\n\n    # In this case, the new pixel values y(m,n) are given by\n    # y(m,n) = ( 12*x(m-1,n) + 12*x(m,n-1) + 256*x(m,n) + 12*x(m,n+1)\n    #          + 12*x(m+1,n) )/(12+12+256+12+12)/0.75 - 16\n\n* Emboss filter (3D relief effect)::\n\n    GeneralConvolution(128, \"\n    -1 0 0\n     0 0 0\n     0 0 1\")\n\nSome other examples can be found `here`_ and `also here`_.\n\n\nChangelog\n----------\n\n+------------------+--------------------------------------------------------------------------+\n| Version          | Changes                                                                  |\n+==================+==========================================================================+\n| AviSynth+ r2768  || Allow 7x7 and 9x9 matrices (was: 3x3 and 5x5).                          |\n|                  || All 8-32 bit formats supported (was: RGB32 only): YUY2 is converted     |\n|                  |  to/from YV16, RGB24/32/48/64 are treated as planar RGB internally.      |\n|                  || Since 32 bit float input is now possible, ``matrix`` elements and       |\n|                  |  ``bias`` parameter are now of float type.                               |\n|                  || For 8-16 bit clips the matrix is converted to integer before use.       |\n|                  || Allow chroma subsampled formats to have their luma or chroma processed. |\n|                  |  E.g. set chroma=false for a YV12 input.                                 |\n|                  || New parameters: ``luma, chroma, alpha``.                                |\n|                  || MT friendly parameter parsing.                                          |\n+------------------+--------------------------------------------------------------------------+\n| AviSynth 2.5.5   | Added ``divisor``, ``auto`` parameters.                                  |\n+------------------+--------------------------------------------------------------------------+\n| AviSynth 2.0.0   | Initial release.                                                         |\n+------------------+--------------------------------------------------------------------------+\n\n$Date: 2022/03/10 14:18:26 $\n\n.. _here:\n    http://web.archive.org/web/20100105183639/http://www.gamedev.net/reference/programming/features/imageproc/page2.asp\n.. _also here:\n    https://web.archive.org/web/20120802031716/https://jeanbruenn.info/2011/03/13/avisynths-convolution-stuff-explained/\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/crop.rst",
    "content": "====\nCrop\n====\n\nAviSynth has two dedicated cropping filters:\n\n* `Crop`_ is an all-purpose cropping filter.\n* `CropBottom`_ only crops the bottom of the frame.\n\nFor subpixel cropping see the cropping section of the\n:ref:`Resize <resize-cropping>` filters.\n\n*Cropping* refers to the removal of the outer parts of an image to improve\nframing, changing the framesize (also called image or storage aspect ratio).\nSee Wikipedia: `Cropping`_.\n\n.. _Crop:\n\nCrop\n----\n\nCrops excess pixels off of each frame. Cropping syntax can be specified in two\ndifferent ways as explained below.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    Crop (clip clip, int left, int top, int width, int height, bool \"align\")\n    Crop (clip clip, int left, int top, int -right, int -bottom, bool \"align\")\n\n.. describe:: clip\n\n    Input clip; all color formats supported.\n\n.. describe:: left, top\n\n        Cropping of the left and top edges respectively, in pixels.\n\n        * See :ref:`crop modulo restrictions <crop-restrictions>` below.\n\n.. describe:: width, height\n.. describe:: -right, -bottom\n\n    The third and fourth arguments have different names or aliases, depending on\n    their value:\n\n    * If  > zero, these set the ``width`` and ``height`` of the resulting clip.\n    * If <= zero, they set the cropping of the ``right`` and ``bottom`` edges\n      respectively.\n\n    Note, there are certain limits:\n\n    * clip.Width must be >= (``left`` + ``width``)\n    * clip.Width must be >  (``left`` + ``right``)\n    * clip.Height must be >= (``top`` + ``height``)\n    * clip.Height must be >  (``top`` + ``bottom``)\n\n    ...otherwise it would enlarge (\"un-crop\") the clip, or reduce width or height\n    to 0, which is not allowed.\n\n    * See :ref:`crop modulo restrictions <crop-restrictions>` below.\n\n.. describe:: align\n\n        Cropping an YUY2/RGB32 image is always `mod4`_ (four bytes). However, when\n        reading x bytes (an int), it is faster when the read is aligned to a modx\n        placement in memory. MMX/SSE likes 8-byte alignment and SSE2 likes 16-byte\n        alignment. If the data is NOT aligned, each read/write operation will be\n        delayed at least 4 cycles. So images are always aligned to mod16 when they\n        are created by AviSynth.\n\n        If an image has been cropped, they will sometimes be placed unaligned in\n        memory; ``align=true`` will copy the entire frame from the unaligned\n        memory placement to an aligned one.\n\n        **So if the penalty of the following filter is larger than the penalty\n        of a complete image copy, using** ``align=true`` **will be faster** –\n        especially when it is followed by smoothers.\n\n        Default: true\n\n.. _CropBottom:\n\nCropBottom\n----------\n\n**CropBottom** was created to crop garbage off the bottom of a clip captured\nfrom VHS tape. It removes ``count`` lines from the bottom of the frame.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    CropBottom (clip clip, int count)\n\n.. describe:: clip\n\n    Input clip; all color formats supported.\n\n.. describe:: count\n\n    | How many lines to crop from the bottom.\n    | See :ref:`crop modulo restrictions <crop-restrictions>` below.\n\n.. _crop-restrictions:\n\nCrop Restrictions\n-----------------\n\nIn order to preserve the data structure of the different colorspaces, the\nfollowing `mods`_ should be used. You will not get an error message if they are\nnot obeyed, but it may create strange artifacts. For a complete discussion on\nthis, see :doc:`../FilterSDK/DataStorageInAviSynth`. Also see the Doom9 Forum\nthread `\"Crop Restrictions\"`_.\n\n\n+----------------+------------------+--------------------------------------+\n| **Colorspace** | **Width**        | **Height**                           |\n+----------------+------------------+-------------------+------------------+\n|                |                  | progressive video | interlaced video |\n+================+==================+===================+==================+\n| RGB            | *no restriction* | *no restriction*  | mod-2            |\n+----------------+------------------+-------------------+------------------+\n+ Y              | *no restriction* | *no restriction*  | mod-2            |\n+----------------+------------------+-------------------+------------------+\n| YUV411         | mod-4            | *no restriction*  | mod-2            |\n+----------------+------------------+-------------------+------------------+\n| YUV420         | mod-2            | mod-2             | mod-4            |\n+----------------+------------------+-------------------+------------------+\n| YUV422         | mod-2            | *no restriction*  | mod-2            |\n+----------------+------------------+-------------------+------------------+\n| YUV444         | *no restriction* | *no restriction*  | mod-2            |\n+----------------+------------------+-------------------+------------------+\n\n.. note:: The :doc:`resize functions <resize>` optionally allow fractional pixel\n    cropping of the input frame, this results in a weighting being applied to the\n    edge pixels being resized.  These options may be used if the mod-n format\n    dimension restriction of crop are inconvenient.\n\n    In summary: *for cropping off hard artifacts like VHS head noise or letterbox\n    borders always use Crop. For extracting a portion of an image and to maintain\n    accurate edge resampling use the resize cropping parameters.* (`Doom9 thread`_)\n\n\nExamples\n--------\n\nIf your source video has 720x480 resolution, and you want to reduce it to 352x240\nfor `VideoCD`_, here's the correct way to do it::\n\n    # Converts CCIR601 to VCD, preserving the correct aspect ratio\n    ReduceBy2\n    Crop(4, 0, 352, 240)\n\nUsing the alternative syntax with negative (or zero) values in the last two\nparameters, they become offsets, `VirtualDub`_-style::\n\n    # Crops 16 pixels all the way around the picture, regardless of image size\n    Crop(16, 16, -16, -16)\n\n    # crop 8 off the left, 2 off the top, 9 off the right, and 4 off the bottom\n    Crop(8, 2, -9, -4)\n\n\nChangelog\n----------\n\n.. table::\n    :widths: auto\n\n    +------------------+----------------------------------------------------+\n    | Version          | Changes                                            |\n    +==================+====================================================+\n    | AviSynth+ r1576  | Fix: a fix for bad alignment in the Crop filter.   |\n    +------------------+----------------------------------------------------+\n    | AviSynth+ <r1576 | Crop: ``align`` now defaults to true. (2013-11-24) |\n    +------------------+----------------------------------------------------+\n    | AviSynth 2.5.3   | Crop: added ``align`` option (false by default).   |\n    +------------------+----------------------------------------------------+\n    | AviSynth 2.0.1   | Crop: added VDub style crop syntax.                |\n    +------------------+----------------------------------------------------+\n\n$Date: 2022/03/16 15:10:22 $\n\n.. _Cropping:\n    http://en.wikipedia.org/wiki/Cropping_(image)\n.. _mod4:\n    http://avisynth.nl/index.php/Modulo\n.. _mods:\n    http://avisynth.nl/index.php/Modulo\n.. _\"Crop Restrictions\":\n    https://forum.doom9.org/showthread.php?t=51923\n.. _Doom9 thread:\n    http://forum.doom9.org/showthread.php?s=&threadid=91630\n.. _VideoCD:\n    http://en.wikipedia.org/wiki/Video_CD\n.. _VirtualDub:\n    http://avisynth.nl/index.php/VirtualDub2\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/delayaudio.rst",
    "content": "\nDelayAudio\n==========\n\n**DelayAudio** delays the audio track by seconds.\n\nSyntax and Parameters\n----------------------\n\n::\n    \n    DelayAudio (clip, float seconds)\n\n.. describe:: clip\n\n    Source clip.\n    \n.. describe:: seconds\n\n    Delay time, in seconds. Seconds can be negative and/or have a fractional part.\n\n\nExamples\n---------\n\n* Play audio half a second earlier::\n\n    DelayAudio(-0.5)\n\n PS: if audio is loaded from separate file (for example :doc:`WavSource <avisource>`), \n it's better do the negative delay after AudioDub, or else it may cause problems.\n\n* When demuxing audio streams with `DGIndex`_ or `DGDecNV`_ , the delay \n  (actually how the delay should be corrected) is written into the name of the \n  demuxed audio stream. For example::\n\n    vid = MPEG2Source(\"movie.d2v\")\n    aud = FFAudioSource(\"movie T01 2_0ch 448Kbps DELAY -218ms.ac3\")\n    AudioDub(vid, aud)\n    DelayAudio(-0.218)\n\n$Date: 2022/02/04 22:44:06 $\n\n.. _DGIndex:\n    http://avisynth.nl/index.php/DGDecode\n.. _DGDecNV:\n    http://avisynth.nl/index.php/DGDecNV\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/deleteframe.rst",
    "content": "\nDeleteFrame\n===========\n\n**DeleteFrame** is the opposite of :doc:`DuplicateFrame <duplicateframe>`.\nIt deletes a set of frames, given as a number of arguments. The soundtrack is\nnot modified, so if you use this filter to delete many frames you may get\nnoticeable desynchronization.\n\nSyntax and Parameters\n----------------------\n\n::\n\n    DeleteFrame (clip, int frame [, ...])\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n.. describe:: frame\n\n    Frame number(s) to delete. Note that frames are numbered starting from zero.\n    If needed, use :ref:`ShowFrameNumber` before **DeleteFrame** to make sure\n    the right frames are selected.\n\n\nExamples\n--------\n\nDelete frames 3, 9, 21 and 42:\n\n::\n\n    DeleteFrame(3, 9, 21, 42)\n\nIf you want to delete a range of frames (*a* to *b*, say) along with the\ncorresponding portion of the soundtrack, you can do it with :doc:`Trim <trim>`,\nlike this:\n\n::\n\n    Trim(0,a-1) ++ Trim(b+1,0)\n\nOr with :doc:`Loop <loop>`, like this:\n\n::\n\n    Loop(0,a,b)\n\n\nChangelog\n----------\n\n+----------------+--------------------------------------+\n| Version        | Changes                              |\n+================+======================================+\n| AviSynth 2.5.8 | Added support for multiple arguments |\n+----------------+--------------------------------------+\n\n$Date: 2022/03/02 19:42:53 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/directshowsource.rst",
    "content": "================\nDirectShowSource\n================\n\n**DirectShowSource** reads media files using Microsoft `DirectShow`_, the same\nmultimedia playback system that WMP (*Windows Media Player*) uses. It can read\nmost formats that WMP can, including MP4, MP3, most MOV (QuickTime) files, as\nwell as AVI files that AVISource doesn't support (like DV type 1, or files using\nDirectShow-only codecs). There is also support for `GraphEdit`_ (grf) files.\n\nThere are some caveats:\n\n* Some decoders (notably MS MPEG-4) will produce upside-down video. You'll have\n  to use :doc:`FlipVertical <flip>`.\n* DirectShow video decoders are not required to support frame-accurate seeking.\n  In most cases seeking will work, but on some it might not.\n* DirectShow video decoders are not even required to tell you the frame rate of\n  the incoming video. Most do, but the ASF decoder doesn't. You have to specify\n  the frame rate using the ``fps`` parameter, like this:\n  ``DirectShowSource(\"video.asf\", fps=15)``.\n* This version automatically detects the Microsoft DV codec and sets it to\n  decode at full (instead of half) resolution. I guess this isn't a caveat. :-)\n* Also this version attempts to disable any decoder based deinterlacing.\n\nTry reading AVI files with :doc:`AviSource <avisource>` first. For non-AVI files,\ntry `FFmpegSource`_ or `LSMASHSource`_. If that doesn't work then try this filter\ninstead.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    DirectShowSource (string filename, float \"fps\", bool \"seek\", bool \"audio\", bool \"video\",\n                      bool \"convertfps\", bool \"seekzero\", int \"timeout\", string \"pixel_type\",\n                      int \"framecount\", string \"logfile\", int \"logmask\", bool \"utf8\")\n\n\n.. describe:: filename\n\n    The path of the source file; path can be omitted if the source file is in\n    the same directory as the AviSynth script (\\*.avs). See also parameter ``utf8``.\n\n.. describe:: fps\n\n    Frames Per Second of the resulting clip. This is sometimes needed to specify\n    the framerate. If the framerate or the number of frames is incorrect (this\n    can happen with ASF or MOV clips for example), use this option to force the\n    correct framerate. For live sources, this is like \"max fps\" that will be\n    displayed.\n\n    Default: auto\n\n.. describe:: seek\n\n    There is full seeking support available on most file formats. If problems\n    occur, try setting ``seekzero=true`` first. If seeking still causes problems,\n    disable seeking completely with ``seek=false``. With seeking disabled and\n    trying to seek backwards, the audio stream returns silence, and the video\n    stream returns the most recently rendered frame. **Note** the AviSynth cache\n    *may* provide limited access to the previous few frames, but beyond that the\n    most recently frame rendered will be returned.\n\n    Default: true\n\n.. describe:: audio\n\n    Enable audio on the resulting clip. The channel ordering is the same as in\n    the `wave-format-extensible format`_, because the input is always decompressed\n    to WAV. For more information, see also :doc:`GetChannel <getchannel>`.\n    AviSynth loads 8, 16, 24 and 32 bit int PCM samples, and float PCM format,\n    and any number of channels.\n\n    Default: true\n\n.. describe:: video\n\n    Enable video on the resulting clip.\n\n    Default: true\n\n.. describe:: convertfps\n\n    If true, it turns `VFR`_ (variable framerate) video into CFR (constant framerate)\n    video by adding frames. This allows you to open VFR video in AviSynth. It is\n    most useful when fps is set to the least common multiple of the component\n    frame rates, e.g. 120 or 119.880.\n\n    Default: false\n\n.. describe:: seekzero\n\n    If true, restrict backwards seeking only to the beginning, and seeking\n    forwards is done the hard way (by reading all samples). Limited backwards\n    seeking is allowed with non-indexed `ASF`_.\n\n    Default: false\n\n.. describe:: timeout\n\n    For positive values DirectShowSource waits for up to ``timeout`` milliseconds\n    for the DirectShow graph to start. ``timeout`` is clamped between [5000,300000]\n    milliseconds. If the graph fails to start a compile time exception is thrown.\n    Once the graph starts, each GetFrame/GetAudio call will wait for up to the\n    timeout value and then return a grey frame or silence for the audio. No\n    runtime exceptions are ever thrown because of time-outs.\n\n    For negative values DirectShowSource waits for up to 2000 milliseconds for\n    the DirectShow graph to start. If the graph fails to start it is ignored at\n    that point and the initial graph start wait is deferred until the first\n    GetFrame/GetAudio call. If any GetFrame/GetAudio call experiences a timeout\n    a runtime exception is then thrown.\n\n.. describe:: pixel_type\n\n    Request a color format from the decompressor. Valid values are:\n\n    YV24, YV16, YV12, I420, NV12, YUY2, AYUV, Y41P, Y411, ARGB, RGB64, RGB48,\n    RGB32, RGB24,  YUV, YUVex, RGB, AUTO, FULL\n\n        By default, upstream DirectShow filters are free to bid all of their\n        supported media types in the order of their choice. A few DirectShow filters\n        get this wrong. The ``pixel_type`` argument limits the acceptable video\n        stream subformats for the `IPin negotiation`_. Note the graph builder may\n        add a format converter to satisfy your request, so make sure the codec in\n        use can actually decode to your chosen format. The MS format converter is\n        just adequate. The \"YUV\" and \"RGB\" pseudo-types restrict the negotiation to\n        all official supported YUV or RGB formats respectively. The \"YUVex\" also\n        includes YV24, YV16, I420 and NV12 non-standard pixel types. The \"AUTO\"\n        pseudo-type permits the negotiation to use all relevant official formats,\n        YUV plus RGB. The \"FULL\" pseudo-type includes the non-standard pixel types\n        in addition to those supported by \"AUTO\". The full order of preference is\n        YV24, YV16, YV12, I420, NV12, YUY2, AYUV, Y41P, Y411, ARGB, RGB32, RGB24,\n        RGB64, RGB48. Many DirectShow filters get this wrong, which is why it is\n        not enabled by default. The option exists so you have enough control to\n        encourage the  maximum range of filters to serve your media.\n        (See `discussion`_.)\n\n        The non-standard pixel types use the following GUID's respectively :- ::\n\n            MEDIASUBTYPE_I420 = {'024I', 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71};\n            MEDIASUBTYPE_YV24 = {'42VY', 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71};\n            MEDIASUBTYPE_YV16 = {'61VY', 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71};\n            MEDIASUBTYPE_NV12 = {'21VN', 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71};\n\n    In other words, if ``pixel_type=\"AUTO\"``, it will try to output YV24; if\n    that isn't possible it tries YV16, and if that isn't possible it tries\n    YV12, etc...\n\n    For planar color formats, adding a '+' prefix, e.g.\n    ``DirectShowSource(..., pixel_type=\"+YV12\")``, tells AviSynth the video rows\n    are DWORD aligned in memory instead of packed. This can fix skew or tearing\n    of the decoded video when the width of the picture is not divisible by 4.\n\n.. describe:: framecount\n\n    Sometimes needed to specify the :doc:`frame count <../syntax/syntax_clip_properties>`\n    of the video. If the framerate or the number of frames is incorrect (this\n    can happen with ASF or MOV clips for example), use this option to force the\n    correct number of frames. If ``fps`` is also specified, the length of the\n    audio stream is adjusted. For live sources, specify a very large number.\n\n    Default: auto\n\n.. describe:: logfile\n\n    Use this option to specify the name of a log file for debugging.\n\n.. describe:: logmask\n\n    When a ``logfile`` is specified, use this option to select which information\n    is logged.\n\n    +-------+-------------------------+\n    | Value | Data                    |\n    +=======+=========================+\n    | 1     | Format Negotiation      |\n    +-------+-------------------------+\n    | 2     | Receive samples         |\n    +-------+-------------------------+\n    | 4     | GetFrame/GetAudio calls |\n    +-------+-------------------------+\n    | 8     | Directshow callbacks    |\n    +-------+-------------------------+\n    | 16    | Requests to Directshow  |\n    +-------+-------------------------+\n    | 32    | Errors                  |\n    +-------+-------------------------+\n    | 64    | COM object use count    |\n    +-------+-------------------------+\n    | 128   | New objects             |\n    +-------+-------------------------+\n    | 256   | Extra info              |\n    +-------+-------------------------+\n    | 512   | Wait events             |\n    +-------+-------------------------+\n\n    Add the values together of the data you need logged. Specify -1 to log\n    everything. The default, 35, logs 1+2+32, or Format Negotiation, Received\n    samples and Errors.\n\n    Default: 35\n\n.. describe:: utf8\n\n    Use this option if the filename is in utf8 encoding. Note that since Windows 10 v1803\n    utf8 is supported natively, when set in the System Locale setting.\n\n    default: false\n\nExamples\n--------\n\nOpens an avi with the first available RGB format (without audio)::\n\n    DirectShowSource(\"F:\\xvid.avi\", fps=25, audio=false, pixel_type=\"RGB\")\n\nOpens a DV clip with the MS DV decoder::\n\n    DirectShowSource(\"F:\\DVCodecs\\Ced_dv.avi\") # MS-DV\n\nOpens a variable framerate mkv as 119.88 by adding frames (ensuring sync)::\n\n    DirectShowSource(\"F:\\vfr_startrek.mkv\", fps=119.88, convertfps=true)\n\nOpens a realmedia (\\*.rmvb) clip::\n\n    DirectShowSource(\"F:\\test.rmvb\", fps=24, convertfps=true)\n\nOpens a `GraphEdit`_ file::\n\n    V=DirectShowSource(\"F:\\vid_graph.grf\", audio=False) # video only (audio renderer removed)\n    A=DirectShowSource(\"F:\\aud_graph.grf\", video=False) # audio only (video renderer removed)\n    AudioDub(V, A)\n\nSee :ref:`below <dss-downmixingac3>` for some audio examples.\n\n\nTroubleshooting video and audio problems\n----------------------------------------\n\nAviSynth will by default try to open only the media it can open without any\nproblems. If one component cannot be opened it will simply not be added to the\noutput. This will also mean that if there is a problem, you will not see the\nerror. To get the error message to the missing component, use ``audio=false`` or\n``video=false`` and disable the component that is actually working. This way\nAviSynth will print out the error message of the component that doesn't work.\n\n\nRenderFile, the filter graph manager won't talk to me\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThis is a common error that occurs when DirectShow isn't able to deliver any\nformat that is readable to AviSynth. Try creating a filter graph manually and\nsee if you are able to construct a filter graph that delivers any output\nAviSynth can open. If not, you might need to download additional DirectShow\nfilters that can deliver correct material.\n\nThe picture is skewed or torn and the colors are wrong\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nSome DirectShow components incorrectly pad the lines of planar data to be DWORD\naligned as is done for RGB24 DIB format. This is incorrect, but it is a fairly\ncommon mistake. By adding a '+' to the start of the pixel_type string you can\ninform DirectShowSource to treat planar data formats as padded DWORD aligned.\nThis problem shows up when the width of the picture is not divisible by 4.\n\n::\n\n    DirectShowSource(\"NonMod4Video.mp4\", pixel_type=\"+YV12\") # Bad DWORD aligned planar\n\nThe samplerate is wrong\n~~~~~~~~~~~~~~~~~~~~~~~\n\nSome filters might have problems reporting the right samplerate, and then\ncorrect this when the file is actually playing. Unfortunately there is no way\nfor AviSynth to correct this once the file has been opened. Use\n:doc:`AssumeSampleRate <assumerate>` and set the correct samplerate to fix this\nproblem.\n\nMy sound is choppy\n~~~~~~~~~~~~~~~~~~\n\nUnfortunately Directshow is not required to support sample exact seeking.\nOpen the sound another way, or demux your video file and serve it to AviSynth\nanother way. Otherwise you can specify ``seekzero=true`` or ``seek=false`` as\nparameters or use the :doc:`EnsureVBRMP3Sync <ensuresync>` filter to enforce\nlinear access to the Directshow audio stream.\n\n\nMy sound is out of sync\n~~~~~~~~~~~~~~~~~~~~~~~\n\nThis can happen especially with WMV, apparently due to variable frame rate\nvideo being returned. Determine what the fps should be and set it explicitly,\nand also :doc:`ConvertFPS <fps>` to force it to remain constant. And\n:doc:`EnsureVBRMP3Sync <ensuresync>` reduces problems with variable rate audio.\n\n::\n\n    DirectShowSource(\"video.wmv\", fps=25, ConvertFPS=True)\n    EnsureVBRMP3Sync()\n\nMy ASF renders start fast and finish slow\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nMicrosoft in their infinite wisdom chose to implement ASF stream timing in\nthe ASF demuxer. As a result it is not possible to strip ASF format files any\nfaster than realtime. This is most apparent when you first start to process\nthe streams, usually after opening the Avisynth script it takes you a while\nto configure your video editor, all this time the muxer is accumulating\n*credit* time. When you then start to process your stream it races away at\nmaximum speed until you catch up to realtime at which point it slows down to\nthe realtime rate of the source material. This feature makes it impossible to\nuse Avisynth to reclock 24fps ASF material up to 25fps for direct PAL\nplayback.\n\nWindows7 users\n~~~~~~~~~~~~~~\n\nWindows 7 forces its own DirectShow filters for decoding several audio and video\nformats. Changing their merits or physically removing those filters doesn't help.\nclsid made the tool `\"Win7DSFilterTweaker\"`_ to change the preferred filters.\nHowever new decoders need to be added each time so it's not the perfect solution.\n\n\nCommon tasks\n------------\n\nThis section will describe various tasks that might not be 100% obvious. :)\n\n\nOpening GRF files\n~~~~~~~~~~~~~~~~~\n\n`GraphEdit`_ GRF-files are automatically detected by a .grf filename extension\nand directly loaded by DirectShowSource. For AviSynth to be able to connect\nto it, you must leave a pin open in GraphEdit of a media types that AviSynth\nis able to connect to. AviSynth will not attempt to disconnect any filters,\nso it is important that the output type is correct. DirectShowSource only\naccepts YV24, YV16, YV12, YUY2, AYUV, Y41P, Y411, ARGB, RGB32, RGB24, RGB64\nand RGB48 video formats and 32, 24, 16 and 8 bit PCM and IEEE FLOAT audio \nformats.\n\nA given GRF-file should only target one of an audio or video stream to avoid\nconfusion when directshowsource attempts the connection to your open pin(s).\nThis single stream restriction is enforced.\n\n.. _dss-downmixingac3:\n\nDownmixing AC3 to stereo\n~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe following section covers how to downmix a 5.1 AC3 file to stereo using\n`AC3Filter`_ and then load the result with **DirectShowSource**.\n\n#. Install AC3Filter (see warning below).\n\n    a.) Open **AC3Filter Config**. In the \"Main\" tab on the \"Output format\"\n    section and select \"Stereo\" and set the format to \"PCM Float\". [Nothing else\n    is needed.]\n\n    **-OR-**\n\n    b.) Open the AC3 file in a media player. For example, in `MPC-HC`_ (v1.9.19)\n    go to the \"Play\" tab and then scroll down to \"Filters\" and select AC3Filter.\n    The **AC3Filter Config** window will open, from there set the output format\n    to **Stereo** and for maximum quality set the format to **PCM Float**.\n\n    .. list-table::\n\n        * - .. figure:: pictures/ac3filter-downmix.png\n\n               **AC3Filter Config**\n\n    Any changes made within AC3Filter will also be applied to the AC3 file when\n    decoded via **DirectShowSource**. For example, if Gain and/or DRC are used\n    or any other settings in the Mixer, Gains and Equalizer tabs.\n\n    .. warning::\n\n        The `lastest AC3Filter`_ version is 2.6.0b and x64 is only available in\n        the \"full\" version. Note that the full version comes bundled with the\n        (now-defunct) OpenCandy adware module that included unwanted third-party\n        offers during the setup process. More information in the archived\n        `AC3Filter wiki`_ and the `\"Is AC3Filter Safe?\"`_ VideoHelp thread. The\n        \"lite\" version does not contain OpenCandy but does not include a 64-bit\n        AC3Filter.\n\n#. Write the following script::\n\n    v = Mpeg2Source(\"e:\\movie.d2v\")\n    a = DirectShowSource(\"e:\\test.ac3\")\n    AudioDub(v,a)\n\n#. Finally, load the script in VDub or FFmpeg and save the audio stream to the\n   desired format.\n\nNote that this method is not only limited to AC3 files but since AC3Filter is no\nlonger developed, some *modern* formats may not be compatible. However, there are\nother alternatives. For example, ``LWLibavAudioSource(\"test.ac3\", layout=\"DL+DR\")``\nfrom `LSMASHSource`_ will also downmix to stereo. And of course, for more control\nthere are a handful of AviSynth scripts that use the core filters for downmixing.\nSee the examples section in the :doc:`GetChannels <getchannel>` filter page.\n\nSee also\n--------\n\n* Haali media splitter also comes with an (unrelated) DirectShow input plugin\n  `DirectShowSource2`_, aka DSS2.\n\n* Another (unrelated) alternative is `DSS2mod`_.\n\n\nChangelog\n---------\n\n+-------------------+------------------------------------------------------------+\n| Version           | Changes                                                    |\n+===================+============================================================+\n| AviSynth 3.7.4    | Add utf8 support.                                          |\n+-------------------+------------------------------------------------------------+\n| AviSynth+ r2294MT | 16-bit RGB input support (BGR[48], BRA[64])                |\n+-------------------+------------------------------------------------------------+\n| AviSynth 2.6.0    | Added pixel_types \"YV24\", \"YV16\", \"AYUV\", \"Y41P\", \"Y411\".  |\n+-------------------+------------------------------------------------------------+\n| AviSynth 2.5.7    || framecount overrides the length of the streams.           |\n|                   || logfile and logmask specify debug logging.                |\n+-------------------+------------------------------------------------------------+\n| AviSynth 2.5.6    || convertfps turns vfr into constant cfr by adding frames.  |\n|                   || seekzero restricts seeking to begining only.              |\n|                   || timeout controls response to recalcitrant graphs.         |\n|                   || pixel_type specifies/restricts output video pixel format. |\n+-------------------+------------------------------------------------------------+\n\n$Date: 2023/12/02 19:24:00 $\n\n.. _DirectShow:\n    https://en.wikipedia.org/wiki/DirectShow\n.. _GraphEdit:\n    http://avisynth.nl/index.php/GraphEdit\n.. _FFmpegSource:\n    http://avisynth.nl/index.php/FFmpegSource\n.. _LSMASHSource:\n    http://avisynth.nl/index.php/LSMASHSource\n.. _wave-format-extensible format:\n    https://web.archive.org/web/20190905063051/http://www.cs.bath.ac.uk/~jpff/NOS-DREAM/researchdev/wave-ex/wave_ex.html\n.. _VFR:\n    http://avisynth.nl/index.php/VFR\n.. _ASF:\n    https://en.wikipedia.org/wiki/Advanced_Systems_Format\n.. _IPin negotiation:\n    https://en.wikipedia.org/wiki/DirectShow#Architecture\n.. _discussion:\n    https://forum.doom9.org/showthread.php?t=143321\n.. _planar:\n    http://avisynth.nl/index.php/Planar\n.. _\"Win7DSFilterTweaker\":\n    https://forum.doom9.org/showthread.php?t=146910\n.. _AC3Filter:\n    https://web.archive.org/web/20191212120549/http://www.ac3filter.net/wiki/AC3Filter\n.. _MPC-HC:\n    https://github.com/clsid2/mpc-hc\n.. _lastest AC3Filter:\n    https://code.google.com/archive/p/ac3filter/downloads\n.. _AC3Filter wiki:\n    https://web.archive.org/web/20200428203226/http://ac3filter.net/wiki/OpenCandy\n.. _\"Is AC3Filter Safe?\":\n    https://forum.videohelp.com/threads/379482-Is-AC3Filter-Safe\n.. _Channel Downmixer by Trombettworks:\n    https://web.archive.org/web/20190907051617/http://www.trombettworks.com/directshow.php\n.. _DirectShowSource2:\n    http://avisynth.nl/index.php/DSS2#Source_Filters\n.. _DSS2mod:\n    http://avisynth.nl/index.php/DSS2mod\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/dissolve.rst",
    "content": "========\nDissolve\n========\n\n**Dissolve** is like :doc:`AlignedSplice <splice>`, except that the clips are \ncombined with some overlap. The last *overlap* frames of the first video stream \nare blended progressively with the first *overlap* frames of the second video\nstream so that the streams fade into each other. The audio streams are\nblended similarly.\n\nThe term \"dissolve\" is sometimes used for a different effect in which the\ntransition is pointwise rather than gradated. This filter won't do that.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    Dissolve (clip1, clip2 [, ...], int overlap, float \"fps\")\n\n.. describe:: clip1, clip2, ...\n\n    Source clips; the dimensions of the clips and their color formats must be \n    the same. If the clips contain audio, the audio properties must also be the \n    same. The framerate is taken from the first clip, - see \n    :doc:`filters with multiple input clips <../filters_mult_input_clips>` for \n    the resulting :doc:`clip properties <../syntax/syntax_clip_properties>`.\n\n.. describe:: overlap\n\n    How many frames to overlap.\n\n.. describe:: fps\n\n    The ``fps`` parameter is optional and provides a reference for ``overlap`` \n    in audio only clips. It is ignored if a video stream is present. Set \n    ``fps=AudioRate()`` if sample exact audio positioning is required.\n\n    Default: 24.0\n\n\nExamples\n--------\n\n::\n\n     # Load sources\n     a = AVISource(\"clipA.avi\")\n     b = AVISource(\"clipB.avi\")\n     \n     # 30 frame Dissolve between clipA & clipB; last & clipA; last & clipB\n     # Resulting output: clipA (Dissolve) clipB (Dissolve) clipA (Dissolve) clipB.\n     Dissolve(a, b, 30) \n     Dissolve(last, a, 30)\n     Dissolve(last, b, 30)\n\n\nChangelog\n----------\n\n.. table::\n    :widths: 40 60\n    \n    +-----------------+------------------------------+\n    | Version         | Changes                      |\n    +=================+==============================+\n    | AviSynth+ r2290 | Added 16 and 32-bit support. |\n    +-----------------+------------------------------+\n    | AviSynth 2.5.6  | Added ``fps`` parameter.     |\n    +-----------------+------------------------------+\n\n\n$Date: 2022/09/18 12:22:43 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/doubleweave.rst",
    "content": "\nDoubleWeave\n===========\n\n``DoubleWeave`` (clip)\n\nIf the input clip is field-based, the ``DoubleWeave`` filter operates like\n:doc:`Weave <weave>`, except that it produces double the number of frames: instead of\ncombining fields 0 and 1 into frame 0, fields 2 and 3 into frame 1, and so\non, it combines fields 0 and 1 into frame 0, fields 1 and 2 into frame 1, and\nso on. It does not change the frame rate or frame count.\n\nIf the input clip is frame-based, this filter acts just as though you'd\nseparated it into fields with :doc:`SeparateFields <separatefields>` first, only faster!\n\n:doc:`Weave <weave>` is actually just a shorthand for ``DoubleWeave`` followed by\n:doc:`SelectEven <select>`.\n\nMost likely you will want to use a filter like :doc:`SelectOdd <select>` or\n:doc:`Pulldown <pulldown>` after using this filter, unless you really want a 50fps or\n60fps video. It may seem inefficient to interlace every pair of fields only\nto immediately throw away half of the resulting frames. But actually, because\nAvisynth only generates frames on demand, frames that are not needed will\nnever be generated in the first place.\n\nIf you're processing field-based video, like video-camera footage, you\nprobably won't need this filter. But if you're processing NTSC video\nconverted from film and you plan to use the ``Pulldown`` filter, you need to\nuse ``DoubleWeave`` first. See the ``Pulldown`` filter for an explanation.\n\nIf you're processing PAL video converted from film, you don't need\n``Pulldown``, but you might want to use ``DoubleWeave`` in the following\nsituation:\n\n::\n\n    # Duplicate the functionality of the VirtualDub \"PAL deinterlace\" filter\n    DoubleWeave\n    SelectOdd\n\n\n$Date: 2005/01/21 07:47:22 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/duplicateframe.rst",
    "content": "\nDuplicateFrame\n==============\n\n**DuplicateFrame** is the opposite of :doc:`DeleteFrame <deleteframe>`. It\nduplicates a set of frames given as a number of arguments. As with\n:doc:`DeleteFrame <deleteframe>`, the soundtrack is not modified, so if you use\nthis filter to duplicate many frames you may get noticeable desynchronization.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    DuplicateFrame (clip, int frame [, ...])\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n.. describe:: frame\n\n    Frame(s) to duplicate. Note that frames are numbered starting from zero. If\n    needed, use :ref:`ShowFrameNumber` before **DuplicateFrame** to make sure\n    the right frames are selected.\n\n\nExamples\n---------\n\nDuplicate frame number 3 twice and duplicate frame 21 and 42 once::\n\n\n    DuplicateFrame(3, 3, 21, 42) # Add 4 frames\n\n\nChangelog\n---------\n\n+----------------+--------------------------------------+\n| Version        | Changes                              |\n+================+======================================+\n| AviSynth 2.5.8 | Added support for multiple arguments |\n+----------------+--------------------------------------+\n\n$Date: 2022/03/02 19:42:53 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/echo.rst",
    "content": "\nEcho\n====\n\n**Echo** forces getframe accesses to all the input clips (up to the number of \nframes of the first clip). The results from *clip2* and up are discarded. The \nresult from *clip1* is returned.\n\nThis may be useful forcing alternate script paths with \n:doc:`ImageWriter <imagewriter>` and :doc:`WriteFile <write>`.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    Echo (clip1, clip2 [, ...])\n\n.. describe:: clip1, clip2, ...\n\n    Source clip(s).\n\n\nExamples\n--------\n\n::\n\n    clip1 = ColorBars.Trim(0,99).ShowFrameNumber() # numbered clip (640x480)\n    clip2 = clip1.SelectEvery(10, 0) # select frame 0, 10, 20, ...\n    clip2 = clip2.BilinearResize(160, 120) # create thumbnails of frame 0, 10, 20, ...\n    clip2 = clip2.ImageWriter(file=\"D:\\AviSynth\\Plugins\\file\", type=\"jpg\")\n    Echo(clip1, clip2) # returns clip1, exports clip2 (the thumbnails)\n\n\nChangelog\n----------\n\n+----------------+-----------------+\n| Version        | Changes         |\n+================+=================+\n| AviSynth 2.6.0 | Initial release |\n+----------------+-----------------+\n\n$Date: 2022/02/04 13:38:34 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/ensuresync.rst",
    "content": "\nEnsureVBRMP3Sync\n================\n\n**EnsureVBRMP3Sync** will ensure synchronization of video with variable\nbitrate audio (MP3-AVI's for example) during seeking or trimming. It does so\nby buffering the audio. The name of the filter is a bit misleading, since it\nis useful for every stream with variable bitrate audio and not just for MP3.\n\nIt will slow seeking down considerably, but is very useful when using\n:doc:`Trim <trim>` for instance. Always use it before trimming.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    EnsureVBRMP3Sync (clip)\n\n.. describe:: clip\n\n    Source clip.\n\n\nExamples\n--------\n\nEnsures that soundtrack is in sync after trimming::\n\n    AviSource(\"movie.avi\")\n    EnsureVBRMP3Sync()\n    Trim(250,2500)\n\n$Date: 2022/02/05 09:39:34 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/expr.rst",
    "content": "\nExpr\n====\nApplies a `mathematical function`_, defined by an *expression* string, on the\npixels of the source clip(s). A different expression may be set for each color\nchannel. Users of `MaskTools2`_ may be familiar with this concept.\n\nSyntax and Parameters\n---------------------\n\n::\n\n    Expr (clip clip[, ...], string exp[, ...],\n          string \"format\", bool \"optAvx2\", bool \"optSingleMode\", bool \"optSSE2\",\n          string \"scale_inputs\", bool \"clamp_float\", bool \"clamp_float_UV\", \n          int \"lut\", int \"optVectorC\")\n\n.. describe:: clip\n\n    One or more source clips. Up to 26 input clips can be specified.\n\n    * The first three clips are referenced by lowercase letter x, y and z; use\n      'a', 'b' ... 'w' for the rest.\n    * Clips may be YUV(A), RGB(A), or greyscale; 8-16 bit integer or 32 bit float.\n    * Width, height and `chroma subsampling`_ should be the same; bit depths can\n      be different.\n\n.. describe:: exp\n\n        One or more `RPN`_ expressions.\n\n        * A different expression may be set for each color channel (or plane).\n          Plane order is Y-U-V-A or R-G-B-A. (note: due to a bug, versions prior\n          to r2724 used GBRA ordering).\n        * When an expression string is not given, the previous one is used.\n        * The empty string (``\"\"``) is a valid expression; it causes the plane\n          to be copied (see `Expressions`_ below).\n        * Keyword delimiters are space, but TAB, CR and LF characters are allowed\n          as whitespace as well since 3.7.1.\n\n.. describe:: format\n\n    Set color format of the returned clip.\n\n    * Use `pixel format strings`_ like \"YV12\", \"YUV420P8\", \"YUV444P16\", \"RGBP10\".\n    * By default, the output format is the same as the first clip.\n\n    Default: \"\"\n\n.. describe:: optAvx2\n\n    Enables or disables `AVX2`_ code generation if available. Do nothing if AVX2\n    is not supported in AviSynth. False disables AVX2.\n\n    Default: auto\n\n.. describe:: optSingleMode\n\n    If true, generate assembly code using only one XMM/YMM register set\n    instead of two.\n\n    * **Expr** generates assembly code that normally uses two 128 (SSE2) or 256\n      bit (AVX2) registers (\"lanes\"), thus processing 8 (SSE2)/16 (AVX2) pixels\n      per internal cycle.\n    * Experimental parameter, ``optSingleMode=true`` makes the internal compiler\n      generate instructions for only one register (4/8 pixels - SSE2/AVX2). The\n      parameter was introduced to test the speed of x86 code using one working\n      register. Very-very complex expressions would use too many XMM/YMM registers\n      which are then \"swapped\" to memory slots, that could be slow. Using\n      ``optSingleMode=true`` may result in using less registers with no need\n      for swapping them to memory slots.\n\n    Default: false\n\n.. describe:: optSSE2\n\n    Enables or disables `SSE2`_ code generation when in non-AVX2 mode. Setting\n    ``optSSE2=false`` and ``optAVX2=false`` forces expression processing in a\n    slower interpreted way (C language, see also ``optVectorC``). False disables SSE2.\n\n    Default: auto\n\n.. describe:: scale_inputs\n\n    Autoscale any input bit depths to 8-16 bit integer or 32 bit float for\n    internal expression use, the conversion method is either full range\n    (stretch) or limited YUV range (like bit shift). Feature is similar to the\n    one in MaskTools2 v2.2.15. The primary reason of this feature is the \"easy\"\n    usage of formerly written expressions optimized for 8 bits.\n\n        +----------------+--------------------------------------------------------------+\n        | Option         | Description                                                  |\n        +================+==============================================================+\n        | ``\"int\"``      | Scales limited range videos, only integer formats (8-16bits) |\n        |                | to 8 (or bit depth specified by 'i8'..'i16' and 'f32')       |\n        +----------------+--------------------------------------------------------------+\n        | ``\"intf\"``     | Scales full range videos, only integer formats (8-16bits)    |\n        |                | to 8 (or bit depth specified by 'i8'..'i16' and 'f32')       |\n        +----------------+--------------------------------------------------------------+\n        | ``\"float\"`` or | Only scales 32 bit float format to 8 bit                     |\n        | ``\"floatf\"``   | range (or bit depth specified by 'i8'..'i16' and 'f32')      |\n        +----------------+--------------------------------------------------------------+\n        | ``\"floatUV\"``  | Chroma pre and post shift by 0.5 for 32 bit float pixels,    |\n        |                | thus having them in the range of 0..1 instead of -0.5..+0.5  |\n        |                | during Expr evaluation (since v3.5)                          |\n        +----------------+--------------------------------------------------------------+\n        | ``\"all\"``      | Scales videos to 8 (or bit depth specified by 'i8'..'i16'    |\n        |                | and 'f32') - conversion uses limited_range logic             |\n        |                | (mul/div by two's power)                                     |\n        +----------------+--------------------------------------------------------------+\n        | ``\"allf\"``     | Scales videos to 8 (or bit depth specified by 'i8'..'i16'    |\n        |                | and 'f32') - conversion uses full scale logic (stretch)      |\n        +----------------+--------------------------------------------------------------+\n        | ``\"none\"``     | No magic (default)                                           |\n        +----------------+--------------------------------------------------------------+\n\n    * E.g. ``scale_inputs=\"float\"`` will automatically convert 32 bit float\n      input to 8 bit range (but keeps the floating point precision).\n    * The default 8 bit target range can be overridden by the i10 .. i16 or f32\n      specifiers at the beginning of the expression string.\n    * The script inside will treat the clip as a 8 bit one. This only affects\n      the internal calculations, the output is properly scaled back.\n    * Note: ``ymin, ymax, cmin, cmax, range_min, range_max, range_half`` and\n      ``range_size`` internal variables are changed accordingly (this behaviour\n      was fixed in AviSynth+ > r2900).\n\n    Default: \"none\"\n\n.. describe:: clamp_float\n\n    If true: clamps 32 bit float to valid ranges, which is 0..1 for luma or for\n    RGB color space and -0.5..0.5 for YUV chroma UV channels.\n\n    * Until 3.4: Ignored when scale_inputs scales 32bit-float type pixels.\n    * From 3.5: not ignored, even when parameter ``\"scale_inputs\"`` auto-scales\n      32 bit float type pixels to integer.\n\n    Default: false (as usual, 32 bit float pixels are not clamped)\n\n.. describe:: clamp_float_UV\n\n    This parameter affects clamping of chroma planes: chroma is clamped between\n    0..1.0 instead of -0.5..0.5.\n\n    Default: false (as usual, 32 bit float pixels are not clamped)\n\n.. describe:: lut\n\n    LUT (Look-up Table) mode. LUT is precalculated table. Expression values\n    are calculated for all pixel value combinations in advance. Then in each\n    frame the resulting pixel value is 'looked up' from the ready-made table,\n    which is indexed by the actual (x) or (x,y) pixel value. Added in v3.7.1.\n\n        +--------+-----------------------------------------------------------+\n        | Option | Description                                               |\n        +========+===========================================================+\n        | ``0``  | Realtime calculation (default).                           |\n        +--------+-----------------------------------------------------------+\n        | ``1``  | 1D LUT (lutx)                                             |\n        |        |                                                           |\n        |        | - 1D luts are available for 8-16 bit inputs. An 8 bit 1D  |\n        |        |   lut needs 256 byte memory. A 16 bit 1D lut needs 65536  |\n        |        |   2-byte-words (131072 bytes).                            |\n        +--------+-----------------------------------------------------------+\n        | ``2``  | 2D lut (lutxy)                                            |\n        |        |                                                           |\n        |        | - 2D luts are available for 8-14 bit inputs. Note: a 14   |\n        |        |   bit 2D lut needs (2^14)*(2^14)*2 bytes buffer in memory |\n        |        |   per plane (~1GByte).                                    |\n        +--------+-----------------------------------------------------------+\n\n        .. note::\n\n            **Caveats**\n\n            * When lut is not available for a given bit depth then Expr will silently\n              fallback to realtime (lut=0) mode.\n            * In 1D or 2D lut mode some keywords and features are forbidden in the\n              expression: sx, sy, sxr, syr, frameno, time, relative pixel addressing.\n            * Frame property access works, but is limited to frame #0 which is read\n              before LUT evaluation.\n            * In lut mode the input clip's bit depths must be the same.\n\n    Default: 0\n\n.. describe:: optVectorC\n\n    C code is run when\n    \n    - non x86/x64 systems (architectures which are not supported by JIT compiler)\n    - expression contains atan, asin, acos, which are not implemented in JIT.\n      (and ``tan`` before 3.7.4), \n    - JIT is intentionally disabled with optSSE2=False\n    \n    Enables or disables a compiler friendly (more easily vectorizable) C code.\n    The source is written in such a ways that compilers can easily turn it into\n    efficient SIMD vector operation, the patterns - do the same operation on\n    4-8-16 pixels - are easily recognizable.\n    \n    Even if the compiler is not very advanced (MSVC khhhhmm..) this approach is \n    faster because it has less overhead when interpreting the instruction flow. It \n    processes 16, 8, 4, and 1 pixels (32 bit floats) when handling the horizontal \n    line, taking the largest chunks it can then finishing the rest with the smaller ones.\n    \n    This way, a good compiler can achieve one-third the speed of the SSE2 JIT (which is considered \n    fast), so this is quite impressive. Expect 3-20x speedup compared to the old method\n    (which can be tested with optVectorC=False).\n\n    Default: True\n\nExpressions\n-----------\n\n**Expr** accepts 1 to 26 **source clips**, up to four **expression** strings\n(one per color plane), an optional output format string, and some debug options.\nOutput video format is inherited from the first clip, when there is no format\noverride. All clips have to match in their width, height and `chroma subsampling`_.\n\nExpressions are evaluated on each plane, Y, U, V (and A) or R, G, B (,A). When\nan expression string is not specified, the previous expression is used for that\nplane – except for plane A (alpha) which is copied by default. When an expression\nis an empty string (``\"\"``) then the relevant plane will be copied (if the output\nclip bit depth is similar). When an expression is a single clip reference letter\n(\"x\") and the source/target bit depth is similar, then the relevant plane will\nbe copied. When an expression is constant (after constant folding), then the\nrelevant plane will be filled with an optimized memory fill method.\n\n* Example: ``Expr(clip, \"255\", \"128, \"128\")`` fills all three planes.\n* Example: ``Expr(clip, \"x\", \"range_half, \"range_half\")`` copies luma, fills U\n  and V with 128/512/... (bit depth dependent).\n\nOther optimizations: do not call GetFrame for input clips that are not referenced\nor plane-copied.\n\nExpressions are written in `RPN`_.\n\nExpressions use 32 bit float precision internally.\n\nFor 8..16 bit formats output is rounded and clamped from the internal 32 bit\nfloat representation to valid 8, 10, ... 16 bits range. 32 bit float output is\nnot clamped at all.\n\nExpr language/RPN elements\n^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n* Clips: letters *x, y, z, a..w. x* is the first clip parameter, *y* is the\n  second one, etc.\n* Math: ``* / + -``\n* ``%`` (modulo), like fmod. Example: ``result = x - trunc(x/d)*d``. Note: the\n  internal 32-bit float can hold only a 24 bit integer number (approximately).\n* Math constant: ``pi``\n* Functions: ``min, max, sqrt, abs, exp, log, pow ^`` (synonyms: ``pow`` and ``^``)\n* Function: ``neg`` simple negates stack top\n* Function: ``sgn`` simple signum function -1 if x<0; 0 when x==0; 1 if x>0\n* Function: ``clip`` three operand function for clipping. Example: ``x 16 240\n  clip`` means min((max(x,16),240)\n* Functions: ``sin cos atan2 tan asin acos atan`` |br| On Intel x86/x64 the\n  functions ``sin``, ``cos``, ``tan``  and ``atan2`` have SSE2/AVX2 optimization, \n  the others have not (if e.g. ``acos`` is used it makes the whole expression to \n  evaluate without JitASM optimization).\n* Functions: ``round, floor, ceil, trunc`` operators (nearest integer - banker's\n  rounding, round down, round up, round to zero). |br| On Intel builds acceleration\n  requires at least SSE4.1 capable processor or else the whole expression is\n  running in C mode.\n* Logical: ``> < = >= <= and or xor not == & | !=`` (synonyms: ``==`` and ``=``,\n  ``&`` and ``and``, ``|`` and ``or``)\n* Ternary operator: ``?`` - Example: ``x 128 < x y ?``\n* Duplicate stack elements: ``dup, dupn`` (dup1, dup2, ...)\n* Swap stack elements: ``swap, swapn`` (swap1, swap2, ...)\n* Scale by bit shift: ``scaleb`` (operand is treated as being a number in 8 bit\n  range unless i8..i16 or f32 is specified).\n* Scale by full scale stretch: ``scalef`` (operand is treated as being a number\n  in 8 bit range unless i8..i16 or f32 is specified).\n\n\nBit-depth aware constants\n^^^^^^^^^^^^^^^^^^^^^^^^^\n\n* ``ymin, ymax`` (ymin_a .. ymin_z for individual clips) - the usual luma limits\n  (16..235 or scaled equivalents).\n* ``cmin, cmax`` (cmin_a .. cmin_z) - chroma limits (16..240 or scaled equivalents)\n* ``range_half`` (range_half_a .. range_half_z) - half of the range, (128 or scaled\n  equivalents).\n* ``range_size`` (range_size_a .. range_size_z , etc..) - 256, 1024, 4096, 16384,\n  65536 for integer formats, 1.0 for 32 bit float formats.\n* ``range_min, range_max`` (range_min_a .. range_min_z) - chroma/luma plane aware\n  constants for the actual min-max limits.\n* ``yrange_min, yrange_half, yrange_max`` - Unlike the luma/chroma plane adaptive\n  \"range_min\", \"range_half\", \"range_max\" these constants always report the luma\n  (Y) values. Since v3.5.\n\nWhen the constant name is ended with _x, _y, _z, _a, etc.. the constant is brought\nfrom the specified clip (input clips can be of different formats) When by using\nparameter ``\"scale_inputs\"`` the input is converted to e.g. 8 bits, these constants\nare calculated for this internally used bit depth.\n\nKeywords for modifying base bit depth\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n* ``i8, i10, i12, i14, i16, f32`` (used with ``scaleb`` and ``scalef``)\n\nSpatial input variables in expr syntax\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n* ``sx, sy`` (absolute x and y coordinates, 0 to width-1 and 0 to height-1)\n* ``sxr, syr`` (relative x and y coordinates, from 0 to 1.0)\n\nFrame property input\n~~~~~~~~~~~~~~~~~~~~\n\n* Frame properties (Integer or 32 bit float type) can be accessed within the\n  expressions.\n* ``clipletter.frameProperty`` syntax injects actual frame property values into\n  expression.\n* Example: ``x._ColorRange`` will push the value of ``_ColorRange`` frame\n  property on stack (of clip x).\n\nInternal variables\n~~~~~~~~~~~~~~~~~~\n\n    **User variables**\n\n    * Variables can freely be used during evaluation for storing and loading\n      intermediate results within the expression.\n    * Variable names must begin with an English letter (a to z, A to Z) or with\n      _ (underscore), followed by one or more underscore, letters or digits.\n      For example A, X2, _myvar, aa etc.. (until 3.7.1 only uppercase A to Z\n      names were allowed).\n    * Variables names are case sensitive and cannot be already reserved words.\n\n    **Actions with variables**\n\n    * Store: ``varname@``\n        Actual stack top is assigned to a variable.\n    * Store and pop from stack: ``varname^``\n        Actual stack top is assigned to a variable, then is immediately removed\n        from stack top. Use case: when the value assigned to the variable won't\n        be used immediately.\n    * Variables can be used by simply giving their names: ``varname``\n        The actual content of the variable is pushed onto the stack top.\n    * Example: ``\"x y - A^ x y 0.5 + + B^ A B / C@ x +\"``\n\n    **Special predefined variables**\n\n    * ``frameno`` : use current frame number in expression.\n      ``0 <= frameno < clip_frame_count.`` |br| A 32 bit integer converted to\n      float, so it is precise only at approximately 24 bits.\n    * ``time`` : ``calculation: time = frameno/clip_frame_count``. Use relative\n      time position in expression. ``0 <= time < frameno/clip_frame_count``\n    * ``width, height``: clip width and clip height\n\nPixel addressing\n~~~~~~~~~~~~~~~~\n\nIndexed, addressable source clip pixels by relative x,y positions.\n\n    Syntax: ``x[a,b]`` where\n\n    * ``'x'`` : source clip letter a..z\n    * ``'a'`` : horizontal shift. -width < a < width\n    * ``'b'`` : vertical shift. -height < b < height\n\n    ``'a'`` and ``'b`` should be constant. e.g.:\n    ``\"x[-1,-1] x[-1,0] x[-1,1] y[0,-10] + + + 4 /\"``\n\n| When a pixel would come from off-screen, the pixels are cloned from the edge.\n| Optimized version of indexed pixels requires SSSE3, and no AVX2 version is\n  available. Non-SSSE3 falls back to C for the whole expression.\n\nAuto-scale inputs with \"scale_inputs\"\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nAutoscale works by converting any input bit depths to a common 8-16 integer or\n32 bit float bit format for internal expression use, the conversion method is\neither full range or limited YUV range. Feature is similar to the one in\nMaskTools2 v2.2.15.\n\nThe primary reason of this feature is the \"easy\" usage of formerly written\nexpressions optimized for 8 bits.\n\nPossible values for ``scale_inputs``:\n\n* ``\"int\"`` : scales limited range videos, only integer formats (8-16bits) to 8\n  (or bit depth specified by 'i8'..'i16','f32')\n* ``\"intf\"`` : scales full range videos, only integer formats (8-16bits) to 8\n  (or bit depth specified by 'i8'..'i16','f32')\n* ``\"float\"`` or ``\"floatf\"`` : only scales 32 bit float format to 8 bit range\n  (or bit depth specified by 'i8'..'i16','f32')\n* ``\"floatUV\"`` : chroma pre and post shift by 0.5 for 32 bit float pixels, thus\n  having them in the range of 0..1 instead of -0.5..+0.5 during Expr evaluation\n  (since v3.5)\n* ``\"all\"`` : scales videos to 8 (or bit depth specified by 'i8'..'i16','f32')\n  - conversion uses limited_range logic (mul/div by two's power)\n* ``\"allf\"`` : scales videos to 8 (or bit depth specified by 'i8'..'i16','f32')\n  - conversion uses full scale logic (stretch)\n* ``\"none\"`` : no magic\n\nUsually limited range is for normal YUV videos, full scale is for RGB or\nknown-to-be-fullscale YUV.\n\n| By default the internal conversion target is 8 bits, so old expressions written\n  for 8 bit videos will probably work.\n| This internal working bit-depth can be overwritten by the i8, i10, i12, i14,\n  i16 and f32 specifiers.\n\n| When using autoscale mode, ``scaleb`` and ``scalef`` keywords are meaningless\n  for 8-16 bits, because there is nothing to scale. However, 32 bit (float)\n  values will be scaled when ``\"float\"``, ``\"floatUV\"``, ``\"all\"``, ``\"allf\"``\n  is specified.\n| Different conversion methods cannot be set for converting before and after the\n  expression. Neither can you specify different methods for distinct input clips\n  (e.g. x is full, y is limited is not supported).\n\nHow it works:\n\n* 8-32 bit inputs ar all scaled to a common bit depth value, which bit depth is\n  8 by default and can be set to 10, 12, 14, 16 or 32 bits by the 'i10'..'i16',\n  'f32' keywords.\n\n| For example: ``scale_inputs=\"all\"`` converts any inputs to 8 bit range.\n  No truncation occurs however (no precision loss), because even a 16 bit data\n  is converted to 8 bit in floating point precision, using division by 256.0\n  (2^16/2^8).\n| So the conversion is _not_ a simple shift-right-8 in the integer domain, which\n  would lose precision.\n\n* Calculates expression\n* Scales the internal result back to the original video bit depth.\n* Clamping (clipping to valid range) and converting to an integer output\n  (if applicable) occurs here.\n\nThe predefined constants such as ``'range_max'``, etc. will behave according to\nthe internal working bit depth.\n\n.. note::\n\n    **Important note!**\n\n        This feature was created for easy porting earlier 8-bit-video-only lut\n        expressions. You have to understand how it works internally.\n\n        Let's see a 16bit input in ``\"all\"`` and ``\"allf\"`` mode (target is the\n        default 8 bits):\n\n        * Limited range 16->8 bits conversion has a factor of 1/256.0 (Instead\n          of shift right 8 in integer domain, float-division is used or else it\n          would lose presision)\n\n        * Full range 16->8 bits conversion has a factor of 255.0/65535 (chroma\n          is a bit different, since it is converted by moving into signed domain\n          and back such as in (x-32768)*(127/32767)+128)\n\n        * Using bit shifts (really it's division and multiplication by 2^8=256.0):\n          |br| result = calculate_value(input / 256.0) * 256.0\n\n        * Full scale 16-8-16 bit mode (``'intf', 'allf'``): |br|\n          result = calculate_value(input / 65535.0 * 255.0 ) / 255.0 * 65535.0\n\n        * chroma: |br| result = (calculate_value((input-32768) / 32767.0 * 127.0\n          + 128 ) - 128) / 127.0 * 32767.0 + 32768\n\n        * Use ``scale_inputs = \"all\"`` (``\"int\", \"float\"``) for YUV\n          videos with 'limited' range e.g. in 8 bits: Y=16..235, UV=16..240).\n\n        * Use ``scale_inputs = \"allf\"`` (``intf, floatf``) for RGB or\n          YUV videos with 'full' range e.g. in 8 bits: channels 0..255.\n\n        * When input is 32bit float, the 0..1.0 (luma) and -0.5..0.5 (chroma)\n          channel is scaled to 0..255 (8 bits), 0..1023 (i10 mode), 0..4095\n          (i12 mode), 0..16383(i14 mode), 0..65535(i16 mode) then back.\n\nCompared to MaskTools\n^^^^^^^^^^^^^^^^^^^^^\n\nCompared to `MaskTools2`_ version 2.2.15, **Expr** has functionality similar to\n*mt_lut, mt_lutxy, mt_lutxyz, mt_lutxyza* and *mt_lutspa*.\n\nMaskTools2 is very slow for 10+ bit clips, when a `LUT`_ (lookup table) cannot\nbe used for memory size reasons, thus the expression is evaluated/interpreted at\nruntime for each pixel. MaskTools2 (from v2.2.15) however is able to pass the\nexpressions to this AviSynth+ **'Expr'** filter with its ``'use_expr'`` parameter,\nby passing the **expression** strings, and ``clamp_float`` and ``scale_inputs``\nparameters.\n\nThe `JIT compiler`_ in **Expr** (adapted from `VapourSynth`_) turns the\nexpression calculation into realtime assembly code which is much faster and\nbasically bit depth independent.\n\n    In **Expr**:\n\n    * Up to 26 clips are allowed (x,y,z,a,b,...w). Masktools handles only up to\n      4 clips with its mt_lut, mt_lutxy, mt_lutxyz, mt_lutxyza\n    * Clips with different bit depths are allowed\n    * Works with 32 bit floats instead of 64 bit double internally\n    * Less functions (e.g. no bit shifts)\n    * Logical 'false' is 0 instead of -1\n    * The ymin, ymax, etc built-in constants can have a _X suffix, where X is\n      the corresponding clip designator letter. E.g. cmax_z, range_half_x\n    * mt_lutspa-like functionality is available through \"sx\", \"sy\", \"sxr\", \"syr\"\n      internal predefined variables\n    * No y= u= v= parameters with negative values for filling plane with constant\n      value, constant expressions are changed into optimized \"fill\" mode\n\n\nExamples\n--------\n\n* Average three clips::\n\n    c = Expr(clip1, clip2, clip3, \"x y + z + 3 /\")\n\n* When input clips to have more planes than an implicitely specified output format::\n\n    # target is Y only which needs only Y plane from YV12\n    Expr(aYV12Clip, \"x 255.0 /\", format=\"Y32\")\n\n* Y-plane-only clip(s) can be used as source planes when a non-subsampled (rgb\n  or 444) output format is specified::\n\n    # In both examples, the r, g and b expression uses the Y plane\n    Expr(Y, \"x\", \"x 2.0 /\", \"x 3.0 /\", format=\"RGBPS\")\n    Expr(Grey_r, Grey_g, Grey_b, \"x\", \"y 2.0 /\", \"z 3.0 /\", format=\"RGBPS\")\n\n* Using spatial feature::\n\n    c = Expr(clip_for_format, \"sxr syr 1 sxr - 1 syr - * * * 4096 scaleb *\", \"\", \"\")\n\n* Mandelbrot zoomer (original code and idea from this `Doom9 thread`_)::\n\n    a=\"X dup * Y dup * - A + T^ X Y 2 * * B + 2 min Y^ T 2 min X^ \"\n    b=a+a\n    c=b+b\n    blankclip(width=960, height=640, length=1600, pixel_type=\"YUV420P8\")\n    Expr(\"sxr 3 * 2 - -1.2947627 - 1.01 frameno ^ / -1.2947627 + A@ X^ syr 2 * 1 - 0.4399695 \"\n    \\ + \"- 1.01 frameno ^ / 0.4399695 + B@ Y^ \"+c+c+c+c+c+b+a+\"X dup * Y dup * + 4 < 0 255 ?\",\n    \\ \"128\", \"128\")\n\n For other ideas of spatial variables, see MaskTools2: `mt_lutspa`_\n\n* Using the time variable for fades::\n\n    Expr(\"x time *\") # linear fade in\n    Expr(\"x 1 time - *\") # linear fade out\n    Expr(\"x time 2 pow *\") # quadratic(?) fade in\n    Expr(\"x time pi * cos 0.5 * 0.5 + *\") # sinusoidal fade out\n\n See Doom9 thread `\"Fade with configurable time curves?\"`_ for more information.\n\nChangelog\n----------\n\n+-----------------+----------------------------------------------------------+\n| Version         | Changes                                                  |\n+=================+==========================================================+\n| 3.7.4           || Enhancement: vectorizable C implementation helps nonJIT |\n|                 || New parameter: optVectorC                               |\n|                 || Implement ``tan`` for JitASM                            |\n+-----------------+----------------------------------------------------------+\n| AviSynth+ 3.7.2 || Expr: ``scale_inputs`` to case insensitive and add      |\n|                 |  floatUV to error message as an allowed value.           |\n|                 || Fix: Expr LUT operation Access Violation on x86 + AVX2  |\n|                 |  due to an unaligned internal buffer (<32 bytes).        |\n+-----------------+----------------------------------------------------------+\n| AviSynth+ 3.7.1 || New: ``round, floor, ceil, trunc``                      |\n|                 || TAB, CR, LF are valid string delimiters inside expr     |\n|                 |  string                                                  |\n|                 || Enhanced: arbitrary variable names, not only A to Z     |\n|                 || Access clip's frame properties:                         |\n|                 |  *clipletter.frameProperty* syntax                       |\n|                 || Enhanced: ``sin`` and ``cos``: SIMD acceleration        |\n|                 || New: ``atan2``                                          |\n|                 || New: ``neg, sgn``                                       |\n|                 || Enhanced: allow ‘f32’ as internal autoscale target      |\n|                 |  besides integer i8..i16                                 |\n|                 || lut (Lookup table) support 1D and 2D                    |\n|                 || Enhanced: special full scale conversion of chroma plane |\n+-----------------+----------------------------------------------------------+\n| AviSynth+ 3.5.0 || Allow ``\"floatUV\"`` for parameter ``\"clamp_float\"``     |\n|                 || New parameter ``\"clamp_float_UV\"``                      |\n+-----------------+----------------------------------------------------------+\n| AviSynth+ r2724 || New three operand function: clip                        |\n|                 || New parameter ``\"clamp_float\"``                         |\n|                 || New parameter ``\"scale_inputs\"``                        |\n+-----------------+----------------------------------------------------------+\n| AviSynth+ r2574 || New: indexable source clip pixels by relative x,y       |\n|                 |  positions like x[-1,1]                                  |\n|                 || New functions: ``sin cos tan asin acos atan``           |\n|                 || New operator: % (modulo)                                |\n|                 || New: variables: uppercase letters A..Z for storing and  |\n|                 |  reuse temporary results, frequently used computations.  |\n|                 || New: predefined expr variables                          |\n|                 |  ``'frameno', 'time', 'width', 'height'``                |\n|                 || Fix: jitasm code generation at specific circumstances   |\n+-----------------+----------------------------------------------------------+\n| AviSynth+ r2544 |  Optimization; fix ``scalef``                            |\n+-----------------+----------------------------------------------------------+\n| AviSynth+ r2542 |  Initial release                                         |\n+-----------------+----------------------------------------------------------+\n\n$Date: 2025/03/06 16:15:00 $\n\n.. _mathematical function:\n    https://en.wikipedia.org/wiki/Function_(mathematics)\n.. _chroma subsampling:\n    https://en.wikipedia.org/wiki/Chroma_subsampling\n.. _RPN:\n    https://en.wikipedia.org/wiki/Reverse_Polish_notation\n.. _pixel format strings:\n    http://avisynth.nl/index.php/Avisynthplus_color_formats\n.. _AVX2:\n    https://en.wikipedia.org/wiki/Advanced_Vector_Extensions\n.. _SSE2:\n    https://en.wikipedia.org/wiki/SSE2\n.. _Doom9 thread:\n    https://forum.doom9.org/showthread.php?p=1738391#post1738391\n.. _LUT:\n    https://en.wikipedia.org/wiki/Lookup_table\n.. _MaskTools2:\n    http://avisynth.nl/index.php/MaskTools2\n.. _JIT compiler:\n    https://en.wikipedia.org/wiki/Just-in-time_compilation\n.. _VapourSynth:\n    https://www.vapoursynth.com/doc/functions/video/expr.html\n.. _mt_lutspa:\n    http://avisynth.nl/index.php/MaskTools2/mt_lutspa\n.. _\"Fade with configurable time curves?\":\n    https://forum.doom9.org/showthread.php?t=183934\n\n.. |br| raw:: html\n\n      <br>"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/extract.rst",
    "content": "===============\nExtract Filters\n===============\n\nSet of filters to extract a plane (channel) from the source clip:\n\n* **Extract** family includes 7 filters, each name corresponds to the plane that\n  will be extracted.\n* **PlaneToY** works differently, the plane to be extracted is defined by a\n  parameter.\n\nResulting clip is Y-only (Y8, Y10 etc. as appropriate). To extract a plane while\nkeeping the same color format or to cast it to another format use the\n:doc:`Show filter family <showalpha>`.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    ExtractY (clip)\n    ExtractU (clip)\n    ExtractV (clip)\n    ExtractA (clip)\n    ExtractR (clip)\n    ExtractG (clip)\n    ExtractB (clip)\n    PlaneToY (clip, string \"plane\")\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n.. describe:: plane\n\n    The color plane to be extracted.\n    If specified plane does not exist, an error is raised.\n\n    Default: \"Y\"\n\n\nExamples\n--------\n\nFor RGB, ExtractR/G/B are identical to::\n\n    PlaneToY(\"R\") # also ShowRed(\"Y\")\n    PlaneToY(\"G\") # also ShowGreen(\"Y\")\n    PlaneToY(\"B\") # also ShowBlue(\"Y\")\n\nFor YUV, ExtractY/U/V are identical to::\n\n    PlaneToY(\"Y\") # also ShowY(\"Y\") and ConvertToY()\n    PlaneToY(\"U\") # also ShowU(\"Y\") and UToY8()\n    PlaneToY(\"V\") # also ShowV(\"Y\") and VToY8()\n\nFor RGBA/YUVA alpha extraction, ExtractA is identical to::\n\n    PlaneToY(\"A\") # also ShowAlpha(\"Y\")\n\n\nChangelog\n---------\n\n+-----------------+---------------------------------------------------------------+\n| Version         | Changes                                                       |\n+=================+===============================================================+\n| AviSynth+ 3.7.1 | ExtractY/U/V/R/G/B/A, PlaneToY: delete _ChromaLocation        |\n|                 | property. Set _ColorRange property to \"full\" if source is     |\n|                 | Alpha plane.                                                  |\n+-----------------+---------------------------------------------------------------+\n| AviSynth+ r2768 || Fix: Allow ExtractY on greyscale clips.                      |\n|                 || Fix: ShowY, ShowU, ShowV crash for YUV (non-YUVA) sources.   |\n+-----------------+---------------------------------------------------------------+\n| AviSynth+ r2331 || Fix: YUY2 PlaneToY finally works.                            |\n+-----------------+---------------------------------------------------------------+\n| AviSynth+ r1858 || ExtractY, PlaneToY(\"Y\") accepts YUY2 clip.                   |\n|                 || ExtractR, ExtractG, ExtractB, ExtractA, and PlaneToY(\"R\"),   |\n|                 |  PlaneToY(\"G\"), PlaneToY(\"B\"), PlaneToY(\"A\") functions are    |\n|                 |  accepting packed RGB input (RGB24/32/48/64). They are        |\n|                 |  converted to planar RGB on-the-fly before plane extraction.  |\n+-----------------+---------------------------------------------------------------+\n| AviSynth+       | New functions for plane extraction ExtractX. (20161116)       |\n+-----------------+---------------------------------------------------------------+\n\n$Date: 2022/03/23 20:11:14 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/fade.rst",
    "content": "============\nFade Filters\n============\n\n| **FadeIn** blends progressively *from* ``color`` at the beginning.\n| **FadeOut** blends progressively *to* ``color`` at the end.\n| **FadeIO** blends progressively *from/to* ``color`` at both ends.\n\n* The sound track (if present) also fades linearly to and/or from silence.\n\n* The fading affects only the first/last ``num_frames`` frames of the video.\n\n* The first/last frame of the video becomes almost-but-not-quite color. |br|\n  An additional ``color`` frame is added at the start/end, thus increasing the\n  total frame count by one (or for **FadeIO**, by two).\n\n\n| **FadeIn0** / **FadeOut0** / **FadeIO0** do not add the extra ``color`` frames,\n  leaving the end(s) almost-but-not-quite color.\n| **FadeIn2** / **FadeOut2** / **FadeIO2** add two extra ``color`` frames at the\n  start/end instead of one.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    FadeIn (clip clip, int num_frames, int \"color\", float \"fps\", int \"color_yuv\", float+ \"colors\")\n    FadeIO (clip clip, int num_frames, int \"color\", float \"fps\", int \"color_yuv\", float+ \"colors\")\n    FadeOut (clip clip, int num_frames, int \"color\", float \"fps\", int \"color_yuv\", float+ \"colors\")\n\n    FadeIn0 (clip clip, int num_frames, int \"color\", float \"fps\", int \"color_yuv\", float+ \"colors\")\n    FadeIO0 (clip clip, int num_frames, int \"color\", float \"fps\", int \"color_yuv\", float+ \"colors\")\n    FadeOut0 (clip clip, int num_frames, int \"color\", float \"fps\", int \"color_yuv\", float+ \"colors\")\n\n    FadeIn2 (clip clip, int num_frames, int \"color\", float \"fps\", int \"color_yuv\", float+ \"colors\")\n    FadeIO2 (clip clip, int num_frames, int \"color\", float \"fps\", int \"color_yuv\", float+ \"colors\")\n    FadeOut2 (clip clip, int num_frames, int \"color\", float \"fps\", int \"color_yuv\", float+ \"colors\")\n\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n.. describe:: num_frames\n\n    Fade duration, in frames.\n\n.. describe:: color\n\n    | Specifies the start/end color; black by default.\n    | Color is specified as an RGB value in either hexadecimal or decimal notation.\n    | Hex numbers must be preceded with a $. See the\n      :doc:`colors <../syntax/syntax_colors>` page for more information on\n      specifying colors.\n\n    * For YUV clips, colors are converted from full range to limited range\n      `Rec.601`_.\n\n    * Use ``color_yuv`` or ``colors`` to specify full range YUV values or a\n      color with a different matrix.\n\n    Default: $000000\n\n.. describe:: fps\n\n    Provides a reference for num_frames in audio only clips. It is ignored if a\n    video stream is present.\n\n    * Set ``fps=AudioRate`` if sample exact audio positioning is required.\n\n    Default: 24.0\n\n.. describe:: color_yuv\n\n    Specifies the start/end color using YUV values. Input clip must be YUV;\n    otherwise an error is raised. See the :ref:`YUV colors <yuv-colors>` for\n    more information.\n\n.. describe:: colors\n\n    Specifies the start/end color using an array. Use this to pass exact,\n    unscaled color values. If the array is larger, further values are simply\n    ignored.\n\n    Color order: Y,U,V,A or R,G,B,A\n\n\nNotes\n-----\n\n::\n\n    FadeOut(clip, num_frames)\n\nis just a shorthand for ::\n\n    Dissolve(clip, BlankClip(clip, num_frames+1, color=color), num_frames)\n\n(with num_frames+2 instead of num_frames+1 for ``FadeOut2``, and num_frames+0\nfor ``FadeOut0``).\n\n\nExamples\n--------\n\nFade in the first 15 frames from black on a 8-bit clip (either RGB or YUV)::\n\n    # RGB\n    Fade(15, color=$000000)\n    Fade(15, colors=[0,0,0])\n\n    # YUV\n    Fade(15, color=$000000)       # limited range\n    Fade(15, color_yuv=$108080)   # limited range\n    Fade(15, colors=[16,128,128]) # limited range\n    Fade(15, colors=[0,128,128])  # full range\n    Fade(15, color_yuv=$008080)   # full range\n\nFade out the last 15 frames to white on a 8-bit clip (either RGB or YUV)::\n\n    # RGB\n    Fade(15, color=$FFFFFF)\n    Fade(15, colors=[255,255,255])\n\n    # YUV\n    Fade(15, color=$FFFFFF)        # limited range\n    Fade(15, color_yuv=$EB8080)    # limited range\n    Fade(15, colors=[235,128,128]) # limited range\n    Fade(15, colors=[255,128,128)) # full range\n    Fade(15, color_yuv=$FF8080)   # full range\n\n\nChangelog\n---------\n\n+-----------------+---------------------------------------------------------------------+\n| Version         | Changes                                                             |\n+=================+=====================================================================+\n| AviSynth+ 3.7.2 | Added parameters ``color_yuv`` and ``colors`` for all fade filters. |\n+-----------------+---------------------------------------------------------------------+\n| AviSynth 2.5.6  || Added FadeIn0, FadeOut0, and FadeIO0 filters.                      |\n|                 || Added optional ``fps`` parameter for processing audio only clips.  |\n+-----------------+---------------------------------------------------------------------+\n| AviSynth 2.0.7  || Added FadeIn, FadeIn2, FadeIO and FadeIO2 filters.                 |\n|                 || Added the ``color`` parameter to all fade functions.               |\n+-----------------+---------------------------------------------------------------------+\n\n$Date: 2022/09/17 11:43:32 $\n\n.. _Rec.601:\n    https://en.wikipedia.org/wiki/Rec._601\n\n.. |br| raw:: html\n\n      <br>\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/fixbrokenchromaupsampling.rst",
    "content": "\nFixBrokenChromaUpsampling\n=========================\n\nThe free Canopus DV Codec v1.00 upsamples the chroma channels incorrectly\n(although newer non-free versions appear to work fine). Chroma is `duplicated\nfrom the other field`_, resulting in the famous :doc:`Chroma Upsampling Error <../advancedtopics/sampling>`.\n\n**FixBrokenChromaUpsampling** filter compensates for it. You should put this\nafter :doc:`AviSource <avisource>` if you're using the above Canopus DV codec. \nOld versions of the DirectShow based MS DV codec also might have this problem \n(the one that comes with DirectX7 (but i need to check this), the one that comes \nwith DirectX8/9 works fine).\n\nThe Canopus DV codec swaps the chroma of the middle 2 for each group of 4\nlines:\n\n+---------------+---------------+\n| frame_correct | frame_Canopus |\n+===============+===============+\n| line 1        | line 1        |\n+---------------+---------------+\n| line 2        | line 3        |\n+---------------+---------------+\n| line 3        | line 2        |\n+---------------+---------------+\n| line 4        | line 4        |\n+---------------+---------------+\n| line 5        | line 5        |\n+---------------+---------------+\n| line 6        | line 7        |\n+---------------+---------------+\n| line 7        | line 6        |\n+---------------+---------------+\n| line 8        | line 8        |\n+---------------+---------------+\n\nFor each group of 4 lines **FixBrokenChromaUpsampling** corrects this by\nswapping the chroma of the middle 2 back.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    FixBrokenChromaUpsampling (clip)\n\n.. describe:: clip\n\n    Source clip; only YUY2 color format supported.\n\n$Date: 2022/02/13 12:37:33 $\n\n.. _duplicated from the other field:\n    http://forum.doom9.org/showthread.php?p=180052#post180052\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/fixluminance.rst",
    "content": "\nFixLuminance\n============\n\n.. warning::\n\n    This filter is considered broken/deprecated: see `discussion`_\n\nThe purpose of this filter is to progressively darken the top of the image; \nfor example, to compensate for certain VCRs which make the top of each frame \nbrighter than the bottom. In practice it only works for NTSC content and it \nneeds its fields separated.\n\nWhen applying it to an image with height > 255 pixels, you will see a repetitive \ngradient. So it doesn't work for field-separated PAL content. \n\n\nSyntax and Parameters\n----------------------\n\n::\n    \n    FixLuminance (clip, int intercept, int slope)\n\n.. describe:: clip\n\n    Source clip; only YUY2 is supported.\n\n.. describe:: intercept\n\n    Bottom line at which to start correction. ``intercept`` should be equal to \n    or smaller than the height of the image. \n        \n.. describe:: slope\n\n    | Slope of correction function. The top of the picture is made darker by 1 \n      (on a 0-255 scale) every ``slope`` lines. \n    | Maximum darkening (at top line) = ``intercept`` / ``slope`` \n\n\nExamples\n--------\n\n* Progressively darken top lines:\n\n ::\n\n    ColorBars(width=512, height=480, pixel_type=\"YUY2\")\n    Crop(0, 0, 0, 256)\n    FixLuminance(100, 4)\n\n .. figure:: pictures/fixluminance-colorbars.png\n    :align: left\n\n    Line 99 is normal; line 0, the topmost line, is darker by 25 \n    (``intercept``/``slope`` = 100/4 = 25) \n\n* Make a *ramp* test image:\n\n ::\n\n    BlankClip(width=512, height=256, pixel_type=\"YUY2\", color_yuv=$FF8080)\n    FixLuminance(255, 1)\n\n .. figure:: pictures/fixluminance-ramp.png\n    :align: left\n\n$Date: 2022/02/08 22:44:06 $\n\n.. _discussion:\n    http://avisynth.nl/index.php/Talk:FixLuminance\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/flip.rst",
    "content": "\nFlipHorizontal / FlipVertical\n=============================\n\n**FlipHorizontal** flips (or mirrors) the video left to right.\n\n**FlipVertical** flips the video top to bottom.\n\n| It is useful for dealing with some video codecs which return an upside-down image.\n| It doesn't modify the interlaced :doc:`parity flags <parity>`. \n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    FlipHorizontal (clip)\n    FlipVertical (clip)\n\n.. describe:: clip\n\n    Source clip.\n\n.. note::\n    Using ``FlipHorizontal()`` followed by ``FlipVertical()`` is equivalent to \n    :doc:`Turn180() <turn>`.\n\n\nChangelog\n----------\n\n+----------------+----------------------------------------------------+\n| Version        | Changes                                            |\n+================+====================================================+\n| AviSynth 2.5.6 | RGB32 FlipHorizontal() code tweaked.               |\n+----------------+----------------------------------------------------+\n| AviSynth 2.5.3 | Fixed YUY2 FlipHorizontal giving garbage/crashing. |\n+----------------+----------------------------------------------------+\n| AviSynth 2.5.0 | Fliphorizontal implemented.                        |\n+----------------+----------------------------------------------------+\n\n$Date: 2022/02/05 22:44:06 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/fps.rst",
    "content": "===========\nFPS Filters\n===========\n\nA set of functions to change the frame rate of a clip:\n\n* `AssumeFPS`_ changes the frame rate without changing the frame count.\n* `AssumeScaledFPS`_ is similar to `AssumeFPS`_, but works by directly scaling\n  the frame rate numerator and denominator.\n* `ChangeFPS`_ changes the frame rate by deleting or duplicating frames.\n* `ConvertFPS`_ attempts to convert the frame rate without dropping or inserting\n  frames.\n\n\nAssumeFPS\n---------\nChanges the frame rate without changing the frame count, causing the video to\nplay faster or slower. **AssumeFPS** can be called 4 different ways, as\ndocumented below.\n\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    AssumeFPS (clip1, clip2, bool \"sync_audio\")\n    AssumeFPS (clip, float fps, bool \"sync_audio\")\n    AssumeFPS (clip, int numerator, int denominator, bool \"sync_audio\")\n    AssumeFPS (clip, string preset, bool \"sync_audio\")\n\n\n.. describe:: clip, clip1\n\n   Source clip; all color formats supported.\n\n.. describe:: clip2\n\n    If supplied, the new framerate is taken from this clip.\n\n.. describe:: fps\n\n    | If supplied, the new framerate is set to ``fps``.\n    | Due to the way frame rates are stored, ``fps`` must be converted to the\n      closest ratio of 32-bit signed integers, eg, 33.3333 → 329833/9895\n      (33.3332996)\n\n.. describe:: numerator, denominator\n\n    If supplied, the new framerate is set to ``numerator`` divided by\n    ``denominator``. If only the ``numerator`` is given, ``denominator`` defaults\n    to 1.\n\n.. describe:: preset\n\n    If supplied, the new framerate is taken from a set of standard rates,\n    as shown below:\n\n    +---------------------+-----------+-------------+-----------------+\n    |   preset            | numerator | denominator | approximate FPS |\n    +=====================+===========+=============+=================+\n    | \"ntsc_film\"         | 24000     | 1001        | 23.976          |\n    +---------------------+-----------+-------------+-----------------+\n    | \"ntsc_video\"        | 30000     | 1001        | 29.970          |\n    +---------------------+-----------+-------------+-----------------+\n    | \"ntsc_double\"       | 60000     | 1001        | 59.940          |\n    +---------------------+-----------+-------------+-----------------+\n    | \"ntsc_quad\"         | 120000    | 1001        | 119.880         |\n    +---------------------+-----------+-------------+-----------------+\n    | \"ntsc_round_film\"   | 2997      | 125         | 23.976          |\n    +---------------------+-----------+-------------+-----------------+\n    | \"ntsc_round_video\"  | 2997      | 100         | 29.97           |\n    +---------------------+-----------+-------------+-----------------+\n    | \"ntsc_round_double\" | 2997      | 50          | 59.94           |\n    +---------------------+-----------+-------------+-----------------+\n    | \"ntsc_round_quad\"   | 2997      | 25          | 119.88          |\n    +---------------------+-----------+-------------+-----------------+\n    | \"film\"              | 24        | 1           | 24.0            |\n    +---------------------+-----------+-------------+-----------------+\n    | \"pal_film\"          | 25        | 1           | 25.0            |\n    +---------------------+-----------+-------------+-----------------+\n    | \"pal_video\"         | 25        | 1           | 25.0            |\n    +---------------------+-----------+-------------+-----------------+\n    | \"pal_double\"        | 50        | 1           | 50.0            |\n    +---------------------+-----------+-------------+-----------------+\n    | \"pal_quad\"          | 100       | 1           | 100.0           |\n    +---------------------+-----------+-------------+-----------------+\n\n.. describe:: sync_audio\n\n    | If *true*, the audio sample rate is changed by the same amount; the pitch\n      of the resulting audio is shifted.\n    | If *false*, the audio is unchanged; this means the audio will lose\n      synchronization over time.\n\n    Default: false\n\nExamples\n^^^^^^^^\n\nPAL +4% conversion::\n\n    AVISource(\"FILM_clip.avi\") # Get 24fps clip\n    LanczosResize(768, 576)    # Resize to PAL square-pixel frame size.\n    AssumeFPS(25, 1, true)     # Convert frame rate to PAL, also adjust audio.\n    SSRC(44100)                # Restore audio sample rate to a standard rate.\n\n* The +4% speed up is conventionally used for displaying 24fps film on PAL\n  television. The slight increase in pitch and tempo is readily accepted by\n  viewers of PAL material.\n\nSlowing down of video (framerate of original video is 30 frames a second)::\n\n    AviSource(\"video.avi\")\n    AssumeFPS(10, true) # Slows the video down to a third of its speed\n\nSpeeding up of video (framerate of original video is 30 frames a second):\n\n::\n\n    AviSource(\"video.avi\")\n    AssumeFPS(60, true) # Double speed\n\nsync_audio experiments::\n\n    ColorBars() ## 29.97 fps\n    Trim(0, 299) ## vdur (video duration) = 10.01 sec\n    A = Tone().AudioTrim(0, -9.0) ## adur (audio duration) = 9.00 sec, sample rate=48000\n    AudioDub(A) ## vdur=10.01, adur=9.00\n    #return AssumeFPS(24, sync_audio=false) ## vdur=12.50, adur=9.00 (audio unchanged)\n    #return AssumeFPS(24, sync_audio=true)  ## vdur=12.50, adur=11.238, sample rate=38438\n    ## (audio sample rate is changed by the same amount - in this case, by 24.00/29.97)\n\n\n.. _AssumeScaledFPS:\n\nAssumeScaledFPS\n---------------\n\nScales the frame rate without changing the frame count, causing the video to\nplay faster or slower.\n\nIt is similar to `AssumeFPS`_, but works by directly scaling\n:doc:`FrameRateNumerator <../syntax/syntax_clip_properties>` and/or\n:doc:`FrameRateDenominator <../syntax/syntax_clip_properties>`.\n\nThe ``AssumeScaledFPS`` filter scales the frame rate without changing the\nframe count. The numerator is multiplied by the multiplier, the denominator\nis multiplied by the divisor, the resulting rational FPS fraction is\nnormalized, if either the resulting numerator or denominator exceed 31 bits\nthe result is rounded and scaled. This allows exact rational scaling to be\napplied to the FPS property of a clip.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    AssumeScaledFPS (clip, int \"multiplier\", int \"divisor\", bool \"sync_audio\")\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n.. describe:: multiplier\n\n    clip.FrameRateNumerator is multiplied by multiplier.\n\n.. describe:: divisor\n\n    clip.FrameRateDenominator is multiplied by divisor.\n\n.. describe:: sync_audio\n\n    | If *true*, the audio sample rate is changed by the same amount; the pitch\n      of the resulting audio is shifted.\n    | If *false*, the audio is unchanged; this means the audio will lose\n      synchronization over time.\n\n    Default: false\n\n.. _ChangeFPS:\n\nChangeFPS\n---------\nChanges the frame rate by deleting or duplicating frames.\n\nThe audio data are not touched by this filter. Audio will remain synchronized,\nalthough the length of the audio data may slightly differ from that of the video\ndata after the conversion. This is because the output can only contain an\ninteger number of frames. This effect will be more pronounced for shorter clips.\nThe difference in length can be ignored. **ChangeFPS** can be called 4 different\nways, as documented below.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    ChangeFPS (clip1, clip2, bool \"linear\")\n    ChangeFPS (clip, float fps, bool \"linear\")\n    ChangeFPS (clip, int numerator, int denominator, bool \"linear\")\n    ChangeFPS (clip, string preset, bool \"linear\")\n\n.. describe:: clip, clip1\n\n   Source clip; all color formats supported.\n\n.. describe:: clip2\n\n    If supplied, the new framerate is taken from this clip.\n\n.. describe:: fps\n\n    | If supplied, the new framerate is set to ``fps``.\n    | Due to the way frame rates are stored, ``fps`` must be converted to the\n      closest ratio of 32-bit signed integers, eg, 33.3333 → 329833/9895\n      (33.3332996)\n\n.. describe:: numerator, denominator\n\n    If supplied, the new framerate is set to ``numerator`` divided by\n    ``denominator``.  If only the ``numerator`` is given, ``denominator`` defaults\n    to 1.\n\n.. describe:: preset\n\n    If supplied, the new framerate is taken from a set of standard rates, as\n    listed under `AssumeFPS`_.\n\n.. describe:: linear\n\n    If *true* (the default), this will make AviSynth request frames in a linear\n    fashion when skipping frames.\n\n    Default: true\n\nExamples\n^^^^^^^^\n\nPAL->NTSC conversion::\n\n    AVISource(\"PAL_clip.avi\")              # Get clip\n    Bob(height=480)                        # Separate fields and interpolate them to full height.\n    BicubicResize(640,480)                 # Resize to NTSC square-pixel frame size.\n    ChangeFPS(60000, 1001)                 # Convert field rate to NTSC, by duplicating fields.\n    SeparateFields.SelectEvery(4,0,3)      # Undo Bob, even field first. Use SelectEvery(4,1,2) for odd field first.\n    Weave()                                # Finish undoing Bob.\n\nThe effect is similar to 3-2 telecine pull down. Regular viewers of PAL\nmaterial may notice a motion stutter that viewers of NTSC material readily\nignore as for telecined film.\n\n\n.. _ConvertFPS:\n\nConvertFPS\n----------\n\nAttempts to convert the frame rate without dropping or inserting frames,\nproviding a smooth conversion with results similar to those of standalone\nconverter boxes. The output will have (almost) the same duration as clip, but\nthe number of frames will change proportional to the ratio of target and source\nframe rates.\n\nFrame rate conversion is inherently difficult. This filter implements two common\nmethods used by commercial Prosumer-level converter systems. The results are\ntypically quite good. More sophisticated systems employ motion interpolation\nalgorithms, which are difficult to get right, but, if done right, do yield\nsuperior results.\n\nFootage converted with this filter should not be converted again. Blurriness\nbuilds up quickly in subsequent generations.\n\nThe audio data is not touched by this filter. Audio will remain synchronized,\nalthough the length of the audio data may slightly differ from that of the video\ndata after the conversion. This is because the output can only contain an integer\nnumber of frames. This effect will be more pronounced for shorter clips. The\ndifference in length should be ignored.\n\n**ConvertFPS** can be called 4 different ways, as documented below. Not all\nparameter values are checked for sanity.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    ConvertFPS (clip1, clip2, int \"zone\", int \"vbi\")\n    ConvertFPS (clip, float new_rate, int \"zone\", int \"vbi\")\n    ConvertFPS (clip, int numerator, int denominator, int \"zone\", int \"vbi\")\n    ConvertFPS (clip, string preset, int \"zone\", int \"vbi\")\n\n.. describe:: clip, clip1\n\n   Source clip; all color formats supported.\n\n.. describe:: clip2\n\n    If supplied, the new framerate is taken from this clip.\n\n.. describe:: new_rate\n\n    | Target frame rate. Can be integer or floating point number.\n    | In *Blend* mode, ``new_rate`` must be at least 2/3 (66.7%) of the source\n      frame rate, or an error will occur. This is to prevent frame skipping. If\n      you need to slow down the frame rate more than that, use Switch mode.\n    | Due to the way frame rates are stored, ``new_rate`` must be converted to\n      the closest ratio of 32-bit signed integers, eg, 33.3333 → 329833/9895\n      (33.3332996)\n\n.. describe:: numerator, denominator\n\n    If supplied, the new framerate is set to ``numerator`` divided by\n    ``denominator``. The same restrictions apply as for ``new_rate``.  If only\n    the ``numerator`` is given, ``denominator`` defaults to 1.\n\n.. describe:: preset\n\n    If supplied, the new framerate is taken from a set of standard rates, as\n    listed under `AssumeFPS`_.\n\n.. describe:: zone\n\n    If specified, puts the filter into *Switch* mode. Must be greater or equal\n    to zero. If zero, the filter will perform a hard switch, that is, it will\n    immediately display the next frame below the switch line. If greater than\n    zero, specifies the height (in lines) of the transition zone, where one\n    frame is gradually blended into the next. ``zone=80`` yields good results for\n    full-size video (480/576 active lines). The transition is done in the same\n    way as in :doc:`PeculiarBlend <peculiar>`. ``Zone`` must be less or equal\n    than the number of lines of the target frame that correspond to the duration\n    of the source frame. This is typically 5/6 or 6/5 of the target frame height,\n    that is, a few hundred lines. An error occurs if a larger value is chosen.\n\n.. describe:: vbi\n\n    If specified in *Switch* mode, specifies that the filter should apply a\n    timing correction for the vertical blanking interval (VBI). Integer number\n    greater than zero, indicating the height of the VBI of the target frames, in\n    lines. Typically ``vbi=49`` for PAL and ``vbi=45`` for NTSC, but these\n    values are not critical. Ignored in *Blend* mode.\n\nModes\n^^^^^\n\nThe filter has two operating modes. If the optional argument zone is not present,\nit will blend adjacent video frames, weighted by a blend factor proportional to\nthe frames' relative timing (Blend mode). If zone is present, it will switch\nfrom one video frame to the next (Switch mode) whenever a new source frame begins\n– usually somewhere in the middle of a target frame. Switch mode assumes that\nthe output will be shown on a TV where each frame is scanned from top to bottom.\nThe parameter zone specifies the height of the transition region in which the\ncurrent frame will be blended into the next.\n\n* **Blend** mode will cause visible, although slight, blurring of motion. This is a\n  typical artifact of frame rate conversion and can be seen on commercial video\n  tapes and TV programs as well. When working with interlaced video, it is\n  important to let the filter operate on individual fields, not on the interlaced\n  frames. (see Examples below.)\n* **Switch** mode is an attempt to avoid motion blurring, but comes at the expense\n  of slight flicker and motion artifacts. Horizontal and vertical pans may show\n  a slight wobble. Still frames from this conversion show \"broken\" or \"bent\"\n  vertical lines in moving scenes. Scene transitions may occur in the middle of\n  a frame. Nevertheless, the results do look less blurry than in Blend mode.\n\nNeither mode is perfect. Which one to choose depends on personal preference and\non the footage to be converted. Switch mode is probably only suitable if the\noutput will be shown on a TV, not on a computer screen.\n\nExamples\n^^^^^^^^\n\nNTSC->PAL conversion::\n\n    AviSource(\"NTSC_clip.avi\")             # Get clip\n    Bob(height=576)                        # Separate fields and interpolate them to full height.\n    BicubicResize(768,576)                 # Resize to PAL square-pixel frame size.\n    ConvertFPS(50)                         # Convert field rate to PAL, using Blend mode.\n    SeparateFields.SelectEvery(4,0,3)      # Undo Bob, even field first. Use SelectEvery(4,1,2) for odd field first.\n    Weave()                                # Finish undoing Bob.\n\nThis example will also work with frame-based NTSC material, even with telecined\nfilm (movies).\n\nFor film material, however, you will get better results by using an inverse-telecine\nfilter and speeding up the frame rate from 23.976 to 25fps.\n\nChangelog\n---------\n\n+-----------------+------------------------------------------------------------+\n| Version         | Changes                                                    |\n+=================+============================================================+\n| AviSynth+ r2632 | ConvertFPS: added 10-32bits support.                       |\n+-----------------+------------------------------------------------------------+\n| AviSynth 2.5.7  || AssumeFPS, ChangeFPS, ConvertFPS: added preset option.    |\n|                 || ConvertFPS: YV12 and RGB support and fixed blending ratio.|\n|                 || AssumeFPS, ChangeFPS, ConvertFPS: changed framerate       |\n|                 |  behaviour, see below.                                     |\n|                 |                                                            |\n|                 || From v2.57, the behaviour with respect to the framerateis |\n|                 |  a bit changed. The main issue is that users are allowed to|\n|                 |  specify the framerate as float, but the NTSC (FILM and    |\n|                 |  Video) and PAL standards require ratios as framerate.     |\n|                 |  Besides this AviSynth exports the framerate as a ratio, so|\n|                 |  when specifying a float, it will be converted to a ratio. |\n|                 |  The ratios of the standards are given by 24000/1001 for   |\n|                 |  23.976 (FILM) and 30000/1001 for 29.97(Video). When       |\n|                 |  specifying these floats, they are exported by AviSynth as |\n|                 |  ratios, but not as the standard ratios. One of the reasons|\n|                 |  for this is, that those floats are approximations         |\n|                 |  (remember that 24000/1001 = 23.9760239760...), so how     |\n|                 |  should AviSynth know how to choose the correct ratio? In  |\n|                 |  order to overcome this issue, the user can use            |\n|                 |  AssumeFPS(24000,1001) or simply AssumeFPS(\"ntsc_film\").   |\n|                 |                                                            |\n|                 || Another problem is that in v2.56 and older, the converted |\n|                 |  floats were exported with 64 bit precision, resulting in  |\n|                 |  very large numerators and denominators, making some       |\n|                 |  players crash. To overcome this, a smart float-ratio is   |\n|                 |  added internally, and the framerates are approximated     |\n|                 |  accurately by ratios of small numbers. For example,       |\n|                 |  AssumeFPS(23.976) is converted to AssumeFPS(2997, 125) as |\n|                 |  can be checked with :doc:`Info <info>`.                   |\n+-----------------+------------------------------------------------------------+\n| AviSynth 2.5.6  || ChangeFPS and ConvertFPS: added clip2 option.             |\n|                 || Added AssumeScaledFPS filter.                             |\n+-----------------+------------------------------------------------------------+\n| AviSynth 2.5.5  | AssumeFPS: added clip2 option.                             |\n+-----------------+------------------------------------------------------------+\n| AviSynth 2.5.4  | ChangeFPS: added linear=true/false option.                 |\n+-----------------+------------------------------------------------------------+\n| AviSynth 2.0.5  | ChangeFPS: Up to v2.05, the video gets truncated or filled |\n|                 | up to preserve playback speed and play time (the number of |\n|                 | frames was not changed). In later versions, the behaviour  |\n|                 | has been changed and the number of frames is increased or  |\n|                 | decreased as in ConvertFPS.                                |\n+-----------------+------------------------------------------------------------+\n\n$Date: 2022/07/30 14:45:27 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/freezeframe.rst",
    "content": "\nFreezeFrame\n===========\n\n**FreezeFrame** replaces all the frames between *first_frame* and *last_frame*\nwith a copy of *source_frame*. The sound track is not modified. This is useful\nfor covering up glitches in a video in cases where you have a similar\nglitch-free frame available.\n\n\nSyntax and Parameters\n^^^^^^^^^^^^^^^^^^^^^\n\n::\n\n    FreezeFrame (clip, int first_frame, int last_frame, int source_frame)\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n.. describe:: first_frame, last_frame\n\n    First and last frame to replace (inclusive).\n\n.. describe:: source_frame\n\n    Frame to copy. Note that frames are numbered starting from zero. If needed,\n    use :ref:`ShowFrameNumber` before **FreezeFrame** to make sure the right\n    frames are selected.\n\n\nExamples\n--------\n\nReplace frames 5 through 15 with frame 16::\n\n    FreezeFrame(5, 15, 16)\n\nReplace frames 1 through 20 with frame 10::\n\n    FreezeFrame(1, 20, 10)\n\nReplace all frames of a clip with the first frame::\n\n    FreezeFrame(0, FrameCount()-1, 0)\n\n    # Identical to Trim(0,-1).Loop(FrameCount(),0,0)\n    # Except FreezeFrame leaves the audio untouched\n\n\n$Date: 2022/03/02 22:44:06 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/getchannel.rst",
    "content": "==========\nGetChannel\n==========\n\nSet of filters to extract audio channels:\n\n* **GetChannel** returns one or more channels of a multichannel signal.\n* **GetLeftChannel** returns the left channel from a stereo signal, and\n  **GetRightChannel** returns the right.\n* **GetChannels** is an alias for **GetChannel** and can be used interchangeably.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    GetChannel (clip, int ch1 [, int ch2, ...])\n    GetChannels (clip, int ch1 [, int ch2, ...])\n\n    GetLeftChannel(clip clip)\n    GetRightChannel(clip clip)\n\n.. describe:: clip\n\n    Source clip; all audio sample types supported.\n\n.. describe:: ch1, ch2, ...\n\n    Specify what channel(s) to return.\n\n    The ordering of the channels is determined by the ordering of the input\n    file, because AviSynth doesn't assume any ordering (see `Remarks`_).\n\n    In case of WAV files, the ordering should be as follows:\n\n    +-----------------------------------+\n    | WAV, 2 channels (stereo)          |\n    +===+===============================+\n    | 1 | left channel                  |\n    +---+-------------------------------+\n    | 2 | right channel                 |\n    +---+-------------------------------+\n\n    +-----------------------------------+\n    | WAV, 5.1 channels                 |\n    +===+===============================+\n    | 1 | front left channel            |\n    +---+-------------------------------+\n    | 2 | front right channel           |\n    +---+-------------------------------+\n    | 3 | front center channel          |\n    +---+-------------------------------+\n    | 4 | LFE (Subwoofer)               |\n    +---+-------------------------------+\n    | 5 | rear left channel             |\n    +---+-------------------------------+\n    | 6 | rear right channel            |\n    +---+-------------------------------+\n\nRemarks\n^^^^^^^\n\nEvery file format has a different internal channel ordering. The following table\ngives this internal ordering for some formats (useful for plugin writers), but\nit is the decoder's task to return the expected channel order. If you use\ndecoders like `NicAudio`_/\\ `BassAudio`_ or `ffdshow`_/\\ `AC3Filter`_ you don't\nneed to worry about this.\n\n    +-------------+--------------+--------------+--------------+-------------+------------+------------+\n    | Format      | Channel 1    | Channel 2    | Channel 3    | Channel 4   | Channel 5  | Channel 6  |\n    +=============+==============+==============+==============+=============+============+============+\n    | `5.1 WAV`_  | front left   | front right  | front center | LFE         | rear left  | rear right |\n    +-------------+--------------+--------------+--------------+-------------+------------+------------+\n    | `5.1 AC3`_  | front left   | front center | front right  | rear left   | rear right | LFE        |\n    +-------------+--------------+--------------+--------------+-------------+------------+------------+\n    | `5.1 DTS`_\\*| front center | front left   | front right  | rear left   | rear right | LFE        |\n    +-------------+--------------+--------------+--------------+-------------+------------+------------+\n    | `5.1 AAC`_\\*| front center | front left   | front right  | rear left   | rear right | LFE        |\n    +-------------+--------------+--------------+--------------+-------------+------------+------------+\n    | `5.1 AIFF`_ | front left   | rear left    | front center | front right | rear right | LFE        |\n    +-------------+--------------+--------------+--------------+-------------+------------+------------+\n    | `5.1 FLAC`_ | front left   | front right  | front center | LFE         | rear left  | rear right |\n    +-------------+--------------+--------------+--------------+-------------+------------+------------+\n    | `5.1 WMA`_  | front left   | front right  | front center | LFE         | rear left  | rear right |\n    +-------------+--------------+--------------+--------------+-------------+------------+------------+\n    || [1] 5.1 DTS: the LFE is on a separate stream (much like on multichannel MPEG2).                 |\n    || [2] There is no free version of the AAC specification available online.                         |\n    +--------------------------------------------------------------------------------------------------+\n\n\nExamples\n--------\n\n* Get mono audio from left channel of a WAV file, and dub to video from AVI::\n\n    video = AviSource(\"c:\\video.avi\")\n    stereo = WavSource(\"c:\\audio2ch.wav\")\n    mono = GetLeftChannel(stereo)\n    return AudioDub(video, mono)\n\n* Do the same, alternate syntax::\n\n    video = AviSource(\"c:\\video.avi\")\n    stereo = WavSource(\"c:\\audio2ch.wav\")\n    mono = GetChannel(stereo, 1)\n    return AudioDub(video, mono)\n\n* Do the same with the audio channels from the AVI file itself::\n\n    video = AviSource(\"c:\\video+audio2ch.avi\")\n    return GetChannel(video, 1)\n\n* | Convert AVI with 5.1 audio to stereo (copy *front left* and *front right*)\n  | (But see `Remarks`_ for channel ordering, and examples below and `here`_ for\n    more complex downmix functions.)\n\n  ::\n\n    video = AviSource(\"c:\\video+audio6ch.avi\")\n    stereo = GetChannel(video, 1, 2)\n    return AudioDub(video, stereo)\n\n* Get *front left* and *front right* audio from a 5.1 AVI::\n\n    video = AviSource(\"c:\\video+audio6ch.avi\")\n    audio = WavSource(\"c:\\video+audio6ch.avi\")\n    stereo = GetChannel(audio, 1, 2)\n    return AudioDub(video, stereo)\n\n* | Mix 5.1 to stereo - see `discussion here`_.\n  | Note returned audio has sample type `Float`_.\n  | :doc:`Normalize <normalize>` is recommended before\n    :doc:`converting to 16-bit <convertaudio>` to avoid possible overload.\n\n  ::\n\n    AviSource(\"c:\\video+audio6ch.avi\")\n    DownMix()\n    Normalize()\n    ConvertAudioTo16bit()\n    return Last\n\n    function DownMix(clip a, float \"centergain\", float \"surroundgain\")\n    {\n        a.ConvertAudioToFloat()\n\n        ## 5.1 WAV channel layout:\n        fl = GetChannel(1)\n        fr = GetChannel(2)\n        fc = GetChannel(3)\n        lf = GetChannel(4) ## (LFE not used)\n        sl = GetChannel(5)\n        sr = GetChannel(6)\n\n        ## add center\n        gc = Default(centergain, 1.0) * 0.7071\n        fl = MixAudio(fl, fc, 1.0, gc)\n        fr = MixAudio(fr, fc, 1.0, gc)\n\n        ## add surround\n        gs = Default(surroundgain, 1.0) * 0.7071\n        fl = MixAudio(fl, sl, 1.0, gs)\n        fr = MixAudio(fr, sr, 1.0, gs)\n\n        return AudioDub(a, MergeChannels(fl, fr))\n    }\n\n\nChangelog\n----------\n\n+-----------------+---------------------------------------------------+\n| Version         | Changes                                           |\n+=================+===================================================+\n| AviSynth 2.5.0  | Added GetChannel and GetChannels filters.         |\n+-----------------+---------------------------------------------------+\n| AviSynth 2.0.3  | Added GetLeftChannel and GetRightChannel filters. |\n+-----------------+---------------------------------------------------+\n\n$Date: 2022/03/05 18:47:07 $\n\n.. _5.1 WAV:\n    https://web.archive.org/web/20210117100754/http://www.cs.bath.ac.uk/~jpff/NOS-DREAM/researchdev/wave-ex/wave_ex.html\n.. _5.1 AC3:\n    https://web.archive.org/web/20060212130915/http://www.atsc.org:80/standards/a_52a.pdf\n.. _5.1 DTS:\n    https://web.archive.org/web/20060909033736/http://webapp.etsi.org:80/action/PU/20020827/ts_102114v010101p.pdf\n.. _5.1 AAC:\n    https://web.archive.org/web/20080213040722/http://www.hydrogenaudio.org/forums/index.php?showtopic=10986\n.. _5.1 AIFF:\n    https://web.archive.org/web/20030817071619/http://preserve.harvard.edu/standards/Audio%20IFF%20Specification%201%203.pdf/\n.. _5.1 FLAC:\n    http://flac.sourceforge.net/format.html\n.. _5.1 WMA:\n    http://lists.mplayerhq.hu/pipermail/mplayer-users/2006-October/063511.html\n.. _NicAudio:\n    http://avisynth.nl/index.php/NicAudio\n.. _BassAudio:\n    http://avisynth.nl/index.php/BassAudio\n.. _ffdshow:\n    http://avisynth.nl/index.php/Ffdshow\n.. _AC3Filter:\n    https://web.archive.org/web/20200128173805/http://www.ac3filter.net/wiki/AC3Filter\n.. _here:\n    https://forum.doom9.org/showthread.php?p=1243880#post1243880\n.. _discussion here:\n    https://forum.doom9.org/showthread.php?p=1735072#post1735072\n.. _Float:\n    http://avisynth.nl/index.php/Float\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/greyscale.rst",
    "content": "=========\nGreyscale\n=========\n\nConverts the input clip to greyscale (no color), without changing the color format.\nFor RGB, the resulting clip will consist of 3 identical channels. For YUV, the\nluma channel is left as is and the chroma channels are set to grey (neutral).\n\nUK (Greyscale) and US (Grayscale) spellings are both allowed.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    Greyscale (clip  string \"matrix\")\n    Grayscale (clip, string \"matrix\")\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n.. describe:: matrix\n\n    In RGB based formats, the conversion produces the luma using the coefficients\n    given in the ``matrix`` parameter.\n\n    * \"Rec601\" : use `Rec.601`_ coefficients (and keeping luma range unchanged)\n    * \"Rec709\" : use `Rec.709`_ (HD) coefficients (and keeping luma range unchanged)\n    * \"Rec2020\" : use `Rec.2020`_ (UHD) coefficients (and keeping luma range unchanged)\n    * \"AVERAGE\" : use averaged coefficients (Y = (R + G + B) / 3)\n\n    Default: \"Rec601\"\n\n    See :doc:`Color conversions <../advancedtopics/color_conversions>` for an\n    explanation of the coefficients. Broadly speaking though,\n\n    * using ``\"Rec709\"``, **green** contributes more to the output, compared to\n      ``\"Rec2020\"`` or the default ``\"Rec601\"``;\n    * using ``\"Average\"``, **blue** contributes more.\n\n    If the source clip is `YUV`_, the chroma channels are simply set to neutral\n    (e.g. 128 for 8-bit clips) – ``matrix`` is not used and **must not be**\n    specified otherwise an error will be thrown.\n\n    In all cases, luma range is not changed. In other words, **Greyscale** does\n    not do any range conversion, meaning if the source is full range, the output\n    will also be full range. The same applies to limited range.\n\n\nExamples\n--------\n\nFor YUV clips, ``Greyscale()`` is identical to:\n\n.. code-block:: swift\n\n    /* assume a YUV(A) clip as the source */\n    src = last\n    csp = BuildPixelType(sample_clip=src)\n    ShowY(pixel_type=csp)\n\nFor RGB clips, ``Greyscale(matrix=\"Rec601\")`` is identical to:\n\n.. code-block:: swift\n\n    /* assume an RGB(A) clip as the source */\n    src = last\n    compat = IsInterleaved(src) ? true : false\n    csp = BuildPixelType(compat=compat, sample_clip=src)\n    ConvertToY(matrix=\"PC.601\") /* or \"PC.709\" \"PC.2020\", \"Average\" */\n    ShowY(pixel_type=csp)\n    HasAlpha(src) ? AddAlphaPlane(last, src) : last\n\n\nChangelog\n----------\n\n+------------------+--------------------------------------------------------------------+\n| Version          | Changes                                                            |\n+==================+====================================================================+\n| AviSynth+ 3.7.2  | Greyscale to not convert to limited range when RGB. Regression in  |\n|                  | 3.7.1. Issue `#257`_.                                              |\n+------------------+--------------------------------------------------------------------+\n| AviSynth+ r2728  | Greyscale: zero-centered 32bit chroma support.                     |\n+------------------+--------------------------------------------------------------------+\n| AviSynth+ r2487  || Add new matrix: \"Rec2020\".                                        |\n|                  || Add support for RGB64, PlanarRGB(A), and remaining 10-12-14 bit   |\n|                  |  YUV(A) formats.                                                   |\n+------------------+--------------------------------------------------------------------+\n| AviSynth+ r2003  | Added 16 and 32 bit YUV(A) support.                                |\n+------------------+--------------------------------------------------------------------+\n| AviSynth 2.6.0   | Added support for Y8, YV16, YV24 and YV411 formats.                |\n+------------------+--------------------------------------------------------------------+\n| AviSynth 2.5.7   | Greyscale RGB now accepts \"Rec601\" as a valid matrix.              |\n+------------------+--------------------------------------------------------------------+\n| AviSynth 2.5.6   | Added ``matrix`` parameter, Greyscale RGB now supports \"Rec709\"    |\n|                  | and \"Average\" matrices.                                            |\n+------------------+--------------------------------------------------------------------+\n\n$Date: 2022/04/29 13:57:17 $\n\n.. _Rec.601:\n    https://en.wikipedia.org/wiki/Rec._601\n.. _Rec.709:\n    https://en.wikipedia.org/wiki/Rec._709\n.. _Rec.2020:\n    https://en.wikipedia.org/wiki/Rec._2020\n.. _YUV:\n    http://avisynth.nl/index.php/YUV\n.. _#257:\n    https://github.com/AviSynth/AviSynthPlus/issues/257\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/histogram.rst",
    "content": "Histogram\n=========\nA multipurpose audio/video analysis tool.\n\nSyntax and Parameters\n----------------------\n::\n\n    Histogram (clip, string \"mode\", float \"factor\", int \"bits\", bool \"keepsource\", bool \"markers\",\n    string \"matrix\", \n    string \"graticule\", bool \"targets\", bool \"axes\", bool \"iq\", bool \"iq_lines\", bool \"circle\", \n    bool \"targets100\")\n\n.. describe:: clip\n\n    Source clip; bit depths greater than 8 are supported in Classic, Levels,\n    Luma and Colors modes only.\n\n    * Classic, Color, Color2 and Luma modes support all planar YUV(A) formats.\n    * Levels mode support RGB24/32/48/64 and all planar RGB(A)/YUV(A) formats.\n    * Audiolevels and StereoOverlay modes support all 8-bit YUV(A) formats.\n    * Stereo and StereoY8 accept any 8-bit format but always return a 512x512\n      YUV420P8 or a Y8 clip respectively. If only an audio clip is given then\n      the output clip will have a framerate of 25FPS.\n    * Audiolevels and Stereo* modes support all audio samples types.\n\n.. describe:: mode\n\n    Select the ``mode`` to display:\n\n    * :ref:`\"Classic\" <histogram-classic>` : waveform mode;\n    * :ref:`\"Levels\" <histogram-levels>` : RGB/YUV/Y histogram mode;\n    * :ref:`\"Color\" <histogram-color>` : vectorscope mode;\n    * :ref:`\"Color2\" <histogram-color2>` : vectorscope mode with overlays;\n    * :ref:`\"Luma\" <histogram-luma>` : special viewing mode;\n    * :ref:`\"Audiolevels\" <histogram-audiolevels>` : audio level meter; and\n    * :ref:`\"Stereo\", \"StereoOverlay\", \"StereoY8\" <histogram-stereo>` : audio graphs.\n\n    Default: \"classic\"\n\n.. describe:: factor\n\n    Applies only to Levels mode.\n    The ``factor`` option specifies the way how the graphs are displayed,\n    exaggerating the vertical scale. It is specified as percentage of the total\n    population (that is number of luma or chroma pixels in a frame). For example,\n    ``Histogram(\"Levels\", 1.5625)`` will achieve a 1/64th cap. The vertical scale\n    is multiplied by 100.0 / ``factor``.\n\n    | Range: 0.0 - 100.0\n    | Default: 100.0\n\n.. describe:: bits\n\n    Accepts 8, 9, 10, 11 or 12 as input. Applies only to Classic, Levels and\n    Color/Color2 (vectorscope) modes.\n\n    * Classic, Levels: increases the width of the histogram by 2\\ :sup:`(bits-8)`\n    * Color/Color2: increases width and height of the histogram by 2\\ :sup:`(bits-8)`\n\n    For example, ``Histogram(bits=10)`` returns a 1024-pixel wide histogram\n    (width is 256 by default).\n\n    Default: 8\n\n.. describe:: keepsource\n\n    If true, add histogram to right side of existing clip; else return the\n    histogram portion only. Applies only to Classic, Levels, Color and Color2 modes.\n\n    Default: true\n\n.. describe:: markers\n\n    If true, show calibration marks (see screenshots); else hide them.\n    For Levels mode it will also remove the colored background. Applies only to\n    Classic and Levels modes.\n\n    Default: true\n\n.. describe:: matrix\n\n    Applies to Color/Color2 mode. Specifies the YUV matrix used to interpret the\n    chroma values of the input clip, and determines the correct U/V positions of\n    the color bar target boxes and I/Q markers drawn on the vectorscope.\n\n    Accepted values follow the same convention as the ``ConvertToYUV`` family of\n    functions, for example: ``\"2020\"``, ``\"709\"``, etc..\n\n    If not specified, the matrix is read from the clip's ``_Matrix`` and\n    ``_ColorRange`` frame properties. If those are absent, BT.601 is assumed.\n\n    Default: (empty, means auto from frame properties or else BT.601)\n\n.. describe:: graticule\n\n    Applies only to Color and Color2 modes. Controls the visibility of the\n    graticule overlay — the valid chroma range boundary square (16–240 in 8-bit,\n    scaled for higher bit depths) in Color2 mode, and the danger zone shading in\n    Color mode.\n\n    * ``\"on\"`` (default): Always draw the graticule, regardless of the clip's\n      color range. This preserves the behavior of versions prior to 3.7.6.\n    * ``\"off\"``: Never draw the graticule.\n    * ``\"auto\"``: Draw the graticule only for limited-range clips. For full-range\n      clips, where the valid chroma area extends to the display edges, the\n      graticule is suppressed to avoid clutter.\n\n    Default: ``\"on\"``\n\n\n.. describe:: targets\n\n    Applies only to Color and Color2 modes. If true, draw small target boxes\n    on the vectorscope at the expected Cb/Cr positions of the six 75%-amplitude\n    colour bar colours (Yellow, Cyan, Green, Magenta, Red, Blue). The positions\n    are computed from ground-truth linear RGB values converted through the active\n    ``matrix``, and the limited or full range property of the clip, giving\n    accurate targets for any supported matrix and bit depth.\n\n    The target positions correspond to the 75% signal level as used by\n    :doc:`ColorBars <colorbars>` and :doc:`ColorBarsHD <colorbars>`. They are\n    also the correct reference positions for :doc:`ColorBarsUHD <colorbarsuhd>`\n    content after SDR conversion, since the three test patterns share the same\n    scene light level at their respective reference amplitudes:\n\n    * **ColorBarsHD** 75% bars → land on 75% targets directly.\n    * **ColorBarsUHD HLG** (mode=0) 75% BT.709-equivalent bars → land on 75%\n      targets after scene-referred HLG→SDR conversion (ITU Fig. 10).\n    * **ColorBarsUHD PQ** (mode=1) 58% BT.709-equivalent bars → land on 75%\n      targets after scene-referred PQ→SDR conversion at 1000 cd/m² reference,\n      because the 58% PQ signal level corresponds to the same scene light as\n      75% HLG at the 1000 cd/m² reference (203 cd/m² diffuse white).\n\n    For the **HLG/PQ source signal** (before SDR conversion), convert to YUV\n    first and set ``matrix`` to ``\"709\"`` (or ``\"2020\"`` all the same, drawing is\n    matrix-aware) to see the BT.709-equivalent bottom bars land on 75% targets::\n\n        src = ColorBarsUHD(pixel_type=\"RGBP10\", mode=0)\n        src.ConvertToYUV444(matrix=\"709:same\").Histogram(\"color2\", targets=true)\n\n    Default: false\n\n.. describe:: targets100\n\n    Applies only to Color and Color2 modes. If true, draw small target boxes\n    on the vectorscope at the expected Cb/Cr positions of the six **100%**-amplitude\n    colour bar colours. The positions are computed from the same ground-truth\n    linear RGB primaries as ``targets``, scaled to full saturation (100% signal\n    level), using the active ``matrix`` and colour range.\n\n    These targets are useful for validating HDR-to-SDR conversions where HDR\n    primary colour bars exceed the SDR gamut and are hard-clipped. Specifically,\n    after a **scene-referred** HLG→SDR or PQ→SDR conversion, the 75% HLG and\n    58% PQ primary colour bars (Row 2 of ColorBarsUHD) clip to exactly 100% SDR\n    amplitude and should land on these targets:\n\n    * fmtconv scene-referred: bars land **exactly** on the 100% targets —\n      confirming high numerical precision of the analytical conversion path.\n    * zimg/avsresize scene-referred (as of 20260317 patch needed): bars land \n      approximately on the 100% targets with small scatter — due to LUT quantisation \n      in the per-channel gamma path.\n    * Display-referred conversion: bars land approximately near the 100% targets\n      but with visible scatter between bars of the same hue group, because the\n      luminance-weighted OOTF scales each bar by a different factor depending on\n      its luminance content. This scatter is physically correct and expected —\n      the BT.709-equivalent bars were designed to hit targets for scene-referred\n      conversion only (per ITU-R BT.2111-3 Attachment 3).\n\n    Default: false\n\n    See also :ref:`ColorbarsUHD vectorscope example <ColorBarsUHD_vectorscope_example>`\n\n\n.. describe:: axes\n\n    Applies only to Color and Color2 modes. If true, draw horizontal and vertical crosshair\n    lines through the center of the vectorscope, marking the U (Cb) and V (Cr)\n    axes.\n\n    Default: false\n\n.. describe:: iq\n\n    Applies only to Color and Color2 modes. If true, draw target boxes for the NTSC −I, and\n    +Q (ColorBars) and +I (ColorBarsHD) chroma-phase reference signals. These are \n    defined by the luma-corrected broadcast convention (Option 2 below) and are \n    computed through the active ``matrix``. \n\n    The −I and +Q signals are traditionally zero-luma, 20 IRE saturation chroma\n    axis references from the NTSC subcarrier standard. Three interpretations exist\n    in digital studio-swing environments:\n\n    For displaying them on RGB or YUV, \"hack\" is needed to reach valid RGB/YUV values, \n    for more information see ColorBars documentation.\n\n    Default: false\n\n.. describe:: iq_lines\n\n    Applies only to Color and Color2 modes. If true, draw radial lines on the vectorscope\n    passing through the −I/+I and +Q/−Q axis positions. Together with ``axes``,\n    this produces the full eight-line graticule (four cardinal lines at 0°/90°/\n    180°/270° and four diagonal lines through the I/Q phase references) commonly\n    seen on broadcast vectorscopes.\n\n    The diagonal line angles are not derived from the actual computed I/Q U/V\n    positions, and use always textbook values of 33°/123°.\n\n    Default: false\n\n.. describe:: circle\n\n    Applies only to Color and Color2 modes. If true (default for color2), draws \n    hue circle with 15° tick marks around the circumference.\n\n    Default: true (\"color2\"), false (\"Color\")\n\n.. _histogram-classic:\n\nClassic mode\n------------\n\n.. figure:: pictures/histogram-classic.png\n   :align: left\n\nThis will add a per-line luminance graph (called a `Waveform Monitor`_) on the\nright side of the video. The left side of the graph represents the minimum pixel\nvalue (0) and the right side represents the maximum pixel value (for example,\n255 for 8-bit). Values outside the valid  :doc:`CCIR-601 <limiter>` range are\nshown in a brown/yellow-ish color, and a greenish line represents the midpoint\nfor limited range (e.g. 126 for 8-bit since the median of [16,235] is 125.5).\n\n|clearfloat|\n\n.. _histogram-levels:\n\nLevels mode\n-----------\n\n.. figure:: pictures/histogram-levels-rgb.png\n   :align: left\n\n.. figure:: pictures/histogram-levels-yuv.png\n   :align: left\n\nThis mode will display three `histograms`_ on the right side of the video frame.\nThis will show the distribution of the R,G,B or Y,U,V components in the current\nframe.\n\nThe top graph displays the luma (R) or red (Y) distribution of the frame, where\nthe left side represents the minimum pixel value (0) and the right side\nrepresents the maximum pixel value (for example, 255 for 8-bit). For YUV, the\nvalid :doc:`CCIR-601 <limiter>` range has been indicated by a slightly different\ncolor. The midpoint is marked with a dotted line (for example, 128 for 8-bit).\nThe vertical axis shows the number of pixels for a given luma (Y) value. The\nmiddle graph is similar and displays the G or U component, and the bottom graph\ndisplays the B or V component.\n\n|clearfloat|\n\n.. _histogram-color:\n\nColor mode\n----------\n\n.. figure:: pictures/histogram-color.png\n   :align: left\n\nThis mode displays the chroma values (U/V color placement) in a two-dimensional\ngraph called a `vectorscope`_, appended to the right side of the video frame.\nIt functions as a histogram at the same time: the whiter a pixel in the\nvectorscope, the more pixels of the input clip share that chroma value. The\nshaded background denotes the valid :doc:`CCIR-601 <limiter>` range (danger zone\nshading can be controlled with the ``graticule`` parameter).\n\n.. figure:: pictures/histogram-color-labeled.png\n   :align: left\n\nLabels have been added to the second image for reference, showing the U and V\naxes and degrees of hue. Spots show 75% saturated :doc:`ColorBars <colorbars>`\n(clockwise from 0°: blue, magenta, red, yellow, green and cyan).\n\nThe U component is displayed on the horizontal (X) axis (left = 0, right = 255)\nand the V component on the vertical (Y) axis (top = 0, bottom = 255).\n\nA spot's position on the scope corresponds to a chroma value from the input\nclip. As hue changes, the spot moves around the center; as saturation changes,\nit moves in or out. The center (U=V=128) represents zero saturation — no color.\nAt U=255, V=128 the hue is zero (blue) at maximum saturation:\nsaturation = sqrt( (U-128)\\ :sup:`2` + (V-128)\\ :sup:`2` ) = 127.\nTurning hue clockwise 90° gives U=128, V=255 (red, approximately). Decreasing\nsaturation at constant hue moves the spot toward the center, fading the color\nto :doc:`greyscale <greyscale>`.\n\n|clearfloat|\n\n.. _histogram-color2:\n\nColor2 mode\n-----------\n\n.. figure:: pictures/histogram-color2.png\n   :align: left\n\nThis mode displays pixels in a two-dimensional `vectorscope`_ appended to the\nright side of the video frame. It can be used to read the `hue`_ and\n`saturation`_ of a clip.\n\nThe U and V axes are laid out identically to **Color** mode (see above).\nThe grey square (graticule) denotes the valid limited-range Cb/Cr boundary\n(16–240 in 8-bit; see also :doc:`CCIR-601 <limiter>`).\n\n.. figure:: pictures/histogram-color2-labeled.png\n   :align: left\n\nAs in **Color** mode, labels and :doc:`ColorBars <colorbars>` dots have been\nadded to the second image for reference.\n\nUnlike **Color** mode, the background is black rather than shaded, the signal\ndots are brighter and rendered in color, and a color wheel is drawn around the\ncircumference of the scope divided into six hues (clockwise from 0°: blue,\nmagenta, red, yellow, green and cyan) with white tick marks at 15° intervals.\n\n|clearfloat|\n\n.. _histogram-vectorscope-overlays:\n\nVectorscope overlays: Color and Color2\n---------------------------------------\n\nBoth **Color** and **Color2** modes share a common set of optional overlays.\nThe fundamental difference between the two modes is that **Color** operates as\na density histogram plotted over a pre-drawn UV shade background, while\n**Color2** plots individual pixels on a black background with a color wheel.\n\nBoth modes are matrix-aware: the ``matrix`` parameter (or the clip's ``_Matrix``\nand ``_ColorRange`` frame properties) controls how chroma values are interpreted\nand where overlay markers are positioned, giving accurate results for BT.601,\nBT.709, BT.2020 and other supported matrices at all bit depths.\n\n**Optional overlays:**\n\n+-------------+-------------------+-------------------+------------------------------------------+\n| Parameter   | Color default     | Color2 default    | Description                              |\n+=============+===================+===================+==========================================+\n| graticule   | ``\"on\"``          | ``\"on\"``          | Danger zone shading (Color) or valid     |\n|             |                   |                   | chroma boundary square (Color2).         |\n|             |                   |                   | ``\"on\"`` / ``\"off\"`` / ``\"auto\"``        |\n|             |                   |                   | (auto: limited-range only).              |\n+-------------+-------------------+-------------------+------------------------------------------+\n| targets     | false             | false             | Target boxes at the six 75% colour bar   |\n|             |                   |                   | Cb/Cr positions. Matrix-aware. Useful    |\n|             |                   |                   | for ColorBars, ColorBarsHD, and          |\n|             |                   |                   | ColorBarsUHD after SDR conversion.       |\n+-------------+-------------------+-------------------+------------------------------------------+\n| targets100  | false             | false             | Target boxes at the six 100% colour bar  |\n|             |                   |                   | Cb/Cr positions. Matrix-aware. Useful    |\n|             |                   |                   | for validating HDR primary bars after    |\n|             |                   |                   | SDR conversion where HLG/PQ primaries    |\n|             |                   |                   | clip to 100% SDR amplitude.              |\n+-------------+-------------------+-------------------+------------------------------------------+\n| axes        | false             | false             | Horizontal and vertical crosshair        |\n|             |                   |                   | through the scope center.                |\n+-------------+-------------------+-------------------+------------------------------------------+\n| iq          | false             | false             | Target boxes for the NTSC −I, +I         |\n|             |                   |                   | and +Q phase references.                 |\n+-------------+-------------------+-------------------+------------------------------------------+\n| iq_lines    | false             | false             | Radial lines at the fixed 33°/123°       |\n|             |                   |                   | NTSC I/Q phase angles.                   |\n+-------------+-------------------+-------------------+------------------------------------------+\n| circle      | false             | true              | Hue circle with 15° tick marks around    |\n|             |                   |                   | the circumference.                       |\n+-------------+-------------------+-------------------+------------------------------------------+\n\n**Example usage**::\n\n    # ColorBars / ColorBarsHD: 75% targets with BT.601/BT.709 auto-detected\n    ColorBars()\n    Histogram(\"color2\", targets=true, axes=true, iq=true, iq_lines=true)\n\n    # ColorBarsHD with explicit BT.709 matrix\n    # Here unnecessary, \"color2\" knows it from frame properties set to 709,limited\n    ColorBarsHD()\n    Histogram(\"color2\", targets=true, matrix=\"709:l\")\n\n    # ColorBarsUHD HLG source: view in BT.2020 Cb/Cr space\n    # BT.709-equivalent bottom bars land on BT.2020 75% targets\n    ColorBarsUHD(pixel_type=\"RGBP10\", mode=0)\n    Histogram(\"color2\", targets=true, targets100=true)\n\n    # ColorBarsUHD HLG after scene-referred SDR conversion:\n    # 75% HLG primary bars clip to 100% SDR → use targets100\n    # BT.709-equivalent bottom bars land on 75% targets → use targets\n    z_ConvertFormat(last, pixel_type=\"RGBP10\",\n        \\ colorspace_op=\"auto:auto:auto:l=>rgb:709:709:l\",\n        \\ nominal_luminance=203.15, use_props=1,\n        \\ approximate_gamma=false, scene_referred=true)\n    ConvertToYUV444(matrix=\"709:same\")\n    Histogram(\"color2\", targets=true, targets100=true)\n\n    # Override matrix interpretation to BT.709 for an SD clip tagged as 601\n    Histogram(\"color2\", matrix=\"709\", targets=true, iq=true)\n\n    # Suppress the graticule only for full-range clips\n    Histogram(\"color2\", graticule=\"auto\")\n\n    # Switch on all overlays in Color mode\n    Histogram(\"color\", graticule=\"on\", targets=true, targets100=true,\n        \\ axes=true, iq=true, iq_lines=true, circle=true)\n\nSee also\n:ref:`ColorbarsUHD vectorscope example <ColorBarsUHD_vectorscope_example>`\n\n|clearfloat|\n\n.. _histogram-luma:\n\nLuma mode\n---------\n\n.. figure:: pictures/histogram_modeluma-crop.jpg\n   :align: left\n\nThis mode will amplify luminance, and display very small luminance\nvariations. This is good for detecting blocking and noise, and can be helpful\nat adjusting filter parameters. In this mode a 1-pixel luminance difference\nwill show as a 16-pixel luminance pixel, thus seriously enhancing small\nflaws.\n\n|clearfloat|\n\n.. _histogram-stereo:\n\nStereo, StereoY8 and StereoOverlay mode\n---------------------------------------\n\n.. figure:: pictures/histogram-stereo.png\n   :align: left\n\nThis mode shows a stereo graph (known as a `goniometer`_ or phase scope), from\nthe audio in the clip. This can be used to see the left-right and phase\ndistribution of the input signal. Each frame will contain only information from\nthe current frame to the beginning of the next frame. The signal is linearly\nupsampled 8x, to provide clearer visuals. Only **StereoOverlay** will overlay\nthe graph on top of the source clip. **Stereo** and **StereoY8** just return a\n512x512 clip of the graph.\n\n|clearfloat|\n\n.. _histogram-audiolevels:\n\nAudioLevels mode\n----------------\n\n.. figure:: pictures/histogram-audiolevels.png\n   :align: left\n\nShows the audio levels in `decibels`_ for each channel present. For example, if\nthe source has six channels of audio, six vertical bars will be shown. The audio\nlevels are overlaid over the source clip.\n\nThe green bars show the *RMS* level and the blue bars show the *max* (peak)\nlevel, both are calculated with the formulas listed below. The color of the bar\nchanges color to red and yellow whenever that specific channel's peak reaches\n0.0dB.\n\n|clearfloat|\n\n**Formulas**\n\nThe green bars show the *RMS* (`Root Mean Square`_) level of the audio in each\nvideo frame (let's say *n* samples) using the following formula:\n\n.. math::  RMS = 20 * \\log_{10}(1 / 32768 * \\sqrt{1/n * \\sum_{j=1}^n sample(j)^2})\n\nThe blue bars show the *max* (peak) level of the audio in each video frame\nusing the following formula:\n\n.. math:: max = 20 * \\log_{10}(max_{\\text{j}}(sample(j))/32768)\n\nThe maximum possible level without `clipping`_ is 0 dB by definition. The\nminimum level for 16 bit audio is therefore:\n\n.. math:: 20 * \\log_{10}(1/32768) = -90.31 dB \\qquad (\\text{since} \\quad 2^{16} / 2 = 32768)\n\nChangelog\n---------\n\n+-----------------+-------------------------------------------------------------+\n| Version         | Changes                                                     |\n+=================+=============================================================+\n| AviSynth+ 3.7.6 || Vectorscope modes: added ``matrix``, ``graticule``,        |\n|                 |  ``targets``, ``axes``, ``iq``, ``iq_lines``, ``circle``    |\n|                 |  parameters.                                                |\n|                 || Vectorscope modes: matrix-aware; target box                |\n|                 |  and I/Q overlay positions are computed from ground-truth   |\n|                 |  linear 75% RGB values through the active YUV matrix, giving|\n|                 |  accurate results for BT.601, BT.709, BT.2020 and other     |\n|                 |  supported matrices at all bit depths including float.      |\n|                 || Vectorscope modes: copy alpha from clip, initialize alpha  |\n|                 |  to zero in the histogram area.                             |\n|                 || Vectorscope modes: accurate pixel positioning and scaling  |\n|                 |  to the active histogram area, limited/full range aware.    |\n+-----------------+-------------------------------------------------------------+\n| AviSynth+ 3.7.2 || Added support for all YUV(A) formats (10-16 bit and float) |\n|                 |  in \"Luma\" mode.                                            |\n|                 || Fix: prevent crash when factor=0 in \"Levels\" mode.         |\n|                 || Fix: \"Levels\" mode: fix incorrect \"factor\" applied for U/V |\n|                 |  part drawing when format was subsampled (non-444).         |\n|                 || Make \"factor\" a named parameter (previously an unnamed     |\n|                 |  optional parameter).                                       |\n|                 || Fix: check for Planar RGB in \"Audiolevels\", \"Color\",       |\n|                 |   \"Color2\" and \"StereoOverlay\" modes.                       |\n|                 || Levels mode: stop using shades of grey on top of bars.     |\n|                 || Levels mode: use bar color 255 for RGB instead of Y's 235. |\n|                 |  (and scaled equivalents).                                  |\n|                 || Fix: \"Color\" mode may crash on certain dimensions for      |\n|                 |  subsampled formats.                                        |\n|                 || Fix: \"Color2\" missing CCIR rectangle top and bottom line.  |\n+-----------------+-------------------------------------------------------------+\n| AviSynth+ 3.7.0 | Added support for all YUV(A) formats (10-16 bit and float)  |\n|                 | in \"Color2\" mode.                                           |\n+-----------------+-------------------------------------------------------------+\n| AviSynth+ 3.6.1 | Added greyscale support in \"Levels\" mode.                   |\n+-----------------+-------------------------------------------------------------+\n| AviSynth+ 3.4.0 || Added ``keepsource`` and ``bits`` parameters.              |\n|                 || Added support for RGB24/32/48/64 and all planar            |\n|                 |  RGB(A)/YUV(A) formats in \"Levels\" mode.                    |\n|                 || Added support for all YUV(A) formats (10-16 bit and float) |\n|                 |  in \"Classic\" mode.                                         |\n+-----------------+-------------------------------------------------------------+\n| AviSynth 2.6.0  || Added \"StereoY8\" mode.                                     |\n|                 || Added factor option to \"Levels\" mode.                      |\n|                 || Improve colour of chroma legends in \"Levels\" mode.         |\n+-----------------+-------------------------------------------------------------+\n| AviSynth 2.5.8  || Added \"Color2\" and \"AudioLevels\" modes.                    |\n|                 || Added YV12 support.                                        |\n+-----------------+-------------------------------------------------------------+\n| AviSynth 2.5.6  | Added invalid colors in YUY2 mode.                          |\n+-----------------+-------------------------------------------------------------+\n| AviSynth 2.5.5  | Added dots to \"Stereo\" mode to show bias/offsets.           |\n+-----------------+-------------------------------------------------------------+\n| AviSynth 2.5.4  | Added \"Luma\", \"Stereo\", and \"StereoOverlay\" modes.          |\n+-----------------+-------------------------------------------------------------+\n| AviSynth 2.5.3  | Added ``mode`` parameter and \"Levels\" and \"Color\" modes.    |\n+-----------------+-------------------------------------------------------------+\n| AviSynth 2.5.0  | Added markers to show invalid colors in YUV. Invalid values |\n|                 | (below 16 and above 235) will be colored brown/yellow-ish.  |\n+-----------------+-------------------------------------------------------------+\n\n$Date: 2026/02/19 $\n\n.. _histograms:\n    https://en.wikipedia.org/wiki/Color_histogram\n.. _Waveform Monitor:\n    https://en.wikipedia.org/wiki/Waveform_monitor\n.. _vectorscope:\n    https://en.wikipedia.org/wiki/Vectorscope\n.. _hue:\n    https://en.wikipedia.org/wiki/Hue\n.. _saturation:\n    https://en.wikipedia.org/wiki/Colorfulness#Saturation\n.. _decibels:\n    https://en.wikipedia.org/wiki/Decibel\n.. _Root Mean Square:\n    https://en.wikipedia.org/wiki/Root_mean_square\n.. _clipping:\n    https://en.wikipedia.org/wiki/Clipping_(audio)\n.. _goniometer:\n    https://en.wikipedia.org/wiki/Goniometer_(audio)\n\n.. |clearfloat|  raw:: html\n\n    <div class=\"clearer\"></div>"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/imagesource.rst",
    "content": "\nImageReader / ImageSource / ImageSourceAnim\n===========================================\n\n| ``ImageReader`` (string \"file\", int \"start\", int \"end\", float \"fps\", bool\n  \"use_DevIL\", bool \"info\", string \"pixel_type\")\n| ``ImageSource`` (string \"file\", int \"start\", int \"end\", float \"fps\", bool\n  \"use_DevIL\", bool \"info\", string \"pixel_type\")\n| ``ImageSourceAnim`` (string \"file\", float \"fps\", bool \"info\", string\n  \"pixel_type\")\n\n``ImageReader`` is present in *v2.52*, it replaces WarpEnterprises' plugin,\nwith some minor functionality changes. As of *v2.55* ``ImageSource`` is\nequivalent, with some minor functionality changes. ``ImageSource`` is faster\nthan ``ImageReader`` when importing one picture.\n\nfile: template for the image file(s), where frame number substitution can be\nspecified using `sprintf syntax`_. For example, the files written by\n:doc:`ImageWriter <imagewriter>`'s default parameters can be referenced with\n``\"c:\\%06d.ebmp\"``. As of v2.56 if the template points to a single file then\nthat file is read once and subsequently returned for all requested frames.\n\n*start* = 0, *end* = 1000: Specifies the starting and ending numbers used for\nfilename generation. The file corresponding to start is always frame 0 in the\nclip, the file corresponding to end is frame (end-start). The resulting clip\nhas (end-start+1) frames. ``end=0`` does NOT mean 'no upper bound' as with\n:doc:`ImageWriter <imagewriter>`. The first file in the sequence, i.e., corresponding\nto 'start', MUST exist in order for clip parameters to be computed. Any\nmissing files in the sequence are replaced with a blank frame.\n\n*fps* = 24: frames per second of returned clip. An integer value prior to\n*v2.55*.\n\n*use_DevIL* = false: When false, an attempt is made to parse (E)BMP files with\nthe internal parser, upon failure (prior to v2.56) DevIL processing is\ninvoked. When true, execution skips directly to DevIL processing. You should\nonly need to use this if you have BMP files you don't want read by\n``ImageReader``'s internal parser.\n\n*NOTE* : DevIL version 1.6.6 as shipped with Avisynth does not correctly\nsupport DIB/BMP type files that use a pallette, these include 8 bit RGB,\nMonochrome, RLE8 and RLE4. Because the failure is usually catastrophic, from\nrevision 2.56, internal BMP processing does not automatically fail over to\nDevIL processing. Forcing DevIL processing for these file types is currently\nnot recommended.\n\n*info* = false: when true, the source filename and DevIL version is written to\neach video frame (added in *v2.55*).\n\n*pixel_type* = \"rgb24\": Allow the output pixel format to be specified, both\nrgb24 and rgb32 are supported. The alpha channel is loaded only for rgb32 and\nonly if DevIL supports it for the loaded image format. (added in *v2.56*).\n\nThe resulting video clip colorspace is RGB if DevIL is used, otherwise it is\nwhatever colorspace an EBMP sequence was written from (all AviSynth formats\nare supported).\n\nSupported formats are:\n\n-   (e)bmp, dds, ebmp, jpg/jpe/jpeg, pal, pcx, png, pbm/pgm/ppm, raw,\n    sgi/bw/rgb/rgba, tga, tif/tiff.\n-   gif, exr, jp2, psd, hdr. [all of them require 1.7.8 DevIL.dll]\n\n``ImageSourceAnim`` (added in *v2.60*; requires 1.7.8 DevIL.dll) lets you\nimport animations (gif, ppm, tiff or psd). If there is a delay between the\nfirst and second image in the animation, the framerate is set accordingly. If\nthis delay is zero, the framerate is set to 24 fps by default (and can be\nadjusted by setting the *fps* parameter). Note that *pixel_type* is set to\nRGB32 by default. If the images in the animation have unequal dimensions,\nthen the dimension of the first image is taken and the remaining images are\npadded with black pixels below and or to the right.\n\n1.7.8 DevIL.dll can be downloaded `here`_. Just put the DevIL.dll in your\nsystem folder (it will overwrite the 1.6.6 DevIL.dll which comes with\nAviSynth). Be sure to use the non-unicode version, because the other one\nwill result in crashes when loading pictures.\n\nDevIL.dll 1.7.8 requires the 2005 VC runtime libraries to be correctly\ninstalled: `Visual C++ 2005 SP1 Redistributable Package (x86)`_.\n\n::\n\n    # Default parameters: read a 1000-frame native AviSynth EBMP sequence (at 24 fps)\n    ImageSource()\n\n    # Read files \"100.jpeg\" through \"199.jpeg\" into an\n    NTSC clip\n    ImageSource(\"%d.jpeg\", 100, 199, 29.97)\n    # Note: floating-point fps available in v2.56\n\n    # Read files \"00.bmp\"\n    through \"50.bmp\" bypassing AviSynth's internal BMP reader\n    ImageSource(\"%02d.bmp\", end = 50, use_DevIL = true)\n\n    # Read a single\n    image, repeat 300 times\n    ImageSource(\"static.png\", end = 300, use_DevIL=true)\n    # Much, much faster in v2.56\n\n    # Read a greyscale (8-bit) jpg:\n    ImageSource(\"GoldPetals-8bit.jpg\", use_DevIL=true)\n\n    # Read a greyscale (8-bit) BMP (using AviSynth's internal BMP reader):\n    ImageSource(\"GoldPetals-8bit.bmp\")\n\n    # Read a YV24 BMP (created with ImageWriter):\n    ImageSource(\"GoldPetals-24bit.ebmp\")\n\n    # Use a still-frame image with audio:\n    audio = DirectShowSource(\"Gina La Piana - Start Over.flv\")\n    video = ImageSource(\"Gina La Piana.jpg\", fps=25, start=1, end=ceil(25*AudioLengthF(audio)/AudioRate(audio)))\n    return AudioDub(video, audio)\n\n    # Read an animation:\n    ImageSourceAnim(\"F:\\TestPics\\8bit_animated.gif\")\n\n**Notes:**\n\n-   \"EBMP\" is an AviSynth extension of the standard Microsoft RIFF image\n    format that allows you to save raw image data (all color formats are\n    supported). See :doc:`ImageWriter <imagewriter>` for more details.\n-   Greyscale BMPs are not read and written correctly by DevIL. They\n    should be opened using **use_DevIL=false**.\n-   DevIL version 1.6.7 as shipped with AviSynth does not correctly\n    support DIB/BMP type files that use a pallette, these include 8 bit RGB,\n    Monochrome, RLE8 and RLE4. Loading those images requires DevIL version\n    1.7.8. (Because the failure is usually catastrophic, from revision v2.56,\n    internal BMP processing does not automatically fail over to DevIL\n    processing. Forcing DevIL processing with the shipped DevIL version for\n    these file types is currently not recommended.)\n\n+---------+-----------------------------------------------------------+\n| Changes |                                                           |\n+=========+===========================================================+\n| v2.60   | - Added ImageSourceAnim.                                  |\n|         | - Support user upgrade to 1.7.8 DevIL.dll                 |\n|         |   (need to manage CRT dependancies).                      |\n|         | - Palette and compressed bmp images load correctly now    |\n|         |   (issue 894702) [requires 1.7.8 DevIL.dll]               |\n|         | - Support for other formats like: gif, exr, jp2, psd, hdr |\n|         |   [requires 1.7.8 DevIL.dll]                              |\n|         | - Opening greyscale images (as Y8) added; EBMP supports   |\n|         |   all color formats.                                      |\n+---------+-----------------------------------------------------------+\n\n$Date: 2012/10/10 13:41:51 $\n\n.. _sprintf syntax:\n    http://www.cplusplus.com/reference/clibrary/cstdio/sprintf/\n.. _here:\n    https://sourceforge.net/projects/openil/files/DevIL%20Win32/1.7.8/DevIL-EndUser-x86-1.7.8.zip\n.. _Visual C++ 2005 SP1 Redistributable Package (x86):\n    http://www.microsoft.com/downloads/details.aspx?familyid=200B2FD9-AE1A-4A14-984D-389C36F85647&displaylang=en\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/imagewriter.rst",
    "content": "===========\nImageWriter\n===========\n\n**ImageWriter** writes frames from a clip as a sequence of image files using the\n`DevIL library`_ (except when you choose the internal \"ebmp\" format).\n\nNote that frames are not written to the output file until they are actually\nrendered by this filter.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    ImageWriter (clip, string \"file\", int \"start\", int \"end\", string \"type\", bool \"info\")\n\n.. describe:: clip\n\n    | Source clip; only 8 and 16-bit RGB(A) or greyscale (Y) formats supported.\n    | EBMP type only supports 8-bit RGB, YUV or greyscale (Y) formats.\n\n.. describe:: file\n\n    | The path + filename prefix of the saved images.\n    | The images will have file names with the pattern: ``file``\\ 000000.\\ ``type``,\n      ``file``\\ 000001.\\ ``type``, etc.\n    | `Sprintf`_ formatting of the filenames is supported.\n    | By default, images will be saved as *C:\\\\000000.ebmp, C:\\\\000001.ebmp*, etc.\n\n    Default: \"c:\\\\\"\n\n.. describe:: start, end\n\n    The start and end of the frame range that will be written.\n    They both default to 0 (where ``end=0`` means last frame).\n    If ``end`` is negative, it specifies the number of frames that will be written.\n\n    Default: 0, 0\n\n.. describe:: type\n\n    | Set the filename extension that defines the format of the saved image.\n    | The supported values for ``type`` are:\n\n    .. table::\n        :widths: auto\n\n        +-----------------+------------------------------+\n        | Type            | Format                       |\n        +=================+==============================+\n        | bmp             | `BMP file format`_           |\n        +-----------------+------------------------------+\n        | ebmp            | `EBMP`_                      |\n        +-----------------+------------------------------+\n        | dds             | `DirectDraw Surface`_        |\n        +-----------------+------------------------------+\n        | jpg/jpe/jpeg    | `JPEG`_                      |\n        +-----------------+------------------------------+\n        | pcx             | `PiCture eXchange`_          |\n        +-----------------+------------------------------+\n        | png             | `Portable Network Graphics`_ |\n        +-----------------+------------------------------+\n        | pbm/pgm/ppm     | `Portable pixmap`_           |\n        +-----------------+------------------------------+\n        | tga             | `Truevision TGA`_            |\n        +-----------------+------------------------------+\n        | tif/tiff        | `Tag Image File Format`_     |\n        +-----------------+------------------------------+\n        | raw             | `Raw image format`_          |\n        +-----------------+------------------------------+\n        | sgi/bw/rgb/rgba | `Silicon Graphics Image`_    |\n        +-----------------+------------------------------+\n\n    Default: \"ebmp\"\n\n.. describe:: info\n\n    When true, overlay progress information on the video clip, showing whether\n    a file is being written, and if so, the filename.\n\n    Default: false\n\n\nNotes\n-----\n\n* JPGs are saved with the quality setting set to 99. For RGB input, the colorspace\n  is converted to YUV with a 4:2:0 chroma subsampling. When the input is greyscale\n  (Y), JPGs are saved in the same Y format.\n\n* Greyscale BMPs are not written correctly by DevIL (the luma is written to all\n  three channels instead of a single channel). They should be written as ebmp or\n  better yet as PNG or TIFF.\n\n\nEBMP\n~~~~\n\nThe internal image format \"ebmp\" supports all 8-bit color spaces. The \"ebmp\"\nfiles written from the RGB or Y8 color spaces are standard BMP files, but those\nproduced from YUV spaces are special and can probably only be read by AviSynth's\n:doc:`ImageSource <imagesource>`. This special format allows you to save and\nreload raw video in any 8-bit color space.\n\n\"EBMP\" is an AviSynth extension of the standard Microsoft `RIFF`_ image format\nthat allows you to save raw image data.\n\n\nExamples\n--------\n\nExport the entire clip in the current native AviSynth format::\n\n    ImageWriter(\"D:\\backup-stills\\myvideo\")\n\nWrite frame 5 to \"C:\\000005.png\" ::\n\n    ImageWriter(start=5, end=5, type=\"png\")\n\nWrite frame 5 to \"000005.png\" into the current directory::\n\n    ImageWriter(\"\", start=5, end=5, type=\"png\")\n\nWrite frames 100 till the end to *\"F:\\pic-000100.jpeg\", \"F:\\pic-000101.jpeg\",*\netc. and display progress info::\n\n    ImageWriter(file=\"F:\\pic-\", start=100, type=\"jpeg\", info=true)\n\nWrite all frames to \"F:\\00.png\", \"F:\\01.png\", ..., \"F:\\10.png\", \"F:\\11.png\", ...,\n\"F:\\100.png\", ... (thus adding zeros filling two digits)::\n\n    ImageWriter(file=\"F:\\%02d.png\")\n\nLoad a jpg image and extract the Y (luma) plane and save it as a greyscale png::\n\n    FFImageSource(\"GoldPetals.jpg\")\n    ExtractY()\n    ImageWriter(\"GoldPetals-luma\", type=\"png\")\n\nLoad a YUV420 jpg image and convert it to YUV444 and save it as an ebmp::\n\n    FFImageSource(\"GoldPetals.jpg\")\n    ConvertToYUV444(ChromaInPlacement=\"MPEG1\") # \"MPEG2\" for YUV422 JPGs\n    ImageWriter(\"GoldPetals-YUV444\", type=\"ebmp\")\n\nSee the :doc:`ImageReader <imagesource>` page for more information on why the\nJPGs in the last two examples were loaded with `FFImageSource`_ instead of the\ninternal ImageReader filter.\n\nChangelog\n----------\n\n+-----------------+------------------------------------------------------------------+\n| Version         |                                                                  |\n+=================+==================================================================+\n| AviSynth+ r2768 | Fix: ImageReader/Writer: path \"\" means current directory.        |\n+-----------------+------------------------------------------------------------------+\n| AviSynth+ r2502 | Fix: ImageWriter crash when no '.' in filename.                  |\n+-----------------+------------------------------------------------------------------+\n| AviSynth+ r2487 || Added support for support RGB48/64 and Y16 formats.             |\n|                 || Fix: flip greyscale except when raw.                            |\n+-----------------+------------------------------------------------------------------+\n| AviSynth 2.6.1  || DevIL library updated to 1.7.8.                                 |\n|                 || DevIL.dll is now delay loaded, so Avisynth.dll can be used      |\n|                 |  without it, in which case ImageReader/Writer would support only |\n|                 |  ebmp mode.                                                      |\n+-----------------+------------------------------------------------------------------+\n| AviSynth 2.6.0  || ebmp supports all formats; greyscale added for all formats.     |\n|                 || Add support for printf formating of filename string, default is |\n|                 |  (\"%06d.%s\", n, ext).                                            |\n+-----------------+------------------------------------------------------------------+\n| AviSynth 2.5.8  | Added end=-num_frames (supports negative values as -count for    |\n|                 | ``end`` argument).                                               |\n+-----------------+------------------------------------------------------------------+\n| AviSynth 2.5.3  | Added ``info`` parameter.                                        |\n+-----------------+------------------------------------------------------------------+\n| AviSynth 2.5.2  | Added ``start``, ``end`` and ``type`` parameters.                |\n+-----------------+------------------------------------------------------------------+\n| AviSynth 2.5.1  | Added ImageWriter filter in limited form.                        |\n+-----------------+------------------------------------------------------------------+\n\n$Date: 2022/03/24 12:22:43 $\n\n.. _DevIL library:\n    https://github.com/DentonW/DevIL\n.. _Sprintf:\n    http://www.cplusplus.com/reference/cstdio/sprintf/\n.. _BMP file format:\n    https://en.wikipedia.org/wiki/BMP_file_format\n.. _BMP file format:\n    https://en.wikipedia.org/wiki/BMP_file_format\n.. _DirectDraw Surface:\n    https://en.wikipedia.org/wiki/DirectDraw_Surface\n.. _JPEG:\n    https://en.wikipedia.org/wiki/JPEG\n.. _PiCture eXchange:\n    https://en.wikipedia.org/wiki/PCX\n.. _Portable Network Graphics:\n    https://en.wikipedia.org/wiki/Portable_Network_Graphics\n.. _Portable pixmap:\n    https://en.wikipedia.org/wiki/Netpbm#File_formats\n.. _Truevision TGA:\n    https://en.wikipedia.org/wiki/Truevision_TGA\n.. _Tag Image File Format:\n    https://en.wikipedia.org/wiki/TIFF\n.. _Raw image format:\n    https://en.wikipedia.org/wiki/Raw_image_format\n.. _Silicon Graphics Image:\n    https://en.wikipedia.org/wiki/Silicon_Graphics_Image\n.. _RIFF:\n    https://en.wikipedia.org/wiki/Resource_Interchange_File_Format\n.. _FFImageSource:\n    http://avisynth.nl/index.php/FFmpegSource\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/import.rst",
    "content": "\nImport\n======\n::\n\n    Import(filename[, ...] [, bool utf8]))\n\nEvaluates the contents of another script and returns the result of that evaluation.\n\nIt works exactly like :ref:`Eval <syntax_internal_functions_control_eval>`, except\n\n*   The expression to be evaluated comes from a file instead of a string;\n*   The values of ScriptName, ScriptFile and ScriptDir are set to the current (imported) script;\n*   The current working directory (CWD) is set to the current (imported) script.\n*   ``utf8`` if true, assumes filename(s) are UTF8, else (default), assume ANSI. \n\nFunctions, variables and loaded plugins declared inside the imported script are made available to the \nparent script. Import's return value can be assigned to a variable of the parent script; this is most\nuseful when the imported script ends with a clip. \n\nTypically Import is used to make library functions available to the parent script, and the return\nvalue is not used. However this is simply a convention; it is not enforced by the :doc:`AviSynth Syntax <../syntax/syntax>`.\n\nPossible scenarios (an indicative list) where the return value could be of use is for the library script to:\n\n-   Storing multiple script-functions, variables and global variables for reuse by scripts \n    (creation of script libraries).\n-   Retrieving pre-built streams.\n-   Retrieving dynamically configured pre-built streams (the core idea is that the importing \n    script declares some global variables which the imported script uses to configure the \n    stream that will return). \n-   indicate whether it succesfully initialised itself (a bool return value),\n-   inform for the number of presets found on disk (an int return value);\n\nthe value then could be tested by the calling script to decide what action to\ntake next.\n\n*   Note 1: Since the contents of the imported script are evaluated at the point of invocation, \n    it is possible by enclosing the Import call in a nested scope (for example inside a function) \n    to make available to the importing script the functions and globals of the imported script \n    without its script-level variables. \n*   Note 2: Any script with the AVSI extension in the AviSynth Plugins folder is automatically \n    imported. This is useful for making script functions available to any new script you create \n    without having to copy and paste. \n\n*Examples:*\n::\n\n    # B.avsi\n    A.Invert\n    \n    ColorBars\n    A=Subtitle(\"A\", align=5) ## create clip 'A'\n    Import(\"B.avsi\")\n    return Last ## returns clip 'A' with colors inverted\n\n::\n\n    ## here we do not care about the return value (mylib.avsi contains only functions)\n    Import(\"mylib.avsi\")  \n    ...\n    ## mysources.avsi loads predetermined file names from a folder into globals\n    okflag = Import(\"mysources.avsi\")  \n    source = okflag ? global1 + global2 + global3 : BlankClip()\n\n$Date: 2024/01/06 19:00:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/info.rst",
    "content": "\nInfo\n====\n\nGives :doc:`clip property information <../syntax/syntax_clip_properties>` as a \ntext overlay in the upper-left corner.\n\nThe displayed information consists of:\n\n* current frame and total frame count,\n* current time and total duration,\n* colorspace and bit depth,\n* width and height,\n* frame rate (as floating-point and fraction),\n* whether it is field or frame based,\n* parity: whether AviSynth thinks it is bottom or top field first,\n* video pitch (length of a video line in bytes),\n* whether there is audio present,\n* the number of audio channels,\n* audio sample type,\n* audio sample rate,\n* total audio samples and total audio duration (hh:mm:ss:ddd),\n* channel layout\n* CPU capabilities\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    Info (clip clip, string \"font\", float \"size\", int \"text_color\", int \"halo_color\", \n          bool \"bold\", bool \"italic\", bool \"noaa\",\n          bool \"cpu\",\n          float \"x\", float \"y\", int \"align\")\n\n.. describe:: clip\n\n    Source clip. If only an audio clip is supplied, **Info** creates a blank \n    video clip to overlay the information on.\n\n.. describe:: font\n\n    Font name; can be the name of any installed Windows font.\n\n    Default: \"Courier New\"\n\n.. describe:: size\n\n    | Height of the text in pixels, and is rounded to the nearest 0.125 pixel. \n    | Default depends on the dimensions of the clip:\n    \n    * If either the width or height is less than 384x224, the font is auto-scaled.\n    * If the both the width and height are greater than 384x224, ``size`` defaults\n      to 15.\n    * If ``size`` is set to < 0, the font is automatically enlarged for clips \n      over 640x480.\n\n    Default: auto\n\n    On non-Windows-GDI systems the available font sizes are limited.\n\n.. describe:: text_color, halo_color\n\n    | Colors for font fill and outline respectively.  See the\n      :doc:`colors <../syntax/syntax_colors>` page for more information on \n      specifying colors.\n    | Default text color is yellow and halo color is black.\n\n    Default: $FFFF00, $000000\n\n.. describe:: bold\n\n    | Using bold letters or not\n    | Default is true, since bold has better visibility.\n\n    Default: true\n\n.. describe:: italic\n\n    | Using italic letters or not\n\n    Default: false\n\n.. describe:: noaa\n\n    | Disables antialiasing when drawing the text\n\n    Default: false\n\n.. describe:: cpu\n\n    | Enables or disables showing CPU capabilities flags\n\n    Default: true\n\n.. describe:: x, y\n\n    | Reference point of the Info text box area, alignments are\n      calculated relative to that.\n\n    Default: 4, 0 (top left), screen centers or right/bottom when alignment is specified\n\n.. describe:: align\n\n    | an integer number describing at what screen area (or given x,y coordinates)\n      will be the info text box aligned.\n      Values 1-9 are allowed. See your numeric keypad layout, e.g. 7 is top-left,\n      9 is top right, 3: bottom-right, etc..\n\n    Default: 7 (top-left)\n    \n    Note: on Windows-GDI systems the whole text box is aligned. Within the box the text lines\n    are left aligned. On non-Windows-GDI (e.g. Linux) the individual lines are aligned \n    horizontally as well.\n\n\nExamples\n--------\n\n::\n\n    Blankclip(pixel_type=\"YUV444P16\")\n    SetChannelMask(\"mono\")\n    Info()\n\nResults in a video with the following information overlay:\n    \n::\n\n     Frame: 0 of 240\n     Time: 00:00:00:000 of 00:00:10:000\n     ColorSpace: YUV444P16, BitsPerComponent: 16\n     Width: 640 pixels, Height: 480 pixels.\n     Frames per second: 24.0000 (24/1)\n     FieldBased (Separated) Video: NO\n     Parity: Bottom Field First\n     Video Pitch: 1280 bytes.\n     Has Audio: YES\n     Audio Channels: 1\n     Sample Type: Integer 16 bit\n     Samples Per Second: 44100\n     Audio length: 441000 samples. 00:00:10:000\n     Channel mask: mono\n     CPU: SSE2 SSE3 SSSE3 SSE4.1 SSE4.2 AVX F16C\n\nThe following script aligns Info box to the top right, it won't interfere with propShow\nin top left.\n    \n::\n\n    ColorBars()\n    propShow()\n    Info(cpu=false, align=9)\n\n\nChangelog\n---------\n\n+-----------------+-----------------------------------------------------------------------+\n| Version         | Changes                                                               |\n+=================+=======================================================================+\n| AviSynth+ 3.7.4 || Add ``cpu`` parameter                                                |\n|                 || Add ``x, y, align`` parameters                                       |\n|                 || Draw partially visible lines as well                                 |\n+-----------------+-----------------------------------------------------------------------+\n| AviSynth+ 3.7.3 | Add ``bold``, ``italic`` and ``noaa``                                 |\n+-----------------+-----------------------------------------------------------------------+\n| AviSynth+ 3.5.1 | When parameter ``size`` < 0, font is automatically enlarged when the  |\n|                 | dimensions of the clip are greater than 640x480.                      | \n+-----------------+-----------------------------------------------------------------------+\n| AviSynth+ r2487 | Added parameters ``font, size, text_color, halo_color`` and fix       |\n|                 | hardcoded dimensions.                                                 |\n+-----------------+-----------------------------------------------------------------------+\n| AviSynth 2.6.0  | Added support audio only clips.                                       |\n+-----------------+-----------------------------------------------------------------------+\n| AviSynth 2.5.7  | Added time of current frame, total time, numerator and denominator of |\n|                 | the framerate and audio length.                                       |\n+-----------------+-----------------------------------------------------------------------+\n| AviSynth 2.5.5  | Added supported CPU optimizations                                     |\n+-----------------+-----------------------------------------------------------------------+\n| AviSynth 2.5.0  | Initial Release                                                       |\n+-----------------+-----------------------------------------------------------------------+\n\n$Date: 2023/11/03 10:42:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/interleave.rst",
    "content": "==========\nInterleave\n==========\n\n*Interleaves* frames from several clips on a frame-by-frame basis, so for\nexample if you give three arguments, the first three frames of the output video\nare the first frames of the three source clips, the next three frames are the\nsecond frames of the source clips, and so on.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    Interleave (clip1, clip2 [, ...])\n\n.. describe:: clip1, clip2, ...\n\n    Source clips; all color formats supported. The dimensions of the clips and\n    their color formats must be the same. See :doc:`filters with multiple input\n    clips <../filters_mult_input_clips>` for the resulting\n    :doc:`clip properties <../syntax/syntax_clip_properties>`.\n\n\nExamples\n--------\n\n**Interleave** is very useful for comparing two similar videos, stepping\nframe-by-frame::\n\n    Interleave(A.Subtitle(\"A\"), B.Subtitle(\"B\"))\n\n\n\n$Date: 2022/03/24 22:44:06 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/invert.rst",
    "content": "======\nInvert\n======\n\nInverts one or several color channels of a clip.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    Invert (clip, string \"channels\")\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n.. describe:: channels\n\n    | Defines which channels should be inverted by their initial letters, e.g.\n      \"R\" (=red).\n    | Any letters that don't correspond to a channel in the current colorspace\n      are ignored.\n    | Valid channel letters are:\n\n    * R, G, B, A for RGB(A) clips.\n    * Y, U, V, A for YUV(A) clips.\n\n    | Letters are not case sensitive and may be given in any order.\n    | By default, all channels of the current colorspace are inverted.\n\n    Default: \"RGBA\" if input clip is RGB, \"YUVA\" if input clip is YUV.\n\n\nExamples\n---------\n\nInvert the blue and green channels::\n\n    AviSource(\"clip.avi\")\n    ConvertToRGB32()\n    Invert(channels=\"BG\") # can also be written as channels=\"g, b\"\n\nExamples were Invert has no effect::\n\n    AviSource(\"clip.avi\")\n    ConvertToRGB24()\n    Invert(channels=\"A\")     # no effect (no current A channel)\n    Invert(channels=\"VUY\")   # no effect (no current Y, U or V channels)\n\n\nChangelog\n---------\n\n+-----------------+--------------------------------------------------------+\n| Version         | Changes                                                |\n+=================+========================================================+\n| AviSynth+ r2487 | Added support for YUV(A)/PlanarRGB(A) 8,10-16,32 bit,  |\n|                 | RGB48/64 color formats, with SSE2.                     |\n+-----------------+--------------------------------------------------------+\n| AviSynth 2.6.0  | Added support for YV24, YV16, YV411, Y8 color formats. |\n+-----------------+--------------------------------------------------------+\n| Avisynth 2.5.5  | Added support for RGB24, YUY2 and YV12 color formats.  |\n+-----------------+--------------------------------------------------------+\n| AviSynth 2.5.3  | Initial Release.                                       |\n+-----------------+--------------------------------------------------------+\n\n$Date: 2022/03/20 16:58:20 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/killaudio.rst",
    "content": "\nKillAudio / KillVideo\n=====================\n\nRemoves the audio or video from a clip completely. Can be used, if the\ndestination does not accept an audio or video source, or if AviSynth crashes\nwhen processing audio or video from a clip.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    KillAudio (clip)\n    KillVideo (clip)\n\n.. describe:: clip\n\n    Source clip.\n\n\nExamples\n--------\n\n``KillAudio()`` can be called at any time to remove audio, and may be chained::\n\n    DeleteFrame(KillAudio(DirectShowSource(clip)), 100)\n    \n$Date: 2022/02/05 15:10:22 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/layer.rst",
    "content": "\nLayer\n=====\n\nLayer (aka overlay, blend, merge) merges two clips of possibly different sizes, but with the same color format.\n\nFor pixel-wise transparency information, the alpha channel of an RGBA overlay_clip is used as a mask.\n\nNote that some modes can be similar to :doc:`Overlay <overlay>`, but the two filters are still different.\n\n- Overlay accepts mask clip, Layer would use existing A plane.\n- Overlay \"blend\" is Layer \"add\", Overlay \"add\" is different.\n- Lighten and darken is a bit different in Overlay.\n- Layer has \"placement\" parameter for proper mask positioning over chroma.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    Layer (clip base_clip, clip overlay_clip, [string \"op\", int \"level\", int \"x\", \n           int \"y\", int \"threshold\", bool \"use_chroma\", float \"opacity\", string \"placement\"] )\n\n.. describe:: base_clip\n\n    the underlying clip which determines the size and all other video\n    and audio properties of the result. YV411 is not supported.\n\n.. describe:: overlay_clip\n\n    the clip which is merged onto clip. If RGB32 or other alpha-aware color space, \n    the alpha channel is used as a mask. Non-alpha plane YUV/planar RGB color spaces act as having \n    a fully transparent alpha channel. Color format must match base_clip.\n\n    Note: if destination is YUVA/RGBA, the overlay clip also has to be Alpha-aware type.\n    Alpha channel is not updated for YUVA targets, but RGBA targets do get the Alpha \n    updated (like the old RGB32 mode did - compatibility)\n\n.. describe:: op\n\n    the performed merge operation, which can be: \"add\", \"subtract\", \"lighten\", \n    \"darken\", \"fast\", \"mul\"\n\n    +----------+-------------------------------------------------+-------------------------------------------------------------------------------------------------------------+\n    | Operation| Example                                         | Description                                                                                                 |\n    +----------+-------------------------------------------------+-------------------------------------------------------------------------------------------------------------+\n    | add      | .. image:: ./pictures/Layer-base-Lena.png       | | This is the default mode. Equivalent to ``Overlay(mode=\"blend\")``                                         |\n    |          | .. image:: ./pictures/Layer-over-grad.png       |                                                                                                             |\n    |          | .. image:: ./pictures/Layer-example-add.png     | | ``overlay_clip`` will be copied on top of the original, in proportion to ``opacity`` or ``level``         |\n    |          |                                                 |   and subject to the alpha channel.                                                                         |\n    |          |                                                 |                                                                                                             |\n    |          |                                                 | | The difference between ``base_clip`` and ``overlay_clip`` is multiplied with alpha and added to           |\n    |          |                                                 | | ``base_clip``.                                                                                            |\n    |          |                                                 |                                                                                                             |\n    |          |                                                 | | - alpha=0d   → only ``base_clip`` visible                                                                 |\n    |          |                                                 | | - alpha=128d → ``base_clip`` and ``overlay_clip`` equally blended                                         |\n    |          |                                                 | | - alpha=255d → only ``overlay_clip`` visible                                                              |\n    |          |                                                 |                                                                                                             |\n    |          |                                                 | | Formula used :                                                                                            |\n    |          |                                                 | |                                                                                                           |\n    |          |                                                 | | - using ``opacity`` parameter                                                                             |\n    |          |                                                 | |   - Alpha-aware: ``base = base + (overlay - base) * opacity * alpha / max_range``                         |\n    |          |                                                 | |   - No alpha: ``base = base + (overlay - base) * opacity``                                                |\n    |          |                                                 |                                                                                                             |\n    |          |                                                 | | - Deprecated method using ``level`` for 8 bit RGB and YUY2 formats                                        |\n    |          |                                                 | |   - RGB:  ``base = base + ((overlay - base) * (alpha * level + 1) / 256) / 256``                          |\n    |          |                                                 | |   - YUY2: ``base = base + ((overlay - base) * level) / 256``                                              |\n    +----------+-------------------------------------------------+-------------------------------------------------------------------------------------------------------------+\n    | subtract | .. image:: ./pictures/Layer-example-sub.png     | | ``base_clip`` minus ``overlay_clip``. The same as \"add\", but ``overlay_clip`` is inverted before adding.  |\n    |          |                                                 |                                                                                                             |\n    |          |                                                 | | If both clips are equal and ``opacity`` = 0.5 (``level`` = 128), a flat gray field is returned            |\n    |          |                                                 |   compare to :doc:`Subtract <subtract>` .                                                                   |\n    +----------+-------------------------------------------------+-------------------------------------------------------------------------------------------------------------+\n    | lighten  | .. image:: ./pictures/Layer-example-lite.png    | | Copy ``overlay_clip`` over ``base_clip`` in areas where ``overlay_clip`` is lighter by threshold.         |\n    |          |                                                 | |                                                                                                           |\n    |          |                                                 | | Performs the same operation as \"add\", but only when ``overlay_clip`` is BRIGHTER than ``base_clip``.      |\n    |          |                                                 | |                                                                                                           |\n    |          |                                                 | | ``use_chroma`` must be true.                                                                              |\n    |          |                                                 | |                                                                                                           |\n    |          |                                                 | | Also known as lighter color.                                                                              |\n    +----------+-------------------------------------------------+-------------------------------------------------------------------------------------------------------------+\n    | darken   | .. image:: ./pictures/Layer-example-dark.png    | | Copy ``overlay_clip`` over ``base_clip`` in areas where ``overlay_clip`` is darker by threshold.          |\n    |          |                                                 | |                                                                                                           |\n    |          |                                                 | | The same as \"lighten\", but it is performed only when ``overlay_clip`` is DARKER than ``base_clip``.       |\n    |          |                                                 | |                                                                                                           |\n    |          |                                                 | | ``use_chroma`` must be true.                                                                              |\n    |          |                                                 | |                                                                                                           |\n    |          |                                                 | | Also known as darker color.                                                                               |\n    +----------+-------------------------------------------------+-------------------------------------------------------------------------------------------------------------+\n    | mul      | .. image:: ./pictures/Layer-example-mul-rgb.png | | ``base_clip`` multiplied by ``overlay_clip``. This will generally make the output darker.                 |\n    |          |                                                 | | - alpha=0d    → only ``base_clip`` visible.                                                               |\n    |          |                                                 | | - alpha=255d → approx. the same luminance as ``base_clip`` but with the colors of ``overlay_clip``.       |\n    |          |                                                 | | See GIMP: Multiply                                                                                        |\n    +----------+-------------------------------------------------+-------------------------------------------------------------------------------------------------------------+\n    | fast     |                                                 | Like \"add\", but without masking. ``use_chroma`` must be true; ``opacity``, ``level`` and ``threshold``      |\n    |          |                                                 | are not used. The result is simply the average of ``base_clip`` and ``overlay_clip``.                       |\n    +----------+-------------------------------------------------+-------------------------------------------------------------------------------------------------------------+\n\n.. describe:: level\n\n    Note: deprecated in Avisynth+, use \"opacity\" instead.\n\n    Original meaning: the strength of the performed operation.\n\n    - 0: the ``base_clip`` is returned unchanged, \n    - 257 (256 for YUY2): the maximal strength is used.\n\n.. describe:: x, y\n\n    offset position of the ``overlay_clip``\n\n.. describe:: threshold\n\n    Changes the transition point of op = \"darken\", \"lighten.\".\n\n    Automatically scaled for bit depths over 8, keep it between 0 and 255 \n\n\n.. describe:: use_chroma\n    Use chroma of the ``overlay_clip``, default=true. \n\n    When false, different behavior applies depending on color space. Must be true for op = \"darken\", \"lighten\", \"fast.\"\n    \n    **Effect on YUV/YUVA color spaces:**\n    \n    When ``use_chroma=false``:\n    \n    - Luma (Y) channel is processed normally using the overlay's Y values\n    - Chroma (U/V) channels **ignore the overlay** and instead blend toward neutral (128 for 8-bit integer, 0.0 for float)\n    - The result is **progressive desaturation** controlled by opacity:\n      \n      * opacity=0.0 → no change (keeps base chroma)\n      * opacity=0.5 → halfway desaturated  \n      * opacity=1.0 → fully neutral/grayscale\n    \n    **YUV Use Cases:**\n    \n    1. **Luminance-only compositing** - Adjust brightness using overlay's luma while preserving base clip's color:\n    \n       ::\n       \n           # Brighten image using luma overlay, keep original colors\n           Layer(color_clip, bright_overlay, op=\"add\", use_chroma=false, opacity=0.5)\n    \n    2. **Selective desaturation** - Use overlay's alpha channel to control where desaturation occurs:\n    \n       ::\n       \n           # Desaturate regions based on alpha matte\n           Layer(color_clip, alpha_matte, use_chroma=false, opacity=0.8)\n    \n    3. **Overlay graphics without color contamination** - Add logos/text that affect only brightness:\n    \n       ::\n       \n           # Logo affects brightness but doesn't introduce colors\n           Layer(video, logo_rgba, use_chroma=false)\n    \n    **Effect on Planar RGB/RGBA color spaces:**\n    \n    When ``use_chroma=false``:\n    \n    - Overlay RGB is **converted to grayscale** using standard luma coefficients (Rec.709: R×0.2126 + G×0.7152 + B×0.0722)\n    - **All channels** (R, G, B, and A if present) of the base clip blend toward this grayscale luma value\n    - The result is **desaturation** where all RGB channels approach the same value\n    \n    **RGB Use Cases:**\n    \n    1. **Grayscale overlay effect** - Use only the luminance information from a colored overlay:\n    \n       ::\n       \n           # Apply colored overlay as grayscale\n           Layer(color_base, color_overlay, use_chroma=false, opacity=1.0)\n    \n    2. **Luminance-based blending** - Mix clips using only brightness information:\n    \n       ::\n       \n           # Blend two clips ignoring color information from overlay\n           Layer(clip1, clip2, use_chroma=false, opacity=0.5)\n    \n    3. **Controlled desaturation** - Desaturate based on overlay's alpha channel:\n    \n       ::\n       \n           # More transparent areas remain colorful, opaque areas become gray\n           Layer(color_clip, alpha_gradient, use_chroma=false, opacity=0.7)\n    \n    **Summary:**\n    \n    - **YUV with use_chroma=true**: Normal color blending using overlay's U/V values\n    - **YUV with use_chroma=false**: Chroma neutralizes (desaturates), luma blends normally\n    - **RGB with use_chroma=true**: Normal color blending using overlay's R/G/B values  \n    - **RGB with use_chroma=false**: All channels blend toward overlay's grayscale luma (desaturates)\n    \n    In both color spaces, ``use_chroma=false`` produces desaturation, but through different mechanisms \n    appropriate to each color model.\n\n\n.. describe:: opacity\n\n    Transparency level.\n\n    | Usable for all bit depths, replaces the previous ``level`` parameter.\n    | Similar to \"opacity\" in \"Overlay\".\n\n    Valid values are 0.0 to 1.0. Default value is 1.0 if ``level`` does not exist.\n    (1.0 means full transparency)\n\n    If ``level`` parameter is given then ``opacity`` is calculated as:\n\n    - for color spaces having alpha: ``opacity = level / ((1 << bits_per_pixel) + 1)`` which gives 1.0 for level=257 (@8bit) and 65537 (@16 bits) \n    - for color spaces not having alpha: ``opacity = level / ((1 << bits_per_pixel))`` e.g. for YUY2 or other non-Alpha, gives 1.0 for level=256 (@8bit) \n\n    \"opacity\" parameter is bit depth independent (unlike ``level`` which was maxed with level=257 when RGB32 but level=256 for YUY2/YUV)\n\n    Note: originally level was used in formula: (alpha*level + 1) / range_size, \n    now level is calculated from opacity as: ``level = opacity * ((1 << bits_per_pixel) + 1)``\n\n.. describe:: placement\n\n    chroma placement for 420 and 422 YUV formats.\n\n    Possible values: \"mpeg2\" (default), \"mpeg1\".\n\n    Used in \"mul\", \"darken\" and \"lighten\", \"add\" and \"subtract\" modes with planar YUV \n    4:2:0 or 4:2:2 color spaces (not available for YUY2) in order to properly apply \n    luma/overlay mask on U and V chroma channels. \n\nOther notes\n-----------\n\nAudio, FrameRate and FrameCount are taken from the first clip. \n\nThere are some differences in the behaviour and the allowed parameter depending on the color format and the operation; here are the details:\n\n    - When there is no mask (alpha channel), the alpha channel is assumed to be fully opaque (255d) everywhere. \n\n    - in alpha-aware color spaces alpha channel is multiplied with opacity, so the resulting alpha is \n\n        ``alpha * opacity`` \n\n      This means for full strength of operation, alpha has to be 255d and opacity has to be 1.0. \n\nExamples\n~~~~~~~~\n\nThis can be used to combine two captures of different broadcasts for reducing\nnoise. A discussion of this idea can be found `in this thread`_. A sample script (of\ncourse you have to ensure that the frames of the two clips match exactly --\nuse :doc:`DeleteFrame <deleteframe>` if necessary):\n\n::\n\n    clip1 = AviSource(\"F:\\shakira-underneath_your_clothes.avi\").ConvertToYUY2\n    clip2 = AviSource(\"F:\\shakira-\n    underneath_your_clothes2.avi\").ConvertToYUY2\n    return Layer(clip1, clip2, \"fast\")\n\n\nChangelog\n----------\n\n+-----------------+---------------------------------------------------------------+\n| Version         | Changes                                                       |\n+=================+===============================================================+\n| 3.5.0           | Layer: support RGB24 and RGB48                                |\n+-----------------+---------------------------------------------------------------+\n| 3.4.0           | | Layer: support almost all formats, not only RGB32 and YUY2  |\n|                 |   except RGB24, RGB48, YV411                                  |\n|                 | | add \"opacity\" and \"placement\" parameters                    |\n|                 | | Fix: add proper rounding for add/subtract/lighten/darken    |\n|                 | | Fix: \"lighten\" and \"darken\" gave different results between  |\n|                 |   yuy2 and rgb32 when Threshold<>0                            |\n|                 | | Fix: \"darken\" for RGB32 when Threshold<>0                   |\n|                 | | Fix: \"lighten\" and \"darken\" for YUY2 when Threshold<>0      |\n+-----------------+---------------------------------------------------------------+\n\n\n$Date: 2025/01/15 13:15:00 $\n\n.. _in this thread: http://forum.doom9.org/showthread.php?s=&threadid=28438\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/letterbox.rst",
    "content": "\nLetterbox\n=========\n\nFills the top and bottom *rows* of each frame, and optionally the left and right \n*columns*, with black or color. This has several common uses:\n\n* Black out video noise from the existing black bands in an image that's already \n  letterboxed.\n* Black out the video noise at the bottom of the frame in `VHS`_ tape sources.\n* Black out overscan areas in `VCD`_ or `SVCD`_ sources.\n* Create a quick rectangular mask for other filters – a so-called \"`garbage matte`_\". \n* Optionally filters the transient areas. (3.7.4-)\n\nSee also: :doc:`AddBorders <addborders>`, which increases frame size. \n**Letterbox** does not change frame size.\n\nActually, the functionality of **Letterbox** is performed with a combination of \n:doc:`Crop <crop>` and :doc:`AddBorders <addborders>`, but **Letterbox** is \neasier to use.\n\nGenerally, it's better to **Crop** video noise off than to black it out; many \nolder lossy compression algorithms don't deal well with solid-color borders, \nunless the border happens to fall on a `macroblock`_ boundary (16 pixels for \nMPEG). However, in some cases, particularly for certain hardware players, it's \nbetter to use **Letterbox** because it lets you keep a standard frame size. \n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    Letterbox (clip, int top, int bottom, int \"x1\", int \"x2\", int \"color\", int \"color_yuv\"\n               string \"resample\", float \"param1\", float \"param2\", float \"param3\", int \"r\" )\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n.. describe:: top, bottom\n\n    Number of *top* and *bottom* rows to blank out.\n\n    * For YUV420 sources, top and bottom must be `mod2`_ (divisible by 2).\n\n    ``top+bottom`` must be less than the frame height, or else the first phase (Crop) would \n    result in error with a zero-height clip.\n\n.. describe:: x1, x2\n\n    Number of *left* (``x1``) and *right* (``x2``) columns to blank out.\n\n    * For YUV422 and YUV420 sources, left and right must be `mod2`_ (divisible by 2).\n    * For YUV411 sources, left and right must be `mod4`_ (divisible by 4).\n\n    ``x1+x2`` must be less than the frame width, or else the first phase (Crop) would \n    result in error with a zero-width clip.\n\n    Default: 0, 0\n\n.. describe:: color\n\n    | Fill color specified as an RGB value in either hexadecimal or decimal \n      notation.\n    | Hex numbers must be preceded with a $. See the\n      :doc:`colors <../syntax/syntax_colors>` page for more information on \n      specifying colors.\n\n    * For YUV clips, colors are converted from full range (0–255) to limited \n      range (16–235) `Rec.601`_.\n    * Use ``color_yuv`` to specify full range YUV values or a color with a \n      different matrix.\n\n    Default: $000000\n\n.. describe:: color_yuv\n\n    | Specifies the color of the border using YUV values. Input clip must be YUV,\n      otherwise it does nothing. \n    | Similar to ``color_yuv`` in :doc:`BlankClip <blankclip>` \n\n.. describe:: resample\n\n    string  resample = \"gauss\"\n\n    When `r` radius is not zero, then determines which resampler is used in the transient filtering. \n    \n    Default is \"gauss\". \n    \n    For detailed description see :doc:`AddBorders <addborders>`.\n\n\n.. describe:: param1, param2, param3\n\n    These 'float' type parameters can be the additional parameters for the\n    resampler. \n\n    For detailed description see :doc:`AddBorders <addborders>`.\n\n.. describe:: r\n    \n    int  r = 0\n\n    The radius of the transient treatment in pixels. The value is meant as +/- around the border line.\n    \n    For detailed description see :doc:`AddBorders <addborders>`.\n\n\nChangelog\n----------\n\n+-----------------+---------------------------------------------------------------+\n| Version         | Changes                                                       |\n+=================+===============================================================+\n| 3.7.4           | Add filtering. resample, param1, param2, param3, r parameters |\n+-----------------+---------------------------------------------------------------+\n| AviSynth+ 3.4.1 | Added ``color_yuv`` option.                                   |\n+-----------------+---------------------------------------------------------------+\n| AviSynth+ r2487 | Added support for RGB48/64 and all Planar RGB(A)/YUV(A) color |\n|                 | formats.                                                      |\n+-----------------+---------------------------------------------------------------+\n| AviSynth 2.0.7  | Added ``color`` option.                                       |\n+-----------------+---------------------------------------------------------------+\n| AviSynth 2.0.6  | Added optional left and right parameters (``x1`` and ``x2``). |\n+-----------------+---------------------------------------------------------------+\n\n$Date: 2025/03/14 14:00:00 $\n\n.. _VHS:\n    https://en.wikipedia.org/wiki/VHS\n.. _overscan:\n    https://en.wikipedia.org/wiki/Overscan#Overscan_amounts\n.. _VCD:\n    https://en.wikipedia.org/wiki/Video_CD\n.. _SVCD:\n    https://en.wikipedia.org/wiki/Super_Video_CD\n.. _garbage matte:\n    https://en.wikipedia.org/wiki/Matte_(filmmaking)#Garbage_and_holdout_mattes\n.. _macroblock:\n    https://en.wikipedia.org/wiki/Macroblock\n.. _mod2:\n    http://avisynth.nl/index.php/Modulo\n.. _mod4:\n    http://avisynth.nl/index.php/Modulo\n.. _Rec.601:\n    https://en.wikipedia.org/wiki/Rec._601\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/levels.rst",
    "content": "======\nLevels\n======\n\nAdjusts brightness, contrast, and gamma. This is done using the following\n*transfer* function:\n\n.. math::\n\n    \\mathsf{output = ( (input - input\\_low) / (input\\_high - input\\_low) )\n    ^{(1 / gamma)} * (output\\_high - output\\_low) + output\\_low}\n\n* ``input_low`` and ``input_high`` determine what input pixel values are treated\n  as pure black and pure white.\n* ``output_low`` and ``output_high`` determine what output values are treated as\n  pure black and pure white.\n* ``gamma`` controls the degree of non-linearity in the conversion.\n\nThis is one of those filters for which it would really be nice to have a GUI.\nSince we can't offer a GUI (though `AvsPmod`_ does), we at least make this filter\ncompatible with `VirtualDub`_'s when the clip is RGB. In that case you should be\nable to take the numbers from VirtualDub's Levels dialog and pass them as\nparameters to the **Levels** filter and get the same results. Unlike VirtualDub's\nfilter however, the input and output parameters can be larger than the maximum\nvalue of the pixel format (for example, in 8-bit it can be greater than 255, see\ntable below).\n\nWhen processing data in YUV mode, **Levels** only gamma-corrects the luma\ninformation, not the chroma. Gamma correction is really an RGB concept, and is\nonly approximated here in YUV. If ``gamma=1.0`` (unity), the filter should have\nthe same effect in both RGB and YUV modes. For adjusting brightness or contrast\nin YUV mode, it *may* be better (depending on the effect you are looking for) to\nuse :doc:`tweak` or :doc:`coloryuv`, because **Levels** changes the chroma of\nthe clip.\n\nNote in AviSynth+, the parameters ``input_low``, ``input_high``, ``output_low``\nand ``output_high``:\n\n* are float instead of int.\n* are not `autoscaling`_ – they are relative to the current bit depth:\n\n .. table::\n  :widths: auto\n\n  +--------+------+---------+----------+----------+--------+\n  | Bits   | Min. |                               | Max.   |\n  +========+======+=========+==========+==========+========+\n  | **8**  | 0    | 16      | 128      | 235      | 255    |\n  +--------+------+---------+----------+----------+--------+\n  | **10** | 0    | 64      | 512      | 940      | 1023   |\n  +--------+------+---------+----------+----------+--------+\n  | **12** | 0    | 256     | 2048     | 3760     | 4095   |\n  +--------+------+---------+----------+----------+--------+\n  | **14** | 0    | 1024    | 8192     | 15040    | 16383  |\n  +--------+------+---------+----------+----------+--------+\n  | **16** | 0    | 4096    | 32768    | 60160    | 65535  |\n  +--------+------+---------+----------+----------+--------+\n  | **32** | 0    | 16/255  | 128/255  | 235/255  | 1.0    |\n  +--------+------+---------+----------+----------+--------+\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    Levels (clip input, float input_low, float gamma, float input_high, float output_low, float output_high,\n            bool \"coring\", bool \"dither\")\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n.. describe:: input_low\n\n    | Input values at ``input_low`` or lower are treated as black, and lighter\n      colors are darkened proportionally.\n    | Therefore, raising ``input_low`` darkens the output.\n\n.. describe:: gamma\n\n    | `Gamma`_ adjustment. See `examples`_.\n    | Higher ``gamma`` brightens the output; lower ``gamma`` darkens the output.\n\n.. describe:: input_high\n\n    | Input values at ``input_high`` or higher are treated as *white*, and\n      darker colors are brightened proportionally.\n    | Therefore, lowering ``input_high`` brightens the output.\n\n.. describe:: output_low\n\n    Dark values brighten to gray as ``output_low`` becomes larger.\n\n.. describe:: output_high\n\n    Light values darken to gray as ``output_high`` becomes smaller.\n\n.. describe:: coring\n\n    For RGB this parameter is ignored and internally set to false. For Y and YUV,\n    when true (default),\n\n    #. input clip is clamped to limited range (e.g. in 8-bit, 16-235 for luma\n       and 16-240 for chroma);\n    #. this clamped input is scaled from limited range back to full range,\n    #. the conversion takes place according to the transfer function above, and then\n    #. output is scaled back to limited range.\n\n    When false, the conversion takes place according to the transfer function,\n    without any scaling.\n\n    .. note::\n\n       ``coring`` was created for VirtualDub compatibility, and it remains true\n       by default for compatibility with older scripts.\n\n       In the opinion of some, you should `always use coring=false`_ if you are\n       working directly with luma values (whether or not your input is limited\n       range).\n\n       Limited range video can be correctly processed with ``coring=false``; for\n       example::\n\n            Levels(0, 1.6, 255, 0, 255, coring=true)\n\n       Produces the same result as::\n\n            Levels(16, 1.6, 235, 16, 235, coring=false)\n\n       Except that the output is not clipped to limited range. Black and white\n       levels are preserved while adjusting ``gamma``, unlike::\n\n            Levels(0, 1.6, 255, 0, 255, coring=false)\n\n.. describe:: dither\n\n    When true, `ordered dithering`_ is applied to combat `banding`_.\n\n    Default: false\n\n\nExamples\n--------\n\n::\n\n    # does nothing on a [16,235] clip, but it clamps (or rounds) a [0,255] clip to [16,235]:\n    Levels(0, 1, 255, 0, 255)\n\n::\n\n    # the input is scaled from [16,235] to [0,255],\n    # the conversion [0,255]->[16,235] takes place (accordingly to the formula),\n    # and the output is scaled back from [0,255] to [16,235]:\n    # (for example: the luma values in [0,16] are all converted to 30)\n    Levels(0, 1, 255, 16, 235)\n\n::\n\n    # gamma-correct image for display in a brighter environment:\n    # example: luma of 16 stays 16, 59 is converted to 79, etc.\n    Levels(0, 1.3, 255, 0, 255)\n\n::\n\n    # invert the image (make a photo-negative):\n    # example: luma of 16 is converted to 235\n    Levels(0, 1, 255, 255, 0)\n\n::\n\n    # does nothing on a [0,255] clip; does nothing on a [16,235]:\n    Levels(0, 1, 255, 0, 255, coring=false)\n\n::\n\n    # scales a [0,255] clip to [16,235]:\n    Levels(0, 1, 255, 16, 235, coring=false)\n    # note both luma and chroma components are scaled by the same\n    # amount, so it's not exactly the same as ColorYUV(levels=\"PC->TV\")\n\n::\n\n    # scales a [16,235] clip to [0,255]:\n    Levels(16, 1, 235, 0, 255, coring=false)\n    # note both luma and chroma components are scaled by the same\n    # amount, so it's not exactly the same as ColorYUV(levels=\"TV->PC\")\n\n::\n\n    # makes a clip 100% black\n    Levels(0, 1.0, 255, 0, 0)\n\n::\n\n    # apply fading on gamma corrected source (same holds for resizing and smoothing)\n    clip = ...\n    gamma = 2.2\n    clip.Levels(0, gamma, 255, 0, 255) # undo gamma (also called gamma correction)\n    FadeOut(n)\n    Levels(0, 1.0/gamma, 255, 0, 255) # redo gamma\n    ## use bit depth >= 10 to avoid banding in dark areas\n\n\nChangelog\n----------\n\n.. table::\n    :widths: auto\n\n    +-----------------+----------------------------------------------------------------+\n    | Version         | Changes                                                        |\n    +=================+================================================================+\n    | AviSynth+ r2542 | Added 32 bit float support.                                    |\n    +-----------------+----------------------------------------------------------------+\n    | AviSynth+ r2487 || Added 10-16 bit support for YUV(A) and planar RGB(A) formats. |\n    |                 || Added support for RGB48/64 formats.                           |\n    +-----------------+----------------------------------------------------------------+\n    | AviSynth 2.6.0  || Added ``dither`` parameter.                                   |\n    |                 || Added support for Y8, YV16, YV24 and YV411 formats.           |\n    +-----------------+----------------------------------------------------------------+\n    | AviSynth 2.5.3  | Added ``coring`` parameter.                                    |\n    +-----------------+----------------------------------------------------------------+\n\n$Date: 2025-02-25 17:40:16-05:00 $\n\n.. _AvsPmod:\n    https://forum.doom9.org/showthread.php?t=175823\n.. _Gamma:\n    https://en.wikipedia.org/wiki/Gamma_correction\n.. _VirtualDub:\n    http://avisynth.nl/index.php/VirtualDub2\n.. _autoscaling:\n    http://avisynth.nl/index.php/Autoscale_parameter\n.. _always use coring=false:\n    https://web.archive.org/web/20160825211112/http://forum.doom9.org/showthread.php?p=1722885#post1722885\n.. _ordered dithering:\n    http://avisynth.nl/index.php/Ordered_dithering\n.. _banding:\n    https://en.wikipedia.org/wiki/Colour_banding\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/limiter.rst",
    "content": "\nLimiter\n=======\n\n``Limiter`` (clip, int \"min_luma\", int \"max_luma\", int \"min_chroma\", int\n\"max_chroma\", string \"show\")\n\nThis filter is present in *v2.5*. The standard known as CCIR-601 defines the\nrange of pixel values considered legal for presenting on a TV. These ranges\nare 16-235 for the luma component and 16-240 for the chroma component.\n\nPixels outside this range are known to cause problems with some TV sets, and\nthus it is best to remove them before encoding if that is your intended\ndisplay device. By default this filter clips (or \"clamps\") pixels under 16 to\n16 and over 235 (or 240) to 235 (or 240).\n\nPrior to *v2.53* the (incorrect) default value was 236. Use Limiter(16, 235,\n16, 240) for CCIR-601 compliant digital video.\n\nIn  *v2.56*, an option *show* is added. If set, it colors the pixels outside\nthe specified [min_luma,max_luma] or [min_chroma,max_chroma] range.\n\n*show* can be \"luma\" (shows out of bounds luma in red/green), \"luma_grey\"\n(shows out of bounds luma and makes the remaining pixels greyscale), \"chroma\"\n(shows out of bounds chroma in yellow), \"chroma_grey\" (shows out of bounds\nchroma and makes the remaining pixels greyscale). The coloring is done as\nfollows:\n\n| YUY2 (chroma shared between two horizontal pixels p1 and p2: Y1UY2V): j,k=1,2\n| YV24 (no chroma shared): j,k=1\n| YV12 (chroma shared between 2x2 pixels Y11UY12V; Y21UY22V): j,k=11,12,21,22\n\n+-----------------------------------+--------------+-----------------------+\n|                                   | luma         | luma_grey             |\n+===================================+==============+=======================+\n| Yj < min_luma                     | red (pj)     | red (pj)              |\n+-----------------------------------+--------------+-----------------------+\n| Yj > max_luma                     | green (pj)   | green (pj)            |\n+-----------------------------------+--------------+-----------------------+\n| Yj < min_luma and Yk > max_luma   | yellow (all) | puke (pj), olive (pk) |\n+-----------------------------------+--------------+-----------------------+\n\n+-----------------------------------+--------------+-----------------------+\n|                                   | chroma       | chroma_grey           |\n+===================================+==============+=======================+\n| U < min_chroma                    | yellow       | yellow                |\n+-----------------------------------+--------------+-----------------------+\n| U > max_chroma                    | yellow       | blue                  |\n+-----------------------------------+--------------+-----------------------+\n| V < min_chroma                    | yellow       | cyan                  |\n+-----------------------------------+--------------+-----------------------+\n| V > max_chroma                    | yellow       | red                   |\n+-----------------------------------+--------------+-----------------------+\n| U < min_chroma and V < min_chroma | yellow       | green                 |\n+-----------------------------------+--------------+-----------------------+\n| U > max_chroma and V < min_chroma | yellow       | teal                  |\n+-----------------------------------+--------------+-----------------------+\n| U < min_chroma and V > max_chroma | yellow       | orange                |\n+-----------------------------------+--------------+-----------------------+\n| U > max_chroma and V > max_chroma | yellow       | magenta               |\n+-----------------------------------+--------------+-----------------------+\n\n+-----------+----------------------------------------------+\n| Changelog |                                              |\n+===========+==============================================+\n| v2.60     | Added show for YV24.                         |\n+-----------+----------------------------------------------+\n| v2.56     | added show to show out of bounds luma/chroma |\n+-----------+----------------------------------------------+\n\n$Date: 2012/04/09 08:19:32 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/loop.rst",
    "content": "\nLoop\n====\n\nLoops the segment from frame *start* to frame *end* a given number of times.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    Loop (clip, int \"times\", int \"start\", int \"end\")\n\n.. describe:: clip\n\n    Source clip.\n\n.. describe:: times\n\n    The number of times the loop is applied.\n\n    Setting ``times`` to -1 loops a \"very large\" number of times.\n\n    Default: -1\n\n.. describe:: start\n\n    The frame of the clip where the loop starts.\n\n    Default: 0\n\n.. describe:: end\n\n    The frame of the clip where the loop ends.\n\n    Default: FrameCount(clip)\n\n\nExamples\n--------\n\n::\n\n    Loop()                           # play the clip (almost) endlessly.\n    Loop(times=-1)                   # play the clip (almost) endlessly.\n    \n    Loop(times=10)                   # play the clip ten times.\n    \n    Loop(times=-1, start=20, end=29) # play up to frame 19;\n                                     # frames 20-29 are repeated (almost) infinite times. \n    \n    Loop(times=2, start=20, end=29)  # play up to frame 19; \n                                     # play frames 20-29 two times; \n                                     # continue from frame 30 to end of clip. \n    \n    Loop(times=10, start=20, end=29) # play up to frame 19; \n                                     # play frames 20-29 ten times; \n                                     # continue from frame 30 to end of clip. \n    \n    Loop(times=0, start=20, end=29)  # play up to frame 19;\n                                     # delete frames 20-29 (play them zero times); \n                                     # continue to end of clip. \n    \n    Loop(times=1, start=20, end=29)  # play all frames normally. \n\n\n$Date: 2022/02/04 22:44:06 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/mask.rst",
    "content": "============\nMask Filters\n============\n\nSet of filters to manipulate the alpha channel:\n\n* `AddAlphaPlane`_ adds or replaces an alpha plane.\n* `RemoveAlphaPlane`_ removes an alpha plane.\n* `Mask`_ also replaces an alpha plane but works different than `AddAlphaPlane`_.\n* `ResetMask`_ by default sets all pixel values in the alpha plane to the\n  maximum value.\n* `ColorKeyMask`_ is a simple color keying filter, it sets transparency in the\n  alpha channel in areas where the specified color meets the criteria.\n\n.. _AddAlphaPlane:\n\nAddAlphaPlane\n-------------\n**AddAlphaPlane** adds an alpha plane to the source clip. It can also be used to\nreplace the existing alpha plane of the source clip. Note that the color format\nchanges after using ``AddAlphaPlane()`` on an alpha-less format, for example,\nRGBP16 becomes RGBAP16.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    AddAlphaPlane (clip, clip mask)\n    AddAlphaPlane (clip, float mask)\n    AddAlphaPlane (clip, int mask)\n    AddAlphaPlane (clip, float \"opacity\")\n\n.. describe:: clip\n\n    Source clip; RGB24, RGB32, RGB48, RGB64, and all Planar RGB(A) and YUV(A)\n    formats supported.\n\n.. describe:: mask\n\n    The ``mask`` parameter can be specified in 3 different ways, as a clip, an\n    integer or a float value.\n    \n    **Clip:** The alpha source clip can either be a single channel greyscale (Y) \n    or an alpha capable format (such as RGBAP8 or RGB64). If a clip is supplied,\n    depending on the type, either the greyscale clip or the alpha channel is\n    then copied onto the alpha channel of the source clip. The alpha source\n    clip must be the same bit depth and dimensions as the source clip.\n    \n    **Pixel value (integer or float):** If the numeric-type mask parameter is\n    supplied, it will be used as filler value of the resulting alpha plane. No\n    bit depth scaling happens, parameter value is used as-is. For reference,\n    the table below shows all of the maximum values in regards to bit depth.\n    \n    .. table::\n        :widths: auto\n\n        +-------+--------+--------+--------+--------+--------+\n        | 8-bit | 10-bit | 12-bit | 14-bit | 16-bit | 32-bit |\n        +-------+--------+--------+--------+--------+--------+\n        | 255   | 1023   | 4095   | 16383  | 65535  | 1.0    |\n        +-------+--------+--------+--------+--------+--------+\n\n    A value of 0 creates a fully transparent mask (black) and the maximum pixel\n    value creates a completely opaque mask (white). Range for all bit depths is\n    from 0 to the max value. 32-bit Float clips are specified in the range of\n    [0.0 - 1.0].\n    \n    Example for 8-bit: ``mask=128`` sets the alpha channel to 128 (50% opacity).\n    \n    Note: Cannot be used together with ``opacity`` parameter.\n\n.. describe:: opacity\n\n    Sets the opacity level in the range of [0.0 - 1.0], where:\n    \n    - **opacity = 1.0** means fully **opaque** (completely visible, white mask)\n    - **opacity = 0.0** means fully **transparent** (invisible, black mask)\n    \n    This parameter is more intuitive than ``mask`` as it automatically scales to \n    the correct bit depth.\n    \n    Example for 8-bit: ``opacity=0.5`` automatically sets the alpha channel to \n    128 (which is 0.5 × 255).\n    \n    Note: Cannot be used together with ``mask`` parameter. To set the alpha \n    channel to the maximum value, it's easier to use `ResetMask`_.\n\n\n.. _RemoveAlphaPlane:\n\nRemoveAlphaPlane\n----------------\n\n**RemoveAlphaPlane** removes the alpha plane from the source clip. Note that the\ncolor format changes after using ``RemoveAlphaPlane()``, for example, YUVA444P8\nbecomes YUV444P8.\n\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    RemoveAlphaPlane (clip)\n\n.. describe:: clip\n\n    Source clip; RGB32, RGB64, and all Planar RGBA and YUVA formats supported.\n\n.. _Mask:\n\nMask\n----\n\n**Mask** replaces the alpha channel in the source clip with a \"luma mask\"\ncreated from the specified mask clip. Internally the mask clip is converted to\ngreyscale (``ConvertToY(matrix=\"PC.601\")``), this result is then used to replace\nthe alpha plane in the source clip. Note that **Mask** is a legacy filter, the\nintended use was to convert a greyscale RGB clip that consisted of 3 identical\nchannels to an alpha channel. Using `AddAlphaPlane`_ is recommended.\n\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    Mask (clip, clip mask)\n\n.. describe:: clip\n\n    Source clip; RGB32, RGB64, and all Planar RGBA formats supported.\n\n.. describe:: mask\n\n    Mask clip to replace the alpha channel in the source clip. The dimensions\n    and bit depth must be the same as the source clip. The alpha channel in this\n    clip is ignored.\n\n.. _ResetMask:\n\nResetMask\n---------\n**ResetMask** by default sets all of the pixels in the alpha channel to the\nmaximum value, effectively making it white (completely opaque).\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    ResetMask (clip, float \"mask\", float \"opacity\")\n\n.. describe:: clip\n\n    Source clip; RGB32, RGB64, and all Planar RGBA and YUVA formats supported.\n\n.. describe:: mask\n\n    Sets the pixel value of the mask channel directly. By default, it is set to \n    the maximum value of the pixel format. For reference, the table below shows \n    all of the maximum values in regards to bit depth.\n\n    .. table::\n        :widths: auto\n\n        +-------+--------+--------+--------+--------+--------+\n        | 8-bit | 10-bit | 12-bit | 14-bit | 16-bit | 32-bit |\n        +-------+--------+--------+--------+--------+--------+\n        | 255   | 1023   | 4095   | 16383  | 65535  | 1.0    |\n        +-------+--------+--------+--------+--------+--------+\n\n    A value of 0 creates a fully transparent mask (black) and the maximum pixel\n    value creates a completely opaque mask (white). Range for all bit depths is\n    from 0 to the max value. 32-bit Float clips are specified in the range of\n    [0.0 - 1.0].\n    \n    Note: No bit-depth scaling occurs; the parameter value is used as-is.\n    \n    Example for 8-bit: ``mask=128`` sets the alpha channel to 128 (50% opacity).\n\n.. describe:: opacity\n\n    Sets the opacity level in the range of [0.0 - 1.0], where:\n    \n    - **opacity = 1.0** means fully **opaque** (completely visible, white mask)\n    - **opacity = 0.0** means fully **transparent** (invisible, black mask)\n    \n    This parameter is more intuitive than ``mask`` as it automatically scales to \n    the correct bit depth. When ``opacity`` is specified, it overrides ``mask``.\n    \n    Example for 8-bit: ``opacity=0.5`` automatically sets the alpha channel to \n    128 (which is 0.5 × 255).\n    \n    Default: 1.0 (fully opaque)\n\n\n.. _ColorKeyMask:\n\nColorKeyMask\n------------\n\nClears pixels in the alpha channel by comparing the specified color. Each pixel\nwith a color differing less than the tolerance is set to zero (that is black\nor transparent), otherwise it is left unchanged. i.e. It is NOT set to opaque\n(white). To start off with a fully opaque mask, use `ResetMask`_ beforehand,\nthis allows an aggregate mask to be constructed with multiple calls to\n**ColorKeyMask** to build up transparent areas where each color of interest\noccurs. To view or extract the mask use :doc:`ShowAlpha <showalpha>` or the\n:doc:`Extract <extract>` filters. See the :ref:`examples <ColorKeyMask-example>`\nsection for more information.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    ColorKeyMask (clip, int color[, int tolB, int tolG, int tolR])\n\n.. describe:: clip\n\n    Source clip; RGB32, RGB64 and all Planar RGBA formats supported.\n\n.. describe:: color\n\n    Specify the color to compare. Color is specified as an RGB value in either\n    hexadecimal or decimal notation. Hex numbers must be preceded with a $. See\n    the :doc:`colors <../syntax/syntax_colors>` page for more information on\n    specifying colors.\n\n\n.. describe:: tolB, tolG, tolR\n\n    Tolerance specifies the range for which close colors are considered the same.\n    The range is from 0 to 255 and the values are autoscaled for bit depths\n    greater than 8 bit. Note that these parameters are unnamed, however they do\n    have a default. When ``tolR`` or ``tolG`` are not set, they use the value\n    from ``tolB``. When ``tolB`` is not defined, it defaults to 10.\n\nNote 1: ``color``, ``tolB``, ``tolG`` and ``tolR`` parameters are unnamed.\n\nNote 2: ``color`` and tolerance parameters are the same as for 8 bit RGB32. \nInternally they are automatically scaled to the current bit-depth.\n\nExamples\n--------\n\n.. rubric:: AddAlphaPlane\n\nLet's create some colorful text using :doc:`ColorBars <colorbars>`,\n:doc:`Subtitle <subtitle>` and `AddAlphaPlane`_ and then save it to a png:\n\n.. code-block:: c++\n\n    src = ColorBars(width=256, height=192, pixel_type=\"RGB32\").Crop(0,0,0,-143)\n    msk = BlankClip(src).Subtitle(\"AviSynth+\", size=55, align=2, text_color=$FFFFFF).ExtractR()\n\n    AddAlphaPlane(src, msk)\n    ImageWriter(\"colorful text\", type=\"png\")\n\n.. list-table::\n\n   * - .. figure:: pictures/addalphaplane-colorfultext.png\n\n          Result\n\nNow suppose that you made a mask in an image editor and want to load it in\nAviSynth to use it as an alpha for a clip. The process is similar to the\nprevious example::\n\n    src = FFVideoSource(video.mkv)\n    msk = FFImageSource(\"mask.png\").ExtractR() # see note below\n\n    AddAlphaPlane(src, msk)\n\nIf the mask was saved as a single channel greycale (Y) image or if the mask is\nin the alpha channel then :doc:`ExtractR() <extract>` is not needed.\n\n.. _ColorKeyMask-example:\n\n.. rubric:: ColorKeyMask\n\nLet's use `ColorKeyMask`_ to remove the background and then :doc:`overlay` the\nresult over a :doc:`ColorBars <colorbars>` clip:\n\n.. code-block:: c++\n\n    src  = ImageSource(\"colorkeymask-dog.png\")\n    base = ColorBars(width=src.Width(), height=src.Height())\n\n    ResetMask(src)\n    ColorKeyMask($F22E42, 25)\n    ColorKeyMask($DC2026, 25)\n    ColorKeyMask($B92708, 25)\n\n    # MaskTools2: mt_inpand shrinks the mask and mt_deflate feathers the mask outward.\n    msk = ExtractA().mt_inpand().mt_inflate().mt_inflate()\n\n    Overlay(base, src, mask=msk)\n\n    # To use Layer instead, comment out Overlay and use the following commands.\n    # src = AddAlphaPlane(src, msk)\n    # Layer(base, src)\n\n.. list-table::\n\n   * - .. figure:: pictures/colorkeymask-dog.png\n\n          `Source`_\n\n     - .. figure:: pictures/colorkeymask-dog-result.png\n\n          Result\n\nThe result is by no means perfect, but it gives the general idea of how to use\nthe ColorKeyMask filter. There are more intricate ways of improving the result,\nfor example:\n\n* Lightly denoising the source clip prior to ColorKeyMask often helps\n  (specially with noisy sources). Scaling the source clip to a lower resolution\n  can also be beneficial. Both methods help reduce variations in the target color,\n  leading to lower tolerance values.\n* Scaling the source clip to a higher resolution prior to ColorKeyMask can help\n  retain finer details in the mask, like stray hairs or edges.\n* Using color correction filters to reduce some of the color spill. This sometimes\n  requires multipass masking and layering that target only the troublesome areas.\n* And then there is `MaskTools2`_ which includes various filters for dealing\n  with masks, as shown in the example above.\n\nIt should be noted that ColorKeyMask is a primitive color keying filter, if the\nend goal is green screen removal (`chroma keying`_), it may not be the best\noption. There is dedicated software that handle this type of task much better,\nas discussed in the \"`Chaining calls to ColorKeyMask`_\" VideoHelp thread.\n\n\nChangelog\n---------\n\n+-----------------+-------------------------------------------------------------+\n| Version         | Changes                                                     |\n+=================+=============================================================+\n| AviSynth+ r2487 || Mask: support RGB64 and all Planar RGBA formats.           |\n|                 || ColorKeyMask: support RGB64 and all Planar RGBA formats.   |\n|                 || ResetMask: support RGB64 and all Planar RGBA/YUVA formats. |\n|                 || ResetMask: new ``mask`` parameter.                         |\n|                 || New filters: AddAlphaPlane and RemoveAlphaPlane.           |\n+-----------------+-------------------------------------------------------------+\n| AviSynth 2.5.8  | ColorKeyMask: Allow independant tolerance levels for each   |\n|                 | channel.                                                    |\n+-----------------+-------------------------------------------------------------+\n| AviSynth 2.0.6  | Added ResetMask filter.                                     |\n+-----------------+-------------------------------------------------------------+\n| AviSynth 2.0.3  | Added ColorKeyMask filter.                                  |\n+-----------------+-------------------------------------------------------------+\n\n$Date: 2022/03/30 15:25:39 $\n\n.. _chroma keying:\n    https://en.wikipedia.org/wiki/Chroma_key\n.. _Source:\n    https://www.pexels.com/photo/banana-peel-on-the-head-of-a-french-bulldog-4587982/\n.. _MaskTools2:\n    http://avisynth.nl/index.php/MaskTools2\n.. _Chaining calls to ColorKeyMask:\n    https://forum.videohelp.com/threads/380989-Chaining-calls-to-ColorKeyMask-in-Avisynth"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/maskhs.rst",
    "content": "======\nMaskHS\n======\n\nReturns a mask (as greyscale Y) of clip using a given hue and saturation range.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    MaskHS (clip, float \"startHue\", float \"endHue\", float \"maxSat\", float \"minSat\", bool \"coring\", bool \"realcalc\")\n\n.. describe:: clip\n\n    Source clip. All YUV(A) color formats supported.\n\n    Note that the output size of the mask depends on the color format of the\n    source clip. For example, if the clip is YUV420, the mask will be half the\n    size. If needed, use :doc:`ConvertToYUV444 <convert>` beforehand to output\n    a full size mask.\n\n.. describe:: startHue, endHue\n\n    The resulting mask will contain source values in the range [``startHue``,\n    ``endHue``] when ``startHue``\\ <\\ ``endHue``. Note that the hue is periodic,\n    thus a hue of 360 degrees corresponds with a hue of zero degrees.\n\n    If ``endHue``\\ <\\ ``startHue`` then the range [``endHue``, 360] and\n    [0, ``startHue``] will be selected (thus anti-clockwise). If you need to\n    select a range of [350, 370] for example, you need to specify\n    ``startHue``\\ =370, ``endHue``\\ =350.\n\n    | Range: 0 to 360 (degrees)\n    | Default: 0, 360; thus, when using the default values, all pixels will be\n      processed.\n\n    The following shows some arbitrary ``startHue`` and ``endHue`` values for\n    the basic colors, with a Histogram vectorscope to illustrate the color circle:\n\n    .. image::  pictures/maskhs-table.png\n\n.. describe:: maxSat, minSat\n\n    The resulting mask will contain source values in the range\n    [``minSat``, ``maxSat``].\n\n    Practically the saturation of a pixel will be in the range [0,100]\n    (thus 0-100%), since these correspond to valid RGB pixels (100% corresponds\n    to R=255, G=B=0, which has a saturation of 119). An overshoot (up to 150%)\n    is allowed for non-valid RGB pixels (150% corresponds to U=V=255, which has\n    a saturation of sqrt(127\\ :sup:`2` \\+127\\ :sup:`2`) = 180).\n\n    Default: 150, 0\n\n.. describe:: coring\n\n    When set to true, the luma (Y) is clipped to limited range (TV); when set\n    to false, the luma is left untouched.\n\n    Default: true\n\n.. describe:: realcalc\n\n    By default, **MaskHS** uses a `LUT`_ for 8/10/12 bits. For bit depths greater\n    than 12, the calculation for each pixel is always done in realtime. When\n    ``realcalc=true``, it overrides using a LUT and calculates each pixel\n    on-the-fly.\n\n    Default: false\n\n\nExamples\n--------\n\nSuppose we want to create a mask of the skin of the girl below. The proper way\nto do this is to look at the vectorscope of :doc:`Histogram <histogram>`:\n\n.. list-table::\n\n    * - .. figure:: pictures/tweak_original2_plus_hist.jpg\n\n        ::\n\n            clip = FFImageSource(\"tweak_original2.jpg\")\n            Histogram(clip, mode=\"color2\")\n\n\nand estimate the hue range you want to select. As can be seen, the orange hue\nis between (about) 105 and 165 degrees.\n\n*Note: axis labels have been added to the vectorscope as a guide – they are\nnot generated by the above script.*\n\nStart with a wide hue range and narrow it until the output of **MaskHS**\nisolates the range of interest. You can also use :doc:`Tweak <tweak>` to preview\nthe affected range (with *sat* \\=0), as the arguments are compatible.\n\nIn our example we end at ``startHue=105, endHue=138``, and the following mask\nis obtained:\n\n.. list-table::\n\n    * - .. figure::  pictures/tweak_original2.jpg\n\n           Original: *tweak_original2.jpg*\n\n      - .. figure:: pictures/maskhs-mask.png\n\n           ``MaskHS(startHue=105, endHue=138)``\n\n.. rubric:: Another example:\n\nLooking at the blue screen example in :doc:`Overlay <overlay>`, the following\ncan be used::\n\n    testcard = ColorBars()\n\n    # example subtitle file with blue background:\n    subs = FFImageSource(\"overlay_blue.jpg\").ConvertToYV24()\n\n    # subs.Histogram(mode=\"color2\").ConvertToRGB # blue in [345,359]\n    mask_hs = subs.MaskHS(startHue=340, endHue=359).Invert()\n\n    Overlay(testcard, subs, mask=mask_hs, mode=\"blend\", opacity=1)\n\n\nChangelog\n---------\n\n.. table::\n    :widths: auto\n\n    +-----------------+-------------------------------------------------------------+\n    | Version         | Changes                                                     |\n    +=================+=============================================================+\n    | AviSynth+ r2487 || Added support for 10-16bit and float YUV(A) color formats. |\n    |                 || Added ``realcalc`` parameter.                              |\n    +-----------------+-------------------------------------------------------------+\n    | AviSynth 2.6.0  | Initial Release.                                            |\n    +-----------------+-------------------------------------------------------------+\n\n$Date: 2023/01/19 20:09:50 $\n\n.. _LUT:\n    https://en.wikipedia.org/wiki/Lookup_table\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/merge.rst",
    "content": "=============\nMerge Filters\n=============\n\nSet of filters to merge (blend) two clips together:\n\n* **Merge** merges all channels (RGB(A) or YUV(A)) from one video clip into another.\n* **MergeChroma** merges only the chroma (U/V channels) from one video clip\n  into another.\n* **MergeLuma** merges only the luma (Y channel) from one video clip into\n  another.\n\nThere is an optional weighting, so a percentage between the two clips can be\nspecified.\n\nSyntax and Parameters\n---------------------\n\n::\n\n    Merge (clip clip1, clip clip2, float \"weight\")\n    MergeChroma (clip clip1, clip clip2, float \"weight\")\n    MergeLuma (clip clip1, clip  clip2, float \"weight\")\n\n    MergeChroma (clip clip1, clip clip2, float \"chromaweight\")\n    MergeLuma (clip clip1, clip clip2, float \"lumaweight\")\n\n.. describe:: clip1, clip2\n\n    Source clips:\n\n    * ``clip1``; the clip that has the pixels merged into (the base clip).\n    * ``clip2``; the clip from which the pixel data is taken (the overlay clip).\n    * **Merge** supports all RGB(A)/YUV(A) color formats.\n    * **MergeChroma** and **MergeLuma**, only YUV(A) color formats supported.\n\n    | Clips must have the same color format and dimensions.\n    | Audio, FrameRate and FrameCount are taken from the first clip.\n    | If clips contain an alpha channel, it is also processed.\n\n.. describe:: weight\n\n    Defines how much influence the new clip should have. Range is 0.0–1.0.\n\n    * At 0.0, ``clip2`` has no influence on the output.\n    * At 0.5, the output is the average of ``clip1`` and ``clip2``.\n    * At 1.0, ``clip2`` replaces ``clip1`` completely.\n\n      * For **MergeChroma**, output chroma taken only from ``clip2``.\n      * For **MergeLuma**,  output luma taken only from ``clip2``.\n\n    | Default: 0.5 (Merge)\n    | Default: 1.0 (MergeChroma, MergeLuma)\n\n    Note that the alternate parameter names ``chromaweight`` and ``lumaweight``\n    are considered deprecated.\n\nExamples\n--------\n\n::\n\n    # Blur the Luma channel.\n    MPEG2Source(\"main.d2v\")\n    clipY = Blur(1.0)\n    MergeLuma(clipY)\n\n::\n\n    # Do a spatial smooth on the chroma channel\n    # that will be mixed 50/50 with the original image.\n    MPEG2Source(\"main.d2v\")\n    clipC = SpatialSoften(2,3)\n    MergeChroma(clipC, weight=0.5)\n\n::\n\n    # Run a temporal smoother and a soft spatial\n    # smoother on the luma channel, and a more aggressive\n    # spatial smoother on the chroma channel.\n    # The original luma channel is then added with the\n    # smoothed version at 75%. The chroma channel is\n    # fully replaced with the blurred version.\n    MPEG2Source(\"main.d2v\")\n    clipY = TemporalSoften(2,3).SpatialSoften(3,10,10)\n    clipC = SpatialSoften(3,40,40)\n    MergeLuma(clipY, weight=0.75)\n    MergeChroma(clipC)\n\n::\n\n    # Average two video sources.\n    vid1 = AviSource(\"main.avi\")\n    vid2 = AviSource(\"main2.avi\")\n    Merge(vid1, vid2)\n\n\nChangelog\n---------\n\n+-----------------+-----------------------------------------------------------------+\n| Version         | Changes                                                         |\n+=================+=================================================================+\n| AviSynth+ r2487 || Merge: added planar RGB(A) and YUV(A) support.                 |\n|                 || Merge: SSE2 for 10-14 bits (10-16 for SSE4.1 still work).      |\n|                 || Merge (Merge,MergeChroma/Luma): add AVX2.                      |\n|                 || Merge: float to sse2 (weighted and average).                   |\n+-----------------+-----------------------------------------------------------------+\n| AviSynth+ r2290 | Merge filters: added 16/32 bit support.                         |\n+-----------------+-----------------------------------------------------------------+\n| AviSynth 2.6.0  || MergeChroma and MergeLuma: Added alias ``weight`` for          |\n|                 |  ``chromaweight`` and ``lumaweight``.                           |\n|                 || Added support for Y8, YV16, YV24 and YV411 color formats.      |\n+-----------------+-----------------------------------------------------------------+\n| AviSynth 2.5.6  | Added Merge filter.                                             |\n+-----------------+-----------------------------------------------------------------+\n\n$Date: 2022/03/10 16:46:19 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/mergechannels.rst",
    "content": "\nMergeChannels\n=============\n\nMerge the audio channels of two or more clips.\n\nThere is no *mixing* of channels – :doc:`MixAudio <mixaudio>` and \n:doc:`ConvertToMono <converttomono>` do this. The channels are added to the \nnew clip unchanged.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    MergeChannels (clip1 , clip2 [, clip3, ...])\n\n.. describe:: clip1, clip2, ...\n\n    | Source clips; a minimum of 2 are required.\n    | Output video, framerate and running time are taken from clip1.\n    | All audio is :doc:`converted <convertaudio>` to the sample type of clip1. \n\n\nExamples\n--------\n\nFor example, given the following source clips:\n\n    | A (mono) \n    | B (mono) \n\n...and merging them::\n\n    MergeChannels(A, B)\n\nResults in a clip with the following :doc:`properties <../syntax/syntax_clip_properties>`:\n\n    | video = A \n    | audio channel 1 = A \n    | audio channel 2 = B \n\nThis is equivalent to using :doc:`MonoToStereo <monotostereo>`.\n\n-------------\n\nFor a more complex example, given the following source clips:\n\n    | A and B (stereo) \n    | C and D (mono) \n\n...and merging them::\n\n    MergeChannels(A, B, C, D)\n\nResults in a clip with the following :doc:`properties <../syntax/syntax_clip_properties>`:\n\n    | video = A \n    | audio channel 1 = A channel 1 \n    | audio channel 2 = A channel 2 \n    | audio channel 3 = B channel 1 \n    | audio channel 4 = B channel 2 \n    | audio channel 5 = C \n    | audio channel 6 = D \n\n$Date: 2022/02/08 21:28:07 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/mergergb.rst",
    "content": "\nMergeARGB / MergeRGB\n====================\n\n::\n\n    MergeARGB (clipA, clipR, clipG, clipB [, string \"pixel_type\"])\n    MergeRGB (clipR, clipG, clipB [, string \"pixel_type\"])\n\nMerge the alpha (transparency) and color channels from the source video clips \ninto the output video clip. \n\n*ClipA* is the clip that provided the alpha data to merge into the output clip.\nFor a YUV format input clip the data is taken from the Luma channel. \nFor a planar RGBA or RGB32/64 input clip the data is taken from the Alpha channel. \nIt may not be RGB24/48 or alpha-less planar RGB format.\n\n*ClipR*, *ClipG* and *ClipB* are the clips that provided the R, G and B data\nrespectively to merge into the output clip. For YUV format input clips the\ndata is taken from the Luma channel. For RGB format input clips the data is\ntaken from the respective source channel. i.e. R to R, G to G, B to B. The\nunused chroma or color channels of the input clips are ignored.\n\nAll YUV luma pixel data is assumed to be pc-range, [0..255] (8 bit example, for\nhigher bit depths scaled from ``0`` to ``2^N-1``; or 0.0 to 1.0 when 32 bit float.\nThere is no tv-range, [16..235], scaling. Chroma data from YUV clips is ignored. \nInput clips may be a mixture of all formats, even single greyscale will do.\n\n*pixel_type* default RGB32 or planar RGB (see below the rules), specifies the output format.\nAccept any RGB, or planar RGB(A) pixel_type, plus a special one: \"rgb\".\n\nThe output format is planar rgb(a) (MergeRGB/MergeARGB) when\n\n- pixel_type = \"rgb\" or\n- pixel_type is empty and\n\n  - either input is planar RGB\n  - either input is different from 8 or 16 bits (no packed RGB formats there)\n- pixel_type is explicitely set to a valid planar rgb constant e.g. \"RGBP10\"\n\nOther notes:\n\n- Alpha channel is filled with zero when MergeRGB output pixel_type format is specified to have an alpha plane.\n- Frame property source is the R clip; ``_Matrix`` and ``_ChromaLocation`` are removed if R is not an RGB clip\n\nThe unused channels of the input clips are ignored.\n\nAudio, FrameRate and FrameCount are taken from the first clip. \n\nAlso see :ref:`here <multiclip>` for the resulting clip properties.\n\n**Examples:**\n::\n\n    # This will only blur the Green channel.\n    mpeg2source(\"c:\\apps\\avisynth\\main.d2v\")\n    ConvertToRGB24()\n    MergeRGB(Last, Blur(0.5), Last)\n\n\n    # This will swap the red and blue channels and\n    # load the alpha from a second video sources.\n    vid1 = avisource(\"c:\\apps\\avisynth\\main.avi\")\n    vid2 = avisource(\"c:\\apps\\avisynth\\alpha.avi\")\n    MergeARGB(vid2, vid1.ShowBlue(\"YV12\"), vid1, vid1.ShowRed(\"YV12\"))\n    AudioDub(vid1)\n\n\n+-----------+-----------------------------------------------------------------------------------+\n| Changelog |                                                                                   |\n+===========+===================================================================================+\n| 3.7.2     || add MergeARGB parameter \"pixel_type\", similar to MergeRGB                        |\n|           || accept pixel_type other than 8-bit packed RGB formats, plus a special \"rgb\"      |\n|           || output format can be planar rgb(a)                                               |\n|           || Accept planar RGB clip in place of input clips and the appropriate color plane   |\n|           |  is copied from them                                                              |\n|           || Fill alpha channel with zero when MergeRGB output pixel_type format is specified |\n|           |  to have an alpha plane                                                           |\n|           || frame property source is the R clip; _Matrix and _ChromaLocation are removed if  |\n|           |  R is not an RGB clip                                                             |\n+-----------+-----------------------------------------------------------------------------------+\n| v2.56     | added MergeARGB and MergeRGB                                                      |\n+-----------+-----------------------------------------------------------------------------------+\n\n$Date: 2025/03/07 14:15:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/message.rst",
    "content": "\nMessageClip\n===========\n\n**MessageClip** produces a clip containing a text message. Used internally for \nerror reporting.\n\nThe font face is \"Arial\". The font size is between 24 points and 9 points - \nchosen to fit, if possible, in the width by height clip. The pixeltype is RGB32\nand 240 frames in length.\nOn non-Windows GDI systems fixed Terminus font is used instead.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    MessageClip (string message, int \"width\", int \"height\", bool \"shrink\",\n                 int \"text_color\", int \"halo_color\", int \"bg_color\", bool \"utf8\")\n\n.. describe:: message\n\n    The message to be displayed. Required.\n\n.. describe:: width, height\n\n    Width and height of the resulting clip. By default, the width and height are \n    chosen such that it can display the message with size 24 points.\n    \n    Default: -1, -1\n\n.. describe:: shrink\n\n    | If true, and ``width`` and/or ``height`` are specified, the clip resolution \n      is reduced to a smaller size, if possible, to fit the text.\n    | If false, the text will appear at the top-center of the video frame.\n    \n    Default: false\n\n.. describe:: text_color, halo_color, bg_color\n\n    Colors for font fill, outline and background respectively. See the\n    :doc:`colors <../syntax/syntax_colors>` page for more information on \n    specifying colors. Default text color is yellow and halo and background \n    color are black.\n    \n    Default: $FFFFFF, $000000, $000000\n\n.. describe:: utf8\n\n    | If true, message string is interpreted as an utf8 string.\n    | Available since 3.7.6.\n    \n    Default: false on windows GDI systems, true otherwise\n\nExamples\n--------\n\nDisplaying AviSynth+ version information with ``MessageClip``::\n\n    MessageClip(VersionString)\n    \n.. image:: pictures/messageclip-versionstring.png\n\n\n+------------+--------------------------------+\n| Changelog: |                                |\n+============+================================+\n| 3.7.6      | Added utf8 parameter           |\n+------------+--------------------------------+\n\n$Date: 2025/08/31 17:52:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/mixaudio.rst",
    "content": "========\nMixAudio\n========\n\nMixes audio from two clips. A volume for the two clips can be given, but is\noptional.\n\nSyntax and Parameters\n----------------------\n\n::\n\n    MixAudio (clip1, clip2, float \"clip1_factor\", float \"clip2_factor\")\n\n.. describe:: clip1, clip2\n\n    Source clips; all audio sample types supported. Output video is copied from\n    ``clip1``.\n\n    * The sample rate of the two clips needs to be the same – use\n      :doc:`ResampleAudio <resampleaudio>` if necessary.\n    * The source clips also need to have the same number of channels – use\n      :doc:`ConvertToMono <converttomono>`, :doc:`MonoToStereo <monotostereo>`\n      or :doc:`MergeChannels <mergechannels>` if necessary.\n.. describe:: clip1_factor, clip1_factor\n\n    Set the volume of each clip's audio, where 0.0 is no audio from that clip,\n    and 1.0 is 100% audio.\n\n    * If ``clip1_factor`` + ``clip2_factor`` > 1.0, you risk `clipping`_ the\n      audio if the sample type is not `Float`_.\n    * If only one the first factor is given, the second factor will be\n      (1.0-``clip1_factor``).\n\n    Default: 0.5, (1.0 - ``track1_factor``)\n\n\nExamples\n--------\n\nMixes two sources, with one source slightly lower than the other::\n\n    video = AviSource(\"c:\\movie.avi\")\n    Soundtrack = WavSource(\"c:\\soundtrack.wav\")\n    Speak = WavSource(\"c:\\speak.wav\")\n    audio = MixAudio(Soundtrack, Speak, 0.75, 0.25)\n    return AudioDub(video, audio)\n\nFor this particular example, setting ``clip2_factor`` to 0.25 is redundant. When\nthe second factor is not given, it defaults to ``(1.0 - clip1_factor)``, which\nends up being 0.25.\n\n\nChangelog\n---------\n\n+-----------------+------------------------+\n| Version         | Changes                |\n+=================+========================+\n| AviSynth 2.0.3  | Added MixAudio filter. |\n+-----------------+------------------------+\n\n$Date: 2022/03/24 14:45:27 $\n\n.. _clipping:\n    https://en.wikipedia.org/wiki/Clipping_(audio)\n.. _Float:\n    http://avisynth.nl/index.php/Float\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/monotostereo.rst",
    "content": "\nMonoToStereo\n============\n.. note::\n    Starting from AviSynth v2.5 ``MonoToStereo`` is replaced by \n    :doc:`MergeChannels <mergechannels>`. ``MonoToStereo`` is simply mapped to \n    ``MergeChannels``.\n\n**MonoToStereo** converts two mono signals to one stereo signal. This can be used, \nif one or both channels has been modified separately, and then has to be recombined.\n\nThe sample rate of the two clips need to be the same (use \n:doc:`ResampleAudio <resampleaudio>` if this is a problem). If either of the \nsources are in stereo, the signal will be taken from the corresponding channel \n(left channel from the *left_channel_clip*, and vice versa for the right channel). \n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    MonoToStereo (left_channel_clip, right_channel_clip)\n\n.. describe:: clip\n\n    Source clip; the left channel will be taken from the first clip.\n\n.. describe:: clip\n\n    Source clip; the right channel will be taken from the second clip.\n\n\nExample\n-------\n\nCombines two separate wav sources to a stereo signal::\n\n    left_channel = WavSource(\"c:\\left_channel.wav\")\n    right_channel = WavSource(\"c:\\right_channel.wav\")\n    return MonoToStereo(left_channel, right_channel)\n\n\n$Date: 2022/02/05 21:28:07 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/multioverlay.rst",
    "content": "\nMultiOverlay\n============\n\nThe ``MultiOverlay`` filter allows you to copy and paste one or more source clips onto a \nbase clip. The source clips can be of different sizes, but they must have the same color \nformat as the base clip.\n\nThis filter performs a straightforward BitBlt (copy-paste) operation of the original clips or their sub-areas.\nIt does not support transparency, mask clips, or blending modes—just a simple copy.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    MultiOverlay (clip base_clip, clip overlay_clips[], int overlay_params[] )\n\n.. describe:: base_clip\n\n    the underlying clip which determines the size and all other video\n    and audio properties of the result.\n\n.. describe:: overlay_clips\n\n    One or more source clips. Color formats must match base_clip.\n\n.. describe:: overlay_params\n\n    List of integer values.\n    \n    You must provide either two or six parameters for each source clip.\n    The parameters needn't be separated between clips.\n    \n    The two parameter version needs \n    \n    - ``target_x`` and ``target_y``.\n    \n    The six parameter version reads\n    \n    - ``source_x`` and ``source_y``.\n    - ``width_to_copy`` and ``height_to_copy``.\n\n    ``target_x`` and ``target_y`` and the offset positions of the actual ``overlay_clip``\n    \n    When additional parameters are specified, it is possible to read from an arbitrary \n    ``source_x`` and ``source_y`` position of the input clip, with a specified width and height:\n    ``width_to_copy`` and ``height_to_copy``.\n    \n    Rules:\n    \n    - ``target_x`` and ``target_y`` must be >= 0\n    - ``source_x``+``width_to_copy`` cannot exceed the full width of the actual ``overlay_clip`` \n    - ``source_y``+``height_to_copy`` cannot exceed the full height of the actual ``overlay_clip`` \n    - All positions and widths must fulfill the subsampling rules of the video format.\n      E.g. all positions and dimensions must be mod2 for a YV12 clip.\n    \n    But:\n    \n    - ``source_x`` and ``source_y`` are allowed to be negative values. Obviously, the off-clip contents\n      will shift the visual experience.\n\nOther notes\n-----------\n\nAudio, FrameRate and FrameCount are taken from the first clip.\n\nThis filter was originally developed for :doc:`AddBorders <addborders>`, as a helper filter,\nin which the eight smaller blurred areas are copied back into the transient areas of the \noriginal clip atop the boundary of the new borders as a ringing prevention measure.\n\nExamples\n~~~~~~~~\n\n::\n\n    ColorbarsHD()\n    Info() # let us have some text to see the effect\n    b=last.Crop(0, 0, 80,80)\n    c=last.Crop(80, 0, 80,80)\n    # two clips, \n    # copy \"b\" from sub-positions (40,40) a 30x30 area to (-10,300) onto original clip \n    # copy \"c\" from sub-positions (20,20) a 60x60 area to (80,300) onto original clip\n    #      (part or the 2nd clip is off-screen, not drawn)\n    MultiOverlay(last, b,c, \\\n      -10, 300, 40, 40, 30, 30, \\\n      80, 300, 20, 20, 60, 60 \\\n      )\n\n    # copy the whole 80x80 \"b\" clip to (0,400) onto original clip\n    # copy the whole 80x80 \"c\" clip to (80,400) onto original clip\n    MultiOverlay(last, b,c, \\\n      0, 400, \\\n      80, 400)\n\n\nChangelog\n----------\n\n+-----------------+---------------------------------------------------------------+\n| Version         | Changes                                                       |\n+=================+===============================================================+\n| 3.7.4           | Initial release                                               |\n+-----------------+---------------------------------------------------------------+\n\n\n$Date: 2025/03/14 12:58:00 $\n\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/normalize.rst",
    "content": "=========\nNormalize\n=========\n\nRaises (or lowers) the loudest peak of the audio track to a given volume. This\nprocess is called `audio normalization`_.\n\nNote that **Normalize** performs `peak normalization`_ (used to prevent audio\nclipping) and not `loudness normalization`_.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    Normalize (clip, float \"volume\", bool \"show\")\n\n.. describe:: clip\n\n    | Source clip. Supported audio sample types: 16-bit integer and 32-bit float.\n    | Other sample types (8, 24 and 32-bit integer) are automatically\n      :doc:`converted <convertaudio>` to 32-bit float.\n\n.. describe:: volume\n\n    Set the amplitude of the loudest audio. Default = 1.0 for peaking at 0\\ `dB`_:\n    for `floating-point`_ samples, this corresponds to the range -1.0 to +1.0,\n    and for 16-bit integer samples, this corresponds to the range -32768 to\n    +32767 – the widest range possible without `clipping`_.\n\n    * For a particular peak decibel level, use the equation ``volume`` =\n      10 :sup:`dB` / 20\n    * For example, set a -3dB peak with ``volume`` = 10\\ :sup:`-3/20` or 0.7079.\n    * Where multiple audio channels are present, all channel gains are set in\n      proportion. For example, if the loudest peak on the loudest channel comes\n      to -10dB, by default a gain of +10dB is applied to all channels.\n\n    Default: 1.0\n\n\n.. describe:: show\n\n    If *true*, a text overlay will show the calculated amplification factor and\n    the frame number of the loudest peak.\n\n    Default: false\n\n\nNormalization and Floating-point Audio\n--------------------------------------\n\nThe idea of digital *clipping* (when the signal is outside the range that can be\nstored accurately) really applies only to *integer* sample types; floating-point\nsamples will never become clipped in practice, as `the maximum value`_ is around\n3.4×10\\ :sup:`38` – some 29 orders of magnitude (580 dB) larger than 16-bit\nsamples can store.\n\n**Normalize** is therefore not needed for floating-point audio, but using it is\nrecommended before converting to an integer type, especially if any processing\nhas been done – such as :doc:`amplification <amplify>`, :doc:`mixing <mixaudio>`\nor :doc:`equalization <supereq>` – which may expand the audio peaks beyond the\ninteger clipping range.\n\n\nExamples\n--------\n\nNormalize signal to 98% ::\n\n    video = AviSource(\"video.avi\")\n    audio = WavSource(\"audio.wav\").Normalize(0.98)\n    return AudioDub(video, audio)\n\nNormalize each channel separately (eg for separate language tracks)::\n\n    video = AviSource(\"video.avi\")\n    audio = WavSource(\"audio2ch.wav\")\n    left_ch = GetChannel(audio,1).Normalize()\n    right_ch = GetChannel(audio,2).Normalize()\n    return AudioDub(video, MergeChannels(left_ch, right_ch))\n\nEffect of ``show=true`` with added :doc:`Histogram <histogram>`, `Waveform`_ and\n:ref:`current_frame <Special runtime variables and functions>` overlays::\n\n    LoadPlugin(\"waveform.dll\") # or autoload\n    V = BlankClip(pixel_type=\"YUV444P8\", width=480, height=360).Loop()\n    A = WavSource(\"music.wav\")\n    AudioDub(V, A).AudioTrim(0.0, A.AudioDuration)\n    ScriptClip(Last, \"\"\"Subtitle(Last, \"frame \"+String(current_frame), align=5)\"\"\")\n    Normalize(volume=1.0, show=true).Crop(0,0,-120,0).AddBorders(120,0,0,0)\n    Histogram(mode=\"audiolevels\")\n    Waveform(window=3, under=true)\n    return Last\n\n.. figure:: pictures/normalize-show.png\n   :align: left\n\n   Showing frame 386 where the loudest peak was detected, but note that\n   *Amplify Factor* is the same for all frames.\n\n\nChangelog\n----------\n\n+-----------------+-----------------------------------------------------+\n| Version         | Changes                                             |\n+=================+=====================================================+\n| AviSynth 2.5.0  | Replaced left and right parameters with ``volume``. |\n+-----------------+-----------------------------------------------------+\n| AviSynth 2.0.8  | Added ``show`` parameter.                           |\n+-----------------+-----------------------------------------------------+\n| AviSynth 2.0.3  | Added Normalize filter.                             |\n+-----------------+-----------------------------------------------------+\n\n$Date: 2022/03/05 15:10:22 $\n\n.. _audio normalization:\n    https://en.wikipedia.org/wiki/Audio_normalization\n.. _peak normalization:\n    https://en.wikipedia.org/wiki/Audio_normalization#Peak_normalization\n.. _clipping:\n    https://en.wikipedia.org/wiki/Clipping_(audio)#Digital_clipping\n.. _loudness normalization:\n    https://en.wikipedia.org/wiki/Audio_normalization#Loudness_normalization\n.. _floating-point:\n    http://avisynth.nl/index.php/Float\n.. _dB:\n    https://en.wikipedia.org/wiki/DBFS\n.. _the maximum value:\n    https://en.wikipedia.org/wiki/Single-precision_floating-point_format\n.. _Waveform:\n    http://avisynth.nl/index.php/Waveform\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/overlay.rst",
    "content": "Overlay\n=======\n\nPuts clip ``overlay`` on top of clip ``base`` using different blend ``modes``, and \nwith optional ``x``, ``y`` positioning, ``mask`` operation and ``opacity``. \n\n* In some modes the input clips (``base``, ``overlay`` and ``mask``) are converted \n  to 4:4:4 internally. The output is re-converted to the input colorspace (or to the \n  ``output`` colorspace, if specified). \n  But, if possible, original colorspace is preserved during the processing, such as \n  in \"blend\", \"luma\" and \"chroma\" modes; or RGB in \"add\" and \"subtract\". See ``use444``, \n  below.\n* Only specific modes like \"blend\", \"luma\", \"chroma\", \"add\", and \"subtract\" support 32-bit float input. \n  For these modes, 32-bit float input is natively supported, and the behavior is consistent \n  with other formats, but clamping is not necessarily done.\n* \"add\" and \"subtract\" modes also support conversionless RGB processing without the internal\n  conversion to 4:4:4. This means that for RGB sources, the overlay operation is \n  performed directly in the RGB domain, avoiding unnecessary colorspace conversions.\n* In general all clips are treated as full-range values. This means that numbers will \n  not be clipped at TV range; you may use :doc:`Limiter <limiter>` for this task afterwards. \n  If your ``mask`` is TV-range, you should convert it to full-range, or the mask will \n  never be fully opaque. You can use :doc:`Histogram <histogram>` in ``Histogram(\"levels\")`` \n  mode to view the color distributions. If your mask is of limited (TV) range, use\n  ``ConvertBits(fulls=false, fulld=true)`` or ``ColorYUV(levels=\"TV->PC`` to upscale \n  the color levels.\n* It is not recommended to do overlays on interlaced material, unless you know what \n  you are doing. \n\n\nSyntax and Parameters\n---------------------\n::\n\n    Overlay (clip, clip overlay, int \"x\", int \"y\", clip \"mask\", float \"opacity\",\n             string \"mode\", bool \"greymask\", string \"output\", \n             bool \"ignore_conditional\", bool \"pc_range\", bool \"use444\", \n             string \"condvarsuffix\")\n\n.. describe:: clip\n\n    This clip will be the base, and the overlay picture will be placed on top of\n    this.\n\n.. describe:: overlay\n    \n    This is the image that will be placed on top of the base clip. The colorspace\n    or image dimensions do not have to match the base clip.\n\n.. describe:: x, y\n\n    These two variables define the placement of the overlay image on the base\n    clip in pixels. The variable can be positive or negative.\n\n    Default: 0, 0\n\n.. describe:: mask\n\n    Optional transparency mask for the overlay image. Must be the same size as \n    the overlay clip. Where mask is darker, overlay will be more transparent. \n    \n    By default only the greyscale (luma) components are used, but this can be \n    overridden with ``greymask``=``false``. \n\n    There is no default, but not specifying is equivalent to supplying a fully\n    255 (in general ``2^bit_depth - 1``  for 8-16 bit formats or ``1.0`` for \n    32 bit float format) clip. Maximum pixel value means a 1.0 mask multiplier,\n    that means full opacity.\n\n.. describe:: opacity\n\n    This will set how transparent your image will be. The value is from 0.0 to\n    1.0, where 0.0 is transparent and 1.0 is fully opaque (if no mask is used).\n    When used together with a mask this value is multiplied by the mask value to\n    form the **final** opacity.\n    \n    Default: 1.0\n\n.. describe:: mode\n\n    Mode defines how your clip should be overlaid on your image.\n\n    Default: \"Blend\"\n\n+-----------+-------------------------------------------------------+-------------------------------------------------------------------------------------------------------+\n| Mode      |                                                       | Description                                                                                           |\n+===========+=======================================================+=======================================================================================================+\n| Blend     |  .. image:: ./pictures/Layer-base-Lena.png            | This is the default mode. When opacity is 1.0 and there is no mask the                                |\n|           |  .. image:: ./pictures/Layer-over-grad.png            | overlay image will be copied on top of the original. Ordinary transparent blending is used otherwise. |\n|           |  .. image:: ./pictures/Overlay-example-blend.png      | Supports float input and RGB input natively, without conversion to 4:4:4.                             |\n|           |                                                       |                                                                                                       |\n|           |                                                       |                                                                                                       |\n|           |                                                       |                                                                                                       |\n|           |                                                       |                                                                                                       |\n|           |                                                       |                                                                                                       |\n|           |                                                       |                                                                                                       |\n|           |                                                       |                                                                                                       |\n|           |                                                       |                                                                                                       |\n|           |                                                       |                                                                                                       |\n|           |                                                       |                                                                                                       |\n|           |                                                       |                                                                                                       |\n|           |                                                       |                                                                                                       |\n|           |                                                       | y                                                                                                     |\n+-----------+-------------------------------------------------------+-------------------------------------------------------------------------------------------------------+\n| Add       |  .. image:: ./pictures/Overlay-example-add.png        | This will add the overlay video to the base video, making the video                                   |\n|           |                                                       | brighter. In YUV, \"add\" and \"subtract\" are not just per-channel math. The luma (Y) is added or        |\n|           |                                                       | subtracted (see \"Subtract\"), but if the result overflows (Y > max) or underflows (Y < 0), the chroma  |\n|           |                                                       | (U/V) is \"pulled\" toward neutral (gray/white) to mimic how RGB overbright/underbright behaves         |\n|           |                                                       | visually. In RGB, adding two bright colors can result in \"white\" (all channels maxed). In YUV, if you |\n|           |                                                       | just add Y, U, and V, we can get weird color shifts. The code compensates by blending U/V toward      |\n|           |                                                       | neutral when Y is out of range, making the result look more like RGB addition.                        |\n|           |                                                       | For RGB, a simple per-channel add/subtract (with clamping for 8-16-bit, or no clamping for float) is  |\n|           |                                                       | done. RGB input is processed natively, without conversion to 4:4:4.                                   |\n|           |                                                       | In 32 bit float with YUV, overshoot (Y > 1.0f) and undershoot (Y < 0.0f) are used and clamping occurs.|\n+-----------+-------------------------------------------------------+-------------------------------------------------------------------------------------------------------+\n| Subtract  |  .. image:: ./pictures/Overlay-example-subtract.png   | The opposite of Add. This will make the areas darker. In YUV, subtracting can cause undershoot        |\n|           |                                                       | (Y < 0.0f), see description at \"Add\".                                                                 |\n|           |                                                       | For RGB, subtraction is performed directly on the channels, without conversion.                       |\n|           |                                                       | \"subtract\" supports float input and RGB input natively, without conversion to 4:4:4.                  |\n+-----------+-------------------------------------------------------+-------------------------------------------------------------------------------------------------------+\n| Multiply  |  .. image:: ./pictures/Overlay-example-multiply.png   | This will also darken the image, but it works different than subtract.                                |\n+-----------+-------------------------------------------------------+-------------------------------------------------------------------------------------------------------+\n| Chroma    |  .. image:: ./pictures/Overlay-example-chroma.png     | This will only overlay the color information of the overlay clip on to the base image.                |\n+-----------+-------------------------------------------------------+-------------------------------------------------------------------------------------------------------+\n| Luma      |  .. image:: ./pictures/Overlay-example-luma.png       | This will only overlay the luminosity information of the overlay clip on to the base image.           |\n+-----------+-------------------------------------------------------+-------------------------------------------------------------------------------------------------------+\n| Lighten   |  .. image:: ./pictures/Overlay-example-lighten.png    | This will copy the light infomation from the overlay clip to the base                                 |\n|           |                                                       | clip, only if the overlay is lighter than the base image.                                             |\n+-----------+-------------------------------------------------------+-------------------------------------------------------------------------------------------------------+\n| Darken    |  .. image:: ./pictures/Overlay-example-darken.png     | This will copy the light infomation from the overlay clip to the base                                 |\n|           |                                                       | clip, only if the overlay is darker than the base image.                                              |\n+-----------+-------------------------------------------------------+-------------------------------------------------------------------------------------------------------+\n| SoftLight |  .. image:: ./pictures/Overlay-example-softlight.png  | This will ligten or darken the base clip, based on the light level                                    |\n|           |                                                       | of the overlay clip. If the overlay is darker than luma = 128 [``(2^bit_depth)-1``], the base image   |\n|           |                                                       | will be darker. If the overlay is lighter than luma=128 [``(2^bit_depth)-1``], the base image will    |\n|           |                                                       | be lighter. This is useful for adding shadows to an image. Painting with pure                         |\n|           |                                                       | black or white produces a distinctly darker or lighter area but does not                              |\n|           |                                                       | result in pure black or white.                                                                        |\n+-----------+-------------------------------------------------------+-------------------------------------------------------------------------------------------------------+\n| HardLight |  .. image:: ./pictures/Overlay-example-hardlight.png  | This will ligten or darken the base clip, based on the light level                                    |\n|           |                                                       | of the overlay clip. If the overlay is darker than luma = 128, the base image                         |\n|           |                                                       | will be darker. If the overlay is lighter than luma=128, the base image will                          |\n|           |                                                       | be lighter. This is useful for adding shadows to an image. Painting with pure                         |\n|           |                                                       | black or white results in pure black or white.                                                        |\n+-----------+-------------------------------------------------------+-------------------------------------------------------------------------------------------------------+\n| Difference|  .. image:: ./pictures/Overlay-example-difference.png | This will display the difference between the clip and the overlay.                                    |\n|           |                                                       | Note that like :doc:`Subtract <subtract>` a difference of zero is displayed as grey, but              |\n|           |                                                       | with luma=128 instead of 126. If you want the pure difference, use                                    |\n|           |                                                       | mode=\"Subtract\" or add `ColorYUV(off_y=-128)`.                                                        |\n+-----------+-------------------------------------------------------+-------------------------------------------------------------------------------------------------------+\n| Exclusion |  .. image:: ./pictures/Overlay-example-exclusion.png  | This will invert the image based on the luminosity of the overlay                                     |\n|           |                                                       | image. Blending with white inverts the base color values; blending with black                         |\n|           |                                                       | produces no change.                                                                                   |\n+-----------+-------------------------------------------------------+-------------------------------------------------------------------------------------------------------+\n\n.. describe:: greymask\n\n    Specifies whether chroma should be used for chroma transparency. Generally you \n    want to leave this alone, this mode shouldn't be disabled. External filters like\n    ``mSharpen`` and ``Masktools`` are able to export proper chroma maps. \n\n    Default: true\n\n.. describe:: output\n\n    It is possible to make Overlay return another colorspace.\n    e.g. \"YV24\", \"YUV420P14\" or \"RGB64\" \n\n    Default: (input colorspace)\n\n.. describe:: ignore_conditional\n\n    Ignore any given conditional (runtime) variables. \n\n    See also: conditional variables section :doc:`ColorYUV <coloryuv>`, or \n    :doc:`ConditionalReader <conditionalreader>` or \n    http://avisynth.nl/index.php/ColorYUV.\n\n    Default: false\n\n.. describe:: pc_range\n\n    When set to true, this will make all internal RGB→YUV→RGB conversions assume that \n    YUV sources are full-range instead of the default TV range. It is only recommended\n    to change this setting if you know what you are doing. See RGB considerations below.\n\n    Planned on the roadmap: when frame property _ColorRange is supported in Avisynth, Overlay \n    will be able to automatically detect the range of the input clips, and adjust accordingly.\n    Only when pc_range is intentionally given, would it override the automatic detection.\n    But this is not yet implemented.\n\n    Default: false\n\n.. describe:: use444\n\n    If set to false, Overlay uses conversionless mode where possible instead of going \n    through YUV 4:4:4. However, for ``Luma`` and ``Chroma`` modes, RGB must be converted \n    to YUV 4:4:4.\n    \n    Default: (adaptive) \n    \n    * false when mode=\"blend\" and format is RGB \n    * false when mode=\"blend\", \"luma\" or \"chroma\" and format is YUV420/YUV422 (YV12/YV16). \n      Original format is kept throughout the whole process, no 4:4:4 conversion occurs. \n    * false when mode=\"add\" or mode=\"subtract\" and format is RGB \n    * true for all other cases (input is converted internally to 4:4:4)\n\n.. describe:: condvarsuffix\n\n    Allows multiple filter instances to use differently named conditional parameters.\n    Prevents collision and overwrite of variables which are used by different Overlay \n    instances.\n\n    See also: conditional variables section :doc:`ColorYUV <coloryuv>`, or \n    :doc:`ConditionalReader <conditionalreader>`, or :doc:`RGBAdjust <adjust>`.\n    \n    How does it work: when reading the global variables, the ``condvarsuffix`` parameter is \n    appended to the variable name. E.g. variable name \"myvar_a\" will be read instead of \n    \"myvar\" when ``condvarsuffix = \"_a\"`` is provided.\n    \n    Useful for ``ColorYUV``, ``RGBAdjust``, ``Overlay`` when the conditional variables\n    are enabled (or here, in Overlay, is not disabled).\n\n    In the matching ConditionalReader one have to use the modified name as well:\n\n    ::\n\n        ConditionalReader(\"overlay_a_offset.txt\", \"OL_opacity_offset\", false, CondVarSuffix = \"_a\")\n        # \"_a\" is added here by parameter\n\n    or specify the suffixed name directly:\n\n    ::\n\n        ConditionalReader(\"overlay_a_offset.txt\", \"OL_opacity_offset_a\", false)\n        # \"_a\" is added here manually\n\n    Default: \"\"\n\n\n\nRGB considerations\n------------------\n\nRGB inputs are accepted. However, Overlay for specific modes may convert the RGB clip\ninternally to 4:4:4 (see Avisynth+ exceptions), this will lead to an RGB→YUV conversion. \nThere are two modes for this conversion, toggled by the ``pc_range`` parameter. This \nparameter will extend the YUV range from 16-235 (8 bit example) (this is the range \nused by all Avisynth converters) to 0-255. There are some cases where enabling \n``pc_range`` is a good idea:\n\n* When overlaying an RGB clip using the ``add``, ``subtract`` or ``multiply`` modes,\n  the range of the overlay clip is better, if it is full range (PC range), since this \n  will enable completely dark areas not to influence the result (instead of adding 16 \n  to every value; since 16 is the \"limited\" range lowest nominal value).\n* When NOT doing a colorspace conversion on output. If the output colorspace \n  (RGB vs. YUV) is different from the input, the scale will be wrong. If \n  ``pc_range=true``, and input is RGB, while output is YV16, the YV16 will have an \n  invalid range, and not CCIR-601 range.\n* Planar RGB formats are also supported besides 8 bit packed RGB formats plus RGB48/RGB64.\n* \"blend\", \"add\", and \"subtract\" modes keep original RGB format, no YUV intermediate \n  conversion is used for RGB input.\n\n**Outputting RGB**\n\nIt might be a good idea to let Overlay output YV24 or YUV444P10-16, even if your \ninput colorspace is RGB, as this avoids a colorspace conversion back to RGB from \nYUV. You should however be aware that your material might be \"overscaled\", as \nmentioned above, if you use ``pc_range=true``. You can correct this by using \n``ConvertBits(fulls=true, fulld=false)`` or ``ColorYUV(levels=\"pc->tv\")`` to \nconvert back to 16-235 range (or equivalent ranges to 10+ bits). \n\n**Inputting RGB for mask clip**\n\nAn RGB mask clip may behave a bit oddly if it contains color information. \nIf you use a greyscale ``mask``, or if you leave ``greymask=true``, you will get \nthe result you would expect. Note that mask values are never scaled, so it \nwill automatically be in full-range, directly copied from the RGB values.\nTraditionally, the mask is retrieved from channel \"B\" (Blue).\nThe maximum mask value is bit depth dependent, 255 for 8 bit, 65535 for 16 bit,\nand 1.0 for 32-bit float formats.\n\n**Using RGB32, RGB64 or planar RGBA alpha channel**\n\nOverlay ignores the alpha (transparency) channel in an RGB32 clip. If you \nwant the alpha, you can use something like \n``Overlay(kitten, mask=kitten.ExtractA())`` or\n``Overlay(kitten, mask=kitten.ShowAlpha(\"RGB32\"))``.\n\nSee also :doc:`Extract filters <extract>` and :doc:`ShowAlpha <showalpha>`.\n\n**Repeated overlays on RGB base clip**\n\nFor modes, where RGB is not directly supported, when doing repeated partial \noverlays on an RGB base clip, the unchanged parts of the base clip may \nundergo a RGB→YV24→RGB conversion for each call to Overlay, producing a progressive \nloss of color accuracy. In these situations, it is better to convert the base \nclip to 4:4:4 format (e.g. YV24) before doing the overlays and convert back to \nRGB afterwards. Remember, that \"blend\", \"add\", and \"subtract\" do not convert from RGB.\n\nConditional Variables\n---------------------\n\nThe global variables ``OL_opacity_offset``, ``OL_x_offset`` and\n``OL_y_offset`` are read each frame, and applied. It is possible to modify\nthese variables using :doc:`FrameEvaluate <conditionalfilter>`. The values of these variables\nwill be added to the original on each frame. So if you specify \"x = 100\" as a\nfilter parameter, and the global variable ``OL_x_offset`` is set to 50, the\noverlay will be placed at x = 150.\n\nIf you need to use conditional variables in multiple filters, use \n``condvarsuffix`` parameter to make them unique for each filter instance.\n\nIn other Overlay filters this can even be disabled by using the\n``ignore_conditional = true`` parameter.\n\nThere is an example of conditional modification at the\n:doc:`ConditionalReader <conditionalreader>` page.\n\n\nExamples\n--------\n\n::\n\n    # Prepares some sources.\n    bg = ColorBars(512,384).ConvertToYUY2\n    text = BlankClip(bg).Subtitle(\"Colorbars\", size=92, \n    \\          text_color=$ffffff).ColorYUV(levels=\"tv->pc\")\n\n    # Overlay the text in three different versions.\n    return Overlay(bg, text, x=50, y=20, mode=\"subtract\", opacity=0.25)\n    return Overlay(text, x=50, y=120, mode=\"add\", opacity=0.5)\n    return Overlay(text, x=50, y=240, mode=\"blend\", opacity=0.7)\n\n    # Overlay yuy2 clip with rgb clip using a yuy2 mask\n    # (note that the luma range of the mask is [0-255]). \n    return Overlay(yuy2clip, rgbclip, mask=rgbclip.ShowAlpha(\"yuy2\"))\n\n    # ...which is the same as \n    mask = rgbclip.ShowAlpha(\"rgb\").ConvertToYUY2\n    \\             .ColorYUV(levels=\"TV->PC\")\n    return Overlay(yuy2clip, rgbclip, mask=mask)\n\n    # ...which is the same as \n    mask = rgbclip.ShowAlpha(\"rgb\")\n    return Overlay(yuy2clip, rgbclip, mask=mask)\n\n- This will take the average of two clips. It can be used for example to \n  combine two captures of different broadcast captures for reducing noise. \n  A discussion of this idea can be found [`here`_]. A sample script (of course\n  you have to ensure that the frames of the two clips matches exactly, \n  using Trim as needed): \n\n::\n\n    clip1 = AviSource(\"F:\\shakira-underneath_your_clothes1.avi\")\n    clip2 = AviSource(\"F:\\shakira-underneath_your_clothes2.avi\")\n    Overlay(clip1, clip2, mode=\"blend\", opacity=0.5)\n\n- Another use is to detect an altered video using Video Error Level Analysis \n  (VELA), where clip2 is clip1 resaved using an h.263 Codec (e.g. XVID). \n  This method is effective when the suspected altered video (clip1) has \n  not been resaved multiple times. Levels is used to exaggerate contrast \n  for view-ability:\n\n::\n\n    clip1 = AviSource(\"SuspectVideo.avi\")\n    clip2 = AviSource(\"SuspectVideo_resaved.avi\")\n    result= Overlay(clip1,clip2,mode=\"Subtract\").Levels(0, 5.0, 100, 0, 255)\n\n- Use a blue (or any other color) background (blue.jpg is a blue frame\n  overlaid with subtitles in a black rectangle) as mask. The black rectangle\n  containing the subtitles will be visible on the source clip (which is\n  :doc:`ColorBars <colorbars>` here):\n\n::\n\n    testcard = ColorBars()\n\n    # get a blue mask clip (the same blue as in ColorBars is used: R16 G16 B180)\n    maskclip = BlankClip(testcard, color=$0f0fb4)\n\n    # Example subtitle file with blue backgroud as above\n    subs = ImageSource(\"F:\\TestClips\\blue.jpg\").ConvertToRGB32\n\n    maskclip = ColorKeyMask(subs, $0f0fb4, 60)\n\n    Overlay(testcard, subs, mask=ShowAlpha(maskclip), mode=\"blend\", opacity=1)\n\n.. image:: pictures/overlay_blue.jpg\n.. image:: pictures/overlay_subs.png\n\n\nA tolerance of 60 is used here because the blue is not entirely uniform. Near\nthe black rectangles the blue is given by R23 G22 B124. Probably due to the\ncompression of blue.jpg.\n\n- Move a red (or any other color) dot on a clip using ``ConditionalReader``\n  (dot.bmp is a red dot on a black background):\n\n::\n\n    a1 = ColorBars().Trim(0,399)\n    a2 = ImageSource(\"F:\\TestClips\\dot.bmp\").ConvertToRGB32\n\n    # a2.GreyScale returns a grey dot on a black background; Levels makes the dot white\n    mask_clip = Mask(a2, a2.GreyScale.Levels(0, 1, 75, 0, 255))\n    Overlay(a1, a2, mask=ShowAlpha(mask_clip), y=0, x=0, mode=\"blend\", opacity=1)\n\n    ConditionalReader(\"xoffset.txt\", \"ol_x_offset\", false)\n    ConditionalReader(\"yoffset.txt\", \"ol_y_offset\", false)\n\nMake xoffset.txt containing the x-positions and yoffset.txt containing the\ny-positions of the moving dot (see :doc:`ConditionalReader <conditionalreader>` for more info), and\nput it in the same folder as your script:\n\n::\n\n    xoffset.txt\n\n    Type int\n    Default -50\n\n    R 0 100 20\n    I 100 200 20 250\n    R 200 300 250\n    I 300 400 250 400 ::yoffset.txt\n\n    Type int\n    Default -50\n\n    R 0 100 20\n    I 100 200 20 350\n    R 200 300 350\n    I 300 400 350 40\n\n.. image:: pictures/overlay_dot.png\n.. image:: pictures/overlay_dot2.png\n\nthus the dot moves in the following way: (20,20) -> (250,350) -> (400,40).\nNb, it's also possible to do this with Animate.\n\nAnd the same with using ``condvarsuffix``:\n\n::\n\n    a1 = ColorBars().Trim(0,399)\n    a2 = ImageSource(\"F:\\TestClips\\dot.bmp\").ConvertToRGB32\n\n    # a2.GreyScale returns a grey dot on a black background; Levels makes the dot white\n    mask_clip = Mask(a2, a2.GreyScale.Levels(0, 1, 75, 0, 255))\n    Overlay(a1, a2, mask=ShowAlpha(mask_clip), y=0, x=0, mode=\"blend\", opacity=1, \\\n            condvarsuffix=\"_a\")\n\n    # directly read the _a prefixed variable\n    ConditionalReader(\"xoffset.txt\", \"ol_x_offset_a\", false)\n    # or _a as exactly named parameter\n    ConditionalReader(\"yoffset.txt\", \"ol_y_offset\", false, condvarsuffix=\"a\")\n\n\nTest script for different bit depths with and without masks\n\n::\n\n    # Prepares some sources.\n    bg = ColorBars(512,384).ConvertToYV16() # or ConvertToYUV444()\n    text = BlankClip(bg).Subtitle(\"Colorbars\", size=92, \n    \\          text_color=$ffffff).ColorYUV(levels=\"tv->pc\").ConvertToYV16()\n    mask = BlankClip(bg).Subtitle(\"I am the Mask\", size=62, \n    \\          text_color=$ffffff).ColorYUV(levels=\"tv->pc\")\n    \n    # use these two lines for RGB tests instead of YUV\n    bg = bg.ConvertToRGB32().ConvertToPlanarRGB()\n    text = text.ConvertToRGB32().ConvertToPlanarRGB()\n    \n    mask = mask.GreyScale().ConvertToYV16()\n    \n    # tests for 8-10-16-32 bits\n    \n    #add no mask\n    ov8 = Overlay(bg,text, x=50, y=120, mode=\"subtract\", opacity=0.5).Info()\n    ov10 = Overlay(bg.ConvertBits(10),text.ConvertBits(10), x=50, y=120, mode=\"subtract\", opacity=0.5).Info().ConvertBits(8)\n    ov16 = Overlay(bg.ConvertBits(16),text.ConvertBits(16), x=50, y=120, mode=\"subtract\", opacity=0.5).Info().ConvertBits(8)\n    ov32 = Overlay(bg.ConvertBits(32),text.ConvertBits(32), x=50, y=120, mode=\"subtract\", opacity=0.5).Info().ConvertBits(8)\n    \n    #add with mask\n    ov8m = Overlay(bg,text, x=50, y=120, mode=\"subtract\", opacity=0.5, mask=mask).Info()\n    ov10m = Overlay(bg.ConvertBits(10),text.ConvertBits(10), x=50, y=120, mode=\"subtract\", opacity=0.5, mask=mask.ConvertBits(10)).Info().ConvertBits(8)\n    ov16m = Overlay(bg.ConvertBits(16),text.ConvertBits(16), x=50, y=120, mode=\"subtract\", opacity=0.5, mask=mask.ConvertBits(16)).Info().ConvertBits(8)\n    ov32m = Overlay(bg.ConvertBits(32),text.ConvertBits(32), x=50, y=120, mode=\"subtract\", opacity=0.5, mask=mask.ConvertBits(32)).Info().ConvertBits(8)\n    /*\n    opacity 1.0\n    #add no mask\n    ov8 = Overlay(bg,text, x=50, y=120, mode=\"subtract\", opacity=1.0).Info()\n    ov10 = Overlay(bg.ConvertBits(10),text.ConvertBits(10), x=50, y=120, mode=\"subtract\", opacity=1.0).Info().ConvertBits(8)\n    ov16 = Overlay(bg.ConvertBits(16),text.ConvertBits(16), x=50, y=120, mode=\"subtract\", opacity=1.0).Info().ConvertBits(8)\n    ov32 = Overlay(bg.ConvertBits(32),text.ConvertBits(32), x=50, y=120, mode=\"subtract\", opacity=1.0).Info().ConvertBits(8)\n    \n    #add with mask\n    ov8m = Overlay(bg,text, x=50, y=120, mode=\"subtract\", opacity=0.5, mask=mask).Info()\n    ov10m = Overlay(bg.ConvertBits(10),text.ConvertBits(10), x=50, y=120, mode=\"subtract\", opacity=1.0, mask=mask.ConvertBits(10)).Info().ConvertBits(8)\n    ov16m = Overlay(bg.ConvertBits(16),text.ConvertBits(16), x=50, y=120, mode=\"subtract\", opacity=1.0, mask=mask.ConvertBits(16)).Info().ConvertBits(8)\n    ov32m = Overlay(bg.ConvertBits(32),text.ConvertBits(32), x=50, y=120, mode=\"subtract\", opacity=1.0, mask=mask.ConvertBits(32)).Info().ConvertBits(8)\n    */\n    \n    return StackHorizontal(\\\n    Stackvertical(ov8,ov10,ov16,ov32),\\ \n    Stackvertical(ov8m,ov10m,ov16m,ov32m)\\\n    ).ConvertToRGB32()\n\n  \n+-----------+------------------------------------------------------------------------+\n| Changelog |                                                                        |\n+===========+========================================================================+\n| 3.7.6     | | \"add\", and \"subtract\" supports 32-bit float input.                   |\n|           | | \"add\" and \"subtract\" support RGB input without 4:4:4 conversion.     |\n|           | | Check for unsupported 32-bit float, such modes give error.           |\n+-----------+------------------------------------------------------------------------+\n| 3.7.2     | Address issue #255: \"blend\": now using accurate formula using float    |\n|           | calculation internally.                                                |\n+-----------+------------------------------------------------------------------------+\n| 3.7.1     | Overlay mode \"multiply\": overlay clip is not converted to 4:4:4        |\n|           | when when 420 or 422, since only Y is used from it (speed).            |\n+-----------+------------------------------------------------------------------------+\n| 3.7.0     || allow 4:1:1 input                                                     |\n|           || fix crash when mask is YUV411 and greymask=false                      |\n+-----------+------------------------------------------------------------------------+\n| 3.4.0     | Add \"condvarsuffix\" parameter                                          |\n+-----------+------------------------------------------------------------------------+\n| r2502     | Correct masked blend: keep exact clip1 or clip2 pixel values           |\n|           | for mask extremes 255 or 0.                                            |\n|           | Previously 0 became 1 for zero mask, similarly 255 changed into        |\n|           | 254 for full transparency (255) mask                                   |\n+-----------+------------------------------------------------------------------------+\n| r2420     || \"Blend\" native greyscale mode: process y plane only w/o conversion    |\n|           || automatic use444=false for \"blend\"/\"luma\"/\"chroma\"                    |\n|           |  for inputs: 420/422/444 and any RGB, lossless Planar RGB intermediate |\n|           |  for PackedRGB.                                                        |\n|           || mask auto-follows input clip format. For compatibility: when          |\n|           |  greymask=true (default) and mask is RGB then mask source is           |\n|           |   the B channel 254 for full transparency (255) mask                   |\n+-----------+------------------------------------------------------------------------+\n| r2359     || new parameter: bool use444 (default true for compatibility)           |\n|           || lossless RGB \"blend\" w/o YUV conversion                               |\n+-----------+------------------------------------------------------------------------+\n| v2.54     | Initial Release                                                        |\n+-----------+------------------------------------------------------------------------+\n\n$Date: 2025/11/22 10:35:50 $\n\n.. _here: http://forum.doom9.org/showthread.php?s=&threadid=28438\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/parity.rst",
    "content": "==============\nParity Filters\n==============\n\nAviSynth includes these filters to change the parity state of a clip:\n\n* `AssumeFrameBased / AssumeFieldBased`_ forces frame-based or field-based material.\n* `AssumeTFF / AssumeBFF`_ forces field order.\n* `ComplementParity`_ changes top fields to bottom fields and vice-versa.\n\n.. _AssumeFrameBased:\n.. _AssumeFieldBased:\n.. _AssumeFrameField:\n\nAssumeFrameBased / AssumeFieldBased\n-----------------------------------\n\nAviSynth keeps track of whether a given clip is *field-based* or *frame-based*.\nIf the clip is field-based it also keeps track of the *parity* of each field –\nthat is, whether it's the top or the bottom field. If the clip is frame-based\nit keeps track of the *dominant field* in each frame – that is, which field in\nthe frame comes first when they are separated.\n\nHowever, this information isn't necessarily correct, because field information\nusually isn't stored in video files and AviSynth's source filters just guess at\nit. **AssumeFrameBased** and **AssumeFieldBased** let you tell AviSynth the\ncorrect type of a clip. See this `Doom9 thread`_ for a bit more information.\n\n**AssumeFrameBased** throws away the existing information and assumes that the\nclip is frame-based, with the bottom (even) field dominant in each frame. This\nhappens to be what the source filters guess. If you want the top field dominant,\nuse `ComplementParity`_ afterwards.\n\n**AssumeFieldBased** throws away the existing information and assumes that the\nclip is field-based, with the even-numbered fields being bottom fields and the\nodd-numbered fields being top fields. If you want it the other way around,\nuse `ComplementParity`_ afterwards.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    AssumeFrameBased (clip)\n    AssumeFieldBased (clip)\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n.. _AssumeBFF:\n.. _AssumeTFF:\n.. _AssumeFieldFirst:\n\nAssumeTFF / AssumeBFF\n---------------------\nAviSynth keeps track of whether a given clip is *field-based* or *frame-based*.\nIf the clip is field-based it also keeps track of the *parity* of each field –\nthat is, whether it's the top or the bottom field. If the clip is frame-based\nit keeps track of the *dominant field* in each frame – that is, which field in\nthe frame comes first when they're separated.\n\nHowever, this information isn't necessarily correct, because field information\nusually isn't stored in video files and AviSynth's source filters just normally\ndefault to assuming bottom field first (with the exception of the `MPEG2Source`_\nplugin, which gets it right!). **AssumeTFF** and **AssumeBFF** let you tell\nAviSynth what you believe the field order a clip has.\n\n**AssumeTFF** sets the field order to Top Field First and **AssumeBFF** to\nBottom Field First. They do not change the actual field order, just the internal\nstate flags in AviSynth relating to the source clip used.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    AssumeTFF (clip)\n    AssumeBFF (clip)\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n--------------\n\n.. rubric:: Examples\n\n::\n\n    AviSource(\"test.avi\")\n    AssumeTFF()\n    SeparateFields()\n\nWill always return the top field of the first frame followed by the bottom\nfield of the first frame and so on.\n\n::\n\n    AviSource(\"test.avi\")\n    AssumeBFF()\n    SeparateFields()\n\nWill always return the bottom field of the first frame followed by the top\nfield of the first frame and so on.\n\n.. _ComplementParity:\n\nComplementParity\n----------------\n\nIf the input clip is field-based, **ComplementParity** changes top fields to\nbottom fields and vice-versa. If the input clip is frame-based, it changes\neach frame's dominant field (bottom-dominant to top-dominant and vice-versa).\n\nIt does not change the actual field order, just the internal state flags in\nAviSynth relating to the source clip used.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    ComplementParity (clip)\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n\nChangelog\n----------\n\n.. table::\n    :widths: auto\n\n    +------------------+----------------------------------------------------+\n    | Version          | Changes                                            |\n    +==================+====================================================+\n    | AviSynth 2.0.3   | Added AssumeBFF / AssumeTFF filters.               |\n    +------------------+----------------------------------------------------+\n    \n$Date: 2022/03/17 21:41:11 $\n\n.. _Doom9 thread:\n    https://forum.doom9.org/showthread.php?t=150472\n.. _MPEG2Source:\n    http://avisynth.nl/index.php/DGDecode/MPEG2Source\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/peculiar.rst",
    "content": "\nPeculiarBlend\n=============\n\nThis filter blends each frame with the following frame in a peculiar way.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    PeculiarBlend (clip, int cutoff)\n\n.. describe:: clip\n\n    Source clip; only YUY2 is supported.\n\n.. describe:: cutoff\n\n    The portion of the frame below scanline number ``cutoff`` is unchanged. \n    The portion above scanline number (``cutoff``-30) is replaced with the \n    corresponding portion of the following frame. The 30 scan lines in \n    between are blended incrementally to disguise the switchover.\n    \n    You're probably wondering why anyone would use this filter. Well, it's \n    like this. Most videos which were originally shot on film use the \n    3:2 pulldown technique which is described in the description of the \n    :doc:`Pulldown <pulldown>` filter. But some use a much nastier system \n    (`involving a camera pointed at a movie screen`_) in which the crossover \n    to the  next frame occurs in the middle of a field--in other words, \n    individual  fields look like one movie frame on the top, and another on \n    the bottom. This filter partially undoes this peculiar effect. It should \n    be used before :doc:`Pulldown <pulldown>`. To determine ``cutoff``, \n    examine a frame which is blended in this way and set it to the number of \n    the first scanline in which you notice a blend.\n\n\n$Date: 2022/02/08 21:28:07 $\n\n.. _involving a camera pointed at a movie screen:\n    http://forum.doom9.org/showthread.php?p=455092&highlight=PeculiarBlend#post455092\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/preroll.rst",
    "content": "=======\nPreroll\n=======\n\n**Preroll** will seek *video* frames and/or *audio* seconds before the target\npoint on any non-linear access.\n\nThis may help avoid decoding problems with source filters that do not handle\nrandom access correctly.\n\n“Preroll works by detecting any out of order access in the audio or video track,\nand seeking the specified amount earlier in the stream and then taking a\ncontiguous run up to the desired frame or audio sample. Skipping forward less\nthan the preroll values results in linear access behaviour, i.e. all the\nintervening samples are accessed and discarded.” [`IanB`_]\n\nAlso see this `Doom9 thread`_.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    Preroll (clip, int \"video\", float \"audio\")\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n.. describe:: video\n\n    Frames to preroll.\n\n    Default: 0\n\n.. describe:: audio\n\n    Audio to preroll, in seconds.\n\n    Default: 0.0\n\n\nExamples\n---------\n\n25 frame video preroll, 10.0 seconds audio preroll::\n\n    xxxSource(\"video.mp4\")\n    Preroll(video=25, audio=10.0)\n\n\nChangelog\n----------\n\n+----------------+-----------------+\n| Version        | Changes         |\n+================+=================+\n| AviSynth 2.6.0 | Initial release |\n+----------------+-----------------+\n\n$Date: 2022/04/17 13:38:34 $\n\n.. _IanB:\n    https://forum.doom9.org/showthread.php?p=1629239#post1629239\n.. _Doom9 thread:\n    https://forum.doom9.org/showthread.php?t=164457\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/propShow.rst",
    "content": "\npropShow\n========\n\nSee also: :doc:`Internal functions: frame properties <../syntax/syntax_internal_functions_frame_properties>`.\n\nLists frame properties to screen (a debug filter).\n\nGives frame property information as a text overlay, if the position is not specified, in the upper-left corner.\n\nThe displayed information consists of:\n\n* Number of frame properties (only if no name filter is given)\n* each line describes a frame property with its name and value\n* display _Matrix, _ColorRange and _ChromaLocation constants with friendly names, e.g. _ColorRange = 1 = limited\n\nListing appears as a name = value list. Arrays values are put between [ and ]\nTop line contains number is properties. If no properties found, nothing is displayed.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    propShow (clip clip, int \"size\", string \"font\", bool \"showtype\", \n          string \"font\", int \"text_color\", int \"halo_color\", \n          bool \"bold\", float \"x\", float \"y\", int \"align\", string[] \"props\")\n\n.. describe:: clip\n\n    Source clip which properties will be written to itself\n\n.. describe:: showtype\n\n    If true, the data type in parenthesis appears next to the property key name\n    \n    Default: false\n\n.. describe:: size\n\n    | Height of the text in pixels (fixed fonts)\n    \n    Default: 16\n\n.. describe:: font\n\n    Font name; \"Terminus\" or \"info_h\" or can be the name of a bdf bitmap font.\n\n    Default: \"Terminus\"\n\n.. describe:: text_color, halo_color\n\n    | Colors for font fill and outline respectively.  See the\n      :doc:`colors <../syntax/syntax_colors>` page for more information on \n      specifying colors.\n    | Default text color is yellow and halo color is black.\n    | halo color MSB have special meaning\n    |   FF (e.g. FF000000) -> no outline + semi transparent background\n    |   FE (e.g. FE000000) -> outline + semi transparent background\n    |   01 (e.g. 01000000) -> no outline + normal display\n    |   00 (e.g. 00000000) -> outline + normal display\n    \n    Default: $FFFF00, $000000 (that is $00FFFF00, $00000000)\n\n.. describe:: bold\n\n    | Using bold letters or not\n\n    Default: false\n\n.. describe:: x, y\n\n    | Reference point of the Info text box area, alignments are\n      calculated relative to that.\n\n    Default: 4, 0 (top left), screen centers or right/bottom when alignment is specified\n\n.. describe:: align\n\n    | an integer number describing at what screen area (or given x,y coordinates)\n      will be the info text box aligned.\n      Values 1-9 are allowed. See your numeric keypad layout, e.g. 7 is top-left,\n      9 is top right, 3: bottom-right, etc..\n\n    Default: 7 (top-left)\n    \n    Note: The individual lines are aligned horizontally as well.\n\n.. describe:: props\n\n    | single string or array of strings\n      - name: exact match\n      - regex: starting \"^\" end with \"$\"\n      - wildcard: contains \"*\"\n      \n      If given, no \"Number of keys\" header is shown.\n\n\nExamples\n--------\n\n::\n\n    ColorBarsHD()\n    propShow(align=1, halo_color=$FF000000)\n    propShow(size=6,bold=true, align=3, halo_color=$FE000000)  \n    propShow(size=16,bold=true, align=5, halo_color=$00000000)\n    propShow(font=\"info_h\", align=9, halo_color=$01000000)\n    \n    ColorBarsHD()\n    PropSet(\"MyProp1\", 121)\n    PropSet(\"MyProp2\", \"Hello Avisynth\")\n    propShow() # display all properties, with header\n    propShow(props=\"*\", align=2) # display all properties, no header, bottom center\n    propShow(props=\"_*\", align=8) # display properties starting with \"_\", top center\n    propShow(props=\"^[^_].*$\", align=9) # display properties NOT starting with \"_\", , top right corner\n\nThe following script aligns Info box to the top right, and propShow to the bottom left.\n    \n::\n\n    ColorBars()\n    propShow(align=1)\n    Info(cpu=false, align=9)\n\n\nChangelog\n---------\n\n+-----------------+-----------------------------------------------------------------------+\n| Version         | Changes                                                               |\n+=================+=======================================================================+\n| AviSynth+ 3.7.4 || Add ``font``, ``text_color``, ``halo_color``, ``bold``  parameter    |\n|                 || Add ``x, y, align`` parameters                                       |\n|                 || add \"props\" parameter with wildcard and regex support                |\n+-----------------+-----------------------------------------------------------------------+\n| AviSynth+ 3.7.1 | display _Matrix, _ColorRange and _ChromaLocation constants with       |\n|                 | friendly names                                                        |\n+-----------------+-----------------------------------------------------------------------+\n| AviSynth+ 3.6.0 | Initial release                                                       |\n+-----------------+-----------------------------------------------------------------------+\n\nBack to :doc:`Internal functions <../syntax/syntax_internal_functions>`.\n\n$Date: 2025/03/04 12:20:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/pulldown.rst",
    "content": "\nPulldown\n========\n\n``Pulldown`` (clip, int a, int b)\n\n\na:b Pulldown\n------------\n\nIn general, **a:b pulldown** (also called **telecine**) means that the first\nframe is represented by \"a\" fields of video, the second frame is represented\nby \"b\" fields of video, which is repeated till the end of the clip. **inverse\ntelecine**: means undoing the telecine.\n\n**Example:**\n\n**2:3 or 3:2 pulldown**: 23.976 -> 29.97 by adding duplicate fields in the\nfollowing way: Thus the first frame is represented by two fields of video,\nthe second frame by three fields of video, which is repeated to the end of\nthe clip:\n\n::\n\n    source: AtAb BtBb CtCb DtDb (four frames)\n    2:3 pulldown: AtAb BtBb BtCb CtDb DtDb (five frames)\n    3:2 pulldown: AtAb AtBb BtCb CtCb DtDb (five frames)\n    etc ...\n\nPulldown as AviSynth filter\n---------------------------\n\n``Pulldown(a,b)`` (with a < b) selects frames a, b, 5+a, 5+b, 2*5+a, 2*5+b,\n... So the filter simply selects two out of every five frames of the source\nvideo. The frame rate is reduced to two-fifths of its original value. Note\nthat a a:b telecine can be undone by ``Pulldown(a,b)`` if a+b=5.\n\n**Example:**\n\n::\n\n    DoubleWeave()\n    Pulldown(0,3)\n\nis the same as undoing a 2:3 (or 3:2) pulldown (ie 29.97 -> 23.976).\n\nSuppose you have material on which 2:3 pulldown is applied, that is\n\n::\n\n    AtAb BtBb CtCb DtDb => AtAb BtBb BtCb CtDb DtDb (five frames)\n\nThe reason you need to use :doc:`DoubleWeave <doubleweave>` first is that many capture\ncards sometimes recombine fields in the \"wrong\" way. In terms of fields, the\n3:2 pulldown sequence is simply \"At Ab Bt Bb Bt Cb Ct Db Dt Db ...\", where\n\"A\" through \"D\" represent the original film frames (before the broadcaster\ntelecined it). But many capture cards the fields into frames with no respect\nfor the pulldown pattern, and you get this:\n\n::\n\n    AtAb BtAb BtBb BtBb BtCb CtCb CtDb DtDb DtDb\n\n``Pulldown(0,3)`` selects frames 0, 3, 5+0, 5+3, 10+0, 10+3, ...\n\n::\n\n    AtAb BtAb BtBb BtBb BtCb CtCb CtDb DtDb DtDb\n     *              *         *              *\n\nthus getting\n\n::\n\n    AtAb BtBb CtCb DtDb\n\n``Pulldown(a,b)`` is implemented internally as\n::\n\n    SelectEvery(5,a,b).AssumeFrameBased\n\n$Date: 2010/01/06 16:01:28 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/reduceby2.rst",
    "content": "=========\nReduceBy2\n=========\n\nSet of filters to resize the width and/or height by 2:\n\n* **HorizontalReduceBy2** reduces the horizontal size of each frame by half.\n* **VerticalReduceBy2** reduces the vertical size by half.\n* **ReduceBy2**, reduces the vertical and horizontal size by half. It is the\n  same as ``HorizontalReduceBy2`` followed by ``VerticalReduceBy2``.\n\nThe filter kernel used is (1/4,1/2,1/4), which is the same as in VirtualDub's\n\"2:1 reduction (high quality)\" filter. This avoids the aliasing problems that\noccur with a (1/2,1/2) kernel.\n\nIf the source video is interlaced, the ``VerticalReduceBy2`` filter will\ndeinterlace it (by field blending) as a side-effect.\n\n.. note::\n\n    Note that, ``ReduceBy2`` is a quick and dirty filter (performance related compromise).\n    Unlike the standard :doc:`resize <resize>` filters, the ``ReduceBy2`` filters do not\n    preserve the position of the image center. It shifts color planes by half of\n    pixel. In fact, ``ReduceBy2()`` is equivalent to:\n\n    ::\n\n        # for RGB\n        BilinearResize(Width/2, Height/2, 0.5, -0.5)\n\n        # for YUY420\n        MergeChroma(BilinearResize(Width/2,Height/2,0.5,0.5),BilinearResize(Width/2, Height/2,1.0,1.0))\n\n        # for YUV422\n        MergeChroma(BilinearResize(Width/2,Height/2,0.5,0.5),BilinearResize(Width/2,Height/2,1.0,0.5))\n\n    See the `\"ReduceBy2() introduces chroma shift\"`_ thread for more information.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    HorizontalReduceBy2 (clip)\n    VerticalReduceBy2 (clip)\n    ReduceBy2 (clip)\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n\nChangelog\n---------\n\n+-----------------+--------------------------------------------------------------------------+\n| Version         | Changes                                                                  |\n+=================+==========================================================================+\n| AviSynth+ r2487 | Horizontal/VerticalReduceBy2: add support for RGB48/64, planar RGB(A)    |\n|                 | and YUV(A).                                                              |\n+-----------------+--------------------------------------------------------------------------+\n| AviSynth+ r2290 | Horizontal/VerticalReduceBy2: add 16/32 bit support.                     |\n+-----------------+--------------------------------------------------------------------------+\n\n$Date: 2023/01/20 19:19:07 $\n\n.. _\"ReduceBy2() introduces chroma shift\":\n    https://forum.doom9.org/showthread.php?t=143692\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/resampleaudio.rst",
    "content": "\nResampleAudio\n=============\n\nHigh-quality audio sample rate converter:\n\n* Accepts any number of channels.\n* The conversion is skipped if the sample rate is already at the given rate.\n* Supports fractional resampling (where *new_rate_denominator* ≠ 1).\n* Note, internal rounding may affect \n  :doc:`AudioDuration <../syntax/syntax_clip_properties>` slightly – see \n  `Examples`_ below. \n\nSee Wikipedia: `Sample-rate conversion`_\n\nSyntax and Parameters\n----------------------\n\n::\n\n    ResampleAudio (clip, int new_rate_numerator, int \"new_rate_denominator\")\n\n.. describe:: clip\n\n    | Source clip. Supported audio sample types: 16-bit integer and 32-bit float. \n    | Other sample types (8-, 24- and 32-bit integer) are automatically \n      :doc:`converted <convertaudio>` to 32-bit float.\n\n.. describe:: new_rate_numerator\n\n    Set the numerator for the new sample rate. \n\n.. describe:: new_rate_denominator\n\n    Set the denominator for the new sample rate.\n\n    Default: 1 \n\n\nExamples\n--------\n\n* Resample audio to 48 kHz::\n\n    source = AviSource(\"c:\\audio.wav\")\n    return ResampleAudio(source, 48000)\n\n* Exact 4% speed up for Pal telecine::\n\n    nfr_num = 25\n    nfr_den = 1\n    AviSource(\"C:\\Film.avi\") # 23.976 fps, 44100Hz\n    ar = Audiorate()\n    # intermediate sample rate:\n    ResampleAudio(ar*FramerateNumerator*nfr_den, FramerateDenominator*nfr_num)\n    # final sample rate:\n    AssumeSampleRate(ar)\n    AssumeFPS(nfr_num, nfr_den, sync_audio=False)\n\n In the example above, the intermediate sample rate needs to be:\n\n    | ``(AudioRate*FramerateNumerator*nfr_den=1)/(FramerateDenominator*nfr_num=25)``\n    | or (44100 * 24000 * 1) / (1001 * 25) = 42293.706294... \n\n But because audio sample rates are always integers, 42293.706294 must be \n rounded to 42294, which results in a time slippage of about 30ms per hour.\n\n\nChangelog\n---------\n\n+----------------+----------------------------------------------------------+\n| Version        | Changes                                                  |\n+================+==========================================================+\n| AviSynth 2.5.6 || Added Float support in ResampleAudio().                 |\n|                || Added Fractional resampling support in ResampleAudio(). |\n+----------------+----------------------------------------------------------+\n| AviSynth 2.5.3 | ResampleAudio now accepts any number of channels.        |\n+----------------+----------------------------------------------------------+\n\n$Date: 2022/02/13 11:10:51 $\n\n.. _Sample-rate conversion:\n    https://en.wikipedia.org/wiki/Sample-rate_conversion\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/resize.rst",
    "content": "==============\nResize Filters\n==============\n\nThe resize filters scale the input video frames to an arbitrary new resolution,\nand can optionally crop the frame before resizing with sub-pixel precision.\n\nThey can be used either for ordinary resizing tasks or as convolution filters.\n\nIn image resizing, a convolution filter is a mathematical tool used to apply various\neffects to an image, such as blurring, sharpening, edge detection, and more. When \nresizing images, convolution filters help in smoothing or sharpening the image to \navoid artifacts like aliasing, which can occur when the image is scaled up or down. \nCommon convolution filters used in resizing include Gaussian, Lanczos, and Bicubic\nfilters.\n\nThe following resizers are included:\n\n* **BicubicResize** is similar to **BilinearResize**, except that instead of a\n  linear filtering function it uses the `Mitchell–Netravali`_ two-part cubic.\n  The parameters ``b`` and ``c`` can be used to adjust the properties of the\n  cubic; they are sometimes referred to as \"blurring\" and \"ringing\" respectively.\n\n  If you are enlarging your video, you will get sharper results with\n  **BicubicResize** than with **BilinearResize**. However, if you are shrinking\n  it, you may prefer BilinearResize as it performs some `antialiasing`_.\n\n* **BilinearResize** uses standard `bilinear filtering`_ and is a good choice\n  for smoothing overly sharp sources.\n\n* **BlackmanResize** is a modification of **LanczosResize** that has better\n  control of `ringing`_ artifacts for high numbers of ``taps``.\n\n* **GaussResize** uses a `gaussian`_ resizer, which unlike the bicubics, does\n  not overshoot – but perhaps does not appear as sharp to the eye.\n  Since 3.7.4 it got an extra ``b``, ``s`` parameters.\n\n* **LanczosResize** is a sharper alternative to **BicubicResize**. It is NOT suited\n  for low bitrate video; the various Bicubic flavours are much better for this.\n\n* **Lanczos4Resize** is a short hand for ``LanczosResize(taps=4)``. It produces\n  sharper images than **LanczosResize** with the default ``taps=3``, especially\n  useful when upsizing a clip.\n\n* **PointResize** is the simplest resizer possible. It uses a Point Sampler or\n  `Nearest Neighbour`_ algorithm, which usually results in a very \"blocky\" image.\n  So, in general this filter should only be used, if you intend to have inferior\n  quality, or you need the clear pixel drawings. Useful for magnifying small\n  areas for examination.\n\n* **SincResize** uses the truncated sinc function. It is very sharp, but prone\n  to `ringing`_ artifacts.\n\n* **SincLin2Resize** (v3.7.3-)\n  A high-quality resizer that supplements SincResize, designed to maintain performance \n  with increased sinc taps for minimal artifacts.\n\n  This is a version of ``SincResize`` with a workaround for the 'kernel edge computing issue'\n  present in the original SincResize kernel. It is slightly sharper compared to other \n  weighted sinc kernels with the same number of taps (such as ``Lanczos`` or ``Blackman``). To \n  suppress computing errors below 1 LSB of 8-bit, a recommended number of taps is greater \n  than 3 or 4. Using too few taps may still expose this issue. For higher precision computing \n  (greater than 8-bit per sample), the minimum number of taps required to shift residual \n  computing errors below 1 LSB may be higher.\n\n* **UserDefined2Resize** (v3.7.3-)\n  A versatile resizer offering fine control over sharpness and ringing, ideal for \n  downsampling and high-quality antialiasing with adjustable parameters.\n\n* **SinPowerResize** (v3.7.3-)\n  An easy-to-adjust resizer with a single control parameter, perfect for downsampling \n  and creating content conditioned to reduce aliasing and ringing.\n\n  Both ``SinPow`` and ``UserDefined2`` resizers allow control over the `acutance`_ effect of the\n  output while minimizing excessive ringing (within a certain range of control parameters). \n  Acutance of the Gauss kernel can be considered the 'zero level,' whereas for SinPow and \n  UserDefined2, it can be greater than zero, depending on the control parameters.\n\n* **Spline16Resize**, **Spline36Resize** and **Spline64Resize** are three\n  `Spline based`_ resizers. They are the (cubic) spline-based resizers from\n  `Panorama tools`_ that fit a spline through the sample points and then derives\n  the filter kernel from the resulting blending polynomials. See `this thread`_\n  for the technical details.\n\n  The rationale for Spline is to be as sharp as possible with less ringing\n  artifacts than **LanczosResize** produces. **Spline16Resize** uses √16 or 4\n  sample points, **Spline36Resize** uses √36 or 6 sample points, etc  ... The\n  more sample points used, the more accurate the resampling. Several resizer\n  comparison pages are given in the `External Links`_ section.\n\n  * **Spline64Resize** may be the most accurate of the Resize filters. [`Dersch`_]\n  * **Spline16Resize** is sharper and rings just a bit (which may be desirable\n    with soft sources), and looks pleasing to the eye when enlarging or reducing\n    in moderate amounts. [`Doom9`_]\n  * **Spline36Resize** is somewhere in between the other two.\n\nAs with any resampling, there are trade-offs to be considered between preservation\n(or augmentation) of image detail and possible artifacts (i.e., oversharpening).\n\nThe set of ``SinPower``/``UserDefined2`` and ``Sinc``/``SincLin2``/``Lanczos``/``Blackman`` resizers form a \ncomplementary set for a sinc-based workflow in digital imaging, allowing controlled \nsharpness and ringing. ``SinPowerResize`` or ``UserDefined2Resize`` are used for content creation \nas downscaling (compressing), while any sinc-based resizer can be used for upscaling \nfor display or intermediate processing (interpolation, decompressing).\n\nMost resizers (except Point?) can be used for convolution processing with their kernel \nwithout resampling. To force the processing even when dimensions are unchanged (no phyisical resizing\nhappens), use the ``force`` parameter (since v3.7.4)\n(Before 3.7.4 to enable (force) processing for unchanged dimensions, users must set non-zero \nvalues for src_left and/or src_top parameters (depending on the required dimensions for processing.\nTo avoid visible shifting, the values must be very low floats - like 0.000001 - need to check the \nlowest acceptable non-zero float value).\n\nSince 3.7.4, resizers are aware of the chroma placement of color subsampled formats (411, 420, 422).\nEither the ``_ChromaLocation`` frame property or the new, direct ``placement`` parameter is used.\nPreviously, a fixed \"center\" placement was assumed, which, for example, resulted in chroma shifts when\na 422 format with MPEG-2 (left) chroma placement was downsized.\n\nIn 3.7.4, a new ``keep_center`` parameter was introduced as well, allowing one to disable the chroma \nplacement corrections altogether.\n\nResizers in ConvertToXXXX\n-------------------------\n\nResizers are implicitely work in :doc:`ConvertToXXX <convert>` function family,\nwhen U and V chroma must be converted (chroma placement or subsampling rate change).\n\nChroma resamplers can be specified for the converters, along with their \nparameters. One should specify the resizer type, e.g. ``SincLin2Resize`` is 'sinclin2',\n``SinPowerResize`` is \"sinpow\" and ``UserDefined2Resize`` is called \"userdefined2\" there.\n\nThe control parameters of the resizers are to be given in \"param1\", \"param2\" and \n\"param3\", they are valid (not all - depends on the resizer type). They are used  \nif \"chromaresample\" parameter exists. Since 3.7.3 it is possible to use chromaresample \nwith nondefault settings.\n  \n- param1 will set 'taps', 'b', or 'p', while param2 sets 'b' or 'c' parameter for resizers where applicable.\n- param3 sets 's' parameter for userdefined2 and gauss\n\n  * b,c: bicubic (1/3.0, 1/3.0)\n  * b,c,s: userdefined2 (121.0, 19.0, 2.3)\n  * taps: lanczos (3), blackman (4), sinc (4), sinclin2 (15)\n  * p,b,s: gauss (30.0, 2.0, 4.0) (``b`` and ``s`` since 3.7.4) \n  * p: sinpow (2.5)\n  * 'param1', 'param2' and \"param3\" are always float. For 'taps' 'param1' is truncated to integer internally.\n    When a resizer does not use one or more parameters they are simply ignored.\n\nResizers in AddBorders and LetterBox\n------------------------------------\n\nOptionally, when a filtering radius is given, a custom resizer can be added to :doc:`AddBorders <addborders>` and\n:doc:`LetterBox <letterbox>`. In these filters the transient areas (boundary of the new borders) are filtered, \nin order to prevent ringing e.g. in a subsequent upscale.\n\nThe filters are used purely as convolution filters, no real resize happens.\n\nEverything is the same as mentioned above in ``Resizers in ConvertToXXXX`` section, except, that \n``'gauss'`` default parameters are tunes for blurring:\n\n* p,b,s: gauss (p=10, b=2.71828182, s=0)\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    BicubicResize (clip, int target_width, int target_height, float \"b\", float \"c\",\n                   float \"src_left\", float \"src_top\", float, \"src_width\", float \"src_height\",\n                   int \"force\", bool \"keep_center\", string \"placement\")\n\n    BilinearResize (clip, int target_width, int target_height,\n                    float \"src_left\", float \"src_top\", float \"src_width\", float \"src_height\",\n                    int \"force\", bool \"keep_center\", string \"placement\")\n\n    BlackmanResize (clip, int target_width, int target_height,\n                    float \"src_left\", float \"src_top\", float \"src_width\", float \"src_height\", \n                    int \"taps\", int \"force\", bool \"keep_center\", string \"placement\")\n\n    LanczosResize (clip, int target_width, int target_height,\n                   float \"src_left\", float \"src_top\", float \"src_width\", float \"src_height\",\n                   int \"taps\", int \"force\", bool \"keep_center\", string \"placement\")\n\n    Lanczos4Resize (clip, int target_width, int target_height,\n                    float \"src_left\", float \"src_top\", float \"src_width\", float \"src_height\",\n                    int \"force\", bool \"keep_center\", string \"placement\")\n\n    PointResize (clip, int target_width, int target_height,\n                 float \"src_left\", float \"src_top\", float \"src_width\", float \"src_height\",\n                 int \"force\", bool \"keep_center\", string \"placement\")\n\n    Spline16Resize (clip, int target_width, int target_height,\n                    float \"src_left\", float \"src_top\", float \"src_width\", float \"src_height\",\n                    int \"force\", bool \"keep_center\", string \"placement\")\n\n    Spline36Resize (clip, int target_width, int target_height,\n                    float \"src_left\", float \"src_top\", float \"src_width\", float \"src_height\",\n                    int \"force\", bool \"keep_center\", string \"placement\")\n\n    Spline64Resize (clip, int target_width, int target_height,\n                    float \"src_left\", float \"src_top\", float \"src_width\", float \"src_height\",\n                    int \"force\", bool \"keep_center\", string \"placement\")\n\n    GaussResize (clip, int target_width, int target_height,\n                 float \"src_left\", float \"src_top\", float \"src_width\", float \"src_height\",\n                 float \"p\", float \"b\", float \"s\", int \"force\",\n                 bool \"keep_center\", string \"placement\")\n\n    SincResize (clip, int target_width, int target_height,\n                float \"src_left\", float \"src_top\", float \"src_width\", float \"src_height\",\n                int \"taps\", int \"force\", bool \"keep_center\", string \"placement\")\n\n    SinPowerResize (clip, int target_width, int target_height,\n                    float \"src_left\", float \"src_top\", float \"src_width\", float \"src_height\",\n                    float \"p\", int \"force\", bool \"keep_center\", string \"placement\")\n\n    SincLinResize (clip, int target_width, int target_height,\n                   float \"src_left\", float \"src_top\", float \"src_width\", float \"src_height\",\n                   int \"taps\", int \"force\", bool \"keep_center\", string \"placement\")\n\n    UserDefined2Resize (clip, int target_width, int target_height, float \"b\", float \"c\", float \"s\",\n                        float \"src_left\", float \"src_top\", float \"src_width\", float \"src_height\",\n                        int \"force\", bool \"keep_center\", string \"placement\")\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n.. describe:: target_width, target_height\n\n    Width and height of the returned clip.\n\n.. describe:: b, c, s\n\n    Parameters ``b`` for **BicubicResize** and **UserDefined2Resize** and **GaussResize** only.\n\n    Parameters ``c`` for **BicubicResize** and **UserDefined2Resize** only.\n\n    Parameter ``s`` for **GaussResize** and **UserDefined2Resize** only.\n\n    **BicubicResize**\n    \n    The default for both ``b`` and ``c`` is 1/3, which were recommended by\n    Mitchell and Netravali for having the most visually pleasing results.\n\n    Set [``b`` + 2\\ ``c`` = 1] for the most numerically accurate filter. This\n    gives, for ``b=0``, the maximum value of 0.5 for ``c``, which is the\n    `Catmull-Rom spline`_ and a good suggestion for sharpness.\n\n    Larger values of ``b`` and ``c`` can produce interesting op-art effects –\n    for example, try ``(b=0, c= -5.0)``.\n\n    As ``c`` exceeds 0.6, the filter starts to `\"ring\"`_ or overshoot. You won't\n    get true sharpness – what you'll get is exaggerated edges. Negative values\n    for ``b`` (although allowed) give undesirable results, so use ``b=0`` for\n    values of ``c`` > 0.5.\n\n    With ``(b=0, c=0.75)`` the filter is the same as `VirtualDub's \"Precise Bicubic\"`_.\n\n    | **BicubicResize** may be the most visually pleasing of the Resize filters\n      for downsizing to half-size or less. `Doom9 [2]`_\n    | Try the default setting, ``(b=0, c=0.75)`` as above, or ``(b= -0.5, c=0.25)``.\n\n    Default: 1/3, 1/3\n\n    **GaussResize**\n    \n    Parameters\n    \n    * p: Controls the blurring. Valid range: 0.01 to 100. (before 3.7.4: 0.1 to 100)\n    * b: Controls the blurring. Valid range: 1.5 to 3.5. Filter kernel is ``b^(-p*0.1*(x^2))``.\n      Default ``b`` is 2.0 to be compatible with pre-3.7.4 use cases. If high precision \n      Gauss kernel is required (for example for filtering applications) it is recommended to \n      use the base of the natural logarithm 2.71828182. \n    * s (support): Controls the support size. Default is 4. Valid range: 0.1 to 150.\n    \n      Special case: ``s==0`` (auto):\n      \n      **s** is calculated from ``b`` and ``p`` parameters for 0.01 of residual kernel value.\n      as ``s = sqrt(4.6 / ((p_param * 0.1) * ln(b)))``, original equation is \n      ``s = sqrt(-ln(0.01)/(p_param*ln(b))``, where ``ln(0.01)`` is about ``-4.6`` \n      and ``-ln(0.01)`` is ``4.6``, and ``p`` and ``b`` are directly entered by \n      user parameter values.\n    \n    Default: p=30.0, b=2.0, s=4.0\n    \n    **UserDefined2Resize**\n    \n    UserDefined2Resize is a flexible resizer that allows for fine control over the \n    sharpness and ringing of the output. It is particularly useful for downsampling \n    and high-quality antialiasing.\n    \n    Parameters:\n\n    * b: Controls the blurring. Optimal range: -50 to 250.\n    * c: Controls the ringing. Optimal range: -50 to 250.\n    * s (support): Controls the support size. Default is 2.3. Valid range: 1.5 to 15.0.\n\n    For b, the valid range is -50 to 250 (values outside this range are typically nonsensical and\n    are clipped to -50 to 250). However, recommended c values may be as low as -40, so the lower range \n    clipping can be expanded to -60 or lower.\n\n    The typical usable range for b is 70 to 130, and for c is -30 to 23.\n\n    The b and c values are generally interconnected via tables of recommended values. Typically, b controls \n    the 'sharpness look/makeup,' while c supplements to balance the kernel to produce as little ringing as \n    possible.\n\n    .. image:: ./pictures/userdefined2_b_c.png\n\n    ``ovsh`` means overshoot. Columns are classified as an 'overshoot/acutance' view of the output, \n    but only a single combination of ``b`` and ``c`` may produce minimal ringing for each ``b`` and\n    ``c`` pair (which may also depend on source sharpness, such as the Fourier spectrum). \n    \n    The table of recommended ``b`` and ``c`` values is mostly valid for high downsampling \n    ratios like 10:1 or more, but typically usable for ratios down to about 2:1 and less.\n\n    * b > 130: Typically close to ``GaussResize`` with 'zero acutance' ('film' look/makeup).\n    * b < 95: Produces high levels of sharpness/acutance ('video' look/makeup).\n    \n    For the initial setup, the c value must follow the b value from the table and may be \n    adjusted for each source to minimize ringing.\n\n    Internally, it is based on a sum of weighted sinc functions by b and c parameters. \n    With b = c = 16, it is equivalent to SincResize with the given support size by the s parameter.\n\n    **s** parameter controls the used part of the computed kernel in the resampler. Also affect the resamplers' \n    performance (more support - less performance). Most sinc-based resizers have ``support``=``taps``.\n\n    For ``UserDefine2Resize`` it is possible to manually control support value: Low values like \n    ``1.8`` to ``2.2`` may give some additional 'crispening' effect (while can cause more ringing). \n    High values like 3..4 and more required for more linear processing (highest level of ringing \n    suppression). Also the 'wide-long' soft kernels like b=210 c=98 may require larger support to save from too early kernel truncation in a resampler. If the kernel decays very fast - too much support param may be useless wasting of the computing resources. Higher values of support param may be required for highest precision computing using float samples formats.\n\n    Effects:\n\n    * Allows for precise control over the sharpness and ringing of the output.\n    * Can produce very soft (film-look) or sharper (video-look) results depending on the \n      b and c values.\n    * Increasing the s parameter allows for better control over residual ringing but makes\n      the result a bit softer.\n    * The default values of b and c (121/19) create a soft film-like look/makeup. It may be better to use \n      sharper values like 80/-20 with higher 'sharpness/acutance'\n\n    Defaults: ``b=121.0``, ``c=19.0``, ``s=2.3``\n\n.. describe:: src_left, src_top\n\n    See `Cropping`_ section below.\n\n    Cropping of the left and top edges respectively, in pixels, before resizing.\n\n    Default: 0.0, 0.0\n\n.. describe:: src_width, src_height\n\n    See `Cropping`_ section below.\n\n    As with :doc:`Crop <crop>`, these arguments have different functionality,\n    depending on their value:\n\n    * If  > zero, these set the **width** and **height** of the clip before resizing.\n    * If <= zero, they set the cropping of the **right** and **bottom** edges\n      respectively, before resizing.\n\n    Note, there are certain limits:\n\n    * clip.Width must be >= (``src_left`` + **width**)\n    * clip.Width must be >  (``src_left`` + **right**)\n    * clip.Height must be >= (``src_top`` + **height**)\n    * clip.Height must be >  (``src_top`` + **bottom**)\n\n    ...otherwise it would enlarge (\"un-crop\") the clip, or reduce width or height\n    to 0, which is not allowed.\n\n    Default: source width, source height\n\n.. describe:: taps\n\n    Parameters for **BlackmanResize**, **LanczosResize**, **SincResize** \n    and **SincLin2Resize** only.\n\n    Basically, taps affects sharpness. Equal to the number of filter `lobes`_\n    (ignoring mirroring around the origin).\n\n    Note: the input argument named taps should really be called \"lobes\". When\n    discussing resizers, \"taps\" has a different meaning, as described below:\n\n    “So when people talk about Lanczos2, they mean a 2-lobe Lanczos-windowed\n    sinc function. There are actually 4 lobes -- 2 on each side...\n\n    For upsampling (making the image larger), the filter is sized such that the\n    entire equation falls across 4 input samples, making it a 4-tap filter. It\n    doesn't matter how big the output image is going to be - it's still just 4\n    taps. For downsampling (making the image smaller), the equation is sized so\n    it will fall across 4 *destination* samples, which obviously are spaced at\n    wider intervals than the source samples. So for downsampling by a factor of\n    2 (making the image half as big), the filter covers 8 input samples, and\n    thus 8 taps. For 3X downsampling, you need 12 taps, and so forth.\n\n    The total number of taps you need for downsampling is the downsampling\n    ratio times the number of lobes, times 2. And practically, one needs to\n    round that up to the next even integer. For upsampling, it's always 4 taps.”\n    `Don Munsil (avsforum post)`_ | `mirror`_.\n\n    **SincLin2Resize**\n    \n    ``SincLin2Resize`` is a workaround supplement to ``SincResize``.\n\n    It provides at least ``taps/2`` full-strike sinc taps (lobes ?) count before beginning of linear \n    weighting to zero at the end of the kernel. Recommended to set SincLin2(taps) to two times larger \n    in comparison with previously used SincResize(taps) in old projects. While performance of the resampler \n    will degrade proportionally to taps value used\". Taps param controls the balance between performance \n    and quality and ringing length (if present).\n    \n    Effects:\n\n    * Provides better performance in terms of sinc lobes without degradation from \n      weighting.\n    * Useful for high-quality resizing with minimal artifacts.\n\n    Range:\n\n    * 1-100 for **BlackmanResize** and **LanczosResize**\n    * 1-150 for **SincResize**\n    * 1-40 for **SincLine2Resize**\n\n    Default:\n\n    * 3 for **LanczosResize**\n    * 4 for **BlackmanResize** and **SincResize**\n    * 15 for **SincLin2Resize**\n\n.. describe:: p\n\n    Parameter for **GaussResize** and **SinPowerResize** only.\n\n    Sharpness. Range from about 1 to 100, with 1 being very blurry and 100 being\n    very sharp.\n\n    **GaussResize**\n    \n    Original equation is ``s = sqrt(-ln(0.01)/(p*ln(b))``.\n\n    As seen, the ``p`` parameter passed to GaussResize is internally scaled by 0.1. (We don't \n    know why, probably for historical reasons, when this arguments was integer (?)). \n    So from user's view original equation is ``s = sqrt(-ln(0.01)/((p_param * 0.1)*ln(b))``.\n    ``p`` and ``b`` are directly entered by user params values.\n    For more details see the description of b, c and s parameters.\n\n    Default: 30.0\n\n    **SinPowerResize**\n    \n    SinPowerResize is designed for downsampling and can also be used as a convolution filter. \n    It is easier to adjust with a single control parameter.\n    \n    ``p`` Controls the sharpness. Optimal range: 2.5 to 3.5. Where 2.5 is very sharp and 3.0+\n    is closer to Gauss in softness.\n    \n    Effects:\n\n    * Provides a balance between sharpness and softness.\n    * Useful for creating content conditioned to the band-limited channel, reducing aliasing\n      and Gibbs-ringing.\n    * Can enhance visual sharpness (`acutance`_) by producing single lobe peaking.\n    \n    Default: 2.5\n\n.. describe:: force\n\n    Force the resizing or convolution with resize kernel (filtering) process even if the dimensions \n    remain unchanged and ``src_width`` or ``src_top`` are zero. Useful to intentionally prevent sudden \n    visual differences that might occur if resizing is unexpectedly skipped or if convolution only \n    (filtering) without resize is required.\n    Some sources say it must be co-used with ``keep_center=false`` -- to be checked.\n    \n    * 0 - return unchanged if no resize needed\n    * 1 - force H - Horizontal resizing phase\n    * 2 - force V - Vertical resizing phase\n    * 3 - force H and V\n\n    ::\n\n        version.crop(8,32,16,16)\n        w=Width()\n        h=height()\n        force=3\n        # at frame 50 Force=0 (default) omits resizing, thus the \n        # intentional blur.\n        animate(0,100,\"bicubicresize\",\\\n        16,16,1.0/3.0,1.0/3.0,-1.0,-1.0,w,h,force,\\\n        16,16,1.0/3.0,1.0/3.0, 1.0, 1.0,w,h,force)\n\n    Default: 0\n\n.. describe:: keep_center (boolean) \n\n    If ``true`` (default), the chroma shift from \"placement\" is now respected when resizing chroma.\n    ``fmtconv`` documentation mentions that this must be false for convolution filter use, \n    when no resize occurs and ``force`` is not 0.\n\n    Default: True\n\n.. describe:: placement (string) \n\n    Specifies chroma placement. Valid options are \"auto\", \"mpeg2\", \"center\", etc.,\n    similar to ConvertToXXXX and Text.\n    \n    - ``\"MPEG2\"`` (synonyms: ``\"left\"``)\n      Subsampling used in MPEG-2 4:2:x and most other formats. Chroma samples are located on the left pixel column of the group (default).\n    - ``\"MPEG1\"`` (synonyms: ``\"jpeg\"``, ``\"center\"``)\n      Subsampling used in MPEG-1 4:2:0. Chroma samples are located on the center of each group of 4 pixels.\n    - ``\"DV\"``\n      Like MPEG-2, but U and V channels are co-sited vertically: V on the top row, and U on the bottom row. For 4:1:1, chroma is located on the leftmost column.\n    - ``\"top_left\"``\n      Subsampling used in UHD 4:2:0. Chroma samples are located on the top left pixel column of the group.\n    - ``bottom_left`` 4:2:0 only\n    - ``bottom``   4:2:0 only \n\n    The default is \"auto\", which reads the frame property ``_ChromaLocation`` for 420, 422, and 411 \n    formats. The chroma placement is ignored when ``keep_center`` is set to ``False`` or in \n    ``PointResize``. Frame property ``_ChromaLocation`` is only read, not set.\n\n    The positions of the sampling points are relative to the frame's top/left border in plane coordinates.\n    For reference, the frame border is at 0.5 units of luma from the first luma sampling point, \n    meaning the luma sampling point is at the pixel's center. RGB planes all behave like a luma plane\n    with pixel center placed sampling position (0.5, 0.5).\n    For more information, visit this link. http://www.mir.com/DMG/chroma.html\n    \n    Rules:\n    \n    The used chroma placement is\n    \n    - read from ``\"_ChromaLocation\"`` frame property, otherwise ``\"center\"``\n    - override or set from ``\"placement\"`` parameter if parameter is other than ``\"auto\"``\n    - if ``\"auto\"`` + have frame property -> use frame property\n    - if ``\"auto\"`` + no frame property -> use ``\"center\"``\n    - no frame property and no parameter -> use ``\"center\"``\n\n    Note that Avisynth does not take into account fieldbased or interlaced material.\n\n    ::\n\n        ColorBarsHD(1024,768)\n        ConvertToYV16() # sets \"_ChromaLocation\" to 0 (mpeg2 / left)\n        # mimic pre-v3.7.4 Avisynth, results in heavy chroma shift:\n        a=GaussResize(width/6, height/6, placement=\"center\")\n        # set \"left\", which is the same as in frame propery, so b and c are equal\n        b=GaussResize(width/6, height/6, placement=\"left\")\n        # same as with additional placement=\"auto\":\n        c=GaussResize(width/6, height/6)\n        Interleave(a,b,c)\n\n\n    Default: \"auto\"\n\n.. _resize-cropping:\n\nCropping\n--------\n\n* All resizers have an expanded syntax which **crops** the frame before resizing::\n\n    BilinearResize(100, 150, src_left=10, src_top=10, src_width=200, src_height=300)\n\n ...or more succinctly::\n\n    BilinearResize(100, 150, 10, 10, 200, 300)\n\n* The operations are the same as if you put :doc:`Crop <crop>` before the Resize::\n\n    Crop(10, 10, 200, 300).BilinearResize(100, 150)\n\n* The cropping parameters are all :doc:`floating point <../syntax/syntax_script_variables>`.\n  This allows any **Resize** filter to be used as a sub-pixel shifter. [`IanB`_]\n\n* **PointResize** cannot do subpixel shifting because it uses only integer pixel\n  coordinates.\n\n* Note that :doc:`Crop <crop>` gives a hard boundary, whereas the **Resize**\n  filters interpolate pixels outside the cropped region – depending on the\n  resizer kernel – bilinear, bicubic etc, and not beyond the edge of the image.\n\n* As a general rule,\n    * :doc:`Crop <crop>` any hard borders or noise; **Resize** cropping may\n      propagate the noise into the output.\n    * Use **Resize** cropping to maintain accurate edge rendering when excising\n      a part of a complete image.\n\n* Negative cropping is allowed; this results in repeated edge pixels as shown\n  below::\n\n    FFImageSource(\"resize-sintel-6291.jpg\")\n    BilinearResize(Width, Height, -32, -32, Width, Height)\n\n .. list-table::\n\n     * - .. figure::  pictures/resize-sintel-6291.jpg\n\n            Original\n\n       - .. figure:: pictures/resize-sintel-6291-shift.jpg\n\n            Repeated edge pixels\n\n\nExamples\n--------\n\n* Cropping::\n\n    Crop(10, 10, 200, 300).BilinearResize(100, 150)\n\n which is nearly the same as::\n\n    BilinearResize(100, 150, 10, 10, 200, 300)\n\n* Load a video file and resize it to 240x180 (from whatever it was before)::\n\n    AviSource(\"video.avi\").BilinearResize(240,180)\n\n* Load a 720x480 (`Rec. 601`_) video and resize it to 352x240 (`VCD`_),\n  preserving the correct aspect ratio::\n\n    AviSource(\"dv.avi\").BilinearResize(352, 240, 8, 0, 704, 480)\n\n which is the same as::\n\n    AviSource(\"dv.avi\").BilinearResize(352, 240, 8, 0, -8, -0)\n\n* Extract the upper-right quadrant of a 320x240 video and zoom it to fill the\n  whole frame::\n\n    BilinearResize(320, 240, 160, 0, 160, 120)\n\n\nNotes\n-----\n\n* AviSynth has completely separate vertical and horizontal resizers. If input is\n  the same as output on one axis, that resizer will be skipped. The resizer with\n  the smallest downscale ratio is called first; this is done to preserve maximum\n  quality, so the second resizer has the best possible picture to work with.\n  :doc:`Data storing <../FilterSDK/DataStorageInAviSynth>` will have an impact on\n  what `mods`_ should be used for sizes when resizing and cropping; see\n  :ref:`Crop Restrictions <crop-restrictions>`.\n\n\nExternal Links\n--------------\n\n* `AviSynth resize filter comparison`_ (hermidownloads.craqstar.de)\n* `Upscaling in AviSynth – Comparison of resizers`_ (jeanbruenn.info)\n* `Testing Interpolator Quality`_ (Helmut Dersch, Technical University Furtwangen)\n* `Discussion of resizers for downsizing`_ (doom9.org)\n* `Resampling guide`_ (guide.encode.moe)\n* Github discussion on newly added resizer kernels: https://github.com/AviSynth/AviSynthPlus/issues/337\n* `fmtconv`_ (https://gitlab.com/EleonoreMizo/fmtconv)\n\n\nChangelog\n---------\n\n+-----------------+---------------------------------------------------------------+\n| Version         | Changes                                                       |\n+=================+===============================================================+\n| 3.7.4           || Add \"force\" parameter                                        |\n|                 || Add \"keep_center\" parameter                                  |\n|                 || Add \"placement\" parameter                                    |\n|                 || Resizers now respect chroma placement setting                |\n|                 || GaussResize: add \"b\" and \"s\" parameters                      |\n+-----------------+---------------------------------------------------------------+\n| 3.7.3           | Add SinPowerResize, SincLin2Resize, UserDefined2Resize        |\n+-----------------+---------------------------------------------------------------+\n| AviSynth+ r2768 | Resizers: don't use crop at special edge cases to avoid       |\n|                 | inconsistent results across different parameters/colorspaces. |\n+-----------------+---------------------------------------------------------------+\n| AviSynth+ r2664 | AVX2 resizer possible access violation in extreme resizes     |\n|                 | (e.g. 600->20)                                                |\n+-----------------+---------------------------------------------------------------+\n| AviSynth+ r2632 || Fix: Resizers for 32 bit float rare random garbage on right  |\n|                 |  pixels (simd code NaN issue)                                 |\n|                 || Completely rewritten 16bit and float resizers, much faster   |\n|                 |  (and not only with AVX2)                                     |\n|                 || 8 bit resizers: AVX2 support.                                |\n+-----------------+---------------------------------------------------------------+\n| AviSynth+ r2487 || Added support for RGB48/64, Planar RGB 8/16/Float formats.   |\n|                 || Added support for Alpha in planar RGBA and YUVA formats.     |\n+-----------------+---------------------------------------------------------------+\n| AviSynth+ r2290 | Added support for 16/32 bit YUV formats (C routine only).     |\n+-----------------+---------------------------------------------------------------+\n| AviSynth+ r1858 | Fix: RGB resizers shift horizontally to the opposite          |\n|                 | direction when ``src_left`` param is used.                    |\n+-----------------+---------------------------------------------------------------+\n| AviSynth 2.6.0  | Added ``SincResize``.                                         |\n+-----------------+---------------------------------------------------------------+\n| AviSynth 2.5.8  | Added ``BlackmanResize, Spline64Resize``.                     |\n+-----------------+---------------------------------------------------------------+\n| AviSynth 2.5.6  || Added ``Spline16Resize, Spline36Resize, GaussResize``.       |\n|                 || Added ``taps`` parameter in LanczosResize.                   |\n|                 || Added offsets in Crop part of xxxResize.                     |\n+-----------------+---------------------------------------------------------------+\n| AviSynth 2.5.5  | Added ``Lanczos4Resize``.                                     |\n+-----------------+---------------------------------------------------------------+\n\n\n$Date: 2025/03/23 11:45:00 $\n\n.. _fmtconv:\n    https://gitlab.com/EleonoreMizo/fmtconv\n.. _acutance:\n    https://en.wikipedia.org/wiki/Acutance\n.. _Mitchell–Netravali:\n    http://en.wikipedia.org/wiki/Mitchell%E2%80%93Netravali_filters\n.. _antialiasing:\n    http://en.wikipedia.org/wiki/Spatial_anti-aliasing#Examples\n.. _bilinear filtering:\n    http://en.wikipedia.org/wiki/Bilinear_filtering\n.. _ringing:\n    http://en.wikipedia.org/wiki/Ringing_artifacts\n.. _gaussian:\n    http://en.wikipedia.org/wiki/Gaussian_filter\n.. _Nearest Neighbour:\n    http://en.wikipedia.org/wiki/Nearest-neighbor_interpolation\n.. _Spline based:\n    http://en.wikipedia.org/wiki/Spline_interpolation\n.. _Panorama tools:\n    http://panotools.sourceforge.net/\n.. _this thread:\n    http://forum.doom9.org/showthread.php?t=147117\n.. _Dersch:\n    http://web.archive.org/web/20060827184031/http://www.path.unimelb.edu.au/~dersch/interpolator/interpolator.html\n.. _Doom9:\n    http://forum.doom9.org/showthread.php?p=1689519#post1689519\n.. _Catmull-Rom spline:\n    http://en.wikipedia.org/wiki/Cubic_Hermite_spline#Catmull.E2.80.93Rom_spline\n.. _\"ring\":\n    http://en.wikipedia.org/wiki/Ringing_artifacts\n.. _VirtualDub's \"Precise Bicubic\":\n    http://www.virtualdub.org/blog/pivot/entry.php?id=95\n.. _Doom9 [2]:\n    http://forum.doom9.org/showthread.php?t=172871&page=2\n.. _lobes:\n    http://en.wikipedia.org/wiki/Lanczos_resampling#Lanczos_kernel\n.. _Don Munsil (avsforum post):\n    https://www.avsforum.com/threads/lanczos-vs-bicubic-comparison.460922/page-2#post-4760581\n.. _mirror:\n    http://avisynth.nl/index.php/Lanczos_lobs/taps\n.. _IanB:\n    http://forum.doom9.org/showpost.php?p=938102&postcount=2\n.. _Rec. 601:\n    http://en.wikipedia.org/wiki/Rec._601\n.. _VCD:\n    http://en.wikipedia.org/wiki/Video_CD\n.. _AviSynth resize filter comparison:\n    http://web.archive.org/web/20090422150849/http://hermidownloads.craqstar.de/videoresizefiltercomparasion/\n.. _mods:\n    http://avisynth.nl/index.php/Modulo\n.. _Upscaling in AviSynth – Comparison of resizers:\n    http://web.archive.org/web/20140207171106/http://jeanbruenn.info/2011/10/30/upscaling-in-avisynth-comparison-of-resizers/\n.. _Testing Interpolator Quality:\n    http://web.archive.org/web/20060827184031/http://www.path.unimelb.edu.au/~dersch/interpolator/interpolator.html\n.. _Discussion of resizers for downsizing:\n    http://forum.doom9.org/showthread.php?t=172871\n.. _Resampling guide:\n    https://guide.encode.moe/encoding/resampling.html\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/reverse.rst",
    "content": "\nReverse\n=======\n\n**Reverse** makes a clip play in reverse. This is useful for watching people\nwalk backwards while listening to hidden satanic messages.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    Reverse (clip)\n\n.. describe:: clip\n\n    Source clip.\n\n.. note::\n    Fields :doc:`parity <parity>` (Top Field First - Bottom Field First) \n    of interlaced clip will be changed.\n\n$Date: 2022/02/04 20:14:59 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/segmentedsource.rst",
    "content": "==============================================\nSegmentedAviSource / SegmentedDirectShowSource\n==============================================\n\nThese filters automatically load and join up to 100 clips each:\n\n* `SegmentedAviSource`_ loads AVI files using AviSource and joins them together\n  using :doc:`UnalignedSplice <splice>`.\n\n* `SegmentedDirectShowSource`_ works the same way, but calling DirectShowSource\n  in place of AviSource.\n\nParameters are the same as :doc:`AviSource <avisource>` and\n:doc:`DirectShowSource <directshowsource>`. See respective pages for full\ndocumentation.\n\n\nSegmentedAVISource\n------------------\n\n**SegmentedAviSource** loads up to 100 AVI files per *base_filename* using\n:doc:`AviSource <avisource>` and joins them using :doc:`UnalignedSplice <splice>`.\nAs with AviSource there is built-in `Audio Compression Manager`_ support\nfor decoding compressed audio tracks (MP3, AAC, AC3, etc).\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    SegmentedAVISource (string base_filename [, ...], bool \"audio\", string \"pixel_type\"\n                        string \"fourCC\", int \"vtrack\", int \"atrack\", bool \"utf8\")\n\n.. describe:: base_filename\n\n    Full or relative path to one or more filenames. Each given filename will\n    serve as the \"base\" filename for loading clips. For example,\n    ``SegmentedDirectShowSource(\"d:\\filename.ext\")`` will load the files\n    d:\\filename.\\ **00**\\ .ext, d:\\filename.\\ **01**\\ .ext and so on, through\n    d:\\filename.\\ **99**\\ .ext. Any files in this sequence that don't exist or\n    do not have the same media properties as the first clip will be skipped.\n    See `Notes`_ below for information on loading clips in multiple directories.\n    `UTF-8`_ filenames are supported when ``utf8=true``.\n\n.. describe:: audio\n\n    If true, load the first audio stream, or the stream specified by ``atrack``\n    if present. If false, audio is disabled.\n\n    Default: true\n\n.. describe:: pixel_type\n\n    Chooses the output color format of the decompressor. Valid values are listed\n    in the table below. This argument has no effect if the video is uncompressed,\n    as no decompressor will be used in that case. See the\n    :ref:`10+ bit inputs <AVISource-hbd>` section for a full list of pixel types.\n\n    * If omitted or \"FULL\", AviSynth will use the first format supported by the\n      decompressor, in the order shown in the table below.\n    * If \"AUTO\", AviSynth will use the alternate (older) order as shown.\n\n      .. table::\n          :widths: auto\n\n          +------------+-------+-------+-------+--------+-------+--------+--------+\n          | pixel_type | Color formats, listed by decoding priority (high to low) |\n          +============+=======+=======+=======+========+=======+========+========+\n          | FULL       | YV24  | YV16  | YV12  | YV411  | YUY2  | RGB32  | RGB24  |\n          +------------+-------+-------+-------+--------+-------+--------+--------+\n          | AUTO       |       |       | YV12  |        | YUY2  | RGB32  | RGB24  |\n          +------------+-------+-------+-------+--------+-------+--------+--------+\n\n    In other words, if you don't specify anything, it will try to output YV24;\n    if that isn't possible it tries YV16, and if that isn't possible it tries\n    YV12, etc ...\n\n    For `planar`_ color formats, adding a '+' prefix, e.g.\n    ``SegmentedAVISource(..., pixel_type=\"+YV12\")``, tells AviSynth the video\n    rows are DWORD aligned in memory instead of packed. **This can fix skew or\n    tearing of the decoded video** with bad codecs when the width of the picture\n    is not divisible by 4.\n\n    Default: \"FULL\"\n\n.. describe:: fourCC\n\n    Forces AviSynth to use a specific decoder instead of the one specified in\n    the source file. See `FourCC`_ for more information.\n\n    Default: auto from source\n\n.. describe:: vtrack\n\n    Specifies a numbered video track. Track numbers start from zero, and are\n    guaranteed to be continuous (i.e. there must be a track 1 if there is a\n    track 0 and a track 2). If no video stream numbered ``vtrack`` exists, an\n    error will be raised.\n\n    Default: 0\n\n.. describe:: atrack\n\n    Specifies a numbered audio track. Track numbers start from zero, and are\n    guaranteed to be continuous (i.e. there must be a track 1 if there is a\n    track 0 and a track 2). If no audio stream numbered ``atrack`` exists, no\n    error will be raised, and no audio will be returned.\n\n    Default: 0\n\n.. describe:: utf8\n\n    If true, file name is treated as `UTF-8`_.\n\n    Default: false\n\nSegmentedDirectShowSource\n-------------------------\n\n**SegmentedDirectShowSource** loads up to 100 files per *base_filename* using\n:doc:`DirectShowSource <directshowsource>` and joins them using :doc:`UnalignedSplice <splice>`.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    SegmentedDirectShowSource (string base_filename [, ...], float \"fps\", bool \"seek\",\n                               bool \"audio\", bool \"video\", bool \"convertfps\", bool \"seekzero\",\n                               int \"timeout\", string \"pixel_type\")\n\n.. describe:: base_filename\n\n    Full or relative path to one or more filenames. Each given filename will\n    serve as the \"base\" filename for loading clips. For example,\n    ``SegmentedDirectShowSource(\"d:\\filename.ext\")`` will load the files\n    d:\\filename.\\ **00**\\ .ext, d:\\filename.\\ **01**\\ .ext and so on, through\n    d:\\filename.\\ **99**\\ .ext. Any files in this sequence that don't exist or\n    do not have the same media properties as the first clip will be skipped.\n    See `Notes`_ below for information on loading clips in multiple directories.\n\n.. describe:: fps\n\n    Frames Per Second of the resulting clip. This is sometimes needed to specify\n    the framerate. If the framerate or the number of frames is incorrect (this\n    can happen with ASF or MOV clips for example), use this option to force the\n    correct framerate. For live sources, this is like \"max fps\" that will be\n    displayed.\n\n    Default: auto\n\n.. describe:: seek\n\n    There is full seeking support available on most file formats. If problems\n    occur, try setting ``seekzero=true`` first. If seeking still causes problems,\n    disable seeking completely with ``seek=false``. With seeking disabled and\n    trying to seek backwards, the audio stream returns silence, and the video\n    stream returns the most recently rendered frame. **Note** the AviSynth cache\n    *may* provide limited access to the previous few frames, but beyond that the\n    most recently frame rendered will be returned.\n\n    Default: true\n\n.. describe:: audio\n\n    Enable audio on the resulting clip. The channel ordering is the same as in\n    the `wave-format-extensible format`_, because the input is always decompressed\n    to WAV. For more information, see also :doc:`GetChannel <getchannel>`.\n    AviSynth loads 8, 16, 24 and 32 bit int PCM samples, and float PCM format,\n    and any number of channels.\n\n    Default: true\n\n.. describe:: video\n\n    Enable video on the resulting clip.\n\n    Default: true\n\n.. describe:: convertfps\n\n    If true, it turns `VFR`_ (variable framerate) video into CFR (constant framerate)\n    video by adding frames. This allows you to open VFR video in AviSynth. It is\n    most useful when fps is set to the least common multiple of the component\n    frame rates, e.g. 120 or 119.880.\n\n    Default: false\n\n.. describe:: seekzero\n\n    If true, restrict backwards seeking only to the beginning, and seeking\n    forwards is done the hard way (by reading all samples). Limited backwards\n    seeking is allowed with non-indexed `ASF`_.\n\n    Default: false\n\n.. describe:: timeout\n\n    For positive values DirectShowSource waits for up to ``timeout`` milliseconds\n    for the DirectShow graph to start. ``timeout`` is clamped between [5000,300000]\n    milliseconds. If the graph fails to start a compile time exception is thrown.\n    Once the graph starts, each GetFrame/GetAudio call will wait for up to the\n    timeout value and then return a grey frame or silence for the audio. No\n    runtime exceptions are ever thrown because of time-outs.\n\n    For negative values DirectShowSource waits for up to 2000 milliseconds for\n    the DirectShow graph to start. If the graph fails to start it is ignored at\n    that point and the initial graph start wait is deferred until the first\n    GetFrame/GetAudio call. If any GetFrame/GetAudio call experiences a timeout\n    a runtime exception is then thrown.\n\n.. describe:: pixel_type\n\n    Request a color format from the decompressor. Valid values are:\n\n    YV24, YV16, YV12, I420, NV12, YUY2, AYUV, Y41P, Y411, ARGB, RGB64, RGB48,\n    RGB32, RGB24,  YUV, YUVex, RGB, AUTO, FULL\n\n        By default, upstream DirectShow filters are free to bid all of their\n        supported media types in the order of their choice. A few DirectShow filters\n        get this wrong. The ``pixel_type`` argument limits the acceptable video\n        stream subformats for the `IPin negotiation`_. Note the graph builder may\n        add a format converter to satisfy your request, so make sure the codec in\n        use can actually decode to your chosen format. The MS format converter is\n        just adequate. The \"YUV\" and \"RGB\" pseudo-types restrict the negotiation to\n        all official supported YUV or RGB formats respectively. The \"YUVex\" also\n        includes YV24, YV16, I420 and NV12 non-standard pixel types. The \"AUTO\"\n        pseudo-type permits the negotiation to use all relevant official formats,\n        YUV plus RGB. The \"FULL\" pseudo-type includes the non-standard pixel types\n        in addition to those supported by \"AUTO\". The full order of preference is\n        YV24, YV16, YV12, I420, NV12, YUY2, AYUV, Y41P, Y411, ARGB, RGB32, RGB24,\n        RGB64, RGB48. Many DirectShow filters get this wrong, which is why it is\n        not enabled by default. The option exists so you have enough control to\n        encourage the  maximum range of filters to serve your media.\n        (See `discussion`_.)\n\n        The non-standard pixel types use the following GUID's respectively :- ::\n\n            MEDIASUBTYPE_I420 = {'024I', 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71};\n            MEDIASUBTYPE_YV24 = {'42VY', 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71};\n            MEDIASUBTYPE_YV16 = {'61VY', 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71};\n            MEDIASUBTYPE_NV12 = {'21VN', 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71};\n\n    In other words, if ``pixel_type=\"AUTO\"``, it will try to output YV24; if\n    that isn't possible it tries YV16, and if that isn't possible it tries\n    YV12, etc...\n\n    For planar color formats, adding a '+' prefix, e.g.\n    ``SegmentedDirectShowSource(..., pixel_type=\"+YV12\")``, tells AviSynth the\n    video rows are DWORD aligned in memory instead of packed. This can fix skew\n    or tearing of the decoded video when the width of the picture is not\n    divisible by 4.\n\nNotes\n-----\n\nHelpful hints\n^^^^^^^^^^^^^\n\n* | If you get an *Unrecognized Exception* while reading a VirtualDub-generated\n    segmented AVI, delete the small final .avi file.\n\n* If segments are spanned across multiple drives/folders, they can be loaded\n  provided the folders are given in the correct order. For example, if you have\n  capture files arrange across several folders like this:\n\n .. image:: pictures/segmentedavisource-img1.png\n\n To load all segments in order, call this::\n\n    SegmentedAviSource(\"F:\\t1\\cap.avi\", \"F:\\t2\\cap.avi\", \"F:\\t3\\cap.avi\")\n\n\n$Date: 2022/03/28 13:57:17 $\n\n.. _Audio Compression Manager:\n    https://en.wikipedia.org/wiki/Windows_legacy_audio_components#Audio_Compression_Manager\n.. _UTF-8:\n    https://en.wikipedia.org/wiki/UTF-8\n.. _planar:\n    http://avisynth.nl/index.php/Planar\n.. _FourCC:\n    http://avisynth.nl/index.php/FourCC\n.. _wave-format-extensible format:\n    https://web.archive.org/web/20190905063051/http://www.cs.bath.ac.uk/~jpff/NOS-DREAM/researchdev/wave-ex/wave_ex.html\n.. _VFR:\n    http://avisynth.nl/index.php/VFR\n.. _ASF:\n    https://en.wikipedia.org/wiki/Advanced_Systems_Format\n.. _IPin negotiation:\n    https://en.wikipedia.org/wiki/DirectShow#Architecture\n.. _discussion:\n    https://forum.doom9.org/showthread.php?t=143321\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/select.rst",
    "content": "\nSelectEven / SelectOdd\n======================\n\n**SelectEven** makes an output video stream using only the even-numbered\nframes from the input. **SelectOdd** is its odd counterpart.\n\nSince frames are numbered starting from zero, **SelectEven** actually selects\nthe first, third, fifth,... frames by human counting conventions.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    SelectEven (clip)\n    SelectOdd (clip)\n\n.. describe:: clip\n\n    Source clip.\n\n\n$Date: 2022/02/06 21:28:07 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/selectevery.rst",
    "content": "\nSelectEvery\n===========\n\n**SelectEvery** returns a clip with only some of the frames in every \n*step_size* selected. **SelectEvery** is a generalization of filters like \n:doc:`SelectEven <select>` and :doc:`Pulldown <pulldown>`.\n\nSyntax and Parameters\n----------------------\n\n::\n    \n    SelectEvery (clip, int step_size, int offset1 [, int offset2 [, ...]])\n\n.. describe:: clip\n\n    Source clip.\n    \n.. describe:: step_size\n\n    The number of frames in the pattern.\n    \n.. describe:: offset\n\n    The offset(s) into the step to select a frame. If omitted it defaults to 0.\n\n\nExamples\n--------\n\nReturn even numbered frames, starting with 0::\n\n    SelectEvery(clip, 2, 0) # identical to SelectEven(clip)\n    \nReturn odd numbered frames, starting with 1::\n\n    SelectEvery(clip, 2, 1) # identical to SelectOdd(clip)\n    \nSelect frames 3, 6, 7, 13, 16, 17, ... from source clip::\n\n    SelectEvery(clip, 10, 3, 6, 7)\n\nSelect frames 0, 9, 18, ... from source clip::\n    \n    SelectEvery(clip, 9, 0)\n    \nFixed pattern 1 in 5 decimation, first frame in every ``step_size`` removed::\n\n    SelectEvery(clip, 5, 1, 2, 3, 4)\n\nDuplicate every fourth frame::\n\n    SelectEvery(clip, 4, 0, 1, 2, 3, 3)\n    \nTake a 24fps progressive input clip and apply 3:2 pulldown, yielding a 30fps \ninterlaced output clip::\n\n    AssumeFrameBased()\n    SeparateFields()\n    SelectEvery(8, 0, 1, 2, 3, 2, 5, 4, 7, 6, 7) # standard NTSC-Film telecine pattern\n    Weave()\n\n$Date: 2022/02/06 21:28:07 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/selectrangeevery.rst",
    "content": "\nSelectRangeEvery\n================\n\n**SelectRangeEvery** selects *length* number of frames *every* n frames, \nstarting from frame *offset*.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    SelectRangeEvery (clip, int \"every\", int \"length\", int \"offset\", bool \"audio\")\n\n.. describe:: clip\n\n    Source clip.\n\n.. describe:: every\n\n    Frame selection interval.\n\n    Default: 1500\n\n.. describe:: length\n\n    Frame selection length; how many frames to select.\n\n    Default: 50\n\n.. describe:: offset\n\n    Frame selection offset.\n\n    Default: 0\n\n.. describe:: audio\n\n    Audio processing; set it to false to keep the original audio.\n\n    Default: true\n\n\nExamples\n--------\n\n**SelectRangeEvery** with default settings selects 50 frames every 1500 frames, \nstarting with first selection at frame 0. ::\n\n    SelectRangeEvery(clip, every=1500, length=50, offset=0)\n\nSelects the frames 0 to 13, 280 to 293, 560 to 573, etc. ::\n\n    SelectRangeEvery(clip, every=280, length=14, offset=0)\n\nSelects the frames 2 to 15, 282 to 295, 562 to 575, etc. ::\n\n    SelectRangeEvery(clip, every=280, length=14, offset=2)\n\n$Date: 2022/02/05 18:54:28 $\n\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/separatefields.rst",
    "content": "================\nSeparate Filters\n================\n\nSet of filters to separate a frame:\n\n* `SeparateFields`_ splits each frame into its component top and bottom fields.\n* `SeparateColumns`_  separates the columns of each frame into new frames.\n* `SeparateRows`_  Separates the rows of each frame into new frames.\n\n.. _SeparateFields:\n\nSeparateFields\n--------------\n\n**SeparateFields** is the opposite of :ref:`Weave`: it takes a frame-based clip\nand splits each frame into its component fields, producing a new half height\nclip with twice the frame rate and twice the frame count. This is useful if you\nwould like to use :doc:`Trim <trim>` and similar filters with single-field\naccuracy.\n\n**SeparateFields** uses the field-dominance information in the source clip to\ndecide which of each pair of fields to place first in the output. If it gets\nit wrong, use :ref:`ComplementParity`, :ref:`AssumeTFF <AssumeFieldFirst>` or\n:ref:`AssumeBFF <AssumeFieldFirst>` before **SeparateFields**.\n\n**SeparateFields** raises an exception if the clip is already field-based.\nYou may want to use :ref:`AssumeFrameBased <AssumeFrameField>`  to force\nseparate a second time.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    SeparateFields (clip)\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n.. _SeparateColumns:\n\nSeparateColumns\n---------------\n**SeparateColumns** is the opposite of :ref:`WeaveColumns`: it separates the\ncolumns of each frame into *interval* frames. The number of frames of the new\nclip is *interval* times the number of frames of the old clip.\n**SeparateColumns** is a relatively slow filter due to the sparse pixel picking\nrequired by the algorithm. In some applications it may be faster to use\n:doc:`TurnLeft/Right <turn>` with `SeparateRows`_.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    SeparateColumns (clip, int interval)\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n.. describe:: interval\n\n    | ``interval`` must be less than or equal width and greater than zero.\n    | The width of the frame must be a multiple of ``interval``, otherwise\n      an error is thrown.\n\n.. _SeparateRows:\n\nSeparateRows\n-------------\n\n**SeparateRows** is the opposite of :ref:`WeaveRows`: it separates the rows of\neach frame into *interval* frames. The number of frames of the new clip is\n*interval* times the number of frames of the old clip. **SeparateRows** like\n`SeparateFields`_ is very fast as it uses zero cost subframing to perform it's\nmagic. ``SeparateRows(2)`` is the same as ``SeparateFields()`` except the output\nis frame-based instead of field-based.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    SeparateRows (clip, int interval)\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n.. describe:: interval\n\n    | ``interval`` must be less than or equal height and greater than zero.\n    | The height of the frame must be a multiple of ``interval``, otherwise\n      an error is thrown.\n\n\nExamples\n--------\n\n::\n\n    # returns the original clip:\n    AviSource(\"c:\\file.avi\")\n    SeparateColumns(1)\n\n    # returns a clip where the columns are separated:\n    # frame 0 consists of the columns 0,3,6,... of the original frame 0\n    # frame 1 consists of the columns 1,4,7,... of the original frame 0\n    # frame 2 consists of the columns 2,5,8,... of the original frame 0\n    # frame 3 consists of the columns 0,3,6,... of the original frame 1\n    # etc ...\n    AviSource(\"c:\\file.avi\")\n    SeparateColumns(3)\n\n    # returns a clip where the rows are separated:\n    # frame 0 consists of the rows 0,2,4,... of the original frame 0\n    # frame 1 consists of the rows 1,3,5,... of the original frame 0\n    # frame 2 consists of the rows 0,2,4,... of the original frame 1\n    # frame 3 consists of the rows 1,3,5,... of the original frame 1\n    # etc ...\n    AviSource(\"c:\\file.avi\")\n    SeparateRows(2)\n\n\nChangelog\n---------\n\n+-----------------+---------------------------------------------------+\n| Version         | Changes                                           |\n+=================+===================================================+\n| AviSynth+ r2487 | Separate filters: added support for 10-16bit,     |\n|                 | float, Planar RGB(A)/YUV(A) and RGB48/64 formats. |\n+-----------------+---------------------------------------------------+\n| AviSynth 2.6.0  | Added SeparateColumns and SeparateRows.           |\n+-----------------+---------------------------------------------------+\n\n$Date: 2022/02/27 14:59:41 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/setchannelmask.rst",
    "content": "\nThis page describes SetChannelMask, GetChannelMask and IsChannelMaskKnown\n\nGetChannelMask\n==============\n\nReturns the actual channel layout mask. If layout mask is not set, returns 0.\n\n::\n\n    int GetChannelMask (clip)\n\n.. describe:: clip\n\n    Source clip.\n\n\nIsChannelMaskKnown\n==================\n\nReturns true, if the channel layout mask is set, false otherwise.\n\n::\n\n    bool IsChannelMaskKnown (clip)\n\n.. describe:: clip\n\n    Source clip.\n\n\nSetChannelMask (int version)\n============================\n\nSets the actual channel layout mask.\n\n\n::\n\n    SetChannelMask (clip , bool IsChannelMaskKnown, int dwChannelMask)\n\n.. describe:: clip\n\n    Source clip of which these properties must be set.\n\n.. describe:: IsChannelMaskKnown\n\n    - true: Channel mask is valid. dwChannelMask parameter will be set.\n    - false: makes channel mask info invalid. Also sets the mask to 0 internally.\n\n    Default: false\n\n.. describe:: dwChannelMask\n\n    Channel mask is an integer number, which describes the speaker (audio layout) \n    configuration of the clip. The number of '1' bits in mask must match with the number\n    of audio channels.\n    The lowest 18 bit is used, as defined in WAVE_FORMAT_EXTENSIBLE dwChannelMask definitions \n    (https://learn.microsoft.com/en-us/windows/win32/api/mmreg/ns-mmreg-waveformatextensible)\n    As a special case $80000000 value (32 bit msb bit is 1) implies \"speaker all\" setting.\n    (for developers: these bits are specified in avisynth.h as well)\n\n    Default: 0\n\n::\n\n     enum AvsChannelMask {\n           MASK_SPEAKER_FRONT_LEFT = 0x1,\n           MASK_SPEAKER_FRONT_RIGHT = 0x2,\n           MASK_SPEAKER_FRONT_CENTER = 0x4,\n           MASK_SPEAKER_LOW_FREQUENCY = 0x8,\n           MASK_SPEAKER_BACK_LEFT = 0x10,\n           MASK_SPEAKER_BACK_RIGHT = 0x20,\n           MASK_SPEAKER_FRONT_LEFT_OF_CENTER = 0x40,\n           MASK_SPEAKER_FRONT_RIGHT_OF_CENTER = 0x80,\n           MASK_SPEAKER_BACK_CENTER = 0x100,\n           MASK_SPEAKER_SIDE_LEFT = 0x200,\n           MASK_SPEAKER_SIDE_RIGHT = 0x400,\n           MASK_SPEAKER_TOP_CENTER = 0x800,\n           MASK_SPEAKER_TOP_FRONT_LEFT = 0x1000,\n           MASK_SPEAKER_TOP_FRONT_CENTER = 0x2000,\n           MASK_SPEAKER_TOP_FRONT_RIGHT = 0x4000,\n           MASK_SPEAKER_TOP_BACK_LEFT = 0x8000,\n           MASK_SPEAKER_TOP_BACK_CENTER = 0x10000,\n           MASK_SPEAKER_TOP_BACK_RIGHT = 0x20000,\n           MASK_SPEAKER_ALL = 0x80000000\n     }\n     \n\n\nSetChannelMask (string version)\n===============================\n\n::\n\n    SetChannelMask (clip , string ChannelMask)\n\n.. describe:: clip\n\n    Source clip of which this property must be set.\n\n.. describe:: ChannelMask\n\n    Channel mask is a string, which can contain one or more \n\n    - predefined, frequently used layout name,\n    - speaker position name\n    - a number followed by 'c' meaning a default layout for a given channel count\n    - or a direct decimal mask value \n\n    They can be set alone or combined with the plus sign (+).\n\n    String is case sensitive!\n\n    If ChannelMask is \"\" (empty) then the layout will be marked as 'not set': same \n    as SetChannelMask(clip, false, 0)\n\n    Default: \"\"\n\n\nExamples\n--------\n\nThese are the same:\n\n::\n\n    SetChannelMask(\"mono\")\n    SetChannelMask(\"FC\")\n\nThese are the same:\n\n::\n\n    SetChannelMask(\"stereo\")\n    SetChannelMask(\"FL+FR\")\n\nThese are the same:\n\n::\n\n    SetChannelMask(\"stereo+LFE\")\n    SetChannelMask(\"2.1\")\n\nSets the default choice for 2 channels (which is \"stereo\"):\n\n::\n\n    SetChannelMask(\"2c\")\n\nSets the default choice for 6 channels (which is \"5.1\"):\n\n::\n\n    SetChannelMask(\"6c\")\n\nSets the exact mask or 3=1+2, that is \"FL+FR\" = \"stereo\":\n\n::\n\n    SetChannelMask(\"3\")\n\nSet layout info as invalid:\n\n::\n\n    SetChannelMask(false, 0)\n    SetChannelMask(\"\")\n\nSet layout info to exact number, then the same with the string variant:\n\n::\n\n    SetChannelMask(true, 1+2+8)\n    SetChannelMask(\"FL+FR+LFE\")\n\n\n\nIndividual Speaker Channels\n---------------------------\n\n    | \"FL\"  front left\n    | \"FR\"  front right\n    | \"FC\"  front center\n    | \"LFE\" low frequency\n    | \"BL\"  back left\n    | \"BR\"  back right\n    | \"FLC\" front left-of-center\n    | \"FRC\" front right-of-center\n    | \"BC\"  back center\n    | \"SL\"  side left\n    | \"SR\"  side right\n    | \"TC\"  top center\n    | \"TFL\" top front left\n    | \"TFC\" top front center\n    | \"TFR\" top front right\n    | \"TBL\" top back left\n    | \"TBC\" top back center\n    | \"TBR\" top back right\n\n\nPredefined frequently used channel layouts\n------------------------------------------\n\n    | \"mono\"\n    | \"stereo\"\n    | \"2.1\"\n    | \"3.0\"\n    | \"3.0(back)\"\n    | \"4.0\"\n    | \"quad\"\n    | \"quad(side)\"\n    | \"3.1\"\n    | \"5.0\"\n    | \"5.0(side)\"\n    | \"4.1\"\n    | \"5.1\"\n    | \"5.1(side)\"\n    | \"6.0\"\n    | \"6.0(front)\"\n    | \"hexagonal\"\n    | \"6.1\"\n    | \"6.1(back)\"\n    | \"6.1(front)\"\n    | \"7.0\"\n    | \"7.0(front)\"\n    | \"7.1\"\n    | \"7.1(wide)\"\n    | \"7.1(wide-side)\"\n    | \"7.1(top)\"\n    | \"octagonal\"\n    | \"cube\"\n    | \"speaker_all\"\n\n\n$Date: 2023/03/21 15:41:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/setfilterprop.rst",
    "content": "\nSetFilterProp / GetFilterProps\n==============================\n\nAutomatically inject frame properties on the output of a named filter every\ntime it is instantiated by the script engine.  The rule is registered once\n(typically in an auto-loaded ``.avsi`` file) and is applied transparently,\nwithout touching the script that uses the filter.\n\nThere are two forms:\n\n- **Simple form** — injects a fixed property value (or a value captured from\n  the filter's own call argument) on every instantiation.\n- **Conditional form** — injects a property value only when a specific named\n  call argument equals a given match value.\n\n\nSyntax and Parameters\n---------------------\n\n*Simple form*\n\n::\n\n    SetFilterProp (string filter, string key, int       value [, int \"mode\"])\n    SetFilterProp (string filter, string key, float     value [, int \"mode\"])\n    SetFilterProp (string filter, string key, string    value [, int \"mode\"])\n    SetFilterProp (string filter, string key, bool      value [, int \"mode\"])\n    SetFilterProp (string filter, string key, func      value [, int \"mode\"])\n    SetFilterProp (string filter, string key, undefined()     [, int \"mode\"])\n\n*Conditional form*\n\n::\n\n    SetFilterProp (string filter, string param_name, any param_match,\n                   string key, any value [, int \"mode\"])\n\n    GetFilterProps ()\n\n----\n\n.. describe:: filter\n\n    Name of the filter whose output should receive the property.  The\n    comparison is case-insensitive and follows the same normalisation rules\n    used by ``SetFilterMTMode``.\n\n    When ``SetFilterProp`` is called from inside a plugin's initialisation\n    function (``AvisynthPluginInit3``), the plugin's base name is\n    automatically prepended (``pluginname_filtername``), exactly as\n    ``SetFilterMTMode`` does.\n\n.. describe:: key\n\n    Frame-property key name.  Must start with a letter (``a``–``z``,\n    ``A``–``Z``) or underscore, followed only by letters, digits or\n    underscores — the same constraints enforced by ``propSet`` and the\n    VapourSynth-compatible property API.  Key names are **case-sensitive**.\n\n.. describe:: value  (simple form)\n\n    The value to stamp on every frame produced by *filter*.  Accepted types:\n\n    - **int** — stored as a 64-bit integer property.\n    - **float** — stored as a double-precision float property.\n    - **string** — stored as a UTF-8 string property.\n    - **bool** — stored as a 64-bit integer property (``true`` → ``1``,\n      ``false`` → ``0``).  Frame properties have no dedicated bool type.\n    - **func** — a function object (lambda or named function) evaluated\n      **per frame** with the filter's output clip as its implicit first\n      argument.  The function must return an ``int``, ``float``, or\n      ``string``.  This allows the injected value to depend on per-clip\n      attributes such as resolution or colour format::\n\n          SetFilterProp(\"Spline36Resize\", \"_Matrix\",\n              function[](clip c) { c.Width() >= 1280 ? 1 : 6 })\n\n    - **undefined()** — *capture mode*: instead of a fixed value, the actual\n      value of the filter's named call argument whose name equals *key* is\n      captured at instantiation time and injected as the property.  The\n      property key and the parameter name must therefore be identical.  If\n      the filter is not called with that named argument, no property is\n      injected for that invocation::\n\n          # Capture the \"radius\" argument of Blur() and store it as a\n          # frame property also named \"radius\".\n          SetFilterProp(\"Blur\", \"radius\", undefined())\n\n      .. note::\n          Capture mode works for both positional and named call sites.\n          ``Blur(1.5)`` and ``Blur(radius=1.5)`` are treated identically.\n\n.. describe:: param_name  (conditional form)\n\n    The name of the filter's call argument to inspect.  Case-insensitive.\n\n.. describe:: param_match  (conditional form)\n\n    The value — or **array of aliases** — that *param_name* must equal for\n    the injection to take place.\n\n    - **Scalar** (int, float, bool, or string): the condition is true when the\n      actual argument value equals *param_match* exactly.\n    - **Array of scalars**: the condition is true when the actual argument\n      value equals *any* element of the array (int, float, bool, or string).\n      This is the idiomatic way to handle the many equivalent string\n      representations that colour-science parameters tend to accept::\n\n          # \"709\", \"1\", and \"AVS_MATRIX_BT709\" all map to _Matrix = 1\n          SetFilterProp(\"Convert\", \"matrix\",\n              [\"709\", \"1\", \"AVS_MATRIX_BT709\"], \"_Matrix\", 1)\n\n    Comparisons:\n\n    - string vs string — case-insensitive (``_stricmp``), consistent with\n      how AviSynth itself matches named parameters.\n    - int vs int, bool vs bool, int vs bool — integer equality; ``true``\n      and ``1`` are considered equal, ``false`` and ``0`` are equal.\n    - float vs float — exact bitwise equality.\n\n    A type mismatch between the actual argument value and a candidate never\n    raises an error; the condition simply evaluates to false.\n\n    If the filter is not called with *param_name* as a named argument, the\n    condition cannot be evaluated and the injection is skipped silently.\n\n.. describe:: value  (conditional form)\n\n    The property value to inject when the condition is met.  Accepted types:\n    **int**, **float**, **bool**, **string**, **func**.  ``bool`` is stored as\n    integer (``true`` → ``1``, ``false`` → ``0``).  ``undefined()`` is not\n    accepted here; the value must be known at registration time.\n\n.. describe:: mode\n\n    Controls how the property is written when the frame already carries a\n    value for *key*.  Uses the same constants as ``propSet``:\n\n    - ``0`` — **replace** (default): overwrite any existing value.\n    - ``1`` — **append**: add to an array alongside the existing value.\n    - ``2`` — **touch**: do nothing if the key already exists.\n\n    The default ``replace`` mode includes an optimisation inherited from\n    ``SetProperty``: if the existing value is already identical to the new\n    value (int, float, or string comparison), the frame is returned\n    unmodified without making the property map writable.\n\n    Default: 0 (replace)\n\n.. describe:: GetFilterProps\n\n    Returns all registered rules as a JSON string (array of objects), useful\n    for inspection and debugging.\n\n    Simple rules::\n\n        [\n          {\"filter\":\"spline36resize\",\"key\":\"_Matrix\",\"type\":\"int\",\"value\":1,\"mode\":0},\n          {\"filter\":\"blur\",\"key\":\"radius\",\"type\":\"capture\",\"value\":null,\"mode\":0}\n        ]\n\n    Conditional rules gain two additional fields, ``when_param`` and\n    ``when_value``.  When an alias array was registered, ``when_value`` is a\n    JSON array::\n\n        [\n          {\"filter\":\"colormatrix\",\"key\":\"_Matrix\",\n           \"when_param\":\"mode\",\n           \"when_value\":[\"Rec.601->Rec.709\",\"FCC->Rec.709\",\"SMPTE 240M->Rec.709\",\"Rec.2020->Rec.709\"],\n           \"type\":\"int\",\"value\":1,\"mode\":0},\n          {\"filter\":\"convert\",\"key\":\"_Matrix\",\n           \"when_param\":\"matrix\",\"when_value\":[\"709\",\"1\",\"AVS_MATRIX_BT709\"],\n           \"type\":\"int\",\"value\":1,\"mode\":0}\n        ]\n\n    Type values in the JSON output:\n\n    ============  ===========================================\n    ``\"int\"``     Static integer value (includes bool, stored as 0/1).\n    ``\"float\"``   Static float value.\n    ``\"string\"``  Static string value.\n    ``\"function\"``  Per-frame function object (value is null).\n    ``\"capture\"`` Capture-from-param rule (value is null).\n    ``\"unknown\"`` Unexpected type (should not occur).\n    ============  ===========================================\n\n    Function-valued rules are serialised with ``\"type\":\"function\",\"value\":null``.\n\n    Bool values in ``when_value`` (conditional *param_match*) are serialised as\n    JSON booleans (``true`` / ``false``).\n\n\nPlacement in the filter graph\n------------------------------\n\nThe ``SetProperty`` wrapper is inserted **after** both ``MTGuard`` and\n``CacheGuard``, and **outside** the \"unaltered clip\" bypass.  This means:\n\n- The property is stamped even when the filter returns one of its input clips\n  unchanged (a common optimisation in no-op conditions).\n- The property wrapper is not duplicated on filters that are constructed\n  internally as part of another filter's constructor (chained construction).\n- The cache sees the property-stamped output, so cached frames already carry\n  the correct properties.\n\nFor the conditional and capture forms, argument matching happens **before**\n``InstantiateFilter`` is called, using the fully-resolved argument array\n(``args3``) built from the ``Invoke`` call.  This means:\n\n- Both positional and named call sites are matched: ``ColorMatrix(\"Rec.601->Rec.709\")``\n  and ``ColorMatrix(mode=\"Rec.601->Rec.709\")`` are treated identically.\n- The matched value reflects exactly what the script passed, not any default\n  substitution the filter may apply internally.\n\nExample\n-------\n::\n\n    ColorbarsHD().ConvertToYV12() # ColorMatrix only accepts YV12\n    SetFilterProp(\"ColorMatrix\", \"mode\", [\"Rec.601->Rec.709\"], \"_Matrix\", 1) # 1 = BT.709\n    SetFilterProp(\"ColorMatrix\", \"mode\", \"Rec.709->Rec.601\", \"_Matrix\", 6)   # 6 = 170M\n    Colormatrix(\"Rec.601->Rec.709\")\n    propShow(align=1) # see _Matrix = 1 in bottom left corner\n    Colormatrix(mode=\"Rec.709->Rec.601\")\n    propShow(align=3) # see _Matrix = 6 in bottom right corner\n\n\n\n\nTypical usage via auto-loaded script\n-------------------------------------\n\nCreate a file ``my_props.avsi`` in the AviSynth+ auto-load folder and add\nrules there.  Because ``.avsi`` files are executed before the main script,\nthe rules are in place for every subsequent filter instantiation::\n\n    # my_props.avsi  (place in the autoload directory)\n\n    # Tag all Spline36Resize output as BT.709, limited range\n    SetFilterProp(\"Spline36Resize\", \"_Matrix\",     1)   # 1 = BT.709\n    SetFilterProp(\"Spline36Resize\", \"_ColorRange\", 1)   # 1 = limited\n\n    # Derive _Matrix from output resolution (HD → 709, SD → 601)\n    SetFilterProp(\"ConvertToYUV420\", \"_Matrix\",\n        function[](clip c) { c.Width() >= 1280 ? 1 : 6 })\n\n    # Do not overwrite _FieldBased if the filter already set it\n    SetFilterProp(\"Bob\", \"_FieldBased\", 0, mode=2)\n\n    # Tag ColorMatrix output with the _Matrix of the destination colorspace.\n    # ColorMatrix uses mode=\"source->dest\"; group all modes by their destination.\n    # String matching is case-insensitive, so \"rec.709->rec.601\" matches too.\n    SetFilterProp(\"ColorMatrix\", \"mode\",\n        [\"Rec.601->Rec.709\", \"FCC->Rec.709\", \"SMPTE 240M->Rec.709\", \"Rec.2020->Rec.709\"],\n        \"_Matrix\", 1)   # 1 = BT.709\n    SetFilterProp(\"ColorMatrix\", \"mode\",\n        [\"Rec.709->Rec.601\", \"FCC->Rec.601\", \"SMPTE 240M->Rec.601\", \"Rec.2020->Rec.601\"],\n        \"_Matrix\", 6)   # 6 = Rec.601 / SMPTE 170M\n    SetFilterProp(\"ColorMatrix\", \"mode\",\n        [\"Rec.709->FCC\", \"Rec.601->FCC\", \"SMPTE 240M->FCC\", \"Rec.2020->FCC\"],\n        \"_Matrix\", 4)   # 4 = FCC\n    SetFilterProp(\"ColorMatrix\", \"mode\",\n        [\"Rec.709->SMPTE 240M\", \"Rec.601->SMPTE 240M\", \"FCC->SMPTE 240M\", \"Rec.2020->SMPTE 240M\"],\n        \"_Matrix\", 7)   # 7 = SMPTE 240M\n    SetFilterProp(\"ColorMatrix\", \"mode\",\n        [\"Rec.709->Rec.2020\", \"Rec.601->Rec.2020\", \"FCC->Rec.2020\", \"SMPTE 240M->Rec.2020\"],\n        \"_Matrix\", 9)   # 9 = BT.2020 NCL\n    # Integer dest= parameter form (when mode= is not used):\n    SetFilterProp(\"ColorMatrix\", \"dest\", 0, \"_Matrix\", 1)   # 0 = Rec.709\n    SetFilterProp(\"ColorMatrix\", \"dest\", 2, \"_Matrix\", 6)   # 2 = Rec.601\n    SetFilterProp(\"ColorMatrix\", \"dest\", 1, \"_Matrix\", 4)   # 1 = FCC\n    SetFilterProp(\"ColorMatrix\", \"dest\", 3, \"_Matrix\", 7)   # 3 = SMPTE 240M\n    SetFilterProp(\"ColorMatrix\", \"dest\", 4, \"_Matrix\", 9)   # 4 = Rec.2020\n\n    # Capture Blur's radius argument as a frame property of the same name\n    SetFilterProp(\"Blur\", \"radius\", undefined())\n\nMultiple calls for the same filter and key are allowed; they are applied in\nregistration order (the last ``replace``-mode entry that matches wins).\n\n\nNotes\n-----\n\n- Rules registered with ``SetFilterProp`` survive the autoload phase and\n  remain active for the entire script session.\n- The rule table is global to the script environment; it cannot be modified\n  after a ``SetFilterProp`` call has been made from within a plugin init.\n- Conditional rules use exact-equality matching.  For range checks or other\n  complex logic, use the ``func`` value type in the simple form instead.\n- The alias-array form ``[\"a\", \"b\", \"c\"]`` for *param_match* is the\n  recommended way to handle colour-science parameters that accept many\n  equivalent string representations for the same concept.  A single\n  ``.avsi`` file with one ``SetFilterProp`` call per canonical value covers\n  what would otherwise require a separate call per alias string.\n- Multiple conditional rules for the same filter and property are evaluated\n  in registration order; only the first matching rule that writes (mode 0 or\n  1) takes effect on a given frame if an earlier rule already set the key.\n  Use ``mode=2`` (touch) on later rules if the first match should win.\n- ``GetFilterProps`` is intended for diagnostics; parsing its output to\n  reconstruct a rule table is not supported — write rules directly in\n  ``.avsi`` instead.\n\n\nExamples\n--------\n\n**Simple static injection**\n\nThe following script demonstrates mode ``0`` (replace): the property is\nalways overwritten, regardless of any value the filter may have already set.\nAfter ``Spline36Resize(640, 480)`` the output clip is 640×480, so the\nfunction evaluates ``Width() >= 1280`` as false and stamps ``_Matrix = 6``\n(BT.601).  The string-valued ``Width`` property and integer-valued\n``HeightInt`` property illustrate that function rules can return any\nsupported type.  ``SubTitle`` shows the rule table; ``propShow`` shows the\nproperties actually present on the decoded frame.\n\n::\n\n    ColorbarsHD()\n\n    # mode=0 (default) always overwrites the property\n    SetFilterProp(\"Spline36Resize\", \"_Matrix\",\n        function[](clip c) { c.Width() >= 1280 ? 1 : 6 }, 0)\n\n    # Function returning a string (String() converts int to string)\n    SetFilterProp(\"Spline36Resize\", \"Width\",\n        function[](clip c) { String(c.Width()) })\n\n    # Function returning an int directly\n    SetFilterProp(\"Spline36Resize\", \"HeightInt\",\n        function[](clip c) { c.Height() })\n\n    Spline36Resize(640, 480)  # output is SD → _Matrix will be 6\n\n    SubTitle(GetFilterProps())  # display the registered rule table\n    propShow(align=1)           # display frame properties on the frame\n\n**Conditional injection — ColorMatrix**\n\n``ColorMatrix`` (the third-party filter) converts between colour matrices\nusing a ``mode=\"source->dest\"`` string parameter and, alternatively, integer\n``source`` / ``dest`` parameters.  The alias-array form lets all modes that\nshare a destination be grouped into one rule, covering the complete matrix\nin five calls::\n\n    # my_props.avsi\n    # String mode= form — group by destination, one rule per output matrix.\n    # String matching is case-insensitive, so any capitalisation variant works.\n    SetFilterProp(\"ColorMatrix\", \"mode\",\n        [\"Rec.601->Rec.709\", \"FCC->Rec.709\",\n         \"SMPTE 240M->Rec.709\", \"Rec.2020->Rec.709\"],   \"_Matrix\", 1)\n    SetFilterProp(\"ColorMatrix\", \"mode\",\n        [\"Rec.709->Rec.601\", \"FCC->Rec.601\",\n         \"SMPTE 240M->Rec.601\", \"Rec.2020->Rec.601\"],   \"_Matrix\", 6)\n    SetFilterProp(\"ColorMatrix\", \"mode\",\n        [\"Rec.709->FCC\", \"Rec.601->FCC\",\n         \"SMPTE 240M->FCC\", \"Rec.2020->FCC\"],           \"_Matrix\", 4)\n    SetFilterProp(\"ColorMatrix\", \"mode\",\n        [\"Rec.709->SMPTE 240M\", \"Rec.601->SMPTE 240M\",\n         \"FCC->SMPTE 240M\", \"Rec.2020->SMPTE 240M\"],    \"_Matrix\", 7)\n    SetFilterProp(\"ColorMatrix\", \"mode\",\n        [\"Rec.709->Rec.2020\", \"Rec.601->Rec.2020\",\n         \"FCC->Rec.2020\", \"SMPTE 240M->Rec.2020\"],      \"_Matrix\", 9)\n\n    # Integer dest= form — for scripts that use source/dest integers instead.\n    SetFilterProp(\"ColorMatrix\", \"dest\", 0, \"_Matrix\", 1)   # 0 = Rec.709\n    SetFilterProp(\"ColorMatrix\", \"dest\", 2, \"_Matrix\", 6)   # 2 = Rec.601\n    SetFilterProp(\"ColorMatrix\", \"dest\", 1, \"_Matrix\", 4)   # 1 = FCC\n    SetFilterProp(\"ColorMatrix\", \"dest\", 3, \"_Matrix\", 7)   # 3 = SMPTE 240M\n    SetFilterProp(\"ColorMatrix\", \"dest\", 4, \"_Matrix\", 9)   # 4 = Rec.2020\n\n    # Main script — no changes needed:\n    ColorMatrix(mode=\"Rec.601->Rec.709\")  # → _Matrix = 1 (BT.709)\n    ColorMatrix(mode=\"Rec.709->Rec.2020\") # → _Matrix = 9 (BT.2020 NCL)\n    ColorMatrix(dest=2)                   # → _Matrix = 6 (Rec.601)\n\n**Capture mode — propagating a call argument as a property**\n\n::\n\n    # Register once in an .avsi file:\n    SetFilterProp(\"Blur\", \"radius\", undefined())\n\n    # Main script:\n    Blur(radius=1.5)   # → frame property \"radius\" = 1.5\n    Blur(radius=3.0)   # → frame property \"radius\" = 3.0\n    Blur(0.5)          # positional: property \"radius\" = 0.5 (same as named)\n\n\n----\n\n\nSetFilterPropPassthrough\n========================\n\nCompatibility shim for old filters that predate frame-property support.  These\nfilters create output frames with ``NewVideoFrame`` (not ``NewVideoFrameP``),\nsilently discarding every frame property that arrived on the input clip.\n``SetFilterPropPassthrough`` inserts a transparent wrapper that forwards all\ninput frame properties to the filter's output.\n\n\nSyntax and Parameters\n---------------------\n\n::\n\n    SetFilterPropPassthrough (string filter)\n\n----\n\n.. describe:: filter\n\n    Name of the filter to wrap.  Case-insensitive, follows the same\n    normalisation rules as ``SetFilterProp`` and ``SetFilterMTMode``.\n\n    The first clip-typed argument of the filter is used as the property source.\n    If the filter does not take a clip as its first argument the call has no\n    effect.\n\n\nBehaviour\n---------\n\nThe wrapper is evaluated per frame at ``GetFrame`` time:\n\n1. The filter's output frame is obtained.\n2. If the output frame already carries **any** frame properties (i.e. the\n   plugin was updated to use ``NewVideoFrameP`` in the meantime), the wrapper\n   is a no-op and returns the frame unmodified.  This makes the shim\n   **self-healing**: when the plugin author ships a fixed build, the wrapper\n   retires itself automatically without any ``.avsi`` changes.\n3. Otherwise all properties from the first input clip's corresponding frame are\n   copied to the output frame (via ``env->copyFrameProps``).\n\nIf ``SetFilterProp`` rules are also registered for the same filter they are\napplied **after** the passthrough copy, so specific injections override the\ninherited values (subject to the ``mode`` parameter of each rule).\n\n\nTypical usage\n-------------\n\nPlace in an auto-loaded ``.avsi`` file alongside any ``SetFilterProp`` rules\nfor the same filter::\n\n    # my_compat.avsi\n\n    # ColorMatrix (third-party) predates frame properties; forward them.\n    SetFilterPropPassthrough(\"ColorMatrix\")\n\n    # On top of the forwarded properties, stamp the correct output matrix.\n    SetFilterProp(\"ColorMatrix\", \"mode\",\n        [\"Rec.601->Rec.709\", \"FCC->Rec.709\",\n         \"SMPTE 240M->Rec.709\", \"Rec.2020->Rec.709\"],   \"_Matrix\", 1)\n    SetFilterProp(\"ColorMatrix\", \"mode\",\n        [\"Rec.709->Rec.601\", \"FCC->Rec.601\",\n         \"SMPTE 240M->Rec.601\", \"Rec.2020->Rec.601\"],   \"_Matrix\", 6)\n    # ... remaining rules ...\n\n    # Main script — no changes needed:\n    ColorbarsHD().ConvertToYV12()\n    ColorMatrix(mode=\"Rec.601->Rec.709\")\n    # Output frame carries all properties from ConvertToYV12's output,\n    # with _Matrix overridden to 1 (BT.709) by the SetFilterProp rule.\n\nNotes\n-----\n\n- Call ``SetFilterPropPassthrough`` **once** per filter name; registering the\n  same name twice is harmless but redundant.\n- Only the **first** clip argument is used as the property source.  Multi-clip\n  filters (dissolves, masked merges, …) are not typical targets for this shim;\n  those filters usually postdate frame properties and propagate them natively.\n- ``SetFilterPropPassthrough`` is a no-op for filters that are not called with\n  a clip as their first argument (source filters, generators).\n- Remove the call from your ``.avsi`` when the plugin is updated to propagate\n  properties natively.  The self-healing ``propNumKeys > 0`` check means\n  leaving it in is safe but wastes a small amount of work per frame.\n\n\nChangelog\n---------\n\n.. list-table::\n   :widths: auto\n\n   * - v3.7.6\n     - Added ``SetFilterProp`` (simple form: static int/float/string/function value),\n       ``GetFilterProps`` (JSON diagnostic dump), and ``SetFilterPropPassthrough``\n       (input-property forwarding shim for legacy filters).\n   * - v3.7.6\n     - Added ``SetFilterProp`` conditional form: inject a property only when a named\n       call argument equals a given value or any element of an alias array.\n       String comparison is case-insensitive.\n   * - v3.7.6\n     - Added ``SetFilterProp`` capture mode (``undefined()`` value): capture the\n       actual call-time argument value and stamp it as a frame property.\n       Works for both positional and named call sites.\n\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/showalpha.rst",
    "content": "\nShowAlpha, ShowRed, ShowGreen, ShowBlue, ShowY, ShowU, ShowV\n============================================================\n\nReturns the selected channel as a greyscale clip.\n\n::\n\n    ShowAlpha (clip, string pixel_type)\n    ShowBlue (clip, string pixel_type)\n    ShowGreen (clip, string pixel_type)\n    ShowRed (clip, string pixel_type)\n    ShowY (clip, string pixel_type)\n    ShowU (clip, string pixel_type)\n    ShowV (clip, string pixel_type)\n\n``ShowAlpha`` Returns the alpha channel of a RGB32/RGB64/RGBAP/YUVA clip in greyscale.\n\n``ShowBlue``, ``ShowGreen``, ``ShowRed`` returns the selected channel of a RGB clip\n\n``ShowY``, ``ShowU``, ``ShowV`` returns the selected channel of a YUV clip\n\n``pixel_type`` Sets the color format of the output.\n\nDefault pixel_type is adaptive.\n\nIf pixel_type is empty and source is RGB, or pixel_type=\"rgb\", then output type is\n\n- RGB32 or RGB64 when source if packed RGB(A) (match the bit depth)\n- RGBP with the matching bit depth if source is planar RGB(A)\n\nIf pixel_type is empty and source is YUV, or pixel_type=\"yuv\", then output type is\n\n- YUV444 (match the bit depth)\n\nIf pixel_type is \"y\" or \"rgbp\" or \"rgbap\" then output type is\n\n- Y, RGBP or RGBAP respectively with the matching bit depth.\n\nAt all other cases, the pixel_type should be explicitely given.\n\nConversion rules:\n\nFor RGB output the selected channel is copied to all R, G and B channels, \nbut not the Alpha channel which is left untouched (if target format has alpha).\n\nFor Y or YUV output the selected channel is copied to the Luma channel.\nFor YUV output the chroma (U and Y) channels are set to grey (0x80 when 8 bits).\n\nIf output is set to a Y/YUV format, they are are full range (8 bits: 0-255), and so \ncan be used as the mask argument to Overlay. \n\n**Examples:**\n::\n\n    # shows alpha channels of clip\n    AviSource(\"clip.avi\")\n    ShowAlpha()\n\n    # swaps red and blue channels:\n    AviSource(\"clip.avi\")\n    MergeRGB(ShowBlue(\"YV12\"), Last, ShowRed(\"YV12\"))\n\nSee also :doc:`plane Extract functions <extract>` (AviSynth+)\n\n+-----------+---------------------------------------+\n| Changelog |                                       |\n+===========+=======================================+\n| v3.7.4    | Fix swapped ShowGreen/ShowBlue for    |\n|           | planar RGB input                      |\n+-----------+---------------------------------------+\n| AviSynth+ | | added ShowY, ShowU, ShowV           |\n|           | | allow any planar/packed RGB(A)      |\n|           | | allow YUV input                     |\n|           | | allow any valid pixel_type          |\n+-----------+---------------------------------------+\n| v2.6      | pixel_type \"Y8\"                       |\n+-----------+---------------------------------------+\n| v2.56     | added ShowBlue, ShowGreen and ShowRed |\n+-----------+---------------------------------------+\n| v2.53     | added ShowAlpha                       |\n+-----------+---------------------------------------+\n\n$Date: 2005/07/08 22:53:16 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/showfive.rst",
    "content": "================\nShowFiveVersions\n================\n\n**ShowFiveVersions** takes five video streams and combines them in a\nstaggered arrangement from left to right.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    ShowFiveVersions (clip1, clip2, clip3, clip4, clip5)\n\n.. describe:: clip\n\n    Source clips; all 5 required and all must have the same color format, etc.\n\n\nExamples\n---------\n\nThe only use for this (that I can think of) is to help find the NTSC pulldown\npattern. You can do this using code like this:\n\n::\n\n    # View all five pulldown patterns at once\n    DoubleWeave()\n    # put a resizing filter here if necessary (see below)\n    a = Pulldown(0,2).Subtitle(\"0,2\")\n    b = Pulldown(1,3).Subtitle(\"1,3\")\n    c = Pulldown(2,4).Subtitle(\"2,4\")\n    d = Pulldown(0,3).Subtitle(\"0,3\")\n    e = Pulldown(1,4).Subtitle(\"1,4\")\n    ShowFiveVersions(a,b,c,d,e)\n\n\nThis code displays the five pulldown patterns with some text identifying\nwhich is which. You can then look through the movie and pick the pattern which\navoids blending frames. (In ordinary pulldown, there will actually be two\nwhich work equally well. Look at the diagrams in the :doc:`Pulldown <pulldown>`\nfilter section to see why). If none of the five work properly, then you're\ndealing with one of the more perverse forms of pulldown and you might want to\nuse :doc:`PeculiarBlend <peculiar>`.\n\nIf you're planning to capture at a high resolution and then scale down after,\nyou should place the :doc:`ReduceBy2 <reduceby2>` or :doc:`BilinearResize <resize>`\nor whatever just after the :doc:`DoubleWeave <doubleweave>` statement in the\ncode above. Before :doc:`DoubleWeave <doubleweave>` it won't work correctly,\nand if you postpone it any further, **ShowFiveVersions** will produce a *really*\nbig frame.\n\n\nChangelog\n---------\n\n+----------------+----------------------------------+\n| Version        | Changes                          |\n+================+==================================+\n| AviSynth 2.6.0 | Added Y8, YV16, and YV24 support |\n+----------------+----------------------------------+\n| AviSynth 2.5.6 | Added YV12 support               |\n+----------------+----------------------------------+\n\n$Date: 2022/03/17 22:08:36 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/showframes.rst",
    "content": "==========\nShowFrames\n==========\n\nSet of filters to overlay frame numbers and timecodes onto a video clip:\n\n* `ShowFrameNumber`_ displays the frame number on each frame.\n* `ShowSMPTE`_ displays SMPTE timecodes.\n* `ShowTime`_ displays time for the current frame.\n\nSee the `Examples`_ section for visuals.\n\n.. _ShowFrameNumber:\n\nShowFrameNumber\n---------------\nDraws text on every frame indicating what frame number AviSynth sees at that\npoint in the script. This is sometimes useful when writing scripts. If you\napply additional filters to the clip, they will treat the text on the frame\njust as they would treat an image, so the numbers may be distorted by the\ntime you see them. Sometimes this is what you want, as it shows frame blending etc.\n\nThe frame numbers will be drawn on the left side of the clip for *frame-based,\ntop field first* material; on the right side for *frame-based, bottom field first*\nmaterial and alternating on the left side and right for *field-based* material,\ndepending whether the field is top or bottom. Much more on the topic of\ninterlaced video on this page: `Interlaced Fieldbased`_.\n\nDue to antialiased text rendering, this filter can be a little slow.\n\nSee the :ref:`ShowFrameNumber examples <ShowFrameNumber-examples>` section.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    ShowFrameNumber (clip, bool \"scroll\", int \"offset\", float \"x\", float \"y\", string \"font\", float \"size\",\n                     int \"text_color\", int \"halo_color\", float \"font_width\", float \"font_angle\",\n                     bool \"bold\", bool \"italic\", bool \"noaa\")\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n.. describe:: scroll\n\n    | If *true*, the frame number will be drawn only once on the video and\n      scroll from top to bottom;\n    | If *false*, it will be drawn on one side, stacked vertically as often\n      as it fits.\n\n    Default: false\n\n.. describe:: offset\n\n    Sets the starting frame number.\n\n    Default: 0\n\n.. describe:: x, y\n\n    Text position. Their interpretation corresponds to :doc:`Subtitle's <subtitle>`\n    *align=4* and the special meaning of -1 is not available. Note that ``x``\n    and ``y`` must be used together or not at all; if they are present, the\n    ``scroll`` option is ignored.\n\n    Default: 0.0, 0.0\n\n.. describe:: font\n\n    Font name; can be the name of any installed Windows font.\n\n    Default: \"Arial\"\n\n.. describe:: size\n\n    Height of the text in pixels.\n\n    Default 24.\n\n.. describe:: text_color, halo_color\n\n    | Colors for font fill and outline respectively. Default is yellow and black.\n    | See :doc:`Subtitle <subtitle>` and the :doc:`colors <../syntax/syntax_colors>`\n      page for more information on specifying colors.\n\n    Default: $00FFFFFF, $00000000\n\n.. describe:: font_width\n\n    | Set character width in logical units, to the nearest 0.125 unit.\n    | See the example section of :doc:`Subtitle <subtitle>` for an example.\n\n    Default: 0 (use Windows' default width)\n\n.. describe:: font_angle\n\n    Adjust the baseline angle of text in degrees anti-clockwise to the\n    nearest 0.1 degree.\n\n    Default: 0.0 (no rotation)\n\n.. describe:: bold\n\n    | Using bold letters or not\n\n    Default: true on Windows GDI, false otherwise (e.g. in Linux)\n\n.. describe:: italic\n\n    | Using italic letters or not\n\n    Default: false\n\n.. describe:: noaa\n\n    | Disables antialiasing when drawing the text\n\n    Default: false\n\n\n.. _ShowSMPTE:\n\nShowSMPTE\n---------\n\nDisplays `SMPTE`_-style timecode labels for the current frame. Format is\nHH:MM:SS:FF (for example \"03:52:39:24\" = 3 hours, 52 minutes, 39 seconds and\n24 frames).\n\nFrame 0 is marked \"00:00:00:00\", frame 1 is marked \"00:00:00:01\" and so on –\nunless an *offset* is applied.\n\nDue to antialiased text rendering, this filter can be a little slow.\n\nSee the :ref:`ShowSMPTE examples <ShowSMPTE-examples>` section.\n\n.. note::\n    With certain exceptions, SMPTE timecode has no concept of fractional frame\n    rates (like 24.5 fps for example).\n\n    **ShowSMPTE** source clips must have an *integer* framerate (18, 24, 25, 30,\n    31,...) or a *drop-frame* rate ('29.97' being the most common). Supported\n    drop-frame rates are listed in the :ref:`table below <ShowSMPTE-table>`. If\n    that's not the case an error will be thrown.\n\n    If the framerate is not integral or drop-frame (let's call it \"nonstandard\"\n    for short), use `ShowFrameNumber`_ or `ShowTime`_ instead.\n\n    You may encounter media sources that are almost at a standard framerate,\n    but not quite – perhaps due to an error in processing at some point, or\n    perhaps the source was something like a security camera or a video game\n    console. In this case you should force the clip to the nearest standard\n    framerate with :doc:`AssumeFPS <fps>`.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    ShowSMPTE (clip, float \"fps\", string \"offset\", int \"offset_f\", float \"x\", float \"y\", string \"font\",\n               float \"size\", int \"text_color\", int \"halo_color\", float \"font_width\", float \"font_angle\",\n               bool \"bold\", bool \"italic\", bool \"noaa\")\n\n.. describe:: clip\n\n    Source clip; all color formats supported. See boxed note above.\n\n.. describe:: fps\n\n    | Not required, unless the current fps can't be used.\n    | If used, ``fps`` must be either an integer or a standard drop-frame rate\n      as listed in the :ref:`table below <ShowSMPTE-table>`.\n\n    Default: (clip.Framerate)\n\n.. describe:: offset\n\n    Sets the start time. Format is *HH:MM:SS:FF* (for example \"03:52:39:24\" -\n    3 hours, 52 minutes, 39 seconds and 24 frames).\n\n.. describe:: offset_f\n\n    Sets the starting frame number; ignored if ``offset`` is supplied.\n\n    Default: 0\n\n.. describe:: x, y\n\n    | Text position. Their interpretation corresponds to :doc:`Subtitle's <subtitle>`\n      *align=2*.\n\n    Default: 0.0, 0.0\n\n.. describe:: font\n\n    Font name; can be the name of any installed Windows font.\n\n    Default: \"Arial\"\n\n.. describe:: size\n\n    Height of the text in pixels.\n\n    Default 24.\n\n.. describe:: text_color, halo_color\n\n    | Colors for font fill and outline respectively. Default is yellow and black.\n    | See :doc:`Subtitle <subtitle>` and the :doc:`colors <../syntax/syntax_colors>`\n      page for more information on specifying colors.\n\n    Default: $00FFFFFF, $00000000\n\n.. describe:: font_width\n\n    | Set character width in logical units, to the nearest 0.125 unit.\n    | See the example section of :doc:`Subtitle <subtitle>` for an example.\n\n    Default: 0 (use Windows' default width)\n\n.. describe:: font_angle\n\n    Adjust the baseline angle of text in degrees anti-clockwise to the\n    nearest 0.1 degree.\n\n    Default: 0.0 (no rotation)\n\n.. describe:: bold\n\n    | Using bold letters or not\n\n    Default: true on Windows GDI, false otherwise (e.g. in Linux)\n\n.. describe:: italic\n\n    | Using italic letters or not\n\n    Default: false\n\n.. describe:: noaa\n\n    | Disables antialiasing when drawing the text\n\n    Default: false\n\nDrop-Frame versus Non-Drop-Frame Time Code\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWhen television began, it was black-and-white only. At that time NTSC\n(\"American\" standard) television ran at 30 frames per second (60 fields per\nsecond). When the television engineers added color, they slowed the frame rate\nby the precise ratio 1000/1001, due to `technical reasons`_. NTSC televisions\nnow run at 30×1000/1001 or approximately 29.97002997 frames per second. This is\ncommonly called \"29.97 fps.\" 29.97 is the *nominal* framerate, a convenient\nshortcut term for 30×1000/1001.\n\nThis slight slowing of the framerate complicates the display of timecode.\nA second of time no longer consists of a whole number of frames. If the\ntimecode readout simply advanced the *seconds* counter every 30 frames, the\ntimecode reading would be slower than clock time by about 3.6 seconds per hour.\nTimecode displays cannot show \"fractional\" frames (their whole purpose is to\nuniquely identify every frame) so they `drop`_ the display of just enough frame\nnumbers to make the displayed timecode correspond to real or clock time. This\nis done in a prescribed and repeatable fashion: the first two frame numbers of\nevery minute, except for the tenth minute, are dropped, ie::\n\n    00:00:00:00, 00:00:00:01, 00:00:00:02, ...,\n    00:00:59:29, 00:01:00:02, 00:01:00:03,\n    00:01:59:29, 00:02:00:02, 00:02:00:03, ...,\n    00:08:59:29, 00:09:00:02, 00:09:00:03, ...,\n    00:09:59:29, 00:10:00:00, 00:10:00:01, etc\n\n.. _ShowSMPTE-table:\n\n**ShowSMPTE** automatically assumes `drop-frame timecode`_ given certain input\nframerate ranges, as listed in the table below. For example, if the input\nframerate is > 29.969 and < 29.971 fps, the framerate is assumed to be\n30×1000/1001 for time calculation, and drop-frame counting is used.\n\n    .. table::\n        :widths: auto\n\n        +-----------------------------+---------------+--------------+\n        | Input fps (bounds excluded) | Assumed rate  | Nominal rate |\n        +=============================+===============+==============+\n        | 23.975 – 23.977             | 24×1000/1001  | 23.98        |\n        +-----------------------------+---------------+--------------+\n        | 29.969 – 29.971             | 30×1000/1001  | 29.97        |\n        +-----------------------------+---------------+--------------+\n        | 47.951 – 47.953             | 48×1000/1001  | 47.95        |\n        +-----------------------------+---------------+--------------+\n        | 59.939 – 59.941             | 60×1000/1001  | 59.94        |\n        +-----------------------------+---------------+--------------+\n        | 119.879 - 119.881           | 120×1000/1001 | 119.88       |\n        +-----------------------------+---------------+--------------+\n\nYou may encounter the term \"NDF\" - this means \"*non-drop-frame*.\" As you would\nexpect, this is used for all the integer framerates. Sometimes though, video\nrunning at *drop-frame rates* will have NDF timecode. This is most common for\nshort-form videos of a few minutes' duration at most: some video professionals\nprefer not to skip frame numbers at all, even though the time display will be\noff slightly. To get **ShowSMPTE** to show NDF timecode at drop-frame rates, see\nthe :ref:`examples section below <ShowSMPTE-ndf>`.\n\n.. _ShowTime:\n\nShowTime\n--------\n\nDisplays time for the current frame. Format is HH:MM:SS.DDD (for example\n\"03:52:39.800\" = 3 hours, 52 minutes, 39 seconds and 800 milliseconds).\n\nDue to antialiased text rendering, this filter can be a little slow.\n\nSee the :ref:`ShowTime examples <ShowTime-examples>` section.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    ShowTime (clip, int \"offset_f\", float \"x\", float \"y\", string \"font\", float \"size\",\n              int \"text_color\", int \"halo_color\", float \"font_width\", float \"font_angle\",\n              bool \"bold\", bool \"italic\", bool \"noaa\")\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n.. describe:: offset_f\n\n    Sets the starting frame number. Displayed time will be increased by\n    ``offset_f/clip.FrameRate`` seconds.\n\n    Default: 0\n\n.. describe:: x, y\n\n    | Text position. Their interpretation corresponds to :doc:`Subtitle's <subtitle>`\n      *align=2*.\n\n    Default: 0.0, 0.0\n\n.. describe:: font\n\n    Font name; can be the name of any installed Windows font.\n\n    Default: \"Arial\"\n\n.. describe:: size\n\n    Height of the text in pixels.\n\n    Default 24.\n\n.. describe:: text_color, halo_color\n\n    | Colors for font fill and outline respectively. Default is yellow and black.\n    | See :doc:`Subtitle <subtitle>` and the :doc:`colors <../syntax/syntax_colors>`\n      page for more information on specifying colors.\n\n    Default: $00FFFFFF, $00000000\n\n.. describe:: font_width\n\n    | Set character width in logical units, to the nearest 0.125 unit.\n    | See the example section of :doc:`Subtitle <subtitle>` for an example.\n\n    Default: 0 (use Windows' default width)\n\n.. describe:: font_angle\n\n    Adjust the baseline angle of text in degrees anti-clockwise to the\n    nearest 0.1 degree.\n\n    Default: 0.0 (no rotation)\n\n.. describe:: bold\n\n    | Using bold letters or not\n\n    Default: true on Windows GDI, false otherwise (e.g. in Linux)\n\n.. describe:: italic\n\n    | Using italic letters or not\n\n    Default: false\n\n.. describe:: noaa\n\n    | Disables antialiasing when drawing the text\n\n    Default: false\n\nExamples\n--------\n\n.. _ShowFrameNumber-examples:\n\n.. rubric:: `ShowFrameNumber`_\n\n* Default appearance if source is frame-based:\n\n .. list-table::\n\n    * - .. figure:: pictures/showframenumber-sintel-4592.jpg\n\n        ::\n\n            LSMASHSource(\"sintel-2048-surround.mp4\")\n            ShowFrameNumber()\n\n* Draw the frame numbers in red, scrolling from top to bottom, starting with\n  \"00009\"::\n\n    # this is always top field first, therefore numbers will be on the left\n    Mpeg2Source(\"clip.d2v\")\n    ShowFrameNumber(scroll=true, offset=9, text_color=$ff0000)\n\n.. _ShowSMPTE-examples:\n\n.. rubric:: `ShowSMPTE`_\n\n* Default appearance:\n\n .. list-table::\n\n    * - .. figure:: pictures/showsmpte-sintel-4592.jpg\n\n        ::\n\n            LSMASHSource(\"sintel-2048-surround.mp4\")\n            ShowSMPTE()\n\n* Change the position::\n\n    fontheight=32\n\n    ##bottom center\n    ShowSMPTE(size=fontheight)\n\n    ##top center\n    ShowSMPTE(size=fontheight, y=(fontheight))\n\n    ##top left\n    ShowSMPTE(size=fontheight, x=(fontheight*3), y=(fontheight))\n\n    ##top right\n    ShowSMPTE(size=fontheight, x=(Width-fontheight*3), y=(fontheight))\n\n.. _ShowSMPTE-ndf:\n\n* Showing non-drop-frame timecode at drop-frame rates::\n\n    ColorBars()               ## (framerate = 29.97)\n    ShowSMPTE(size=24, y=24)  ## timecode (top of screen) is DF (drop-frame)\n    C=Last\n    AssumeFPS(30)             ## force integer framerate\n    ShowSMPTE()               ## timecode (bottom of screen) is NDF\n    AssumeFPS(C)              ## fps returned to original\n    return Last\n\n    ## DF (top) skips frame numbers at frames 1800, 3598, 106094...\n    ## NDF (bottom) does not skip numbers but runs slower than real time\n    ##  (frame 106094 = DF \"00:59:00:02\" == NDF \"00:58:56:14\")\n\n* Using ``offset``, ``x``, ``y``, ``font``, ``size``, and ``text_color``\n  arguments::\n\n    ShowSMPTE(offset=\"00:00:59:29\", x=360, y=576, font=\"georgia\", size=24, text_color=$ff0000)\n\n.. _ShowTime-examples:\n\n.. rubric:: `ShowTime`_\n\n* Default appearance:\n\n .. list-table::\n\n    * - .. figure:: pictures/showtime-sintel-4592.jpg\n\n        ::\n\n            LSMASHSource(\"sintel-2048-surround.mp4\")\n            ShowTime()\n\nChangelog\n---------\n\n+-----------------+-----------------------------------------------------------------------------+\n| Version         | Changes                                                                     |\n+=================+=============================================================================+\n| AviSynth+ 3.7.3 | Add ``bold``, ``italic`` and ``noaa``                                       |\n+-----------------+-----------------------------------------------------------------------------+\n| AviSynth 2.6.0  || All functions: position (x,y) can be float (previously int) (with 0.125    |\n|                 |  pixel granularity).                                                        |\n|                 || ShowSMPTE: added drop-frame for other framerates (other than 30).          |\n+-----------------+-----------------------------------------------------------------------------+\n| AviSynth 2.5.8  || Added ShowTime function.                                                   |\n|                 || Added ``font_width``, ``font_angle`` args.                                 |\n+-----------------+-----------------------------------------------------------------------------+\n| AviSynth 2.5.6  | Added ``offset`` and other options.                                         |\n+-----------------+-----------------------------------------------------------------------------+\n\n$Date: 2023/11/03 11:15:00 $\n\n.. _Interlaced Fieldbased:\n    http://avisynth.nl/index.php/Interlaced_fieldbased\n.. _SMPTE:\n    http://en.wikipedia.org/wiki/SMPTE_timecode\n.. _drop-frame timecode:\n    https://web.archive.org/web/20090206001750/http://teched.vt.edu/GCC/HTML/VirtualTextbook/PDFs/AdobeTutorialsPDFs/Premiere/PremiereTimecode.pdf\n.. _technical reasons:\n    https://web.archive.org/web/20180810220539/http://documentation.apple.com/en/finalcutpro/usermanual/index.html#chapter=D%26section=6%26tasks=true\n.. _drop:\n    https://en.wikipedia.org/wiki/SMPTE_timecode#Drop-frame_timecode\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/skewrows.rst",
    "content": "========\nSkewRows\n========\n\nSkews the rows of a clip. It can be used to correct (deskew) problem clips such\nas the :doc:`error message <message>` shown below.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    SkewRows (clip, int skew)\n\n.. describe:: clip\n\n    Source clip. All :doc:`interleaved <../FilterSDK/InterleavedImageFormat>`\n    pixel formats are supported (including Y8).\n\n.. describe:: skew\n\n    Skew amount, can be positive or negative. For YUY2 sources, ``skew`` should\n    be even (divisible by 2). The skewing is memory layout based, so RGB images\n    are skewed from the bottom up, YUV images are skewed from the top down.\n\n    The effect of the algorithm is to paste all of the input rows together as\n    one single very long row, then slice them up based on the new width (= input\n    width + ``skew``). When the skew amount is negative, the last skew pixels of\n    each line are added to the beginning of the next line and you get some extra\n    lines at the end. The last line is padded with grey pixels when required.\n\n    The geometry of the output is calculated as follows:\n\n    * ``OutWidth = InWidth + skew`` // signed skew values acceptable\n    * ``OutHeight = (InHeight*InWidth + OutWidth-1) / OutWidth`` // rounded up\n      to nearest integer\n\n    In other words, the width and height of the output clip are therefore\n    altered slightly.\n\nExamples\n---------\n\n.. list-table::\n\n    * - .. figure:: pictures/skewrows_before.png\n\n           (original with skew problem)\n\n    * - .. figure:: pictures/skewrows_after.png\n\n           ``SkewRows(1)``\n\n\nSee also\n--------\n\n:doc:`AviSource <avisource>` and :doc:`DirectShowSource <directshowsource>`\npixel_type:\n\n    For planar color formats, adding a '+' prefix, e.g.\n    DirectShowSource(..., pixel_type=\"+YV12\"), tells AviSynth the video rows are\n    DWORD aligned in memory instead of packed. **This can fix skew or tearing of\n    the decoded video when the width of the picture is not divisible by 4.**\n\n\nChangelog\n----------\n\n+----------------+-----------------+\n| Version        | Changes         |\n+================+=================+\n| AviSynth 2.6.0 | Initial release |\n+----------------+-----------------+\n\n$Date: 2022/03/17 12:22:43 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/soften.rst",
    "content": "Soften Filters\n==============\n\n`SpatialSoften`_ and `TemporalSoften`_ remove noise from a video clip by\nselectively blending pixels.\n\n.. _SpatialSoften:\n\nSpatialSoften\n-------------\n\nLike :doc:`Blur <blur>`, **SpatialSoften** blends neighboring pixels in the\nframe – but with a wider possible ``radius``, and only if neighboring pixels\nare within ``luma_threshold`` and ``chroma_threshold``, as explained below.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    SpatialSoften (clip clip, int radius, int luma_threshold, int chroma_threshold)\n\n.. describe:: clip\n\n    Source clip. Must be `YUY2`_ color format.\n\n.. describe:: radius\n\n    | Filter radius – defines which pixels are processed.\n    | Range 0-32; ``radius=0`` results in no smoothing. Values > 32 may cause\n      AviSynth to crash.\n\n.. describe:: luma_threshold, chroma_threshold\n\n    When smoothing a given pixel P, ``SpatialSoften`` ignores any neighbor pixel\n    P\\ :sub:`n` where:\n\n    * P\\ :sub:`n` luma differs from P luma by more than ``luma_threshold``, OR\n    * P\\ :sub:`n` chroma differs from P chroma by more than ``chroma_threshold``.\n\n.. _TemporalSoften:\n\nTemporalSoften\n--------------\n\nBlends corresponding pixels in neighboring frames. All frames no more than radius\naway are examined. Blending occurs only if corresponding pixels are within\n``luma_threshold`` or ``chroma_threshold``, as explained below.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    TemporalSoften (clip clip, int radius, int luma_threshold, int chroma_threshold,\n                    int \"scenechange\", int \"mode\")\n\n.. describe:: clip\n\n    Source clip. All color formats are supported except RGB24 and RGB48.\n\n.. describe:: radius\n\n    | Filter radius. All frames no more than ``radius`` from the current frame\n      are examined.\n    | (for ``radius=2``, FIVE frames are processed: the current frame, two ahead\n      and two behind)\n    | Range 0-7; ``radius=0`` results in no smoothing.\n\n.. describe:: luma_threshold\n\n    When smoothing a given luma pixel Y, the corresponding pixel in neighboring\n    frame Y\\ :sub:`n` is ignored where Y\\ :sub:`n` differs from Y by more than\n    ``luma_threshold``.\n\n.. describe:: chroma_threshold\n\n    When smoothing a given chroma pixel C, the corresponding pixel in neighboring\n    frame C\\ :sub:`n` is ignored where C\\ :sub:`n` differs from C by more than\n    ``chroma_threshold``.\n\n    * Good starting values are around 1 or 2 times ``luma_threshold``.\n\n.. describe:: scenechange\n\n    Defines the maximum average pixel change between frames; set properly, this\n    will avoid blending across scene changes.\n\n    * Good values are between 5 and 30, somewhat higher than ``luma_threshold``.\n    * ``scenechange`` not supported in RGB32 and RGB64 colorspaces.\n\n    Default: 0\n\n.. describe:: mode\n\n    **Deprecated** - this parameter is simply ignored.\n\n.. note::\n    Note that arguments are `autoscaling`_ – they are always 0-255 at all bit depths.\n\n\nExamples\n--------\n\nGood initial values:\n\n::\n\n    TemporalSoften(4, 4, 8, scenechange=15)\n\n\nChangelog\n---------\n\n+-----------------+---------------------------------------------------------------------------+\n| Version         | Changes                                                                   |\n+=================+===========================================================================+\n| AviSynth+ 3.5.0 | Fix: TemporalSoften possible access violation after SeparateFields        |\n|                 | (in general: after filters that only change frame pitch).                 |\n+-----------------+---------------------------------------------------------------------------+\n| AviSynth+ r2580 | Fix: TemporalSoften 10-14 bits: an SSE 4.1 instruction was used for       |\n|                 | SSE2-only CPUs.                                                           |\n+-----------------+---------------------------------------------------------------------------+\n| AviSynth+ r2508 | Fix: TemporalSoften threshold < 255 (probably since r1576).               |\n+-----------------+---------------------------------------------------------------------------+\n| AviSynth+ r2487 || TemporalSoften: 10-12-14 bit support for planar RGB(A)/YUV(A) and        |\n|                 |  RGB32/64 formats.                                                        |\n|                 || TemporalSoften: much faster average mode (thres=255).                    |\n+-----------------+---------------------------------------------------------------------------+\n| AviSynth+ r2397 || TemporalSoften: Planar RGB(A) support.                                   |\n|                 || TemporalSoften: much faster average mode (thres=255).                    |\n+-----------------+---------------------------------------------------------------------------+\n| AviSynth+ r2290 | TemporalSoften: added 16/32 bit support.                                  |\n+-----------------+---------------------------------------------------------------------------+\n| AviSynth+ r1841 | TemporalSoften: frame leak fix.                                           |\n+-----------------+---------------------------------------------------------------------------+\n| Avisynth+ r1576 || TemporalSoften: mode 1 removed, ``mode`` parameter ignored.              |\n|                 || TemporalSoften: now has C and SSE2 versions.                             |\n+-----------------+---------------------------------------------------------------------------+\n| AviSynth 2.6.0  | TemporalSoften: added support for Y8, YV411, YV16 and YV24 color formats. |\n+-----------------+---------------------------------------------------------------------------+\n| AviSynth 2.5.6  | TemporalSoften working also with RGB32 input (as well as YV12, YUY2).     |\n+-----------------+---------------------------------------------------------------------------+\n\n$Date: 2022/02/28 18:06:23 $\n\n.. _YUY2:\n    http://avisynth.nl/index.php/YUY2\n.. _autoscaling:\n    http://avisynth.nl/index.php/Autoscale_parameter\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/soundout.rst",
    "content": "\nSoundOut\n========\n\nSoundOut is a GUI driven sound output module for AviSynth.\n\n\nInstallation and Usage\n----------------------\n\nCopy \"SoundOut.dll\" and \"libsndfile-1.dll\" to your AviSynth plugin directory,\nusually ``\"c:\\program files\\avisynth 2.5\\plugins\"``. If you want to have\n\"SoundOut.dll\" at another location, you should move \"libsndfile-1.dll\" to\nyour system32 folder, usually ``\"c:\\windows\\system32\"``.\n\nAdd ``SoundOut()`` to your script, where you would like to export audio. If\nyou have your video stored in a variable, use ``SoundOut(variable)`` to add\nSoundOut. A GUI should pop up, when you open your script. Here is a simple\nexample of how to use it:\n\n::\n\n    AviSource(\"myvideo.avi\")\n    SoundOut()\n\nIf you need some sample processing, to change samplerate or otherwise edit\nyour video, you must do it before calling the SoundOut module. Like this:\n\n::\n\n    AviSource(\"myvideo.avi\")\n    Amplifydb(3)\n    SSRC(44100)\n    SoundOut()\n\nOutput Modules\n--------------\n\n\nWAV/AIF/CAF\n~~~~~~~~~~~\n\nThis will allow you to export uncompressed audio to the following formats:\n\n-   Microsoft WAV format\n-   Apple/SGI AIFF format\n-   Sun/NeXT AU format\n-   RAW PCM data\n-   Sonic Foundry's 64 bit RIFF/WAV (WAVE64)\n-   Apple Core Audio File format\n-   Microsoft WAV format with Broadcast Wave Format chunk.\n\nNote, that 8 bit samples are NOT supported in the Core Audio File and\nSun/NeXT AU format.\n\n\nFLAC\n~~~~\n\nThis will allow you to export lossless compressed audio FLAC format.\n\nFLAC supports 8,16 or 24 bit audio. Any other format is internally converted\nto 24 bit.\n\n\nAPE\n~~~\n\nThis will allow you to export lossless compressed audio to the Monkey Audio\nCodec (APE) format.\n\nAPE does not support input sample sizes that are larger than 2GB. Use only\nfor smaller files.\n\nAPE supports 8, 16 or 24 bit audio. Any other format is internally converted\nto 24 bit.\n\n\nMP2\n~~~\n\nThis will allow you to compress your audio to MPEG 1 Layer 2 (MP2).\n\nTwoLame only supports 16 mono or stereo audio. If you attempt to compress\nmore than two channels, an error will be shown. Any other format than 16 bit\ninteger samples are internally converted to 16 bit.\n\n\nMP3\n~~~\n\nThis will allow you to compress your audio to MPEG 1 Layer 3 (MP3) using LAME\nv3.97 encoder.\n\n| LAME Supports up to two channels of audio and the following samplerates:\n| 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025 and 8000 Hz.\n\n\nAC3\n~~~\n\nThis will allow you to compress your audio to A/52 (AC3). The encoding is\ndone via libaften.\n\nAften supports 1 to 6 channel audio. Supported samplerates are 48000, 44100\nor 32000 samples per second.\n\nChannel mapping is:\n\n+--------------------+---------------------------------------------------------+\n| Number of channels | Channel order                                           |\n+====================+=========================================================+\n| 1                  | Center                                                  |\n+--------------------+---------------------------------------------------------+\n| 2                  | Left, Right                                             |\n+--------------------+---------------------------------------------------------+\n| 3                  | Left, Center, Right                                     |\n+--------------------+---------------------------------------------------------+\n| 4                  | Left, Right, Surround Left, Surround Right              |\n+--------------------+---------------------------------------------------------+\n| 5                  | Left, Center, Right, Surround Left, Surround Right      |\n+--------------------+---------------------------------------------------------+\n| 6                  | Left, Center, Right, Surround Left, Surround Right, LFE |\n+--------------------+---------------------------------------------------------+\n\nOGG\n~~~\n\nThis will allow you to compress your audio to an Vorbis encoded OGG file. It\nis possible to give an average bitrate, or do the encode as CBR.\n\n\nWavPack\n~~~~~~~\n\nWavPack is a completely open audio compression format providing lossless,\nhigh-quality lossy compression mode. Compatible with virtually all PCM audio\nformats including 8, 16, 24, and 32-bit ints; 32-bit floats; mono, stereo,\nand multichannel; sampling rates from 6 to 192 kHz (and non-standard rates)\n\n\nCommandline Output\n~~~~~~~~~~~~~~~~~~\n\nThis output module will allow you to output to any program that supports\ninput from stdin. This gives you complete control of your encoding, if you\nhave commandline tools for the job.\n\nYou can select the format SoundOut should deliver to the application you use.\nThere are three WAV formats and RAW PCM data. This is sent to stdin of the\napplication. The program builds the command line from 4 parts, *the\nexecutable*, *command line options* before the output file, the *output file*\nthat is selected, and *command line options* after the output file name.\n\nThere are two ways of specifying the executable. Either give complete path to\nthe executable, or simply enter the executable's filename, and place it in a\nsubdirectory called SoundOut in your plugin directory.\n\n\nExporting from script\n---------------------\n\nIt is possible to use SoundOut as an ordinary filter, running inside the\nscript and giving parameters for each output mode. The parameters consists of\ntwo things: General Parameters, which can be used for all filters, and filter\nspecific parameters, which gives parameters to the active output module.\n\nThe **out** parameter determines whether the GUI will be shown, if it is\nproperly set, the filter will begin exporting audio as soon as it is started.\n\nIf the **out** parameter is **not** set, it is still possible to set\nadditional parameters. The defaults will however be retrieved from the\nregistry, but specific parameters override\n\n\nGeneral Parameters\n~~~~~~~~~~~~~~~~~~\n\n+----------------+---------+----------------------------------------------------------------------------------------+\n| Parameter name | Type    | Values                                                                                 |\n+================+=========+========================================================================================+\n| output         | string  || Select output module to use. Possible values are:                                     |\n|                |         || \"WAV\", \"AC3\", \"MP2\", \"MP3\", \"OGG\", \"FLAC\", \"MAC\", \"WV\" and \"CMD\".                     |\n|                |         || If none, or an invalid value is given, the ordinary GUI will be shown.                |\n+----------------+---------+----------------------------------------------------------------------------------------+\n| filename       | string  || Full path to the output filename, including extension.                                |\n|                |         || No extra quotes are required.                                                         |\n|                |         || If no filename is given a file selector will pop up.                                  |\n+----------------+---------+----------------------------------------------------------------------------------------+\n| showprogress   | bool    || Show the progress window? Default: true                                               |\n+----------------+---------+----------------------------------------------------------------------------------------+\n| overwritefile  | string  || \"Yes\": Always overwrite file.                                                         |\n|                |         || \"No\": Never Overwrite file                                                            |\n|                |         || \"Ask\": Ask if file should be overwritten.                                             |\n+----------------+---------+----------------------------------------------------------------------------------------+\n| autoclose      | bool    || Should the progress window close automatically 5 seconds after                        |\n|                |         |  encoding has finished?                                                                |\n|                |         || This will also code the window, even though an error occurred                         |\n|                |         || Default: false                                                                        |\n+----------------+---------+----------------------------------------------------------------------------------------+\n| silentblock    | bool    || When processing, enabling this option will return silent                              |\n|                |         |  samples instead of blocking the requesting application. If disabled, any              |\n|                |         |  application requesting audio will be blocking, while sound is being exported          |\n|                |         || Default: true                                                                         |\n+----------------+---------+----------------------------------------------------------------------------------------+\n| addvideo       | bool    || When enabled, this will add video to the current output, if none                      |\n|                |         |  is present. The video is a black 32x32 pixels at 25fps, with the length of the audio. |\n|                |         || Default: true                                                                         |\n+----------------+---------+----------------------------------------------------------------------------------------+\n| wait           | integer || How many seconds should the output window be shown, if autoclose is on.               |\n|                |         || Default: 5.                                                                           |\n+----------------+---------+----------------------------------------------------------------------------------------+\n\nWAV/AIF/CAF Script Parameters\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n+----------------+---------+----------------------------------------------------+\n| Parameter name | Type    | Values                                             |\n+================+=========+====================================================+\n| type           | integer || Select WAVE format                                |\n|                |         || 0: Microsoft WAV (default),                       |\n|                |         || 1: WAV with WAVEFORMATEX,                         |\n|                |         || 2: Apple/SGI AIFF,                                |\n|                |         || 3: Sun/NeXT AU,                                   |\n|                |         || 4: RAW PCM,                                       |\n|                |         || 5: S.F. WAVE64,                                   |\n|                |         || 6: Core Audio File,                               |\n|                |         || 7: Broadcast Wave.                                |\n+----------------+---------+----------------------------------------------------+\n| format         | integer || Sets the sample format number of bits per sample. |\n|                |         || 0: 16bit per sample,                              |\n|                |         || 1: 24bit per sample,                              |\n|                |         || 2: 32bit per sample,                              |\n|                |         || 3: 32bit float per sample,                        |\n|                |         || Default: Same as input.                           |\n+----------------+---------+----------------------------------------------------+\n| peakchunck     | bool    || Add Peak chunk to WAV file?                       |\n|                |         || Default: false                                    |\n+----------------+---------+----------------------------------------------------+\n\nAudio will be written in the format delivered to the SoundOut plugin. All\ninternal sound formats are supported.\n\n\nFLAC Script Parameters\n~~~~~~~~~~~~~~~~~~~~~~\n\n+------------------+---------+-------------------------------------------------------+\n| Parameter name   | Type    | Values                                                |\n+==================+=========+=======================================================+\n| compressionlevel | integer || Sets the compression level. 1(fastest) to 8(slowest) |\n|                  |         || Default: 6                                           |\n+------------------+---------+-------------------------------------------------------+\n\nAPE Script Parameters\n~~~~~~~~~~~~~~~~~~~~~\n\n+------------------+---------+-------------------------------------------------------+\n| Parameter name   | Type    | Values                                                |\n+==================+=========+=======================================================+\n| compressionlevel | integer || Sets the compression level. 1(fastest) to 6(slowest) |\n|                  |         || Default: 3                                           |\n+------------------+---------+-------------------------------------------------------+\n\nMP2 Script Parameters\n~~~~~~~~~~~~~~~~~~~~~\n\n+----------------+---------+-------------------------------------------------------+\n| Parameter name | Type    | Values                                                |\n+================+=========+=======================================================+\n| bitrate        | integer || Sets Bitrate for CBR or maximum bitrate for VBR.     |\n|                |         || Default: 192                                         |\n+----------------+---------+-------------------------------------------------------+\n| stereomode     | integer || -1: Automatic (default)                              |\n|                |         || 0: Separate Stereo                                   |\n|                |         || 1: Separate Stereo                                   |\n|                |         || 2: Joint Stereo                                      |\n|                |         || 3: Dual Channel                                      |\n|                |         || 4: Mono                                              |\n+----------------+---------+-------------------------------------------------------+\n| psymodel       | integer || -1: Fast & Dumb                                      |\n|                |         || 0: Low complexity                                    |\n|                |         || 1: ISO PAM 1                                         |\n|                |         || 2: ISO PAM 2                                         |\n|                |         || 3: PAM 1 Rewrite (default)                           |\n|                |         || 4: PAM 2 Rewrite                                     |\n+----------------+---------+-------------------------------------------------------+\n| vbrquality     | float   || Sets VBR Quality. Useful range is about -10 to 10.   |\n|                |         || Default is 0                                         |\n+----------------+---------+-------------------------------------------------------+\n| vbr            | bool    || Encode as VBR?                                       |\n|                |         || Default: false.                                      |\n+----------------+---------+-------------------------------------------------------+\n| quick          | bool    || Quick Encode?                                        |\n|                |         || Default: false.                                      |\n+----------------+---------+-------------------------------------------------------+\n| dab            | bool    || Add DAB Extensions?                                  |\n|                |         || Default: false.                                      |\n|                |         || *According to TwoLame documentation this might not   |\n|                |         |  be reliable.*                                        |\n+----------------+---------+-------------------------------------------------------+\n| crc            | bool    || Add CRC Error checks?                                |\n|                |         || Default: false.                                      |\n+----------------+---------+-------------------------------------------------------+\n| original       | bool    || Set Original Flag?                                   |\n|                |         || Default: false.                                      |\n+----------------+---------+-------------------------------------------------------+\n| copyright      | bool    || Set Copyright flag?                                  |\n|                |         || Default: false.                                      |\n+----------------+---------+-------------------------------------------------------+\n| emphasis       | integer || Set Emphasis flag.                                   |\n|                |         || 0: No Emphasis (default)                             |\n|                |         || 1: 50/15 ms                                          |\n|                |         || 3: CCIT J.17                                         |\n+----------------+---------+-------------------------------------------------------+\n\n\nMP3 Script Parameters\n~~~~~~~~~~~~~~~~~~~~~\n\n+----------------+---------+-------------------------------------------------------+\n| Parameter name | Type    | Values                                                |\n+================+=========+=======================================================+\n| mode           | integer || Sets Encoding mode:                                  |\n|                |         || 0: VBR (default)                                     |\n|                |         || 1: ABR                                               |\n|                |         || 2: CBR                                               |\n+----------------+---------+-------------------------------------------------------+\n| vbrpreset      | integer || Sets quality preset, when using VBR mode.            |\n|                |         || Standard = 1001 (default),                           |\n|                |         || extreme = 1002,                                      |\n|                |         || insane = 1003,                                       |\n|                |         || standard_fast = 1004,                                |\n|                |         || extreme_fast = 1005,                                 |\n|                |         || medium = 1006,                                       |\n|                |         || medium_fast = 1007                                   |\n+----------------+---------+-------------------------------------------------------+\n| abrrate        | integer || Sets Average bitrate for ABR encoding.               |\n|                |         || Default: 128                                         |\n+----------------+---------+-------------------------------------------------------+\n| cbrrate        | integer || Sets Bitrate for CBR encoding.                       |\n|                |         || Default: 128                                         |\n+----------------+---------+-------------------------------------------------------+\n\nAC3 Script Parameters\n~~~~~~~~~~~~~~~~~~~~~\n\n+---------------------+---------+--------------------------------------------------------------+\n| Parameter name      | Type    | Values                                                       |\n+=====================+=========+==============================================================+\n| iscbr               | bool    || Encode at Constant Bitrate?                                 |\n|                     |         || Default: true.                                              |\n+---------------------+---------+--------------------------------------------------------------+\n| cbrrate             | integer || Sets Bitrate for CBR or maximum bitrate for VBR.            |\n|                     |         || Default: 384                                                |\n+---------------------+---------+--------------------------------------------------------------+\n| vbrquality          | integer || VBR Bitrate quality. Values between 1 and 1023 are accepted |\n|                     |         || Default: 220.                                               |\n+---------------------+---------+--------------------------------------------------------------+\n| drc                 | integer || Dynamic Range Compression                                   |\n|                     |         || 0: Film Light                                               |\n|                     |         || 1: Film Standard                                            |\n|                     |         || 2: Music Light                                              |\n|                     |         || 3: Music Standard                                           |\n|                     |         || 4: Speech                                                   |\n|                     |         || 5: None (default)                                           |\n+---------------------+---------+--------------------------------------------------------------+\n| acmod               | integer || Set channel mapping                                         |\n|                     |         || 0 = 1+1 (Ch1,Ch2)                                           |\n|                     |         || 1 = 1/0 (C)                                                 |\n|                     |         || 2 = 2/0 (L,R)                                               |\n|                     |         || 3 = 3/0 (L,R,C)                                             |\n|                     |         || 4 = 2/1 (L,R,S)                                             |\n|                     |         || 5 = 3/1 (L,R,C,S)                                           |\n|                     |         || 6 = 2/2 (L,R,SL,SR)                                         |\n|                     |         || 7 = 3/2 (L,R,C,SL,SR)                                       |\n+---------------------+---------+--------------------------------------------------------------+\n| dialognormalization | integer || Dialog normalization. Values from 0 to 31 are               |\n|                     |         |  accepted                                                    |\n|                     |         || Default: 31.                                                |\n+---------------------+---------+--------------------------------------------------------------+\n| islfe               | bool    || Is there LFE channel present?                               |\n|                     |         || Default: false if less than 4 channels, true otherwise.     |\n+---------------------+---------+--------------------------------------------------------------+\n| bandwidthfilter     | bool    || Use the bandwidth low-pass filter?                          |\n|                     |         || Default: false.                                             |\n+---------------------+---------+--------------------------------------------------------------+\n| lfelowpass          | bool    || Use the LFE low-pass filter                                 |\n|                     |         || Default: false.                                             |\n+---------------------+---------+--------------------------------------------------------------+\n| dchighpass          | bool    || Use the DC high-pass filter                                 |\n|                     |         || Default: false.                                             |\n+---------------------+---------+--------------------------------------------------------------+\n| dolbysurround       | bool    || Is the material Dolby Surround encoded? (only applies to    |\n|                     |         |  stereo sound, otherwise ignored)                            |\n|                     |         || Default: false.                                             |\n+---------------------+---------+--------------------------------------------------------------+\n| blockswitch         | bool    || Selectively use 256-point MDCT?                             |\n|                     |         || Default: false (Use only 512-point MDCT).                   |\n+---------------------+---------+--------------------------------------------------------------+\n| accuratealloc       | bool    || Do more accurate encoding?                                  |\n|                     |         || Default: true.                                              |\n+---------------------+---------+--------------------------------------------------------------+\n\nOGG Script Parameters\n~~~~~~~~~~~~~~~~~~~~~\n\n+----------------+---------+-------------------------------------------+\n| Parameter name | Type    | Values                                    |\n+================+=========+===========================================+\n| vbrbitrate     | integer || Selects the average bitrate to encode at |\n|                |         || Default: 128.                            |\n+----------------+---------+-------------------------------------------+\n| cbr            | bool    || Encode as CBR?                           |\n|                |         || Default: false.                          |\n+----------------+---------+-------------------------------------------+\n\nWavpack Script Parameters\n~~~~~~~~~~~~~~~~~~~~~~~~~\n\n+------------------+---------+----------------------------------------------------+\n| Parameter name   | Type    | Values                                             |\n+==================+=========+====================================================+\n| compressionlevel | integer || Sets the compression level. 0(Very Fast) to       |\n|                  |         |  5(Extremely Slow)                                 |\n|                  |         || Default: 2 (Normal)                               |\n+------------------+---------+----------------------------------------------------+\n| format           | integer || Sets the sample format number of bits per sample. |\n|                  |         || 0: 8bit per sample,                               |\n|                  |         || 1: 16bit per sample,                              |\n|                  |         || 2: 24bit per sample,                              |\n|                  |         || 3: 32bit per sample,                              |\n|                  |         || 4: 32bit float per sample,                        |\n|                  |         || Default: Same as input.                           |\n+------------------+---------+----------------------------------------------------+\n\nCommandline Output Script Parameters\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n+----------------+---------+--------------------------------------------------------+\n| Parameter name | Type    | Values                                                 |\n+================+=========+========================================================+\n| type           | integer || Select WAVE format                                    |\n|                |         || 0: Microsoft WAV (default),                           |\n|                |         || 1: WAV with WAVEFORMATEX,                             |\n|                |         || 2: RAW PCM,                                           |\n|                |         || 3: S.F. WAVE64.                                       |\n+----------------+---------+--------------------------------------------------------+\n| format         | integer || Select Output Bits per sample                         |\n|                |         || 0: 16 Bit                                             |\n|                |         || 1: 24 Bit                                             |\n|                |         || 2: 32 Bit                                             |\n|                |         || 3: 32 bit float                                       |\n|                |         || Default is same as input.                             |\n+----------------+---------+--------------------------------------------------------+\n| executable     | string  || Executable to use                                     |\n|                |         || Default: \"aften.exe\" (without quotes).                |\n+----------------+---------+--------------------------------------------------------+\n| prefilename    | string  || Parameters that are placed before the output filename |\n|                |         || Default: \"-b 384 -\" (without quotes).                 |\n+----------------+---------+--------------------------------------------------------+\n| postfilename   | string  || Parameters that are placed after the output filename  |\n|                |         || Default: \"\" (without quotes).                         |\n+----------------+---------+--------------------------------------------------------+\n| showoutput     | bool    || Show the output window?                               |\n|                |         || Default: true.                                        |\n+----------------+---------+--------------------------------------------------------+\n| nofilename     | bool    || Encode without output filename, and don't use         |\n|                |         |  postfilename?                                         |\n|                |         || Default: false.                                       |\n+----------------+---------+--------------------------------------------------------+\n\nExamples\n--------\n\n::\n\n    SoundOut(output = \"mp3\", filename=\"c:\\outputFile.mp3\", autoclose = true, \\\n             showprogress=true, mode = 2, cbrrate = 192)\n    # Engages mp3 output module with CBR at 192kbit/sec.\n\nImplementation notes\n--------------------\n\nSoundOut is Multithreaded, and uses one thread for requesting audio from the\nprevious filters, and another thread for encoding. The threads are given a\n\"below normal\" priority.\n\nOnly attempt to run two exports at the same time at your own risk. It is most\nlikely slower and could potentially crash. You can safely export sound while\nyou encode, if your encode does not read audio from AviSynth.\n\n\n+------------+----------------------------------+\n| Changelist |                                  |\n+============+==================================+\n| v2.60      | Initial Release; based on v1.1.1 |\n+------------+----------------------------------+\n\n+-----------------------+---------------------------------------------------+\n| Changelist (SoundOut) |                                                   |\n+=======================+===================================================+\n| v1.1.1                | - Downgraded FLAC to v1.2.0, to avoid backwards   |\n|                       |   incompatible 24 bit files.                      |\n|                       | - Conversion tune-up.                             |\n|                       | - OverWriteFile set to \"No\" was not respected.    |\n|                       | - Client sample requests shown in GUI.            |\n+-----------------------+---------------------------------------------------+\n| v1.1.0                | - Added WavPack output module.                    |\n|                       | - Added Sample type selection to WAV Output.      |\n|                       | - Updated FLAC to v 1.2.1 - 24 bit/sample seems   |\n|                       |   broken, so only 8 & 16 bit are enabled.         |\n|                       | - Fixed bug in FLAC to enable files larger than   |\n|                       |   2GB.                                            |\n|                       | - FLAC now uses the same GUI as other filters.    |\n|                       | - Aften updated.                                  |\n|                       | - Re-enabled Aften multithreading.                |\n|                       | - Faster 3DNOW! float to 24 bit conversion.       |\n+-----------------------+---------------------------------------------------+\n| v1.0.3                | - Vorbis, AC3 and MP3 now checks if file can be   |\n|                       |   created.                                        |\n|                       | - Fixed hang in aften on multiprocessor machines. |\n|                       | - Added wait parameter, how many seconds should   |\n|                       |   SoundOut wait on autoclose.                     |\n|                       | - Avoid lockup if encoder cannot be initialized   |\n|                       |   and set for direct output.                      |\n|                       | - Fixed OverwriteFile was not always being        |\n|                       |   respected.                                      |\n+-----------------------+---------------------------------------------------+\n| v1.0.2                | - Updated libaften to rev534.                     |\n|                       | - Fixed overwriteFile not being recognized in     |\n|                       |   script.                                         |\n|                       | - Fixed crash if mp2 file could not be opened for |\n|                       |   writing.                                        |\n|                       | - Exit blocked, even if filter is (almost)        |\n|                       |   instantly destroyed, if script is set for       |\n|                       |   output.                                         |\n|                       | - AC3 is now reporting the actual samples encoded |\n|                       |   (including padding).                            |\n+-----------------------+---------------------------------------------------+\n| v1.0.1                | - Updated libaften to rev. 512.                   |\n|                       | - Added overwriteFile=\"yes\"/\"no\"/\"ask\".           |\n|                       |   Default is Ask.                                 |\n+-----------------------+---------------------------------------------------+\n| v1.0.0                | - The application will not exit, as long as an    |\n|                       |   encode window is open.                          |\n|                       | - Fixed \"nofilename\" not being recognized in      |\n|                       |   script.                                         |\n|                       | - LFE no longer overridden by registry, when      |\n|                       |   using GUI.                                      |\n+-----------------------+---------------------------------------------------+\n| v0.9.9                | - Added ReplayGain calculation to Analyze.        |\n|                       | - Parent filters are now blocked, or silent       |\n|                       |   samples are returned, if the filter is          |\n|                       |   currently exporting sound.                      |\n|                       | - Video is automatically added, if none is        |\n|                       |   present. (black 32x32 RGB32)                    |\n|                       | - Buttons for export are disabled when output     |\n|                       |   window is open.                                 |\n|                       | - Main window is now minimized when export module |\n|                       |   is selected.                                    |\n|                       | - Fixed Analyze bug on 16 bit samples.            |\n|                       | - Fixed WAVEFORMATEXTENSIBLE channel mapping in   |\n|                       |   Commandline Output.                             |\n|                       | - AC3 output: LFE option disabled when not        |\n|                       |   relevant.                                       |\n|                       | - AC3 output: LFE option named properly.          |\n+-----------------------+---------------------------------------------------+\n| v0.9.8                | - Added Analyze option to calculate average,      |\n|                       |   maximum and RMS levels. Only available through  |\n|                       |   GUI.                                            |\n|                       | - WAVEFORMATEXTENSIBLE in commandline out         |\n|                       |   attempts to set channel maps based on channel   |\n|                       |   number.                                         |\n|                       | - Fixed thread race issue on very fast encoders.  |\n|                       | - Minor GUI tweaks.                               |\n+-----------------------+---------------------------------------------------+\n| v0.9.7                | - Added channelmapping to AC3 output.             |\n|                       | - Added LFE channel indicator switch to AC3       |\n|                       |   output.                                         |\n|                       | - GUI now spawned in a new thread, fixing GUI     |\n|                       |   lockup in foobar2000 and similar.               |\n|                       | - Fixed general thread race issue, where a fast   |\n|                       |   encoder might lead to incomplete output.        |\n|                       | - Fixed WAVE_FORMAT_EXTENSIBLE header without     |\n|                       |   info in CmdLine Output.                         |\n|                       | - Fixed \"Format\" not working on Commandline       |\n|                       |   output.                                         |\n|                       | - Fixed Filename dialog not appearing.            |\n|                       | - Forced final samplereading to be correct.       |\n|                       | - Removed \"private\" option from MP2 GUI and       |\n|                       |   script, as there is no way to set it via        |\n|                       |   twolame.                                        |\n|                       | - Removed DAB Extensions from MP2 GUI, as TwoLame |\n|                       |   reports it as not functioning.                  |\n+-----------------------+---------------------------------------------------+\n| v0.9.6                | - Added complete script customization.            |\n|                       | - Added possibility to set output file from       |\n|                       |   script.                                         |\n|                       | - Added window autoclose option to script.        |\n|                       | - Added option to script to disable progress      |\n|                       |   window.                                         |\n|                       | - GUI creates message handle thread.              |\n|                       | - Settings are now saved to registry if output    |\n|                       |   filter initializes successfully.                |\n|                       | - Updated documentation.                          |\n+-----------------------+---------------------------------------------------+\n| v0.9.5                | - Added Broadcast WAVE out.                       |\n|                       | - Fixed OGG Vorbis support.                       |\n|                       | - Fixed Text fields not being correctly read.     |\n|                       | - Fixed AC3 settings not being restored properly. |\n|                       | - Added: MP2 settings are now saved.              |\n+-----------------------+---------------------------------------------------+\n| v0.9.4                | - Added OGG Vorbis support.                       |\n|                       | - Added: Parameters stored (on save) and read to  |\n|                       |   registry.                                       |\n|                       | - Added: \"No filename needed\" option in           |\n|                       |   commandline output, to disable output filename  |\n|                       |   prompt.                                         |\n|                       | - Fixed collision between libaften and libvorbis. |\n|                       | - Updated libaften to rev 257.                    |\n|                       | - Enabled SSE optimizations in libaften.          |\n|                       | - Hopefully fixed issue with commandline          |\n|                       |   executable filename becoming garbled.           |\n+-----------------------+---------------------------------------------------+\n| v0.9.3                | - Added Commandline piping output.                |\n|                       | - Added MP3 / LAME output.                        |\n|                       | - Fixed AC3 VBR Error sometimes wrongly being     |\n|                       |   displayed.                                      |\n|                       | - Fixed AC3 DRC Setting not being respected.      |\n|                       | - Various GUI bugfixes.                           |\n+-----------------------+---------------------------------------------------+\n| v0.9.2                | - Updated AC3 GUI.                                |\n|                       | - Fixed crash in WAV output.                      |\n|                       | - More stats during conversion.                   |\n+-----------------------+---------------------------------------------------+\n| v0.9.1                | - Added AC3 Output.                               |\n|                       | - Added new parameter handling.                   |\n|                       | - Fixed last block not being encoded.             |\n+-----------------------+---------------------------------------------------+\n\n$Date: 2011/04/29 20:09:50 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/splice.rst",
    "content": "===============================\nAlignedSplice / UnalignedSplice\n===============================\n\n**AlignedSplice** and **UnalignedSplice** join two or more video clips end to\nend. The difference between the filters lies in the way they treat the sound\ntrack.\n\n* **AlignedSplice** cuts off the first sound track or inserts silence as\n  necessary to ensure that the second sound track remains synchronized with the\n  video.\n\n* **UnalignedSplice** simply concatenates the sound tracks without regard to\n  synchronization with the video.\n\nYou should use **AlignedSplice** for most situations.\n\nYou should use **UnalignedSplice** when the soundtracks being joined were\noriginally contiguous—for example, when you're joining files captured with\n`AVI-IO`_. Using **AlignedSplice** in these situations may lead to glitches in\nthe sound.\n\nAviSynth provides ``++`` and ``+`` :doc:`operators <../syntax/syntax_operators>`\nas synonyms for **AlignedSplice** and **UnalignedSplice** respectively.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    AlignedSplice (clip1, clip2 [, ...])\n    UnAlignedSplice (clip1, clip2 [, ...])\n\n.. describe:: clip1, clip2, ...\n\n    Source clips; the :doc:`media properties <../syntax/syntax_clip_properties>`\n    must be compatible, meaning all clips must have:\n\n    #. the same height and width,\n    #. the same :doc:`color format <convert>`,\n    #. the same frame rate, and\n    #. the same audio sample rate, bit depth and number of channels.\n\n    See :doc:`filters with multiple input clips <../filters_mult_input_clips>`\n    for the resulting clip properties.\n\nExamples\n--------\n\nJoin segmented capture files (with UnalignedSplice) to produce a single clip::\n\n    UnalignedSplice(AVISource(\"cap1.avi\"),AVISource(\"cap2.avi\"),AVISource(\"cap3.avi\"))\n    # or:\n    AVISource(\"cap1.avi\") + AVISource(\"cap2.avi\") + AVISource(\"cap3.avi\")\n\nExtract three scenes from a clip and join them together in a new order with\nAlignedSplice::\n\n    AVISource(\"video.avi\")\n    Trim(2000,2500) ++ Trim(3000,3500) ++ Trim(1000,1500)\n\n\n$Date: 2022/09/18 21:28:07 $\n\n.. _AVI-IO:\n    http://www.avi-io.com/\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/ssrc.rst",
    "content": "\nSSRC\n====\n\n**SSRC** (Shibata Sample Rate Converter) is a High quality audio sample rate \nconverter by `Naoki Shibata`_. This filter should result in better audio quality \nthan :doc:`ResampleAudio <resampleaudio>` when converting between 44100↔48000 Hz.\n\n    “44.1kHz sampling rate is used for a CD, and 48kHz is used for a DVD... \n    Converting between these frequencies is hard, because the ratio between \n    these two frequencies is 147:160, which are not small numbers. Accordingly, \n    we need a very long FIR filter in order not to degrade the sound quality \n    during conversion. This program utilizes FFTs to apply the FIR filter in \n    order to reduce the amount of computation.” `[1]`_\n\nUnlike :doc:`ResampleAudio <resampleaudio>`, **SSRC** doesn't work for arbitrary \nsample rate ratios. If it cannot handle resampling between the two sample rates, \nan error is raised.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    SSRC (clip, int samplerate, bool \"fast\")\n\n.. describe:: clip\n\n    Source clip. Supported audio sample types: 32-bit float. Use \n    :doc:`ConvertToFloat <convertaudio>` if necessary.\n\n.. describe:: samplerate\n\n    Target sample rate.\n\n.. describe:: fast\n\n    | Enable faster processing at slightly lower quality. \n    | Set this to *false* if you are doing large-ratio rate conversions (more than \n      a factor 2). \n\n    Default: True\n\n\nExamples\n--------\n\nDownsampling to 44,1 kHz::\n\n    AviSource(\"c:\\file.avi\") # Has 48000 audio\n    SSRC(44100)\n\n\nChangelog\n---------\n\n+------------------+----------------------------------------------------+\n| Version          | Changes                                            |\n+==================+====================================================+\n| AviSynth+ <r1555 || Convert SSRC into a proper plugin (Shibatch.dll). |\n|                  || SSRC no longer automatically converts input clip  |\n|                  |  to Float. (2013/09/15)                            |\n+------------------+----------------------------------------------------+\n| AviSynth 2.5.4   | Initial Release                                    |\n+------------------+----------------------------------------------------+\n\n| Some parts of SSRC are:\n| Copyright © 2001-2003, Peter Pawlowski. All rights reserved.\n\n$Date: 2022/02/13 14:59:42 $\n\n.. _Naoki Shibata:\n    http://shibatch.sourceforge.net/\n.. _[1]:\n    http://shibatch.sourceforge.net/\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/stack.rst",
    "content": "===============================\nStackHorizontal / StackVertical\n===============================\n\n**StackHorizontal** takes two or more video clips and displays them together\nin left-to-right order.\n\n**StackVertical** is similar, working top-to-bottom.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    StackHorizontal (clip1, clip2 [, ...])\n    StackVertical (clip1, clip2 [, ...])\n\n.. describe:: clip1, clip2, ...\n\n    Source clips; all color formats supported.\n\n    * The color formats must be the same for all clips.\n    * **StackHorizontal**: the height must be the same for all clips.\n    * **StackVertical**: the width must be the same for all clips.\n\n    Most properties (soundtrack, frame rate, etc) are taken from the first clip,\n    see :doc:`filters with multiple input clips <../filters_mult_input_clips>`\n    for the resulting :doc:`clip properties <../syntax/syntax_clip_properties>`.\n\n\nExamples\n--------\n\nCompare frames with and without noise reduction::\n\n    StackVertical(last, last.SpatialSoften(2,3,6))\n\n\nShow clips in variables a,b,c,d in a box like this::\n\n    # a b\n    # c d\n    StackVertical(StackHorizontal(a,b),StackHorizontal(c,d))\n\n\n$Date: 2022/04/29 21:28:07 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/subtitle.rst",
    "content": "===============\nSubtitle / Text\n===============\n\nSet of filters to overlay text on a clip:\n\n* `Subtitle`_ adds anti-aliased text to a range of frames. It includes features\n  like alpha blending, font spacing, rotation, etc. Only available on Windows.\n* `Text`_ is a stripped-down version of the `Subtitle`_ filter. It only works\n  with bitmap fonts and the set of features are limited. Available on Windows\n  and other non-Windows OSes.\n\n.. _Subtitle:\n\nSubtitle\n--------\n\nThe ``Subtitle`` filter adds anti-aliased text to a range of frames. All\nparameters after text are optional and can be omitted or specified out of order\nusing the name=value syntax.\n\nThe short form (with all default parameters) is useful when you don't really\ncare what the subtitle looks like as long as you can see it—for example, when\nyou're using :doc:`StackVertical <stack>` and its ilk to display several\nversions of a frame at once, and you want to label them to remember which is which.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    Subtitle (clip, string text, float \"x\", float \"y\", int \"first_frame\",\n              int \"last_frame\", string \"font\", float \"size\", int \"text_color\",\n              int \"halo_color\", int \"align\", int \"spc\", int \"lsp\", float \"font_width\",\n              float \"font_angle\", bool \"interlaced\", string \"font_filename\", bool \"utf8\",\n              bool \"bold\", bool \"italic\", bool \"noaa\")\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n.. describe:: text\n\n    The text to be displayed.\n\n.. describe:: x, y\n\n    Text position. Can be set to -1 to automatically center the text horizontally\n    or vertically, respectively. Negative values of ``x`` and ``y`` not equal to\n    -1 can be used to move subtitles partially off the screen.\n\n    Default values:\n\n    * ``x`` = 8 if align=1,4,7 or none; -1 if align=2,5,8; or width-8 if align=3,6,9\n    * ``y`` = size if align=4,5,6 or none; 0 if align=7,8,9; or height-1 if align=1,2,3\n\n.. describe:: first_frame, last_frame\n\n    The text will be shown starting from frame ``first_frame`` and ending with\n    frame ``last_frame``.\n\n    Default: 0, (inputclip.Framecount-1)\n\n.. describe:: font\n\n    Font name; can be the name of any installed Windows font.\n\n    Default: \"arial\"\n\n.. describe:: size\n\n    Height of the text in pixels, and is rounded to the nearest 0.125 pixel.\n\n    Default: 18\n\n.. describe:: text_color, halo_color\n\n    Colors for font fill and outline respectively.\n\n    These may be any of the `preset colors`_, or specified as hexadecimal\n    $AARRGGBB values, similar to HTML--except that they start with $ instead\n    of # and the 4th octet specifies the alpha transparency. $\\ **00**\\rrggbb\n    is completely opaque, $\\ **FF**\\rrggbb is fully transparent. You can\n    disable the halo by using FF as the alpha value.\n\n    * See :doc:`Colors <../syntax/syntax_colors>` for more information on\n      specifying colors.\n    * For YUV clips, the colors are converted from full range to limited range\n      `Rec.601`_.\n\n    Default: $00FFFF00, $00000000\n\n.. describe:: align\n\n    Set where the text is placed, based on the numeric keypad layout, as follows:\n\n        .. image:: pictures/subtitle-align-chart.png\n\n        .. image:: pictures/subtitle-align-demo.png\n\n    Default: 7, or top-left. If ``x`` and/or ``y`` are given, text is positioned\n    relative to the (``x,y``) location. Note there is no Y-center alignment setting.\n\n.. describe:: spc\n\n    Modify the inter-character spacing. If ``spc`` is less than zero, inter-character\n    spacing is decreased; if greater, the spacing is increased. Default is 0:\n    use Windows' default spacing.\n\n    This is helpful for trying to match typical fonts on the PC to fonts used in\n    film and television credits which are usually wider for the same height or\n    to just fit or fill in a space with a fixed per-character adjustment. See\n    example below.\n\n    For more information, see the Microsoft documentation of the function\n    `SetTextCharacterExtra()`_.\n\n    Default: 0\n\n.. describe:: lsp\n\n    **L**\\ine **S**\\pacing **P**\\arameter; enables *multi-line* text (where \"\\\\n\"\n    enters a line break). If ``lsp`` is less than zero, inter-line spacing is\n    decreased; if greater, the spacing is increased, relative to Windows'\n    default spacing. By default, multi-line text disabled.\n\n    In the unlikely event that you want to output the characters \"\\\\n\" literally\n    in a multi-line text, you can do this by using \"\\\\\\\\n\".\n\n    Since 3.7.4 SubTitle accept real LF (``\\r``) or CR LF (``\\r\\n``) control\n    characters for line break, without the need of specifying ``lsp`` parameter.\n\n    String functions which return an LF separated list such as\n    :doc:`ListAutoloadDirs <../syntax/syntax_plugins>` can be Subtitle'd directly.\n\n.. describe:: font_width\n\n    Set character width in logical units, to the nearest 0.125 unit.\n    Default=0, use Windows' default width. See example below.\n\n    Character width varies, depending on the font face and size, but \"Arial\" at\n    ``size=16`` is about 7 units wide; if ``font_width`` is less than that, (but\n    greater than zero), the text is squeezed, and if it is greater, the text is\n    stretched. Negative numbers are converted to their absolute values.\n\n    For more information, see the Microsoft documentation of the function\n    `CreateFont()`_.\n\n    Default: 0.0\n\n.. describe:: font_angle\n\n    Adjust the baseline angle of text in degrees anti-clockwise to the nearest\n    0.1 degree. Default 0, no rotation.\n\n    Default: 0.0\n\n.. describe:: interlaced\n\n    When enabled, reduces flicker from sharp fine vertical transitions on\n    interlaced displays. It applies a mild vertical blur by increasing the\n    anti-aliasing window to include 0.5 of the pixel weight from the lines\n    above and below.\n\n    Default: false\n\n.. describe:: font_filename\n\n    Allows using non-installed font, by giving the font file name. Once it is\n    loaded, other **Subtitle** instances can use it.\n\n    Default: \"\"\n\n.. describe:: utf8\n\n    Allows drawing text encoded in `UTF-8`_. Can be a bit tricky, since AviSynth\n    does not support utf8 scripts. But when a unicode script containing non-ansi\n    characters is saved as UTF8 without BOM, the text itself can be passed as-is\n    and providing the ``utf8=true`` setting.\n\n    Default: false\n\n.. describe:: bold\n\n    | Using bold letters or not\n    | Default is true, since bold has better visibility.\n\n    Default: true\n\n.. describe:: italic\n\n    | Using italic letters or not\n\n    Default: false\n\n.. describe:: noaa\n\n    | Disables antialiasing when drawing the text.\n    | Setting it true will disable antialiasing.\n      Useful when someone would use ``\"VCR OSD Mono\"`` as-is, without beautifying the outlines,\n      as it as mentioned in https://forum.doom9.org/showthread.php?t=184627\n\n    Default: false\n\n\n.. _Text:\n\nText\n----\n\nThe **Text** filter is a stripped-down version of the `Subtitle`_ filter that\nworks with bitmap fonts. It includes 2 fonts or can load an external `BDF`_ font\nfile.\n\nText treats real LF (``\\n``) control characters for line break, without the need \nof specifying ``lsp`` parameter.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    Text (clip, string text, float \"x\", float \"y\", int \"first_frame\",\n          int \"last_frame\", string \"font\", float \"size\", int \"text_color\",\n          int \"halo_color\", int \"align\", int \"spc\", int \"lsp\", float \"font_width\",\n          float \"font_angle\", bool \"interlaced\", string \"font_filename\", bool \"utf8\",\n          bool \"bold\", bool \"italic\", bool \"noaa\", string \"placement\")\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n.. describe:: text\n\n    The text to be displayed.\n\n.. describe:: x, y, first_frame, last_frame\n\n    Same as Subtitle.\n\n.. describe:: font\n\n    | Font name; can be \"Terminus\" or \"Info_h\" or path to a BDF font file.\n    | \"Info_h\" is fixed to 10x20 in size.\n\n    Default: \"Terminus\"\n\n.. describe:: size\n\n    Only applicable when ``font=\"Terminus\"``; valid sizes are\n    12, 14, 16, 18, 20, 22, 24, 28, 32.\n\n    Default: 18\n\n.. describe:: text_color, halo_color\n\n    Colors for font fill and outline respectively. Works the same as Subtitle,\n    except for the transparency values. There is no transparency for ``text_color``\n    and for ``halo_color`` only the following options are available.\n\n    MSB byte of ``halo_color``:\n\n    * FF : semi-transparent box around text without halo.\n    * FE : semi-transparent box around text and use ordinary color bytes of ``halo_color``.\n    * 00 : use ``halo_color``.\n    * 01 - FD : no halo.\n\n    Default: $00FFFF00, $00000000\n\n.. describe:: align, spc, lsp\n\n    Same as Subtitle; ``spc`` not available.\n\n.. describe:: font_width, font_angle, interlaced\n\n    Not available.\n\n.. describe:: font_filename\n\n    Same as Subtitle except it only accepts BDF fonts.\n\n    Default: \"\"\n\n.. describe:: utf8\n\n    Same as Subtitle. Much more international unicode characters (1354), use\n    ``utf8=true`` under Windows.\n\n    Default: false\n\n.. describe:: bold\n\n    Only applicable when ``font=\"Terminus\"``; set to true for bold text.\n\n    Default: false\n\n.. describe:: italic, noaa\n\n    These parameters have no effect in Text. They are provided only to match the parameter list \n    with SubTitle, because on non-Windows systems \"Subtitle\" is aliased to \"Text\", so\n    each Subtitle parameter must exist in \"Text\" as well.\n\n.. describe:: placement\n\n    Chroma location hint. Used in subsampled YUV formats, otherwise ignored.\n    Valid values for \"placement\" are the same as in ``ChromaInPlacement`` and \n    ``ChromaOutPlacement`` in the :doc:`Convert <convert>` functions.\n    \n    The placement can be one of these strings: \n\n    - ``\"MPEG2\"`` (synonyms: ``\"left\"``)\n      Subsampling used in MPEG-2 4:2:x and most other formats. Chroma samples are located on the left pixel column of the group (default).\n    - ``\"MPEG1\"`` (synonyms: ``\"jpeg\"``, ``\"center\"``)\n      Subsampling used in MPEG-1 4:2:0. Chroma samples are located on the center of each group of 4 pixels.\n    - ``\"DV\"``\n      Like MPEG-2, but U and V channels are co-sited vertically: V on the top row, and U on the bottom row. For 4:1:1, chroma is located on the leftmost column.\n    - ``\"top_left\"``\n      Subsampling used in UHD 4:2:0. Chroma samples are located on the top left pixel column of the group.\n    - ``bottom_left`` 4:2:0 only\n    - ``bottom``   4:2:0 only \n\n    Meaningful values: \"center\", \"left\", \"auto\" at the moment, only ``\"center\"`` and ``\"left\"`` \n    is implemented. \n    \n    Default value is\n    \n    - read from ``\"_ChromaLocation\"`` frame property, otherwise ``\"left\"``\n    - override or set from ``\"placement\"`` parameter if parameter is other than ``\"auto\"``\n    - if ``\"auto\"`` + have frame property -> use frame property\n    - if ``\"auto\"`` + no frame property -> use ``\"left\"``\n    - no frame property and no parameter -> use ``\"left\"``\n\nExamples\n--------\n\n**Center text** ::\n\n    AviSource(\"clip.avi\")\n    Subtitle(\"Hello world!\", align=5)\n\n**Some text in the upper right corner of the clip with specified font, size and\ncolor red** ::\n\n    AviSource(\"clip.avi\")\n    Subtitle(\"Hello world!\", font=\"georgia\", size=24, text_color=$ff0000, align=9)\n\n**Prints text on multiple lines without any text halo border.** ::\n\n    BlankClip()\n    Subtitle( \\\n      \"Some text on line 1\\\\nMore text on line 1\\n\" + \\\n      \"Some text on line 2\", \\\n             lsp=10, halo_color=$ff000000)\n\nIt results in: ::\n\n    Some text on line 1\\nMore text on line 1\n    Some text on line 2\n\n**Prints text on multiple lines, direct control characters** ::\n\n    BlankClip()\n    Subtitle( \\\n      e\"Some text on line 1\\n\" + \\\n      \"Some text on line 2\", \\\n             , halo_color=$ff000000)\n    #note: using e-prefixed escape sequence aware string literal\n\n**Use String() to display values of functions.** ::\n\n    AviSource(\"clip.avi\")\n    Subtitle(\"Width=\" + String(Width()))\n\n**Using spc and font_width arguments** ::\n\n    ColorBars().KillAudio()\n    Subtitle(\"ROYGBIV\", x=-1, y=100, spc=-10, font_width=6)\n    Subtitle(\"ROYGBIV\", x=-1, y=150, spc=0,  font_width=0) ## width=default\n    Subtitle(\"ROYGBIV\", x=-1, y=200, spc=10, font_width=10)\n    Subtitle(\"ROYGBIV\", x=-1, y=250, spc=20, font_width=20)\n\n.. _Subtitle-animated-demo:\n\n**Animated parameter demonstration** ::\n\n    ColorbarsHD(width=640, height=360)\n    AmplifyDB(-30)\n    Tweak(cont=0.5, sat=0.5)\n    ConvertToRGB32(matrix=\"PC.709\")\n    Trim(0, 255)\n    s1 = \"THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.\"\n    s3 = \"THE QUICK BROWN FOX \\nJUMPS OVER \\nTHE LAZY DOG.\"\n    minvalue = -32.0\n    maxvalue = +128.0\n    B = BlankClip(Last, length=15)\n    return Animate(Last, 0, 255, \"anim_aln\", s3, 1.000000, s3, 9.999999)\n       \\ + B\n       \\ + Animate(Last, 0, 255, \"anim_spc\", s1, minvalue, s1, maxvalue)\n       \\ + B\n       \\ + Animate(Last, 0, 255, \"anim_wid\", s1, minvalue, s1, maxvalue)\n       \\ + B\n       \\ + Animate(Last, 0, 255, \"anim_lsp\", s3, minvalue, s3, maxvalue)\n       \\ + B\n       \\ + Animate(Last, 0, 255, \"anim_ang\", s1, -15.0000, s1, 375.0000).FadeOut(15)\n    function anim_aln(clip C, string s, float f) {\n        return C.Subtitle(s, align=Floor(f), lsp=0)\n        \\       .Subtitle(\"align = \"+String(Floor(f)),\n        \\                 x=-1, y=C.Height-42, size=32, text_color=$c0c0c0)\n    }\n    function anim_spc(clip C, string s, float f) {\n        return C.Subtitle(s, align=8, spc=0, text_color=$c0c0c0)\n        \\       .Subtitle(s, align=5, spc=Round(f))\n        \\       .Subtitle(\"spc = \"+String(Round(f)),\n        \\                 align=2, size=32, text_color=$c0c0c0)\n    }\n    function anim_wid(clip C, string s, float f) {\n        return C.Subtitle(s, align=8, font_width=0, text_color=$c0c0c0)\n        \\       .Subtitle(s, align=5, font_width=Round(f))\n        \\       .Subtitle(\"font_width = \"+String(Round(f)),\n        \\                 align=2, size=32, text_color=$c0c0c0)\n    }\n    function anim_lsp(clip C, string s, float f) {\n        return C.Subtitle(s, align=8, lsp=0, text_color=$c0c0c0)\n        \\       .Subtitle(s, align=5, lsp=Round(f))\n        \\       .Subtitle(\"lsp = \"+String(Round(f)),\n        \\                 align=2, size=32, text_color=$c0c0c0)\n    }\n    function anim_ang(clip C, string s, float f) {\n        return C.Subtitle(s, align=5, font_angle=f)\n        \\       .Subtitle(\"font_angle = \"+String(f, \"%03.3f\"),\n        \\                 align=2, size=32, text_color=$c0c0c0)\n    }\n\n**UTF8 text indirectly** ::\n\n    Title=\"Cherry blossom \"+CHR($E6)+CHR($A1)+CHR($9C)+CHR($E3)+CHR($81)+CHR($AE)+CHR($E8)+CHR($8A)+CHR($B1)\n    Subtitle(Title, utf8=true)\n\n**Using the Text filter** ::\n\n    Text(\"Terminus\", size=20, align=4)\n    Text(\"Info_h\", font=\"Info_h\", align=5)\n    Text(\"Load bdf font\", font=\"spleen-12x24.bdf\", align=6)\n\n\nChangelog\n---------\n\n+-----------------+--------------------------------------------------------------------------+\n| Version         | Changes                                                                  |\n+=================+==========================================================================+\n| 3.7.4           | Feature: SubTitle to accept real LF (``\\r``) or CR LF (``\\r\\n``) control |\n|                 | characters for line break.                                               |\n+-----------------+--------------------------------------------------------------------------+\n| AviSynth+ 3.7.3 || Fix: \"Text\" filter negative x or y coordinates (e.g. 0 instead of -1)   |\n|                 || Fix: \"Text\" filter would omit last character when x<0                   |\n|                 || \"Text\" Fix: ``halo_color`` needs only MSB=$FF and not the exact         |\n|                 |   $FF000000 constant for fade                                            |\n|                 || \"Text\" ``halo_color`` allows to have both halo and shaded background    |\n|                 || \"Text\" much nicer rendering of subsampled formats (#308)                |\n|                 || Fix: \"Subtitle\" and \"Text\" filter to respect the explicitely (#293)     |\n|                 |  given coorditanes for y=-1 or x=-1, instead of applying                 |\n|                 |  vertical/horizontal center alignment.                                   |\n|                 || Fix: \"Text\" to throw proper error message if the specified font (#293)  |\n|                 |  name (e.g. Arial) is not found among internal bitmap fonts.             |\n|                 || \"Text\": add \"italic\" and \"noaa\" (unused) parameters                     |\n|                 || \"SubTitle\": add \"bold\", \"italic\" and \"noaa\" parameters                  |\n|                 || \"Text\": add \"placement\" parameter                                       |\n+-----------------+--------------------------------------------------------------------------+\n| AviSynth+ 3.7.1 | Fix: \"Text\" filter would crash when y coord is odd and format has        |\n|                 | vertical subsampling.                                                    |\n+-----------------+--------------------------------------------------------------------------+\n| AviSynth+ 3.6.0 | New \"Text\" filter.                                                       |\n+-----------------+--------------------------------------------------------------------------+\n| AviSynth+ r2632 | Fix: Subtitle for Planar RGB/RGBA: wrong text colors.                    |\n+-----------------+--------------------------------------------------------------------------+\n| AviSynth+ r2487 | Subtitle: new parameters \"font_filename\" and \"utf8\".                     |\n+-----------------+--------------------------------------------------------------------------+\n| AviSynth  2.60  | Position (x,y) can be float (previously int) (with 0.125 pixel           |\n|                 | granularity).                                                            |\n+-----------------+--------------------------------------------------------------------------+\n| AviSynth  2.58  | Added ``font_width``, ``font_angle``, ``interlaced`` parameters and      |\n|                 | alpha color blending.                                                    |\n+-----------------+--------------------------------------------------------------------------+\n| AviSynth  2.57  | Added multi-line text and line spacing parameter.                        |\n+-----------------+--------------------------------------------------------------------------+\n| AviSynth  2.07  || Added ``align`` and ``spc`` parameters.                                 |\n|                 || Setting y=-1 calculates vertical center (alignment unaffected).         |\n|                 || Default x and y values dependent on alignment (previously x=8, y=size). |\n+-----------------+--------------------------------------------------------------------------+\n| AviSynth  1.00  | Setting x=-1 uses horizontal center and center alignment                 |\n|                 | (undocumented prior to v2.07)                                            |\n+-----------------+--------------------------------------------------------------------------+\n\n$Date: 2025/03/23 22:30:00 $\n\n.. _BDF:\n    https://en.wikipedia.org/wiki/Glyph_Bitmap_Distribution_Format\n.. _SetTextCharacterExtra():\n    https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-settextcharacterextra\n.. _CreateFont():\n    https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createfonta\n.. _preset colors:\n    http://avisynth.nl/index.php/Preset_colors\n.. _Rec.601:\n    https://en.wikipedia.org/wiki/Rec._601\n.. _UTF-8:\n    https://en.wikipedia.org/wiki/UTF-8\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/subtract.rst",
    "content": "\nSubtract\n========\n\n``Subtract`` (clip1, clip2)\n\n``Subtract`` produces an output clip in which every pixel is set according to\nthe difference between the corresponding pixels in *clip1* and *clip2*. More\nspecifically, it sets each pixel to (50% gray) + (*clip1* pixel) - (*clip2*\npixel). You can use :doc:`Levels <levels>` afterwards if you want to increase the\ncontrast.\n\nAlso see :ref:`here <multiclip>` for the resulting clip properties.\n\n**Examples:**\n\n::\n\n    # Make the differences between clip1 and clip2 blatantly obvious\n    Subtract(clip1, clip2).Levels(127, 1, 129, 0, 255)\n\nIf you want to see the deltas between adjacent frames in a single clip, you\ncan do it like this:\n\n::\n\n    Subtract(clip.Trim(1,0), clip)\n\n**About offset of luma range:**\n\nFor YUV formats the valid Y range is from 16 to 235 inclusive and subtract\ntakes this into account. This means that the following script\n\n::\n\n    Subtract(any_clip, any_clip)\n\nwill result in a grey clip with luma = 126. For those that require a subtract\nfunction for pc_range YUV data use :doc:`Overlay <overlay>`:\n\n::\n\n    #Overlay(any_clip, any_clip, mode=\"Difference\", pc_range=true)\n    # grey clip with luma = 128\n    Overlay(clip1, clip2, mode=\"Difference\", pc_range=true)\n\n$Date: 2006/09/27 18:41:25 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/supereq.rst",
    "content": "\nSuperEQ\n=======\n\n**Equalization** (British: equalisation, **EQ** for short) is the process of \nadjusting the balance between frequency components within an electronic signal. \nThe most well known use of equalization is in sound recording and reproduction \nbut there are many other applications in electronics and telecommunications. \nThe circuit or equipment used to achieve equalization is called an equalizer. \nThese devices boost or cut the energy of specific frequency bands. \n(source: wikipedia: `Equalization`_)\n\n**SuperEQ** (Shibatch Super Equalizer) is a `graphic equalizer`_, originally \ncreated as a plugin for Winamp by `Naoki Shibata`_. **SuperEQ** uses 16383th \norder `FIR`_ filters using `FFT`_. Its equalization is very precise. Note that \nunlike traditional equalizers, there is very little `roll-off`_ or overlap \nbetween the bands.\n\nSyntax and Parameters\n----------------------\n\n::\n\n    SuperEQ (clip, string filename)\n    SuperEQ (clip, int band1 [, int band2, ..., int band18])\n\n.. describe:: clip\n\n    Source clip. Supported audio sample types: 32-bit float. Use \n    :doc:`ConvertToFloat <convertaudio>` if necessary.\n\n.. describe:: filename\n\n    Set EQ bands from a preset file (see `Preset Files`_ below). \n\n.. describe:: band1, ..., band18\n\n    | Set EQ bands within your script (see `Band Gain Arguments`_ below). \n    | The 18 bands cover the following frequency ranges:\n\n    .. table::\n        :widths: 30 35 35\n        \n        ========= ========== =========== \n        Band #    f (low)    f (high)   \n        ========= ========== =========== \n        1         0 Hz       65 Hz      \n        2         65 Hz      93 Hz      \n        3         93 Hz      131 Hz     \n        4         131 Hz     185 Hz     \n        5         185 Hz     262 Hz     \n        6         262 Hz     370 Hz     \n        7         370 Hz     523 Hz     \n        8         523 Hz     740 Hz     \n        9         740 Hz     1047 Hz    \n        10        1047 Hz    1480 Hz    \n        11        1480 Hz    2093 Hz    \n        12        2093 Hz    2960 Hz    \n        13        2960 Hz    4186 Hz    \n        14        4186 Hz    5920 Hz    \n        15        5920 Hz    8372 Hz    \n        16        8372 Hz    11840 Hz   \n        17        11840 Hz   16744 Hz   \n        18        16744 Hz   22000±Hz   \n        ========= ========== =========== \n    \n    | Frequency ranges apply to both *.feq* preset files and the ``band`` arguments.\n    | (Adapted from  AviSynthPlus/plugins/Shibatch/`supereq.h`_ ) \n\n\nExamples\n--------\n\nBelow are examples and additional information on how to use ``preset`` files \nand the ``band`` parameters.\n\n\nPreset Files\n^^^^^^^^^^^^\n\n**SuperEQ** can accept a `foobar2k`_ equalizer Preset (.feq) file. Foobar's \nequalizer can be found in the `DSPManager`_, and presets are adjusted and saved \nfrom there as well.\n\n    A Preset file is a text file with a positive or negative integer on each \n    line. Nothing else is allowed on the line, except white space. Empty (blank) \n    lines are ignored. Each line sets the gain in decibels for a frequency band. \n    All text after the first 18 non-empty lines is ignored, allowing you to add \n    comments to the file.\n\nPreset files can be found in your \\\\AviSynth+\\\\Examples folder or `here`_, or \nmay be found by searching the Web for \"foobar2000 presets.\"\n\n**Example 1**: *Using a Preset file*::\n\n    SuperEq(\"C:\\Equalizer Presets\\Loudness.feq\")\n\nContents of Loudness.feq::\n\n    4\n    4\n    4\n    2\n    -2\n    -2\n    -2\n    -2\n    -2\n    -2\n    -2\n    -4\n    -10\n    -7\n    0\n    3\n    4\n    4\n\n    *comment* \n    (text after the first 18 non-empty lines will be ignored)\n\nTo give a very rough indication of the frequency response of the above example, \nhere is a screenshot of an `Audacity`_ spectrum analysis of processed \n`white noise`_ (which should be approximately flat without equalization, \nallowing for low-frequency variability).\n\n.. image:: pictures/supereq-loudness-586x512.png\n\n\nBand Gain Arguments\n^^^^^^^^^^^^^^^^^^^\n\n``Band`` gain arguments allow all 18 bands to be set within your script, instead \nof requiring a *preset file*. The values are specified in decibels (in integer \nformat).\n\n**Example 2**: *Boost midrange (speech) using* ``band`` *arguments*::\n\n    ConvertAudioToFloat()\n    SuperEQ(\n    \\   0,  [*     0 -    65  *]\n    \\   0,  [*    65 -    93  *]\n    \\   0,  [*    93 -   131  *]\n    \\   0,  [*   131 -   185  *]\n    \\   0,  [*   185 -   262  *]\n    \\   0,  [*   262 -   370  *]\n    \\   0,  [*   370 -   523  *]\n    \\   5,  [*   523 -   740  *]\n    \\  10,  [*   740 -  1047  *]\n    \\  10,  [*  1047 -  1480  *]\n    \\  10,  [*  1480 -  2093  *]\n    \\   5,  [*  2093 -  2960  *]\n    \\   0,  [*  2960 -  4186  *]\n    \\   0,  [*  4186 -  5920  *]\n    \\   0,  [*  5920 -  8372  *]\n    \\   0,  [*  8372 - 11840  *]\n    \\   0,  [* 11840 - 16744  *]\n    \\   0   [* 16744 - 22000± *]\n    \\ )\n    Normalize() ## avoid possible overload\n    ConvertAudioTo16bit() \n\nTo give a very rough indication of the frequency response of the above example, \nhere is a screenshot of an `Audacity`_ spectrum analysis of processed \n`white noise`_ (which should be approximately flat without equalization, \nallowing for low-frequency variability).\n\n.. image:: pictures/supereq-midboost-586x510.png\n\nChangelog\n---------\n\n+------------------+------------------------------------------------------------------------+\n| Version          | Changes                                                                |\n+==================+========================================================================+\n| AviSynth+ <r1555 || Convert SuperEQ into a proper plugin (Shibatch.dll).                  |\n|                  || SuperEQ no longer automatically converts input clip to Float.         |\n|                  |  (2013/09/15)                                                          |\n+------------------+------------------------------------------------------------------------+\n| AviSynth 2.6.1   | SuperEQ gain arguments can only be int, enforce it.                    |\n+------------------+------------------------------------------------------------------------+\n| AviSynth 2.6.0   | Added custom band setting to allow all 16 bands to be set from script. |\n+------------------+------------------------------------------------------------------------+\n| AviSynth 2.5.4   | Initial Release                                                        |\n+------------------+------------------------------------------------------------------------+\n\n| Some parts of SuperEQ are:\n| Copyright © Naoki Shibata\n\n| Other parts are:\n| Copyright © 2001-2003, Peter Pawlowski All rights reserved.\n\n$Date: 2022/02/12 15:10:22 $\n\n.. _Equalization:\n    https://en.wikipedia.org/wiki/Equalization_%28audio%29\n.. _graphic equalizer:\n    https://en.wikipedia.org/wiki/Equalization_%28audio%29#Graphic_equalizer\n.. _Naoki Shibata:\n    http://shibatch.sourceforge.net/\n.. _FIR:\n    https://en.wikipedia.org/wiki/Finite_impulse_response\n.. _FFT:\n    https://en.wikipedia.org/wiki/Fast_Fourier_transform\n.. _roll-off:\n    https://en.wikipedia.org/wiki/Roll-off\n.. _supereq.h:\n    https://github.com/AviSynth/AviSynthPlus/blob/master/plugins/Shibatch/supereq.h\n.. _foobar2k:\n    http://www.foobar2000.org\n.. _DSPManager:\n    https://wiki.hydrogenaud.io/index.php?title=Foobar2000:Preferences:Playback:DSP_Manager\n.. _here:\n    https://github.com/AviSynth/AviSynthPlus/tree/master/distrib/Examples/Equalizer%20Presets\n.. _here2:\n    https://web.archive.org/web/20040405181005if_/http://www.beingalink.de:80/files/Equalizer%20Presets.rar\n.. _Audacity:\n    https://www.audacityteam.org/\n.. _white noise:\n    https://en.wikipedia.org/wiki/White_noise\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/swap.rst",
    "content": "============\nSwap Filters\n============\n\nSet of filters to combine, extract and manipulate the order of channels in\nYUV(A) clips:\n\n* `SwapUV`_ swaps the order of the U/V channels.\n* `UToY / VToY`_ copies the U/V channel onto the Y (luma) channel and keeps the\n  same color format.\n* `UToY8 / VToY8`_ extract the U/V chroma channel to a Y-only greyscale clip.\n* `YToUV`_ combines individual YUV(A) planes into a new YUV(A) clip.\n\nThese filters provide similar functionality to the :doc:`CombinePlanes <combineplanes>`,\n:doc:`Extract <extract>` and :doc:`ShowU/V <showalpha>` filters.\n\n.. _SwapUV:\n\nSwapUV\n------\n\nSwaps the U and V (chroma) channels. Corrects certain decoding errors – faces\nblue instead of red, etc.\n\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    SwapUV (clip)\n\n.. describe:: clip\n\n    Source clip. All YUV(A) color formats supported.\n\n.. _UToY:\n.. _VToY:\n\nUToY / VToY\n-----------\n\n**UToY** and **VToY** copy the U or V chroma plane to the Y luma plane and\nkeeps the same color format as the source clip. All color (chroma) information\nis removed and set to neutral (greyscale). Depending on the color format, the\nimage resolution can be changed – i.e.,\n\n* with a YUV444 source, the output clip will be the same width and height as\n  input clip, but\n* with a YUV420 source, the output clip will be half the input clip's width and\n  height.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    UToY (clip)\n    VToY (clip)\n\n.. describe:: clip\n\n    Source clip; all YUV(A) color formats supported.\n\n.. _UToY8:\n.. _VToY8:\n\nUToY8 / VToY8\n-------------\n\n**UToY8** and **VToY8** extract the U or V chroma channel to a Y-only greyscale\nclip. Despite the names, all bit depths are supported. Resulting clip will be Y8,\nY10 etc. as appropriate.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    UToY8 (clip)\n    VToY8 (clip)\n\n.. describe:: clip\n\n    Source clip; all YUV(A) color formats supported.\n\n.. _YToUV:\n\nYToUV\n-----\n\n**YToUV** combines up to 4 independent clips to create a new YUV(A) clip.\nThe Y channel of each of the supplied clips are then copied onto the respective\nchannel of the output clip. Note that all of the parameters are unnamed, however,\nonly the first two clips are mandatory. Only Y or YUV(A) color formats are\naccepted.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    YToUV (clip clipU, clip clipV, clip clipY, clip clipA)\n\n.. describe:: clipU, clipV\n\n    | Source clips; dimensions of both clips must be identical.\n    | The first clip is used for the U channel and the second clip for the V\n      channel.\n\n    | ``clipU`` determines the color format of the output clip unless ``clipY``\n      is defined.\n\n.. describe:: clipY\n\n    Source clip; If ``clipY`` is given, the Y channel is copied onto the Y\n    channel of the output clip. The dimensions of this clip determines the\n    color format of the output clip, for example:\n\n    * If the width and height of ``clipY`` are the same as the U/V channels, the\n      output clip will be YUV444.\n    * If the width and height of ``clipY`` are double the size of the U/V\n      channels, the output clip will be YUV420.\n    * Due to `chroma subsampling`_ restrictions, some dimensions are not\n      compatible with YUV420 and YUV422 color formats.\n\n    If ``clipY`` is not given, the Y channel of the output clip will be set to\n    grey (0x7e).\n\n.. describe:: clipA\n\n    Source clip; if ``clipA`` is given, the Y channel is copied onto the A\n    channel of the output clip. Dimensions must be identical to ``clipY``.\n\n\nExamples\n--------\n\nBlur the U and V chroma channels different amounts::\n\n    video = ColorBars(512, 512, pixel_type=\"YUV420P8\")\n    u = UToY8(video).Blur(1.5)\n    v = VToY8(video).Blur(0.5)\n    YtoUV(u, v, video)\n\nShow *U* and V channels stacked side by side for illustration purposes.\n\n* Note that with a YUV420 source (like the image below), the *U* and *V* images\n  will be half the size of the original.\n* In the *U* and *V* images, grey will be \"neutral\" (for example, 128 for 8-bit)\n  and saturated colors will appear brighter or darker.\n\n .. list-table::\n\n    * - .. figure:: pictures/swap-peppers.jpg\n\n           *swap-peppers.jpg*\n\n    * - .. figure:: pictures/swap-peppers-uv.jpg\n\n        .. code::\n\n            src   = FFImageSource(\"swap-peppers.jpg\")\n            srcU  = src.UToY().Subtitle(\"UtoY\", align=2)\n            srcV  = src.VToY().Subtitle(\"VtoY\", align=2)\n            srcUV = StackHorizontal(srcU, srcV)\n\n            StackVertical(src, srcUV)\n\n\nChangelog\n---------\n\n.. table::\n    :widths: auto\n\n    +-----------------+----------------------------------------------+\n    | Version         | Changes                                      |\n    +=================+==============================================+\n    | AviSynth+ r2487 || Added parameter ``clipA`` to YToUV.         |\n    |                 || Added YUVA support to SwapUV.               |\n    |                 || Added support for 10-16 bits and float.     |\n    +-----------------+----------------------------------------------+\n    | AviSynth 2.6.0  || Added UToY8 and VToY8.                      |\n    |                 || Added support for Y8, YV411, YV16, YV24.    |\n    +-----------------+----------------------------------------------+\n    | AviSynth 2.5.3  | Added support for YUY2.                      |\n    +-----------------+----------------------------------------------+\n    | AviSynth 2.5.1  | Added parameter ``clipY`` to YToUV.          |\n    +-----------------+----------------------------------------------+\n    | AviSynth 2.5.0  | Added UToY, VToY, YToUV.                     |\n    +-----------------+----------------------------------------------+\n\n$Date: 2022/09/17 14:12:41 $\n\n.. _chroma subsampling:\n    https://en.wikipedia.org/wiki/Chroma_subsampling\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/swapfields.rst",
    "content": "==========\nSwapFields\n==========\n\nThe **SwapFields** filter swaps image line 0 with line 1, line 2 with line 3,\nand so on, thus effectively swapping the two fields in an interlaced frame.\nIt's the same as :ref:`SeparateFields() <SeparateFields>`.\\\n:ref:`ComplementParity() <ComplementParity>`.\\ :ref:`Weave() <weave>` (and it's\nimplemented that way).\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    SwapFields (clip)\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n\n$Date: 2022/03/17 22:07:09 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/tcpdeliver.rst",
    "content": "==========\nTCPDeliver\n==========\n\n**TCPDeliver** includes the `TCPServer`_ and `TCPSource`_ filters that enable\nyou to send and receive clips over your network. You can connect several clients\nto the same machine.\n\n.. note::\n\n    AviSynth+ does not include the TCPDeliver plugin in the installation.\n    Download the `updated TCPDeliver`_, which supports all planar RGB(A) and \\\n    YUV(A) color formats.\n\n\nTCPServer\n---------\n\n**TCPServer** spawns a server thread on the current machine running on the\nspecified port. You will get output in the application you open your script in,\nbut the server will only be running as long as the application (VDub for instance)\nis open.\n\nExample::\n\n    ColorBars(512, 256)\n    TCPServer()\n\nThis will start a server.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    TCPServer (clip, int \"port\")\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n.. describe:: port\n\n    Port default is 22050.\n\n\nTCPSource\n---------\n\n**TCPSource** connects to the machine with the given address (IP-number for\ninstance) to a server running on the given port.\n\nExample::\n\n    TCPSource(\"127.0.0.1\")\n    Info()\n\nThis will connect to the local machine, if a server is running. \"127.0.0.1\" is\nthe localhost, or \"local loopback\".\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    TCPSource (string hostname, int \"port\", string \"compression\")\n\n.. describe:: hostname\n\n    ``hostname`` can be a computer name or an IP address.\n\n.. describe:: port\n\n    Port default is 22050.\n\n.. describe:: compression\n\n    Choose the compression used for the video:\n\n    +------------------+----------------------------------------------------------------------------+\n    | Compression Type | Description                                                                |\n    +==================+============================================================================+\n    | None             | Use no compression. Fastest option - video will not be compressed before   |\n    |                  | being sent over the network.                                               |\n    +------------------+----------------------------------------------------------------------------+\n    | LZO              | Use `LZO`_ dictionary compression. Fairly fast, but only compresses well   |\n    |                  | on artificial sources, like cartoons and anime with very uniform surfaces. |\n    +------------------+----------------------------------------------------------------------------+\n    | Huffman          | Uses a fairly slow Huffman routine by `Marcus Geelnard`_. Compresses       |\n    |                  | natural video better than LZO.                                             |\n    +------------------+----------------------------------------------------------------------------+\n    | GZip             | Uses a `Gzip`_ Huffman only compression. Works much like Huffman           |\n    |                  | setting, but seems faster.                                                 |\n    +------------------+----------------------------------------------------------------------------+\n    | RLE              | RLE (`Run Length Encoding`_) is the simplest possible lossless compression |\n    |                  | method by `Marcus Geelnard`_. The compression is particularly well suited  |\n    |                  | for palette-based bitmapped images.                                        |\n    +------------------+----------------------------------------------------------------------------+\n\n    If no compression is given, GZip is currently used by default. Interlaced\n    material compresses worse than non-interlaced due to downwards delta-encoding.\n    If network speed is a problem you might want to use :doc:`SeparateFields <separatefields>`.\n\n\nExamples\n--------\n\nYou can use this to run each/some filters on different PC's. For example::\n\n    #Clustermember 1:\n    AVISource()\n    Deinterlacer()\n    TCPServer()\n\n    # Clustermember 2:\n    TCPSource()\n    Sharpener()\n    TCPServer()\n\n    # Clustermember 3:\n    TCPSource()\n    # client app -> video codec -> final file\n\nSee the Doom9 thread: \"`Can't get TCPServer() and TCPSource() to work`_\" for\nmore information.\n\n\nUsability Notes\n---------------\n\nOnce you have added a TCPServer, you cannot add more filters to the chain, or\nuse the output from the filter. The server runs in a separate thread, but\nsince AviSynth isn't completely thread-safe you cannot reliably run multiple\nservers. This should **not** be used:\n\n::\n\n    AviSource(\"avi.avi\")\n    TCPServer(1001)\n    TCPServer(1002) # This is NOT a good idea\n\nSo the basic rule is **never more than one TCPServer per script**.\n\nUsing commands after TCPServer is also a bad idea:\n\n::\n\n    AviSource(\"avi.avi\")\n    TCPServer(1001)\n    AviSource(\"avi2.avi\") # Do not do this, this will disable the server.\n\nAviSynth detects that the output of TCPServer isn't used, so it kills the\nServer filter. **TCPServer should always be the last filter.**\n\n\nChangelog\n---------\n\nTCPDeliver is based from the AviSynth 2.6 source.\n\n+---------+-------------------------------------------------------------------+\n| Version | Changes                                                           |\n+=========+===================================================================+\n| v0.2    || Support for YUVA/PlanarRGBA colorspaces;                         |\n|         || HBD formats should be handled better if compression is involved; |\n|         || Dropped old garbage from source code;                            |\n|         || No need in the old VS runtime.                                   |\n+---------+-------------------------------------------------------------------+\n| v0.1    | Initial release.                                                  |\n+---------+-------------------------------------------------------------------+\n\n$Date: 2022/03/26 14:51:17 $\n\n.. _updated TCPDeliver:\n    https://github.com/DJATOMs-archive/TCPDeliver/releases\n.. _LZO:\n    http://www.oberhumer.com/opensource/lzo/\n.. _Marcus Geelnard:\n    https://web.archive.org/web/20181025055443/http://bcl.comli.eu/\n.. _Gzip:\n    http://www.gzip.org/\n.. _Run Length Encoding:\n    https://en.wikipedia.org/wiki/Run-length_encoding\n.. _Can't get TCPServer() and TCPSource() to work:\n    https://forum.doom9.org/showthread.php?t=174478\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/timestretch.rst",
    "content": "===========\nTimeStretch\n===========\n\n**TimeStretch** allows changing the sound tempo, `pitch`_ and playback rate\nparameters independently from each other, i.e.:\n\n* ``tempo`` adjusts speed while maintaining the original pitch.\n* ``pitch`` adjusts speed while maintaining the original tempo.\n* ``rate`` adjusts playback rate that affects both tempo and pitch at the same time.\n\nYou can use these parameters in any combination – for example, 104% ``tempo``\nwith 95% ``pitch``.\n\nSyntax and Parameters\n---------------------\n\n::\n\n    TimeStretch (clip, float \"tempo\", float \"rate\", float \"pitch\",\n                 int \"sequence\", int \"seekwindow\", int \"overlap\", bool \"quickseek\", int \"aa\")\n\n    TimeStretch (clip, int \"tempo_n\", int \"tempo_d\", int \"rate_n\", int \"rate_d\", int \"pitch_n\", int \"pitch_d\",\n                 int \"sequence\", int \"seekwindow\", int \"overlap\", bool \"quickseek\", int \"aa\")\n\n.. describe:: clip\n\n    Source clip; only 32-bit `float`_ audio is supported. Use\n    :doc:`ConvertToFloat <convertaudio>` if necessary.\n\n.. _TimeStretch-percentage-float:\n\n.. rubric:: Tempo, Rate and Pitch\n\n.. describe:: tempo\n\n    | Changes speed while maintaining the original `pitch`_.\n    | If ``tempo=200``, the audio will play twice (200%) as fast; if ``tempo=50``,\n      the audio will play half (50%) as fast.\n    | The effect is also known as `time-stretching`_.\n\n    Default: 100.0\n\n.. describe:: rate\n\n    | Changes speed while allowing `pitch`_ to rise or fall, like the traditional\n      analog `vari-speed`_ effect.\n    | If ``rate=200``, the audio will play twice (200%) as fast; if ``rate=50``,\n      the audio will play half (50%) as fast.\n\n    | Rate control is implemented purely by sample rate transposing.\n    | If ``rate`` is adjusted by itself, no `time-stretching or pitch-shifting`_\n      is performed, and the :ref:`Advanced Parameters <timestretch-advanced>`\n      will have no effect.\n\n    Default: 100.0\n\n.. describe:: pitch\n\n    | Changes `pitch`_ while maintaining the original speed (within a small\n      tolerance–see `Notes`_ below).\n    | If ``pitch=200``, the audio will sound an `octave`_ higher; if ``pitch=50``,\n      the audio will sound an octave lower.\n    | The effect is also known as `pitch-shifting`_.\n\n    Default: 100.0\n\n``tempo``, ``rate`` and ``pitch`` can all be adjusted independently, in which\ncase their effects are added together. See section `3.3. About algorithms`_ in\nthe SoundTouch readme for more information.\n\n.. _TimeStretch-rational-pair:\n\n.. rubric:: Tempo_n, Tempo_d, Rate_n, Rate_d, Pitch_n and Pitch_d\n\nWhen needing more accuracy you can use the rational pair parameters ``tempo_n``,\n``tempo_d``, ``rate_n``, ``rate_d``, ``pitch_n`` and ``pitch_d`` instead. All\nparameters are integers and have default value 1. Internally ``tempo`` is\ncalculated as double(``tempo_n``/``tempo_d``) (``rate`` and ``pitch`` likewise),\nbefore further processing. Seeking should be sample exact.\n\n.. _TimeStretch-advanced:\n\n.. rubric:: Advanced Parameters\n\nThe time-stretch algorithm has a few parameters that can be tuned to optimize\nsound quality for certain applications. The current default parameters have been\nchosen by iterative if-then analysis (read: \"trial and error\") to obtain the\nbest subjective sound quality in pop/rock music processing, but in applications\nprocessing different kind of sound the default parameter set may return a\nsub-optimal result. See section `3.4. Tuning the algorithm parameters`_ in the\nSoundTouch readme for more information.\n\nThese parameters affect the time-stretch algorithm as follows:\n\n.. describe:: sequence\n\n    This is the length of a single *processing sequence* in milliseconds, which\n    determines how the original sound is chopped in the time-stretch algorithm.\n    Larger values mean fewer, and longer, sequences are used. In general,\n\n    * a larger ``sequence`` value sounds better with a lower ``tempo`` and/or\n      ``pitch``;\n    * a smaller ``sequence`` value sounds better with a higher ``tempo`` and/or\n      ``pitch``.\n\n    Default: 100 *\n\n.. describe:: seekwindow\n\n    The length in milliseconds for the algorithm that searches for the best\n    possible overlap location. For larger ``seekwindow`` values, the possibility\n    of finding a better mixing position increases, but an overly large\n    ``seekwindow`` may cause **drifting** (a disturbing artifact where audio\n    pitch seems unsteady) because neighboring sequences may be chosen at more\n    uneven intervals.\n\n    Default: 22 *\n\n.. describe:: overlap\n\n    The overlap length in milliseconds. When the sound sequences are mixed back\n    together to form a continuous sound stream again, ``overlap`` defines how\n    much of the ends of the consecutive sequences will be overlapped. This\n    shouldn't be a critical parameter. If you reduce the ``sequence`` by a large\n    amount, you might wish to try a smaller ``overlap``.\n\n    Default: 8\n\n.. describe:: quickseek\n\n    The time-stretch routine has a 'quick' mode that substantially speeds up the\n    algorithm but may degrade the sound quality when ``quickseek`` is set to true.\n\n    * Try ``quickseek=false`` if you hear artifacts like warbling, clicking etc.\n\n    Default: false\n\n.. describe:: aa\n\n    Controls the number of taps the `anti-alias filter`_ uses. Set to 0 to\n    disable the filter. Must be a multiple of 4.\n\n    Default: 64\n\n-------------\n\nThe table below summarizes how the parameters can be adjusted for different\napplications:\n\n.. table::\n    :widths: auto\n\n    +----------------+--------------------------+---------------------------+---------------------------+---------------+-----------------+-----------------------------+\n    | Parameter      | Default value            | If larger...              | If smaller...             | Music         | Speech          | CPU burden                  |\n    +================+==========================+===========================+===========================+===============+=================+=============================+\n    | ``Sequence``   | Relatively large, chosen | Usually better for        | Accelerates \"echoing\"     | Default value | A smaller value | Smaller value increases     |\n    |                | for slowing down music   | slowing down tempo.       | artifact when slowing     | usually good. | might be        | CPU burden.                 |\n    |                | tempo.                   | tempo. You might need     | down the tempo.           |               | better.         |                             |\n    |                |                          | less ``overlap``.         |                           |               |                 |                             |\n    |                |                          |                           |                           |               |                 |                             |\n    |                |                          |                           |                           |               |                 |                             |\n    +----------------+--------------------------+---------------------------+---------------------------+---------------+-----------------+-----------------------------+\n    | ``SeekWindow`` | Relatively large, chosen | Eases finding a good      | Makes finding a good      | Default       | Default value   | Larger value increases CPU  |\n    |                | for slowing down music   | mixing position, but may  | mixing position more      | usually good, | usually good.   | burden.                     |\n    |                | tempo.                   | cause \"drifting\"          | difficult.                | unless        |                 |                             |\n    |                |                          | artifact.                 |                           | \"drifting\"    |                 |                             |\n    |                |                          |                           |                           | is a problem. |                 |                             |\n    |                |                          |                           |                           |               |                 |                             |\n    +----------------+--------------------------+---------------------------+---------------------------+---------------+-----------------+-----------------------------+\n    | ``Overlap``    | Relatively large, chosen |                           |                           |               |                 | Larger value increases CPU  |\n    |                | to suit with above       |                           |                           |               |                 | burden.                     |\n    |                | parameters.              |                           |                           |               |                 |                             |\n    |                |                          |                           |                           |               |                 |                             |\n    +----------------+--------------------------+---------------------------+---------------------------+---------------+-----------------+-----------------------------+\n\n\\* ``sequence`` and ``seekwindow`` have default values 100 and 22. However they\nare updated if the calculated tempo is different from the default value (100).\nThe calculated tempo depends on the specified tempo or pitch in your script. It\nwill be different from 100 if tempo or pitch in your script is different from\n100. The update of the default values happens in TDStretch::calcSeqParameters().\n\n\nNotes\n-----\n\n* Since ``tempo``, ``rate`` and ``pitch`` are floating-point values, but sample\n  rates are integers, rounding effects in calculations are unavoidable; the\n  resulting audio track duration may be off by up to several 10's of milliseconds\n  (less than one video frame) per hour.\n\n  Pitch is also rounded for the same reason, but the amount is so small that the\n  effect is inaudible: according to Wikipedia, the `just-noticeable pitch\n  difference`_ is 0.1%–0.6%, while the rounding error is about 0.002%.\n\n  Use the :ref:`rational pair parameters <TimeStretch-rational-pair>` if greater\n  accuracy is required.\n\n* In AviSynth+ r2003 and greater, an updated SoundTouch library is used which\n  supports multichannel audio (added in v1.8.0). Versions prior to AviSynth+\n  r2003 or AviSynth v2.6.0 supports stereo only. If the source clip has two audio\n  channels, special processing is used to preserve `stereo imaging`_. Otherwise,\n  channels are processed independently. Independent processing works well for\n  unrelated audio tracks, but not very well for `surround sound`_. See the thread\n  `TimeStretch in AviSynth 2.5.5 Alpha - Strange stereo effects?`_ for details.\n\n\nExamples\n--------\n\n* Raise pitch one `octave`_, without changing speed::\n\n    TimeStretch(pitch=200.0)\n    # TimeStretch(pitch_n=2, pitch_d=1) # more accurate processing\n\n* Raise pitch one `semitone`_, without changing speed::\n\n    delta_pitch=1.0 ## (semitones)\n    TimeStretch(pitch=100.0*pow(2.0, delta_pitch/12.0))\n\n* Raise playback tempo from NTSC Film speed (23.97 fps) to PAL speed (25 fps)\n  without changing pitch::\n\n    TimeStretch(tempo=100.0*25.0/(24000.0/1001.0))\n\n* Increase speed to 105%, allowing pitch to rise::\n\n    TimeStretch(rate=105)\n\n ...which is equivalent to::\n\n    ar=AudioRate\n    AssumeSampleRate(Round(ar*1.05))\n    ResampleAudio(ar)\n\n\nCredits\n-------\n\n**TimeStretch** uses the *SoundTouch Audio Processing Library*\n\n    | Copyright © Olli Parviainen\n    | SoundTouch home page: http://www.surina.net/soundtouch/\n    | Source: https://codeberg.org/soundtouch/soundtouch\n\n\nBuild instructions\n------------------\n\nTimeStretch is part of Avisynth+ as an external DLL, which is - under Windows - is shipped with \nthe normal installer.\n\nFor other operating systems or custom builds see instructions:\n\n:doc:`This page <../contributing/avsplus_external_deps_guide_manual>` which describes the build process.\n\n\nChangelog\n---------\n\n+------------------+-------------------------------------------------------------------+\n| Version          | Changes                                                           |\n+==================+===================================================================+\n| AviSynth+ 3.7.4  || SoundTouch library *source* is no longer part of AviSynth repo   |\n|                  || Actual version is 2.3.3                                          |\n|                  || Increase max nr. of channels from 16 to 32 (upstream)            |\n+------------------+-------------------------------------------------------------------+\n| AviSynth+ 3.7.3  || Update SoundTouch library to v2.3.1.                             |\n|                  || Add TimeStretch overload with rational pair arguments.           |\n+------------------+-------------------------------------------------------------------+\n| AviSynth+ 3.4.0  | Update SoundTouch library to  v2.1.3 (Jan 07, 2019).              |\n+------------------+-------------------------------------------------------------------+\n| AviSynth+ r2003  || Merge TimeStretch changes from AviSynth 2.6.1                    |\n|                  || Update SoundTouch library to v1.9.2 - fixes                      |\n|                  |  multichannel issues.                                             |\n+------------------+-------------------------------------------------------------------+\n| AviSynth+ <r1555 || Sep 15, 2013                                                     |\n|                  || Put TimeStretch function into its own plugin.                    |\n|                  || TimeStretch no longer automatically converts input               |\n|                  |  clip to Float.                                                   |\n|                  || Update SoundTouch library to v1.7.1, results in                  |\n|                  |  audible quality improvement for TimeStretch.                     |\n+------------------+-------------------------------------------------------------------+\n| AviSynth 2.5.7   || Expose SoundTouch adavanced parameters.                          |\n|                  || Update SoundTouch library to v1.3.1.                             |\n+------------------+-------------------------------------------------------------------+\n| AviSynth 2.5.5   | Initial Release (based on SoundTouch library v1.2.1).             |\n+------------------+-------------------------------------------------------------------+\n\n\n$Date: 2025/01/15 16:46:19 $\n\n\n.. _pitch:\n    https://en.wikipedia.org/wiki/Pitch_(music)\n.. _float:\n    http://avisynth.nl/index.php/Float\n.. _time-stretching:\n    https://en.wikipedia.org/wiki/Audio_time_stretching_and_pitch_scaling\n.. _vari-speed:\n    https://en.wikipedia.org/wiki/Pitch_control\n.. _time-stretching or pitch-shifting:\n    https://en.wikipedia.org/wiki/Audio_time_stretching_and_pitch_scaling\n.. _octave:\n    https://en.wikipedia.org/wiki/Octave\n.. _3.3. About algorithms:\n    http://www.surina.net/soundtouch/README.html\n.. _3.4. Tuning the algorithm parameters:\n    http://www.surina.net/soundtouch/README.html\n.. _anti-alias filter:\n    https://en.wikipedia.org/wiki/Finite_impulse_response\n.. _octave:\n    https://en.wikipedia.org/wiki/Octave\n.. _pitch-shifting:\n    https://en.wikipedia.org/wiki/Audio_time_stretching_and_pitch_scaling\n.. _just-noticeable pitch difference:\n    https://en.wikipedia.org/wiki/Pitch_(music)#Just-noticeable_difference\n.. _stereo imaging:\n    https://en.wikipedia.org/wiki/Stereo_imaging\n.. _surround sound:\n    https://en.wikipedia.org/wiki/5.1_surround_sound\n.. _TimeStretch in AviSynth 2.5.5 Alpha - Strange stereo effects?:\n    http://forum.doom9.org/showthread.php?t=71632\n.. _semitone:\n    https://en.wikipedia.org/wiki/Semitone\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/tone.rst",
    "content": "\nTone\n====\n\n**Tone** generates sound (a waveform) at a given ``frequency`` for a given\n``length`` of time in seconds. The output audio sample type is 32-bit float.\nUse :doc:`ConvertAudio <convertaudio>` if this is not what you want.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    Tone (float \"length\", float \"frequency\", int \"samplerate\", int \"channels\", string \"type\", float \"level\")\n\n.. describe:: length\n\n    Length of time in seconds.\n\n    Default: 10.00\n\n.. describe:: frequency\n\n    Tone frequency.\n\n    Default: 440\n\n.. describe:: samplerate\n\n    Audio sample rate.\n\n    Default: 48000\n\n.. describe:: channels\n\n    Number of audio channels.\n\n    Default: 2\n\n.. describe:: type\n\n    \"Silence\", \"Sine\", \"Noise\", \"Square\", \"Triangle\" or \"Sawtooth\".\n\n    Default: \"Sine\"\n\n.. describe:: level\n\n    | The amplitude of the waveform. Default = 1.0 (or 0\\ `dB`_, the maximum level\n      possible without `clipping`_).\n    | For a particular decibel level, use the equation ``level`` =\n      10 :sup:`dB / 20`\n    | For example, create a -12dB tone with ``level`` = 10\\ :sup:`-12/20` or 0.251.\n\n    Default: 1.0\n\n\nDiscussion\n----------\n\n.. image:: pictures/tone.png\n\n``Tone(frequency=2, samplerate=48000, channels=2, type=\"sine\", level=0.4)``\n\nIn the figure above, a sinus is generated (on a black clip with framerate 24\nfps). The period of the waveform (in frames) is the *framerate* divided by\n*frequency* (or fps/freq, which is 24/2=12 frames in our example). The part of\nthe graph which is light-green represents all samples of the frame under\nconsideration (which is frame 1 here). The number of samples in a particular\nframe is given by the *samplerate* divided by the *framerate* (which is\n48000/24 = 2000 samples in our example).\n\nMore generally, the waveform above is described by\n\n    ``g(n,s) = level * sin(2*pi*(frequency*n/framerate + s*frequency/samplerate))``\n\nwith *n* the frame and *s* the sample under consideration (note that s runs\nfrom 0 to samplerate/framerate - 1).\n\nIn the example above, this reduces to\n\n    ``g(n,s) = 0.4 * sin(2*pi*(2*n/24 + s*2/48000))``\n\nwith *n* the frame and *s* the sample under consideration (note that s runs\nfrom 0 to 1999).\n\nNote that the bars are made with :doc:`Histogram <histogram>` and the graph with\nthe `AudioGraph`_ plugin.\n\n\nExamples\n--------\n\n`We Wish You a Merry Christmas`_, in harmony (author hanzfrunz)\n\n\nChangelog\n---------\n\n+----------------+----------------------------+\n| Version        | Changes                    |\n+================+============================+\n| AviSynth 2.5.6 | Added ``level`` parameter. |\n+----------------+----------------------------+\n| AviSynth 2.5.4 | Initial release.           |\n+----------------+----------------------------+\n\n$Date: 2022/03/04 00:53:01 $\n\n.. _dB:\n    https://en.wikipedia.org/wiki/Decibel\n.. _clipping:\n    https://en.wikipedia.org/wiki/Clipping_(audio)\n.. _AudioGraph:\n    http://avisynth.nl/index.php/AudioGraph\n.. _We Wish You a Merry Christmas:\n    https://forum.doom9.org/showthread.php?t=172979\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/trim.rst",
    "content": "================\nTrim / AudioTrim\n================\n\nSet of filters to trim audio and video:\n\n* `Trim`_ can trim video only clips and also clips with both audio and video.\n* `AudioTrim`_ can trim audio only clips and also clips with both audio and video.\n\n.. _Trim:\n\nTrim\n----\n\n*Trims* a clip – removes frames from one or both ends.\n\n**Trim** cannot trim a clip if there is no video. Use `AudioTrim`_ for that case.\n\nThe resulting clip starts with frame number 0, and this must be taken into\naccount when making additional edits using that clip. To view a clip's frame\nnumber at any point in your script, temporarily insert an :doc:`Info <info>`\nor :ref:`ShowFrameNumber` statement.\n\n.. rubric:: Syntax and Parameters\n\nFor convenience, **Trim** can be called in four slightly different ways:\n\n::\n\n    Trim (clip, int first_frame, int last_frame , bool \"pad\", bool \"cache\")\n\n.. describe:: clip\n\n    Source clip; all color formats and audio sample types supported.\n\n.. describe:: first_frame, last_frame\n\n    Returns a clip starting at ``first_frame`` and running up to and including\n    ``last_frame``.\n\n    * For example, ``Trim(3, 5)`` returns source clip frames 3, 4 and 5.\n    * Remember, AviSynth starts counting at frame 0.\n    * If you set ``last_frame`` to 0, you will get a clip starting at\n      ``first_frame`` and running to the end of the clip.\n\n.. describe:: pad\n\n    ``pad`` causes the audio stream to be padded to align with the video stream.\n    Otherwise the tail of a short audio stream is left so. You should use\n    ``pad=false`` when the soundtracks being joined were originally contiguous –\n    compare to :doc:`UnalignedSplice <splice>`.\n\n    Default: true\n\n.. describe:: cache\n\n    When set to false: lower memory consumption but may be slower. Benefits\n    heavily depend on how trimmed clips are used later. See `issue #274`_ for\n    more information.\n\n    Default: true\n\n------------------\n\n::\n\n    Trim (clip, int first_frame, int -num_frames , bool \"pad\", bool \"cache\")\n\n.. describe:: first_frame, -num_frames\n\n    With a negative value for the second argument, you get a clip starting at\n    ``first_frame`` and running for ``num_frames`` frames.\n\n    * For example, ``Trim(0, -4)`` returns source clip frames 0, 1, 2 and 3.\n\n------------------\n\n::\n\n    Trim (clip, int first_frame, int \"end\" , bool \"pad\", bool \"cache\")\n\n.. describe:: first_frame, end\n\n    Returns a clip starting at ``first_frame`` and running up to and including\n    frame ``end``.\n\n    * For example, ``Trim(3, end=7)`` is equivalent to ``Trim(3, 7)``; both\n      return frames 3, 4, 5, 6 and 7.\n    * ``end`` default = 0; must be >= ``first_frame``.\n    * Unlike the ``last_frame`` syntax, the ``end`` syntax has no discontinuous\n      boundary values: ``end=0`` means end at frame 0. This feature is useful\n      in avoiding unexpected boundary conditions in your user functions.\n\n------------------\n\n::\n\n    Trim (clip, int first_frame, int \"length\" , bool \"pad\", bool \"cache\")\n\n.. describe:: first_frame, length\n\n    Returns a clip starting at ``first_frame`` and running for ``length`` frames.\n\n    * For example, ``Trim(3, length=5)`` is equivalent to ``Trim(3, -5)``;\n      both return frames 3, 4, 5, 6 and 7.\n    * ``length`` default = 0; must be >= 0.\n    * Unlike the ``num_frames`` syntax, the ``length`` syntax has no\n      discontinuous boundary values: ``length=0`` means return a zero length\n      clip. This feature is useful in avoiding unexpected boundary conditions\n      in your user functions.\n\n.. _AudioTrim:\n\nAudioTrim\n---------\n\n**AudioTrim** trims a clip based on time, not on frames. This is most useful\nfor audio-only clips, where \"frames\" have no meaning anyway, and you may want\nto edit with finer precision than whole frames (at 30fps, 1 frame=33.3ms).\n\nAll time arguments are in seconds, floating-point.\n\n* Trims on audio-only clips are accurate to the nearest audio sample.\n* Trims on clips with video are accurate to the nearest whole video frame.\n\n**AudioTrim** cannot trim a clip if there is no audio. Use `Trim`_ for that case.\n\nThe resulting clip starts with time = 0.0, and this must be taken into account\nwhen making additional edits to that clip. To view a clip's time at any point\nin your script, temporarily insert an :doc:`Info <info>` or :ref:`ShowTime`\nstatement.\n\n.. rubric:: Syntax and Parameters\n\nFor convenience, **AudioTrim** can be called in four slightly different ways:\n\n::\n\n    AudioTrim (clip, float start_time, float end_time, bool \"cache\")\n\n.. describe:: clip\n\n    Source clip; all color formats and audio sample types supported.\n\n.. describe:: start_time, end_time\n\n    Returns a clip starting at ``start_time`` and running up to and including\n    time ``end_time``.\n\n    * For example, ``AudioTrim(3.0, 5.0)`` returns source clip from time\n      00:00:03.000 to 00:00:05.000.\n    * If you set ``end_time`` to 0.0, you will get a clip starting at\n      ``start_time`` seconds and running to the end of the clip.\n\n.. describe:: cache\n\n  When set to false: lower memory consumption but may be slower. Benefits\n  heavily depend on how trimmed clips are used later. See `issue #274`_ for\n  more information.\n\n  Default: true\n\n------------------\n\n::\n\n    AudioTrim (clip, float start_time, float -duration, bool \"cache\")\n\n.. describe:: start_time, -duration\n\n    With a negative value for the second argument, you will get a clip\n    starting at ``start_time`` and running for ``duration`` seconds.\n\n    * For example, ``AudioTrim(0.0, -4.0)`` returns the source clip from time\n      00:00:00.000 to 00:00:04.000.\n\n------------------\n\n::\n\n    AudioTrim (clip, float start_time, float \"end\", bool \"cache\")\n\n.. describe:: start_time, end\n\n    Returns a clip starting at ``start_time`` and running up to and including\n    time ``end``.\n\n    * For example, ``AudioTrim(3.0, end=7.0)`` is equivalent to\n      ``AudioTrim(3.0, 7.0)``\n    * ``end`` default = 0.0; must be >= ``start_time``.\n    * Unlike the ``end_time`` syntax, the ``end`` syntax has no discontinuous\n      boundary values: ``end=0.0`` means return a zero-length clip. This\n      feature is useful in avoiding unexpected boundary conditions in your\n      user functions.\n\n------------------\n\n::\n\n    AudioTrim (clip, float start_time, float \"length\", bool \"cache\")\n\n.. describe:: start_time, length\n\n    Returns a clip starting at ``start_time`` and running for ``length`` seconds.\n\n    * For example, ``AudioTrim(3.0, length=4.0)`` is equivalent to\n      ``AudioTrim(3.0, -4.0)``\n    * ``length`` default = 0.0; must be >= 0.\n    * Unlike the duration syntax, the ``length`` syntax has no discontinuous\n      boundary values: ``length=0.0`` means return a zero-length clip. This\n      feature is useful in avoiding unexpected boundary conditions in your\n      user functions.\n\n\nExamples\n--------\n\n* Return only the first frame (frame 0)::\n\n    Trim(0, -1)\n    Trim(0, end=0)\n    Trim(0, length=1)\n\n* Return only the last frame::\n\n    Trim(FrameCount, -1)\n    Trim(FrameCount, end=Framecount)\n    Trim(FrameCount, length=1)\n\n* Return frames 100-199 (duration=100)::\n\n    Trim(100, 199)\n    Trim(100, -100)\n\n* Delete the first 100 frames; audio padded or trimmed to match the video\n  length. ::\n\n    Trim(100, 0) # (pad=true by default)\n\n* Delete the first 100 frames of audio and video; the resulting stream lengths\n  remain independent. ::\n\n    Trim(100, 0, pad=false)\n\n* Trim audio if longer than video (pad does affect this action)::\n\n    Trim(0, FrameCount-1)\n\n* Audio will be trimmed if longer, but not padded if shorter to frame 199::\n\n    Trim(100, 199, pad=false)\n\n* AudioTrim: trim video if longer than audio::\n\n    AudioTrim(0, AudioDuration)\n\n* AudioTrim: keep the audio between 1.0 and 6.5 seconds (ie, delete the first\n  second, keep the following 5.5 seconds)::\n\n    AudioTrim(1, 6.5)\n    AudioTrim(1, -5.5)\n    AudioTrim(1, length=5.5)\n\n\nChangelog\n----------\n\n+-----------------+----------------------------------------------------+\n| Version         | Changes                                            |\n+=================+====================================================+\n| AviSynth+ 3.7.2 | Added ``cache`` parameter.                         |\n+-----------------+----------------------------------------------------+\n| AviSynth 2.6.0  || Added AudioTrim.                                  |\n|                 || Added explicit ``length`` and ``end`` parameters. |\n+-----------------+----------------------------------------------------+\n| AviSynth 2.5.6  | Added ``pad`` audio parameter.                     |\n+-----------------+----------------------------------------------------+\n\n$Date: 2022/03/12 14:59:42 $\n\n.. _issue #274:\n    https://github.com/AviSynth/AviSynthPlus/issues/274\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/turn.rst",
    "content": "\nTurnLeft / TurnRight / Turn180\n==============================\n\nSet of filters to rotate:\n\n* **TurnLeft** \trotates the clip 90 degrees counterclockwise.\n* **TurnRight** rotates the clip 90 degrees clockwise.\n* **Turn180** \trotates the clip 180 degrees.\n\nSyntax and Parameters\n----------------------\n\n::\n\n    TurnLeft (clip)\n    TurnRight (clip)\n    Turn180 (clip)\n\n.. describe:: clip\n\n    Source clip.\n\n\nChangelog\n----------\n\n+------------------+-------------------------------------------------+\n| Version          | Changes                                         |\n+==================+=================================================+\n| AviSynth+ r2728  | Fix: RGB64 Turnleft/Turnright (which are also   |\n|                  | used in RGB64 Resizers).                        |\n+------------------+-------------------------------------------------+\n| AviSynth+ r2322  | Make Planar RGB TurnLeft, TurnRight work again. |\n|                  | (2016/11/20)                                    |\n+------------------+-------------------------------------------------+\n| AviSynth+ <r1555 | Code from FTurn is now integrated into the core | \n|                  | (with some additional optimizations and new     |\n|                  | RGB32 routines). (2013/11/24)                   |\n+------------------+-------------------------------------------------+\n| AviSynth 2.5.5   | ``Turn180`` added.                              |\n+------------------+-------------------------------------------------+\n\n$Date: 2022/02/04 04:52:52 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/tweak.rst",
    "content": "=====\nTweak\n=====\n\nAdjust hue, saturation, brightness, and contrast of a video clip.\n\nBoth the saturation and hue can be adjusted for range of saturation from\n``minSat`` to ``maxSat`` and a range of hue from ``startHue`` to ``endHue``.\n\nAll parameters are `autoscaling`_ – they work without changes at all bit depths.\n\n\nSyntax and Parameters\n----------------------\n\n::\n\n    Tweak (clip,\n           float \"hue\", float \"sat\", float \"bright\", float \"cont\",\n           bool \"coring\", bool \"sse\", float \"startHue\", float \"endHue\",\n           float \"maxSat\", float \"minSat\", float \"interp\", bool \"dither\",\n           bool \"realcalc\", float \"dither_strength\")\n\n\n.. describe:: clip\n\n    Source clip; all YUV(A) color formats supported.\n\n.. describe:: hue = 0.0\n\n    Adjust the color hue of the image.\n\n    * ``hue``\\ >0.0 shifts the image towards red.\n    * ``hue``\\ <0.0 shifts the image towards green.\n\n    | Range: -180.0 to +180.0\n    | Default: 0.0\n\n.. describe:: sat\n\n    Adjust the color saturation of the image by controlling gain of the color\n    channels.\n\n    * ``sat``\\ >1.0 increases the saturation.\n    * ``sat``\\ <1.0 reduces the saturation.\n    * ``sat=0`` converts to :doc:`greyscale`.\n\n    | Range: 0.0 to 10.0\n    | Default: 1.0\n\n.. describe:: bright\n\n    Change the brightness of the image by applying a constant bias to the luma\n    channel.\n\n    * ``bright``\\ >0.0 increases the brightness.\n    * ``bright``\\ <0.0 decreases the brightness.\n\n    | Range: -255.0 to 255.0\n    | Default: 0.0\n\n.. describe:: cont\n\n    Change the contrast of the image by multiplying the luma values by a constant.\n\n    * ``cont``\\ >1.0 increase the contrast (the luma range will be stretched).\n    * ``cont``\\ <1.0 decrease the contrast (the luma range will be contracted).\n\n    | Range: 0.0 to 10.0\n    | Default: 1.0\n\n.. describe:: coring\n\n    | When set to true, the luma (Y) and chroma are clipped to limited range (TV);\n    | When set to false, the luma and chroma are unconstrained.\n\n    Default: true\n\n.. describe:: sse = false\n\n    | Only available for YUY2 with ``coring=false`` and with the default\n      ``hue``, ``sat``, ``bright`` and ``cont`` options.\n    | If ``sse=true``, it re-enables the SSE code if required.\n\n    Default: false\n\n.. describe:: startHue, endHue\n\n    The hue and saturation will be adjusted for image values in the range\n    [``startHue``, ``endHue``] when ``startHue``\\ <``endHue``. Note that the\n    hue is periodic, thus a hue of 360 degrees corresponds with a hue of zero\n    degrees.\n\n    | Range: 0 to 360  (given in degrees)\n    | Default: 0, 360 (all hues)\n\n    The following shows some arbitrary ``startHue`` and ``endHue`` values for\n    the basic colors, with a :ref:`Histogram Vectorscope <histogram-color2>` to\n    illustrate the color circle:\n\n    .. image::  pictures/maskhs-table.png\n\n    If ``endHue``\\ <``startHue`` then the range [``endHue``, 360] and\n    [0, ``startHue``] will be selected (thus anti-clockwise). If you need to\n    select a range of [350, 370] for example, you need to specify ``startHue=350``\n    and ``endHue=10``, (370-360). Thus when using the default values, all pixels\n    will be processed.\n\n.. describe:: maxSat, minSat\n\n    The hue and saturation will be adjusted for image values in the range\n    [``minSat``, ``maxSat``].\n\n    Practically speaking, the percentage saturation of a pixel will be in the\n    range [0, 100], since these correspond to valid RGB pixels (100% corresponds\n    to R=255, G=B=0, which has a saturation of 119 in units of chroma). An\n    overshoot (up to 150%) is allowed for non-valid RGB pixels (150% corresponds\n    to U=V=255, which has a saturation of √(127\\ :sup:`2`\\ +127\\ :sup:`2`) = 180).\n    Thus when using the default values all pixels will be processed.\n\n    | Range: 0 to 150; ``minSat`` must be less than ``maxSat``.\n    | Default: 150, 0\n\n.. describe:: interp\n\n    Interpolate the saturation adjustment at the edges of the chosen range to\n    prevent banding.\n\n    The adjustment is interpolated between 1.0 and sat in the range\n    [*minS*\\ -\\ ``interp``, *minS*] and between sat and 1.0 in\n    [*maxS*, *maxS*\\ +\\ ``interp``], where *minS* and *maxS* are the equivalents\n    of ``minSat`` and ``maxSat`` in chroma units (100% = 119 units). There is no\n    interpolation for ``interp=0``, which can be useful when a clip consists of\n    uniform colors and you want a hard cutoff. The interpolation is linear.\n\n    | Range: 0 to 32; given in units of chroma, rather than a percentage.\n    | Default: 16.0\n\n.. describe:: dither\n\n    When true, ordered dithering is applied when doing the adjustment.\n\n    Default: false\n\n.. describe:: realcalc\n\n    By default, **Tweak** uses a `LUT`_ for the luma channel when the bit depth\n    is 8 to 16 bits and uses realtime calculation for 32-bit float. For the\n    chroma channels, a LUT is used only for 8 or 10 bits, greater than 10 and\n    the calculation for each pixel is done in realtime. When ``realcalc=true``,\n    it overrides using a LUT and calculates each pixel on-the-fly.\n\n    Default: false\n\n.. describe:: dither_strength\n\n    Control the dithering amount. For example, ``dither_strength=1.0`` adds a\n    ±0.5 amplitude dither for all bit depths. As the bit depth increases the\n    less noticiable the dithering strength is. To get the same visual output as\n    in 8-bit and ``dither_strength=1.0``, the strength needs to be set to 4 for\n    10-bit, 16 for 12-bit, 64 for 14-bit and 256 for 16-bit.\n\n    Default: 1.0\n\n\nExamples\n--------\n\nAdjusting contrast and brightness\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n.. list-table::\n\n    * - .. figure:: pictures/tweak_original.jpg\n\n           Original\n\nThere are two problems with this picture. It is too dark, and the contrast is\ntoo small (the details of the tree are not visible for example). First, we\nwill increase the brightness to make the picture less dark (left picture\nbelow). Second, we will increase the contrast to make details in the dark\nareas more visible (right picture below). Make sure that the bright parts\ndoes not get too bright though.\n\n\n.. list-table::\n\n    * - .. figure::  pictures/tweak_bright20.jpg\n\n           ``Tweak(bright=20)``\n\n      - .. figure:: pictures/tweak_bright20_cont12.jpg\n\n           ``Tweak(bright=20, cont=1.2)``\n\n\nAdjusting saturation\n^^^^^^^^^^^^^^^^^^^^\n\n.. list-table::\n\n    * - .. figure::  pictures/tweak_original2.jpg\n\n           Original\n\n      - .. figure:: pictures/tweak_sat075.jpg\n\n           ``Tweak(sat=0.75)``\n\nSuppose we want to lower the saturation of the skin of the girl, and the\nbackground should be left intact. The proper way to do this is to set ``sat=0``,\nand lower the hue range till you found the correct hue range which should be\nprocessed. This can be done by using a Vectorscope, but also manually. (If it\nis needed the saturation range can also be specified if the dark and white\nparts of that hue should not be processed.) The result is below.\n\n.. list-table::\n\n    * - .. figure::  pictures/tweak_hue105-138.jpg\n\n           ``Tweak(sat=0, startHue=105, endHue=138)``\n\n      - .. figure:: pictures/tweak_hue105-138_sat075.jpg\n\n           ``Tweak(sat=0.75, startHue=105, endHue=138)``\n\n\nInstead, we can also try to \"select\" the skin of the girl by narrowing the\nsaturation range only. The result is below. In this case the result is pretty\nmuch identical.\n\n.. list-table::\n\n    * - .. figure::  pictures/tweak_sat70-50.jpg\n\n           ``Tweak(sat=0, maxSat=75, minSat=55)``\n\n      - .. figure:: pictures/tweak_sat70-50_sat075.jpg\n\n           ``Tweak(sat=0.75, maxSat=75, minSat=55)``\n\n\nYUV to YIQ conversion\n---------------------\n\nThe NTSC analog television system used the YUV color space with the UV axes\nexchanged and rotated by minus 33 degrees. See `Colour FAQ of Charles Poynton`_.\nNote he gives the reverse transformation (from YIQ to YUV).\n\nWith its axes rotated by 33 degrees, a color space called `YIQ`_. In YIQ, orange\nand teal are along the in-phase (I) axis, while green and magenta are along the\nquadrature (Q) axis. The eye is far more sensitive to detail along the I axis\nthan along the Q axis, and NTSC allocated more bandwidth for I than for Q.\n\nThe **Tweak** filter can be used to convert YUV to YIQ, where the U axis\nrepresents I and V represents Q. The following example, based on an example at\n:doc:`Swap <swap>`, converts a YUV clip to YIQ, blanks the Q channel, and\nconverts back to YUV. This produces the \"orange and teal\" color scheme that\nbecame a `cliché`_.\n\n::\n\n    Function YUVtoYIQ(clip clip)\n    {\n       YtoUV(clip.VtoY(), clip.UtoY(), clip) # swap U and V\n       Tweak(hue=-33)\n       # Now: U corresponds to I, V corresponds to Q\n       # could also have used: FlipHorizontal(clip).Tweak(hue=57)\n    }\n\n    Function YIQtoYUV(clip clip)\n    {\n       clip.Tweak(hue=33)\n       YtoUV(VtoY(), UtoY(), last) # swap U and V\n    }\n\n    clip = AviSource(...)\n    yiqclip = YUVtoYIQ(clip)  # convert to YIQ\n    v_chroma = BlankClip(VToY(yiqclip), color=$808080)\n    YToUV(yiqclip.UToY, v_chroma, yiqclip)\n    YIQtoYUV()  # convert back to YUV\n    AudioDub(yiqclip)\n\nThis allows processing the I and Q signals separately. See the `VideoHelp thread`_\nfor more info.\n\nDeveloper notes\n----------------\n\n| AviSynth uses the following definitions for hue and saturation:\n| As can be seen in the first image above, hue is the angle between the positive\n  V-axis of the  chroma plane and the point given by the centralised coordinates\n  (V,U) on it. The saturation is the amplitude of the centralised chroma plane.\n  Mathematically:\n\n* hue = 180/π * `atan2`_\\ ((V-128)/128, (U-128)/128)\n* sat = √((U-128)2 + (V-128)2)\n\n\nChangelog\n---------\n\n.. table::\n    :widths: auto\n\n    +-----------------+-------------------------------------------------------+\n    | Version         | Changes                                               |\n    +=================+=======================================================+\n    | AviSynth r2487  || Added Luma LUT for 10-16 bits, Chroma LUT for 10 bit |\n    |                 |  (old: LUT 8 bit only).                               |\n    |                 || Added ``dither_strength`` parameter.                 |\n    +-----------------+-------------------------------------------------------+\n    | AviSynth r2290  || Added support for 16/32 bits, without lookup tables. |\n    |                 || Added ``realcalc`` parameter.                        |\n    +-----------------+-------------------------------------------------------+\n    | AviSynth 2.6.0  | Added ``dither`` parameter.                           |\n    +-----------------+-------------------------------------------------------+\n    | AviSynth 2.5.8  | Added parameters ``startHue, endHue, maxSat, minSat`` |\n    |                 | and ``interp``.                                       |\n    +-----------------+-------------------------------------------------------+\n    | AviSynth 2.5.6  | Added ``sse`` parameter.                              |\n    +-----------------+-------------------------------------------------------+\n    | AviSynth 2.5.3  | Added ``coring`` parameter.                           |\n    +-----------------+-------------------------------------------------------+\n\n$Date: 2022/09/17 15:28:44 $\n\n.. _autoscaling:\n    http://avisynth.nl/index.php/Autoscale_parameter\n.. _ordered dithering:\n    http://avisynth.nl/index.php/Ordered_dithering\n.. _LUT:\n    https://en.wikipedia.org/wiki/Lookup_table\n.. _Colour FAQ of Charles Poynton:\n    http://poynton.ca/notes/colour_and_gamma/ColorFAQ.html#RTFToC33\n.. _YIQ:\n    https://en.wikipedia.org/wiki/YIQ\n.. _cliché:\n    https://tvtropes.org/pmwiki/pmwiki.php/Main/OrangeBlueContrast\n.. _VideoHelp thread:\n    https://forum.videohelp.com/threads/377237-Purple-green-VHS#post2435970\n.. _atan2:\n    https://en.wikipedia.org/wiki/Atan2\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/version.rst",
    "content": "\nVersion\n=======\n\n**Version** by default generates a 24\\ `fps`_, 10-second, `RGB24`_\\-format video\nclip with a version, build time, copyright statement, and homepage information\nin 24-point, Arial, light yellow (:doc:`$ECF2BF <../syntax/syntax_colors>`) text\non a 25% grey ($404040) background. Width and height are automatically chosen to\nfit the message, so clip size varies by version.\n\n.. image:: pictures/version-3.7.1.png\n\n\nSyntax and Parameters\n----------------------\n\n.. code::\n\n    Version(int \"length\", int \"width\", int \"height\", string \"pixel_type\", clip \"clip\")\n\n.. describe:: length\n\n    Length of the resulting clip (in frames).\n\n    Default: 240\n\n.. describe:: width, height\n\n    Width and height of the resulting clip.\n    When set to  -1 (or <= 0), it is automatically sized to fit font size 24.\n\n    Default: -1, -1\n\n.. describe:: pixel_type\n\n    Pixel type of the resulting clip. See :doc:`Blankclip <blankclip>` for a\n    complete list of color formats.\n\n    Default: \"RGB24\"\n\n.. describe:: clip\n\n    Template clip; if present, the resulting clip will have the clip-properties\n    of the template, except for the properties defined explicitly.\n\n\nChangelog\n---------\n\n+-----------------+---------------------------------------------------------+\n| Version         | Changes                                                 |\n+=================+=========================================================+\n| AviSynth+ 3.7.2 | Added parameters ``length, width, height, pixel_type``, |\n|                 | and ``clip``.                                           |\n+-----------------+---------------------------------------------------------+\n\n$Date: 2022/03/03 21:28:07 $\n\n.. _fps:\n    http://en.wikipedia.org/wiki/Frame_rate\n.. _RGB24:\n    http://avisynth.nl/index.php/RGB24\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/weave.rst",
    "content": "=============\nWeave Filters\n=============\n\nSet of filters to weave fields, columns and rows:\n\n* `Weave`_ combines fields together to produce interlaced frames.\n* `WeaveColumns`_ takes a clip and weaves sets of columns together to produce\n  composite frames.\n* `WeaveRows`_ takes a clip and weaves sets of rows together to produce\n  composite frames.\n\n\n.. _Weave:\n\nWeave\n-----\n\n**Weave** is the opposite of :ref:`SeparateFields`: it takes pairs of fields\nfrom the input video clip and combines them together to produce interlaced\nframes. The new clip has half the frame rate and frame count. **Weave** uses\nthe frame-parity information in the source clip to decide which field to put\non top. If it gets it wrong, use :ref:`ComplementParity` beforehand or\n:doc:`SwapFields <swapfields>` afterwards.\n\nAll AviSynth filters keep track of field parity, so **Weave** will always join\nthe fields together in the proper order. If you want to change the order, you'll\nhave to use :ref:`ComplementParity`, :ref:`AssumeTFF <AssumeFieldFirst>` or\n:ref:`AssumeBFF <AssumeFieldFirst>` beforehand or :doc:`SwapFields <swapfields>`\nafterwards.\n\n**Weave** raises an exception if the clip is already frame-based. You may want\nto use :ref:`AssumeFieldBased <AssumeFrameField>` to force weave a second time.\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    Weave (clip)\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n\n.. _WeaveColumns:\n\nWeaveColumns\n------------\n\n**WeaveColumns** is the opposite of :ref:`SeparateColumns`: it weaves the\ncolumns of *period* frames into a single output frame. The number of frames of\nthe new clip is the ceiling of the number of frames of the input clip divided\nby *period*. **WeaveColumns** is a relatively slow filter due to the sparse\npixel placing required by the algorithm. In some applications it may be faster\nto use :doc:`TurnLeft/Right <turn>` with `WeaveRows`_.\n\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    WeaveColumns (clip, int period)\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n.. describe:: period\n\n    ``period`` must be greater than zero.\n\n\n.. _WeaveRows:\n\nWeaveRows\n---------\n\n**WeaveRows** is the opposite of :ref:`SeparateRows`: it weaves the rows of\nperiod frames into a single output frame. The number of frames of the new\nclip is the ceiling of the number of frames of the input clip divided by\n*period*. **WeaveRows** is a relatively quick filter, typically costing 1\noutput frame blit. ``WeaveRows(2)`` is the same as ``Weave()``.\n\n\n.. rubric:: Syntax and Parameters\n\n::\n\n    WeaveRows (clip, int period)\n\n.. describe:: clip\n\n    Source clip; all color formats supported.\n\n.. describe:: period\n\n    ``period`` must be greater than zero.\n\n\nExamples\n--------\n\n::\n\n    # makes a black and white checkerboard\n    # (without changing the spatial position of the rows and columns)\n\n    BlankClip # black\n\n    # frame 0 consists of the rows 0,2,4,... of the original frame 0\n    # frame 1 consists of the rows 1,3,5,... of the original frame 0\n    # frame 2 consists of the rows 0,2,4,... of the original frame 1\n    # frame 3 consists of the rows 1,3,5,... of the original frame 1\n    # etc ...\n    SeparateRows(2)\n\n    # E1 consists of even frames thus\n    # rows 0,2,4,... of the original frame 0\n    # rows 0,2,4,... of the original frame 1\n    # etc ...\n    E1 = SelectEven()\n\n    # O1 consists of the odd frames thus\n    # rows 1,3,5,... of the original frame 0\n    # rows 1,3,5,... of the original frame 1\n    # etc ...\n    O1 = SelectOdd\n\n    # likewise for a white clip\n    BlankClip(color=$FFFFFF)\n    SeparateRows(2)\n    E2 = SelectEven()\n    O2 = SelectOdd()\n\n    # rows 0,2,4,... of the original black frame 0\n    # rows 0,2,4,... of the original white frame 0\n    # rows 0,2,4,... of the original black frame 1\n    # rows 0,2,4,... of the original white frame 1\n    # etc ...\n    EI = Interleave(E1, E2)\n\n    # rows 1,3,5,... of the original white frame 0\n    # rows 1,3,5,... of the original black frame 0\n    # rows 1,3,5,... of the original white frame 1\n    # rows 1,3,5,... of the original black frame 1\n    # etc ...\n    OI = Interleave(O2, O1)\n\n    # alternating black and white columns frame 0\n    # alternating black and white columns frame 1\n    # etc ...\n    E = EI.WeaveColumns(2)\n\n    # alternating white and black columns frame 0\n    # alternating white and black columns frame 1\n    # etc ...\n    O = OI.WeaveColumns(2)\n\n    # alternating black and white columns frame 0\n    # alternating white and black columns frame 0\n    # alternating black and white columns frame 1\n    # alternating white and black columns frame 1\n    # etc ...\n    Interleave(E, O)\n\n    # weaves the even and odd rows of the original clips\n    # with alternating black and white columns\n    WeaveRows(2)\n\n\nChangelog\n---------\n\n+-----------------+---------------------------------------------------+\n| Version         | Changes                                           |\n+=================+===================================================+\n| AviSynth+ r2487 | Weave filters: added support for 10-16bit, float, |\n|                 | Planar RGB(A)/YUV(A) and RGB48/64 formats.        |\n+-----------------+---------------------------------------------------+\n| AviSynth 2.6.0  | Added WeaveColumns and WeaveRows.                 |\n+-----------------+---------------------------------------------------+\n\n$Date: 2022/02/27 13:38:34 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters/write.rst",
    "content": "\nWriteFile\n=========\n\n**WriteFile** and related functions evaluate each `expression`_, convert the\nresult to a string and put the concatenated results into a file, followed by a\nnewline.\n\n* **WriteFile** evaluates the *expressions* and generates output for each frame\n  rendered by the filter.\n\n* **WriteFileIf** is similar, but generates output only if the first expression\n  evaluates to true.\n\n  * In both cases, there is no output at script opening or closure.\n  * Note that with :ref:`ScriptClip`, script opening and closure occurs on every\n    frame.\n  * Note that since output is produced only for rendered frames, there will be\n    no output at all if the result of the filter is |not used| in deriving the\n    final result of the script.\n\n* **WriteFileStart** and **WriteFileEnd** generate output only on script opening\n  and closure respectively.\n\n  * There is no action on each frame, unless used within :ref:`ScriptClip`.\n  * The expressions are evaluated exactly once, at the location of the filter\n    in the script.\n\n\nSyntax and Parameters\n---------------------\n\n::\n\n    WriteFile (clip, string filename, string expression1 [, string expression2 [, ...]], bool \"append\", bool \"flush\")\n\n    WriteFileIf (clip, string filename, string expression1 [, string expression2 [, ...]], bool \"append\", bool \"flush\")\n\n    WriteFileStart (clip, string filename, string expression1 [, string expression2 [, ...]], bool \"append\")\n\n    WriteFileEnd (clip, string filename, string expression1 [, string expression2 [, ...]], bool \"append\"*)\n\n.. describe:: clip\n\n    Source clip.\n\n.. describe:: filename\n\n    Path and filename of the file to be saved. If path is omitted the file will\n    be saved in the same location as the script.\n\n.. describe:: expression1, expression2, ...\n\n    Specify the expressions to use. Usage is best explained in the `Examples`_\n    section.\n\n    The |runtime| variable *current_frame* is set so that you can use it in\n    expressions (as with :ref:`ScriptClip`).\n\n    * *current_frame* is set to -1 when the script is loaded and to -2 when\n      the script is closed.\n\n.. describe:: append\n\n    When ``append=true``, the results will be appended to any existing file\n    filename; if false, a new file is created and the old one is overwritten.\n\n    * Only script opening and closure are affected; **WriteFile** and\n      **WriteFileIf** per-frame execution always append.\n    * The default for ``append`` is *true*, except for **WriteFileStart**,\n      where it is *false*.\n\n\n\n.. describe:: flush\n\n    When ``flush=true``, after each operation a flush is performed: any\n    unwritten data is written to disk, and the file is closed and reopened.\n\n    * After flushing you may read the updated file immediately, either through\n      :doc:`conditionalreader` or an external application.\n    * The default for ``flush`` is *true* for **WriteFile** and **WriteFileIf**\n      and always *true* (no user option) for **WriteFileStart** and\n      **WriteFileEnd**.\n    * Note that flushing after every frame may be significantly slower.\n\n\nExamples\n--------\n\nUsage is best explained with some simple examples:\n\n::\n\n    filename = \"c:\\myprojects\\output.txt\"\n    # create a test video to get frames\n    Version()\n\n    # the expression here is only a variable, which is evaluated and put in the file\n    # you will get a file with the framenumber in each line\n    WriteFile(filename, \"current_frame\")\n\n    # this line is written when the script is opened\n    WriteFileStart(filename, \"\"\" \"This is the header\" \"\"\")\n\n    # and this when the script is closed\n    WriteFileEnd(filename, \"\"\" \"Now the script was closed\" \"\"\")\n\nLook how you can use triple-quotes to type a string in a string!\n\nIf the expression cannot be evaluated, the error message is written instead.\nIn case this happens with the If-expression in **WriteFileIf** the result is\nassumed to be true.\n\n::\n\n    # will result in \"I don't know what \"this\" means\"\n    WriteFile(filename, \"this is nonsense\")\n\n--------\n\n\nThere are easier ways to write numbers in a file, BUT ... with this example you\ncan see how to use the *runtime function* |AverageLuma|:\n\n::\n\n    # create a test video to get different frames\n    Version().FadeIn(50).ConvertToYV12()\n\n    # this will print the frame number, a \":\" and the average luma for that frame\n    colon = \": \"\n    WriteFile(\"C:\\text.log\", \"current_frame\", \"colon\", \"AverageLuma\")\n\nOr maybe you want the actual time printed too:\n\n::\n\n    # create a test video to get different frames\n    Version().FadeIn(50).ConvertToYV12()\n\n    # this will print the frame number, the current time and the average luma for that frame\n    # the triple quotes are necessary to put quotes inside a string\n    WriteFile(last, \"text.log\", \"current_frame\", \"\"\" time(\" %H:%M:%S\") \"\"\", \"AverageLuma\")\n\n--------\n\n**More examples**\n\nIn **WriteFileIf** the FIRST expression is expected to be boolean (true or\nfalse). Only if it is TRUE the other expressions are evaluated and the line\nis printed. (Remember: && is AND, || is OR, == is EQUAL, != is NOT EQUAL)\nThat way you can omit lines completely from your file.\n\n::\n\n    # create a test video to get different frames\n    Version().FadeIn(50).ConvertToYV12()\n\n    # this will print the frame number, but only of frames where AverageLuma is between 30 and 60\n    WriteFileIf(last, \"text.log\", \"(AverageLuma>30) && (AverageLuma<60)\", \"current_frame\", \"\"\" \":\" \"\"\", \"AverageLuma\")\n\n\nChangelog\n---------\n+----------------+------------------------------------------------------------+\n| Version        | Changes                                                    |\n+================+============================================================+\n| AviSynth 2.6.0 | Number of expressions changed from 16 to nearly unlimited. |\n+----------------+------------------------------------------------------------+\n| AviSynth 2.5.5 | Initial release.                                           |\n+----------------+------------------------------------------------------------+\n\n$Date: 2022/02/24 16:01:28 $\n\n.. _expression:\n    http://avisynth.nl/index.php/Grammar\n\n.. |not used| replace:: :doc:`not used <../script_ref/script_ref_execution_model>`\n.. |runtime| replace:: :ref:`runtime <Special runtime variables and functions>`\n.. |AverageLuma| replace:: :doc:`AverageLuma <../syntax/syntax_internal_functions_runtime>`\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/corefilters.rst",
    "content": "\nCore Filters\n============\n\nIntroduction\n------------\n\nThe available (internal) filters are listed here and divided into categories.\nA short description is added, including the supported color formats (and\nsample types for the audio filters). There are some functions which combine\ntwo or more clips in different ways. How the video content is calculated is\ndescribed for each function, but :doc:`here is a summary which explains which\nproperties that the resulting clip will have <filters_mult_input_clips>`.\n\n.. _Media file filters:\n\nMedia file filters\n------------------\n\nThese filters can be used to read or write media files. Usually they produce\nsource clips for processing. See debug filters for non-file source filters.\n\n- :doc:`AVISource / OpenDMLSource / AVIFileSource <corefilters/avisource>` Opens an AVI file.\n- :doc:`DirectShowSource <corefilters/directshowsource>` DirectShowSource reads filename using DirectShow\n- :doc:`ImageReader / ImageSource / ImageSourceAnim <corefilters/imagesource>` These filters produce a video\n  clip by reading in still images or an animated image.\n- :doc:`Imagewriter <corefilters/imagewriter>` Writes frames as images to your hard disk.\n- :doc:`Import <corefilters/import>` Import an AviSynth script into the current script\n- :doc:`SegmentedAVISource / SegmentedDirectShowSource <corefilters/segmentedsource>` The SegmentedAVISource\n  filter automatically loads up to 100 avi files per argument\n- :doc:`SoundOut <corefilters/soundout>` SoundOut is a GUI driven sound output module for AviSynth (it\n  exports audio to several compressors).\n- :doc:`WAVSource <corefilters/avisource>` Opens a WAV file or the audio of an AVI file.\n\n.. _Color conversion and adjustment filters:\n\nColor conversion and adjustment filters\n---------------------------------------\n\nThese filters can be used to change the color format or adjust the colors of\na clip.\n\n- :doc:`ColorYUV <corefilters/coloryuv>` Adjusts colors and luma independently.\n- :doc:`ConvertBackToYUY2 / ConvertToRGB / ConvertToRGB24 / ConvertToRGB32 /\n  ConvertToYUY2 / ConvertToY8 / ConvertToYV411 / ConvertToYV12 / ConvertToYV16 /\n  ConvertToYV24 <corefilters/convert>` AviSynth can deal internally with the\n  color formats, RGB24, RGB32, YUY2, Y8, YV411, YV12, YV16 and YV24. These filters\n  convert between them.\n- :doc:`FixLuminance <corefilters/fixluminance>` Correct shifting vertical luma offset\n- :doc:`Greyscale <corefilters/greyscale>` Converts a video to greyscale.\n- :doc:`Invert <corefilters/invert>` Inverts selected color channels of a video.\n- :doc:`Levels <corefilters/levels>` The Levels filter scales and clamps the blacklevel and whitelevel\n  and adjusts the gamma.\n- :doc:`Limiter <corefilters/limiter>` A filter for clipping levels to within CCIR-601 range.\n- :doc:`MergeARGB / MergeRGB <corefilters/mergergb>` This filter makes it possible to select and combine a\n  color channel from each of the input videoclips.\n- :doc:`Merge / MergeChroma / MergeLuma <corefilters/merge>` This filter makes it possible to merge\n  luma, chroma or both from a videoclip into another. There is an optional\n  weighting, so a percentage between the two clips can be specified.\n- :doc:`RGBAdjust <corefilters/adjust>` Adjust each color channel seperately.\n- :doc:`ShowAlpha / ShowRed / ShowGreen / ShowBlue <corefilters/showalpha>` Shows the selected channel of\n  an (A)RGB clip.\n- :doc:`SwapUV / UToY / UToY8 / VToY / VToY8 / YToUV <corefilters/swap>` Swaps/copies chroma channels\n  of a clip.\n- :doc:`Subtract <corefilters/subtract>` Subtract produces an output clip in which every pixel is set\n  according to the difference between the corresponding pixels\n- :doc:`Tweak <corefilters/tweak>` Adjust the hue, saturation, brightness, and contrast.\n\n.. _Overlay and Mask filters:\n\nOverlay and Mask filters\n------------------------\n\nThese filters can be used to layer clips with or without using masks and to\ncreate masks.\n\n- :doc:`ColorKeyMask <corefilters/layer>` Sets the alpha-channel (similar as Mask does) but generates\n  it by comparing the color.\n- :doc:`Layer <corefilters/layer>` Layering two videos.\n- :doc:`Mask <corefilters/layer>` Applies an alpha-mask to a clip.\n- :doc:`MaskHS <corefilters/maskhs>` Returns a mask (as Y8) of clip using a given hue and saturation\n  range.\n- :doc:`Overlay <corefilters/overlay>` Overlay puts two clips on top of each other with an optional\n  displacement of the overlaying image, and using different overlay methods.\n  Furthermore opacity can be adjusted for the overlay clip.\n- :doc:`ResetMask <corefilters/layer>` Applies an \"all-opaque\" alpha-mask to clip.\n\n.. _Geometric deformation filters:\n\nGeometric deformation filters\n-----------------------------\n\nThese filters can be used to change image size, process borders or make other\ndeformations of a clip.\n\n- :doc:`AddBorders <corefilters/addborders>` AddBorders adds black borders around the image.\n- :doc:`Crop / CropBottom <corefilters/crop>` Crop crops excess pixels off of each frame.\n- :doc:`FlipHorizontal / FlipVertical <corefilters/flip>` Flips the video upside-down or left-to-right\n- :doc:`Letterbox <corefilters/letterbox>` Letterbox simply blackens out the top and the bottom and\n  optionally left and right side of each frame.\n- :doc:`Overlay <corefilters/overlay>` Overlay puts two clips on top of each other with an optional\n  displacement of the overlaying image, and using different overlay methods.\n  Furthermore opacity can be adjusted for the overlay clip.\n- :doc:`ReduceBy2 / HorizontalReduceBy2 / VerticalReduceBy2 <corefilters/reduceby2>` ReduceBy2 reduces the\n  size of each frame by half.\n- :doc:`BilinearResize / BicubicResize / BlackmanResize / GaussResize / LanczosResize /\n  Lanczos4Resize / PointResize / SincResize / Spline16Resize / Spline36Resize /\n  Spline64Resize <corefilters/resize>` The Resize filters rescale the input video\n  frames to an arbitrary new resolution, using different sampling algorithms.\n- :doc:`SkewRows <corefilters/skewrows>` SkewRows skews the rows of a clip.\n- :doc:`TurnLeft / TurnRight / Turn180 <corefilters/turn>` Rotates the clip 90 degrees counterclock\n  wise / 90 degrees clock wise / 180 degrees.\n\n.. _Pixel restoration filters:\n\nPixel restoration filters\n-------------------------\n\nThese filters can be used for image detail (pixel) restoration (like\ndenoising, sharpening) of a clip.\n\n- :doc:`Blur / Sharpen <corefilters/blur>` These are simple 3x3-kernel blurring and sharpening\n  filters.\n- :doc:`GeneralConvolution <corefilters/convolution>` General 3x3 or 5x5 convolution matrix.\n- :doc:`SpatialSoften / TemporalSoften <corefilters/soften>` The SpatialSoften and TemporalSoften\n  filters remove noise from a video clip by selectively blending pixels.\n- :doc:`FixBrokenChromaUpsampling <corefilters/fixbrokenchromaupsampling>` I noticed that the MS DV codec upsamples the\n  chroma channels incorrectly, and I added a FixBrokenChromaUpsampling filter\n  to compensate for it.\n\n.. _Timeline editing filters:\n\nTimeline editing filters\n------------------------\n\nThese filters can be used to arrange frames in time (clip cutting, splicing\nand other editing).\n\n- :doc:`AlignedSplice / UnalignedSplice <corefilters/splice>` AlignedSplice and UnalignedSplice join two\n  or more video clips end to end.\n- :doc:`AssumeFPS / AssumeScaledFPS / ChangeFPS / ConvertFPS <corefilters/fps>` Changes framerates in\n  different ways.\n- :doc:`DeleteFrame <corefilters/deleteframe>` DeleteFrame deletes a set of single frames, given as a number\n  of arguments.\n- :doc:`Dissolve <corefilters/dissolve>` Dissolve is like AlignedSplice, except that the clips are\n  combined with some overlap.\n- :doc:`DuplicateFrame <corefilters/duplicateframe>` DuplicateFrame duplicates a set of single frames, given as\n  a number of arguments.\n- :doc:`FadeIn0 / FadeOut0 / FadeIn / FadeOut / FadeIn2 / FadeOut2 / FadeIO0 / FadeIO / FadeIO2 <corefilters/fade>` FadeIn and FadeOut cause the video stream to fade linearly\n  to black at the start or end.\n- :doc:`FreezeFrame <corefilters/freezeframe>` The FreezeFrame filter replaces all the frames between first-\n  frame and last-frame with a selected frame.\n- :doc:`Interleave <corefilters/interleave>` Interleave interleaves frames from several clips on a frame-by-\n  frame basis.\n- :doc:`Loop <corefilters/loop>` Loops the segment from start frame to end frame a given number of\n  times.\n- :doc:`Reverse <corefilters/reverse>` This filter makes a clip play in reverse.\n- :doc:`SelectEven / SelectOdd <corefilters/select>` SelectEven makes an output video stream using only\n  the even-numbered frames\n- :doc:`SelectEvery <corefilters/selectevery>` SelectEvery is a generalization of filters like SelectEven and\n  Pulldown.\n- :doc:`SelectRangeEvery <corefilters/selectrangeevery>` This filters selects a range of frames with a certain\n  period.\n- :doc:`Trim <corefilters/trim>` Trims a video clip so that it includes only the frames first-frame\n  through last-frame.\n\n.. _Interlace filters:\n\nInterlace filters\n-----------------\n\nThese filters can be used for creating and processing field-based material\n(which is frame-based material separated into fields). AviSynth is capable of\ndealing with both progressive and interlaced material. The main problem is,\nthat it often doesn't know what it receives from source filters. This is the\nreason that the field-based flag exists and can be used when dealing with\ninterlaced material. More information about field-based video can be found\n:doc:`here <advancedtopics/interlaced_fieldbased>`.\n\n- :doc:`AssumeFrameBased / AssumeFieldBased <corefilters/parity>` Forces frame-based or field-based\n  material.\n- :doc:`AssumeTFF / AssumeBFF <corefilters/parity>` Forces field order.\n- :doc:`Bob <corefilters/bob>` Bob takes a clip and bob-deinterlaces it\n- :doc:`ComplementParity <corefilters/parity>` Changes top fields to bottom fields and vice-versa.\n- :doc:`DoubleWeave <corefilters/doubleweave>` The DoubleWeave filter operates like Weave, except that it\n  produces double the number of frames by combining both the odd and even pairs\n  of fields.\n- :doc:`PeculiarBlend <corefilters/peculiar>` This filter blends each frame with the following frame in a\n  peculiar way.\n- :doc:`Pulldown <corefilters/pulldown>` The Pulldown filter simply selects two out of every five frames\n  of the source video.\n- :doc:`SeparateColumns / SeparateRows <corefilters/separatefields>` Takes a clip and separates the columns or\n  rows of each frame into new frames.\n- :doc:`SeparateFields <corefilters/separatefields>` SeparateFields takes a frame-based clip and splits each\n  frame into its component top and bottom fields.\n- :doc:`SwapFields <corefilters/swapfields>` The SwapFields filter swaps the two fields in an interlaced\n  frame\n- :doc:`Weave <corefilters/weave>` Weave takes even pairs of fields from a Fields Separated input video\n  clip and combines them together to produce interlaced frames.\n- :doc:`WeaveColumns / WeaveRows <corefilters/weave>` Takes a clip and weaves sets of columns or rows\n  together to produce a composite frames.\n\n.. _Audio processing filters:\n\nAudio processing filters\n------------------------\n\nThese filters can be used to process audio. Audio samples from a clip will be\nautomatically converted if any filters requires a special type of sample.\nThis means that if a filter doesn't support the type of sample it is given,\nit will automatically convert the samples to something it supports. The\ninternal formats supported in each filter is listed in the sample type\ncolumn. A specific sample type can be forced by using the :doc:`ConvertAudio <corefilters/convertaudio>`\nfunctions.\n\nIf the sample type is float, when AviSynth has to output the data, it will be\nconverted to 16 bit, since float cannot be passed as valid AVI data.\n\n- :doc:`Amplify / AmplifydB <corefilters/amplify>` Amplify multiply audio samples by amount.\n- :doc:`AssumeSampleRate <corefilters/assumerate>` Adjusts the playback speed of the audio.\n- :doc:`AudioDub / AudioDubEx <corefilters/audiodub>` AudioDub takes the video stream from the first\n  argument and the audio stream from the second argument and combines them.\n  AudioDubEx is similar, but it doesn't throw an exception if both clips don't\n  have a video or audio stream.\n- :doc:`AudioTrim <corefilters/trim>` Trims an audio clip so that it includes only the start_time\n  through end_time.\n- :doc:`ConvertToMono <corefilters/converttomono>` Merges all audio channels.\n- :doc:`ConvertAudioTo8bit / ConvertAudioTo16bit / ConvertAudioTo24bit / ConvertAudioTo32bit /\n  ConvertAudioToFloat <corefilters/convertaudio>` Converts audio samples to 8, 16,\n  24, 32 bits or float.\n- :doc:`DelayAudio <corefilters/delayaudio>` DelayAudio delays the audio track by seconds seconds.\n- :doc:`EnsureVBRMP3Sync <corefilters/ensuresync>` Corrects out-of-sync mp3-AVI's, when seeking ot trimming.\n- :doc:`GetChannel <corefilters/getchannel>` Returns a channel from an audio signal.\n- :doc:`KillAudio <corefilters/killaudio>` Removes the audio from a clip completely.\n- :doc:`KillAudio <corefilters/killaudio>` Removes the video from a clip completely.\n- :doc:`MergeChannels <corefilters/mergechannels>` Merges channels of two or more audio clips.\n- :doc:`MixAudio <corefilters/mixaudio>` Mixes audio from two clips.\n- :doc:`Normalize <corefilters/normalize>` Amplifies the entire waveform as much as possible, without\n  clipping.\n- :doc:`ResampleAudio <corefilters/resampleaudio>` Performs a change of the audio sample rate.\n- :doc:`SSRC <corefilters/ssrc>` Performs a high-quality change of the audio sample rate. It uses SSRC\n  by Naoki Shibata, which offers the best resample quality available.\n- :doc:`SuperEQ <corefilters/supereq>` High quality 16 band sound equalizer.\n- :doc:`TimeStretch <corefilters/timestretch>` This filter can change speed of the sound without changing the\n  pitch, and change the pitch of a sound without changing the length of a\n  sound.\n- :doc:`SetChannelMask, GetChannelMask, IsChannelMaskKnown <corefilters/setchannelmask>` \n  This filter help you with setting and getting the audio channel layout of the audio stream.\n\n.. _Meta filters:\n\nMeta filters\n------------\n\nThese special filters can be used to control other filters execution.\n\n- :doc:`Animate / ApplyRange <corefilters/animate>` Animate (ApplyRange) is a meta-filter which evaluates\n  its parameter filter with continuously varying (the same) arguments.\n- :doc:`TCPDeliver <corefilters/tcpdeliver>` This filter will enable you to send clips over your network.\n  You can connect several clients to the same machine.\n\n.. _Conditional filters:\n\nConditional filters\n-------------------\n\nThe basic characteristic of conditional filters is that 'their scripts' are\nevaluated (executed) at every frame instead of the whole clip. This allows\nfor complex video processing that would be difficult or impossible to be\nperformed by a normal AviSynth script.\n\n- :doc:`ConditionalFilter / FrameEvaluate / ScriptClip / ConditionalSelect <corefilters/conditionalfilter>`\n  ConditionalFilter returns source1 if some condition is met, otherwise it\n  returns source2. ScriptClip/FrameEvaluate returns the clip which is returned\n  by the function evaluated on every frame. ConditionalSelect returns one frame\n  from several sources based on an integer evaluator.\n- :doc:`ConditionalReader <corefilters/conditionalreader>` ConditionalReader allows you to import information from\n  a text file, with different values for each frame - or a range of frames.\n- :doc:`WriteFile / WriteFileIf / WriteFileStart / WriteFileEnd <corefilters/write>` These filters\n  evaluate expressions and output the results to a text-file.\n\n.. _Debug filters:\n\nDebug filters\n-------------\n\n- :doc:`BlankClip / Blackness <corefilters/blankclip>` The BlankClip filter produces a solid color, silent\n  video clip of the specified length (in frames).\n- :doc:`ColorBars / ColorBarsHD <corefilters/colorbars>` The ColorBars filters produce a video clip\n  containing SMPTE color bars scaled to any image size.\n- :doc:`Compare <corefilters/compare>` Compares two clips and prints out information about the\n  differences.\n- :doc:`Echo <corefilters/echo>` Forces getframe calls to all input clips. Returns only first clip\n  result.\n- :doc:`Histogram <corefilters/histogram>` Adds a Histogram.\n- :doc:`Info <corefilters/info>` Prints out image and sound information.\n- :doc:`Preroll <corefilters/preroll>` Preroll the audio or video on non linear access.\n- :doc:`MessageClip <corefilters/message>` MessageClip produces a clip containing a text message\n- :doc:`ShowFiveVersions <corefilters/showfive>` ShowFiveVersions takes five video streams and combines\n  them in a staggered arrangement from left to right.\n- :doc:`ShowFrameNumber / ShowSMPTE / ShowTime <corefilters/showframes>` ShowFrameNumber draws text on every\n  frame indicating what number Avisynth thinks it is.\n  ShowSMPTE displays the SMPTE timecode. **hh:mm:ss:ff**\n  ShowTime displays the duration with millisecond resolution. **hh:mm:ss.sss**\n- :doc:`StackHorizontal / StackVertical <corefilters/stack>` StackHorizontal takes two or more video\n  clips and displays them together in left-to-right order.\n- :doc:`Subtitle <corefilters/subtitle>` The Subtitle filter adds a single line of anti-aliased text to a\n  range of frames.\n- :doc:`Tone <corefilters/tone>` This will generate sound.\n- :doc:`Version <corefilters/version>` The Version filter generates a video clip with a short version and\n  copyright statement\n\n$Date: 2013/01/06 13:38:34 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/externalplugins.rst",
    "content": "\nAvisynth 2.5 Selected External Plugin Reference\n===============================================\n\n.. _General info:\n\nGeneral info\n------------\n\nAviSynth plugins are external linked modules (libraries) implementing one or\nmore additional functions (filters) for deinterlacing, noise reduction, etc.\nA great number of plugins (200 or more) were written by independent developers\nas free software.\n\nAn up-to-date list of external plugins is available `here`_.\n\n$Date: 2015/03/15 22:10:10 $\n\n.. _here: http://avisynth.nl/index.php/External_filters"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/faq/faq.rst",
    "content": "\nAvisynth Frequently Asked Questions\n===================================\n\n**Remark**: a more recent version can be found\n`here <faq_sections.rst>`_ and at\n`<http://avisynth.nl/index.php/Main_Page>`__\n\nThe faq is divided into four sections: a general section, one related to\nframeserving, one related to filters and plugins, and one related to\nimporting VirtualDub filters. Recently, the old stuff \"related to\nAviSynth v2.06 and older versions\" is removed. Thus, if you have\nproblems, make sure that you install a more recent version of AviSynth.\n\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\n\nS1: About Avisynth\n------------------\n\nQ1.1: What is AviSynth?\n~~~~~~~~~~~~~~~~~~~~~~~\n\nA: AviSynth (AVI SYNTHesizer) is a frameserver. An excellent discription\nis given on `Lukes homepage <http://neuron2.net/LVG/avisynth.html>`__:\n\n\"AviSynth is a very useful utility created by Ben Rudiak-Gould. It\nprovides many options for joining and filtering videos. What makes\nAviSynth unique is the fact that it is not a stand-alone program that\nproduces output files. Instead, AviSynth acts as the \"middle man\"\nbetween your videos and video applications.\n\nBasically, AviSynth works like this: First, you create a simple text\ndocument with special commands, called a script. These commands make\nreferences to one or more videos and the filters you wish to run on\nthem. Then, you run a video application, such as VirtualDub, and open\nthe script file. This is when AviSynth takes action.  It opens the\nvideos you referenced in the script, runs the specified filters, and\nfeeds the output to video application. The application, however, is not\naware that AviSynth is working in the background.  Instead, the\napplication thinks that it is directly opening a filtered AVI file that\nresides on your hard drive.\n\nThere are five main reasons why you would want to use AviSynth:\n\n#. Join Videos: AviSynth lets you join together any number of videos,\n   including segmented AVIs. You can even selectively join certain\n   portions of a video or dub soundtracks.\n#. Filter Videos: Many video processing filters are built in to\n   AviSynth. For example, filters for resizing, cropping, and sharpening\n   your videos.\n#. Break the 2 GB Barrier: AviSynth feeds a video to a program rather\n   than letting the program directly open the video itself. Because of\n   this, you can usually use AviSynth to open files larger than 2 GB in\n   programs that don't natively support files of that size.\n#. Open Unsupported Formats: AviSynth can open almost any type of video,\n   including MPEGs and certain Quicktime MOVs. However, when AviSynth\n   feeds video to a program, it looks just like a standard AVI to that\n   program. This allows you to open certain video formats in programs\n   that normally wouldn't support them.\n#. Save Disk Space: AviSynth generates the video that it feeds to a\n   program on the fly. Therefore, no temporary or intermediate videos\n   are created. Because of this, you save disk space.\"\n\nQ1.2: Who is developing AviSynth?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n| A: AviSynth (up to v1.0b) is developed by Ben Rudiak-Gould, see\n  `<http://math.berkeley.edu/~benrg/avisynth.html>`__. \n| Ben stopped developing and Edwin van Eggelen continued, see\n  `<http://www.videotools.net/uk/download.php>`__.\n| His latest release is version v1.0b6 which can be found on Edwins\n  homepage given above.\n\nSome versions appeared on the AviSynth forum, for example `v1.0b7a by\nDivine <http://forum.doom9.org/showthread.php?s=&threadid=18243>`__ and\n`v1.0b7d by\nDividee <http://forum.doom9.org/showthread.php?s=&threadid=18243>`__.\n\nIn the beginning of July 2002 there was a `second revision\n(v2.0x) <http://sourceforge.net/projects/avisynth2/>`__ of the\nsourceforge project.  (In the `first sourceforge\nproject <http://sourceforge.net/projects/avisynth/>`__ didn't happen\nmuch.)\n\nThe most recent version is v2.5x series, weekly builds v2.5.0-2.5.5 by\nleading developer Klaus Post were\n`here <http://cultact-server.novi.dk/kpo/avisynth/avs_cvs.html>`__.\n\nThe main developer of AviSynth v2.5.6-2.5.7 is Ian Brabham (IanB). Many\nother people contributed to AviSynth. For partial list see (play)\n`Authors.avs <../../Examples/Authors.avs>`__ file. Official\n`memberlist <http://sourceforge.net/project/memberlist.php?group_id=57023>`__\nat sourceforge project:\n\n| Alex\\_e\\_Basta aka alex\\_e\\_basta (doc writer)\n| David Pierre aka bidoche (developer)\n| Frank Skare aka dolemite1 (developer)\n| Vincent TORRI aka doursse (developer)\n| Alexander Balakhnin aka fizick (doc writer)\n| Ian Brabham aka ianb1957 (developer, admin)\n| Jonathan Ernst aka jernst (doc writer)\n| kostarum (translator)\n| Cedric PAILLOT aka macpaille (doc writer)\n| Donald Graft aka neuron2 (project manager)\n| Richard Berg aka richardberg (project manager)\n| Klaus Post aka sh0dan (developer, admin)\n| Andrew Dunstan aka squid\\_80 (developer)\n| Tonny S Petersen aka tsp42 (developer)\n| Ernst Peche aka warpenterprises (doc writer)\n| Wilbert Dijkhof aka wilbertd (project manager, doc writer).\n\nAviSynth is free open source program distributed under GNU General\nPublic License as published by the Free Software Foundation.\n\nQ1.3: Where can I download the latest versions of AviSynth?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: See `Q1.2 <#q1-2-who-is-developing-avisynth>`__. It is also contained in the DVD2SVCD package\nand on the download page of Doom (these might be not be the newest\nversions of AviSynth).\n\nLatest versions of AviSynth can now be downloaded at `sourceforge\npage. <http://sourceforge.net/project/showfiles.php?group_id=57023>`__\n\nQ1.4: What are the main bugs in these versions?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: The latest versions:\n\n| v1.0b5: `Dissolve <corefilters/dissolve.rst>`__ doesn't work, BicubicResize doesn't work properly.\n| v1.0b6: ?\n| v1.0b7a/v1.0b7d: `Dissolve <corefilters/dissolve.rst>`__ doesn't work.\n| v2.01: ?\n| v2.02: `Layer <corefilters/layer.rst>`__ and `MergeChroma <corefilters/merge.rst>`__ don't work.\n| v2.05: `Loop <corefilters/loop.rst>`__ doesn't work when loading a clip without sound.\n| v2.07/v2.50: `SegmentedAviSource <corefilters/segmentedsource.rst>`__ doesn't load the avi's if the last empty segment isn't deleted.\n\n| v2.50 beta\n| v2.51 beta\n| v2.52\n\n| v2.58: `Known Issues 2.58 <http://avisynth.nl/index.php/Known_Issues_v2.58>`__.\n| v2.6: `Known Issues 2.6 <http://avisynth.nl/index.php/Known_Issues>`__.\n\nother bugs can be found in the documentation on the project page, see `Q1.5 <#q1-5-where-can-i-find-documentation-about-avisynth>`__.\n\nQ1.5: Where can I find documentation about AviSynth?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: Documentation about the filters of AviSynth can be found on this\nsite `<http://avisynth.nl/index.php/Main_Page>`__, and also\non the `filters <corefilters.rst>`__ page. For a tutorial on avisynth\nscripting, have a look at `this page <syntax.rst>`__. **You should read\nthese documents before posting to the forum** (but it's OK to post if\nyou have trouble understanding them).\n\nQ1.6: How do I install/uninstall AviSynth?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: In v2.05 or older versions: move avisynth.dll to your\nsystem/system32 directory and run install.reg. Starting from v2.06\nAviSynth comes with an auto installer. **Also make sure you have no\nother versions of AviSynth floating around on your harddisc, because\nthere is a change that one of those versions will be registered. Remove\nthem if necessary.** For uninstalling AviSynth go to \"program\",\n\"AviSynth 2\" and select \"Uninstall AviSynth\".\n\nQ1.7: Is there any difference between v1.0x, v2.0x or v2.5x?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: The versions v1.0x and v2.0x are compatible (the main difference is\nthat v2.0x doesn't contain IPCSource, while it contains other filters\nwhich are not present in v1.0x).  The main difference with v2.5x is that\nthe internal structure of AviSynth has changed (YV12 and multichannel\nsupport) with the consequence that **external plugins compiled for v1.0x\nor v2.0x will not work for v2.5x and vice versa**.\n\nQ1.8: Are plugins compiled for v2.5x compatible with v1.0x/v2.0x and vice versa?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: As explained in `Q1.7 <#q1-7-is-there-any-difference-between-v1-0x-v2-0x-or-v2-5x>`__ that is not the case.  However it\nis possible to use a v1.0x/v2.0x plugin in v2.5x, see `Q1.15 <#q1-15-how-do-i-use-a-plugin-compiled-for-v2-0x-in-v2-5x>`__.\n\nQ1.9: Which encoding programs support YV12?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: There are several options for encoding to DivX/XviD:\n\n#. There is a modified version (called VirtualdubMod) which has YV12\n   support:  This modification (by pulco-citron, Suiryc and Belgador)\n   has OGM and AVS-preview support.  It can be downloaded from\n   `here <http://sourceforge.net/projects/virtualdubmod>`__.  In order\n   to use the YV12 support (without doing any color conversions) you\n   have to load your AVI in VirtualdubMod and select \"**fast\n   recompress**\\ \".\n#. VirtualDub support YV12 starting from v1.5.6.  In order to use the\n   YV12 support (without doing any color conversions) you have to load\n   your AVI in VirtualDub and select \"**fast recompress**\\ \".\n#. For easy (and fast) YV12 support, you can also try out the new\n   commandline compressor: AVS2AVI, see also `Q1.21 <#q1-21-i-got-the-message-loadplugin-unable-to-load-xxx-is-not-an-avisynth-1-0-avisynth-2-5-plugin>`__.\n\n\nQ1.10: How do I use v2.5x if the encoding programs can't handle YV12 (like Virtualdub, TMPGEnc or CCE SP)?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: Using Virtualdub you have to add\n\"`ConvertToYUY2 <corefilters/convert.rst>`__\\ \" to your script or you\nhave to install a YV12 decompressor like DivX5 or one of the recent XviD\nbuilds of Koepi (`XviD-04112002-1 or\nnewer <http://roeder.goe.net/~koepi/xvid.shtml>`__).  Enabling \"fast\nrecompress\" implies that there will be a YV12 --> YUY2 --> YV12\nconversion.  (DivX3/4 also supports YV12, except that PIV users could\nexperience `crashes <http://www.divx-digest.com/software/divxcodec4.html>`__ when\nencoding to DivX4 in YV12.)\n\nUsing TMPGEnc you have to add the line\n`ConvertToRGB24 <corefilters/convert.rst>`__ to your script, and for CCE\nSP you need to add the line `ConvertToYUY2 <corefilters/convert.rst>`__\nto your script, since Windows has no internal YV12 compressor.  You can\nalso install DivX5 one of the recent XviD builds of Koepi\n(`XviD-04112002-1 or newer <http://roeder.goe.net/~koepi/xvid.shtml>`__)\nwhich will decompress the YV12-AVI for you when loading the avi in\nTMPGEnc or CCE SP.\n\nQ1.11: How do I use with AviSynth v2.5 with Gordian Knot?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n- If you are using GKnot 0.26 you have to rename mpeg2dec3.dll (the one\n  for AviSynth v2.5) to mpeg2dec.dll, and virtualdubmod.exe to\n  virtualdub.exe (keeping copies of the original exe and dll somewhere).\n\n- If you are using GKnot 0.27 you can follow the same procedure as\n  above, or you can enter mpeg2dec3.dll as an alternative mpeg2dec.dll in\n  the options menu and rename virtualdubmod.exe to virtualdub.exe.\n\n- But you can also try the new GKnot 0.28.\n\n| If you are using VirtualdubMod 1.4.13.1 older and experience problems,\n  download the latest\n  `prerelease <http://sourceforge.net/project/showfiles.php?group_id=65889&release_id=130443>`__.\n\nQ1.12: What are the main advantages and processing/encoding in YV12?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: There are two advantages:\n\n- speed increase:\n\n  It depends entirely on the external plugins whether they will have YV12\n  support or not.  If they have then speed increases like 25-35 percent are\n  expected.  Of course there will only be a large speed increase if both your\n  source and target are in YV12, for example in DVD to DivX/Xvid conversions.\n\n- no color conversions:\n\n  It depends entirely on the external plugins whether they will have YV12\n  support or not.  If they have then speed increases like 25-35 percent are\n  expected.  Of course there will only be a large speed increase if both your\n  source and target are in YV12, for example in DVD to DivX/Xvid conversions.\n\n\nQ1.13: Is there a command line utility for encoding to DivX/XviD using AviSynth?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: As explained in `Q1.9 <#q1-9-which-encoding-programs-support-yv12>`__ there is a command line utility\ncalled `AVS2AVI <http://forum.doom9.org/showthread.php?s=&threadid=36768>`__\n(and AVS2AVI GUI) for encoding to DivX/XviD using AviSynth.\n\nQ1.14: Where can I find VCF2AVS?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: VCF2AVS is a nice litte tool to convert vcf to avs files. You can\nedit your captures in vdub (basically cutting, cropping and resizing),\nthen edit the resulting avs. Be carefull since there are two versions\nfloating around:\n\n-  VCF2AVS by Darksoul71 which can be found\n   `here <http://forum.doom9.org/showthread.php?s=&threadid=41927>`__.\n\n-  VCF2AVS by BB (more basic) which can be found\n   `here <http://forum.doom9.org/showthread.php?s=&threadid=30587>`__.\n\nTry them both and look which one fullfills your needs :)\n\nQ1.15: How do I use a plugin compiled for v2.0x in v2.5x?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: In `WarpSharp-package for AviSynth v2.5x <#JapanesePlugin>`__ you\nwill find a plugin called \"LoadPluginEx.dll\". **When using an older\nversion of LoadPluginEx.dll, don't move this plugin to your plugin dir. \nBut move it to a separate dir, otherwise VirtualdubMod and WMP6.4 will\ncrash on exist.**  This will enable you using v2.0x plugins in v2.5x. \nAn example script (using the v2.0x plugin Dust by Steady):\n::\n\n    LoadPlugin(\"C:\\Program Files\\avisynth2_temp\\plugins\\LoadPluginEx.dll\")\n    LoadPlugin(\"C:\\Program Files\\avisynth2_temp\\plugins\\dustv5.dll\")\n\n    AviSource(\"D:\\clip.avi\").ConvertToYUY2\n    PixieDust(5)\n\n\nQ1.16: How do I switch between differents AviSynth versions without re-install?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA:\n\n-  You can use AvisynthSwitcher available\n   `here <http://www.lalternative.org>`__.  Versions 2.08 and 2.50 are\n   provided, but you can easily add a new one under\n   AvisynthSwitcher\\\\versions\\\\Avisynth 2.x.x.\n-  Some other ways are described\n   `here <http://forum.doom9.org/showthread.php?s=&threadid=45181>`__.\n\n\nQ1.17: How do I make an AVS-file?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: See `Q1.19 <#q1-19-how-do-i-know-which-version-number-of-avisynth-i-have>`__ (using the text editor you prefer).\n\nQ1.18: Where do I save my AVS-file?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: Anywhere on your harddrive.\n\nQ1.19: How do I know which version number of AviSynth I have?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: Open a text-editor, for example notepad. Add the following line\n\n  `Version <corefilters/version.rst>`__\n\nand save the file with the extension \"avs\".  Save for example as\nversion.avs (make sure that the extension is \"avs\" and not \"txt\").  Open\nthe file in an application which can read AVI-files, for example WMP\n6.4. The version number will be displayed.\n\nQ1.20: Does AviSynth have a GUI (graphical user interface)?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: Several nice tools are available:\n\n- VirtualdubMod, see also `Q1.9 <#q1-9-which-encoding-programs-support-yv12>`__.  Regarding to AviSynth the\n  following utilities are added:\n\n  - 'Open via AVISynth' command. This allows you to open any AviSynth\n    compatible video file by automatically generating a suitable script by a\n    selectable template.\n\n  - AVS Editor (Hotkey Ctrl+E): Just open your AVS and under tools select\n    \"script editor\". Change something and press F5 to preview the video.\n\n- `AvisynthEditor, an advanced AviSynth script editor featuring syntax highlighting,\n  auto-complete code and per versions plugin definitions files. Here is a\n  `screenshot <http://web.archive.org/web/20100617104422/http://www.lalternative.org/img/AvisynthEditor.gif>`__.  It\n  can be found `here <http://web.archive.org/web/20100810100731/http://www.lalternative.org/>`__.  Discussion can be\n  found on `Doom9.org\n  forum <http://forum.doom9.org/showthread.php?s=&threadid=49487>`__.\n\n- `AVSGenie <http://www.yeomanfamily.demon.co.uk/avsgenie/avsgenie.rst>`__:\n  AVSGenie allows the user to select a filter from a drop down list or\n  from a popup menu. An editable page of parameters will then be brought\n  into view, with a guide to the filter and it's parameters. A video\n  preview window opens, showing \"source\" and \"target\" views.  The source\n  window, in simple cases, shows output of the first line of the script,\n  generally an opened video file. The target window shows the output of\n  the whole script. In this way, effects of filters can easily be seen.\n  The line which represents the source window can be changed.  Discussion\n  can be found\n  `here <http://forum.doom9.org/showthread.php?s=&threadid=54090>`__.\n\n- `SwiftAVS (by Snollygoster) <http://www.swiftavs.net>`__: Another nice\n  gui, formerly known as AviSynthesizer.\n  [`discussion <http://forum.doom9.org/showthread.php?s=&threadid=48326>`__\\ ]\n\nQ1.21: I got the message \"LoadPlugin: unable to load \"xxx\" is not an AviSynth 1.0/AviSynth 2.5 plugin\"?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: You are using a plugin which is not compatiable with that version\nof AviSynth.  Have a look at `Q1.8 <#q1-8-are-plugins-compiled-for-v2-5x-compatible-with-v1-0x-v2-0x-and-vice-versa>`__.\n\nQ1.22: How do I know which colorspace I'm using at a given place in my script?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: To see which colorspace you are using at a given place in your\nscript, add:\n\n  `Info <corefilters/info.rst>`__\n\n... and AviSynth will give you much information about colorspace\namongst other things!\n\nQ1.23: I installed AviSynth v2.5 and DivX5 (or one of the latest Xvid builds of Koepi), all I got is a black screen when opening my avs in Virtualdub/!VirtualdubMod/CCE/TMPGEnc?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: Ok, apperently your video is not decompressed by DivX5 (or XviD).  Go\nto your windows-dir and rename a file called MSYUV.DLL, or add the\nfollowing to your registry file:\n::\n\n    REGEDIT4\n\n    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32]\n    \"VIDC.YV12\"=\"divx.dll\"\n\nReplace \"divx.dll\" by \"xvid.dll\" for XviD.\n\nQ1.24: My computer seems to crash at random during a second pass in any encoder?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA : AviSynth (especially v2.5x) is highly optimized. As a consequence\nit is possible that your computer seems to crash at random during a\nsecond pass. Try running the\n[`Prime95 <http://www.mersenne.org/freesoft.rst>`__\\ ] stress test for\nan hour, to check if your system is stable. If this test fails (or your\ncomputer locks up) make sure that your computer is not overclocked and\nlower your bus speed of your processor in steps of (say) five MHz till\nthe crashes are gone.\n\nQ1.25:VirtualdubMod, WMP6.4, CCE and other programs crash every time on exit (when previewing an avs file)?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: This problem arises if you got an older version of LoadPluginEx.dll\n(or WarpSharp.dll) of the WarpSharp package in your plugin dir. The\nsolution is to move it outside the plugin directory and load it\nmanually. I hope that the maker of this plugin also noticed this ...\n\nQ1.26: Are there any lossless YV12 codecs, which I can use for capturing for example?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: There are several of them:\n\n#. `VBLE codec (by MarcFD) <http://forum.doom9.org/showthread.php?s=&threadid=38389&pagenumber=5>`__:\n   an huffyuv based encoder\n#. `LocoCodec (by TheRealMoh) <http://forum.doom9.org/showthread.php?s=&threadid=50363>`__\n#. `MJPEG codec <http://forum.doom9.org/showthread.php?s=&threadid=48504>`__:\n   Leaves a small logo in the right upper side of the clip.\n\n\nS2: AviSynth and frameserving\n-----------------------------\n\nQ2.1: What is frameserving and what is it good for?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: An excellent discription is found on `Lukes\nhomepage <http://neuron2.net/LVG/frameserving.html>`__:\n\n\"Frameserving is a process by which you directly transfer video data\nfrom one program on your computer to another. No intermediate or\ntemporary files are created. The program that opens the source file(s)\nand outputs the video data is called the frameserver. The program that\nreceives the data could be any type of video application.\n\nThere are two main reasons that you would want to frameserve a video:\n\n#. Save Disk Space:\n\n   Depending the on the frameserving application, you can usually edit/process\n   your video as it is being frameserved. Because frameserving produces no\n   intermediate files, you can use a frameserver to alter your videos without\n   requiring any additional disk space. For example, if you wanted to join two\n   video files, resize them, and feed them to another video application,\n   frameserving would allow you to do this without creating a large intermediate\n   file.\n\n#. Increased Compatibility:\n\n   To the video application that's receiving the frameserved video, the input\n   looks like a relatively small, uncompressed video file. However, the source\n   file that the frameserver is transferring could actually be, for example, a\n   highly compressed MPEG-1 video. If your video application doesn't support\n   MPEG-1 files, it's not a problem because the application is just receiving\n   standard uncompressed video from the frameserver. This feature of\n   frameserving enables you to open certain types of files in an application\n   that wouldn't normally support them.\n\n\nFurthermore, because the video application is being fed the source\nvideo one frame at a time, it doesn't know anything about the file size\nof the source video. Therefore, if your application has 2 GB or 4 GB\nlimit on input file size, it won't have any effect on your frameserved\nvideo. You could feed 100 GB of video via a frameserver to an\napplication limited to 2 GB and it wouldn't cause a problem.\"\n\nQ2.2: How do I use AviSynth as a frameserver?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: Write a script using a text editor. Load your clip (see\n`Q2.8 <#q2-8-how-do-i-load-my-clip-into-avisynth-video>`__) in AviSynth, do the necessary filtering and load the\nAVS-file in encoder/application X (must be an encoder or application\nwhich can read AVI-files, see `Q2.3 <#q2-3-how-do-i-frameserve-my-avs-file-to-encoder-application-x>`__ and `Q2.4 <#q2-4-problems-when-encoder-x-reads-avs-files>`__).\n\nQ2.3: How do I frameserve my AVS-file to encoder/application X?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA:\n\n- Frameserving to TMPGEnc, CCE SP, VirtualDub or WMP6.4:\n\n  Just open your AVS-file in TMPGEnc, CCE SP, VirtualDub or WMP6.4 (or whatever\n  encoder/application you use) and have a look at `Q2.4 <#q2-4-problems-when-encoder-x-reads-avs-files>`__.\n\n\n- Frameserving to VFAPI:\n\n  For VFAPI you need to install the `ReadAVS <http://www.vcdhelp.com/forum/userguides/87270.php>`__ plugin. Just copy ReadAVS.dll to\n  the VFAPI reader directory and open the reg-file ReadAVS.reg in notepad and\n  change the corresponding path. Save it, and doubleclick on it to merge it\n  with your registry-file.\n\n- Frameserving to Premiere or Ulead:\n\n  - For frameserving to Premiere there exists an import plugin\n    \"IM-Avisynth.prm\". The original version can be downloaded from `Bens\n    site <http://math.berkeley.edu/~benrg/avisynth-premiere.html>`__. A\n    much improved version can be downloaded from the [`Video Editors Kit\n    sourceforge\n    page <http://sourceforge.net/projects/videoeditorskit/>`__\\ ]. This\n    works for Premiere 5.x,6.x and Pro at present. To install the import\n    plugin move the IM-Avisynth.prm file into your Premiere \"Plug-ins\"\n    directory.\n  - You can also download a program called [`makeAVIS (included in the\n    ffvfw codec\n    package <http://cultact-server.novi.dk/kpo/avisynth/avs_cvs.html>`__\\ ]\n    (this is an AVI Wrapper),\n    [`discussion <http://forum.doom9.org/showthread.php?s=&threadid=49964>`__\\ ].\n    Note that this program is included in the installation of AviSynth\n    v2.52. For Ulead you must use this program.\n\n- Frameserving to Windows Media 9 Encoder:\n\n  Download Nic's Windows Media 9 Encoder and make sure you also\n  installed the Windows Media 9 codec. Both can be found\n  `here <http://nic.dnsalias.com/WM9Enc.html>`__.\n\n.. _Problems when Encoder X reads AVS-files:\n\nQ2.4: Problems when Encoder X reads AVS-files?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA:\n\n*Why can't I open my AVS-file in TMPGEnc (this happens in old versions\nof TMPGEnc)?*\n\n-  Install VFAPI plugin for TMPGEnc\n-  Disable the direct show filters within TMPGEnc and turn off the\n   VirtualDub proxy before frameserving.\n\n-  Add \"`ConvertToRGB24 <corefilters/convert.rst>`__\\ ()\" at the end of\n   your AVS-file\n-  Install\n   `Huffyuv <http://avisynth.nl/index.php/Huffyuv>`__/`DivX5 <http://avisynth.nl/index.php/DivX>`__\n   codec so that it can do the decompression for you when loading an AVI\n   in TMPGEnc.\n-  Install the\n   `ReadAVS <http://www.dvdrhelp.com/forum/userguides/87270.php>`__\n   plugin for TMPGEnc\n\n*CCE SP crashes when reading an AVS-file, what to do?*\n\n-  If you're using Win2k then run CCE in WinNT4-SP5 compatibility mode.\n-  If you're frameserving with AviSynth v1.0x/v2.0x put\n   \"`ResampleAudio <corefilters/resampleaudio.rst>`__\\ (44100)\" in your\n   script, even if you don't have any audio in your AVS-file.\n-  If you're frameserving with AviSynth v2.5x the ResampleAudio trick\n   doesn't work anymore because it doesn't add a silent audio stream to\n   your video clip.  Instead make a script (called \"addaudio.avsi\") as\n   described `here <http://avisynth.nl/index.php/AddAudio>`__,\n   and put it in your plugin dir.\n\n*Encoders/players (like CCE SP v2.62/v2.64) will not read AVS-files ?*\n\nMany \"new\" programs do NOT use the Windows functions to read the\nAVI-files. If they do NOT use those standard Windows functions the\nAviSynth-script files will not work. Known programs that do NOT use\nthose routines are CCE SP v2.62, Windows Media Encoder vx.x. Furthermore\npeople report problems with Windows Media Player 7.\n\n-  Use CCE SP v2.50 and WMP6.4 (under \"Program Files\" and \"Windows Media\n   Player\" you will find a file called \"mplayer2.exe\", this is WMP6.4).\n   In case that you want to use Windows Media Encoder you can use the\n   AVI Wrapper \"makeAVIS\" instead, see\\ `Q2.3 <#q2-3-how-do-i-frameserve-my-avs-file-to-encoder-application-x>`__. For Windows\n   Media Encoder 9 have a look at `Q2.3 <#q2-3-how-do-i-frameserve-my-avs-file-to-encoder-application-x>`__.\n-  If you still want to use CCE SP v2.62 you can try the following:\n   Frameserve to CCE SP v2.62 with VFAPI. Create an AVS script and then\n   make a fake AVI with VFAPI (VFAPI accepts AVS-files, see\n   `Q2.3 <#q2-3-how-do-i-frameserve-my-avs-file-to-encoder-application-x>`__, and can be downloaded from Dooms site).\n-  Cinemacraft says that their CCE SP v2.66 can accept AviSynth\n   scripts.  So if you have this version you sould be safe.\n\n*Wrong YUY2 Codec causes colorspace errors on AviSynth scripts feeding\nTMPGEnc?*\n\nSome time ago I suddenly found that feeding TMPGEnc with an AviSynth\nscript resulted in what looked like a colorspace conversion error; as if\nthe video had been badly dithered down from 24 bit to 8 bit! (..)\n\nIf you have such problems add\n\"`ConvertToRGB24 <corefilters/convert.rst>`__\\ \" as the last line of\nyour script or have a look at the thread (and the suggested solutions)\n`colorspace conversion\nerrors <http://forum.doom9.org/showthread.php?s=&threadid=27932>`__.\n\nQ2.5: How do I frameserve from Premiere/Ulead/Vegas to AviSynth?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: You can try the AviSynth compatible frameserver (import) for\n[`PluginPace frameserver (by Satish Kumar) <http://www.debugmode.com/pluginpac/frameserver.php>`__\\ ]:\nFor frameserving from SonicFoundry Vegas (and earlier Vegas Video/VideoFactory? versions),\nAdobe Premiere or Ulead MediaStudio Pro to AviSynth.\n[`discussion <http://forum.doom9.org/showthread.php?s=&threadid=51242>`__\\ ].\n\nQ2.6: When frameserving I got the following message: \"Script error, there is no function named \"xxx (the name of some filter)\"\"?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: You probably installed/registered a version of AviSynth which\ndoesn't contain the filter.  Make sure that there are no other versions\nfloating around on your hard disc (there's a possibility that a version\nwill be registered while it is not in your system directory).  Check\nwhether the correct version is registered, see also `Q1.19 <#q1-19-how-do-i-know-which-version-number-of-avisynth-i-have>`__.\n\nQ2.7: I get an unrecognized exception error trying to load an avs file with VirtualDub, using dvd2avi v1.77.3?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: .d2v created with dvd2avi v1.77.3 is NOT compatible with\nmpeg2dec.dll! Use v1.76 instead. If you still want to use v1.77.3, make\nsure that you have AviSynth v2.5 installed and mpeg2dec3.dll v1.07 (or a\nmore recent version).\n\nQ2.8: How do I load my clip into AviSynth (video)?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: Make a script containing the lines (replace the filename and the\npath of the filename):\n\n1. AVI-files (with uncompressed WAV, or CBR/VBR MP3-audio (starting from v2.04)):\n\n::\n\n    AviSource(\"d:\\filename.avi\")\n\n    or disabling the audio:\n\n    AviSource(\"d:\\filename.avi\", false)\n\n2. AVI-files that AVISource doesn't support (for example \"DV type I AVI-files\"):\n\n::\n\n    DirectShowSource(\"d:\\filename.avi\")\n    DirectShowSource(\"d:\\\\filename.mpg\")\n\n\n3. Have a look at the `Mpeg decoder plugins for AviSynth v1.0x/v2.0x <#MpegDecoders>`__\n   and the `Mpeg decoder plugins for AviSynth v2.5x <#MpegDecoders2>`__:\n\n   Using AviSynth v2.0x/AviSynth v2.5x and MPEGdecoder.dll:\n\n::\n\n    LoadPlugin(\"d:\\MPEGdecoder.dll\")\n    mpegsource(\"d:\\filename.mpg\")\n\n4. MPEG2-files (extension m2p or m2v):\n\n   Have a look at the `Mpeg decoder plugins for AviSynth v1.0x/v2.0x <#MpegDecoders>`__\n   and the `Mpeg decoder plugins for AviSynth v2.5x <#MpegDecoders2>`__. Some examples:\n\n- Using AviSynth v2.0x and mpeg2dec.dll:\n\n  Make a DVD2AVI project file and save it (filename.d2v) and load this clip into AviSynth:\n\n::\n\n    LoadPlugin(\"d:\\mpeg2dec.dll\")\n    mpeg2source(\"d:\\filename.d2v\")\n\n- Using AviSynth v2.5x and MPEGdecoder.dll:\n\n::\n\n    LoadPlugin(\"d:\\MPEGdecoder.dll\")\n    mpegsource(\"d:\\filename.m2p\")\n\n    or (only the video stream)\n\n    LoadPlugin(\"d:\\MPEGdecoder.dll\")\n    mpegsource(\"d:\\filename.m2v\", -2, \"raw\")\n\n5. VOB-files:\n\n   Have a look at the `Mpeg decoder plugins for AviSynth v1.0x/v2.0x <#MpegDecoders>`__\n   and the `Mpeg decoder plugins for AviSynth v2.5x <#MpegDecoders2>`__. Some examples:\n\n- Using AviSynth v2.0x and mpeg2dec.dll:\n\n  Make a DVD2AVI project file and save it (filename.d2v) and load this clip into AviSynth:\n\n::\n\n    LoadPlugin(\"d:\\mpeg2dec.dll\")\n    mpeg2source(\"d:\\filename.d2v\")\n\n- Using AviSynth v2.5x and MPEGdecoder.dll:\n\n::\n\n    LoadPlugin(\"d:\\MPEGdecoder.dll\")\n    mpegsource(\"d:\\filename1.vob+d:\\filename2.vob\")\n\n6. ATSC transport streams (extension ``*.trp`` or ``*.ts``):\n\n-  Using AviSynth v2.0x:\n\n   Download mpeg2dec2 and a special version of `dvd2avi <http://www.trbarry.com/DVD2AVIT3.zip>`__.  Don't forget to\n   specify the video and audio pid's in the DVD2AVI.ini file:\n\n::\n\n    LoadPlugin(\"d:\\mpeg2dec2.dll\")\n    mpeg2source(\"d:\\filename.d2v\")\n\n-  Using AviSynth v2.0x/v2.5x:\n\n   Download mpeg2dec3 or mpegdecoder and a special version of `dvd2avi <http://www.trbarry.com/DVD2AVIT3.zip>`__:\n\n::\n\n    LoadPlugin(\"d:\\mpeg2dec3.dll\")\n    mpeg2source(\"d:\\filename.d2v\")\n\n    or if you want to used mpegdecoder:\n\n    LoadPlugin(\"d:\\mpegdecoder.dll\")\n    mpegsource(\"d:\\filename.d2v\")\n\nIf both methods fail you can try `HDTV2MPEG2 <http://www.avsforum.com/avs-vb/attachment.php?s=&postid=1408610>`__ (produces non dvd compliant\nmpeg2 files) to create a temporary mpeg2 file and import that in AviSynth\nwith dvd2avi. For demuxing AAC audio: use [`TSDemux <http://www.avsforum.com/avs-vb/showthread.php?s=&threadid=222055>`__]. The Moonlight\n`Xmuxer <http://www.moonlight.co.il/download/?dl=xmuxer>`__ package has also a bunch of DirectShow filters that deal with\nmuxing and demuxing MPEG-1/2 TS and PVA files.\n\n7. PVA transport streams:\n\n   You are out of luck here.  AFAIK the only options are PVAStrumento and\n   `Xmuxer <http://www.moonlight.co.il/download/?dl=xmuxer>`__.\n\n8. d2v-files (DVD2AVI frameserver files):\n\n::\n\n    LoadPlugin(\"d:\\mpeg2dec.dll\")\n    mpeg2source(\"d:\\filename.d2v\")\n\n9. vdr-files (VirtualDubs frameserver files):\n\n::\n\n    AVISource(\"d:\\filename.vdr\")\n\n10. ASF-files (the framerate has to be specified, right click on the file in windows explorer):\n\n::\n\n    DirectShowSource(\"d:\\filename.asf\", fps=15)\n\n11. tpr-files (TMPGEnc project files):\n\n    First note that the plugin GreedyHMA is proving to be a better IVTC\n    solution (not to mention *MUCH* easier) than TMPGEnc. So if you want\n    to use TMPGEnc for this get the GreedyHMA plugin (this plugin works in\n    YUV-space).\n\n    If you still want to import a tpr-file into an AVS-file, there are two\n    possibilities:\n\n- The TMPGEnc plugin is contained in the VFAPI Plugin zip file (ends\n  with -vfp.zip) which can be download from Dooms site. (This method\n  doesn't always work, some encoders like CCE SP can't read them.)\n\n::\n\n    LoadVFAPIplugin(\"d:\\TMPGenc.vfp\",\"TMPGsource\")\n    TMPGsource(\"d:\\filename.tpr\")\n    FlipVertical\n\n- Import the tpr-file in VFAPI, create a fake avi and then load it into\n  AviSynth (note that VFAPI works in RGB-space). See also\n  `<http://forum.doom9.org/showthread.php?s=&threadid=10007>`__.\n\n12. aup-files (AviUtl projects)\n\n    I don't know if it is possible to load it directly into AviSynth.\n    Import the aup-file in VFAPI, create a fake avi and then load it into\n    AviSynth (note that VFAPI works in RGB). See also\n    `<http://forum.doom9.org/showthread.php?s=&threadid=10007>`__.\n\n13. QuickTime-files (see `<http://forum.doom9.org/showthread.php?s=&threadid=23139>`__):\n\n    Use DirectShowSource:\n\n::\n\n    DirectShowSource(\"d:\\filename.mov\")\n\n    or if that doesn't work download a plugin (can be found in Dooms download section):\n\n    LoadVFAPIPlugin(\"C:\\QTReader\\QTReader.vfp\", \"QTReader\")\n    QTReader(\"C:\\quicktime.mov\")\n\n14. AVS-files:\n\n    Just import it at the beginning of your script:\n\n::\n\n    Import(\"d:\\filename.avs\")\n\nIn v2.05 or more recent version you can use the autoplugin loading. \nJust move your AVS-file in the plugindir containing the other (external)\nplugins, and rename (since v.2.08, v2.5) the extension to 'avsi'.  See\nalso `Q5.2 <#q5.2>`__.\n\n\nQ2.9: How do I load my clip into AviSynth (audio)?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: This can be done in several ways:\n\n1. Using AviSource (with uncompressed WAV, CBR/VBR MP2-audio (starting\n   from v2.04) or CBR/VBR MP3-audio (starting from v2.04)):\n\n::\n\n    AviSource(\"d:\\filename.avi\")\n\n    Starting from v2.05 you can extract audio from a AVI-file in this way:\n\n    WavSource(\"d:\\filename.avi\")\n\n2. Use the audio decoder plugin MPASource, see `Q3.4 <#q3-4-where-can-i-download-external-filters-for-avisynth-v1-0x-v2-0x>`__ and\n   `Q3.5 <#q3-5-where-can-i-download-external-filters-for-avisynth-v2-5x>`__ for importing mp1/mp2/mp3 audio.\n3. See `DirectShowSource <corefilters/directshowsource.rst>`__ for\n   downmixing AC3 audio.\n4. Put a WAV-header on your\n   `mp2 <http://www.geocities.wilbertdijkhof/mpa2wav.zip>`__ or mp3\n   (with Besweet) audio file and use WavSource to import the audio.  You\n   also need ACM codecs for\n   `mp2 <http://www.geocities.wilbertdijkhof/qmpeg_mp2.zip>`__, and for\n   mp3 (Radium codec, see doom's download section).  Use WavSource to\n   load the WAV:\n\n::\n\n    WavSource(\"d:\\filename.wav\")\n\nUp to v2.07 the audio must be mono or stereo.  Starting from v2.5 you\ncan also import uncompressed multichannel audio.\n\nQ2.10: Can I import an audio file other than a WAV-file?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: Yes:\n\n-  Uncompressed audio files (that is uncompressed WAV-files) can be\n   loaded in all versions up to v2.03.\n-  Starting from v2.04 compressed WAV-files can be loaded (currently\n   only MP2/MP3-files with a WAV-header).\n-  Starting from v2.5 you can also load uncompressed multichannel audio.\n-  Using the MPASource and AC3filter plugins you can import mp1/mp2/mp3\n   and AC3 audio.\n\n| See also `Q2.9 <#q2-9-how-do-i-load-my-clip-into-avisynth-audio>`__.\n|  \n\nQ2.11: How do I join video and audio?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: Make an avs-file containing the lines (change the filenames and paths):\n::\n\n    video = AviSource(\"d:\\filename1.avi\")\n    audio = WavSource(\"d:\\filename2.wav\")\n    AudioDub(video, audio)\n\nQ2.12:  I get an unrecognized exception in the line where I use DirectShowSource?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: Have you got VobSub installed? Have a look at this\n`thread <http://forum.doom9.org/showthread.php?s=&threadid=34350>`__.\nUpgrade to VobSub v2.20 or higher. If someone has an explanation, please\npost it in the thread.\n\nS3: Filters and colorspaces\n---------------------------\n\nQ3.1: What is RGB/YUV-colorspace?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: These are two different ways to represent colors: YUV colorspace and\nRGB colorspace.  In YUV colorspace there is one component that represent\nlightness (luma) and two other components that represent color\n(chroma).  As long as the luma is conveyed with full detail, detail in\nthe chroma components can be reduced by subsampling (filtering, or\naveraging) which can be done in several ways (thus there are multiple\nformats for storing a picture in YUV colorspace).  In RGB colorspace\nthere are three components, one for the amount of Red, one for the\namount of Green and one for the amount of Blue.  Also in the colorspace\nthere are multiple formats for storing a picture which differ in the\namount of samples are used for one of the three colors.\n\nInformation can be found here: `YUV\nFormats <http://www.fourcc.org/fccyuv.rst>`__, `RGB\nFormats <http://www.fourcc.org/fccrgb.rst>`__, `MSDN YUV\nFormats <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/YUVFormats.asp>`__\nand `Chroma subsampling by Charles\nPoyton <http://www.inforamp.net/~poynton/PDFs/Chroma_subsampling_notation.pdf>`__.\n\nAs of AviSynth v1.0x/v2.0x, RGB24, RGB32, and YUY2 are supported.  In\nAviSynth v2.5x there is also support for YV12.\n\nQ3.2: In which colorspaces do AviSynth and the internal filters work?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: AviSynth works in RGB and YUV using the RGB32, RGB24, YUY2 and YV12\nformats.  Most of the internal filters work in any of these formats,\ntoo. Which color format a filter requires, can be found\n[`here <quick_ref.rst>`__].\n\nQ3.3: How do I load a plugin in to AviSynth?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: Starting from v2.05 you can use its auto-plugin loading feature. The\npath of the plugin directory is set during install. But if you want to\nchange it for some reason, change or add the following lines:\n::\n\n    REGEDIT4\n\n    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Avisynth]\n    \"PluginDir\"=\"c:\\\\program files\\\\avisynth 2.5\\\\plugins\"\n\nChange the path above if necessary and make sure you created the\nplugin-dir as well. Save it as install\\_autoplugin.reg, and merge it to\nyour registry file by right-clicking on it in your explorer. Finally\nmove all your plugins/script-functions into the plugin directory. If you\nwant to load plugins manually, use \"LoadPlugin\". An example script:\n::\n\n    LoadPlugin(\"d:\\mpeg2dec.dll\")\n    mpeg2source(\"d:\\filename.d2v\")\n\nQ3.4: Where can I download external filters for AviSynth v1.0x/v2.0x?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: Most of them can be found in the AviSynth section at Doom9. But below\nyou will find links to most of them. If you know of a plugin which is\nmissing, please feel free to add it to the list using the \"Edit this\ndocument\" link to the left. Most of these plugins work in YUY2. If you\ncan't find the plugin (the attachments are still disabled), you can\ndownload the plugins at\n[`WarpEnterprises <http://www.avisynth.nl/users/warpenterprises/>`__]\nhomepage.\n\n| **Deinterlacing & Pulldown Removal:**\n| *All PAL, NTSC, and SECAM video is interlaced, which means that only\n  every other line is broadcast at each refresh interval.  Deinterlacing\n  filters let you take care of any problems caused by this. IVTC (inverse\n  telecine, aka pulldown removal) filters undo the telecine process, which\n  comes from differences between the timing of your video and its original\n  source.*\n\n#. `Decomb Filter package (by Donald\n   Graft) <http://neuron2.net/mine.html>`__: This package of plugin\n   functions for AviSynth provides the means for removing combing\n   artifacts from telecined progressive streams, interlaced streams, and\n   mixtures thereof. Functions can be combined to implement inverse\n   telecine for both NTSC and PAL streams. *[YUY2]*\n#. `ViewFields/UnViewFields (by Simon\n   Walters) <http://www.geocities.com/siwalters_uk/fnews.html>`__:\n   ViewFields and UnViewFields are a complementary pair of filters to\n   display and identify top and bottom fields from an interlaced source.\n   *[YUY2]*\n#. `GreedyHMA plugin (by Tom\n   Barry) <http://www.trbarry.com/GreedyHMA.zip>`__: DScaler's Greedy/HM\n   algorithm code to perform pulldown matching, filtering, and video\n   deinterlacing. *[YUY2]*\n#. `Motion compensated deinterlace filter \"TomsMoComp\" (by Tom\n   Barry) <http://forum.doom9.org/showthread.php?s=&threadid=28778>`__:\n   This filter uses motion compensation and adaptive processing to\n   deinterlace video source (not for NTSC film). *[YUY2]*\n#. `SmoothDeinterlacer (by Gunnar Thalin, ported to AviSynth by\n   Xesdeeni) <http://home.bip.net/gunnart/video/AVSPorts/SmoothDeinterlacer/>`__:\n   A port of the VirtualDub [Smooth Deinterlacer] filter. *[YUY2, RGB]*\n#. IVTC plugin v2.2 (by \"Wizard\\_FL\", Dooms download section): This\n   plugin reverses the telecine process. *[YUY2]*\n#. `\"IT\" (by\n   thejam79) <http://members.tripod.co.jp/thejam79/IT_0051.zip>`__:\n   Inverse telecine plugin. `Translation of\n   README <http://avisynth.nl/index.php/IT>`__\n#. `\"AntiComb\" (by\n   ?) <http://www.geocities.co.jp/SiliconValley-Sunnyvale/3109/acomb05.zip>`__:\n   This filter remove combing (interlace artifacts). `Translation of\n   README <https://web.archive.org/web/20050317011825/http://www.avisynth.org/index.php?page=AntiComb>`__\n#. See also Auto24FPS and AutoDeint in the\n   `MiscPlugins <#MiscellaneousPlugins>`__ section below.\n\n| **Spatio-Temporal Smoothers:**\n| *These filters use color similarities and differences both within and\n  between frames to reduce noise and improve compressed size.  They can\n  greatly improve noisy video, but some care should be taken with them to\n  avoid blurred movement and loss of detail.*\n\n#. `PeachSmoother (by Lindsey\n   Dubb) <http://students.washington.edu/ldubb/computer/PeachSmoother.zip>`__:\n   An adaptive smoother optimized for TV broadcasts:\n   `documentation <http://students.washington.edu/ldubb/computer/Read_Me_Peach_Smoother.rst>`__;\n   `discussion <http://forum.doom9.org/showthread.php?s=&threadid=36575>`__.\n   The Peach works by looking for good pixels and gathering orange smoke\n   from them. When it has gathered enough orange smoke, it sprinkles\n   that onto the bad pixels, making them better. Works only on computers\n   with SSE instructions (Athlons, Pentium 3 or 4, recent Celerons, or\n   later). *[YUY2]*\n#. `\"MAM\" (by Marc\n   FD) <http://ziquash.chez.tiscali.fr/%20Motion%20Adaptive%20Mixer>`__:\n   This filter uses movement detection to adapt the denoising method\n   used, in still areas it uses temporal filtering and in moving areas\n   it uses spatial filtering with any spatial and temporal filter you\n   want.  It is no longer developed but it can temporarily be downloaded\n   from this\n   `site <http://forum.doom9.org/showthread.php?s=&postid=193412>`__.\n   *[YUY2]*\n#. `NoMoSmooth (by\n   SansGrip) <http://www.jungleweb.net/~sansgrip/avisynth/>`__: A motion\n   adaptive spatio-temporal smoother:\n   `documentation <http://www.jungleweb.net/~sansgrip/avisynth/NoMoSmooth-readme.html>`__;\n   `discussion <http://forum.doom9.org/showthread.php?s=&threadid=37471>`__.\n   *[YUY2]*\n#. `Dust (by\n   Steady) <http://forum.doom9.org/showthread.php?s=&threadid=42749>`__:\n   A noise remover. *[YUY2, RGB]*\n#. `SpatioTemporal Median Filter \"STMedianFilter\" (by Tom\n   Barry) <http://www.trbarry.com/STMedianFilter.zip>`__: STMedianFilter\n   is a (slightly motion compensated) spatial/temporal median filter.\n   Bug: strange color changes (clip becomes purple) *[YUY2]*\n#. `Convolution3D (by Vlad59) <http://hellninjacommando.com/con3d/>`__:\n   Convolution3D is a spatio-temporal smoother, it applies a 3D\n   convolution filter to all pixels of consecutive frames. *[YUY2]*\n\n| **Spatial Smoothers:**\n| *These use color similarities and differences within a frame to\n  improve the picture and reduce compressed size. They can smooth out\n  noise very well, but overly aggressive settings for them can cause a\n  loss of detail.*\n\n#. `Masked Smoother \"msmooth\" (by Donald\n   Graft) <http://forum.doom9.org/showthread.php?s=&threadid=31679>`__:\n   The filter is effective at removing mosquito noise as well as\n   effectively smoothing flat areas in (especially) anime. (currently in\n   the repair shop) *[RGB]*\n#. `Smoother HiQ(uality) plugin (by Klaus\n   Post) <http://cultact-server.novi.dk/kpo/avisynth/smooth_hiq_as.html>`__:\n   This filter performs (spatial) smoothing on video material to\n   eliminate noise and MPEG artifacts. *[YUY2]*\n#. `msoften (by Marc\n   FD) <http://forum.doom9.org/showthread.php?s=&threadid=44308>`__:\n   This Filter is a spatial denoiser like 2dcleaner.  Some discussion\n   can be found\n   `here <http://forum.doom9.org/showthread.php?s=&threadid=36148>`__.\n   *[YUY2]*\n#. `General convolution plugin (by Richard\n   Berg) <http://forum.doom9.org/showthread.php?s=&threadid=28318>`__: A\n   spatial smoother\n   (`description <http://forum.doom9.org/showthread.php?s=&threadid=25908>`__).\n   This plugin will be a built-in function starting from AviSynth v2.01.\n   *[YUY2, RGB]*\n#. `Wavelet Noise Reduction (by\n   thejam) <http://forum.doom9.org/showthread.php?s=&threadid=31754>`__:\n   It can remove single-frequency noise in three different frequency\n   bands, independently for X- and Y-direction and for the Y, Cr and Cb\n   colorplane\n   (`documentation <http://forum.doom9.org/showthread.php?s=&threadid=31754&pagenumber=2>`__).\n   Note that it only works for PC's with SSE instructructions. *[YUY2]*\n#. `2D Cleaner Noise Reduction filter\n   \"\\_2DClenYUY2\" <http://members.tripod.co.jp/kiraru2002/>`__ *[YUY2]*\n#. Also see KenKunNR in the `Misc Plugins <#MiscellaneousPlugins>`__\n   section, below.\n\n| **Temporal Smoothers:**\n| *These filters use color similarities and differences between frames\n  to improve the picture and reduce compressed size.  They can get rid of\n  most noise in stationary areas without losing detail, but overly strong\n  settings can cause moving areas to be blurred.*\n\n#. `TemporalSoften2 plugin (by\n   Dividee) <http://forum.doom9.org/showthread.php?s=&threadid=22096>`__:\n   This plugin is better than the built-in TemporalSoften up to v2.02;\n   it removes noise from a video clip by selectively blending pixels. \n   It is built into v2.03 and all subsequent versions (it replaces the\n   old function and it is called the same: TemporalSoften). *[YUY2]*\n#. `TemporalSmoother plugin (by\n   Dividee) <http://users.win.be/dividee/avisynth.html>`__: This filter\n   is an adaptive noise reducer, working along the time axis. *[YUY2]*\n#. `TemporalCleaner (by Jim Casaburi; ported to AviSynth by\n   Vlad59) <http://forum.doom9.org/showthread.php?s=&threadid=37620>`__:\n   A simple but very fast temporal denoiser, aimed to improve\n   compressibility. *[YUY2]*\n#. `Grape Smoother (by Lindsey\n   Dubb) <http://students.washington.edu/ldubb/computer/GrapeSmoother.zip>`__:\n   `documentation <http://students.washington.edu/ldubb/computer/Read_Me_Grape_Smoother.rst>`__;\n   `discussion <http://forum.doom9.org/showthread.php?s=&threadid=37196>`__; \n   When colors change just a little, the filter decides that it is\n   probably noise, and only slightly changes the color from the previous\n   frame. As the change in color increases, the filter becomes more and\n   more convinced that the change is due to motion rather than noise,\n   and the new color gets more and more weight. *[YUY2]*\n#. `Chroma Noise Reducer (by Marc\n   FD) <http://forum.doom9.org/showthread.php?s=&threadid=44308>`__:\n   Reduces the noise on the chroma (UV) and preserves the luma (Y),\n   `discussion <http://forum.doom9.org/showthread.php?s=&threadid=29529>`__.\n   *[YUY2]*\n#. `Dynamical Noise Reduction 2 filter\n   \"DNR2\" <http://members.tripod.co.jp/kiraru2002/>`__ *[YUY2, RGB]*\n#. Also see KenKunNRT in the `Misc Plugins <#MiscellaneousPlugins>`__\n   section, below.\n\n| **Sharpen/Soften Plugins:**\n| *These are closely related to the Spatial Smoothers, above.  They\n  attempt to improve image quality by sharpening or softening edges.*\n\n#. `Smart sharpening filter \"MSharpen\" (by Donald\n   Graft) <http://neuron2.net/mine.html>`__: This filter is very\n   effective at sharpening important edges without amplifying noise.\n   *[YUY2, RGB]*\n#. `Sharpen/Blur filter \"Focus2\" (by Marc\n   FD) <http://forum.doom9.org/showthread.php?s=&threadid=44308>`__:\n   Sharpen2 and Blur2 are MMX optimisations of the built in Sharpen and\n   Blur functions.  Starting from v2.50 it will replace the Sharpen and\n   Blur functions. *[YUY2, RGB]*\n#. `Unfilter plugin (by Tom\n   Barry) <http://www.trbarry.com/UnFilter.zip>`__: This filter\n   softens/sharpens a clip:\n   `discussion <http://forum.doom9.org/showthread.php?s=&threadid=28197>`__. \n   It implements horizontal and vertical filters designed to (slightly)\n   reverse previous efforts at softening or edge enhancment that are\n   common (but ugly) in DVD mastering. *[YUY2]*\n#. See also WarpSharp, Xsharpen, and Unsharp Mask in the `Misc\n   Plugins <#MiscellaneousPlugins>`__ section, below.\n\n**Resizers:**\n\n#. `Lanczos resize filter (Implemented by\n   Nic) <http://nic.dnsalias.com/lanczos3.zip>`__: Starting from v2.06\n   AviSynth will have faster a built-in lanczos3 resizer. *[YUY2, RGB]*\n#. `SimpleResize plugin (by Tom\n   Barry) <http://www.trbarry.com/SimpleResize.zip>`__: Very simple and\n   fast two tap linear interpolation.  It is unfiltered which means it\n   will not soften much. *[YUY2]*\n\n**Subtitles:**\n\n#. `VobSub plugin (by Gabest) <http://vobsub.edensrising.com/>`__: A\n   plugin for importing your subtitles. *[YUY2, RGB]*\n\n**MPEG Decoder (source) Plugins:**\n\n#. `\"MPEG2DEC\" (by\n   dividee): <http://users.win.be/dividee/avisynth.html>`__ Mpeg2dec is\n   a plugin which enables AviSynth to import MPEG2 files.\n#. `\"MPEG2DEC2\" (by Tom\n   Barry) <http://www.trbarry.com/MPEG2DEC2.zip>`__: A MPEG2DEC.DLL\n   substitute.  It is the same MPEG2DEC.DLL with SSE2 optimization.\n   Faster with Pentium IV CPU.\n#. `\"MPEG2DEC3\" (by Marc\n   FD) <http://forum.doom9.org/showthread.php?s=&threadid=44308>`__: A\n   MPEG2DEC.DLL modification with deblocking and deringing,\n   `discussion <http://forum.doom9.org/attachment.php?s=&postid=185758>`__.\n#. `\"MpegDecoder\" (by Nic) <http://nic.dnsalias.com/MPEGDecoder.zip>`__:\n   A MPEG2DEC.DLL substitute.  Can also read MPEG-2 Transport Streams\n   (VOB) and works very quickly.\n\n**MPA Decoder (source) Plugins:**\n\n#. `MPASource (by\n   Warpenterprises): A\n   mp1/mp2/mp3 audio decoder plugin,\n   `discussion <http://forum.doom9.org/showthread.php?s=&threadid=41435>`__.\n\n| **Broadcast Video Plugins:**\n| *These are meant to take care of various problems which show up when\n  over the air video is captured.  Some help with luma/chroma separation,\n  others reduce interference problems or compensate for overscan.*\n\n#. `AntiBlink (by\n   Kurosu) <http://forum.doom9.org/showthread.php?s=&threadid=33319>`__:\n   Tries to diminish shimmering (rainbow effects) in areas with sharp\n   changes in luminance (for instance, letters). *[YUY2]*\n#. `Guava Comb (by Lindsey\n   Dubb) <http://students.washington.edu/ldubb/computer/GuavaComb.zip>`__:\n   This is a comb filter, meant to get rid of rainbows, dot crawl, and\n   shimmering in stationary parts of an image.\n   `documentation <http://students.washington.edu/ldubb/computer/Read_Me_Guava_Comb.rst>`__;\n   `discussion <http://forum.doom9.org/showthread.php?s=&threadid=37456>`__\\ *[YUY2]*\n#. `Ghostbuster (by\n   SansGrip) <http://forum.doom9.org/showthread.php?s=&threadid=35339>`__:\n   This filter removes \"ghosts\" from a clip.  A ghost in this context is\n   a faint copy of the picture offset horizontally.  It works by either\n   subtracting or adding the image from itself at the specified offset. \n   This filter is based on Krzysztof Wojdon's\n   `Exorcist <http://www.republika.pl/vander74/virtualdub/exorcist.zip>`__\n   VirtualDub filter. *[YUY2]*\n#. `BorderControl plugin (by Simon\n   Walters) <http://www.geocities.com/siwalters_uk/bdrcntrl.html>`__:\n   After capturing video you might want to crop your video to get rid of\n   rubbish.  BorderControl enables you to smear added borders instead of\n   adding solid borders preventing artefacts between picture and border.\n   *[YUY2]*\n#. `AutoCrop plugin (by\n   CropsyX) <http://www.videofringe.com/autocrop/>`__: Automatically\n   crops black borders from a clip.\n   `discussion <http://forum.doom9.org/showthread.php?s=&threadid=37204>`__\\ *[YUY2]*\n\n**Misc Plugins:**\n\n#. `ImageSequence plugin (by\n   Bzzz2) <http://forum.doom9.org/showthread.php?s=&threadid=26855>`__:\n   A plugin that lets you open image sequences.\n#. `Robust duplicate frame detector \"Dub\" (by Donald\n   Graft) <http://neuron2.net/mine.html>`__: This filter reduces the\n   size of anime movies by \"removing\" duplicated frames. *[YUY2]*\n#. `Tweak plugin (by Donald\n   Graft) <http://shelob.mordor.net/dgraft/mine.html>`__: Adjusts hue,\n   saturation, brightness, and contrast.  This is a built in function\n   starting with AviSynth v2.01. *[YUY2]*\n#. `WarpSharp, Xsharpen, UnsharpMask, KenKunNR, KenKunNRT, UVTimingH,\n   UVTimingV, LoadAviUtlInputPlugin, LoadAviUtlFilterPlugin,\n   ConvertYUY2ToAviUtlYC, ConvertAviUtlYCToYUY2, EraseGhost,\n   SearchGhost, EraseGhostV, SearchGhostV, Auto24FPS, AutoDeint,\n   FrameCache, AVIEncodeVideo, LoadPlugin (by\n   ???) <http://forum.doom9.org/showthread.php?s=&threadid=34076>`__:\n   Ported VirtualDub filters and AviUtl filters. Last version can be\n   found\n   `here <http://www.geocities.co.jp/SiliconValley-PaloAlto/2382/>`__.\n   *[YUY2]*\n#. `AviSynth monitor \"avsmon\" (by\n   johann.Langhofer) <http://forum.doom9.org/showthread.php?s=&threadid=32125&pagenumber=4>`__:\n   This plugin enables you to preview the video during the conversion\n   and to determine the exact audio delay.\\ *[YUY2, RGB ?]*\n#. `MergeLuma/MergeChroma plugin (by Klaus\n   Post) <http://cultact-server.novi.dk/kpo/avisynth/merge_as.html>`__:\n   This plugin is a built in function starting with AviSynth v2.01.\n   *[YUY2]*\n#. `Call (by\n   Nic) <http://forum.doom9.org/showthread.php?s=&threadid=46506>`__: A\n   plugin which enables you to call and pass parameters to a external\n   commandline program like Besweet.\n#. `Blockbuster (by\n   SansGrip) <http://www.jungleweb.net/~sansgrip/avisynth/>`__: With\n   this filter one can use several methods to reduce or eliminate DCT\n   blocks: adding noise (Gaussian distributed), sharpening, or\n   blurring.  Some discussion can be found\n   `here <http://forum.doom9.org/showthread.php?s=&threadid=37135>`__.\n   *[YUY2, RGB ?]*\n#. `ChromaShift (by Simon\n   Walters) <http://www.geocities.com/siwalters_uk/chromashift.html>`__:\n   ChromaShift shifts the chrominance information to the right by two\n   pixels to compensate for incorrect Y/UV registration. *[YUY2]*\n#. `TurnLeft and TurnRight (by\n   Warpenterprises) <http://forum.doom9.org/showthread.php?s=&threadid=44853>`__:\n   Rotates your clip -90 or 90 degrees.  This plugin will is a built in\n   function starting with AviSynth v2.51.\\ *[RGB]*\n#. `Chr.dll (by\n   WarpEnterprises) <http://forum.doom9.org/showthread.php?s=&threadid=47972&pagenumber=2>`__:\n   Let's you add ASCII CHaRacters and starting time.\n#. `Spray (by\n   WarpEnterprises) <http://forum.doom9.org/showthread.php?s=&threadid=49557>`__:\n   It takes pixels from \"nearby\" and sprays them around, so you can\n   spray pixel from outside the logo area randomly inside. *[RGB32]*\n#. `Zoom \"Pan/Zoom/Rotate\" (by\n   WarpEnterprises) <http://forum.doom9.org/showthread.php?s=&postid=283982>`__:\n   A plugin for Pan/Zoom/Rotate your clip. *[RGB32]*\n#. `MJPEGcorrect\n   plugin <http://inmatrix.hoyty.com/mirror/mjpegcorrect.zip>`__: Luma\n   (brightness) in MJPEG decoders is often decoded incorrectly to the\n   YUV luma-range.  This is a special purpose plugin written to fix this\n   issue with MJPEG videos,\n   `description <http://www.inmatrix.com/articles/ivtcsynth1.shtml>`__.\n   *[YUY2]*\n#. Many VirtualDub filters, see section `S4: Importing filters from\n   VirtualDub <#s4>`__. *[RGB32]*\n\nQ3.5: Where can I download external filters for AviSynth v2.5x?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: Most of them can be found in the AviSynth section at Doom9. But below\nyou will find links to most of them. If you know of a plugin which is\nmissing, please feel free to add it to the list using the \"Edit this\ndocument\" link to the left. Most of these plugins work in YUY2. If you\ncan't find the plugin (the attachments are still disable), you can\ndownload the plugins at\n[`WarpEnterprises <http://www.avisynth.nl/users/warpenterprises/>`__\\ ]\nhomepage.\n\n| **Deinterlacing & Pulldown Removal:**\n| *All PAL, NTSC, and SECAM video is interlaced, which means that only\n  every other line is broadcast at each refresh interval.  Deinterlacing\n  filters let you take care of any problems caused by this. IVTC (inverse\n  telecine, aka pulldown removal) filters undo the telecine process, which\n  comes from differences between the timing of your video and its original\n  source.*\n\n#. `rePal (by\n   Bach) <http://forum.doom9.org/showthread.php?s=&threadid=48401>`__: A\n   usefull plugin for doing a 30->25 IVTC conversion. It must be used in\n   conjunction with a (smart)bob. It can be used when your source is PAL\n   telecined material. *[YV12, YUY2]*\n#. `Unblend (by\n   Bach) <http://forum.doom9.org/showthread.php?s=&threadid=55019>`__: A\n   plugin based on Warpenterprise's deblend algorithm and Neuron2's\n   decimate code. It's for messed up NTSC->PAL conversions.\\ *[YV12]*\n#. `Decomb Filter package (by Donald\n   Graft) <http://neuron2.net/mine.html>`__: This package of plugin\n   functions for AviSynth provides the means for removing combing\n   artifacts from telecined progressive streams, interlaced streams, and\n   mixtures thereof. Functions can be combined to implement inverse\n   telecine for both NTSC and PAL streams.\n   `discussion <http://neuron2.net/ipw-web/bulletin/bb/viewtopic.php?t=56>`__\\ *[YV12,\n   YUY2]*\n#. `Area based deinterlacer (by Donald\n   Graft) <http://forum.doom9.org/showthread.php?s=&threadid=46161>`__:\n   Port of the Virtuldub filter. *[RGB32]*\n#. `DGBob (by Donald Graft) <http://neuron2.net/mine.html>`__: This\n   filter splits each field of the source into its own frame and then\n   adaptively creates the missing lines either by interpolating the\n   current field or by using the previous field's data.\n   `discussion <http://forum.doom9.org/showthread.php?s=&threadid=55598>`__\\ *[YV12,\n   YUY2, RGB]*\n#. `KernelDeint (by Donald Graft) <http://neuron2.net/mine.html>`__:\n   This filter deinterlaces using a kernel approach. It gives greatly\n   improved vertical resolution in deinterlaced areas compared to simple\n   field discarding.\n   [`discussion <http://neuron2.net/ipw-web/bulletin/bb/viewtopic.php?t=57>`__\\ ].\n   *[YV12, YUY2, RGB]*\n#. `MultiDecimate (by Donald Graft) <http://neuron2.net/mine.html>`__:\n   Removes N out of every M frames, taking the frames most similar to\n   their predecessors.\n   `discussion <http://forum.doom9.org/showthread.php?s=&threadid=51901&perpage=20&pagenumber=2>`__\\ *[YUY2]*\n#. `Smoothdeinterlacer (recompiled by Donald\n   Graft) <http://forum.doom9.org/showthread.php?s=&threadid=46161&pagenumber=2>`__:\n   A port of the VirtualDub Smooth Deinterlacer filter. *[YUY2, RGB32]*\n#. `Interpolation Bob (by\n   kevina20723) <http://forum.doom9.org/showthread.php?s=&threadid=62142>`__:\n   This filter works identically to the AviSynth built-in Bob filter\n   except that it uses linear interpolation instead of bicubic resizing\n   (C-plugin). *[YV12, YUY2]*\n#. `SmartDecimate (by\n   kevina20723) <http://forum.doom9.org/showthread.php?s=&threadid=60031>`__:\n   It should be very good at handling irregular telecines, and will also\n   handle hybrid clips fairly well without any excessive jerkiness or\n   blurring (C-plugin).\n   [`discussion <http://neuron2.net/ipw-web/bulletin/bb/viewtopic.php?t=61&start=50>`__\\ ].\n   *[YV12, YUY2]*\n#. `TPRIVTC (by\n   Kurosu) <http://forum.doom9.org/showthread.php?s=&threadid=44854>`__:\n   It uses the IVTC information from Tsunami MPEG Encoder Project\n   Files.\\ *[YV12, YUY2]*\n#. `Progressive Frame Restorer \"PFR\" (by Simon\n   Walters) <http://www.geocities.com/siwalters_uk/pfravs.html>`__:\n   Recover original progressive film frames that have undergone the\n   telecine to NTSC 30fps to PAL 25fps process whilst trying to maintain\n   correct temporal field order.\n   [`discussion <http://forum.doom9.org/showthread.php?s=&threadid=49815>`__\\ ].\n   *[YV12, YUY2]*\n#. `\"IT\" (by thejam79, recompiled by Donald\n   Graft) <http://forum.doom9.org/showthread.php?s=&threadid=44872>`__:\n   Inverse telecine plugin. `Translation of\n   README <http://avisynth.nl/index.php/IT>`__.\\ *[YUY2]*\n#. `GreedyHMA (by Tom\n   Barry) <http://mywebpages.comcast.net/trbarry/downloads.rst>`__:\n   DScaler's Greedy/HM algorithm code to perform pulldown matching,\n   filtering, and video deinterlacing.\n   `discussion <http://forum.doom9.org/showthread.php?s=&threadid=45995>`__\\ *[YUY2]*\n#. `Motion compensated deinterlace filter \"TomsMoComp\" (by Tom\n   Barry) <http://mywebpages.comcast.net/trbarry/downloads.rst>`__: This\n   filter uses motion compensation and adaptive processing to\n   deinterlace video source (not for NTSC film).\n   `discussion <http://forum.doom9.org/showthread.php?s=&threadid=37915>`__\\ *[YV12,\n   YUY2]*\n#. `UnComb IVTC (by Tom\n   Barry) <http://mywebpages.comcast.net/trbarry/downloads.rst>`__:\n   Filter for matching up even and odd fields of properly telecined NTSC\n   or PAL film source video.\n   `discussion <http://forum.doom9.org/showthread.php?s=&threadid=52333>`__\\ *[YV12]*\n#. See also Auto24FPS and AutoDeint in the\n   `MiscPlugins <#MiscellaneousPlugins2>`__ section below.\n\n| **Spatio-Temporal Smoothers:**\n| *These filters use color similarities and differences both within and\n  between frames to reduce noise and improve compressed size.  They can\n  greatly improve noisy video, but some care should be taken with them to\n  avoid blurred movement and loss of detail.*\n\n#. `PeachSmoother (by Lindsey\n   Dubb) <http://forum.doom9.org/showthread.php?s=&threadid=58674>`__:\n   An adaptive smoother optimized for TV broadcasts:\n   [`documentation <http://students.washington.edu/ldubb/computer/Read_Me_Peach_Smoother.rst>`__\\ ],\n   [`discussion <http://forum.doom9.org/showthread.php?s=&threadid=36575>`__\\ ].\n   The Peach works by looking for good pixels and gathering orange smoke\n   from them. When it has gathered enough orange smoke, it sprinkles\n   that onto the bad pixels, making them better. Works only on computers\n   with SSE instructions (Athlons, Pentium 3 or 4, recent Celerons, or\n   later). *[YUY2]*\n#. `FluxSmooth (by\n   SansGrip) <http://www.jungleweb.net/~sansgrip/avisynth/>`__:\n   spatio-temporal smoother,\n   `discussion <http://forum.doom9.org/showthread.php?s=&threadid=38296>`__\\ *.\n   [YV12]*\n#. `MipSmooth filter (by\n   Sh0dan) <http://forum.doom9.org/showthread.php?s=&threadid=63153>`__:\n   It takes the source frame, and creates three new versions, each half\n   the size of the previous. They are scaled back to original size. They\n   are compared to the original, and if the difference is below the\n   threshold, the information is used to form the final pixel. *[YV12]*\n#. `SpatioTemporal Median Filter \"STMedianFilter\" (by Tom\n   Barry) <http://www.trbarry.com/STMedianFilter.zip>`__: STMedianFilter\n   is a (slightly motion compensated) spatial/temporal median\n   filter.\\ *[YV12, YUY2]*\n#. `Convolution3DYV12 (by\n   Vlad59) <http://forum.doom9.org/showthread.php?s=&threadid=49806>`__:\n   Convolution3D is a spatio-temporal smoother, it applies a 3D\n   convolution filter to all pixels of consecutive frames.\n   `discussion <http://forum.doom9.org/showthread.php?s=&threadid=38281>`__\\ *[YV12]*\n\n| **Spatial Smoothers:**\n| *These use color similarities and differences within a frame to\n  improve the picture and reduce compressed size. They can smooth out\n  noise very well, but overly aggressive settings for them can cause a\n  loss of detail.*\n\n#. `Masked Smoother \"MSmooth\" (by Donald\n   Graft) <http://neuron2.net/mine.html>`__: This filter is effective at\n   removing mosquito noise as well as effectively smoothing flat areas\n   in anime.\n   `discussion <http://forum.doom9.org/showthread.php?s=&threadid=43976>`__\\ *[YV12,\n   RGB32]*\n#. `SmoothUV (by\n   Kurosu) <http://kurosu.inforezo.org/avs/Smooth/index.html>`__: This\n   filter can be used to reduce rainbows, as done by SmartSmoothIQ.\n   [`discussion <http://forum.doom9.org/showthread.php?s=&threadid=60631>`__\\ ].\n   *[YV12]*\n#. `VagueDenoiser (by\n   Lefungus) <http://forum.doom9.org/showthread.php?s=&threadid=56871>`__:\n   A simple denoiser that uses wavelets. *[YV12]*\n#. `Deen (by Marc FD) <http://ziquash.chez.tiscali.fr/>`__: Several\n   denoisers.\n   [`discussion <http://forum.doom9.org/showthread.php?s=&threadid=41643>`__\\ ]\n   This filter can cause memory leaks, so use at your own risk. *[YV12]*\n#. `eDeen (by Marc FD) <http://ziquash.chez.tiscali.fr/>`__: Spatial\n   monster. This filter can cause memory leaks, so use at your own\n   risk.\\ *[YV12]*\n#. `SmoothHiQ (recompiled by\n   Richard) <http://forum.doom9.org/showthread.php?s=&threadid=45277>`__:\n   *[YUY2]*\n#. `2D Cleaner Noise Reduction filter\n   \"\\_2DClenYUY2\" <http://members.tripod.co.jp/kiraru2002/>`__ *[YUY2]*\n#. Also see KenKunNR in the `Misc Plugins <#MiscellaneousPlugins2>`__\n   section, below.\n\n| **Temporal Smoothers:**\n| *These filters use color similarities and differences between frames\n  to improve the picture and reduce compressed size.  They can get rid of\n  most noise in stationary areas without losing detail, but overly strong\n  settings can cause moving areas to be blurred.*\n\n#. `TemporalCleaner (by Jim Casaburi; ported to AviSynth by\n   Vlad59) <http://forum.doom9.org/showthread.php?s=&threadid=37620&perpage=20&pagenumber=3>`__:\n   A simple but very fast temporal denoiser, aimed to improve\n   compressibility. *[YV12]*\n#. `Grape Smoother (by Lindsey\n   Dubb) <http://forum.doom9.org/showthread.php?s=&threadid=58674>`__:\n   [`documentation <http://students.washington.edu/ldubb/computer/Read_Me_Grape_Smoother.rst>`__\\ ],\n   [`discussion <http://forum.doom9.org/showthread.php?s=&threadid=37196>`__\\ ].\n   When colors change just a little, the filter decides that it is\n   probably noise, and only slightly changes the color from the previous\n   frame. As the change in color increases, the filter becomes more and\n   more convinced that the change is due to motion rather than noise,\n   and the new color gets more and more weight. *[YUY2]*\n#. `atc (by Marc FD) <http://ziquash.chez.tiscali.fr/>`__: Temporal\n   cleaner.\\ *[YV12]*\n#. `Chroma Noise Reducer \"Cnr2\" (by Marc\n   FD) <http://forum.doom9.org/showthread.php?s=&threadid=44500>`__:\n   Reduces the noise on the chroma (UV) and preserves the luma (Y),\n   [`discussion <http://forum.doom9.org/showthread.php?s=&threadid=29529&pagenumber=2>`__\\ ]\n   *[YV12, YUY2]*\n#. `Dynamical Noise Reduction 2 filter\n   \"DNR2\" <http://members.tripod.co.jp/kiraru2002/>`__ *[YV12]*\n#. Also see KenKunNRT in the `Misc Plugins <#MiscellaneousPlugins2>`__\n   section, below.\n\n| **Sharpen/Soften Plugins:**\n| *These are closely related to the Spatial Smoothers, above.  They\n  attempt to improve image quality by sharpening or softening edges.*\n\n#. `MSharpen (by Donald Graft) <http://neuron2.net/mine.html>`__: This\n   plugin for Avisynth implements an unusual concept in spatial\n   sharpening. Although designed specifically for anime, it also works\n   quite well on normal video. The filter is very effective at\n   sharpening important edges without amplifying noise.\n   `discussion <http://forum.doom9.org/showthread.php?s=&threadid=42839>`__\\ *[YV12,\n   YUY2, RGB]*\n#. `asharp (by MarcFD) <http://ziquash.chez.tiscali.fr/>`__: adaptive\n   sharpening filter,\n   [`discussion <http://forum.doom9.org/showthread.php?s=&threadid=38436>`__\\ ]\n   *[YV12]*\n#. `Unfilter plugin (by Tom\n   Barry) <http://mywebpages.comcast.net/trbarry/downloads.rst>`__: This\n   filter softens/sharpens a clip.  It implements horizontal and\n   vertical filters designed to (slightly) reverse previous efforts at\n   softening or edge enhancment that are common (but ugly) in DVD\n   mastering.\n   [`discussion <http://forum.doom9.org/showthread.php?s=&threadid=28197&pagenumber=3>`__\\ ]\\ *[YV12,\n   YUY2]*\n#. See also WarpSharp, Xsharpen, and Unsharp Mask in the `Misc\n   Plugins <#MiscellaneousPlugins2>`__ section, below.\n\n**Resizers:**\n\n#. `bicublinresize (by Marc FD) <http://ziquash.chez.tiscali.fr/>`__:\n   This is a set of resamplers: FastBilinear (similar to tbarry's\n   simpleresize), FastBicubic (an unfiltered Bicubic resampler) and\n   Bicublin (uses bicubic on Y plane and bilinear on UV planes).\n   `discussion <http://forum.doom9.org/showthread.php?s=&threadid=43207>`__.\n   *[YV12]*\n#. `ReduceBy2 replacement for TMPGEnc (by\n   scmccarthy) <http://forum.doom9.org/showthread.php?s=&postid=378363>`__:\n   This filter is only useful as a replacement for ReduceBy for users\n   who need to convert to the RGB color space anyway. It avoids the\n   interpolation of the chroma planes needed to convert to RGB by\n   resizing the luma plane instead. *[RGB]*\n#. `SimpleResize (by Tom\n   Barry) <http://mywebpages.comcast.net/trbarry/downloads.rst>`__: Very\n   simple and fast two tap linear interpolation.  It is unfiltered which\n   means it will not soften much. *[YV12, YUY2]*\n#. `YV12InterlacedReduceBy2 (by Tom\n   Barry) <http://mywebpages.comcast.net/trbarry/downloads.rst>`__:\n   InterlacedReduceBy2 is a fast Reduce By 2 filter, usefull as a very\n   fast downsize of an interlaced clip.\n   [`discussion <http://forum.doom9.org/showthread.php?s=&postid=271863>`__\\ ]\\ *[YV12]*\n\n**Subtitles:**\n\n#. `VSFilter (by Gabest) <http://www.sf.net/projects/guliverkli>`__: For\n   the subtitle fans!\n   [`discussion <http://forum.doom9.org/showthread.php?s=&threadid=41196>`__\\ ]\n\n**MPEG Decoder (source) Plugins:**\n\n#. `MPEG2DEC (by\n   dividee) <http://forum.doom9.org/showthread.php?s=&threadid=42301>`__\n   Mpeg2dec is a plugin which lets AviSynth import MPEG2 files. (outputs\n   to YUY2)\n#. `MPEG2DEC3 (by Marc FD and\n   others) <http://forum.doom9.org/showthread.php?s=&threadid=53164>`__:\n   A MPEG2DEC.DLL modification with deblocking and deringing. Note that\n   the colorspace information of dvd2avi is ignored when using mpeg2dec.\n#. `Mpegdecoder (by Nic) <http://nic.dnsalias.com/MPEGDecoder.html>`__:\n   This DLL lets you load VOB/MPEG-2/MPEG-1 files to be loaded directly\n   into AviSynth.\n   `discussion <http://forum.doom9.org/showthread.php?s=&postid=240354#post240354>`__.\n\n**MPA Decoder (source) Plugins:**\n\n#. `evilMPASource (by\n   Nic) <http://forum.doom9.org/showthread.php?s=&threadid=53164&perpage=20&pagenumber=12>`__:\n   MPASource with MPEG1/2 input support.\n#. `MPASource (by\n   Warpenterprises) <http://members.aon.at/archi/warpenterprises>`__: A\n   mp1/mp2/mp3 audio decoder plugin,\n   `discussion <http://forum.doom9.org/showthread.php?s=&threadid=41435>`__.\n\n**Plugins to compare video quality using specific video quality metrics:**\n\n#. `SSIM (by\n   Lefungus) <http://forum.doom9.org/showthread.php?s=&threadid=61128>`__:\n   Filter to compare video quality (similar as psnr, but using a\n   different video quality metric). *[YV12]*\n#. `VqmCalc (by\n   Lefungus) <http://forum.doom9.org/showthread.php?s=&threadid=61128>`__:\n   Filter to compare video quality (similar as psnr, but using a\n   different video quality metric). *[YV12]*\n\n| **Broadcast Video Plugins:**\n| *These are meant to take care of various problems which show up when\n  over the air video is captured.  Some help with luma/chroma separation;\n  Others reduce interference problems or compensate for overscan.*\n\n#. `Super8Equal (by\n   Belgabor) <http://forum.doom9.org/showthread.php?s=&threadid=48951>`__:\n   One problem of the transfer of Super8 films to digital media is the\n   inhomogenous brightness produced by projectors. Usually the brighness\n   drops in a circular fashion from the center to the rim. This filter\n   was written to counteract this problem. *[YV12, YUY2, RGB]*\n#. `AutoCrop plugin (by\n   CropsyX) <http://www.videofringe.com/autocrop/>`__: Automatically\n   crops black borders from a clip.\n   `discussion <http://forum.doom9.org/showthread.php?s=&threadid=37204&pagenumber=2>`__.\n   *[YV12, YUY2]*\n#. `Declick (by Donald\n   Graft) <http://forum.doom9.org/showthread.php?s=&threadid=52310>`__:\n   Removes light horizontal clicks. *[YUY2]*\n#. `Deflicker filter (by Donald Graft, port of the VirtualDub\n   filter) <http://forum.doom9.org/showthread.php?s=&threadid=40293>`__:\n   This filter corrects video that has frame luminance variations over\n   time, what we might generically call flickering. *[YUY2]*\n#. `Conditional Temporal Median Filter (by\n   kevina20723) <http://forum.doom9.org/showthread.php?s=&threadid=57914>`__:\n   Removes temporal noise in the form of small dots and streaks\n   (C-plugin). *[YV12]*\n#. `X-Logo (by\n   Leuf) <http://forum.doom9.org/showthread.php?s=&threadid=56660>`__: A\n   filter to remove logos. (Note there's an internal conversion to RGB32\n   and back.) *[YV12, YUY2, RGB]*\n#. `Guava Comb (by Lindsey\n   Dubb) <http://forum.doom9.org/showthread.php?s=&threadid=58674>`__:\n   This is a comb filter, meant to get rid of rainbows, dot crawl, and\n   shimmering in stationary parts of an image.\n   [`documentation <http://students.washington.edu/ldubb/computer/Read_Me_Guava_Comb.rst>`__\\ ],\n   [`discussion <http://forum.doom9.org/showthread.php?s=&threadid=37456>`__\\ ].\n   *[YUY2]*\n#. `FixVHSOversharp (by\n   MrTibs) <http://www.geocities.com/mrtibsvideo/fixvhsoversharp.html>`__:\n   Repairs the light and dark halos that follow high contrast edges\n   found in VHS sources.\n   [`discussion <http://www.kvcd.net/forum/viewtopic.php?t=3119>`__\\ ].\n   *[YUY2]*\n#. `BorderControl (by Simon\n   Walters) <http://forum.doom9.org/showthread.php?s=&threadid=45670>`__:\n   After capturing video you might want to crop your video to get rid of\n   rubbish.  BorderControl enables you to smear added borders instead of\n   adding solid borders preventing artefacts between picture and border.\n   *[YV12, YUY2]*\n#. `FillMargins (by Tom\n   Barry) <http://mywebpages.comcast.net/trbarry/downloads.rst>`__: A\n   similar filter as BorderControl.\n   [`discussion <http://forum.doom9.org/showthread.php?s=&threadid=50132>`__\\ ]\n   *[YV12]*\n#. `Reinterpolate411 (by Tom\n   Barry) <http://www.trbarry.com/ReInterpolate411.zip>`__: It seems\n   that even chroma pixels are just being duplicated in the MainConcept\n   codec (NTSC). The new filter will help that by discarding the odd\n   chroma pixels and recreating them as the average of the 2 adjacent\n   even pixels.\n   [`discussion <http://forum.doom9.org/showthread.php?s=&threadid=58294&pagenumber=2>`__\\ ].\n   *[YUY2]*\n\n**Misc Plugins:**\n\n#. `Imagesequence plugin (by Bzzz, modified by Warpenterprises and\n   Sh0dan) <http://forum.doom9.org/showthread.php?s=&threadid=26855&pagenumber=2>`__:\n   Let's you import image sequences like .TIF, .TGA and .JPG files\n   (images need to be 24 or 32 bits per pixel). This plugin is built in\n   starting from AviSynth v2.52, and it is called\n   `ImageReader <corefilters/imagesource.rst>`__.\n#. `Dup (by Donald Graft) <http://neuron2.net/mine.html>`__: This is\n   intended for use in clips that have a significant number of duplicate\n   content frames, but which differ due to noise. Typically anime has\n   many such duplicates. By replacing noisy duplicates with exact\n   duplicates, a bitrate reduction can be achieved.\n   `discussion <http://forum.doom9.org/showthread.php?s=&threadid=41850>`__\\ *[YV12,\n   YUY2]*\n#. `Convert3d (by\n   hanfrunz) <http://forum.doom9.org/showthread.php?s=&threadid=48842>`__:\n   Converts interlaced 3D Movies (one field left, other field right\n   picture) to anaglyph (red/cyan) format using photoshops\n   \"screen\"-blend method. *[YUY2, RGB]*\n#. `AviSynth monitor \"avsmon\" (by\n   johann.Langhofer) <http://forum.doom9.org/showthread.php?s=&threadid=32125&pagenumber=4>`__:\n   This plugin enables you to preview the video during the conversion\n   and to determine the exact audio delay.\\ *[YV12, YUY2 ?, RGB ?]*\n#. `AVISynth C API (by\n   kevina20723) <http://kevin.atkinson.dhs.org/avisynth_c/>`__:\n   C-plugins must be loaded with LoadCPlugin using AviSynth v2.52 or\n   older versions, and can also be loaded with LoadPlugin starting from\n   AviSynth v2.53. Advice: keep this plugin outside your auto plugin\n   loading directory to prevent crashes.\n   [`discussion <http://forum.doom9.org/showthread.php?s=&threadid=58840>`__\\ ].\n#. `MaskTools (by\n   Kurosu) <http://forum.doom9.org/showthread.php?s=&threadid=49892>`__:\n   Some general mask tools. *[YV12]*\n#. `Call (by\n   Nic) <http://forum.doom9.org/showthread.php?s=&threadid=46506>`__: A\n   plugin which enables you to call and pass parameters to an external\n   commandline program like Besweet.\n#. `AudioGraph (by Richard Ling, modified by\n   Sh0dan) <http://forum.doom9.org/showthread.php?s=&threadid=59412>`__:\n   Displays the audio waveform on top of the video. *[YUY2, RGB]*\n#. `Blockbuster (by Sansgrip, recompiled by\n   CruNcher) <http://forum.doom9.org/showthread.php?s=&threadid=44927>`__:\n   With this filter one can use several methods to reduce or eliminate\n   DCT blocks: adding noise (Gaussian distributed), sharpening, or\n   blurring. *[YUY2]*\n#. `ReverseFieldDominance (by\n   Sansgrip) <http://www.geocities.com/siwalters_uk/fnews.html>`__:\n   Reverses the field dominance of PAL DV.\n   `discussion <http://forum.doom9.org/showthread.php?s=&threadid=46765&perpage=20&pagenumber=2>`__.\n   *[YUY2, RGB]*\n#. `ChromaShift (by Simon\n   Walters) <http://www.geocities.com/siwalters_uk/chromashift.html>`__:\n   ChromaShift shifts the chrominance information in any direction, to\n   compensate for incorrect Y/UV registration. *[YUY2]*\n#. `CompareYV12 (by\n   Shalcker) <http://web.etel.ru/~shalcker/CompareYV12.zip>`__: YV12\n   version of the internal filter \"Compare\".\n   [`discussion <http://forum.doom9.org/showthread.php?s=&threadid=58187>`__\\ ].\n   *[YV12]*\n#. `SelectByString (by\n   stickboy) <http://forum.doom9.org/showthread.php?s=&threadid=60532>`__:\n   This filter can be used to create wrapper functions to specify\n   presets to other filters (C-plugin). *[YV12, YUY2, RGB]*\n#. `AddGrain (by Tom\n   Barry) <http://mywebpages.comcast.net/trbarry/downloads.rst>`__:\n   AddGrain generates film like grain or other effects (like rain) by\n   adding random noise to a video clip. This noise may optionally be\n   horizontally or vertically correlated to cause streaking. *[YV12]*\n#. `BT709ToBT601 (by Tom\n   Barry) <http://mywebpages.comcast.net/trbarry/downloads.rst>`__:\n   Converts HDTV (BT.709) to SDTV (BT.601) color space.\n   [`discussion <http://forum.doom9.org/showthread.php?s=&threadid=50588>`__\\ ]\n   *[YV12]*\n#. `DctFilter (by Tom\n   Barry) <http://mywebpages.comcast.net/trbarry/downloads.rst>`__:\n   Reduces high frequency noise components using Discrete Cosine\n   Transform and its inverse.  Results in a high compressibility gain,\n   when it is used at the end of your script.  Height/width must be a\n   multiple of 16.\n   `discussion <http://forum.doom9.org/showthread.php?s=&postid=252451>`__.\n   *[YV12, YUY2]*\n#. `FrameDbl (by Tom\n   Barry) <http://mywebpages.comcast.net/trbarry/downloads.rst>`__: A\n   motion compensated frame doubler, made from STMedianFilter.\n   [`discussion <http://forum.doom9.org/showthread.php?s=&threadid=56036>`__\\ ]\n   *[YV12]*\n#. `Undot (by Tom\n   Barry) <http://mywebpages.comcast.net/trbarry/downloads.rst>`__:\n   UnDot is a simple median filter for removing dots, that is stray\n   orphan pixels and mosquito noise.  It basicly just clips each pixel\n   value to stay within min and max of its eight surrounding neigbors.\n   [`discussion <http://forum.doom9.org/showthread.php?s=&postid=205442#post205442>`__\\ ].\n   *[YV12, YUY2]*\n#. `Chr (by\n   WarpEnterprises) <http://forum.doom9.org/showthread.php?s=&threadid=47972&pagenumber=2>`__:\n   Let's you add ASCII CHaRacters and starting time. This plugin will be\n   a built-in function starting from v2.52.\n#. `DVinfo (by\n   WarpEnterprises) <http://forum.doom9.org/showthread.php?s=&threadid=61688>`__:\n   This filter grabs the timestamp and recording date info out of a\n   DV-AVI. It should work with Type-1 and Type-2, standard AVI and\n   openDML.\n#. `Zoom \"Pan/Zoom/Rotate\" (by\n   WarpEnterprises) <http://forum.doom9.org/showthread.php?s=&postid=283982>`__:\n   A plugin for Pan/Zoom/Rotate your clip. *[RGB32]*\n\n.. _JapanesePlugin:\n\nWarpSharp, Xsharpen, UnsharpMask, KenKunNR, KenKunNRT, UVTimingH, UVTimingV,\nLoadAviUtlInputPlugin, LoadAviUtlFilterPlugin, ConvertYUY2ToAviUtlYC,\nConvertAviUtlYCToYUY2, EraseGhost, SearchGhost, EraseGhostV, SearchGhostV,\nAuto24FPS, AutoDeint, FrameCache, AVIEncodeVideo, LoadPluginEx (`by our Japanese\nfriend) <http://www.geocities.co.jp/SiliconValley-PaloAlto/2382/>`__:\nPorted VirtualDub filters and AviUtl filters. Some documentation can\nbe found\n[`here <http://forum.doom9.org/showthread.php?s=&threadid=34076>`__\\ ].\nYou need to copy the\n[`msvcp71.dll/msvcr71.dll <http://www.geocities.com/wilbertdijkhof/71.cab>`__\\ ]\n(Microsoft C Runtime Library, v7) to your windows system directory.\n*[YV12, YUY2]*\n\n\nQ3.6: Where can I download utilities for AviSynth?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: Several utilities are available:\n\n-  `AvsCompare (by TheWEF and\n   aquaplaning) <http://aquaplaning.20m.com/>`__: This is a little tool\n   to compare video material and/or the effect of choosen AviSynth\n   filters.\n   [`discussion <http://forum.doom9.org/showthread.php?s=&threadid=40675>`__\\ ]\n-  `AvsTimer (by\n   kassandro) <http://forum.doom9.org/showthread.php?s=&threadid=56090>`__:\n   A small filter with virtually no overhead, which allows one to\n   measure the performance of plugins or groups of plugins.\n-  `AVISynth\n   BatchScripting <http://sourceforge.net/projects/avsbatches>`__: A\n   little Batch file for creating fastly \"AVS AviSynth Script files\".\n   With available presets: 1:1-VGA to VCD, DVB/DVD-PAL to 1:1-VGA and\n   DVB/DVD-PAL to VCD. (Batches runs under WinNT/2000/XP only)\n\n\nQ3.7: How do I convert between the colorspaces?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: If you are using mpeg2dec3 (the appropriate one for AviSynth v2.5x)\nyou can also use the conversions available in this dll (for example when\nyou want to convert to RGB24).  Using AviSynth itself:\n\n| *converting to YV12:*\n| `ConvertToYV12 <corefilters/convert.rst>`__\n\n| *converting to YUY2:*\n| `ConvertToYUY2 <corefilters/convert.rst>`__\n\n| *converting to RGB:*\n| `ConvertToRGB <corefilters/convert.rst>`__\n\nNote that converting between colorspaces isn't completely lossless,\nand doing several conversions back and forth may degrade your signal. \nThe first conversion back and forth does not hurt your source, but if\nyou use three or more, it may.  Starting with version v2.03, there is a\n`ConvertBackToYUY2 <corefilters/convert.rst>`__ which offers better\nsymmetry if your RGB source was previously converted from YUY2.\n\nQ3.8: What/when do I care when filter X works in RGB- or YUV-space?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: The main reason why you should care is the improvement in speed you\ncan obtain by not unnecessarily changing between colorspaces.  If your\nsource is YV12 (when encoding DVD's for example, or captures from\ndigital sources) try to use only filters/plugins which work with YV12\ninput.  On the other hand if your source is in RGB (for example from\nanalog captures) try to use only filters/plugins which work in\nRGB-space.\n\nSpeed is also quite different between the different colorspaces, because\neach colorspace takes up different amounts of memory.  The slowest\ncolorspace is usually RGB24, because every pixel has an odd alignment in\nmemory, avoid using this mode.  The fastest mode is usually YV12\n(followed by YUY2), because data takes less than half as much space as\nRGB32.  So if you have to process your video a lot, try using\nConvertToYV12 or `ConvertToYUY2 <corefilters/convert.rst>`__ before you\ndo your filtering.  Note that `ConvertToRGB <corefilters/convert.rst>`__\nconverts to RGB32 if the source is YV12/YUY2 - use\n`ConvertToRGB32 <corefilters/convert.rst>`__ to force a RGB24 to RGB32\nconversion.\n\nYou should also consider your destination colorspace.  If you plan on\nconverting to DivX/XviD/Huffyuv in VirtualDub without applying filters\nin VirtualDub, \"Fast Recompress\" will deliver the YUY2-data (or YV12\ndata if you use VirtualdubMod) directly to the codec, saving you another\ncolorspace conversion.  On the other hand, if you plan using TMPGEnc or\nVirtualDub in \"Full Processing\" mode, you may consider delivering the\nsource as RGB.\n\nQ3.9: How do I use and where can I get the \"Subtitler\" and \"BMP Loader\" plugins?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: These dll files are created by DVD2SVCD and only DVD2SVCD is using\nthem. But you can also use them in AviSynth. Have a look in this\n[`thread <http://forum.doom9.org/showthread.php?s=&threadid=23296>`__\\ ].\n\nS4: Importing filters from VirtualDub\n-------------------------------------\n\nQ4.1: Where can I download the latest version of scripts which import filters from VirtualDub?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: The AviSynth scripts are on the\n`Shared_functions <http://www.avisynth.nl/index.php/Shared_functions>`__\npage, or you can download a package called vdub\\_filtersv15.zip from\n`<http://forum.doom9.org/showthread.php?s=&threadid=23804>`__\nor `<http://neuron2.net/hosted.html>`__\n\nQ4.2: Which filters are imported?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: Most filters.  Read the corresponding documentation available in the zip-file.\n\nQ4.3: Do these scripts work in RGB-space or in YUV-space?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: Only in RGB-space (RGB32).\n\nQ4.4: How do I make such a script?\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA: Example script (this VirtualDub filter can be downloaded from\n`Donald's homepage <http://shelob.mordor.net/dgraft/>`__):\n\nSmart Bob by Donald Graft:\n::\n\n    function VD\\_SmartBob(clip clip, bool \"show_motion\", int \"threshold\", bool \"motion_map_denoising\")\n        LoadVirtualdubPlugin(\"d:\\bob.vdf\", \"_VD_SmartBob\", 1)\n        return clip.SeparateFields._VD_SmartBob(clip.GetParity?1:0,\n     \\  default(show_motion, false)?1:0, default(threshold, 10),\n     \\  default(motion_map_denoising, true)?1:0)\n    }\n\nThe VirtualDub plugin is imported with the command\n\"LoadVirtualdubPlugin\".  The first argument gives the path of the\nplugin, the second argument the name for the plugin that will be used in\nthe script and the third argument is called the preroll.\n\nThe preroll should be set to at least the number of frames the filter\nneeds to pre-process to fill its buffers and/or updates its internal\nvariables.  This last argument is used in some filters like: SmartBob,\nSmartDeinterlace, TemporalCleaner and others.  The reason is that due to\nfiltering architecture of Virtual Dub the future frames can't be\naccessed by a filter.  Dividee reports: \"In the \"Add filter\" dialog of\nVirtualDub, some filters have a \"Lag:\" value in their description. I\nthink this is the value that must be used as preroll.  Unfortunately,\nthis indication is not always present.  In those cases you have to\nguess.\"  Of course you can always ask the creator of the filter.\n\nThe first step is to find out the sequence of the arguments in the last\nline where the clip is returned.  Configure the script in VirtualDub and\nselect \"Save processing Settings\" in the File Menu or press Ctrl+S. \nOpen the created .vcf file with a text editor and you should see lines\nlike this:\n\n| ``VirtualDub.video.filters.Add(\"smart bob (1.1 beta 2)\");``\n| ``VirtualDub.video.filters.instance[0].Config(1, 0, 10, 1);``\n\nThe order of the arguments is the one that has to be used in AviSynth. \nTo find the role of the arguments, play with them in VirtualDub and\nexamine the resulting lines.\n\nThe second step is to test the filter and to compare it with the\nVirtualDub filter itself.  For the programming itself you can learn a\nlot by looking at the script which are already contained in\nvdub_filters.avs.\n\nExample script which uses the function VD_SmartBob:\n::\n\n    Import(\"d:\\vdub_filters.avs\")\n    AviSource(\"d:\\filename.avi\")\n    ConvertToRGB32 # only when necessary (but doesn't hurt)\n    VD_SmartBob(1, 0, 10, 1)\n    ConvertBackToYUY2 # only when necessary\n\n$Date: 2025-02-21 18:02:36-05:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/faq/faq_common_errors.rst",
    "content": "\nAviSynth FAQ - Some common error messages\n=========================================\n\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\n\nI got the message \"LoadPlugin: unable to load \"xxx (some plugin)\" is not an AviSynth 1.0/AviSynth 2.0 plugin\"?\n--------------------------------------------------------------------------------------------------------------\n\nYou are using a plugin which is not compatiable with that version of AviSynth. As explained\n:ref:`here <How do I use a plugin compiled for v2.0x in v2.5x>`, plugins\ncompiled for AviSynth v2.5 are not compatible with AviSynth v1.0x/v2.0x and vice versa.\n\n\nWhen frameserving I got the following message: \"Script error, there is no function named \"xxx (some filter)\"\"?\n--------------------------------------------------------------------------------------------------------------\n\nYou probably installed/registered a version of AviSynth which doesn't contain\nthat specific filter. Make sure that there are no other versions floating\naround on your hard disk (there's a possibility that a version will be\nregistered while it is not in your system directory). Make sure that the\nlatest stable version is registered, see also :ref:`this FAQ entry <How do I know which version number of AviSynth I have>`.\n\n\nI installed AviSynth and got the following error message: \"Couldn't locate decompressor for format 'YV12' (unknown).\"?\n----------------------------------------------------------------------------------------------------------------------\n\nInstall a codec which supports YV12. DivX5 or one of the recent `XviD builds\nof Koepi`_ or `Helix YUV codec`_ or some other (ffvfw, ffdshow). If that\nstill doesn't work, modify your registry as explained in the next question.\n\n\nWhen encoding I got the following error \"ACM failed to suggest a compatible PCM format\"?\n----------------------------------------------------------------------------------------\n\nThis error means that you are using AviSource to open your AVI file, but you\ndon't have an ACM codec to decode the audio stream. The most common problem\nis that your audio is an AC3 or a MP3 stream, but you don't have the\ncorresponding ACM codec installed. It can also happen that your audio is a\n\"crippled\" (that is, with an incorrect header) MP3 `[1]`_ `[2]`_ `[3]`_.\n\nThere are several solutions for this problem:\n\n-   Get the proper ACM codec. You can use `GSpot`_ to find out which\n    audio stream you are dealing with. The needed ACM codecs can be found\n    :doc:`in the table here <../advancedtopics/importing_media>`.\n-   Demux your audio with an application like `AVI-Mux GUI`_ or\n    `VirtualDub`_, and import your audio with a specific plugin. See also\n    :doc:`the loading clips FAQ. <faq_loading_clips>`\n-   Use :doc:`DirectShowSource <../corefilters/directshowsource>` to open the audio. Install `ffdshow`_ and\n    enable the specific audio format in the \"Audio Decoder Properties\" tab.\n    Create the following script:\n\n::\n\n    Vid = AviSource(\"Blah.avi\", audio=false)\n    Aud = DirectShowSource(\"Blah.avi\", video=false)\n    AudioDub(Vid, Aud)\n\nWhen encoding I got the following error: \"framesize xyz x 56 not supported\"?\n----------------------------------------------------------------------------\n\nThis usually is an indicator of a script error, where the input is actually\nthe error message being displayed. Here, xyz is the length of the error\nmessage text and 56 is the height (xyz will vary depending on the error\nmessage whilst the height will always be 56 pixels). Your encoder is seeing\nthe error message as an RGB32 input source and hence the error. Opening the\nscript with WMP or VirtualDub should display the error message. Fix the error\nin the script and retry to encode.\n\n\nWhen frameserving I got the following message: \"AVISource: couldn't locate a decompressor for fourcc (...)\"?\n------------------------------------------------------------------------------------------------------------\n\nUsually, this error message shows up if you don't have the right VfW codec\ninstalled for decoding your video. Get `Gspot`_ to find out which codec you\nneed. Get, for example, `XviD`_ for your MPEG-4 ASP clips and `Cedocida\ncodec`_ for your DV clips. If you have problems finding the right one, ask\naround on the video forums.\n\nBut it can also show up if you call :doc:`AviSource <../corefilters/avisource>` too many times. The dll for\nthe decompression codec is loaded separately for every AviSource call.\nEventually an OS-imposed limit is reached, the codec can't be loaded and you\nget that error message. More discussion can be found `in this thread`_. A good solution\nis to use a number of scripts (keeping each below the problematic limit of\navi calls) and encode them separately, and join them afterwards in some\napplication.\n\n\nWhen frameserving I got the following message: \"DirectShowSource: Could not open as video or audio / Video Returned: \"DirectShowSource: the filter graph manager won't talk to me\"\"?\n------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n\nThis is a common error that occurs when DirectShow isn't able to deliver any\nformat that is readable to AviSynth. Try creating a filter graph manually.\nSee if you are able to construct a filter graph that delivers any output that\nAviSynth can open. If not, you might need to download additional DirectShow\nfilters that can deliver correct material. If you can play the graph in\n`GraphEdit`_, make sure to remove the video and audio renderers, before\nsaving the graph and opening it in AviSynth. Some examples can be found\n:ref:`in the importing media FAQ <graphs>`.\n\n\nI am trying to load a script that has a path name with a mix of japanese characters (someone's name) and Ascii test. I got an import error and the path that is displayed has some strange characters (not the japanese characters)?\n------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n\nAviSynth has problems with non-ANSI chars on filenames. It only supports `8\nbit character ANSI text`_. Some discussion about this: `[4]`_ and `[5]`_.\n\n\nWhen frameserving I got the following message: \"CAVIStreamSynth: System exception - Access Violation at 0x0, reading from 0x0\"?\n-------------------------------------------------------------------------------------------------------------------------------\n\nAccess Violation at 0x0, reading from 0x0 is usually caused by running out of\nmemory (memory leak ???). It can be caused by a plugin which is leaking\nmemory, but apparently it can also be caused by other things (codecs,\napplications ???) [`1`_] [`2`_]. Add SetMemoryMax(...) at the beginning of\nthe script. If that doesn't help, report the issue in the doom9 forums, and\nwe will try to help finding the cause of it.\n\n\nWhen frameserving I got a message similar to: \"Avisynth open failure: Script error: Invalid arguments to function \"xxx (some filter)\" (I:\\Video.avs, line 5)\"\n-------------------------------------------------------------------------------------------------------------------------------------------------------------\n\nIt means you are passing incorrect arguments (that is of the correct type) to\nyour script, filter or plugin. For example:\n\n::\n\n    # passing a float (2.0), while Loop expects an int:\n    Loop(clip, 2.0)\n\n::\n\n    # passing three clips to Overlay instead of two:\n    AviSource(\"anime_raw.avi\")\n    karaoke = AviSource(\"karaoke.avi\")\n    Trim(0,999) + Trim(1000,1030).Overlay(last, karaoke, mask=sign.ShowAlpha()) + Trim(1031,0)\n    # last should be omitted as argument to Overlay\n\n::\n\n    # implicit 'last' not defined\n    v = AviSource(\"myvid.avi\")\n    Trim(100, 199)\n    # need to use v.Trim(...) here\n\nSo make sure the passed arguments are of the correct type and read the\ncorresponding documentation if necessary.\n\n| :doc:`Main Page <faq_sections>` | :doc:`General Info <faq_general_info>` | :doc:`Loading Clips <faq_loading_clips>` | :doc:`Loading Scripts <faq_frameserving>` | **Common Error Messages** | :doc:`Processing Different Content <faq_different_types_content>` | :doc:`Dealing with YV12 <faq_yv12>` | :doc:`Processing with Virtualdub Plugins <faq_using_virtualdub_plugins>` |\n\n$Date: 2025-02-25 17:17:18-05:00 $\n\n.. _XviD: http://www.xvid.org/\n.. _XviD builds of Koepi: http://www.xvid.org/\n.. _Helix YUV codec:\n    http://forum.doom9.org/showthread.php?s=&threadid=56972\n.. _[1]: http://forums.virtualdub.org/index.php?act=ST&f=4&t=802&hl=0055\n.. _[2]: http://forums.virtualdub.org/index.php?act=ST&f=3&t=10931&hl=unknown%20tag%200055&st=15\n.. _[3]: http://forum.doom9.org/showthread.php?t=94760\n.. _GSpot: http://www.headbands.com/gspot/\n.. _AVI-Mux     GUI: http://www.alexander-noe.com/video/amg/\n.. _VirtualDub: http://www.virtualdub.org\n.. _ffdshow: http://ffdshow-tryout.sourceforge.net/\n.. _Cedocida codec: http://forum.doom9.org/showthread.php?t=94458\n.. _in this thread: http://forum.doom9.org/showthread.php?t=131687\n.. _GraphEdit: http://avisynth.nl/index.php/GraphEdit\n.. _8 bit character ANSI text: http://en.wikipedia.org/wiki/ASCII\n.. _[4]: http://forum.doom9.org/showthread.php?t=110467\n.. _[5]: http://forum.doom9.org/showthread.php?t=131419\n.. _1: http://forum.doom9.org/showthread.php?t=123195\n.. _2: http://forum.doom9.org/showthread.php?t=128403\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/faq/faq_different_types_content.rst",
    "content": "\nAviSynth FAQ - Recognizing and processing different types of content\n====================================================================\n\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\n\nThe video and audio in my final encoding is out of sync, what should I do?\n--------------------------------------------------------------------------\n\nAssuming that you processed your video and or audio with AviSynth, there can\nbe several reasons why your final encoding is not in sync (synchronization).\nThe most common ones are:\n\n1) Your source is already out of sync (thus before any AviSynth\n   processing or any encoding). It's a pain to correct this, but that's not\n   the scope of this FAQ.\n\n2) The audio has a constant delay, and you forgot to add the delay\n   (either in AviSynth if you imported the audio in AviSynth or in an\n   encoder if you imported the audio directly in your encoder). As an\n   example, the demuxed audio stream from a VOB has often a delay. When\n   demuxing this audio stream with DGIndex, the delay (actually how the\n   delay should be corrected) is written into the name of the demuxed audio\n   stream. You can use :doc:`DelayAudio <../corefilters/delayaudio>` to add the delay in AviSynth.\n\n::\n\n    vid = MPEG2Source(\"D:\\movie.d2v\")\n    aud = NicAC3Source(\"D:\\movie T01 2_0ch 448Kbps DELAY -218ms.ac3\")\n    AudioDub(vid, aud)\n    DelayAudio(-0.218)\n\n3) The audio has a variable delay (with a zero delay at the beginning and\n   a maximal delay at the end). This can be caused when you load a clip into\n   AviSynth which has a variable framerate. Pretty much anything except\n   video contained in an AVI or MPEG-2/VOB file can be variable framerate.\n   If you used `DirectShowSource`_ the load your clip, you can use the\n   following to ensure sync. What happens is that frames are added or\n   removed to ensure sync, thus converting it to a constant framerate video.\n\n::\n\n    # a mkv-file is used here as an example:\n    DirectShowSource(\"D:\\movie.mkv\", fps=xxx, convertfps=true) # fps = average framerate\n\nIf you are not using DirectShowSource or you don't want to add or remove\nframes, you need to create a timecodes file first and use it later on in your\nfinal encoding. Have a look at :doc:`this article <../advancedtopics/hybrid_video>` for more information on this\nsubject.\n\n\nHow do I recognize progressive, interlaced, telecined, hybrid and blended content?\n----------------------------------------------------------------------------------\n\nIt is important to know your content if you want to process it. The most\nimportant ones are: progressive, interlaced, telecined, hybrid and blended\ncontent, and they should be processed differently.\n\n-   **Progressive and interlaced content:**\n\n|     Most filters assume that your content is progressive (which means that every\n      frame is taken at a different time-instant), unless the filter has an option\n      interlaced=true/false. When the option is present you can use interlaced=true\n      for interlaced content. For interlaced content, every field (a frame consists\n      of two fields) is taken at a different time-instant. This is explained in the\n      `Analog Capture Guide`_ and the `Force Film, IVTC, and Deinterlacing`_\n      tutorial.\n\n-   **Telecined content:**\n\n|     Usually movies are shot at 24 fps (frames per second). When putting this on a\n      dvd, fields are added to get the required frame rate of 30 fps (well, it's\n      actually 29.97 fps, but that's not important here). When doing this, the\n      content is called \"telecined content\" (this holds for the conversions 25 fps\n      -> 30 fps and 24 fps -> 25 fps as well, provided fields are added). More\n      about this can be found in the `Force Film, IVTC, and Deinterlacing`_\n      tutorial.\n\n-   **Hybrid content:**\n\n|     Hybrid content is content with different base frame rates (for example 8, 12,\n      and 16 fps at which anime is often drawn). Start Trek is a different example\n      consisting of telecined (at 30 fps) and interlaced content (at 30 fps).  Have\n      a look at :doc:`this article <../advancedtopics/hybrid_video>` for more information on this subject.\n\n-   **Blended content:**\n\n|     Blended content is content which consists of blended fields (in some fields\n      there is content from different time-instants visible). It's usually the\n      result of bad NTSC to PAL conversions (and vice-versa), or messed-up\n      deinterlacing. Some examples can be found `in these guides`_ `on Doom9`_.\n\n\nHow do I process interlaced content?\n------------------------------------\n\nThere are two ways to process your interlaced content (assuming that you use\na filter which has no interlaced=true option). The first one is the most\naccurate, but also the slowest: bobbing, processing and reinterlacing. The\nsecond one is the fastest, but also less accurate one: processing the fields\nseparately.\n\n1) bobbing:\n\n::\n\n    AssumeTFF() # or AssumeBFF (set the video's field order correctly)\n    TDeint(mode=1, type=3) # or any other smart Bob\n    Filter(...)\n    AssumeTFF() # or AssumeBFF (set the video's field order correctly)\n    Separatefields()\n    Selectevery(4,0,3)\n    Weave()\n\n2) processing the fields separately:\n\n::\n\n    SeparateFields()\n    even = SelectEven(last).Filter(...)\n    odd = SelectOdd(last).Filter(...)\n    Interleave(even, odd)\n    Weave()\n\n\nHow do I process telecined content?\n-----------------------------------\n\nYou need to inverse telecine (IVTC) before you do any processing. You can use\nthe plugin Decomb for example, `which can be downloaded here`_. See the\ntutorials \"`Force Film, IVTC, and Deinterlacing - what is DVD2AVI trying to\ntell you and what can you do about it.`_\" or \"`the analog capture guide`_\"\nwhich explain how to do this.\n\n\nHow do I process hybrid content?\n--------------------------------\n\nYou only run into troubles when your clip as openend in AviSynth shows\ncombing (being partly interlaced, telecined, etc ...). I'm not sure yet what\nto do in that case.\n\n\nWhat is variable framerate video?\n---------------------------------\n\nThere are two kinds of video when considering framerate, constant framerate\n(cfr) video and variable framerate (vfr) video. For cfr video the frames have\na constant duration, and for vfr video the frames have a non-constant\nduration. Many editing programs (including VirtualDub and AviSynth) assume\nthat the video is cfr, partly because avi doesn't support vfr. Although the\navi container doesn't support vfr, there are several containers (mkv, mp4 and\nwmv/asf for example) which do support vfr. More information can be found\n:doc:`here <../advancedtopics/hybrid_video>`.\n\n\nHow do I import variable framerate video into AviSynth and how do I process it?\n-------------------------------------------------------------------------------\n\nThere are two ways to import variable framerate video into AviSynth:\n\n1.  Open the video in AviSynth using for example DirectShowSource(...,\n    convertfps=false) or FFmpegSource. The problem is that in those cases no\n    frames are added or removed to convert it to constant framerate video to\n    ensure sync.\n\nGenerate a timecode file using some external program or using the AviSynth\nplugin you use for importing the video into AviSynth (if possible). Many non-\nAVI files contain video with a variable framerate, and in that case you need\nto make sure of the following two things:\n\n    1.  *Don't change the framerate and the number of frames in\n    AviSynth.* If you don't this (and you don't change the timecodes file\n    manually) your video and audio in your final encoding will be out of\n    sync.\n\n    2.  *Use the timecodes file again when muxing your encoded video and\n    audio.* If you don't do this your video and audio in your final encoding\n    will be out of sync.\n\n2.  Open the video in AviSynth using for example DirectShowSource(...,\n    convertfps=true). In this case frames are added or removed to convert it\n    to constant framerate video to ensure sync. You can process the video the\n    way you want. You can even create a new timecodes file and create a new\n    variable framerate video using it. More information can be found :doc:`here <../advancedtopics/hybrid_video>`.\n\nRegarding the first way. If you did change the framerate or the number of\nframes, you can use DeDup to recreate a new timecode file:\n\n::\n\n    dedup_dedup(threshold=0.1, maxcopies=10, maxdrops=4, log=\"01.log\", timesin=\"original.tmc\", times=\"final.tmc\")\n\nThe parameter \"timesin\" specifies the timecode file of the original video on\nwhich the output file will be based on (rather than just using the input\nstream's framerate). I never used it, so I'm not sure how good this is. Look\n`here for a discussion`_.\n\n| :doc:`Main Page <faq_sections>` | :doc:`General Info <faq_general_info>` | :doc:`Loading Clips <faq_loading_clips>` | :doc:`Loading Scripts <faq_frameserving>` | :doc:`Common Error Messages <faq_common_errors>` | **Processing Different Content** | :doc:`Dealing with YV12 <faq_yv12>` | :doc:`Processing with Virtualdub Plugins <faq_using_virtualdub_plugins>` |\n\n$Date: 2025-02-25 17:15:45-05:00 $\n\n.. _DirectShowSource: http://avisynth.nl/index.php/DirectShowSource\n.. _Analog Capture Guide: http://www.doom9.org/index.html?/capture/introduction.html\n.. _Force Film, IVTC, and Deinterlacing: http://www.doom9.org/ivtc-tut.htm\n.. _in these guides:\n    http://www.doom9.org/index.html?/capture/postprocessing_avisynth.html\n.. _which can be downloaded here: http://neuron2.net/decomb/decombnew.html\n.. _Force Film, IVTC, and Deinterlacing - what is DVD2AVI trying to tell\n    you and what can you do about it.: http://www.doom9.org/ivtc-tut.htm\n.. _on Doom9: http://www.doom9.org/ivtc-tut.htm\n.. _the analog capture guide:\n    http://www.doom9.org/index.html?/capture/postprocessing_avisynth.html\n.. _here for a discussion: http://forum.doom9.org/showthread.php?t=121593\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/faq/faq_frameserving.rst",
    "content": "\nAviSynth FAQ - Opening scripts in encoder and player applications\n=================================================================\n\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\n\nWhat is frameserving and what is it good for?\n---------------------------------------------\n\nAn excellent description is found on `Lukes homepage`_:\n\n\"Frameserving is a process by which you directly transfer video data from one\nprogram on your computer to another. No intermediate or temporary files are\ncreated. The program that opens the source file(s) and outputs the video data\nis called the frameserver. The program that receives the data could be any\ntype of video application.\n\nThere are two main reasons that you would want to frameserve a video:\n\n1.  **Save Disk Space**: Depending on the frameserving application, you\n    can usually edit/process your video as it is being frameserved. Because\n    frameserving produces no intermediate files, you can use a frameserver to\n    alter your videos without requiring any additional disk space. For\n    example, if you wanted to join two video files, resize them, and feed\n    them to another video application, frameserving would allow you to do\n    this without creating a large intermediate file.\n2.  **Increased Compatibility**: To the video application that's\n    receiving the frameserved video, the input looks like a relatively small,\n    uncompressed video file. However, the source file that the frameserver is\n    transferring could actually be, for example, a highly compressed MPEG-1\n    video. If your video application doesn't support MPEG-1 files, it's not a\n    problem because the application is just receiving standard uncompressed\n    video from the frameserver. This feature of frameserving enables you to\n    open certain types of files in an application that wouldn't normally\n    support them.\n\nFurthermore, because the video application is being fed the source video one\nframe at a time, it doesn't know anything about the file size of the source\nvideo. Therefore, if your application has 2 GB or 4 GB limit on input file\nsize, it won't have any effect on your frameserved video. You could feed 100\nGB of video via a frameserver to an application limited to 2 GB and it\nwouldn't cause a problem.\"\n\n\nHow do I use AviSynth as a frameserver?\n---------------------------------------\n\nWrite a script using a text editor. Load your clip in AviSynth (see\n:doc:`FAQ loading clips <faq_loading_clips>`), do the necessary filtering and load the AVS-file in\nencoder/application X (must be an encoder or application which can read AVI-\nfiles (see also `here`_).\n\n\nHow do I frameserve my AVS-file to encoder/application X?\n---------------------------------------------------------\n\nThere is simple way for many applications, and tricky ways for many others.\n\n\nDirect frameserving to compatible applications\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nSimply open your AVS file in coder/application with menu, command line or\ndrag-and-drop AVS file to it (working ways are dependent on the application).\nSome programs have ``\"AviSynth *.avs\"`` in \"Open\" menu, for others try select\n\"All files *.*\" or type AVS file name instead of \"AVI\".\n\nPlayers: Media Player Classic, Windows Media Player 6.4, 9 and others.\n\nEncoders: QuEnc, Mencoder, HC Encoder, CCE SP 2.50 and 2.66, Canopus Procoder\n1.5 and above, MainConcept MPEG Encoder, TMPGEnc, TMPGEncXpress 3/4, Elecard\nConverter Studio, xvid_encraw, FFMpeg (new versions), Nero 6, Nero 7 (drag-\nand-drop only) and others.\n\nEditors: VirtualDub, AviDemux (through its avs proxy option)\n\nBut some applications work fine only with some specific video or audio\nformats, have a look at the next section.\n\n\nDirect frameserving to applications using additional plugins\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n-   For frameserving to Premiere there exists an import plugin \"IM-\n    Avisynth.prm\".\n\nThe original version was located at `Bens site`_, see `mirror`_. A much\nimproved version can be downloaded from the `Video Editors Kit sourceforge\npage`_. This works for Premiere 5.x, 6.x and Pro at present. Version 1.5 also\nworks for Premier CS3. To install the import plugin move the IM-Avisynth.prm\nfile into your Premiere \"Plug-ins\" directory.\n\n\nDirect frameserving to special or modified versions of encoders\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nSome programs initially could not open AviSynth scripts, but updated or\nalternative programs can do it:\n\n-   Mencoder\n-   FFMpeg: Versions older then SVN-r6129 use the \"AVSredirect.dll\" for\n    communication with Avisynth. From SVN-r6129 up, AVS redirect code is\n    integrated in the FFmpeg executable (as option at compiling). Use builds\n    at `http://ffdshow.faireal.net/mirror/ffmpeg/`_\n-   Windows Media 9 Encoder: Download Nic's Windows Media 9 Encoder and\n    make sure you also installed the Windows Media 9 codec. Both can be found\n    `here`_.\n\n\nFrameserving to applications via fake AVI files and proxy utilities\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nMany \"new\" programs do NOT use the Windows functions to read the AVI-files.\nIf they use own read functions the AviSynth-script files will not work. There\nare utilities that can create small fake AVI file with special type (FOURCC),\nand provide correspondent system codec to \"decode\" these dummy compressed\nfiles.\n\nSelect your AVS file in utility menu, set options and create fake AVI file\nwith some name. Then you can open this fake AVI in your application/encoder,\nthat will be receive frames from the codec that wiil be receive frames from\nAviSynth.\n\nSeveral such utilities are different by supported modes (formats) of output\nvideo (with or without conversion) and audio (unpacked audio is most\ncompatible but filesize is larger), by user interface (window, command line)\nand number of bugs.\n\n-   `VFAPI reader codec`_ with DGVfapi (as a client) from `DGDMPGDec`_.\n\nFeatures - output RGB24 only, unpacked audio, multiple files support, good\ncompatibility, but a bit slow.\n\n-   MakeAVIS is included in ffvfw and `FFDShow`_.\n\nFeatures - ouput to any color format. Uncompressed audio works properly in\nold ffvfw and recent (13 november 2007) ffdshow (8 and 16 bit only, use\n:doc:`ConvertAudioTo16bit <../corefilters/convertaudio>` when necessary).\n\n-   `Proxy-codec AVS2AVI`_. (Note that the same-name utility by Moitah\n    and others is an encoder and not an AVI-wrapper.)\n\nFeatures - video output same as input format, no audio.\n\nKnown programs that will not open AVS scrips without these utilities:\nCCE SP v2.62-2.64, Windows Media Encoder vx.x. (older than v9), Ulead\nVideoStudio 5-11, MediaStudio 6-8, Pinnacle Studio, Sony Vegas, Nero 8,\nImageMixer and others.\n\n\nFrameserving via pipe from auxiliary programs to application-encoders\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n`Avs2YUV`_ is a command-line program, intended for use under Wine, to\ninterface between AviSynth and Linux-based video tools.\n\nPrograms: Mpeg2enc, Mencoder, FFMpeg.\n\navs2yuv out.avs -o - | mpeg2enc - options...\n\nThis way is obsolete since these programs have native AviSynth support now.\n\n\nHow do I solve problems when opening/reading scripts in encoders and players?\n-----------------------------------------------------------------------------\n\n1.  TMPGEnc doesn't read my AVS files (this happens in old versions of\n    TMPGEnc), what to do?\n\n    -   Install the VFAPI plugin for TMPGEnc.\n    -   Disable the direct show filters within TMPGEnc and turn off the\n        VirtualDub proxy before frameserving.\n    -   Add \":doc:`ConvertToRGB24 <../corefilters/convert>`\" at the end of your AVS-file.\n    -   Install `Huffyuv`_/`DivX`_ codec so that it can do the\n        decompression for you when loading an AVI in TMPGEnc.\n    -   Install the `ReadAVS plugin`_. Just copy ReadAVS.dll to the VFAPI\n        reader directory and open the reg-file ReadAVS.reg in notepad and change\n        the corresponding path. Save it, and doubleclick on it to merge it with\n        your registry-file.\n\n2.  CCE SP crashes when reading an AVS-file, what to do?\n\n    -   If you're using Win2k then run CCE in WinNT4-SP5 compatibility mode.\n    -   Put addaudio.avsi in your AviSynth plugin folder and add\n        ``AddAudio(44100)`` in your script, if you don't have any audio in your\n        AVS-file.\n    -   Some versions (like CCE SP v2.62/v2.64) don't read AVS files. Get\n        CCE SP v2.66 or a more recent version.\n\n3.  My encoder or player doesn't open AviSynth scripts, what should I do?\n\n    -   In this case you may try other way, for example an AVI wrapper,\n        like `vfapi`_ or `makeAVIS`_.\n\n4.  When opening my clip in an encoder or player, the colors are messed\n    up, what to do?\n\n    -   If you have such problems, some external (or internal) codec is\n        messing up the used colorspace conversion. If you have such problems add\n        :doc:`ConvertToRGB24 <../corefilters/convert>` as the last line of your script (for Procoder and CCE\n        use ConvertToYUY2(interlaced=true) or =false) and have a look at the\n        thread (and the suggested solutions) `colorspace conversion errors`_.\n\n5.  Windows Media Encoder 9 Series does not open AVS files, what to do?\n\n    -   Use an `updated WMCmd.vbs script`_ [`discussion about the fix`_].\n\n    -   In order to use AviSynth source with WME9, you need to set the\n        encoder source to \"Both device and file\" in the Session Properties, see\n        `discussion`_ and `WMV faq`_. Or use `Nic's WMV encoder`_.\n\n6.  WMP11 on Vista dos no play AVS, what to do?\n\n    -   You may `edit registry`_ to add .avs as known extension. Copy the\n        registry key (and subkeys) for\n\n        ``HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Multimedia\\WMPlayer\\Extensions\\.avi``\n\n        to\n\n        ``HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Multimedia\\WMPlayer\\Extensions\\.avs``\n\n    -   On Vista x64 you have to copy the correct 32-Bit nodes:\n\n        ``HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Multimedia\\WMPlayer\\Extensions\\.avi``\n\n        to\n\n        ``HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Multimedia\\WMPlayer\\Extensions\\.avs``\n\n    -   Do not change anything at the registry if you are not experienced!\n\n\nHow do I frameserve from Premiere/Ulead/Vegas to AviSynth?\n----------------------------------------------------------\n\nInstall the AviSynth compatible frameserver `PluginPace frameserver (by\nSatish Kumar)`_ for frameserving from SonicFoundry Vegas (and earlier Vegas\nVideo/VideoFactory versions), Adobe Premiere, Ulead MediaStudio Pro or Wax to\nAviSynth (`discussion here`_).\n\n| :doc:`Main Page <faq_sections>` | :doc:`General Info <faq_general_info>` | :doc:`Loading Clips <faq_loading_clips>` | **Loading Scripts** | :doc:`Common Error Messages <faq_common_errors>` | :doc:`Processing Different Content <faq_different_types_content>` | :doc:`Dealing with YV12 <faq_yv12>` | :doc:`Processing with Virtualdub Plugins <faq_using_virtualdub_plugins>` |\n\n$Date: 2025-02-25 17:18:34-05:00 $\n\n.. _Lukes homepage: http:///neuron2.net/lvg/frameserving.html\n.. _Bens site: http://math.berkeley.edu/~benrg/avisynth-premiere.html\n.. _mirror: http://neuron2.net/www.math.berkeley.edu/benrg/avisynth-premiere.html\n.. _Video Editors Kit sourceforge page:\n    http://sourceforge.net/projects/videoeditorskit/\n.. _http://ffdshow.faireal.net/mirror/ffmpeg/:\n    http://ffdshow.faireal.net/mirror/ffmpeg/\n.. _here: http://nic.dnsalias.com/WM9Enc.html\n.. _Nic's WMV encoder: http://nic.dnsalias.com/WM9Enc.html\n.. _VFAPI reader codec:\n    http://www.doom9.org/Soft21/SupportUtils/VFAPIConv-1.05-EN.zip\n.. _DGDMPGDec: http://neuron2.net/dgmpgdec/dgmpgdec.html\n.. _FFDShow: http://sourceforge.net/project/showfiles.php?group_id=173941\n.. _Proxy-codec AVS2AVI: http://hmd.c58.ru/files.html\n.. _Avs2YUV: http://akuvian.org/src/avisynth/avs2yuv/\n.. _Huffyuv: http://avisynth.nl/index.php/Huffyuv\n.. _DivX: http://avisynth.nl/index.php/DivX\n.. _ReadAVS plugin: http://www.math.berkeley.edu/~benrg/avisynth/tmpgenc-readavs.zip\n.. _AddAudio: http://avisynth.nl/index.php/AddAudio\n.. _vfapi: http://avisynth.nl/index.php/Vfapi\n.. _makeAVIS: http://avisynth.nl/index.php/MakeAVIS\n.. _colorspace conversion errors:\n    http://forum.doom9.org/showthread.php?s=&threadid=27932\n.. _updated WMCmd.vbs script: http://www.citizeninsomniac.com/WMV/#WMCmd\n.. _discussion about the fix:\n    http://forum.doom9.org/showthread.php?t=65638\n.. _discussion: http://forum.doom9.org/showthread.php?t=48477\n.. _WMV faq: http://forum.doom9.org/showthread.php?t=112634\n.. _edit registry: http://forum.doom9.org/showthread.php?t=121674\n.. _PluginPace frameserver (by Satish Kumar):\n    http://www.debugmode.com/pluginpac/frameserver.php\n.. _discussion here: http://forum.doom9.org/showthread.php?s=&threadid=51242\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/faq/faq_general_info.rst",
    "content": "\nAviSynth FAQ - General information\n==================================\n\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\n\n.. _What is AviSynth:\n\nWhat is AviSynth?\n-----------------\n\nAviSynth (AVI SYNTHesizer) is a frameserver. An excellent description is\ngiven on `Lukes homepage`_:\n\n\"AviSynth is a very useful utility created by Ben Rudiak-Gould. It provides\nmany options for joining and filtering videos. What makes AviSynth unique is\nthe fact that it is not a stand-alone program that produces output files.\nInstead, AviSynth acts as the \"middle man\" between your videos and video\napplications.\n\nBasically, AviSynth works like this: First, you create a simple text document\nwith special commands, called a script. These commands make references to one\nor more videos and the filters you wish to run on them. Then, you run a video\napplication, such as Virtualdub, and open the script file. This is when\nAviSynth takes action. It opens the videos you referenced in the script, runs\nthe specified filters, and feeds the output to video application. The\napplication, however, is not aware that AviSynth is working in the\nbackground. Instead, the application thinks that it is directly opening a\nfiltered AVI file that resides on your hard drive.\n\nThere are five main reasons why you would want to use AviSynth:\n\n1.  Join Videos: AviSynth lets you join together any number of videos,\n    including segmented AVIs. You can even selectively join certain portions\n    of a video or dub soundtracks.\n2.  Filter Videos: Many video processing filters are built in to\n    AviSynth. For example, filters for resizing, cropping, and sharpening\n    your videos.\n3.  Break the 2 GB Barrier: AviSynth feeds a video to a program rather\n    than letting the program directly open the video itself. Because of this,\n    you can usually use AviSynth to open files larger than 2 GB in programs\n    that don't natively support files of that size.\n4.  Open Unsupported Formats: AviSynth can open almost any type of video,\n    including MPEGs and certain Quicktime MOVs. However, when AviSynth feeds\n    video to a program, it looks just like a standard AVI to that program.\n    This allows you to open certain video formats in programs that normally\n    wouldn't support them.\n5.  Save Disk Space: AviSynth generates the video that it feeds to a\n    program on the fly. Therefore, no temporary or intermediate videos are\n    created. Because of this, you save disk space.\"\n\n\n.. _Who is developing AviSynth:\n\nWho is developing AviSynth?\n---------------------------\n\nOriginally AviSynth (up to v1.0b) was developed by Ben Rudiak-Gould. See\n`mirror of his homepage`_. Currently it is developed by Sh0dan, IanB,\nd'Oursse (AviSynth v3), Bidoche (AviSynth v3) and `others`_.\n\n\n.. _Where can I download the latest versions of AviSynth:\n\nWhere can I download the latest versions of AviSynth?\n-----------------------------------------------------\n\nThe most recent stable version is v2.57, which can be found `on Sourceforge`_ (just as\nmore recent builds).\n\n\n.. _What are the main bugs in these versions:\n\nWhat are the main bugs in these versions?\n-----------------------------------------\n\nCurrent bugs can be found in the documentation on the `AviSynth project\npage`_. Fixed bugs can be found in the :doc:`Changelist <../changelist>`.\n\n\n.. _Where can I find documentation about AviSynth:\n\nWhere can I find documentation about AviSynth?\n----------------------------------------------\n\nDocumentation about the filters of AviSynth can be found on the main\npage of `AviSynth's website`_, and in particular here: :doc:`Internal filters <../corefilters>`. You should read these\ndocuments before posting to the forum, but it's OK to post if you have\ntrouble understanding them.\n\n\n.. _How do I install/uninstall AviSynth:\n\nHow do I install/uninstall AviSynth?\n------------------------------------\n\nStarting from v2.06 AviSynth comes with an auto installer. Also make sure you\nhave no other versions of AviSynth floating around on your harddisk, because\nthere is a chance that one of those versions will be registered. Remove them\nif necessary. For uninstalling AviSynth go to \"program\", \"AviSynth 2.5\" and\nselect \"Uninstall AviSynth\".\n\nInstalling AviSynth v2.05 or older versions: move avisynth.dll to your\nsystem/system32 directory and run install.reg. For uninstalling run\nuninstall.reg and delete avisynth.dll.\n\n\n.. _What is the main difference between v1.0x, v2.0x, v2.5x, v2.6x and v3.x:\n\nWhat is the main difference between v1.0x, v2.0x, v2.5x, v2.6x and v3.x?\n------------------------------------------------------------------------\n\nThe versions v1.0x and v2.0x are compatible and outdated. The main difference\nwith v2.5x is that the internal structure of AviSynth has changed (YV12 and\nmultichannel support) with the consequence that external plugins compiled for\nv1.0x/v2.0x will not work for v2.5x/v2.6x and vice versa. In v2.6x other\nplanar formats like YV24 and Y8 are added. v2.5x plugins will work in v2.6x\nbut not vice-versa. All versions are incompatible with v3.x, which will also\nwork under Linux/MacOSX (see `AviSynth v3`_) and rely on the GStreamer API.\n\n\n.. _How do I know which version number of AviSynth I have:\n\nHow do I know which version number of AviSynth I have?\n------------------------------------------------------\n\nOpen a text-editor, for example notepad. Add the following line\n\n::\n\n    Version()\n\nand save the file with the extension \"avs\". Save for example as \"version.avs\"\n(make sure that the extension is \"avs\" and not \"txt\"). Open the file in an\napplication which can read AVI-files, for example WMP 6.4 or Media Player\nClassic. The version number will be displayed.\n\n\n.. _How do I make an AVS-file:\n\nHow do I make an AVS-file?\n--------------------------\n\nUse your preferred text editor (e.g. Notepad). See also :ref:`this <How do I know which version number of AviSynth I have>`.\n\nAlthough AviSynth doesn't need them, there are several GUIs (graphical user\ninterface) which may help you writing your AVS files. You can read a\ndescription for each one of them :ref:`under the GUI entry <Does AviSynth have a GUI (graphical user interface)>`.\n\n\n.. _Where do I save my AVS-file:\n\nWhere do I save my AVS-file?\n----------------------------\n\nAnywhere on your hard-disk.\n\n\n.. _Are plugins compiled for v2.5x/v2.6x compatible with v1.0x/v2.0x and vice versa:\n\nAre plugins compiled for v2.5x/v2.6x compatible with v1.0x/v2.0x and vice versa?\n--------------------------------------------------------------------------------\n\nAs explained :ref:`earlier <What is the main difference between v1.0x, v2.0x, v2.5x, v2.6x and v3.x>` that is not the case. However it is possible to use a\nv1.0x/v2.0x plugin in v2.5x/v2.6x, as explained :ref:`next <How do I use a plugin compiled for v2.0x in v2.5x>`.\n\n\n.. _How do I use a plugin compiled for v2.0x in v2.5x:\n\nHow do I use a plugin compiled for v2.0x in v2.5x?\n--------------------------------------------------\n\nSee http://avisynth.nl/index.php/LoadOldPlugins. (When using an older version of LoadPluginEx.dll, don't\nmove this plugin to your plugin dir. But move it to a separate folder,\notherwise VirtualdubMod and WMP6.4 will crash on exit.) This will enable you\nusing v2.0x plugins in v2.5x. An example script (using the v2.0x plugin Dust\nby Steady):\n\n::\n\n    LoadPlugin(\"C:\\Program Files\\avisynth2_temp\\plugins\\LoadPluginEx.dll\")\n    LoadPlugin(\"C:\\Program Files\\avisynth2_temp\\plugins\\dustv5.dll\")\n\n    AviSource(\"D:\\clip.avi\")\n    ConvertToYUY2()\n    PixieDust(5)\n\nIf you want to automate this process, have a look at `LoadOldPlugins`_.\n\n\n.. _How do I switch between different AviSynth versions without re-install:\n\nHow do I switch between different AviSynth versions without re-install?\n-----------------------------------------------------------------------\n\n-   You can use AvisynthSwitcher available `on lalternative`_. Versions v2.08 and\n    v2.50 are provided, but you can easily add a new one under\n    AvisynthSwitcher\\versions\\Avisynth 2.x.x.\n\n-   Some other ways are described `in this thread`_.\n\n\n.. _VirtualdubMod, WMP6.4, CCE and other programs crash every time on exit (when previewing an avs file):\n\nVirtualdubMod, WMP6.4, CCE and other programs crash every time on exit (when previewing an avs file)?\n-----------------------------------------------------------------------------------------------------\n\nThis problem can be caused by certain plugins in your (autoloading) plugin\nfolder. The solution is to move the problematic plugins outside your plugin\nfolder and load them manually.\n\n\n.. _My computer seems to crash at random during a second pass in any encoder:\n\nMy computer seems to crash at random during a second pass in any encoder?\n-------------------------------------------------------------------------\n\nAviSynth is highly optimized. As a consequence it is possible that your\ncomputer seems to crash at random during a second pass. Try running the\n`Prime95`_ stress test for an hour, to check if your system is stable. If\nthis test fails (or your computer locks up) make sure that your computer is\nnot overclocked and lower your bus speed of your processor in steps of (say)\nfive MHz till the crashes are gone.\n\n\n.. _Is there a command line utility for encoding to DivX/XviD using AviSynth:\n\nIs there a command line utility for encoding to DivX/XviD using AviSynth?\n-------------------------------------------------------------------------\n\n-   There is a command line utility called `AVS2AVI`_ (and AVS2AVI GUI)\n    for encoding to DivX / XviD using AviSynth. [`discussion thread`_]\n-   `xvid_encraw`_ for encoding to XviD in M4V. Use `mp4box`_ or `YAMB`_\n    to mux it into MP4.\n\n\n.. _Does AviSynth have a GUI (graphical user interface):\n\nDoes AviSynth have a GUI (graphical user interface)?\n----------------------------------------------------\n\nAviSynth doesn't have a full fledged gui, but several tools are available:\n\n-   `VirtualDubMod`_: The following AviSynth related utilities are\n    present:\n\n    -   'Open via AVISynth' command: This allows you to open any AviSynth\n        compatible video file by automatically generating a suitable script by a\n        selectable template.\n    -   AVS Editor (Hotkey Ctrl+E): Just open your AVS and under tools\n        select \"script editor\". Change something and press F5 to preview the\n        video.\n\n-   AvisynthEditor: This is an advanced AviSynth script editor featuring\n    syntax highlighting, auto-complete code and per version plugin definition\n    files. `Here is a screenshot`_. It can be found `on lalternative`_. Discussion can\n    be found on `Doom9.org forum`_.\n-   `AVSGenie`_: AVSGenie allows the user to select a filter from a drop\n    down list or from a popup menu. An editable page of parameters will then\n    be brought into view, with a guide to the filter and it's parameters. A\n    video preview window opens, showing \"source\" and \"target\" views. The\n    source window, in simple cases, shows output of the first line of the\n    script, generally an opened video file. The target window shows the\n    output of the whole script. In this way, effects of filters can easily be\n    seen. The line which represents the source window can be changed.\n    Discussion can be found `on Doom9`_.\n-   `SwiftAVS (by Snollygoster)`_: Another nice gui, formerly known as\n    AviSynthesizer. [`discussion`_]\n-   `AvsP`_: It's a tabbed script editor for Avisynth. It has many\n    features common to programming editors, such as syntax highlighting,\n    autocompletion, call tips. It also has an integrated video preview, which\n    when coupled with tabs for each script make video comparisons a snap.\n    What really makes AvsP unique is the ability to create graphical sliders\n    and other elements for any filter's arguments, essentially giving\n    Avisynth a gui without losing any of its powerful features. Discussion\n    can be found `here`_.\n\n| :doc:`Main Page <faq_sections>` | **General Info** | :doc:`Loading Clips <faq_loading_clips>` | :doc:`Loading Scripts <faq_frameserving>` | :doc:`Common Error Messages <faq_common_errors>` | :doc:`Processing Different Content <faq_different_types_content>` | :doc:`Dealing with YV12 <faq_yv12>` | :doc:`Processing with Virtualdub Plugins <faq_using_virtualdub_plugins>` |\n\n$Date: 2025-02-25 17:11:30-05:00 $\n\n.. _Lukes homepage: http://neuron2.net/LVG/avisynth.html\n.. _mirror of his homepage:\n    http://neuron2.net/www.math.berkeley.edu/benrg/index.html\n.. _others: http://sourceforge.net/project/memberlist.php?group_id=57023\n.. _on Sourceforge: http://sourceforge.net/project/showfiles.php?group_id=57023\n.. _AviSynth project page:\n    http://sourceforge.net/tracker/?atid=482673&group_id=57023\n.. _AviSynth's website: http://avisynth.nl/index.php/Main_Page\n.. _AviSynth v3: http://avisynth.nl/index.php/AviSynth_v3\n.. _LoadOldPlugins: http://avisynth.nl/index.php/LoadOldPlugins\n.. _on lalternative: http://www.lalternative.org\n.. _in this thread: http://forum.doom9.org/showthread.php?s=&threadid=45181\n.. _Prime95: http://www.mersenne.org/freesoft.htm\n.. _AVS2AVI: http://www.avs2avi.org/\n.. _discussion thread: http://forum.doom9.org/showthread.php?t=71493\n.. _xvid_encraw: http://forum.doom9.org/showthread.php?t=98469\n.. _mp4box: http://kurtnoise.free.fr/index.php?dir=mp4tools/\n.. _YAMB: http://forum.doom9.org/showthread.php?t=115459\n.. _VirtualDubMod: http://avisynth.nl/index.php/VirtualDubMod\n.. _Here is a screenshot:\n    http://www.lalternative.org/img/AvisynthEditor.gif\n.. _Doom9.org forum:\n    http://forum.doom9.org/showthread.php?s=&threadid=49487\n.. _AVSGenie: http://www.yeomanfamily.demon.co.uk/avsgenie/avsgenie.htm\n.. _on Doom9: http://forum.doom9.org/showthread.php?s=&threadid=54090\n.. _SwiftAVS (by Snollygoster):\n    http://sourceforge.net/project/showfiles.php?group_id=74272\n.. _discussion: http://forum.doom9.org/showthread.php?s=&threadid=48326\n.. _AvsP: http://avisynth.nl/users/qwerpoi/\n.. _here: http://forum.doom9.org/showthread.php?t=129385\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/faq/faq_loading_clips.rst",
    "content": "\nAviSynth FAQ - Loading clips (video, audio and images) into AviSynth\n====================================================================\n\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\n\nWhich media formats can be loaded into AviSynth?\n------------------------------------------------\n\nMost video/audio formats can be loaded into AviSynth, but there are some\nexceptions like flv4 (VP6) and dvr-ms. If it is not possible to load a clip\ninto AviSynth, you will have to convert it into some other format which can\nbe loaded. Remember to choose a format for which you will have a minimal\ndowngrade in quality as a result of the conversion.\n\n\nWhich possibilities exist to load my clip into AviSynth?\n--------------------------------------------------------\n\nIn general there are two ways to load your video into AviSynth:\n\n1.  using an AviSynth internal filter or plugin which is designed to open\n    some specific format.\n2.  using the :doc:`DirectShowSource <../corefilters/directshowsource>` plugin.\n\nMake sure that your clip contains maximal one video and/or one audio stream\n(thus remove the subtitles and remove other video/audio streams). If you want\nto load a clip which contains both video and audio, you have two options:\n\n-   Demux the audio stream and load the streams separately in AviSynth.\n-   Try to load the clip in AviSynth. This might or might not work. For\n    AVIs, make sure you have a good AVI splitter installed, e.g. `Gabest's\n    AVI splitter`_. (Yes, Windows comes with an own AVI splitter, which will\n    work in most cases.)\n\nWhen loading a clip into AviSynth it is advised to follow the following\nguidelines:\n\n-   When it is possible to load your clip into AviSynth using either\n    AviSource or a specific plugin then do so, since this is more reliable\n    than the alternatives which are listed below.\n-   If the above fails, load your clip using the DirectShowSource plugin.\n-   If the above fails, convert your clip into a different format (into\n    one which is supported by AviSynth).\n\n\nWhat are the advantages and disadvantages of using DirectShowSource to load your media files?\n---------------------------------------------------------------------------------------------\n\n*advantages of DirectShowSource:*\n\n-   Many video and audio formats are supported through DirectShowSource\n    (have a look at ffdshow for example).\n\n*disadvantages of DirectShowSource:*\n\n-   It's less reliable than AviSource and specific video/audio input\n    plugins.\n-   Seeking problems.\n-   It might be much trouble to get specific DirectShow filter doing the\n    decoding for you. In many cases you will have multiple decoders that can\n    decode the same specific format. The one which will be used is the one\n    with the highest merit. It might be difficult to ensure that a specific\n    decoder is doing the decoding. The document\n    \":doc:`Importing media into AviSynth <../advancedtopics/importing_media>`\"\n    contains some more information about this.\n\n\nHas AviSynth a direct stream copy mode like VirtualDub?\n-------------------------------------------------------\n\nNo, the video and the audio are decompressed when opening them into AviSynth.\n\nThere is a modification of AviSynth v2.55 which supports 'direct stream copy'\nfor both video and audio. This modification is called DSynth and can be\ndownloaded `here`_. Perhaps it will be updated and merged into the official\nAviSynth builds one day.\n\n\nHow do I load AVI files into AviSynth?\n--------------------------------------\n\nUse :doc:`AviSource <../corefilters/avisource>` to load your AVI files in AviSynth. Example:\n\n::\n\n    AviSource(\"d:\\filename.avi\")\n\nor without the audio:\n\n::\n\n    AviSource(\"d:\\filename.avi\", false)\n\nIf AviSynth is complaining about not being able to load your avi (couldn't\ndecompress ...) you need to install an appropriate codec. `GSpot`_, for\nexample, will tell you what codec you need to install in order to be able to\nopen your avi.\n\nForcing a decoder being used for loading the clip into AviSynth:\n\n::\n\n    # load your avi using the XviD codec:\n    AviSource(\"d:\\filename.avi\", fourCC=\"XVID\")\n    # opens an avi (for example encoded with DivX3) using the XviD Codec\n\n::\n\n    # load your dv-avi using the Canopus DV Codec:\n    AviSource(\"d:\\filename.avi\", fourCC=\"CDVC\")\n\nCan I load video with audio from AVI into AviSynth?\n---------------------------------------------------\n\nIt is always possible to demux your audio from the AVI file and load it\nseparately in AviSynth using an audio decoder, but in some cases (for\nexample: AVI with MP2/MP3/AC3/DTS audio) it is possible to load it directly\nin AviSynth.\n\nFor loading your AVI with audio you need (1) a VfW (Video for Windows) codec\nto open (that is decode) your video in AviSynth and an ACM (Audio Compression\nManager) codec to open your audio in AviSynth. For many video and audio\nformat such codecs are available, but certainly not for all of them.\n\nYou can find those codecs in the document \":doc:`Importing media into AviSynth <../advancedtopics/importing_media>`\" .\n\n\nHow do I load MPEG-1/MPEG-2/DVD VOB/TS/PVA into AviSynth?\n---------------------------------------------------------\n\nDGDecode is an external plugin and supports MPEG-1, MPEG-2 / VOB, TS (with\nMPEG-4 ASP video) and PVA streams. Open them into DGIndex first and create a\nd2v script which can be opened in AviSynth (note that it will only open the\nvideo into AviSynth):\n\nA few examples:\n\n::\n\n    # DGDecode:\n    LoadPlugin(\"d:\\dgdecode.dll\")\n    mpeg2source(\"d:\\filename.d2v\")\n\nIf your transport stream (``*.TS``) contains MPEG-4 AVC video you need to demux\nthe raw video stream from it and use `DGAVCDec`_ to open it in AviSynth. See\n`here`_ for its usage.\n\n\nHow do I load QuickTime files into AviSynth?\n--------------------------------------------\n\nThere are two ways to load your quicktime movies into AviSynth (and also\nRawSource for uncompressed movs): QTSource and QTReader. The former one is\nvery recent and able to open many quicktime formats (with the possibility to\nopen them as YUY2), but you need to install QuickTime player in order to be\nable to use this plugin. The latter one is very old, no installation of a\nplayer is required in order to be able to open quicktime formats in AviSynth.\n\nQTSource:\n\nYou will need Quicktime 6 for getting video only or Quicktime 7 for getting\naudio and video.\n\n::\n\n    # YUY2 (default):\n    QTInput(\"FileName.mov\", color=2)\n\n    # with audio (in many cases possible with QuickTime 7)\n    QTInput(\"FileName.mov\", color=2, audio=1)\n\n    # raw (with for example a YUYV format):\n    QTInput(\"FileName.mov\", color=2, mode=1, raw=\"yuyv\")\n\n    # dither = 1; converts raw 10bit to 8bit video (v210 = 10bit uyvy):\n    QTInput(\"FileName.mov\", color=2, dither=1, raw=\"v210\")\n\nQTReader:\n\nIf that doesn't work, or you don't have QuickTime, download the QTReader\nplugin (can be found in Dooms download section):\n\n::\n\n    LoadVFAPIPlugin(\"C:\\QTReader\\QTReader.vfp\", \"QTReader\")\n    QTReader(\"C:\\quicktime.mov\")\n\nHow do I load raw source video files into AviSynth?\n---------------------------------------------------\n\nThe external plugin RawSource supports all kinds of raw video files with the\nYUV4MPEG2 header and without header (video files which contains YUV2, YV16,\nYV12, RGB or Y8 video data).\n\nExamples:\n\n::\n\n    # This assumes there is a valid YUV4MPEG2-header inside:\n    RawSource(\"d:\\yuv4mpeg.yuv\")\n\n    # A raw file with RGBA data:\n    RawSource(\"d:\\src6_625.raw\",720,576,\"BGRA\")\n\n    # You can enter the byte positions of the video frames directly (which can be found with yuvscan.exe).\n    # This is useful if it's not really raw video, but e.g. uncompressed MOV files or a file with some kind of header:\n    RawSource(\"d:\\yuv.mov\", 720, 576, \"UYVY\", index=\"0:192512 1:1021952 25:21120512 50:42048512 75:62976512\")\n\nHow do I load RealMedia files into AviSynth?\n--------------------------------------------\n\nRM/RMVB (RealMedia / RealMedia Variable Bitrate usually containing Real\nVideo/Audio): install the `rmvb splitter`_ and the Real codecs by installing\nRealPlayer/`RealAlternative`_. Create the script:\n\n::\n\n    DirectShowSource(\"d:\\clip.rmvb\", fps=25, convertfps=true) # adjust fps if necessary\n\nHow do I load Windows Media Video files into AviSynth?\n------------------------------------------------------\n\nWMV/ASF (Windows Media Video / Advanced Systems Format; usually containing\nWMV/WMA) is not fully supported by ffdshow, so you will have to install wmv\ncodecs. Get `WMF SDK v9 for W2K or later for XP/Vista`_ which contains the\ncodecs (and the DMO wrappers necessary to use DMO filters in DirectShow). You\ncan also get these codecs from Windows Media Player 9 Series or later,\nWindows Media Format runtime (WMFDist.exe), Codec Installation Package\n(WM9Codecs.exe) from Microsoft site or other place. (Note that Microsoft's\nown VC1 codec is not supported in W2K since you need WMF SDK v11.) Create the\nscript:\n\n::\n\n    DirectShowSource(\"d:\\clip.wmv\", fps=25, convertfps=true) # adjust fps if necessary\n\n\n.. _How do I load MP4/MKV/M2TS/EVO into AviSynth:\n\nHow do I load MP4/MKV/M2TS/EVO into AviSynth?\n---------------------------------------------\n\nIf your media file contains MPEG-4 ASP video, then there are two\npossibilities of opening them in AviSynth:\n\n1) Using the plugin `FFmpegSource`_. Some examples:\n\n::\n\n    # loading the video from MKV and returning a timecodes file:\n    FFmpegSource(\"D:\\file.mkv\", vtrack = -1, atrack = -2, timecodes=\"timecodes_file.txt\")\n\n    # loading the video and audio from a MP4 and returning a timecodes file:\n    FFmpegSource(\"D:\\file_aac.mp4\", vtrack = -1, atrack = -1, timecodes=\"timecodes_file.txt\")\n\nIt's important to generate a timecode file to check whether the video has a\nconstant framerate. If this the case you don't need to use the timecode file\nand you can process the video in any way you want. However, many non-AVI\nfiles contain video with a variable framerate (AVI files always have a\nconstant framerate though), and in that case you need to make sure of the\nfollowing two things:\n\n1.  *Don't change the framerate and the number of frames in AviSynth.* If\n    you do this (and you don't change the timecodes file manually) your video\n    and audio in your final encoding will be out of sync.\n2.  *:ref:`Use the timecodes file again <create-vfr-mkv>` when muxing your encoded video and\n    audio.* If you don't do this your video and audio in your final encoding\n    will be out of sync.\n\nThe main reason for this is that FFmpegSource opens the video as it is. It\ndoesn't add or remove frames to convert it to constant framerate video to\nensure sync.\n\n2) Get `ffdshow`_ and open the MP4/MKV file with DirectShowSource, thus\n   for example\n\n::\n\n    DirectShowSource(\"D:\\file.mkv\", convertfps=true)\n    # convertfps=true ensures sync if your video has a variable framerate\n\nIf your media file contains MPEG-4 AVC video, then there are two\npossibilities of opening them in AviSynth:\n\n1) Using the plugin `FFmpegSource`_. See above for its usage. At the\n   moment, the supported containers are: AVI, MKV and MP4.\n\n2) Get `DGAVCDec`_. At the moment you need to extract the raw stream\n   (``*.264``)  from the container first (using MKVExtract, MPlayer, TSRemux or\n   whatever program can extract those streams). Open the raw stream file in\n   DGAVCIndex to create an index file (say track1.dga). Open the index file\n   in AviSynth:\n\n::\n\n    # raw video demuxed from M2TS (Blu-ray BDAV MPEG-2 transport streams)\n    LoadPlugin(\"C:\\Program Files\\AviSynth\\plugins\\DGAVCDecode.dll\")\n    AVCSource(\"D:\\track1.dga\")\n\nHow do I load WAVE PCM files into AviSynth?\n-------------------------------------------\n\nUse WavSource to open your WAVE PCM files (assuming that they are smaller\nthan 4GB):\n\n::\n\n    WavSource(\"D:\\file.wav\")\n\nUse the plugin RaWav to open your WAVE PCM files that are larger than 4GB\n(`Sonic Foundry Video Editor Wave64 Files or W64`_):\n\n::\n\n    RaWavSource(\"D:\\file.w64\", SampleRate=96000, SampleBits=24, Channels=6)\n\n    # or when a W64 header is present\n    RaWavSource(\"D:\\file.w64\", SampleRate=6) # assumes the presence of a\n    W64 header and reads the needed info from it\n\nHow do I load MP1/MP2/MP3/MPA/AC3/DTS/LPCM into AviSynth?\n---------------------------------------------------------\n\nUse NicAudio for loading your MP1/MP2/MP3/MPA/AC3/DTS/LPCM in AviSynth:\n\nSome examples:\n\n::\n\n    LoadPlugin(\"C:\\Program Files\\AviSynth25\\plugins\\NicAudio.dll\")\n\n    # AC3 audio:\n    V = BlankClip(height=576, width=720, fps=25)\n    A = NicAC3Source(\"D:\\audio.AC3\")\n    # A = NicAC3Source(\"D:\\audio.AC3\", downmix=2) # downmix to stereo\n    AudioDub(V, A) ::# LPCM audio (48 kHz, 16 bit and stereo):\n    V = BlankClip(height=576, width=720, fps=25)\n    A = NicLPCMSource(\"D:\\audio.lpcm\", 48000, 16, 2)\n    AudioDub(V, A)\n\nHow do I load aac/flac/ogg files into AviSynth?\n-----------------------------------------------\n\nUse ffdshow (set AAC to libfaad or realaac), and use\n\n::\n\n    DirectShowSource(\"d:\\audio.aac\")\n\nFor WAVE_FORMAT_EXTENSIBLE, ogg, flac, wma, and other formats, `BassAudio and\nthe correspoding libraries and Add-Ons`_ can be used. Note that\nBassAudioSource can decode stereo aac/mp4, but it can't decode multichannel\naac.\n\nSome examples:\n\n::\n\n    bassAudioSource(\"C:\\ab\\Dido\\001 Here With Me.m4a\")\n\n    or\n\n    bassAudioSource(\"C:\\ab\\Dido\\001 Here With Me.aac\")\n\n\nHow do I load pictures into AviSynth?\n-------------------------------------\n\n1) Use :doc:`ImageReader <../corefilters/imagesource>` or :doc:`ImageSource <../corefilters/imagesource>` to load your pictures into\n   AviSynth (can load the most popular formats, except GIF and animated\n   formats). See internal documentation for information.\n\n2) Use the Immaavs plugin for GIF, animated formats and other type of\n   pictures.\n\n::\n\n    # single picture:\n    immareadpic(\"x:\\path\\pic.bmp\")\n\n    # animation:\n    immareadanim(\"x:\\path\\anim.gif\")\n\n    # image sequence:\n    immareadseq(\"x:\\path\\seq%3.3d.png\", start=5, stop=89, fps=25,\n    textmode=2, posx=50, posy=50)\n\n| :doc:`Main Page <faq_sections>` | :doc:`General Info <faq_general_info>` | **Loading Clips** | :doc:`Loading Scripts <faq_frameserving>` | :doc:`Common Error Messages <faq_common_errors>` | :doc:`Processing Different Content <faq_different_types_content>` | :doc:`Dealing with YV12 <faq_yv12>` | :doc:`Processing with Virtualdub Plugins <faq_using_virtualdub_plugins>` |\n\n$Date: 2011/12/04 15:27:59 $\n\n.. _Gabest's AVI splitter:\n    http://sourceforge.net/project/showfiles.php?group_id=205650\n.. _here: http://esby.free.fr/\n.. _GSpot: http://www.headbands.com/gspot/\n.. _DGAVCDec: http://forum.doom9.org/showthread.php?p=959013\n.. _rmvb splitter: http://sourceforge.net/projects/guliverkli/\n.. _RealAlternative: http://www.free-codecs.com/download/Real_Alternative.htm\n.. _WMF SDK v9 for W2K or later for XP/Vista:\n    http://msdn.microsoft.com/windowsmedia/downloads/default.aspx\n.. _FFmpegSource: http://forum.doom9.org/showthread.php?t=127037\n.. _ffdshow: http://ffdshow-tryout.sourceforge.net/\n.. _Sonic Foundry Video Editor Wave64 Files or W64:\n    http://dotwhat.net/w64/9033/\n.. _BassAudio and the correspoding libraries and Add-Ons:\n    http://forum.doom9.org/showthread.php?t=108254\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/faq/faq_sections.rst",
    "content": "\nAviSynth Frequently Asked Questions\n===================================\n\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\n\nGeneral information\n-------------------\n\n:doc:`Section [1] <faq_general_info>` contains some general information about AviSynth. It's about\nits history, the different versions floating around. It explains how to get\nit to work, how to create a script and how to use plugins. It also discusses\nsome command line utilities and graphical user interfaces which are able to\nopen AviSynth scripts.\n\n\nLoading clips (video, audio and images) into AviSynth\n-----------------------------------------------------\n\n:doc:`Section [2] <faq_loading_clips>` explains how to import the most common media formats (video,\naudio and images) into AviSynth. It explains which internal filters or\nexternal plugins can be used to import them and how this should be done. If\nthis section doesn't provide enough information to load your media format,\nyou should read the following document: :doc:`Importing_media <../advancedtopics/importing_media>`. It discusses many\nmedia formats, and gives a systematic way (using multiple ways) of loading\nthese formats into AviSynth.\n\n\nOpening scripts in encoder and player applications\n--------------------------------------------------\n\n:doc:`Section [3] <faq_frameserving>` describes frameserving and how to frameserve from and to\nAviSynth. It explains how to load AviSynth scripts in supported encoders and\nplayers, and what you can do if they don't support AviSynth scripts.\n\n\nSome common error messages\n--------------------------\n\n:doc:`Section [4] <faq_common_errors>` describes some common error messages and explains what to do\nabout them.\n\n\nRecognizing and processing different types of content\n-----------------------------------------------------\n\n:doc:`Section [5] <faq_different_types_content>` explains what you should do when the video and audio in your\nfinal encoding is not in sync. It discusses variable framerate video. It\nexplains how to recognize and process progressive, interlaced, telecined,\nhybrid and blended content.\n\n\nThe color format YV12 and related processing and encoding issues\n----------------------------------------------------------------\n\n:doc:`Section [6] <faq_yv12>` contains specific information about the color format YV12 and\nrelated processing and encoding issues.\n\n\nHow to use VirtualDub's plugins in AviSynth\n-------------------------------------------\n\n:doc:`Section [7] <faq_using_virtualdub_plugins>` explains how to use plugins written for VirtualDub in\nAviSynth.\n\n$Date: 2009/09/12 20:57:20 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/faq/faq_using_virtualdub_plugins.rst",
    "content": "\nAviSynth FAQ - Using VirtualDub plugins in AviSynth\n===================================================\n\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\n\nWhere can I download the latest version of scripts which import filters from VirtualDub?\n----------------------------------------------------------------------------------------\n\nThe AviSynth scripts are on the `Shared_functions`_ page, or you can download\na package called vdub_filtersv15.zip from `[1]`_.\n\n\nWhich filters can be imported?\n------------------------------\n\nMost filters. Read the corresponding documentation.\n\n\nDo these scripts work in RGB-space or in YUV-space?\n---------------------------------------------------\n\nYou need to convert your clip to RGB32 before applying these scripts.\n\n\nHow do I make such a script?\n----------------------------\n\nTake a look at the following example script (this VirtualDub filter can be\ndownloaded from `Donald's homepage`_):\n\nSmart Bob by Donald Graft:\n\n::\n\n    function VD_SmartBob(clip clip, bool show_motion, int threshold, bool\n                         motion_map_denoising)\n    {\n      LoadVirtualdubPlugin(\"d:\\bob.vdf\", \"_VD_SmartBob\", 1)\n      return clip.SeparateFields._VD_SmartBob(clip.GetParity?1:0,\n        \\  default(show_motion,false)?1:0, default(threshold,10),\n        \\  default(motion_map_denoising,true)?1:0)\n    }\n\nThe VirtualDub plugin is imported with the command \"LoadVirtualdubPlugin\".\nThe first argument gives the path of the plugin, the second argument the name\nfor the plugin that will be used in the script and the third argument is\ncalled the preroll.\n\nThe preroll should be set to at least the number of frames the filter needs\nto pre-process to fill its buffers and/or updates its internal variables.\nThis last argument is used in some filters like: SmartBob, SmartDeinterlace,\nTemporalCleaner and others. The reason is that due to filtering architecture\nof VirtualDub the future frames can't be accessed by a filter. Dividee\nreports: \"In the \"Add filter\" dialog of VirtualDub, some filters have a\n\"Lag:\" value in their description. I think this is the value that must be\nused as preroll. Unfortunately, this indication is not always present. In\nthose cases you have to guess.\" Of course you can always ask the creator of\nthe filter.\n\nThe first step is to find out the sequence of the arguments in the last line\nwhere the clip is returned. Configure the script in VirtualDub and select\n\"Save processing Settings\" in the File Menu or press Ctrl+S. Open the created\n.vcf file with a text editor and you should see lines like this:\n\n::\n\n    VirtualDub.video.filters.Add(\"smart bob (1.1 beta 2)\");\n    VirtualDub.video.filters.instance[0].Config(1, 0, 10, 1);\n\nThe order of the arguments is the one that has to be used in AviSynth. To\nfind the role of the arguments, play with them in VirtualDub and examine the\nresulting lines.\n\nThe second step is to test the filter and to compare it with the VirtualDub\nfilter itself. For the programming itself you can learn a lot by looking at\nthe script which are already contained in vdub_filters.avs.\n\nExample script which uses the function VD_SmartBob:\n\n::\n\n    Import(\"d:\\vdub_filters.avs\")\n    AviSource(\"d:\\filename.avi\")\n    ConvertToRGB32()  # only when necessary (but doesn't hurt)\n    VD_SmartBob(false, 10, true)\n    ConvertBackToYUY2()  # only when necessary\n\nThe package vdub_filtersv15.zip is a bit outdated since many new VirtualDub\nfilters are not in it. If that's the case for your VirtualDub filter and you\ndon't want to create a function yourself (such as VD_SmartBob), could also\nuse the following script:\n\n::\n\n    LoadVirtualdubplugin(\"d:\\bob.vdf\", \"VD_SmartBob\", 1)\n    VD_SmartBob(1, 0, 10, 1) # parameters taken from the .vcf file\n\n| :doc:`Main Page <faq_sections>` | :doc:`General Info <faq_general_info>` | :doc:`Loading Clips <faq_loading_clips>` | :doc:`Loading Scripts <faq_frameserving>` | :doc:`Common Error Messages <faq_common_errors>` | :doc:`Processing Different Content <faq_different_types_content>` | :doc:`Dealing with YV12 <faq_yv12>` | **Processing with Virtualdub Plugins** |\n\n$Date: 2025-02-25 14:12:56-05:00 $\n\n.. _Shared_functions: http://avisynth.nl/index.php/Shared_functions\n.. _[1]: http://neuron2.net/hosted.html (http://neuron2.net/hosted.html)\n.. _Donald's homepage: http://neuron2.net/bob.html\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/faq/faq_yv12.rst",
    "content": "\nAviSynth FAQ - The color format YV12 and related processing and encoding issues\n===============================================================================\n\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\n\nWhat is YV12?\n-------------\n\nThese are several different ways to represent colors. For example: YUV and\nRGB colorspace. In YUV colorspace there is one component that represent\nlightness (luma) and two other components that represent color (chroma). As\nlong as the luma is conveyed with full detail, detail in the chroma\ncomponents can be reduced by subsampling (filtering, or averaging) which can\nbe done in several ways (thus there are multiple formats for storing a\npicture in YUV colorspace). YV12 is such a format (where chroma is shared in\nevery 2x2 pixel block) that is supported by AviSynth. Many important codecs\nstored the video in YV12: MPEG-4 (x264, XviD, DivX and many others), MPEG-2\non DVDs, MPEG-1 and MJPEG.\n\nWhere can I download the latest stable AviSynth version which supports YV12?\n----------------------------------------------------------------------------\n\n\"AviSynth v2.57\" (and more recent versions) can be downloaded `on Sourceforge`_.\n\nWhere can I download the DGIndex/DGDecode plugin, which supports YV12, to import MPEG-1/MPEG-2/TS/PVA in AviSynth?\n------------------------------------------------------------------------------------------------------------------\n\nThe latest DGIndex/DGDecode combo can be downloaded `from its website`_.\n\nWhich encoding programs support YV12?\n-------------------------------------\n\nThe regular builds of Virtualdub (by Avery Lee) have YV12 support in fast\nrecompress mode since v1.5.6. There are also two another options for encoding\nto DivX/XviD:\n\n- There is a modified version (called VirtualdubMod) which has YV12 support:\n  This modification (by pulco-citron, Suiryc and Belgabor) has OGM and AVS-\n  preview support. It can be downloaded from `its Sourceforge page`_. In order to use the YV12\n  support (without doing any color conversions) you have to load your AVI in\n  VirtualdubMod and select \"fast recompress\".\n\n- For easy (and fast) YV12 support, you can also try out the command line\n  utility `AVS2AVI`_ - compresses video from an AviSynth script using any VFW\n  codec, see also `here`_.\n\n- The MPEG-1/MPEG-2 encoders `HC`_ and `QuEnc`_ also support (and even\n  require) YV12.\n\nHow do I use v2.5x if the encoding programs can't handle YV12 (like TMPGEnc or CCE SP)?\n---------------------------------------------------------------------------------------\n\nUsing TMPGEnc you have to add the line \":doc:`ConvertToRGB24 <../corefilters/convert>`\" (with proper\n\"interlaced\" option) to your script, and for CCE SP you need to add the line\n\":doc:`ConvertToYUY2 <../corefilters/convert>`\" to your script, since Windows has no internal YV12\ndecompressor.\n\nYou can also install some :ref:`YV12 decompressor (codec) <Couldn't locate decompressor>` which will decompress\nthe YV12-AVI for you when loading the avi in TMPGEnc or CCE SP.\n\nWhat will be the main advantages of processing in YV12?\n-------------------------------------------------------\n\n-   speed increase:\n\n    That depends entirely on the external plugins whether they will have YV12\n    support or not. Speed increases like 25-35 percent are expected. Of course\n    there will only be a large speed increase if both your source and target are\n    in YV12, for example in DVD to DivX/Xvid conversions.\n\n-   no color conversions:\n\n    The colour information doesn't get interpolated (so often) and thus stays\n    more realistic.\n\nMPEG-2 encoders such as CCE, Procoder and TMPGEnc can't handle YV12 input\ndirectly. CCE and Procoder needs YUY2, and TMPGEnc RGB24. This only means\nthat the last line of AviSynth must be a :doc:`ConvertToYUY2 <../corefilters/convert>` (for CCE/Procoder,\nor :doc:`ConvertToRGB24 <../corefilters/convert>` for TMPGEnc) call, and that you will not be able to\ntake full advantage of YV12 colorspace. Still there are two advantages:\n\n1.  All internal filtering in AviSynth will be faster though (less data\n    to filter, better structure to filter, and a very fast conversion from\n    YV12 to YUY2), and you will definitely be able to tell the difference\n    between v2.06 and v2.5.\n2.  If you are making a progressive clip there is another advantage.\n    Putting off the YV12->YUY2 conversion until the end of the script allows\n    you to first IVTC or Deinterlace to create progressive frames. But the\n    YV12 to YUY2 conversion for progressive frames maintains more chroma\n    detail than it does for interlaced or field-based frames.\n\nThe color conversions:\nCCE: YV12 -> YUY2 -> YV12\nTMPGEnc: YV12 -> RGB24 -> YV12\n\n\nHow do I use VirtualDub/VirtualDubMod such that there are no unnecessary color conversions?\n-------------------------------------------------------------------------------------------\n\nJust load your avs file in VirtualDub/VirtualdubMod and set the video on\n\"Fast recompress\". In this mode the process will stay in YV12 (all the\nnecessary filtering has to be done in AviSynth itself). Under compression\nselect a codec which support YV12, like Xvid, DivX5, RealVideo (provided you\ndownload the lastest binaries) or 3ivx D4 (provided you download the lastest\nbinaries). Note that DivX3/4 also supports YV12, except that PIV users could\nexperience crashes when encoding to DivX4 in YV12.\nIf you want to preview the video you also need a :ref:`YV12 decompressor. <Couldn't locate decompressor>`\n\nWhich internal filters support YV12?\n------------------------------------\n\nIn principal all internal filters support YV12 natively. Which color formats\nthe filters support is specified in the documentation.\n\nWhich external plugins support YV12?\n------------------------------------\n\nThe plugins which are compiled for AviSynth v2.5 are given in\n:doc:`External plugins <../externalplugins>`. New plugins are listed in\nthis `sticky`_. Most of them support YV12 (see documentation).\n\nAre there any disadvantages of processing in YV12?\n--------------------------------------------------\n\n-   If source format is not YV12 (analog capture, DV) or final encoding\n    format is not YV12, then color format conversion will results in chroma\n    interpolation with some quality decreasing.\n-   Filtering of subsampled chroma can result in some chroma broadening\n    relatively luminocity pixels, especially for interlaced video.\n-   Because the chroma in interlaced YV12 video occurs on alternating\n    lines, it is necessary to use a different upsampling/downsampling method\n    when converting between YV12 and YUV 4:2:2 or RGB. This can lead to\n    chroma upsampling/downsampling errors if the wrong color space conversion\n    method is used on the video.\n-   If YV12 video is stored in an AVI container, there is no metadata to\n    indicate whether the video is interlaced or progressive. This means that\n    an application or component doing color space conversion has no easy way\n    of choosing the correct conversion method (interlaced or progressive).\n    Most color space converters assume progressive which can lead to chroma\n    upsampling/downsampling errors when interlaced video is processed in such\n    an environment.\n\n\nHow do I know which colorspace I'm using at a given place in my script?\n-----------------------------------------------------------------------\n\nTo see which colorspace you are using at a given place in your script, add:\n::\n\n    Info()\n\n... and AviSynth will give you much information about colorspace amongst\nother things!\n\nThe colors are swapped when I load a DivX file in AviSynth v2.5?\n----------------------------------------------------------------\n\nThis happens due to a bug in old versions of DivX5. Download the latest\nbinaries or use \":doc:`SwapUV() <../corefilters/swap>`\".\n\nI got a green (or colored line) at the left or at the right of the clip, how do I get rid of it?\n------------------------------------------------------------------------------------------------\n\nYour decoder is probably borked, try a ConvertToRGB() at the end of your\nscript just to be sure and check whether the line has disappeared. Some\napplication have trouble displaying YV12 clips where the width or height is\nnot a multiple of 16.\n\nThere are several solutions to this problem:\n\n-   Try having the codec decode to RGB or YUY2 (using pixel_type=\"...\"\n    argument in :doc:`AviSource <../corefilters/avisource>` or :doc:`DirectShowSource <../corefilters/directshowsource>`).\n-   Use a codec that correctly decodes YV12 clips where the width or\n    height is not a multiple of 16.\n\n\n.. _Couldn't locate decompressor:\n\nI installed AviSynth v2.5 and get the following error message: \"Couldn't locate decompressor for format 'YV12' (unknown).\"?\n---------------------------------------------------------------------------------------------------------------------------\n\nInstall a codec which supports YV12. DivX5 or one of the recent `XviD\nbuilds`_ or `Helix YUV codec`_ or some other (ffvfw, ffdshow). If that still\ndoesn't work, modify your registry as explained in the next question.\n\n\nI installed AviSynth v2.5 and DivX5 (or one of the latest Xvid builds of Koepi), all I got is a black screen when opening my avs in VirtualDub/VirtualDubMod/MPEG-2 encoder?\n----------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n\nOk, apparently your video is not decompressed by DivX 5.02 (or Xvid). Try to\nuse `VCSwap utility`_ for hot swapping video codecs.\n\nAdvanced user can also do it by hand. Go to your windows-dir and rename a\nfile called MSYUV.DLL, or add the following to your registry file:\n\n::\n\n    REGEDIT4\n\n    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\n    NT\\CurrentVersion\\Drivers32]\n    \"VIDC.YV12\"=\"divx.dll\"\n\nReplace \"divx.dll\" by \"xvid.dll\" for xvid v0.9 or \"xvidvfw.dll\" for xvid\nv1.0.\n\nAre there any lossless YV12 codecs, which I can use for capturing for example?\n------------------------------------------------------------------------------\n\nCapturing in YV12 is not recommended due to issues of interlacing and chroma;\nYUY2 will generally pose fewer problems. A lossless YV12 codec is more useful\nfor saving intermediate files before a multi-pass encode, to avoid having to\nrun a CPU-intensive script several times. There are several lossless YV12\ncodecs:\n\n-   `VBLE Codec (by MarcFD)`_: A huffyuv based encoder [`discussion`_].\n-   `LocoCodec (by TheRealMoh)`_: see also `here`_.\n-   `ffvfw codec`_ - has various modes, in particular HuffYUV yv12.\n-   `Lagarith codec (by Ben Greenwood)`_ - better compression than\n    Huffyuv but slower.\n\n\nSome important links\n--------------------\n\n-   `Technical explanation of YV12 (and similar formats)`_\n-   `Good Microsoft page on YUV`_\n-   `4:2:0 Video Pixel Formats`_\n\n| :doc:`Main Page <faq_sections>` | :doc:`General Info <faq_general_info>` | :doc:`Loading Clips <faq_loading_clips>` | :doc:`Loading Scripts <faq_frameserving>` | :doc:`Common Error Messages <faq_common_errors>` | :doc:`Processing Different Content <faq_different_types_content>` | **Dealing with YV12** | :doc:`Processing with Virtualdub Plugins <faq_using_virtualdub_plugins>` |\n\n$Date: 2013/03/19 18:10:26 $\n\n.. _on Sourceforge: http://sourceforge.net/project/showfiles.php?group_id=57023\n.. _from its website: http://neuron2.net/dgmpgdec/dgmpgdec.html\n.. _its Sourceforge page: http://sourceforge.net/projects/virtualdubmod/virtualdubmod.html\n.. _AVS2AVI: http://www.avs2avi.org\n.. _here: http://forum.doom9.org/showthread.php?t=71493\n.. _HC: http://www.bitburners.com/HC_Encoder/\n.. _QuEnc: http://www.bitburners.com/QuEnc/\n.. _sticky: http://forum.doom9.org/showthread.php?s=&threadid=84481\n.. _XviD builds: http://www.xvid.org/\n.. _Helix YUV codec:\n    http://forum.doom9.org/showthread.php?s=&threadid=56972\n.. _VCSwap utility: http://members.chello.nl/~p.bekke/\n.. _VBLE Codec (by MarcFD):\n    http://forum.doom9.org/showthread.php?s=&threadid=53305\n.. _discussion:\n    http://forum.doom9.org/showthread.php?s=&threadid=38389&pagenumber=5\n.. _LocoCodec (by TheRealMoh):\n    http://forum.doom9.org/showthread.php?s=&threadid=50363\n.. _ffvfw codec: http://www.free-codecs.com/ffvfw_download.htm\n.. _Lagarith codec (by Ben Greenwood):\n    http://lags.leetcode.net/codec.html\n.. _Technical explanation of YV12 (and similar formats):\n    http://www.fourcc.org/fccyuv.htm#YV12\n.. _Good Microsoft page on YUV:\n    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/yuvformats.asp\n.. _4:2:0 Video Pixel Formats:\n    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/Display_d/hh/Display_d/dxvaguide_00174d47-49a2-4c28-b67e-ce5a0a58e8ae.xml.asp\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/faq/troubleshooting.rst",
    "content": "\nTroubleshooting\n===============\n\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\n\nInstallation problems\n---------------------\n\nIf you got problems getting AviSynth to work at all, try the following\nscript:\n::\n\n    Version()\n\nand open it in Windows Media Player 6.4 (it is a file ``mplayer2.exe`` located\nin ``C:\\Program Files\\Windows Media Player``, other versions of WMP will not\nwork). If you see a video with a message with Avisynth version and Copyright,\nthen it is installed properly.\n\nIf that doesn't work, you can try the following:\n\n-   Empty the plugin folder of AviSynth: autoloaded scripts (``*.avsi``) or\n    some filters can cause this (:ref:`see here <Check your autoloading plugin directory>`).\n-   Install codecs, in particular `Huffyuv`_: it can be that there is no\n    decoder present which can decode your video.\n-   If you use an encoding package (like DVD2SVCD, GKnot, DVX, ...) make\n    sure that you use the version of AviSynth that came with that package: it\n    might be that new versions of AviSynth are not compatible with the\n    package. Try to get support from the package developers.\n-   Reinstall AviSynth: it might be that something went wrong with the\n    installation. If you tried playing with new beta version, reinstall a\n    stable release.\n-   If all of the above doesn't help drop a post in the `Doom9 Forums`_.\n\n\nOther problems\n--------------\n\nCreating scripts with AviSynth is not always easy, and sometimes AviSynth\nproduces very strange results. This is a little guide to help you figure out\nthe most common errors.\n\n\nWrite Simple\n------------\n\nIf AviSynth produces strange results, try simplifying your script. Try\nsplitting up your script into as many lines as possible. This will help you\nidentify your problem. For example:\n::\n\n    video =\n    AviSource(\"file23.avi\").ConvertToYUY2().Trim(539,8534)\n    return AudioDub(Blur(video,1.5).Reduceby2().Bilinearrresize(512,384),\n    Wavsource(\"file23.wav\").AmplifyDB(4.5)\n\nis not as readable as\n::\n\n    AviSource(\"file23.avi\")\n    ConvertToYUY2()\n    Trim(539, 8534)\n    Blur(1.5)\n    Reduceby2()\n    Bilinearrresize(512, 384)\n    AudioDub(Wavsource(\"file23.wav\"))\n    AmplifyDB(4.5)\n\nFurthermore it has the advantage, that you more easily:\n\n-   Comment out a single command (line). This is good for testing the\n    effect of a filter.\n-   Get the proper position (line) of problem command, if there is a\n    syntax error.\n-   Put in a \"return last\" at some position in the script. This will\n    output the video at that place in the filterchain. So by varying the\n    place of the \"return last\" you can check up to which line the video is\n    correct.\n-   Get an overview of the \"flow\" of the script. (Is it a good thing that\n    the :doc:`Trim <../corefilters/trim>` command only affects the video in the clip above?)\n\n\nAlways check parameters\n-----------------------\n\nIf you have a filter that gives you unexpected results, try using it with the\nsimplest parameters. Always check the internal filters either on AviSynth\nhomepage or in the documentation that came along with your AviSynth.\n\nBe sure you use the same type of parameters as the ones described in the\ndocumentation. The most common error in this case is related to the first\nparameter in all filters, \"clip\". Be sure you understand how \"implicit last\"\nworks. If you do not have a \"last clip\", most filters will fail with an\n\"Invalid parameter\" error.\n\n\"Filter does not return a clip\" is reported if the output of your last filter\nis put into a variable, and there isn't any \"last clip\". For instance:\n::\n\n    video = AviSource(\"file.avi\")\n    audio = WavSource(\"file.wav\")\n    combined = AudioDub(video, audio)\n\nwill fail. This can be solved by:\n::\n\n    video = AviSource(\"file.avi\")\n    audio = WavSource(\"file.wav\")\n    AudioDub(video, audio)\n\nwhere 'last' now contains a clip, or:\n::\n\n    video = AviSource(\"file.avi\")\n    audio = WavSource(\"file.wav\")\n    combined = AudioDub(video, audio)\n    return combined\n\nwhere the variable is returned, or even:\n::\n\n    video = AviSource(\"file.avi\")\n    audio = WavSource(\"file.wav\")\n    return AudioDub(video, audio)\n\n\nTest scripts using Virtualdub\n-----------------------------\n\nAlways use `Virtualdub`_ or even better `VirtualDubMod`_ to test your\nscripts. This is what all AviSynth functionality is tested against (by its\ndevelopers). AviSynth does of course work with other programs, but if you get\nerrors in other applications it's most likely not an AviSynth problem, but a\nlimitation within the software you are using.\n\nThese limitations are mostly linked to:\n\n-   Color format problems. The application you are using does not support\n    the color format you are using as script output.\n-   Size problems. Some programs does not accept all sizes of images.\n\n\nGo through the script step by step\n----------------------------------\n\nAs mentioned in \"Write Simple\" it is always a good thing to test every step\nof your script, if there are problems.\n\nYou can comment out a filter (filters) by placing a '#' in front of the line\n(or before filter). That way it (and all rest of the line) will be ignored by\nAviSynth.\n\nYou can put in a \"return last\" or \"return myvariable\" any place in the\nscript.\n\nAt any place in the script you can add the :doc:`Info() <../corefilters/info>` filter to get\ninformation about the image and sound at the current stage of the filtering.\n\n\n.. _Check your autoloading plugin directory:\n\nCheck your autoloading plugin directory\n---------------------------------------\n\nPlugins autoloading usually works fine, but you must NOT put here:\n\n-   any plugins for incompatible AviSynth versions (e.g. old 2.0.x).\n-   special LoadPluginEx.DLL plugin (from WarpSharp package) used for\n    loading of old 2.0 plugins.\n-   AviSynth C-plugins which use AviSynth C API instead of regular\n    interface.\n-   too many AviSynth plugins (this 50 plugins auto prescan load limit is\n    removed in v2.57 though).\n-   any other DLL files (usually it is safe, but is not recommended).\n\nYou must also remember, that all AVSI files in your plugin-directory are\nautomatically included in your script. This is a feature, to allow you to\ninclude your own (or borrowed) functions, without have to copy/paste them\ninto every script.\n\n*Notes. In old AviSynth versions (up to 2.0.7) all AVS files in your plugin-\ndirectory were automatically included in your script. This also means that if\nyou copy any sample scripts into your plugin directory they will always be\nincluded, and may generate errors (in old versions!).*\n\nIn general, any AVSI (early AVS) file whose commands are not wrapped into\nfunctions will be problematic.\n\nAll other file formats besides AVSI and DLL files are ignored, so you can\nsafely leave your documentation there.\n\nHow to empty plugin dir? Simply create some subfolder (e.g. \"hide\") and move\nall (or some) files there.\n\nRemember some files (DirectShowSource.dll, TCPDeliver.dll plugins,\nColorRGB.avsi) are part of AviSynth (since v2.56).\n\n\nUse conservative image sizes\n----------------------------\n\nIf you have problems with distorted images, try using conservative frame\nsizes. That means, use sizes, where height and width are always divisible by\n16. Using image sizes that are not divisible by 2 is in many cases\nproblematic, and should always be avoided.\n\nIf you do however find that there is a problem with certain sizes of images,\nplease submit a bug-report. See below how to do that.\n\n\nFinally check the AviSynth Q&A\n------------------------------\n\nIf you still got problems (loading scripts in certain encoders, or colorspace\nerrors) have a look at the AviSynth Q&A, especially :ref:`Problems when\nEncoder X reads AVS-files`. Be also sure to check What are the main\nbugs in these versions in the FAQ.\n\n\nReporting bugs / Asking for help\n--------------------------------\n\nWe will need many informations to be able to help you. If you don't supply us\nwith that, there is a good chance that we won't be able to help you or locate\nthe error.\n\nBe sure to ** always** include:\n\n-   AviSynth version. (and date of beta, if not a SourceForge final\n    release)\n-   The simplest possible script for recreating the error.\n-   The EXACT error message you get.\n-   VirtualDub (Mod) version.\n-   All file information from VirtualDub / File / File Information.\n-   Used plugin versions.\n-   Codecs and image sizes of input material.\n\nBug reports should be submitted at the `SourceForge Project page`_. Be sure\nto check if there is already a bug summitted similar to yours - there might\njust be. Errors in external plugins shouldn't be reported here, but to the\nauthor of the filter.\n\nA very good place to get help is the `Doom9 Forums`_. Be sure to search the\nforum before asking questions. Many topics have been covered there! - Then\nenter into the discussion.\n\n$Date: 2025-02-25 14:12:56-05:00 $\n\n.. _Huffyuv: http://avisynth.nl/index.php/Huffyuv\n.. _Doom9 Forums: http://forum.doom9.org/forumdisplay.php?s=&forumid=33\n.. _Virtualdub: http://avisynth.nl/index.php/VirtualDub\n.. _VirtualDubMod: http://avisynth.nl/index.php/VirtualDubMod\n.. _SourceForge Project page: http://sourceforge.net/projects/avisynth2\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/filters_mult_input_clips.rst",
    "content": "\nFilters with multiple input clips\n=================================\n\nThere are some functions which combine two or more clips in different ways.\nHow the video content is calculated is described for each function, but here\nis a summary which properties the result clip will have.\n\nThe input clips must always have the same color format and - with the\nexception of :doc:`Layer <corefilters/layer>` and :doc:`Overlay <corefilters/overlay>` - the same dimensions.\n\n+------------------------------------------------------------+----------------------+----------------------+------------------------+---------------------+\n| filter                                                     | framerate            | framecount           | audio content          | audio sampling rate |\n+============================================================+======================+======================+========================+=====================+\n| :doc:`AlignedSplice, UnalignedSplice <corefilters/splice>` | first clip           | sum of all clips     | see filter description | first clip          |\n+------------------------------------------------------------+                      +----------------------+                        |                     |\n| :doc:`Dissolve <corefilters/dissolve>`                     |                      | sum of all clips     |                        |                     |\n|                                                            |                      | minus the overlap    |                        |                     |\n+------------------------------------------------------------+                      +----------------------+------------------------+                     |\n| :doc:`Merge, MergeLuma, MergeChroma <corefilters/merge>`,  |                      | first clip `1`:sup:  | first clip             |                     |\n| :doc:`Merge(A)RGB <corefilters/mergergb>`                  |                      |                      |                        |                     |\n+------------------------------------------------------------+                      |                      |                        |                     |\n| :doc:`Layer <corefilters/layer>`                           |                      |                      |                        |                     |\n+------------------------------------------------------------+                      +----------------------+                        |                     |\n| :doc:`Subtract <corefilters/subtract>`                     |                      | longer clip `2`:sup: |                        |                     |\n+------------------------------------------------------------+                      |                      |                        |                     |\n| :doc:`StackHorizontal, StackVertical <corefilters/stack>`  |                      |                      |                        |                     |\n+------------------------------------------------------------+----------------------+----------------------+                        |                     |\n| :doc:`Interleave <corefilters/interleave>`                 || (fps of first clip) || N x frame-count     |                        |                     |\n|                                                            || x                   || of longer clip      |                        |                     |\n|                                                            || (number of clips)   || `2`:sup:            |                        |                     |\n+------------------------------------------------------------+----------------------+----------------------+------------------------+---------------------+\n\n| `1`:sup: (the last frame of the shorter clip is repeated until the end of the clip)\n| `2`:sup: (the last frame of the shorter clip is repeated until the end of the clip)\n\nAs you can see the functions are not completely symmetric but take some attributes from the FIRST clip.\n\n$Date: 2008/07/19 15:17:14 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/getting_started.rst",
    "content": "\nGetting started\n===============\n\nBasically, AviSynth works like this: First, you create a simple text document\nwith special commands, called a script. These commands make references to one\nor more videos and the filters you wish to run on them. Then, you run a video\napplication, such as VirtualDub, and open the script file. This is when\nAviSynth takes action. It opens the videos you referenced in the script, runs\nthe specified filters, and feeds the output to video application. The\napplication, however, is not aware that AviSynth is working in the\nbackground. Instead, the application thinks that it is directly opening a\nfiltered AVI file that resides on your hard drive.\n\nLinear Editing\n--------------\n\nThe simplest thing you can do with AviSynth is the sort of editing you can do\nin VirtualDub. The scripts for this are easy to write because you don't have\nto worry about variables and complicated expressions if you don't want.\n\nFor testing create a file called test.avs and put the following single line\nof text in it:\n::\n\n    Version\n\nNow open this file with e.g. Windows Media Player and you should see a ten-\nsecond video clip showing AviSynth's version number and a copyright notice.\n\n``Version`` is what's called a \"source filter\", meaning that it generates a\nclip instead of modifying one. The first command in an AviSynth script will\nalways be a source filter.\n\nNow add a second line to the script file, so that it reads like this:\n::\n\n    Version\n    ReduceBy2\n\nReopen the file in Media Player. You should see the copyright notice again,\nbut now half as large as before.\n:doc:`ReduceBy2 <corefilters/reduceby2>` is a \"transformation filter,\" meaning that it takes the\nprevious clip and modifies it in some way. You can chain together lots of\ntransformation filters, just as in VirtualDub.\nLet's add another one to make the video fade to black at the end. Add another\nline to the script file so that it reads:\n::\n\n    Version\n    ReduceBy2\n    FadeOut(10)\n\nNow reopen the file. The clip should be the same for the first 9 seconds, and\nthen in the last second it should fade smoothly to black.\nThe :doc:`FadeOut <corefilters/fade>` filter takes a numerical argument, which indicates the number\nof frames to fade.\n\nIt takes a long time before the fade starts, so let's trim the beginning of\nthe clip to reduce the wait, and fade out after that.\nLet's discard the first 120 of them, and keep the frames 120-150:\n::\n\n    Version\n    ReduceBy2\n    # Chop off the first 119 frames, and keep the frames 120-150\n    # (AviSynth starts numbering frames from 0)\n    Trim(120,150)\n    FadeOut(10)\n\nIn this example we used a comment for the first time.\nComments start with the # character and continue to the end of the line, and\nare ignored completely by AviSynth.\nThe :doc:`Trim <corefilters/trim>` filter takes two arguments, separated by a comma: the first and\nthe last frame to keep from the clip. If you put 0 for the last frame, it's\nthe same as \"end of clip,\" so if you only want to remove the first 119 frames\nyou should use Trim(120,0).\n\nKeeping track of frame numbers this way is a chore. It's much easier to open\na partially-completed script in an application like VirtualDub which will\ndisplay the frame numbers for you. You can also use the :doc:`ShowFrameNumber <corefilters/showframes>`\nfilter, which prints each frame's number onto the frame itself.\n\nIn practice a much more useful source filter than :doc:`Version <corefilters/version>` is :doc:`AVISource <corefilters/avisource>`,\nwhich reads in an AVI file (or one of several other types of files) from\ndisk. If you have an AVI file handy, you can try applying these same filters\nto your file:\n::\n\n    AVISource(\"d:\\capture.avi\")  # or whatever the actual pathname is\n    ReduceBy2\n    FadeOut(15)\n    Trim(120,0)\n\nEven a single-line script containing only the AVISource command can be useful\nfor adding support for >2GB AVI files to applications which only support <2GB\nones.\n\n\n--------\n\n\nNon-Linear Editing\n------------------\n\nNow we're getting to the fun part. Make an AVS file with the following script\nin it:\n::\n\n    StackVertical(Version, Version)\n\nNow open it. Result: An output video with two identical lines of version\ninformation, one on top of the other.\nInstead of taking numbers or strings as arguments, :doc:`StackVertical <corefilters/stack>` takes\nvideo clips as arguments. In this script, the Version filter is being called\ntwice. Each time, it returns a copy of the version clip. These two clips are\nthen given to :doc:`StackVertical <corefilters/stack>`, which joins them together (without knowing\nwhere they came from).\n\nOne of the most useful filters of this type is :doc:`UnalignedSplice <corefilters/splice>`, which\njoins video clips end-to-end. Here's a script which loads three AVI files\n(such as might be produced by AVI_IO) and concatenates them together.\n::\n\n    UnalignedSplice(AVISource(\"d:\\capture.00.avi\"), \\\n    AVISource(\"d:\\capture.01.avi\"), \\\n    AVISource(\"d:\\capture.02.avi\"))\n\nBoth :doc:`StackVertical <corefilters/stack>` and :doc:`UnalignedSplice <corefilters/splice>` can take as few as two arguments\nor as many as sixty.\nYou can use the ``+`` operator as a shorthand for :doc:`UnalignedSplice <corefilters/splice>`.\n\nFor example, this script does the same thing as the previous example:\n::\n\n    AVISource(\"d:\\capture.00.avi\") + \\\n    AVISource(\"d:\\capture.01.avi\") + \\\n    AVISource(\"d:\\capture.02.avi\")\n\nNow let's suppose you're capturing with an application that also saves the\nvideo in multiple AVI segments, but puts the audio in a separate WAV file.\nCan we recombine everything? You bet:\n::\n\n    AudioDub(AVISource(\"d:\\capture.00.avi\") + \\\n    AVISource(\"d:\\capture.01.avi\") + \\\n    AVISource(\"d:\\capture.02.avi\"), \\\n    WAVSource(\"d:\\audio.wav\"))\n\n$Date: 2008/07/18 17:38:49 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/index.rst",
    "content": ".. AviSynth+ documentation master file, created by\n   sphinx-quickstart on Sun Mar  8 20:56:40 2015.\n   You can adapt this file completely to your liking, but it should at least\n   contain the root `toctree` directive.\n\nInvisible Tree\n==============\n\n.. toctree::\n   :hidden:\n   :glob:\n\n   *\n   advancedtopics/*\n   script_ref/*\n   syntax/*\n   corefilters/*\n   faq/*\n   FilterSDK/*\n   contributing/*\n\n\nIndices and tables\n==================\n\n* :ref:`genindex`\n* :ref:`modindex`\n* :ref:`search`\n\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/license.rst",
    "content": "\nLicense\n=======\n\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\nAviSynth License\n----------------\n\nAviSynth v2.5 Copyright (C) 2002-2006  Ben Rudiak-Gould et al.\n`<http://avisynth.nl/index.php/Main_Page>`_\n\nThis program is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation; either version 2 of the License, or\n(at your option) any later version.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with this program; if not, write to the Free Software\nFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n`<http://www.gnu.org/copyleft/gpl.html>`_\n\nLinking Avisynth statically or dynamically with other modules is\nmaking a\ncombined work based on Avisynth.  Thus, the terms and conditions of\nthe GNU\nGeneral Public License cover the whole combination.\n\nAs a special exception, the copyright holders of Avisynth give you\npermission to link Avisynth with independent modules that communicate\nwith Avisynth solely through the interfaces defined in avisynth.h,\nregardless of the license terms of these independent modules, and to\ncopy and distribute the resulting combined work under terms of your\nchoice, provided that every copy of the combined work is accompanied\nby\na complete copy of the source code of Avisynth (the version of\nAvisynth\nused to produce the combined work), being distributed under the terms\nof\nthe GNU General Public License plus this exception.  An independent\nmodule is a module which is not derived from or based on Avisynth,\nsuch\nas 3rd-party filters, import and export plugins, or graphical user\ninterfaces.\n\n\nSee `full text of the of GNU General Public license (GPL) version 2 <../../../../License/gpl.txt>`_.\n\nSee copyright notices of Avisynth developers in supplied source codes for\ndetails.\n\nSee AviSynth external Filter SDK license :doc:`text <FilterSDK/SDKLicense>` (link valid if installed).\n\n\nAviSynth documentation license\n------------------------------\n\nAviSynth documentation is Copyright (C) 2002-2007 AviSynth developers and\ncontributors.\n\nStarting from 5 August 2007 the following documentation is released under the\n`CreativeCommons Attribution-ShareAlike 3.0 License`_ (abbreviated by \"CC BY-\nSA 3.0\", see also `full license terms`_):\n\n-   All content of the AviSynth Wiki at avisynth.nl, except the AviSynth\n    Filter SDK.\n-   The off-line documentation which is distributed with AviSynth itself,\n    except any external plugin documentation which is copyright corresponding\n    authors (see description of these plugins for their license terms).\n\nWhen editing this Wiki or using material from this Wiki or off-line\ndocumentation you are bound by the terms of this license, and these terms are\nbriefly as follows:\n\nYou are allowed to copy, modify or improve the content of the AviSynth Wiki\nand the off-line documentation provided that:\n\n-   Share Alike (SA): The resulting changes are licensed under the same\n    or a compatible license as the AviSynth Wiki and the off-line\n    documentation (which is \"CC BY-SA 3.0\").\n-   Attribution (BY): Permit users to copy, distribute, display and\n    perform the work and make derivative works based upon it only if they\n    give the author or licensor the credits in the manner specified by these.\n    This implies that if you distribute parts of the documentation (such as\n    articles or scripts) your should refer to \"AviSynth documentation Wiki\"\n    (or \"AviSynth documentation\") with link to these pages or to the main\n    site: avisynth.nl. You must also keep attributions for the parts\n    attributed to other resources or authors.\n\nBesides above two requirements, you also agree that:\n\n-   attribution of your contributions will (or may) be given to AviSynth\n    project in a form \"AviSynth documentation\" or \"AviSynth documentation\n    Wiki\" (avisynth.nl).\n-   your contribution (and main Wiki content) may be relicensed by the\n    AviSynth developers team under a compatible license.\n-   you are also promising us that you wrote the contributions yourself,\n    or copied it from public domain, or from work with a compatible license.\n    DO NOT SUBMIT COPYRIGHTED WORK WITHOUT PERMISSION!\n\nNote that this license has a fair-use clause (article 2):\n\n*\"2. Fair Dealing Rights. Nothing in this License is intended to reduce,\nlimit, or restrict any uses free from copyright or rights arising from\nlimitations or exceptions that are provided for in connection with the\ncopyright protection under copyright law or other applicable laws.\"*\n\nwhich, in our opinion, explicitly permits you to post and discuss scripts\n(from the documentation) where ever you want without the need to mention its\nlicense or its authors, but it is civil to credit the developers and script\nauthors. Of course, you may not declare yourself as its author or distribute\nthe documentation under an uncompatible license.\n\nAviSynth documentation translations to other languages (both at the wiki and\noff-line) should be under same or compatible license terms.\n\n\nAviSynth logo\n-------------\n\n'Film and Gears' logo was contributed to AviSynth project by doom9 forum\nmember 'Shayne'.\n\n'Tray and AviSynth' logo (now at old wiki pages) was contributed to AviSynth\nproject by anonymous sh0dan's friend.\n\nPermission to use and/or modify these logos is granted provided that your\nmaterials are related to AviSynth and you give an attribution to\navisynth.nl.\n\n\nAvisynth uses codes from following projects:\n--------------------------------------------\n\nAvisynth's frameclient and OpenDML code, part of the subtitling code,\nCPUExtensions code, VirtualDub plugins interface were taken from:\n::\n\n    VirtualDub - Video processing and capture application\n    Copyright (C) 1999-2001 Avery Lee\n    http://www.virtualdub.org\n\n    VirtualDub is distributed under terms of GNU GPL.\n    Special permission by Avery Lee to distribute existing (at November 2006)\n    VirtualDub-derived elements in Avisynth under the current Avisynth license,\n    which is GPL plus a special exemption.\n\nThe DirectShowSource filter was adapted from parts of\n::\n\n    bbMPEG by Brent Beyeler, 1999-2000\n    http://members.home.net/beyeler/bbmpeg.html (old link)\n    http://members.cox.net/beyeler/bbmpeg.html (new link)\n\n    bbMPEG is released as freeware. Freely distributable.\n\nAvisynth C interface\n::\n\n    Copyright (C) 2003-2004 Kevin Atkinson\n    http://kevin.atkinson.dhs.org/avisynth_c/\n\n    Distributed under terms of GNU GPL with a special exception:\n    As a special exception, I give you permission to link to the\n    Avisynth C interface with independent modules that communicate with\n    the Avisynth C interface solely through the interfaces defined in\n    avisynth_c.h, regardless of the license terms of these independent\n    modules, and to copy and distribute the resulting combined work\n    under terms of your choice, provided that every copy of the\n    combined work is accompanied by a complete copy of the source code\n    of the Avisynth C interface and Avisynth itself (with the version\n    used to produce the combined work), being distributed under the\n    terms of the GNU General Public License plus this exception.  An\n    independent module is a module which is not derived from or based\n    on Avisynth C Interface, such as 3rd-party filters, import and\n    export plugins, or graphical user interfaces.\n\nImageLib (DevIL) image processing library (v1.6.6; used in ImageRead,ImageWrite)\n::\n\n    Copyright (C) 2000-2002 by Denton Woods\n    http://openil.sourceforge.net/\n    Distributed under terms of the GNU Lesser Public License (LGPL).\n\n\nSee `full text <../../../../License/lgpl_for_used_libs.txt>`_ of GNU LGPL for license terms of such libraries.\nYou should have received a copy of the GNU Lesser General Public License\nalong with this program; if not, write to the Free Software\nFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n`<http://www.gnu.org/copyleft/lgpl.html>`_\n\nCorresponding source codes are supplied.\n\nSoftWire class library  (v4.4.1; used in Limiter and image resiser)\n::\n\n    Copyright (C) 2002-2003 Nicolas Capens\n    http://softwire.sourceforge.net/ (closed in October 2005)\n    It was distributed under terms of the GNU LGPL with following notice:\n      If you only derive from a class to write your own specific\n      implementation,  you don't have to release the source code\n      of your whole project, just give credit where due.\n\nSoundTouch audio processing library (v1.3.1 or other; used in TimeStretch)\n::\n\n    Copyright (C) 2002-2006 Olli Parviainen\n    http://www.surina.net/soundtouch\n    Distributed under terms of the GNU LGPL.\n\nAudio super equalizer and sampling rate converter are based on:\n::\n\n    Shibatch Super Equalizer (SuperEQ) and Sampling Rate Converter (SSRC)\n    Copyright (C) 2001-2003 Naoki Shibata\n    http://shibatch.sourceforge.net/\n    Both are distributed under terms of GNU LGPL (except FFT part).\n\n    Some changes are:\n    Copyright (C) 2001-2003, Peter Pawlowski\n    http://www.foobar2000.org\n    (with addition of PFC library)\n\n    Other changes are:\n    Copyright (C) 2003, Klaus Post\n\nPFC class library (portion of Foobar2000 0.7 SDK)\n::\n\n    Copyright (C) 2001-2003, Peter Pawlowski\n    All rights reserved.\n\n    Used Foobar2000 SDK was distributed under following conditions:\n\n    Redistribution and use in source and binary forms, with or without\n    modification, are permitted provided that the following conditions\n    are met: Redistributions of source code must retain the above copyright\n    notice, this list of conditions and the following disclaimer.\n    Redistributions in binary form must reproduce the above copyright\n    notice, this list of conditions and the following disclaimer in the\n    documentation and/or other materials provided with the distribution.\n    Neither the name of the author nor the names of its contributors may\n    be used to endorse or promote products derived from this software\n    without specific prior written permission.\n    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n    \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\n    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\n    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR\n    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n    OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nFFT part of SuperRQ and SSRC is based on General Purpose FFT package\n::\n\n    http://momonga.t.u-tokyo.ac.jp/~ooura/fft.html\n      It is originally distributed under following license terms:\n\n    Copyright (C) 1996-2001 Takuya OOURA\n    (Email: ooura@kurims.kyoto-u.ac.jp or ooura@mmm.t.u-tokyo.ac.jp)\n\n    You may use, copy, modify and distribute this code for any purpose\n    (include commercial use) and without fee.\n    Please refer to this package when you modify this code.\n\n:doc:`Thanks also to everyone else contributing to the AviSynth project! <changelist>`\n\n$Date: 2025-02-21 18:17:53-05:00 $\n\n.. _CreativeCommons Attribution-ShareAlike 3.0 License:\n    http://creativecommons.org/licenses/by-sa/3.0/\n.. _full license terms:\n    http://creativecommons.org/licenses/by-sa/3.0/legalcode\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/links.rst",
    "content": "\nAviSynth Internet Links\n=======================\n\n`Official AviSynth site avisynth.nl/index.php/Main_Page`_\n\n`Official AviSynth project at sourceforge (source codes and binaries\ndownload)`_\n\n`AviSynth Usage forum at doom9 site`_\n\n`AviSynth Development forum at doom9 site`_\n\n`VirtualDub video editor (by Avery Lee)`_\n\n`VirtualDubMod video editor with AviSynth script editor`_\n\n`AVSEdit Editor description`_\n\n`AvsP Editor homepage (by qwerpoi)`_\n\n`AviSynth filter collection, some utilities too (maintained by\nWarpEnterprises)`_\n\n`Command-line and batch utilities for AviSynth`_\n\n`New plugins and utilities for AviSynth`_\n\n`Postprocessing video using AviSynth`_ (the section from Analog TV capture\nguide)\n\n$Date: 2006/12/17 10:28:23 $\n\n.. _Official AviSynth site avisynth.nl/index.php/Main_Page:\n    http://avisynth.nl/index.php/Main_Page\n.. _Official AviSynth project at sourceforge (source codes and binaries\n    download): http://sourceforge.net/projects/avisynth2/\n.. _AviSynth Usage forum at doom9 site:\n    http://forum.doom9.org/forumdisplay.php?f=33\n.. _AviSynth Development forum at doom9 site:\n    http://forum.doom9.org/forumdisplay.php?f=69\n.. _VirtualDub video editor (by Avery Lee): http://www.virtualdub.org/\n.. _VirtualDubMod video editor with AviSynth script editor:\n    http://sourceforge.net/projects/virtualdubmod/\n.. _AVSEdit Editor description:\n    http://www.geocities.com/wilbertdijkhof/guides/avsedit/AVSEdit.htm\n.. _AvsP Editor homepage (by qwerpoi): http://avisynth.nl/users/qwerpoi/\n.. _AviSynth filter collection, some utilities too (maintained by\n    WarpEnterprises): http://avisynth.nl/users/warpenterprises\n.. _Command-line and batch utilities for AviSynth:\n    http://forum.doom9.org/showthread.php?t=96451\n.. _New plugins and utilities for AviSynth:\n    http://forum.doom9.org/showthread.php?t=84481\n.. _Postprocessing video using AviSynth:\n    http://www.doom9.org/capture/postprocessing_avisynth.html\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/overview.rst",
    "content": "\nOverview\n========\n\n\nQuick Reference\n---------------\n\n:doc:`Quick Reference <quick_ref>`\n\n[ :ref:`A` :ref:`B` :ref:`C` :ref:`D` :ref:`E` :ref:`F` :ref:`G` :ref:`H` :ref:`I`\n  [J] :ref:`K` :ref:`L` :ref:`M` :ref:`N` :ref:`O` :ref:`P` [Q] :ref:`R`\n  :ref:`S` :ref:`T` [U] :ref:`V` :ref:`W` [X] [Y] [Z] ]\n\n\nGetting started\n----------------------------------------\n\n:doc:`Getting started <getting_started>`\n\n\nAviSynth Syntax\n---------------\n\n:doc:`AviSynth Syntax <syntax/syntax_sections>`\n\n-   :doc:`The full Avisynth Syntax <syntax/syntax_the_full_grammar>`\n-   :doc:`Statements <syntax/syntax_ref>`\n-   :doc:`Script variables <syntax/syntax_script_variables>`\n-   :doc:`Colors <syntax/syntax_colors>`\n-   :doc:`Operators <syntax/syntax_operators>`\n-   :doc:`Control structures <syntax/syntax_control_structures>`\n-   :doc:`Internal functions <syntax/syntax_internal_functions>`\n\n    -   :doc:`Boolean functions <syntax/syntax_internal_functions_boolean>`\n    -   :doc:`Control functions <syntax/syntax_internal_functions_control>`\n    -   :doc:`Type conversion functions <syntax/syntax_internal_functions_conversion>`\n    -   :doc:`Casting to function object <syntax/syntax_internal_functions_function_object>`\n    -   :doc:`Multithreading functions <syntax/syntax_internal_functions_multithreading_new>`\n    -   :doc:`Global options and resource control (memory, CPU, cache) <syntax/syntax_internal_functions_global_options>`\n    -   :doc:`Numeric functions <syntax/syntax_internal_functions_numeric>`\n    -   :doc:`Trigonometry functions <syntax/syntax_internal_functions_trig>`\n    -   :doc:`Bit functions <syntax/syntax_internal_functions_bit>`\n    -   :doc:`Runtime functions <syntax/syntax_internal_functions_runtime>`\n    -   :doc:`Script functions <syntax/syntax_internal_functions_script>`\n    -   :doc:`String functions <syntax/syntax_internal_functions_string>`\n    -   :doc:`Version functions <syntax/syntax_internal_functions_version>`\n    -   :doc:`Frame property functions <syntax/syntax_internal_functions_frame_properties>`\n    -   :doc:`Debugging helper function <syntax/syntax_internal_functions_debug>`\n    -   :doc:`History: Avisynth 2.6 Multithreading functions <syntax/syntax_internal_functions_multithreading>` (v2.6)\n\n-   :doc:`Clip properties <syntax/syntax_clip_properties>`\n-   :doc:`User defined script functions <syntax/syntax_userdefined_scriptfunctions>`\n-   :doc:`Runtime environment <syntax/syntax_runtime_environment>`\n-   :doc:`Plugins <syntax/syntax_plugins>`\n\n\nScripting reference\n-------------------\n\n:doc:`Scripting reference <script_ref/script_ref>`\n\n-   :doc:`The script execution model <script_ref/script_ref_execution_model>`\n\n    -   :doc:`Sequence of events <script_ref/script_ref_execution_model_sequence_events>`\n    -   :doc:`The (implicit) filter graph <script_ref/script_ref_execution_model_filter_graph>`\n    -   :doc:`The fetching of frames (from bottom to top) <script_ref/script_ref_execution_model_fetching_frames>`\n    -   :doc:`Scope and lifetime of variables <script_ref/script_ref_execution_model_lifetime_variables>`\n    -   :doc:`Evaluation of runtime scripts <script_ref/script_ref_execution_model_eval_scripts>`\n    -   :doc:`Performance considerations <script_ref/script_ref_execution_model_perf_cons>`\n\n-   :doc:`User functions <script_ref/script_ref_user_functions>`\n-   :doc:`Block statements <script_ref/script_ref_block_statements>`\n-   :doc:`Arrays <script_ref/script_ref_arrays>`\n-   :doc:`Scripting at runtime <syntax/syntax_runtime_environment>`\n\n\nCore Filters\n------------\n\n:doc:`Core Filters <corefilters>`\n\n-   :ref:`Media file filters`\n-   :ref:`Color conversion and adjustment filters`\n-   :ref:`Overlay and Mask filters`\n-   :ref:`Geometric deformation filters`\n-   :ref:`Pixel restoration filters`\n-   :ref:`Timeline editing filters`\n-   :ref:`Interlace filters`\n-   :ref:`Audio processing filters`\n-   :ref:`Meta filters`\n-   :ref:`Conditional filters`\n-   :ref:`Debug filters`\n\n\nExternal Filters (Plugins)\n---------------------------------------------------\n\n:doc:`External Filters (Plugins) <externalplugins>`\n\n\nHave a Question?\n----------------\n\n-   :doc:`Troubleshooting <faq/troubleshooting>` - read this first when getting problems\n-   :doc:`FAQ <faq/faq_general_info>` - general info about AviSynth\n\n\nAdvanced Topics\n---------------\n\n:doc:`Advanced Topics <advancedtopics>`\n\n-   :ref:`Interlaced and field-based video`\n-   :ref:`Video Sampling`\n-   :ref:`ColorSpace Conversions`\n-   :ref:`Hybrid Video`\n-   :ref:`Importing Media into AviSynth`\n\n\nVersions History\n----------------\n\n-   :doc:`Changelist 3.7.6 <changelist376>`\n-   :doc:`Changelist 3.7.5 <changelist375>`\n-   :doc:`Changelist 3.7.4 <changelist374>`\n-   :doc:`Changelist 3.7.3 <changelist373>`\n-   :doc:`Changelist 3.7.2 <changelist372>`\n-   :doc:`Changelist 3.7.1 <changelist371>`\n-   :doc:`Changelist 3.7 <changelist37>`\n-   :doc:`Changelist 3.6 <changelist36>`\n-   :doc:`Changelist 3.5 <changelist35>`\n-   :doc:`Changelist 3.4 <changelist34>`\n-   :doc:`Changelist r1825- <changelist34pre>`\n-   :doc:`AviSynth+<avisynthplus>`\n-   :doc:`Changelist 2.6 <changelist26>`\n-   :doc:`AviSynth 2.6 <twopointsix>`\n-   :doc:`AviSynth 2.5 <twopointfive>`\n-   :doc:`Release Notes v2.58 <releasenotes>`\n-   :doc:`Changelist <changelist>`\n-   :doc:`License Terms <license>`\n\n\nInternet Links\n--------------\n\n:doc:`Internet Links <links>`\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/quick_ref.rst",
    "content": "\nQuick Reference\n===============\n\n**Abbreviations:**\n\nNamed arguments are written as \"arg\" and are always optional, non-named\noptional arguments are placed into [] brackets.\nThe types of the non-clip-arguments can be int (integer), float, string or\nbool.\n\n*[yuy2]* etc. denotes the color formats the filter can deal with. See\n:doc:`colorspace conversion filters <corefilters/convert>` for more details.\n\n*[16 bit, float]* etc, denotes the sample types which are supported by the\naudio filter. \"float\" is the most accurate one.\n\n*[v2.53]* denotes the version of AviSynth (above 2.01) since the filter is\navailable, or the last changes in the filter.\n\n\n--------\n\n\nAlphabetic view\n================\n\n:ref:`A` :ref:`B` :ref:`C` :ref:`D` :ref:`E` :ref:`F` :ref:`G` :ref:`H` :ref:`I` [J] :ref:`K`\n:ref:`L` :ref:`M` :ref:`N` :ref:`O` :ref:`P` [Q] :ref:`R` :ref:`S` :ref:`T` [U] :ref:`V` :ref:`W`\n[X] [Y] [Z]\n\n.. _A:\n\nA\n-\n\n:doc:`AddBorders <corefilters/addborders>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``AddBorders`` (clip, int left, int top, int right, int bottom, int\n    \"color\")\n\n:doc:`AudioTrim <corefilters/trim>`\n\n-   ``AudioTrim`` (clip, float start_time, float end_time) *[v2.60]*\n-   ``AudioTrim`` (clip, float start_time, float -duration) *[v2.60]*\n-   ``AudioTrim`` (clip, float start_time, float \"end\") *[v2.60]*\n-   ``AudioTrim`` (clip, float start_time, float \"length\") *[v2.60]*\n\n:doc:`Amplify / AmplifydB <corefilters/amplify>` *[16 bit, float]*\n\n-   ``Amplify`` (clip, float amount1 [, ...])\n-   ``AmplifydB`` (clip, float amount1 [, ...])\n\n:doc:`Animate / ApplyRange <corefilters/animate>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32]\n[rgb24]*\n\n-   ``Animate`` (clip, int start_frame, int end_frame, string filtername,\n    start_args, end_args)\n-   ``ApplyRange`` (clip, int start_frame, int end_frame, string\n    filtername, args)* [v2.51]*\n\n:doc:`AssumeFPS <corefilters/fps>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``AssumeFPS`` (clip, int numerator , int denominator, bool\n    \"sync_audio\")\n-   ``AssumeFPS`` (clip, float fps, bool \"sync_audio\")\n-   ``AssumeFPS`` (clip1, clip2, bool \"sync_audio\") *[v2.55]*\n-   ``AssumeFPS`` (clip, string preset) *[v2.57]*\n\n:ref:`AssumeFrameBased / AssumeFieldBased <AssumeFrameField>` *[yv24] [yv16] [yv12] [yv411] [y8]\n[yuy2] [rgb32] [rgb24]*\n\n-   ``AssumeFrameBased`` (clip)\n-   ``AssumeFieldBased`` (clip)\n\n:ref:`AssumeBFF / AssumeTFF <AssumeFieldFirst>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32]\n[rgb24]*\n\n-   ``AssumeBFF`` (clip)\n-   ``AssumeTFF`` (clip)\n\n:doc:`AssumeSampleRate <corefilters/assumerate>` *[all]*\n\n-   ``AssumeSampleRate`` (clip, int samplerate)\n\n:ref:`AssumeScaledFPS` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``AssumeScaledFPS`` (clip, int \"multiplier\", int \"divisor\", bool\n    \"sync_audio\") *[v2.56]*\n\n:doc:`AudioDub / AudioDubEx <corefilters/audiodub>` *[all]*\n\n-   ``AudioDub`` (video_clip, audio_clip)\n-   ``AudioDubEx`` (video_clip, audio_clip) *[v2.56]*\n\n:doc:`AVISource / OpenDMLSource / AVIFileSource / WAVSource <corefilters/avisource>`\n\n-   ``AVISource`` (string filename [, ...], bool \"audio\", string\n    \"pixel_type\" [, string fourCC])\n-   ``OpenDMLSource`` (string filename [, ...], bool \"audio\", string\n    \"pixel_type\" [, string fourCC])\n-   ``AVIFileSource`` (string filename [, ...], bool \"audio\", string\n    \"pixel_type\" [, string fourCC])\n-   ``WAVSource`` (string filename [, ...])\n\n.. _B:\n\nB\n-\n\n:doc:`BlankClip / Blackness <corefilters/blankclip>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32]\n[rgb24]*\n\n-   ``BlankClip`` (clip clip, int \"length\", int \"width\", int \"height\",\n    string \"pixel_type\", float \"fps\", int \"fps_denominator\",\n    int \"audio_rate\", bool \"stereo\", bool \"sixteen_bit\", int \"color\", int\n    \"color_yuv\")\n-   ``BlankClip`` (clip clip, int \"length\", int \"width\", int \"height\",\n    string \"pixel_type\", float \"fps\", int \"fps_denominator\",\n    int \"audio_rate\", int \"channels\", string \"sample_type\", int \"color\",\n    int \"color_yuv\") *[v2.58]*\n-   ``Blackness`` ()\n\n:doc:`Blur / Sharpen <corefilters/blur>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``Blur`` (clip, float amount)\n-   ``Blur`` (clip, float amountH, float amountV)\n-   ``Sharpen`` (clip, float amount)\n-   ``Sharpen`` (clip, float amountH, float amountV)\n\n:doc:`Bob <corefilters/bob>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``Bob`` (clip, float \"b\", float \"c\", float \"height\")\n\n.. _C:\n\nC\n-\n\n:ref:`ChangeFPS` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``ChangeFPS`` (clip, int numerator , int denominator, bool \"linear\")\n    *[v2.50]*\n-   ``ChangeFPS`` (clip, float fps, bool \"linear\") *[v2.50]*\n-   ``ChangeFPS`` (clip1, clip2, bool \"linear\") *[v2.56]*\n-   ``ChangeFPS`` (clip, string preset) *[v2.57]*\n\n:doc:`ColorBars / ColorBarsHD <corefilters/colorbars>` *[rgb32] [yuy2] [yv12] [yv24]*\n\n-   ``ColorBars`` (int \"width\", int \"height\", string \"pixel_type\")\n-   ``ColorBarsHD`` (int \"width\", int \"height\", string \"pixel_type\")\n    *[v2.60]*\n\n:doc:`ColorYUV <corefilters/coloryuv>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``ColorYUV`` (clip, float \"gain_y\", float \"off_y\", float \"gamma_y\", float\n    \"cont_y\", float \"gain_u\", float \"off_u\", float \"gamma_u\",\n    float \"cont_u\", float \"gain_v\", float \"off_v\", float \"gamma_v\", float\n    \"cont_v\", string \"levels\", string \"opt\", bool \"showyuv\", bool \"analyze\",\n    bool \"autowhite\", bool \"autogain\") *[v2.50]*\n\n:ref:`ComplementParity` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32]\n[rgb24]*\n\n-   ``ComplementParity`` (clip)\n\n:doc:`Compare <corefilters/compare>` *[yv12] [yuy2] [rgb32] [rgb24]*\n\n-   ``Compare`` (clip_filtered, clip_original, string \"channels\", string\n    \"logfile\", bool \"show_graph\")\n\n:doc:`ConditionalFilter / ConditionalSelect / FrameEvaluate / ScriptClip <corefilters/conditionalfilter>` /\n:doc:`ConditionalReader <corefilters/conditionalreader>` *[yv12] [yuy2]*\n\n-   ``ConditionalFilter`` (clip testclip, clip source1, clip source2,\n    string expression1, string operator, string expression2, bool \"show\")\n    *[v2.52]*\n-   ``ConditionalSelect`` (clip testclip, string expression, clip\n    source0, clip source1, clip source2, ..., bool \"show\") *[v2.60]*\n-   ``FrameEvaluate`` (clip clip, script function, bool \"after_frame\")\n    *[v2.52]*\n-   ``ScriptClip`` (clip clip, string function, bool \"show\", bool\n    \"after_frame\") *[v2.52]*\n-   ``ConditionalReader`` (clip clip, string filename, string\n    variablename, bool \"show\") *[v2.54]*\n\n:doc:`ConvertAudioTo8bit / ConvertAudioTo16bit / ConvertAudioTo24bit / ConvertAudioTo32bit / ConvertAudioToFloat <corefilters/convertaudio>` *[all]*\n\n-   ``ConvertAudioTo8bit`` (clip) *[v2.50]*\n-   ``ConvertAudioTo16bit`` (clip)\n-   ``ConvertAudioTo24bit`` (clip) *[v2.53]*\n-   ``ConvertAudioTo32bit`` (clip) *[v2.50]*\n-   ``ConvertAudioToFloat`` (clip) *[v2.50]*\n\n:doc:`ConvertBackToYUY2 / ConvertToRGB / ConvertToRGB24 / ConvertToRGB32 / ConvertToY8 / ConvertToYUY2 / ConvertToYV12 / ConvertToYV16 / ConvertToYV24 / ConvertToYV411 <corefilters/convert>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2]\n[rgb32] [rgb24]*\n\n-   ``ConvertToRGB`` (clip, string \"matrix\", bool \"interlaced\", string\n    \"ChromaInPlacement\", string \"chromaresample\")\n-   ``ConvertToRGB24`` (clip, string \"matrix\", bool \"interlaced\", string\n    \"ChromaInPlacement\", string \"chromaresample\")\n-   ``ConvertToRGB32`` (clip, string \"matrix\", bool \"interlaced\", string\n    \"ChromaInPlacement\", string \"chromaresample\")\n-   ``ConvertToYUY2`` (clip, bool \"interlaced\", string \"matrix\", string\n    \"ChromaInPlacement\", string \"chromaresample\")\n-   ``ConvertToBackYUY2`` (clip, string \"matrix\")\n-   ``ConvertToY8`` (clip, string \"matrix\") *[v 2.60]*\n-   ``ConvertToYV12`` (clip, bool \"interlaced\", string \"matrix\", string\n    \"ChromaInPlacement\", string \"chromaresample\", string\n    \"ChromaOutPlacement\") *[v 2.50]*\n-   ``ConvertToYV16`` (clip, bool \"interlaced\", string \"matrix\", string\n    \"ChromaInPlacement\", string \"chromaresample\") *[v 2.60]*\n-   ``ConvertToYV24`` (clip, bool \"interlaced\", string \"matrix\", string\n    \"ChromaInPlacement\", string \"chromaresample\") *[v 2.60]*\n-   ``ConvertToYV411`` (clip, bool \"interlaced\", string \"matrix\", string\n    \"ChromaInPlacement\", string \"chromaresample\") *[v 2.60]*\n\n:ref:`ConvertFPS` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``ConvertFPS`` (clip, float new_fps, int \"zone\", int \"vbi\")\n-   ``ConvertFPS`` (clip, int numerator, int denominator, int \"zone\", int \"vbi\")\n-   ``ConvertFPS`` (clip1, clip2, int \"zone\", int \"vbi\") *[v2.56]*\n-   ``ConvertFPS`` (clip, string preset) *[v2.57]*\n\n:doc:`ConvertToMono <corefilters/converttomono>` *[16 bit, float]*\n\n-   ``ConvertToMono`` (clip)\n\n:doc:`Crop / CropBottom <corefilters/crop>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``Crop`` (clip, int left, int top, int width, int height, bool \"align\")\n-   ``Crop`` (clip, int left, int top, int -right, int -bottom, bool \"align\")\n-   ``CropBottom`` (clip, int count,  bool \"align\")\n\n.. _D:\n\nD\n-\n\n:doc:`DelayAudio <corefilters/delayaudio>` *[all]*\n\n-   ``DelayAudio`` (clip, float seconds)\n\n:doc:`DeleteFrame <corefilters/deleteframe>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``DeleteFrame`` (clip, int frame [, ...])\n\n:doc:`DirectShowSource <corefilters/directshowsource>`\n\n-   ``DirectShowSource`` (string filename, float \"fps\", bool \"seek\", bool\n    \"audio\", bool \"video\", bool \"convertfps\", bool \"seekzero\", int \"timeout\",\n    string \"pixel_type\", int \"framecount\", string \"logfile\", int \"logmask\")\n\n:doc:`Dissolve <corefilters/dissolve>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``Dissolve`` (clip1, clip2 [, ...], int overlap, float \"fps\")\n\n:doc:`DoubleWeave <corefilters/doubleweave>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``DoubleWeave`` (clip)\n\n:doc:`DuplicateFrame <corefilters/duplicateframe>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``DuplicateFrame`` (clip, int frame [, ...])\n\n.. _E:\n\nE\n-\n\n:doc:`Echo <corefilters/echo>` *[all]*\n\n-   ``Echo`` (clip1, clip2 [, ...])\n\n:doc:`EnsureVBRMP3Sync <corefilters/ensuresync>` *[all]*\n\n-   ``EnsureVBRMP3Sync`` (clip)\n\n.. _F:\n\nF\n-\n\n:doc:`FadeIn0 / FadeIO0 / FadeOut0 / FadeIn / FadeIO / FadeOut / FadeIn2 / FadeIO2/ FadeOut2 <corefilters/fade>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2]\n[rgb32] [rgb24]*\n\n-   ``FadeIn0`` (clip, int frames, int \"color\", float \"fps\") *[v2.56]*\n-   ``FadeIn`` (clip, int frames, int \"color\", float \"fps\")\n-   ``FadeIn2`` (clip, int frames, int \"color\", float \"fps\")\n-   ``FadeIO0`` (clip, int frames, int \"color\", float \"fps\") *[v2.56]*\n-   ``FadeIO`` (clip, int frames, int \"color\", float \"fps\")\n-   ``FadeIO2`` (clip, int frames, int \"color\", float \"fps\")\n-   ``FadeOut0`` (clip, int frames, int \"color\", float \"fps\") *[v2.56]*\n-   ``FadeOut`` (clip, int frames, int \"color\", float \"fps\")\n-   ``FadeOut2`` (clip, int frames, int \"color\", float \"fps\")\n\n:doc:`FixBrokenChromaUpsampling <corefilters/fixbrokenchromaupsampling>` *[yuy2]*\n\n-   ``FixBrokenChromaUpsampling`` (clip)\n\n:doc:`FixLuminance <corefilters/fixluminance>` *[yuy2]*\n\n-   ``FixLuminance`` (clip, int intercept, int slope)\n\n:doc:`FlipHorizontal / FlipVertical <corefilters/flip>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2]\n[rgb32] [rgb24]*\n\n-   ``FlipHorizontal`` (clip) *[v2.50]*\n-   ``FlipVertical`` (clip)\n\n:doc:`FreezeFrame <corefilters/freezeframe>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``FreezeFrame`` (clip, int first_frame, int last_frame, int\n    source_frame)\n\n.. _G:\n\nG\n-\n\n:doc:`GeneralConvolution <corefilters/convolution>` *[rgb32]*\n\n-   ``GeneralConvolution`` (clip, int \"bias\", string \"matrix\", float\n    \"divisor\", bool \"auto\") *[v2.55]*\n\n:doc:`GetChannel <corefilters/getchannel>` *[all]*\n\n-   ``GetChannel`` (clip, int ch1 [, int ch2, ...]) *[v2.50]*\n-   ``GetChannels`` (clip, int ch1 [, int ch2, ...]) *[v2.50]*\n\n:doc:`Greyscale <corefilters/greyscale>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``Greyscale`` (clip, string \"matrix\")\n\n.. _H:\n\nH\n-\n\n:doc:`Histogram <corefilters/histogram>` *[yv12] [yuy2]*\n\n-   ``Histogram`` (clip, string ''mode'') *[v2.54]*\n\n.. _I:\n\nI\n-\n\n:doc:`ImageReader / ImageSource/ ImageSourceAnim <corefilters/imagesource>` / :doc:`ImageWriter <corefilters/imagewriter>` *[yv12] [y8]\n[yuy2] [rgb32] [rgb24]*\n\n-   ``ImageReader`` (string \"path\", int \"start\", int \"end\", float \"fps\",\n    bool \"use_DevIL\", bool \"info\", string \"pixel_type\") *[v2.52]*\n-   ``ImageSource`` (string \"path\", int \"start\", int \"end\", float \"fps\",\n    bool \"use_DevIL\", bool \"info\", string \"pixel_type\") *[v2.55]*\n-   ``ImageSourceAnim`` (string \"file\", float \"fps\", bool \"info\", string\n    \"pixel_type\") *[v2.60]*\n-   ``ImageWriter`` (clip, string \"path\", int \"start\", int \"end\", string\n    \"type\", bool \"info\") *[v2.52]*\n\n:doc:`Import <corefilters/import>`\n\n-   ``Import`` (string [, ...])\n\n:doc:`Info <corefilters/info>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``Info`` (clip) *[v2.50]*\n\n:doc:`Interleave <corefilters/interleave>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``Interleave`` (clip1, clip2 [, ...])\n\n:doc:`Invert <corefilters/invert>` *[yv12, v2.55] [yuy2, v2.55] [rgb32] [rgb24, v2.55]*\n\n-   ``Invert`` (clip, string \"channels\") *[v2.53]*\n\n.. _K:\n\nK\n-\n\n:doc:`KillAudio <corefilters/killaudio>` *[all]*\n\n-   ``KillAudio`` (clip)\n\n:doc:`KillVideo <corefilters/killaudio>` *[all]*\n\n-   ``KillVideo`` (clip) *[v2.57]*\n\n.. _L:\n\nL\n-\n\n:doc:`Layer / Mask / ResetMask / ColorKeyMask <corefilters/layer>` *[RGB32]*\n\n-   ``Layer`` (clip, layer_clip, string \"op\", int \"level\", int \"x\", int\n    \"y\", int \"threshold\", bool \"use_chroma\") *[yuy2] [rgb32]*\n-   ``Mask`` (clip, mask_clip) *[rgb32]*\n-   ``ResetMask`` (clip) *[rgb32]*\n-   ``ColorKeyMask`` (clip, int \"color\", int \"tolB\" [, int \"tolG\", int\n    \"tolR\"]) *[rgb32]*\n\n:doc:`Letterbox <corefilters/letterbox>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``Letterbox`` (clip, int top, int bottom [, int left, int right])\n\n:doc:`Levels <corefilters/levels>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``Levels`` (clip, int input_low, float gamma, int input_high, int\n    output_low, int output_high, bool \"coring\", bool \"dither\")\n\n:doc:`Limiter <corefilters/limiter>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2]*\n\n-   ``Limiter`` (clip, int \"min_luma\", int \"max_luma\", int \"min_chroma\",\n    int \"max_chroma\" [, string show])* [v2.50]*\n\n:doc:`Loop <corefilters/loop>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``Loop`` (clip, int \"times\", int \"start\", int \"end\")\n\n.. _M:\n\nM\n-\n\n:doc:`MaskHS <corefilters/maskhs>` *[yv24] [yv16] [yv12] [yv411] [yuy2] [2.60]*\n\n-   ``MaskHS`` (clip, float \"startHue\", float \"endHue\", float \"maxSat\",\n    float \"minSat\", bool \"coring\")\n\n:doc:`MergeARGB / MergeRGB <corefilters/mergergb>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32]\n[rgb24] [v2.56]*\n\n-   ``MergeARGB`` (clipA, clipR, clipG, clipB)\n-   ``MergeRGB`` (clipR, clipG, clipB [, string \"pixel_type\"])\n\n:doc:`MergeChannels <corefilters/mergechannels>` *[all]*\n\n-   ``MergeChannels`` (clip1, clip2 [, ...])* [v2.50]*\n\n:doc:`Merge / MergeChroma / MergeLuma <corefilters/merge>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2]*\n\n-   ``Merge`` (clip1, clip2, float \"weight\") *[yv12, yuy2, rgb32, rgb24] [v2.56]*\n-   ``MergeChroma`` (clip1, clip2, float \"weight\")\n-   ``MergeLuma`` (clip1, clip2, float \"weight\")\n\n:doc:`MessageClip <corefilters/message>` *[rgb32]*\n\n-   ``MessageClip`` (string message, int \"width\", int \"height\", bool\n    \"shrink\", int \"text_color\", int \"halo_color\", int \"bg_color\")\n\n:doc:`MixAudio <corefilters/mixaudio>` *[16 bit, float]*\n\n-   ``MixAudio`` (clip1, clip 2, float clip1_factor, float\n    \"clip2_factor\")\n\n.. _N:\n\nN\n-\n\n:doc:`Normalize <corefilters/normalize>` *[16 bit, float]*\n\n-   ``Normalize`` (clip, float \"volume\", bool \"show\")\n\n.. _O:\n\nO\n-\n\n:doc:`Overlay <corefilters/overlay>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``Overlay`` (clip, clip overlay, int \"x\", int \"y\", clip \"mask\", float\n    \"opacity\", string \"mode\", bool \"greymask\", string \"output\",\n    bool \"ignore_conditional\", bool \"pc_range\") *[v2.54]*\n\n.. _P:\n\nP\n-\n\n:doc:`PeculiarBlend <corefilters/peculiar>` *[yuy2]*\n\n-   ``PeculiarBlend`` (clip, int cutoff)\n\n:doc:`Preroll <corefilters/preroll>` *[all]*\n\n-   ``Preroll`` (clip, int \"video\", float \"audio\")\n\n:doc:`Pulldown <corefilters/pulldown>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``Pulldown`` (clip, int a , int b)\n\n.. _R:\n\nR\n-\n\n:doc:`RGBAdjust <corefilters/adjust>` *[rgb32] [rgb24]*\n\n-   ``RGBAdjust`` (clip, float \"r\", float \"g\", float \"b\", float \"a\",\n    float \"rb\", float \"gb\", float \"bb\", float \"ab\", float \"rg\", float \"gg\",\n    float \"bg\", float \"ag\", bool \"analyze\", bool \"dither\")\n\n:doc:`ReduceBy2 / HorizontalReduceBy2 / VerticalReduceBy2 <corefilters/reduceby2>` *[yv24] [yv16] [yv12]\n[yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``HorizontalReduceBy2`` (clip)\n-   ``VerticalReduceBy2`` (clip)\n-   ``ReduceBy2`` (clip)\n\n:doc:`ResampleAudio <corefilters/resampleaudio>` *[16 bit, float]*\n\n-   ``ResampleAudio`` (clip, int new_rate_numberator [, int\n    new_rate_denominator])\n\n:doc:`BilinearResize / BicubicResize / BlackmanResize / GaussResize / LanczosResize / Lanczos4Resize / PointResize / SincResize / Spline16Resize / Spline36Resize / Spline64Resize <corefilters/resize>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2]\n[rgb32] [rgb24]*\n\n-   ``BilinearResize`` (clip, int target_width, int target_height, float\n    \"src_left\", float \"src_top\", float \"src_width\", float \"src_height\")\n-   ``BicubicResize`` (clip, int target_width, int target_height, float\n    \"b=1./3.\", float \"c=1./3.\", float \"src_left\", float \"src_top\", float\n    \"src_width\", float \"src_height\")\n-   ``BlackmanResize`` (clip, int target_width, int target_height, float\n    \"src_left\", float \"src_top\", float \"src_width\", float \"src_height\", int\n    \"taps=4\") *[v2.58]*\n-   ``GaussResize`` (clip, int target_width, int target_height, float\n    \"src_left\", float \"src_top\", float \"src_width\", float \"src_height\", float\n    \"p=30.0\") *[v2.56]*\n-   ``LanczosResize`` (clip, int target_width, int target_height, float\n    \"src_left\", float \"src_top\", float \"src_width\", float \"src_height\", int\n    \"taps=3\")\n-   ``Lanczos4Resize`` (clip, int target_width, int target_height, float\n    \"src_left\", float \"src_top\", float \"src_width\", float \"src_height\")\n    *[v2.55]*\n-   ``PointResize`` (clip, int target_width, int target_height, float\n    \"src_left\", float \"src_top\", float \"src_width\", float \"src_height\")\n-   ``SincResize`` (clip, int target_width, int target_height, float\n    \"src_left\", float \"src_top\", float \"src_width\", float \"src_height\", int\n    \"taps=4\") *[v2.6]*\n-   ``Spline16Resize`` (clip, int target_width, int target_height, float\n    \"src_left\", float \"src_top\", float \"src_width\", float \"src_height\")\n    *[v2.56]*\n-   ``Spline36Resize`` (clip, int target_width, int target_height, float\n    \"src_left\", float \"src_top\", float \"src_width\", float \"src_height\")\n    *[v2.56]*\n-   ``Spline64Resize`` (clip, int target_width, int target_height, float\n    \"src_left\", float \"src_top\", float \"src_width\", float \"src_height\")\n    *[v2.58]*\n-   all resizers: ``xxxResize`` (clip, int target_width, int\n    target_height, float \"src_left\", float \"src_top\", float -\"src_right\",\n    float -\"src_bottom\") *[v2.56]*\n\n:doc:`Reverse <corefilters/reverse>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``Reverse`` (clip)\n\n.. _S:\n\nS\n-\n\n:doc:`SegmentedAVISource / SegmentedDirectShowSource <corefilters/segmentedsource>`\n\n-   ``SegmentedAVISource`` (string base_filename [, ...], bool \"audio\")\n-   ``SegmentedDirectShowSource`` (string base_filename [, ...]  [, fps])\n\n:doc:`SelectEven / SelectOdd <corefilters/select>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32]\n[rgb24]*\n\n-   ``SelectEven`` (clip)\n-   ``SelectOdd`` (clip)\n\n:doc:`SelectEvery <corefilters/selectevery>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``SelectEvery`` (clip, int step_size, int offset1 [, int offset2 [,\n    ...]])\n\n:doc:`SelectRangeEvery <corefilters/selectrangeevery>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32]\n[rgb24]*\n\n-   ``SelectRangeEvery`` (clip, int every, int length, int \"offset\", bool\n    \"audio'') *[v2.50]*\n\n:doc:`SeparateFields <corefilters/separatefields>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``SeparateFields`` (clip)\n-   ``SeparateColumns`` (clip, int interval) *[v2.60]*\n-   ``SeparateRows`` (clip, int interval) *[v2.60]*\n\n:doc:`ShowAlpha <corefilters/showalpha>` *[rgb32]*\n\n-   ``ShowAlpha`` (clip, string \"pixel_type\") *[v2.54]*\n\n:doc:`ShowRed, ShowGreen, ShowBlue <corefilters/showalpha>` *[rgb24] [rgb32] [v2.56]*\n\n-   ``ShowRed`` (clip, string \"pixel_type\")\n-   ``ShowGreen`` (clip, string \"pixel_type\")\n-   ``ShowBlue`` (clip, string \"pixel_type\")\n\n:doc:`ShowFiveVersions <corefilters/showfive>` *[yv12] [yuy2] [rgb32] [rgb24]*\n\n-   ``ShowFiveVersions`` (clip1, clip2, clip3, clip4, clip5)\n\n:doc:`ShowFrameNumber / ShowSMPTE / ShowTime <corefilters/showframes>` *[yv12] [yuy2] [rgb32] [rgb24]*\n\n-   ``ShowFrameNumber`` (clip, bool \"scroll\", int \"offset\", float \"x\",\n    float \"y\", string \"font\", int \"size\", int \"text_color\", int \"halo_color\",\n    float \"font_width\", float \"font_angle\")\n-   ``ShowSMPTE`` (clip, float \"fps\", string \"offset\", int \"offset_f\",\n    float \"x\", float \"y\", string \"font\", int \"size\", int \"text_color\", int\n    \"halo_color\", float \"font_width\", float \"font_angle\")\n-   ``ShowTime`` (clip, int \"offset_f\", float \"x\", float \"y\", string\n    \"font\", int \"size\", int \"text_color\", int \"halo_color\", float\n    \"font_width\", float \"font_angle\")* [v2.58]*\n\n:doc:`SkewRows <corefilters/skewrows>` *[y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``SkewRows`` (clip, int skew) *[v2.60]*\n\n:doc:`SoundOut <corefilters/soundout>` *[all] [v2.60]*\n\n-   ``SoundOut`` (string output, string filename, bool \"showprogress\",\n    string overwritefile, bool \"autoclose\", bool \"silentblock\", bool\n    \"addvideo\", special parameters)\n\n-   -   (the :doc:`special parameters <corefilters/soundout>` are output dependent and they are explained in the\n        documentation itself)\n\n:doc:`SpatialSoften / TemporalSoften <corefilters/soften>` *[yv12] [yuy2] [rgb32, v2.56]*\n\n-   ``SpatialSoften`` (clip, int radius, int luma_threshold, int\n    chroma_threshold)\n-   ``TemporalSoften`` (clip, int radius, int luma_threshold, int\n    chroma_threshold, int \"scenechange\", int \"mode\")* [v2.50]*\n\n:doc:`AlignedSplice / UnalignedSplice <corefilters/splice>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2]\n[rgb32] [rgb24]*\n\n-   ``AlignedSplice`` (clip1, clip2 [, ...])\n-   ``UnAlignedSplice`` (clip1, clip2 [, ...])\n\n:doc:`SSRC <corefilters/ssrc>` *[float]*\n\n-   ``SSRC`` (clip, int samplerate, bool \"fast\") *[v2.54]*\n\n:doc:`StackHorizontal / StackVertical <corefilters/stack>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2]\n[rgb32] [rgb24]*\n\n-   ``StackHorizontal`` (clip1, clip2 [, ...])\n-   ``StackVertical`` (clip1, clip2 [, ...])\n\n:doc:`Subtitle <corefilters/subtitle>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``Subtitle`` (clip, string text, float \"x\", float \"y\", int\n    \"first_frame\", int \"last_frame\", string \"font\", int \"size\", int\n    \"text_color\", int \"halo_color\", int \"lsp\", float \"font_width\", float\n    \"font_angle\", bool \"interlaced\")\n-   ``Subtitle`` (clip, string \"text\")\n\n:doc:`Subtract <corefilters/subtract>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``Subtract`` (clip1, clip2)\n\n:doc:`SuperEQ <corefilters/supereq>` *[float]*\n\n-   ``SuperEQ`` (clip, string filename) *[v2.54]*\n-   ``SuperEQ`` (clip, float band1 [, float band1, ..., float band18])\n    *[v2.60]*\n\n:doc:`SwapUV / UToY / VToY / YToUV <corefilters/swap>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2]*\n\n-   ``SwapUV`` (clip) *[v2.50]*\n-   ``UToY`` (clip) *[v2.50]*\n-   ``UToY8`` (clip) *[v2.60]*\n-   ``VToY`` (clip) *[v2.50]*\n-   ``VToY8`` (clip) *[v2.60]*\n-   ``YToUV`` (clip clipU, clip clipV [, clip clipY]) *[v2.50, v2.51]*\n\n:doc:`SwapFields <corefilters/swapfields>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``SwapFields`` (clip)\n\n.. _T:\n\nT\n-\n\n:doc:`TCPDeliver <corefilters/tcpdeliver>`\n\n-   ``TCPServer`` (clip, int \"port\") *[v2.55]*\n-   ``TCPSource`` (string hostname, int \"port\", string \"compression\")\n    *[v2.55]*\n\n:doc:`TimeStretch <corefilters/timestretch>` *[float]*\n\n-   ``TimeStretch`` (clip, float \"tempo\", float \"rate\", float \"pitch\",\n    int \"sequence\", int \"seekwindow\", int \"overlap\", bool \"quickseek\", int\n    \"aa\") *[v2.57]*\n\n:doc:`Tone <corefilters/tone>` *[float]*\n\n-   ``Tone`` (float \"length\", float \"frequency\", int \"samplerate\", int\n    \"channels\", string \"type\", float \"level\") *[v2.54]*\n\n:doc:`Trim <corefilters/trim>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``Trim`` (clip, int first_frame, int last_frame [, bool \"pad\"])\n    *[v2.56]*\n-   ``Trim`` (clip, int first_frame, int -num_frames [, bool \"pad\"])\n    *[v2.56]*\n-   ``Trim`` (clip, int start_time, int \"end\" [, bool \"pad\"]) *[v2.60]*\n-   ``Trim`` (clip, int start_time, int \"length\" [, bool \"pad\"])\n    *[v2.60]*\n\n:doc:`TurnLeft / TurnRight / Turn180 <corefilters/turn>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2]\n[rgb32] [rgb24]*\n\n-   ``TurnLeft`` (clip) *[v2.51]*\n-   ``TurnRight`` (clip) *[v2.51]*\n-   ``Turn180`` (clip) *[v2.55]*\n\n:doc:`Tweak <corefilters/tweak>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2]*\n\n-   ``Tweak`` (clip, float \"hue\", float \"sat\", float \"bright\", float\n    \"cont\", bool \"coring\", bool \"sse\", float \"startHue\", float \"endHue\",\n    float \"maxSat\", float \"minSat\", float \"interp\", bool \"dither\")\n\n.. _V:\n\nV\n-\n\n:doc:`Version <corefilters/version>` *[rgb24]*\n\n-   ``Version`` ()\n\n.. _W:\n\nW\n-\n\n:doc:`Weave <corefilters/weave>` *[yv24] [yv16] [yv12] [yv411] [y8] [yuy2] [rgb32] [rgb24]*\n\n-   ``Weave`` (clip)\n-   ``WeaveColumns`` (clip, int period) *[v2.60]*\n-   ``WeaveRows`` (clip, int period) *[v2.60]*\n\n:doc:`WriteFile / WriteFileIf / WriteFileStart / WriteFileEnd <corefilters/write>` *[yv12] [yuy2]\n[rgb32] [rgb24]*\n\n-   ``WriteFile`` (clip, string filename, *string expression1 [, string\n    expression2 [, ...]], bool \"append\", bool \"flush\"*)\n-   ``WriteFileIf`` (clip, string filename, *string expression1 [, string\n    expression2 [, ...]], bool \"append\", bool \"flush\"*)\n-   ``WriteFileStart`` (clip, string filename, *string expression1 [,\n    string expression2 [, ...]], bool \"append\"*)\n-   ``WriteFileEnd`` (clip, string filename, *string expression1 [,\n    string expression2 [, ...]], bool \"append\"*)\n\n[ :ref:`A` :ref:`B` :ref:`C` :ref:`D` :ref:`E` :ref:`F` :ref:`G` :ref:`H` :ref:`I` [J] :ref:`K`\n:ref:`L` :ref:`M` :ref:`N` :ref:`O` :ref:`P` [Q] :ref:`R` :ref:`S` :ref:`T` [U] :ref:`V` :ref:`W`\n[X] [Y] [Z] ]\n\n$Date: 2013/01/06 13:38:34 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/releasenotes.rst",
    "content": "\nRelease Notes\n=============\n\nAviSynth 2.58\n-------------\n\n\nSummary of changelist (with respect to v2.57)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n-   Added Czech doc translation.\n-   Added Polish doc translation by Slim, Krismen & Co.\n-   Added Japanese doc translation by niiyan.\n-   Added Installer standalone option.\n-   Added Blankclip audio channels= and sample_type= arguments.\n-   ConvertAudio(cii) available to plugins via env->Invoke().\n-   Added font aspect, rotation and alpha to text routines.\n-   Added ``/* xxx */`` block comments.\n-   Added ``[* [* xxx *] *]`` nestable block comments.\n-   SetMemoryMax(0) now just returns Memory Max value.\n-   Added planar YV12 color format to Compare().\n-   ColorKeyMask: Allow independant tolerance levels for each channel.\n-   Added Tweak Hue/Saturation range limiting.\n-   Added AudioLevels and Color2 modes to Histogram.\n-   Added WAVE_FORMAT_EXTENSIBLE audio output.\n-   Added ShowTime() script verb, like ShowSMPTE() but with milliseconds.\n-   Added BlackmanResize() and Spline64Resize().\n-   Modified DeleteFrame()/DuplicateFrame() to process multiple\n    arguments.\n-   Added Min()/Max() script functions.\n\n-   Fixed ShowFiveVersions() YV12 chroma position in bottom half.\n    Regression.\n-   Fixed Histogram() Classic mode restore graph brightness. Regression.\n-   Fixed Compare() graph pixel values exceeding YUV limits.\n-   Fixed AddBorders() args negative value clamping.\n-   Fixed AviSource() decoding to RGB24 logic regression.\n-   Added workaround for HuffYUV, Xvid reading past end of input buffer.\n-   Fixed current_frame value in nested runtime script invocations\n    (Gavino).\n-   Fixed Dissolve overlap arg range checking (gzarkadas).\n-   Fixed OpenDMLSource() multithreading race problem (QuaddiMM).\n-   Fixed unsaved variableName string in ConditionalReader.\n-   Fixed Parser FunctionTable::TypeMatch() missing compulsory arguments.\n    Dissolve bug (Various).\n-   Fixed DirectShowSource() convertfps=false logic regression.\n-   Fixed DirectShowSource() Flush task interlock race.\n-   Fixed DirectShowSource() QueryId() use CoTaskMemAlloc for returned\n    value (Dean Pavlekovic).\n-   Fixed DirectShowSource() use GraphBuilder object for media control\n    (Avery Lee).\n-   Fixed DirectShowSource() remove PulseEvent calls (Avery Lee).\n-   Fixed DirectShowSource() QueryAccept() modifying VideoInfo in running\n    script (Haali).\n-   Fixed Blankclip clip= argument parsing.\n-   Fixed trashed GPF report, i.e reading 0x0 at 0x0 exception reporting.\n-   Fixed and refactored Overlay RGB<->YUV conversion routines.\n-   Fixed ImageReader incompletely inited videoInfo.\n-   Fixed Layer RGB32 100% alpha implementation, use level=257 (new\n    default).\n-   Fixed avisynth_c.h avs_is_parity_known().\n-   Fixed C++ ConvertAudio::Saturate_int32() rounding.\n-   Fixed WriteFile(), Now remebers absolute path to file.\n-   Fixed Info() frame pitch, reports pitch of input frame.\n-   Fixed Invert() right edge memory overrun/corruption.\n-   Fixed Histogram() Classic mode pixel values exceeding YUV limits.\n-   Fixed Histogram() chroma plane initialization to 128.\n-   Fixed Conditional reader/writer illegally saving IScriptEnvironment\n    pointer.\n-   Fixed YV12 Blur()/Sharpen() right edge pixel corruption with non-\n    writable input frames.\n-   Fixed MMX Blur()/Sharpen() code to full 8 bit precision.\n-   Fixed IsAudioFloat()/IsAudioInt() script functions.\n-   Fixed Cache memory oversubscription of SetMemoryMax() limit.\n\n-   DirectShowSource() convertfps=true add 0.5ms rounding to expected\n    sample time. Improves performance with millisecond based DS spliters.\n-   DirectShowSource() FPS detection as last attempt try getting the\n    duration of 1st frame.\n-   DirectShowSource() convertfps=true rely only on sample start time\n    values.\n-   Cache: Trap returned NULL PVideoFrames, i.e. Don't crash, Winge about\n    it!.\n-   Refactor horizontal planar resizer, no width restrictions or 2 byte\n    overwrite.\n-   Provide a simple and fast text writing primatives, see info.h\n-   Make audio cache actually functional.\n-   Tweak speed improvements.\n-   Subtract speed improvements.\n-   Tuneup Overlay() ISSE Convert444ChromaToYV12 and also provide MMX\n    version.\n-   PokeCache interface implemented.\n-   Cache and Memory management enhancements.\n\n-   Initial Memory Max value clamped to 512MB.\n-   Default Memory Max value restored to quarter of Free memory. Minimum\n    16Mb. As per 2.5.7.\n-   Test VFB data buffer for NULL malloc's, if so then Throw!\n-   Installer Start menu shortcut names translated.\n-   Test for UTF-8 and Unicode BOM prefixes and issue a useful warning.\n-   Removed useless current_sample from runtime script environment.\n-   Added critical section to CAVIFileSynth class.\n-   Enable Installer multi language support.\n-   FunctionTable::Lookup() now considers named arguments in making its\n    selection.\n-   ImageWriter supports negative values as -count for End argument.\n-   ChangeFPS() use floor instead of round in source frame number\n    calculation.\n-   Update usage of correct (updated) Rec.709 coefficients.\n-   Add TCPDeliver.map and DirectShowSource.map to releases.\n-   Convert to 2.6 Dynamic Assembled rgb to yuy2 code.\n-   Avisynth_c.h boolean functions return 1 for true instead of arbitrary\n    non-zero.\n-   Internal RGB2YUV() now copies Alpha top byte through.\n-   CoUninitialize() done immediately for S_FALSE CoInitialize() returns.\n-   Pfc, Softwire and SoundTouch updated and added as dependency\n    projects.\n-   UPX updated to version 2.03 (2006-11-07).\n-   AVISource/WavSource map WAVEFORMATEXTENSIBLE back to equivalent\n    WAVEFORMATEX.\n-   DirectShowSource() now recognises incorrect WAVE_FORMAT_EXTENSIBLE\n    audio and accepts it.\n-   DirectShowSource() now attempts to use partial graph from failing\n    RenderFile call.\n-   DirectShowSource() now detects and handles non 32 bit aligned picture\n    lines from dud codecs.\n-   Crop(align=true) tests actual alignment in each GetFrame call.\n-   Relax YV12 resizer width restriction, now mod 2 was mod 4.\n-   .AVSI failures during env->CreateScriptEnvironment() are now\n    available to the GetError() interface.\n-   SetCacheHints(CACHE_RANGE, n) will now surrender frames to satisfy\n    SetMemoryMax().\n-   CoInitialize()/CoUninitialize() now done as part of ScriptEnvironment\n    creation/deletion.\n-   Much code from 2.6 base included. Typically IsYV12() changed to\n    IsPlanar().\n\nA complete list can be found :doc:`here <changelist>` and `there`_.\n\n\nKnown problems and issues\n~~~~~~~~~~~~~~~~~~~~~~~~~\n\n-   Rightclick on scripts to open them in VDubMod: When the script is\n    messed up in the script editor, the correct error message does not\n    appear.\n-   Possible other bugs which are reported `sourceforge`_.\n\n\nFuture plans\n~~~~~~~~~~~~\n\n\nAviSynth v2.60\n--------------\n\nThis version will be the next major version. Plugins for v2.5 will work in\nv2.6. Most of the new code will be dormant inside 2.58 and with a minimal\nsurgical change a parallel 2.60 release will be made. This should allow easy\nA-B testing for coding problems versus 2.6 interface problems. Design goals\nand proposals can be found `in this thread`_. Proposals include the following:\n\n-   New Y8 (greyscale), YV411(4:1:1 planar), YV16 (4:2:2 planar), YV24\n    (4:4:4 planar) formats.\n-   All planes are created 16 byte address aligned and have mod 16 pitch.\n-   Thread-safe avisynth.h.\n\n\nAviSynth v2.61\n--------------\n\nThis version will use the free Microsoft compiler. It will be feature\nidentical to 2.60 i.e. Source new syntax changes only!\n\n\nAviSynth v2.6n\n--------------\n\nA bit further down the track as time and volunteers permit.\n\n-   Add MaskTools to the core.\n-   Official Win64 support.\n-   ImageMagick support to import and export pictures (besides DevIL).\n\n\nAviSynth v3\n-----------\n\nAviSynth v3.0 is a powerful frameserver for Windows and Linux, and it is a\ncomplete rewrite of AviSynth v2.5, written from scratch by Bidoche (David\nPierre), Kurosu, Caro and others. v3.0 is not relying on vfw anymore,\nalthough it can be used when possible. It is made in such a way, that new\nAPIs can be added to the core, like ffmpeg and gstreamer. Also here many new\ncolorformats will be added: YV24, RGB45 and YV45 which are 15 bits depth\nversions of RGB24 and YV24. Direct streaming will be supported, and many\nother new things. The progress can be found `on avisynth.nl`_. The\ndiscussion takes place at irc.freenode.org#avisynth and `on Doom9`_.\n\n$Date: 2025-02-25 17:47:02-05:00 $\n\n.. _there: http://avisynth.nl/index.php/Changelist\n.. _sourceforge:\n    http://sourceforge.net/tracker/?atid=482673&group_id=57023&func=browse\n.. _in this thread: http://forum.doom9.org/showthread.php?t=98585\n.. _on avisynth.nl: http://avisynth.nl/index.php/AviSynth_v3\n.. _on Doom9: http://forum.doom9.org/showthread.php?p=721468\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/script_ref/script_ref.rst",
    "content": "\nScripting reference\n===================\n\nThis section contains information that goes beyond scripting basics. It\npresents the internals of AviSynth script processing, their influence on\nscript performance as well as advanced techniques for using productively the\nfeatures of the AviSynth script language. Before reading further it is\nrecommended that you first become familiar with basic concepts of the\n:doc:`AviSynth syntax <../syntax/syntax_ref>`.\n\n-   :doc:`The script execution model <script_ref_execution_model>`\n\nThe steps behind the scenes from the script to the final video clip output.\nThe filter graph. Scope and lifetime of variables. Evaluation of runtime\nscripts.\n\n-   :doc:`User functions <script_ref_user_functions>`\n\nHow to effectively write and invoke user functions; common pitfalls to avoid;\nways to organise your function collection and create libraries of functions,\nand many more.\n\n-   :doc:`Block statements <script_ref_block_statements>`\n\nTechniques and coding idioms for creating blocks of AviSynth script\nstatements.\n\n-   :doc:`Arrays <script_ref_arrays>`\n\nUsing arrays and array operators for manipulating collections of data in a\nsingle step.\n\n-   :doc:`Runtime environment <../syntax/syntax_runtime_environment>`\n\nHow to unravel the power of runtime filters and create complex runtime\nscripts that can perform interesting (and memory/speed efficient)\nediting/processing operations and effects.\n\n$Date: 2008/04/20 19:07:33 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/script_ref/script_ref_arrays.rst",
    "content": "\nArrays\n======\n\nArrays (AviSynth+)\n^^^^^^^^^^^^^^^^^^\n\nBeginning Avisynth+ 3.6 script arrays are supported. Functionality is different from `AVSLib`_ described below.\n\n-  Arrays can have one or more dimensions\n-  They even can be empty.\n-  AVSValue (internal representation of any Avisynth variable) is deep copied for arrays (arrays in arrays in ...)\n   (note: this is true when using them through c++ plugins. C interface is different, there is no deep-copy there)\n-  untyped and unconstrained element number\n-  arrays can appear as internal filter parameters (named and unnamed).\n-  arrays can appear as user defined function parameters (named and unnamed).\n-  elements are accessible with indexes or in a dictionary-like associative way\n-  Array modifier functions allow multidimensional subarray indexes\n-  array indexes start from zero.\n\n  - ArrayIns - insert before position\n  - ArrayAdd - append\n  - ArrayDel - delete from position\n  - ArraySet - replace at position\n  - ArrayGet - a function-like version of the bracket-type [] syntax\n  - ArraySort - sort arrays of bool, numeric or string values\n\n-  Query the array length with ``ArraySize``\n-  Test is a variable is of explicite array type: ``IsArray``\n\nArrayIns\n^^^^^^^^\n::\n\n  ArrayIns(array_to_mod, value_to_insert, index1 [, index2, index3...])\n\nInsert a value into an array or into its subarray.\n\nReturns a new array with value_to_insert inserted into array_to_mod (1D array) or \narray_to_mod[index1 (, index2, index3...)] (multi-dimensional array).\n\nThe indexes point to the insertion point. Index 0 will insert at the beginning of the array.\nIndex (ArraySize) will insert after the last element (same as ArrayAdd - append)\nOriginal array (as with the other functions) remains untouched.\n\nArrayAdd\n^^^^^^^^\n::\n\n    ArrayAdd(array_to_mod, value_to_append [, index1, index2, index3...])\n\nAppends value to the end of an array or its subarray.\n\nReturns a new array with value_to_append appended to array_to_mod (1D array) or array_to_mod[index1 (, index2, index3...)] (multi-dimensional array).\nOriginal array (as with the other functions) remains untouched.\n\nArrayDel\n^^^^^^^^\n::\n\n    ArrayDel(array_to_mod, index1 (, index2, index3...])\n\nReturns a new array in which the requested position was deleted.\nOriginal array (as with the other functions) remains untouched.\n\nArraySet\n^^^^^^^^\n::\n\n    ArraySet(array_to_mod, replacement_value, index1 [, index2, index3...])\n\nReturns a new array with array_to_mod[index1 (, index2, index3...)] = replacement_value\n\nOriginal array (as with the other functions) remains untouched.\n\nArrayGet\n^^^^^^^^\n::\n\n    ArrayGet(array, index1 [, index2, index3...])\n\nA function version of accessing an array element.\n\nDuring the script parsing the bracketed syntax is silenly converted to ``ArrayGet``.\n\n*Example*\n::\n\n    # these are the same\n    x = a[1]\n    x = ArrayGet(a, 1)\n    x = a.ArrayGet(1)\n    n = b[3, 2]\n    n = ArrayGet(b, 3, 2)\n    n = b.ArrayGet(3, 2)\n\nArraySize\n^^^^^^^^^\n::\n\n    int ArraySize(array_value)\n\nReturns the size of the parameter.\nFor getting the size of a subarray, pass the inner element.\n\nArraySort\n^^^^^^^^^\n::\n\n  ArraySort(array_to_sort)\n\nSorts an one dimensional array of bool, numeric or string values.\n\nReturns a new sorted array.\nDifferent basic types cannot be mixed inside the array, e.g. elements must be all bools, numbers or strings.\nInteger and floating point values can be mixed however.\n\nThe original array remains untouched.\n\n::\n\n    a = [\"banana\", \"apple\", \"lemon\", \"aardvark\"]\n    b = arraySort(a)\n    for (i=1, ArraySize(b)) {\n      SubTitle(Format(\"Element i={i} = {0} \", b[i-1] ), x=0, y=i*20)\n    }\n    # Element i=1 = aardvark\n    # Element i=2 = apple\n    # Element i=3 = banana\n    # Element i=4 = lemon\n\n::\n\n    a = [7, 3.1, 5.1, 4, 9.0, 7]\n    c = arraySort(a)\n    for (i=1, ArraySize(c)) {\n      SubTitle(Format(\"Element i={i} = {0} \", c[i-1] ), x=300, y=i*20)\n    }\n    # Element i=1 = 3.100000\n    # Element i=2 = 4\n    # Element i=3 = 5.100000\n    # Element i=4 = 7\n    # Element i=5 = 7\n    # Element i=6 = 9.000000\n\nGeneral examples\n----------------\n\n::\n\n      ColorbarsHD()\n      # array indexes are zero based\n      a = []\n      a=ArrayAdd(a,[1,2]) # [[1,2]]\n      a=ArrayIns(a,3,0) # [3,[1,2]]\n      a=ArrayAdd(a,\"s1\") # [3,[1,2],\"s1\"]\n      a=ArrayAdd(a,\"s2\") # [3,[1,2],\"s1\",\"s2\"]\n      a=ArrayDel(a,2) # [3,[1,2],\"s2\"]\n      a=ArraySet(a,\"g\",1,0) # [3,[\"g\",2],\"s2\"]\n      a=ArrayAdd(a,\"h\",1) # [3,[\"g\",2,\"h\"],\"s2\"]\n      a=ArrayAdd(a,[10,11,12],1) # append to (1) -> [3,[\"g\",2,\"h\",[10,11,12]],\"s2\"]\n      a=ArrayDel(a,1,3,0) # del from (1,3,0) -> [3,[\"g\",2,\"h\",[11,12]],\"s2\"]\n      a=ArrayAdd(a,\"added\") # [3,[\"g\",2,\"h\",[11,12]],\"s2\",\"added\"]\n      a=ArrayAdd(a,[\"yet\",\"another\",\"sub\"]) # [3,[\"g\",2,\"h\",[11,12]],\"s2\",\"added\",[\"yet\",\"another\",\"sub\"]]\n      x=a[0] #3\n      x=a[1,0] #g\n      x=a[1,2] #h\n      x=a[1,3,1] #12\n      x=a[3] #\"added\"\n      x=a[4,1] #\"another\"\n      SubTitle(\"x = \" + String(x) + \" Size=\" + String(a.ArraySize()))\n\n::\n\n      array_variable = [[1, 2, 3], [4, 5, 8], \"hello\"]\n      dictionary = [[\"one\", 1], [\"two\", 2]]\n      empty = []\n      subarray = array_variable[0]\n      val = subarray[2]\n      val2 = array_variable[1, 3]\n      str = array_variable[2]\n      n = ArraySize(array_variable) #3\n      n2 = ArraySize(empty) #0\n      val3 = dictionary[\"two\"]\n\n::\n\n      a = []\n      a=ArrayAdd(a,[1,2]) # [[1,2]]\n      a=ArrayIns(a,3,0) # [3,[1,2]]\n      a=ArrayAdd(a,\"s1\") # [3,[1,2],\"s1\"]\n      a=ArrayAdd(a,\"s2\") # [3,[1,2],\"s1\",\"s2\"]\n      a=ArrayDel(a,2) # [3,[1,2],\"s2\"]\n      \n      b = [\"hello\", \"leo\"]\n\n::\n\n      ColorBars()\n      clip=last\n      a = [[1,2],[3,4]]\n      aa = [1]\n      b = a[1,1] + ArrayGet(a, 1,0) + aa[0]\n      \n      empty_array = []\n      empty_array_2 = empty_array\n      #n3 = empty_array_2.ArrayGet(0) # array index out out range error!\n      \n      black_yuv_16 = [0,32768,32768]\n      grey_yuv_16 = [32768,32768,32768]\n      white_yuv_16 = [65535,32768,32768]\n      aSelectColors = [\\\n        [\"black\", black_yuv_16],\\\n        [\"grey\", grey_yuv_16],\\\n        [\"white\",white_yuv_16],\\\n        [\"empty\",empty_array]\\\n      ]\n      test_array = [99, 1.0, \"this is a string\"] # mixed types\n      test_array2 = [199, 2.0, \"This is a string\"]\n\n      n = ArraySize(test_array) # 3\n      n2 = ArraySize(empty_array_2) # 0\n      sum = FirstNSum(grey_yuv_16,2)\n      b = b\n      \n      clip = clip.Text(e\"Array size = \" + String(n) +\\\n       e\"\\n Empty array size = \" + String(n2) +\\\n       e\"\\n sum = \" + String(sum) +\\\n       e\"\\n b = \" + String(b) +\\\n       e\"\\n white_yuv_16[1]=\" + String(aSelectColors[\"white\"][1]) + \\\n       e\"\\n [0]=\" + String(ArrayGet(test_array,0)) + \\\n       e\"\\n [1]=\" + String(ArrayGet(test_array,1)) + \\\n       e\"\\n [2]=\" + ArrayGet(test_array,2), lsp=0, bold=true, font=\"info_h\")\n      \n      return clip\n      \n      function FirstNSum(array x, int n)\n      {\n        a = 0\n        for (i=0, x.ArraySize()-1) {\n          a = a + x[i]\n        }\n        return a\n      }\n\n\nArrays in user defined functions\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nAvisynth accepts arrays in the place of \"val\" script function parameter type regardless of being named or unnamed.\n(Note: \"val\" is translateed to \".\" in internal function signatures)\n\nExample:\n\n::\n\n      BlankClip(pixel_type=\"yv12\")\n      r([1, 2, 3])\n      r(n=[10,11,[12,13]])\n      r(\"hello\")\n      function r(clip c, val \"n\")\n      {\n        if (IsArray(n)) {\n         if (IsArray(n[2])) {\n           return Subtitle(c, String(n[2,1]), align=8) #13 at the top\n         } else {\n           return Subtitle(c, String(n[2]), align=2) #3 at the bottom\n         }\n        } else {\n          return Subtitle(c, String(n), align=5) #hello in the center\n        }\n      }\n\nSome facts which are inherited from the compatible Avisynth functionality.\n\n-  Array-typed parameters with \"name\" have the value \"Undefined\" when they are not passed.\n-  But the value is \"Defined\" and its value is a zero-sized array if the parameter is unnamed, like in other Avisynth functions.\n\n**\"Array of Anything\" issues**\n\nWhat about parameter handling for \"array of anything\" parameter when array(s) would be passed directly.\n\nAvisynth traditionally makes difference between zero-or-more and one-or-more kind of array parameters.\nThe special case is \"array of anything\"\n\n- Avisynth signature: .* or .+\n- Script function specifier val_array or val_array_nz (nz denotes to nonzero)\n\nWhen parameter signature is array of anything (.+ or .*) and the\nparameter is passed unnamed (even if it is a named parameter) then\nthere is an ambiguos situation.\n\nExample:\n\n    1,2,3 will be detected as [1,2,3] (compatibility: Avisynth collects arrays from comma separated function values, when such function signature is found)\n\n    1 will be detected as [1] (compatibility)\n\n    (nothing) will be detected as [], but marked in order to override it later directly by name\n\nConsequences:\n\n    Passing a direct script array [1,2,3] will be detected as [[1,2,3]], because unnamed and untyped parameters are\n    put together into an array, which has the size (number of elements) of the list. This is a list of 1 element which happens to be an array.\n    Avisynth cannot 'guess' whether we want to define a single array directly or this array is the only one part of the list.\n    [1,2,3] or [ [1,2,3] ]\n\nSyntax hint:\n\nWhen someone would like to pass a directly specified array (e.g. [1,2,3] instead of 1,2,3) to a .+ or .* parameter\nthe parameter must be passed by name! Or better: instead of \"array of anything\" use the val (function signature \".\") type.\nIt will acceopt any type, including arrays. Then you can check inside your function with IsArray() and ArraySize() if it is really an array.\n\nBecause of the existing AviSynth syntax rule: arguments given as unnamed in the place of an array-of-anything parameter\nare considered to be list elements from which Avisynth creates an array\n\n::\n\n      function foo(val_array \"n\")\n        Call                          n\n        foo()                   O.K.  Undefined\n        foo(1)                  O.K.  [1] (compatible Avisynth way)\n        foo(1,2,3)              O.K.  [1,2,3] (compatible Avisynth way)\n        foo([1,2,3])            !     [[1,2,3]] (compatible Avisynth way)\n        foo([1,2,3],[4,5])      !     [[1,2,3],[4,5]] (compatible Avisynth way)\n        foo(n=[1,2,3])          O.K.  [1,2,3]\n        foo(n=[[1,2,3],[4,5]])  O.K.  [[1,2,3],[4,5]]\n        foo(n=[])               O.K.  []\n        foo(n=\"hello\")          Syntax error, \"hello\" is not an array\n\n        // unnamed signature\n      function foo(val_array n)\n        Call                          n\n        foo()                   O.K.  [] (defined and array size is zero) Avisynth compatible behaviour\n\nScript functions supports avisynth function array \n- signature '+' (one or more) with _nz type suffix. E.g. int_array_nz\n- signature '*' (zero or more) without _nz type suffix. E.g. float_array\n\nE.g.: val_array -> .* val_array_nz -> .+, int_array -> i* int_array_nz -> i+\nEach basic type has its array and array_nz variant.\nSuch as bool_array_nz, float_array_nz, string_array_nz, clip_array_nz, func_array_nz.\n\nNote 1: There is an error message when a script array is passed to a non-array named function argument\n(e.g. foo(sigma=[1.1,1.1]) to [foo]f parameter signature\n\nNote 2: Type-free unnamed arrays \".+\" or \".*\" cannot be followed by additional parameters\n\nNote 3: A backward compatible way (AVS 2.6 and non-script-array AviSynth+ versions) of using named\nor unnamed arrays is to specify a single type as \".\" and the plugin would check the argument type by IsArray\n\nUser defined functions get array parameter types:\n\n- \"array\" or \"val_array\": array of any type.\n\n    When unnamed, then this kind of parameter must be the very last one.\n    Unnamed free-typed parametes cannot be followed by any other parameter.\n    Translates to \".*\" in a plugin parameter definition rule.\n\n-  \"bool_array\" \"int_array\", \"float_array\", \"string_array\", \"clip_array\", \"func_array\"\n\n    Translates to \"b*\", \"i*\", \"f*\", \"s*\", \"c*\", \"f*\" in a plugin parameter definition rule.\n\n-  \"bool_array_nz\" \"int_array_nz\", \"float_array_nz\", \"string_array_nz\", \"clip_array_nz\", \"func_array_nz\"\n\n    Translates to \"b+\", \"i+\", \"f+\", \"s+\", \"c+\", \"n+\" in a plugin parameter definition rule.\n\nExample:\n\n::\n\n    a = [1.0, 2.0, 4.2]\n    b = [3, 4, 5]\n    multi = [a,b]\n    \n    sum = Summa(multi[0], multi[1], 2)\n    SubTitle(Format({sum}))\n    \n    Function Summa(array \"x\", array \"y\", int \"N\")\n    {\n      sum = 0.0\n      FOR(i=0,N-1) {\n        sum = sum + x[i] * y[i]\n      }\n      return sum\n    }\n\nor\n\n::\n\n    Function Summa(float_array x, float_array y, int \"N\")\n    {\n      sum = 0.0\n      FOR(i=0,N-1) {\n        sum = sum + x[i] * y[i]\n      }\n      return sum\n    }\n\nArrays (pre AviSynth+: AVSLib)\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nBefore Avisynth+ 3.6 arrays were not supported natively by the\nscripting language.\n\nHowever, a library named [`AVSLib`_] exists that provides a functional\ninterface for creating and manipulating arrays. Coupled with Avisynth's OOP\nstyle for calling functions, one can treat arrays as objects with methods,\nwhich is a familiar and easy to understand and code scripting concept.\n\nTherefore, two preparatory steps are needed before being able to create and\nmanipulate process arrays into your script:\n\n-   [`Download`_] and install the most current version of AVSLib into\n    your system.\n-   Import the needed AVSLib files in your script as follows (see the\n    instructions inside the library's documentation to fill-in the gaps):\n-   AVSLib 1.1.x versions: Enter ``LoadPackage(\"avslib\", \"array\")`` to\n    load the array implementation files, or ``LoadLibrary(\"avslib\",\n    CONFIG_AVSLIB_FULL)`` to load entire AVSLib.\n-   AVSLib 1.0.x versions: Enter an appropriate :doc:`Import <../corefilters/import>` ({path to AVSLib\n    header}) statement as the first line of your script.\n\nNow you are ready to create your first array! In order to provide an almost\nreal case example let's assume the following (which are commonplace in many\nsituations) about the script you want to create:\n\n-   The script selects a distinct range of frames from each video clip.\n-   Some of the input clips may have different size, fps, audio and/or\n    colorspace; thus they need to be converted.\n-   Some of the filtering parameters are distinct for each clip.\n\nHaving done that, let's proceed to the actual code:\n\nFirst, we create the array; ..1.., ..2.., etc. are actual filename strings.\nClip loading is made by :doc:`AviSource <../corefilters/avisource>` in the example but\n:doc:`DirectShowSource <../corefilters/directshowsource>` may also be specified.\n\n::\n\n    inp = ArrayCreate( \\\n        AviSource(..1..), \\\n        AviSource(..2..), \\\n        ... \\\n        AviSource(..n..) )\n\nThen we convert to same fps, audio, colorspace and size by using\n:doc:`AssumeFPS <../corefilters/fps>`, :doc:`ConvertAudioTo16bit <../corefilters/convertaudio>`,\n:doc:`ConvertToYV12 <../corefilters/convert>` and :doc:`BilinearResize <../corefilters/resize>`\nrespectively (or any resizer that you find fit). We use OOP + chaining to\nmake compact expressions.\n\nNote that since Avisynth does not provide a way for in-place variable\nmodification we must reassign to an array variable after each array operation\n(usually the same).\n\n::\n\n    inp = inp.ArrayOpFunc(\"AssumeFPS\", \"24\").ArrayOpFunc(\"ConvertAudioTo16bit\" \\\n        ).ArrayOpFunc(\"ConvertToYV12\").ArrayOpFunc(\"BilinearResize\", \"640,480\")\n\nTo perform trimming we will use arrays of other types also. Below *ts* stands\nfor first frame to trim, *te* for last; each number corresponds to a clip in\n*inp* variable.\n\n::\n\n    ts = ArrayCreate(12, 24, ..., 33) # n numbers in total\n    te = ArrayCreate(8540, 7834, ..., 5712) # n numbers in total\n\nWe also need a counter to make things easier; we will use ArrayRange to\ncreate an array of 0,1,2,...\n\n::\n\n    cnt = ArrayRange(0, inp.ArrayLen()-1)\n\nIn addition we must define a user function that will accept *inp*, *ts*, *te*\nand *cnt* and do the trimming.\n\nSince ArrayOpArrayFunc only accepts two arrays for per-element processing, it\nis easier to pass 'inp' and *cnt* as array elements and *ts*, *te* as entire\narrays.\n\n::\n\n    Function MyTrim(clip c, int count, string fs, string fe) {\n        return c.Trim(fs.ArrayGet(count), fe.ArrayGet(count))\n    }\n\nNow we are ready to do the trim (line below).\n\n::\n\n    inp = ArrayOpArrayFunc(inp, cnt, \"MyTrim\", StrQuote(ts)+\",\"+StrQuote(te))\n\nWe will finish the processing with a final tweak on brightness with different\nsettings on each clip and on hue with same settings for all clips.\n\n::\n\n    bright = ArrayCreate(2.0, 1.5, ..., 3.1) # n numbers in total\n\n    Function MyTweak(clip c, float br) {\n        return c.Tweak(bright=br, hue=12.3)\n    }\n\n    inp = ArrayOpArrayFunc(inp, bright, \"MyTweak\")\n\nAnd now we are ready to combine the results and return them as script's\noutput. We will use `Dissolve`_ for a smoother transition.\n\n::\n\n    return inp.ArraySum(sum_func=\"Dissolve\", sum_args=\"5\")\n\nThis is it; the n input clips have been converted to a common video and audio\nformat, trimmed and tweaked with individual settings and returned as a single\nvideo stream with only 11 lines of code (excluding comments).\n\nOther types of array processing are also possible (slicing ie operation on a\nsubset of elements, joining, multiplexing, etc.) but these are topics to be\ndiscussed in other pages. Those that are interested can browse the `AVSLib`_\ndocumentation. One can also take a closer look at the `examples section`_\nof the AVSLib documentation.\n\n--------\n\nBack to :doc:`scripting reference <script_ref>`.\n\n$Date: 2025-02-25 17:26:15-05:00 $\n\n.. _AVSLib: http://avslib.sourceforge.net/\n.. _Download: http://sourceforge.net/projects/avslib/\n.. _Dissolve: http://avisynth.nl/index.php/Dissolve\n.. _examples section: http://avslib.sourceforge.net/examples/index.html\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/script_ref/script_ref_block_statements.rst",
    "content": "\nBlock statements\n================\n\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\n\nBackground\n----------\n\nNote:\nAvisynth+ has integrated the ``if..else``, ``for`` loop and ``while`` loop\ncontrol constructs from `GScript`_. This the following parts may be obsolate workarounds,\nnevertheless the methods can still be used.\n\nA first glance at Avisynth documentation leaves the impression that aside\nfrom function definitions, block statements are not possible in Avisynth\nscript. However, there are specific features of the language allowing the\nconstruction of block statements that have remained unaltered to date and\nprobably will remain so in the future since block statements are very useful\nin extending the capabilities of the script language.\n\nIndeed, in most programming and scripting languages, block statements are\nvery useful tools for grouping together a set of operations that should be\napplied together under certain conditions. They are also useful in Avisynth\nscripts.\n\nAssume, for example, that after an initial processing of your input video\nfile, you want to further process your input differently (for example, apply\na different series of :doc:`filters <../corefilters>` or apply the same set of filters with\ndifferent order) based on a certain condition calculated during the initial\nprocessing, which is coded at the value of Boolean variable *cond*.\n\nInstead of making an ugly series of successive conditional assignments using\nthe conditional (ternary) :doc:`operator <../syntax/syntax_operators>`, ``?:``,\nas in **Example 1** below (items in brackets are not needed if you use the\nimplicit *last* variable to hold the result):\n\n**Example 1**\n\n::\n\n    [result_1 = ]cond ? filter1_1 : filter2_1\n    [result_2 = ]cond ? filter1_2 : filter2_2\n    ...\n    [result_n = ]cond ? filter1_n : filter2_n\n\nIt would be nice to be able to construct two blocks of filter operations and\nbranch in a single step, as in the (ideal) **Example 2** below:\n\n**Example 2**\n\n::\n\n    [result = ] cond ? {\n        filter1_1\n        filter1_2\n        ...\n        filter1_n\n    } : {\n        filter2_1\n        filter2_2\n        ...\n        filter2_n\n    }\n\nSomething approaching this construction (and others) **is** possible; perhaps\nsome constraints may apply, but you will nevertheless be capable of providing\nmore powerful flow control to your scripts. The rest of this section will\nshow you how to implement them using standard Avisynth constructs.\n\n(An alternative, and possibly more user-friendly, approach would be to use\nthe external `GScript`_ plugin, which extends the Avisynth scripting language\nto provide multi-line conditionals (if-then-else blocks), 'while' loops and\n'for' loops. Note: Avisynth+ has built-in support for these.)\n\n\nFeatures enabling construction of block statements\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe list below briefly presents the features making possible the creation of\nblock statements in your script. Listed first are the more obvious ones,\nfollowed by those that are somewhat more esoteric and require a little\ndigging inside the Avisynth documentation and experimenting with test cases\nto discover them.\n\n-   globals (in particular, variables preceded by the \"global\" keyword)\n    allow the communication of information between code blocks executing in\n    different context.\n\n-   The conditional operator (condition ? expr_if_true : expr_if_false)\n    can contain an arbitrary number of nested expressions, if grouped by\n    parentheses.\n\n-   Strings can contain double quote (\") characters inside them if they\n    are surrounded by three-double-quotes (\"\"\").  Thus, the following strings\n    are valid in Avisynth script (note that the 2nd and 3rd ones could be\n    lines in a script):\n\n    -   \"\"\"this is a string with \" inside it\"\"\"\n    -   \"\"\"var = \"a string value\" \"\"\"\n    -   \"\"\"var = \"a string value\" # this is a comment\"\"\"\n\n-   There is a script function, :doc:`Eval <../syntax/syntax_internal_functions_control>`, that allows the evaluation of\n    strings containing arbitrary script expressions.  Thus, every expression\n    that you can write in a script can be, if stored in a string, passed to\n    Eval. Eval returns the result of the evaluated expression, ie *anything*\n    that can be constructed by such an expression (a clip, a number, a bool,\n    a string). The evaluation of the string is done in the same context as\n    the call to Eval. Thus, if Eval is called at the script level, the\n    expression is assumed to reference script-level variables or / and\n    globals (globals are allowed everywhere). But if Eval is called inside a\n    user-defined function then the expression is assumed to reference\n    variables local to the function (ie arguments and any locally declared\n    variable\n\n-   There is a script function, :doc:`Import <../corefilters/import>`, that allows the evaluation\n    of arbitrary Avisynth scripts.  Thus, any script written in Avisynth\n    script language can be evaluated by Import. Import returns the return\n    value of the script.\n\nDespite the common misbelief that this can only be a clip, it can actually be\n*any* type of variable (a clip, a number, a bool, a string).\n\nLike Eval, the evaluation of the script is done in the same context as the\ncall to Import.\n\nHence, as a side-effect of the script evaluation any functions and variables\ndeclared inside the imported script are accessible from the caller script,\nfrom the point of the Import call and afterwards.\n\n-   Recursion (ie calling a function from inside that function) can be\n    used for traversing elements of a collection.  Thus, for..next,\n    do..while, do..until loops can be constructed by using recursion.\n\n-   Multiline strings, ie strings that contain newlines (the CR/LF pair)\n    inside them, are allowed by the script language.\n\n-   Multiline strings are parsed by :doc:`Eval <../syntax/syntax_internal_functions_control>` as if they were scripts.\n    Thus, each line of a multiline string will be evaluated as if it was a\n    line in a script. Also, return statements inside the string are allowed\n    (the value of their expression will be the return value of Eval(), as\n    well as comments, function calls and in general every feature of the\n    script language.\n\nConsider the following **Example 3**, of a (useless) script that returns some\nblack frames followed by some white frames:\n\n**Example 3**\n\n::\n\n     c = BlankClip().Trim(0,23)\n     d = BlankClip(color=$ffffff).Trim(0,23)\n     b = true\n     dummy = b ? Eval(\"\"\"\n         k = c       # here comments are allowed!\n         l = d\n         return k    # this will be stored in dummy\n         \"\"\") : Eval(\"\"\"\n         k = d\n         l = c\n         return k    # this will be stored in dummy\n         \"\"\")\n     # variables declared inside a multiline string\n     # are available to the script after calling Eval\n     return k + l\n\nVariables *k*, *l* are not declared anywhere before the evaluation of the\nif..else block. However, since Eval evaluates the string at the script-level\ncontext, it is as if the statements inside the string were written at the\nscript level. Therefore, after Eval() they are available to the script. A few\nother interesting things to note are the following:\n\n-   The return statement at the end of the selected (by the value of *b*)\n    string for evaluation is the value that will be returned to the *dummy*\n    variable.\n\n-   Contrary to the case of line continuation by backslashes, a multiline\n    string allows comments everywhere that they would be allowed in a script.\n\n\nImplementation Guide\n--------------------\n\nThe features above can be used to construct block statements in various ways.\nThe most common implementation cases are presented in this section, grouped\nby block statement type.\n\n\nThe if..else block statement\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n(Note: Avisynth+ has built-in support for if..else)\n\nUsing Eval() and three-double-quotes quoted strings\n:::::::::::::::::::::::::::::::::::::::::::::::::::\n\nThis is by far the more flexible implementation, since the flow of text\napproaches most the \"natural\" (ie the commonly used in other languages) way\nof branching code execution.\n\nUsing the rather common case illustrated by **Example 1**, the solution would\nbe (again items in square brackets are optional):\n\n**Example 4**\n\n::\n\n    [result = ] cond ? Eval(\"\"\"\n        filter1_1\n        filter1_2\n        ...\n        filter1_n\n      [ return {result of last filter} ]\n        \"\"\") : Eval(\"\"\"\n        filter2_1\n        filter2_2\n        ...\n        filter2_n\n      [ return {result of last filter} ]\n       \"\"\")\n\nIn short, you write the code blocks as if Avisynth script would support block\nstatements and then enclose the blocks in three-double-quotes to make them\nmultiline strings, wrap a call to :doc:`Eval <../syntax/syntax_internal_functions_control>` around each string and finally\nassemble Eval calls into a conditional operator statement.\n\nThe return statements at the end of each block are needed only if you want to\nassign a useful value to the *result* variable. If you simply want to execute\nthe statements without returning a result, then you can omit the *return*\nstatement at the end of each block.\n\nOne important thing to note is that the implicit setting of *last* continues\nto work as normal inside the Eval block. If the result of Eval is assigned to\na variable, *last* will not be updated for the final expression in the block\n(with or without *return*), but it will be (where appropriate) for other\nstatements in the block.\n\nIf the block statement produces a result you intend to use, it is clearer to\nenter a *return {result}* line as the last line of each block, but the\nkeyword *return* is not strictly necessary.\n\nThe following real-case examples illustrate the above:\n\n**Example 5** In this example, all results are assigned to script variables,\nso *last* is unchanged.\n\n::\n\n    c = AviSource(...)\n    ...\n    cond = {expr}\n    ...\n    cond ? Eval(\"\"\"\n        text = \"single double quotes are allowed inside three-double-\n        quotes\"\n        pos = FindStr(text, \"llo\")   # comments also\n        d = c.Subtitle(LeftStr(text, pos - 1))\n    \"\"\") : Eval(\"\"\"\n        text = \"thus by using three-double-quotes you can write\n        expressions like you do in a script\"\n        pos = FindStr(text, \"tes\")\n        d = c.SubTitle(MidStr(text, pos + StrLen(\"tes\")))\n    \"\"\")\n    return d\n\n**Example 6** This example assigns a different clip to d depending on the\n:doc:`Framecount <../syntax/syntax_clip_properties>` of a source clip.\n\n::\n\n    a = AviSource(...)\n    c = BlankClip().Subtitle(\"a test case for an if..else block\n    statement\")\n    d = a.Framecount >= c.Framecount ? Eval_(\"\"\"\n        a = a.BilinearResize(c.Width, c.Height)\n        c = c.Tweak(hue=120)\n        return Overlay(a, c, opacity=0.5)\n    \"\"\") : Eval(\"\"\"\n        c = c.BilinearResize(a.Width, a.Height)\n        a = a.Tweak(hue=120)\n        return Overlay(c, a, opacity=0.5)\n    \"\"\")\n    return d\n\n**Example 7** This example is a recode of Example 6 using implicit assignment\nto the *last* special variable. Since the result of the entire Eval() is not\nassigned to another variable, the implicit assignments to *last* on each line\nof the string (including the *last line* of the string) are preserved and\nthus the desired result is obtained.\n\n::\n\n    c = BlankClip().SubTitle(\"a test case for an if..else block statement\")\n    AviSource(...)\n    last.Framecount >= c.Framecount ? Eval(\"\"\"\n        BilinearResize(c.Width, c.Height)\n        c = c.Tweak(hue=120)\n        Overlay(last, c, opacity=0.5)\n    \"\"\") : Eval(\"\"\"\n        c = c.BilinearResize(last.Width, last.Height)\n        Tweak(hue=120)\n        Overlay(c, last, opacity=0.5)\n    \"\"\")\n\nThe only disadvantage of the Eval approach is that coding errors inside the\nstring blocks are masked by the :doc:`Eval <../syntax/syntax_internal_functions_control>` call, since the parser actually\nparses a **single line** of code:\n\n::\n\n    [result = ] cond ? Eval(\"\"\"block 1\"\"\") : Eval(\"\"\"block 2\"\"\")\n\nThus, any error(s) inside the blocks will be reported as a single error\nhappening on the above line. You will not be pointed to the exact line of\nerror as in normal script flow. Therefore, you will have to figure out where\nexactly the error occured, which can be a great debugging pain, especially if\nyou write big blocks.\n\n\nUsing separate scripts as blocks and the Import() function\n::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\n\nUsing **Example 1** as above, the solution would be (again items in square\nbrackets are optional):\n\n**Example 8** Code of script file *block1.avs*:\n\n::\n\n    filter1_1\n    filter1_2\n    ...\n    filter1_n\n\nCode of script file *block2.avs*:\n\n::\n\n    filter2_1\n    filter2_2\n    ...\n    filter2_n\n\nCode of main script where the conditional branch is desired:\n\n::\n\n    ...\n    [result = ]cond ? Import(\"block1.avs\") : Import(\"block2.avs\")\n    ...\n\nIn short, you create separate scripts for each block and then conditionally\nimport them at the main script.\n\nIf you need to pass :doc:`variables <../syntax/syntax_script_variables>` as \"parameters\" to the blocks, declare them\nin your main script and just reference them into the block scripts. The\nfollowing example demonstrates this:\n\n**Example 9** Code of script file *block1.avs*:\n\n::\n\n    filter1_1(..., param1, ...)\n    filter1_2(..., param2, ...)\n    ...\n    filter1_n(..., param3, ...)\n\nCode of script file *block2.avs*:\n\n::\n\n    filter2_1(..., param1, ...)\n    filter2_2(..., param2, ...)\n    ...\n    filter2_n(..., param3, ...)\n\nCode of main script where the conditional branch is desired:\n\n::\n\n    # variables must be defined *before* importing the block script\n    param1 = ...\n    param2 = ...\n    param3 = ...\n    ...\n    [result = ]cond ? Import(\"block1.avs\") : Import(\"block2.avs\")\n    ...\n\nUsing :doc:`Import <../corefilters/import>` instead of :doc:`Eval <../syntax/syntax_internal_functions_control>` and three-double-quoted multiline\nstrings has some disadvantages:\n\n-   There is an administration overhead because instead of one file *2k +\n    1* files have to be maintained (*k* = the number of conditional branches\n    in your script).\n-   The code has less clarity, in the sense that it does not visually\n    appears as a block statement, neither the communication of parameters is\n    apparent by inspection of the main script.\n\nOn the other hand:\n\n-   Debugging is not an issue; every error will be reported with accurate\n    line information.\n-   You can reuse scripts that you frequently use and build more complex\n    ones by simply importing ready-made components.\n-   For large-scale operations where few parameters have to be\n    communicated it is usually a better approach.\n\nOne useful general purpose application of this implementation is to\nprototype, test and debug a block conditional branch and then recode it (by\nadding the Eval() and three-double-quotes wrapper code and removing the\n:doc:`global <../syntax/syntax_script_variables>` keyword before the parameter's declarations) so that a single\nscript using multiline strings as blocks is created. This workaround\ncompensates for the main disadvantage of the Eval() and three-double-quotes\nimplementation.\n\n\nUsing functions (one function for each block)\n:::::::::::::::::::::::::::::::::::::::::::::\n\nThis is the most \"loyal\" to the Avisynth script's :doc:`syntax <../syntax/syntax_ref>` approach. Using\n**Example 1** as above, the solution would be (again items in square brackets\nare optional):\n\n**Example 10**\n\n::\n\n    Function block_if_1()\n    {\n        filter1_1\n        filter1_2\n        ...\n        filter1_n\n    }\n\n    Function block_else_1()\n    {\n        filter2_1\n        filter2_2\n        ...\n        filter2_n\n    }\n    ...\n    [result = ]cond ? block_if_1() : block_else_1()\n    ...\n\nIn short, you create separate functions for each block and then conditionally\ncall them at the branch point.\n\nIf you need to pass variables as \"parameters\" to the blocks, either declare\nthem *global* in your main script and just reference them into the functions\nor - better - use argument lists at the functions. The following example\ndemonstrates this:\n\n**Example 11**\n\n::\n\n    Function block_if_1(arg1, arg2, arg3, ...)\n    {\n        filter1_1(..., arg1, ...)\n        filter1_2(..., arg2, ...)\n        ...\n        filter1_n(..., arg3, ...)\n    }\n\n    Function block_else_1(arg1, arg2, arg3, ...)\n    {\n        filter2_1(..., arg1, ...)\n        filter2_2(..., arg2, ...)\n        ...\n        filter2_n(..., arg3, ...)\n    }\n    ...\n    [result = ]cond \\\n        ? block_if_1(arg1, arg2, arg3, ...) \\\n        : block_else_1(arg1, arg2, arg3, ...)\n    ...\n\nCompared to the other two implementations this one has the following\ndisadvantages:\n\n-   There is an extra overhead due to the need for supplying function\n    headers and (typically) argument lists.\n-   It tends to \"pollute\" the global namespace, thus having the potential\n    of strange errors due to name conflicts; use a clear naming scheme, as\n    the suggested above.\n\nOn the other hand:\n\n-   It is **portable**; it does not depend on any type of hack or\n    specific behavior to work. It is thus guaranteed to continue working in\n    the long term.\n-   It does not raise any special debuging difficulties.\n-   It has coding clarity.\n\n\nThe if..elif..else block statement\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n(Note: Avisynth+ has built-in support for if..else if..else)\n\nBy nesting If..Else block expressions inside the conditional operator, you\ncan create entire if..elseif...else conditional constructs of any level\ndesired to accomodate more complex needs.\n\nA generic example for each if..else implementation presented above is\nfollowing. Of course, any combination of the three above pure cases is\npossible.\n\n\nUsing Eval() and three-double-quotes quoted strings\n:::::::::::::::::::::::::::::::::::::::::::::::::::\n\nThe solution would be (again items in square brackets are optional):\n\n**Example 12**\n\n::\n\n    [result = \\]\n        cond_1 ? Eval(\"\"\"\n            statement 1_1\n            ...\n            statement 1_n\n        \"\"\") : [(] \\\n        cond_2 ? Eval(\"\"\" # inner a?b:c enclosed in parentheses for\n        clarity (optional)\n            statement 2_1\n            ...           # since backslash line continuation is\n            used between Eval blocks\n            statement 2_n # place comments only inside the\n            strings\n        \"\"\") : [(] \\\n        ...\n        cond_n ? Eval(\"\"\"\n            statement n_1\n            ...\n            statement n_n\n        \"\"\") \\\n        : Eval(\"\"\"\n            statement n+1_1\n            ...\n            statement n+1_n\n        \"\"\")[...))]  # 1 closing parenthesis for Eval() + n-1 to\n        balance the opening ones (if used)\n\nUsing separate scripts as blocks and the Import() function\n::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\n\nThe solution would be (again items in square brackets are optional):\n\n**Example 13**\n\n::\n\n    # here no comments are allowed; every line but the last must end with a \\\n    [result = \\]\n        cond_1 ? \\\n            Import(\"block1.avs\") : [(] \\\n        cond_2 ? \\\n            Import(\"block2.avs\") : [(] \\\n        ...\n        cond_n ? \\\n            Import(\"blockn.avs\") \\\n        : \\\n            Import(\"block-else.avs\") \\\n        )...))  # n-1 closing parentheses to balance the opening ones\n\nUsing functions (one function for each block)\n:::::::::::::::::::::::::::::::::::::::::::::\n\nThe solution would be (again items in square brackets are optional):\n\n**Example 14**\n\n::\n\n    # here no comments are allowed; every line but the last must end with a \\\n    [result = \\]\n        cond_1 ? \\\n            function_block_1({arguments}) : [(] \\\n        cond_2 ? \\\n            function_block_2({arguments}) : [(] \\\n        ...\n        cond_n ? \\\n            function_block_n({arguments}) \\\n        : \\\n            function_block_else({arguments}) \\\n        [)...))]  # n-1 closing parentheses to balance the opening\n        ones (if used)\n\nThe for..next block statement\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n(Note: Avisynth+ has built-in support for ``for`` loops)\n\nThe problem here is to implement the ``for..next`` loop in a way that allows\naccessing variables in the local scope, so that changes made in local scope\nvariables inside the loop can be accessible by the caller when it is\nfinished. This is the way that the ``for..next`` loop works in most\nprogramming languages that provide it. In addition, a means for getting out\nof the loop before is finished (ie breaking out of the loop) should be\navailable.\n\nThere is of course the alternative to implement the ``for..next`` loop in a\nway that does not allow access to local variables. This is easier in\nAviSynth, since then it can be implemented by a function; but it is also less\nuseful. However in many cases it would be appropriate to use suc a construct\nand thus it will be presented here.\n\n\nFor..Next loop with access to variables in local scope\n::::::::::::::::::::::::::::::::::::::::::::::::::::::\n\n1.  Use a ``ForNext(start, end, step, blocktext)`` function to create a\n    multiline string (a script) that will unroll the loop in a series of\n    statements and then\n2.  use Eval() to execute the script in the current scope.\n\nThe ``blocktext`` is a script text, typically a multiline string in triple\ndouble quotes, that contains the instructions to be executed in each loop,\nalong with special variables (say ${i} for the loop counter) that are\ntextually replaced by the ``ForNext`` function with the current value(s) in\neach loop. The `StrReplace()`_ function is particularly suited for the\nreplacement task.\n\nA little tweak is needed in order to implement the ``break`` statement; the\nunrolled string must be constructed in such a way that when the break flag is\nset the rest of the code is skipped.\n\nThe following proof-of-concept example demonstrates the procedure:\n\n::\n\n    a = AviSource(\"c:\\some.avi\")\n    cnt = 12\n    b = a.Trim(0,-4)\n    cond = false\n\n    # here we would like to do the following\n    # for (i = 0; i < 6; i++) {\n    #    b = b + a.Trim(i*cnt, -4)\n    #    cond = b.Framecount() > 20 ? true : false\n    #    if (cond)\n    #        break\n    # }\n\n    return b\n\nIn order to make this happen in AviSynth, our script with ``ForNext`` would\nlook like that:\n\n::\n\n    a = AviSource(\"c:\\some.avi\")\n    cnt = 12\n    b = a.Trim(0,-4)\n    cond = false\n    block = ForNext(0, 5, 1, \"\"\"\n        b = b + a.Trim(${i}*cnt, -4)\n        cond = b.Framecount() > 20 ? true : false\n        ${break(cond)}\n        \"\"\")\n    void = Eval_(block)\n    return b\n\nor more succinctly:\n\n::\n\n    a = AviSource(\"c:\\some.avi\")\n    cnt = 12\n    b = a.Trim(0,-4)\n    void = Eval(ForNext(0, 5, 1, \"\"\"\n        b = b + a.Trim(${i}*cnt, -4)\n        cond = b.Framecount() > 20 ? true : false\n        ${break(cond)}\n        \"\"\"))\n    return b\n\nand the output of ForNext with the above arguments should be something like\nthis (the only problem is that string literals cannot be typed inside the\nblock text):\n\n::\n\n    \"\"\"\n    __break = false\n    dummy = __break ? NOP : Eval(\"\n        b = b + a.Trim(0*cnt, -4)\n        cond = b.Framecount() > 20 ? true : false\n        __break = cond ? true : false\n    \")\n    dummy = __break ? NOP : Eval(\"\n        b = b + a.Trim(1*cnt, -4)\n        cond = b.Framecount() > 20 ? true : false\n        __break = cond ? true : false\n    \")\n    dummy = __break ? NOP : Eval(\"\n        b = b + a.Trim(2*cnt, -4)\n        cond = b.Framecount() > 20 ? true : false\n        __break = cond ? true : false\n    \")\n    dummy = __break ? NOP : Eval(\"\n        b = b + a.Trim(3*cnt, -4)\n        cond = b.Framecount() > 20 ? true : false\n        __break = cond ? true : false\n    \")\n    dummy = __break ? NOP : Eval(\"\n        b = b + a.Trim(4*cnt, -4)\n        cond = b.Framecount() > 20 ? true : false\n        __break = cond ? true : false\n    \")\n    dummy = __break ? NOP : Eval(\"\n        b = b + a.Trim(5*cnt, -4)\n        cond = b.Framecount() > 20 ? true : false\n        __break = cond ? true : false\n    \")\n    \"\"\"\n\nTO BE CONTINUED...\n\n\nFor..Next loop without access to variables in local scope\n:::::::::::::::::::::::::::::::::::::::::::::::::::::::::\n\nIf we don't care for accessing variables in the local scope, then the\nimplementation is straightforward:\n\n1.  Create an :doc:`AVSLib array <script_ref_arrays>` with the appropriate loop values.\n2.  Define needed globals (for example a bool flag to return immediately\n    from the block if true).\n3.  Pack the block's code inside a function.\n4.  Use an `array operator`_ to execute the block for every loop value.\n\nTO BE CONTINUED...\n\n\nThe do..while and do..until block statements\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n(Note: Avisynth+ has built-in support for ``while`` loops)\n\nTODO...\n\n\nDeciding which implementation to use\n------------------------------------\n\nTo be frank, there is no clear-cut answer to this question; it depends on the\npurpose that the script will serve, your coding abilities and habits, whether\nthere are ready-made components available and what type are they (scripts,\nfunction libraries, etc.) and similar factors.\n\nThus, only some generic guidelines will be presented here, grouped on the\ntype of block statement\n\n\nThe if..else and if..elif..else block statements\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n-   For short (up to say 10 lines) blocks, using Eval() and three-double-\n    quotes quoted strings is generally the best solution; it is fast to code\n    and presents a \"natural\" text flow to the reader (thus it is easy to\n    comprehend).\n\n-   For long blocks, using any of the other two implementations is\n    generally better because it is easier to debug.\n\n-   If the blocks pre-exist as independent scripts, using :doc:`Import <../corefilters/import>` is,\n    obviously, preferred.\n\n-   If building a function library, usually an implementation with\n    functions will be easier to maintain and debug. However using :doc:`Eval <../syntax/syntax_internal_functions_control>`\n    for small blocks is still an option to consider, to minimise the risk of\n    namespace clashing with user's own functions.\n\n\nThe for..next block statement\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nTODO...\n\n\nThe do..while and do..until block statements\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nTODO...\n\n\nReferences\n----------\n\n[1] `<http://avisynth.nl/users/stickboy/ternary_eval.html>`_\n\n[2] `<http://forum.doom9.org/showthread.php?t=102929>`_\n\n[3] `<http://forum.doom9.org/showthread.php?p=732882#post732882>`_\n\n--------\n\nBack to :doc:`scripting reference <script_ref>`.\n\n$Date: 2025-02-25 17:28:13-05:00 $\n\n.. _GScript: http://forum.doom9.org/showthread.php?t=147846\n.. _StrReplace():\n    http://avslib.sourceforge.net/functions/s/strreplace.html\n.. _array operator:\n    http://avslib.sourceforge.net/tutorials/operators.html\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/script_ref/script_ref_execution_model.rst",
    "content": "\nThe script execution model\n==========================\n\nThis section is a walkthrough to the internals of the AviSynth script engine.\nIts aim is to provide a better understanding of how AviSynth transforms\nscript commands to actual video frames and help a user that has already\ngrasped the basics of AviSynth scripting to start writing better and\noptimised scripts.\n\nThe following subsections present the various parts that when combined\ntogether form what can be called the AviSynth's \"script execution model\":\n\n-   :doc:`Sequence of events <script_ref_execution_model_sequence_events>`\n\nA detailed description of the sequence of events that occur when you execute\n(ie load and render to your favorite encoder) an AviSynth script.\n\n-   :doc:`The (implicit) filter graph <script_ref_execution_model_filter_graph>`\n\nA glance at the basic internal data structure that holds the representation\nof a parsed AviSynth script.\n\n-   :doc:`The fetching of frames (from bottom to top) <script_ref_execution_model_fetching_frames>`\n\nHow the AviSynth engine requests frames from filters.\n\n-   :doc:`Scope and lifetime of variables <script_ref_execution_model_lifetime_variables>`\n\nThe interplay of variables' scope and lifetime with the other features of\nAviSynth :doc:`syntax <../syntax/syntax_ref>`.\n\n-   :doc:`Evaluation of runtime scripts <script_ref_execution_model_eval_scripts>`\n\nThe details of runtime scripts' evaluation.\n\n-   :doc:`Performance considerations <script_ref_execution_model_perf_cons>`\n\nVarious performance-related issues and advice on how to optimise your\nAviSynth scripts and configuration.\n\n--------\n\nBack to :doc:`scripting reference <script_ref>`.\n\n$Date: 2008/04/20 19:07:33 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/script_ref/script_ref_execution_model_eval_scripts.rst",
    "content": "\nThe script execution model - Evaluation of runtime scripts\n==========================================================\n\nEvaluation of runtime scripts starts, as already stated, at the frame serving\nphase of the main script's execution. At that point frames of the final\noutput clip are requested by the host video application. This triggers a\nsequence of successive calls to the GetFrame / GetAudio methods of all\nfilters along the filter graph. Whenever one of those filters is a runtime\nfilter, the following three-phase sequence of events happens *in every\nframe*:\n\n-   Runtime environment initialisation.\n-   Runtime script parsing and evaluation.\n-   Runtime environment cleanup and delivery of the resulting frame.\n\nThe following paragraphs examine each phase in more detail.\n\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\n\nRuntime environment initialisation\n----------------------------------\n\nThe runtime filter code sets (at the top-level script local scope) its\n:doc:`special variables <../syntax/syntax_runtime_environment>` for the runtime script. These at the minimum include\n``last``, which is set to the filter's source clip and ``current_frame``,\nwhich is set to the frame number requested by the filter from the AviSynth\ncode.\n\nAs a consequence, those special variables *cannot* be passed between runtime\nscripts; whatever value the passing script will set, it will be overwritten\nby the receiving filter's frame initialisation code.\n\n\nRuntime script parsing and evaluation\n-------------------------------------\n\nThe runtime script is parsed, as a regular script would be parsed if loaded\nin AviSynth. The parsing mechanism is the same. Thus *everything* allowed to\na regular script is allowed to a runtime script; *what changes is the context\nof execution*. For example, you can:\n\n-   Use **multi-line scripts**; they just have to be contained inside a\n    three-double-quotes pair (this is a requirement only if string literals\n    are used inside the script, else single double quotes can be used also).\n-   Define / assign variables, both local and global.\n-   :doc:`Import <../corefilters/import>` other scripts and/or load plugins and/or define functions.\n-   Call functions and filters.\n-   Use :doc:`arrays <script_ref_arrays>` and :doc:`block statements <script_ref_block_statements>`.\n-   Use :doc:`control structures <../syntax/syntax_control_structures>`.\n\nOf course, some of the above are **not advisable**, because the different\nexecution context poses different constrains regarding performance and\nresource usage. The main rule of thumb here is: **Parsing occurs in every\nframe requested. Therefore, computationally expensive actions should be\navoided**. More on the :doc:`performance considerations <script_ref_execution_model>` section.\n\n\nRuntime environment cleanup and delivery of the resulting frame\n---------------------------------------------------------------\n\nThe runtime filter code receives the result of script parsing and evaluation.\nIf all went well, the result will be a valid filter graph (the runtime filter\ngraph) from which the runtime filter requests to fetch the needed frame. If\nnot, the filter will propagate the error to the caller. When the filter's\ncode will return the final video frame, the runtime filter graph will be\ndestroyed. As part of the cleanup the runtime filter code also restores the\n``last`` special variable to its previous value.\n\n\nThe runtime environment in detail\n---------------------------------\n\nDespite the very thin layer of added features (just a handful of variables\nand functions) the runtime environment is much more dynamic that the normal\n(main) script environment. The *key-difference* is the event-driven model of\nruntime script execution as opposed to the linear flow of the main script's\nexecution. Execution of a runtime script occurs only in the event of a frame\nrequest. In addition, since intermediate filters in the chain may shuffle and\ncombine frames in an arbitrary fashion, the requested frame's number may be\ndifferent than the final clip's frame number.\n\n\nElements of the runtime environment\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nAt any time during the frame serving phase, the elements of the runtime\nenvironment are the following:\n\n-   The environment inherited by the main script's parsing phase, that is\n    the main script's top-level local variables, the global variables and all\n    imported script and plugin functions.\n-   The :doc:`special variables <../syntax/syntax_runtime_environment>` set on every frame by the runtime filter\n    initialisation code (``last``, ``current_frame``, etc.)\n-   A set of :doc:`runtime functions <../syntax/syntax_internal_functions_runtime>` to assist common information extraction\n    operations.\n-   The environment created by the successive evaluation of runtime\n    scripts triggered by all the final output clip's frames that have been\n    requested so far by the host video application. This may include\n    modifications to the environment inherited by the parsing phase such as\n    change of variables' values, as well as addition of new locals and\n    globals.\n\n\nRuntime functions and current_frame\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nAn interesting feature of :doc:`runtime functions <../syntax/syntax_internal_functions_runtime>` is that they consult the value\nof the ``current_frame`` special variable in order to determine what frame of\ntheir input clip(s) to inspect for extracting information. This provides the\nability inside a runtime script to easily request information for *any* frame\nof a clip by changing before the call to the function the ``current_frame``\nvariable.\n\nAs explained above, setting the ``current_frame`` variable has no effect on\nother runtime scripts in the filter chain because the runtime filters'\ninitialisation code resets ``current_frame`` to the proper value before\nexecuting the runtime script. It also has no effect on subsequent filter\ncalls in the runtime script. But it does have on runtime functions and\nanywhere the value of ``current_frame`` is used. Therefore, after such a\nusage it is good practice to restore the variable to its initial value before\nissuing other script commands.\n\nA skeleton example of a runtime script that computes a weighted second order\nluma interpolation value (the actions after the computation are omitted)\nfollows:\n\n::\n\n    ...previous processing omitted...\n    ScriptClip(\"\"\"  # this is a multiline string\n        n = current_frame\n        lm_k = AverageLuma()\n        current_frame = n - 1\n        lm_km1 = AverageLuma()\n        current_frame = n + 1\n        lm_kp1 = AverageLuma()\n        dvg = (lm_km1 - 2 * lm_k + lm_kp1) / 2\n        lm_ipl = lm_k + Sign(dvg) * Sqrt(Abs(dvg))\n        current_frame = n # remember to reset current_frame\n        ...rest of script omitted...\n        \"\"\")\n    ...subsequent processing omitted...\n\nChecklist for developing correct runtime scripts\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nDespite the dynamic nature of the runtime environment, creating runtime\nscripts is relatively easy if you follow a simple set of rules:\n\n-   Remember that your input (source) clip is stored upon start of script\n    execution in the ``last`` special variable.\n-   If you assign temporary clips to variables, remember to set ``last``\n    at the end or issue a ``return`` statement.\n-   Do not change (with respect to the source clip of the filter) the\n    dimensions, colorspace or framerate of the final result.\n-   Do not assume - unless there is a **very** compelling performance-\n    related reason- a particular ordering of frame requests; try to build\n    ordering-neutral scripts, that depend only on ``current_frame``.\n-   Inspect the names of all input variables (ie those variables that are\n    *not initialised* to a value inside the runtime script) of your runtime\n    scripts to ensure that they are not overridden accidentally by a normal,\n    not used for inter-script communication variable in any runtime script\n    along the chain.\n-   In particular, avoid putting inside :doc:`functions <../syntax/syntax_userdefined_scriptfunctions>` calls to runtime\n    filters that share state between invocations or with other filters\n    through variables; it is easy to forget that *you may only call the\n    function once*, else you will end up with multiple filters that share\n    *the same* variables, thus with a bug in your script.\n\nIn view of the above, runtime filters should be used in functions only if\nthey either:\n\n-   do not share state between invocations or with other filters through\n    variables, or\n-   the function code takes care to create *unique names* of all the\n    runtime script's shared variables on each function invocation.\n\nA way to avoid variables is to dynamically build the runtime script using\nstring concatenation and assign the related arguments' values to local\nvariables in the runtime script. See the example code of the :doc:`bracket_luma <script_ref_execution_model_lifetime_variables>`\nfunction.\n\n--------\n\nBack to the :doc:`script execution model <script_ref_execution_model>`.\n\n$Date: 2011/04/29 20:11:14 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/script_ref/script_ref_execution_model_fetching_frames.rst",
    "content": "\nThe script execution model - The fetching of frames\n===================================================\n\nDespite that the script writer writes the script from top to bottom, AviSynth\nrequests frames from the filters included in the script in the reverse order\n(**from bottom to top**). This is a consequence of the fact that AviSynth\nfakes the existence of an AVI file to the host video application through its\nAVI handler code.\n\nThe host video application does not know that AviSynth is behind the scenes;\nit just requests a finished and ready to render video frame, that is the\nfinal result of the script's processing from the AVI handler. The AVI handler\nin turn requests the frame from the root of the filter graph, ie from the\nfinal clip returned by the script.\n\nIn order to create the frame the final clip requests video frame(s) from its\ninput clip(s). This process continues until a source filter, such as\n:doc:`AviSource <../corefilters/avisource>`, is reached which directly produces a video frame without\nrequesting input from other filters. Therefore, the request process traverses\nthe filter chain from bottom to top. That frame is then subsequently\nprocessed by all filters in the request chain (now from top to bottom, as in\nthe script source code), resulting in the finished video frame that is served\nto the host video application.\n\nThis backward searching implementation has been chosen for effectiveness\nreasons and it doesn't need to bother you except for one important case: when\nyou use runtime filters (cf. next sections).\n\n--------\n\nBack to the :doc:`script execution model <script_ref_execution_model>`.\n\n$Date: 2008/04/20 19:07:33 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/script_ref/script_ref_execution_model_filter_graph.rst",
    "content": "\nThe script execution model - The filter graph\n=============================================\n\nThe final purpose of every AviSynth script is to create a filter graph that\ncan be used by the top-level AVI stream object (see previous section) to call\nthe filters needed for the creation of each specific frame that is requested\nby the host video application.\n\nThis filter graph is **implicit** in the sense that it is not directly\navailable to script writers for querying or modification. However it is\ncreated and built-up on each filter call that the script source code makes,\nusing the following rules:\n\n-   Each filter -actually its resulting clip- links to *all* its source\n    clips (those that it uses directly or indirectly for input).\n-   Source filters (such as :doc:`AviSource <../corefilters/avisource>`) do not link to other clips.\n    Their resulting clip is a leaf-node in the filter graph.\n-   Only filters -ie their resulting clips- that are linked by the final\n    clip returned by the script are part of the filter graph. That is a clip\n    is part of the filter graph only if there is a path that connects it with\n    the final clip returned by the script.\n\nIn Avisynth+ you can use two debug filters, with which the filter graph\ncan be visualized. See :ref:`filter graph helpers <syntax_debug_filtergraph>`.\n\n\nAn example of a filter graph\n----------------------------\n\nConsider the following script, which loads a clip, makes a simple levels\nprocessing and muxes it with a custom sound track; then it overlays on top of\nit another clip, along with its inverted image, as separate windows.\n\n::\n\n    AviSource(\"clip1.avi\")\n    Levels(10, 1, 248, 0, 255)\n    aud = WavSource(\"mysoundtrack.wav\")\n    AudioDub(last, aud)\n    ov = AviSource(\"clip2.avi\")\n    ov1 = Lanczos4Resize(ov, 280, 210)\n    ov2 = ov1.Invert()\n    w = last.Width\n    h = last.Height\n    Overlay(ov1, x=w-280-40, y=40) # first clip is last\n    Overlay(ov2, x=w-280-40, y=h-210-40)\n\nThe filter graph that results from the script code above is the following.\n\n::\n\n    AviSource(clip1) <-- Levels <--+\n                                   |\n    WavSource <--------------------+-- AudioDub <--+\n                         |\n    AviSource(clip2) <-- Lanczos4Resize <--+-------+-- Overlay <--+\n         |                      |\n         +-- Invert\n                                           <-----------+-- Overlay (filter graph's root)\n\nThe root of the filter graph, that is the filter from which the host video\napplication requests video frames is the second :doc:`Overlay <../corefilters/overlay>` (the last line of\nthe script).\n\n--------\n\nBack to the :doc:`script execution model <script_ref_execution_model>`.\n\n$Date: 2010/11/28 18:47:26 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/script_ref/script_ref_execution_model_lifetime_variables.rst",
    "content": "\nThe script execution model - Scope and lifetime of variables\n============================================================\n\nThere are essentially two scope types in the AviSynth script language:\n\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\n\nGlobal scope\n------------\n\nEvery :doc:`variable <../syntax/syntax_script_variables>` placed in this scope can be freely accessed from any nested\nblock of script code at any level of nesting. That is, you can access a\nglobal from the top-level script block, from inside a user :doc:`function <../syntax/syntax_userdefined_scriptfunctions>` at any\nlevel of recursion, as well as from inside :doc:`runtime scripts <../syntax/syntax_runtime_environment>`.\n\n**Note:** One important precondition for the above rule to apply is that *you\nmust not have a local variable with the same name as a global one*. If you\ndefine a local variable with the same name as a global one, then you can no\nlonger get (read) the value of the global variable in that specific local\nscope. This is because AviSynth when given a variable's name it first\nsearches in the current local scope; only if the search fails the global\nscope is searched. You can however set (write) the global's value, since in\nthat case the use of the keyword ``global`` distinguishes between a global\nand a local variable.\n\n\nLocal scope\n-----------\n\nVariables placed in this scope can be accessed (read or written) *only* from\nscript code within that scope. This allows the isolation of nested local\nscopes and makes the creation and usage of script functions possible.\n\nThe most important local scope is the top-level script scope (the one that is\ncreated just before the executing script is parsed and evaluated). All non-\nglobal variables defined inside the script-level source code reside there.\nAll the other local scopes are created due to function calls and are nested\ninside this one.\n\nNested local scopes result from function or filter calls (plugin writers can\ncreate nested scopes through ``env->PushContext()`` and\n``env->PopContext()``) and can be created at an arbitrary depth. For example,\na recursive user function such as the one below:\n\n::\n\n    function strfill(string s, int count) {\n        return count > 0 ? s + strfill(s, count - 1) : \"\"\n    }\n\nwill result during its evaluation in the creation and subsequent destruction\nof eleven nested local scopes if called with a value ten for its ``count``\nargument.\n\n\nLifetime of variables\n---------------------\n\nThe lifetime of variables defined at the global and top-level script (local)\nscope spans from the time of the definition (that is the first statement that\nassigns a value to them) to the end of frame serving and the unload of\n``avisynth.dll``.\n\nThe lifetime of variables defined at nested local scopes spans from the time\nof the definition in the nested local scope to the end of the nested local\nscope's lifetime. Since nested local scopes result from function / filter\ncalls, the nested scope's lifetime is the lifetime of the function / filter\ncall.\n\n\nA variables scope and lifetime example\n--------------------------------------\n\nTo clarify the statements of the previous section, the following example\ndemonstrates the scope and lifetime of variables in a moderately complex\nAviSynth script that also includes runtime scripts.\n\nWhat the script does is to divide a clip (after some processing tweaks) in 4\nequal-sized regions and evaluate the average luma of each region per frame.\nIf this is outside a range defined by two thresholds, the corresponding\nregion is turned to all black (if below) or white (if above) for that frame.\n\n::\n\n    function Quartile(clip c, int quartile) {\n        Assert(quartile >= 0 && quartile <= 3, \"Invalid\n        Quartile!\")\n        hw = Int(c.Width() / 2)\n        hh = Int(c.Height() / 2)\n        return Select(quartile, \\\n            Crop(c, 0, 0, hw, hh), Crop(c, hw, 0, hw, hh), \\\n            Crop(c, 0, hh, hw, hh), Crop(c, hw, hh, hw, hh))\n    }\n\n    function bracket_luma(clip c, float th1, float th2) {\n        Assert(0 <= th1 && th1 < th2 && th2 <= 255, \"Invalid\n        thresholds!\")\n        script =  \"th1 = \" + String(th1) + Chr(13) + Chr(10) + \\\n            \"th2 = \" + String(th2) + \"\"\"\n            avl = AverageLuma()\n            return avl <= th1 ? last.BlankClip() : (avl >= th2\n            ? \\\n                last.BlankClip(color=color_white) : last)\n            \"\"\"\n        return ScriptClip(c, script)\n    }\n\n    clp = AviSource(\"myclip.avi\")\n    clp = Tweak(clp, hue=20, sat=1.1)\n    threshold1 = 12.0\n    threshold2 = 78.0\n    q0 = Quartile(clp, 0).bracket_luma(threshold1, threshold2)\n    q1 = Quartile(clp, 1).bracket_luma(threshold1, threshold2)\n    q2 = Quartile(clp, 2).bracket_luma(threshold1, threshold2)\n    q3 = Quartile(clp, 3).bracket_luma(threshold1, threshold2)\n    StackVertical(StackHorizontal(q0, q1), StackHorizontal(q2, q3))\n\nThe scope and lifetime of all variables in the example script is presented in\nthe following timeline (the ``color_white`` global is from the autoloaded\n.avsi that ships with AviSynth):\n\n::\n\n    +-- scope --+------- parsing phase ---------------------->+----- frameserving phase -------->+\n    |           |                                             |                                  |\n    | global    |color_white - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->|\n    +-----------+---------------------------------------------+----------------------------------|\n    | local,    |clp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->|\n    | top-level | threshold1,threshold2- - - - - - - - - - - - - - - - - - - - - - - - - - - - ->|\n    |           |  q0,q1,q2,q3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->|\n    |           |                                             |avl,th1,th2 - - - - - - - - - - ->|\n    +-----------+---------------------------------------------+----------------------------------|\n    | local,    |   c,  - - - ->|           |                |\n    | Quartile  |   quartile, ->|           | repeated       |\n    | function  |    hw,hh- - ->|           | three times,   |\n    +-----------+-------------------------->| in immediate ->|\n    | local,    |   |            c, - - - ->| succession     |\n    | bracket_l.|   |            th1,th2, ->|                |\n    | function  |   |             script- ->|                |\n    +-----------+---------------------------------------------+----------------------------------|\n\nCode-injecting language facilities and scopes\n---------------------------------------------\n\nThere are certain language constructs (functions, filters and control\nstructures) that allow the injection of code in the script, ie the execution\nof arbitrary sequences of AviSynth script language :doc:`statements <../syntax/syntax_ref>`.\n\nThis is a *very* useful functionality that allows among other things dynamic\ncode evaluation, the creation of :doc:`block statements <script_ref_block_statements>` and :doc:`arrays <script_ref_arrays>`, the\norganisation of AviSynth code in libraries, etc. However, there are some\nsubtle issues regarding variables' scope and visibility that can lead to\nsurprises if not fully understood.\n\n\nImport and Eval\n~~~~~~~~~~~~~~~\n\n:doc:`Import <../corefilters/import>` and :doc:`Eval <../syntax/syntax_internal_functions_control>` evaluate the passed-in script source code in the\ncontext of the current local scope.\n\nThis means that variables contained in the top-level scope of the imported\nscript or in the code string passed to Eval() are created inside the current\nlocal scope and become available for read/write to the following script\nsource code. For example:\n\n**1. File \"a.avs\"**\n\n::\n\n    x = 12\n    y = 24\n    c = BlankClip(pixel_type=\"YV12\", color=color_orange, width=240, height=180)\n\n**2. File \"b.avs\"**\n\n::\n\n    Import(\"a.avs\")\n    AviSource(\"myvideo.avi\")\n    Levels(**x**, 1.0, 255, **y**, 242)\n    Overlay(**c**, x=last.Width-320, y=last.Height-240, mode=\"chroma\")\n\nIn addition, the imported script or the code string passed to Eval() can use\npreviously defined in that scope local variables (as well as globals, of\ncourse). For example (the use of multiline triply quoted strings makes easier\nthe writing of :doc:`block statements <script_ref_block_statements>`):\n\n::\n\n    x = 5\n    AviSource(\"aclip.avi\")\n    f = Framecount()\n    f < 100 ? Eval(\"\"\"\n        Trim(x, f-2)\n        x = 0\n    \"\"\") : Eval(\"\"\"\n        Trim(x, 15*x + 30)\n        x = 1\n    \"\"\")\n    x == 0 ? Invert() : Subtitle(String(last.Framecount))\n\nEspecially the later is something that you must always keep in mind -mostly\nfor :doc:`Import <../corefilters/import>` since the code is not immediately visible; only the filename\nshows up in the script- because it has the potential to introduce bugs by\nunexpected overriding of a variable's value.\n\nConsider, the following example:\n\n**1. File \"mylib.avsi\"**\n\n::\n\n    function preset(int num) { # 0 to 3\n        return Select(num, AviSource(\"...\"), AviSource(\"...\"),\n        AviSource(\"...\"), AviSource(\"...\"))\n    }\n    global def_preset = preset(0)\n\n**2. File \"myscript.avs\"**\n\n::\n\n    global def_preset = AviSource(\"myfav.avi\")\n    Import(\"mylib.avsi\")\n    Tweak(def_preset, hue=20) # oops, using clip from mylib.avsi instead of myscript.avs!\n    ...\n\nThe imported script changed a previously defined variable and the results\nwill now be suprising (until of course the bug is discovered).\n\nHowever, this same feature has a number of interesting possibilities, for\nexample:\n\n-   You can define sub-scripts that communicate with the parent script\n    through a defined set of variables.\n-   You can create libraries (AviSynth include files) that perform\n    initialisation code based on \"environment\" variables (the ones you set in\n    the parent script before importing) and / or return status information\n    (through a variable that they set at the global or top-script level code)\n-   You can implement :doc:`block statements <script_ref_block_statements>`.\n\n**Note:** To test for the existence of input/output variables in the above\nscenarios try to read their value in a ``try..catch`` block; else your script\nwill die hard if for any reason they do not exist.\n\n\nRuntime scripts\n~~~~~~~~~~~~~~~\n\nLocal variables inside runtime filters' scripts are **always** binded to the\ntop-level script local scope; even if the filter calls were made inside a\nuser function. This is because the parsing of runtime scripts is done *after*\nthe parsing of the script, at the frame serving phase. At that point in\nscript execution, nested local scopes have already vanished and only the\nglobal and the top-level script local scopes survive.\n\nThe same is true for the :doc:`special variables <../syntax/syntax_runtime_environment>` set by the runtime filters\n(such as for example ``current_frame``); they are defined at the top-level\nscript local scope.\n\nSome consequences of the above setup are the following:\n\n-   You can use top-level script local variables inside the runtime\n    scripts to pass information, just as is customary to do with global ones.\n-   You must be careful if you define local variables in your runtime\n    scripts to not clash with local variables in other runtime scripts in the\n    filter chain. This is also true for globals, but globals are typically\n    used for inter-filter communication; use of locals is not so common and\n    thus may be overlooked by script writers.\n-   Overriding a variable (either local or global) does not have an efect\n    at the main script, because the evaluation of the main script is done at\n    the parsing phase, before the execution of any runtime script.\n-   When examining the way that a variable will be modified by a chain of\n    runtime scripts, you must remember that the evaluation of scripts is done\n    from bottom to top, just like the fetching of frames.\n\nConsider the following example:\n\n::\n\n    AviSource(\"myclip.avi\")\n    x = 5\n    fc = Framecount()\n    fc > 2x ? Trim(x, fc - x) : Trim(0, fc - x)\n    fc = Framecount()\n    ScriptClip(\"\"\"Subtitle(\"and the value of x is : \" + String(x))\"\"\")\n    FrameEvaluate(\"x = (x % 3 == (fc - x - 1) % 3) ? x + 2 : x - 1\")\n    FrameEvaluate(\"x = current_frame\")\n\nThe assignment ``x = 5`` at the main script is used to control trimming of\nthe source clip. ``x`` is passed as argument in the :doc:`Trim <../corefilters/trim>` filter during the\nscript's parsing phase. Thus the modifications by the runtime scripts that\nstart at the frame serving phase has no effect on the values passed to Trim.\n\nBy the time the first frame will be fetched, ``x`` will have been overrided\nby the ``x = current_frame`` assignment in the last :doc:`FrameEvaluate <../corefilters/conditionalfilter>` filter's\nruntime script. Thus its value in the script has no effect (in this\nparticular case) to the results of the runtime filters processing.\n\nHere, using ``x`` in all runtime filter scripts does not pose a naming clash\nproblem. ``x`` is the variable used to communicate state information along\nthe runtime filter chain. However, if we have needed a conditional assignment\nby frame number and we have accidentally used the following runtime script in\nplace of the last FrameEvaluate line,\n\n::\n\n    FrameEvaluate(\"\"\"\n        fc = 12\n        x = current_frame < fc ? current_frame : fc\n        \"\"\")\n\nthen there would be a clash with the use of ``fc`` in the previous line (the\nclips framecount would have been overwritten with an unrelated value) and the\nlogic of our processing would be in error.\n\n\nThe try...catch block\n~~~~~~~~~~~~~~~~~~~~~\n\nThis may seem surprising at first, but the ``try...catch`` block does inject\ncode in the script (at the scope that contains it). If this code defines new\nvariables, then those variables are available to the code in the section that\nfollows the ``try...catch`` block. More specifically, there are two\npossibilities:\n\n-   *No error* occurs inside the ``try{...}`` section.\n\n1.  All statements of the code contained in the ``try{...}`` section are\n    evaluated and affect the script code that follows.\n\n-   An error *does* occur inside the ``try{...}`` section.\n\n1.  Statements of the code contained in the ``try{...}`` section up to\n    the point of error are evaluated and affect the script code that follows.\n2.  All statements of the code contained in the ``catch{...}`` section\n    are evaluated and affect the script code that follows.\n3.  The variable that is used the ``catch{...}`` section to store the\n    error message becomes available to the script code that follows.\n\nThe following example code excerpt clarifies the above:\n\n::\n\n    a = ... # it is assumed that the (missing) code may result in a being either 1 or 0\n    try {\n        y = 3\n        x = 6 / a  # if a == 0 this will lead to an error\n        z = 12\n    }\n    catch (msg) {\n        NOP\n    }\n    ...code that follows...\n\nNow, if ``a`` is *not* zero at the point the ``try...catch`` block is\nevaluated, then three new local variables in the current scope will be\ncreated (``x``, ``y`` and ``z``) and be available for use by the code that\nfollows.\n\nIf however, ``a`` *is* zero, then from the three variables in the try section\nonly ``y`` will be created; in addition, since the catch section will be\nevaluated, ``msg`` will be created. Thus the variables available for use by\nthe code that follows will be ``x`` and ``msg``.\n\n--------\n\nBack to the :doc:`script execution model <script_ref_execution_model>`.\n\n$Date: 2011/04/29 20:11:14 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/script_ref/script_ref_execution_model_perf_cons.rst",
    "content": "\nThe script execution model - Performance considerations\n=======================================================\n\nThis section presents some performance-related issues that originate from the\nway AviSynth scripts are executed; it also provides advice on how to optimise\nyour scripts and AviSynth configuration so that your scripts are parsed\nand/or encoded faster.\n\n\nPlugin auto-loading\n-------------------\n\nAn important thing to note is that auto-loading although is a convenient\nmethod to have all your favorite filters on hands, it *does* incur a speed\npenalty. The penalty is twofold:\n\n1.  The loading, registering and unloading of plugins takes some time.\n    The parsing of .avsi scripts also takes some time. This time, although\n    small, is payed *in every* AviSynth script invocation.\n2.  The registering of many functions and globals increases the size of\n    internal AviSynth data structures, which on turn increases the seek time\n    to locate a filter / variable during the parsing phase as well as during\n    runtime script parsing.\n\nFor small scripts and / or small number of auto-loading plugins the ease of\nuse outweights the above speed penalty (since there is also a speed penalty\nin writing a lot of :doc:`LoadPlugin <../syntax/syntax_plugins>` calls in every script that needs them).\nHowever if you regularly write large and complex scripts and have a large\nnumber of plugins / include scripts in your AviSynth plugin folder, you\nshould consider a more granular approach to increase overall script parsing /\nencoding performance.\n\nFor example, you could group :doc:`LoadPlugin <../syntax/syntax_plugins>` calls for related plugins in\nseparate .avsi scripts and have a central .avsi script with a config function\nthat loads different .avsi scripts depending on its arguments. Then place in\nthe plugin folder only the central .avsi script and the bare-essential\nplugins that you use almost every time.\n\n\nFrame caching and the effect on spliting filter graph's paths\n-------------------------------------------------------------\n\nIn order to improve performance AviSynth places, transparently to script\nwriters, a specialised Cache filter just after each filter. The purpose of\nthe cache is to avoid the computationally expensive generation of a video\nframe that has recently been created; if the frame is in the cache then it is\nreturned immediately, avoiding a possibly long chain of filter calls.\n\nThe presence of the cache gives a speed and memory advantage to filter graphs\nthat split processing paths *as late as possible*. In our filter graph\nexample above, if instead of:\n\n::\n\n    ov = AviSource(\"clip2.avi\")\n    ov1 = Lanczos4Resize(ov, 280, 210)\n    ov2 = ov1.Invert()\n\nwe have used the following code:\n\n::\n\n    ov = AviSource(\"clip2.avi\")\n    ov2 = ov\n    ov1 = Lanczos4Resize(ov, 280, 210)\n    ov2 = ov2.Lanczos4Resize(280, 210).Invert()\n\nthen the respective part of the filter graph would have been:\n\n::\n\n    ...\n               |\n    AviSource(clip2) <--+-- Lanczos4Resize <--+-- Overlay <--+\n                        |\n                        |\n                        +-- Lanczos4Resize <-- Invert\n                        <------+-- Overlay (filter graph's root)\n\nIn the later case we would have one more filter (and cache) in the filter\nchain and -more importantly- we would have to generate two resized frames for\neach call by the host application to get a frame instead of one.\n\nTherefore, always try to split processing paths as late as possible; it will\nmake your scripts faster.\n\n\nWhat *not* to include in runtime scripts\n----------------------------------------\n\nAlthough as said above, runtime scripts are parsed as regular scripts do and\nthus every statement allowed to a regular script is allowed in a runtime\nscript, some statements are not advisable from a performance point of view.\n\nThe principal reason is that runtime script parsing occurs in *every* frame\nrequested. Therefore, as a rule of thumb, computationally expensive actions\nshould in general be placed outside the runtime environment (at the main\nscript) in order to be executed only once. This practice trades some start-up\noverhead with savings during frame serving, which in general dominates the\noverall clip rendering / encoding time; thus it is justified as an\noptimisation. This is of course to be taken with a grain of salt because\nthere are circmustances where the application needs force the (balanced) use\nof such statements.\n\nHaving said all that, let's see our not-to-do-in-runtime-scripts list (and\nsome interesting counter-examples):\n\n-   The following actions should most of the time be avoided:\n\n    -   Importing a script.\n    -   Loading a plugin.\n    -   Defining a user function.\n\nIssuing them on every frame will slow down (maybe significantly) encoding\nspeed and (subject to implementation details) eat valuable memory. Moreover,\nthis overhead will be beared without returning significant gains. It is in\ngeneral much better to place them at the main script. See however an example\nof acceptable use: `Subtitles from a changing text-file`_.\n\n-   Calling a lot of filters / functions inside the runtime script will\n    slow down your encoding speed. Those filters will be created and\n    destroyed on every frame; thus you pay initialisation/cleanup costs at\n    every frame.\n\nIf you can, put not-essential for the runtime processing filter calls outside\nthe runtime environment; break the runtime script in more scripts if you have\nto. For example, instead of doing this:\n::\n\n    AviSource(\"myclip.avi\")\n    total_frames = Framecount()\n    ScriptClip(\"\"\"\n        Levels(0, 0.9, 255, 5, 250)\n        total_frames % current_frame < 2 ? FlipHorizontal : last\n        Tweak(hue=18)\n        Subtitle(\"frame: \" + String(current_frame), y=320)\n        \"\"\")\n\ndo this:\n\n::\n\n    AviSource(\"myclip.avi\")\n    total_frames = Framecount()\n    Levels(0, 0.9, 255, 5, 250)\n    ScriptClip(\"\"\"total_frames % current_frame < 2 ? FlipHorizontal : last\"\"\")\n    Tweak(hue=18)\n    ScriptClip(\"\"\"Subtitle(\"frame: \" + String(current_frame), y=320)\"\"\")\n\n-   :doc:`Arrays <script_ref_arrays>`, due to their recursive, script-based implementation can be\n    expensive to parse, especially if they host a large number of elements.\n    Using them without paying attention to minimize operations will slow down\n    your encoding speed.\n\nSee however an example of acceptable use: `Per frame filtering, exporting\nspecific frame(s)`_ (note that FrameFilter is a wrapper around\n:doc:`ScriptClip <../corefilters/conditionalfilter>`).\n\n--------\n\nBack to the :doc:`script execution model <script_ref_execution_model>`.\n\n$Date: 2011/04/29 20:11:14 $\n\n.. _Subtitles from a changing text-file:\n    http://forum.doom9.org/showthread.php?t=129191\n.. _Per frame filtering, exporting specific frame(s):\n    http://avslib.sourceforge.net/examples/example-016.html\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/script_ref/script_ref_execution_model_sequence_events.rst",
    "content": "\nThe script execution model - Sequence of events\n===============================================\n\nThe sequence of events that occur when you execute (ie load and render to\nyour favorite encoder) an AviSynth script is presented below.\n\nThe sequence is conceptually divided in three major phases:\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\n\nThe initialisation phase\n------------------------\n\nDuring this phase the following events occur:\n\n-   An AVI stream object is created by the operating system, using the\n    handler code provided by AviSynth.\n-   AviSynth dll is loaded and performs (among other initialization\n    actions) auto-loading of the following files that are placed in the\n    AviSynth autoload folder:\n\n    -   All AviSynth plugins (files with ``.dll`` extension).\n    -   All AviSynth include scripts (files with ``.avsi`` extension).\n\nDuring auto-loading:\n\n-   The plugin and script functions are registered in the internal data\n    structures of AviSynth; all plugins are unloaded after this phase. Only\n    if a function is actually used inside the script, the plugin is loaded\n    again.\n-   Avisynth include scripts are parsed (executed), as if they where all\n    included in the top of the script source code with :doc:`Import <../corefilters/import>` statements.\n\n\nThe script loading and parsing phase\n------------------------------------\n\nDuring this phase the following events occur:\n\n-   The host video application (the editor or the encoder) requests a\n    frame from the AVI stream object (usually frame 0, but you should not\n    count on this always being true).\n-   The script is loaded with a call to the Import :doc:`internal function <../syntax/syntax_internal_functions>`\n    and its contents are passed to the Eval() :doc:`control function <../syntax/syntax_internal_functions_control>` for\n    parsing.\n-   The entire parse process takes place. :doc:`Expressions <../syntax/syntax_ref>` are evaluated,\n    :doc:`variables <../syntax/syntax_script_variables>` are set and clips are created and chained together to form\n    the script's fitler graph (see next section).\n-   At this point, just after the end of the parse process:\n\n    -   The filter graph has been formed.\n    -   Global variables have attained their final (regarding the parsing\n        phase) values and, along with all functions defined in the script or\n        imported in the global scope, are available for use and possibly\n        **modification** by the runtime scripts.\n\n\nThe video frames serving phase\n------------------------------\n\nDuring this phase the following events occur:\n\n-   The initially requested frame is delivered to the host application.\n    This forces runtime scripts that are possibly included in the source code\n    to be parsed (executed) for that frame.\n-   The host video application requests additional frames. Each frame is\n    delivered, possibly forcing runtime scripts that are in the filter chain\n    for that frame to be parsed (executed).\n\n**Note:** since runtime scripts may be anywhere in the filter chain and\nframes may be shuffled (AviSynth is an NLE after all!) the statement \"for\nthat frame\" should be interpreted as \"for that frame of the final clip and\nany linked frames of intermediate clips\".\n\n--------\n\nBack to the :doc:`script execution model <script_ref_execution_model>`.\n\n$Date: 2010/11/28 18:47:26 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/script_ref/script_ref_user_functions.rst",
    "content": "\nUser functions\n==============\n\nHaving read the basics about :doc:`user-defined script functions <../syntax/syntax_userdefined_scriptfunctions>`, we can now\nstep forward to examine in detail each function building block and identify\nrules for effective code development.\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\n\nThe function declaration (header)\n---------------------------------\n\nThe function declaration consists of the keyword ``function`` followed by the\nfunction's name and a (possibly empty) list of parameters (arguments)\nenclosed in a pair of parentheses. Its purpose is to declare the function,\nthat is both make its name visible to the running script and state the number\nand type of the arguments that it expects in subsequent invocations (function\ncalls).\n\nNote that in AviSynth script language the declaration is also a definition;\nthe function body (the code that is executed every time the function is\ncalled) must be supplied immediately after.\n\n\nThe function name\n~~~~~~~~~~~~~~~~~\n\nTo name your user function you can pick any name that appropriately describes\nthe purpose of it. You should however avoid naming a function with an already\nwidely used name; the AviSynth script language namespace is flat and thus any\nsuch name collision means you (and others) cannot use both functions\ntogether. Note also that function names (as everything in AviSynth script\nlanguage) are case insensitive.\n\n\nThe argument list\n~~~~~~~~~~~~~~~~~\n\nRegarding the possible different kinds of arguments a function can declare,\nthere are two orthogonal to each other categorical divisions:\n\n1.  **Typed** vs **variable** arguments.\n2.  **Required** vs **optional** arguments.\n\n\nTyped and variable (``val``) arguments\n::::::::::::::::::::::::::::::::::::::\n\nTyped arguments have a fixed type, decided by the specific type prefix (clip,\nint, float, bool, string) used during function declaration. Whenever a script\nis calling a function, AviSynth checks the supplied values for all typed\narguments to ensure that they are of the proper type; if a discrepancy is\nfound an error condition is triggered. Therefore, typed arguments can always\nbe assumed of being the correct type (but not 'value'!) inside the body of\nthe function, simplifying coding.\n\nVariable arguments can accept *any* AviSynth type (clip, int, float, bool,\nstring) when the function is called. You can declare a function argument as\nbeing variable with either of two ways:\n\n-   specify ``val`` as the type of the argument, for example:\n\n::\n\n    function myfunc(clip c, val effect) { ... }\n    function myfunc2(clip c, **val \"action\"**) { ... }\n\n-   do *not* specify a type for the argument, for example:\n\n::\n\n    function myfunc(clip c, effect) { ... }\n    function myfunc2(clip c, **\"action\"**) { ... }\n\nAs a side effect, whenever you neglet to provide the type of an argument you\nwill get a variable argument. Keep this in mind when you are debugging your\nscripts.\n\nVariable arguments can also be optional. To do so, you simply enclose the\nargument in double quotes, as for typed arguments.\n\nVariable arguments are useful in some situations because they provide\nflexibility and reduce the size of the argument list. However, they have the\ndrawback that your function code has to check the type of each variable\nargument in order to ensure its validity for the intended operation (for\ntyped arguments, the type check is performed by AviSynth).\n\n\nRequired and optional arguments\n:::::::::::::::::::::::::::::::\n\nRequired arguments must always be supplied when you are calling the function\n\nOptional arguments need not be supplied; they default (if the function is\ncoded correctly) to reasonable initial values.\n\n\nThe function body\n-----------------\n\nThe function body contains the bulk of the code that makes up your function.\nSince they strongly depend on the tasks-on-hand, the contents of the function\nbody are quite arbitrary. However, there are some frequently occuring coding\npatterns that together form a more or less \"standard\" recipe for constructing\nthe function body. These are in the usual order of appearance the following:\n\n-   Argument validation and setup of local variables.\n-   Performance of intermediate computations.\n-   Return of final computation outcome to the caller of the function.\n\nWe will now look closer on each one in the paragraphs that follow.\n\n\nArgument validation and setup of local variables\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n\nPerformance of intermediate computations\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n\nReturn of final computation outcome to the caller\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n\nDesigning and developing user functions\n---------------------------------------\n\n\nDefining goals\n~~~~~~~~~~~~~~\n\n\nManipulating globals\n~~~~~~~~~~~~~~~~~~~~\n\nhow to use effectively and safely\n\n\nRecursion\n~~~~~~~~~\n\nthe only tool to act upon collections\n\n\nTuning performance\n------------------\n\n\nDesign and coding-style considerations\n--------------------------------------\n\n\nOrganising user defined functions\n---------------------------------\n\n\nBack to :doc:`scripting reference <script_ref>`.\n\n$Date: 2011/04/29 20:36:18 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax.rst",
    "content": "\nGetting started\n===============\n\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\n\nBasically, AviSynth works like this: First, you create a simple text document\nwith special commands, called a script. These commands make references to one\nor more videos and the filters you wish to run on them. Then, you run a video\napplication, such as VirtualDub, and open the script file. This is when\nAviSynth takes action. It opens the videos you referenced in the script, runs\nthe specified filters, and feeds the output to video application. The\napplication, however, is not aware that AviSynth is working in the\nbackground. Instead, the application thinks that it is directly opening a\nfiltered AVI file that resides on your hard drive.\n\nThere is much new and re-discovered functionality in AviSynth2. To make those\nitems clearly visible (especially when the feature was not well documented in\nthe past) they are marked with **v2**\n\nThe version 2.5 is a major internal upgrade. Read :doc:`AviSynth 2.5 <../twopointfive>` carefully\nbefore you use it. Relevant changes are marked with **v2.5**\n\nLinear Editing\n--------------\n\nThe simplest thing you can do with AviSynth is the sort of editing you can do\nin VirtualDub. The scripts for this are easy to write because you don't have\nto worry about variables and complicated expressions if you don't want.\n\nFor testing create a file called test.avs and put the following single line\nof text in it:\n::\n\n    Version\n\nNow open this file with e.g. Windows Media Player and you should see a ten-\nsecond video clip showing AviSynth's version number and a copyright notice.\n\n``Version`` is what's called a \"source filter\", meaning that it generates a\nclip instead of modifying one. The first command in an AviSynth script will\nalways be a source filter.\n\nNow add a second line to the script file, so that it reads like this:\n::\n\n    Version\n    ReduceBy2\n\nReopen the file in Media Player. You should see the copyright notice again,\nbut now half as large as before.\n:doc:`ReduceBy2 <../corefilters/reduceby2>` is a \"transformation filter,\" meaning that it takes the\nprevious clip and modifies it in some way. You can chain together lots of\ntransformation filters, just as in VirtualDub.\nLet's add another one to make the video fade to black at the end. Add another\nline to the script file so that it reads:\n::\n\n    Version\n    ReduceBy2\n    FadeOut(10)\n\nNow reopen the file. The clip should be the same for the first 9 seconds, and\nthen in the last second it should fade smoothly to black.\nThe :doc:`FadeOut <../corefilters/fade>` filter takes a numerical argument, which indicates the number\nof frames to fade.\n\nIt takes a long time before the fade starts, so let's trim the beginning of\nthe clip to reduce the wait, and fade out after that.\nLet's discard the first 120 of them, and keep the frames 120-150:\n::\n\n    Version\n    ReduceBy2\n    # Chop off the first 119 frames, and keep the frames 120-150\n    # (AviSynth starts numbering frames from 0)\n    Trim(120,150)\n    FadeOut(10)\n\nIn this example we used a comment for the first time.\nComments start with the # character and continue to the end of the line, and\nare ignored completely by AviSynth.\nThe :doc:`Trim <../corefilters/trim>` filter takes two arguments, separated by a comma: the first and\nthe last frame to keep from the clip. If you put 0 for the last frame, it's\nthe same as \"end of clip,\" so if you only want to remove the first 119 frames\nyou should use Trim(120,0).\n\nKeeping track of frame numbers this way is a chore. It's much easier to open\na partially-completed script in an application like VirtualDub which will\ndisplay the frame numbers for you. You can also use the :doc:`ShowFrameNumber <../corefilters/showframes>`\nfilter, which prints each frame's number onto the frame itself.\n\nIn practice a much more useful source filter than :doc:`Version <../corefilters/version>` is :doc:`AVISource <../corefilters/avisource>`,\nwhich reads in an AVI file (or one of several other types of files) from\ndisk. If you have an AVI file handy, you can try applying these same filters\nto your file:\n::\n\n    AVISource(\"d:\\capture.avi\")  # or whatever the actual pathname is\n    ReduceBy2\n    FadeOut(15)\n    Trim(120,0)\n\nEven a single-line script containing only the AVISource command can be useful\nfor adding support for >2GB AVI files to applications which only support <2GB\nones.\n\n\n--------\n\n\nNon-Linear Editing\n------------------\n\nNow we're getting to the fun part. Make an AVS file with the following script\nin it:\n::\n\n    StackVertical(Version, Version)\n\nNow open it. Result: An output video with two identical lines of version\ninformation, one on top of the other.\nInstead of taking numbers or strings as arguments, :doc:`StackVertical <../corefilters/stack>` takes\nvideo clips as arguments. In this script, the Version filter is being called\ntwice. Each time, it returns a copy of the version clip. These two clips are\nthen given to :doc:`StackVertical <../corefilters/stack>`, which joins them together (without knowing\nwhere they came from).\n\nOne of the most useful filters of this type is :doc:`UnalignedSplice <../corefilters/splice>`, which\njoins video clips end-to-end. Here's a script which loads three AVI files\n(such as might be produced by AVI_IO) and concatenates them together.\n::\n\n    UnalignedSplice(AVISource(\"d:\\capture.00.avi\"), \\\n    AVISource(\"d:\\capture.01.avi\"), \\\n    AVISource(\"d:\\capture.02.avi\"))\n\nBoth :doc:`StackVertical <../corefilters/stack>` and :doc:`UnalignedSplice <../corefilters/splice>` can take as few as two arguments\nor as many as sixty.\nYou can use the ``+`` operator as a shorthand for :doc:`UnalignedSplice <../corefilters/splice>`.\n\nFor example, this script does the same thing as the previous example:\n::\n\n    AVISource(\"d:\\capture.00.avi\") + \\\n    AVISource(\"d:\\capture.01.avi\") + \\\n    AVISource(\"d:\\capture.02.avi\")\n\nNow let's suppose you're capturing with an application that also saves the\nvideo in multiple AVI segments, but puts the audio in a separate WAV file.\nCan we recombine everything? You bet:\n::\n\n    AudioDub(AVISource(\"d:\\capture.00.avi\") + \\\n    AVISource(\"d:\\capture.01.avi\") + \\\n    AVISource(\"d:\\capture.02.avi\"), \\\n    WAVSource(\"d:\\audio.wav\"))\n\n--------\n\n\nSyntax\n------\n\n\nExpressions\n~~~~~~~~~~~\n\nAn AviSynth script consists of multiple lines of statements looking like\nthis:\n::\n\n    variable_name = expression\n\nIn this example expression is evaluated and the result is assigned to\nvariable_name.\n\nVery important is the common shortcut form:\n::\n\n    expression\n\nIn this case, expression is evaluated and the result is assigned to the\nspecial clip variable last.\nThis is the same as\n::\n\n    last = expression\n\nThe end of the script often looks like:\n::\n\n    return expression\n\nHere expression is evaluated and is used as the \"return value\" of the script\n--that is, the video clip that will be seen by the application which opens\nthe AVS file.\n\nIf \"return\" is not specified explicitly, the clip last is used as a \"return\nvalue\".\n\nThe basic form of an expression which invokes a function is\n::\n\n    Function(args)\n\nClip functions always produce a new video clip and never modify an existing\none,\nArgs is a list of function arguments separated by commas. The list can be\nempty (which means all or some arguments can be optional)\n\nIf the filter function expects a video clip as its first argument, and that\nargument is not supplied, then the clip in the special variable last will be\nused.\n\nAviSynth filters can take named arguments. The named arguments can be\nspecified in any order,\nand the filter will choose default values for any that you leave off (named\narguments are always optional).\nThis makes certain filters much easier to use. You can write\n::\n\n    Subtitle(\"Hello, World!\", text_color=$00FF00, x=100, y=200)\n\ninstead of\n::\n\n    Subtitle(\"Hello, World!\", 100, 200, 0, 999999, \"Arial\", 24, $00FF00)\n\nAn alternate syntax (called \"OOP notation\") for clip functions is\n::\n\n    expression.Function(args)\n\n    e.g.:\n    Version.ReduceBy2.FadeOut(15)\n\nThis is equivalent to\n::\n\n    Function(expression, args)\n\n    e.g.:\n    FadeOut(15, ReduceBy2(Version))\n\nand can be thought of ``Function`` applied to ``expression``.\nOne disadvantage of OOP notation is that it can only be used with filters\nwhich take a single video-clip argument, not with filters which take several.\n\nAll AviSynth functions produce defined number of output frames and framerate,\neven if the statement seems very complex.\nAviSynth knows after having read the script how long the output will be,\nwhich framerate it has and the \"cutting sequence\" of all used inputs\nThis is all calculated on opening the script. Only the actual filtering is\ndone runtime on request.\n\n\n--------\n\n**Comments**: AviSynth ignores anything from a # character to the end of that\nline:\n::\n\n    # comment\n\nIn *v2.58* it is possible to add block and nested block comments in the\nfollowing way:\n::\n\n    # block comment:\n    /*\n    comment 1\n    comment 2\n    */ ::# nested block comments:\n    [* [* a meaningful example with follow later :) *] *]\n\nAviSynth ignores anything from an ``__END__`` keyword (with double\nunderscores) to the end of the script file. This can be used to disable some\nlast commands of script.\n\n::\n\n    Version()\n    __END__\n    ReduceBy2()\n    Result is not reduced and we can write any text here\n\n\n**Ignore Case**: aViSouRCe is just as good as AVISource.\n\n**Continue** on next or from previous line: \\\n::\n\n    Subtitle (\"Test-Text\")\n\n    Subtitle ( \\\n              \"Test-Text\")\n\n    Subtitle (\n           \\ \"Test-Text\")\n\n--------\n\n\nVariables\n~~~~~~~~~\n\nA variable name can be up to 50 characters long (actually more than 4000\ncharacters in Avisynth *v2.56*) and can contain (English) letters, digits,\nand underscores (_), but no other characters. The name cannot start with a\ndigit.\n\nYou may use characters from your language system codepage (locale) in strings\nand file names (ANSI 8 bit, utf8, but not a 16 bit Unicode).\n\nThe following types of variables can be used:\n\n- *clip*: a video clip containing video and / or audio. At least one variable for\n  a clip must be used and returned by the script.\n  string: surrounded either by \"quotation marks\" or by 3 quotation marks like\n  ``\"\"\"this example\"\"\"``. A text string can contain any character except the\n  terminating quotation mark or double-apostrophe. If you need to put a\n  quotation mark inside a string, use the triple quote-notation:\n\n::\n\n    Subtitle\n    (\"\"\"This displays \"hello world\" with quotes\"\"\")\n\nStrings containing escaped characters start with ``e`` prefix before the\nquotation mark.\n\n::\n\n    Subtitle\n    (e\"This displays \\\"hello world\\\" with quotes\\nand automatic multiline\")\n\n- *int*, *long*: entered as a string of digits, optionally with a + or - at the\n  beginning. Since 3.7.4 64-bit integers are supported. In general 'int' covers\n  any 32 or 64-bit integer.\n- *float*, *double*: entered as a string of digits with a period (.) somewhere in it and an\n  optional + or -. For example, +1. is treated as a floating-point number.\n  Since 3.7.4 64-bit double is supported. In general 'float' covers\n  any 32 or 64-bit floating point number.\n- *val*: as type of a function argument where it does not matter if it is int or\n  float\n- *bool*: can be TRUE or FALSE\n- *hexadecimal numbers*: entered by preceding it with a $. This variable is\n  treated as an integer. Several filters use this notation for specifying\n  colors. For example, $FF8800 is a shade of orange. A hexadecimal constant is \n  32-bit integer by default. Suffixed by \"L\" or \"l\" makes it 64-bit long.\n\n::\n\n    a = $FFFFFFFF  # integer = -1\n    b = $FFFFFFFFL # long 64 bit = 4294967295\n\n\n- *global*: defines a global variable, which can be used by all user-defined\n  functions and the main script in common.\n\nHere's another version of the example from above that's more manageable and\neasier to understand:\n::\n\n    a = AVISource(\"d:\\capture.00.avi\")\n    b = AVISource(\"d:\\capture.01.avi\")\n    c = AVISource(\"d:\\capture.02.avi\")\n    sound_track = WAVSource(\"d:\\audio.wav\")\n\n    AudioDub(a+b+c, sound_track)\n\n--------\n\n\nColors\n------\n\nIn some filters (BlankClip, Letterbox, AddBorders and FadeXXX) a color\nargument can be specified. In all cases the color should be specified in RGB\nformat even if the color format of the input clip is YUV. This can be done in\nhexadecimal or decimal notation. In hexadecimal notation the number is\ncomposed as follows: the first two digits denote the red channel, the next\ntwo the green channel and the last two the blue channel. The hexadecimal\nnumber must be preceded with a $. In decimal notation the number is as\nfollows: the red channel value is multiplied by 65536, the green channel\nvalue is multiplied by 256 and the two resulting products are both added to\nthe blue channel value.\n\nLet's consider an example. Brown is given by R=$A5 (165), G=$2A (42), B=$2A\n(42). Thus ``BlankClip(color=$A52A2A)`` gives a brown frame. Converting each\nchannel to decimal (remember that A=10, B=11, C=12, D=14, E=14, F=15) gives\n::\n\n    R = $A5 = 10*16^1 +  5*16^0 = 165\n    G = $2A =  2*16^1 + 10*16^0 =  42\n    B = $2A =  2*16^1 + 10*16^0 =  42\n\n    165*65536 + 42*256 + 42 = 10824234\n\nThus creating a brown frame specifying the color in decimal notation gives\n``BlankClip(color=10824234)``.\n\nCommon color presets can be found in the file colors_rgb.avsi, which should\nbe present in your plugin autoload folder (look into the file for list of\npresets). Thus ``BlankClip(color=color_brown)`` gives the same brown frames.\n\nNote that black RGB=$000000 will be converted to Y=16, U=V=128 if the\ncolorformat of the input clip is YUV, since the default color conversion RGB\n[0,255] -> YUV [16,235] is used.\n\n--------\n\n\nOperators\n---------\n\n| For all types of operands (clip, int, float, string, bool) you can use:\n| ``==`` is equal to\n| ``!=`` is not equal to\n\n| For numeric types (int, float):\n| ``+`` add\n| ``-`` subtract\n| ``*`` multiply\n| ``/`` divide\n| ``%`` mod\n| ``>=`` greater than or equal to\n| ``<=`` less than or equal to\n| ``<`` less than\n| ``>`` greater than\n\nNote: since 3.7.4 ``int`` and ``float`` means any 32 or 64-bit integer or floating point value, respectively.\nThe exact type of value (e.g. if a variable or constant is 32-bit float or 64-bit double) is known.\n('i'nteger - 32-bit integer, 'l'ong - 64-bit integer, 'f'loat - 32-bit foating point, 'd'ouble - 64-bit floating point) \n\nInteger calculations are done in 64-bit precision. When the result fits into the 32 bit range, it is stored back as 32-bit integer ``i``.\nOtherwise the result is stored into 64-bit long ``l``.\n\nWhen both operands are 32-bit float, arithmetic is done in 32-bits and the result is a 32-bit float.\nOtherwise the calculation is done in 64-bit double ``d`` precision.\n\n| For string type:\n| ``+`` add\n| ``>=`` greater or equal than (case-insensitive)\n| ``<=`` less or equal than (case-insensitive)\n| ``<`` less than (case-insensitive)\n| ``>`` greater than (case-insensitive)\n\n| For clip type:\n| ``+`` the same as the function ``UnalignedSplice``\n| ``++`` the same as the function ``AlignedSplice``\n\n| For bool type (true/false):\n| ``||`` or\n| ``&&`` and\n| ``?:`` execute code conditionally ::b = (a==true) ? 1 : 2\n\n    This means in pseudo-basic:\n\n    if (a=true) then b=1 else b=2\n\n--------\n\n\nScript Functions\n----------------\n\nThe input and output of these functions are not clips, but some other\nvariables used in the script.\n\nNumerical functions\n~~~~~~~~~~~~~~~~~~~\n\nExcept ``MulDiv``, ``Rand`` and ``Spline`` the calculations are 64-bit (int or double) compatible.\n``HexValue`` has a special ``HexValue64`` variant.\n\nSee :doc:`AviSynth Syntax - Numeric functions <syntax_internal_functions_numeric>`, and\n:doc:`AviSynth Syntax - Numeric functions <syntax_internal_functions_conversion>`.\n\n\n+----------------------------------------------------------+---------------------------------------------+\n| ``Max(int, int[, ...])`` / ``Max(float, float[, ...])``: || ``Max`` (1, 2) = 2                         |\n|   Maximum value of a set of numbers.                     || ``Max`` (5, 3.0, 2) = 5.0                  |\n+----------------------------------------------------------+---------------------------------------------+\n| ``Min(int, int[, ...])`` / ``Min(float, float[, ...])``: || ``Min`` (1, 2) = 1                         |\n|   Minimum value of a set of numbers.                     || ``Min`` (5, 3.0, 2) = 2.0                  |\n+----------------------------------------------------------+---------------------------------------------+\n| ``MulDiv(int, int, int)``:                               || ``MulDiv`` (1, 1, 2) = 1                   |\n|   (m*n+d/2)/d using 64 bit intermediate result           || ``MulDiv`` (2, 3, 2) = 3                   |\n+----------------------------------------------------------+---------------------------------------------+\n| ``Floor(float)``:                                        || ``Floor`` (1.6) = 1                        |\n|   converts from float to int ``Floor`` (1.2) = 1         || ``Floor`` (-1.2) = -2                      |\n|                                                          || ``Floor`` (-1.6) = -2                      |\n+----------------------------------------------------------+---------------------------------------------+\n| ``Ceil(float)``:                                         || ``Ceil`` (1.6) = 2.0                       |\n|   converts from float to int ``Ceil`` (1.2) = 2.0        || ``Ceil`` (-1.2) = -1                       |\n|                                                          || ``Ceil`` (-1.6) = -1                       |\n+----------------------------------------------------------+---------------------------------------------+\n| ``Round(float)``:                                        || ``Round`` (1.6) = 2                        |\n|   converts from float to int ``Round`` (1.2) = 1         || ``Round`` (-1.2) = -1                      |\n|                                                          || ``Round`` (-1.6) = -2                      |\n+----------------------------------------------------------+---------------------------------------------+\n| ``Int(float)``:                                          || ``Int`` (1.2) = 1                          |\n|   Converts from float to int (round towards zero).       || ``Int`` (1.6) = 1                          |\n|                                                          || ``Int`` (-1.2) = -1                        |\n|                                                          || ``Int`` (-1.6) = -1                        |\n+----------------------------------------------------------+---------------------------------------------+\n| ``Float(int)``:                                          | ``Float`` (1) = 1.0                         |\n|   Converts int to float                                  |                                             |\n+----------------------------------------------------------+---------------------------------------------+\n| ``Frac(float)``:                                         || ``Frac`` (3.7) = 0.7                       |\n|   Returns the fractional portion of the value provided.  || ``Frac`` (-1.8) = -0.8                     |\n+----------------------------------------------------------+---------------------------------------------+\n| ``Abs(integer)`` / ``Abs(float)``:                       || ``Abs`` (-6) = 6                           |\n|   Returns the absolute value (returns float for float,   || ``Abs`` (-1.8) = 1.8                       |\n|   integer for integer).                                  |                                             |\n+----------------------------------------------------------+---------------------------------------------+\n| ``Sign(int)`` / ``Sign(float)``:                         || ``Sign`` (-3.5) = -1                       |\n|   Returns sign of value (1, 0 or -1).                    || ``Sign`` (3.5) = 1                         |\n|                                                          || ``Sign`` (0) = 0                           |\n+----------------------------------------------------------+---------------------------------------------+\n| ``HexValue(string)``:                                    || ``HexValue`` (\"FF00\") = 65280              |\n|   Evaluates string as hexadecimal value.                 || ``HexValue`` (\"FFFFFFFF\") = -1             |\n|   Result is always 32-bits.                              |                                             |\n+----------------------------------------------------------+---------------------------------------------+\n| ``HexValue64(string)``:                                  || ``HexValue64`` (\"FF00\") = 65280            |\n|   Evaluates string as hexadecimal value.                 || ``HexValue64`` (\"FFFFFFFF\") = 4294967295   |\n|   Result is always 64-bits.                              |                                             |\n+----------------------------------------------------------+---------------------------------------------+\n| ``Sin(float)``:                                          || ``Sin`` (Pi()/4) = 0.707                   |\n|   Returns the sine of the argument (assumes it is        || ``Sin`` (Pi()/2) = 1.0                     |\n|   radians).                                              |                                             |\n+----------------------------------------------------------+---------------------------------------------+\n| ``Cos(float)``:                                          || ``Cos`` (Pi()/4) = 0.707                   |\n|   Returns the cosine of the argument (assumes it is      || ``Cos`` (Pi()/2) = 0.0                     |\n|   radians).                                              |                                             |\n+----------------------------------------------------------+---------------------------------------------+\n| ``Pi()``:                                                | d = Pi() # d == 3.141593                    |\n|   Returns the value of the \"pi\" constant (the ratio of   |                                             |\n|   a circle's perimeter to its diameter).                 |                                             |\n+----------------------------------------------------------+---------------------------------------------+\n| ``Log(float)``:                                          || ``Log`` (1) = 0.0                          |\n|   Returns the natural (base-e) logarithm of the argument.|| ``Log`` (10) = 2.30259                     |\n+----------------------------------------------------------+---------------------------------------------+\n| ``Exp(float)``:                                          || ``Exp`` (1) = 2.718282                     |\n|   Returns the natural (base-e) exponent of the argument. || ``Exp`` (0) = 1.0                          |\n+----------------------------------------------------------+---------------------------------------------+\n| ``Pow(float base, float power)``:                        || ``Pow`` (2, 3) = 8                         |\n|   Returns \"base\" raised to the power indicated by the    || ``Pow`` (3, 2) = 9                         |\n|   second argument.                                       || ``Pow`` (3.45, 1.75) = 8.7334              |\n+----------------------------------------------------------+---------------------------------------------+\n| ``Sqrt(float)``:                                         || ``Sqrt`` (1) = 1.0                         |\n|   Returns the square root of the argument.               || ``Sqrt`` (2) = 1.4142                      |\n+----------------------------------------------------------+---------------------------------------------+\n| ``Rand([int max] [, bool scale] [, bool seed])``:        | ``Rand`` (100) =                            |\n|   returns random integer between 0 and max.              |    integer number between 0 and 99,         |\n|                                                          |    all number equally probable.             |\n|  defaults:                                               |                                             |\n|                                                          | ``Rand`` (32767, False) =                   |\n|  ``max`` = 32768,  scale = TRUE,  seed = FALSE           |    integer number between 0 and 32766,      |\n|                                                          |    with 0 two times more probable           |\n|  ``Scale`` = FALSE, modulus mode, (Rand(32768)%limit)    |    than the other numbers.                  |\n|                                                          |                                             |\n|  ``Seed`` = TRUE, use time as seed                       |                                             |\n+----------------------------------------------------------+---------------------------------------------+\n| ``Spline(float X,  x1, y1, x2, y2, ...., bool \"cubic\")`` | ``Spline`` (5, 0,0, 10,10, 20,0, false) = 5 |\n|   **v2.5**:                                              |                                             |\n|                                                          |                                             |\n|   Interpolates the Y value at point X using the control  | ``Spline`` (5, 0,0, 10,10, 20,0, true) = 7  |\n|   points x1/y1, ...                                      |                                             |\n|                                                          |                                             |\n|   There have to be at least 2 x/y-pairs.                 |                                             |\n|   The interpolation can be cubic (the result is a        |                                             |\n|   spline) or linear (the result is a polygon)            |                                             |\n+----------------------------------------------------------+---------------------------------------------+\n\n\nString functions\n~~~~~~~~~~~~~~~~\n\n+---------------------------------------------------------------+---------------------------------------------------------------------------------------------+\n| ``UCase(string)``: returns the string in uppercase            | ``UCase`` (\"AviSynth\") = \"AVISYNTH\"                                                         |\n+---------------------------------------------------------------+---------------------------------------------------------------------------------------------+\n| ``LCase(string)``: returns the string in lowercase            | ``LCase`` (\"AviSynth\") = \"avisynth\"                                                         |\n+---------------------------------------------------------------+---------------------------------------------------------------------------------------------+\n| ``RevStr(string)``: returns the string in reverse             | ``RevStr`` (\"AviSynth\") = \"htnySivA\"                                                        |\n+---------------------------------------------------------------+---------------------------------------------------------------------------------------------+\n| ``StrLen(string)``: returns the length of string              | ``StrLen`` (\"AviSynth\") = 8                                                                 |\n+---------------------------------------------------------------+---------------------------------------------------------------------------------------------+\n| ``Findstr(string1, string2)``:                                | ``Findstr`` (\"AviSynth\",\"syn\") = 4                                                          |\n|   returns the offset of string2 inside string1. The search is |                                                                                             |\n|   case-sensitive.                                             |                                                                                             |\n+---------------------------------------------------------------+---------------------------------------------------------------------------------------------+\n| ``LeftStr(string, length)`` / ``RightStr(string, length)``:   | ``LeftStr`` (\"AviSynth\",3) = \"Avi\"                                                          |\n|   returns left or right portion of string specified by length |                                                                                             |\n+---------------------------------------------------------------+---------------------------------------------------------------------------------------------+\n| ``MidStr(string, start [, length])``:                         | ``MidStr`` (\"AviSynth\",3,2) = \"iS\"                                                          |\n|   returns portion of string starting at start (for the first  |                                                                                             |\n|   character start=1) for the number of characters specified   |                                                                                             |\n|   by length or to the end.                                    |                                                                                             |\n+---------------------------------------------------------------+---------------------------------------------------------------------------------------------+\n| ``Chr(int)``: returns the ASCII character **v2.5**            | ``Chr`` (34) returns the quote character                                                    |\n+---------------------------------------------------------------+---------------------------------------------------------------------------------------------+\n| ``Time(string)``:                                             || Codes for output formatting:                                                               |\n|   returns a string with the current system time formatted as  ||   %a Abbreviated weekday name                                                              |\n|   defined by the string **v2.5**                              ||   %A Full weekday name                                                                     |\n|                                                               ||   %b Abbreviated month name                                                                |\n|                                                               ||   %B Full month name                                                                       |\n|                                                               ||   %c Date and time representation appropriate for locale                                   |\n|                                                               ||   %d Day of month as decimal number (01 - 31)                                              |\n|                                                               ||   %H Hour in 24-hour format (00 - 23)                                                      |\n|                                                               ||   %I Hour in 12-hour format (01 - 12)                                                      |\n|                                                               ||   %j Day of year as decimal number (001 - 366)                                             |\n|                                                               ||   %m Month as decimal number (01 - 12)                                                     |\n|                                                               ||   %M Minute as decimal number (00 - 59)                                                    |\n|                                                               ||   %p Current locale's A.M./P.M. indicator for 12-hour clock                                |\n|                                                               ||   %S Second as decimal number (00 - 59)                                                    |\n|                                                               ||   %U Week of year as decimal number,                                                       |\n|                                                               ||      with Sunday as first day of week (00 - 53)                                            |\n|                                                               ||   %w Weekday as decimal number (0 - 6; Sunday is 0)                                        |\n|                                                               ||   %W Week of year as decimal number,                                                       |\n|                                                               ||      with Monday as first day of week (00 - 53)                                            |\n|                                                               ||   %x Date representation for current locale                                                |\n|                                                               ||   %X Time representation for current locale                                                |\n|                                                               ||   %y Year without century, as decimal number (00 - 99)                                     |\n|                                                               ||   %Y Year with century, as decimal number                                                  |\n|                                                               ||   %z, %Z Time-zone name or abbreviation; no characters if                                  |\n|                                                               ||          time zone is unknown                                                              |\n|                                                               ||   %% Percent sign                                                                          |\n|                                                               |                                                                                             |\n|                                                               || The # flag may prefix any formatting code. In that case,                                   |\n|                                                               || the meaning of the format code is changed as follows.                                      |\n|                                                               |                                                                                             |\n|                                                               ||   %#a, %#A, %#b, %#B, %#p, %#X, %#z, %#Z, %#% # flag is ignored.                           |\n|                                                               ||   %#c Long date and time representation, appropriate for current locale.                   |\n|                                                               ||       For example: \"Tuesday, March 14, 1995, 12:41:29\".                                    |\n|                                                               ||   %#x Long date representation, appropriate to current locale.                             |\n|                                                               ||       For example: \"Tuesday, March 14, 1995\".                                              |\n|                                                               ||   %#d, %#H, %#I, %#j, %#m, %#M, %#S, %#U, %#w, %#W, %#y, %#Y Remove leading zeros (if any).|\n+---------------------------------------------------------------+---------------------------------------------------------------------------------------------+\n\nConversions\n~~~~~~~~~~~\n\n+---------------------------------------------------------------+-------------------------------------------------------------------+\n| ``Value(string)``: Returns the value of an string.            | ``Value`` ( \"-2.7\" ) = -2.7                                       |\n+---------------------------------------------------------------+-------------------------------------------------------------------+\n| ``String(float / int / string, format_string)``:              || e.g. ``Subtitle`` (\"Clip height is \" + ``String`` (last.height) )|\n|   converts a number to a string. If the variable is           || ``String`` (1.23, \"%f\") = '1.23'                                 |\n|   float or integer, it converts it to a float and             || ``String`` (1.23, \"%5.1f\") = ' 1.2'                              |\n|   uses the format_string to convert it to a string.           || ``String`` (1.23, \"%1.3f\") = '1.230'                             |\n|                                                               |                                                                   |\n|   The syntax of the format_string is as follows:              |                                                                   |\n|                                                               |                                                                   |\n|   %[flags][width][.precision]f                                |                                                                   |\n|                                                               |                                                                   |\n||     width: the minimum width (the string is never truncated) |                                                                   |\n||     precision: the number of digits printed                  |                                                                   |\n||     flags:                                                   |                                                                   |\n||       ``-`` left align (instead right align)                 |                                                                   |\n||       ``+`` always print the +/- sign                        |                                                                   |\n||       ``0`` padding with leading zeros                       |                                                                   |\n||       ``' '`` print a blank instead of a \"+\"                 |                                                                   |\n||       ``#`` always print the decimal point                   |                                                                   |\n|                                                               |                                                                   |\n+---------------------------------------------------------------+-------------------------------------------------------------------+\n\nVersion checking functions\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n+---------------------------------------------+---------------------------------------------------------------------+\n| ``VersionNumber()``:                        | ``VersionNumber()`` = 2.56                                          |\n|   Returns AviSynth version number as float  |                                                                     |\n+---------------------------------------------+---------------------------------------------------------------------+\n| ``VersionString()``:                        | ``VersionString()`` = \"AviSynth 2.56, build:Oct 28 2005 [18:43:54]\" |\n|   Returns AviSynth version info as string   |                                                                     |\n|   (first line used in ``Version`` command). |                                                                     |\n+---------------------------------------------+---------------------------------------------------------------------+\n\nTest functions\n~~~~~~~~~~~~~~\n\n| ``IsBool(var)``\n| ``IsInt(var)``\n| ``IsLongStrict(var)``\n| ``IsFloat(var)``\n| ``IsFloatfStrict(var)``\n| ``IsString(var)``\n| ``IsClip(var)``\n\nOther functions\n~~~~~~~~~~~~~~~\n\n| ``Select`` (index, item0 [, item1...]): Returns item selected by the index (0=item0). Items can be any variable or clip and can even be mixed.\n| ``Defined`` (var): for defining optional parameters in user-defined functions.\n| ``Default`` (x, d): returns x if Defined(x), d otherwise.\n| ``Exist`` (filename): returns TRUE or FALSE after checking if the file exists.\n| ``NOP`` (): returns NULL, provided mainly for conditional execution with non-return value items such as import and no \"else\" condition desired.\n| ``Eval`` (string), ``Apply`` (func-string, arg,...): ``Eval`` (\"f(x)\") is equivalent to ``f(x)`` is equivalent to ``Apply`` (\"f\", x)\n\n::\n\n    You can use Eval for something like:\n    settings = \"352, 288\"\n    Eval( \"BicubicResize(\" + settings + \")\" )\n\n``Import`` (filename): evals contents of another AviSynth script (imports the text of another script)\n\n| For error reporting and catching bad input to user-defined function you can use:\n| ``Assert`` (bool, string error-message)\n\n``Try ... Catch``: this is a function for checking if an error WILL arise:\n::\n\n    Try {\n      AviSource(\"file.avi\")\n    }\n    Catch(err_msg) {\n       Blackness.Subtitle(err_msg)\n    }\n\n--------\n\n\n.. _runtime-functions:\n\nRuntime Functions\n-----------------\n\nThere are now :doc:`Conditional Filters <../corefilters/conditionalfilter>` which evaluate scripts when a frame is\nprocessed, so you can change variables on a per-frame basis.\nTo have more applications there have to be :ref:`Runtime Functions <conditional-runtime-functions>` which\nevaluate the content of the clip and return a value. **v2.5**\n\nA simple example is to calculate the average luma for each frame and display\nit.\n::\n\n    Version()      # Generate a test clip\n    ConvertToYV12()# We need YV12\n    FadeIn(10)     # Make the luma variable so\n                   # we can see something happen\n\n                   # Evaluate Subtitle(...) for each frame\n                   # the output of AverageLuma is converted to\n                   # a string and Subtitled on the input clip\n    ScriptClip(\" Subtitle(String(AverageLuma())) \")\n    ConvertToRgb   # View it in RGB\n\n--------\n\n\nControl Functions\n------------------\n\n:doc:`AviSynth Syntax - Global options and resource control <syntax_internal_functions_global_options>`\nand\n:doc:`AviSynth+ Syntax - Multithreading functions <syntax_internal_functions_multithreading_new>`\n\nfor old Avisynth 2.6 see\n\n:doc:`AviSynth Syntax - Global options and resource control <syntax_internal_functions_multithreading>`.\n\nThis section is mainly historical.\n\n``SetPlanarLegacyAlignment`` (clip, bool): Set alignment mode for planar\nframes. **v2.5.6**\n\nSome older plugins illegally assume the layout of video frames in memory.\nThis special filter forces the memory layout of planar frames to be\ncompatible with prior version of AviSynth. The filter works on the GetFrame()\ncall stack, so it effects filters **before** it in the script.\n\n*Example : Using an older version of Mpeg2Source()*\n::\n\n    LoadPlugin(\"...\\Mpeg2Decode.dll\")\n    Mpeg2Source(\"test.d2v\")         # A plugin that illegally\n                                    # assumes the layout of memory\n    SetPlanarLegacyAlignment(true)  # Set legacy memory alignment\n                                    # for prior statements\n    ConvertToYUY2()                 # Statements thru to the end\n                                    # of the script have advanced\n    ...                             # memory alignment.\n\n``SetWorkingDir`` (string): Sets the default directory for Avisynth. **v2**\n\nThis is primarily for easy loading of source clips, etc. Does not affect\nplugin autoloading.\n\n    ``Return value: 0 if successful, -1 otherwise.``\n\n| ``global OPT_AllowFloatAudio=True``: **v2.57**\n| This option enables WAVE_FORMAT_IEEE_FLOAT audio output. The default is to autoconvert Float audio to 16 bit.\n\n| ``global OPT_UseWaveExtensible=True``: **v2.58**\n| This option enables WAVE_FORMAT_EXTENSIBLE audio output. The default is WAVE_FORMAT_EX.\n\nNote: The default DirectShow component for .AVS files, \"AVI/WAV File Source\",\ndoes not correctly implement WAVE_FORMAT_EXTENSIBLE processing, so many\napplication may not be able to detect the audio track. There are third party\nDirectShow readers that do work correctly. Intermediate work files written\nusing the AVIFile interface for later DirectShow processing will work\ncorrectly if they use the DirectShow \"File Source (async)\" component or\nequivalent.\n\n--------\n\n\nClip Properties\n---------------\n\nThese functions take a clip as input and you get back a property of the clip.\n\nSince Avisynth 2.6 many more property checkers are available (more color spaces, audio channels), \nsee the relevant sections.\n\nSee :doc:`AviSynth Clip properties <syntax_clip_properties>`.\n\n+------------------------------------------+--------------------------------------------------------+\n| ``Width(clip)``                          | Returns the width of the clip in pixels (type: int).   |\n+------------------------------------------+--------------------------------------------------------+\n| ``Height(clip)``                         | Returns the height of the clip in pixels (type: int).  |\n+------------------------------------------+--------------------------------------------------------+\n| ``Framecount(clip)``                     | Returns the number of frames of the clip (type: int).  |\n+------------------------------------------+--------------------------------------------------------+\n| ``Framerate(clip)``                      | Returns the number of frames per seconds of the clip.  |\n|                                          | (type: float)                                          |\n+------------------------------------------+--------------------------------------------------------+\n| ``FramerateNumerator(clip)``             |                                                        |\n+------------------------------------------+--------------------------------------------------------+\n| ``FramerateDenominator(clip)``           |                                                        |\n+------------------------------------------+--------------------------------------------------------+\n| ``Audiorate(clip)``                      | Returns the sample rate of the audio of the clip.      |\n+------------------------------------------+--------------------------------------------------------+\n| ``Audiolength(clip)``                    | Returns the number of samples of the audio of the clip |\n|                                          | (type: int, since 3.7.4 exact 64 bit number).          |\n|                                          | On pre-3.7.4 be aware of possible overflow on very     |\n|                                          | long clips ( 2^31 samples limit - 32 bit integer).     |\n+------------------------------------------+--------------------------------------------------------+\n| ``AudiolengthF(clip)``                   | Returns the number of samples of the audio of the clip |\n|                                          | (type: float, since 3.7.4 a 64 bit double, still not   |\n|                                          | exact and may overflow, use Audiolength)               |\n+------------------------------------------+--------------------------------------------------------+\n| ``Audiochannels(clip)``                  | Returns the number of audio channels of the clip.      |\n+------------------------------------------+--------------------------------------------------------+\n| ``Audiobits(clip)``                      | Returns the audio bit depth of the clip.               |\n+------------------------------------------+--------------------------------------------------------+\n| ``IsAudioFloat(clip)``                   | Returns true if the bit depth of the audio of the clip |\n|                                          | is float.                                              |\n+------------------------------------------+--------------------------------------------------------+\n| ``IsAudioInt(clip)``                     | Returns true if the bit depth of the audio of the clip |\n|                                          | an integer.                                            |\n+------------------------------------------+--------------------------------------------------------+\n| ``IsRGB(clip)``                          | Returns true if the clip is RGB, false otherwise       |\n|                                          | (type: bool).                                          |\n+------------------------------------------+--------------------------------------------------------+\n| ``IsRGB24(clip)``                        | Returns true if the clip is RGB24, false otherwise     |\n|                                          | (type: bool).                                          |\n+------------------------------------------+--------------------------------------------------------+\n| ``IsRGB32(clip)``                        | Returns true if the clip is RGB32, false otherwise     |\n|                                          | (type: bool).                                          |\n+------------------------------------------+--------------------------------------------------------+\n| ``IsYUY2(clip)``                         | Returns true if the clip is YUY2, false otherwise      |\n|                                          | (type: bool).                                          |\n+------------------------------------------+--------------------------------------------------------+\n| ``IsYV12(clip)``                         | Returns true if the clip is YV12, false otherwise      |\n|                                          | (type: bool).                                          |\n+------------------------------------------+--------------------------------------------------------+\n| ``IsYUV(clip)``                          | Returns true if the clip is YUV, false otherwise       |\n|                                          | (type: bool).                                          |\n+------------------------------------------+--------------------------------------------------------+\n| ``IsPlanar(clip)``                       | Returns true if the clip color format is planar,       |\n|                                          | false otherwise (type: bool).                          |\n+------------------------------------------+--------------------------------------------------------+\n| ``IsInterleaved(clip)``                  | Returns true if the clip color format is interleaved,  |\n|                                          | false otherwise (type: bool).                          |\n+------------------------------------------+--------------------------------------------------------+\n| ``IsFieldBased(clip)``                   |                                                        |\n+------------------------------------------+--------------------------------------------------------+\n| ``IsFrameBased(clip)``                   |                                                        |\n+------------------------------------------+--------------------------------------------------------+\n| ``GetParity(clip, int \"n\")``             | Returns true if frame n (default 0) is top field of    |\n|                                          | fieldbased clip, or it is full frame with top field    |\n|                                          | first of framebased clip (type: bool).                 |\n+------------------------------------------+--------------------------------------------------------+\n| ``HasAudio(clip)``                       | Returns true if the clip has audio, false otherwise    |\n|                                          | (type: bool).                                          |\n+------------------------------------------+--------------------------------------------------------+\n| ``HasVideo(clip)``                       | Returns true if the clip has video, false otherwise    |\n|                                          | (type: bool).                                          |\n+------------------------------------------+--------------------------------------------------------+\n\nDon't forget: you can use the Properties with the implicit variable LAST or in OOP-notation:\n::\n\n    BilinearResize(Width/2, Height/2)\n       is the same as\n    BilinearResize(Width(Last)/2, Height(Last)/2)\n       is the same as\n    BilinearResize(Last.Width / 2, Last.Height / 2)\n\n--------\n\n\nUser-Defined Functions\n----------------------\n\nYou can define your own functions. This is best explained by an example:\n::\n\n    Function NTSC2PAL( clip c) {\n        Assert(c.height == 480, \\\n               \"NTSC2PAL: input clip must have 480 scan\n               lines\")\n        Bob(c, height=576)\n        return Weave()\n    }\n\nEven recursive functions can be defined.\n::\n\n    function TRANSITION(clip clip, int start, int expo, int overlap)\n    {\n       return ( start >= clip.framecount-expo ?\n    \\      Trim(clip,start,0) :\n    \\      Dissolve(Trim(clip,start,start+expo-1),\n    \\         TRANSITION(clip,start+expo,expo,overlap),\n    \\         overlap\n    \\              )\n    \\         )\n    }\n\n--------\n\n\n.. _multiclip:\n\nFunctions with more than one input clip\n---------------------------------------\n\nThere are some functions which combine two or more clips in different ways.\nHow the video content is calculated is described for each function, but here\nis a summary which properties the result clip will have.\n\nThe input clips must always have the same color format and - with the\nexception of *Layer* - the same dimensions.\n\n+------------------------------------+---------------------+--------------------------------+---------------------+------------------------+---------------------+\n|                                    | frame-rate          | frame-count                    |                     | audio content          | audio sampling rate |\n+====================================+=====================+================================+=====================+========================+=====================+\n| **AlignedSplice, UnalignedSplice** | first clip          | sum of all clips               |                     | see filter description | first clip          |\n+------------------------------------+                     +--------------------------------+---------------------+------------------------+                     |\n| **Dissolve**                       |                     | sum of all clips minus the     |                     | see filter description |                     |\n|                                    |                     | overlap                        |                     |                        |                     |\n+------------------------------------+                     +--------------------------------+---------------------+------------------------+                     |\n| **Merge, MergeLuma, MergeChroma,** |                     | first clip                     | the last frame of   | first clip             |                     |\n| **Merge(A)RGB**                    |                     |                                | the shorter clip    |                        |                     |\n|                                    |                     |                                | is repeated until   |                        |                     |\n+------------------------------------+                     |                                | the end of the clip |                        |                     |\n| **Layer**                          |                     |                                |                     |                        |                     |\n+------------------------------------+                     +--------------------------------+                     |                        |                     |\n| **Subtract**                       |                     | longer clip                    |                     |                        |                     |\n+------------------------------------+                     |                                |                     |                        |                     |\n| **StackHorizontal, StackVertical** |                     |                                |                     |                        |                     |\n+------------------------------------+---------------------+--------------------------------+                     |                        |                     |\n| **Interleave**                     | (fps of first clip) |                                |                     |                        |                     |\n|                                    | x                   |                                |                     |                        |                     |\n|                                    | (number of clips)   | N x frame-count of longer clip |                     |                        |                     |\n+------------------------------------+---------------------+--------------------------------+---------------------+------------------------+---------------------+\n\nAs you can see the functions are not completely symmetric but take some\nattributes from the FIRST clip.\n\n\n--------\n\n\n.. _syntax-rst-plugins:\n\nPlugins\n-------\n\nWith these functions you can add external functions to AviSynth.\n\n``LoadPlugin(\"filename\" [, ...])``\n\nLoads one or more external avisynth plugins (DLLs).\n\nAvisynth+ can automatically detect and load any C or CPP plugins by a simple LoadPlugin.\n\n\n--------\n\n``LoadVirtualDubPlugin(\"filename\", \"filtername\", preroll)``\n\nThis loads a plugin written for VirtualDub. \"filename\" is the name of the\n.vdf file. After calling this function, the filter will be known as\n\"filtername\" in avisynth. VirtualDub filters only supports RGB32. If the\nvideo happens to be in RGB24-format, then you must use ``ConvertToRGB32``\n(``ConvertToRGB`` won't suffice).\n\nSome filters output depends on previous frames; for those preroll should be\nset to at least the number of frames the filter needs to pre-process to fill\nits buffers and/or updates its internal variables.\n\n\n--------\n\n``LoadVFAPIPlugin(\"filename\", \"filtername\")``\n\nThis allows you to use VFAPI plugins (TMPGEnc import plugins).\n\n\n--------\n\n| ``LoadCPlugin(\"filename\" [, ...])``\n| ``Load_Stdcall_Plugin(\"filename\" [, ...])``\n\nLoads so called Avisynth C-plugins (DLLs).\nLoad_Stdcall_Plugin() is an alias for LoadCPlugin().\nC-plugins are created on pure C language and use special \"AviSynth C API\"\n(unlike ordinary Avisynt plugins which are created with MS C++). C-plugins\nmust be loaded with LoadCPlugin() or Load_Stdcall_Plugin().\n\nKevin provides a LoadCPlugin.dll that overloads the LoadCPlugin() verb to\nsupport plugins compiled using the C subroutine calling sequence, use\nLoad_Stdcall_Plugin() to load stdcall calling sequence plugins when using\nKevins version. Advice: keep these plugins outside your auto plugin loading\ndirectory to prevent crashes. [`discussion`_] [`AVISynth C API (by\nkevina20723)`_]\n\n--------\n\n\nPlugin autoload and name precedence **v2**\n------------------------------------------\n\nIt is possible to put all plugins and script files with user-defined\nfunctions or (global) variables in a directory from where all files with the\nextension .AVSI (**v2.08, v2.5**, the type was .AVS in **v2.05-2.07**) and\n.DLL are loaded at startup, unloaded and then loaded dynamically as the\nscript needs them.\n\n.AVSI scripts in this directory should only contain function definitions and\nglobal variables, no main processing section (else strange errors may occur),\nit also is not recommended to put other files in that directory.\n\nThe directory is stored in the registry (the registry key has changed for\n**v2.5**). You can use double-clicking a .REG-file with the following lines\nto set the path (of course inserting your actual path):\n::\n\n    REGEDIT4\n\n    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Avisynth]\n    \"plugindir2_5\"=\"c:\\\\program files\\\\avisynth 2.5\\\\plugins\"\n\nThe order in which function names take precedence is as follows: ::user-\ndefined function (always have the highest priority)\n::\n\n       plugin-function (have higher priority than built-in\n       functions, they will override a built-in function)\n          built-in function\n\nInside those groups the function loaded at last takes precedence, there is no\nerror in a namespace conflict.\n\n\nPlugin autoload and conflicting function names **v2.55**\n--------------------------------------------------------\n\nStarting from v2.55 there is DLLName_function() naming convention support. The problem is that\ntwo plugins can have different functions which are named the same. To call\nthe needed one, DLLName_function() support is added. It auto-generates the\nadditional names both for auto-loaded plugins and for plugins loaded with\nLoadPlugin.\n\n**Some examples:**\n\n::\n\n    # using fielddeinterlace from decomb510.dll\n    AviSource(\"D:\\captures\\jewel.avi\")\n    decomb510_fielddeinterlace(blend=false)\n\nSuppose you have  the plugins mpeg2dec.dll and mpeg2dec3.dll in your auto\nplugin dir, and you want to load a d2v file with mpeg2dec.dll (which outputs\nYUY2):\n\n::\n\n    # using mpeg2source from mpeg2dec.dll\n    mpeg2dec_mpeg2source(\"F:\\From_hell\\from_hell.d2v\")\n\nor with mpeg2dec3.dll (which outputs YV12):\n\n::\n\n    # using mpeg2source from mpeg2dec3.dll\n    mpeg2dec3_mpeg2source(\"F:\\From_hell\\from_hell.d2v\")\n\n\n\nChangelog\n~~~~~~~~~\n+----------------+------------------------------------------------------------+\n| Version        | Changes                                                    |\n+================+============================================================+\n| Avisynth 3.7.4 | | Added 64-bit types, integer long, floating point double  |\n|                | | Add \"L\" suffixed hexadecimal notation                    |\n|                | | Add HexValue64 function                                  |\n|                | | Add IsFloatfStrict() and IsLongStrict()                  |\n|                | | Add Double(), FloatF(), Long(), IntI() type casts        |\n|                | | AudioLength returns 64 bit integer (exact size)          |\n|                | | AudioLengthF returns 64 bit double                       |\n+----------------+------------------------------------------------------------+\n\n$Date: 2025/02/05 10:22:00 $\n\n.. _discussion: http://forum.doom9.org/showthread.php?s=&threadid=58840\n.. _AVISynth C API (by kevina20723):\n    http://kevin.atkinson.dhs.org/avisynth_c/\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_clip_properties.rst",
    "content": "\nAviSynth Clip properties\n========================\n\nYou can access clip properties in AVS scripts. For example, if the variable\n*clip* holds a video clip, then *clip.height* is its height in pixels,\n*clip.framecount* is its length in frames, and so on. Clip properties can be\nmanipulated just like :doc:`script variables <syntax_script_variables>` (see the :doc:`AviSynth Syntax <syntax_ref>` for\nmore), except that they cannot be l-values in C-terminology.\n\nThe full list of properties:\n\n-   Width (clip)\n\nReturns the width of the clip in pixels (type: int).\n\n-   Height (clip)\n\nReturns the height of the clip in pixels (type: int).\n\n-   FrameCount (clip)\n\nReturns the number of frames of the clip (type: int).\n\n-   FrameRate (clip)\n\nReturns the number of frames per seconds of the clip (type: float). The\nframerate is internally stored as a ratio though and more about it can be\nread :doc:`here[1] <../corefilters/fps>`.\n\n-   FrameRateNumerator (clip) (v2.55)\n\nReturns the numerator of the number of frames per seconds of the clip\n(type: int).\n\n-   FrameRateDenominator (clip) (v2.55)\n\nReturns the denominator of the number of frames per seconds of the clip\n(type: int).\n\n-   AudioRate (clip)\n\nReturns the sample rate of the audio of the clip (type: int).\n\n-   AudioLength (clip) (v2.51, v3.7.4)\n\nReturns the number of samples of the audio of the clip.\n(type: int, since 3.7.4 exact 64 bit number).\nOn pre-3.7.4 be aware of possible overflow on very\nlong clips ( 2^31 samples limit - 32 bit integer).\n\n-   AudioLengthLo (clip [, int]) (v2.60)\n\nReturns the number of samples of the audio of the clip modulo int. int is\n1,000,000,000 by default (type: int).\n\n-   AudioLengthHi (clip [, int]) (v2.60)\n\nReturns the number of samples of the audio of the clip divided by int\n(truncated to nearest integer). int is 1,000,000,000 by default (type: int).\n\n-   AudioLengthS (clip) (v2.60)\n\nReturns a string formated with the total number of samples of the audio of\nthe clip (type: string).\n\n-   AudioLengthF (clip) (v2.55, v3.7.4)\n\nReturns the number of samples of the audio of the clip.\n(type: float, since 3.7.4 a 64 bit double, still not exact and may overflow, \nuse Audiolength) \n\n-   AudioDuration (clip) (v2.60)\n\nReturns the duration in seconds of the audio of the clip (type: float).\n\n-   AudioChannels (clip)\n\nReturns the number of audio channels of the clip (type: int).\n\n-   AudioBits (clip)\n\nReturns the audio bit depth of the clip (type: int).\n\n-   IsAudioFloat (clip) (v2.55)\n\nReturns true if the audio format of the clip is float (type: bool).\n\n-   IsAudioInt (clip) (v2.55)\n\nReturns true if the audio format of the clip is an integer type (type: bool).\n\n-   IsRGB (clip)\n\nReturns true if the clip is `RGB`_, false otherwise (type: bool).\n\n-   IsPlanarRGB (clip)\n\nReturns true if the clip is planar RGB, false otherwise (type: bool).\n\n-   IsPlanarRGBA (clip)\n\nReturns true if the clip is planar RGBA, false otherwise (type: bool).\n\n-   IsRGB24 (clip) (v2.07)\n\nReturns true if the clip is `RGB24`_, false otherwise (type: bool).\n\n-   IsRGB32 (clip) (v2.07)\n\nReturns true if the clip is `RGB32`_, false otherwise (type: bool).\n\n-   IsRGB48 (clip) (Avisynth+)\n\nReturns true if the clip is RGB48, false otherwise (type: bool).\n\n-   IsRGB64 (clip) (Avisynth+)\n\nReturns true if the clip is RGB64, false otherwise (type: bool).\n\n-   IsYUV (clip) (v2.54)\n\nReturns true if the clip is `YUV`_, false otherwise (type: bool).\n\n-   IsYUVA (clip) (Avisynth+)\n\nReturns true if the clip is YUVA (YUV + alpha channel), false \notherwise (type: bool).\n\n-   IsY8 (clip) (2.60)\n\nReturns true if the clip is `Y8`_, false otherwise (type: bool).\n\n-   IsY (clip) (Avisynth+)\n\nReturns true if the clip is Y (like Y8, but bit depth independent)\ngrey scale, false otherwise (type: bool).\n\n-   IsYUY2 (clip)\n\nReturns true if the clip is `YUY2`_, false otherwise (type: bool).\n\n-   IsYV12 (clip) (v2.52)\n\nReturns true if the clip is `YV12`_, false otherwise (type: bool).\n\n-   Is420 (clip) (Avisynth+)\n\nReturns true if the clip is 4:2:0 (like IsYV12, but bit depth \nindependently), false otherwise (type: bool).\n\n-   IsYV16 (clip) (v2.60)\n\nReturns true if the clip is `YV16`_, false otherwise (type: bool).\n\n-   Is422 (clip) (Avisynth+)\n\nReturns true if the clip is 4:2:2 (like Is YV16, but bit depth\nindependently), false otherwise (type: bool).\n\n-   IsYV24 (clip) (v2.60)\n\nReturns true if the clip is `YV24`_, false otherwise (type: bool).\n\n-   Is444 (clip) (Avisynth+)\n\nReturns true if the clip is 4:4:4 (like IsYV24, but bit depth\nindependently), false otherwise (type: bool).\n\n-   IsYV411 (clip) (v2.60)\n\nReturns true if the clip is `YV411`_, false otherwise (type: bool).\n\n-   PixelType (clip) (v2.60)\n\nReturns the name of the pixel format (type: string).\n\n-   IsFieldBased (clip)\n\nReturns true if the clip is field-based (type: bool). What this means is\nexplained :doc:`here[2] <../advancedtopics/interlaced_fieldbased>`.\n\n-   IsFrameBased (clip)\n\nReturns true if the clip is frame-based (type: bool). What this means is\nexplained :doc:`here[2] <../advancedtopics/interlaced_fieldbased>`.\n\n-   IsPlanar (clip) (v2.52)\n\nReturns true if the clip is `planar`_, false otherwise (type: bool).\n\n-   IsInterleaved (clip) (v2.52)\n\nReturns true if the clip color format is Interleaved, false otherwise (type:\nbool).\n\n-   GetParity (clip, int n)\n\nReturns true if frame n (default 0) is top field of field-based clip, or it\nis full frame with top field first of frame-based clip (type: bool).\n\n-   HasAudio (clip) (v2.56)\n\nReturns true if the clip has audio, false otherwise (type: bool).\n\n-   HasVideo (clip) (v2.56)\n\nReturns true if the clip has video, false otherwise (type: bool).\n\n-   HasVideo (clip) (v2.56)\n\nReturns true if the clip has video, false otherwise (type: bool).\n\n-   ComponentSize (clip) (Avisynth+)\n\nReturns 1 for 8 bit, 2 for 10-16 bits, 4 for 32 bit float pixel \nformats (type: int).\n\n-   BitsPerComponent (clip) (Avisynth+)\n\nReturns 8, 10, 12, 14, 16 or 32: the actual bit depth of the video format\n(type: int).\n\n-   NumComponents (clip) (Avisynth+)\n\nReturns 1 for greyscale, 3 for alpha-less RGB and YUV formats, 4 for formats\nwith alpha channel: YUVA, planar RGBA, RGB32 or RGB64 (type: int).\n\n-   HasAlpha (clip) (Avisynth+)\n\nReturns true if video format has alpha channel (type: bool).\n\n-   IsPackedRGB (clip) (Avisynth+)\n\nReturns true if video format is one of the packed (not planar) RGB formats:\nRGB24, RGB32, RGB48 or RGB64 (type: bool).\n\n-   IsChannelMaskKnown (clip) (Avisynth+ v3.7.3)\n\nReturns true if the clip has audio channel mask defined (type: bool).\n\n-   GetChannelMask (clip) (Avisynth+ v3.7.3)\n\nReturns the channel mask (a 32 bit number), if audio channel mask is \ndefined, 0 otherwise. Channel mask bits - speaker bits - follow\nWAVE_FORMAT_EXTENSIBLE dwChannelMask speaker position definitions, see\nhttps://learn.microsoft.com/en-us/windows/win32/api/mmreg/ns-mmreg-waveformatextensible\n(type: int)\n\n--------\n\nBack to :doc:`AviSynth Syntax <syntax_ref>`.\n\n$Date: 2025-02-25 17:08:52-05:00 $\n\n.. _rgb: http://avisynth.nl/index.php/RGB\n.. _rgb24: http://avisynth.nl/index.php/RGB24\n.. _rgb32: http://avisynth.nl/index.php/RGB32\n.. _yuv: http://avisynth.nl/index.php/YUV\n.. _y8: http://avisynth.nl/index.php/Y8\n.. _yuy2: http://avisynth.nl/index.php/YUY2\n.. _yv12: http://avisynth.nl/index.php/YV12\n.. _yv16: http://avisynth.nl/index.php/YV16\n.. _yv24: http://avisynth.nl/index.php/YV24\n.. _yv411: http://avisynth.nl/index.php/YV411\n.. _planar: http://avisynth.nl/index.php/Planar\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_colors.rst",
    "content": "\nAviSynth - Colors\n=================\n\nIn some filters (`BlankClip`_, `Letterbox`_, `AddBorders`_ and `FadeXXX`_) a\ncolor argument can be specified. In all cases the color should be specified\nin `RGB`_ format even if the colorformat of the input clip is `YUV`_. This\ncan be done in hexadecimal or decimal notation.\n\nIn **hexadecimal notation** the number is composed as follows: the first two\ndigits denote the red channel, the next two the green channel and the last\ntwo the blue channel. The hexadecimal number must be preceded with a $.\n\nIn **decimal notation** the number is as follows: the red channel value is\nmultiplied by 65536, the green channel value is multiplied by 256 and the two\nresulting products are both added to the blue channel value.\n\nLet's consider an example. Brown is given by R=$A5 (165), G=$2A (42), B=$2A\n(42). Thus\n\n::\n\n    BlankClip(color=$A52A2A)\n\ngives a brown frame. Converting each channel to decimal (remember that A=10,\nB=11, C=12, D=14, E=14, F=15) gives\n\n::\n\n    R = $A5 = 10*16^1 +  5*16^0 = 165\n    G = $2A =  2*16^1 + 10*16^0 =  42\n    B = $2A =  2*16^1 + 10*16^0 =  42\n\n    165*65536 + 42*256 + 42 = 10824234\n\nThus creating a brown frame specifying the color in decimal notation gives\n\n::\n\n    BlankClip(color=10824234)\n\nCommon color presets can be found in the file colors_rgb.avsi, which should\nbe present in your plugin autoload folder (look into the file for list of\npresets). Thus BlankClip(color=color_brown) gives the same brown frames.\n\nNote that black RGB=$000000 will be converted to Y=16, U=V=128 if the\ncolorformat of the input clip is YUV, since the default color conversion RGB\n[0,255] -> YUV [16,235] is used.\n\n$Date: 2025-02-25 17:09:47-05:00 $\n\n.. _BlankClip: http://avisynth.nl/index.php/BlankClip\n.. _Letterbox: http://avisynth.nl/index.php/Letterbox\n.. _AddBorders: http://avisynth.nl/index.php/AddBorders\n.. _FadeXXX: http://avisynth.nl/index.php/Fade\n.. _RGB: http://avisynth.nl/index.php/RGB\n.. _YUV: http://avisynth.nl/index.php/YUV\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_control_structures.rst",
    "content": "\nAviSynth Syntax - Control structures\n====================================\n\nIn the strict sense, :doc:`AviSynth Syntax <syntax>` provides four control structures\n(actually five, the fifth being the conditional :doc:`operator <syntax_operators>`, ``?:``, presented\nelsewhere), the ``try..catch`` statement, the ``if..else`` statement, and the ``while`` and ``for`` loop.\n\n.. toctree::\n    :maxdepth: 2\n\n.. contents:: Table of contents\n\n\n\nThe ``try..catch`` statement\n----------------------------\n\nThe ``try..catch`` statement permits the execution of code that **may**\ngenerate a run-time error and the handling of the error, if it actually\narises.\n\nThe full syntax of the ``try..catch`` statement is:\n\n::\n\n    try {\n        ...\n        statements\n        ...\n    }\n    catch(err_msg) {\n        ...\n        statements\n        ...\n    }\n\nThe ``err_msg`` string in the ``catch`` block contains the text generated by\nAviSynth when the error inside the ``try`` block was encountered. This text\nis the same that would appear in the familiar MessageBox that shows up when a\nfatal script error occures.\n\nYou can query the text (it is a normal string :doc:`variable <syntax_script_variables>`) to find specific\nsubstrings inside that indicate the error that has been encountered. This is\na technique that can produce many useful results (for an example, see\n`here`_).\n\nThe ``if..else`` statement\n--------------------------\nAdapted from Gavino's `GScript`_ plugin.\n\nThe full syntax of the ``if`` or ``if..else`` statement is:\n\n::\n\n    if ( condition ) {\n        ...\n        statements\n        ...\n    }\n    else {\n        ...\n        statements\n        ...\n    }\n\nwhere ``condition`` is any boolean expression.\nThe statements can be any Avisynth statements, including the control structures themselves, and \nso the new constructs can be nested.\nThe else part may be omitted (equivalent to else {}).\n\n::\n\n    if ( condition ) {\n        ...\n        statements\n        ...\n    }\n\n\nThe 'else if' construct is also provided (optionally repeated to create a chain of conditionals).\n\n::\n\n    if ( condition ) {\n        statements\n    }\n    else if ( condition ) {\n        statements\n    }\n    else if (...) { ... }\n    ...\n    else {\n        ...\n        statements\n        ...\n    }\n\n\nThe ``while`` loop\n------------------\nAdapted from Gavino's `GScript`_ plugin.\n\nThe full syntax of the ``while`` loop is:\n\n::\n\n    while ( condition ) {\n        ...\n        statements\n        ...\n    }\n\nwhere ``condition`` is any boolean expression.\n\nThe statements are repeated while the condition is true.\n\nExample:\n\n::\n\n    while (Height() < h) {\n      StackVertical(last, c) \n    }\n\n``break`` and ``continue`` can be used as well (see example later) - available from v3.7.4\n\nThe ``for`` loop\n----------------\nAdapted from Gavino's `GScript`_ plugin.\n\nThe full syntax of the ``for`` loop is:\n\n::\n\n    for ( variable = init , limit , step ) {\n        ...\n        statements\n        ...\n    }\n\n``init``, ``limit`` and ``step`` are integer expressions, with ``step`` non-zero. ``step`` is optional and defaults to 1.\n\nFirst the ``variable`` is set to the value of ``init``.\nThe statements are repeated until the exit condition is met,\nie ``variable`` exceeds ``limit`` (if ``step`` > 0), or is less then ``limit`` (if ``step`` < 0).\nAfter each iteration, ``variable`` is incremented by ``step``.\nIf the initial value satisfies the exit condition, the number of iterations will be zero.\n\nExample:\n\n::\n\n    for (i=1, nBlurs) {\n      Blur(0.5)\n    }\n\n``break`` and ``continue`` can be used as well (see example later) - available from v3.7.4\n\nUsing ``break`` and ``continue`` in loops\n-----------------------------------------\n\n``break`` and ``continue`` are used to control the flow of loops.\n\nThe break statement is used to terminate the loop prematurely when a certain condition is met and \ncontrol is transferred to the next statement after the loop. \n\nThe continue statement skips the current iteration and control is transferred to the beginning of \nthe loop for the next iteration. \n\n::\n\n    ColorBars()\n    for (i=1, 6) {\n      SubTitle(Format(\"statement_1 i={i}\"), x=0, y=i*20)\n      SubTitle(Format(\"statement_2 i={i}\"), x=140, y=i*20)\n      if(i == 4) { \n        SubTitle(Format(\"Break at i={i}\"), x=280, y=i*20)\n        break  # Terminates the loop when i equals 4\n      }\n      SubTitle(Format(\"statement_3 i={i}\"), x=280, y=i*20)\n      if(i == 2) { \n        SubTitle(Format(\"Continue at i={i}\"), x=420, y=i*20)\n        continue # Skips the current iteration when i equals 2\n      }\n      SubTitle(Format(\"Final statement in i={i}\"), x=420, y=i*20)\n    }\n    SubTitle(Format(\"Outside\"), x=0, y=7*20)\n\nresults in the output:\n\n::\n\n    statement_1 i=1    statement_2 i=1    statment_3 i=1   Final statement in i=1\n    statement_1 i=2    statement_2 i=2    statment_3 i=2   continue at i=2\n    statement_1 i=3    statement_2 i=3    statment_3 i=3   Final statement in i=3\n    statement_1 i=4    statement_2 i=4    Break at i=4\n    \n    Outside\n\n\nOther control structures (in the broad sense)\n---------------------------------------------\n\nIn the broad sense, there are many elements inside :doc:`AviSynth Syntax <syntax>` that\nalthough not control structures by themselves, together they allow the\ncreation of language constructs equivalent to a control structure. Those\nconstructs in turn allow the performance of complex programming tasks.\n\nThe elements under consideration are the following:\n\n1.  The ``Eval()`` statement that allows execution of arbitrary script\n    language statements (and its cousin ``Apply`` that simplifies calling\n    functions by name).\n2.  Multiline strings and in particular multiline strings surrounded by\n    triple double quotes (the ``\"\"\"`` sequence of chars), since they allow to\n    write string literals inside them naturally, as one would do in a normal\n    AviSynth script.\n3.  The ``Import()`` statement that allows execution of arbitrary\n    scripts, which can return a value (not necessarily a clip; a script can\n    return a value of any type, which can be assigned to a :doc:`variable <syntax_script_variables>` of the\n    calling script).\n4.  Recursion (the ability to create recursive functions).\n5.  Control functions, in particular Assert, Select, Default, NOP.\n\nThe first three allow one to create simple :doc:`Block statements <../script_ref/script_ref_block_statements>`, such as\nbranching blocks (the analogous of the ``if..elseif..else`` control structure\ncommonly encountered in programming and scripting languages). A basic example\nis presented below (see the link above for more):\n\n::\n\n    # define different filtering based on this flag\n    heavy_filtering = true\n    AviSource(\"c:\\sources\\mysource.avi\")\n    # assign result of Eval() to a variable to preserve the value of the\n    last special variable\n    dummy = flag ? Eval(\"\"\"\n        Levels(0, 1.2, 255, 20, 235)\n        stext = \"heavily filtered\"\n        Spline36Resize(720, 400)\n    \"\"\") : Eval(\"\"\"\n        stext = \"lightly filtered\"\n        BicubicResize(720, 400)\n    \"\"\"\n    AddBorders(0, 40, 0, 40)\n    Subtitle(stext)\n\nThe fourth is the general tool provided by the :doc:`AviSynth syntax <syntax>` for operating on\ncollections and calculating expressions of any complexity. It is also,\ncurrently, **the only** tool.\n\nThis does not mean that there is something that you can't do inside the\nAviSynth script language; in fact recursion together with assignment can\nachieve everything an imperative language with looping constructs can do. It\njust does it in a way that most people without special programming skills are\nnot familiar, since functional programming is not a major ICT course but\nrather a specialised topic.\n\nThe fifth are more or less necessary tools inside the above constructs for\ncontrolling input, setting values and facilitating proper execution of the\nconstruct.\n\nLets look at some examples of recursion, to grasp the general pattern that\none must follow to master it for its purposes.\n\n\nExample 1: Create a function that returns a n-times repeated character sequence\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nWe will use an existing implementation, from `AVSLib`_ as our example:\n\n::\n\n    Function StrFill(string s, int count, bool \"strict\") {\n        strict = Default(strict, true)\n        Assert((strict ? count >= 0 : true), \"StrFill: 'count'\n        cannot be negative\")\n        return count > 0 ? s + StrFill(s, count - 1) : \"\"\n    }\n\nThe recursion is the call that the function makes to itself at the ``return``\nstatement. In order to be done properly, the sequence of recursive calls must\neventually end to a single return value. Thus a recursive function's return\nstatement will always use the conditional :doc:`operator <syntax_operators>`, ``?:``.\n\nThis is all that is about recursion, the other two lines (where the fifth\nelement, control functions are used) are simply for ensuring that proper\narguments are passed in. The \"strict\" argument is just and add-on for using\nthe functions in case where it should quietly (without throwing an error)\nreturn an empty string.\n\n\nExample 2: Create a function that selects frames of a clip in arbitrary intervals\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nFilters like :doc:`SelectEvery <../corefilters/selectevery>` allow the efficient selection of arbitrary sets\nof frames. They require though that each set of frames has a constant frame\nseparation with its successor and predecessor set (in other words, the sets\nare periodic on frame number). In order to select frames with varying\nseparation (that is non-periodic) we have to resort to script functions that\nuse recursion.\n\nThe function below is a generic frame selection filter, which in order to\nselect arbitrary frames uses a user-defined function (the ``func`` argument\nmust contain its name) that maps the interval ``[s_idx..e_idx)`` to the set\nof frames that will be selected. ``func`` must accept a single integer as\nargument and return the corresponding mapped frame number.\n\n::\n\n    Function FSelectEvery(clip c, string func, int s_idx, int e_idx) {\n        Assert(s_idx >= 0, \"FSelectEvery: start frame index\n        (s_idx) is negative\")\n        f = Apply(func, s_idx)\n        return (s_idx < e_idx && f >= 0 && f < c.Framecount) \\\n           ? c.Trim(f, -1) + FSelectEvery(c, func, s_idx + 1,\n           e_idx) \\\n           : c.BlankClip(length=0)\n    }\n\nThe recursive step (first conditional branch in the ``return`` statement) is\nagain an expression that involves the function as a subpart. This is not\nnecessary in the general case (depending on the specific task, it could also\nbe just the function call) but it is the most usual case when building\ncomplex constructs.\n\n``Apply`` calls the user function to calculate the frame number (a more\nrobust implementation would enclose this call in a ``try...catch`` block). If\nthe frame number is within the clip's frames then the associated frame is\nappended to the result else recursion ends.\n\nThe following example will clarify the design:\n\n::\n\n    # my custom selector (x^2)\n    Function CalcFrame(int idx) { return Int(Pow(idx, 2)) }\n\n    AviSource(\"my_200_frames.avi\")\n    # select up to 20 frames, mapped by CalcFrame\n    # in this case: 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144,\n    169, 196\n    FSelectEvery(last, \"CalcFrame\", 0, 20)\n\nChangelog\n---------\n+-----------------+----------------------------------+\n| Version         | Changes                          |\n+=================+==================================+\n| Avisynth+ 3.7.4 | Added \"break\" and \"continue      |\n+-----------------+----------------------------------+\n\n\n$Date: 2024/04/10 9:38:00 $\n\n.. _here: http://forum.doom9.org/showthread.php?t=66627\n.. _AVSLib: http://avslib.sourceforge.net/\n.. _GScript: https://forum.doom9.org/showthread.php?t=147846\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_formal_avisynth_grammar.rst",
    "content": "\nFormal AviSynth grammar\n=======================\n\nIntroduction\n~~~~~~~~~~~~\n\nThis page presents the formal grammar of the AviSynth script language. This is a dense representation of all the \nrules of the AviSynth script language. While it probably is of more interest to a developer than to an average user, \nit is nevertheless an essential piece of documentation for any programming language and it is thus provided here for \nthose more inclined to abstract mathematical reasoning. Have fun!\n\nBefore going to the grammar, a few introductory material will be necessary for all those that don't eat bytes \nfor breakfast. If you are familiar with BNF / EBNF syntax then skip the following section. \n\nBackground Information\n~~~~~~~~~~~~~~~~~~~~~~\n\nFormal grammars of programming and scripting languages are typically written in Backus-Naur Form (BNF) or \nExtended Backus-Naur Form (EBNF) syntax. We have chosen the EBNF syntax because it is easier for human comprehension and \nthus it is a slightly better selection for documentation purposes. The syntax used here follows the ISO/IEC 14977 \nStandard, \"Extended BNF\". The table below summarizes the notation used (infix means that the operator has left \nassociativity; postfix that it has right associativity). \n\n\n+-------------+--------+----------------------------------------------+-------------------------------------------------------------------------------+\n|Extended BNF |Operator|Meaning                                       | Comment                                                                       |\n+-------------+--------+----------------------------------------------+-------------------------------------------------------------------------------+\n| unquoted    |        |Non-terminal symbol                           | A symbol that is a grouping of low-level symbols (ie not a fundamental one).  |\n| words       |        |                                              |                                                                               |\n+-------------+--------+----------------------------------------------+-------------------------------------------------------------------------------+\n| \"...\"       |        |Terminal symbol                               | A fundamental (ie not further divisible) symbol of the language.              |\n+-------------+--------+----------------------------------------------+-------------------------------------------------------------------------------+\n| '...'       |        |Terminal symbol                               | Same as above.                                                                |\n+-------------+--------+----------------------------------------------+-------------------------------------------------------------------------------+\n| (...)       |        |Brackets                                      | Parentheses just group the symbols inside them in a single (non-terminal)     |\n|             |        |                                              | symbol.                                                                       |\n+-------------+--------+----------------------------------------------+-------------------------------------------------------------------------------+\n| [...]       |        |Optional symbols                              | The symbols inside square braces are optional (ie they are present either 0   |\n|             |        |                                              | or 1 times)                                                                   |\n+-------------+--------+----------------------------------------------+-------------------------------------------------------------------------------+\n| {...}       |        |Symbols repeated zero or more (ie >= 0) times |                                                                               |\n+-------------+--------+----------------------------------------------+-------------------------------------------------------------------------------+\n| {...}-      |        |Symbols repeated one or more (ie >= 1) times  | Note that the - immediately follows the curly braces.                         |\n+-------------+--------+----------------------------------------------+-------------------------------------------------------------------------------+\n| =           |infix   |Defining symbol                               | This is the \"assignment\" operator of EBNF; the left (non-terminal) symbol is  |\n|             |        |                                              | (equal to) the right grouping of symbols.                                     |\n+-------------+--------+----------------------------------------------+-------------------------------------------------------------------------------+\n| ;           |postfix |Rule terminator                               | This operator signals the end of the (assignment) rule (just like in C ; ends |\n|             |        |                                              | a statement).                                                                 |\n+-------------+--------+----------------------------------------------+-------------------------------------------------------------------------------+\n| \\|          |infix   |Alternative                                   | Either one of the alternative terminal or non-terminal symbols (and only one) |\n|             |        |                                              | will be matched.                                                              |\n+-------------+--------+----------------------------------------------+-------------------------------------------------------------------------------+\n| ,           |infix   |Concatenation                                 | Symbols on both ends of the , (comma) operator are joined sequentially to     |\n|             |        |                                              | form a single (non-terminal) symbol.                                          |\n+-------------+--------+----------------------------------------------+-------------------------------------------------------------------------------+\n| \\-          |infix   |Exception                                     | The effect is the logical negation of the rule following. For example -\"a\"    |\n|             |        |                                              | becomes  ? all characters not equal to a ?.                                   |\n+-------------+--------+----------------------------------------------+-------------------------------------------------------------------------------+\n| \\*          |infix   |Occurences of                                 | The effect of this operator is to repeat the symbol to its right {n} times,   |\n|             |        |                                              | where n is the value to its left. For example to state that a (fortran) label |\n|             |        |                                              | has exactly 5 characters, one can state: label = 5 * character;.              |\n+-------------+--------+----------------------------------------------+-------------------------------------------------------------------------------+\n| (\\*...\\*)   |        |Comment                                       | Arbitrary text documenting something (this is the comment facility of the     |\n|             |        |                                              | EBNF language).                                                               |\n+-------------+--------+----------------------------------------------+-------------------------------------------------------------------------------+\n| ?...?       |        |Special sequence                              | Arbitrary text whose interpretation is beyond the scope of the EBNF standard. |\n+-------------+--------+----------------------------------------------+-------------------------------------------------------------------------------+\n\nNote: For defining character sequences as terminal symbols one can either use the \"string\" or 'string' \nfacilities of the EBNF language or to use the concatenation operator: character-a , character-b , ..., character-z. \nHowever for some repetitive tasks such as enumerating all characters of the alphabet or all numeric digits, etc. \nit is common to use a range notation of the form start...end as an extension to the standard. We use it also here. \n\nThe AviSynth Grammar in EBNF Notation\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nIn the formulation of the AviSynth grammar below, there are certain items that are not considered part of the grammar \nand thus are considered responsibilities of the tokenizer (to process and strip-off). These are the following:\n\n-   Whitespace.\n-   Comments (both single-line and multi-line).\n-   Line continuations.\n-   The end-of-file condition. \n\n::\n\n    script =\n                { declaration }-\n                ;\n    declaration =\n                statement\n                | function_definition \n                ;\n    function_definition =\n                kw_function , identifier , '(' , [ parameters_list ] , ')' , \n                compound_statement\n                ;\n    (* optional arguments must come after all positional arguments *)\n    parameters_list =\n                arguments , ',' , optional_arguments     (* either both types in order *)\n                | arguments                              (* or only one (any) of them  *)\n                | optional_arguments\n                ;\n    arguments =\n                argument , [ { ',' , argument } ]\n                ;\n    (* Note: If type_spec is missing, it is implicitly assumed to be: t_val *)\n    argument =\n                [ type_spec ] , identifier\n                ;\n    optional_arguments =\n                optional_argument , [ { ',' , optional_argument } ]\n                ;\n    (* Despite the formulation, the tokenizer does not handle whitespace correctly. *)\n    (* Example: an optional argument declared simply \"int f\" parses without error.  *)\n    optional_argument =\n                [ type_spec ] , quote , identifier , quote\n                ;\n    type_spec =\n                t_val | t_string | t_bool | t_int | t_float | t_clip\n                ;\n    (* This is probably a parser bug (due to C-origin) because there is only one global *)\n    (* function table in AviSynth; it should be  '{' , { statement } , '}'  instead and *)\n    (* statement definition below would include function_definition. Then, declaration  *)\n    (* would be un-needed as a grammar rule and also: script = { statement }- ;         *)\n    compound_statement = \n                '{' , { declaration } , '}'\n                ;\n    statement =                  (* free-standing compound statements are ?not? allowed *)\n                expression\n                | try_statement\n                | jump_statement\n                ;\n    try_statement =\n                kw_try , compound_statement , \n                kw_catch , '(' , [ identifier ] , ')' , compound_statement\n                ;\n    jump_statement = \n                kw_return , [ expression ]\n                ;\n    (* Although expression has only one subtype, keep as a separate production rule *)\n    (* for documentation and for easier update of the grammar if extended at future. *)\n    expression =\n                assignment_exp\n                ;\n    assignment_exp =\n                conditional_exp\n                | [ kw_global ] , identifier , '=' , assignment_exp\n                ;\n    conditional_exp =\n                logical_or_exp\n                | logical_or_exp , '?' , expression , ':' , conditional_exp\n                ;\n    logical_or_exp =\n                logical_and_exp\n                | logical_or_exp , '||' , logical_and_exp\n                ;\n    logical_and_exp =\n                equality_exp\n                | logical_and_exp , '&&' , equality_exp\n                ;\n    equality_exp =\n                relational_exp\n                | equality_exp , equ_binary_operator , relational_exp\n                ;\n    equ_binary_operator = \n                '==' | '!=' | '<>'\n                ;\n    relational_exp =\n                additive_exp\n                | relational_exp , rel_binary_operator , additive_exp\n                ;\n    rel_binary_operator = \n                '<' | '>' | '<=' | '>='\n                ;\n    additive_exp =\n                multiplicative_exp\n                | additive_exp , add_binary_operator , multiplicative_exp\n                ;\n    add_binary_operator = \n                '+' | '-' | '++'                               (* ++ is for clips *)\n                ;\n    multiplicative_exp = \n                unary_exp\n                | multiplicative_exp , mul_binary_operator , unary_exp\n                ;\n    mul_binary_operator = \n                '*' |  '/' |  '%'\n                ;\n    unary_exp = \n                [ unary_operator ] , postfix_exp\n                ;\n    unary_operator = \n                sign | '!'\n                ;\n    (* Because OOP notation simply puts the 1st argument of a function in front of its call *)\n    (* it can be chained to all alternatives of primary_exp; therefore this is its place    *)\n    postfix_exp = \n                primary_exp\n                | function_call\n                | primary_exp , { '.' , function_call }-       (* the OOP notation *)\n                ;\n    function_call =\n                identifier , [ '(' , [ argument_exp_list ] , ')' ]\n                ;\n    (* Assignment is allowed only to optional arguments, *)\n    (* which must come after all positional arguments    *)\n    argument_exp_list = \n                positional_arg_list , ',' , optional_arg_list  (* either both types in order *)\n                | positional_arg_list                          (* or only one (any) of them  *)\n                | optional_arg_list\n                ;\n    positional_arg_list = \n                expression\n                | positional_arg_list , ',' , expression\n                ;\n    optional_arg_list = \n                identifier , '=' , expression\n                | optional_arg_list , ',' , identifier , '=' , expression\n                ;\n    primary_exp =\n                constant\n                | identifier\n                | '(' , expression , ')'\n                ;\n    identifier = \n                ( letter | \"_\" )  , { letter | digit | \"_\" }\n                ;\n    constant = \n                integer_constant | float_constant | boolean_constant | stringliteral\n                ;\n    stringliteral = \n                quote , { -quote } , quote | tripleqouote , { -tripleqouote } , tripleqouote\n                ;\n    boolean_constant =\n                true | false | yes | no\n                ;\n    integer_constant = \n                decimalinteger | hexinteger\n                ;\n    float_constant = \n                [ sign ] , ( [ intpart ] , fraction | intpart , '.' )\n                ;\n    decimalinteger = \n                [ sign ] , ( nzero_digit , { digit } | '0' )\n                ;\n    hexinteger = \n                \"$\" , { hexdigit }-\n                ;\n    fraction = \n                '.' , intpart\n                ;\n    intpart = \n                { digit }-\n                ;\n    hexdigit = \n                digit | 'a'...'f' | 'A'...'F' \n                ;\n    letter = \n                'a'...'z' | 'A'...'Z' \n                ;\n    digit = \n                '0' | nzero_digit\n                ;\n    nzero_digit =\n                '1'...'9'\n                ;\n    sign =\n                '-' | '+'\n                ;\n    \n    quote       = '\"'   ;\n    triplequote = '\"\"\"' ;\n    \n    true        = i_t , i_r , i_u , i_e ;\n    false       = i_f , i_a , i_l , i_s , i_e ;\n    yes         = i_y , i_e , i_s ;\n    no          = i_n , i_o ;\n    \n    t_val       = i_v , i_a , i_l ;\n    t_string    = i_s , i_t , i_r , i_i , i_n , i_g ;\n    t_bool      = i_b , i_o , i_o , i_l ;\n    t_int       = i_i , i_n , i_t ;\n    t_float     = i_f , i_l , i_o , i_a , i_t ;\n    t_clip      = i_c , i_l , i_i , i_p ;\n    \n    kw_function = i_f , i_u , i_n , i_c , i_t , i_i , i_o , i_n ;\n    kw_try      = i_t , i_r , i_y ;\n    kw_catch    = i_c , i_a , i_t , i_c , i_h ;\n    kw_global   = i_g , i_l , i_o , i_b , i_a , i_l ;\n    kw_return   = i_r , i_e , i_t , i_u , i_r , i_n ;\n    \n    i_a = ( 'a' | 'A' ) ;\n    i_b = ( 'b' | 'B' ) ;\n    i_c = ( 'c' | 'C' ) ;\n    i_e = ( 'e' | 'E' ) ;\n    i_f = ( 'f' | 'F' ) ;\n    i_g = ( 'g' | 'G' ) ;\n    i_h = ( 'h' | 'H' ) ;\n    i_i = ( 'i' | 'I' ) ;\n    i_l = ( 'l' | 'L' ) ;\n    i_n = ( 'n' | 'N' ) ;\n    i_o = ( 'o' | 'O' ) ;\n    i_p = ( 'p' | 'P' ) ;\n    i_r = ( 'r' | 'R' ) ;\n    i_s = ( 's' | 'S' ) ;\n    i_t = ( 't' | 'T' ) ;\n    i_u = ( 'u' | 'U' ) ;\n    i_v = ( 'v' | 'V' ) ;\n    i_y = ( 'y' | 'Y' ) ;\n    \n\n-------\n\nBack to: :doc:`Avisynth: the full grammar <syntax_the_full_grammar>`\n\nBack to: :doc:`Avisynth syntax <syntax>`\n\nBack to: :doc:`Avisynth syntax old ref. <syntax_ref>`\n\nThis page is originated from `Avisynth.nl: The Format Avisynth Grammar <http://avisynth.nl/index.php/Formal_AviSynth_grammar>`_\n\n\n$Date: 2024/01/09 10:00:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_function_objects.rst",
    "content": "\nAviSynth Syntax - Function objects\n==================================\n\nThis feature introduces function objects into scripts.\n\nFunctions (along their parameter definition) can also appear as standard Avisynth \nvariables\n\nFunction objects can even be inlined, like lambdas.\n\nThey can work even with variable capture [] (like in GRuntT args).\n\nIn Avisynth+ runtime filters (e.g. ScriptClip) can accept function objects as well, \nwhere in the classic syntax a stringified script would appear.\n\n    The input clip\n    The function object. See Function_objects\n    Capture variables (part of function object syntax). \n\nIn this case Script is not an assembled string but a prewritten function, either inline or separately written. \n\nThe concept was first introduced in nekopanda's Avisynth+ fork.\n\nFunction object basics\n----------------------\n\nConcept of function objects was introduced in Avisynth Neo and was backported to Avisynth+ \n(avaliable from v3.6). Function object is a new variable type. Once declared, they can be assigned \nto a variable, and use as function arguments.\n\n:doc:`Internal functions can be casted <syntax_internal_functions_function_object>` to function objects, this helpes a cleaner syntax for some \nexisting internal function (e.g. ScriptClip).\n\nA user defined function or an external plugin can even take such type as an argument in the parameter list.\n(in FilterSDK: ``AVSValue type='n'``)\n\nThe syntax allows capturing the variable at that point with '[]' before the formal argument.\n\n*Examples*\n\nBasic example\n::\n\n    a = function(int x, int y) {\n        return x + y\n    }\n    MessageClip(String(a)) #Function\n    b = a\n    MessageClip(String(b)) #Function\n    MessageClip(String(a == b)) # true\n\nTake as an argument\n::\n\n    function MyFunc(func f) {\n        return f(2, 3)\n    }\n    a = MyFunc(function(x, y) {\n        return x + y\n    })\n    MessageClip(String(a)) # 5\n\nreturn as a return value\n::\n\n    function MyFunc() {\n        return function(x, y) {\n            return x + y\n        }\n    }\n    a = MyFunc()(2, 3)\n    MessageClip(String(a)) # 5\n\nCapture example\n::\n\n    function MyFunc() {\n        x = 2\n        y = 3\n        return function[x, y]() {\n            return x + y\n        }\n    }\n    a = MyFunc()()\n    MessageClip(String(a)) # 5\n\nSpecification details\n~~~~~~~~~~~~~~~~~~~~~\n\nFunction objects are functions defined with the new syntax.\n::\n\n    function [] () {...}\n\nIt looks like an unnamed function compared to the usual function definitions so far.\n``'[]'`` Does not have to be optional.\n\nFunctions defined in the normal function format are not function objects (for compatibility).\n::\n\n    function MyFunc() {return 123}\n    a = MyFunc\n    MessageClip(String(a)) # 123 (Not Function)\n\nSimilarly, built-in functions and plug-in functions are not function objects.\n::\n\n    a = Invert # Error: I don't know what 'Invert' means.\n\nFunctions that are not function objects can be made into function objects by using the \n:doc:`Func <syntax_internal_functions_function_object>` function.\n::\n\n    a = func(Invert)\n    Version().a() # Invert a clip\n\nA new 'func' has been added to the value type.\n::\n\n    function MyFunc(func x, func y, int z) {\n      return x () + y () + z\n    }\n    a = MyFunc(function(){1}, function(){2}, 3)\n    MessageClip(String(a)) # 6 (= 1 + 2 + 3)\n\nThe :doc:`IsFunction <syntax_internal_functions_boolean>` function that determines the function object has been added.\n::\n\n    a = function() {}\n    MessageClip(String(IsFunction(a))) # true\n\nCompared with GRunT\n~~~~~~~~~~~~~~~~~~~\n\nLet's compare function objects with ``GRunT``, a plugin from the Avisynth 2.6 era that makes \nScriptClip easier to write.\n\nThe following code on the GRunT introduction page\n::\n\n    function bracket_luma(clip c, float th1, float th2) {\n        Assert (0 <= th1 && th1 <th2 && th2 <= 255, \"Invalid thresholds!\")\n        ScriptClip (c, \"\" \"\n            avl = AverageLuma ()\n            avl <= th1? Last.BlankClip (): avl> = th2? last.BlankClip (color = color_white): last\n        \"\" \", args =\" th1, th2 \", local = true)\n    }\n\nIt is a sample to appeal the goodness of GRunT, but with Avisynth+ (first in Neo fork) it can \nbe written as follows.\n::\n\n    function bracket_luma(clip c, float th1, float th2) {\n        Assert (0 <= th1 && th1 <th2 && th2 <= 255, \"Invalid thresholds!\")\n        ScriptClip(c, function [th1, th2] () {\n            avl = AverageLuma()\n            avl <= th1? Last.BlankClip() : avl> = th2? last.BlankClip(color = color_white) : last\n        })\n    }\n\nThere are the following differences compared to GRunT.\n\n- There is no need to pass the processing content as a character string \n- Variables to be used can be written in a special syntax, so the amount of description is reduced.\n- Supports 'function' type of input of built-in functions\n\nExamples on runtime filters with extended syntax\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nA version that can pass the function object has been added to some filters.\nFormerly these only allowed and processed content as a script string.\n\nScriptClip\n^^^^^^^^^^\n::\n\n    ScriptClip(clip clip, func filter [, bool show, bool after_frame])\n\n*Examples:*\n::\n\n    Version()\n    ScriptClip (function [] (clip c) {\n        c.Subtitle(String(current_frame))\n    })\n\nComparison with string input:\n::\n\n    # ScriptClip with text script input\n    SSS2=\"\"\"\n    p=(current_frame)*pow(framecount(last)-1,-1)*100\n    q=ceil(0.0625*((framecount(last))-(current_frame+1)))\n      Subtitle(String(q,\"%.0f\")+String(\" - \")+String(p,\"%.2f\")+String(\"% - \")+String(current_frame,\"%.0f\")) \n    \"\"\"\n    clip1 = Input.Scriptclip(SSS2,After_Frame=True)\n    \n    # With function object (declared inline)\n    clip1 = Input.ScriptClip(function[](clip c) { p=(current_frame)*pow(framecount(last)-1,-1)*100 \\\n      q=ceil(0.0625*((framecount(last))-(current_frame+1))) \\\n      Subtitle(String(q,\"%.0f\")+String(\" - \")+String(p,\"%.2f\")+String(\"% - \")+String(current_frame,\"%.0f\")) \\\n    }, After_Frame=True)\n\nConditionalFilter\n^^^^^^^^^^^^^^^^^\n::\n\n    ConditionalFilter(clip testclip, clip source1, clip source2, func condition [, bool show])\n\n*Example:*\n::\n\n    a = Version()\n    b = a.Invert()\n    ConditionalFilter(a, a, b, function [] (clip c) {\n        current_frame<30 # if true return a else b\n    })\n\nConditionalSelect\n^^^^^^^^^^^^^^^^^\n::\n\n    ConditionalSelect(clip testclip, func get_index, clip source0 [, clip source1 ...] [, bool show])\n\n*Example:*\n::\n\n    Version ()\n    ConditionalSelect(function [] (clip c) {\n        current_frame / 100\n    }, subtitle(\"0\"), subtitle(\"1\"), subtitle(\"2\"))\n\nWriteFile system\n^^^^^^^^^^^^^^^^\n::\n\n    WriteFile(clip clip, string filename, func expression1 [, func expression2 [, ...]] [, bool append, bool flush]) \n    WriteFileIf(clip clip, string filename, func expression1 [, func expression2 [, ...]] [, bool append, bool flush]) \n    WriteFileStart (clip clip, string filename, func expression1 [, func expression2 [, ...]] [, bool append]) \n    WriteFileEnd (clip clip, string filename, func expression1 [, func expression2 [, ...]] [, bool append]) \n\n*Example:*\n::\n\n    Version().ConvertToY()\n    WriteFile(\"out.txt\", function() {\n        string(current_frame) + \":\" + string(YPlaneMedian())\n    })\n\nType cast\n~~~~~~~~~\n::\n\n    Func \n\nSee at conversion function :doc:`Func <syntax_internal_functions_function_object>`\n\n::\n\n    # write frame properties with function object\n    ScriptClip(\"\"\"propSetInt(\"frameprop_from_str\",func(YPlaneMax))\"\"\")\n    # write frame properties with traditional script string\n    ScriptClip(function[](clip c) { propSetInt(\"frameluma_sc_func\",func(AverageLuma)) })\n\nChangelog\n~~~~~~~~~\n+----------------+------------------------------------------------------------+\n| Version        | Changes                                                    |\n+================+============================================================+\n| Avisynth 3.6.0 | Added function objects                                     |\n+----------------+------------------------------------------------------------+\n\n--------\n\nBack to :doc:`Internal functions <syntax_internal_functions>`.\n\nThis page was backported from `Avisynth.nl <http://avisynth.nl/index.php/Function_objects>`_\n\n$Date: 2024/01/0914:13:14 $\n\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_internal_functions.rst",
    "content": "\nAviSynth Syntax - Internal functions\n====================================\n\nIn addition to :doc:`internal filters <../corefilters>` AviSynth has a fairly large number of\nother (non-clip) internal functions. The input or/and output of these\nfunctions are not clips, but some other variables which can be used in a\nscript. They are roughly classified as follows:\n\n-   :doc:`Boolean functions <syntax_internal_functions_boolean>`\n\nThey return true or false, if the condition that they test holds or not,\nrespectively.\n\n-   :doc:`Control functions <syntax_internal_functions_control>`\n\nThey facilitate flow of control (loading of scripts, arguments checks, global\nsettings adjustment, etc.).\n\n-   :doc:`Type conversion functions <syntax_internal_functions_conversion>`\n\nThey convert between different types.\n\n-   :doc:`Numeric functions <syntax_internal_functions_numeric>`\n\nThey provide common mathematical operations on numeric variables.\n\n-   :doc:`Trigonometry functions <syntax_internal_functions_trig>`\n\nThey provide trigonometry functions.\n\n-   :doc:`Bit functions <syntax_internal_functions_bit>`\n\nThey provide bitwise functions.\n\n-   :doc:`Casting to function object <syntax_internal_functions_function_object>`\n\nCasting an internal function to a function object.\n\n-   :doc:`Runtime functions <syntax_internal_functions_runtime>`\n\nThese are internal functions which are evaluated at every frame. They can be\nused inside the scripts passed to runtime filters (:doc:`ConditionalFilter <../corefilters/conditionalfilter>`,\n:doc:`ScriptClip <../corefilters/conditionalfilter>`, :doc:`FrameEvaluate <../corefilters/conditionalfilter>`) to return information for a frame.\n\n-   :doc:`Script functions <syntax_internal_functions_script>`\n\nThey provide AviSynth script information.\n\n-   :doc:`String functions <syntax_internal_functions_string>`\n\nThey provide common operations on string variables.\n\n-   :doc:`Version functions <syntax_internal_functions_version>`\n\nThey provide AviSynth version and Avisynth/Operating System bitness information.\n\n-   :doc:`Frame property functions <syntax_internal_functions_frame_properties>`\n\nThey provide manipulation (read, write, delete) of frame properties.\n\nThis section contains an overview on the concept and lists the quasi-standard\nframe properties as well.\n\n-   :doc:`Multithreading <syntax_internal_functions_multithreading_new>` (Avisynth+)\n\nControlling the threads mechanism.\n\n-   :doc:`Global options and resource control (memory, CPU, cache) <syntax_internal_functions_global_options>`\n\nMethods for fine-tune resources: memory, cache strategy and CPU environment settings.\n\nGlobal variables which affect specific audio or video (VfW export) features.\n\n-   :doc:`Debugging helper function <syntax_internal_functions_debug>`\n\nDebugging and troubleshooting helper functions. Filter graphs, logging.\n\n-   :doc:`History: Avisynth 2.6 Multithreading and memory limit functions <syntax_internal_functions_multithreading>`\n\n(Historical: Avisynth 2.6) Controlling the threads and the maximum used memory.\n\nBack to :doc:`Avisynth Syntax <syntax>`.\nBack to :doc:`Avisynth Syntax ref <syntax_ref>`.\nBack to :doc:`The full Avisynth grammar <syntax_the_full_grammar>`.\n\n$Date: 2024/01/10 10:38:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_internal_functions_bit.rst",
    "content": "\nAviSynth Syntax - Bit functions\n===============================\n\nThe functions are *bitwise operators*. They manipulate individual bits within integer variables. \nThis means that their arguments (being integers) are converted to binary numbers, the operation is \nperformed on their bits, and the resulting binary number is converted back again.\n\nSince Avisynth 3.7.4 the functions have special 64-bit versions. \nOld functions work and return with the lower 32 bits even if 64-bit data is passed.\n\n64-bit versions work on full 64 bit data.\n\nBitAnd\n~~~~~~\nBitAnd64\n~~~~~~~~\n::\n\n    BitAnd(int, int)\n    BitAnd64(int, int)\n\nReturns the bitwise AND (sets bit to 1 if both bits are 1 and sets bit to 0 otherwise).\n\n*Examples:*\n::\n\n    BitAnd(5, 6) = 4 # since 5 = 101, 6 = 110, and 101&110 = 100\n\nBitNot\n~~~~~~\nBitNot64\n~~~~~~~~\n::\n\n    BitNot(int)\n    BitNot64(int)\n\nReturns the bit-inversion (sets bit to 1 if bit is 0 and vice-versa).\n\n*Examples:*\n::\n\n    BitNOT(5) = -6 \n    # since  5 = 101, \n    # and ~101 = 1111 1111 1111 1111 1111 1111 1111 1010 = -6\n\nNote: \n::\n\n    1111 1111 1111 1111 1111 1111 1111 1010 = \n    (2^32-1)-2^0-2^2 = 2^32-(1+2^0+2^2) = \n    (signed) -(1+2^0+2^2) = \n    -6.\n\nBitOr\n~~~~~\nBitOr64\n~~~~~~~\n::\n\n    BitOr(int, int)\n    BitOr64(int, int)\n\nReturns the bitwise inclusive OR (sets bit to 1 if one of the bits (or both) \nis 1 and sets bit to 0 otherwise). \n\n*Examples:*\n::\n\n    BitOr(5, 6) = 7 # since 5 = 101, 6 = 110, and 101|110 = 111\n    BitOr(4, 2) = 6 # since 4 = 100, 2 = 010, and 100|010 = 110\n\n\nBitXor\n~~~~~~\nBitXor64\n~~~~~~~~\n::\n\n    BitXor(int, int)\n    BitXor64(int, int)\n\nReturns the bitwise exclusive OR (sets bit to 1 if exactly one of the bits is \n1 and sets bit to 0 otherwise). \n\n*Examples:*\n::\n\n    BitXor(5, 6) = 3 # since 5 = 101, 6 = 110, and 101^110 = 011\n    BitXor(4, 2) = 6 # since 4 = 100, 2 = 010, and 100^010 = 110\n\nBit Shift Left (BitLShift, BitShl, BitSal)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nBit Shift Left 64-bit (BitShl64, BitSal64)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n::\n\n    BitLShift(int, int)\n    BitShl(int, int)\n    BitSal(int, int)\n    BitShl64(int, int)\n    BitSal64(int, int)\n\nShift the bits of a number to the left.\n\nNote: When you shift to the left, both logical and arithmetic shifts behave the same way.\nNevertheless, multiple names are provided.\n\nSynonyms. Even more synonyms for 32 bit versions are: ``BitLShiftL``, ``BitLShiftA``, ``BitLShiftU``, ``BitLShiftS``\n\n*Examples:*\n\nShifts the bits of the number 5 two bits to the left:\n::\n\n    BitLShift(5, 2) = 20 (since 101 << 2 = 10100)\n\nBit shift right, signed (BitRShiftA, BitRShiftS, BitSar)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nBit shift right, signed 64-bit (BitSar64)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n::\n\n    BitRShiftA(int, int)\n    BitRShiftS(int, int)\n    BitSar(int, int)\n    BitSar64(int, int)\n\nShift the bits of an integer to the right. (Arithmetic, Sign bit fill, Right Shift) \n\nAll 32 bit versions are synonyms.\n\n*Examples:*\n\nShifts the bits of the number -42 one bit to the right, treating it as signed:\n::\n\n    BitRShiftA(-42, 1) = -21 \n    # (since 1111 1111 1111 1111 1111 1111 1101 0110 >> 1  \n    #      = 1111 1111 1111 1111 1111 1111 1110 1011)\n\nBit shift right, unsigned (BitRShiftL, BitRShiftU, BitShr)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nBit shift right, unsigned 64-bit (BitShr64)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n::\n\n    BitRShiftL(int, int)\n    BitRShiftU(int, int)\n    BitShr(int, int)\n    BitShr64(int, int)\n\nShift the bits of an unsigned integer to the right. (Logical, zero fill, Right Shift) \n\nAll 32 bit versions are synonyms.\n\n*Examples:*\n\nShifts the bits of the number -42 one bit to the right, treating it as unsigned:\n::\n\n    BitRShiftL(-42, 1) = 2147483627 \n    # (since 1111 1111 1111 1111 1111 1111 1101 0110 >> 1 \n    #      = 0111 1111 1111 1111 1111 1111 1110 1011)\n\nNote:\n::\n\n    -42 = -(1+2^0+2^3+2^5) = (unsigned) (2^32-1)-(2^0+2^3+2^5) =\n    1111 1111 1111 1111 1111 1111 1101 0110 \n\nBit rotate left (BitLRotate, BitRol)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nBit rotate left 64-bit (bitrol64)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n::\n\n    BitLRotate(int, int)\n    BitRol(int, int)\n    BitRol64(int, int)\n\nRotates the bits of an integer to the left by the number of bits specified in \nthe second operand. For each rotation specified, the high order bit that exits from \nthe left of the operand returns at the right to become the new low order bit. \n\n*Examples:*\n\nRotates the bits of the number -2147483642 one bit to the left:\n::\n\n    BitLRotate(-2147483642, 1) = 13 \n    # (since 10000000000000000000000000000110 ROL 1\n    #      = 00000000000000000000000000001101)\n\nBit rotate right (BitRRotate, BitRor)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nBit rotate right 64-bit (BitRor64)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n::\n\n    BitRRotateL(int, int)\n    BitRor(int, int)\n    BitRor64(int, int)\n\nRotates the bits of an integer to the right by the number of bits specified in \nthe second operand. For each rotation specified, the low order bit that exits from \nthe right of the operand returns at the left to become the new high order bit. \n\n*Examples:*\n\nRotates the bits of the number 13 one bit to the right:\n::\n\n    BitRRotate(13, 1) = -2147483642 \n    # (since 00000000000000000000000000001101 ROR 1 \n    #      = 10000000000000000000000000000110)\n\nBit test (BitTest, BitTst)\n~~~~~~~~~~~~~~~~~~~~~~~~~~\nBit test 64-bit (BitTst64)\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n::\n\n    BitTest(int, int)\n    BitTst(int, int)\n    BitTst64(int, int)\n\nTests a single bit (that is, it returns true if its state is one, else it \nreturns false). The second operand denotes the location of the bit which is \nspecified as an offset from the low order end of the operand (starting at zero). \n\n*Examples:*\n\nCheck the state of the fourth bit:\n::\n\n    BitTest(3, 4) = False\n    BitTest(19, 4) = True\n\n\nCheck the state of the sign bit on a 32 bit value:\n::\n\n    BitTest(-1, 31) = True\n    BitTest(2147483647, 31) = False\n\n\nBitSet\n~~~~~~\nBitSet64\n~~~~~~~~\n::\n\n    BitSet(int, int)\n    BitSet64(int, int)\n\nSets a single bit to one (so it sets its state to one). The second operand denotes the \nlocation of the bit which is specified as an offset from the low order end of the \noperand (starting at zero). \n\n*Examples:*\n\nSet the state of the fourth bit to one:\n::\n\n    BitSet(3, 4) = 19\n    BitSet(19, 4) = 19\n\n\nSet the state of the sign bit to one, return a 32 bit data:\n::\n\n    BitSet(-1, 31) = -1\n    BitSet(2147483647, 31) = -1\n\n\nBitSetCount\n~~~~~~~~~~~\nBitSetCount64\n~~~~~~~~~~~~~\n::\n\n    BitSetCount(int [, int...])\n    BitSetCount64(int [, int...])\n\nReturns the total number of set bits in all supplied integer arguments. \n\n\nBit clear (BitClear, BitClr)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nBit clear 64-bit (BitClr64)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\n::\n\n    BitClear(int, int)\n    BitClr(int, int)\n    BitClr64(int, int)\n\nSets a single bit to zero (so it sets its state to zero). The second operand denotes \nthe location of the bit which is specified as an offset from the low order end of the \noperand (starting at zero). \n\n*Examples:*\n\nClear the bits of the number 5\n::\n\n    BitClear(5, 0) = 4 (first bit is set to zero)\n    BitClear(5, 1) = 5 (second bit is already zero)\n    BitClear(5, 2) = 1 (third bit is set to zero)\n    BitClear(5, 3) = 5 (fourth bit is already zero)\n\n\nClear the state of the sign bit, returns a 32 bit data:\n::\n\n    BitClear(-1, 31) = 2147483647\n\nBit change (BitChange, BitChg)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nBit change 64-bit (BitChg64)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n::\n\n    BitChange(int, int)\n    BitChg(int, int)\n    BitChg64(int, int)\n\nSets a single bit to its complement (so it changes the state of a single bit; 1 becomes 0 \nand vice versa). The second operand denotes the location of the bit which is specified as \nan offset from the low order end of the operand (starting at zero). \n\nThe sign bit is bit 31 on the 32-bit version.\n\nThe sign bit is bit 63 on the 64-bit version of the function.\n\n*Examples:*\n\nChange the state of the a bit of the number 5:\n::\n\n    BitChange(5, 0) = 4 (first bit is set to zero)\n    BitChange(5, 1) = 7 (second bit is set to one)\n    BitChange(5, 2) = 1 (third bit is set to zero)\n    BitChange(5, 3) = 13 (fourth bit is set to one)\n\n\nChange the state of the sign bit:\n::\n\n    BitChange(-1, 31) = 2147483647\n\n\nChangelog\n---------\n+-----------------+-----------------------------------------------------+\n| Version         | Changes                                             |\n+=================+=====================================================+\n| Avisynth 3.7.4  || 64-bit versions of the bit functions.              |\n|                 || Add \"BitAnd64\", \"BitNot64\", \"BitOr64\", \"BitXor64   |\n|                 || Add \"BitShl64\", \"BitSal64\"                         |\n|                 || Add \"BitShr64\", \"BitSar64\"                         |\n|                 || Add \"BitRol64\", \"BitRor64\"                         |\n|                 || Add \"BitChg64\", \"BitClr64\", \"BitSet64\", \"BitTst64\" |\n|                 || Add \"BitSetCount64\"                                |\n+-----------------+-----------------------------------------------------+\n| Avisynth 3.7.3  | Fix bitrol/bitror when first                        |\n|                 | argument is negative (Avisynth+                     |\n|                 | regression)                                         |\n+-----------------+-----------------------------------------------------+\n| Avisynth+ r2632 | BitSetCount                                         |\n+-----------------+-----------------------------------------------------+\n| Avisynth 2.6    | | BitAnd, BitNot, BitOr, BitXor,                    |\n|                 | | BitLShift, BitShl, BitSal,                        |\n|                 | | BitRShiftA, BitRShiftS, BitSar,                   |\n|                 | | BitRShiftL, BitRShiftU, BitShr,                   |\n|                 | | BitRol, BitRor,                                   |\n|                 | | BitTest, BitTst,                                  |\n|                 | | BitSet, BitClear, BitClr,                         |\n|                 | | BitChange, BitChg                                 |\n+-----------------+-----------------------------------------------------+\n\n\n--------\n\nBack to :doc:`Internal functions <syntax_internal_functions>`.\n\n$Date: 2025/02/05 13:48:34 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_internal_functions_boolean.rst",
    "content": "\nAviSynth Syntax - Boolean functions\n===================================\n\nBoolean functions return true or false, if the condition that they test holds\nor not, respectively.\n\nIsBool\n------\n::\n\n    IsBool(var)\n\nTests if *var* is of the bool type. *var* can be any expression allowed by\nthe :doc:`AviSynth Syntax <syntax>`.\n\n*Examples:*\n::\n\n    b = false\n    IsBool(b) = true\n    IsBool(1 < 2 && 0 == 1) = true\n    IsBool(123) = false\n\nIsClip\n------\n::\n\n    IsClip(var)\n\nTests if *var* is of the clip type. *var* can be any expression allowed by\nthe :doc:`AviSynth Syntax <syntax>`.\n\n*Examples:*\n::\n\n    c = AviSource(...)\n    IsClip(c) = true\n    IsClip(\"c\") = false\n\nIsFloat\n-------\n::\n\n    IsFloat(var)\n\nTests if *var* is of the float type. *var* can be any expression allowed by\nthe :doc:`AviSynth Syntax <syntax>`.\n\n*Examples:*\n::\n\n    f = Sqrt(2)\n    IsFloat(f) = true\n    IsFloat(true) = false\n    IsFloat(\"42.\") = false\n    IsFloat(2) = true   # ints are considered to be floats by this function\n    IsReallyFloat(2) = false # see below\n    IsReallyDouble(2.0) = true # see below\n    IsReallyDouble(Floatf(2.0)) = false # see below\n\nAs a workaround for the issue noted above, you may use the following user function: \n::\n\n    ## return true for floating point numbers only\n    function IsReallyFloat(val v)\n    {\n        return (IsInt(v)==false) && IsFloat(v)\n    }\n\n    ## return true for 64 bit doubles only\n    function IsReallyDouble(val v)\n    {\n        return (IsInt(v)==false) && IsFloat(v) && !IsFloatfStrict(v)\n    }\n\nIsFloatfStrict\n--------------\n::\n\n    IsFloatfStrict(var)\n\nTests if *var* is of the exact 32 bit float type. *var* can be any expression allowed by\nthe :doc:`AviSynth Syntax <syntax>`.\n\nSince Avisynth 3.7.4.\n\n*Examples:*\n::\n\n    f = Sqrt(2.0)\n    IsFloatfStrict(f) = false # arithmetic is 64 bit precision since 3.7.4\n    IsFloatfStrict(true) = false\n    IsFloatfStrict(\"42.\") = false # string :)\n    IsFloatfStrict(2) = false\n    IsFloatfStrict((Floatf(2)) = true # direct type cast\n\nIsInt\n-----\n::\n\n    IsInt(var)\n\nTests if *var* is of the int type. *var* can be any expression allowed by the\n:doc:`AviSynth Syntax <syntax>`.\n\nSince 3.7.4 we have 64 bit longs, IsInt returns true for any 32 or 64-bit integer number.\n\n*Examples:*\n::\n\n    IsInt(2) = true\n    IsInt(9007199254740992) = true # big number, 2^53 is stored as 64 bit integer, which is still Int\n    IsInt(2.1) = false\n    IsInt(true) = false\n\nIsLongStrict\n------------\n::\n\n    IsLongStrict(var)\n\nTests if *var* is of the 64-bit int type 'long'. *var* can be any expression allowed by the\n:doc:`AviSynth Syntax <syntax>`.\n\nSince Avisynth 3.7.4.\n\n*Examples:*\n::\n\n    IsLongStrict(2) = false # numeric literals if fit into 32 bit, keep 32 bit integer type\n    IsLongStrict($FFL) = true # forced 64 bit hexadecimal literal\n    IsLongStrict(9007199254740992) = true # big number, 2^53 is stored as 64 bit integer\n    IsLongStrict(2.1) = false\n\nIsString\n--------\n::\n\n    IsString(var)\n\nTests if *var* is of the string type. *var* can be any expression allowed by\nthe :doc:`AviSynth Syntax <syntax>`.\n\n*Examples:*\n::\n\n    IsString(\"test\") = true\n    IsString(2.3) = false\n    IsString(String(2.3)) = true\n\nIsFunction\n----------\n::\n\n    IsFunction(var)\n\nTests if *var* is of the function type. *var* can be any expression allowed by\nthe :doc:`AviSynth Syntax <syntax>`.\n\n*Examples:*\n::\n\n    function MyFunc(clip c) {\n      return c.Invert()\n    }\n    \n    IsFunction(\"MyFunc\") = true\n\nDefined\n-------\n::\n\n    Defined(var)\n\nTests if *var* is defined. Can be used inside :doc:`Script functions <syntax_userdefined_scriptfunctions>` to test if\nan optional argument has been given an explicit value. More formally, the\nfunction returns false if its argument (normally a function argument or\nvariable) has the void ('undefined') type, otherwise it returns true.\n\n*Examples:*\n::\n\n    b_arg_supplied = Defined(arg)\n    myvar = b_arg_supplied ? ... : ...\n\n\nExist\n-----\n::\n\n    Exist(string filename)\n\nTests if the file specified by *filename* exists.\n\n*Examples:*\n::\n\n    filename = ...\n    clp = Exist(filename) ? AviSource(filename) : Assert(false,\n    \\ \"file: \" + filename + \" does not exist\")\n\n\nFunctionExists\n--------------\n::\n\n    FunctionExists(string name)\n\nTests if the function or filter or :doc:`clip property <syntax_clip_properties>` name is defined in the script. \n\n*Examples:*\n::\n\n    ## using a filter only if it exists (AVS+ only)\n    ColorBars  \n    return FunctionExists(\"MyFilter\") \n    \\ ? Apply(\"MyFilter\", Last, \"TEST\") \n    \\ : Last \n\n\nInternalFunctionExists\n----------------------\n::\n\n    InternalFunctionExists(string name)\n\nTests if the function, filter or property name is defined natively within AviSynth+.\n\nUnlike `FunctionExists`, returns false for external plugins and user-defined functions. \n\n\nVarExist\n---------\n::\n\n    VarExist(string name)\n\nTests if the \"name\" variable exists or not.\n\nNote: if variable exists, it returns true regardless of the \"defined\" state of the variable.\n\n\nChangelog\n---------\n+----------------+---------------------------------------------+\n| Version        | Changes                                     |\n+================+=============================================+\n| 3.7.4          | | Changed \"IsFloat\", \"IsInt\"                |\n|                | | Added \"IsFloatfStrict\", \"IsLongStrict     |\n+----------------+---------------------------------------------+\n| Avisynth+      | | Added \"IsFunction\"                        |\n|                | | Added \"FunctionExists\"                    |\n|                | | Added \"InternalFunctionExists\"            |\n|                | | Added \"VarExist\"                          |\n+----------------+---------------------------------------------+\n\nBack to :doc:`Internal functions <syntax_internal_functions>`.\n\n$Date: 2025/02/05 11:53:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_internal_functions_control.rst",
    "content": "\nAviSynth Syntax - Script control functions\n==========================================\n\nThey facilitate flow of control at language level (loading of scripts, arguments checks, etc.).\n\nApply\n~~~~~\n::\n\n    Apply(string func_string [, arg1 [, arg2 [, ... [,argn]]]] )\n\nApply calls the function or filter func_string with arguments arg1, arg2,\n..., argn (as many as supplied).\n\nIt provides a way to call a function or filter **by name** providing \narguments in the usual way as in a typical function call.\n\nConsequently,\n\n* ``Apply(\"f\", x)`` is equivalent to ``f(x)``\n* which in turn is equivalent to ``Eval(\"f(\" + String(x) + \")\")``.\n\nNote that the clip argument must be supplied - ``last`` is not implicitly assumed.\n\n*Examples:*\n::\n\n    # here the same call to BicubicResize as in the Eval() example is shown\n    Apply(\"BicubicResize\", last, 352, 288)\n    # Note that the clip argument must be supplied - 'Last' is not implicitly assumed\n    \n    ## the same action, using Eval\n    Eval( \"BicubicResize(\" + String(new_width) + \",\" + String(new_height) + \")\" )\n\n::\n\n    ## using a filter only if it exists (AVS+ only)\n    ColorBars  \n    return FunctionExists(\"MyFilter\") \n    \\ ? Apply(\"MyFilter\", Last, \"TEST\") \n    \\ : Last \n\n::\n\n    ## using a filter only if it exists (AviSynth 2.6)\n    function MyFilter(clip C, string s) { \n        return C.Subtitle(\"MyFilter: \"+s, align=5)\n    }\n    ColorBars \n    try {\n        Apply(\"MyFilter\", Last, \"TEST\")\n    } catch (err_msg) {\n        # (ignore)\n    }\n    return Last\n\n\n.. _syntax_internal_functions_control_eval:\n\nEval\n~~~~\n::\n\n    Eval(expression [, string \"name\"])\n\nEval evaluates an arbitrary *expression* as if it was placed inside the\nscript at the point of the call to Eval and returns the result of evaluation\n(either to the :doc:`variable <syntax_script_variables>` that is explicitly assigned to or to the last\nspecial variable. \n\nIt works exactly like Import below, except\n\n*   The expression to be evaluated comes from a string instead of a file;\n*   The values of ScriptName, ScriptFile and ScriptDir are not changed;\n*   The current working directory (CWD) is not changed. \n\nArgument name will be shown in the error message beside the script name. Both will be followed \nwith the line number in expression where the error occurred. \n\nVariables in your calling script are available within expression; global variables are not required. \n\nNote: Eval can return the result of any valid expression; usually a clip, but also a string, boolean etc. \n\nYou can use Eval to construct and evaluate expressions dynamically inside your scripts, based on variable input data. \n\nEval is useful as a control structure for creating multi-line block statements without requiring AviSynth+ features. \n\nEval can be used to put aside the need to install external plugins if they are not actually used. \n\n*Examples:*\n::\n\n    ## Building an expression dynamically \n    ## calls BicubicResize(last, 352, 288)\n    settings = \"352, 288\"\n    Eval( \"BicubicResize(\" + settings + \")\" )\n\n::\n\n    ## if...else control structure simulation\n    option = true\n    option  \n    \\ ? Eval(\"\"\"\n        Levels(0, 1.2, 255, 20, 235)\n        Spline36Resize(720, 400)\n        Sharpen(0.2)\n    \"\"\") \n    \\ : Eval(\"\"\"\n        BicubicResize(720, 400)\n        Sharpen(0.3)\n    \"\"\")\n\n::\n\n    ## using a filter only if it is needed; \n    ## in this example, SMDegrain only needs to be installed if the option is true.\n    option = false\n    option \n    \\ ? Eval(\"\"\"\n        SMDegrain(tr=2, thSAD=250, contrasharp=true, refinemotion=true, lsb=true)\n    \"\"\")\n    \\ : Last \n\n::\n\n    ## accessing script variables\n    ColorBars\n    A=Subtitle(\"A\", align=5)\n    Eval(\"A\")\n    return Last ## returns clip 'A'\n\n::\n\n\n    ## setting script variables\n    ColorBars\n    A=Subtitle(\"A\", align=5)\n    Eval(\"B = A.Invert\")\n    return B ## returns clip 'A' with colors inverted\n\n::\n\n    ## Increment a global variable, based on a local variable\n    Eval(\"global my_counter = my_counter + \" + String(increment)) \n\n::\n\n    ## multi-line example with comment and line continuation\n    Eval(\"\"\"\n    ColorBars\n    BicubicResize(352, 288)\n    #FlipVertical\n    Subtitle(\n    \\   \"Width  = \"  + String(Width) + \"\\n\"\n    \\ + \"Height = \" + String(Height)\n    \\ , align=7, lsp=0)\n    \"\"\")\n\n::\n\n    ## Empty expression \n    ## results in error: 'Defined(u) == false'\n    u = Eval(\"#\")   \n\n::\n\n    ## Error reporting\n    ColorBars\n    A=Subtitle(\"A\", size=Height, align=2)\n    Eval(\"\"\"\n    A\n    foo(\"bar\") ## ERROR!\n    \"\"\", \"eval_test_1\") ## name for error reporting purposes\n    return Last\n    \n    results in the error message:\n    Script error: there is no function named \"foo\"\n    (eval_test_1, line 3)\n    (E:\\_test.avs, line 6)\n\n\nImport\n~~~~~~\n::\n\n    Import(filename[, ...] [, bool utf8]))\n\nEvaluates the contents of another script and returns the result of that evaluation.\n\nIt works exactly like Eval above, except\n\n*   The expression to be evaluated comes from a file instead of a string;\n*   The values of ScriptName, ScriptFile and ScriptDir are set to the current (imported) script;\n*   The current working directory (CWD) is set to the current (imported) script.\n*   ``utf8`` if true, assumes filename(s) are UTF8, else (default), assume ANSI. \n\nFunctions, variables and loaded plugins declared inside the imported script are made available to the \nparent script. Import's return value can be assigned to a variable of the parent script; this is most\nuseful when the imported script ends with a clip. \n\nTypically Import is used to make library functions available to the parent script, and the return\nvalue is not used. However this is simply a convention; it is not enforced by the :doc:`AviSynth Syntax <syntax>`.\n\nSee also the dedicated :doc:`Import <../corefilters/import>` page in \n:doc:`Internal filters <../corefilters>` for other possible uses.\n\nSelect\n~~~~~~\n::\n\n    Select(index, item0 [, item1 [, ... [, itemn]]])\n\nReturns the item selected by the index argument, which must be of int type (0\nreturns ``item0``, 1 returns ``item1``, ..., etc). Items can be any :doc:`script variable <syntax_script_variables>`\nor expression of any type and can even be mixed.\n\nIf ``index`` is out of range, an error is raised. \n\n*Examples:*\n::\n\n    # select a clip-brush from a set of presets\n    idx = 2\n    brush = Select(idx, AviSource(\"round.avi\"), \n    \\        rectangle, diagonal, diagonal.FlipHorizontal)\n\nNote - all branches are evaluated:\n::\n\n    index=1\n    Select(index, \"zero\", \"one\", \"two\", \n    \\        Assert(false, \"Select evaluates all branches\")) \n    ## NOTE this code does not run - it throws Assert error\n    ## because Select evaluates all branches\n\nIf this is not desired, use the conditional execution operator:\n::\n\n    index=1\n    x = (index==0) ? \"zero\"\n    \\ : (index==1) ? \"one\"\n    \\ : (index==2) ? \"two\"\n    \\ : Assert(false, \"index out of range\")\n    \n\n\nDefault\n~~~~~~~\n::\n\n    Default(x, d)\n\nReturns *x* if ``Defined(x)`` is true, *d* otherwise. *x* must either be a\nfunction's argument or an already declared script variable (ie a variable\nwhich has been assigned a value) else an error will occur.\n\n*Examples:*\n::\n\n    function myfunc(clip c, ..., int \"strength\") {\n        ...\n        strength = Default(strength, 4) # if not supplied make it 4\n        ...\n    }\n\n\nAssert\n~~~~~~\n::\n\n    Assert(condition [, err_msg])\n\nDoes nothing if ``condition`` is true; throws an error, immediately terminating\nscript execution, if ``condition`` is false. In the later case ``err_msg``, if\nsupplied, is presented to the user; else the standard message \"Assert:\nassertion failed\". shows up.\n\n*Examples:*\n::\n\n    function myfunc(clip c, ..., int \"strength\") {\n        ...\n        strength = Default(strength, 4) # if not supplied make it 4\n        Assert(strength > 0, \"'strength' must be positive\")\n        ...\n    }\n\n\nNOP\n~~~\n::\n\n    NOP()\n\nThis is a no-operation function provided mainly for conditional execution\nwith non-return value items such as :doc:`Import <../corefilters/import>`, when no \"else\" condition is\ndesired. That is, use it whenever the :doc:`AviSynth Syntax <syntax>` requires an\noperation (such as with the ?: operator) but your script does not need one.\n\nReturn value: 0 (int type).\n\n*Examples:*\n::\n\n    preset = want_presets ? AviSource(\"c:\\presets\\any.avi\") : NOP\n    ...\n    loadlib ? Import(\"my_useful_functions.avs\") : NOP\n\n\nUnDefined\n~~~~~~~~~\n::\n\n    UnDefined()\n\nReturns the undefined state.\n\nIt's the state for which Defined() returns false.\n\n*Examples:*\n::\n\n    x = Undefined()\n        Defined(x) # = true\n\n--------\n\nBack to :doc:`Internal functions <syntax_internal_functions>`.\n\n$Date: 2025-02-25 15:25:59-05:00 $\n\n.. _planar: http://avisynth.nl/index.php/Planar\n.. _memory alignment used in the AVIFile output emulation (not yet written):\n    http://avisynth.nl/index.php/AVIFile_output_emulation\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_internal_functions_conversion.rst",
    "content": "\nAviSynth Syntax - Type conversion functions\n===========================================\n\nConversion functions convert between different types. There are also some\n:doc:`numeric functions <syntax_internal_functions_numeric>` that can be classified in this \ncategory, namely: ``Ceil``, ``Floor``, ``Float``, ``Int``, ``IntI``, ``Long``, ``FloatF``,\n``Double`` and ``Round``.\n\nSee :doc:`AviSynth Syntax - Numeric functions <syntax_internal_functions_numeric>`.\n\nValue\n~~~~~\n::\n\n    Value(string)\n\nConverts a decimal string to its associated numeric value.\n\n*Examples:*\n::\n\n    Value (\"-2.7\") = -2.7\n\n\nHexValue\n~~~~~~~~\nHexValue64\n~~~~~~~~~~\n::\n\n    HexValue(string[, int \"pos\"])\n    HexValue64(string[, int \"pos\"])\n\nConverts a hexadecimal string to its associated numeric value.\n\nHexValue returns 32 bit integer.\n\nHexValue64 returns 64 bit long. (since v3.7.4)\n\nConversion will cease at the first non legal number base digit, without \nproducing an error.\n\nFunction returns 0 if ``pos`` is erroenus: ie less than 1 or greater than string length.\n\n.. describe:: int pos (default 1)\n\n    Sets the starting point of the numeric parser. All characters to the \n    left of pos are ignored. Default is 1 (start of string).\n\n*Examples:*\n::\n\n    HexValue (\"FF00\") # 65280\n    HexValue (\"FFA0\", 3) # 160\n    HexValue (\"FFFFFFFF\") # -1\n    HexValue64 (\"FF00\") # 65280\n    HexValue64 (\"FFFFFFFF\") # 4294967295\n\n\nHex\n~~~\n::\n\n    Hex(int [, int \"width\"])\n\nConverts a numerical value to its hexadecimal value string. See `Colors`_ for\nmore information on specifying colors.\n\nFunction returns hex string in uppercase, instead of lowercase.\n\n.. describe:: int width (default 0)\n\n    Width is 0 to 16 the *minimum* width of the returned string. (8 hex digit is the\n    max of Avisynth 32 bit integer, 16 digits for 64 bit numbers)\n\n    Resulting string will be left-padded with zeroes as needed.\n\n    When width is 0 (default) or not supplied then string length is a minimum needed.\n\n*Examples:*\n::\n\n    Hex(10824234) # \"A52A2A\"\n    Hex(255,4) # returns \"00FF\".\n\nString\n~~~~~~\n::\n\n    String(float / int [, string format_string])\n\nConverts a variable to a string. \n\n- String arguments are passed along unchanged; \n- bools are converted to \"true\" or \"false\"; \n- numbers are formatted as described below; \n- other variable types (clip, val) are converted to the empty string. \n\nIf the variable is float or integer and ``format_string`` exists, it\nfirst converts it to a float and then uses format_string to convert the float\nto a string. The syntax of ``format_string`` is as follows:\n\n- ``%[flags][width][.precision]f``\n\n  the leading ``'%'`` and trailing ``'f'`` are required!\n\n  - *width*: the minimum width (the string is never truncated if it is wider than width)\n  - *precision*: the number of digits printed\n  - *flags*:\n\n    - ``-`` left align (instead right align)\n    - ``+`` always print the +/- sign (show only '+' by default)\n    - ``0`` pad (see width) with leading zeroes (pad with spaces by default)  \n    - ``' '`` print a blank instead of a \"+\"\n    - ``#`` always print the decimal point (dropped by default if there are no decimal digits)\n\nYou can also put arbitrary text around the format_string as defined above, similar to the C-language *printf* function.\n\n*Examples:*\n::\n\n    Subtitle( String(1.23) )                    # '1.230000' (six decimals by default for floats)\n    Subtitle( String(123) )                     # '123'      (no decimals by default for ints)\n    \n    Subtitle( String(1.23, \"%0.2f\" ))           # '1.23'\n    Subtitle( String(1.23, \"%0.1f\" ))           # '1.2'\n    Subtitle( String(1.23, \"%5.1f\") )           # '  1.2'    (padded to 5 characters wide)\n    Subtitle( String(1.23, \"%1.3f\") )           # '1.230'    (3 decimals; add trailing zeroes)\n    \n    Subtitle( String(123, \"%0.0f\") )            # '123'      (no decimals for precision=0)\n    Subtitle( String(123, \"%#0.0f\") )           # '123.'     ('#' flag: always show decimal point)\n    Subtitle( String(123, \"%0.2f\") )            # '123.00'   (2 decimals: add trailing zeroes)\n    Subtitle( String(123, \"%5.0f\") )            # '  123'    (padded to 5 characters wide using ' ')\n    Subtitle( String(123, \"%05.0f\") )           # '00123'    (padded to 5 characters wide using '0')\n    \n    Subtitle( String(PI, \"PI=%0.0f\") )          # 'PI=3'     (text around format_string)\n    Subtitle( String(PI, \"PI=%#0.0f\") )         # 'PI=3.'    ('#' flag: always show decimal point)\n    Subtitle( String(PI, \"PI=%2.0f\") )          # 'PI= 3'\n    Subtitle( String(PI, \"PI=%3.2f\") )          # 'PI=3.14'\n    Subtitle( String(PI, \"PI=%0.5f\") )          # 'PI=3.14159'\n    Subtitle( String(PI, \"PI=%6.3f\") )          # 'PI= 3.142'\n    \n    Subtitle( String(32, \"%0.0f\") )             # '32'\n    Subtitle( String(32, \"%3.0f\") )             # ' 32'\n    Subtitle( String(32, \"%8.0f\") )             # '      32'\n\n::\n\n    ## arbitrary text around format_string:\n    Subtitle( String(Last.Height, \"Clip height is %0.0f\") ) # 'Clip height is 480'\n    ## same output as above but using string concatenation:\n    Subtitle( \"Clip height is \" + String(Last.Height) )\n    \n    Subtitle( String(x, \"Value of x is %.3f after AR calc\") )\n    Subtitle( \"Value of x is \" + String(x, \"%.3f\") + \" after AR calc\") )\n    # same as above\n\n\nChangelog\n---------\n+-----------------+----------------------------------+\n| Version         | Changes                          |\n+=================+==================================+\n| 3.7.4           | | Add HexValue64                 |\n|                 | | Add IntI, Long, FloatF, Double |\n+-----------------+----------------------------------+\n| Avisynth+ r2632 | | Hex: added \"width\"             |\n|                 | | Hexvalue: added \"pos\"          |\n+-----------------+----------------------------------+\n\n\n--------\n\nBack to :doc:`Internal functions <syntax_internal_functions>`.\n\n$Date: 2025/03/06 16:00:00 $\n\n.. _Colors: http://avisynth.nl/index.php/Colors\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_internal_functions_debug.rst",
    "content": "\nAviSynth Syntax - Debug helper function\n=======================================\n\nFilter graph handling and logging.\n\n.. _syntax_debug_filtergraph:\n\nFilter graph\n------------\n\nSwitch it on by putting ``SetGraphAnalysis(true)`` at the beginning of the script.\nDump to text file with ``DumpFilterGraph``. E.g. ``DumpFilterGraph(\"graph.txt\", mode=2)``\nOutput is in \"dot\" format, it can be converted to an image with Graphviz as follows:\n::\n\n    dot -Tsvg graph.txt -o graph.svg\n\nSetGraphAnalysis\n~~~~~~~~~~~~~~~~\n::\n\n    SetGraphAnalysis (bool)\n\nEnables (true) or disables (false) graph node insertion into the instantiated filter.\nTo output a filter graph, a graph node must be inserted in the filter.\nWhen a graph node is inserted, performance may decrease slightly due to the increase of internal function calls.\n(In most cases, there is no observable performance degradation.)\n\nDumpFilterGraph\n~~~~~~~~~~~~~~~\n::\n\n    DumpFilterGraph (clip, string \"outfile\", int \"mode\", int \"nframes\", bool \"repeat\")\n\nOutputs a filter graph.\n\n.. describe:: clip\n\n    Clip to output filter graph\n\n.. describe:: string outfile = \"\"\n\n    Output file path\n\n.. describe:: int mode = 0\n\n.. describe:: int nframes = -1\n\n     Outputs the filter graph when processing the specified frame. The cache size and memory usage of \n     each filter at that time are output together. This is effective when you want to know the memory \n     usage of each filter. If -1, output when DumpFilterGraph is called (before the frame is processed).\n\n.. describe:: bool repeat = false\n\n    Valid only when nframes> 0. Outputs a filter graph repeatedly at nframes intervals.\n\nLogging\n-------\n\nSetLogParams\n~~~~~~~~~~~~\n::\n\n    SetLogParams([string target, int level])\n\nSets a file path for a log file, used by LogMsg and internal error reporting.\n\n.. describe:: string target\n\n    Names a file which will be created when the script loads. If attempting to create or write to \n    target fails, the script will raise an error immediately. If the file exists, new log entries\n    will be appended to the end. If omitted, target defaults to ``stderr``.\n\n.. describe:: int level\n\n    Sets the log verbosity; it can be one of the following: \n\n    - LOG_ERROR (1) creates the fewest log entries\n    - LOG_WARNING (2)\n    - LOG_INFO (3) creates the most log entries \n\n    If omitted, level defaults to LOG_INFO. \n\n    For examples see ``LogMsg`` below. \n\nLogMsg\n~~~~~~\n::\n\n    LogMsg(string, int)\n\nCreates a new log entry.\n\n.. describe:: string (required)\n\n    specifies the log message.\n\n.. describe:: int (required)\n\n    specifies the log entry level: see ``SetLogParams`` above.\n\n*Examples:*\n::\n\n    ## creating file and set path for future log entries:\n    SetLogParams(\"<path>\\_test1.log\", LOG_INFO)\n\nlog content at this point:\n\n::\n\n    (empty)\n\n::\n\n    ## logging an INFO message:\n    SetLogParams(\"<path>\\_test2.log\", LOG_INFO)\n    LogMsg(\"this is a test\", LOG_INFO)\n\nlog contents at this point:\n::\n\n    ---------------------------------------------------------------------\n    INFO: this is a test\n\n::\n\n    ## logging a script error:\n    SetLogParams(\"<path>\\_test3.log\", LOG_INFO)\n    foo(\"bar\") ## ERROR!\n\nlog contents (redundant entries are common):\n::\n\n    ERROR: Script error: There is no function named 'foo'.\n    ---------------------------------------------------------------------\n    ERROR: Script error: There is no function named 'foo'.\n    (<path>\\_test.avs, line 35)\n\n::\n\n    ## logging INFO context for script error:\n    SetLogParams(\"<path>\\_test4.log\", LOG_INFO)\n    function MyFunction(clip C)\n    {\n        C\n        try {\n            foo(\"bar\") ## ERROR!\n        } catch (err_msg) {\n            msg2 = \"Error in MyFunction: \"\n            LogMsg(Time(\"%Y-%m-%d %I:%M:%S %p, %z\") + \": \" + msg2, LOG_INFO)\n            #Assert(false, msg2 + err_msg) ## optional: stop script, else continue\n        }\n        return Last\n    }\n\nlog contents (redundant entries omitted):\n\n::\n\n    ---------------------------------------------------------------------\n    ERROR: Script error: There is no function named 'foo'.\n    (<path>\\_test.avs, line 54)\n    ---------------------------------------------------------------------\n    INFO: 2017-11-12 11:03:41 AM, -0500: Error in MyFunction:\n    (<path>\\_test.avs, line 54)\n\nChangelog\n---------\n+----------------+----------------------------------+\n| Version        | Changes                          |\n+================+==================================+\n| AviSynth 3.7.4 | Fix SetLogParams defaults        |\n+----------------+----------------------------------+\n| AviSynth+      | all of them                      |\n+----------------+----------------------------------+\n\nBack to :doc:`Internal functions <syntax_internal_functions>`.\n\n$Date: 2024/04/10 9:43:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_internal_functions_frame_properties.rst",
    "content": "\nAviSynth Syntax - Frame properties\n==================================\n\n\nThe concept was ported from VapourSynth.\n\nFrame properties are per-frame data. Source or other filters can store useful \ndata into frame properties such as information on colorimetry.\n\nImagine them as an array of zero or more elements of PropertyName=Value pairs.\n\nReading or writing them is possible either in runtime environment or at the normal script level. \n\nAvisynth provides the necessary framework for handling (set, read, clear, pass) such properties,\nboth from users scripts and from the Filter SDK.\n\nBefore v3.6.2test7 none of its internal functions (such as color space converters) were able\nto set or work upon frame property values. However the set of frame properties which are \nactively used by Avisynth core can extend in later versions. E.g. in 3.7.x color space converters or \neven \"Text\" filter read and/or set some colormetry or color matrix related properties.\n\nAnd there are external filters (like avsresize) and source plugins that use frame properties.\n\nDeveloper info (see also in Filter SDK):\n\nOn filter level the set of frame properties should be copied from a previous (or specific) input frame.\nWhen a filter is using ``env->MakeWritable`` in its ``GetFrame`` method this happens automatically. \n\nA simple ``env->NewVideoFrame`` however means a dead-end for frame property passing mechanism. Filter \nmust either use ``env->NewVideoFrameP`` which has an additional parameter: a source frame (origin) of \nthe frame properties. Or frame properties have to be copied later, programatically by the ``copyFrameProps``\n``ScriptEnvironment`` function. \n\nFor compatibility reasons ``NewVideoFrameP`` must be called adaptively instead of the traditional \n``NewVideoFrame``, since it does not exist in older Avisynth versions. Only usable after detecting \nAvisynth interface version 8 (NewVideoFrameP was introduced in v8).\n\nWhat happens if this copy is not done properly? Nothing deadly, but then the filter is a dead-end for \nthe flow of frame properties since NewVideoFrame constructs new frame without them. Old filters which are\nnot written with this in mind will behave like this.\n\nFrame property getter functions are evaluated at every frame. They can be used inside the scripts passed \nto runtime filters (ScriptClip).\n\nFrame property setters can be called both at script level and in runtime. When a property is set on script \nlevel it will be constant along the lifetime of the whole clip, unless it is changed in runtime, inside ScriptClip. \n\nDefinition\n----------\n\nFrame properties are stored as key-value pairs.\nEach video frame can contain such a list, which can even be different from frame to frame.\n\n* Key is an alphanumeric identifier.\n\n* Value can be of single value or array of type\n\n  * 64 bit integer (32 bit integer when converted to AVSValue inside Avisynth+, AVSValue limitation)\n  * 64 bit double (32 bit float when converted to AVSValue inside Avisynth+, AVSValue limitation)\n  * string (or byte data) with given length. Strings are null terminated.\n    The content whether it is string or binary data can be given as a hint; from Avisynth scripting \n    only strings allowed.\n\n  * frame reference (PVideoFrame)\n  * clip reference (PClip)\n\nManipulation modes\n------------------\n\nProperty setting has 3 modes: 0-replace 1-append 2-touch.\n(for developers: see ``AVSPropAppendMode`` in avisynth.h)\n\n* 0 - single value for that key is replaced\n\n* 1 - property is appended (make arrays by calling with mode=1 consecutively)\n\n* 2 - touch (deprecated, just creates the key)\n\nReserved frame property names\n-----------------------------\n\nThere are quasi-standard frame property names which are used widespread.\n\nSome of them are used in Avisynth core:\n\n- _ChromaLocation\n- _ColorRange\n- _Matrix\n\nbut the others are used only by external plugins.\n\nFrame property concept came from VapourSynth (see \"Reserved Frame Properties\" \nat http://www.vapoursynth.com/doc/apireference.html). But it is convenient that \nAvisynth plugins use the same property names and their and values. \n\nKeys starting with _ have strictly defined meanings specified below. It is acceptable \nto not set any of these keys if they are unknown. It is also a fatal error to set them \nto a value not specified below.\n\n_ChromaLocation\n~~~~~~~~~~~~~~~\n\n    int _ChromaLocation\n\n    Chroma sample position in YUV formats.\n\n        0=left, 1=center, 2=topleft, 3=top, 4=bottomleft, 5=bottom.\n\n        Synonyms:\n\n        * left, mpeg2\n        * center, jpeg, mpeg1\n\n_ColorRange\n~~~~~~~~~~~\n\n    int _ColorRange\n\n    Full or limited range (PC/TV range). Primarily used with YUV formats, but can mark Studio RGB as well.\n\n        0=full range, 1=limited range (RGB: narrow range).\n\n_Primaries\n~~~~~~~~~~\n\n    int _Primaries\n\n    Color primaries as specified in ITU-T H.265 Table E.3. \n\n_Matrix\n~~~~~~~\n\n    int _Matrix\n\n    Matrix coefficients as specified in ITU-T H.265 Table E.5. \n\n_Transfer\n~~~~~~~~~\n\n    int _Transfer\n\n    Transfer characteristics as specified in ITU-T H.265 Table E.4. \n\n_FieldBased\n~~~~~~~~~~~\n\n    int _FieldBased\n\n    If the frame is composed of two independent fields (interlaced).\n\n        0=frame based (progressive), 1=bottom field first, 2=top field first \n\n_AbsoluteTime\n~~~~~~~~~~~~~\n\n    float _AbsoluteTime\n\n    The frame’s absolute timestamp in seconds if reported by the source filter. Should only be set \n    by the source filter and not be modified. Use durations for all operations that depend on frame length. \n\n_DurationNum\n~~~~~~~~~~~~\n\n    int _DurationNum\n\n_DurationDen\n~~~~~~~~~~~~\n\n    int _DurationDen\n\n    The frame’s duration in seconds as a rational number.\n    Filters that modify the framerate should also change these values.\n\n    This fraction (_DurationNum/_DurationDen) should always be normalized. \n\n_Combed\n~~~~~~~\n\n    int _Combed (boolean)\n\n    Whether or not the frame needs postprocessing, usually hinted from field matching filters. \n\n_Field\n~~~~~~\n\n    int _Field\n\n    This property signals which field was used to generate this frame.\n    VapourSynth is using it in core.std.SeparateFields, in Avisynth core it is not used at all.\n\n        0=from bottom field, 1=from top field. \n\n_PictType\n~~~~~~~~~\n\n    string _PictType\n\n    A single character describing the frame type. It uses the common IPB letters but other\n    letters may also be used for formats with additional frame types.\n\n_SARNum\n~~~~~~~\n\n    int _SARNum\n\n_SARDen\n~~~~~~~\n\n    int _SARDen\n\n    Pixel (sample) aspect ratio as a rational number. \n\n_SceneChangeNext\n~~~~~~~~~~~~~~~~\n\n    int _SceneChangeNext (boolean)\n\n    If 1, this frame is the last frame of the current scene. The next frame starts a new scene. \n\n_SceneChangePrev\n~~~~~~~~~~~~~~~~\n\n    int _SceneChangePrev (boolean)\n\n    If 1, this frame starts a new scene. \n\nProperty set\n------------\n\nInput value of setter functions are to be come either\n\n- from the return value of \"function objects\"\n- direct value \n\nProperty setter function names begin with ``propSet``\n\nCommon parameters:\n\n::\n\n    clip c,\n    string key_name,\n    direct value of supported types (integer, float, string, array, clip) or a \"function object\"\n    int \"mode\": 0=replace (default), 1=append, 2=touch. There is no append mode for inserting a full array into the property. \n\npropSet\n~~~~~~~\n::\n\n    propSet(clip, string key_name, function func_obj [, integer \"mode\"])\n\ngeneric property setter, automatic type recognition by the return value of the function object \n\n::\n\n    propSet(clip, string key_name, integer value [, integer \"mode\"])\n    propSet(clip, string key_name, float value [, integer \"mode\"])\n    propSet(clip, string key_name, string value [, integer \"mode\"])\n    propSet(clip, string key_name, array value)\n    propSet(clip, string key_name, clip value [, integer \"mode\"])\n\nThe above functions are setting a property from a directly passed values \n\nnote: array must contain only the similarly typed values, e.g. cannot mix strings with integers.\n\npropSetInt\n~~~~~~~~~~\n::\n\n    propSetInt(clip, string key_name, function func_obj [, integer \"mode\"])\n\npropSetFloat\n~~~~~~~~~~~~\n::\n\n    propSetFloat(clip, string key_name, function func_obj [, integer \"mode\"])\n\npropSetString\n~~~~~~~~~~~~~\n::\n\n    propSetString(clip, string key_name, function func_obj [, integer \"mode\"])\n\npropSetArray\n~~~~~~~~~~~~\n\n::\n\n    propSetArray(clip, string key_name, function func_obj [, integer \"mode\"])\n\npropSetClip\n~~~~~~~~~~~\n\n::\n\n    propSetClip(clip, string key_name, function func_obj [, integer \"mode\"])\n\nthese setters accept only the specific type \n\nProperty get\n------------\n\nGet properties by name or as a whole.\n\nSince AviSynth 3.7.1: allow propGetXXX property getter functions called as normal functions, outside runtime.\n\nBy default frame property values are read from frame#0 which index can be overridden by the offset parameter.\n\nWhen called from inside runtime functions will return frame properties of the actual frame (+offset).\n\n\nCommon parameters:\n\n::\n\n    clip c, \n    string key_name, \n    integer \"index\", (default 0): for zero based indexing array access \n    integer \"offset\" (default 0), similar to the other runtime functions: frame offset (e.g. -1: previous, 2: next next) \n\npropGetAny\n~~~~~~~~~~\n::\n\n    propGetAny(clip, string key_name[, integer \"index\", integer \"offset\"])\n\nreturns the automatically detected type \n\npropGetInt\n~~~~~~~~~~\n::\n\n    propGetInt(clip, string key_name[, integer \"index\", integer \"offset\"])\n\nreturns only if value is integer, throws an error otherwise (note: unlike Avisynth integer frame properties internally use 64 bit integers) \n\npropGetFloat\n~~~~~~~~~~~~\n::\n\n    propGetFloat(clip, string key_name[, integer \"index\", integer \"offset\"])\n\nIf the content is not of floating point type, it throws an error. Until version 3.7.3, \nthe internal representation of floating point numbers was 32-bit float. Starting from \nAvisynth 3.7.4, float frame properties are read as real 64-bit doubles.\n\npropGetString\n~~~~~~~~~~~~~\n::\n\n    propGetString(clip, string key_name[, integer \"index\", integer \"offset\"])\n\nreturns only if value is string, throws an error otherwise \n\npropGetAsArray\n~~~~~~~~~~~~~~\n::\n\n    propGetAsArray(clip, string key_name[, integer \"index\", integer \"offset\"])\n\nA frame property can hold multiple values of the same type: it can be an array.\n\n``propGetAsArray`` returns an array. For a single property the array size will be 1.\n\npropGetClip\n~~~~~~~~~~~\n::\n\n    propGetClip(clip, string key_name[, integer \"index\", integer \"offset\"])\n\nreturns only if value is clip, throws an error otherwise\n\npropGetAll\n~~~~~~~~~~\n::\n\n    propGetAll(clip [, integer \"offset\"])\n\nReturns all frame properties in an array of [key-value] pairs. Array size will be ``numProps``\n\nEach key-value pair is contained in a two dimensional subarray.\nIf the property value itself is an array again then \"value\" will be an array as well.\n\nThis array contains all properties of the specific frame.\n\nThey are accessible with the associative feature of AviSynth array access. (See syntax there)\n\n**Example:**\n\n::\n\n    ScriptClip(\"\"\"last.propSet(\"cica\",\"hello\"+String(current_frame)).\\\n      propSetInt(\"test_i1\",function[](clip c) { return current_frame*3 }).\\\n      propSet(\"test_i2\", current_frame * 2) \"\"\")\n    ScriptClip(\"\"\"p = propGetAll() \\\n    SubTitle(\"size:\" + String(p.ArraySize()) + \" \" + \\\n                      String(p[\"test_i1\"]) + \" \" + \\\n                      String(p[\"cica\"]) + \" \" + \\\n                      String(p[\"test_i2\"]))\"\"\")\n    ScriptClip(\"\"\"p = propGetAll() \\\n    SubTitle(\"size:\" + String(p.ArraySize()) + \" \" + \\\n       String(p[0,1]) + \" \" + \\\n       String(p[1,1]) + \" \" + \\\n       String(p[2,1]), x=0, y=20)\"\"\")\n\n**Example (read-write basic)**\n\n::\n\n    ColorBars()\n    \n    # just practicing with function objects\n    ScriptClip(function[](clip c) { c.Subtitle(String(current_frame)) })\n    \n    # write frame properties with function object\n    ScriptClip(\"\"\"propSetInt(\"frameprop_from_str\",func(YPlaneMax))\"\"\")\n    # write frame properties with traditional script string\n    ScriptClip(function[](clip c) { propSetInt(\"frameluma_sc_func\",func(AverageLuma)) })\n    \n    # read frame properties (function object, string)\n    ScriptClip(function[](clip c) { SubTitle(string(propGetInt(\"frameprop_from_str\")), y=20) })\n    ScriptClip(\"\"\"SubTitle(string(propGetInt(\"frameluma_sc_func\")), y=40)\"\"\")\n    \n    return last\n\n**Example (almost everything)**\n\n::\n\n    ColorBars(width=640, height=480, pixel_type=\"yv12\", staticframes=true)\n    \n    ScriptClip(function[](clip c) { propSetString(\"s\",function[](clip c) { return \"Hello \" + string(current_frame) }) })\n    ScriptClip(function[](clip c) { propSetString(\"s\",function[](clip c) { return \"Hello array element #2 \" }, mode=1) })\n    ScriptClip(function[](clip c) { propSetString(\"s\",function[](clip c) { return \"Hello array element #3 \"}, mode=1 ) })\n    \n    ScriptClip(function[](clip c) { propSetString(\"s2\",function[](clip c) { return \"Another property \"} ) })\n    \n    ScriptClip(function[](clip c) { propSetInt(\"s_int\",function[](clip c) { return current_frame*1 }) })\n    ScriptClip(function[](clip c) { propSetInt(\"s_int\",function[](clip c) { return current_frame*2 }, mode=1) })\n    ScriptClip(function[](clip c) { propSetInt(\"s_int\",function[](clip c) { return current_frame*4 }, mode=1 ) })\n    \n    ScriptClip(function[](clip c) { propSetFloat(\"s_float\",function[](clip c) { return current_frame*1*3.14 }) })\n    ScriptClip(function[](clip c) { propSetFloat(\"s_float\",function[](clip c) { return current_frame*2*3.14 }, mode=1) })\n    ScriptClip(function[](clip c) { propSetFloat(\"s_float\",function[](clip c) { return current_frame*3*3.14 }, mode=1 ) })\n    \n    ScriptClip(function[](clip c) { propSetArray(\"s_float_arr\",function[](clip c) { return [1.1, 2.2] } ) })\n    ScriptClip(function[](clip c) { propSetArray(\"s_int_arr\",function[](clip c) { return [-1,-2,-5] } ) })\n    ScriptClip(function[](clip c) { propSetArray(\"s_string\",function[](clip c) { return [\"ArrayElementS_1\", \"ArrayElementS_2\"] } ) })\n    #ScriptClip(\"\"\"propDelete(\"s\")\"\"\")\n    ScriptClip(function[](clip c) {\n      y = 0\n      SubTitle(\"Prop Key count =\" + String(propNumKeys), y=y)\n      y = y + 15\n      numKeys = propNumKeys() - 1\n      for ( i = 0 , numKeys) {\n        propName = propGetKeyByIndex(index = i)\n        propType = propGetType(propName)\n        SubTitle(\"#\"+String(i) + \" property: '\" + propName + \"', Type = \" + String(propType) , y=y)\n        y = y + 15\n    \n        for(j=0, propNumElements(propName) - 1) {\n          SubTitle(\"element #\" + String(j) + \", size = \" + String(propType == 3 ? propGetDataSize(propName, index=j) : 0) + \", Value = \" + String(propGetAny(propName, index=j)), y = y)\n          #SubTitle(\"element #\" + String(j) + \" size = \" + String(propType == 3 ? propGetDataSize(propName, index=j) : 0) + \", Value = \" + String(propGetAny(propName, index=j)), y = y)\n          y = y + 15\n        }\n      }\n      return last\n    })\n    \n    ScriptClip(function[](clip c) {\n      a = propGetAsArray(\"s\")\n      y = 100\n      x = 400\n      SubTitle(string(a.ArraySize()), x=x, y=y)\n      for(i=0, a.ArraySize()-1) {\n        SubTitle(\"[\"+String(i)+\"]=\"+ String(a[i]),x=x,y=y)\n        y = y + 15\n      }\n      return last\n    })\n    \n    # get int array one pass\n    ScriptClip(function[](clip c) {\n      a = propGetAsArray(\"s_int\")\n      y = 440\n      x = 400\n      SubTitle(\"Array size=\" + string(a.ArraySize()), x=x, y=y)\n      y = y + 15\n      for(i=0, a.ArraySize()-1) {\n        SubTitle(\"[\"+String(i)+\"]=\"+ String(a[i]),x=x,y=y)\n        y = y + 15\n      }\n      return last\n    })\n    \n    # get float array one pass\n    ScriptClip(function[](clip c) {\n      a = propGetAsArray(\"s_float\")\n      y = 440\n      x = 200\n      SubTitle(\"Array size=\" + string(a.ArraySize()), x=x, y=y)\n      y = y + 15\n      for(i=0, a.ArraySize()-1) {\n        SubTitle(\"[\"+String(i)+\"]=\"+ String(a[i]),x=x,y=y)\n        y = y + 15\n      }\n      return last\n    })\n    \n    # get string array\n    ScriptClip(function[](clip c) {\n      a = propGetAsArray(\"s_string\")\n      y = 440\n      x = 000\n      SubTitle(\"Array size=\" + string(a.ArraySize()), x=x, y=y)\n      y = y + 15\n      for(i=0, a.ArraySize()-1) {\n        SubTitle(\"[\"+String(i)+\"]=\"+ String(a[i]),x=x,y=y)\n        y = y + 15\n      }\n      return last\n    })\n\nAviSynth 3.7.1: allow propGetXXX property getter functions called as normal functions, outside runtime.\nBy default frame property values are read from frame#0 which index can be overridden by the offset parameter.\n\n**Example:**\n\n::\n\n    Colorbars()\n    PropSet(last, \"hello\", 1) # Set to 1 for all frames\n    # Override to 2 with runtime function except for frameNo=1\n    ScriptClip(\"\"\"if(current_frame!=1) {propSet(\"hello\",2)}\"\"\")\n    n0 = propGetInt(\"hello\") # same as propGetInt(\"hello\",offset=0)\n    # or get the frame property from the Nth frame\n    n1 = propGetInt(\"hello\",offset=1)\n    n2 = propGetInt(\"hello\",offset=2)\n    # n0 and n2 is 2 (overridden in runtime)\n    # n1 will be 1 (keeps global setting)\n    SubTitle(\"n0/n1/n2=\" + \"{n0}/{n1}/{n2}\".Format)\n\nDeleting properties\n-------------------\n\nDeletes specific properties or all property entries \n\npropDelete\n~~~~~~~~~~\n::\n\n    propDelete(clip, string)\n\nDeletes a property by name. If property does not exist, do nothing.\n\n* clip (required) specifies clip.\n* string (required) or string array: key_name (case sensitive) specifies the \n  \n  - name of the parameter to delete \n  - a regex expression, starts with \"^\", ends with \"$\"\n  - a wildcard name specifier (contains ``*``)\n\n*Example:*\n\n::\n\n    ScriptClip(\"\"\"propDelete(\"my_spec_prop\")\"\"\")\n    propDelete(\"_*\") # deletes all properties starting with \"_\"\n\npropClearAll\n~~~~~~~~~~~~\n::\n\n    propClearAll(clip)\n\nClears all properties for a given video frame\n\n* clip (required) specifies clip. \n\nOther property functions\n------------------------\n\npropShow\n~~~~~~~~\n\n    This debug filter lists frame properties on screen. \n    Listing appears as a name = value list and can be filtered\n    \n    See here: :doc:`propShow <../corefilters/propShow>`.\n\npropGetDataSize\n~~~~~~~~~~~~~~~\n::\n\n    propGetDataSize(clip, string key_name [, integer \"index\", integer \"offset\"])\n\nreturns the size of the string or underlying data array \n\npropNumElements\n~~~~~~~~~~~~~~~\n::\n\n    propNumElements(clip, string key_name [, integer \"offset\"])\n\nreturns the array size of a given property. 1=single value \n\npropNumKeys\n~~~~~~~~~~~\n::\n\n    propNumKeys(clip, [, integer \"offset\"])\n\nreturns number of entries (keys) for a frame \n\npropGetKeyByIndex\n~~~~~~~~~~~~~~~~~\n::\n\n    propGetKeyByIndex(clip, integer \"index\" [, integer \"offset\")\n\nreturns the key name for the Nth property (zero based, 0<=index<propNumKeys) \n\npropGetType\n~~~~~~~~~~~\n::\n\n    propGetType(clip, string key_name [, integer \"offset\"])\n\nreturns the type of the given key\n\n* unset: 0\n* integer: 1\n* float: 2\n* string: 3\n* clip: 4\n* frame: 5 \n\npropCopy\n~~~~~~~~\n::\n\n    propCopy(clip, clip [,bool \"merge\"], [,string[] \"props\"], [,bool \"exclude\"]\n\nCopies the frame properties of the second clip to the first.\n\nParameter ``merge`` (default false): \n\n* when false: exact copy (original target properties will be lost)\n* when true: keeps original properties, appends relevant properties from source but \n  overwrite if a parameter with the same name already exists. \n\nParameter ``props`` \n  a string or string array:\n\n  - name of the parameter to copy\n  - a regex expression, starts with \"^\", ends with \"$\"\n  - a wildcard name specifier (contains ``*``)\n  \nParameter ``exclude``\n\n  - when true specify that the property list is a negative list.\n\n*Example:*\n\n::\n\n    PropCopy(a) # make all properties the same with of clip a\n    PropCopy(a, merge=true) # Adds new properties from clip a, overwrites if already exists\n    \n    # Add properties from clip \"a\" which end with \"1\" or \"2\" \n    b.PropCopy(a, merge=true, props=[\"*2\",\"*1\"])\n    \n    # Add properties from clip \"a\" where not started with \"_\"\n    b.PropCopy(a, merge=true, props=\"_*\", exclude = True)\n    \n    # same with regex\n    b.PropCopy(a, merge=true, props=\"^[^_].*$\")\n    \n    # erase all, then copy all, except listed ones\n    propCopy(org,props=[\"_Matrix\", \"_ColorRange\"], exclude = true)\n\nChangelog\n---------\n+----------------+--------------------------------------------------+\n| Version        | Changes                                          |\n+================+==================================================+\n| 3.7.4          | | wildcard and regex support in props parameter  |\n|                |   for propDelete, propShow, propCopy             |\n|                | | add \"props\" parameter to propShow as well      |\n+----------------+--------------------------------------------------+\n| 3.7.2          | | exclude parameter for negative list            |\n+----------------+--------------------------------------------------+\n| AviSynth 3.7.1 | | allow propGetXXX called outside                |\n|                |   runtime functions                              |\n|                | | add propCopy                                   |\n+----------------+--------------------------------------------------+\n| AviSynth 3.7.0 | add propGetType                                  |\n+----------------+--------------------------------------------------+\n\nBack to :doc:`Internal functions <syntax_internal_functions>`.\n\n$Date: 2025/03/04 12:20:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_internal_functions_function_object.rst",
    "content": "\nAviSynth Syntax - Cast to function object\n=========================================\n\nFunc\n~~~~\n::\n\n    Func( script_function )\n\nConverts an internal function to a valid function object.\n\nFor some functions (e.g. ScriptClip) it is convenient to use their \"function object\" parameter version.\nWith this function an internal function can be converted into it.\n\nSee also: :doc:`Function objects <syntax_function_objects>`\n\n::\n\n    # write frame properties with function object\n    ScriptClip(\"\"\"propSetInt(\"frameprop_from_str\",func(YPlaneMax))\"\"\")\n    # write frame properties with traditional script string\n    ScriptClip(function[](clip c) { propSetInt(\"frameluma_sc_func\",func(AverageLuma)) })\n\nChangelog\n~~~~~~~~~\n+----------------+------------------------------------------------------------+\n| Version        | Changes                                                    |\n+================+============================================================+\n| Avisynth 3.6.0 | Added function objects                                     |\n+----------------+------------------------------------------------------------+\n\n--------\n\nBack to :doc:`Internal functions <syntax_internal_functions>`.\n\n\n$Date: 2025-02-25 17:06:49-05:00 $\n\n.. _planar: http://avisynth.nl/index.php/Planar\n.. _memory alignment used in the AVIFile output emulation (not yet written):\n    http://avisynth.nl/index.php/AVIFile_output_emulation\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_internal_functions_global_options.rst",
    "content": "\nAviSynth Syntax - Global options and resource control\n=====================================================\n\nMemory, CPU, cache directory and other global settings adjustments.\n\nSetMemoryMax\n~~~~~~~~~~~~\n::\n\n    SetMemoryMax(int amount, int \"type\", int \"index\")\n\nSets the maximum memory (in MB) that AviSynth uses for its internal Video\nFrame cache to the value of *amount*. Setting to zero just returns the current Memory Max value.\n\nIn Avisynth+ default Memory Max is 1024MB for 32 bits and 4096MB on the x64 version.\nThis limit is fine-tuned however if physical memory is low:\n\n``DefaultMemoryMax = minimum(physical_memory / 4, secondary_memory_max_limit)``\n\n``Type`` and ``index`` are additional arguments for devices such as GPUs.\nUsed to be used in Avisynth Neo, where Avisynth core was able to govern CUDA aware plugins\nand their resources: memory usage could be managed individually for devices such as GPUs.\n\nThis special option was introduced in Neo, but is not used in ordinary Avisynth release.\n\n.. describe:: int amount\n\n    Device (including CPU) memory limit (MB) \n\n.. describe:: int type\n\n    Device type. The following values are available:\n\n    * ``DEV_TYPE_CPU``: CPU (default) \n    * ``DEV_TYPE_CUDA``: GPU \n\n.. describe:: int index\n\n    Device number. Same as onCUDA device_index. Only 0 for DEV_TYPE_CPU. \n\n    Default value: 0 \n\nReturn value: Actual MemoryMax value set.\n\n*Examples:*\n::\n\n    SetMemoryMax(16384)\n\n\nSetCacheMode\n~~~~~~~~~~~~\n::\n\n    SetCacheMode(int mode)\n\nFine tunes the internal video frame caching strategy.\n\nAvailable values:\n\n*   0 or ``CACHE_FAST_START``: start up time and size balanced mode (default)\n*   1 or ``CACHE_OPTIMAL_SIZE`` slow start up but optimal speed and cache size \n\n\n.. _setmaxcpu:\n\n\nSetMaxCPU\n~~~~~~~~~\n::\n\n    SetMaxCPU([string feature1, string feature2, ...])\n\nA debug control method. Intel processor specific.\n\nLimits the CPU capabilities which AviSynth reports to its core and thus for external plugins and filters\nthrough :ref:`env->GetCPUFlags <cplusplus_getcpuflags>` or :ref:`env->GetCPUFlagsEx <cplusplus_getcpuflags>`.\n\nAvailable values (**Intel** CPU features):\n\n*   ``\"\"`` or ``\"none\"`` for zero SIMD support, no processor flags are reported\n*   ``\"mmx\"``, ``\"sse\"``, ``\"sse2\"``, ``\"sse3\"``, ``\"ssse3\"``, ``\"sse4\"`` or ``\"sse4.1\"``,\n    ``\"sse4.2\"``, ``\"avx\"``, ``\"avx2\"``, ``\"avx512base\"``, ``\"avx512fast\"`` \n\nAvailable values (**ARM64** (aarch64) CPU features):\n\n*   ``\"\"`` or ``\"none\"`` for zero SIMD support, no processor flags are reported\n*   ``\"neon\"``, ``\"dotprod\"``, ``\"sve2\"``\n\nParameters are case insensitive. \n\n* Processor options w/o any modifier will limit the CPU flag report to at most the processor level.\n* When \"feature\" is ended by '+', relevant processor feature flag will be switched on\n* When \"feature\" is ended by '-', relevant processor feature flag will be removed. \n\nNotes:\n* ``\"avx2\"`` triggers FMA3 flag as well.\n* ``\"avx512base\"`` enables all AVX-512 base features, as a group (F, CD, BW, DQ, VL).\n* ``\"avx512fast\"`` enables all Ice Lake AVX-512 features, as a group (VNNI, VBMI, VBMI2, BITALG, VPOPCNTDQ) without \nthe Avisynth-irrelevant and AVX10 not-required cryptographic flags (VAES, VPCLMULQDQ, GFNI).\n* The cryptographic flags (VAES, VPCLMULQDQ, GFNI) are not vital for Avisynth algorithms, they are only checked for\ndistinguishing the Ice Lake generation from the earlier Skylake-X and Cascade Lake (slow AVX-512) server processors.\n\nMultiple options can be put in a comma separated list. They will evaluate in that order. \n\nThe ``\"avx512base\"`` and ``\"avx512fast\"`` cover a group of feature flags. Internal Avisynth+ codes test for \n``CPUF_AVX512_BASE`` and ``CPUF_AVX512_FAST`` in internal AVX-512 optimized paths.\n\n.. note::\n\n    **Usability of AVX-512 and Throttling**\n\n    While AVX-512 features were first introduced with Skylake-SP (Intel Xeon), the earliest client CPUs\n    to implement a *truly usable* 512-bit wide vector unit were **Ice Lake (10th Generation Mobile) and \n    Rocket Lake (11th Generation Desktop)**. These later microarchitectures significantly reduced the severe \n    clock-speed throttling penalty and the voltage/frequency impact (AVX-512 down-binning) that plagued \n    earlier implementations.\n\n    For this reason, high-performance projects like **FFmpeg** often use feature checks similar to ``\"avx512fast\"`` \n    (CPU flag ICL - Ice Lake in their naming) to classify a processor as having \"good\" or \"usable\" AVX-512 support. \n    Compiling and testing code solely with ``\"avx512base\"`` (which often only implies first-generation AVX-512) can \n    lead to **misleadingly poor performance** due to aggressive clock throttling on older hardware.\n\n    Developers should generally use the ``\"avx512fast\"`` group for realistic performance testing of 512-bit code paths.\n    \n    Users, who have AVX512 Base level CPU but \"Fast\" is not fulfilled, must manually enable the Base features,\n    despite that the individual flags (F, CD, BW, DQ, VL) may exist.\n\n\n*Examples:*\n::\n\n    SetMaxCPU(\"SSE2\") #reports at most SSE2 processor (even if AVX2 is available)\n    SetMaxCPU(\"avx,sse4.1-\") #limits to avx2 but explicitely removes reporting sse4.1 support\n    SetMaxCPU(\"none,avx2+\") #limits to plain C, then switches on AVX2-only support\n    SetMaxCPU(\"avx512base+\") # Forcibly switches on AVX512 Base support, for users of old AVX512 CPU.\n\nOnCPU\n~~~~~\n\nOnCPU/OnCUDA (collectively called OnDevice)\n\nSince 3.6 Avisynth Neo features were backported to Avisynth+. \nSuch as supporting \"devices\", like CPU and CUDA and the data transfer between them.\n\nNeo has rewritten some internal and external plugins to CUDA processing.\nCUDA support needs special build, still experimental after v3.7. \nAvisynth itself does not process in CUDA, even not in such builds, just\nprovides the framework work such plugins.\n\nIf all are valid, the chain will be as follows.\n\nUpstream → Upstream cache → Thread → Transfer → Downstream cache → Downstream → is \nthe flow of frame data (reverse of GetFrame call direction)\n\nNumber of prefetch frames\n\n*   0: Synchronous call without all cache\n*   1: Synchronous call, but only transfer is read ahead and executed asynchronously. Downstream cache is enabled.\n*   2 or more: Pre-read upstream processing using threads. Both upstream and downstream caches are valid. \n\nThe number of upstream threads is fixed at 1 thread when prefetch = 2 or more, and \nthe number of prefetches is fixed at 2. The downstream look-ahead number is set to the specified prefetch sheet.\n\n::\n\n    OnCPU(clip, int \"num_prefetch\") \n\n.. describe:: clip\n\n    This clip is processed by the CPU. In other words, the processing before this is processed by the CPU. \n\n.. describe:: int num_prefetch\n\n    Here you specify the number of frames to prefetch. About 2 will give you enough performance. \n    Unlike Prefetch, it has only one thread because it is a prefetch for parallelizing processing on the GPU and CPU. \n\n    default: 0 \n\nIf 0 is specified, it will be a synchronous call without using threads.\n\nOnCUDA\n~~~~~~\n::\n\n    OnCUDA(clip, int \"num_prefetch\", int \"device_index\")\n\n.. describe:: clip\n\n    This clip is processed by CUDA. In other words, the processing before this is processed by CUDA.\n    A filter that does not support CUDA processing will result in an error. (answering a specific ScriptEnvironment request)\n\n    Currently, internal filters are rarely (=not) supported, so you can only use external filters that are specially made.\n\n.. describe:: int  num_prefetch =\n\n    Same as OnCPU prefetch. Here you specify the number of frames to prefetch. About 2 will give you enough performance.\n    Unlike Prefetch, it has only one thread because it is a prefetch for parallelizing processing on the GPU and CPU. \n\n    default: 0 \n\n.. describe:: int  device_index =\n\n    Specifies the GPU to run. If you have only one GPU, you can only use 0. \n    If you have two GPUs, you can specify 0 or 1. There is no limit on the number. \n\n    default: 0 \n\n\nOf course, valid only on Avisynth+ built with CUDA option and works if the system has proper device and driver combination. \n\nSetWorkingDir\n~~~~~~~~~~~~~\n::\n\n    SetWorkingDir(path)\n\nSets the default directory for AviSynth to the *path* argument. This is\nprimarily for easy loading of source clips, :doc:`importing <../corefilters/import>` scripts, etc. It\ndoes not affect plugins' autoloading.\n\nReturn value is 0 if successful, -1 otherwise.\n\n*Examples:*\n::\n\n    SetWorkingDir(\"c:\\my_presets\")\n    AviSource(\"border_mask.avi\")  # this loads c:\\my_presets\\border_mask.avi\n\nSetPlanarLegacyAlignment\n~~~~~~~~~~~~~~~~~~~~~~~~\n::\n\n    SetPlanarLegacyAlignment(mode)\n\nSet alignment mode for `planar`_ frames. *mode* can either be true or false.\nSome older (?pre 2005?) :doc:`plugins <../externalplugins>` illegally assume the layout of video frames in memory.\nThis special filter forces the memory layout of planar frames to be\ncompatible with prior versions of AviSynth. The filter works on the\nGetFrame() call stack, so it effects filters **before** it in the script.\n\n*Examples:*\n::\n\n    Example - Using an older version of Mpeg2Source() (1.10 or older):\n\n    LoadPlugin(\"...\\Mpeg2Decode.dll\")\n    Mpeg2Source(\"test.d2v\")         # A plugin that illegally assumes the layout of memory\n    SetPlanarLegacyAlignment(true)  # Set legacy memory alignment for prior statements\n    ConvertToYUY2()     # Statements through to the end of the script have\n    ...                             # advanced memory alignment.\n\nGlobal variables OPT_xx\n~~~~~~~~~~~~~~~~~~~~~~~\n\nOPT_AllowFloatAudio\n-------------------\n::\n\n    global OPT_AllowFloatAudio = true ## default false\n\nFloat audio is converted to 16 bit when frameserving through ACM, unless ``OPT_AllowFloatAudio``\nis set to true (this option enables ``WAVE_FORMAT_IEEE_FLOAT`` audio output). \nIn that case the audio is kept as it is. When accessing AviSynth directly (like MeGUI, BeHappy \nor ffmpeg do for example), there is no automatic conversion. \n\nThe automatic conversion is done for clients that cannot handle Float audio (in the old days \nmost of them couldn't).\n\nNote: conversion takes place after the script processing is finished. Float audio is always allowed \nwithin the script.\n\n\nOPT_UseWaveExtensible\n---------------------\n::\n\n    global OPT_UseWaveExtensible = true ## default false\n\nThis option enables ``WAVE_FORMAT_EXTENSIBLE`` audio output. The default is\n``WAVE_FORMAT_EX``.\n\n*Note:*\n\nNote: The default DirectShow component for .AVS files, \"AVI/WAV File Source\", \ndoes not correctly implement WAVE_FORMAT_EXTENSIBLE processing, so many application may not be \nable to detect the audio track. There are third party DirectShow readers that do work correctly. \nIntermediate work files written using the AVIFile interface for later DirectShow processing \nwill work correctly if they use the DirectShow \"File Source (async)\" component or equivalent. \n\n\nOPT_dwChannelMask\n-----------------\n::\n\n    global OPT_dwChannelMask(int v)   v2.60 \n\nThis option enables you to set ChannelMask.\nIt overrides WAVEFORMATEXTENSIBLE.dwChannelMask which is set according to this table:\n\nWhen using these OPT, only VfW clients are affected, but not others such as ffmpeg.\nSince Avisynth+ 3.7.3 audio channel masks are part of the system.\n\n::\n\n    0x00004, // 1   -- -- Cf\n    0x00003, // 2   Lf Rf\n    0x00007, // 3   Lf Rf Cf\n    0x00033, // 4   Lf Rf -- -- Lr Rr\n    0x00037, // 5   Lf Rf Cf -- Lr Rr\n    0x0003F, // 5.1 Lf Rf Cf Sw Lr Rr\n    0x0013F, // 6.1 Lf Rf Cf Sw Lr Rr -- -- Cr\n    0x0063F, // 7.1 Lf Rf Cf Sw Lr Rr -- -- -- Ls Rs\n\nOPT_AVIPadScanlines\n-------------------\n::\n\n    global OPT_AVIPadScanlines = true ## default false   v2.60 \n\nThis option enables DWORD aligned planar padding. Default is packed aligned planar padding.\nSee memory alignment used in the AVIFile output emulation.\n\nhttp://avisynth.nl/index.php/AVIFile_output_emulation\n\nOPT_VDubPlanarHack\n------------------\n::\n\n    global OPT_VDubPlanarHack = true ## default false   v2.60 \n\nThis option enables flipped YV24 and YV16 chroma planes. This is an hack for\nearly versions of Virtualdub with YV24/YV16 support.\n\nOPT_Enable_V210\n---------------\n::\n\n    global OPT_Enable_V210 = true ## default false   AVS+ \n\nWhen enabled, for 10bit YUV422, frameserve interleaved V210 instead of planar P210. (VfW) \n\nVfW here means Video For Windows clients such as VirtualDub.\n\nWhen using these OPTs, only VfW clients are affected, but not others such as ffmpeg.\n\n\nOPT_Enable_Y3_10_10\n-------------------\n::\n\n    global OPT_Enable_Y3_10_10 = true ## default false   AVS+ \n\nWhen enabled, for 10bit YUV422, set the FourCC to ``Y3[10][10]`` ('Y', '3', 10, 10) instead of P210 ('P', '2', '1', '0'). (VfW)\n\nOPT_Enable_Y3_10_16\n-------------------\n::\n\n    global OPT_Enable_Y3_10_16 = true ## default false   AVS+ \n\nWhen enabled, for 16bit YUV422 ``Y3[10][16]`` is used instead of P216 (VfW)\n\nOPT_Enable_b64a\n---------------\n::\n\n    global OPT_Enable_b64a = true ## default false   AVS+ \n\nUse ``b64a`` instead of ``BRA[64]`` (VfW) \n\nOPT_Enable_PlanarToPackedRGB\n----------------------------\n::\n\n    global OPT_Enable_PlanarToPackedRGB = true ## default false   AVS+ \n\nConvert Planar RGB to packed RGB (VfW) \n\n*   Planar RGB 8, 10, 12, 14 and 16 bits are reported as ``G3[0][8]``, ``G3[0][10]``, ``G3[0][12]``, ``G3[0][14]`` and ``G3[0][16]`` fourCC codes \n*   Planar RGBA 8, 10, 12, 14 and 16 bits are reported as ``G4[0][8]``, ``G4[0][10]``, ``G4[0][12]``, ``G4[0][14]`` and ``G4[0][16]`` \n\nWhen these FourCC codes are not handled through VfW, use ``OPT_Enable_PlanarToPackedRGB=true``. \n\nAvisynth+ will convert the clip from planar to RGB64 (packed 16bit RGB) and will negotiate this format instead\n\n\nChangelog\n~~~~~~~~~\n+----------------+------------------------------------------------------------+\n| Version        | Changes                                                    |\n+================+============================================================+\n| Avisynth 3.7.6 | Add \"avx512base\" and \"avx512cli\" to SetMaxCPU              |\n+----------------+------------------------------------------------------------+\n| Avisynth 3.6.1 | | Added \"SetCacheMode\" (Neo addition)                      |\n|                | | Added \"SetMemoryMax\" type and index options              |\n+----------------+------------------------------------------------------------+\n| Avisynth 3.6.0 | Added \"SetMaxCPU\"                                          |\n+----------------+------------------------------------------------------------+\n\n--------\n\nBack to :doc:`Internal functions <syntax_internal_functions>`.\n\n\n$Date: 2025-12-14 21:02:00 $\n\n.. _planar: http://avisynth.nl/index.php/Planar\n.. _memory alignment used in the AVIFile output emulation (not yet written):\n    http://avisynth.nl/index.php/AVIFile_output_emulation\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_internal_functions_multithreading.rst",
    "content": "\nAviSynth Syntax - 2.6 Multithreading and memory functions\n=========================================================\n\nA historical page showing how memory settings and multithreading for classic\n``Avisynth 2.6`` worked.\n\nSetMemoryMax\n~~~~~~~~~~~~\n::\n\n    SetMemoryMax(amount)\n\nSets the maximum memory (in MB) that AviSynth uses for its internal Video\nFrame cache to the value of *amount*. From v2.5.8, setting to zero just\nreturns the current Memory Max value. In the 2.5 series the default Memory\nMax value is 25% of the free physical memory, with a minimum of 16MB. From\nrev 2.5.8 RC4, the default Memory Max is also limited to 512MB.\n\n+-----------------------------+-----+-----+-----+-----+------+------+------+\n| Free                        | <64 | 128 | 256 | 512 | 1024 | 2048 | 3072 |\n+=============================+=====+=====+=====+=====+======+======+======+\n| Default Max v2.57 and older | 16  | 32  | 64  | 128 | 256  | 512  | 768  |\n+-----------------------------+-----+-----+-----+-----+------+------+------+\n| Default Max since v2.58 RC4 | 16  | 32  | 64  | 128 | 256  | 512  | 512  |\n+-----------------------------+-----+-----+-----+-----+------+------+------+\n\nIn some versions there is a default setting of 5MB, which is quite low. If\nyou encounter problems (e.g. low speed) try to set this values to at least\n32MB. Too high values can result in crashes because of 2GB address space\nlimit.  Return value: Actual MemoryMax value set.\n\n*Examples:*\n::\n\n    SetMemoryMax(128)\n\nGetMTMode, SetMTMode\n~~~~~~~~~~~~~~~~~~~~\n::\n\n    GetMTMode(threads)\n    SetMTMode(mode, threads)\n\nThese functions enable AviSynth to use more than one thread when processing\nfilters. This is useful if you have more than one cpu/core or hyperthreading.\nThis feature is still experimental.\n\n::\n\n    GetMTMode(bool threads):\n\nIf *threads* is set to true GetMTMode returns the number of threads used else\nthe current mode is returned (see below). Default value false.\n\n::\n\n    SetMTMode(int mode, int threads):\n\nPlace this at the first line in the avs file to enable temporal (that is more\nthan one frame is processed at the same time) multithreading. Use it later in\nthe script to change the mode for the filters below it.\n\n*mode*: There are 6 modes 1 to 6. Default value 2.\n\n-   Mode 1 is the fastest but only works with a few filter.\n-   Mode 2 should work with most filters but uses more memory.\n-   Mode 3 should work with some of the filters that doesn't work with\n    mode 2 but is slower.\n-   Mode 4 is a combination of mode 2 and 3 and should work with even\n    more filter but is both slower and uses more memory\n-   Mode 5 is slowest but should work with all filters that doesn't\n    require linear frameserving (that is the frames come in order (frame\n    0,1,2 ... last).\n-   Mode 6 is a modified mode 5 that might be slightly faster.\n\n*threads*: Number of threads to use. Set to 0 to set it to the number of\nprocessors available. It is not possible to change the number of threads\nother than in the first SetMTMode. Default value 0.\n\n**Example:**\n\n::\n\n    SetMTMode(2,0)                      # enables multithreading using thread = to\n                                        # the number of available processors and mode 2\n    LoadPlugin(\"...\\LoadPluginEX.dll\")  # needed to load avisynth 2.0 plugins\n    LoadPlugin(\"...\\DustV5.dll\")        # Loads Pixiedust\n    Import(\"limitedsharpen.avs\")\n    src = AviSource(\"test.avi\")\n    SetMTMode(5)                        # change the mode to 5 for the lines below\n    src = src.ConvertToYUY2.PixieDust() # Pixiedust needs mode 5 to function.\n    SetMTMode(2)                        # change the mode back to 2\n    src.LimitedSharpen()                # because LimitedSharpen works well with mode 2\n    # display mode and number of threads in use\n    Subtitle(\"Number of threads used: \" + String(GetMTMode(true))\n     \\ + \" Current MT Mode: \" + String(GetMTMode()))\n\n--------\n\nBack to :doc:`Internal functions <syntax_internal_functions>`.\n\n$Date: 2024/01/06 20:02:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_internal_functions_multithreading_new.rst",
    "content": "\nAviSynth+ Syntax - Multithreading functions\n===========================================\n\nBy default, AviSynth is single-threaded.\n\nThis page documents how to enable multi-threading: use more than \none thread when processing filters. This is useful if you have more than \none cpu/core or hyperthreading, so nearly always.\n\nIn this document the abbreviation MT is used for multithreading.\n\nOn startup default MT mode is \"MT_MULTI_INSTANCE\". Plugins or SetFilterMTMode can override this.\n\nAviSynth+ does the multithreading differently than classic Avisynth 2.6.\n\nIn AviSynth+, you specify the MT-mode for only specific filters, and those filters will then automatically \nuse their own mode, even if there were other MT-modes in between. This means that for old filters you can \nspecify all the MT modes at the beginning without polluting your script. \n\nYou can even make a SetMTMode.avsi if you wish and let it autoload for all of your scripts, \nor import() it from their top. This is much cleaner, and it allows you to maintain all your \nMT-modes centrally at a single place. To make this distinction clear from AviSynth+, Avisynth 2.6's \nSetMTMode() is called SetFilterMTMode() in AviSynth+. \n\nNotes\n\n1.  Source filters are auto detected by Avisynth (such filters have no input clip parameters) and are \n    always set to MT_SERIALIZED (no threaded calls)\n2.  Mode 3 (MT_SERIALIZED) is evil. It is necessary for some filters, and it is usually no problem \n    for source filters, but it can literally completely negate all advantages of MT, if such a filter \n    is placed near the end of your script. In general, avoid such calls if you want performance.\n\n    Programmers can check ``class MtModeEvaluator`` in ``avisynth.cpp``.\n\n    <todo check: what's the effect of using multiple Prefetch sections?>\n3.  Though Avisynth video frame caches will save you a lot of memory in single-threaded scripts, \n    but due to the way they work, they will also use more memory than before with MT enabled. \n\n    The memory usage will scale much closer with the number of threads you have. Just something to keep in mind. \n\nNotes for filter writers:\n\n-   Always specify your filters' required MT mode by answering with an ``MT_xxxx`` constant on \n    ``CACHE_GET_MTMODE`` in your ``SetCacheHints`` implementation.\n    But don't go too safe with specifying MT_SERIALIZED, do it only when it's really necessary: See Note 2.\n\n\nMT Modes explained\n==================\n\n*   MT_NICE_FILTER:\n\n    Some filters (like nnedi3) use some buffers to do their dirty work and with mode 1 you get \n    multiple threads writing data from different frames to the same buffer. \n    This causes corruption when later someone tries to read from this buffer and gets not what was expected. \n    Most of the \"more complicated\" filters use some kind of temporary storage thus won't work \n    well with this mode. Simple filters might. \n\n*   MT_MULTI_INSTANCE:\n\n    Mode 2 doesn't have this issue because multiple threads will get their own buffers and no data will be shared.\n    Hence mode 2 is the \"default\" mode which should work with most filters, \n    but it wastes memory like crazy (take SangNom2 for example - for 1080p YV12 frame, \n    size of temporary buffers is about 10MB, so with 4 threads you get 40MBs on single filter invocation.\n    Now add some usual supersampling to this and multiple invocations in most aa scripts and... you get the idea).\n\n*   MT_SERIALIZED: \n\n    If the filter requires sequential access or uses some global storage, then mode 3 is the only way to go. \n    Source filter (filters without clip parameter) are autodetected, they do not need an \n    explicit MT mode setting, they will automatically use MT_SERIALIZED. \n\n*   MT_SPECIAL_MT: \n\n    Experimental, no longer is needed. It was used only for MP_Pipeline, the filter is like a source filter \n    (no input clip parameter), internally multithreaded, and suffer heavy performance degradation from any \n    of the three regular mt modes. Really, this is a workaround. Available from AviSynth+ version r2440. \n    Avisynth+ 3.6 has gained serious MT fixes from Neo fork, this mode is probably not needed anymore. \n\nPrefetch\n========\n::\n\n    Prefetch (clip, int \"threads\", int \"frames\") \n\n.. describe:: clip\n\n    Input clip. \n\n.. describe:: int threads\n\n    Number of threads to use. If it is 0, it passes without doing anything. \n    \n    default: (number of logical cores in the system) +1 \n\n.. describe:: int frames\n\n    Expert parameter.\n\n    Number of frames to prefetch. Again, if it is 0, it passes without doing anything. \n\n    default: threads * 2 \n\nIn the original Avisynth+ (before v3.6), only one ``Prefetch`` per script was supported, \ntypically placed at the very end of the script.\n\nStarting from Neo fork you can use as many as you like. Also, a \"frames\" argument has been added \nto specify the number of frames to prefetch. Neo's multithreading enhancements were backported \nto the mainstream Avisynth+ and are available since v3.6\n\n*Examples:*\n::\n\n    # This line causes all filters that don't have an MT mode explicitly use mode 2 by default.\n    # Mode 2 is a relatively safe choice until you don't know most of your calls to be either mode 1 or 3.\n    # Compared with mode 1, mode 2 trades memory for MT-safety, but only a select few filters will work with mode 1.\n    SetFilterMTMode(\"DEFAULT_MT_MODE\", 2)\n    or\n    SetFilterMTMode(\"DEFAULT_MT_MODE\", MT_MULTI_INSTANCE)\n\nSetting a source filter to MT mode 3 (MT_SERIALIZED) is no longer needed.\n::\n\n    # FFVideoSource(), like most of all source filters, needs MT mode 3. \n    # Note: starting  with AviSynth+ r2069, it will now automatically recognize source filters.\n    # If it sees a source filter which has no MT-mode specified at all, it will automatically use \n    # mode 3 instead of the default MT mode.\n    SetFilterMTMode(\"FFVideoSource\", 3)\n    or \n    SetFilterMTMode(\"FFVideoSource\", MT_SERIALIZED)\n    \n    # Now comes your script as usual\n    FFVideoSource(...)\n    Trim(...)\n    QTGMC(...)\n    ...\n    \n    # Enable MT!\n    Prefetch(4)\n\nPipeline parallelization\n\n::\n\n    Filtering A\n    Prefetch(1,4)\n    Filtering B\n    Prefetch(1,4)\n    Filtering C\n    Prefetch(1,4)\n\nPrefetch (1,4) makes one thread stand and read four frames ahead.\n\nIn the above example, the filtering processes A, B, and C are executed in parallel in a pipeline.\nSince the number of threads of each Prefetch is arbitrary, for example, filter processing B is heavy, \nso if you want to increase the number of parallels by that amount, you can increase the number of threads as follows:\n\n::\n\n    Filtering A\n    Prefetch(1,4)\n    Filtering B\n    Prefetch(4)\n    Filtering C\n    Prefetch(1,4)\n\nSetFilterMTMode\n===============\n::\n\n    SetFilterMTMode (string filtername, int mode, bool \"force\")\n\nDepending on the filter type, different multithreading rules can be set.\nThe filter developer can specify which one is used, this can be done programatically,\n(self-registering) so no user intervention is necessary.\n\nWhen ``force`` = false then the function has effect only if the filter doesn't \nset (self-register) own MT mode. Usually the recent versions of the plugins have set MT mode.\n\nFor old filters, this method can set the proper behaviour, how Avisynth core will treat it MT-wise.\nMeaningful only if this mode is different that the default MT mode.\n\n.. describe:: string filtername  =\n\n    name of the filter you want to set an MT Mode for. You cannot set the MT mode on script function calls, \n    only on binary (external plugin) filters.\n    \n    ``\"DEFAULT_MT_MODE\"``, sets the default MT mode for all filters that do not have an MT mode \n    explicitly set. Does not affect for source filters and filters that self-register their own MT mode. \n\n.. describe:: int mode\n\n    Sets MT Mode, there are three basic MT modes (1,2,3) and an experimental workaround mode (4). Instead of the numbers, you can also use symbolic names for MT modes:\n\n    *   1 : MT_NICE_FILTER\n    *   2 : MT_MULTI_INSTANCE\n    *   3 : MT_SERIALIZED\n    *   (4 : MT_SPECIAL_MT do not use, early workaround setting for a problem, which has been solved since then)\n\n.. describe:: bool force = false \n\n    Force MT mode. Default is false.\n    Override the setting even if filter was registering its MT mode programatically.\n    When false, MT mode of self-registering filters won't be changed.\n\nAs a side effect, a filter with MT_SERIALIZED (either set by ``SetFilterMTMode`` or self-registering it) \ncan downgrade the MT modes of the filters in the chain before the filter, despite of they have their \nown ``SetFilterMTMode``. It has performance effects as mentioned in Notes 2.\n\nThere was a discussion about this topic:\nhttps://forum.doom9.org/showthread.php?p=1823754#post1823754\nanswering on\nhttps://forum.doom9.org/showthread.php?p=1823726#post1823726\n\n\n*Examples:*\n\n::\n\n    SetFilterMTMode(X, MT_SERIALIZED, force=true)\n    sourceFilter\n    \n    # filterY has own MT mode MT_MULTI_INSTANCE but now is changed to MT_SERIALIZED\n    filterY\n    \n    # filterZ has own MT mode MT_NICE_FILTER but now is changed to MT_SERIALIZED\n    filterZ\n    \n    filterX\n\n::\n\n    SetFilterMTMode(X, MT_MULTI_INSTANCE, force=true)\n    sourceFilter\n    \n    # filterY has own MT mode MT_SERIALIZED, not changed\n    filterY\n    \n    # filterZ has own MT mode MT_NICE_FILTER but now is changed to MT_MULTI_INSTANCE\n    filterZ\n    \n    filterX\n\n::\n\n    SetFilterMTMode(X, MT_NICE_FILTER, force=true)\n    sourceFilter\n    \n    # filterY has own MT mode MT_SERIALIZED, not changed\n    filterY\n    \n    # filterZ has own MT mode MT_MULTI_INSTANCE, not changed\n    filterZ\n    \n    filterX\n\n::\n\n    SetFilterMTMode(X, MT_SERIALIZED, force=true)\n    SetFilterMTMode(Y, MT_NICE_FILTER, force=true)\n    sourceFilter\n    \n    # filterY has own MT mode MT_MULTI_INSTANCE but now is changed to MT_SERIALIZED\n    # SetFilterMTMode(Y, MT_NICE_FILTER, force=true) doesn't have effect\n    filterY\n    \n    # filterZ has own MT mode MT_NICE_FILTER but now is changed to MT_SERIALIZED\n    filterZ\n    \n    filterX\n\n::\n\n    SetFilterMTMode(X, MT_MULTI_INSTANCE, force=true)\n    SetFilterMTMode(Y, MT_SERIALIZED, force=true)\n    sourceFilter\n    \n    # filterY has own MT mode MT_MULTI_INSTANCE but now is changed to MT_SERIALIZED\n    filterY\n    \n    # filterZ has own MT mode MT_NICE_FILTER but now is changed to MT_MULTI_INSTANCE\n    filterZ\n    \n    filterX\n\n--------\n\nBack to :doc:`Internal functions <syntax_internal_functions>`.\n\n$Date: 2024/01/07 09:37:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_internal_functions_numeric.rst",
    "content": "\nAviSynth Syntax - Numeric functions\n===================================\n\nNumeric functions provide common mathematical operations on numeric\nvariables.\n\nNote: since 3.7.4 ``int`` and ``float`` means any 32 or 64-bit integer or floating point value, respectively.\nThe exact type of value (e.g. if a variable or constant is 32-bit float or 64-bit double) is known.\n('i'nteger - 32-bit integer, 'l'ong - 64-bit integer, 'f'loat - 32-bit foating point, 'd'ouble - 64-bit floating point) \n\nInteger calculations are done in 64-bit precision. When the result fits into the 32 bit range, it is stored back as 32-bit integer ``i``.\nOtherwise the result is stored into 64-bit long ``l``.\n\nWhen both operands are 32-bit float, arithmetic is done in 32-bits and the result is a 32-bit float.\nOtherwise the calculation is done in 64-bit double ``d`` precision.\n\nExcept ``MulDiv``, ``Rand`` and ``Spline`` the calculations are 64-bit (int or double) compatible.\n\nMax\n~~~\n::\n\n    Max(float, float [, ...])\n\nReturns the maximum value of a set of numbers.\n\nVersion 3.7.4-:\n\n- If all the values are of type Int (any 32 or 64-bit), the result is an Int. \n- If any of the values are of type 64-bit float (double), the result is a double.\n  This may cause an unexpected result when an Int value greater than 9007199254740992\n  (2^53) is mixed with double values.\n\n- If all values are 32-bit float, the result is a 32-bit float.\n\nVersion <3.7.4:\n\n- If all the values are of type Int, the result is an Int. If any of the values\n  are of type Float, the result is a Float.\n  \n- This may cause an unexpected result when an Int value greater than 16777216 (2^24) \n  is mixed with Float values.\n\n*Examples:*\n::\n\n    Max (1, 2) = 2\n    Max (5, 3.0, 2) = 5.0\n\nMin\n~~~\n::\n\n    Min(float, float [, ...])\n\nReturns the minimum value of a set of numbers.\n\n*Examples:*\n::\n\n    Max (1, 2) = 1\n    Max (5, 3.0, 2) = 2.0\n\n\nMulDiv\n~~~~~~\n::\n\n    MulDiv(int, int, int)\n\nMultiplies two ints (m, n) and divides the product by a third (d) in a single\noperation, with 64 bit intermediate result. The actual equation used is ``(m\n* n + d / 2) / d``.\n\nParameters are treated as 32 bits, even from Avisynth 3.7.4.\n\n*Examples:*\n::\n\n    MulDiv (1, 1, 2) = 1\n    MulDiv (2, 3, 2) = 3\n\nFloor\n~~~~~\n::\n\n    Floor(float)\n\nConverts from float to int (round down on any fractional amount).\n\n*Examples:*\n::\n\n    Floor(1.2) = 1\n    Floor(1.6) = 1\n    Floor(-1.2) = -2\n    Floor(-1.6) = -2\n\nCeil\n~~~~\n::\n\n    Ceil(float)\n\nConverts from float to int (round up on any fractional amount).\n\n*Examples:*\n::\n\n    Ceil(1.2) = 2.0\n    Ceil(1.6) = 2.0\n    Ceil(-1.2) = -1\n    Ceil(-1.6) = -1\n\nRound\n~~~~~\n::\n\n    Round(float)\n\nConverts from float to int (round off to nearest integer).\n\n*Examples:*\n::\n\n    Round(1.2) = 1\n    Round(1.6) = 2\n    Round(-1.2) = -1\n    Round(-1.6) = -2\n\nInt\n~~~\n::\n\n    Int(float)\n\nConverts from single-precision, `floating-point`_ or any integer value to int (round towards\nzero). If the result fit into 32 bit integer, the result type is integer, else 64 bit long.\n\n*Examples:*\n::\n\n    Int(1.2) = 1\n    Int(1.6) = 1\n    Int(-1.2) = -1\n    Int(-1.6) = -1\n\nIntI\n~~~~\n::\n\n    IntI(float)\n\nConverts from a `floating-point`_ or any integer value to 32 bit int (round towards zero).\n\nSince v3.7.4.\n\n*Examples:*\n::\n\n    Int(1.2) = 1\n    Int(1.6) = 1\n    Int(-1.2) = -1\n    Int(-1.6) = -1\n\nLong\n~~~~\n::\n\n    Long(float)\n\nConverts from a `floating-point`_ or any integer value to 64 bit int (round towards zero).\n\nSince v3.7.4.\n\n*Examples:*\n::\n\n    Long(1.2) = 1\n    Long(1.6) = 1\n    Long(-1.2) = -1\n    Int(-1.6) = -1\n\nFloat\n~~~~~\n::\n\n    Float(int)\n\nConverts any int to `floating-point`_ value. \n\nSince v3.7.4 this means\n\n- Integer input is converted to 64 bit double:\n  Integer values that require more than 53-bits to be represented will have their lower bits\n  truncated yielding unexpected values.\n- if input is already a floating point type, it's kept as-is, 32 bit float is not converted to double.\n\nPre v3.7.4:\n\n- Convert to 32 bit float.\n- Integer values that require more than 24-bits to be represented will have their lower bits\n  truncated yielding unexpected values.\n\n\n*Examples:*\n::\n\n    Float(4) = 4.0\n    Float(4) / 3 = 1.333 (while 4 / 3 = 1 , due to integer division)\n\nFloatf\n~~~~~~\n::\n\n    Floatf(int)\n\nConverts int to 32 bit single-precision, `floating-point`_ value. Integer values\nthat require more than 24-bits to be represented will have their lower 8-bits\ntruncated yielding unexpected values.\n\n\nFmod\n~~~~\n::\n\n    Fmod(float, float)\n\nReturns the modulo of the argument. Output is float.\n\n*Examples:*\n::\n\n    Fmod(3.5, 0.5) = 0 (since 3.5 - 7*0.5 = 0)\n    Fmod(3.5, 1.0) = 0.5 (since 3.5 - 3*1.0 = 0.5)\n\nPi\n~~\n::\n\n    Pi()\n\nReturns the value of the \"pi\" constant (the ratio of a circle's circumference\nto its diameter).\n\n*Examples:*\n::\n\n    d = Pi()    # d == 3.141593\n\nExp\n~~~\n::\n\n    Exp(float)\n\nReturns the natural (base-e) exponent of the argument.\n\n*Examples:*\n::\n\n    Exp(1) = 2.718282\n    Exp(0) = 1.0\n\nLog\n~~~\n::\n\n    Log(float)\n\nReturns the natural (base-e) logarithm of the argument.\n\n*Examples:*\n::\n\n    Log(1) = 0.0\n    Log(10) = 2.30259\n    Log(Exp(1)) = 1.0\n\nLog10\n~~~~~\n::\n\n    Log10(float)\n\nReturns the common logarithm of the argument.\n\n*Examples:*\n::\n\n    Log10(1.0) = 0\n    Log10(10.0) = 1.0\n    Log10(2.0) = 0.3010299957\n\nPow\n~~~\n::\n\n    Pow(float base, float power)\n\nReturns \"base\" raised to the power indicated by the second argument.\n\n*Examples:*\n::\n\n    Pow(2, 3) = 8\n    Pow(3, 2) = 9\n    Pow(3.45, 1.75) = 8.7334\n\nSqrt\n~~~~\n::\n\n    Sqrt(float)\n\nReturns the square root of the argument.\n\n*Examples:*\n::\n\n    Sqrt(1) = 1.0\n    Sqrt(2) = 1.4142\n\nAbs\n~~~\n::\n\n    Abs(float or int)\n\nReturns the absolute value of its argument (returns float for float, integer\nfor integer).\n\n*Examples:*\n::\n\n    Abs(-3.8) = 3.8\n    Abs(-4) = 4\n\nSign\n~~~~\n::\n\n    Sign(float)\n\nReturns the sign of the value passed as argument (1, 0 or -1).\n\n*Examples:*\n::\n\n    Sign(-3.5) = -1\n    Sign(3.5) = 1\n    Sign(0) = 0\n\nFrac\n~~~~\n::\n\n    Frac(float)\n\nReturns the fractional portion of the value provided.\n\n*Examples:*\n::\n\n    Frac(3.7) = 0.7\n    Frac(-1.8) = -0.8\n\nRand\n~~~~\n::\n\n    Rand([int max] [, bool scale] [, bool seed])\n\nReturns a random integer value. All parameters are optional.\n\n-   *max* sets the maximum value+1 (default 32768) and can be set\n    negative for negative results. It operates either in scaled or modulus\n    mode (default scale=true only if abs(max) > 32768, false otherwise).\n-   Scaled mode (scale=true) scales the internal random number\n    generator value to the maximum value, while modulus mode (scale=false)\n    uses the remainder from an integer divide of the random generator value\n    by the maximum. I found modulus mode is best for smaller maximums.\n-   Using *seed=true* seeds the random number generator with the current\n    time. *seed* defaults to false and probably isn't necessary, although\n    it's there just in case.\n\nTypically, this function would be used with the Select function for random\nclips.\n\n*Examples:*\n::\n\n    Select(Rand(5), clip1, clip2, clip3, clip4, clip5)\n\nSpline\n~~~~~~\n::\n\n    Spline(float X, x1, y1, x2, y2, .... [, bool cubic])\n\nInterpolates the Y value at point X using the control points x1/y1, ... There\nhave to be at least 2 x/y-pairs. The interpolation can be cubic (the result\nis a spline) or linear (the result is a polygon). Default is cubic.\n\n*Examples:*\n::\n\n    Spline(5, 0, 0, 10, 10, 20, 0, false) = 5\n    Spline(5, 0, 0, 10, 10, 20, 0, true) = 7\n\nContinuedNumerator, ContinuedDenominator\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n::\n\n    ContinuedNumerator(float, int limit)\n    ContinuedNumerator(int, int, int limit)\n    ContinuedDenominator(float, int limit)\n    ContinuedDenominator(int, int, int limit)\n\nThe rational pair (ContinuedNumerator,ContinuedDenominator) returned has the\nsmallest possible denominator such that the absolute error is less than\n1/limit. More information can be found on `the wikipedia article for Continued fraction`_. If *limit* is not\nspecified in the Float case the rational pair returned is to the limit of the\nsingle precision floating point value. Thus ``(float)((double)Num/(double)Den)\n== V``. In the Int pair case if *limit* is not specified then the normalised\noriginal values will be returned, i.e. reduced by the GCD. (GCD = greatest common divisor)\n\n*Examples:*\n::\n\n    ContinuedNumerator(PI(), limit=5000]) = 355\n    ContinuedDenominator(PI(), limit=5000) = 113\n\n    ContinuedNumerator(PI(), limit=50]) = 22\n    ContinuedDenominator(PI(), limit=50) = 7\n\n    ContinuedNumerator(355, 113, limit=50]) = 22\n    ContinuedDenominator(355, 113, limit=50) = 7\n\nChangelog\n~~~~~~~~~\n+-----------------+-----------------------------------+\n| Version         | Changes                           |\n+=================+===================================+\n| 3.7.4           | | Changed Float, Int              |\n|                 | | Add IntI, Long, FloatF, Double  |\n+-----------------+-----------------------------------+\n| Avisynth 2.6    | Fmod, Log10,                      |\n|                 | ContinuedNumerator,               |\n|                 | ContinuedDenominator              |\n+-----------------+-----------------------------------+\n\n--------\n\nBack to :doc:`Internal functions <syntax_internal_functions>`.\n\n$Date: 2024/01/15 16:26:00 $\n\n.. _wikipedia: http://en.wikipedia.org/wiki/Hyperbolic_function\n.. _floating-point: http://en.wikipedia.org/wiki/Floating_point\n.. _the wikipedia article for Continued fraction: http://en.wikipedia.org/wiki/Continued_fraction\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_internal_functions_runtime.rst",
    "content": "\nAviSynth Syntax - Runtime functions\n===================================\n\nThese are the internal functions which are evaluated at every frame. They can\nbe used inside the scripts passed to runtime filters (:doc:`ConditionalFilter <../corefilters/conditionalfilter>`,\n:doc:`ScriptClip <../corefilters/conditionalfilter>`, :doc:`FrameEvaluate <../corefilters/conditionalfilter>`) to return information for a frame (usually\nthe current one). When using these functions there is an implicit\n``last`` clip (the one that is passed to the runtime filter). Thus, first\nparameter doesn't have to be specified; it is replaced by the ``last`` clip.\n\nAverage\n~~~~~~~\n\n::\n\n    AverageLuma(clip[, int offset = 0])\n    AverageChromaU(clip[, int offset = 0])\n    AverageChromaV(clip[, int offset = 0])\n    AverageR(clip[, int offset = 0])\n    AverageG(clip[, int offset = 0])\n    AverageB(clip[, int offset = 0])\n\nThis group of functions return a float value with the average pixel value of\na plane (Luma, U-chroma and V-chroma, R, G or B respectively).\n\nIn v2.61 an offset argument is added which enables you to access other frames than the current one.\n\n*Examples:*\n::\n\n    ScriptClip(Last, \"\"\"\n        threshold = 55\n        luma = AverageLuma ## gives the average luma of the current frame\n        #luma = AverageLuma(1) ## gives the average luma of the next frame\n        luma < threshold \n        \\ ? Levels(0, 1.0+0.5*(threshold-luma)/threshold, 255, 0, 255) \n        \\ : last\n        Subtitle(\"luma=\" + String(luma), align=2)\n    \"\"\")\n\nDifference\n~~~~~~~~~~\n::\n\n  RGBDifference(clip1, clip2)\n  LumaDifference(clip1, clip2)\n  ChromaUDifference(clip1, clip2)\n  ChromaVDifference(clip1, clip2)\n  RDifference(clip1, clip2)\n  GDifference(clip1, clip2)\n  BDifference(clip1, clip2)\n\nSingle-plane versions support only planar YUV or planar RGB clips. \nRGBDifference supports only packed (non-planar) RGB clips (that is RGB24/32/48/64).\n\nThis group of functions return a float value between 0 and 255 (or 0 and max_pixel_value for \nbit depths over 8) of the absolute difference between two planes from two different clips.\n\nEither the combined RGB difference or the Luma, U-chroma or V-chroma, or R, B or B\ncomponent differences, respectively.\n\n*Examples:*\n::\n\n    ovl = Overlay(last, mov_star, x=some_xvalue, y=some_yvalue, mask=mov_mask)\n    ldif = LumaDifference(ovl) # implicit last for clip1\n    udif = ChromaUDifference(Tweak(hue=24), ovl)\n    ...\n\nDifference from previous\n~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe \"Difference\" function groups should be quite handy for detecting scene\nchange transitions:\n\n::\n\n  RGBDifferenceFromPrevious(clip)\n  LumaDifferenceFromPrevious(clip)\n  ChromaUDifferenceFromPrevious(clip)\n  ChromaVDifferenceFromPrevious(clip)\n  RDifferenceFromPrevious(clip1)\n  GDifferenceFromPrevious(clip1)\n  BDifferenceFromPrevious(clip1)\n\nThis group of functions return the absolute difference of pixel value between \nthe current and previous frame of clip – either the combined RGB difference or\nthe Luma, U-chroma, V-chroma or R, G, B differences, respectively. \n\n*Examples:*\n::\n\n    scene_change = (YDifferenceFromPrevious) > threshold)\n    scene_change ? some_filter(...) : another_filter(...)\n\nDifference to next\n~~~~~~~~~~~~~~~~~~\n::\n\n    RGBDifferenceToNext(clip[, int offset = 1])\n    LumaDifferenceToNext(clip[, int offset = 1])\n    ChromaUDifferenceToNext(clip[, int offset = 1])\n    ChromaVDifferenceToNext(clip[, int offset = 1])\n    RDifferenceToNext(clip[, int offset = 1])\n    GDifferenceToNext(clip[, int offset = 1])\n    BDifferenceToNext(clip[, int offset = 1])\n\nThis group of functions return the absolute difference of pixel value between \nthe current and next frame of clip – either the combined RGB difference or \nthe Luma, U-chroma, V-chroma, R, G or B differences, respectively.\n\nIn v2.61 an offset argument is added, which enables you to access the difference \nbetween the RGB, luma, chroma or R/G/B plane of the current frame and of any other \nframe. \n\nNote that for example ``clip.RGBDifferenceToNext(-1) = clip.RGBDifferenceToPrevious``, \nand ``clip.RGBDifferenceToNext(0) = 0``. \n\n*Examples:*\n::\n\n    # both th1, th2 are positive thresholds; th1 is larger enough than th2\n    scene_change = (YDifferenceFromPrevious > th1) && (YDifferenceToNext < th2)\n    scene_change ? some_filter(...) : another_filter(...)\n\nColor plane median, min, max, range \n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nSee also: \n\n\n::\n\n    YPlaneMedian(clip[, int offset = 0])\n    UPlaneMedian(clip[, int offset = 0])\n    VPlaneMedian(clip[, int offset = 0])\n    RPlaneMedian(clip[, int offset = 0])\n    GPlaneMedian(clip[, int offset = 0])\n    BPlaneMedian(clip[, int offset = 0])\n    \n    YPlaneMax(clip[, float threshold, int offset = 0])\n    UPlaneMax(clip[, float threshold, int offset = 0])\n    VPlaneMax(clip[, float threshold, int offset = 0])\n    RPlaneMax(clip[, float threshold, int offset = 0])\n    GPlaneMax(clip[, float threshold, int offset = 0])\n    BPlaneMax(clip[, float threshold, int offset = 0])\n    \n    YPlaneMin(clip[, float threshold, int offset = 0])\n    UPlaneMin(clip[, float threshold, int offset = 0])\n    VPlaneMin(clip[, float threshold, int offset = 0])\n    RPlaneMin(clip[, float threshold, int offset = 0])\n    GPlaneMin(clip[, float threshold, int offset = 0])\n    BPlaneMin(clip[, float threshold, int offset = 0])\n    \n    YPlaneMinMaxDifference(clip[, float threshold, int offset = 0])\n    UPlaneMinMaxDifference(clip[, float threshold, int offset = 0])\n    VPlaneMinMaxDifference(clip[, float threshold, int offset = 0])\n    RPlaneMinMaxDifference(clip[, float threshold, int offset = 0])\n    GPlaneMinMaxDifference(clip[, float threshold, int offset = 0])\n    BPlaneMinMaxDifference(clip[, float threshold, int offset = 0])\n\nThis group of functions return statistics about the distribution of pixel values on \na plane (Luma, U-chroma, V-chroma, R, G and B respectively). The statistics are, \nin order of presentation: maximum, minimum, median and range (maximum - minimum difference). \n\nThreshold is a percentage, stating how many percent of the pixels are allowed \nabove or below minimum. The ``threshold`` is optional and defaults to 0.\n\nIn v2.61 an offset argument is added, which enables you to access the statistics of \nother frames than the current one. \n\nThe decision is based on creating a histogram on pixel values and counts then\nthe given threshold is checked against this pixel level-pixel count table.\n\nThis histogram cannot be done for 32 bit float data thus 32 bit float pixels\nare converted to 16 bit integer data before creating the histogram.\n\n*Examples:*\n::\n\n    # median and average are close only on even distributions; \n    # this can be a useful diagnostic\n    have_intense_brights = YPlaneMedian() - AverageLuma() < threshold\n    ...\n    # a simple per-frame normalizer to [16..235], CCIR, range\n    Levels(YPlaneMin(), 1.0, YPlaneMax(), 16, 235)\n\nSee more at :doc:`Conditional filters <../corefilters/conditionalfilter>` section.\n\nAll-in-one stats\n~~~~~~~~~~~~~~~~\n::\n\n    PlaneMinMaxStats(clip[, float threshold, int offset, int plane, bool setvar])\n\nReturns an 6-element array with [min,max,thresholded minimum,thresholded maximum,median,average]\n\nSee more at :doc:`Conditional filters <../corefilters/conditionalfilter>` section.\n\n--------\n\nBack to :doc:`Internal functions <syntax_internal_functions>`.\n\nChangelog\n---------\n+----------------+------------------------------------------------------------+\n| Version        | Changes                                                    |\n+================+============================================================+\n| Avisynth 3.7.2 | Added a 6th element to PlaneMinMaxStats result             |\n+----------------+------------------------------------------------------------+\n| Avisynth 3.7.1 | Added PlaneMinMaxStats                                     |\n+----------------+------------------------------------------------------------+\n| Avisynth+      | Added R, G, B versions of AverageXX, Min, Max,             |\n| pre2294        | Difference and Median family.                              |\n+----------------+------------------------------------------------------------+\n| AviSynth 2.61  | added offset parameters                                    |\n+----------------+------------------------------------------------------------+\n\n$Date: 2025-02-25 17:10:48-05:00 $\n\n.. _YV12: http://avisynth.nl/index.php/YV12\n.. _colorspace: http://avisynth.nl/index.php/Color_spaces\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_internal_functions_script.rst",
    "content": "\nAviSynth Syntax - Script functions\n==================================\n\nThey provide AviSynth script information.\n\n-   ScriptName   |   v2.60   |   ScriptName()\n\nReturns the as entered path and filename of the loaded script as a string.\n\n*Examples:*\n::\n\n    name = ScriptName() # name = \"F:\\Directory\\Tmp\\..\\video.avs\"\n\n-   ScriptFile   |   v2.60   |   ScriptFile()\n\nReturns the resolved filename of the loaded script as a string.\n\n*Examples:*\n::\n\n    file = ScriptFile() # name = \"video.avs\"\n\n-   ScriptDir   |   v2.60   |   ScriptDir()\n\nReturns the resolved path of the loaded script as a string.\n\n*Examples:*\n::\n\n    folder = ScriptDir() # name = \"F:\\Directory\"\n\n--------\n\nBack to :doc:Internal functions <syntax_internal_functions>`.\n\n$Date: 2011/04/17 03:58:18 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_internal_functions_string.rst",
    "content": "\nAviSynth Syntax - String functions\n==================================\n\nString functions provide common operations on string variables.\n\nThese function may not work as expected, if you feed them with utf8 strings.\nSome function (e.g. UCase, LCase) may not work as expected, if parameter contains national accented characters.\n\nE.g. Strlen of an utf8-encoded string, which contains non-latin or accented national characters \nmay report more length than is visible by human reader.\n\nLCase\n~~~~~\n::\n\n    LCase(string)\n\nReturns lower case of string.\n\n*Examples:*\n::\n\n    LCase(\"AviSynth\") = \"avisynth\"\n\nUCase\n~~~~~\n::\n\n    UCase(string)\n\nReturns upper case of string.\n\n*Examples:*\n::\n\n    UCase(\"AviSynth\") = \"AVISYNTH\"\n\nStrToUtf8\n~~~~~~~~~\n::\n\n    StrToUtf8(string)\n\nConverts string from ANSI to UTF8. \n\nNote, that since Windows 10 the codepage for non-unicode programs can\nbe set to UTF8 natively. ANSI is meant to be the active code page of the system.\n\nStrFromUtf8\n~~~~~~~~~~~\n::\n\n    StrFromUtf8(string)\n\nConverts string from UTF8 to ANSI.\n\nValid on Windows.\n\nNote, that since Windows 10 the codepage for non-unicode programs can\nbe set to UTF8 natively.\n\nStrLen\n~~~~~~\n::\n\n    StrLen(string)\n\nReturns length of string.\n\n*Examples:*\n::\n\n    StrLen(\"AviSynth\") = 8\n\nRevStr\n~~~~~~\n::\n\n    RevStr(string)\n\nReturns string backwards.\n\n*Examples:*\n::\n\n    RevStr(\"AviSynth\") = \"htnySivA\"\n\nLeftStr\n~~~~~~~\n::\n\n    LeftStr(string, int)\n\nReturns first int number of characters.\n\n*Examples:*\n::\n\n    LeftStr(\"AviSynth\", 3) = \"Avi\"\n\nRightStr\n~~~~~~~~\n::\n\n    RightStr(string, int)\n\nReturns last int number of characters.\n\n*Examples:*\n::\n\n    RightStr(\"AviSynth\", 5) = \"Synth\"\n\nMidStr\n~~~~~~\n::\n\n    MidStr(string, int pos [, int length])\n\nReturns substring starting at ``pos`` for optional ``length`` or to end. ``pos=1``\nspecifies start.\n\n*Examples:*\n::\n\n    MidStr(\"AviSynth\", 3, 2) = \"iS\"\n\nFindStr\n~~~~~~~\n::\n\n    FindStr(string, substring)\n\nReturns position of ``substring`` within ``string``.\n\nReturns 0 if substring is not found.\n\n*Examples:*\n::\n\n    FindStr(\"AviSynth\", \"Syn\") ## returns 4\n    FindStr(\"AviSynth\", \"SYN\") ## returns 0\n\nReplaceStr\n~~~~~~~~~~\n::\n\n    ReplaceStr(string, substring, replacement_string [, bool sig])\n\nReplaces occurrences of ``substring`` with ``replacement_string`` and returns the result.\n\n.. describe:: bool sig\n\n    - false (the default): search is case sensitive\n    - true: search is not case insensitive.\n\n*Example:*\n::\n\n    ReplaceStr(\"FlipHorizontal\", \"Horizontal\", \"Vertical\")\n    ReplaceStr(\"$a x *\", \"$a\", String(1.5)) ## (a MaskTools expression with argument)\n    ## this latter is more elegant with using \"Format\"\n\nAvisynth 2.6.x users have other options, such as the user function below, adapted from StrReplace, \nfound `here <https://avisynth.nl/index.php/HDColorBars>`_ .\n\n::\n\n    # for old systems where ReplaceStr is missing:\n    function ReplaceStr(string base, string sought, string repstr) {\n        pos = FindStr(base, sought)\n        return (sought==\"\" || pos==0) ? base : ReplaceStr(\n        \\       LeftStr(base, pos-1) + repstr +\n        \\       MidStr(base, pos+StrLen(sought)),\n        \\       sought, repstr)\n    }\n\nFormat\n~~~~~~\n::\n\n    Format(formatstring [, value1, value2, ...])\n\nReplaces the in-string placeholders with parameters and returns the result\n\nParameters can be of any type; each parameter is converted to string beforehand.\n\n.. describe:: string formatstring\n\n    unnamed parameter. A string literal with parameter insertion points marked with ``{}``.\n\n.. describe:: value1, value2, etc.\n\n    zero or more values which are inserted into the format string one after another \n\nDescription:\n\n    The format string consists of \n\n    - ordinary characters ( except ``{`` and ``}`` ), which are copied unchanged to the output,\n    - escape sequences: double ``\"{\"`` (``\"{{\"``) and double ``\"}\"`` (``\"}}\"``), which are replaced with \n      ``\"{\"`` and ``\"}\"`` respectively in the output\n    - replacement placeholder fields. \n\nEach replacement field has the following format:\n\n::\n\n    introductory { character; \n    (optional) \n        arg-id, a non-negative number;\n      or: \n        identifier which is used for lookup named parameters. (when values are given in [\"name\", value] construction)\n      or: \n        valid AviSynth variable name \n    final } character. \n\n- If arg-id is a number it specifies the index of the argument \n  in args whose value is to be used for formatting; \n- Index is zero based. \n- If arg-id is string then it serves as a lookup key from the \n  parameters list given as an array [\"name\",value] pair. \n- If not found, then arg-id is searched among Avisynth variables. \n- If arg-id is omitted, the arguments are used in order. \n- Mixing manual and automatic indexing is not an error. \n\nNotes\n\n    It is not an error to provide more arguments than the format string requires: \n\n::\n\n    Format(\"{} {}!\", \"Hello\", \"world\", \"something\") # OK, produces \"Hello world!\"\n\n*Examples:*\n\n::\n\n    # By Avisynth variable\n    max_pixel_value = 255\n    SubTitle(Format(\"max={max_pixel_value}!\")) # no format value given, inserts directly from variable\n    # result: \"max=255!\"\n\n::\n\n    # By index:\n    SubTitle(Format(\"{0} {1} {0}\", \"Home\", \"sweet\"))\n    # result: \"Home sweet Home\"\n\n::\n\n    # by order:\n    SubTitle(Format(\"{} {} {}\", \"AviSynth\", \"+\", 2020))\n    # result: \"AviSynth + 2020\"\n\n::\n\n    # by Array name-value pairs:\n    SubTitle(Format(\"maximum={max} minimum={min} max again {max}!\", [\"max\",255], [\"min\",0]))\n    # result: \"\"maximum=255 minimum=0 max again 255!\"\n\n\nFillStr\n~~~~~~~\n::\n\n    FillStr(int [, string]) Fills a string.\n\nWhen ``int > 1`` it concatenates the string ``int`` times. ``String`` is space by default.\n\n*Examples:*\n::\n\n    FillStr(1, \"AviSynth\") = \"AviSynth\"\n    FillStr(2, \"AviSynth\") = \"AviSynthAviSynth\"\n\nStrCmp\n~~~~~~\n::\n\n    StrCmp(string, string)\n\nCompares two character strings. The comparison is case-sensitive. If the\nfirst string is less than the second string, the return value is negative. If\nit's greater, the return value is positive. If they are equal, the return\nvalue is zero. (The actual value seems to be host operating system dependent\nso it can't be relied upon.)\n\n*Examples:*\n::\n\n    StrCmp(\"AviSynth\", \"AviSynth\") = 0 # strings are equal.\n    StrCmp(\"AviSynth\", \"Avisynth\") != 0 # strings are not equal.\n\nStrCmpi\n~~~~~~~\n::\n\n    StrCmpi(string, string)\n\nCompares two character strings. The comparison is not case-sensitive. If the\nfirst string is less than the second string, the return value is negative. If\nit's greater, the return value is positive. If they are equal, the return\nvalue is zero. (The actual value seems to be host operating system dependent\nso it can't be relied upon.)\n\n*Examples:*\n::\n\n    StrCmpi(\"AviSynth\", \"AviSynth\") = 0 # strings are equal.\n    StrCmpi(\"AviSynth\", \"Avisynth\") = 0 # strings are equal.\n    StrCmpi(\"abcz\", \"abcdefg\") != 0 # returns the difference betweeen \"z\"\n    and \"d\" (which is positive).\n\nTrimLeft, TrimRight, TrimAll\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n::\n\n    TrimLeft(string)\n    TrimRight(string)\n    TrimAll(string)\n\nRemoves whitespace characters (space, tab, `nonbreaking space <https://en.wikipedia.org/wiki/Non-breaking_space>`_\n) from the left, right, or both ends (respectively) of ``string``.\n\nChr\n~~~\n::\n\n    Chr(int)\n\nReturns the ASCII character. Note that characters above the ASCII character\nset (ie above 127) are code page dependent and may render different (visual)\nresults in different systems. This has an importance only for user-supplied\nlocalised text messages.\n\n*Examples:*\n::\n\n    Chr(34) returns the quote character\n    Chr(9) returns the tab  character\n\nOrd\n~~~\n::\n\n    Ord(string)\n\nGives the ordinal number of the  first character of a string.\n\n*Examples:*\n::\n\n    Ord(\"a\") = 97\n    Ord(\"AviSynth\") = Ord(\"A\") = 65\n    Ord(\"§\") = 167\n\nTime\n~~~~\n::\n\n    Time(string)\n\nReturns a string with the current system time formatted as defined by the\nstring. The string may contain any of the codes for output formatting\npresented below:\n\n+--------+---------------------------------------------------+\n| Code   | Description                                       |\n+========+===================================================+\n| %a     | Abbreviated weekday name                          |\n|        |                                                   |\n| %A     | Full weekday name                                 |\n+--------+---------------------------------------------------+\n| %b     | Abbreviated month name                            |\n|        |                                                   |\n| %B     | Full month name                                   |\n+--------+---------------------------------------------------+\n| %c     | Date and time representation                      |\n|        | appropriate for locale                            |\n+--------+---------------------------------------------------+\n| %d     | Day of month as decimal number (01 ? 31)          |\n+--------+---------------------------------------------------+\n| %H     | Hour in 24-hour format (00 ? 23)                  |\n|        |                                                   |\n| %I     | Hour in 12-hour format (01 ? 12)                  |\n+--------+---------------------------------------------------+\n| %j     | Day of year as decimal number (001 ? 366)         |\n+--------+---------------------------------------------------+\n| %m     | Month as decimal number (01 ? 12)                 |\n+--------+---------------------------------------------------+\n| %M     | Minute as decimal number (00 ? 59)                |\n+--------+---------------------------------------------------+\n| %p     | Current locale's A.M./P.M.                        |\n|        | indicator for 12-hour clock                       |\n+--------+---------------------------------------------------+\n| %S     | Second as decimal number (00 ? 59)                |\n+--------+---------------------------------------------------+\n| %U     | Week of year as decimal number,                   |\n|        | with Sunday as first day of week (00 ? 53)        |\n+--------+---------------------------------------------------+\n| %w     | Weekday as decimal number (0 ? 6; Sunday is 0)    |\n+--------+---------------------------------------------------+\n| %W     | Week of year as decimal number,                   |\n|        | with Monday as first day of week (00 ? 53)        |\n+--------+---------------------------------------------------+\n| %x     | Date representation for current locale            |\n+--------+---------------------------------------------------+\n| %X     | Time representation for current locale            |\n+--------+---------------------------------------------------+\n| %y     | Year without century, as decimal number (00 ? 99) |\n|        |                                                   |\n| %Y     | Year *with* century, as decimal number            |\n+--------+---------------------------------------------------+\n| %z, %Z | Time-zone name or abbreviation;                   |\n|        | no characters if time zone is unknown             |\n+--------+---------------------------------------------------+\n| %%     | Percent sign                                      |\n+--------+---------------------------------------------------+\n\nThe # flag may prefix any formatting code. In that case, the meaning of the\nformat code is changed as follows:\n\n+-------------------------------+---------------------------------------------------------------------------------+\n| Code with # flag              | Change in meaning                                                               |\n+===============================+=================================================================================+\n| %#a, %#A, %#b, %#B,           |                                                                                 |\n|                               | No change; # flag is ignored.                                                   |\n| %#p, %#X, %#z, %#Z, %#%       |                                                                                 |\n+-------------------------------+---------------------------------------------------------------------------------+\n| %#c                           || Long date and time representation, appropriate for current locale. For example:|\n|                               || ``?Tuesday, March 14, 1995, 12:41:29?.``                                       |\n+-------------------------------+---------------------------------------------------------------------------------+\n| %#x                           || Long date representation, appropriate to current locale. For example:          |\n|                               || ``?Tuesday, March 14, 1995?.``                                                 |\n+-------------------------------+---------------------------------------------------------------------------------+\n| %#d, %#H, %#I, %#j, %#m, %#M, |                                                                                 |\n|                               | Remove leading zeros (if any).                                                  |\n| %#S, %#U, %#w, %#W, %#y, %#Y  |                                                                                 |\n+-------------------------------+---------------------------------------------------------------------------------+\n\n\nChangelog\n~~~~~~~~~\n+----------------+--------------------------------------------+\n| Version        | Changes                                    |\n+================+============================================+\n| Avisynth+      | | Added \"Format\"                           |\n|                | | Added \"StrToUtf8\"                        |\n|                | | Added \"StrFromUtf8\"                      |\n|                | | Added \"ReplaceStr\"                       |\n|                | | Added \"Format\"                           |\n|                | | Added \"TrimLeft\", \"TrimRight\", \"TrimAll\" |\n+----------------+--------------------------------------------+\n\n\n--------\n\nBack to :doc:`Internal functions <syntax_internal_functions>`.\n\n$Date: 2024/01/08 14:58:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_internal_functions_trig.rst",
    "content": "\nAviSynth Syntax - Trigonometry functions\n========================================\n\nRelationships involving lengths and angles of triangles. \n\n\nSin\n~~~\n::\n\n    Sin(float)\n\nReturns the sine of the argument (assumes it is radians).\n\n*Examples:*\n::\n\n    Sin(Pi()/4) = 0.707\n    Sin(Pi()/2) = 1.0\n\nCos\n~~~\n::\n\n    Cos(float)\n\nReturns the cosine of the argument (assumes it is radians).\n\n*Examples:*\n::\n\n    Cos(Pi()/4) = 0.707\n    Cos(Pi()/2) = 0.0\n\nTan\n~~~\n::\n\n    Tan(float)\n\nReturns the tangent of the argument (assumes it is radians).\n\n*Examples:*\n::\n\n    Tan(Pi()/4) = 1.0\n    Tan(Pi()/2) = not defined\n\n32 bit IEEE floats do not have sufficient resolution to exactly represent \npi/2 so AviSynth returns a large positive number for the value slightly less \nthan pi/2 and a large negative value for the next possible value which is \nslightly greater than pi/2. \n\nAsin\n~~~~\n::\n\n    Asin(float)\n\nReturns the inverse of the sine of the argument (output is radians).\n\n*Examples:*\n::\n\n    Asin(0.707) = 0.7852471634 (~ Pi/4)\n    Asin(1.0) = 1.570796327 (~ Pi/2)\n\nAcos\n~~~~\n::\n\n    Acos(float)\n\nReturns the inverse of the cosine of the argument (output is in radians).\n\n*Examples:*\n::\n\n    Acos(0.707) = 0.7852471634 (~ Pi/4)\n    Acos(0.0) = 1.570796327 (~ Pi/2)\n\nAtan\n~~~~\n::\n\n    Atan(float)\n\nReturns the inverse of the tangent of the argument (output is in radians).\n\n*Examples:*\n::\n\n    Atan(0.707) = 0.6154085176\n    Atan(1.0) = 0.7853981634 (~ Pi/4)\n\nAtan2\n~~~~~\n::\n\n    Atan2(float, float)\n\nReturns the angle between the positive x-axis of a plane and the point given\nby the coordinates (x, y) on it (output is in radians). See `the wikipedia article on Atan2`_ for\nmore information. y is the first argument and x is the second argument.\n\n*Examples:*\n::\n\n    Atan2(1.0, 0) = 1.570796327 (~ Pi/2)\n    Atan2(1.0, 1.0) = 0.7852471634 (~ Pi/4)\n    Atan2(-1.0, -1.0) = -2.356194490 (~ -3Pi/4)\n\n\nSinh\n~~~~\n::\n\n    Sinh(float)\n\nReturns the hyperbolic sine of the argument. See `wikipedia`_ for more\ninformation.\n\n*Examples:*\n::\n\n    Sinh(2.0) = 3.626860408\n\nCosh\n~~~~\n::\n\n    Cosh(float)\n\nReturns the hyperbolic cosine of the argument.\n\n*Examples:*\n::\n\n    Cosh(2.0) = 3.762195691\n\nTanh\n~~~~\n::\n\n    Tanh(float)\n\nReturns the hyperbolic tangent of the argument.\n\n*Examples:*\n::\n\n    Tanh(2.0) = 0.9640275801\n\n--------\n\nBack to :doc:`Internal functions <syntax_internal_functions>`.\n\n$Date: 2024/01/15 16:16:00 $\n\n.. _the wikipedia article on Atan2: http://en.wikipedia.org/wiki/Atan2\n.. _wikipedia: http://en.wikipedia.org/wiki/Hyperbolic_function\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_internal_functions_version.rst",
    "content": "\nAviSynth Syntax - Version functions\n===================================\n\nVersion functions provide AviSynth and OS version or bitness information.\n\nVersionNumber\n~~~~~~~~~~~~~\n::\n\n    VersionNumber()\n\nReturns AviSynth version number as a float.\n\nNote: use VersionString below to determine if running in AviSynth+. \n\n*Examples:*\n::\n\n    ver = VersionNumber() # ver == 2.57\n    VersionNumber ## returns 2.60 (release version as of 11/2017)\n    VersionNumber ## returns 2.61 (beta)\n    VersionNumber ## returns 2.60 (AVS+ releases)\n\nVersionString\n~~~~~~~~~~~~~\n::\n\n    VersionString()\n\nReturns AviSynth version info as a string (first line used in :doc:`Version <../corefilters/version>`\ncommand).\n\n*Examples:*\n::\n\n    VersionString ## returns \"AviSynth 2.60, build:Mar 31 2015 [16:38:54]\"\n    VersionString ## returns \"AviSynth 2.61, build:May 17 2016 [16:06:18] VC2008Exp\"\n    VersionString ## returns \"AviSynth+ 0.1, (r2508, MT, x86_64)\"\n    VersionString ## returns \"AviSynth+ 3.7.3 (r4041, master, x86_64)\"\n\nSometimes we have distinct between Avisynth+ or Avisynth classic 2.6\n::\n\n    function IsAvsPlus()\n    {\n        sVer = LCase(VersionString) \n        return (FindStr(sVer, \"avisynth+\")    > 0)\n        \\   || (FindStr(sVer, \"avisynthplus\") > 0)\n    }\n\nIsVersionOrGreater\n~~~~~~~~~~~~~~~~~~\n::\n\n    bool IsVersionOrGreater(int majorVersion, int minorVersion [,int bugfixVersion])\n    \n    Returns true if Avisynth+ version is is equal or greater than the required one in the parameters. \n    Since Avisynth+ 3.5 \n\n*Examples:*\n\nCheck if script is run under at least...\n::\n\n    isAtLeast3_10 = IsVersionOrGreater(3,10)\n    isAtLeast3_5_1 = IsVersionOrGreater(3,5,1)\n\n    if(IsVersionOrGreater(3,7))\n    {  SubTitle(\"at least 3.7\") \n    }\n    if(IsVersionOrGreater(3,7,3))\n    {  SubTitle(\"at least 3.7.3\") \n    }\n\n\nGetProcessInfo\n~~~~~~~~~~~~~~\n::\n\n    GetProcessInfo(int)\n\nReturns information about the process the script is running in. \n\n.. describe:: int (required)\n\n    valid values are 0 (default) and 1.\n\n    - 0 (default):\n\n      - returns 64 for a 64-bit process \n      - returns 32 for a 32-bit process.\n\n    - 1\n\n      - returns 0 for 32-bit process on 32-bit OS;\n      - returns 1 for 32-bit process on 64-bit OS;\n      - returns 2 for 64-bit process on 64-bit OS;\n      - else returns -1 (unknown) \n\n*Examples:*\n\nAlways loads the appropriate 32/64 bit plugin version:\n::\n\n    IF (GetProcessInfo() == 32) {\n    LoadVirtualdubPlugin(\"c:\\virtualdub\\plugins32\\Deshaker.vdf\",\"deshaker\")\n    } else {\n    LoadVirtualdubPlugin(\"c:\\virtualdub\\plugins64\\Deshaker_64.vdf\",\"deshaker\")\n    }\n    .. source filter ..\n    ConvertBits(8)\n    ConvertToRGB32()\n    Deshaker(\"19|1|30|4|1|0|1|0|640|480|1|2|1000|1000|1000|1000|4|1|0|2|8|30|300|4|C:\\\\temp\\\\Deshaker.log|0|0|0|0|0|0|0|0|0|0|0|0|0|1|15|15|5|15|0|0|30|30|0|0|0|0|1|1|0|10|1000|1|88|1|1|20|5000|100|20|1|0|ff00ff\")\n\nWith parameters:\n::\n\n    SubTitle(\"Process bits=\" + string(GetProcessInfo) + \\\n      \" detailed=\" + string(GetProcessInfo(1)) + \\\n      \" type0=\" + string(GetProcessInfo(0)))\n    # returns process bits=64 detailed=2 type0=64\n    # running a 64 bit Avisynth on 64 bit OS\n\n\n+----------------+----------------------------------+\n| Version        | Changes                          |\n+================+==================================+\n| AviSynth+      | | IsVersionOrGreater             |\n|                | | GetProcessInfo                 |\n+----------------+----------------------------------+\n\n\n--------\n\nBack to :doc:`Internal functions <syntax_internal_functions>`.\n\n$Date: 2008/04/20 19:07:34 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_operators.rst",
    "content": "\nAviSynth Syntax - Operators\n===========================\n\nAs in all programming and scripting languages, operators in AviSynth script\nlanguage allow the performance of actions (operations) onto :doc:`variables <syntax_script_variables>`.\nOperators form the basis for building up expressions, the building blocks of\nAviSynth scripts.\n\nAviSynth operators follow loosely the same rules as C operators, regarding\nmeaning, precedence and associativity. By loosely we mean that there are some\nexceptions, indicated in the text below.\n\nNote that when a binary operator is applied to an int and a float, the int is\nfirst converted to float, as in C.\n\n\nAvailable Operators per Type\n----------------------------\n\nFor **all types** of operands (clip, int, float, string, bool) you can use\nthe following operators:\n\n+--------+--------------------------------------+\n| ``==`` | is equal                             |\n+--------+--------------------------------------+\n| ``!=`` | not equal                            |\n+--------+--------------------------------------+\n| ``<>`` | not equal (alternative to !=, v2.07) |\n+--------+--------------------------------------+\n\nString comparisons are not case-sensitive, so \"abc\" == \"ABC\" returns *true*.\n\nFor **numeric** types (int, float) you can use the following int/float-\nspecific operators:\n\n+--------+-----------------------+\n| ``+``  | add                   |\n+--------+-----------------------+\n| ``-``  | subtract              |\n+--------+-----------------------+\n| ``*``  | multiply              |\n+--------+-----------------------+\n| ``/``  | divide                |\n+--------+-----------------------+\n| ``%``  | mod                   |\n+--------+-----------------------+\n| ``>=`` | greater or equal than |\n+--------+-----------------------+\n| ``<=`` | less or equal than    |\n+--------+-----------------------+\n| ``<``  | less than             |\n+--------+-----------------------+\n| ``>``  | greater than          |\n+--------+-----------------------+\n\n*AviSynth in former versions parsed expressions from right to left, which\ngave unexpected results.* For example:\n\n-   a = 10 - 5 - 5 resulted in 10 - (5 - 5) = 10 instead of (10 - 5) - 5\n    = 0 !\n-   b = 100. / 2. / 4. resulted in 100. / (2. / 4.) = 200 instead of\n    (100. / 2.) / 4. = 12.5 !\n\nThese \"bugs\" have been corrected in v2.53!\n\nFor **string** type you can use the following string-specific operators:\n\n+--------+-------------------------------+\n| ``+``  | concatenate                   |\n+--------+-------------------------------+\n| ``>=`` | greater or equal than (v2.07) |\n+--------+-------------------------------+\n| ``<=`` | less or equal than (v2.07)    |\n+--------+-------------------------------+\n| ``<``  | less than (v2.07)             |\n+--------+-------------------------------+\n| ``>``  | greater than (v2.07)          |\n+--------+-------------------------------+\n\nLike the equality operator, these string comparisons are case-insensitive.\n\nFor **clip** type you can use the following clip-specific operators:\n\n+--------+-------------------------------------------------------------------------+\n| ``+``  | the same as the function :doc:`UnalignedSplice <../corefilters/splice>` |\n+--------+-------------------------------------------------------------------------+\n| ``++`` | the same as the function :doc:`AlignedSplice <../corefilters/splice>`   |\n+--------+-------------------------------------------------------------------------+\n\nFor **bool** type (true/false) you can use the following bool-specific\noperators:\n\n+--------+----------------------------+\n| ``||`` | or                         |\n+--------+----------------------------+\n| ``&&`` | and                        |\n+--------+----------------------------+\n| ``?:`` | execute code conditionally |\n+--------+----------------------------+\n| ``!``  | not                        |\n+--------+----------------------------+\n\nThe conditional execution operator is used as in the following example:\n\n::\n\n    b = (a==true) ? 1 : 2\n\nThis means in pseudo-basic:\n\n::\n\n    if (a=true) then b=1 else b=2\n\nFrom version v2.07, AviSynth provides a NOP() function which can be used\ninside a conditional execution block in cases where \"else\" may not otherwise\nbe desirable (such as a conditional :doc:`Import <../corefilters/import>` or :doc:`LoadPlugin <syntax_plugins>`).\n\n\nOperator Precedence\n-------------------\n\nThe precedence of AviSynth operators is presented at the table below.\nOperators higher to the top of the table have higher precedence. Operators\ninside the same row have the same order of precedence.\n\n+--------+--------+--------+--------+---------+--------+--------+\n| ``*``  | ``/``  | ``%``  |        |         |        |        |\n+--------+--------+--------+--------+---------+--------+--------+\n| ``+``  | ``++`` | ``-``  |        |         |        |        |\n+--------+--------+--------+--------+---------+--------+--------+\n| ``<``  | ``>``  | ``<=`` | ``>=`` |  ``!=`` | ``<>`` | ``==`` |\n+--------+--------+--------+--------+---------+--------+--------+\n| ``&&`` |        |        |        |         |        |        |\n+--------+--------+--------+--------+---------+--------+--------+\n| ``||`` |        |        |        |         |        |        |\n+--------+--------+--------+--------+---------+--------+--------+\n| ``?:`` |        |        |        |         |        |        |\n+--------+--------+--------+--------+---------+--------+--------+\n\nThe dot symbol (**.**), used in the \"OOP notation\" for a function call, is\nnot strictly an operator, but effectively has a higher precedence than any\noperator symbol. So for example, ``a + b.f(args)`` means ``a + f(b, args)``\nand not ``f(a+b, args)`` (which could be written as ``(a+b).f(args)``)\n\n$Date: 2012/03/11 16:05:32 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_plugins.rst",
    "content": "\nAviSynth Syntax - Plugins\n=========================\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\nWith these functions you can add external functions to AviSynth or\nget/set autoload directories.\n\nIn general, where applicable:\n\n- ``utf8`` (optional, boolean) - when ``true``, the supplied directory or file name \n  string is interpreted as UTF-8. When ``false``, on Windows the string is interpreted\n  as ANSI (system code page) and converted internally to UTF-8 before being used.\n- Default behaviour:\n\n  * On non-Windows platforms (POSIX, macOS, Linux) the system uses UTF-8 by default,\n    so the function behaves as UTF-8-only and the ``utf8`` parameter is effectively\n    transparent (default === ``true``).\n  * On Windows the historical default is ANSI. If you do not pass ``utf8`` the\n    function will behave in the legacy ANSI manner (default === ``false``). To pass\n    a UTF-8 encoded directory path from a script on Windows, pass ``utf8=true``.\n  * When the Windows process is built or launched with UTF-8 manifest (making the\n    process use UTF-8 as the default ANSI code page), the behaviour is transparent\n    UTF-8 and supplying ``utf8`` is not required.\n\nManual plugin loading\n---------------------\n\nLoadPlugin\n~~~~~~~~~~\n::\n\n    LoadPlugin (\"filename\" [, ...] [, bool utf8=false])\n\nLoads one or more external avisynth plugins (DLLs).\n\nPlugins can be either C or C++ plugins, they are autodetected.\n\nWindows historically uses ANSI (system code page) for script string parameters,\nso scripts that need to supply UTF-8 paths must indicate this explicitly. The\n``utf8`` parameter allows a script to unambiguously tell the function that the\nprovided filename path is UTF-8 encoded. On UTF-8-native systems (POSIX or Windows\nwith UTF-8 manifest) the conversion step is unnecessary and thus transparent, the\nparameter is ignored.\n\n\nLoadVirtualDubPlugin\n~~~~~~~~~~~~~~~~~~~~\n::\n\n    LoadVirtualDubPlugin (\"filename\", \"filtername\", preroll)\n\nThis loads a plugin written for VirtualDub. \"filename\" is the name of the\n.vdf file. After calling this function, the filter will be known as\n\"filtername\" in avisynth. \n\nOld VirtualDub filters only supports RGB32, but then some came with YUV support\n(a newer API). The most compatible way of using them is using ``ConvertToRGB32``\n(``ConvertToRGB`` won't suffice for an RGB24 source).\n\nSome filters output depends on previous frames; for those preroll should be\nset to at least the number of frames the filter needs to pre-process to fill\nits buffers and/or updates its internal variables.\n\n\nLoadVFAPIPlugin (removed, not part of AviSynth+)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n::\n\n    LoadVFAPIPlugin (\"filename\", \"filtername\")\n\nThis allows you to use VFAPI plugins (TMPGEnc import plugins).\n\n\nLoadCPlugin\n~~~~~~~~~~~\nLoad_Stdcall_Plugin\n~~~~~~~~~~~~~~~~~~~\n::\n\n    LoadCPlugin (\"filename\" [, ...])\n    Load_Stdcall_Plugin (\"filename\" [, ...])\n\nIn Avisynth+ these function were kept for script compatibility reasons.\n\nLoadPlugin can load any type of (C or C++) plugins by automatically detecting \ntheir types.\n\nLoads so called Avisynth C-plugins (DLLs).\nLoad_Stdcall_Plugin() is an alias for LoadCPlugin().\nC-plugins are created on pure C language and use special \"AviSynth C API\"\n(unlike ordinary Avisynt plugins which are created with MS C++). C-plugins\nmust be loaded with LoadCPlugin() or Load_Stdcall_Plugin().\n\nKevin provides a LoadCPlugin.dll that overloads the LoadCPlugin() verb to\nsupport plugins compiled using the C subroutine calling sequence, use\nLoad_Stdcall_Plugin() to load stdcall calling sequence plugins when using\nKevins version. Advice: keep these plugins outside your auto plugin loading\ndirectory to prevent crashes. `[discussion]`_ `[AVISynth C API (by\nkevina20723)]`_\n\n\nAutoload helper functions\n-------------------------\n\nAddAutoloadDir\n~~~~~~~~~~~~~~\n::\n\n    AddAutoloadDir (string \"directory\", bool toFront = true, bool utf8 = false)\n\nThis function appends an extra directory to the autoload directory list. The plugins\nare searched in the order the directories appear in the list. Setting the optional \n``toFront`` parameter to false will put the directory at the end of \nthe list (the lowest priority place).\n\nWindows historically uses ANSI (system code page) for script string parameters,\nso scripts that need to supply UTF-8 paths must indicate this explicitly. The\n``utf8`` parameter allows a script to unambiguously tell the function that the\nprovided directory path is UTF-8 encoded.\n\nOn UTF-8-native systems (POSIX or Windows with UTF-8 manifest) the conversion step\nis unnecessary and thus transparent, the parameter is ignored.\n\n``directory`` parameter can contain macros. These are expanded to their actual values\nduring the operation.\n\n- Folder names maintained by Avisynth instance:\n\n  * ``SCRIPTDIR`` from Avisynth variable ``$ScriptDirUtf8$``\n  * ``MAINSCRIPTDIR`` from Avisynth variable ``$MainScriptDirUtf8$``\n  * ``PROGRAMDIR`` the actual folder of the host executable \n  \n- Windows specific: registry-backed macros that can contain plugin folder paths \n\n  - x86 (Intel 32 or 64 bit builds)\n\n    * ``USER_PLUS_PLUGINS`` from ``HKCU\\Software\\Avisynth\\PluginDir+`` (or GNU C Build: ``HKCU\\Software\\Avisynth\\PluginDir+GCC``)\n    * ``MACHINE_PLUS_PLUGINS`` from ``HKLM\\Software\\Avisynth\\PluginDir+`` (or GNU C Build:  ``HKLM\\Software\\Avisynth\\PluginDir+GCC``)\n    * ``USER_CLASSIC_PLUGINS`` from ``HKCU\\Software\\Avisynth\\PluginDir2_5``\n    * ``MACHINE_CLASSIC_PLUGINS`` from ``HKLM\\Software\\Avisynth\\PluginDir2_5``\n  \n  - other (e.g. ARM)\n  \n    * ``USER_PLUS_PLUGINS`` from ``HKCU\\Software\\Avisynth\\PluginDir+``\n    * ``MACHINE_PLUS_PLUGINS`` from ``HKLM\\Software\\Avisynth\\PluginDir+``\n\n\nClearAutoloadDirs\n~~~~~~~~~~~~~~~~~\n::\n\n    ClearAutoloadDirs\n\nRemoves everything from the plugin autoload directory list, making a clean \nstart for your custom environment.\n\nListAutoloadDirs\n~~~~~~~~~~~~~~~~\n::\n\n    ListAutoloadDirs(bool utf8 = false)\n\nReturns a LF (0x0A, \\\\n) separated list of the currently set autoload directories.\nThe multiline string can be displayed with \"Text\" or \"Subtitle\" directly.\n\nWindows historically uses ANSI (system code page) for script string parameters,\nso scripts that need to obtain path in UTF-8 must indicate this explicitly. The\n``utf8`` parameter allows a script to unambiguously tell the function that the\nexpected directory path list is UTF-8 encoded. On UTF-8-native systems (POSIX or Windows\nwith UTF-8 manifest) the conversion step is unnecessary and thus transparent, the\nparameter is ignored.\n\n::\n\n    # This works for ANSI-only hosts as well\n    AddAutoLoadDir(\"d:\\20251116_Utf8pathImportError_Утка Πάπια\\\", utf8=true)\n    AddAutoLoadDir(\"MAINSCRIPTDIR\\myplugins\")\n    AddAutoLoadDir(\"SCRIPTDIR\\myplugins2\")\n    AddAutoLoadDir(\"PROGRAMDIR\\extraplugins\")\n    AddAutoLoadDir(\"MACHINE_PLUS_PLUGINS\\myplugins3\")\n    SubTitle(ListAutoLoadDirs(utf8=true), align=7, size=20, utf8=true)\n\nAutoloadPlugins\n~~~~~~~~~~~~~~~\n::\n\n    AutoloadPlugins\n\nInitiates plugin autoloading, if it did not happened so far.\n\n\nPlugin autoload and name precedence (Historical, Avisynth v2)\n-------------------------------------------------------------\n\nIt is possible to put all plugins and script files with user-defined\nfunctions or (global) variables in a directory from where all files with the\nextension .AVSI (**v2.08, v2.5**, the type was .AVS in **v2.05-2.07**) and\n.DLL are loaded at startup, unloaded and then loaded dynamically as the\nscript needs them.\n\n.AVSI scripts in this directory should only contain function definitions and\nglobal variables, no main processing section (else strange errors may occur),\nit also is not recommended to put other files in that directory.\n\nThe directory is stored in the registry (the registry key has changed for\n**v2.5**). You can use double-clicking a .REG-file with the following lines\nto set the path (of course inserting your actual path):\n::\n\n    REGEDIT4\n\n    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Avisynth]\n    \"plugindir2_5\"=\"c:\\\\program files\\\\avisynth 2.5\\\\plugins\"\n\nThe order in which function names take precedence is as follows:\n::\n\n    user-defined function (always have the highest priority)\n       plugin-function (have higher priority than built-in functions, they will override a built-in function)\n          built-in function\n\nInside those groups the function loaded at last takes precedence, there is no\nerror in a namespace conflict.\n\n\nPlugin autoload and conflicting function names (v2.55)\n------------------------------------------------------\n\nStarting from v2.55 there is DLLName_function() support. The problem is that\ntwo plugins can have different functions which are named the same. To call\nthe needed one, DLLName_function() support is added. It auto-generates the\nadditional names both for auto-loaded plugins and for plugins loaded with\nLoadPlugin.\n\n**Some examples:**\n\n::\n\n    # using fielddeinterlace from decomb510.dll\n    AviSource(\"D:\\captures\\jewel.avi\")\n    decomb510_fielddeinterlace(blend=false)\n\nSuppose you have  the plugins mpeg2dec.dll and mpeg2dec3.dll in your auto\nplugin dir, and you want to load a d2v file with mpeg2dec.dll (which outputs\nYUY2):\n\n::\n\n    # using mpeg2source from mpeg2dec.dll\n    mpeg2dec_mpeg2source(\"F:\\From_hell\\from_hell.d2v\")\n\nor with mpeg2dec3.dll (which outputs YV12):\n\n::\n\n    # using mpeg2source from mpeg2dec3.dll\n    mpeg2dec3_mpeg2source(\"F:\\From_hell\\from_hell.d2v\")\n\nChangelog\n~~~~~~~~~\n+----------------+------------------------------------------------------------+\n| Version        | Changes                                                    |\n+================+============================================================+\n| Avisynth 3.7.6 | | Added utf8 parameter to AddAutoLoadDir, mention folder   |\n|                |   macros in documentation                                  |\n|                | | Added utf8 parameter to ListAutoLoadDirs                 |\n|                | | Added utf8 parameter to LoadPlugin                       |\n+----------------+------------------------------------------------------------+\n\n$Date: 2025/11/18 11:38:00 $\n\n.. _[discussion]: http://forum.doom9.org/showthread.php?s=&threadid=58840\n.. _[AVISynth C API (by kevina20723)]:\n    http://kevin.atkinson.dhs.org/avisynth_c/\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_ref.rst",
    "content": "\nAviSynth Syntax\n===============\n\nAll basic AviSynth scripting statements have one of these forms:\n\n1.  *variable_name* = *expression*\n2.  *expression*\n3.  **return** *expression*\n\n(Higher-level constructs also exist - the :doc:`function declaration <syntax_userdefined_scriptfunctions>`, the \n:doc:`try..catch statement <syntax_control_structures>`, :doc:`if..else statement <syntax_control_structures>`, \n:doc:`while loop <syntax_control_structures>` and :doc:`for loop <syntax_control_structures>`. \nThe latter three - introduced by Gavino - was an extension to classic Avisynth and now integral part of Avisynth+)\n\nIn the first case, *expression* is evaluated and the result is assigned to\n*variable_name*. In the second case, *expression* is evaluated and the\nresult, if a clip, is assigned to the special variable **last**. In the third\ncase, *expression* is evaluated and is used as the \"return value\" of the\nactive script block--that is either a function or the entire script. In the\nlatter case, the return value is typically the video clip that will be seen\nby the application which opens the AVS file. As a shorthand, a bare\nexpression as the final statement in a script (or script block) is treated as\nif the keyword **return** was present.\n\nMost of the time the result of an expression will be a video clip; however an\nexpression's result can be of any type supported by the scripting language\n(clip, int, float, bool, string) and this is how utility functions such as\n:doc:`internal script functions <syntax_internal_functions>` operate.\n\nAn *expression* can have one of these forms:\n\n1.  *numeric_constant*, *string_constant* or *boolean_constant* or *array_constant*\n2.  *variable_name* or *clip_property* or *indexed array_variable_name*\n3.  *Function*(*args*)\n4.  *expression*.*Function*(*args*)\n5.  *expression1* **operator** *expression2*\n6.  *bool_expression* ? *expression1* : *expression2*\n7.  *function object*\n8.  *function object*(*args*)\n\nIn the first case, the value of the *expression* is the value of the\nconstant. In the second case, the values correspond to :doc:`clip properties <syntax_clip_properties>` or\n:doc:`script variables <syntax_script_variables>` (which must have been previously initialized). In the\nthird case, the value is the return value of an AVS function (see below). The\nfourth case is an alternate syntax (called \"OOP notation\") which is\nequivalent to *Function*(*expression*, *args*).\n\n:doc:`Script arrays <../script_ref/script_ref_arrays>` were natively introduced in Avisynth+.\n\nThe 5th and 6th cases show that one can manipulate expressions using all of the\nusual arithmetic and logical :doc:`operators <syntax_operators>` (from C) as you'd expect on ints,\nfloats and bools, as well as execute code conditionally with the ternary\noperator. Strings can be compared with relational operators and concatenated\nwith '+'. The following operators are also defined on video clips: **a + b**\nis equivalent to :doc:`UnalignedSplice <../corefilters/splice>` (*a*, *b*), and **a ++ b** is equivalent\nto :doc:`AlignedSplice <../corefilters/splice>` (*a*, *b*).\n\nThe 7th and 8th is using :doc:`Function objects <syntax_function_objects>`. they were introduced in Avisynth+ 3.6.0.\n\nThe functions in AviSynth's scripting language are, by and large, video\nfilters. Although a function can return any type it chooses (this is a useful\nfeature for creating utility code to reuse in scripts; you can define your\nown :doc:`script functions <syntax_userdefined_scriptfunctions>`) functions which do **not** return a **clip** are\nalways limited to intermediate processing of variables to pass as arguments\nto filters (functions that *do* return a clip). The script should always\nreturn a clip as its final value. After all, AviSynth is a video processing\napplication.\n\nFunctions can take up to sixty arguments (hope that's enough), and the return\nvalue can be of any type supported by the scripting language (clip, int,\nfloat, bool, string, array, function object). Functions always produce a new value and never modify\nan existing one. What that means is that all arguments to a function are\npassed \"by value\" and not \"by reference\"; in order to alter a variable's\nvalue in AviSynth script language you must assign to it a new value.\n\nTo see the syntax of the function call for each built-in filter, view the\n:doc:`internal filters: <../corefilters>`. There are also built-in :doc:`internal functions <syntax_internal_functions>` that\nperform common operations on non-clip variables.\n\n*Args* is a list of function arguments separated by commas. The list can be\nempty. Each argument must be an expression whose type (eg text string,\ninteger, floating-point number, boolean value or video clip) matches the one\nexpected by the function. If the function expects a video clip as its first\nargument, and that argument is not supplied, then the clip in the special\nvariable *last* will be used.\n\nAviSynth functions can take named arguments. The named arguments can be\nspecified in any order, and the filter will choose default values for any\nthat you leave off. This makes certain filters much easier to use. For\nexample, you can now write\n\n**Subtitle(\"Hello, World!\", text_color=$00FF00, x=100, y=200)**\n\ninstead of\n\n**Subtitle(\"Hello, World!\", 100, 200, 0, 999999, \"Arial\", 24, $00FF00)**\n\n:doc:`Colors <syntax_colors>` can be specified in hexadecimal as\nin the example above or in decimal. In both cases it should be specified as\nRGB value, even if the clip itself is YUV.\n\nIf no arguments are being passed to the function, you can also make the\nfunction call without parentheses, e.g. **FilterName**. The primary reason\nfor this is to retain compatibility with old scripts. However, it's sometimes\nconvenient to leave off the parentheses when there's no possibility of\nconfusion.\n\nAvisynth ignores anything from a # character to the end of that line. This\ncan be used to add **comments** to a script.\n\n::\n\n    # comment\n\nIn v2.58 it is possible to add **block** and **nested block** comments in the\nfollowing way:\n\n::\n\n    # block comment:\n    /*\n    comment 1\n    comment 2\n    */ ::# nested block comments:\n    [* [* a meaningful example will follow later :) *] *]\n\nAvisynth ignores anything from an __END__ keyword (with double underscores)\nto the end of the script file. This can be used to disable some last commands\nof script.\n\n::\n\n    Version()\n    __END__\n    ReduceBy2()\n    Result is not reduced and we can write any text here\n\nAvisynth **ignores case**: aViSouRCe is just as good as AVISource.\n\nMultiple Avisynth statements on a single line can only be achieved in the\ncontext of OOP notation or embedding filters as parameters of another\nfunction such as:\n\n::\n\n    AviSource(\"c:\\video.avi\").Trim(0, 499)\n    -or-\n    AudioDub(AviSource(\"c:\\video.avi\"), WavSource(\"c:\\audio.wav\"))\n\nAvisynth statements can be split across multiple lines by placing a backslash\n(\"\\\") either as the last non-space character of the line being extended, or\nas the first non-space character on the next line.\n\nLine splitting examples (both valid and equal):\n\n::\n\n    Subtitle(\"Hello, World!\", 100, 200, 0, \\\n      999999, \"Arial\", 24, $00FF00)\n\n-or-\n\n::\n\n    Subtitle(\"Hello, World!\", 100, 200, 0,\n      \\ 999999, \"Arial\", 24, $00FF00)\n\nWhen splitting across multiple lines you may *place comments only at the end\nof the last line*. Mixing comments with backslashes at an intermediate line\nof the line-split will either produce an error message or result at hard to\ntrace bugs.\n\nExample of a not-signaled bug by improper mixing of comments and line\nseparation:\n\n::\n\n    ColorBars\n    ShowFrameNumber\n    Trim(0,9) # select some frames  \\\n      + Trim(20,29)\n\nThe above example does not return frames [0..9,20..29] as intended because\nthe \"\\\" is masked by the \"#\" character before it; thus the line continuation\nnever happens.\n\n$Date: 2024/01/09 10:00:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_runtime_environment.rst",
    "content": "\nAviSynth Runtime environment\n============================\n\n\n.. toctree::\n    :maxdepth: 3\n\n.. contents:: Table of contents\n\n\n\nDefinition\n----------\n\nThe runtime environment is an extension to the normal AviSynth script\nexecution environment that is available to scripts executed by\n:ref:`runtime filters <Runtime filters>`. Its basic characteristic is\nthat the runtime filters' scripts are evaluated (compiled) **at every frame**.\nThis allows for complex video processing that it would be difficult or\nimpossible to perform in a normal AviSynth script.\n\nLet's now look at the above definition in more detail. The runtime\nenvironment is:\n\n1.  An environment, that is a set of available local and global variables\n    and filters / functions to be used by the script.\n2.  An extension to the normal AviSynth script execution environment;\n    that is there are additional variables and functions available to runtime\n    scripts.\n3.  Available to scripts executed by runtime filters **only**, that is\n    scripts inside it are executed only during the AviSynth \"runtime\" (the\n    frame serving phase).\n\nThe last is the biggest difference. Normal script code is parsed and\nevaluated (compiled) at the start of the script's :doc:`execution <../script_ref/script_ref_execution_model_sequence_events>` (the parsing\nphase) in a linear fashion, from top to bottom; the result is the creation of\na :doc:`filter graph <../script_ref/script_ref_execution_model_filter_graph>` that is used by AviSynth to serve frames to the host video\napplication. Runtime script code is executed *after* the parsing phase, when\nframes are served. Moreover it is compiled on every frame requested and only\nfor that specific frame, in an event-driven fashion.\n\n**Note:** Audio is *not* handled by the runtime environment; it is passed\nthrough untouched. This also means that you cannot modify clip audio with\nruntime filters.\n\n\n.. _Runtime filters:\n\nRuntime filters\n---------------\n\nThe following :doc:`filters: <../corefilters>` are the basic set of the so-called \"runtime\nfilters\":\n\n-   :doc:`ConditionalFilter <../corefilters/conditionalfilter>`: Selects, on every frame, from one of two\n    (provided) filters based on the evaluation of a conditional expression.\n-   :doc:`ScriptClip <../corefilters/conditionalfilter>`: Compiles arbitrary script code on every frame and\n    returns a clip.\n-   :doc:`FrameEvaluate <../corefilters/conditionalfilter>`: Compiles arbitrary script code on every frame but\n    the filter's output is ignored.\n-   :doc:`ConditionalReader <../corefilters/conditionalreader>`: Loads input from an external file to a\n    selectable :doc:`variable <syntax_script_variables>` on every frame.\n\nIn addition, the :doc:`WriteFile <../corefilters/write>` filter can also be considered a runtime filter,\nbecause it sets the special variables set by all runtime filters before\nevaluating the expressions passed to it, which can use the special :doc:`runtime functions <syntax_internal_functions_runtime>`.\n\n\n.. _Special runtime variables and functions:\n\nSpecial runtime variables and functions\n---------------------------------------\n\nAll runtime filters set and make available to runtime scripts the following\nspecial variables.\n\n-   last: The clip passed as argument to the filter\n-   current_frame: The frame number (ranging from zero to input clip's\n    :doc:`Framecount <syntax_clip_properties>` minus one) of the requested frame.\n\nAll the above variables are defined at the :doc:`top-level script local scope <../script_ref/script_ref_execution_model_lifetime_variables>`.\nThat is you read and write to them in a runtime script as if they where\nvariables that you declare at the script level.\n\nRuntime scripts can also call a rich set of :doc:`special functions <syntax_internal_functions_runtime>` that provide\nvarious pieces of information for the current frame of their input clip.\n\n\nHow to script inside the runtime environment\n--------------------------------------------\n\nUsing the runtime environment is simple: you use one of the :ref:`runtime\nfilters <Runtime filters>` and supply it with the needed arguments. Among them, two are the\nmost important:\n\n-   The input clip\n-   The runtime script\n\nThe latter is supplied as a string argument which contains the AviSynth\nscript commands. Scripts can contain many statements (you can use a multiline\nstring), local and global variables and function calls, as well as special\n:doc:`runtime functions <syntax_internal_functions_runtime>` and :ref:`variables <Special runtime variables and functions>`. In general all statements of the\nAviSynth :doc:`syntax <syntax>` are permitted, but attention must be paid to avoid overly\ncomplex scripts because this has a penalty on speed that is paid at **every\nframe**. See the runtime section of :doc:`scripting reference's <../script_ref/script_ref>`\n:doc:`performance considerations <../script_ref/script_ref_execution_model_perf_cons>` for details.\n\nLet's see a few examples:\n\n::\n\n    TODO...EXAMPLES\n\n--------\n\nOther points:\n\n-   :doc:`Runtime functions <syntax_internal_functions_runtime>` and variables, such as current_frame,\n    AverageLuma(), etc., are available only at the runtime script's scope. To\n    use them in a function you must pass them as arguments.\n-   You can include an explicit ``return`` statement in your runtime\n    script to return a clip that is not contained in the special ``last``\n    variable.\n\n--------\n\nBack to :doc:`AviSynth Syntax <syntax>`.\n\n$Date: 2008/12/07 15:46:17 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_script_variables.rst",
    "content": "\nAviSynth Syntax - Script variables\n==================================\n\nThis page shows how to use *variables* to store intermediate values for\nfurther processing in a script. It also describes the types of data that\nscripts can manipulate, and how *literals* (constants) of those types are\nwritten.\n\nA *variable name* can be a character string of practically any length (more\nthan 4000 characters in Avisynth 2.56 and later) that contains (English)\nletters, digits, and underscores (_), but no other characters. The name\ncannot start with a digit.\n\nYou may use characters from your language system codepage (locale) in strings\nand file names (ANSI 8 bit, utf8, but not a 16 bit Unicode).\n\nA variable's placement in an *expression* is determined by the\n:doc:`AviSynth Syntax <syntax_ref>`.\n\nVariables can have a value of one of the following *types*:\n\n-   clip\n\nA video clip containing video and / or audio. A script must return a value of\nthis type.\n\n-   string\n\nA sequence of characters representing text. String literals are written as\ntext surrounded either by \"quotation marks\" or by \"\"\"three quotes\"\"\". The\ntext can contain any characters except the terminating quotation mark or\ntriple-quote sequence. If you need to put a quotation mark inside a string, \nyou need to use `Python-style`_ \"\"\"three quotes\"\"\". For example:\n::\n\n    Subtitle(\"\"\"AVISynth is as they say \"l33t\".\"\"\")\n\nAlternatively, you can use Windows extended-ASCII curly-quotes\ninside the string instead of straight quotes to get around this limitation.\n\nSince Avisynth+ 3.6 string containing escaped characters are available.\n\nIn a string literal, an escape character is a special character that starts \nwith a backslash (\\) and is followed by another character or a sequence of \ncharacters. The escape character modifies the meaning of the following character \nor sequence, and allows you to represent characters that are not normally \nprintable or that have special functions.\n\nConverted escape sequences:\n\n-   ``\\n`` to LF-Chr(10)\n-   ``\\r`` to CR-Chr(13)\n-   ``\\t`` to TAB-Chr(9)\n-   ``\\0`` to NUL-Chr(0) (NUL is string terminator, use at your own risk)\n-   ``\\a`` to Chr(7)-audible beep\n-   ``\\f`` to FF-Chr(12) - Form feed\n-   ``\\\\`` (double \\) to Backslash\n-   ``\\\"`` to \" (double-quotation mark)\n-   ``\\'`` to ' (single-quotation mark) (since 3.7.1)\n-   ``\\b`` to BS-CHR(8) - backspace (since 3.7.1)\n-   ``\\v`` to VT-CHR(11) - vertical tab (since 3.7.1)\n\n::\n\n    e\"Hello \\n\" will store actual LF (0x0A, 10) control character into the string\n\n-   int\n-   long\n\nInteger is signed 32-bit. Long is signed 64-bit. In general when 'integer' is \nmentioned, it can be any (32 or 64-bit) integers.\n64-bit is available since Avisynth version 3.7.4 (3.8?).\nAn integer literal is entered as a sequence of digits, optionally with a + or - \nat the beginning.\n\nThe value can be given in *hexadecimal* by preceding them with a \"$\" character. \nFor example ``$FF`` as well as ``$ff`` (case does not matter) are equal to 255.\nUnlike decimal constants, hexadecimal constants are 32 bit by default.\nSuffixed by \"L\" or \"l\" makes it 64-bit long.\n\n\n-   float\n-   double\n\nFloat is a single-precision, double is a 64-bit `floating-point`_ number. \nLiterals are entered as a sequence of digits with a decimal point (.) somewhere \nin it and an optional + or -. For example, +1. is treated as a floating-point number. Note that\nexponent-style notation is **not** supported.\n\n-   bool\n\nBoolean values must be either *true* or *false*. In addition they can be\nwritten as ''yes'' or ''no'', but you should avoid using these in your\nscripts (they remain for compatibility purposes only).\n\n-   array\n\nArray values are supported at script level in Avisynth+.\nSee also at :doc:`script array concept and helper functions <../script_ref/script_ref_arrays>` .\n\n-   function\n\nFunction objects are supported in Avisynth+.\nSee also at :doc:`Function objects <syntax_function_objects>` .\n\n-   val\n\nA generic type name. It is applicable only inside a\n:doc:`user defined script functions <syntax_userdefined_scriptfunctions>` argument list,\nin order to be able to declare an argument variable to be of *any* type (int, float, bool, string, or clip). You must\nthen explicitly test for its type (using the :doc:`boolean functions <syntax_internal_functions_boolean>`) and take\nappropriate actions.\n\nThere is another type which is used internally by Avisynth - the void or\n'undefined' type. Its principal use is in conjunction with optional function\narguments. See the :doc:`Defined() <syntax_internal_functions_boolean>` function.\n\nVariables can be either local (bound to the local scope of the executing\nscript block) or global. Global variables are bound to the global script\nenvironment's scope and can be accessed by all :doc:`Internal functions <syntax_internal_functions>`,\n:doc:`User defined script functions <syntax_userdefined_scriptfunctions>`, :doc:`runtime environment <syntax_runtime_environment>` scripts and the main\nscript also.\n\nTo define and / or assign a value to a global variable you must precede its\nname with the keyword ``global`` at the left side of the assignment. The\nkeyword is not needed (actually it is not allowed) in order to read the value\nof a global variable. Examples:\n\n::\n\n    global canvas = BlankClip(length=200, pixel_type=\"yv12\")\n    global stroke_intensity = 0.7\n    ...\n    global canvas = Overlay(canvas, pen, opacity=stroke_intensity, mask=brush)\n\nTo declare a variable, simply type the variable name, followed by '=' (an\nequals sign), followed by its initial value. The type must not be declared;\nit is inferred by the value assigned to it (and can actually be changed by\nsubsequent assignments). The only place where it is allowed (though not\nstrictly required) to declare a variable's type is in\n:doc:`user defined script functions <syntax_userdefined_scriptfunctions>` argument lists. Examples:\n\n::\n\n    b = false      # this declares a variable named 'b' of type 'bool' and initializes it to 'false'\n    x = $100       # type int (initial value is in hexadecimal)\n    y = 256        # type int (initial value is in decimal)\n    global f = 0.0 # type float declared globally\n    ...\n    function my_recolor_filter(clip c, int new_color, float amount, val\n    \"userdata\") { ... }\n\nThen since Avisynth+ 3.6.0 exists UseVar. UseVar is special filter, opens a clean variable environment in which only the\nvariables in the parameter list can be seen.\n\nChangelog\n~~~~~~~~~\n+----------------+------------------------------------------------------------+\n| Version        | Changes                                                    |\n+================+============================================================+\n| Avisynth 3.7.4 | Added 64-bit decimals                                      |\n|                | Added 64-bit floating point                                |\n|                | Added \"L\" suffixed hexadecimal notation                    |\n+----------------+------------------------------------------------------------+\n| Avisynth 3.6.0 | Added \"Usevar\"                                             |\n|                | Added types: function objects and array                    |\n|                | escaped string literal syntax                              |\n+----------------+------------------------------------------------------------+\n\n\n$Date: 2025/02/05 11:11:11 $\n\n.. _Python-style: http://forum.doom9.org/showthread.php?s=&threadid=71597\n.. _floating-point: http://en.wikipedia.org/wiki/Floating_point\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_sections.rst",
    "content": "\nAviSynth Syntax\n===============\n\n-   :doc:`The full Avisynth Syntax <syntax_the_full_grammar>` - The official reference documentation.\n-   :doc:`AviSynth Syntax <syntax_ref>` - The (old) official reference documentation.\n-   :doc:`Plugins <syntax_plugins>` - How to load plugins (AviSynth, VirtualDub, VFAPI and\n    C-plugins), autoloading and name-precedence.\n-   :doc:`Script variables <syntax_script_variables>` - How to declare and use them in scripts.\n-   :doc:`Operators <syntax_operators>` - Available operators and relative precedence.\n-   :doc:`User defined script functions <syntax_userdefined_scriptfunctions>` - How to define and use them in\n    scripts.\n-   :doc:`Control structures <syntax_control_structures>` - Language constructs for script flow\n    control.\n-   :doc:`Internal functions <syntax_internal_functions>` - Ready-made non-clip functions to use in scripts,\n    helper functions for multithreading, cache and frame property reference\n-   :doc:`Clip properties <syntax_clip_properties>` - Functions that return a property of a clip.\n-   :doc:`Runtime environment <syntax_runtime_environment>` - Scripting on a per clip frame basis.\n-   :doc:`Scripting reference <../script_ref/script_ref>` - Beyond scripting basics.\n-   :doc:`The script execution model <../script_ref/script_ref_execution_model>` - The steps behind the scenes from\n    the script to the final video clip output. The filter graph. Scope and\n    lifetime of variables. Evaluation of runtime scripts.\n-   :doc:`User functions <../script_ref/script_ref_user_functions>` - How to effectively write and invoke user\n    defined script functions; common pitfalls to avoid; ways to organise your\n    function collection and create libraries of functions, and many more.\n-   :doc:`Block statements <../script_ref/script_ref_block_statements>` - Techniques and coding idioms for creating\n    blocks of AviSynth script statements.\n-   :doc:`Arrays <../script_ref/script_ref_arrays>` - Using arrays (and array operators) for manipulating\n    collections of data in a single step.\n-   :doc:`Scripting at runtime <syntax_runtime_environment>` - How to unravel the power of runtime\n    filters and create complex runtime scripts that can perform interesting\n    (and memory/speed efficient) editing/processing operations and effects.\n\nBack to :doc:`Overview <../overview>`.\n\n$Date: 2024/01/07 08:39:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_the_full_grammar.rst",
    "content": "\nThe full AviSynth grammar\n=========================\n\nA new, revised version of syntax, syntax_ref, backported from \n`Avisynth.nl: The full Avisynth grammar <http://avisynth.nl/index.php/The_full_AviSynth_grammar>`_\n\nIntroduction\n~~~~~~~~~~~~\n\nFrom the perspective of the AviSynth interpreter each script is a series of tokens. The general \nterm token corresponds to the basic building element of a script (if we imagine a script as a wall, \nthen the tokens are the bricks). The AviSynth grammar is the set of rules (the recipe) for \nidentifying and grouping tokens into higher-level structures.\n\nWe present those rules in the following sections, in a bottom-up fashion (from low-level to \nhigher-level constructs). However, for a reader with a basic understanding of programming that \nwants a quick tour of the language another road is possible: start directly with the \nExpressions and Statements section and visit previous sections if a clarification is needed.\n\nCase\n~~~~\n\nThe very first and maybe most important one rule of the AviSynth grammar is case. AviSynth ignores case:\n::\n\n    aViSouRCe \n\nis just as good as\n::\n\n    AVISource\n\nFor the AviSynth Grammar both entries correspond to the same token. Thus, you should always have \nin mind that capitalisation does not matter when defining your variables and functions; you must \nalways ensure that they are unique in a case-insensitive manner.\n\nWhitespace, Line Continuation and Comments\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe first layer of grammar rules concerns the identification of tokens out of the overall script \ntext. Text that does not belong to a token is commonly referred to as whitespace in most \nprogramming and scripting languages.\n\nWhitespace\n----------\n\nWhitespace in AviSynth language consists of:\n\n-   Space, tab and newline characters (except inside string literals).\n-   The backslash (\\) character when it is the first or last non-whitespace character in a line (and not inside a string literal).\n-   Comments.\n-   Anything from the appearance of the __END__ special keyword up to the end of the script file. \n\nBackslash\n---------\n\nThe backslash character serves the role of line continuation. It is used to split a large line \nof code in multiple ones for better readability of the script when editing, yet serve it to the \nAviSynth interpreter as a single logical line of code. Line splitting examples (both valid and equal):\n::\n\n    Subtitle(\"Hello, World!\", 100, 200, 0, \\\n      999999, \"Arial\", 24, $00FF00)\n\n-or-\n::\n\n    Subtitle(\"Hello, World!\", 100, 200, 0,\n      \\ 999999, \"Arial\", 24, $00FF00)\n\nComments\n--------\n\nComments serve the purpose of code documentation. They come in the following flavors:\n\n-   Standard comments: They start with a pound (#) character and extend to the end of the line. \n-   Block comments (AviSynth v2.58 and later): They start either with /* or [* and extend until \n    a (closing) */ or *], respectively, is found downstream the script text. They can span \n    multiple lines and the [* form also supports nested block comments. \n\nExamples of comments:\n::\n\n    AviSource(\"myclip.avi\")    # this is a standard comment\n\n::\n\n    /* this is a block comment \n    we can write a lot here\n    SubTitle(\"Hello, World!\")\n    and also comment out multiple lines of code\n    */\n\n::\n\n    [* this is a nested block comment\n    [* \n    a meaningful example will follow later :)\n    *]\n    for the time being just experiment *]\n\nThe comments mechanism has higher precedence than the backslash. If you comment out a line that \nends with \\, line continuation will not happen. A quick example from real life (someone did \nsubmitted a bug report for this):\n::\n\n    ColorBars\n    ShowFrameNumber\n    Trim(0,9) # select some frames  \\\n      + Trim(20,29)\n\nThe above example does not return frames [0..9,20..29] as the user intended because the \"\\\" is masked \nby the comment start \"#\" character before it; thus the line continuation never happens. \nThe comment should go at the last line.\n\nThe __END__ special keyword\n---------------------------\n\nThe ``__END__`` special keyword can be used to quickly disable some last commands of the script.\n\nExample:\n::\n\n    Version()\n    __END__\n    ReduceBy2()\n    Result is not reduced and we can write any text here\n\nKeywords, Identifiers, Literals and Punctuation\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe second layer of grammar rules - once whitespace has been handled and tokens have been \nidentified - concerns the categorisation of tokens (that is, finding the type of the tokens). \nTokens generally belong to one of the following categories:\n\n-   *Keywords*: Tokens with specific, standard meaning for the AviSynth language (ie reserved words).\n-   *Identifiers*: Tokens that identify an entity (a variable, a function, etc.).\n-   *Literals*: Tokens that represent a value (ie a constant quantity).\n-   *Punctuation*: This generic term comprises all tokens with specific, standard meaning \n    for the AviSynth language that are too short to be considered keywords. They include: \n\n    -   :doc:`Operators <syntax_operators>`.\n    -   Grouping and ordering tokens. \n\nKeywords\n--------\n\nThe following are AviSynth language's keywords. We use here an all lowercase notation,\n but bear in mind that since AviSynth ignores case, any equivalent combination of \n uppercase / lowercase letters counts as a keyword (for example: try, Try, tRy, trY, TRy, TrY, tRY, TRY):\n\n-   function : Begins the declaration of a :doc:`user-defined script function <syntax_userdefined_scriptfunctions>` .\n-   global : Modifies a variable, such that it has global scope.\n-   return : Returns (the result of the expression on the right) from the enclosing\n    'script block' - usually a function or the main script, but may also be a try or \n    catch block, an Eval string or an Import file.\n-   try : Starts the try part of a try..catch block. See :doc:`Control structures <syntax_control_structures>` for details.\n-   catch : Starts the catch part of a try..catch block. See :doc:`Control structures <syntax_control_structures>` for details. \n\nThe following keyword is a special identifier (ie variable):\n\n-   *last* : The special last variable available on any scope for implicit \n     assignment (see below in Expressions and Statements for details). \n\nThe following keywords are special literals (ie constants):\n\n-   *true* : Boolean constant denoting a positive truth value (a true statement).\n-   *false* : Boolean constant denoting a negative truth value (a false statement).\n-   *yes* : Same as true.\n-   *no* : Same as false. \n\nThe following keywords are used only inside arguments lists of function declarations \nto declare the type of arguments:\n\n-   *clip* : The function argument following the keyword is a video clip.\n-   *int* : The function argument following the keyword is an integer.\n-   *float* : The function argument following the keyword is a floating point number.\n-   *string* : The function argument following the keyword is a character string.\n-   *bool* : The function argument following the keyword is a boolean (true/false) variable.\n-   *func* : The function argument following the keyword is a function object variable. (Avisynth+)\n-   *array* : The function argument following the keyword is an :doc:`array <../script_ref/script_ref_arrays>` variable. (Avisynth+)\n-   *val* : The function argument following the keyword can be of any type (ie any of the above types). \n\nIdentifiers\n-----------\n\nIdentifiers, as the term suggests, are specific and unique names that you use in your \nscript to refer to distinct entities. In AviSynth language identifiers are used to \nname the following types of entities:\n\n-   :doc:`Variables <syntax_script_variables>` : A variable is a symbolic placeholder for a value\n    that can be read and changed (as a result of an assignment) many times during script execution.\n-   Functions : A function is a piece of code that performs a specific computation and \n    returns its result to the caller. \n\nThus, whenever you need in your script to refer to a variable or function, either built-in\n or user-defined you have to use an identifier. Bear in mind that since AviSynth ignores case, \n your identifiers should be unique in a case-insensitive manner.\n\nFor example, the following is probably an error:\n::\n\n    MyClip = AviSource(\"clip1.avi\")\n    myclip = AviSource(\"clip2.avi\")    # oops! these two lines assign to the *same* variable\n\nwhile this is correct:\n::\n\n    MyClip = AviSource(\"clip1.avi\")\n    YourClip = AviSource(\"clip2.avi\")\n\nLiterals\n--------\n\nLiterals are all the constant (ie specific) values that you use in your scripts. For instance, \nall the tokens that appear at the right side of the assignment operator (the \"=\" character) \nin the examples below are literals:\n\n::\n\n    a_num = 123\n    another_num = 2.456\n    \n    a_string = \"this is a string literal\"\n    \n    another_string = \"\"\"this is a multiline\n           string literal. Note that the 2nd line has leading spaces (which are included)\n    while this line has not. Also newlines are included in this type\n           of strings\"\"\"\n    \n    a_boolean = true\n\nsince Avisynth+ 3.6: \n::\n\n    escaped_string = e\"Hello \\n\"\n      with e prefix right before the quotation mark will store actual control character into the string\n      Converted literals:\n        \\n to LF-Chr(10)\n        \\r to CR-Chr(13)\n        \\t to TAB-Chr(9)\n        \\0 to NUL-Chr(0) (NUL is string terminator, use at your own risk)\n        \\a to Chr(7)-audible beep\n        \\f to FF-Chr(12) - Form feed\n        \\\\ (double \\) to Backslash\n        \\\" to \" (double-quotation mark)\n        \\' to ' (single-quotation mark) (since 3.7.1)\n        \\b to BS-CHR(8) - backspace (since 3.7.1)\n        \\v to VT-CHR(11) - vertical tab (since 3.7.1)\n\nAs you can see, literals can be of any type (except clips; currently AviSynth does not have clip-type literals).\n The thing that differentiates them from identifiers is that they are not names that hold a value but bare values.\n\nPunctuation\n-----------\n\nAs said before, this generic term comprises all tokens with specific, standard meaning for the AviSynth \nlanguage that are too short to be considered keywords. The tokens that are bundled under this catch-all category are:\n\n-   operators: Operators apply an operation to one or more entities (and allow to retrieve the result of \n    the operation); this is the reason that they are named that way. \n\n    In essence operators are mini-functions that are defined in the script grammar with a more \n    user-friendly syntax (for instance, instead of calling ``Add(a, b)`` it is easier to write ``a + b``). \n    Due to their significance in the AviSynth language operators are documented in a :doc:`separate page <syntax_operators>` . \n    They are just listed here for completeness:\n\n    -   Assignment: =\n    -   Sign and common math operations: + , - , * , / , % , ++ (the last is for clips only)\n    -   Comparisons: ==, != , <> , < , > , <= , >=\n    -   Boolean operations: ! , && , ||\n    -   Ternary operation (if...else): ?: \n\n-   Grouping / ordering tokens. These include: \n\n    -   The comma character [,]: For separating arguments in function argument lists only.\n    -   The dot character [.]: When successive calls to functions are chained together with \n        the use of the OOP notation.\n    -   The parenthesis, opening and closing [()]: For grouping expressions into a single unit. \n        Also for grouping arguments of a function declaration or call.\n    -   The (curly) brackets [{}]: For grouping multiple statements in a single block of code\n        (currently: function bodies and ``try...catch`` blocks only). \n\nExpressions and Statements\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe third layer of grammar rules - after whitespace has been handled and tokens have been identified \nand distributed to the available categories (keywords, identifiers, etc.) - concerns the grouping of \ntokens in higher-level structures of the grammar: expressions and statements. A little terminology \nis necessary at this point to clarify the difference between them.\n\n-   Expressions are groupings of tokens that perform a computation and return a value. They form a \n    distinct part of either a larger enclosing expression or a statement.\n-   Statements are the smallest standalone element of an AviSynth script; in other words a statement \n    is a single unit of script code (in the case of AviSynth language, this is typically a line of script code). \n\nHaving made this distinction, lets see each one in more detail at the sections that follow.\n\nExpressions\n-----------\n\nExpressions are the first step in the creation of the higher-level grammar constructs. \nThey combine tokens in order to compute a new value from old ones and deliver this new value \nto either a surrounding expression or directly to an even higher-level construct, ie a statement.\n\nA few examples will help to fully understand the concepts presented above:\n::\n\n    # 10 is a literal; \n    # it is also an expression; a grouping can have just 1 element\n    a = 10\n    \n    # a + 7 is an expression; so is (a + 7) / 5\n    b = (a + 7) / 5\n    \n    # b > 0, 12, 25 are expressions (see 1st line); \n    # [b > 0 ? 12 : 25] is also an expression\n    c = b > 0 ? 12 : 25\n    \n    # BlankClip(...) below is an expression; \n    # so is Trim(...)\n    Trim(BlankClip(width=b, height=c, pixel_type=\"RGB32\"), 0, a)\n    \n    # all the above lines of code are statements\n    \nMost of the time the result of an expression will be a video clip; however an expression's result \ncan be of any type supported by the scripting language (clip, int, float, bool, string) and this \nis how utility functions such as internal script functions operate.\n\nCombining all information presented above, we can now see that an AviSynth expression typically has \none of these forms (with square brackets, ([]), we enclose optional elements, with the vertical bar \ncharacter, (|), we separate alternatives, with the pound character, (#), we enclose comments):\n\n-    Literal, ie: \n\n    ::\n\n        numeric_constant\n        | string_constant\n        | bool_constant\n\nThe value of the expression is the value of the constant.\n\n-   Identifier, ie: \n\n    ::\n\n        variable_name \n        | clip_property\n        | function_name                                  # without (args) #\n\nThe value of the expression is the value returned by clip properties or contained inside script \nvariables (which must have been previously initialized).\n\n-   Expression, ie: \n\n    ::\n\n        [ + | - | ! ] expression                         # unary operator expression #\n        | ( expression )                                 # expression inside parentheses #\n        | expression-1 operator expression-2             # binary operator expression #\n        | bool_expression ? expression-1 : expression-2  # the ternary operator #\n        | function_name[ ( args ) ]                      # function call #\n        | expression.function_name[ ( args ) ]           # OOP notation #\n\nThe value of the expression is either the result of the computation of the sub-expressions or \nthe return value of the function_name call.\n\nLooking a bit closer at the possible expression alternatives, the following notes can be made:\n\n-   The first three cases show that one can manipulate expressions using all of the usual \n    arithmetic and logical operators (from C) as you'd expect on ints, floats, vals, and bools. \n\n    -   Strings can be concatenated with '+'.\n    -   The following operators are also defined on video clips: \n\n    ::\n\n        a + b   \n        # is equivalent to:\n        UnalignedSplice(a, b) \n\n    and: \n    ::\n\n        a ++ b\n        # is equivalent to:\n        AlignedSplice(a, b)\n\n-   The fourth case shows that one can execute code conditionally with the ternary operator.\n-   The fifth case shows that a function call is, from the grammar's perspective, a special type of expression.\n-   The sixth case shows OOP notation, an alternate syntax for chaining function calls, which is equivalent to: \n    ::\n\n        function_name(expression, args)\n\nStatements\n----------\n\nStatements are the smallest standalone element of an AviSynth script/ Statements do not compute a value; \nthey are evaluated for their side effects (which are most of the time the assignment of a value \ncomputed by an expression to a :doc:`variable <syntax_script_variables>`).\n\nStatements are grouped together to form a script. An AviSynth script is simply the aggregate of a number of statements.\n\nAll statements in AviSynth scripting language have one of these forms (with square brackets, ([]), \nwe enclose optional elements, with the vertical bar character, (|), we separate alternatives, \nwith the pound character, (#), we enclose comments):\n\n::\n\n    [ global ] variable_identifier = expression\n    | [ return ] expression\n    | try_catch_block\n    | function_declaration\n\nFor each specific type of statement, the following notes can be made:\n\n-   In the first case, *expression* is evaluated and the result is assigned to an identifier.\n    The identifier can only identify a variable, either local or global (if the optional global \n    keyword is present). That is you can only assign to variables. Hence the name *variable_identifier*. \n\n-   In the second case, *expression* is evaluated and the result is used as follows: \n\n    -   If the return keyword is present or the statement is the last in its script block, it is used \n        as the \"return value\" of the active script block - that is, either a function or the entire \n        script. In the latter case, the return value is typically the video clip that will be seen by \n        the application which opens the AVS file.\n    -   Otherwise, if the result is a clip, it is assigned to the special variable ``last``. If the result \n        is not a clip, it is simply discarded. \n\nThe last two cases are the only compound statements supported by AviSynth script language.\nThey are presented in detail in the section that follows.\n\nCompound Statements\n-------------------\n\nA compound statement is a block of statements that is considered a single unit of code (ie statement). \nThus a compound statement is a multiline statement. As we saw, AviSynth supports two types of compound \nstatements: the *try_catch_block* and *function_declaration*.\n\n-   The *try_catch_block* statement has the following form: \n    ::\n\n        try {                         # the try part is always executed #\n          [ statement                 # you can put as many statements as you want #\n            ...\n            statement ]               # an empty block is allowed (but not very useful!) #\n        }\n        catch (variable_identifier) { # catch part is executed only if an error occurs in try part #\n          [ statement                 # you can put as many statements as you want #\n            ... \n            statement ]               # an empty block is allowed and causes the error to be ignored #\n        }\n\n    It implements the try..catch :doc:`control structure <syntax_control_structures>`.\n    See there for details. \n\n-   The *function_declaration* statement has the following form: \n    ::\n\n        function identifier( [ argument_list ] )\n        /* from v2.60 you can also put comments here */\n        {\n          [ statement                 # you can put as many statements as you want #\n            ...\n            statement ]               # an empty function is allowed (but not very useful!) #\n        }\n\n    It declares a user-defined function and makes it available for calling to the rest of script code, \n    by using the identifier as the name of the function to be called. \n\n    The optional argument_list (yes, you can have functions without arguments) declares the type \n    and name of function's arguments, as well as whether they are required or are optional. \n    Optional arguments are also called named arguments, because you can supply them by name \n    in a function call. It has the following form: \n\n    ::\n\n        argument-1 , ... , argument-K , optional_argument-K+1 , ... , optional_argument-N\n\n        ``argument-i`` (i = 1 to K) and ``optional_argument-j`` (j = K + 1 to N) have the following \n        forms (again, with square brackets, ([]), we enclose optional elements, with the vertical bar \n        character, (|), we separate alternatives, with the pound character, (#), \n        we enclose comments), respectively: \n\n    ::\n\n        [ type_keyword ] identifier     # (normal) argument\n        [ type_keyword ] \"identifier\"   # optional argument    \n\n    As you can see, *optional arguments* distinguish from (normal) arguments in that they *are enclosed \n    in double quotation marks*. In a function call you can refer to an optional argument as: \n    ``identifier = value``. You can also refer to in the normal way as if it was a normal, positional argument.\n\nThree more things to note are the following:\n\n-   Once you declare an optional argument, all subsequent arguments must also be declared optional.\n-   If you don't supply the type of the argument in the declaration (ie one of the type keywords \n    presented above), the argument is of the val type. That is it can be of any type. Consequently \n    in the body of the function you have to query for its type, if you want your code to be robust.\n-   Function declarations can be written in any order and at any point in the script where a statement \n    is allowed, independently of where the functions themselves are called. The presence of the \n    declaration itself does not interfere with the order of script execution or its result. \n    However, the usual convention is to group functions together at the start of the script. \n\nA few examples will help to clarify things:\n::\n\n    function MyFunc1() {                 # a function with no arguments\n        ...\n    }\n\n::\n\n    function MyFunc2(clip c, int n) {    # a function with two (normal) arguments\n        ...\n    }\n\n::\n\n    function MyFunc3(clip c, string \"text\", bool \"invert\") {\n        ...                              # a function with one argument and two optional arguments\n    }                                    # if they are not supplied, it uses some default values\n\n::\n\n    function MyFunc4(clip \"c\", bool \"invert, int \"n\") {\n        ...                              # you can declare a function with all arguments optional\n    }\n\n::\n\n    function MyFunc5(clip clp, effect, \"text\") {\n        ...                              # a function with two normal and one optional argument\n    }                                    # the last two arguments are of val (ie any) type\n    ...\n    f = MyFunc1()\n    g = MyFunc2(ColorBars(), 6)      # all normal arguments *must* be supplied\n    ...\n    h = MyFunc3(g, \"some text\", false)   # you can supply optional arguments as if they were normal\n    i = MyFunc3(g)                       # but you can omit them also entirely\n    j = MyFunc3(g, invert=true)          # or you can pass some of them by name\n    ...\n    k = MyFunc4()                        # MyFunc4 will use defaults for all its arguments\n    l = MyFunc4(g, n=12)                 # you can supply some optional arguments as positional\n    ...                                  # and some by name\n    ...\n    m = MyFunc5(g, 25, \"test\")           # you can pass any type in the last two arguments of MyFunc5\n    n = MyFunc5(g, \"dissolve\", text=m)   # this can be both flexible *AND* dangerous if you don't check\n    o = MyFunc5(g, g)                    # the type of the arguments; you can of course omit optional ones\n\n\nClosing Remarks\n~~~~~~~~~~~~~~~\n\nThe set of rules for identifying and grouping tokens into higher-level structures (ie the AviSynth Grammar) \nends with statements. An AviSynth script is simply the aggregate of a number of statements. \nIn it you place as many statements as required to do the job. \nThe grammar does not care how you do so. However, there are a couple of things that are worth noting here \nto make developing scripts easier:\n\n-   The return value of the entire script is either (cf. the second case of Statements section above): \n\n    -   The result of a return expression statement anywhere in the main script block (ie not in a \n        function body or inside a try...catch block); all statements below that one will be ignored. \n        As a shorthand, a bare expression as the final statement is treated as if the keyword return \n        was present.\n    -   If there is no (explicit or implicit) return, a void value (ie a value of the 'undefined' type) \n        is returned. For example, this will happen if the last statement is an assignment. \n\n-    AviSynth provides a mechanism to include other scripts inside the current script block: the \n     Import function. The result of calling Import is the same as if you have typed the entire imported \n     script text at the point of the function call. \n\n-    Making self-contained scripts and using Import to include them in you scripts is a way to organise \n     and reuse your code (for example, your favorite used-defined functions). \n\nThe Full Avisynth Grammar - For Language Lawyers\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nFor those readers that prefer a formal definition of the AviSynth script language's grammar, \nthere is one available (though not \"officially-endorsed\" at the moment) in \n:doc:`Extended Backus-Naur form <syntax_formal_avisynth_grammar>` (or EBNF for short). \n\nBack to :doc:`Avisynth Syntax sections<syntax_sections>`.\n\n$Date: 2024/01/09 10:00:00 $\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/syntax/syntax_userdefined_scriptfunctions.rst",
    "content": "\nAviSynth Syntax - User defined script functions\n===============================================\n\n\nDefinition and Structure\n------------------------\n\nYou can define and call your own functions in AviSynth scripts as shown\nbelow. The function can return any clip or variable type. An user defined\nscript function is an independent block of script code that is executed each\ntime a call to the function is made in the script. An example of a simple\nuser defined script function (here a custom filter) immediately follows:\n\n::\n\n    function MuteRange(clip c, int fstart, int fend)\n    {\n        before = c.Trim(0, -fstart)\n        current = c.Trim(fstart, fend)\n        after = c.Trim(fend + 1, 0)\n        audio = Dissolve(before, current.BlankClip, 3)\n        return AudioDub(c, audio)\n    }\n\nUser defined script functions start with the keyword ``function`` followed by\nthe function name. The name of a script function follows the same naming\nrules as :doc:`script variables <syntax_script_variables>`.\n\nImmediately after the name, the function's argument list follows. The list\n(which can be empty) consists of (expected argument's type - argument's name)\npairs. Each argument's :doc:`type <syntax_script_variables>` may be any of those supported by the scripting\nlanguage.\n\n::\n\n    function MuteRange(clip c, int fstart, int fend)\n\nThen comes the function body, ie the code that is executed each time the\nfunction is called. The arguments are accessed within the function body by\ntheir names. The function body is contained within an opening and closing\nbrace pair ``{ ... }``.\n\n::\n\n    {\n        before = c.Trim(0, -fstart)\n        current = c.Trim(fstart, fend)\n        after = c.Trim(fend + 1, 0)\n        audio = Dissolve(before, current.BlankClip, 3)\n        return AudioDub(c, audio)\n    }\n\n(For simplicity, this code assumes the function will only be called with\nfstart > 0 and fend < c.Framecount-1. A more complete version would also\nhandle the special cases fstart=0 and fend=c.Framecount-1.)\n\nAt the end of the function body a ``return`` statement which returns the\nfinal value calculated from the arguments and the function's body code is\nplaced.\n\n::\n\n    return AudioDub(c, audio)\n\nIt should be noted that unlike other languages where multiple return\nstatements are allowed inside the function body, in AviSynth functions\ncontain a *single* return statement. This is because the language does not\nsupport branching (i.e. compound block statements).\n\n\nFacts about user defined script functions\n-----------------------------------------\n\n-   Functions can take up to sixty arguments and the return value can be\n    of any type supported by the scripting language (clip, int, float, bool,\n    string).\n\n-   Although not recommended practice, an argument type may be omitted,\n    and will default to ``val``, the generic type.\n\n-   If the function expects a video clip as its first argument, and that\n    argument is not supplied, then the clip in the special ``last`` variable\n    will be used.\n\n-   Functions support *named arguments*. Simply enclose an argument's\n    name inside double quotes to make it a named argument. Note that after\n    doing so the following apply:\n\n    -   1.  All subsequent arguments in the argument list must be made named also.\n    -   2.  **A named argument is an optional argument**, that is, it need not be supplied by the caller.\n    -   3.  When a function is called, any optional argument which has *not*\n            been provided is set to a value which has the void ('undefined') type.\n            This does not mean that its value is random garbage - simply that its\n            type is neither clip, int, float, bool or string and so it has *no*\n            usable value.\n    -   4.  Normally, you should use the :doc:`Defined <syntax_internal_functions_boolean>` function to test if an\n            optional argument has an explicit value, or the :doc:`Default <syntax_internal_functions_control>` function,\n            which combines the Defined test with the delivery of a default value if\n            appropriate.\n    -   5.  A void ('undefined') value can be passed on to another function\n            as one of its optional arguments. This is useful when you want to write a\n            wrapper function that calls another function, preserving the same\n            defaults.\n\n-   Functions always produce a new value and never modify an existing\n    one. What that means is that all arguments to a function are passed \"by\n    value\" and not \"by reference\"; in order to alter a variable's value in\n    AviSynth script language you must assign to it a new value.\n\n-   Functions can call other functions, *including theirselves*. The\n    latter is known as recursion and is a very useful technique for creating\n    functions that can accomplish complex tasks.\n\n-   Local function variables mask global ones with the same name inside\n    the function body. For example, if you define in a function a local\n    variable ``myvar`` by assigning to it a value, then you cannot read the\n    global ``myvar`` anymore inside this function.\n\n-   The above is also true for arguments, since from the perspective of a\n    function arguments are initialized local variables.\n\n-   Each function has its own local version of the special variable\n    *last*. On entry to a function, *last* is set to a void ('undefined')\n    value.\n\n\nRelated Links\n-------------\n\n-   `Shared functions`_. An ever growing collection of shared script\n    functions created by the members of the AviSynth community.\n\n-   :doc:`Conditional filters and script functions <../corefilters/conditionalfilter>`. A collection of highly\n    useful conditional filters implemented as user defined script functions.\n\n| {TEMP:\n| https://web.archive.org/web/20090129025123/http://www.avisynth.org/ExportingSingleImage,\n| https://web.archive.org/web/20090129091050/http://www.avisynth.org/HowToApplyFilterToManySingleFrames,\n| Perhaps make decent functions from the last two?}\n\n$Date: 2025-02-25 17:06:49-05:00 $\n\n.. _Shared functions: http://avisynth.nl/index.php/Shared_functions\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/twopointfive.rst",
    "content": "\nAviSynth 2.5\n============\n\n\nNew Video Features\n------------------\n\n-   A new color format: native YV12 support. Supports YV12 planar input\n    from DirectShowSource, AviSource and several MPEG decoders.\n\nFor a description of the color formats AviSynth can deal with see\n:doc:`the documentation for Convert() <corefilters/convert>`.\n\n\nNew Audio Features\n------------------\n\n-   Internal float point samples support. AviSynth now has internal\n    processing of float samples.\n-   Native Int24 and Int32 sample support. Support input and output of\n    higher precision samples.\n-   Multiple channel support. AviSynth now supports an unlimited number\n    of channels for both input and output.\n-   Automatic sample conversion. If some filters doesn't support a\n    specific sample type, they are converted to the format preserving most\n    quality (most often floats). Float samples are also automatically\n    converted back to 16bit before delivering them as output.\n\n\nNew Conditional Filters (v2.52)\n-------------------------------\n\n-   It is now possible to change variables and filter parameter every\n    frame - very powerful and versatile function!\n\nSee :doc:`ConditionalFilter <corefilters/conditionalfilter>`, :doc:`ConditionalReader <corefilters/conditionalreader>` and :ref:`here <runtime-functions>`.\n\n\nNew Internal Features\n---------------------\n\n-   Optimizations. Many basic features has been optimized, and now\n    performs much better than previous versions.\n-   Better cache efficiency. Filters can give hints to the cache, if they\n    don't want their input cached, so memory can be used more efficiently.\n\n\nC-style plugin support (v2.53)\n------------------------------\n\nAdded C-style plugin support (still in testing) to allow plugin writers to\nuse other compilers than MSVC.\nSee `this thread`_ for further info. The C-plugins must be loaded with\nLoadCPlugin after loading avisynth_c.dll. Your script becomes for example\n::\n\n    LoadPlugin(\"...\\avisynth_c.dll\")\n    LoadCPlugin(\"...\\smartdecimate.dll\") # notice the C in loadCplugin\n    AviSource(...)\n    SmartDecimate()\n\nDirectShow audio support (v2.53)\n--------------------------------\n\nUsing DirectShowSource it is possible to load audio from all sources that can\nbe opened through DirectShow.\nFor example, formats like: WAV/DTS/AC3/MP3 can be opened. Look\n:doc:`at the documentation <corefilters/directshowsource>` for more information.\n\nPlugins\n-------\n\nFilters for AviSynth v1.0x and v2.0x do no longer work in v2.5x. When you try\nto load them, they will most likely even crash. You have to use a special\nplugin \"`LoadPluginEx.dll (this plugin is contained in the WarpSharp\npackage)`_\" to load v2.0x plugins in v2.5x.\nYou first have to load the v2.5x plugins, then LoadPluginEx.dll and finally\nthe v2.0x plugins. You will also need to copy :ref:`msvcp71.dll and msvcr71.dll <JapanesePlugin>`\nto your system dir. Your script becomes for example\n::\n\n    LoadPlugin(\"C:\\Program Files\\avisynth2_temp\\LoadPluginEx.dll\")\n    LoadPlugin(\"C:\\Program Files\\avisynth2_temp\\plugins\\dustv5.dll\")\n\n    AviSource(\"D:\\clip.avi\")\n    ConvertToYUY2  # v2.0x plugins require YUY2 (or RGB)\n    PixieDust(5)\n\nI think that you can use the same plugin to load v2.5x plugins in v2.0x,\nhowever I never have tested this.\n\n$Date: 2007/12/03 19:45:17 $\n\n.. _this thread: http://forum.doom9.org/showthread.php?s=&threadid=58840\n.. _LoadPluginEx.dll (this plugin is contained in the WarpSharp package):\n    http://www.geocities.co.jp/SiliconValley-PaloAlto/2382/\n"
  },
  {
    "path": "distrib/docs/english/source/avisynthdoc/twopointsix.rst",
    "content": "\nAviSynth 2.6\n============\n\n\nNew Video Features\n------------------\n\n-   A new color formats: YV24 (24 bit), YV16 (16 bit), YV411 (12 bit) and\n    Y8 (8 bit; greyscale). For a description of the color formats AviSynth\n    can deal with see :doc:`here <corefilters/convert>`.\n\n\nNew Audio Features\n------------------\n\n-   none\n\n\nNew Internal Features\n---------------------\n\n-   MultiThreading support, including ScriptEnvironment::SetMTMode and\n    ScriptEnvironment::GetMTMode.\n\n$Date: 2009/09/12 20:57:20 $\n"
  },
  {
    "path": "distrib/docs/english/source/conf.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n#\n# AviSynth+ documentation build configuration file, created by\n# sphinx-quickstart on Sun Mar  8 20:56:40 2015.\n#\n# This file is execfile()d with the current directory set to its\n# containing dir.\n#\n# Note that not all possible configuration values are present in this\n# autogenerated file.\n#\n# All configuration values have a default; values that are commented out\n# serve to show the default.\n\nimport sys\nimport os\nimport sphinx\n\n# If extensions (or modules to document with autodoc) are in another directory,\n# add these directories to sys.path here. If the directory is relative to the\n# documentation root, use os.path.abspath to make it absolute, like shown here.\n#sys.path.insert(0, os.path.abspath('.'))\n\n# -- General configuration ------------------------------------------------\n\n# If your documentation needs a minimal Sphinx version, state it here.\n#needs_sphinx = '1.0'\n\n# Add any Sphinx extension module names here, as strings. They can be\n# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom\n# ones.\nextensions = [\n    'sphinx.ext.autodoc',\n]\n\n# Add any paths that contain templates here, relative to this directory.\ntemplates_path = ['_templates']\n\n# The suffix of source filenames.\nsource_suffix = '.rst'\n\n# The encoding of source files.\n#source_encoding = 'utf-8-sig'\n\n# The master toctree document.\nmaster_doc = 'index'\n\n# General information about the project.\nproject = 'AviSynth+'\ncopyright = '2000-2025, AviSynth and AviSynth+ contributors'\n\n# The version info for the project you're documenting, acts as replacement for\n# |version| and |release|, also used in various other places throughout the\n# built documents.\n#\n# The short X.Y version.\nversion = '3.7'\n# The full version, including alpha/beta/rc tags.\nrelease = '3.7'\n\n# The language for content autogenerated by Sphinx. Refer to documentation\n# for a list of supported languages.\n#language = None\n\n# There are two options for replacing |today|: either, you set today to some\n# non-false value, then it is used:\n#today = ''\n# Else, today_fmt is used as the format for a strftime call.\n#today_fmt = '%B %d, %Y'\n\n# List of patterns, relative to source directory, that match files and\n# directories to ignore when looking for source files.\nexclude_patterns = []\n\n# The reST default role (used for this markup: `text`) to use for all\n# documents.\n#default_role = None\n\n# If true, '()' will be appended to :func: etc. cross-reference text.\n#add_function_parentheses = True\n\n# If true, the current module name will be prepended to all description\n# unit titles (such as .. function::).\n#add_module_names = True\n\n# If true, sectionauthor and moduleauthor directives will be shown in the\n# output. They are ignored by default.\n#show_authors = False\n\n# The name of the Pygments (syntax highlighting) style to use.\npygments_style = 'sphinx'\n\n# A list of ignored prefixes for module index sorting.\n#modindex_common_prefix = []\n\n# If true, keep warnings as \"system message\" paragraphs in the built documents.\n#keep_warnings = False\n\n\n# -- Options for HTML output ----------------------------------------------\n\n# The theme to use for HTML and HTML Help pages.  See the documentation for\n# a list of builtin themes.\nif sphinx.__version__ >= '1.3':\n    html_theme = 'bizstyle'\nelse:\n    html_theme = 'default'\n\n# Theme options are theme-specific and customize the look and feel of a theme\n# further.  For a list of options available for each theme, see the\n# documentation.\nif html_theme == 'classic' or html_theme == 'default':\n    html_theme_options = {\n        \"collapsiblesidebar\": \"true\"\n    }\n\n# Add any paths that contain custom themes here, relative to this directory.\n#html_theme_path = []\n\n# The name for this set of Sphinx documents.  If None, it defaults to\n# \"<project> v<release> documentation\".\n#html_title = None\n\n# A shorter title for the navigation bar.  Default is the same as html_title.\n#html_short_title = None\n\n# The name of an image file (relative to this directory) to place at the top\n# of the sidebar.\nhtml_logo = '../../../Icons/DocIcon-Large.svg'\n\n# The name of an image file (within the static path) to use as favicon of the\n# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32\n# pixels large.\nhtml_favicon = '../../../Icons/Ico/AvsiDoc.ico'\n\n# Add any paths that contain custom static files (such as style sheets) here,\n# relative to this directory. They are copied after the builtin static files,\n# so a file named \"default.css\" will overwrite the builtin \"default.css\".\nhtml_static_path = ['_static']\n\n# Add any extra paths that contain custom files (such as robots.txt or\n# .htaccess) here, relative to this directory. These files are copied\n# directly to the root of the documentation.\n#html_extra_path = []\n\n# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,\n# using the given strftime format.\n#html_last_updated_fmt = '%b %d, %Y'\n\n# If true, SmartyPants will be used to convert quotes and dashes to\n# typographically correct entities.\n#html_use_smartypants = True\nsmartquotes = False\n\n# Custom sidebar templates, maps document names to template names.\n#html_sidebars = {}\n\n# Additional templates that should be rendered to pages, maps page names to\n# template names.\n#html_additional_pages = {}\n\n# If false, no module index is generated.\n#html_domain_indices = True\n\n# If false, no index is generated.\n#html_use_index = True\n\n# If true, the index is split into individual pages for each letter.\n#html_split_index = False\n\n# If true, links to the reST sources are added to the pages.\n#html_show_sourcelink = True\n\n# If true, \"Created using Sphinx\" is shown in the HTML footer. Default is True.\n#html_show_sphinx = True\n\n# If true, \"(C) Copyright ...\" is shown in the HTML footer. Default is True.\n#html_show_copyright = True\n\n# If true, an OpenSearch description file will be output, and all pages will\n# contain a <link> tag referring to it.  The value of this option must be the\n# base URL from which the finished HTML is served.\n#html_use_opensearch = ''\n\n# This is the file name suffix for HTML files (e.g. \".xhtml\").\n#html_file_suffix = None\n\n# Output file base name for HTML help builder.\nhtmlhelp_basename = 'AviSynthdoc'\n\n\n# -- Options for LaTeX output ---------------------------------------------\n\nlatex_elements = {\n# The paper size ('letterpaper' or 'a4paper').\n#'papersize': 'letterpaper',\n\n# The font size ('10pt', '11pt' or '12pt').\n#'pointsize': '10pt',\n\n# Additional stuff for the LaTeX preamble.\n#'preamble': '',\n}\n\n# Grouping the document tree into LaTeX files. List of tuples\n# (source start file, target name, title,\n#  author, documentclass [howto, manual, or own class]).\nlatex_documents = [\n  ('index', 'AviSynth.tex', 'AviSynth+ Documentation',\n   'AviSynth+ contributors', 'manual'),\n]\n\n# The name of an image file (relative to this directory) to place at the top of\n# the title page.\nlatex_logo = '../../../Icons/DocIcon-Large.svg'\n\n# For \"manual\" documents, if this is true, then toplevel headings are parts,\n# not chapters.\n#latex_use_parts = False\n\n# If true, show page references after internal links.\n#latex_show_pagerefs = False\n\n# If true, show URL addresses after external links.\n#latex_show_urls = False\n\n# Documents to append as an appendix to all manuals.\n#latex_appendices = []\n\n# If false, no module index is generated.\n#latex_domain_indices = True\n\n\n# -- Options for manual page output ---------------------------------------\n\n# One entry per manual page. List of tuples\n# (source start file, name, description, authors, manual section).\nman_pages = [\n    ('index', 'avisynth', 'AviSynth+ Documentation',\n     ['AviSynth+ contributors'], 1)\n]\n\n# If true, show URL addresses after external links.\n#man_show_urls = False\n\n\n# -- Options for Texinfo output -------------------------------------------\n\n# Grouping the document tree into Texinfo files. List of tuples\n# (source start file, target name, title, author,\n#  dir menu entry, description, category)\ntexinfo_documents = [\n  ('index', 'AviSynth', 'AviSynth+ Documentation',\n   'AviSynth+ contributors', 'AviSynth', 'One line description of project.',\n   'Miscellaneous'),\n]\n\n# Documents to append as an appendix to all manuals.\n#texinfo_appendices = []\n\n# If false, no module index is generated.\n#texinfo_domain_indices = True\n\n# How to display URL addresses: 'footnote', 'no', or 'inline'.\n#texinfo_show_urls = 'footnote'\n\n# If true, do not generate a @detailmenu in the \"Top\" node's menu.\n#texinfo_no_detailmenu = False\n"
  },
  {
    "path": "distrib/docs/english/source/index.rst",
    "content": ".. AviSynth+ documentation master file, created by\n   sphinx-quickstart on Sun Mar  8 20:56:40 2015.\n   You can adapt this file completely to your liking, but it should at least\n   contain the root `toctree` directive.\n\nAviSynth+ documentation\n=======================\n\nContents:\n\n.. toctree::\n   :maxdepth: 2\n   :glob:\n\n   avisynthdoc/overview\n   avisynthdoc/FilterSDK/FilterSDK\n   avisynthdoc/contributing/compiling_avsplus\n   avisynthdoc/contributing/posix\n   avisynthdoc/contributing/avsplus_external_deps_guide_manual\n   avisynthdoc/contributing/avsplus_external_deps_guide_manual_arm\n   avisynthdoc/contributing/contributing_with_git\n   avisynthdoc/index\n\n\nIndices and tables\n==================\n\n* :ref:`genindex`\n* :ref:`modindex`\n* :ref:`search`\n\n"
  },
  {
    "path": "distrib/gpl-cs.txt",
    "content": "  GNU GENERAL PUBLIC LICENSE,\n                              esk peklad\n                  -----------------------------------------\n  Tento text je neoficilnm pekladem GNU General Public License (GNU GPL). Nebyl\nvydn nadac Free Software Foundation a nevyjaduje prvn podstatu podmnek pro\nen softwaru pouvajcho GNU GPL - tomuto elu slou vhradn pvodn\nanglick verze GNU GPL. Pesto doufme, e tento peklad pome eskm tenm\nlpe porozumt licenci GNU GPL.\n\n\n    This is an unofficial translation of the GNU General Public\n    License into Czech.  It was not published by the Free\n    Software Foundation, and does not legally state the\n    distribution terms for software that uses the GNU GPL--only\n    the original English text of the GNU GPL does that.  However,\n    we hope that this translation will help Czech speakers\n    understand the GNU GPL better.\n\n----------------------------------------------------------------------------------\n\n                    GNU GENERAL PUBLIC LICENSE\n                 esk peklad verze 2, erven 1991\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n                          675 Mass Ave, Cambridge, MA 02139, USA\n\n Koprovn a distribuce doslovnch kopi tohoto licennho dokumentu jsou\n dovoleny komukoliv, jeho zmny jsou vak zakzny.\n\n                            Preambule\n\n  Softwarov licence jsou vtinou navreny tak, e vm odebraj prvo svobodnho\nsdlen a prav program. Smyslem GNU General Public License je naproti tomu\nzaruit svobodu ke sdlen a pravm svobodnho softwaru - pro zajitn\nsvobodnho pstupu k tomuto softwaru pro vechny jeho uivatele. Tato General\nPublic License se vztahuje na vtinu softwaru nadace Free Software Foundation a\nna jakkoli jin program, jeho autor se piklon k jejmu pouvn. (Nkter\ndal software od Free Software Foundation je namsto toho pokryt GNU Lesser\nGeneral Public License.) Mete ji rovn pout pro sv programy.\n\n  Pokud mluvme o svobodnm softwaru, mme na mysli svobodu, nikoliv cenu. Nae\nGeneral Public License je navrena pro zajitn toho, e mete svobodn it\nkopie svobodnho softwaru (a tovat si poplatek za tuto slubu, pokud chcete),\ne obdrte zdrojov kd anebo jej mete zskat, pokud ho chcete, e mete\ntento software modifikovat nebo jeho sti pout v novch svobodnch programech;\na e vte, e tyto vci smte dlat.\n\n  Abychom mohli vae prva chrnit, musme vytvoit omezen, kter zak komukoli\nvm tato prva odeprat nebo vs dat, abyste se tchto prv vzdal. Tato\nomezen se promtaj do jistch povinnost, kterm muste dostt, pokud te\nkopie dotynho softwaru anebo ho modifikujete.\n\n  Napklad, te-li kopie takovho programu, a ji zdarma nebo za poplatek,\nmuste poskytnout pjemcm vechna prva, kter mte sm. Muste zaruit, e\npjemci rovn dostanou anebo mohou zskat zdrojov kd. A muste jim ukzat\ntyto podmnky, aby znali sv prva.\n\n  Vae prva chrnme ve dvou krocch: (1) autorizac softwaru a (2) nabdkou tto\nlicence, kter vm dv prvoplatn svolen ke koprovn, en a modifikaci\nsoftwaru.\n\n  Kvli ochran kadho autora i ns samotnch chceme zajistit, aby kad chpal\nskutenost, e pro svobodn software neplat dn zruky. Je-li software nkm\njinm modifikovn a posln dle, chceme, aby pjemci vdli, e to, co maj,\nnen originl, take jakkoliv problmy vnesen jinmi se neodraz na reputaci\npvodnch autor.\n\n  Konen, kad svobodn program je neustle ohroen softwarovmi patenty.\nPejeme si zamezit nebezpe, e redistributoi svobodnho programu obdr\nsamostatn patentov osvden a tm uin program vzanm. Abychom tomu\nzamezili, deklarovali jsme, e kad patent mus bt bu vydn s tm, e\numouje kadmu svobodn uit, anebo nesm bt vydn vbec.\n\n  Pesn ustanoven a podmnky pro koprovn, en a modifikaci jsou uvedeny\ndle.\n\n    USTANOVEN A PODMNKY PRO KOPROVN, DISTRIBUCI A MODIFIKACI\n\n  0. Tato licence se vztahuje na kterkoliv program i jin dlo, kter obsahuje\nzmnku, umstnou v nm dritelem autorskch prv, o tom, e dlo me bt\neno podle ustanoven GNU General Public License. V dalm textu znamen\n\"program\" kad takov program nebo dlo a \"dlo zaloen na programu\" znamen\nbu program samotn anebo kad jin dlo z nj odvozen, kter podlh\nautorskmu zkonu: tm se mn dlo obsahujc program nebo jeho st, bu\ndoslovn anebo s modifikacemi, poppad v pekladu do jinho jazyka. (Nadle\nje peklad zahrnovn bez omezen pod pojem \"modifikace\".) Kad uivatel\nlicence je oznaovn jako \"vy\".\n\nJin innosti ne koprovn, en a modifikace nejsou pokryty touto licenc;\nsahaj mimo jej rmec. Akt sputn programu nen omezen a vstup z programu je\npokryt pouze tehdy, jestlie obsah vstupu tvo dlo zaloen na programu (nezvisle\nna tom, zda bylo vytvoeno innost programu). Posouzen platnosti pedchoz\nvty zvis na tom, co program dl.\n\n  1. Smte koprovat a it doslovn kopie zdrojovho kdu programu tak, jak jste\njej obdrel a na libovolnm mdiu, za pedpokladu, e na kad kopii viditeln a\nnleit zveejnte zmnku o autorskch prvech a absenci zruky; ponechte\nnedoten vechny zmnky vztahujc se k tto licenci a k absenci zruky; a dte\nkadmu pjemci spolu s programem kopii tto licence.\n\nZa fyzick akt penesen kopie mete dat poplatek a podle vlastnho uven\nmete nabdnout za poplatek zrun ochranu.\n\n  2. Mete modifikovat vai kopii i kopie programu anebo kterkoliv jeho sti,\na tak vytvoit dlo zaloen na programu a koprovat a roziovat takov\nmodifikace i dlo podle podmnek paragrafu 1 ve, za pedpokladu, e splnte\nvechny tyto podmnky:\n\n    a) Modifikovan soubory muste opatit zetelnou zmnkou uvdjc, e jste\n    soubory zmnil a datum kad zmny.\n\n    b) Muste umonit, aby jakkoliv vmi publikovan i roziovan dlo, kter\n    obsahuje zcela nebo zsti program nebo jakoukoli jeho st, poppad je z\n    programu nebo jeho sti odvozeno, mohlo bt jako celek bezplatn poskytnuto\n    kad tet osob v souladu s ustanovenmi tto licence.\n\n    c) Pokud modifikovan program pracuje normln tak, e te interaktivn povely,\n    muste zajistit, e pi nejbnjm zpsobu jeho sputn vytiskne nebo zobraz\n    hlen zahrnujc pslunou zmnku o autorskm prvu a uvede, e neexistuje\n    dn zruka (nebo ppadn, e zruku poskytujete vy), a e uivatel mohou\n    za tchto podmnek program redistribuovat, a mus uivateli sdlit, jakm\n    zpsobem me nahldnout do kopie tto licence. (Vjimka: v ppad, e sm\n    program je interaktivn, avak dn takov hlen nevypisuje, nepoaduje\n    se, aby vae dlo zaloen na programu takov hlen vypisovalo.)\n\nTyto poadavky se vztahuj k modifikovanmu dlu jako celku. Pokud lze\nidentifikovat sti takovho dla, kter zejm nejsou odvozeny z programu a\nmohou bt samy o sob rozumn povaovny za nezvisl a samostatn dla, pak\nse tato licence a jej ustanoven nevztahuj na tyto sti, jsou-li eny jako\nnezvisl dla. Avak jakmile tyt sti roziujete jako st celku, jm je\ndlo zaloen na programu, mus bt roziovn tohoto celku podzeno\nustanovenm tto licence tak, e povolen poskytnut dalm uivatelm se\nroz na cel dlo, tedy na vechny jeho sti bez ohledu na to, kdo kterou\nst napsal.\n\nSmyslem tohoto paragrafu tedy nen zskn prv na dlo zcela napsan vmi ani\npoprn vaich prv vi nmu; skutenm smyslem je vkon prva na zen\ndistribuce odvozench nebo kolektivnch dl zaloench na programu.\n\nPouh spojen jinho dla, je nen na programu zaloeno, s programem (anebo\ndlem zaloenm na programu) na pamovm nebo distribunm mdiu neuvazuje\ntoto jin dlo do psobnosti tto licence.\n\n  3. Mete koprovat a roziovat program (nebo dlo na nm zaloen, viz\nparagraf 2) v objektov anebo spustiteln podob podle ustanoven paragraf 1 a\n2 ve, pokud splnte nkterou z nsledujcch nleitost:\n\n    a) Doprovodte jej zdrojovm kdem ve strojov iteln form. Zdrojov kd mus\n    bt roziovn podle ustanoven paragraf 1 a 2 ve, a to na mdiu bn\n    pouvanm pro vmnu softwaru; nebo\n\n    b) Doprovodte jej psemnou nabdkou s platnost nejmn ti roky, podle n\n    poskytnete jakkoli tet stran, za poplatek nepevyujc vae vdaje\n    vynaloen na fyzickou vrobou zdrojov distribuce, kompletn strojov itelnou\n    kopii odpovdajcho zdrojovho kdu, jen mus bt en podle ustanoven\n    paragraf 1 a 2 ve na mdiu bn pouvanm pro vmnu softwaru; nebo\n\n    c) Doprovodte jej informacemi, kter jste dostal ohledn nabdky na poskytnut\n    zdrojovho kdu. (Tato alternativa je povolena jen pro nekomern en a jenom\n    tehdy, pokud jste obdrel program v objektovm nebo spustitelnm tvaru spolu s\n    takovou nabdkou, v souladu s polokou b ve.)\n\nZdrojov kd k dlu je nejvhodnj formou dla z hlediska jeho ppadnch\nmodifikac. Pro dlo ve spustitelnm tvaru znamen pln zdrojov kd veker\nzdrojov kd pro vechny moduly, kter obsahuje, plus jakkoli dal soubory pro\ndefinici rozhran, plus dvkov soubory potebn pro kompilaci a instalaci\nspustitelnho programu. Zvltn vjimkou jsou vak ty softwarov komponenty,\nkter jsou normln eny (bu ve zdrojov nebo binrn form) s hlavnmi\nsoustmi operanho systmu, na nm spustiteln program b (tj. s\npekladaem, jdrem apod.). Tyto komponenty nemus bt eny se zdrojovm kdem,\npokud ovem komponenta sama nedoprovz spustitelnou podobu dla.\n\nJe-li en objektovho nebo spustitelnho kdu inno nabdkou pstupu ke\nkoprovn z uritho msta, potom se za distribuci zdrojovho kdu pot i\nnabdnut ekvivalentnho pstupu ke koprovn zdrojovho kdu ze stejnho\nmsta, by pitom nejsou tet strany nuceny ke zkoprovn zdrojovho kdu\nspolu s objektovm.\n\n  4. Nesmte koprovat, modifikovat, poskytovat sublicence anebo it program\njinm zpsobem ne vslovn uvedenm v tto licenci. Jakkoli jin pokus o\nkoprovn, modifikovn, poskytnut sublicence anebo en programu je\nneplatn a automaticky ukon vae prva dan touto licenc. Strany, kter od\nvs obdrely kopie anebo prva v souladu s touto licenc, vak nemaj sv\nlicence ukoneny, dokud se jim pln podizuj.\n\n  5. Nen va povinost tuto licenci pijmout, protoe jste ji nepodepsal. Nic\njinho vm vak nedv monost koprovat nebo it program nebo odvozen dla.\nV ppad, e tuto licenci nepijmete, jsou tyto innosti zkonem zakzny. Tm\npdem modifikac anebo enm programu (anebo kadho dla zaloenho na\nprogramu) vyjadujete sv podzen se licenci a vem jejm ustanovenm a\npodmnkm pro koprovan, modifikovn a en programu a dl na nm zaloench.\n\n  6. Pokad, kdy redistribuujete program (nebo dlo zaloen na programu),\nzskv pjemce od pvodnho dritele licence prvo koprovat, modifikovat a\nit program v souladu s tmito ustanovenmi a podmnkami. Nesmte klst dn\ndal pekky vkonu zde zaruench pjemcovch prv. Nejste odpovdn za\nvymhn dodrovn tto licence tetmi stranami.\n\n  7. Jsou-li vm z rozhodnut soudu, obvinnm z poruen patentu nebo z\njakhokoli jinho dvodu (nejen v souvislosti s patenty) uloeny takov podmnky\n(a ji pkazem soudu, smlouvou nebo jinak), kter se vyluuj s podmnkami\ntto licence, nejste tm osvobozen od podmnek tto licence. Pokud nemete\nit program tak, abyste vyhovl zrove svm zvazkm vyplvajcm z tto\nlicence a jinm platnm zvazkm, nesmte jej v dsledku toho it vbec. Pokud\nby napklad patentov osvden nepovolovalo bezplatnou redistribuci programu\nvemi, kdo vam piinnm zskaj pmo nebo nepmo jeho kopie, pak by jedin\nmon zpsob jak vyhovt zrove patentovmu osvden i tto licenci spoval v\nukonen distribuce programu.\n\nPokud by se za njakch specifickch okolnost jevila nkter st tohoto\nparagrafu jako neplatn nebo nevynutiteln, povauje se za smrodatnou rovnovha\nvyjden tmto paragrafem a paragraf jako celek se povauje za smrodatn za\njinch okolnost.\n\nSmyslem tohoto paragrafu nen navdt vs k poruovn patent i jinch\nustanoven vlastnickho prva, anebo tato ustanoven zpochybovat; jedinm jeho\nsmyslem je ochrana integrity systmu en svobodnho softwaru, kter je\npodloen veejnmi licennmi pedpisy. Mnoz lid poskytli sv pspvky do\nirokho okruhu softwaru enho tmto systmem, spolehnuve se na jeho\ndsledn uplatovn; zle na autorovi/drci, aby rozhodl, zda si peje it\nsoftware pomoc njakho jinho systmu a dn uivatel licence neme takov\nrozhodnut zpochybovat.\n\nSmyslem tohoto paragrafu je zevrubn osvtlit to, co je povaovno za dsledek\nplynouc ze zbytku tto licence.\n\n  8. Pokud je en i pouit programu v nkterch zemch omezeno bu patenty\nanebo autorsky chrnnmi rozhranmi, me dritel pvodnch autorskch prv,\nkter svuje program do psobnosti tto licence, pidat vslovn omezen pro\ngeografick en, vyluujc takov zem, take en je povoleno jen v tch\nzemch nebo mezi tmi zemmi, kter nejsou tmto zpsobem vyloueny. Tato\nlicence zahrnuje v tomto ppad takov omezen pesn tak, jako by bylo zapsno\nv textu tto licence.\n\n  9. Free Software Foundation me as od asu vydvat upraven nebo nov verze\nGeneral Public License. Takov nov verze se budou svm duchem podobat souasn\nverzi, v jednotlivostech se vak mohou liit s ohledem na nov problmy i zjmy.\n\nKad verzi je pidleno rozliujc slo verze. Pokud program specifikuje\nslo verze, kter se na nj vztahuje, a \"vechny nsledujc verze\", mete se\npodle uven dit ustanovenmi a podmnkami buto on konkrtn verze anebo\nkterkoliv nsledujc verze, kterou vydala Free Software Foundation. Jestlie\nprogram nespecifikuje slo verze tto licence, mete si vybrat libovolnou\nverzi, kterou kdy Free Software Foundation vydala.\n\n  10. Pokud si pejete zahrnout sti programu do jinch svobodnch program,\njejich distribun podmnky jsou odlin, zalete autorovi dost o povolen. V\nppad softwaru, k nmu vlastn autorsk prva Free Software Foundation,\nnapite Free Software Foundation; nkdy inme vjimky ze zde uvedench\nustanoven. Nae rozhodnut bude vedeno dvma cli: zachovnm svobodn povahy\nvech odvozenin naeho svobodnho softwaru a podporou sdlen a optovnho\nvyuit softwaru obecn.\n\n                           ZRUKA SE NEPOSKYTUJE\n\n  11. VZHLEDEM K BEZPLATNMU POSKYTNUT LICENCE K PROGRAMU SE NA\nPROGRAM NEVZTAHUJE DN ZRUKA, A TO V ME POVOLEN PLATNM\nZKONEM.  POKUD NEN PSEMN STANOVENO JINAK, POSKYTUJ DRITEL\nAUTORSKCH PRV POPPAD JIN STRANY PROGRAM \"TAK, JAK JE\", BEZ\nZRUKY JAKHOKOLI DRUHU, A VSLOVN NEBO VYPLVAJC, VETN, ALE\nNIKOLI JEN, ZRUK PRODEJNOSTI A VHODNOSTI PRO URIT EL. POKUD\nJDE O KVALITU A VKONNOST PROGRAMU, LE VEKER RIZIKO NA VS.\nPOKUD BY SE U PROGRAMU PROJEVILY ZVADY, PADAJ NKLADY ZA VECHNU\nPOTEBNOU DRBU, OPRAVU I NPRAVU NA V VRUB.\n\n  12. V DNM PPAD, S VJIMKOU TOHO, KDY TO VYADUJE PLATN\nZKON, ANEBO KDY TO BYLO PSEMN ODSOUHLASENO, VM NEBUDE DN\nZ DRITEL AUTORSKCH PRV ANI DN JIN STRANA, KTER SM\nMODIFIKOVAT I IT PROGRAM V SOULADU S PEDCHOZMI USTANOVENMI,\nODPOVDNI ZA KODY, VETN VECH OBECNCH, SPECILNCH, NAHODILCH\nNEBO NSLEDNCH KOD VYPLVAJCCH Z UVN ANEBO NESCHOPNOSTI\nUVAT PROGRAMU (VETN, ALE NIKOLI JEN, ZTRTY NEBO ZKRESLEN DAT,\nNEBO TRVALCH KOD ZPSOBENCH VM NEBO TETM STRANM, NEBO\nSELHN FUNKCE PROGRAMU V SOUINNOSTI S JINMI PROGRAMY), A TO I V\nPPAD, E TAKOV DRITEL AUTORSKCH PRV NEBO JIN STRANA BYLI\nUPOZORNNI NA MONOST TAKOVCH KOD.\n\n                         KONEC USTANOVEN A PODMNEK\n\n\n----------------------------------------------------------------------------------\n(c) 2004, Strnky o svobodnm software (info@gnu.cz)\nTento peklad je z velk sti zaloen na pekladu od Ladislava Lhotky.\nV ppad doplujcch informac nebo oprav kontaktujte maintainera: kysela@gnu.cz\nPosledn prava: 22. 12. 2004\n----------------------------------------------------------------------------------\n"
  },
  {
    "path": "distrib/gpl-de.txt",
    "content": "                              GNU General Public License\n\n                  Deutsche bersetzung der Version 2, Juni 1991\n\n            Den offiziellen englischen Originaltext finden Sie unter\n                  http://www.gnu.org/licenses/gpl-2.0.html.\n\n\n   Diese bersetzung wurde ursprnglich erstellt von Katja Lachmann bersetzungen\n   im Auftrag der S.u.S.E. GmbH - http://www.suse.de. Sie wurde berarbeitet von\n   Peter Gerwinski, G-N-U GmbH - http://www.g-n-u.de (31. Oktober 1996, 4. Juni 2000)\n\n\n   Diese bersetzung wird mit der Absicht angeboten, das Verstndnis der GNU\n   General Public License (GNU GPL) zu erleichtern. Es handelt sich jedoch nicht\n   um eine offizielle oder im rechtlichen Sinne anerkannte bersetzung.\n\n   Die Free Software Foundation (FSF) ist nicht der Herausgeber dieser bersetzung,\n   und sie hat diese bersetzung auch nicht als rechtskrftigen Ersatz fr die\n   Original-GNU-GPL anerkannt. Da die bersetzung nicht sorgfltig von Anwlten\n   berprft wurde, knnen die bersetzer nicht garantieren, da die bersetzung\n   die rechtlichen Aussagen der GNU GPL exakt wiedergibt. Wenn Sie sichergehen\n   wollen, da von Ihnen geplante Aktivitten im Sinne der GNU GPL gestattet\n   sind, halten Sie sich bitte an die englischsprachige Originalversion.\n\n   Die bersetzer und die Free Software Foundation mchten Sie darum bitten, diese\n   bersetzung nicht als offizielle Lizenzbedingungen fr von Ihnen geschriebene\n   Programme zu verwenden. Bitte benutzen Sie hierfr stattdessen die von der Free\n   Software Foundation herausgegebene englischsprachige Originalversion.\n\n\n\n   This is a translation of the GNU General Public License into German. This\n   translation is distributed in the hope that it will facilitate understanding, but\n   it is not an official or legally approved translation.\n\n   The Free Software Foundation is not the publisher of this translation and has not\n   approved it as a legal substitute for the authentic GNU General Public License.\n   The translation has not been reviewed carefully by lawyers, and therefore the\n   translator cannot be sure that it exactly represents the legal meaning of the\n   GNU General Public License. If you wish to be sure whether your planned\n   activities are permitted by the GNU General Public License, please refer\n   to the authentic English version.\n\n   The translators and the Free Software Foundation strongly urge you not to use\n   this translation as the official distribution terms for your programs; instead, please\n   use the authentic English version published by the Free Software Foundation.\n\n\n\n                              GNU General Public License\n\n                  Deutsche bersetzung der Version 2, Juni 1991\n\n                Copyright  1989, 1991 Free Software Foundation, Inc.\n                  51 Franklin St, Fifth Floor, Boston, MA 02110, USA\n\nEs ist jedermann gestattet, diese Lizenzurkunde zu vervielfltigen und unvernderte Kopien zu verbreiten; nderungen sind jedoch nicht erlaubt.\n\nDiese bersetzung ist kein rechtskrftiger Ersatz fr die englischsprachige Originalversion!\n\n\nVorwort\n\n\nDie meisten Softwarelizenzen sind daraufhin entworfen worden, Ihnen die Freiheit zu nehmen, die Software weiterzugeben und zu verndern. Im Gegensatz dazu soll Ihnen die GNU General Public License, die Allgemeine ffentliche GNU-Lizenz, ebendiese Freiheit garantieren. Sie soll sicherstellen, da die Software fr alle Benutzer frei ist. Diese Lizenz gilt fr den Groteil der von der Free Software Foundation herausgegebenen Software und fr alle anderen Programme, deren Autoren ihr Werk dieser Lizenz unterstellt haben. Auch Sie knnen diese Mglichkeit der Lizenzierung fr Ihre Programme anwenden. (Ein anderer Teil der Software der Free Software Foundation unterliegt stattdessen der GNU Lesser General Public License, der Kleineren Allgemeinen ffentlichen GNU-Lizenz.)\n\nDie Bezeichnung \"freie\" Software bezieht sich auf Freiheit, nicht auf den Preis. Unsere Lizenzen sollen Ihnen die Freiheit garantieren, Kopien freier Software zu verbreiten (und etwas fr diesen Service zu berechnen, wenn Sie mchten), die Mglichkeit, die Software im Quelltext zu erhalten oder den Quelltext auf Wunsch zu bekommen. Die Lizenzen sollen garantieren, da Sie die Software ndern oder Teile davon in neuen freien Programmen verwenden drfen - und da Sie wissen, da Sie dies alles tun drfen.\n\nUm Ihre Rechte zu schtzen, mssen wir Einschrnkungen machen, die es jedem verbieten, Ihnen diese Rechte zu verweigern oder Sie aufzufordern, auf diese Rechte zu verzichten. Aus diesen Einschrnkungen folgen bestimmte Verantwortlichkeiten fr Sie, wenn Sie Kopien der Software verbreiten oder sie verndern.\n\nBeispielsweise mssen Sie den Empfngern alle Rechte gewhren, die Sie selbst haben, wenn Sie - kostenlos oder gegen Bezahlung - Kopien eines solchen Programms verbreiten. Sie mssen sicherstellen, da auch die Empfnger den Quelltext erhalten bzw. erhalten knnen. Und Sie mssen ihnen diese Bedingungen zeigen, damit sie ihre Rechte kennen.\n\nWir schtzen Ihre Rechte in zwei Schritten: (1) Wir stellen die Software unter ein Urheberrecht (Copyright), und (2) wir bieten Ihnen diese Lizenz an, die Ihnen das Recht gibt, die Software zu vervielfltigen, zu verbreiten und/oder zu verndern.\n\nUm die Autoren und uns zu schtzen, wollen wir darberhinaus sicherstellen, da jeder erfhrt, da fr diese freie Software keinerlei Garantie besteht. Wenn die Software von jemand anderem modifiziert und weitergegeben wird, mchten wir, da die Empfnger wissen, da sie nicht das Original erhalten haben, damit irgendwelche von anderen verursachte Probleme nicht den Ruf des ursprnglichen Autors schdigen.\n\nSchlielich und endlich ist jedes freie Programm permanent durch Software-Patente bedroht. Wir mchten die Gefahr ausschlieen, da Distributoren eines freien Programms individuell Patente lizensieren - mit dem Ergebnis, da das Programm proprietr wrde. Um dies zu verhindern, haben wir klargestellt, da jedes Patent entweder fr freie Benutzung durch jedermann lizenziert werden mu oder berhaupt nicht lizenziert werden darf.\n\nEs folgen die genauen Bedingungen fr die Vervielfltigung, Verbreitung und Bearbeitung:\n\n\nAllgemeine ffentliche GNU-Lizenz\n\n\nBedingungen fr die Vervielfltigung, Verbreitung und Bearbeitung\n\n\n0. Diese Lizenz gilt fr jedes Programm und jedes andere Werk, in dem ein entsprechender Vermerk des Copyright-Inhabers darauf hinweist, da das Werk unter den Bestimmungen dieser General Public License verbreitet werden darf. Im folgenden wird jedes derartige Programm oder Werk als \"das Programm\" bezeichnet; die Formulierung \"auf dem Programm basierendes Werk\" bezeichnet das Programm sowie jegliche Bearbeitung des Programms im urheberrechtlichen Sinne, also ein Werk, welches das Programm, auch auszugsweise, sei es unverndert oder verndert und/oder in eine andere Sprache bersetzt, enthlt. (Im folgenden wird die bersetzung ohne Einschrnkung als \"Bearbeitung\" eingestuft.) Jeder Lizenznehmer wird im folgenden als \"Sie\" angesprochen.\n\nAndere Handlungen als Vervielfltigung, Verbreitung und Bearbeitung werden von dieser Lizenz nicht berhrt; sie fallen nicht in ihren Anwendungsbereich. Der Vorgang der Ausfhrung des Programms wird nicht eingeschrnkt, und die Ausgaben des Programms unterliegen dieser Lizenz nur, wenn der Inhalt ein auf dem Programm basierendes Werk darstellt (unabhngig davon, da die Ausgabe durch die Ausfhrung des Programmes erfolgte). Ob dies zutrifft, hngt von den Funktionen des Programms ab.\n\n1. Sie drfen auf beliebigen Medien unvernderte Kopien des Quelltextes des Programms, wie sie ihn erhalten haben, anfertigen und verbreiten. Voraussetzung hierfr ist, da Sie mit jeder Kopie einen entsprechenden Copyright-Vermerk sowie einen Haftungsausschlu verffentlichen, alle Vermerke, die sich auf diese Lizenz und das Fehlen einer Garantie beziehen, unverndert lassen und desweiteren allen anderen Empfngern des Programms zusammen mit dem Programm eine Kopie dieser Lizenz zukommen lassen.\n\nSie drfen fr den eigentlichen Kopiervorgang eine Gebhr verlangen. Wenn Sie es wnschen, drfen Sie auch gegen Entgelt eine Garantie fr das Programm anbieten.\n\n2. Sie drfen Ihre Kopie(n) des Programms oder eines Teils davon verndern, wodurch ein auf dem Programm basierendes Werk entsteht; Sie drfen derartige Bearbeitungen unter den Bestimmungen von Paragraph 1 vervielfltigen und verbreiten, vorausgesetzt, da zustzlich alle im folgenden genannten Bedingungen erfllt werden:\n\n a. Sie mssen die vernderten Dateien mit einem aufflligen Vermerk versehen, der auf die von Ihnen vorgenommene Modifizierung und das Datum jeder nderung hinweist.\n\n b. Sie mssen dafr sorgen, da jede von Ihnen verbreitete oder verffentlichte Arbeit, die ganz oder teilweise von dem Programm oder Teilen davon abgeleitet ist, Dritten gegenber als Ganzes unter den Bedingungen dieser Lizenz ohne Lizenzgebhren zur Verfgung gestellt wird.\n\n c. Wenn das vernderte Programm normalerweise bei der Ausfhrung interaktiv Kommandos einliest, mssen Sie dafr sorgen, da es, wenn es auf dem blichsten Wege fr solche interaktive Nutzung gestartet wird, eine Meldung ausgibt oder ausdruckt, die einen geeigneten Copyright-Vermerk enthlt sowie einen Hinweis, da es keine Gewhrleistung gibt (oder anderenfalls, da Sie Garantie leisten), und da die Benutzer das Programm unter diesen Bedingungen weiter verbreiten drfen. Auch mu der Benutzer darauf hingewiesen werden, wie er eine Kopie dieser Lizenz ansehen kann. (Ausnahme: Wenn das Programm selbst interaktiv arbeitet, aber normalerweise keine derartige Meldung ausgibt, mu Ihr auf dem Programm basierendes Werk auch keine solche Meldung ausgeben).\n\nDiese Anforderungen gelten fr das bearbeitete Werk als Ganzes. Wenn identifizierbare Teile des Werkes nicht von dem Programm abgeleitet sind und vernnftigerweise als unabhngige und eigenstndige Werke fr sich selbst zu betrachten sind, dann gelten diese Lizenz und ihre Bedingungen nicht fr die betroffenen Teile, wenn Sie diese als eigenstndige Werke weitergeben. Wenn Sie jedoch dieselben Abschnitte als Teil eines Ganzen weitergeben, das ein auf dem Programm basierendes Werk darstellt, dann mu die Weitergabe des Ganzen nach den Bedingungen dieser Lizenz erfolgen, deren Bedingungen fr weitere Lizenznehmer somit auf das gesamte Ganze ausgedehnt werden - und somit auf jeden einzelnen Teil, unabhngig vom jeweiligen Autor.\n\nSomit ist es nicht die Absicht dieses Abschnittes, Rechte fr Werke in Anspruch zu nehmen oder Ihnen die Rechte fr Werke streitig zu machen, die komplett von Ihnen geschrieben wurden; vielmehr ist es die Absicht, die Rechte zur Kontrolle der Verbreitung von Werken, die auf dem Programm basieren oder unter seiner auszugsweisen Verwendung zusammengestellt worden sind, auszuben.\n\nFerner bringt auch das einfache Zusammenlegen eines anderen Werkes, das nicht auf dem Programm basiert, mit dem Programm oder einem auf dem Programm basierenden Werk auf ein- und demselben Speicher- oder Vertriebsmedium dieses andere Werk nicht in den Anwendungsbereich dieser Lizenz.\n\n3. Sie drfen das Programm (oder ein darauf basierendes Werk gem Paragraph 2) als Objectcode oder in ausfhrbarer Form unter den Bedingungen der Paragraphen 1 und 2 kopieren und weitergeben - vorausgesetzt, da Sie auerdem eine der folgenden Leistungen erbringen:\n\n\n a. Liefern Sie das Programm zusammen mit dem vollstndigen zugehrigen maschinenlesbaren Quelltext auf einem fr den Datenaustausch blichen Medium aus, wobei die Verteilung unter den Bedingungen der Paragraphen 1 und 2 erfolgen mu. Oder:\n\n b. Liefern Sie das Programm zusammen mit einem mindestens drei Jahre lang gltigen schriftlichen Angebot aus, jedem Dritten eine vollstndige maschinenlesbare Kopie des Quelltextes zur Verfgung zu stellen - zu nicht hheren Kosten als denen, die durch den physikalischen Kopiervorgang anfallen -, wobei der Quelltext unter den Bedingungen der Paragraphen 1 und 2 auf einem fr den Datenaustausch blichen Medium weitergegeben wird. Oder:\n\n c. Liefern Sie das Programm zusammen mit dem schriftlichen Angebot der Zurverfgungstellung des Quelltextes aus, das Sie selbst erhalten haben. (Diese Alternative ist nur fr nicht-kommerzielle Verbreitung zulssig und nur, wenn Sie das Programm als Objectcode oder in ausfhrbarer Form mit einem entsprechenden Angebot gem Absatz b erhalten haben.)\n\nUnter dem Quelltext eines Werkes wird diejenige Form des Werkes verstanden, die fr Bearbeitungen vorzugsweise verwendet wird. Fr ein ausfhrbares Programm bedeutet \"der komplette Quelltext\": Der Quelltext aller im Programm enthaltenen Module einschlielich aller zugehrigen Modulschnittstellen-Definitionsdateien sowie der zur Compilation und Installation verwendeten Skripte. Als besondere Ausnahme jedoch braucht der verteilte Quelltext nichts von dem zu enthalten, was blicherweise (entweder als Quelltext oder in binrer Form) zusammen mit den Hauptkomponenten des Betriebssystems (Kernel, Compiler usw.) geliefert wird, unter dem das Programm luft - es sei denn, diese Komponente selbst gehrt zum ausfhrbaren Programm.\n\nWenn die Verbreitung eines ausfhrbaren Programms oder von Objectcode dadurch erfolgt, da der Kopierzugriff auf eine dafr vorgesehene Stelle gewhrt wird, so gilt die Gewhrung eines gleichwertigen Zugriffs auf den Quelltext als Verbreitung des Quelltextes, auch wenn Dritte nicht dazu gezwungen sind, den Quelltext zusammen mit dem Objectcode zu kopieren.\n\n4. Sie drfen das Programm nicht vervielfltigen, verndern, weiter lizenzieren oder verbreiten, sofern es nicht durch diese Lizenz ausdrcklich gestattet ist. Jeder anderweitige Versuch der Vervielfltigung, Modifizierung, Weiterlizenzierung und Verbreitung ist nichtig und beendet automatisch Ihre Rechte unter dieser Lizenz. Jedoch werden die Lizenzen Dritter, die von Ihnen Kopien oder Rechte unter dieser Lizenz erhalten haben, nicht beendet, solange diese die Lizenz voll anerkennen und befolgen.\n\n5. Sie sind nicht verpflichtet, diese Lizenz anzunehmen, da Sie sie nicht unterzeichnet haben. Jedoch gibt Ihnen nichts anderes die Erlaubnis, das Programm oder von ihm abgeleitete Werke zu verndern oder zu verbreiten. Diese Handlungen sind gesetzlich verboten, wenn Sie diese Lizenz nicht anerkennen. Indem Sie das Programm (oder ein darauf basierendes Werk) verndern oder verbreiten, erklren Sie Ihr Einverstndnis mit dieser Lizenz und mit allen ihren Bedingungen bezglich der Vervielfltigung, Verbreitung und Vernderung des Programms oder eines darauf basierenden Werks.\n\n6. Jedesmal, wenn Sie das Programm (oder ein auf dem Programm basierendes Werk) weitergeben, erhlt der Empfnger automatisch vom ursprnglichen Lizenzgeber die Lizenz, das Programm entsprechend den hier festgelegten Bestimmungen zu vervielfltigen, zu verbreiten und zu verndern. Sie drfen keine weiteren Einschrnkungen der Durchsetzung der hierin zugestandenen Rechte des Empfngers vornehmen. Sie sind nicht dafr verantwortlich, die Einhaltung dieser Lizenz durch Dritte durchzusetzen.\n\n7. Sollten Ihnen infolge eines Gerichtsurteils, des Vorwurfs einer Patentverletzung oder aus einem anderen Grunde (nicht auf Patentfragen begrenzt) Bedingungen (durch Gerichtsbeschlu, Vergleich oder anderweitig) auferlegt werden, die den Bedingungen dieser Lizenz widersprechen, so befreien Sie diese Umstnde nicht von den Bestimmungen dieser Lizenz. Wenn es Ihnen nicht mglich ist, das Programm unter gleichzeitiger Beachtung der Bedingungen in dieser Lizenz und Ihrer anderweitigen Verpflichtungen zu verbreiten, dann drfen Sie als Folge das Programm berhaupt nicht verbreiten. Wenn zum Beispiel ein Patent nicht die gebhrenfreie Weiterverbreitung des Programms durch diejenigen erlaubt, die das Programm direkt oder indirekt von Ihnen erhalten haben, dann besteht der einzige Weg, sowohl das Patentrecht als auch diese Lizenz zu befolgen, darin, ganz auf die Verbreitung des Programms zu verzichten.\n\nSollte sich ein Teil dieses Paragraphen als ungltig oder unter bestimmten Umstnden nicht durchsetzbar erweisen, so soll dieser Paragraph seinem Sinne nach angewandt werden; im brigen soll dieser Paragraph als Ganzes gelten.\n\nZweck dieses Paragraphen ist nicht, Sie dazu zu bringen, irgendwelche Patente oder andere Eigentumsansprche zu verletzen oder die Gltigkeit solcher Ansprche zu bestreiten; dieser Paragraph hat einzig den Zweck, die Integritt des Verbreitungssystems der freien Software zu schtzen, das durch die Praxis ffentlicher Lizenzen verwirklicht wird. Viele Leute haben grozgige Beitrge zu dem groen Angebot der mit diesem System verbreiteten Software im Vertrauen auf die konsistente Anwendung dieses Systems geleistet; es liegt am Autor/Geber, zu entscheiden, ob er die Software mittels irgendeines anderen Systems verbreiten will; ein Lizenznehmer hat auf diese Entscheidung keinen Einflu.\n\nDieser Paragraph ist dazu gedacht, deutlich klarzustellen, was als Konsequenz aus dem Rest dieser Lizenz betrachtet wird.\n\n8. Wenn die Verbreitung und/oder die Benutzung des Programms in bestimmten Staaten entweder durch Patente oder durch urheberrechtlich geschtzte Schnittstellen eingeschrnkt ist, kann der Urheberrechtsinhaber, der das Programm unter diese Lizenz gestellt hat, eine explizite geographische Begrenzung der Verbreitung angeben, in der diese Staaten ausgeschlossen werden, so da die Verbreitung nur innerhalb und zwischen den Staaten erlaubt ist, die nicht ausgeschlossen sind. In einem solchen Fall beinhaltet diese Lizenz die Beschrnkung, als wre sie in diesem Text niedergeschrieben.\n\n9. Die Free Software Foundation kann von Zeit zu Zeit berarbeitete und/oder neue Versionen der General Public License verffentlichen. Solche neuen Versionen werden vom Grundprinzip her der gegenwrtigen entsprechen, knnen aber im Detail abweichen, um neuen Problemen und Anforderungen gerecht zu werden.\n\nJede Version dieser Lizenz hat eine eindeutige Versionsnummer. Wenn in einem Programm angegeben wird, da es dieser Lizenz in einer bestimmten Versionsnummer oder \"jeder spteren Version\" (\"any later version) unterliegt, so haben Sie die Wahl, entweder den Bestimmungen der genannten Version zu folgen oder denen jeder beliebigen spteren Version, die von der Free Software Foundation verffentlicht wurde. Wenn das Programm keine Versionsnummer angibt, knnen Sie eine beliebige Version whlen, die je von der Free Software Foundation verffentlicht wurde.\n\n10. Wenn Sie den Wunsch haben, Teile des Programms in anderen freien Programmen zu verwenden, deren Bedingungen fr die Verbreitung anders sind, schreiben Sie an den Autor, um ihn um die Erlaubnis zu bitten. Fr Software, die unter dem Copyright der Free Software Foundation steht, schreiben Sie an die Free Software Foundation; wir machen zu diesem Zweck gelegentlich Ausnahmen. Unsere Entscheidung wird von den beiden Zielen geleitet werden, zum einen den freien Status aller von unserer freien Software abgeleiteten Werke zu erhalten und zum anderen das gemeinschaftliche Nutzen und Wiederverwenden von Software im allgemeinen zu frdern.\n\n\nKeine Gewhrleistung\n\n\n11. Da das Programm ohne jegliche Kosten lizenziert wird, besteht keinerlei Gewhrleistung fr das Programm, soweit dies gesetzlich zulssig ist. Sofern nicht anderweitig schriftlich besttigt, stellen die Copyright-Inhaber und/oder Dritte das Programm so zur Verfgung, \"wie es ist\", ohne irgendeine Gewhrleistung, weder ausdrcklich noch implizit, einschlielich - aber nicht begrenzt auf - Marktreife oder Verwendbarkeit fr einen bestimmten Zweck. Das volle Risiko bezglich Qualitt und Leistungsfhigkeit des Programms liegt bei Ihnen. Sollte sich das Programm als fehlerhaft herausstellen, liegen die Kosten fr notwendigen Service, Reparatur oder Korrektur bei Ihnen.\n\n12. In keinem Fall, auer wenn durch geltendes Recht gefordert oder schriftlich zugesichert, ist irgendein Copyright-Inhaber oder irgendein Dritter, der das Programm wie oben erlaubt modifiziert oder verbreitet hat, Ihnen gegenber fr irgendwelche Schden haftbar, einschlielich jeglicher allgemeiner oder spezieller Schden, Schden durch Seiteneffekte (Nebenwirkungen) oder Folgeschden, die aus der Benutzung des Programms oder der Unbenutzbarkeit des Programms folgen (einschlielich - aber nicht beschrnkt auf - Datenverluste, fehlerhafte Verarbeitung von Daten, Verluste, die von Ihnen oder anderen getragen werden mssen, oder dem Unvermgen des Programms, mit irgendeinem anderen Programm zusammenzuarbeiten), selbst wenn ein Copyright-Inhaber oder Dritter ber die Mglichkeit solcher Schden unterrichtet worden war.\n\n\nEnde der Bedingungen\n\n\nWie Sie diese Bedingungen auf Ihre eigenen, neuen Programme anwenden knnen\n\n\nWenn Sie ein neues Programm entwickeln und wollen, da es vom grtmglichen Nutzen fr die Allgemeinheit ist, dann erreichen Sie das am besten, indem Sie es zu freier Software machen, die jeder unter diesen Bestimmungen weiterverbreiten und verndern kann.\n\nUm dies zu erreichen, fgen Sie die folgenden Vermerke zu Ihrem Programm hinzu. Am sichersten ist es, sie an den Anfang einer jeden Quelldatei zu stellen, um den Gewhrleistungsausschlu mglichst deutlich darzustellen; zumindest aber sollte jede Datei eine Copyright-Zeile besitzen sowie einen kurzen Hinweis darauf, wo die vollstndigen Vermerke zu finden sind.\n\n    [eine Zeile mit dem Programmnamen und einer kurzen Beschreibung]\n    Copyright (C) [Jahr]  [Name des Autors]\n\n    This program is free software; you can redistribute it and/or modify it under the\n    terms of the GNU General Public License as published by the Free Software\n    Foundation; either version 2 of the License, or (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful, but WITHOUT ANY\n    WARRANTY; without even the implied warranty of MERCHANTABILITY or\n    FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n    License for more details.\n\n    You should have received a copy of the GNU General Public License along with\n    this program; if not, write to the Free Software Foundation, Inc.,\n    51 Franklin St, Fifth Floor, Boston, MA 02110, USA\n\nAuf Deutsch:\n\n    [eine Zeile mit dem Programmnamen und einer kurzen Beschreibung]\n    Copyright (C) [Jahr]  [Name des Autors]\n\n    Dieses Programm ist freie Software. Sie knnen es unter den Bedingungen der\n    GNU General Public License, wie von der Free Software Foundation verffentlicht,\n    weitergeben und/oder modifizieren, entweder gem Version 2 der Lizenz oder\n    (nach Ihrer Option) jeder spteren Version.\n\n    Die Verffentlichung dieses Programms erfolgt in der Hoffnung, da es Ihnen\n    von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die\n    implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FR EINEN\n    BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License.\n\n    Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem\n    Programm erhalten haben. Falls nicht, schreiben Sie an die Free Software\n    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA.\n\nFgen Sie auch einen kurzen Hinweis hinzu, wie Sie elektronisch und per Brief erreichbar sind.\n\nWenn Ihr Programm interaktiv ist, sorgen Sie dafr, da es nach dem Start einen kurzen Vermerk ausgibt:\n\n    version 69, Copyright (C) [Jahr]  [Name des Autors]\n    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type\n    'show w'. This is free software, and you are welcome to redistribute it under\n    certain conditions; type 'show c' for details.\n\nAuf Deutsch:\n\n    Version 69, Copyright (C) [Jahr]  [Name des Autors] Fr Gnomovision besteht\n    KEINERLEI GARANTIE; geben Sie \"show w\" fr Details ein. Gnonovision ist\n    freie Software, die Sie unter bestimmten Bedingungen weitergeben drfen;\n    geben Sie \"show c\" fr Details ein.\n\nDie hypothetischen Kommandos \"show w\" und \"show c\" sollten die entsprechenden Teile der GNU-GPL anzeigen. Natrlich knnen die von Ihnen verwendeten Kommandos anders heien als \"show w\" und \"show c\"; es knnten auch Mausklicks oder Menpunkte sein - was immer am besten in Ihr Programm pat.\n\nSoweit vorhanden, sollten Sie auch Ihren Arbeitgeber (wenn Sie als Programmierer arbeiten) oder Ihre Schule einen Copyright-Verzicht fr das Programm unterschreiben lassen. Hier ein Beispiel. Die Namen mssen Sie natrlich ndern.\n\n    Yoyodyne, Inc., hereby disclaims all copyright interest in the program 'Gnomovision'\n    (which makes passes at compilers) written by James Hacker.\n\n    [Unterschrift von Ty Coon], 1 April 1989\n    Ty Coon, President of Vice\n\nAuf Deutsch:\n\n    Die Yoyodyne GmbH erhebt keinen urheberrechtlichen Anspruch auf das von James\n    Hacker geschriebene Programm \"Gnomovision\" (einem Schrittmacher fr Compiler).\n\n    [Unterschrift von Ty Coon], 1. April 1989\n    Ty Coon, Vizeprsident\n\nDiese General Public License gestattet nicht die Einbindung des Programms in proprietre Programme. Ist Ihr Programm eine Funktionsbibliothek, so kann es sinnvoller sein, das Binden proprietrer Programme mit dieser Bibliothek zu gestatten. Wenn Sie dies tun wollen, sollten Sie die GNU Lesser General Public License anstelle dieser Lizenz verwenden.\n"
  },
  {
    "path": "distrib/gpl-el.txt",
    "content": "         \nGNU (GNU GPL)  .      \n (Free Software Foundation)      \n        \nGNU-          (GNU GPL).\n,          \n      GNU GPL.\n\nThis is an unofficial translation of the GNU General Public License into greek. It was not published by the Free Software Foundation, and does not legally state the distribution terms for software that uses the GNU GPL-only the original English text of the GNU GPL does that. However, we hope that this translation will help greek speakers understand the GNU GPL better.\n\n\n\t\t\t    GNU\n\n\t\t\t\t 2,  1991\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n         \n     ,       .\n\n\t\t\t\t\t\n\n                       .   ,      GNU                     --            .                 (Free Software Foundation),               .  (               GNU.)             .\n\n     ,     , \n  .                      (  ,   ,     ),          ,   ,                --           .\n\n       ,     \n                  .                   .\n\n   ,      ,  \n  ,            .         ,    ,   .            ,        .\n\n        : (1)     (2)     ,       ,  /   .\n\n  ,         ,               .            ,              ,              .\n\n  ,          .              ,       .       ,              ,       .\n\n        ,   .\n\n\t\t        GNU\n      ,   \n\n  0.            \n     ,                   .    \"\", ,       ,    \"   \"                :   ,           ,      /    .  (   ,         \"\".)            \"/\".\n\n    ,            -     .         ,                   (         ).           .\n\n  1.                 ,    ,    :     ,   ,           -                  - , ,                  .\n\n            ,    ,    ,    .\n\n  2.              ,          ,              1  ,           :\n\n    )                       .\n\n    )            ,            ,     ,  ,     ,       .\n\n    )       ,     ,    ,           ,         ,                      (, ,   )                ,               .  (:              ,             .)\n\n        .            ,              ,              ,       .                 ,           ,              ,       ,        .\n\n,                          -  , ,                  .\n\n,      ,     ,     (       )       ,          .\n\n  3.        (     ,     2)       ,       1  2  ,           :\n\n    )     ,   ,                    1  2 ,       - ,\n    )     ,                 ,     ,         ,          1  2  ,      - ,\n\n    )                .  (                         ,     [] .)\n\n                .     ,               ,      ,                .  ,   ,             (  ,    )      (,  ...)         ,         .\n\n          \n      ,   \n                 -      \n         .\n\n  4.    , ,               .  ,    , ,                    .\n,             ,    ,   ,    \n       .\n\n  5.         ,     .  ,                    .        ,      .  ,          (      ),      ,              ,           .\n\n  6.       (     ),        ,             .                 .              .\n\n  7. ,                  (    ),    (   ,     )        ,           .                            , ,  ,         .   ,                       ,                           .\n\n                ,                .\n\n           \n              .               ,          .                ,       .     /           ,           .\n\n         ,       .\n\n  8.    /        ,            ,       ,           ,        ,    ,              .    ,               .\n\n  9.     (Free Software Foundation)        /       .              ,      ,\n      .\n\n       .    \n      ,     ,   \"  \",                            (Free Software Foundation).        \n  ,              .\n\n  10.          \n,       ,            .              (Free Software Foundation),        (     ).                         ,              .\n\n                             \n\n  11.         ,      ,       .       ,     /      \" \"    ,    ,   , ,      .               .      ,          .\n\n  12.   ,           ,     ,          /       ,        ,    , ,                  (, ,         ,          ,         ),                 .\n\n\n\t\t          \n\n\n\t          \n\n             \n   ,            ,              .\n     ,      .             ,          -           \" \"          .\n\n    <              .>\n    Copyright (C) <>  < >\n\n         .    /           GNU (GNU General Public License),         (Free Software Foundation) -    2  ,  (' )   .\n\n              ,      -         .          GNU (GNU General Public License).\n\n                GNU (GNU General Public License)     .  ,        (Free Software Foundation), Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n\n,                   .\n\n    ,                 :\n\n    <_>  <_>, Copyright (C) <> <_>\n     <_>    .    `show w'.\n        ,         .  `show c'  .\n\n   `show w'  `show c'            .           `show w'  `show c'.               --     .\n\n  ,          (   )    ,  ,    \"   \" (copyright disclaimer)   .\n     ,   :\n\n   <_/>         <_>',      <_>.\n\n  <__/>, <, >\n\n\n               .        ,            .    ,        GNU (GNU Library General Public License)    .\n"
  },
  {
    "path": "distrib/gpl-fr.txt",
    "content": "GPL Introduction\n\nThis is an unofficial translation of the GNU General Public License into\nFrench. It was not published by the Free Software Foundation, and does not\nlegally state the distribution terms for software that uses the GNU GPL--only\nthe original English text of the GNU GPL does that. However, we hope that this\ntranslation will help French speakers understand the GNU GPL better.\n\nVoici (http://www.linux-france.org/article/these/gpl.html) une adaptation non\nofficielle de la Licence Publique Gnrale du projet GNU. Elle n'a pas t\npublie par la Free Software Foundation et son contenu n'a aucune porte lgale\ncar seule la version anglaise de ce document dtaille le mode de distribution\ndes logiciels sous GNU GPL. Nous esprons cependant qu'elle permettra aux\nfrancophones de mieux comprendre la GPL.\n\n                      Licence Publique Gnrale GNU\n                      Version 2, Juin 1991\n\n  Copyright  Free Software Foundation, Inc.\n              59 Temple Place, Suite 330, Boston, MA 02111-1307\n  tats-Unis, 1989, 1991.\n\nLa copie et la distribution de copies exactes de ce document sont autorises,\nmais aucune modification n'est permise.\n\n                              Prambule\n\nLes licences d'utilisation de la plupart des programmes sont dfinies pour\nlimiter ou supprimer toute libert  l'utilisateur.  l'inverse, la Licence\nPublique Gnrale (General Public License) est destine  vous garantir la\nlibert de partager et de modifier les logiciels libres, et de s'assurer que\nces logiciels sont effectivement accessibles  tout utilisateur.\n\nCette Licence Publique Gnrale s'applique  la plupart des programmes de la\nFree Software Foundation, comme  tout autre programme dont l'auteur l'aura\ndcid (d'autres logiciels de la FSF sont couverts pour leur part par la\nLicence Publique Gnrale pour Bibliothques GNU (LGPL)). Vous pouvez aussi\nappliquer les termes de cette Licence  vos propres programmes, si vous le\ndsirez.\n\nLibert des logiciels ne signifie pas ncessairement gratuit. Notre Licence\nest conue pour vous assurer la libert de distribuer des copies des\nprogrammes, gratuitement ou non, de recevoir le code source ou de pouvoir\nl'obtenir, de modifier les programmes ou d'en utiliser des lments dans de\nnouveaux programmes libres, en sachant que vous y tes autoris.\n\nAfin de garantir ces droits, nous avons d introduire des restrictions\ninterdisant  quiconque de vous les refuser ou de vous demander d'y renoncer.\nCes restrictions vous imposent en retour certaines obligations si vous\ndistribuez ou modifiez des copies de programmes protgs par la Licence. En\nd'autre termes, il vous incombera en ce cas de :\n\ntransmettre aux destinataires tous les droits que vous possdez, expdier aux\ndestinataires le code source ou bien tenir celui-ci  leur disposition, leur\nremettre cette Licence afin qu'ils prennent connaissance de leurs droits.  Nous\nprotgeons vos droits de deux faons : d'abord par le copyright du logiciel,\nensuite par la remise de cette Licence qui vous autorise lgalement  copier,\ndistribuer et/ou modifier le logiciel.\n\nEn outre, pour protger chaque auteur ainsi que la FSF, nous affirmons\nsolennellement que le programme concern ne fait l'objet d'aucune garantie. Si\nun tiers le modifie puis le redistribue, tous ceux qui en recevront une copie\ndoivent savoir qu'il ne s'agit pas de l'original afin qu'une copie dfectueuse\nn'entache pas la rputation de l'auteur du logiciel.\n\nEnfin, tout programme libre est sans cesse menac par des dpts de brevets.\nNous souhaitons  tout prix viter que des distributeurs puissent dposer des\nbrevets sur les Logiciels Libres pour leur propre compte. Pour viter cela,\nnous stipulons bien que tout dpt ventuel de brevet doit accorder\nexpressment  tout un chacun le libre usage du produit.\n\nLes dispositions prcises et les conditions de copie, de distribution et de\nmodification de nos logiciels sont les suivantes :\n\nStipulations et conditions relatives  la copie, la distribution et la\nmodification\n\n--------------------------------------------------------------------------------\n\nArticle 0\n\nLa prsente Licence s'applique  tout Programme (ou autre travail) o figure\nune note, place par le dtenteur des droits, stipulant que ledit Programme ou\ntravail peut tre distribu selon les termes de la prsente Licence. Le terme\nProgramme dsigne aussi bien le Programme lui-mme que tout travail qui en est\ndriv selon la loi, c'est--dire tout ouvrage reproduisant le Programme ou une\npartie de celui-ci,  l'identique ou bien modifi, et/ou traduit dans une autre\nlangue (la traduction est considre comme une modification). Chaque personne\nconcerne par la Licence Publique Gnrale sera dsigne par le terme Vous.\n\nLes activits autres que copie, distribution et modification ne sont pas\ncouvertes par la prsente Licence et sortent de son cadre. Rien ne restreint\nl'utilisation du Programme et les donnes issues de celui-ci ne sont couvertes\nque si leur contenu constitue un travail bas sur le logiciel (indpendemment\ndu fait d'avoir t ralis en lanant le Programme). Tout dpend de ce que le\nProgramme est cens produire.\n\n--------------------------------------------------------------------------------\n\nArticle 1.\n\nVous pouvez copier et distribuer des copies conformes du code source du\nProgramme, tel que Vous l'avez reu, sur n'importe quel support,  condition de\nplacer sur chaque copie un copyright appropri et une restriction de garantie,\nde ne pas modifier ou omettre toutes les stipulations se rfrant  la prsente\nLicence et  la limitation de garantie, et de fournir avec toute copie du\n\nProgramme un exemplaire de la Licence.\n\nVous pouvez demander une rtribution financire pour la ralisation de la copie\net demeurez libre de proposer une garantie assure par vos soins, moyennant\nfinances.\n\n--------------------------------------------------------------------------------\n\nArticle 2.\n\nVous pouvez modifier votre copie ou vos copies du Programme ou partie de\ncelui-ci, ou d'un travail bas sur ce Programme, et copier et distribuer ces\nmodifications selon les termes de l'article 1,  condition de Vous conformer\ngalement aux conditions suivantes :\n\n  a) Ajouter aux fichiers modifis l'indication trs claire des modifications\n     effectues, ainsi que la date de chaque changement.\n\n  b) Distribuer sous les termes de la Licence Publique Gnrale l'ensemble de\n     toute ralisation contenant tout ou partie du Programme, avec ou sans\n     modifications.\n\n  c) Si le Programme modifi lit des commandes de manire interactive lors de\n     son excution, faire en sorte qu'il affiche, lors d'une invocation\n     ordinaire, le copyright appropri en indiquant clairement la limitation de\n     garantie (ou la garantie que Vous Vous engagez  fournir Vous-mme), qu'il\n     stipule que tout utilisateur peut librement redistribuer le Programme selon\n     les conditions de la Licence Publique Gnrale GNU, et qu'il montre  tout\n     utilisateur comment lire une copie de celle-ci (exception : si le Programme\n     original est interactif mais n'affiche pas un tel message en temps normal,\n     tout travail driv de ce Programme ne sera pas non plus contraint de\n     l'afficher).\n\nToutes ces conditions s'appliquent  l'ensemble des modifications. Si des\nlments identifiables de ce travail ne sont pas drivs du Programme et\npeuvent tre raisonnablement considrs comme indpendants, la prsente Licence\nne s'applique pas  ces lments lorsque Vous les distribuez seuls. Mais, si\nVous distribuez ces mmes lments comme partie d'un ensemble cohrent dont le\nreste est bas sur un Programme soumis  la Licence, ils lui sont galement\nsoumis, et la Licence s'tend ainsi  l'ensemble du produit, quel qu'en soit\nl'auteur.\n\nCet article n'a pas pour but de s'approprier ou de contester vos droits sur un\ntravail entirement ralis par Vous, mais plutt d'ouvrir droit  un contrle\nde la libre distribution de tout travail driv ou collectif bas sur le\nProgramme.\n\nEn outre, toute fusion d'un autre travail, non bas sur le Programme, avec le\nProgramme (ou avec un travail driv de ce dernier), effectue sur un support\nde stockage ou de distribution, ne fait pas tomber cet autre travail sous le\ncontrle de la Licence.\n\n--------------------------------------------------------------------------------\n\nArticle 3.\n\nVous pouvez copier et distribuer le Programme (ou tout travail driv selon les\nconditions nonces dans l'article 1) sous forme de code objet ou excutable,\nselon les termes des articles 0 et 1,  condition de respecter l'une des\nclauses suivantes :\n\n  a) Fournir le code source complet du Programme, sous une forme lisible par\n     un ordinateur et selon les termes des articles 0 et 1, sur un support\n     habituellement utilis pour l'change de donnes ; ou,\n\n  b) Faire une offre crite, valable pendant au moins trois ans, prvoyant de\n     donner  tout tiers qui en fera la demande une copie, sous forme lisible\n     par un ordinateur, du code source correspondant, pour un tarif n'excdant\n     pas le cot de la copie, selon les termes des articles 0 et 1, sur un\n     support couramment utilis pour l'change de donnes informatiques ; ou,\n\n  c) Informer le destinataire de l'endroit o le code source peut tre obtenu\n     (cette solution n'est recevable que dans le cas d'une distribution non\n     commerciale, et uniquement si Vous avez reu le Programme sous forme de\n     code objet ou excutable avec l'offre prvue  l'alina b ci-dessus).\n\nLe code source d'un travail dsigne la forme de cet ouvrage sous laquelle les\nmodifications sont les plus aises. Sont ainsi dsigns la totalit du code\nsource de tous les modules composant un Programme excutable, de mme que tout\nfichier de dfinition associ, ainsi que les scripts utiliss pour effectuer la\ncompilation et l'installation du Programme excutable. Toutefois,\nl'environnement standard de dveloppement du systme d'exploitation mis en\noeuvre (source ou binaire) -- compilateurs, bibliothques, noyau, etc. --\nconstitue une exception, sauf si ces lments sont diffuss en mme temps que\nle Programme excutable.\n\nSi la distribution de l'excutable ou du code objet consiste  offrir un accs\npermettant de copier le Programme depuis un endroit particulier, l'offre d'un\naccs quivalent pour se procurer le code source au mme endroit est considr\ncomme une distribution de ce code source, mme si l'utilisateur choisit de ne\npas profiter de cette offre.\n\n--------------------------------------------------------------------------------\n\nArticle 4.\n\nVous ne pouvez pas copier, modifier, cder, dposer ou distribuer le Programme\nd'une autre manire que l'autorise la Licence Publique Gnrale. Toute\ntentative de ce type annule immdiatement vos droits d'utilisation du Programme\nsous cette Licence. Toutefois, les tiers ayant reu de Vous des copies du\nProgramme ou le droit d'utiliser ces copies continueront  bnficier de leur\ndroit d'utilisation tant qu'ils respecteront pleinement les conditions de la\nLicence.\n\n--------------------------------------------------------------------------------\n\nArticle 5.\n\nNe l'ayant pas signe, Vous n'tes pas oblig d'accepter cette Licence.\nCependant, rien d'autre ne Vous autorise  modifier ou distribuer le Programme\nou quelque travaux drivs : la loi l'interdit tant que Vous n'acceptez pas les\ntermes de cette Licence. En consquence, en modifiant ou en distribuant le\nProgramme (ou tout travail bas sur lui), Vous acceptez implicitement tous les\ntermes et conditions de cette Licence.\n\n--------------------------------------------------------------------------------\n\nArticle 6.\n\nLa diffusion d'un Programme (ou de tout travail driv) suppose l'envoi\nsimultan d'une licence autorisant la copie, la distribution ou la modification\ndu Programme, aux termes et conditions de la Licence. Vous n'avez pas le droit\nd'imposer de restrictions supplmentaires aux droits transmis au destinataire.\nVous n'tes pas responsable du respect de la Licence par un tiers.\n\n\n--------------------------------------------------------------------------------\n\nArticle 7.\n\nSi,  la suite d'une dcision de Justice, d'une plainte en contrefaon ou pour\ntoute autre raison (lie ou non  la contrefaon), des conditions Vous sont\nimposes (que ce soit par ordonnance, accord amiable ou autre) qui se rvlent\nincompatibles avec les termes de la prsente Licence, Vous n'tes pas pour\nautant dgag des obligations lies  celle-ci : si Vous ne pouvez concilier\nvos obligations lgales ou autres avec les conditions de cette Licence, Vous ne\ndevez pas distribuer le Programme.\n\nSi une partie quelconque de cet article est invalide ou inapplicable pour\nquelque raison que ce soit, le reste de l'article continue de s'appliquer et\nl'intgralit de l'article s'appliquera en toute autre circonstance.\n\nLe prsent article n'a pas pour but de Vous pousser  enfreindre des droits ou\ndes dispositions lgales ni en contester la validit ; son seul objectif est de\nprotger l'intgrit du systme de distribution du Logiciel Libre. De\nnombreuses personnes ont gnreusement contribu  la large gamme de Programmes\ndistribue de cette faon en toute confiance ; il appartient  chaque\nauteur/donateur de dcider de diffuser ses Programmes selon les critres de son\nchoix.\n\n--------------------------------------------------------------------------------\n\nArticle 8.\n\nSi la distribution et/ou l'utilisation du Programme est limite dans certains\npays par des brevets ou des droits sur des interfaces, le dtenteur original\ndes droits qui place le Programme sous la Licence Publique Gnrale peut\najouter explicitement une clause de limitation gographique excluant ces pays.\nDans ce cas, cette clause devient une partie intgrante de la Licence.\n\n--------------------------------------------------------------------------------\n\nArticle 9.\n\nLa Free Software Foundation se rserve le droit de publier priodiquement des\nmises  jour ou de nouvelles versions de la Licence. Rdiges dans le mme\nesprit que la prsente version, elles seront cependant susceptibles d'en\nmodifier certains dtails  mesure que de nouveaux problmes se font jour.\n\nChaque version possde un numro distinct. Si le Programme prcise un numro de\nversion de cette Licence et  toute version ultrieure , Vous avez le choix de\nsuivre les termes et conditions de cette version ou de toute autre version plus\nrcente publie par la Free Software Foundation. Si le Programme ne spcifie\naucun numro de version, Vous pouvez alors choisir l'une quelconque des\nversions publies par la Free Software Foundation.\n\n--------------------------------------------------------------------------------\n\nArticle 10.\n\nSi Vous dsirez incorporer des lments du Programme dans d'autres Programmes\nlibres dont les conditions de distribution diffrent, Vous devez crire \nl'auteur pour lui en demander la permission. Pour ce qui est des Programmes\ndirectement dposs par la Free Software Foundation, crivez-nous : une\nexception est toujours envisageable. Notre dcision sera base sur notre\nvolont de prserver la libert de notre Programme ou de ses drivs et celle\nde promouvoir le partage et la rutilisation du logiciel en gnral.\n\n--------------------------------------------------------------------------------\n                         LIMITATION DE GARANTIE\n\nArticle 11.\n\nParce que l'utilisation de ce Programme est libre et gratuite, aucune garantie\nn'est fournie, comme le permet la loi. Sauf mention crite, les dtenteurs du\ncopyright et/ou les tiers fournissent le Programme en l'tat, sans aucune sorte\nde garantie explicite ou implicite, y compris les garanties de\ncommercialisation ou d'adaptation dans un but particulier. Vous assumez tous\nles risques quant  la qualit et aux effets du Programme. Si le Programme est\ndfectueux, Vous assumez le cot de tous les services, corrections ou\nrparations ncessaires.\n\n--------------------------------------------------------------------------------\n\nArticle 12.\n\nSauf lorsqu'explicitement prvu par la Loi ou accept par crit, ni le\ndtenteur des droits, ni quiconque autoris  modifier et/ou redistribuer le\nProgramme comme il est permis ci-dessus ne pourra tre tenu pour responsable de\ntout dommage direct, indirect, secondaire ou accessoire (pertes financires\ndues au manque  gagner,  l'interruption d'activits ou  la perte de donnes,\netc., dcoulant de l'utilisation du Programme ou de l'impossibilit d'utiliser\ncelui-ci).\n\n                      FIN DES TERMES ET CONDITIONS\n--------------------------------------------------------------------------------\n           Comment appliquer ces directives  vos nouveaux programmes\n\nSi vous dveloppez un nouveau programme et dsirez en faire bnficier tout un\nchacun, la meilleure mthode est d'en faire un Logiciel Libre que tout le monde\npourra redistribuer et modifier selon les termes de la Licence Publique\nGnrale.\n\nPour cela, insrez les indications suivantes dans votre programme (il est\nprfrable et plus sr de les faire figurer au dbut de chaque fichier source ;\ndans tous les cas, chaque module source devra comporter au minimum la ligne de\n copyright  et indiquer o rsident toutes les autres indications) :\n\n--------------------------------------------------------------------------------\n  ((une ligne pour donner le nom du programme et donner une ide de sa finalit))\n  Copyright (C) 19xx ((nom de l'auteur))\n\n  Ce programme est libre, vous pouvez le redistribuer et/ou le modifier selon\n  les termes de la Licence Publique Gnrale GNU publie par la Free Software\n  Foundation (version 2 ou bien toute autre version ultrieure choisie par\n  vous).\n\n  Ce programme est distribu car potentiellement utile, mais SANS AUCUNE\n  GARANTIE, ni explicite ni implicite, y compris les garanties de\n  commercialisation ou d'adaptation dans un but spcifique. Reportez-vous\n   la Licence Publique Gnrale GNU pour plus de dtails.\n\n  Vous devez avoir reu une copie de la Licence Publique Gnrale GNU en mme\n  temps que ce programme ; si ce n'est pas le cas, crivez  la Free Software\n  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,\n  tats-Unis.\n\n--------------------------------------------------------------------------------\n\nAjoutez galement votre adresse lectronique, le cas chant, ainsi que votre\nadresse postale.\n\nSi le programme est interactif, faites-lui afficher un court avertissement du\ntype de celui-ci  chaque invocation :\n\n--------------------------------------------------------------------------------\n\n  ...(nom du programme) version 69, Copyright (C) 19aa nom de l'auteur\n  ...(nom du programme) est fourni sans AUCUNE GARANTIE.\n  Pour plus de dtails, tapez `g'.\n\n  Ce programme est libre et vous tes encourag  le redistribuer sous\n  certaines conditions ; tapez `c' pour plus de dtails.\n\n--------------------------------------------------------------------------------\n\nLes commandes hypothtiques `g' et `c' doivent afficher les sections\nappropries de la Licence Publique Gnrale GNU. Bien entendu, vous pouvez\nimplanter ces commandes comme bon vous semble : options dans un menu, ou bien\naccessibles d'un clic de souris, etc., tout dpend de votre programme.\n\nSi vous officiez en tant que programmeur, n'omettez pas de demander  votre\nemployeur, votre tablissement scolaire ou autres de signer une dcharge\nstipulant leur renoncement aux droits qu'ils pourraient avoir sur le programme :\n\n--------------------------------------------------------------------------------\n  ...((employeur, cole...)) dclare par la prsente ne pas revendiquer de\n  droits sur le programme  (nom du programme)  ralis par ...((nom de\n  l'auteur)).\n\n  ((signature du responsable)), ...((date)), ...((nom et qualit du responsable)).\n\nLa Licence Publique Gnrale ne permet pas d'inclure votre programme dans des\nlogiciels sous licence commerciale spcifique. Si votre programme est une\nfonction de bibliothque, vous jugerez probablement plus judicieux de le faire\nrelever de la Licence Gnrale de Bibliothque GNU (LGPL) plutt que de la\nprsente.\n\n--------------------------------------------------------------------------------\nLast modified: Tue Sep 29 22:41:45 MET DST 1998\n--------------------------------------------------------------------------------\n"
  },
  {
    "path": "distrib/gpl-it.txt",
    "content": "Questa  una traduzione  italiana non ufficiale della Licenza Pubblica\nGenerica GNU.  Non   pubblicata dalla Free Software  Foundation e non\nha  valore  legale  nell'esprimere  i  termini  di  distribuzione  del\nsoftware che usa la licenza GPL. Solo la versione originale in inglese\ndella  licenza ha  valore legale.  Ad ogni  modo, speriamo  che questa\ntraduzione  aiuti le  persone di  lingua italiana  a capire  meglio il\nsignificato della licenza GPL.\n\n    This is  an unofficial translation  of  the GNU General Public\n    License   into Italian.  It  was  not   published by the  Free\n    Software  Foundation,  and   does  not  legally    state   the\n    distribution terms for software   that uses the  GNU GPL--only\n    the original English text of the GNU GPL  does that.  However,\n    we    hope that this translation   will  help Italian speakers\n    understand the GNU GPL better.\n\n\n\n        LICENZA PUBBLICA GENERICA (GPL) DEL PROGETTO GNU\n                  Versione 2, Giugno 1991\n\n       Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\nTraduzione curata  da gruppo  Pluto, da ILS  e dal gruppo  italiano di\ntraduzione GNU.  Ultimo aggiornamento 19 aprile 2000.\n\nChiunque pu copiare e distribuire copie letterali di questo documento\ndi licenza, ma non ne  permessa la modifica.\n\n                           Preambolo\n\nLe  licenze  della maggior  parte  dei  programmi  hanno lo  scopo  di\ntogliere  all'utente  la  libert   di  condividere  e  modificare  il\nprogramma stesso. Viceversa, la Licenza Pubblica Generica GNU  intesa\na garantire la libert di condividere e modificare il software libero,\nal fine  di assicurare che i  programmi siano liberi per  tutti i loro\nutenti.   Questa Licenza  si  applica alla  maggioranza dei  programmi\ndella Free Software Foundation e  ad ogni altro programma i cui autori\nhanno deciso  di usare questa  Licenza.  Alcuni altri  programmi della\nFree Software  Foundation sono  invece coperti dalla  Licenza Pubblica\nGenerica  Minore.  Chiunque  pu  usare questa  Licenza  per i  propri\nprogrammi.\n\nQuando si  parla di software  libero (free software), ci  si riferisce\nalla libert,  non al prezzo.   Le nostre Licenze  (la GPL e  la LGPL)\nsono  progettate per  assicurarsi  che ciascuno  abbia  la libert  di\ndistribuire copie del  software libero (e farsi pagare  per questo, se\nvuole), che ciascuno riceva il codice sorgente o che lo possa ottenere\nse lo  desidera, che ciascuno  possa modificare il programma  o usarne\ndelle parti in nuovi programmi  liberi e che ciascuno sappia di potere\nfare queste cose.\n\nPer proteggere i diritti  dell'utente, abbiamo bisogno di creare delle\nrestrizioni  che vietino  a chiunque  di  negare questi  diritti o  di\nchiedere  di rinunciarvi.   Queste restrizioni  si traducono  in certe\nresponsabilit per  chi distribuisce copie  del software e per  chi lo\nmodifica.\n\nPer esempio,  chi distribuisce copie  di un programma coperto  da GPL,\nsia gratis sia in cambio di un compenso, deve concedere ai destinatari\ntutti  i  diritti che  ha  ricevuto.   Deve  anche assicurarsi  che  i\ndestinatari ricevano  o possano ottenere  il codice sorgente.   E deve\nmostrar loro queste condizioni di  licenza, in modo che essi conoscano\ni propri diritti.\n\nProteggiamo  i diritti  dell'utente in  due modi:  (1)  proteggendo il\nsoftware  con un  copyright,  e (2)  offrendo  una licenza  che dia il\npermesso legale di copiare, distribuire e modificare il Programma.\n\nInoltre, per proteggere ogni autore e noi stessi, vogliamo assicurarci\nche ognuno capisca che non ci sono garanzie per i programmi coperti da\nGPL.    Se  il  programma   viene  modificato   da  qualcun   altro  e\nridistribuito, vogliamo che gli  acquirenti sappiano che ci che hanno\nnon  l'originale,  in modo che ogni problema  introdotto da altri non\nsi rifletta sulla reputazione degli autori originari.\n\nInfine, ogni programma libero   costantemente minacciato dai brevetti\nsui programmi.  Vogliamo evitare il pericolo che chi ridistribuisce un\nprogramma libero ottenga la propriet di brevetti, rendendo in pratica\nil programma  cosa di sua propriet.  Per  prevenire questa evenienza,\nabbiamo chiarito  che ogni brevetto  debba essere concesso  in licenza\nd'uso a chiunque, o non avere alcuna restrizione di licenza d'uso.\n\nSeguono  i  termini   e  le  condizioni  precisi  per   la  copia,  la\ndistribuzione e la modifica.\n\n                  LICENZA PUBBLICA GENERICA GNU\n  TERMINI E CONDIZIONI PER LA COPIA, LA DISTRIBUZIONE E LA MODIFICA\n\n  0.  Questa Licenza  si applica  a ogni programma  o altra  opera che\ncontenga una  nota da parte del  detentore del copyright  che dica che\ntale opera  pu essere distribuita  sotto i termini di  questa Licenza\nPubblica Generica.  Il termine \"Programma\" nel seguito si riferisce ad\nogni programma  o opera cos  definita, e l'espressione  \"opera basata\nsul  Programma\" indica  sia il  Programma sia  ogni  opera considerata\n\"derivata\" in base alla legge sul copyright; in altre parole, un'opera\ncontenente il Programma o una  porzione di esso, sia letteralmente sia\nmodificato  o tradotto  in  un'altra  lingua.  Da  qui  in avanti,  la\ntraduzione   in ogni  caso considerata  una \"modifica\".   Vengono ora\nelencati i diritti dei beneficiari della licenza.\n\nAttivit diverse  dalla copiatura,  distribuzione e modifica  non sono\ncoperte  da questa Licenza  e sono  al di  fuori della  sua influenza.\nL'atto di  eseguire il  Programma non viene  limitato, e  l'output del\nprogramma    coperto da  questa  Licenza  solo  se il  suo  contenuto\ncostituisce un'opera basata sul Programma (indipendentemente dal fatto\nche sia stato creato eseguendo il Programma).  In base alla natura del\nProgramma il suo output pu essere o meno coperto da questa Licenza.\n\n  1.     lecito  copiare  e  distribuire copie  letterali  del codice\nsorgente del Programma cos  come viene ricevuto, con qualsiasi mezzo,\na  condizione  che venga  riprodotta  chiaramente  su  ogni copia  una\nappropriata  nota  di copyright  e  di  assenza  di garanzia;  che  si\nmantengano intatti tutti i  riferimenti a questa Licenza e all'assenza\ndi ogni garanzia;  che si dia a ogni  altro destinatario del Programma\nuna copia di questa Licenza insieme al Programma.\n\n possibile richiedere un pagamento per il trasferimento fisico di una\ncopia  del   Programma,    anche  possibile   a  propria  discrezione\nrichiedere un pagamento in cambio di una copertura assicurativa.\n\n  2.   lecito modificare la propria  copia o copie  del  Programma, o\nparte di esso, creando perci un'opera basata sul Programma, e copiare\no distribuire  tali  modifiche o tale  opera  secondo  i  termini  del\nprecedente comma 1, a patto  che siano soddisfatte tutte le condizioni\nche seguono:\n\n    a) Bisogna indicare  chiaramente nei file  che si tratta  di copie\n    modificate e la data di ogni modifica.\n\n    b) Bisogna fare  in modo che ogni opera  distribuita o pubblicata,\n    che in parte o nella sua  totalit derivi dal Programma o da parti\n    di esso, sia  concessa nella  sua interezza in licenza gratuita ad\n    ogni terza parte, secondo i termini di questa Licenza.\n\n    c)   Se   normalmente  il   programma  modificato   legge  comandi\n    interattivamente quando  viene eseguito, bisogna fare  in modo che\n    all'inizio  dell'esecuzione  interattiva  usuale, esso  stampi  un\n    messaggio  contenente  una  appropriata  nota di  copyright  e  di\n    assenza di garanzia (oppure che specifichi il tipo di garanzia che\n    si offre).  Il messaggio deve inoltre specificare che chiunque pu\n    ridistribuire il  programma alle  condizioni qui descritte  e deve\n    indicare come  reperire questa Licenza.   Se per il  programma di\n    partenza   interattivo ma normalmente non  stampa tale messaggio,\n    non occorre che un'opera basata sul Programma lo stampi.\n\nQuesti requisiti si applicano  all'opera modificata nel suo complesso.\nSe sussistono parti identificabili dell'opera modificata che non siano\nderivate   dal  Programma   e  che   possono   essere  ragionevolmente\nconsiderate  lavori  indipendenti,  allora  questa Licenza  e  i  suoi\ntermini  non  si  applicano  a  queste  parti  quando  queste  vengono\ndistribuite  separatamente. Se per  queste parti  vengono distribuite\nall'interno di  un prodotto  che  un'opera  basata sul  Programma, la\ndistribuzione  di quest'opera  nella sua  interezza deve  avvenire nei\ntermini di questa Licenza, le  cui norme nei confronti di altri utenti\nsi  estendono all'opera  nella sua  interezza,  e quindi  ad ogni  sua\nparte, chiunque ne sia l'autore.\n\nQuindi, non  nelle intenzioni di questa sezione accampare diritti, n\ncontestare diritti su opere  scritte interamente da altri; l'intento \npiuttosto  quello   di  esercitare   il  diritto  di   controllare  la\ndistribuzione di opere derivati dal Programma o che lo contengano.\n\nInoltre,  la  semplice  aggregazione  di  un'opera  non  derivata  dal\nProgramma col Programma o con un'opera da esso derivata su di un mezzo\ndi  memorizzazione o di  distribuzione, non   sufficente  a includere\nl'opera non derivata nell'ambito di questa Licenza.\n\n  3.  lecito copiare e distribuire il Programma (o un'opera basata su\ndi esso,  come espresso al  comma 2) sotto  forma di codice  oggetto o\neseguibile secondo i  termini dei precedenti commi 1 e  2, a patto che\nsi applichi una delle seguenti condizioni:\n\n    a) Il Programma sia corredato del codice sorgente completo, in una\n    forma  leggibile  da  calcolatore,  e tale  sorgente  sia  fornito\n    secondo  le regole  dei precedenti  commi  1 e  2 su  di un  mezzo\n    comunemente usato per lo scambio di programmi.\n\n    b) Il Programma sia accompagnato da un'offerta scritta, valida per\n    almeno tre  anni, di  fornire a chiunque  ne faccia  richiesta una\n    copia  completa del  codice sorgente,  in una  forma  leggibile da\n    calcolatore, in cambio  di un compenso non superiore  al costo del\n    trasferimento  fisico  di  tale  copia, che  deve  essere  fornita\n    secondo  le regole  dei precedenti  commi  1 e  2 su  di un  mezzo\n    comunemente usato per lo scambio di programmi.\n\n    c) Il Programma sia accompagnato dalle informazioni che sono state\n    ricevute riguardo alla possibilit di ottenere il codice sorgente.\n    Questa alternativa   permessa solo  in caso di  distribuzioni non\n    commerciali e solo se il programma  stato ottenuto sotto forma di\n    codice  oggetto o  eseguibile in  accordo al  precedente  comma B.\n\nPer  \"codice sorgente  completo\"  di  un'opera   si  intende la  forma\npreferenziale  usata  per  modificare  un'opera.    Per  un  programma\neseguibile,  \"codice  sorgente  completo\"  significa tutto  il  codice\nsorgente di tutti i moduli  in esso contenuti, pi ogni file associato\nche  definisca le  interfacce esterne  del programma,  pi  gli script\nusati    per   controllare    la   compilazione    e   l'installazione\ndell'eseguibile. In ogni caso non   necessario che il codice sorgente\nfornito  includa  nulla  che  sia normalmente  distribuito  (in  forma\nsorgente o in formato binario) con i principali componenti del sistema\noperativo sotto cui viene  eseguito il Programma (compilatore, kernel,\ne cos via), a meno che tali componenti accompagnino l'eseguibile.\n\nSe la distribuzione dell'eseguibile  o del codice oggetto  effettuata\nindicando  un luogo dal  quale sia  possibile copiarlo,  permettere la\ncopia del codice sorgente dallo  stesso luogo  considerata una valida\nforma  di  distribuzione del  codice  sorgente,  anche  se copiare  il\nsorgente  facoltativo per l'acquirente.\n\n  4.  Non   lecito copiare, modificare,  sublicenziare, o distribuire\nil  Programma in  modi  diversi da  quelli  espressamente previsti  da\nquesta Licenza.  Ogni tentativo  di copiare, modificare, sublicenziare\no  distribuire  altrimenti il  Programma  non   autorizzato,  e  far\nterminare  automaticamente  i  diritti garantiti  da  questa  Licenza.\nD'altra parte  ogni acquirente  che abbia  ricevuto copie,  o diritti,\ncoperti da questa  Licenza da parte di persone che  violano la Licenza\ncome qui indicato  non vedranno invalidata la loro  Licenza, purch si\ncomportino conformemente ad essa.\n\n  5.   L'acquirente   non    tenuto  ad  accettare   questa  Licenza,\npoich  non  l'ha  firmata.   D'altra  parte  nessun  altro  documento\ngarantisce il  permesso di modificare  o distribuire il Programma  o i\nlavori derivati da esso.  Queste  azioni sono proibite dalla legge per\nchi non accetta questa  Licenza; perci, modificando o distribuendo il\nProgramma o  un'opera  basata  sul programma,  si indica nel  fare ci\nl'accettazione di questa Licenza e quindi di tutti i suoi termini e le\ncondizioni  poste sulla  copia,  la distribuzione  e  la modifica  del\nProgramma o di lavori basati su di esso.\n\n  6. Ogni volta che il Programma o un'opera basata  su di esso vengono\ndistribuiti, l'acquirente riceve  automaticamente una licenza d'uso da\nparte del  licenziatario originale.  Tale licenza regola  la copia, la\ndistribuzione  e la modifica  del Programma  secondo questi  termini e\nqueste  condizioni.   Non     lecito  imporre  restrizioni  ulteriori\nall'acquirente  nel  suo esercizio  dei  diritti  qui garantiti.   Chi\ndistribuisce  programmi  coperti da  questa  Licenza  non e'  comunque\ntenuto a imporre il rispetto di questa Licenza a terzi.\n\n  7.  Se,  come conseguenza  del giudizio  di un  tribunale, o  di una\nimputazione per la violazione di  un brevetto o per ogni altra ragione\n(non   limitatamente  a  questioni   di  brevetti),   vengono  imposte\ncondizioni  che contraddicono  le  condizioni di  questa licenza,  che\nqueste condizioni siano dettate dalla corte, da accordi tra le parti o\naltro,  queste  condizioni non  esimono  nessuno dall'osservazione  di\nquesta Licenza. Se non   possibile distribuire un prodotto in un modo\nche soddisfi simultaneamente gli  obblighi dettati da questa Licenza e\naltri  obblighi  pertinenti,  il   prodotto  non  pu  essere  affatto\ndistribuito.   Per esempio,  se un  brevetto non  permettesse  a tutti\nquelli che  lo ricevono di ridistribuire il  Programma senza obbligare\nal  pagamento   di  diritti,   allora  l'unico  modo   per  soddisfare\ncontemporaneamente il brevetto e  questa Licenza e' di non distribuire\naffatto il Programma.\n\nSe una  qualunque parte di  questo comma   ritenuta non valida  o non\napplicabile  in  una   qualunque  circostanza,  deve  comunque  essere\napplicata l'idea  espressa da questo comma; in  ogni altra circostanza\ninvece deve essere applicato questo comma nel suo complesso.\n\nNon  nelle finalit di  questo comma indurre gli utenti ad infrangere\nalcun brevetto  n ogni altra rivendicazione di  diritti di propriet,\nn di  contestare la validit  di alcuna di queste  rivendicazioni; lo\nscopo di  questo comma   unicamente quello di  proteggere l'integrit\ndel  sistema   di  distribuzione  dei  programmi   liberi,  che  viene\nrealizzato tramite  l'uso di  licenze pubbliche.  Molte  persone hanno\ncontribuito  generosamente alla vasta  gamma di  programmi distribuiti\nattraverso questo sistema,  basandosi sull'applicazione fedele di tale\nsistema.  L'autore/donatore pu decidere  di sua volont se preferisce\ndistribuire il  software avvalendosi di altri  sistemi, e l'acquirente\nnon pu imporre la scelta del sistema di distribuzione.\n\nQuesto comma serve a rendere  il pi chiaro possibile ci che crediamo\nsia una conseguenza del resto di questa Licenza.\n\n  8.  Se in alcuni  paesi la distribuzione o l'uso  del Programma sono\nlimitati da brevetto o dall'uso di interfacce coperte da copyright, il\ndetentore del  copyright originale che pone il  Programma sotto questa\nLicenza pu aggiungere limiti geografici espliciti alla distribuzione,\nper escludere questi paesi dalla  distribuzione stessa, in modo che il\nprogramma  possa essere  distribuito  solo nei  paesi  non esclusi  da\nquesta regola.   In questo  caso i limiti  geografici sono  inclusi in\nquesta Licenza e ne fanno parte a tutti gli effetti.\n\n  9.  All'occorrenza  la  Free   Software  Foundation pu   pubblicare\nrevisioni o nuove versioni  di questa Licenza Pubblica Generica.  Tali\nnuove  versioni saranno  simili a  questa nello  spirito,  ma potranno\ndifferire  nei dettagli  al fine  di  coprire nuovi  problemi e  nuove\nsituazioni.\n\nAd ogni versione viene dato un numero identificativo.  Se il Programma\nasserisce  di essere  coperto da  una particolare  versione  di questa\nLicenza e \"da ogni versione successiva\", l'acquirente pu scegliere se\nseguire le condizioni della  versione specificata o di una successiva.\nSe il  Programma non specifica  quale versione di questa  Licenza deve\napplicarsi,  l'acquirente  pu scegliere  una  qualsiasi versione  tra\nquelle pubblicate dalla Free Software Foundation.\n\n  10.    Se  si desidera incorporare  parti     del Programma in altri\nprogrammi liberi  le cui  condizioni di distribuzione  differiscano da\nqueste,   possibile scrivere  all'autore del Programma  per chiederne\nl'autorizzazione.  Per  il software il cui copyright   detenuto dalla\nFree  Software Foundation,  si scriva  alla Free  Software Foundation;\ntalvolta facciamo eccezioni alle  regole di questa Licenza.  La nostra\ndecisione sar guidata da due finalit: preservare la libert di tutti\ni  prodotti  derivati  dal  nostro  software libero  e  promuovere  la\ncondivisione e il riutilizzo del software in generale.\n\n\n                       NON C' GARANZIA\n\n 11. POICH IL PROGRAMMA  CONCESSO IN USO GRATUITAMENTE, NON\nC' GARANZIA PER IL PROGRAMMA, NEI LIMITI PERMESSI DALLE VIGENTI\nLEGGI. SE NON INDICATO DIVERSAMENTE PER ISCRITTO, IL DETENTORE\nDEL COPYRIGHT E LE ALTRE PARTI FORNISCONO IL PROGRAMMA \"COS\nCOM'\", SENZA ALCUN TIPO DI GARANZIA, N ESPLICITA N IMPLICITA;\nCI COMPRENDE, SENZA LIMITARSI A QUESTO, LA GARANZIA IMPLICITA DI\nCOMMERCIABILIT E UTILIZZABILIT PER UN PARTICOLARE SCOPO.\nL'INTERO RISCHIO CONCERNENTE LA QUALIT E LE PRESTAZIONI DEL\nPROGRAMMA  DELL'ACQUIRENTE. SE IL PROGRAMMA DOVESSE RIVELARSI\nDIFETTOSO, L'ACQUIRENTE SI ASSUME IL COSTO DI OGNI MANUTENZIONE,\nRIPARAZIONE O CORREZIONE NECESSARIA.\n\n 12. N IL DETENTORE DEL COPYRIGHT N ALTRE PARTI CHE POSSONO\nMODIFICARE O RIDISTRIBUIRE IL PROGRAMMA COME PERMESSO IN QUESTA\nLICENZA SONO RESPONSABILI PER DANNI NEI CONFRONTI\nDELL'ACQUIRENTE, A MENO CHE QUESTO NON SIA RICHIESTO DALLE LEGGI\nVIGENTI O APPAIA IN UN ACCORDO SCRITTO. SONO INCLUSI DANNI\nGENERICI, SPECIALI O INCIDENTALI, COME PURE I DANNI CHE\nCONSEGUONO DALL'USO O DALL'IMPOSSIBILIT DI USARE IL PROGRAMMA;\nCI COMPRENDE, SENZA LIMITARSI A QUESTO, LA PERDITA DI DATI, LA\nCORRUZIONE DEI DATI, LE PERDITE SOSTENUTE DALL'ACQUIRENTE O DA\nTERZI E L'INCAPACIT DEL PROGRAMMA A INTERAGIRE CON ALTRI\nPROGRAMMI, ANCHE SE IL DETENTORE O ALTRE PARTI SONO STATE\nAVVISATE DELLA POSSIBILIT DI QUESTI DANNI.\n\n              FINE DEI TERMINI E DELLE CONDIZIONI\n\n      Appendice: come applicare questi termini a nuovi programmi\n\nSe si sviluppa un nuovo programma e lo si vuole rendere della maggiore\nutilit possibile per il pubblico,  la cosa migliore da fare  rendere\ntale  programma  libero,  cosicch  ciascuno  possa  ridistribuirlo  e\nmodificarlo sotto questi termini.\n\nPer fare questo, si inserisca  nel programma la seguente nota. La cosa\nmigliore da fare   mettere la nota all`inizio  di ogni file sorgente,\nper chiarire nel modo  pi efficiente possibile l'assenza di garanzia;\nogni  file   dovrebbe  contenere  almeno   la  nota  di   copyright  e\nl'indicazione di dove trovare l'intera nota.\n\n    <una riga per dire in breve il nome del programma e cosa fa>\n    Copyright (C) <anno> <nome dell'autore>\n\n    Questo  programma   software  libero;   lecito redistribuirlo  o\n    modificarlo secondo i termini  della Licenza Pubblica Generica GNU\n    come  pubblicata dalla Free  Software Foundation; o la versione 2\n    della licenza o (a propria scelta) una versione successiva.\n\n    Questo programma   distribuito nella  speranza che sia  utile, ma\n    SENZA  ALCUNA GARANZIA;  senza  neppure la  garanzia implicita  di\n    NEGOZIABILIT  o di  APPLICABILIT PER  UN PARTICOLARE  SCOPO.  Si\n    veda la Licenza Pubblica Generica GNU per avere maggiori dettagli.\n\n    Questo  programma deve  essere  distribuito assieme  ad una  copia\n    della Licenza Pubblica Generica GNU;  in caso contrario, se ne pu\n    ottenere  una scrivendo  alla Free  Software Foundation,  Inc., 59\n    Temple Place, Suite 330, Boston, MA 02111-1307 USA\n\nSi  aggiungano anche  informazioni su  come si  pu  essere contattati\ntramite posta elettronica e cartacea.\n\nSe il programma  interattivo, si  faccia in modo che stampi una breve\nnota simile a questa quando viene usato interattivamente:\n\n    Orcaloca versione 69, Copyright (C) anno nome dell'autore\n    Orcaloca non ha ALCUNA GARANZIA; per dettagli usare il comando `show g'.\n    Questo  software libero, e ognuno  libero di ridistribuirlo secondo\n    certe condizioni; usare il comando `show c' per i dettagli.\n\nGli  ipotetici  comandi \"show  g\"  e  \"show  c\" mostreranno  le  parti\nappropriate della  Licenza Pubblica Generica.   Chiaramente, i comandi\nusati possono  essere chiamati diversamente da  \"show g\" e  \"show c\" e\npossono anche essere selezionati con  il mouse o attraverso un men, o\ncomunque sia pertinente al programma.\n\nSe necessario, si  deve anche far firmare al  proprio datore di lavoro\n(per chi lavora  come programmatore) o alla propria  scuola, per chi \nstudente,  una \"rinuncia  al  copyright\" per  il  programma.  Ecco  un\nesempio con nomi fittizi:\n\n   Yoyodinamica SPA rinuncia con  questo documento ad ogni diritto sul\n   copyright  del  programma  `Orcaloca'  (che  svolge  dei  passi  di\n   compilazione) scritto da Giovanni Smanettone.\n\n       <firma di Primo Tizio>, 1 April 3000\n       Primo Tizio, Presidente\n\nI programmi  coperti da questa  Licenza Pubblica Generica  non possono\nessere  incorporati  all'interno  di  programmi  proprietari.   Se  il\nproprio programma   una  libreria di funzioni,  pu essere  pi utile\npermettere di  collegare applicazioni proprietarie  alla libreria.  Se\nsi  ha questa  intenzione  consigliamo di  usare  la Licenza  Pubblica\nGenerica Minore GNU (LGPL) invece di questa Licenza.\n"
  },
  {
    "path": "distrib/gpl-ja.txt",
    "content": "                    GNU 一般公衆利用許諾契約書\n                       バージョン2、1991年6月\n                       日本語訳、2002年5月20日\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n この利用許諾契約書を、一字一句そのままに複製し頒布することは許可する。\n しかし変更は認めない。\n\n This is an unofficial translation of the GNU General Public License\n into Japanese.  It was not published by the Free Software Foundation,\n and does not legally state the distribution terms for software that\n uses the GNU GPL--only the original English text of the GNU GPL does\n that. However, we hope that this translation will help Japanese\n speakers understand the GNU GPL better.\n\n (訳: 以下はGNU General Public Licenseの非公式な日本語訳です。これはフ\n リーソフトウェア財団(the Free Software Foundataion)によって発表された\n ものではなく、GNU GPLを適用したソフトウェアの頒布条件を法的に有効な形\n で述べたものではありません。頒布条件としてはGNU GPLの英語版テキストで\n 指定されているもののみが有効です。しかしながら、私たちはこの翻訳が、\n 日本語を使用する人々にとってGNU GPLをより良く理解する助けとなることを\n 望んでいます。)\n\n 翻訳は 八田真行 <mhatta@gnu.org> が行った。原文は\n http://www.gnu.org/licenses/gpl.txt である。誤訳の指摘や改善案を歓迎す\n る。\n                            はじめに\n\nソフトウェア向けライセンスの大半は、あなたがそのソフトウェアを共有した\nり変更したりする自由を奪うように設計されています。対照的に、GNU 一般公\n衆利用許諾契約書は、あなたがフリーソフトウェアを共有したり変更したりす\nる自由を保証する--すなわち、ソフトウェアがそのユーザすべてにとってフリー\nであることを保証することを目的としています。この一般公衆利用許諾契約書\nはフリーソフトウェア財団のソフトウェアのほとんどに適用されており、また\nGNU GPLを適用すると決めたフリーソフトウェア財団以外の作者によるプログ\nラムにも適用されています(いくつかのフリーソフトウェア財団のソフトウェ\nアには、GNU GPLではなくGNU ライブラリ一般公衆利用許諾契約書が適用され\nていることもあります)。あなたもまた、ご自分のプログラムにGNU GPLを適用\nすることが可能です。\n\n私たちがフリーソフトウェアと言うとき、それは利用の自由について言及して\nいるのであって、価格は問題にしていません。私たちの一般公衆利用許諾契約\n書は、あなたがフリーソフトウェアの複製物を頒布する自由を保証するよう設\n計されています(希望に応じてその種のサービスに手数料を課す自由も保証さ\nれます)。また、あなたがソースコードを受け取るか、あるいは望めばそれを\n入手することが可能であるということ、あなたがソフトウェアを変更し、その\n一部を新たなフリーのプログラムで利用できるということ、そして、以上で述\nべたようなことができるということがあなたに知らされるということも保証さ\nれます。\n\nあなたの権利を守るため、私たちは誰かがあなたの有するこれらの権利を否定\nすることや、これらの権利を放棄するよう要求することを禁止するという制限\nを加える必要があります。よって、あなたがソフトウェアの複製物を頒布した\nりそれを変更したりする場合には、これらの制限のためにあなたにある種の責\n任が発生することになります。\n\n例えば、あなたがフリーなプログラムの複製物を頒布する場合、有料か無料に\n関わらず、あなたは自分が有する権利を全て受領者に与えなければなりません。\nまた、あなたは彼らもソースコードを受け取るか手に入れることができるよう\n保証しなければなりません。そして、あなたは彼らに対して以下で述べる条件\nを示し、彼らに自らの持つ権利について知らしめるようにしなければなりませ\nん。\n\n私たちはあなたの権利を二段階の手順を踏んで保護します。(1) まずソフトウェ\nアに対して著作権を主張し、そして (2) あなたに対して、ソフトウェアの複\n製や頒布または改変についての法的な許可を与えるこの契約書を提示します。\n\nまた、各作者や私たちを保護するため、私たちはこのフリーソフトウェアには\n何の保証も無いということを誰もが確実に理解するようにし、またソフトウェ\nアが誰か他人によって改変され、それが次々と頒布されていったとしても、そ\nの受領者は彼らが手に入れたソフトウェアがオリジナルのバージョンでは無い\nこと、そして原作者の名声は他人によって持ち込まれた可能性のある問題によっ\nて影響されることがないということを周知させたいと思います。\n\n最後に、ソフトウェア特許がいかなるフリーのプログラムの存在にも不断の脅\n威を投げかけていますが、私たちは、フリーなプログラムの再頒布者が個々に\n特許ライセンスを取得することによって、事実上プログラムを独占的にしてし\nまうという危険を避けたいと思います。こういった事態を予防するため、私た\nちはいかなる特許も誰もが自由に利用できるようライセンスされるか、全くラ\nイセンスされないかのどちらかでなければならないことを明確にしました。\n\n(訳注: 本契約書で「独占的(proprietary)」とは、ソフトウェアの利用や再頒\n布、改変が禁止されているか、許可を得ることが必要とされているか、あるい\nは厳しい制限が課せられていて自由にそうすることが事実上できなくなってい\nる状態のことを指す。詳しくは\nhttp://www.gnu.org/philosophy/categories.ja.html#ProprietarySoftware\nを参照せよ。)\n\n複製や頒布、改変についての正確な条件と制約を以下で述べていきます。\n\n                    GNU 一般公衆利用許諾契約書\n                 複製、頒布、改変に関する条件と制約\n\n0. この利用許諾契約書は、そのプログラム(またはその他の著作物)をこの一\n般公衆利用許諾契約書の定める条件の下で頒布できるという告知が著作権者に\nよって記載されたプログラムまたはその他の著作物全般に適用される。以下で\nは、「『プログラム』」とはそのようにしてこの契約書が適用されたプログラ\nムや著作物全般を意味し、また「『プログラム』を基にした著作物」とは『プ\nログラム』やその他著作権法の下で派生物と見なされるもの全般を指す。すな\nわち、『プログラム』かその一部を、全く同一のままか、改変を加えたか、あ\nるいは他の言語に翻訳された形で含む著作物のことである(「改変」という語\nの本来の意味からはずれるが、以下では翻訳も改変の一種と見なす)。それぞ\nれの契約者は「あなた」と表現される。\n\n複製や頒布、改変以外の活動はこの契約書ではカバーされない。それらはこの\n契約書の対象外である。『プログラム』を実行する行為自体に制限はない。ま\nた、そのような『プログラム』の出力結果は、その内容が『プログラム』を基\nにした著作物を構成する場合のみこの契約書によって保護される(『プログラ\nム』を実行したことによって作成されたということとは無関係である)。この\nような線引きの妥当性は、『プログラム』が何をするのかに依存する。\n\n1. それぞれの複製物において適切な著作権表示と保証の否認声明(disclaimer\nof warranty)を目立つよう適切に掲載し、またこの契約書および一切の保証の\n不在に触れた告知すべてをそのまま残し、そしてこの契約書の複製物を『プロ\nグラム』のいかなる受領者にも『プログラム』と共に頒布する限り、あなたは\n『プログラム』のソースコードの複製物を、あなたが受け取った通りの形で複\n製または頒布することができる。媒体は問わない。\n\nあなたは、物理的に複製物を譲渡するという行為に関して手数料を課しても良\nいし、希望によっては手数料を取って交換における保護の保証を提供しても良\nい。\n\n2. あなたは自分の『プログラム』の複製物かその一部を改変して『プログラ\nム』を基にした著作物を形成し、そのような改変点や著作物を上記第1節の定\nめる条件の下で複製または頒布することができる。ただし、そのためには以下\nの条件すべてを満たしていなければならない:\n\n    a) あなたがそれらのファイルを変更したということと変更した日時が良\n    く分かるよう、改変されたファイルに告示しなければならない。\n\n    b) 『プログラム』またはその一部を含む著作物、あるいは『プログラム』\n    かその一部から派生した著作物を頒布あるいは発表する場合には、その全\n    体をこの契約書の条件に従って第三者へ無償で利用許諾しなければならな\n    い。\n\n    c) 改変されたプログラムが、通常実行する際に対話的にコマンドを読む\n    ようになっているならば、そのプログラムを最も一般的な方法で対話的に\n    実行する際、適切な著作権表示、無保証であること(あるいはあなたが保\n    証を提供するということ)、ユーザがプログラムをこの契約書で述べた条\n    件の下で頒布することができるということ、そしてこの契約書の複製物を\n    閲覧するにはどうしたらよいかというユーザへの説明を含む告知が印刷さ\n    れるか、あるいは画面に表示されるようにしなければならない(例外とし\n    て、『プログラム』そのものは対話的であっても通常そのような告知を印\n    刷しない場合には、『プログラム』を基にしたあなたの著作物にそのよう\n    な告知を印刷させる必要はない)。\n\n以上の必要条件は全体としての改変された著作物に適用される。著作物の一部\nが『プログラム』から派生したものではないと確認でき、それら自身別の独立\nした著作物であると合理的に考えられるならば、あなたがそれらを別の著作物\nとして分けて頒布する場合、そういった部分にはこの契約書とその条件は\n適用されない。しかし、あなたが同じ部分を『プログラム』を基にした著作物\n全体の一部として頒布するならば、全体としての頒布物は、この契約書が\n課す条件に従わなければならない。というのは、この契約書が他の契約者\nに与える許可は『プログラム』丸ごと全体に及び、誰が書いたかは関係なく各\n部分のすべてを保護するからである。\n\nよって、すべてあなたによって書かれた著作物に対し、権利を主張したりあな\nたの権利に異議を申し立てることはこの節の意図するところではない。むしろ、\nその趣旨は『プログラム』を基にした派生物ないし集合著作物の頒布を管理す\nる権利を行使するということにある。\n\nまた、『プログラム』を基にしていないその他の著作物を『プログラム』(あ\nるいは『プログラム』を基にした著作物)と一緒に集めただけのものを一巻の\n保管装置ないし頒布媒体に収めても、その他の著作物までこの契約書が保\n護する対象になるということにはならない。\n\n3. あなたは上記第1節および2節の条件に従い、『プログラム』(あるいは第2\n節における派生物)をオブジェクトコードないし実行形式で複製または頒布す\nることができる。ただし、その場合あなたは以下のうちどれか一つを実施しな\nければならない:\n\n    a) 著作物に、『プログラム』に対応した完全かつ機械で読み取り可能な\n    ソースコードを添付する。ただし、ソースコードは上記第1節および2節の\n    条件に従いソフトウェアの交換で習慣的に使われる媒体で頒布しなければ\n    ならない。あるいは、\n\n    b) 著作物に、いかなる第三者に対しても、『プログラム』に対応した完\n    全かつ機械で読み取り可能なソースコードを、頒布に要する物理的コスト\n    を上回らない程度の手数料と引き換えに提供する旨述べた少なくとも3年\n    間は有効な書面になった申し出を添える。ただし、ソースコードは上記第\n    1節および2節の条件に従いソフトウェアの交換で習慣的に使われる媒体で\n    頒布しなければならない。あるいは、\n\n    c) 対応するソースコード頒布の申し出に際して、あなたが得た情報を一\n    緒に引き渡す(この選択肢は、営利を目的としない頒布であって、かつあ\n    なたが上記小節bで指定されているような申し出と共にオブジェクトコー\n    ドあるいは実行形式のプログラムしか入手していない場合に限り許可され\n    る)。\n\n著作物のソースコードとは、それに対して改変を加える上で好ましいとされる\n著作物の形式を意味する。ある実行形式の著作物にとって完全なソースコード\nとは、それが含むモジュールすべてのソースコード全部に加え、関連するイン\nターフェース定義ファイルのすべてとライブラリのコンパイルやインストール\nを制御するために使われるスクリプトをも加えたものを意味する。しかし特別\nな例外として、そのコンポーネント自体が実行形式に付随するのでは無い限り、\n頒布されるものの中に、実行形式が実行されるオペレーティングシステムの主\n要なコンポーネント(コンパイラやカーネル等)と通常一緒に(ソースかバイナ\nリ形式のどちらかで)頒布されるものを含んでいる必要はないとする。\n\n実行形式またはオブジェクトコードの頒布が、指定された場所からコピーする\nためのアクセス手段を提供することで為されるとして、その上でソースコード\nも同等のアクセス手段によって同じ場所からコピーできるようになっているな\nらば、第三者がオブジェクトコードと一緒にソースも強制的にコピーさせられ\nるようになっていなくてもソースコード頒布の条件を満たしているものとする。\n\n4. あなたは『プログラム』を、この契約書において明確に提示された行\n為を除き複製や改変、サブライセンス、あるいは頒布してはならない。他に\n『プログラム』を複製や改変、サブライセンス、あるいは頒布する企てはすべ\nて無効であり、この契約書の下でのあなたの権利を自動的に終結させるこ\nとになろう。しかし、複製物や権利をこの契約書に従ってあなたから得た\n人々に関しては、そのような人々がこの契約書に完全に従っている限り彼\nらのライセンスまで終結することはない。\n\n5. あなたはこの契約書を受諾する必要は無い。というのは、あなたはこ\nれに署名していないからである。しかし、この契約書以外にあなたに対し\nて『プログラム』やその派生物を変更、頒布する許可を与えるものは存在しな\nい。これらの行為は、あなたがこの契約書を受け入れない限り法によって\n禁じられている。そこで、『プログラム』(あるいは『プログラム』を基にし\nた著作物のすべて)を改変ないし頒布することにより、あなたは自分がそのよ\nうな行為を行うためにこの契約書を受諾したということ、そして『プログ\nラム』とそれに基づく著作物の複製や頒布、改変についてこの契約書が課\nす制約と条件をすべて受け入れたということを示したものと見なす。\n\n6. あなたが『プログラム』(または『プログラム』を基にした著作物全般)を\n再頒布するたびに、その受領者は元々のライセンス許可者から、この契約書で\n指定された条件と制約の下で『プログラム』を複製や頒布、あるいは改変する\n許可を自動的に得るものとする。あなたは、受領者がここで認められた権利を\n行使することに関してこれ以上他のいかなる制限も課すことができない。あな\nたには、第三者がこの契約書に従うことを強制する責任はない。\n\n7. 特許侵害あるいはその他の理由(特許関係に限らない)から、裁判所の判決\nあるいは申し立ての結果としてあなたに(裁判所命令や契約などにより)この契\n約書の条件と矛盾する制約が課された場合でも、あなたがこの契約書の条件を\n免除されるわけではない。もしこの契約書の下であなたに課せられた責任と他\nの関連する責任を同時に満たすような形で頒布できないならば、結果としてあ\nなたは『プログラム』を頒布することが全くできないということである。例え\nば特許ライセンスが、あなたから直接間接を問わずコピーを受け取った人が誰\nでも『プログラム』を使用料無料で再頒布することを認めていない場合、あな\nたがその制約とこの契約書を両方とも満たすには『プログラム』の頒布を完全\nに中止するしかないだろう。\n\nこの節の一部分が特定の状況の下で無効ないし実施不可能な場合でも、節の残\nりの部分は適用されるよう意図されている。その他の状況では節が全体として\n適用されるよう意図されている。\n\n特許やその他の財産権を侵害したり、そのような権利の主張の効力に異議を唱\nえたりするようあなたを誘惑することがこの節の目的ではない。この節には、\n人々によってライセンス慣行として実現されてきた、フリーソフトウェア頒布\nのシステムの完全性を護るという目的しかない。多くの人々が、フリーソフト\nウェアの頒布システムが首尾一貫して適用されているという信頼に基づき、こ\nのシステムを通じて頒布される多様なソフトウェアに寛大な貢献をしてきたの\nは事実であるが、人がどのようなシステムを通じてソフトウェアを頒布したい\nと思うかはあくまでも作者/寄与者次第であり、あなたが選択を押しつけるこ\nとはできない。\n\nこの節は、この契約書のこの節以外の部分の一帰結になると考えられるケー\nスを徹底的に明らかにすることを目的としている。\n\n8. 『プログラム』の頒布や利用が、ある国においては特許または著作権が主\n張されたインターフェースのいずれかによって制限されている場合、『プログ\nラム』にこの契約書を適用した元の著作権者は、そういった国々を排除し\nた明確な地理的頒布制限を加え、そこで排除されていない国の中やそれらの国々\nの間でのみ頒布が許可されるようにしても構わない。その場合、そのような制\n限はこの契約書本文で書かれているのと同様に見なされる。\n\n9. フリーソフトウェア財団は、時によって改訂または新版の一般公衆利用許\n諾書を発表することができる。そのような新版は現在のバージョンとその精神\nにおいては似たものになるだろうが、新たな問題や懸念を解決するため細部で\nは異なる可能性がある。\n\nそれぞれのバージョンには、見分けが付くようにバージョン番号が振られてい\nる。『プログラム』においてそれに適用されるこの契約書のバージョン番号が\n指定されていて、更に「それ以降のいかなるバージョン」も適用して良いとなっ\nていた場合、あなたは従う条件と制約として、指定のバージョンか、フリーソ\nフトウェア財団によって発行された指定のバージョン以降の版のどれか一つの\nどちらかを選ぶことが出来る。『プログラム』でライセンスのバージョン番号\nが指定されていないならば、あなたは今までにフリーソフトウェア財団から発\n行されたバージョンの中から好きに選んで構わない。\n\n10. もしあなたが『プログラム』の一部を、その頒布条件がこの契約書と\n異なる他のフリーなプログラムと統合したいならば、作者に連絡して許可を求\nめよ。フリーソフトウェア財団が著作権を保有するソフトウェアについては、\nフリーソフトウェア財団に連絡せよ。私たちは、このような場合のために特別\nな例外を設けることもある。私たちが決定を下すにあたっては、私たちのフリー\nソフトウェアの派生物すべてがフリーな状態に保たれるということと、一般的\nにソフトウェアの共有と再利用を促進するという二つの目標を規準に検討され\nるであろう。\n                            無保証について\n\n11. 『プログラム』は代価無しに利用が許可されるので、適切な法が認める限\nりにおいて、『プログラム』に関するいかなる保証も存在しない。書面で別に\n述べる場合を除いて、著作権者、またはその他の団体は、『プログラム』を、\n表明されたか言外にかは問わず、商業的適性を保証するほのめかしやある特定\nの目的への適合性(に限られない)を含む一切の保証無しに「あるがまま」で提\n供する。『プログラム』の質と性能に関するリスクのすべてはあなたに帰属す\nる。『プログラム』に欠陥があると判明した場合、あなたは必要な保守点検や\n補修、修正に要するコストのすべてを引き受けることになる。\n\n12. 適切な法か書面での同意によって命ぜられない限り、著作権者、または上\n記で許可されている通りに『プログラム』を改変または再頒布したその他の団\n体は、あなたに対して『プログラム』の利用ないし利用不能で生じた一般的、\n特別的、偶然的、必然的な損害(データの消失や不正確な処理、あなたか第三\n者が被った損失、あるいは『プログラム』が他のソフトウェアと一緒に動作し\nないという不具合などを含むがそれらに限らない)に一切の責任を負わない。\nそのような損害が生ずる可能性について彼らが忠告されていたとしても同様で\nある。\n\n                          条件と制約終わり\n\n            以上の条項をあなたの新しいプログラムに適用する方法\n\nあなたが新しいプログラムを開発したとして、公衆によってそれが利用される\n可能性を最大にしたいなら、そのプログラムをこの契約書の条項に従って\n誰でも再頒布あるいは変更できるようフリーソフトウェアにするのが最善です。\n\nそのためには、プログラムに以下のような表示を添付してください。その場合、\n保証が排除されているということを最も効果的に伝えるために、それぞれのソー\nスファイルの冒頭に表示を添付すれば最も安全です。少なくとも、「著作権表\n示」という行と全文がある場所へのポインタだけは各ファイルに含めて置いて\nください。\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program; if not, write to the Free Software\n    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n    (訳:\n\n    <プログラムの名前と、それが何をするかについての簡単な説明。>\n    Copyright (C) <西暦年>  <作者の名前>\n\n    このプログラムはフリーソフトウェアです。あなたはこれを、フリーソフ\n    トウェア財団によって発行された GNU 一般公衆利用許諾契約書(バージョ\n    ン2か、希望によってはそれ以降のバージョンのうちどれか)の定める条件\n    の下で再頒布または改変することができます。\n\n    このプログラムは有用であることを願って頒布されますが、*全くの無保\n    証* です。商業可能性の保証や特定の目的への適合性は、言外に示された\n    ものも含め全く存在しません。詳しくはGNU 一般公衆利用許諾契約書をご\n    覧ください。\n\n    あなたはこのプログラムと共に、GNU 一般公衆利用許諾契約書の複製物を\n    一部受け取ったはずです。もし受け取っていなければ、フリーソフトウェ\n    ア財団まで請求してください(宛先は the Free Software Foundation,\n    Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA)。\n\n    )\n\n電子ないし紙のメールであなたに問い合わせる方法についての情報も書き加え\nましょう。\n\nプログラムが対話的なものならば、対話モードで起動した際に出力として以下\nのような短い告知が表示されるようにしてください:\n\n    Gnomovision version 69, Copyright (C) year name of author\n    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\n    (訳:\n\n    Gnomovision バージョン 69, Copyright (C) 年 作者の名前\n    Gnomovision は*全くの無保証*で提供されます。詳しくは「show w」\n    とタイプして下さい。これはフリーソフトウェアであり、ある条件の下で\n    再頒布することが奨励されています。詳しくは「show c」とタイプして下\n    さい。\n\n    )\n\nここで、仮想的なコマンド「show w」と「show c」は一般公衆利用許諾契約書\nの適切な部分を表示するようになっていなければなりません。もちろん、あな\nたが使うコマンドを「show w」や「show c」と呼ぶ必然性はありませんので、\nあなたのプログラムに合わせてマウスのクリックやメニューのアイテムにして\nも結構です。\n\nまたあなたは、必要ならば(プログラマーとして働いていたら)あなたの雇用主、\nあるいは場合によっては学校から、そのプログラムに関する「著作権放棄声明\n(copyright disclaimer)」に署名してもらうべきです。以下は例ですので、名\n前を変えてください:\n\n  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n\n  <signature of Ty Coon>, 1 April 1989\n  Ty Coon, President of Vice\n\n  (訳:\n\n  Yoyodyne社はここに、James Hackerによって書かれたプログラム\n  「Gnomovision」(コンパイラへ通すプログラム)に関する一切の著作権の利\n  益を放棄します。\n\n   <Ty Coon氏の署名>、1989年4月1日\n   Ty Coon、副社長\n\n  )\n\nこの一般公衆利用許諾契約書では、あなたのプログラムを独占的なプログラム\nに統合することを認めていません。あなたのプログラムがサブルーチンライブ\nラリならば、独占的なアプリケーションとあなたのライブラリをリンクするこ\nとを許可したほうがより便利であると考えるかもしれません。もしこれがあな\nたの望むことならば、この契約書の代わりにGNU ライブラリ一般公衆利用許諾\n契約書を適用してください。\n"
  },
  {
    "path": "distrib/gpl-pl.txt",
    "content": "  Powszechna Licencja Publiczna GNU\n\n      Tumaczenie GNU General Public License\n      <http://www.fsf.org/copyleft/gpl.html>\n\n\n      Uwaga!\n\nTo jest nieoficjalne tumaczenie Powszechnej Licencji Publicznej GNU na\njzyk polski. Nie zostao opublikowane przez Free Software Foundation\ni pod wzgldem prawnym nie stanowi warunkw rozpowszechniania\noprogramowania stosujcego GNU GPL -- ustanawia je wycznie oryginalny\nangielski tekst licencji GNU GPL <http://www.fsf.org/copyleft/gpl.html>.\nJednak mamy nadziej, e pomoe ono lepiej zrozumie Licencj osobom\nmwicym po polsku.\n\n\n      Note!\n\nThis is an unofficial translation of the GNU General Public License into\nPolish. It was not published by the Free Software Foundation, and does\nnot legally state the distribution terms for software that uses the GNU\nGPL--only the original English text of the GNU GPL\n<http://www.fsf.org/copyleft/gpl.html> does that. However, we hope that\nthis translation will help Polish speakers understand the GNU GPL better.\n\n\n    Powszechna Licencja Publiczna GNU\n\n      Wersja 2, czerwiec 1991\n\nCopyright (c) 1989, 1991 Free Software Foundation, Inc., 675 Mass Ave,\nCambridge, MA 02139 USA.\n\nZezwala si na kopiowanie i rozpowszechnianie wiernych kopii niniejszego\ndokumentu licencyjnego, jednak bez prawa wprowadzania zmian.\n\n\n      Preambua\n\nWikszo licencji na oprogramowanie pomylana jest po to, aby odebra\nuytkownikowi moliwo swobodnego udostpniania innym i zmieniania\ndanego software'u. Natomiast w wypadku Powszechnej Licencji Publicznej\nGNU (/GNU General Public License/, GPL) celem jest zagwarantowanie\nuytkownikowi swobody udostpniania i zmieniania tego wolnego\noprogramowania, a wic danie pewnoci, i oprogramowanie jest wolno\ndostpne dla wszystkich uytkownikw. Niniejsza Powszechna Licencja\nPubliczna dotyczy wikszoci oprogramowania wydawanego przez Fundacj\nWolnego Oprogramowania (/Free Software Foundation/) oraz wszelkich\ninnych programw, ktrych autorzy zobowizuj si do jej stosowania.\n(Niektre rodzaje oprogramowania wydawanego przez Fundacj objte s\nPowszechn Licencj Publiczn GNU dla Bibliotek, /GNU Library General\nPublic License/). Uytkownik moe stosowa j rwnie do swoich programw.\n\nMwic o wolnym oprogramowaniu mamy na myli swobod, a nie cen. Nasze\nPowszechne Licencje Publiczne wprowadzono po to, aby zapewni Pastwu\nswobod rozpowszechniania kopii tego oprogramowania (i - jeli kto chce\n- pobierania za t usug opaty), jak rwnie aby udostpni kod\nrdowy oraz umoliwi dokonywanie zmian tego oprogramowania lub\nwykorzystywania jego fragmentw w nowych, wolnych programach. Nie bez\nznaczenia jest te sama moliwo dotarcia do Pastwa z informacj\no wszystkich tych udogodnieniach.\n\nW celu ochrony praw uytkownika jestemy zmuszeni wprowadza\nograniczenia zabraniajce komukolwiek kwestionowanie jego praw albo\nsugerowanie rezygnacji z tych praw. Ograniczenia te sprowadzaj si do\npewnych dla Pastwa obowizkw w przypadku rozpowszechniania przez Was\nkopii naszego oprogramowania bd dokonywania w nim zmian.\n\nNa przykad, jeli rozprowadzacie Pastwo kopie takiego programu,\nniezalenie czy gratisowo, czy za opat, musicie Pastwo odbiorcy\nudzieli wszelkich tych praw, jakie mielicie sami. Musicie zapewni mu\nrwnie otrzymanie kodu rdowego (lub moliwo otrzymania) oraz\nprzedstawi niniejsze Warunki, aby mg on pozna swoje prawa.\n\nOchrona Pastwa praw przebiega w dwch etapach:\n\n   1. zastrzegamy prawo wasnoci autorskiej do oprogramowania,\n   2. oferujemy Pastwu niniejsz licencj, ktra daje Wam sankcjonowane\n      prawem zezwolenie na kopiowanie, rozpowszechnianie i/lub\n      modyfikowanie tego oprogramowania.\n\nPonadto dla ochrony tak autora, jak i naszej, pragniemy mie pewno, e\nkady zrozumie, i na niniejsze wolne oprogramowanie nie udziela si\ngwarancji. W razie dokonania w nim przez kogo modyfikacji i puszczenia\ndalej do obrotu, pragniemy, aby dalsi odbiorcy zdawali sobie spraw\nz tego, e problemy wprowadzone przez inne osoby nie s wyrazem\noryginalnych dziaa twrcw.\n\nI rzecz ostatnia: kademu wolnemu programowi stale zagraaj patenty na\noprogramowanie. Naszym pragnieniem jest unikanie takiego\nniebezpieczestwa, kiedy redystrybutorzy wolnego programu indywidualnie\nuzyskuj prawa patentowe, nadajc tym samym programowi charakter prawnie\nzastrzeony. W celu zapobieenia takim zjawiskom jednoznacznie\nwyjanilimy, e kady patent musi by wydawany albo dla swobodnego\nuytku przez wszystkich, albo nie wydawany wcale.\n\nPoniej podajemy dokadne zasady i warunki kopiowania, rozpowszechniania\ni modyfikowania.\n\n\n      Zasady i warunki kopiowania, rozpowszechniania i modyfikowania\n\n*0.*\n    Niniejsza Licencja dotyczy programw i innych prac, na ktrych\n    umieszczona jest pochodzca od waciciela praw autorskich\n    informacja, e dany program lub praca moe by rozpowszechniana na\n    warunkach niniejszej Powszechnej Licencji Publicznej. Uywane\n    poniej sowo \"Program\" oznacza wanie takie programy lub prace,\n    za okrelenie \"praca oparta na Programie\" dotyczy albo Programu,\n    albo pochodzcej od niego pracy w rozumieniu prawa autorskiego, to\n    jest pracy zawierajcej Program lub jego cz dosown, bd\n    zmodyfikowan i/lub przeoon na inny jzyk. (W dalszym cigu\n    niniejszego, pojcie przekadu wcza si bez ogranicze do terminu\n    \"modyfikacja\"). Do kadego licencjobiorcy bdziemy zwraca si \"per\n    Ty\".\n\n    Niniejsza Licencja nie obejmuje dziaa innych ni kopiowanie,\n    rozprowadzanie i modyfikowanie - nie mieszcz si one w jej\n    zakresie. Czynno uywania Programu nie jest poddana ograniczeniom,\n    a produkty uzyskane z Programu objte s Licencj tylko wtedy, gdy\n    ich tre stanowi prac opart na Programie (niezalenie od\n    stworzenia jej przy uyciu Programu). To, czy fakt taki jest prawd,\n    zaley od tego, co dany Program wykonuje.\n\n*1.*\n    Moesz kopiowa i rozprowadza w dowolnych mediach wierne kopie kodu\n    rdowego Programu w otrzymanej formie pod warunkiem, e w widoczny\n    sposb i  odpowiednio podasz na kadej kopii waciw informacj\n    o prawie autorskim i zrzeczenie si uprawnie z tytuu gwarancji;\n    wszelkie napisy informacyjne na temat Licencji i faktu nieudzielania\n    gwarancji musisz chroni przed uszkodzeniem, za wszystkim innym\n    odbiorcom Programu musisz wraz z Programem wrcza egzemplarz\n    niniejszej Licencji.\n\n    Moesz pobiera opat za fizyczn czynno przekazania kopii\n    i wedug wasnej decyzji moesz za opat proponowa ochron\n    gwarancyjn.\n\n*2.*\n    Moesz modyfikowa swoj kopi czy kopie Programu oraz dowolne jego\n    czci, tworzc przez to prac opart na Programie, jak rwnie\n    kopiowa i rozprowadza takie modyfikacje i prac na warunkach\n    podanych w pkt.1 powyej - pod warunkiem przestrzegania caoci\n    poniszych wymogw:\n\n    a.\n        Musisz spowodowa umieszczenie na zmodyfikowanych plikach\n        widocznej informacji o tym, e dane pliki zostay przez ciebie\n        zmienione, wraz z dat dokonania zmian.\n\n    b.\n        Musisz doprowadzi do tego, aby kada rozpowszechniana lub\n        publikowana przez ciebie praca, ktra w caoci lub czci\n        zawiera Program, albo pochodzi od niego lub jego czci, bya\n        w caoci i bezpatnie licencjonowana dla wszelkich stron\n        trzecich na warunkach niniejszej Licencji.\n\n    c.\n        Jeeli zmodyfikowany program podczas korzystania z niego\n        w normalnym trybie odczytuje polecenia interaktywnie, musisz\n        spowodowa, aby po uruchomieniu (uyty w interaktywny sposb\n        w najzwyklejszym trybie), wydrukowywa on lub wywietla\n        powiadomienie o odnonym prawie autorskim i braku gwarancji\n        (ewentualnie o zapewnianiu gwarancji przez ciebie), oraz o tym,\n        e uytkownicy mog redystrybuowa ten program na niniejszych\n        warunkach wraz z informacj, jak uytkownik moe zapozna si\n        z treci niniejszej Licencji. (Wyjtek: jeli sam Program jest\n        interaktywny, ale normalnie nie drukuje takiego powiadomienia,\n        twoja praca oparta na nim te nie musi wydrukowywa takiego\n        powiadomienia).\n\n    Niniejsze wymogi odnosz si do zmodyfikowanej pracy jako caoci.\n    Jeli dajce si ustali sekcje danej pracy nie pochodz od Programu\n    i mog by racjonalnie uwaane za samodzielne i odrbne same\n    w sobie, to niniejsza Licencja i jej warunki nie maj zastosowania\n    do takich sekcji przy rozprowadzaniu ich przez ciebie jako odrbne\n    prace. Jeli jednak rozprowadzasz je jako cz caoci, bdcej\n    prac opart na Programie, rozpowszechnianie tej caoci musi by\n    dokonywane na warunkach niniejszej Licencji, ktrej zezwolenia dla\n    innych licencjobiorcw rozcigaj si w  caej szerokoci na t\n    cao, a tym samym i na kad indywidualn jej cz, niezalenie\n    od jej autorstwa.\n\n    Dlatego te intencj tego fragmentu nie jest roszczenie sobie praw\n    albo podwaanie twych praw do pracy napisanej w caoci przez\n    ciebie. Chodzi nam raczej o korzystanie z prawa kontrolowania\n    dystrybucji pochodnych i zbiorowych prac opartych na Programie.\n\n    I jeszcze jedno: samo tylko poczenie z Programem (lub z prac\n    opart na Programie) innej pracy - nie opartej na Programie,\n    w ramach wolumenu nonika przechowywania lub dystrybucji, nie\n    powoduje objcia takiej pracy zakresem niniejszej Licencji.\n\n*3.*\n    Moesz kopiowa i rozprowadza Program (lub opart na nim prac -\n    zgodnie z pkt.2 w kodzie wynikowym lub w formie wykonywalnej w myl\n    postanowie pkt.1 i 2 powyej, pod warunkiem zrealizowania rwnie\n    poniszych wymogw:\n\n    a.\n        Musisz doczy do niego odpowiadajcy mu, kompletny i moliwy\n        do odczytania przez urzdzenia cyfrowe kod rdowy, ktry musi\n        by rozpowszechniany na warunkach pkt.1 i 2 powyej i na noniku\n        zwyczajowo uywanym dla wzajemnej wymiany oprogramowania; lub\n\n    b.\n        doczy do niego pisemn ofert, wan co najmniej 3 lata,\n        przyznajc kadej stronie trzeciej - za opat nie\n        przekraczajc twego kosztu fizycznego wykonywania dystrybucji\n        rda - kompletn, odczytywaln przez urzdzenia cyfrowe kopi\n        odpowiadajcego mu kodu rdowego, rozprowadzan na warunkach\n        pkt.1 i 2 powyej, na noniku zwyczajowo uywanym do wzajemnej\n        wymiany oprogramowania; lub\n\n    c.\n        doczy do niego informacj, jak otrzymae na temat oferty\n        rozprowadzania odpowiedniego kodu rdowego. (Ta moliwo\n        dozwolona jest tylko dla dystrybucji niehandlowej i jedynie\n        wtedy, gdy otrzymae dany program w kodzie wynikowym lub formie\n        wykonywalnej wraz z wymienion ofert - zgodnie z podpunktem \"b\"\n        powyej).\n\n    Okrelenie kod rdowy dla pracy oznacza form pracy preferowan\n    dla wprowadzania do niej modyfikacji. Dla wykonanej pracy, kompletny\n    kod rdowy oznacza cay kod rdowy wszystkich moduw, wszelkie\n    sprzone z ni poredniczce pliki opisujce oraz zbiory komend\n    stosowane do sterowania kompilacj i instalowaniem programw.\n    Niemniej jednak, jako wyjtek specjalny, dystrybuowany (w formie\n    rdowej albo binarnej) kod rdowy nie musi obejmowa niczego, co\n    jest normalnie rozprowadzane przy pomocy gwnych komponentw\n    (kompilator, jdro itd.) systemu operacyjnego, na ktrym pracuje\n    cz wykonywalna, o ile sam taki komponent towarzyszy tej czci.\n\n    Jeli dystrybucja czci wykonywalnej albo kodu wynikowego\n    realizowana jest poprzez oferowanie dostpu do kopii z wyznaczonego\n    miejsca, to oferowanie rwnowanego dostpu dla kopiowania kodu\n    rdowego z tego samego miejsca liczy si jako rozpowszechnianie\n    kodu rdowego, nawet gdy strony trzecie nie s zmuszone do\n    kopiowania rda wraz z kodem wynikowym.\n\n*4.*\n    Poza przypadkami jednoznacznie dozwolonymi w niniejszej Licencji,\n    nie moesz kopiowa, modyfikowa, sublicencjonowa ani\n    rozpowszechnia Programu. We wszystkich pozostaych wypadkach, kada\n    prba skopiowania, sublicencjonowania lub rozpowszechnienia Programu\n    jest niewana i powoduje automatyczne wyganicie twoich praw\n    z tytuu Licencji. Niemniej jednak, stronom, ktre ju otrzymay od\n    ciebie kopie albo prawa w ramach niniejszej Licencji, licencje nie\n    wygasaj tak dugo, jak dugo strony te w peni stosuj si do nich.\n\n*5.*\n    Nie musisz akceptowa niniejszej Licencji, jeeli jej nie\n    podpisae. Niemniej jednak, nic innego nie zapewni ci zezwolenia na\n    modyfikowanie lub rozprowadzanie Programu i pochodzcych od niego\n    prac. Dziaania takie s prawnie zabronione, jeeli nie przyjmujesz\n    niniejszej Licencji. Dlatego te, poprzez modyfikowanie bd\n    rozpowszechnianie Programu (lub pracy na nim opartej) dajesz wyraz\n    swojej akceptacji dla Licencji i wszelkich jej postanowie\n    i warunkw dotyczcych kopiowania, rozprowadzania i modyfikowania\n    Programu lub opartych na nim prac.\n\n*6.*\n    W kadym przypadku redystrybucji przez ciebie Programu (albo opartej\n    na nim pracy), odbiorca automatycznie otrzymuje od pierwotnego\n    licencjodawcy licencj na kopiowanie, rozpowszechnianie\n    i modyfikowanie Programu na niniejszych zasadach i warunkach. Na\n    korzystanie przez odbiorc z udzielonych w niniejszej Licencji praw\n    nie moesz narzuca ju dalszych ogranicze. Nie jeste stron\n    odpowiedzialn za kontrol przestrzegania Licencji przez osoby trzecie.\n\n*7.*\n    Jeli na skutek wyroku sdowego lub zarzutu naruszenia patentu, jak\n    te z kadej innej przyczyny (nie ograniczonej do kwestii\n    patentowych) zostan narzucone na ciebie (niezalenie czy to moc\n    wyroku sdowego, umowy, czy w inny sposb) warunki sprzeczne\n    z warunkami niniejszej Licencji, to nie zwalniaj one ciebie\n    z warunkw Licencji. Jeli nie moesz prowadzi dystrybucji tak, aby\n    wypenia jednoczenie swoje obowizki z tytuu niniejszej Licencji\n    i inne odnone obowizki, to w rezultacie nie moesz wcale\n    rozprowadza Programu. Na przykad, gdyby licencja patentowa nie\n    zezwalaa na woln od opat licencyjnych redystrybucj Programu\n    przez wszystkie osoby, ktre otrzymay kopie bezporednio lub\n    porednio od ciebie, to jedynym sposobem pozwalajcym ci na\n    przestrzeganie i licencji patentowej, i Licencji niniejszej, byoby\n    cakowite powstrzymanie si od jakiejkolwiek dystrybucji Programu.\n\n    Jeeli w jakich szczeglnych okolicznociach ktry fragment\n    niniejszego punktu staby si niewany lub niewykonywalny, to\n    intencj jest, aby znajdowaa zastosowanie pozostaa cz punktu,\n    a tre caego punktu bya stosowana w pozostaych okolicznociach.\n\n    Celem niniejszego punktu nie jest zachcanie do naruszania patentw\n    czy innych praw wasnoci, albo te do podwaania ich wanoci;\n    niniejszy punkt za swj jedyny cel ma ochron integralnoci systemu\n    rozpowszechniania wolnego oprogramowania, realizowanego za pomoc\n    publicznych licencji. Wielu ludzi bezinteresownie wnioso swj wkad\n    do stworzenia szerokiego zakresu oprogramowania upowszechnianego\n    w tym systemie, majc zaufanie do konsekwentnego jego stosowania;\n    wycznie do autora/ofiarodawcy naley decyzja, czy yczy on sobie\n    rozprowadzania oprogramowania za porednictwem innego systemu\n    i licencjobiorca nie moe tego prawa wyboru ogranicza.\n\n    Intencj niniejszego punktu jest jasne i wyrane przedstawienie\n    tego, co uwaa si za skutki, jakie rodzi pozostaa cz niniejszej\n    Licencji.\n\n*8.*\n    W przypadku, gdy dystrybucja i/lub uywanie Programu w niektrych\n    krajach poddane jest ograniczeniom patentowym lub zastrzeeniom\n    prawami autorskimi, pocztkowy posiadacz praw autorskich, ktry\n    poddaje Program pod oddziaywanie niniejszej Licencji, moe doda\n    wyranie zakrelone geograficzne ograniczenie rozpowszechniania\n    wyczajce te kraje, dziki czemu dystrybucja dozwolona bdzie\n    wycznie w krajach czy wrd krajw nie objtych takim wyczeniem.\n    W przypadku takim, niniejsza Licencja obejmuje dane ograniczenie\n    tak, jakby byo ono wpisane w jej tre.\n\n*9.*\n    W miar potrzeby Fundacja Wolnego Oprogramowania moe publikowa\n    poprawione i/lub nowe wersje Powszechnej Licencji Publicznej. Takie\n    nowe wersje bd napisane w duchu podobnym do obecnej wersji, ale\n    mog rni si w szczegach poruszajcych nowe problemy czy\n    zagadnienia.\n\n    Kadej wersji nadaje si wyrniajcy j numer. Jeeli Program\n    podaje numer wersji niniejszej Licencji, odnoszcy si do tej wersji\n    i \"wszelkich wersji nastpnych\", masz do wyboru albo stosowa si do\n    postanowie i warunkw tej wersji, albo ktrejkolwiek wersji\n    pniejszej wydanej przez Fundacj Wolnego Oprogramowania. O ile\n    Program nie podaje numeru wersji niniejszej Licencji, moesz wybra\n    dowoln wersj kiedykolwiek opublikowan przez Fundacj.\n\n*10.*\n    Jeli chcesz wczy czci Programu do innych wolnych programw,\n    ktrych warunki rozpowszechniania s inne, zwr si pisemnie do\n    autora z prob o pozwolenie. W przypadku oprogramowania objtego\n    przez Fundacj prawem autorskim, napisz do Fundacji; czasami czynimy\n    od tego odstpstwa. W naszej decyzji kierujemy si dwoma celami:\n    utrzymania wolnego statusu wszystkich pochodnych naszego wolnego\n    oprogramowania oraz - generalnie - promowania wspudziau\n    i wielokrotnego stosowania oprogramowania.\n\n    *WYRB BEZ GWARANCJI*\n\n*11.*\n    PONIEWA PROGRAM JEST LICENCJONOWANY BEZPATNIE, NIE JEST\n    OBJTY GWARANCJ W ZAKRESIE DOZWOLONYM PRZEZ OBOWIZUJCE\n    PRZEPISY. O ILE NA PIMIE NIE STANOWI SI INACZEJ,\n    POSIADACZE PRAW AUTORSKICH I/LUB INNE STRONY ZAPEWNIAJ\n    PROGRAM W STANIE, W JAKIM JEST (\"JAK WIDA\") BEZ\n    JAKIEJKOLWIEK GWARANCJI, ANI WYRANEJ, ANI DOMYLNEJ, W TYM\n    MIDZY INNYMI DOMYLNYCH GWARANCJI CO DO PRZYDATNOCI\n    HANDLOWEJ I PRZYDATNOCI DO OKRELONYCH ZASTOSOWA. CAO\n    RYZYKA W ZAKRESIE JAKOCI I SKUTECZNOCI DZIAANIA PROGRAMU\n    PONOSISZ SAM. W RAZIE GDYBY PROGRAM OKAZA SI WADLIWY,\n    PONOSISZ KOSZT CAEGO NIEZBDNEGO SERWISU, NAPRAWY I\n    KORYGOWANIA.\n\n*12.*\n    O ILE OBOWIZUJCE PRAWO NIE STANOWI INACZEJ ALBO CZEGO\n    INNEGO NIE UZGODNIONO W FORMIE PISEMNEJ, ADEN POSIADACZ\n    PRAW AUTORSKICH ANI INNA STRONA MODYFIKUJCA I/LUB\n    REDYSTRYBUJCA PROGRAM ZGODNIE Z POWYSZYMI ZEZWOLENIAMI,\n    W ADNYM WYPADKU NIE JEST ODPOWIEDZIALNA WOBEC CIEBIE ZA\n    SZKODY, W TYM SZKODY OGLNE, SPECJALNE, UBOCZNE LUB\n    SKUTKOWE, WYNIKE Z UYCIA BD NIEMOLIWOCI UYCIA\n    PROGRAMU (W TYM, MIDZY INNYMI, ZA UTRAT DANYCH LUB\n    POWSTANIE DANYCH NIEDOKADNYCH, ALBO ZA STRATY PONIESIONE\n    PRZEZ CIEBIE LUB STRONY TRZECIE, JAK TE NIEDZIAANIE\n    PROGRAMU Z INNYMI PROGRAMAMI), NAWET JELI DANY POSIADACZ\n    BD INNA STRONA ZOSTALI POWIADOMIENI O MOLIWOCI POWSTANIA\n    TAKICH SZKD.\n\n\n      KONIEC ZASAD I WARUNKW\n\n\n      Jak stosowa niniejsze Warunki do Twoich nowych programw\n\nJeli opracowujesz nowy program i chciaby, aby sta si on przydatny\ndla szerokiego ogu, najlepsz drog do osignicia tego bdzie nadanie\ntwemu programowi charakteru wolnego oprogramowania, ktre kady moe\nredystrybuowa i zmienia na niniejszych warunkach.\n\nW tym celu do programu docz ponisze informacje. Bezpieczniej jest\ndoczy je na pocztku kadego pliku rdowego, dziki czemu\nnajskuteczniej mona przekaza fakt nieistnienia gwarancji; kady plik\npowinien przy tym nosi uwag \"copyright\" i odnonik, gdzie mona\nznale pen informacj.\n\n    /nazwa programu i informacja, do czego on suy.\n    /Copyright (C) 19../20.. /nazwisko autora/\n\n    Niniejszy program jest wolnym oprogramowaniem; moesz go\n    rozprowadza dalej i/lub modyfikowa na warunkach Powszechnej\n    Licencji Publicznej GNU, wydanej przez Fundacj Wolnego\n    Oprogramowania - wedug wersji 2-giej tej Licencji lub ktrej\n    z pniejszych wersji.\n\n    Niniejszy program rozpowszechniany jest z nadziej, i bdzie on\n    uyteczny - jednak BEZ JAKIEJKOLWIEK GWARANCJI, nawet domylnej\n    gwarancji PRZYDATNOCI HANDLOWEJ albo PRZYDATNOCI DO OKRELONYCH\n    ZASTOSOWA. W celu uzyskania bliszych informacji - Powszechna\n    Licencja Publiczna GNU.\n\n    Z pewnoci wraz z niniejszym programem otrzymae te egzemplarz\n    Powszechnej Licencji Publicznej GNU (GNU General Public License);\n    jeli nie - napisz do Free Software Foundation, Inc., 675 Mass Ave,\n    Cambridge, MA 02139, USA.\n\nPodaj te informacje o sposobie kontaktowania si z tob poczt\nelektroniczn lub zwyk.\n\nJeli dany program jest interaktywny, spraw, aby w momencie wchodzenia\nw tryb interaktywny wywietla on komunikat jak w poniszym przykadzie:\n\n    Gnomovision wersja 69, Copyright C 19.. nazwisko autora\n\n    Gnomovision wydawany jest ABSOLUTNIE BEZ ADNEJ GWARANCJI -\n    w celu uzyskania dalszych szczegw wpisz \"show w\".\n    To jest wolne oprogramowanie i mile widziane jest dalsze\n    rozpowszechnianie go przez ciebie na okrelonych warunkach -\n    w celu uzyskania bliszych szczegw wpisz \"show c\".\n\nPowysze hipotetyczne polecenia \"show w\" i \"show c\" winny powodowa\nwywietlenie odpowiednich czci Powszechnej Licencji Publicznej.\nOczywicie moesz uywa innych polece ni \"show w\" i \"show c\"; mog to\nby nawet kliknicia mysz lub pozycje menu - co tylko sobie uznasz za\nstosowne.\n\nPowiniene te poprosi swego pracodawc (jeli pracujesz jako\nprogramista) czy te swoj szko (jeli jeste uczniem), o podpisanie,\nw razie potrzeby, \"Rezygnacji z praw autorskich\" do programu. Poniej\npodajemy przykad (zmie nazwy/nazwiska):\n\n    My, firma Jojodyne Sp. z o.o. niniejszym zrzekamy si\n    i rezygnujemy z wszelkich interesw prawnych w zakresie\n    praw autorskich do programu \"Gnomovision\" (ktry realizuje\n    nastpujce funkcje...), napisanego przez p.Jana Kowalskiego.\n\n    /Podpis: /-/ Gniewosaw Wielkowany/\n\n    Gniewosaw Wielkowany, Prezes...itp\n\nPowszechna Licencja Publiczna nie zezwala na wczanie twego programu do\nprogramw prawnie zastrzeonych. Jeli twj program jest bibliotek\npodprogramw, moesz rozway, czy nie bdzie korzystniej zezwoli na\npowizanie prawnie zastrzeonych aplikacji z bibliotek. Jeli chciaby\nwanie tego dokona, zamiast niniejszej Licencji zastosuj Powszechn\nLicencj Publiczn GNU dla Bibliotek.\n"
  },
  {
    "path": "distrib/gpl-pt.txt",
    "content": "LICENA PBLICA GERAL GNU\nVerso 2, junho de 1991\n\n This is an unofficial translation of the GNU General Public License into\n Portuguese. It was not published by the Free Software Foundation, and does not\n legally state the distribution terms for software that uses the GNU GPL -- only\n the original English text of the GNU GPL does that. However, we hope that this\n translation will help Portuguese speakers understand the GNU GPL better.\n\n Esta  uma traduo no-oficial da Licena Pblica Geral GNU (\"GPL GNU\") para\n Portugus. No foi publicada pela Free Software Foundation, e legalmente no\n afirma os termos de distribuio de software que utilize a GPL GNU -- apenas o\n texto original da GPL GNU, em ingls, faz isso. Contudo, esperamos que esta\n traduo ajude aos que falam portugus a entender melhor a GPL GNU.\n\nPara sugestes ou correces a esta traduo, contacte:\n\nmiguel.andrade@neoscopio.com\n\n\n--- Traduo do documento original a partir desta linha ---\n\n\nLICENA PBLICA GERAL GNU\nVerso 2, junho de 1991\n\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave,\n Cambridge, MA 02139, USA\n\n A qualquer pessoa  permitido copiar e distribuir cpias deste documento de\n licena, desde que sem qualquer alterao.\n\nIntroduo\n\n As licenas de software so normalmente desenvolvidas para restringir a\n liberdade de compartilh-lo e modifica-lo. Pelo contrrio, a Licena Pblica\n Geral GNU pretende garantir a sua liberdade de compartilhar e modificar o\n software livre -- garantindo que o software ser livre para os seus\n utilizadores. Esta Licena Pblica Geral aplica-se  maioria do software da\n Free Software Foundation e a qualquer outro programa ao qual o seu autor decida\n aplic-la. (Algum software da FSF  cobertos pela Licena Pblica Geral de\n Bibliotecas.) Tambm poder aplic-la aos seus programas.\n\n Quando nos referimos a software livre, estamo-nos a referir  liberdade e no\n ao preo. A Licena Pblica Geral (GPL - General Public Licence - em Ingls.)\n foi desenvolvida para garantir a sua liberdade de distribuir cpias de software\n livre (e cobrar por isso, se quiser); receber o cdigo-fonte ou ter acesso a\n ele, se quiser; poder modificar o software ou utilizar partes dele em novos\n programas livres; e que saiba que est no seu direito de o fazer.\n\n Para proteger seus direitos, precisamos fazer restries que impeam a qualquer\n um negar estes direitos ou solicitar que voc abdique deles. Estas restries\n traduzem-se em certas responsabilidades para si, caso venha a distribuir cpias\n do software, ou modific-lo.\n\n Por exemplo, se voc distribuir cpias de um programa sobre este tipo de\n licenciamento, gratuitamente ou por alguma quantia, tem que fornecer igualmente\n todos os direitos que possui sobre ele. Tem igualmente que garantir que os\n destinatrios recebam ou possam obter o cdigo-fonte. Alm disto, tem que\n fornecer-lhes estes termos para que possam conhecer seus direitos.\n\n Ns protegemos seus direitos por duas formas que se completam: (1) com\n copyright do software e (2) com a oferta desta licena, que lhe d permisso\n legal para copiar, distribuir e/ou modificar o software.\n\n Alm disso, tanto para a proteco do autor quanto a nossa, gostaramos de\n certificar-nos de que todos entendam que no h qualquer garantia sobre o\n software livre. Se o software  modificado por algum e redistribudo, queremos\n que seus destinatrios saibam que o que eles obtiveram no  original, de forma\n que qualquer problema introduzido por terceiros no interfira na reputao do\n autor original.\n\n Finalmente, qualquer programa  ameaado constantemente por patentes de\n software. Queremos evitar o perigo de que distribuidores de software livre\n obtenham patentes individuais sobre o software, o que teria o efeito de tornar\n o software proprietrio. Para prevenir isso, deixamos claro que qualquer\n patente tem que ser licenciada para uso livre e gratuito por qualquer pessoa,\n ou ento que nem necessite ser licenciada.\n\n Os termos e condies precisas para cpia, distribuio e modificao\n encontram-se abaixo:\n\nLICENA PBLICA GERAL GNU TERMOS E CONDIES PARA CPIA, DISTRIBUIO E\nMODIFICAO\n\n 0. Esta licena aplica-se a qualquer programa ou outro trabalho que contenha um\n aviso colocado pelo detentor dos direitos autorais informando que aquele pode\n ser distribudo sob as condies desta Licena Pblica Geral. O \"Programa\"\n abaixo refere-se a qualquer programa ou trabalho e \"trabalho baseado no\n Programa\" significa tanto o Programa em si, como quaisquer trabalhos derivados,\n de acordo com a lei de direitos de autor: isto quer dizer um trabalho que\n contenha o Programa ou parte dele, tanto na forma original ou modificado, e/ou\n traduo para outros idiomas. ***(Doravante o termo \"modificao\" ou sinnimos\n sero usados livremente.) *** Cada licenciado  mencionado como \"voc\".\n\n Actividades outras que a cpia, a distribuio e modificao no esto cobertas\n por esta Licena; elas esto fora do seu mbito. O acto de executar o Programa\n no  restringido e o resultado do Programa  coberto pela licena apenas se o\n seu contedo contenha trabalhos baseados no Programa (independentemente de\n terem sido gerados pela execuo do Programa). Este ltimo ponto depende das\n funcionalidades especficas de cada programa.\n\n 1. Voc pode copiar e distribuir cpias fiis do cdigo-fonte do Programa da\n mesma forma que voc o recebeu, usando qualquer meio, deste que inclua em cada\n cpia um aviso de direitos de autor e uma declarao de inexistncia de\n garantias; mantenha intactos todos os avisos que se referem a esta Licena e \n ausncia total de garantias; e fornea aos destinatrios do Programa uma cpia\n desta Licena, em conjunto com o Programa.\n\n Voc pode cobrar pelo acto fsico de transferir uma cpia e pode,\n opcionalmente, oferecer garantias em troca de pagamento.\n\n 2. Voc pode modificar sua cpia ou cpias do Programa, ou qualquer parte dele,\n gerando assim um trabalho derivado, copiar e distribuir essas modificaes ou\n trabalhos sob os termos da seco 1 acima, desde que se enquadre nas seguintes\n condies:\n\n a) Os arquivos modificados devem conter avisos proeminentes afirmando que voc\n alterou os arquivos, incluindo a data de qualquer alterao.\n\n b) Deve ser licenciado, sob os termos desta Licena, integralmente e sem custo\n algum para terceiros, qualquer trabalho seu que contenha ou seja derivado do\n Programa ou de parte dele.\n\n c) Se qualquer programa modificado, quando executado, l normalmente comandos\n interactivamente, tem que fazer com que, quando iniciado o uso interactivo,\n seja impresso ou mostrado um anncio de que no h qualquer garantia (ou ento\n que voc fornece a garantia) e que os utilizadores podem redistribuir o\n programa sob estas condies, ainda informando os utilizadores como consultar\n uma cpia desta Licena. (Excepo: se o Programa em si  interactivo mas\n normalmente no imprime estes tipos de anncios, ento o seu trabalho derivado\n no precisa imprimir um anncio.)\n\n Estas exigncias aplicam-se ao trabalho derivado como um todo. Se seces\n identificveis de tal trabalho no so derivadas do Programa, e podem ser\n razoavelmente consideradas trabalhos independentes e separados por si s, ento\n esta Licena, e seus termos, no se aplicam a estas seces caso as distribua\n como um trabalho separado. Mas se distribuir as mesmas seces como parte de um\n todo que constitui trabalho derivado, a distribuio como um todo tem que\n enquadrar-se nos termos desta Licena, cujos direitos para outros licenciados\n se estendem ao todo, portanto tambm para toda e qualquer parte do programa,\n independente de quem a escreveu.\n\n Desta forma, esta seco no tem a inteno de reclamar direitos ou contestar\n seus direitos sobre o trabalho escrito completamente por si; ao invs disso, a\n inteno  a de exercitar o direito de controlar a distribuio de trabalhos,\n derivados ou colectivos, baseados no Programa.\n\n Adicionalmente, a mera adio ao Programa (ou a um trabalho derivado deste) de\n um outro trabalho num volume de armazenamento ou meio de distribuio no faz\n esse outro trabalho seja includo no mbito desta Licena.\n\n 3. Voc pode copiar e distribuir o Programa (ou trabalho derivado, conforme\n descrito na Seco 2) em cdigo-objecto ou em forma executvel sob os termos\n das Seces 1 e 2 acima, desde que cumpra uma das seguintes alienas:\n\n a) O faa acompanhar com o cdigo-fonte completo e em forma acessvel por\n mquinas, cdigo esse que tem que ser distribudo sob os termos das Seces 1 e\n 2 acima e em meio normalmente utilizado para o intercmbio de software; ou,\n\n b) O acompanhe com uma oferta escrita, vlida por pelo menos trs anos, de\n fornecer a qualquer um, com um custo no superior ao custo de distribuio\n fsica do material, uma cpia do cdigo-fonte completo e em forma acessvel por\n mquinas,  cdigo esse que tem que ser distribudo sob os termos das Seces 1\n e 2 acima e em meio normalmente utilizado para o intercmbio de software; ou,\n\n c) O acompanhe com a informao que voc recebeu em relao  oferta de\n distribuio do cdigo-fonte correspondente. (Esta alternativa  permitida\n somente em distribuio no comerciais, e apenas se voc recebeu o programa em\n forma de cdigo-objecto ou executvel, com uma oferta de acordo com a Subseco\n b) acima.)\n\n O cdigo-fonte de um trabalho corresponde  forma de trabalho preferida para se\n fazer modificaes. Para um trabalho em forma executvel, o cdigo-fonte\n completo significa todo o cdigo-fonte de todos os mdulos que ele contm, mais\n quaisquer arquivos de definio de \"interface\", mais os \"scripts\" utilizados\n para se controlar a compilao e a instalao do executvel. Contudo, como\n excepo especial, o cdigo-fonte distribudo no precisa incluir qualquer\n componente normalmente distribudo (tanto em forma original quanto binria) com\n os maiores componentes (o compilador, o \"kernel\" etc.) do sistema operativo sob\n o qual o executvel funciona, a menos que o componente em si acompanhe o\n executvel.\n\n Se a distribuio do executvel ou cdigo-objecto  feita atravs da oferta de\n acesso a cpias em algum lugar, ento oferecer o acesso equivalente a cpia, no\n mesmo lugar, do cdigo-fonte, equivale  distribuio do cdigo-fonte, mesmo\n que terceiros no sejam compelidos a copiar o cdigo-fonte em conjunto com o\n cdigo-objecto.\n\n 4. Voc no pode copiar, modificar, sublicenciar ou distribuir o Programa,\n excepto de acordo com as condies expressas nesta Licena. Qualquer outra\n tentativa de cpia, modificao, sublicenciamento ou distribuio do Programa\n no  valida, e cancelar automaticamente os direitos que lhe foram fornecidos\n por esta Licena. No entanto, terceiros que receberam de si cpias ou direitos,\n fornecidos sob os termos desta Licena, no tero a sua licena terminada,\n desde que permaneam em total concordncia com ela.\n\n 5. Voc no  obrigado a aceitar esta Licena j que no a assinou. No entanto,\n nada mais lhe dar permisso para modificar ou distribuir o Programa ou\n trabalhos derivados deste. Estas aces so proibidas por lei, caso voc no\n aceite esta Licena. Desta forma, ao modificar ou distribuir o Programa (ou\n qualquer trabalho derivado do Programa), voc estar a indicar a sua total\n concordncia com os termos desta Licena, nomeadamente os termos e condies\n para copiar, distribuir ou modificar o Programa, ou trabalhos baseados nele.\n\n 6. Cada vez que redistribuir o Programa (ou qualquer trabalho derivado), os\n destinatrios adquiriro automaticamente do autor original uma licena para\n copiar, distribuir ou modificar o Programa, sujeitos a estes termos e\n condies. Voc no poder impor aos destinatrios qualquer outra restrio ao\n exerccio dos direitos ento adquiridos. Voc no  responsvel em garantir a\n concordncia de terceiros a esta Licena.\n\n 7. Se, em consequncia de decises judiciais ou alegaes de violao de\n patentes ou quaisquer outras razes (no limitadas a assuntos relacionados a\n patentes), lhe forem impostas condies (por ordem judicial, acordos ou outras\n formas) e que contradigam as condies desta Licena, elas no o livram das\n condies desta Licena. Se no puder distribuir de forma a satisfazer\n simultaneamente suas obrigaes para com esta Licena e para com as outras\n obrigaes pertinentes, ento como consequncia voc no poder distribuir o\n Programa. Por exemplo, se uma licena de patente no permitir a redistribuio,\n sem obrigao ao pagamento de \"royalties\", por todos aqueles que receberem\n cpias directa ou indirectamente de si, ento a nica forma de voc satisfazer\n a licena de patente e a esta Licena seria a de desistir completamente de\n distribuir o Programa.\n\n Se qualquer parte desta seco for considerada invlida ou no aplicvel em\n qualquer circunstncia particular, o restante da seco aplica-se, e a seco\n como um todo aplicar-se- em outras circunstncias.\n\n O propsito desta seco no  o de induzi-lo a infringir quaisquer patentes ou\n reivindicao de direitos de propriedade de outros, ou a contestar a validade\n de quaisquer dessas reivindicaes; esta seco tem como nico propsito\n proteger a integridade dos sistemas de distribuio de software livre, que \n implementado pela prtica de licenas pblicas. Vrias pessoas tm contribudo\n generosamente e em grande escala para software distribudo usando este sistema,\n na certeza de que sua aplicao  feita de forma consistente; fica a critrio\n do autor/doador decidir se ele ou ela est disposto(a) a distribuir software\n utilizando outro sistema, e um outro detentor de uma licena no pode impor\n esta ou qualquer outra escolha.\n\n Esta seco destina-se a tornar bastante claro o que se acredita ser\n consequncia do restante desta Licena.\n\n 8. Se a distribuio e/ou uso do Programa so restringidos em certos pases por\n patentes ou direitos de autor, o detentor dos direitos de autor original, que\n colocou o Programa sob esta Licena, pode incluir uma limitao geogrfica de\n distribuio, excluindo aqueles pases, de forma a apenas permitir a\n distribuio nos pases no excludos. Nestes casos, esta Licena incorpora a\n limitao como se a mesma constasse escrita nesta Licena.\n\n 9. A Free Software Foundation pode publicar verses revistas e/ou novas da\n Licena Pblica Geral de tempos em tempos. Estas novas verses sero similares\n em esprito  verso actual, mas podem diferir em detalhes que resolvam novos\n problemas ou situaes.\n\n A cada verso  dada um nmero distinto. Se o Programa especifica um nmero de\n verso especfico desta Licena que se aplica a ele e a \"qualquer nova verso\",\n voc tem a opo de aceitar os termos e condies daquela verso ou de qualquer\n outra verso posterior publicada pela Free Software Foundation. Se o programa\n no especificar um nmero de verso desta Licena, poder escolher qualquer\n verso publicada pela Free Software Foundation.\n\n 10. Se voc pretende incorporar partes do Programa em outros programas livres\n cujas condies de distribuio sejam diferentes, escreva ao autor e solicite\n permisso para tal. Para o software que a Free Software Foundation detm\n direitos de autor, escreva  Free Software Foundation; s vezes ns permitimos\n excepes para estes casos. A nossa deciso ser guiada por dois objectivos: o\n de preservar a condio de liberdade de todas os trabalhos derivados do nosso\n software livre, e o de promover a partilha e reutilizao de software de um\n modo geral.\n\n\nAUSNCIA DE GARANTIAS\n\n 11. UMA VEZ QUE O PROGRAMA  LICENCIADO SEM NUS, NO H QUALQUER\n GARANTIA PARA O PROGRAMA, NA EXTENSO PERMITIDA PELAS LEIS\n APLICVEIS. EXCEPTO QUANDO EXPRESSO DE FORMA ESCRITA, OS\n DETENTORES DOS DIREITOS AUTORAIS E/OU TERCEIROS DISPONIBILIZAM O\n PROGRAMA \"COMO ESTA\", SEM QUALQUER TIPO DE GARANTIAS, EXPRESSAS\n OU IMPLCITAS, INCLUINDO, MAS NO LIMITADO A, S GARANTIAS\n IMPLCITAS DE COMERCIALIZAO E S DE ADEQUAO A QUALQUER\n PROPSITO. O RISCO COM A QUALIDADE E DESEMPENHO DO PROGRAMA\n  TOTALMENTE SEU. CASO O PROGRAMA SE REVELE DEFEITUOSO, VOC\n ASSUME OS CUSTOS DE TODAS AS MANUTENES, REPAROS E\n CORRECES QUE JULGUE NECESSRIAS.\n\n 12. EM NENHUMA CIRCUNSTNCIA, A MENOS QUE EXIGIDO PELAS LEIS\n APLICVEIS OU ACORDO ESCRITO, OS DETENTORES DOS DIREITOS DE\n AUTOR, OU QUALQUER OUTRA PARTE QUE POSSA MODIFICAR E/OU\n REDISTRIBUIR O PROGRAMA CONFORME PERMITIDO ACIMA, SERO\n RESPONSABILIZADOS POR SI OU POR SEU INTERMDIO, POR DANOS,\n INCLUINDO QUALQUER DANO EM GERAL, ESPECIAL, ACIDENTAL OU\n CONSEQUENTE, RESULTANTES DO USO OU INCAPACIDADE DE USO DO\n PROGRAMA (INCLUINDO, MAS NO LIMITADO A, A PERDA DE DADOS OU\n DADOS TORNADOS INCORRECTOS, OU PERDAS SOFRIDAS POR SI OU POR\n OUTRAS PARTES, OU FALHAS DO PROGRAMA AO OPERAR COM QUALQUER\n OUTRO PROGRAMA), MESMO QUE TAIS DETENTORES OU PARTES\n TENHAM SIDO AVISADOS DA POSSIBILIDADE DE TAIS DANOS.\n\nFIM DOS TERMOS E CONDIES\n\n---------------------\n\n\n\nComo Aplicar Estes Termos aos Seus Novos Programas\n\n Se voc desenvolver um novo programa, e quer que ele seja utilizado amplamente\n pelo pblico, a melhor forma de alcanar este objectivo  torn-lo software\n livre, software que qualquer um pode redistribuir e alterar, sob estes termos.\n\n Para tal, inclua os seguintes avisos no programa.  mais seguro inclui-los logo\n no incio de cada arquivo-fonte para reforar mais efectivamente a inexistncia\n de garantias; e cada arquivo deve conter pelo menos a linha de \"copyright\" e\n uma indicao sobre onde encontrar o texto completo da licena.\n\nExemplo:\n\n <uma linha que fornea o nome do programa e uma ideia do que ele faz.>\n Copyright (C) <ano> <nome do autor>\n\n Este programa  software livre; voc pode redistribu-lo e/ou modific-lo sob\n os termos da Licena Pblica Geral GNU, conforme publicada pela Free Software\n Foundation; tanto a verso 2 da Licena como (a seu critrio) qualquer verso\n mais actual.\n\n Este programa  distribudo na expectativa de ser til, mas SEM QUALQUER\n GARANTIA; incluindo as garantias implcitas de COMERCIALIZAO ou de\n ADEQUAO A QUALQUER PROPSITO EM PARTICULAR. Consulte a\n Licena Pblica Geral GNU para obter mais detalhes.\n\n Voc deve ter recebido uma cpia da Licena Pblica Geral GNU em conjunto com\n este programa; caso contrrio, escreva para a Free Software Foundation, Inc.,\n 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.\n\n\n\n Inclua tambm informaes sobre como contact-lo electronicamente e por carta.\n\n Se o programa  interactivo, faa-o mostrar um aviso breve como este, ao\n iniciar um modo interactivo:\n\nExemplo:\n\n\n Gnomovision verso 69, Copyright (C) <ano> <nome do autor> O Gnomovision no\n possui QUALQUER GARANTIA; para obter mais detalhes escreva `mostrar g'. \n software livre e voc est convidado a redistribui-lo sob certas condies;\n digite `mostrar c' para obter detalhes.\n\n Os comandos hipotticos `mostrar g e `mostrar c' devem mostrar as partes\n apropriadas da Licena Pblica Geral.  claro que os comandos que escolher usar\n podem ser activados de outra forma que `mostrar g' e `mostrar c'; podem ser\n cliques do rato ou itens de um menu -- o que melhor se adequar ao seu programa.\n\n Voc tambm deve obter da sua entidade patronal (se  trabalhar como\n programador) ou escola, conforme o caso, uma \"declarao de ausncia de\n direitos autorais\" sobre o programa, se necessrio. Aqui est um exemplo:\n\n\n Neoscopio Lda., declara a ausncia de quaisquer direitos autorais sobre o\n programa `Gnomovision' escrito por Jorge Andrade.\n\n10 de Junho de 2004\n <assinatura de Miguel Nunes>,\n\nMiguel Nunes, Gerente de Neoscopio Lda.\n\n\n\n Esta Licena Pblica Geral no permite incorporar o seu programa em programas\n proprietrios. Se o seu programa  uma biblioteca de sub-rotinas, poder\n considerar mais til permitir ligar aplicaes proprietrias com a biblioteca.\n Se  isto que pretende, use a Licena Pblica Geral de Bibliotecas GNU,\n em vez desta Licena.\n"
  },
  {
    "path": "distrib/gpl-pt_br.txt",
    "content": "\t\t      LICENA PBLICA GERAL GNU\n\t\t          Verso 2, junho de 1991\n\n This is an unofficial translation of the GNU General Public License\n into Brazilian Portuguese. It was not published by the Free Software\n   Foundation, and does not legally state the distribution terms for\n   software that uses the GNU GPL -- only the original English text of\n   the GNU GPL does that. However, we hope that this translation will\n  help Brazilian Portuguese speakers understand the GNU GPL better.\n\n  Esta  uma traduo no-oficial da Licena Pblica Geral GNU (\"GPL\n  GNU\") para o portugus do Brasil. Ela no foi publicada pela Free\nSoftware Foundation, e legalmente no afirma os termos de distribuio\n de software que utiliza a GPL GNU -- apenas o texto original da GPL\n GNU, em ingls, faz isso. Contudo, esperamos que esta traduo ajude\n aos que utilizam o portugus do Brasil a entender melhor a GPL GNU.\n\n   Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave,\n\t\t        Cambridge, MA 02139, USA\n\nA qualquer pessoa  permitido copiar e distribuir cpias desse\ndocumento de licena, desde que sem qualquer alterao.\n\n\t\t\t    Introduo\n\n  As licenas de muitos software so desenvolvidas para restringir sua\nliberdade de compartilh-lo e mud-lo. Contrria a isso, a Licena\nPblica Geral GNU pretende garantir sua liberdade de compartilhar e\nalterar software livres -- garantindo que o software ser livre e\ngratuito para os seus usurios. Esta Licena Pblica Geral aplica-se \nmaioria dos software da Free Software Foundation e a qualquer outro\nprograma cujo autor decida aplic-la. (Alguns outros software da FSF\nso cobertos pela Licena Pblica Geral de Bibliotecas, no entanto.)\nVoc pode aplic-la tambm aos seus programas.\n\n  Quando nos referimos a software livre, estamos nos referindo a\nliberdade e no a preo. Nossa Licena Pblica Geral foi desenvolvida\npara garantir que voc tenha a liberdade de distribuir cpias de\nsoftware livre (e cobrar por isso, se quiser); que voc receba o\ncdigo-fonte ou tenha acesso a ele, se quiser; que voc possa mudar o\nsoftware ou utilizar partes dele em novos programas livres e\ngratuitos; e que voc saiba que pode fazer tudo isso.\n\n  Para proteger seus direitos, precisamos fazer restries que impeam\na qualquer um negar estes direitos ou solicitar que voc deles\nabdique. Estas restries traduzem-se em certas responsabilidades para\nvoc, se voc for distribuir cpias do software ou modific-lo.\n\n  Por exemplo, se voc distribuir cpias de um programa, gratuitamente\nou por alguma quantia, voc tem que fornecer aos recebedores todos os\ndireitos que voc possui. Voc tem que garantir que eles tambm\nrecebam ou possam obter o cdigo-fonte. E voc tem que mostrar-lhes\nestes termos para que eles possam conhecer seus direitos.\n\n  Ns protegemos seus direitos em dois passos: (1) com copyright do\nsoftware e (2) com a oferta desta licena, que lhe d permisso legal\npara copiar, distribuir e/ou modificar o software.\n\n  Alm disso, tanto para a proteo do autor quanto a nossa,\ngostaramos de certificar-nos que todos entendam que no h qualquer\ngarantia nestes software livres. Se o software  modificado por algum\nmais e passado adiante, queremos que seus recebedores saibam que o que\neles obtiveram no  original, de forma que qualquer problema\nintroduzido por terceiros no interfira na reputao do autor\noriginal.\n\n  Finalmente, qualquer programa  ameaado constantemente por patentes\nde software. Queremos evitar o perigo de que distribuidores de\nsoftware livre obtenham patentes individuais, o que tem o efeito de\ntornar o programa proprietrio. Para prevenir isso, deixamos claro que\nqualquer patente tem que ser licenciada para uso livre e gratuito por\nqualquer pessoa, ou ento que nem necessite ser licenciada.\n\n  Os termos e condies precisas para cpia, distribuio e\nmodificao se encontram abaixo:\n\n\t\t      LICENA PBLICA GERAL GNU\n      TERMOS E CONDIES PARA CPIA, DISTRIBUIO E MODIFICAO\n\n  0. Esta licena se aplica a qualquer programa ou outro trabalho que\ncontenha um aviso colocado pelo detentor dos direitos autorais\ninformando que aquele pode ser distribudo sob as condies desta\nLicena Pblica Geral. O \"Programa\" abaixo refere-se a qualquer\nprograma ou trabalho, e \"trabalho baseado no Programa\" significa tanto\no Programa em si como quaisquer trabalhos derivados, de acordo com a\nlei de direitos autorais: isto quer dizer um trabalho que contenha o\nPrograma ou parte dele, tanto originalmente ou com modificaes, e/ou\ntraduo para outros idiomas. (Doravante o processo de traduo est\nincludo sem limites no termo \"modificao\".) Cada licenciado \nmencionado como \"voc\".\n\nAtividades outras que a cpia, a distribuio e modificao no esto\ncobertas por esta Licena; elas esto fora de seu escopo.  O ato de\nexecutar o Programa no  restringido e o resultado do Programa \ncoberto apenas se seu contedo contenha trabalhos baseados no Programa\n(independentemente de terem sido gerados pela execuo do\nPrograma). Se isso  verdadeiro depende do que o programa faz.\n\n  1. Voc pode copiar e distribuir cpias fiis do cdigo-fonte do\nPrograma da mesma forma que voc o recebeu, usando qualquer meio,\ndeste que voc conspcua e apropriadamente publique em cada cpia um\naviso de direitos autorais e uma declarao de inexistncia de\ngarantias; mantenha intactas todos os avisos que se referem a esta\nLicena e  ausncia total de garantias; e fornea a outros\nrecebedores do Programa uma cpia desta Licena, junto com o Programa.\n\nVoc pode cobrar pelo ato fsico de transferir uma cpia e pode,\nopcionalmente, oferecer garantia em troca de pagamento.\n\n  2. Voc pode modificar sua cpia ou cpias do Programa, ou qualquer\nparte dele, assim gerando um trabalho baseado no Programa, e copiar e\ndistribuir essas modificaes ou trabalhos sob os termos da seo 1\nacima, desde que voc tambm se enquadre em todas estas condies:\n\n    a) Voc tem que fazer com que os arquivos modificados levem avisos\n    proeminentes afirmando que voc alterou os arquivos, incluindo a\n    data de qualquer alterao.\n\n    b) Voc tem que fazer com que quaisquer trabalhos que voc\n    distribua ou publique, e que integralmente ou em partes contenham\n    ou sejam derivados do Programa ou de suas partes, sejam\n    licenciados, integralmente e sem custo algum para quaisquer\n    terceiros, sob os termos desta Licena.\n\n    c) Se qualquer programa modificado normalmente l comandos\n    interativamente quando executados, voc tem que fazer com que,\n    quando iniciado tal uso interativo da forma mais simples, seja\n    impresso ou mostrado um anncio de que no h qualquer garantia\n    (ou ento que voc fornece a garantia) e que os usurios podem\n    redistribuir o programa sob estas condies, ainda informando os\n    usurios como consultar uma cpia desta Licena. (Exceo: se o\n    Programa em si  interativo mas normalmente no imprime estes\n    tipos de anncios, seu trabalho baseado no Programa no precisa\n    imprimir um anncio.)\n\nEstas exigncias aplicam-se ao trabalho modificado como um todo. Se\nsees identificveis de tal trabalho no so derivadas do Programa, e\npodem ser razoavelmente consideradas trabalhos independentes e\nseparados por si s, ento esta Licena, e seus termos, no se aplicam\na estas sees quando voc distribui-las como trabalhos em\nseparado. Mas quando voc distribuir as mesmas sees como parte de um\ntodo que  trabalho baseado no Programa, a distribuio como um todo\ntem que se enquadrar nos termos desta Licena, cujas permisses para\noutros licenciados se estendem ao todo, portanto tambm para cada e\ntoda parte independente de quem a escreveu.\n\nDesta forma, esta seo no tem a inteno de reclamar direitos os\ncontestar seus direitos sobre o trabalho escrito completamente por\nvoc; ao invs disso, a inteno  a de exercitar o direito de\ncontrolar a distribuio de trabalhos, derivados ou coletivos,\nbaseados no Programa.\n\nAdicionalmente, a mera adio ao Programa de outro trabalho no\nbaseado no Programa (ou de trabalho baseado no Programa) em um volume\nde armazenamento ou meio de distribuio no faz o outro trabalho\nparte do escopo desta Licena.\n\n  3. Voc pode copiar e distribuir o Programa (ou trabalho baseado\nnele, conforme descrito na Seo 2) em cdigo-objeto ou em forma\nexecutvel sob os termos das Sees 1 e 2 acima, desde que voc\nfaa um dos seguintes:\n\n    a) O acompanhe com o cdigo-fonte completo e em forma acessvel\n    por mquinas, que tem que ser distribudo sob os termos das Sees\n    1 e 2 acima e em meio normalmente utilizado para o intercmbio de\n    software; ou,\n\n    b) O acompanhe com uma oferta escrita, vlida por pelo menos trs\n    anos, de fornecer a qualquer um, com um custo no superior ao\n    custo de distribuio fsica do material, uma cpia do\n    cdigo-fonte completo e em forma acessvel por mquinas, que tem\n    que ser distribudo sob os termos das Sees 1 e 2 acima e em meio\n    normalmente utilizado para o intercmbio de software; ou,\n\n    c) O acompanhe com a informao que voc recebeu em relao \n    oferta de distribuio do cdigo-fonte correspondente. (Esta\n    alternativa  permitida somente em distribuio no comerciais, e\n    apenas se voc recebeu o programa em forma de cdigo-objeto ou\n    executvel, com oferta de acordo com a Subseo b acima.)\n\nO cdigo-fonte de um trabalho corresponde  forma de trabalho\npreferida para se fazer modificaes. Para um trabalho em forma\nexecutvel, o cdigo-fonte completo significa todo o cdigo-fonte de\ntodos os mdulos que ele contm, mais quaisquer arquivos de definio\nde \"interface\", mais os \"scripts\" utilizados para se controlar a\ncompilao e a instalao do executvel. Contudo, como exceo\nespecial, o cdigo-fonte distribudo no precisa incluir qualquer\ncomponente normalmente distribudo (tanto em forma original quanto\nbinria) com os maiores componentes (o compilador, o \"kernel\" etc.) do\nsistema operacional sob o qual o executvel funciona, a menos que o\ncomponente em si acompanhe o executvel.\n\nSe a distribuio do executvel ou cdigo-objeto  feita atravs da\noferta de acesso a cpias de algum lugar, ento ofertar o acesso\nequivalente a cpia, do mesmo lugar, do cdigo-fonte equivale \ndistribuio do cdigo-fonte, mesmo que terceiros no sejam compelidos\na copiar o cdigo-fonte com o cdigo-objeto.\n\n  4. Voc no pode copiar, modificar, sub-licenciar ou distribuir o\nPrograma, exceto de acordo com as condies expressas nesta\nLicena. Qualquer outra tentativa de cpia, modificao,\nsub-licenciamento ou distribuio do Programa no  valida, e\ncancelar automaticamente os direitos que lhe foram fornecidos por\nesta Licena. No entanto, terceiros que de voc receberam cpias ou\ndireitos, fornecidos sob os termos desta Licena, no tero suas\nlicenas terminadas, desde que permaneam em total concordncia com\nela.\n\n  5. Voc no  obrigado a aceitar esta Licena j que no a\nassinou. No entanto, nada mais o dar permisso para modificar ou\ndistribuir o Programa ou trabalhos derivados deste. Estas aes so\nproibidas por lei, caso voc no aceite esta Licena. Desta forma, ao\nmodificar ou distribuir o Programa (ou qualquer trabalho derivado do\nPrograma), voc estar indicando sua total aceitao desta Licena\npara faz-los, e todos os seus termos e condies para copiar,\ndistribuir ou modificar o Programa, ou trabalhos baseados nele.\n\n  6. Cada vez que voc redistribuir o Programa (ou qualquer trabalho\nbaseado nele), os recebedores adquiriro automaticamente do\nlicenciador original uma licena para copiar, distribuir ou modificar\no Programa, sujeitos a estes termos e condies. Voc no poder impor\naos recebedores qualquer outra restrio ao exerccio dos direitos\nento adquiridos. Voc no  responsvel em garantir a concordncia de\nterceiros a esta Licena.\n\n  7. Se, em conseqncia de decises judiciais ou alegaes de\ninfringimento de patentes ou quaisquer outras razes (no limitadas a\nassuntos relacionados a patentes), condies forem impostas a voc\n(por ordem judicial, acordos ou outras formas) e que contradigam as\ncondies desta Licena, elas no o livram das condies desta\nLicena. Se voc no puder distribuir de forma a satisfazer\nsimultaneamente suas obrigaes para com esta Licena e para com as\noutras obrigaes pertinentes, ento como conseqncia voc no poder\ndistribuir o Programa. Por exemplo, se uma licena de patente no\npermitir a redistribuio, livre de \"royalties\", do Programa, por\ntodos aqueles que receberem cpias direta ou indiretamente de voc,\nento a nica forma de voc satisfazer a ela e a esta Licena seria a\nde desistir completamente de distribuir o Programa.\n\nSe qualquer parte desta seo for considerada invlida ou no\naplicvel em qualquer circunstncia particular, o restante da seo se\naplica, e a seo como um todo se aplica em outras circunstncias.\n\nO propsito desta seo no  o de induzi-lo a infringir quaisquer\npatentes ou reivindicao de direitos de propriedade outros, ou a\ncontestar a validade de quaisquer dessas reivindicaes; esta seo\ntem como nico propsito proteger a integridade dos sistemas de\ndistribuio de software livres, o que  implementado pela prtica de\nlicenas pblicas. Vrias pessoas tm contribudo generosamente e em\ngrande escala para os software distribudos usando este sistema, na\ncerteza de que sua aplicao  feita de forma consistente; fica a\ncritrio do autor/doador decidir se ele ou ela est disposto a\ndistribuir software utilizando outro sistema, e um licenciado no pode\nimpor qualquer escolha.\n\nEsta seo destina-se a tornar bastante claro o que se acredita ser\nconseqncia do restante desta Licena.\n\n  8. Se a distribuio e/ou uso do Programa so restringidos em certos\npases por patentes ou direitos autorais, o detentor dos direitos\nautorais original, e que colocou o Programa sob esta Licena, pode\nincluir uma limitao geogrfica de distribuio, excluindo aqueles\npases de forma a tornar a distribuio permitida apenas naqueles ou\nentre aqueles pases ento no excludos. Nestes casos, esta Licena\nincorpora a limitao como se a mesma constasse escrita nesta Licena.\n\n  9. A Free Software Foundation pode publicar verses revisadas e/ou\nnovas da Licena Pblica Geral de tempos em tempos. Estas novas\nverses sero similares em esprito  verso atual, mas podem diferir\nem detalhes que resolvem novos problemas ou situaes.\n\nA cada verso  dada um nmero distinto. Se o Programa especifica um\nnmero de verso especfico desta Licena que se aplica a ele e a\n\"qualquer nova verso\", voc tem a opo de aceitar os termos e\ncondies daquela verso ou de qualquer outra verso publicada pela\nFree Software Foundation. Se o programa no especifica um nmero de\nverso desta Licena, voc pode escolher qualquer verso j publicada\npela Free Software Foundation.\n\n  10. Se voc pretende incorporar partes do Programa em outros\nprogramas livres cujas condies de distribuio so diferentes,\nescreva ao autor e solicite permisso. Para o software que a Free\nSoftware Foundation detm direitos autorais, escreva  Free Software\nFoundation; s vezes ns permitimos excees a este caso. Nossa\ndeciso ser guiada pelos dois objetivos de preservar a condio de\nliberdade de todas as derivaes do nosso software livre, e de\npromover o compartilhamento e reutilizao de software em aspectos\ngerais.\n\n\t\t\tAUSNCIA DE GARANTIAS\n\n  11. UMA VEZ QUE O PROGRAMA  LICENCIADO SEM NUS, NO H\nQUALQUER GARANTIA PARA O PROGRAMA, NA EXTENSO PERMITIDA PELAS\nLEIS APLICVEIS. EXCETO QUANDO EXPRESSADO DE FORMA ESCRITA, OS\nDETENTORES DOS DIREITOS AUTORAIS E/OU TERCEIROS DISPONIBILIZAM\nO PROGRAMA \"NO ESTADO\", SEM QUALQUER TIPO DE GARANTIAS,\nEXPRESSAS OU IMPLCITAS, INCLUINDO, MAS NO LIMITADO A, AS\nGARANTIAS IMPLCITAS DE COMERCIALIZAO E AS DE ADEQUAO A\nQUALQUER PROPSITO. O RISCO TOTAL COM A QUALIDADE E DESEMPENHO\nDO PROGRAMA  SEU. SE O PROGRAMA SE MOSTRAR DEFEITUOSO, VOC\nASSUME OS CUSTOS DE TODAS AS MANUTENES, REPAROS E CORREES.\n\n  12. EM NENHUMA OCASIO, A MENOS QUE EXIGIDO PELAS LEIS\nAPLICVEIS OU ACORDO ESCRITO, OS DETENTORES DOS DIREITOS\nAUTORAIS, OU QUALQUER OUTRA PARTE QUE POSSA MODIFICAR E/OU\nREDISTRIBUIR O PROGRAMA CONFORME PERMITIDO ACIMA, SERO\nRESPONSABILIZADOS POR VOC POR DANOS, INCLUINDO QUALQUER DANO\nEM GERAL, ESPECIAL, ACIDENTAL OU CONSEQENTE, RESULTANTES DO\nUSO OU INCAPACIDADE DE USO DO PROGRAMA (INCLUINDO, MAS NO\nLIMITADO A, A PERDA DE DADOS OU DADOS TORNADOS INCORRETOS, OU\nPERDAS SOFRIDAS POR VOC OU POR OUTRAS PARTES, OU FALHAS DO\nPROGRAMA AO OPERAR COM QUALQUER OUTRO PROGRAMA), MESMO QUE\nTAL DETENTOR OU PARTE TENHAM SIDO AVISADOS DA POSSIBILIDADE\nDE TAIS DANOS.\n\n\t\t      FIM DOS TERMOS E CONDIES\n\n\t  Como Aplicar Estes Termos aos Seus Novos Programas\n\n  Se voc desenvolver um novo programa, e quer que ele seja utilizado\namplamente pelo pblico, a melhor forma de alcanar este objetivo \ntorn-lo software livre que qualquer um pode redistribuir e alterar,\nsob estes termos.\n\n  Para isso, anexe os seguintes avisos ao programa.  mais seguro\nanex-los logo no incio de cada arquivo-fonte para reforarem mais\nefetivamente a inexistncia de garantias; e cada arquivo deve possuir\npelo menos a linha de \"copyright\" e uma indicao de onde o texto\ncompleto se encontra.\n\n    <uma linha que fornea o nome do programa e uma idia do que ele faz.>\n    Copyright (C) <ano>  <nome do autor>\n\n    Este programa  software livre; voc pode redistribu-lo e/ou\n    modific-lo sob os termos da Licena Pblica Geral GNU, conforme\n    publicada pela Free Software Foundation; tanto a verso 2 da\n    Licena como (a seu critrio) qualquer verso mais nova.\n\n    Este programa  distribudo na expectativa de ser til, mas SEM\n    QUALQUER GARANTIA; sem mesmo a garantia implcita de\n    COMERCIALIZAO ou de ADEQUAO A QUALQUER PROPSITO\n\tEM PARTICULAR. Consulte a Licena Pblica Geral GNU para obter\n\tmais detalhes.\n\n    Voc deve ter recebido uma cpia da Licena Pblica Geral GNU\n    junto com este programa; se no, escreva para a Free Software\n    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA\n    02111-1307, USA.\n\nInclua tambm informaes sobre como contact-lo eletronicamente e por\ncarta.\n\nSe o programa  interativo, faa-o mostrar um aviso breve como este,\nao iniciar um modo interativo:\n\n    Gnomovision verso 69, Copyright (C) ano nome do autor\n    O Gnomovision no possui QUALQUER GARANTIA; para obter mais\n    detalhes digite `show w'. Ele  software livre e voc est\n    convidado a redistribui-lo sob certas condies; digite `show c'\n    para obter detalhes.\n\nOs comandos hipotticos `show w' e `show c' devem mostrar as partes\napropriadas da Licena Pblica Geral. Claro, os comandos que voc usar\npodem ser ativados de outra forma que `show w' e `show c'; eles podem\nat ser cliques do mouse ou itens de um menu -- o que melhor se\nadequar ao programa.\n\nVoc tambm deve obter do seu empregador (se voc trabalha como\nprogramador) ou escola, se houver, uma \"declarao de ausncia de\ndireitos autorais\" sobre o programa, se necessrio. Aqui est um\nexemplo; altere os nomes:\n\n   Yoyodyne, Inc., aqui declara a ausncia de quaisquer direitos\n   autorais sobre o programa `Gnomovision' (que executa interpretaes\n   em compiladores) escrito por James Hacker.\n\n   <assinatura de Ty Coon>, 1o. de abril de 1989\n   Ty Con, Vice-presidente\n\nEsta Licena Pblica Geral no permite incorporar seu programa em\nprogramas proprietrios. Se seu programa  uma biblioteca de\nsub-rotinas, voc deve considerar mais til permitir ligar aplicaes\nproprietrias com a biblioteca. Se isto  o que voc deseja, use a\nLicena Pblica Geral de Bibliotecas GNU, ao invs desta Licena.\n"
  },
  {
    "path": "distrib/gpl-ru.txt",
    "content": "This is an unofficial translation of the GNU General Public License into Russian language. It was not published by the Free Software Foundation, and does not legally state the distribution terms for software that uses the GNU GPL—only the original English text of the GNU GPL does that. However, we hope that this translation will help language speakers understand the GNU GPL better.\n\nЭто неофициальный перевод GNU General Public License на русский язык. Он был опубликован не Фондом свободного программного обеспечения и не содержит условий распространения программ, которые используют GNU GPL -- для этого пригоден только ее исходный английский текст. Тем не менее мы надеемся, что этот перевод поможет лучше понять ее текст.\nВы можете распространять перевод, с изменениями или без, только с соблюдением условий, описанных по адресу: http://www.gnu.org/licenses/translations.html.\n\n      Генеральная публичная лицензия GNU. Редакция 2, Июнь 1991 г.\n\nCopyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Перевод: Павел Протасов <pvphome@gmail.com>, 2002, 2016. Разрешается свободно копировать и распространять текст настоящей Лицензии, запрещается вносить в него изменения.\n\n      Введение\n\n  Лицензионные договоры на использование большинства программных продуктов составлены так, чтобы запретить Вам распространять и изменять их. Генеральная публичная лицензия GNU, напротив, ставит своей целью обеспечить Вам право на распространение и изменение, то есть убедиться в том, что все пользователи программы могут свободно использовать ее. На условиях, изложенных в настоящей Лицензии, осуществляется использование большей части программ Фонда свободного программного обеспечения, а также любой программы, автор которой соглашается с этими условиями. (На некоторые из программ Фонда свободного программного обеспечения распространяет свое действие Малая Генеральная публичная лицензия GNU). Вы также можете распространять свои программы на этих условиях.\n\n  Когда нами употребляется термин \"свободное программное обеспечение\", он относится к свободе использования, а не к бесплатности. Наши Генеральные публичные лицензии составлены так, чтобы обеспечить Вам свободное распространение копий свободного программного обеспечения (при желании Вы можете брать за это плату); получение исходных текстов, либо возможность их получения по желанию; внесение в программу изменений, а также использование ее частей в новых свободных программах; знание того, что Вы можете совершать эти действия.\n\n  Для того, чтобы защитить Ваши права, мы должны исключить возможность отказа в их предоставлении либо понуждения к отказу от них. Эти ограничения налагают определенную ответственность и на Вас, если Вы распространяете ее копии или изменяете ее.\n\n  Например, если Вы распространяете копии такой программы, безвозмездно или за плату, Вы должны предоставить пользователям все те права, которые имеете сами. Вы также должны быть уверены в том, что они получили или могут получить исходные тексты. Также Вы должны ознакомить их с условиями настоящего соглашения для того, чтобы они знали о своих правах.\n\n  Мы защищаем Ваши права при помощи следующих мер: (1) закрепляем авторское право на программу и (2) предлагаем Вам принять условия настоящей Лицензии, закрепляющей Ваше право на создание копий, распространение и (или) модификацию программного обеспечения.\n\n  Также, для защиты каждого автора и своей собственной защиты, мы хотим быть уверены в том, что каждый уведомлен об отсутствии гарантий на настоящее свободное программное обеспечение. Если программа изменена кем-либо и осуществляется распространение ее измененной версии, мы хотим уведомить пользователей о том, что это -- не первоначальный вариант, чтобы проблемы, вызванные другими, не отразились на деловой репутации автора исходной программы.\n\n  И наконец, любой свободной программе постоянно угрожает возможность ее патентования. Мы хотим исключить возможность получения распространителями программы патентов на нее, вследствие чего программа станет их собственностью. Для предотвращения этого мы разъясняем, что любому лицу должно быть предоставлено право на свободное использование любого такого патента, в противном случае такое право не должно предоставляться никому.\n\n  Детальные определения используемых терминов и описание условий копирования, распространения и внесения изменений приведены ниже.\n\n      ГЕНЕРАЛЬНАЯ ПУБЛИЧНАЯ ЛИЦЕНЗИЯ GNU\n\n      ТЕРМИНЫ И УСЛОВИЯ КОПИРОВАНИЯ, РАСПРОСТРАНЕНИЯ И ВНЕСЕНИЯ ИЗМЕНЕНИЙ\n\n  0. Настоящая Лицензия распространяет свое действие на любую программу или другое произведение, которое содержит уведомление правообладателя о том, что ее (его) использование осуществляется на условиях настоящей Генеральной публичной лицензии. Термин \"Программа\" в дальнейшем обозначает любую такую программу или произведение, а \"произведение, основанное на Программе\" обозначает Программу или производное произведение, защищенное авторским правом, то есть содержащее в себе саму Программу либо ее часть в неизменном или модифицированном виде и (или) переведенную на другой язык. (В дальнейшем понятие перевода целиком включается в понятие модификации ). Лицо, присоединившееся к Соглашению , в дальнейшем именуется \"Вы\".\n\n  На действия, отличные от копирования, распространения и модификации, настоящая Лицензия не распространяется; они не входят в сферу ее действия. Функционирование Программы ею не ограничено, на порождаемую Программой информацию она распространяется только в том случае, если эта информация является произведением, основанным на Программе (независимо от того, была она получена при запуске Программы или нет). Истинность этого условия зависит от того, какие действия выполняет Программа.\n\n  1. После получения исходного текста Программы Вы можете создавать его копии и распространять его без внесения изменений на любом носителе, при условии сопровождения каждой копии надлежащим уведомлением об авторских правах и отказе от предоставления гарантий, сделанным таким образом, чтобы обеспечить ознакомление с ним пользователя; оставления в неизменном виде всех уведомлений, относящихся к настоящей Лицензии и отсутствию гарантий; передачи другим получателям Программы копии настоящей Лицензии вместе с ней.\n\n  Вы можете брать плату за передачу экземпляра Программы, также Вы можете по своему усмотрению предлагать пользователям гарантийное обслуживание за вознаграждение.\n\n  2. Вы можете перерабатывать свою копию (копии) Программы или любой ее части, создавая таким образом произведение, основанное на Программе; воспроизводить и распространять такие изменения или само произведение на условиях Раздела 1, приведенного выше, при соблюдении следующих условий:\n\n    a) Вы обязаны снабдить измененные файлы в месте, заметном для пользователя, сообщением о том, что файл изменен, и датой каждого изменения.\n\n    b) Вы обязаны заключить со всеми третьими лицами договор на использование любого произведения, содержащего Программу или ее часть либо основанного на ней или на ее части с условиями, содержащимися в настоящей Лицензии.\n\n    c) Если модифицированная программа при работе получает команды в диалоговом режиме, Вы должны сделать так, чтобы при обычном начале работы в таком режиме она выводила сообщение, включающее в себя надлежащее оповещение об авторских правах и об отказе от предоставления гарантий (или, наоборот, об их предоставлении Вами); уведомление пользователя о том, что он может распространять программу на этих условиях, и сведения о том, как пользователь может ознакомиться с копией настоящей Лицензии. (Примечание: если Программа работает в диалоговом режиме, но обычно не выводит подобных сообщений, от вашего произведения, основанного на Программе, этого также не требуется).\n\n  Эти требования применяются ко всему производному произведению в целом. Если могущие быть идентифицированными части такого произведения не являются производными от Программы и сами по себе могут обоснованно считаться самостоятельными и независимыми произведениями, то, в случае отдельного их распространения, условия, изложенные в настоящей Лицензии, к ним не применяются. Однако в случае распространения тех же частей в составном произведении, основанном на Программе, их распространение должно осуществляться на условиях настоящей Лицензии; при этом права, приобретаемые пользователями на ее основании, распространяются на составное произведение в целом, включая каждую из его частей, независимо от того, кто является ее автором.\n\n  Таким образом, целью данного раздела Лицензии является не предъявление претензий или оспаривание Ваших прав на произведение, автором которого Вы являетесь; скорее, его цель состоит в обеспечении права на контроль за распространением производных и составных произведений, основанных на Программе.\n\n  Кроме того, простое объединение Программы с другим произведением, не основанным на Программе (либо произведением, основанным на Программе), на одном устройстве памяти или дистрибутивном носителе информации, не ведет к распространению условий настоящей Лицензии на это произведение.\n\n  3. Вы можете копировать и распространять Программу (либо основанное на ней произведение, созданное соответствии с Разделом 2), в виде объектного кода или в форме, пригодной для функционирования, в соответствии с условиями, описанными в приведенных выше Разделах 1 и 2, при выполнении одного из следующих действий:\n\n    a) Прилагая к ней полный исходный текст в машинно-читаемой форме, распространяемый на условиях, описанных в приведенных выше Разделах 1 и 2, способом, обычно используемым для обмена программным обеспечением; или\n\n    b) Прилагая к ней в письменной форме действительное в течение трех лет предложение передать любому третьему лицу за плату, не превышающую издержек, понесенных Вами при совершении передачи, машинно-читаемую копию полного исходного текста произведения, на условиях, описанных в приведенных выше Разделах 1 и 2, способом, обычно используемым для обмена программным обеспечением; или\n\n    c) Прилагая к ней информацию, полученную Вами в качестве предложения передать полный исходный текст. (Соблюдение данного условия допускается только при распространении без извлечения прибыли и только в случаях, когда Вы получили программу, в виде объектного кода или в исполняемой форме, в комплекте с таким предложением, описанным в приведенном выше подразделе b).\n\n  Под исходным текстом понимается произведение в форме, наиболее подходящей для внесения в него изменений. Для произведения в исполняемой форме под полным исходным текстом понимается исходный текст всех составляющих его модулей, любые прилагаемые файлы с описанием интерфейса, тексты сценариев, используемых для управления процессами компиляции и установки исполняемых файлов. Однако, в порядке исключения, в распространяемый исходный текст не нужно включать то, что обычно распространяется ( как в виде исходного текста, так и объектного кода) с основными компонентами (компилятор, ядро и т.п.) операционной системы, под управлением которой происходит выполнение исполняемого файла, за исключением случаев, когда исполняемый файл комплектуется этим компонентом.\n\n  Если распространение исполняемого файла или объектного кода осуществляется с помощью предоставления доступа для копирования из определенного источника, предложение аналогичной возможности копирования исходного текста из того же источника приравнивается к распространению исходного текста, даже в том случае, если возможно копирование объектного кода отдельно от исходного текста.\n\n  4. Вам запрещается копировать, изменять, сублицензировать или распространять Программу иначе, чем на условиях, описанных в настоящей Лицензии. Любая попытка копирования, изменения, сублицензирования или распространения Программы иначе не имеет юридической силы и автоматически лишает Вас прав, предоставленных настоящей Лицензией. Однако соглашения с третьими лицами, получившими от Вас копии программы или права, предоставляемые настоящим Соглашением, не прекращают своего действия до тех пор, пока указанные лица соблюдают его условия.\n\n  5. В случае, если Вы не подписали настоящую Лицензию, от Вас не требуется принятия ее условий. Однако изменение или распространение Программы или основанных на ней произведений на иных условиях не разрешается. Если Вы не исполняете условий настоящей Лицензии, Ваши действия преследуются по закону. Следовательно, изменяя или распространяя Программу (либо произведение, основанное на Программе), Вы выражаете свое согласие с условиями настоящей Лицензии и ее условиями на копирование, распространение и изменение Программы или произведений, основанных на ней.\n\n  6. Каждый раз, когда Вы распространяете полученную от других лиц Программу (или любое произведение, основанное на Программе), ее получатель автоматически принимает условия соглашения с первоначальным правообладателем на копирование, распространение и изменение Программы, описанные в настоящей Лицензии. В дальнейшем Вы не можете налагать ограничения на осуществление пользователем предоставленных ему прав, описанных выше. Вы не несете ответственности за несоблюдение третьими лицами условий настоящей Лицензии.\n\n  7. Если вследствие судебного решения, заявления о нарушении патента или по любой иной причине (не ограниченной патентными спорами) на Вас наложены обязательства (по решению суда, соглашению или на ином основании), которые противоречат условиям настоящей Лицензии, это не освобождает Вас от соблюдения условий настоящей Лицензии. Если Вы не можете заниматься распространением, исполняя обязательства, наложенные на Вас настоящей Лицензией, одновременно с другими обязательствами, Вы не должны распространять Программу. Например, если условиями соглашения об использовании патента пользователям, получившим экземпляры Программы непосредственно от Вас или через посредников, не разрешено самим безвозмездно распространять их, то единственным способом удовлетворения его условий и условий настоящей Лицензии будет отказ от распространения Программы.\n\n  В случае, если любое из положений настоящего раздела решением суда было признано не имеющим силы либо не подлежащим применению в конкретном случае, остальные положения раздела подлежат применению; весь раздел целиком подлежит применению в иных случаях.\n\n  Целью настоящего раздела не является побуждение Вас к нарушению патентных или иных имущественных прав либо оспаривание юридической силы любого положения или договора из области этих прав; его назначение состоит исключительно в защите принципов системы распространения свободного программного обеспечения, которые закрепляются посредством публичных лицензий. Многие люди оказали большое содействие в разработке большого числа программ, распространяемых подобным образом, будучи уверенными в последовательном применении этих принципов; вопрос о том, распространять ли программное обеспечение на других условиях, решается автором (лицом, оказывающим поддержку) самостоятельно, лицензиат не может влиять на принятие данного решения.\n\n  Назначение этого раздела состоит в окончательном разъяснении последствий применения остальной части настоящей Лицензии.\n\n  8. Если распространение и (или) использование Программы в отдельных государствах ограничено нормами авторского или патентного права, правообладатель, первоначально распространивший на Программу условия настоящей Лицензии, может в явной форме ограничить территорию ее распространения, исключив из нее такие страны, с тем, чтобы разрешить распространение только внутри остальных стран либо между ними. В этом случае такое условие включается в настоящую Лицензию, имея одинаковую силу с условиями, содержащимися в ее тексте.\n\n  9. Фонд свободного программного обеспечения может публиковать измененные и (или) новые редакции Генеральной публичной лицензии. Такие редакции будут сходны в основных принципах с настоящей редакцией, но могут отличаться от нее в деталях, направленных на решение новых проблем и вопросов.\n\n  Каждой редакции присваивается собственный уникальный номер. Если в документации на Программу указан номер редакции настоящей Лицензии, условия которой распространяются на нее, а также слова \"и любые следующие версии (редакции)\", то Вы имеете право выбора между условиями этой редакции и любой редакции, опубликованной Фондом свободного программного обеспечения после нее. Если для Программы не указан номер редакции Лицензии, Вы можете выбрать любую редакцию, опубликованную Фондом свободного программного обеспечения.\n\n  10. Если Вы намереваетесь включить части Программы в состав другого свободного программного обеспечения, условия распространения которого отличаются от условий, описанных в настоящей Лицензии, Вы должны получить на это разрешение автора. Для программы, авторское право на которую принадлежит Фонду свободного программного обеспечения, разрешение следует получать у Фонда; иногда мы делаем исключения в таких случаях. При этом мы руководствуемся двумя целями: обеспечением сохранения своего статуса всеми произведениями, основанными на свободном программном обеспечении, и достижением более широкого распространения и использования программного обеспечения вообще.\n\n      ОТСУТСТВИЕ ГАРАНТИЙ\n\n  11. Поскольку использование Программы осуществляется безвозмездно, на нее не предоставляется никаких гарантий, за исключением тех, которые установлены действующим законодательством. Если иное не указано в письменной форме, правообладатели и (или) иные стороны предоставляют Программу в том виде, в котором осуществляется ее распространение, без принятия на себя каких-либо гарантийных обязательств, как выраженных явно, так и подразумеваемых, в том числе подразумеваемых гарантий качества и пригодности для конкретных целей. Вы несете все риски, касающиеся качества и работы Программы. В случае, если в Программе будут обнаружены недостатки, на Вас возлагаются все расходы, связанные с обслуживанием, восстановлением или исправлением Программы.\n\n  12. Если иное не предусмотрено действующим законодательством или соглашением сторон, заключенным в письменной форме, правообладатель или иное лицо, которое имеет возможность изменять и (или) повторно распространять Программу на условиях, сформулированных выше, не может нести ответственность перед Вами за причиненный ущерб, включая ущерб общего либо специфического характера, причиненный случайно или являющийся следствием использования программы либо невозможности ее использования (в том числе уничтожение или модификацию информации, либо убытки, понесенные вами или третьими лицами, либо сбои Программы при взаимодействии с другим программным обеспечением), в том числе и в случаях, когда правообладатель или третье лицо предупреждены о возможности причинения таких убытков.\n\n      КОНЕЦ ОПРЕДЕЛЕНИЙ И УСЛОВИЙ\n\n      Порядок применения условий Лицензии к Вашим программам\n\n  Если Вы разрабатываете новую программу и хотите, чтобы ее использование принесло максимальную пользу обществу, наилучший способ достичь этого -- сделать ее свободной, чтобы все могли распространять и изменять ее на условиях настоящей Лицензии\n\n  Для этого сделайте так, чтобы программа содержала в себе описанные ниже уведомления. Наиболее надежным способом для этого является включение их в начало каждого файла исходного текста, чтобы наиболее эффективным образом сообщить об отсутствии гарантий; каждый файл должен иметь по меньшей мере строку с оповещением об авторских правах и указание на то, где находится полный текст уведомлений.\n\n    <Строка с названием программы и информацией о ее назначении.> Copyright © <год выпуска программы в свет> <имя автора>\n\n    Эта программа является свободной; Вы можете распространять ее и (или) изменять, соблюдая условия Генеральной публичной лицензии GNU, опубликованной Фондом свободного программного обеспечения; либо редакции 2 Лицензии, либо (на ваше усмотрение) любой редакции, выпущенной позже.\n\n    Эта программа распространяется в надежде на то, что она окажется полезной, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, включая подразумеваемую гарантию КАЧЕСТВА либо ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробности содержатся в Генеральной публичной лицензии GNU.\n\n    Вместе с этой программой должен распространяться экземпляр Генеральной публичной лицензии GNU, если он отсутствует, сообщите об этом в Фонд свободного программного обеспечения (Free Software Foundation, Inc.), 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n\n  Также добавьте информацию о том, как связаться с Вами посредством электронной или обычной почты.\n\n  Если программа работает в диалоговом режиме, сделайте так, чтобы при начале такого режима работы она выводила короткое сообщение, подобное приведенному ниже:\n\n    Gnomovision версии 69, © год первого выпуска программы в свет; имя автора. Gnomovision распространяется БЕЗО ВСЯКИХ ГАРАНТИЙ; для получения подробной информации, введите команду \"show w\". Это свободное программное обеспечение, Вы можете распространять его, соблюдая определенные условия; для того, чтобы с ними ознакомиться, введите команду \"show c\".\n\n  Гипотетические команды \"show w\" и \"show c\" должны приводить к выводу соответствующих частей Генеральной публичной лицензии. Разумеется, команды, которые используете Вы, могут быть названы иначе, не \"show w\" и \"show c\"; они могут представлять собой нажатия кнопок мыши или выбор пунктов меню -- то есть все, что можно выполнить при работе с программой.\n\n  Вы также должны получить от своего работодателя (если вы работаете программистом) или, при необходимости, учебного заведения, письменный отказ от исключительных прав на нее, если это необходимо. Ниже приведен образец, Вы можете использовать его, заменив имена:\n\n    Yoyodyne, Inc. отказывается от всех исключительных прав на использование программы 'Gnomovision' (выполняющей проходы компилятора), написанной Джеймсом Хакером.\n\n    <Подпись>, 1 апреля 1989 г. Тай Кун, заместитель директора\n\n  Условиями настоящей Генеральной публичной лицензии не разрешается включать Вашу программу в состав программы, которая не удовлетворяет критериям свободного программного обеспечения. Если ваша программа представляет собой библиотеку процедур, Вы можете прийти к выводу, что более полезным было бы разрешение на связывание ее с такой программой. Если Вы хотите сделать это, используйте условия Малой Генеральной публичной лицензии GNU вместо условий настоящей Лицензии.\n"
  },
  {
    "path": "distrib/gpl.txt",
    "content": "\t\t    GNU GENERAL PUBLIC LICENSE\n\t\t       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n\t\t\t    Preamble\n\n  The licenses for most software are designed to take away your\nfreedom to share and change it.  By contrast, the GNU General Public\nLicense is intended to guarantee your freedom to share and change free\nsoftware--to make sure the software is free for all its users.  This\nGeneral Public License applies to most of the Free Software\nFoundation's software and to any other program whose authors commit to\nusing it.  (Some other Free Software Foundation software is covered by\nthe GNU Library General Public License instead.)  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthis service if you wish), that you receive source code or can get it\nif you want it, that you can change the software or use pieces of it\nin new free programs; and that you know you can do these things.\n\n  To protect your rights, we need to make restrictions that forbid\nanyone to deny you these rights or to ask you to surrender the rights.\nThese restrictions translate to certain responsibilities for you if you\ndistribute copies of the software, or if you modify it.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must give the recipients all the rights that\nyou have.  You must make sure that they, too, receive or can get the\nsource code.  And you must show them these terms so they know their\nrights.\n\n  We protect your rights with two steps: (1) copyright the software, and\n(2) offer you this license which gives you legal permission to copy,\ndistribute and/or modify the software.\n\n  Also, for each author's protection and ours, we want to make certain\nthat everyone understands that there is no warranty for this free\nsoftware.  If the software is modified by someone else and passed on, we\nwant its recipients to know that what they have is not the original, so\nthat any problems introduced by others will not reflect on the original\nauthors' reputations.\n\n  Finally, any free program is threatened constantly by software\npatents.  We wish to avoid the danger that redistributors of a free\nprogram will individually obtain patent licenses, in effect making the\nprogram proprietary.  To prevent this, we have made it clear that any\npatent must be licensed for everyone's free use or not licensed at all.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n\t\t    GNU GENERAL PUBLIC LICENSE\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License applies to any program or other work which contains\na notice placed by the copyright holder saying it may be distributed\nunder the terms of this General Public License.  The \"Program\", below,\nrefers to any such program or work, and a \"work based on the Program\"\nmeans either the Program or any derivative work under copyright law:\nthat is to say, a work containing the Program or a portion of it,\neither verbatim or with modifications and/or translated into another\nlanguage.  (Hereinafter, translation is included without limitation in\nthe term \"modification\".)  Each licensee is addressed as \"you\".\n\nActivities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning the Program is not restricted, and the output from the Program\nis covered only if its contents constitute a work based on the\nProgram (independent of having been made by running the Program).\nWhether that is true depends on what the Program does.\n\n  1. You may copy and distribute verbatim copies of the Program's\nsource code as you receive it, in any medium, provided that you\nconspicuously and appropriately publish on each copy an appropriate\ncopyright notice and disclaimer of warranty; keep intact all the\nnotices that refer to this License and to the absence of any warranty;\nand give any other recipients of the Program a copy of this License\nalong with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and\nyou may at your option offer warranty protection in exchange for a fee.\n\n  2. You may modify your copy or copies of the Program or any portion\nof it, thus forming a work based on the Program, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) You must cause the modified files to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in\n    whole or in part contains or is derived from the Program or any\n    part thereof, to be licensed as a whole at no charge to all third\n    parties under the terms of this License.\n\n    c) If the modified program normally reads commands interactively\n    when run, you must cause it, when started running for such\n    interactive use in the most ordinary way, to print or display an\n    announcement including an appropriate copyright notice and a\n    notice that there is no warranty (or else, saying that you provide\n    a warranty) and that users may redistribute the program under\n    these conditions, and telling the user how to view a copy of this\n    License.  (Exception: if the Program itself is interactive but\n    does not normally print such an announcement, your work based on\n    the Program is not required to print an announcement.)\n\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Program,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Program, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Program.\n\nIn addition, mere aggregation of another work not based on the Program\nwith the Program (or with a work based on the Program) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may copy and distribute the Program (or a work based on it,\nunder Section 2) in object code or executable form under the terms of\nSections 1 and 2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable\n    source code, which must be distributed under the terms of Sections\n    1 and 2 above on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three\n    years, to give any third party, for a charge no more than your\n    cost of physically performing source distribution, a complete\n    machine-readable copy of the corresponding source code, to be\n    distributed under the terms of Sections 1 and 2 above on a medium\n    customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer\n    to distribute corresponding source code.  (This alternative is\n    allowed only for noncommercial distribution and only if you\n    received the program in object code or executable form with such\n    an offer, in accord with Subsection b above.)\n\nThe source code for a work means the preferred form of the work for\nmaking modifications to it.  For an executable work, complete source\ncode means all the source code for all modules it contains, plus any\nassociated interface definition files, plus the scripts used to\ncontrol compilation and installation of the executable.  However, as a\nspecial exception, the source code distributed need not include\nanything that is normally distributed (in either source or binary\nform) with the major components (compiler, kernel, and so on) of the\noperating system on which the executable runs, unless that component\nitself accompanies the executable.\n\nIf distribution of executable or object code is made by offering\naccess to copy from a designated place, then offering equivalent\naccess to copy the source code from the same place counts as\ndistribution of the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\n  4. You may not copy, modify, sublicense, or distribute the Program\nexcept as expressly provided under this License.  Any attempt\notherwise to copy, modify, sublicense or distribute the Program is\nvoid, and will automatically terminate your rights under this License.\nHowever, parties who have received copies, or rights, from you under\nthis License will not have their licenses terminated so long as such\nparties remain in full compliance.\n\n  5. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Program or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Program (or any work based on the\nProgram), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n\n  6. Each time you redistribute the Program (or any work based on the\nProgram), the recipient automatically receives a license from the\noriginal licensor to copy, distribute or modify the Program subject to\nthese terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties to\nthis License.\n\n  7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Program at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Program by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under\nany particular circumstance, the balance of the section is intended to\napply and the section as a whole is intended to apply in other\ncircumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system, which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\n  8. If the distribution and/or use of the Program is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Program under this License\nmay add an explicit geographical distribution limitation excluding\nthose countries, so that distribution is permitted only in or among\ncountries not thus excluded.  In such case, this License incorporates\nthe limitation as if written in the body of this License.\n\n  9. The Free Software Foundation may publish revised and/or new versions\nof the General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Program\nspecifies a version number of this License which applies to it and \"any\nlater version\", you have the option of following the terms and conditions\neither of that version or of any later version published by the Free\nSoftware Foundation.  If the Program does not specify a version number of\nthis License, you may choose any version ever published by the Free Software\nFoundation.\n\n  10. If you wish to incorporate parts of the Program into other free\nprograms whose distribution conditions are different, write to the author\nto ask for permission.  For software which is copyrighted by the Free\nSoftware Foundation, write to the Free Software Foundation; we sometimes\nmake exceptions for this.  Our decision will be guided by the two goals\nof preserving the free status of all derivatives of our free software and\nof promoting the sharing and reuse of software generally.\n\n\t\t\t    NO WARRANTY\n\n  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO\nWARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE\nLAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\"\nWITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,\nINCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE\nENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS\nWITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE\nCOST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN\nWRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY\nMODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE\nLIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,\nINCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR\nINABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS\nOF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED\nBY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE\nWITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY\nHAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\n\n\t\t     END OF TERMS AND CONDITIONS\n\n\t    How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nconvey the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program; if not, write to the Free Software\n    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program is interactive, make it output a short notice like this\nwhen it starts in an interactive mode:\n\n    Gnomovision version 69, Copyright (C) year name of author\n    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, the commands you use may\nbe called something other than `show w' and `show c'; they could even be\nmouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a programmer) or your\nschool, if any, to sign a \"copyright disclaimer\" for the program, if\nnecessary.  Here is a sample; alter the names:\n\n  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n\n  <signature of Ty Coon>, 1 April 1989\n  Ty Coon, President of Vice\n\nThis General Public License does not permit incorporating your program into\nproprietary programs.  If your program is a subroutine library, you may\nconsider it more useful to permit linking proprietary applications with the\nlibrary.  If this is what you want to do, use the GNU Library General\nPublic License instead of this License.\n"
  },
  {
    "path": "distrib/lgpl_for_used_libs.txt",
    "content": "\t\t  GNU LESSER GENERAL PUBLIC LICENSE\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License Agreement applies to any software library or other\nprogram which contains a notice placed by the copyright holder or\nother authorized party saying it may be distributed under the terms of\nthis Lesser General Public License (also called \"this License\").\nEach licensee is addressed as \"you\".\n\n  A \"library\" means a collection of software functions and/or data\nprepared so as to be conveniently linked with application programs\n(which use some of those functions and data) to form executables.\n\n  The \"Library\", below, refers to any such software library or work\nwhich has been distributed under these terms.  A \"work based on the\nLibrary\" means either the Library or any derivative work under\ncopyright law: that is to say, a work containing the Library or a\nportion of it, either verbatim or with modifications and/or translated\nstraightforwardly into another language.  (Hereinafter, translation is\nincluded without limitation in the term \"modification\".)\n\n  \"Source code\" for a work means the preferred form of the work for\nmaking modifications to it.  For a library, complete source code means\nall the source code for all modules it contains, plus any associated\ninterface definition files, plus the scripts used to control compilation\nand installation of the library.\n\n  Activities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning a program using the Library is not restricted, and output from\nsuch a program is covered only if its contents constitute a work based\non the Library (independent of the use of the Library in a tool for\nwriting it).  Whether that is true depends on what the Library does\nand what the program that uses the Library does.\n\n  1. You may copy and distribute verbatim copies of the Library's\ncomplete source code as you receive it, in any medium, provided that\nyou conspicuously and appropriately publish on each copy an\nappropriate copyright notice and disclaimer of warranty; keep intact\nall the notices that refer to this License and to the absence of any\nwarranty; and distribute a copy of this License along with the\nLibrary.\n\n  You may charge a fee for the physical act of transferring a copy,\nand you may at your option offer warranty protection in exchange for a\nfee.\n\n  2. You may modify your copy or copies of the Library or any portion\nof it, thus forming a work based on the Library, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) The modified work must itself be a software library.\n\n    b) You must cause the files modified to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    c) You must cause the whole of the work to be licensed at no\n    charge to all third parties under the terms of this License.\n\n    d) If a facility in the modified Library refers to a function or a\n    table of data to be supplied by an application program that uses\n    the facility, other than as an argument passed when the facility\n    is invoked, then you must make a good faith effort to ensure that,\n    in the event an application does not supply such function or\n    table, the facility still operates, and performs whatever part of\n    its purpose remains meaningful.\n\n    (For example, a function in a library to compute square roots has\n    a purpose that is entirely well-defined independent of the\n    application.  Therefore, Subsection 2d requires that any\n    application-supplied function or table used by this function must\n    be optional: if the application does not supply it, the square\n    root function must still compute square roots.)\n\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Library,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Library, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote\nit.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Library.\n\nIn addition, mere aggregation of another work not based on the Library\nwith the Library (or with a work based on the Library) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may opt to apply the terms of the ordinary GNU General Public\nLicense instead of this License to a given copy of the Library.  To do\nthis, you must alter all the notices that refer to this License, so\nthat they refer to the ordinary GNU General Public License, version 2,\ninstead of to this License.  (If a newer version than version 2 of the\nordinary GNU General Public License has appeared, then you can specify\nthat version instead if you wish.)  Do not make any other change in\nthese notices.\n\n  Once this change is made in a given copy, it is irreversible for\nthat copy, so the ordinary GNU General Public License applies to all\nsubsequent copies and derivative works made from that copy.\n\n  This option is useful when you wish to copy part of the code of\nthe Library into a program that is not a library.\n\n  4. You may copy and distribute the Library (or a portion or\nderivative of it, under Section 2) in object code or executable form\nunder the terms of Sections 1 and 2 above provided that you accompany\nit with the complete corresponding machine-readable source code, which\nmust be distributed under the terms of Sections 1 and 2 above on a\nmedium customarily used for software interchange.\n\n  If distribution of object code is made by offering access to copy\nfrom a designated place, then offering equivalent access to copy the\nsource code from the same place satisfies the requirement to\ndistribute the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\n  5. A program that contains no derivative of any portion of the\nLibrary, but is designed to work with the Library by being compiled or\nlinked with it, is called a \"work that uses the Library\".  Such a\nwork, in isolation, is not a derivative work of the Library, and\ntherefore falls outside the scope of this License.\n\n  However, linking a \"work that uses the Library\" with the Library\ncreates an executable that is a derivative of the Library (because it\ncontains portions of the Library), rather than a \"work that uses the\nlibrary\".  The executable is therefore covered by this License.\nSection 6 states terms for distribution of such executables.\n\n  When a \"work that uses the Library\" uses material from a header file\nthat is part of the Library, the object code for the work may be a\nderivative work of the Library even though the source code is not.\nWhether this is true is especially significant if the work can be\nlinked without the Library, or if the work is itself a library.  The\nthreshold for this to be true is not precisely defined by law.\n\n  If such an object file uses only numerical parameters, data\nstructure layouts and accessors, and small macros and small inline\nfunctions (ten lines or less in length), then the use of the object\nfile is unrestricted, regardless of whether it is legally a derivative\nwork.  (Executables containing this object code plus portions of the\nLibrary will still fall under Section 6.)\n\n  Otherwise, if the work is a derivative of the Library, you may\ndistribute the object code for the work under the terms of Section 6.\nAny executables containing that work also fall under Section 6,\nwhether or not they are linked directly with the Library itself.\n\n  6. As an exception to the Sections above, you may also combine or\nlink a \"work that uses the Library\" with the Library to produce a\nwork containing portions of the Library, and distribute that work\nunder terms of your choice, provided that the terms permit\nmodification of the work for the customer's own use and reverse\nengineering for debugging such modifications.\n\n  You must give prominent notice with each copy of the work that the\nLibrary is used in it and that the Library and its use are covered by\nthis License.  You must supply a copy of this License.  If the work\nduring execution displays copyright notices, you must include the\ncopyright notice for the Library among them, as well as a reference\ndirecting the user to the copy of this License.  Also, you must do one\nof these things:\n\n    a) Accompany the work with the complete corresponding\n    machine-readable source code for the Library including whatever\n    changes were used in the work (which must be distributed under\n    Sections 1 and 2 above); and, if the work is an executable linked\n    with the Library, with the complete machine-readable \"work that\n    uses the Library\", as object code and/or source code, so that the\n    user can modify the Library and then relink to produce a modified\n    executable containing the modified Library.  (It is understood\n    that the user who changes the contents of definitions files in the\n    Library will not necessarily be able to recompile the application\n    to use the modified definitions.)\n\n    b) Use a suitable shared library mechanism for linking with the\n    Library.  A suitable mechanism is one that (1) uses at run time a\n    copy of the library already present on the user's computer system,\n    rather than copying library functions into the executable, and (2)\n    will operate properly with a modified version of the library, if\n    the user installs one, as long as the modified version is\n    interface-compatible with the version that the work was made with.\n\n    c) Accompany the work with a written offer, valid for at\n    least three years, to give the same user the materials\n    specified in Subsection 6a, above, for a charge no more\n    than the cost of performing this distribution.\n\n    d) If distribution of the work is made by offering access to copy\n    from a designated place, offer equivalent access to copy the above\n    specified materials from the same place.\n\n    e) Verify that the user has already received a copy of these\n    materials or that you have already sent this user a copy.\n\n  For an executable, the required form of the \"work that uses the\nLibrary\" must include any data and utility programs needed for\nreproducing the executable from it.  However, as a special exception,\nthe materials to be distributed need not include anything that is\nnormally distributed (in either source or binary form) with the major\ncomponents (compiler, kernel, and so on) of the operating system on\nwhich the executable runs, unless that component itself accompanies\nthe executable.\n\n  It may happen that this requirement contradicts the license\nrestrictions of other proprietary libraries that do not normally\naccompany the operating system.  Such a contradiction means you cannot\nuse both them and the Library together in an executable that you\ndistribute.\n\n  7. You may place library facilities that are a work based on the\nLibrary side-by-side in a single library together with other library\nfacilities not covered by this License, and distribute such a combined\nlibrary, provided that the separate distribution of the work based on\nthe Library and of the other library facilities is otherwise\npermitted, and provided that you do these two things:\n\n    a) Accompany the combined library with a copy of the same work\n    based on the Library, uncombined with any other library\n    facilities.  This must be distributed under the terms of the\n    Sections above.\n\n    b) Give prominent notice with the combined library of the fact\n    that part of it is a work based on the Library, and explaining\n    where to find the accompanying uncombined form of the same work.\n\n  8. You may not copy, modify, sublicense, link with, or distribute\nthe Library except as expressly provided under this License.  Any\nattempt otherwise to copy, modify, sublicense, link with, or\ndistribute the Library is void, and will automatically terminate your\nrights under this License.  However, parties who have received copies,\nor rights, from you under this License will not have their licenses\nterminated so long as such parties remain in full compliance.\n\n  9. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Library or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Library (or any work based on the\nLibrary), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Library or works based on it.\n\n  10. Each time you redistribute the Library (or any work based on the\nLibrary), the recipient automatically receives a license from the\noriginal licensor to copy, distribute, link with or modify the Library\nsubject to these terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties with\nthis License.\n\n  11. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Library at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Library by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Library.\n\nIf any portion of this section is held invalid or unenforceable under any\nparticular circumstance, the balance of the section is intended to apply,\nand the section as a whole is intended to apply in other circumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\n  12. If the distribution and/or use of the Library is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Library under this License may add\nan explicit geographical distribution limitation excluding those countries,\nso that distribution is permitted only in or among countries not thus\nexcluded.  In such case, this License incorporates the limitation as if\nwritten in the body of this License.\n\n  13. The Free Software Foundation may publish revised and/or new\nversions of the Lesser General Public License from time to time.\nSuch new versions will be similar in spirit to the present version,\nbut may differ in detail to address new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Library\nspecifies a version number of this License which applies to it and\n\"any later version\", you have the option of following the terms and\nconditions either of that version or of any later version published by\nthe Free Software Foundation.  If the Library does not specify a\nlicense version number, you may choose any version ever published by\nthe Free Software Foundation.\n\n  14. If you wish to incorporate parts of the Library into other free\nprograms whose distribution conditions are incompatible with these,\nwrite to the author to ask for permission.  For software which is\ncopyrighted by the Free Software Foundation, write to the Free\nSoftware Foundation; we sometimes make exceptions for this.  Our\ndecision will be guided by the two goals of preserving the free status\nof all derivatives of our free software and of promoting the sharing\nand reuse of software generally.\n\n\t\t\t    NO WARRANTY\n\n  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO\nWARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.\nEXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR\nOTHER PARTIES PROVIDE THE LIBRARY \"AS IS\" WITHOUT WARRANTY OF ANY\nKIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE\nLIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME\nTHE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN\nWRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY\nAND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU\nFOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR\nCONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE\nLIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING\nRENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A\nFAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF\nSUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH\nDAMAGES.\n\n\t\t     END OF TERMS AND CONDITIONS"
  },
  {
    "path": "distrib/rst_migration_notes.txt",
    "content": "\n(no this file is not in RST format, there's no need)\n\nTreatment of index.htm\n----------------------\n\nindex.htm doesn't get moved to .rst because .rst doesn't\nsupport frames.  index.htm also doesn't do anything except\nload overview.htm in the left pane and syntax.htm (default)\nin the right pane.\n\nSo index.htm is preserved in HTML form and gets special\ntreatment so the frame-based display of the original docs\nis kept after the installation process runs rst2html. On\nGithub it means nothing.\n\nFor pure .rst documentation it's not needed, though it may\ncome in handy when rst2html and/or rst2pdf get used.\n\n\nConversion of HTML to RST\n-------------------------\n\nTo convert the HTML files in a directory to RST, do the\nfollowing in bash:\n\nfor n in *.htm ; do\n    iconv -f <codepage> -t utf-8 \"$n\" | pandoc --from=html --to=rst - -o \"${n%.*}.rst\"\ndone\n\nReplace <codepage> in the iconv command with the codepage of the\noriginal docs' language.  The old .htm files can be deleted since\nbackups already exist in docs/htm/.  Keeping the old docs as\nreference while proof-checking the .rst versions is an option,\nbut remember to remove them when everything's done so that the\nonly HTML copies remaining are the backups in docs/htm/.\n\nTo not worry about the encoding of the .rst file, it's advisable\nto do this under Linux. The above works on Windows (provided you\nhave bash and iconv installed), but the user must be aware of/use\ntext editors that acknowledge UTF-8 encoded text files without a\nBOM (in other words, not Notepad). Also, restview is annoying to\nworry about installing on Windows, so it's probably best not to\neven try.\n\n\nBe aware that pandoc can be finicky in regard to what text it\nactually converts: during the process of checking faq.rst, I\nrealized that it hadn't converted entire blocks of text, and\nhad deleted them from the output file.  So make sure to check\nagainst the original HTML version to make sure all the text\nis actually there.\n\nWhy use pandoc then?  Because unfortunately, html2rst (which\ndoesn't seem to have this particular problem) can't handle\nnon-English text (or perhaps more precisely, non-CP1252 text),\neven if the text encoding of the file itself is UTF-8. It ends\nup mangling non-CP1252 text into an unrecognizable mess of ???s,\nif it converts at all.  pandoc doesn't have this problem, and\ncan correctly handle this.  It also tends to be more readily-\ncorrect syntactically than html2rst, but it's more verbose\n(lots of unnecessary syntax elements for things).\n\nI actually used html2rst to do the initial conversions of\nlike, 99% of the English and FilterSDK documentation, because\nI simply didn't realize pandoc existed at the time. The upside\nof this is that I actually had to get a firmer grasp of RST\nsyntax.\n\n\nGenerating HTML docs from RST\n-----------------------------\n\nWhen generating rst docs to html, use:\n\nrst2html --stylesheet=<filename> --link-stylesheet \"$n\"\n\nwhere <filename> is the name of the .css stylesheet that was\nlinked to in the old documentation.\n\n\n\nSome basic style guidelines:\n----------------------------\n\nLinks\n-----\n\nLinks that consist only of a URL should look like:\n`<url>`__\n\nRST actually will *probably* parse plain urls as urls\nwithout needing the `<>`__ stuff, but it's better to\nbe explicit about it.\n\nThe __ format also resolves 'duplicate explicit name'\nerrors from rst2html when more than one tag uses the\nsame name, so they're preferred everywhere a link occurs\n(the only reason the English docs don't strictly adhere\nto this is because most of it was converted before I\nnoticed that feature, so the tags themselves were changed\nin order to avoid the error).\n\nTry to avoid the use of footnote markup for links.\nThankfully, pandoc seems to adhere to this idea, and\ndoesn't generate them, instead putting links inline\n(but it will do `url <url>`__, which needs simplifying).\nThe reason the English docs use the footnote markup is\nbecause they weren't generated with pandoc (mostly), and\nhtml2rst *does* use the footnote style.\n\n\nTables of contents\n------------------\n\nIf a table of contents is present in the HTML, use\n\n.. contents:: Table of contents\n    :depth: 3\n\nto automatically generate a table of contents from the section\nheaders, and delete the original. A depth of 3 isn't necessarily\nneeded, just make sure all the items from the original TOC are\npresent in the auto-generated one.\n\n\nSection numbering\n-----------------\n\nIf the TOC's contents were numbered, use\n\n.. sectnum::\n    :depth: 3\n    :suffix: .\n\nto automatically number the section headers and TOC contents.\nLike the previous caveat, a depth of 3 isn't necessarily needed.\nThe suffix, however, is, since the section numbering in the\nAviSynth docs were almost always of the form: 1.1.2.\n\n\nTables\n------\n\nTables should always use the grid style. It may be more verbose,\nbut it's more flexible on possible customization and more strict\non syntax.\n\nTables should use top-header style in the subject row, ex.\n\n+---+---+\n| 1 | 2 |\n+===+===+\n| A | B |\n+---+---+\n| C | D |\n+---+---+\n| E | F |\n+---+---+\n\nSubdividing a subject row (ex: corefilters/crop.rst) is allowed\nto use normal ** ** emphasis on the subject lines that would\nnot get bolded by the ====.\n\n+-------+-------+\n| **1** | **2** |\n+-------+---+---+\n|       | 3 | 4 |\n+=======+===+===+\n| A     | B | C |\n+-------+---+---+\n| D     | E | F |\n+-------+---+---+\n| G     | H | I |\n+-------+---+---+\n\n\nSection headers\n---------------\n\nSection headers follow in the order:\n====\n----\n\nThe following may or may not be recognized\n~~~~\n^^^^\n....\n::::\n\nUse ==== on all top-headers, and generally no-where else,\nwith exception for multiple heading sections that are all\npacked in the same file; this is mostly a concern for the\nfilter-specific docs (ex: corefilters/conditionalfilter.rst).\nThe others get used with discretion.  It's a good idea to\nuse :::: or .... to make .. contents:: ignore the 'Abstract'\nin the externalfilters docs.\n\nOtherwise, try to stick close to what the original docs used\nfor particular sections in regard to bold, italic,\nnewline/paragraphs, indentation, and such.  Or just match the\nEnglish RST documentation (that's probably easier)."
  },
  {
    "path": "plugins/CMakeLists.txt",
    "content": "include_directories(${AvsCore_SOURCE_DIR}/include)\n\n# These plugins are for Windows only\nif (WIN32)\n  # VDubFilter is x86/x64-only, so default to OFF unless target is x86/x64.\n  set(VDUBFILTER_DEFAULT \"OFF\")\n  if (CMAKE_VS_PLATFORM_NAME STREQUAL \"Win32\" OR CMAKE_VS_PLATFORM_NAME STREQUAL \"x64\")\n       set(VDUBFILTER_DEFAULT \"ON\")\n  endif()\n\n  option(BUILD_VDUBFILTER \"Build VDubFilter plugin\" ${VDUBFILTER_DEFAULT})\n  option(BUILD_VDUBFILTER \"Build VDubFilter plugin\" ON)\n  #option(BUILD_VFAPIFILTER \"Build VFAPIFilter plugin\" ON)\nendif()\n\n# DevIL detection: skip auto detection if paths are pre-supplied via -DIL_LIBRARIES=...\nif(IL_LIBRARIES AND IL_INCLUDE_DIR)\n  message(STATUS \"DevIL paths pre-supplied, skipping auto-detection.\")\n  set(DevIL_FOUND TRUE)\n  set(DEVIL_PLUGIN_STATE ON)\nelse()\n  include(FindDevIL) # official CMake module\n  if(DevIL_FOUND)\n    set(DEVIL_PLUGIN_STATE ON)\n  else()\n    MESSAGE(WARNING \"DevIL library not found. ImageSeq plugin will not be built.\")\n    set(DEVIL_PLUGIN_STATE OFF)\n  endif()\nendif()\n\n# SoundTouch detection: skip auto-detection if paths are pre-supplied via -DSOUNDTOUCH_LINK_LIBRARIES=...\nif(SOUNDTOUCH_LINK_LIBRARIES AND SOUNDTOUCH_INCLUDE_DIRS)\n  message(STATUS \"SoundTouch paths pre-supplied, skipping auto-detection.\")\n  set(SOUNDTOUCH_PLUGIN_STATE ON)\nelse()\n  find_package(PkgConfig)\n  if(PkgConfig_FOUND)\n    pkg_check_modules(SOUNDTOUCH soundtouch)\n  endif()\n\n  if(SOUNDTOUCH_FOUND)\n    set(SOUNDTOUCH_PLUGIN_STATE ON)\n  else()\n    # check to see if SoundTouch's CMake files were installed and whether the library itself exists\n    MESSAGE(WARNING \"SoundTouch not found by pkg-config, falling back to CMake detection\")\n    find_package(SoundTouch)\n    find_library(SOUNDTOUCH SoundTouch PATH ${SoundTouch_LIBRARY_DIRS})\n    if(SoundTouch_FOUND)\n      # override the SOUNDTOUCH_LINK_LIBRARIES and SOUNDTOUCH_INCLUDE_DIRS variables\n      # that pkg-config would have set, and allow these to be overridden at configure time as well\n      set(SOUNDTOUCH_LINK_LIBRARIES ${SOUNDTOUCH} CACHE PATH \"Path to SoundTouch library\")\n      set(SOUNDTOUCH_INCLUDE_DIRS ${CMAKE_PREFIX_PATH}/include/soundtouch CACHE PATH \"Path to SoundTouch headers\")\n      set(SOUNDTOUCH_PLUGIN_STATE ON)\n    else()\n      MESSAGE(WARNING \"SoundTouch library not found. TimeStretch plugin will not be built.\")\n      set(SOUNDTOUCH_PLUGIN_STATE OFF)\n    endif()\n  endif()\nendif()\n\noption(BUILD_IMAGESEQ \"Build ImageSeq plugin\" ${DEVIL_PLUGIN_STATE})\noption(BUILD_TIMESTRETCH \"Build TimeStretch plugin\" ${SOUNDTOUCH_PLUGIN_STATE})\noption(BUILD_SHIBATCH \"Build Shibatch plugin\" ON)\noption(BUILD_CONVERTSTACKED \"Build ConvertStacked plugin\" ON)\n\nif(CMAKE_SIZEOF_VOID_P EQUAL 4)\n  if(NOT MSVC)\n    add_definitions(\"-DAVSC_WIN32_GCC32\")\n  endif()\nendif()\n\nif (WIN32)\n  if(BUILD_DIRECTSHOWSOURCE)\n    add_subdirectory(\"DirectShowSource\")\n  endif()\n\n# obviously depends on VirtualDub being available natively,\n# which is only true for X86 and AMD64\nstring(TOLOWER \"${CMAKE_SYSTEM_PROCESSOR}\" ARCHID)\nif( (\"${ARCHID}\" STREQUAL \"x86\") OR\n    (\"${ARCHID}\" STREQUAL \"x64\") OR\n    (\"${ARCHID}\" STREQUAL \"i686\") OR\n    (\"${ARCHID}\" STREQUAL \"amd64\") OR\n    (\"${ARCHID}\" STREQUAL \"x86_64\") )\n  if (BUILD_VDUBFILTER)\n    add_subdirectory(\"VDubFilter\")\n  endif()\nendif()\n\n  #if (BUILD_VFAPIFILTER)\n    #add_subdirectory(\"VFAPIFilter\")\n  #endif()\nendif()\n\nif (BUILD_IMAGESEQ)\nadd_subdirectory(\"ImageSeq\")\nendif()\n\nif (BUILD_TIMESTRETCH)\nadd_subdirectory(\"TimeStretch\")\nendif()\n\nif (BUILD_SHIBATCH)\nadd_subdirectory(\"Shibatch\")\nendif()\n\nif (BUILD_CONVERTSTACKED)\nadd_subdirectory(\"ConvertStacked\")\nendif()\n"
  },
  {
    "path": "plugins/ConvertStacked/CMakeLists.txt",
    "content": "CMAKE_MINIMUM_REQUIRED( VERSION 3.6.2...3.11 )\n\nset(PluginName \"ConvertStacked\")\nset(ProjectName \"Plugin${PluginName}\")\n\nif (NOT WIN32)\n  string(TOLOWER \"${PluginName}\" PluginName)\nendif()\n\n# Create library\nproject(${ProjectName} VERSION ${PROJECT_VERSION} LANGUAGES CXX)\nlist (APPEND SourceFiles\n    \"ConvertStacked.cpp\"\n)\nadd_library(${ProjectName} SHARED ${SourceFiles})\nset_property(GLOBAL APPEND PROPERTY BUILT_TARGETS ${ProjectName})\nset_target_properties(${ProjectName} PROPERTIES \"OUTPUT_NAME\" ${PluginName})\nif (MINGW)\n  set_target_properties(${ProjectName} PROPERTIES PREFIX \"\")\n  set_target_properties(${ProjectName} PROPERTIES IMPORT_PREFIX \"\")\nendif()\n\n# Library dependencies\ntarget_link_libraries(${ProjectName})\n\n# Include directories\ntarget_include_directories(${ProjectName} PRIVATE ${AvsCore_SOURCE_DIR})\n\nif (MSVC_IDE)\n  # Copy output to a common folder for easy deployment\n  add_custom_command(\n    TARGET ${ProjectName}\n    POST_BUILD\n    COMMAND xcopy /Y \\\"$(TargetPath)\\\" \\\"${CMAKE_BINARY_DIR}/Output/plugins\\\"\n  )\nendif()\n\nINSTALL(TARGETS \"${ProjectName}\"\n        DESTINATION \"${CORE_PLUGIN_INSTALL_PATH}/avisynth\")\n"
  },
  {
    "path": "plugins/ConvertStacked/ConvertStacked.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// ConvertNativeToStacked, ConvertStackedToNative 2016 by pinterf\n\n#include <avisynth.h>\n#include <avs/alignment.h>\n#include <cstdint>\n#ifdef INTEL_INTRINSICS\n\n// Intrinsics base header + really required extension headers\n#if defined(_MSC_VER)\n#include <intrin.h> // MSVC\n#else \n#include <x86intrin.h> // GCC/MinGW/Clang/LLVM\n#endif\n\n#endif // INTEL_INTRINSICS\n\nclass ConvertToStacked : public GenericVideoFilter\n{\npublic:\n\n    ConvertToStacked(PClip src, IScriptEnvironment* env) : GenericVideoFilter(src)\n    {\n        if (vi.IsColorSpace(VideoInfo::CS_YUV420P16)) vi.pixel_type = VideoInfo::CS_YV12;\n        else if (vi.IsColorSpace(VideoInfo::CS_YUV422P16)) vi.pixel_type = VideoInfo::CS_YV16;\n        else if (vi.IsColorSpace(VideoInfo::CS_YUV444P16)) vi.pixel_type = VideoInfo::CS_YV24;\n        else if (vi.IsColorSpace(VideoInfo::CS_Y16)) vi.pixel_type = VideoInfo::CS_Y8;\n        else env->ThrowError(\"ConvertToStacked: Input clip must be native 16 bit: YUV420P16, YUV422P16, YUV444P16, Y16\");\n\n        vi.height = vi.height << 1; // * 2 stacked\n                                    // back from native 16 bit to stacked 8 bit\n\n        return;\n    }\n\n    PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override\n    {\n        PVideoFrame src = child->GetFrame(n, env);\n        PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n\n        const int planes[] = { PLANAR_Y, PLANAR_U, PLANAR_V };\n        const int plane_count = vi.IsY8() ? 1 : 3; // checking the stacked 8 bit format constants\n        for (int p = 0; p < plane_count; ++p) {\n            const int plane = planes[p];\n            const uint16_t* srcp = reinterpret_cast<const uint16_t*>(src->GetReadPtr(plane));\n            uint8_t* msb = dst->GetWritePtr(plane);\n            const int src_pitch = src->GetPitch(plane) / sizeof(uint16_t);\n            const int dst_pitch = dst->GetPitch(plane);\n            const int height = src->GetHeight(plane); // non-stacked real height\n            const int width = dst->GetRowSize(plane);\n            uint8_t* lsb = msb + dst_pitch*height;\n\n#ifdef INTEL_INTRINSICS\n            bool use_sse2 = (env->GetCPUFlags() & CPUF_SSE2) && IsPtrAligned(msb, 16) && IsPtrAligned(srcp, 16);\n\n            if (use_sse2)\n            {\n                // read 32bytes from src, write 16bytes to msb and lsb.\n                // pitch is aligned at least 32 bytes. Thus, an access violation does not happen.\n                for (int y = 0; y < height; ++y) {\n                    for (int x = 0; x < width; x += 16) {\n                        __m128i data16_1, data16_2;\n                        __m128i masklo = _mm_set1_epi16(0x00FF);\n                        data16_1 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x));       // 16 bytes, 8 words ABCDEFGH\n                        data16_2 = _mm_load_si128(reinterpret_cast<const __m128i*>(srcp + x + 8));   // 16 bytes, 8 words\n                        _mm_stream_si128(reinterpret_cast<__m128i*>(msb + x), _mm_packus_epi16(_mm_srli_epi16(data16_1, 8), _mm_srli_epi16(data16_2, 8))); // ABCDEFGH Hi\n                        _mm_stream_si128(reinterpret_cast<__m128i*>(lsb + x), _mm_packus_epi16(_mm_and_si128(data16_1, masklo), _mm_and_si128(data16_2, masklo))); // ABCDEFGH Lo\n                    }\n                    srcp += src_pitch;\n                    msb += dst_pitch;\n                    lsb += dst_pitch;\n                } // y\n            }\n            else\n#endif // INTEL_INTRINSICS\n            {\n                for (int y = 0; y < height; ++y) {\n                    for (int x = 0; x < width; ++x) {\n                        const uint16_t out = srcp[x];\n                        msb[x] = out >> 8;\n                        lsb[x] = (uint8_t)out;\n                    }\n\n                    srcp += src_pitch;\n                    msb += dst_pitch;\n                    lsb += dst_pitch;\n                }\n            }\n        }\n        return dst;\n    }\n\n    int __stdcall SetCacheHints(int cachehints, int frame_range) override\n    {\n        return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n    }\n\n    static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env)\n    {\n        PClip clip = args[0].AsClip();\n        /*if (clip->GetVideoInfo().IsY8())\n        return clip;*/\n        return new ConvertToStacked(clip, env);\n    }\n};\n\n\nclass ConvertFromStacked : public GenericVideoFilter\n{\npublic:\n\n    ConvertFromStacked(PClip src, int bits, IScriptEnvironment* env) : GenericVideoFilter(src)\n    {\n        if (bits == 10 && vi.IsYV12())\n            vi.pixel_type = VideoInfo::CS_YUV420P10;\n        else if (bits == 10 && vi.IsYV16())\n            vi.pixel_type = VideoInfo::CS_YUV422P10;\n        else if (bits == 10 && vi.IsYV24())\n            vi.pixel_type = VideoInfo::CS_YUV444P10;\n        else if (bits == 10 && vi.IsY8())\n            vi.pixel_type = VideoInfo::CS_Y10;\n        else if (bits == 12 && vi.IsYV12())\n            vi.pixel_type = VideoInfo::CS_YUV420P12;\n        else if (bits == 12 && vi.IsYV16())\n            vi.pixel_type = VideoInfo::CS_YUV422P12;\n        else if (bits == 12 && vi.IsYV24())\n            vi.pixel_type = VideoInfo::CS_YUV444P12;\n        else if (bits == 12 && vi.IsY8())\n            vi.pixel_type = VideoInfo::CS_Y12;\n        else if (bits == 14 && vi.IsYV12())\n            vi.pixel_type = VideoInfo::CS_YUV420P14;\n        else if (bits == 14 && vi.IsYV16())\n            vi.pixel_type = VideoInfo::CS_YUV422P14;\n        else if (bits == 14 && vi.IsYV24())\n            vi.pixel_type = VideoInfo::CS_YUV444P14;\n        else if (bits == 14 && vi.IsY8())\n            vi.pixel_type = VideoInfo::CS_Y14;\n        else if (bits == 16 && vi.IsYV12())\n            vi.pixel_type = VideoInfo::CS_YUV420P16;\n        else if (bits == 16 && vi.IsYV16())\n            vi.pixel_type = VideoInfo::CS_YUV422P16;\n        else if (bits == 16 && vi.IsYV24())\n            vi.pixel_type = VideoInfo::CS_YUV444P16;\n        else if (bits == 16 && vi.IsY8())\n            vi.pixel_type = VideoInfo::CS_Y16;\n        else env->ThrowError(\"ConvertFromStacked: Input stacked clip must be YV12, YV16, YV24 or Y8\");\n\n        vi.height = vi.height >> 1; // div 2 non stacked\n\n        return;\n    }\n\n    PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override\n    {\n        PVideoFrame src = child->GetFrame(n, env);\n        PVideoFrame dst = env->NewVideoFrameP(vi, &src);\n        const int planes[] = { PLANAR_Y, PLANAR_U, PLANAR_V };\n        const int plane_count = vi.IsY() ? 1 : 3;\n        for (int p = 0; p < plane_count; ++p) {\n            const int plane = planes[p];\n            const uint8_t* msb = src->GetReadPtr(plane);\n            uint16_t* dstp = reinterpret_cast<uint16_t*>(dst->GetWritePtr(plane));\n            const int src_pitch = src->GetPitch(plane);\n            const int dst_pitch = dst->GetPitch(plane) / sizeof(uint16_t);\n            const int height = dst->GetHeight(plane); // real non-stacked height\n            const int width = src->GetRowSize(plane);\n            const uint8_t* lsb = msb + src_pitch*height;\n\n#ifdef INTEL_INTRINSICS\n            bool use_sse2 = (env->GetCPUFlags() & CPUF_SSE2) && IsPtrAligned(msb, 16) && IsPtrAligned(dstp, 16);\n\n            if (use_sse2)\n            {\n                // pf my very first intrinsic, hey\n                for (int y = 0; y < height; ++y) {\n                    // Read 16 bytes from msb and lsb, write 32bytes to dst.\n                    // pitch is aligned at least 32bytes. Thus, we don't have to care about buffer over run.\n                    for (int x = 0; x < width; x += 16) {\n                        __m128i data_hi, data_lo;\n                        data_hi = _mm_load_si128(reinterpret_cast<const __m128i*>(msb + x)); // 16 bytes\n                        data_lo = _mm_load_si128(reinterpret_cast<const __m128i*>(lsb + x));\n                        // Interleaves the lower 8 signed or unsigned 8-bit integers in a with the lower 8 signed or unsigned 8-bit integers in b.\n                        _mm_stream_si128(reinterpret_cast<__m128i*>(dstp + x), _mm_unpacklo_epi8(data_lo, data_hi));\n                        // Interleaves the higher 8 signed or unsigned 8-bit integers in a with the lower 8 signed or unsigned 8-bit integers in b.\n                        _mm_stream_si128(reinterpret_cast<__m128i*>(dstp + x + 8), _mm_unpackhi_epi8(data_lo, data_hi));\n                    }\n                    msb += src_pitch;\n                    lsb += src_pitch;\n                    dstp += dst_pitch;\n                }\n            }\n            else\n#endif // INTEL_INTRINSICS\n           {\n                for (int y = 0; y < height; ++y) {\n                    for (int x = 0; x < width; ++x) {\n                        dstp[x] = msb[x] << 8 | lsb[x];\n                    }\n                    msb += src_pitch;\n                    lsb += src_pitch;\n                    dstp += dst_pitch;\n                }\n            }\n        }\n        return dst;\n    }\n\n    int __stdcall SetCacheHints(int cachehints, int frame_range) override\n    {\n        return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n    }\n\n\n    static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env)\n    {\n        PClip clip = args[0].AsClip();\n        int bits = args[1].AsInt(16);\n\n        return new ConvertFromStacked(clip, bits, env);\n    }\n};\n\n\nclass ConvertFromDoubleWidth : public GenericVideoFilter\n{\npublic:\n\n    ConvertFromDoubleWidth(PClip src, int bits, IScriptEnvironment* env) : GenericVideoFilter(src)\n    {\n        if (!vi.IsRGB() && vi.RowSize(PLANAR_U) % 2)\n            env->ThrowError(\"ConvertFromDoubleWidth: Input clip's chroma width must be even.\");\n        if ((vi.IsRGB24() || vi.IsRGB32()) && bits != 16)\n          env->ThrowError(\"ConvertFromDoubleWidth: only bits=16 allowed for RGB24 or RGB32 input\");\n\n        if (bits == 10 && vi.IsYV12())\n            vi.pixel_type = VideoInfo::CS_YUV420P10;\n        else if (bits == 10 && vi.IsYV16())\n            vi.pixel_type = VideoInfo::CS_YUV422P10;\n        else if (bits == 10 && vi.IsYV24())\n            vi.pixel_type = VideoInfo::CS_YUV444P10;\n        else if (bits == 10 && vi.IsY8())\n            vi.pixel_type = VideoInfo::CS_Y10;\n        else if (bits == 12 && vi.IsYV12())\n            vi.pixel_type = VideoInfo::CS_YUV420P12;\n        else if (bits == 12 && vi.IsYV16())\n            vi.pixel_type = VideoInfo::CS_YUV422P12;\n        else if (bits == 12 && vi.IsYV24())\n            vi.pixel_type = VideoInfo::CS_YUV444P12;\n        else if (bits == 12 && vi.IsY8())\n            vi.pixel_type = VideoInfo::CS_Y12;\n        else if (bits == 14 && vi.IsYV12())\n            vi.pixel_type = VideoInfo::CS_YUV420P14;\n        else if (bits == 14 && vi.IsYV16())\n            vi.pixel_type = VideoInfo::CS_YUV422P14;\n        else if (bits == 14 && vi.IsYV24())\n            vi.pixel_type = VideoInfo::CS_YUV444P14;\n        else if (bits == 14 && vi.IsY8())\n            vi.pixel_type = VideoInfo::CS_Y14;\n        else if (bits == 16 && vi.IsYV12())\n            vi.pixel_type = VideoInfo::CS_YUV420P16;\n        else if (bits == 16 && vi.IsYV16())\n            vi.pixel_type = VideoInfo::CS_YUV422P16;\n        else if (bits == 16 && vi.IsYV24())\n            vi.pixel_type = VideoInfo::CS_YUV444P16;\n        else if (bits == 16 && vi.IsY8())\n            vi.pixel_type = VideoInfo::CS_Y16;\n        else if (bits == 16 && vi.IsRGB24())\n          vi.pixel_type = VideoInfo::CS_BGR48;\n        else if (bits == 16 && vi.IsRGB32())\n          vi.pixel_type = VideoInfo::CS_BGR64;\n        else env->ThrowError(\"ConvertFromDoubleWidth: Input double width clip must be YV12, YV16, YV24, Y8, RGB24 or RGB32\");\n\n        vi.width /= 2;\n    }\n\n    PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override\n    {\n        PVideoFrame frame = child->GetFrame(n, env);\n        env->MakeWritable(&frame);\n        frame->AmendPixelType(vi.pixel_type);\n        return frame;\n    }\n\n    int __stdcall SetCacheHints(int cachehints, int frame_range) override\n    {\n        return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n    }\n\n\n    static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env)\n    {\n        PClip clip = args[0].AsClip();\n        int bits = args[1].AsInt(16);\n\n        return new ConvertFromDoubleWidth(clip, bits, env);\n    }\n};\n\n\nclass ConvertToDoubleWidth : public GenericVideoFilter\n{\npublic:\n\n    ConvertToDoubleWidth(PClip src, IScriptEnvironment* env) : GenericVideoFilter(src)\n    {\n        if (vi.IsColorSpace(VideoInfo::CS_YUV420P16)) vi.pixel_type = VideoInfo::CS_YV12;\n        else if (vi.IsColorSpace(VideoInfo::CS_YUV422P16)) vi.pixel_type = VideoInfo::CS_YV16;\n        else if (vi.IsColorSpace(VideoInfo::CS_YUV444P16)) vi.pixel_type = VideoInfo::CS_YV24;\n        else if (vi.IsColorSpace(VideoInfo::CS_Y16)) vi.pixel_type = VideoInfo::CS_Y8;\n        else if (vi.IsColorSpace(VideoInfo::CS_BGR48)) vi.pixel_type = VideoInfo::CS_BGR24;\n        else if (vi.IsColorSpace(VideoInfo::CS_BGR64)) vi.pixel_type = VideoInfo::CS_BGR32;\n        else env->ThrowError(\"ConvertToDoubleWidth: Input clip must be 16bit YUV format, RGB48 or RGB64\");\n\n        vi.width *= 2;\n    }\n\n    PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) override\n    {\n        PVideoFrame frame = child->GetFrame(n, env);\n        env->MakeWritable(&frame);\n        frame->AmendPixelType(vi.pixel_type);\n        return frame;\n    }\n\n    int __stdcall SetCacheHints(int cachehints, int frame_range) override\n    {\n        return cachehints == CACHE_GET_MTMODE ? MT_NICE_FILTER : 0;\n    }\n\n    static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env)\n    {\n        PClip clip = args[0].AsClip();\n        return new ConvertToDoubleWidth(clip, env);\n    }\n};\n\n\nconst AVS_Linkage* AVS_linkage = 0;\nextern \"C\" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors) {\n    AVS_linkage = vectors;\n\n    env->AddFunction(\"ConvertFromStacked\", \"c[bits]i\", ConvertFromStacked::Create, 0);\n    env->AddFunction(\"ConvertToStacked\", \"c\", ConvertToStacked::Create, 0);\n    env->AddFunction(\"ConvertFromDoubleWidth\", \"c[bits]i\", ConvertFromDoubleWidth::Create, 0);\n    env->AddFunction(\"ConvertToDoubleWidth\", \"c\", ConvertToDoubleWidth::Create, 0);\n\n    return \"`ConvertStacked' Stacked format conversion for 16-bit formats.\";\n}\n"
  },
  {
    "path": "plugins/DirectShowSource/CMakeLists.txt",
    "content": "CMAKE_MINIMUM_REQUIRED( VERSION 3.6.2...3.11 )\n\nset(PluginName \"DirectShowSource\")\nset(ProjectName \"Plugin${PluginName}\")\n\n# Sensible defaults that should just work if WINSDK is installed and baseclasses built\nset(DEFAULT_BASECLASSES_PATH \"C:/Program Files/Microsoft SDKs/Windows/v7.1/Samples/multimedia/directshow/baseclasses\")\nif(CMAKE_SIZEOF_VOID_P EQUAL 4) # 32-bit\n  set(DEFAULT_BASECLASSES_LIB \"${DEFAULT_BASECLASSES_PATH}/Release_MBCS/strmbase.lib\")\nelse() # 64-bit\n  set(DEFAULT_BASECLASSES_LIB \"${DEFAULT_BASECLASSES_PATH}/x64/Release_MBCS/strmbase.lib\")\nendif()\n\n# We need these variables set by the user to compile successfully\nset(DSHOWSRC_BASECLASSES_PATH \"${DEFAULT_BASECLASSES_PATH}\" CACHE STRING   \"Folder path to the DirectShow example baseclasses.\")\nset(DSHOWSRC_BASECLASSES_LIB  \"${DEFAULT_BASECLASSES_LIB}\"  CACHE FILEPATH \"File path to the DirectShow example baseclasses precompiled static library ('strmbase.lib').\")\n\n# Create library\nproject(${ProjectName} VERSION ${PROJECT_VERSION} LANGUAGES CXX)\nlist (APPEND SourceFiles\n    \"directshow_source.cpp\"\n    \"directshow_source.h\"\n)\nadd_library(${ProjectName} SHARED ${SourceFiles})\nset_property(GLOBAL APPEND PROPERTY BUILT_TARGETS ${ProjectName})\nset_target_properties(${ProjectName} PROPERTIES \"OUTPUT_NAME\" ${PluginName})\nif (MINGW)\n  set_target_properties(${ProjectName} PROPERTIES PREFIX \"\")\n  set_target_properties(${ProjectName} PROPERTIES IMPORT_PREFIX \"\")\nendif()\n\n# Library dependencies\ntarget_link_libraries(${ProjectName} \"Winmm.lib\" \"Quartz.lib\" \"Ole32.lib\" \"User32.lib\" \"Oleaut32.lib\" \"Advapi32.lib\" ${DSHOWSRC_BASECLASSES_LIB})\n\n# Include directories\ntarget_include_directories(${ProjectName} PRIVATE ${AvsCore_SOURCE_DIR} ${DSHOWSRC_BASECLASSES_PATH})\n\n# Mark this target for skipping /permissive- \n# Old v7 SDK code won't compile otherwise, DirectShow Base Classes use non-conformant C++.\n# High-level CMakeLists.txt checks this property and won't inject the flag.\nset_target_properties(${ProjectName} PROPERTIES SKIP_PERMISSIVE_FLAG ON)\n\nif (MSVC_IDE)\n  # Copy output to a common folder for easy deployment\n  add_custom_command(\n    TARGET ${ProjectName}\n    POST_BUILD\n    COMMAND xcopy /Y \\\"$(TargetPath)\\\" \\\"${CMAKE_BINARY_DIR}/Output/plugins\\\"\n  )\nendif()\n\nINSTALL(TARGETS \"${ProjectName}\"\n        DESTINATION \"${CORE_PLUGIN_INSTALL_PATH}/avisynth\")\n"
  },
  {
    "path": "plugins/DirectShowSource/directshow_source.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include \"directshow_source.h\"\n#include <avs/minmax.h>\n#include <memory>\n\n#define DSS_VERSION \"2.6.1\"\n\n/************************************\n *          Logging Utility         *\n ************************************/\n\n/* WARNING - For some stupid reason the compile chokes if I put ()'s around f in the macros\n   so that f & log->mask cannot be subverted by the caller. Therefore the brackets have to\n   go in the calls to the macros. DAMN!!!!! */\n\n// Based on M$ _RPT<n> macros\n//\n// We print a timestamp, the objects address, the message\n//\n#define dssRPT0(f, s)                 _RPT0(0, \"DSS \" s);                \\\n      if (log && (f & log->mask)) fprintf(log->file, \"%s %03x 0x%p 0x%08X \" s, Tick(), f, this, GetCurrentThreadId())\n#define dssRPT1(f, s, a1)             _RPT1(0, \"DSS \" s, a1);            \\\n      if (log && (f & log->mask)) fprintf(log->file, \"%s %03x 0x%p 0x%08X \" s, Tick(), f, this, GetCurrentThreadId(), a1)\n#define dssRPT2(f, s, a1, a2)         _RPT2(0, \"DSS \" s, a1, a2);        \\\n      if (log && (f & log->mask)) fprintf(log->file, \"%s %03x 0x%p 0x%08X \" s, Tick(), f, this, GetCurrentThreadId(), a1, a2)\n#define dssRPT3(f, s, a1, a2, a3)     _RPT3(0, \"DSS \" s, a1, a2, a3);    \\\n      if (log && (f & log->mask)) fprintf(log->file, \"%s %03x 0x%p 0x%08X \" s, Tick(), f, this, GetCurrentThreadId(), a1, a2, a3)\n#define dssRPT4(f, s, a1, a2, a3, a4) _RPT4(0, \"DSS \" s, a1, a2, a3, a4);\\\n      if (log && (f & log->mask)) fprintf(log->file, \"%s %03x 0x%p 0x%08X \" s, Tick(), f, this, GetCurrentThreadId(), a1, a2, a3, a4)\n\n// Reporting masks\nenum {\n  dssNEG   = 1 << 0, //   1    Format Negotiation\n  dssSAMP  = 1 << 1, //   2    Received samples\n  dssCALL  = 1 << 2, //   4    GetFrame/GetAudio calls\n  dssCMD   = 1 << 3, //   8    Directshow callbacks\n  dssPROC  = 1 << 4, //  16    Requests to Directshow\n  dssERROR = 1 << 5, //  32    Errors\n  dssREF   = 1 << 6, //  64    COM object use count\n  dssNEW   = 1 << 7, // 128    New objects\n  dssINFO  = 1 << 8, // 256    Extra info\n  dssWAIT  = 1 << 9  // 512    Wait events\n};\n\n// Millisecond timestamp\nchar* Tick() {\n  static unsigned long firstTick;\n  static bool init = true;\n  static char buf[16];\n\n  unsigned long tick = timeGetTime();\n\n  if (init) {\n      init = false;\n      firstTick = tick;\n  }\n\n  tick -= firstTick;\n\n  unsigned msec = tick % 1000;\n  tick /= 1000;\n  unsigned sec = tick % 60;\n  tick /= 60;\n  unsigned min = tick % 60;\n  tick /= 60;\n  tick %= 99;\n\n  _snprintf(buf, 15, \"%02u:%02u:%02u.%03u\", tick, min, sec, msec);\n  buf[15] = 0;\n\n  return buf;\n}\n\nLOG::LOG(const char* fn, int _mask, IScriptEnvironment* env) : mask(_mask), count(0) {\n  file = fopen(fn, \"a\");\n  if (!file)\n    env->ThrowError(\"DirectShowSource: Not able to open log file, '%s' for appending.\", fn);\n\n  fprintf(file, \"%s fff 0x00000000 DirectShowSource \" DSS_VERSION \" build:\" __DATE__ \" [\" __TIME__ \"]\\n\", Tick());\n}\n\nLOG::~LOG() {\n  fclose(file);\n}\n\nvoid LOG::DelRef(const char* s) {\n  fprintf(file, \"%s fff 0x00000000 Close %s log %d.\\n\", Tick(), s, count);\n\n  if (!(--count)) {\n    delete this;\n  }\n};\n\n// For some reason KSDATAFORMAT_SUBTYPE_IEEE_FLOAT and KSDATAFORMAT_SUBTYPE_PCM doesn't work - we construct the GUID manually!\nconst GUID SUBTYPE_IEEE_AVSPCM     = {0x00000001, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};\nconst GUID SUBTYPE_IEEE_AVSFLOAT   = {0x00000003, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};\n\n// Cope with missing code in DirectShow \"AVI/WAV File Source\"\nconst GUID MEDIASUBTYPE_extensible = {0x0000FFFE, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};\n\n#define FourCC(ch4) ( (((DWORD)(ch4) &       0xFF) << 24) | \\\n                      (((DWORD)(ch4) &     0xFF00) <<  8) | \\\n                      (((DWORD)(ch4) &   0xFF0000) >>  8) | \\\n                      (((DWORD)(ch4) & 0xFF000000) >> 24) )\n\nconst GUID MEDIASUBTYPE_I420 = {FourCC('I420'), 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};\n// Causes redefinition error\n// Already defined by platform headers: const GUID MEDIASUBTYPE_NV12 = {FourCC('NV12'), 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};\nconst GUID MEDIASUBTYPE_YV16 = {FourCC('YV16'), 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};\nconst GUID MEDIASUBTYPE_YV24 = {FourCC('YV24'), 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};\nconst GUID MEDIASUBTYPE_BRA64 = { FourCC('BRA\\100'), 0x0000, 0x0010,{ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } }; // BRA@ ie. BRA[64]\nconst GUID MEDIASUBTYPE_BGR48 = { FourCC('BGR\\060'), 0x0000, 0x0010,{ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } }; // BGR0 ie. BGR[48]\n\n\n// Format a GUID for printing\nchar* PrintGUID(const GUID *g) {\n\n  static char buf[41];\n\n  if (g) {\n    _snprintf(buf, 40, \"{%08x-%04hx-%04hx-%02x%02x-%02x%02x%02x%02x%02x%02x}\\0\",\n              g->Data1,    g->Data2,    g->Data3,    g->Data4[0], g->Data4[1],\n              g->Data4[2], g->Data4[3], g->Data4[4], g->Data4[5], g->Data4[6], g->Data4[7]);\n    buf[40] = 0;\n  }\n  else {\n    lstrcpy(buf, \"<null>\");\n  }\n  return buf;\n}\n\n// Format a state for printing\nchar* PrintState(FILTER_STATE state) {\n  switch (state) {\n    case State_Stopped: return \"State_Stopped\";\n    case State_Paused:  return \"State_Paused\";\n    case State_Running: return \"State_Running\";\n    default: break;\n  }\n  return \"State Unknown\";\n}\n\n// Format a FourCC for printing\nstatic inline char BePrintable(int ch) {\n  ch &= 0xff;\n  return (char)(isprint(ch) ? ch : '.');\n}\n\nchar* PrintFourCC(const int fccType) {\n  static char fcc[5];\n\n  fcc[0] = BePrintable(fccType      );\n  fcc[1] = BePrintable(fccType >>  8);\n  fcc[2] = BePrintable(fccType >> 16);\n  fcc[3] = BePrintable(fccType >> 24);\n  fcc[4] = 0;\n\n  return fcc;\n}\n\nchar* PrintAudioType(const int type) {\n  switch (type) {\n    case SAMPLE_INT8:  return \"Int8\";\n    case SAMPLE_INT16: return \"Int16\";\n    case SAMPLE_INT24: return \"Int24\";\n    case SAMPLE_INT32: return \"Int32\";\n    case SAMPLE_FLOAT: return \"SFloat\";\n    default: break;\n  }\n\n  static char buf[21];\n  _snprintf(buf, 20, \"unknown 0x%x\", type);\n  buf[20] = 0;\n  return buf;\n}\n\nchar* PrintPixelType(int pixel_type) {\n  switch (pixel_type) {\n    case VideoInfo::CS_BGR24:    return \"RGB24\";\n    case VideoInfo::CS_BGR32:    return \"RGB32\";\n    case VideoInfo::CS_BGR48:    return \"RGB48\";\n    case VideoInfo::CS_BGR64:    return \"RGB64\";\n    case VideoInfo::CS_YUY2:     return \"YUY2\";\n//  case VideoInfo::CS_RAW32:    return \"Raw32\";\n    case VideoInfo::CS_YV24:     return \"YV24\";\n    case VideoInfo::CS_YV16:     return \"YV16\";\n    case VideoInfo::CS_YV12:     return \"YV12\";\n    case VideoInfo::CS_I420:     return \"I420\";\n//  case VideoInfo::CS_YUV9:     return \"YUV9\";\n    case VideoInfo::CS_YV411:    return \"YV411\";\n    case VideoInfo::CS_Y8:       return \"Y8\";\n    default: break;\n  }\n\n  static char buf[12];\n  _snprintf(buf, 11, \"0x%08x\", pixel_type);\n  buf[11] = 0;\n  return buf;\n}\n\n/************************************\n *             GetSample            *\n ************************************/\n\n\ninline void InitMediaType(AM_MEDIA_TYPE* &media_type, const GUID &major, const GUID &sub) {\n  media_type = new AM_MEDIA_TYPE;\n  memset(media_type, 0, sizeof(AM_MEDIA_TYPE));\n  media_type->majortype  = major;\n  media_type->subtype    = sub;\n  media_type->formattype = GUID_NULL;\n}\n\n\nGetSample::GetSample(bool _load_audio, bool _load_video, unsigned _media, LOG* _log)\n  : load_audio(_load_audio), load_video(_load_video), media(_media),\n    streamName(_load_audio ? \"audio\" : \"video\"), log(_log), lockvi(false), pvf(0) {\n\n    if(log) log->AddRef();\n\n    dssRPT1(dssNEW, \"New GetSample (%s).\\n\", streamName);\n\n    am_media_type = 0;\n    refcnt = 1;\n    Allocator = 0;\n    source_pin = 0;\n    filter_graph = 0;\n    pclock = 0;\n    m_pPos =0;\n    state = State_Stopped;\n    avg_time_per_frame = 0;\n    av_sample_bytes = 0;\n    av_buffer = 0;\n    seeking = flushing = end_of_stream = false;\n    memset(&vi, 0, sizeof(vi));\n    m_bInvertFrames = false;\n    sample_end_time = sample_start_time = segment_start_time = segment_stop_time = 0;\n    evtDoneWithSample = ::CreateEvent(NULL, FALSE, FALSE, NULL);\n    evtNewSampleReady = ::CreateEvent(NULL, FALSE, FALSE, NULL);\n\n    if (load_audio) {\n      unsigned i=0;\n      InitMediaType(my_media_types[i++], MEDIATYPE_Audio, MEDIASUBTYPE_IEEE_FLOAT);\n      InitMediaType(my_media_types[i++], MEDIATYPE_Audio, MEDIASUBTYPE_PCM);\n      no_my_media_types = i;\n    }\n    else {\n      // Make sure my_media_types[16] is long enough!\n      unsigned i=0;\n//    In the order we want codecs to bid\n      if (media & mediaYV24)   InitMediaType(my_media_types[i++], MEDIATYPE_Video, MEDIASUBTYPE_YV24);\n      if (media & mediaYV16)   InitMediaType(my_media_types[i++], MEDIATYPE_Video, MEDIASUBTYPE_YV16);\n      if (media & mediaYV12)   InitMediaType(my_media_types[i++], MEDIATYPE_Video, MEDIASUBTYPE_YV12);\n      if (media & mediaI420)   InitMediaType(my_media_types[i++], MEDIATYPE_Video, MEDIASUBTYPE_I420);\n      if (media & mediaNV12)   InitMediaType(my_media_types[i++], MEDIATYPE_Video, MEDIASUBTYPE_NV12); //Needs unpacking\n      if (media & mediaYUY2)   InitMediaType(my_media_types[i++], MEDIATYPE_Video, MEDIASUBTYPE_YUY2);\n      if (media & mediaAYUV)   InitMediaType(my_media_types[i++], MEDIATYPE_Video, MEDIASUBTYPE_AYUV); //Needs unpacking\n      if (media & mediaY41P)   InitMediaType(my_media_types[i++], MEDIATYPE_Video, MEDIASUBTYPE_Y41P); //Needs unpacking\n      if (media & mediaY411)   InitMediaType(my_media_types[i++], MEDIATYPE_Video, MEDIASUBTYPE_Y411); //Needs unpacking\n//    if (media & mediaYUV9)   InitMediaType(my_media_types[i++], MEDIATYPE_Video, MEDIASUBTYPE_YUV9);\n      if (media & mediaARGB)   InitMediaType(my_media_types[i++], MEDIATYPE_Video, MEDIASUBTYPE_ARGB32);\n      if (media & mediaRGB32)  InitMediaType(my_media_types[i++], MEDIATYPE_Video, MEDIASUBTYPE_RGB32);\n      if (media & mediaRGB24)  InitMediaType(my_media_types[i++], MEDIATYPE_Video, MEDIASUBTYPE_RGB24);\n      if (media & mediaRGB64)  InitMediaType(my_media_types[i++], MEDIATYPE_Video, MEDIASUBTYPE_BRA64);\n      if (media & mediaRGB48)  InitMediaType(my_media_types[i++], MEDIATYPE_Video, MEDIASUBTYPE_BGR48);\n      no_my_media_types = i;\n      if (media == mediaNONE) media = mediaAUTO;\n    }\n  }\n\n  GetSample::~GetSample() {\n    dssRPT1(dssNEW, \"~GetSample(%s).\\n\", streamName);\n\n    if (am_media_type)\n      DeleteMediaType(am_media_type);\n    am_media_type = 0;\n\n    SetEvent(evtDoneWithSample);\n    SetEvent(evtNewSampleReady);\n\n    CloseHandle(evtDoneWithSample);\n    CloseHandle(evtNewSampleReady);\n\n    for (unsigned i=0; i<no_my_media_types; i++)\n      delete my_media_types[i];\n\n    if (Allocator) {\n      dssRPT1(dssNEW, \"Releasing Allocator 0x%08p.\\n\", Allocator);\n      Allocator->Release();\n      Allocator = 0;\n    }\n\n    if (log) log->DelRef(streamName);\n  }\n\n\n  const AM_MEDIA_TYPE *GetSample::GetMediaType(unsigned pos) {\n    return my_media_types[(pos < no_my_media_types) ? pos : 0];\n  }\n\n\n  bool GetSample::WaitForStart(DWORD &timeout) {\n\n    // Give the graph an opportunity to start before we return empty data\n\n    if (state == State_Stopped) {\n      dssRPT1(dssERROR, \"WaitForStart() state == State_Stopped (%s)\\n\", streamName); // Opps should never happen!\n      return false;\n    }\n\n    if (graphTimeout)\n      graphTimeout = (WaitForSingleObject(evtNewSampleReady, timeout) == WAIT_TIMEOUT);\n    if (graphTimeout) {\n      dssRPT0(dssERROR, \"** TIMEOUT ** waiting for Graph to start!\\n\");\n      timeout = 55; // 1 windows tick\n    }\n    return graphTimeout;\n  }\n\n\n  PVideoFrame GetSample::GetCurrentFrame(IScriptEnvironment* env, int n, bool _TrapTimeouts, DWORD &timeout) {\n\n    if (WaitForStart(timeout))\n      if (_TrapTimeouts) {\n        dssRPT1(dssERROR, \"GetCurrentFrame() Timeout waiting for video frame=%d!\\n\", n);\n        env->ThrowError(\"DirectShowSource : Timeout waiting for video.\");\n    }\n\n    if (av_buffer) {\n\n      pvf = env->NewVideoFrame(vi);\n\n      // Put any knowledge of video packing and alignment here and\n      // keep it independant of any AviSynth packing and alignment.\n\n      PBYTE buf = av_buffer;\n\n      if (!vi.IsPlanar() || vi.IsY8()) { // All DIB formats have rows 32bit aligned\n\n        const int rowsize = pvf->GetRowSize();\n        int height  = pvf->GetHeight();\n        int stride;\n\n        // Check for rows not being 32 bit aligned as expected\n        if (((rowsize*height + 3)&~3) == ((av_sample_bytes+3)&~3)) {\n          // Setup for a naughty packed layout\n          stride = rowsize;\n        } else  {\n          // Setup for the expected padded layout\n          stride  = (rowsize+3)&~3;\n        }\n\n        // Check input size is adequate\n        if (av_sample_bytes < height*stride) {\n          // Truncate the height to avoid buffer overrun.\n          dssRPT2(dssERROR, \"GetCurrentFrame() Input buffer to small, %d expecting %d!\\n\", av_sample_bytes, height*stride);\n          height = av_sample_bytes/stride;\n        }\n\n        if (m_bInvertFrames) {\n          buf += stride * (height - 1);\n          stride = -stride;\n        }\n\n        env->BitBlt(pvf->GetWritePtr(), pvf->GetPitch(), buf, stride, rowsize, height);\n      }\n      else {\n        const int rowsize   = pvf->GetRowSize(PLANAR_Y);\n        int height          = pvf->GetHeight(PLANAR_Y);\n\n        const int UVrowsize = pvf->GetRowSize(PLANAR_V);\n        int UVheight        = pvf->GetHeight(PLANAR_V);\n\n        // Unlike DIB based formats planar data is supposed to be fully packed\n        // but some implemetation incorrectly pad both the Y and UV rows out\n        // to 32 bit while other implementations pad the Y rows out to 32 bit\n        // and pad the UV rows as subsampled Y rows.\n\n        // Start with what is expected, i.e. packed\n        int stride   = rowsize;\n        int UVstride = UVrowsize;\n\n        if (media & mediaPAD) {\n          // Use mod4 Y row with subsampled UV rows\n          stride   = (rowsize+3) & ~3;\n          UVstride = stride >> vi.GetPlaneWidthSubsampling(PLANAR_U);\n        }\n\n        BYTE* dstY = pvf->GetWritePtr(PLANAR_Y);\n        BYTE* dstU = pvf->GetWritePtr(PLANAR_U);\n        BYTE* dstV = pvf->GetWritePtr(PLANAR_V);\n        BYTE* const dstT = dstV;\n        BYTE* srcP = buf;\n\n        const int pitchY = pvf->GetPitch(PLANAR_Y);\n        const int pitchUV = pvf->GetPitch(PLANAR_U);\n        int src_pitch;\n\n        switch (am_media_type->subtype.Data1)\n        {\n          // Standard planar formats\n          case FourCC('I420'):\n            // Swap U and V pointers\n            dstV = dstU;\n            dstU = dstT;\n          case FourCC('YV12'):\n          case FourCC('YV16'):\n          case FourCC('YV24'):\n            dssRPT3(dssINFO, \"GetCurrentFrame() Input buffer size %d, stride %d, UVstride %d\\n\",\n                             av_sample_bytes, stride, UVstride);\n\n            // Check input size is adequate\n            if (av_sample_bytes < height*stride) {\n              // Truncate the height to avoid buffer overrun.\n              dssRPT2(dssERROR, \"GetCurrentFrame() Input buffer to small, %d expecting %d!\\n\", av_sample_bytes, height*stride);\n              height = av_sample_bytes/stride;\n            }\n            env->BitBlt(dstY, pitchY, srcP, stride, rowsize, height);\n\n            // Check input size is adequate\n            if (av_sample_bytes < height*stride+2*UVheight*UVstride) {\n              // Truncate the height to avoid buffer overrun.\n              dssRPT2(dssERROR, \"GetCurrentFrame() Input buffer to small, %d expecting %d!\\n\",\n                                av_sample_bytes, height*stride+2*UVheight*UVstride);\n              UVheight = (av_sample_bytes-height*stride)/(2*UVstride);\n            }\n            // V plane first, after aligned end of Y plane\n            srcP += stride * height;\n            env->BitBlt(dstV, pitchUV, srcP, UVstride, UVrowsize, UVheight);\n\n            // And U plane last, after aligned end of V plane\n            srcP += UVstride * UVheight;\n            env->BitBlt(dstU, pitchUV, srcP, UVstride, UVrowsize, UVheight);\n            break;\n\n          // 4:2:0 which needs packed chroma -> planar conversion.\n          case FourCC('NV12'):\n\n            UVstride *= 2;\n\n            dssRPT3(dssINFO, \"GetCurrentFrame() Input buffer size %d, stride %d, UVstride %d\\n\",\n                             av_sample_bytes, stride, UVstride);\n\n            // Check input size is adequate\n            if (av_sample_bytes < height*stride) {\n              // Truncate the height to avoid buffer overrun.\n              dssRPT2(dssERROR, \"GetCurrentFrame() Input buffer to small, %d expecting %d!\\n\",\n                                av_sample_bytes, height*stride);\n              height = av_sample_bytes/stride;\n            }\n            env->BitBlt(dstY, pitchY, srcP, stride, rowsize, height);\n\n            // Check input size is adequate\n            if (av_sample_bytes < height*stride+UVheight*UVstride) {\n              // Truncate the height to avoid buffer overrun.\n              dssRPT2(dssERROR, \"GetCurrentFrame() Input buffer to small, %d expecting %d!\\n\",\n                                av_sample_bytes, height*stride+UVheight*UVstride);\n              UVheight = (av_sample_bytes-height*stride)/UVstride;\n            }\n            // Packed UV plane after aligned end of Y plane\n            srcP += stride * height;\n\n            {for (int y=0; y<UVheight; y++) {\n              for(int x=0; x<UVrowsize; x++) {\n                dstU[x] = srcP[(x*2)+0];\n                dstV[x] = srcP[(x*2)+1];\n              }\n              dstU += pitchUV;\n              dstV += pitchUV;\n              srcP += UVstride;\n            }}\n            break;\n\n          // 4:4:4 which needs packed -> planar conversion.\n          case FourCC('AYUV'):\n            // V0 U0 Y0 A0\n            src_pitch = vi.width * 4;  // Naturally aligned.\n\n            // Check input size is adequate\n            if (av_sample_bytes < height*src_pitch) {\n              dssRPT2(dssERROR, \"GetCurrentFrame() Input buffer to small, %d expecting %d!\\n\",\n                                av_sample_bytes, height*src_pitch);\n              height = av_sample_bytes/src_pitch;\n            }\n\n            {for (int y=0; y<height; y++) {\n              for(int x=0; x<rowsize; x++) {\n                dstV[x] = srcP[(x*4)+0];\n                dstU[x] = srcP[(x*4)+1];\n                dstY[x] = srcP[(x*4)+2];\n              }\n              dstY += pitchY;\n              dstU += pitchUV;\n              dstV += pitchUV;\n              srcP += src_pitch;\n            }}\n            break;\n\n          // 4:1:1 which needs packed -> planar conversion.\n          case FourCC('Y41P'):\n          case FourCC('Y411'):\n            // U0 Y0 V0 Y1   U4 Y2 V4 Y3   Y4 Y5 Y6 Y7\n            src_pitch = (vi.width / 8) * 12;  // Naturally aligned.\n\n            // Check input size is adequate\n            if (av_sample_bytes < height*src_pitch) {\n              dssRPT2(dssERROR, \"GetCurrentFrame() Input buffer to small, %d expecting %d!\\n\",\n                                av_sample_bytes, height*src_pitch);\n              height = av_sample_bytes/src_pitch;\n            }\n\n            {for (int y=0; y<height; y++) {\n              for(int px=0, dx=0; px<rowsize; px+=12, dx+=2) {\n                dstU[dx+0] = srcP[px+0];\n                dstU[dx+1] = srcP[px+4];\n\n                dstV[dx+0] = srcP[px+2];\n                dstV[dx+1] = srcP[px+6];\n\n                dstY[dx*4+0] = srcP[px+1];\n                dstY[dx*4+1] = srcP[px+3];\n                dstY[dx*4+2] = srcP[px+5];\n                dstY[dx*4+3] = srcP[px+7];\n\n                dstY[dx*4+4] = srcP[px+8];\n                dstY[dx*4+5] = srcP[px+9];\n                dstY[dx*4+6] = srcP[px+10];\n                dstY[dx*4+7] = srcP[px+11];\n              }\n              dstY += pitchY;\n              dstU += pitchUV;\n              dstV += pitchUV;\n              srcP += src_pitch;\n            }}\n            break;\n\n          default:\n            dssRPT2(dssERROR, \"GetCurrentFrame() unknown pixel type '%s' %s\\n\",\n                    PrintFourCC(am_media_type->subtype.Data1), PrintGUID(&am_media_type->subtype));\n            break;\n        }\n      }\n    }\n    else if (pvf) {\n      dssRPT1(dssERROR, \"GetCurrentFrame() Returning last good frame %d!\\n\", n);\n    }\n    else {\n      dssRPT1(dssERROR, \"GetCurrentFrame() Returning ** BLANK ** frame %d!\\n\", n);\n\n      pvf = env->NewVideoFrame(vi);\n\n      // If the graph still hasn't started yet we won't have a current frame\n      // so dummy up a grey frame so at least things won't be fatal.\n\n      memset(pvf->GetWritePtr(), 128, pvf->GetPitch()*pvf->GetHeight() +\n                                      pvf->GetPitch(PLANAR_U)*pvf->GetHeight(PLANAR_U)*2);\n    }\n    return pvf;\n  }\n\n\n  HRESULT GetSample::StartGraph(IGraphBuilder* gb) {\n    dssRPT1(dssPROC, \"StartGraph(%s) enter...\\n\", streamName);\n    try {\n      ResetEvent(evtDoneWithSample);  // Nuke any unused SetEvents\n      ResetEvent(evtNewSampleReady);  // Nuke any unused SetEvents\n      IMediaControl* mc;\n      gb->QueryInterface(&mc);\n      seeking = flushing = end_of_stream = false;\n      pvf = NULL; // Nuke current frame\n      HRESULT hr = mc->Run();\n      dssRPT2(dssPROC, \"StartGraph(%s) mc->Run() = 0x%x\\n\", streamName, hr);\n      // Retry!!\n      if (hr == E_FAIL) {\n        hr = mc->Run();\n        dssRPT2(dssPROC, \"Retry(%s) mc->Run() = 0x%x\\n\", streamName, hr);\n      }\n      if (hr == S_FALSE) {\n        // Damn! graph is stuffing around and has not started (yet?)\n        OAFilterState fs = State_Stopped;\n        hr = mc->GetState(5000, &fs); // Give it 5 seconds to sort itself out\n        dssRPT3(dssPROC, \"StartGraph(%s) mc->GetState(%s) = 0x%x\\n\", streamName, PrintState(FILTER_STATE(fs)), hr);\n        if ((fs == State_Running) && ((hr == S_OK) || (hr == VFW_S_STATE_INTERMEDIATE)))\n          hr = S_OK; // It is good or still may become good\n        else if (SUCCEEDED(hr))\n          hr = E_FAIL;  // It's playing possum and about to lock up\n//      else\n//        it's totally screwed\n      }\n//    else\n//      hr == S_OK or some serious error like the infamous E_FAIL\n      mc->Release();\n      graphTimeout = true;\n      dssRPT2(dssPROC, \"StartGraph(%s) ... exit 0x%x\\n\", streamName, hr);\n      return hr;\n    }\n    catch (...) {\n      dssRPT1((dssERROR|dssPROC), \"StartGraph(%s) Unknown Exception!\\n\", streamName);\n      return E_FAIL;\n    }\n  }\n\n  void GetSample::StopGraph(IGraphBuilder* gb) {\n    dssRPT1(dssPROC, \"StopGraph() indicating done with sample - %s\\n\", PrintState(state));\n    IMediaControl* mc;\n    gb->QueryInterface(&mc);\n    SetEvent(evtDoneWithSample); // Free task if waiting\n    graphTimeout = true;\n    mc->Stop();\n    mc->Release();\n    if (m_pPos)\n      m_pPos->Release();\n    m_pPos = 0;\n  }\n\n  void GetSample::PauseGraph(IGraphBuilder* gb) {\n    dssRPT0(dssPROC, \"PauseGraph()\\n\");\n    IMediaControl* mc;\n    gb->QueryInterface(&mc);\n    mc->Pause();\n    mc->Release();\n  }\n\n  HRESULT GetSample::SeekTo(__int64 pos, IGraphBuilder* gb) {\n    HRESULT hr;\n\n    dssRPT1(dssPROC, \"SeekTo() seeking to new position %I64d\\n\", pos);\n\n    // If trying to seek past the known end of stream just exit.\n    if (end_of_stream && pos >= GetSampleStartTime()) {\n      dssRPT1(dssPROC, \"SeekTo() End_of_stream last samples position %I64d\\n\", GetSampleStartTime());\n      return S_OK;\n    }\n\n    seeking = true;\n\n    IMediaControl* mc = NULL;\n    try {\n      gb->QueryInterface(&mc);\n      SetEvent(evtDoneWithSample); // Free task if waiting\n      graphTimeout = true;\n      mc->Stop();\n      dssRPT0(dssPROC, \"SeekTo() mc->Stop()\\n\");\n      mc->Release();\n      if (m_pPos)\n        m_pPos->Release();\n      m_pPos = 0;\n    }\n    catch (...) {\n      if (mc) mc->Release();\n    }\n\n    IMediaSeeking* ms = NULL;\n    try {\n      gb->QueryInterface(&ms);\n\n//    It looks like GetCapabilities() is a useless liar. So it seems the\n//    best thing is to just try the seeks and test the result code\n//\n//    ms->GetCapabilities(&dwCaps);\n\n      ms->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME); // Setting can give E_NOTIMPL\n\n      LONGLONG pCurrent = -1, pStop;\n      GUID time_f;\n\n      ms->GetTimeFormat(&time_f);                 // so check what it currently is\n      if (time_f != TIME_FORMAT_MEDIA_TIME) {\n        // Probably should implement code for all the time formats  :: FIXME\n        dssRPT0(dssERROR, \"Could not set time format to media time!\\n\");\n      }\n\n      if (SUCCEEDED(hr = ms->SetPositions(&pos, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning)))\n          goto SeekExit;\n      dssRPT1(dssERROR, \"Absolute seek failed! 0x%x\\n\", hr); // and now trying relative seek\n\n      if (FAILED(hr = ms->GetPositions(&pCurrent, &pStop)) || (pCurrent == -1)) {\n        dssRPT1(dssERROR, \"GetPositions failed! 0x%x\\n\", hr);\n        pCurrent = GetSampleStartTime(); // Wing it from last the sample delived\n      }\n\n      pCurrent = pos - pCurrent;\n      if (FAILED(hr = ms->SetPositions(&pCurrent, AM_SEEKING_RelativePositioning, NULL, AM_SEEKING_NoPositioning))) {\n        dssRPT1(dssERROR, \"Relative seek failed! 0x%x\\n\", hr); }\n\nSeekExit:\n      ms->GetPositions(&pCurrent, &pStop);\n      dssRPT2(dssPROC, \"SeekTo() ms->GetPositions(%I64d, %I64d)\\n\", pCurrent, pStop);\n      ms->Release();\n    }\n    catch (...) {\n      dssRPT0((dssERROR|dssPROC), \"SeekTo() Unknown Exception!\\n\");\n      if (ms) ms->Release();\n      return E_FAIL;\n    }\n\n    hr = SUCCEEDED(hr) ? S_OK : S_FALSE;\n\n    HRESULT hr1 = StartGraph(gb);\n    if (FAILED(hr1))\n      hr = hr1;  // pretty serious the Graph is not running\n\n    return hr;\n  }\n\n\n  bool GetSample::NextSample(DWORD &timeout) {\n\n    if (end_of_stream) {\n      dssRPT1(dssPROC, \"NextSample() end of stream (%s)\\n\", streamName);\n      return false;\n    }\n\n    if (state == State_Stopped) {\n      dssRPT1(dssERROR, \"NextSample() state == State_Stopped (%s)\\n\", streamName); // Opps should never happen!\n      return false;\n    }\n\n    // If the graph didn't start, check if it has yet. We absolutly have to keep in lock\n    // step with the evtNewSampleReady and evtDoneWithSample synchronizaton objects. This\n    // is a bit kludgy because when it happens blank frames or silence are returned but\n    // it is better than returning totally corrupt data.\n\n    if (WaitForStart(timeout)) return false;\n\n    dssRPT1(dssPROC, \"NextSample() indicating done with previous sample...(%s)\\n\", streamName);\n\n    SetEvent(evtDoneWithSample);  // We indicate that Receive can run again. We have now finished using the frame.\n\n    dssRPT1(dssPROC, \"...NextSample() waiting for new sample...(%s)\\n\", streamName);\n    graphTimeout = false;\n    if (WaitForSingleObject(evtNewSampleReady, timeout) == WAIT_TIMEOUT) {\n      dssRPT1(dssERROR, \"...NextSample() TIMEOUT waiting for new sample (%s)\\n\", streamName);\n      timeout = 55;\n      graphTimeout = true;\n      return false;\n    }\n\n    dssRPT1(dssPROC, \"...NextSample() done waiting for new sample (%s)\\n\", streamName);\n    return !end_of_stream;\n  }\n\n  // IUnknown\n\n  ULONG __stdcall GetSample::AddRef() {\n    ULONG ref = InterlockedIncrement(&refcnt);\n    dssRPT1(dssREF, \"GetSample::AddRef() -> %d\\n\", ref);\n    return ref;\n  }\n\n  ULONG __stdcall GetSample::Release() {\n    ULONG ref = InterlockedDecrement(&refcnt);\n    dssRPT1(dssREF, \"GetSample::Release() -> %d\\n\", ref);\n    return ref;\n  }\n\n  HRESULT __stdcall GetSample::QueryInterface(REFIID iid, void** ppv) {\n    if      (iid == IID_IUnknown)     *ppv = static_cast<IUnknown*>(static_cast<IBaseFilter*>(this));\n    else if (iid == IID_IPersist)     *ppv = static_cast<IPersist*>(this);\n    else if (iid == IID_IMediaFilter) *ppv = static_cast<IMediaFilter*>(this);\n    else if (iid == IID_IBaseFilter)  *ppv = static_cast<IBaseFilter*>(this);\n    else if (iid == IID_IPin)         *ppv = static_cast<IPin*>(this);\n    else if (iid == IID_IMemInputPin) *ppv = static_cast<IMemInputPin*>(this);\n    else if (iid == IID_IMediaSeeking || iid == IID_IMediaPosition) {\n      if (!source_pin) {\n        *ppv = 0;\n        dssRPT1(dssERROR, \"GetSample::QueryInterface(%s, ppv) ** E_NOINTERFACE **, No Source Pin!\\n\", PrintGUID(&iid));\n        return E_NOINTERFACE;\n      }\n      if (m_pPos == NULL)  {\n        // We have not created the CPosPassThru object yet. Do so now.\n        HRESULT hr = CreatePosPassThru(NULL , FALSE, static_cast<IPin*>(this), &m_pPos);\n\n        if (FAILED(hr))  {\n          *ppv = 0;\n          dssRPT1(dssERROR, \"GetSample::QueryInterface(%s, ppv), Failed CreatePosPassThru!\\n\", PrintGUID(&iid));\n          return hr;\n        }\n      }\n      dssRPT1(dssCMD, \"GetSample::QueryInterface(%s, ppv) -> m_pPos\\n\", PrintGUID(&iid));\n      return m_pPos->QueryInterface(iid, ppv);\n    }\n    else {\n      *ppv = 0;\n      dssRPT1(dssCMD, \"GetSample::QueryInterface(%s, ppv) ** E_NOINTERFACE **\\n\", PrintGUID(&iid));\n      return E_NOINTERFACE;\n    }\n    AddRef();\n    dssRPT1(dssCMD, \"GetSample::QueryInterface(%s, ppv)\\n\", PrintGUID(&iid));\n    return S_OK;\n  }\n\n  // IPersist\n\n  HRESULT __stdcall GetSample::GetClassID(CLSID* pClassID) {\n    dssRPT0(dssCMD, \"GetSample::GetClassID() E_NOTIMPL\\n\");\n    return E_NOTIMPL;\n  }\n\n  // IMediaFilter\n\n  HRESULT __stdcall GetSample::Stop() {\n    dssRPT1(dssCMD, \"GetSample::Stop(), state was %s\\n\", PrintState(state));\n    state = State_Stopped;\n    SetEvent(evtDoneWithSample);\n    graphTimeout = true;\n/*\n    if (Allocator) {\n      HRESULT result = Allocator->Decommit();\n      dssRPT2(dssNEW, \"GetSample::Stop(), %x = 0x%08x->Decommit().\\n\", result, Allocator);\n    }\n*/\n    return S_OK;\n  }\n\n  HRESULT __stdcall GetSample::Pause() {\n    dssRPT1(dssCMD, \"GetSample::Pause(), state was %s\\n\", PrintState(state));\n    state = State_Paused;\n    return S_OK;\n  }\n\n  HRESULT __stdcall GetSample::Run(REFERENCE_TIME tStart) {\n    dssRPT2(dssCMD, \"GetSample::Run(%I64d), state was %s\\n\", tStart, PrintState(state));\n    ResetEvent(evtDoneWithSample);\n    state = State_Running;\n    return S_OK;\n  }\n\n  HRESULT __stdcall GetSample::GetState(DWORD dwMilliSecsTimeout, FILTER_STATE* State) {\n    if (!State) {\n      dssRPT1(dssERROR, \"GetSample::GetState() ** E_POINTER **, state is %s\\n\", PrintState(state));\n      return E_POINTER;\n    }\n    dssRPT1(dssCMD, \"GetSample::GetState(), state is %s\\n\", PrintState(state));\n    *State = state;\n    return S_OK;\n  }\n\n  HRESULT __stdcall GetSample::SetSyncSource(IReferenceClock* pClock) {\n    dssRPT2(dssCMD, \"GetSample::SetSyncSource(0x%08p), was 0x%08p\\n\", pClock, pclock);\n    pclock = pClock;\n    return S_OK;\n  }\n\n  HRESULT __stdcall GetSample::GetSyncSource(IReferenceClock** ppClock) {\n    if (!ppClock) {\n      dssRPT1(dssERROR, \"GetSample::GetSyncSource() ** E_POINTER **, is 0x%08p\\n\", pclock);\n      return E_POINTER;\n    }\n    dssRPT1(dssCMD, \"GetSample::GetSyncSource(), is 0x%08p\\n\", pclock);\n    *ppClock = pclock;\n    if (pclock) pclock->AddRef();\n    return S_OK;\n  }\n\n  // IBaseFilter\n\n  HRESULT __stdcall GetSample::EnumPins(IEnumPins** ppEnum) {\n    if (!ppEnum) {\n      dssRPT0(dssERROR, \"GetSample::EnumPins() ** E_POINTER **\\n\");\n      return E_POINTER;\n    }\n    dssRPT0(dssCMD, \"GetSample::EnumPins()\\n\");\n    *ppEnum = new GetSampleEnumPins(this);\n    return *ppEnum ? S_OK : E_OUTOFMEMORY;\n  }\n\n  HRESULT __stdcall GetSample::FindPin(LPCWSTR Id, IPin** ppPin) { // See QueryID\n    if (!Id) {\n      dssRPT0(dssERROR, \"GetSample::FindPin(Id, ppPin) ** E_POINTER **\\n\");\n      return E_POINTER;\n    }\n\n    if (!ppPin) {\n      dssRPT1(dssERROR, \"GetSample::FindPin(%ls, ppPin) ** E_POINTER **\\n\", Id);\n      return E_POINTER;\n    }\n\n    if (wcscmp(L\"GetSample01\", Id)) {\n      dssRPT1(dssERROR, \"GetSample::FindPin(%ls, ppPin) ** VFW_E_NOT_FOUND **\\n\", Id);\n      *ppPin = NULL;\n      return VFW_E_NOT_FOUND;\n    }\n\n    dssRPT1(dssCMD, \"GetSample::FindPin(%ls, ppPin)\\n\", Id);\n\n    *ppPin = static_cast<IPin*>(this);\n\n    AddRef();\n\n    return S_OK;\n  }\n\n  HRESULT __stdcall GetSample::QueryFilterInfo(FILTER_INFO* pInfo) {\n    if (!pInfo) {\n      dssRPT0(dssERROR, \"GetSample::QueryFilterInfo() ** E_POINTER **\\n\");\n      return E_POINTER;\n    }\n    dssRPT0(dssCMD, \"GetSample::QueryFilterInfo()\\n\");\n    wcsncpy(pInfo->achName, L\"GetSample\", MAX_FILTER_NAME);\n    pInfo->pGraph = filter_graph;\n    if (filter_graph) filter_graph->AddRef();\n    return S_OK;\n  }\n\n  HRESULT __stdcall GetSample::JoinFilterGraph(IFilterGraph* pGraph, LPCWSTR pName) {\n    dssRPT2(dssCMD, \"GetSample::JoinFilterGraph(0x%08p, %ls)\\n\", pGraph, pName);\n    filter_graph = pGraph;\n    return S_OK;\n  }\n\n  HRESULT __stdcall GetSample::QueryVendorInfo(LPWSTR* pVendorInfo) {\n    dssRPT0(dssCMD, \"GetSample::QueryVendorInfo() E_NOTIMPL\\n\");\n    return E_NOTIMPL;\n  }\n\n  // IPin\n\n  HRESULT __stdcall GetSample::Connect(IPin* pReceivePin, const AM_MEDIA_TYPE* pmt) {\n    dssRPT0(dssERROR, \"GetSample::Connect() E_UNEXPECTED\\n\");\n    return E_UNEXPECTED;\n  }\n\n  HRESULT __stdcall GetSample::ReceiveConnection(IPin* pConnector, const AM_MEDIA_TYPE* pmt) {\n\n    if (!pConnector || !pmt) {\n      dssRPT0(dssERROR, \"GetSample::ReceiveConnection() ** E_POINTER **\\n\");\n      return E_POINTER;\n    }\n\n    if (state != State_Stopped) {\n      dssRPT0(dssERROR, \"GetSample::ReceiveConnection() ** VFW_E_NOT_STOPPED **\\n\");\n      return VFW_E_NOT_STOPPED;\n    }\n\n    if (source_pin) {\n      dssRPT0(dssERROR, \"GetSample::ReceiveConnection() ** VFW_E_ALREADY_CONNECTED **\\n\");\n      return VFW_E_ALREADY_CONNECTED;\n    }\n\n    VideoInfo tmp = vi;\n    bool bInvertFrames = false;\n\n    if (GetSample::InternalQueryAccept(pmt, tmp, bInvertFrames) != S_OK) {\n      dssRPT0(dssERROR, \"GetSample::ReceiveConnection() ** VFW_E_TYPE_NOT_ACCEPTED **\\n\");\n      return VFW_E_TYPE_NOT_ACCEPTED;\n    }\n\n    dssRPT1(dssCMD, \"GetSample::ReceiveConnection(0x%08p, pmt)\\n\", pConnector);\n    vi = tmp;\n    m_bInvertFrames = bInvertFrames;\n    source_pin = pConnector;\n    if (am_media_type)\n      DeleteMediaType(am_media_type);\n    am_media_type = CreateMediaType(pmt);\n    return S_OK;\n  }\n\n  HRESULT __stdcall GetSample::Disconnect() {\n    if (state != State_Stopped) {\n      dssRPT0(dssERROR, \"GetSample::Disconnect() ** VFW_E_NOT_STOPPED **\\n\");\n      return VFW_E_NOT_STOPPED;\n    }\n    if (!source_pin) {\n      dssRPT0(dssCMD, \"GetSample::Disconnect() ** S_FALSE **\\n\");\n      return S_FALSE;\n    }\n    source_pin = 0;\n    if (am_media_type)\n      DeleteMediaType(am_media_type);\n    am_media_type = 0;\n\n    if (Allocator) {\n      dssRPT1(dssNEW, \"Releasing Allocator 0x%08p.\\n\", Allocator);\n      Allocator->Release();\n      Allocator = 0;\n    }\n\n    dssRPT0(dssCMD, \"GetSample::Disconnect()\\n\");\n    return S_OK;\n  }\n\n  HRESULT __stdcall GetSample::ConnectedTo(IPin** ppPin) {\n    if (!ppPin) {\n      dssRPT0(dssERROR, \"GetSample::ConnectedTo() ** E_POINTER **\\n\");\n      return E_POINTER;\n    }\n    *ppPin = source_pin;\n    if (!source_pin) {\n      dssRPT0(dssERROR, \"GetSample::ConnectedTo() ** VFW_E_NOT_CONNECTED **\\n\");\n      return VFW_E_NOT_CONNECTED;\n    }\n    source_pin->AddRef();\n    dssRPT1(dssCMD, \"GetSample::ConnectedTo() is 0x%08p\\n\", source_pin);\n    return S_OK;\n  }\n\n  HRESULT __stdcall GetSample::ConnectionMediaType(AM_MEDIA_TYPE* pmt) {\n    if (!pmt) {\n      dssRPT0(dssERROR, \"GetSample::ConnectionMediaType() ** E_POINTER **\\n\");\n      return E_POINTER;\n    }\n    if (!source_pin || !am_media_type) {\n      dssRPT0(dssERROR, \"GetSample::ConnectionMediaType() ** VFW_E_NOT_CONNECTED **\\n\");\n      return VFW_E_NOT_CONNECTED;\n    }\n    FreeMediaType(*pmt);\n    CopyMediaType(pmt, am_media_type);\n    dssRPT0(dssCMD, \"GetSample::ConnectionMediaType()\\n\");\n\n    return S_OK;\n  }\n\n  HRESULT __stdcall GetSample::QueryPinInfo(PIN_INFO* pInfo) {\n    if (!pInfo) {\n      dssRPT0(dssERROR, \"GetSample::QueryPinInfo() ** E_POINTER **\\n\");\n      return E_POINTER;\n    }\n    pInfo->pFilter = static_cast<IBaseFilter*>(this);\n    AddRef();\n    pInfo->dir = PINDIR_INPUT;\n    wcsncpy(pInfo->achName, L\"GetSample\", MAX_PIN_NAME);\n    dssRPT1(dssCMD, \"GetSample::QueryPinInfo() 0x%08p\\n\", this);\n    return S_OK;\n  }\n\n  HRESULT __stdcall GetSample::QueryDirection(PIN_DIRECTION* pPinDir) {\n    if (!pPinDir) {\n      dssRPT0(dssERROR, \"GetSample::QueryDirection() ** E_POINTER **\\n\");\n      return E_POINTER;\n    }\n    *pPinDir = PINDIR_INPUT;\n    dssRPT0(dssCMD, \"GetSample::QueryDirection()\\n\");\n    return S_OK;\n  }\n\n  HRESULT __stdcall GetSample::QueryId(LPWSTR* Id) { // See FindPin\n    if (!Id) {\n      dssRPT0(dssERROR, \"GetSample::QueryId() ** E_POINTER **\\n\");\n      return E_POINTER;\n    }\n    // CoTaskMemAlloc() fix from Dean Pavlekovic (dpavlekovic) May 2008\n    const WCHAR name[] = L\"GetSample01\";\n    const DWORD nameSize = sizeof(name);\n    *Id = (LPWSTR) CoTaskMemAlloc(nameSize);\n    if (*Id == NULL) {\n       dssRPT0(dssERROR, \"GetSample::QueryId() ** E_OUTOFMEMORY **\\n\");\n       return E_OUTOFMEMORY;\n    }\n    memcpy(*Id, name, nameSize);\n    dssRPT0(dssCMD, \"GetSample::QueryId()\\n\");\n    return S_OK;\n  }\n\n  HRESULT __stdcall GetSample::QueryAccept(const AM_MEDIA_TYPE* pmt) {\n    VideoInfo tmp = vi;\n    bool bInvertFrames = false;\n\n    HRESULT result = InternalQueryAccept(pmt, tmp, bInvertFrames);\n\n    if (result == S_OK) {\n      vi = tmp;\n      m_bInvertFrames = bInvertFrames;\n    }\n\n    return result;\n  }\n\n  HRESULT GetSample::InternalQueryAccept(const AM_MEDIA_TYPE* pmt, VideoInfo &vi, bool &bInvertFrames) {\n    if (!pmt) {\n      dssRPT0(dssERROR, \"GetSample::QueryAccept() ** E_POINTER **\\n\");\n      return E_POINTER;\n    }\n\n    if      (pmt->majortype == MEDIATYPE_Video) {\n      dssRPT1(dssNEG, \"GetSample::QueryAccept(%s) MEDIATYPE_Video\\n\", streamName);\n      if (!load_video) {\n        dssRPT2(dssNEG,  \"*** Video: Subtype - '%s' %s\\n\", PrintFourCC(pmt->subtype.Data1), PrintGUID(&pmt->subtype));\n        dssRPT1(dssNEG,  \"*** Video: Format type - %s\\n\", PrintGUID(&pmt->formattype));\n        return S_FALSE;\n      }\n    }\n    else if (pmt->majortype == MEDIATYPE_Audio) {\n      dssRPT1(dssNEG, \"GetSample::QueryAccept(%s) MEDIATYPE_Audio\\n\", streamName);\n      if (!load_audio) {\n        dssRPT1(dssNEG,  \"*** Audio: Subtype - %s\\n\", PrintGUID(&pmt->subtype));\n        dssRPT1(dssNEG,  \"*** Audio: Format type - %s\\n\", PrintGUID(&pmt->formattype));\n        return S_FALSE;\n      }\n    }\n    else {\n      dssRPT3(dssNEG, \"GetSample::QueryAccept(%s) reject major type '%s' %s\\n\",\n              streamName, PrintFourCC(pmt->majortype.Data1), PrintGUID(&pmt->majortype));\n      dssRPT1(dssNEG,  \"*** Subtype - %s\\n\", PrintGUID(&pmt->subtype));\n      dssRPT1(dssNEG,  \"*** Format type - %s\\n\", PrintGUID(&pmt->formattype));\n      return S_FALSE;\n    }\n\n// Handle audio:\n/*\nAudio: WAVE_FORMAT_EXTENSIBLE 48000Hz 6ch 6912Kbps\n\nAM_MEDIA_TYPE:\nmajortype: MEDIATYPE_Audio {73647561-0000-0010-8000-00AA00389B71}\nsubtype: MEDIASUBTYPE_PCM {00000001-0000-0010-8000-00AA00389B71}\nformattype: FORMAT_WaveFormatEx {05589F81-C356-11CE-BF01-00AA0055595A}\nbFixedSizeSamples: 1\nbTemporalCompression: 0\nlSampleSize: 0\ncbFormat: 40\n\nWAVEFORMATEX:\nwFormatTag: WAVE_FORMAT_EXTENSIBLE = 0xfffe\nnChannels: 6\nnSamplesPerSec: 48000\nnAvgBytesPerSec: 864000\nnBlockAlign: 18\nwBitsPerSample: 24\ncbSize: 22 (extra bytes)\n\nWAVEFORMATEXTENSIBLE:\nwValidBitsPerSample: 24\ndwChannelMask: 0x0000003f\nSubFormat: KSDATAFORMAT_SUBTYPE_PCM {00000001-0000-0010-8000-00AA00389B71}\n\npbFormat:\n0000: fe ff 06 00 80 bb 00 00 00 2f 0d 00 12 00 18 00 ........./......\n0010: 16 00 18 00 3f 00 00 00 01 00 00 00 00 00 10 00 ....?...........\n0020: 80 00 00 aa 00 38 9b 71\n*/\n    if (pmt->majortype == MEDIATYPE_Audio) {\n\n      if (pmt->subtype != MEDIASUBTYPE_PCM\n       && pmt->subtype != MEDIASUBTYPE_IEEE_FLOAT\n       && pmt->subtype != MEDIASUBTYPE_extensible ) {\n        dssRPT1(dssNEG,  \"*** Audio: Subtype rejected - %s\\n\", PrintGUID(&pmt->subtype));\n        return S_FALSE;\n      }\n\n      dssRPT1(dssNEG,  \"*** Audio: Subtype accepted - %s\\n\", PrintGUID(&pmt->subtype));\n\n      if (pmt->formattype != FORMAT_WaveFormatEx) {\n        dssRPT1(dssNEG,  \"*** Audio: Not FORMAT_WaveFormatEx - %s\\n\", PrintGUID(&pmt->formattype));\n        return S_FALSE;\n      }\n      if (pmt->cbFormat < sizeof(WAVEFORMATEX)) {\n        dssRPT2(dssNEG,  \"*** Audio: AM_MEDIA_TYPE.cbFormat to small - %d of %zd\\n\",\n                         pmt->cbFormat, sizeof(WAVEFORMATEX));\n        return S_FALSE;\n      }\n      WAVEFORMATEX* wex = (WAVEFORMATEX*)pmt->pbFormat;\n\n      if ((wex->wFormatTag != WAVE_FORMAT_PCM) &&\n          (wex->wFormatTag != WAVE_FORMAT_IEEE_FLOAT) &&\n          (wex->wFormatTag != WAVE_FORMAT_EXTENSIBLE)) {\n        dssRPT1(dssNEG,  \"*** Audio: Unsupported format - WAVEFORMATEX.wFormatTag=0x%04x\\n\", wex->wFormatTag);\n        return S_FALSE;\n      }\n\n      int sample_type = 0;\n\n      if (wex->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) {\n        sample_type = SAMPLE_FLOAT;\n      }\n      else {\n        switch (wex->wBitsPerSample) {\n          case  8: sample_type = SAMPLE_INT8;  break;\n          case 16: sample_type = SAMPLE_INT16; break;\n          case 24: sample_type = SAMPLE_INT24; break;\n          case 32: sample_type = SAMPLE_INT32; break;\n          default:\n            dssRPT1(dssNEG,  \"*** Audio: Unsupported number of bits per sample: %d\\n\", wex->wBitsPerSample);\n            return S_FALSE;\n        }\n\n        if (wex->wFormatTag == WAVE_FORMAT_EXTENSIBLE) {\n          if (pmt->cbFormat < sizeof(WAVEFORMATEXTENSIBLE)) {\n            dssRPT2(dssNEG,  \"*** Audio: AM_MEDIA_TYPE.cbFormat to small - %d of %zd\\n\",\n                             pmt->cbFormat, sizeof(WAVEFORMATEXTENSIBLE));\n            return S_FALSE;\n          }\n          if (wex->cbSize < 22) {\n            dssRPT1(dssNEG,  \"*** Audio: Extended wave format structure wrong size: %d of 22\\n\", wex->cbSize);\n            return S_FALSE;\n          }\n          // Override settings with extended data (float or >2 ch).\n          WAVEFORMATEXTENSIBLE* wext =  (WAVEFORMATEXTENSIBLE*)pmt->pbFormat;\n\n          if (wext->Samples.wValidBitsPerSample != wext->Format.wBitsPerSample) {\n            dssRPT2(dssNEG,  \"*** Audio: Warning ValidBitsPerSample(%d) != BitsPerSample(%d)!\\n\",\n                     wext->Samples.wValidBitsPerSample, wext->Format.wBitsPerSample);\n//          return S_FALSE; // accept the data here - a postprocessing filter can repair it later\n          }\n\n          if (wext->SubFormat == SUBTYPE_IEEE_AVSFLOAT) {  // We have float audio.\n            sample_type = SAMPLE_FLOAT;\n          } else if (wext->SubFormat != SUBTYPE_IEEE_AVSPCM) {\n            dssRPT1(dssNEG,  \"*** Audio: Extended WAVE format must be Float or PCM. %s\\n\", PrintGUID(&wext->SubFormat));\n            return S_FALSE;\n          }\n        }\n      }\n\n      if (lockvi) {\n        if ( (vi.audio_samples_per_second != (int)wex->nSamplesPerSec)\n          || (vi.nchannels                != wex->nChannels)\n          || (vi.sample_type              != sample_type) ) {\n          dssRPT4(dssNEG,  \"*** Audio: Reject format change! Channels:%d. Samples/sec:%d. Bits/sample:%d. Type:%s\\n\",\n                wex->nChannels, wex->nSamplesPerSec, wex->wBitsPerSample, PrintAudioType(sample_type));\n          return S_FALSE;\n        }\n      }\n\n      vi.audio_samples_per_second = wex->nSamplesPerSec;\n      vi.nchannels = wex->nChannels;\n      vi.sample_type = sample_type;\n\n      dssRPT4(dssNEG,  \"*** Audio: Accepted! Channels:%d. Samples/sec:%d. Bits/sample:%d. Type:%s\\n\",\n            wex->nChannels, wex->nSamplesPerSec, wex->wBitsPerSample, PrintAudioType(sample_type));\n      return S_OK;\n    }\n\n// Handle video:\n\n    if (pmt->majortype == MEDIATYPE_Video) {\n      int pixel_type = 0;\n      bool invert_if_height_is_negative = false; // For RGB24,RGB32,ARGB32.\n      bInvertFrames = false;\n      if        (pmt->subtype == MEDIASUBTYPE_YV12) {\n        if (!(media & mediaYV12)) {\n          dssRPT0(dssNEG,  \"*** Video: Subtype denied - YV12\\n\");\n          return S_FALSE;\n        }\n        pixel_type = VideoInfo::CS_YV12;\n\n      } else if (pmt->subtype == MEDIASUBTYPE_I420) {\n        if (!(media & mediaI420)) {\n          dssRPT0(dssNEG,  \"*** Video: Subtype denied - I420\\n\");\n          return S_FALSE;\n        }\n        pixel_type = VideoInfo::CS_I420;\n\n      } else if (pmt->subtype == MEDIASUBTYPE_NV12) {\n        if (!(media & mediaNV12)) {\n          dssRPT0(dssNEG,  \"*** Video: Subtype denied - NV12\\n\");\n          return S_FALSE;\n        }\n        pixel_type = VideoInfo::CS_YV12;\n\n      } else if (pmt->subtype == MEDIASUBTYPE_YV16) {\n        if (!(media & mediaYV16)) {\n          dssRPT0(dssNEG,  \"*** Video: Subtype denied - YV16\\n\");\n          return S_FALSE;\n        }\n        pixel_type = VideoInfo::CS_YV16;\n\n      } else if (pmt->subtype == MEDIASUBTYPE_YV24) {\n        if (!(media & mediaYV24)) {\n          dssRPT0(dssNEG,  \"*** Video: Subtype denied - YV24\\n\");\n          return S_FALSE;\n        }\n        pixel_type = VideoInfo::CS_YV24;\n\n      } else if (pmt->subtype == MEDIASUBTYPE_Y411) {\n        if (!(media & mediaY411)) {\n          dssRPT0(dssNEG,  \"*** Video: Subtype denied - Y411\\n\");\n          return S_FALSE;\n        }\n        pixel_type = VideoInfo::CS_YV411;\n\n      } else if (pmt->subtype == MEDIASUBTYPE_Y41P) {\n        if (!(media & mediaY41P)) {\n          dssRPT0(dssNEG,  \"*** Video: Subtype denied - Y41P\\n\");\n          return S_FALSE;\n        }\n        pixel_type = VideoInfo::CS_YV411;\n\n      } else if (pmt->subtype == MEDIASUBTYPE_AYUV) {\n        if (!(media & mediaAYUV)) {\n          dssRPT0(dssNEG,  \"*** Video: Subtype denied - AYUV\\n\");\n          return S_FALSE;\n        }\n        pixel_type = VideoInfo::CS_YV24;\n\n      } else if (pmt->subtype == MEDIASUBTYPE_YUY2) {\n        if (!(media & mediaYUY2)) {\n          dssRPT0(dssNEG,  \"*** Video: Subtype denied - YUY2\\n\");\n          return S_FALSE;\n        }\n        pixel_type = VideoInfo::CS_YUY2;\n\n      } else if (pmt->subtype == MEDIASUBTYPE_RGB24) {\n        if (!(media & mediaRGB24)) {\n          dssRPT0(dssNEG,  \"*** Video: Subtype denied - RGB24\\n\");\n          return S_FALSE;\n        }\n        pixel_type = VideoInfo::CS_BGR24;\n        invert_if_height_is_negative = true;\n\n      } else if (pmt->subtype == MEDIASUBTYPE_RGB32) {\n        if (!(media & mediaRGB32)) {\n          dssRPT0(dssNEG,  \"*** Video: Subtype denied - RGB32\\n\");\n          return S_FALSE;\n        }\n        pixel_type = VideoInfo::CS_BGR32;\n        invert_if_height_is_negative = true;\n\n      } else if (pmt->subtype == MEDIASUBTYPE_ARGB32) {\n        if (!(media & mediaARGB)) {\n          dssRPT0(dssNEG,  \"*** Video: Subtype denied - ARGB32\\n\");\n          return S_FALSE;\n        }\n        pixel_type = VideoInfo::CS_BGR32;\n        invert_if_height_is_negative = true;\n\n      } else if (pmt->subtype == MEDIASUBTYPE_BGR48) {\n        if (!(media & mediaRGB48)) {\n          dssRPT0(dssNEG,  \"*** Video: Subtype denied - BGR[48]\\n\");\n          return S_FALSE;\n        }\n        pixel_type = VideoInfo::CS_BGR48;\n        bInvertFrames = true; // BGR[48] is top-down, CS_BGR48 is bottom-up\n\n      } else if (pmt->subtype == MEDIASUBTYPE_BRA64) {\n        if (!(media & mediaRGB64)) {\n          dssRPT0(dssNEG,  \"*** Video: Subtype denied - BRA[64]\\n\");\n          return S_FALSE;\n        }\n        pixel_type = VideoInfo::CS_BGR64;\n        bInvertFrames = true; // BRA[64] is top-down, CS_BGR64 is bottom-up\n\n//      } else if (pmt->subtype == MEDIASUBTYPE_Y8) {\n//        TODO: Y8\n\n      } else {\n        dssRPT2(dssNEG,  \"*** Video: Subtype rejected - '%s' %s\\n\", PrintFourCC(pmt->subtype.Data1), PrintGUID(&pmt->subtype));\n        dssRPT1(dssNEG,  \"*** Video: Format type - %s\\n\", PrintGUID(&pmt->formattype));\n        return S_FALSE;\n      }\n\n      dssRPT2(dssNEG,  \"*** Video: Subtype accepted - '%s' %s\\n\", PrintFourCC(pmt->subtype.Data1), PrintGUID(&pmt->subtype));\n\n      BITMAPINFOHEADER* pbi;\n      unsigned _avg_time_per_frame;\n\n      if (pmt->formattype == FORMAT_VideoInfo) {\n        VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)pmt->pbFormat;\n        _avg_time_per_frame = unsigned(vih->AvgTimePerFrame);\n        pbi = &vih->bmiHeader;\n      }\n      else if (pmt->formattype == FORMAT_VideoInfo2) {\n        VIDEOINFOHEADER2* vih2 = (VIDEOINFOHEADER2*)pmt->pbFormat;\n        _avg_time_per_frame = unsigned(vih2->AvgTimePerFrame);\n        pbi = &vih2->bmiHeader;\n//      if (vih2->dwInterlaceFlags & AMINTERLACE_1FieldPerSample) {\n//        vi.SetFieldBased(true);\n//      }\n      }\n      else {\n        dssRPT1(dssNEG,  \"*** Video: Format type rejected - %s\\n\", PrintGUID(&pmt->formattype));\n        return S_FALSE;\n      }\n\n      dssRPT1(dssNEG,  \"*** Video: Format type accepted - %s\\n\", PrintGUID(&pmt->formattype));\n\n      if (lockvi) {\n        if ( (vi.pixel_type != pixel_type)\n          || (vi.width      != pbi->biWidth)\n          || (vi.height     != ((pbi->biHeight < 0) ? -pbi->biHeight : pbi->biHeight)) ) {\n          dssRPT3(dssNEG,  \"*** Video: reject format change: %dx%d, pixel_type %s\\n\",\n                  pbi->biWidth, pbi->biHeight, PrintPixelType(pixel_type));\n          return S_FALSE;\n        }\n      }\n\n      vi.pixel_type = pixel_type;\n      vi.width = pbi->biWidth;\n      vi.height = (pbi->biHeight < 0) ? -pbi->biHeight : pbi->biHeight;\n\n      if (pbi->biHeight < 0 && invert_if_height_is_negative) {\n        bInvertFrames = true;\n      }\n\n      if (_avg_time_per_frame) {\n        vi.SetFPS(10000000, _avg_time_per_frame);\n      } else {\n        vi.fps_numerator = 1;\n        vi.fps_denominator = 0;\n      }\n\n      dssRPT4(dssNEG,  \"*** Video: format accepted: %dx%d, pixel_type %s, avg_time_per_frame %dx100ns\\n\",\n              vi.width, vi.height, PrintPixelType(vi.pixel_type), _avg_time_per_frame);\n      dssRPT3(dssNEG,  \"*** Video: bFixedSizeSamples=%d, bTemporalCompression=%d, lSampleSize=%d\\n\",\n            pmt->bFixedSizeSamples, pmt->bTemporalCompression, pmt->lSampleSize);\n\n      return S_OK;\n    }\n    return S_FALSE;\n  }\n\n  HRESULT __stdcall GetSample::EnumMediaTypes(IEnumMediaTypes** ppEnum) {\n    if (!ppEnum) {\n      dssRPT0(dssERROR, \"GetSample::EnumMediaTypes() ** E_POINTER **\\n\");\n      return E_POINTER;\n    }\n    if (no_my_media_types == 0) {\n      dssRPT0(dssCMD, \"GetSample::EnumMediaTypes() ** E_NOTIMPL **\\n\");\n      return E_NOTIMPL;\n    }\n    dssRPT0(dssCMD, \"GetSample::EnumMediaTypes()\\n\");\n    *ppEnum = new GetSampleEnumMediaTypes(this, no_my_media_types);\n    return *ppEnum ? S_OK : E_OUTOFMEMORY;\n  }\n\n  HRESULT __stdcall GetSample::QueryInternalConnections(IPin** apPin, ULONG* nPin) {\n    if (!nPin) {\n      dssRPT0(dssERROR, \"GetSample::QueryInternalConnections() ** E_POINTER **\\n\");\n      return E_POINTER;\n    }\n    *nPin = 0;\n    dssRPT0(dssCMD, \"GetSample::QueryInternalConnections()\\n\");\n    return S_OK;\n  }\n\n  HRESULT __stdcall GetSample::EndOfStream() {\n    dssRPT1((dssSAMP|dssCMD), \"GetSample::EndOfStream() (%s)\\n\", streamName);\n    end_of_stream = true;\n    if (filter_graph) {\n      IMediaEventSink* mes = NULL;\n      try {\n        if (SUCCEEDED(filter_graph->QueryInterface(&mes))) {\n          mes->Notify(EC_COMPLETE, (LONG_PTR)S_OK, (LONG_PTR)static_cast<IBaseFilter*>(this));\n          mes->Release();\n        }\n      }\n      catch (...) {\n        dssRPT0((dssERROR|dssCMD), \"GetSample::EndOfStream() Unknown Exception!\\n\");\n        if (mes) mes->Release();\n      }\n    }\n    dssRPT0(dssCMD, \"EndOfStream() indicating new sample ready\\n\");\n    SetEvent(evtNewSampleReady);\n    return S_OK;\n  }\n\n  HRESULT __stdcall GetSample::BeginFlush() {\n    dssRPT1(dssCMD, \"GetSample::BeginFlush() (%s)\\n\", streamName);\n    flushing = true;\n    SetEvent(evtDoneWithSample); // Free task if waiting\n    graphTimeout = true;\n    return S_OK;\n  }\n\n  HRESULT __stdcall GetSample::EndFlush() {\n    dssRPT1(dssCMD, \"GetSample::EndFlush() (%s)\\n\", streamName);\n    ResetEvent(evtDoneWithSample);  // Nuke any unused SetEvents\n    flushing = false;\n    return S_OK;\n  }\n\n  HRESULT __stdcall GetSample::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) {\n    dssRPT4(dssSAMP, \"GetSample::NewSegment(%I64d, %I64d, %f) (%s)\\n\", tStart, tStop, dRate, streamName);\n    segment_start_time = tStart;\n    segment_stop_time  = tStop;\n    time_of_last_frame = int(sample_end_time - sample_start_time);\n    sample_end_time = sample_start_time = 0;\n    return S_OK;\n  }\n\n  // IMemInputPin\n\n  HRESULT __stdcall GetSample::GetAllocator(IMemAllocator** ppAllocator) {\n    if (!ppAllocator) {\n      dssRPT0(dssCMD, \"GetSample::GetAllocator() E_POINTER\\n\");\n      return E_POINTER;\n    }\n    if (!Allocator) {\n      dssRPT0(dssCMD, \"GetSample::GetAllocator() VFW_E_NO_ALLOCATOR\\n\");\n      return VFW_E_NO_ALLOCATOR;\n    }\n    dssRPT1(dssCMD, \"GetSample::GetAllocator(0x%08p)\\n\", Allocator);\n    Allocator->AddRef();\n    *ppAllocator = Allocator;\n    return S_OK;\n  }\n\n  HRESULT __stdcall GetSample::NotifyAllocator(IMemAllocator* pAllocator, BOOL bReadOnly) {\n    dssRPT4(dssCMD, \"GetSample::NotifyAllocator(0x%08p, %x) was 0x%08p (%s)\\n\", pAllocator, bReadOnly, Allocator, streamName);\n    if (!pAllocator) {\n      dssRPT0(dssCMD, \"GetSample::NotifyAllocator() E_POINTER\\n\");\n      return E_POINTER;\n    }\n    if (Allocator) {\n      Allocator->Release();\n    }\n    Allocator = pAllocator;\n    Allocator->AddRef();\n    return S_OK;\n  }\n\n  HRESULT __stdcall GetSample::GetAllocatorRequirements(ALLOCATOR_PROPERTIES* pProps) {\n    if (!pProps) {\n      dssRPT0(dssERROR, \"GetSample::GetAllocatorRequirements(*pProps) E_POINTER\\n\");\n      return E_POINTER;\n    }\n    dssRPT4(dssCMD, \"GetSample::GetAllocatorRequirements(%d, %d, %d, %d) E_NOTIMPL\\n\",\n            pProps->cBuffers, pProps->cbBuffer, pProps->cbAlign, pProps->cbPrefix);\n    return E_NOTIMPL;\n  }\n\n  HRESULT __stdcall GetSample::Receive(IMediaSample* pSamples) {\n    if (seeking) {\n      dssRPT1(dssSAMP, \"Receive: discarding sample (seeking) (%s)\\n\", streamName);\n      return S_OK;\n    }\n    if (S_OK == pSamples->IsPreroll()) {\n      dssRPT1(dssSAMP, \"Receive: discarding sample (preroll) (%s)\\n\", streamName);\n      return S_OK;\n    }\n    if (flushing) {\n      dssRPT1(dssSAMP, \"Receive: discarding sample (flushing) (%s)\\n\", streamName);\n      return S_FALSE;\n    }\n    if (state == State_Stopped) {\n      dssRPT1(dssSAMP, \"Receive: discarding sample (State_Stopped) (%s)\\n\", streamName);\n      return VFW_E_WRONG_STATE;\n    }\n\n    pSamples->GetPointer(&av_buffer);\n    int deltaT = avg_time_per_frame;\n\n    av_sample_bytes = pSamples->GetActualDataLength();\n    if (load_audio) {  // audio\n      deltaT = MulDiv(av_sample_bytes, 10000000, vi.BytesPerAudioSample()*vi.SamplesPerSecond());\n      dssRPT1(dssSAMP, \"Receive: Got %d bytes of audio data.\\n\",av_sample_bytes);\n    }\n\n    HRESULT result = pSamples->GetTime(&sample_start_time, &sample_end_time);\n    if (result == VFW_S_NO_STOP_TIME) {\n      dssRPT0(dssINFO, \"VFW_S_NO_STOP_TIME!\\n\");\n      sample_end_time = sample_start_time + deltaT; // wing it\n    }\n    else if (FAILED(result)) {\n      dssRPT0(dssINFO, \"GetTime failed!\\n\");\n      sample_start_time += deltaT; // wing it\n      sample_end_time = sample_start_time + deltaT;\n    }\n    // Yes +1! Some brain dead decoders think an acceptable implementation is\n    // STOP_TIME = START_TIME + 1, others get it just plain wrong i.e. Negative etc,\n    else if (sample_end_time <= sample_start_time+1) {\n      dssRPT1(dssINFO, \"Got bogus stop time! %I64d\\n\", sample_end_time);\n      sample_end_time = sample_start_time + deltaT;\n    }\n    dssRPT4(dssSAMP, \"Receive: %s sample time span x100ns %I64d to %I64d (%d)\\n\", streamName,\n            sample_start_time, sample_end_time, DWORD(sample_end_time - sample_start_time));\n    HRESULT wait_result;\n    SetEvent(evtNewSampleReady);  // New sample is finished - wait releasing it\n                                  // until it has been fetched (DoneWithSample).\n    do {\n      dssRPT1(dssWAIT, \"...Receive() waiting for DoneWithSample. (%s)\\n\", streamName);\n      if (log && log->mask && log->file) fflush(log->file);\n      wait_result = WaitForSingleObject(evtDoneWithSample, 15000);\n    } while ((wait_result == WAIT_TIMEOUT) && (state != State_Stopped));\n\n    av_buffer = 0;\n    av_sample_bytes = 0;\n\n    dssRPT1(dssINFO, \"Receive() - returning. (%s)\\n\", streamName);\n\n    return S_OK;\n  }\n\n  HRESULT __stdcall GetSample::ReceiveMultiple(IMediaSample** ppSamples, long nSamples, long* nSamplesProcessed) {\n    dssRPT0(dssCMD, \"GetSample::ReceiveMultiple()\\n\");\n    for (int i=0; i<nSamples; ++i) {\n      HRESULT hr = Receive(ppSamples[i]);\n      if (FAILED(hr)) {\n        *nSamplesProcessed = i;\n        return hr;\n      }\n    }\n    *nSamplesProcessed = nSamples;\n    return S_OK;\n  }\n\n  HRESULT __stdcall GetSample::ReceiveCanBlock() {\n    dssRPT0(dssCMD, \"GetSample::ReceiveCanBlock()\\n\");\n    return S_OK;\n  }\n\n\n\n/***********************************************\n *             GetSampleEnumPins               *\n ***********************************************/\n\n\n\nGetSampleEnumPins::GetSampleEnumPins(GetSample* _parent, int _pos)\n : parent(_parent), log(_parent->log) {\n  dssRPT0(dssNEW, \"New GetSampleEnumPins.\\n\");\n  pos=_pos;\n  refcnt = 1;\n}\n\nGetSampleEnumPins::~GetSampleEnumPins() {\n  dssRPT0(dssNEW, \"~GetSampleEnumPins.\\n\");\n}\n\nHRESULT __stdcall GetSampleEnumPins::Next(ULONG cPins, IPin** ppPins, ULONG* pcFetched) {\n  if (!ppPins || !pcFetched) return E_POINTER;\n  int copy = *pcFetched = min(int(cPins), 1-pos);\n  if (copy>0) {\n    *ppPins = static_cast<IPin*>(parent);\n    parent->AddRef();\n  }\n  pos += copy;\n  return int(cPins) > copy ? S_FALSE : S_OK;\n}\n\n\n/***********************************************\n *          GetSampleEnumMediaTypes            *\n ***********************************************/\n\n\n\nGetSampleEnumMediaTypes::GetSampleEnumMediaTypes(GetSample* _parent, unsigned _count, unsigned _pos)\n : parent(_parent), log(_parent->log) {\n\n  dssRPT0(dssNEW, \"New GetSampleEnumMediaTypes.\\n\");\n\n  pos = 0;\n  count = _count;\n  refcnt = 1;\n}\n\nGetSampleEnumMediaTypes::~GetSampleEnumMediaTypes() {\n  dssRPT0(dssNEW, \"~GetSampleEnumMediaTypes.\\n\");\n}\n\nHRESULT __stdcall GetSampleEnumMediaTypes::Next(ULONG cMediaTypes, AM_MEDIA_TYPE** ppMediaTypes, ULONG* pcFetched) {\n  if (!ppMediaTypes) {\n    dssRPT0(dssERROR, \"GetSampleEnumMediaTypes::Next(ppMediaTypes) E_POINTER\\n\");\n    return E_POINTER;\n  }\n  if (!pcFetched && (cMediaTypes != 1)) {\n    dssRPT0(dssERROR, \"GetSampleEnumMediaTypes::Next(pcFetched) E_POINTER\\n\");\n    return E_POINTER;\n  }\n  dssRPT2(dssCMD, \"GetSampleEnumMediaTypes::Next(%u) pos=%u\\n\", cMediaTypes, pos);\n  unsigned long copy = min(cMediaTypes, (unsigned long)(count-pos));\n  if (pcFetched) *pcFetched = copy;\n  while (copy-- > 0) {\n    *ppMediaTypes++ = CreateMediaType(parent->GetMediaType(pos++)) ;\n  }\n  return (pos >= count) ? S_FALSE : S_OK;\n}\n\nHRESULT __stdcall GetSampleEnumMediaTypes::Skip(ULONG cMediaTypes) {\n  dssRPT2(dssCMD, \"GetSampleEnumMediaTypes::Skip(%u) pos=%u\\n\", cMediaTypes, pos);\n  pos += cMediaTypes;\n  if (pos >= count) {\n    pos = count;\n    return S_FALSE;\n  }\n  return S_OK;\n}\n\nHRESULT __stdcall GetSampleEnumMediaTypes::Reset() {\n  pos=0;\n  return S_OK;\n}\n\nHRESULT __stdcall GetSampleEnumMediaTypes::Clone(IEnumMediaTypes** ppEnum) {\n  if (!ppEnum) {\n    dssRPT0(dssERROR, \"GetSampleEnumMediaTypes::Clone() E_POINTER\\n\");\n    return E_POINTER;\n  }\n  dssRPT0(dssCMD, \"GetSampleEnumMediaTypes::Clone()\\n\");\n  *ppEnum = new GetSampleEnumMediaTypes(parent, count, pos);\n  return *ppEnum ? S_OK : E_OUTOFMEMORY;\n}\n\n\n/***********************************************\n *    DirectShowSource Helper Functions.       *\n ***********************************************/\n\n\n\nstatic bool HasNoConnectedOutputPins(IBaseFilter* bf) {\n  IEnumPins* ep;\n  if (FAILED(bf->EnumPins(&ep)))\n    return true;\n  ULONG fetched=1;\n  IPin* pin;\n  while (S_OK == ep->Next(1, &pin, &fetched)) {\n    PIN_DIRECTION dir;\n    pin->QueryDirection(&dir);\n    if (dir == PINDIR_OUTPUT) {\n      IPin* other;\n      pin->ConnectedTo(&other);\n      if (other) {\n        other->Release();\n        pin->Release();\n        ep->Release();\n        return false;\n      }\n    }\n    pin->Release();\n  }\n  ep->Release();\n  return true;\n}\n\n\n\nstatic void DisconnectAllPinsAndRemoveFilter(IGraphBuilder* gb, IBaseFilter* bf) {\n  IEnumPins* ep;\n  if (SUCCEEDED(bf->EnumPins(&ep))) {\n    ULONG fetched=1;\n    IPin* pin;\n    while (S_OK == ep->Next(1, &pin, &fetched)) {\n      IPin* other;\n      pin->ConnectedTo(&other);\n      if (other) {\n        gb->Disconnect(other);\n        gb->Disconnect(pin);\n        other->Release();\n      }\n      pin->Release();\n    }\n    ep->Release();\n  }\n  gb->RemoveFilter(bf);\n}\n\n\nstatic void RemoveUselessFilters(IGraphBuilder* gb, IBaseFilter* not_this_one, IBaseFilter* nor_this_one) {\n  IEnumFilters* ef;\n  if (FAILED(gb->EnumFilters(&ef)))\n    return;\n  ULONG fetched=1;\n  IBaseFilter* bf;\n  while (S_OK == ef->Next(1, &bf, &fetched)) {\n    if (bf != not_this_one && bf != nor_this_one) {\n      if (HasNoConnectedOutputPins(bf)) {\n        DisconnectAllPinsAndRemoveFilter(gb, bf);\n        ef->Reset();\n      }\n    }\n    bf->Release();\n  }\n  ef->Release();\n}\n\nstatic HRESULT AttemptConnectFilters(IGraphBuilder* gb, IBaseFilter* connect_filter) {\n  IEnumFilters* ef;\n\n  if (FAILED(gb->EnumFilters(&ef)))\n    return E_UNEXPECTED;\n\n  HRESULT hr;\n  ULONG fetched=1;\n  IBaseFilter* bf;\n  IEnumPins* ep_conn;\n\n  connect_filter->EnumPins(&ep_conn);\n  IPin* p_conn;\n\n  if (FAILED(ep_conn->Next(1, &p_conn, &fetched)))\n    return E_UNEXPECTED;\n\n  while (S_OK ==(ef->Next(1, &bf, &fetched))) {\n    if (bf != connect_filter) {\n      IEnumPins* ep;\n\n      bf->EnumPins(&ep);\n      IPin* pPin;\n      while (S_OK == (ep->Next(1, &pPin, &fetched)))  {\n\n        PIN_DIRECTION PinDirThis;\n        pPin->QueryDirection(&PinDirThis);\n\n        if (PinDirThis == PINDIR_OUTPUT) {\n          hr = gb->ConnectDirect(pPin, p_conn, NULL);\n          if (SUCCEEDED(hr)) {\n            pPin->Release();\n            ep->Release();\n            bf->Release();\n            ep_conn->Release();\n            ef->Release();\n            return S_OK;\n          }\n        }\n      }\n      pPin->Release();\n      ep->Release();\n    }\n    bf->Release();\n  }\n  ep_conn->Release();\n  ef->Release();\n  return S_OK;\n}\n\nvoid DirectShowSource::SetMicrosoftDVtoFullResolution(IGraphBuilder* gb) {\n  // Microsoft's DV codec defaults to half-resolution, to everyone's\n  // great annoyance.  This will set it to full res if possible.\n  // Note that IIPDVDec is not declared in older versions of\n  // strmif.h; you may need the Win2000 platform SDK.\n  IEnumFilters* ef;\n  if (FAILED(gb->EnumFilters(&ef)))\n    return;\n  ULONG fetched=1;\n  IBaseFilter* bf;\n  while (S_OK == ef->Next(1, &bf, &fetched)) {\n    IIPDVDec* pDVDec;\n    if (SUCCEEDED(bf->QueryInterface(&pDVDec))) {\n      dssRPT1(dssINFO, \"DVtoFullResolution() pDVDec=0x%08p\\n\", pDVDec);\n      pDVDec->put_IPDisplay(DVRESOLUTION_FULL); // DVDECODERRESOLUTION_720x480);   // yes, this includes 720x576\n      pDVDec->Release();\n    }\n    bf->Release();\n  }\n  ef->Release();\n\n}\n\n// The following constant is from \"wmcodecconst.h\" in the\n// \"Windows Media Audio and Video Codec Interfaces download package\"\n// available for download from MSDN.\nstatic const WCHAR *g_wszWMVCDecoderDeinterlacing = L\"_DECODERDEINTERLACING\";\n\nvoid DirectShowSource::DisableDeinterlacing(IFilterGraph *pGraph)\n{\n  IEnumFilters *pEnum = NULL;\n  IBaseFilter *pFilter;\n  ULONG cFetched;\n\n  HRESULT hr = pGraph->EnumFilters(&pEnum);\n  if (FAILED(hr))\n    return;\n\n  while(pEnum->Next(1, &pFilter, &cFetched) == S_OK) {\n    FILTER_INFO FilterInfo;\n\n    hr = pFilter->QueryFilterInfo(&FilterInfo);\n    if (SUCCEEDED(hr)) {\n      if (wcscmp(FilterInfo.achName, L\"WMVideo Decoder DMO\") == 0) {\n        IPropertyBag *pPropertyBag = NULL;\n\n        hr = pFilter->QueryInterface(IID_IPropertyBag, (void**)&pPropertyBag);\n        if(SUCCEEDED(hr)) {\n          dssRPT1(dssINFO, \"DisableDeinterlacing() pPropertyBag=0x%08p\\n\", pPropertyBag);\n          VARIANT myVar;\n\n          VariantInit(&myVar);\n          // Disable decoder deinterlacing\n          myVar.vt   = VT_BOOL;\n          myVar.lVal = FALSE;\n          pPropertyBag->Write(g_wszWMVCDecoderDeinterlacing, &myVar);\n\n          pPropertyBag->Release();\n        }\n        else {\n          dssRPT2(dssINFO, \"DisableDeinterlacing() pFilter=0x%08p code=%X\\n\", pFilter, hr);\n        }\n      }\n      // The FILTER_INFO structure holds a pointer to the Filter Graph\n      // Manager, with a reference count that must be released.\n      if (FilterInfo.pGraph != NULL)\n        FilterInfo.pGraph->Release();\n    }\n    pFilter->Release();\n  }\n  pEnum->Release();\n}\n\n\nstatic const WCHAR *g_wszWMACHiResOutput = L\"_HIRESOUTPUT\";\n\nvoid DirectShowSource::SetWMAudioDecoderDMOtoHiResOutput(IFilterGraph *pGraph)\n{\n  IEnumFilters *pEnum = NULL;\n  IBaseFilter *pFilter;\n  ULONG cFetched;\n\n  HRESULT hr = pGraph->EnumFilters(&pEnum);\n  if (FAILED(hr))\n    return;\n\n  // Search graph for \"WMAudio Decoder DMO\"\n  while(pEnum->Next(1, &pFilter, &cFetched) == S_OK) {\n    FILTER_INFO FilterInfo;\n\n    hr = pFilter->QueryFilterInfo(&FilterInfo);\n    if (SUCCEEDED(hr)) {\n      if (wcscmp(FilterInfo.achName, L\"WMAudio Decoder DMO\") == 0) {\n        IPropertyBag *pPropertyBag = NULL;\n\n        hr = pFilter->QueryInterface(IID_IPropertyBag, (void**)&pPropertyBag);\n        if(SUCCEEDED(hr)) {\n          dssRPT1(dssINFO, \"WMAudioDecoderDMOtoHiRes() pPropertyBag=0x%08p\\n\", pPropertyBag);\n          VARIANT myVar;\n\n          VariantInit(&myVar);\n          // Enable full output capabilities\n          myVar.vt      = VT_BOOL;\n          myVar.boolVal = -1; // True\n          pPropertyBag->Write(g_wszWMACHiResOutput, &myVar);\n\n          pPropertyBag->Release();\n\n          IEnumPins* ep;\n          if (SUCCEEDED(pFilter->EnumPins(&ep))) {\n            ULONG fetched=1;\n            IPin* pin;\n            // Search for output pin\n            while (S_OK == ep->Next(1, &pin, &fetched)) {\n              PIN_DIRECTION dir;\n              pin->QueryDirection(&dir);\n              if (dir == PINDIR_OUTPUT) {\n                // Reconnect output pin\n                hr = pGraph->Reconnect(pin);\n                if(FAILED(hr)) {\n                  dssRPT1(dssINFO, \"WMAudioDecoderDMOtoHiRes() Reconnect failed, code = %X\\n\", hr);\n                }\n              }\n              pin->Release();\n            }\n            ep->Release();\n          }\n        }\n        else {\n          dssRPT2(dssINFO, \"WMAudioDecoderDMOtoHiRes() pFilter=0x%08p code=%X\\n\", pFilter, hr);\n        }\n      }\n      // The FILTER_INFO structure holds a pointer to the Filter Graph\n      // Manager, with a reference count that must be released.\n      if (FilterInfo.pGraph != NULL)\n        FilterInfo.pGraph->Release();\n    }\n    pFilter->Release();\n  }\n  pEnum->Release();\n}\n\nstatic std::unique_ptr<wchar_t[]> AnsiToWideCharACP(const char* s_ansi)\n{\n  const size_t bufsize = strlen(s_ansi) + 1;\n  auto w_string = std::make_unique<wchar_t[]>(bufsize);\n  MultiByteToWideChar(CP_ACP, 0, s_ansi, -1, w_string.get(), (int)bufsize);\n  //mbstowcs(script_name_w, script_name, len); // ansi to wchar_t, does not convert properly out-of-the box\n  return w_string;\n}\n\nstatic std::unique_ptr<wchar_t[]> Utf8ToWideChar(const char* s_ansi)\n{\n  const size_t wchars_count = MultiByteToWideChar(CP_UTF8, 0, s_ansi, -1, NULL, 0);\n  const size_t bufsize = wchars_count + 1;\n  auto w_string = std::make_unique<wchar_t[]>(bufsize);\n  MultiByteToWideChar(CP_UTF8, 0, s_ansi, -1, w_string.get(), (int)bufsize);\n  return w_string;\n}\n\n/************************************************\n *               DirectShowSource               *\n ***********************************************/\n\n\nDirectShowSource::DirectShowSource(const char* filename, int _avg_time_per_frame, int _seekmode,\n                                   bool _enable_audio, bool _enable_video, bool _convert_fps, unsigned _media,\n                                   int _timeout, int _frames, LOG* _log, bool _utf8, IScriptEnvironment* env)\n  : get_sample(_enable_audio, _enable_video, _media, _log), seekmode(_seekmode), convert_fps(_convert_fps),\n    gb(NULL), currentFrame(0), TrapTimeouts(_timeout < 0), WaitTimeout(abs(_timeout)), log(_log) {\n\n  dssRPT0(dssNEW, \"New DirectShowSource.\\n\");\n\n  IMediaFilter*  mf = 0;\n  IMediaSeeking* ms = 0;\n\n  try {\n    CheckHresult(env, CoCreateInstance(CLSID_FilterGraphNoThread, 0, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&gb),\n                 \"couldn't create filter graph\");\n\n    auto filenameW = !_utf8 ? AnsiToWideCharACP(filename) : Utf8ToWideChar(filename);\n\n    CheckHresult(env, gb->AddFilter(static_cast<IBaseFilter*>(&get_sample), L\"GetSample\"), \"couldn't add GetSample filter\");\n\n    int fnlen = lstrlen(filename);\n    bool load_grf = (fnlen >= 4) ? !lstrcmpi(filename+fnlen-4,\".grf\") : false;  // Detect \".GRF\" extension and load as graph if so.\n\n    if (load_grf) {\n      CheckHresult(env, LoadGraphFile(gb, filenameW.get()), \"Couldn't open GRF file.\", filename);\n      // Try connecting to any open pins.\n      AttemptConnectFilters(gb, &get_sample);\n      if (!get_sample.IsConnected()) {\n        if (_enable_video)\n          env->ThrowError(\"DirectShowSource: GRF file does not have a compatible open video pin.\\n\"\n                          \"Graph must have 1 output pin that will bid RGB24, RGB32, RGB48, RGB64, ARGB, YUY2,\\n\"\n                          \"YV12, I420, NV12, YV16, YV24, Y41P, Y411 or AYUV\");\n        else\n          env->ThrowError(\"DirectShowSource: GRF file does not have a compatible open audio pin.\\n\"\n                          \"Graph must have 1 output pin that will bid 8, 16, 24 or 32 bit PCM or IEEE Float.\");\n      }\n    } else {\n      HRESULT RFHresult = gb->RenderFile(filenameW.get(), NULL);\n      if (!get_sample.IsConnected()) { // Ignore arbitary errors, run with what we got\n        CheckHresult(env, RFHresult, \"couldn't open file \", filename);\n        env->ThrowError(\"DirectShowSource: RenderFile, the filter graph manager won't talk to me\");\n      }\n    }\n\n    RemoveUselessFilters(gb, &get_sample, &get_sample);\n\n    if (_enable_video) {\n      SetMicrosoftDVtoFullResolution(gb);\n      DisableDeinterlacing(gb);\n    }\n\n    if (_enable_audio) {\n      SetWMAudioDecoderDMOtoHiResOutput(gb);\n    }\n\n    // Prevent the graph from trying to run in \"real time\"\n    // ... Disabled because it breaks ASF.  Now I know why\n    // Avery swears so much.\n    CheckHresult(env, gb->QueryInterface(&mf), \"couldn't get IMediaFilter interface\");\n    CheckHresult(env, mf->SetSyncSource(NULL), \"couldn't set null sync source\");\n    SAFE_RELEASE(mf);\n\n    CheckHresult(env, gb->QueryInterface(&ms), \"couldn't get IMediaSeeking interface\");\n\n    CheckHresult(env, get_sample.StartGraph(gb), \"DirectShowSource : Graph refused to run.\");\n\n    if (TrapTimeouts) {\n      DWORD timeout = 2000;   // 2 seconds\n      get_sample.WaitForStart(timeout);\n    }\n    else {\n      DWORD timeout = clamp(WaitTimeout, 5000ul, 300000ul);   // 5 seconds to 5 minutes\n      if (get_sample.WaitForStart(timeout))\n        // If returning grey frames, trap on init!\n        env->ThrowError(\"DirectShowSource : Timeout waiting for graph to start.\");\n    }\n\n    vi = get_sample.GetVideoInfo();\n\n    if (vi.HasVideo()) {\n      __int64 frame_count = 0, duration = 0;\n      GUID time_fmt = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};\n\n      // SetTimeFormat can give E_NOTIMPL\n      ms->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME);\n      // so check what it currently is\n      ms->GetTimeFormat(&time_fmt);\n\n      if (time_fmt == TIME_FORMAT_MEDIA_TIME) ms->GetDuration(&duration);\n\n      if (duration <= 0) duration = get_sample.segment_stop_time-get_sample.segment_start_time;\n\n      // run in frame mode if we can set time format to frame\n      frame_units = SUCCEEDED(ms->SetTimeFormat(&TIME_FORMAT_FRAME));\n\n      if (frame_units) ms->GetDuration(&frame_count);\n\n      dssRPT2((dssNEG|dssCALL), \"Directshow duration %I64d, frame_count %I64d.\\n\", duration, frame_count);\n\n      if (convert_fps || frame_count <= 0) frame_units = false;\n\n      if (duration <= 0 && !frame_units && !_frames) {\n        env->ThrowError(\"DirectShowSource: unable to determine the duration of the video.\");\n      }\n\n      if (_avg_time_per_frame) { // User specified FPS\n        get_sample.avg_time_per_frame = _avg_time_per_frame;\n        vi.SetFPS(10000000, _avg_time_per_frame);\n        vi.num_frames = int(frame_units ? frame_count : (duration + (_avg_time_per_frame-1)) / _avg_time_per_frame); // Ceil()\n      }\n      else {\n        // this is exact (no rounding needed) because of the way the fps is set in GetSample\n        get_sample.avg_time_per_frame = 10000000 / vi.fps_numerator * vi.fps_denominator; // Floor()\n\n        if (get_sample.avg_time_per_frame != 0) {\n          // We have all the info\n          vi.num_frames = int(frame_units ? frame_count :\n                              (duration + (get_sample.avg_time_per_frame-1)) / get_sample.avg_time_per_frame); // Ceil()\n        }\n        else {\n          // Try duration divided by frame count\n          if (frame_count > 0 && duration > 0) {\n            get_sample.avg_time_per_frame = int((duration + (frame_count>>1)) / frame_count); // Round()\n            vi.num_frames = int(frame_count);\n\n            unsigned __int64 numerator   = 10000000 * frame_count;\n            unsigned __int64 denominator = duration;\n\n            unsigned __int64 x=numerator, y=denominator;\n            while (y) {   // find gcd\n              unsigned __int64 t = x%y; x = y; y = t;\n            }\n            numerator   /= x; // normalize\n            denominator /= x;\n\n            unsigned __int64 temp = numerator | denominator; // Just looking for top bit\n            unsigned u = 0;\n            while (temp & 0xffffffff80000000) {\n              temp = Int64ShrlMod32(temp, 1);\n              u++;\n            }\n            if (u) { // Scale to fit\n              const unsigned round = 1 << (u-1);\n              vi.SetFPS( (unsigned)Int64ShrlMod32(numerator   + round, u),\n                         (unsigned)Int64ShrlMod32(denominator + round, u) );\n            }\n            else {\n              vi.fps_numerator   = (unsigned)numerator;\n              vi.fps_denominator = (unsigned)denominator;\n            }\n          }\n          // Try duration of first frame\n          else {\n            switch (get_sample.time_of_last_frame) {\n              case 160000: case 170000:\n                vi.fps_numerator   = 60000;\n                vi.fps_denominator = 1001;\n                get_sample.avg_time_per_frame = 166833;\n                break;\n\n              case 200000:\n                vi.fps_numerator   = 50;\n                vi.fps_denominator = 1;\n                get_sample.avg_time_per_frame = 200000;\n                break;\n\n              case 330000: case 340000:\n                vi.fps_numerator   = 30000;\n                vi.fps_denominator = 1001;\n                get_sample.avg_time_per_frame = 333667;\n                break;\n\n              case 400000:\n                vi.fps_numerator   = 25;\n                vi.fps_denominator = 1;\n                get_sample.avg_time_per_frame = 400000;\n                break;\n\n              case 410000: case 420000:\n                vi.fps_numerator   = 24000;\n                vi.fps_denominator = 1001;\n                get_sample.avg_time_per_frame = 417083;\n                break;\n\n              default:\n                env->ThrowError(\"DirectShowSource: I can't determine the frame rate\\n\"\n                                \"of the video, you must use the \\\"fps\\\" parameter.\"); // Note must match message below\n            }\n            vi.num_frames = int(frame_units ? frame_count :\n               (duration*vi.fps_numerator + vi.fps_denominator*10000000i64 - 1) / (vi.fps_denominator*10000000i64) ); // Ceil()\n          }\n        }\n      }\n      if (_frames) vi.num_frames = _frames;\n\n      dssRPT4((dssNEG|dssCALL), \"New Video: %dx%d, frame_count=%d, pixel type=%s.\\n\",\n                                vi.width, vi.height, vi.num_frames, PrintPixelType(vi.pixel_type));\n    }\n\n    if (vi.HasAudio()) {\n      GUID time_fmt = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};\n      __int64 audio_dur = 0;\n\n      if (_avg_time_per_frame && _frames) { // User specified FPS + FrameCount\n        audio_dur = Int32x32To64(_avg_time_per_frame, _frames);\n      }\n      else {\n        // SetTimeFormat can give E_NOTIMPL\n        ms->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME);\n        // so check what it currently is\n        ms->GetTimeFormat(&time_fmt);\n\n        if (time_fmt == TIME_FORMAT_MEDIA_TIME) ms->GetDuration(&audio_dur);\n\n        if (audio_dur == 0) audio_dur = get_sample.segment_stop_time-get_sample.segment_start_time;\n\n        if (audio_dur == 0) {\n            env->ThrowError(\"DirectShowSource: unable to determine the duration of the audio.\\n\"\n                            \"Manually specify FPS and Framecount. Duration = Framecount / FPS\");\n        }\n      }\n\n      vi.num_audio_samples = (audio_dur * vi.audio_samples_per_second + 9999999) / 10000000; // Ceil()\n\n      dssRPT2((dssNEG|dssCALL), \"New Audio: audio_dur %I64dx100ns, samples %I64d.\\n\",\n                                audio_dur, vi.num_audio_samples);\n    }\n    SAFE_RELEASE(ms);\n\n    cur_frame = 0;\n    audio_bytes_read = 0;\n    next_sample = 0;\n  }\n  catch (...) {\n    SAFE_RELEASE(mf);\n    SAFE_RELEASE(ms);\n    cleanUp();\n    throw;\n  }\n}\n\n\n  DirectShowSource::~DirectShowSource() {\n    dssRPT0(dssNEW, \"~DirectShowSource.\\n\");\n\n    cleanUp();\n  }\n\n  void DirectShowSource::cleanUp() {\n    if (gb) {\n      IMediaControl* mc = NULL;\n      try {\n      if (SUCCEEDED(gb->QueryInterface(&mc))) {\n        OAFilterState st;\n        mc->GetState(1000, &st);\n        if (st != State_Stopped) mc->Stop();\n        mc->Release();\n      }\n      get_sample.StopGraph(gb);\n      SAFE_RELEASE(gb);\n      }\n      catch (...) {\n        dssRPT0(dssERROR, \"cleanup Unknown Exception!\\n\");\n        if (mc) mc->Release();\n      }\n    }\n  }\n\n#if 0\n  PVideoFrame __stdcall DirectShowSource::GetFrame(int n, IScriptEnvironment* env) {\n    DWORD timeout = WaitTimeout;\n    n = max(min(n, vi.num_frames-1), 0);\n\n    // Ask for the frame whose [start_time ->T<- end_time] spans sample_time\n    const __int64 sample_time = (n == 0) ? 0 : Int32x32To64(n, get_sample.avg_time_per_frame) + (get_sample.avg_time_per_frame>>1);\n\n    dssRPT2(dssCALL, \"GetFrame: Frame %d time %I64dx100ns.\\n\", n, sample_time);\n\n    if ( (seekmode == 0 && n >= cur_frame) || (seekmode == 2) || (n >= cur_frame && n <= cur_frame+10) ) {\n      // seekzero==true+forwards or seek==false or a short hop forwards\n      if (convert_fps) {\n        // automatic fps conversion: trust only sample time\n        while (get_sample.GetSampleEndTime() <= sample_time) {\n          if(!get_sample.NextSample(timeout)) break;\n        }\n        cur_frame = n;\n      }\n      else {\n        while (cur_frame < n) {\n          if (!get_sample.NextSample(timeout)) break;\n          cur_frame++;\n        }\n      }\n    }\n    else {\n      HRESULT hr;\n      if (seekmode == 0) {\n        // Seekzero=true and stepping back\n        hr = get_sample.SeekTo(0);\n        if (hr == S_OK) hr = S_FALSE;\n      }\n      else {\n        // Seek=true and stepping back or a long hop forwards\n        hr = get_sample.SeekTo(sample_time);\n      }\n\n      if (hr == S_OK) {\n        // seek ok!\n        cur_frame = n;\n      }\n      else if (hr == S_FALSE) {\n        // seekzero or seek failed!\n        if (!get_sample.WaitForStart(timeout)) {\n          // We have stopped and started the graph. Many unseekable streams\n          // reset to 0, others don't move. Try to get our position\n          cur_frame = int(get_sample.GetSampleStartTime() / get_sample.avg_time_per_frame);\n          if (frame_units) {\n            while (cur_frame < n) {\n              if (!get_sample.NextSample(timeout)) break;\n              cur_frame++;\n            }\n          }\n          else {\n            while (get_sample.GetSampleEndTime() <= sample_time) {\n              if(!get_sample.NextSample(timeout)) break;\n            }\n            cur_frame = n;\n          }\n        }\n      }\n      else {\n        env->ThrowError(\"DirectShowSource : The video Graph failed to restart after seeking. Status = 0x%x\", hr);\n      }\n    }\n    dssRPT2(dssCALL, \"GetFrame: Frame time span x100ns %I64d to %I64d\\n\",\n            get_sample.GetSampleStartTime(), get_sample.GetSampleEndTime());\n\n    return get_sample.GetCurrentFrame(env, n, TrapTimeouts, timeout);\n  }\n\n#else\n\n  PVideoFrame __stdcall DirectShowSource::GetFrame(int n, IScriptEnvironment* env) {\n    DWORD timeout = WaitTimeout;\n\n    n = max(min(n, vi.num_frames-1), 0);\n    // Ask for the frame whose start_time == T\n    const __int64 sample_time = Int32x32To64(n, get_sample.avg_time_per_frame);\n\n    dssRPT2(dssCALL, \"GetFrame: Frame %d start time %I64dx100ns.\\n\", n, sample_time);\n\n    HRESULT hr = S_OK;\n    switch (seekmode) {\n      case 0: // Seekzero\n        if (n < cur_frame) {\n          hr = get_sample.SeekTo(0, gb);  // stepping back\n          cur_frame = 0;\n        }\n        break;\n\n      case 1: // Seek\n        if (n < cur_frame) {\n          hr = get_sample.SeekTo(sample_time, gb);\n          cur_frame = n;\n        }\n        else if (convert_fps) {\n          if (sample_time > get_sample.GetSampleStartTime() + get_sample.avg_time_per_frame*30) {\n            hr = get_sample.SeekTo(sample_time, gb);\n            cur_frame = n;\n          }\n        }\n        else {\n          if (n > cur_frame+30) {\n            hr = get_sample.SeekTo(sample_time, gb);\n            cur_frame = n;\n          }\n        }\n        break;\n\n      case 2: // No_Search\n        break;\n\n      default:\n        env->ThrowError(\"DirectShowSource : Invalid seek mode %d\", seekmode);\n    }\n    if (FAILED(hr))\n      env->ThrowError(\"DirectShowSource : The video Graph failed to restart after seeking. Status = 0x%x\", hr);\n\n    if (convert_fps) {\n      while (get_sample.GetSampleStartTime() <= (sample_time+5000) || !currentFrame) { // Allow 0.5 millisecond roundup\n        sampleStartTime = get_sample.GetSampleStartTime();\n        cur_frame = int(sampleStartTime / get_sample.avg_time_per_frame); // Floor()\n        currentFrame = get_sample.GetCurrentFrame(env, n, TrapTimeouts, timeout);\n        if(!get_sample.NextSample(timeout)) break;\n      }\n      dssRPT3(dssCALL, \"GetFrame: VFR Frame %d time span x100ns %I64d to %I64d\\n\", n,\n              sampleStartTime, get_sample.GetSampleStartTime());\n    }\n    else {\n      while (cur_frame < n) {\n        if (!get_sample.NextSample(timeout)) break;\n        cur_frame++;\n      }\n      currentFrame = get_sample.GetCurrentFrame(env, n, TrapTimeouts, timeout);\n      dssRPT3(dssCALL, \"GetFrame: CFR Frame %d time span x100ns %I64d to %I64d\\n\", n,\n              get_sample.GetSampleStartTime(), get_sample.GetSampleEndTime());\n    }\n\n    return currentFrame;\n  }\n#endif\n\n\n  void __stdcall DirectShowSource::GetAudio(void* buf, __int64 start, __int64 count, IScriptEnvironment* env) {\n    DWORD timeout = WaitTimeout;\n    int bytes_filled = 0;\n\n    if (next_sample != start) {  // We have been searching!  Skip until sync!\n\n      dssRPT2(dssCALL, \"GetAudio: Seeking to %I64d previous was %I64d samples.\\n\", start, next_sample);\n\n      // Backup to begining of current buffer\n      next_sample -= vi.AudioSamplesFromBytes(audio_bytes_read);\n      audio_bytes_read = 0;\n\n      const __int64 avail_samples = vi.AudioSamplesFromBytes(get_sample.av_sample_bytes);\n      if ( ((seekmode != 2) && (start < next_sample))\n        // Seek=true and Seekzero=true and stepping back\n        || ((seekmode == 1) && (start >= next_sample+avail_samples+50000))) {\n        // Seek=true and a long hop forwards\n        const __int64 seekTo = (seekmode == 0) ? 0 : (start*10000000 + (vi.audio_samples_per_second>>1)) / vi.audio_samples_per_second; // Round()\n        dssRPT1(dssCALL, \"GetAudio: SeekTo %I64dx100ns media time.\\n\", seekTo);\n\n        HRESULT hr = get_sample.SeekTo(seekTo, gb);\n\n        if (seekmode == 0 && hr == S_OK) hr = S_FALSE;\n\n        if (hr == S_OK) {\n          // Seek succeeded!\n          next_sample = start;\n          audio_bytes_read = 0;\n        }\n        else if (hr == S_FALSE) {\n          // seek failed!\n          if (!get_sample.WaitForStart(timeout)) {\n            // We have stopped and started the graph many unseekable streams\n            // reset to 0, others don't move. Try to get our position\n            next_sample = (get_sample.GetSampleStartTime() * vi.audio_samples_per_second + 5000000) / 10000000; // Round()\n          }\n        }\n        else {\n          env->ThrowError(\"DirectShowSource : The audio Graph failed to restart after seeking. Status = 0x%x\", hr);\n        }\n      }\n\n      if (start < next_sample) { // We are behind sync - pad with 0\n        const int fill_nsamples  = (int)min(next_sample - start, count);\n        dssRPT1(dssCALL, \"GetAudio: Padding %d samples.\\n\", fill_nsamples);\n\n        // We cannot seek.\n        if (vi.sample_type == SAMPLE_FLOAT) {\n          float* samps = (float*)buf;\n          for (int i = 0; i < fill_nsamples; i++)\n            samps[i] = 0.0f;\n        }\n        else {\n          memset(buf,0, (unsigned int)vi.BytesFromAudioSamples(fill_nsamples));\n        }\n\n        if (fill_nsamples == count)  // Buffer is filled - return\n          return;\n        start += fill_nsamples;\n        count -= fill_nsamples;\n        bytes_filled += (int)vi.BytesFromAudioSamples(fill_nsamples);\n      }\n\n      if (start > next_sample) {  // Skip forward (decode)\n        // Should we search?\n        int skip_left = (int)vi.BytesFromAudioSamples(start - next_sample);\n        dssRPT1(dssCALL, \"GetAudio: Skipping %d bytes.\\n\", skip_left);\n\n        if (get_sample.WaitForStart(timeout))\n          if (TrapTimeouts)\n            env->ThrowError(\"DirectShowSource : Timeout waiting for audio.\");\n\n        while (skip_left > 0) {\n          if (get_sample.av_sample_bytes-audio_bytes_read >= skip_left) {\n            audio_bytes_read += skip_left;\n            break;\n          }\n          skip_left -= get_sample.av_sample_bytes-audio_bytes_read;\n          audio_bytes_read = get_sample.av_sample_bytes;\n\n          if (get_sample.NextSample(timeout))\n            audio_bytes_read = 0;\n          else\n             break;  // EndOfStream? Timeout?\n        } // end while\n        next_sample = start;\n      }\n    }\n\n    BYTE* samples = (BYTE*)buf;\n    int bytes_left = (int)vi.BytesFromAudioSamples(count);\n    dssRPT2(dssCALL, \"GetAudio: Reading %I64d samples, %d bytes.\\n\", count, bytes_left);\n\n    if (get_sample.WaitForStart(timeout))\n      if (TrapTimeouts)\n        env->ThrowError(\"DirectShowSource : Timeout waiting for audio.\");\n    while (bytes_left) {\n      // Can we read from the Directshow filters buffer?\n      if (get_sample.av_sample_bytes - audio_bytes_read > 0) { // Copy as many bytes as needed.\n\n        // This many bytes can be safely read.\n        const int available_bytes = min(bytes_left, get_sample.av_sample_bytes - audio_bytes_read);\n        dssRPT2(dssCALL, \"GetAudio: Memcpy %d offset, %d bytes.\\n\", bytes_filled, available_bytes);\n\n        memcpy(&samples[bytes_filled], &get_sample.av_buffer[audio_bytes_read], available_bytes);\n\n        bytes_left -= available_bytes;\n        bytes_filled += available_bytes;\n        audio_bytes_read += available_bytes;\n\n      }\n      else { // Read more samples\n        if (get_sample.NextSample(timeout)) {\n          audio_bytes_read = 0;\n        }\n        else { // Pad with 0\n          if (TrapTimeouts)\n            if (get_sample.WaitForStart(timeout))\n              env->ThrowError(\"DirectShowSource : Timeout waiting for audio.\");\n\n          dssRPT2(dssCALL, \"GetAudio: Memset %d offset, %d bytes.\\n\", bytes_filled, bytes_left);\n          if (vi.sample_type == SAMPLE_FLOAT) {\n            float* samps = (float*)(&samples[bytes_filled]); // Aligned just to be sure\n            const int samples_left = (bytes_left+sizeof(float)-1)/sizeof(float);\n            for (int i = 0; i < samples_left; i++)\n              samps[i] = 0.0f;\n          } else {\n            memset(&samples[bytes_filled],0,bytes_left);\n          }\n          bytes_left = 0;\n          break;\n        }\n      }\n    }\n    next_sample +=count;\n  }\n\n\n\nvoid DirectShowSource::CheckHresult(IScriptEnvironment* env, HRESULT hr, const char* msg, const char* msg2) {\n  if (SUCCEEDED(hr)) return;\n//  char buf[1024] = {0};\n//  if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, hr, 0, buf, 1024, NULL))\n  char buf[MAX_ERROR_TEXT_LEN+1] = {0};\n  if (!AMGetErrorText(hr, buf, MAX_ERROR_TEXT_LEN))\n    wsprintf(buf, \"error code 0x%x\", hr);\n  env->ThrowError(\"DirectShowSource: %s%s:\\n%s\", msg, msg2, buf);\n}\n\nint __stdcall DirectShowSource::SetCacheHints(int cachehints,int frame_range)\n{\n  switch(cachehints)\n  {\n  case CACHE_GET_MTMODE:\n    return MT_SERIALIZED;\n  default:\n    return 0;\n  }\n}\n\nHRESULT DirectShowSource::LoadGraphFile(IGraphBuilder *pGraph, const WCHAR* wszName)\n{\n    IStorage *pStorage = 0;\n    if (S_OK != StgIsStorageFile(wszName)) return E_FAIL;\n\n    HRESULT hr = StgOpenStorage(wszName, 0,\n        STGM_TRANSACTED | STGM_READ | STGM_SHARE_DENY_WRITE,\n        0, 0, &pStorage);\n    if (FAILED(hr)) return hr;\n\n    IPersistStream *pPersistStream = 0;\n    hr = pGraph->QueryInterface(IID_IPersistStream,\n             reinterpret_cast<void**>(&pPersistStream));\n    if (SUCCEEDED(hr))\n    {\n        IStream *pStream = 0;\n        hr = pStorage->OpenStream(L\"ActiveMovieGraph\", 0,\n            STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream);\n        if(SUCCEEDED(hr))\n        {\n            hr = pPersistStream->Load(pStream);\n            pStream->Release();\n        }\n        pPersistStream->Release();\n    }\n    pStorage->Release();\n    return hr;\n}\n\n\n/* As this is currently implemented we use two separate instance of DSS, one for video and\n * one for audio. This means we create two (2) filter graphs. An alternate implementation\n * would be to have a video GetSample::IPin object and a separate audio GetSample::IPin object\n * in the one filter graph. Possible problems with this idea could be related to independant\n * positioning of the Video and Audio streams within the one filter graph. */\n\n\nAVSValue __cdecl Create_DirectShowSource(AVSValue args, void*, IScriptEnvironment* env) {\n\n  const char* filename = args[0].AsString();\n  const int _avg_time_per_frame = args[1].Defined() ? int(10000000 / args[1].AsFloat() + 0.5) : 0;\n\n  const bool audio    = args[3].AsBool(true);\n  const bool video    = args[4].AsBool(true);\n\n  if (!(audio || video))\n    env->ThrowError(\"DirectShowSource: Both video and audio are disabled!\");\n\n  const bool seek     = args[2].AsBool(true);\n  const bool seekzero = args[6].AsBool(false);\n  const int  seekmode = seek ? (seekzero ? 0 : 1) : 2; // 0=seek_zero, 1=seek, 2=no_search\n\n  const int _timeout  = args[7].AsInt(60000); // Default timeout = 1 minute\n\n  unsigned _media = GetSample::mediaNONE;\n  if (args[8].Defined()) {\n    bool mediaPad = false;\n    const char* pixel_type = args[8].AsString();\n    if (pixel_type[0] == '+') {\n      pixel_type += 1;\n      mediaPad = true;\n    }\n    if      (!lstrcmpi(pixel_type, \"YUY2\"))  { _media = GetSample::mediaYUY2; }\n    else if (!lstrcmpi(pixel_type, \"YV12\"))  { _media = GetSample::mediaYV12; }\n    else if (!lstrcmpi(pixel_type, \"I420\"))  { _media = GetSample::mediaI420; }\n//  else if (!lstrcmpi(pixel_type, \"YUV9\"))  { _media = GetSample::mediaYUV9; }\n    else if (!lstrcmpi(pixel_type, \"Y41P\"))  { _media = GetSample::mediaY41P; }\n    else if (!lstrcmpi(pixel_type, \"Y411\"))  { _media = GetSample::mediaY411; }\n    else if (!lstrcmpi(pixel_type, \"AYUV\"))  { _media = GetSample::mediaAYUV; }\n    else if (!lstrcmpi(pixel_type, \"RGB24\")) { _media = GetSample::mediaRGB24; }\n    else if (!lstrcmpi(pixel_type, \"RGB32\")) { _media = GetSample::mediaRGB32 | GetSample::mediaARGB; }\n    else if (!lstrcmpi(pixel_type, \"RGB48\")) { _media = GetSample::mediaRGB48; }\n    else if (!lstrcmpi(pixel_type, \"RGB64\")) { _media = GetSample::mediaRGB64; }\n    else if (!lstrcmpi(pixel_type, \"ARGB\"))  { _media = GetSample::mediaARGB; }\n    else if (!lstrcmpi(pixel_type, \"RGB\"))   { _media = GetSample::mediaRGB; }\n    else if (!lstrcmpi(pixel_type, \"YUV\"))   { _media = GetSample::mediaYUV; }\n    else if (!lstrcmpi(pixel_type, \"AUTO\"))  { _media = GetSample::mediaAUTO; }\n    else if (!lstrcmpi(pixel_type, \"NV12\"))  { _media = GetSample::mediaNV12; }\n    else if (!lstrcmpi(pixel_type, \"YV24\"))  { _media = GetSample::mediaYV24; }\n    else if (!lstrcmpi(pixel_type, \"YV16\"))  { _media = GetSample::mediaYV16; }\n    else if (!lstrcmpi(pixel_type, \"YUVEX\")) { _media = GetSample::mediaYUVex; }\n    else if (!lstrcmpi(pixel_type, \"FULL\"))  { _media = GetSample::mediaFULL; }\n    else {\n      env->ThrowError(\"DirectShowSource: pixel_type must be \\\"RGB24\\\", \\\"RGB32\\\", \\\"ARGB\\\", \\\"RGB48\\\", \\\"RGB64\\\", \"\n                      \"\\\"YUY2\\\", \\\"YV12\\\", \\\"I420\\\", \\\"YV16\\\", \\\"YV24\\\", \\\"AYUV\\\", \\\"Y41P\\\", \"\n                      \"\\\"Y411\\\", \\\"NV12\\\", \\\"RGB\\\", \\\"YUV\\\" , \\\"YUVex\\\", \\\"AUTO\\\"  or \\\"FULL\\\"\");\n    }\n    if (mediaPad) _media |= GetSample::mediaPAD;\n  }\n  const int _frames = args[9].AsInt(0);\n\n  LOG* log = NULL;\n\n  if (args[10].Defined()) {\n    log = new LOG(args[10].AsString(), args[11].AsInt(dssNEG | dssSAMP | dssERROR), env);\n    if (!log) env->ThrowError(\"DirectShowSource: No memory for Log.\");\n  }\n\n  const bool utf8 = args[12].AsBool(false);\n\n  if (!(audio && video)) { // Hey - simple!!\n    if (audio) {\n      return new DirectShowSource(filename, _avg_time_per_frame, seekmode, true , false,\n                                  args[5].AsBool(false), _media, _timeout, _frames, log, utf8, env);\n    } else {\n      return new DirectShowSource(filename, _avg_time_per_frame, seekmode, false , true,\n                                  args[5].AsBool(false), _media, _timeout, _frames, log, utf8, env);\n    }\n  }\n\n  PClip DS_audio;\n  PClip DS_video;\n\n  bool audio_success = true;\n  bool video_success = true;\n\n  if (log) log->AddRef();\n  try {\n    int fnlen = lstrlen(filename);\n    if ((fnlen >= 4) && !lstrcmpi(filename+fnlen-4,\".grf\")) {\n      env->ThrowError(\"DirectShowSource: Only 1 stream supported for .GRF files, one of Audio or Video must be disabled.\");\n    }\n\n    const char *a_e_msg = \"\";\n    const char *v_e_msg = \"\";\n\n    try {\n      DS_audio = new DirectShowSource(filename, _avg_time_per_frame, seekmode, true , false,\n                                      args[5].AsBool(false), _media, _timeout, _frames, log, utf8, env);\n    } catch (const AvisynthError &e) {\n      a_e_msg = e.msg;\n      audio_success = false;\n    }\n\n    try {\n      DS_video = new DirectShowSource(filename, _avg_time_per_frame, seekmode, false, true,\n                                      args[5].AsBool(false), _media, _timeout, _frames, log, utf8, env);\n    } catch (const AvisynthError &e) {\n      if (!lstrcmpi(e.msg, \"DirectShowSource: I can't determine the frame rate\\n\"\n                           \"of the video, you must use the \\\"fps\\\" parameter.\") ) { // Note must match message above\n            env->ThrowError(e.msg);\n        }\n      v_e_msg = e.msg;\n      video_success = false;\n    }\n\n\n    if (!(audio_success || video_success)) {\n      env->ThrowError(\"DirectShowSource: Could not open as video or audio.\\r\\n\\r\\n\"\n                                        \"Video returned:  \\\"%s\\\"\\r\\n\\r\\n\"\n                                        \"Audio returned:  \\\"%s\\\"\\r\\n\", v_e_msg, a_e_msg);\n    }\n  }\n  catch (...) {\n    if (log) log->DelRef(\"Create_DirectShowSource Cleanup Handler\");\n    throw;\n  }\n  if (log) log->DelRef(\"Create_DirectShowSource\");\n\n  if (!audio_success)\n    return DS_video;\n\n  if (!video_success)\n    return DS_audio;\n\n  AVSValue inv_args[2] = { DS_video, DS_audio };\n  PClip ds_all =  env->Invoke(\"AudioDub\",AVSValue(inv_args,2)).AsClip();\n\n  return ds_all;\n}\n\nconst AVS_Linkage *AVS_linkage = 0;\n\nextern \"C\" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors)\n{\n  AVS_linkage = vectors;\n\n  env->AddFunction(\"DirectShowSource\",\n// args 0  1     2       3       4         5           6\n       \"s[fps]f[seek]b[audio]b[video]b[convertfps]b[seekzero]b\"\n//          7            8            9        10        11       12\n       \"[timeout]i[pixel_type]s[framecount]i[logfile]s[logmask]i[utf8]b\",\n       Create_DirectShowSource, 0);\n\n  return \"DirectShowSource\";\n}\n"
  },
  {
    "path": "plugins/DirectShowSource/directshow_source.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n#include <avisynth.h>\n#include <avs/win.h>\n\n#include <streams.h>\n#include <stdio.h>\n\n\n/********************************************************************\n# Build Hints for DirectShow SDK\n\n# Hints for Avisynth+, Visual Studio 2019\n\n- download and install 7.1 SDK\n  Microsoft Windows SDK for Windows 7 and .NET Framework 4\n    https://www.microsoft.com/en-us/download/details.aspx?id=8279\n\n  In case of problems:\n  https://social.msdn.microsoft.com/Forums/vstudio/en-US/1de7c9b4-1feb-4c98-b426-f7f02cbafa99/windows-sdk-71-on-windows-10\n  Uninstall VC2010 redist, download offline ISO image installer, install\n\n- [Building strmbase.lib]\n  - Open solution in\n      c:\\Program Files\\Microsoft SDKs\\Windows\\v7.1A\\Samples\\multimedia\\directshow\\baseclasses\\\n    (or replace v7.1A with appropriate v7 SDK folder)\n    Project is of old format, will be converted.\n  - Compile for targets Release_MBCS x86 and x64.\n    Find compiled library strmbase.lib in\n      c:\\Program Files\\Microsoft SDKs\\Windows\\v7.1A\\Samples\\multimedia\\directshow\\baseclasses\\Release_MBCS\\;\n    and\n      c:\\Program Files\\Microsoft SDKs\\Windows\\v7.1A\\Samples\\multimedia\\directshow\\baseclasses\\x64\\Release_MBCS\\;\n- [Building DirectShowSource.dll]\n  - Open PluginDirectShowSource project in the AviSynth plus solution\n  - Note: Usually Avisynth+ CMake is configuring the settings below properly.\n  - Edit Project Properties|VC++ Directories|Include Paths\n    Add to the beginning\n    c:\\Program Files\\Microsoft SDKs\\Windows\\v7.1A\\Samples\\multimedia\\directshow\\baseclasses\\;\n    c:\\Program Files\\Microsoft SDKs\\Windows\\v7.1A\\Include\\; or put behind $(VC_IncludePath) if windows.h not found\n  - Edit Project Properties|VC++ Directories|Library Directories\n    For x86 target add\n      c:\\Program Files\\Microsoft SDKs\\Windows\\v7.1A\\Samples\\multimedia\\directshow\\baseclasses\\Release_MBCS\\;\n    For x64 target add\n      c:\\Program Files\\Microsoft SDKs\\Windows\\v7.1A\\Samples\\multimedia\\directshow\\baseclasses\\x64\\Release_MBCS\\;\n    For XP target add (to find winmm.lib)\n      c:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v7.1A\\Lib\\; (for 32 bit build)\n      c:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v7.1A\\Lib\\x64\\; (for 64 bit build)\n  - Edit Project Properties|Linker|Input|Additional Dependencies\n    Add strmbase.lib to the list\n  - For XP compatibility\n    - choose Platform Toolset v141_xp\n    - Edit Project Properties|C/C++|Command Line\n      Add\n      /Zc:threadSafeInit-\n  - Build\n\n# Hints from 2.6.1alpha1:\n\n# Patch ($Platform SDK)\\Samples\\Multimedia\\DirectShow\\BaseClasses\\streams.h\n# remove ATL reference\n\n#define NO_SHLWAPI_STRFCNS\n// #include <atlbase.h>    <<---- Line 179\n#include <strsafe.h>\n\n# Start a Visual Studio Command Prompt\nTools>Visual Studio 200x Command Prompt\n\n# Add DirectX SDK to front of INCLUDE path\nSet INCLUDE=C:\\Program Files\\Microsoft DirectX SDK (August 2009)\\Include;%INCLUDE%\n\nSet INCLUDE=C:\\Program Files (x86)\\Microsoft DirectX SDK (August 2009)\\Include;%INCLUDE%\n\n# Cd to the Platform SDK directory.\ncd \"C:\\Program Files\\Microsoft Platform SDK for Windows Server 2003 R2\"\n\n# Define SDK environment\nSetEnv /XP32 /RETAIL\n\n# Cd to BaseClasses directory\ncd Samples\\Multimedia\\DirectShow\\BaseClasses\n\n# Make strmbase.lib (Probably won't have write access, so take a copy)\nnmake\n\n# Add DirectShow and DirectX to C++ command line INCLUDE path\n/I \"C:\\Program Files\\Microsoft Platform SDK for Windows Server 2003 R2\\Samples\\Multimedia\\DirectShow\\BaseClasses\"\n/I \"C:\\Program Files\\Microsoft DirectX SDK (August 2009)\\Include\"\n\n/I \"C:\\Program Files (x86)\\Microsoft DirectX SDK (August 2009)\\Include\"\n\n# Add DirectShow and DirectX to link command line LIB path\n/LIBPATH:\"C:\\Program Files\\Microsoft Platform SDK for Windows Server 2003 R2\\Samples\\Multimedia\\DirectShow\\BaseClasses\\XP32_RETAIL\"\n/LIBPATH:\"C:\\Program Files\\Microsoft DirectX SDK (August 2009)\\Lib\\x86\"\n\n/LIBPATH:\"C:\\Program Files (x86)\\Microsoft DirectX SDK (August 2009)\\Lib\\x86\"\n********************************************************************/\n\n#define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; }\n\n\n\n#include <evcode.h>\n#include <control.h>\n#include <strmif.h>\n#include <amvideo.h>\n#include <dvdmedia.h>\n#include <vfwmsgs.h>\n#include <initguid.h>\n#include <uuids.h>\n#include <errors.h>\n\n\n// Ahhgg we don't want all of vfw.h just for this\n#define WAVE_FORMAT_IEEE_FLOAT 0x0003\n\n\nclass GetSample;\n\n\n// Log utility class\nclass LOG {\n  int count;\n\npublic:\n  FILE* file;\n  const int mask;\n\n  LOG(const char* fn, int _mask, IScriptEnvironment* env);\n  ~LOG();\n  void AddRef() { count += 1; };\n  void DelRef(const char* s);\n};\n\n\nclass GetSampleEnumMediaTypes : public IEnumMediaTypes {\n  long refcnt;\n  GetSample* const parent;\n  unsigned pos, count;\n\n  LOG* log;\n\npublic:\n  GetSampleEnumMediaTypes(GetSample* _parent, unsigned _count, unsigned _pos=0);\n  ~GetSampleEnumMediaTypes();\n\n// IUnknown::\n\n  ULONG __stdcall AddRef() { InterlockedIncrement(&refcnt); return refcnt; }\n  ULONG __stdcall Release() {\n    if (!InterlockedDecrement(&refcnt)) {\n      delete this;\n      return 0;\n    } else {\n      return refcnt;\n    }\n  }\n  HRESULT __stdcall QueryInterface(REFIID iid, void** ppv) {\n    if      (iid == IID_IUnknown)        *ppv = static_cast<IUnknown*>(this);\n    else if (iid == IID_IEnumMediaTypes) *ppv = static_cast<IEnumMediaTypes*>(this);\n    else {\n      *ppv = 0;\n      return E_NOINTERFACE;\n    }\n    AddRef();\n    return S_OK;\n  }\n\n// IEnumMediaTypes::\n\n  HRESULT __stdcall Next(ULONG cMediaTypes, AM_MEDIA_TYPE** ppMediaTypes, ULONG* pcFetched);\n  HRESULT __stdcall Skip(ULONG cMediaTypes);\n  HRESULT __stdcall Reset();\n  HRESULT __stdcall Clone(IEnumMediaTypes** ppEnum);\n};\n\n\nclass GetSampleEnumPins : public IEnumPins {\n  long refcnt;\n  GetSample* const parent;\n  int pos;\n\n  LOG* log;\n\npublic:\n  GetSampleEnumPins(GetSample* _parent, int _pos=0);\n  ~GetSampleEnumPins();\n\n// IUnknown::\n\n  ULONG __stdcall AddRef() { InterlockedIncrement(&refcnt); return refcnt; }\n  ULONG __stdcall Release() {\n    if (!InterlockedDecrement(&refcnt)) {\n      delete this;\n      return 0;\n    } else {\n      return refcnt;\n    }\n  }\n  HRESULT __stdcall QueryInterface(REFIID iid, void** ppv) {\n    if      (iid == IID_IUnknown)  *ppv = static_cast<IUnknown*>(this);\n    else if (iid == IID_IEnumPins) *ppv = static_cast<IEnumPins*>(this);\n    else {\n      *ppv = 0;\n      return E_NOINTERFACE;\n    }\n    AddRef();\n    return S_OK;\n  }\n\n// IEnumPins::\n\n  HRESULT __stdcall Next(ULONG cPins, IPin** ppPins, ULONG* pcFetched);\n  HRESULT __stdcall Skip(ULONG cPins) { return E_NOTIMPL; }\n  HRESULT __stdcall Reset() { pos=0; return S_OK; }\n  HRESULT __stdcall Clone(IEnumPins** ppEnum) { return E_NOTIMPL; }\n};\n\n\nclass GetSample : public IBaseFilter, public IPin, public IMemInputPin {\n\n  long refcnt;\n  IMemAllocator* Allocator;  // refcounted\n  IPin* source_pin;  // not refcounted\n  IFilterGraph* filter_graph;  // not refcounted\n  IReferenceClock* pclock;  // not refcounted\n  FILTER_STATE state;\n  bool end_of_stream, flushing, seeking;\n  IUnknown *m_pPos;  // Pointer to the CPosPassThru object.\n  VideoInfo vi;\n  bool m_bInvertFrames; // Data in av_buffer is flipped vertically compared to the expected orientation of vi.pixel_type\n  bool lockvi; // Format negotiation is allowed until DSS is fully created\n\n  HANDLE evtDoneWithSample, evtNewSampleReady;\n\n  const bool load_audio;\n  const bool load_video;\n\n  bool graphTimeout;\n\n  const char * const streamName;\n\n  AM_MEDIA_TYPE *am_media_type;\n\n  unsigned media, no_my_media_types;\n  AM_MEDIA_TYPE *my_media_types[18]; // 2.6\n\n  PVideoFrame pvf;\n\npublic:\n  enum {\n    mediaNONE   = 0,\n    mediaYUV9   = 1<<0, // not implemented\n    mediaYV12   = 1<<1,\n    mediaYUY2   = 1<<2,\n    mediaARGB   = 1<<3,\n    mediaRGB32  = 1<<4,\n    mediaRGB24  = 1<<5,\n    mediaAYUV   = 1<<6, // 2.6\n    mediaY411   = 1<<7, // 2.6\n    mediaY41P   = 1<<8, // 2.6\n    mediaYV16   = 1<<9, // 2.6\n    mediaYV24   = 1<<10,// 2.6\n    mediaI420   = 1<<11,// 2.6\n    mediaNV12   = 1<<12,// 2.6\n    mediaRGB64  = 1<<13,\n    mediaRGB48  = 1<<14,\n    mediaRGB    = mediaARGB | mediaRGB32 | mediaRGB24 | mediaRGB64 | mediaRGB48,\n    mediaYUV    = mediaYUV9 | mediaYV12 | mediaYUY2 | mediaAYUV | mediaY411 | mediaY41P,\n    mediaYUVex  = mediaYUV  | mediaYV16 | mediaYV24 | mediaI420 | mediaNV12,\n    mediaAUTO   = mediaRGB | mediaYUV,\n    mediaFULL   = mediaRGB | mediaYUVex,\n    mediaPAD    = 1<<31,\n  };\n\n  __int64 segment_start_time, segment_stop_time, sample_start_time, sample_end_time;\n\n  int avg_time_per_frame;\n  int time_of_last_frame;\n\n  int av_sample_bytes;\n  BYTE* av_buffer;         // Killed on StopGraph\n\n  LOG* log;\n\n  GetSample(bool _load_audio, bool _load_video, unsigned _media, LOG* _log);\n  ~GetSample();\n\n  // These are utility functions for use by DirectShowSource.  Note that\n  // the other thread (the one used by the DirectShow filter graph side of\n  // things) is always blocked when any of these functions is called, and\n  // is always blocked when they return\n\n  bool IsConnected() { return !!source_pin; }\n  bool IsEndOfStream() { return end_of_stream; }\n  const VideoInfo& GetVideoInfo() { lockvi = true; return vi; }\n  PVideoFrame GetCurrentFrame(IScriptEnvironment* env, int n, bool _TrapTimeouts, DWORD &timeout);\n  __int64 GetSampleStartTime() { return segment_start_time + sample_start_time; }\n  __int64 GetSampleEndTime() { return segment_start_time + sample_end_time; }\n  bool WaitForStart(DWORD &timeout);\n  const AM_MEDIA_TYPE *GetMediaType(unsigned pos);\n\n  // These all cause the other thread (the one used by the DirectShow filter\n  // graph side of things) to do it's thing and cycle. Hopefully it is blocked\n  // again as they exit, a timeouts from StartGraph violates this.\n\n  HRESULT StartGraph(IGraphBuilder* gb);\n  void StopGraph(IGraphBuilder* gb);\n  void PauseGraph(IGraphBuilder* gb);\n  HRESULT SeekTo(__int64 pos, IGraphBuilder* gb);\n  bool NextSample(DWORD &timeout);\n\n// IUnknown::\n\n  ULONG __stdcall AddRef();\n  ULONG __stdcall Release();\n  HRESULT __stdcall QueryInterface(REFIID iid, void** ppv);\n\n// IPersist::\n\n  HRESULT __stdcall GetClassID(CLSID* pClassID);\n\n// IMediaFilter::\n\n  HRESULT __stdcall Stop();\n  HRESULT __stdcall Pause();\n  HRESULT __stdcall Run(REFERENCE_TIME tStart);\n  HRESULT __stdcall GetState(DWORD dwMilliSecsTimeout, FILTER_STATE* State);\n  HRESULT __stdcall SetSyncSource(IReferenceClock* pClock);\n  HRESULT __stdcall GetSyncSource(IReferenceClock** ppClock);\n\n// IBaseFilter::\n\n  HRESULT __stdcall EnumPins(IEnumPins** ppEnum);\n  HRESULT __stdcall FindPin(LPCWSTR Id, IPin** ppPin);\n  HRESULT __stdcall QueryFilterInfo(FILTER_INFO* pInfo);\n  HRESULT __stdcall JoinFilterGraph(IFilterGraph* pGraph, LPCWSTR pName);\n  HRESULT __stdcall QueryVendorInfo(LPWSTR* pVendorInfo);\n\n// IPin::\n\n  HRESULT __stdcall Connect(IPin* pReceivePin, const AM_MEDIA_TYPE* pmt);\n  HRESULT __stdcall ReceiveConnection(IPin* pConnector, const AM_MEDIA_TYPE* pmt);\n  HRESULT __stdcall Disconnect();\n  HRESULT __stdcall ConnectedTo(IPin** ppPin);\n  HRESULT __stdcall ConnectionMediaType(AM_MEDIA_TYPE* pmt);\n  HRESULT __stdcall QueryPinInfo(PIN_INFO* pInfo);\n  HRESULT __stdcall QueryDirection(PIN_DIRECTION* pPinDir);\n  HRESULT __stdcall QueryId(LPWSTR* Id);\n  HRESULT __stdcall QueryAccept(const AM_MEDIA_TYPE* pmt);\n  HRESULT __stdcall EnumMediaTypes(IEnumMediaTypes** ppEnum);\n  HRESULT __stdcall QueryInternalConnections(IPin** apPin, ULONG* nPin);\n  HRESULT __stdcall EndOfStream();\n  HRESULT __stdcall BeginFlush();\n  HRESULT __stdcall EndFlush();\n  HRESULT __stdcall NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);\n\n// IMemInputPin::\n\n  HRESULT __stdcall GetAllocator(IMemAllocator** ppAllocator);\n  HRESULT __stdcall NotifyAllocator(IMemAllocator* pAllocator, BOOL bReadOnly);\n  HRESULT __stdcall GetAllocatorRequirements(ALLOCATOR_PROPERTIES* pProps);\n  HRESULT __stdcall Receive(IMediaSample* pSamples);\n  HRESULT __stdcall ReceiveMultiple(IMediaSample** ppSamples, long nSamples, long* nSamplesProcessed);\n  HRESULT __stdcall ReceiveCanBlock();\n\nprivate:\n  /// \\param bInvertFrames[out] If true, the image is flipped vertically compared to the expected orientation of vi.pixel_type\n  HRESULT InternalQueryAccept(const AM_MEDIA_TYPE* pmt, VideoInfo &vi, bool &bInvertFrames);\n\n};\n\n\nstatic bool HasNoConnectedOutputPins(IBaseFilter* bf);\nstatic void DisconnectAllPinsAndRemoveFilter(IGraphBuilder* gb, IBaseFilter* bf);\nstatic void RemoveUselessFilters(IGraphBuilder* gb, IBaseFilter* not_this_one, IBaseFilter* nor_this_one);\nstatic HRESULT AttemptConnectFilters(IGraphBuilder* gb, IBaseFilter* connect_filter);\nstatic void SetMicrosoftDVtoFullResolution(IGraphBuilder* gb);\n\n\nclass DirectShowSource : public IClip {\n\n  __int64 sampleStartTime;\n  __int64 next_sample;\n\n  GetSample get_sample;\n  IGraphBuilder* gb;\n\n  PVideoFrame currentFrame;\n\n  VideoInfo vi;\n  bool frame_units;\n  bool convert_fps;\n  int cur_frame;\n  int seekmode;\n  int audio_bytes_read;\n\n  const bool TrapTimeouts;\n  const DWORD WaitTimeout;\n\n  LOG* log;\n\n  void CheckHresult(IScriptEnvironment* env, HRESULT hr, const char* msg, const char* msg2 = \"\");\n  HRESULT LoadGraphFile(IGraphBuilder *pGraph, const WCHAR* wszName);\n  void cleanUp();\n  void SetMicrosoftDVtoFullResolution(IGraphBuilder* gb);\n  void DisableDeinterlacing(IFilterGraph *pGraph);\n  void SetWMAudioDecoderDMOtoHiResOutput(IFilterGraph *pGraph);\n\npublic:\n\n  DirectShowSource(const char* filename, int _avg_time_per_frame, int _seekmode, bool _enable_audio, bool _enable_video,\n                   bool _convert_fps, unsigned _media, int _timeout, int _frames, LOG* _log, bool _utf8, IScriptEnvironment* env);\n  ~DirectShowSource();\n  const VideoInfo& __stdcall GetVideoInfo() { return vi; }\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n\n\n  bool __stdcall GetParity(int n) { return false; }\n  int __stdcall SetCacheHints(int cachehints,int frame_range);\n\n  void __stdcall GetAudio(void* buf, __int64 start, __int64 count, IScriptEnvironment* env);\n\n};\n\n\nAVSValue __cdecl Create_DirectShowSource(AVSValue args, void*, IScriptEnvironment* env);\n"
  },
  {
    "path": "plugins/ImageSeq/CMakeLists.txt",
    "content": "CMAKE_MINIMUM_REQUIRED( VERSION 3.6.2...3.11 )\n\nset(PluginName \"ImageSeq\")\nset(ProjectName \"Plugin${PluginName}\")\n\nif (NOT WIN32)\n  string(TOLOWER \"${PluginName}\" PluginName)\nendif()\n\n# Create library\nproject(${ProjectName} VERSION ${PROJECT_VERSION} LANGUAGES CXX)\nlist (APPEND SourceFiles\n    \"ImageSeq.cpp\"\n    \"ImageSeq.h\"\n    \"ImageReader.cpp\"\n    \"ImageWriter.cpp\"\n)\nadd_library(${ProjectName} SHARED ${SourceFiles})\nset_property(GLOBAL APPEND PROPERTY BUILT_TARGETS ${ProjectName})\nset_target_properties(${ProjectName} PROPERTIES \"OUTPUT_NAME\" ${PluginName})\nif (MINGW)\n  set_target_properties(${ProjectName} PROPERTIES PREFIX \"\")\n  set_target_properties(${ProjectName} PROPERTIES IMPORT_PREFIX \"\")\nendif()\n\n# If checked out with compat filesystem submodule, add that to system include directories\nget_filename_component(\n    GHS_FILESYSTEM_INCLUDE_DIR\n    ${CMAKE_CURRENT_SOURCE_DIR}/../../filesystem/include\n    ABSOLUTE\n)\nif (EXISTS ${GHS_FILESYSTEM_INCLUDE_DIR})\n    target_include_directories(${ProjectName} SYSTEM PRIVATE ${GHS_FILESYSTEM_INCLUDE_DIR})\nendif()\n\n# stdc++fs was mainlined into stdc++ in GCC 9, but GCC 8 can build it too\nif (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9)\n    set(FSLIB \"stdc++fs\")\nendif()\n\n  # linux: sudo apt-get install libdevil-dev\n  # fixme: put it to dependancy?\ninclude(FindDevIL) # official CMake module\n\n  # This module locates the developer's image library. http://openil.sourceforge.net/\n  # IL_LIBRARIES -   the name of the IL library. These include the full path to\n  #                  the core DevIL library. This one has to be linked into the\n  #                  application.\n  # IL_INCLUDE_DIR - where to find the il.h, ilu.h and ilut.h files.\n  # DevIL_FOUND    - this is set to TRUE if all the above variables were set.\n  #                  This will be set to false if ILU or ILUT are not found,\n  #                  even if they are not needed. In most systems, if one\n  #                  library is found all the others are as well. That's the\n  #                  way the DevIL developers release it.\nif(DevIL_FOUND)\n    message(\"Found DevIL library: ${IL_LIBRARIES}\") \n    target_link_libraries(${ProjectName} \"${IL_LIBRARIES}\" \"${FSLIB}\")\n    target_include_directories(${ProjectName} PRIVATE \"${IL_INCLUDE_DIR}\" ${AvsCore_SOURCE_DIR})\nelse()\n    target_link_libraries(${ProjectName} \"${FSLIB}\")\nendif()\n\nif (MSVC_IDE)\n  # Copy output to a common folder for easy deployment\n  add_custom_command(\n    TARGET ${ProjectName}\n    POST_BUILD\n    COMMAND xcopy /Y \\\"$(TargetPath)\\\" \\\"${CMAKE_BINARY_DIR}/Output/plugins\\\"\n  )\nendif()\n\nINSTALL(TARGETS \"${ProjectName}\"\n        DESTINATION \"${CORE_PLUGIN_INSTALL_PATH}/avisynth\")\n"
  },
  {
    "path": "plugins/ImageSeq/ImageReader.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n\n#include <avisynth.h>\n#include \"ImageSeq.h\"\n#include <algorithm>\n#include <sstream>\n#include <avs/config.h>\n#include <avs/filesystem.h>\n\n#define TEXT_COLOR 0xf0f080\n\nusing namespace std;\n\n\nImageReader::ImageReader(const char * _base_name, const int _start, const int _end,\n                         const double _fps, bool _use_DevIL, bool _info, const char * _pixel,\n                         bool _animation, IScriptEnvironment* env)\n : start(_start), use_DevIL(_use_DevIL), info(_info), animation(_animation), framecopies(0)\n{\n  if (DevIL_Version == 0) // Init the DevIL.dll version\n    DevIL_Version = ilGetInteger(IL_VERSION_NUM);\n\n#ifdef AVS_WINDOWS\n  // treat empty input as current directory\n  const char *base_name_good = (*_base_name == 0) ? \".\\\\\" : _base_name;\n  // Make sure we have an absolute path.\n  DWORD len = GetFullPathName(base_name_good, 0, base_name, NULL);\n  if (len == 0)\n    env->ThrowError(\"ImageReader: GetFullPathName failed. Error code: %d.\", GetLastError());\n  if (len > sizeof(base_name))\n    env->ThrowError(\"ImageReader: Path to %s too long.\", _base_name);\n  (void)GetFullPathName(base_name_good, len, base_name, NULL);\n  _snprintf(filename, (sizeof filename) - 1, base_name, start);\n\n#else\n  std::string base_name_good = (*_base_name == 0) ? \"./\" : _base_name;\n  auto path = fs::path(base_name_good);\n  std::error_code ec;\n  auto fullpath = fs::absolute(path, ec);\n  // to-do: check ec\n  //auto fullpath = fs::canonical(path, ec); // canonical removes e.g. dot. Path must exist.\n  std::string fullpaths = fullpath.string();\n  // cout << fullpaths.c_str() << \"\\n\"; // debug\n  if (fullpaths.size() > sizeof(base_name) - 1)\n    env->ThrowError(\"ImageReader: Path to %s too long.\", _base_name);\n  strcpy(base_name, fullpath.c_str());\n\n  snprintf(filename, (sizeof filename) - 1, base_name, start);\n\n#endif\n\n\n  memset(&vi, 0, sizeof(vi));\n\n  // Invariants\n  vi.num_frames = -start + _end + 1;  // make sure each frame can be requested\n  vi.audio_samples_per_second = 0;\n  double num = _fps;  // calculate fps as num/denom for vi\n  unsigned denom = 1;\n  while (num < 16777216 && denom < 16777216) { num*=2; denom*=2; } // float mantissa is only 24 bits\n  vi.SetFPS(unsigned(num+0.5), denom); // And normalize\n\n  if (use_DevIL == false)\n  {\n    fileHeader.bfType = 0;\n    // Try to parse as bmp/ebmp\n    ifstream file(filename, ios::binary);\n    file.read( reinterpret_cast<char *> (&fileHeader), sizeof(fileHeader) );\n    file.read( reinterpret_cast<char *> (&infoHeader), sizeof(infoHeader) );\n    file.close();\n\n    if ( fileHeader.bfType == ('M' << 8) + 'B')\n    {\n      if (infoHeader.biCompression == 0) {\n        vi.width = infoHeader.biWidth;\n        vi.height = infoHeader.biHeight;\n\n        if (infoHeader.biPlanes == 1) {\n          if (infoHeader.biBitCount == 32)\n            vi.pixel_type = VideoInfo::CS_BGR32;\n          else if (infoHeader.biBitCount == 24)\n            vi.pixel_type = VideoInfo::CS_BGR24;\n          else if (infoHeader.biBitCount == 16)\n            vi.pixel_type = VideoInfo::CS_YUY2;\n          else if (infoHeader.biBitCount == 8)\n            vi.pixel_type = VideoInfo::CS_Y8;\n          else if (DevIL_Version <= 166)\n            // DevIL 1.6.6 has a major coronary with palletted BMP files so don't fail thru to it\n            env->ThrowError(\"ImageReader: %d bit BMP is unsupported.\", infoHeader.biBitCount);\n          else\n            use_DevIL = true; // give it to DevIL (for example: biBitCount == 1 or 4 bit)\n        }\n        else if (infoHeader.biPlanes == 3) {\n          if (infoHeader.biBitCount == 24)\n            vi.pixel_type = VideoInfo::CS_YV24;\n          else if (infoHeader.biBitCount == 16)\n            vi.pixel_type = VideoInfo::CS_YV16;\n          else if (infoHeader.biBitCount == 12) {\n            if (!lstrcmpi(_pixel, \"rgb24\")) // Hack - the default text is \"rgb24\"\n              vi.pixel_type = VideoInfo::CS_YV12;\n            else if (!lstrcmpi(_pixel, \"yv12\"))\n              vi.pixel_type = VideoInfo::CS_YV12;\n            else if (!lstrcmpi(_pixel, \"yv411\"))\n              vi.pixel_type = VideoInfo::CS_YV411;\n            else\n              env->ThrowError(\"ImageReader: 12 bit, 3 plane EBMP: Pixel_type must be \\\"YV12\\\" or \\\"YV411\\\".\");\n          }\n          else\n            env->ThrowError(\"ImageReader: %d bit, 3 plane EBMP is unsupported.\", infoHeader.biBitCount);\n        }\n        else\n          env->ThrowError(\"ImageReader: %d plane BMP is unsupported.\", infoHeader.biPlanes);\n\n        if (DevIL_Version > 166 && (infoHeader.biWidth <= 0 || infoHeader.biHeight <= 0)) {\n            use_DevIL = true; // Not values we know, give it to DevIL\n        }\n        else {\n          if (infoHeader.biWidth <= 0)\n            // use_DevIL = true; // Not a type we know, give it to DevIL\n            env->ThrowError(\"ImageReader: Unsupported width %d\", infoHeader.biWidth);\n          if (infoHeader.biHeight <= 0)\n            // use_DevIL = true; // Not a type we know, give it to DevIL\n            env->ThrowError(\"ImageReader: Unsupported height %d\", infoHeader.biHeight);\n        }\n      }\n      else {\n        // DevIL 1.6.6 has a major coronary with compressed BMP files so don't fail thru to it\n        if (DevIL_Version <= 166)\n          env->ThrowError(\"ImageReader: EBMP reader cannot handle compressed images.\");\n\n        use_DevIL = true; // give it to DevIL (image is compressed)\n      }\n    }\n    else {\n      use_DevIL = true; // Not a BMP, give it to DevIL\n    }\n  }\n\n  if (use_DevIL == true) {  // attempt to open via DevIL\n\n    std::unique_lock<std::mutex> lock(DevIL_mutex);\n\n    ilInit();\n\n    ILuint myImage=0;\n    ilGenImages(1, &myImage);\n    ilBindImage(myImage);\n\n    ilLoadImage(filename);\n\n    vi.width = ilGetInteger(IL_IMAGE_WIDTH);\n    vi.height = ilGetInteger(IL_IMAGE_HEIGHT);\n\n    if (!lstrcmpi(_pixel, \"rgb\")) {\n      vi.pixel_type = VideoInfo::CS_BGR32;\n    }\n    else if (!lstrcmpi(_pixel, \"rgb32\")) {\n      vi.pixel_type = VideoInfo::CS_BGR32;\n    }\n    else if (!lstrcmpi(_pixel, \"rgb24\")) {\n      vi.pixel_type = VideoInfo::CS_BGR24;\n    }\n    else if (!lstrcmpi(_pixel, \"y8\")) {\n      vi.pixel_type = VideoInfo::CS_Y8;\n    }\n    else if (!lstrcmpi(_pixel, \"y16\")) {\n      vi.pixel_type = VideoInfo::CS_Y16;\n    }\n    else if (!lstrcmpi(_pixel, \"rgb48\")) {\n      vi.pixel_type = VideoInfo::CS_BGR48;\n    }\n    else if (!lstrcmpi(_pixel, \"rgb64\")) {\n      vi.pixel_type = VideoInfo::CS_BGR64;\n    }\n    /*\n    else if (!lstrcmpi(_pixel, \"rgbp8\") || !lstrcmpi(_pixel, \"rgbp\")) {\n      vi.pixel_type = VideoInfo::CS_RGBP;\n    }\n    else if (!lstrcmpi(_pixel, \"rgbap8\") || !lstrcmpi(_pixel, \"rgbap\")) {\n      vi.pixel_type = VideoInfo::CS_RGBAP;\n    }\n    else if (!lstrcmpi(_pixel, \"rgbp16\")) {\n      vi.pixel_type = VideoInfo::CS_RGBP16;\n    }\n    else if (!lstrcmpi(_pixel, \"rgbap16\")) {\n      vi.pixel_type = VideoInfo::CS_RGBAP16;\n    }\n    // these would need on-the-fly conversion, todo\n    */\n    else {\n      lock.unlock();\n      //env->ThrowError(\"ImageReader: supports the following pixel types: RGB24/32/48/64, Y8/16 or RGB(A)P8/16\");\n      env->ThrowError(\"ImageReader: supports the following pixel types: RGB24/32/48/64 or Y8/16\");\n    }\n\n    if (animation) {\n      vi.num_frames = ilGetInteger(IL_NUM_IMAGES) + 1; // bug in DevIL (ilGetInteger is one off in 166 en 178)\n      if (vi.num_frames <= 0) {\n        lock.unlock();\n        env->ThrowError(\"ImageSourceAnim: DevIL can't detect the number of images in the animation\");\n      }\n\n      unsigned duration_ms = (unsigned)ilGetInteger(IL_IMAGE_DURATION);\n      if (duration_ms != 0 && _fps == 24.0) { // overwrite framerate in case of non-zero duration\n          vi.SetFPS(1000, duration_ms);\n      }\n    }\n\n    // Get errors if any\n    // (note: inability to parse an (e)bmp will show up here as a DevIL error)\n    ILenum err = ilGetError();\n\n    ilDeleteImages(1, &myImage);\n\n    lock.unlock();\n\n    if (err != IL_NO_ERROR) {\n      env->ThrowError(\"ImageReader: error '%s' in DevIL library.\\nreading file \\\"%s\\\"\\nDevIL version %d.\", getErrStr(err), filename, DevIL_Version);\n    }\n    // work around DevIL upside-down bug with compressed images\n    should_flip = false;\n    const char * ext = strrchr(_base_name, '.') + 1;\n    if (  !lstrcmpi(ext, \"jpeg\") || !lstrcmpi(ext, \"jpg\") || !lstrcmpi(ext, \"jpe\") || !lstrcmpi(ext, \"dds\") ||\n          !lstrcmpi(ext, \"pal\") || !lstrcmpi(ext, \"psd\") || !lstrcmpi(ext, \"pcx\") || !lstrcmpi(ext, \"png\") ||\n          !lstrcmpi(ext, \"pbm\") || !lstrcmpi(ext, \"pgm\") || !lstrcmpi(ext, \"ppm\") || !lstrcmpi(ext, \"gif\") ||\n          !lstrcmpi(ext, \"exr\") || !lstrcmpi(ext, \"jp2\") || !lstrcmpi(ext, \"hdr\") )\n    {\n      should_flip = true;\n    }\n    else if ((DevIL_Version > 166) && (!lstrcmpi(ext, \"tif\") || !lstrcmpi(ext, \"tiff\")))\n    {\n      should_flip = true;\n    }\n    // flip back for Y8 or Y16\n    if (vi.IsY()) {\n        should_flip = !should_flip;\n    }\n  }\n\n  // undecorated filename means they want a single, static image or an animation\n  if (strcmp(filename, base_name) == 0) {\n    if (animation)\n      framecopies = 1;\n    else\n      framecopies = vi.num_frames;\n  }\n}\n\n\nImageReader::~ImageReader()\n{\n  if (use_DevIL) {\n      std::lock_guard<std::mutex> lock(DevIL_mutex);\n      ilShutDown();\n  }\n}\n\n/*  Notes to clear thinking!\n\n  vi.num_frames = end-start+1\n  0 <= n < vi.num_frames\n\n  for animation=true: vi.num_frames = ilGetInteger(IL_NUM_IMAGES)\n*/\n\nPVideoFrame ImageReader::GetFrame(int n, IScriptEnvironment* env)\n{\n  ILenum err = IL_NO_ERROR;\n\n  PVideoFrame frame = env->NewVideoFrame(vi);\n  BYTE * dstPtr = frame->GetWritePtr();\n  BYTE * const WritePtr = dstPtr;\n\n  const int pitch = frame->GetPitch();\n  const int row_size = frame->GetRowSize();\n  const int height = frame->GetHeight();\n  const int width = vi.width;\n\n#ifdef AVS_WINDOWS\n  _snprintf(filename, (sizeof filename)-1, base_name, n+start);\n#else\n  snprintf(filename, (sizeof filename) - 1, base_name, n+start);\n#endif\n\n  // do not lock right now\n  std::unique_lock<std::mutex> lock(DevIL_mutex, std::defer_lock);\n\n  if (use_DevIL)  /* read using DevIL */\n  {\n    lock.lock();\n\n    // Setup\n    ILuint myImage = 0;\n    ilGenImages(1, &myImage);\n    ilBindImage(myImage);\n\n    if (ilLoadImage(filename) == IL_FALSE) {\n      // Get errors if any\n      err = ilGetError();\n\n      // Cleanup\n      ilDeleteImages(1, &myImage);\n\n      lock.unlock();\n\n      memset(WritePtr, 0, pitch * height);  // Black frame\n      if ((info) || (err != IL_COULD_NOT_OPEN_FILE)) {\n        ostringstream ss;\n        ss << \"ImageReader: error '\" << getErrStr(err) << \"' in DevIL library\\n\"\n          \"opening file \\\"\" << filename << \"\\\"\\n\"\n          \"DevIL version \" << DevIL_Version << \".\";\n        env->ApplyMessage(&frame, vi, ss.str().c_str(), vi.width / 4, TEXT_COLOR, 0, 0);\n      }\n      return frame;\n    }\n\n    if (animation) {\n        if (ilActiveImage(n) == IL_FALSE) { // load image N from file\n          // Get errors if any\n          err = ilGetError();\n\n          // Cleanup\n          ilDeleteImages(1, &myImage);\n\n          lock.unlock();\n\n          memset(WritePtr, 0, pitch * height);  // Black frame\n          if (info) {\n            ostringstream ss;\n            ss << \"ImageSourceAnim: error '\" << getErrStr(err) << \"' in DevIL library\\n\"\n              \"processing image \" << n << \" from file \\\"\" << filename << \"\\\"\\n\"\n              \"DevIL version \" << DevIL_Version << \".\";\n            env->ApplyMessage(&frame, vi, ss.str().c_str(), vi.width / 4, TEXT_COLOR, 0, 0);\n          }\n          return frame;\n        }\n      }\n    else {\n      // Check some parameters\n      if (ilGetInteger(IL_IMAGE_HEIGHT) != height)\n      {\n        // Cleanup\n        ilDeleteImages(1, &myImage);\n\n        lock.unlock();\n\n        memset(WritePtr, 0, pitch * height);\n        env->ApplyMessage(&frame, vi, \"ImageReader: images must have identical heights\", vi.width / 4, TEXT_COLOR, 0, 0);\n        return frame;\n      }\n\n      if (ilGetInteger(IL_IMAGE_WIDTH) != width)\n      {\n        // Cleanup\n        ilDeleteImages(1, &myImage);\n\n        lock.unlock();\n\n        memset(WritePtr, 0, pitch * height);\n        env->ApplyMessage(&frame, vi, \"ImageReader: images must have identical widths\", vi.width / 4, TEXT_COLOR, 0, 0);\n        return frame;\n      }\n    }\n\n    const ILenum il_format = vi.IsY() ? IL_LUMINANCE : ( (vi.IsRGB32() || vi.IsRGB64()) ? IL_BGRA : IL_BGR );\n    const ILenum linesize = width * ( vi.IsY() ? 1 : ( (vi.IsRGB32() || vi.IsRGB64()) ? 4 : 3 ) ) * vi.ComponentSize();\n    const int height_image = min(height, ilGetInteger(IL_IMAGE_HEIGHT));\n    const int width_image = min(width, ilGetInteger(IL_IMAGE_WIDTH));\n    const ILenum linesize_image = width_image * ( vi.IsY() ? 1 : ( (vi.IsRGB32() || vi.IsRGB64()) ? 4 : 3 ) ) * vi.ComponentSize();\n\n    if (!vi.IsY()) {\n      // fill bottom with black pixels\n      memset(dstPtr, 0, pitch * (height-height_image));\n      dstPtr += pitch * (height-height_image);\n    }\n\n    int ilPixelType = vi.ComponentSize() == 1 ? IL_UNSIGNED_BYTE : IL_UNSIGNED_SHORT;\n\n    // Copy raster to AVS frame\n////if (ilGetInteger(IL_ORIGIN_MODE) == IL_ORIGIN_UPPER_LEFT, IL_ORIGIN_LOWER_LEFT ???\n    if (should_flip)\n    {\n      // Copy upside down\n      for (int y=height_image-1; y>=0; --y)\n      {\n        if (ilCopyPixels(0, y, 0, width_image, 1, 1, il_format, ilPixelType, dstPtr) > linesize)\n          break; // Try not to spew all over memory\n        memset(dstPtr+linesize_image, 0, linesize-linesize_image);\n        dstPtr += pitch;\n      }\n    }\n    else {\n      // Copy right side up\n      for (int y=0; y<height_image; ++y)\n      {\n        if (ilCopyPixels(0, y, 0, width_image, 1, 1, il_format, ilPixelType, dstPtr) > linesize)\n          break; // Try not to spew all over memory\n        memset(dstPtr+linesize_image, 0, linesize-linesize_image);\n        dstPtr += pitch;\n      }\n    }\n\n    if (vi.IsY()) {\n      // fill bottom with black pixels\n      memset(dstPtr, 0, pitch * (height-height_image));\n    }\n\n    // Get errors if any\n    err = ilGetError();\n\n    // Cleanup\n    ilDeleteImages(1, &myImage);\n\n    lock.unlock();\n\n    if (err != IL_NO_ERROR)\n    {\n      memset(WritePtr, 0, pitch * height);\n      ostringstream ss;\n      ss << \"ImageReader: error '\" << getErrStr(err) << \"' in DevIL library\\n\"\n            \"reading file \\\"\" << filename << \"\\\"\\n\"\n            \"DevIL version \" << DevIL_Version << \".\";\n      env->ApplyMessage(&frame, vi, ss.str().c_str(), vi.width/4, TEXT_COLOR, 0, 0);\n      return frame;\n    }\n  }\n  else {  /* treat as ebmp  */\n    // Open file, ensure it has the expected properties\n    ifstream file(filename, ios::binary);\n    if (!checkProperties(file, frame, env)) {\n      file.close();\n      return frame;\n    }\n\n    // Seek past padding\n    file.seekg (fileHeader.bfOffBits, ios::beg);\n\n    // Read in raster\n    if (vi.IsY())\n    {\n      // read upside down\n      BYTE * endPtr = dstPtr + pitch * (height-1);\n      fileRead(file, endPtr, -pitch, row_size, height);\n    }\n    else\n    {\n      fileRead(file, dstPtr, pitch, row_size, height);\n\n      if (vi.IsPlanar())\n      {\n        dstPtr = frame->GetWritePtr(PLANAR_U);\n        const int pitchUV = frame->GetPitch(PLANAR_U);\n        const int row_sizeUV = frame->GetRowSize(PLANAR_U);\n        const int heightUV = frame->GetHeight(PLANAR_U);\n        fileRead(file, dstPtr, pitchUV, row_sizeUV, heightUV);\n\n        dstPtr = frame->GetWritePtr(PLANAR_V);\n        fileRead(file, dstPtr, pitchUV, row_sizeUV, heightUV);\n      }\n    }\n\n    file.close();\n  }\n\n  if (info) {\n    // overlay on video output: progress indicator\n    ostringstream text;\n    text << \"Frame \" << n << \".\\n\"\n            \"Read from \\\"\" << filename << \"\\\"\\n\"\n            \"DevIL version \" << DevIL_Version << \".\";\n    env->ApplyMessage(&frame, vi, text.str().c_str(), vi.width/4, TEXT_COLOR, 0, 0);\n  }\n\n  return frame;\n}\n\n\nvoid ImageReader::fileRead(istream & file, BYTE * dstPtr, const int pitch, const int row_size, const int height)\n{\n  int padding = (4 - (row_size % 4)) % 4;\n  for (int y=0; y<height; ++y)\n  {\n    file.read( reinterpret_cast<char *> (dstPtr), row_size);\n    file.seekg(padding, ios_base::cur);\n    dstPtr += pitch;\n  }\n}\n\n\nvoid ImageReader::BlankFrame(PVideoFrame & frame)\n{\n  const int size = frame->GetPitch() * frame->GetHeight();\n\n  if (vi.IsPlanarRGB() || vi.IsPlanarRGBA()) {\n    bool hasAlpha = vi.IsPlanarRGBA();\n    int pixelsize = vi.ComponentSize();\n    if (pixelsize == 1) {\n      memset(frame->GetWritePtr(PLANAR_G), 128, size); // Grey frame\n      memset(frame->GetWritePtr(PLANAR_B), 128, size);\n      memset(frame->GetWritePtr(PLANAR_R), 128, size);\n      if(hasAlpha)\n        memset(frame->GetWritePtr(PLANAR_A), 255, size); // transparent alpha\n    }\n    else if (pixelsize == 2) {\n      uint16_t half = 1 << (vi.BitsPerComponent() - 1);\n      uint16_t max = (1 << vi.BitsPerComponent()) - 1;\n      std::fill_n((uint16_t *)frame->GetWritePtr(PLANAR_G), size / 2, half); // Grey frame\n      std::fill_n((uint16_t *)frame->GetWritePtr(PLANAR_B), size / 2, half); // Grey frame\n      std::fill_n((uint16_t *)frame->GetWritePtr(PLANAR_R), size / 2, half); // Grey frame\n      if (hasAlpha)\n        std::fill_n((uint16_t *)frame->GetWritePtr(PLANAR_A), size / 2, max); // transparent alpha\n    }\n    else if (pixelsize == 4) { // float\n      const float half = 0.5f;\n      std::fill_n((float *)frame->GetWritePtr(PLANAR_G), size / 4, half); // Grey frame\n      std::fill_n((float *)frame->GetWritePtr(PLANAR_B), size / 4, half); // Grey frame\n      std::fill_n((float *)frame->GetWritePtr(PLANAR_R), size / 4, half); // Grey frame\n      if (hasAlpha)\n        std::fill_n((float *)frame->GetWritePtr(PLANAR_A), size / 4, 1.0f); // Grey frame\n    }\n  } else if (vi.IsRGB() || vi.IsY()) {\n    memset(frame->GetWritePtr(), 0, size); // Black frame\n  }\n  else {\n    int pixelsize = vi.ComponentSize();\n    const int UVpitch = frame->GetPitch(PLANAR_U);\n    if (pixelsize == 1) {\n      memset(frame->GetWritePtr(), 128, size); // Grey frame\n\n      if (UVpitch) {\n        const int UVsize = UVpitch * frame->GetHeight(PLANAR_U);\n\n        memset(frame->GetWritePtr(PLANAR_U), 128, UVsize);\n        memset(frame->GetWritePtr(PLANAR_V), 128, UVsize);\n      }\n    }\n    else if (pixelsize == 2) {\n      uint16_t half = 1 << (vi.BitsPerComponent() - 1);\n      std::fill_n((uint16_t *)frame->GetWritePtr(), size / 2, half); // Grey frame\n\n      if (UVpitch) {\n        const int UVsize = UVpitch * frame->GetHeight(PLANAR_U);\n        std::fill_n((uint16_t *)frame->GetWritePtr(PLANAR_U), UVsize / 2, half); // Grey frame\n        std::fill_n((uint16_t *)frame->GetWritePtr(PLANAR_V), UVsize / 2, half); // Grey frame\n      }\n    }\n    else if (pixelsize == 4) { // float\n      const float half = 0.5f;\n#ifdef FLOAT_CHROMA_IS_HALF_CENTERED\n      const float halfUV = 0.5f;\n#else\n      const float halfUV = 0.0f;\n#endif\n      std::fill_n((float *)frame->GetWritePtr(), size / 4, half); // Grey frame\n\n      if (UVpitch) {\n        const int UVsize = UVpitch * frame->GetHeight(PLANAR_U);\n        std::fill_n((float *)frame->GetWritePtr(PLANAR_U), UVsize / 4, halfUV); // Grey frame\n        std::fill_n((float *)frame->GetWritePtr(PLANAR_V), UVsize / 4, halfUV); // Grey frame\n      }\n    }\n  }\n}\n\n\nvoid ImageReader::BlankApplyMessage(PVideoFrame & frame, const char * text, IScriptEnvironment * env)\n{\n  BlankFrame(frame);\n  env->ApplyMessage(&frame, vi, text, vi.width/4, TEXT_COLOR, 0, 0);\n}\n\n\nbool ImageReader::checkProperties(ifstream & file, PVideoFrame & frame, IScriptEnvironment * env)\n{\n  if (!file.is_open())\n  {\n    if (info)\n      BlankApplyMessage(frame, \"ImageReader: cannot open file\", env);\n    else\n      BlankFrame(frame);\n\n    return false;\n  }\n\n  BITMAPFILEHEADER tempFileHeader;\n  BITMAPINFOHEADER tempInfoHeader;\n\n  file.read( reinterpret_cast<char *> (&tempFileHeader), sizeof(tempFileHeader) );\n  file.read( reinterpret_cast<char *> (&tempInfoHeader), sizeof(tempInfoHeader) );\n\n  if (tempFileHeader.bfType != fileHeader.bfType)\n  {\n    BlankApplyMessage(frame, \"ImageReader: invalid (E)BMP file\", env);\n    return false;\n  }\n\n  if (tempInfoHeader.biWidth != infoHeader.biWidth)\n  {\n    BlankApplyMessage(frame, \"ImageReader: image widths must be identical\", env);\n    return false;\n  }\n\n  if (tempInfoHeader.biHeight != infoHeader.biHeight)\n  {\n    BlankApplyMessage(frame, \"ImageReader: image heights must be identical\", env);\n    return false;\n  }\n\n  if (tempInfoHeader.biPlanes != infoHeader.biPlanes)\n  {\n    BlankApplyMessage(frame, \"ImageReader: images must have the same number of planes\", env);\n    return false;\n  }\n\n  if (tempInfoHeader.biBitCount != infoHeader.biBitCount)\n  {\n    BlankApplyMessage(frame, \"ImageReader: images must have identical bits per pixel\", env);\n    return false;\n  }\n\n  if (tempFileHeader.bfSize != fileHeader.bfSize)\n  {\n    BlankApplyMessage(frame, \"ImageReader: raster sizes must be identical\", env);\n    return false;\n  }\n\n  if (tempInfoHeader.biCompression != 0)\n  {\n    BlankApplyMessage(frame, \"ImageReader: EBMP reader cannot handle compressed images\", env);\n    return false;\n  }\n\n  return true;\n}\n"
  },
  {
    "path": "plugins/ImageSeq/ImageSeq.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n\n#include <avisynth.h>\n#include \"ImageSeq.h\"\n\n// Since devIL isn't threadsafe, we need to ensure that only one thread at the time requests frames\nstd::mutex DevIL_mutex;\nvolatile ILint DevIL_Version = 0;\n\nAVSValue __cdecl Create_ImageWriter(AVSValue args, void* user_data, IScriptEnvironment* env)\n{\n  PClip clip = args[0].AsClip();\n  const VideoInfo &vi = clip->GetVideoInfo();\n  if (vi.IsPlanarRGB() || vi.IsPlanarRGBA())\n  {\n    // silently convert to packed bitmap\n    int bits_per_pixel = vi.BitsPerComponent();\n    bool hasAlpha = vi.IsPlanarRGBA();\n    AVSValue new_args[1] = { clip };\n    if (bits_per_pixel == 8) {\n      if (hasAlpha)\n        clip = env->Invoke(\"ConvertToRGB32\", AVSValue(new_args, 1)).AsClip();\n      else\n        clip = env->Invoke(\"ConvertToRGB24\", AVSValue(new_args, 1)).AsClip();\n    }\n    else if (bits_per_pixel == 16) {\n      if (hasAlpha)\n        clip = env->Invoke(\"ConvertToRGB64\", AVSValue(new_args, 1)).AsClip();\n      else\n        clip = env->Invoke(\"ConvertToRGB48\", AVSValue(new_args, 1)).AsClip();\n    }\n    else {\n      env->ThrowError(\"ImageWriter: only 8 or 16 bit planar RGB formats supported\");\n    }\n  }\n\n  return new ImageWriter(clip,\n#ifdef AVS_WINDOWS\n                         env->SaveString(args[1].AsString(\"c:\\\\\")),\n#else\n                         env->SaveString(args[1].AsString(\"\")),\n#endif\n                         args[2].AsInt(0),\n                         args[3].AsInt(0),\n                         env->SaveString(args[4].AsString(\"ebmp\")),\n                         args[5].AsBool(false), env);\n}\n\nAVSValue __cdecl Create_ImageReader(AVSValue args, void*, IScriptEnvironment* env)\n{\n#ifdef AVS_WINDOWS\n  const char * path = args[0].AsString(\"c:\\\\%06d.ebmp\");\n#else\n  const char* path = args[0].AsString(\"./%06d.ebmp\");\n#endif\n\n  ImageReader *IR = new ImageReader(path, args[1].AsInt(0), args[2].AsInt(1000), (float)args[3].AsDblDef(24.0),\n                                    args[4].AsBool(false), args[5].AsBool(false), args[6].AsString(\"rgb24\"),\n                                    /*animation*/ false, env);\n  // If we are returning a stream of 2 or more copies of the same image\n  // then use FreezeFrame and the Cache to minimise any reloading.\n  if (IR->framecopies > 1) {\n    AVSValue cache = env->Invoke(\"Cache\", AVSValue(IR));\n    AVSValue ff_args[4] = { cache, 0, IR->framecopies-1, 0 };\n    return env->Invoke(\"FreezeFrame\", AVSValue(ff_args, 4)).AsClip();\n  }\n\n  return IR;\n}\n\nAVSValue __cdecl Create_Animated(AVSValue args, void*, IScriptEnvironment* env)\n{\n  if (!args[0].IsString())\n    env->ThrowError(\"ImageSourceAnim: You must specify a filename.\");\n\n  return new ImageReader(args[0].AsString(), 0, 0, (float)args[1].AsDblDef(24.0), /*use_DevIL*/ true,\n                         args[2].AsBool(false), args[3].AsString(\"rgb32\"), /*animation*/ true, env);\n}\n\nconst AVS_Linkage * AVS_linkage = 0;\nextern \"C\" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors)\n{\n\tAVS_linkage = vectors;\n\n  // clip, base filename, start, end, image format/extension, info\n  env->AddFunction(\"ImageWriter\", \"c[file]s[start]i[end]i[type]s[info]b\", Create_ImageWriter, 0);\n\n  // base filename (sprintf-style), start, end, frames per second, default reader to use, info, pixel_type\n  env->AddFunction(\"ImageReader\", \"[file]s[start]i[end]i[fps]f[use_devil]b[info]b[pixel_type]s\", Create_ImageReader, 0);\n  env->AddFunction(\"ImageSource\", \"[file]s[start]i[end]i[fps]f[use_devil]b[info]b[pixel_type]s\", Create_ImageReader, 0);\n\n  env->AddFunction(\"ImageSourceAnim\", \"[file]s[fps]f[info]b[pixel_type]s\", Create_Animated, 0);\n\n  return \"`ImageSeq' Methods for loading and writing still images.\";\n}\n\nconst char *const getErrStr(ILenum err)\n{\n  if (err == IL_INVALID_ENUM)\n    return \"Invalid Enum\";\n  if (err == IL_OUT_OF_MEMORY)\n    return \"Out of memory\";\n  if (err == IL_FORMAT_NOT_SUPPORTED)\n    return \"Format not supported\";\n  if (err == IL_INTERNAL_ERROR)\n    return \"Internal error\";\n  if (err == IL_INVALID_VALUE)\n    return \"Invalid value\";\n  if (err == IL_ILLEGAL_OPERATION)\n    return \"Illegal operation\";\n  if (err == IL_ILLEGAL_FILE_VALUE)\n    return \"Illegal file value\";\n  if (err == IL_INVALID_FILE_HEADER)\n    return \"Illegal file header\";\n  if (err == IL_INVALID_PARAM)\n    return \"Invalid Parameter\";\n  if (err == IL_COULD_NOT_OPEN_FILE)\n    return \"Could not open file\";\n  if (err == IL_INVALID_EXTENSION)\n    return \"Invalid extension\";\n  if (err == IL_FILE_ALREADY_EXISTS)\n    return \"File already exists\";\n  if (err == IL_OUT_FORMAT_SAME)\n    return \"Output format same\";\n  if (err == IL_STACK_OVERFLOW)\n    return \"Stack overflow\";\n  if (err == IL_STACK_UNDERFLOW)\n    return \"Stack underflow\";\n  if (err == IL_INVALID_CONVERSION)\n    return \"Invalid conversion\";\n  if (err == IL_BAD_DIMENSIONS)\n    return \"Bad dimensions\";\n  if ((err == IL_FILE_READ_ERROR) || (err == IL_FILE_WRITE_ERROR))\n    return \"File read/write error\";\n  if (err == IL_LIB_GIF_ERROR)\n    return \"LibGif error\";\n  if (err == IL_LIB_JPEG_ERROR)\n    return \"LibJpeg error\";\n  if (err == IL_LIB_PNG_ERROR)\n    return \"LibPng error\";\n  if (err == IL_LIB_TIFF_ERROR)\n    return \"LibTiff error\";\n  if (err == IL_LIB_MNG_ERROR)\n    return \"LibMng error\";\n#if IL_VERSION >= 178\n  if (err == IL_LIB_JP2_ERROR)\n    return \"LibJP2 error\";\n  if (err == IL_LIB_EXR_ERROR)\n    return \"LibExr error\";\n#endif\n  if (err == IL_UNKNOWN_ERROR)\n    return \"Unknown error\";\n\n  return \"Unknown error\";\n}\n\n"
  },
  {
    "path": "plugins/ImageSeq/ImageSeq.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __Image_Sequence_H__\n#define __Image_Sequence_H__\n\n#include \"il.h\"\n#include <avs/config.h>\n#ifdef AVS_WINDOWS\n#include <avs/win.h>\n#else\n#include <avs/posix.h>\n#endif\n\n#include <cassert>\n#include <fstream>\n#include <atomic>\n#include <mutex>\n\n#ifndef AVS_WINDOWS\ntypedef uint16_t      WORD;\ntypedef int32_t       LONG;\ntypedef uint32_t      DWORD;\n\ntypedef struct tagBITMAPFILEHEADER {\n  WORD    bfType;\n  DWORD   bfSize;\n  WORD    bfReserved1;\n  WORD    bfReserved2;\n  DWORD   bfOffBits;\n} BITMAPFILEHEADER;\n\ntypedef struct tagBITMAPINFOHEADER {\n  DWORD      biSize;\n  LONG       biWidth;\n  LONG       biHeight;\n  WORD       biPlanes;\n  WORD       biBitCount;\n  DWORD      biCompression;\n  DWORD      biSizeImage;\n  LONG       biXPelsPerMeter;\n  LONG       biYPelsPerMeter;\n  DWORD      biClrUsed;\n  DWORD      biClrImportant;\n} BITMAPINFOHEADER;\n\n#endif\n\nclass ImageWriter : public GenericVideoFilter\n/**\n  * Class to write video as a sequence of images\n **/\n{\npublic:\n  ImageWriter(PClip _child, const char * _base_name, const int _start, const int _end, const char * _ext, bool _info, IScriptEnvironment* env);\n  ~ImageWriter();\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n\nprivate:\n  void fileWrite(std::ostream & file, const BYTE * srcPtr, const int pitch, const int row_size, const int height);\n\n  bool info;\n\n#ifdef AVS_WINDOWS\n  char base_name[MAX_PATH + 1];\n#else\n  char base_name[PATH_MAX + 1];\n#endif\n  const char * ext;\n  int start;\n  int end;\n\n  bool should_flip;\n\n  BITMAPFILEHEADER fileHeader;\n  BITMAPINFOHEADER infoHeader;\n};\n\n\nclass ImageReader : public IClip\n/**\n  * Class to read image sequences into video buffers\n **/\n{\npublic:\n  ImageReader(const char * _base_name, const int _start, const int _end,\n              const double _fps, bool _use_DevIL, bool _info, const char * _pixel,\n              bool _animation, IScriptEnvironment* env);\n  ~ImageReader();\n\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);\n\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env) {}\n  const VideoInfo& __stdcall GetVideoInfo() { return vi; }\n  bool __stdcall GetParity(int n) { return false; }\n  int __stdcall SetCacheHints(int cachehints,int frame_range) { return 0; };\n\n  int  framecopies;\n\nprivate:\n  void fileRead(std::istream & file, BYTE * dstPtr, const int pitch, const int row_size, const int height);\n  void BlankFrame(PVideoFrame & frame);\n  void BlankApplyMessage(PVideoFrame & frame, const char * text, IScriptEnvironment * env);\n  bool checkProperties(std::ifstream & file, PVideoFrame & frame, IScriptEnvironment * env);\n\n#ifdef AVS_WINDOWS\n  char base_name[MAX_PATH + 1];\n#else\n  char base_name[PATH_MAX + 1];\n#endif\n  const int start;\n  bool use_DevIL;\n  bool info;\n  bool animation;\n\n  VideoInfo vi;\n\n#ifdef AVS_WINDOWS\n  char filename[MAX_PATH + 1];\n#else\n  char filename[PATH_MAX + 1];\n#endif\nbool should_flip;\n\n  BITMAPFILEHEADER fileHeader;\n  BITMAPINFOHEADER infoHeader;\n};\n\n\nconst char *const getErrStr(ILenum err);\n\n// Since devIL isn't threadsafe, we need to ensure that only one thread at the time requests frames\nextern std::mutex DevIL_mutex;\nextern volatile ILint DevIL_Version;\n\n#endif // __Image_Sequence_H__\n"
  },
  {
    "path": "plugins/ImageSeq/ImageWriter.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n\n\n#include <avisynth.h>\n#include \"ImageSeq.h\"\n#include <algorithm>\n#include <sstream>\n#include <avs/config.h>\n#include <avs/filesystem.h>\n#include <iostream>\n\n#define TEXT_COLOR 0xf0f080\n\nusing namespace std;\n\n\nImageWriter::ImageWriter(PClip _child, const char * _base_name, const int _start, const int _end,\n                         const char * _ext, bool _info, IScriptEnvironment* env)\n : GenericVideoFilter(_child), ext(_ext), info(_info)\n{\n#ifdef AVS_WINDOWS\n  // treat empty input as current directory\n  const char *base_name_good = (*_base_name == 0) ? \".\\\\\" : _base_name;\n  // Make sure we have an absolute path.\n  DWORD len = GetFullPathName(base_name_good, 0, base_name, NULL);\n  if (len == 0)\n    env->ThrowError(\"ImageWriter: GetFullPathName failed. Error code: %d.\", GetLastError());\n  if (len > sizeof(base_name))\n    env->ThrowError(\"ImageWriter: Path to %s too long.\", _base_name);\n  (void)GetFullPathName(base_name_good, len, base_name, NULL);\n#else\n  std::string base_name_good = (*_base_name == 0) ? \"./\" : _base_name;\n  auto path = fs::path(base_name_good);\n  std::error_code ec;\n  auto fullpath = fs::absolute(path, ec);\n  // to-do: check ec\n  //auto fullpath = fs::canonical(path, ec); // canonical removes e.g. dot. Path must exist.\n  std::string fullpaths = fullpath.string();\n  // cout << fullpaths.c_str() << \"\\n\"; // debug\n  if (fullpaths.size() > sizeof(base_name) - 1)\n    env->ThrowError(\"ImageWriter: Path to %s too long.\", _base_name);\n  strcpy(base_name, fullpaths.c_str());\n#endif\n\n  if (strchr(base_name, '%') == NULL) {\n    base_name[(sizeof base_name)-8] = '\\0';\n    strcat(base_name, \"%06d.%s\"); // Append default formating\n  }\n\n  if (!lstrcmpi(ext, \"ebmp\"))\n  {\n    if (vi.BitsPerComponent() != 8)\n      env->ThrowError(\"ImageWriter: ebmp requires 8 bits/component images\");\n    // construct file header\n    fileHeader.bfType = ('M' << 8) + 'B'; // I hate little-endian\n    fileHeader.bfSize = vi.BMPSize(); // includes 4-byte padding\n    fileHeader.bfReserved1 = 0;\n    fileHeader.bfReserved2 = 0;\n    fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);\n    fileHeader.bfSize += fileHeader.bfOffBits;\n\n    // construct info header\n    infoHeader.biSize = sizeof(BITMAPINFOHEADER);\n    infoHeader.biWidth = vi.width;\n    infoHeader.biHeight = vi.height;\n    infoHeader.biPlanes = (vi.IsPlanar() && !vi.IsY()) ? 3 : 1;\n    infoHeader.biBitCount = WORD(vi.BitsPerPixel());\n    infoHeader.biCompression = 0;\n    infoHeader.biSizeImage = fileHeader.bfSize - fileHeader.bfOffBits;\n    infoHeader.biXPelsPerMeter = 0;\n    infoHeader.biYPelsPerMeter = 0;\n    infoHeader.biClrUsed = 0;\n    infoHeader.biClrImportant = 0;\n  }\n  else {\n    should_flip = false;\n    if (vi.IsY())\n      should_flip = true;\n    if (!lstrcmpi(ext, \"raw\"))\n      should_flip = false;\n\n    if (!((vi.IsY() && (vi.BitsPerComponent() == 8 || vi.BitsPerComponent() == 16)) || (vi.IsRGB() && !vi.IsPlanar())))\n      env->ThrowError(\"ImageWriter: DevIL requires 8 or 16 bits per channel RGB or greyscale input\");\n\n\n    {\n      std::lock_guard<std::mutex> lock(DevIL_mutex);\n      ilInit();\n    }\n  }\n\n  start = max(_start, 0);\n\n  if (_end==0)\n    end = vi.num_frames-1;\n  else if (_end<0)\n    end = start - _end - 1;\n  else\n    end = _end;\n\n  end = max(end, start);\n}\n\n\nImageWriter::~ImageWriter()\n{\n  if (!!lstrcmpi(ext, \"ebmp\")) {\n    std::lock_guard<std::mutex> lock(DevIL_mutex);\n    ilShutDown();\n  }\n}\n\n\n\nPVideoFrame ImageWriter::GetFrame(int n, IScriptEnvironment* env)\n{\n  PVideoFrame frame = child->GetFrame(n, env);\n\n  // check bounds\n  if ((n<start)||(n>end))\n  {\n    if (info) {\n      ostringstream ss;\n      ss << \"ImageWriter: frame \" << n << \" not in range\";\n      env->MakeWritable(&frame);\n      env->ApplyMessage(&frame, vi, ss.str().c_str(), vi.width/4, TEXT_COLOR, 0, 0);\n    }\n    return frame;\n  }\n\n  // construct filename\n#ifdef AVS_WINDOWS\n  char filename[MAX_PATH + 1];\n  _snprintf(filename, MAX_PATH, base_name, n, ext, 0, 0);\n  filename[MAX_PATH] = '\\0';\n#else\n  char filename[PATH_MAX + 1];\n  snprintf(filename, PATH_MAX, base_name, n, ext, 0, 0);\n  filename[PATH_MAX] = '\\0';\n#endif\n\n  if (!lstrcmpi(ext, \"ebmp\"))  /* Use internal 'ebmp' writer */\n  {\n    // initialize file object\n    ofstream file(filename, ios::out | ios::trunc | ios::binary);\n    if (!file)\n    {\n      ostringstream ss;\n      ss << \"ImageWriter: could not create file '\" << filename << \"'\";\n      env->MakeWritable(&frame);\n      env->ApplyMessage(&frame, vi, ss.str().c_str(), vi.width/4, TEXT_COLOR, 0, 0);\n      return frame;\n    }\n\n    // write headers\n    file.write(reinterpret_cast<const char *>( &fileHeader ), sizeof(BITMAPFILEHEADER));\n    file.write(reinterpret_cast<const char *>( &infoHeader ), sizeof(BITMAPINFOHEADER));\n\n    // write raster\n    const BYTE * srcPtr = frame->GetReadPtr();\n    int pitch = frame->GetPitch();\n    int row_size = frame->GetRowSize();\n    int height = frame->GetHeight();\n\n    if (vi.IsY8())\n    {\n      // write upside down\n      const BYTE * endPtr = srcPtr + pitch * (height-1);\n      fileWrite(file, endPtr, -pitch, row_size, height);\n    }\n    else\n    {\n      fileWrite(file, srcPtr, pitch, row_size, height);\n\n      if (vi.IsPlanar())\n      {\n        srcPtr = frame->GetReadPtr(PLANAR_U);\n        pitch = frame->GetPitch(PLANAR_U);\n        row_size = frame->GetRowSize(PLANAR_U);\n        height = frame->GetHeight(PLANAR_U);\n        fileWrite(file, srcPtr, pitch, row_size, height);\n\n        srcPtr = frame->GetReadPtr(PLANAR_V);\n        fileWrite(file, srcPtr, pitch, row_size, height);\n      }\n    }\n\n    // clean up\n    file.close();\n  }\n  else { /* Use DevIL library */\n    std::unique_lock<std::mutex> lock(DevIL_mutex);\n\n    // Set up DevIL\n    ILuint myImage = 0;\n    ilGenImages(1, &myImage); // Initialize 1 image structure\n    ilBindImage(myImage);     // Set this as the current image\n\n    const ILenum il_format = vi.IsY() ? IL_LUMINANCE : ((vi.IsRGB32() || vi.IsRGB64()) ? IL_BGRA : IL_BGR);\n    const ILenum ilPixelType = vi.ComponentSize() == 1 ? IL_UNSIGNED_BYTE : IL_UNSIGNED_SHORT;\n\n    // Set image parameters\n    int bytesPerPixel = vi.BitsPerPixel() / 8 / vi.ComponentSize();\n    if (IL_TRUE == ilTexImage(vi.width, vi.height, 1, ILubyte(bytesPerPixel), il_format, ilPixelType, NULL)) {\n\n      // Program actual image raster\n      const BYTE* srcPtr = frame->GetReadPtr();\n      int pitch = frame->GetPitch();\n      if (should_flip) {\n        for (int y = vi.height - 1; y >= 0; --y)\n        {\n          ilSetPixels(0, y, 0, vi.width, 1, 1, il_format, ilPixelType, (void*)srcPtr);\n          srcPtr += pitch;\n        }\n      }\n      else {\n        for (int y = 0; y < vi.height; ++y)\n        {\n          ilSetPixels(0, y, 0, vi.width, 1, 1, il_format, ilPixelType, (void*)srcPtr);\n          srcPtr += pitch;\n        }\n      }\n\n      // DevIL writer fails if the file exists, so delete first\n#ifdef AVS_WINDOWS\n      DeleteFile(filename);\n#else\n      fs::remove(fs::path(filename));\n#endif\n\n      // Save to disk (format automatically inferred from extension)\n      ilSaveImage(filename);\n    }\n\n    // Get errors if any\n    ILenum err = ilGetError();\n\n    // Clean up\n    ilDeleteImages(1, &myImage);\n\n    lock.unlock();\n\n    if (err != IL_NO_ERROR)\n    {\n      ostringstream ss;\n      ss << \"ImageWriter: error '\" << getErrStr(err) << \"' in DevIL library\\n\"\n            \"writing file \\\"\" << filename << \"\\\"\\n\"\n            \"DevIL version \" << DevIL_Version << \".\";\n      env->MakeWritable(&frame);\n      env->ApplyMessage(&frame, vi, ss.str().c_str(), vi.width / 4, TEXT_COLOR, 0, 0);\n      return frame;\n    }\n  }\n\n  if (info) {\n    // overlay on video output: progress indicator\n    ostringstream text;\n    text << \"Frame \" << n << \" written to: \" << filename;\n    env->MakeWritable(&frame);\n    env->ApplyMessage(&frame, vi, text.str().c_str(), vi.width/4, TEXT_COLOR, 0, 0);\n  }\n\n  return frame;\n}\n\n\nvoid ImageWriter::fileWrite(ostream & file, const BYTE * srcPtr, const int pitch, const int row_size, const int height)\n{\n  int dummy = 0;\n  int padding = (4 - (row_size % 4)) % 4;\n\n  for(int i=0; i < height; ++i)\n  {\n    file.write(reinterpret_cast<const char *>( srcPtr ), row_size);\n    file.write(reinterpret_cast<char *>( &dummy ), padding); // pad with 0's to mod-4\n    srcPtr += pitch;\n  }\n}\n"
  },
  {
    "path": "plugins/Shibatch/CMakeLists.txt",
    "content": "CMAKE_MINIMUM_REQUIRED( VERSION 3.6.2...3.11 )\n\nset(PluginName \"Shibatch\")\nset(ProjectName \"Plugin${PluginName}\")\n\nif (NOT WIN32)\n  string(TOLOWER \"${PluginName}\" PluginName)\nendif()\n\n# Create library\nproject(${ProjectName} VERSION ${PROJECT_VERSION} LANGUAGES C CXX)\nlist (APPEND SourceFiles\n    \"dbesi0.c\"\n    \"fft.h\"\n    \"paramlist.h\"\n    \"ssrc.cpp\"\n    \"ssrc.h\"\n    \"ssrc-convert.cpp\"\n    \"ssrc-convert.h\"\n    \"supereq.cpp\"\n    \"supereq.h\"\n    \"mem_block.cpp\"\n    \"mem_block.h\"\n    \"shibatch.cpp\"\n)\nadd_library(${ProjectName} SHARED ${SourceFiles})\nset_property(GLOBAL APPEND PROPERTY BUILT_TARGETS ${ProjectName})\nset_target_properties(${ProjectName} PROPERTIES \"OUTPUT_NAME\" ${PluginName})\nif (MINGW)\n  set_target_properties(${ProjectName} PROPERTIES PREFIX \"\")\n  set_target_properties(${ProjectName} PROPERTIES IMPORT_PREFIX \"\")\nendif()\n\n# Library dependencies\n\n# Include directories\ntarget_include_directories(${ProjectName} PRIVATE ${AvsCore_SOURCE_DIR})\n\nif (MSVC_IDE)\n  # Copy output to a common folder for easy deployment\n  add_custom_command(\n    TARGET ${ProjectName}\n    POST_BUILD\n    COMMAND xcopy /Y \\\"$(TargetPath)\\\" \\\"${CMAKE_BINARY_DIR}/Output/plugins\\\"\n  )\nendif()\n\nINSTALL(TARGETS \"${ProjectName}\"\n        DESTINATION \"${CORE_PLUGIN_INSTALL_PATH}/avisynth\")\n"
  },
  {
    "path": "plugins/Shibatch/dbesi0.c",
    "content": "/* Bessel I_0(x) function in double precision */\n\n//#include \"stdafx.h\"\n\n#include <math.h>\n\ndouble dbesi0(double x)\n{\n    int k;\n    double w, t, y;\n    static const double a[65] = {\n        8.5246820682016865877e-11, 2.5966600546497407288e-9,\n        7.9689994568640180274e-8, 1.9906710409667748239e-6,\n        4.0312469446528002532e-5, 6.4499871606224265421e-4,\n        0.0079012345761930579108, 0.071111111109207045212,\n        0.444444444444724909, 1.7777777777777532045,\n        4.0000000000000011182, 3.99999999999999998,\n        1.0000000000000000001,\n        1.1520919130377195927e-10, 2.2287613013610985225e-9,\n        8.1903951930694585113e-8, 1.9821560631611544984e-6,\n        4.0335461940910133184e-5, 6.4495330974432203401e-4,\n        0.0079013012611467520626, 0.071111038160875566622,\n        0.44444450319062699316, 1.7777777439146450067,\n        4.0000000132337935071, 3.9999999968569015366,\n        1.0000000003426703174,\n        1.5476870780515238488e-10, 1.2685004214732975355e-9,\n        9.2776861851114223267e-8, 1.9063070109379044378e-6,\n        4.0698004389917945832e-5, 6.4370447244298070713e-4,\n        0.0079044749458444976958, 0.071105052411749363882,\n        0.44445280640924755082, 1.7777694934432109713,\n        4.0000055808824003386, 3.9999977081165740932,\n        1.0000004333949319118,\n        2.0675200625006793075e-10, -6.1689554705125681442e-10,\n        1.2436765915401571654e-7, 1.5830429403520613423e-6,\n        4.2947227560776583326e-5, 6.3249861665073441312e-4,\n        0.0079454472840953930811, 0.070994327785661860575,\n        0.44467219586283000332, 1.7774588182255374745,\n        4.0003038986252717972, 3.9998233869142057195,\n        1.0000472932961288324,\n        2.7475684794982708655e-10, -3.8991472076521332023e-9,\n        1.9730170483976049388e-7, 5.9651531561967674521e-7,\n        5.1992971474748995357e-5, 5.7327338675433770752e-4,\n        0.0082293143836530412024, 0.069990934858728039037,\n        0.44726764292723985087, 1.7726685170014087784,\n        4.0062907863712704432, 3.9952750700487845355,\n        1.0016354346654179322\n    };\n    static const double b[70] = {\n        6.7852367144945531383e-8, 4.6266061382821826854e-7,\n        6.9703135812354071774e-6, 7.6637663462953234134e-5,\n        7.9113515222612691636e-4, 0.0073401204731103808981,\n        0.060677114958668837046, 0.43994941411651569622,\n        2.7420017097661750609, 14.289661921740860534,\n        59.820609640320710779, 188.78998681199150629,\n        399.8731367825601118, 427.56411572180478514,\n        1.8042097874891098754e-7, 1.2277164312044637357e-6,\n        1.8484393221474274861e-5, 2.0293995900091309208e-4,\n        0.0020918539850246207459, 0.019375315654033949297,\n        0.15985869016767185908, 1.1565260527420641724,\n        7.1896341224206072113, 37.354773811947484532,\n        155.80993164266268457, 489.5211371158540918,\n        1030.9147225169564806, 1093.5883545113746958,\n        4.8017305613187493564e-7, 3.261317843912380074e-6,\n        4.9073137508166159639e-5, 5.3806506676487583755e-4,\n        0.0055387918291051866561, 0.051223717488786549025,\n        0.42190298621367914765, 3.0463625987357355872,\n        18.895299447327733204, 97.915189029455461554,\n        407.13940115493494659, 1274.3088990480582632,\n        2670.9883037012547506, 2815.7166284662544712,\n        1.2789926338424623394e-6, 8.6718263067604918916e-6,\n        1.3041508821299929489e-4, 0.001428224737372747892,\n        0.014684070635768789378, 0.13561403190404185755,\n        1.1152592585977393953, 8.0387088559465389038,\n        49.761318895895479206, 257.2684232313529138,\n        1066.8543146269566231, 3328.3874581009636362,\n        6948.8586598121634874, 7288.4893398212481055,\n        3.409350368197032893e-6, 2.3079025203103376076e-5,\n        3.4691373283901830239e-4, 0.003794994977222908545,\n        0.038974209677945602145, 0.3594948380414878371,\n        2.9522878893539528226, 21.246564609514287056,\n        131.28727387146173141, 677.38107093296675421,\n        2802.3724744545046518, 8718.5731420798254081,\n        18141.348781638832286, 18948.925349296308859\n    };\n    static const double c[45] = {\n        2.5568678676452702768e-15, 3.0393953792305924324e-14,\n        6.3343751991094840009e-13, 1.5041298011833009649e-11,\n        4.4569436918556541414e-10, 1.746393051427167951e-8,\n        1.0059224011079852317e-6, 1.0729838945088577089e-4,\n        0.05150322693642527738,\n        5.2527963991711562216e-15, 7.202118481421005641e-15,\n        7.2561421229904797156e-13, 1.482312146673104251e-11,\n        4.4602670450376245434e-10, 1.7463600061788679671e-8,\n        1.005922609132234756e-6, 1.0729838937545111487e-4,\n        0.051503226936437300716,\n        1.3365917359358069908e-14, -1.2932643065888544835e-13,\n        1.7450199447905602915e-12, 1.0419051209056979788e-11,\n        4.58047881980598326e-10, 1.7442405450073548966e-8,\n        1.0059461453281292278e-6, 1.0729837434500161228e-4,\n        0.051503226940658446941,\n        5.3771611477352308649e-14, -1.1396193006413731702e-12,\n        1.2858641335221653409e-11, -5.9802086004570057703e-11,\n        7.3666894305929510222e-10, 1.6731837150730356448e-8,\n        1.0070831435812128922e-6, 1.0729733111203704813e-4,\n        0.051503227360726294675,\n        3.7819492084858931093e-14, -4.8600496888588034879e-13,\n        1.6898350504817224909e-12, 4.5884624327524255865e-11,\n        1.2521615963377513729e-10, 1.8959658437754727957e-8,\n        1.0020716710561353622e-6, 1.073037119856927559e-4,\n        0.05150322383300230775\n    };\n\n    w = fabs(x);\n    if (w < 8.5) {\n        t = w * w * 0.0625;\n        k = 13 * ((int) t);\n        y = (((((((((((a[k] * t + a[k + 1]) * t +\n            a[k + 2]) * t + a[k + 3]) * t + a[k + 4]) * t +\n            a[k + 5]) * t + a[k + 6]) * t + a[k + 7]) * t +\n            a[k + 8]) * t + a[k + 9]) * t + a[k + 10]) * t +\n            a[k + 11]) * t + a[k + 12];\n    } else if (w < 12.5) {\n        k = (int) w;\n        t = w - k;\n        k = 14 * (k - 8);\n        y = ((((((((((((b[k] * t + b[k + 1]) * t +\n            b[k + 2]) * t + b[k + 3]) * t + b[k + 4]) * t +\n            b[k + 5]) * t + b[k + 6]) * t + b[k + 7]) * t +\n            b[k + 8]) * t + b[k + 9]) * t + b[k + 10]) * t +\n            b[k + 11]) * t + b[k + 12]) * t + b[k + 13];\n    } else {\n        t = 60 / w;\n        k = 9 * ((int) t);\n        y = ((((((((c[k] * t + c[k + 1]) * t +\n            c[k + 2]) * t + c[k + 3]) * t + c[k + 4]) * t +\n            c[k + 5]) * t + c[k + 6]) * t + c[k + 7]) * t +\n            c[k + 8]) * sqrt(t) * exp(w);\n    }\n    return y;\n}\n\n"
  },
  {
    "path": "plugins/Shibatch/fft.h",
    "content": "#ifndef _DSP_MATH_SHARED_H_\n#define _DSP_MATH_SHARED_H_\n\n#include <math.h>\n\n#pragma warning(disable:4244)\n\n#define PI 3.1415926535897932384626433832795\n\ntemplate<class REAL>\nclass fft\n{\npublic:\n\t/*\n\tFast Fourier/Cosine/Sine Transform\n\t\tdimension   :one\n\t\tdata length :power of 2\n\t\tdecimation  :frequency\n\t\tradix       :split-radix\n\t\tdata        :inplace\n\t\ttable       :use\n\tfunctions\n\t\tcdft: Complex Discrete Fourier Transform\n\t\trdft: Real Discrete Fourier Transform\n\t\tddct: Discrete Cosine Transform\n\t\tddst: Discrete Sine Transform\n\t\tdfct: Cosine Transform of RDFT (Real Symmetric DFT)\n\t\tdfst: Sine Transform of RDFT (Real Anti-symmetric DFT)\n\tfunction prototypes\n\t\tvoid cdft(int, int, REAL *, int *, REAL *);\n\t\tvoid rdft(int, int, REAL *, int *, REAL *);\n\t\tvoid ddct(int, int, REAL *, int *, REAL *);\n\t\tvoid ddst(int, int, REAL *, int *, REAL *);\n\t\tvoid dfct(int, REAL *, REAL *, int *, REAL *);\n\t\tvoid dfst(int, REAL *, REAL *, int *, REAL *);\n\n\n\t-------- Complex DFT (Discrete Fourier Transform) --------\n\t\t[definition]\n\t\t\t<case1>\n\t\t\t\tX[k] = sum_j=0^n-1 x[j]*exp(2*pi*i*j*k/n), 0<=k<n\n\t\t\t<case2>\n\t\t\t\tX[k] = sum_j=0^n-1 x[j]*exp(-2*pi*i*j*k/n), 0<=k<n\n\t\t\t(notes: sum_j=0^n-1 is a summation from j=0 to n-1)\n\t\t[usage]\n\t\t\t<case1>\n\t\t\t\tip[0] = 0; // first time only\n\t\t\t\tcdft(2*n, 1, a, ip, w);\n\t\t\t<case2>\n\t\t\t\tip[0] = 0; // first time only\n\t\t\t\tcdft(2*n, -1, a, ip, w);\n\t\t[parameters]\n\t\t\t2*n            :data length (int)\n\t\t\t\t\t\t\tn >= 1, n = power of 2\n\t\t\ta[0...2*n-1]   :input/output data (REAL *)\n\t\t\t\t\t\t\tinput data\n\t\t\t\t\t\t\t\ta[2*j] = Re(x[j]),\n\t\t\t\t\t\t\t\ta[2*j+1] = Im(x[j]), 0<=j<n\n\t\t\t\t\t\t\toutput data\n\t\t\t\t\t\t\t\ta[2*k] = Re(X[k]),\n\t\t\t\t\t\t\t\ta[2*k+1] = Im(X[k]), 0<=k<n\n\t\t\tip[0...*]      :work area for bit reversal (int *)\n\t\t\t\t\t\t\tlength of ip >= 2+sqrt(n)\n\t\t\t\t\t\t\tstrictly,\n\t\t\t\t\t\t\tlength of ip >=\n\t\t\t\t\t\t\t\t2+(1<<(int)(log(n+0.5)/log(2))/2).\n\t\t\t\t\t\t\tip[0],ip[1] are pointers of the cos/sin table.\n\t\t\tw[0...n/2-1]   :cos/sin table (REAL *)\n\t\t\t\t\t\t\tw[],ip[] are initialized if ip[0] == 0.\n\t\t[remark]\n\t\t\tInverse of\n\t\t\t\tcdft(2*n, -1, a, ip, w);\n\t\t\tis\n\t\t\t\tcdft(2*n, 1, a, ip, w);\n\t\t\t\tfor (j = 0; j <= 2 * n - 1; j++) {\n\t\t\t\t\ta[j] *= 1.0 / n;\n\t\t\t\t}\n\t\t\t.\n\n\n\t-------- Real DFT / Inverse of Real DFT --------\n\t\t[definition]\n\t\t\t<case1> RDFT\n\t\t\t\tR[k] = sum_j=0^n-1 a[j]*cos(2*pi*j*k/n), 0<=k<=n/2\n\t\t\t\tI[k] = sum_j=0^n-1 a[j]*sin(2*pi*j*k/n), 0<k<n/2\n\t\t\t<case2> IRDFT (excluding scale)\n\t\t\t\ta[k] = (R[0] + R[n/2]*cos(pi*k))/2 +\n\t\t\t\t\t   sum_j=1^n/2-1 R[j]*cos(2*pi*j*k/n) +\n\t\t\t\t\t   sum_j=1^n/2-1 I[j]*sin(2*pi*j*k/n), 0<=k<n\n\t\t[usage]\n\t\t\t<case1>\n\t\t\t\tip[0] = 0; // first time only\n\t\t\t\trdft(n, 1, a, ip, w);\n\t\t\t<case2>\n\t\t\t\tip[0] = 0; // first time only\n\t\t\t\trdft(n, -1, a, ip, w);\n\t\t[parameters]\n\t\t\tn              :data length (int)\n\t\t\t\t\t\t\tn >= 2, n = power of 2\n\t\t\ta[0...n-1]     :input/output data (REAL *)\n\t\t\t\t\t\t\t<case1>\n\t\t\t\t\t\t\t\toutput data\n\t\t\t\t\t\t\t\t\ta[2*k] = R[k], 0<=k<n/2\n\t\t\t\t\t\t\t\t\ta[2*k+1] = I[k], 0<k<n/2\n\t\t\t\t\t\t\t\t\ta[1] = R[n/2]\n\t\t\t\t\t\t\t<case2>\n\t\t\t\t\t\t\t\tinput data\n\t\t\t\t\t\t\t\t\ta[2*j] = R[j], 0<=j<n/2\n\t\t\t\t\t\t\t\t\ta[2*j+1] = I[j], 0<j<n/2\n\t\t\t\t\t\t\t\t\ta[1] = R[n/2]\n\t\t\tip[0...*]      :work area for bit reversal (int *)\n\t\t\t\t\t\t\tlength of ip >= 2+sqrt(n/2)\n\t\t\t\t\t\t\tstrictly,\n\t\t\t\t\t\t\tlength of ip >=\n\t\t\t\t\t\t\t\t2+(1<<(int)(log(n/2+0.5)/log(2))/2).\n\t\t\t\t\t\t\tip[0],ip[1] are pointers of the cos/sin table.\n\t\t\tw[0...n/2-1]   :cos/sin table (REAL *)\n\t\t\t\t\t\t\tw[],ip[] are initialized if ip[0] == 0.\n\t\t[remark]\n\t\t\tInverse of\n\t\t\t\trdft(n, 1, a, ip, w);\n\t\t\tis\n\t\t\t\trdft(n, -1, a, ip, w);\n\t\t\t\tfor (j = 0; j <= n - 1; j++) {\n\t\t\t\t\ta[j] *= 2.0 / n;\n\t\t\t\t}\n\t\t\t.\n\n\n\t-------- DCT (Discrete Cosine Transform) / Inverse of DCT --------\n\t\t[definition]\n\t\t\t<case1> IDCT (excluding scale)\n\t\t\t\tC[k] = sum_j=0^n-1 a[j]*cos(pi*j*(k+1/2)/n), 0<=k<n\n\t\t\t<case2> DCT\n\t\t\t\tC[k] = sum_j=0^n-1 a[j]*cos(pi*(j+1/2)*k/n), 0<=k<n\n\t\t[usage]\n\t\t\t<case1>\n\t\t\t\tip[0] = 0; // first time only\n\t\t\t\tddct(n, 1, a, ip, w);\n\t\t\t<case2>\n\t\t\t\tip[0] = 0; // first time only\n\t\t\t\tddct(n, -1, a, ip, w);\n\t\t[parameters]\n\t\t\tn              :data length (int)\n\t\t\t\t\t\t\tn >= 2, n = power of 2\n\t\t\ta[0...n-1]     :input/output data (REAL *)\n\t\t\t\t\t\t\toutput data\n\t\t\t\t\t\t\t\ta[k] = C[k], 0<=k<n\n\t\t\tip[0...*]      :work area for bit reversal (int *)\n\t\t\t\t\t\t\tlength of ip >= 2+sqrt(n/2)\n\t\t\t\t\t\t\tstrictly,\n\t\t\t\t\t\t\tlength of ip >=\n\t\t\t\t\t\t\t\t2+(1<<(int)(log(n/2+0.5)/log(2))/2).\n\t\t\t\t\t\t\tip[0],ip[1] are pointers of the cos/sin table.\n\t\t\tw[0...n*5/4-1] :cos/sin table (REAL *)\n\t\t\t\t\t\t\tw[],ip[] are initialized if ip[0] == 0.\n\t\t[remark]\n\t\t\tInverse of\n\t\t\t\tddct(n, -1, a, ip, w);\n\t\t\tis\n\t\t\t\ta[0] *= 0.5;\n\t\t\t\tddct(n, 1, a, ip, w);\n\t\t\t\tfor (j = 0; j <= n - 1; j++) {\n\t\t\t\t\ta[j] *= 2.0 / n;\n\t\t\t\t}\n\t\t\t.\n\n\n\t-------- DST (Discrete Sine Transform) / Inverse of DST --------\n\t\t[definition]\n\t\t\t<case1> IDST (excluding scale)\n\t\t\t\tS[k] = sum_j=1^n A[j]*sin(pi*j*(k+1/2)/n), 0<=k<n\n\t\t\t<case2> DST\n\t\t\t\tS[k] = sum_j=0^n-1 a[j]*sin(pi*(j+1/2)*k/n), 0<k<=n\n\t\t[usage]\n\t\t\t<case1>\n\t\t\t\tip[0] = 0; // first time only\n\t\t\t\tddst(n, 1, a, ip, w);\n\t\t\t<case2>\n\t\t\t\tip[0] = 0; // first time only\n\t\t\t\tddst(n, -1, a, ip, w);\n\t\t[parameters]\n\t\t\tn              :data length (int)\n\t\t\t\t\t\t\tn >= 2, n = power of 2\n\t\t\ta[0...n-1]     :input/output data (REAL *)\n\t\t\t\t\t\t\t<case1>\n\t\t\t\t\t\t\t\tinput data\n\t\t\t\t\t\t\t\t\ta[j] = A[j], 0<j<n\n\t\t\t\t\t\t\t\t\ta[0] = A[n]\n\t\t\t\t\t\t\t\toutput data\n\t\t\t\t\t\t\t\t\ta[k] = S[k], 0<=k<n\n\t\t\t\t\t\t\t<case2>\n\t\t\t\t\t\t\t\toutput data\n\t\t\t\t\t\t\t\t\ta[k] = S[k], 0<k<n\n\t\t\t\t\t\t\t\t\ta[0] = S[n]\n\t\t\tip[0...*]      :work area for bit reversal (int *)\n\t\t\t\t\t\t\tlength of ip >= 2+sqrt(n/2)\n\t\t\t\t\t\t\tstrictly,\n\t\t\t\t\t\t\tlength of ip >=\n\t\t\t\t\t\t\t\t2+(1<<(int)(log(n/2+0.5)/log(2))/2).\n\t\t\t\t\t\t\tip[0],ip[1] are pointers of the cos/sin table.\n\t\t\tw[0...n*5/4-1] :cos/sin table (REAL *)\n\t\t\t\t\t\t\tw[],ip[] are initialized if ip[0] == 0.\n\t\t[remark]\n\t\t\tInverse of\n\t\t\t\tddst(n, -1, a, ip, w);\n\t\t\tis\n\t\t\t\ta[0] *= 0.5;\n\t\t\t\tddst(n, 1, a, ip, w);\n\t\t\t\tfor (j = 0; j <= n - 1; j++) {\n\t\t\t\t\ta[j] *= 2.0 / n;\n\t\t\t\t}\n\t\t\t.\n\n\n\t-------- Cosine Transform of RDFT (Real Symmetric DFT) --------\n\t\t[definition]\n\t\t\tC[k] = sum_j=0^n a[j]*cos(pi*j*k/n), 0<=k<=n\n\t\t[usage]\n\t\t\tip[0] = 0; // first time only\n\t\t\tdfct(n, a, t, ip, w);\n\t\t[parameters]\n\t\t\tn              :data length - 1 (int)\n\t\t\t\t\t\t\tn >= 2, n = power of 2\n\t\t\ta[0...n]       :input/output data (REAL *)\n\t\t\t\t\t\t\toutput data\n\t\t\t\t\t\t\t\ta[k] = C[k], 0<=k<=n\n\t\t\tt[0...n/2]     :work area (REAL *)\n\t\t\tip[0...*]      :work area for bit reversal (int *)\n\t\t\t\t\t\t\tlength of ip >= 2+sqrt(n/4)\n\t\t\t\t\t\t\tstrictly,\n\t\t\t\t\t\t\tlength of ip >=\n\t\t\t\t\t\t\t\t2+(1<<(int)(log(n/4+0.5)/log(2))/2).\n\t\t\t\t\t\t\tip[0],ip[1] are pointers of the cos/sin table.\n\t\t\tw[0...n*5/8-1] :cos/sin table (REAL *)\n\t\t\t\t\t\t\tw[],ip[] are initialized if ip[0] == 0.\n\t\t[remark]\n\t\t\tInverse of\n\t\t\t\ta[0] *= 0.5;\n\t\t\t\ta[n] *= 0.5;\n\t\t\t\tdfct(n, a, t, ip, w);\n\t\t\tis\n\t\t\t\ta[0] *= 0.5;\n\t\t\t\ta[n] *= 0.5;\n\t\t\t\tdfct(n, a, t, ip, w);\n\t\t\t\tfor (j = 0; j <= n; j++) {\n\t\t\t\t\ta[j] *= 2.0 / n;\n\t\t\t\t}\n\t\t\t.\n\n\n\t-------- Sine Transform of RDFT (Real Anti-symmetric DFT) --------\n\t\t[definition]\n\t\t\tS[k] = sum_j=1^n-1 a[j]*sin(pi*j*k/n), 0<k<n\n\t\t[usage]\n\t\t\tip[0] = 0; // first time only\n\t\t\tdfst(n, a, t, ip, w);\n\t\t[parameters]\n\t\t\tn              :data length + 1 (int)\n\t\t\t\t\t\t\tn >= 2, n = power of 2\n\t\t\ta[0...n-1]     :input/output data (REAL *)\n\t\t\t\t\t\t\toutput data\n\t\t\t\t\t\t\t\ta[k] = S[k], 0<k<n\n\t\t\t\t\t\t\t(a[0] is used for work area)\n\t\t\tt[0...n/2-1]   :work area (REAL *)\n\t\t\tip[0...*]      :work area for bit reversal (int *)\n\t\t\t\t\t\t\tlength of ip >= 2+sqrt(n/4)\n\t\t\t\t\t\t\tstrictly,\n\t\t\t\t\t\t\tlength of ip >=\n\t\t\t\t\t\t\t\t2+(1<<(int)(log(n/4+0.5)/log(2))/2).\n\t\t\t\t\t\t\tip[0],ip[1] are pointers of the cos/sin table.\n\t\t\tw[0...n*5/8-1] :cos/sin table (REAL *)\n\t\t\t\t\t\t\tw[],ip[] are initialized if ip[0] == 0.\n\t\t[remark]\n\t\t\tInverse of\n\t\t\t\tdfst(n, a, t, ip, w);\n\t\t\tis\n\t\t\t\tdfst(n, a, t, ip, w);\n\t\t\t\tfor (j = 1; j <= n - 1; j++) {\n\t\t\t\t\ta[j] *= 2.0 / n;\n\t\t\t\t}\n\t\t\t.\n\n\n\tAppendix :\n\t\tThe cos/sin table is recalculated when the larger table required.\n\t\tw[] and ip[] are compatible with all routines.\n\t*/\n\n\n\tstatic void cdft(int n, int isgn, REAL *a, int *ip, REAL *w)\n\t{\n\t\tint nw;\n\n\t\tnw = ip[0];\n\t\tif (n > (nw << 2)) {\n\t\t\tnw = n >> 2;\n\t\t\tmakewt(nw, ip, w);\n\t\t}\n\t\tif (isgn >= 0) {\n\t\t\tcftfsub(n, a, ip + 2, nw, w);\n\t\t} else {\n\t\t\tcftbsub(n, a, ip + 2, nw, w);\n\t\t}\n\t}\n\n\n\tstatic void rdft(int n, int isgn, REAL *a, int *ip, REAL *w)\n\t{\n\t\tint nw, nc;\n\t\tREAL xi;\n\n\t\tnw = ip[0];\n\t\tif (n > (nw << 2)) {\n\t\t\tnw = n >> 2;\n\t\t\tmakewt(nw, ip, w);\n\t\t}\n\t\tnc = ip[1];\n\t\tif (n > (nc << 2)) {\n\t\t\tnc = n >> 2;\n\t\t\tmakect(nc, ip, w + nw);\n\t\t}\n\t\tif (isgn >= 0) {\n\t\t\tif (n > 4) {\n\t\t\t\tcftfsub(n, a, ip + 2, nw, w);\n\t\t\t\trftfsub(n, a, nc, w + nw);\n\t\t\t} else if (n == 4) {\n\t\t\t\tcftfsub(n, a, ip + 2, nw, w);\n\t\t\t}\n\t\t\txi = a[0] - a[1];\n\t\t\ta[0] += a[1];\n\t\t\ta[1] = xi;\n\t\t} else {\n\t\t\ta[1] = 0.5 * (a[0] - a[1]);\n\t\t\ta[0] -= a[1];\n\t\t\tif (n > 4) {\n\t\t\t\trftbsub(n, a, nc, w + nw);\n\t\t\t\tcftbsub(n, a, ip + 2, nw, w);\n\t\t\t} else if (n == 4) {\n\t\t\t\tcftbsub(n, a, ip + 2, nw, w);\n\t\t\t}\n\t\t}\n\t}\n\n\n\tstatic void ddct(int n, int isgn, REAL *a, int *ip, REAL *w)\n\t{\n\t\tint j, nw, nc;\n\t\tREAL xr;\n\n\t\tnw = ip[0];\n\t\tif (n > (nw << 2)) {\n\t\t\tnw = n >> 2;\n\t\t\tmakewt(nw, ip, w);\n\t\t}\n\t\tnc = ip[1];\n\t\tif (n > nc) {\n\t\t\tnc = n;\n\t\t\tmakect(nc, ip, w + nw);\n\t\t}\n\t\tif (isgn < 0) {\n\t\t\txr = a[n - 1];\n\t\t\tfor (j = n - 2; j >= 2; j -= 2) {\n\t\t\t\ta[j + 1] = a[j] - a[j - 1];\n\t\t\t\ta[j] += a[j - 1];\n\t\t\t}\n\t\t\ta[1] = a[0] - xr;\n\t\t\ta[0] += xr;\n\t\t\tif (n > 4) {\n\t\t\t\trftbsub(n, a, nc, w + nw);\n\t\t\t\tcftbsub(n, a, ip + 2, nw, w);\n\t\t\t} else if (n == 4) {\n\t\t\t\tcftbsub(n, a, ip + 2, nw, w);\n\t\t\t}\n\t\t}\n\t\tdctsub(n, a, nc, w + nw);\n\t\tif (isgn >= 0) {\n\t\t\tif (n > 4) {\n\t\t\t\tcftfsub(n, a, ip + 2, nw, w);\n\t\t\t\trftfsub(n, a, nc, w + nw);\n\t\t\t} else if (n == 4) {\n\t\t\t\tcftfsub(n, a, ip + 2, nw, w);\n\t\t\t}\n\t\t\txr = a[0] - a[1];\n\t\t\ta[0] += a[1];\n\t\t\tfor (j = 2; j < n; j += 2) {\n\t\t\t\ta[j - 1] = a[j] - a[j + 1];\n\t\t\t\ta[j] += a[j + 1];\n\t\t\t}\n\t\t\ta[n - 1] = xr;\n\t\t}\n\t}\n\n\n\tstatic void ddst(int n, int isgn, REAL *a, int *ip, REAL *w)\n\t{\n\t\tint j, nw, nc;\n\t\tREAL xr;\n\n\t\tnw = ip[0];\n\t\tif (n > (nw << 2)) {\n\t\t\tnw = n >> 2;\n\t\t\tmakewt(nw, ip, w);\n\t\t}\n\t\tnc = ip[1];\n\t\tif (n > nc) {\n\t\t\tnc = n;\n\t\t\tmakect(nc, ip, w + nw);\n\t\t}\n\t\tif (isgn < 0) {\n\t\t\txr = a[n - 1];\n\t\t\tfor (j = n - 2; j >= 2; j -= 2) {\n\t\t\t\ta[j + 1] = -a[j] - a[j - 1];\n\t\t\t\ta[j] -= a[j - 1];\n\t\t\t}\n\t\t\ta[1] = a[0] + xr;\n\t\t\ta[0] -= xr;\n\t\t\tif (n > 4) {\n\t\t\t\trftbsub(n, a, nc, w + nw);\n\t\t\t\tcftbsub(n, a, ip + 2, nw, w);\n\t\t\t} else if (n == 4) {\n\t\t\t\tcftbsub(n, a, ip + 2, nw, w);\n\t\t\t}\n\t\t}\n\t\tdstsub(n, a, nc, w + nw);\n\t\tif (isgn >= 0) {\n\t\t\tif (n > 4) {\n\t\t\t\tcftfsub(n, a, ip + 2, nw, w);\n\t\t\t\trftfsub(n, a, nc, w + nw);\n\t\t\t} else if (n == 4) {\n\t\t\t\tcftfsub(n, a, ip + 2, nw, w);\n\t\t\t}\n\t\t\txr = a[0] - a[1];\n\t\t\ta[0] += a[1];\n\t\t\tfor (j = 2; j < n; j += 2) {\n\t\t\t\ta[j - 1] = -a[j] - a[j + 1];\n\t\t\t\ta[j] -= a[j + 1];\n\t\t\t}\n\t\t\ta[n - 1] = -xr;\n\t\t}\n\t}\n\n\n\tstatic void dfct(int n, REAL *a, REAL *t, int *ip, REAL *w)\n\t{\n\t\tint j, k, l, m, mh, nw, nc;\n\t\tREAL xr, xi, yr, yi;\n\n\t\tnw = ip[0];\n\t\tif (n > (nw << 3)) {\n\t\t\tnw = n >> 3;\n\t\t\tmakewt(nw, ip, w);\n\t\t}\n\t\tnc = ip[1];\n\t\tif (n > (nc << 1)) {\n\t\t\tnc = n >> 1;\n\t\t\tmakect(nc, ip, w + nw);\n\t\t}\n\t\tm = n >> 1;\n\t\tyi = a[m];\n\t\txi = a[0] + a[n];\n\t\ta[0] -= a[n];\n\t\tt[0] = xi - yi;\n\t\tt[m] = xi + yi;\n\t\tif (n > 2) {\n\t\t\tmh = m >> 1;\n\t\t\tfor (j = 1; j < mh; j++) {\n\t\t\t\tk = m - j;\n\t\t\t\txr = a[j] - a[n - j];\n\t\t\t\txi = a[j] + a[n - j];\n\t\t\t\tyr = a[k] - a[n - k];\n\t\t\t\tyi = a[k] + a[n - k];\n\t\t\t\ta[j] = xr;\n\t\t\t\ta[k] = yr;\n\t\t\t\tt[j] = xi - yi;\n\t\t\t\tt[k] = xi + yi;\n\t\t\t}\n\t\t\tt[mh] = a[mh] + a[n - mh];\n\t\t\ta[mh] -= a[n - mh];\n\t\t\tdctsub(m, a, nc, w + nw);\n\t\t\tif (m > 4) {\n\t\t\t\tcftfsub(m, a, ip + 2, nw, w);\n\t\t\t\trftfsub(m, a, nc, w + nw);\n\t\t\t} else if (m == 4) {\n\t\t\t\tcftfsub(m, a, ip + 2, nw, w);\n\t\t\t}\n\t\t\ta[n - 1] = a[0] - a[1];\n\t\t\ta[1] = a[0] + a[1];\n\t\t\tfor (j = m - 2; j >= 2; j -= 2) {\n\t\t\t\ta[2 * j + 1] = a[j] + a[j + 1];\n\t\t\t\ta[2 * j - 1] = a[j] - a[j + 1];\n\t\t\t}\n\t\t\tl = 2;\n\t\t\tm = mh;\n\t\t\twhile (m >= 2) {\n\t\t\t\tdctsub(m, t, nc, w + nw);\n\t\t\t\tif (m > 4) {\n\t\t\t\t\tcftfsub(m, t, ip + 2, nw, w);\n\t\t\t\t\trftfsub(m, t, nc, w + nw);\n\t\t\t\t} else if (m == 4) {\n\t\t\t\t\tcftfsub(m, t, ip + 2, nw, w);\n\t\t\t\t}\n\t\t\t\ta[n - l] = t[0] - t[1];\n\t\t\t\ta[l] = t[0] + t[1];\n\t\t\t\tk = 0;\n\t\t\t\tfor (j = 2; j < m; j += 2) {\n\t\t\t\t\tk += l << 2;\n\t\t\t\t\ta[k - l] = t[j] - t[j + 1];\n\t\t\t\t\ta[k + l] = t[j] + t[j + 1];\n\t\t\t\t}\n\t\t\t\tl <<= 1;\n\t\t\t\tmh = m >> 1;\n\t\t\t\tfor (j = 0; j < mh; j++) {\n\t\t\t\t\tk = m - j;\n\t\t\t\t\tt[j] = t[m + k] - t[m + j];\n\t\t\t\t\tt[k] = t[m + k] + t[m + j];\n\t\t\t\t}\n\t\t\t\tt[mh] = t[m + mh];\n\t\t\t\tm = mh;\n\t\t\t}\n\t\t\ta[l] = t[0];\n\t\t\ta[n] = t[2] - t[1];\n\t\t\ta[0] = t[2] + t[1];\n\t\t} else {\n\t\t\ta[1] = a[0];\n\t\t\ta[2] = t[0];\n\t\t\ta[0] = t[1];\n\t\t}\n\t}\n\n\n\tstatic void dfst(int n, REAL *a, REAL *t, int *ip, REAL *w)\n\t{\n\t\tint j, k, l, m, mh, nw, nc;\n\t\tREAL xr, xi, yr, yi;\n\n\t\tnw = ip[0];\n\t\tif (n > (nw << 3)) {\n\t\t\tnw = n >> 3;\n\t\t\tmakewt(nw, ip, w);\n\t\t}\n\t\tnc = ip[1];\n\t\tif (n > (nc << 1)) {\n\t\t\tnc = n >> 1;\n\t\t\tmakect(nc, ip, w + nw);\n\t\t}\n\t\tif (n > 2) {\n\t\t\tm = n >> 1;\n\t\t\tmh = m >> 1;\n\t\t\tfor (j = 1; j < mh; j++) {\n\t\t\t\tk = m - j;\n\t\t\t\txr = a[j] + a[n - j];\n\t\t\t\txi = a[j] - a[n - j];\n\t\t\t\tyr = a[k] + a[n - k];\n\t\t\t\tyi = a[k] - a[n - k];\n\t\t\t\ta[j] = xr;\n\t\t\t\ta[k] = yr;\n\t\t\t\tt[j] = xi + yi;\n\t\t\t\tt[k] = xi - yi;\n\t\t\t}\n\t\t\tt[0] = a[mh] - a[n - mh];\n\t\t\ta[mh] += a[n - mh];\n\t\t\ta[0] = a[m];\n\t\t\tdstsub(m, a, nc, w + nw);\n\t\t\tif (m > 4) {\n\t\t\t\tcftfsub(m, a, ip + 2, nw, w);\n\t\t\t\trftfsub(m, a, nc, w + nw);\n\t\t\t} else if (m == 4) {\n\t\t\t\tcftfsub(m, a, ip + 2, nw, w);\n\t\t\t}\n\t\t\ta[n - 1] = a[1] - a[0];\n\t\t\ta[1] = a[0] + a[1];\n\t\t\tfor (j = m - 2; j >= 2; j -= 2) {\n\t\t\t\ta[2 * j + 1] = a[j] - a[j + 1];\n\t\t\t\ta[2 * j - 1] = -a[j] - a[j + 1];\n\t\t\t}\n\t\t\tl = 2;\n\t\t\tm = mh;\n\t\t\twhile (m >= 2) {\n\t\t\t\tdstsub(m, t, nc, w + nw);\n\t\t\t\tif (m > 4) {\n\t\t\t\t\tcftfsub(m, t, ip + 2, nw, w);\n\t\t\t\t\trftfsub(m, t, nc, w + nw);\n\t\t\t\t} else if (m == 4) {\n\t\t\t\t\tcftfsub(m, t, ip + 2, nw, w);\n\t\t\t\t}\n\t\t\t\ta[n - l] = t[1] - t[0];\n\t\t\t\ta[l] = t[0] + t[1];\n\t\t\t\tk = 0;\n\t\t\t\tfor (j = 2; j < m; j += 2) {\n\t\t\t\t\tk += l << 2;\n\t\t\t\t\ta[k - l] = -t[j] - t[j + 1];\n\t\t\t\t\ta[k + l] = t[j] - t[j + 1];\n\t\t\t\t}\n\t\t\t\tl <<= 1;\n\t\t\t\tmh = m >> 1;\n\t\t\t\tfor (j = 1; j < mh; j++) {\n\t\t\t\t\tk = m - j;\n\t\t\t\t\tt[j] = t[m + k] + t[m + j];\n\t\t\t\t\tt[k] = t[m + k] - t[m + j];\n\t\t\t\t}\n\t\t\t\tt[0] = t[m + mh];\n\t\t\t\tm = mh;\n\t\t\t}\n\t\t\ta[l] = t[0];\n\t\t}\n\t\ta[0] = 0;\n\t}\n\n\n\n\tstatic void makewt(int nw, int *ip, REAL *w)\n\t{\n\t\tint j, nwh, nw0, nw1;\n\t\tREAL delta, wn4r, wk1r, wk1i, wk3r, wk3i;\n\n\t\tip[0] = nw;\n\t\tip[1] = 1;\n\t\tif (nw > 2) {\n\t\t\tnwh = nw >> 1;\n\t\t\tdelta = atan(1.0) / nwh;\n\t\t\twn4r = cos(delta * nwh);\n\t\t\tw[0] = 1;\n\t\t\tw[1] = wn4r;\n\t\t\tif (nwh >= 4) {\n\t\t\t\tw[2] = 0.5 / cos(delta * 2);\n\t\t\t\tw[3] = 0.5 / cos(delta * 6);\n\t\t\t}\n\t\t\tfor (j = 4; j < nwh; j += 4) {\n\t\t\t\tw[j] = cos(delta * j);\n\t\t\t\tw[j + 1] = sin(delta * j);\n\t\t\t\tw[j + 2] = cos(3 * delta * j);\n\t\t\t\tw[j + 3] = sin(3 * delta * j);\n\t\t\t}\n\t\t\tnw0 = 0;\n\t\t\twhile (nwh > 2) {\n\t\t\t\tnw1 = nw0 + nwh;\n\t\t\t\tnwh >>= 1;\n\t\t\t\tw[nw1] = 1;\n\t\t\t\tw[nw1 + 1] = wn4r;\n\t\t\t\tif (nwh >= 4) {\n\t\t\t\t\twk1r = w[nw0 + 4];\n\t\t\t\t\twk3r = w[nw0 + 6];\n\t\t\t\t\tw[nw1 + 2] = 0.5 / wk1r;\n\t\t\t\t\tw[nw1 + 3] = 0.5 / wk3r;\n\t\t\t\t}\n\t\t\t\tfor (j = 4; j < nwh; j += 4) {\n\t\t\t\t\twk1r = w[nw0 + 2 * j];\n\t\t\t\t\twk1i = w[nw0 + 2 * j + 1];\n\t\t\t\t\twk3r = w[nw0 + 2 * j + 2];\n\t\t\t\t\twk3i = w[nw0 + 2 * j + 3];\n\t\t\t\t\tw[nw1 + j] = wk1r;\n\t\t\t\t\tw[nw1 + j + 1] = wk1i;\n\t\t\t\t\tw[nw1 + j + 2] = wk3r;\n\t\t\t\t\tw[nw1 + j + 3] = wk3i;\n\t\t\t\t}\n\t\t\t\tnw0 = nw1;\n\t\t\t}\n\t\t}\n\t}\n\n\n\tstatic void makect(int nc, int *ip, REAL *c)\n\t{\n\t\tint j, nch;\n\t\tREAL delta;\n\n\t\tip[1] = nc;\n\t\tif (nc > 1) {\n\t\t\tnch = nc >> 1;\n\t\t\tdelta = atan(1.0) / nch;\n\t\t\tc[0] = cos(delta * nch);\n\t\t\tc[nch] = 0.5 * c[0];\n\t\t\tfor (j = 1; j < nch; j++) {\n\t\t\t\tc[j] = 0.5 * cos(delta * j);\n\t\t\t\tc[nc - j] = 0.5 * sin(delta * j);\n\t\t\t}\n\t\t}\n\t}\n\n\n\t/* -------- child routines -------- */\n\n\n\t#ifndef CDFT_RECURSIVE_N  /* length of the recursive FFT mode */\n\t#define CDFT_RECURSIVE_N 512  /* <= (L1 cache size) / 16 */\n\t#endif\n\n\n\tstatic void cftfsub(int n, REAL *a, int *ip, int nw, REAL *w)\n\t{\n\t\tint m;\n\n\t\tif (n > 32) {\n\t\t\tm = n >> 2;\n\t\t\tcftf1st(n, a, &w[nw - m]);\n\t\t\tif (n > CDFT_RECURSIVE_N) {\n\t\t\t\tcftrec1(m, a, nw, w);\n\t\t\t\tcftrec2(m, &a[m], nw, w);\n\t\t\t\tcftrec1(m, &a[2 * m], nw, w);\n\t\t\t\tcftrec1(m, &a[3 * m], nw, w);\n\t\t\t} else if (m > 32) {\n\t\t\t\tcftexp1(n, a, nw, w);\n\t\t\t} else {\n\t\t\t\tcftfx41(n, a, nw, w);\n\t\t\t}\n\t\t\tbitrv2(n, ip, a);\n\t\t} else if (n > 8) {\n\t\t\tif (n == 32) {\n\t\t\t\tcftf161(a, &w[nw - 8]);\n\t\t\t\tbitrv216(a);\n\t\t\t} else {\n\t\t\t\tcftf081(a, w);\n\t\t\t\tbitrv208(a);\n\t\t\t}\n\t\t} else if (n == 8) {\n\t\t\tcftf040(a);\n\t\t} else if (n == 4) {\n\t\t\tcftx020(a);\n\t\t}\n\t}\n\n\n\tstatic void cftbsub(int n, REAL *a, int *ip, int nw, REAL *w)\n\t{\n\t\tint m;\n\n\t\tif (n > 32) {\n\t\t\tm = n >> 2;\n\t\t\tcftb1st(n, a, &w[nw - m]);\n\t\t\tif (n > CDFT_RECURSIVE_N) {\n\t\t\t\tcftrec1(m, a, nw, w);\n\t\t\t\tcftrec2(m, &a[m], nw, w);\n\t\t\t\tcftrec1(m, &a[2 * m], nw, w);\n\t\t\t\tcftrec1(m, &a[3 * m], nw, w);\n\t\t\t} else if (m > 32) {\n\t\t\t\tcftexp1(n, a, nw, w);\n\t\t\t} else {\n\t\t\t\tcftfx41(n, a, nw, w);\n\t\t\t}\n\t\t\tbitrv2conj(n, ip, a);\n\t\t} else if (n > 8) {\n\t\t\tif (n == 32) {\n\t\t\t\tcftf161(a, &w[nw - 8]);\n\t\t\t\tbitrv216neg(a);\n\t\t\t} else {\n\t\t\t\tcftf081(a, w);\n\t\t\t\tbitrv208neg(a);\n\t\t\t}\n\t\t} else if (n == 8) {\n\t\t\tcftb040(a);\n\t\t} else if (n == 4) {\n\t\t\tcftx020(a);\n\t\t}\n\t}\n\n\n\tstatic void bitrv2(int n, int *ip, REAL *a)\n\t{\n\t\tint j, j1, k, k1, l, m, m2;\n\t\tREAL xr, xi, yr, yi;\n\n\t\tip[0] = 0;\n\t\tl = n;\n\t\tm = 1;\n\t\twhile ((m << 3) < l) {\n\t\t\tl >>= 1;\n\t\t\tfor (j = 0; j < m; j++) {\n\t\t\t\tip[m + j] = ip[j] + l;\n\t\t\t}\n\t\t\tm <<= 1;\n\t\t}\n\t\tm2 = 2 * m;\n\t\tif ((m << 3) == l) {\n\t\t\tfor (k = 0; k < m; k++) {\n\t\t\t\tfor (j = 0; j < k; j++) {\n\t\t\t\t\tj1 = 2 * j + ip[k];\n\t\t\t\t\tk1 = 2 * k + ip[j];\n\t\t\t\t\txr = a[j1];\n\t\t\t\t\txi = a[j1 + 1];\n\t\t\t\t\tyr = a[k1];\n\t\t\t\t\tyi = a[k1 + 1];\n\t\t\t\t\ta[j1] = yr;\n\t\t\t\t\ta[j1 + 1] = yi;\n\t\t\t\t\ta[k1] = xr;\n\t\t\t\t\ta[k1 + 1] = xi;\n\t\t\t\t\tj1 += m2;\n\t\t\t\t\tk1 += 2 * m2;\n\t\t\t\t\txr = a[j1];\n\t\t\t\t\txi = a[j1 + 1];\n\t\t\t\t\tyr = a[k1];\n\t\t\t\t\tyi = a[k1 + 1];\n\t\t\t\t\ta[j1] = yr;\n\t\t\t\t\ta[j1 + 1] = yi;\n\t\t\t\t\ta[k1] = xr;\n\t\t\t\t\ta[k1 + 1] = xi;\n\t\t\t\t\tj1 += m2;\n\t\t\t\t\tk1 -= m2;\n\t\t\t\t\txr = a[j1];\n\t\t\t\t\txi = a[j1 + 1];\n\t\t\t\t\tyr = a[k1];\n\t\t\t\t\tyi = a[k1 + 1];\n\t\t\t\t\ta[j1] = yr;\n\t\t\t\t\ta[j1 + 1] = yi;\n\t\t\t\t\ta[k1] = xr;\n\t\t\t\t\ta[k1 + 1] = xi;\n\t\t\t\t\tj1 += m2;\n\t\t\t\t\tk1 += 2 * m2;\n\t\t\t\t\txr = a[j1];\n\t\t\t\t\txi = a[j1 + 1];\n\t\t\t\t\tyr = a[k1];\n\t\t\t\t\tyi = a[k1 + 1];\n\t\t\t\t\ta[j1] = yr;\n\t\t\t\t\ta[j1 + 1] = yi;\n\t\t\t\t\ta[k1] = xr;\n\t\t\t\t\ta[k1 + 1] = xi;\n\t\t\t\t}\n\t\t\t\tj1 = 2 * k + m2 + ip[k];\n\t\t\t\tk1 = j1 + m2;\n\t\t\t\txr = a[j1];\n\t\t\t\txi = a[j1 + 1];\n\t\t\t\tyr = a[k1];\n\t\t\t\tyi = a[k1 + 1];\n\t\t\t\ta[j1] = yr;\n\t\t\t\ta[j1 + 1] = yi;\n\t\t\t\ta[k1] = xr;\n\t\t\t\ta[k1 + 1] = xi;\n\t\t\t}\n\t\t} else {\n\t\t\tfor (k = 1; k < m; k++) {\n\t\t\t\tfor (j = 0; j < k; j++) {\n\t\t\t\t\tj1 = 2 * j + ip[k];\n\t\t\t\t\tk1 = 2 * k + ip[j];\n\t\t\t\t\txr = a[j1];\n\t\t\t\t\txi = a[j1 + 1];\n\t\t\t\t\tyr = a[k1];\n\t\t\t\t\tyi = a[k1 + 1];\n\t\t\t\t\ta[j1] = yr;\n\t\t\t\t\ta[j1 + 1] = yi;\n\t\t\t\t\ta[k1] = xr;\n\t\t\t\t\ta[k1 + 1] = xi;\n\t\t\t\t\tj1 += m2;\n\t\t\t\t\tk1 += m2;\n\t\t\t\t\txr = a[j1];\n\t\t\t\t\txi = a[j1 + 1];\n\t\t\t\t\tyr = a[k1];\n\t\t\t\t\tyi = a[k1 + 1];\n\t\t\t\t\ta[j1] = yr;\n\t\t\t\t\ta[j1 + 1] = yi;\n\t\t\t\t\ta[k1] = xr;\n\t\t\t\t\ta[k1 + 1] = xi;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\n\tstatic void bitrv2conj(int n, int *ip, REAL *a)\n\t{\n\t\tint j, j1, k, k1, l, m, m2;\n\t\tREAL xr, xi, yr, yi;\n\n\t\tip[0] = 0;\n\t\tl = n;\n\t\tm = 1;\n\t\twhile ((m << 3) < l) {\n\t\t\tl >>= 1;\n\t\t\tfor (j = 0; j < m; j++) {\n\t\t\t\tip[m + j] = ip[j] + l;\n\t\t\t}\n\t\t\tm <<= 1;\n\t\t}\n\t\tm2 = 2 * m;\n\t\tif ((m << 3) == l) {\n\t\t\tfor (k = 0; k < m; k++) {\n\t\t\t\tfor (j = 0; j < k; j++) {\n\t\t\t\t\tj1 = 2 * j + ip[k];\n\t\t\t\t\tk1 = 2 * k + ip[j];\n\t\t\t\t\txr = a[j1];\n\t\t\t\t\txi = -a[j1 + 1];\n\t\t\t\t\tyr = a[k1];\n\t\t\t\t\tyi = -a[k1 + 1];\n\t\t\t\t\ta[j1] = yr;\n\t\t\t\t\ta[j1 + 1] = yi;\n\t\t\t\t\ta[k1] = xr;\n\t\t\t\t\ta[k1 + 1] = xi;\n\t\t\t\t\tj1 += m2;\n\t\t\t\t\tk1 += 2 * m2;\n\t\t\t\t\txr = a[j1];\n\t\t\t\t\txi = -a[j1 + 1];\n\t\t\t\t\tyr = a[k1];\n\t\t\t\t\tyi = -a[k1 + 1];\n\t\t\t\t\ta[j1] = yr;\n\t\t\t\t\ta[j1 + 1] = yi;\n\t\t\t\t\ta[k1] = xr;\n\t\t\t\t\ta[k1 + 1] = xi;\n\t\t\t\t\tj1 += m2;\n\t\t\t\t\tk1 -= m2;\n\t\t\t\t\txr = a[j1];\n\t\t\t\t\txi = -a[j1 + 1];\n\t\t\t\t\tyr = a[k1];\n\t\t\t\t\tyi = -a[k1 + 1];\n\t\t\t\t\ta[j1] = yr;\n\t\t\t\t\ta[j1 + 1] = yi;\n\t\t\t\t\ta[k1] = xr;\n\t\t\t\t\ta[k1 + 1] = xi;\n\t\t\t\t\tj1 += m2;\n\t\t\t\t\tk1 += 2 * m2;\n\t\t\t\t\txr = a[j1];\n\t\t\t\t\txi = -a[j1 + 1];\n\t\t\t\t\tyr = a[k1];\n\t\t\t\t\tyi = -a[k1 + 1];\n\t\t\t\t\ta[j1] = yr;\n\t\t\t\t\ta[j1 + 1] = yi;\n\t\t\t\t\ta[k1] = xr;\n\t\t\t\t\ta[k1 + 1] = xi;\n\t\t\t\t}\n\t\t\t\tk1 = 2 * k + ip[k];\n\t\t\t\ta[k1 + 1] = -a[k1 + 1];\n\t\t\t\tj1 = k1 + m2;\n\t\t\t\tk1 = j1 + m2;\n\t\t\t\txr = a[j1];\n\t\t\t\txi = -a[j1 + 1];\n\t\t\t\tyr = a[k1];\n\t\t\t\tyi = -a[k1 + 1];\n\t\t\t\ta[j1] = yr;\n\t\t\t\ta[j1 + 1] = yi;\n\t\t\t\ta[k1] = xr;\n\t\t\t\ta[k1 + 1] = xi;\n\t\t\t\tk1 += m2;\n\t\t\t\ta[k1 + 1] = -a[k1 + 1];\n\t\t\t}\n\t\t} else {\n\t\t\ta[1] = -a[1];\n\t\t\ta[m2 + 1] = -a[m2 + 1];\n\t\t\tfor (k = 1; k < m; k++) {\n\t\t\t\tfor (j = 0; j < k; j++) {\n\t\t\t\t\tj1 = 2 * j + ip[k];\n\t\t\t\t\tk1 = 2 * k + ip[j];\n\t\t\t\t\txr = a[j1];\n\t\t\t\t\txi = -a[j1 + 1];\n\t\t\t\t\tyr = a[k1];\n\t\t\t\t\tyi = -a[k1 + 1];\n\t\t\t\t\ta[j1] = yr;\n\t\t\t\t\ta[j1 + 1] = yi;\n\t\t\t\t\ta[k1] = xr;\n\t\t\t\t\ta[k1 + 1] = xi;\n\t\t\t\t\tj1 += m2;\n\t\t\t\t\tk1 += m2;\n\t\t\t\t\txr = a[j1];\n\t\t\t\t\txi = -a[j1 + 1];\n\t\t\t\t\tyr = a[k1];\n\t\t\t\t\tyi = -a[k1 + 1];\n\t\t\t\t\ta[j1] = yr;\n\t\t\t\t\ta[j1 + 1] = yi;\n\t\t\t\t\ta[k1] = xr;\n\t\t\t\t\ta[k1 + 1] = xi;\n\t\t\t\t}\n\t\t\t\tk1 = 2 * k + ip[k];\n\t\t\t\ta[k1 + 1] = -a[k1 + 1];\n\t\t\t\ta[k1 + m2 + 1] = -a[k1 + m2 + 1];\n\t\t\t}\n\t\t}\n\t}\n\n\n\tstatic void bitrv216(REAL *a)\n\t{\n\t\tREAL x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i,\n\t\t\tx5r, x5i, x7r, x7i, x8r, x8i, x10r, x10i,\n\t\t\tx11r, x11i, x12r, x12i, x13r, x13i, x14r, x14i;\n\n\t\tx1r = a[2];\n\t\tx1i = a[3];\n\t\tx2r = a[4];\n\t\tx2i = a[5];\n\t\tx3r = a[6];\n\t\tx3i = a[7];\n\t\tx4r = a[8];\n\t\tx4i = a[9];\n\t\tx5r = a[10];\n\t\tx5i = a[11];\n\t\tx7r = a[14];\n\t\tx7i = a[15];\n\t\tx8r = a[16];\n\t\tx8i = a[17];\n\t\tx10r = a[20];\n\t\tx10i = a[21];\n\t\tx11r = a[22];\n\t\tx11i = a[23];\n\t\tx12r = a[24];\n\t\tx12i = a[25];\n\t\tx13r = a[26];\n\t\tx13i = a[27];\n\t\tx14r = a[28];\n\t\tx14i = a[29];\n\t\ta[2] = x8r;\n\t\ta[3] = x8i;\n\t\ta[4] = x4r;\n\t\ta[5] = x4i;\n\t\ta[6] = x12r;\n\t\ta[7] = x12i;\n\t\ta[8] = x2r;\n\t\ta[9] = x2i;\n\t\ta[10] = x10r;\n\t\ta[11] = x10i;\n\t\ta[14] = x14r;\n\t\ta[15] = x14i;\n\t\ta[16] = x1r;\n\t\ta[17] = x1i;\n\t\ta[20] = x5r;\n\t\ta[21] = x5i;\n\t\ta[22] = x13r;\n\t\ta[23] = x13i;\n\t\ta[24] = x3r;\n\t\ta[25] = x3i;\n\t\ta[26] = x11r;\n\t\ta[27] = x11i;\n\t\ta[28] = x7r;\n\t\ta[29] = x7i;\n\t}\n\n\n\tstatic void bitrv216neg(REAL *a)\n\t{\n\t\tREAL x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i,\n\t\t\tx5r, x5i, x6r, x6i, x7r, x7i, x8r, x8i,\n\t\t\tx9r, x9i, x10r, x10i, x11r, x11i, x12r, x12i,\n\t\t\tx13r, x13i, x14r, x14i, x15r, x15i;\n\n\t\tx1r = a[2];\n\t\tx1i = a[3];\n\t\tx2r = a[4];\n\t\tx2i = a[5];\n\t\tx3r = a[6];\n\t\tx3i = a[7];\n\t\tx4r = a[8];\n\t\tx4i = a[9];\n\t\tx5r = a[10];\n\t\tx5i = a[11];\n\t\tx6r = a[12];\n\t\tx6i = a[13];\n\t\tx7r = a[14];\n\t\tx7i = a[15];\n\t\tx8r = a[16];\n\t\tx8i = a[17];\n\t\tx9r = a[18];\n\t\tx9i = a[19];\n\t\tx10r = a[20];\n\t\tx10i = a[21];\n\t\tx11r = a[22];\n\t\tx11i = a[23];\n\t\tx12r = a[24];\n\t\tx12i = a[25];\n\t\tx13r = a[26];\n\t\tx13i = a[27];\n\t\tx14r = a[28];\n\t\tx14i = a[29];\n\t\tx15r = a[30];\n\t\tx15i = a[31];\n\t\ta[2] = x15r;\n\t\ta[3] = x15i;\n\t\ta[4] = x7r;\n\t\ta[5] = x7i;\n\t\ta[6] = x11r;\n\t\ta[7] = x11i;\n\t\ta[8] = x3r;\n\t\ta[9] = x3i;\n\t\ta[10] = x13r;\n\t\ta[11] = x13i;\n\t\ta[12] = x5r;\n\t\ta[13] = x5i;\n\t\ta[14] = x9r;\n\t\ta[15] = x9i;\n\t\ta[16] = x1r;\n\t\ta[17] = x1i;\n\t\ta[18] = x14r;\n\t\ta[19] = x14i;\n\t\ta[20] = x6r;\n\t\ta[21] = x6i;\n\t\ta[22] = x10r;\n\t\ta[23] = x10i;\n\t\ta[24] = x2r;\n\t\ta[25] = x2i;\n\t\ta[26] = x12r;\n\t\ta[27] = x12i;\n\t\ta[28] = x4r;\n\t\ta[29] = x4i;\n\t\ta[30] = x8r;\n\t\ta[31] = x8i;\n\t}\n\n\n\tstatic void bitrv208(REAL *a)\n\t{\n\t\tREAL x1r, x1i, x3r, x3i, x4r, x4i, x6r, x6i;\n\n\t\tx1r = a[2];\n\t\tx1i = a[3];\n\t\tx3r = a[6];\n\t\tx3i = a[7];\n\t\tx4r = a[8];\n\t\tx4i = a[9];\n\t\tx6r = a[12];\n\t\tx6i = a[13];\n\t\ta[2] = x4r;\n\t\ta[3] = x4i;\n\t\ta[6] = x6r;\n\t\ta[7] = x6i;\n\t\ta[8] = x1r;\n\t\ta[9] = x1i;\n\t\ta[12] = x3r;\n\t\ta[13] = x3i;\n\t}\n\n\n\tstatic void bitrv208neg(REAL *a)\n\t{\n\t\tREAL x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i,\n\t\t\tx5r, x5i, x6r, x6i, x7r, x7i;\n\n\t\tx1r = a[2];\n\t\tx1i = a[3];\n\t\tx2r = a[4];\n\t\tx2i = a[5];\n\t\tx3r = a[6];\n\t\tx3i = a[7];\n\t\tx4r = a[8];\n\t\tx4i = a[9];\n\t\tx5r = a[10];\n\t\tx5i = a[11];\n\t\tx6r = a[12];\n\t\tx6i = a[13];\n\t\tx7r = a[14];\n\t\tx7i = a[15];\n\t\ta[2] = x7r;\n\t\ta[3] = x7i;\n\t\ta[4] = x3r;\n\t\ta[5] = x3i;\n\t\ta[6] = x5r;\n\t\ta[7] = x5i;\n\t\ta[8] = x1r;\n\t\ta[9] = x1i;\n\t\ta[10] = x6r;\n\t\ta[11] = x6i;\n\t\ta[12] = x2r;\n\t\ta[13] = x2i;\n\t\ta[14] = x4r;\n\t\ta[15] = x4i;\n\t}\n\n\n\tstatic void cftf1st(int n, REAL *a, REAL *w)\n\t{\n\t\tint j, j0, j1, j2, j3, k, m, mh;\n\t\tREAL wn4r, csc1, csc3, wk1r, wk1i, wk3r, wk3i,\n\t\t\twd1r, wd1i, wd3r, wd3i;\n\t\tREAL x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i,\n\t\t\ty0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i;\n\n\t\tmh = n >> 3;\n\t\tm = 2 * mh;\n\t\tj1 = m;\n\t\tj2 = j1 + m;\n\t\tj3 = j2 + m;\n\t\tx0r = a[0] + a[j2];\n\t\tx0i = a[1] + a[j2 + 1];\n\t\tx1r = a[0] - a[j2];\n\t\tx1i = a[1] - a[j2 + 1];\n\t\tx2r = a[j1] + a[j3];\n\t\tx2i = a[j1 + 1] + a[j3 + 1];\n\t\tx3r = a[j1] - a[j3];\n\t\tx3i = a[j1 + 1] - a[j3 + 1];\n\t\ta[0] = x0r + x2r;\n\t\ta[1] = x0i + x2i;\n\t\ta[j1] = x0r - x2r;\n\t\ta[j1 + 1] = x0i - x2i;\n\t\ta[j2] = x1r - x3i;\n\t\ta[j2 + 1] = x1i + x3r;\n\t\ta[j3] = x1r + x3i;\n\t\ta[j3 + 1] = x1i - x3r;\n\t\twn4r = w[1];\n\t\tcsc1 = w[2];\n\t\tcsc3 = w[3];\n\t\twd1r = 1;\n\t\twd1i = 0;\n\t\twd3r = 1;\n\t\twd3i = 0;\n\t\tk = 0;\n\t\tfor (j = 2; j < mh - 2; j += 4) {\n\t\t\tk += 4;\n\t\t\twk1r = csc1 * (wd1r + w[k]);\n\t\t\twk1i = csc1 * (wd1i + w[k + 1]);\n\t\t\twk3r = csc3 * (wd3r + w[k + 2]);\n\t\t\twk3i = csc3 * (wd3i - w[k + 3]);\n\t\t\twd1r = w[k];\n\t\t\twd1i = w[k + 1];\n\t\t\twd3r = w[k + 2];\n\t\t\twd3i = -w[k + 3];\n\t\t\tj1 = j + m;\n\t\t\tj2 = j1 + m;\n\t\t\tj3 = j2 + m;\n\t\t\tx0r = a[j] + a[j2];\n\t\t\tx0i = a[j + 1] + a[j2 + 1];\n\t\t\tx1r = a[j] - a[j2];\n\t\t\tx1i = a[j + 1] - a[j2 + 1];\n\t\t\ty0r = a[j + 2] + a[j2 + 2];\n\t\t\ty0i = a[j + 3] + a[j2 + 3];\n\t\t\ty1r = a[j + 2] - a[j2 + 2];\n\t\t\ty1i = a[j + 3] - a[j2 + 3];\n\t\t\tx2r = a[j1] + a[j3];\n\t\t\tx2i = a[j1 + 1] + a[j3 + 1];\n\t\t\tx3r = a[j1] - a[j3];\n\t\t\tx3i = a[j1 + 1] - a[j3 + 1];\n\t\t\ty2r = a[j1 + 2] + a[j3 + 2];\n\t\t\ty2i = a[j1 + 3] + a[j3 + 3];\n\t\t\ty3r = a[j1 + 2] - a[j3 + 2];\n\t\t\ty3i = a[j1 + 3] - a[j3 + 3];\n\t\t\ta[j] = x0r + x2r;\n\t\t\ta[j + 1] = x0i + x2i;\n\t\t\ta[j + 2] = y0r + y2r;\n\t\t\ta[j + 3] = y0i + y2i;\n\t\t\ta[j1] = x0r - x2r;\n\t\t\ta[j1 + 1] = x0i - x2i;\n\t\t\ta[j1 + 2] = y0r - y2r;\n\t\t\ta[j1 + 3] = y0i - y2i;\n\t\t\tx0r = x1r - x3i;\n\t\t\tx0i = x1i + x3r;\n\t\t\ta[j2] = wk1r * x0r - wk1i * x0i;\n\t\t\ta[j2 + 1] = wk1r * x0i + wk1i * x0r;\n\t\t\tx0r = y1r - y3i;\n\t\t\tx0i = y1i + y3r;\n\t\t\ta[j2 + 2] = wd1r * x0r - wd1i * x0i;\n\t\t\ta[j2 + 3] = wd1r * x0i + wd1i * x0r;\n\t\t\tx0r = x1r + x3i;\n\t\t\tx0i = x1i - x3r;\n\t\t\ta[j3] = wk3r * x0r + wk3i * x0i;\n\t\t\ta[j3 + 1] = wk3r * x0i - wk3i * x0r;\n\t\t\tx0r = y1r + y3i;\n\t\t\tx0i = y1i - y3r;\n\t\t\ta[j3 + 2] = wd3r * x0r + wd3i * x0i;\n\t\t\ta[j3 + 3] = wd3r * x0i - wd3i * x0r;\n\t\t\tj0 = m - j;\n\t\t\tj1 = j0 + m;\n\t\t\tj2 = j1 + m;\n\t\t\tj3 = j2 + m;\n\t\t\tx0r = a[j0] + a[j2];\n\t\t\tx0i = a[j0 + 1] + a[j2 + 1];\n\t\t\tx1r = a[j0] - a[j2];\n\t\t\tx1i = a[j0 + 1] - a[j2 + 1];\n\t\t\ty0r = a[j0 - 2] + a[j2 - 2];\n\t\t\ty0i = a[j0 - 1] + a[j2 - 1];\n\t\t\ty1r = a[j0 - 2] - a[j2 - 2];\n\t\t\ty1i = a[j0 - 1] - a[j2 - 1];\n\t\t\tx2r = a[j1] + a[j3];\n\t\t\tx2i = a[j1 + 1] + a[j3 + 1];\n\t\t\tx3r = a[j1] - a[j3];\n\t\t\tx3i = a[j1 + 1] - a[j3 + 1];\n\t\t\ty2r = a[j1 - 2] + a[j3 - 2];\n\t\t\ty2i = a[j1 - 1] + a[j3 - 1];\n\t\t\ty3r = a[j1 - 2] - a[j3 - 2];\n\t\t\ty3i = a[j1 - 1] - a[j3 - 1];\n\t\t\ta[j0] = x0r + x2r;\n\t\t\ta[j0 + 1] = x0i + x2i;\n\t\t\ta[j0 - 2] = y0r + y2r;\n\t\t\ta[j0 - 1] = y0i + y2i;\n\t\t\ta[j1] = x0r - x2r;\n\t\t\ta[j1 + 1] = x0i - x2i;\n\t\t\ta[j1 - 2] = y0r - y2r;\n\t\t\ta[j1 - 1] = y0i - y2i;\n\t\t\tx0r = x1r - x3i;\n\t\t\tx0i = x1i + x3r;\n\t\t\ta[j2] = wk1i * x0r - wk1r * x0i;\n\t\t\ta[j2 + 1] = wk1i * x0i + wk1r * x0r;\n\t\t\tx0r = y1r - y3i;\n\t\t\tx0i = y1i + y3r;\n\t\t\ta[j2 - 2] = wd1i * x0r - wd1r * x0i;\n\t\t\ta[j2 - 1] = wd1i * x0i + wd1r * x0r;\n\t\t\tx0r = x1r + x3i;\n\t\t\tx0i = x1i - x3r;\n\t\t\ta[j3] = wk3i * x0r + wk3r * x0i;\n\t\t\ta[j3 + 1] = wk3i * x0i - wk3r * x0r;\n\t\t\tx0r = y1r + y3i;\n\t\t\tx0i = y1i - y3r;\n\t\t\ta[j3 - 2] = wd3i * x0r + wd3r * x0i;\n\t\t\ta[j3 - 1] = wd3i * x0i - wd3r * x0r;\n\t\t}\n\t\twk1r = csc1 * (wd1r + wn4r);\n\t\twk1i = csc1 * (wd1i + wn4r);\n\t\twk3r = csc3 * (wd3r - wn4r);\n\t\twk3i = csc3 * (wd3i - wn4r);\n\t\tj0 = mh;\n\t\tj1 = j0 + m;\n\t\tj2 = j1 + m;\n\t\tj3 = j2 + m;\n\t\tx0r = a[j0 - 2] + a[j2 - 2];\n\t\tx0i = a[j0 - 1] + a[j2 - 1];\n\t\tx1r = a[j0 - 2] - a[j2 - 2];\n\t\tx1i = a[j0 - 1] - a[j2 - 1];\n\t\tx2r = a[j1 - 2] + a[j3 - 2];\n\t\tx2i = a[j1 - 1] + a[j3 - 1];\n\t\tx3r = a[j1 - 2] - a[j3 - 2];\n\t\tx3i = a[j1 - 1] - a[j3 - 1];\n\t\ta[j0 - 2] = x0r + x2r;\n\t\ta[j0 - 1] = x0i + x2i;\n\t\ta[j1 - 2] = x0r - x2r;\n\t\ta[j1 - 1] = x0i - x2i;\n\t\tx0r = x1r - x3i;\n\t\tx0i = x1i + x3r;\n\t\ta[j2 - 2] = wk1r * x0r - wk1i * x0i;\n\t\ta[j2 - 1] = wk1r * x0i + wk1i * x0r;\n\t\tx0r = x1r + x3i;\n\t\tx0i = x1i - x3r;\n\t\ta[j3 - 2] = wk3r * x0r + wk3i * x0i;\n\t\ta[j3 - 1] = wk3r * x0i - wk3i * x0r;\n\t\tx0r = a[j0] + a[j2];\n\t\tx0i = a[j0 + 1] + a[j2 + 1];\n\t\tx1r = a[j0] - a[j2];\n\t\tx1i = a[j0 + 1] - a[j2 + 1];\n\t\tx2r = a[j1] + a[j3];\n\t\tx2i = a[j1 + 1] + a[j3 + 1];\n\t\tx3r = a[j1] - a[j3];\n\t\tx3i = a[j1 + 1] - a[j3 + 1];\n\t\ta[j0] = x0r + x2r;\n\t\ta[j0 + 1] = x0i + x2i;\n\t\ta[j1] = x0r - x2r;\n\t\ta[j1 + 1] = x0i - x2i;\n\t\tx0r = x1r - x3i;\n\t\tx0i = x1i + x3r;\n\t\ta[j2] = wn4r * (x0r - x0i);\n\t\ta[j2 + 1] = wn4r * (x0i + x0r);\n\t\tx0r = x1r + x3i;\n\t\tx0i = x1i - x3r;\n\t\ta[j3] = -wn4r * (x0r + x0i);\n\t\ta[j3 + 1] = -wn4r * (x0i - x0r);\n\t\tx0r = a[j0 + 2] + a[j2 + 2];\n\t\tx0i = a[j0 + 3] + a[j2 + 3];\n\t\tx1r = a[j0 + 2] - a[j2 + 2];\n\t\tx1i = a[j0 + 3] - a[j2 + 3];\n\t\tx2r = a[j1 + 2] + a[j3 + 2];\n\t\tx2i = a[j1 + 3] + a[j3 + 3];\n\t\tx3r = a[j1 + 2] - a[j3 + 2];\n\t\tx3i = a[j1 + 3] - a[j3 + 3];\n\t\ta[j0 + 2] = x0r + x2r;\n\t\ta[j0 + 3] = x0i + x2i;\n\t\ta[j1 + 2] = x0r - x2r;\n\t\ta[j1 + 3] = x0i - x2i;\n\t\tx0r = x1r - x3i;\n\t\tx0i = x1i + x3r;\n\t\ta[j2 + 2] = wk1i * x0r - wk1r * x0i;\n\t\ta[j2 + 3] = wk1i * x0i + wk1r * x0r;\n\t\tx0r = x1r + x3i;\n\t\tx0i = x1i - x3r;\n\t\ta[j3 + 2] = wk3i * x0r + wk3r * x0i;\n\t\ta[j3 + 3] = wk3i * x0i - wk3r * x0r;\n\t}\n\n\n\tstatic void cftb1st(int n, REAL *a, REAL *w)\n\t{\n\t\tint j, j0, j1, j2, j3, k, m, mh;\n\t\tREAL wn4r, csc1, csc3, wk1r, wk1i, wk3r, wk3i,\n\t\t\twd1r, wd1i, wd3r, wd3i;\n\t\tREAL x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i,\n\t\t\ty0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i;\n\n\t\tmh = n >> 3;\n\t\tm = 2 * mh;\n\t\tj1 = m;\n\t\tj2 = j1 + m;\n\t\tj3 = j2 + m;\n\t\tx0r = a[0] + a[j2];\n\t\tx0i = -a[1] - a[j2 + 1];\n\t\tx1r = a[0] - a[j2];\n\t\tx1i = -a[1] + a[j2 + 1];\n\t\tx2r = a[j1] + a[j3];\n\t\tx2i = a[j1 + 1] + a[j3 + 1];\n\t\tx3r = a[j1] - a[j3];\n\t\tx3i = a[j1 + 1] - a[j3 + 1];\n\t\ta[0] = x0r + x2r;\n\t\ta[1] = x0i - x2i;\n\t\ta[j1] = x0r - x2r;\n\t\ta[j1 + 1] = x0i + x2i;\n\t\ta[j2] = x1r + x3i;\n\t\ta[j2 + 1] = x1i + x3r;\n\t\ta[j3] = x1r - x3i;\n\t\ta[j3 + 1] = x1i - x3r;\n\t\twn4r = w[1];\n\t\tcsc1 = w[2];\n\t\tcsc3 = w[3];\n\t\twd1r = 1;\n\t\twd1i = 0;\n\t\twd3r = 1;\n\t\twd3i = 0;\n\t\tk = 0;\n\t\tfor (j = 2; j < mh - 2; j += 4) {\n\t\t\tk += 4;\n\t\t\twk1r = csc1 * (wd1r + w[k]);\n\t\t\twk1i = csc1 * (wd1i + w[k + 1]);\n\t\t\twk3r = csc3 * (wd3r + w[k + 2]);\n\t\t\twk3i = csc3 * (wd3i - w[k + 3]);\n\t\t\twd1r = w[k];\n\t\t\twd1i = w[k + 1];\n\t\t\twd3r = w[k + 2];\n\t\t\twd3i = -w[k + 3];\n\t\t\tj1 = j + m;\n\t\t\tj2 = j1 + m;\n\t\t\tj3 = j2 + m;\n\t\t\tx0r = a[j] + a[j2];\n\t\t\tx0i = -a[j + 1] - a[j2 + 1];\n\t\t\tx1r = a[j] - a[j2];\n\t\t\tx1i = -a[j + 1] + a[j2 + 1];\n\t\t\ty0r = a[j + 2] + a[j2 + 2];\n\t\t\ty0i = -a[j + 3] - a[j2 + 3];\n\t\t\ty1r = a[j + 2] - a[j2 + 2];\n\t\t\ty1i = -a[j + 3] + a[j2 + 3];\n\t\t\tx2r = a[j1] + a[j3];\n\t\t\tx2i = a[j1 + 1] + a[j3 + 1];\n\t\t\tx3r = a[j1] - a[j3];\n\t\t\tx3i = a[j1 + 1] - a[j3 + 1];\n\t\t\ty2r = a[j1 + 2] + a[j3 + 2];\n\t\t\ty2i = a[j1 + 3] + a[j3 + 3];\n\t\t\ty3r = a[j1 + 2] - a[j3 + 2];\n\t\t\ty3i = a[j1 + 3] - a[j3 + 3];\n\t\t\ta[j] = x0r + x2r;\n\t\t\ta[j + 1] = x0i - x2i;\n\t\t\ta[j + 2] = y0r + y2r;\n\t\t\ta[j + 3] = y0i - y2i;\n\t\t\ta[j1] = x0r - x2r;\n\t\t\ta[j1 + 1] = x0i + x2i;\n\t\t\ta[j1 + 2] = y0r - y2r;\n\t\t\ta[j1 + 3] = y0i + y2i;\n\t\t\tx0r = x1r + x3i;\n\t\t\tx0i = x1i + x3r;\n\t\t\ta[j2] = wk1r * x0r - wk1i * x0i;\n\t\t\ta[j2 + 1] = wk1r * x0i + wk1i * x0r;\n\t\t\tx0r = y1r + y3i;\n\t\t\tx0i = y1i + y3r;\n\t\t\ta[j2 + 2] = wd1r * x0r - wd1i * x0i;\n\t\t\ta[j2 + 3] = wd1r * x0i + wd1i * x0r;\n\t\t\tx0r = x1r - x3i;\n\t\t\tx0i = x1i - x3r;\n\t\t\ta[j3] = wk3r * x0r + wk3i * x0i;\n\t\t\ta[j3 + 1] = wk3r * x0i - wk3i * x0r;\n\t\t\tx0r = y1r - y3i;\n\t\t\tx0i = y1i - y3r;\n\t\t\ta[j3 + 2] = wd3r * x0r + wd3i * x0i;\n\t\t\ta[j3 + 3] = wd3r * x0i - wd3i * x0r;\n\t\t\tj0 = m - j;\n\t\t\tj1 = j0 + m;\n\t\t\tj2 = j1 + m;\n\t\t\tj3 = j2 + m;\n\t\t\tx0r = a[j0] + a[j2];\n\t\t\tx0i = -a[j0 + 1] - a[j2 + 1];\n\t\t\tx1r = a[j0] - a[j2];\n\t\t\tx1i = -a[j0 + 1] + a[j2 + 1];\n\t\t\ty0r = a[j0 - 2] + a[j2 - 2];\n\t\t\ty0i = -a[j0 - 1] - a[j2 - 1];\n\t\t\ty1r = a[j0 - 2] - a[j2 - 2];\n\t\t\ty1i = -a[j0 - 1] + a[j2 - 1];\n\t\t\tx2r = a[j1] + a[j3];\n\t\t\tx2i = a[j1 + 1] + a[j3 + 1];\n\t\t\tx3r = a[j1] - a[j3];\n\t\t\tx3i = a[j1 + 1] - a[j3 + 1];\n\t\t\ty2r = a[j1 - 2] + a[j3 - 2];\n\t\t\ty2i = a[j1 - 1] + a[j3 - 1];\n\t\t\ty3r = a[j1 - 2] - a[j3 - 2];\n\t\t\ty3i = a[j1 - 1] - a[j3 - 1];\n\t\t\ta[j0] = x0r + x2r;\n\t\t\ta[j0 + 1] = x0i - x2i;\n\t\t\ta[j0 - 2] = y0r + y2r;\n\t\t\ta[j0 - 1] = y0i - y2i;\n\t\t\ta[j1] = x0r - x2r;\n\t\t\ta[j1 + 1] = x0i + x2i;\n\t\t\ta[j1 - 2] = y0r - y2r;\n\t\t\ta[j1 - 1] = y0i + y2i;\n\t\t\tx0r = x1r + x3i;\n\t\t\tx0i = x1i + x3r;\n\t\t\ta[j2] = wk1i * x0r - wk1r * x0i;\n\t\t\ta[j2 + 1] = wk1i * x0i + wk1r * x0r;\n\t\t\tx0r = y1r + y3i;\n\t\t\tx0i = y1i + y3r;\n\t\t\ta[j2 - 2] = wd1i * x0r - wd1r * x0i;\n\t\t\ta[j2 - 1] = wd1i * x0i + wd1r * x0r;\n\t\t\tx0r = x1r - x3i;\n\t\t\tx0i = x1i - x3r;\n\t\t\ta[j3] = wk3i * x0r + wk3r * x0i;\n\t\t\ta[j3 + 1] = wk3i * x0i - wk3r * x0r;\n\t\t\tx0r = y1r - y3i;\n\t\t\tx0i = y1i - y3r;\n\t\t\ta[j3 - 2] = wd3i * x0r + wd3r * x0i;\n\t\t\ta[j3 - 1] = wd3i * x0i - wd3r * x0r;\n\t\t}\n\t\twk1r = csc1 * (wd1r + wn4r);\n\t\twk1i = csc1 * (wd1i + wn4r);\n\t\twk3r = csc3 * (wd3r - wn4r);\n\t\twk3i = csc3 * (wd3i - wn4r);\n\t\tj0 = mh;\n\t\tj1 = j0 + m;\n\t\tj2 = j1 + m;\n\t\tj3 = j2 + m;\n\t\tx0r = a[j0 - 2] + a[j2 - 2];\n\t\tx0i = -a[j0 - 1] - a[j2 - 1];\n\t\tx1r = a[j0 - 2] - a[j2 - 2];\n\t\tx1i = -a[j0 - 1] + a[j2 - 1];\n\t\tx2r = a[j1 - 2] + a[j3 - 2];\n\t\tx2i = a[j1 - 1] + a[j3 - 1];\n\t\tx3r = a[j1 - 2] - a[j3 - 2];\n\t\tx3i = a[j1 - 1] - a[j3 - 1];\n\t\ta[j0 - 2] = x0r + x2r;\n\t\ta[j0 - 1] = x0i - x2i;\n\t\ta[j1 - 2] = x0r - x2r;\n\t\ta[j1 - 1] = x0i + x2i;\n\t\tx0r = x1r + x3i;\n\t\tx0i = x1i + x3r;\n\t\ta[j2 - 2] = wk1r * x0r - wk1i * x0i;\n\t\ta[j2 - 1] = wk1r * x0i + wk1i * x0r;\n\t\tx0r = x1r - x3i;\n\t\tx0i = x1i - x3r;\n\t\ta[j3 - 2] = wk3r * x0r + wk3i * x0i;\n\t\ta[j3 - 1] = wk3r * x0i - wk3i * x0r;\n\t\tx0r = a[j0] + a[j2];\n\t\tx0i = -a[j0 + 1] - a[j2 + 1];\n\t\tx1r = a[j0] - a[j2];\n\t\tx1i = -a[j0 + 1] + a[j2 + 1];\n\t\tx2r = a[j1] + a[j3];\n\t\tx2i = a[j1 + 1] + a[j3 + 1];\n\t\tx3r = a[j1] - a[j3];\n\t\tx3i = a[j1 + 1] - a[j3 + 1];\n\t\ta[j0] = x0r + x2r;\n\t\ta[j0 + 1] = x0i - x2i;\n\t\ta[j1] = x0r - x2r;\n\t\ta[j1 + 1] = x0i + x2i;\n\t\tx0r = x1r + x3i;\n\t\tx0i = x1i + x3r;\n\t\ta[j2] = wn4r * (x0r - x0i);\n\t\ta[j2 + 1] = wn4r * (x0i + x0r);\n\t\tx0r = x1r - x3i;\n\t\tx0i = x1i - x3r;\n\t\ta[j3] = -wn4r * (x0r + x0i);\n\t\ta[j3 + 1] = -wn4r * (x0i - x0r);\n\t\tx0r = a[j0 + 2] + a[j2 + 2];\n\t\tx0i = -a[j0 + 3] - a[j2 + 3];\n\t\tx1r = a[j0 + 2] - a[j2 + 2];\n\t\tx1i = -a[j0 + 3] + a[j2 + 3];\n\t\tx2r = a[j1 + 2] + a[j3 + 2];\n\t\tx2i = a[j1 + 3] + a[j3 + 3];\n\t\tx3r = a[j1 + 2] - a[j3 + 2];\n\t\tx3i = a[j1 + 3] - a[j3 + 3];\n\t\ta[j0 + 2] = x0r + x2r;\n\t\ta[j0 + 3] = x0i - x2i;\n\t\ta[j1 + 2] = x0r - x2r;\n\t\ta[j1 + 3] = x0i + x2i;\n\t\tx0r = x1r + x3i;\n\t\tx0i = x1i + x3r;\n\t\ta[j2 + 2] = wk1i * x0r - wk1r * x0i;\n\t\ta[j2 + 3] = wk1i * x0i + wk1r * x0r;\n\t\tx0r = x1r - x3i;\n\t\tx0i = x1i - x3r;\n\t\ta[j3 + 2] = wk3i * x0r + wk3r * x0i;\n\t\ta[j3 + 3] = wk3i * x0i - wk3r * x0r;\n\t}\n\n\n\tstatic void cftrec1(int n, REAL *a, int nw, REAL *w)\n\t{\n\t\tint m;\n\n\t\tm = n >> 2;\n\t\tcftmdl1(n, a, &w[nw - 2 * m]);\n\t\tif (n > CDFT_RECURSIVE_N) {\n\t\t\tcftrec1(m, a, nw, w);\n\t\t\tcftrec2(m, &a[m], nw, w);\n\t\t\tcftrec1(m, &a[2 * m], nw, w);\n\t\t\tcftrec1(m, &a[3 * m], nw, w);\n\t\t} else {\n\t\t\tcftexp1(n, a, nw, w);\n\t\t}\n\t}\n\n\n\tstatic void cftrec2(int n, REAL *a, int nw, REAL *w)\n\t{\n\t\tint m;\n\n\t\tm = n >> 2;\n\t\tcftmdl2(n, a, &w[nw - n]);\n\t\tif (n > CDFT_RECURSIVE_N) {\n\t\t\tcftrec1(m, a, nw, w);\n\t\t\tcftrec2(m, &a[m], nw, w);\n\t\t\tcftrec1(m, &a[2 * m], nw, w);\n\t\t\tcftrec2(m, &a[3 * m], nw, w);\n\t\t} else {\n\t\t\tcftexp2(n, a, nw, w);\n\t\t}\n\t}\n\n\n\tstatic void cftexp1(int n, REAL *a, int nw, REAL *w)\n\t{\n\t\tint j, k, l;\n\n\t\tl = n >> 2;\n\t\twhile (l > 128) {\n\t\t\tfor (k = l; k < n; k <<= 2) {\n\t\t\t\tfor (j = k - l; j < n; j += 4 * k) {\n\t\t\t\t\tcftmdl1(l, &a[j], &w[nw - (l >> 1)]);\n\t\t\t\t\tcftmdl2(l, &a[k + j], &w[nw - l]);\n\t\t\t\t\tcftmdl1(l, &a[2 * k + j], &w[nw - (l >> 1)]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcftmdl1(l, &a[n - l], &w[nw - (l >> 1)]);\n\t\t\tl >>= 2;\n\t\t}\n\t\tfor (k = l; k < n; k <<= 2) {\n\t\t\tfor (j = k - l; j < n; j += 4 * k) {\n\t\t\t\tcftmdl1(l, &a[j], &w[nw - (l >> 1)]);\n\t\t\t\tcftfx41(l, &a[j], nw, w);\n\t\t\t\tcftmdl2(l, &a[k + j], &w[nw - l]);\n\t\t\t\tcftfx42(l, &a[k + j], nw, w);\n\t\t\t\tcftmdl1(l, &a[2 * k + j], &w[nw - (l >> 1)]);\n\t\t\t\tcftfx41(l, &a[2 * k + j], nw, w);\n\t\t\t}\n\t\t}\n\t\tcftmdl1(l, &a[n - l], &w[nw - (l >> 1)]);\n\t\tcftfx41(l, &a[n - l], nw, w);\n\t}\n\n\n\tstatic void cftexp2(int n, REAL *a, int nw, REAL *w)\n\t{\n\t\tint j, k, l, m;\n\n\t\tm = n >> 1;\n\t\tl = n >> 2;\n\t\twhile (l > 128) {\n\t\t\tfor (k = l; k < m; k <<= 2) {\n\t\t\t\tfor (j = k - l; j < m; j += 2 * k) {\n\t\t\t\t\tcftmdl1(l, &a[j], &w[nw - (l >> 1)]);\n\t\t\t\t\tcftmdl1(l, &a[m + j], &w[nw - (l >> 1)]);\n\t\t\t\t}\n\t\t\t\tfor (j = 2 * k - l; j < m; j += 4 * k) {\n\t\t\t\t\tcftmdl2(l, &a[j], &w[nw - l]);\n\t\t\t\t\tcftmdl2(l, &a[m + j], &w[nw - l]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tl >>= 2;\n\t\t}\n\t\tfor (k = l; k < m; k <<= 2) {\n\t\t\tfor (j = k - l; j < m; j += 2 * k) {\n\t\t\t\tcftmdl1(l, &a[j], &w[nw - (l >> 1)]);\n\t\t\t\tcftfx41(l, &a[j], nw, w);\n\t\t\t\tcftmdl1(l, &a[m + j], &w[nw - (l >> 1)]);\n\t\t\t\tcftfx41(l, &a[m + j], nw, w);\n\t\t\t}\n\t\t\tfor (j = 2 * k - l; j < m; j += 4 * k) {\n\t\t\t\tcftmdl2(l, &a[j], &w[nw - l]);\n\t\t\t\tcftfx42(l, &a[j], nw, w);\n\t\t\t\tcftmdl2(l, &a[m + j], &w[nw - l]);\n\t\t\t\tcftfx42(l, &a[m + j], nw, w);\n\t\t\t}\n\t\t}\n\t}\n\n\n\tstatic void cftmdl1(int n, REAL *a, REAL *w)\n\t{\n\t\tint j, j0, j1, j2, j3, k, m, mh;\n\t\tREAL wn4r, wk1r, wk1i, wk3r, wk3i;\n\t\tREAL x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;\n\n\t\tmh = n >> 3;\n\t\tm = 2 * mh;\n\t\tj1 = m;\n\t\tj2 = j1 + m;\n\t\tj3 = j2 + m;\n\t\tx0r = a[0] + a[j2];\n\t\tx0i = a[1] + a[j2 + 1];\n\t\tx1r = a[0] - a[j2];\n\t\tx1i = a[1] - a[j2 + 1];\n\t\tx2r = a[j1] + a[j3];\n\t\tx2i = a[j1 + 1] + a[j3 + 1];\n\t\tx3r = a[j1] - a[j3];\n\t\tx3i = a[j1 + 1] - a[j3 + 1];\n\t\ta[0] = x0r + x2r;\n\t\ta[1] = x0i + x2i;\n\t\ta[j1] = x0r - x2r;\n\t\ta[j1 + 1] = x0i - x2i;\n\t\ta[j2] = x1r - x3i;\n\t\ta[j2 + 1] = x1i + x3r;\n\t\ta[j3] = x1r + x3i;\n\t\ta[j3 + 1] = x1i - x3r;\n\t\twn4r = w[1];\n\t\tk = 0;\n\t\tfor (j = 2; j < mh; j += 2) {\n\t\t\tk += 4;\n\t\t\twk1r = w[k];\n\t\t\twk1i = w[k + 1];\n\t\t\twk3r = w[k + 2];\n\t\t\twk3i = -w[k + 3];\n\t\t\tj1 = j + m;\n\t\t\tj2 = j1 + m;\n\t\t\tj3 = j2 + m;\n\t\t\tx0r = a[j] + a[j2];\n\t\t\tx0i = a[j + 1] + a[j2 + 1];\n\t\t\tx1r = a[j] - a[j2];\n\t\t\tx1i = a[j + 1] - a[j2 + 1];\n\t\t\tx2r = a[j1] + a[j3];\n\t\t\tx2i = a[j1 + 1] + a[j3 + 1];\n\t\t\tx3r = a[j1] - a[j3];\n\t\t\tx3i = a[j1 + 1] - a[j3 + 1];\n\t\t\ta[j] = x0r + x2r;\n\t\t\ta[j + 1] = x0i + x2i;\n\t\t\ta[j1] = x0r - x2r;\n\t\t\ta[j1 + 1] = x0i - x2i;\n\t\t\tx0r = x1r - x3i;\n\t\t\tx0i = x1i + x3r;\n\t\t\ta[j2] = wk1r * x0r - wk1i * x0i;\n\t\t\ta[j2 + 1] = wk1r * x0i + wk1i * x0r;\n\t\t\tx0r = x1r + x3i;\n\t\t\tx0i = x1i - x3r;\n\t\t\ta[j3] = wk3r * x0r + wk3i * x0i;\n\t\t\ta[j3 + 1] = wk3r * x0i - wk3i * x0r;\n\t\t\tj0 = m - j;\n\t\t\tj1 = j0 + m;\n\t\t\tj2 = j1 + m;\n\t\t\tj3 = j2 + m;\n\t\t\tx0r = a[j0] + a[j2];\n\t\t\tx0i = a[j0 + 1] + a[j2 + 1];\n\t\t\tx1r = a[j0] - a[j2];\n\t\t\tx1i = a[j0 + 1] - a[j2 + 1];\n\t\t\tx2r = a[j1] + a[j3];\n\t\t\tx2i = a[j1 + 1] + a[j3 + 1];\n\t\t\tx3r = a[j1] - a[j3];\n\t\t\tx3i = a[j1 + 1] - a[j3 + 1];\n\t\t\ta[j0] = x0r + x2r;\n\t\t\ta[j0 + 1] = x0i + x2i;\n\t\t\ta[j1] = x0r - x2r;\n\t\t\ta[j1 + 1] = x0i - x2i;\n\t\t\tx0r = x1r - x3i;\n\t\t\tx0i = x1i + x3r;\n\t\t\ta[j2] = wk1i * x0r - wk1r * x0i;\n\t\t\ta[j2 + 1] = wk1i * x0i + wk1r * x0r;\n\t\t\tx0r = x1r + x3i;\n\t\t\tx0i = x1i - x3r;\n\t\t\ta[j3] = wk3i * x0r + wk3r * x0i;\n\t\t\ta[j3 + 1] = wk3i * x0i - wk3r * x0r;\n\t\t}\n\t\tj0 = mh;\n\t\tj1 = j0 + m;\n\t\tj2 = j1 + m;\n\t\tj3 = j2 + m;\n\t\tx0r = a[j0] + a[j2];\n\t\tx0i = a[j0 + 1] + a[j2 + 1];\n\t\tx1r = a[j0] - a[j2];\n\t\tx1i = a[j0 + 1] - a[j2 + 1];\n\t\tx2r = a[j1] + a[j3];\n\t\tx2i = a[j1 + 1] + a[j3 + 1];\n\t\tx3r = a[j1] - a[j3];\n\t\tx3i = a[j1 + 1] - a[j3 + 1];\n\t\ta[j0] = x0r + x2r;\n\t\ta[j0 + 1] = x0i + x2i;\n\t\ta[j1] = x0r - x2r;\n\t\ta[j1 + 1] = x0i - x2i;\n\t\tx0r = x1r - x3i;\n\t\tx0i = x1i + x3r;\n\t\ta[j2] = wn4r * (x0r - x0i);\n\t\ta[j2 + 1] = wn4r * (x0i + x0r);\n\t\tx0r = x1r + x3i;\n\t\tx0i = x1i - x3r;\n\t\ta[j3] = -wn4r * (x0r + x0i);\n\t\ta[j3 + 1] = -wn4r * (x0i - x0r);\n\t}\n\n\n\tstatic void cftmdl2(int n, REAL *a, REAL *w)\n\t{\n\t\tint j, j0, j1, j2, j3, k, kr, m, mh;\n\t\tREAL wn4r, wk1r, wk1i, wk3r, wk3i, wd1r, wd1i, wd3r, wd3i;\n\t\tREAL x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y2r, y2i;\n\n\t\tmh = n >> 3;\n\t\tm = 2 * mh;\n\t\twn4r = w[1];\n\t\tj1 = m;\n\t\tj2 = j1 + m;\n\t\tj3 = j2 + m;\n\t\tx0r = a[0] - a[j2 + 1];\n\t\tx0i = a[1] + a[j2];\n\t\tx1r = a[0] + a[j2 + 1];\n\t\tx1i = a[1] - a[j2];\n\t\tx2r = a[j1] - a[j3 + 1];\n\t\tx2i = a[j1 + 1] + a[j3];\n\t\tx3r = a[j1] + a[j3 + 1];\n\t\tx3i = a[j1 + 1] - a[j3];\n\t\ty0r = wn4r * (x2r - x2i);\n\t\ty0i = wn4r * (x2i + x2r);\n\t\ta[0] = x0r + y0r;\n\t\ta[1] = x0i + y0i;\n\t\ta[j1] = x0r - y0r;\n\t\ta[j1 + 1] = x0i - y0i;\n\t\ty0r = wn4r * (x3r - x3i);\n\t\ty0i = wn4r * (x3i + x3r);\n\t\ta[j2] = x1r - y0i;\n\t\ta[j2 + 1] = x1i + y0r;\n\t\ta[j3] = x1r + y0i;\n\t\ta[j3 + 1] = x1i - y0r;\n\t\tk = 0;\n\t\tkr = 2 * m;\n\t\tfor (j = 2; j < mh; j += 2) {\n\t\t\tk += 4;\n\t\t\twk1r = w[k];\n\t\t\twk1i = w[k + 1];\n\t\t\twk3r = w[k + 2];\n\t\t\twk3i = -w[k + 3];\n\t\t\tkr -= 4;\n\t\t\twd1i = w[kr];\n\t\t\twd1r = w[kr + 1];\n\t\t\twd3i = w[kr + 2];\n\t\t\twd3r = -w[kr + 3];\n\t\t\tj1 = j + m;\n\t\t\tj2 = j1 + m;\n\t\t\tj3 = j2 + m;\n\t\t\tx0r = a[j] - a[j2 + 1];\n\t\t\tx0i = a[j + 1] + a[j2];\n\t\t\tx1r = a[j] + a[j2 + 1];\n\t\t\tx1i = a[j + 1] - a[j2];\n\t\t\tx2r = a[j1] - a[j3 + 1];\n\t\t\tx2i = a[j1 + 1] + a[j3];\n\t\t\tx3r = a[j1] + a[j3 + 1];\n\t\t\tx3i = a[j1 + 1] - a[j3];\n\t\t\ty0r = wk1r * x0r - wk1i * x0i;\n\t\t\ty0i = wk1r * x0i + wk1i * x0r;\n\t\t\ty2r = wd1r * x2r - wd1i * x2i;\n\t\t\ty2i = wd1r * x2i + wd1i * x2r;\n\t\t\ta[j] = y0r + y2r;\n\t\t\ta[j + 1] = y0i + y2i;\n\t\t\ta[j1] = y0r - y2r;\n\t\t\ta[j1 + 1] = y0i - y2i;\n\t\t\ty0r = wk3r * x1r + wk3i * x1i;\n\t\t\ty0i = wk3r * x1i - wk3i * x1r;\n\t\t\ty2r = wd3r * x3r + wd3i * x3i;\n\t\t\ty2i = wd3r * x3i - wd3i * x3r;\n\t\t\ta[j2] = y0r + y2r;\n\t\t\ta[j2 + 1] = y0i + y2i;\n\t\t\ta[j3] = y0r - y2r;\n\t\t\ta[j3 + 1] = y0i - y2i;\n\t\t\tj0 = m - j;\n\t\t\tj1 = j0 + m;\n\t\t\tj2 = j1 + m;\n\t\t\tj3 = j2 + m;\n\t\t\tx0r = a[j0] - a[j2 + 1];\n\t\t\tx0i = a[j0 + 1] + a[j2];\n\t\t\tx1r = a[j0] + a[j2 + 1];\n\t\t\tx1i = a[j0 + 1] - a[j2];\n\t\t\tx2r = a[j1] - a[j3 + 1];\n\t\t\tx2i = a[j1 + 1] + a[j3];\n\t\t\tx3r = a[j1] + a[j3 + 1];\n\t\t\tx3i = a[j1 + 1] - a[j3];\n\t\t\ty0r = wd1i * x0r - wd1r * x0i;\n\t\t\ty0i = wd1i * x0i + wd1r * x0r;\n\t\t\ty2r = wk1i * x2r - wk1r * x2i;\n\t\t\ty2i = wk1i * x2i + wk1r * x2r;\n\t\t\ta[j0] = y0r + y2r;\n\t\t\ta[j0 + 1] = y0i + y2i;\n\t\t\ta[j1] = y0r - y2r;\n\t\t\ta[j1 + 1] = y0i - y2i;\n\t\t\ty0r = wd3i * x1r + wd3r * x1i;\n\t\t\ty0i = wd3i * x1i - wd3r * x1r;\n\t\t\ty2r = wk3i * x3r + wk3r * x3i;\n\t\t\ty2i = wk3i * x3i - wk3r * x3r;\n\t\t\ta[j2] = y0r + y2r;\n\t\t\ta[j2 + 1] = y0i + y2i;\n\t\t\ta[j3] = y0r - y2r;\n\t\t\ta[j3 + 1] = y0i - y2i;\n\t\t}\n\t\twk1r = w[m];\n\t\twk1i = w[m + 1];\n\t\tj0 = mh;\n\t\tj1 = j0 + m;\n\t\tj2 = j1 + m;\n\t\tj3 = j2 + m;\n\t\tx0r = a[j0] - a[j2 + 1];\n\t\tx0i = a[j0 + 1] + a[j2];\n\t\tx1r = a[j0] + a[j2 + 1];\n\t\tx1i = a[j0 + 1] - a[j2];\n\t\tx2r = a[j1] - a[j3 + 1];\n\t\tx2i = a[j1 + 1] + a[j3];\n\t\tx3r = a[j1] + a[j3 + 1];\n\t\tx3i = a[j1 + 1] - a[j3];\n\t\ty0r = wk1r * x0r - wk1i * x0i;\n\t\ty0i = wk1r * x0i + wk1i * x0r;\n\t\ty2r = wk1i * x2r - wk1r * x2i;\n\t\ty2i = wk1i * x2i + wk1r * x2r;\n\t\ta[j0] = y0r + y2r;\n\t\ta[j0 + 1] = y0i + y2i;\n\t\ta[j1] = y0r - y2r;\n\t\ta[j1 + 1] = y0i - y2i;\n\t\ty0r = wk1i * x1r - wk1r * x1i;\n\t\ty0i = wk1i * x1i + wk1r * x1r;\n\t\ty2r = wk1r * x3r - wk1i * x3i;\n\t\ty2i = wk1r * x3i + wk1i * x3r;\n\t\ta[j2] = y0r - y2r;\n\t\ta[j2 + 1] = y0i - y2i;\n\t\ta[j3] = y0r + y2r;\n\t\ta[j3 + 1] = y0i + y2i;\n\t}\n\n\n\tstatic void cftfx41(int n, REAL *a, int nw, REAL *w)\n\t{\n\t\tif (n == 128) {\n\t\t\tcftf161(a, &w[nw - 8]);\n\t\t\tcftf162(&a[32], &w[nw - 32]);\n\t\t\tcftf161(&a[64], &w[nw - 8]);\n\t\t\tcftf161(&a[96], &w[nw - 8]);\n\t\t} else {\n\t\t\tcftf081(a, &w[nw - 16]);\n\t\t\tcftf082(&a[16], &w[nw - 16]);\n\t\t\tcftf081(&a[32], &w[nw - 16]);\n\t\t\tcftf081(&a[48], &w[nw - 16]);\n\t\t}\n\t}\n\n\n\tstatic void cftfx42(int n, REAL *a, int nw, REAL *w)\n\t{\n\t\tif (n == 128) {\n\t\t\tcftf161(a, &w[nw - 8]);\n\t\t\tcftf162(&a[32], &w[nw - 32]);\n\t\t\tcftf161(&a[64], &w[nw - 8]);\n\t\t\tcftf162(&a[96], &w[nw - 32]);\n\t\t} else {\n\t\t\tcftf081(a, &w[nw - 16]);\n\t\t\tcftf082(&a[16], &w[nw - 16]);\n\t\t\tcftf081(&a[32], &w[nw - 16]);\n\t\t\tcftf082(&a[48], &w[nw - 16]);\n\t\t}\n\t}\n\n\n\tstatic void cftf161(REAL *a, REAL *w)\n\t{\n\t\tREAL wn4r, wk1r, wk1i,\n\t\t\tx0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i,\n\t\t\ty0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i,\n\t\t\ty4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i,\n\t\t\ty8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i,\n\t\t\ty12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i;\n\n\t\twn4r = w[1];\n\t\twk1i = wn4r * w[2];\n\t\twk1r = wk1i + w[2];\n\t\tx0r = a[0] + a[16];\n\t\tx0i = a[1] + a[17];\n\t\tx1r = a[0] - a[16];\n\t\tx1i = a[1] - a[17];\n\t\tx2r = a[8] + a[24];\n\t\tx2i = a[9] + a[25];\n\t\tx3r = a[8] - a[24];\n\t\tx3i = a[9] - a[25];\n\t\ty0r = x0r + x2r;\n\t\ty0i = x0i + x2i;\n\t\ty4r = x0r - x2r;\n\t\ty4i = x0i - x2i;\n\t\ty8r = x1r - x3i;\n\t\ty8i = x1i + x3r;\n\t\ty12r = x1r + x3i;\n\t\ty12i = x1i - x3r;\n\t\tx0r = a[2] + a[18];\n\t\tx0i = a[3] + a[19];\n\t\tx1r = a[2] - a[18];\n\t\tx1i = a[3] - a[19];\n\t\tx2r = a[10] + a[26];\n\t\tx2i = a[11] + a[27];\n\t\tx3r = a[10] - a[26];\n\t\tx3i = a[11] - a[27];\n\t\ty1r = x0r + x2r;\n\t\ty1i = x0i + x2i;\n\t\ty5r = x0r - x2r;\n\t\ty5i = x0i - x2i;\n\t\tx0r = x1r - x3i;\n\t\tx0i = x1i + x3r;\n\t\ty9r = wk1r * x0r - wk1i * x0i;\n\t\ty9i = wk1r * x0i + wk1i * x0r;\n\t\tx0r = x1r + x3i;\n\t\tx0i = x1i - x3r;\n\t\ty13r = wk1i * x0r - wk1r * x0i;\n\t\ty13i = wk1i * x0i + wk1r * x0r;\n\t\tx0r = a[4] + a[20];\n\t\tx0i = a[5] + a[21];\n\t\tx1r = a[4] - a[20];\n\t\tx1i = a[5] - a[21];\n\t\tx2r = a[12] + a[28];\n\t\tx2i = a[13] + a[29];\n\t\tx3r = a[12] - a[28];\n\t\tx3i = a[13] - a[29];\n\t\ty2r = x0r + x2r;\n\t\ty2i = x0i + x2i;\n\t\ty6r = x0r - x2r;\n\t\ty6i = x0i - x2i;\n\t\tx0r = x1r - x3i;\n\t\tx0i = x1i + x3r;\n\t\ty10r = wn4r * (x0r - x0i);\n\t\ty10i = wn4r * (x0i + x0r);\n\t\tx0r = x1r + x3i;\n\t\tx0i = x1i - x3r;\n\t\ty14r = wn4r * (x0r + x0i);\n\t\ty14i = wn4r * (x0i - x0r);\n\t\tx0r = a[6] + a[22];\n\t\tx0i = a[7] + a[23];\n\t\tx1r = a[6] - a[22];\n\t\tx1i = a[7] - a[23];\n\t\tx2r = a[14] + a[30];\n\t\tx2i = a[15] + a[31];\n\t\tx3r = a[14] - a[30];\n\t\tx3i = a[15] - a[31];\n\t\ty3r = x0r + x2r;\n\t\ty3i = x0i + x2i;\n\t\ty7r = x0r - x2r;\n\t\ty7i = x0i - x2i;\n\t\tx0r = x1r - x3i;\n\t\tx0i = x1i + x3r;\n\t\ty11r = wk1i * x0r - wk1r * x0i;\n\t\ty11i = wk1i * x0i + wk1r * x0r;\n\t\tx0r = x1r + x3i;\n\t\tx0i = x1i - x3r;\n\t\ty15r = wk1r * x0r - wk1i * x0i;\n\t\ty15i = wk1r * x0i + wk1i * x0r;\n\t\tx0r = y12r - y14r;\n\t\tx0i = y12i - y14i;\n\t\tx1r = y12r + y14r;\n\t\tx1i = y12i + y14i;\n\t\tx2r = y13r - y15r;\n\t\tx2i = y13i - y15i;\n\t\tx3r = y13r + y15r;\n\t\tx3i = y13i + y15i;\n\t\ta[24] = x0r + x2r;\n\t\ta[25] = x0i + x2i;\n\t\ta[26] = x0r - x2r;\n\t\ta[27] = x0i - x2i;\n\t\ta[28] = x1r - x3i;\n\t\ta[29] = x1i + x3r;\n\t\ta[30] = x1r + x3i;\n\t\ta[31] = x1i - x3r;\n\t\tx0r = y8r + y10r;\n\t\tx0i = y8i + y10i;\n\t\tx1r = y8r - y10r;\n\t\tx1i = y8i - y10i;\n\t\tx2r = y9r + y11r;\n\t\tx2i = y9i + y11i;\n\t\tx3r = y9r - y11r;\n\t\tx3i = y9i - y11i;\n\t\ta[16] = x0r + x2r;\n\t\ta[17] = x0i + x2i;\n\t\ta[18] = x0r - x2r;\n\t\ta[19] = x0i - x2i;\n\t\ta[20] = x1r - x3i;\n\t\ta[21] = x1i + x3r;\n\t\ta[22] = x1r + x3i;\n\t\ta[23] = x1i - x3r;\n\t\tx0r = y5r - y7i;\n\t\tx0i = y5i + y7r;\n\t\tx2r = wn4r * (x0r - x0i);\n\t\tx2i = wn4r * (x0i + x0r);\n\t\tx0r = y5r + y7i;\n\t\tx0i = y5i - y7r;\n\t\tx3r = wn4r * (x0r - x0i);\n\t\tx3i = wn4r * (x0i + x0r);\n\t\tx0r = y4r - y6i;\n\t\tx0i = y4i + y6r;\n\t\tx1r = y4r + y6i;\n\t\tx1i = y4i - y6r;\n\t\ta[8] = x0r + x2r;\n\t\ta[9] = x0i + x2i;\n\t\ta[10] = x0r - x2r;\n\t\ta[11] = x0i - x2i;\n\t\ta[12] = x1r - x3i;\n\t\ta[13] = x1i + x3r;\n\t\ta[14] = x1r + x3i;\n\t\ta[15] = x1i - x3r;\n\t\tx0r = y0r + y2r;\n\t\tx0i = y0i + y2i;\n\t\tx1r = y0r - y2r;\n\t\tx1i = y0i - y2i;\n\t\tx2r = y1r + y3r;\n\t\tx2i = y1i + y3i;\n\t\tx3r = y1r - y3r;\n\t\tx3i = y1i - y3i;\n\t\ta[0] = x0r + x2r;\n\t\ta[1] = x0i + x2i;\n\t\ta[2] = x0r - x2r;\n\t\ta[3] = x0i - x2i;\n\t\ta[4] = x1r - x3i;\n\t\ta[5] = x1i + x3r;\n\t\ta[6] = x1r + x3i;\n\t\ta[7] = x1i - x3r;\n\t}\n\n\n\tstatic void cftf162(REAL *a, REAL *w)\n\t{\n\t\tREAL wn4r, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i,\n\t\t\tx0r, x0i, x1r, x1i, x2r, x2i,\n\t\t\ty0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i,\n\t\t\ty4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i,\n\t\t\ty8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i,\n\t\t\ty12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i;\n\n\t\twn4r = w[1];\n\t\twk1r = w[4];\n\t\twk1i = w[5];\n\t\twk3r = w[6];\n\t\twk3i = w[7];\n\t\twk2r = w[8];\n\t\twk2i = w[9];\n\t\tx1r = a[0] - a[17];\n\t\tx1i = a[1] + a[16];\n\t\tx0r = a[8] - a[25];\n\t\tx0i = a[9] + a[24];\n\t\tx2r = wn4r * (x0r - x0i);\n\t\tx2i = wn4r * (x0i + x0r);\n\t\ty0r = x1r + x2r;\n\t\ty0i = x1i + x2i;\n\t\ty4r = x1r - x2r;\n\t\ty4i = x1i - x2i;\n\t\tx1r = a[0] + a[17];\n\t\tx1i = a[1] - a[16];\n\t\tx0r = a[8] + a[25];\n\t\tx0i = a[9] - a[24];\n\t\tx2r = wn4r * (x0r - x0i);\n\t\tx2i = wn4r * (x0i + x0r);\n\t\ty8r = x1r - x2i;\n\t\ty8i = x1i + x2r;\n\t\ty12r = x1r + x2i;\n\t\ty12i = x1i - x2r;\n\t\tx0r = a[2] - a[19];\n\t\tx0i = a[3] + a[18];\n\t\tx1r = wk1r * x0r - wk1i * x0i;\n\t\tx1i = wk1r * x0i + wk1i * x0r;\n\t\tx0r = a[10] - a[27];\n\t\tx0i = a[11] + a[26];\n\t\tx2r = wk3i * x0r - wk3r * x0i;\n\t\tx2i = wk3i * x0i + wk3r * x0r;\n\t\ty1r = x1r + x2r;\n\t\ty1i = x1i + x2i;\n\t\ty5r = x1r - x2r;\n\t\ty5i = x1i - x2i;\n\t\tx0r = a[2] + a[19];\n\t\tx0i = a[3] - a[18];\n\t\tx1r = wk3r * x0r - wk3i * x0i;\n\t\tx1i = wk3r * x0i + wk3i * x0r;\n\t\tx0r = a[10] + a[27];\n\t\tx0i = a[11] - a[26];\n\t\tx2r = wk1r * x0r + wk1i * x0i;\n\t\tx2i = wk1r * x0i - wk1i * x0r;\n\t\ty9r = x1r - x2r;\n\t\ty9i = x1i - x2i;\n\t\ty13r = x1r + x2r;\n\t\ty13i = x1i + x2i;\n\t\tx0r = a[4] - a[21];\n\t\tx0i = a[5] + a[20];\n\t\tx1r = wk2r * x0r - wk2i * x0i;\n\t\tx1i = wk2r * x0i + wk2i * x0r;\n\t\tx0r = a[12] - a[29];\n\t\tx0i = a[13] + a[28];\n\t\tx2r = wk2i * x0r - wk2r * x0i;\n\t\tx2i = wk2i * x0i + wk2r * x0r;\n\t\ty2r = x1r + x2r;\n\t\ty2i = x1i + x2i;\n\t\ty6r = x1r - x2r;\n\t\ty6i = x1i - x2i;\n\t\tx0r = a[4] + a[21];\n\t\tx0i = a[5] - a[20];\n\t\tx1r = wk2i * x0r - wk2r * x0i;\n\t\tx1i = wk2i * x0i + wk2r * x0r;\n\t\tx0r = a[12] + a[29];\n\t\tx0i = a[13] - a[28];\n\t\tx2r = wk2r * x0r - wk2i * x0i;\n\t\tx2i = wk2r * x0i + wk2i * x0r;\n\t\ty10r = x1r - x2r;\n\t\ty10i = x1i - x2i;\n\t\ty14r = x1r + x2r;\n\t\ty14i = x1i + x2i;\n\t\tx0r = a[6] - a[23];\n\t\tx0i = a[7] + a[22];\n\t\tx1r = wk3r * x0r - wk3i * x0i;\n\t\tx1i = wk3r * x0i + wk3i * x0r;\n\t\tx0r = a[14] - a[31];\n\t\tx0i = a[15] + a[30];\n\t\tx2r = wk1i * x0r - wk1r * x0i;\n\t\tx2i = wk1i * x0i + wk1r * x0r;\n\t\ty3r = x1r + x2r;\n\t\ty3i = x1i + x2i;\n\t\ty7r = x1r - x2r;\n\t\ty7i = x1i - x2i;\n\t\tx0r = a[6] + a[23];\n\t\tx0i = a[7] - a[22];\n\t\tx1r = wk1i * x0r + wk1r * x0i;\n\t\tx1i = wk1i * x0i - wk1r * x0r;\n\t\tx0r = a[14] + a[31];\n\t\tx0i = a[15] - a[30];\n\t\tx2r = wk3i * x0r - wk3r * x0i;\n\t\tx2i = wk3i * x0i + wk3r * x0r;\n\t\ty11r = x1r + x2r;\n\t\ty11i = x1i + x2i;\n\t\ty15r = x1r - x2r;\n\t\ty15i = x1i - x2i;\n\t\tx1r = y0r + y2r;\n\t\tx1i = y0i + y2i;\n\t\tx2r = y1r + y3r;\n\t\tx2i = y1i + y3i;\n\t\ta[0] = x1r + x2r;\n\t\ta[1] = x1i + x2i;\n\t\ta[2] = x1r - x2r;\n\t\ta[3] = x1i - x2i;\n\t\tx1r = y0r - y2r;\n\t\tx1i = y0i - y2i;\n\t\tx2r = y1r - y3r;\n\t\tx2i = y1i - y3i;\n\t\ta[4] = x1r - x2i;\n\t\ta[5] = x1i + x2r;\n\t\ta[6] = x1r + x2i;\n\t\ta[7] = x1i - x2r;\n\t\tx1r = y4r - y6i;\n\t\tx1i = y4i + y6r;\n\t\tx0r = y5r - y7i;\n\t\tx0i = y5i + y7r;\n\t\tx2r = wn4r * (x0r - x0i);\n\t\tx2i = wn4r * (x0i + x0r);\n\t\ta[8] = x1r + x2r;\n\t\ta[9] = x1i + x2i;\n\t\ta[10] = x1r - x2r;\n\t\ta[11] = x1i - x2i;\n\t\tx1r = y4r + y6i;\n\t\tx1i = y4i - y6r;\n\t\tx0r = y5r + y7i;\n\t\tx0i = y5i - y7r;\n\t\tx2r = wn4r * (x0r - x0i);\n\t\tx2i = wn4r * (x0i + x0r);\n\t\ta[12] = x1r - x2i;\n\t\ta[13] = x1i + x2r;\n\t\ta[14] = x1r + x2i;\n\t\ta[15] = x1i - x2r;\n\t\tx1r = y8r + y10r;\n\t\tx1i = y8i + y10i;\n\t\tx2r = y9r - y11r;\n\t\tx2i = y9i - y11i;\n\t\ta[16] = x1r + x2r;\n\t\ta[17] = x1i + x2i;\n\t\ta[18] = x1r - x2r;\n\t\ta[19] = x1i - x2i;\n\t\tx1r = y8r - y10r;\n\t\tx1i = y8i - y10i;\n\t\tx2r = y9r + y11r;\n\t\tx2i = y9i + y11i;\n\t\ta[20] = x1r - x2i;\n\t\ta[21] = x1i + x2r;\n\t\ta[22] = x1r + x2i;\n\t\ta[23] = x1i - x2r;\n\t\tx1r = y12r - y14i;\n\t\tx1i = y12i + y14r;\n\t\tx0r = y13r + y15i;\n\t\tx0i = y13i - y15r;\n\t\tx2r = wn4r * (x0r - x0i);\n\t\tx2i = wn4r * (x0i + x0r);\n\t\ta[24] = x1r + x2r;\n\t\ta[25] = x1i + x2i;\n\t\ta[26] = x1r - x2r;\n\t\ta[27] = x1i - x2i;\n\t\tx1r = y12r + y14i;\n\t\tx1i = y12i - y14r;\n\t\tx0r = y13r - y15i;\n\t\tx0i = y13i + y15r;\n\t\tx2r = wn4r * (x0r - x0i);\n\t\tx2i = wn4r * (x0i + x0r);\n\t\ta[28] = x1r - x2i;\n\t\ta[29] = x1i + x2r;\n\t\ta[30] = x1r + x2i;\n\t\ta[31] = x1i - x2r;\n\t}\n\n\n\tstatic void cftf081(REAL *a, REAL *w)\n\t{\n\t\tREAL wn4r, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i,\n\t\t\ty0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i,\n\t\t\ty4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i;\n\n\t\twn4r = w[1];\n\t\tx0r = a[0] + a[8];\n\t\tx0i = a[1] + a[9];\n\t\tx1r = a[0] - a[8];\n\t\tx1i = a[1] - a[9];\n\t\tx2r = a[4] + a[12];\n\t\tx2i = a[5] + a[13];\n\t\tx3r = a[4] - a[12];\n\t\tx3i = a[5] - a[13];\n\t\ty0r = x0r + x2r;\n\t\ty0i = x0i + x2i;\n\t\ty2r = x0r - x2r;\n\t\ty2i = x0i - x2i;\n\t\ty1r = x1r - x3i;\n\t\ty1i = x1i + x3r;\n\t\ty3r = x1r + x3i;\n\t\ty3i = x1i - x3r;\n\t\tx0r = a[2] + a[10];\n\t\tx0i = a[3] + a[11];\n\t\tx1r = a[2] - a[10];\n\t\tx1i = a[3] - a[11];\n\t\tx2r = a[6] + a[14];\n\t\tx2i = a[7] + a[15];\n\t\tx3r = a[6] - a[14];\n\t\tx3i = a[7] - a[15];\n\t\ty4r = x0r + x2r;\n\t\ty4i = x0i + x2i;\n\t\ty6r = x0r - x2r;\n\t\ty6i = x0i - x2i;\n\t\tx0r = x1r - x3i;\n\t\tx0i = x1i + x3r;\n\t\tx2r = x1r + x3i;\n\t\tx2i = x1i - x3r;\n\t\ty5r = wn4r * (x0r - x0i);\n\t\ty5i = wn4r * (x0r + x0i);\n\t\ty7r = wn4r * (x2r - x2i);\n\t\ty7i = wn4r * (x2r + x2i);\n\t\ta[8] = y1r + y5r;\n\t\ta[9] = y1i + y5i;\n\t\ta[10] = y1r - y5r;\n\t\ta[11] = y1i - y5i;\n\t\ta[12] = y3r - y7i;\n\t\ta[13] = y3i + y7r;\n\t\ta[14] = y3r + y7i;\n\t\ta[15] = y3i - y7r;\n\t\ta[0] = y0r + y4r;\n\t\ta[1] = y0i + y4i;\n\t\ta[2] = y0r - y4r;\n\t\ta[3] = y0i - y4i;\n\t\ta[4] = y2r - y6i;\n\t\ta[5] = y2i + y6r;\n\t\ta[6] = y2r + y6i;\n\t\ta[7] = y2i - y6r;\n\t}\n\n\n\tstatic void cftf082(REAL *a, REAL *w)\n\t{\n\t\tREAL wn4r, wk1r, wk1i, x0r, x0i, x1r, x1i,\n\t\t\ty0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i,\n\t\t\ty4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i;\n\n\t\twn4r = w[1];\n\t\twk1r = w[4];\n\t\twk1i = w[5];\n\t\ty0r = a[0] - a[9];\n\t\ty0i = a[1] + a[8];\n\t\ty1r = a[0] + a[9];\n\t\ty1i = a[1] - a[8];\n\t\tx0r = a[4] - a[13];\n\t\tx0i = a[5] + a[12];\n\t\ty2r = wn4r * (x0r - x0i);\n\t\ty2i = wn4r * (x0i + x0r);\n\t\tx0r = a[4] + a[13];\n\t\tx0i = a[5] - a[12];\n\t\ty3r = wn4r * (x0r - x0i);\n\t\ty3i = wn4r * (x0i + x0r);\n\t\tx0r = a[2] - a[11];\n\t\tx0i = a[3] + a[10];\n\t\ty4r = wk1r * x0r - wk1i * x0i;\n\t\ty4i = wk1r * x0i + wk1i * x0r;\n\t\tx0r = a[2] + a[11];\n\t\tx0i = a[3] - a[10];\n\t\ty5r = wk1i * x0r - wk1r * x0i;\n\t\ty5i = wk1i * x0i + wk1r * x0r;\n\t\tx0r = a[6] - a[15];\n\t\tx0i = a[7] + a[14];\n\t\ty6r = wk1i * x0r - wk1r * x0i;\n\t\ty6i = wk1i * x0i + wk1r * x0r;\n\t\tx0r = a[6] + a[15];\n\t\tx0i = a[7] - a[14];\n\t\ty7r = wk1r * x0r - wk1i * x0i;\n\t\ty7i = wk1r * x0i + wk1i * x0r;\n\t\tx0r = y0r + y2r;\n\t\tx0i = y0i + y2i;\n\t\tx1r = y4r + y6r;\n\t\tx1i = y4i + y6i;\n\t\ta[0] = x0r + x1r;\n\t\ta[1] = x0i + x1i;\n\t\ta[2] = x0r - x1r;\n\t\ta[3] = x0i - x1i;\n\t\tx0r = y0r - y2r;\n\t\tx0i = y0i - y2i;\n\t\tx1r = y4r - y6r;\n\t\tx1i = y4i - y6i;\n\t\ta[4] = x0r - x1i;\n\t\ta[5] = x0i + x1r;\n\t\ta[6] = x0r + x1i;\n\t\ta[7] = x0i - x1r;\n\t\tx0r = y1r - y3i;\n\t\tx0i = y1i + y3r;\n\t\tx1r = y5r - y7r;\n\t\tx1i = y5i - y7i;\n\t\ta[8] = x0r + x1r;\n\t\ta[9] = x0i + x1i;\n\t\ta[10] = x0r - x1r;\n\t\ta[11] = x0i - x1i;\n\t\tx0r = y1r + y3i;\n\t\tx0i = y1i - y3r;\n\t\tx1r = y5r + y7r;\n\t\tx1i = y5i + y7i;\n\t\ta[12] = x0r - x1i;\n\t\ta[13] = x0i + x1r;\n\t\ta[14] = x0r + x1i;\n\t\ta[15] = x0i - x1r;\n\t}\n\n\n\tstatic void cftf040(REAL *a)\n\t{\n\t\tREAL x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;\n\n\t\tx0r = a[0] + a[4];\n\t\tx0i = a[1] + a[5];\n\t\tx1r = a[0] - a[4];\n\t\tx1i = a[1] - a[5];\n\t\tx2r = a[2] + a[6];\n\t\tx2i = a[3] + a[7];\n\t\tx3r = a[2] - a[6];\n\t\tx3i = a[3] - a[7];\n\t\ta[0] = x0r + x2r;\n\t\ta[1] = x0i + x2i;\n\t\ta[4] = x0r - x2r;\n\t\ta[5] = x0i - x2i;\n\t\ta[2] = x1r - x3i;\n\t\ta[3] = x1i + x3r;\n\t\ta[6] = x1r + x3i;\n\t\ta[7] = x1i - x3r;\n\t}\n\n\n\tstatic void cftb040(REAL *a)\n\t{\n\t\tREAL x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;\n\n\t\tx0r = a[0] + a[4];\n\t\tx0i = a[1] + a[5];\n\t\tx1r = a[0] - a[4];\n\t\tx1i = a[1] - a[5];\n\t\tx2r = a[2] + a[6];\n\t\tx2i = a[3] + a[7];\n\t\tx3r = a[2] - a[6];\n\t\tx3i = a[3] - a[7];\n\t\ta[0] = x0r + x2r;\n\t\ta[1] = x0i + x2i;\n\t\ta[4] = x0r - x2r;\n\t\ta[5] = x0i - x2i;\n\t\ta[2] = x1r + x3i;\n\t\ta[3] = x1i - x3r;\n\t\ta[6] = x1r - x3i;\n\t\ta[7] = x1i + x3r;\n\t}\n\n\n\tstatic void cftx020(REAL *a)\n\t{\n\t\tREAL x0r, x0i;\n\n\t\tx0r = a[0] - a[2];\n\t\tx0i = a[1] - a[3];\n\t\ta[0] += a[2];\n\t\ta[1] += a[3];\n\t\ta[2] = x0r;\n\t\ta[3] = x0i;\n\t}\n\n\n\tstatic void rftfsub(int n, REAL *a, int nc, REAL *c)\n\t{\n\t\tint j, k, kk, ks, m;\n\t\tREAL wkr, wki, xr, xi, yr, yi;\n\n\t\tm = n >> 1;\n\t\tks = 2 * nc / m;\n\t\tkk = 0;\n\t\tfor (j = 2; j < m; j += 2) {\n\t\t\tk = n - j;\n\t\t\tkk += ks;\n\t\t\twkr = 0.5 - c[nc - kk];\n\t\t\twki = c[kk];\n\t\t\txr = a[j] - a[k];\n\t\t\txi = a[j + 1] + a[k + 1];\n\t\t\tyr = wkr * xr - wki * xi;\n\t\t\tyi = wkr * xi + wki * xr;\n\t\t\ta[j] -= yr;\n\t\t\ta[j + 1] -= yi;\n\t\t\ta[k] += yr;\n\t\t\ta[k + 1] -= yi;\n\t\t}\n\t}\n\n\n\tstatic void rftbsub(int n, REAL *a, int nc, REAL *c)\n\t{\n\t\tint j, k, kk, ks, m;\n\t\tREAL wkr, wki, xr, xi, yr, yi;\n\n\t\tm = n >> 1;\n\t\tks = 2 * nc / m;\n\t\tkk = 0;\n\t\tfor (j = 2; j < m; j += 2) {\n\t\t\tk = n - j;\n\t\t\tkk += ks;\n\t\t\twkr = 0.5 - c[nc - kk];\n\t\t\twki = c[kk];\n\t\t\txr = a[j] - a[k];\n\t\t\txi = a[j + 1] + a[k + 1];\n\t\t\tyr = wkr * xr + wki * xi;\n\t\t\tyi = wkr * xi - wki * xr;\n\t\t\ta[j] -= yr;\n\t\t\ta[j + 1] -= yi;\n\t\t\ta[k] += yr;\n\t\t\ta[k + 1] -= yi;\n\t\t}\n\t}\n\n\n\tstatic void dctsub(int n, REAL *a, int nc, REAL *c)\n\t{\n\t\tint j, k, kk, ks, m;\n\t\tREAL wkr, wki, xr;\n\n\t\tm = n >> 1;\n\t\tks = nc / n;\n\t\tkk = 0;\n\t\tfor (j = 1; j < m; j++) {\n\t\t\tk = n - j;\n\t\t\tkk += ks;\n\t\t\twkr = c[kk] - c[nc - kk];\n\t\t\twki = c[kk] + c[nc - kk];\n\t\t\txr = wki * a[j] - wkr * a[k];\n\t\t\ta[j] = wkr * a[j] + wki * a[k];\n\t\t\ta[k] = xr;\n\t\t}\n\t\ta[m] *= c[0];\n\t}\n\n\tstatic void dstsub(int n, REAL *a, int nc, REAL *c)\n\t{\n\t\tint j, k, kk, ks, m;\n\t\tREAL wkr, wki, xr;\n\n\t\tm = n >> 1;\n\t\tks = nc / n;\n\t\tkk = 0;\n\t\tfor (j = 1; j < m; j++) {\n\t\t\tk = n - j;\n\t\t\tkk += ks;\n\t\t\twkr = c[kk] - c[nc - kk];\n\t\t\twki = c[kk] + c[nc - kk];\n\t\t\txr = wki * a[k] - wkr * a[j];\n\t\t\ta[k] = wkr * a[k] + wki * a[j];\n\t\t\ta[j] = xr;\n\t\t}\n\t\ta[m] *= c[0];\n\t}\n};\n\n#endif //_DSP_MATH_SHARED_H_"
  },
  {
    "path": "plugins/Shibatch/mem_block.cpp",
    "content": "#include \"mem_block.h\"\n\nvoid * mem_block::set_size(unsigned int new_used)\n{\n\tif (new_used==0)\n\t{\n\t\tif (mem_logic != ALLOC_FAST_DONTGODOWN)\n\t\t{\n\t\t\tif (data!=0) {free(data);data=0;}\n\t\t\tsize = 0;\n\t\t}\n\t}\n\telse\n\t{\n\t\tunsigned int new_size;\n\t\tif (mem_logic == ALLOC_FAST || mem_logic == ALLOC_FAST_DONTGODOWN)\n\t\t{\n\t\t\tnew_size = size;\n\t\t\tif (new_size < 1) new_size = 1;\n\t\t\twhile(new_size < new_used) new_size <<= 1;\n\t\t\tif (mem_logic!=ALLOC_FAST_DONTGODOWN) while(new_size>>1 > new_used) new_size >>= 1;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tnew_size = new_used;\n\t\t}\n\n\t\tif (new_size!=size)\n\t\t{\n\t\t\tif (data==0)\n\t\t\t{\n\t\t\t\tdata = malloc(new_size);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvoid * new_data;\n#if defined(_DEBUG) && 0\n\t\t\t\tnew_data = malloc(new_size);\n\t\t\t\tif (new_data) memcpy(new_data,data,new_size>size ? size : new_size);\n\t\t\t\tif (size >= 4) *(DWORD*)data = 0xDEADBEEF;\n\t\t\t\tfree(data);\n\t\t\t\tdata = new_data;\n#else\n\t\t\t\tnew_data = realloc(data,new_size);\n\t\t\t\tif (new_data==0) free(data);\n\t\t\t\tdata = new_data;\n#endif\n\t\t\t}\n\t\t\tsize = new_size;\n\t\t}\n\t}\n\tused = new_used;\n\treturn data;\n}\n\nvoid mem_block::prealloc(unsigned int num)\n{\n\tif (size<num && mem_logic==ALLOC_FAST_DONTGODOWN)\n\t{\n\t\tint old_used = used;\n\t\tset_size(num);\n\t\tused = old_used;\n\t}\n}\n\nvoid* mem_block::copy(const void *ptr, unsigned bytes,unsigned start)\n{\n\tcheck_size(bytes+start);\n\n\tif (ptr)\n\t\tmemcpy((char*)get_ptr()+start,ptr,bytes);\n\telse\n\t\tmemset((char*)get_ptr()+start,0,bytes);\n\n\treturn (char*)get_ptr()+start;\n}\n\ninline static void apply_order_swap(unsigned char * base,unsigned size,unsigned ptr1,unsigned ptr2,unsigned char * temp)\n{\n\tunsigned char * realptr1 = base + ptr1 * size, * realptr2 = base + ptr2 * size;\n\tmemcpy(temp,realptr1,size);\n\tmemcpy(realptr1,realptr2,size);\n\tmemcpy(realptr2,temp,size);\n}\n#if 0\nvoid mem_block::g_apply_order(void * data,unsigned size,const int * order,unsigned num)\n{\n\tunsigned char * base = (unsigned char *) data;\n\tunsigned char * temp = (unsigned char*)alloca(size);\n\tunsigned done_size = bit_array_bittable::g_estimate_size(num);\n\tmem_block_t<unsigned char> done_block;\n\tunsigned char * done = done_size > PFC_ALLOCA_LIMIT ? done_block.set_size(done_size) : (unsigned char*)alloca(done_size);\n\tmemset(done,0,done_size);\n\tunsigned n;\n\tfor(n=0;n<num;n++)\n\t{\n\t\tunsigned next = order[n];\n\t\tif (next!=n && !bit_array_bittable::g_get(done,n))\n\t\t{\n\t\t\tunsigned prev = n;\n\t\t\tdo\n\t\t\t{\n\t\t\t\tassert(!bit_array_bittable::g_get(done,next));\n\t\t\t\tassert(next>n);\n\t\t\t\tassert(n<num);\n\t\t\t\tapply_order_swap(base,size,prev,next,temp);\n\t\t\t\tbit_array_bittable::g_set(done,next,true);\n\t\t\t\tprev = next;\n\t\t\t\tnext = order[next];\n\t\t\t} while(next!=n);\n\t\t\t//bit_array_bittable::g_set(done,n,true);\n\t\t}\n\t}\n}\n#endif\n"
  },
  {
    "path": "plugins/Shibatch/mem_block.h",
    "content": "#ifndef _PFC_MEM_BLOCK_H_\n#define _PFC_MEM_BLOCK_H_\n\n#include <cstring>\n#include <cstdlib>\n\ntemplate<class T>\nclass mem_ops\n{\npublic:\n\tstatic void copy(T* dst,const T* src,unsigned count) {memcpy(dst,src,count*sizeof(T));}\n\tstatic void move(T* dst,const T* src,unsigned count) {memmove(dst,src,count*sizeof(T));}\n\tstatic void set(T* dst,int val,unsigned count) {memset(dst,val,count*sizeof(T));}\n\tstatic void setval(T* dst,T val,unsigned count) {for(;count;count--) *(dst++)=val;}\n\tstatic T* alloc(unsigned count) {return reinterpret_cast<T*>(malloc(count * sizeof(T)));}\n\tstatic T* alloc_zeromem(unsigned count)\n\t{\n\t\tT* ptr = alloc(count);\n\t\tif (ptr) set(ptr,0,count);\n\t\treturn ptr;\n\t}\n\tstatic T* realloc_block(T* ptr,unsigned count)\n\t{return ptr ? reinterpret_cast<T*>(::realloc(reinterpret_cast<void*>(ptr),count * sizeof(T))) : alloc(count);}\n\n\tstatic void free_block(T* ptr) {::free(reinterpret_cast<void*>(ptr)); }\n\tinline static T make_null_item()\n\t{\n\t\tchar item[sizeof(T)];\n\t\tmemset(&item,0,sizeof(T));\n\t\treturn * reinterpret_cast<T*>(&item);\n\t}\n\tinline static void swap(T& item1,T& item2) {T temp; temp=item1; item1=item2; item2=temp;}\n};\n\nclass mem_block\n{\npublic:\n\tenum mem_logic_t {ALLOC_DEFAULT,ALLOC_FAST,ALLOC_FAST_DONTGODOWN};\nprivate:\n\tvoid * data;\n\tunsigned size,used;\n\tmem_logic_t mem_logic;\npublic:\n  inline void set_mem_logic(mem_logic_t v) {mem_logic=v;}\n\tinline mem_logic_t get_mem_logic() const {return mem_logic;}\n\n  void prealloc(unsigned size);\n\n\tinline mem_block() {data=0;size=0;used=0;mem_logic=ALLOC_DEFAULT;}\n\tinline ~mem_block() {if (data) free(data);}\n\n\tinline unsigned get_size() const {return used;}\n\n\tinline const void * get_ptr() const {return data;}\n\tinline void * get_ptr() {return data;}\n\n\tvoid * set_size(unsigned new_used);\n\n\tinline void * check_size(unsigned new_size)\n\t{\n\t\tif (used<new_size) return set_size(new_size);\n\t\telse return get_ptr();\n\t}\n\n\tinline operator const void * () const {return get_ptr();}\n\tinline operator void * () {return get_ptr();}\n\n\tvoid* copy(const void *ptr, unsigned bytes,unsigned start=0);\n\n\tinline void* append(const void *ptr, unsigned bytes) {return copy(ptr,bytes,used);}\n\n\tinline void zeromemory() {memset(get_ptr(),0,used);}\n\n\tinline void force_reset() {if (data) free(data);data=0;size=0;used=0;}\n\n#if 0\n  static void g_apply_order(void * data,unsigned size,const int * order,unsigned num);\n#endif\n};\n\ntemplate<class T>\nclass mem_block_t //: public mem_block\n{\n\tmem_block theBlock;//msvc7 sucks\npublic:\n\tmem_block_t() {}\n\tmem_block_t(unsigned s) {theBlock.set_size(s*sizeof(T));}\n\n\tinline void set_mem_logic(mem_block::mem_logic_t v) {theBlock.set_mem_logic(v);}\n\tinline mem_block::mem_logic_t get_mem_logic() const {return theBlock.get_mem_logic();}\n\n\tinline unsigned get_size() const {return theBlock.get_size()/sizeof(T);}\n\n\tinline const T* get_ptr() const {return static_cast<const T*>(theBlock.get_ptr());}\n\tinline T* get_ptr() {return static_cast<T*>(theBlock.get_ptr());}\n\n\tinline T* set_size(unsigned new_size) {return static_cast<T*>(theBlock.set_size(new_size*sizeof(T)));}\n\n\tinline T* check_size(unsigned new_size) {return static_cast<T*>(theBlock.check_size(new_size*sizeof(T)));}\n\n\tinline operator const T * () const {return get_ptr();}\n\tinline operator T * () {return get_ptr();}\n\n#if 0\n  inline T* copy(const T* ptr,unsigned size,unsigned start=0) {return static_cast<T*>(theBlock.copy(static_cast<const void*>(ptr),size*sizeof(T),start*sizeof(T)));}\n\tinline T* append(const T* ptr,unsigned size) {return static_cast<T*>(theBlock.append(static_cast<const void*>(ptr),size*sizeof(T)));}\n\tinline void append(T item) {theBlock.append(static_cast<const void*>(&item),sizeof(item));}\n\n  inline void swap(unsigned idx1,unsigned idx2)\n\t{\n\t\tT * ptr = get_ptr();\n\t\tmem_ops<T>::swap(ptr[idx1],ptr[idx2]);\n\t}\n\n\tunsigned write_circular(unsigned offset,const T* src,unsigned count)\n\t{//returns new offset\n\t\tunsigned total = get_size();\n\t\tif (offset<0)\n\t\t{\n\t\t\toffset = total - ( (-(int)offset)%total );\n\t\t}\n\t\telse offset%=total;\n\n\t\tif (count>total)\n\t\t{\n\t\t\tsrc += count - total;\n\t\t\tcount = total;\n\t\t}\n\n\t\twhile(count>0)\n\t\t{\n\t\t\tunsigned delta = count;\n\t\t\tif (delta > total - offset) delta = total - offset;\n\t\t\tunsigned n;\n\t\t\tfor(n=0;n<delta;n++)\n\t\t\t\tget_ptr()[n+offset] = *(src++);\n\t\t\tcount -= delta;\n\t\t\toffset = (offset + delta) % total;\n\t\t}\n\t\treturn offset;\n\t}\n\n\tunsigned read_circular(unsigned offset,T* dst,unsigned count)\n\t{\n\t\tunsigned total = get_size();\n\t\tif (offset<0)\n\t\t{\n\t\t\toffset = total - ( (-(int)offset)%total );\n\t\t}\n\t\telse offset%=total;\n\n\t\twhile(count>0)\n\t\t{\n\t\t\tunsigned delta = count;\n\t\t\tif (delta > total - offset) delta = total - offset;\n\t\t\tunsigned n;\n\t\t\tfor(n=0;n<delta;n++)\n\t\t\t\t*(dst++) = get_ptr()[n+offset];\n\t\t\tcount -= delta;\n\t\t\toffset = (offset + delta) % total;\n\t\t}\n\t\treturn offset;\n\t}\n#endif\n\tinline void zeromemory() {theBlock.zeromemory();}\n\n\tvoid fill(T val)\n\t{\n\t\tunsigned n = get_size();\n\t\tT * dst = get_ptr();\n\t\tfor(;n;n--) *(dst++) = val;\n\t}\n\n\tinline void force_reset() {theBlock.force_reset();}\n\n#if 0\n\tvoid apply_order(const int * order,unsigned num)\n\t{\n\t\tassert(num<=get_size());\n\t\tmem_block::g_apply_order(get_ptr(),sizeof(T),order,num);\n\t}\n#endif\n\n#if 0\n  inline void prealloc(unsigned size) {theBlock.prealloc(size*sizeof(T));}\n#endif\n};\n\n#if 0\ntemplate<class T>\nclass mem_block_fastalloc : public mem_block_t<T>\n{\npublic:\n\tmem_block_fastalloc(unsigned initsize=0) {set_mem_logic(mem_block::ALLOC_FAST_DONTGODOWN);if (initsize) prealloc(initsize);}\n};\n#endif\n\n#if 0\n\n#if 0\n\n#define mem_block_aligned_t mem_block_t\n\n#else\n\ntemplate<class T>\nclass mem_block_aligned_t\n{\n\tmem_block data;\n\tT * ptr_aligned;\npublic:\n\tmem_block_aligned_t() {ptr_aligned = 0;}\n\tmem_block_aligned_t(unsigned size) {ptr_aligned = 0;set_size(size);}\n\n\tunsigned get_size() const {return data.get_size()/sizeof(T);}\n\n\tinline void set_mem_logic(mem_block::mem_logic_t v) {data.set_mem_logic(v);}\n\tinline mem_block::mem_logic_t get_mem_logic() const {return data.get_mem_logic();}\n\n\tT * set_size(unsigned size)\n\t{\n\t\tunsigned size_old = get_size();\n\t\tint delta_old = (unsigned)ptr_aligned - (unsigned)data.get_ptr();\n\t\tunsigned ptr = (unsigned)data.set_size( (size+1) * sizeof(T) - 1), old_ptr = ptr;\n\t\tptr += sizeof(T) - 1;\n\t\tptr -= ptr % sizeof(T);\n\t\tint delta_new = ptr - old_ptr;\n\t\tif (delta_new != delta_old)\n\t\t{\n\t\t\tunsigned to_move = size_old > size ? size : size_old;\n\t\t\tmemmove((char*)ptr,(char*)ptr - (delta_new-delta_old),to_move * sizeof(T));\n\t\t}\n\t\tptr_aligned = (T*)ptr;\n\t\treturn ptr_aligned;\n\t}\n\n\tT* check_size(unsigned size)\n\t{\n\t\treturn size > get_size() ? set_size(size) : get_ptr();\n\t}\n\n\tvoid fill(T val)\n\t{\n\t\tunsigned n = get_size();\n\t\tT * dst = get_ptr();\n\t\tfor(;n;n--) *(dst++) = val;\n\t}\n\n\tinline void zeromemory() {data.zeromemory();}\n\tinline const T * get_ptr() const {return ptr_aligned;}\n\tinline T * get_ptr() {return ptr_aligned;}\n\tinline operator const T * () const {return get_ptr();}\n\tinline operator T * () {return get_ptr();}\n};\n#endif\n#endif\n#endif"
  },
  {
    "path": "plugins/Shibatch/paramlist.h",
    "content": "#ifndef __PARAMLIST_H__\n#define __PARAMLIST_H__\n\n#include <cstdio>\n#include <stdlib.h>\n#include <string.h>\n\nclass paramlistelm {\npublic:\n\tparamlistelm *next;\n\n\tchar left,right;\n\tfloat lower,upper,gain,gain2;\n\tint sortindex;\n\n\tparamlistelm(void) {\n\t\tleft = right = 1;\n\t\tlower = upper = gain = 0;\n\t\tnext = NULL;\n\t};\n\n\t~paramlistelm() {\n\t\tdelete next;\n\t\tnext = NULL;\n\t};\n\n\tchar *getString(void) {\n\t\tstatic char str[64];\n\t\tsprintf(str,\"%gHz to %gHz, %gdB %c%c\",\n\t\t\t(double)lower,(double)upper,(double)gain,left?'L':' ',right?'R':' ');\n\t\treturn str;\n\t}\n};\n\nclass paramlist {\npublic:\n\tparamlistelm *elm;\n\n\tparamlist(void) {\n\t\telm = NULL;\n\t}\n\n\t~paramlist() {\n\t\tdelete elm;\n\t\telm = NULL;\n\t}\n\n\tvoid copy(paramlist &src)\n\t{\n\t\tdelete elm;\n\t\telm = NULL;\n\n\t\tparamlistelm **p,*q;\n\t\tfor(p=&elm,q=src.elm;q != NULL;q = q->next,p = &(*p)->next)\n\t\t{\n\t\t\t*p = new paramlistelm;\n\t\t\t(*p)->left  = q->left;\n\t\t\t(*p)->right = q->right;\n\t\t\t(*p)->lower = q->lower;\n\t\t\t(*p)->upper = q->upper;\n\t\t\t(*p)->gain  = q->gain;\n\t\t}\n\t}\n\n\tparamlistelm *newelm(void)\n\t{\n\t\tparamlistelm **e;\n\t\tfor(e = &elm;*e != NULL;e = &(*e)->next) ;\n\t\t*e = new paramlistelm;\n\n\t\treturn *e;\n\t}\n\n\tint getnelm(void)\n\t{\n\t\tint i;\n\t\tparamlistelm *e;\n\n\t\tfor(e = elm,i = 0;e != NULL;e = e->next,i++) ;\n\n\t\treturn i;\n\t}\n\n\tvoid delelm(paramlistelm *p)\n\t{\n\t\tparamlistelm **e;\n\t\tfor(e = &elm;*e != NULL && p != *e;e = &(*e)->next) ;\n\t\tif (*e == NULL) return;\n\t\t*e = (*e)->next;\n\t\tp->next = NULL;\n\t\tdelete p;\n\t}\n\n\tvoid sortelm(void)\n\t{\n\t\tint i=0;\n\n\t\tif (elm == NULL) return;\n\n\t\tfor(paramlistelm *r = elm;r\t!= NULL;r = r->next) r->sortindex = i++;\n\n\t\tparamlistelm **p,**q;\n\n\t\tfor(p=&elm->next;*p != NULL;)\n\t\t{\n\t\t\tfor(q=&elm;*q != *p;q = &(*q)->next)\n\t\t\t\tif ((*p)->lower < (*q)->lower ||\n\t\t\t\t\t((*p)->lower == (*q)->lower && (*p)->sortindex < (*q)->sortindex)) break;\n\n\t\t\tif (p == q) {p = &(*p)->next; continue;}\n\n\t\t\tparamlistelm **pn = p;\n\t\t\tparamlistelm *pp = *p;\n\t\t\t*p = (*p)->next;\n\t\t\tpp->next = *q;\n\t\t\t*q = pp;\n\n\t\t\tp = pn;\n\t    }\n\t}\n};\n#endif // __PARAMLIST_H__\n"
  },
  {
    "path": "plugins/Shibatch/shibatch.cpp",
    "content": "/******************************************************\nSuperEQ written by Naoki Shibata  shibatch@users.sourceforge.net\n\nShibatch Super Equalizer is a graphic and parametric equalizer plugin\nfor winamp. This plugin uses 16383th order FIR filter with FFT algorithm.\nIt's equalization is very precise. Equalization setting can be done\nfor each channel separately.\n\n\nHomepage : http://shibatch.sourceforge.net/\ne-mail   : shibatch@users.sourceforge.net\n\nSome changes are from foobar2000 (www.foobar2000.org):\n\nCopyright (c) 2001-2003, Peter Pawlowski\nAll rights reserved.\n\nOther changes are:\n\nCopyright (c) 2003, Klaus Post\n\n*******************************************************/\n\n#include <avisynth.h>\n#include \"ssrc-convert.h\"\n#include \"supereq.h\"\n\nconst AVS_Linkage * AVS_linkage = 0;\nextern \"C\" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors) {\n  AVS_linkage = vectors;\n\n  env->AddFunction(\"SSRC\", \"ci[fast]b\", Create_SSRC, 0);\n\n  env->AddFunction(\"SuperEQ\", \"cs\", Create_SuperEq, 0);\n  env->AddFunction(\"SuperEQ\", \"ci+\", Create_SuperEqCustom, 0);\n\n  return \"`Shibatch' Audio equalization and high-quality resampling from Naoki Shibata\";\n}\n"
  },
  {
    "path": "plugins/Shibatch/ssrc-convert.cpp",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include \"ssrc-convert.h\"\n#include <avs/config.h>\n#ifdef AVS_WINDOWS\n#include <avs/win.h>\n#endif\n\n\n/******************************************\n *******   Resample Audio using SSRC******\n *****************************************/\n\n\nSSRC::SSRC(PClip _child, int _target_rate, bool _fast, IScriptEnvironment* env)\n  : GenericVideoFilter(_child), target_rate(_target_rate), fast(_fast)\n{\n  srcbuffer = nullptr;  // If constructor should return\n  res = nullptr;\n\n  if ((target_rate==vi.audio_samples_per_second)||(vi.audio_samples_per_second==0)) {\n\t\tskip_conversion=true;\n\t\treturn;\n\t}\n\n  skip_conversion = false;\n  source_rate = vi.audio_samples_per_second;\n\n  factor = double(target_rate) / vi.audio_samples_per_second;\n  vi.num_audio_samples = (vi.num_audio_samples * target_rate + vi.audio_samples_per_second - 1) / vi.audio_samples_per_second; // Ceil\n\n  res = SSRC_create(source_rate, target_rate, vi.AudioChannels(), 2,1, fast);\n\n  if (!res)\n    env->ThrowError(\"SSRC: could not resample between the two samplerates.\");\n\n  input_samples = source_rate;  // We convert one second of input per loop.\n  vi.audio_samples_per_second = target_rate;\n  srcbuffer = new SFLOAT[vi.AudioChannels() * input_samples];\n\n  for(int i=0; i<vi.AudioChannels() * input_samples; i++)  // We stuff one second into the input (preroll)\n    srcbuffer[i] = 0.0f;\n\n  next_sample = -target_rate;\n  inputReadOffset = 0;\n  res->Write(srcbuffer, input_samples * vi.AudioChannels());\n\n}\n\n /***************************************\n * Implementation notes:\n * - For some strange reason SSRC delivers a\n * loud click in the very beginning of the sample.\n *   Therefore we preroll a second of audio whenever\n * a new instance is created.\n ****************************************/\n\n\nvoid __stdcall SSRC::GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env)\n{\n  if (skip_conversion) {\n\t\tchild->GetAudio(buf, start, count, env);\n\t\treturn;\n\t}\n\n  count *= vi.AudioChannels();   // This is how SSRC keeps count. We'll do the same\n\n  if (start != next_sample) {  // Reset on seek\n    bool skip_restart = false;\n\n    if (start > next_sample) { // Don't seek if within 10 sek, but skip\n      if ((next_sample + input_samples * 10) > start) {\n        skip_restart = true;\n      }\n    }\n\n    if (!skip_restart)  {\n      inputReadOffset = (start * source_rate / target_rate) -  input_samples;  // Floor, Reset at new read position minus ONE second.\n      res = SSRC_create(source_rate, target_rate, vi.AudioChannels(), 2, 1, fast);\n      _RPT2(0, \"SSRC: Resetting position. Next_sample: %d. Start:%d.!\\n\", (int)next_sample, (int)start);\n      next_sample = start - target_rate;\n    }\n  }\n\n\n  int ssrc_samples_tbr = int(count)*sizeof(SFLOAT);  // count in bytes\n  bool buffer_full = false;\n\n\n  if (next_sample < start) { // Skip\n    int skip_count = int(start - next_sample) * vi.AudioChannels();\n    _RPT1(0,\"SSRC: Skipping %u samples\", skip_count);\n    int skip_nsamples = skip_count*sizeof(SFLOAT);  // count in bytes\n    do {\n      int ssrc_samples_av;\n      res->GetBuffer(&ssrc_samples_av);\n\n      if (ssrc_samples_av < skip_nsamples) {  // We don't have enough bytes - feed more.\n\n        child->GetAudio(srcbuffer, inputReadOffset, input_samples, env);\n        inputReadOffset += input_samples;\n\n        res->Write(srcbuffer, input_samples * vi.AudioChannels());\n\n      } else {  // Now we have enough data\n        res->Read(skip_count);\n        next_sample += start;\n        buffer_full = true;\n      }\n    } while (!buffer_full);\n\n    buffer_full = false;\n  }\n\n\n  do {\n    int ssrc_samples_av;\n    SFLOAT* ssrc_samples = res->GetBuffer(&ssrc_samples_av);\n\n    if (ssrc_samples_av < ssrc_samples_tbr) {  // We don't have enough bytes - feed more.\n\n      child->GetAudio(srcbuffer, inputReadOffset, input_samples, env);\n      inputReadOffset += input_samples;\n      res->Write(srcbuffer, input_samples * vi.AudioChannels());\n\n    } else {  // Now we have enough data\n\n      env->BitBlt((BYTE*)buf, ssrc_samples_tbr, (BYTE*)ssrc_samples, ssrc_samples_tbr, ssrc_samples_tbr , 1);\n      res->Read((unsigned int)count);\n      buffer_full = true;\n    }\n\n  } while (!buffer_full);\n  next_sample = start + (count/vi.AudioChannels());\n\n}\n\nAVSValue __cdecl Create_SSRC(AVSValue args, void*, IScriptEnvironment* env) {\n\n  PClip clip = args[0].AsClip();\n\n  if (!clip->GetVideoInfo().HasAudio())\n    env->ThrowError(\"Input clip does not have audio.\");\n\n  if (!(clip->GetVideoInfo().SampleType()&SAMPLE_FLOAT))\n    env->ThrowError(\"Input audio sample format to SSRC must be float.\");\n\n  return new SSRC(args[0].AsClip(), args[1].AsInt(), args[2].AsBool(true), env);\n}\n"
  },
  {
    "path": "plugins/Shibatch/ssrc-convert.h",
    "content": "// Avisynth v2.5.  Copyright 2002 Ben Rudiak-Gould et al.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#ifndef __SSRC_Audio_H__\n#define __SSRC_Audio_H__\n\ntypedef float REAL;\n\n#include <avisynth.h>\n#include \"ssrc.h\"\n\n\nAVSValue __cdecl Create_SSRC(AVSValue args, void*, IScriptEnvironment* env);\n\n\nclass SSRC : public GenericVideoFilter\n/**\n  * Class to resample the audio stream\n **/\n{\npublic:\n  SSRC(PClip _child, int _target_rate, bool _fast, IScriptEnvironment* env);\n  ~SSRC() {\n     delete res;\n     delete[] srcbuffer;\n    }\n  void __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env);\n  static AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\n\nprivate:\n  const int target_rate;\n  int source_rate;\n  int srcbuffer_size;\n  bool skip_conversion;\n  double factor;\n  int input_samples;\n  bool fast;\n\n  SFLOAT* srcbuffer;\n  int64_t next_sample;\n  int64_t inputReadOffset;\n\n\tResampler_base * res;\n\n};\n\n\n#endif  // __SSRC_Audio_H__\n\n"
  },
  {
    "path": "plugins/Shibatch/ssrc.cpp",
    "content": "﻿/******************************************************\n  A fast and high quality sampling rate converter SSRC\n                                           written by Naoki Shibata\n\n\nHomepage : http://shibatch.sourceforge.net/\ne-mail   : shibatch@users.sourceforge.net\n\nSome changes are:\n\nCopyright (c) 2001-2003, Peter Pawlowski\nAll rights reserved.\n\n*******************************************************/\n\n#include \"ssrc.h\"\n#include <avs/alignment.h>\n#include <avs/config.h>\n#include <cassert>\n\n#pragma warning(disable:4244)\n\ntemplate<class REAL>\nclass Resampler_i_base : public Resampler_base\n{\nprotected:\n\tResampler_i_base(const Resampler_base::CONFIG & c) : Resampler_base(c) {}\n\tvoid make_outbuf(int nsmplwrt2, REAL* outbuf, int& delay2);\n  void make_inbuf(int nsmplread, int inbuflen, REAL_inout* rawinbuf, REAL* inbuf, int toberead);\n};\n\n#define M 15\n\n#ifndef M_PI\n#define M_PI 3.1415926535897932384626433832795028842\n#endif\n\n#define RANDBUFLEN 65536\n\n#define RINT(x) ((x) >= 0 ? ((int)((x) + 0.5)) : ((int)((x) - 0.5)))\n\nextern \"C\"\n{\nextern double dbesi0(double);\n}\n\n\nstatic double alpha(double a)\n{\n  if (a <= 21) return 0;\n  if (a <= 50) return 0.5842*pow(a-21,0.4)+0.07886*(a-21);\n  return 0.1102*(a-8.7);\n}\n\n\nstatic double win(double n,int len,double alp,double iza)\n{\n  return dbesi0(alp*sqrt(1-4*n*n/(((double)len-1)*((double)len-1))))/iza;\n}\n\nstatic double sinc(double x)\n{\n  return x == 0 ? 1 : sin(x)/x;\n}\n\nstatic double hn_lpf(int n,double lpf,double fs)\n{\n  double t = 1/fs;\n  double omega = 2*M_PI*lpf;\n  return 2*lpf*t*sinc(n*omega*t);\n}\n\n\n\n\nstatic int gcd(int x, int y)\n{\n    int t;\n\n    while (y != 0) {\n        t = x % y;  x = y;  y = t;\n    }\n    return x;\n}\n\nint CanResample(int sfrq,int dfrq)\n{\n\tif (sfrq==dfrq) return 1;\n    int frqgcd = gcd(sfrq,dfrq);\n\n\tif (dfrq>sfrq)\n\t{\n\t\tint fs1 = sfrq / frqgcd * dfrq;\n\n\t\tif (fs1/dfrq == 1) return 1;\n\t\telse if (fs1/dfrq % 2 == 0) return 1;\n\t\telse if (fs1/dfrq % 3 == 0) return 1;\n\t\telse return 0;\n\t}\n\telse\n\t{\n\t\tif (dfrq/frqgcd == 1) return 1;\n\t\telse if (dfrq/frqgcd % 2 == 0) return 1;\n\t\telse if (dfrq/frqgcd % 3 == 0) return 1;\n\t\telse return 0;\n\t}\n}\n\nvoid Buffer::Read(int size)\n{\n\tif (size)\n\t{\n\t\tif (buf_data==size) buf_data=0;\n\t\telse\n\t\t{\n\t\t\tmem_ops<REAL_inout>::move(buffer,buffer+size,buf_data-size);\n\t\t\tbuf_data-=size;\n\t\t}\n\t}\n}\n\nvoid Buffer::Write(const REAL_inout * ptr,int size)\n{\n\tbuffer.check_size(buf_data + size);\n\tmem_ops<REAL_inout>::copy(buffer+buf_data,ptr,size);\n\tbuf_data+=size;\n}\n\nvoid Resampler_base::bufloop(int finish)\n{\n\tint s;\n\tREAL_inout * ptr = in.GetBuffer(&s);\n\tint done=0;\n\twhile(done<s)\n\t{\n\t\tint d=Resample(ptr,s-done,finish);\n\t\tif (d==0) break;\n\t\tdone+=d;\n\t\tptr+=d;\n\t}\n\tin.Read(done);\n}\n\nvoid Resampler_base::Write(const REAL_inout * input,int size)\n{\n\tin.Write(input,size);\n\tbufloop(0);\n}\n\ntemplate<class REAL>\nvoid Resampler_i_base<REAL>::make_inbuf(int nsmplread, int inbuflen, REAL_inout* rawinbuf, REAL* inbuf, int toberead)\n{\n\tconst int\tMaxLoop = nsmplread * nch;\n\tconst int\tInbufBase = inbuflen * nch;\n\n\tfor(int i = 0; i < MaxLoop; i++) {\n\t\tinbuf[InbufBase + i] = rawinbuf[i];\n\t}\n\n\tsize_t\tClearSize = toberead - nsmplread;\n\n\tif(ClearSize) {\n\t\tmemset(inbuf + InbufBase + MaxLoop, 0, ClearSize * nch * sizeof(REAL));\n\t}\n}\n\ntemplate<class REAL>\nvoid Resampler_i_base<REAL>::make_outbuf(int nsmplwrt2, REAL* outbuf, int& delay2)\n{\n\tconst int\tMaxLoop = nsmplwrt2 * nch;\n\n\tfor(int i = 0; i < MaxLoop; i++) {\n\t\tREAL\ts = outbuf[i] * gain;\n\n\t\tif(s > 1.0) {\n\t\t\tpeak = peak < s ? s : peak;\n//\t\t\ts =  1.0;\n\t\t} else if(s < -1.0) {\n\t\t\tpeak = peak < -s ? -s : peak;\n//\t\t\ts = -1.0;\n\t\t}\n\n\t\t__output((REAL_inout)s,delay2);\n\t}\n}\n\n\n#ifdef _WIN32\n#if defined(GCC) || (defined(CLANG) && !defined(MSVC))\n#ifndef MulDiv\n  #define MulDiv(x,y,z) ((x)*(y)/(z))\n#endif\n#else\nextern \"C\" {\n  _declspec(dllimport) int _stdcall MulDiv(int nNumber,int nNumerator,int nDenominator);\n}\n#endif\n#else\n#ifndef MulDiv\n  #define MulDiv(x,y,z) ((x)*(y)/(z))\n#endif\n#endif\n\nunsigned int Resampler_base::GetLatency()\n{\n\treturn MulDiv(in.Size(),1000,sfrq*nch) + MulDiv(out.Size(),1000,dfrq*nch);\n}\n\ntemplate<class REAL>\nclass Upsampler : public Resampler_i_base<REAL>\n{\n  using Resampler_i_base<REAL>::FFTFIRLEN;\n  using Resampler_i_base<REAL>::peak;\n  using Resampler_i_base<REAL>::sfrq;\n  using Resampler_i_base<REAL>::dfrq;\n  using Resampler_i_base<REAL>::nch;\n  using Resampler_i_base<REAL>::DF;\n  using Resampler_i_base<REAL>::AA;\n  using Resampler_i_base<REAL>::make_outbuf;\n  using Resampler_i_base<REAL>::make_inbuf;\n\n  int64_t fs1;\n  int frqgcd,osf,fs2;\n  REAL **stage1,*stage2;\n  int n1,n1x,n1y,n2,n2b;\n  int filter2len;\n  int *f1order,*f1inc;\n  int *fft_ip;// = NULL;\n  REAL *fft_w;// = NULL;\n  //unsigned char *rawinbuf,*rawoutbuf;\n  REAL *inbuf,*outbuf;\n  REAL **buf1,**buf2;\n  int spcount;\n  int i,j;\n\n\t\tint n2b2;//=n2b/2;\n\t\tint rp;        // keep the location of the next samples to read in inbuf at fs1.\n\t\tint ds;        // number of samples to dispose next in sfrq.\n\t\tint nsmplwrt1; // actually number of samples to send stage2 filters .\n\t\tint nsmplwrt2; // actually number of samples to send stage2 filters .\n\t\tint s1p;       // the reminder obtained by dividing the samples output from stage1 filter by n1y*osf.\n    int init;\n\t\tunsigned int sumread,sumwrite;\n\t\tint osc;\n\t\tREAL *ip,*ip_backup;\n\t\tint s1p_backup,osc_backup;\n\t\tint p;\n\t\tint inbuflen;\n\t\tint delay;// = 0;\n\t\tint delay2;\n\n\npublic:\n  Upsampler(const Resampler_base::CONFIG & c);\n  unsigned int Resample(REAL_inout * rawinbuf, unsigned int in_size, int ending);\n  ~Upsampler();\n\n};\n\n\ntemplate<class REAL>\nUpsampler<REAL>::Upsampler(const Resampler_base::CONFIG & c) : Resampler_i_base<REAL>(c)\n{\n  fft_ip = NULL;\n  fft_w = NULL;\n  peak = 0;\n  spcount = 0;\n\n\n  filter2len = FFTFIRLEN; /* stage 2 filter length */\n\n                          /* Make stage 1 filter */\n\n  {\n    double aa = AA; /* stop band attenuation(dB) */\n    double lpf, delta, d, df, alp, iza;\n    double guard = 2;\n\n    frqgcd = gcd(sfrq, dfrq);\n\n    fs1 = (int64_t)(sfrq / frqgcd) * (int64_t)dfrq;\n\n    if (fs1 / dfrq == 1) osf = 1;\n    else if (fs1 / dfrq % 2 == 0) osf = 2;\n    else if (fs1 / dfrq % 3 == 0) osf = 3;\n    else {\n      //\t\t  fprintf(stderr,\"Resampling from %dHz to %dHz is not supported.\\n\",sfrq,dfrq);\n      //\t\t  fprintf(stderr,\"%d/gcd(%d,%d)=%d must be divided by 2 or 3.\\n\",sfrq,sfrq,dfrq,fs1/dfrq);\n      //\t\t  exit(-1);\n      return;\n    }\n\n    df = (dfrq*osf / 2 - sfrq / 2) * 2 / guard;\n    lpf = sfrq / 2 + (dfrq*osf / 2 - sfrq / 2) / guard;\n\n    delta = pow(10.0, -aa / 20);\n    if (aa <= 21) d = 0.9222; else d = (aa - 7.95) / 14.36;\n\n    n1 = fs1 / df * d + 1;\n    if (n1 % 2 == 0) n1++;\n\n    alp = alpha(aa);\n    iza = dbesi0(alp);\n    //printf(\"iza = %g\\n\",iza);\n\n    n1y = fs1 / sfrq;\n    n1x = n1 / n1y + 1;\n\n    f1order = (int*)avs_malloc(sizeof(int)*n1y*osf, 64);\n    for (i = 0; i<n1y*osf; i++) {\n      f1order[i] = fs1 / sfrq - (i*(fs1 / (dfrq*osf))) % (fs1 / sfrq);\n      if (f1order[i] == fs1 / sfrq) f1order[i] = 0;\n    }\n\n    f1inc = (int*)avs_malloc(sizeof(int)*n1y*osf, 64);\n    for (i = 0; i<n1y*osf; i++) {\n      f1inc[i] = f1order[i] < fs1 / (dfrq*osf) ? nch : 0;\n      if (f1order[i] == fs1 / sfrq) f1order[i] = 0;\n    }\n\n    stage1 = (REAL**)avs_malloc(sizeof(REAL *)*n1y, 64);\n    stage1[0] = (REAL*)avs_malloc(sizeof(REAL)*n1x*n1y, 64);\n\n    for (i = 1; i<n1y; i++) {\n      stage1[i] = &(stage1[0][n1x*i]);\n      for (j = 0; j<n1x; j++) stage1[i][j] = 0;\n    }\n\n    for (i = -(n1 / 2); i <= n1 / 2; i++)\n    {\n      stage1[(i + n1 / 2) % n1y][(i + n1 / 2) / n1y] = win(i, n1, alp, iza)*hn_lpf(i, lpf, fs1)*fs1 / sfrq;\n    }\n  }\n\n  /* Make stage 2 filter */\n\n  {\n    double aa = AA; /* stop band attenuation(dB) */\n    double lpf, delta, d, df, alp, iza;\n    int ipsize, wsize;\n\n    delta = pow(10.0, -aa / 20);\n    if (aa <= 21) d = 0.9222; else d = (aa - 7.95) / 14.36;\n\n    fs2 = dfrq * osf;\n\n    for (i = 1;; i = i * 2)\n    {\n      n2 = filter2len * i;\n      if (n2 % 2 == 0) n2--;\n      df = (fs2*d) / (n2 - 1);\n      lpf = sfrq / 2;\n      if (df < DF) break;\n    }\n\n    alp = alpha(aa);\n\n    iza = dbesi0(alp);\n\n    for (n2b = 1; n2b<n2; n2b *= 2);\n    n2b *= 2;\n\n    stage2 = (REAL*)avs_malloc(sizeof(REAL)*n2b, 64);\n\n    for (i = 0; i<n2b; i++) stage2[i] = 0;\n\n    for (i = -(n2 / 2); i <= n2 / 2; i++) {\n      stage2[i + n2 / 2] = win(i, n2, alp, iza)*hn_lpf(i, lpf, fs2) / n2b * 2;\n    }\n\n    ipsize = 2 + sqrt((double)n2b);\n    fft_ip = (int*)avs_malloc(sizeof(int)*ipsize, 64);\n    fft_ip[0] = 0;\n    wsize = n2b / 2;\n    fft_w = (REAL*)avs_malloc(sizeof(REAL)*wsize, 64);\n\n    fft<REAL>::rdft(n2b, 1, stage2, fft_ip, fft_w);\n  }\n\n  //\t  delay=0;\n  n2b2 = n2b / 2;\n\n  buf1 = (REAL**)avs_malloc(sizeof(REAL *)*nch, 64);\n  for (i = 0; i<nch; i++)\n  {\n    buf1[i] = (REAL*)avs_malloc(sizeof(REAL)*(n2b2 / osf + 1), 64);\n    for (j = 0; j<(n2b2 / osf + 1); j++) buf1[i][j] = 0;\n  }\n\n  buf2 = (REAL**)avs_malloc(sizeof(REAL *)*nch, 64);\n  for (i = 0; i<nch; i++) buf2[i] = (REAL*)avs_malloc(sizeof(REAL)*n2b, 64);\n\n\n  inbuf = (REAL*)avs_malloc(nch*(n2b2 + n1x) * sizeof(REAL), 64);\n  outbuf = (REAL*)avs_malloc(sizeof(REAL)*nch*(n2b2 / osf + 1), 64);\n\n  s1p = 0;\n  rp = 0;\n  ds = 0;\n  osc = 0;\n\n  init = 1;\n  inbuflen = n1 / 2 / (fs1 / sfrq) + 1;\n  delay = (double)n2 / 2 / (fs2 / dfrq);\n  delay2 = delay * nch;\n\n  sumread = sumwrite = 0;\n\n}\n\ntemplate<class REAL>\nunsigned int Upsampler<REAL>::Resample(REAL_inout * rawinbuf, unsigned int in_size, int ending)\n{\n  /* Apply filters */\n\n  int nsmplread, toberead, toberead2;\n  unsigned int rv = 0;\n  int ch;\n\n\n  toberead2 = toberead = floor((double)n2b2*sfrq / (dfrq*osf)) + 1 + n1x - inbuflen;\n\n  if (!ending)\n  {\n    rv = nch * toberead;\n    if (in_size<rv) return 0;\n    nsmplread = toberead;\n  }\n  else\n  {\n    nsmplread = in_size / nch;\n    rv = nsmplread * nch;\n  }\n\n  make_inbuf(nsmplread, inbuflen, rawinbuf, inbuf, toberead);\n\n  inbuflen += toberead2;\n\n  sumread += nsmplread;\n\n  //nsmplwrt1 = ((rp-1)*sfrq/fs1+inbuflen-n1x)*dfrq*osf/sfrq;\n  //if (nsmplwrt1 > n2b2) nsmplwrt1 = n2b2;\n  nsmplwrt1 = n2b2;\n\n\n  // apply stage 1 filter\n\n  ip = &inbuf[((sfrq*(rp - 1) + fs1) / fs1)*nch];\n\n  s1p_backup = s1p;\n  ip_backup = ip;\n  osc_backup = osc;\n\n  for (ch = 0; ch<nch; ch++)\n  {\n    REAL *op = &outbuf[ch];\n    int fdo = fs1 / (dfrq*osf), no = n1y * osf;\n\n    s1p = s1p_backup; ip = ip_backup + ch;\n\n    switch (n1x)\n    {\n    case 7:\n      for (p = 0; p<nsmplwrt1; p++)\n      {\n        int s1o = f1order[s1p];\n\n        buf2[ch][p] =\n          stage1[s1o][0] * *(ip + 0 * nch) +\n          stage1[s1o][1] * *(ip + 1 * nch) +\n          stage1[s1o][2] * *(ip + 2 * nch) +\n          stage1[s1o][3] * *(ip + 3 * nch) +\n          stage1[s1o][4] * *(ip + 4 * nch) +\n          stage1[s1o][5] * *(ip + 5 * nch) +\n          stage1[s1o][6] * *(ip + 6 * nch);\n\n        ip += f1inc[s1p];\n\n        s1p++;\n        if (s1p == no) s1p = 0;\n      }\n      break;\n\n    case 9:\n      for (p = 0; p<nsmplwrt1; p++)\n      {\n        int s1o = f1order[s1p];\n\n        buf2[ch][p] =\n          stage1[s1o][0] * *(ip + 0 * nch) +\n          stage1[s1o][1] * *(ip + 1 * nch) +\n          stage1[s1o][2] * *(ip + 2 * nch) +\n          stage1[s1o][3] * *(ip + 3 * nch) +\n          stage1[s1o][4] * *(ip + 4 * nch) +\n          stage1[s1o][5] * *(ip + 5 * nch) +\n          stage1[s1o][6] * *(ip + 6 * nch) +\n          stage1[s1o][7] * *(ip + 7 * nch) +\n          stage1[s1o][8] * *(ip + 8 * nch);\n\n        ip += f1inc[s1p];\n\n        s1p++;\n        if (s1p == no) s1p = 0;\n      }\n      break;\n\n    default:\n      for (p = 0; p<nsmplwrt1; p++)\n      {\n        REAL tmp = 0;\n        REAL *ip2 = ip;\n\n        int s1o = f1order[s1p];\n\n        for (i = 0; i<n1x; i++)\n        {\n          tmp += stage1[s1o][i] * *ip2;\n          ip2 += nch;\n        }\n        buf2[ch][p] = tmp;\n\n        ip += f1inc[s1p];\n\n        s1p++;\n        if (s1p == no) s1p = 0;\n      }\n      break;\n    }\n\n    osc = osc_backup;\n\n    // apply stage 2 filter\n\n    for (p = nsmplwrt1; p<n2b; p++) buf2[ch][p] = 0;\n\n    //for(i=0;i<n2b2;i++) printf(\"%d:%g \",i,buf2[ch][i]);\n\n    fft<REAL>::rdft(n2b, 1, buf2[ch], fft_ip, fft_w);\n\n\n    buf2[ch][0] = stage2[0] * buf2[ch][0];\n    buf2[ch][1] = stage2[1] * buf2[ch][1];\n\n\n\n    for (i = 1; i<n2b / 2; i++)\n    {\n      REAL re, im;\n\n      re = stage2[i * 2] * buf2[ch][i * 2] - stage2[i * 2 + 1] * buf2[ch][i * 2 + 1];\n      im = stage2[i * 2 + 1] * buf2[ch][i * 2] + stage2[i * 2] * buf2[ch][i * 2 + 1];\n\n      //printf(\"%d : %g %g %g %g %g %g\\n\",i,stage2[i*2],stage2[i*2+1],buf2[ch][i*2],buf2[ch][i*2+1],re,im);\n\n      buf2[ch][i * 2] = re;\n      buf2[ch][i * 2 + 1] = im;\n    }\n\n    fft<REAL>::rdft(n2b, -1, buf2[ch], fft_ip, fft_w);\n\n    for (i = osc, j = 0; i<n2b2; i += osf, j++)\n    {\n      REAL f = (buf1[ch][j] + buf2[ch][i]);\n      op[j*nch] = f;\n    }\n\n    nsmplwrt2 = j;\n\n    osc = i - n2b2;\n\n    for (j = 0; i<n2b; i += osf, j++)\n      buf1[ch][j] = buf2[ch][i];\n\n  }\n\n  rp += nsmplwrt1 * (sfrq / frqgcd) / osf;\n\n\n  make_outbuf(nsmplwrt2, outbuf, delay2);\n\n  if (!init) {\n    if (ending) {\n      if ((double)sumread*dfrq / sfrq + 2 > sumwrite + nsmplwrt2) {\n\n\n        sumwrite += nsmplwrt2;\n      }\n      else {\n\n      }\n    }\n    else {\n      sumwrite += nsmplwrt2;\n    }\n  }\n  else {\n    if (nsmplwrt2 < delay) {\n      delay -= nsmplwrt2;\n    }\n    else {\n      if (ending) {\n        if ((double)sumread*dfrq / sfrq + 2 > sumwrite + nsmplwrt2 - delay) {\n          sumwrite += nsmplwrt2 - delay;\n        }\n        else {\n\n        }\n      }\n      else {\n\n        sumwrite += nsmplwrt2 - delay;\n        init = 0;\n      }\n    }\n  }\n\n  {\n    int ds = (rp - 1) / (fs1 / sfrq);\n\n    assert(inbuflen >= ds);\n\n    mem_ops<REAL>::move(inbuf, inbuf + nch * ds, nch*(inbuflen - ds));\n    inbuflen -= ds;\n    rp -= ds * (fs1 / sfrq);\n  }\n\n  return rv;\n\n}\n\ntemplate<class REAL>\nUpsampler<REAL>::~Upsampler()\n{\n  avs_free(f1order);\n  avs_free(f1inc);\n  avs_free(stage1[0]);\n  avs_free(stage1);\n  avs_free(stage2);\n  avs_free(fft_ip);\n  avs_free(fft_w);\n  for (i = 0; i<nch; i++) avs_free(buf1[i]);\n  avs_free(buf1);\n  for (i = 0; i<nch; i++) avs_free(buf2[i]);\n  avs_free(buf2);\n  avs_free(inbuf);\n  avs_free(outbuf);\n  //free(rawoutbuf);\n}\n\n\ntemplate<class REAL>\nclass Downsampler : public Resampler_i_base<REAL>\n{\n  //using Resampler_i_base<REAL>::peak; overridden here\n  // Strict c++: access protected fields from a templated class (or use this->)\n  using Resampler_i_base<REAL>::FFTFIRLEN;\n  using Resampler_i_base<REAL>::sfrq;\n  using Resampler_i_base<REAL>::dfrq;\n  using Resampler_i_base<REAL>::nch;\n  using Resampler_i_base<REAL>::DF;\n  using Resampler_i_base<REAL>::AA;\n  using Resampler_i_base<REAL>::make_outbuf;\n  using Resampler_i_base<REAL>::make_inbuf;\n\nprivate:\n  int frqgcd,osf,fs1,fs2;\n  REAL *stage1,**stage2;\n  int n2,n2x,n2y,n1,n1b;\n  int filter1len;\n  int *f2order,*f2inc;\n  int *fft_ip;// = NULL;\n  REAL *fft_w;// = NULL;\n  //unsigned char *rawinbuf,*rawoutbuf;\n  REAL *inbuf,*outbuf;\n  REAL **buf1,**buf2;\n  int i,j;\n  int spcount;// = 0;\n  double peak;//=0;\n\n\n\n    int n1b2;// = n1b/2;\n    int rp;        // keep the location of the next samples to read in inbuf at fs1.\n    int rps;       // the reminder obtained by dividing rp by (fs1/sfrq=osf).\n    int rp2;       // keep the location of the next samples to read in buf2 at fs2.\n    int ds;        // the number of samples to dispose next in sfrq.\n    int nsmplwrt2; // actually number of samples to send stage2 filter .\n    int s2p;       // the reminder obtained by dividing the samples output from stage1 filter by n1y*osf.\n    int init,ending;\n    int osc;\n    REAL *bp; // the location of the next samples to read calculated with rp2\n    int rps_backup,s2p_backup;\n    int k,ch,p;\n    int inbuflen;//=0;\n    unsigned int sumread,sumwrite;\n    int delay;// = 0;\n    int delay2;\n    REAL *op;\n\npublic:\n  Downsampler(Resampler_base::CONFIG & c);\n\n  ~Downsampler();\n  /*\n  {\n\tavs_free(stage1);\n\tavs_free(fft_ip);\n\tavs_free(fft_w);\n\tavs_free(f2order);\n\tavs_free(f2inc);\n\tavs_free(stage2[0]);\n\tavs_free(stage2);\n\tfor(i=0;i<nch;i++) avs_free(buf1[i]);\n\tavs_free(buf1);\n\tfor(i=0;i<nch;i++) avs_free(buf2[i]);\n\tavs_free(buf2);\n\tavs_free(inbuf);\n\tavs_free(outbuf);\n\t//free(rawoutbuf);\n  }; // dtor\n  */\n  unsigned int Resample(REAL_inout * rawinbuf, unsigned int in_size, int ending);\n\n};\n\ntemplate<class REAL>\nDownsampler<REAL>::Downsampler(Resampler_base::CONFIG & c) : Resampler_i_base<REAL>(c)\n{\n  spcount = 0;\n  peak = 0;\n  fft_ip = 0;\n  fft_w = 0;\n\n\n\n  filter1len = FFTFIRLEN; /* stage 1 filter length */\n\n                          /* Make stage 1 filter */\n\n  {\n    double aa = AA; /* stop band attenuation(dB) */\n    double lpf, delta, d, df, alp, iza;\n    int ipsize, wsize;\n\n    frqgcd = gcd(sfrq, dfrq);\n\n    if (dfrq / frqgcd == 1) osf = 1;\n    else if (dfrq / frqgcd % 2 == 0) osf = 2;\n    else if (dfrq / frqgcd % 3 == 0) osf = 3;\n    else {\n      //      fprintf(stderr,\"Resampling from %dHz to %dHz is not supported.\\n\",sfrq,dfrq);\n      //      fprintf(stderr,\"%d/gcd(%d,%d)=%d must be divided by 2 or 3.\\n\",dfrq,sfrq,dfrq,dfrq/frqgcd);\n      //      exit(-1);\n      return;\n    }\n\n    fs1 = sfrq * osf;\n\n    delta = pow(10.0, -aa / 20);\n    if (aa <= 21) d = 0.9222; else d = (aa - 7.95) / 14.36;\n\n    n1 = filter1len;\n    for (i = 1;; i = i * 2)\n    {\n      n1 = filter1len * i;\n      if (n1 % 2 == 0) n1--;\n      df = (fs1*d) / (n1 - 1);\n      lpf = (dfrq - df) / 2;\n      if (df < DF) break;\n    }\n\n    alp = alpha(aa);\n\n    iza = dbesi0(alp);\n\n    for (n1b = 1; n1b<n1; n1b *= 2);\n    n1b *= 2;\n\n    stage1 = (REAL*)avs_malloc(sizeof(REAL)*n1b, 64);\n\n    for (i = 0; i<n1b; i++) stage1[i] = 0;\n\n    for (i = -(n1 / 2); i <= n1 / 2; i++) {\n      stage1[i + n1 / 2] = win(i, n1, alp, iza)*hn_lpf(i, lpf, fs1)*fs1 / sfrq / n1b * 2;\n    }\n\n    ipsize = 2 + sqrt((double)n1b);\n    fft_ip = (int*)avs_malloc(sizeof(int)*ipsize, 64);\n    fft_ip[0] = 0;\n    wsize = n1b / 2;\n    fft_w = (REAL*)avs_malloc(sizeof(REAL)*wsize, 64);\n\n    fft<REAL>::rdft(n1b, 1, stage1, fft_ip, fft_w);\n  }\n\n  /* Make stage 2 filter */\n\n  if (osf == 1) {\n    fs2 = sfrq / frqgcd * dfrq;\n    n2 = 1;\n    n2y = n2x = 1;\n    f2order = (int*)avs_malloc(sizeof(int)*n2y, 64);\n    f2order[0] = 0;\n    f2inc = (int*)avs_malloc(sizeof(int)*n2y, 64);\n    f2inc[0] = sfrq / dfrq;\n    stage2 = (REAL**)avs_malloc(sizeof(REAL *)*n2y, 64);\n    stage2[0] = (REAL*)avs_malloc(sizeof(REAL)*n2x*n2y, 64);\n    stage2[0][0] = 1;\n  }\n  else {\n    double aa = AA; /* stop band attenuation(dB) */\n    double lpf, delta, d, df, alp, iza;\n    double guard = 2;\n\n    fs2 = sfrq / frqgcd * dfrq;\n\n    df = (fs1 / 2 - sfrq / 2) * 2 / guard;\n    lpf = sfrq / 2 + (fs1 / 2 - sfrq / 2) / guard;\n\n    delta = pow(10.0, -aa / 20);\n    if (aa <= 21) d = 0.9222; else d = (aa - 7.95) / 14.36;\n\n    n2 = fs2 / df * d + 1;\n    if (n2 % 2 == 0) n2++;\n\n    alp = alpha(aa);\n    iza = dbesi0(alp);\n\n    n2y = fs2 / fs1; // The interval where the sample which isn't 0 in fs2 exists.\n    n2x = n2 / n2y + 1;\n\n    f2order = (int*)avs_malloc(sizeof(int)*n2y, 64);\n    for (i = 0; i<n2y; i++) {\n      f2order[i] = fs2 / fs1 - (i*(fs2 / dfrq)) % (fs2 / fs1);\n      if (f2order[i] == fs2 / fs1) f2order[i] = 0;\n    }\n\n    f2inc = (int*)avs_malloc(sizeof(int)*n2y, 64);\n    for (i = 0; i<n2y; i++) {\n      f2inc[i] = (fs2 / dfrq - f2order[i]) / (fs2 / fs1) + 1;\n      if (f2order[i + 1 == n2y ? 0 : i + 1] == 0) f2inc[i]--;\n    }\n\n    stage2 = (REAL**)avs_malloc(sizeof(REAL *)*n2y, 64);\n    stage2[0] = (REAL*)avs_malloc(sizeof(REAL)*n2x*n2y, 64);\n\n    for (i = 1; i<n2y; i++) {\n      stage2[i] = &(stage2[0][n2x*i]);\n      for (j = 0; j<n2x; j++) stage2[i][j] = 0;\n    }\n\n    for (i = -(n2 / 2); i <= n2 / 2; i++)\n    {\n      stage2[(i + n2 / 2) % n2y][(i + n2 / 2) / n2y] = win(i, n2, alp, iza)*hn_lpf(i, lpf, fs2)*fs2 / fs1;\n    }\n  }\n\n  /* Apply filters */\n\n  n1b2 = n1b / 2;\n  inbuflen = 0;\n  //    delay = 0;\n\n  //    |....B....|....C....|   buf1      n1b2+n1b2\n  //|.A.|....D....|             buf2  n2x+n1b2\n  //\n  // At first, take samples from inbuf and multiplied by osf, then write those into B.\n  // Clear C.\n  // Apply stage1-filter to B and C.\n  // Add B to D.\n  // Apply stage2-filter to A and D\n  // Move last part of D to A.\n  // Copy C to D.\n\n  buf1 = (REAL**)avs_malloc(sizeof(REAL *)*nch, 64);\n  for (i = 0; i<nch; i++)\n    buf1[i] = (REAL*)avs_malloc(n1b * sizeof(REAL), 64);\n\n  buf2 = (REAL**)avs_malloc(sizeof(REAL *)*nch, 64);\n  for (i = 0; i<nch; i++) {\n    buf2[i] = (REAL*)avs_malloc(sizeof(REAL)*(n2x + 1 + n1b2), 64);\n    for (j = 0; j<n2x + n1b2; j++) buf2[i][j] = 0;\n  }\n\n  //rawoutbuf = (unsigned char*)malloc(dbps*nch*((double)n1b2*sfrq/dfrq+1));\n  inbuf = (REAL*)avs_malloc(nch*(n1b2 / osf + osf + 1) * sizeof(REAL), 64);\n  outbuf = (REAL*)avs_malloc(sizeof(REAL)*nch*((double)n1b2*sfrq / dfrq + 1), 64);\n\n  op = outbuf;\n\n  s2p = 0;\n  rp = 0;\n  rps = 0;\n  ds = 0;\n  osc = 0;\n  rp2 = 0;\n\n  init = 1;\n  ending = 0;\n  delay = (double)n1 / 2 / ((double)fs1 / dfrq) + (double)n2 / 2 / ((double)fs2 / dfrq);\n  delay2 = delay * nch;\n\n  sumread = sumwrite = 0;\n\n\n\n}; // ctor\n\n\ntemplate<class REAL>\nDownsampler<REAL>::~Downsampler()\n{\n  avs_free(stage1);\n  avs_free(fft_ip);\n  avs_free(fft_w);\n  avs_free(f2order);\n  avs_free(f2inc);\n  avs_free(stage2[0]);\n  avs_free(stage2);\n  for (i = 0; i<nch; i++) avs_free(buf1[i]);\n  avs_free(buf1);\n  for (i = 0; i<nch; i++) avs_free(buf2[i]);\n  avs_free(buf2);\n  avs_free(inbuf);\n  avs_free(outbuf);\n  //free(rawoutbuf);\n}; // dtor\n\ntemplate<class REAL>\nunsigned int Downsampler<REAL>::Resample(REAL_inout * rawinbuf, unsigned int in_size, int ending) {\n  unsigned int rv;\n  int nsmplread;\n  int toberead;\n\n  toberead = (n1b2 - rps - 1) / osf + 1;\n\n  if (!ending)\n  {\n    rv = nch * toberead;\n    if (in_size<rv) return 0;\n    nsmplread = toberead;\n  }\n  else\n  {\n    nsmplread = in_size / nch;\n    rv = nsmplread * nch;\n  }\n\n  make_inbuf(nsmplread, inbuflen, rawinbuf, inbuf, toberead);\n\n  sumread += nsmplread;\n\n  rps_backup = rps;\n  s2p_backup = s2p;\n\n  for (ch = 0; ch<nch; ch++)\n  {\n    rps = rps_backup;\n\n    for (k = 0; k<rps; k++) buf1[ch][k] = 0;\n\n    for (i = rps, j = 0; i<n1b2; i += osf, j++)\n    {\n      assert(j < ((n1b2 - rps - 1) / osf + 1));\n\n      buf1[ch][i] = inbuf[j*nch + ch];\n\n      for (k = i + 1; k<i + osf; k++) buf1[ch][k] = 0;\n    }\n\n    assert(j == ((n1b2 - rps - 1) / osf + 1));\n\n    for (k = n1b2; k<n1b; k++) buf1[ch][k] = 0;\n\n    rps = i - n1b2;\n    rp += j;\n\n    fft<REAL>::rdft(n1b, 1, buf1[ch], fft_ip, fft_w);\n\n    buf1[ch][0] = stage1[0] * buf1[ch][0];\n    buf1[ch][1] = stage1[1] * buf1[ch][1];\n\n    for (i = 1; i<n1b2; i++)\n    {\n      REAL re, im;\n\n      re = stage1[i * 2] * buf1[ch][i * 2] - stage1[i * 2 + 1] * buf1[ch][i * 2 + 1];\n      im = stage1[i * 2 + 1] * buf1[ch][i * 2] + stage1[i * 2] * buf1[ch][i * 2 + 1];\n\n      buf1[ch][i * 2] = re;\n      buf1[ch][i * 2 + 1] = im;\n    }\n\n    fft<REAL>::rdft(n1b, -1, buf1[ch], fft_ip, fft_w);\n\n    for (i = 0; i<n1b2; i++) {\n      buf2[ch][n2x + 1 + i] += buf1[ch][i];\n    }\n\n    {\n      int t1 = rp2 / (fs2 / fs1);\n      if (rp2 % (fs2 / fs1) != 0) t1++;\n\n      bp = &(buf2[ch][t1]);\n    }\n\n    s2p = s2p_backup;\n\n    for (p = 0; bp - buf2[ch]<n1b2 + 1; p++)\n    {\n      REAL tmp = 0;\n      REAL *bp2;\n      int s2o;\n\n      bp2 = bp;\n      s2o = f2order[s2p];\n      bp += f2inc[s2p];\n      s2p++;\n\n      if (s2p == n2y) s2p = 0;\n\n      assert((bp2 - &(buf2[ch][0]))*(fs2 / fs1) - (rp2 + p * (fs2 / dfrq)) == s2o);\n\n      for (i = 0; i<n2x; i++)\n        tmp += stage2[s2o][i] * *bp2++;\n\n      op[p*nch + ch] = tmp;\n    }\n\n    nsmplwrt2 = p;\n  }\n\n  rp2 += nsmplwrt2 * (fs2 / dfrq);\n\n  make_outbuf(nsmplwrt2, outbuf, delay2);\n\n  if (!init) {\n    if (ending) {\n      if ((double)sumread*dfrq / this->sfrq + 2 > sumwrite + nsmplwrt2) {\n\n        sumwrite += nsmplwrt2;\n      }\n      else {\n\n        return rv;\n      }\n    }\n    else {\n\n      sumwrite += nsmplwrt2;\n    }\n  }\n  else {\n    if (nsmplwrt2 < delay) {\n      delay -= nsmplwrt2;\n    }\n    else {\n      if (ending) {\n        if ((double)sumread*this->dfrq / this->sfrq + 2 > sumwrite + nsmplwrt2 - delay) {\n\n          sumwrite += nsmplwrt2 - delay;\n        }\n        else {\n\n          return rv;\n        }\n      }\n      else {\n\n        sumwrite += nsmplwrt2 - delay;\n        init = 0;\n      }\n    }\n  }\n\n  {\n    int ds = (rp2 - 1) / (fs2 / fs1);\n\n    if (ds > n1b2) ds = n1b2;\n\n    for (ch = 0; ch<nch; ch++)\n      mem_ops<REAL>::move(buf2[ch], buf2[ch] + ds, n2x + 1 + n1b2 - ds);\n\n    rp2 -= ds * (fs2 / fs1);\n  }\n\n  for (ch = 0; ch<nch; ch++)\n    mem_ops<REAL>::copy(buf2[ch] + n2x + 1, buf1[ch] + n1b2, n1b2);\n\n  return rv;\n}\n\nResampler_base::Resampler_base(const Resampler_base::CONFIG & c)\n{\n\tif (c.fast)\n\t{\n\t\tAA = 96;\n\t\tDF = 8000;\n\t\tFFTFIRLEN = 1024;\n\t}\n\telse\n\t{\n\t\tAA=120;\n\t\tDF=100;\n\t\tFFTFIRLEN=16384;\n\t}\n/*\n#else\n\tAA=170;\n\tDF=100;\n\tFFTFIRLEN=65536;\n#endif\n\t*/\n\n\tnch=c.nch;\n\tsfrq=c.sfrq;\n\tdfrq=c.dfrq;\n\n\tdouble noiseamp = 0.18;\n\t//double att=0;\n\tgain=1;//pow(10.0,-att/20);\n\n}\n\nResampler_base * Resampler_base::Create(Resampler_base::CONFIG & c)\n{\n\tif (!CanResample(c.sfrq,c.dfrq)) return 0;\n\n/*\tif (c.math)\n\t{\n\t\tif (c.sfrq < c.dfrq) return new Upsampler<double>(c);\n\t\telse if (c.sfrq > c.dfrq) return new Downsampler<double>(c);\n\t\telse return 0;\n\t}\n\telse*/\n\t{\n\t\tif (c.sfrq < c.dfrq) return new Upsampler<float>(c);\n\t\telse if (c.sfrq > c.dfrq) return new Downsampler<float>(c);\n\t\telse return 0;\n\t}\n}\n\nResampler_base *SSRC_create(int sfrq, int dfrq, int nch, int dither, int pdf, int fast)\n{\n  Resampler_base::CONFIG c(sfrq, dfrq, nch, dither, pdf, fast);\n  return Resampler_base::Create(c);\n}\n\n"
  },
  {
    "path": "plugins/Shibatch/ssrc.h",
    "content": "/******************************************************\n  A fast and high quality sampling rate converter SSRC\n                                           written by Naoki Shibata\n\n\nHomepage : http://shibatch.sourceforge.net/\ne-mail   : shibatch@users.sourceforge.net\n\nSome changes are:\n\nCopyright (c) 2001-2003, Peter Pawlowski\nAll rights reserved.\n\nOther changes are:\n\nCopyright (c) 2003, Klaus Post\n\n*******************************************************/\n\n\n#include <avisynth.h>\n#include <avs/config.h>\n#include <cstring>\n#include \"mem_block.h\"\n\ntypedef SFLOAT audio_sample;\ntypedef audio_sample REAL_inout;\n\n#include \"fft.h\"\n\n#include <stdlib.h>\n#ifndef AVS_WINDOWS\n#define _aligned_malloc(size, alignment) aligned_alloc(alignment, size)\n#define _aligned_free(ptr) free(ptr)\n#endif\n\nclass Buffer\n{\nprivate:\n\tmem_block_t<REAL_inout> buffer;\n\tint buf_data;\npublic:\n\tAVS_FORCEINLINE Buffer() {buf_data=0;buffer.set_mem_logic(mem_block::ALLOC_FAST_DONTGODOWN);}\n\tAVS_FORCEINLINE REAL_inout * GetBuffer(int * siz) {*siz=buf_data;return buffer;}\n\tAVS_FORCEINLINE int Size() {return buf_data;}\n\tvoid Read(int size);\n\tvoid Write(const REAL_inout * ptr,int size);\n};\n\n\nclass Resampler_base\n{\npublic:\n\tclass CONFIG\n\t{\n\tpublic:\n\t\tint sfrq,dfrq,nch,dither,pdf,fast;\n\t\tAVS_FORCEINLINE CONFIG(int _sfrq,int _dfrq,int _nch,int _dither,int _pdf,int _fast=1)\n\t\t{\n\t\t\tsfrq=_sfrq;\n\t\t\tdfrq=_dfrq;\n\t\t\tnch=_nch;\n\t\t\tdither=_dither;\n\t\t\tpdf=_pdf;\n\t\t\tfast=_fast;\n\t\t}\n\t};\n\nprivate:\n\tBuffer in,out;\n\tvoid bufloop(int finish);\nprotected:\n\n\tResampler_base(const Resampler_base::CONFIG & c);\n\n\tvoid AVS_FORCEINLINE __output(REAL_inout value, int& delay2)\n\t{\n\t\tif(delay2 == 0) {\n\t\t\tout.Write(&value,1);\n\t\t} else {\n\t\t\tdelay2--;\n\t\t}\n\t};\n\n\tvirtual unsigned int Resample(REAL_inout * input,unsigned int size,int ending)=0;\n\n\tdouble peak;\n\tint nch,sfrq,dfrq;\n\tdouble gain;\n\n\n\tdouble AA,DF;\n\tint FFTFIRLEN;\n\npublic:\n\tdouble GetPeak() {return peak;}//havent tested if this actually still works\n\nvoid Write(const REAL_inout* input,int size);\n\tAVS_FORCEINLINE void Finish() {bufloop(1);}\n\n\tAVS_FORCEINLINE REAL_inout* GetBuffer(int * s) {return out.GetBuffer(s);}\n\tAVS_FORCEINLINE void Read(unsigned int s) {out.Read(s);}\n\n\tunsigned int GetLatency();//returns amount of audio data in in/out buffers in milliseconds\n\n\tAVS_FORCEINLINE unsigned int GetDataInInbuf() {return in.Size();}\n\n\tvirtual ~Resampler_base() {}\n\n\tstatic Resampler_base * Create(Resampler_base::CONFIG & c);\n};\n\n/*\n#define SSRC_create(sfrq,dfrq,nch,dither,pdf,fast) \\\n\tResampler_base::Create(Resampler_base::CONFIG(sfrq,dfrq,nch,dither,pdf,fast))\n\nmoved outside\n*/\nResampler_base *SSRC_create(int sfrq, int dfrq, int nch, int dither, int pdf, int fast);\n\n/*\nUSAGE:\nResampler_base::Create() / SSRC_create with your resampling params (see source for exact info what they do)\n\n loop:\nWrite() your PCM data to be resampled\nGetBuffer() to get pointer to buffer with resampled data and amount of resampled data available (in bytes)\n(note: SSRC operates on blocks, don't expect it to return any data right after your first Write() )\n\nRead() to tell the resampler how much data you took from the buffer ( <= size returned by GetBuffer )\n\nyou can use GetLatency() to get amount of audio data (in ms) currently being kept in resampler's buffers\n(quick hack for determining current output time without extra stupid counters)\n\nFinish() to force-convert remaining PCM data after last Write() (warning: never Write() again after Flush() )\n\ndelete when done\n\n*/\n"
  },
  {
    "path": "plugins/Shibatch/supereq.cpp",
    "content": "/******************************************************\nSuperEQ written by Naoki Shibata  shibatch@users.sourceforge.net\n\nShibatch Super Equalizer is a graphic and parametric equalizer plugin\nfor winamp. This plugin uses 16383th order FIR filter with FFT algorithm.\nIt's equalization is very precise. Equalization setting can be done\nfor each channel separately.\n\n\nHomepage : http://shibatch.sourceforge.net/\ne-mail   : shibatch@users.sourceforge.net\n\nSome changes are from foobar2000 (www.foobar2000.org):\n\nCopyright (c) 2001-2003, Peter Pawlowski\nAll rights reserved.\n\nOther changes are:\n\nCopyright (c) 2003, Klaus Post\n\n*******************************************************/\n\n#include <math.h>\n#include \"supereq.h\"\n#include \"paramlist.h\"\n#include <vector>\n#include <avs/minmax.h>\n#include <avisynth.h>\n\n\n\nenum {N_BANDS=18};\n\nstruct eq_config\n{\n\tint bands[N_BANDS];\n};\n\nstatic const eq_config def_bands = {20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20};\n\n\nstatic void setup_bands(const eq_config & src,double dst[N_BANDS])\n{\n\tint n;\n\tfor(n=0;n<N_BANDS;n++)\n\t{\n\t\tdst[n] = (double)pow(10.0,(src.bands[n]-20)/-20.0);\n\t}\n}\n\n\nclass AVSsupereq : public GenericVideoFilter\n{\nprivate:\n\tstd::vector<supereq_base*> eqs;\n\tparamlist paramroot;\n\teq_config my_eq;\n\n  int dstbuffer_size;\n  int dst_samples_filled;\n\n  SFLOAT* dstbuffer;\n  SFLOAT* passbuffer;\n  int64_t next_sample;\n  int64_t inputReadOffset;\n\npublic:\nAVSsupereq(PClip _child, const char* filename, IScriptEnvironment* env)\n: GenericVideoFilter(_child)\n{\n  const unsigned last_nch   = (unsigned)vi.AudioChannels();\n  const unsigned last_srate = (unsigned)vi.audio_samples_per_second;\n\n  FILE *settingsfile;\n  settingsfile = fopen(filename, \"r\");\n\n  if (settingsfile != NULL) {\n    int n;\n    for(n=0;n<N_BANDS;n++) {\n      int readval;\n      if (fscanf(settingsfile, \"%d\", &readval) == 1) {\n        my_eq.bands[n] = ((-readval)+20);\n      }\n    }\n    fclose(settingsfile);\n  } else {\n    env->ThrowError(\"SuperEQ: Could not open file\");\n  }\n\n  unsigned n;\n  for(n=0;n<last_nch;n++)\n    eqs.push_back(new supereq<float>);\n  double bands[N_BANDS];\n  //    my_eq = cfg_eq;\n  setup_bands(my_eq,bands);\n  for(n=0;n<last_nch;n++)\n    eqs[n]->equ_makeTable(bands,&paramroot,(double)last_srate);\n\n  dstbuffer = new SFLOAT[last_srate * last_nch];  // Our buffer can minimum contain one second.\n  passbuffer = new SFLOAT[last_srate];  // Our buffer can minimum contain one second.\n  dstbuffer_size = last_srate;\n\n  next_sample = 0;  // Next output sample\n  inputReadOffset = 0;  // Next input sample\n  dst_samples_filled = 0;\n}\n\nAVSsupereq(PClip _child, int* values, IScriptEnvironment* env)\n: GenericVideoFilter(_child)\n{\n  const unsigned last_nch   = (unsigned)vi.AudioChannels();\n  const unsigned last_srate = (unsigned)vi.audio_samples_per_second;\n\n  unsigned n;\n  for(n=0; n<N_BANDS; n++) {\n      my_eq.bands[n] = (-values[n]+20);\n  }\n\n  for(n=0; n<last_nch; n++)\n    eqs.push_back(new supereq<float>);\n\n  double bands[N_BANDS];\n  //    my_eq = cfg_eq;\n  setup_bands(my_eq, bands);\n\n  for(n=0; n<last_nch; n++)\n    eqs[n]->equ_makeTable(bands, &paramroot, (double)last_srate);\n\n  dstbuffer = new SFLOAT[last_srate * last_nch];  // Our buffer can minimum contain one second.\n  passbuffer = new SFLOAT[last_srate];  // Our buffer can minimum contain one second.\n  dstbuffer_size = last_srate;\n\n  next_sample = 0;  // Next output sample\n  inputReadOffset = 0;  // Next input sample\n  dst_samples_filled = 0;\n}\nprivate:\n\nvoid __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env)\n{\n  const unsigned last_nch   = (unsigned)vi.AudioChannels();\n  const unsigned last_srate = (unsigned)vi.audio_samples_per_second;\n\n  if (start != next_sample) {  // Reset on seek\n    inputReadOffset = start;  // Reset at new read position.\n    dst_samples_filled=0;\n\n    for (size_t i = 0; i < eqs.size(); ++i)\n      delete eqs[i];\n    eqs.clear();\n\n    unsigned n;\n    for(n=0;n<last_nch;n++)\n      eqs.push_back(new supereq<float>);\n    double bands[N_BANDS];\n    setup_bands(my_eq,bands);\n    for(n=0;n<last_nch;n++)\n      eqs[n]->equ_makeTable(bands,&paramroot,(double)last_srate);\n  }\n\n  bool buffer_full = false;\n  int samples_filled = 0;\n\n  do {\n    // Empty buffer if something is still left.\n    if (dst_samples_filled) {\n      int copysamples = min((int)count-samples_filled, dst_samples_filled);\n      // Copy finished samples\n      int pitch = copysamples*last_nch*sizeof(SFLOAT);\n      env->BitBlt((BYTE*)buf+samples_filled*last_nch*sizeof(SFLOAT), pitch,\n        (BYTE*)dstbuffer, pitch,\n        pitch, 1\n      );\n      dst_samples_filled -= copysamples;\n\n      if (dst_samples_filled) { // Move non-used samples\n        memcpy(dstbuffer, &dstbuffer[copysamples*last_nch], dst_samples_filled*sizeof(SFLOAT)*last_nch);\n      }\n      samples_filled += copysamples;\n      if (samples_filled >= count)\n        buffer_full = true;\n    }\n    // If buffer empty - refill\n    if (dst_samples_filled<=0) {\n      // Feed new samples to filter\n      child->GetAudio(dstbuffer, inputReadOffset, last_srate, env);\n      inputReadOffset += last_srate;\n\n      {for (unsigned n=0; n<last_nch; n++) { // Copies n channels to separate buffers to individual filters\n        SFLOAT *db = dstbuffer + n;\n        for (unsigned s=0, r=0; s<last_srate; s++, r+=last_nch)\n          passbuffer[s] = db[r];\n\n        eqs[n]->write_samples(passbuffer, last_srate);\n      }}\n\n      // Read back samples from filter\n      int samples_out = 0;\n      {for (unsigned n=0; n<last_nch; n++) { // Copies back samples from individual filters\n        SFLOAT *data_out = eqs[n]->get_output(&samples_out);\n        // Check temp buffer size\n        if (dstbuffer_size < samples_out) {\n          if (n) { // Extremely unlikely but if it happens we need to transcribe the old buf.\n            SFLOAT *db = new SFLOAT[samples_out*last_nch];\n            if (dstbuffer_size) {\n              memcpy(db, dstbuffer, dstbuffer_size*sizeof(SFLOAT)*last_nch);\n              delete[] dstbuffer;\n\t\t\t}\n            dstbuffer = db;\n            dstbuffer_size = samples_out;\n          }\n          else {\n            if (dstbuffer_size)\n              delete[] dstbuffer;\n            dstbuffer = new SFLOAT[samples_out*last_nch];\n            dstbuffer_size = samples_out;\n          }\n        }\n        SFLOAT *db = dstbuffer + n;\n        for (int s=0, r=0; s<samples_out; s++, r+=last_nch)\n          db[r] = data_out[s];\n      }}\n      dst_samples_filled = samples_out;\n    }\n  } while (!buffer_full);\n  next_sample += count;\n}\n\t~AVSsupereq()\n\t{\n    delete[] dstbuffer;\n    delete[] passbuffer;\n    for (size_t i = 0; i < eqs.size(); ++i)\n      delete eqs[i];\n\t}\n\n\n};\n\nAVSValue __cdecl Create_SuperEq(AVSValue args, void*, IScriptEnvironment* env) {\n\n  PClip clip = args[0].AsClip();\n\n  if (!clip->GetVideoInfo().HasAudio())\n    env->ThrowError(\"Input clip does not have audio.\");\n\n  if (!(clip->GetVideoInfo().SampleType()&SAMPLE_FLOAT))\n    env->ThrowError(\"Input audio sample format to SuperEQ must be float.\");\n\n  return new AVSsupereq(args[0].AsClip(), args[1].AsString(), env);\n}\n\nAVSValue __cdecl Create_SuperEqCustom(AVSValue args, void*, IScriptEnvironment* env) {\n\n  PClip clip = args[0].AsClip();\n\n  if (!clip->GetVideoInfo().HasAudio())\n    env->ThrowError(\"Input clip does not have audio.\");\n\n  if (!(clip->GetVideoInfo().SampleType()&SAMPLE_FLOAT))\n    env->ThrowError(\"Input audio sample format to SuperEQ must be float.\");\n\n  int eq[N_BANDS];\n  AVSValue args_c = args[1];\n  const int num_args = args_c.ArraySize();\n  for (int i = 0; i<N_BANDS; i++) {\n    eq[i] = i<num_args ? args_c[i].AsInt() : 0;\n  }\n  return new AVSsupereq(args[0].AsClip(), eq, env);\n}\n"
  },
  {
    "path": "plugins/Shibatch/supereq.h",
    "content": "/******************************************************\nSuperEQ written by Naoki Shibata  shibatch@users.sourceforge.net\n\nShibatch Super Equalizer is a graphic and parametric equalizer plugin\nfor winamp. This plugin uses 16383th order FIR filter with FFT algorithm.\nIt's equalization is very precise. Equalization setting can be done\nfor each channel separately.\n\n\nHomepage : http://shibatch.sourceforge.net/\ne-mail   : shibatch@users.sourceforge.net\n\nSome changes are from foobar2000 (www.foobar2000.org):\n\nCopyright (c) 2001-2003, Peter Pawlowski\nAll rights reserved.\n\nOther changes are:\n\nCopyright (c) 2003, Klaus Post\n\n*******************************************************/\n\n#ifndef _SUPEREQ_H_\n#define _SUPEREQ_H_\n\n#include <avisynth.h>\n#include <stdlib.h>\n#include <cstring>\n#include \"mem_block.h\"\n\n#include \"paramlist.h\"\n\ntypedef SFLOAT audio_sample;\ntypedef audio_sample REAL_inout;\n\n#include \"fft.h\"\n\nAVSValue __cdecl Create_SuperEq(AVSValue args, void*, IScriptEnvironment* env);\nAVSValue __cdecl Create_SuperEqCustom(AVSValue args, void*, IScriptEnvironment* env);\n\n#ifdef _MSC_VER\n//#define NOVTABLE _declspec(novtable)\n#define NOVTABLE\n#else\n#define NOVTABLE\n#endif\n\nclass NOVTABLE supereq_base\n{\npublic:\n\tvirtual void equ_makeTable(double *bc,class paramlist *param,double fs) = 0;\n\tvirtual void equ_clearbuf() = 0;\n\n\tvirtual void write_samples(audio_sample*buf,int nsamples) = 0;\n\tvirtual audio_sample * get_output(int *nsamples) = 0;\n\tvirtual int samples_buffered() = 0;\n\tvirtual ~supereq_base() {};\n};\n\ntemplate<class REAL>\nclass supereq : public supereq_base\n{\npublic:\n\tenum {NBANDS = 17};\nprivate:\n\n\tenum\n\t{\n\t\tM=15\n\t};\n\n\tint rfft_ipsize,rfft_wsize;\n\tint *rfft_ip;\n\tREAL *rfft_w;\n\n\n\tREAL fact[M+1];\n\tREAL aa;\n\tREAL iza;\n\tREAL *lires,*lires1,*lires2,*irest;\n\tREAL *fsamples;\n\tREAL *ditherbuf;\n\tvolatile int chg_ires,cur_ires;\n\tint winlen,winlenbit,tabsize,nbufsamples;\n\tint firstframe;\n\n\tmem_block_t<REAL> inbuf,outbuf;\n\tmem_block_t<audio_sample> done;\n\tint samples_done;\n\n\tvoid rfft(int n,int isign,REAL x[])\n\t{\n\t\tint newipsize,newwsize;\n\n\t\tif (n == 0) {\n\t\t\tfree(rfft_ip); rfft_ip = NULL; rfft_ipsize = 0;\n\t\t\tfree(rfft_w);  rfft_w  = NULL; rfft_wsize  = 0;\n\t\t\treturn;\n\t\t}\n\n\t\tnewipsize = 2+sqrt((float)(n/2));\n\t\tif (newipsize > rfft_ipsize) {\n\t\t\trfft_ipsize = newipsize;\n\t\t\trfft_ip = mem_ops<int>::realloc_block(rfft_ip,rfft_ipsize);\n\t\t\trfft_ip[0] = 0;\n\t\t}\n\n\t\tnewwsize = n/2;\n\t\tif (newwsize > rfft_wsize) {\n\t\t\trfft_wsize = newwsize;\n\t\t\trfft_w = mem_ops<REAL>::realloc_block(rfft_w,rfft_wsize);\n\t\t}\n\n\t\tfft<REAL>::rdft(n,isign,x,rfft_ip,rfft_w);\n\t}\n\n\tREAL izero(REAL x)\n\t{\n\t\tREAL ret = 1;\n\t\tint m;\n\n\t\tfor(m=1;m<=M;m++)\n\t\t{\n\t\t\tREAL t;\n\t\t\tt = pow(x/2,m)/fact[m];\n\t\t\tret += t*t;\n\t\t}\n\n\t\treturn ret;\n\t}\n\n\tREAL win(REAL n,int N) {return izero(alpha(aa)*sqrt(1-4*n*n/((N-1)*(N-1))))/iza;}\n\n\tvoid equ_init(int wb)\n\t{\n\t\t  int i,j;\n\n\t\t  if (lires1 != NULL)   free(lires1);\n\t\t  if (lires2 != NULL)   free(lires2);\n\t\t  if (irest != NULL)    free(irest);\n\t\t  if (fsamples != NULL) free(fsamples);\n\n\t\t  winlen = (1 << (wb-1))-1;\n\t\t  winlenbit = wb;\n\t\t  tabsize  = 1 << wb;\n\n\t\t  lires1   = mem_ops<REAL>::alloc_zeromem(tabsize);\n\t\t  lires2   = mem_ops<REAL>::alloc_zeromem(tabsize);\n\t\t  irest    = mem_ops<REAL>::alloc_zeromem(tabsize);\n\t\t  fsamples = mem_ops<REAL>::alloc_zeromem(tabsize);\n\t\t  inbuf.set_size(winlen);\n\t\t  inbuf.zeromemory();\n\t\t  outbuf.set_size(tabsize);\n\t\t  outbuf.zeromemory();\n\n\t\t  lires = lires1;\n\t\t  cur_ires = 1;\n\t\t  chg_ires = 1;\n\n\t\t  for(i=0;i<=M;i++)\n\t\t\t{\n\t\t\t  fact[i] = 1;\n\t\t\t  for(j=1;j<=i;j++) fact[i] *= j;\n\t\t\t}\n\n\t\t  iza = izero(alpha(aa));\n\n\t}\n\n\tstatic REAL alpha(REAL a)\n\t{\n\t\tif (a <= 21) return 0;\n\t\tif (a <= 50) return 0.5842*pow((a-21.),0.4)+0.07886*(a-21);\n\t\treturn 0.1102*(a-8.7);\n\t}\n\n\tstatic REAL sinc(REAL x) {return x == 0 ? 1 : sin(x)/x;}\n\n\tstatic REAL hn_lpf(int n,REAL f,REAL fs)\n\t{\n\t\tREAL t = 1/fs;\n\t\tREAL omega = 2*PI*f;\n\t\treturn 2*f*t*sinc(n*omega*t);\n\t}\n\n\tstatic REAL hn_imp(int n) {return n == 0 ? 1.0 : 0.0;}\n\n\tstatic REAL hn(int n,class paramlist &param2,REAL fs)\n\t{\n\t\tparamlistelm *e;\n\t\tREAL ret,lhn;\n\n\t\tlhn = hn_lpf(n,param2.elm->upper,fs);\n\t\tret = param2.elm->gain*lhn;\n\n\t\tfor(e=param2.elm->next;e->next != NULL && e->upper < fs/2;e = e->next)\n\t\t{\n\t\t\tREAL lhn2 = hn_lpf(n,e->upper,fs);\n\t\t\tret += e->gain*(lhn2-lhn);\n\t\t\tlhn = lhn2;\n\t\t}\n\n\t\tret += e->gain*(hn_imp(n)-lhn);\n\n\t\treturn ret;\n\n\t}\n\n\n\tstatic void process_param(double *bc,paramlist *param,paramlist &param2,double fs,int ch)\n\t{\nstatic const double bands[NBANDS] = { // Half octave spacing, i.e. *=sqrt(2.0)\n  65.406392, 92.498606, 130.81278, 184.99721, 261.62557, 369.99442, 523.25113,\n  739.98884, 1046.5023, 1479.9768, 2093.0045, 2959.9536, 4186.0091, 5919.9072,\n  8372.0181, 11839.814, 16744.036\n};\n\n\t\t  paramlistelm **pp,*p,*e,*e2;\n\t\t  int i;\n\n\t\t  delete param2.elm;\n\t\t  param2.elm = NULL;\n\n\t\t  for(i=0,pp=&param2.elm;i<=NBANDS;i++,pp = &(*pp)->next)\n\t\t  {\n\t\t\t(*pp) = new paramlistelm;\n\t\t\t(*pp)->lower = i == 0        ?  0 : bands[i-1];\n\t\t\t(*pp)->upper = i == NBANDS ? fs : bands[i  ];\n\t\t\t(*pp)->gain  = bc[i];\n\t\t  }\n\n\t\t  for(e = param->elm;e != NULL;e = e->next)\n\t\t  {\n\t\t\tif ((ch == 0 && !e->left) || (ch == 1 && !e->right)) continue;\n\t\t\tif (e->lower >= e->upper) continue;\n\n\t\t\tfor(p=param2.elm;p != NULL;p = p->next)\n\t\t\t\tif (p->upper > e->lower) break;\n\n\t\t\twhile(p != NULL && p->lower < e->upper)\n\t\t\t{\n\t\t\t\tif (e->lower <= p->lower && p->upper <= e->upper) {\n\t\t\t\t\tp->gain *= pow(10.0,e->gain/20.0);\n\t\t\t\t\tp = p->next;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (p->lower < e->lower && e->upper < p->upper) {\n\t\t\t\t\te2 = new paramlistelm;\n\t\t\t\t\te2->lower = e->upper;\n\t\t\t\t\te2->upper = p->upper;\n\t\t\t\t\te2->gain  = p->gain;\n\t\t\t\t\te2->next  = p->next;\n\t\t\t\t\tp->next   = e2;\n\n\t\t\t\t\te2 = new paramlistelm;\n\t\t\t\t\te2->lower = e->lower;\n\t\t\t\t\te2->upper = e->upper;\n\t\t\t\t\te2->gain  = p->gain * pow(10.,e->gain/20.0);\n\t\t\t\t\te2->next  = p->next;\n\t\t\t\t\tp->next   = e2;\n\n\t\t\t\t\tp->upper  = e->lower;\n\n\t\t\t\t\tp = p->next->next->next;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (p->lower < e->lower) {\n\t\t\t\t\te2 = new paramlistelm;\n\t\t\t\t\te2->lower = e->lower;\n\t\t\t\t\te2->upper = p->upper;\n\t\t\t\t\te2->gain  = p->gain * pow(10.0,e->gain/20.0);\n\t\t\t\t\te2->next  = p->next;\n\t\t\t\t\tp->next   = e2;\n\n\t\t\t\t\tp->upper  = e->lower;\n\t\t\t\t\tp = p->next->next;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (e->upper < p->upper) {\n\t\t\t\t\te2 = new paramlistelm;\n\t\t\t\t\te2->lower = e->upper;\n\t\t\t\t\te2->upper = p->upper;\n\t\t\t\t\te2->gain  = p->gain;\n\t\t\t\t\te2->next  = p->next;\n\t\t\t\t\tp->next   = e2;\n\n\t\t\t\t\tp->upper  = e->upper;\n\t\t\t\t\tp->gain   = p->gain * pow(10.0,e->gain/20.0);\n\t\t\t\t\tp = p->next->next;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tabort();\n\t\t\t}\n\t\t  }\n\n\t}\npublic:\n\tsupereq(int wb=14)\n\t{\n\t\tfirstframe=1;\n\t\trfft_ipsize = 0;\n\t\trfft_wsize=0;\n\t\trfft_ip = NULL;\n\t\trfft_w = NULL;\n\n\t\taa = 96;\n\t\tmemset(fact,0,sizeof(fact));\n\t\tiza=0;\n\t\tlires=0;\n\t\tlires1=0;\n\t\tlires2=0;\n\t\tirest=0;\n\t\tfsamples=0;\n\t\tditherbuf=0;\n\t\tchg_ires=0;\n\t\tcur_ires=0;\n\t\twinlen=0;\n\t\twinlenbit=0;\n\t\ttabsize=0;\n\t\tnbufsamples=0;\n\t\tsamples_done=0;\n\t\tequ_init(wb);\n\t}\n\n  void equ_makeTable(double *bc,paramlist *param,double fs) override\n\t{\n\t\tint i,cires = cur_ires;\n\t\tREAL *nires;\n\n\t\tif (fs <= 0) return;\n\n\t\tparamlist param2;\n\n\t\t// L\n\n\t\tprocess_param(bc,param,param2,fs,0);\n\n\t\tfor(i=0;i<winlen;i++)\n\t\t\tirest[i] = hn(i-winlen/2,param2,fs)*win(i-winlen/2,winlen);\n\n\t\tfor(;i<tabsize;i++)\n\t\t\tirest[i] = 0;\n\n\t\trfft(tabsize,1,irest);\n\n\t\tnires = cires == 1 ? lires2 : lires1;\n\n\t\tfor(i=0;i<tabsize;i++)\n\t\t\tnires[i] = irest[i];\n\n\n\t\tchg_ires = cires == 1 ? 2 : 1;\n\n\t}\n\n\tvoid equ_clearbuf() override\n\t{\n\t\tfirstframe = 1;\n\t\tsamples_done = 0;\n\t\tnbufsamples = 0;\n\t}\n\n\tvoid write_samples(audio_sample*buf,int nsamples) override\n\t{\n\t\tint i,p;\n\t\tREAL *ires;\n\n\t\tif (chg_ires) {\n\t\t\tcur_ires = chg_ires;\n\t\t\tlires = cur_ires == 1 ? lires1 : lires2;\n\t\t\tchg_ires = 0;\n\t\t}\n\n\t\tp = 0;\n\n\t\tint flush_length = 0;\n\n\t\tif (!buf)//flush\n\t\t{\n\t\t\tif (nbufsamples==0) return;\n\t\t\tflush_length = nbufsamples;\n\t\t\tnsamples = winlen - nbufsamples;\n\t\t}\n\n\t\twhile(nbufsamples+nsamples >= winlen)\n\t\t{\n\t\t\tif (buf)\n\t\t\t{\n\t\t\t\tfor(i=0;i<winlen-nbufsamples;i++)\n\t\t\t\t\tinbuf[nbufsamples+i] = (REAL)buf[i+p];\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfor(i=0;i<winlen-nbufsamples;i++)\n\t\t\t\t\tinbuf[nbufsamples+i]=0;\n\t\t\t}\n\n\t\t\tfor(i=winlen;i<tabsize;i++)\n\t\t\t\toutbuf[i-winlen] = outbuf[i];\n\n\n\t\t\tp += winlen-nbufsamples;\n\t\t\tnsamples -= winlen-nbufsamples;\n\t\t\tnbufsamples = 0;\n\n\t\t\tires = lires;\n\t\t\tfor(i=0;i<winlen;i++)\n\t\t\t\tfsamples[i] = inbuf[i];\n\n\t\t\tfor(i=winlen;i<tabsize;i++)\n\t\t\t\tfsamples[i] = 0;\n\n\t\t\trfft(tabsize,1,fsamples);\n\n\t\t\tfsamples[0] = ires[0]*fsamples[0];\n\t\t\tfsamples[1] = ires[1]*fsamples[1];\n\n\t\t\tfor(i=1;i<tabsize/2;i++)\n\t\t\t{\n\t\t\t\tREAL re,im;\n\t\t\t\tre = ires[i*2  ]*fsamples[i*2] - ires[i*2+1]*fsamples[i*2+1];\n\t\t\t\tim = ires[i*2+1]*fsamples[i*2] + ires[i*2  ]*fsamples[i*2+1];\n\n\t\t\t\tfsamples[i*2  ] = re;\n\t\t\t\tfsamples[i*2+1] = im;\n\t\t\t}\n\t\t\trfft(tabsize,-1,fsamples);\n\n\t\t\tfor(i=0;i<winlen;i++) outbuf[i] += fsamples[i]/tabsize*2;\n\n\t\t\tfor(i=winlen;i<tabsize;i++) outbuf[i] = fsamples[i]/tabsize*2;\n\n\t\t\tint out_length = flush_length>0 ? flush_length+winlen/2 : winlen;\n\n\t\t\tdone.check_size(samples_done + out_length);\n\n\t\t\tfor(i=firstframe ? winlen/2 : 0;i<out_length;i++)\n\t\t\t{\n\t\t\t\tdone[samples_done++]=outbuf[i];\n\t\t\t}\n\t\t\tfirstframe=0;\n\t\t}\n\n\t\tif (buf)\n\t\t{\n\t\t\tfor(i=0;i<nsamples;i++)\n\t\t\t{\n\t\t\t\tinbuf[nbufsamples+i] = (REAL)buf[i+p];\n\t\t\t}\n\t\t\tp += nsamples;\n\t\t}\n\t\tnbufsamples += nsamples;\n\t}\n\n  audio_sample* get_output(int* nsamples) override\n\t{\n\t\t*nsamples = samples_done;\n\t\tsamples_done = 0;\n\t\treturn done.get_ptr();\n\t}\n\n\tint samples_buffered() override {return nbufsamples;}\n\n\t~supereq()\n\t{\n\t\tif (lires1) free(lires1);\n\t\tif (lires2) free(lires2);\n\t\tif (irest) free(irest);\n\t\tif (fsamples) free(fsamples);\n\t\trfft(0,0,NULL);\n\t}\n};\n\n#endif\n"
  },
  {
    "path": "plugins/Shibatch/whence.txt",
    "content": "This plugin uses code (SSRC, SuperEQ) from Naoki Shibata.\nhttp://shibatch.sourceforge.net/"
  },
  {
    "path": "plugins/TimeStretch/CMakeLists.txt",
    "content": "CMAKE_MINIMUM_REQUIRED( VERSION 3.6.2...3.11 )\n\nset(PluginName \"TimeStretch\")\nset(ProjectName \"Plugin${PluginName}\")\n\nif (NOT WIN32)\n  string(TOLOWER \"${PluginName}\" PluginName)\nendif()\n\n# Create library\nproject(${ProjectName} VERSION ${PROJECT_VERSION} LANGUAGES CXX)\nlist (APPEND SourceFiles\n    \"TimeStretch.cpp\"\n)\nadd_library(${ProjectName} SHARED ${SourceFiles})\nset_property(GLOBAL APPEND PROPERTY BUILT_TARGETS ${ProjectName})\nset_target_properties(${ProjectName} PROPERTIES \"OUTPUT_NAME\" ${PluginName})\nif (MINGW)\n  set_target_properties(${ProjectName} PROPERTIES PREFIX \"\")\n  set_target_properties(${ProjectName} PROPERTIES IMPORT_PREFIX \"\")\nendif()\n\n# Library dependencies\ntarget_link_libraries(${ProjectName} ${SOUNDTOUCH_LINK_LIBRARIES})\n\n# Include directories\ntarget_include_directories(${ProjectName} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${AvsCore_SOURCE_DIR} ${SOUNDTOUCH_INCLUDE_DIRS})\n\nif (MSVC_IDE)\n  # Copy output to a common folder for easy deployment\n  add_custom_command(\n    TARGET ${ProjectName}\n    POST_BUILD\n    COMMAND xcopy /Y \\\"$(TargetPath)\\\" \\\"${CMAKE_BINARY_DIR}/Output/plugins\\\"\n  )\nendif()\n\nINSTALL(TARGETS \"${ProjectName}\"\n        DESTINATION \"${CORE_PLUGIN_INSTALL_PATH}/avisynth\")\n"
  },
  {
    "path": "plugins/TimeStretch/TimeStretch.cpp",
    "content": "// Avisynth v2.5.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n// AviSynth -> SoundTouch interface (c) 2004, Klaus Post.\n\n\n\n#include <vector>\n#include <avisynth.h>\n#include <avs/minmax.h>\n#include <SoundTouch.h>\n\n\n#define BUFFERSIZE 8192\n\nusing namespace soundtouch;\n\n\nclass AVSsoundtouch : public GenericVideoFilter\n{\nprivate:\n  SoundTouch* sampler;\n\n  int dst_samples_filled;\n\n  SFLOAT* dstbuffer;\n  int64_t next_sample;\n  int64_t inputReadOffset;\n  long double sample_multiplier; // 64bit mantissa!\n\npublic:\nstatic AVSValue __cdecl Create(AVSValue args, void*, IScriptEnvironment* env);\nstatic AVSValue __cdecl CreateRational(AVSValue args, void*, IScriptEnvironment* env);\n\n\nAVSsoundtouch(PClip _child, double _tempo, double _rate, double _pitch, const AVSValue* args, IScriptEnvironment* env)\n: GenericVideoFilter(_child)\n{\n  dstbuffer = new SFLOAT[BUFFERSIZE * vi.AudioChannels()];\n\n  sample_multiplier  = (long double)_tempo * (long double)_rate;\n\n  sampler = new SoundTouch();\n\n  sampler->setRate(_rate);\n  sampler->setTempo(_tempo);\n  sampler->setPitch(_pitch);\n  sampler->setChannels(vi.AudioChannels());\n  sampler->setSampleRate(vi.audio_samples_per_second);\n  setSettings(sampler, args, env);\n\n  vi.num_audio_samples = (int64_t)(vi.num_audio_samples / sample_multiplier);\n\n  next_sample = 0;  // Next output sample\n  inputReadOffset = 0;  // Next input sample\n  dst_samples_filled = 0;\n\n}\n\nstatic void setSettings(SoundTouch* sampler, const AVSValue* args, IScriptEnvironment* env)\n{\n\n  if (args[0].Defined()) sampler->setSetting(SETTING_SEQUENCE_MS,   args[0].AsInt());\n  if (args[1].Defined()) sampler->setSetting(SETTING_SEEKWINDOW_MS, args[1].AsInt());\n  if (args[2].Defined()) sampler->setSetting(SETTING_OVERLAP_MS,    args[2].AsInt());\n\n  if (args[3].Defined()) sampler->setSetting(SETTING_USE_QUICKSEEK, args[3].AsBool() ? 1 : 0);\n\n  if (args[4].Defined()) {\n    int i = args[4].AsInt();\n    if (i<0 || i%4 != 0)\n      env->ThrowError(\"TimeStretch: AntiAliaser filter length must divisible by 4.\");\n\n    if (i)\n      sampler->setSetting(SETTING_AA_FILTER_LENGTH, i);\n    else\n      sampler->setSetting(SETTING_USE_AA_FILTER,    0);\n  }\n\n}\n\nvoid __stdcall GetAudio(void* buf, int64_t start, int64_t count, IScriptEnvironment* env)\n{\n\n  if (start != next_sample) {  // Reset on seek\n    sampler->clear();\n    next_sample = start;\n    inputReadOffset = (int64_t)(sample_multiplier * start);  // Reset at new read position (NOT sample exact :( ).\n    dst_samples_filled=0;\n  }\n\n  bool buffer_full = false;\n  int samples_filled = 0;\n\n  do {\n    // Empty buffer if something is still left.\n    if (dst_samples_filled) {\n      int copysamples = min((int)count-samples_filled, dst_samples_filled);\n      // Copy finished samples\n      if (copysamples) {\n        memcpy((BYTE*)buf+vi.BytesFromAudioSamples(samples_filled), (BYTE*)dstbuffer, (size_t)vi.BytesFromAudioSamples(copysamples));\n        samples_filled += copysamples;\n\n        dst_samples_filled -= copysamples;\n        // Move non-used samples\n        memcpy(dstbuffer, &dstbuffer[copysamples*vi.AudioChannels()], (size_t)vi.BytesFromAudioSamples(dst_samples_filled));\n      }\n      if (samples_filled >= count)\n        buffer_full = true;\n    }\n\n    // If buffer empty - refill\n    if (dst_samples_filled==0) {\n      // Read back samples from filter\n      int samples_out = 0;\n      int gotsamples = 0;\n      do {\n        gotsamples = sampler->receiveSamples(&dstbuffer[vi.BytesFromAudioSamples(samples_out)], BUFFERSIZE - samples_out);\n        samples_out += gotsamples;\n      } while (gotsamples > 0);\n\n      dst_samples_filled = samples_out;\n\n      if (!dst_samples_filled) {  // We didn't get any samples\n          // Feed new samples to filter\n        child->GetAudio(dstbuffer, inputReadOffset, BUFFERSIZE, env);\n        inputReadOffset += BUFFERSIZE;\n        sampler->putSamples(dstbuffer, BUFFERSIZE);\n      } // End if no samples\n    } // end if empty buffer\n  } while (!buffer_full);\n  next_sample += count;\n}\n\n~AVSsoundtouch()\n{\n    delete[] dstbuffer;\n    delete sampler;\n}\n\n\n};\n\n// Percentage float arguments.\nAVSValue __cdecl Create_SoundTouch(AVSValue args, void*, IScriptEnvironment* env)\n{\n    try { // HIDE DAMN SEH COMPILER BUG!!!\n    // 2021?? Probably for VS2005 or so\n\n        PClip clip = args[0].AsClip();\n\n        if (!clip->GetVideoInfo().HasAudio())\n            env->ThrowError(\"Input clip does not have audio.\");\n\n        if (!(clip->GetVideoInfo().SampleType()&SAMPLE_FLOAT))\n            env->ThrowError(\"Input audio sample format to TimeStretch must be float.\");\n\n        return new AVSsoundtouch(\n            args[0].AsClip(),\n            args[1].AsFloat(100.0) / 100.0,\n            args[2].AsFloat(100.0) / 100.0,\n            args[3].AsFloat(100.0) / 100.0,\n            &args[4],\n            env\n        );\n\n  }\n  catch (const std::runtime_error &error)\n  {\n    env->ThrowError(\"TimeStretch: %s \",error.what());\n  }\n  catch (...) { throw; }\n  return AVSValue(); // n/a\n}\n\n// Rational pair arguments\nAVSValue __cdecl CreateRational_SoundTouch(AVSValue args, void*, IScriptEnvironment* env)\n{\n    try { // HIDE DAMN SEH COMPILER BUG!!!\n    // 2021?? Probably for VS2005 or so\n\n        PClip clip = args[0].AsClip();\n\n        if (!clip->GetVideoInfo().HasAudio())\n            env->ThrowError(\"Input clip does not have audio.\");\n\n        if (!(clip->GetVideoInfo().SampleType()&SAMPLE_FLOAT))\n            env->ThrowError(\"Input audio sample format to TimeStretch must be float.\");\n\n        return new AVSsoundtouch(\n            args[0].AsClip(),\n            (double)args[1].AsInt(1) / args[2].AsInt(1),\n            (double)args[3].AsInt(1) / args[4].AsInt(1),\n            (double)args[5].AsInt(1) / args[6].AsInt(1),\n            &args[7],\n            env\n        );\n\n  }\n  catch (const std::runtime_error &error)\n  {\n    env->ThrowError(\"TimeStretch: %s \",error.what());\n  }\n  catch (...) { throw; }\n  return AVSValue(); // n/a\n}\n\nconst AVS_Linkage * AVS_linkage = 0;\nextern \"C\" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors) {\n  AVS_linkage = vectors;\n\n  // clip, base filename, start, end, image format/extension, info\n  env->AddFunction(\"TimeStretch\", \"c[tempo]f[rate]f[pitch]f[sequence]i[seekwindow]i[overlap]i[quickseek]b[aa]i\", Create_SoundTouch, 0);\n  env->AddFunction(\"TimeStretch\", \"c[tempo_n]i[tempo_d]i[rate_n]i[rate_d]i[pitch_n]i[pitch_d]i[sequence]i[seekwindow]i[overlap]i[quickseek]b[aa]i\", CreateRational_SoundTouch, 0);\n\n  return \"`TimeStretch' Changes tempo, pitch, and/or playback rate of audio.\";\n}\n"
  },
  {
    "path": "plugins/VDubFilter/CMakeLists.txt",
    "content": "CMAKE_MINIMUM_REQUIRED( VERSION 3.6.2...3.11 )\n\nset(PluginName \"VDubFilter\")\nset(ProjectName \"Plugin${PluginName}\")\n\n# Create library\nproject(${ProjectName} VERSION ${PROJECT_VERSION} LANGUAGES CXX)\nlist (APPEND SourceFiles\n    \"VDubFilter.cpp\"\n    \"GetCPUFlags.cpp\"\n    \"ScriptInterpreter.h\"\n    \"ScriptValue.h\"\n    \"VBitmap.h\"\n    \"vdplugin.h\"\n    \"vdvideofilt.h\"\n)\nadd_library(${ProjectName} SHARED ${SourceFiles})\nset_property(GLOBAL APPEND PROPERTY BUILT_TARGETS ${ProjectName})\nset_target_properties(${ProjectName} PROPERTIES \"OUTPUT_NAME\" ${PluginName})\nif (MINGW)\n  set_target_properties(${ProjectName} PROPERTIES PREFIX \"\")\n  set_target_properties(${ProjectName} PROPERTIES IMPORT_PREFIX \"\")\nendif()\n\n# Library dependencies\ntarget_link_libraries(${ProjectName} \"user32\")\n\n# Include directories\ntarget_include_directories(${ProjectName} PRIVATE ${AvsCore_SOURCE_DIR})\n\nif (MSVC_IDE)\n  # Copy output to a common folder for easy deployment\n  add_custom_command(\n    TARGET ${ProjectName}\n    POST_BUILD\n    COMMAND xcopy /Y \\\"$(TargetPath)\\\" \\\"${CMAKE_BINARY_DIR}/Output/plugins\\\"\n  )\nendif()\n\nINSTALL(TARGETS \"${ProjectName}\"\n        DESTINATION \"${CORE_PLUGIN_INSTALL_PATH}/avisynth\")\n"
  },
  {
    "path": "plugins/VDubFilter/GetCPUFlags.cpp",
    "content": "// Avisynth v1.0 beta.  Copyright 2000 Ben Rudiak-Gould.\n// http://www.math.berkeley.edu/~benrg/avisynth.html\n\n//\tVirtualDub - Video processing and capture application\n//\tCopyright (C) 1998-2000 Avery Lee\n//\n//\tThis program is free software; you can redistribute it and/or modify\n//\tit under the terms of the GNU General Public License as published by\n//\tthe Free Software Foundation; either version 2 of the License, or\n//\t(at your option) any later version.\n//\n//\tThis program is distributed in the hope that it will be useful,\n//\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n//\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//\tGNU General Public License for more details.\n//\n//\tYou should have received a copy of the GNU General Public License\n//\talong with this program; if not, write to the Free Software\n//\tFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n#include <avs/cpuid.h>\n#include <intrin.h>\n\n#define IS_BIT_SET(bitfield, bit) ((bitfield) & (1<<(bit)) ? true : false)\n\nstatic int CPUCheckForExtensions()\n{\n  int result = 0;\n  int cpuinfo[4];\n\n  __cpuid(cpuinfo, 1);\n  if (IS_BIT_SET(cpuinfo[3], 0))\n    result |= CPUF_FPU;\n  if (IS_BIT_SET(cpuinfo[3], 23))\n    result |= CPUF_MMX;\n  if (IS_BIT_SET(cpuinfo[3], 25))\n    result |= CPUF_SSE | CPUF_INTEGER_SSE;\n  if (IS_BIT_SET(cpuinfo[3], 26))\n    result |= CPUF_SSE2;\n  if (IS_BIT_SET(cpuinfo[2], 0))\n    result |= CPUF_SSE3;\n  if (IS_BIT_SET(cpuinfo[2], 9))\n    result |= CPUF_SSSE3;\n  if (IS_BIT_SET(cpuinfo[2], 19))\n    result |= CPUF_SSE4_1;\n  if (IS_BIT_SET(cpuinfo[2], 20))\n    result |= CPUF_SSE4_2;\n\n  // AVX\n#if (_MSC_FULL_VER >= 160040219)    // We require VC++2010 SP1 at least\n  bool xgetbv_supported = IS_BIT_SET(cpuinfo[2], 27);\n  bool avx_supported = IS_BIT_SET(cpuinfo[2], 28);\n  if (xgetbv_supported && avx_supported)\n  {\n    if ((_xgetbv(_XCR_XFEATURE_ENABLED_MASK) & 0x6ull) == 0x6ull)\n      result |= CPUF_AVX;\n  }\n#endif\n\n  // 3DNow!, 3DNow!, and ISSE\n  __cpuid(cpuinfo, 0x80000000);\n  if (cpuinfo[0] >= 0x80000001)\n  {\n    __cpuid(cpuinfo, 0x80000001);\n\n    if (IS_BIT_SET(cpuinfo[3], 31))\n      result |= CPUF_3DNOW;\n\n    if (IS_BIT_SET(cpuinfo[3], 30))\n      result |= CPUF_3DNOW_EXT;\n\n    if (IS_BIT_SET(cpuinfo[3], 22))\n      result |= CPUF_INTEGER_SSE;\n  }\n\n  return result;\n}\n\nint GetCPUFlags() {\n  static int lCPUExtensionsAvailable = CPUCheckForExtensions();\n  return lCPUExtensionsAvailable;\n}\n"
  },
  {
    "path": "plugins/VDubFilter/ScriptInterpreter.h",
    "content": "#ifndef f_SYLIA_SCRIPTINTERPRETER_H\n#define f_SYLIA_SCRIPTINTERPRETER_H\n\nclass VDScriptValue;\nclass VDScriptError;\nstruct VDScriptObject;\nclass IVDScriptInterpreter;\nstruct VDScriptFunctionDef;\n\ntypedef VDScriptValue (*VDScriptRootHandlerPtr)(IVDScriptInterpreter *,char *,void *);\n\nclass IVDScriptInterpreter {\npublic:\n\tvirtual\t~IVDScriptInterpreter() {}\n\n\tvirtual void __cdecl SetRootHandler(VDScriptRootHandlerPtr, void *)\t=0;\n\n\tvirtual void __cdecl ExecuteLine(const char *s)\t\t\t\t\t\t=0;\n\n\tvirtual void __cdecl ScriptError(int e)\t\t\t\t\t\t\t\t=0;\n\tvirtual const char* __cdecl TranslateScriptError(const VDScriptError& cse)\t=0;\n\tvirtual char** __cdecl AllocTempString(long l)\t\t\t\t\t\t=0;\n\n\tvirtual VDScriptValue __cdecl LookupObjectMember(const VDScriptObject *obj, void *, char *szIdent) = 0;\n\n\tvirtual const VDScriptFunctionDef * __cdecl GetCurrentMethod() = 0;\n\tvirtual int __cdecl GetErrorLocation() = 0;\n\tvirtual VDScriptValue\t__cdecl DupCString(const char *) = 0;\n};\n\nIVDScriptInterpreter *VDCreateScriptInterpreter();\n\n#define VDSCRIPT_EXT_ERROR(x)\tif(true){isi->ScriptError(VDScriptError::x); VDNEVERHERE;}else\n\n#endif\n"
  },
  {
    "path": "plugins/VDubFilter/ScriptValue.h",
    "content": "#ifndef f_SYLIA_SCRIPTVALUE_H\n#define f_SYLIA_SCRIPTVALUE_H\n\n// diff from original VDub: direct include\n// Copied from vdtypes.h.  Must be in sync.\n#ifndef VD_STANDARD_TYPES_DECLARED\n#if defined(_MSC_VER)\ntypedef signed __int64\t\tsint64;\ntypedef unsigned __int64\tuint64;\n#elif defined(__GNUC__)\ntypedef signed long long\tsint64;\ntypedef unsigned long long\tuint64;\n#endif\ntypedef signed int\t\t\tsint32;\ntypedef unsigned int\t\tuint32;\ntypedef signed short\t\tsint16;\ntypedef unsigned short\t\tuint16;\ntypedef signed char\t\t\tsint8;\ntypedef unsigned char\t\tuint8;\n\ntypedef sint64\t\t\t\tint64;\ntypedef sint32\t\t\t\tint32;\ntypedef sint16\t\t\t\tint16;\ntypedef sint8\t\t\t\tint8;\n\ntypedef ptrdiff_t\t\t\tsintptr;\ntypedef size_t\t\t\t\tuintptr;\n#endif\n\n\nclass VDScriptArray;\nstruct VDScriptObject;\nclass VDScriptValue;\nclass IVDScriptInterpreter;\nclass VariableTableEntry;\n\n// Note: These objects must match the corresponding objects from the plugin interface.\n\ntypedef VDScriptValue (*VDScriptObjectLookupFuncPtr)(IVDScriptInterpreter *, const VDScriptObject *, void *lpVoid, char *szName);\ntypedef void (*VDScriptFunction)(IVDScriptInterpreter *, VDScriptValue *, int);\n\nstruct VDScriptFunctionDef {\n\tVDScriptFunction\tfunc_ptr;\n\tconst char *name;\n\tconst char *arg_list;\n};\n\nstruct VDScriptObjectDef {\n\tconst char *name;\n\tconst VDScriptObject *obj;\n};\n\nstruct VDScriptObject {\n\tconst char *mpName;\n\tVDScriptObjectLookupFuncPtr Lookup;\n\tconst VDScriptFunctionDef\t\t*func_list;\n\tconst VDScriptObjectDef\t\t\t*obj_list;\n\tconst VDScriptObject\t\t*pNextObject;\n\tconst VDScriptFunctionDef\t*prop_list;\n};\n\nclass VDScriptValue {\npublic:\n\tenum { T_VOID, T_INT, T_PINT, T_STR, T_ARRAY, T_OBJECT, T_FNAME, T_FUNCTION, T_VARLV, T_LONG, T_DOUBLE } type;\n\tconst VDScriptObject *thisPtr;\n\tunion {\n\t\tint i;\n\t\tchar **s;\n\t\tstruct {\n\t\t\tconst VDScriptObject *def;\n\t\t\tvoid *p;\n\t\t} obj;\n\t\tstruct {\n\t\t\tconst VDScriptFunctionDef *pfn;\n\t\t\tvoid *p;\n\t\t} method;\n\t\tVariableTableEntry *vte;\n\t\tsint64 l;\n\t\tdouble d;\n\t} u;\n\n\tVDScriptValue()\t\t\t\t\t\t{ type = T_VOID; }\n\texplicit VDScriptValue(int i)\t\t\t\t{ type = T_INT;\t\t\tu.i = i; }\n\texplicit VDScriptValue(sint64 l)\t\t\t\t{ type = T_LONG;\t\tu.l = l; }\n\texplicit VDScriptValue(double d)\t\t\t\t{ type = T_DOUBLE;\t\tu.d = d; }\n\texplicit VDScriptValue(char **s)\t\t\t\t{ type = T_STR;\t\t\tu.s = s; }\n\texplicit VDScriptValue(void *p, const VDScriptObject *obj)\t{ type = T_OBJECT;\t\tu.obj.def = obj; u.obj.p = p; }\n\texplicit VDScriptValue(void *p, const VDScriptObject *obj, const VDScriptFunctionDef *pf)\t{ type = T_FNAME;\t\tthisPtr = obj; u.method.pfn = pf; u.obj.p = p; }\n\texplicit VDScriptValue(VariableTableEntry *vte) { type = T_VARLV;\t\tu.vte = vte; }\n\n\tVDScriptValue& operator=(int i) { type = T_INT; u.i = i; return *this; }\n\tVDScriptValue& operator=(sint64 l) { type = T_LONG; u.l = l; return *this; }\n\tVDScriptValue& operator=(double d) { type = T_DOUBLE; u.d = d; return *this; }\n\n\tbool isVoid() const\t\t\t{ return type == T_VOID; }\n\tbool isInt() const\t\t\t{ return type == T_INT; }\n\tbool isLong() const\t\t\t{ return type == T_LONG; }\n\tbool isDouble() const\t\t{ return type == T_DOUBLE; }\n\tbool isString() const\t\t{ return type == T_STR; }\n\tbool isObject() const\t\t{ return type == T_OBJECT; }\n\tbool isVarLV() const\t\t{ return type == T_VARLV; }\n\tbool isMethod() const\t\t{ return type == T_FNAME; }\n\n\tint\t\t\t\t\t\tasInt() const\t\t\t{ return u.i; }\n\tsint64\t\t\t\t\tasLong() const\t\t\t{ return u.l; }\n\tdouble\t\t\t\t\tasDouble() const\t\t{ return u.d; }\n\tchar **\t\t\t\t\tasString() const\t\t{ return u.s; }\n\tconst VDScriptObject *\tasObjectDef() const\t\t{ return u.obj.def; }\n\tvoid *\t\t\t\t\tasObjectPtr() const\t\t{ return u.obj.p; }\n\tVariableTableEntry*\t\tasVarLV() const\t\t{ return u.vte; }\n};\n\n#endif\n"
  },
  {
    "path": "plugins/VDubFilter/VBitmap.h",
    "content": "//\tVirtualDub - Video processing and capture application\n//\tCopyright (C) 1998-2001 Avery Lee\n//\n//\tThis program is free software; you can redistribute it and/or modify\n//\tit under the terms of the GNU General Public License as published by\n//\tthe Free Software Foundation; either version 2 of the License, or\n//\t(at your option) any later version.\n//\n//\tThis program is distributed in the hope that it will be useful,\n//\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n//\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//\tGNU General Public License for more details.\n//\n//\tYou should have received a copy of the GNU General Public License\n//\talong with this program; if not, write to the Free Software\n//\tFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n#ifndef f_VIRTUALDUB_VBITMAP_H\n#define f_VIRTUALDUB_VBITMAP_H\n\n#include <windows.h>\n\ntypedef unsigned\t\tPixel;\ntypedef unsigned\t\tPixel32;\ntypedef unsigned char\tPixel8;\ntypedef long\t\t\tPixCoord;\ntypedef\tlong\t\t\tPixDim;\ntypedef\tptrdiff_t\t\tPixOffset;\n\n#ifdef VDEXT_VIDEO_FILTER\n#define NOVTABLE __declspec(novtable)\n#else\n#define NOVTABLE\n#endif\n\nclass NOVTABLE VBitmap {\npublic:\n\tPixel *\t\t\tdata;\n\tPixel *\t\t\tpalette;\n\tint\t\t\t\tdepth;\n\tPixCoord\t\tw, h;\n\tPixOffset\t\tpitch;\n\tPixOffset\t\tmodulo;\n\tPixOffset\t\tsize;\n\tPixOffset\t\toffset;\n\n\tPixel *Address(PixCoord x, PixCoord y) const {\n\t\treturn Addressi(x, h-y-1);\n\t}\n\n\tPixel *Addressi(PixCoord x, PixCoord y) const {\n\t\treturn (Pixel *)((char *)data + y*pitch + x*(depth>>3));\n\t}\n\n\tPixel *Address16(PixCoord x, PixCoord y) const {\n\t\treturn Address16i(x, h-y-1);\n\t}\n\n\tPixel *Address16i(PixCoord x, PixCoord y) const {\n\t\treturn (Pixel *)((char *)data + y*pitch + x*2);\n\t}\n\n\tPixel *Address32(PixCoord x, PixCoord y) const {\n\t\treturn Address32i(x, h-y-1);\n\t}\n\n\tPixel *Address32i(PixCoord x, PixCoord y) const {\n\t\treturn (Pixel *)((char *)data + y*pitch + x*sizeof(Pixel));\n\t}\n\n\tPixOffset PitchAlign4() {\n\t\treturn ((w * depth + 31)/32)*4;\n\t}\n\n\tPixOffset PitchAlign8() {\n\t\treturn ((w * depth + 63)/64)*8;\n\t}\n\n\tPixOffset Modulo() {\n\t\treturn pitch - (w*depth+7)/8;\n\t}\n\n\tPixOffset Size() {\n\t\treturn pitch*h;\n\t}\n\n\t//////\n\n\tVBitmap() {\n#ifdef VDEXT_VIDEO_FILTER\n\t\tinit();\n#endif\n\t}\n\tVBitmap(void *data, PixDim w, PixDim h, int depth);\n\tVBitmap(void *data, BITMAPINFOHEADER *);\n\n#ifdef VDEXT_VIDEO_FILTER\n\tvoid init() { *(void **)this = g_vtbls.pvtblVBitmap; }\n#endif\n\n\tvirtual VBitmap& init(void *data, PixDim w, PixDim h, int depth);\n\tvirtual VBitmap& init(void *data, BITMAPINFOHEADER *);\n\n\tvirtual void MakeBitmapHeader(BITMAPINFOHEADER *bih) const;\n\n\tvirtual void AlignTo4();\n\tvirtual void AlignTo8();\n\n\tvirtual void BitBlt(PixCoord x2, PixCoord y2, const VBitmap *src, PixCoord x1, PixCoord y1, PixDim dx, PixDim dy) const;\n\tvirtual void BitBltDither(PixCoord x2, PixCoord y2, const VBitmap *src, PixDim x1, PixDim y1, PixDim dx, PixDim dy, bool to565) const;\n\tvirtual void BitBlt565(PixCoord x2, PixCoord y2, const VBitmap *src, PixDim x1, PixDim y1, PixDim dx, PixDim dy) const;\n\n\tvirtual bool BitBltXlat1(PixCoord x2, PixCoord y2, const VBitmap *src, PixCoord x1, PixCoord y1, PixDim dx, PixDim dy, const Pixel8 *tbl) const;\n\tvirtual bool BitBltXlat3(PixCoord x2, PixCoord y2, const VBitmap *src, PixCoord x1, PixCoord y1, PixDim dx, PixDim dy, const Pixel32 *tbl) const;\n\n\tvirtual bool StretchBltNearestFast(PixCoord x1, PixCoord y1, PixDim dx, PixDim dy, const VBitmap *src, double x2, double y2, double dx1, double dy1) const;\n\n\tvirtual bool StretchBltBilinearFast(PixCoord x1, PixCoord y1, PixDim dx, PixDim dy, const VBitmap *src, double x2, double y2, double dx1, double dy1) const;\n\n\tvirtual bool RectFill(PixCoord x1, PixCoord y1, PixDim dx, PixDim dy, Pixel32 c) const;\n\n\tenum {\n\t\tHISTO_LUMA,\n\t\tHISTO_GRAY,\n\t\tHISTO_RED,\n\t\tHISTO_GREEN,\n\t\tHISTO_BLUE,\n\t};\n\n\tvirtual bool Histogram(PixCoord x, PixCoord y, PixCoord dx, PixCoord dy, long *pHisto, int iHistoType) const;\n\n\t//// NEW AS OF VIRTUALDUB V1.2B\n\n\tvirtual bool BitBltFromYUY2(PixCoord x2, PixCoord y2, const VBitmap *src, PixCoord x1, PixCoord y1, PixDim dx, PixDim dy) const;\n\tvirtual bool BitBltFromI420(PixCoord x2, PixCoord y2, const VBitmap *src, PixCoord x1, PixCoord y1, PixDim dx, PixDim dy) const;\n\n\t//// NEW AS OF VIRTUALDUB V1.4C\n\n\tvirtual void MakeBitmapHeaderNoPadding(BITMAPINFOHEADER *bih) const;\n\n\t///////////\n\n\tbool BitBltFromYUY2Fullscale(PixCoord x2, PixCoord y2, const VBitmap *src, PixCoord x1, PixCoord y1, PixDim dx, PixDim dy) const;\n\nprivate:\n\tbool dualrectclip(PixCoord& x2, PixCoord& y2, const VBitmap *src, PixCoord& x1, PixCoord& y1, PixDim& dx, PixDim& dy) const;\n};\n\n#undef NOVTABLE\n\n\n\n#ifndef VDEXT_VIDEO_FILTER\nstruct VDPixmap;\n\nVDPixmap VDAsPixmap(const VBitmap& bm);\nVDPixmap VDAsPixmap565(const VBitmap& bm);\nVBitmap VDAsVBitmap(const VDPixmap& px);\n#endif\n\n#endif\n"
  },
  {
    "path": "plugins/VDubFilter/VDubFilter.cpp",
    "content": "// Avisynth v2.5.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include <avisynth.h>\n#include <avs/win.h>\n#include <avs/minmax.h>\n#include <cstdio>\n#include <new>\n#include <stddef.h>\n#include <vector>\n\n/********************************************************************\n* VirtualDub plugin support\n********************************************************************/\n// Update by pinterf, headers from VirtualDub2 project, April 2018\n// - Update from V6 interface to V20, Filtermod version 6\n// - VirtualDub2 support with extended colorspaces:\n// - Allow RGB24, RGB48, RGB64 besides RGB32\n// - AutoConvert 8 bit Planar RGB to/from RGB24, RGBPA to/from RGB32 (lossless)\n// - AutoConvert RGB48 and 16 bit Planar RGB(A) to/from RGB64 (lossless)\n// - Support YUV(A) 8 bits: YV12, YV16, YV24, YV411, YUVA420P8, YUVA422P8, YUVA444P8\n// - Support YUV(A) 10-16 bits (properly set \"ref_x\" maximum levels, no autoconvert)\n// - Supports prefetchProc2 callback (API >= V14 and prefetchProc2 is defined) for multiple input frames from one input clip\n//   PrefetchFrameDirect and PrefetchFrame are supported. PrefetchFrameSymbolic not supported\n// - Supports prefetchProc callback (API >= V12 and prefetchProc is defined)\n// - Supports when filter changes frame count of the output clip\n// - Range hint\n//   Imported Virtualdub filters are getting and extra named parameter to the end:\n//      String [rangehint]\n//   This parameter can tell the filter about a YUV-type clip colorspace info\n//   Allowed values:\n//     \"rec601\": limited range + 601\n//     \"rec709\": limited range + 709\n//     \"PC.601\": full range + 601\n//     \"PC.709\": full range + 709\n//     \"\"      : not defined (same as not given)\n//   Parameter will be ignored when clip is non-YUV\n//   How it works: the hint will _not_ change the internal VirtualDub colorspace\n//   constant (e.g. kPixFormat_YUV420_Planar -> kPixFormat_YUV420_Planar_709) but keeps\n//   the basic color space and sets colorSpaceMode and colorRangeMode in PixmapLayout.formatEx.\n//   Filter can either use this information or not, depending on supported API version\n//   and its implementation.\n//   E.g. Crossfade(20,30) -> Crossfade(20,30,\"rec601\") though this specific filter won't use it.\n\n\n//  VirtualDub - Video processing and capture application\n//  Copyright (C) 1998-2009 Avery Lee\n//\n//  This program is free software; you can redistribute it and/or modify\n//  it under the terms of the GNU General Public License as published by\n//  the Free Software Foundation; either version 2 of the License, or\n//  (at your option) any later version.\n//\n//  This program is distributed in the hope that it will be useful,\n//  but WITHOUT ANY WARRANTY; without even the implied warranty of\n//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//  GNU General Public License for more details.\n//\n//  You should have received a copy of the GNU General Public License\n//  along with this program; if not, write to the Free Software\n//  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n#include \"vdvideofilt.h\"\n#include \"vdplugin.h\"\n#include \"ScriptValue.h\"\n#include \"ScriptInterpreter.h\"\n#include \"VBitmap.h\"\n\nint GetCPUFlags(); // to have a prototype\n\n#define VDcall __cdecl\n\n//////////////////// from plugins.h ////////////////////\n\n// we need only VDXFilterModule in Avisynth\nstruct VDXFilterModule {\t\t// formerly FilterModule\n  struct VDXFilterModule *next, *prev;\n  VDXHINSTANCE\t\t\thInstModule;\n  VDXFilterModuleInitProc\tinitProc;\n  FilterModModuleInitProc\tfilterModInitProc;\n  VDXFilterModuleDeinitProc\tdeinitProc;\n};\n\n//////////////////// from videofilt.h ////////////////////\n\nstruct VDXFilterDefinition2 : public VDXFilterDefinition {\n  FilterModDefinition filterMod;\n\n  VDXFilterDefinition2() {\n    fm = 0;\n  }\n\n  VDXFilterDefinition2(const VDXFilterDefinition2& a)\n    :VDXFilterDefinition(a)\n  {\n    filterMod = a.filterMod;\n    fm = &filterMod;\n  }\n};\n\n//////////////////// helper for parameter passing ////////////////////\n\nclass CScriptValueStringHelper {\npublic:\n  void *lpVoid; // avs+: char ** helper, introduced for x64, the CScriptValue union is already 8 bytes\n};\n\n//////////////////// vbitmap things ////////////////////\n\nVBitmap& VBitmap::init(void *lpData, BITMAPINFOHEADER *bmih) {\n  data      = (Pixel *)lpData;\n  palette     = (Pixel *)(bmih+1);\n  depth     = bmih->biBitCount;\n  w       = bmih->biWidth;\n  h       = bmih->biHeight;\n  offset      = 0;\n  AlignTo4();\n\n  return *this;\n}\n\nVBitmap& VBitmap::init(void *data, PixDim w, PixDim h, int depth) {\n  this->data    = (Pixel32 *)data;\n  this->palette = NULL;\n  this->depth   = depth;\n  this->w     = w;\n  this->h     = h;\n  this->offset  = 0;\n  AlignTo8();\n\n  return *this;\n}\n\nvoid VBitmap::MakeBitmapHeader(BITMAPINFOHEADER *bih) const {\n  bih->biSize       = sizeof(BITMAPINFOHEADER);\n  bih->biBitCount   = (WORD)depth;\n  bih->biPlanes     = 1;\n  bih->biCompression    = BI_RGB;\n\n  if (pitch == ((w*bih->biBitCount + 31)/32) * 4)\n    bih->biWidth    = w;\n  else\n    bih->biWidth    = LONG(pitch*8 / depth);\n\n  bih->biHeight     = h;\n  bih->biSizeImage    = DWORD(pitch*h);\n  bih->biClrUsed      = 0;\n  bih->biClrImportant   = 0;\n  bih->biXPelsPerMeter  = 0;\n  bih->biYPelsPerMeter  = 0;\n}\n\nvoid VBitmap::AlignTo4() {\n  pitch   = PitchAlign4();\n  modulo    = Modulo();\n  size    = Size();\n}\n\nvoid VBitmap::AlignTo8() {\n  pitch   = PitchAlign8();\n  modulo    = Modulo();\n  size    = Size();\n}\n\n// Avisynth doesn't support the following functions.\n\nvoid VBitmap::BitBlt(PixCoord x2, PixCoord y2, const VBitmap *src, PixCoord x1, PixCoord y1, PixDim dx, PixDim dy) const\n{\n  throw AvisynthError(\"Unsupported VBitmap method: BitBlt\");\n}\n\nvoid VBitmap::BitBltDither(PixCoord x2, PixCoord y2, const VBitmap *src, PixDim x1, PixDim y1, PixDim dx, PixDim dy, bool to565) const\n{\n  throw AvisynthError(\"Unsupported VBitmap method: BitBltDither\");\n}\n\nvoid VBitmap::BitBlt565(PixCoord x2, PixCoord y2, const VBitmap *src, PixDim x1, PixDim y1, PixDim dx, PixDim dy) const\n{\n  throw AvisynthError(\"Unsupported VBitmap method: BitBlt565\");\n}\n\nbool VBitmap::BitBltXlat1(PixCoord x2, PixCoord y2, const VBitmap *src, PixCoord x1, PixCoord y1, PixDim dx, PixDim dy, const Pixel8 *tbl) const\n{\n  throw AvisynthError(\"Unsupported VBitmap method: BitBltXlat1\");\n}\n\nbool VBitmap::BitBltXlat3(PixCoord x2, PixCoord y2, const VBitmap *src, PixCoord x1, PixCoord y1, PixDim dx, PixDim dy, const Pixel32 *tbl) const\n{\n  throw AvisynthError(\"Unsupported VBitmap method: BitBltXlat3\");\n}\n\nbool VBitmap::StretchBltNearestFast(PixCoord x1, PixCoord y1, PixDim dx, PixDim dy, const VBitmap *src, double x2, double y2, double dx1, double dy1) const\n{\n  throw AvisynthError(\"Unsupported VBitmap method: StretchBltNearestFast\");\n}\n\nbool VBitmap::StretchBltBilinearFast(PixCoord x1, PixCoord y1, PixDim dx, PixDim dy, const VBitmap *src, double x2, double y2, double dx1, double dy1) const\n{\n  throw AvisynthError(\"Unsupported VBitmap method: StretchBltBilinearFast\");\n}\n\nbool VBitmap::RectFill(PixCoord x1, PixCoord y1, PixDim dx, PixDim dy, Pixel32 c) const\n{\n  throw AvisynthError(\"Unsupported VBitmap method: RectFill\");\n}\n\nbool VBitmap::Histogram(PixCoord x, PixCoord y, PixCoord dx, PixCoord dy, long *pHisto, int iHistoType) const\n{\n  throw AvisynthError(\"Unsupported VBitmap method: Histogram\");\n}\n\nbool VBitmap::BitBltFromYUY2(PixCoord x2, PixCoord y2, const VBitmap *src, PixCoord x1, PixCoord y1, PixDim dx, PixDim dy) const\n{\n  throw AvisynthError(\"Unsupported VBitmap method: BitBltFromYUY2\");\n}\n\nbool VBitmap::BitBltFromI420(PixCoord x2, PixCoord y2, const VBitmap *src, PixCoord x1, PixCoord y1, PixDim dx, PixDim dy) const\n{\n  throw AvisynthError(\"Unsupported VBitmap method: BitBltFromI420\");\n}\n\n//// NEW AS OF VIRTUALDUB V1.4C\n\nvoid VBitmap::MakeBitmapHeaderNoPadding(BITMAPINFOHEADER *bih) const\n{\n  throw AvisynthError(\"Unsupported VBitmap method: MakeBitmapHeaderNoPadding\");\n}\n\nbool VBitmap::BitBltFromYUY2Fullscale(PixCoord x2, PixCoord y2, const VBitmap *src, PixCoord x1, PixCoord y1, PixDim dx, PixDim dy) const\n{\n  throw AvisynthError(\"Unsupported VBitmap method: BitBltFromYUY2Fullscale\");\n}\n\n// end of old stuff\n///////////\n\nclass DummyFilterPreview : public IVDXFilterPreview {\n  void Die() { throw AvisynthError(\"VirtualDubFilterProxy: IFilterPreview not supported\"); }\npublic:\n  virtual void VDcall SetButtonCallback(VDXFilterPreviewButtonCallback, void *) { Die(); }\n  virtual void VDcall SetSampleCallback(VDXFilterPreviewSampleCallback, void *) { Die(); }\n  virtual bool VDcall isPreviewEnabled() { return false; }\n  virtual void VDcall Toggle(VDXHWND) {}\n  virtual void VDcall Display(VDXHWND, bool) {}\n  virtual void VDcall RedoFrame() {}\n  virtual void VDcall RedoSystem() {}\n  virtual void VDcall UndoSystem() {}\n  virtual void VDcall InitButton(VDXHWND) {}\n  virtual void VDcall Close() {}\n  virtual bool VDcall SampleCurrentFrame() { return false; }\n  virtual long VDcall SampleFrames() { return 0; }\n};\n\nclass DummyFilterPreview2 : public IVDXFilterPreview2 {\n  void Die() { throw AvisynthError(\"VirtualDubFilterProxy: IFilterPreview2 not supported\"); }\npublic:\n  virtual void VDcall SetButtonCallback(VDXFilterPreviewButtonCallback, void*) { Die(); }\n  virtual void VDcall SetSampleCallback(VDXFilterPreviewSampleCallback, void*) { Die(); }\n\n  virtual bool VDcall isPreviewEnabled() { return false; }\n  virtual void VDcall Toggle(VDXHWND) {}\n  virtual void VDcall Display(VDXHWND, bool) {}\n  virtual void VDcall RedoFrame() {}\n  virtual void VDcall RedoSystem() {}\n  virtual void VDcall UndoSystem() {}\n  virtual void VDcall InitButton(VDXHWND) {}\n  virtual void VDcall Close() {}\n  virtual bool VDcall SampleCurrentFrame() { return false; }\n  virtual long VDcall SampleFrames() { return 0; }\n\n  virtual bool VDcall IsPreviewDisplayed() { return false; };\n};\n\n////////////////////////////////////////////////////////////\n\nclass FilterDefinitionList;\n\ntypedef struct MyVDXFilterModule : VDXFilterModule {\n  IScriptEnvironment*    env;\n  const char*            avisynth_function_name;\n  int                    preroll;\n\n  int filterdef_ver_lo, filterdef_ver_hi; // compatible and actual filterdef version\n  int filtermod_ver_lo, filtermod_ver_hi; // compatible and actual filtermod version\n\n  int refcounter;\n\n  FilterDefinitionList*  fdl;\n} MyVDXFilterModule;\n\nclass FilterDefinitionList {\npublic:\n  MyVDXFilterModule * myFilterModule;\n  VDXFilterDefinition2* fd;\n  FilterDefinitionList* fdl;\n\n  FilterDefinitionList(MyVDXFilterModule* _myFilterModule, VDXFilterDefinition2* _fd) : myFilterModule(_myFilterModule), fd(_fd), fdl(myFilterModule->fdl) { };\n};\n\n////////////////// from pixmap.h //////////////////////////\n// to have a VDPixmap/VDPixmapLayout with 4th plane (alpha)\n\ntypedef sint32\t\tvdpixpos;\ntypedef sint32\t\tvdpixsize;\ntypedef ptrdiff_t\tvdpixoffset;\n\nstruct VDPixmap {\n  void\t\t\t*data;\n  const uint32\t*palette;\n  vdpixsize\t\tw;\n  vdpixsize\t\th;\n  vdpixoffset\t\tpitch;\n  sint32\t\t\tformat;\n\n  // Auxiliary planes are always byte-per-pixel.\n\n  void\t\t\t*data2;\t\t// Cb (U) for YCbCr\n  vdpixoffset\t\tpitch2;\n  void\t\t\t*data3;\t\t// Cr (V) for YCbCr\n  vdpixoffset\t\tpitch3;\n  void\t\t\t*data4;\t\t// Alpha\n  vdpixoffset\t\tpitch4;\n\n  FilterModPixmapInfo info;\n\n  void clear() {\n    data = 0;\n    palette = 0;\n    w = 0;\n    h = 0;\n    pitch = 0;\n    format = 0;\n    data2 = 0;\n    pitch2 = 0;\n    data3 = 0;\n    pitch3 = 0;\n    data4 = 0;\n    pitch4 = 0;\n    info.clear();\n  }\n\n  static VDPixmap copy(const VDXPixmap& a);\n};\n\n// from pixmaputils.cpp\n// avs+ uses nsVDXPixmap here instead of nsVDPixmap\nbool VDPixmapFormatHasAlphaPlane(sint32 format) {\n  switch (format) {\n  case nsVDXPixmap::kPixFormat_YUV444_Alpha_Planar:\n  case nsVDXPixmap::kPixFormat_YUV422_Alpha_Planar:\n  case nsVDXPixmap::kPixFormat_YUV420_Alpha_Planar:\n  case nsVDXPixmap::kPixFormat_YUV444_Alpha_Planar16:\n  case nsVDXPixmap::kPixFormat_YUV422_Alpha_Planar16:\n  case nsVDXPixmap::kPixFormat_YUV420_Alpha_Planar16:\n    return true;\n  }\n  return false;\n}\n\nVDPixmap VDPixmap::copy(const VDXPixmap& a) {\n  VDPixmap b;\n  b.data = a.data;\n  b.palette = a.palette;\n  b.w = a.w;\n  b.h = a.h;\n  b.pitch = a.pitch;\n  b.format = a.format;\n  b.data2 = a.data2;\n  b.pitch2 = a.pitch2;\n  b.data3 = a.data3;\n  b.pitch3 = a.pitch3;\n\n  if (VDPixmapFormatHasAlphaPlane(a.format)) {\n    const VDXPixmapAlpha& aa = (const VDXPixmapAlpha&)a;\n    b.data4 = aa.data4;\n    b.pitch4 = aa.pitch4;\n  }\n\n  return b;\n}\n\nstruct VDPixmapFormatEx {\n  sint32\t\t\tformat;\n  nsVDXPixmap::ColorSpaceMode colorSpaceMode;\n  nsVDXPixmap::ColorRangeMode colorRangeMode;\n\n  operator int() const { return format; }\n\n  VDPixmapFormatEx() {\n    format = 0;\n    colorSpaceMode = nsVDXPixmap::kColorSpaceMode_None;\n    colorRangeMode = nsVDXPixmap::kColorRangeMode_None;\n  }\n  VDPixmapFormatEx(sint32 v) {\n    format = v;\n    colorSpaceMode = nsVDXPixmap::kColorSpaceMode_None;\n    colorRangeMode = nsVDXPixmap::kColorRangeMode_None;\n  }\n  VDPixmapFormatEx(const VDPixmap& v) {\n    format = v.format;\n    colorSpaceMode = v.info.colorSpaceMode;\n    colorRangeMode = v.info.colorRangeMode;\n  }\n  VDPixmapFormatEx(const VDPixmapFormatEx& v) {\n    format = v.format;\n    colorSpaceMode = v.colorSpaceMode;\n    colorRangeMode = v.colorRangeMode;\n  }\n  bool fullEqual(const VDPixmapFormatEx& v) const {\n    return (format == v.format &&\n      colorSpaceMode == v.colorSpaceMode &&\n      colorRangeMode == v.colorRangeMode);\n  }\n  bool defaultMode() const {\n    return colorSpaceMode == nsVDXPixmap::kColorSpaceMode_None && colorRangeMode == nsVDXPixmap::kColorRangeMode_None;\n  }\n};\n\nstruct VDPixmapLayout {\n  ptrdiff_t data;\n  const uint32 *palette;\n  vdpixsize w;\n  vdpixsize h;\n  vdpixoffset pitch;\n  sint32 format;\n\n  // Auxiliary planes are always byte-per-pixel.\n\n  ptrdiff_t data2; // Cb (U) for YCbCr\n  vdpixoffset pitch2;\n  ptrdiff_t data3; // Cr (V) for YCbCr\n  vdpixoffset pitch3;\n  ptrdiff_t data4; // Alpha\n  vdpixoffset pitch4;\n\n  VDPixmapFormatEx formatEx;\n};\n/// end of pixmap.h\n\nclass MyFilterModPixmap : public IFilterModPixmap {\npublic:\n  // not VDcall calling convention!\n  virtual FilterModPixmapInfo* GetPixmapInfo(const VDXPixmap* pixmap) {\n    return &((VDPixmap*)pixmap)->info;\n  }\n  virtual uint64 GetFormat_XRGB64() {\n    return nsVDXPixmap::kPixFormat_XRGB64;\n  }\n};\n\n// Callback definitions\n\nchar exception_conversion_buffer[2048];\n\nstatic void VDcall VDFilterCallbackThrowExcept(const char *format, ...) {\n  va_list val;\n  va_start(val, format);\n  _vsnprintf(exception_conversion_buffer, sizeof(exception_conversion_buffer)-1, format, val);\n  va_end(val);\n  exception_conversion_buffer[sizeof(exception_conversion_buffer)-1] = '\\0';\n  throw AvisynthError(exception_conversion_buffer);\n}\n\nstatic void VDcall VDFilterCallbackExceptMemory() {\n  throw AvisynthError(\"VDubFilter: Out of memory.\");\n}\n\n// original quote from VD source :)\n// This is really disgusting...\n\nstruct VDXFilterVTbls {\n  void *pvtblVBitmap;\n};\n\nstatic void VDcall VDFilterCallbackInitVTables(VDXFilterVTbls *pvtbls) {\n  VBitmap tmp;\n  pvtbls->pvtblVBitmap = *(void **)&tmp;\n}\n\nVDXFilterDefinition *VDcall FilterAdd(VDXFilterModule *fm, VDXFilterDefinition *pfd, int fd_len);\nVDXFilterDefinition *VDcall FilterModAdd(VDXFilterModule *fm, VDXFilterDefinition *pfd, int fd_len, FilterModDefinition *pfm, int fm_len);\n\nvoid VDcall FilterRemove(VDXFilterDefinition*) {}\n\nstatic long VDFilterCallbackGetHostVersionInfo(char *buf, int len) {\n  char tbuf[256];\n\n  long version_num = 2; // why not\n  strcpy(tbuf, \"Avisynth+ VirtualDub interface\");\n  _snprintf(buf, len, tbuf, version_num,\n#ifdef _DEBUG\n    \"debug\"\n#else\n    \"release\"\n#endif\n  );\n\n  return version_num;\n}\n\nstatic long VDcall VDFilterCallbackGetCPUFlags() {\n  return GetCPUFlags();\n}\n\nbool VDcall VDFilterCallbackIsFPUEnabled() { return !!(GetCPUFlags() & CPUF_FPU); }\nbool VDcall VDFilterCallbackIsMMXEnabled() { return !!(GetCPUFlags() & CPUF_MMX); }\n\nVDXFilterFunctions g_VDFilterCallbacks={\n  FilterAdd, FilterRemove, VDFilterCallbackIsFPUEnabled, VDFilterCallbackIsMMXEnabled, VDFilterCallbackInitVTables,\n  VDFilterCallbackExceptMemory, VDFilterCallbackThrowExcept, VDFilterCallbackGetCPUFlags,VDFilterCallbackGetHostVersionInfo\n};\n\nFilterModInitFunctions g_FilterModCallbacks = {\n  FilterModAdd // yes, this is a single function\n};\n\n////////////////////////////////////////////////////////////\n\nclass MyScriptInterpreter : public IVDScriptInterpreter {\n  IScriptEnvironment* const env;\npublic:\n  MyScriptInterpreter(IScriptEnvironment* _env) : env(_env) {}\n  void VDcall Destroy() {}\n  void VDcall SetRootHandler(VDScriptRootHandlerPtr, void*) {}\n  void VDcall ExecuteLine(const char *s) {}\n  void VDcall ScriptError(int e) {\n    switch (e) {\n      case 21: env->ThrowError(\"VirtualdubFilterProxy: OUT_OF_MEMORY\");\n      case 24: env->ThrowError(\"VirtualdubFilterProxy: FCALL_OUT_OF_RANGE\");\n      case 26: env->ThrowError(\"VirtualdubFilterProxy: FCALL_UNKNOWN_STR\");\n      default: env->ThrowError(\"VirtualdubFilterProxy: Unknown error code %d\", e);\n    }\n  }\n  const char* VDcall TranslateScriptError(const VDScriptError&  cse) { return const_cast<char *>(\"\"); }\n  char** VDcall AllocTempString(long l) { return (char**)0; }\n  VDScriptValue VDcall LookupObjectMember(const VDScriptObject *obj, void *, char *szIdent) { return VDScriptValue(); }\n  // vdub2\n  const VDScriptFunctionDef* VDcall GetCurrentMethod() { return (VDScriptFunctionDef *)0; }\n  int VDcall GetErrorLocation() { return 0; }; // n/a\n  VDScriptValue VDcall DupCString(const char *s) { return VDScriptValue((char **)&s); }; // n/a\n};\n\n////////////////////////////////////////////////////////////////////////\n// prefetchProc2 implementation\n// (multiple source frames from the same clip)\n\n#if 0\n// just a sample, how a Prefetch2 in crossfade filter is calling\nbool Filter::Prefetch2(sint64 frame, IVDXVideoPrefetcher* prefetcher)\n{\n  if (param.pos == -1 || frame<param.pos - param.width) {\n    prefetcher->PrefetchFrameDirect(0, frame);\n    return true;\n  }\n  if (frame >= param.pos) {\n    prefetcher->PrefetchFrameDirect(0, frame + param.width);\n    return true;\n  }\n\n  prefetcher->PrefetchFrame(0, frame, 0);\n  prefetcher->PrefetchFrame(0, frame + param.width, 0);\n\n  return true;\n}\n#endif\n\n///////////////////////////////////////////////////////////////////////////\nclass VideoPrefetcher : public IVDXVideoPrefetcher {\npublic:\n  VideoPrefetcher(uint32 sourceCount);\n\n  bool operator==(const VideoPrefetcher& other) const;\n  bool operator!=(const VideoPrefetcher& other) const;\n\n  void Clear();\n#ifdef USE_TransformToNearestUnique\n  // not in AVS+\n  void TransformToNearestUnique(const vdvector<vdrefptr<IVDFilterFrameSource> >& src);\n  void Finalize();\n#endif\n\n  int VDXAPIENTRY AddRef() { return 2; }\n  int VDXAPIENTRY Release() { return 1; }\n\n  void * VDXAPIENTRY AsInterface(uint32 iid) {\n    if (iid == IVDXUnknown::kIID)\n      return static_cast<IVDXUnknown *>(this);\n    else if (iid == IVDXVideoPrefetcher::kIID)\n      return static_cast<IVDXVideoPrefetcher *>(this);\n\n    return NULL;\n  }\n\n  virtual void VDXAPIENTRY PrefetchFrame(sint32 srcIndex, sint64 frame, uint64 cookie);\n  virtual void VDXAPIENTRY PrefetchFrameDirect(sint32 srcIndex, sint64 frame);\n  virtual void VDXAPIENTRY PrefetchFrameSymbolic(sint32 srcIndex, sint64 frame);\n\n  struct PrefetchInfo {\n    sint64 mFrame;\n    uint64 mCookie;\n    uint32 mSrcIndex;\n\n    bool operator==(const PrefetchInfo& other) const {\n      return mFrame == other.mFrame && mCookie == other.mCookie && mSrcIndex == other.mSrcIndex;\n    }\n\n    bool operator!=(const PrefetchInfo& other) const {\n      return mFrame != other.mFrame || mCookie != other.mCookie || mSrcIndex != other.mSrcIndex;\n    }\n  };\n\n  // PF regular vector in avs\n  //typedef vdfastfixedvector<PrefetchInfo, 32> SourceFrames;\n  typedef std::vector<PrefetchInfo> SourceFrames;\n  SourceFrames mSourceFrames;\n\n  sint64\tmDirectFrame;\n  sint64\tmSymbolicFrame;\n  uint32\tmDirectFrameSrcIndex;\n  uint32\tmSymbolicFrameSrcIndex;\n  uint32\tmSourceCount;\n  const char *mpError;\n};\n\nVideoPrefetcher::VideoPrefetcher(uint32 sourceCount)\n  : mDirectFrame(-1)\n  , mDirectFrameSrcIndex(0)\n  , mSymbolicFrame(-1)\n  , mSymbolicFrameSrcIndex(0)\n  , mSourceCount(sourceCount)\n  , mpError(NULL)\n{\n}\n\nbool VideoPrefetcher::operator==(const VideoPrefetcher& other) const {\n  return mDirectFrame == other.mDirectFrame && mSourceFrames == other.mSourceFrames;\n}\n\nbool VideoPrefetcher::operator!=(const VideoPrefetcher& other) const {\n  return mDirectFrame != other.mDirectFrame || mSourceFrames != other.mSourceFrames;\n}\n\nvoid VideoPrefetcher::Clear() {\n  mDirectFrame = -1;\n  mSymbolicFrame = -1;\n  mSourceFrames.clear();\n}\n\n#ifdef USE_TransformToNearestUnique\n// not in avs+\nvoid VirtualdubFilterProxy::VideoPrefetcher::TransformToNearestUnique(const vdvector<vdrefptr<IVDFilterFrameSource> >& srcs) {\n  if (mDirectFrame >= 0)\n    mDirectFrame = srcs[mDirectFrameSrcIndex]->GetNearestUniqueFrame(mDirectFrame);\n\n  for (SourceFrames::iterator it(mSourceFrames.begin()), itEnd(mSourceFrames.end()); it != itEnd; ++it) {\n    PrefetchInfo& info = *it;\n\n    info.mFrame = srcs[info.mSrcIndex]->GetNearestUniqueFrame(info.mFrame);\n  }\n}\n\n// not supported in AVS\nvoid VirtualdubFilterProxy::VideoPrefetcher::Finalize() {\n  if (mSymbolicFrame < 0 && !mSourceFrames.empty()) {\n    vdint128 accum(0);\n    int count = 0;\n\n    for (SourceFrames::const_iterator it(mSourceFrames.begin()), itEnd(mSourceFrames.end()); it != itEnd; ++it) {\n      const PrefetchInfo& info = *it;\n      accum += info.mFrame;\n      ++count;\n    }\n\n    accum += (count >> 1);\n    mSymbolicFrame = accum / count;\n  }\n}\n#endif\n\nvoid VDXAPIENTRY VideoPrefetcher::PrefetchFrame(sint32 srcIndex, sint64 frame, uint64 cookie) {\n  if (srcIndex >= (sint64)mSourceCount) {\n    mpError = \"An invalid source index was specified in a prefetch operation.\";\n    return;\n  }\n\n  if (frame < 0)\n    frame = 0;\n\n  /*\n  // VD original:\n  PrefetchInfo& info = mSourceFrames.push_back();\n  info.mFrame = frame;\n  info.mCookie = cookie;\n  info.mSrcIndex = srcIndex;\n  */\n  PrefetchInfo info;\n  info.mFrame = frame;\n  info.mCookie = cookie;\n  info.mSrcIndex = srcIndex;\n  mSourceFrames.push_back(info);\n}\n\nvoid VDXAPIENTRY VideoPrefetcher::PrefetchFrameDirect(sint32 srcIndex, sint64 frame) {\n  if (srcIndex >= (sint64)mSourceCount) {\n    mpError = \"An invalid source index was specified in a prefetch operation.\";\n    return;\n  }\n\n  if (mDirectFrame >= 0) {\n    mpError = \"PrefetchFrameDirect() was called multiple times.\";\n    return;\n  }\n\n  if (frame < 0)\n    frame = 0;\n\n  mDirectFrame = frame;\n  mDirectFrameSrcIndex = srcIndex;\n  mSymbolicFrame = frame;\n  mSymbolicFrameSrcIndex = srcIndex;\n}\n\nvoid VDXAPIENTRY VideoPrefetcher::PrefetchFrameSymbolic(sint32 srcIndex, sint64 frame) {\n  if (srcIndex >= (sint64)mSourceCount) {\n    mpError = \"An invalid source index was specified in a prefetch operation.\";\n    return;\n  }\n\n  if (mSymbolicFrame >= 0) {\n    mpError = \"PrefetchFrameSymbolic() was called after a symbolic frame was already set.\";\n    return;\n  }\n\n  if (frame < 0)\n    frame = 0;\n\n  mSymbolicFrame = frame;\n  mSymbolicFrameSrcIndex = srcIndex;\n}\n\n// End of VideoPrefetcher help from FilterInstance.cpp\n///////////////////////////////////////////////////////////////////////////\n\n// filter instance\nclass VirtualdubFilterProxy : public GenericVideoFilter {\n  PVideoFrame src, dst, last;\n  VDXFBitmap vbSrc, vbLast, vbDst;\n  VDPixmapLayout PixmapLayoutSrc, PixmapLayoutLast, PixmapLayoutDst;\n  VDPixmap PixmapSrc, PixmapLast, PixmapDst;\n\n  // for multiple source frames\n  std::vector<VDXFBitmap *> mSourceFrameArray;\n  std::vector<VDXFBitmap *> mDestFrameArray; // only 1 supported\n\n  FilterDefinitionList* const fdl;\n  VDXFilterDefinition2* const fd;\n  VDXFilterStateInfo fsi;\n  VDXFilterActivation fa;\n  FilterModActivation fma;\n\n  DummyFilterPreview fp;\n  DummyFilterPreview2 fp2;\n  int expected_frame_number;\n\n  MyFilterModPixmap FilterModPixmap;\n\n  // prefetchProc2 support\n  VideoPrefetcher *AvsVdubPrefetcher;\n\n  // rangehint extra avs parameter support\n  enum RangeHintType {\n    kRangeHintNotSpecified = 0,\n    kRangeHintLimited601 = 1,\n    kRangeHintLimited709 = 2,\n    kRangeHintFull601 = 3,\n    kRangeHintFull709 = 4\n  };\n  uint32 rangeHint;\n\n  void CallStartProc() {\n    if (fd->startProc) {\n      int result = fd->startProc(&fa, &g_VDFilterCallbacks);\n      if (result != 0) {\n        if (fd->endProc)\n          fd->endProc(&fa, &g_VDFilterCallbacks);\n        throw AvisynthError(\"VirtualdubFilterProxy: error calling startProc\");\n      }\n    }\n  }\n\n  void CallEndProc() {\n    if (fd->endProc) {\n      int result = fd->endProc(&fa, &g_VDFilterCallbacks);\n      if (result != 0) {\n        throw AvisynthError(\"VirtualdubFilterProxy: error calling endProc\");\n      }\n    }\n  }\n\npublic:\n  VirtualdubFilterProxy(PClip _child, FilterDefinitionList* _fdl, AVSValue args, IScriptEnvironment* env)\n    : GenericVideoFilter(_child), fdl(_fdl), fd(_fdl->fd), fa(vbDst, vbSrc, &vbLast), AvsVdubPrefetcher(nullptr), rangeHint(0)\n  {\n    fdl->myFilterModule->refcounter++;\n\n    _RPT2(0, \"VirtualdubFilterProxy: Create called for %s, instanceNo=%d\\r\\n\", fdl->myFilterModule->avisynth_function_name, fdl->myFilterModule->refcounter);\n\n    if (!fd)\n      env->ThrowError(\"VirtualdubFilterProxy: No FilterDefinition structure!\");\n\n    if (vi.BitsPerComponent() == 32)\n      throw AvisynthError(\"VirtualdubFilterProxy: 32 bit float colorspaces are supported\");\n\n    if (!vi.IsRGB24() && !vi.IsRGB32() && !vi.IsRGB64() && !(vi.IsYV411() || vi.Is420() || vi.Is422() || vi.Is444() || vi.IsY()))\n      throw AvisynthError(\"VirtualdubFilterProxy: video format not supported\");\n\n    fma.filterMod = fdl->fd->fm;\n\n    fa.filter = fd;\n\n    fa.pfsi = &fsi; // VDXFilterStateInfo *pfsi;\n    fa.ifp = &fp;   // dummy filter preview\n    fa.ifp2 = &fp2; // dummy FilterPreview2\n    fa.filter_data = 0;\n\n    fa.x1 = 0;\n    fa.y1 = 0;\n    fa.x2 = 0;\n    fa.y2 = 0;\n\n    const int api_ver = fdl->myFilterModule->filterdef_ver_hi;\n\n    // we can specify multiple source frames from the same clip, see prefetch2\n    int sourceframecount = 1;\n\n    if (api_ver >= 14) {\n      fa.mSourceFrameCount = sourceframecount;\n    }\n\n    mSourceFrameArray.resize(sourceframecount);\n    mSourceFrameArray[0] = (VDXFBitmap *)&vbSrc;\n\n    // size=1 supported\n    mDestFrameArray.resize(1);\n    mDestFrameArray[0] = (VDXFBitmap *)&vbDst;\n\n    if (api_ver >= 14) {\n      // multiple source frame support from v14 (prefetch2)\n      fa.mpSourceFrames = reinterpret_cast<VDXFBitmap * const *>(mSourceFrameArray.data());\n      fa.mpOutputFrames = reinterpret_cast<VDXFBitmap * const *>(mDestFrameArray.data());\n    }\n    if (api_ver >= 15) {\n      fa.mpVDXA = nullptr; // IVDXAContext *mpVDXA;\n    }\n    if (api_ver >= 16) {\n      fa.mSourceStreamCount = 0; // (V16+)\n      fa.mpSourceStreams = nullptr; // (V16+)\n    }\n\n    if (api_ver >= 18) {\n      fma.filter = fd;\n      fma.fmpixmap = &FilterModPixmap;\n      fma.fmpreview = 0;\n      fma.fmsystem = 0;\n      fma.fmtimeline = 0;\n    }\n\n    fsi.lMicrosecsPerFrame = fsi.lMicrosecsPerSrcFrame = MulDiv(vi.fps_denominator, 1000000, vi.fps_numerator);\n\n    if (fd->inst_data_size) {\n      fa.filter_data = new char[fd->inst_data_size];\n      memset(fa.filter_data, 0, fd->inst_data_size);\n      if (fd->initProc) {\n        if (fd->initProc(&fa, &g_VDFilterCallbacks) != 0)\n          throw AvisynthError(\"VirtualdubFilterProxy: Error calling initProc\");\n      }\n\n      if (fma.filterMod) {\n        if (fma.filterMod->activateProc) {\n          fa.fma = &fma; // FilterModActivation* fma; // (V18+)\n          fma.filter_data = fa.filter_data; // just use pointer from fa\n          try {\n            fma.filterMod->activateProc(&fma, &g_VDFilterCallbacks);\n          }\n          catch (...) {\n            throw AvisynthError(\"VirtualdubFilterProxy: Error calling filtermod activateProc\");\n          }\n        }\n      }\n\n      // here we pass argument values of avs script to the filter's config\n      // extra avs-only parameter: [rangeHint]s\n      // There is always a clip-parameter-only kind of the filter, rangeHint is not applicable.\n      const int skipLastN = args.ArraySize() == 1 ? 0 : 1;\n\n      if (args.ArraySize() > 1 + skipLastN)\n        InvokeSyliaConfigFunction(fd, args, env, skipLastN);\n\n      // parse extra parameter seen only by avisynth\n      rangeHint = kRangeHintNotSpecified;\n      if (skipLastN > 0) {\n        const char *rangeHintStr = args[args.ArraySize() - skipLastN].AsString();\n        if (rangeHintStr) {\n          _RPT1(0, \"VdubFilterProxy Extra parameter found: %s\", rangeHint);\n          if (!lstrcmpi(rangeHintStr, \"rec601\"))\n            rangeHint = kRangeHintLimited601;\n          else if (!lstrcmpi(rangeHintStr, \"rec709\"))\n            rangeHint = kRangeHintLimited709;\n          else if (!lstrcmpi(rangeHintStr, \"PC.601\"))\n            rangeHint = kRangeHintFull601;\n          else if (!lstrcmpi(rangeHintStr, \"PC.709\"))\n            rangeHint = kRangeHintFull709;\n          else if (!lstrcmpi(rangeHintStr, \"\"))\n            rangeHint = kRangeHintNotSpecified;\n          else\n            env->ThrowError(\"VirtualDubFilterProxy: invalid 'rangehint' for '%s'\\r\\n\", fdl->myFilterModule->avisynth_function_name);\n        }\n      }\n\n    }\n\n/*  https://github.com/shekh/VirtualDub2/wiki/videofilt_processingvideoframes\n    The source frame buffers are specified by the src field of the VDXFilterActivation structure,\n    and the output frame buffer is specified by the dst field.The task of runProc is to process\n    the source image and write the result into the output image.The host has already allocated\n    both frame buffers and fetched the source frame by the time the filter is invoked,\n    so the only thing that needs to happen is to process the image data.\n\n    Note that if paramProc specified that the filter is operating in in-place mode, the source\n    and output frame buffers will point to the same memory.\n*/\n\n    // our intermediate lifetime buffer (when no prefetch2, single source frame case)\n    src = env->NewVideoFrame(vi);\n\n    SetVFBitmap(src, &vbSrc, vi, PixmapLayoutSrc, PixmapSrc, api_ver, rangeHint);\n    SetVFBitmap(src, &vbLast, vi, PixmapLayoutLast, PixmapLast, api_ver, rangeHint);\n    SetVFBitmap(src, &vbDst, vi, PixmapLayoutDst, PixmapDst, api_ver, rangeHint);\n\n    const long flags = fd->paramProc ? fd->paramProc(&fa, &g_VDFilterCallbacks) : FILTERPARAM_SWAP_BUFFERS;\n\n    // filter can change output frame count (length of clip) in paramProc\n    if (api_ver >= 12 && fa.dst.mFrameCount >= 0)\n      vi.num_frames = (int)fa.dst.mFrameCount;\n\n    // todo check what is does, do we need call both?\n    long flags2 = 0;\n    if (fd->fm) {\n      flags2 = fd->fm->paramProc ? fd->fm->paramProc(&fa, &g_VDFilterCallbacks) : 0;\n    }\n\n    if (flags == FILTERPARAM_NOT_SUPPORTED) {\n      env->ThrowError(\"VirtualdubFilterProxy: format not supported by %s\", fdl->myFilterModule->avisynth_function_name);\n    }\n\n    // Request distinct source and destination buffers. Otherwise, the source and destination buffers alias (in-place mode)\n    const bool two_buffers = !!(flags & FILTERPARAM_SWAP_BUFFERS);\n    const bool needs_last = !!(flags & FILTERPARAM_NEEDS_LAST); // since V16 this option is deprecated\n\n    // Filter supports image formats other than RGB32.\n    const bool supports_alternative_formats = !!(flags & FILTERPARAM_SUPPORTS_ALTFORMATS);\n    if (!supports_alternative_formats && !vi.IsRGB32())\n      env->ThrowError(\"VirtualdubFilterProxy: filter supports RGB32 only: %s\", fdl->myFilterModule->avisynth_function_name);\n\n    /// Filter requests that 16-bits input bitmap is normalized. This guarantees that info.ref_r..info.ref_a attributes are 0xFFFF when applicable.\n    const bool normalize16 = !!(flags & FILTERPARAM_NORMALIZE16);\n    if (normalize16)\n    {\n      if (vi.BitsPerComponent() >= 10 && vi.BitsPerComponent() <= 14)\n        env->ThrowError(\"VirtualdubFilterProxy: 10-14 bit formats are required to be normalized to 16 bits. %s\", fdl->myFilterModule->avisynth_function_name);\n    }\n\n    // FILTERPARAM_ALIGN_SCANLINES_16/32/64: not checked since avs+ has 64bytes alignment\n    // in classic AVS 2.6.0.5 only align=16 was guaranteed (except when unaligned crop is used)\n\n    const bool src_needs_hdc = (vbSrc.dwFlags & VDXFBitmap::NEEDS_HDC);\n    const bool dst_needs_hdc = (vbDst.dwFlags & VDXFBitmap::NEEDS_HDC);\n    if (src_needs_hdc || dst_needs_hdc) {\n      // only for RGB32, old feature\n      //      throw AvisynthError(\"VirtualdubFilterProxy: HDC not supported\");\n      vbSrc.hdc = vbDst.hdc = vbLast.hdc = (VDXHDC)GetDC(NULL);\n    }\n\n    // obsolate since v16\n    if (needs_last) {\n      last = env->NewVideoFrame(vi);\n      SetVFBitmap(last, &vbLast, vi, PixmapLayoutLast, PixmapLast, api_ver, rangeHint);\n    }\n\n    if (two_buffers) {\n      vi.width = vbDst.w;\n      vi.height = vbDst.h;\n      // for copying result back to Avisynth\n      dst = env->NewVideoFrame(vi);\n      SetVFBitmap(dst, &vbDst, vi, PixmapLayoutDst, PixmapDst, api_ver, rangeHint);\n    }\n\n    CallStartProc();\n    expected_frame_number = 0;\n  }\n\n  void SetVFBitmap(const PVideoFrame& pvf, VDXFBitmap* const pvb, const VideoInfo& vi\n    , VDPixmapLayout &PixmapLayout, VDPixmap &Pixmap, int api_ver, int rangeHint\n  ) {\n    pvb->data = (Pixel*)pvf->GetReadPtr();\n    pvb->palette = 0; // Not used for video filters.\n\n    /*\n    depth: Indicates the bit depth of the image. For video filters (RGB32), this is typically 32,\n    indicating 24-bit RGB with an unused 8 - bit alpha channel in the high byte(fourth byte in\n    memory order).\n    If this is zero, it means the bitmap uses an alternate format and the mpPixmap field must be used.\n        For multi-plane (e.g. UV) we should pass info in mpPixmapLayout\n    */\n    bool hasNewPixelFormats = api_ver >= 12;\n    pvb->depth = hasNewPixelFormats ? 0 : vi.BitsPerComponent() * vi.NumComponents(); // // 8*4=32 or 16*4=64\n    pvb->w = vi.width;\n    pvb->h = pvf->GetHeight();\n\n    /* pitch:\n    V12+ only: Bitmaps can be stored top - down as well as bottom-up.\n    The pitch value value is positive if the image is stored bottom-up\n    in memory and negative if the image is stored top-down. This is only\n    permitted if the filter declares support for flexible formats by\n    returning FILTERPARAM_SUPPORTS_ALTFORMATS from paramProc; otherwise,\n    the host ensures that the filter receives a bottom-up orientation\n    with a positive pitch, flipping the bitmap beforehand if necessary.\n    */\n    pvb->pitch = pvf->GetPitch();\n\n    /*\n    Distance from the end of one scanline to the beginning of the next,\n    in bytes. This value is positive or zero if the image is stored bottom-up\n    in memory and negative if the image is stored top-down. A value of zero\n    indicates that the image is stored bottom-up with no padding between\n    scanlines. For a 32-bit bitmap, modulo is equal to pitch - 4*w\n    */\n    pvb->modulo = pvf->GetPitch() - pvf->GetRowSize(); //   (pvb->w*pvb->depth + 7) / 8; // pvb->Modulo();\n    pvb->size = pvb->pitch * pvb->h; // size of plane 0 including padding\n    pvb->offset = 0; // Offset from the start of the buffer to the beginning of the bitmap, in bytes. V12+ only: For image formats that use multiple planes, this points to the base of plane 0.\n    pvb->dwFlags = 0;\n    pvb->hdc = 0;\n    if (api_ver >= 12) {\n      pvb->mFrameRateHi = vi.fps_numerator; // Frame rate numerator (V1.7.4+)\n      pvb->mFrameRateLo = vi.fps_denominator; // Frame rate denominator (V1.7.4+)\n      pvb->mFrameCount = vi.num_frames; // Frame count; -1 if unlimited or indeterminate (V1.7.4+)\n\n      /* mpPixmapLayout\n      V12+ only: More flexible description of bitmap layout, which is\n      able to accommodate multi - plane and YCbCr formats.In paramProc,\n      this field is always valid when provided by the host. When set by\n      the filter in paramProc, this field is activated when the depth\n      field of the bitmap is set to zero.\n      */\n      PixmapLayout.data = (ptrdiff_t)pvb->data; // (Pixel*)pvf->GetReadPtr();\n      PixmapLayout.pitch = pvb->pitch;\n      PixmapLayout.w = pvb->w;\n      PixmapLayout.h = pvb->h;\n      if (!vi.IsY() && (vi.IsYUV() || vi.IsYUVA()))\n      {\n        PixmapLayout.data2 = (ptrdiff_t)pvf->GetReadPtr(PLANAR_U);\n        PixmapLayout.data3 = (ptrdiff_t)pvf->GetReadPtr(PLANAR_V);\n        PixmapLayout.data4 = (ptrdiff_t)pvf->GetReadPtr(PLANAR_A);\n        PixmapLayout.pitch2 = (ptrdiff_t)pvf->GetPitch(PLANAR_U);\n        PixmapLayout.pitch3 = (ptrdiff_t)pvf->GetPitch(PLANAR_V);\n        PixmapLayout.pitch4 = (ptrdiff_t)pvf->GetPitch(PLANAR_A);;\n      }\n      else if (vi.IsPlanarRGB() || vi.IsPlanarRGBA()) // not used yet\n      {\n        PixmapLayout.data = (ptrdiff_t)pvf->GetReadPtr(PLANAR_G);\n        PixmapLayout.data2 = (ptrdiff_t)pvf->GetReadPtr(PLANAR_B);\n        PixmapLayout.data3 = (ptrdiff_t)pvf->GetReadPtr(PLANAR_R);\n        PixmapLayout.data4 = (ptrdiff_t)pvf->GetReadPtr(PLANAR_A);\n        PixmapLayout.pitch = (ptrdiff_t)pvf->GetPitch(PLANAR_G);\n        PixmapLayout.pitch2 = (ptrdiff_t)pvf->GetPitch(PLANAR_B);\n        PixmapLayout.pitch3 = (ptrdiff_t)pvf->GetPitch(PLANAR_R);\n        PixmapLayout.pitch4 = (ptrdiff_t)pvf->GetPitch(PLANAR_A);;\n      }\n      else {\n        PixmapLayout.data2 = 0;\n        PixmapLayout.data3 = 0;\n        PixmapLayout.data4 = 0;\n        PixmapLayout.pitch2 = 0;\n        PixmapLayout.pitch3 = 0;\n        PixmapLayout.pitch4 = 0;\n      }\n\n      if (vi.IsRGB24())\n        PixmapLayout.format = nsVDXPixmap::kPixFormat_RGB888;\n      else if (vi.IsRGB32())\n        PixmapLayout.format = nsVDXPixmap::kPixFormat_XRGB8888;\n      else if (vi.IsRGB64())\n        PixmapLayout.format = nsVDXPixmap::kPixFormat_XRGB64; // same as in GetFormat_XRGB64\n      else if (vi.IsY() && vi.BitsPerComponent() == 8)\n        PixmapLayout.format = nsVDXPixmap::kPixFormat_Y8;\n      else if (vi.IsYV411())\n        PixmapLayout.format = nsVDXPixmap::kPixFormat_YUV411_Planar;\n      else if (vi.IsYV12())\n        PixmapLayout.format = nsVDXPixmap::kPixFormat_YUV420_Planar;\n      else if (vi.IsYV16())\n        PixmapLayout.format = nsVDXPixmap::kPixFormat_YUV422_Planar;\n      else if (vi.IsYV24())\n        PixmapLayout.format = nsVDXPixmap::kPixFormat_YUV444_Planar;\n      else if (vi.Is420() && vi.IsYUVA() && vi.BitsPerComponent() == 8)\n        PixmapLayout.format = nsVDXPixmap::kPixFormat_YUV420_Alpha_Planar;\n      else if (vi.Is422() && vi.IsYUVA() && vi.BitsPerComponent() == 8)\n        PixmapLayout.format = nsVDXPixmap::kPixFormat_YUV422_Alpha_Planar;\n      else if (vi.Is444() && vi.IsYUVA() && vi.BitsPerComponent() == 8)\n        PixmapLayout.format = nsVDXPixmap::kPixFormat_YUV444_Alpha_Planar;\n      else if (vi.IsY() && vi.BitsPerComponent() <= 16) // allow 10-16 bits to report themselves as 16, normalize later\n        PixmapLayout.format = nsVDXPixmap::kPixFormat_Y16;\n      else if (vi.Is420() && vi.BitsPerComponent() <= 16)\n        PixmapLayout.format = vi.IsYUVA() ? nsVDXPixmap::kPixFormat_YUV420_Alpha_Planar16 : nsVDXPixmap::kPixFormat_YUV420_Planar16;\n      else if (vi.Is422() && vi.BitsPerComponent() <= 16)\n        PixmapLayout.format = vi.IsYUVA() ? nsVDXPixmap::kPixFormat_YUV422_Alpha_Planar16 : nsVDXPixmap::kPixFormat_YUV422_Planar16;\n      else if (vi.Is444() && vi.BitsPerComponent() <= 16)\n        PixmapLayout.format = vi.IsYUVA() ? nsVDXPixmap::kPixFormat_YUV444_Alpha_Planar16 : nsVDXPixmap::kPixFormat_YUV444_Planar16;\n\n      PixmapLayout.palette = 0;\n\n      // Avs terminology:\n      // don't use original constants, use base formats and formatEx instead\n      // Rec.601  kColorRangeMode_Limited, kColorSpaceMode_601 (n/a)\n      // Rec.709  kColorRangeMode_Limited, kColorSpaceMode_709 (_709)\n      // PC.601   kColorRangeMode_Full   , kColorSpaceMode_601 (_FR)\n      // PC.709   kColorRangeMode_Full   , kColorSpaceMode_709 (709_FR)\n      if (vi.IsYUV() || vi.IsYUVA() || vi.IsY()) {\n        switch (rangeHint) {\n        case kRangeHintLimited601:\n          PixmapLayout.formatEx.format = PixmapLayout.format;\n          PixmapLayout.formatEx.colorRangeMode = nsVDXPixmap::kColorRangeMode_Limited;\n          if(!vi.IsY())\n            PixmapLayout.formatEx.colorSpaceMode = nsVDXPixmap::kColorSpaceMode_601;\n          break;\n        case kRangeHintLimited709:\n          PixmapLayout.formatEx.format = PixmapLayout.format;\n          PixmapLayout.formatEx.colorRangeMode = nsVDXPixmap::kColorRangeMode_Limited;\n          if (!vi.IsY())\n            PixmapLayout.formatEx.colorSpaceMode = nsVDXPixmap::kColorSpaceMode_709;\n          break;\n        case kRangeHintFull601:\n          PixmapLayout.formatEx.format = PixmapLayout.format;\n          PixmapLayout.formatEx.colorRangeMode = nsVDXPixmap::kColorRangeMode_Full;\n          if (!vi.IsY())\n            PixmapLayout.formatEx.colorSpaceMode = nsVDXPixmap::kColorSpaceMode_601;\n          break;\n        case kRangeHintFull709:\n          PixmapLayout.formatEx.format = PixmapLayout.format;\n          PixmapLayout.formatEx.colorRangeMode = nsVDXPixmap::kColorRangeMode_Full;\n          if (!vi.IsY())\n            PixmapLayout.formatEx.colorSpaceMode = nsVDXPixmap::kColorSpaceMode_709;\n          break;\n        }\n      }\n\n      /* mpPixmap\n      V12 + only: More flexible description of bitmap, which is able to accommodate\n      multi - plane and YCbCr formats.\n      This field is always valid in runProc, even if mpPixmapLayout was not used in paramProc.\n      For filters that require V12 + of the API, mpPixmap may be used exclusively in runProc\n      in lieu of the regular data, pitch, etc.fields above.\n      */\n      Pixmap.data = (void *)PixmapLayout.data;\n      Pixmap.data2 = (void *)PixmapLayout.data2;\n      Pixmap.data3 = (void *)PixmapLayout.data3;\n      Pixmap.data4 = (void *)PixmapLayout.data4;\n      Pixmap.pitch = PixmapLayout.pitch;\n      Pixmap.pitch2 = PixmapLayout.pitch2;\n      Pixmap.pitch3 = PixmapLayout.pitch3;\n      Pixmap.pitch4 = PixmapLayout.pitch4;\n      Pixmap.format = PixmapLayout.format;\n      Pixmap.palette = PixmapLayout.palette;\n      Pixmap.h = PixmapLayout.h;\n      Pixmap.w = PixmapLayout.w;\n      // really it's FilterModVersion>=5\n      Pixmap.info.colorRangeMode = PixmapLayout.formatEx.colorRangeMode;\n      Pixmap.info.colorSpaceMode = PixmapLayout.formatEx.colorSpaceMode;\n\n      /*\n      With new 16 - bit formats these fields indicate maximum value(per channels for rgba, and only ref_r for all yuv channels).\n      When bitmap is normalized, ref values are 0xFFFF.\n      For example when bitmap contains un - normalized 10 - bit from ffmpeg, ref values are 0x3FF.\n      Can change with each frame(for example when appending different clips or using image sequence of different formats).\n      No matter what ref values are, all pixel values that fit in uint16 are legal (clamp during processing if necessary).\n      */\n      const int bits_per_pixel = vi.BitsPerComponent();\n      if (bits_per_pixel > 8) {\n        const int ref = (1 << bits_per_pixel) - 1;\n        if (vi.IsYUV() || vi.IsYUVA()) {\n          Pixmap.info.ref_r = ref;\n          Pixmap.info.ref_g = 0;\n          Pixmap.info.ref_b = 0;\n          Pixmap.info.ref_a = vi.IsYUVA() ? ref : 0;\n        }\n        else {\n          Pixmap.info.ref_r = ref;\n          Pixmap.info.ref_g = ref;\n          Pixmap.info.ref_b = ref;\n          Pixmap.info.ref_a = ref;\n        }\n      }\n\n      // originally Pixmap is VDPixmap w/ plane4 and info fields\n      pvb->mpPixmapLayout = (VDXPixmapLayout *)&PixmapLayout; // VDXPixmapLayout\t*mpPixmapLayout;\n      pvb->mpPixmap = (VDXPixmap *)&Pixmap; // const VDXPixmap* mpPixmap;\n\n      pvb->mAspectRatioHi = 0; ///< Pixel aspect ratio fraction (numerator). 0/0 = unknown\n      pvb->mAspectRatioLo = 0; ///< Pixel aspect ratio fraction (denominator).\n\n      pvb->mFrameNumber = 0; ///< Current frame number (zero based).\n      pvb->mFrameTimestampStart = 0; ///< Starting timestamp of frame, in 100ns units.\n      pvb->mFrameTimestampEnd = 0; ///< Ending timestamp of frame, in 100ns units.\n      pvb->mCookie = 0; ///< Cookie supplied when frame was requested.\n\n      pvb->mVDXAHandle = 0; ///< Acceleration handle to be used with VDXA routines.\n      pvb->mBorderWidth = 0;\n      pvb->mBorderHeight = 0;\n    }\n  }\n\n  void CopyFrame(PVideoFrame &dst, PVideoFrame &src, VideoInfo &vi, IScriptEnvironment* env)\n  {\n    const int planes_y[4] = { PLANAR_Y, PLANAR_U, PLANAR_V, PLANAR_A };\n    const int planes_r[4] = { PLANAR_G, PLANAR_B, PLANAR_R, PLANAR_A };\n    const int *planes;\n\n    int planeCount;\n    planeCount = vi.IsPlanar() ? vi.NumComponents() : 1;\n    planes = (!vi.IsPlanar() || vi.IsYUV() || vi.IsYUVA()) ? planes_y : planes_r;\n\n    for (int j = 0; j < planeCount; ++j)\n    {\n      int plane = planes[j];\n      env->BitBlt(dst->GetWritePtr(plane), dst->GetPitch(plane), src->GetReadPtr(plane), src->GetPitch(plane),\n        dst->GetRowSize(plane), dst->GetHeight(plane));\n    }\n  }\n\n  PVideoFrame FilterFrame(int n, IScriptEnvironment* env, bool in_preroll) {\n    // src: intermediate variable of the proxy, of which write pointers are prepared and 'published'\n    // Usage of last is not recommended anymore, anyway, old filters may use it.\n    if (last)\n      CopyFrame(last, src, vi, env);\n\n    /* https://github.com/shekh/VirtualDub2/wiki/videofilt_prefetchingmultiplesourceframes\n    ** prefetching multiple source frames\n    By default, VirtualDub video filters operate in 1:1 mode, where each source frame corresponds to\n    exactly one output frame.The output frame stream has the same frame count, frame rate, and frame\n    timings as the source stream.\n    V13 or earlier: Not possible.\n\n    Prefetching multiple source frames per output frame is only possible starting with API V14.\n    If you are targeting an earlier API version, you need to use alternative ways of handling this,\n    such as using internal buffering. See setting filter parameters on how to declare an internal\n    lagging delay in your filter to accommodate this.\n\n    In order to receive multiple source frames, a filter must implement the prefetchProc2 method.\n    This method receives a prefetcher object which is invoked by the filter for each source frame required.\n\n    ** Processing with multiple source frames\n    Normally, the runProc method receives input and output frames via the src and dst fields of\n    the VDXFilterActivation structure. The V14 API adds the mpInputFrames and mpOutputFrames arrays,\n    which contain pointers to source and output frames. The src and dst fields alias onto the first\n    entry of those arrays, whereas any additional frames take up additional slots.\n\n    If your filter does not need more than one source frame, it can continue to use src and dst.\n\n    ** Fetching frames in direct mode\n    With the prefetcher object, you can also invoke the PrefetchFrameDirect() method to indicate that\n    a frame should be copied directly from source to output. In addition to speeding up rendering for\n    frames that your filter does not need to process, this also permits smart rendering logic to\n    bypass the entire filter chain whenever possible and copy compressed frames directly from source.\n    This runs much faster and preserves full quality in the source. If your filter is designed to\n    only process a portion of its video, you should use PrefetchFrameDirect() whenever possible\n    to enable direct mode operation.\n\n    Note that even if you mark a frame as direct, your filter's runProc method may still be called.\n    One reason this may occur is if the frame cannot be copied in direct mode. When this happens,\n    your filter should copy the frame as required.\n\n    Direct mode requires that source and output frame formats be compatible. If the formats or frame\n    sizes do not match, it is a logic error to request a direct copy. You can, however, request a\n    direct copy between streams that are of different frame rates or aspect ratios.\n    */\n    const int api_ver = fdl->myFilterModule->filterdef_ver_hi;\n\n#if 0\n    if (filter->prefetchProc2) {\n      bool handled = false;\n\n      VDExternalCodeBracket bracket(mFilterName.c_str(), __FILE__, __LINE__);\n      vdprotected1(\"prefetching filter \\\"%s\\\"\", const char *, filter->name) {\n        handled = filter->prefetchProc2(AsVDXFilterActivation(), &g_VDFilterCallbacks, outputFrame, &prefetcher);\n      }\n\n      if (handled) {\n        if (prefetcher.mpError)\n          SetLogicErrorF(\"%s\", prefetcher.mpError);\n\n        if (!requireOutput || !prefetcher.mSourceFrames.empty() || prefetcher.mDirectFrame >= 0)\n          return;\n      }\n    }\n    else if (filter->prefetchProc) {\n      sint64 inputFrame;\n\n      VDExternalCodeBracket bracket(mFilterName.c_str(), __FILE__, __LINE__);\n      vdprotected1(\"prefetching filter \\\"%s\\\"\", const char *, filter->name) {\n        inputFrame = filter->prefetchProc(AsVDXFilterActivation(), &g_VDFilterCallbacks, outputFrame);\n      }\n\n      prefetcher.PrefetchFrame(0, inputFrame, 0);\n      return;\n    }\n\n    double factor = ((double)mRealSrc.mFrameRateHi * (double)mRealDst.mFrameRateLo) / ((double)mRealSrc.mFrameRateLo * (double)mRealDst.mFrameRateHi);\n\n    prefetcher.PrefetchFrame(0, VDFloorToInt64((outputFrame + 0.5f) * factor), 0); #endif\n#endif\n    std::vector<PVideoFrame> inputFrames;\n    std::vector<VDXFBitmap> inputBitmaps;\n    std::vector<VDPixmapLayout> inputPixmapLayouts;\n    std::vector<VDPixmap> inputPixmaps;\n\n    if (api_ver >= 14 && fd->prefetchProc2) {\n      bool handled = false;\n      // multiple source frames by using prefetch2\n      AvsVdubPrefetcher = new VideoPrefetcher(1); // one source\n      handled = fd->prefetchProc2(&fa, &g_VDFilterCallbacks, n, AvsVdubPrefetcher);\n      int numOfInputFrames;\n\n      if (handled) {\n        if (AvsVdubPrefetcher->mpError) {\n          env->ThrowError(\"VirtualdubFilterProxy: error during Prefetch2: %s\\r\\n\", AvsVdubPrefetcher->mpError);\n        }\n        const int mDirectFrameSrcIndex = AvsVdubPrefetcher->mDirectFrameSrcIndex; // no multiple sources yet, 0 at the moment\n        const int mDirectFrame = (int)AvsVdubPrefetcher->mDirectFrame;\n        if (mDirectFrame >= 0) {\n          delete AvsVdubPrefetcher;\n          // direct frame copy was requested by the filter (fast!)\n          PVideoFrame _src = child->GetFrame(mDirectFrame, env);\n          return _src;\n        }\n        // filter assembled a list of one or more frame numbers\n        numOfInputFrames = (int)AvsVdubPrefetcher->mSourceFrames.size();\n      }\n      else {\n        // 'not handled' case\n        numOfInputFrames = 1;\n      }\n\n      fa.mSourceFrameCount = numOfInputFrames;\n      mSourceFrameArray.resize(numOfInputFrames);\n\n      inputFrames.reserve(numOfInputFrames);\n      inputBitmaps.resize(numOfInputFrames);\n      inputPixmapLayouts.resize(numOfInputFrames);\n      inputPixmaps.resize(numOfInputFrames);\n\n      for (int i = 0; i < numOfInputFrames; i++) {\n        const int mSrcIndex = handled ? AvsVdubPrefetcher->mSourceFrames[i].mSrcIndex : 0; // no multiple sources, 0 at the moment\n        const int mFrame = handled ? (int)AvsVdubPrefetcher->mSourceFrames[i].mFrame : n; // frame no set in proc2 or original 'n'\n\n        inputFrames.emplace_back(child->GetFrame(mFrame, env));\n        SetVFBitmap(inputFrames[i], &inputBitmaps[i], vi, inputPixmapLayouts[i], inputPixmaps[i], api_ver, rangeHint);\n        mSourceFrameArray[i] = &inputBitmaps[i];\n      }\n      fa.mpSourceFrames = reinterpret_cast<VDXFBitmap * const *>(mSourceFrameArray.data());\n      delete AvsVdubPrefetcher;\n    }\n    else if (api_ver >= 12 && fd->prefetchProc) {\n      sint64 inputFrame = fd->prefetchProc(&fa, &g_VDFilterCallbacks, n);\n      PVideoFrame _src = child->GetFrame((int)inputFrame, env);\n      CopyFrame(src, _src, vi, env);\n    }\n    else\n    { // scoped to kill _src\n      PVideoFrame _src = child->GetFrame(n, env);\n      // PVideoFrame src is the variable, of which read pointers are filled into 'fa.src'\n      CopyFrame(src, _src, vi, env);\n    }\n\n    fsi.lCurrentSourceFrame = fsi.lCurrentFrame = n;\n    fsi.lDestFrameMS = fsi.lSourceFrameMS = MulDiv(n, fsi.lMicrosecsPerFrame, 1000);\n\n    fsi.flags = 0;\n    fsi.mOutputFrame = n; // (V13/V1.8.2+) current output frame\n\n    vbDst.mFrameNumber = n;\n\n    fd->runProc(&fa, &g_VDFilterCallbacks);\n\n    if (in_preroll) {\n      return 0;\n    } else {\n      PVideoFrame _dst = env->NewVideoFrame(vi);\n      CopyFrame(_dst, dst ? dst : src, vi, env);\n      return _dst;\n    }\n  }\n\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) {\n    _RPT1(0, \"GetFrame called %d\\r\\n\", n);\n    if (n != expected_frame_number) {\n      CallEndProc();\n      CallStartProc();\n      int preroll = fdl->myFilterModule->preroll;\n      for (int i = min(n, preroll); i > 0; i--)\n        FilterFrame(n - i, env, true);\n    }\n    expected_frame_number = n+1;\n    return FilterFrame(n, env, false);\n  }\n\n  static int ConvertArgs(const AVSValue* args, VDXScriptValue* sylia_args, CScriptValueStringHelper* sylia_args_string_helper, int count) {\n    for (int i=0; i<count; ++i) {\n      if (args[i].IsInt()) {\n        // the 64 bitness of an 'l' parameters is lost here, since avs has only as 32 bit Int, so we better fill up the whole 64 bits\n        sylia_args[i] = (sint64)args[i].AsInt();\n      } else if (args[i].IsFloat()) { // new from 160420 double support\n        sylia_args[i] = args[i].AsFloat();\n      } else if (args[i].IsString()) {\n        // Oops, where can we put the pointer to pointer in x64? no place in CScriptValue struct\n        // helper class/struct needed.\n        sylia_args_string_helper[i].lpVoid = (void*)args[i].AsString();\n        sylia_args[i] = (char**)&sylia_args_string_helper[i].lpVoid;\n        /* original, works only for 32 bit\n        sylia_args[i].lpVoid = (void*)args[i].AsString();\n        sylia_args[i] = (char**)&sylia_args[i].lpVoid;\n        */\n      } else if (args[i].IsArray()) {\n        return i+ConvertArgs(&args[i][0], sylia_args+i, sylia_args_string_helper+i, args[i].ArraySize());\n      } else {\n        return -1000;\n      }\n    }\n    return count;\n  }\n\n  // skipLastN: number of optinal extra avs-only parameters\n  void InvokeSyliaConfigFunction(VDXFilterDefinition* fd, AVSValue args, IScriptEnvironment* env, int skipLastN) {\n    if (fd->script_obj && fd->script_obj->func_list && args.ArraySize() > 1 + skipLastN) {\n      for (VDXScriptFunctionDef* i = fd->script_obj->func_list; i->arg_list; i++) {\n        const char* p = i->arg_list; // p: original virtualdub param list e.g. 0ddddddddd\n        int j;\n        for (j = 1; j < args.ArraySize() - skipLastN; j++) {\n          if (p[j] == 'i' && args[j].IsInt()) continue;\n          else if (p[j] == 'l' && args[j].IsInt()) continue;    // param long is only Int in avs\n          else if (p[j] == 'd' && args[j].IsFloat()) continue;  // 160420 type double support\n          else if (p[j] == 's' && args[j].IsString()) continue;\n          else if (p[j] == '.' && args[j].IsArray()) continue;\n          else break;\n        }\n        if (j == args.ArraySize() - skipLastN && p[j] == 0) {\n          // match\n          MyScriptInterpreter si(env);\n          VDXScriptValue sylia_args[30];\n          CScriptValueStringHelper sylia_args_string_helper[30]; // helper class. x64 char ** helper did not fit into CScriptValue class size\n          //int sylia_arg_count = ConvertArgs(&args[1], sylia_args, sylia_args_string_helper, args.ArraySize() - 1);\n          int sylia_arg_count = ConvertArgs(&args[1], sylia_args, sylia_args_string_helper, args.ArraySize()-1 - skipLastN);\n          if (sylia_arg_count < 0)\n            env->ThrowError(\"VirtualdubFilterProxy: arguments (after first) must be integers, double and strings only\");\n\n          // was: i->func_ptr(reinterpret_cast<IVDXScriptInterpreter *>(&si), &fa, sylia_args, sylia_arg_count);\n          // Casting to void retval is important, see in vdvideofilt.h VDXVideoFilterScriptAdapter:\n          // static void AdaptFn(IVDXScriptInterpreter *isi, void *fa0, const VDXScriptValue *argv, int argc)\n          VDXScriptVoidFunctionPtr fptr = reinterpret_cast<VDXScriptVoidFunctionPtr>(i->func_ptr);\n          fptr(reinterpret_cast<IVDXScriptInterpreter *>(&si), &fa, sylia_args, sylia_arg_count);\n          return;\n        }\n      }\n      env->ThrowError(\"VirtualdubFilterProxy: no matching config function (this shouldn't happen)\");\n    }\n  }\n\n  ~VirtualdubFilterProxy() {\n    _RPT3(0, \"VirtualdubFilterProxy: destructor called fdl=%p MyFilterModule=%p fd=%p\\r\\n\", fdl, fdl->myFilterModule, fd);\n    CallEndProc();\n    _RPT4(0, \"CallEndProc done fdl=%p MyFilterModule=%p fd=%p, instanceNo=%d\\r\\n\", fdl, fdl->myFilterModule, fd, fdl->myFilterModule->refcounter);\n    // filter activation is per instance\n    if (fa.filter_data) {\n      delete[] (char *)fa.filter_data; // PF 180417 190409 cast to char * before free (gcc warning: delete on void *)\n      fa.filter_data = nullptr;\n      fma.filter_data = nullptr; // fma had no separate filter data, just a same pointer\n    }\n    fdl->myFilterModule->refcounter--;\n    // don't delete until we reach the last filter instance\n    if (fdl->myFilterModule->refcounter == 0) {\n      FreeFilterModule(fdl->myFilterModule);\n      _RPT1(0, \"FreeFilterModule done fd:%p\\r\\n\", fd);\n    }\n    if (vbSrc.hdc)\n      ReleaseDC(NULL, (HDC)vbSrc.hdc);\n  }\n\n  void __cdecl FreeFilterModule(MyVDXFilterModule* fm) {\n    for (FilterDefinitionList* fdl = fm->fdl; fdl; fdl = fdl->fdl) {\n      _RPT1(0, \"VDub: FilterDefinition to be freed, fd: %p \\r\\n\", fdl->fd);\n      delete fdl->fd;\n      fdl->fd = nullptr;\n    }\n\n    fm->deinitProc(fm, &g_VDFilterCallbacks);\n    FreeLibrary((HMODULE)fm->hInstModule);\n    if (fm->prev)\n      fm->prev->next = fm->next;\n    if (fm->next)\n      fm->next->prev = fm->prev;\n    delete fm;\n  }\n\n  static AVSValue __cdecl Create(AVSValue args, void* user_data, IScriptEnvironment* env) {\n    FilterDefinitionList* fdl = (FilterDefinitionList*)user_data;\n    _RPT1(0, \"VDub: create new VirtualdubFilterProxy with fdl=%p\\r\\n\", fdl);\n\n    VideoInfo vi = (args[0].AsClip())->GetVideoInfo();\n\n    PClip clip = args[0].AsClip();\n\n    AVSValue new_args[1] = { clip };\n\n    // AutoConvert RGB24/48, and 8/16 bit Planar RGBAs to RGB32/64\n    // RGB24, RGBP8, RGBAP8 -> RGB32\n    // RGB48, RGBP16, RGBAP16 -> RGB64\n    if (vi.BitsPerComponent() == 8 && vi.IsPlanarRGB()) {\n      clip = env->Invoke(\"ConvertToRGB24\", AVSValue(new_args, 1)).AsClip();\n    }\n    else if (vi.BitsPerComponent() == 8 && vi.IsPlanarRGBA()) {\n      clip = env->Invoke(\"ConvertToRGB32\", AVSValue(new_args, 1)).AsClip();\n    }\n    else if (vi.IsRGB48() || (vi.BitsPerComponent() == 16 && (vi.IsPlanarRGB() || vi.IsPlanarRGBA()))) {\n      clip = env->Invoke(\"ConvertToRGB64\", AVSValue(new_args, 1)).AsClip();\n    }\n\n    clip = new VirtualdubFilterProxy(clip, fdl, args, env);\n\n    AVSValue new_args2[1] = { clip };\n    if (vi.IsPlanarRGB()) {\n      clip = env->Invoke(\"ConvertToPlanarRGB\", AVSValue(new_args2, 1)).AsClip();\n    }\n    else if (vi.IsPlanarRGBA()) {\n      clip = env->Invoke(\"ConvertToPlanarRGBA\", AVSValue(new_args2, 1)).AsClip();\n    }\n    else if (vi.IsRGB48()) {\n      clip = env->Invoke(\"ConvertToRGB48\", AVSValue(new_args2, 1)).AsClip();\n    }\n\n    return clip;\n  }\n};\n\n\n// helper for FilterModAdd and FilterAdd\nstatic void FilterBaseAdd_CreateAvsFnByParams(MyVDXFilterModule * fm2, FilterDefinitionList * fdl, VDXFilterDefinition2 * fd)\n{\n  const int MAX_PARAMS = 64;\n  char converted_paramlist[MAX_PARAMS + 1];\n\n  // send actual filter definition list as 'user_data' for create\n  // add optinal rangehint parameter, which is seen only by avisynth.\n  // See also skipLastN references, which should match the number of extra parameters here\n  fm2->env->AddFunction(fm2->avisynth_function_name, \"c\", VirtualdubFilterProxy::Create, fdl);\n  if (fd->script_obj && fd->script_obj->func_list) {\n    for (VDXScriptFunctionDef* i = fd->script_obj->func_list; i->arg_list; i++) {\n      // avisynth does not know 'd'ouble or 'l'ong\n      // let's fake them to 'f'loat and 'i'nt for avisynth\n      const char *p_src = i->arg_list + 1;\n      char *p_target = converted_paramlist;\n      char ch;\n      while ((ch = *p_src++) && (p_target - converted_paramlist)<MAX_PARAMS) {\n        if (ch == 'd') ch = 'f';\n        else if (ch == 'l') ch = 'i';\n        *p_target++ = ch;\n      }\n      *p_target = '\\0';\n\n      // put * if . found\n      const char* params = fm2->env->Sprintf(\"c%s%s[rangehint]s\", converted_paramlist, strchr(i->arg_list + 1, '.') ? \"*\" : \"\");\n      // send actual filter definition list as 'user_data' for create\n      fm2->env->AddFunction(fm2->avisynth_function_name, params, VirtualdubFilterProxy::Create, fdl);\n    }\n  }\n}\n\n// FilterAdd and FilterModAdd are callbacks\n// Each DLL (vdf filter group) informs the host about their available internal filters\n// These internal filters of a FilterModule are listed in the fdl (FilterDefinitionList) inside each fm (FilterModule)\n\nVDXFilterDefinition *VDcall FilterAdd(VDXFilterModule *fm, VDXFilterDefinition *pfd, int fd_len) {\n  VDXFilterDefinition2 *fd = new(std::nothrow) VDXFilterDefinition2;\n\n  MyVDXFilterModule *fm2 = reinterpret_cast<MyVDXFilterModule *>(fm);\n  _RPT1(0, \"VDXFilterDefinition created for %s\\r\\n\", fm2->avisynth_function_name);\n\n  FilterDefinitionList _fdl(fm2, fd);\n  // saving the fdl to the safe String-store\n  FilterDefinitionList *fdl = (FilterDefinitionList*)(fm2->env->SaveString((const char*)&_fdl, sizeof(_fdl)));\n  fm2->fdl = fdl;\n\n  if (fd) {\n    memcpy(fd, pfd, min(size_t(fd_len), sizeof(VDXFilterDefinition)));\n\n    fd->_module = NULL; // fd->module  = fm2; // deprecated, set to null\n    fd->_prev = NULL;\n    fd->_next = NULL;\n  }\n\n  FilterBaseAdd_CreateAvsFnByParams(fm2, fdl, fd);\n\n  return fd;\n}\n\nVDXFilterDefinition *VDcall FilterModAdd(VDXFilterModule *fm, VDXFilterDefinition *pfd, int fd_len, FilterModDefinition *pfm, int fm_len) {\n  VDXFilterDefinition2 *fd = new(std::nothrow) VDXFilterDefinition2;\n\n  MyVDXFilterModule *fm2 = reinterpret_cast<MyVDXFilterModule *>(fm); // cast to access our extra fields\n  _RPT1(0, \"VDXFilterDefinition2 created for %s\\r\\n\", fm2->avisynth_function_name);\n\n  FilterDefinitionList _fdl(fm2, fd);\n  // saving the fdl to the safe String-store\n  FilterDefinitionList *fdl = (FilterDefinitionList*)(fm2->env->SaveString((const char*)&_fdl, sizeof(_fdl)));\n  fm2->fdl = fdl;\n\n  if (fd) {\n    memcpy(fd, pfd, min(size_t(fd_len), sizeof(VDXFilterDefinition)));\n    // copy additional function pointer fields of FilterModDefinition\n    memcpy(&fd->fm, &pfm, min(size_t(fm_len), sizeof(FilterModDefinition)));\n\n    fd->_module = NULL; // deprecated, set to null\n    fd->_prev = NULL;\n    fd->_next = NULL;\n  }\n\n  FilterBaseAdd_CreateAvsFnByParams(fm2, fdl, fd);\n\n  return fd;\n}\n\nAVSValue __cdecl LoadVirtualdubPlugin(AVSValue args, void*, IScriptEnvironment* env) {\n  const char* const szModule = args[0].AsString();\n  const char* const avisynth_function_name = args[1].AsString();\n  const int preroll = args[2].AsInt(0);\n\n  HMODULE hmodule = LoadLibrary(szModule);\n  if (!hmodule)\n    env->ThrowError(\"LoadVirtualdubPlugin: Error opening \\\"%s\\\", error=0x%x\", szModule, GetLastError());\n\n  VDXFilterModuleInitProc initProc   = (VDXFilterModuleInitProc  )GetProcAddress(hmodule, \"VirtualdubFilterModuleInit2\");\n  VDXFilterModuleDeinitProc deinitProc = (VDXFilterModuleDeinitProc)GetProcAddress(hmodule, \"VirtualdubFilterModuleDeinit\");\n\n  FilterModModuleInitProc filterModInitProc = (FilterModModuleInitProc)GetProcAddress(hmodule, \"FilterModModuleInit\");\n\n  if (!initProc || !deinitProc) {\n    FreeLibrary(hmodule);\n    env->ThrowError(\"LoadVirtualdubPlugin: Module \\\"%s\\\" does not contain VirtualDub filters.\", szModule);\n  }\n\n  VDXFilterModule* loaded_modules = 0;\n  try {\n    loaded_modules = (VDXFilterModule*)env->GetVar(\"$LoadVirtualdubPlugin$\").AsString();\n  }\n  catch (IScriptEnvironment::NotFound) {}\n\n  for (VDXFilterModule* i = loaded_modules; i; i = i->next) {\n    if (i->hInstModule == (VDXHINSTANCE)hmodule) {\n      FreeLibrary(hmodule);\n      return AVSValue();\n    }\n  }\n\n  // For each different virtualdub dlls (vfd) one MyVDXFilterModule fm is created\n  // which contains necessary callbacks.\n  // The 'next' field of MyVDXFilterModule will link to the previous vdf entry.\n  MyVDXFilterModule* fm = new MyVDXFilterModule;\n  fm->refcounter = 0; // counts multiple instances of a filter\n\n  fm->hInstModule = (VDXHINSTANCE)hmodule;\n  fm->initProc = initProc;\n  fm->deinitProc = deinitProc;\n  fm->filterModInitProc = filterModInitProc;\n\n  fm->env = env;\n  fm->avisynth_function_name = avisynth_function_name;\n  fm->preroll = preroll;\n\n  // chain previous tree\n  fm->next = loaded_modules;\n  fm->prev = 0;\n\n  fm->fdl = 0; // no filter definition list yet\n\n  fm->filterdef_ver_hi = VIRTUALDUB_FILTERDEF_VERSION;\n  fm->filterdef_ver_lo = VIRTUALDUB_FILTERDEF_COMPATIBLE;\n  fm->filtermod_ver_hi = 0;\n  fm->filtermod_ver_lo = 0;\n\n  int errorNo = 0;\n\n  // trying filterModInitProc\n  if (filterModInitProc) {\n    fm->filtermod_ver_lo = FILTERMOD_VERSION;\n    fm->filtermod_ver_hi = FILTERMOD_VERSION;\n\n    if (filterModInitProc(fm, &g_FilterModCallbacks, fm->filterdef_ver_hi, fm->filterdef_ver_lo, fm->filtermod_ver_hi, fm->filtermod_ver_lo)) {\n      errorNo = 1;\n    }\n    else {\n      _RPT5(0, \"VDub2 filter added %s FILTERDEF_VER compat:%d hi:%d, FILTERMOD_VER lo:%d hi:%d \\r\\n\",\n        szModule, fm->filterdef_ver_lo, fm->filterdef_ver_hi, fm->filtermod_ver_lo, fm->filtermod_ver_hi);\n      // Check if the plugin's minimal requirement is higher than used by this Avs+ simulation\n      if (fm->filtermod_ver_lo > FILTERMOD_VERSION) {\n        fm->deinitProc(fm, &g_VDFilterCallbacks);\n        errorNo = 2;\n      }\n    }\n  }\n  else\n  {\n    if (fm->initProc(fm, &g_VDFilterCallbacks, fm->filterdef_ver_hi, fm->filterdef_ver_lo)) {\n      errorNo = 3;\n    }\n    else {\n      _RPT3(0, \"VDub oldstyle filter added %s FILTERDEF_VER compat:%d hi:%d\\r\\n\", szModule, fm->filterdef_ver_lo, fm->filterdef_ver_hi);\n    }\n  }\n\n  if (errorNo > 0) {\n    // Neuter any AVS functions that may have been created\n    for (FilterDefinitionList* fdl = fm->fdl; fdl; fdl = fdl->fdl) {\n      delete fdl->fd;\n      fdl->fd = 0;\n    }\n    FreeLibrary(hmodule);\n    delete fm;\n    switch (errorNo) {\n    case 1: env->ThrowError(\"LoadVirtualdubPlugin (mod): Error initializing module \\\"%s\\\"\", szModule);\n    case 2: env->ThrowError(\"LoadVirtualdubPlugin (mod): This filter uses too new of a filter interface!\"\n      \"You'll need to upgrade to a newer version of Avisynth VirtualDub plugin to use this filter \\\"%s\\\"\", szModule);\n    case 3: env->ThrowError(\"LoadVirtualdubPlugin: Error initializing module \\\"%s\\\"\", szModule);\n    }\n  }\n\n  // allow two directions\n  if (fm->next)\n    fm->next->prev = fm;\n\n  env->SetGlobalVar(\"$LoadVirtualdubPlugin$\", (const char*)fm);\n\n  return AVSValue();\n}\n\nconst AVS_Linkage * AVS_linkage = 0;\nextern \"C\" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors) {\n\tAVS_linkage = vectors;\n\n  // clip, base filename, start, end, image format/extension, info\n  env->AddFunction(\"LoadVirtualdubPlugin\", \"ss[preroll]i\", LoadVirtualdubPlugin, 0);\n\n  return \"`LoadVirtualdubPlugin' Allows to load and use filters written for VirtualDub.\";\n}\n"
  },
  {
    "path": "plugins/VDubFilter/vdplugin.h",
    "content": "//\tVirtualDub - Video processing and capture application\n//\tPlugin headers\n//\tCopyright (C) 1998-2007 Avery Lee, All Rights Reserved.\n//\n//\tThe plugin headers in the VirtualDub plugin SDK are licensed differently\n//\tdifferently than VirtualDub and the Plugin SDK themselves.  This\n//\tparticular file is thus licensed as follows (the \"zlib\" license):\n//\n//\tThis software is provided 'as-is', without any express or implied\n//\twarranty.  In no event will the authors be held liable for any\n//\tdamages arising from the use of this software.\n//\n//\tPermission is granted to anyone to use this software for any purpose,\n//\tincluding commercial applications, and to alter it and redistribute it\n//\tfreely, subject to the following restrictions:\n//\n//\t1.\tThe origin of this software must not be misrepresented; you must\n//\t\tnot claim that you wrote the original software. If you use this\n//\t\tsoftware in a product, an acknowledgment in the product\n//\t\tdocumentation would be appreciated but is not required.\n//\t2.\tAltered source versions must be plainly marked as such, and must\n//\t\tnot be misrepresented as being the original software.\n//\t3.\tThis notice may not be removed or altered from any source\n//\t\tdistribution.\n\n#ifndef f_VD2_PLUGIN_VDPLUGIN_H\n#define f_VD2_PLUGIN_VDPLUGIN_H\n\n#include <stddef.h>\n\n// Copied from <vd2/system/vdtypes.h>.  Must be in sync.\n#ifndef VD_STANDARD_TYPES_DECLARED\n\t#if defined(_MSC_VER)\n\t\ttypedef signed __int64\t\tsint64;\n\t\ttypedef unsigned __int64\tuint64;\n\t#elif defined(__GNUC__)\n\t\ttypedef signed long long\tsint64;\n\t\ttypedef unsigned long long\tuint64;\n\t#endif\n\ttypedef signed int\t\t\tsint32;\n\ttypedef unsigned int\t\tuint32;\n\ttypedef signed short\t\tsint16;\n\ttypedef unsigned short\t\tuint16;\n\ttypedef signed char\t\t\tsint8;\n\ttypedef unsigned char\t\tuint8;\n\n\ttypedef sint64\t\t\t\tint64;\n\ttypedef sint32\t\t\t\tint32;\n\ttypedef sint16\t\t\t\tint16;\n\ttypedef sint8\t\t\t\tint8;\n\n\ttypedef ptrdiff_t\t\t\tsintptr;\n\ttypedef size_t\t\t\t\tuintptr;\n#endif\n\ntypedef struct VDXHINSTANCEStruct *VDXHINSTANCE;\ntypedef struct VDXHDCStruct *VDXHDC;\ntypedef struct VDXHWNDStruct *VDXHWND;\n\n#ifndef VDXAPIENTRY\n\t#define VDXAPIENTRY __stdcall\n#endif\n\n#ifndef VDXAPIENTRYV\n\t#define VDXAPIENTRYV __cdecl\n#endif\n\nenum VDXCPUFeatureFlags {\n\tkVDXCPUF_CPUID\t\t= 0x00000001,\n\tkVDXCPUF_MMX\t\t= 0x00000004,\n\tkVDXCPUF_ISSE\t\t= 0x00000008,\n\tkVDXCPUF_SSE\t\t= 0x00000010,\n\tkVDXCPUF_SSE2\t\t= 0x00000020,\n\tkVDXCPUF_3DNOW\t\t= 0x00000040,\n\tkVDXCPUF_3DNOW_EXT\t= 0x00000080,\n\tkVDXCPUF_SSE3\t\t= 0x00000100,\n\tkVDXCPUF_SSSE3\t\t= 0x00000200,\n\tkVDXCPUF_SSE41\t\t= 0x00000400,\n\tkVDXCPUF_AVX\t\t= 0x00000800\n};\n\nenum {\n\tkVDXPlugin_APIVersion\t\t= 12\n};\n\n\nenum {\n\tkVDXPluginType_Video,\t\t// Updated video filter API is not yet complete.\n\tkVDXPluginType_Audio,\n\tkVDXPluginType_Input,\n\tkVDXPluginType_Tool,\n\tkVDXPluginType_Output,\n\tkVDXPluginType_AudioEnc\n};\n\ntypedef bool (VDXAPIENTRY *VDXShowStaticAboutProc)(VDXHWND parent);\ntypedef bool (VDXAPIENTRY *VDXShowStaticConfigureProc)(VDXHWND parent);\n\nstruct VDXPluginInfo {\n\tuint32\t\t\tmSize;\t\t\t\t// size of this structure in bytes\n\tconst wchar_t\t*mpName;\n\tconst wchar_t\t*mpAuthor;\n\tconst wchar_t\t*mpDescription;\n\tuint32\t\t\tmVersion;\t\t\t// (major<<24) + (minor<<16) + build.  1.4.1000 would be 0x010403E8.\n\tuint32\t\t\tmType;\n\tuint32\t\t\tmFlags;\n\tuint32\t\t\tmAPIVersionRequired;\n\tuint32\t\t\tmAPIVersionUsed;\n\tuint32\t\t\tmTypeAPIVersionRequired;\n\tuint32\t\t\tmTypeAPIVersionUsed;\n\tconst void *\tmpTypeSpecificInfo;\n\n\t// NEW\n\tVDXShowStaticAboutProc\t\tmpStaticAboutProc;\n\tVDXShowStaticConfigureProc\tmpStaticConfigureProc;\n};\n\ntypedef const VDXPluginInfo *const *(VDXAPIENTRY *tpVDXGetPluginInfo)();\n\ntypedef VDXPluginInfo VDPluginInfo;\ntypedef tpVDXGetPluginInfo tpVDPluginInfo;\n\nclass IVDXPluginCallbacks {\npublic:\n\tvirtual void * VDXAPIENTRY GetExtendedAPI(const char *pExtendedAPIName) = 0;\n\tvirtual void VDXAPIENTRYV SetError(const char *format, ...) = 0;\n\tvirtual void VDXAPIENTRY SetErrorOutOfMemory() = 0;\n\tvirtual uint32 VDXAPIENTRY GetCPUFeatureFlags() = 0;\n};\n\ntypedef IVDXPluginCallbacks IVDPluginCallbacks;\n\nstruct VDXPluginConfigEntry {\n\tenum Type {\n\t\tkTypeInvalid\t= 0,\n\t\tkTypeU32\t\t= 1,\n\t\tkTypeS32,\n\t\tkTypeU64,\n\t\tkTypeS64,\n\t\tkTypeDouble,\n\t\tkTypeAStr,\n\t\tkTypeWStr,\n\t\tkTypeBlock\n\t};\n\n\tconst VDXPluginConfigEntry *next;\n\n\tunsigned\tidx;\n\tuint32\t\ttype;\n\tconst wchar_t *name;\n\tconst wchar_t *label;\n\tconst wchar_t *desc;\n};\n\nstruct VDXRect {\n\tsint32\tleft;\n\tsint32\ttop;\n\tsint32\tright;\n\tsint32\tbottom;\n};\n\nnamespace nsVDXPixmap {\n\tenum ColorSpaceMode {\n\t\tkColorSpaceMode_None,\n\t\tkColorSpaceMode_601,\n\t\tkColorSpaceMode_709,\n\t\tkColorSpaceModeCount\n\t};\n\n\tenum ColorRangeMode {\n\t\tkColorRangeMode_None,\n\t\tkColorRangeMode_Limited,\n\t\tkColorRangeMode_Full,\n\t\tkColorRangeModeCount\n\t};\n};\n\nstruct FilterModPixmapInfo {\n\tenum MappingType {\n\t\tkTransferUnknown = 0,\n\t\tkTransferGamma = 1,\n\t\tkTransferLinear = 2,\n\t};\n\tenum AlphaType {\n\t\tkAlphaInvalid = 0,      // not present or garbage\n\t\tkAlphaMask = 1,         // arbitrary data, no default display\n\t\tkAlphaOpacity_pm = 2,   // display with transparency\n\t\tkAlphaOpacity = 3,      // display with transparency\n\t};\n\n\tuint32 ref_r;\n\tuint32 ref_g;\n\tuint32 ref_b;\n\tuint32 ref_a;\n\n\tuint32 transfer_type;\n\tuint32 alpha_type;\n\tint64 frame_num;\n\n\t// FilterModVersion>=5\n\tnsVDXPixmap::ColorSpaceMode colorSpaceMode;\n\tnsVDXPixmap::ColorRangeMode colorRangeMode;\n\n\tFilterModPixmapInfo() {\n\t\tclear();\n\t}\n\n\tvoid clear() {\n\t\tref_r = 0;\n\t\tref_g = 0;\n\t\tref_b = 0;\n\t\tref_a = 0;\n\t\ttransfer_type = kTransferUnknown;\n\t\talpha_type = kAlphaInvalid;\n\t\tframe_num = -1;\n\t\tcolorSpaceMode = nsVDXPixmap::kColorSpaceMode_None;\n\t\tcolorRangeMode = nsVDXPixmap::kColorRangeMode_None;\n\t}\n\n\tvoid copy_ref(const FilterModPixmapInfo& a) {\n\t\tref_r = a.ref_r;\n\t\tref_g = a.ref_g;\n\t\tref_b = a.ref_b;\n\t\tref_a = a.ref_a;\n\t}\n\tvoid copy_frame(const FilterModPixmapInfo& a) {\n\t\tframe_num = a.frame_num;\n\t}\n\tvoid copy_alpha(const FilterModPixmapInfo& a) {\n\t\talpha_type = a.alpha_type;\n\t}\n\tvoid copy_dynamic(const FilterModPixmapInfo& a) {\n\t\tcopy_ref(a);\n\t\tcopy_frame(a);\n\t\tcopy_alpha(a);\n\t\ttransfer_type = a.transfer_type;\n\t}\n};\n\nstruct VDXPixmap {\n\tvoid\t\t\t*data;\n\tconst uint32\t*palette;\n\tsint32\t\t\tw;\n\tsint32\t\t\th;\n\tptrdiff_t\t\tpitch;\n\tsint32\t\t\tformat;\n\n\t// Auxiliary planes are always byte-per-pixel.\n\tvoid\t\t\t*data2;\t\t// Cb (U) for YCbCr\n\tptrdiff_t\t\tpitch2;\n\tvoid\t\t\t*data3;\t\t// Cr (V) for YCbCr\n\tptrdiff_t\t\tpitch3;\n};\n\nstruct VDXPixmapLayout {\n\tptrdiff_t\t\tdata;\n\tconst uint32\t*palette;\n\tsint32\t\t\tw;\n\tsint32\t\t\th;\n\tptrdiff_t\t\tpitch;\n\tsint32\t\t\tformat;\n\n\t// Auxiliary planes are always byte-per-pixel.\n\tptrdiff_t\t\tdata2;\t\t// Cb (U) for YCbCr\n\tptrdiff_t\t\tpitch2;\n\tptrdiff_t\t\tdata3;\t\t// Cr (V) for YCbCr\n\tptrdiff_t\t\tpitch3;\n};\n\n// Alpha extensions: safe to upcast only when format defines alpha plane\n\nstruct VDXPixmapAlpha: public VDXPixmap {\n\tvoid\t\t\t*data4;\n\tptrdiff_t\t\tpitch4;\n};\n\nstruct VDXPixmapLayoutAlpha: public VDXPixmapLayout {\n\tptrdiff_t\t\tdata4;\n\tptrdiff_t\t\tpitch4;\n};\n\nclass IFilterModPixmap {\npublic:\n\tvirtual FilterModPixmapInfo* GetPixmapInfo(const VDXPixmap* pixmap)=0;\n\tvirtual uint64 GetFormat_XRGB64()=0;\n};\n\nnamespace nsVDXPixmap {\n\tenum VDXPixmapFormat {\n\t\tkPixFormat_Null\t\t\t\t\t\t= 0,\n\t\tkPixFormat_XRGB1555\t\t\t\t\t= 5,\n\t\tkPixFormat_RGB565\t\t\t\t\t= 6,\n\t\tkPixFormat_RGB888\t\t\t\t\t= 7,\n\t\tkPixFormat_XRGB8888\t\t\t\t\t= 8,\n\t\tkPixFormat_Y8\t\t\t\t\t\t= 9,\n\t\tkPixFormat_YUV422_UYVY\t\t\t\t= 10,\n\t\tkPixFormat_YUV422_YUYV\t\t\t\t= 11,\n\t\tkPixFormat_YUV444_Planar\t\t\t= 13,\n\t\tkPixFormat_YUV422_Planar\t\t\t= 14,\n\t\tkPixFormat_YUV420_Planar\t\t\t= 15,\n\t\tkPixFormat_YUV411_Planar\t\t\t= 16,\n\t\tkPixFormat_YUV410_Planar\t\t\t= 17,\n\t\tkPixFormat_YUV422_V210\t\t\t\t= 21,\n\t\tkPixFormat_YUV422_UYVY_709\t\t\t= 22,\n\t\tkPixFormat_Y8_FR\t\t\t\t\t= 24,\n\t\tkPixFormat_YUV422_YUYV_709\t\t\t= 25,\n\t\tkPixFormat_YUV444_Planar_709\t\t= 26,\n\t\tkPixFormat_YUV422_Planar_709\t\t= 27,\n\t\tkPixFormat_YUV420_Planar_709\t\t= 28,\n\t\tkPixFormat_YUV411_Planar_709\t\t= 29,\n\t\tkPixFormat_YUV410_Planar_709\t\t= 30,\n\t\tkPixFormat_YUV422_UYVY_FR\t\t\t= 31,\n\t\tkPixFormat_YUV422_YUYV_FR\t\t\t= 32,\n\t\tkPixFormat_YUV444_Planar_FR\t\t\t= 33,\n\t\tkPixFormat_YUV422_Planar_FR\t\t\t= 34,\n\t\tkPixFormat_YUV420_Planar_FR\t\t\t= 35,\n\t\tkPixFormat_YUV411_Planar_FR\t\t\t= 36,\n\t\tkPixFormat_YUV410_Planar_FR\t\t\t= 37,\n\t\tkPixFormat_YUV422_UYVY_709_FR\t\t= 38,\n\t\tkPixFormat_YUV422_YUYV_709_FR\t\t= 39,\n\t\tkPixFormat_YUV444_Planar_709_FR\t\t= 40,\n\t\tkPixFormat_YUV422_Planar_709_FR\t\t= 41,\n\t\tkPixFormat_YUV420_Planar_709_FR\t\t= 42,\n\t\tkPixFormat_YUV411_Planar_709_FR\t\t= 43,\n\t\tkPixFormat_YUV410_Planar_709_FR\t\t= 44,\n\t\tkPixFormat_YUV420i_Planar\t\t\t= 45,\n\t\tkPixFormat_YUV420i_Planar_FR\t\t= 46,\n\t\tkPixFormat_YUV420i_Planar_709\t\t= 47,\n\t\tkPixFormat_YUV420i_Planar_709_FR\t= 48,\n\t\tkPixFormat_YUV420it_Planar\t\t\t= 49,\n\t\tkPixFormat_YUV420it_Planar_FR\t\t= 50,\n\t\tkPixFormat_YUV420it_Planar_709\t\t= 51,\n\t\tkPixFormat_YUV420it_Planar_709_FR\t= 52,\n\t\tkPixFormat_YUV420ib_Planar\t\t\t= 53,\n\t\tkPixFormat_YUV420ib_Planar_FR\t\t= 54,\n\t\tkPixFormat_YUV420ib_Planar_709\t\t= 55,\n\t\tkPixFormat_YUV420ib_Planar_709_FR\t= 56,\n\n\t\tkPixFormat_XRGB64\t\t\t= 57,\n\t\tkPixFormat_YUV444_Planar16\t= 58,\n\t\tkPixFormat_YUV422_Planar16\t= 59,\n\t\tkPixFormat_YUV420_Planar16\t= 60,\n\t\tkPixFormat_Y16\t\t\t\t= 61,\n\t\tkPixFormat_YUV444_Y416\t= 62,\n\t\tkPixFormat_YUV444_V410\t= 63,\n\t\tkPixFormat_YUV444_Y410\t= 64,\n\t\tkPixFormat_R210\t\t\t= 65,\n\t\tkPixFormat_R10K\t\t\t= 66,\n\t\tkPixFormat_YUV444_V308\t= 67,\n\t\tkPixFormat_YUV422_P210\t= 68,\n\t\tkPixFormat_YUV420_P010\t= 69,\n\t\tkPixFormat_YUV422_P216\t= 70,\n\t\tkPixFormat_YUV420_P016\t= 71,\n\n\t\tkPixFormat_YUV444_Alpha_Planar = 72,\n\t\tkPixFormat_YUV422_Alpha_Planar = 73,\n\t\tkPixFormat_YUV420_Alpha_Planar = 74,\n\t\tkPixFormat_YUV444_Alpha_Planar16 = 75,\n\t\tkPixFormat_YUV422_Alpha_Planar16 = 76,\n\t\tkPixFormat_YUV420_Alpha_Planar16 = 77,\n\n\t\tkPixFormat_YUV422_YU64 = 78,\n\n\t\tkPixFormat_VDXA_RGB\t\t\t= 0x10001,\n\t\tkPixFormat_VDXA_YUV\t\t\t= 0x10002\n\t};\n};\n\n#define VDXMAKEFOURCC(a, b, c, d) ((uint32)(uint8)(d) + ((uint32)(uint8)(c) << 8) + ((uint32)(uint8)(b) << 16) + ((uint32)(uint8)(a) << 24))\n\nclass IVDXUnknown {\npublic:\n\tenum { kIID = VDXMAKEFOURCC('X', 'u', 'n', 'k') };\n\tvirtual int VDXAPIENTRY AddRef() = 0;\n\tvirtual int VDXAPIENTRY Release() = 0;\n\tvirtual void *VDXAPIENTRY AsInterface(uint32 iid) = 0;\n};\n\n#endif\n"
  },
  {
    "path": "plugins/VDubFilter/vdvideofilt.h",
    "content": "//\tVirtualDub - Video processing and capture application\n//\tCopyright (C) 1998-2001 Avery Lee\n//\n//\tThis program is free software; you can redistribute it and/or modify\n//\tit under the terms of the GNU General Public License as published by\n//\tthe Free Software Foundation; either version 2 of the License, or\n//\t(at your option) any later version.\n//\n//\tThis program is distributed in the hope that it will be useful,\n//\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n//\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n//\tGNU General Public License for more details.\n//\n//\tYou should have received a copy of the GNU General Public License\n//\talong with this program; if not, write to the Free Software\n//\tFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n#ifndef f_VD2_PLUGIN_VDVIDEOFILT_H\n#define f_VD2_PLUGIN_VDVIDEOFILT_H\n\n#ifdef _MSC_VER\n\t#pragma once\n#endif\n\n#include <stddef.h>\n\n#include \"vdplugin.h\"\n\n//////////////////\n\nstruct VDXScriptObject;\nstruct VDXFilterVTbls;\n\n//////////////////\n\nenum {\n\t/// Request distinct source and destination buffers. Otherwise, the source and destination buffers\n\t/// alias (in-place mode).\n\tFILTERPARAM_SWAP_BUFFERS\t\t= 0x00000001L,\n\n\t/// Request an extra buffer for the previous source frame.\n\tFILTERPARAM_NEEDS_LAST\t\t\t= 0x00000002L,\n\n\t/// Filter supports image formats other than RGB32. Filters that support format negotiation must\n\t/// set this flag for all calls to paramProc.\n\t///\n\t/// (API V16 - Now required)\n\tFILTERPARAM_SUPPORTS_ALTFORMATS\t= 0x00000004L,\n\n\t/// Filter requests 16 byte alignment for source and destination buffers. This guarantees that:\n\t///\n\t///\t\t- data and pitch fields are multiples of 16 bytes (aligned)\n\t///\t\t- an integral number of 16 byte vectors may be read, even if the last vector includes\n\t///\t\t  some bytes beyond the end of the scanline (their values are undefined)\n\t///\t\t- an integral number of 16 byte vectors may be written, even if the last vector includes\n\t///\t\t  some bytes beyong the end of the scanline (their values are ignored)\n\t///\n\tFILTERPARAM_ALIGN_SCANLINES_16\t\t= 0x00000008L,\n\tFILTERPARAM_ALIGN_SCANLINES\t\t\t= FILTERPARAM_ALIGN_SCANLINES_16,\n\n\t///\t\t- same with 32,64 bytes alignment\n\t///\n\tFILTERPARAM_ALIGN_SCANLINES_32\t\t= 0x00000048L,  // v19\n\tFILTERPARAM_ALIGN_SCANLINES_64\t\t= 0x00000040L,  // v19\n\n\t/// Filter's output is purely a function of configuration parameters and source image data, and not\n\t/// source or output frame numbers. In other words, two output frames produced by a filter instance\n\t/// can be assumed to be identical images if:\n\t///\n\t///\t\t- the same number of source frames are prefetched\n\t///\t\t- the same type of prefetches are performed (direct vs. non-direct)\n\t///\t\t- the frame numbers for the two prefetch lists, taken in order, correspond to identical\n\t///\t\t  source frames\n\t///\t\t- the prefetch cookies match\n\t///\n\t/// Enabling this flag improves the ability of the host to identify identical frames and drop them\n\t/// in preview or in the output file.\n\t///\n\tFILTERPARAM_PURE_TRANSFORM\t\t= 0x00000010L,\n\n\t/// Filter requests that 16-bits input bitmap is normalized. This guarantees that info.ref_r..info.ref_a attributes are 0xFFFF when applicable.\n\t///\n\tFILTERPARAM_NORMALIZE16\t\t= 0x00000020L,\n\n\t/// Filter cannot support the requested source format. Note that this sets all bits, so the meaning\n\t/// of other bits is ignored. The one exception is that FILTERPARAM_SUPPORTS_ALTFORMATS is assumed\n\t/// to be implicitly set.\n\tFILTERPARAM_NOT_SUPPORTED\t\t= (long)0xFFFFFFFF,\n\n\t/// Filter requires that image is not modified further and cpu time is not wasted.\n\t/// Intended for \"analyzis\" filters.\n\tFILTERPARAM_TERMINAL\t= 0x00000080L,  // v19\n};\n\n/// The filter has a delay from source to output. For instance, a lag of 3 indicates that the\n/// filter internally buffers three frames, so when it is fed frames in sequence, frame 0 emerges\n/// after frame 3 has been processed. The host attempts to correct timestamps in order to compensate.\n///\n/// VirtualDub 1.9.1 or later: Setting this flag can have a performance penalty, as it causes the host\n/// to request additional frames to try to produce the correct requested output frames.\n///\n#define FILTERPARAM_HAS_LAG(frames) ((int)(frames) << 16)\n\n///////////////////\n\nclass VDXFBitmap;\nclass VDXFilterActivation;\nstruct VDXFilterFunctions;\nclass FilterModActivation;\nstruct FilterModInitFunctions;\nstruct VDXFilterModule;\nstruct VDXFilterDefinition;\nclass IVDXVideoPrefetcher;\nclass IVDXAContext;\n\nenum {\n\tkVDXVFEvent_None\t\t\t\t= 0,\n\tkVDXVFEvent_InvalidateCaches\t= 1\n};\n\ntypedef int  (__cdecl *VDXFilterInitProc     )(VDXFilterActivation *fa, const VDXFilterFunctions *ff);\ntypedef void (__cdecl *VDXFilterDeinitProc   )(VDXFilterActivation *fa, const VDXFilterFunctions *ff);\ntypedef int  (__cdecl *VDXFilterRunProc      )(const VDXFilterActivation *fa, const VDXFilterFunctions *ff);\ntypedef long (__cdecl *VDXFilterParamProc    )(VDXFilterActivation *fa, const VDXFilterFunctions *ff);\ntypedef int  (__cdecl *VDXFilterConfigProc   )(VDXFilterActivation *fa, const VDXFilterFunctions *ff, VDXHWND hWnd);\ntypedef void (__cdecl *VDXFilterStringProc   )(const VDXFilterActivation *fa, const VDXFilterFunctions *ff, char *buf);\ntypedef int  (__cdecl *VDXFilterStartProc    )(VDXFilterActivation *fa, const VDXFilterFunctions *ff);\ntypedef int  (__cdecl *VDXFilterEndProc      )(VDXFilterActivation *fa, const VDXFilterFunctions *ff);\ntypedef bool (__cdecl *VDXFilterScriptStrProc)(VDXFilterActivation *fa, const VDXFilterFunctions *, char *, int);\ntypedef void (__cdecl *VDXFilterStringProc2  )(const VDXFilterActivation *fa, const VDXFilterFunctions *ff, char *buf, int maxlen);\ntypedef int  (__cdecl *VDXFilterSerialize    )(VDXFilterActivation *fa, const VDXFilterFunctions *ff, char *buf, int maxbuf);\ntypedef void (__cdecl *VDXFilterDeserialize  )(VDXFilterActivation *fa, const VDXFilterFunctions *ff, const char *buf, int maxbuf);\ntypedef void (__cdecl *VDXFilterCopy         )(VDXFilterActivation *fa, const VDXFilterFunctions *ff, void *dst);\ntypedef sint64 (__cdecl *VDXFilterPrefetch   )(const VDXFilterActivation *fa, const VDXFilterFunctions *ff, sint64 frame);\ntypedef void (__cdecl *VDXFilterCopy2Proc    )(VDXFilterActivation *fa, const VDXFilterFunctions *ff, void *dst, VDXFilterActivation *fa2, const VDXFilterFunctions *ff2);\ntypedef bool (__cdecl *VDXFilterPrefetch2Proc)(const VDXFilterActivation *fa, const VDXFilterFunctions *ff, sint64 frame, IVDXVideoPrefetcher *prefetcher);\ntypedef bool (__cdecl *VDXFilterEventProc\t )(const VDXFilterActivation *fa, const VDXFilterFunctions *ff, uint32 event, const void *eventData);\ntypedef void (__cdecl *VDXFilterAccelRunProc )(const VDXFilterActivation *fa, const VDXFilterFunctions *ff);\ntypedef void (__cdecl *FilterModActivateProc )(FilterModActivation *fma, const VDXFilterFunctions *ff);\ntypedef long (__cdecl *FilterModParamProc    )(VDXFilterActivation *fa, const VDXFilterFunctions *ff);\n\ntypedef int (__cdecl *VDXFilterModuleInitProc)(VDXFilterModule *fm, const VDXFilterFunctions *ff, int& vdfd_ver, int& vdfd_compat);\ntypedef int (__cdecl *FilterModModuleInitProc)(VDXFilterModule *fm, const FilterModInitFunctions *ff, int& vdfd_ver, int& vdfd_compat, int& mod_ver, int& mod_min);\ntypedef void (__cdecl *VDXFilterModuleDeinitProc)(VDXFilterModule *fm, const VDXFilterFunctions *ff);\n\n//////////\n\ntypedef void (__cdecl *VDXFilterPreviewButtonCallback)(bool fNewState, void *pData);\ntypedef void (__cdecl *VDXFilterPreviewSampleCallback)(VDXFBitmap *, long lFrame, long lCount, void *pData);\n\nclass IFilterModPreviewSample {\npublic:\n\t// Run returns combination of these flags\n\tenum {\n\t\tresult_image = 1, // destination image can be displayed in preview window\n\t};\n\n\tvirtual int Run(const VDXFilterActivation *fa, const VDXFilterFunctions *ff)=0;\n\tvirtual void GetNextFrame(sint64 frame, sint64* next_frame, sint64* total_count)=0;\n\tvirtual void Cancel()=0;\n};\n\n// avs+: have to set __cdecl for x86\nclass IVDXFilterPreview {\npublic:\n\tvirtual void __cdecl SetButtonCallback(VDXFilterPreviewButtonCallback, void *)=0;\n\tvirtual void __cdecl SetSampleCallback(VDXFilterPreviewSampleCallback, void *)=0;\n\n\tvirtual bool __cdecl isPreviewEnabled()=0;\n\tvirtual void __cdecl Toggle(VDXHWND)=0;\n\tvirtual void __cdecl Display(VDXHWND, bool)=0;\n\tvirtual void __cdecl RedoFrame()=0;\n\tvirtual void __cdecl RedoSystem()=0;\n\tvirtual void __cdecl UndoSystem()=0;\n\tvirtual void __cdecl InitButton(VDXHWND)=0;\n\tvirtual void __cdecl Close()=0;\n\tvirtual bool __cdecl SampleCurrentFrame()=0;\n\tvirtual long __cdecl SampleFrames()=0;\n};\n\nstruct PreviewZoomInfo {\n\tint version;\n\tenum {\n\t\tpopup_update = 1,\n\t\tpopup_cancel = 2,\n\t\tpopup_click =  4,\n\t};\n\tint flags;\n\tint x,y;\n\tfloat r,g,b,a;\n\n\tPreviewZoomInfo() { version = 0; }\n};\n\nstruct PreviewExInfo {\n\tint version;\n\tenum {\n\t\tthick_border = 1,\n\t\tcustom_draw = 2,\n\t\tdisplay_source = 4,\n\t\tno_exit = 8,\n\t};\n\tint flags;\n\n\tPreviewExInfo() { version = 0; flags = 0; }\n};\n\nstruct ClipEditInfo {\n\tint version;\n\tenum {\n\t\tedit_update = 1,\n\t\tedit_finish = 2,\n\t\tfill_border = 4,\n\t\tinit_size = 8,\n\t\tedit_time_range = 16,\n\t};\n\tint flags;\n\tint x1,y1,x2,y2;\n\tint w,h;\n\n\tClipEditInfo() { version = 0; flags = 0; }\n};\n\ntypedef void (__cdecl *FilterModPreviewPositionCallback)(int64 pos, void *pData);\ntypedef void (__cdecl *FilterModPreviewZoomCallback)(PreviewZoomInfo& info, void *pData);\ntypedef void (__cdecl *FilterModPreviewClipEditCallback)(ClipEditInfo& info, void *pData);\nstruct tagMSG;\n\nclass IVDXFilterPreview2 : public IVDXFilterPreview {\npublic:\n\tvirtual bool __cdecl IsPreviewDisplayed() = 0;\n};\n\nclass IFilterModPreview {\npublic:\n\tvirtual int64 FMSetPosition(int64 pos)=0;\n\tvirtual void FMSetPositionCallback(FilterModPreviewPositionCallback, void *)=0;\n\tvirtual void FMSetZoomCallback(FilterModPreviewZoomCallback, void *)=0;\n\n\t// FilterModVersion>=4\n\tvirtual int FMTranslateAccelerator(tagMSG* msg)=0;\n\n\t// FilterModVersion>=5\n\tvirtual long SampleFrames(IFilterModPreviewSample*)=0;\n\n\t// new\n\tvirtual void DisplayEx(VDXHWND, PreviewExInfo& info)=0;\n\tvirtual void SetClipEdit(ClipEditInfo& info) = 0;\n\tvirtual void SetClipEditCallback(FilterModPreviewClipEditCallback, void *) = 0;\n};\n\nclass IFilterModTimeline {\npublic:\n\tvirtual int64 GetTimelinePos()=0;\n\tvirtual int64 TimelineToFilterSource(int64 frame)=0;\n\tvirtual int64 FilterSourceToTimeline(int64 frame)=0;\n};\n\nclass FilterReturnInfo {\npublic:\n\tvirtual void setName(const char* s)=0;\n\tvirtual void setDesc(const char* s)=0;\n\tvirtual void setMaker(const char* s)=0;\n\tvirtual void setModulePath(const wchar_t* s)=0;\n\tvirtual void setBuiltinDef(const VDXFilterDefinition* desc)=0;\n};\n\nclass IFilterModSystem {\npublic:\n\tvirtual bool CreateVideoFilter(VDXHWND hParent, FilterReturnInfo& a)=0;\n\tvirtual bool FindVideoFilter(const char* name, FilterReturnInfo& a)=0;\n};\n\nclass IFilterModProject {\npublic:\n\tvirtual bool GetData(void* buf, size_t* buf_size, const wchar_t* id)=0;\n\tvirtual bool SetData(const void* buf, const size_t buf_size, const wchar_t* id)=0;\n\tvirtual bool GetProjectData(void* buf, size_t* buf_size, const wchar_t* id)=0;\n\tvirtual bool SetProjectData(const void* buf, const size_t buf_size, const wchar_t* id)=0;\n\tvirtual bool GetDataDir(wchar_t* buf, size_t* buf_size)=0;\n\tvirtual bool GetProjectDir(wchar_t* buf, size_t* buf_size)=0;\n\t// FilterModVersion>=6\n\tvirtual bool GetMainSource(wchar_t* buf, size_t* buf_size)=0;\n};\n\nclass IVDXVideoPrefetcher : public IVDXUnknown {\npublic:\n\tenum { kIID = VDXMAKEFOURCC('X', 'v', 'p', 'f') };\n\n\t/// Request a video frame fetch from an upstream source.\n\tvirtual void VDXAPIENTRY PrefetchFrame(sint32 srcIndex, sint64 frame, uint64 cookie) = 0;\n\n\t/// Request a video frame fetch from an upstream source in direct mode.\n\t/// This specifies that the output frame is the same as the input frame.\n\t/// There cannot be more than one direct fetch and there must be no standard\n\t/// fetches at the same time. There can, however, be symbolic fetches.\n\tvirtual void VDXAPIENTRY PrefetchFrameDirect(sint32 srcIndex, sint64 frame) = 0;\n\n\t/// Request a symbolic fetch from a source. This does not actually fetch\n\t/// any frames, but marks an association from source to output. This is\n\t/// useful for indicating the approximate center of where an output derives\n\t/// in a source, even if those frames aren't fetched (perhaps due to caching).\n\t/// There may be either zero or one symbolic fetch per source.\n\t///\n\t/// If no symbolic fetches are performed, the symbolic frame is assumed to\n\t/// be the rounded mean of the fetched source frames.\n\tvirtual void VDXAPIENTRY PrefetchFrameSymbolic(sint32 srcIndex, sint64 frame) = 0;\n};\n\n//////////\n\nenum {\n\t// This is the highest API version supported by this header file.\n\tVIRTUALDUB_FILTERDEF_VERSION\t\t= 20,\n\n\t// This is the absolute lowest API version supported by this header file.\n\t// Note that V4 is rather old, corresponding to VirtualDub 1.2.\n\t// Chances are you will need to declare a higher version.\n\tVIRTUALDUB_FILTERDEF_COMPATIBLE\t\t= 4,\n\n\t// API V9 is a slightly saner baseline, since it is the first API\n\t// version that has copy constructor support. You may still need to\n\t// declare a higher vdfd_compat version in your module init if you\n\t// need features beyond V9 (VirtualDub 1.4.12).\n\tVIRTUALDUB_FILTERDEF_COMPATIBLE_COPYCTOR = 9,\n\n\t// API V17 was last before vdubFM\n\tVIRTUALDUB_OFFICIAL\t\t= 17,\n};\n\n// v3: added lCurrentSourceFrame to FrameStateInfo\n// v4 (1.2): lots of additions (VirtualDub 1.2)\n// v5 (1.3d): lots of bugfixes - stretchblt bilinear, and non-zero startproc\n// v6 (1.4): added error handling functions\n// v7 (1.4d): added frame lag, exception handling\n// v8 (1.4.11): added string2 proc\n// v9 (1.4.12): added (working) copy constructor\n// v10 (1.5.10): added preview flag\n// v11 (1.7.0): guaranteed src structure setup before configProc; added IVDFilterPreview2\n// v12 (1.7.4): support for frame alteration\n// v13 (1.8.2): added mOutputFrame field to VDXFilterStateInfo\n// v14 (1.9.1): added copyProc2, prefetchProc2, input/output frame arrays\n// v15 (1.9.3): added VDXA support\n// v16 (1.10.x): added multi-source support, feature deprecation\n// v17: added mpStaticAboutProc\n// v18: added FilterModActivation\n// v19: added flags\n\nstruct FilterModDefinition;\n/*\nstruct FilterModDefinition {\n  FilterModActivateProc\t\tactivateProc;\n  FilterModParamProc\t\t  paramProc;\n  // avs+:\n  //FilterModDefinition(FilterModActivateProc _activateProc, FilterModParamProc _paramProc) : activateProc(_activateProc), paramProc(_paramProc) {};\n};\n*/\nstruct VDXFilterDefinition {\n\tvoid *_next;\t\t// deprecated - set to NULL\n\tvoid *_prev;\t\t// deprecated - set to NULL\n\tvoid *_module;\t\t// deprecated - set to NULL\n\n\tconst char *\t\tname;\n\tconst char *\t\tdesc;\n\tconst char *\t\tmaker;\n\tvoid *\t\t\t\tprivate_data;\n\tint\t\t\t\t\tinst_data_size;\n\n\tVDXFilterInitProc\t\tinitProc;\n\tVDXFilterDeinitProc\t\tdeinitProc;\n\tVDXFilterRunProc\t\trunProc;\n\tVDXFilterParamProc\t\tparamProc;\n\tVDXFilterConfigProc\t\tconfigProc;\n\tVDXFilterStringProc\t\tstringProc;\t\t\t// DEPRECATED - ignored as of v16; use stringProc2\n\tVDXFilterStartProc\t\tstartProc;\n\tVDXFilterEndProc\t\tendProc;\n\n\tVDXScriptObject\t\t\t*script_obj;\n\n\tVDXFilterScriptStrProc\tfssProc;\n\n\t// NEW - 1.4.11\n\tVDXFilterStringProc2\tstringProc2;\n\tVDXFilterSerialize\t\tserializeProc;\n\tVDXFilterDeserialize\tdeserializeProc;\n\tVDXFilterCopy\t\t\tcopyProc;\t\t\t// DEPRECATED - ignored as of v16; use copyProc2\n\n\tVDXFilterPrefetch\t\tprefetchProc;\t\t// (V12/V1.7.4+)\n\n\t// NEW - V14 / 1.9.1\n\tVDXFilterCopy2Proc\t\tcopyProc2;\n\tVDXFilterPrefetch2Proc\tprefetchProc2;\n\tVDXFilterEventProc\t\teventProc;\n\n\t// NEW - V15 / 1.9.3\n\tVDXFilterAccelRunProc\taccelRunProc;\n\n\t// NEW - V16 / 1.10.1\n\tsint32\t\t\t\t\tmSourceCountLowMinus1;\n\tsint32\t\t\t\t\tmSourceCountHighMinus1;\n\n\t// NEW - V17 / 1.10.2\n\tVDXShowStaticAboutProc\t\tmpStaticAboutProc;\n\tVDXShowStaticConfigureProc\tmpStaticConfigureProc;\n\n\t// NEW - V20\n\tFilterModDefinition* fm;\n};\n\nstruct FilterModDefinition {\n\tFilterModActivateProc\t\tactivateProc;\n\tFilterModParamProc\t\t  paramProc;\n};\n\n//////////\n\n// FilterStateInfo: contains dynamic info about file being processed\n\nclass VDXFilterStateInfo {\npublic:\n\tsint32\tlCurrentFrame;\t\t\t\t// current sequence frame (previously called output frame)\n\tsint32\tlMicrosecsPerFrame;\t\t\t// microseconds per sequence frame\n\tsint32\tlCurrentSourceFrame;\t\t// current source frame\n\tsint32\tlMicrosecsPerSrcFrame;\t\t// microseconds per source frame\n\tsint32\tlSourceFrameMS;\t\t\t\t// source frame timestamp\n\tsint32\tlDestFrameMS;\t\t\t\t// output frame timestamp\n\n\tenum {\n\t\tkStateNone\t\t= 0x00000000,\n\t\tkStatePreview\t= 0x00000001,\t// (V1.5.10+) Job output is not being saved to disk.\n\t\tkStateRealTime\t= 0x00000002,\t// (V1.5.10+) Operation is running in real-time (capture, playback).\n\t\tkStateMax\t\t= 0xFFFFFFFF\n\t};\n\n\tuint32\tflags;\n\n\tsint32\tmOutputFrame;\t\t\t\t// (V13/V1.8.2+) current output frame\n};\n\n// VDXFBitmap: VBitmap extended to hold filter-specific information\n\nclass VDXBitmap {\npublic:\n\tvoid *\t\t\t_vtable;\t// Reserved - do not use.\n\tuint32 *\t\tdata;\t\t// Pointer to start of _bottom-most_ scanline of plane 0.\n\tuint32 *\t\tpalette;\t// Pointer to palette (reserved - set to NULL).\n\tsint32\t\t\tdepth;\t\t// Bit depth, in bits. Set to zero if mpPixmap/mpPixmapLayout are active.\n\tsint32\t\t\tw;\t\t\t// Width of bitmap, in pixels.\n\tsint32\t\t\th;\t\t\t// Height of bitmap, in pixels.\n\tptrdiff_t\t\tpitch;\t\t// Distance, in bytes, from the start of one scanline in plane 0 to the next.\n\tptrdiff_t\t\tmodulo;\t\t// Distance, in bytes, from the end of one scanline in plane 0 to the start of the next.\n\tptrdiff_t\t\tsize;\t\t// Size of plane 0, including padding.\n\tptrdiff_t\t\toffset;\t\t// Offset from beginning of buffer to beginning of plane 0.\n\n\tuint32 *Address32(int x, int y) const {\n\t\treturn Address32i(x, h-y-1);\n\t}\n\n\tuint32 *Address32i(int x, int y) const {\n\t\treturn (uint32 *)((char *)data + y*pitch + x*4);\n\t}\n\n\tvoid AlignTo4() {\n\t\tpitch = w << 2;\n\t}\n\n\tvoid AlignTo8() {\n\t\tpitch = ((w+1)&~1) << 2;\n\t}\n};\n\nclass VDXFBitmap : public VDXBitmap {\npublic:\n\tenum {\n\t\t/// Set in paramProc if the filter requires a Win32 GDI display context\n\t\t/// for a bitmap.\n\t\t///\n\t\t/// (Deprecated as of API V12 - do not use)\n\t\t/// (Blocked as of API V16)\n\t\tNEEDS_HDC\t\t= 0x00000001L,\n\t};\n\n\tuint32\t\tdwFlags;\n\tVDXHDC\t\thdc;\n\n\tuint32\tmFrameRateHi;\t\t// Frame rate numerator (V1.7.4+)\n\tuint32\tmFrameRateLo;\t\t// Frame rate denominator (V1.7.4+)\n\tsint64\tmFrameCount;\t\t// Frame count; -1 if unlimited or indeterminate (V1.7.4+)\n\n\tVDXPixmapLayout\t*mpPixmapLayout;\n\tconst VDXPixmap\t*mpPixmap;\n\n\tuint32\tmAspectRatioHi;\t\t\t\t///< Pixel aspect ratio fraction (numerator).\t0/0 = unknown\n\tuint32\tmAspectRatioLo;\t\t\t\t///< Pixel aspect ratio fraction (denominator).\n\n\tsint64\tmFrameNumber;\t\t\t\t///< Current frame number (zero based).\n\tsint64\tmFrameTimestampStart;\t\t///< Starting timestamp of frame, in 100ns units.\n\tsint64\tmFrameTimestampEnd;\t\t\t///< Ending timestamp of frame, in 100ns units.\n\tsint64\tmCookie;\t\t\t\t\t///< Cookie supplied when frame was requested.\n\n\tuint32\tmVDXAHandle;\t\t\t\t///< Acceleration handle to be used with VDXA routines.\n\tuint32\tmBorderWidth;\n\tuint32\tmBorderHeight;\n};\n\n// VDXFilterActivation: This is what is actually passed to filters at runtime.\n\nclass VDXFilterActivation {\npublic:\n\tconst VDXFilterDefinition *filter;\t\t//\n\tvoid *filter_data;\n\tVDXFBitmap&\tdst;\n\tVDXFBitmap&\tsrc;\n\tVDXFBitmap\t*_reserved0;\n\tVDXFBitmap\t*const last;\n\tuint32\t\tx1;\n\tuint32\t\ty1;\n\tuint32\t\tx2;\n\tuint32\t\ty2;\n\n\tVDXFilterStateInfo\t*pfsi;\n\tIVDXFilterPreview\t*ifp;\n\tIVDXFilterPreview2\t*ifp2;\t\t\t// (V11+)\n\n\tuint32\t\tmSourceFrameCount;\t\t// (V14+)\n\tVDXFBitmap *const *mpSourceFrames;\t// (V14+)\n\tVDXFBitmap *const *mpOutputFrames;\t// (V14+)\n\n\tIVDXAContext\t*mpVDXA;\t\t\t// (V15+)\n\n\tuint32\t\tmSourceStreamCount;\t\t// (V16+)\n\tVDXFBitmap *const *mpSourceStreams;\t// (V16+)\n\n\tFilterModActivation* fma;\t// (V18+)\n  // avs+:\n  VDXFilterActivation(VDXFBitmap& _dst, VDXFBitmap& _src, VDXFBitmap *_last) : dst(_dst), src(_src), last(_last) {};\n};\n\nenum {\n\t// This is the highest API version supported by this header file.\n\tFILTERMOD_VERSION = 6,\n};\n\nclass FilterModActivation {\npublic:\n\tconst VDXFilterDefinition *filter;\n\tconst FilterModDefinition *filterMod;\n\tvoid *filter_data;\n\tIFilterModPreview *fmpreview;\n\tIFilterModTimeline *fmtimeline;\n\tIFilterModSystem *fmsystem;\n\n\t// FilterModVersion>=2\n\tIFilterModPixmap *fmpixmap;\n\n\t// FilterModVersion>=3\n\tIFilterModProject *fmproject;\n};\n\n// These flags must match those in cpuaccel.h!\n\n#ifndef f_VIRTUALDUB_CPUACCEL_H\n#define CPUF_SUPPORTS_CPUID\t\t\t(0x00000001L)\n#define CPUF_SUPPORTS_FPU\t\t\t(0x00000002L) //  386/486DX\n#define CPUF_SUPPORTS_MMX\t\t\t(0x00000004L) //  P55C, K6, PII\n#define CPUF_SUPPORTS_INTEGER_SSE\t(0x00000008L) //  PIII, Athlon\n#define CPUF_SUPPORTS_SSE\t\t\t(0x00000010L) //  PIII, Athlon XP/MP\n#define CPUF_SUPPORTS_SSE2\t\t\t(0x00000020L) //  PIV, K8\n#define CPUF_SUPPORTS_3DNOW\t\t\t(0x00000040L) //  K6-2\n#define CPUF_SUPPORTS_3DNOW_EXT\t\t(0x00000080L) //  Athlon\n\n#define CPUF_SUPPORTS_SSE3\t\t\t(0x00000100L) //  PIV+, K8 Venice\n#define CPUF_SUPPORTS_SSSE3\t\t\t(0x00000200L) //  Core 2\n#define CPUF_SUPPORTS_SSE41\t\t\t(0x00000400L) //  Penryn, Wolfdale, Yorkfield\n#define CPUF_SUPPORTS_AVX\t\t\t(0x00000800L) //  Sandy Bridge, Bulldozer\n#define CPUF_SUPPORTS_SSE42\t\t\t(0x00001000L) //  Nehalem\n\n// VirtualDubFilterMod specific, identical to AVS+\n#define CPUF_SUPPORTS_AVX2\t\t\t(0x00002000L) //  Haswell\n#define CPUF_SUPPORTS_FMA3\t\t\t(0x00004000L)\n#define CPUF_SUPPORTS_F16C\t\t\t(0x00008000L)\n#define CPUF_SUPPORTS_MOVBE\t\t\t(0x00010000L) // Big Endian move\n#define CPUF_SUPPORTS_POPCNT\t\t(0x00020000L)\n#define CPUF_SUPPORTS_AES\t\t\t(0x00040000L)\n#define CPUF_SUPPORTS_FMA4\t\t\t(0x00080000L)\n\n#define CPUF_SUPPORTS_AVX512F\t\t(0x00100000L) // AVX-512 Foundation.\n#define CPUF_SUPPORTS_AVX512DQ\t\t(0x00200000L) // AVX-512 DQ (Double/Quad granular) Instructions\n#define CPUF_SUPPORTS_AVX512PF\t\t(0x00400000L) // AVX-512 Prefetch\n#define CPUF_SUPPORTS_AVX512ER\t\t(0x00800000L) // AVX-512 Exponential and Reciprocal\n#define CPUF_SUPPORTS_AVX512CD\t\t(0x01000000L) // AVX-512 Conflict Detection\n#define CPUF_SUPPORTS_AVX512BW\t\t(0x02000000L) // AVX-512 BW (Byte/Word granular) Instructions\n#define CPUF_SUPPORTS_AVX512VL\t\t(0x04000000L) // AVX-512 VL (128/256 Vector Length) Extensions\n#define CPUF_SUPPORTS_AVX512IFMA\t(0x08000000L) // AVX-512 IFMA integer 52 bit\n#define CPUF_SUPPORTS_AVX512VBMI\t(0x10000000L) // AVX-512 VBMI\n#endif\n\nstruct VDXFilterFunctions {\n\tVDXFilterDefinition *(__cdecl *addFilter)(VDXFilterModule *, VDXFilterDefinition *, int fd_len);\n\tvoid __declspec(deprecated) (__cdecl *removeFilter)(VDXFilterDefinition *);\n\tbool (__cdecl *isFPUEnabled)();\n\tbool (__cdecl *isMMXEnabled)();\n\tvoid (__cdecl *InitVTables)(VDXFilterVTbls *);\n\n\t// These functions permit you to throw MyError exceptions from a filter.\n\t// YOU MUST ONLY CALL THESE IN runProc, initProc, and startProc.\n\n\tvoid (__cdecl *ExceptOutOfMemory)();\t\t\t\t\t\t// ADDED: V6 (VirtualDub 1.4)\n\tvoid (__cdecl *Except)(const char *format, ...);\t\t\t// ADDED: V6 (VirtualDub 1.4)\n\n\t// These functions are callable at any time.\n\n\tlong (__cdecl *getCPUFlags)();\t\t\t\t\t\t\t\t// ADDED: V6 (VirtualDub 1.4)\n\tlong (__cdecl *getHostVersionInfo)(char *buffer, int len);\t// ADDED: V7 (VirtualDub 1.4d)\n};\n\nstruct FilterModInitFunctions {\n\tVDXFilterDefinition *(__cdecl *addFilter)(VDXFilterModule *, VDXFilterDefinition *, int fd_len, FilterModDefinition*, int md_len);\n};\n\n\n\n///////////////////////////////////////////////////////////////////////////\n\nclass VDXScriptValue;\nclass VDXScriptError;\nstruct VDXScriptObject;\n\nclass VDXScriptError {\npublic:\n\tenum {\n\t\tPARSE_ERROR=1,\n\t\tSEMICOLON_EXPECTED,\n\t\tIDENTIFIER_EXPECTED,\n\n\t\tTYPE_INT_REQUIRED,\n\t\tTYPE_ARRAY_REQUIRED,\n\t\tTYPE_FUNCTION_REQUIRED,\n\t\tTYPE_OBJECT_REQUIRED,\n\n\t\tOBJECT_MEMBER_NAME_REQUIRED,\n\t\tFUNCCALLEND_EXPECTED,\n\t\tTOO_MANY_PARAMS,\n\t\tDIVIDE_BY_ZERO,\n\t\tVAR_NOT_FOUND,\n\t\tMEMBER_NOT_FOUND,\n\t\tOVERLOADED_FUNCTION_NOT_FOUND,\n\t\tIDENT_TOO_LONG,\n\t\tOPERATOR_EXPECTED,\n\t\tCLOSEPARENS_EXPECTED,\n\t\tCLOSEBRACKET_EXPECTED,\n\n\t\tVAR_UNDEFINED,\n\n\t\tOUT_OF_STRING_SPACE,\n\t\tOUT_OF_MEMORY,\n\t\tINTERNAL_ERROR,\n\t\tEXTERNAL_ERROR,\n\n\t\tFCALL_OUT_OF_RANGE,\n\t\tFCALL_INVALID_PTYPE,\n\t\tFCALL_UNKNOWN_STR,\n\n\t\tARRAY_INDEX_OUT_OF_BOUNDS,\n\n\t\tNUMERIC_OVERFLOW,\n\t\tSTRING_NOT_AN_INTEGER_VALUE,\n\t\tSTRING_NOT_A_REAL_VALUE,\n\n\t\tASSERTION_FAILED,\n\t\tAMBIGUOUS_CALL,\n\t\tCANNOT_CAST\n\t};\n};\n\nclass IVDXScriptInterpreter {\npublic:\n\tvirtual\tvoid _placeholder1() {}\n\tvirtual void _placeholder2(void *, void *) {}\n\tvirtual void _placeholder3(char *s) {}\n\n\tvirtual void ScriptError(int e)=0;\n\tvirtual void _placeholder4(VDXScriptError& cse) {}\n\tvirtual char** AllocTempString(long l)=0;\n\n\tvirtual void _placeholder5() {}\n};\n\n#define EXT_SCRIPT_ERROR(x)\t(isi->ScriptError((VDXScriptError::x)))\n\ntypedef VDXScriptValue (*VDXScriptFunctionPtr)(IVDXScriptInterpreter *, void *, const VDXScriptValue *, int);\ntypedef void (*VDXScriptVoidFunctionPtr)(IVDXScriptInterpreter *, void *, const VDXScriptValue *, int);\ntypedef int (*VDXScriptIntFunctionPtr)(IVDXScriptInterpreter *, void *, const VDXScriptValue *, int);\n\nstruct VDXScriptFunctionDef {\n\tVDXScriptFunctionPtr func_ptr;\n\tconst char *name;\n\tconst char *arg_list;\n};\n\nstruct VDXScriptObject {\n\tvoid *_lookup;\t\t\t\t\t\t\t// reserved - set to NULL\n\tVDXScriptFunctionDef\t*func_list;\n\tvoid *_obj_list;\t\t\t\t\t\t// reserved - set to NULL\n};\n\nclass VDXScriptValue {\npublic:\n\tenum { T_VOID, T_INT, T_PINT, T_STR, T_ARRAY, T_OBJECT, T_FNAME, T_FUNCTION, T_VARLV, T_LONG, T_DOUBLE } type;\n\tVDXScriptObject *thisPtr;\n\tunion {\n\t\tint i;\n\t\tchar **s;\n\t\tsint64 l;\n\t\tdouble d;\n\t} u;\n\n\tVDXScriptValue()\t\t\t\t\t{ type = T_VOID; }\n\tVDXScriptValue(int i)\t\t\t\t{ type = T_INT;\t\t\tu.i = i; }\n\tVDXScriptValue(sint64 l)\t\t\t{ type = T_LONG;\t\tu.l = l; }\n\tVDXScriptValue(double d)\t\t\t{ type = T_DOUBLE;\t\tu.d = d; }\n\tVDXScriptValue(char **s)\t\t\t{ type = T_STR;\t\t\tu.s = s; }\n\n\tbool isVoid() const\t\t\t\t\t{ return type == T_VOID; }\n\tbool isInt() const\t\t\t\t\t{ return type == T_INT; }\n\tbool isString() const\t\t\t\t{ return type == T_STR; }\n\tbool isLong() const\t\t\t\t\t{ return type == T_LONG; }\n\tbool isDouble() const\t\t\t\t{ return type == T_DOUBLE; }\n\n\tint\t\tasInt() const\t\t\t\t{ return u.i; }\n\tsint64\tasLong() const\t\t\t\t{ return u.l; }\n\tdouble\tasDouble() const\t\t\t{ return u.d; }\n\tchar **\tasString() const \t\t\t{ return u.s; }\n};\n\n#endif\n"
  },
  {
    "path": "plugins/VFAPIFilter/CMakeLists.txt",
    "content": "CMAKE_MINIMUM_REQUIRED( VERSION 3.6.2...3.11 )\n\nset(PluginName \"VFAPIFilter\")\nset(ProjectName \"Plugin${PluginName}\")\n\n# We need these variables set by the user to compile successfully\nset(DSHOWSRC_BASECLASSES_PATH \"C:/Program Files/Microsoft SDKs/Windows/v7.1/Samples/multimedia/directshow/baseclasses\" CACHE STRING \"Folder path to the DirectShow example baseclasses.\")\nset(DSHOWSRC_BASECLASSES_LIB CACHE FILEPATH \"File path to the DirectShow example baseclasses precompiled static library ('strmbase.lib').\")\nset(DSHOWSRC_DX_INCLUDE_PATH \"C:/Program Files/Microsoft DirectX SDK (August 2009)/Include\" CACHE STRING \"Include folder path to the DirectX headers.\")\n\n# Create library\nproject(${ProjectName} VERSION ${PROJECT_VERSION} LANGUAGES CXX)\nlist (APPEND SourceFiles\n    \"VFAPIFilter.cpp\"\n)\nadd_library(${ProjectName} SHARED ${SourceFiles})\nset_target_properties(${ProjectName} PROPERTIES \"OUTPUT_NAME\" ${PluginName})\nif (MINGW)\n  set_target_properties(${ProjectName} PROPERTIES PREFIX \"\")\n  set_target_properties(${ProjectName} PROPERTIES IMPORT_PREFIX \"\")\nendif()\n\n# Library dependencies\ntarget_link_libraries(${ProjectName} \"User32.lib\")\n\n# Include directories\ntarget_include_directories(${ProjectName} PRIVATE ${AvsCore_SOURCE_DIR} ${DSHOWSRC_BASECLASSES_PATH} ${DSHOWSRC_DX_INCLUDE_PATH})\n\nif (MSVC_IDE)\n  # Copy output to a common folder for easy deployment\n  add_custom_command(\n    TARGET ${ProjectName}\n    POST_BUILD\n    COMMAND xcopy /Y \\\"$(TargetPath)\\\" \\\"${CMAKE_BINARY_DIR}/Output/plugins\\\"\n  )\nendif()\n\nINSTALL(TARGETS \"${ProjectName}\"\n        DESTINATION \"${CORE_PLUGIN_INSTALL_PATH}/avisynth\")\n"
  },
  {
    "path": "plugins/VFAPIFilter/VFAPIFilter.cpp",
    "content": "// Avisynth v2.5.\n// http://avisynth.nl\n\n// This program is free software; you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation; either version 2 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with this program; if not, write to the Free Software\n// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit\n// http://www.gnu.org/copyleft/gpl.html .\n//\n// Linking Avisynth statically or dynamically with other modules is making a\n// combined work based on Avisynth.  Thus, the terms and conditions of the GNU\n// General Public License cover the whole combination.\n//\n// As a special exception, the copyright holders of Avisynth give you\n// permission to link Avisynth with independent modules that communicate with\n// Avisynth solely through the interfaces defined in avisynth.h, regardless of the license\n// terms of these independent modules, and to copy and distribute the\n// resulting combined work under terms of your choice, provided that\n// every copy of the combined work is accompanied by a complete copy of\n// the source code of Avisynth (the version of Avisynth used to produce the\n// combined work), being distributed under the terms of the GNU General\n// Public License plus this exception.  An independent module is a module\n// which is not derived from or based on Avisynth, such as 3rd-party filters,\n// import and export plugins, or graphical user interfaces.\n\n#include <avisynth.h>\n#include <avs/win.h>\n#include <avs/minmax.h>\n\n/********************************************************************\n* VFAPI plugin support\n********************************************************************/\n\n#define VF_STREAM_VIDEO   0x00000001\n#define VF_STREAM_AUDIO   0x00000002\n#define VF_OK       0x00000000\n#define VF_ERROR      0x80004005\n\nstruct VF_PluginInfo {\n  DWORD dwSize;\n  DWORD dwAPIVersion;\n  DWORD dwVersion;\n  DWORD dwSupportStreamType;\n  char  cPluginInfo[256];\n  char  cFileType[256];\n};\n\ntypedef DWORD VF_FileHandle;\n\nstruct VF_FileInfo {\n  DWORD dwSize;\n  DWORD dwHasStreams;\n};\n\nstruct VF_StreamInfo_Video {\n  DWORD dwSize;\n  DWORD dwLengthL;\n  DWORD dwLengthH;\n  DWORD dwRate;\n  DWORD dwScale;\n  DWORD dwWidth;\n  DWORD dwHeight;\n  DWORD dwBitCount;\n};\n\nstruct VF_StreamInfo_Audio {\n  DWORD dwSize;\n  DWORD dwLengthL;\n  DWORD dwLengthH;\n  DWORD dwRate;\n  DWORD dwScale;\n  DWORD dwChannels;\n  DWORD dwBitsPerSample;\n  DWORD dwBlockAlign;\n};\n\nstruct VF_ReadData_Video {\n  DWORD dwSize;\n  DWORD dwFrameNumberL;\n  DWORD dwFrameNumberH;\n  void  *lpData;\n  long  lPitch;\n};\n\nstruct VF_ReadData_Audio {\n  DWORD dwSize;\n  DWORD dwSamplePosL;\n  DWORD dwSamplePosH;\n  DWORD dwSampleCount;\n  DWORD dwReadedSampleCount;\n  DWORD dwBufSize;\n  void  *lpBuf;\n};\n\nstruct VF_PluginFunc {\n  DWORD dwSize;\n  HRESULT (_stdcall *OpenFile)( const char *lpFileName, VF_FileHandle* lpFileHandle );\n  HRESULT (_stdcall *CloseFile)( VF_FileHandle hFileHandle );\n  HRESULT (_stdcall *GetFileInfo)( VF_FileHandle hFileHandle, VF_FileInfo* lpFileInfo );\n  HRESULT (_stdcall *GetStreamInfo)( VF_FileHandle hFileHandle,DWORD dwStream,void *lpStreamInfo );\n  HRESULT (_stdcall *ReadData)( VF_FileHandle hFileHandle,DWORD dwStream,void *lpData );\n};\n\nstruct VFAPI_PluginRefs\n{\n  HMODULE Library;\n  VF_PluginFunc PluginFunc;\n};\n\ntypedef HRESULT (__stdcall *VF_GetPluginInfo)(VF_PluginInfo* lpPluginInfo);\ntypedef HRESULT (__stdcall *VF_GetPluginFunc)(VF_PluginFunc* lpPluginFunc);\n\nvoid CheckHresult(IScriptEnvironment* env, HRESULT hr) {\n  if (FAILED(hr)) {\n    env->ThrowError(\"VFAPI plugin returned an error (0x%X)\", hr);\n  }\n}\n\nvoid DeleteVFPluginFunc(void* vfpf, IScriptEnvironment*) {\n\n  VFAPI_PluginRefs *ref = (VFAPI_PluginRefs*)vfpf;\n  FreeLibrary(ref->Library);\n  delete ref;\n}\n\nclass VFAPIPluginProxy : public IClip {\n  VideoInfo vi;\n  const VF_PluginFunc* const plugin_func;\n  VF_FileHandle h;\npublic:\n  VFAPIPluginProxy(const char* filename, const VF_PluginFunc* _plugin_func, IScriptEnvironment* env)\n    : plugin_func(_plugin_func)\n  {\n    CheckHresult(env, plugin_func->OpenFile(filename, &h));\n    VF_FileInfo file_info = { sizeof(VF_FileInfo) };\n    CheckHresult(env, plugin_func->GetFileInfo(h, &file_info));\n\n    memset(&vi, 0, sizeof(VideoInfo));\n    if (file_info.dwHasStreams & VF_STREAM_VIDEO) {\n      VF_StreamInfo_Video stream_info = { sizeof(VF_StreamInfo_Video) };\n      CheckHresult(env, plugin_func->GetStreamInfo(h, VF_STREAM_VIDEO, &stream_info));\n      if (stream_info.dwBitCount == 24) {\n        vi.pixel_type = VideoInfo::CS_BGR24;\n      } else if (stream_info.dwBitCount == 32) {\n        vi.pixel_type = VideoInfo::CS_BGR32;\n      } else {\n        env->ThrowError(\"VFAPIPluginProxy: plugin returned invalid bit depth (%d)\", stream_info.dwBitCount);\n      }\n      vi.width = stream_info.dwWidth;\n      vi.height = stream_info.dwHeight;\n      vi.num_frames = stream_info.dwLengthL;\n      vi.SetFPS(stream_info.dwRate, stream_info.dwScale);\n    }\n    if (file_info.dwHasStreams & VF_STREAM_AUDIO) {\n      VF_StreamInfo_Audio stream_info = { sizeof(VF_StreamInfo_Audio) };\n      CheckHresult(env, plugin_func->GetStreamInfo(h, VF_STREAM_AUDIO, &stream_info));\n      vi.audio_samples_per_second = stream_info.dwRate / stream_info.dwScale;\n      vi.num_audio_samples = stream_info.dwLengthL;\n      vi.nchannels = stream_info.dwChannels;\n\n      if (stream_info.dwBitsPerSample == 8)\n        vi.sample_type = SAMPLE_INT8;\n      else if (stream_info.dwBitsPerSample == 16)\n        vi.sample_type = SAMPLE_INT16;\n      else if (stream_info.dwBitsPerSample == 24)\n        vi.sample_type = SAMPLE_INT24;\n      else if (stream_info.dwBitsPerSample == 32)\n        vi.sample_type = SAMPLE_INT32;\n      else\n        env->ThrowError(\"VFAPIPluginProxy: plugin returned invalid audio sample depth (%d)\", stream_info.dwBitsPerSample);\n    }\n\n    if (!vi.HasVideo() && !vi.HasAudio())\n      env->ThrowError(\"VFAPIPluginProxy: no video or audio stream\");\n  }\n\n  const VideoInfo& __stdcall GetVideoInfo() { return vi; }\n\n  PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) {\n    n = max(min(n, vi.num_frames-1), 0);\n    PVideoFrame result = env->NewVideoFrame(vi);\n    VF_ReadData_Video vfrdv = { sizeof(VF_ReadData_Video), n, 0, result->GetWritePtr(), result->GetPitch() };\n    CheckHresult(env, plugin_func->ReadData(h, VF_STREAM_VIDEO, &vfrdv));\n    return result;\n  }\n\n  void __stdcall GetAudio(void* buf, __int64 start, __int64 count, IScriptEnvironment* env) {\n    if (start < 0) {\n      int bytes = (int)vi.BytesFromAudioSamples(-start);\n      memset(buf, 0, bytes);\n      buf = (char*)buf + bytes;\n      count += start;\n      start = 0;\n    }\n    VF_ReadData_Audio vfrda = { sizeof(VF_ReadData_Audio), (int)start, 0, (int)count, 0, (int)vi.BytesFromAudioSamples(count), buf };\n    CheckHresult(env, plugin_func->ReadData(h, VF_STREAM_AUDIO, &vfrda));\n    if (int(vfrda.dwReadedSampleCount) < count) {\n      memset((char*)buf + vi.BytesFromAudioSamples(vfrda.dwReadedSampleCount),\n        0, (size_t)vi.BytesFromAudioSamples(count - vfrda.dwReadedSampleCount));\n    }\n  }\n\n  bool __stdcall GetParity(int n) { return false; }\n  int __stdcall SetCacheHints(int cachehints,int frame_range) { return 0; };\n\n  static AVSValue __cdecl Create(AVSValue args, void* user_data, IScriptEnvironment* env) {\n    args = args[0];\n    PClip result = new VFAPIPluginProxy(args[0].AsString(), (VF_PluginFunc*)user_data, env);\n    for (int i=1; i<args.ArraySize(); ++i)\n      result = new_Splice(result, new VFAPIPluginProxy(args[i].AsString(), (VF_PluginFunc*)user_data, env), false, env);\n    return result;\n  }\n};\n\n\nAVSValue LoadVFAPIPlugin(AVSValue args, void*, IScriptEnvironment* env) {\n  const char* plugin_name = args[0].AsString();\n\n  HMODULE hmodule = LoadLibrary(plugin_name);\n  if (!hmodule)\n    env->ThrowError(\"LoadVirtualdubPlugin: Error opening \\\"%s\\\", error=0x%x\", plugin_name, GetLastError());\n\n  VF_GetPluginInfo vfGetPluginInfo = (VF_GetPluginInfo)GetProcAddress(hmodule, \"vfGetPluginInfo\");\n  VF_GetPluginFunc vfGetPluginFunc = (VF_GetPluginFunc)GetProcAddress(hmodule, \"vfGetPluginFunc\");\n  if (!vfGetPluginInfo || !vfGetPluginFunc)\n  {\n    FreeLibrary(hmodule);\n    env->ThrowError(\"LoadPlugin: \\\"%s\\\" is not a VFAPI plugin\", plugin_name);\n  }\n\n  VF_PluginInfo plugin_info = { sizeof(VF_PluginInfo) };\n  CheckHresult(env, vfGetPluginInfo(&plugin_info));\n\n  VFAPI_PluginRefs *refs = new VFAPI_PluginRefs();\n  refs->Library = hmodule;\n  VF_PluginFunc* plugin_func = &(refs->PluginFunc);\n  env->AtExit(DeleteVFPluginFunc, plugin_func);\n\n  plugin_func->dwSize = sizeof(VF_PluginFunc);\n  CheckHresult(env, vfGetPluginFunc(plugin_func));\n\n  env->AddFunction(args[1].AsString(), \"s+\", VFAPIPluginProxy::Create, plugin_func);\n\n  return plugin_info.cPluginInfo ? AVSValue(plugin_info.cPluginInfo) : AVSValue();\n}\n\nconst AVS_Linkage * AVS_linkage = 0;\nextern \"C\" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors) {\n\tAVS_linkage = vectors;\n\n  // clip, base filename, start, end, image format/extension, info\n  env->AddFunction(\"LoadVFAPIPlugin\", \"ss\", LoadVFAPIPlugin, 0);\n\n  return \"`LoadVFAPIPlugin' Allows to load and use filters written for VFAPI.\";\n}\n"
  }
]